diff --git a/.github/actions/setup-repo/action.yml b/.github/actions/setup-repo/action.yml new file mode 100644 index 00000000..1932a677 --- /dev/null +++ b/.github/actions/setup-repo/action.yml @@ -0,0 +1,35 @@ +name: Setup repo +description: Runs all steps to setup the repo (install node_modules, build, etc...) +inputs: + registry-token: + description: 'PAT to access registries' +runs: + using: 'composite' + steps: + - name: Get yarn cache directory path + id: yarn-cache-dir-path + shell: bash + run: | + echo "::set-output name=dir::$(yarn cache dir)" + echo "::set-output name=version::$(yarn -v)" + + - uses: actions/setup-node@v3 + with: + node-version: '20' + + - uses: actions/cache@v2 + id: yarn-cache + with: + path: | + **/node_modules + ${{ steps.yarn-cache-dir-path.outputs.dir }} + + key: ${{ runner.os }}-yarn-${{ hashFiles('**/yarn.lock') }} + restore-keys: | + ${{ runner.os }}-yarn- + + - name: Install dependencies + shell: bash + run: echo "//npm.pkg.github.com/:_authToken=$GH_REGISTRY_ACCESS_TOKEN" >> .npmrc && yarn install --frozen-lockfile --verbose && rm -f .npmrc + env: + GH_REGISTRY_ACCESS_TOKEN: ${{ inputs.registry-token }} diff --git a/logo.svg b/.github/assets/logo.svg similarity index 100% rename from logo.svg rename to .github/assets/logo.svg diff --git a/.github/workflows/ci-deep.yml b/.github/workflows/ci-deep.yml index 18b8a6cf..98a2b99e 100644 --- a/.github/workflows/ci-deep.yml +++ b/.github/workflows/ci-deep.yml @@ -1,13 +1,13 @@ -name: "CI Deep" +name: 'CI Deep' on: schedule: - - cron: "0 3 * * 0" # at 3:00am UTC every Sunday + - cron: '0 3 * * 0' # at 3:00am UTC every Sunday workflow_dispatch: inputs: fuzzRuns: - default: "10000" - description: "Unit: number of fuzz runs." + default: '10000' + description: 'Unit: number of fuzz runs.' required: false jobs: @@ -19,7 +19,12 @@ jobs: - uses: actions/setup-node@v3 with: node-version: 18 - cache: "yarn" + cache: 'yarn' + + - name: Setup repo + uses: ./.github/actions/setup-repo + with: + registry-token: ${{ secrets.GH_REGISTRY_ACCESS_TOKEN }} - name: Install dependencies run: yarn install @@ -27,7 +32,7 @@ jobs: - name: Run solhint run: yarn lint:check - - name: "Add lint summary" + - name: 'Add lint summary' run: | echo "## Lint result" >> $GITHUB_STEP_SUMMARY echo "✅ Passed" >> $GITHUB_STEP_SUMMARY @@ -37,12 +42,17 @@ jobs: steps: - uses: actions/checkout@v3 with: - submodules: "recursive" + submodules: 'recursive' - uses: actions/setup-node@v3 with: node-version: 18 - cache: "yarn" + cache: 'yarn' + + - name: Setup repo + uses: ./.github/actions/setup-repo + with: + registry-token: ${{ secrets.GH_REGISTRY_ACCESS_TOKEN }} - name: Install dependencies run: yarn install --frozen-lockfile @@ -58,10 +68,10 @@ jobs: - name: Compile foundry run: yarn foundry:compile --sizes - - name: "Cache the build so that it can be re-used by the other jobs" - uses: "actions/cache/save@v3" + - name: 'Cache the build so that it can be re-used by the other jobs' + uses: 'actions/cache/save@v3' with: - key: "build-${{ github.sha }}" + key: 'build-${{ github.sha }}' path: | cache-forge out @@ -70,13 +80,13 @@ jobs: typechain node_modules - - name: "Add build summary" + - name: 'Add build summary' run: | echo "## Build result" >> $GITHUB_STEP_SUMMARY echo "✅ Passed" >> $GITHUB_STEP_SUMMARY hardhat-tests: - needs: ["build", "lint"] + needs: ['build', 'lint'] runs-on: ubuntu-latest steps: - uses: actions/checkout@v3 @@ -84,13 +94,13 @@ jobs: - uses: actions/setup-node@v3 with: node-version: 18 - cache: "yarn" + cache: 'yarn' - - name: "Restore the cached build" - uses: "actions/cache/restore@v3" + - name: 'Restore the cached build' + uses: 'actions/cache/restore@v3' with: fail-on-cache-miss: true - key: "build-${{ github.sha }}" + key: 'build-${{ github.sha }}' path: | cache-forge out @@ -110,29 +120,29 @@ jobs: ETH_NODE_URI_FORK: ${{ secrets.ETH_NODE_URI_FORK }} ETH_NODE_URI_MAINNET: ${{ secrets.ETH_NODE_URI_MAINNET }} - - name: "Add test summary" + - name: 'Add test summary' run: | echo "## Hardhat Unit tests result" >> $GITHUB_STEP_SUMMARY echo "✅ Passed" >> $GITHUB_STEP_SUMMARY foundry-tests: - needs: ["build", "lint"] + needs: ['build', 'lint'] runs-on: ubuntu-latest steps: - uses: actions/checkout@v2 with: - submodules: "recursive" + submodules: 'recursive' - name: Install Foundry uses: foundry-rs/foundry-toolchain@v1 with: version: nightly - - name: "Restore the cached build" - uses: "actions/cache/restore@v3" + - name: 'Restore the cached build' + uses: 'actions/cache/restore@v3' with: fail-on-cache-miss: true - key: "build-${{ github.sha }}" + key: 'build-${{ github.sha }}' path: | cache-forge out @@ -150,7 +160,7 @@ jobs: ETH_NODE_URI_FANTOM: ${{ secrets.ETH_NODE_URI_FANTOM }} FOUNDRY_FUZZ_RUNS: ${{ github.event.inputs.fuzzRuns || '10000' }} - - name: "Add test summary" + - name: 'Add test summary' run: | echo "## Foundry Unit tests result" >> $GITHUB_STEP_SUMMARY - echo "✅ Passed" >> $GITHUB_STEP_SUMMARY \ No newline at end of file + echo "✅ Passed" >> $GITHUB_STEP_SUMMARY diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index e8f3fe88..471e9049 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -1,11 +1,11 @@ -name: "CI" +name: 'CI' on: workflow_dispatch: pull_request: push: branches: - - "main" + - 'main' jobs: lint: @@ -16,7 +16,12 @@ jobs: - uses: actions/setup-node@v3 with: node-version: 18 - cache: "yarn" + cache: 'yarn' + + - name: Setup repo + uses: ./.github/actions/setup-repo + with: + registry-token: ${{ secrets.GH_REGISTRY_ACCESS_TOKEN }} - name: Install dependencies run: yarn install @@ -24,7 +29,7 @@ jobs: - name: Run solhint run: yarn lint:check - - name: "Add lint summary" + - name: 'Add lint summary' run: | echo "## Lint result" >> $GITHUB_STEP_SUMMARY echo "✅ Passed" >> $GITHUB_STEP_SUMMARY @@ -33,12 +38,17 @@ jobs: steps: - uses: actions/checkout@v3 with: - submodules: "recursive" + submodules: 'recursive' - uses: actions/setup-node@v3 with: node-version: 18 - cache: "yarn" + cache: 'yarn' + + - name: Setup repo + uses: ./.github/actions/setup-repo + with: + registry-token: ${{ secrets.GH_REGISTRY_ACCESS_TOKEN }} - name: Install dependencies run: yarn install --frozen-lockfile @@ -54,10 +64,10 @@ jobs: - name: Compile foundry run: yarn foundry:compile --sizes - - name: "Cache the build so that it can be re-used by the other jobs" - uses: "actions/cache/save@v3" + - name: 'Cache the build so that it can be re-used by the other jobs' + uses: 'actions/cache/save@v3' with: - key: "build-${{ github.sha }}" + key: 'build-${{ github.sha }}' path: | cache-forge out @@ -65,13 +75,13 @@ jobs: artifacts typechain node_modules - - name: "Add build summary" + - name: 'Add build summary' run: | echo "## Build result" >> $GITHUB_STEP_SUMMARY echo "✅ Passed" >> $GITHUB_STEP_SUMMARY hardhat-tests: - needs: ["build", "lint"] + needs: ['build', 'lint'] runs-on: ubuntu-latest steps: - uses: actions/checkout@v3 @@ -79,13 +89,13 @@ jobs: - uses: actions/setup-node@v3 with: node-version: 18 - cache: "yarn" + cache: 'yarn' - - name: "Restore the cached build" - uses: "actions/cache/restore@v3" + - name: 'Restore the cached build' + uses: 'actions/cache/restore@v3' with: fail-on-cache-miss: true - key: "build-${{ github.sha }}" + key: 'build-${{ github.sha }}' path: | cache-forge out @@ -94,7 +104,6 @@ jobs: typechain node_modules - run: export NODE_OPTIONS=--max_old_space_size=11264 - - name: Run unit tests run: yarn hardhat:test env: @@ -104,29 +113,29 @@ jobs: ETH_NODE_URI_FORK: ${{ secrets.ETH_NODE_URI_FORK }} ETH_NODE_URI_MAINNET: ${{ secrets.ETH_NODE_URI_MAINNET }} - - name: "Add test summary" + - name: 'Add test summary' run: | echo "## Hardhat Unit tests result" >> $GITHUB_STEP_SUMMARY echo "✅ Passed" >> $GITHUB_STEP_SUMMARY foundry-tests: - needs: ["build", "lint"] + needs: ['build', 'lint'] runs-on: ubuntu-latest steps: - uses: actions/checkout@v2 with: - submodules: "recursive" + submodules: 'recursive' - name: Install Foundry uses: foundry-rs/foundry-toolchain@v1 with: version: nightly - - name: "Restore the cached build" - uses: "actions/cache/restore@v3" + - name: 'Restore the cached build' + uses: 'actions/cache/restore@v3' with: fail-on-cache-miss: true - key: "build-${{ github.sha }}" + key: 'build-${{ github.sha }}' path: | cache-forge out @@ -141,38 +150,60 @@ jobs: ETH_NODE_URI_POLYGON: ${{ secrets.ETH_NODE_URI_POLYGON }} ETH_NODE_URI_GOERLI: ${{ secrets.ETH_NODE_URI_GOERLI }} ETH_NODE_URI_FANTOM: ${{ secrets.ETH_NODE_URI_FANTOM }} - FOUNDRY_FUZZ_RUNS: "5000" + FOUNDRY_FUZZ_RUNS: '5000' - - name: "Add test summary" + - name: 'Add test summary' run: | echo "## Foundry Unit tests result" >> $GITHUB_STEP_SUMMARY echo "✅ Passed" >> $GITHUB_STEP_SUMMARY slither-analyze: - needs: ["build", "lint"] + needs: ['build', 'lint'] permissions: - actions: "read" - contents: "read" - security-events: "write" - runs-on: "ubuntu-latest" + actions: 'read' + contents: 'read' + security-events: 'write' + runs-on: 'ubuntu-latest' steps: - - name: "Check out the repo" - uses: "actions/checkout@v3" + - name: 'Check out the repo' + uses: 'actions/checkout@v3' + + - name: 'Restore the cached build' + uses: 'actions/cache/restore@v3' + with: + fail-on-cache-miss: true + key: 'build-${{ github.sha }}' + path: | + cache-forge + out + cache-hh + artifacts + typechain + node_modules + + - name: Install Foundry + uses: foundry-rs/foundry-toolchain@v1 + with: + version: nightly + + - name: Compile foundry + run: forge clean && forge build --build-info --force - - name: "Run Slither analysis" - uses: "crytic/slither-action@v0.3.0" - id: "slither" + - name: 'Run Slither analysis' + uses: 'crytic/slither-action@v0.3.0' + id: 'slither' with: - fail-on: "none" - sarif: "results.sarif" + fail-on: 'none' + sarif: 'results.sarif' node-version: 18 + ignore-compile: true - - name: "Upload SARIF file to GitHub code scanning" - uses: "github/codeql-action/upload-sarif@v2" + - name: 'Upload SARIF file to GitHub code scanning' + uses: 'github/codeql-action/upload-sarif@v2' with: sarif_file: ${{ steps.slither.outputs.sarif }} - - name: "Add Slither summary" + - name: 'Add Slither summary' run: | echo "## Slither result" >> $GITHUB_STEP_SUMMARY - echo "✅ Uploaded to GitHub code scanning" >> $GITHUB_STEP_SUMMARY \ No newline at end of file + echo "✅ Uploaded to GitHub code scanning" >> $GITHUB_STEP_SUMMARY diff --git a/.gitmodules b/.gitmodules index 888d42dc..5eff2c56 100644 --- a/.gitmodules +++ b/.gitmodules @@ -1,3 +1,11 @@ [submodule "lib/forge-std"] path = lib/forge-std url = https://github.com/foundry-rs/forge-std +[submodule "lib/solidity-stringutils"] + path = lib/solidity-stringutils + url = https://github.com/Arachnid/solidity-stringutils + ignore = dirty +[submodule "lib/prb-math"] + path = lib/prb-math + url = https://github.com/PaulRBerg/prb-math + ignore = dirty \ No newline at end of file diff --git a/.npmrc b/.npmrc new file mode 100644 index 00000000..af66bba8 --- /dev/null +++ b/.npmrc @@ -0,0 +1 @@ +@angleprotocol:registry=https://npm.pkg.github.com diff --git a/README.md b/README.md index 2f6ad935..0f4dc3dd 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ -# Angle Borrowing Module Angle Borrowing Module +# Angle Borrowing Module Angle Borrowing Module [![CI](https://github.com/AngleProtocol/borrow-contracts/actions/workflows/ci.yml/badge.svg)](https://github.com/AngleProtocol/borrow-contracts/actions) [![Docs](https://img.shields.io/badge/docs-%F0%9F%93%84-blue)](https://docs.angle.money/angle-borrowing-module/borrowing-module) diff --git a/contracts/agToken/AgEUR.sol b/contracts/agToken/AgEUR.sol new file mode 100644 index 00000000..9c17ff64 --- /dev/null +++ b/contracts/agToken/AgEUR.sol @@ -0,0 +1,112 @@ +// SPDX-License-Identifier: GPL-3.0 + +pragma solidity ^0.8.12; + +import "../interfaces/IAgToken.sol"; +import "../interfaces/coreModule/IStableMaster.sol"; +import "../interfaces/ITreasury.sol"; +import "@openzeppelin/contracts-upgradeable/token/ERC20/extensions/draft-ERC20PermitUpgradeable.sol"; + +/// @title AgEUR +/// @author Angle Labs, Inc. +/// @notice Base contract for agEUR, Angle's Euro stablecoin +/// @dev This contract is an upgraded version of the agEUR contract that was first deployed on Ethereum mainnet +contract AgEUR is IAgToken, ERC20PermitUpgradeable { + // ================================= REFERENCES ================================ + + /// @notice Reference to the `StableMaster` contract associated to agEUR + address public stableMaster; + + /// @custom:oz-upgrades-unsafe-allow constructor + constructor() initializer {} + + // ============================== ADDED PARAMETERS ============================= + + /// @inheritdoc IAgToken + mapping(address => bool) public isMinter; + /// @notice Reference to the treasury contract which can grant minting rights + address public treasury; + /// @notice Boolean used to check whether the contract had been reinitialized after an upgrade + bool public treasuryInitialized; + + // =================================== EVENTS ================================== + + event TreasuryUpdated(address indexed _treasury); + event MinterToggled(address indexed minter); + + // =================================== ERRORS ================================== + + error BurnAmountExceedsAllowance(); + error InvalidSender(); + error InvalidTreasury(); + error NotGovernor(); + error NotMinter(); + error NotTreasury(); + error TreasuryAlreadyInitialized(); + + // ================================= MODIFIERS ================================= + + /// @notice Checks to see if it is the `Treasury` calling this contract + modifier onlyTreasury() { + if (msg.sender != treasury) revert NotTreasury(); + _; + } + + /// @notice Checks whether the sender has the minting right + modifier onlyMinter() { + if (!isMinter[msg.sender]) revert NotMinter(); + _; + } + + // ============================= EXTERNAL FUNCTION ============================= + + /// @notice Allows anyone to burn stablecoins + /// @param amount Amount of stablecoins to burn + /// @dev This function can typically be called if there is a settlement mechanism to burn stablecoins + function burnStablecoin(uint256 amount) external { + _burn(msg.sender, amount); + } + + // ========================= MINTER ROLE ONLY FUNCTIONS ======================== + + /// @inheritdoc IAgToken + function burnSelf(uint256 amount, address burner) external onlyMinter { + _burn(burner, amount); + } + + /// @inheritdoc IAgToken + function burnFrom(uint256 amount, address burner, address sender) external onlyMinter { + if (burner != sender) { + uint256 currentAllowance = allowance(burner, sender); + if (currentAllowance < amount) revert BurnAmountExceedsAllowance(); + _approve(burner, sender, currentAllowance - amount); + } + _burn(burner, amount); + } + + /// @inheritdoc IAgToken + function mint(address account, uint256 amount) external onlyMinter { + _mint(account, amount); + } + + // ========================== TREASURY ONLY FUNCTIONS ========================== + + /// @inheritdoc IAgToken + function addMinter(address minter) external onlyTreasury { + isMinter[minter] = true; + emit MinterToggled(minter); + } + + /// @inheritdoc IAgToken + function removeMinter(address minter) external { + if (msg.sender != minter && msg.sender != address(treasury)) revert InvalidSender(); + isMinter[minter] = false; + emit MinterToggled(minter); + } + + /// @inheritdoc IAgToken + function setTreasury(address _treasury) external onlyTreasury { + treasury = _treasury; + emit TreasuryUpdated(_treasury); + } +} diff --git a/contracts/agToken/AgToken.sol b/contracts/agToken/AgToken.sol index c0fd9ca3..3f7272ff 100644 --- a/contracts/agToken/AgToken.sol +++ b/contracts/agToken/AgToken.sol @@ -2,85 +2,90 @@ pragma solidity ^0.8.12; +/* + * █ + ***** ▓▓▓ + * ▓▓▓▓▓▓▓ + * ///. ▓▓▓▓▓▓▓▓▓▓▓▓▓ + ***** //////// ▓▓▓▓▓▓▓ + * ///////////// ▓▓▓ + ▓▓ ////////////////// █ ▓▓ + ▓▓ ▓▓ /////////////////////// ▓▓ ▓▓ + ▓▓ ▓▓ //////////////////////////// ▓▓ ▓▓ + ▓▓ ▓▓ /////////▓▓▓///////▓▓▓///////// ▓▓ ▓▓ + ▓▓ ,////////////////////////////////////// ▓▓ ▓▓ + ▓▓ ////////////////////////////////////////// ▓▓ + ▓▓ //////////////////////▓▓▓▓///////////////////// + ,//////////////////////////////////////////////////// + .////////////////////////////////////////////////////////// + .//////////////////////////██.,//////////////////////////█ + .//////////////////////████..,./////////////////////██ + ...////////////////███████.....,.////////////////███ + ,.,////////////████████ ........,///////////████ + .,.,//////█████████ ,.......///////████ + ,..//████████ ........./████ + ..,██████ .....,███ + .██ ,.,█ + + + + ▓▓ ▓▓▓▓▓▓▓▓▓▓ ▓▓▓▓▓▓▓▓▓▓ ▓▓ ▓▓▓▓▓▓▓▓▓▓ + ▓▓▓▓▓▓ ▓▓▓ ▓▓▓ ▓▓▓ ▓▓ ▓▓ ▓▓▓▓ + ▓▓▓ ▓▓▓ ▓▓▓ ▓▓▓ ▓▓▓ ▓▓▓ ▓▓ ▓▓▓▓▓ + ▓▓▓ ▓▓ ▓▓▓ ▓▓▓ ▓▓▓▓▓▓▓▓▓▓ ▓▓▓▓▓▓▓▓▓▓ ▓▓▓▓▓▓▓▓▓▓ +*/ + import "../interfaces/IAgToken.sol"; -import "../interfaces/coreModule/IStableMaster.sol"; import "../interfaces/ITreasury.sol"; -// OpenZeppelin may update its version of the ERC20PermitUpgradeable token import "@openzeppelin/contracts-upgradeable/token/ERC20/extensions/draft-ERC20PermitUpgradeable.sol"; /// @title AgToken /// @author Angle Labs, Inc. -/// @notice Base contract for agEUR, Angle's Euro stablecoin -/// @dev This contract is an upgraded version of the first agEUR implementation deployed on Ethereum mainnet -/// @dev This implementation can be generalized to other Angle stablecoins which support the protocol's Core Module +/// @notice Base contract for Angle agTokens on Ethereum and on other chains +/// @dev By default, agTokens are ERC-20 tokens with 18 decimals contract AgToken is IAgToken, ERC20PermitUpgradeable { - // ========================= References to other contracts ===================== - - /// @notice Reference to the `StableMaster` contract associated to this `AgToken` - address public stableMaster; - - // ============================= Constructor =================================== - - /// @notice Initializes the `AgToken` contract - /// @param name_ Name of the token - /// @param symbol_ Symbol of the token - /// @param stableMaster_ Reference to the `StableMaster` contract associated to this agToken - /// @dev By default, agTokens are ERC-20 tokens with 18 decimals - function initialize(string memory name_, string memory symbol_, address stableMaster_) external initializer { - __ERC20Permit_init(name_); - __ERC20_init(name_, symbol_); - require(stableMaster_ != address(0), "0"); - stableMaster = stableMaster_; - } - - /// @custom:oz-upgrades-unsafe-allow constructor - constructor() initializer {} - - // ======= Added Parameters and Variables from the first implementation ======== + // =========================== PARAMETERS / VARIABLES ========================== /// @inheritdoc IAgToken mapping(address => bool) public isMinter; /// @notice Reference to the treasury contract which can grant minting rights address public treasury; - /// @notice Boolean to check whether the contract has been reinitialized after its upgrade - bool public treasuryInitialized; - // =============================== Added Events ================================ + // =================================== EVENTS ================================== event TreasuryUpdated(address indexed _treasury); event MinterToggled(address indexed minter); - // =============================== Added Errors ================================ + // =================================== ERRORS ================================== error BurnAmountExceedsAllowance(); error InvalidSender(); error InvalidTreasury(); - error NotGovernor(); error NotMinter(); error NotTreasury(); - error TreasuryAlreadyInitialized(); - // =============================== Setup Function ============================== + // ================================ CONSTRUCTOR ================================ + + /// @custom:oz-upgrades-unsafe-allow constructor + constructor() initializer {} + + /// @notice Initializes the `AgToken` contract + function initialize(string memory name_, string memory symbol_, address _treasury) external { + _initialize(name_, symbol_, _treasury); + } - /// @notice Sets up the treasury contract in this AgToken contract - /// @param _treasury Treasury contract to add - /// @dev The address calling this function has to be hard-coded in the contract - /// @dev Can be called only once - function setUpTreasury(address _treasury) external { - // Only governor - if (msg.sender != 0xdC4e6DFe07EFCa50a197DF15D9200883eF4Eb1c8) revert NotGovernor(); + /// @notice Initializes the contract + function _initialize(string memory name_, string memory symbol_, address _treasury) internal virtual initializer { if (address(ITreasury(_treasury).stablecoin()) != address(this)) revert InvalidTreasury(); - if (treasuryInitialized) revert TreasuryAlreadyInitialized(); + __ERC20Permit_init(name_); + __ERC20_init(name_, symbol_); treasury = _treasury; - treasuryInitialized = true; - isMinter[stableMaster] = true; emit TreasuryUpdated(_treasury); } - // =============================== Modifiers =================================== + // ================================= MODIFIERS ================================= /// @notice Checks to see if it is the `Treasury` calling this contract - /// @dev There is no Access Control here, because it can be handled cheaply through this modifier modifier onlyTreasury() { if (msg.sender != treasury) revert NotTreasury(); _; @@ -92,38 +97,16 @@ contract AgToken is IAgToken, ERC20PermitUpgradeable { _; } - // ========================= External Functions ================================ - // The following functions allow anyone to burn stablecoins without redeeming collateral - // in exchange for that - - /// @notice Destroys `amount` token from the caller without giving collateral back - /// @param amount Amount to burn - /// @param poolManager Reference to the `PoolManager` contract for which the `stocksUsers` will - /// need to be updated - /// @dev When calling this function, people should specify the `poolManager` for which they want to decrease - /// the `stocksUsers`: this is a way for the protocol to maintain healthy accounting variables - function burnNoRedeem(uint256 amount, address poolManager) external { - _burn(msg.sender, amount); - IStableMaster(stableMaster).updateStocksUsers(amount, poolManager); - } + // ============================= EXTERNAL FUNCTION ============================= - /// @notice Burns `amount` of agToken on behalf of another account without redeeming collateral back - /// @param account Account to burn on behalf of - /// @param amount Amount to burn - /// @param poolManager Reference to the `PoolManager` contract for which the `stocksUsers` will need to be updated - function burnFromNoRedeem(address account, uint256 amount, address poolManager) external { - _burnFromNoRedeem(amount, account, msg.sender); - IStableMaster(stableMaster).updateStocksUsers(amount, poolManager); - } - - /// @notice Allows anyone to burn agToken without redeeming collateral back + /// @notice Allows anyone to burn stablecoins /// @param amount Amount of stablecoins to burn /// @dev This function can typically be called if there is a settlement mechanism to burn stablecoins function burnStablecoin(uint256 amount) external { _burn(msg.sender, amount); } - // ======================= Minter Role Only Functions ========================== + // ========================= MINTER ROLE ONLY FUNCTIONS ======================== /// @inheritdoc IAgToken function burnSelf(uint256 amount, address burner) external onlyMinter { @@ -132,7 +115,12 @@ contract AgToken is IAgToken, ERC20PermitUpgradeable { /// @inheritdoc IAgToken function burnFrom(uint256 amount, address burner, address sender) external onlyMinter { - _burnFromNoRedeem(amount, burner, sender); + if (burner != sender) { + uint256 currentAllowance = allowance(burner, sender); + if (currentAllowance < amount) revert BurnAmountExceedsAllowance(); + _approve(burner, sender, currentAllowance - amount); + } + _burn(burner, amount); } /// @inheritdoc IAgToken @@ -140,7 +128,7 @@ contract AgToken is IAgToken, ERC20PermitUpgradeable { _mint(account, amount); } - // ======================= Treasury Only Functions ============================= + // ========================== GOVERNANCE ONLY FUNCTIONS ========================== /// @inheritdoc IAgToken function addMinter(address minter) external onlyTreasury { @@ -150,29 +138,14 @@ contract AgToken is IAgToken, ERC20PermitUpgradeable { /// @inheritdoc IAgToken function removeMinter(address minter) external { - // The `treasury` contract cannot remove the `stableMaster` - if (msg.sender != minter && (msg.sender != address(treasury) || minter == stableMaster)) revert InvalidSender(); + if (msg.sender != address(treasury) && msg.sender != minter) revert InvalidSender(); isMinter[minter] = false; emit MinterToggled(minter); } /// @inheritdoc IAgToken - function setTreasury(address _treasury) external onlyTreasury { + function setTreasury(address _treasury) external virtual onlyTreasury { treasury = _treasury; emit TreasuryUpdated(_treasury); } - - // ============================ Internal Function ============================== - - /// @notice Internal version of the function `burnFromNoRedeem` - /// @param amount Amount to burn - /// @dev It is at the level of this function that allowance checks are performed - function _burnFromNoRedeem(uint256 amount, address burner, address sender) internal { - if (burner != sender) { - uint256 currentAllowance = allowance(burner, sender); - if (currentAllowance < amount) revert BurnAmountExceedsAllowance(); - _approve(burner, sender, currentAllowance - amount); - } - _burn(burner, amount); - } } diff --git a/contracts/agToken/AgTokenSideChain.sol b/contracts/agToken/AgTokenSideChain.sol deleted file mode 100644 index bf0c77d5..00000000 --- a/contracts/agToken/AgTokenSideChain.sol +++ /dev/null @@ -1,15 +0,0 @@ -// SPDX-License-Identifier: GPL-3.0 - -pragma solidity ^0.8.12; - -import "./BaseAgTokenSideChain.sol"; - -/// @title AgTokenSideChain -/// @author Angle Labs, Inc. -/// @notice Implementation for Angle agTokens to be deployed on chains where there is no need to support -/// bridging and swapping in and out from other bridge tokens -contract AgTokenSideChain is BaseAgTokenSideChain { - function initialize(string memory name_, string memory symbol_, address _treasury) external { - _initialize(name_, symbol_, _treasury); - } -} diff --git a/contracts/agToken/AgTokenSideChainImmutable.sol b/contracts/agToken/AgTokenSideChainImmutable.sol deleted file mode 100644 index e1d82142..00000000 --- a/contracts/agToken/AgTokenSideChainImmutable.sol +++ /dev/null @@ -1,17 +0,0 @@ -// SPDX-License-Identifier: GPL-3.0 - -pragma solidity ^0.8.17; - -import "./AgTokenSideChain.sol"; - -/// @title AgTokenImmutable -/// @author Angle Labs, Inc. -/// @notice Contract for immutable Angle's stablecoins -contract AgTokenSideChainImmutable is AgTokenSideChain { - constructor(string memory name_, string memory symbol_, address _treasury) AgTokenSideChain() initializer { - _initializeBase(name_, symbol_, _treasury); - } - - /// @inheritdoc BaseAgTokenSideChain - function _initialize(string memory name_, string memory symbol_, address _treasury) internal override {} -} diff --git a/contracts/agToken/AgTokenSideChainMultiBridge.sol b/contracts/agToken/AgTokenSideChainMultiBridge.sol index 9bde501f..5cdb522b 100644 --- a/contracts/agToken/AgTokenSideChainMultiBridge.sol +++ b/contracts/agToken/AgTokenSideChainMultiBridge.sol @@ -2,7 +2,7 @@ pragma solidity ^0.8.12; -import "./BaseAgTokenSideChain.sol"; +import "./AgToken.sol"; import "@openzeppelin/contracts/token/ERC20/IERC20.sol"; import "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol"; @@ -11,16 +11,13 @@ import "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol"; /// @notice Contract for Angle agTokens on other chains than Ethereum mainnet /// @dev This contract supports bridge tokens having a minting right on the stablecoin (also referred to as the canonical /// or the native token) -/// @dev References: -/// - FRAX implementation: https://polygonscan.com/address/0x45c32fA6DF82ead1e2EF74d17b76547EDdFaFF89#code -/// - QiDAO implementation: https://snowtrace.io/address/0x5c49b268c9841AFF1Cc3B0a418ff5c3442eE3F3b#code -contract AgTokenSideChainMultiBridge is BaseAgTokenSideChain { +contract AgTokenSideChainMultiBridge is AgToken { using SafeERC20 for IERC20; /// @notice Base used for fee computation - uint256 public constant BASE_PARAMS = 10 ** 9; + uint256 public constant BASE_PARAMS = 1e9; - // =============================== Bridging Data =============================== + // =============================== BRIDGING DATA =============================== /// @notice Struct with some data about a specific bridge token struct BridgeDetails { @@ -52,7 +49,7 @@ contract AgTokenSideChainMultiBridge is BaseAgTokenSideChain { /// @notice Usage per hour on that chain. Maps an hourly timestamp to the total volume swapped out on the chain mapping(uint256 => uint256) public chainTotalUsage; - // ================================== Events =================================== + // =================================== EVENTS ================================== event BridgeTokenAdded(address indexed bridgeToken, uint256 limit, uint256 hourlyLimit, uint64 fee, bool paused); event BridgeTokenToggled(address indexed bridgeToken, bool toggleStatus); @@ -64,7 +61,7 @@ contract AgTokenSideChainMultiBridge is BaseAgTokenSideChain { event Recovered(address indexed token, address indexed to, uint256 amount); event FeeToggled(address indexed theAddress, uint256 toggleStatus); - // =============================== Errors ================================ + // =================================== ERRORS ================================== error AssetStillControlledInReserves(); error HourlyLimitExceeded(); @@ -75,18 +72,7 @@ contract AgTokenSideChainMultiBridge is BaseAgTokenSideChain { error TooHighParameterValue(); error ZeroAddress(); - // ============================= Constructor =================================== - - /// @notice Initializes the `AgToken` contract - /// @param name_ Name of the token - /// @param symbol_ Symbol of the token - /// @param _treasury Reference to the `Treasury` contract associated to this agToken - /// @dev By default, agTokens are ERC-20 tokens with 18 decimals - function initialize(string memory name_, string memory symbol_, address _treasury) external { - _initialize(name_, symbol_, _treasury); - } - - // =============================== Modifiers =================================== + // ================================= MODIFIERS ================================= /// @notice Checks whether the `msg.sender` has the governor role or not modifier onlyGovernor() { @@ -100,7 +86,7 @@ contract AgTokenSideChainMultiBridge is BaseAgTokenSideChain { _; } - // ==================== External Permissionless Functions ====================== + // ===================== EXTERNAL PERMISSIONLESS FUNCTIONS ===================== /// @notice Returns the list of all supported bridge tokens /// @dev Helpful for UIs @@ -186,7 +172,7 @@ contract AgTokenSideChainMultiBridge is BaseAgTokenSideChain { return bridgeOut; } - // ======================= Governance Functions ================================ + // ============================ GOVERNANCE FUNCTIONS =========================== /// @notice Adds support for a bridge token /// @param bridgeToken Bridge token to add: it should be a version of the stablecoin from another bridge diff --git a/contracts/agToken/BaseAgTokenSideChain.sol b/contracts/agToken/BaseAgTokenSideChain.sol deleted file mode 100644 index 45b966db..00000000 --- a/contracts/agToken/BaseAgTokenSideChain.sol +++ /dev/null @@ -1,165 +0,0 @@ -// SPDX-License-Identifier: GPL-3.0 - -pragma solidity ^0.8.12; - -/* - * █ - ***** ▓▓▓ - * ▓▓▓▓▓▓▓ - * ///. ▓▓▓▓▓▓▓▓▓▓▓▓▓ - ***** //////// ▓▓▓▓▓▓▓ - * ///////////// ▓▓▓ - ▓▓ ////////////////// █ ▓▓ - ▓▓ ▓▓ /////////////////////// ▓▓ ▓▓ - ▓▓ ▓▓ //////////////////////////// ▓▓ ▓▓ - ▓▓ ▓▓ /////////▓▓▓///////▓▓▓///////// ▓▓ ▓▓ - ▓▓ ,////////////////////////////////////// ▓▓ ▓▓ - ▓▓ ////////////////////////////////////////// ▓▓ - ▓▓ //////////////////////▓▓▓▓///////////////////// - ,//////////////////////////////////////////////////// - .////////////////////////////////////////////////////////// - .//////////////////////////██.,//////////////////////////█ - .//////////////////////████..,./////////////////////██ - ...////////////////███████.....,.////////////////███ - ,.,////////////████████ ........,///////////████ - .,.,//////█████████ ,.......///////████ - ,..//████████ ........./████ - ..,██████ .....,███ - .██ ,.,█ - - - - ▓▓ ▓▓▓▓▓▓▓▓▓▓ ▓▓▓▓▓▓▓▓▓▓ ▓▓ ▓▓▓▓▓▓▓▓▓▓ - ▓▓▓▓▓▓ ▓▓▓ ▓▓▓ ▓▓▓ ▓▓ ▓▓ ▓▓▓▓ - ▓▓▓ ▓▓▓ ▓▓▓ ▓▓▓ ▓▓▓ ▓▓▓ ▓▓ ▓▓▓▓▓ - ▓▓▓ ▓▓ ▓▓▓ ▓▓▓ ▓▓▓▓▓▓▓▓▓▓ ▓▓▓▓▓▓▓▓▓▓ ▓▓▓▓▓▓▓▓▓▓ -*/ - -import "../interfaces/IAgToken.sol"; -import "../interfaces/ITreasury.sol"; -import "@openzeppelin/contracts-upgradeable/token/ERC20/extensions/draft-ERC20PermitUpgradeable.sol"; - -/// @title BaseAgTokenSideChain -/// @author Angle Labs, Inc. -/// @notice Base contract for Angle agTokens on Ethereum and on other chains -/// @dev By default, agTokens are ERC-20 tokens with 18 decimals -contract BaseAgTokenSideChain is IAgToken, ERC20PermitUpgradeable { - // =========================== PARAMETERS / VARIABLES ========================== - - /// @inheritdoc IAgToken - mapping(address => bool) public isMinter; - /// @notice Reference to the treasury contract which can grant minting rights - address public treasury; - - // =================================== EVENTS ================================== - - event TreasuryUpdated(address indexed _treasury); - event MinterToggled(address indexed minter); - - // =================================== ERRORS ================================== - - error BurnAmountExceedsAllowance(); - error InvalidSender(); - error InvalidTreasury(); - error NotMinter(); - error NotTreasury(); - - // ================================ CONSTRUCTOR ================================ - - /// @notice Wraps `_initializeBase` for `BaseAgTokenSideChain` and makes a safety check - /// on `_treasury` - function _initialize(string memory name_, string memory symbol_, address _treasury) internal virtual initializer { - if (address(ITreasury(_treasury).stablecoin()) != address(this)) revert InvalidTreasury(); - _initializeBase(name_, symbol_, _treasury); - } - - /// @custom:oz-upgrades-unsafe-allow constructor - constructor() initializer {} - - /// @notice Initializes the contract - /// @param name_ Name of the token - /// @param symbol_ Symbol of the token - /// @param _treasury Reference to the `Treasury` contract associated to this agToken implementation - function _initializeBase(string memory name_, string memory symbol_, address _treasury) internal virtual { - __ERC20Permit_init(name_); - __ERC20_init(name_, symbol_); - treasury = _treasury; - emit TreasuryUpdated(address(_treasury)); - } - - // ================================= MODIFIERS ================================= - - /// @notice Checks to see if it is the `Treasury` calling this contract - /// @dev There is no Access Control here, because it can be handled cheaply through this modifier - modifier onlyTreasury() { - if (msg.sender != address(treasury)) revert NotTreasury(); - _; - } - - /// @notice Checks whether the sender has the minting right - modifier onlyMinter() { - if (!isMinter[msg.sender]) revert NotMinter(); - _; - } - - // ============================= EXTERNAL FUNCTION ============================= - - /// @notice Allows anyone to burn agToken without redeeming collateral back - /// @param amount Amount of stablecoins to burn - /// @dev This function can typically be called if there is a settlement mechanism to burn stablecoins - function burnStablecoin(uint256 amount) external { - _burn(msg.sender, amount); - } - - // ========================= MINTER ROLE ONLY FUNCTIONS ======================== - - /// @inheritdoc IAgToken - function burnSelf(uint256 amount, address burner) external onlyMinter { - _burn(burner, amount); - } - - /// @inheritdoc IAgToken - function burnFrom(uint256 amount, address burner, address sender) external onlyMinter { - _burnFromNoRedeem(amount, burner, sender); - } - - /// @inheritdoc IAgToken - function mint(address account, uint256 amount) external onlyMinter { - _mint(account, amount); - } - - // ========================== TREASURY ONLY FUNCTIONS ========================== - - /// @inheritdoc IAgToken - function addMinter(address minter) external onlyTreasury { - isMinter[minter] = true; - emit MinterToggled(minter); - } - - /// @inheritdoc IAgToken - function removeMinter(address minter) external { - if (msg.sender != address(treasury) && msg.sender != minter) revert InvalidSender(); - isMinter[minter] = false; - emit MinterToggled(minter); - } - - /// @inheritdoc IAgToken - function setTreasury(address _treasury) external virtual onlyTreasury { - treasury = _treasury; - emit TreasuryUpdated(_treasury); - } - - // ============================= INTERNAL FUNCTION ============================= - - /// @notice Internal version of the function `burnFromNoRedeem` - /// @param amount Amount to burn - /// @dev It is at the level of this function that allowance checks are performed - function _burnFromNoRedeem(uint256 amount, address burner, address sender) internal { - if (burner != sender) { - uint256 currentAllowance = allowance(burner, sender); - if (currentAllowance < amount) revert BurnAmountExceedsAllowance(); - _approve(burner, sender, currentAllowance - amount); - } - _burn(burner, amount); - } -} diff --git a/contracts/agToken/layerZero/LayerZeroBridge.sol b/contracts/agToken/layerZero/LayerZeroBridge.sol index 49817ac6..823313c6 100644 --- a/contracts/agToken/layerZero/LayerZeroBridge.sol +++ b/contracts/agToken/layerZero/LayerZeroBridge.sol @@ -20,8 +20,7 @@ contract LayerZeroBridge is OFTCore, PausableUpgradeable { /// @notice Maps an address to the amount of token bridged but not received mapping(address => uint256) public balanceOf; - // ============================= Constructor =================================== - + // ================================ CONSTRUCTOR ================================ /// @notice Initializes the contract /// @param _name Name of the token corresponding to this contract /// @param _lzEndpoint Layer zero endpoint to pass messages @@ -35,7 +34,7 @@ contract LayerZeroBridge is OFTCore, PausableUpgradeable { /// @custom:oz-upgrades-unsafe-allow constructor constructor() initializer {} - // ==================== External Permissionless Functions ====================== + // ===================== EXTERNAL PERMISSIONLESS FUNCTIONS ===================== /// @inheritdoc OFTCore function sendWithPermit( @@ -67,7 +66,7 @@ contract LayerZeroBridge is OFTCore, PausableUpgradeable { return _withdraw(amount, recipient, recipient); } - // ========================== Internal Functions =============================== + // ============================= INTERNAL FUNCTIONS ============================ /// @notice Withdraws `amount` from the balance of the `from` address and sends these tokens to the `to` address /// @dev It's important to make sure that `from` is either the `msg.sender` or that `from` and `to` are the same @@ -105,14 +104,14 @@ contract LayerZeroBridge is OFTCore, PausableUpgradeable { return _amount; } - // ========================= View Functions ==================================== + // =============================== VIEW FUNCTIONS ============================== /// @inheritdoc ERC165Upgradeable function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) { return interfaceId == type(IOFTCore).interfaceId || super.supportsInterface(interfaceId); } - // ======================= Governance Functions ================================ + // ============================ GOVERNANCE FUNCTIONS =========================== /// @notice Pauses bridging through the contract /// @param pause Future pause status diff --git a/contracts/agToken/layerZero/LayerZeroBridgeToken.sol b/contracts/agToken/layerZero/LayerZeroBridgeToken.sol index 2b12f1a4..a24f4d02 100644 --- a/contracts/agToken/layerZero/LayerZeroBridgeToken.sol +++ b/contracts/agToken/layerZero/LayerZeroBridgeToken.sol @@ -15,11 +15,11 @@ contract LayerZeroBridgeToken is OFTCore, ERC20Upgradeable, PausableUpgradeable /// @dev Immutable IAgTokenSideChainMultiBridge public canonicalToken; - // =============================== Errors ================================ + // =================================== ERROR =================================== error InvalidAllowance(); - // ============================= Constructor =================================== + // ================================ CONSTRUCTOR ================================ /// @notice Initializes the contract /// @param _name Name of the token corresponding to this contract @@ -46,7 +46,7 @@ contract LayerZeroBridgeToken is OFTCore, ERC20Upgradeable, PausableUpgradeable /// @custom:oz-upgrades-unsafe-allow constructor constructor() initializer {} - // ==================== External Permissionless Functions ====================== + // ===================== EXTERNAL PERMISSIONLESS FUNCTIONS ===================== /// @inheritdoc OFTCore function sendWithPermit( @@ -76,7 +76,7 @@ contract LayerZeroBridgeToken is OFTCore, ERC20Upgradeable, PausableUpgradeable } } - // ============================= Internal Functions =================================== + // ============================= INTERNAL FUNCTIONS ============================ /// @inheritdoc OFTCore function _debitFrom( @@ -112,7 +112,7 @@ contract LayerZeroBridgeToken is OFTCore, ERC20Upgradeable, PausableUpgradeable } } - // ======================= View Functions ================================ + // =============================== VIEW FUNCTIONS ============================== /// @inheritdoc ERC165Upgradeable function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) { @@ -122,7 +122,7 @@ contract LayerZeroBridgeToken is OFTCore, ERC20Upgradeable, PausableUpgradeable super.supportsInterface(interfaceId); } - // ======================= Governance Functions ================================ + // ============================ GOVERNANCE FUNCTIONS =========================== /// @notice Mints the intermediate contract to the `canonicalToken` /// @dev Used to increase the bridging capacity diff --git a/contracts/deprecated/OldAgEUR.sol b/contracts/deprecated/OldAgEUR.sol new file mode 100644 index 00000000..686c32cd --- /dev/null +++ b/contracts/deprecated/OldAgEUR.sol @@ -0,0 +1,179 @@ +// SPDX-License-Identifier: GPL-3.0 + +pragma solidity ^0.8.12; + +import "../interfaces/IAgToken.sol"; +import "../interfaces/coreModule/IStableMaster.sol"; +import "../interfaces/ITreasury.sol"; +// OpenZeppelin may update its version of the ERC20PermitUpgradeable token +import "@openzeppelin/contracts-upgradeable/token/ERC20/extensions/draft-ERC20PermitUpgradeable.sol"; + +/// @title AgToken +/// @author Angle Labs, Inc. +/// @notice Base contract for agToken, that is to say Angle's stablecoins +/// @dev This contract is used to create and handle the stablecoins of Angle protocol +/// @dev It is still possible for any address to burn its agTokens without redeeming collateral in exchange +/// @dev This contract is the upgraded version of the AgToken that was first deployed on Ethereum mainnet +contract OldAgEUR is IAgToken, ERC20PermitUpgradeable { + // ========================= References to other contracts ===================== + + /// @notice Reference to the `StableMaster` contract associated to this `AgToken` + address public stableMaster; + + // ============================= Constructor =================================== + + /// @notice Initializes the `AgToken` contract + /// @param name_ Name of the token + /// @param symbol_ Symbol of the token + /// @param stableMaster_ Reference to the `StableMaster` contract associated to this agToken + /// @dev By default, agTokens are ERC-20 tokens with 18 decimals + function initialize(string memory name_, string memory symbol_, address stableMaster_) external initializer { + __ERC20Permit_init(name_); + __ERC20_init(name_, symbol_); + require(stableMaster_ != address(0), "0"); + stableMaster = stableMaster_; + } + + /// @custom:oz-upgrades-unsafe-allow constructor + constructor() initializer {} + + // ======= Added Parameters and Variables from the first implementation ======== + + /// @inheritdoc IAgToken + mapping(address => bool) public isMinter; + /// @notice Reference to the treasury contract which can grant minting rights + address public treasury; + /// @notice Boolean to check whether the contract has been reinitialized after its upgrade + bool public treasuryInitialized; + + // =============================== Added Events ================================ + + event TreasuryUpdated(address indexed _treasury); + event MinterToggled(address indexed minter); + + // =============================== Added Errors ================================ + + error BurnAmountExceedsAllowance(); + error InvalidSender(); + error InvalidTreasury(); + error NotGovernor(); + error NotMinter(); + error NotTreasury(); + error TreasuryAlreadyInitialized(); + + // =============================== Setup Function ============================== + + /// @notice Sets up the treasury contract in this AgToken contract + /// @param _treasury Treasury contract to add + /// @dev The address calling this function has to be hard-coded in the contract + /// @dev Can be called only once + function setUpTreasury(address _treasury) external { + // Only governor + if (msg.sender != 0xdC4e6DFe07EFCa50a197DF15D9200883eF4Eb1c8) revert NotGovernor(); + if (address(ITreasury(_treasury).stablecoin()) != address(this)) revert InvalidTreasury(); + if (treasuryInitialized) revert TreasuryAlreadyInitialized(); + treasury = _treasury; + treasuryInitialized = true; + isMinter[stableMaster] = true; + emit TreasuryUpdated(_treasury); + } + + // =============================== Modifiers =================================== + + /// @notice Checks to see if it is the `Treasury` calling this contract + /// @dev There is no Access Control here, because it can be handled cheaply through this modifier + modifier onlyTreasury() { + if (msg.sender != treasury) revert NotTreasury(); + _; + } + + /// @notice Checks whether the sender has the minting right + modifier onlyMinter() { + if (!isMinter[msg.sender]) revert NotMinter(); + _; + } + + // ========================= External Functions ================================ + // The following functions allow anyone to burn stablecoins without redeeming collateral + // in exchange for that + + /// @notice Destroys `amount` token from the caller without giving collateral back + /// @param amount Amount to burn + /// @param poolManager Reference to the `PoolManager` contract for which the `stocksUsers` will + /// need to be updated + /// @dev When calling this function, people should specify the `poolManager` for which they want to decrease + /// the `stocksUsers`: this is a way for the protocol to maintain healthy accounting variables + function burnNoRedeem(uint256 amount, address poolManager) external { + _burn(msg.sender, amount); + IStableMaster(stableMaster).updateStocksUsers(amount, poolManager); + } + + /// @notice Burns `amount` of agToken on behalf of another account without redeeming collateral back + /// @param account Account to burn on behalf of + /// @param amount Amount to burn + /// @param poolManager Reference to the `PoolManager` contract for which the `stocksUsers` will need to be updated + function burnFromNoRedeem(address account, uint256 amount, address poolManager) external { + _burnFromNoRedeem(amount, account, msg.sender); + IStableMaster(stableMaster).updateStocksUsers(amount, poolManager); + } + + /// @notice Allows anyone to burn agToken without redeeming collateral back + /// @param amount Amount of stablecoins to burn + /// @dev This function can typically be called if there is a settlement mechanism to burn stablecoins + function burnStablecoin(uint256 amount) external { + _burn(msg.sender, amount); + } + + // ======================= Minter Role Only Functions ========================== + + /// @inheritdoc IAgToken + function burnSelf(uint256 amount, address burner) external onlyMinter { + _burn(burner, amount); + } + + /// @inheritdoc IAgToken + function burnFrom(uint256 amount, address burner, address sender) external onlyMinter { + _burnFromNoRedeem(amount, burner, sender); + } + + /// @inheritdoc IAgToken + function mint(address account, uint256 amount) external onlyMinter { + _mint(account, amount); + } + + // ======================= Treasury Only Functions ============================= + + /// @inheritdoc IAgToken + function addMinter(address minter) external onlyTreasury { + isMinter[minter] = true; + emit MinterToggled(minter); + } + + /// @inheritdoc IAgToken + function removeMinter(address minter) external { + // The `treasury` contract cannot remove the `stableMaster` + if (msg.sender != minter && (msg.sender != address(treasury) || minter == stableMaster)) revert InvalidSender(); + isMinter[minter] = false; + emit MinterToggled(minter); + } + + /// @inheritdoc IAgToken + function setTreasury(address _treasury) external onlyTreasury { + treasury = _treasury; + emit TreasuryUpdated(_treasury); + } + + // ============================ Internal Function ============================== + + /// @notice Internal version of the function `burnFromNoRedeem` + /// @param amount Amount to burn + /// @dev It is at the level of this function that allowance checks are performed + function _burnFromNoRedeem(uint256 amount, address burner, address sender) internal { + if (burner != sender) { + uint256 currentAllowance = allowance(burner, sender); + if (currentAllowance < amount) revert BurnAmountExceedsAllowance(); + _approve(burner, sender, currentAllowance - amount); + } + _burn(burner, amount); + } +} diff --git a/contracts/interfaces/external/aave/AToken.sol b/contracts/interfaces/external/aave/AToken.sol deleted file mode 100644 index 1ea3c5e5..00000000 --- a/contracts/interfaces/external/aave/AToken.sol +++ /dev/null @@ -1,13 +0,0 @@ -// SPDX-License-Identifier: GPL-3.0 - -pragma solidity ^0.8.12; - -//solhint-disable -interface AToken { - function mint( - address user, - // address onBehalfOf, - uint256 amount, - uint256 index - ) external returns (bool); -} diff --git a/contracts/interfaces/external/aave/ILendingPool.sol b/contracts/interfaces/external/aave/ILendingPool.sol deleted file mode 100644 index af44b156..00000000 --- a/contracts/interfaces/external/aave/ILendingPool.sol +++ /dev/null @@ -1,8 +0,0 @@ -// SPDX-License-Identifier: GPL-3.0 - -pragma solidity ^0.8.12; - -//solhint-disable -interface ILendingPool { - function deposit(address asset, uint256 amount, address onBehalfOf, uint16 referralCode) external; -} diff --git a/contracts/interfaces/external/create2/ImmutableCreate2Factory.sol b/contracts/interfaces/external/create2/ImmutableCreate2Factory.sol new file mode 100644 index 00000000..a4cffdfe --- /dev/null +++ b/contracts/interfaces/external/create2/ImmutableCreate2Factory.sol @@ -0,0 +1,17 @@ +// SPDX-License-Identifier: GPL-3.0 + +pragma solidity ^0.8.12; + +interface ImmutableCreate2Factory { + function safeCreate2(bytes32 salt, bytes memory initCode) external payable returns (address deploymentAddress); + + function findCreate2Address( + bytes32 salt, + bytes calldata initCode + ) external view returns (address deploymentAddress); + + function findCreate2AddressViaHash( + bytes32 salt, + bytes32 initCodeHash + ) external view returns (address deploymentAddress); +} diff --git a/contracts/interfaces/external/euler/IEulerMarket.sol b/contracts/interfaces/external/euler/IEulerMarket.sol deleted file mode 100644 index ba85f453..00000000 --- a/contracts/interfaces/external/euler/IEulerMarket.sol +++ /dev/null @@ -1,294 +0,0 @@ -// SPDX-License-Identifier: MIT -// Forked from https://github.com/euler-xyz/euler-interfaces -pragma solidity >=0.8.12; - -/// @notice Main storage contract for the Euler system -interface IEulerConstants { - /// @notice gives the maxExternalAmount in base 18 - //solhint-disable-next-line - function MAX_SANE_AMOUNT() external view returns (uint256); -} - -/// @notice Main storage contract for the Euler system -interface IEuler { - /// @notice Lookup the current implementation contract for a module - /// @param moduleId Fixed constant that refers to a module type (ie MODULEID__ETOKEN) - /// @return An internal address specifies the module's implementation code - function moduleIdToImplementation(uint256 moduleId) external view returns (address); - - /// @notice Lookup a proxy that can be used to interact with a module (only valid for single-proxy modules) - /// @param moduleId Fixed constant that refers to a module type (ie MODULEID__MARKETS) - /// @return An address that should be cast to the appropriate module interface, ie IEulerMarkets(moduleIdToProxy(2)) - function moduleIdToProxy(uint256 moduleId) external view returns (address); - - /// @notice Euler-related configuration for an asset - struct AssetConfig { - address eTokenAddress; - bool borrowIsolated; - uint32 collateralFactor; - uint32 borrowFactor; - uint24 twapWindow; - } -} - -/// @notice Activating and querying markets, and maintaining entered markets lists -interface IEulerMarkets { - /// @notice Create an Euler pool and associated EToken and DToken addresses. - /// @param underlying The address of an ERC20-compliant token. There must be an initialised uniswap3 pool for the underlying/reference asset pair. - /// @return The created EToken, or the existing EToken if already activated. - function activateMarket(address underlying) external returns (address); - - /// @notice Create a pToken and activate it on Euler. pTokens are protected wrappers around assets that prevent borrowing. - /// @param underlying The address of an ERC20-compliant token. There must already be an activated market on Euler for this underlying, and it must have a non-zero collateral factor. - /// @return The created pToken, or an existing one if already activated. - function activatePToken(address underlying) external returns (address); - - /// @notice Given an underlying, lookup the associated EToken - /// @param underlying Token address - /// @return EToken address, or address(0) if not activated - function underlyingToEToken(address underlying) external view returns (address); - - /// @notice Given an underlying, lookup the associated DToken - /// @param underlying Token address - /// @return DToken address, or address(0) if not activated - function underlyingToDToken(address underlying) external view returns (address); - - /// @notice Given an underlying, lookup the associated PToken - /// @param underlying Token address - /// @return PToken address, or address(0) if it doesn't exist - function underlyingToPToken(address underlying) external view returns (address); - - /// @notice Looks up the Euler-related configuration for a token, and resolves all default-value placeholders to their currently configured values. - /// @param underlying Token address - /// @return Configuration struct - function underlyingToAssetConfig(address underlying) external view returns (IEuler.AssetConfig memory); - - /// @notice Looks up the Euler-related configuration for a token, and returns it unresolved (with default-value placeholders) - /// @param underlying Token address - /// @return config Configuration struct - function underlyingToAssetConfigUnresolved( - address underlying - ) external view returns (IEuler.AssetConfig memory config); - - /// @notice Given an EToken address, looks up the associated underlying - /// @param eToken EToken address - /// @return underlying Token address - function eTokenToUnderlying(address eToken) external view returns (address underlying); - - /// @notice Given an EToken address, looks up the associated DToken - /// @param eToken EToken address - /// @return dTokenAddr DToken address - function eTokenToDToken(address eToken) external view returns (address dTokenAddr); - - /// @notice Looks up an asset's currently configured interest rate model - /// @param underlying Token address - /// @return Module ID that represents the interest rate model (IRM) - function interestRateModel(address underlying) external view returns (uint256); - - /// @notice Retrieves the current interest rate for an asset - /// @param underlying Token address - /// @return The interest rate in yield-per-second, scaled by 10**27 - function interestRate(address underlying) external view returns (int96); - - /// @notice Retrieves the current interest rate accumulator for an asset - /// @param underlying Token address - /// @return An opaque accumulator that increases as interest is accrued - function interestAccumulator(address underlying) external view returns (uint256); - - /// @notice Retrieves the reserve fee in effect for an asset - /// @param underlying Token address - /// @return Amount of interest that is redirected to the reserves, as a fraction scaled by RESERVE_FEE_SCALE (4e9) - function reserveFee(address underlying) external view returns (uint32); - - /// @notice Retrieves the pricing config for an asset - /// @param underlying Token address - /// @return pricingType (1=pegged, 2=uniswap3, 3=forwarded) - /// @return pricingParameters If uniswap3 pricingType then this represents the uniswap pool fee used, otherwise unused - /// @return pricingForwarded If forwarded pricingType then this is the address prices are forwarded to, otherwise address(0) - function getPricingConfig( - address underlying - ) external view returns (uint16 pricingType, uint32 pricingParameters, address pricingForwarded); - - /// @notice Retrieves the list of entered markets for an account (assets enabled for collateral or borrowing) - /// @param account User account - /// @return List of underlying token addresses - function getEnteredMarkets(address account) external view returns (address[] memory); - - /// @notice Add an asset to the entered market list, or do nothing if already entered - /// @param subAccountId 0 for primary, 1-255 for a sub-account - /// @param newMarket Underlying token address - function enterMarket(uint256 subAccountId, address newMarket) external; - - /// @notice Remove an asset from the entered market list, or do nothing if not already present - /// @param subAccountId 0 for primary, 1-255 for a sub-account - /// @param oldMarket Underlying token address - function exitMarket(uint256 subAccountId, address oldMarket) external; -} - -/// @notice Definition of callback method that deferLiquidityCheck will invoke on your contract -interface IDeferredLiquidityCheck { - function onDeferredLiquidityCheck(bytes memory data) external; -} - -/// @notice Batch executions, liquidity check deferrals, and interfaces to fetch prices and account liquidity -interface IEulerExec { - /// @notice Liquidity status for an account, either in aggregate or for a particular asset - struct LiquidityStatus { - uint256 collateralValue; - uint256 liabilityValue; - uint256 numBorrows; - bool borrowIsolated; - } - - /// @notice Aggregate struct for reporting detailed (per-asset) liquidity for an account - struct AssetLiquidity { - address underlying; - LiquidityStatus status; - } - - /// @notice Single item in a batch request - struct EulerBatchItem { - bool allowError; - address proxyAddr; - bytes data; - } - - /// @notice Single item in a batch response - struct EulerBatchItemResponse { - bool success; - bytes result; - } - - /// @notice Compute aggregate liquidity for an account - /// @param account User address - /// @return status Aggregate liquidity (sum of all entered assets) - function liquidity(address account) external returns (LiquidityStatus memory status); - - /// @notice Compute detailed liquidity for an account, broken down by asset - /// @param account User address - /// @return assets List of user's entered assets and each asset's corresponding liquidity - function detailedLiquidity(address account) external returns (AssetLiquidity[] memory assets); - - /// @notice Retrieve Euler's view of an asset's price - /// @param underlying Token address - /// @return twap Time-weighted average price - /// @return twapPeriod TWAP duration, either the twapWindow value in AssetConfig, or less if that duration not available - function getPrice(address underlying) external returns (uint256 twap, uint256 twapPeriod); - - /// @notice Retrieve Euler's view of an asset's price, as well as the current marginal price on uniswap - /// @param underlying Token address - /// @return twap Time-weighted average price - /// @return twapPeriod TWAP duration, either the twapWindow value in AssetConfig, or less if that duration not available - /// @return currPrice The current marginal price on uniswap3 (informational: not used anywhere in the Euler protocol) - function getPriceFull(address underlying) external returns (uint256 twap, uint256 twapPeriod, uint256 currPrice); - - /// @notice Defer liquidity checking for an account, to perform rebalancing, flash loans, etc. msg.sender must implement IDeferredLiquidityCheck - /// @param account The account to defer liquidity for. Usually address(this), although not always - /// @param data Passed through to the onDeferredLiquidityCheck() callback, so contracts don't need to store transient data in storage - function deferLiquidityCheck(address account, bytes memory data) external; - - /// @notice Execute several operations in a single transaction - /// @param items List of operations to execute - /// @param deferLiquidityChecks List of user accounts to defer liquidity checks for - /// @return List of operation results - function batchDispatch( - EulerBatchItem[] calldata items, - address[] calldata deferLiquidityChecks - ) external returns (EulerBatchItemResponse[] memory); - - /// @notice Results of a batchDispatch, but with extra information - struct EulerBatchExtra { - EulerBatchItemResponse[] responses; - uint256 gasUsed; - AssetLiquidity[][] liquidities; - } - - /// @notice Call batchDispatch, but return extra information. Only intended to be used with callStatic. - /// @param items List of operations to execute - /// @param deferLiquidityChecks List of user accounts to defer liquidity checks for - /// @param queryLiquidity List of user accounts to return detailed liquidity information for - /// @return output Structure with extra information - function batchDispatchExtra( - EulerBatchItem[] calldata items, - address[] calldata deferLiquidityChecks, - address[] calldata queryLiquidity - ) external returns (EulerBatchExtra memory output); - - /// @notice Enable average liquidity tracking for your account. Operations will cost more gas, but you may get additional benefits when performing liquidations - /// @param subAccountId subAccountId 0 for primary, 1-255 for a sub-account. - /// @param delegate An address of another account that you would allow to use the benefits of your account's average liquidity (use the null address if you don't care about this). The other address must also reciprocally delegate to your account. - /// @param onlyDelegate Set this flag to skip tracking average liquidity and only set the delegate. - function trackAverageLiquidity(uint256 subAccountId, address delegate, bool onlyDelegate) external; - - /// @notice Disable average liquidity tracking for your account and remove delegate - /// @param subAccountId subAccountId 0 for primary, 1-255 for a sub-account - function unTrackAverageLiquidity(uint256 subAccountId) external; - - /// @notice Retrieve the average liquidity for an account - /// @param account User account (xor in subAccountId, if applicable) - /// @return The average liquidity, in terms of the reference asset, and post risk-adjustment - function getAverageLiquidity(address account) external returns (uint256); - - /// @notice Retrieve the average liquidity for an account or a delegate account, if set - /// @param account User account (xor in subAccountId, if applicable) - /// @return The average liquidity, in terms of the reference asset, and post risk-adjustment - function getAverageLiquidityWithDelegate(address account) external returns (uint256); - - /// @notice Retrieve the account which delegates average liquidity for an account, if set - /// @param account User account (xor in subAccountId, if applicable) - /// @return The average liquidity delegate account - function getAverageLiquidityDelegateAccount(address account) external view returns (address); - - /// @notice Transfer underlying tokens from sender's wallet into the pToken wrapper. Allowance should be set for the euler address. - /// @param underlying Token address - /// @param amount The amount to wrap in underlying units - function pTokenWrap(address underlying, uint256 amount) external; - - /// @notice Transfer underlying tokens from the pToken wrapper to the sender's wallet. - /// @param underlying Token address - /// @param amount The amount to unwrap in underlying units - function pTokenUnWrap(address underlying, uint256 amount) external; -} - -/// @notice Tokenised representation of assets -interface IEulerEToken is IEulerConstants { - /// @notice Pool name, ie "Euler Pool: DAI" - function name() external view returns (string memory); - - /// @notice Pool symbol, ie "eDAI" - function symbol() external view returns (string memory); - - /// @notice Decimals, always normalised to 18. - function decimals() external pure returns (uint8); - - /// @notice Sum of all balances, in internal book-keeping units (non-increasing) - function totalSupply() external view returns (uint256); - - /// @notice Sum of all balances, in underlying units (increases as interest is earned) - function totalSupplyUnderlying() external view returns (uint256); - - /// @notice Balance of a particular account, in internal book-keeping units (non-increasing) - function balanceOf(address account) external view returns (uint256); - - /// @notice Balance of a particular account, in underlying units (increases as interest is earned) - function balanceOfUnderlying(address account) external view returns (uint256); - - /// @notice Balance of the reserves, in internal book-keeping units (non-increasing) - function reserveBalance() external view returns (uint256); - - /// @notice Balance of the reserves, in underlying units (increases as interest is earned) - function reserveBalanceUnderlying() external view returns (uint256); - - /// @notice Updates interest accumulator and totalBorrows, credits reserves, re-targets interest rate, and logs asset status - function touch() external; - - /// @notice Transfer underlying tokens from sender to the Euler pool, and increase account's eTokens - /// @param subAccountId 0 for primary, 1-255 for a sub-account - /// @param amount In underlying units (use max uint256 for full underlying token balance) - function deposit(uint256 subAccountId, uint256 amount) external; - - /// @notice Transfer underlying tokens from Euler pool to sender, and decrease account's eTokens - /// @param subAccountId 0 for primary, 1-255 for a sub-account - /// @param amount In underlying units (use max uint256 for full pool balance) - function withdraw(uint256 subAccountId, uint256 amount) external; -} diff --git a/contracts/mock/MockSidechainAgEUR.sol b/contracts/mock/MockSidechainAgEUR.sol index ba98c3e1..1aa96366 100644 --- a/contracts/mock/MockSidechainAgEUR.sol +++ b/contracts/mock/MockSidechainAgEUR.sol @@ -2,7 +2,7 @@ pragma solidity ^0.8.12; -import "../agToken/BaseAgTokenSideChain.sol"; +import "../agToken/AgToken.sol"; import "@openzeppelin/contracts/token/ERC20/IERC20.sol"; import "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol"; @@ -14,7 +14,7 @@ import "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol"; /// @dev References: /// - FRAX implementation: https://polygonscan.com/address/0x45c32fA6DF82ead1e2EF74d17b76547EDdFaFF89#code /// - QiDAO implementation: https://snowtrace.io/address/0x5c49b268c9841AFF1Cc3B0a418ff5c3442eE3F3b#code -contract MockSidechainAgEUR is BaseAgTokenSideChain { +contract MockSidechainAgEUR is AgToken { using SafeERC20 for IERC20; /// @notice Base used for fee computation @@ -73,17 +73,6 @@ contract MockSidechainAgEUR is BaseAgTokenSideChain { // ============================= Constructor =================================== - /// @notice Initializes the `AgToken` contract - /// @param name_ Name of the token - /// @param symbol_ Symbol of the token - /// @param _treasury Reference to the `Treasury` contract associated to this agToken - /// @dev By default, agTokens are ERC-20 tokens with 18 decimals - function initialize(string memory name_, string memory symbol_, address _treasury) external { - _initialize(name_, symbol_, _treasury); - } - - // =============================== Modifiers =================================== - /// @notice Checks whether the `msg.sender` has the governor role or not modifier onlyGovernor() { if (!ITreasury(treasury).isGovernor(msg.sender)) revert NotGovernor(); diff --git a/contracts/mock/MockTreasuryImmutable.sol b/contracts/mock/MockTreasuryImmutable.sol deleted file mode 100644 index d4fc62e8..00000000 --- a/contracts/mock/MockTreasuryImmutable.sol +++ /dev/null @@ -1,25 +0,0 @@ -// SPDX-License-Identifier: GPL-3.0 - -pragma solidity ^0.8.17; - -import "../treasury/TreasuryImmutable.sol"; - -/// @title Treasury -/// @author Angle Labs, Inc. -/// @notice Mock Immutable Treasury of Angle Borrowing Module -contract MockTreasuryImmutable is TreasuryImmutable { - bytes32 private _MOCK_VAULT_MANAGER_IMPLEMENTATION; - - /// @param _core Address of the `CoreBorrow` contract of the module - constructor(ICoreBorrow _core) TreasuryImmutable(_core) {} - - /// @notice Get the vault manger implementation bytecode hash - function _vaultManagerImpl() internal view override returns (bytes32) { - return _MOCK_VAULT_MANAGER_IMPLEMENTATION; - } - - /// @notice Get the vault manger implementation bytecode hash - function setVaultManagerImpl(bytes32 _newImplemetation) external { - _MOCK_VAULT_MANAGER_IMPLEMENTATION = _newImplemetation; - } -} diff --git a/contracts/mock/MockVaultManagerLiquidationBoostImmutable.sol b/contracts/mock/MockVaultManagerLiquidationBoostImmutable.sol deleted file mode 100644 index 05be1ccc..00000000 --- a/contracts/mock/MockVaultManagerLiquidationBoostImmutable.sol +++ /dev/null @@ -1,37 +0,0 @@ -// SPDX-License-Identifier: GPL-3.0 - -pragma solidity ^0.8.17; - -import "../vaultManager/VaultManagerLiquidationBoostImmutable.sol"; - -/// @title MockCorrectVaultManagerLiquidationBoostImmutable -/// @author Angle Labs, Inc. -/// @notice Mock VaultManagerLiquidationBoostImmutable with slightly different constructor -contract MockCorrectVaultManagerLiquidationBoostImmutable is VaultManagerLiquidationBoostImmutable { - constructor( - ITreasury _treasury, - IERC20 _collateral, - IOracle _oracle, - VaultParameters memory params, - string memory _symbol - ) VaultManagerLiquidationBoostImmutable(_treasury, _collateral, _oracle, params, _symbol) initializer {} -} - -/// @title MockIncorrectVaultManagerLiquidationBoostImmutable -/// @author Angle Labs, Inc. -/// @notice Mock VaultManagerLiquidationBoostImmutable with slightly different implementation -contract MockIncorrectVaultManagerLiquidationBoostImmutable is VaultManagerLiquidationBoostImmutable { - constructor( - ITreasury _treasury, - IERC20 _collateral, - IOracle _oracle, - VaultParameters memory params, - string memory _symbol - ) VaultManagerLiquidationBoostImmutable(_treasury, _collateral, _oracle, params, _symbol) initializer {} - - /// @inheritdoc VaultManagerERC721 - /// @dev this is the function changed - function _whitelistingActivated() internal pure override returns (bool) { - return true; - } -} diff --git a/contracts/oracle/BaseOracleChainlinkOneFeed.sol b/contracts/oracle/BaseOracleChainlinkOneFeed.sol new file mode 100644 index 00000000..b428d357 --- /dev/null +++ b/contracts/oracle/BaseOracleChainlinkOneFeed.sol @@ -0,0 +1,25 @@ +// SPDX-License-Identifier: GPL-3.0 + +pragma solidity ^0.8.12; + +import "@chainlink/contracts/src/v0.8/interfaces/AggregatorV3Interface.sol"; + +import "./BaseOracleChainlinkMulti.sol"; + +/// @title BaseOracleChainlinkOneFeed +/// @author Angle Labs, Inc. +/// @notice Base contract for an oracle that reads into one Chainlink feeds with 8 decimals +abstract contract BaseOracleChainlinkOneFeed is BaseOracleChainlinkMulti { + constructor(uint32 _stalePeriod, address _treasury) BaseOracleChainlinkMulti(_stalePeriod, _treasury) {} + + /// @notice Returns the quote amount of the oracle contract + function _getQuoteAmount() internal view virtual returns (uint256) { + return 10 ** 18; + } + + /// @inheritdoc IOracle + function read() external view virtual override returns (uint256 quoteAmount) { + AggregatorV3Interface[] memory _circuitChainlink = circuitChainlink(); + quoteAmount = _readChainlinkFeed(_getQuoteAmount(), _circuitChainlink[0], 1, 8); + } +} diff --git a/contracts/oracle/OracleChainlinkMultiTemplate.sol b/contracts/oracle/OracleChainlinkMultiTemplate.sol deleted file mode 100644 index 6717db13..00000000 --- a/contracts/oracle/OracleChainlinkMultiTemplate.sol +++ /dev/null @@ -1,53 +0,0 @@ -// SPDX-License-Identifier: GPL-3.0 - -pragma solidity ^0.8.12; - -import "@chainlink/contracts/src/v0.8/interfaces/AggregatorV3Interface.sol"; - -import "./BaseOracleChainlinkMulti.sol"; - -/// @title OracleChainlinkMultiTemplate -/// @author Angle Labs, Inc. -/// @notice Oracle contract, one contract is deployed per collateral/stablecoin pair -/// @dev This contract concerns an oracle that uses Chainlink with multiple pools to read from -/// @dev This is a template and a more gas-efficient implementation of the `OracleChainlinkMulti` contract -contract OracleChainlinkMultiTemplate is BaseOracleChainlinkMulti { - // ===================== To be modified before deployment ====================== - uint256 public constant OUTBASE = 10 ** 18; - string public constant DESCRIPTION = "ETH/EUR Oracle"; - - // ============================================================================= - - /// @notice Constructor for an oracle using Chainlink with multiple pools to read from - /// @param _stalePeriod Minimum feed update frequency for the oracle to not revert - /// @param _treasury Treasury associated to the VaultManager which reads from this feed - constructor(uint32 _stalePeriod, address _treasury) BaseOracleChainlinkMulti(_stalePeriod, _treasury) {} - - // ============================= Reading Oracles =============================== - - function circuitChainlink() public pure override returns (AggregatorV3Interface[] memory) { - AggregatorV3Interface[] memory _circuitChainlink = new AggregatorV3Interface[](2); - _circuitChainlink[0] = AggregatorV3Interface(address(0)); - _circuitChainlink[1] = AggregatorV3Interface(address(0)); - return _circuitChainlink; - } - - /// @inheritdoc IOracle - function read() external view override returns (uint256 quoteAmount) { - quoteAmount = OUTBASE; - // ===================== To be modified before deployment ================== - AggregatorV3Interface[] memory _circuitChainlink = circuitChainlink(); - uint8[2] memory circuitChainIsMultiplied = [0, 0]; - uint8[2] memory chainlinkDecimals = [0, 0]; - // ========================================================================= - uint256 circuitLength = _circuitChainlink.length; - for (uint256 i; i < circuitLength; ++i) { - quoteAmount = _readChainlinkFeed( - quoteAmount, - _circuitChainlink[i], - circuitChainIsMultiplied[i], - chainlinkDecimals[i] - ); - } - } -} diff --git a/contracts/oracle/implementations/mainnet/USD/OracleWSTETHUSDChainlink.sol b/contracts/oracle/implementations/mainnet/USD/OracleWSTETHUSDChainlink.sol new file mode 100644 index 00000000..4c1910c4 --- /dev/null +++ b/contracts/oracle/implementations/mainnet/USD/OracleWSTETHUSDChainlink.sol @@ -0,0 +1,31 @@ +// SPDX-License-Identifier: GPL-3.0 + +pragma solidity ^0.8.12; + +import "@chainlink/contracts/src/v0.8/interfaces/AggregatorV3Interface.sol"; + +import "../../../BaseOracleChainlinkOneFeed.sol"; +import "../../../../interfaces/external/lido/IStETH.sol"; + +/// @title OracleWSTETHUSDChainlink +/// @author Angle Labs, Inc. +/// @notice Gives the price of wSTETH in USD in base 18 +contract OracleWSTETHUSDChainlink is BaseOracleChainlinkOneFeed { + string public constant DESCRIPTION = "wSTETH/USD Oracle"; + IStETH public constant STETH = IStETH(0xae7ab96520DE3A18E5e111B5EaAb095312D7fE84); + + constructor(uint32 _stalePeriod, address _treasury) BaseOracleChainlinkOneFeed(_stalePeriod, _treasury) {} + + /// @inheritdoc IOracle + function circuitChainlink() public pure override returns (AggregatorV3Interface[] memory) { + AggregatorV3Interface[] memory _circuitChainlink = new AggregatorV3Interface[](1); + // Oracle stETH/USD + _circuitChainlink[0] = AggregatorV3Interface(0xCfE54B5cD566aB89272946F602D76Ea879CAb4a8); + return _circuitChainlink; + } + + /// @inheritdoc BaseOracleChainlinkOneFeed + function _getQuoteAmount() internal view override returns (uint256) { + return STETH.getPooledEthByShares(1 ether); + } +} diff --git a/contracts/treasury/TreasuryImmutable.sol b/contracts/treasury/TreasuryImmutable.sol deleted file mode 100644 index 6e033a9b..00000000 --- a/contracts/treasury/TreasuryImmutable.sol +++ /dev/null @@ -1,61 +0,0 @@ -// SPDX-License-Identifier: GPL-3.0 - -pragma solidity ^0.8.17; - -import "./Treasury.sol"; - -/// @title Treasury -/// @author Angle Labs, Inc. -/// @notice Immutable Treasury of Angle Borrowing Module -contract TreasuryImmutable is Treasury { - // =============================== References ================================== - bytes32 private constant _VAULT_MANAGER_IMPL = - hex"fb142eb126393574530347669f9b8d8a8f6a7c6a07d17deccf3b03fe6084e96f"; - - // ======================= Parameters and Variables ============================ - uint8 private _isSetStablecoin; - - // =============================== Errors ====================================== - - error AlreadySetStablecoin(); - error InvalidVaultManager(); - error InvalidStablecoin(); - - /// @param _core Address of the `CoreBorrow` contract of the module - constructor(ICoreBorrow _core) initializer { - if (address(_core) == address(0)) revert ZeroAddress(); - core = _core; - } - - /// @notice Can only be called once after by governance to link the `agToken` to the `treasury` - /// @param _stablecoin Address of the stablecoin - function setStablecoin(IAgToken _stablecoin) public onlyGovernor { - if (_isSetStablecoin == type(uint8).max || IAgToken(_stablecoin).treasury() != address(this)) - revert InvalidStablecoin(); - _isSetStablecoin = type(uint8).max; - stablecoin = _stablecoin; - } - - /// @inheritdoc Treasury - function addVaultManager(address vaultManager) external override onlyGovernor { - if (keccak256(vaultManager.code) != _vaultManagerImpl()) revert InvalidVaultManager(); - _addVaultManager(vaultManager); - } - - /// @notice Get the vault manger implementation bytecode hash - function _vaultManagerImpl() internal view virtual returns (bytes32) { - return _VAULT_MANAGER_IMPL; - } - - /// @inheritdoc Treasury - function initialize(ICoreBorrow _core, IAgToken _stablecoin) public override {} - - /// @inheritdoc Treasury - function addMinter(address minter) external override {} - - /// @inheritdoc Treasury - function removeMinter(address minter) external override {} - - /// @inheritdoc Treasury - function setTreasury(address _treasury) external override {} -} diff --git a/contracts/vaultManager/VaultManagerLiquidationBoostImmutable.sol b/contracts/vaultManager/VaultManagerLiquidationBoostImmutable.sol deleted file mode 100644 index 6db452ec..00000000 --- a/contracts/vaultManager/VaultManagerLiquidationBoostImmutable.sol +++ /dev/null @@ -1,79 +0,0 @@ -// SPDX-License-Identifier: GPL-3.0 - -pragma solidity ^0.8.17; - -import "./VaultManagerLiquidationBoost.sol"; - -/// @title VaultManagerLiquidationBoost -/// @author Angle Labs, Inc. -/// @notice Immutable VaultManagerLiquidationBoost -contract VaultManagerLiquidationBoostImmutable is VaultManagerLiquidationBoost { - constructor( - ITreasury _treasury, - IERC20 _collateral, - IOracle _oracle, - VaultParameters memory params, - string memory _symbol - ) VaultManagerLiquidationBoost() initializer { - _initialize(_treasury, _collateral, _oracle, params, _symbol); - } - - /// @inheritdoc VaultManager - function setUint64(uint64 param, bytes32 what) external override onlyGovernorOrGuardian { - if (what == "CF") { - if (param > liquidationSurcharge) revert TooHighParameterValue(); - collateralFactor = param; - } else if (what == "THF") { - if (param < BASE_PARAMS) revert TooSmallParameterValue(); - targetHealthFactor = param; - } else if (what == "BF") { - if (param > BASE_PARAMS) revert TooHighParameterValue(); - borrowFee = param; - } else if (what == "IR") { - _accrue(); - interestRate = param; - } else if (what == "MLD") { - if (param > BASE_PARAMS) revert TooHighParameterValue(); - maxLiquidationDiscount = param; - } else { - revert InvalidParameterType(); - } - emit FiledUint64(param, what); - } - - /// @inheritdoc VaultManagerERC721 - function _whitelistingActivated() internal pure virtual override returns (bool) { - return false; - } - - /// @inheritdoc VaultManager - function _paused() internal pure override returns (bool) { - return false; - } - - /// @inheritdoc VaultManager - function _repayFee() internal pure override returns (uint64) { - return 0; - } - - /// @inheritdoc VaultManager - function initialize( - ITreasury _treasury, - IERC20 _collateral, - IOracle _oracle, - VaultParameters calldata params, - string memory _symbol - ) external override {} - - /// @inheritdoc VaultManager - function togglePause() external override {} - - /// @inheritdoc VaultManager - function toggleWhitelist(address target) external override {} - - /// @inheritdoc VaultManager - function setOracle(address _oracle) external override {} - - /// @inheritdoc VaultManager - function setTreasury(address _treasury) external override {} -} diff --git a/deploy/6_vaultManagerProxy.ts b/deploy/6_vaultManagerProxy.ts deleted file mode 100644 index 2dc25114..00000000 --- a/deploy/6_vaultManagerProxy.ts +++ /dev/null @@ -1,100 +0,0 @@ -import { ChainId, CONTRACTS_ADDRESSES, registry } from '@angleprotocol/sdk/dist'; -import { SignerWithAddress } from '@nomiclabs/hardhat-ethers/signers'; -import { Contract } from 'ethers'; -import hre from 'hardhat'; -import { DeployFunction } from 'hardhat-deploy/types'; -import yargs from 'yargs'; - -import { expect } from '../test/hardhat/utils/chai-setup'; -import { Treasury__factory, VaultManager__factory } from '../typechain'; -import { deployProxy } from './helpers'; -import params from './networks'; -const argv = yargs.env('').boolean('ci').parseSync(); - -const func: DeployFunction = async ({ deployments, ethers, network }) => { - /** - * TODO: change implementation depending on what is being deployed - */ - const implementationName = 'VaultManager_PermissionedLiquidations_Implementation'; - // const implementation = (await ethers.getContract(implementationName)).address; - const implementation = '0x88fE06D438F5264dA8e2CDCAc3DAED1eA70F995a'; - - const { deploy } = deployments; - const { deployer } = await ethers.getNamedSigners(); - - let proxyAdminAddress: string; - - const json = await import('./networks/' + network.name + '.json'); - const vaultsList = json.vaultsList; - const stableName = 'EUR'; - let treasuryAddress; - - if (!network.live) { - // If we're in mainnet fork, we're using the `ProxyAdmin` address from mainnet - proxyAdminAddress = CONTRACTS_ADDRESSES[ChainId.MAINNET].ProxyAdmin!; - treasuryAddress = registry(ChainId.MAINNET)?.agEUR?.Treasury!; - } else { - // Otherwise, we're using the proxy admin address from the desired network - proxyAdminAddress = (await ethers.getContract('ProxyAdmin')).address; - treasuryAddress = registry(network.config.chainId as ChainId)?.agEUR?.Treasury!; - } - - console.log(`Deploying proxies for the following vaultManager: ${vaultsList}`); - - if (params.stablesParameters[stableName]?.vaultManagers) { - for (const vaultManagerParams of params.stablesParameters[stableName]?.vaultManagers!) { - const collat = vaultManagerParams.symbol.split('-')[0]; - const stable = vaultManagerParams.symbol.split('-')[1]; - if (!vaultsList.includes(collat)) continue; - const name = `VaultManager_${collat}_${stable}`; - const oracle = (await ethers.getContract(`Oracle_${vaultManagerParams.oracle}`)).address; - - console.log('Now deploying the Proxy for:', name); - console.log(`The params for this vaultManager are:`); - console.log(`collateral: ${vaultManagerParams.collateral}`); - console.log(`oracle address: ${oracle}`); - console.log(`symbol: ${vaultManagerParams.symbol}`); - console.log(`debtCeiling: ${vaultManagerParams.params.debtCeiling.toString()}`); - console.log(`collateralFactor: ${vaultManagerParams.params.collateralFactor.toString()}`); - console.log(`targetHealthFactor: ${vaultManagerParams.params.targetHealthFactor.toString()}`); - console.log(`borrowFee: ${vaultManagerParams.params.borrowFee.toString()}`); - console.log(`repayFee: ${vaultManagerParams.params.repayFee.toString()}`); - console.log(`interestRate: ${vaultManagerParams.params.interestRate.toString()}`); - console.log(`liquidationSurcharge: ${vaultManagerParams.params.liquidationSurcharge.toString()}`); - console.log(`maxLiquidationDiscount: ${vaultManagerParams.params.maxLiquidationDiscount.toString()}`); - console.log(`baseBoost: ${vaultManagerParams.params.baseBoost.toString()}`); - console.log(`whitelistingActivated: ${vaultManagerParams.params.whitelistingActivated.toString()}`); - console.log(''); - - const treasury = new Contract(treasuryAddress, Treasury__factory.abi, deployer); - - const callData = new ethers.Contract( - implementation, - VaultManager__factory.createInterface(), - ).interface.encodeFunctionData('initialize', [ - treasury.address, - vaultManagerParams.collateral, - oracle, - vaultManagerParams.params, - vaultManagerParams.symbol, - ]); - await deploy(name, { - contract: 'TransparentUpgradeableProxy', - from: deployer.address, - args: [implementation, proxyAdminAddress, callData], - log: !argv.ci, - }); - - const vaultManagerAddress = (await deployments.get(name)).address; - console.log(`Successfully deployed ${name} at the address ${vaultManagerAddress}`); - console.log(`${vaultManagerAddress} ${implementation} ${proxyAdminAddress} ${callData}`); - console.log(''); - } - } - - console.log('Proxy deployments done'); -}; - -func.tags = ['vaultManagerProxy']; -func.dependencies = ['oracle']; -export default func; diff --git a/deploy/8_governanceSetup.ts b/deploy/8_governanceSetup.ts deleted file mode 100644 index e52fca14..00000000 --- a/deploy/8_governanceSetup.ts +++ /dev/null @@ -1,54 +0,0 @@ -import { ChainId, CONTRACTS_ADDRESSES } from '@angleprotocol/sdk'; -import { SignerWithAddress } from '@nomiclabs/hardhat-ethers/signers'; -import hre from 'hardhat'; -import { DeployFunction } from 'hardhat-deploy/types'; - -import { ProxyAdmin, ProxyAdmin__factory, Treasury, Treasury__factory } from '../typechain'; -import params from './networks'; - -const func: DeployFunction = async ({ deployments, ethers, network }) => { - // This file is only useful in mainnet fork - const json = await import('./networks/' + network.name + '.json'); - const governor = json.governor; - let proxyAdminAddress: string; - let agTokenAddress: string; - let proxyAdmin: ProxyAdmin; - let treasuryContract: Treasury; - let signer: SignerWithAddress; - const stableName = 'GOLD'; - - if (!network.live) { - proxyAdminAddress = CONTRACTS_ADDRESSES[ChainId.MAINNET].ProxyAdmin!; - await hre.network.provider.request({ - method: 'hardhat_impersonateAccount', - params: [governor], - }); - await hre.network.provider.send('hardhat_setBalance', [governor, '0x10000000000000000000000000000']); - signer = await ethers.getSigner(governor); - agTokenAddress = (await deployments.get(`AgToken_${stableName}`)).address; - - const vaultsList = json.vaultsList; - proxyAdmin = new ethers.Contract(proxyAdminAddress, ProxyAdmin__factory.createInterface(), signer) as ProxyAdmin; - const treasury = await deployments.get(`Treasury_${stableName}`); - treasuryContract = new ethers.Contract(treasury.address, Treasury__factory.createInterface(), signer) as Treasury; - console.log('Setting new vaultManager contracts on the treasury'); - - if (params.stablesParameters[stableName].vaultManagers) { - for (const vaultManagerParams of params.stablesParameters[stableName]?.vaultManagers!) { - const collat = vaultManagerParams.symbol.split('-')[0]; - const stable = vaultManagerParams.symbol.split('-')[1]; - if (!vaultsList.includes(collat)) continue; - const name = `VaultManager_${collat}_${stable}`; - const vaultManagerAddress = (await deployments.get(name)).address; - console.log(`Now setting ${name} ...`); - await (await treasuryContract.connect(signer).addVaultManager(vaultManagerAddress)).wait(); - console.log(`Success`); - console.log(''); - } - } - } -}; - -func.tags = ['governanceSetup']; -func.dependencies = ['vaultManagerProxy']; -export default func; diff --git a/deploy/9_governanceUnpausing.ts b/deploy/9_governanceUnpausing.ts deleted file mode 100644 index 7ffad567..00000000 --- a/deploy/9_governanceUnpausing.ts +++ /dev/null @@ -1,69 +0,0 @@ -import { ChainId, CONTRACTS_ADDRESSES } from '@angleprotocol/sdk'; -import { SignerWithAddress } from '@nomiclabs/hardhat-ethers/signers'; -import { formatBytes32String, parseEther } from 'ethers/lib/utils'; -import hre from 'hardhat'; -import { DeployFunction } from 'hardhat-deploy/types'; - -import { VaultManager, VaultManager__factory } from '../typechain'; -import params from './networks'; - -const func: DeployFunction = async ({ deployments, ethers, network }) => { - const json = await import('./networks/' + network.name + '.json'); - const vaultsList = json.vaultsList; - const governor = json.governor; - let agTokenAddress: string; - let signer: SignerWithAddress; - const stableName = 'GOLD'; - - if (!network.live) { - // If we're in mainnet fork, we're using the `ProxyAdmin` address from mainnet - await hre.network.provider.request({ - method: 'hardhat_impersonateAccount', - params: [governor], - }); - await hre.network.provider.send('hardhat_setBalance', [governor, '0x10000000000000000000000000000']); - signer = await ethers.getSigner(governor); - agTokenAddress = CONTRACTS_ADDRESSES[ChainId.MAINNET].agEUR?.AgToken!; - - console.log('Unpausing vaultManager contracts'); - - if (params.stablesParameters[stableName].vaultManagers) { - for (const vaultManagerParams of params.stablesParameters[stableName]?.vaultManagers!) { - const collat = vaultManagerParams.symbol.split('-')[0]; - const stable = vaultManagerParams.symbol.split('-')[1]; - if (!vaultsList.includes(collat)) continue; - const name = `VaultManager_${collat}_${stable}`; - - const vaultManagerAddress = (await deployments.get(name)).address; - console.log('Now unpausing:', name); - const vaultManager = (await new ethers.Contract( - vaultManagerAddress, - VaultManager__factory.createInterface(), - signer, - )) as VaultManager; - await (await vaultManager.togglePause()).wait(); - console.log('Success'); - - // Set borrowFee and repayFee if needed - if (!vaultManagerParams.params.borrowFee.isZero()) { - await (await vaultManager.setUint64(vaultManagerParams.params.borrowFee, formatBytes32String('BF'))).wait(); - console.log(`BorrowFee of ${vaultManagerParams.params.borrowFee} set successfully`); - } - if (!vaultManagerParams.params.repayFee.isZero()) { - await (await vaultManager.setUint64(vaultManagerParams.params.repayFee, formatBytes32String('RF'))).wait(); - console.log(`RepayFee of ${vaultManagerParams.params.repayFee} set successfully`); - } - console.log('Setting dusts'); - // if gold: 2 XAU is like 4k agEUR - await (await vaultManager.setDusts(0, parseEther('4'), parseEther('4'))).wait(); - console.log('Success'); - console.log(''); - } - } - console.log('Success, all desired vaultManager contracts have been unpaused and fees have been set'); - } -}; - -func.tags = ['unpausing']; -func.dependencies = ['governanceSetup']; -export default func; diff --git a/deploy/agTokenUpgrade.ts b/deploy/agTokenUpgrade.ts deleted file mode 100644 index a5d15233..00000000 --- a/deploy/agTokenUpgrade.ts +++ /dev/null @@ -1,100 +0,0 @@ -import yargs from 'yargs'; -import { DeployFunction } from 'hardhat-deploy/types'; -import { ChainId, CONTRACTS_ADDRESSES } from '@angleprotocol/sdk'; -import { SignerWithAddress } from '@nomiclabs/hardhat-ethers/signers'; -import { - AgTokenIntermediateUpgrade, - AgTokenIntermediateUpgrade__factory, - ProxyAdmin, - ProxyAdmin__factory, -} from '../typechain'; -import { parseEther } from 'ethers/lib/utils'; -import hre from 'hardhat'; -const argv = yargs.env('').boolean('ci').parseSync(); - -const func: DeployFunction = async ({ deployments, ethers, network }) => { - // Deployment script for agToken upgrade - const { deploy } = deployments; - const { deployer } = await ethers.getNamedSigners(); - - let implementationName: string; - let proxyAdmin: ProxyAdmin; - let agToken: AgTokenIntermediateUpgrade; - let signer: SignerWithAddress; - - implementationName = 'AgTokenIntermediateUpgrade'; - - console.log('Now deploying the implementation for the upgraded AgToken'); - await deploy(`${implementationName}_Implementation`, { - contract: implementationName, - from: deployer.address, - log: !argv.ci, - }); - const agTokenImplementation = (await ethers.getContract(`${implementationName}_Implementation`)).address; - - console.log(`Successfully deployed the implementation for AgTokenUpgrade at ${agTokenImplementation}`); - console.log(''); - - // ------------------------------------------------------------------------------ - // ------------------------------ MAINNET FORK ---------------------------------- - // ------------------------------------------------------------------------------ - - if (!network.live) { - // https://docs.euler.finance/developers/integration-guide#deposit-and-withdraw - const governor = '0xdc4e6dfe07efca50a197df15d9200883ef4eb1c8'; - const eulerMainnet = '0x27182842E098f60e3D576794A5bFFb0777E025d3'; - const eulerMarkets = '0x3520d5a913427E6F0D6A83E07ccD4A4da316e4d3'; - await hre.network.provider.request({ - method: 'hardhat_impersonateAccount', - params: [governor], - }); - await hre.network.provider.send('hardhat_setBalance', [governor, '0x10000000000000000000000000000']); - signer = await ethers.getSigner(governor); - - const proxyAdminAddress = CONTRACTS_ADDRESSES[ChainId.MAINNET].ProxyAdmin!; - const agTokenAddress = CONTRACTS_ADDRESSES[ChainId.MAINNET].agEUR?.AgToken!; - proxyAdmin = new ethers.Contract(proxyAdminAddress, ProxyAdmin__factory.createInterface(), signer) as ProxyAdmin; - - // We're just upgrading the agToken in mainnet fork - console.log('Upgrading AgToken'); - await (await proxyAdmin.connect(signer).upgrade(agTokenAddress, agTokenImplementation)).wait(); - console.log('Success'); - console.log(''); - agToken = new ethers.Contract( - agTokenAddress, - AgTokenIntermediateUpgrade__factory.createInterface(), - signer, - ) as AgTokenIntermediateUpgrade; - - console.log('Setting up the minter role on the agToken'); - await (await agToken.connect(signer).setUpMinter()).wait(); - console.log('Success'); - console.log(''); - console.log('Now minting agToken'); - await (await agToken.connect(signer).mint(governor, parseEther('1000000'))).wait(); - console.log('Success'); - console.log('Approving Euler Market'); - await (await agToken.connect(signer).approve(eulerMainnet, parseEther('1000000'))).wait(); - console.log('Success'); - const eulerMarketsInterface = new ethers.utils.Interface([ - 'function underlyingToEToken(address token) external view returns(address)', - ]); - console.log('Etoken address'); - const eulerMarketsContract = new ethers.Contract(eulerMarkets, eulerMarketsInterface, signer); - const eToken = await eulerMarketsContract.underlyingToEToken(agTokenAddress); - console.log(eToken); - const eTokenInterface = new ethers.utils.Interface([ - 'function deposit(uint256 account, uint256 amount) external', - 'function balanceOf(address who) external view returns(uint256)', - ]); - console.log('Now proceeding with the deposit'); - const eTokenContract = new ethers.Contract(eToken, eTokenInterface, signer); - await (await eTokenContract.connect(signer).deposit(0, parseEther('1000000'))).wait(); - console.log('Success'); - console.log('Balance'); - console.log((await eTokenContract.balanceOf(governor)).toString()); - } -}; - -func.tags = ['agTokenUpgrade']; -export default func; diff --git a/deploy/bridges/LayerZeroSetSources.ts b/deploy/bridges/LayerZeroSetSources.ts index 2615b636..6e55e56b 100644 --- a/deploy/bridges/LayerZeroSetSources.ts +++ b/deploy/bridges/LayerZeroSetSources.ts @@ -2,37 +2,24 @@ import { Contract } from 'ethers'; import { DeployFunction } from 'hardhat-deploy/types'; import { LayerZeroBridge, LayerZeroBridge__factory } from '../../typechain'; +import { OFTs } from '../constants/constants'; import LZ_CHAINIDS from '../constants/layerzeroChainIds.json'; // For more details on trustedRemote, check: https://layerzero.gitbook.io/docs/evm-guides/master/set-trusted-remotes // LayerZero chains: https://layerzero.gitbook.io/docs/technical-reference/mainnet/supported-chain-ids const func: DeployFunction = async ({ ethers, network }) => { const { deployer } = await ethers.getNamedSigners(); + const stableName = 'EUR'; - const OFTs: { [string: string]: string } = { - polygon: '0x0c1EBBb61374dA1a8C57cB6681bF27178360d36F', - optimism: '0x840b25c87B626a259CA5AC32124fA752F0230a72', - arbitrum: '0x16cd38b1B54E7abf307Cb2697E2D9321e843d5AA', - mainnet: '0x4Fa745FCCC04555F2AFA8874cd23961636CdF982', - avalanche: '0x14C00080F97B9069ae3B4Eb506ee8a633f8F5434', - bsc: '0xe9f183FC656656f1F17af1F2b0dF79b8fF9ad8eD', - celo: '0xf1dDcACA7D17f8030Ab2eb54f2D9811365EFe123', - gnosis: '0xFA5Ed56A203466CbBC2430a43c66b9D8723528E7', - polygonzkevm: '0x2859a4eBcB58c8Dd5cAC1419C4F63A071b642B20', - base: '0x2859a4eBcB58c8Dd5cAC1419C4F63A071b642B20', - linea: '0x12f31B73D812C6Bb0d735a218c086d44D5fe5f89', - mantle: '0x2859a4eBcB58c8Dd5cAC1419C4F63A071b642B20', - }; - - const local = OFTs[network.name]; + const local = OFTs[stableName][network.name]; const contractAngleOFT = new Contract(local, LayerZeroBridge__factory.abi, deployer) as LayerZeroBridge; console.log('Getting payloads to execute on the new chain'); console.log('--------------------------------------------'); - for (const chain of Object.keys(OFTs)) { + for (const chain of Object.keys(OFTs[stableName])) { if (chain !== network.name) { console.log(chain); - const trustedRemote = ethers.utils.solidityPack(['address', 'address'], [OFTs[chain], local]); + const trustedRemote = ethers.utils.solidityPack(['address', 'address'], [OFTs[stableName][chain], local]); console.log(`Trusted remote ${trustedRemote}`); console.log(local); console.log( @@ -48,12 +35,12 @@ const func: DeployFunction = async ({ ethers, network }) => { /* console.log('Getting payloads to execute on all the other chains'); console.log('--------------------------------------------'); - for (const chain of Object.keys(OFTs)) { + for (const chain of Object.keys(OFTs[stableName])) { if (chain !== network.name) { console.log(chain); - const trustedRemote = ethers.utils.solidityPack(['address', 'address'], [local, OFTs[chain]]); + const trustedRemote = ethers.utils.solidityPack(['address', 'address'], [local, OFTs[stableName][chain]]); console.log(`Trusted remote ${trustedRemote}`); - console.log(OFTs[chain]); + console.log(OFTs[stableName][chain]); console.log( contractAngleOFT.interface.encodeFunctionData('setTrustedRemote', [ (LZ_CHAINIDS as any)[network.name], diff --git a/deploy/constants/constants.ts b/deploy/constants/constants.ts new file mode 100644 index 00000000..2653fed7 --- /dev/null +++ b/deploy/constants/constants.ts @@ -0,0 +1,80 @@ +import { ChainId } from '@angleprotocol/sdk/dist'; +import { BigNumber } from 'ethers'; +import { parseEther } from 'ethers/lib/utils'; + +import { parseAmount } from '../../utils/bignumber'; +// Mined address for the stablecoin +export const minedAddress = '0x0000206329b97DB379d5E1Bf586BbDB969C63274'; +export const stableName = 'USD'; +export const vaultsList = ['wstETH']; +export const forkedChain = ChainId.MAINNET; +export const forkedChainName = 'mainnet'; + +export const immutableCreate2Factory = '0x0000000000FFe8B47B3e2130213B802212439497'; + +export const OFTs: OFTsStructure = { + EUR: { + polygon: '0x0c1EBBb61374dA1a8C57cB6681bF27178360d36F', + optimism: '0x840b25c87B626a259CA5AC32124fA752F0230a72', + arbitrum: '0x16cd38b1B54E7abf307Cb2697E2D9321e843d5AA', + mainnet: '0x4Fa745FCCC04555F2AFA8874cd23961636CdF982', + avalanche: '0x14C00080F97B9069ae3B4Eb506ee8a633f8F5434', + bsc: '0xe9f183FC656656f1F17af1F2b0dF79b8fF9ad8eD', + celo: '0xf1dDcACA7D17f8030Ab2eb54f2D9811365EFe123', + gnosis: '0xFA5Ed56A203466CbBC2430a43c66b9D8723528E7', + polygonzkevm: '0x2859a4eBcB58c8Dd5cAC1419C4F63A071b642B20', + base: '0x2859a4eBcB58c8Dd5cAC1419C4F63A071b642B20', + linea: '0x12f31B73D812C6Bb0d735a218c086d44D5fe5f89', + mantle: '0x2859a4eBcB58c8Dd5cAC1419C4F63A071b642B20', + }, + USD: { + arbitrum: '0x8f4245D2eFEC45aF24E5Fa35f07172a830Fc0aDE', + avalanche: '0xC492fBAe68cE6C5E14C7ed5cd8a59babD5c90e4C', + base: '0x1A42a30dCbA20A22b69C40098d89cB7304f429B9', + bsc: '0x52F0C256E58c579Bf9E41e4332669b4f7C7209c5', + celo: '0xdD6A0A00fE3353e813F3B3864694D55D2a7cE11C', + gnosis: '0x4DD4758F594B60551dC64f30289204D34cCd077D', + linea: '0x07C89CC845D046aEad377DddC61114AA9D920Ac0', + mainnet: '0xEc0B13b2271E212E1a74D55D51932BD52A002961', + optimism: '0xc69e66109943fAF5Cbda22F360b7eB7c27Bb5C88', + polygon: '0xe70575daaB2B1b3fa9658fa76cC506fcB0007169', + polygonzkevm: '0x1E5B48c08D6b5efE0792d04f27602bD90026514a', + }, +}; + +interface CurrencyNetworkAddresses { + [network: string]: string; +} + +interface OFTsStructure { + [currency: string]: CurrencyNetworkAddresses; +} + +export const interestRate5 = BigNumber.from('1547125982881425408'); + +export const vaultManagers = { + USD: { + vaults: [ + { + collateral: '0x7f39C581F595B53c5cb19bD0b3f8dA6c935E2Ca0', + symbol: 'wstETH-USD', + oracle: 'WSTETH_USD', + params: { + debtCeiling: parseEther('1000'), + collateralFactor: parseAmount.gwei('0.75'), + targetHealthFactor: parseAmount.gwei('1.05'), + borrowFee: parseAmount.gwei('0'), + repayFee: parseAmount.gwei('0'), + interestRate: interestRate5, + liquidationSurcharge: parseAmount.gwei('0.98'), + maxLiquidationDiscount: parseAmount.gwei('0.1'), + whitelistingActivated: false, + baseBoost: parseAmount.gwei('1.5'), + dust: parseEther('0'), + dustCollateral: parseEther('0'), + dustLiquidation: parseEther('10'), + }, + }, + ], + }, +}; diff --git a/deploy/coreMerkl.ts b/deploy/coreMerkl.ts deleted file mode 100644 index 441e6ab7..00000000 --- a/deploy/coreMerkl.ts +++ /dev/null @@ -1,64 +0,0 @@ -import { ChainId, CONTRACTS_ADDRESSES, registry } from '@angleprotocol/sdk'; -import { DeployFunction } from 'hardhat-deploy/types'; -import yargs from 'yargs'; - -import { expect } from '../test/hardhat/utils/chai-setup'; -import { CoreBorrow__factory } from '../typechain'; -const argv = yargs.env('').boolean('ci').parseSync(); - -const func: DeployFunction = async ({ deployments, ethers, network }) => { - const { deploy } = deployments; - const { deployer } = await ethers.getNamedSigners(); - const json = await import('./networks/' + network.name + '.json'); - const angleLabs = json.angleLabs; - const guardian = json.guardian; - let proxyAdmin: string; - let implementation: string; - console.log('Let us get started with deployment'); - if (!network.live || network.config.chainId === ChainId.MAINNET) { - // If we're in mainnet fork, we're using the `ProxyAdmin` address from mainnet - proxyAdmin = CONTRACTS_ADDRESSES[ChainId.MAINNET]?.ProxyAdminGuardian!; - implementation = '0x4D144B7355bC2C33FA091339279e9D77261461fE'; - } else { - // Otherwise, we're using the proxy admin address from the desired network - proxyAdmin = registry(network.config.chainId as ChainId)?.ProxyAdminGuardian!; - try { - implementation = (await deployments.get('CoreBorrow_Implementation')).address; - } catch { - console.log('Now deploying the implementation for CoreBorrow'); - await deploy('CoreBorrow_Implementation', { - contract: 'CoreBorrow', - from: deployer.address, - log: !argv.ci, - }); - console.log(''); - implementation = (await ethers.getContract('CoreBorrow_Implementation')).address; - } - } - - proxyAdmin = '0xE6d9bD6796bDAF9B391Fac2A2D34bAE9c1c3c1C4'; - - const coreBorrowInterface = CoreBorrow__factory.createInterface(); - const dataCoreBorrow = new ethers.Contract(implementation, coreBorrowInterface).interface.encodeFunctionData( - 'initialize', - [angleLabs, guardian], - ); - - console.log('Now deploying the Proxy'); - console.log('The contract will be initialized with the following governor and guardian addresses'); - console.log(angleLabs, guardian); - console.log(`The proxyAdmin address is ${proxyAdmin}`); - - await deploy('CoreMerkl', { - contract: 'TransparentUpgradeableProxy', - from: deployer.address, - args: [implementation, proxyAdmin, dataCoreBorrow], - log: !argv.ci, - }); - - const coreMerkl = (await deployments.get('CoreMerkl')).address; - console.log(`Successfully deployed CoreMerkl at the address ${coreMerkl}`); -}; - -func.tags = ['coreMerkl']; -export default func; diff --git a/deploy/flashAngle.ts b/deploy/flashloan/0_flashAngle.ts similarity index 95% rename from deploy/flashAngle.ts rename to deploy/flashloan/0_flashAngle.ts index 3a1e09ee..84d389f9 100644 --- a/deploy/flashAngle.ts +++ b/deploy/flashloan/0_flashAngle.ts @@ -2,8 +2,8 @@ import { ChainId, CONTRACTS_ADDRESSES } from '@angleprotocol/sdk'; import { DeployFunction } from 'hardhat-deploy/types'; import yargs from 'yargs'; -import { expect } from '../test/hardhat/utils/chai-setup'; -import { FlashAngle__factory } from '../typechain'; +import { expect } from '../../test/hardhat/utils/chai-setup'; +import { FlashAngle__factory } from '../../typechain'; const argv = yargs.env('').boolean('ci').parseSync(); const func: DeployFunction = async ({ deployments, ethers, network }) => { diff --git a/deploy/flashAngleGovernance.ts b/deploy/flashloan/1_flashAngleGovernance.ts similarity index 68% rename from deploy/flashAngleGovernance.ts rename to deploy/flashloan/1_flashAngleGovernance.ts index 44ba580b..4bcffcfa 100644 --- a/deploy/flashAngleGovernance.ts +++ b/deploy/flashloan/1_flashAngleGovernance.ts @@ -2,6 +2,7 @@ import { ChainId, CONTRACTS_ADDRESSES } from '@angleprotocol/sdk'; import { SignerWithAddress } from '@nomiclabs/hardhat-ethers/signers'; import hre from 'hardhat'; import { DeployFunction } from 'hardhat-deploy/types'; + import { CoreBorrow, CoreBorrow__factory, @@ -11,8 +12,15 @@ import { ProxyAdmin__factory, Treasury, Treasury__factory, -} from '../typechain'; -import params from './networks'; +} from '../../typechain'; +import { parseAmount } from '../../utils/bignumber'; + +const flashLoanParams = { + // 3m at the moment, should not be too big with respect to the total agEUR in circulation + maxBorrowable: parseAmount.ether('300000'), + // Free flash loans for agEUR + flashLoanFee: parseAmount.gwei('0'), +}; const func: DeployFunction = async ({ deployments, ethers, network }) => { const { deployer } = await ethers.getNamedSigners(); @@ -57,34 +65,28 @@ const func: DeployFunction = async ({ deployments, ethers, network }) => { ) as CoreBorrow; console.log('Setting up the flash loan module parameter'); - if (params.stablesParameters.EUR.flashloan) { - const flashLoanParams = params.stablesParameters.EUR.flashloan; - const flashAngleAddress = await deployments.get('FlashAngle'); - flashAngle = (await new ethers.Contract( - flashAngleAddress.address, - FlashAngle__factory.createInterface(), - signer, - )) as FlashAngle; - console.log('Setting up the flashAngle on the coreBorrow'); - await (await coreBorrow.setFlashLoanModule(flashAngle.address)).wait(); - console.log('Success'); - console.log(''); + const flashAngleAddress = await deployments.get('FlashAngle'); + flashAngle = (await new ethers.Contract( + flashAngleAddress.address, + FlashAngle__factory.createInterface(), + signer, + )) as FlashAngle; + + console.log('Setting up the flashAngle on the coreBorrow'); + await (await coreBorrow.setFlashLoanModule(flashAngle.address)).wait(); + console.log('Success'); + console.log(''); - console.log('Setting up the treasury on the flashAngle'); - await (await coreBorrow.connect(signer).addFlashLoanerTreasuryRole(treasury.address)).wait(); - console.log('Success'); - console.log(''); + console.log('Setting up the treasury on the flashAngle'); + await (await coreBorrow.connect(signer).addFlashLoanerTreasuryRole(treasury.address)).wait(); + console.log('Success'); + console.log(''); - console.log('Setting up flash loan parameters'); - await ( - await flashAngle.setFlashLoanParameters( - agTokenAddress, - flashLoanParams.flashLoanFee, - flashLoanParams.maxBorrowable, - ) - ).wait(); - } + console.log('Setting up flash loan parameters'); + await ( + await flashAngle.setFlashLoanParameters(agTokenAddress, flashLoanParams.flashLoanFee, flashLoanParams.maxBorrowable) + ).wait(); console.log('Success'); console.log(''); }; diff --git a/deploy/helpers.ts b/deploy/helpers.ts index ef3e2373..84402ef2 100644 --- a/deploy/helpers.ts +++ b/deploy/helpers.ts @@ -76,7 +76,7 @@ export const deployProxy = async ( }); address = (await ethers.getContract(deploymentName)).address; - console.log(`Successfully deployed the implementation for ${deploymentName} at ${address}`); + console.log(`Successfully deployed the proxy for ${deploymentName} at ${address}`); } return address; }; diff --git a/deploy/keeperMulticall.ts b/deploy/keeper/keeperMulticall.ts similarity index 96% rename from deploy/keeperMulticall.ts rename to deploy/keeper/keeperMulticall.ts index f288addd..1864d48e 100644 --- a/deploy/keeperMulticall.ts +++ b/deploy/keeper/keeperMulticall.ts @@ -1,7 +1,7 @@ import { ChainId, CONTRACTS_ADDRESSES } from '@angleprotocol/sdk'; import { DeployFunction } from 'hardhat-deploy/types'; -import { KeeperMulticall__factory } from '../typechain'; +import { KeeperMulticall__factory } from '../../typechain'; const func: DeployFunction = async ({ deployments, ethers, network }) => { const { deploy } = deployments; diff --git a/deploy/keeperRegistry.ts b/deploy/keeper/keeperRegistry.ts similarity index 96% rename from deploy/keeperRegistry.ts rename to deploy/keeper/keeperRegistry.ts index 551e1803..1ec0344d 100644 --- a/deploy/keeperRegistry.ts +++ b/deploy/keeper/keeperRegistry.ts @@ -1,7 +1,7 @@ import { ChainId, CONTRACTS_ADDRESSES } from '@angleprotocol/sdk'; import { DeployFunction } from 'hardhat-deploy/types'; -import { KeeperRegistry__factory } from '../typechain'; +import { KeeperRegistry__factory } from '../../typechain'; const func: DeployFunction = async ({ deployments, ethers, network }) => { const { deploy } = deployments; diff --git a/deploy/multicallWithFailure.ts b/deploy/keeper/multicallWithFailure.ts similarity index 100% rename from deploy/multicallWithFailure.ts rename to deploy/keeper/multicallWithFailure.ts diff --git a/deploy/ui-helpers.ts b/deploy/keeper/ui-helpers.ts similarity index 96% rename from deploy/ui-helpers.ts rename to deploy/keeper/ui-helpers.ts index 6d219ce9..b60b8929 100644 --- a/deploy/ui-helpers.ts +++ b/deploy/keeper/ui-helpers.ts @@ -1,7 +1,7 @@ import { ChainId, CONTRACTS_ADDRESSES } from '@angleprotocol/sdk'; import { DeployFunction } from 'hardhat-deploy/types'; -import { AngleHelpers__factory } from '../typechain'; +import { AngleHelpers__factory } from '../../typechain'; const func: DeployFunction = async ({ deployments, ethers, network }) => { const { deploy } = deployments; diff --git a/deploy/networks/index.ts b/deploy/networks/index.ts deleted file mode 100644 index 3115931b..00000000 --- a/deploy/networks/index.ts +++ /dev/null @@ -1,4 +0,0 @@ -import { ChainId, CONSTANTS } from '@angleprotocol/sdk'; -import { network } from 'hardhat'; - -export default CONSTANTS((network.config.chainId == 1337 ? 1 : network.config.chainId) as ChainId); diff --git a/deploy/networks/mainnet.json b/deploy/networks/mainnet.json index c4c0b859..ef4335e3 100644 --- a/deploy/networks/mainnet.json +++ b/deploy/networks/mainnet.json @@ -9,5 +9,5 @@ "oneInchRouter": "0x1111111254EEB25477B68fb85Ed929f73A960582", "angleRouter": "0xBB755240596530be0c1DE5DFD77ec6398471561d", "dust": "0", - "vaultsList": ["bHIGH"] + "vaultsList": ["wstETH"] } diff --git a/deploy/4_oracle.ts b/deploy/newBorrowCollat/0_oracle.ts similarity index 98% rename from deploy/4_oracle.ts rename to deploy/newBorrowCollat/0_oracle.ts index 756f608d..16974de0 100644 --- a/deploy/4_oracle.ts +++ b/deploy/newBorrowCollat/0_oracle.ts @@ -2,7 +2,7 @@ import { ChainId, registry } from '@angleprotocol/sdk'; import { DeployFunction } from 'hardhat-deploy/types'; import yargs from 'yargs'; -import { OracleIB01EURChainlink, OracleIB01EURChainlink__factory } from '../typechain'; +import { OracleIB01EURChainlink, OracleIB01EURChainlink__factory } from '../../typechain'; const argv = yargs.env('').boolean('ci').parseSync(); diff --git a/deploy/5_vaultManagerImplementation.ts b/deploy/newBorrowCollat/1_vaultManagerImplementation.ts similarity index 100% rename from deploy/5_vaultManagerImplementation.ts rename to deploy/newBorrowCollat/1_vaultManagerImplementation.ts diff --git a/deploy/newBorrowCollat/2_vaultManagerProxy.ts b/deploy/newBorrowCollat/2_vaultManagerProxy.ts new file mode 100644 index 00000000..d983d682 --- /dev/null +++ b/deploy/newBorrowCollat/2_vaultManagerProxy.ts @@ -0,0 +1,152 @@ +import { ChainId, CONTRACTS_ADDRESSES, registry } from '@angleprotocol/sdk/dist'; +import { Contract } from 'ethers'; +import { formatBytes32String } from 'ethers/lib/utils'; +import hre from 'hardhat'; +import { DeployFunction } from 'hardhat-deploy/types'; +import yargs from 'yargs'; + +import { Treasury__factory, VaultManager__factory } from '../../typechain'; +import { stableName, vaultManagers, vaultsList } from '../constants/constants'; +const argv = yargs.env('').boolean('ci').parseSync(); + +const func: DeployFunction = async ({ deployments, ethers, network }) => { + /** + * TODO: change implementation depending on what is being deployed + */ + const implementationName = 'VaultManager_PermissionedLiquidations_Implementation'; + // const implementation = (await ethers.getContract(implementationName)).address; + const implementation = '0x88fE06D438F5264dA8e2CDCAc3DAED1eA70F995a'; + + /** + * TODO: set to false if deployer is not admin + */ + const isDeployerAdmin = true; + + /** + * TODO: make sure that the vaultsList to deploy is updated + */ + + const { deploy } = deployments; + const { deployer } = await ethers.getNamedSigners(); + + let proxyAdminAddress: string; + let treasuryAddress; + + if (!network.live) { + // If we're in mainnet fork, we're using the `ProxyAdmin` address from mainnet + proxyAdminAddress = CONTRACTS_ADDRESSES[ChainId.MAINNET].ProxyAdmin!; + treasuryAddress = registry(ChainId.MAINNET)?.agEUR?.Treasury!; + } else { + // Otherwise, we're using the proxy admin address from the desired network + proxyAdminAddress = (await ethers.getContract('ProxyAdmin')).address; + treasuryAddress = registry(network.config.chainId as ChainId)?.agEUR?.Treasury!; + } + + console.log(`Deploying proxies for the following vaultManager: ${vaultsList}`); + + for (const vaultManagerParams of vaultManagers[stableName]?.vaults!) { + const collat = vaultManagerParams.symbol.split('-')[0]; + const stable = vaultManagerParams.symbol.split('-')[1]; + if (!vaultsList.includes(collat)) continue; + const name = `VaultManager_${collat}_${stable}`; + const oracle = (await ethers.getContract(`Oracle_${vaultManagerParams.oracle}`)).address; + + console.log('Now deploying the Proxy for:', name); + console.log(`The params for this vaultManager are:`); + console.log(`collateral: ${vaultManagerParams.collateral}`); + console.log(`oracle address: ${oracle}`); + console.log(`symbol: ${vaultManagerParams.symbol}`); + console.log(`debtCeiling: ${vaultManagerParams.params.debtCeiling.toString()}`); + console.log(`collateralFactor: ${vaultManagerParams.params.collateralFactor.toString()}`); + console.log(`targetHealthFactor: ${vaultManagerParams.params.targetHealthFactor.toString()}`); + console.log(`borrowFee: ${vaultManagerParams.params.borrowFee.toString()}`); + console.log(`repayFee: ${vaultManagerParams.params.repayFee.toString()}`); + console.log(`interestRate: ${vaultManagerParams.params.interestRate.toString()}`); + console.log(`liquidationSurcharge: ${vaultManagerParams.params.liquidationSurcharge.toString()}`); + console.log(`maxLiquidationDiscount: ${vaultManagerParams.params.maxLiquidationDiscount.toString()}`); + console.log(`baseBoost: ${vaultManagerParams.params.baseBoost.toString()}`); + console.log(`whitelistingActivated: ${vaultManagerParams.params.whitelistingActivated.toString()}`); + console.log(''); + + const treasury = new Contract(treasuryAddress, Treasury__factory.abi, deployer); + + const callData = new ethers.Contract( + implementation, + VaultManager__factory.createInterface(), + ).interface.encodeFunctionData('initialize', [ + treasury.address, + vaultManagerParams.collateral, + oracle, + vaultManagerParams.params, + vaultManagerParams.symbol, + ]); + await deploy(name, { + contract: 'TransparentUpgradeableProxy', + from: deployer.address, + args: [implementation, proxyAdminAddress, callData], + log: !argv.ci, + }); + + const vaultManagerAddress = (await deployments.get(name)).address; + const vaultManager = new Contract(vaultManagerAddress, VaultManager__factory.abi, deployer); + console.log(`Successfully deployed ${name} at the address ${vaultManagerAddress}`); + console.log(`${vaultManagerAddress} ${implementation} ${proxyAdminAddress} ${callData}`); + console.log(''); + + let signer = deployer; + if (!isDeployerAdmin) { + const json = await import('./networks/' + network.name + '.json'); + const governor = json.governor; + + await hre.network.provider.request({ + method: 'hardhat_impersonateAccount', + params: [governor], + }); + await hre.network.provider.send('hardhat_setBalance', [governor, '0x10000000000000000000000000000']); + signer = await ethers.getSigner(governor); + } + + console.log(`Now adding ${name} to the VaultManager`); + await (await treasury.connect(signer).addVaultManager(vaultManagerAddress)).wait(); + console.log(`Success`); + + console.log('Unpausing vaultManager'); + await (await vaultManager.togglePause()).wait(); + console.log('Success'); + + // Set borrowFee and repayFee if needed + if (!vaultManagerParams.params.borrowFee.isZero()) { + await ( + await vaultManager.connect(signer).setUint64(vaultManagerParams.params.borrowFee, formatBytes32String('BF')) + ).wait(); + console.log(`BorrowFee of ${vaultManagerParams.params.borrowFee} set successfully`); + } + if (!vaultManagerParams.params.repayFee.isZero()) { + await ( + await vaultManager.connect(signer).setUint64(vaultManagerParams.params.repayFee, formatBytes32String('RF')) + ).wait(); + console.log(`RepayFee of ${vaultManagerParams.params.repayFee} set successfully`); + } + if ( + !vaultManagerParams.params.dust.isZero() || + !vaultManagerParams.params.dustLiquidation.isZero() || + !vaultManagerParams.params.dustCollateral.isZero() + ) { + console.log('Setting dusts'); + await ( + await vaultManager + .connect(signer) + .setDusts( + vaultManagerParams.params.dust, + vaultManagerParams.params.dustLiquidation, + vaultManagerParams.params.dustCollateral, + ) + ).wait(); + console.log('Success'); + } + } +}; + +func.tags = ['vaultManagerProxy']; +func.dependencies = ['oracle']; +export default func; diff --git a/deploy/7_swapper.ts b/deploy/newBorrowCollat/3_swapper.ts similarity index 100% rename from deploy/7_swapper.ts rename to deploy/newBorrowCollat/3_swapper.ts diff --git a/deploy/0_proxyAdmin.ts b/deploy/newChain/0_proxyAdmin.ts similarity index 91% rename from deploy/0_proxyAdmin.ts rename to deploy/newChain/0_proxyAdmin.ts index c892e7cb..92fdd115 100644 --- a/deploy/0_proxyAdmin.ts +++ b/deploy/newChain/0_proxyAdmin.ts @@ -1,9 +1,8 @@ // To be used in other chains than mainnet to deploy proxy admin for our upgradeable contracts import { DeployFunction } from 'hardhat-deploy/types'; -// import { DeployFunction } from '@matterlabs/hardhat-zksync-deploy'; import yargs from 'yargs'; -import { ProxyAdmin, ProxyAdmin__factory } from '../typechain'; +import { ProxyAdmin, ProxyAdmin__factory } from '../../typechain'; const argv = yargs.env('').boolean('ci').parseSync(); const func: DeployFunction = async ({ deployments, ethers, network }) => { diff --git a/deploy/1_coreBorrow.ts b/deploy/newChain/1_coreBorrow.ts similarity index 95% rename from deploy/1_coreBorrow.ts rename to deploy/newChain/1_coreBorrow.ts index 99d147ea..556f5b90 100644 --- a/deploy/1_coreBorrow.ts +++ b/deploy/newChain/1_coreBorrow.ts @@ -1,8 +1,9 @@ +// To be used when deploying governance for the first time on a new chain import { ChainId, CONTRACTS_ADDRESSES } from '@angleprotocol/sdk'; import { DeployFunction } from 'hardhat-deploy/types'; import yargs from 'yargs'; -import { CoreBorrow__factory } from '../typechain'; +import { CoreBorrow__factory } from '../../typechain'; const argv = yargs.env('').boolean('ci').parseSync(); const func: DeployFunction = async ({ deployments, ethers, network }) => { diff --git a/deploy/2_agTokenImplementation.ts b/deploy/newChain/2_agTokenImplementation.ts similarity index 81% rename from deploy/2_agTokenImplementation.ts rename to deploy/newChain/2_agTokenImplementation.ts index 191b21fb..f3962a13 100644 --- a/deploy/2_agTokenImplementation.ts +++ b/deploy/newChain/2_agTokenImplementation.ts @@ -1,3 +1,4 @@ +// To deploy an agToken on a new chain import { ChainId, registry } from '@angleprotocol/sdk'; import { DeployFunction } from 'hardhat-deploy/types'; import yargs from 'yargs'; @@ -9,16 +10,8 @@ const func: DeployFunction = async ({ deployments, ethers, network }) => { const { deployer } = await ethers.getNamedSigners(); const stableName = 'EUR'; - let implementationName: string; - let proxyAdmin: string; - - if (network.config.chainId == 1 || !network.live) { - implementationName = 'AgTokenSideChain'; - proxyAdmin = registry(ChainId.MAINNET)?.ProxyAdmin!; - } else { - implementationName = 'AgTokenSideChainMultiBridge'; - proxyAdmin = (await deployments.get('ProxyAdmin')).address; - } + const implementationName = 'AgTokenSideChainMultiBridge'; + const proxyAdmin = (await deployments.get('ProxyAdmin')).address; console.log(`Now deploying the implementation for AgToken on ${network.name}`); console.log(`Using implementation ${implementationName}`); diff --git a/deploy/3_treasury.ts b/deploy/newChain/3_treasury.ts similarity index 96% rename from deploy/3_treasury.ts rename to deploy/newChain/3_treasury.ts index 3727995e..6d757655 100644 --- a/deploy/3_treasury.ts +++ b/deploy/newChain/3_treasury.ts @@ -2,8 +2,8 @@ import { ChainId, registry } from '@angleprotocol/sdk'; import { DeployFunction } from 'hardhat-deploy/types'; import yargs from 'yargs'; -import { AgTokenSideChainMultiBridge, AgTokenSideChainMultiBridge__factory, Treasury__factory } from '../typechain'; -import { deployProxy } from './helpers'; +import { AgTokenSideChainMultiBridge, AgTokenSideChainMultiBridge__factory, Treasury__factory } from '../../typechain'; +import { deployProxy } from '../helpers'; const argv = yargs.env('').boolean('ci').parseSync(); diff --git a/deploy/newStable/0_coreBorrow.ts b/deploy/newStable/0_coreBorrow.ts new file mode 100644 index 00000000..1245c63c --- /dev/null +++ b/deploy/newStable/0_coreBorrow.ts @@ -0,0 +1,71 @@ +import { ChainId, registry } from '@angleprotocol/sdk'; +import { DeployFunction } from 'hardhat-deploy/types'; +import yargs from 'yargs'; + +import { CoreBorrow__factory } from '../../typechain'; +import { forkedChain } from '../constants/constants'; +const argv = yargs.env('').boolean('ci').parseSync(); + +/** + * TODO: before starting the deployment, make sure that the constant are up to date with the stablecoin name + */ + +const func: DeployFunction = async ({ deployments, ethers, network }) => { + // This is for a test CoreBorrow implementation + const { deploy } = deployments; + const { deployer } = await ethers.getNamedSigners(); + const json = await import('../networks/' + network.name + '.json'); + const name = 'CoreBorrowTest'; + const governor = deployer.address; + const guardian = json.guardian; + let proxyAdmin: string; + + if (!network.live) { + proxyAdmin = registry(forkedChain)?.ProxyAdmin!; + } else { + proxyAdmin = registry(network.config.chainId as ChainId)?.ProxyAdmin!; + } + + let coreBorrowImplementation; + try { + coreBorrowImplementation = (await ethers.getContract('CoreBorrow_Implementation')).address; + } catch { + // Typically if we're in mainnet fork + console.log('Now deploying CoreBorrow implementation'); + await deploy('CoreBorrow_Implementation', { + contract: 'CoreBorrow', + from: deployer.address, + args: [], + log: !argv.ci, + }); + coreBorrowImplementation = (await ethers.getContract('CoreBorrow_Implementation')).address; + } + console.log(''); + + const coreBorrowInterface = CoreBorrow__factory.createInterface(); + + const dataCoreBorrow = new ethers.Contract( + coreBorrowImplementation, + coreBorrowInterface, + ).interface.encodeFunctionData('initialize', [governor, guardian]); + + console.log(`Deploying the Proxy for ${name}`); + console.log('The contract will be initialized with the following governor and guardian addresses'); + console.log(governor, guardian); + + await deploy(name, { + contract: 'TransparentUpgradeableProxy', + from: deployer.address, + args: [coreBorrowImplementation, proxyAdmin, dataCoreBorrow], + log: !argv.ci, + }); + + const coreBorrow = (await deployments.get(name)).address; + console.log(`Successfully deployed ${name} at the address ${coreBorrow}`); + + console.log(`${coreBorrow} ${coreBorrowImplementation} ${proxyAdmin} ${dataCoreBorrow} `); + console.log(''); +}; + +func.tags = ['coreNewStable']; +export default func; diff --git a/deploy/newStable/1_agTokenImplementation.ts b/deploy/newStable/1_agTokenImplementation.ts new file mode 100644 index 00000000..8f7177e1 --- /dev/null +++ b/deploy/newStable/1_agTokenImplementation.ts @@ -0,0 +1,71 @@ +import { ChainId, registry } from '@angleprotocol/sdk'; +import { DeployFunction } from 'hardhat-deploy/types'; +import yargs from 'yargs'; + +import { TransparentUpgradeableProxy, TransparentUpgradeableProxy__factory } from '../../typechain'; +import { forkedChain, immutableCreate2Factory, minedAddress } from '../constants/constants'; + +const argv = yargs.env('').boolean('ci').parseSync(); + +const func: DeployFunction = async ({ deployments, ethers, network }) => { + const { deploy } = deployments; + const { deployer } = await ethers.getNamedSigners(); + const json = await import('../../scripts/vanity.json'); + + let implementationName: string; + let proxyAdmin: string; + + if (network.config.chainId == 1 || (!network.live && (forkedChain as ChainId) === ChainId.MAINNET)) { + implementationName = 'AgToken'; + proxyAdmin = registry(ChainId.MAINNET)?.ProxyAdmin!; + } else if (!network.live && (forkedChain as ChainId) != ChainId.MAINNET) { + implementationName = 'AgTokenSideChainMultiBridge'; + proxyAdmin = registry(forkedChain)?.ProxyAdmin!; + } else { + implementationName = 'AgTokenSideChainMultiBridge'; + proxyAdmin = registry(network.config.chainId as ChainId)?.ProxyAdmin!; + } + + console.log(`Now deploying the implementation for AgToken on ${network.name}`); + console.log(`Using implementation ${implementationName}`); + + await deploy(`${implementationName}_Implementation`, { + contract: implementationName, + from: deployer.address, + args: [], + log: !argv.ci, + }); + const agTokenImplementation = (await deployments.get(`${implementationName}_Implementation`)).address; + + // Init code for TransparentUpgradeableProxy with as an implementation the IMMUTABLE_CREATE2_FACTORY_ADDRESS and an owner the deployer + // If changing the deployer, we need to update this initCode + const initCode = + '0x60406080815262000f5f80380380620000188162000364565b9283398101906060818303126200035f576200003481620003a0565b9160209262000045848401620003a0565b8584015190936001600160401b0391908282116200035f57019280601f850112156200035f57835193620000836200007d86620003b5565b62000364565b94808652878601928882840101116200035f578288620000a49301620003d1565b823b1562000305577f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc80546001600160a01b03199081166001600160a01b0386811691821790935590959194600093909290917fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b8580a2805115801590620002fd575b620001f5575b50505050507fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103937f7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f86865493815196818616885216958684820152a18315620001a357501617905551610b0a9081620004558239f35b60849086519062461bcd60e51b82526004820152602660248201527f455243313936373a206e65772061646d696e20697320746865207a65726f206160448201526564647265737360d01b6064820152fd5b8951946060860190811186821017620002e9578a52602785527f416464726573733a206c6f772d6c6576656c2064656c65676174652063616c6c89860152660819985a5b195960ca1b8a860152823b156200029657928092819262000280969551915af43d156200028c573d620002706200007d82620003b5565b9081528092893d92013e620003f6565b5038808080806200012d565b60609150620003f6565b895162461bcd60e51b8152600481018a9052602660248201527f416464726573733a2064656c65676174652063616c6c20746f206e6f6e2d636f6044820152651b9d1c9858dd60d21b6064820152608490fd5b634e487b7160e01b85526041600452602485fd5b508362000127565b865162461bcd60e51b815260048101879052602d60248201527f455243313936373a206e657720696d706c656d656e746174696f6e206973206e60448201526c1bdd08184818dbdb9d1c9858dd609a1b6064820152608490fd5b600080fd5b6040519190601f01601f191682016001600160401b038111838210176200038a57604052565b634e487b7160e01b600052604160045260246000fd5b51906001600160a01b03821682036200035f57565b6001600160401b0381116200038a57601f01601f191660200190565b60005b838110620003e55750506000910152565b8181015183820152602001620003d4565b9091901562000403575090565b815115620004145750805190602001fd5b6044604051809262461bcd60e51b825260206004830152620004468151809281602486015260208686019101620003d1565b601f01601f19168101030190fdfe6080604052600436101561002c575b361561001f575b61001d6104dd565b005b6100276104dd565b610015565b6000803560e01c9081633659cfe614610093575080634f1ef2861461008a5780635c60da1b146100815780638f283970146100785763f851a4400361000e57610073610455565b61000e565b506100736102f0565b5061007361023b565b50610073610157565b3461012c5760207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc36011261012c576100ca61012f565b73ffffffffffffffffffffffffffffffffffffffff7fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103541633146000146101235761012090610117610639565b908382526106f3565b80f35b506101206104dd565b80fd5b6004359073ffffffffffffffffffffffffffffffffffffffff8216820361015257565b600080fd5b5060407ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126101525761018a61012f565b60243567ffffffffffffffff9182821161015257366023830112156101525781600401359283116101525736602484840101116101525773ffffffffffffffffffffffffffffffffffffffff7fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035416331460001461023057600060208480602461021e61021961001d996106aa565b610666565b96828852018387013784010152610833565b50505061001d6104dd565b50346101525760007ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc360112610152576020600073ffffffffffffffffffffffffffffffffffffffff90817fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103541633146000146102e25750807f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc5416905b60405191168152f35b906102eb6104dd565b6102d9565b50346101525760207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126101525761032861012f565b73ffffffffffffffffffffffffffffffffffffffff907fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d610391808354163314600014610230577f7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f604084549281519481851686521693846020820152a181156103d1577fffffffffffffffffffffffff000000000000000000000000000000000000000016179055005b60846040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f455243313936373a206e65772061646d696e20697320746865207a65726f206160448201527f64647265737300000000000000000000000000000000000000000000000000006064820152fd5b50346101525760007ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc360112610152576020600073ffffffffffffffffffffffffffffffffffffffff7fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61038181541633146000146104d85754604051911681529050f35b506102eb5b5073ffffffffffffffffffffffffffffffffffffffff807fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035416331461055f577f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc54166000808092368280378136915af43d82803e1561055b573d90f35b3d90fd5b60a46040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604260248201527f5472616e73706172656e745570677261646561626c6550726f78793a2061646d60448201527f696e2063616e6e6f742066616c6c6261636b20746f2070726f7879207461726760648201527f65740000000000000000000000000000000000000000000000000000000000006084820152fd5b507f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b604051906020820182811067ffffffffffffffff82111761065957604052565b610661610609565b604052565b907fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f604051930116820182811067ffffffffffffffff82111761065957604052565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f60209267ffffffffffffffff81116106e6575b01160190565b6106ee610609565b6106e0565b803b156107af5773ffffffffffffffffffffffffffffffffffffffff81167f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc817fffffffffffffffffffffffff00000000000000000000000000000000000000008254161790557fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b600080a28151158015906107a7575b610792575050565b6107a49161079e6108d9565b91610957565b50565b50600061078a565b60846040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602d60248201527f455243313936373a206e657720696d706c656d656e746174696f6e206973206e60448201527f6f74206120636f6e7472616374000000000000000000000000000000000000006064820152fd5b803b156107af5773ffffffffffffffffffffffffffffffffffffffff81167f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc817fffffffffffffffffffffffff00000000000000000000000000000000000000008254161790557fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b600080a28151158015906108d157610792575050565b50600161078a565b604051906060820182811067ffffffffffffffff82111761094a575b604052602782527f206661696c6564000000000000000000000000000000000000000000000000006040837f416464726573733a206c6f772d6c6576656c2064656c65676174652063616c6c60208201520152565b610952610609565b6108f5565b9190823b156109a0576000816109959460208394519201905af43d15610998573d90610985610219836106aa565b9182523d6000602084013e610a24565b90565b606090610a24565b60846040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f416464726573733a2064656c65676174652063616c6c20746f206e6f6e2d636f60448201527f6e747261637400000000000000000000000000000000000000000000000000006064820152fd5b90919015610a30575090565b815115610a405750805190602001fd5b604051907f08c379a000000000000000000000000000000000000000000000000000000000825281602080600483015282519283602484015260005b848110610abd575050507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f836000604480968601015201168101030190fd5b818101830151868201604401528593508201610a7c56fea26469706673582212206eca7257d81e920296a8c93c0ac0d93d9bb0927ce3e4cefa34ff129bc0cdbceb64736f6c634300081100330000000000000000000000000000000000ffe8b47b3e2130213b802212439497000000000000000000000000fda462548ce04282f4b6d6619823a7c64fdc018500000000000000000000000000000000000000000000000000000000000000600000000000000000000000000000000000000000000000000000000000000000'; + + const immutableCreate2Interface = new ethers.utils.Interface([ + 'function safeCreate2(bytes32 salt, bytes memory initCode) external payable returns (address deploymentAddress)', + 'function findCreate2Address(bytes32 salt,bytes calldata initCode) external view returns (address deploymentAddress)', + ]); + const immutableCreate2 = new ethers.Contract(immutableCreate2Factory, immutableCreate2Interface, deployer); + const computedAddress = await immutableCreate2.findCreate2Address(json.salt, initCode); + if (computedAddress != minedAddress) throw Error('Invalid Mined address'); + console.log(`Deploying agToken at the address ${computedAddress}`); + await (await immutableCreate2.safeCreate2(json.salt, initCode)).wait(); + console.log('agToken deployed'); + const agToken = new ethers.Contract( + minedAddress, + TransparentUpgradeableProxy__factory.createInterface(), + deployer, + ) as TransparentUpgradeableProxy; + console.log('Upgrading the implementation'); + await (await agToken.upgradeTo(agTokenImplementation)).wait(); + console.log('Success'); + console.log('Changing the admin'); + await (await agToken.changeAdmin(proxyAdmin)).wait(); + console.log('Success'); + console.log(''); +}; + +func.tags = ['agTokenNewStable']; +func.dependencies = ['coreNewStable']; +export default func; diff --git a/deploy/newStable/2_treasury.ts b/deploy/newStable/2_treasury.ts new file mode 100644 index 00000000..2acfaa28 --- /dev/null +++ b/deploy/newStable/2_treasury.ts @@ -0,0 +1,64 @@ +import { ChainId, registry } from '@angleprotocol/sdk'; +import { DeployFunction } from 'hardhat-deploy/types'; +import yargs from 'yargs'; + +import { AgTokenSideChainMultiBridge, AgTokenSideChainMultiBridge__factory, Treasury__factory } from '../../typechain'; +import { forkedChain, minedAddress, stableName } from '../constants/constants'; +import { deployProxy } from '../helpers'; + +const argv = yargs.env('').boolean('ci').parseSync(); + +const func: DeployFunction = async ({ deployments, ethers, network }) => { + const { deploy } = deployments; + const { deployer } = await ethers.getNamedSigners(); + let proxyAdmin: string; + let coreBorrow: string; + + const agTokenName = `Angle ${stableName}`; + const agTokenSymbol = `ag${stableName}`; + + if (!network.live) { + proxyAdmin = registry(forkedChain)?.ProxyAdmin!; + } else { + proxyAdmin = registry(network.config.chainId as ChainId)?.ProxyAdmin!; + } + coreBorrow = (await deployments.get('CoreBorrowTest')).address; + let treasuryImplementation: string; + try { + treasuryImplementation = (await deployments.get('Treasury_Implementation')).address; + } catch { + // Typically if we're in mainnet fork + console.log('Now deploying Treasury implementation'); + await deploy('Treasury_Implementation', { + contract: 'Treasury', + from: deployer.address, + args: [], + log: !argv.ci, + }); + treasuryImplementation = (await deployments.get('Treasury_Implementation')).address; + } + + const treasuryInterface = Treasury__factory.createInterface(); + const dataTreasury = new ethers.Contract(treasuryImplementation, treasuryInterface).interface.encodeFunctionData( + 'initialize', + [coreBorrow, minedAddress], + ); + + const treasury = await deployProxy(`Treasury_${stableName}`, treasuryImplementation, proxyAdmin, dataTreasury); + + console.log(''); + + console.log('Initializing the agToken contract now that we have the treasury address'); + const agToken = new ethers.Contract( + minedAddress, + AgTokenSideChainMultiBridge__factory.createInterface(), + deployer, + ) as AgTokenSideChainMultiBridge; + await (await agToken.connect(deployer).initialize(agTokenName, agTokenSymbol, treasury)).wait(); + console.log('Success: agToken successfully initialized'); + console.log(''); +}; + +func.tags = ['treasuryNewStable']; +func.dependencies = ['agTokenNewStable']; +export default func; diff --git a/deploy/newStable/3_oracle.ts b/deploy/newStable/3_oracle.ts new file mode 100644 index 00000000..40261893 --- /dev/null +++ b/deploy/newStable/3_oracle.ts @@ -0,0 +1,43 @@ +import { ChainId } from '@angleprotocol/sdk'; +import { DeployFunction } from 'hardhat-deploy/types'; +import yargs from 'yargs'; + +import { OracleWSTETHUSDChainlink, OracleWSTETHUSDChainlink__factory } from '../../typechain'; +import { forkedChain, forkedChainName, stableName } from '../constants/constants'; + +const argv = yargs.env('').boolean('ci').parseSync(); + +const func: DeployFunction = async ({ deployments, ethers, network }) => { + const { deploy } = deployments; + const { deployer } = await ethers.getNamedSigners(); + if ((!network.live && (forkedChain as ChainId) === ChainId.MAINNET) || network.config.chainId == 1) { + const treasury = (await deployments.get(`Treasury_${stableName}`)).address; + console.log('Now deploying the Oracle wstETH/USD'); + console.log(`Treasury: ${treasury}`); + await deploy('Oracle_WSTETH_USD', { + contract: `OracleWSTETHUSDChainlink`, + from: deployer.address, + args: [3600 * 24, treasury], + log: !argv.ci, + }); + const oracle = (await deployments.get('Oracle_WSTETH_USD')).address; + console.log(`Successfully deployed Oracle wstETH/USD at the address ${oracle}`); + + const oracleContract = new ethers.Contract( + oracle, + OracleWSTETHUSDChainlink__factory.createInterface(), + deployer, + ) as OracleWSTETHUSDChainlink; + + const oracleValue = await oracleContract.read(); + console.log('Oracle address', oracleValue); + console.log(''); + } else { + console.log(`Not deploying any oracle on ${forkedChainName}`); + console.log(''); + } +}; + +func.tags = ['oracleNewStable']; +func.dependencies = ['treasuryNewStable']; +export default func; diff --git a/deploy/newStable/4_vaultManagerProxy.ts b/deploy/newStable/4_vaultManagerProxy.ts new file mode 100644 index 00000000..7f101ebd --- /dev/null +++ b/deploy/newStable/4_vaultManagerProxy.ts @@ -0,0 +1,163 @@ +import { ChainId, registry } from '@angleprotocol/sdk/dist'; +import { Contract } from 'ethers'; +import { formatBytes32String } from 'ethers/lib/utils'; +import hre from 'hardhat'; +import { DeployFunction } from 'hardhat-deploy/types'; +import yargs from 'yargs'; + +import { Treasury__factory, VaultManager__factory } from '../../typechain'; +import { forkedChain, forkedChainName, stableName, vaultManagers, vaultsList } from '../constants/constants'; +const argv = yargs.env('').boolean('ci').parseSync(); + +const func: DeployFunction = async ({ deployments, ethers, network }) => { + /** + * TODO: change implementation depending on what is being deployed + */ + const implementationName = 'VaultManager_NoDust'; + + /** + * TODO: set to false if deployer is not admin + */ + const isDeployerAdmin = true; + + /** + * TODO: make sure that the vaultsList to deploy is updated + */ + + const { deploy } = deployments; + const { deployer } = await ethers.getNamedSigners(); + + if ((!network.live && (forkedChain as ChainId) == ChainId.MAINNET) || network.config.chainId == 1) { + let implementation: string; + try { + implementation = (await ethers.getContract(implementationName)).address; + } catch { + // Typically if we're in mainnet fork + console.log('Now deploying VaultManager implementation'); + await deploy(implementationName, { + contract: 'VaultManagerLiquidationBoost', + from: deployer.address, + args: [], + log: !argv.ci, + }); + implementation = (await ethers.getContract(implementationName)).address; + } + // If we're in mainnet fork, we're using the `ProxyAdmin` address from mainnet + const proxyAdminAddress = registry(ChainId.MAINNET)?.ProxyAdmin!; + const treasuryAddress = (await deployments.get(`Treasury_${stableName}`)).address; + console.log(`Treasury: ${treasuryAddress}`); + + console.log(`Deploying proxies for the following vaultManager: ${vaultsList}`); + + for (const vaultManagerParams of vaultManagers[stableName]?.vaults!) { + const collat = vaultManagerParams.symbol.split('-')[0]; + const stable = vaultManagerParams.symbol.split('-')[1]; + if (!vaultsList.includes(collat)) continue; + const name = `VaultManager_${collat}_${stable}`; + const oracle = (await ethers.getContract(`Oracle_${vaultManagerParams.oracle}`)).address; + + console.log('Now deploying the Proxy for:', name); + console.log(`The params for this vaultManager are:`); + console.log(`collateral: ${vaultManagerParams.collateral}`); + console.log(`oracle address: ${oracle}`); + console.log(`symbol: ${vaultManagerParams.symbol}`); + console.log(`debtCeiling: ${vaultManagerParams.params.debtCeiling.toString()}`); + console.log(`collateralFactor: ${vaultManagerParams.params.collateralFactor.toString()}`); + console.log(`targetHealthFactor: ${vaultManagerParams.params.targetHealthFactor.toString()}`); + console.log(`borrowFee: ${vaultManagerParams.params.borrowFee.toString()}`); + console.log(`repayFee: ${vaultManagerParams.params.repayFee.toString()}`); + console.log(`interestRate: ${vaultManagerParams.params.interestRate.toString()}`); + console.log(`liquidationSurcharge: ${vaultManagerParams.params.liquidationSurcharge.toString()}`); + console.log(`maxLiquidationDiscount: ${vaultManagerParams.params.maxLiquidationDiscount.toString()}`); + console.log(`baseBoost: ${vaultManagerParams.params.baseBoost.toString()}`); + console.log(`whitelistingActivated: ${vaultManagerParams.params.whitelistingActivated.toString()}`); + console.log(''); + + const treasury = new Contract(treasuryAddress, Treasury__factory.abi, deployer); + + const callData = new ethers.Contract( + implementation, + VaultManager__factory.createInterface(), + ).interface.encodeFunctionData('initialize', [ + treasury.address, + vaultManagerParams.collateral, + oracle, + vaultManagerParams.params, + vaultManagerParams.symbol, + ]); + await deploy(name, { + contract: 'TransparentUpgradeableProxy', + from: deployer.address, + args: [implementation, proxyAdminAddress, callData], + log: !argv.ci, + }); + + const vaultManagerAddress = (await deployments.get(name)).address; + const vaultManager = new Contract(vaultManagerAddress, VaultManager__factory.abi, deployer); + console.log(`Successfully deployed ${name} at the address ${vaultManagerAddress}`); + console.log(`${vaultManagerAddress} ${implementation} ${proxyAdminAddress} ${callData}`); + console.log(''); + + let signer = deployer; + if (!isDeployerAdmin) { + const json = await import('./networks/' + network.name + '.json'); + const governor = json.governor; + + await hre.network.provider.request({ + method: 'hardhat_impersonateAccount', + params: [governor], + }); + await hre.network.provider.send('hardhat_setBalance', [governor, '0x10000000000000000000000000000']); + signer = await ethers.getSigner(governor); + } + + console.log(`Now adding ${name} to the VaultManager`); + await (await treasury.connect(signer).addVaultManager(vaultManagerAddress)).wait(); + console.log(`Success`); + + console.log('Unpausing vaultManager'); + await (await vaultManager.togglePause()).wait(); + console.log('Success'); + + // Set borrowFee and repayFee if needed + if (!vaultManagerParams.params.borrowFee.isZero()) { + await ( + await vaultManager.connect(signer).setUint64(vaultManagerParams.params.borrowFee, formatBytes32String('BF')) + ).wait(); + console.log(`BorrowFee of ${vaultManagerParams.params.borrowFee} set successfully`); + } + if (!vaultManagerParams.params.repayFee.isZero()) { + await ( + await vaultManager.connect(signer).setUint64(vaultManagerParams.params.repayFee, formatBytes32String('RF')) + ).wait(); + console.log(`RepayFee of ${vaultManagerParams.params.repayFee} set successfully`); + } + if ( + !vaultManagerParams.params.dust.isZero() || + !vaultManagerParams.params.dustLiquidation.isZero() || + !vaultManagerParams.params.dustCollateral.isZero() + ) { + console.log('Setting dusts'); + await ( + await vaultManager + .connect(signer) + .setDusts( + vaultManagerParams.params.dust, + vaultManagerParams.params.dustLiquidation, + vaultManagerParams.params.dustCollateral, + ) + ).wait(); + console.log('Success'); + } + } + console.log('Proxy deployments done'); + console.log(''); + } else { + console.log(`Not deploying any vault on ${forkedChainName}`); + console.log(''); + } +}; + +func.tags = ['vaultNewStable']; +func.dependencies = ['oracleNewStable']; +export default func; diff --git a/deploy/newStable/5_layerZeroBridge.ts b/deploy/newStable/5_layerZeroBridge.ts new file mode 100644 index 00000000..316bfc4d --- /dev/null +++ b/deploy/newStable/5_layerZeroBridge.ts @@ -0,0 +1,44 @@ +import { ChainId, registry } from '@angleprotocol/sdk/dist'; +import { DeployFunction } from 'hardhat-deploy/types'; + +import { LayerZeroBridge__factory } from '../../typechain'; +import { forkedChain, forkedChainName, stableName } from '../constants/constants'; +import LZ_ENDPOINTS from '../constants/layerzeroEndpoints.json'; +import { deployImplem, deployProxy } from '../helpers'; + +const func: DeployFunction = async ({ ethers, network, deployments }) => { + if ((!network.live && (forkedChain as ChainId) == ChainId.MAINNET) || network.config.chainId == 1) { + const treasury = await ethers.getContract(`Treasury_${stableName}`); + const proxyAdminAddress = registry(ChainId.MAINNET)?.ProxyAdmin!; + console.log(treasury.address, proxyAdminAddress); + + const endpointAddr = (LZ_ENDPOINTS as { [name: string]: string }).mainnet; + console.log('Now deploying the LayerZero bridge contract'); + console.log(`[${network.name}] LayerZero Endpoint address: ${endpointAddr}`); + let layerZeroBridgeImplem; + try { + layerZeroBridgeImplem = (await deployments.get('LayerZeroBridge')).address; + } catch { + // Typically if we're in mainnet fork + layerZeroBridgeImplem = await deployImplem('LayerZeroBridge'); + } + + await deployProxy( + `LayerZeroBridge_${stableName}`, + layerZeroBridgeImplem, + proxyAdminAddress, + LayerZeroBridge__factory.createInterface().encodeFunctionData('initialize', [ + `LayerZero Bridge ag${stableName}`, + endpointAddr, + treasury.address, + ]), + ); + } else { + console.log(`Not deploying any LayerZeroBridge contract on ${forkedChainName}`); + console.log(''); + } +}; + +func.tags = ['lzBridgeNewStable']; +func.dependencies = ['vaultNewStable']; +export default func; diff --git a/deploy/newStable/6_layerZeroBridgeToken.ts b/deploy/newStable/6_layerZeroBridgeToken.ts new file mode 100644 index 00000000..fa71fa61 --- /dev/null +++ b/deploy/newStable/6_layerZeroBridgeToken.ts @@ -0,0 +1,97 @@ +import { ChainId, registry } from '@angleprotocol/sdk'; +import { parseEther } from 'ethers/lib/utils'; +import { DeployFunction } from 'hardhat-deploy/types'; +import yargs from 'yargs'; + +import { + AgTokenSideChainMultiBridge, + AgTokenSideChainMultiBridge__factory, + LayerZeroBridgeToken, + LayerZeroBridgeToken__factory, +} from '../../typechain'; +import { forkedChain, minedAddress, stableName } from '../constants/constants'; +import LZ_ENDPOINTS from '../constants/layerzeroEndpoints.json'; +import { deployProxy } from '../helpers'; + +const argv = yargs.env('').boolean('ci').parseSync(); +const func: DeployFunction = async ({ ethers, network, deployments }) => { + const { deploy } = deployments; + const { deployer } = await ethers.getNamedSigners(); + const isDeployerAdmin = true; + if ((!network.live && (forkedChain as ChainId) == ChainId.MAINNET) || network.config.chainId == 1) { + console.log(''); + console.log('Not deploying any bridge token on Ethereum'); + console.log(''); + } else { + const treasury = await ethers.getContract(`Treasury_${stableName}`); + let proxyAdmin; + if (!network.live) { + proxyAdmin = registry(forkedChain)?.ProxyAdmin!; + } else { + proxyAdmin = registry(network.config.chainId as ChainId)?.ProxyAdmin!; + } + + console.log(treasury.address, proxyAdmin); + + const endpointAddr = (LZ_ENDPOINTS as { [name: string]: string })[network.name]; + console.log(`[${network.name}] LayerZero Endpoint address: ${endpointAddr}`); + const deploymentName = 'LayerZeroBridgeToken_V1_0_Implementation'; + + let implementationAddress; + try { + implementationAddress = (await ethers.getContract(deploymentName)).address; + } catch { + await deploy(deploymentName, { + contract: 'LayerZeroBridgeToken', + from: deployer.address, + log: !argv.ci, + }); + implementationAddress = (await ethers.getContract(deploymentName)).address; + } + + const lzAddress = await deployProxy( + `LayerZeroBridge_${stableName}`, + implementationAddress, + proxyAdmin, + LayerZeroBridgeToken__factory.createInterface().encodeFunctionData('initialize', [ + `LayerZero Bridge ag${stableName}`, + `LZ-ag${stableName}`, + endpointAddr, + treasury.address, + parseEther('0'), + ]), + ); + + if (isDeployerAdmin) { + const lzTokenContract = new ethers.Contract( + lzAddress, + LayerZeroBridgeToken__factory.createInterface(), + deployer, + ) as LayerZeroBridgeToken; + const agTokenContract = new ethers.Contract( + minedAddress, + AgTokenSideChainMultiBridge__factory.createInterface(), + deployer, + ) as AgTokenSideChainMultiBridge; + console.log('Setting the useCustomAdapterParams'); + await (await lzTokenContract.setUseCustomAdapterParams(1)).wait(); + console.log('Success'); + console.log('Adding bridge token'); + await ( + await agTokenContract.addBridgeToken(lzAddress, parseEther('1000000'), parseEther('50000'), 0, false) + ).wait(); + /* + console.log('Success'); + console.log('Setting chain total hourly limit'); + await (await agTokenContract.setChainTotalHourlyLimit(parseEther('5000'))).wait(); + console.log('Success'); + console.log(''); + */ + } + // The last thing to be done is to set the trusted remote once everything has been deployed + } +}; + +func.tags = ['lzBridgeTokenNewStable']; +// func.dependencies = ['lzBridgeNewStable']; +export default func; diff --git a/deploy/newStable/7_layerZeroSetup.ts b/deploy/newStable/7_layerZeroSetup.ts new file mode 100644 index 00000000..7bb64157 --- /dev/null +++ b/deploy/newStable/7_layerZeroSetup.ts @@ -0,0 +1,47 @@ +import { Contract } from 'ethers'; +import { DeployFunction } from 'hardhat-deploy/types'; + +import { LayerZeroBridge, LayerZeroBridge__factory } from '../../typechain'; +import { OFTs } from '../constants/constants'; +import LZ_CHAINIDS from '../constants/layerzeroChainIds.json'; + +// For more details on trustedRemote, check: https://layerzero.gitbook.io/docs/evm-guides/master/set-trusted-remotes +// LayerZero chains: https://layerzero.gitbook.io/docs/technical-reference/mainnet/supported-chain-ids +// TODO make sure that the OFT table is up to date before running this script +const func: DeployFunction = async ({ ethers, network }) => { + const { deployer } = await ethers.getNamedSigners(); + const stable = 'USD'; + + let networkName = network.name; + if (!network.live) networkName = 'mainnet'; + + const local = OFTs[stable]?.[networkName] as string; + const contractAngleOFT = new Contract(local, LayerZeroBridge__factory.abi, deployer) as LayerZeroBridge; + + console.log(`Setting the trusted remote addresses on ${networkName}`); + console.log(`On this chain, the LZ address is ${local}`); + console.log('--------------------------------------------'); + for (const chain of Object.keys(OFTs[stable])) { + if (chain !== networkName) { + console.log(`LZ ${stable} contract on ${chain} is ${OFTs[stable][chain]}`); + const trustedRemote = ethers.utils.solidityPack(['address', 'address'], [OFTs[stable][chain], local]); + console.log( + 'Encoded data', + contractAngleOFT.interface.encodeFunctionData('setTrustedRemote', [(LZ_CHAINIDS as any)[chain], trustedRemote]), + ); + console.log('LZ Chain ID & Trusted remote', (LZ_CHAINIDS as any)[chain], trustedRemote); + console.log(`Now creating the transaction to connect ${chain} to ${networkName}`); + // Check admin rights here + await ( + await contractAngleOFT.connect(deployer).setTrustedRemote((LZ_CHAINIDS as any)[chain], trustedRemote) + ).wait(); + console.log('Success'); + console.log(''); + } + } + console.log('--------------------------------------------'); + console.log(''); +}; + +func.tags = ['lzSetupNewStable']; +export default func; diff --git a/deployments/arbitrum/AgTokenSideChainMultiBridge_Implementation.json b/deployments/arbitrum/AgTokenSideChainMultiBridge_Implementation.json index 200bc9aa..f6ebe218 100644 --- a/deployments/arbitrum/AgTokenSideChainMultiBridge_Implementation.json +++ b/deployments/arbitrum/AgTokenSideChainMultiBridge_Implementation.json @@ -1,5 +1,5 @@ { - "address": "0x12f31B73D812C6Bb0d735a218c086d44D5fe5f89", + "address": "0x862f596E76A549363fFBa54B4BE296988CBDc763", "abi": [ { "inputs": [], @@ -249,6 +249,19 @@ "name": "HourlyLimitUpdated", "type": "event" }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint8", + "name": "version", + "type": "uint8" + } + ], + "name": "Initialized", + "type": "event" + }, { "anonymous": false, "inputs": [ @@ -1111,7 +1124,7 @@ "inputs": [ { "internalType": "address", - "name": "recipient", + "name": "to", "type": "address" }, { @@ -1135,12 +1148,12 @@ "inputs": [ { "internalType": "address", - "name": "sender", + "name": "from", "type": "address" }, { "internalType": "address", - "name": "recipient", + "name": "to", "type": "address" }, { @@ -1198,30 +1211,44 @@ "type": "function" } ], - "transactionHash": "0x9bd72baabcfc8c3eef045872dd65b2dc77875e04350f280929afbd3e67f22f77", + "transactionHash": "0xbd3ae4ceaa5781a2136487802b345e2a034e09e72214dd8d35d8115c1dd59ad6", "receipt": { "to": null, "from": "0xfdA462548Ce04282f4B6D6619823a7C64Fdc0185", - "contractAddress": "0x12f31B73D812C6Bb0d735a218c086d44D5fe5f89", - "transactionIndex": 0, - "gasUsed": "59206527", - "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", - "blockHash": "0xbf2355a14d103faf5f70a00b0afdda76d8ffb40bb43d85150560e101deae66a6", - "transactionHash": "0x9bd72baabcfc8c3eef045872dd65b2dc77875e04350f280929afbd3e67f22f77", - "logs": [], - "blockNumber": 17238266, - "cumulativeGasUsed": "29068707", + "contractAddress": "0x862f596E76A549363fFBa54B4BE296988CBDc763", + "transactionIndex": 2, + "gasUsed": "27806324", + "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000080000000000000000000100000000000000000000000000400000000000000000000000000000000000008000000000000000000000000040000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "blockHash": "0xb7dda4480054efb4022004b9e5320267d4e98276a35be0087571f31a7e44fdf5", + "transactionHash": "0xbd3ae4ceaa5781a2136487802b345e2a034e09e72214dd8d35d8115c1dd59ad6", + "logs": [ + { + "transactionIndex": 2, + "blockNumber": 168975723, + "transactionHash": "0xbd3ae4ceaa5781a2136487802b345e2a034e09e72214dd8d35d8115c1dd59ad6", + "address": "0x862f596E76A549363fFBa54B4BE296988CBDc763", + "topics": [ + "0x7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb3847402498" + ], + "data": "0x0000000000000000000000000000000000000000000000000000000000000001", + "logIndex": 0, + "blockHash": "0xb7dda4480054efb4022004b9e5320267d4e98276a35be0087571f31a7e44fdf5" + } + ], + "blockNumber": 168975723, + "cumulativeGasUsed": "28205562", "status": 1, "byzantium": true }, "args": [], - "solcInputHash": "8a26d6606024625e1a63f4cee8837487", - "metadata": "{\"compiler\":{\"version\":\"0.8.12+commit.f00d7308\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[],\"name\":\"AssetStillControlledInReserves\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"BurnAmountExceedsAllowance\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"HourlyLimitExceeded\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidSender\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidToken\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidTreasury\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"NotGovernor\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"NotGovernorOrGuardian\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"NotMinter\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"NotTreasury\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"TooBigAmount\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"TooHighParameterValue\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ZeroAddress\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"spender\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"}],\"name\":\"Approval\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"bridgeToken\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"limit\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"hourlyLimit\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"fee\",\"type\":\"uint64\"},{\"indexed\":false,\"internalType\":\"bool\",\"name\":\"paused\",\"type\":\"bool\"}],\"name\":\"BridgeTokenAdded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"bridgeToken\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"fee\",\"type\":\"uint64\"}],\"name\":\"BridgeTokenFeeUpdated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"bridgeToken\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"hourlyLimit\",\"type\":\"uint256\"}],\"name\":\"BridgeTokenHourlyLimitUpdated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"bridgeToken\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"limit\",\"type\":\"uint256\"}],\"name\":\"BridgeTokenLimitUpdated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"bridgeToken\",\"type\":\"address\"}],\"name\":\"BridgeTokenRemoved\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"bridgeToken\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"bool\",\"name\":\"toggleStatus\",\"type\":\"bool\"}],\"name\":\"BridgeTokenToggled\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"theAddress\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"toggleStatus\",\"type\":\"uint256\"}],\"name\":\"FeeToggled\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"hourlyLimit\",\"type\":\"uint256\"}],\"name\":\"HourlyLimitUpdated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"minter\",\"type\":\"address\"}],\"name\":\"MinterToggled\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"Recovered\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"}],\"name\":\"Transfer\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"_treasury\",\"type\":\"address\"}],\"name\":\"TreasuryUpdated\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"BASE_PARAMS\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"DOMAIN_SEPARATOR\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"bridgeToken\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"limit\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"hourlyLimit\",\"type\":\"uint256\"},{\"internalType\":\"uint64\",\"name\":\"fee\",\"type\":\"uint64\"},{\"internalType\":\"bool\",\"name\":\"paused\",\"type\":\"bool\"}],\"name\":\"addBridgeToken\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"minter\",\"type\":\"address\"}],\"name\":\"addMinter\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"allBridgeTokens\",\"outputs\":[{\"internalType\":\"address[]\",\"name\":\"\",\"type\":\"address[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"spender\",\"type\":\"address\"}],\"name\":\"allowance\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"spender\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"approve\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"}],\"name\":\"balanceOf\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"name\":\"bridgeTokensList\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"bridges\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"limit\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"hourlyLimit\",\"type\":\"uint256\"},{\"internalType\":\"uint64\",\"name\":\"fee\",\"type\":\"uint64\"},{\"internalType\":\"bool\",\"name\":\"allowed\",\"type\":\"bool\"},{\"internalType\":\"bool\",\"name\":\"paused\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"burner\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"}],\"name\":\"burnFrom\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"burner\",\"type\":\"address\"}],\"name\":\"burnSelf\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"burnStablecoin\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"chainTotalHourlyLimit\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"name\":\"chainTotalUsage\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"currentTotalUsage\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"bridgeToken\",\"type\":\"address\"}],\"name\":\"currentUsage\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"decimals\",\"outputs\":[{\"internalType\":\"uint8\",\"name\":\"\",\"type\":\"uint8\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"spender\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"subtractedValue\",\"type\":\"uint256\"}],\"name\":\"decreaseAllowance\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"spender\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"addedValue\",\"type\":\"uint256\"}],\"name\":\"increaseAllowance\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"string\",\"name\":\"name_\",\"type\":\"string\"},{\"internalType\":\"string\",\"name\":\"symbol_\",\"type\":\"string\"},{\"internalType\":\"address\",\"name\":\"_treasury\",\"type\":\"address\"}],\"name\":\"initialize\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"isFeeExempt\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"isMinter\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"mint\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"name\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"}],\"name\":\"nonces\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"spender\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"deadline\",\"type\":\"uint256\"},{\"internalType\":\"uint8\",\"name\":\"v\",\"type\":\"uint8\"},{\"internalType\":\"bytes32\",\"name\":\"r\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32\",\"name\":\"s\",\"type\":\"bytes32\"}],\"name\":\"permit\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"tokenAddress\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amountToRecover\",\"type\":\"uint256\"}],\"name\":\"recoverERC20\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"bridgeToken\",\"type\":\"address\"}],\"name\":\"removeBridgeToken\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"minter\",\"type\":\"address\"}],\"name\":\"removeMinter\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"hourlyLimit\",\"type\":\"uint256\"}],\"name\":\"setChainTotalHourlyLimit\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"bridgeToken\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"hourlyLimit\",\"type\":\"uint256\"}],\"name\":\"setHourlyLimit\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"bridgeToken\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"limit\",\"type\":\"uint256\"}],\"name\":\"setLimit\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"bridgeToken\",\"type\":\"address\"},{\"internalType\":\"uint64\",\"name\":\"fee\",\"type\":\"uint64\"}],\"name\":\"setSwapFee\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_treasury\",\"type\":\"address\"}],\"name\":\"setTreasury\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"bridgeToken\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"swapIn\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"bridgeToken\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"swapOut\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"symbol\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"bridgeToken\",\"type\":\"address\"}],\"name\":\"toggleBridge\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"theAddress\",\"type\":\"address\"}],\"name\":\"toggleFeesForAddress\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"totalSupply\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"recipient\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"transfer\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"recipient\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"transferFrom\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"treasury\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"name\":\"usage\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"}],\"devdoc\":{\"author\":\"Angle Core Team\",\"details\":\"This contract supports bridge tokens having a minting right on the stablecoin (also referred to as the canonical or the native token)References: - FRAX implementation: https://polygonscan.com/address/0x45c32fA6DF82ead1e2EF74d17b76547EDdFaFF89#code - QiDAO implementation: https://snowtrace.io/address/0x5c49b268c9841AFF1Cc3B0a418ff5c3442eE3F3b#code\",\"kind\":\"dev\",\"methods\":{\"DOMAIN_SEPARATOR()\":{\"details\":\"See {IERC20Permit-DOMAIN_SEPARATOR}.\"},\"addBridgeToken(address,uint256,uint256,uint64,bool)\":{\"params\":{\"bridgeToken\":\"Bridge token to add: it should be a version of the stablecoin from another bridge\",\"fee\":\"Fee taken upon swapping for or against this token\",\"hourlyLimit\":\"Limit on the hourly volume for this bridge\",\"limit\":\"Limit on the balance of bridge token this contract could hold\",\"paused\":\"Whether swapping for this token should be paused or not\"}},\"addMinter(address)\":{\"details\":\"Zero address checks are performed directly in the `Treasury` contract\",\"params\":{\"minter\":\"Minter address to add\"}},\"allBridgeTokens()\":{\"details\":\"Helpful for UIs\"},\"allowance(address,address)\":{\"details\":\"See {IERC20-allowance}.\"},\"approve(address,uint256)\":{\"details\":\"See {IERC20-approve}. Requirements: - `spender` cannot be the zero address.\"},\"balanceOf(address)\":{\"details\":\"See {IERC20-balanceOf}.\"},\"burnFrom(uint256,address,address)\":{\"details\":\"This method is to be called by a contract with the minter right after being requested to do so by a `sender` address willing to burn tokens from another `burner` addressThe method checks the allowance between the `sender` and the `burner`\",\"params\":{\"amount\":\"Amount of tokens to burn\",\"burner\":\"Address to burn from\",\"sender\":\"Address which requested the burn from `burner`\"}},\"burnSelf(uint256,address)\":{\"details\":\"This method is to be called by a contract with a minter right on the AgToken after being requested to do so by an address willing to burn tokens from its address\",\"params\":{\"amount\":\"Amount of tokens to burn\",\"burner\":\"Address to burn from\"}},\"burnStablecoin(uint256)\":{\"details\":\"This function can typically be called if there is a settlement mechanism to burn stablecoins\",\"params\":{\"amount\":\"Amount of stablecoins to burn\"}},\"currentTotalUsage()\":{\"details\":\"Helpful for UIs\"},\"currentUsage(address)\":{\"details\":\"Helpful for UIs\",\"params\":{\"bridgeToken\":\"Bridge used to mint\"}},\"decimals()\":{\"details\":\"Returns the number of decimals used to get its user representation. For example, if `decimals` equals `2`, a balance of `505` tokens should be displayed to a user as `5.05` (`505 / 10 ** 2`). Tokens usually opt for a value of 18, imitating the relationship between Ether and Wei. This is the value {ERC20} uses, unless this function is overridden; NOTE: This information is only used for _display_ purposes: it in no way affects any of the arithmetic of the contract, including {IERC20-balanceOf} and {IERC20-transfer}.\"},\"decreaseAllowance(address,uint256)\":{\"details\":\"Atomically decreases the allowance granted to `spender` by the caller. This is an alternative to {approve} that can be used as a mitigation for problems described in {IERC20-approve}. Emits an {Approval} event indicating the updated allowance. Requirements: - `spender` cannot be the zero address. - `spender` must have allowance for the caller of at least `subtractedValue`.\"},\"increaseAllowance(address,uint256)\":{\"details\":\"Atomically increases the allowance granted to `spender` by the caller. This is an alternative to {approve} that can be used as a mitigation for problems described in {IERC20-approve}. Emits an {Approval} event indicating the updated allowance. Requirements: - `spender` cannot be the zero address.\"},\"initialize(string,string,address)\":{\"details\":\"By default, agTokens are ERC-20 tokens with 18 decimals\",\"params\":{\"_treasury\":\"Reference to the `Treasury` contract associated to this agToken\",\"name_\":\"Name of the token\",\"symbol_\":\"Symbol of the token\"}},\"mint(address,uint256)\":{\"details\":\"The contracts allowed to issue agTokens are the `StableMaster` contract, `VaultManager` contracts associated to this stablecoin as well as the flash loan module (if activated) and potentially contracts whitelisted by governance\",\"params\":{\"account\":\"Address to mint to\",\"amount\":\"Amount to mint\"}},\"name()\":{\"details\":\"Returns the name of the token.\"},\"nonces(address)\":{\"details\":\"See {IERC20Permit-nonces}.\"},\"permit(address,address,uint256,uint256,uint8,bytes32,bytes32)\":{\"details\":\"See {IERC20Permit-permit}.\"},\"recoverERC20(address,address,uint256)\":{\"details\":\"Can be used to withdraw bridge tokens for them to be de-bridged on mainnet\"},\"removeBridgeToken(address)\":{\"params\":{\"bridgeToken\":\"Address of the bridge token to remove support for\"}},\"removeMinter(address)\":{\"details\":\"This function can also be called by a minter wishing to revoke itself\",\"params\":{\"minter\":\"Minter address to remove\"}},\"setTreasury(address)\":{\"params\":{\"_treasury\":\"New treasury address\"}},\"swapIn(address,uint256,address)\":{\"details\":\"Some fees may be taken by the protocol depending on the token used and on the address calling\",\"params\":{\"amount\":\"Amount of bridge tokens to send\",\"bridgeToken\":\"Bridge token to use to mint\",\"to\":\"Address to which the stablecoin should be sent\"},\"returns\":{\"_0\":\"Amount of the canonical stablecoin actually minted\"}},\"swapOut(address,uint256,address)\":{\"details\":\"Some fees may be taken by the protocol depending on the token used and on the address calling\",\"params\":{\"amount\":\"Amount of canonical tokens to burn\",\"bridgeToken\":\"Bridge token required\",\"to\":\"Address to which the bridge token should be sent\"},\"returns\":{\"_0\":\"Amount of bridge tokens actually sent back\"}},\"symbol()\":{\"details\":\"Returns the symbol of the token, usually a shorter version of the name.\"},\"totalSupply()\":{\"details\":\"See {IERC20-totalSupply}.\"},\"transfer(address,uint256)\":{\"details\":\"See {IERC20-transfer}. Requirements: - `recipient` cannot be the zero address. - the caller must have a balance of at least `amount`.\"},\"transferFrom(address,address,uint256)\":{\"details\":\"See {IERC20-transferFrom}. Emits an {Approval} event indicating the updated allowance. This is not required by the EIP. See the note at the beginning of {ERC20}. Requirements: - `sender` and `recipient` cannot be the zero address. - `sender` must have a balance of at least `amount`. - the caller must have allowance for ``sender``'s tokens of at least `amount`.\"}},\"title\":\"AgTokenSideChainMultiBridge\",\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{\"BASE_PARAMS()\":{\"notice\":\"Base used for fee computation\"},\"addBridgeToken(address,uint256,uint256,uint64,bool)\":{\"notice\":\"Adds support for a bridge token\"},\"addMinter(address)\":{\"notice\":\"Adds a minter in the contract\"},\"allBridgeTokens()\":{\"notice\":\"Returns the list of all supported bridge tokens\"},\"bridgeTokensList(uint256)\":{\"notice\":\"List of all bridge tokens\"},\"bridges(address)\":{\"notice\":\"Maps a bridge token to data\"},\"burnFrom(uint256,address,address)\":{\"notice\":\"Burns `amount` tokens from a `burner` address after being asked to by `sender`\"},\"burnSelf(uint256,address)\":{\"notice\":\"Burns `amount` tokens from a `burner` address\"},\"burnStablecoin(uint256)\":{\"notice\":\"Allows anyone to burn agToken without redeeming collateral back\"},\"chainTotalHourlyLimit()\":{\"notice\":\"Limit to the amount of tokens that can be sent from that chain to another chain\"},\"chainTotalUsage(uint256)\":{\"notice\":\"Usage per hour on that chain. Maps an hourly timestamp to the total volume swapped out on the chain\"},\"currentTotalUsage()\":{\"notice\":\"Returns the current total volume on the chain for the current hour\"},\"currentUsage(address)\":{\"notice\":\"Returns the current volume for a bridge, for the current hour\"},\"initialize(string,string,address)\":{\"notice\":\"Initializes the `AgToken` contract\"},\"isFeeExempt(address)\":{\"notice\":\"Maps an address to whether it is exempt of fees for when it comes to swapping in and out\"},\"isMinter(address)\":{\"notice\":\"Checks whether an address has the right to mint agTokens\"},\"mint(address,uint256)\":{\"notice\":\"Lets the `StableMaster` contract or another whitelisted contract mint agTokens\"},\"recoverERC20(address,address,uint256)\":{\"notice\":\"Recovers any ERC20 token\"},\"removeBridgeToken(address)\":{\"notice\":\"Removes support for a token\"},\"removeMinter(address)\":{\"notice\":\"Removes a minter from the contract\"},\"setChainTotalHourlyLimit(uint256)\":{\"notice\":\"Updates the `chainTotalHourlyLimit` amount\"},\"setHourlyLimit(address,uint256)\":{\"notice\":\"Updates the `hourlyLimit` amount for `bridgeToken`\"},\"setLimit(address,uint256)\":{\"notice\":\"Updates the `limit` amount for `bridgeToken`\"},\"setSwapFee(address,uint64)\":{\"notice\":\"Updates the `fee` value for `bridgeToken`\"},\"setTreasury(address)\":{\"notice\":\"Sets a new treasury contract\"},\"swapIn(address,uint256,address)\":{\"notice\":\"Mints the canonical token from a supported bridge token\"},\"swapOut(address,uint256,address)\":{\"notice\":\"Burns the canonical token in exchange for a bridge token\"},\"toggleBridge(address)\":{\"notice\":\"Pauses or unpauses swapping in and out for a token\"},\"toggleFeesForAddress(address)\":{\"notice\":\"Toggles fees for the address `theAddress`\"},\"treasury()\":{\"notice\":\"Reference to the treasury contract which can grant minting rights\"},\"usage(address,uint256)\":{\"notice\":\"Maps a bridge token to the associated hourly volume\"}},\"notice\":\"Contract for Angle agTokens on other chains than Ethereum mainnet\",\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/agToken/AgTokenSideChainMultiBridge.sol\":\"AgTokenSideChainMultiBridge\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":1000000},\"remappings\":[]},\"sources\":{\"@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (proxy/utils/Initializable.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../../utils/AddressUpgradeable.sol\\\";\\n\\n/**\\n * @dev This is a base contract to aid in writing upgradeable contracts, or any kind of contract that will be deployed\\n * behind a proxy. Since a proxied contract can't have a constructor, it's common to move constructor logic to an\\n * external initializer function, usually called `initialize`. It then becomes necessary to protect this initializer\\n * function so it can only be called once. The {initializer} modifier provided by this contract will have this effect.\\n *\\n * TIP: To avoid leaving the proxy in an uninitialized state, the initializer function should be called as early as\\n * possible by providing the encoded function call as the `_data` argument to {ERC1967Proxy-constructor}.\\n *\\n * CAUTION: When used with inheritance, manual care must be taken to not invoke a parent initializer twice, or to ensure\\n * that all initializers are idempotent. This is not verified automatically as constructors are by Solidity.\\n *\\n * [CAUTION]\\n * ====\\n * Avoid leaving a contract uninitialized.\\n *\\n * An uninitialized contract can be taken over by an attacker. This applies to both a proxy and its implementation\\n * contract, which may impact the proxy. To initialize the implementation contract, you can either invoke the\\n * initializer manually, or you can include a constructor to automatically mark it as initialized when it is deployed:\\n *\\n * [.hljs-theme-light.nopadding]\\n * ```\\n * /// @custom:oz-upgrades-unsafe-allow constructor\\n * constructor() initializer {}\\n * ```\\n * ====\\n */\\nabstract contract Initializable {\\n /**\\n * @dev Indicates that the contract has been initialized.\\n */\\n bool private _initialized;\\n\\n /**\\n * @dev Indicates that the contract is in the process of being initialized.\\n */\\n bool private _initializing;\\n\\n /**\\n * @dev Modifier to protect an initializer function from being invoked twice.\\n */\\n modifier initializer() {\\n // If the contract is initializing we ignore whether _initialized is set in order to support multiple\\n // inheritance patterns, but we only do this in the context of a constructor, because in other contexts the\\n // contract may have been reentered.\\n require(_initializing ? _isConstructor() : !_initialized, \\\"Initializable: contract is already initialized\\\");\\n\\n bool isTopLevelCall = !_initializing;\\n if (isTopLevelCall) {\\n _initializing = true;\\n _initialized = true;\\n }\\n\\n _;\\n\\n if (isTopLevelCall) {\\n _initializing = false;\\n }\\n }\\n\\n /**\\n * @dev Modifier to protect an initialization function so that it can only be invoked by functions with the\\n * {initializer} modifier, directly or indirectly.\\n */\\n modifier onlyInitializing() {\\n require(_initializing, \\\"Initializable: contract is not initializing\\\");\\n _;\\n }\\n\\n function _isConstructor() private view returns (bool) {\\n return !AddressUpgradeable.isContract(address(this));\\n }\\n}\\n\",\"keccak256\":\"0x68861bcc80cacbd498efde75aab6c74a486cc48262660d326c8d7530d9752097\",\"license\":\"MIT\"},\"@openzeppelin/contracts-upgradeable/token/ERC20/ERC20Upgradeable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (token/ERC20/ERC20.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"./IERC20Upgradeable.sol\\\";\\nimport \\\"./extensions/IERC20MetadataUpgradeable.sol\\\";\\nimport \\\"../../utils/ContextUpgradeable.sol\\\";\\nimport \\\"../../proxy/utils/Initializable.sol\\\";\\n\\n/**\\n * @dev Implementation of the {IERC20} interface.\\n *\\n * This implementation is agnostic to the way tokens are created. This means\\n * that a supply mechanism has to be added in a derived contract using {_mint}.\\n * For a generic mechanism see {ERC20PresetMinterPauser}.\\n *\\n * TIP: For a detailed writeup see our guide\\n * https://forum.zeppelin.solutions/t/how-to-implement-erc20-supply-mechanisms/226[How\\n * to implement supply mechanisms].\\n *\\n * We have followed general OpenZeppelin Contracts guidelines: functions revert\\n * instead returning `false` on failure. This behavior is nonetheless\\n * conventional and does not conflict with the expectations of ERC20\\n * applications.\\n *\\n * Additionally, an {Approval} event is emitted on calls to {transferFrom}.\\n * This allows applications to reconstruct the allowance for all accounts just\\n * by listening to said events. Other implementations of the EIP may not emit\\n * these events, as it isn't required by the specification.\\n *\\n * Finally, the non-standard {decreaseAllowance} and {increaseAllowance}\\n * functions have been added to mitigate the well-known issues around setting\\n * allowances. See {IERC20-approve}.\\n */\\ncontract ERC20Upgradeable is Initializable, ContextUpgradeable, IERC20Upgradeable, IERC20MetadataUpgradeable {\\n mapping(address => uint256) private _balances;\\n\\n mapping(address => mapping(address => uint256)) private _allowances;\\n\\n uint256 private _totalSupply;\\n\\n string private _name;\\n string private _symbol;\\n\\n /**\\n * @dev Sets the values for {name} and {symbol}.\\n *\\n * The default value of {decimals} is 18. To select a different value for\\n * {decimals} you should overload it.\\n *\\n * All two of these values are immutable: they can only be set once during\\n * construction.\\n */\\n function __ERC20_init(string memory name_, string memory symbol_) internal onlyInitializing {\\n __Context_init_unchained();\\n __ERC20_init_unchained(name_, symbol_);\\n }\\n\\n function __ERC20_init_unchained(string memory name_, string memory symbol_) internal onlyInitializing {\\n _name = name_;\\n _symbol = symbol_;\\n }\\n\\n /**\\n * @dev Returns the name of the token.\\n */\\n function name() public view virtual override returns (string memory) {\\n return _name;\\n }\\n\\n /**\\n * @dev Returns the symbol of the token, usually a shorter version of the\\n * name.\\n */\\n function symbol() public view virtual override returns (string memory) {\\n return _symbol;\\n }\\n\\n /**\\n * @dev Returns the number of decimals used to get its user representation.\\n * For example, if `decimals` equals `2`, a balance of `505` tokens should\\n * be displayed to a user as `5.05` (`505 / 10 ** 2`).\\n *\\n * Tokens usually opt for a value of 18, imitating the relationship between\\n * Ether and Wei. This is the value {ERC20} uses, unless this function is\\n * overridden;\\n *\\n * NOTE: This information is only used for _display_ purposes: it in\\n * no way affects any of the arithmetic of the contract, including\\n * {IERC20-balanceOf} and {IERC20-transfer}.\\n */\\n function decimals() public view virtual override returns (uint8) {\\n return 18;\\n }\\n\\n /**\\n * @dev See {IERC20-totalSupply}.\\n */\\n function totalSupply() public view virtual override returns (uint256) {\\n return _totalSupply;\\n }\\n\\n /**\\n * @dev See {IERC20-balanceOf}.\\n */\\n function balanceOf(address account) public view virtual override returns (uint256) {\\n return _balances[account];\\n }\\n\\n /**\\n * @dev See {IERC20-transfer}.\\n *\\n * Requirements:\\n *\\n * - `recipient` cannot be the zero address.\\n * - the caller must have a balance of at least `amount`.\\n */\\n function transfer(address recipient, uint256 amount) public virtual override returns (bool) {\\n _transfer(_msgSender(), recipient, amount);\\n return true;\\n }\\n\\n /**\\n * @dev See {IERC20-allowance}.\\n */\\n function allowance(address owner, address spender) public view virtual override returns (uint256) {\\n return _allowances[owner][spender];\\n }\\n\\n /**\\n * @dev See {IERC20-approve}.\\n *\\n * Requirements:\\n *\\n * - `spender` cannot be the zero address.\\n */\\n function approve(address spender, uint256 amount) public virtual override returns (bool) {\\n _approve(_msgSender(), spender, amount);\\n return true;\\n }\\n\\n /**\\n * @dev See {IERC20-transferFrom}.\\n *\\n * Emits an {Approval} event indicating the updated allowance. This is not\\n * required by the EIP. See the note at the beginning of {ERC20}.\\n *\\n * Requirements:\\n *\\n * - `sender` and `recipient` cannot be the zero address.\\n * - `sender` must have a balance of at least `amount`.\\n * - the caller must have allowance for ``sender``'s tokens of at least\\n * `amount`.\\n */\\n function transferFrom(\\n address sender,\\n address recipient,\\n uint256 amount\\n ) public virtual override returns (bool) {\\n _transfer(sender, recipient, amount);\\n\\n uint256 currentAllowance = _allowances[sender][_msgSender()];\\n require(currentAllowance >= amount, \\\"ERC20: transfer amount exceeds allowance\\\");\\n unchecked {\\n _approve(sender, _msgSender(), currentAllowance - amount);\\n }\\n\\n return true;\\n }\\n\\n /**\\n * @dev Atomically increases the allowance granted to `spender` by the caller.\\n *\\n * This is an alternative to {approve} that can be used as a mitigation for\\n * problems described in {IERC20-approve}.\\n *\\n * Emits an {Approval} event indicating the updated allowance.\\n *\\n * Requirements:\\n *\\n * - `spender` cannot be the zero address.\\n */\\n function increaseAllowance(address spender, uint256 addedValue) public virtual returns (bool) {\\n _approve(_msgSender(), spender, _allowances[_msgSender()][spender] + addedValue);\\n return true;\\n }\\n\\n /**\\n * @dev Atomically decreases the allowance granted to `spender` by the caller.\\n *\\n * This is an alternative to {approve} that can be used as a mitigation for\\n * problems described in {IERC20-approve}.\\n *\\n * Emits an {Approval} event indicating the updated allowance.\\n *\\n * Requirements:\\n *\\n * - `spender` cannot be the zero address.\\n * - `spender` must have allowance for the caller of at least\\n * `subtractedValue`.\\n */\\n function decreaseAllowance(address spender, uint256 subtractedValue) public virtual returns (bool) {\\n uint256 currentAllowance = _allowances[_msgSender()][spender];\\n require(currentAllowance >= subtractedValue, \\\"ERC20: decreased allowance below zero\\\");\\n unchecked {\\n _approve(_msgSender(), spender, currentAllowance - subtractedValue);\\n }\\n\\n return true;\\n }\\n\\n /**\\n * @dev Moves `amount` of tokens from `sender` to `recipient`.\\n *\\n * This internal function is equivalent to {transfer}, and can be used to\\n * e.g. implement automatic token fees, slashing mechanisms, etc.\\n *\\n * Emits a {Transfer} event.\\n *\\n * Requirements:\\n *\\n * - `sender` cannot be the zero address.\\n * - `recipient` cannot be the zero address.\\n * - `sender` must have a balance of at least `amount`.\\n */\\n function _transfer(\\n address sender,\\n address recipient,\\n uint256 amount\\n ) internal virtual {\\n require(sender != address(0), \\\"ERC20: transfer from the zero address\\\");\\n require(recipient != address(0), \\\"ERC20: transfer to the zero address\\\");\\n\\n _beforeTokenTransfer(sender, recipient, amount);\\n\\n uint256 senderBalance = _balances[sender];\\n require(senderBalance >= amount, \\\"ERC20: transfer amount exceeds balance\\\");\\n unchecked {\\n _balances[sender] = senderBalance - amount;\\n }\\n _balances[recipient] += amount;\\n\\n emit Transfer(sender, recipient, amount);\\n\\n _afterTokenTransfer(sender, recipient, amount);\\n }\\n\\n /** @dev Creates `amount` tokens and assigns them to `account`, increasing\\n * the total supply.\\n *\\n * Emits a {Transfer} event with `from` set to the zero address.\\n *\\n * Requirements:\\n *\\n * - `account` cannot be the zero address.\\n */\\n function _mint(address account, uint256 amount) internal virtual {\\n require(account != address(0), \\\"ERC20: mint to the zero address\\\");\\n\\n _beforeTokenTransfer(address(0), account, amount);\\n\\n _totalSupply += amount;\\n _balances[account] += amount;\\n emit Transfer(address(0), account, amount);\\n\\n _afterTokenTransfer(address(0), account, amount);\\n }\\n\\n /**\\n * @dev Destroys `amount` tokens from `account`, reducing the\\n * total supply.\\n *\\n * Emits a {Transfer} event with `to` set to the zero address.\\n *\\n * Requirements:\\n *\\n * - `account` cannot be the zero address.\\n * - `account` must have at least `amount` tokens.\\n */\\n function _burn(address account, uint256 amount) internal virtual {\\n require(account != address(0), \\\"ERC20: burn from the zero address\\\");\\n\\n _beforeTokenTransfer(account, address(0), amount);\\n\\n uint256 accountBalance = _balances[account];\\n require(accountBalance >= amount, \\\"ERC20: burn amount exceeds balance\\\");\\n unchecked {\\n _balances[account] = accountBalance - amount;\\n }\\n _totalSupply -= amount;\\n\\n emit Transfer(account, address(0), amount);\\n\\n _afterTokenTransfer(account, address(0), amount);\\n }\\n\\n /**\\n * @dev Sets `amount` as the allowance of `spender` over the `owner` s tokens.\\n *\\n * This internal function is equivalent to `approve`, and can be used to\\n * e.g. set automatic allowances for certain subsystems, etc.\\n *\\n * Emits an {Approval} event.\\n *\\n * Requirements:\\n *\\n * - `owner` cannot be the zero address.\\n * - `spender` cannot be the zero address.\\n */\\n function _approve(\\n address owner,\\n address spender,\\n uint256 amount\\n ) internal virtual {\\n require(owner != address(0), \\\"ERC20: approve from the zero address\\\");\\n require(spender != address(0), \\\"ERC20: approve to the zero address\\\");\\n\\n _allowances[owner][spender] = amount;\\n emit Approval(owner, spender, amount);\\n }\\n\\n /**\\n * @dev Hook that is called before any transfer of tokens. This includes\\n * minting and burning.\\n *\\n * Calling conditions:\\n *\\n * - when `from` and `to` are both non-zero, `amount` of ``from``'s tokens\\n * will be transferred to `to`.\\n * - when `from` is zero, `amount` tokens will be minted for `to`.\\n * - when `to` is zero, `amount` of ``from``'s tokens will be burned.\\n * - `from` and `to` are never both zero.\\n *\\n * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].\\n */\\n function _beforeTokenTransfer(\\n address from,\\n address to,\\n uint256 amount\\n ) internal virtual {}\\n\\n /**\\n * @dev Hook that is called after any transfer of tokens. This includes\\n * minting and burning.\\n *\\n * Calling conditions:\\n *\\n * - when `from` and `to` are both non-zero, `amount` of ``from``'s tokens\\n * has been transferred to `to`.\\n * - when `from` is zero, `amount` tokens have been minted for `to`.\\n * - when `to` is zero, `amount` of ``from``'s tokens have been burned.\\n * - `from` and `to` are never both zero.\\n *\\n * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].\\n */\\n function _afterTokenTransfer(\\n address from,\\n address to,\\n uint256 amount\\n ) internal virtual {}\\n uint256[45] private __gap;\\n}\\n\",\"keccak256\":\"0x23a373902059fb51db98e32e13f89a0ef0c570039081a1345022e66bc7e315d4\",\"license\":\"MIT\"},\"@openzeppelin/contracts-upgradeable/token/ERC20/IERC20Upgradeable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (token/ERC20/IERC20.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Interface of the ERC20 standard as defined in the EIP.\\n */\\ninterface IERC20Upgradeable {\\n /**\\n * @dev Returns the amount of tokens in existence.\\n */\\n function totalSupply() external view returns (uint256);\\n\\n /**\\n * @dev Returns the amount of tokens owned by `account`.\\n */\\n function balanceOf(address account) external view returns (uint256);\\n\\n /**\\n * @dev Moves `amount` tokens from the caller's account to `recipient`.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * Emits a {Transfer} event.\\n */\\n function transfer(address recipient, uint256 amount) external returns (bool);\\n\\n /**\\n * @dev Returns the remaining number of tokens that `spender` will be\\n * allowed to spend on behalf of `owner` through {transferFrom}. This is\\n * zero by default.\\n *\\n * This value changes when {approve} or {transferFrom} are called.\\n */\\n function allowance(address owner, address spender) external view returns (uint256);\\n\\n /**\\n * @dev Sets `amount` as the allowance of `spender` over the caller's tokens.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * IMPORTANT: Beware that changing an allowance with this method brings the risk\\n * that someone may use both the old and the new allowance by unfortunate\\n * transaction ordering. One possible solution to mitigate this race\\n * condition is to first reduce the spender's allowance to 0 and set the\\n * desired value afterwards:\\n * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729\\n *\\n * Emits an {Approval} event.\\n */\\n function approve(address spender, uint256 amount) external returns (bool);\\n\\n /**\\n * @dev Moves `amount` tokens from `sender` to `recipient` using the\\n * allowance mechanism. `amount` is then deducted from the caller's\\n * allowance.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * Emits a {Transfer} event.\\n */\\n function transferFrom(\\n address sender,\\n address recipient,\\n uint256 amount\\n ) external returns (bool);\\n\\n /**\\n * @dev Emitted when `value` tokens are moved from one account (`from`) to\\n * another (`to`).\\n *\\n * Note that `value` may be zero.\\n */\\n event Transfer(address indexed from, address indexed to, uint256 value);\\n\\n /**\\n * @dev Emitted when the allowance of a `spender` for an `owner` is set by\\n * a call to {approve}. `value` is the new allowance.\\n */\\n event Approval(address indexed owner, address indexed spender, uint256 value);\\n}\\n\",\"keccak256\":\"0x5ca0eb1120133a6d0799752532d4638048391823a2b623c4fe9ff46e262266fb\",\"license\":\"MIT\"},\"@openzeppelin/contracts-upgradeable/token/ERC20/extensions/IERC20MetadataUpgradeable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (token/ERC20/extensions/IERC20Metadata.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../IERC20Upgradeable.sol\\\";\\n\\n/**\\n * @dev Interface for the optional metadata functions from the ERC20 standard.\\n *\\n * _Available since v4.1._\\n */\\ninterface IERC20MetadataUpgradeable is IERC20Upgradeable {\\n /**\\n * @dev Returns the name of the token.\\n */\\n function name() external view returns (string memory);\\n\\n /**\\n * @dev Returns the symbol of the token.\\n */\\n function symbol() external view returns (string memory);\\n\\n /**\\n * @dev Returns the decimals places of the token.\\n */\\n function decimals() external view returns (uint8);\\n}\\n\",\"keccak256\":\"0x605434219ebbe4653f703640f06969faa5a1d78f0bfef878e5ddbb1ca369ceeb\",\"license\":\"MIT\"},\"@openzeppelin/contracts-upgradeable/token/ERC20/extensions/draft-ERC20PermitUpgradeable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (token/ERC20/extensions/draft-ERC20Permit.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"./draft-IERC20PermitUpgradeable.sol\\\";\\nimport \\\"../ERC20Upgradeable.sol\\\";\\nimport \\\"../../../utils/cryptography/draft-EIP712Upgradeable.sol\\\";\\nimport \\\"../../../utils/cryptography/ECDSAUpgradeable.sol\\\";\\nimport \\\"../../../utils/CountersUpgradeable.sol\\\";\\nimport \\\"../../../proxy/utils/Initializable.sol\\\";\\n\\n/**\\n * @dev Implementation of the ERC20 Permit extension allowing approvals to be made via signatures, as defined in\\n * https://eips.ethereum.org/EIPS/eip-2612[EIP-2612].\\n *\\n * Adds the {permit} method, which can be used to change an account's ERC20 allowance (see {IERC20-allowance}) by\\n * presenting a message signed by the account. By not relying on `{IERC20-approve}`, the token holder account doesn't\\n * need to send a transaction, and thus is not required to hold Ether at all.\\n *\\n * _Available since v3.4._\\n */\\nabstract contract ERC20PermitUpgradeable is Initializable, ERC20Upgradeable, IERC20PermitUpgradeable, EIP712Upgradeable {\\n using CountersUpgradeable for CountersUpgradeable.Counter;\\n\\n mapping(address => CountersUpgradeable.Counter) private _nonces;\\n\\n // solhint-disable-next-line var-name-mixedcase\\n bytes32 private _PERMIT_TYPEHASH;\\n\\n /**\\n * @dev Initializes the {EIP712} domain separator using the `name` parameter, and setting `version` to `\\\"1\\\"`.\\n *\\n * It's a good idea to use the same `name` that is defined as the ERC20 token name.\\n */\\n function __ERC20Permit_init(string memory name) internal onlyInitializing {\\n __Context_init_unchained();\\n __EIP712_init_unchained(name, \\\"1\\\");\\n __ERC20Permit_init_unchained(name);\\n }\\n\\n function __ERC20Permit_init_unchained(string memory name) internal onlyInitializing {\\n _PERMIT_TYPEHASH = keccak256(\\\"Permit(address owner,address spender,uint256 value,uint256 nonce,uint256 deadline)\\\");}\\n\\n /**\\n * @dev See {IERC20Permit-permit}.\\n */\\n function permit(\\n address owner,\\n address spender,\\n uint256 value,\\n uint256 deadline,\\n uint8 v,\\n bytes32 r,\\n bytes32 s\\n ) public virtual override {\\n require(block.timestamp <= deadline, \\\"ERC20Permit: expired deadline\\\");\\n\\n bytes32 structHash = keccak256(abi.encode(_PERMIT_TYPEHASH, owner, spender, value, _useNonce(owner), deadline));\\n\\n bytes32 hash = _hashTypedDataV4(structHash);\\n\\n address signer = ECDSAUpgradeable.recover(hash, v, r, s);\\n require(signer == owner, \\\"ERC20Permit: invalid signature\\\");\\n\\n _approve(owner, spender, value);\\n }\\n\\n /**\\n * @dev See {IERC20Permit-nonces}.\\n */\\n function nonces(address owner) public view virtual override returns (uint256) {\\n return _nonces[owner].current();\\n }\\n\\n /**\\n * @dev See {IERC20Permit-DOMAIN_SEPARATOR}.\\n */\\n // solhint-disable-next-line func-name-mixedcase\\n function DOMAIN_SEPARATOR() external view override returns (bytes32) {\\n return _domainSeparatorV4();\\n }\\n\\n /**\\n * @dev \\\"Consume a nonce\\\": return the current value and increment.\\n *\\n * _Available since v4.1._\\n */\\n function _useNonce(address owner) internal virtual returns (uint256 current) {\\n CountersUpgradeable.Counter storage nonce = _nonces[owner];\\n current = nonce.current();\\n nonce.increment();\\n }\\n uint256[49] private __gap;\\n}\\n\",\"keccak256\":\"0x7fb71e823080ba5e320f036c7dbda29f3676f3d516db4dcdb8b0adbfbae5d830\",\"license\":\"MIT\"},\"@openzeppelin/contracts-upgradeable/token/ERC20/extensions/draft-IERC20PermitUpgradeable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (token/ERC20/extensions/draft-IERC20Permit.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Interface of the ERC20 Permit extension allowing approvals to be made via signatures, as defined in\\n * https://eips.ethereum.org/EIPS/eip-2612[EIP-2612].\\n *\\n * Adds the {permit} method, which can be used to change an account's ERC20 allowance (see {IERC20-allowance}) by\\n * presenting a message signed by the account. By not relying on {IERC20-approve}, the token holder account doesn't\\n * need to send a transaction, and thus is not required to hold Ether at all.\\n */\\ninterface IERC20PermitUpgradeable {\\n /**\\n * @dev Sets `value` as the allowance of `spender` over ``owner``'s tokens,\\n * given ``owner``'s signed approval.\\n *\\n * IMPORTANT: The same issues {IERC20-approve} has related to transaction\\n * ordering also apply here.\\n *\\n * Emits an {Approval} event.\\n *\\n * Requirements:\\n *\\n * - `spender` cannot be the zero address.\\n * - `deadline` must be a timestamp in the future.\\n * - `v`, `r` and `s` must be a valid `secp256k1` signature from `owner`\\n * over the EIP712-formatted function arguments.\\n * - the signature must use ``owner``'s current nonce (see {nonces}).\\n *\\n * For more information on the signature format, see the\\n * https://eips.ethereum.org/EIPS/eip-2612#specification[relevant EIP\\n * section].\\n */\\n function permit(\\n address owner,\\n address spender,\\n uint256 value,\\n uint256 deadline,\\n uint8 v,\\n bytes32 r,\\n bytes32 s\\n ) external;\\n\\n /**\\n * @dev Returns the current nonce for `owner`. This value must be\\n * included whenever a signature is generated for {permit}.\\n *\\n * Every successful call to {permit} increases ``owner``'s nonce by one. This\\n * prevents a signature from being used multiple times.\\n */\\n function nonces(address owner) external view returns (uint256);\\n\\n /**\\n * @dev Returns the domain separator used in the encoding of the signature for {permit}, as defined by {EIP712}.\\n */\\n // solhint-disable-next-line func-name-mixedcase\\n function DOMAIN_SEPARATOR() external view returns (bytes32);\\n}\\n\",\"keccak256\":\"0xcc70d8e2281fb3ff69e8ab242500f10142cd0a7fa8dd9e45882be270d4d09024\",\"license\":\"MIT\"},\"@openzeppelin/contracts-upgradeable/utils/AddressUpgradeable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (utils/Address.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Collection of functions related to the address type\\n */\\nlibrary AddressUpgradeable {\\n /**\\n * @dev Returns true if `account` is a contract.\\n *\\n * [IMPORTANT]\\n * ====\\n * It is unsafe to assume that an address for which this function returns\\n * false is an externally-owned account (EOA) and not a contract.\\n *\\n * Among others, `isContract` will return false for the following\\n * types of addresses:\\n *\\n * - an externally-owned account\\n * - a contract in construction\\n * - an address where a contract will be created\\n * - an address where a contract lived, but was destroyed\\n * ====\\n */\\n function isContract(address account) internal view returns (bool) {\\n // This method relies on extcodesize, which returns 0 for contracts in\\n // construction, since the code is only stored at the end of the\\n // constructor execution.\\n\\n uint256 size;\\n assembly {\\n size := extcodesize(account)\\n }\\n return size > 0;\\n }\\n\\n /**\\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\\n * `recipient`, forwarding all available gas and reverting on errors.\\n *\\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\\n * imposed by `transfer`, making them unable to receive funds via\\n * `transfer`. {sendValue} removes this limitation.\\n *\\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\\n *\\n * IMPORTANT: because control is transferred to `recipient`, care must be\\n * taken to not create reentrancy vulnerabilities. Consider using\\n * {ReentrancyGuard} or the\\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\\n */\\n function sendValue(address payable recipient, uint256 amount) internal {\\n require(address(this).balance >= amount, \\\"Address: insufficient balance\\\");\\n\\n (bool success, ) = recipient.call{value: amount}(\\\"\\\");\\n require(success, \\\"Address: unable to send value, recipient may have reverted\\\");\\n }\\n\\n /**\\n * @dev Performs a Solidity function call using a low level `call`. A\\n * plain `call` is an unsafe replacement for a function call: use this\\n * function instead.\\n *\\n * If `target` reverts with a revert reason, it is bubbled up by this\\n * function (like regular Solidity function calls).\\n *\\n * Returns the raw returned data. To convert to the expected return value,\\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\\n *\\n * Requirements:\\n *\\n * - `target` must be a contract.\\n * - calling `target` with `data` must not revert.\\n *\\n * _Available since v3.1._\\n */\\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\\n return functionCall(target, data, \\\"Address: low-level call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\\n * `errorMessage` as a fallback revert reason when `target` reverts.\\n *\\n * _Available since v3.1._\\n */\\n function functionCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n return functionCallWithValue(target, data, 0, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but also transferring `value` wei to `target`.\\n *\\n * Requirements:\\n *\\n * - the calling contract must have an ETH balance of at least `value`.\\n * - the called Solidity function must be `payable`.\\n *\\n * _Available since v3.1._\\n */\\n function functionCallWithValue(\\n address target,\\n bytes memory data,\\n uint256 value\\n ) internal returns (bytes memory) {\\n return functionCallWithValue(target, data, value, \\\"Address: low-level call with value failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\\n * with `errorMessage` as a fallback revert reason when `target` reverts.\\n *\\n * _Available since v3.1._\\n */\\n function functionCallWithValue(\\n address target,\\n bytes memory data,\\n uint256 value,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n require(address(this).balance >= value, \\\"Address: insufficient balance for call\\\");\\n require(isContract(target), \\\"Address: call to non-contract\\\");\\n\\n (bool success, bytes memory returndata) = target.call{value: value}(data);\\n return verifyCallResult(success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but performing a static call.\\n *\\n * _Available since v3.3._\\n */\\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\\n return functionStaticCall(target, data, \\\"Address: low-level static call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\\n * but performing a static call.\\n *\\n * _Available since v3.3._\\n */\\n function functionStaticCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal view returns (bytes memory) {\\n require(isContract(target), \\\"Address: static call to non-contract\\\");\\n\\n (bool success, bytes memory returndata) = target.staticcall(data);\\n return verifyCallResult(success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the\\n * revert reason using the provided one.\\n *\\n * _Available since v4.3._\\n */\\n function verifyCallResult(\\n bool success,\\n bytes memory returndata,\\n string memory errorMessage\\n ) internal pure returns (bytes memory) {\\n if (success) {\\n return returndata;\\n } else {\\n // Look for revert reason and bubble it up if present\\n if (returndata.length > 0) {\\n // The easiest way to bubble the revert reason is using memory via assembly\\n\\n assembly {\\n let returndata_size := mload(returndata)\\n revert(add(32, returndata), returndata_size)\\n }\\n } else {\\n revert(errorMessage);\\n }\\n }\\n }\\n}\\n\",\"keccak256\":\"0x3f0f878c796dfc7feba6d3c4e3e526c14c7deae8b7bfc71088e3f38fab0d77b3\",\"license\":\"MIT\"},\"@openzeppelin/contracts-upgradeable/utils/ContextUpgradeable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)\\n\\npragma solidity ^0.8.0;\\nimport \\\"../proxy/utils/Initializable.sol\\\";\\n\\n/**\\n * @dev Provides information about the current execution context, including the\\n * sender of the transaction and its data. While these are generally available\\n * via msg.sender and msg.data, they should not be accessed in such a direct\\n * manner, since when dealing with meta-transactions the account sending and\\n * paying for execution may not be the actual sender (as far as an application\\n * is concerned).\\n *\\n * This contract is only required for intermediate, library-like contracts.\\n */\\nabstract contract ContextUpgradeable is Initializable {\\n function __Context_init() internal onlyInitializing {\\n __Context_init_unchained();\\n }\\n\\n function __Context_init_unchained() internal onlyInitializing {\\n }\\n function _msgSender() internal view virtual returns (address) {\\n return msg.sender;\\n }\\n\\n function _msgData() internal view virtual returns (bytes calldata) {\\n return msg.data;\\n }\\n uint256[50] private __gap;\\n}\\n\",\"keccak256\":\"0x0b0d548f6381370d394f7a434f994dc678b3ef3e755de106109d61343a685ea7\",\"license\":\"MIT\"},\"@openzeppelin/contracts-upgradeable/utils/CountersUpgradeable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (utils/Counters.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @title Counters\\n * @author Matt Condon (@shrugs)\\n * @dev Provides counters that can only be incremented, decremented or reset. This can be used e.g. to track the number\\n * of elements in a mapping, issuing ERC721 ids, or counting request ids.\\n *\\n * Include with `using Counters for Counters.Counter;`\\n */\\nlibrary CountersUpgradeable {\\n struct Counter {\\n // This variable should never be directly accessed by users of the library: interactions must be restricted to\\n // the library's function. As of Solidity v0.5.2, this cannot be enforced, though there is a proposal to add\\n // this feature: see https://github.com/ethereum/solidity/issues/4637\\n uint256 _value; // default: 0\\n }\\n\\n function current(Counter storage counter) internal view returns (uint256) {\\n return counter._value;\\n }\\n\\n function increment(Counter storage counter) internal {\\n unchecked {\\n counter._value += 1;\\n }\\n }\\n\\n function decrement(Counter storage counter) internal {\\n uint256 value = counter._value;\\n require(value > 0, \\\"Counter: decrement overflow\\\");\\n unchecked {\\n counter._value = value - 1;\\n }\\n }\\n\\n function reset(Counter storage counter) internal {\\n counter._value = 0;\\n }\\n}\\n\",\"keccak256\":\"0x798741e231b22b81e2dd2eddaaf8832dee4baf5cd8e2dbaa5c1dd12a1c053c4d\",\"license\":\"MIT\"},\"@openzeppelin/contracts-upgradeable/utils/StringsUpgradeable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (utils/Strings.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev String operations.\\n */\\nlibrary StringsUpgradeable {\\n bytes16 private constant _HEX_SYMBOLS = \\\"0123456789abcdef\\\";\\n\\n /**\\n * @dev Converts a `uint256` to its ASCII `string` decimal representation.\\n */\\n function toString(uint256 value) internal pure returns (string memory) {\\n // Inspired by OraclizeAPI's implementation - MIT licence\\n // https://github.com/oraclize/ethereum-api/blob/b42146b063c7d6ee1358846c198246239e9360e8/oraclizeAPI_0.4.25.sol\\n\\n if (value == 0) {\\n return \\\"0\\\";\\n }\\n uint256 temp = value;\\n uint256 digits;\\n while (temp != 0) {\\n digits++;\\n temp /= 10;\\n }\\n bytes memory buffer = new bytes(digits);\\n while (value != 0) {\\n digits -= 1;\\n buffer[digits] = bytes1(uint8(48 + uint256(value % 10)));\\n value /= 10;\\n }\\n return string(buffer);\\n }\\n\\n /**\\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation.\\n */\\n function toHexString(uint256 value) internal pure returns (string memory) {\\n if (value == 0) {\\n return \\\"0x00\\\";\\n }\\n uint256 temp = value;\\n uint256 length = 0;\\n while (temp != 0) {\\n length++;\\n temp >>= 8;\\n }\\n return toHexString(value, length);\\n }\\n\\n /**\\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length.\\n */\\n function toHexString(uint256 value, uint256 length) internal pure returns (string memory) {\\n bytes memory buffer = new bytes(2 * length + 2);\\n buffer[0] = \\\"0\\\";\\n buffer[1] = \\\"x\\\";\\n for (uint256 i = 2 * length + 1; i > 1; --i) {\\n buffer[i] = _HEX_SYMBOLS[value & 0xf];\\n value >>= 4;\\n }\\n require(value == 0, \\\"Strings: hex length insufficient\\\");\\n return string(buffer);\\n }\\n}\\n\",\"keccak256\":\"0x398d3323c1932a5986bf36be7c57593e121e69d5db5b6574b4ee0d031443de37\",\"license\":\"MIT\"},\"@openzeppelin/contracts-upgradeable/utils/cryptography/ECDSAUpgradeable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (utils/cryptography/ECDSA.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../StringsUpgradeable.sol\\\";\\n\\n/**\\n * @dev Elliptic Curve Digital Signature Algorithm (ECDSA) operations.\\n *\\n * These functions can be used to verify that a message was signed by the holder\\n * of the private keys of a given address.\\n */\\nlibrary ECDSAUpgradeable {\\n enum RecoverError {\\n NoError,\\n InvalidSignature,\\n InvalidSignatureLength,\\n InvalidSignatureS,\\n InvalidSignatureV\\n }\\n\\n function _throwError(RecoverError error) private pure {\\n if (error == RecoverError.NoError) {\\n return; // no error: do nothing\\n } else if (error == RecoverError.InvalidSignature) {\\n revert(\\\"ECDSA: invalid signature\\\");\\n } else if (error == RecoverError.InvalidSignatureLength) {\\n revert(\\\"ECDSA: invalid signature length\\\");\\n } else if (error == RecoverError.InvalidSignatureS) {\\n revert(\\\"ECDSA: invalid signature 's' value\\\");\\n } else if (error == RecoverError.InvalidSignatureV) {\\n revert(\\\"ECDSA: invalid signature 'v' value\\\");\\n }\\n }\\n\\n /**\\n * @dev Returns the address that signed a hashed message (`hash`) with\\n * `signature` or error string. This address can then be used for verification purposes.\\n *\\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\\n * this function rejects them by requiring the `s` value to be in the lower\\n * half order, and the `v` value to be either 27 or 28.\\n *\\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\\n * verification to be secure: it is possible to craft signatures that\\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\\n * this is by receiving a hash of the original message (which may otherwise\\n * be too long), and then calling {toEthSignedMessageHash} on it.\\n *\\n * Documentation for signature generation:\\n * - with https://web3js.readthedocs.io/en/v1.3.4/web3-eth-accounts.html#sign[Web3.js]\\n * - with https://docs.ethers.io/v5/api/signer/#Signer-signMessage[ethers]\\n *\\n * _Available since v4.3._\\n */\\n function tryRecover(bytes32 hash, bytes memory signature) internal pure returns (address, RecoverError) {\\n // Check the signature length\\n // - case 65: r,s,v signature (standard)\\n // - case 64: r,vs signature (cf https://eips.ethereum.org/EIPS/eip-2098) _Available since v4.1._\\n if (signature.length == 65) {\\n bytes32 r;\\n bytes32 s;\\n uint8 v;\\n // ecrecover takes the signature parameters, and the only way to get them\\n // currently is to use assembly.\\n assembly {\\n r := mload(add(signature, 0x20))\\n s := mload(add(signature, 0x40))\\n v := byte(0, mload(add(signature, 0x60)))\\n }\\n return tryRecover(hash, v, r, s);\\n } else if (signature.length == 64) {\\n bytes32 r;\\n bytes32 vs;\\n // ecrecover takes the signature parameters, and the only way to get them\\n // currently is to use assembly.\\n assembly {\\n r := mload(add(signature, 0x20))\\n vs := mload(add(signature, 0x40))\\n }\\n return tryRecover(hash, r, vs);\\n } else {\\n return (address(0), RecoverError.InvalidSignatureLength);\\n }\\n }\\n\\n /**\\n * @dev Returns the address that signed a hashed message (`hash`) with\\n * `signature`. This address can then be used for verification purposes.\\n *\\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\\n * this function rejects them by requiring the `s` value to be in the lower\\n * half order, and the `v` value to be either 27 or 28.\\n *\\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\\n * verification to be secure: it is possible to craft signatures that\\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\\n * this is by receiving a hash of the original message (which may otherwise\\n * be too long), and then calling {toEthSignedMessageHash} on it.\\n */\\n function recover(bytes32 hash, bytes memory signature) internal pure returns (address) {\\n (address recovered, RecoverError error) = tryRecover(hash, signature);\\n _throwError(error);\\n return recovered;\\n }\\n\\n /**\\n * @dev Overload of {ECDSA-tryRecover} that receives the `r` and `vs` short-signature fields separately.\\n *\\n * See https://eips.ethereum.org/EIPS/eip-2098[EIP-2098 short signatures]\\n *\\n * _Available since v4.3._\\n */\\n function tryRecover(\\n bytes32 hash,\\n bytes32 r,\\n bytes32 vs\\n ) internal pure returns (address, RecoverError) {\\n bytes32 s;\\n uint8 v;\\n assembly {\\n s := and(vs, 0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff)\\n v := add(shr(255, vs), 27)\\n }\\n return tryRecover(hash, v, r, s);\\n }\\n\\n /**\\n * @dev Overload of {ECDSA-recover} that receives the `r and `vs` short-signature fields separately.\\n *\\n * _Available since v4.2._\\n */\\n function recover(\\n bytes32 hash,\\n bytes32 r,\\n bytes32 vs\\n ) internal pure returns (address) {\\n (address recovered, RecoverError error) = tryRecover(hash, r, vs);\\n _throwError(error);\\n return recovered;\\n }\\n\\n /**\\n * @dev Overload of {ECDSA-tryRecover} that receives the `v`,\\n * `r` and `s` signature fields separately.\\n *\\n * _Available since v4.3._\\n */\\n function tryRecover(\\n bytes32 hash,\\n uint8 v,\\n bytes32 r,\\n bytes32 s\\n ) internal pure returns (address, RecoverError) {\\n // EIP-2 still allows signature malleability for ecrecover(). Remove this possibility and make the signature\\n // unique. Appendix F in the Ethereum Yellow paper (https://ethereum.github.io/yellowpaper/paper.pdf), defines\\n // the valid range for s in (301): 0 < s < secp256k1n \\u00f7 2 + 1, and for v in (302): v \\u2208 {27, 28}. Most\\n // signatures from current libraries generate a unique signature with an s-value in the lower half order.\\n //\\n // If your library generates malleable signatures, such as s-values in the upper range, calculate a new s-value\\n // with 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141 - s1 and flip v from 27 to 28 or\\n // vice versa. If your library also generates signatures with 0/1 for v instead 27/28, add 27 to v to accept\\n // these malleable signatures as well.\\n if (uint256(s) > 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D576E7357A4501DDFE92F46681B20A0) {\\n return (address(0), RecoverError.InvalidSignatureS);\\n }\\n if (v != 27 && v != 28) {\\n return (address(0), RecoverError.InvalidSignatureV);\\n }\\n\\n // If the signature is valid (and not malleable), return the signer address\\n address signer = ecrecover(hash, v, r, s);\\n if (signer == address(0)) {\\n return (address(0), RecoverError.InvalidSignature);\\n }\\n\\n return (signer, RecoverError.NoError);\\n }\\n\\n /**\\n * @dev Overload of {ECDSA-recover} that receives the `v`,\\n * `r` and `s` signature fields separately.\\n */\\n function recover(\\n bytes32 hash,\\n uint8 v,\\n bytes32 r,\\n bytes32 s\\n ) internal pure returns (address) {\\n (address recovered, RecoverError error) = tryRecover(hash, v, r, s);\\n _throwError(error);\\n return recovered;\\n }\\n\\n /**\\n * @dev Returns an Ethereum Signed Message, created from a `hash`. This\\n * produces hash corresponding to the one signed with the\\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\\n * JSON-RPC method as part of EIP-191.\\n *\\n * See {recover}.\\n */\\n function toEthSignedMessageHash(bytes32 hash) internal pure returns (bytes32) {\\n // 32 is the length in bytes of hash,\\n // enforced by the type signature above\\n return keccak256(abi.encodePacked(\\\"\\\\x19Ethereum Signed Message:\\\\n32\\\", hash));\\n }\\n\\n /**\\n * @dev Returns an Ethereum Signed Message, created from `s`. This\\n * produces hash corresponding to the one signed with the\\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\\n * JSON-RPC method as part of EIP-191.\\n *\\n * See {recover}.\\n */\\n function toEthSignedMessageHash(bytes memory s) internal pure returns (bytes32) {\\n return keccak256(abi.encodePacked(\\\"\\\\x19Ethereum Signed Message:\\\\n\\\", StringsUpgradeable.toString(s.length), s));\\n }\\n\\n /**\\n * @dev Returns an Ethereum Signed Typed Data, created from a\\n * `domainSeparator` and a `structHash`. This produces hash corresponding\\n * to the one signed with the\\n * https://eips.ethereum.org/EIPS/eip-712[`eth_signTypedData`]\\n * JSON-RPC method as part of EIP-712.\\n *\\n * See {recover}.\\n */\\n function toTypedDataHash(bytes32 domainSeparator, bytes32 structHash) internal pure returns (bytes32) {\\n return keccak256(abi.encodePacked(\\\"\\\\x19\\\\x01\\\", domainSeparator, structHash));\\n }\\n}\\n\",\"keccak256\":\"0x1762ac67d230279d7fb183567ce22bbe202054ce08f94224d8794f9d19546d51\",\"license\":\"MIT\"},\"@openzeppelin/contracts-upgradeable/utils/cryptography/draft-EIP712Upgradeable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (utils/cryptography/draft-EIP712.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"./ECDSAUpgradeable.sol\\\";\\nimport \\\"../../proxy/utils/Initializable.sol\\\";\\n\\n/**\\n * @dev https://eips.ethereum.org/EIPS/eip-712[EIP 712] is a standard for hashing and signing of typed structured data.\\n *\\n * The encoding specified in the EIP is very generic, and such a generic implementation in Solidity is not feasible,\\n * thus this contract does not implement the encoding itself. Protocols need to implement the type-specific encoding\\n * they need in their contracts using a combination of `abi.encode` and `keccak256`.\\n *\\n * This contract implements the EIP 712 domain separator ({_domainSeparatorV4}) that is used as part of the encoding\\n * scheme, and the final step of the encoding to obtain the message digest that is then signed via ECDSA\\n * ({_hashTypedDataV4}).\\n *\\n * The implementation of the domain separator was designed to be as efficient as possible while still properly updating\\n * the chain id to protect against replay attacks on an eventual fork of the chain.\\n *\\n * NOTE: This contract implements the version of the encoding known as \\\"v4\\\", as implemented by the JSON RPC method\\n * https://docs.metamask.io/guide/signing-data.html[`eth_signTypedDataV4` in MetaMask].\\n *\\n * _Available since v3.4._\\n */\\nabstract contract EIP712Upgradeable is Initializable {\\n /* solhint-disable var-name-mixedcase */\\n bytes32 private _HASHED_NAME;\\n bytes32 private _HASHED_VERSION;\\n bytes32 private constant _TYPE_HASH = keccak256(\\\"EIP712Domain(string name,string version,uint256 chainId,address verifyingContract)\\\");\\n\\n /* solhint-enable var-name-mixedcase */\\n\\n /**\\n * @dev Initializes the domain separator and parameter caches.\\n *\\n * The meaning of `name` and `version` is specified in\\n * https://eips.ethereum.org/EIPS/eip-712#definition-of-domainseparator[EIP 712]:\\n *\\n * - `name`: the user readable name of the signing domain, i.e. the name of the DApp or the protocol.\\n * - `version`: the current major version of the signing domain.\\n *\\n * NOTE: These parameters cannot be changed except through a xref:learn::upgrading-smart-contracts.adoc[smart\\n * contract upgrade].\\n */\\n function __EIP712_init(string memory name, string memory version) internal onlyInitializing {\\n __EIP712_init_unchained(name, version);\\n }\\n\\n function __EIP712_init_unchained(string memory name, string memory version) internal onlyInitializing {\\n bytes32 hashedName = keccak256(bytes(name));\\n bytes32 hashedVersion = keccak256(bytes(version));\\n _HASHED_NAME = hashedName;\\n _HASHED_VERSION = hashedVersion;\\n }\\n\\n /**\\n * @dev Returns the domain separator for the current chain.\\n */\\n function _domainSeparatorV4() internal view returns (bytes32) {\\n return _buildDomainSeparator(_TYPE_HASH, _EIP712NameHash(), _EIP712VersionHash());\\n }\\n\\n function _buildDomainSeparator(\\n bytes32 typeHash,\\n bytes32 nameHash,\\n bytes32 versionHash\\n ) private view returns (bytes32) {\\n return keccak256(abi.encode(typeHash, nameHash, versionHash, block.chainid, address(this)));\\n }\\n\\n /**\\n * @dev Given an already https://eips.ethereum.org/EIPS/eip-712#definition-of-hashstruct[hashed struct], this\\n * function returns the hash of the fully encoded EIP712 message for this domain.\\n *\\n * This hash can be used together with {ECDSA-recover} to obtain the signer of a message. For example:\\n *\\n * ```solidity\\n * bytes32 digest = _hashTypedDataV4(keccak256(abi.encode(\\n * keccak256(\\\"Mail(address to,string contents)\\\"),\\n * mailTo,\\n * keccak256(bytes(mailContents))\\n * )));\\n * address signer = ECDSA.recover(digest, signature);\\n * ```\\n */\\n function _hashTypedDataV4(bytes32 structHash) internal view virtual returns (bytes32) {\\n return ECDSAUpgradeable.toTypedDataHash(_domainSeparatorV4(), structHash);\\n }\\n\\n /**\\n * @dev The hash of the name parameter for the EIP712 domain.\\n *\\n * NOTE: This function reads from storage by default, but can be redefined to return a constant value if gas costs\\n * are a concern.\\n */\\n function _EIP712NameHash() internal virtual view returns (bytes32) {\\n return _HASHED_NAME;\\n }\\n\\n /**\\n * @dev The hash of the version parameter for the EIP712 domain.\\n *\\n * NOTE: This function reads from storage by default, but can be redefined to return a constant value if gas costs\\n * are a concern.\\n */\\n function _EIP712VersionHash() internal virtual view returns (bytes32) {\\n return _HASHED_VERSION;\\n }\\n uint256[50] private __gap;\\n}\\n\",\"keccak256\":\"0x92e61d8dd5ba90b513769c06da820e0a8f5d93810a9c6d5207308af345815011\",\"license\":\"MIT\"},\"@openzeppelin/contracts/token/ERC20/IERC20.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (token/ERC20/IERC20.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Interface of the ERC20 standard as defined in the EIP.\\n */\\ninterface IERC20 {\\n /**\\n * @dev Returns the amount of tokens in existence.\\n */\\n function totalSupply() external view returns (uint256);\\n\\n /**\\n * @dev Returns the amount of tokens owned by `account`.\\n */\\n function balanceOf(address account) external view returns (uint256);\\n\\n /**\\n * @dev Moves `amount` tokens from the caller's account to `recipient`.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * Emits a {Transfer} event.\\n */\\n function transfer(address recipient, uint256 amount) external returns (bool);\\n\\n /**\\n * @dev Returns the remaining number of tokens that `spender` will be\\n * allowed to spend on behalf of `owner` through {transferFrom}. This is\\n * zero by default.\\n *\\n * This value changes when {approve} or {transferFrom} are called.\\n */\\n function allowance(address owner, address spender) external view returns (uint256);\\n\\n /**\\n * @dev Sets `amount` as the allowance of `spender` over the caller's tokens.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * IMPORTANT: Beware that changing an allowance with this method brings the risk\\n * that someone may use both the old and the new allowance by unfortunate\\n * transaction ordering. One possible solution to mitigate this race\\n * condition is to first reduce the spender's allowance to 0 and set the\\n * desired value afterwards:\\n * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729\\n *\\n * Emits an {Approval} event.\\n */\\n function approve(address spender, uint256 amount) external returns (bool);\\n\\n /**\\n * @dev Moves `amount` tokens from `sender` to `recipient` using the\\n * allowance mechanism. `amount` is then deducted from the caller's\\n * allowance.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * Emits a {Transfer} event.\\n */\\n function transferFrom(\\n address sender,\\n address recipient,\\n uint256 amount\\n ) external returns (bool);\\n\\n /**\\n * @dev Emitted when `value` tokens are moved from one account (`from`) to\\n * another (`to`).\\n *\\n * Note that `value` may be zero.\\n */\\n event Transfer(address indexed from, address indexed to, uint256 value);\\n\\n /**\\n * @dev Emitted when the allowance of a `spender` for an `owner` is set by\\n * a call to {approve}. `value` is the new allowance.\\n */\\n event Approval(address indexed owner, address indexed spender, uint256 value);\\n}\\n\",\"keccak256\":\"0x61437cb513a887a1bbad006e7b1c8b414478427d33de47c5600af3c748f108da\",\"license\":\"MIT\"},\"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (token/ERC20/utils/SafeERC20.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../IERC20.sol\\\";\\nimport \\\"../../../utils/Address.sol\\\";\\n\\n/**\\n * @title SafeERC20\\n * @dev Wrappers around ERC20 operations that throw on failure (when the token\\n * contract returns false). Tokens that return no value (and instead revert or\\n * throw on failure) are also supported, non-reverting calls are assumed to be\\n * successful.\\n * To use this library you can add a `using SafeERC20 for IERC20;` statement to your contract,\\n * which allows you to call the safe operations as `token.safeTransfer(...)`, etc.\\n */\\nlibrary SafeERC20 {\\n using Address for address;\\n\\n function safeTransfer(\\n IERC20 token,\\n address to,\\n uint256 value\\n ) internal {\\n _callOptionalReturn(token, abi.encodeWithSelector(token.transfer.selector, to, value));\\n }\\n\\n function safeTransferFrom(\\n IERC20 token,\\n address from,\\n address to,\\n uint256 value\\n ) internal {\\n _callOptionalReturn(token, abi.encodeWithSelector(token.transferFrom.selector, from, to, value));\\n }\\n\\n /**\\n * @dev Deprecated. This function has issues similar to the ones found in\\n * {IERC20-approve}, and its usage is discouraged.\\n *\\n * Whenever possible, use {safeIncreaseAllowance} and\\n * {safeDecreaseAllowance} instead.\\n */\\n function safeApprove(\\n IERC20 token,\\n address spender,\\n uint256 value\\n ) internal {\\n // safeApprove should only be called when setting an initial allowance,\\n // or when resetting it to zero. To increase and decrease it, use\\n // 'safeIncreaseAllowance' and 'safeDecreaseAllowance'\\n require(\\n (value == 0) || (token.allowance(address(this), spender) == 0),\\n \\\"SafeERC20: approve from non-zero to non-zero allowance\\\"\\n );\\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, value));\\n }\\n\\n function safeIncreaseAllowance(\\n IERC20 token,\\n address spender,\\n uint256 value\\n ) internal {\\n uint256 newAllowance = token.allowance(address(this), spender) + value;\\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));\\n }\\n\\n function safeDecreaseAllowance(\\n IERC20 token,\\n address spender,\\n uint256 value\\n ) internal {\\n unchecked {\\n uint256 oldAllowance = token.allowance(address(this), spender);\\n require(oldAllowance >= value, \\\"SafeERC20: decreased allowance below zero\\\");\\n uint256 newAllowance = oldAllowance - value;\\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));\\n }\\n }\\n\\n /**\\n * @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement\\n * on the return value: the return value is optional (but if data is returned, it must not be false).\\n * @param token The token targeted by the call.\\n * @param data The call data (encoded using abi.encode or one of its variants).\\n */\\n function _callOptionalReturn(IERC20 token, bytes memory data) private {\\n // We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since\\n // we're implementing it ourselves. We use {Address.functionCall} to perform this call, which verifies that\\n // the target address contains contract code and also asserts for success in the low-level call.\\n\\n bytes memory returndata = address(token).functionCall(data, \\\"SafeERC20: low-level call failed\\\");\\n if (returndata.length > 0) {\\n // Return data is optional\\n require(abi.decode(returndata, (bool)), \\\"SafeERC20: ERC20 operation did not succeed\\\");\\n }\\n }\\n}\\n\",\"keccak256\":\"0xc3d946432c0ddbb1f846a0d3985be71299df331b91d06732152117f62f0be2b5\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/Address.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (utils/Address.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Collection of functions related to the address type\\n */\\nlibrary Address {\\n /**\\n * @dev Returns true if `account` is a contract.\\n *\\n * [IMPORTANT]\\n * ====\\n * It is unsafe to assume that an address for which this function returns\\n * false is an externally-owned account (EOA) and not a contract.\\n *\\n * Among others, `isContract` will return false for the following\\n * types of addresses:\\n *\\n * - an externally-owned account\\n * - a contract in construction\\n * - an address where a contract will be created\\n * - an address where a contract lived, but was destroyed\\n * ====\\n */\\n function isContract(address account) internal view returns (bool) {\\n // This method relies on extcodesize, which returns 0 for contracts in\\n // construction, since the code is only stored at the end of the\\n // constructor execution.\\n\\n uint256 size;\\n assembly {\\n size := extcodesize(account)\\n }\\n return size > 0;\\n }\\n\\n /**\\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\\n * `recipient`, forwarding all available gas and reverting on errors.\\n *\\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\\n * imposed by `transfer`, making them unable to receive funds via\\n * `transfer`. {sendValue} removes this limitation.\\n *\\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\\n *\\n * IMPORTANT: because control is transferred to `recipient`, care must be\\n * taken to not create reentrancy vulnerabilities. Consider using\\n * {ReentrancyGuard} or the\\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\\n */\\n function sendValue(address payable recipient, uint256 amount) internal {\\n require(address(this).balance >= amount, \\\"Address: insufficient balance\\\");\\n\\n (bool success, ) = recipient.call{value: amount}(\\\"\\\");\\n require(success, \\\"Address: unable to send value, recipient may have reverted\\\");\\n }\\n\\n /**\\n * @dev Performs a Solidity function call using a low level `call`. A\\n * plain `call` is an unsafe replacement for a function call: use this\\n * function instead.\\n *\\n * If `target` reverts with a revert reason, it is bubbled up by this\\n * function (like regular Solidity function calls).\\n *\\n * Returns the raw returned data. To convert to the expected return value,\\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\\n *\\n * Requirements:\\n *\\n * - `target` must be a contract.\\n * - calling `target` with `data` must not revert.\\n *\\n * _Available since v3.1._\\n */\\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\\n return functionCall(target, data, \\\"Address: low-level call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\\n * `errorMessage` as a fallback revert reason when `target` reverts.\\n *\\n * _Available since v3.1._\\n */\\n function functionCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n return functionCallWithValue(target, data, 0, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but also transferring `value` wei to `target`.\\n *\\n * Requirements:\\n *\\n * - the calling contract must have an ETH balance of at least `value`.\\n * - the called Solidity function must be `payable`.\\n *\\n * _Available since v3.1._\\n */\\n function functionCallWithValue(\\n address target,\\n bytes memory data,\\n uint256 value\\n ) internal returns (bytes memory) {\\n return functionCallWithValue(target, data, value, \\\"Address: low-level call with value failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\\n * with `errorMessage` as a fallback revert reason when `target` reverts.\\n *\\n * _Available since v3.1._\\n */\\n function functionCallWithValue(\\n address target,\\n bytes memory data,\\n uint256 value,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n require(address(this).balance >= value, \\\"Address: insufficient balance for call\\\");\\n require(isContract(target), \\\"Address: call to non-contract\\\");\\n\\n (bool success, bytes memory returndata) = target.call{value: value}(data);\\n return verifyCallResult(success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but performing a static call.\\n *\\n * _Available since v3.3._\\n */\\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\\n return functionStaticCall(target, data, \\\"Address: low-level static call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\\n * but performing a static call.\\n *\\n * _Available since v3.3._\\n */\\n function functionStaticCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal view returns (bytes memory) {\\n require(isContract(target), \\\"Address: static call to non-contract\\\");\\n\\n (bool success, bytes memory returndata) = target.staticcall(data);\\n return verifyCallResult(success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but performing a delegate call.\\n *\\n * _Available since v3.4._\\n */\\n function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {\\n return functionDelegateCall(target, data, \\\"Address: low-level delegate call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\\n * but performing a delegate call.\\n *\\n * _Available since v3.4._\\n */\\n function functionDelegateCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n require(isContract(target), \\\"Address: delegate call to non-contract\\\");\\n\\n (bool success, bytes memory returndata) = target.delegatecall(data);\\n return verifyCallResult(success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the\\n * revert reason using the provided one.\\n *\\n * _Available since v4.3._\\n */\\n function verifyCallResult(\\n bool success,\\n bytes memory returndata,\\n string memory errorMessage\\n ) internal pure returns (bytes memory) {\\n if (success) {\\n return returndata;\\n } else {\\n // Look for revert reason and bubble it up if present\\n if (returndata.length > 0) {\\n // The easiest way to bubble the revert reason is using memory via assembly\\n\\n assembly {\\n let returndata_size := mload(returndata)\\n revert(add(32, returndata), returndata_size)\\n }\\n } else {\\n revert(errorMessage);\\n }\\n }\\n }\\n}\\n\",\"keccak256\":\"0x51b758a8815ecc9596c66c37d56b1d33883a444631a3f916b9fe65cb863ef7c4\",\"license\":\"MIT\"},\"contracts/agToken/AgTokenSideChainMultiBridge.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-3.0\\n\\npragma solidity 0.8.12;\\n\\nimport \\\"./BaseAgTokenSideChain.sol\\\";\\nimport \\\"@openzeppelin/contracts/token/ERC20/IERC20.sol\\\";\\nimport \\\"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\\\";\\n\\n/// @title AgTokenSideChainMultiBridge\\n/// @author Angle Core Team\\n/// @notice Contract for Angle agTokens on other chains than Ethereum mainnet\\n/// @dev This contract supports bridge tokens having a minting right on the stablecoin (also referred to as the canonical\\n/// or the native token)\\n/// @dev References:\\n/// - FRAX implementation: https://polygonscan.com/address/0x45c32fA6DF82ead1e2EF74d17b76547EDdFaFF89#code\\n/// - QiDAO implementation: https://snowtrace.io/address/0x5c49b268c9841AFF1Cc3B0a418ff5c3442eE3F3b#code\\ncontract AgTokenSideChainMultiBridge is BaseAgTokenSideChain {\\n using SafeERC20 for IERC20;\\n\\n /// @notice Base used for fee computation\\n uint256 public constant BASE_PARAMS = 10**9;\\n\\n // =============================== Bridging Data ===============================\\n\\n /// @notice Struct with some data about a specific bridge token\\n struct BridgeDetails {\\n // Limit on the balance of bridge token held by the contract: it is designed\\n // to reduce the exposure of the system to hacks\\n uint256 limit;\\n // Limit on the hourly volume of token minted through this bridge\\n // Technically the limit over a rolling hour is hourlyLimit x2 as hourly limit\\n // is enforced only between x:00 and x+1:00\\n uint256 hourlyLimit;\\n // Fee taken for swapping in and out the token\\n uint64 fee;\\n // Whether the associated token is allowed or not\\n bool allowed;\\n // Whether swapping in and out from the associated token is paused or not\\n bool paused;\\n }\\n\\n /// @notice Maps a bridge token to data\\n mapping(address => BridgeDetails) public bridges;\\n /// @notice List of all bridge tokens\\n address[] public bridgeTokensList;\\n /// @notice Maps a bridge token to the associated hourly volume\\n mapping(address => mapping(uint256 => uint256)) public usage;\\n /// @notice Maps an address to whether it is exempt of fees for when it comes to swapping in and out\\n mapping(address => uint256) public isFeeExempt;\\n /// @notice Limit to the amount of tokens that can be sent from that chain to another chain\\n uint256 public chainTotalHourlyLimit;\\n /// @notice Usage per hour on that chain. Maps an hourly timestamp to the total volume swapped out on the chain\\n mapping(uint256 => uint256) public chainTotalUsage;\\n\\n // ================================== Events ===================================\\n\\n event BridgeTokenAdded(address indexed bridgeToken, uint256 limit, uint256 hourlyLimit, uint64 fee, bool paused);\\n event BridgeTokenToggled(address indexed bridgeToken, bool toggleStatus);\\n event BridgeTokenRemoved(address indexed bridgeToken);\\n event BridgeTokenFeeUpdated(address indexed bridgeToken, uint64 fee);\\n event BridgeTokenLimitUpdated(address indexed bridgeToken, uint256 limit);\\n event BridgeTokenHourlyLimitUpdated(address indexed bridgeToken, uint256 hourlyLimit);\\n event HourlyLimitUpdated(uint256 hourlyLimit);\\n event Recovered(address indexed token, address indexed to, uint256 amount);\\n event FeeToggled(address indexed theAddress, uint256 toggleStatus);\\n\\n // =============================== Errors ================================\\n\\n error AssetStillControlledInReserves();\\n error HourlyLimitExceeded();\\n error InvalidToken();\\n error NotGovernor();\\n error NotGovernorOrGuardian();\\n error TooBigAmount();\\n error TooHighParameterValue();\\n error ZeroAddress();\\n\\n // ============================= Constructor ===================================\\n\\n /// @notice Initializes the `AgToken` contract\\n /// @param name_ Name of the token\\n /// @param symbol_ Symbol of the token\\n /// @param _treasury Reference to the `Treasury` contract associated to this agToken\\n /// @dev By default, agTokens are ERC-20 tokens with 18 decimals\\n function initialize(\\n string memory name_,\\n string memory symbol_,\\n address _treasury\\n ) external {\\n _initialize(name_, symbol_, _treasury);\\n }\\n\\n // =============================== Modifiers ===================================\\n\\n /// @notice Checks whether the `msg.sender` has the governor role or not\\n modifier onlyGovernor() {\\n if (!ITreasury(treasury).isGovernor(msg.sender)) revert NotGovernor();\\n _;\\n }\\n\\n /// @notice Checks whether the `msg.sender` has the governor role or the guardian role\\n modifier onlyGovernorOrGuardian() {\\n if (!ITreasury(treasury).isGovernorOrGuardian(msg.sender)) revert NotGovernorOrGuardian();\\n _;\\n }\\n\\n // ==================== External Permissionless Functions ======================\\n\\n /// @notice Returns the list of all supported bridge tokens\\n /// @dev Helpful for UIs\\n function allBridgeTokens() external view returns (address[] memory) {\\n return bridgeTokensList;\\n }\\n\\n /// @notice Returns the current volume for a bridge, for the current hour\\n /// @param bridgeToken Bridge used to mint\\n /// @dev Helpful for UIs\\n function currentUsage(address bridgeToken) external view returns (uint256) {\\n return usage[bridgeToken][block.timestamp / 3600];\\n }\\n\\n /// @notice Returns the current total volume on the chain for the current hour\\n /// @dev Helpful for UIs\\n function currentTotalUsage() external view returns (uint256) {\\n return chainTotalUsage[block.timestamp / 3600];\\n }\\n\\n /// @notice Mints the canonical token from a supported bridge token\\n /// @param bridgeToken Bridge token to use to mint\\n /// @param amount Amount of bridge tokens to send\\n /// @param to Address to which the stablecoin should be sent\\n /// @return Amount of the canonical stablecoin actually minted\\n /// @dev Some fees may be taken by the protocol depending on the token used and on the address calling\\n function swapIn(\\n address bridgeToken,\\n uint256 amount,\\n address to\\n ) external returns (uint256) {\\n BridgeDetails memory bridgeDetails = bridges[bridgeToken];\\n if (!bridgeDetails.allowed || bridgeDetails.paused) revert InvalidToken();\\n uint256 balance = IERC20(bridgeToken).balanceOf(address(this));\\n if (balance + amount > bridgeDetails.limit) {\\n // In case someone maliciously sends tokens to this contract\\n // Or the limit changes\\n if (bridgeDetails.limit > balance) amount = bridgeDetails.limit - balance;\\n else {\\n amount = 0;\\n }\\n }\\n\\n // Checking requirement on the hourly volume\\n uint256 hour = block.timestamp / 3600;\\n uint256 hourlyUsage = usage[bridgeToken][hour] + amount;\\n if (hourlyUsage > bridgeDetails.hourlyLimit) {\\n // Edge case when the hourly limit changes\\n if (bridgeDetails.hourlyLimit > usage[bridgeToken][hour])\\n amount = bridgeDetails.hourlyLimit - usage[bridgeToken][hour];\\n else {\\n amount = 0;\\n }\\n }\\n usage[bridgeToken][hour] = usage[bridgeToken][hour] + amount;\\n\\n IERC20(bridgeToken).safeTransferFrom(msg.sender, address(this), amount);\\n uint256 canonicalOut = amount;\\n // Computing fees\\n if (isFeeExempt[msg.sender] == 0) {\\n canonicalOut -= (canonicalOut * bridgeDetails.fee) / BASE_PARAMS;\\n }\\n _mint(to, canonicalOut);\\n return canonicalOut;\\n }\\n\\n /// @notice Burns the canonical token in exchange for a bridge token\\n /// @param bridgeToken Bridge token required\\n /// @param amount Amount of canonical tokens to burn\\n /// @param to Address to which the bridge token should be sent\\n /// @return Amount of bridge tokens actually sent back\\n /// @dev Some fees may be taken by the protocol depending on the token used and on the address calling\\n function swapOut(\\n address bridgeToken,\\n uint256 amount,\\n address to\\n ) external returns (uint256) {\\n BridgeDetails memory bridgeDetails = bridges[bridgeToken];\\n if (!bridgeDetails.allowed || bridgeDetails.paused) revert InvalidToken();\\n\\n uint256 hour = block.timestamp / 3600;\\n uint256 hourlyUsage = chainTotalUsage[hour] + amount;\\n // If the amount being swapped out exceeds the limit, we revert\\n // We don't want to change the amount being swapped out.\\n // The user can decide to send another tx with the correct amount to reach the limit\\n if (hourlyUsage > chainTotalHourlyLimit) revert HourlyLimitExceeded();\\n chainTotalUsage[hour] = hourlyUsage;\\n\\n _burn(msg.sender, amount);\\n uint256 bridgeOut = amount;\\n if (isFeeExempt[msg.sender] == 0) {\\n bridgeOut -= (bridgeOut * bridgeDetails.fee) / BASE_PARAMS;\\n }\\n IERC20(bridgeToken).safeTransfer(to, bridgeOut);\\n return bridgeOut;\\n }\\n\\n // ======================= Governance Functions ================================\\n\\n /// @notice Adds support for a bridge token\\n /// @param bridgeToken Bridge token to add: it should be a version of the stablecoin from another bridge\\n /// @param limit Limit on the balance of bridge token this contract could hold\\n /// @param hourlyLimit Limit on the hourly volume for this bridge\\n /// @param paused Whether swapping for this token should be paused or not\\n /// @param fee Fee taken upon swapping for or against this token\\n function addBridgeToken(\\n address bridgeToken,\\n uint256 limit,\\n uint256 hourlyLimit,\\n uint64 fee,\\n bool paused\\n ) external onlyGovernor {\\n if (bridges[bridgeToken].allowed || bridgeToken == address(0)) revert InvalidToken();\\n if (fee > BASE_PARAMS) revert TooHighParameterValue();\\n BridgeDetails memory _bridge;\\n _bridge.limit = limit;\\n _bridge.hourlyLimit = hourlyLimit;\\n _bridge.paused = paused;\\n _bridge.fee = fee;\\n _bridge.allowed = true;\\n bridges[bridgeToken] = _bridge;\\n bridgeTokensList.push(bridgeToken);\\n emit BridgeTokenAdded(bridgeToken, limit, hourlyLimit, fee, paused);\\n }\\n\\n /// @notice Removes support for a token\\n /// @param bridgeToken Address of the bridge token to remove support for\\n function removeBridgeToken(address bridgeToken) external onlyGovernor {\\n if (IERC20(bridgeToken).balanceOf(address(this)) != 0) revert AssetStillControlledInReserves();\\n delete bridges[bridgeToken];\\n // Deletion from `bridgeTokensList` loop\\n uint256 bridgeTokensListLength = bridgeTokensList.length;\\n for (uint256 i = 0; i < bridgeTokensListLength - 1; i++) {\\n if (bridgeTokensList[i] == bridgeToken) {\\n // Replace the `bridgeToken` to remove with the last of the list\\n bridgeTokensList[i] = bridgeTokensList[bridgeTokensListLength - 1];\\n break;\\n }\\n }\\n // Remove last element in array\\n bridgeTokensList.pop();\\n emit BridgeTokenRemoved(bridgeToken);\\n }\\n\\n /// @notice Recovers any ERC20 token\\n /// @dev Can be used to withdraw bridge tokens for them to be de-bridged on mainnet\\n function recoverERC20(\\n address tokenAddress,\\n address to,\\n uint256 amountToRecover\\n ) external onlyGovernor {\\n IERC20(tokenAddress).safeTransfer(to, amountToRecover);\\n emit Recovered(tokenAddress, to, amountToRecover);\\n }\\n\\n /// @notice Updates the `limit` amount for `bridgeToken`\\n function setLimit(address bridgeToken, uint256 limit) external onlyGovernorOrGuardian {\\n if (!bridges[bridgeToken].allowed) revert InvalidToken();\\n bridges[bridgeToken].limit = limit;\\n emit BridgeTokenLimitUpdated(bridgeToken, limit);\\n }\\n\\n /// @notice Updates the `hourlyLimit` amount for `bridgeToken`\\n function setHourlyLimit(address bridgeToken, uint256 hourlyLimit) external onlyGovernorOrGuardian {\\n if (!bridges[bridgeToken].allowed) revert InvalidToken();\\n bridges[bridgeToken].hourlyLimit = hourlyLimit;\\n emit BridgeTokenHourlyLimitUpdated(bridgeToken, hourlyLimit);\\n }\\n\\n /// @notice Updates the `chainTotalHourlyLimit` amount\\n function setChainTotalHourlyLimit(uint256 hourlyLimit) external onlyGovernorOrGuardian {\\n chainTotalHourlyLimit = hourlyLimit;\\n emit HourlyLimitUpdated(hourlyLimit);\\n }\\n\\n /// @notice Updates the `fee` value for `bridgeToken`\\n function setSwapFee(address bridgeToken, uint64 fee) external onlyGovernorOrGuardian {\\n if (!bridges[bridgeToken].allowed) revert InvalidToken();\\n if (fee > BASE_PARAMS) revert TooHighParameterValue();\\n bridges[bridgeToken].fee = fee;\\n emit BridgeTokenFeeUpdated(bridgeToken, fee);\\n }\\n\\n /// @notice Pauses or unpauses swapping in and out for a token\\n function toggleBridge(address bridgeToken) external onlyGovernorOrGuardian {\\n if (!bridges[bridgeToken].allowed) revert InvalidToken();\\n bool pausedStatus = bridges[bridgeToken].paused;\\n bridges[bridgeToken].paused = !pausedStatus;\\n emit BridgeTokenToggled(bridgeToken, !pausedStatus);\\n }\\n\\n /// @notice Toggles fees for the address `theAddress`\\n function toggleFeesForAddress(address theAddress) external onlyGovernorOrGuardian {\\n uint256 feeExemptStatus = 1 - isFeeExempt[theAddress];\\n isFeeExempt[theAddress] = feeExemptStatus;\\n emit FeeToggled(theAddress, feeExemptStatus);\\n }\\n}\\n\",\"keccak256\":\"0xf2f2d77a9504fa20ef62faae227c548cc32d8f796ef427864ec79580617d0cb3\",\"license\":\"GPL-3.0\"},\"contracts/agToken/BaseAgTokenSideChain.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-3.0\\n\\npragma solidity 0.8.12;\\n\\nimport \\\"../interfaces/IAgToken.sol\\\";\\nimport \\\"../interfaces/ITreasury.sol\\\";\\nimport \\\"@openzeppelin/contracts-upgradeable/token/ERC20/extensions/draft-ERC20PermitUpgradeable.sol\\\";\\n\\n/// @title BaseAgTokenSideChain\\n/// @author Angle Core Team\\n/// @notice Base Contract for Angle agTokens on other chains than Ethereum mainnet\\n/// @dev This type of contract can be used to create and handle the stablecoins of Angle protocol in different chains than Ethereum\\ncontract BaseAgTokenSideChain is IAgToken, ERC20PermitUpgradeable {\\n // ======================= Parameters and Variables ============================\\n\\n /// @inheritdoc IAgToken\\n mapping(address => bool) public isMinter;\\n /// @notice Reference to the treasury contract which can grant minting rights\\n address public treasury;\\n\\n // ================================== Events ===================================\\n\\n event TreasuryUpdated(address indexed _treasury);\\n event MinterToggled(address indexed minter);\\n\\n // =============================== Errors ================================\\n\\n error BurnAmountExceedsAllowance();\\n error InvalidSender();\\n error InvalidTreasury();\\n error NotMinter();\\n error NotTreasury();\\n\\n // ============================= Constructor ===================================\\n\\n /// @notice Initializes the contract\\n /// @param name_ Name of the token\\n /// @param symbol_ Symbol of the token\\n /// @param _treasury Reference to the `Treasury` contract associated to this agToken implementation\\n /// @dev By default, agTokens are ERC-20 tokens with 18 decimals\\n function _initialize(\\n string memory name_,\\n string memory symbol_,\\n address _treasury\\n ) internal initializer {\\n __ERC20Permit_init(name_);\\n __ERC20_init(name_, symbol_);\\n if (address(ITreasury(_treasury).stablecoin()) != address(this)) revert InvalidTreasury();\\n treasury = _treasury;\\n emit TreasuryUpdated(address(_treasury));\\n }\\n\\n /// @custom:oz-upgrades-unsafe-allow constructor\\n constructor() initializer {}\\n\\n // =============================== Modifiers ===================================\\n\\n /// @notice Checks to see if it is the `Treasury` calling this contract\\n /// @dev There is no Access Control here, because it can be handled cheaply through this modifier\\n modifier onlyTreasury() {\\n if (msg.sender != address(treasury)) revert NotTreasury();\\n _;\\n }\\n\\n /// @notice Checks whether the sender has the minting right\\n modifier onlyMinter() {\\n if (!isMinter[msg.sender]) revert NotMinter();\\n _;\\n }\\n\\n // =========================== External Function ===============================\\n\\n /// @notice Allows anyone to burn agToken without redeeming collateral back\\n /// @param amount Amount of stablecoins to burn\\n /// @dev This function can typically be called if there is a settlement mechanism to burn stablecoins\\n function burnStablecoin(uint256 amount) external {\\n _burn(msg.sender, amount);\\n }\\n\\n // ======================= Minter Role Only Functions ==========================\\n\\n /// @inheritdoc IAgToken\\n function burnSelf(uint256 amount, address burner) external onlyMinter {\\n _burn(burner, amount);\\n }\\n\\n /// @inheritdoc IAgToken\\n function burnFrom(\\n uint256 amount,\\n address burner,\\n address sender\\n ) external onlyMinter {\\n _burnFromNoRedeem(amount, burner, sender);\\n }\\n\\n /// @inheritdoc IAgToken\\n function mint(address account, uint256 amount) external onlyMinter {\\n _mint(account, amount);\\n }\\n\\n // ======================= Treasury Only Functions =============================\\n\\n /// @inheritdoc IAgToken\\n function addMinter(address minter) external onlyTreasury {\\n isMinter[minter] = true;\\n emit MinterToggled(minter);\\n }\\n\\n /// @inheritdoc IAgToken\\n function removeMinter(address minter) external {\\n if (msg.sender != address(treasury) && msg.sender != minter) revert InvalidSender();\\n isMinter[minter] = false;\\n emit MinterToggled(minter);\\n }\\n\\n /// @inheritdoc IAgToken\\n function setTreasury(address _treasury) external onlyTreasury {\\n treasury = _treasury;\\n emit TreasuryUpdated(_treasury);\\n }\\n\\n // ============================ Internal Function ==============================\\n\\n /// @notice Internal version of the function `burnFromNoRedeem`\\n /// @param amount Amount to burn\\n /// @dev It is at the level of this function that allowance checks are performed\\n function _burnFromNoRedeem(\\n uint256 amount,\\n address burner,\\n address sender\\n ) internal {\\n if (burner != sender) {\\n uint256 currentAllowance = allowance(burner, sender);\\n if (currentAllowance < amount) revert BurnAmountExceedsAllowance();\\n _approve(burner, sender, currentAllowance - amount);\\n }\\n _burn(burner, amount);\\n }\\n}\\n\",\"keccak256\":\"0xf54ef7218eba0e71f2b57da57956646f0227356fc18a55c8984f6c6a8f592077\",\"license\":\"GPL-3.0\"},\"contracts/interfaces/IAgToken.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-3.0\\n\\npragma solidity 0.8.12;\\n\\nimport \\\"@openzeppelin/contracts-upgradeable/token/ERC20/IERC20Upgradeable.sol\\\";\\n\\n/// @title IAgToken\\n/// @author Angle Core Team\\n/// @notice Interface for the stablecoins `AgToken` contracts\\n/// @dev This interface only contains functions of the `AgToken` contract which are called by other contracts\\n/// of this module or of the first module of the Angle Protocol\\ninterface IAgToken is IERC20Upgradeable {\\n // ======================= Minter Role Only Functions ===========================\\n\\n /// @notice Lets the `StableMaster` contract or another whitelisted contract mint agTokens\\n /// @param account Address to mint to\\n /// @param amount Amount to mint\\n /// @dev The contracts allowed to issue agTokens are the `StableMaster` contract, `VaultManager` contracts\\n /// associated to this stablecoin as well as the flash loan module (if activated) and potentially contracts\\n /// whitelisted by governance\\n function mint(address account, uint256 amount) external;\\n\\n /// @notice Burns `amount` tokens from a `burner` address after being asked to by `sender`\\n /// @param amount Amount of tokens to burn\\n /// @param burner Address to burn from\\n /// @param sender Address which requested the burn from `burner`\\n /// @dev This method is to be called by a contract with the minter right after being requested\\n /// to do so by a `sender` address willing to burn tokens from another `burner` address\\n /// @dev The method checks the allowance between the `sender` and the `burner`\\n function burnFrom(\\n uint256 amount,\\n address burner,\\n address sender\\n ) external;\\n\\n /// @notice Burns `amount` tokens from a `burner` address\\n /// @param amount Amount of tokens to burn\\n /// @param burner Address to burn from\\n /// @dev This method is to be called by a contract with a minter right on the AgToken after being\\n /// requested to do so by an address willing to burn tokens from its address\\n function burnSelf(uint256 amount, address burner) external;\\n\\n // ========================= Treasury Only Functions ===========================\\n\\n /// @notice Adds a minter in the contract\\n /// @param minter Minter address to add\\n /// @dev Zero address checks are performed directly in the `Treasury` contract\\n function addMinter(address minter) external;\\n\\n /// @notice Removes a minter from the contract\\n /// @param minter Minter address to remove\\n /// @dev This function can also be called by a minter wishing to revoke itself\\n function removeMinter(address minter) external;\\n\\n /// @notice Sets a new treasury contract\\n /// @param _treasury New treasury address\\n function setTreasury(address _treasury) external;\\n\\n // ========================= External functions ================================\\n\\n /// @notice Checks whether an address has the right to mint agTokens\\n /// @param minter Address for which the minting right should be checked\\n /// @return Whether the address has the right to mint agTokens or not\\n function isMinter(address minter) external view returns (bool);\\n}\\n\",\"keccak256\":\"0xcd50d86128e457543483981ea6127cb8dac03584b919614352aa89d7e991405c\",\"license\":\"GPL-3.0\"},\"contracts/interfaces/ICoreBorrow.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-3.0\\n\\npragma solidity 0.8.12;\\n\\n/// @title ICoreBorrow\\n/// @author Angle Core Team\\n/// @notice Interface for the `CoreBorrow` contract\\n/// @dev This interface only contains functions of the `CoreBorrow` contract which are called by other contracts\\n/// of this module\\ninterface ICoreBorrow {\\n /// @notice Checks if an address corresponds to a treasury of a stablecoin with a flash loan\\n /// module initialized on it\\n /// @param treasury Address to check\\n /// @return Whether the address has the `FLASHLOANER_TREASURY_ROLE` or not\\n function isFlashLoanerTreasury(address treasury) external view returns (bool);\\n\\n /// @notice Checks whether an address is governor of the Angle Protocol or not\\n /// @param admin Address to check\\n /// @return Whether the address has the `GOVERNOR_ROLE` or not\\n function isGovernor(address admin) external view returns (bool);\\n\\n /// @notice Checks whether an address is governor or a guardian of the Angle Protocol or not\\n /// @param admin Address to check\\n /// @return Whether the address has the `GUARDIAN_ROLE` or not\\n /// @dev Governance should make sure when adding a governor to also give this governor the guardian\\n /// role by calling the `addGovernor` function\\n function isGovernorOrGuardian(address admin) external view returns (bool);\\n}\\n\",\"keccak256\":\"0x25b65b3f506ca91745a444502a36f0556585d82d9d60f4bd32fbcaabc12840d4\",\"license\":\"GPL-3.0\"},\"contracts/interfaces/IFlashAngle.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-3.0\\n\\npragma solidity 0.8.12;\\n\\nimport \\\"./IAgToken.sol\\\";\\nimport \\\"./ICoreBorrow.sol\\\";\\n\\n/// @title IFlashAngle\\n/// @author Angle Core Team\\n/// @notice Interface for the `FlashAngle` contract\\n/// @dev This interface only contains functions of the contract which are called by other contracts\\n/// of this module\\ninterface IFlashAngle {\\n /// @notice Reference to the `CoreBorrow` contract managing the FlashLoan module\\n function core() external view returns (ICoreBorrow);\\n\\n /// @notice Sends the fees taken from flash loans to the treasury contract associated to the stablecoin\\n /// @param stablecoin Stablecoin from which profits should be sent\\n /// @return balance Amount of profits sent\\n /// @dev This function can only be called by the treasury contract\\n function accrueInterestToTreasury(IAgToken stablecoin) external returns (uint256 balance);\\n\\n /// @notice Adds support for a stablecoin\\n /// @param _treasury Treasury associated to the stablecoin to add support for\\n /// @dev This function can only be called by the `CoreBorrow` contract\\n function addStablecoinSupport(address _treasury) external;\\n\\n /// @notice Removes support for a stablecoin\\n /// @param _treasury Treasury associated to the stablecoin to remove support for\\n /// @dev This function can only be called by the `CoreBorrow` contract\\n function removeStablecoinSupport(address _treasury) external;\\n\\n /// @notice Sets a new core contract\\n /// @param _core Core contract address to set\\n /// @dev This function can only be called by the `CoreBorrow` contract\\n function setCore(address _core) external;\\n}\\n\",\"keccak256\":\"0xc17654e512897efe41e3f1173c07dd4676e8c699a72b859d14b473d1e8300e45\",\"license\":\"GPL-3.0\"},\"contracts/interfaces/ITreasury.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-3.0\\n\\npragma solidity 0.8.12;\\n\\nimport \\\"./IAgToken.sol\\\";\\nimport \\\"./ICoreBorrow.sol\\\";\\nimport \\\"./IFlashAngle.sol\\\";\\n\\n/// @title ITreasury\\n/// @author Angle Core Team\\n/// @notice Interface for the `Treasury` contract\\n/// @dev This interface only contains functions of the `Treasury` which are called by other contracts\\n/// of this module\\ninterface ITreasury {\\n /// @notice Stablecoin handled by this `treasury` contract\\n function stablecoin() external view returns (IAgToken);\\n\\n /// @notice Checks whether a given address has the governor role\\n /// @param admin Address to check\\n /// @return Whether the address has the governor role\\n /// @dev Access control is only kept in the `CoreBorrow` contract\\n function isGovernor(address admin) external view returns (bool);\\n\\n /// @notice Checks whether a given address has the guardian or the governor role\\n /// @param admin Address to check\\n /// @return Whether the address has the guardian or the governor role\\n /// @dev Access control is only kept in the `CoreBorrow` contract which means that this function\\n /// queries the `CoreBorrow` contract\\n function isGovernorOrGuardian(address admin) external view returns (bool);\\n\\n /// @notice Checks whether a given address has well been initialized in this contract\\n /// as a `VaultManager``\\n /// @param _vaultManager Address to check\\n /// @return Whether the address has been initialized or not\\n function isVaultManager(address _vaultManager) external view returns (bool);\\n\\n /// @notice Sets a new flash loan module for this stablecoin\\n /// @param _flashLoanModule Reference to the new flash loan module\\n /// @dev This function removes the minting right to the old flash loan module and grants\\n /// it to the new module\\n function setFlashLoanModule(address _flashLoanModule) external;\\n}\\n\",\"keccak256\":\"0xced9b7256fcbedc75682037e11ce51fe9116e5604794b8545e00dea0607629cc\",\"license\":\"GPL-3.0\"}},\"version\":1}", - "bytecode": "0x60806040523480156200001157600080fd5b50600054610100900460ff166200002f5760005460ff161562000039565b62000039620000de565b620000a15760405162461bcd60e51b815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201526d191e481a5b9a5d1a585b1a5e995960921b606482015260840160405180910390fd5b600054610100900460ff16158015620000c4576000805461ffff19166101011790555b8015620000d7576000805461ff00191690555b5062000102565b6000620000f630620000fc60201b620027c81760201c565b15905090565b3b151590565b61479b80620001126000396000f3fe608060405234801561001057600080fd5b50600436106102ff5760003560e01c806361d027b31161019c5780639f48118f116100ee578063ced67f0c11610097578063dd62ed3e11610071578063dd62ed3e14610724578063e3e286551461076a578063f0f442601461077d57600080fd5b8063ced67f0c1461066b578063d44ad63f146106fe578063d505accf1461071157600080fd5b8063aa271e1a116100c8578063aa271e1a14610620578063ba330bd714610643578063cd4839ca1461065657600080fd5b80639f48118f146105ef578063a457c2d7146105fa578063a9059cbb1461060d57600080fd5b80637ecebe001161015057806395d89b411161012a57806395d89b41146105c1578063983b2d56146105c95780639e4e0dae146105dc57600080fd5b80637ecebe00146105705780638933fb791461058357806390218cff146105ae57600080fd5b80637334d020116101815780637334d020146105425780637d4c9c2d146105555780637d74e25f1461056857600080fd5b806361d027b3146104c757806370a082311461050c57600080fd5b80633092afd511610255578063395093511161020957806340c10f19116101e357806340c10f19146104815780634dc32fcc146104945780635bfbec96146104a757600080fd5b8063395093511461043b5780633a55f89d1461044e5780633f4218e01461046157600080fd5b8063350ebe041161023a578063350ebe041461040d5780633644e5151461042057806336db43b51461042857600080fd5b80633092afd5146103eb578063313ce567146103fe57600080fd5b8063151dd755116102b757806323b872dd1161029157806323b872dd146103b25780632b471d8e146103c55780632e403e14146103d857600080fd5b8063151dd7551461038057806318160ddd146103a15780632342fb0e146103a957600080fd5b80630919a951116102e85780630919a95114610337578063095ea7b31461034a5780631171bda91461036d57600080fd5b806306fdde0314610304578063077f224a14610322575b600080fd5b61030c610790565b604051610319919061404a565b60405180910390f35b610335610330366004614197565b610822565b005b61033561034536600461420f565b610832565b61035d61035836600461422c565b610995565b6040519015158152602001610319565b61033561037b366004614258565b6109ab565b61039361038e366004614299565b610b00565b604051908152602001610319565b603554610393565b61039360d25481565b61035d6103c0366004614258565b610e51565b6103356103d33660046142d0565b610f3c565b6103356103e636600461420f565b610f93565b6103356103f936600461420f565b611345565b60405160128152602001610319565b61033561041b366004614300565b61142e565b610393611482565b61033561043636600461422c565b611491565b61035d61044936600461422c565b611621565b61033561045c366004614337565b61166a565b61039361046f36600461420f565b60d16020526000908152604090205481565b61033561048f36600461422c565b61176d565b6103936104a236600461420f565b6117c0565b6103936104b5366004614337565b60d36020526000908152604090205481565b60cd546104e79073ffffffffffffffffffffffffffffffffffffffff1681565b60405173ffffffffffffffffffffffffffffffffffffffff9091168152602001610319565b61039361051a36600461420f565b73ffffffffffffffffffffffffffffffffffffffff1660009081526033602052604090205490565b61033561055036600461422c565b611808565b61033561056336600461437b565b61199b565b610393611d03565b61039361057e36600461420f565b611d28565b61039361059136600461422c565b60d060209081526000928352604080842090915290825290205481565b6103356105bc366004614337565b611d55565b61030c611d62565b6103356105d736600461420f565b611d71565b6103356105ea3660046143d8565b611e39565b610393633b9aca0081565b61035d61060836600461422c565b612045565b61035d61061b36600461422c565b61211d565b61035d61062e36600461420f565b60cc6020526000908152604090205460ff1681565b6104e7610651366004614337565b61212a565b61065e612161565b604051610319919061440d565b6106c561067936600461420f565b60ce6020526000908152604090208054600182015460029092015490919067ffffffffffffffff81169060ff680100000000000000008204811691690100000000000000000090041685565b60408051958652602086019490945267ffffffffffffffff9092169284019290925290151560608301521515608082015260a001610319565b61039361070c366004614299565b6121cf565b61033561071f366004614467565b612393565b6103936107323660046144de565b73ffffffffffffffffffffffffffffffffffffffff918216600090815260346020908152604080832093909416825291909152205490565b61033561077836600461420f565b612534565b61033561078b36600461420f565b612708565b60606036805461079f9061450c565b80601f01602080910402602001604051908101604052809291908181526020018280546107cb9061450c565b80156108185780601f106107ed57610100808354040283529160200191610818565b820191906000526020600020905b8154815290600101906020018083116107fb57829003601f168201915b5050505050905090565b61082d8383836127ce565b505050565b60cd546040517f521d4de900000000000000000000000000000000000000000000000000000000815233600482015273ffffffffffffffffffffffffffffffffffffffff9091169063521d4de990602401602060405180830381865afa1580156108a0573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906108c4919061455a565b6108fa576040517f99e120bc00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff8116600090815260d1602052604081205461092b9060016145a6565b73ffffffffffffffffffffffffffffffffffffffff8316600081815260d160205260409081902083905551919250907f979ef83e7e7a87cb48064e296dd7e997870d50f43acf8d7ad221313526c8ca0f906109899084815260200190565b60405180910390a25050565b60006109a2338484612a3f565b50600192915050565b60cd546040517fe43581b800000000000000000000000000000000000000000000000000000000815233600482015273ffffffffffffffffffffffffffffffffffffffff9091169063e43581b890602401602060405180830381865afa158015610a19573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610a3d919061455a565b610a73576040517fee3675d400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b610a9473ffffffffffffffffffffffffffffffffffffffff84168383612bea565b8173ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff167ffff3b3844276f57024e0b42afec1a37f75db36511e43819a4f2a63ab7862b64883604051610af391815260200190565b60405180910390a3505050565b73ffffffffffffffffffffffffffffffffffffffff8316600090815260ce60209081526040808320815160a081018352815481526001820154938101939093526002015467ffffffffffffffff81169183019190915260ff680100000000000000008204811615801560608501526901000000000000000000909204161515608083015280610b90575080608001515b15610bc7576040517fc1ab6dc100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015260009073ffffffffffffffffffffffffffffffffffffffff8716906370a0823190602401602060405180830381865afa158015610c34573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610c5891906145bd565b8251909150610c6786836145d6565b1115610c8f578151811015610c8a578151610c839082906145a6565b9450610c8f565b600094505b6000610c9d610e10426145ee565b73ffffffffffffffffffffffffffffffffffffffff8816600090815260d06020908152604080832084845290915281205491925090610cdd9088906145d6565b90508360200151811115610d715773ffffffffffffffffffffffffffffffffffffffff8816600090815260d060209081526040808320858452825290912054908501511115610d6c5773ffffffffffffffffffffffffffffffffffffffff8816600090815260d06020908152604080832085845282529091205490850151610d6591906145a6565b9650610d71565b600096505b73ffffffffffffffffffffffffffffffffffffffff8816600090815260d060209081526040808320858452909152902054610dad9088906145d6565b73ffffffffffffffffffffffffffffffffffffffff8916600081815260d060209081526040808320878452909152902091909155610ded9033308a612cbe565b33600090815260d160205260409020548790610e3957633b9aca00856040015167ffffffffffffffff1682610e229190614629565b610e2c91906145ee565b610e3690826145a6565b90505b610e438782612d1c565b9450505050505b9392505050565b6000610e5e848484612e3c565b73ffffffffffffffffffffffffffffffffffffffff8416600090815260346020908152604080832033845290915290205482811015610f24576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602860248201527f45524332303a207472616e7366657220616d6f756e742065786365656473206160448201527f6c6c6f77616e636500000000000000000000000000000000000000000000000060648201526084015b60405180910390fd5b610f318533858403612a3f565b506001949350505050565b33600090815260cc602052604090205460ff16610f85576040517ff8d2906c00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b610f8f81836130ef565b5050565b60cd546040517fe43581b800000000000000000000000000000000000000000000000000000000815233600482015273ffffffffffffffffffffffffffffffffffffffff9091169063e43581b890602401602060405180830381865afa158015611001573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611025919061455a565b61105b576040517fee3675d400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015273ffffffffffffffffffffffffffffffffffffffff8216906370a0823190602401602060405180830381865afa1580156110c5573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906110e991906145bd565b15611120576040517f2ef630ec00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff8116600090815260ce602052604081208181556001810182905560020180547fffffffffffffffffffffffffffffffffffffffffffff0000000000000000000016905560cf54905b6111886001836145a6565b811015611296578273ffffffffffffffffffffffffffffffffffffffff1660cf82815481106111b9576111b9614666565b60009182526020909120015473ffffffffffffffffffffffffffffffffffffffff1614156112845760cf6111ee6001846145a6565b815481106111fe576111fe614666565b60009182526020909120015460cf805473ffffffffffffffffffffffffffffffffffffffff909216918390811061123757611237614666565b9060005260206000200160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550611296565b8061128e81614695565b91505061117d565b5060cf8054806112a8576112a86146ce565b60008281526020812082017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff90810180547fffffffffffffffffffffffff000000000000000000000000000000000000000016905590910190915560405173ffffffffffffffffffffffffffffffffffffffff8416917f5c95b49c4d59d97a2f044167723f29c74b30f99702e3fd406c3830160aa9ccb891a25050565b60cd5473ffffffffffffffffffffffffffffffffffffffff16331480159061138357503373ffffffffffffffffffffffffffffffffffffffff821614155b156113ba576040517fddb5de5e00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff8116600081815260cc602052604080822080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00169055517f98c15241d6c02bc5ee0b780e11b3ea737a2defd9d04877edbe9f9497065bd02f9190a250565b33600090815260cc602052604090205460ff16611477576040517ff8d2906c00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b61082d8383836132dc565b600061148c613397565b905090565b60cd546040517f521d4de900000000000000000000000000000000000000000000000000000000815233600482015273ffffffffffffffffffffffffffffffffffffffff9091169063521d4de990602401602060405180830381865afa1580156114ff573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611523919061455a565b611559576040517f99e120bc00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff8216600090815260ce602052604090206002015468010000000000000000900460ff166115c7576040517fc1ab6dc100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff8216600081815260ce602052604090819020839055517fe7b113fba37131b6396680a0c55790a697ec975e198ff8cfd89dac90a6379e61906109899084815260200190565b33600081815260346020908152604080832073ffffffffffffffffffffffffffffffffffffffff8716845290915281205490916109a29185906116659086906145d6565b612a3f565b60cd546040517f521d4de900000000000000000000000000000000000000000000000000000000815233600482015273ffffffffffffffffffffffffffffffffffffffff9091169063521d4de990602401602060405180830381865afa1580156116d8573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906116fc919061455a565b611732576040517f99e120bc00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60d28190556040518181527fc3b69829afe2345596a02c8b587d41f796ba0094481d899e1b2e07b7532a1e219060200160405180910390a150565b33600090815260cc602052604090205460ff166117b6576040517ff8d2906c00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b610f8f8282612d1c565b73ffffffffffffffffffffffffffffffffffffffff8116600090815260d060205260408120816117f2610e10426145ee565b8152602001908152602001600020549050919050565b60cd546040517f521d4de900000000000000000000000000000000000000000000000000000000815233600482015273ffffffffffffffffffffffffffffffffffffffff9091169063521d4de990602401602060405180830381865afa158015611876573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061189a919061455a565b6118d0576040517f99e120bc00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff8216600090815260ce602052604090206002015468010000000000000000900460ff1661193e576040517fc1ab6dc100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff8216600081815260ce602052604090819020600101839055517fe13ac9338b2ee623233f83c1b3ceab16490fa3e3737fac7f0970d0830a9f4871906109899084815260200190565b60cd546040517fe43581b800000000000000000000000000000000000000000000000000000000815233600482015273ffffffffffffffffffffffffffffffffffffffff9091169063e43581b890602401602060405180830381865afa158015611a09573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611a2d919061455a565b611a63576040517fee3675d400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff8516600090815260ce602052604090206002015468010000000000000000900460ff1680611aba575073ffffffffffffffffffffffffffffffffffffffff8516155b15611af1576040517fc1ab6dc100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b633b9aca008267ffffffffffffffff161115611b39576040517feca1d2c600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040805160a08101825260008082526020820181905291810182905260608101829052608081019190915284815260208082018581528315156080840190815267ffffffffffffffff808716604080870191825260016060880181815273ffffffffffffffffffffffffffffffffffffffff8e16600081815260ce9099528389208a5181559751888401559351600290970180549151965115156901000000000000000000027fffffffffffffffffffffffffffffffffffffffffffff00ffffffffffffffffff97151568010000000000000000027fffffffffffffffffffffffffffffffffffffffffffffff000000000000000000909316989096169790971717949094169290921790935560cf805492830181559093527facb8d954e2cfef495862221e91bd7523613cf8808827cb33edfe4904cc51bf290180547fffffffffffffffffffffffff0000000000000000000000000000000000000000168217905590517f53087ff85d80a7671594bd2e86b92af22e0b3c2c441c8033bba7399b7b5cbe2390611cf3908890889088908890938452602084019290925267ffffffffffffffff1660408301521515606082015260800190565b60405180910390a2505050505050565b600060d381611d14610e10426145ee565b815260200190815260200160002054905090565b73ffffffffffffffffffffffffffffffffffffffff81166000908152609960205260408120545b92915050565b611d5f33826130ef565b50565b60606037805461079f9061450c565b60cd5473ffffffffffffffffffffffffffffffffffffffff163314611dc2576040517fb90cdbb100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff8116600081815260cc602052604080822080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00166001179055517f98c15241d6c02bc5ee0b780e11b3ea737a2defd9d04877edbe9f9497065bd02f9190a250565b60cd546040517f521d4de900000000000000000000000000000000000000000000000000000000815233600482015273ffffffffffffffffffffffffffffffffffffffff9091169063521d4de990602401602060405180830381865afa158015611ea7573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611ecb919061455a565b611f01576040517f99e120bc00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff8216600090815260ce602052604090206002015468010000000000000000900460ff16611f6f576040517fc1ab6dc100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b633b9aca008167ffffffffffffffff161115611fb7576040517feca1d2c600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff8216600081815260ce602090815260409182902060020180547fffffffffffffffffffffffffffffffffffffffffffffffff00000000000000001667ffffffffffffffff861690811790915591519182527f901f9de19b475adc8da4110434b8df940dce085afd05e2281c86807f3a899d299101610989565b33600090815260346020908152604080832073ffffffffffffffffffffffffffffffffffffffff8616845290915281205482811015612106576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602560248201527f45524332303a2064656372656173656420616c6c6f77616e63652062656c6f7760448201527f207a65726f0000000000000000000000000000000000000000000000000000006064820152608401610f1b565b6121133385858403612a3f565b5060019392505050565b60006109a2338484612e3c565b60cf818154811061213a57600080fd5b60009182526020909120015473ffffffffffffffffffffffffffffffffffffffff16905081565b606060cf80548060200260200160405190810160405280929190818152602001828054801561081857602002820191906000526020600020905b815473ffffffffffffffffffffffffffffffffffffffff16815260019091019060200180831161219b575050505050905090565b73ffffffffffffffffffffffffffffffffffffffff8316600090815260ce60209081526040808320815160a081018352815481526001820154938101939093526002015467ffffffffffffffff81169183019190915260ff68010000000000000000820481161580156060850152690100000000000000000090920416151560808301528061225f575080608001515b15612296576040517fc1ab6dc100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60006122a4610e10426145ee565b600081815260d36020526040812054919250906122c29087906145d6565b905060d254811115612300576040517f6d43d1ac00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600082815260d36020526040902081905561231b33876130ef565b33600090815260d16020526040902054869061236757633b9aca00846040015167ffffffffffffffff16826123509190614629565b61235a91906145ee565b61236490826145a6565b90505b61238873ffffffffffffffffffffffffffffffffffffffff89168783612bea565b979650505050505050565b834211156123fd576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f45524332305065726d69743a206578706972656420646561646c696e650000006044820152606401610f1b565b6000609a5488888861240e8c613412565b60408051602081019690965273ffffffffffffffffffffffffffffffffffffffff94851690860152929091166060840152608083015260a082015260c0810186905260e001604051602081830303815290604052805190602001209050600061247682613447565b90506000612486828787876134b0565b90508973ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff161461251d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601e60248201527f45524332305065726d69743a20696e76616c6964207369676e617475726500006044820152606401610f1b565b6125288a8a8a612a3f565b50505050505050505050565b60cd546040517f521d4de900000000000000000000000000000000000000000000000000000000815233600482015273ffffffffffffffffffffffffffffffffffffffff9091169063521d4de990602401602060405180830381865afa1580156125a2573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906125c6919061455a565b6125fc576040517f99e120bc00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff8116600090815260ce602052604090206002015468010000000000000000900460ff1661266a576040517fc1ab6dc100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff8116600081815260ce602090815260409182902060020180547fffffffffffffffffffffffffffffffffffffffffffff00ffffffffffffffffff811669010000000000000000009182900460ff16801592830291909117909255925192835292917ff7c93079dcbf699749d66345a351afab7d24219bb1d915c9f4fc4cf03f00d3979101610989565b60cd5473ffffffffffffffffffffffffffffffffffffffff163314612759576040517fb90cdbb100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60cd80547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83169081179091556040517f7dae230f18360d76a040c81f050aa14eb9d6dc7901b20fc5d855e2a20fe814d190600090a250565b3b151590565b600054610100900460ff166127e95760005460ff16156127ed565b303b155b612879576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201527f647920696e697469616c697a65640000000000000000000000000000000000006064820152608401610f1b565b600054610100900460ff161580156128b857600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0000166101011790555b6128c1846134d8565b6128cb84846135bf565b3073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1663e9cbd8226040518163ffffffff1660e01b8152600401602060405180830381865afa15801561292d573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061295191906146fd565b73ffffffffffffffffffffffffffffffffffffffff161461299e576040517f14bcf5c800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60cd80547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff84169081179091556040517f7dae230f18360d76a040c81f050aa14eb9d6dc7901b20fc5d855e2a20fe814d190600090a28015612a3957600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff1690555b50505050565b73ffffffffffffffffffffffffffffffffffffffff8316612ae1576040517f08c379a0000000000000000000000000000000000000000000000000000000008152602060048201526024808201527f45524332303a20617070726f76652066726f6d20746865207a65726f2061646460448201527f72657373000000000000000000000000000000000000000000000000000000006064820152608401610f1b565b73ffffffffffffffffffffffffffffffffffffffff8216612b84576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602260248201527f45524332303a20617070726f766520746f20746865207a65726f20616464726560448201527f73730000000000000000000000000000000000000000000000000000000000006064820152608401610f1b565b73ffffffffffffffffffffffffffffffffffffffff83811660008181526034602090815260408083209487168084529482529182902085905590518481527f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b9259101610af3565b60405173ffffffffffffffffffffffffffffffffffffffff831660248201526044810182905261082d9084907fa9059cbb00000000000000000000000000000000000000000000000000000000906064015b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff0000000000000000000000000000000000000000000000000000000090931692909217909152613668565b60405173ffffffffffffffffffffffffffffffffffffffff80851660248301528316604482015260648101829052612a399085907f23b872dd0000000000000000000000000000000000000000000000000000000090608401612c3c565b73ffffffffffffffffffffffffffffffffffffffff8216612d99576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601f60248201527f45524332303a206d696e7420746f20746865207a65726f2061646472657373006044820152606401610f1b565b8060356000828254612dab91906145d6565b909155505073ffffffffffffffffffffffffffffffffffffffff821660009081526033602052604081208054839290612de59084906145d6565b909155505060405181815273ffffffffffffffffffffffffffffffffffffffff8316906000907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef9060200160405180910390a35050565b73ffffffffffffffffffffffffffffffffffffffff8316612edf576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602560248201527f45524332303a207472616e736665722066726f6d20746865207a65726f20616460448201527f64726573730000000000000000000000000000000000000000000000000000006064820152608401610f1b565b73ffffffffffffffffffffffffffffffffffffffff8216612f82576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602360248201527f45524332303a207472616e7366657220746f20746865207a65726f206164647260448201527f65737300000000000000000000000000000000000000000000000000000000006064820152608401610f1b565b73ffffffffffffffffffffffffffffffffffffffff831660009081526033602052604090205481811015613038576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f45524332303a207472616e7366657220616d6f756e742065786365656473206260448201527f616c616e636500000000000000000000000000000000000000000000000000006064820152608401610f1b565b73ffffffffffffffffffffffffffffffffffffffff80851660009081526033602052604080822085850390559185168152908120805484929061307c9084906145d6565b925050819055508273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef846040516130e291815260200190565b60405180910390a3612a39565b73ffffffffffffffffffffffffffffffffffffffff8216613192576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602160248201527f45524332303a206275726e2066726f6d20746865207a65726f2061646472657360448201527f73000000000000000000000000000000000000000000000000000000000000006064820152608401610f1b565b73ffffffffffffffffffffffffffffffffffffffff821660009081526033602052604090205481811015613248576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602260248201527f45524332303a206275726e20616d6f756e7420657863656564732062616c616e60448201527f63650000000000000000000000000000000000000000000000000000000000006064820152608401610f1b565b73ffffffffffffffffffffffffffffffffffffffff831660009081526033602052604081208383039055603580548492906132849084906145a6565b909155505060405182815260009073ffffffffffffffffffffffffffffffffffffffff8516907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef9060200160405180910390a3505050565b8073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff161461338d5773ffffffffffffffffffffffffffffffffffffffff8281166000908152603460209081526040808320938516835292905220548381101561337c576040517f715ec26c00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b61338b838361166587856145a6565b505b61082d82846130ef565b600061148c7f8b73c3c69bb8fe3d512ecc4cf759cc79239f7b179b0ffacaa9a75d522b39400f6133c660655490565b6066546040805160208101859052908101839052606081018290524660808201523060a082015260009060c0016040516020818303038152906040528051906020012090509392505050565b73ffffffffffffffffffffffffffffffffffffffff811660009081526099602052604090208054600181018255905b50919050565b6000611d4f613454613397565b836040517f19010000000000000000000000000000000000000000000000000000000000006020820152602281018390526042810182905260009060620160405160208183030381529060405280519060200120905092915050565b60008060006134c187878787613774565b915091506134ce8161388c565b5095945050505050565b600054610100900460ff1661356f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201527f6e697469616c697a696e670000000000000000000000000000000000000000006064820152608401610f1b565b613577613ae5565b6135b6816040518060400160405280600181526020017f3100000000000000000000000000000000000000000000000000000000000000815250613b7e565b611d5f81613c2f565b600054610100900460ff16613656576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201527f6e697469616c697a696e670000000000000000000000000000000000000000006064820152608401610f1b565b61365e613ae5565b610f8f8282613ced565b60006136ca826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c65648152508573ffffffffffffffffffffffffffffffffffffffff16613dab9092919063ffffffff16565b80519091501561082d57808060200190518101906136e8919061455a565b61082d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e60448201527f6f742073756363656564000000000000000000000000000000000000000000006064820152608401610f1b565b6000807f7fffffffffffffffffffffffffffffff5d576e7357a4501ddfe92f46681b20a08311156137ab5750600090506003613883565b8460ff16601b141580156137c357508460ff16601c14155b156137d45750600090506004613883565b6040805160008082526020820180845289905260ff881692820192909252606081018690526080810185905260019060a0016020604051602081039080840390855afa158015613828573d6000803e3d6000fd5b50506040517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0015191505073ffffffffffffffffffffffffffffffffffffffff811661387c57600060019250925050613883565b9150600090505b94509492505050565b60008160048111156138a0576138a061471a565b14156138a95750565b60018160048111156138bd576138bd61471a565b1415613925576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601860248201527f45434453413a20696e76616c6964207369676e617475726500000000000000006044820152606401610f1b565b60028160048111156139395761393961471a565b14156139a1576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601f60248201527f45434453413a20696e76616c6964207369676e6174757265206c656e677468006044820152606401610f1b565b60038160048111156139b5576139b561471a565b1415613a43576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602260248201527f45434453413a20696e76616c6964207369676e6174757265202773272076616c60448201527f75650000000000000000000000000000000000000000000000000000000000006064820152608401610f1b565b6004816004811115613a5757613a5761471a565b1415611d5f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602260248201527f45434453413a20696e76616c6964207369676e6174757265202776272076616c60448201527f75650000000000000000000000000000000000000000000000000000000000006064820152608401610f1b565b600054610100900460ff16613b7c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201527f6e697469616c697a696e670000000000000000000000000000000000000000006064820152608401610f1b565b565b600054610100900460ff16613c15576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201527f6e697469616c697a696e670000000000000000000000000000000000000000006064820152608401610f1b565b815160209283012081519190920120606591909155606655565b600054610100900460ff16613cc6576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201527f6e697469616c697a696e670000000000000000000000000000000000000000006064820152608401610f1b565b507f6e71edae12b1b97f4d1f60370fef10105fa2faae0126114a169c64845d6126c9609a55565b600054610100900460ff16613d84576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201527f6e697469616c697a696e670000000000000000000000000000000000000000006064820152608401610f1b565b8151613d97906036906020850190613f85565b50805161082d906037906020840190613f85565b6060613dba8484600085613dc2565b949350505050565b606082471015613e54576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f60448201527f722063616c6c00000000000000000000000000000000000000000000000000006064820152608401610f1b565b843b613ebc576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006044820152606401610f1b565b6000808673ffffffffffffffffffffffffffffffffffffffff168587604051613ee59190614749565b60006040518083038185875af1925050503d8060008114613f22576040519150601f19603f3d011682016040523d82523d6000602084013e613f27565b606091505b509150915061238882828660608315613f41575081610e4a565b825115613f515782518084602001fd5b816040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610f1b919061404a565b828054613f919061450c565b90600052602060002090601f016020900481019282613fb35760008555613ff9565b82601f10613fcc57805160ff1916838001178555613ff9565b82800160010185558215613ff9579182015b82811115613ff9578251825591602001919060010190613fde565b50614005929150614009565b5090565b5b80821115614005576000815560010161400a565b60005b83811015614039578181015183820152602001614021565b83811115612a395750506000910152565b602081526000825180602084015261406981604085016020870161401e565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169190910160400192915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b600082601f8301126140db57600080fd5b813567ffffffffffffffff808211156140f6576140f661409b565b604051601f83017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0908116603f0116810190828211818310171561413c5761413c61409b565b8160405283815286602085880101111561415557600080fd5b836020870160208301376000602085830101528094505050505092915050565b73ffffffffffffffffffffffffffffffffffffffff81168114611d5f57600080fd5b6000806000606084860312156141ac57600080fd5b833567ffffffffffffffff808211156141c457600080fd5b6141d0878388016140ca565b945060208601359150808211156141e657600080fd5b506141f3868287016140ca565b925050604084013561420481614175565b809150509250925092565b60006020828403121561422157600080fd5b8135610e4a81614175565b6000806040838503121561423f57600080fd5b823561424a81614175565b946020939093013593505050565b60008060006060848603121561426d57600080fd5b833561427881614175565b9250602084013561428881614175565b929592945050506040919091013590565b6000806000606084860312156142ae57600080fd5b83356142b981614175565b925060208401359150604084013561420481614175565b600080604083850312156142e357600080fd5b8235915060208301356142f581614175565b809150509250929050565b60008060006060848603121561431557600080fd5b83359250602084013561432781614175565b9150604084013561420481614175565b60006020828403121561434957600080fd5b5035919050565b803567ffffffffffffffff8116811461436857600080fd5b919050565b8015158114611d5f57600080fd5b600080600080600060a0868803121561439357600080fd5b853561439e81614175565b945060208601359350604086013592506143ba60608701614350565b915060808601356143ca8161436d565b809150509295509295909350565b600080604083850312156143eb57600080fd5b82356143f681614175565b915061440460208401614350565b90509250929050565b6020808252825182820181905260009190848201906040850190845b8181101561445b57835173ffffffffffffffffffffffffffffffffffffffff1683529284019291840191600101614429565b50909695505050505050565b600080600080600080600060e0888a03121561448257600080fd5b873561448d81614175565b9650602088013561449d81614175565b95506040880135945060608801359350608088013560ff811681146144c157600080fd5b9699959850939692959460a0840135945060c09093013592915050565b600080604083850312156144f157600080fd5b82356144fc81614175565b915060208301356142f581614175565b600181811c9082168061452057607f821691505b60208210811415613441577f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b60006020828403121561456c57600080fd5b8151610e4a8161436d565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b6000828210156145b8576145b8614577565b500390565b6000602082840312156145cf57600080fd5b5051919050565b600082198211156145e9576145e9614577565b500190565b600082614624577f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b500490565b6000817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff048311821515161561466157614661614577565b500290565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8214156146c7576146c7614577565b5060010190565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603160045260246000fd5b60006020828403121561470f57600080fd5b8151610e4a81614175565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b6000825161475b81846020870161401e565b919091019291505056fea2646970667358221220103b8d652dd7975983cef70f41cb81056a0bf607243b7332223b4013506c7eb664736f6c634300080c0033", - "deployedBytecode": "0x608060405234801561001057600080fd5b50600436106102ff5760003560e01c806361d027b31161019c5780639f48118f116100ee578063ced67f0c11610097578063dd62ed3e11610071578063dd62ed3e14610724578063e3e286551461076a578063f0f442601461077d57600080fd5b8063ced67f0c1461066b578063d44ad63f146106fe578063d505accf1461071157600080fd5b8063aa271e1a116100c8578063aa271e1a14610620578063ba330bd714610643578063cd4839ca1461065657600080fd5b80639f48118f146105ef578063a457c2d7146105fa578063a9059cbb1461060d57600080fd5b80637ecebe001161015057806395d89b411161012a57806395d89b41146105c1578063983b2d56146105c95780639e4e0dae146105dc57600080fd5b80637ecebe00146105705780638933fb791461058357806390218cff146105ae57600080fd5b80637334d020116101815780637334d020146105425780637d4c9c2d146105555780637d74e25f1461056857600080fd5b806361d027b3146104c757806370a082311461050c57600080fd5b80633092afd511610255578063395093511161020957806340c10f19116101e357806340c10f19146104815780634dc32fcc146104945780635bfbec96146104a757600080fd5b8063395093511461043b5780633a55f89d1461044e5780633f4218e01461046157600080fd5b8063350ebe041161023a578063350ebe041461040d5780633644e5151461042057806336db43b51461042857600080fd5b80633092afd5146103eb578063313ce567146103fe57600080fd5b8063151dd755116102b757806323b872dd1161029157806323b872dd146103b25780632b471d8e146103c55780632e403e14146103d857600080fd5b8063151dd7551461038057806318160ddd146103a15780632342fb0e146103a957600080fd5b80630919a951116102e85780630919a95114610337578063095ea7b31461034a5780631171bda91461036d57600080fd5b806306fdde0314610304578063077f224a14610322575b600080fd5b61030c610790565b604051610319919061404a565b60405180910390f35b610335610330366004614197565b610822565b005b61033561034536600461420f565b610832565b61035d61035836600461422c565b610995565b6040519015158152602001610319565b61033561037b366004614258565b6109ab565b61039361038e366004614299565b610b00565b604051908152602001610319565b603554610393565b61039360d25481565b61035d6103c0366004614258565b610e51565b6103356103d33660046142d0565b610f3c565b6103356103e636600461420f565b610f93565b6103356103f936600461420f565b611345565b60405160128152602001610319565b61033561041b366004614300565b61142e565b610393611482565b61033561043636600461422c565b611491565b61035d61044936600461422c565b611621565b61033561045c366004614337565b61166a565b61039361046f36600461420f565b60d16020526000908152604090205481565b61033561048f36600461422c565b61176d565b6103936104a236600461420f565b6117c0565b6103936104b5366004614337565b60d36020526000908152604090205481565b60cd546104e79073ffffffffffffffffffffffffffffffffffffffff1681565b60405173ffffffffffffffffffffffffffffffffffffffff9091168152602001610319565b61039361051a36600461420f565b73ffffffffffffffffffffffffffffffffffffffff1660009081526033602052604090205490565b61033561055036600461422c565b611808565b61033561056336600461437b565b61199b565b610393611d03565b61039361057e36600461420f565b611d28565b61039361059136600461422c565b60d060209081526000928352604080842090915290825290205481565b6103356105bc366004614337565b611d55565b61030c611d62565b6103356105d736600461420f565b611d71565b6103356105ea3660046143d8565b611e39565b610393633b9aca0081565b61035d61060836600461422c565b612045565b61035d61061b36600461422c565b61211d565b61035d61062e36600461420f565b60cc6020526000908152604090205460ff1681565b6104e7610651366004614337565b61212a565b61065e612161565b604051610319919061440d565b6106c561067936600461420f565b60ce6020526000908152604090208054600182015460029092015490919067ffffffffffffffff81169060ff680100000000000000008204811691690100000000000000000090041685565b60408051958652602086019490945267ffffffffffffffff9092169284019290925290151560608301521515608082015260a001610319565b61039361070c366004614299565b6121cf565b61033561071f366004614467565b612393565b6103936107323660046144de565b73ffffffffffffffffffffffffffffffffffffffff918216600090815260346020908152604080832093909416825291909152205490565b61033561077836600461420f565b612534565b61033561078b36600461420f565b612708565b60606036805461079f9061450c565b80601f01602080910402602001604051908101604052809291908181526020018280546107cb9061450c565b80156108185780601f106107ed57610100808354040283529160200191610818565b820191906000526020600020905b8154815290600101906020018083116107fb57829003601f168201915b5050505050905090565b61082d8383836127ce565b505050565b60cd546040517f521d4de900000000000000000000000000000000000000000000000000000000815233600482015273ffffffffffffffffffffffffffffffffffffffff9091169063521d4de990602401602060405180830381865afa1580156108a0573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906108c4919061455a565b6108fa576040517f99e120bc00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff8116600090815260d1602052604081205461092b9060016145a6565b73ffffffffffffffffffffffffffffffffffffffff8316600081815260d160205260409081902083905551919250907f979ef83e7e7a87cb48064e296dd7e997870d50f43acf8d7ad221313526c8ca0f906109899084815260200190565b60405180910390a25050565b60006109a2338484612a3f565b50600192915050565b60cd546040517fe43581b800000000000000000000000000000000000000000000000000000000815233600482015273ffffffffffffffffffffffffffffffffffffffff9091169063e43581b890602401602060405180830381865afa158015610a19573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610a3d919061455a565b610a73576040517fee3675d400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b610a9473ffffffffffffffffffffffffffffffffffffffff84168383612bea565b8173ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff167ffff3b3844276f57024e0b42afec1a37f75db36511e43819a4f2a63ab7862b64883604051610af391815260200190565b60405180910390a3505050565b73ffffffffffffffffffffffffffffffffffffffff8316600090815260ce60209081526040808320815160a081018352815481526001820154938101939093526002015467ffffffffffffffff81169183019190915260ff680100000000000000008204811615801560608501526901000000000000000000909204161515608083015280610b90575080608001515b15610bc7576040517fc1ab6dc100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015260009073ffffffffffffffffffffffffffffffffffffffff8716906370a0823190602401602060405180830381865afa158015610c34573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610c5891906145bd565b8251909150610c6786836145d6565b1115610c8f578151811015610c8a578151610c839082906145a6565b9450610c8f565b600094505b6000610c9d610e10426145ee565b73ffffffffffffffffffffffffffffffffffffffff8816600090815260d06020908152604080832084845290915281205491925090610cdd9088906145d6565b90508360200151811115610d715773ffffffffffffffffffffffffffffffffffffffff8816600090815260d060209081526040808320858452825290912054908501511115610d6c5773ffffffffffffffffffffffffffffffffffffffff8816600090815260d06020908152604080832085845282529091205490850151610d6591906145a6565b9650610d71565b600096505b73ffffffffffffffffffffffffffffffffffffffff8816600090815260d060209081526040808320858452909152902054610dad9088906145d6565b73ffffffffffffffffffffffffffffffffffffffff8916600081815260d060209081526040808320878452909152902091909155610ded9033308a612cbe565b33600090815260d160205260409020548790610e3957633b9aca00856040015167ffffffffffffffff1682610e229190614629565b610e2c91906145ee565b610e3690826145a6565b90505b610e438782612d1c565b9450505050505b9392505050565b6000610e5e848484612e3c565b73ffffffffffffffffffffffffffffffffffffffff8416600090815260346020908152604080832033845290915290205482811015610f24576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602860248201527f45524332303a207472616e7366657220616d6f756e742065786365656473206160448201527f6c6c6f77616e636500000000000000000000000000000000000000000000000060648201526084015b60405180910390fd5b610f318533858403612a3f565b506001949350505050565b33600090815260cc602052604090205460ff16610f85576040517ff8d2906c00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b610f8f81836130ef565b5050565b60cd546040517fe43581b800000000000000000000000000000000000000000000000000000000815233600482015273ffffffffffffffffffffffffffffffffffffffff9091169063e43581b890602401602060405180830381865afa158015611001573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611025919061455a565b61105b576040517fee3675d400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015273ffffffffffffffffffffffffffffffffffffffff8216906370a0823190602401602060405180830381865afa1580156110c5573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906110e991906145bd565b15611120576040517f2ef630ec00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff8116600090815260ce602052604081208181556001810182905560020180547fffffffffffffffffffffffffffffffffffffffffffff0000000000000000000016905560cf54905b6111886001836145a6565b811015611296578273ffffffffffffffffffffffffffffffffffffffff1660cf82815481106111b9576111b9614666565b60009182526020909120015473ffffffffffffffffffffffffffffffffffffffff1614156112845760cf6111ee6001846145a6565b815481106111fe576111fe614666565b60009182526020909120015460cf805473ffffffffffffffffffffffffffffffffffffffff909216918390811061123757611237614666565b9060005260206000200160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550611296565b8061128e81614695565b91505061117d565b5060cf8054806112a8576112a86146ce565b60008281526020812082017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff90810180547fffffffffffffffffffffffff000000000000000000000000000000000000000016905590910190915560405173ffffffffffffffffffffffffffffffffffffffff8416917f5c95b49c4d59d97a2f044167723f29c74b30f99702e3fd406c3830160aa9ccb891a25050565b60cd5473ffffffffffffffffffffffffffffffffffffffff16331480159061138357503373ffffffffffffffffffffffffffffffffffffffff821614155b156113ba576040517fddb5de5e00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff8116600081815260cc602052604080822080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00169055517f98c15241d6c02bc5ee0b780e11b3ea737a2defd9d04877edbe9f9497065bd02f9190a250565b33600090815260cc602052604090205460ff16611477576040517ff8d2906c00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b61082d8383836132dc565b600061148c613397565b905090565b60cd546040517f521d4de900000000000000000000000000000000000000000000000000000000815233600482015273ffffffffffffffffffffffffffffffffffffffff9091169063521d4de990602401602060405180830381865afa1580156114ff573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611523919061455a565b611559576040517f99e120bc00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff8216600090815260ce602052604090206002015468010000000000000000900460ff166115c7576040517fc1ab6dc100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff8216600081815260ce602052604090819020839055517fe7b113fba37131b6396680a0c55790a697ec975e198ff8cfd89dac90a6379e61906109899084815260200190565b33600081815260346020908152604080832073ffffffffffffffffffffffffffffffffffffffff8716845290915281205490916109a29185906116659086906145d6565b612a3f565b60cd546040517f521d4de900000000000000000000000000000000000000000000000000000000815233600482015273ffffffffffffffffffffffffffffffffffffffff9091169063521d4de990602401602060405180830381865afa1580156116d8573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906116fc919061455a565b611732576040517f99e120bc00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60d28190556040518181527fc3b69829afe2345596a02c8b587d41f796ba0094481d899e1b2e07b7532a1e219060200160405180910390a150565b33600090815260cc602052604090205460ff166117b6576040517ff8d2906c00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b610f8f8282612d1c565b73ffffffffffffffffffffffffffffffffffffffff8116600090815260d060205260408120816117f2610e10426145ee565b8152602001908152602001600020549050919050565b60cd546040517f521d4de900000000000000000000000000000000000000000000000000000000815233600482015273ffffffffffffffffffffffffffffffffffffffff9091169063521d4de990602401602060405180830381865afa158015611876573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061189a919061455a565b6118d0576040517f99e120bc00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff8216600090815260ce602052604090206002015468010000000000000000900460ff1661193e576040517fc1ab6dc100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff8216600081815260ce602052604090819020600101839055517fe13ac9338b2ee623233f83c1b3ceab16490fa3e3737fac7f0970d0830a9f4871906109899084815260200190565b60cd546040517fe43581b800000000000000000000000000000000000000000000000000000000815233600482015273ffffffffffffffffffffffffffffffffffffffff9091169063e43581b890602401602060405180830381865afa158015611a09573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611a2d919061455a565b611a63576040517fee3675d400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff8516600090815260ce602052604090206002015468010000000000000000900460ff1680611aba575073ffffffffffffffffffffffffffffffffffffffff8516155b15611af1576040517fc1ab6dc100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b633b9aca008267ffffffffffffffff161115611b39576040517feca1d2c600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040805160a08101825260008082526020820181905291810182905260608101829052608081019190915284815260208082018581528315156080840190815267ffffffffffffffff808716604080870191825260016060880181815273ffffffffffffffffffffffffffffffffffffffff8e16600081815260ce9099528389208a5181559751888401559351600290970180549151965115156901000000000000000000027fffffffffffffffffffffffffffffffffffffffffffff00ffffffffffffffffff97151568010000000000000000027fffffffffffffffffffffffffffffffffffffffffffffff000000000000000000909316989096169790971717949094169290921790935560cf805492830181559093527facb8d954e2cfef495862221e91bd7523613cf8808827cb33edfe4904cc51bf290180547fffffffffffffffffffffffff0000000000000000000000000000000000000000168217905590517f53087ff85d80a7671594bd2e86b92af22e0b3c2c441c8033bba7399b7b5cbe2390611cf3908890889088908890938452602084019290925267ffffffffffffffff1660408301521515606082015260800190565b60405180910390a2505050505050565b600060d381611d14610e10426145ee565b815260200190815260200160002054905090565b73ffffffffffffffffffffffffffffffffffffffff81166000908152609960205260408120545b92915050565b611d5f33826130ef565b50565b60606037805461079f9061450c565b60cd5473ffffffffffffffffffffffffffffffffffffffff163314611dc2576040517fb90cdbb100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff8116600081815260cc602052604080822080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00166001179055517f98c15241d6c02bc5ee0b780e11b3ea737a2defd9d04877edbe9f9497065bd02f9190a250565b60cd546040517f521d4de900000000000000000000000000000000000000000000000000000000815233600482015273ffffffffffffffffffffffffffffffffffffffff9091169063521d4de990602401602060405180830381865afa158015611ea7573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611ecb919061455a565b611f01576040517f99e120bc00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff8216600090815260ce602052604090206002015468010000000000000000900460ff16611f6f576040517fc1ab6dc100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b633b9aca008167ffffffffffffffff161115611fb7576040517feca1d2c600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff8216600081815260ce602090815260409182902060020180547fffffffffffffffffffffffffffffffffffffffffffffffff00000000000000001667ffffffffffffffff861690811790915591519182527f901f9de19b475adc8da4110434b8df940dce085afd05e2281c86807f3a899d299101610989565b33600090815260346020908152604080832073ffffffffffffffffffffffffffffffffffffffff8616845290915281205482811015612106576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602560248201527f45524332303a2064656372656173656420616c6c6f77616e63652062656c6f7760448201527f207a65726f0000000000000000000000000000000000000000000000000000006064820152608401610f1b565b6121133385858403612a3f565b5060019392505050565b60006109a2338484612e3c565b60cf818154811061213a57600080fd5b60009182526020909120015473ffffffffffffffffffffffffffffffffffffffff16905081565b606060cf80548060200260200160405190810160405280929190818152602001828054801561081857602002820191906000526020600020905b815473ffffffffffffffffffffffffffffffffffffffff16815260019091019060200180831161219b575050505050905090565b73ffffffffffffffffffffffffffffffffffffffff8316600090815260ce60209081526040808320815160a081018352815481526001820154938101939093526002015467ffffffffffffffff81169183019190915260ff68010000000000000000820481161580156060850152690100000000000000000090920416151560808301528061225f575080608001515b15612296576040517fc1ab6dc100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60006122a4610e10426145ee565b600081815260d36020526040812054919250906122c29087906145d6565b905060d254811115612300576040517f6d43d1ac00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600082815260d36020526040902081905561231b33876130ef565b33600090815260d16020526040902054869061236757633b9aca00846040015167ffffffffffffffff16826123509190614629565b61235a91906145ee565b61236490826145a6565b90505b61238873ffffffffffffffffffffffffffffffffffffffff89168783612bea565b979650505050505050565b834211156123fd576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f45524332305065726d69743a206578706972656420646561646c696e650000006044820152606401610f1b565b6000609a5488888861240e8c613412565b60408051602081019690965273ffffffffffffffffffffffffffffffffffffffff94851690860152929091166060840152608083015260a082015260c0810186905260e001604051602081830303815290604052805190602001209050600061247682613447565b90506000612486828787876134b0565b90508973ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff161461251d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601e60248201527f45524332305065726d69743a20696e76616c6964207369676e617475726500006044820152606401610f1b565b6125288a8a8a612a3f565b50505050505050505050565b60cd546040517f521d4de900000000000000000000000000000000000000000000000000000000815233600482015273ffffffffffffffffffffffffffffffffffffffff9091169063521d4de990602401602060405180830381865afa1580156125a2573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906125c6919061455a565b6125fc576040517f99e120bc00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff8116600090815260ce602052604090206002015468010000000000000000900460ff1661266a576040517fc1ab6dc100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff8116600081815260ce602090815260409182902060020180547fffffffffffffffffffffffffffffffffffffffffffff00ffffffffffffffffff811669010000000000000000009182900460ff16801592830291909117909255925192835292917ff7c93079dcbf699749d66345a351afab7d24219bb1d915c9f4fc4cf03f00d3979101610989565b60cd5473ffffffffffffffffffffffffffffffffffffffff163314612759576040517fb90cdbb100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60cd80547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83169081179091556040517f7dae230f18360d76a040c81f050aa14eb9d6dc7901b20fc5d855e2a20fe814d190600090a250565b3b151590565b600054610100900460ff166127e95760005460ff16156127ed565b303b155b612879576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201527f647920696e697469616c697a65640000000000000000000000000000000000006064820152608401610f1b565b600054610100900460ff161580156128b857600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0000166101011790555b6128c1846134d8565b6128cb84846135bf565b3073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1663e9cbd8226040518163ffffffff1660e01b8152600401602060405180830381865afa15801561292d573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061295191906146fd565b73ffffffffffffffffffffffffffffffffffffffff161461299e576040517f14bcf5c800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60cd80547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff84169081179091556040517f7dae230f18360d76a040c81f050aa14eb9d6dc7901b20fc5d855e2a20fe814d190600090a28015612a3957600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff1690555b50505050565b73ffffffffffffffffffffffffffffffffffffffff8316612ae1576040517f08c379a0000000000000000000000000000000000000000000000000000000008152602060048201526024808201527f45524332303a20617070726f76652066726f6d20746865207a65726f2061646460448201527f72657373000000000000000000000000000000000000000000000000000000006064820152608401610f1b565b73ffffffffffffffffffffffffffffffffffffffff8216612b84576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602260248201527f45524332303a20617070726f766520746f20746865207a65726f20616464726560448201527f73730000000000000000000000000000000000000000000000000000000000006064820152608401610f1b565b73ffffffffffffffffffffffffffffffffffffffff83811660008181526034602090815260408083209487168084529482529182902085905590518481527f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b9259101610af3565b60405173ffffffffffffffffffffffffffffffffffffffff831660248201526044810182905261082d9084907fa9059cbb00000000000000000000000000000000000000000000000000000000906064015b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff0000000000000000000000000000000000000000000000000000000090931692909217909152613668565b60405173ffffffffffffffffffffffffffffffffffffffff80851660248301528316604482015260648101829052612a399085907f23b872dd0000000000000000000000000000000000000000000000000000000090608401612c3c565b73ffffffffffffffffffffffffffffffffffffffff8216612d99576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601f60248201527f45524332303a206d696e7420746f20746865207a65726f2061646472657373006044820152606401610f1b565b8060356000828254612dab91906145d6565b909155505073ffffffffffffffffffffffffffffffffffffffff821660009081526033602052604081208054839290612de59084906145d6565b909155505060405181815273ffffffffffffffffffffffffffffffffffffffff8316906000907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef9060200160405180910390a35050565b73ffffffffffffffffffffffffffffffffffffffff8316612edf576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602560248201527f45524332303a207472616e736665722066726f6d20746865207a65726f20616460448201527f64726573730000000000000000000000000000000000000000000000000000006064820152608401610f1b565b73ffffffffffffffffffffffffffffffffffffffff8216612f82576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602360248201527f45524332303a207472616e7366657220746f20746865207a65726f206164647260448201527f65737300000000000000000000000000000000000000000000000000000000006064820152608401610f1b565b73ffffffffffffffffffffffffffffffffffffffff831660009081526033602052604090205481811015613038576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f45524332303a207472616e7366657220616d6f756e742065786365656473206260448201527f616c616e636500000000000000000000000000000000000000000000000000006064820152608401610f1b565b73ffffffffffffffffffffffffffffffffffffffff80851660009081526033602052604080822085850390559185168152908120805484929061307c9084906145d6565b925050819055508273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef846040516130e291815260200190565b60405180910390a3612a39565b73ffffffffffffffffffffffffffffffffffffffff8216613192576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602160248201527f45524332303a206275726e2066726f6d20746865207a65726f2061646472657360448201527f73000000000000000000000000000000000000000000000000000000000000006064820152608401610f1b565b73ffffffffffffffffffffffffffffffffffffffff821660009081526033602052604090205481811015613248576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602260248201527f45524332303a206275726e20616d6f756e7420657863656564732062616c616e60448201527f63650000000000000000000000000000000000000000000000000000000000006064820152608401610f1b565b73ffffffffffffffffffffffffffffffffffffffff831660009081526033602052604081208383039055603580548492906132849084906145a6565b909155505060405182815260009073ffffffffffffffffffffffffffffffffffffffff8516907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef9060200160405180910390a3505050565b8073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff161461338d5773ffffffffffffffffffffffffffffffffffffffff8281166000908152603460209081526040808320938516835292905220548381101561337c576040517f715ec26c00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b61338b838361166587856145a6565b505b61082d82846130ef565b600061148c7f8b73c3c69bb8fe3d512ecc4cf759cc79239f7b179b0ffacaa9a75d522b39400f6133c660655490565b6066546040805160208101859052908101839052606081018290524660808201523060a082015260009060c0016040516020818303038152906040528051906020012090509392505050565b73ffffffffffffffffffffffffffffffffffffffff811660009081526099602052604090208054600181018255905b50919050565b6000611d4f613454613397565b836040517f19010000000000000000000000000000000000000000000000000000000000006020820152602281018390526042810182905260009060620160405160208183030381529060405280519060200120905092915050565b60008060006134c187878787613774565b915091506134ce8161388c565b5095945050505050565b600054610100900460ff1661356f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201527f6e697469616c697a696e670000000000000000000000000000000000000000006064820152608401610f1b565b613577613ae5565b6135b6816040518060400160405280600181526020017f3100000000000000000000000000000000000000000000000000000000000000815250613b7e565b611d5f81613c2f565b600054610100900460ff16613656576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201527f6e697469616c697a696e670000000000000000000000000000000000000000006064820152608401610f1b565b61365e613ae5565b610f8f8282613ced565b60006136ca826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c65648152508573ffffffffffffffffffffffffffffffffffffffff16613dab9092919063ffffffff16565b80519091501561082d57808060200190518101906136e8919061455a565b61082d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e60448201527f6f742073756363656564000000000000000000000000000000000000000000006064820152608401610f1b565b6000807f7fffffffffffffffffffffffffffffff5d576e7357a4501ddfe92f46681b20a08311156137ab5750600090506003613883565b8460ff16601b141580156137c357508460ff16601c14155b156137d45750600090506004613883565b6040805160008082526020820180845289905260ff881692820192909252606081018690526080810185905260019060a0016020604051602081039080840390855afa158015613828573d6000803e3d6000fd5b50506040517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0015191505073ffffffffffffffffffffffffffffffffffffffff811661387c57600060019250925050613883565b9150600090505b94509492505050565b60008160048111156138a0576138a061471a565b14156138a95750565b60018160048111156138bd576138bd61471a565b1415613925576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601860248201527f45434453413a20696e76616c6964207369676e617475726500000000000000006044820152606401610f1b565b60028160048111156139395761393961471a565b14156139a1576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601f60248201527f45434453413a20696e76616c6964207369676e6174757265206c656e677468006044820152606401610f1b565b60038160048111156139b5576139b561471a565b1415613a43576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602260248201527f45434453413a20696e76616c6964207369676e6174757265202773272076616c60448201527f75650000000000000000000000000000000000000000000000000000000000006064820152608401610f1b565b6004816004811115613a5757613a5761471a565b1415611d5f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602260248201527f45434453413a20696e76616c6964207369676e6174757265202776272076616c60448201527f75650000000000000000000000000000000000000000000000000000000000006064820152608401610f1b565b600054610100900460ff16613b7c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201527f6e697469616c697a696e670000000000000000000000000000000000000000006064820152608401610f1b565b565b600054610100900460ff16613c15576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201527f6e697469616c697a696e670000000000000000000000000000000000000000006064820152608401610f1b565b815160209283012081519190920120606591909155606655565b600054610100900460ff16613cc6576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201527f6e697469616c697a696e670000000000000000000000000000000000000000006064820152608401610f1b565b507f6e71edae12b1b97f4d1f60370fef10105fa2faae0126114a169c64845d6126c9609a55565b600054610100900460ff16613d84576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201527f6e697469616c697a696e670000000000000000000000000000000000000000006064820152608401610f1b565b8151613d97906036906020850190613f85565b50805161082d906037906020840190613f85565b6060613dba8484600085613dc2565b949350505050565b606082471015613e54576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f60448201527f722063616c6c00000000000000000000000000000000000000000000000000006064820152608401610f1b565b843b613ebc576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006044820152606401610f1b565b6000808673ffffffffffffffffffffffffffffffffffffffff168587604051613ee59190614749565b60006040518083038185875af1925050503d8060008114613f22576040519150601f19603f3d011682016040523d82523d6000602084013e613f27565b606091505b509150915061238882828660608315613f41575081610e4a565b825115613f515782518084602001fd5b816040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610f1b919061404a565b828054613f919061450c565b90600052602060002090601f016020900481019282613fb35760008555613ff9565b82601f10613fcc57805160ff1916838001178555613ff9565b82800160010185558215613ff9579182015b82811115613ff9578251825591602001919060010190613fde565b50614005929150614009565b5090565b5b80821115614005576000815560010161400a565b60005b83811015614039578181015183820152602001614021565b83811115612a395750506000910152565b602081526000825180602084015261406981604085016020870161401e565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169190910160400192915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b600082601f8301126140db57600080fd5b813567ffffffffffffffff808211156140f6576140f661409b565b604051601f83017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0908116603f0116810190828211818310171561413c5761413c61409b565b8160405283815286602085880101111561415557600080fd5b836020870160208301376000602085830101528094505050505092915050565b73ffffffffffffffffffffffffffffffffffffffff81168114611d5f57600080fd5b6000806000606084860312156141ac57600080fd5b833567ffffffffffffffff808211156141c457600080fd5b6141d0878388016140ca565b945060208601359150808211156141e657600080fd5b506141f3868287016140ca565b925050604084013561420481614175565b809150509250925092565b60006020828403121561422157600080fd5b8135610e4a81614175565b6000806040838503121561423f57600080fd5b823561424a81614175565b946020939093013593505050565b60008060006060848603121561426d57600080fd5b833561427881614175565b9250602084013561428881614175565b929592945050506040919091013590565b6000806000606084860312156142ae57600080fd5b83356142b981614175565b925060208401359150604084013561420481614175565b600080604083850312156142e357600080fd5b8235915060208301356142f581614175565b809150509250929050565b60008060006060848603121561431557600080fd5b83359250602084013561432781614175565b9150604084013561420481614175565b60006020828403121561434957600080fd5b5035919050565b803567ffffffffffffffff8116811461436857600080fd5b919050565b8015158114611d5f57600080fd5b600080600080600060a0868803121561439357600080fd5b853561439e81614175565b945060208601359350604086013592506143ba60608701614350565b915060808601356143ca8161436d565b809150509295509295909350565b600080604083850312156143eb57600080fd5b82356143f681614175565b915061440460208401614350565b90509250929050565b6020808252825182820181905260009190848201906040850190845b8181101561445b57835173ffffffffffffffffffffffffffffffffffffffff1683529284019291840191600101614429565b50909695505050505050565b600080600080600080600060e0888a03121561448257600080fd5b873561448d81614175565b9650602088013561449d81614175565b95506040880135945060608801359350608088013560ff811681146144c157600080fd5b9699959850939692959460a0840135945060c09093013592915050565b600080604083850312156144f157600080fd5b82356144fc81614175565b915060208301356142f581614175565b600181811c9082168061452057607f821691505b60208210811415613441577f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b60006020828403121561456c57600080fd5b8151610e4a8161436d565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b6000828210156145b8576145b8614577565b500390565b6000602082840312156145cf57600080fd5b5051919050565b600082198211156145e9576145e9614577565b500190565b600082614624577f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b500490565b6000817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff048311821515161561466157614661614577565b500290565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8214156146c7576146c7614577565b5060010190565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603160045260246000fd5b60006020828403121561470f57600080fd5b8151610e4a81614175565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b6000825161475b81846020870161401e565b919091019291505056fea2646970667358221220103b8d652dd7975983cef70f41cb81056a0bf607243b7332223b4013506c7eb664736f6c634300080c0033", + "numDeployments": 2, + "solcInputHash": "871924e0c138825a2736b76def8fef8d", + "metadata": "{\"compiler\":{\"version\":\"0.8.17+commit.8df45f5f\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[],\"name\":\"AssetStillControlledInReserves\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"BurnAmountExceedsAllowance\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"HourlyLimitExceeded\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidSender\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidToken\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidTreasury\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"NotGovernor\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"NotGovernorOrGuardian\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"NotMinter\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"NotTreasury\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"TooBigAmount\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"TooHighParameterValue\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ZeroAddress\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"spender\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"}],\"name\":\"Approval\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"bridgeToken\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"limit\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"hourlyLimit\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"fee\",\"type\":\"uint64\"},{\"indexed\":false,\"internalType\":\"bool\",\"name\":\"paused\",\"type\":\"bool\"}],\"name\":\"BridgeTokenAdded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"bridgeToken\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"fee\",\"type\":\"uint64\"}],\"name\":\"BridgeTokenFeeUpdated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"bridgeToken\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"hourlyLimit\",\"type\":\"uint256\"}],\"name\":\"BridgeTokenHourlyLimitUpdated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"bridgeToken\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"limit\",\"type\":\"uint256\"}],\"name\":\"BridgeTokenLimitUpdated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"bridgeToken\",\"type\":\"address\"}],\"name\":\"BridgeTokenRemoved\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"bridgeToken\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"bool\",\"name\":\"toggleStatus\",\"type\":\"bool\"}],\"name\":\"BridgeTokenToggled\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"theAddress\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"toggleStatus\",\"type\":\"uint256\"}],\"name\":\"FeeToggled\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"hourlyLimit\",\"type\":\"uint256\"}],\"name\":\"HourlyLimitUpdated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint8\",\"name\":\"version\",\"type\":\"uint8\"}],\"name\":\"Initialized\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"minter\",\"type\":\"address\"}],\"name\":\"MinterToggled\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"Recovered\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"}],\"name\":\"Transfer\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"_treasury\",\"type\":\"address\"}],\"name\":\"TreasuryUpdated\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"BASE_PARAMS\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"DOMAIN_SEPARATOR\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"bridgeToken\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"limit\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"hourlyLimit\",\"type\":\"uint256\"},{\"internalType\":\"uint64\",\"name\":\"fee\",\"type\":\"uint64\"},{\"internalType\":\"bool\",\"name\":\"paused\",\"type\":\"bool\"}],\"name\":\"addBridgeToken\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"minter\",\"type\":\"address\"}],\"name\":\"addMinter\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"allBridgeTokens\",\"outputs\":[{\"internalType\":\"address[]\",\"name\":\"\",\"type\":\"address[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"spender\",\"type\":\"address\"}],\"name\":\"allowance\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"spender\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"approve\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"}],\"name\":\"balanceOf\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"name\":\"bridgeTokensList\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"bridges\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"limit\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"hourlyLimit\",\"type\":\"uint256\"},{\"internalType\":\"uint64\",\"name\":\"fee\",\"type\":\"uint64\"},{\"internalType\":\"bool\",\"name\":\"allowed\",\"type\":\"bool\"},{\"internalType\":\"bool\",\"name\":\"paused\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"burner\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"}],\"name\":\"burnFrom\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"burner\",\"type\":\"address\"}],\"name\":\"burnSelf\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"burnStablecoin\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"chainTotalHourlyLimit\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"name\":\"chainTotalUsage\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"currentTotalUsage\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"bridgeToken\",\"type\":\"address\"}],\"name\":\"currentUsage\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"decimals\",\"outputs\":[{\"internalType\":\"uint8\",\"name\":\"\",\"type\":\"uint8\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"spender\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"subtractedValue\",\"type\":\"uint256\"}],\"name\":\"decreaseAllowance\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"spender\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"addedValue\",\"type\":\"uint256\"}],\"name\":\"increaseAllowance\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"string\",\"name\":\"name_\",\"type\":\"string\"},{\"internalType\":\"string\",\"name\":\"symbol_\",\"type\":\"string\"},{\"internalType\":\"address\",\"name\":\"_treasury\",\"type\":\"address\"}],\"name\":\"initialize\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"isFeeExempt\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"isMinter\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"mint\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"name\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"}],\"name\":\"nonces\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"spender\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"deadline\",\"type\":\"uint256\"},{\"internalType\":\"uint8\",\"name\":\"v\",\"type\":\"uint8\"},{\"internalType\":\"bytes32\",\"name\":\"r\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32\",\"name\":\"s\",\"type\":\"bytes32\"}],\"name\":\"permit\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"tokenAddress\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amountToRecover\",\"type\":\"uint256\"}],\"name\":\"recoverERC20\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"bridgeToken\",\"type\":\"address\"}],\"name\":\"removeBridgeToken\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"minter\",\"type\":\"address\"}],\"name\":\"removeMinter\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"hourlyLimit\",\"type\":\"uint256\"}],\"name\":\"setChainTotalHourlyLimit\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"bridgeToken\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"hourlyLimit\",\"type\":\"uint256\"}],\"name\":\"setHourlyLimit\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"bridgeToken\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"limit\",\"type\":\"uint256\"}],\"name\":\"setLimit\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"bridgeToken\",\"type\":\"address\"},{\"internalType\":\"uint64\",\"name\":\"fee\",\"type\":\"uint64\"}],\"name\":\"setSwapFee\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_treasury\",\"type\":\"address\"}],\"name\":\"setTreasury\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"bridgeToken\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"swapIn\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"bridgeToken\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"swapOut\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"symbol\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"bridgeToken\",\"type\":\"address\"}],\"name\":\"toggleBridge\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"theAddress\",\"type\":\"address\"}],\"name\":\"toggleFeesForAddress\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"totalSupply\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"transfer\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"transferFrom\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"treasury\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"name\":\"usage\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"}],\"devdoc\":{\"author\":\"Angle Labs, Inc.\",\"details\":\"This contract supports bridge tokens having a minting right on the stablecoin (also referred to as the canonical or the native token)\",\"kind\":\"dev\",\"methods\":{\"DOMAIN_SEPARATOR()\":{\"details\":\"See {IERC20Permit-DOMAIN_SEPARATOR}.\"},\"addBridgeToken(address,uint256,uint256,uint64,bool)\":{\"params\":{\"bridgeToken\":\"Bridge token to add: it should be a version of the stablecoin from another bridge\",\"fee\":\"Fee taken upon swapping for or against this token\",\"hourlyLimit\":\"Limit on the hourly volume for this bridge\",\"limit\":\"Limit on the balance of bridge token this contract could hold\",\"paused\":\"Whether swapping for this token should be paused or not\"}},\"addMinter(address)\":{\"details\":\"Zero address checks are performed directly in the `Treasury` contract\",\"params\":{\"minter\":\"Minter address to add\"}},\"allBridgeTokens()\":{\"details\":\"Helpful for UIs\"},\"allowance(address,address)\":{\"details\":\"See {IERC20-allowance}.\"},\"approve(address,uint256)\":{\"details\":\"See {IERC20-approve}. NOTE: If `amount` is the maximum `uint256`, the allowance is not updated on `transferFrom`. This is semantically equivalent to an infinite approval. Requirements: - `spender` cannot be the zero address.\"},\"balanceOf(address)\":{\"details\":\"See {IERC20-balanceOf}.\"},\"burnFrom(uint256,address,address)\":{\"details\":\"This method is to be called by a contract with the minter right after being requested to do so by a `sender` address willing to burn tokens from another `burner` addressThe method checks the allowance between the `sender` and the `burner`\",\"params\":{\"amount\":\"Amount of tokens to burn\",\"burner\":\"Address to burn from\",\"sender\":\"Address which requested the burn from `burner`\"}},\"burnSelf(uint256,address)\":{\"details\":\"This method is to be called by a contract with a minter right on the AgToken after being requested to do so by an address willing to burn tokens from its address\",\"params\":{\"amount\":\"Amount of tokens to burn\",\"burner\":\"Address to burn from\"}},\"burnStablecoin(uint256)\":{\"details\":\"This function can typically be called if there is a settlement mechanism to burn stablecoins\",\"params\":{\"amount\":\"Amount of stablecoins to burn\"}},\"currentTotalUsage()\":{\"details\":\"Helpful for UIs\"},\"currentUsage(address)\":{\"details\":\"Helpful for UIs\",\"params\":{\"bridgeToken\":\"Bridge used to mint\"}},\"decimals()\":{\"details\":\"Returns the number of decimals used to get its user representation. For example, if `decimals` equals `2`, a balance of `505` tokens should be displayed to a user as `5.05` (`505 / 10 ** 2`). Tokens usually opt for a value of 18, imitating the relationship between Ether and Wei. This is the value {ERC20} uses, unless this function is overridden; NOTE: This information is only used for _display_ purposes: it in no way affects any of the arithmetic of the contract, including {IERC20-balanceOf} and {IERC20-transfer}.\"},\"decreaseAllowance(address,uint256)\":{\"details\":\"Atomically decreases the allowance granted to `spender` by the caller. This is an alternative to {approve} that can be used as a mitigation for problems described in {IERC20-approve}. Emits an {Approval} event indicating the updated allowance. Requirements: - `spender` cannot be the zero address. - `spender` must have allowance for the caller of at least `subtractedValue`.\"},\"increaseAllowance(address,uint256)\":{\"details\":\"Atomically increases the allowance granted to `spender` by the caller. This is an alternative to {approve} that can be used as a mitigation for problems described in {IERC20-approve}. Emits an {Approval} event indicating the updated allowance. Requirements: - `spender` cannot be the zero address.\"},\"mint(address,uint256)\":{\"details\":\"The contracts allowed to issue agTokens are the `StableMaster` contract, `VaultManager` contracts associated to this stablecoin as well as the flash loan module (if activated) and potentially contracts whitelisted by governance\",\"params\":{\"account\":\"Address to mint to\",\"amount\":\"Amount to mint\"}},\"name()\":{\"details\":\"Returns the name of the token.\"},\"nonces(address)\":{\"details\":\"See {IERC20Permit-nonces}.\"},\"permit(address,address,uint256,uint256,uint8,bytes32,bytes32)\":{\"details\":\"See {IERC20Permit-permit}.\"},\"recoverERC20(address,address,uint256)\":{\"details\":\"Can be used to withdraw bridge tokens for them to be de-bridged on mainnet\"},\"removeBridgeToken(address)\":{\"params\":{\"bridgeToken\":\"Address of the bridge token to remove support for\"}},\"removeMinter(address)\":{\"details\":\"This function can also be called by a minter wishing to revoke itself\",\"params\":{\"minter\":\"Minter address to remove\"}},\"setTreasury(address)\":{\"params\":{\"_treasury\":\"New treasury address\"}},\"swapIn(address,uint256,address)\":{\"details\":\"Some fees may be taken by the protocol depending on the token used and on the address calling\",\"params\":{\"amount\":\"Amount of bridge tokens to send\",\"bridgeToken\":\"Bridge token to use to mint\",\"to\":\"Address to which the stablecoin should be sent\"},\"returns\":{\"_0\":\"Amount of the canonical stablecoin actually minted\"}},\"swapOut(address,uint256,address)\":{\"details\":\"Some fees may be taken by the protocol depending on the token used and on the address calling\",\"params\":{\"amount\":\"Amount of canonical tokens to burn\",\"bridgeToken\":\"Bridge token required\",\"to\":\"Address to which the bridge token should be sent\"},\"returns\":{\"_0\":\"Amount of bridge tokens actually sent back\"}},\"symbol()\":{\"details\":\"Returns the symbol of the token, usually a shorter version of the name.\"},\"totalSupply()\":{\"details\":\"See {IERC20-totalSupply}.\"},\"transfer(address,uint256)\":{\"details\":\"See {IERC20-transfer}. Requirements: - `to` cannot be the zero address. - the caller must have a balance of at least `amount`.\"},\"transferFrom(address,address,uint256)\":{\"details\":\"See {IERC20-transferFrom}. Emits an {Approval} event indicating the updated allowance. This is not required by the EIP. See the note at the beginning of {ERC20}. NOTE: Does not update the allowance if the current allowance is the maximum `uint256`. Requirements: - `from` and `to` cannot be the zero address. - `from` must have a balance of at least `amount`. - the caller must have allowance for ``from``'s tokens of at least `amount`.\"}},\"title\":\"AgTokenSideChainMultiBridge\",\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{\"BASE_PARAMS()\":{\"notice\":\"Base used for fee computation\"},\"addBridgeToken(address,uint256,uint256,uint64,bool)\":{\"notice\":\"Adds support for a bridge token\"},\"addMinter(address)\":{\"notice\":\"Adds a minter in the contract\"},\"allBridgeTokens()\":{\"notice\":\"Returns the list of all supported bridge tokens\"},\"bridgeTokensList(uint256)\":{\"notice\":\"List of all bridge tokens\"},\"bridges(address)\":{\"notice\":\"Maps a bridge token to data\"},\"burnFrom(uint256,address,address)\":{\"notice\":\"Burns `amount` tokens from a `burner` address after being asked to by `sender`\"},\"burnSelf(uint256,address)\":{\"notice\":\"Burns `amount` tokens from a `burner` address\"},\"burnStablecoin(uint256)\":{\"notice\":\"Allows anyone to burn stablecoins\"},\"chainTotalHourlyLimit()\":{\"notice\":\"Limit to the amount of tokens that can be sent from that chain to another chain\"},\"chainTotalUsage(uint256)\":{\"notice\":\"Usage per hour on that chain. Maps an hourly timestamp to the total volume swapped out on the chain\"},\"currentTotalUsage()\":{\"notice\":\"Returns the current total volume on the chain for the current hour\"},\"currentUsage(address)\":{\"notice\":\"Returns the current volume for a bridge, for the current hour\"},\"initialize(string,string,address)\":{\"notice\":\"Initializes the `AgToken` contract\"},\"isFeeExempt(address)\":{\"notice\":\"Maps an address to whether it is exempt of fees for when it comes to swapping in and out\"},\"isMinter(address)\":{\"notice\":\"Checks whether an address has the right to mint agTokens\"},\"mint(address,uint256)\":{\"notice\":\"Lets the `StableMaster` contract or another whitelisted contract mint agTokens\"},\"recoverERC20(address,address,uint256)\":{\"notice\":\"Recovers any ERC20 token\"},\"removeBridgeToken(address)\":{\"notice\":\"Removes support for a token\"},\"removeMinter(address)\":{\"notice\":\"Removes a minter from the contract\"},\"setChainTotalHourlyLimit(uint256)\":{\"notice\":\"Updates the `chainTotalHourlyLimit` amount\"},\"setHourlyLimit(address,uint256)\":{\"notice\":\"Updates the `hourlyLimit` amount for `bridgeToken`\"},\"setLimit(address,uint256)\":{\"notice\":\"Updates the `limit` amount for `bridgeToken`\"},\"setSwapFee(address,uint64)\":{\"notice\":\"Updates the `fee` value for `bridgeToken`\"},\"setTreasury(address)\":{\"notice\":\"Sets a new treasury contract\"},\"swapIn(address,uint256,address)\":{\"notice\":\"Mints the canonical token from a supported bridge token\"},\"swapOut(address,uint256,address)\":{\"notice\":\"Burns the canonical token in exchange for a bridge token\"},\"toggleBridge(address)\":{\"notice\":\"Pauses or unpauses swapping in and out for a token\"},\"toggleFeesForAddress(address)\":{\"notice\":\"Toggles fees for the address `theAddress`\"},\"treasury()\":{\"notice\":\"Reference to the treasury contract which can grant minting rights\"},\"usage(address,uint256)\":{\"notice\":\"Maps a bridge token to the associated hourly volume\"}},\"notice\":\"Contract for Angle agTokens on other chains than Ethereum mainnet\",\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/agToken/AgTokenSideChainMultiBridge.sol\":\"AgTokenSideChainMultiBridge\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":1000000},\"remappings\":[]},\"sources\":{\"@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.7.0) (proxy/utils/Initializable.sol)\\n\\npragma solidity ^0.8.2;\\n\\nimport \\\"../../utils/AddressUpgradeable.sol\\\";\\n\\n/**\\n * @dev This is a base contract to aid in writing upgradeable contracts, or any kind of contract that will be deployed\\n * behind a proxy. Since proxied contracts do not make use of a constructor, it's common to move constructor logic to an\\n * external initializer function, usually called `initialize`. It then becomes necessary to protect this initializer\\n * function so it can only be called once. The {initializer} modifier provided by this contract will have this effect.\\n *\\n * The initialization functions use a version number. Once a version number is used, it is consumed and cannot be\\n * reused. This mechanism prevents re-execution of each \\\"step\\\" but allows the creation of new initialization steps in\\n * case an upgrade adds a module that needs to be initialized.\\n *\\n * For example:\\n *\\n * [.hljs-theme-light.nopadding]\\n * ```\\n * contract MyToken is ERC20Upgradeable {\\n * function initialize() initializer public {\\n * __ERC20_init(\\\"MyToken\\\", \\\"MTK\\\");\\n * }\\n * }\\n * contract MyTokenV2 is MyToken, ERC20PermitUpgradeable {\\n * function initializeV2() reinitializer(2) public {\\n * __ERC20Permit_init(\\\"MyToken\\\");\\n * }\\n * }\\n * ```\\n *\\n * TIP: To avoid leaving the proxy in an uninitialized state, the initializer function should be called as early as\\n * possible by providing the encoded function call as the `_data` argument to {ERC1967Proxy-constructor}.\\n *\\n * CAUTION: When used with inheritance, manual care must be taken to not invoke a parent initializer twice, or to ensure\\n * that all initializers are idempotent. This is not verified automatically as constructors are by Solidity.\\n *\\n * [CAUTION]\\n * ====\\n * Avoid leaving a contract uninitialized.\\n *\\n * An uninitialized contract can be taken over by an attacker. This applies to both a proxy and its implementation\\n * contract, which may impact the proxy. To prevent the implementation contract from being used, you should invoke\\n * the {_disableInitializers} function in the constructor to automatically lock it when it is deployed:\\n *\\n * [.hljs-theme-light.nopadding]\\n * ```\\n * /// @custom:oz-upgrades-unsafe-allow constructor\\n * constructor() {\\n * _disableInitializers();\\n * }\\n * ```\\n * ====\\n */\\nabstract contract Initializable {\\n /**\\n * @dev Indicates that the contract has been initialized.\\n * @custom:oz-retyped-from bool\\n */\\n uint8 private _initialized;\\n\\n /**\\n * @dev Indicates that the contract is in the process of being initialized.\\n */\\n bool private _initializing;\\n\\n /**\\n * @dev Triggered when the contract has been initialized or reinitialized.\\n */\\n event Initialized(uint8 version);\\n\\n /**\\n * @dev A modifier that defines a protected initializer function that can be invoked at most once. In its scope,\\n * `onlyInitializing` functions can be used to initialize parent contracts. Equivalent to `reinitializer(1)`.\\n */\\n modifier initializer() {\\n bool isTopLevelCall = !_initializing;\\n require(\\n (isTopLevelCall && _initialized < 1) || (!AddressUpgradeable.isContract(address(this)) && _initialized == 1),\\n \\\"Initializable: contract is already initialized\\\"\\n );\\n _initialized = 1;\\n if (isTopLevelCall) {\\n _initializing = true;\\n }\\n _;\\n if (isTopLevelCall) {\\n _initializing = false;\\n emit Initialized(1);\\n }\\n }\\n\\n /**\\n * @dev A modifier that defines a protected reinitializer function that can be invoked at most once, and only if the\\n * contract hasn't been initialized to a greater version before. In its scope, `onlyInitializing` functions can be\\n * used to initialize parent contracts.\\n *\\n * `initializer` is equivalent to `reinitializer(1)`, so a reinitializer may be used after the original\\n * initialization step. This is essential to configure modules that are added through upgrades and that require\\n * initialization.\\n *\\n * Note that versions can jump in increments greater than 1; this implies that if multiple reinitializers coexist in\\n * a contract, executing them in the right order is up to the developer or operator.\\n */\\n modifier reinitializer(uint8 version) {\\n require(!_initializing && _initialized < version, \\\"Initializable: contract is already initialized\\\");\\n _initialized = version;\\n _initializing = true;\\n _;\\n _initializing = false;\\n emit Initialized(version);\\n }\\n\\n /**\\n * @dev Modifier to protect an initialization function so that it can only be invoked by functions with the\\n * {initializer} and {reinitializer} modifiers, directly or indirectly.\\n */\\n modifier onlyInitializing() {\\n require(_initializing, \\\"Initializable: contract is not initializing\\\");\\n _;\\n }\\n\\n /**\\n * @dev Locks the contract, preventing any future reinitialization. This cannot be part of an initializer call.\\n * Calling this in the constructor of a contract will prevent that contract from being initialized or reinitialized\\n * to any version. It is recommended to use this to lock implementation contracts that are designed to be called\\n * through proxies.\\n */\\n function _disableInitializers() internal virtual {\\n require(!_initializing, \\\"Initializable: contract is initializing\\\");\\n if (_initialized < type(uint8).max) {\\n _initialized = type(uint8).max;\\n emit Initialized(type(uint8).max);\\n }\\n }\\n}\\n\",\"keccak256\":\"0x0203dcadc5737d9ef2c211d6fa15d18ebc3b30dfa51903b64870b01a062b0b4e\",\"license\":\"MIT\"},\"@openzeppelin/contracts-upgradeable/token/ERC20/ERC20Upgradeable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.7.0) (token/ERC20/ERC20.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"./IERC20Upgradeable.sol\\\";\\nimport \\\"./extensions/IERC20MetadataUpgradeable.sol\\\";\\nimport \\\"../../utils/ContextUpgradeable.sol\\\";\\nimport \\\"../../proxy/utils/Initializable.sol\\\";\\n\\n/**\\n * @dev Implementation of the {IERC20} interface.\\n *\\n * This implementation is agnostic to the way tokens are created. This means\\n * that a supply mechanism has to be added in a derived contract using {_mint}.\\n * For a generic mechanism see {ERC20PresetMinterPauser}.\\n *\\n * TIP: For a detailed writeup see our guide\\n * https://forum.zeppelin.solutions/t/how-to-implement-erc20-supply-mechanisms/226[How\\n * to implement supply mechanisms].\\n *\\n * We have followed general OpenZeppelin Contracts guidelines: functions revert\\n * instead returning `false` on failure. This behavior is nonetheless\\n * conventional and does not conflict with the expectations of ERC20\\n * applications.\\n *\\n * Additionally, an {Approval} event is emitted on calls to {transferFrom}.\\n * This allows applications to reconstruct the allowance for all accounts just\\n * by listening to said events. Other implementations of the EIP may not emit\\n * these events, as it isn't required by the specification.\\n *\\n * Finally, the non-standard {decreaseAllowance} and {increaseAllowance}\\n * functions have been added to mitigate the well-known issues around setting\\n * allowances. See {IERC20-approve}.\\n */\\ncontract ERC20Upgradeable is Initializable, ContextUpgradeable, IERC20Upgradeable, IERC20MetadataUpgradeable {\\n mapping(address => uint256) private _balances;\\n\\n mapping(address => mapping(address => uint256)) private _allowances;\\n\\n uint256 private _totalSupply;\\n\\n string private _name;\\n string private _symbol;\\n\\n /**\\n * @dev Sets the values for {name} and {symbol}.\\n *\\n * The default value of {decimals} is 18. To select a different value for\\n * {decimals} you should overload it.\\n *\\n * All two of these values are immutable: they can only be set once during\\n * construction.\\n */\\n function __ERC20_init(string memory name_, string memory symbol_) internal onlyInitializing {\\n __ERC20_init_unchained(name_, symbol_);\\n }\\n\\n function __ERC20_init_unchained(string memory name_, string memory symbol_) internal onlyInitializing {\\n _name = name_;\\n _symbol = symbol_;\\n }\\n\\n /**\\n * @dev Returns the name of the token.\\n */\\n function name() public view virtual override returns (string memory) {\\n return _name;\\n }\\n\\n /**\\n * @dev Returns the symbol of the token, usually a shorter version of the\\n * name.\\n */\\n function symbol() public view virtual override returns (string memory) {\\n return _symbol;\\n }\\n\\n /**\\n * @dev Returns the number of decimals used to get its user representation.\\n * For example, if `decimals` equals `2`, a balance of `505` tokens should\\n * be displayed to a user as `5.05` (`505 / 10 ** 2`).\\n *\\n * Tokens usually opt for a value of 18, imitating the relationship between\\n * Ether and Wei. This is the value {ERC20} uses, unless this function is\\n * overridden;\\n *\\n * NOTE: This information is only used for _display_ purposes: it in\\n * no way affects any of the arithmetic of the contract, including\\n * {IERC20-balanceOf} and {IERC20-transfer}.\\n */\\n function decimals() public view virtual override returns (uint8) {\\n return 18;\\n }\\n\\n /**\\n * @dev See {IERC20-totalSupply}.\\n */\\n function totalSupply() public view virtual override returns (uint256) {\\n return _totalSupply;\\n }\\n\\n /**\\n * @dev See {IERC20-balanceOf}.\\n */\\n function balanceOf(address account) public view virtual override returns (uint256) {\\n return _balances[account];\\n }\\n\\n /**\\n * @dev See {IERC20-transfer}.\\n *\\n * Requirements:\\n *\\n * - `to` cannot be the zero address.\\n * - the caller must have a balance of at least `amount`.\\n */\\n function transfer(address to, uint256 amount) public virtual override returns (bool) {\\n address owner = _msgSender();\\n _transfer(owner, to, amount);\\n return true;\\n }\\n\\n /**\\n * @dev See {IERC20-allowance}.\\n */\\n function allowance(address owner, address spender) public view virtual override returns (uint256) {\\n return _allowances[owner][spender];\\n }\\n\\n /**\\n * @dev See {IERC20-approve}.\\n *\\n * NOTE: If `amount` is the maximum `uint256`, the allowance is not updated on\\n * `transferFrom`. This is semantically equivalent to an infinite approval.\\n *\\n * Requirements:\\n *\\n * - `spender` cannot be the zero address.\\n */\\n function approve(address spender, uint256 amount) public virtual override returns (bool) {\\n address owner = _msgSender();\\n _approve(owner, spender, amount);\\n return true;\\n }\\n\\n /**\\n * @dev See {IERC20-transferFrom}.\\n *\\n * Emits an {Approval} event indicating the updated allowance. This is not\\n * required by the EIP. See the note at the beginning of {ERC20}.\\n *\\n * NOTE: Does not update the allowance if the current allowance\\n * is the maximum `uint256`.\\n *\\n * Requirements:\\n *\\n * - `from` and `to` cannot be the zero address.\\n * - `from` must have a balance of at least `amount`.\\n * - the caller must have allowance for ``from``'s tokens of at least\\n * `amount`.\\n */\\n function transferFrom(\\n address from,\\n address to,\\n uint256 amount\\n ) public virtual override returns (bool) {\\n address spender = _msgSender();\\n _spendAllowance(from, spender, amount);\\n _transfer(from, to, amount);\\n return true;\\n }\\n\\n /**\\n * @dev Atomically increases the allowance granted to `spender` by the caller.\\n *\\n * This is an alternative to {approve} that can be used as a mitigation for\\n * problems described in {IERC20-approve}.\\n *\\n * Emits an {Approval} event indicating the updated allowance.\\n *\\n * Requirements:\\n *\\n * - `spender` cannot be the zero address.\\n */\\n function increaseAllowance(address spender, uint256 addedValue) public virtual returns (bool) {\\n address owner = _msgSender();\\n _approve(owner, spender, allowance(owner, spender) + addedValue);\\n return true;\\n }\\n\\n /**\\n * @dev Atomically decreases the allowance granted to `spender` by the caller.\\n *\\n * This is an alternative to {approve} that can be used as a mitigation for\\n * problems described in {IERC20-approve}.\\n *\\n * Emits an {Approval} event indicating the updated allowance.\\n *\\n * Requirements:\\n *\\n * - `spender` cannot be the zero address.\\n * - `spender` must have allowance for the caller of at least\\n * `subtractedValue`.\\n */\\n function decreaseAllowance(address spender, uint256 subtractedValue) public virtual returns (bool) {\\n address owner = _msgSender();\\n uint256 currentAllowance = allowance(owner, spender);\\n require(currentAllowance >= subtractedValue, \\\"ERC20: decreased allowance below zero\\\");\\n unchecked {\\n _approve(owner, spender, currentAllowance - subtractedValue);\\n }\\n\\n return true;\\n }\\n\\n /**\\n * @dev Moves `amount` of tokens from `from` to `to`.\\n *\\n * This internal function is equivalent to {transfer}, and can be used to\\n * e.g. implement automatic token fees, slashing mechanisms, etc.\\n *\\n * Emits a {Transfer} event.\\n *\\n * Requirements:\\n *\\n * - `from` cannot be the zero address.\\n * - `to` cannot be the zero address.\\n * - `from` must have a balance of at least `amount`.\\n */\\n function _transfer(\\n address from,\\n address to,\\n uint256 amount\\n ) internal virtual {\\n require(from != address(0), \\\"ERC20: transfer from the zero address\\\");\\n require(to != address(0), \\\"ERC20: transfer to the zero address\\\");\\n\\n _beforeTokenTransfer(from, to, amount);\\n\\n uint256 fromBalance = _balances[from];\\n require(fromBalance >= amount, \\\"ERC20: transfer amount exceeds balance\\\");\\n unchecked {\\n _balances[from] = fromBalance - amount;\\n }\\n _balances[to] += amount;\\n\\n emit Transfer(from, to, amount);\\n\\n _afterTokenTransfer(from, to, amount);\\n }\\n\\n /** @dev Creates `amount` tokens and assigns them to `account`, increasing\\n * the total supply.\\n *\\n * Emits a {Transfer} event with `from` set to the zero address.\\n *\\n * Requirements:\\n *\\n * - `account` cannot be the zero address.\\n */\\n function _mint(address account, uint256 amount) internal virtual {\\n require(account != address(0), \\\"ERC20: mint to the zero address\\\");\\n\\n _beforeTokenTransfer(address(0), account, amount);\\n\\n _totalSupply += amount;\\n _balances[account] += amount;\\n emit Transfer(address(0), account, amount);\\n\\n _afterTokenTransfer(address(0), account, amount);\\n }\\n\\n /**\\n * @dev Destroys `amount` tokens from `account`, reducing the\\n * total supply.\\n *\\n * Emits a {Transfer} event with `to` set to the zero address.\\n *\\n * Requirements:\\n *\\n * - `account` cannot be the zero address.\\n * - `account` must have at least `amount` tokens.\\n */\\n function _burn(address account, uint256 amount) internal virtual {\\n require(account != address(0), \\\"ERC20: burn from the zero address\\\");\\n\\n _beforeTokenTransfer(account, address(0), amount);\\n\\n uint256 accountBalance = _balances[account];\\n require(accountBalance >= amount, \\\"ERC20: burn amount exceeds balance\\\");\\n unchecked {\\n _balances[account] = accountBalance - amount;\\n }\\n _totalSupply -= amount;\\n\\n emit Transfer(account, address(0), amount);\\n\\n _afterTokenTransfer(account, address(0), amount);\\n }\\n\\n /**\\n * @dev Sets `amount` as the allowance of `spender` over the `owner` s tokens.\\n *\\n * This internal function is equivalent to `approve`, and can be used to\\n * e.g. set automatic allowances for certain subsystems, etc.\\n *\\n * Emits an {Approval} event.\\n *\\n * Requirements:\\n *\\n * - `owner` cannot be the zero address.\\n * - `spender` cannot be the zero address.\\n */\\n function _approve(\\n address owner,\\n address spender,\\n uint256 amount\\n ) internal virtual {\\n require(owner != address(0), \\\"ERC20: approve from the zero address\\\");\\n require(spender != address(0), \\\"ERC20: approve to the zero address\\\");\\n\\n _allowances[owner][spender] = amount;\\n emit Approval(owner, spender, amount);\\n }\\n\\n /**\\n * @dev Updates `owner` s allowance for `spender` based on spent `amount`.\\n *\\n * Does not update the allowance amount in case of infinite allowance.\\n * Revert if not enough allowance is available.\\n *\\n * Might emit an {Approval} event.\\n */\\n function _spendAllowance(\\n address owner,\\n address spender,\\n uint256 amount\\n ) internal virtual {\\n uint256 currentAllowance = allowance(owner, spender);\\n if (currentAllowance != type(uint256).max) {\\n require(currentAllowance >= amount, \\\"ERC20: insufficient allowance\\\");\\n unchecked {\\n _approve(owner, spender, currentAllowance - amount);\\n }\\n }\\n }\\n\\n /**\\n * @dev Hook that is called before any transfer of tokens. This includes\\n * minting and burning.\\n *\\n * Calling conditions:\\n *\\n * - when `from` and `to` are both non-zero, `amount` of ``from``'s tokens\\n * will be transferred to `to`.\\n * - when `from` is zero, `amount` tokens will be minted for `to`.\\n * - when `to` is zero, `amount` of ``from``'s tokens will be burned.\\n * - `from` and `to` are never both zero.\\n *\\n * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].\\n */\\n function _beforeTokenTransfer(\\n address from,\\n address to,\\n uint256 amount\\n ) internal virtual {}\\n\\n /**\\n * @dev Hook that is called after any transfer of tokens. This includes\\n * minting and burning.\\n *\\n * Calling conditions:\\n *\\n * - when `from` and `to` are both non-zero, `amount` of ``from``'s tokens\\n * has been transferred to `to`.\\n * - when `from` is zero, `amount` tokens have been minted for `to`.\\n * - when `to` is zero, `amount` of ``from``'s tokens have been burned.\\n * - `from` and `to` are never both zero.\\n *\\n * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].\\n */\\n function _afterTokenTransfer(\\n address from,\\n address to,\\n uint256 amount\\n ) internal virtual {}\\n\\n /**\\n * @dev This empty reserved space is put in place to allow future versions to add new\\n * variables without shifting down storage in the inheritance chain.\\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\\n */\\n uint256[45] private __gap;\\n}\\n\",\"keccak256\":\"0x7c7ac0bc6c340a7f320524b9a4b4b079ee9da3c51258080d4bab237f329a427c\",\"license\":\"MIT\"},\"@openzeppelin/contracts-upgradeable/token/ERC20/IERC20Upgradeable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.6.0) (token/ERC20/IERC20.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Interface of the ERC20 standard as defined in the EIP.\\n */\\ninterface IERC20Upgradeable {\\n /**\\n * @dev Emitted when `value` tokens are moved from one account (`from`) to\\n * another (`to`).\\n *\\n * Note that `value` may be zero.\\n */\\n event Transfer(address indexed from, address indexed to, uint256 value);\\n\\n /**\\n * @dev Emitted when the allowance of a `spender` for an `owner` is set by\\n * a call to {approve}. `value` is the new allowance.\\n */\\n event Approval(address indexed owner, address indexed spender, uint256 value);\\n\\n /**\\n * @dev Returns the amount of tokens in existence.\\n */\\n function totalSupply() external view returns (uint256);\\n\\n /**\\n * @dev Returns the amount of tokens owned by `account`.\\n */\\n function balanceOf(address account) external view returns (uint256);\\n\\n /**\\n * @dev Moves `amount` tokens from the caller's account to `to`.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * Emits a {Transfer} event.\\n */\\n function transfer(address to, uint256 amount) external returns (bool);\\n\\n /**\\n * @dev Returns the remaining number of tokens that `spender` will be\\n * allowed to spend on behalf of `owner` through {transferFrom}. This is\\n * zero by default.\\n *\\n * This value changes when {approve} or {transferFrom} are called.\\n */\\n function allowance(address owner, address spender) external view returns (uint256);\\n\\n /**\\n * @dev Sets `amount` as the allowance of `spender` over the caller's tokens.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * IMPORTANT: Beware that changing an allowance with this method brings the risk\\n * that someone may use both the old and the new allowance by unfortunate\\n * transaction ordering. One possible solution to mitigate this race\\n * condition is to first reduce the spender's allowance to 0 and set the\\n * desired value afterwards:\\n * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729\\n *\\n * Emits an {Approval} event.\\n */\\n function approve(address spender, uint256 amount) external returns (bool);\\n\\n /**\\n * @dev Moves `amount` tokens from `from` to `to` using the\\n * allowance mechanism. `amount` is then deducted from the caller's\\n * allowance.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * Emits a {Transfer} event.\\n */\\n function transferFrom(\\n address from,\\n address to,\\n uint256 amount\\n ) external returns (bool);\\n}\\n\",\"keccak256\":\"0x4e733d3164f73f461eaf9d8087a7ad1ea180bdc8ba0d3d61b0e1ae16d8e63dff\",\"license\":\"MIT\"},\"@openzeppelin/contracts-upgradeable/token/ERC20/extensions/IERC20MetadataUpgradeable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (token/ERC20/extensions/IERC20Metadata.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../IERC20Upgradeable.sol\\\";\\n\\n/**\\n * @dev Interface for the optional metadata functions from the ERC20 standard.\\n *\\n * _Available since v4.1._\\n */\\ninterface IERC20MetadataUpgradeable is IERC20Upgradeable {\\n /**\\n * @dev Returns the name of the token.\\n */\\n function name() external view returns (string memory);\\n\\n /**\\n * @dev Returns the symbol of the token.\\n */\\n function symbol() external view returns (string memory);\\n\\n /**\\n * @dev Returns the decimals places of the token.\\n */\\n function decimals() external view returns (uint8);\\n}\\n\",\"keccak256\":\"0x605434219ebbe4653f703640f06969faa5a1d78f0bfef878e5ddbb1ca369ceeb\",\"license\":\"MIT\"},\"@openzeppelin/contracts-upgradeable/token/ERC20/extensions/draft-ERC20PermitUpgradeable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.6.0) (token/ERC20/extensions/draft-ERC20Permit.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"./draft-IERC20PermitUpgradeable.sol\\\";\\nimport \\\"../ERC20Upgradeable.sol\\\";\\nimport \\\"../../../utils/cryptography/draft-EIP712Upgradeable.sol\\\";\\nimport \\\"../../../utils/cryptography/ECDSAUpgradeable.sol\\\";\\nimport \\\"../../../utils/CountersUpgradeable.sol\\\";\\nimport \\\"../../../proxy/utils/Initializable.sol\\\";\\n\\n/**\\n * @dev Implementation of the ERC20 Permit extension allowing approvals to be made via signatures, as defined in\\n * https://eips.ethereum.org/EIPS/eip-2612[EIP-2612].\\n *\\n * Adds the {permit} method, which can be used to change an account's ERC20 allowance (see {IERC20-allowance}) by\\n * presenting a message signed by the account. By not relying on `{IERC20-approve}`, the token holder account doesn't\\n * need to send a transaction, and thus is not required to hold Ether at all.\\n *\\n * _Available since v3.4._\\n *\\n * @custom:storage-size 51\\n */\\nabstract contract ERC20PermitUpgradeable is Initializable, ERC20Upgradeable, IERC20PermitUpgradeable, EIP712Upgradeable {\\n using CountersUpgradeable for CountersUpgradeable.Counter;\\n\\n mapping(address => CountersUpgradeable.Counter) private _nonces;\\n\\n // solhint-disable-next-line var-name-mixedcase\\n bytes32 private constant _PERMIT_TYPEHASH =\\n keccak256(\\\"Permit(address owner,address spender,uint256 value,uint256 nonce,uint256 deadline)\\\");\\n /**\\n * @dev In previous versions `_PERMIT_TYPEHASH` was declared as `immutable`.\\n * However, to ensure consistency with the upgradeable transpiler, we will continue\\n * to reserve a slot.\\n * @custom:oz-renamed-from _PERMIT_TYPEHASH\\n */\\n // solhint-disable-next-line var-name-mixedcase\\n bytes32 private _PERMIT_TYPEHASH_DEPRECATED_SLOT;\\n\\n /**\\n * @dev Initializes the {EIP712} domain separator using the `name` parameter, and setting `version` to `\\\"1\\\"`.\\n *\\n * It's a good idea to use the same `name` that is defined as the ERC20 token name.\\n */\\n function __ERC20Permit_init(string memory name) internal onlyInitializing {\\n __EIP712_init_unchained(name, \\\"1\\\");\\n }\\n\\n function __ERC20Permit_init_unchained(string memory) internal onlyInitializing {}\\n\\n /**\\n * @dev See {IERC20Permit-permit}.\\n */\\n function permit(\\n address owner,\\n address spender,\\n uint256 value,\\n uint256 deadline,\\n uint8 v,\\n bytes32 r,\\n bytes32 s\\n ) public virtual override {\\n require(block.timestamp <= deadline, \\\"ERC20Permit: expired deadline\\\");\\n\\n bytes32 structHash = keccak256(abi.encode(_PERMIT_TYPEHASH, owner, spender, value, _useNonce(owner), deadline));\\n\\n bytes32 hash = _hashTypedDataV4(structHash);\\n\\n address signer = ECDSAUpgradeable.recover(hash, v, r, s);\\n require(signer == owner, \\\"ERC20Permit: invalid signature\\\");\\n\\n _approve(owner, spender, value);\\n }\\n\\n /**\\n * @dev See {IERC20Permit-nonces}.\\n */\\n function nonces(address owner) public view virtual override returns (uint256) {\\n return _nonces[owner].current();\\n }\\n\\n /**\\n * @dev See {IERC20Permit-DOMAIN_SEPARATOR}.\\n */\\n // solhint-disable-next-line func-name-mixedcase\\n function DOMAIN_SEPARATOR() external view override returns (bytes32) {\\n return _domainSeparatorV4();\\n }\\n\\n /**\\n * @dev \\\"Consume a nonce\\\": return the current value and increment.\\n *\\n * _Available since v4.1._\\n */\\n function _useNonce(address owner) internal virtual returns (uint256 current) {\\n CountersUpgradeable.Counter storage nonce = _nonces[owner];\\n current = nonce.current();\\n nonce.increment();\\n }\\n\\n /**\\n * @dev This empty reserved space is put in place to allow future versions to add new\\n * variables without shifting down storage in the inheritance chain.\\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\\n */\\n uint256[49] private __gap;\\n}\\n\",\"keccak256\":\"0x564385ebed633694decce3e13d687f3ac7e8eaef64f7a504bfb3f03ad210601f\",\"license\":\"MIT\"},\"@openzeppelin/contracts-upgradeable/token/ERC20/extensions/draft-IERC20PermitUpgradeable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (token/ERC20/extensions/draft-IERC20Permit.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Interface of the ERC20 Permit extension allowing approvals to be made via signatures, as defined in\\n * https://eips.ethereum.org/EIPS/eip-2612[EIP-2612].\\n *\\n * Adds the {permit} method, which can be used to change an account's ERC20 allowance (see {IERC20-allowance}) by\\n * presenting a message signed by the account. By not relying on {IERC20-approve}, the token holder account doesn't\\n * need to send a transaction, and thus is not required to hold Ether at all.\\n */\\ninterface IERC20PermitUpgradeable {\\n /**\\n * @dev Sets `value` as the allowance of `spender` over ``owner``'s tokens,\\n * given ``owner``'s signed approval.\\n *\\n * IMPORTANT: The same issues {IERC20-approve} has related to transaction\\n * ordering also apply here.\\n *\\n * Emits an {Approval} event.\\n *\\n * Requirements:\\n *\\n * - `spender` cannot be the zero address.\\n * - `deadline` must be a timestamp in the future.\\n * - `v`, `r` and `s` must be a valid `secp256k1` signature from `owner`\\n * over the EIP712-formatted function arguments.\\n * - the signature must use ``owner``'s current nonce (see {nonces}).\\n *\\n * For more information on the signature format, see the\\n * https://eips.ethereum.org/EIPS/eip-2612#specification[relevant EIP\\n * section].\\n */\\n function permit(\\n address owner,\\n address spender,\\n uint256 value,\\n uint256 deadline,\\n uint8 v,\\n bytes32 r,\\n bytes32 s\\n ) external;\\n\\n /**\\n * @dev Returns the current nonce for `owner`. This value must be\\n * included whenever a signature is generated for {permit}.\\n *\\n * Every successful call to {permit} increases ``owner``'s nonce by one. This\\n * prevents a signature from being used multiple times.\\n */\\n function nonces(address owner) external view returns (uint256);\\n\\n /**\\n * @dev Returns the domain separator used in the encoding of the signature for {permit}, as defined by {EIP712}.\\n */\\n // solhint-disable-next-line func-name-mixedcase\\n function DOMAIN_SEPARATOR() external view returns (bytes32);\\n}\\n\",\"keccak256\":\"0xcc70d8e2281fb3ff69e8ab242500f10142cd0a7fa8dd9e45882be270d4d09024\",\"license\":\"MIT\"},\"@openzeppelin/contracts-upgradeable/utils/AddressUpgradeable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.7.0) (utils/Address.sol)\\n\\npragma solidity ^0.8.1;\\n\\n/**\\n * @dev Collection of functions related to the address type\\n */\\nlibrary AddressUpgradeable {\\n /**\\n * @dev Returns true if `account` is a contract.\\n *\\n * [IMPORTANT]\\n * ====\\n * It is unsafe to assume that an address for which this function returns\\n * false is an externally-owned account (EOA) and not a contract.\\n *\\n * Among others, `isContract` will return false for the following\\n * types of addresses:\\n *\\n * - an externally-owned account\\n * - a contract in construction\\n * - an address where a contract will be created\\n * - an address where a contract lived, but was destroyed\\n * ====\\n *\\n * [IMPORTANT]\\n * ====\\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\\n *\\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\\n * constructor.\\n * ====\\n */\\n function isContract(address account) internal view returns (bool) {\\n // This method relies on extcodesize/address.code.length, which returns 0\\n // for contracts in construction, since the code is only stored at the end\\n // of the constructor execution.\\n\\n return account.code.length > 0;\\n }\\n\\n /**\\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\\n * `recipient`, forwarding all available gas and reverting on errors.\\n *\\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\\n * imposed by `transfer`, making them unable to receive funds via\\n * `transfer`. {sendValue} removes this limitation.\\n *\\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\\n *\\n * IMPORTANT: because control is transferred to `recipient`, care must be\\n * taken to not create reentrancy vulnerabilities. Consider using\\n * {ReentrancyGuard} or the\\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\\n */\\n function sendValue(address payable recipient, uint256 amount) internal {\\n require(address(this).balance >= amount, \\\"Address: insufficient balance\\\");\\n\\n (bool success, ) = recipient.call{value: amount}(\\\"\\\");\\n require(success, \\\"Address: unable to send value, recipient may have reverted\\\");\\n }\\n\\n /**\\n * @dev Performs a Solidity function call using a low level `call`. A\\n * plain `call` is an unsafe replacement for a function call: use this\\n * function instead.\\n *\\n * If `target` reverts with a revert reason, it is bubbled up by this\\n * function (like regular Solidity function calls).\\n *\\n * Returns the raw returned data. To convert to the expected return value,\\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\\n *\\n * Requirements:\\n *\\n * - `target` must be a contract.\\n * - calling `target` with `data` must not revert.\\n *\\n * _Available since v3.1._\\n */\\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\\n return functionCall(target, data, \\\"Address: low-level call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\\n * `errorMessage` as a fallback revert reason when `target` reverts.\\n *\\n * _Available since v3.1._\\n */\\n function functionCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n return functionCallWithValue(target, data, 0, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but also transferring `value` wei to `target`.\\n *\\n * Requirements:\\n *\\n * - the calling contract must have an ETH balance of at least `value`.\\n * - the called Solidity function must be `payable`.\\n *\\n * _Available since v3.1._\\n */\\n function functionCallWithValue(\\n address target,\\n bytes memory data,\\n uint256 value\\n ) internal returns (bytes memory) {\\n return functionCallWithValue(target, data, value, \\\"Address: low-level call with value failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\\n * with `errorMessage` as a fallback revert reason when `target` reverts.\\n *\\n * _Available since v3.1._\\n */\\n function functionCallWithValue(\\n address target,\\n bytes memory data,\\n uint256 value,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n require(address(this).balance >= value, \\\"Address: insufficient balance for call\\\");\\n require(isContract(target), \\\"Address: call to non-contract\\\");\\n\\n (bool success, bytes memory returndata) = target.call{value: value}(data);\\n return verifyCallResult(success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but performing a static call.\\n *\\n * _Available since v3.3._\\n */\\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\\n return functionStaticCall(target, data, \\\"Address: low-level static call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\\n * but performing a static call.\\n *\\n * _Available since v3.3._\\n */\\n function functionStaticCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal view returns (bytes memory) {\\n require(isContract(target), \\\"Address: static call to non-contract\\\");\\n\\n (bool success, bytes memory returndata) = target.staticcall(data);\\n return verifyCallResult(success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the\\n * revert reason using the provided one.\\n *\\n * _Available since v4.3._\\n */\\n function verifyCallResult(\\n bool success,\\n bytes memory returndata,\\n string memory errorMessage\\n ) internal pure returns (bytes memory) {\\n if (success) {\\n return returndata;\\n } else {\\n // Look for revert reason and bubble it up if present\\n if (returndata.length > 0) {\\n // The easiest way to bubble the revert reason is using memory via assembly\\n /// @solidity memory-safe-assembly\\n assembly {\\n let returndata_size := mload(returndata)\\n revert(add(32, returndata), returndata_size)\\n }\\n } else {\\n revert(errorMessage);\\n }\\n }\\n }\\n}\\n\",\"keccak256\":\"0x611aa3f23e59cfdd1863c536776407b3e33d695152a266fa7cfb34440a29a8a3\",\"license\":\"MIT\"},\"@openzeppelin/contracts-upgradeable/utils/ContextUpgradeable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)\\n\\npragma solidity ^0.8.0;\\nimport \\\"../proxy/utils/Initializable.sol\\\";\\n\\n/**\\n * @dev Provides information about the current execution context, including the\\n * sender of the transaction and its data. While these are generally available\\n * via msg.sender and msg.data, they should not be accessed in such a direct\\n * manner, since when dealing with meta-transactions the account sending and\\n * paying for execution may not be the actual sender (as far as an application\\n * is concerned).\\n *\\n * This contract is only required for intermediate, library-like contracts.\\n */\\nabstract contract ContextUpgradeable is Initializable {\\n function __Context_init() internal onlyInitializing {\\n }\\n\\n function __Context_init_unchained() internal onlyInitializing {\\n }\\n function _msgSender() internal view virtual returns (address) {\\n return msg.sender;\\n }\\n\\n function _msgData() internal view virtual returns (bytes calldata) {\\n return msg.data;\\n }\\n\\n /**\\n * @dev This empty reserved space is put in place to allow future versions to add new\\n * variables without shifting down storage in the inheritance chain.\\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\\n */\\n uint256[50] private __gap;\\n}\\n\",\"keccak256\":\"0x963ea7f0b48b032eef72fe3a7582edf78408d6f834115b9feadd673a4d5bd149\",\"license\":\"MIT\"},\"@openzeppelin/contracts-upgradeable/utils/CountersUpgradeable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (utils/Counters.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @title Counters\\n * @author Matt Condon (@shrugs)\\n * @dev Provides counters that can only be incremented, decremented or reset. This can be used e.g. to track the number\\n * of elements in a mapping, issuing ERC721 ids, or counting request ids.\\n *\\n * Include with `using Counters for Counters.Counter;`\\n */\\nlibrary CountersUpgradeable {\\n struct Counter {\\n // This variable should never be directly accessed by users of the library: interactions must be restricted to\\n // the library's function. As of Solidity v0.5.2, this cannot be enforced, though there is a proposal to add\\n // this feature: see https://github.com/ethereum/solidity/issues/4637\\n uint256 _value; // default: 0\\n }\\n\\n function current(Counter storage counter) internal view returns (uint256) {\\n return counter._value;\\n }\\n\\n function increment(Counter storage counter) internal {\\n unchecked {\\n counter._value += 1;\\n }\\n }\\n\\n function decrement(Counter storage counter) internal {\\n uint256 value = counter._value;\\n require(value > 0, \\\"Counter: decrement overflow\\\");\\n unchecked {\\n counter._value = value - 1;\\n }\\n }\\n\\n function reset(Counter storage counter) internal {\\n counter._value = 0;\\n }\\n}\\n\",\"keccak256\":\"0x798741e231b22b81e2dd2eddaaf8832dee4baf5cd8e2dbaa5c1dd12a1c053c4d\",\"license\":\"MIT\"},\"@openzeppelin/contracts-upgradeable/utils/StringsUpgradeable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.7.0) (utils/Strings.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev String operations.\\n */\\nlibrary StringsUpgradeable {\\n bytes16 private constant _HEX_SYMBOLS = \\\"0123456789abcdef\\\";\\n uint8 private constant _ADDRESS_LENGTH = 20;\\n\\n /**\\n * @dev Converts a `uint256` to its ASCII `string` decimal representation.\\n */\\n function toString(uint256 value) internal pure returns (string memory) {\\n // Inspired by OraclizeAPI's implementation - MIT licence\\n // https://github.com/oraclize/ethereum-api/blob/b42146b063c7d6ee1358846c198246239e9360e8/oraclizeAPI_0.4.25.sol\\n\\n if (value == 0) {\\n return \\\"0\\\";\\n }\\n uint256 temp = value;\\n uint256 digits;\\n while (temp != 0) {\\n digits++;\\n temp /= 10;\\n }\\n bytes memory buffer = new bytes(digits);\\n while (value != 0) {\\n digits -= 1;\\n buffer[digits] = bytes1(uint8(48 + uint256(value % 10)));\\n value /= 10;\\n }\\n return string(buffer);\\n }\\n\\n /**\\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation.\\n */\\n function toHexString(uint256 value) internal pure returns (string memory) {\\n if (value == 0) {\\n return \\\"0x00\\\";\\n }\\n uint256 temp = value;\\n uint256 length = 0;\\n while (temp != 0) {\\n length++;\\n temp >>= 8;\\n }\\n return toHexString(value, length);\\n }\\n\\n /**\\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length.\\n */\\n function toHexString(uint256 value, uint256 length) internal pure returns (string memory) {\\n bytes memory buffer = new bytes(2 * length + 2);\\n buffer[0] = \\\"0\\\";\\n buffer[1] = \\\"x\\\";\\n for (uint256 i = 2 * length + 1; i > 1; --i) {\\n buffer[i] = _HEX_SYMBOLS[value & 0xf];\\n value >>= 4;\\n }\\n require(value == 0, \\\"Strings: hex length insufficient\\\");\\n return string(buffer);\\n }\\n\\n /**\\n * @dev Converts an `address` with fixed length of 20 bytes to its not checksummed ASCII `string` hexadecimal representation.\\n */\\n function toHexString(address addr) internal pure returns (string memory) {\\n return toHexString(uint256(uint160(addr)), _ADDRESS_LENGTH);\\n }\\n}\\n\",\"keccak256\":\"0xea5339a7fff0ed42b45be56a88efdd0b2ddde9fa480dc99fef9a6a4c5b776863\",\"license\":\"MIT\"},\"@openzeppelin/contracts-upgradeable/utils/cryptography/ECDSAUpgradeable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.7.0) (utils/cryptography/ECDSA.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../StringsUpgradeable.sol\\\";\\n\\n/**\\n * @dev Elliptic Curve Digital Signature Algorithm (ECDSA) operations.\\n *\\n * These functions can be used to verify that a message was signed by the holder\\n * of the private keys of a given address.\\n */\\nlibrary ECDSAUpgradeable {\\n enum RecoverError {\\n NoError,\\n InvalidSignature,\\n InvalidSignatureLength,\\n InvalidSignatureS,\\n InvalidSignatureV\\n }\\n\\n function _throwError(RecoverError error) private pure {\\n if (error == RecoverError.NoError) {\\n return; // no error: do nothing\\n } else if (error == RecoverError.InvalidSignature) {\\n revert(\\\"ECDSA: invalid signature\\\");\\n } else if (error == RecoverError.InvalidSignatureLength) {\\n revert(\\\"ECDSA: invalid signature length\\\");\\n } else if (error == RecoverError.InvalidSignatureS) {\\n revert(\\\"ECDSA: invalid signature 's' value\\\");\\n } else if (error == RecoverError.InvalidSignatureV) {\\n revert(\\\"ECDSA: invalid signature 'v' value\\\");\\n }\\n }\\n\\n /**\\n * @dev Returns the address that signed a hashed message (`hash`) with\\n * `signature` or error string. This address can then be used for verification purposes.\\n *\\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\\n * this function rejects them by requiring the `s` value to be in the lower\\n * half order, and the `v` value to be either 27 or 28.\\n *\\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\\n * verification to be secure: it is possible to craft signatures that\\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\\n * this is by receiving a hash of the original message (which may otherwise\\n * be too long), and then calling {toEthSignedMessageHash} on it.\\n *\\n * Documentation for signature generation:\\n * - with https://web3js.readthedocs.io/en/v1.3.4/web3-eth-accounts.html#sign[Web3.js]\\n * - with https://docs.ethers.io/v5/api/signer/#Signer-signMessage[ethers]\\n *\\n * _Available since v4.3._\\n */\\n function tryRecover(bytes32 hash, bytes memory signature) internal pure returns (address, RecoverError) {\\n // Check the signature length\\n // - case 65: r,s,v signature (standard)\\n // - case 64: r,vs signature (cf https://eips.ethereum.org/EIPS/eip-2098) _Available since v4.1._\\n if (signature.length == 65) {\\n bytes32 r;\\n bytes32 s;\\n uint8 v;\\n // ecrecover takes the signature parameters, and the only way to get them\\n // currently is to use assembly.\\n /// @solidity memory-safe-assembly\\n assembly {\\n r := mload(add(signature, 0x20))\\n s := mload(add(signature, 0x40))\\n v := byte(0, mload(add(signature, 0x60)))\\n }\\n return tryRecover(hash, v, r, s);\\n } else if (signature.length == 64) {\\n bytes32 r;\\n bytes32 vs;\\n // ecrecover takes the signature parameters, and the only way to get them\\n // currently is to use assembly.\\n /// @solidity memory-safe-assembly\\n assembly {\\n r := mload(add(signature, 0x20))\\n vs := mload(add(signature, 0x40))\\n }\\n return tryRecover(hash, r, vs);\\n } else {\\n return (address(0), RecoverError.InvalidSignatureLength);\\n }\\n }\\n\\n /**\\n * @dev Returns the address that signed a hashed message (`hash`) with\\n * `signature`. This address can then be used for verification purposes.\\n *\\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\\n * this function rejects them by requiring the `s` value to be in the lower\\n * half order, and the `v` value to be either 27 or 28.\\n *\\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\\n * verification to be secure: it is possible to craft signatures that\\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\\n * this is by receiving a hash of the original message (which may otherwise\\n * be too long), and then calling {toEthSignedMessageHash} on it.\\n */\\n function recover(bytes32 hash, bytes memory signature) internal pure returns (address) {\\n (address recovered, RecoverError error) = tryRecover(hash, signature);\\n _throwError(error);\\n return recovered;\\n }\\n\\n /**\\n * @dev Overload of {ECDSA-tryRecover} that receives the `r` and `vs` short-signature fields separately.\\n *\\n * See https://eips.ethereum.org/EIPS/eip-2098[EIP-2098 short signatures]\\n *\\n * _Available since v4.3._\\n */\\n function tryRecover(\\n bytes32 hash,\\n bytes32 r,\\n bytes32 vs\\n ) internal pure returns (address, RecoverError) {\\n bytes32 s = vs & bytes32(0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff);\\n uint8 v = uint8((uint256(vs) >> 255) + 27);\\n return tryRecover(hash, v, r, s);\\n }\\n\\n /**\\n * @dev Overload of {ECDSA-recover} that receives the `r and `vs` short-signature fields separately.\\n *\\n * _Available since v4.2._\\n */\\n function recover(\\n bytes32 hash,\\n bytes32 r,\\n bytes32 vs\\n ) internal pure returns (address) {\\n (address recovered, RecoverError error) = tryRecover(hash, r, vs);\\n _throwError(error);\\n return recovered;\\n }\\n\\n /**\\n * @dev Overload of {ECDSA-tryRecover} that receives the `v`,\\n * `r` and `s` signature fields separately.\\n *\\n * _Available since v4.3._\\n */\\n function tryRecover(\\n bytes32 hash,\\n uint8 v,\\n bytes32 r,\\n bytes32 s\\n ) internal pure returns (address, RecoverError) {\\n // EIP-2 still allows signature malleability for ecrecover(). Remove this possibility and make the signature\\n // unique. Appendix F in the Ethereum Yellow paper (https://ethereum.github.io/yellowpaper/paper.pdf), defines\\n // the valid range for s in (301): 0 < s < secp256k1n \\u00f7 2 + 1, and for v in (302): v \\u2208 {27, 28}. Most\\n // signatures from current libraries generate a unique signature with an s-value in the lower half order.\\n //\\n // If your library generates malleable signatures, such as s-values in the upper range, calculate a new s-value\\n // with 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141 - s1 and flip v from 27 to 28 or\\n // vice versa. If your library also generates signatures with 0/1 for v instead 27/28, add 27 to v to accept\\n // these malleable signatures as well.\\n if (uint256(s) > 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D576E7357A4501DDFE92F46681B20A0) {\\n return (address(0), RecoverError.InvalidSignatureS);\\n }\\n if (v != 27 && v != 28) {\\n return (address(0), RecoverError.InvalidSignatureV);\\n }\\n\\n // If the signature is valid (and not malleable), return the signer address\\n address signer = ecrecover(hash, v, r, s);\\n if (signer == address(0)) {\\n return (address(0), RecoverError.InvalidSignature);\\n }\\n\\n return (signer, RecoverError.NoError);\\n }\\n\\n /**\\n * @dev Overload of {ECDSA-recover} that receives the `v`,\\n * `r` and `s` signature fields separately.\\n */\\n function recover(\\n bytes32 hash,\\n uint8 v,\\n bytes32 r,\\n bytes32 s\\n ) internal pure returns (address) {\\n (address recovered, RecoverError error) = tryRecover(hash, v, r, s);\\n _throwError(error);\\n return recovered;\\n }\\n\\n /**\\n * @dev Returns an Ethereum Signed Message, created from a `hash`. This\\n * produces hash corresponding to the one signed with the\\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\\n * JSON-RPC method as part of EIP-191.\\n *\\n * See {recover}.\\n */\\n function toEthSignedMessageHash(bytes32 hash) internal pure returns (bytes32) {\\n // 32 is the length in bytes of hash,\\n // enforced by the type signature above\\n return keccak256(abi.encodePacked(\\\"\\\\x19Ethereum Signed Message:\\\\n32\\\", hash));\\n }\\n\\n /**\\n * @dev Returns an Ethereum Signed Message, created from `s`. This\\n * produces hash corresponding to the one signed with the\\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\\n * JSON-RPC method as part of EIP-191.\\n *\\n * See {recover}.\\n */\\n function toEthSignedMessageHash(bytes memory s) internal pure returns (bytes32) {\\n return keccak256(abi.encodePacked(\\\"\\\\x19Ethereum Signed Message:\\\\n\\\", StringsUpgradeable.toString(s.length), s));\\n }\\n\\n /**\\n * @dev Returns an Ethereum Signed Typed Data, created from a\\n * `domainSeparator` and a `structHash`. This produces hash corresponding\\n * to the one signed with the\\n * https://eips.ethereum.org/EIPS/eip-712[`eth_signTypedData`]\\n * JSON-RPC method as part of EIP-712.\\n *\\n * See {recover}.\\n */\\n function toTypedDataHash(bytes32 domainSeparator, bytes32 structHash) internal pure returns (bytes32) {\\n return keccak256(abi.encodePacked(\\\"\\\\x19\\\\x01\\\", domainSeparator, structHash));\\n }\\n}\\n\",\"keccak256\":\"0xe8c62ca00ed2d0a4d9b7e3c4bf7d62c821618b2cdb3c844da91a1193986851bf\",\"license\":\"MIT\"},\"@openzeppelin/contracts-upgradeable/utils/cryptography/draft-EIP712Upgradeable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (utils/cryptography/draft-EIP712.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"./ECDSAUpgradeable.sol\\\";\\nimport \\\"../../proxy/utils/Initializable.sol\\\";\\n\\n/**\\n * @dev https://eips.ethereum.org/EIPS/eip-712[EIP 712] is a standard for hashing and signing of typed structured data.\\n *\\n * The encoding specified in the EIP is very generic, and such a generic implementation in Solidity is not feasible,\\n * thus this contract does not implement the encoding itself. Protocols need to implement the type-specific encoding\\n * they need in their contracts using a combination of `abi.encode` and `keccak256`.\\n *\\n * This contract implements the EIP 712 domain separator ({_domainSeparatorV4}) that is used as part of the encoding\\n * scheme, and the final step of the encoding to obtain the message digest that is then signed via ECDSA\\n * ({_hashTypedDataV4}).\\n *\\n * The implementation of the domain separator was designed to be as efficient as possible while still properly updating\\n * the chain id to protect against replay attacks on an eventual fork of the chain.\\n *\\n * NOTE: This contract implements the version of the encoding known as \\\"v4\\\", as implemented by the JSON RPC method\\n * https://docs.metamask.io/guide/signing-data.html[`eth_signTypedDataV4` in MetaMask].\\n *\\n * _Available since v3.4._\\n *\\n * @custom:storage-size 52\\n */\\nabstract contract EIP712Upgradeable is Initializable {\\n /* solhint-disable var-name-mixedcase */\\n bytes32 private _HASHED_NAME;\\n bytes32 private _HASHED_VERSION;\\n bytes32 private constant _TYPE_HASH = keccak256(\\\"EIP712Domain(string name,string version,uint256 chainId,address verifyingContract)\\\");\\n\\n /* solhint-enable var-name-mixedcase */\\n\\n /**\\n * @dev Initializes the domain separator and parameter caches.\\n *\\n * The meaning of `name` and `version` is specified in\\n * https://eips.ethereum.org/EIPS/eip-712#definition-of-domainseparator[EIP 712]:\\n *\\n * - `name`: the user readable name of the signing domain, i.e. the name of the DApp or the protocol.\\n * - `version`: the current major version of the signing domain.\\n *\\n * NOTE: These parameters cannot be changed except through a xref:learn::upgrading-smart-contracts.adoc[smart\\n * contract upgrade].\\n */\\n function __EIP712_init(string memory name, string memory version) internal onlyInitializing {\\n __EIP712_init_unchained(name, version);\\n }\\n\\n function __EIP712_init_unchained(string memory name, string memory version) internal onlyInitializing {\\n bytes32 hashedName = keccak256(bytes(name));\\n bytes32 hashedVersion = keccak256(bytes(version));\\n _HASHED_NAME = hashedName;\\n _HASHED_VERSION = hashedVersion;\\n }\\n\\n /**\\n * @dev Returns the domain separator for the current chain.\\n */\\n function _domainSeparatorV4() internal view returns (bytes32) {\\n return _buildDomainSeparator(_TYPE_HASH, _EIP712NameHash(), _EIP712VersionHash());\\n }\\n\\n function _buildDomainSeparator(\\n bytes32 typeHash,\\n bytes32 nameHash,\\n bytes32 versionHash\\n ) private view returns (bytes32) {\\n return keccak256(abi.encode(typeHash, nameHash, versionHash, block.chainid, address(this)));\\n }\\n\\n /**\\n * @dev Given an already https://eips.ethereum.org/EIPS/eip-712#definition-of-hashstruct[hashed struct], this\\n * function returns the hash of the fully encoded EIP712 message for this domain.\\n *\\n * This hash can be used together with {ECDSA-recover} to obtain the signer of a message. For example:\\n *\\n * ```solidity\\n * bytes32 digest = _hashTypedDataV4(keccak256(abi.encode(\\n * keccak256(\\\"Mail(address to,string contents)\\\"),\\n * mailTo,\\n * keccak256(bytes(mailContents))\\n * )));\\n * address signer = ECDSA.recover(digest, signature);\\n * ```\\n */\\n function _hashTypedDataV4(bytes32 structHash) internal view virtual returns (bytes32) {\\n return ECDSAUpgradeable.toTypedDataHash(_domainSeparatorV4(), structHash);\\n }\\n\\n /**\\n * @dev The hash of the name parameter for the EIP712 domain.\\n *\\n * NOTE: This function reads from storage by default, but can be redefined to return a constant value if gas costs\\n * are a concern.\\n */\\n function _EIP712NameHash() internal virtual view returns (bytes32) {\\n return _HASHED_NAME;\\n }\\n\\n /**\\n * @dev The hash of the version parameter for the EIP712 domain.\\n *\\n * NOTE: This function reads from storage by default, but can be redefined to return a constant value if gas costs\\n * are a concern.\\n */\\n function _EIP712VersionHash() internal virtual view returns (bytes32) {\\n return _HASHED_VERSION;\\n }\\n\\n /**\\n * @dev This empty reserved space is put in place to allow future versions to add new\\n * variables without shifting down storage in the inheritance chain.\\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\\n */\\n uint256[50] private __gap;\\n}\\n\",\"keccak256\":\"0xaf5a96100f421d61693605349511e43221d3c2e47d4b3efa87af2b936e2567fc\",\"license\":\"MIT\"},\"@openzeppelin/contracts/token/ERC20/IERC20.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.6.0) (token/ERC20/IERC20.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Interface of the ERC20 standard as defined in the EIP.\\n */\\ninterface IERC20 {\\n /**\\n * @dev Emitted when `value` tokens are moved from one account (`from`) to\\n * another (`to`).\\n *\\n * Note that `value` may be zero.\\n */\\n event Transfer(address indexed from, address indexed to, uint256 value);\\n\\n /**\\n * @dev Emitted when the allowance of a `spender` for an `owner` is set by\\n * a call to {approve}. `value` is the new allowance.\\n */\\n event Approval(address indexed owner, address indexed spender, uint256 value);\\n\\n /**\\n * @dev Returns the amount of tokens in existence.\\n */\\n function totalSupply() external view returns (uint256);\\n\\n /**\\n * @dev Returns the amount of tokens owned by `account`.\\n */\\n function balanceOf(address account) external view returns (uint256);\\n\\n /**\\n * @dev Moves `amount` tokens from the caller's account to `to`.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * Emits a {Transfer} event.\\n */\\n function transfer(address to, uint256 amount) external returns (bool);\\n\\n /**\\n * @dev Returns the remaining number of tokens that `spender` will be\\n * allowed to spend on behalf of `owner` through {transferFrom}. This is\\n * zero by default.\\n *\\n * This value changes when {approve} or {transferFrom} are called.\\n */\\n function allowance(address owner, address spender) external view returns (uint256);\\n\\n /**\\n * @dev Sets `amount` as the allowance of `spender` over the caller's tokens.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * IMPORTANT: Beware that changing an allowance with this method brings the risk\\n * that someone may use both the old and the new allowance by unfortunate\\n * transaction ordering. One possible solution to mitigate this race\\n * condition is to first reduce the spender's allowance to 0 and set the\\n * desired value afterwards:\\n * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729\\n *\\n * Emits an {Approval} event.\\n */\\n function approve(address spender, uint256 amount) external returns (bool);\\n\\n /**\\n * @dev Moves `amount` tokens from `from` to `to` using the\\n * allowance mechanism. `amount` is then deducted from the caller's\\n * allowance.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * Emits a {Transfer} event.\\n */\\n function transferFrom(\\n address from,\\n address to,\\n uint256 amount\\n ) external returns (bool);\\n}\\n\",\"keccak256\":\"0x9750c6b834f7b43000631af5cc30001c5f547b3ceb3635488f140f60e897ea6b\",\"license\":\"MIT\"},\"@openzeppelin/contracts/token/ERC20/extensions/draft-IERC20Permit.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (token/ERC20/extensions/draft-IERC20Permit.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Interface of the ERC20 Permit extension allowing approvals to be made via signatures, as defined in\\n * https://eips.ethereum.org/EIPS/eip-2612[EIP-2612].\\n *\\n * Adds the {permit} method, which can be used to change an account's ERC20 allowance (see {IERC20-allowance}) by\\n * presenting a message signed by the account. By not relying on {IERC20-approve}, the token holder account doesn't\\n * need to send a transaction, and thus is not required to hold Ether at all.\\n */\\ninterface IERC20Permit {\\n /**\\n * @dev Sets `value` as the allowance of `spender` over ``owner``'s tokens,\\n * given ``owner``'s signed approval.\\n *\\n * IMPORTANT: The same issues {IERC20-approve} has related to transaction\\n * ordering also apply here.\\n *\\n * Emits an {Approval} event.\\n *\\n * Requirements:\\n *\\n * - `spender` cannot be the zero address.\\n * - `deadline` must be a timestamp in the future.\\n * - `v`, `r` and `s` must be a valid `secp256k1` signature from `owner`\\n * over the EIP712-formatted function arguments.\\n * - the signature must use ``owner``'s current nonce (see {nonces}).\\n *\\n * For more information on the signature format, see the\\n * https://eips.ethereum.org/EIPS/eip-2612#specification[relevant EIP\\n * section].\\n */\\n function permit(\\n address owner,\\n address spender,\\n uint256 value,\\n uint256 deadline,\\n uint8 v,\\n bytes32 r,\\n bytes32 s\\n ) external;\\n\\n /**\\n * @dev Returns the current nonce for `owner`. This value must be\\n * included whenever a signature is generated for {permit}.\\n *\\n * Every successful call to {permit} increases ``owner``'s nonce by one. This\\n * prevents a signature from being used multiple times.\\n */\\n function nonces(address owner) external view returns (uint256);\\n\\n /**\\n * @dev Returns the domain separator used in the encoding of the signature for {permit}, as defined by {EIP712}.\\n */\\n // solhint-disable-next-line func-name-mixedcase\\n function DOMAIN_SEPARATOR() external view returns (bytes32);\\n}\\n\",\"keccak256\":\"0xf41ca991f30855bf80ffd11e9347856a517b977f0a6c2d52e6421a99b7840329\",\"license\":\"MIT\"},\"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.7.0) (token/ERC20/utils/SafeERC20.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../IERC20.sol\\\";\\nimport \\\"../extensions/draft-IERC20Permit.sol\\\";\\nimport \\\"../../../utils/Address.sol\\\";\\n\\n/**\\n * @title SafeERC20\\n * @dev Wrappers around ERC20 operations that throw on failure (when the token\\n * contract returns false). Tokens that return no value (and instead revert or\\n * throw on failure) are also supported, non-reverting calls are assumed to be\\n * successful.\\n * To use this library you can add a `using SafeERC20 for IERC20;` statement to your contract,\\n * which allows you to call the safe operations as `token.safeTransfer(...)`, etc.\\n */\\nlibrary SafeERC20 {\\n using Address for address;\\n\\n function safeTransfer(\\n IERC20 token,\\n address to,\\n uint256 value\\n ) internal {\\n _callOptionalReturn(token, abi.encodeWithSelector(token.transfer.selector, to, value));\\n }\\n\\n function safeTransferFrom(\\n IERC20 token,\\n address from,\\n address to,\\n uint256 value\\n ) internal {\\n _callOptionalReturn(token, abi.encodeWithSelector(token.transferFrom.selector, from, to, value));\\n }\\n\\n /**\\n * @dev Deprecated. This function has issues similar to the ones found in\\n * {IERC20-approve}, and its usage is discouraged.\\n *\\n * Whenever possible, use {safeIncreaseAllowance} and\\n * {safeDecreaseAllowance} instead.\\n */\\n function safeApprove(\\n IERC20 token,\\n address spender,\\n uint256 value\\n ) internal {\\n // safeApprove should only be called when setting an initial allowance,\\n // or when resetting it to zero. To increase and decrease it, use\\n // 'safeIncreaseAllowance' and 'safeDecreaseAllowance'\\n require(\\n (value == 0) || (token.allowance(address(this), spender) == 0),\\n \\\"SafeERC20: approve from non-zero to non-zero allowance\\\"\\n );\\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, value));\\n }\\n\\n function safeIncreaseAllowance(\\n IERC20 token,\\n address spender,\\n uint256 value\\n ) internal {\\n uint256 newAllowance = token.allowance(address(this), spender) + value;\\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));\\n }\\n\\n function safeDecreaseAllowance(\\n IERC20 token,\\n address spender,\\n uint256 value\\n ) internal {\\n unchecked {\\n uint256 oldAllowance = token.allowance(address(this), spender);\\n require(oldAllowance >= value, \\\"SafeERC20: decreased allowance below zero\\\");\\n uint256 newAllowance = oldAllowance - value;\\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));\\n }\\n }\\n\\n function safePermit(\\n IERC20Permit token,\\n address owner,\\n address spender,\\n uint256 value,\\n uint256 deadline,\\n uint8 v,\\n bytes32 r,\\n bytes32 s\\n ) internal {\\n uint256 nonceBefore = token.nonces(owner);\\n token.permit(owner, spender, value, deadline, v, r, s);\\n uint256 nonceAfter = token.nonces(owner);\\n require(nonceAfter == nonceBefore + 1, \\\"SafeERC20: permit did not succeed\\\");\\n }\\n\\n /**\\n * @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement\\n * on the return value: the return value is optional (but if data is returned, it must not be false).\\n * @param token The token targeted by the call.\\n * @param data The call data (encoded using abi.encode or one of its variants).\\n */\\n function _callOptionalReturn(IERC20 token, bytes memory data) private {\\n // We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since\\n // we're implementing it ourselves. We use {Address.functionCall} to perform this call, which verifies that\\n // the target address contains contract code and also asserts for success in the low-level call.\\n\\n bytes memory returndata = address(token).functionCall(data, \\\"SafeERC20: low-level call failed\\\");\\n if (returndata.length > 0) {\\n // Return data is optional\\n require(abi.decode(returndata, (bool)), \\\"SafeERC20: ERC20 operation did not succeed\\\");\\n }\\n }\\n}\\n\",\"keccak256\":\"0x032807210d1d7d218963d7355d62e021a84bf1b3339f4f50be2f63b53cccaf29\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/Address.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.7.0) (utils/Address.sol)\\n\\npragma solidity ^0.8.1;\\n\\n/**\\n * @dev Collection of functions related to the address type\\n */\\nlibrary Address {\\n /**\\n * @dev Returns true if `account` is a contract.\\n *\\n * [IMPORTANT]\\n * ====\\n * It is unsafe to assume that an address for which this function returns\\n * false is an externally-owned account (EOA) and not a contract.\\n *\\n * Among others, `isContract` will return false for the following\\n * types of addresses:\\n *\\n * - an externally-owned account\\n * - a contract in construction\\n * - an address where a contract will be created\\n * - an address where a contract lived, but was destroyed\\n * ====\\n *\\n * [IMPORTANT]\\n * ====\\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\\n *\\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\\n * constructor.\\n * ====\\n */\\n function isContract(address account) internal view returns (bool) {\\n // This method relies on extcodesize/address.code.length, which returns 0\\n // for contracts in construction, since the code is only stored at the end\\n // of the constructor execution.\\n\\n return account.code.length > 0;\\n }\\n\\n /**\\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\\n * `recipient`, forwarding all available gas and reverting on errors.\\n *\\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\\n * imposed by `transfer`, making them unable to receive funds via\\n * `transfer`. {sendValue} removes this limitation.\\n *\\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\\n *\\n * IMPORTANT: because control is transferred to `recipient`, care must be\\n * taken to not create reentrancy vulnerabilities. Consider using\\n * {ReentrancyGuard} or the\\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\\n */\\n function sendValue(address payable recipient, uint256 amount) internal {\\n require(address(this).balance >= amount, \\\"Address: insufficient balance\\\");\\n\\n (bool success, ) = recipient.call{value: amount}(\\\"\\\");\\n require(success, \\\"Address: unable to send value, recipient may have reverted\\\");\\n }\\n\\n /**\\n * @dev Performs a Solidity function call using a low level `call`. A\\n * plain `call` is an unsafe replacement for a function call: use this\\n * function instead.\\n *\\n * If `target` reverts with a revert reason, it is bubbled up by this\\n * function (like regular Solidity function calls).\\n *\\n * Returns the raw returned data. To convert to the expected return value,\\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\\n *\\n * Requirements:\\n *\\n * - `target` must be a contract.\\n * - calling `target` with `data` must not revert.\\n *\\n * _Available since v3.1._\\n */\\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\\n return functionCall(target, data, \\\"Address: low-level call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\\n * `errorMessage` as a fallback revert reason when `target` reverts.\\n *\\n * _Available since v3.1._\\n */\\n function functionCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n return functionCallWithValue(target, data, 0, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but also transferring `value` wei to `target`.\\n *\\n * Requirements:\\n *\\n * - the calling contract must have an ETH balance of at least `value`.\\n * - the called Solidity function must be `payable`.\\n *\\n * _Available since v3.1._\\n */\\n function functionCallWithValue(\\n address target,\\n bytes memory data,\\n uint256 value\\n ) internal returns (bytes memory) {\\n return functionCallWithValue(target, data, value, \\\"Address: low-level call with value failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\\n * with `errorMessage` as a fallback revert reason when `target` reverts.\\n *\\n * _Available since v3.1._\\n */\\n function functionCallWithValue(\\n address target,\\n bytes memory data,\\n uint256 value,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n require(address(this).balance >= value, \\\"Address: insufficient balance for call\\\");\\n require(isContract(target), \\\"Address: call to non-contract\\\");\\n\\n (bool success, bytes memory returndata) = target.call{value: value}(data);\\n return verifyCallResult(success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but performing a static call.\\n *\\n * _Available since v3.3._\\n */\\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\\n return functionStaticCall(target, data, \\\"Address: low-level static call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\\n * but performing a static call.\\n *\\n * _Available since v3.3._\\n */\\n function functionStaticCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal view returns (bytes memory) {\\n require(isContract(target), \\\"Address: static call to non-contract\\\");\\n\\n (bool success, bytes memory returndata) = target.staticcall(data);\\n return verifyCallResult(success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but performing a delegate call.\\n *\\n * _Available since v3.4._\\n */\\n function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {\\n return functionDelegateCall(target, data, \\\"Address: low-level delegate call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\\n * but performing a delegate call.\\n *\\n * _Available since v3.4._\\n */\\n function functionDelegateCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n require(isContract(target), \\\"Address: delegate call to non-contract\\\");\\n\\n (bool success, bytes memory returndata) = target.delegatecall(data);\\n return verifyCallResult(success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the\\n * revert reason using the provided one.\\n *\\n * _Available since v4.3._\\n */\\n function verifyCallResult(\\n bool success,\\n bytes memory returndata,\\n string memory errorMessage\\n ) internal pure returns (bytes memory) {\\n if (success) {\\n return returndata;\\n } else {\\n // Look for revert reason and bubble it up if present\\n if (returndata.length > 0) {\\n // The easiest way to bubble the revert reason is using memory via assembly\\n /// @solidity memory-safe-assembly\\n assembly {\\n let returndata_size := mload(returndata)\\n revert(add(32, returndata), returndata_size)\\n }\\n } else {\\n revert(errorMessage);\\n }\\n }\\n }\\n}\\n\",\"keccak256\":\"0xd6153ce99bcdcce22b124f755e72553295be6abcd63804cfdffceb188b8bef10\",\"license\":\"MIT\"},\"contracts/agToken/AgToken.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-3.0\\n\\npragma solidity ^0.8.12;\\n\\n/*\\n * \\u2588 \\n ***** \\u2593\\u2593\\u2593 \\n * \\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593 \\n * ///. \\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593 \\n ***** //////// \\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593 \\n * ///////////// \\u2593\\u2593\\u2593 \\n \\u2593\\u2593 ////////////////// \\u2588 \\u2593\\u2593 \\n \\u2593\\u2593 \\u2593\\u2593 /////////////////////// \\u2593\\u2593 \\u2593\\u2593 \\n \\u2593\\u2593 \\u2593\\u2593 //////////////////////////// \\u2593\\u2593 \\u2593\\u2593 \\n \\u2593\\u2593 \\u2593\\u2593 /////////\\u2593\\u2593\\u2593///////\\u2593\\u2593\\u2593///////// \\u2593\\u2593 \\u2593\\u2593 \\n \\u2593\\u2593 ,////////////////////////////////////// \\u2593\\u2593 \\u2593\\u2593 \\n \\u2593\\u2593 ////////////////////////////////////////// \\u2593\\u2593 \\n \\u2593\\u2593 //////////////////////\\u2593\\u2593\\u2593\\u2593///////////////////// \\n ,//////////////////////////////////////////////////// \\n .////////////////////////////////////////////////////////// \\n .//////////////////////////\\u2588\\u2588.,//////////////////////////\\u2588 \\n .//////////////////////\\u2588\\u2588\\u2588\\u2588..,./////////////////////\\u2588\\u2588 \\n ...////////////////\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588.....,.////////////////\\u2588\\u2588\\u2588 \\n ,.,////////////\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588 ........,///////////\\u2588\\u2588\\u2588\\u2588 \\n .,.,//////\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588 ,.......///////\\u2588\\u2588\\u2588\\u2588 \\n ,..//\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588 ........./\\u2588\\u2588\\u2588\\u2588 \\n ..,\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588 .....,\\u2588\\u2588\\u2588 \\n .\\u2588\\u2588 ,.,\\u2588 \\n \\n \\n \\n \\u2593\\u2593 \\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593 \\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593 \\u2593\\u2593 \\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593 \\n \\u2593\\u2593\\u2593\\u2593\\u2593\\u2593 \\u2593\\u2593\\u2593 \\u2593\\u2593\\u2593 \\u2593\\u2593\\u2593 \\u2593\\u2593 \\u2593\\u2593 \\u2593\\u2593\\u2593\\u2593 \\n \\u2593\\u2593\\u2593 \\u2593\\u2593\\u2593 \\u2593\\u2593\\u2593 \\u2593\\u2593\\u2593 \\u2593\\u2593\\u2593 \\u2593\\u2593\\u2593 \\u2593\\u2593 \\u2593\\u2593\\u2593\\u2593\\u2593 \\n \\u2593\\u2593\\u2593 \\u2593\\u2593 \\u2593\\u2593\\u2593 \\u2593\\u2593\\u2593 \\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593 \\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593 \\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593 \\n*/\\n\\nimport \\\"../interfaces/IAgToken.sol\\\";\\nimport \\\"../interfaces/ITreasury.sol\\\";\\nimport \\\"@openzeppelin/contracts-upgradeable/token/ERC20/extensions/draft-ERC20PermitUpgradeable.sol\\\";\\n\\n/// @title AgToken\\n/// @author Angle Labs, Inc.\\n/// @notice Base contract for Angle agTokens on Ethereum and on other chains\\n/// @dev By default, agTokens are ERC-20 tokens with 18 decimals\\ncontract AgToken is IAgToken, ERC20PermitUpgradeable {\\n // =========================== PARAMETERS / VARIABLES ==========================\\n\\n /// @inheritdoc IAgToken\\n mapping(address => bool) public isMinter;\\n /// @notice Reference to the treasury contract which can grant minting rights\\n address public treasury;\\n\\n // =================================== EVENTS ==================================\\n\\n event TreasuryUpdated(address indexed _treasury);\\n event MinterToggled(address indexed minter);\\n\\n // =================================== ERRORS ==================================\\n\\n error BurnAmountExceedsAllowance();\\n error InvalidSender();\\n error InvalidTreasury();\\n error NotMinter();\\n error NotTreasury();\\n\\n // ================================ CONSTRUCTOR ================================\\n\\n /// @custom:oz-upgrades-unsafe-allow constructor\\n constructor() initializer {}\\n\\n /// @notice Initializes the `AgToken` contract\\n function initialize(string memory name_, string memory symbol_, address _treasury) external {\\n _initialize(name_, symbol_, _treasury);\\n }\\n\\n /// @notice Initializes the contract\\n function _initialize(string memory name_, string memory symbol_, address _treasury) internal virtual initializer {\\n if (address(ITreasury(_treasury).stablecoin()) != address(this)) revert InvalidTreasury();\\n __ERC20Permit_init(name_);\\n __ERC20_init(name_, symbol_);\\n treasury = _treasury;\\n emit TreasuryUpdated(_treasury);\\n }\\n\\n // ================================= MODIFIERS =================================\\n\\n /// @notice Checks to see if it is the `Treasury` calling this contract\\n modifier onlyTreasury() {\\n if (msg.sender != treasury) revert NotTreasury();\\n _;\\n }\\n\\n /// @notice Checks whether the sender has the minting right\\n modifier onlyMinter() {\\n if (!isMinter[msg.sender]) revert NotMinter();\\n _;\\n }\\n\\n // ============================= EXTERNAL FUNCTION =============================\\n\\n /// @notice Allows anyone to burn stablecoins\\n /// @param amount Amount of stablecoins to burn\\n /// @dev This function can typically be called if there is a settlement mechanism to burn stablecoins\\n function burnStablecoin(uint256 amount) external {\\n _burn(msg.sender, amount);\\n }\\n\\n // ========================= MINTER ROLE ONLY FUNCTIONS ========================\\n\\n /// @inheritdoc IAgToken\\n function burnSelf(uint256 amount, address burner) external onlyMinter {\\n _burn(burner, amount);\\n }\\n\\n /// @inheritdoc IAgToken\\n function burnFrom(uint256 amount, address burner, address sender) external onlyMinter {\\n if (burner != sender) {\\n uint256 currentAllowance = allowance(burner, sender);\\n if (currentAllowance < amount) revert BurnAmountExceedsAllowance();\\n _approve(burner, sender, currentAllowance - amount);\\n }\\n _burn(burner, amount);\\n }\\n\\n /// @inheritdoc IAgToken\\n function mint(address account, uint256 amount) external onlyMinter {\\n _mint(account, amount);\\n }\\n\\n // ========================== GOVERNANCE ONLY FUNCTIONS ==========================\\n\\n /// @inheritdoc IAgToken\\n function addMinter(address minter) external onlyTreasury {\\n isMinter[minter] = true;\\n emit MinterToggled(minter);\\n }\\n\\n /// @inheritdoc IAgToken\\n function removeMinter(address minter) external {\\n if (msg.sender != address(treasury) && msg.sender != minter) revert InvalidSender();\\n isMinter[minter] = false;\\n emit MinterToggled(minter);\\n }\\n\\n /// @inheritdoc IAgToken\\n function setTreasury(address _treasury) external virtual onlyTreasury {\\n treasury = _treasury;\\n emit TreasuryUpdated(_treasury);\\n }\\n}\\n\",\"keccak256\":\"0x671d54d7840179050e859cf09662fe0e2c34cfaf5ec3782148d6c29e77c54d17\",\"license\":\"GPL-3.0\"},\"contracts/agToken/AgTokenSideChainMultiBridge.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-3.0\\n\\npragma solidity ^0.8.12;\\n\\nimport \\\"./AgToken.sol\\\";\\nimport \\\"@openzeppelin/contracts/token/ERC20/IERC20.sol\\\";\\nimport \\\"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\\\";\\n\\n/// @title AgTokenSideChainMultiBridge\\n/// @author Angle Labs, Inc.\\n/// @notice Contract for Angle agTokens on other chains than Ethereum mainnet\\n/// @dev This contract supports bridge tokens having a minting right on the stablecoin (also referred to as the canonical\\n/// or the native token)\\ncontract AgTokenSideChainMultiBridge is AgToken {\\n using SafeERC20 for IERC20;\\n\\n /// @notice Base used for fee computation\\n uint256 public constant BASE_PARAMS = 1e9;\\n\\n // =============================== BRIDGING DATA ===============================\\n\\n /// @notice Struct with some data about a specific bridge token\\n struct BridgeDetails {\\n // Limit on the balance of bridge token held by the contract: it is designed\\n // to reduce the exposure of the system to hacks\\n uint256 limit;\\n // Limit on the hourly volume of token minted through this bridge\\n // Technically the limit over a rolling hour is hourlyLimit x2 as hourly limit\\n // is enforced only between x:00 and x+1:00\\n uint256 hourlyLimit;\\n // Fee taken for swapping in and out the token\\n uint64 fee;\\n // Whether the associated token is allowed or not\\n bool allowed;\\n // Whether swapping in and out from the associated token is paused or not\\n bool paused;\\n }\\n\\n /// @notice Maps a bridge token to data\\n mapping(address => BridgeDetails) public bridges;\\n /// @notice List of all bridge tokens\\n address[] public bridgeTokensList;\\n /// @notice Maps a bridge token to the associated hourly volume\\n mapping(address => mapping(uint256 => uint256)) public usage;\\n /// @notice Maps an address to whether it is exempt of fees for when it comes to swapping in and out\\n mapping(address => uint256) public isFeeExempt;\\n /// @notice Limit to the amount of tokens that can be sent from that chain to another chain\\n uint256 public chainTotalHourlyLimit;\\n /// @notice Usage per hour on that chain. Maps an hourly timestamp to the total volume swapped out on the chain\\n mapping(uint256 => uint256) public chainTotalUsage;\\n\\n // =================================== EVENTS ==================================\\n\\n event BridgeTokenAdded(address indexed bridgeToken, uint256 limit, uint256 hourlyLimit, uint64 fee, bool paused);\\n event BridgeTokenToggled(address indexed bridgeToken, bool toggleStatus);\\n event BridgeTokenRemoved(address indexed bridgeToken);\\n event BridgeTokenFeeUpdated(address indexed bridgeToken, uint64 fee);\\n event BridgeTokenLimitUpdated(address indexed bridgeToken, uint256 limit);\\n event BridgeTokenHourlyLimitUpdated(address indexed bridgeToken, uint256 hourlyLimit);\\n event HourlyLimitUpdated(uint256 hourlyLimit);\\n event Recovered(address indexed token, address indexed to, uint256 amount);\\n event FeeToggled(address indexed theAddress, uint256 toggleStatus);\\n\\n // =================================== ERRORS ==================================\\n\\n error AssetStillControlledInReserves();\\n error HourlyLimitExceeded();\\n error InvalidToken();\\n error NotGovernor();\\n error NotGovernorOrGuardian();\\n error TooBigAmount();\\n error TooHighParameterValue();\\n error ZeroAddress();\\n\\n // ================================= MODIFIERS =================================\\n\\n /// @notice Checks whether the `msg.sender` has the governor role or not\\n modifier onlyGovernor() {\\n if (!ITreasury(treasury).isGovernor(msg.sender)) revert NotGovernor();\\n _;\\n }\\n\\n /// @notice Checks whether the `msg.sender` has the governor role or the guardian role\\n modifier onlyGovernorOrGuardian() {\\n if (!ITreasury(treasury).isGovernorOrGuardian(msg.sender)) revert NotGovernorOrGuardian();\\n _;\\n }\\n\\n // ===================== EXTERNAL PERMISSIONLESS FUNCTIONS =====================\\n\\n /// @notice Returns the list of all supported bridge tokens\\n /// @dev Helpful for UIs\\n function allBridgeTokens() external view returns (address[] memory) {\\n return bridgeTokensList;\\n }\\n\\n /// @notice Returns the current volume for a bridge, for the current hour\\n /// @param bridgeToken Bridge used to mint\\n /// @dev Helpful for UIs\\n function currentUsage(address bridgeToken) external view returns (uint256) {\\n return usage[bridgeToken][block.timestamp / 3600];\\n }\\n\\n /// @notice Returns the current total volume on the chain for the current hour\\n /// @dev Helpful for UIs\\n function currentTotalUsage() external view returns (uint256) {\\n return chainTotalUsage[block.timestamp / 3600];\\n }\\n\\n /// @notice Mints the canonical token from a supported bridge token\\n /// @param bridgeToken Bridge token to use to mint\\n /// @param amount Amount of bridge tokens to send\\n /// @param to Address to which the stablecoin should be sent\\n /// @return Amount of the canonical stablecoin actually minted\\n /// @dev Some fees may be taken by the protocol depending on the token used and on the address calling\\n function swapIn(address bridgeToken, uint256 amount, address to) external returns (uint256) {\\n BridgeDetails memory bridgeDetails = bridges[bridgeToken];\\n if (!bridgeDetails.allowed || bridgeDetails.paused) revert InvalidToken();\\n uint256 balance = IERC20(bridgeToken).balanceOf(address(this));\\n if (balance + amount > bridgeDetails.limit) {\\n // In case someone maliciously sends tokens to this contract\\n // Or the limit changes\\n if (bridgeDetails.limit > balance) amount = bridgeDetails.limit - balance;\\n else {\\n amount = 0;\\n }\\n }\\n\\n // Checking requirement on the hourly volume\\n uint256 hour = block.timestamp / 3600;\\n uint256 hourlyUsage = usage[bridgeToken][hour];\\n if (hourlyUsage + amount > bridgeDetails.hourlyLimit) {\\n // Edge case when the hourly limit changes\\n amount = bridgeDetails.hourlyLimit > hourlyUsage ? bridgeDetails.hourlyLimit - hourlyUsage : 0;\\n }\\n usage[bridgeToken][hour] = hourlyUsage + amount;\\n\\n IERC20(bridgeToken).safeTransferFrom(msg.sender, address(this), amount);\\n uint256 canonicalOut = amount;\\n // Computing fees\\n if (isFeeExempt[msg.sender] == 0) {\\n canonicalOut -= (canonicalOut * bridgeDetails.fee) / BASE_PARAMS;\\n }\\n _mint(to, canonicalOut);\\n return canonicalOut;\\n }\\n\\n /// @notice Burns the canonical token in exchange for a bridge token\\n /// @param bridgeToken Bridge token required\\n /// @param amount Amount of canonical tokens to burn\\n /// @param to Address to which the bridge token should be sent\\n /// @return Amount of bridge tokens actually sent back\\n /// @dev Some fees may be taken by the protocol depending on the token used and on the address calling\\n function swapOut(address bridgeToken, uint256 amount, address to) external returns (uint256) {\\n BridgeDetails memory bridgeDetails = bridges[bridgeToken];\\n if (!bridgeDetails.allowed || bridgeDetails.paused) revert InvalidToken();\\n\\n uint256 hour = block.timestamp / 3600;\\n uint256 hourlyUsage = chainTotalUsage[hour] + amount;\\n // If the amount being swapped out exceeds the limit, we revert\\n // We don't want to change the amount being swapped out.\\n // The user can decide to send another tx with the correct amount to reach the limit\\n if (hourlyUsage > chainTotalHourlyLimit) revert HourlyLimitExceeded();\\n chainTotalUsage[hour] = hourlyUsage;\\n\\n _burn(msg.sender, amount);\\n uint256 bridgeOut = amount;\\n if (isFeeExempt[msg.sender] == 0) {\\n bridgeOut -= (bridgeOut * bridgeDetails.fee) / BASE_PARAMS;\\n }\\n IERC20(bridgeToken).safeTransfer(to, bridgeOut);\\n return bridgeOut;\\n }\\n\\n // ============================ GOVERNANCE FUNCTIONS ===========================\\n\\n /// @notice Adds support for a bridge token\\n /// @param bridgeToken Bridge token to add: it should be a version of the stablecoin from another bridge\\n /// @param limit Limit on the balance of bridge token this contract could hold\\n /// @param hourlyLimit Limit on the hourly volume for this bridge\\n /// @param paused Whether swapping for this token should be paused or not\\n /// @param fee Fee taken upon swapping for or against this token\\n function addBridgeToken(\\n address bridgeToken,\\n uint256 limit,\\n uint256 hourlyLimit,\\n uint64 fee,\\n bool paused\\n ) external onlyGovernor {\\n if (bridges[bridgeToken].allowed || bridgeToken == address(0)) revert InvalidToken();\\n if (fee > BASE_PARAMS) revert TooHighParameterValue();\\n BridgeDetails memory _bridge;\\n _bridge.limit = limit;\\n _bridge.hourlyLimit = hourlyLimit;\\n _bridge.paused = paused;\\n _bridge.fee = fee;\\n _bridge.allowed = true;\\n bridges[bridgeToken] = _bridge;\\n bridgeTokensList.push(bridgeToken);\\n emit BridgeTokenAdded(bridgeToken, limit, hourlyLimit, fee, paused);\\n }\\n\\n /// @notice Removes support for a token\\n /// @param bridgeToken Address of the bridge token to remove support for\\n function removeBridgeToken(address bridgeToken) external onlyGovernor {\\n if (IERC20(bridgeToken).balanceOf(address(this)) != 0) revert AssetStillControlledInReserves();\\n delete bridges[bridgeToken];\\n // Deletion from `bridgeTokensList` loop\\n uint256 bridgeTokensListLength = bridgeTokensList.length;\\n for (uint256 i; i < bridgeTokensListLength - 1; ++i) {\\n if (bridgeTokensList[i] == bridgeToken) {\\n // Replace the `bridgeToken` to remove with the last of the list\\n bridgeTokensList[i] = bridgeTokensList[bridgeTokensListLength - 1];\\n break;\\n }\\n }\\n // Remove last element in array\\n bridgeTokensList.pop();\\n emit BridgeTokenRemoved(bridgeToken);\\n }\\n\\n /// @notice Recovers any ERC20 token\\n /// @dev Can be used to withdraw bridge tokens for them to be de-bridged on mainnet\\n function recoverERC20(address tokenAddress, address to, uint256 amountToRecover) external onlyGovernor {\\n IERC20(tokenAddress).safeTransfer(to, amountToRecover);\\n emit Recovered(tokenAddress, to, amountToRecover);\\n }\\n\\n /// @notice Updates the `limit` amount for `bridgeToken`\\n function setLimit(address bridgeToken, uint256 limit) external onlyGovernorOrGuardian {\\n if (!bridges[bridgeToken].allowed) revert InvalidToken();\\n bridges[bridgeToken].limit = limit;\\n emit BridgeTokenLimitUpdated(bridgeToken, limit);\\n }\\n\\n /// @notice Updates the `hourlyLimit` amount for `bridgeToken`\\n function setHourlyLimit(address bridgeToken, uint256 hourlyLimit) external onlyGovernorOrGuardian {\\n if (!bridges[bridgeToken].allowed) revert InvalidToken();\\n bridges[bridgeToken].hourlyLimit = hourlyLimit;\\n emit BridgeTokenHourlyLimitUpdated(bridgeToken, hourlyLimit);\\n }\\n\\n /// @notice Updates the `chainTotalHourlyLimit` amount\\n function setChainTotalHourlyLimit(uint256 hourlyLimit) external onlyGovernorOrGuardian {\\n chainTotalHourlyLimit = hourlyLimit;\\n emit HourlyLimitUpdated(hourlyLimit);\\n }\\n\\n /// @notice Updates the `fee` value for `bridgeToken`\\n function setSwapFee(address bridgeToken, uint64 fee) external onlyGovernorOrGuardian {\\n if (!bridges[bridgeToken].allowed) revert InvalidToken();\\n if (fee > BASE_PARAMS) revert TooHighParameterValue();\\n bridges[bridgeToken].fee = fee;\\n emit BridgeTokenFeeUpdated(bridgeToken, fee);\\n }\\n\\n /// @notice Pauses or unpauses swapping in and out for a token\\n function toggleBridge(address bridgeToken) external onlyGovernorOrGuardian {\\n if (!bridges[bridgeToken].allowed) revert InvalidToken();\\n bool pausedStatus = bridges[bridgeToken].paused;\\n bridges[bridgeToken].paused = !pausedStatus;\\n emit BridgeTokenToggled(bridgeToken, !pausedStatus);\\n }\\n\\n /// @notice Toggles fees for the address `theAddress`\\n function toggleFeesForAddress(address theAddress) external onlyGovernorOrGuardian {\\n uint256 feeExemptStatus = 1 - isFeeExempt[theAddress];\\n isFeeExempt[theAddress] = feeExemptStatus;\\n emit FeeToggled(theAddress, feeExemptStatus);\\n }\\n}\\n\",\"keccak256\":\"0x9782497e84a1dc4bc468778ede4aceb35cebf74e4159e2af8f469f49312c3841\",\"license\":\"GPL-3.0\"},\"contracts/interfaces/IAgToken.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-3.0\\n\\npragma solidity ^0.8.12;\\n\\nimport \\\"@openzeppelin/contracts-upgradeable/token/ERC20/IERC20Upgradeable.sol\\\";\\n\\n/// @title IAgToken\\n/// @author Angle Labs, Inc.\\n/// @notice Interface for the stablecoins `AgToken` contracts\\n/// @dev This interface only contains functions of the `AgToken` contract which are called by other contracts\\n/// of this module or of the first module of the Angle Protocol\\ninterface IAgToken is IERC20Upgradeable {\\n // ======================= Minter Role Only Functions ===========================\\n\\n /// @notice Lets the `StableMaster` contract or another whitelisted contract mint agTokens\\n /// @param account Address to mint to\\n /// @param amount Amount to mint\\n /// @dev The contracts allowed to issue agTokens are the `StableMaster` contract, `VaultManager` contracts\\n /// associated to this stablecoin as well as the flash loan module (if activated) and potentially contracts\\n /// whitelisted by governance\\n function mint(address account, uint256 amount) external;\\n\\n /// @notice Burns `amount` tokens from a `burner` address after being asked to by `sender`\\n /// @param amount Amount of tokens to burn\\n /// @param burner Address to burn from\\n /// @param sender Address which requested the burn from `burner`\\n /// @dev This method is to be called by a contract with the minter right after being requested\\n /// to do so by a `sender` address willing to burn tokens from another `burner` address\\n /// @dev The method checks the allowance between the `sender` and the `burner`\\n function burnFrom(uint256 amount, address burner, address sender) external;\\n\\n /// @notice Burns `amount` tokens from a `burner` address\\n /// @param amount Amount of tokens to burn\\n /// @param burner Address to burn from\\n /// @dev This method is to be called by a contract with a minter right on the AgToken after being\\n /// requested to do so by an address willing to burn tokens from its address\\n function burnSelf(uint256 amount, address burner) external;\\n\\n // ========================= Treasury Only Functions ===========================\\n\\n /// @notice Adds a minter in the contract\\n /// @param minter Minter address to add\\n /// @dev Zero address checks are performed directly in the `Treasury` contract\\n function addMinter(address minter) external;\\n\\n /// @notice Removes a minter from the contract\\n /// @param minter Minter address to remove\\n /// @dev This function can also be called by a minter wishing to revoke itself\\n function removeMinter(address minter) external;\\n\\n /// @notice Sets a new treasury contract\\n /// @param _treasury New treasury address\\n function setTreasury(address _treasury) external;\\n\\n // ========================= External functions ================================\\n\\n /// @notice Checks whether an address has the right to mint agTokens\\n /// @param minter Address for which the minting right should be checked\\n /// @return Whether the address has the right to mint agTokens or not\\n function isMinter(address minter) external view returns (bool);\\n\\n /// @notice Get the associated treasury\\n function treasury() external view returns (address);\\n}\\n\",\"keccak256\":\"0x0c83efcfc1fb9ae9ba830f7b89e3dab9abf6ad7a6205a31aa35fbccaa837dcdc\",\"license\":\"GPL-3.0\"},\"contracts/interfaces/ICoreBorrow.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-3.0\\n\\npragma solidity ^0.8.12;\\n\\n/// @title ICoreBorrow\\n/// @author Angle Labs, Inc.\\n/// @notice Interface for the `CoreBorrow` contract\\n/// @dev This interface only contains functions of the `CoreBorrow` contract which are called by other contracts\\n/// of this module\\ninterface ICoreBorrow {\\n /// @notice Checks if an address corresponds to a treasury of a stablecoin with a flash loan\\n /// module initialized on it\\n /// @param treasury Address to check\\n /// @return Whether the address has the `FLASHLOANER_TREASURY_ROLE` or not\\n function isFlashLoanerTreasury(address treasury) external view returns (bool);\\n\\n /// @notice Checks whether an address is governor of the Angle Protocol or not\\n /// @param admin Address to check\\n /// @return Whether the address has the `GOVERNOR_ROLE` or not\\n function isGovernor(address admin) external view returns (bool);\\n\\n /// @notice Checks whether an address is governor or a guardian of the Angle Protocol or not\\n /// @param admin Address to check\\n /// @return Whether the address has the `GUARDIAN_ROLE` or not\\n /// @dev Governance should make sure when adding a governor to also give this governor the guardian\\n /// role by calling the `addGovernor` function\\n function isGovernorOrGuardian(address admin) external view returns (bool);\\n}\\n\",\"keccak256\":\"0x10249210cbf522775f040baf981d7d037472168ce2746d87473ac7c29a34e62e\",\"license\":\"GPL-3.0\"},\"contracts/interfaces/IFlashAngle.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-3.0\\n\\npragma solidity ^0.8.12;\\n\\nimport \\\"./IAgToken.sol\\\";\\nimport \\\"./ICoreBorrow.sol\\\";\\n\\n/// @title IFlashAngle\\n/// @author Angle Labs, Inc.\\n/// @notice Interface for the `FlashAngle` contract\\n/// @dev This interface only contains functions of the contract which are called by other contracts\\n/// of this module\\ninterface IFlashAngle {\\n /// @notice Reference to the `CoreBorrow` contract managing the FlashLoan module\\n function core() external view returns (ICoreBorrow);\\n\\n /// @notice Sends the fees taken from flash loans to the treasury contract associated to the stablecoin\\n /// @param stablecoin Stablecoin from which profits should be sent\\n /// @return balance Amount of profits sent\\n /// @dev This function can only be called by the treasury contract\\n function accrueInterestToTreasury(IAgToken stablecoin) external returns (uint256 balance);\\n\\n /// @notice Adds support for a stablecoin\\n /// @param _treasury Treasury associated to the stablecoin to add support for\\n /// @dev This function can only be called by the `CoreBorrow` contract\\n function addStablecoinSupport(address _treasury) external;\\n\\n /// @notice Removes support for a stablecoin\\n /// @param _treasury Treasury associated to the stablecoin to remove support for\\n /// @dev This function can only be called by the `CoreBorrow` contract\\n function removeStablecoinSupport(address _treasury) external;\\n\\n /// @notice Sets a new core contract\\n /// @param _core Core contract address to set\\n /// @dev This function can only be called by the `CoreBorrow` contract\\n function setCore(address _core) external;\\n}\\n\",\"keccak256\":\"0x39b0097f695b9e934bccdc72676c91513f1077cc5d0fd151908fd25a7c5cfbe4\",\"license\":\"GPL-3.0\"},\"contracts/interfaces/ITreasury.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-3.0\\n\\npragma solidity ^0.8.12;\\n\\nimport \\\"./IAgToken.sol\\\";\\nimport \\\"./ICoreBorrow.sol\\\";\\nimport \\\"./IFlashAngle.sol\\\";\\n\\n/// @title ITreasury\\n/// @author Angle Labs, Inc.\\n/// @notice Interface for the `Treasury` contract\\n/// @dev This interface only contains functions of the `Treasury` which are called by other contracts\\n/// of this module\\ninterface ITreasury {\\n /// @notice Stablecoin handled by this `treasury` contract\\n function stablecoin() external view returns (IAgToken);\\n\\n /// @notice Checks whether a given address has the governor role\\n /// @param admin Address to check\\n /// @return Whether the address has the governor role\\n /// @dev Access control is only kept in the `CoreBorrow` contract\\n function isGovernor(address admin) external view returns (bool);\\n\\n /// @notice Checks whether a given address has the guardian or the governor role\\n /// @param admin Address to check\\n /// @return Whether the address has the guardian or the governor role\\n /// @dev Access control is only kept in the `CoreBorrow` contract which means that this function\\n /// queries the `CoreBorrow` contract\\n function isGovernorOrGuardian(address admin) external view returns (bool);\\n\\n /// @notice Checks whether a given address has well been initialized in this contract\\n /// as a `VaultManager`\\n /// @param _vaultManager Address to check\\n /// @return Whether the address has been initialized or not\\n function isVaultManager(address _vaultManager) external view returns (bool);\\n\\n /// @notice Sets a new flash loan module for this stablecoin\\n /// @param _flashLoanModule Reference to the new flash loan module\\n /// @dev This function removes the minting right to the old flash loan module and grants\\n /// it to the new module\\n function setFlashLoanModule(address _flashLoanModule) external;\\n\\n /// @notice Gets the vault manager list\\n function vaultManagerList(uint256 i) external returns (address);\\n}\\n\",\"keccak256\":\"0x06c2f781c08732ce1b5845c083af5742716245baa6c519bd737f32b230a884c1\",\"license\":\"GPL-3.0\"}},\"version\":1}", + "bytecode": "0x60806040523480156200001157600080fd5b50600054610100900460ff1615808015620000335750600054600160ff909116105b8062000063575062000050306200013d60201b6200273a1760201c565b15801562000063575060005460ff166001145b620000cb5760405162461bcd60e51b815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201526d191e481a5b9a5d1a585b1a5e995960921b606482015260840160405180910390fd5b6000805460ff191660011790558015620000ef576000805461ff0019166101001790555b801562000136576000805461ff0019169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15b506200014c565b6001600160a01b03163b151590565b6146d0806200015c6000396000f3fe608060405234801561001057600080fd5b50600436106102ff5760003560e01c806361d027b31161019c5780639f48118f116100ee578063ced67f0c11610097578063dd62ed3e11610071578063dd62ed3e14610724578063e3e286551461076a578063f0f442601461077d57600080fd5b8063ced67f0c1461066b578063d44ad63f146106fe578063d505accf1461071157600080fd5b8063aa271e1a116100c8578063aa271e1a14610620578063ba330bd714610643578063cd4839ca1461065657600080fd5b80639f48118f146105ef578063a457c2d7146105fa578063a9059cbb1461060d57600080fd5b80637ecebe001161015057806395d89b411161012a57806395d89b41146105c1578063983b2d56146105c95780639e4e0dae146105dc57600080fd5b80637ecebe00146105705780638933fb791461058357806390218cff146105ae57600080fd5b80637334d020116101815780637334d020146105425780637d4c9c2d146105555780637d74e25f1461056857600080fd5b806361d027b3146104c757806370a082311461050c57600080fd5b80633092afd511610255578063395093511161020957806340c10f19116101e357806340c10f19146104815780634dc32fcc146104945780635bfbec96146104a757600080fd5b8063395093511461043b5780633a55f89d1461044e5780633f4218e01461046157600080fd5b8063350ebe041161023a578063350ebe041461040d5780633644e5151461042057806336db43b51461042857600080fd5b80633092afd5146103eb578063313ce567146103fe57600080fd5b8063151dd755116102b757806323b872dd1161029157806323b872dd146103b25780632b471d8e146103c55780632e403e14146103d857600080fd5b8063151dd7551461038057806318160ddd146103a15780632342fb0e146103a957600080fd5b80630919a951116102e85780630919a95114610337578063095ea7b31461034a5780631171bda91461036d57600080fd5b806306fdde0314610304578063077f224a14610322575b600080fd5b61030c610790565b6040516103199190613e48565b60405180910390f35b610335610330366004613f95565b610822565b005b61033561034536600461400d565b610832565b61035d61035836600461402a565b610995565b6040519015158152602001610319565b61033561037b366004614056565b6109af565b61039361038e366004614097565b610b04565b604051908152602001610319565b603554610393565b61039360d25481565b61035d6103c0366004614056565b610dbe565b6103356103d33660046140ce565b610de2565b6103356103e636600461400d565b610e39565b6103356103f936600461400d565b6111e8565b60405160128152602001610319565b61033561041b3660046140fe565b6112d1565b6103936113da565b61033561043636600461402a565b6113e9565b61035d61044936600461402a565b611579565b61033561045c366004614135565b6115c0565b61039361046f36600461400d565b60d16020526000908152604090205481565b61033561048f36600461402a565b6116c3565b6103936104a236600461400d565b611716565b6103936104b5366004614135565b60d36020526000908152604090205481565b60cd546104e79073ffffffffffffffffffffffffffffffffffffffff1681565b60405173ffffffffffffffffffffffffffffffffffffffff9091168152602001610319565b61039361051a36600461400d565b73ffffffffffffffffffffffffffffffffffffffff1660009081526033602052604090205490565b61033561055036600461402a565b61175e565b610335610563366004614179565b6118f1565b610393611c59565b61039361057e36600461400d565b611c7e565b61039361059136600461402a565b60d060209081526000928352604080842090915290825290205481565b6103356105bc366004614135565b611ca9565b61030c611cb6565b6103356105d736600461400d565b611cc5565b6103356105ea3660046141d6565b611d8d565b610393633b9aca0081565b61035d61060836600461402a565b611f99565b61035d61061b36600461402a565b61206f565b61035d61062e36600461400d565b60cc6020526000908152604090205460ff1681565b6104e7610651366004614135565b61207d565b61065e6120b4565b604051610319919061420b565b6106c561067936600461400d565b60ce6020526000908152604090208054600182015460029092015490919067ffffffffffffffff81169060ff680100000000000000008204811691690100000000000000000090041685565b60408051958652602086019490945267ffffffffffffffff9092169284019290925290151560608301521515608082015260a001610319565b61039361070c366004614097565b612122565b61033561071f366004614265565b6122e7565b6103936107323660046142dc565b73ffffffffffffffffffffffffffffffffffffffff918216600090815260346020908152604080832093909416825291909152205490565b61033561077836600461400d565b6124a6565b61033561078b36600461400d565b61267a565b60606036805461079f9061430a565b80601f01602080910402602001604051908101604052809291908181526020018280546107cb9061430a565b80156108185780601f106107ed57610100808354040283529160200191610818565b820191906000526020600020905b8154815290600101906020018083116107fb57829003601f168201915b5050505050905090565b61082d838383612756565b505050565b60cd546040517f521d4de900000000000000000000000000000000000000000000000000000000815233600482015273ffffffffffffffffffffffffffffffffffffffff9091169063521d4de990602401602060405180830381865afa1580156108a0573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906108c49190614357565b6108fa576040517f99e120bc00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff8116600090815260d1602052604081205461092b9060016143a3565b73ffffffffffffffffffffffffffffffffffffffff8316600081815260d160205260409081902083905551919250907f979ef83e7e7a87cb48064e296dd7e997870d50f43acf8d7ad221313526c8ca0f906109899084815260200190565b60405180910390a25050565b6000336109a3818585612a35565b60019150505b92915050565b60cd546040517fe43581b800000000000000000000000000000000000000000000000000000000815233600482015273ffffffffffffffffffffffffffffffffffffffff9091169063e43581b890602401602060405180830381865afa158015610a1d573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610a419190614357565b610a77576040517fee3675d400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b610a9873ffffffffffffffffffffffffffffffffffffffff84168383612be0565b8173ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff167ffff3b3844276f57024e0b42afec1a37f75db36511e43819a4f2a63ab7862b64883604051610af791815260200190565b60405180910390a3505050565b73ffffffffffffffffffffffffffffffffffffffff8316600090815260ce60209081526040808320815160a081018352815481526001820154938101939093526002015467ffffffffffffffff81169183019190915260ff680100000000000000008204811615801560608501526901000000000000000000909204161515608083015280610b94575080608001515b15610bcb576040517fc1ab6dc100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015260009073ffffffffffffffffffffffffffffffffffffffff8716906370a0823190602401602060405180830381865afa158015610c38573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610c5c91906143b6565b8251909150610c6b86836143cf565b1115610c93578151811015610c8e578151610c879082906143a3565b9450610c93565b600094505b6000610ca1610e10426143e2565b73ffffffffffffffffffffffffffffffffffffffff8816600090815260d0602090815260408083208484528252909120549085015191925090610ce488836143cf565b1115610d0f5780846020015111610cfc576000610d0c565b808460200151610d0c91906143a3565b96505b610d1987826143cf565b73ffffffffffffffffffffffffffffffffffffffff8916600081815260d060209081526040808320878452909152902091909155610d599033308a612cb4565b33600090815260d16020526040812054889103610da657633b9aca00856040015167ffffffffffffffff1682610d8f919061441d565b610d9991906143e2565b610da390826143a3565b90505b610db08782612d12565b9450505050505b9392505050565b600033610dcc858285612e32565b610dd7858585612f03565b506001949350505050565b33600090815260cc602052604090205460ff16610e2b576040517ff8d2906c00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b610e3581836131b6565b5050565b60cd546040517fe43581b800000000000000000000000000000000000000000000000000000000815233600482015273ffffffffffffffffffffffffffffffffffffffff9091169063e43581b890602401602060405180830381865afa158015610ea7573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610ecb9190614357565b610f01576040517fee3675d400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015273ffffffffffffffffffffffffffffffffffffffff8216906370a0823190602401602060405180830381865afa158015610f6b573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610f8f91906143b6565b15610fc6576040517f2ef630ec00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff8116600090815260ce602052604081208181556001810182905560020180547fffffffffffffffffffffffffffffffffffffffffffff0000000000000000000016905560cf54905b61102e6001836143a3565b811015611139578273ffffffffffffffffffffffffffffffffffffffff1660cf828154811061105f5761105f614434565b60009182526020909120015473ffffffffffffffffffffffffffffffffffffffff16036111295760cf6110936001846143a3565b815481106110a3576110a3614434565b60009182526020909120015460cf805473ffffffffffffffffffffffffffffffffffffffff90921691839081106110dc576110dc614434565b9060005260206000200160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550611139565b61113281614463565b9050611023565b5060cf80548061114b5761114b61449b565b60008281526020812082017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff90810180547fffffffffffffffffffffffff000000000000000000000000000000000000000016905590910190915560405173ffffffffffffffffffffffffffffffffffffffff8416917f5c95b49c4d59d97a2f044167723f29c74b30f99702e3fd406c3830160aa9ccb891a25050565b60cd5473ffffffffffffffffffffffffffffffffffffffff16331480159061122657503373ffffffffffffffffffffffffffffffffffffffff821614155b1561125d576040517fddb5de5e00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff8116600081815260cc602052604080822080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00169055517f98c15241d6c02bc5ee0b780e11b3ea737a2defd9d04877edbe9f9497065bd02f9190a250565b33600090815260cc602052604090205460ff1661131a576040517ff8d2906c00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff16146113d05773ffffffffffffffffffffffffffffffffffffffff828116600090815260346020908152604080832093851683529290522054838110156113ba576040517f715ec26c00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6113ce83836113c987856143a3565b612a35565b505b61082d82846131b6565b60006113e46133a3565b905090565b60cd546040517f521d4de900000000000000000000000000000000000000000000000000000000815233600482015273ffffffffffffffffffffffffffffffffffffffff9091169063521d4de990602401602060405180830381865afa158015611457573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061147b9190614357565b6114b1576040517f99e120bc00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff8216600090815260ce602052604090206002015468010000000000000000900460ff1661151f576040517fc1ab6dc100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff8216600081815260ce602052604090819020839055517fe7b113fba37131b6396680a0c55790a697ec975e198ff8cfd89dac90a6379e61906109899084815260200190565b33600081815260346020908152604080832073ffffffffffffffffffffffffffffffffffffffff871684529091528120549091906109a390829086906113c99087906143cf565b60cd546040517f521d4de900000000000000000000000000000000000000000000000000000000815233600482015273ffffffffffffffffffffffffffffffffffffffff9091169063521d4de990602401602060405180830381865afa15801561162e573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906116529190614357565b611688576040517f99e120bc00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60d28190556040518181527fc3b69829afe2345596a02c8b587d41f796ba0094481d899e1b2e07b7532a1e219060200160405180910390a150565b33600090815260cc602052604090205460ff1661170c576040517ff8d2906c00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b610e358282612d12565b73ffffffffffffffffffffffffffffffffffffffff8116600090815260d06020526040812081611748610e10426143e2565b8152602001908152602001600020549050919050565b60cd546040517f521d4de900000000000000000000000000000000000000000000000000000000815233600482015273ffffffffffffffffffffffffffffffffffffffff9091169063521d4de990602401602060405180830381865afa1580156117cc573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906117f09190614357565b611826576040517f99e120bc00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff8216600090815260ce602052604090206002015468010000000000000000900460ff16611894576040517fc1ab6dc100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff8216600081815260ce602052604090819020600101839055517fe13ac9338b2ee623233f83c1b3ceab16490fa3e3737fac7f0970d0830a9f4871906109899084815260200190565b60cd546040517fe43581b800000000000000000000000000000000000000000000000000000000815233600482015273ffffffffffffffffffffffffffffffffffffffff9091169063e43581b890602401602060405180830381865afa15801561195f573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906119839190614357565b6119b9576040517fee3675d400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff8516600090815260ce602052604090206002015468010000000000000000900460ff1680611a10575073ffffffffffffffffffffffffffffffffffffffff8516155b15611a47576040517fc1ab6dc100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b633b9aca008267ffffffffffffffff161115611a8f576040517feca1d2c600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040805160a08101825260008082526020820181905291810182905260608101829052608081019190915284815260208082018581528315156080840190815267ffffffffffffffff808716604080870191825260016060880181815273ffffffffffffffffffffffffffffffffffffffff8e16600081815260ce9099528389208a5181559751888401559351600290970180549151965115156901000000000000000000027fffffffffffffffffffffffffffffffffffffffffffff00ffffffffffffffffff97151568010000000000000000027fffffffffffffffffffffffffffffffffffffffffffffff000000000000000000909316989096169790971717949094169290921790935560cf805492830181559093527facb8d954e2cfef495862221e91bd7523613cf8808827cb33edfe4904cc51bf290180547fffffffffffffffffffffffff0000000000000000000000000000000000000000168217905590517f53087ff85d80a7671594bd2e86b92af22e0b3c2c441c8033bba7399b7b5cbe2390611c49908890889088908890938452602084019290925267ffffffffffffffff1660408301521515606082015260800190565b60405180910390a2505050505050565b600060d381611c6a610e10426143e2565b815260200190815260200160002054905090565b73ffffffffffffffffffffffffffffffffffffffff81166000908152609960205260408120546109a9565b611cb333826131b6565b50565b60606037805461079f9061430a565b60cd5473ffffffffffffffffffffffffffffffffffffffff163314611d16576040517fb90cdbb100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff8116600081815260cc602052604080822080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00166001179055517f98c15241d6c02bc5ee0b780e11b3ea737a2defd9d04877edbe9f9497065bd02f9190a250565b60cd546040517f521d4de900000000000000000000000000000000000000000000000000000000815233600482015273ffffffffffffffffffffffffffffffffffffffff9091169063521d4de990602401602060405180830381865afa158015611dfb573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611e1f9190614357565b611e55576040517f99e120bc00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff8216600090815260ce602052604090206002015468010000000000000000900460ff16611ec3576040517fc1ab6dc100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b633b9aca008167ffffffffffffffff161115611f0b576040517feca1d2c600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff8216600081815260ce602090815260409182902060020180547fffffffffffffffffffffffffffffffffffffffffffffffff00000000000000001667ffffffffffffffff861690811790915591519182527f901f9de19b475adc8da4110434b8df940dce085afd05e2281c86807f3a899d299101610989565b33600081815260346020908152604080832073ffffffffffffffffffffffffffffffffffffffff8716845290915281205490919083811015612062576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602560248201527f45524332303a2064656372656173656420616c6c6f77616e63652062656c6f7760448201527f207a65726f00000000000000000000000000000000000000000000000000000060648201526084015b60405180910390fd5b610dd78286868403612a35565b6000336109a3818585612f03565b60cf818154811061208d57600080fd5b60009182526020909120015473ffffffffffffffffffffffffffffffffffffffff16905081565b606060cf80548060200260200160405190810160405280929190818152602001828054801561081857602002820191906000526020600020905b815473ffffffffffffffffffffffffffffffffffffffff1681526001909101906020018083116120ee575050505050905090565b73ffffffffffffffffffffffffffffffffffffffff8316600090815260ce60209081526040808320815160a081018352815481526001820154938101939093526002015467ffffffffffffffff81169183019190915260ff6801000000000000000082048116158015606085015269010000000000000000009092041615156080830152806121b2575080608001515b156121e9576040517fc1ab6dc100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60006121f7610e10426143e2565b600081815260d36020526040812054919250906122159087906143cf565b905060d254811115612253576040517f6d43d1ac00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600082815260d36020526040902081905561226e33876131b6565b33600090815260d160205260408120548791036122bb57633b9aca00846040015167ffffffffffffffff16826122a4919061441d565b6122ae91906143e2565b6122b890826143a3565b90505b6122dc73ffffffffffffffffffffffffffffffffffffffff89168783612be0565b979650505050505050565b83421115612351576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f45524332305065726d69743a206578706972656420646561646c696e650000006044820152606401612059565b60007f6e71edae12b1b97f4d1f60370fef10105fa2faae0126114a169c64845d6126c98888886123808c61341e565b60408051602081019690965273ffffffffffffffffffffffffffffffffffffffff94851690860152929091166060840152608083015260a082015260c0810186905260e00160405160208183030381529060405280519060200120905060006123e882613453565b905060006123f8828787876134bc565b90508973ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff161461248f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601e60248201527f45524332305065726d69743a20696e76616c6964207369676e617475726500006044820152606401612059565b61249a8a8a8a612a35565b50505050505050505050565b60cd546040517f521d4de900000000000000000000000000000000000000000000000000000000815233600482015273ffffffffffffffffffffffffffffffffffffffff9091169063521d4de990602401602060405180830381865afa158015612514573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906125389190614357565b61256e576040517f99e120bc00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff8116600090815260ce602052604090206002015468010000000000000000900460ff166125dc576040517fc1ab6dc100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff8116600081815260ce602090815260409182902060020180547fffffffffffffffffffffffffffffffffffffffffffff00ffffffffffffffffff811669010000000000000000009182900460ff16801592830291909117909255925192835292917ff7c93079dcbf699749d66345a351afab7d24219bb1d915c9f4fc4cf03f00d3979101610989565b60cd5473ffffffffffffffffffffffffffffffffffffffff1633146126cb576040517fb90cdbb100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60cd80547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83169081179091556040517f7dae230f18360d76a040c81f050aa14eb9d6dc7901b20fc5d855e2a20fe814d190600090a250565b73ffffffffffffffffffffffffffffffffffffffff163b151590565b600054610100900460ff16158080156127765750600054600160ff909116105b806127905750303b158015612790575060005460ff166001145b61281c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201527f647920696e697469616c697a65640000000000000000000000000000000000006064820152608401612059565b600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00166001179055801561287a57600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff166101001790555b3073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1663e9cbd8226040518163ffffffff1660e01b8152600401602060405180830381865afa1580156128dc573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061290091906144ca565b73ffffffffffffffffffffffffffffffffffffffff161461294d576040517f14bcf5c800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b612956846134e4565b61296084846135ba565b60cd80547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff84169081179091556040517f7dae230f18360d76a040c81f050aa14eb9d6dc7901b20fc5d855e2a20fe814d190600090a28015612a2f57600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15b50505050565b73ffffffffffffffffffffffffffffffffffffffff8316612ad7576040517f08c379a0000000000000000000000000000000000000000000000000000000008152602060048201526024808201527f45524332303a20617070726f76652066726f6d20746865207a65726f2061646460448201527f72657373000000000000000000000000000000000000000000000000000000006064820152608401612059565b73ffffffffffffffffffffffffffffffffffffffff8216612b7a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602260248201527f45524332303a20617070726f766520746f20746865207a65726f20616464726560448201527f73730000000000000000000000000000000000000000000000000000000000006064820152608401612059565b73ffffffffffffffffffffffffffffffffffffffff83811660008181526034602090815260408083209487168084529482529182902085905590518481527f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b9259101610af7565b60405173ffffffffffffffffffffffffffffffffffffffff831660248201526044810182905261082d9084907fa9059cbb00000000000000000000000000000000000000000000000000000000906064015b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff000000000000000000000000000000000000000000000000000000009093169290921790915261365b565b60405173ffffffffffffffffffffffffffffffffffffffff80851660248301528316604482015260648101829052612a2f9085907f23b872dd0000000000000000000000000000000000000000000000000000000090608401612c32565b73ffffffffffffffffffffffffffffffffffffffff8216612d8f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601f60248201527f45524332303a206d696e7420746f20746865207a65726f2061646472657373006044820152606401612059565b8060356000828254612da191906143cf565b909155505073ffffffffffffffffffffffffffffffffffffffff821660009081526033602052604081208054839290612ddb9084906143cf565b909155505060405181815273ffffffffffffffffffffffffffffffffffffffff8316906000907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef9060200160405180910390a35050565b73ffffffffffffffffffffffffffffffffffffffff8381166000908152603460209081526040808320938616835292905220547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8114612a2f5781811015612ef6576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f45524332303a20696e73756666696369656e7420616c6c6f77616e63650000006044820152606401612059565b612a2f8484848403612a35565b73ffffffffffffffffffffffffffffffffffffffff8316612fa6576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602560248201527f45524332303a207472616e736665722066726f6d20746865207a65726f20616460448201527f64726573730000000000000000000000000000000000000000000000000000006064820152608401612059565b73ffffffffffffffffffffffffffffffffffffffff8216613049576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602360248201527f45524332303a207472616e7366657220746f20746865207a65726f206164647260448201527f65737300000000000000000000000000000000000000000000000000000000006064820152608401612059565b73ffffffffffffffffffffffffffffffffffffffff8316600090815260336020526040902054818110156130ff576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f45524332303a207472616e7366657220616d6f756e742065786365656473206260448201527f616c616e636500000000000000000000000000000000000000000000000000006064820152608401612059565b73ffffffffffffffffffffffffffffffffffffffff8085166000908152603360205260408082208585039055918516815290812080548492906131439084906143cf565b925050819055508273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef846040516131a991815260200190565b60405180910390a3612a2f565b73ffffffffffffffffffffffffffffffffffffffff8216613259576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602160248201527f45524332303a206275726e2066726f6d20746865207a65726f2061646472657360448201527f73000000000000000000000000000000000000000000000000000000000000006064820152608401612059565b73ffffffffffffffffffffffffffffffffffffffff82166000908152603360205260409020548181101561330f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602260248201527f45524332303a206275726e20616d6f756e7420657863656564732062616c616e60448201527f63650000000000000000000000000000000000000000000000000000000000006064820152608401612059565b73ffffffffffffffffffffffffffffffffffffffff8316600090815260336020526040812083830390556035805484929061334b9084906143a3565b909155505060405182815260009073ffffffffffffffffffffffffffffffffffffffff8516907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef9060200160405180910390a3505050565b60006113e47f8b73c3c69bb8fe3d512ecc4cf759cc79239f7b179b0ffacaa9a75d522b39400f6133d260655490565b6066546040805160208101859052908101839052606081018290524660808201523060a082015260009060c0016040516020818303038152906040528051906020012090509392505050565b73ffffffffffffffffffffffffffffffffffffffff811660009081526099602052604090208054600181018255905b50919050565b60006109a96134606133a3565b836040517f19010000000000000000000000000000000000000000000000000000000000006020820152602281018390526042810182905260009060620160405160208183030381529060405280519060200120905092915050565b60008060006134cd87878787613767565b915091506134da8161387f565b5095945050505050565b600054610100900460ff1661357b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201527f6e697469616c697a696e670000000000000000000000000000000000000000006064820152608401612059565b611cb3816040518060400160405280600181526020017f3100000000000000000000000000000000000000000000000000000000000000815250613ad3565b600054610100900460ff16613651576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201527f6e697469616c697a696e670000000000000000000000000000000000000000006064820152608401612059565b610e358282613b84565b60006136bd826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c65648152508573ffffffffffffffffffffffffffffffffffffffff16613c349092919063ffffffff16565b80519091501561082d57808060200190518101906136db9190614357565b61082d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e60448201527f6f742073756363656564000000000000000000000000000000000000000000006064820152608401612059565b6000807f7fffffffffffffffffffffffffffffff5d576e7357a4501ddfe92f46681b20a083111561379e5750600090506003613876565b8460ff16601b141580156137b657508460ff16601c14155b156137c75750600090506004613876565b6040805160008082526020820180845289905260ff881692820192909252606081018690526080810185905260019060a0016020604051602081039080840390855afa15801561381b573d6000803e3d6000fd5b50506040517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0015191505073ffffffffffffffffffffffffffffffffffffffff811661386f57600060019250925050613876565b9150600090505b94509492505050565b6000816004811115613893576138936144e7565b0361389b5750565b60018160048111156138af576138af6144e7565b03613916576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601860248201527f45434453413a20696e76616c6964207369676e617475726500000000000000006044820152606401612059565b600281600481111561392a5761392a6144e7565b03613991576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601f60248201527f45434453413a20696e76616c6964207369676e6174757265206c656e677468006044820152606401612059565b60038160048111156139a5576139a56144e7565b03613a32576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602260248201527f45434453413a20696e76616c6964207369676e6174757265202773272076616c60448201527f75650000000000000000000000000000000000000000000000000000000000006064820152608401612059565b6004816004811115613a4657613a466144e7565b03611cb3576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602260248201527f45434453413a20696e76616c6964207369676e6174757265202776272076616c60448201527f75650000000000000000000000000000000000000000000000000000000000006064820152608401612059565b600054610100900460ff16613b6a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201527f6e697469616c697a696e670000000000000000000000000000000000000000006064820152608401612059565b815160209283012081519190920120606591909155606655565b600054610100900460ff16613c1b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201527f6e697469616c697a696e670000000000000000000000000000000000000000006064820152608401612059565b6036613c278382614564565b50603761082d8282614564565b6060613c438484600085613c4b565b949350505050565b606082471015613cdd576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f60448201527f722063616c6c00000000000000000000000000000000000000000000000000006064820152608401612059565b73ffffffffffffffffffffffffffffffffffffffff85163b613d5b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006044820152606401612059565b6000808673ffffffffffffffffffffffffffffffffffffffff168587604051613d84919061467e565b60006040518083038185875af1925050503d8060008114613dc1576040519150601f19603f3d011682016040523d82523d6000602084013e613dc6565b606091505b50915091506122dc82828660608315613de0575081610db7565b825115613df05782518084602001fd5b816040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016120599190613e48565b60005b83811015613e3f578181015183820152602001613e27565b50506000910152565b6020815260008251806020840152613e67816040850160208701613e24565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169190910160400192915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b600082601f830112613ed957600080fd5b813567ffffffffffffffff80821115613ef457613ef4613e99565b604051601f83017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0908116603f01168101908282118183101715613f3a57613f3a613e99565b81604052838152866020858801011115613f5357600080fd5b836020870160208301376000602085830101528094505050505092915050565b73ffffffffffffffffffffffffffffffffffffffff81168114611cb357600080fd5b600080600060608486031215613faa57600080fd5b833567ffffffffffffffff80821115613fc257600080fd5b613fce87838801613ec8565b94506020860135915080821115613fe457600080fd5b50613ff186828701613ec8565b925050604084013561400281613f73565b809150509250925092565b60006020828403121561401f57600080fd5b8135610db781613f73565b6000806040838503121561403d57600080fd5b823561404881613f73565b946020939093013593505050565b60008060006060848603121561406b57600080fd5b833561407681613f73565b9250602084013561408681613f73565b929592945050506040919091013590565b6000806000606084860312156140ac57600080fd5b83356140b781613f73565b925060208401359150604084013561400281613f73565b600080604083850312156140e157600080fd5b8235915060208301356140f381613f73565b809150509250929050565b60008060006060848603121561411357600080fd5b83359250602084013561412581613f73565b9150604084013561400281613f73565b60006020828403121561414757600080fd5b5035919050565b803567ffffffffffffffff8116811461416657600080fd5b919050565b8015158114611cb357600080fd5b600080600080600060a0868803121561419157600080fd5b853561419c81613f73565b945060208601359350604086013592506141b86060870161414e565b915060808601356141c88161416b565b809150509295509295909350565b600080604083850312156141e957600080fd5b82356141f481613f73565b91506142026020840161414e565b90509250929050565b6020808252825182820181905260009190848201906040850190845b8181101561425957835173ffffffffffffffffffffffffffffffffffffffff1683529284019291840191600101614227565b50909695505050505050565b600080600080600080600060e0888a03121561428057600080fd5b873561428b81613f73565b9650602088013561429b81613f73565b95506040880135945060608801359350608088013560ff811681146142bf57600080fd5b9699959850939692959460a0840135945060c09093013592915050565b600080604083850312156142ef57600080fd5b82356142fa81613f73565b915060208301356140f381613f73565b600181811c9082168061431e57607f821691505b60208210810361344d577f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b60006020828403121561436957600080fd5b8151610db78161416b565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b818103818111156109a9576109a9614374565b6000602082840312156143c857600080fd5b5051919050565b808201808211156109a9576109a9614374565b600082614418577f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b500490565b80820281158282048414176109a9576109a9614374565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff820361449457614494614374565b5060010190565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603160045260246000fd5b6000602082840312156144dc57600080fd5b8151610db781613f73565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b601f82111561082d57600081815260208120601f850160051c8101602086101561453d5750805b601f850160051c820191505b8181101561455c57828155600101614549565b505050505050565b815167ffffffffffffffff81111561457e5761457e613e99565b6145928161458c845461430a565b84614516565b602080601f8311600181146145e557600084156145af5750858301515b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600386901b1c1916600185901b17855561455c565b6000858152602081207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08616915b8281101561463257888601518255948401946001909101908401614613565b508582101561466e57878501517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600388901b60f8161c191681555b5050505050600190811b01905550565b60008251614690818460208701613e24565b919091019291505056fea2646970667358221220f2eb02bac1667a72be85ab617a5b5aa3d8f7a9b09b4d1fde9756b7a5636daf2164736f6c63430008110033", + "deployedBytecode": "0x608060405234801561001057600080fd5b50600436106102ff5760003560e01c806361d027b31161019c5780639f48118f116100ee578063ced67f0c11610097578063dd62ed3e11610071578063dd62ed3e14610724578063e3e286551461076a578063f0f442601461077d57600080fd5b8063ced67f0c1461066b578063d44ad63f146106fe578063d505accf1461071157600080fd5b8063aa271e1a116100c8578063aa271e1a14610620578063ba330bd714610643578063cd4839ca1461065657600080fd5b80639f48118f146105ef578063a457c2d7146105fa578063a9059cbb1461060d57600080fd5b80637ecebe001161015057806395d89b411161012a57806395d89b41146105c1578063983b2d56146105c95780639e4e0dae146105dc57600080fd5b80637ecebe00146105705780638933fb791461058357806390218cff146105ae57600080fd5b80637334d020116101815780637334d020146105425780637d4c9c2d146105555780637d74e25f1461056857600080fd5b806361d027b3146104c757806370a082311461050c57600080fd5b80633092afd511610255578063395093511161020957806340c10f19116101e357806340c10f19146104815780634dc32fcc146104945780635bfbec96146104a757600080fd5b8063395093511461043b5780633a55f89d1461044e5780633f4218e01461046157600080fd5b8063350ebe041161023a578063350ebe041461040d5780633644e5151461042057806336db43b51461042857600080fd5b80633092afd5146103eb578063313ce567146103fe57600080fd5b8063151dd755116102b757806323b872dd1161029157806323b872dd146103b25780632b471d8e146103c55780632e403e14146103d857600080fd5b8063151dd7551461038057806318160ddd146103a15780632342fb0e146103a957600080fd5b80630919a951116102e85780630919a95114610337578063095ea7b31461034a5780631171bda91461036d57600080fd5b806306fdde0314610304578063077f224a14610322575b600080fd5b61030c610790565b6040516103199190613e48565b60405180910390f35b610335610330366004613f95565b610822565b005b61033561034536600461400d565b610832565b61035d61035836600461402a565b610995565b6040519015158152602001610319565b61033561037b366004614056565b6109af565b61039361038e366004614097565b610b04565b604051908152602001610319565b603554610393565b61039360d25481565b61035d6103c0366004614056565b610dbe565b6103356103d33660046140ce565b610de2565b6103356103e636600461400d565b610e39565b6103356103f936600461400d565b6111e8565b60405160128152602001610319565b61033561041b3660046140fe565b6112d1565b6103936113da565b61033561043636600461402a565b6113e9565b61035d61044936600461402a565b611579565b61033561045c366004614135565b6115c0565b61039361046f36600461400d565b60d16020526000908152604090205481565b61033561048f36600461402a565b6116c3565b6103936104a236600461400d565b611716565b6103936104b5366004614135565b60d36020526000908152604090205481565b60cd546104e79073ffffffffffffffffffffffffffffffffffffffff1681565b60405173ffffffffffffffffffffffffffffffffffffffff9091168152602001610319565b61039361051a36600461400d565b73ffffffffffffffffffffffffffffffffffffffff1660009081526033602052604090205490565b61033561055036600461402a565b61175e565b610335610563366004614179565b6118f1565b610393611c59565b61039361057e36600461400d565b611c7e565b61039361059136600461402a565b60d060209081526000928352604080842090915290825290205481565b6103356105bc366004614135565b611ca9565b61030c611cb6565b6103356105d736600461400d565b611cc5565b6103356105ea3660046141d6565b611d8d565b610393633b9aca0081565b61035d61060836600461402a565b611f99565b61035d61061b36600461402a565b61206f565b61035d61062e36600461400d565b60cc6020526000908152604090205460ff1681565b6104e7610651366004614135565b61207d565b61065e6120b4565b604051610319919061420b565b6106c561067936600461400d565b60ce6020526000908152604090208054600182015460029092015490919067ffffffffffffffff81169060ff680100000000000000008204811691690100000000000000000090041685565b60408051958652602086019490945267ffffffffffffffff9092169284019290925290151560608301521515608082015260a001610319565b61039361070c366004614097565b612122565b61033561071f366004614265565b6122e7565b6103936107323660046142dc565b73ffffffffffffffffffffffffffffffffffffffff918216600090815260346020908152604080832093909416825291909152205490565b61033561077836600461400d565b6124a6565b61033561078b36600461400d565b61267a565b60606036805461079f9061430a565b80601f01602080910402602001604051908101604052809291908181526020018280546107cb9061430a565b80156108185780601f106107ed57610100808354040283529160200191610818565b820191906000526020600020905b8154815290600101906020018083116107fb57829003601f168201915b5050505050905090565b61082d838383612756565b505050565b60cd546040517f521d4de900000000000000000000000000000000000000000000000000000000815233600482015273ffffffffffffffffffffffffffffffffffffffff9091169063521d4de990602401602060405180830381865afa1580156108a0573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906108c49190614357565b6108fa576040517f99e120bc00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff8116600090815260d1602052604081205461092b9060016143a3565b73ffffffffffffffffffffffffffffffffffffffff8316600081815260d160205260409081902083905551919250907f979ef83e7e7a87cb48064e296dd7e997870d50f43acf8d7ad221313526c8ca0f906109899084815260200190565b60405180910390a25050565b6000336109a3818585612a35565b60019150505b92915050565b60cd546040517fe43581b800000000000000000000000000000000000000000000000000000000815233600482015273ffffffffffffffffffffffffffffffffffffffff9091169063e43581b890602401602060405180830381865afa158015610a1d573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610a419190614357565b610a77576040517fee3675d400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b610a9873ffffffffffffffffffffffffffffffffffffffff84168383612be0565b8173ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff167ffff3b3844276f57024e0b42afec1a37f75db36511e43819a4f2a63ab7862b64883604051610af791815260200190565b60405180910390a3505050565b73ffffffffffffffffffffffffffffffffffffffff8316600090815260ce60209081526040808320815160a081018352815481526001820154938101939093526002015467ffffffffffffffff81169183019190915260ff680100000000000000008204811615801560608501526901000000000000000000909204161515608083015280610b94575080608001515b15610bcb576040517fc1ab6dc100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015260009073ffffffffffffffffffffffffffffffffffffffff8716906370a0823190602401602060405180830381865afa158015610c38573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610c5c91906143b6565b8251909150610c6b86836143cf565b1115610c93578151811015610c8e578151610c879082906143a3565b9450610c93565b600094505b6000610ca1610e10426143e2565b73ffffffffffffffffffffffffffffffffffffffff8816600090815260d0602090815260408083208484528252909120549085015191925090610ce488836143cf565b1115610d0f5780846020015111610cfc576000610d0c565b808460200151610d0c91906143a3565b96505b610d1987826143cf565b73ffffffffffffffffffffffffffffffffffffffff8916600081815260d060209081526040808320878452909152902091909155610d599033308a612cb4565b33600090815260d16020526040812054889103610da657633b9aca00856040015167ffffffffffffffff1682610d8f919061441d565b610d9991906143e2565b610da390826143a3565b90505b610db08782612d12565b9450505050505b9392505050565b600033610dcc858285612e32565b610dd7858585612f03565b506001949350505050565b33600090815260cc602052604090205460ff16610e2b576040517ff8d2906c00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b610e3581836131b6565b5050565b60cd546040517fe43581b800000000000000000000000000000000000000000000000000000000815233600482015273ffffffffffffffffffffffffffffffffffffffff9091169063e43581b890602401602060405180830381865afa158015610ea7573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610ecb9190614357565b610f01576040517fee3675d400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015273ffffffffffffffffffffffffffffffffffffffff8216906370a0823190602401602060405180830381865afa158015610f6b573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610f8f91906143b6565b15610fc6576040517f2ef630ec00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff8116600090815260ce602052604081208181556001810182905560020180547fffffffffffffffffffffffffffffffffffffffffffff0000000000000000000016905560cf54905b61102e6001836143a3565b811015611139578273ffffffffffffffffffffffffffffffffffffffff1660cf828154811061105f5761105f614434565b60009182526020909120015473ffffffffffffffffffffffffffffffffffffffff16036111295760cf6110936001846143a3565b815481106110a3576110a3614434565b60009182526020909120015460cf805473ffffffffffffffffffffffffffffffffffffffff90921691839081106110dc576110dc614434565b9060005260206000200160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550611139565b61113281614463565b9050611023565b5060cf80548061114b5761114b61449b565b60008281526020812082017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff90810180547fffffffffffffffffffffffff000000000000000000000000000000000000000016905590910190915560405173ffffffffffffffffffffffffffffffffffffffff8416917f5c95b49c4d59d97a2f044167723f29c74b30f99702e3fd406c3830160aa9ccb891a25050565b60cd5473ffffffffffffffffffffffffffffffffffffffff16331480159061122657503373ffffffffffffffffffffffffffffffffffffffff821614155b1561125d576040517fddb5de5e00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff8116600081815260cc602052604080822080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00169055517f98c15241d6c02bc5ee0b780e11b3ea737a2defd9d04877edbe9f9497065bd02f9190a250565b33600090815260cc602052604090205460ff1661131a576040517ff8d2906c00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff16146113d05773ffffffffffffffffffffffffffffffffffffffff828116600090815260346020908152604080832093851683529290522054838110156113ba576040517f715ec26c00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6113ce83836113c987856143a3565b612a35565b505b61082d82846131b6565b60006113e46133a3565b905090565b60cd546040517f521d4de900000000000000000000000000000000000000000000000000000000815233600482015273ffffffffffffffffffffffffffffffffffffffff9091169063521d4de990602401602060405180830381865afa158015611457573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061147b9190614357565b6114b1576040517f99e120bc00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff8216600090815260ce602052604090206002015468010000000000000000900460ff1661151f576040517fc1ab6dc100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff8216600081815260ce602052604090819020839055517fe7b113fba37131b6396680a0c55790a697ec975e198ff8cfd89dac90a6379e61906109899084815260200190565b33600081815260346020908152604080832073ffffffffffffffffffffffffffffffffffffffff871684529091528120549091906109a390829086906113c99087906143cf565b60cd546040517f521d4de900000000000000000000000000000000000000000000000000000000815233600482015273ffffffffffffffffffffffffffffffffffffffff9091169063521d4de990602401602060405180830381865afa15801561162e573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906116529190614357565b611688576040517f99e120bc00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60d28190556040518181527fc3b69829afe2345596a02c8b587d41f796ba0094481d899e1b2e07b7532a1e219060200160405180910390a150565b33600090815260cc602052604090205460ff1661170c576040517ff8d2906c00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b610e358282612d12565b73ffffffffffffffffffffffffffffffffffffffff8116600090815260d06020526040812081611748610e10426143e2565b8152602001908152602001600020549050919050565b60cd546040517f521d4de900000000000000000000000000000000000000000000000000000000815233600482015273ffffffffffffffffffffffffffffffffffffffff9091169063521d4de990602401602060405180830381865afa1580156117cc573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906117f09190614357565b611826576040517f99e120bc00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff8216600090815260ce602052604090206002015468010000000000000000900460ff16611894576040517fc1ab6dc100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff8216600081815260ce602052604090819020600101839055517fe13ac9338b2ee623233f83c1b3ceab16490fa3e3737fac7f0970d0830a9f4871906109899084815260200190565b60cd546040517fe43581b800000000000000000000000000000000000000000000000000000000815233600482015273ffffffffffffffffffffffffffffffffffffffff9091169063e43581b890602401602060405180830381865afa15801561195f573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906119839190614357565b6119b9576040517fee3675d400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff8516600090815260ce602052604090206002015468010000000000000000900460ff1680611a10575073ffffffffffffffffffffffffffffffffffffffff8516155b15611a47576040517fc1ab6dc100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b633b9aca008267ffffffffffffffff161115611a8f576040517feca1d2c600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040805160a08101825260008082526020820181905291810182905260608101829052608081019190915284815260208082018581528315156080840190815267ffffffffffffffff808716604080870191825260016060880181815273ffffffffffffffffffffffffffffffffffffffff8e16600081815260ce9099528389208a5181559751888401559351600290970180549151965115156901000000000000000000027fffffffffffffffffffffffffffffffffffffffffffff00ffffffffffffffffff97151568010000000000000000027fffffffffffffffffffffffffffffffffffffffffffffff000000000000000000909316989096169790971717949094169290921790935560cf805492830181559093527facb8d954e2cfef495862221e91bd7523613cf8808827cb33edfe4904cc51bf290180547fffffffffffffffffffffffff0000000000000000000000000000000000000000168217905590517f53087ff85d80a7671594bd2e86b92af22e0b3c2c441c8033bba7399b7b5cbe2390611c49908890889088908890938452602084019290925267ffffffffffffffff1660408301521515606082015260800190565b60405180910390a2505050505050565b600060d381611c6a610e10426143e2565b815260200190815260200160002054905090565b73ffffffffffffffffffffffffffffffffffffffff81166000908152609960205260408120546109a9565b611cb333826131b6565b50565b60606037805461079f9061430a565b60cd5473ffffffffffffffffffffffffffffffffffffffff163314611d16576040517fb90cdbb100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff8116600081815260cc602052604080822080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00166001179055517f98c15241d6c02bc5ee0b780e11b3ea737a2defd9d04877edbe9f9497065bd02f9190a250565b60cd546040517f521d4de900000000000000000000000000000000000000000000000000000000815233600482015273ffffffffffffffffffffffffffffffffffffffff9091169063521d4de990602401602060405180830381865afa158015611dfb573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611e1f9190614357565b611e55576040517f99e120bc00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff8216600090815260ce602052604090206002015468010000000000000000900460ff16611ec3576040517fc1ab6dc100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b633b9aca008167ffffffffffffffff161115611f0b576040517feca1d2c600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff8216600081815260ce602090815260409182902060020180547fffffffffffffffffffffffffffffffffffffffffffffffff00000000000000001667ffffffffffffffff861690811790915591519182527f901f9de19b475adc8da4110434b8df940dce085afd05e2281c86807f3a899d299101610989565b33600081815260346020908152604080832073ffffffffffffffffffffffffffffffffffffffff8716845290915281205490919083811015612062576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602560248201527f45524332303a2064656372656173656420616c6c6f77616e63652062656c6f7760448201527f207a65726f00000000000000000000000000000000000000000000000000000060648201526084015b60405180910390fd5b610dd78286868403612a35565b6000336109a3818585612f03565b60cf818154811061208d57600080fd5b60009182526020909120015473ffffffffffffffffffffffffffffffffffffffff16905081565b606060cf80548060200260200160405190810160405280929190818152602001828054801561081857602002820191906000526020600020905b815473ffffffffffffffffffffffffffffffffffffffff1681526001909101906020018083116120ee575050505050905090565b73ffffffffffffffffffffffffffffffffffffffff8316600090815260ce60209081526040808320815160a081018352815481526001820154938101939093526002015467ffffffffffffffff81169183019190915260ff6801000000000000000082048116158015606085015269010000000000000000009092041615156080830152806121b2575080608001515b156121e9576040517fc1ab6dc100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60006121f7610e10426143e2565b600081815260d36020526040812054919250906122159087906143cf565b905060d254811115612253576040517f6d43d1ac00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600082815260d36020526040902081905561226e33876131b6565b33600090815260d160205260408120548791036122bb57633b9aca00846040015167ffffffffffffffff16826122a4919061441d565b6122ae91906143e2565b6122b890826143a3565b90505b6122dc73ffffffffffffffffffffffffffffffffffffffff89168783612be0565b979650505050505050565b83421115612351576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f45524332305065726d69743a206578706972656420646561646c696e650000006044820152606401612059565b60007f6e71edae12b1b97f4d1f60370fef10105fa2faae0126114a169c64845d6126c98888886123808c61341e565b60408051602081019690965273ffffffffffffffffffffffffffffffffffffffff94851690860152929091166060840152608083015260a082015260c0810186905260e00160405160208183030381529060405280519060200120905060006123e882613453565b905060006123f8828787876134bc565b90508973ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff161461248f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601e60248201527f45524332305065726d69743a20696e76616c6964207369676e617475726500006044820152606401612059565b61249a8a8a8a612a35565b50505050505050505050565b60cd546040517f521d4de900000000000000000000000000000000000000000000000000000000815233600482015273ffffffffffffffffffffffffffffffffffffffff9091169063521d4de990602401602060405180830381865afa158015612514573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906125389190614357565b61256e576040517f99e120bc00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff8116600090815260ce602052604090206002015468010000000000000000900460ff166125dc576040517fc1ab6dc100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff8116600081815260ce602090815260409182902060020180547fffffffffffffffffffffffffffffffffffffffffffff00ffffffffffffffffff811669010000000000000000009182900460ff16801592830291909117909255925192835292917ff7c93079dcbf699749d66345a351afab7d24219bb1d915c9f4fc4cf03f00d3979101610989565b60cd5473ffffffffffffffffffffffffffffffffffffffff1633146126cb576040517fb90cdbb100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60cd80547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83169081179091556040517f7dae230f18360d76a040c81f050aa14eb9d6dc7901b20fc5d855e2a20fe814d190600090a250565b73ffffffffffffffffffffffffffffffffffffffff163b151590565b600054610100900460ff16158080156127765750600054600160ff909116105b806127905750303b158015612790575060005460ff166001145b61281c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201527f647920696e697469616c697a65640000000000000000000000000000000000006064820152608401612059565b600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00166001179055801561287a57600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff166101001790555b3073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1663e9cbd8226040518163ffffffff1660e01b8152600401602060405180830381865afa1580156128dc573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061290091906144ca565b73ffffffffffffffffffffffffffffffffffffffff161461294d576040517f14bcf5c800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b612956846134e4565b61296084846135ba565b60cd80547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff84169081179091556040517f7dae230f18360d76a040c81f050aa14eb9d6dc7901b20fc5d855e2a20fe814d190600090a28015612a2f57600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15b50505050565b73ffffffffffffffffffffffffffffffffffffffff8316612ad7576040517f08c379a0000000000000000000000000000000000000000000000000000000008152602060048201526024808201527f45524332303a20617070726f76652066726f6d20746865207a65726f2061646460448201527f72657373000000000000000000000000000000000000000000000000000000006064820152608401612059565b73ffffffffffffffffffffffffffffffffffffffff8216612b7a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602260248201527f45524332303a20617070726f766520746f20746865207a65726f20616464726560448201527f73730000000000000000000000000000000000000000000000000000000000006064820152608401612059565b73ffffffffffffffffffffffffffffffffffffffff83811660008181526034602090815260408083209487168084529482529182902085905590518481527f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b9259101610af7565b60405173ffffffffffffffffffffffffffffffffffffffff831660248201526044810182905261082d9084907fa9059cbb00000000000000000000000000000000000000000000000000000000906064015b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff000000000000000000000000000000000000000000000000000000009093169290921790915261365b565b60405173ffffffffffffffffffffffffffffffffffffffff80851660248301528316604482015260648101829052612a2f9085907f23b872dd0000000000000000000000000000000000000000000000000000000090608401612c32565b73ffffffffffffffffffffffffffffffffffffffff8216612d8f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601f60248201527f45524332303a206d696e7420746f20746865207a65726f2061646472657373006044820152606401612059565b8060356000828254612da191906143cf565b909155505073ffffffffffffffffffffffffffffffffffffffff821660009081526033602052604081208054839290612ddb9084906143cf565b909155505060405181815273ffffffffffffffffffffffffffffffffffffffff8316906000907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef9060200160405180910390a35050565b73ffffffffffffffffffffffffffffffffffffffff8381166000908152603460209081526040808320938616835292905220547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8114612a2f5781811015612ef6576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f45524332303a20696e73756666696369656e7420616c6c6f77616e63650000006044820152606401612059565b612a2f8484848403612a35565b73ffffffffffffffffffffffffffffffffffffffff8316612fa6576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602560248201527f45524332303a207472616e736665722066726f6d20746865207a65726f20616460448201527f64726573730000000000000000000000000000000000000000000000000000006064820152608401612059565b73ffffffffffffffffffffffffffffffffffffffff8216613049576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602360248201527f45524332303a207472616e7366657220746f20746865207a65726f206164647260448201527f65737300000000000000000000000000000000000000000000000000000000006064820152608401612059565b73ffffffffffffffffffffffffffffffffffffffff8316600090815260336020526040902054818110156130ff576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f45524332303a207472616e7366657220616d6f756e742065786365656473206260448201527f616c616e636500000000000000000000000000000000000000000000000000006064820152608401612059565b73ffffffffffffffffffffffffffffffffffffffff8085166000908152603360205260408082208585039055918516815290812080548492906131439084906143cf565b925050819055508273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef846040516131a991815260200190565b60405180910390a3612a2f565b73ffffffffffffffffffffffffffffffffffffffff8216613259576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602160248201527f45524332303a206275726e2066726f6d20746865207a65726f2061646472657360448201527f73000000000000000000000000000000000000000000000000000000000000006064820152608401612059565b73ffffffffffffffffffffffffffffffffffffffff82166000908152603360205260409020548181101561330f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602260248201527f45524332303a206275726e20616d6f756e7420657863656564732062616c616e60448201527f63650000000000000000000000000000000000000000000000000000000000006064820152608401612059565b73ffffffffffffffffffffffffffffffffffffffff8316600090815260336020526040812083830390556035805484929061334b9084906143a3565b909155505060405182815260009073ffffffffffffffffffffffffffffffffffffffff8516907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef9060200160405180910390a3505050565b60006113e47f8b73c3c69bb8fe3d512ecc4cf759cc79239f7b179b0ffacaa9a75d522b39400f6133d260655490565b6066546040805160208101859052908101839052606081018290524660808201523060a082015260009060c0016040516020818303038152906040528051906020012090509392505050565b73ffffffffffffffffffffffffffffffffffffffff811660009081526099602052604090208054600181018255905b50919050565b60006109a96134606133a3565b836040517f19010000000000000000000000000000000000000000000000000000000000006020820152602281018390526042810182905260009060620160405160208183030381529060405280519060200120905092915050565b60008060006134cd87878787613767565b915091506134da8161387f565b5095945050505050565b600054610100900460ff1661357b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201527f6e697469616c697a696e670000000000000000000000000000000000000000006064820152608401612059565b611cb3816040518060400160405280600181526020017f3100000000000000000000000000000000000000000000000000000000000000815250613ad3565b600054610100900460ff16613651576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201527f6e697469616c697a696e670000000000000000000000000000000000000000006064820152608401612059565b610e358282613b84565b60006136bd826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c65648152508573ffffffffffffffffffffffffffffffffffffffff16613c349092919063ffffffff16565b80519091501561082d57808060200190518101906136db9190614357565b61082d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e60448201527f6f742073756363656564000000000000000000000000000000000000000000006064820152608401612059565b6000807f7fffffffffffffffffffffffffffffff5d576e7357a4501ddfe92f46681b20a083111561379e5750600090506003613876565b8460ff16601b141580156137b657508460ff16601c14155b156137c75750600090506004613876565b6040805160008082526020820180845289905260ff881692820192909252606081018690526080810185905260019060a0016020604051602081039080840390855afa15801561381b573d6000803e3d6000fd5b50506040517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0015191505073ffffffffffffffffffffffffffffffffffffffff811661386f57600060019250925050613876565b9150600090505b94509492505050565b6000816004811115613893576138936144e7565b0361389b5750565b60018160048111156138af576138af6144e7565b03613916576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601860248201527f45434453413a20696e76616c6964207369676e617475726500000000000000006044820152606401612059565b600281600481111561392a5761392a6144e7565b03613991576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601f60248201527f45434453413a20696e76616c6964207369676e6174757265206c656e677468006044820152606401612059565b60038160048111156139a5576139a56144e7565b03613a32576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602260248201527f45434453413a20696e76616c6964207369676e6174757265202773272076616c60448201527f75650000000000000000000000000000000000000000000000000000000000006064820152608401612059565b6004816004811115613a4657613a466144e7565b03611cb3576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602260248201527f45434453413a20696e76616c6964207369676e6174757265202776272076616c60448201527f75650000000000000000000000000000000000000000000000000000000000006064820152608401612059565b600054610100900460ff16613b6a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201527f6e697469616c697a696e670000000000000000000000000000000000000000006064820152608401612059565b815160209283012081519190920120606591909155606655565b600054610100900460ff16613c1b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201527f6e697469616c697a696e670000000000000000000000000000000000000000006064820152608401612059565b6036613c278382614564565b50603761082d8282614564565b6060613c438484600085613c4b565b949350505050565b606082471015613cdd576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f60448201527f722063616c6c00000000000000000000000000000000000000000000000000006064820152608401612059565b73ffffffffffffffffffffffffffffffffffffffff85163b613d5b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006044820152606401612059565b6000808673ffffffffffffffffffffffffffffffffffffffff168587604051613d84919061467e565b60006040518083038185875af1925050503d8060008114613dc1576040519150601f19603f3d011682016040523d82523d6000602084013e613dc6565b606091505b50915091506122dc82828660608315613de0575081610db7565b825115613df05782518084602001fd5b816040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016120599190613e48565b60005b83811015613e3f578181015183820152602001613e27565b50506000910152565b6020815260008251806020840152613e67816040850160208701613e24565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169190910160400192915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b600082601f830112613ed957600080fd5b813567ffffffffffffffff80821115613ef457613ef4613e99565b604051601f83017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0908116603f01168101908282118183101715613f3a57613f3a613e99565b81604052838152866020858801011115613f5357600080fd5b836020870160208301376000602085830101528094505050505092915050565b73ffffffffffffffffffffffffffffffffffffffff81168114611cb357600080fd5b600080600060608486031215613faa57600080fd5b833567ffffffffffffffff80821115613fc257600080fd5b613fce87838801613ec8565b94506020860135915080821115613fe457600080fd5b50613ff186828701613ec8565b925050604084013561400281613f73565b809150509250925092565b60006020828403121561401f57600080fd5b8135610db781613f73565b6000806040838503121561403d57600080fd5b823561404881613f73565b946020939093013593505050565b60008060006060848603121561406b57600080fd5b833561407681613f73565b9250602084013561408681613f73565b929592945050506040919091013590565b6000806000606084860312156140ac57600080fd5b83356140b781613f73565b925060208401359150604084013561400281613f73565b600080604083850312156140e157600080fd5b8235915060208301356140f381613f73565b809150509250929050565b60008060006060848603121561411357600080fd5b83359250602084013561412581613f73565b9150604084013561400281613f73565b60006020828403121561414757600080fd5b5035919050565b803567ffffffffffffffff8116811461416657600080fd5b919050565b8015158114611cb357600080fd5b600080600080600060a0868803121561419157600080fd5b853561419c81613f73565b945060208601359350604086013592506141b86060870161414e565b915060808601356141c88161416b565b809150509295509295909350565b600080604083850312156141e957600080fd5b82356141f481613f73565b91506142026020840161414e565b90509250929050565b6020808252825182820181905260009190848201906040850190845b8181101561425957835173ffffffffffffffffffffffffffffffffffffffff1683529284019291840191600101614227565b50909695505050505050565b600080600080600080600060e0888a03121561428057600080fd5b873561428b81613f73565b9650602088013561429b81613f73565b95506040880135945060608801359350608088013560ff811681146142bf57600080fd5b9699959850939692959460a0840135945060c09093013592915050565b600080604083850312156142ef57600080fd5b82356142fa81613f73565b915060208301356140f381613f73565b600181811c9082168061431e57607f821691505b60208210810361344d577f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b60006020828403121561436957600080fd5b8151610db78161416b565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b818103818111156109a9576109a9614374565b6000602082840312156143c857600080fd5b5051919050565b808201808211156109a9576109a9614374565b600082614418577f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b500490565b80820281158282048414176109a9576109a9614374565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff820361449457614494614374565b5060010190565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603160045260246000fd5b6000602082840312156144dc57600080fd5b8151610db781613f73565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b601f82111561082d57600081815260208120601f850160051c8101602086101561453d5750805b601f850160051c820191505b8181101561455c57828155600101614549565b505050505050565b815167ffffffffffffffff81111561457e5761457e613e99565b6145928161458c845461430a565b84614516565b602080601f8311600181146145e557600084156145af5750858301515b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600386901b1c1916600185901b17855561455c565b6000858152602081207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08616915b8281101561463257888601518255948401946001909101908401614613565b508582101561466e57878501517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600388901b60f8161c191681555b5050505050600190811b01905550565b60008251614690818460208701613e24565b919091019291505056fea2646970667358221220f2eb02bac1667a72be85ab617a5b5aa3d8f7a9b09b4d1fde9756b7a5636daf2164736f6c63430008110033", "devdoc": { - "author": "Angle Core Team", - "details": "This contract supports bridge tokens having a minting right on the stablecoin (also referred to as the canonical or the native token)References: - FRAX implementation: https://polygonscan.com/address/0x45c32fA6DF82ead1e2EF74d17b76547EDdFaFF89#code - QiDAO implementation: https://snowtrace.io/address/0x5c49b268c9841AFF1Cc3B0a418ff5c3442eE3F3b#code", + "author": "Angle Labs, Inc.", + "details": "This contract supports bridge tokens having a minting right on the stablecoin (also referred to as the canonical or the native token)", "kind": "dev", "methods": { "DOMAIN_SEPARATOR()": { @@ -1249,7 +1276,7 @@ "details": "See {IERC20-allowance}." }, "approve(address,uint256)": { - "details": "See {IERC20-approve}. Requirements: - `spender` cannot be the zero address." + "details": "See {IERC20-approve}. NOTE: If `amount` is the maximum `uint256`, the allowance is not updated on `transferFrom`. This is semantically equivalent to an infinite approval. Requirements: - `spender` cannot be the zero address." }, "balanceOf(address)": { "details": "See {IERC20-balanceOf}." @@ -1293,14 +1320,6 @@ "increaseAllowance(address,uint256)": { "details": "Atomically increases the allowance granted to `spender` by the caller. This is an alternative to {approve} that can be used as a mitigation for problems described in {IERC20-approve}. Emits an {Approval} event indicating the updated allowance. Requirements: - `spender` cannot be the zero address." }, - "initialize(string,string,address)": { - "details": "By default, agTokens are ERC-20 tokens with 18 decimals", - "params": { - "_treasury": "Reference to the `Treasury` contract associated to this agToken", - "name_": "Name of the token", - "symbol_": "Symbol of the token" - } - }, "mint(address,uint256)": { "details": "The contracts allowed to issue agTokens are the `StableMaster` contract, `VaultManager` contracts associated to this stablecoin as well as the flash loan module (if activated) and potentially contracts whitelisted by governance", "params": { @@ -1365,10 +1384,10 @@ "details": "See {IERC20-totalSupply}." }, "transfer(address,uint256)": { - "details": "See {IERC20-transfer}. Requirements: - `recipient` cannot be the zero address. - the caller must have a balance of at least `amount`." + "details": "See {IERC20-transfer}. Requirements: - `to` cannot be the zero address. - the caller must have a balance of at least `amount`." }, "transferFrom(address,address,uint256)": { - "details": "See {IERC20-transferFrom}. Emits an {Approval} event indicating the updated allowance. This is not required by the EIP. See the note at the beginning of {ERC20}. Requirements: - `sender` and `recipient` cannot be the zero address. - `sender` must have a balance of at least `amount`. - the caller must have allowance for ``sender``'s tokens of at least `amount`." + "details": "See {IERC20-transferFrom}. Emits an {Approval} event indicating the updated allowance. This is not required by the EIP. See the note at the beginning of {ERC20}. NOTE: Does not update the allowance if the current allowance is the maximum `uint256`. Requirements: - `from` and `to` cannot be the zero address. - `from` must have a balance of at least `amount`. - the caller must have allowance for ``from``'s tokens of at least `amount`." } }, "title": "AgTokenSideChainMultiBridge", @@ -1402,7 +1421,7 @@ "notice": "Burns `amount` tokens from a `burner` address" }, "burnStablecoin(uint256)": { - "notice": "Allows anyone to burn agToken without redeeming collateral back" + "notice": "Allows anyone to burn stablecoins" }, "chainTotalHourlyLimit()": { "notice": "Limit to the amount of tokens that can be sent from that chain to another chain" @@ -1477,15 +1496,15 @@ "storageLayout": { "storage": [ { - "astId": 772, + "astId": 770, "contract": "contracts/agToken/AgTokenSideChainMultiBridge.sol:AgTokenSideChainMultiBridge", "label": "_initialized", "offset": 0, "slot": "0", - "type": "t_bool" + "type": "t_uint8" }, { - "astId": 775, + "astId": 773, "contract": "contracts/agToken/AgTokenSideChainMultiBridge.sol:AgTokenSideChainMultiBridge", "label": "_initializing", "offset": 1, @@ -1493,7 +1512,7 @@ "type": "t_bool" }, { - "astId": 2592, + "astId": 2486, "contract": "contracts/agToken/AgTokenSideChainMultiBridge.sol:AgTokenSideChainMultiBridge", "label": "__gap", "offset": 0, @@ -1501,7 +1520,7 @@ "type": "t_array(t_uint256)50_storage" }, { - "astId": 1029, + "astId": 1119, "contract": "contracts/agToken/AgTokenSideChainMultiBridge.sol:AgTokenSideChainMultiBridge", "label": "_balances", "offset": 0, @@ -1509,7 +1528,7 @@ "type": "t_mapping(t_address,t_uint256)" }, { - "astId": 1035, + "astId": 1125, "contract": "contracts/agToken/AgTokenSideChainMultiBridge.sol:AgTokenSideChainMultiBridge", "label": "_allowances", "offset": 0, @@ -1517,7 +1536,7 @@ "type": "t_mapping(t_address,t_mapping(t_address,t_uint256))" }, { - "astId": 1037, + "astId": 1127, "contract": "contracts/agToken/AgTokenSideChainMultiBridge.sol:AgTokenSideChainMultiBridge", "label": "_totalSupply", "offset": 0, @@ -1525,7 +1544,7 @@ "type": "t_uint256" }, { - "astId": 1039, + "astId": 1129, "contract": "contracts/agToken/AgTokenSideChainMultiBridge.sol:AgTokenSideChainMultiBridge", "label": "_name", "offset": 0, @@ -1533,7 +1552,7 @@ "type": "t_string_storage" }, { - "astId": 1041, + "astId": 1131, "contract": "contracts/agToken/AgTokenSideChainMultiBridge.sol:AgTokenSideChainMultiBridge", "label": "_symbol", "offset": 0, @@ -1541,7 +1560,7 @@ "type": "t_string_storage" }, { - "astId": 1582, + "astId": 1710, "contract": "contracts/agToken/AgTokenSideChainMultiBridge.sol:AgTokenSideChainMultiBridge", "label": "__gap", "offset": 0, @@ -1549,7 +1568,7 @@ "type": "t_array(t_uint256)45_storage" }, { - "astId": 3269, + "astId": 3203, "contract": "contracts/agToken/AgTokenSideChainMultiBridge.sol:AgTokenSideChainMultiBridge", "label": "_HASHED_NAME", "offset": 0, @@ -1557,7 +1576,7 @@ "type": "t_bytes32" }, { - "astId": 3271, + "astId": 3205, "contract": "contracts/agToken/AgTokenSideChainMultiBridge.sol:AgTokenSideChainMultiBridge", "label": "_HASHED_VERSION", "offset": 0, @@ -1565,7 +1584,7 @@ "type": "t_bytes32" }, { - "astId": 3408, + "astId": 3343, "contract": "contracts/agToken/AgTokenSideChainMultiBridge.sol:AgTokenSideChainMultiBridge", "label": "__gap", "offset": 0, @@ -1573,23 +1592,23 @@ "type": "t_array(t_uint256)50_storage" }, { - "astId": 1712, + "astId": 1840, "contract": "contracts/agToken/AgTokenSideChainMultiBridge.sol:AgTokenSideChainMultiBridge", "label": "_nonces", "offset": 0, "slot": "153", - "type": "t_mapping(t_address,t_struct(Counter)2599_storage)" + "type": "t_mapping(t_address,t_struct(Counter)2493_storage)" }, { - "astId": 1714, + "astId": 1848, "contract": "contracts/agToken/AgTokenSideChainMultiBridge.sol:AgTokenSideChainMultiBridge", - "label": "_PERMIT_TYPEHASH", + "label": "_PERMIT_TYPEHASH_DEPRECATED_SLOT", "offset": 0, "slot": "154", "type": "t_bytes32" }, { - "astId": 1882, + "astId": 2004, "contract": "contracts/agToken/AgTokenSideChainMultiBridge.sol:AgTokenSideChainMultiBridge", "label": "__gap", "offset": 0, @@ -1597,7 +1616,7 @@ "type": "t_array(t_uint256)49_storage" }, { - "astId": 8835, + "astId": 7427, "contract": "contracts/agToken/AgTokenSideChainMultiBridge.sol:AgTokenSideChainMultiBridge", "label": "isMinter", "offset": 0, @@ -1605,7 +1624,7 @@ "type": "t_mapping(t_address,t_bool)" }, { - "astId": 8838, + "astId": 7430, "contract": "contracts/agToken/AgTokenSideChainMultiBridge.sol:AgTokenSideChainMultiBridge", "label": "treasury", "offset": 0, @@ -1613,15 +1632,15 @@ "type": "t_address" }, { - "astId": 7979, + "astId": 7739, "contract": "contracts/agToken/AgTokenSideChainMultiBridge.sol:AgTokenSideChainMultiBridge", "label": "bridges", "offset": 0, "slot": "206", - "type": "t_mapping(t_address,t_struct(BridgeDetails)7973_storage)" + "type": "t_mapping(t_address,t_struct(BridgeDetails)7733_storage)" }, { - "astId": 7983, + "astId": 7743, "contract": "contracts/agToken/AgTokenSideChainMultiBridge.sol:AgTokenSideChainMultiBridge", "label": "bridgeTokensList", "offset": 0, @@ -1629,7 +1648,7 @@ "type": "t_array(t_address)dyn_storage" }, { - "astId": 7990, + "astId": 7750, "contract": "contracts/agToken/AgTokenSideChainMultiBridge.sol:AgTokenSideChainMultiBridge", "label": "usage", "offset": 0, @@ -1637,7 +1656,7 @@ "type": "t_mapping(t_address,t_mapping(t_uint256,t_uint256))" }, { - "astId": 7995, + "astId": 7755, "contract": "contracts/agToken/AgTokenSideChainMultiBridge.sol:AgTokenSideChainMultiBridge", "label": "isFeeExempt", "offset": 0, @@ -1645,7 +1664,7 @@ "type": "t_mapping(t_address,t_uint256)" }, { - "astId": 7998, + "astId": 7758, "contract": "contracts/agToken/AgTokenSideChainMultiBridge.sol:AgTokenSideChainMultiBridge", "label": "chainTotalHourlyLimit", "offset": 0, @@ -1653,7 +1672,7 @@ "type": "t_uint256" }, { - "astId": 8003, + "astId": 7763, "contract": "contracts/agToken/AgTokenSideChainMultiBridge.sol:AgTokenSideChainMultiBridge", "label": "chainTotalUsage", "offset": 0, @@ -1722,19 +1741,19 @@ "numberOfBytes": "32", "value": "t_mapping(t_uint256,t_uint256)" }, - "t_mapping(t_address,t_struct(BridgeDetails)7973_storage)": { + "t_mapping(t_address,t_struct(BridgeDetails)7733_storage)": { "encoding": "mapping", "key": "t_address", "label": "mapping(address => struct AgTokenSideChainMultiBridge.BridgeDetails)", "numberOfBytes": "32", - "value": "t_struct(BridgeDetails)7973_storage" + "value": "t_struct(BridgeDetails)7733_storage" }, - "t_mapping(t_address,t_struct(Counter)2599_storage)": { + "t_mapping(t_address,t_struct(Counter)2493_storage)": { "encoding": "mapping", "key": "t_address", "label": "mapping(address => struct CountersUpgradeable.Counter)", "numberOfBytes": "32", - "value": "t_struct(Counter)2599_storage" + "value": "t_struct(Counter)2493_storage" }, "t_mapping(t_address,t_uint256)": { "encoding": "mapping", @@ -1755,12 +1774,12 @@ "label": "string", "numberOfBytes": "32" }, - "t_struct(BridgeDetails)7973_storage": { + "t_struct(BridgeDetails)7733_storage": { "encoding": "inplace", "label": "struct AgTokenSideChainMultiBridge.BridgeDetails", "members": [ { - "astId": 7964, + "astId": 7724, "contract": "contracts/agToken/AgTokenSideChainMultiBridge.sol:AgTokenSideChainMultiBridge", "label": "limit", "offset": 0, @@ -1768,7 +1787,7 @@ "type": "t_uint256" }, { - "astId": 7966, + "astId": 7726, "contract": "contracts/agToken/AgTokenSideChainMultiBridge.sol:AgTokenSideChainMultiBridge", "label": "hourlyLimit", "offset": 0, @@ -1776,7 +1795,7 @@ "type": "t_uint256" }, { - "astId": 7968, + "astId": 7728, "contract": "contracts/agToken/AgTokenSideChainMultiBridge.sol:AgTokenSideChainMultiBridge", "label": "fee", "offset": 0, @@ -1784,7 +1803,7 @@ "type": "t_uint64" }, { - "astId": 7970, + "astId": 7730, "contract": "contracts/agToken/AgTokenSideChainMultiBridge.sol:AgTokenSideChainMultiBridge", "label": "allowed", "offset": 8, @@ -1792,7 +1811,7 @@ "type": "t_bool" }, { - "astId": 7972, + "astId": 7732, "contract": "contracts/agToken/AgTokenSideChainMultiBridge.sol:AgTokenSideChainMultiBridge", "label": "paused", "offset": 9, @@ -1802,12 +1821,12 @@ ], "numberOfBytes": "96" }, - "t_struct(Counter)2599_storage": { + "t_struct(Counter)2493_storage": { "encoding": "inplace", "label": "struct CountersUpgradeable.Counter", "members": [ { - "astId": 2598, + "astId": 2492, "contract": "contracts/agToken/AgTokenSideChainMultiBridge.sol:AgTokenSideChainMultiBridge", "label": "_value", "offset": 0, @@ -1826,6 +1845,11 @@ "encoding": "inplace", "label": "uint64", "numberOfBytes": "8" + }, + "t_uint8": { + "encoding": "inplace", + "label": "uint8", + "numberOfBytes": "1" } } } diff --git a/deployments/arbitrum/CoreBorrowTest.json b/deployments/arbitrum/CoreBorrowTest.json new file mode 100644 index 00000000..38ef8076 --- /dev/null +++ b/deployments/arbitrum/CoreBorrowTest.json @@ -0,0 +1,325 @@ +{ + "address": "0xb38Ba207d02f07653a37b53C1C0a250B04F97e82", + "abi": [ + { + "inputs": [ + { + "internalType": "address", + "name": "_logic", + "type": "address" + }, + { + "internalType": "address", + "name": "admin_", + "type": "address" + }, + { + "internalType": "bytes", + "name": "_data", + "type": "bytes" + } + ], + "stateMutability": "payable", + "type": "constructor" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "previousAdmin", + "type": "address" + }, + { + "indexed": false, + "internalType": "address", + "name": "newAdmin", + "type": "address" + } + ], + "name": "AdminChanged", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "beacon", + "type": "address" + } + ], + "name": "BeaconUpgraded", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "implementation", + "type": "address" + } + ], + "name": "Upgraded", + "type": "event" + }, + { + "stateMutability": "payable", + "type": "fallback" + }, + { + "inputs": [], + "name": "admin", + "outputs": [ + { + "internalType": "address", + "name": "admin_", + "type": "address" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "newAdmin", + "type": "address" + } + ], + "name": "changeAdmin", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "implementation", + "outputs": [ + { + "internalType": "address", + "name": "implementation_", + "type": "address" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "newImplementation", + "type": "address" + } + ], + "name": "upgradeTo", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "newImplementation", + "type": "address" + }, + { + "internalType": "bytes", + "name": "data", + "type": "bytes" + } + ], + "name": "upgradeToAndCall", + "outputs": [], + "stateMutability": "payable", + "type": "function" + }, + { + "stateMutability": "payable", + "type": "receive" + } + ], + "transactionHash": "0x1f79ba2b8795194b916fe329fa8edcde0befbc0764f7b81e5b106baa8fbd5fe3", + "receipt": { + "to": null, + "from": "0xfdA462548Ce04282f4B6D6619823a7C64Fdc0185", + "contractAddress": "0xb38Ba207d02f07653a37b53C1C0a250B04F97e82", + "transactionIndex": 2, + "gasUsed": "8952695", + "logsBloom": "0x00000004000000000800000400000000480000000000000000010000200000000000002080000000000000000000000000000000000000000000000000000000000000000000002000000000000003000000000000000000000000000000000000000000020000400000000000000800000000800000000000000000000000000000000000000000000000000000000000000003000000000400000000804000000000000000000000010000000000000000000000000000001000000000001000000020020000000000008000000000000800000400000100000000000020000000800000000000008000000000000400000000000000000000000000040000", + "blockHash": "0xd77a02eda6662f3fd0fdb275d79eca91b5a6883f5700ccd51665d7246e5da93c", + "transactionHash": "0x1f79ba2b8795194b916fe329fa8edcde0befbc0764f7b81e5b106baa8fbd5fe3", + "logs": [ + { + "transactionIndex": 2, + "blockNumber": 168975714, + "transactionHash": "0x1f79ba2b8795194b916fe329fa8edcde0befbc0764f7b81e5b106baa8fbd5fe3", + "address": "0xb38Ba207d02f07653a37b53C1C0a250B04F97e82", + "topics": [ + "0xbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b", + "0x0000000000000000000000005183f032bf42109cd370b9559fd22207e432301e" + ], + "data": "0x", + "logIndex": 4, + "blockHash": "0xd77a02eda6662f3fd0fdb275d79eca91b5a6883f5700ccd51665d7246e5da93c" + }, + { + "transactionIndex": 2, + "blockNumber": 168975714, + "transactionHash": "0x1f79ba2b8795194b916fe329fa8edcde0befbc0764f7b81e5b106baa8fbd5fe3", + "address": "0xb38Ba207d02f07653a37b53C1C0a250B04F97e82", + "topics": [ + "0x2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d", + "0x7935bd0ae54bc31f548c14dba4d37c5c64b3f8ca900cb468fb8abd54d5894f55", + "0x000000000000000000000000fda462548ce04282f4b6d6619823a7c64fdc0185", + "0x000000000000000000000000fda462548ce04282f4b6d6619823a7c64fdc0185" + ], + "data": "0x", + "logIndex": 5, + "blockHash": "0xd77a02eda6662f3fd0fdb275d79eca91b5a6883f5700ccd51665d7246e5da93c" + }, + { + "transactionIndex": 2, + "blockNumber": 168975714, + "transactionHash": "0x1f79ba2b8795194b916fe329fa8edcde0befbc0764f7b81e5b106baa8fbd5fe3", + "address": "0xb38Ba207d02f07653a37b53C1C0a250B04F97e82", + "topics": [ + "0x2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d", + "0x55435dd261a4b9b3364963f7738a7a662ad9c84396d64be3365284bb7f0a5041", + "0x00000000000000000000000055f01ddae74b60e3c255bd2f619febdfce560a9c", + "0x000000000000000000000000fda462548ce04282f4b6d6619823a7c64fdc0185" + ], + "data": "0x", + "logIndex": 6, + "blockHash": "0xd77a02eda6662f3fd0fdb275d79eca91b5a6883f5700ccd51665d7246e5da93c" + }, + { + "transactionIndex": 2, + "blockNumber": 168975714, + "transactionHash": "0x1f79ba2b8795194b916fe329fa8edcde0befbc0764f7b81e5b106baa8fbd5fe3", + "address": "0xb38Ba207d02f07653a37b53C1C0a250B04F97e82", + "topics": [ + "0x2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d", + "0x55435dd261a4b9b3364963f7738a7a662ad9c84396d64be3365284bb7f0a5041", + "0x000000000000000000000000fda462548ce04282f4b6d6619823a7c64fdc0185", + "0x000000000000000000000000fda462548ce04282f4b6d6619823a7c64fdc0185" + ], + "data": "0x", + "logIndex": 7, + "blockHash": "0xd77a02eda6662f3fd0fdb275d79eca91b5a6883f5700ccd51665d7246e5da93c" + }, + { + "transactionIndex": 2, + "blockNumber": 168975714, + "transactionHash": "0x1f79ba2b8795194b916fe329fa8edcde0befbc0764f7b81e5b106baa8fbd5fe3", + "address": "0xb38Ba207d02f07653a37b53C1C0a250B04F97e82", + "topics": [ + "0xbd79b86ffe0ab8e8776151514217cd7cacd52c909f66475c3af44e129f0b00ff", + "0x55435dd261a4b9b3364963f7738a7a662ad9c84396d64be3365284bb7f0a5041", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x7935bd0ae54bc31f548c14dba4d37c5c64b3f8ca900cb468fb8abd54d5894f55" + ], + "data": "0x", + "logIndex": 8, + "blockHash": "0xd77a02eda6662f3fd0fdb275d79eca91b5a6883f5700ccd51665d7246e5da93c" + }, + { + "transactionIndex": 2, + "blockNumber": 168975714, + "transactionHash": "0x1f79ba2b8795194b916fe329fa8edcde0befbc0764f7b81e5b106baa8fbd5fe3", + "address": "0xb38Ba207d02f07653a37b53C1C0a250B04F97e82", + "topics": [ + "0xbd79b86ffe0ab8e8776151514217cd7cacd52c909f66475c3af44e129f0b00ff", + "0x7935bd0ae54bc31f548c14dba4d37c5c64b3f8ca900cb468fb8abd54d5894f55", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x7935bd0ae54bc31f548c14dba4d37c5c64b3f8ca900cb468fb8abd54d5894f55" + ], + "data": "0x", + "logIndex": 9, + "blockHash": "0xd77a02eda6662f3fd0fdb275d79eca91b5a6883f5700ccd51665d7246e5da93c" + }, + { + "transactionIndex": 2, + "blockNumber": 168975714, + "transactionHash": "0x1f79ba2b8795194b916fe329fa8edcde0befbc0764f7b81e5b106baa8fbd5fe3", + "address": "0xb38Ba207d02f07653a37b53C1C0a250B04F97e82", + "topics": [ + "0xbd79b86ffe0ab8e8776151514217cd7cacd52c909f66475c3af44e129f0b00ff", + "0x0ae0130c6b34f32239dfe5e419a3fbd7546b44e99783257f2d93526d5a936d46", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x7935bd0ae54bc31f548c14dba4d37c5c64b3f8ca900cb468fb8abd54d5894f55" + ], + "data": "0x", + "logIndex": 10, + "blockHash": "0xd77a02eda6662f3fd0fdb275d79eca91b5a6883f5700ccd51665d7246e5da93c" + }, + { + "transactionIndex": 2, + "blockNumber": 168975714, + "transactionHash": "0x1f79ba2b8795194b916fe329fa8edcde0befbc0764f7b81e5b106baa8fbd5fe3", + "address": "0xb38Ba207d02f07653a37b53C1C0a250B04F97e82", + "topics": [ + "0x7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f" + ], + "data": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000009a5b060bd7b8f86c4c0d720a17367729670afb19", + "logIndex": 11, + "blockHash": "0xd77a02eda6662f3fd0fdb275d79eca91b5a6883f5700ccd51665d7246e5da93c" + } + ], + "blockNumber": 168975714, + "cumulativeGasUsed": "9572582", + "status": 1, + "byzantium": true + }, + "args": [ + "0x5183f032bf42109cD370B9559FD22207e432301E", + "0x9a5b060Bd7b8f86c4C0D720a17367729670AfB19", + "0x485cc955000000000000000000000000fda462548ce04282f4b6d6619823a7c64fdc018500000000000000000000000055f01ddae74b60e3c255bd2f619febdfce560a9c" + ], + "numDeployments": 1, + "solcInputHash": "871924e0c138825a2736b76def8fef8d", + "metadata": "{\"compiler\":{\"version\":\"0.8.17+commit.8df45f5f\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_logic\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"admin_\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"_data\",\"type\":\"bytes\"}],\"stateMutability\":\"payable\",\"type\":\"constructor\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"previousAdmin\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"newAdmin\",\"type\":\"address\"}],\"name\":\"AdminChanged\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"beacon\",\"type\":\"address\"}],\"name\":\"BeaconUpgraded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"implementation\",\"type\":\"address\"}],\"name\":\"Upgraded\",\"type\":\"event\"},{\"stateMutability\":\"payable\",\"type\":\"fallback\"},{\"inputs\":[],\"name\":\"admin\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"admin_\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newAdmin\",\"type\":\"address\"}],\"name\":\"changeAdmin\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"implementation\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"implementation_\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newImplementation\",\"type\":\"address\"}],\"name\":\"upgradeTo\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newImplementation\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"}],\"name\":\"upgradeToAndCall\",\"outputs\":[],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"stateMutability\":\"payable\",\"type\":\"receive\"}],\"devdoc\":{\"details\":\"This contract implements a proxy that is upgradeable by an admin. It is fully forked from OpenZeppelin `TransparentUpgradeableProxy` To avoid https://medium.com/nomic-labs-blog/malicious-backdoors-in-ethereum-proxies-62629adf3357[proxy selector clashing], which can potentially be used in an attack, this contract uses the https://blog.openzeppelin.com/the-transparent-proxy-pattern/[transparent proxy pattern]. This pattern implies two things that go hand in hand: 1. If any account other than the admin calls the proxy, the call will be forwarded to the implementation, even if that call matches one of the admin functions exposed by the proxy itself. 2. If the admin calls the proxy, it can access the admin functions, but its calls will never be forwarded to the implementation. If the admin tries to call a function on the implementation it will fail with an error that says \\\"admin cannot fallback to proxy target\\\". These properties mean that the admin account can only be used for admin actions like upgrading the proxy or changing the admin, so it's best if it's a dedicated account that is not used for anything else. This will avoid headaches due to sudden errors when trying to call a function from the proxy implementation. Our recommendation is for the dedicated account to be an instance of the {ProxyAdmin} contract. If set up this way, you should think of the `ProxyAdmin` instance as the real administrative interface of your proxy.\",\"kind\":\"dev\",\"methods\":{\"admin()\":{\"details\":\"Returns the current admin. NOTE: Only the admin can call this function. See {ProxyAdmin-getProxyAdmin}. TIP: To get this value clients can read directly from the storage slot shown below (specified by EIP1967) using the https://eth.wiki/json-rpc/API#eth_getstorageat[`eth_getStorageAt`] RPC call. `0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103`\"},\"changeAdmin(address)\":{\"details\":\"Changes the admin of the proxy. Emits an {AdminChanged} event. NOTE: Only the admin can call this function. See {ProxyAdmin-changeProxyAdmin}.\"},\"constructor\":{\"details\":\"Initializes an upgradeable proxy managed by `_admin`, backed by the implementation at `_logic`, and optionally initialized with `_data` as explained in {ERC1967Proxy-constructor}.\"},\"implementation()\":{\"details\":\"Returns the current implementation. NOTE: Only the admin can call this function. See {ProxyAdmin-getProxyImplementation}. TIP: To get this value clients can read directly from the storage slot shown below (specified by EIP1967) using the https://eth.wiki/json-rpc/API#eth_getstorageat[`eth_getStorageAt`] RPC call. `0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc`\"},\"upgradeTo(address)\":{\"details\":\"Upgrade the implementation of the proxy. NOTE: Only the admin can call this function. See {ProxyAdmin-upgrade}.\"},\"upgradeToAndCall(address,bytes)\":{\"details\":\"Upgrade the implementation of the proxy, and then call a function from the new implementation as specified by `data`, which should be an encoded function call. This is useful to initialize new storage variables in the proxied contract. NOTE: Only the admin can call this function. See {ProxyAdmin-upgradeAndCall}.\"}},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/external/TransparentUpgradeableProxy.sol\":\"TransparentUpgradeableProxy\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":1000000},\"remappings\":[]},\"sources\":{\"@openzeppelin/contracts/interfaces/draft-IERC1822.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.5.0) (interfaces/draft-IERC1822.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev ERC1822: Universal Upgradeable Proxy Standard (UUPS) documents a method for upgradeability through a simplified\\n * proxy whose upgrades are fully controlled by the current implementation.\\n */\\ninterface IERC1822Proxiable {\\n /**\\n * @dev Returns the storage slot that the proxiable contract assumes is being used to store the implementation\\n * address.\\n *\\n * IMPORTANT: A proxy pointing at a proxiable contract should not be considered proxiable itself, because this risks\\n * bricking a proxy that upgrades to it, by delegating to itself until out of gas. Thus it is critical that this\\n * function revert if invoked through a proxy.\\n */\\n function proxiableUUID() external view returns (bytes32);\\n}\\n\",\"keccak256\":\"0x1d4afe6cb24200cc4545eed814ecf5847277dfe5d613a1707aad5fceecebcfff\",\"license\":\"MIT\"},\"@openzeppelin/contracts/proxy/ERC1967/ERC1967Proxy.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.7.0) (proxy/ERC1967/ERC1967Proxy.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../Proxy.sol\\\";\\nimport \\\"./ERC1967Upgrade.sol\\\";\\n\\n/**\\n * @dev This contract implements an upgradeable proxy. It is upgradeable because calls are delegated to an\\n * implementation address that can be changed. This address is stored in storage in the location specified by\\n * https://eips.ethereum.org/EIPS/eip-1967[EIP1967], so that it doesn't conflict with the storage layout of the\\n * implementation behind the proxy.\\n */\\ncontract ERC1967Proxy is Proxy, ERC1967Upgrade {\\n /**\\n * @dev Initializes the upgradeable proxy with an initial implementation specified by `_logic`.\\n *\\n * If `_data` is nonempty, it's used as data in a delegate call to `_logic`. This will typically be an encoded\\n * function call, and allows initializing the storage of the proxy like a Solidity constructor.\\n */\\n constructor(address _logic, bytes memory _data) payable {\\n _upgradeToAndCall(_logic, _data, false);\\n }\\n\\n /**\\n * @dev Returns the current implementation address.\\n */\\n function _implementation() internal view virtual override returns (address impl) {\\n return ERC1967Upgrade._getImplementation();\\n }\\n}\\n\",\"keccak256\":\"0xa2b22da3032e50b55f95ec1d13336102d675f341167aa76db571ef7f8bb7975d\",\"license\":\"MIT\"},\"@openzeppelin/contracts/proxy/ERC1967/ERC1967Upgrade.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.5.0) (proxy/ERC1967/ERC1967Upgrade.sol)\\n\\npragma solidity ^0.8.2;\\n\\nimport \\\"../beacon/IBeacon.sol\\\";\\nimport \\\"../../interfaces/draft-IERC1822.sol\\\";\\nimport \\\"../../utils/Address.sol\\\";\\nimport \\\"../../utils/StorageSlot.sol\\\";\\n\\n/**\\n * @dev This abstract contract provides getters and event emitting update functions for\\n * https://eips.ethereum.org/EIPS/eip-1967[EIP1967] slots.\\n *\\n * _Available since v4.1._\\n *\\n * @custom:oz-upgrades-unsafe-allow delegatecall\\n */\\nabstract contract ERC1967Upgrade {\\n // This is the keccak-256 hash of \\\"eip1967.proxy.rollback\\\" subtracted by 1\\n bytes32 private constant _ROLLBACK_SLOT = 0x4910fdfa16fed3260ed0e7147f7cc6da11a60208b5b9406d12a635614ffd9143;\\n\\n /**\\n * @dev Storage slot with the address of the current implementation.\\n * This is the keccak-256 hash of \\\"eip1967.proxy.implementation\\\" subtracted by 1, and is\\n * validated in the constructor.\\n */\\n bytes32 internal constant _IMPLEMENTATION_SLOT = 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc;\\n\\n /**\\n * @dev Emitted when the implementation is upgraded.\\n */\\n event Upgraded(address indexed implementation);\\n\\n /**\\n * @dev Returns the current implementation address.\\n */\\n function _getImplementation() internal view returns (address) {\\n return StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value;\\n }\\n\\n /**\\n * @dev Stores a new address in the EIP1967 implementation slot.\\n */\\n function _setImplementation(address newImplementation) private {\\n require(Address.isContract(newImplementation), \\\"ERC1967: new implementation is not a contract\\\");\\n StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value = newImplementation;\\n }\\n\\n /**\\n * @dev Perform implementation upgrade\\n *\\n * Emits an {Upgraded} event.\\n */\\n function _upgradeTo(address newImplementation) internal {\\n _setImplementation(newImplementation);\\n emit Upgraded(newImplementation);\\n }\\n\\n /**\\n * @dev Perform implementation upgrade with additional setup call.\\n *\\n * Emits an {Upgraded} event.\\n */\\n function _upgradeToAndCall(\\n address newImplementation,\\n bytes memory data,\\n bool forceCall\\n ) internal {\\n _upgradeTo(newImplementation);\\n if (data.length > 0 || forceCall) {\\n Address.functionDelegateCall(newImplementation, data);\\n }\\n }\\n\\n /**\\n * @dev Perform implementation upgrade with security checks for UUPS proxies, and additional setup call.\\n *\\n * Emits an {Upgraded} event.\\n */\\n function _upgradeToAndCallUUPS(\\n address newImplementation,\\n bytes memory data,\\n bool forceCall\\n ) internal {\\n // Upgrades from old implementations will perform a rollback test. This test requires the new\\n // implementation to upgrade back to the old, non-ERC1822 compliant, implementation. Removing\\n // this special case will break upgrade paths from old UUPS implementation to new ones.\\n if (StorageSlot.getBooleanSlot(_ROLLBACK_SLOT).value) {\\n _setImplementation(newImplementation);\\n } else {\\n try IERC1822Proxiable(newImplementation).proxiableUUID() returns (bytes32 slot) {\\n require(slot == _IMPLEMENTATION_SLOT, \\\"ERC1967Upgrade: unsupported proxiableUUID\\\");\\n } catch {\\n revert(\\\"ERC1967Upgrade: new implementation is not UUPS\\\");\\n }\\n _upgradeToAndCall(newImplementation, data, forceCall);\\n }\\n }\\n\\n /**\\n * @dev Storage slot with the admin of the contract.\\n * This is the keccak-256 hash of \\\"eip1967.proxy.admin\\\" subtracted by 1, and is\\n * validated in the constructor.\\n */\\n bytes32 internal constant _ADMIN_SLOT = 0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103;\\n\\n /**\\n * @dev Emitted when the admin account has changed.\\n */\\n event AdminChanged(address previousAdmin, address newAdmin);\\n\\n /**\\n * @dev Returns the current admin.\\n */\\n function _getAdmin() internal view returns (address) {\\n return StorageSlot.getAddressSlot(_ADMIN_SLOT).value;\\n }\\n\\n /**\\n * @dev Stores a new address in the EIP1967 admin slot.\\n */\\n function _setAdmin(address newAdmin) private {\\n require(newAdmin != address(0), \\\"ERC1967: new admin is the zero address\\\");\\n StorageSlot.getAddressSlot(_ADMIN_SLOT).value = newAdmin;\\n }\\n\\n /**\\n * @dev Changes the admin of the proxy.\\n *\\n * Emits an {AdminChanged} event.\\n */\\n function _changeAdmin(address newAdmin) internal {\\n emit AdminChanged(_getAdmin(), newAdmin);\\n _setAdmin(newAdmin);\\n }\\n\\n /**\\n * @dev The storage slot of the UpgradeableBeacon contract which defines the implementation for this proxy.\\n * This is bytes32(uint256(keccak256('eip1967.proxy.beacon')) - 1)) and is validated in the constructor.\\n */\\n bytes32 internal constant _BEACON_SLOT = 0xa3f0ad74e5423aebfd80d3ef4346578335a9a72aeaee59ff6cb3582b35133d50;\\n\\n /**\\n * @dev Emitted when the beacon is upgraded.\\n */\\n event BeaconUpgraded(address indexed beacon);\\n\\n /**\\n * @dev Returns the current beacon.\\n */\\n function _getBeacon() internal view returns (address) {\\n return StorageSlot.getAddressSlot(_BEACON_SLOT).value;\\n }\\n\\n /**\\n * @dev Stores a new beacon in the EIP1967 beacon slot.\\n */\\n function _setBeacon(address newBeacon) private {\\n require(Address.isContract(newBeacon), \\\"ERC1967: new beacon is not a contract\\\");\\n require(\\n Address.isContract(IBeacon(newBeacon).implementation()),\\n \\\"ERC1967: beacon implementation is not a contract\\\"\\n );\\n StorageSlot.getAddressSlot(_BEACON_SLOT).value = newBeacon;\\n }\\n\\n /**\\n * @dev Perform beacon upgrade with additional setup call. Note: This upgrades the address of the beacon, it does\\n * not upgrade the implementation contained in the beacon (see {UpgradeableBeacon-_setImplementation} for that).\\n *\\n * Emits a {BeaconUpgraded} event.\\n */\\n function _upgradeBeaconToAndCall(\\n address newBeacon,\\n bytes memory data,\\n bool forceCall\\n ) internal {\\n _setBeacon(newBeacon);\\n emit BeaconUpgraded(newBeacon);\\n if (data.length > 0 || forceCall) {\\n Address.functionDelegateCall(IBeacon(newBeacon).implementation(), data);\\n }\\n }\\n}\\n\",\"keccak256\":\"0xabf3f59bc0e5423eae45e459dbe92e7052c6983628d39008590edc852a62f94a\",\"license\":\"MIT\"},\"@openzeppelin/contracts/proxy/Proxy.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.6.0) (proxy/Proxy.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev This abstract contract provides a fallback function that delegates all calls to another contract using the EVM\\n * instruction `delegatecall`. We refer to the second contract as the _implementation_ behind the proxy, and it has to\\n * be specified by overriding the virtual {_implementation} function.\\n *\\n * Additionally, delegation to the implementation can be triggered manually through the {_fallback} function, or to a\\n * different contract through the {_delegate} function.\\n *\\n * The success and return data of the delegated call will be returned back to the caller of the proxy.\\n */\\nabstract contract Proxy {\\n /**\\n * @dev Delegates the current call to `implementation`.\\n *\\n * This function does not return to its internal call site, it will return directly to the external caller.\\n */\\n function _delegate(address implementation) internal virtual {\\n assembly {\\n // Copy msg.data. We take full control of memory in this inline assembly\\n // block because it will not return to Solidity code. We overwrite the\\n // Solidity scratch pad at memory position 0.\\n calldatacopy(0, 0, calldatasize())\\n\\n // Call the implementation.\\n // out and outsize are 0 because we don't know the size yet.\\n let result := delegatecall(gas(), implementation, 0, calldatasize(), 0, 0)\\n\\n // Copy the returned data.\\n returndatacopy(0, 0, returndatasize())\\n\\n switch result\\n // delegatecall returns 0 on error.\\n case 0 {\\n revert(0, returndatasize())\\n }\\n default {\\n return(0, returndatasize())\\n }\\n }\\n }\\n\\n /**\\n * @dev This is a virtual function that should be overridden so it returns the address to which the fallback function\\n * and {_fallback} should delegate.\\n */\\n function _implementation() internal view virtual returns (address);\\n\\n /**\\n * @dev Delegates the current call to the address returned by `_implementation()`.\\n *\\n * This function does not return to its internal call site, it will return directly to the external caller.\\n */\\n function _fallback() internal virtual {\\n _beforeFallback();\\n _delegate(_implementation());\\n }\\n\\n /**\\n * @dev Fallback function that delegates calls to the address returned by `_implementation()`. Will run if no other\\n * function in the contract matches the call data.\\n */\\n fallback() external payable virtual {\\n _fallback();\\n }\\n\\n /**\\n * @dev Fallback function that delegates calls to the address returned by `_implementation()`. Will run if call data\\n * is empty.\\n */\\n receive() external payable virtual {\\n _fallback();\\n }\\n\\n /**\\n * @dev Hook that is called before falling back to the implementation. Can happen as part of a manual `_fallback`\\n * call, or as part of the Solidity `fallback` or `receive` functions.\\n *\\n * If overridden should call `super._beforeFallback()`.\\n */\\n function _beforeFallback() internal virtual {}\\n}\\n\",\"keccak256\":\"0xc130fe33f1b2132158531a87734153293f6d07bc263ff4ac90e85da9c82c0e27\",\"license\":\"MIT\"},\"@openzeppelin/contracts/proxy/beacon/IBeacon.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (proxy/beacon/IBeacon.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev This is the interface that {BeaconProxy} expects of its beacon.\\n */\\ninterface IBeacon {\\n /**\\n * @dev Must return an address that can be used as a delegate call target.\\n *\\n * {BeaconProxy} will check that this address is a contract.\\n */\\n function implementation() external view returns (address);\\n}\\n\",\"keccak256\":\"0xd50a3421ac379ccb1be435fa646d66a65c986b4924f0849839f08692f39dde61\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/Address.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.7.0) (utils/Address.sol)\\n\\npragma solidity ^0.8.1;\\n\\n/**\\n * @dev Collection of functions related to the address type\\n */\\nlibrary Address {\\n /**\\n * @dev Returns true if `account` is a contract.\\n *\\n * [IMPORTANT]\\n * ====\\n * It is unsafe to assume that an address for which this function returns\\n * false is an externally-owned account (EOA) and not a contract.\\n *\\n * Among others, `isContract` will return false for the following\\n * types of addresses:\\n *\\n * - an externally-owned account\\n * - a contract in construction\\n * - an address where a contract will be created\\n * - an address where a contract lived, but was destroyed\\n * ====\\n *\\n * [IMPORTANT]\\n * ====\\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\\n *\\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\\n * constructor.\\n * ====\\n */\\n function isContract(address account) internal view returns (bool) {\\n // This method relies on extcodesize/address.code.length, which returns 0\\n // for contracts in construction, since the code is only stored at the end\\n // of the constructor execution.\\n\\n return account.code.length > 0;\\n }\\n\\n /**\\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\\n * `recipient`, forwarding all available gas and reverting on errors.\\n *\\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\\n * imposed by `transfer`, making them unable to receive funds via\\n * `transfer`. {sendValue} removes this limitation.\\n *\\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\\n *\\n * IMPORTANT: because control is transferred to `recipient`, care must be\\n * taken to not create reentrancy vulnerabilities. Consider using\\n * {ReentrancyGuard} or the\\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\\n */\\n function sendValue(address payable recipient, uint256 amount) internal {\\n require(address(this).balance >= amount, \\\"Address: insufficient balance\\\");\\n\\n (bool success, ) = recipient.call{value: amount}(\\\"\\\");\\n require(success, \\\"Address: unable to send value, recipient may have reverted\\\");\\n }\\n\\n /**\\n * @dev Performs a Solidity function call using a low level `call`. A\\n * plain `call` is an unsafe replacement for a function call: use this\\n * function instead.\\n *\\n * If `target` reverts with a revert reason, it is bubbled up by this\\n * function (like regular Solidity function calls).\\n *\\n * Returns the raw returned data. To convert to the expected return value,\\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\\n *\\n * Requirements:\\n *\\n * - `target` must be a contract.\\n * - calling `target` with `data` must not revert.\\n *\\n * _Available since v3.1._\\n */\\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\\n return functionCall(target, data, \\\"Address: low-level call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\\n * `errorMessage` as a fallback revert reason when `target` reverts.\\n *\\n * _Available since v3.1._\\n */\\n function functionCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n return functionCallWithValue(target, data, 0, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but also transferring `value` wei to `target`.\\n *\\n * Requirements:\\n *\\n * - the calling contract must have an ETH balance of at least `value`.\\n * - the called Solidity function must be `payable`.\\n *\\n * _Available since v3.1._\\n */\\n function functionCallWithValue(\\n address target,\\n bytes memory data,\\n uint256 value\\n ) internal returns (bytes memory) {\\n return functionCallWithValue(target, data, value, \\\"Address: low-level call with value failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\\n * with `errorMessage` as a fallback revert reason when `target` reverts.\\n *\\n * _Available since v3.1._\\n */\\n function functionCallWithValue(\\n address target,\\n bytes memory data,\\n uint256 value,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n require(address(this).balance >= value, \\\"Address: insufficient balance for call\\\");\\n require(isContract(target), \\\"Address: call to non-contract\\\");\\n\\n (bool success, bytes memory returndata) = target.call{value: value}(data);\\n return verifyCallResult(success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but performing a static call.\\n *\\n * _Available since v3.3._\\n */\\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\\n return functionStaticCall(target, data, \\\"Address: low-level static call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\\n * but performing a static call.\\n *\\n * _Available since v3.3._\\n */\\n function functionStaticCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal view returns (bytes memory) {\\n require(isContract(target), \\\"Address: static call to non-contract\\\");\\n\\n (bool success, bytes memory returndata) = target.staticcall(data);\\n return verifyCallResult(success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but performing a delegate call.\\n *\\n * _Available since v3.4._\\n */\\n function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {\\n return functionDelegateCall(target, data, \\\"Address: low-level delegate call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\\n * but performing a delegate call.\\n *\\n * _Available since v3.4._\\n */\\n function functionDelegateCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n require(isContract(target), \\\"Address: delegate call to non-contract\\\");\\n\\n (bool success, bytes memory returndata) = target.delegatecall(data);\\n return verifyCallResult(success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the\\n * revert reason using the provided one.\\n *\\n * _Available since v4.3._\\n */\\n function verifyCallResult(\\n bool success,\\n bytes memory returndata,\\n string memory errorMessage\\n ) internal pure returns (bytes memory) {\\n if (success) {\\n return returndata;\\n } else {\\n // Look for revert reason and bubble it up if present\\n if (returndata.length > 0) {\\n // The easiest way to bubble the revert reason is using memory via assembly\\n /// @solidity memory-safe-assembly\\n assembly {\\n let returndata_size := mload(returndata)\\n revert(add(32, returndata), returndata_size)\\n }\\n } else {\\n revert(errorMessage);\\n }\\n }\\n }\\n}\\n\",\"keccak256\":\"0xd6153ce99bcdcce22b124f755e72553295be6abcd63804cfdffceb188b8bef10\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/StorageSlot.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.7.0) (utils/StorageSlot.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Library for reading and writing primitive types to specific storage slots.\\n *\\n * Storage slots are often used to avoid storage conflict when dealing with upgradeable contracts.\\n * This library helps with reading and writing to such slots without the need for inline assembly.\\n *\\n * The functions in this library return Slot structs that contain a `value` member that can be used to read or write.\\n *\\n * Example usage to set ERC1967 implementation slot:\\n * ```\\n * contract ERC1967 {\\n * bytes32 internal constant _IMPLEMENTATION_SLOT = 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc;\\n *\\n * function _getImplementation() internal view returns (address) {\\n * return StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value;\\n * }\\n *\\n * function _setImplementation(address newImplementation) internal {\\n * require(Address.isContract(newImplementation), \\\"ERC1967: new implementation is not a contract\\\");\\n * StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value = newImplementation;\\n * }\\n * }\\n * ```\\n *\\n * _Available since v4.1 for `address`, `bool`, `bytes32`, and `uint256`._\\n */\\nlibrary StorageSlot {\\n struct AddressSlot {\\n address value;\\n }\\n\\n struct BooleanSlot {\\n bool value;\\n }\\n\\n struct Bytes32Slot {\\n bytes32 value;\\n }\\n\\n struct Uint256Slot {\\n uint256 value;\\n }\\n\\n /**\\n * @dev Returns an `AddressSlot` with member `value` located at `slot`.\\n */\\n function getAddressSlot(bytes32 slot) internal pure returns (AddressSlot storage r) {\\n /// @solidity memory-safe-assembly\\n assembly {\\n r.slot := slot\\n }\\n }\\n\\n /**\\n * @dev Returns an `BooleanSlot` with member `value` located at `slot`.\\n */\\n function getBooleanSlot(bytes32 slot) internal pure returns (BooleanSlot storage r) {\\n /// @solidity memory-safe-assembly\\n assembly {\\n r.slot := slot\\n }\\n }\\n\\n /**\\n * @dev Returns an `Bytes32Slot` with member `value` located at `slot`.\\n */\\n function getBytes32Slot(bytes32 slot) internal pure returns (Bytes32Slot storage r) {\\n /// @solidity memory-safe-assembly\\n assembly {\\n r.slot := slot\\n }\\n }\\n\\n /**\\n * @dev Returns an `Uint256Slot` with member `value` located at `slot`.\\n */\\n function getUint256Slot(bytes32 slot) internal pure returns (Uint256Slot storage r) {\\n /// @solidity memory-safe-assembly\\n assembly {\\n r.slot := slot\\n }\\n }\\n}\\n\",\"keccak256\":\"0xd5c50c54bf02740ebd122ff06832546cb5fa84486d52695a9ccfd11666e0c81d\",\"license\":\"MIT\"},\"contracts/external/TransparentUpgradeableProxy.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-3.0\\n\\npragma solidity ^0.8.12;\\n\\nimport \\\"@openzeppelin/contracts/proxy/ERC1967/ERC1967Proxy.sol\\\";\\n\\n/**\\n * @dev This contract implements a proxy that is upgradeable by an admin. It is fully forked from OpenZeppelin\\n * `TransparentUpgradeableProxy`\\n *\\n * To avoid https://medium.com/nomic-labs-blog/malicious-backdoors-in-ethereum-proxies-62629adf3357[proxy selector\\n * clashing], which can potentially be used in an attack, this contract uses the\\n * https://blog.openzeppelin.com/the-transparent-proxy-pattern/[transparent proxy pattern]. This pattern implies two\\n * things that go hand in hand:\\n *\\n * 1. If any account other than the admin calls the proxy, the call will be forwarded to the implementation, even if\\n * that call matches one of the admin functions exposed by the proxy itself.\\n * 2. If the admin calls the proxy, it can access the admin functions, but its calls will never be forwarded to the\\n * implementation. If the admin tries to call a function on the implementation it will fail with an error that says\\n * \\\"admin cannot fallback to proxy target\\\".\\n *\\n * These properties mean that the admin account can only be used for admin actions like upgrading the proxy or changing\\n * the admin, so it's best if it's a dedicated account that is not used for anything else. This will avoid headaches due\\n * to sudden errors when trying to call a function from the proxy implementation.\\n *\\n * Our recommendation is for the dedicated account to be an instance of the {ProxyAdmin} contract. If set up this way,\\n * you should think of the `ProxyAdmin` instance as the real administrative interface of your proxy.\\n */\\ncontract TransparentUpgradeableProxy is ERC1967Proxy {\\n /**\\n * @dev Initializes an upgradeable proxy managed by `_admin`, backed by the implementation at `_logic`, and\\n * optionally initialized with `_data` as explained in {ERC1967Proxy-constructor}.\\n */\\n constructor(address _logic, address admin_, bytes memory _data) payable ERC1967Proxy(_logic, _data) {\\n assert(_ADMIN_SLOT == bytes32(uint256(keccak256(\\\"eip1967.proxy.admin\\\")) - 1));\\n _changeAdmin(admin_);\\n }\\n\\n /**\\n * @dev Modifier used internally that will delegate the call to the implementation unless the sender is the admin.\\n */\\n modifier ifAdmin() {\\n if (msg.sender == _getAdmin()) {\\n _;\\n } else {\\n _fallback();\\n }\\n }\\n\\n /**\\n * @dev Returns the current admin.\\n *\\n * NOTE: Only the admin can call this function. See {ProxyAdmin-getProxyAdmin}.\\n *\\n * TIP: To get this value clients can read directly from the storage slot shown below (specified by EIP1967) using the\\n * https://eth.wiki/json-rpc/API#eth_getstorageat[`eth_getStorageAt`] RPC call.\\n * `0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103`\\n */\\n function admin() external ifAdmin returns (address admin_) {\\n admin_ = _getAdmin();\\n }\\n\\n /**\\n * @dev Returns the current implementation.\\n *\\n * NOTE: Only the admin can call this function. See {ProxyAdmin-getProxyImplementation}.\\n *\\n * TIP: To get this value clients can read directly from the storage slot shown below (specified by EIP1967) using the\\n * https://eth.wiki/json-rpc/API#eth_getstorageat[`eth_getStorageAt`] RPC call.\\n * `0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc`\\n */\\n function implementation() external ifAdmin returns (address implementation_) {\\n implementation_ = _implementation();\\n }\\n\\n /**\\n * @dev Changes the admin of the proxy.\\n *\\n * Emits an {AdminChanged} event.\\n *\\n * NOTE: Only the admin can call this function. See {ProxyAdmin-changeProxyAdmin}.\\n */\\n function changeAdmin(address newAdmin) external virtual ifAdmin {\\n _changeAdmin(newAdmin);\\n }\\n\\n /**\\n * @dev Upgrade the implementation of the proxy.\\n *\\n * NOTE: Only the admin can call this function. See {ProxyAdmin-upgrade}.\\n */\\n function upgradeTo(address newImplementation) external ifAdmin {\\n _upgradeToAndCall(newImplementation, bytes(\\\"\\\"), false);\\n }\\n\\n /**\\n * @dev Upgrade the implementation of the proxy, and then call a function from the new implementation as specified\\n * by `data`, which should be an encoded function call. This is useful to initialize new storage variables in the\\n * proxied contract.\\n *\\n * NOTE: Only the admin can call this function. See {ProxyAdmin-upgradeAndCall}.\\n */\\n function upgradeToAndCall(address newImplementation, bytes calldata data) external payable ifAdmin {\\n _upgradeToAndCall(newImplementation, data, true);\\n }\\n\\n /**\\n * @dev Returns the current admin.\\n */\\n function _admin() internal view virtual returns (address) {\\n return _getAdmin();\\n }\\n\\n /**\\n * @dev Makes sure the admin cannot access the fallback function. See {Proxy-_beforeFallback}.\\n */\\n function _beforeFallback() internal virtual override {\\n require(msg.sender != _getAdmin(), \\\"TransparentUpgradeableProxy: admin cannot fallback to proxy target\\\");\\n super._beforeFallback();\\n }\\n}\\n\",\"keccak256\":\"0x93a67a0f612ea3ff2a76315e138a6a88267270a1379d3cc7be52845fbbe611e2\",\"license\":\"GPL-3.0\"}},\"version\":1}", + "bytecode": "0x6080604052604051620010bb380380620010bb8339810160408190526200002691620004d8565b828162000036828260006200009a565b5062000066905060017fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6104620005b8565b6000805160206200107483398151915214620000865762000086620005da565b6200009182620000d7565b50505062000643565b620000a58362000132565b600082511180620000b35750805b15620000d257620000d083836200017460201b6200028c1760201c565b505b505050565b7f7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f62000102620001a5565b604080516001600160a01b03928316815291841660208301520160405180910390a16200012f81620001de565b50565b6200013d8162000293565b6040516001600160a01b038216907fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b90600090a250565b60606200019c8383604051806060016040528060278152602001620010946027913962000347565b90505b92915050565b6000620001cf6000805160206200107483398151915260001b6200042f60201b6200022e1760201c565b546001600160a01b0316919050565b6001600160a01b038116620002495760405162461bcd60e51b815260206004820152602660248201527f455243313936373a206e65772061646d696e20697320746865207a65726f206160448201526564647265737360d01b60648201526084015b60405180910390fd5b80620002726000805160206200107483398151915260001b6200042f60201b6200022e1760201c565b80546001600160a01b0319166001600160a01b039290921691909117905550565b620002a9816200043260201b620002b81760201c565b6200030d5760405162461bcd60e51b815260206004820152602d60248201527f455243313936373a206e657720696d706c656d656e746174696f6e206973206e60448201526c1bdd08184818dbdb9d1c9858dd609a1b606482015260840162000240565b80620002727f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc60001b6200042f60201b6200022e1760201c565b60606001600160a01b0384163b620003b15760405162461bcd60e51b815260206004820152602660248201527f416464726573733a2064656c65676174652063616c6c20746f206e6f6e2d636f6044820152651b9d1c9858dd60d21b606482015260840162000240565b600080856001600160a01b031685604051620003ce9190620005f0565b600060405180830381855af49150503d80600081146200040b576040519150601f19603f3d011682016040523d82523d6000602084013e62000410565b606091505b5090925090506200042382828662000441565b925050505b9392505050565b90565b6001600160a01b03163b151590565b606083156200045257508162000428565b825115620004635782518084602001fd5b8160405162461bcd60e51b81526004016200024091906200060e565b80516001600160a01b03811681146200049757600080fd5b919050565b634e487b7160e01b600052604160045260246000fd5b60005b83811015620004cf578181015183820152602001620004b5565b50506000910152565b600080600060608486031215620004ee57600080fd5b620004f9846200047f565b925062000509602085016200047f565b60408501519092506001600160401b03808211156200052757600080fd5b818601915086601f8301126200053c57600080fd5b8151818111156200055157620005516200049c565b604051601f8201601f19908116603f011681019083821181831017156200057c576200057c6200049c565b816040528281528960208487010111156200059657600080fd5b620005a9836020830160208801620004b2565b80955050505050509250925092565b818103818111156200019f57634e487b7160e01b600052601160045260246000fd5b634e487b7160e01b600052600160045260246000fd5b6000825162000604818460208701620004b2565b9190910192915050565b60208152600082518060208401526200062f816040850160208701620004b2565b601f01601f19169190910160400192915050565b610a2180620006536000396000f3fe60806040526004361061005e5760003560e01c80635c60da1b116100435780635c60da1b146100a85780638f283970146100e6578063f851a440146101065761006d565b80633659cfe6146100755780634f1ef286146100955761006d565b3661006d5761006b61011b565b005b61006b61011b565b34801561008157600080fd5b5061006b610090366004610895565b610135565b61006b6100a33660046108b0565b61017f565b3480156100b457600080fd5b506100bd6101f3565b60405173ffffffffffffffffffffffffffffffffffffffff909116815260200160405180910390f35b3480156100f257600080fd5b5061006b610101366004610895565b610231565b34801561011257600080fd5b506100bd61025e565b6101236102d4565b61013361012e6103ab565b6103b5565b565b61013d6103d9565b73ffffffffffffffffffffffffffffffffffffffff1633036101775761017481604051806020016040528060008152506000610419565b50565b61017461011b565b6101876103d9565b73ffffffffffffffffffffffffffffffffffffffff1633036101eb576101e68383838080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525060019250610419915050565b505050565b6101e661011b565b60006101fd6103d9565b73ffffffffffffffffffffffffffffffffffffffff163303610226576102216103ab565b905090565b61022e61011b565b90565b6102396103d9565b73ffffffffffffffffffffffffffffffffffffffff1633036101775761017481610444565b60006102686103d9565b73ffffffffffffffffffffffffffffffffffffffff163303610226576102216103d9565b60606102b183836040518060600160405280602781526020016109c5602791396104a5565b9392505050565b73ffffffffffffffffffffffffffffffffffffffff163b151590565b6102dc6103d9565b73ffffffffffffffffffffffffffffffffffffffff163303610133576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604260248201527f5472616e73706172656e745570677261646561626c6550726f78793a2061646d60448201527f696e2063616e6e6f742066616c6c6261636b20746f2070726f7879207461726760648201527f6574000000000000000000000000000000000000000000000000000000000000608482015260a4015b60405180910390fd5b60006102216105cd565b3660008037600080366000845af43d6000803e8080156103d4573d6000f35b3d6000fd5b60007fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035b5473ffffffffffffffffffffffffffffffffffffffff16919050565b610422836105f5565b60008251118061042f5750805b156101e65761043e838361028c565b50505050565b7f7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f61046d6103d9565b6040805173ffffffffffffffffffffffffffffffffffffffff928316815291841660208301520160405180910390a161017481610642565b606073ffffffffffffffffffffffffffffffffffffffff84163b61054b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f416464726573733a2064656c65676174652063616c6c20746f206e6f6e2d636f60448201527f6e7472616374000000000000000000000000000000000000000000000000000060648201526084016103a2565b6000808573ffffffffffffffffffffffffffffffffffffffff16856040516105739190610957565b600060405180830381855af49150503d80600081146105ae576040519150601f19603f3d011682016040523d82523d6000602084013e6105b3565b606091505b50915091506105c382828661074e565b9695505050505050565b60007f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc6103fd565b6105fe816107a1565b60405173ffffffffffffffffffffffffffffffffffffffff8216907fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b90600090a250565b73ffffffffffffffffffffffffffffffffffffffff81166106e5576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f455243313936373a206e65772061646d696e20697320746865207a65726f206160448201527f646472657373000000000000000000000000000000000000000000000000000060648201526084016103a2565b807fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035b80547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff9290921691909117905550565b6060831561075d5750816102b1565b82511561076d5782518084602001fd5b816040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016103a29190610973565b73ffffffffffffffffffffffffffffffffffffffff81163b610845576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602d60248201527f455243313936373a206e657720696d706c656d656e746174696f6e206973206e60448201527f6f74206120636f6e74726163740000000000000000000000000000000000000060648201526084016103a2565b807f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc610708565b803573ffffffffffffffffffffffffffffffffffffffff8116811461089057600080fd5b919050565b6000602082840312156108a757600080fd5b6102b18261086c565b6000806000604084860312156108c557600080fd5b6108ce8461086c565b9250602084013567ffffffffffffffff808211156108eb57600080fd5b818601915086601f8301126108ff57600080fd5b81358181111561090e57600080fd5b87602082850101111561092057600080fd5b6020830194508093505050509250925092565b60005b8381101561094e578181015183820152602001610936565b50506000910152565b60008251610969818460208701610933565b9190910192915050565b6020815260008251806020840152610992816040850160208701610933565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016919091016040019291505056fe416464726573733a206c6f772d6c6576656c2064656c65676174652063616c6c206661696c6564a2646970667358221220e96638b07fb1675d93a95c49e417bc8111448b23a59918698cdcd8fd488dd7cf64736f6c63430008110033b53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103416464726573733a206c6f772d6c6576656c2064656c65676174652063616c6c206661696c6564", + "deployedBytecode": "0x60806040526004361061005e5760003560e01c80635c60da1b116100435780635c60da1b146100a85780638f283970146100e6578063f851a440146101065761006d565b80633659cfe6146100755780634f1ef286146100955761006d565b3661006d5761006b61011b565b005b61006b61011b565b34801561008157600080fd5b5061006b610090366004610895565b610135565b61006b6100a33660046108b0565b61017f565b3480156100b457600080fd5b506100bd6101f3565b60405173ffffffffffffffffffffffffffffffffffffffff909116815260200160405180910390f35b3480156100f257600080fd5b5061006b610101366004610895565b610231565b34801561011257600080fd5b506100bd61025e565b6101236102d4565b61013361012e6103ab565b6103b5565b565b61013d6103d9565b73ffffffffffffffffffffffffffffffffffffffff1633036101775761017481604051806020016040528060008152506000610419565b50565b61017461011b565b6101876103d9565b73ffffffffffffffffffffffffffffffffffffffff1633036101eb576101e68383838080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525060019250610419915050565b505050565b6101e661011b565b60006101fd6103d9565b73ffffffffffffffffffffffffffffffffffffffff163303610226576102216103ab565b905090565b61022e61011b565b90565b6102396103d9565b73ffffffffffffffffffffffffffffffffffffffff1633036101775761017481610444565b60006102686103d9565b73ffffffffffffffffffffffffffffffffffffffff163303610226576102216103d9565b60606102b183836040518060600160405280602781526020016109c5602791396104a5565b9392505050565b73ffffffffffffffffffffffffffffffffffffffff163b151590565b6102dc6103d9565b73ffffffffffffffffffffffffffffffffffffffff163303610133576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604260248201527f5472616e73706172656e745570677261646561626c6550726f78793a2061646d60448201527f696e2063616e6e6f742066616c6c6261636b20746f2070726f7879207461726760648201527f6574000000000000000000000000000000000000000000000000000000000000608482015260a4015b60405180910390fd5b60006102216105cd565b3660008037600080366000845af43d6000803e8080156103d4573d6000f35b3d6000fd5b60007fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035b5473ffffffffffffffffffffffffffffffffffffffff16919050565b610422836105f5565b60008251118061042f5750805b156101e65761043e838361028c565b50505050565b7f7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f61046d6103d9565b6040805173ffffffffffffffffffffffffffffffffffffffff928316815291841660208301520160405180910390a161017481610642565b606073ffffffffffffffffffffffffffffffffffffffff84163b61054b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f416464726573733a2064656c65676174652063616c6c20746f206e6f6e2d636f60448201527f6e7472616374000000000000000000000000000000000000000000000000000060648201526084016103a2565b6000808573ffffffffffffffffffffffffffffffffffffffff16856040516105739190610957565b600060405180830381855af49150503d80600081146105ae576040519150601f19603f3d011682016040523d82523d6000602084013e6105b3565b606091505b50915091506105c382828661074e565b9695505050505050565b60007f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc6103fd565b6105fe816107a1565b60405173ffffffffffffffffffffffffffffffffffffffff8216907fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b90600090a250565b73ffffffffffffffffffffffffffffffffffffffff81166106e5576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f455243313936373a206e65772061646d696e20697320746865207a65726f206160448201527f646472657373000000000000000000000000000000000000000000000000000060648201526084016103a2565b807fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035b80547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff9290921691909117905550565b6060831561075d5750816102b1565b82511561076d5782518084602001fd5b816040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016103a29190610973565b73ffffffffffffffffffffffffffffffffffffffff81163b610845576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602d60248201527f455243313936373a206e657720696d706c656d656e746174696f6e206973206e60448201527f6f74206120636f6e74726163740000000000000000000000000000000000000060648201526084016103a2565b807f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc610708565b803573ffffffffffffffffffffffffffffffffffffffff8116811461089057600080fd5b919050565b6000602082840312156108a757600080fd5b6102b18261086c565b6000806000604084860312156108c557600080fd5b6108ce8461086c565b9250602084013567ffffffffffffffff808211156108eb57600080fd5b818601915086601f8301126108ff57600080fd5b81358181111561090e57600080fd5b87602082850101111561092057600080fd5b6020830194508093505050509250925092565b60005b8381101561094e578181015183820152602001610936565b50506000910152565b60008251610969818460208701610933565b9190910192915050565b6020815260008251806020840152610992816040850160208701610933565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016919091016040019291505056fe416464726573733a206c6f772d6c6576656c2064656c65676174652063616c6c206661696c6564a2646970667358221220e96638b07fb1675d93a95c49e417bc8111448b23a59918698cdcd8fd488dd7cf64736f6c63430008110033", + "devdoc": { + "details": "This contract implements a proxy that is upgradeable by an admin. It is fully forked from OpenZeppelin `TransparentUpgradeableProxy` To avoid https://medium.com/nomic-labs-blog/malicious-backdoors-in-ethereum-proxies-62629adf3357[proxy selector clashing], which can potentially be used in an attack, this contract uses the https://blog.openzeppelin.com/the-transparent-proxy-pattern/[transparent proxy pattern]. This pattern implies two things that go hand in hand: 1. If any account other than the admin calls the proxy, the call will be forwarded to the implementation, even if that call matches one of the admin functions exposed by the proxy itself. 2. If the admin calls the proxy, it can access the admin functions, but its calls will never be forwarded to the implementation. If the admin tries to call a function on the implementation it will fail with an error that says \"admin cannot fallback to proxy target\". These properties mean that the admin account can only be used for admin actions like upgrading the proxy or changing the admin, so it's best if it's a dedicated account that is not used for anything else. This will avoid headaches due to sudden errors when trying to call a function from the proxy implementation. Our recommendation is for the dedicated account to be an instance of the {ProxyAdmin} contract. If set up this way, you should think of the `ProxyAdmin` instance as the real administrative interface of your proxy.", + "kind": "dev", + "methods": { + "admin()": { + "details": "Returns the current admin. NOTE: Only the admin can call this function. See {ProxyAdmin-getProxyAdmin}. TIP: To get this value clients can read directly from the storage slot shown below (specified by EIP1967) using the https://eth.wiki/json-rpc/API#eth_getstorageat[`eth_getStorageAt`] RPC call. `0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103`" + }, + "changeAdmin(address)": { + "details": "Changes the admin of the proxy. Emits an {AdminChanged} event. NOTE: Only the admin can call this function. See {ProxyAdmin-changeProxyAdmin}." + }, + "constructor": { + "details": "Initializes an upgradeable proxy managed by `_admin`, backed by the implementation at `_logic`, and optionally initialized with `_data` as explained in {ERC1967Proxy-constructor}." + }, + "implementation()": { + "details": "Returns the current implementation. NOTE: Only the admin can call this function. See {ProxyAdmin-getProxyImplementation}. TIP: To get this value clients can read directly from the storage slot shown below (specified by EIP1967) using the https://eth.wiki/json-rpc/API#eth_getstorageat[`eth_getStorageAt`] RPC call. `0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc`" + }, + "upgradeTo(address)": { + "details": "Upgrade the implementation of the proxy. NOTE: Only the admin can call this function. See {ProxyAdmin-upgrade}." + }, + "upgradeToAndCall(address,bytes)": { + "details": "Upgrade the implementation of the proxy, and then call a function from the new implementation as specified by `data`, which should be an encoded function call. This is useful to initialize new storage variables in the proxied contract. NOTE: Only the admin can call this function. See {ProxyAdmin-upgradeAndCall}." + } + }, + "version": 1 + }, + "userdoc": { + "kind": "user", + "methods": {}, + "version": 1 + }, + "storageLayout": { + "storage": [], + "types": null + } +} \ No newline at end of file diff --git a/deployments/arbitrum/LayerZeroBridge_USD.json b/deployments/arbitrum/LayerZeroBridge_USD.json new file mode 100644 index 00000000..4d32b094 --- /dev/null +++ b/deployments/arbitrum/LayerZeroBridge_USD.json @@ -0,0 +1,275 @@ +{ + "address": "0x8f4245D2eFEC45aF24E5Fa35f07172a830Fc0aDE", + "abi": [ + { + "inputs": [ + { + "internalType": "address", + "name": "_logic", + "type": "address" + }, + { + "internalType": "address", + "name": "admin_", + "type": "address" + }, + { + "internalType": "bytes", + "name": "_data", + "type": "bytes" + } + ], + "stateMutability": "payable", + "type": "constructor" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "previousAdmin", + "type": "address" + }, + { + "indexed": false, + "internalType": "address", + "name": "newAdmin", + "type": "address" + } + ], + "name": "AdminChanged", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "beacon", + "type": "address" + } + ], + "name": "BeaconUpgraded", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "implementation", + "type": "address" + } + ], + "name": "Upgraded", + "type": "event" + }, + { + "stateMutability": "payable", + "type": "fallback" + }, + { + "inputs": [], + "name": "admin", + "outputs": [ + { + "internalType": "address", + "name": "admin_", + "type": "address" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "newAdmin", + "type": "address" + } + ], + "name": "changeAdmin", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "implementation", + "outputs": [ + { + "internalType": "address", + "name": "implementation_", + "type": "address" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "newImplementation", + "type": "address" + } + ], + "name": "upgradeTo", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "newImplementation", + "type": "address" + }, + { + "internalType": "bytes", + "name": "data", + "type": "bytes" + } + ], + "name": "upgradeToAndCall", + "outputs": [], + "stateMutability": "payable", + "type": "function" + }, + { + "stateMutability": "payable", + "type": "receive" + } + ], + "transactionHash": "0x26ab296a920292b43a3842e4b3179f45c1374ec77fb60245bc00f44f0ce02129", + "receipt": { + "to": null, + "from": "0xfdA462548Ce04282f4B6D6619823a7C64Fdc0185", + "contractAddress": "0x8f4245D2eFEC45aF24E5Fa35f07172a830Fc0aDE", + "transactionIndex": 1, + "gasUsed": "7144445", + "logsBloom": "0x00000010000000000000000000000000400000000000000002000000000000000000000000000000000000000000000000000000004000000000000000200000000004008000000000004008000002000000000000000000000000000500000000000000020000000000000400000800000000800000000000000010000000000000000000000000000000000000000000000001000080000000000000800000020000000000000000000000000400000080000000000000000000000000000000000022000000000000000000040010000000000400000000000000000020000010000000000000000000000000000000000000000000000000000000000000", + "blockHash": "0xc840b1c1ba065e9ee2c9a7835f1769744f8e4a71425bf6c7206434b4075d7e1a", + "transactionHash": "0x26ab296a920292b43a3842e4b3179f45c1374ec77fb60245bc00f44f0ce02129", + "logs": [ + { + "transactionIndex": 1, + "blockNumber": 169032375, + "transactionHash": "0x26ab296a920292b43a3842e4b3179f45c1374ec77fb60245bc00f44f0ce02129", + "address": "0x8f4245D2eFEC45aF24E5Fa35f07172a830Fc0aDE", + "topics": [ + "0xbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b", + "0x000000000000000000000000874f1686e8f89374a40196b54f435cc1a72d04e4" + ], + "data": "0x", + "logIndex": 0, + "blockHash": "0xc840b1c1ba065e9ee2c9a7835f1769744f8e4a71425bf6c7206434b4075d7e1a" + }, + { + "transactionIndex": 1, + "blockNumber": 169032375, + "transactionHash": "0x26ab296a920292b43a3842e4b3179f45c1374ec77fb60245bc00f44f0ce02129", + "address": "0x8f4245D2eFEC45aF24E5Fa35f07172a830Fc0aDE", + "topics": [ + "0x8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925", + "0x0000000000000000000000008f4245d2efec45af24e5fa35f07172a830fc0ade", + "0x0000000000000000000000000000206329b97db379d5e1bf586bbdb969c63274" + ], + "data": "0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", + "logIndex": 1, + "blockHash": "0xc840b1c1ba065e9ee2c9a7835f1769744f8e4a71425bf6c7206434b4075d7e1a" + }, + { + "transactionIndex": 1, + "blockNumber": 169032375, + "transactionHash": "0x26ab296a920292b43a3842e4b3179f45c1374ec77fb60245bc00f44f0ce02129", + "address": "0x8f4245D2eFEC45aF24E5Fa35f07172a830Fc0aDE", + "topics": [ + "0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000206329b97db379d5e1bf586bbdb969c63274" + ], + "data": "0x0000000000000000000000000000000000000000000000000000000000000000", + "logIndex": 2, + "blockHash": "0xc840b1c1ba065e9ee2c9a7835f1769744f8e4a71425bf6c7206434b4075d7e1a" + }, + { + "transactionIndex": 1, + "blockNumber": 169032375, + "transactionHash": "0x26ab296a920292b43a3842e4b3179f45c1374ec77fb60245bc00f44f0ce02129", + "address": "0x8f4245D2eFEC45aF24E5Fa35f07172a830Fc0aDE", + "topics": [ + "0x7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb3847402498" + ], + "data": "0x0000000000000000000000000000000000000000000000000000000000000001", + "logIndex": 3, + "blockHash": "0xc840b1c1ba065e9ee2c9a7835f1769744f8e4a71425bf6c7206434b4075d7e1a" + }, + { + "transactionIndex": 1, + "blockNumber": 169032375, + "transactionHash": "0x26ab296a920292b43a3842e4b3179f45c1374ec77fb60245bc00f44f0ce02129", + "address": "0x8f4245D2eFEC45aF24E5Fa35f07172a830Fc0aDE", + "topics": [ + "0x7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f" + ], + "data": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000009a5b060bd7b8f86c4c0d720a17367729670afb19", + "logIndex": 4, + "blockHash": "0xc840b1c1ba065e9ee2c9a7835f1769744f8e4a71425bf6c7206434b4075d7e1a" + } + ], + "blockNumber": 169032375, + "cumulativeGasUsed": "7144445", + "status": 1, + "byzantium": true + }, + "args": [ + "0x874f1686E8F89374A40196B54F435Cc1A72d04e4", + "0x9a5b060Bd7b8f86c4C0D720a17367729670AfB19", + "0xc9aba0aa00000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000000e00000000000000000000000003c2269811836af69497e5f486a85d7316753cf6200000000000000000000000079e4df078a06ac31bfaa0f672f1f6e9b7f38113e000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000164c617965725a65726f204272696467652061675553440000000000000000000000000000000000000000000000000000000000000000000000000000000000084c5a2d6167555344000000000000000000000000000000000000000000000000" + ], + "numDeployments": 1, + "solcInputHash": "871924e0c138825a2736b76def8fef8d", + "metadata": "{\"compiler\":{\"version\":\"0.8.17+commit.8df45f5f\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_logic\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"admin_\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"_data\",\"type\":\"bytes\"}],\"stateMutability\":\"payable\",\"type\":\"constructor\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"previousAdmin\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"newAdmin\",\"type\":\"address\"}],\"name\":\"AdminChanged\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"beacon\",\"type\":\"address\"}],\"name\":\"BeaconUpgraded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"implementation\",\"type\":\"address\"}],\"name\":\"Upgraded\",\"type\":\"event\"},{\"stateMutability\":\"payable\",\"type\":\"fallback\"},{\"inputs\":[],\"name\":\"admin\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"admin_\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newAdmin\",\"type\":\"address\"}],\"name\":\"changeAdmin\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"implementation\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"implementation_\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newImplementation\",\"type\":\"address\"}],\"name\":\"upgradeTo\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newImplementation\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"}],\"name\":\"upgradeToAndCall\",\"outputs\":[],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"stateMutability\":\"payable\",\"type\":\"receive\"}],\"devdoc\":{\"details\":\"This contract implements a proxy that is upgradeable by an admin. It is fully forked from OpenZeppelin `TransparentUpgradeableProxy` To avoid https://medium.com/nomic-labs-blog/malicious-backdoors-in-ethereum-proxies-62629adf3357[proxy selector clashing], which can potentially be used in an attack, this contract uses the https://blog.openzeppelin.com/the-transparent-proxy-pattern/[transparent proxy pattern]. This pattern implies two things that go hand in hand: 1. If any account other than the admin calls the proxy, the call will be forwarded to the implementation, even if that call matches one of the admin functions exposed by the proxy itself. 2. If the admin calls the proxy, it can access the admin functions, but its calls will never be forwarded to the implementation. If the admin tries to call a function on the implementation it will fail with an error that says \\\"admin cannot fallback to proxy target\\\". These properties mean that the admin account can only be used for admin actions like upgrading the proxy or changing the admin, so it's best if it's a dedicated account that is not used for anything else. This will avoid headaches due to sudden errors when trying to call a function from the proxy implementation. Our recommendation is for the dedicated account to be an instance of the {ProxyAdmin} contract. If set up this way, you should think of the `ProxyAdmin` instance as the real administrative interface of your proxy.\",\"kind\":\"dev\",\"methods\":{\"admin()\":{\"details\":\"Returns the current admin. NOTE: Only the admin can call this function. See {ProxyAdmin-getProxyAdmin}. TIP: To get this value clients can read directly from the storage slot shown below (specified by EIP1967) using the https://eth.wiki/json-rpc/API#eth_getstorageat[`eth_getStorageAt`] RPC call. `0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103`\"},\"changeAdmin(address)\":{\"details\":\"Changes the admin of the proxy. Emits an {AdminChanged} event. NOTE: Only the admin can call this function. See {ProxyAdmin-changeProxyAdmin}.\"},\"constructor\":{\"details\":\"Initializes an upgradeable proxy managed by `_admin`, backed by the implementation at `_logic`, and optionally initialized with `_data` as explained in {ERC1967Proxy-constructor}.\"},\"implementation()\":{\"details\":\"Returns the current implementation. NOTE: Only the admin can call this function. See {ProxyAdmin-getProxyImplementation}. TIP: To get this value clients can read directly from the storage slot shown below (specified by EIP1967) using the https://eth.wiki/json-rpc/API#eth_getstorageat[`eth_getStorageAt`] RPC call. `0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc`\"},\"upgradeTo(address)\":{\"details\":\"Upgrade the implementation of the proxy. NOTE: Only the admin can call this function. See {ProxyAdmin-upgrade}.\"},\"upgradeToAndCall(address,bytes)\":{\"details\":\"Upgrade the implementation of the proxy, and then call a function from the new implementation as specified by `data`, which should be an encoded function call. This is useful to initialize new storage variables in the proxied contract. NOTE: Only the admin can call this function. See {ProxyAdmin-upgradeAndCall}.\"}},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/external/TransparentUpgradeableProxy.sol\":\"TransparentUpgradeableProxy\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":1000000},\"remappings\":[]},\"sources\":{\"@openzeppelin/contracts/interfaces/draft-IERC1822.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.5.0) (interfaces/draft-IERC1822.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev ERC1822: Universal Upgradeable Proxy Standard (UUPS) documents a method for upgradeability through a simplified\\n * proxy whose upgrades are fully controlled by the current implementation.\\n */\\ninterface IERC1822Proxiable {\\n /**\\n * @dev Returns the storage slot that the proxiable contract assumes is being used to store the implementation\\n * address.\\n *\\n * IMPORTANT: A proxy pointing at a proxiable contract should not be considered proxiable itself, because this risks\\n * bricking a proxy that upgrades to it, by delegating to itself until out of gas. Thus it is critical that this\\n * function revert if invoked through a proxy.\\n */\\n function proxiableUUID() external view returns (bytes32);\\n}\\n\",\"keccak256\":\"0x1d4afe6cb24200cc4545eed814ecf5847277dfe5d613a1707aad5fceecebcfff\",\"license\":\"MIT\"},\"@openzeppelin/contracts/proxy/ERC1967/ERC1967Proxy.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.7.0) (proxy/ERC1967/ERC1967Proxy.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../Proxy.sol\\\";\\nimport \\\"./ERC1967Upgrade.sol\\\";\\n\\n/**\\n * @dev This contract implements an upgradeable proxy. It is upgradeable because calls are delegated to an\\n * implementation address that can be changed. This address is stored in storage in the location specified by\\n * https://eips.ethereum.org/EIPS/eip-1967[EIP1967], so that it doesn't conflict with the storage layout of the\\n * implementation behind the proxy.\\n */\\ncontract ERC1967Proxy is Proxy, ERC1967Upgrade {\\n /**\\n * @dev Initializes the upgradeable proxy with an initial implementation specified by `_logic`.\\n *\\n * If `_data` is nonempty, it's used as data in a delegate call to `_logic`. This will typically be an encoded\\n * function call, and allows initializing the storage of the proxy like a Solidity constructor.\\n */\\n constructor(address _logic, bytes memory _data) payable {\\n _upgradeToAndCall(_logic, _data, false);\\n }\\n\\n /**\\n * @dev Returns the current implementation address.\\n */\\n function _implementation() internal view virtual override returns (address impl) {\\n return ERC1967Upgrade._getImplementation();\\n }\\n}\\n\",\"keccak256\":\"0xa2b22da3032e50b55f95ec1d13336102d675f341167aa76db571ef7f8bb7975d\",\"license\":\"MIT\"},\"@openzeppelin/contracts/proxy/ERC1967/ERC1967Upgrade.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.5.0) (proxy/ERC1967/ERC1967Upgrade.sol)\\n\\npragma solidity ^0.8.2;\\n\\nimport \\\"../beacon/IBeacon.sol\\\";\\nimport \\\"../../interfaces/draft-IERC1822.sol\\\";\\nimport \\\"../../utils/Address.sol\\\";\\nimport \\\"../../utils/StorageSlot.sol\\\";\\n\\n/**\\n * @dev This abstract contract provides getters and event emitting update functions for\\n * https://eips.ethereum.org/EIPS/eip-1967[EIP1967] slots.\\n *\\n * _Available since v4.1._\\n *\\n * @custom:oz-upgrades-unsafe-allow delegatecall\\n */\\nabstract contract ERC1967Upgrade {\\n // This is the keccak-256 hash of \\\"eip1967.proxy.rollback\\\" subtracted by 1\\n bytes32 private constant _ROLLBACK_SLOT = 0x4910fdfa16fed3260ed0e7147f7cc6da11a60208b5b9406d12a635614ffd9143;\\n\\n /**\\n * @dev Storage slot with the address of the current implementation.\\n * This is the keccak-256 hash of \\\"eip1967.proxy.implementation\\\" subtracted by 1, and is\\n * validated in the constructor.\\n */\\n bytes32 internal constant _IMPLEMENTATION_SLOT = 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc;\\n\\n /**\\n * @dev Emitted when the implementation is upgraded.\\n */\\n event Upgraded(address indexed implementation);\\n\\n /**\\n * @dev Returns the current implementation address.\\n */\\n function _getImplementation() internal view returns (address) {\\n return StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value;\\n }\\n\\n /**\\n * @dev Stores a new address in the EIP1967 implementation slot.\\n */\\n function _setImplementation(address newImplementation) private {\\n require(Address.isContract(newImplementation), \\\"ERC1967: new implementation is not a contract\\\");\\n StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value = newImplementation;\\n }\\n\\n /**\\n * @dev Perform implementation upgrade\\n *\\n * Emits an {Upgraded} event.\\n */\\n function _upgradeTo(address newImplementation) internal {\\n _setImplementation(newImplementation);\\n emit Upgraded(newImplementation);\\n }\\n\\n /**\\n * @dev Perform implementation upgrade with additional setup call.\\n *\\n * Emits an {Upgraded} event.\\n */\\n function _upgradeToAndCall(\\n address newImplementation,\\n bytes memory data,\\n bool forceCall\\n ) internal {\\n _upgradeTo(newImplementation);\\n if (data.length > 0 || forceCall) {\\n Address.functionDelegateCall(newImplementation, data);\\n }\\n }\\n\\n /**\\n * @dev Perform implementation upgrade with security checks for UUPS proxies, and additional setup call.\\n *\\n * Emits an {Upgraded} event.\\n */\\n function _upgradeToAndCallUUPS(\\n address newImplementation,\\n bytes memory data,\\n bool forceCall\\n ) internal {\\n // Upgrades from old implementations will perform a rollback test. This test requires the new\\n // implementation to upgrade back to the old, non-ERC1822 compliant, implementation. Removing\\n // this special case will break upgrade paths from old UUPS implementation to new ones.\\n if (StorageSlot.getBooleanSlot(_ROLLBACK_SLOT).value) {\\n _setImplementation(newImplementation);\\n } else {\\n try IERC1822Proxiable(newImplementation).proxiableUUID() returns (bytes32 slot) {\\n require(slot == _IMPLEMENTATION_SLOT, \\\"ERC1967Upgrade: unsupported proxiableUUID\\\");\\n } catch {\\n revert(\\\"ERC1967Upgrade: new implementation is not UUPS\\\");\\n }\\n _upgradeToAndCall(newImplementation, data, forceCall);\\n }\\n }\\n\\n /**\\n * @dev Storage slot with the admin of the contract.\\n * This is the keccak-256 hash of \\\"eip1967.proxy.admin\\\" subtracted by 1, and is\\n * validated in the constructor.\\n */\\n bytes32 internal constant _ADMIN_SLOT = 0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103;\\n\\n /**\\n * @dev Emitted when the admin account has changed.\\n */\\n event AdminChanged(address previousAdmin, address newAdmin);\\n\\n /**\\n * @dev Returns the current admin.\\n */\\n function _getAdmin() internal view returns (address) {\\n return StorageSlot.getAddressSlot(_ADMIN_SLOT).value;\\n }\\n\\n /**\\n * @dev Stores a new address in the EIP1967 admin slot.\\n */\\n function _setAdmin(address newAdmin) private {\\n require(newAdmin != address(0), \\\"ERC1967: new admin is the zero address\\\");\\n StorageSlot.getAddressSlot(_ADMIN_SLOT).value = newAdmin;\\n }\\n\\n /**\\n * @dev Changes the admin of the proxy.\\n *\\n * Emits an {AdminChanged} event.\\n */\\n function _changeAdmin(address newAdmin) internal {\\n emit AdminChanged(_getAdmin(), newAdmin);\\n _setAdmin(newAdmin);\\n }\\n\\n /**\\n * @dev The storage slot of the UpgradeableBeacon contract which defines the implementation for this proxy.\\n * This is bytes32(uint256(keccak256('eip1967.proxy.beacon')) - 1)) and is validated in the constructor.\\n */\\n bytes32 internal constant _BEACON_SLOT = 0xa3f0ad74e5423aebfd80d3ef4346578335a9a72aeaee59ff6cb3582b35133d50;\\n\\n /**\\n * @dev Emitted when the beacon is upgraded.\\n */\\n event BeaconUpgraded(address indexed beacon);\\n\\n /**\\n * @dev Returns the current beacon.\\n */\\n function _getBeacon() internal view returns (address) {\\n return StorageSlot.getAddressSlot(_BEACON_SLOT).value;\\n }\\n\\n /**\\n * @dev Stores a new beacon in the EIP1967 beacon slot.\\n */\\n function _setBeacon(address newBeacon) private {\\n require(Address.isContract(newBeacon), \\\"ERC1967: new beacon is not a contract\\\");\\n require(\\n Address.isContract(IBeacon(newBeacon).implementation()),\\n \\\"ERC1967: beacon implementation is not a contract\\\"\\n );\\n StorageSlot.getAddressSlot(_BEACON_SLOT).value = newBeacon;\\n }\\n\\n /**\\n * @dev Perform beacon upgrade with additional setup call. Note: This upgrades the address of the beacon, it does\\n * not upgrade the implementation contained in the beacon (see {UpgradeableBeacon-_setImplementation} for that).\\n *\\n * Emits a {BeaconUpgraded} event.\\n */\\n function _upgradeBeaconToAndCall(\\n address newBeacon,\\n bytes memory data,\\n bool forceCall\\n ) internal {\\n _setBeacon(newBeacon);\\n emit BeaconUpgraded(newBeacon);\\n if (data.length > 0 || forceCall) {\\n Address.functionDelegateCall(IBeacon(newBeacon).implementation(), data);\\n }\\n }\\n}\\n\",\"keccak256\":\"0xabf3f59bc0e5423eae45e459dbe92e7052c6983628d39008590edc852a62f94a\",\"license\":\"MIT\"},\"@openzeppelin/contracts/proxy/Proxy.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.6.0) (proxy/Proxy.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev This abstract contract provides a fallback function that delegates all calls to another contract using the EVM\\n * instruction `delegatecall`. We refer to the second contract as the _implementation_ behind the proxy, and it has to\\n * be specified by overriding the virtual {_implementation} function.\\n *\\n * Additionally, delegation to the implementation can be triggered manually through the {_fallback} function, or to a\\n * different contract through the {_delegate} function.\\n *\\n * The success and return data of the delegated call will be returned back to the caller of the proxy.\\n */\\nabstract contract Proxy {\\n /**\\n * @dev Delegates the current call to `implementation`.\\n *\\n * This function does not return to its internal call site, it will return directly to the external caller.\\n */\\n function _delegate(address implementation) internal virtual {\\n assembly {\\n // Copy msg.data. We take full control of memory in this inline assembly\\n // block because it will not return to Solidity code. We overwrite the\\n // Solidity scratch pad at memory position 0.\\n calldatacopy(0, 0, calldatasize())\\n\\n // Call the implementation.\\n // out and outsize are 0 because we don't know the size yet.\\n let result := delegatecall(gas(), implementation, 0, calldatasize(), 0, 0)\\n\\n // Copy the returned data.\\n returndatacopy(0, 0, returndatasize())\\n\\n switch result\\n // delegatecall returns 0 on error.\\n case 0 {\\n revert(0, returndatasize())\\n }\\n default {\\n return(0, returndatasize())\\n }\\n }\\n }\\n\\n /**\\n * @dev This is a virtual function that should be overridden so it returns the address to which the fallback function\\n * and {_fallback} should delegate.\\n */\\n function _implementation() internal view virtual returns (address);\\n\\n /**\\n * @dev Delegates the current call to the address returned by `_implementation()`.\\n *\\n * This function does not return to its internal call site, it will return directly to the external caller.\\n */\\n function _fallback() internal virtual {\\n _beforeFallback();\\n _delegate(_implementation());\\n }\\n\\n /**\\n * @dev Fallback function that delegates calls to the address returned by `_implementation()`. Will run if no other\\n * function in the contract matches the call data.\\n */\\n fallback() external payable virtual {\\n _fallback();\\n }\\n\\n /**\\n * @dev Fallback function that delegates calls to the address returned by `_implementation()`. Will run if call data\\n * is empty.\\n */\\n receive() external payable virtual {\\n _fallback();\\n }\\n\\n /**\\n * @dev Hook that is called before falling back to the implementation. Can happen as part of a manual `_fallback`\\n * call, or as part of the Solidity `fallback` or `receive` functions.\\n *\\n * If overridden should call `super._beforeFallback()`.\\n */\\n function _beforeFallback() internal virtual {}\\n}\\n\",\"keccak256\":\"0xc130fe33f1b2132158531a87734153293f6d07bc263ff4ac90e85da9c82c0e27\",\"license\":\"MIT\"},\"@openzeppelin/contracts/proxy/beacon/IBeacon.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (proxy/beacon/IBeacon.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev This is the interface that {BeaconProxy} expects of its beacon.\\n */\\ninterface IBeacon {\\n /**\\n * @dev Must return an address that can be used as a delegate call target.\\n *\\n * {BeaconProxy} will check that this address is a contract.\\n */\\n function implementation() external view returns (address);\\n}\\n\",\"keccak256\":\"0xd50a3421ac379ccb1be435fa646d66a65c986b4924f0849839f08692f39dde61\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/Address.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.7.0) (utils/Address.sol)\\n\\npragma solidity ^0.8.1;\\n\\n/**\\n * @dev Collection of functions related to the address type\\n */\\nlibrary Address {\\n /**\\n * @dev Returns true if `account` is a contract.\\n *\\n * [IMPORTANT]\\n * ====\\n * It is unsafe to assume that an address for which this function returns\\n * false is an externally-owned account (EOA) and not a contract.\\n *\\n * Among others, `isContract` will return false for the following\\n * types of addresses:\\n *\\n * - an externally-owned account\\n * - a contract in construction\\n * - an address where a contract will be created\\n * - an address where a contract lived, but was destroyed\\n * ====\\n *\\n * [IMPORTANT]\\n * ====\\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\\n *\\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\\n * constructor.\\n * ====\\n */\\n function isContract(address account) internal view returns (bool) {\\n // This method relies on extcodesize/address.code.length, which returns 0\\n // for contracts in construction, since the code is only stored at the end\\n // of the constructor execution.\\n\\n return account.code.length > 0;\\n }\\n\\n /**\\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\\n * `recipient`, forwarding all available gas and reverting on errors.\\n *\\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\\n * imposed by `transfer`, making them unable to receive funds via\\n * `transfer`. {sendValue} removes this limitation.\\n *\\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\\n *\\n * IMPORTANT: because control is transferred to `recipient`, care must be\\n * taken to not create reentrancy vulnerabilities. Consider using\\n * {ReentrancyGuard} or the\\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\\n */\\n function sendValue(address payable recipient, uint256 amount) internal {\\n require(address(this).balance >= amount, \\\"Address: insufficient balance\\\");\\n\\n (bool success, ) = recipient.call{value: amount}(\\\"\\\");\\n require(success, \\\"Address: unable to send value, recipient may have reverted\\\");\\n }\\n\\n /**\\n * @dev Performs a Solidity function call using a low level `call`. A\\n * plain `call` is an unsafe replacement for a function call: use this\\n * function instead.\\n *\\n * If `target` reverts with a revert reason, it is bubbled up by this\\n * function (like regular Solidity function calls).\\n *\\n * Returns the raw returned data. To convert to the expected return value,\\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\\n *\\n * Requirements:\\n *\\n * - `target` must be a contract.\\n * - calling `target` with `data` must not revert.\\n *\\n * _Available since v3.1._\\n */\\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\\n return functionCall(target, data, \\\"Address: low-level call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\\n * `errorMessage` as a fallback revert reason when `target` reverts.\\n *\\n * _Available since v3.1._\\n */\\n function functionCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n return functionCallWithValue(target, data, 0, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but also transferring `value` wei to `target`.\\n *\\n * Requirements:\\n *\\n * - the calling contract must have an ETH balance of at least `value`.\\n * - the called Solidity function must be `payable`.\\n *\\n * _Available since v3.1._\\n */\\n function functionCallWithValue(\\n address target,\\n bytes memory data,\\n uint256 value\\n ) internal returns (bytes memory) {\\n return functionCallWithValue(target, data, value, \\\"Address: low-level call with value failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\\n * with `errorMessage` as a fallback revert reason when `target` reverts.\\n *\\n * _Available since v3.1._\\n */\\n function functionCallWithValue(\\n address target,\\n bytes memory data,\\n uint256 value,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n require(address(this).balance >= value, \\\"Address: insufficient balance for call\\\");\\n require(isContract(target), \\\"Address: call to non-contract\\\");\\n\\n (bool success, bytes memory returndata) = target.call{value: value}(data);\\n return verifyCallResult(success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but performing a static call.\\n *\\n * _Available since v3.3._\\n */\\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\\n return functionStaticCall(target, data, \\\"Address: low-level static call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\\n * but performing a static call.\\n *\\n * _Available since v3.3._\\n */\\n function functionStaticCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal view returns (bytes memory) {\\n require(isContract(target), \\\"Address: static call to non-contract\\\");\\n\\n (bool success, bytes memory returndata) = target.staticcall(data);\\n return verifyCallResult(success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but performing a delegate call.\\n *\\n * _Available since v3.4._\\n */\\n function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {\\n return functionDelegateCall(target, data, \\\"Address: low-level delegate call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\\n * but performing a delegate call.\\n *\\n * _Available since v3.4._\\n */\\n function functionDelegateCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n require(isContract(target), \\\"Address: delegate call to non-contract\\\");\\n\\n (bool success, bytes memory returndata) = target.delegatecall(data);\\n return verifyCallResult(success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the\\n * revert reason using the provided one.\\n *\\n * _Available since v4.3._\\n */\\n function verifyCallResult(\\n bool success,\\n bytes memory returndata,\\n string memory errorMessage\\n ) internal pure returns (bytes memory) {\\n if (success) {\\n return returndata;\\n } else {\\n // Look for revert reason and bubble it up if present\\n if (returndata.length > 0) {\\n // The easiest way to bubble the revert reason is using memory via assembly\\n /// @solidity memory-safe-assembly\\n assembly {\\n let returndata_size := mload(returndata)\\n revert(add(32, returndata), returndata_size)\\n }\\n } else {\\n revert(errorMessage);\\n }\\n }\\n }\\n}\\n\",\"keccak256\":\"0xd6153ce99bcdcce22b124f755e72553295be6abcd63804cfdffceb188b8bef10\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/StorageSlot.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.7.0) (utils/StorageSlot.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Library for reading and writing primitive types to specific storage slots.\\n *\\n * Storage slots are often used to avoid storage conflict when dealing with upgradeable contracts.\\n * This library helps with reading and writing to such slots without the need for inline assembly.\\n *\\n * The functions in this library return Slot structs that contain a `value` member that can be used to read or write.\\n *\\n * Example usage to set ERC1967 implementation slot:\\n * ```\\n * contract ERC1967 {\\n * bytes32 internal constant _IMPLEMENTATION_SLOT = 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc;\\n *\\n * function _getImplementation() internal view returns (address) {\\n * return StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value;\\n * }\\n *\\n * function _setImplementation(address newImplementation) internal {\\n * require(Address.isContract(newImplementation), \\\"ERC1967: new implementation is not a contract\\\");\\n * StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value = newImplementation;\\n * }\\n * }\\n * ```\\n *\\n * _Available since v4.1 for `address`, `bool`, `bytes32`, and `uint256`._\\n */\\nlibrary StorageSlot {\\n struct AddressSlot {\\n address value;\\n }\\n\\n struct BooleanSlot {\\n bool value;\\n }\\n\\n struct Bytes32Slot {\\n bytes32 value;\\n }\\n\\n struct Uint256Slot {\\n uint256 value;\\n }\\n\\n /**\\n * @dev Returns an `AddressSlot` with member `value` located at `slot`.\\n */\\n function getAddressSlot(bytes32 slot) internal pure returns (AddressSlot storage r) {\\n /// @solidity memory-safe-assembly\\n assembly {\\n r.slot := slot\\n }\\n }\\n\\n /**\\n * @dev Returns an `BooleanSlot` with member `value` located at `slot`.\\n */\\n function getBooleanSlot(bytes32 slot) internal pure returns (BooleanSlot storage r) {\\n /// @solidity memory-safe-assembly\\n assembly {\\n r.slot := slot\\n }\\n }\\n\\n /**\\n * @dev Returns an `Bytes32Slot` with member `value` located at `slot`.\\n */\\n function getBytes32Slot(bytes32 slot) internal pure returns (Bytes32Slot storage r) {\\n /// @solidity memory-safe-assembly\\n assembly {\\n r.slot := slot\\n }\\n }\\n\\n /**\\n * @dev Returns an `Uint256Slot` with member `value` located at `slot`.\\n */\\n function getUint256Slot(bytes32 slot) internal pure returns (Uint256Slot storage r) {\\n /// @solidity memory-safe-assembly\\n assembly {\\n r.slot := slot\\n }\\n }\\n}\\n\",\"keccak256\":\"0xd5c50c54bf02740ebd122ff06832546cb5fa84486d52695a9ccfd11666e0c81d\",\"license\":\"MIT\"},\"contracts/external/TransparentUpgradeableProxy.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-3.0\\n\\npragma solidity ^0.8.12;\\n\\nimport \\\"@openzeppelin/contracts/proxy/ERC1967/ERC1967Proxy.sol\\\";\\n\\n/**\\n * @dev This contract implements a proxy that is upgradeable by an admin. It is fully forked from OpenZeppelin\\n * `TransparentUpgradeableProxy`\\n *\\n * To avoid https://medium.com/nomic-labs-blog/malicious-backdoors-in-ethereum-proxies-62629adf3357[proxy selector\\n * clashing], which can potentially be used in an attack, this contract uses the\\n * https://blog.openzeppelin.com/the-transparent-proxy-pattern/[transparent proxy pattern]. This pattern implies two\\n * things that go hand in hand:\\n *\\n * 1. If any account other than the admin calls the proxy, the call will be forwarded to the implementation, even if\\n * that call matches one of the admin functions exposed by the proxy itself.\\n * 2. If the admin calls the proxy, it can access the admin functions, but its calls will never be forwarded to the\\n * implementation. If the admin tries to call a function on the implementation it will fail with an error that says\\n * \\\"admin cannot fallback to proxy target\\\".\\n *\\n * These properties mean that the admin account can only be used for admin actions like upgrading the proxy or changing\\n * the admin, so it's best if it's a dedicated account that is not used for anything else. This will avoid headaches due\\n * to sudden errors when trying to call a function from the proxy implementation.\\n *\\n * Our recommendation is for the dedicated account to be an instance of the {ProxyAdmin} contract. If set up this way,\\n * you should think of the `ProxyAdmin` instance as the real administrative interface of your proxy.\\n */\\ncontract TransparentUpgradeableProxy is ERC1967Proxy {\\n /**\\n * @dev Initializes an upgradeable proxy managed by `_admin`, backed by the implementation at `_logic`, and\\n * optionally initialized with `_data` as explained in {ERC1967Proxy-constructor}.\\n */\\n constructor(address _logic, address admin_, bytes memory _data) payable ERC1967Proxy(_logic, _data) {\\n assert(_ADMIN_SLOT == bytes32(uint256(keccak256(\\\"eip1967.proxy.admin\\\")) - 1));\\n _changeAdmin(admin_);\\n }\\n\\n /**\\n * @dev Modifier used internally that will delegate the call to the implementation unless the sender is the admin.\\n */\\n modifier ifAdmin() {\\n if (msg.sender == _getAdmin()) {\\n _;\\n } else {\\n _fallback();\\n }\\n }\\n\\n /**\\n * @dev Returns the current admin.\\n *\\n * NOTE: Only the admin can call this function. See {ProxyAdmin-getProxyAdmin}.\\n *\\n * TIP: To get this value clients can read directly from the storage slot shown below (specified by EIP1967) using the\\n * https://eth.wiki/json-rpc/API#eth_getstorageat[`eth_getStorageAt`] RPC call.\\n * `0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103`\\n */\\n function admin() external ifAdmin returns (address admin_) {\\n admin_ = _getAdmin();\\n }\\n\\n /**\\n * @dev Returns the current implementation.\\n *\\n * NOTE: Only the admin can call this function. See {ProxyAdmin-getProxyImplementation}.\\n *\\n * TIP: To get this value clients can read directly from the storage slot shown below (specified by EIP1967) using the\\n * https://eth.wiki/json-rpc/API#eth_getstorageat[`eth_getStorageAt`] RPC call.\\n * `0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc`\\n */\\n function implementation() external ifAdmin returns (address implementation_) {\\n implementation_ = _implementation();\\n }\\n\\n /**\\n * @dev Changes the admin of the proxy.\\n *\\n * Emits an {AdminChanged} event.\\n *\\n * NOTE: Only the admin can call this function. See {ProxyAdmin-changeProxyAdmin}.\\n */\\n function changeAdmin(address newAdmin) external virtual ifAdmin {\\n _changeAdmin(newAdmin);\\n }\\n\\n /**\\n * @dev Upgrade the implementation of the proxy.\\n *\\n * NOTE: Only the admin can call this function. See {ProxyAdmin-upgrade}.\\n */\\n function upgradeTo(address newImplementation) external ifAdmin {\\n _upgradeToAndCall(newImplementation, bytes(\\\"\\\"), false);\\n }\\n\\n /**\\n * @dev Upgrade the implementation of the proxy, and then call a function from the new implementation as specified\\n * by `data`, which should be an encoded function call. This is useful to initialize new storage variables in the\\n * proxied contract.\\n *\\n * NOTE: Only the admin can call this function. See {ProxyAdmin-upgradeAndCall}.\\n */\\n function upgradeToAndCall(address newImplementation, bytes calldata data) external payable ifAdmin {\\n _upgradeToAndCall(newImplementation, data, true);\\n }\\n\\n /**\\n * @dev Returns the current admin.\\n */\\n function _admin() internal view virtual returns (address) {\\n return _getAdmin();\\n }\\n\\n /**\\n * @dev Makes sure the admin cannot access the fallback function. See {Proxy-_beforeFallback}.\\n */\\n function _beforeFallback() internal virtual override {\\n require(msg.sender != _getAdmin(), \\\"TransparentUpgradeableProxy: admin cannot fallback to proxy target\\\");\\n super._beforeFallback();\\n }\\n}\\n\",\"keccak256\":\"0x93a67a0f612ea3ff2a76315e138a6a88267270a1379d3cc7be52845fbbe611e2\",\"license\":\"GPL-3.0\"}},\"version\":1}", + "bytecode": "0x6080604052604051620010bb380380620010bb8339810160408190526200002691620004d8565b828162000036828260006200009a565b5062000066905060017fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6104620005b8565b6000805160206200107483398151915214620000865762000086620005da565b6200009182620000d7565b50505062000643565b620000a58362000132565b600082511180620000b35750805b15620000d257620000d083836200017460201b6200028c1760201c565b505b505050565b7f7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f62000102620001a5565b604080516001600160a01b03928316815291841660208301520160405180910390a16200012f81620001de565b50565b6200013d8162000293565b6040516001600160a01b038216907fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b90600090a250565b60606200019c8383604051806060016040528060278152602001620010946027913962000347565b90505b92915050565b6000620001cf6000805160206200107483398151915260001b6200042f60201b6200022e1760201c565b546001600160a01b0316919050565b6001600160a01b038116620002495760405162461bcd60e51b815260206004820152602660248201527f455243313936373a206e65772061646d696e20697320746865207a65726f206160448201526564647265737360d01b60648201526084015b60405180910390fd5b80620002726000805160206200107483398151915260001b6200042f60201b6200022e1760201c565b80546001600160a01b0319166001600160a01b039290921691909117905550565b620002a9816200043260201b620002b81760201c565b6200030d5760405162461bcd60e51b815260206004820152602d60248201527f455243313936373a206e657720696d706c656d656e746174696f6e206973206e60448201526c1bdd08184818dbdb9d1c9858dd609a1b606482015260840162000240565b80620002727f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc60001b6200042f60201b6200022e1760201c565b60606001600160a01b0384163b620003b15760405162461bcd60e51b815260206004820152602660248201527f416464726573733a2064656c65676174652063616c6c20746f206e6f6e2d636f6044820152651b9d1c9858dd60d21b606482015260840162000240565b600080856001600160a01b031685604051620003ce9190620005f0565b600060405180830381855af49150503d80600081146200040b576040519150601f19603f3d011682016040523d82523d6000602084013e62000410565b606091505b5090925090506200042382828662000441565b925050505b9392505050565b90565b6001600160a01b03163b151590565b606083156200045257508162000428565b825115620004635782518084602001fd5b8160405162461bcd60e51b81526004016200024091906200060e565b80516001600160a01b03811681146200049757600080fd5b919050565b634e487b7160e01b600052604160045260246000fd5b60005b83811015620004cf578181015183820152602001620004b5565b50506000910152565b600080600060608486031215620004ee57600080fd5b620004f9846200047f565b925062000509602085016200047f565b60408501519092506001600160401b03808211156200052757600080fd5b818601915086601f8301126200053c57600080fd5b8151818111156200055157620005516200049c565b604051601f8201601f19908116603f011681019083821181831017156200057c576200057c6200049c565b816040528281528960208487010111156200059657600080fd5b620005a9836020830160208801620004b2565b80955050505050509250925092565b818103818111156200019f57634e487b7160e01b600052601160045260246000fd5b634e487b7160e01b600052600160045260246000fd5b6000825162000604818460208701620004b2565b9190910192915050565b60208152600082518060208401526200062f816040850160208701620004b2565b601f01601f19169190910160400192915050565b610a2180620006536000396000f3fe60806040526004361061005e5760003560e01c80635c60da1b116100435780635c60da1b146100a85780638f283970146100e6578063f851a440146101065761006d565b80633659cfe6146100755780634f1ef286146100955761006d565b3661006d5761006b61011b565b005b61006b61011b565b34801561008157600080fd5b5061006b610090366004610895565b610135565b61006b6100a33660046108b0565b61017f565b3480156100b457600080fd5b506100bd6101f3565b60405173ffffffffffffffffffffffffffffffffffffffff909116815260200160405180910390f35b3480156100f257600080fd5b5061006b610101366004610895565b610231565b34801561011257600080fd5b506100bd61025e565b6101236102d4565b61013361012e6103ab565b6103b5565b565b61013d6103d9565b73ffffffffffffffffffffffffffffffffffffffff1633036101775761017481604051806020016040528060008152506000610419565b50565b61017461011b565b6101876103d9565b73ffffffffffffffffffffffffffffffffffffffff1633036101eb576101e68383838080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525060019250610419915050565b505050565b6101e661011b565b60006101fd6103d9565b73ffffffffffffffffffffffffffffffffffffffff163303610226576102216103ab565b905090565b61022e61011b565b90565b6102396103d9565b73ffffffffffffffffffffffffffffffffffffffff1633036101775761017481610444565b60006102686103d9565b73ffffffffffffffffffffffffffffffffffffffff163303610226576102216103d9565b60606102b183836040518060600160405280602781526020016109c5602791396104a5565b9392505050565b73ffffffffffffffffffffffffffffffffffffffff163b151590565b6102dc6103d9565b73ffffffffffffffffffffffffffffffffffffffff163303610133576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604260248201527f5472616e73706172656e745570677261646561626c6550726f78793a2061646d60448201527f696e2063616e6e6f742066616c6c6261636b20746f2070726f7879207461726760648201527f6574000000000000000000000000000000000000000000000000000000000000608482015260a4015b60405180910390fd5b60006102216105cd565b3660008037600080366000845af43d6000803e8080156103d4573d6000f35b3d6000fd5b60007fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035b5473ffffffffffffffffffffffffffffffffffffffff16919050565b610422836105f5565b60008251118061042f5750805b156101e65761043e838361028c565b50505050565b7f7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f61046d6103d9565b6040805173ffffffffffffffffffffffffffffffffffffffff928316815291841660208301520160405180910390a161017481610642565b606073ffffffffffffffffffffffffffffffffffffffff84163b61054b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f416464726573733a2064656c65676174652063616c6c20746f206e6f6e2d636f60448201527f6e7472616374000000000000000000000000000000000000000000000000000060648201526084016103a2565b6000808573ffffffffffffffffffffffffffffffffffffffff16856040516105739190610957565b600060405180830381855af49150503d80600081146105ae576040519150601f19603f3d011682016040523d82523d6000602084013e6105b3565b606091505b50915091506105c382828661074e565b9695505050505050565b60007f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc6103fd565b6105fe816107a1565b60405173ffffffffffffffffffffffffffffffffffffffff8216907fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b90600090a250565b73ffffffffffffffffffffffffffffffffffffffff81166106e5576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f455243313936373a206e65772061646d696e20697320746865207a65726f206160448201527f646472657373000000000000000000000000000000000000000000000000000060648201526084016103a2565b807fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035b80547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff9290921691909117905550565b6060831561075d5750816102b1565b82511561076d5782518084602001fd5b816040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016103a29190610973565b73ffffffffffffffffffffffffffffffffffffffff81163b610845576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602d60248201527f455243313936373a206e657720696d706c656d656e746174696f6e206973206e60448201527f6f74206120636f6e74726163740000000000000000000000000000000000000060648201526084016103a2565b807f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc610708565b803573ffffffffffffffffffffffffffffffffffffffff8116811461089057600080fd5b919050565b6000602082840312156108a757600080fd5b6102b18261086c565b6000806000604084860312156108c557600080fd5b6108ce8461086c565b9250602084013567ffffffffffffffff808211156108eb57600080fd5b818601915086601f8301126108ff57600080fd5b81358181111561090e57600080fd5b87602082850101111561092057600080fd5b6020830194508093505050509250925092565b60005b8381101561094e578181015183820152602001610936565b50506000910152565b60008251610969818460208701610933565b9190910192915050565b6020815260008251806020840152610992816040850160208701610933565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016919091016040019291505056fe416464726573733a206c6f772d6c6576656c2064656c65676174652063616c6c206661696c6564a2646970667358221220e96638b07fb1675d93a95c49e417bc8111448b23a59918698cdcd8fd488dd7cf64736f6c63430008110033b53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103416464726573733a206c6f772d6c6576656c2064656c65676174652063616c6c206661696c6564", + "deployedBytecode": "0x60806040526004361061005e5760003560e01c80635c60da1b116100435780635c60da1b146100a85780638f283970146100e6578063f851a440146101065761006d565b80633659cfe6146100755780634f1ef286146100955761006d565b3661006d5761006b61011b565b005b61006b61011b565b34801561008157600080fd5b5061006b610090366004610895565b610135565b61006b6100a33660046108b0565b61017f565b3480156100b457600080fd5b506100bd6101f3565b60405173ffffffffffffffffffffffffffffffffffffffff909116815260200160405180910390f35b3480156100f257600080fd5b5061006b610101366004610895565b610231565b34801561011257600080fd5b506100bd61025e565b6101236102d4565b61013361012e6103ab565b6103b5565b565b61013d6103d9565b73ffffffffffffffffffffffffffffffffffffffff1633036101775761017481604051806020016040528060008152506000610419565b50565b61017461011b565b6101876103d9565b73ffffffffffffffffffffffffffffffffffffffff1633036101eb576101e68383838080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525060019250610419915050565b505050565b6101e661011b565b60006101fd6103d9565b73ffffffffffffffffffffffffffffffffffffffff163303610226576102216103ab565b905090565b61022e61011b565b90565b6102396103d9565b73ffffffffffffffffffffffffffffffffffffffff1633036101775761017481610444565b60006102686103d9565b73ffffffffffffffffffffffffffffffffffffffff163303610226576102216103d9565b60606102b183836040518060600160405280602781526020016109c5602791396104a5565b9392505050565b73ffffffffffffffffffffffffffffffffffffffff163b151590565b6102dc6103d9565b73ffffffffffffffffffffffffffffffffffffffff163303610133576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604260248201527f5472616e73706172656e745570677261646561626c6550726f78793a2061646d60448201527f696e2063616e6e6f742066616c6c6261636b20746f2070726f7879207461726760648201527f6574000000000000000000000000000000000000000000000000000000000000608482015260a4015b60405180910390fd5b60006102216105cd565b3660008037600080366000845af43d6000803e8080156103d4573d6000f35b3d6000fd5b60007fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035b5473ffffffffffffffffffffffffffffffffffffffff16919050565b610422836105f5565b60008251118061042f5750805b156101e65761043e838361028c565b50505050565b7f7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f61046d6103d9565b6040805173ffffffffffffffffffffffffffffffffffffffff928316815291841660208301520160405180910390a161017481610642565b606073ffffffffffffffffffffffffffffffffffffffff84163b61054b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f416464726573733a2064656c65676174652063616c6c20746f206e6f6e2d636f60448201527f6e7472616374000000000000000000000000000000000000000000000000000060648201526084016103a2565b6000808573ffffffffffffffffffffffffffffffffffffffff16856040516105739190610957565b600060405180830381855af49150503d80600081146105ae576040519150601f19603f3d011682016040523d82523d6000602084013e6105b3565b606091505b50915091506105c382828661074e565b9695505050505050565b60007f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc6103fd565b6105fe816107a1565b60405173ffffffffffffffffffffffffffffffffffffffff8216907fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b90600090a250565b73ffffffffffffffffffffffffffffffffffffffff81166106e5576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f455243313936373a206e65772061646d696e20697320746865207a65726f206160448201527f646472657373000000000000000000000000000000000000000000000000000060648201526084016103a2565b807fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035b80547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff9290921691909117905550565b6060831561075d5750816102b1565b82511561076d5782518084602001fd5b816040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016103a29190610973565b73ffffffffffffffffffffffffffffffffffffffff81163b610845576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602d60248201527f455243313936373a206e657720696d706c656d656e746174696f6e206973206e60448201527f6f74206120636f6e74726163740000000000000000000000000000000000000060648201526084016103a2565b807f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc610708565b803573ffffffffffffffffffffffffffffffffffffffff8116811461089057600080fd5b919050565b6000602082840312156108a757600080fd5b6102b18261086c565b6000806000604084860312156108c557600080fd5b6108ce8461086c565b9250602084013567ffffffffffffffff808211156108eb57600080fd5b818601915086601f8301126108ff57600080fd5b81358181111561090e57600080fd5b87602082850101111561092057600080fd5b6020830194508093505050509250925092565b60005b8381101561094e578181015183820152602001610936565b50506000910152565b60008251610969818460208701610933565b9190910192915050565b6020815260008251806020840152610992816040850160208701610933565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016919091016040019291505056fe416464726573733a206c6f772d6c6576656c2064656c65676174652063616c6c206661696c6564a2646970667358221220e96638b07fb1675d93a95c49e417bc8111448b23a59918698cdcd8fd488dd7cf64736f6c63430008110033", + "devdoc": { + "details": "This contract implements a proxy that is upgradeable by an admin. It is fully forked from OpenZeppelin `TransparentUpgradeableProxy` To avoid https://medium.com/nomic-labs-blog/malicious-backdoors-in-ethereum-proxies-62629adf3357[proxy selector clashing], which can potentially be used in an attack, this contract uses the https://blog.openzeppelin.com/the-transparent-proxy-pattern/[transparent proxy pattern]. This pattern implies two things that go hand in hand: 1. If any account other than the admin calls the proxy, the call will be forwarded to the implementation, even if that call matches one of the admin functions exposed by the proxy itself. 2. If the admin calls the proxy, it can access the admin functions, but its calls will never be forwarded to the implementation. If the admin tries to call a function on the implementation it will fail with an error that says \"admin cannot fallback to proxy target\". These properties mean that the admin account can only be used for admin actions like upgrading the proxy or changing the admin, so it's best if it's a dedicated account that is not used for anything else. This will avoid headaches due to sudden errors when trying to call a function from the proxy implementation. Our recommendation is for the dedicated account to be an instance of the {ProxyAdmin} contract. If set up this way, you should think of the `ProxyAdmin` instance as the real administrative interface of your proxy.", + "kind": "dev", + "methods": { + "admin()": { + "details": "Returns the current admin. NOTE: Only the admin can call this function. See {ProxyAdmin-getProxyAdmin}. TIP: To get this value clients can read directly from the storage slot shown below (specified by EIP1967) using the https://eth.wiki/json-rpc/API#eth_getstorageat[`eth_getStorageAt`] RPC call. `0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103`" + }, + "changeAdmin(address)": { + "details": "Changes the admin of the proxy. Emits an {AdminChanged} event. NOTE: Only the admin can call this function. See {ProxyAdmin-changeProxyAdmin}." + }, + "constructor": { + "details": "Initializes an upgradeable proxy managed by `_admin`, backed by the implementation at `_logic`, and optionally initialized with `_data` as explained in {ERC1967Proxy-constructor}." + }, + "implementation()": { + "details": "Returns the current implementation. NOTE: Only the admin can call this function. See {ProxyAdmin-getProxyImplementation}. TIP: To get this value clients can read directly from the storage slot shown below (specified by EIP1967) using the https://eth.wiki/json-rpc/API#eth_getstorageat[`eth_getStorageAt`] RPC call. `0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc`" + }, + "upgradeTo(address)": { + "details": "Upgrade the implementation of the proxy. NOTE: Only the admin can call this function. See {ProxyAdmin-upgrade}." + }, + "upgradeToAndCall(address,bytes)": { + "details": "Upgrade the implementation of the proxy, and then call a function from the new implementation as specified by `data`, which should be an encoded function call. This is useful to initialize new storage variables in the proxied contract. NOTE: Only the admin can call this function. See {ProxyAdmin-upgradeAndCall}." + } + }, + "version": 1 + }, + "userdoc": { + "kind": "user", + "methods": {}, + "version": 1 + }, + "storageLayout": { + "storage": [], + "types": null + } +} \ No newline at end of file diff --git a/deployments/arbitrum/LayerZeroBridge_USD_Old.json b/deployments/arbitrum/LayerZeroBridge_USD_Old.json new file mode 100644 index 00000000..37b0041e --- /dev/null +++ b/deployments/arbitrum/LayerZeroBridge_USD_Old.json @@ -0,0 +1,275 @@ +{ + "address": "0xea8239Fc12a1c9d075BfA61aA08A50DCdf38FEe5", + "abi": [ + { + "inputs": [ + { + "internalType": "address", + "name": "_logic", + "type": "address" + }, + { + "internalType": "address", + "name": "admin_", + "type": "address" + }, + { + "internalType": "bytes", + "name": "_data", + "type": "bytes" + } + ], + "stateMutability": "payable", + "type": "constructor" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "previousAdmin", + "type": "address" + }, + { + "indexed": false, + "internalType": "address", + "name": "newAdmin", + "type": "address" + } + ], + "name": "AdminChanged", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "beacon", + "type": "address" + } + ], + "name": "BeaconUpgraded", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "implementation", + "type": "address" + } + ], + "name": "Upgraded", + "type": "event" + }, + { + "stateMutability": "payable", + "type": "fallback" + }, + { + "inputs": [], + "name": "admin", + "outputs": [ + { + "internalType": "address", + "name": "admin_", + "type": "address" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "newAdmin", + "type": "address" + } + ], + "name": "changeAdmin", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "implementation", + "outputs": [ + { + "internalType": "address", + "name": "implementation_", + "type": "address" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "newImplementation", + "type": "address" + } + ], + "name": "upgradeTo", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "newImplementation", + "type": "address" + }, + { + "internalType": "bytes", + "name": "data", + "type": "bytes" + } + ], + "name": "upgradeToAndCall", + "outputs": [], + "stateMutability": "payable", + "type": "function" + }, + { + "stateMutability": "payable", + "type": "receive" + } + ], + "transactionHash": "0x5dba82c76e427bb09426d2f87c50762a7f1ef19926f0d8e767b1663e301531d7", + "receipt": { + "to": null, + "from": "0xfdA462548Ce04282f4B6D6619823a7C64Fdc0185", + "contractAddress": "0xea8239Fc12a1c9d075BfA61aA08A50DCdf38FEe5", + "transactionIndex": 1, + "gasUsed": "8962072", + "logsBloom": "0x00000000000000000000000000000000400000000000000002000000000000000002000000000000000000000000000000000000000000000000000000200400000004008000000000004008000002400000000000000000001000000500000000000000020000000000000000000800000000800000000000000010000000000000000000000000000000000000000000000000000080000000000000800000020000000000000010000000000400000000000000000000000000000000000000000022000000000000000000040000000000000400000000020000000020000010000000000000000000000000000000000000000000000000000000000000", + "blockHash": "0x31bcfe4cef46b81d5851f4cfad8c07e7428766c8a352170b72fa34f0b72ebf3c", + "transactionHash": "0x5dba82c76e427bb09426d2f87c50762a7f1ef19926f0d8e767b1663e301531d7", + "logs": [ + { + "transactionIndex": 1, + "blockNumber": 168975761, + "transactionHash": "0x5dba82c76e427bb09426d2f87c50762a7f1ef19926f0d8e767b1663e301531d7", + "address": "0xea8239Fc12a1c9d075BfA61aA08A50DCdf38FEe5", + "topics": [ + "0xbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b", + "0x000000000000000000000000874f1686e8f89374a40196b54f435cc1a72d04e4" + ], + "data": "0x", + "logIndex": 0, + "blockHash": "0x31bcfe4cef46b81d5851f4cfad8c07e7428766c8a352170b72fa34f0b72ebf3c" + }, + { + "transactionIndex": 1, + "blockNumber": 168975761, + "transactionHash": "0x5dba82c76e427bb09426d2f87c50762a7f1ef19926f0d8e767b1663e301531d7", + "address": "0xea8239Fc12a1c9d075BfA61aA08A50DCdf38FEe5", + "topics": [ + "0x8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925", + "0x000000000000000000000000ea8239fc12a1c9d075bfa61aa08a50dcdf38fee5", + "0x0000000000000000000000000000206329b97db379d5e1bf586bbdb969c63274" + ], + "data": "0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", + "logIndex": 1, + "blockHash": "0x31bcfe4cef46b81d5851f4cfad8c07e7428766c8a352170b72fa34f0b72ebf3c" + }, + { + "transactionIndex": 1, + "blockNumber": 168975761, + "transactionHash": "0x5dba82c76e427bb09426d2f87c50762a7f1ef19926f0d8e767b1663e301531d7", + "address": "0xea8239Fc12a1c9d075BfA61aA08A50DCdf38FEe5", + "topics": [ + "0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000206329b97db379d5e1bf586bbdb969c63274" + ], + "data": "0x0000000000000000000000000000000000000000000000000000000000000000", + "logIndex": 2, + "blockHash": "0x31bcfe4cef46b81d5851f4cfad8c07e7428766c8a352170b72fa34f0b72ebf3c" + }, + { + "transactionIndex": 1, + "blockNumber": 168975761, + "transactionHash": "0x5dba82c76e427bb09426d2f87c50762a7f1ef19926f0d8e767b1663e301531d7", + "address": "0xea8239Fc12a1c9d075BfA61aA08A50DCdf38FEe5", + "topics": [ + "0x7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb3847402498" + ], + "data": "0x0000000000000000000000000000000000000000000000000000000000000001", + "logIndex": 3, + "blockHash": "0x31bcfe4cef46b81d5851f4cfad8c07e7428766c8a352170b72fa34f0b72ebf3c" + }, + { + "transactionIndex": 1, + "blockNumber": 168975761, + "transactionHash": "0x5dba82c76e427bb09426d2f87c50762a7f1ef19926f0d8e767b1663e301531d7", + "address": "0xea8239Fc12a1c9d075BfA61aA08A50DCdf38FEe5", + "topics": [ + "0x7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f" + ], + "data": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000009a5b060bd7b8f86c4c0d720a17367729670afb19", + "logIndex": 4, + "blockHash": "0x31bcfe4cef46b81d5851f4cfad8c07e7428766c8a352170b72fa34f0b72ebf3c" + } + ], + "blockNumber": 168975761, + "cumulativeGasUsed": "8962072", + "status": 1, + "byzantium": true + }, + "args": [ + "0x874f1686E8F89374A40196B54F435Cc1A72d04e4", + "0x9a5b060Bd7b8f86c4C0D720a17367729670AfB19", + "0xc9aba0aa00000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000000e000000000000000000000000066a71dcef29a0ffbdbe3c6a460a3b5bc225cd67500000000000000000000000079e4df078a06ac31bfaa0f672f1f6e9b7f38113e000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000164c617965725a65726f204272696467652061675553440000000000000000000000000000000000000000000000000000000000000000000000000000000000084c5a2d6167555344000000000000000000000000000000000000000000000000" + ], + "numDeployments": 1, + "solcInputHash": "871924e0c138825a2736b76def8fef8d", + "metadata": "{\"compiler\":{\"version\":\"0.8.17+commit.8df45f5f\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_logic\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"admin_\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"_data\",\"type\":\"bytes\"}],\"stateMutability\":\"payable\",\"type\":\"constructor\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"previousAdmin\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"newAdmin\",\"type\":\"address\"}],\"name\":\"AdminChanged\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"beacon\",\"type\":\"address\"}],\"name\":\"BeaconUpgraded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"implementation\",\"type\":\"address\"}],\"name\":\"Upgraded\",\"type\":\"event\"},{\"stateMutability\":\"payable\",\"type\":\"fallback\"},{\"inputs\":[],\"name\":\"admin\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"admin_\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newAdmin\",\"type\":\"address\"}],\"name\":\"changeAdmin\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"implementation\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"implementation_\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newImplementation\",\"type\":\"address\"}],\"name\":\"upgradeTo\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newImplementation\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"}],\"name\":\"upgradeToAndCall\",\"outputs\":[],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"stateMutability\":\"payable\",\"type\":\"receive\"}],\"devdoc\":{\"details\":\"This contract implements a proxy that is upgradeable by an admin. It is fully forked from OpenZeppelin `TransparentUpgradeableProxy` To avoid https://medium.com/nomic-labs-blog/malicious-backdoors-in-ethereum-proxies-62629adf3357[proxy selector clashing], which can potentially be used in an attack, this contract uses the https://blog.openzeppelin.com/the-transparent-proxy-pattern/[transparent proxy pattern]. This pattern implies two things that go hand in hand: 1. If any account other than the admin calls the proxy, the call will be forwarded to the implementation, even if that call matches one of the admin functions exposed by the proxy itself. 2. If the admin calls the proxy, it can access the admin functions, but its calls will never be forwarded to the implementation. If the admin tries to call a function on the implementation it will fail with an error that says \\\"admin cannot fallback to proxy target\\\". These properties mean that the admin account can only be used for admin actions like upgrading the proxy or changing the admin, so it's best if it's a dedicated account that is not used for anything else. This will avoid headaches due to sudden errors when trying to call a function from the proxy implementation. Our recommendation is for the dedicated account to be an instance of the {ProxyAdmin} contract. If set up this way, you should think of the `ProxyAdmin` instance as the real administrative interface of your proxy.\",\"kind\":\"dev\",\"methods\":{\"admin()\":{\"details\":\"Returns the current admin. NOTE: Only the admin can call this function. See {ProxyAdmin-getProxyAdmin}. TIP: To get this value clients can read directly from the storage slot shown below (specified by EIP1967) using the https://eth.wiki/json-rpc/API#eth_getstorageat[`eth_getStorageAt`] RPC call. `0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103`\"},\"changeAdmin(address)\":{\"details\":\"Changes the admin of the proxy. Emits an {AdminChanged} event. NOTE: Only the admin can call this function. See {ProxyAdmin-changeProxyAdmin}.\"},\"constructor\":{\"details\":\"Initializes an upgradeable proxy managed by `_admin`, backed by the implementation at `_logic`, and optionally initialized with `_data` as explained in {ERC1967Proxy-constructor}.\"},\"implementation()\":{\"details\":\"Returns the current implementation. NOTE: Only the admin can call this function. See {ProxyAdmin-getProxyImplementation}. TIP: To get this value clients can read directly from the storage slot shown below (specified by EIP1967) using the https://eth.wiki/json-rpc/API#eth_getstorageat[`eth_getStorageAt`] RPC call. `0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc`\"},\"upgradeTo(address)\":{\"details\":\"Upgrade the implementation of the proxy. NOTE: Only the admin can call this function. See {ProxyAdmin-upgrade}.\"},\"upgradeToAndCall(address,bytes)\":{\"details\":\"Upgrade the implementation of the proxy, and then call a function from the new implementation as specified by `data`, which should be an encoded function call. This is useful to initialize new storage variables in the proxied contract. NOTE: Only the admin can call this function. See {ProxyAdmin-upgradeAndCall}.\"}},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/external/TransparentUpgradeableProxy.sol\":\"TransparentUpgradeableProxy\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":1000000},\"remappings\":[]},\"sources\":{\"@openzeppelin/contracts/interfaces/draft-IERC1822.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.5.0) (interfaces/draft-IERC1822.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev ERC1822: Universal Upgradeable Proxy Standard (UUPS) documents a method for upgradeability through a simplified\\n * proxy whose upgrades are fully controlled by the current implementation.\\n */\\ninterface IERC1822Proxiable {\\n /**\\n * @dev Returns the storage slot that the proxiable contract assumes is being used to store the implementation\\n * address.\\n *\\n * IMPORTANT: A proxy pointing at a proxiable contract should not be considered proxiable itself, because this risks\\n * bricking a proxy that upgrades to it, by delegating to itself until out of gas. Thus it is critical that this\\n * function revert if invoked through a proxy.\\n */\\n function proxiableUUID() external view returns (bytes32);\\n}\\n\",\"keccak256\":\"0x1d4afe6cb24200cc4545eed814ecf5847277dfe5d613a1707aad5fceecebcfff\",\"license\":\"MIT\"},\"@openzeppelin/contracts/proxy/ERC1967/ERC1967Proxy.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.7.0) (proxy/ERC1967/ERC1967Proxy.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../Proxy.sol\\\";\\nimport \\\"./ERC1967Upgrade.sol\\\";\\n\\n/**\\n * @dev This contract implements an upgradeable proxy. It is upgradeable because calls are delegated to an\\n * implementation address that can be changed. This address is stored in storage in the location specified by\\n * https://eips.ethereum.org/EIPS/eip-1967[EIP1967], so that it doesn't conflict with the storage layout of the\\n * implementation behind the proxy.\\n */\\ncontract ERC1967Proxy is Proxy, ERC1967Upgrade {\\n /**\\n * @dev Initializes the upgradeable proxy with an initial implementation specified by `_logic`.\\n *\\n * If `_data` is nonempty, it's used as data in a delegate call to `_logic`. This will typically be an encoded\\n * function call, and allows initializing the storage of the proxy like a Solidity constructor.\\n */\\n constructor(address _logic, bytes memory _data) payable {\\n _upgradeToAndCall(_logic, _data, false);\\n }\\n\\n /**\\n * @dev Returns the current implementation address.\\n */\\n function _implementation() internal view virtual override returns (address impl) {\\n return ERC1967Upgrade._getImplementation();\\n }\\n}\\n\",\"keccak256\":\"0xa2b22da3032e50b55f95ec1d13336102d675f341167aa76db571ef7f8bb7975d\",\"license\":\"MIT\"},\"@openzeppelin/contracts/proxy/ERC1967/ERC1967Upgrade.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.5.0) (proxy/ERC1967/ERC1967Upgrade.sol)\\n\\npragma solidity ^0.8.2;\\n\\nimport \\\"../beacon/IBeacon.sol\\\";\\nimport \\\"../../interfaces/draft-IERC1822.sol\\\";\\nimport \\\"../../utils/Address.sol\\\";\\nimport \\\"../../utils/StorageSlot.sol\\\";\\n\\n/**\\n * @dev This abstract contract provides getters and event emitting update functions for\\n * https://eips.ethereum.org/EIPS/eip-1967[EIP1967] slots.\\n *\\n * _Available since v4.1._\\n *\\n * @custom:oz-upgrades-unsafe-allow delegatecall\\n */\\nabstract contract ERC1967Upgrade {\\n // This is the keccak-256 hash of \\\"eip1967.proxy.rollback\\\" subtracted by 1\\n bytes32 private constant _ROLLBACK_SLOT = 0x4910fdfa16fed3260ed0e7147f7cc6da11a60208b5b9406d12a635614ffd9143;\\n\\n /**\\n * @dev Storage slot with the address of the current implementation.\\n * This is the keccak-256 hash of \\\"eip1967.proxy.implementation\\\" subtracted by 1, and is\\n * validated in the constructor.\\n */\\n bytes32 internal constant _IMPLEMENTATION_SLOT = 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc;\\n\\n /**\\n * @dev Emitted when the implementation is upgraded.\\n */\\n event Upgraded(address indexed implementation);\\n\\n /**\\n * @dev Returns the current implementation address.\\n */\\n function _getImplementation() internal view returns (address) {\\n return StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value;\\n }\\n\\n /**\\n * @dev Stores a new address in the EIP1967 implementation slot.\\n */\\n function _setImplementation(address newImplementation) private {\\n require(Address.isContract(newImplementation), \\\"ERC1967: new implementation is not a contract\\\");\\n StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value = newImplementation;\\n }\\n\\n /**\\n * @dev Perform implementation upgrade\\n *\\n * Emits an {Upgraded} event.\\n */\\n function _upgradeTo(address newImplementation) internal {\\n _setImplementation(newImplementation);\\n emit Upgraded(newImplementation);\\n }\\n\\n /**\\n * @dev Perform implementation upgrade with additional setup call.\\n *\\n * Emits an {Upgraded} event.\\n */\\n function _upgradeToAndCall(\\n address newImplementation,\\n bytes memory data,\\n bool forceCall\\n ) internal {\\n _upgradeTo(newImplementation);\\n if (data.length > 0 || forceCall) {\\n Address.functionDelegateCall(newImplementation, data);\\n }\\n }\\n\\n /**\\n * @dev Perform implementation upgrade with security checks for UUPS proxies, and additional setup call.\\n *\\n * Emits an {Upgraded} event.\\n */\\n function _upgradeToAndCallUUPS(\\n address newImplementation,\\n bytes memory data,\\n bool forceCall\\n ) internal {\\n // Upgrades from old implementations will perform a rollback test. This test requires the new\\n // implementation to upgrade back to the old, non-ERC1822 compliant, implementation. Removing\\n // this special case will break upgrade paths from old UUPS implementation to new ones.\\n if (StorageSlot.getBooleanSlot(_ROLLBACK_SLOT).value) {\\n _setImplementation(newImplementation);\\n } else {\\n try IERC1822Proxiable(newImplementation).proxiableUUID() returns (bytes32 slot) {\\n require(slot == _IMPLEMENTATION_SLOT, \\\"ERC1967Upgrade: unsupported proxiableUUID\\\");\\n } catch {\\n revert(\\\"ERC1967Upgrade: new implementation is not UUPS\\\");\\n }\\n _upgradeToAndCall(newImplementation, data, forceCall);\\n }\\n }\\n\\n /**\\n * @dev Storage slot with the admin of the contract.\\n * This is the keccak-256 hash of \\\"eip1967.proxy.admin\\\" subtracted by 1, and is\\n * validated in the constructor.\\n */\\n bytes32 internal constant _ADMIN_SLOT = 0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103;\\n\\n /**\\n * @dev Emitted when the admin account has changed.\\n */\\n event AdminChanged(address previousAdmin, address newAdmin);\\n\\n /**\\n * @dev Returns the current admin.\\n */\\n function _getAdmin() internal view returns (address) {\\n return StorageSlot.getAddressSlot(_ADMIN_SLOT).value;\\n }\\n\\n /**\\n * @dev Stores a new address in the EIP1967 admin slot.\\n */\\n function _setAdmin(address newAdmin) private {\\n require(newAdmin != address(0), \\\"ERC1967: new admin is the zero address\\\");\\n StorageSlot.getAddressSlot(_ADMIN_SLOT).value = newAdmin;\\n }\\n\\n /**\\n * @dev Changes the admin of the proxy.\\n *\\n * Emits an {AdminChanged} event.\\n */\\n function _changeAdmin(address newAdmin) internal {\\n emit AdminChanged(_getAdmin(), newAdmin);\\n _setAdmin(newAdmin);\\n }\\n\\n /**\\n * @dev The storage slot of the UpgradeableBeacon contract which defines the implementation for this proxy.\\n * This is bytes32(uint256(keccak256('eip1967.proxy.beacon')) - 1)) and is validated in the constructor.\\n */\\n bytes32 internal constant _BEACON_SLOT = 0xa3f0ad74e5423aebfd80d3ef4346578335a9a72aeaee59ff6cb3582b35133d50;\\n\\n /**\\n * @dev Emitted when the beacon is upgraded.\\n */\\n event BeaconUpgraded(address indexed beacon);\\n\\n /**\\n * @dev Returns the current beacon.\\n */\\n function _getBeacon() internal view returns (address) {\\n return StorageSlot.getAddressSlot(_BEACON_SLOT).value;\\n }\\n\\n /**\\n * @dev Stores a new beacon in the EIP1967 beacon slot.\\n */\\n function _setBeacon(address newBeacon) private {\\n require(Address.isContract(newBeacon), \\\"ERC1967: new beacon is not a contract\\\");\\n require(\\n Address.isContract(IBeacon(newBeacon).implementation()),\\n \\\"ERC1967: beacon implementation is not a contract\\\"\\n );\\n StorageSlot.getAddressSlot(_BEACON_SLOT).value = newBeacon;\\n }\\n\\n /**\\n * @dev Perform beacon upgrade with additional setup call. Note: This upgrades the address of the beacon, it does\\n * not upgrade the implementation contained in the beacon (see {UpgradeableBeacon-_setImplementation} for that).\\n *\\n * Emits a {BeaconUpgraded} event.\\n */\\n function _upgradeBeaconToAndCall(\\n address newBeacon,\\n bytes memory data,\\n bool forceCall\\n ) internal {\\n _setBeacon(newBeacon);\\n emit BeaconUpgraded(newBeacon);\\n if (data.length > 0 || forceCall) {\\n Address.functionDelegateCall(IBeacon(newBeacon).implementation(), data);\\n }\\n }\\n}\\n\",\"keccak256\":\"0xabf3f59bc0e5423eae45e459dbe92e7052c6983628d39008590edc852a62f94a\",\"license\":\"MIT\"},\"@openzeppelin/contracts/proxy/Proxy.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.6.0) (proxy/Proxy.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev This abstract contract provides a fallback function that delegates all calls to another contract using the EVM\\n * instruction `delegatecall`. We refer to the second contract as the _implementation_ behind the proxy, and it has to\\n * be specified by overriding the virtual {_implementation} function.\\n *\\n * Additionally, delegation to the implementation can be triggered manually through the {_fallback} function, or to a\\n * different contract through the {_delegate} function.\\n *\\n * The success and return data of the delegated call will be returned back to the caller of the proxy.\\n */\\nabstract contract Proxy {\\n /**\\n * @dev Delegates the current call to `implementation`.\\n *\\n * This function does not return to its internal call site, it will return directly to the external caller.\\n */\\n function _delegate(address implementation) internal virtual {\\n assembly {\\n // Copy msg.data. We take full control of memory in this inline assembly\\n // block because it will not return to Solidity code. We overwrite the\\n // Solidity scratch pad at memory position 0.\\n calldatacopy(0, 0, calldatasize())\\n\\n // Call the implementation.\\n // out and outsize are 0 because we don't know the size yet.\\n let result := delegatecall(gas(), implementation, 0, calldatasize(), 0, 0)\\n\\n // Copy the returned data.\\n returndatacopy(0, 0, returndatasize())\\n\\n switch result\\n // delegatecall returns 0 on error.\\n case 0 {\\n revert(0, returndatasize())\\n }\\n default {\\n return(0, returndatasize())\\n }\\n }\\n }\\n\\n /**\\n * @dev This is a virtual function that should be overridden so it returns the address to which the fallback function\\n * and {_fallback} should delegate.\\n */\\n function _implementation() internal view virtual returns (address);\\n\\n /**\\n * @dev Delegates the current call to the address returned by `_implementation()`.\\n *\\n * This function does not return to its internal call site, it will return directly to the external caller.\\n */\\n function _fallback() internal virtual {\\n _beforeFallback();\\n _delegate(_implementation());\\n }\\n\\n /**\\n * @dev Fallback function that delegates calls to the address returned by `_implementation()`. Will run if no other\\n * function in the contract matches the call data.\\n */\\n fallback() external payable virtual {\\n _fallback();\\n }\\n\\n /**\\n * @dev Fallback function that delegates calls to the address returned by `_implementation()`. Will run if call data\\n * is empty.\\n */\\n receive() external payable virtual {\\n _fallback();\\n }\\n\\n /**\\n * @dev Hook that is called before falling back to the implementation. Can happen as part of a manual `_fallback`\\n * call, or as part of the Solidity `fallback` or `receive` functions.\\n *\\n * If overridden should call `super._beforeFallback()`.\\n */\\n function _beforeFallback() internal virtual {}\\n}\\n\",\"keccak256\":\"0xc130fe33f1b2132158531a87734153293f6d07bc263ff4ac90e85da9c82c0e27\",\"license\":\"MIT\"},\"@openzeppelin/contracts/proxy/beacon/IBeacon.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (proxy/beacon/IBeacon.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev This is the interface that {BeaconProxy} expects of its beacon.\\n */\\ninterface IBeacon {\\n /**\\n * @dev Must return an address that can be used as a delegate call target.\\n *\\n * {BeaconProxy} will check that this address is a contract.\\n */\\n function implementation() external view returns (address);\\n}\\n\",\"keccak256\":\"0xd50a3421ac379ccb1be435fa646d66a65c986b4924f0849839f08692f39dde61\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/Address.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.7.0) (utils/Address.sol)\\n\\npragma solidity ^0.8.1;\\n\\n/**\\n * @dev Collection of functions related to the address type\\n */\\nlibrary Address {\\n /**\\n * @dev Returns true if `account` is a contract.\\n *\\n * [IMPORTANT]\\n * ====\\n * It is unsafe to assume that an address for which this function returns\\n * false is an externally-owned account (EOA) and not a contract.\\n *\\n * Among others, `isContract` will return false for the following\\n * types of addresses:\\n *\\n * - an externally-owned account\\n * - a contract in construction\\n * - an address where a contract will be created\\n * - an address where a contract lived, but was destroyed\\n * ====\\n *\\n * [IMPORTANT]\\n * ====\\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\\n *\\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\\n * constructor.\\n * ====\\n */\\n function isContract(address account) internal view returns (bool) {\\n // This method relies on extcodesize/address.code.length, which returns 0\\n // for contracts in construction, since the code is only stored at the end\\n // of the constructor execution.\\n\\n return account.code.length > 0;\\n }\\n\\n /**\\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\\n * `recipient`, forwarding all available gas and reverting on errors.\\n *\\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\\n * imposed by `transfer`, making them unable to receive funds via\\n * `transfer`. {sendValue} removes this limitation.\\n *\\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\\n *\\n * IMPORTANT: because control is transferred to `recipient`, care must be\\n * taken to not create reentrancy vulnerabilities. Consider using\\n * {ReentrancyGuard} or the\\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\\n */\\n function sendValue(address payable recipient, uint256 amount) internal {\\n require(address(this).balance >= amount, \\\"Address: insufficient balance\\\");\\n\\n (bool success, ) = recipient.call{value: amount}(\\\"\\\");\\n require(success, \\\"Address: unable to send value, recipient may have reverted\\\");\\n }\\n\\n /**\\n * @dev Performs a Solidity function call using a low level `call`. A\\n * plain `call` is an unsafe replacement for a function call: use this\\n * function instead.\\n *\\n * If `target` reverts with a revert reason, it is bubbled up by this\\n * function (like regular Solidity function calls).\\n *\\n * Returns the raw returned data. To convert to the expected return value,\\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\\n *\\n * Requirements:\\n *\\n * - `target` must be a contract.\\n * - calling `target` with `data` must not revert.\\n *\\n * _Available since v3.1._\\n */\\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\\n return functionCall(target, data, \\\"Address: low-level call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\\n * `errorMessage` as a fallback revert reason when `target` reverts.\\n *\\n * _Available since v3.1._\\n */\\n function functionCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n return functionCallWithValue(target, data, 0, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but also transferring `value` wei to `target`.\\n *\\n * Requirements:\\n *\\n * - the calling contract must have an ETH balance of at least `value`.\\n * - the called Solidity function must be `payable`.\\n *\\n * _Available since v3.1._\\n */\\n function functionCallWithValue(\\n address target,\\n bytes memory data,\\n uint256 value\\n ) internal returns (bytes memory) {\\n return functionCallWithValue(target, data, value, \\\"Address: low-level call with value failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\\n * with `errorMessage` as a fallback revert reason when `target` reverts.\\n *\\n * _Available since v3.1._\\n */\\n function functionCallWithValue(\\n address target,\\n bytes memory data,\\n uint256 value,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n require(address(this).balance >= value, \\\"Address: insufficient balance for call\\\");\\n require(isContract(target), \\\"Address: call to non-contract\\\");\\n\\n (bool success, bytes memory returndata) = target.call{value: value}(data);\\n return verifyCallResult(success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but performing a static call.\\n *\\n * _Available since v3.3._\\n */\\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\\n return functionStaticCall(target, data, \\\"Address: low-level static call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\\n * but performing a static call.\\n *\\n * _Available since v3.3._\\n */\\n function functionStaticCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal view returns (bytes memory) {\\n require(isContract(target), \\\"Address: static call to non-contract\\\");\\n\\n (bool success, bytes memory returndata) = target.staticcall(data);\\n return verifyCallResult(success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but performing a delegate call.\\n *\\n * _Available since v3.4._\\n */\\n function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {\\n return functionDelegateCall(target, data, \\\"Address: low-level delegate call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\\n * but performing a delegate call.\\n *\\n * _Available since v3.4._\\n */\\n function functionDelegateCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n require(isContract(target), \\\"Address: delegate call to non-contract\\\");\\n\\n (bool success, bytes memory returndata) = target.delegatecall(data);\\n return verifyCallResult(success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the\\n * revert reason using the provided one.\\n *\\n * _Available since v4.3._\\n */\\n function verifyCallResult(\\n bool success,\\n bytes memory returndata,\\n string memory errorMessage\\n ) internal pure returns (bytes memory) {\\n if (success) {\\n return returndata;\\n } else {\\n // Look for revert reason and bubble it up if present\\n if (returndata.length > 0) {\\n // The easiest way to bubble the revert reason is using memory via assembly\\n /// @solidity memory-safe-assembly\\n assembly {\\n let returndata_size := mload(returndata)\\n revert(add(32, returndata), returndata_size)\\n }\\n } else {\\n revert(errorMessage);\\n }\\n }\\n }\\n}\\n\",\"keccak256\":\"0xd6153ce99bcdcce22b124f755e72553295be6abcd63804cfdffceb188b8bef10\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/StorageSlot.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.7.0) (utils/StorageSlot.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Library for reading and writing primitive types to specific storage slots.\\n *\\n * Storage slots are often used to avoid storage conflict when dealing with upgradeable contracts.\\n * This library helps with reading and writing to such slots without the need for inline assembly.\\n *\\n * The functions in this library return Slot structs that contain a `value` member that can be used to read or write.\\n *\\n * Example usage to set ERC1967 implementation slot:\\n * ```\\n * contract ERC1967 {\\n * bytes32 internal constant _IMPLEMENTATION_SLOT = 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc;\\n *\\n * function _getImplementation() internal view returns (address) {\\n * return StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value;\\n * }\\n *\\n * function _setImplementation(address newImplementation) internal {\\n * require(Address.isContract(newImplementation), \\\"ERC1967: new implementation is not a contract\\\");\\n * StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value = newImplementation;\\n * }\\n * }\\n * ```\\n *\\n * _Available since v4.1 for `address`, `bool`, `bytes32`, and `uint256`._\\n */\\nlibrary StorageSlot {\\n struct AddressSlot {\\n address value;\\n }\\n\\n struct BooleanSlot {\\n bool value;\\n }\\n\\n struct Bytes32Slot {\\n bytes32 value;\\n }\\n\\n struct Uint256Slot {\\n uint256 value;\\n }\\n\\n /**\\n * @dev Returns an `AddressSlot` with member `value` located at `slot`.\\n */\\n function getAddressSlot(bytes32 slot) internal pure returns (AddressSlot storage r) {\\n /// @solidity memory-safe-assembly\\n assembly {\\n r.slot := slot\\n }\\n }\\n\\n /**\\n * @dev Returns an `BooleanSlot` with member `value` located at `slot`.\\n */\\n function getBooleanSlot(bytes32 slot) internal pure returns (BooleanSlot storage r) {\\n /// @solidity memory-safe-assembly\\n assembly {\\n r.slot := slot\\n }\\n }\\n\\n /**\\n * @dev Returns an `Bytes32Slot` with member `value` located at `slot`.\\n */\\n function getBytes32Slot(bytes32 slot) internal pure returns (Bytes32Slot storage r) {\\n /// @solidity memory-safe-assembly\\n assembly {\\n r.slot := slot\\n }\\n }\\n\\n /**\\n * @dev Returns an `Uint256Slot` with member `value` located at `slot`.\\n */\\n function getUint256Slot(bytes32 slot) internal pure returns (Uint256Slot storage r) {\\n /// @solidity memory-safe-assembly\\n assembly {\\n r.slot := slot\\n }\\n }\\n}\\n\",\"keccak256\":\"0xd5c50c54bf02740ebd122ff06832546cb5fa84486d52695a9ccfd11666e0c81d\",\"license\":\"MIT\"},\"contracts/external/TransparentUpgradeableProxy.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-3.0\\n\\npragma solidity ^0.8.12;\\n\\nimport \\\"@openzeppelin/contracts/proxy/ERC1967/ERC1967Proxy.sol\\\";\\n\\n/**\\n * @dev This contract implements a proxy that is upgradeable by an admin. It is fully forked from OpenZeppelin\\n * `TransparentUpgradeableProxy`\\n *\\n * To avoid https://medium.com/nomic-labs-blog/malicious-backdoors-in-ethereum-proxies-62629adf3357[proxy selector\\n * clashing], which can potentially be used in an attack, this contract uses the\\n * https://blog.openzeppelin.com/the-transparent-proxy-pattern/[transparent proxy pattern]. This pattern implies two\\n * things that go hand in hand:\\n *\\n * 1. If any account other than the admin calls the proxy, the call will be forwarded to the implementation, even if\\n * that call matches one of the admin functions exposed by the proxy itself.\\n * 2. If the admin calls the proxy, it can access the admin functions, but its calls will never be forwarded to the\\n * implementation. If the admin tries to call a function on the implementation it will fail with an error that says\\n * \\\"admin cannot fallback to proxy target\\\".\\n *\\n * These properties mean that the admin account can only be used for admin actions like upgrading the proxy or changing\\n * the admin, so it's best if it's a dedicated account that is not used for anything else. This will avoid headaches due\\n * to sudden errors when trying to call a function from the proxy implementation.\\n *\\n * Our recommendation is for the dedicated account to be an instance of the {ProxyAdmin} contract. If set up this way,\\n * you should think of the `ProxyAdmin` instance as the real administrative interface of your proxy.\\n */\\ncontract TransparentUpgradeableProxy is ERC1967Proxy {\\n /**\\n * @dev Initializes an upgradeable proxy managed by `_admin`, backed by the implementation at `_logic`, and\\n * optionally initialized with `_data` as explained in {ERC1967Proxy-constructor}.\\n */\\n constructor(address _logic, address admin_, bytes memory _data) payable ERC1967Proxy(_logic, _data) {\\n assert(_ADMIN_SLOT == bytes32(uint256(keccak256(\\\"eip1967.proxy.admin\\\")) - 1));\\n _changeAdmin(admin_);\\n }\\n\\n /**\\n * @dev Modifier used internally that will delegate the call to the implementation unless the sender is the admin.\\n */\\n modifier ifAdmin() {\\n if (msg.sender == _getAdmin()) {\\n _;\\n } else {\\n _fallback();\\n }\\n }\\n\\n /**\\n * @dev Returns the current admin.\\n *\\n * NOTE: Only the admin can call this function. See {ProxyAdmin-getProxyAdmin}.\\n *\\n * TIP: To get this value clients can read directly from the storage slot shown below (specified by EIP1967) using the\\n * https://eth.wiki/json-rpc/API#eth_getstorageat[`eth_getStorageAt`] RPC call.\\n * `0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103`\\n */\\n function admin() external ifAdmin returns (address admin_) {\\n admin_ = _getAdmin();\\n }\\n\\n /**\\n * @dev Returns the current implementation.\\n *\\n * NOTE: Only the admin can call this function. See {ProxyAdmin-getProxyImplementation}.\\n *\\n * TIP: To get this value clients can read directly from the storage slot shown below (specified by EIP1967) using the\\n * https://eth.wiki/json-rpc/API#eth_getstorageat[`eth_getStorageAt`] RPC call.\\n * `0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc`\\n */\\n function implementation() external ifAdmin returns (address implementation_) {\\n implementation_ = _implementation();\\n }\\n\\n /**\\n * @dev Changes the admin of the proxy.\\n *\\n * Emits an {AdminChanged} event.\\n *\\n * NOTE: Only the admin can call this function. See {ProxyAdmin-changeProxyAdmin}.\\n */\\n function changeAdmin(address newAdmin) external virtual ifAdmin {\\n _changeAdmin(newAdmin);\\n }\\n\\n /**\\n * @dev Upgrade the implementation of the proxy.\\n *\\n * NOTE: Only the admin can call this function. See {ProxyAdmin-upgrade}.\\n */\\n function upgradeTo(address newImplementation) external ifAdmin {\\n _upgradeToAndCall(newImplementation, bytes(\\\"\\\"), false);\\n }\\n\\n /**\\n * @dev Upgrade the implementation of the proxy, and then call a function from the new implementation as specified\\n * by `data`, which should be an encoded function call. This is useful to initialize new storage variables in the\\n * proxied contract.\\n *\\n * NOTE: Only the admin can call this function. See {ProxyAdmin-upgradeAndCall}.\\n */\\n function upgradeToAndCall(address newImplementation, bytes calldata data) external payable ifAdmin {\\n _upgradeToAndCall(newImplementation, data, true);\\n }\\n\\n /**\\n * @dev Returns the current admin.\\n */\\n function _admin() internal view virtual returns (address) {\\n return _getAdmin();\\n }\\n\\n /**\\n * @dev Makes sure the admin cannot access the fallback function. See {Proxy-_beforeFallback}.\\n */\\n function _beforeFallback() internal virtual override {\\n require(msg.sender != _getAdmin(), \\\"TransparentUpgradeableProxy: admin cannot fallback to proxy target\\\");\\n super._beforeFallback();\\n }\\n}\\n\",\"keccak256\":\"0x93a67a0f612ea3ff2a76315e138a6a88267270a1379d3cc7be52845fbbe611e2\",\"license\":\"GPL-3.0\"}},\"version\":1}", + "bytecode": "0x6080604052604051620010bb380380620010bb8339810160408190526200002691620004d8565b828162000036828260006200009a565b5062000066905060017fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6104620005b8565b6000805160206200107483398151915214620000865762000086620005da565b6200009182620000d7565b50505062000643565b620000a58362000132565b600082511180620000b35750805b15620000d257620000d083836200017460201b6200028c1760201c565b505b505050565b7f7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f62000102620001a5565b604080516001600160a01b03928316815291841660208301520160405180910390a16200012f81620001de565b50565b6200013d8162000293565b6040516001600160a01b038216907fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b90600090a250565b60606200019c8383604051806060016040528060278152602001620010946027913962000347565b90505b92915050565b6000620001cf6000805160206200107483398151915260001b6200042f60201b6200022e1760201c565b546001600160a01b0316919050565b6001600160a01b038116620002495760405162461bcd60e51b815260206004820152602660248201527f455243313936373a206e65772061646d696e20697320746865207a65726f206160448201526564647265737360d01b60648201526084015b60405180910390fd5b80620002726000805160206200107483398151915260001b6200042f60201b6200022e1760201c565b80546001600160a01b0319166001600160a01b039290921691909117905550565b620002a9816200043260201b620002b81760201c565b6200030d5760405162461bcd60e51b815260206004820152602d60248201527f455243313936373a206e657720696d706c656d656e746174696f6e206973206e60448201526c1bdd08184818dbdb9d1c9858dd609a1b606482015260840162000240565b80620002727f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc60001b6200042f60201b6200022e1760201c565b60606001600160a01b0384163b620003b15760405162461bcd60e51b815260206004820152602660248201527f416464726573733a2064656c65676174652063616c6c20746f206e6f6e2d636f6044820152651b9d1c9858dd60d21b606482015260840162000240565b600080856001600160a01b031685604051620003ce9190620005f0565b600060405180830381855af49150503d80600081146200040b576040519150601f19603f3d011682016040523d82523d6000602084013e62000410565b606091505b5090925090506200042382828662000441565b925050505b9392505050565b90565b6001600160a01b03163b151590565b606083156200045257508162000428565b825115620004635782518084602001fd5b8160405162461bcd60e51b81526004016200024091906200060e565b80516001600160a01b03811681146200049757600080fd5b919050565b634e487b7160e01b600052604160045260246000fd5b60005b83811015620004cf578181015183820152602001620004b5565b50506000910152565b600080600060608486031215620004ee57600080fd5b620004f9846200047f565b925062000509602085016200047f565b60408501519092506001600160401b03808211156200052757600080fd5b818601915086601f8301126200053c57600080fd5b8151818111156200055157620005516200049c565b604051601f8201601f19908116603f011681019083821181831017156200057c576200057c6200049c565b816040528281528960208487010111156200059657600080fd5b620005a9836020830160208801620004b2565b80955050505050509250925092565b818103818111156200019f57634e487b7160e01b600052601160045260246000fd5b634e487b7160e01b600052600160045260246000fd5b6000825162000604818460208701620004b2565b9190910192915050565b60208152600082518060208401526200062f816040850160208701620004b2565b601f01601f19169190910160400192915050565b610a2180620006536000396000f3fe60806040526004361061005e5760003560e01c80635c60da1b116100435780635c60da1b146100a85780638f283970146100e6578063f851a440146101065761006d565b80633659cfe6146100755780634f1ef286146100955761006d565b3661006d5761006b61011b565b005b61006b61011b565b34801561008157600080fd5b5061006b610090366004610895565b610135565b61006b6100a33660046108b0565b61017f565b3480156100b457600080fd5b506100bd6101f3565b60405173ffffffffffffffffffffffffffffffffffffffff909116815260200160405180910390f35b3480156100f257600080fd5b5061006b610101366004610895565b610231565b34801561011257600080fd5b506100bd61025e565b6101236102d4565b61013361012e6103ab565b6103b5565b565b61013d6103d9565b73ffffffffffffffffffffffffffffffffffffffff1633036101775761017481604051806020016040528060008152506000610419565b50565b61017461011b565b6101876103d9565b73ffffffffffffffffffffffffffffffffffffffff1633036101eb576101e68383838080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525060019250610419915050565b505050565b6101e661011b565b60006101fd6103d9565b73ffffffffffffffffffffffffffffffffffffffff163303610226576102216103ab565b905090565b61022e61011b565b90565b6102396103d9565b73ffffffffffffffffffffffffffffffffffffffff1633036101775761017481610444565b60006102686103d9565b73ffffffffffffffffffffffffffffffffffffffff163303610226576102216103d9565b60606102b183836040518060600160405280602781526020016109c5602791396104a5565b9392505050565b73ffffffffffffffffffffffffffffffffffffffff163b151590565b6102dc6103d9565b73ffffffffffffffffffffffffffffffffffffffff163303610133576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604260248201527f5472616e73706172656e745570677261646561626c6550726f78793a2061646d60448201527f696e2063616e6e6f742066616c6c6261636b20746f2070726f7879207461726760648201527f6574000000000000000000000000000000000000000000000000000000000000608482015260a4015b60405180910390fd5b60006102216105cd565b3660008037600080366000845af43d6000803e8080156103d4573d6000f35b3d6000fd5b60007fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035b5473ffffffffffffffffffffffffffffffffffffffff16919050565b610422836105f5565b60008251118061042f5750805b156101e65761043e838361028c565b50505050565b7f7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f61046d6103d9565b6040805173ffffffffffffffffffffffffffffffffffffffff928316815291841660208301520160405180910390a161017481610642565b606073ffffffffffffffffffffffffffffffffffffffff84163b61054b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f416464726573733a2064656c65676174652063616c6c20746f206e6f6e2d636f60448201527f6e7472616374000000000000000000000000000000000000000000000000000060648201526084016103a2565b6000808573ffffffffffffffffffffffffffffffffffffffff16856040516105739190610957565b600060405180830381855af49150503d80600081146105ae576040519150601f19603f3d011682016040523d82523d6000602084013e6105b3565b606091505b50915091506105c382828661074e565b9695505050505050565b60007f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc6103fd565b6105fe816107a1565b60405173ffffffffffffffffffffffffffffffffffffffff8216907fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b90600090a250565b73ffffffffffffffffffffffffffffffffffffffff81166106e5576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f455243313936373a206e65772061646d696e20697320746865207a65726f206160448201527f646472657373000000000000000000000000000000000000000000000000000060648201526084016103a2565b807fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035b80547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff9290921691909117905550565b6060831561075d5750816102b1565b82511561076d5782518084602001fd5b816040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016103a29190610973565b73ffffffffffffffffffffffffffffffffffffffff81163b610845576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602d60248201527f455243313936373a206e657720696d706c656d656e746174696f6e206973206e60448201527f6f74206120636f6e74726163740000000000000000000000000000000000000060648201526084016103a2565b807f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc610708565b803573ffffffffffffffffffffffffffffffffffffffff8116811461089057600080fd5b919050565b6000602082840312156108a757600080fd5b6102b18261086c565b6000806000604084860312156108c557600080fd5b6108ce8461086c565b9250602084013567ffffffffffffffff808211156108eb57600080fd5b818601915086601f8301126108ff57600080fd5b81358181111561090e57600080fd5b87602082850101111561092057600080fd5b6020830194508093505050509250925092565b60005b8381101561094e578181015183820152602001610936565b50506000910152565b60008251610969818460208701610933565b9190910192915050565b6020815260008251806020840152610992816040850160208701610933565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016919091016040019291505056fe416464726573733a206c6f772d6c6576656c2064656c65676174652063616c6c206661696c6564a2646970667358221220e96638b07fb1675d93a95c49e417bc8111448b23a59918698cdcd8fd488dd7cf64736f6c63430008110033b53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103416464726573733a206c6f772d6c6576656c2064656c65676174652063616c6c206661696c6564", + "deployedBytecode": "0x60806040526004361061005e5760003560e01c80635c60da1b116100435780635c60da1b146100a85780638f283970146100e6578063f851a440146101065761006d565b80633659cfe6146100755780634f1ef286146100955761006d565b3661006d5761006b61011b565b005b61006b61011b565b34801561008157600080fd5b5061006b610090366004610895565b610135565b61006b6100a33660046108b0565b61017f565b3480156100b457600080fd5b506100bd6101f3565b60405173ffffffffffffffffffffffffffffffffffffffff909116815260200160405180910390f35b3480156100f257600080fd5b5061006b610101366004610895565b610231565b34801561011257600080fd5b506100bd61025e565b6101236102d4565b61013361012e6103ab565b6103b5565b565b61013d6103d9565b73ffffffffffffffffffffffffffffffffffffffff1633036101775761017481604051806020016040528060008152506000610419565b50565b61017461011b565b6101876103d9565b73ffffffffffffffffffffffffffffffffffffffff1633036101eb576101e68383838080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525060019250610419915050565b505050565b6101e661011b565b60006101fd6103d9565b73ffffffffffffffffffffffffffffffffffffffff163303610226576102216103ab565b905090565b61022e61011b565b90565b6102396103d9565b73ffffffffffffffffffffffffffffffffffffffff1633036101775761017481610444565b60006102686103d9565b73ffffffffffffffffffffffffffffffffffffffff163303610226576102216103d9565b60606102b183836040518060600160405280602781526020016109c5602791396104a5565b9392505050565b73ffffffffffffffffffffffffffffffffffffffff163b151590565b6102dc6103d9565b73ffffffffffffffffffffffffffffffffffffffff163303610133576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604260248201527f5472616e73706172656e745570677261646561626c6550726f78793a2061646d60448201527f696e2063616e6e6f742066616c6c6261636b20746f2070726f7879207461726760648201527f6574000000000000000000000000000000000000000000000000000000000000608482015260a4015b60405180910390fd5b60006102216105cd565b3660008037600080366000845af43d6000803e8080156103d4573d6000f35b3d6000fd5b60007fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035b5473ffffffffffffffffffffffffffffffffffffffff16919050565b610422836105f5565b60008251118061042f5750805b156101e65761043e838361028c565b50505050565b7f7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f61046d6103d9565b6040805173ffffffffffffffffffffffffffffffffffffffff928316815291841660208301520160405180910390a161017481610642565b606073ffffffffffffffffffffffffffffffffffffffff84163b61054b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f416464726573733a2064656c65676174652063616c6c20746f206e6f6e2d636f60448201527f6e7472616374000000000000000000000000000000000000000000000000000060648201526084016103a2565b6000808573ffffffffffffffffffffffffffffffffffffffff16856040516105739190610957565b600060405180830381855af49150503d80600081146105ae576040519150601f19603f3d011682016040523d82523d6000602084013e6105b3565b606091505b50915091506105c382828661074e565b9695505050505050565b60007f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc6103fd565b6105fe816107a1565b60405173ffffffffffffffffffffffffffffffffffffffff8216907fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b90600090a250565b73ffffffffffffffffffffffffffffffffffffffff81166106e5576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f455243313936373a206e65772061646d696e20697320746865207a65726f206160448201527f646472657373000000000000000000000000000000000000000000000000000060648201526084016103a2565b807fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035b80547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff9290921691909117905550565b6060831561075d5750816102b1565b82511561076d5782518084602001fd5b816040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016103a29190610973565b73ffffffffffffffffffffffffffffffffffffffff81163b610845576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602d60248201527f455243313936373a206e657720696d706c656d656e746174696f6e206973206e60448201527f6f74206120636f6e74726163740000000000000000000000000000000000000060648201526084016103a2565b807f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc610708565b803573ffffffffffffffffffffffffffffffffffffffff8116811461089057600080fd5b919050565b6000602082840312156108a757600080fd5b6102b18261086c565b6000806000604084860312156108c557600080fd5b6108ce8461086c565b9250602084013567ffffffffffffffff808211156108eb57600080fd5b818601915086601f8301126108ff57600080fd5b81358181111561090e57600080fd5b87602082850101111561092057600080fd5b6020830194508093505050509250925092565b60005b8381101561094e578181015183820152602001610936565b50506000910152565b60008251610969818460208701610933565b9190910192915050565b6020815260008251806020840152610992816040850160208701610933565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016919091016040019291505056fe416464726573733a206c6f772d6c6576656c2064656c65676174652063616c6c206661696c6564a2646970667358221220e96638b07fb1675d93a95c49e417bc8111448b23a59918698cdcd8fd488dd7cf64736f6c63430008110033", + "devdoc": { + "details": "This contract implements a proxy that is upgradeable by an admin. It is fully forked from OpenZeppelin `TransparentUpgradeableProxy` To avoid https://medium.com/nomic-labs-blog/malicious-backdoors-in-ethereum-proxies-62629adf3357[proxy selector clashing], which can potentially be used in an attack, this contract uses the https://blog.openzeppelin.com/the-transparent-proxy-pattern/[transparent proxy pattern]. This pattern implies two things that go hand in hand: 1. If any account other than the admin calls the proxy, the call will be forwarded to the implementation, even if that call matches one of the admin functions exposed by the proxy itself. 2. If the admin calls the proxy, it can access the admin functions, but its calls will never be forwarded to the implementation. If the admin tries to call a function on the implementation it will fail with an error that says \"admin cannot fallback to proxy target\". These properties mean that the admin account can only be used for admin actions like upgrading the proxy or changing the admin, so it's best if it's a dedicated account that is not used for anything else. This will avoid headaches due to sudden errors when trying to call a function from the proxy implementation. Our recommendation is for the dedicated account to be an instance of the {ProxyAdmin} contract. If set up this way, you should think of the `ProxyAdmin` instance as the real administrative interface of your proxy.", + "kind": "dev", + "methods": { + "admin()": { + "details": "Returns the current admin. NOTE: Only the admin can call this function. See {ProxyAdmin-getProxyAdmin}. TIP: To get this value clients can read directly from the storage slot shown below (specified by EIP1967) using the https://eth.wiki/json-rpc/API#eth_getstorageat[`eth_getStorageAt`] RPC call. `0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103`" + }, + "changeAdmin(address)": { + "details": "Changes the admin of the proxy. Emits an {AdminChanged} event. NOTE: Only the admin can call this function. See {ProxyAdmin-changeProxyAdmin}." + }, + "constructor": { + "details": "Initializes an upgradeable proxy managed by `_admin`, backed by the implementation at `_logic`, and optionally initialized with `_data` as explained in {ERC1967Proxy-constructor}." + }, + "implementation()": { + "details": "Returns the current implementation. NOTE: Only the admin can call this function. See {ProxyAdmin-getProxyImplementation}. TIP: To get this value clients can read directly from the storage slot shown below (specified by EIP1967) using the https://eth.wiki/json-rpc/API#eth_getstorageat[`eth_getStorageAt`] RPC call. `0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc`" + }, + "upgradeTo(address)": { + "details": "Upgrade the implementation of the proxy. NOTE: Only the admin can call this function. See {ProxyAdmin-upgrade}." + }, + "upgradeToAndCall(address,bytes)": { + "details": "Upgrade the implementation of the proxy, and then call a function from the new implementation as specified by `data`, which should be an encoded function call. This is useful to initialize new storage variables in the proxied contract. NOTE: Only the admin can call this function. See {ProxyAdmin-upgradeAndCall}." + } + }, + "version": 1 + }, + "userdoc": { + "kind": "user", + "methods": {}, + "version": 1 + }, + "storageLayout": { + "storage": [], + "types": null + } +} \ No newline at end of file diff --git a/deployments/arbitrum/Treasury_USD.json b/deployments/arbitrum/Treasury_USD.json new file mode 100644 index 00000000..92ec03a2 --- /dev/null +++ b/deployments/arbitrum/Treasury_USD.json @@ -0,0 +1,235 @@ +{ + "address": "0x79E4dF078A06AC31BfAA0f672f1f6E9B7F38113E", + "abi": [ + { + "inputs": [ + { + "internalType": "address", + "name": "_logic", + "type": "address" + }, + { + "internalType": "address", + "name": "admin_", + "type": "address" + }, + { + "internalType": "bytes", + "name": "_data", + "type": "bytes" + } + ], + "stateMutability": "payable", + "type": "constructor" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "previousAdmin", + "type": "address" + }, + { + "indexed": false, + "internalType": "address", + "name": "newAdmin", + "type": "address" + } + ], + "name": "AdminChanged", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "beacon", + "type": "address" + } + ], + "name": "BeaconUpgraded", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "implementation", + "type": "address" + } + ], + "name": "Upgraded", + "type": "event" + }, + { + "stateMutability": "payable", + "type": "fallback" + }, + { + "inputs": [], + "name": "admin", + "outputs": [ + { + "internalType": "address", + "name": "admin_", + "type": "address" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "newAdmin", + "type": "address" + } + ], + "name": "changeAdmin", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "implementation", + "outputs": [ + { + "internalType": "address", + "name": "implementation_", + "type": "address" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "newImplementation", + "type": "address" + } + ], + "name": "upgradeTo", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "newImplementation", + "type": "address" + }, + { + "internalType": "bytes", + "name": "data", + "type": "bytes" + } + ], + "name": "upgradeToAndCall", + "outputs": [], + "stateMutability": "payable", + "type": "function" + }, + { + "stateMutability": "payable", + "type": "receive" + } + ], + "transactionHash": "0x3581bfef8d78df4cd1d75cba9aabbc844edcd0974022d9a4b5755358105c9927", + "receipt": { + "to": null, + "from": "0xfdA462548Ce04282f4B6D6619823a7C64Fdc0185", + "contractAddress": "0x79E4dF078A06AC31BfAA0f672f1f6E9B7F38113E", + "transactionIndex": 1, + "gasUsed": "8637999", + "logsBloom": "0x00000000008000000000000000000000400000000000000000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000000000000800800000000000000000000000000000000000000000000000000000000000000000000000001000000800000000000000000000000000000000000000000000000000000000000000000000000000020000000000800000000000000000000000400000000000000000000000080000000000000000000000000000000000000000000000000000000000000", + "blockHash": "0xae55c2afebac8199bf6be927313f1cf07e4b732953705b3200512d6ce8babf84", + "transactionHash": "0x3581bfef8d78df4cd1d75cba9aabbc844edcd0974022d9a4b5755358105c9927", + "logs": [ + { + "transactionIndex": 1, + "blockNumber": 168975747, + "transactionHash": "0x3581bfef8d78df4cd1d75cba9aabbc844edcd0974022d9a4b5755358105c9927", + "address": "0x79E4dF078A06AC31BfAA0f672f1f6E9B7F38113E", + "topics": [ + "0xbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b", + "0x000000000000000000000000f1ddcaca7d17f8030ab2eb54f2d9811365efe123" + ], + "data": "0x", + "logIndex": 0, + "blockHash": "0xae55c2afebac8199bf6be927313f1cf07e4b732953705b3200512d6ce8babf84" + }, + { + "transactionIndex": 1, + "blockNumber": 168975747, + "transactionHash": "0x3581bfef8d78df4cd1d75cba9aabbc844edcd0974022d9a4b5755358105c9927", + "address": "0x79E4dF078A06AC31BfAA0f672f1f6E9B7F38113E", + "topics": [ + "0x7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f" + ], + "data": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000009a5b060bd7b8f86c4c0d720a17367729670afb19", + "logIndex": 1, + "blockHash": "0xae55c2afebac8199bf6be927313f1cf07e4b732953705b3200512d6ce8babf84" + } + ], + "blockNumber": 168975747, + "cumulativeGasUsed": "8637999", + "status": 1, + "byzantium": true + }, + "args": [ + "0xf1dDcACA7D17f8030Ab2eb54f2D9811365EFe123", + "0x9a5b060Bd7b8f86c4C0D720a17367729670AfB19", + "0x485cc955000000000000000000000000b38ba207d02f07653a37b53c1c0a250b04f97e820000000000000000000000000000206329b97db379d5e1bf586bbdb969c63274" + ], + "numDeployments": 1, + "solcInputHash": "871924e0c138825a2736b76def8fef8d", + "metadata": "{\"compiler\":{\"version\":\"0.8.17+commit.8df45f5f\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_logic\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"admin_\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"_data\",\"type\":\"bytes\"}],\"stateMutability\":\"payable\",\"type\":\"constructor\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"previousAdmin\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"newAdmin\",\"type\":\"address\"}],\"name\":\"AdminChanged\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"beacon\",\"type\":\"address\"}],\"name\":\"BeaconUpgraded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"implementation\",\"type\":\"address\"}],\"name\":\"Upgraded\",\"type\":\"event\"},{\"stateMutability\":\"payable\",\"type\":\"fallback\"},{\"inputs\":[],\"name\":\"admin\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"admin_\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newAdmin\",\"type\":\"address\"}],\"name\":\"changeAdmin\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"implementation\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"implementation_\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newImplementation\",\"type\":\"address\"}],\"name\":\"upgradeTo\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newImplementation\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"}],\"name\":\"upgradeToAndCall\",\"outputs\":[],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"stateMutability\":\"payable\",\"type\":\"receive\"}],\"devdoc\":{\"details\":\"This contract implements a proxy that is upgradeable by an admin. It is fully forked from OpenZeppelin `TransparentUpgradeableProxy` To avoid https://medium.com/nomic-labs-blog/malicious-backdoors-in-ethereum-proxies-62629adf3357[proxy selector clashing], which can potentially be used in an attack, this contract uses the https://blog.openzeppelin.com/the-transparent-proxy-pattern/[transparent proxy pattern]. This pattern implies two things that go hand in hand: 1. If any account other than the admin calls the proxy, the call will be forwarded to the implementation, even if that call matches one of the admin functions exposed by the proxy itself. 2. If the admin calls the proxy, it can access the admin functions, but its calls will never be forwarded to the implementation. If the admin tries to call a function on the implementation it will fail with an error that says \\\"admin cannot fallback to proxy target\\\". These properties mean that the admin account can only be used for admin actions like upgrading the proxy or changing the admin, so it's best if it's a dedicated account that is not used for anything else. This will avoid headaches due to sudden errors when trying to call a function from the proxy implementation. Our recommendation is for the dedicated account to be an instance of the {ProxyAdmin} contract. If set up this way, you should think of the `ProxyAdmin` instance as the real administrative interface of your proxy.\",\"kind\":\"dev\",\"methods\":{\"admin()\":{\"details\":\"Returns the current admin. NOTE: Only the admin can call this function. See {ProxyAdmin-getProxyAdmin}. TIP: To get this value clients can read directly from the storage slot shown below (specified by EIP1967) using the https://eth.wiki/json-rpc/API#eth_getstorageat[`eth_getStorageAt`] RPC call. `0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103`\"},\"changeAdmin(address)\":{\"details\":\"Changes the admin of the proxy. Emits an {AdminChanged} event. NOTE: Only the admin can call this function. See {ProxyAdmin-changeProxyAdmin}.\"},\"constructor\":{\"details\":\"Initializes an upgradeable proxy managed by `_admin`, backed by the implementation at `_logic`, and optionally initialized with `_data` as explained in {ERC1967Proxy-constructor}.\"},\"implementation()\":{\"details\":\"Returns the current implementation. NOTE: Only the admin can call this function. See {ProxyAdmin-getProxyImplementation}. TIP: To get this value clients can read directly from the storage slot shown below (specified by EIP1967) using the https://eth.wiki/json-rpc/API#eth_getstorageat[`eth_getStorageAt`] RPC call. `0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc`\"},\"upgradeTo(address)\":{\"details\":\"Upgrade the implementation of the proxy. NOTE: Only the admin can call this function. See {ProxyAdmin-upgrade}.\"},\"upgradeToAndCall(address,bytes)\":{\"details\":\"Upgrade the implementation of the proxy, and then call a function from the new implementation as specified by `data`, which should be an encoded function call. This is useful to initialize new storage variables in the proxied contract. NOTE: Only the admin can call this function. See {ProxyAdmin-upgradeAndCall}.\"}},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/external/TransparentUpgradeableProxy.sol\":\"TransparentUpgradeableProxy\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":1000000},\"remappings\":[]},\"sources\":{\"@openzeppelin/contracts/interfaces/draft-IERC1822.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.5.0) (interfaces/draft-IERC1822.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev ERC1822: Universal Upgradeable Proxy Standard (UUPS) documents a method for upgradeability through a simplified\\n * proxy whose upgrades are fully controlled by the current implementation.\\n */\\ninterface IERC1822Proxiable {\\n /**\\n * @dev Returns the storage slot that the proxiable contract assumes is being used to store the implementation\\n * address.\\n *\\n * IMPORTANT: A proxy pointing at a proxiable contract should not be considered proxiable itself, because this risks\\n * bricking a proxy that upgrades to it, by delegating to itself until out of gas. Thus it is critical that this\\n * function revert if invoked through a proxy.\\n */\\n function proxiableUUID() external view returns (bytes32);\\n}\\n\",\"keccak256\":\"0x1d4afe6cb24200cc4545eed814ecf5847277dfe5d613a1707aad5fceecebcfff\",\"license\":\"MIT\"},\"@openzeppelin/contracts/proxy/ERC1967/ERC1967Proxy.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.7.0) (proxy/ERC1967/ERC1967Proxy.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../Proxy.sol\\\";\\nimport \\\"./ERC1967Upgrade.sol\\\";\\n\\n/**\\n * @dev This contract implements an upgradeable proxy. It is upgradeable because calls are delegated to an\\n * implementation address that can be changed. This address is stored in storage in the location specified by\\n * https://eips.ethereum.org/EIPS/eip-1967[EIP1967], so that it doesn't conflict with the storage layout of the\\n * implementation behind the proxy.\\n */\\ncontract ERC1967Proxy is Proxy, ERC1967Upgrade {\\n /**\\n * @dev Initializes the upgradeable proxy with an initial implementation specified by `_logic`.\\n *\\n * If `_data` is nonempty, it's used as data in a delegate call to `_logic`. This will typically be an encoded\\n * function call, and allows initializing the storage of the proxy like a Solidity constructor.\\n */\\n constructor(address _logic, bytes memory _data) payable {\\n _upgradeToAndCall(_logic, _data, false);\\n }\\n\\n /**\\n * @dev Returns the current implementation address.\\n */\\n function _implementation() internal view virtual override returns (address impl) {\\n return ERC1967Upgrade._getImplementation();\\n }\\n}\\n\",\"keccak256\":\"0xa2b22da3032e50b55f95ec1d13336102d675f341167aa76db571ef7f8bb7975d\",\"license\":\"MIT\"},\"@openzeppelin/contracts/proxy/ERC1967/ERC1967Upgrade.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.5.0) (proxy/ERC1967/ERC1967Upgrade.sol)\\n\\npragma solidity ^0.8.2;\\n\\nimport \\\"../beacon/IBeacon.sol\\\";\\nimport \\\"../../interfaces/draft-IERC1822.sol\\\";\\nimport \\\"../../utils/Address.sol\\\";\\nimport \\\"../../utils/StorageSlot.sol\\\";\\n\\n/**\\n * @dev This abstract contract provides getters and event emitting update functions for\\n * https://eips.ethereum.org/EIPS/eip-1967[EIP1967] slots.\\n *\\n * _Available since v4.1._\\n *\\n * @custom:oz-upgrades-unsafe-allow delegatecall\\n */\\nabstract contract ERC1967Upgrade {\\n // This is the keccak-256 hash of \\\"eip1967.proxy.rollback\\\" subtracted by 1\\n bytes32 private constant _ROLLBACK_SLOT = 0x4910fdfa16fed3260ed0e7147f7cc6da11a60208b5b9406d12a635614ffd9143;\\n\\n /**\\n * @dev Storage slot with the address of the current implementation.\\n * This is the keccak-256 hash of \\\"eip1967.proxy.implementation\\\" subtracted by 1, and is\\n * validated in the constructor.\\n */\\n bytes32 internal constant _IMPLEMENTATION_SLOT = 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc;\\n\\n /**\\n * @dev Emitted when the implementation is upgraded.\\n */\\n event Upgraded(address indexed implementation);\\n\\n /**\\n * @dev Returns the current implementation address.\\n */\\n function _getImplementation() internal view returns (address) {\\n return StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value;\\n }\\n\\n /**\\n * @dev Stores a new address in the EIP1967 implementation slot.\\n */\\n function _setImplementation(address newImplementation) private {\\n require(Address.isContract(newImplementation), \\\"ERC1967: new implementation is not a contract\\\");\\n StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value = newImplementation;\\n }\\n\\n /**\\n * @dev Perform implementation upgrade\\n *\\n * Emits an {Upgraded} event.\\n */\\n function _upgradeTo(address newImplementation) internal {\\n _setImplementation(newImplementation);\\n emit Upgraded(newImplementation);\\n }\\n\\n /**\\n * @dev Perform implementation upgrade with additional setup call.\\n *\\n * Emits an {Upgraded} event.\\n */\\n function _upgradeToAndCall(\\n address newImplementation,\\n bytes memory data,\\n bool forceCall\\n ) internal {\\n _upgradeTo(newImplementation);\\n if (data.length > 0 || forceCall) {\\n Address.functionDelegateCall(newImplementation, data);\\n }\\n }\\n\\n /**\\n * @dev Perform implementation upgrade with security checks for UUPS proxies, and additional setup call.\\n *\\n * Emits an {Upgraded} event.\\n */\\n function _upgradeToAndCallUUPS(\\n address newImplementation,\\n bytes memory data,\\n bool forceCall\\n ) internal {\\n // Upgrades from old implementations will perform a rollback test. This test requires the new\\n // implementation to upgrade back to the old, non-ERC1822 compliant, implementation. Removing\\n // this special case will break upgrade paths from old UUPS implementation to new ones.\\n if (StorageSlot.getBooleanSlot(_ROLLBACK_SLOT).value) {\\n _setImplementation(newImplementation);\\n } else {\\n try IERC1822Proxiable(newImplementation).proxiableUUID() returns (bytes32 slot) {\\n require(slot == _IMPLEMENTATION_SLOT, \\\"ERC1967Upgrade: unsupported proxiableUUID\\\");\\n } catch {\\n revert(\\\"ERC1967Upgrade: new implementation is not UUPS\\\");\\n }\\n _upgradeToAndCall(newImplementation, data, forceCall);\\n }\\n }\\n\\n /**\\n * @dev Storage slot with the admin of the contract.\\n * This is the keccak-256 hash of \\\"eip1967.proxy.admin\\\" subtracted by 1, and is\\n * validated in the constructor.\\n */\\n bytes32 internal constant _ADMIN_SLOT = 0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103;\\n\\n /**\\n * @dev Emitted when the admin account has changed.\\n */\\n event AdminChanged(address previousAdmin, address newAdmin);\\n\\n /**\\n * @dev Returns the current admin.\\n */\\n function _getAdmin() internal view returns (address) {\\n return StorageSlot.getAddressSlot(_ADMIN_SLOT).value;\\n }\\n\\n /**\\n * @dev Stores a new address in the EIP1967 admin slot.\\n */\\n function _setAdmin(address newAdmin) private {\\n require(newAdmin != address(0), \\\"ERC1967: new admin is the zero address\\\");\\n StorageSlot.getAddressSlot(_ADMIN_SLOT).value = newAdmin;\\n }\\n\\n /**\\n * @dev Changes the admin of the proxy.\\n *\\n * Emits an {AdminChanged} event.\\n */\\n function _changeAdmin(address newAdmin) internal {\\n emit AdminChanged(_getAdmin(), newAdmin);\\n _setAdmin(newAdmin);\\n }\\n\\n /**\\n * @dev The storage slot of the UpgradeableBeacon contract which defines the implementation for this proxy.\\n * This is bytes32(uint256(keccak256('eip1967.proxy.beacon')) - 1)) and is validated in the constructor.\\n */\\n bytes32 internal constant _BEACON_SLOT = 0xa3f0ad74e5423aebfd80d3ef4346578335a9a72aeaee59ff6cb3582b35133d50;\\n\\n /**\\n * @dev Emitted when the beacon is upgraded.\\n */\\n event BeaconUpgraded(address indexed beacon);\\n\\n /**\\n * @dev Returns the current beacon.\\n */\\n function _getBeacon() internal view returns (address) {\\n return StorageSlot.getAddressSlot(_BEACON_SLOT).value;\\n }\\n\\n /**\\n * @dev Stores a new beacon in the EIP1967 beacon slot.\\n */\\n function _setBeacon(address newBeacon) private {\\n require(Address.isContract(newBeacon), \\\"ERC1967: new beacon is not a contract\\\");\\n require(\\n Address.isContract(IBeacon(newBeacon).implementation()),\\n \\\"ERC1967: beacon implementation is not a contract\\\"\\n );\\n StorageSlot.getAddressSlot(_BEACON_SLOT).value = newBeacon;\\n }\\n\\n /**\\n * @dev Perform beacon upgrade with additional setup call. Note: This upgrades the address of the beacon, it does\\n * not upgrade the implementation contained in the beacon (see {UpgradeableBeacon-_setImplementation} for that).\\n *\\n * Emits a {BeaconUpgraded} event.\\n */\\n function _upgradeBeaconToAndCall(\\n address newBeacon,\\n bytes memory data,\\n bool forceCall\\n ) internal {\\n _setBeacon(newBeacon);\\n emit BeaconUpgraded(newBeacon);\\n if (data.length > 0 || forceCall) {\\n Address.functionDelegateCall(IBeacon(newBeacon).implementation(), data);\\n }\\n }\\n}\\n\",\"keccak256\":\"0xabf3f59bc0e5423eae45e459dbe92e7052c6983628d39008590edc852a62f94a\",\"license\":\"MIT\"},\"@openzeppelin/contracts/proxy/Proxy.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.6.0) (proxy/Proxy.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev This abstract contract provides a fallback function that delegates all calls to another contract using the EVM\\n * instruction `delegatecall`. We refer to the second contract as the _implementation_ behind the proxy, and it has to\\n * be specified by overriding the virtual {_implementation} function.\\n *\\n * Additionally, delegation to the implementation can be triggered manually through the {_fallback} function, or to a\\n * different contract through the {_delegate} function.\\n *\\n * The success and return data of the delegated call will be returned back to the caller of the proxy.\\n */\\nabstract contract Proxy {\\n /**\\n * @dev Delegates the current call to `implementation`.\\n *\\n * This function does not return to its internal call site, it will return directly to the external caller.\\n */\\n function _delegate(address implementation) internal virtual {\\n assembly {\\n // Copy msg.data. We take full control of memory in this inline assembly\\n // block because it will not return to Solidity code. We overwrite the\\n // Solidity scratch pad at memory position 0.\\n calldatacopy(0, 0, calldatasize())\\n\\n // Call the implementation.\\n // out and outsize are 0 because we don't know the size yet.\\n let result := delegatecall(gas(), implementation, 0, calldatasize(), 0, 0)\\n\\n // Copy the returned data.\\n returndatacopy(0, 0, returndatasize())\\n\\n switch result\\n // delegatecall returns 0 on error.\\n case 0 {\\n revert(0, returndatasize())\\n }\\n default {\\n return(0, returndatasize())\\n }\\n }\\n }\\n\\n /**\\n * @dev This is a virtual function that should be overridden so it returns the address to which the fallback function\\n * and {_fallback} should delegate.\\n */\\n function _implementation() internal view virtual returns (address);\\n\\n /**\\n * @dev Delegates the current call to the address returned by `_implementation()`.\\n *\\n * This function does not return to its internal call site, it will return directly to the external caller.\\n */\\n function _fallback() internal virtual {\\n _beforeFallback();\\n _delegate(_implementation());\\n }\\n\\n /**\\n * @dev Fallback function that delegates calls to the address returned by `_implementation()`. Will run if no other\\n * function in the contract matches the call data.\\n */\\n fallback() external payable virtual {\\n _fallback();\\n }\\n\\n /**\\n * @dev Fallback function that delegates calls to the address returned by `_implementation()`. Will run if call data\\n * is empty.\\n */\\n receive() external payable virtual {\\n _fallback();\\n }\\n\\n /**\\n * @dev Hook that is called before falling back to the implementation. Can happen as part of a manual `_fallback`\\n * call, or as part of the Solidity `fallback` or `receive` functions.\\n *\\n * If overridden should call `super._beforeFallback()`.\\n */\\n function _beforeFallback() internal virtual {}\\n}\\n\",\"keccak256\":\"0xc130fe33f1b2132158531a87734153293f6d07bc263ff4ac90e85da9c82c0e27\",\"license\":\"MIT\"},\"@openzeppelin/contracts/proxy/beacon/IBeacon.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (proxy/beacon/IBeacon.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev This is the interface that {BeaconProxy} expects of its beacon.\\n */\\ninterface IBeacon {\\n /**\\n * @dev Must return an address that can be used as a delegate call target.\\n *\\n * {BeaconProxy} will check that this address is a contract.\\n */\\n function implementation() external view returns (address);\\n}\\n\",\"keccak256\":\"0xd50a3421ac379ccb1be435fa646d66a65c986b4924f0849839f08692f39dde61\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/Address.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.7.0) (utils/Address.sol)\\n\\npragma solidity ^0.8.1;\\n\\n/**\\n * @dev Collection of functions related to the address type\\n */\\nlibrary Address {\\n /**\\n * @dev Returns true if `account` is a contract.\\n *\\n * [IMPORTANT]\\n * ====\\n * It is unsafe to assume that an address for which this function returns\\n * false is an externally-owned account (EOA) and not a contract.\\n *\\n * Among others, `isContract` will return false for the following\\n * types of addresses:\\n *\\n * - an externally-owned account\\n * - a contract in construction\\n * - an address where a contract will be created\\n * - an address where a contract lived, but was destroyed\\n * ====\\n *\\n * [IMPORTANT]\\n * ====\\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\\n *\\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\\n * constructor.\\n * ====\\n */\\n function isContract(address account) internal view returns (bool) {\\n // This method relies on extcodesize/address.code.length, which returns 0\\n // for contracts in construction, since the code is only stored at the end\\n // of the constructor execution.\\n\\n return account.code.length > 0;\\n }\\n\\n /**\\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\\n * `recipient`, forwarding all available gas and reverting on errors.\\n *\\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\\n * imposed by `transfer`, making them unable to receive funds via\\n * `transfer`. {sendValue} removes this limitation.\\n *\\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\\n *\\n * IMPORTANT: because control is transferred to `recipient`, care must be\\n * taken to not create reentrancy vulnerabilities. Consider using\\n * {ReentrancyGuard} or the\\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\\n */\\n function sendValue(address payable recipient, uint256 amount) internal {\\n require(address(this).balance >= amount, \\\"Address: insufficient balance\\\");\\n\\n (bool success, ) = recipient.call{value: amount}(\\\"\\\");\\n require(success, \\\"Address: unable to send value, recipient may have reverted\\\");\\n }\\n\\n /**\\n * @dev Performs a Solidity function call using a low level `call`. A\\n * plain `call` is an unsafe replacement for a function call: use this\\n * function instead.\\n *\\n * If `target` reverts with a revert reason, it is bubbled up by this\\n * function (like regular Solidity function calls).\\n *\\n * Returns the raw returned data. To convert to the expected return value,\\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\\n *\\n * Requirements:\\n *\\n * - `target` must be a contract.\\n * - calling `target` with `data` must not revert.\\n *\\n * _Available since v3.1._\\n */\\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\\n return functionCall(target, data, \\\"Address: low-level call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\\n * `errorMessage` as a fallback revert reason when `target` reverts.\\n *\\n * _Available since v3.1._\\n */\\n function functionCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n return functionCallWithValue(target, data, 0, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but also transferring `value` wei to `target`.\\n *\\n * Requirements:\\n *\\n * - the calling contract must have an ETH balance of at least `value`.\\n * - the called Solidity function must be `payable`.\\n *\\n * _Available since v3.1._\\n */\\n function functionCallWithValue(\\n address target,\\n bytes memory data,\\n uint256 value\\n ) internal returns (bytes memory) {\\n return functionCallWithValue(target, data, value, \\\"Address: low-level call with value failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\\n * with `errorMessage` as a fallback revert reason when `target` reverts.\\n *\\n * _Available since v3.1._\\n */\\n function functionCallWithValue(\\n address target,\\n bytes memory data,\\n uint256 value,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n require(address(this).balance >= value, \\\"Address: insufficient balance for call\\\");\\n require(isContract(target), \\\"Address: call to non-contract\\\");\\n\\n (bool success, bytes memory returndata) = target.call{value: value}(data);\\n return verifyCallResult(success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but performing a static call.\\n *\\n * _Available since v3.3._\\n */\\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\\n return functionStaticCall(target, data, \\\"Address: low-level static call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\\n * but performing a static call.\\n *\\n * _Available since v3.3._\\n */\\n function functionStaticCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal view returns (bytes memory) {\\n require(isContract(target), \\\"Address: static call to non-contract\\\");\\n\\n (bool success, bytes memory returndata) = target.staticcall(data);\\n return verifyCallResult(success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but performing a delegate call.\\n *\\n * _Available since v3.4._\\n */\\n function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {\\n return functionDelegateCall(target, data, \\\"Address: low-level delegate call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\\n * but performing a delegate call.\\n *\\n * _Available since v3.4._\\n */\\n function functionDelegateCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n require(isContract(target), \\\"Address: delegate call to non-contract\\\");\\n\\n (bool success, bytes memory returndata) = target.delegatecall(data);\\n return verifyCallResult(success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the\\n * revert reason using the provided one.\\n *\\n * _Available since v4.3._\\n */\\n function verifyCallResult(\\n bool success,\\n bytes memory returndata,\\n string memory errorMessage\\n ) internal pure returns (bytes memory) {\\n if (success) {\\n return returndata;\\n } else {\\n // Look for revert reason and bubble it up if present\\n if (returndata.length > 0) {\\n // The easiest way to bubble the revert reason is using memory via assembly\\n /// @solidity memory-safe-assembly\\n assembly {\\n let returndata_size := mload(returndata)\\n revert(add(32, returndata), returndata_size)\\n }\\n } else {\\n revert(errorMessage);\\n }\\n }\\n }\\n}\\n\",\"keccak256\":\"0xd6153ce99bcdcce22b124f755e72553295be6abcd63804cfdffceb188b8bef10\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/StorageSlot.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.7.0) (utils/StorageSlot.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Library for reading and writing primitive types to specific storage slots.\\n *\\n * Storage slots are often used to avoid storage conflict when dealing with upgradeable contracts.\\n * This library helps with reading and writing to such slots without the need for inline assembly.\\n *\\n * The functions in this library return Slot structs that contain a `value` member that can be used to read or write.\\n *\\n * Example usage to set ERC1967 implementation slot:\\n * ```\\n * contract ERC1967 {\\n * bytes32 internal constant _IMPLEMENTATION_SLOT = 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc;\\n *\\n * function _getImplementation() internal view returns (address) {\\n * return StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value;\\n * }\\n *\\n * function _setImplementation(address newImplementation) internal {\\n * require(Address.isContract(newImplementation), \\\"ERC1967: new implementation is not a contract\\\");\\n * StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value = newImplementation;\\n * }\\n * }\\n * ```\\n *\\n * _Available since v4.1 for `address`, `bool`, `bytes32`, and `uint256`._\\n */\\nlibrary StorageSlot {\\n struct AddressSlot {\\n address value;\\n }\\n\\n struct BooleanSlot {\\n bool value;\\n }\\n\\n struct Bytes32Slot {\\n bytes32 value;\\n }\\n\\n struct Uint256Slot {\\n uint256 value;\\n }\\n\\n /**\\n * @dev Returns an `AddressSlot` with member `value` located at `slot`.\\n */\\n function getAddressSlot(bytes32 slot) internal pure returns (AddressSlot storage r) {\\n /// @solidity memory-safe-assembly\\n assembly {\\n r.slot := slot\\n }\\n }\\n\\n /**\\n * @dev Returns an `BooleanSlot` with member `value` located at `slot`.\\n */\\n function getBooleanSlot(bytes32 slot) internal pure returns (BooleanSlot storage r) {\\n /// @solidity memory-safe-assembly\\n assembly {\\n r.slot := slot\\n }\\n }\\n\\n /**\\n * @dev Returns an `Bytes32Slot` with member `value` located at `slot`.\\n */\\n function getBytes32Slot(bytes32 slot) internal pure returns (Bytes32Slot storage r) {\\n /// @solidity memory-safe-assembly\\n assembly {\\n r.slot := slot\\n }\\n }\\n\\n /**\\n * @dev Returns an `Uint256Slot` with member `value` located at `slot`.\\n */\\n function getUint256Slot(bytes32 slot) internal pure returns (Uint256Slot storage r) {\\n /// @solidity memory-safe-assembly\\n assembly {\\n r.slot := slot\\n }\\n }\\n}\\n\",\"keccak256\":\"0xd5c50c54bf02740ebd122ff06832546cb5fa84486d52695a9ccfd11666e0c81d\",\"license\":\"MIT\"},\"contracts/external/TransparentUpgradeableProxy.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-3.0\\n\\npragma solidity ^0.8.12;\\n\\nimport \\\"@openzeppelin/contracts/proxy/ERC1967/ERC1967Proxy.sol\\\";\\n\\n/**\\n * @dev This contract implements a proxy that is upgradeable by an admin. It is fully forked from OpenZeppelin\\n * `TransparentUpgradeableProxy`\\n *\\n * To avoid https://medium.com/nomic-labs-blog/malicious-backdoors-in-ethereum-proxies-62629adf3357[proxy selector\\n * clashing], which can potentially be used in an attack, this contract uses the\\n * https://blog.openzeppelin.com/the-transparent-proxy-pattern/[transparent proxy pattern]. This pattern implies two\\n * things that go hand in hand:\\n *\\n * 1. If any account other than the admin calls the proxy, the call will be forwarded to the implementation, even if\\n * that call matches one of the admin functions exposed by the proxy itself.\\n * 2. If the admin calls the proxy, it can access the admin functions, but its calls will never be forwarded to the\\n * implementation. If the admin tries to call a function on the implementation it will fail with an error that says\\n * \\\"admin cannot fallback to proxy target\\\".\\n *\\n * These properties mean that the admin account can only be used for admin actions like upgrading the proxy or changing\\n * the admin, so it's best if it's a dedicated account that is not used for anything else. This will avoid headaches due\\n * to sudden errors when trying to call a function from the proxy implementation.\\n *\\n * Our recommendation is for the dedicated account to be an instance of the {ProxyAdmin} contract. If set up this way,\\n * you should think of the `ProxyAdmin` instance as the real administrative interface of your proxy.\\n */\\ncontract TransparentUpgradeableProxy is ERC1967Proxy {\\n /**\\n * @dev Initializes an upgradeable proxy managed by `_admin`, backed by the implementation at `_logic`, and\\n * optionally initialized with `_data` as explained in {ERC1967Proxy-constructor}.\\n */\\n constructor(address _logic, address admin_, bytes memory _data) payable ERC1967Proxy(_logic, _data) {\\n assert(_ADMIN_SLOT == bytes32(uint256(keccak256(\\\"eip1967.proxy.admin\\\")) - 1));\\n _changeAdmin(admin_);\\n }\\n\\n /**\\n * @dev Modifier used internally that will delegate the call to the implementation unless the sender is the admin.\\n */\\n modifier ifAdmin() {\\n if (msg.sender == _getAdmin()) {\\n _;\\n } else {\\n _fallback();\\n }\\n }\\n\\n /**\\n * @dev Returns the current admin.\\n *\\n * NOTE: Only the admin can call this function. See {ProxyAdmin-getProxyAdmin}.\\n *\\n * TIP: To get this value clients can read directly from the storage slot shown below (specified by EIP1967) using the\\n * https://eth.wiki/json-rpc/API#eth_getstorageat[`eth_getStorageAt`] RPC call.\\n * `0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103`\\n */\\n function admin() external ifAdmin returns (address admin_) {\\n admin_ = _getAdmin();\\n }\\n\\n /**\\n * @dev Returns the current implementation.\\n *\\n * NOTE: Only the admin can call this function. See {ProxyAdmin-getProxyImplementation}.\\n *\\n * TIP: To get this value clients can read directly from the storage slot shown below (specified by EIP1967) using the\\n * https://eth.wiki/json-rpc/API#eth_getstorageat[`eth_getStorageAt`] RPC call.\\n * `0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc`\\n */\\n function implementation() external ifAdmin returns (address implementation_) {\\n implementation_ = _implementation();\\n }\\n\\n /**\\n * @dev Changes the admin of the proxy.\\n *\\n * Emits an {AdminChanged} event.\\n *\\n * NOTE: Only the admin can call this function. See {ProxyAdmin-changeProxyAdmin}.\\n */\\n function changeAdmin(address newAdmin) external virtual ifAdmin {\\n _changeAdmin(newAdmin);\\n }\\n\\n /**\\n * @dev Upgrade the implementation of the proxy.\\n *\\n * NOTE: Only the admin can call this function. See {ProxyAdmin-upgrade}.\\n */\\n function upgradeTo(address newImplementation) external ifAdmin {\\n _upgradeToAndCall(newImplementation, bytes(\\\"\\\"), false);\\n }\\n\\n /**\\n * @dev Upgrade the implementation of the proxy, and then call a function from the new implementation as specified\\n * by `data`, which should be an encoded function call. This is useful to initialize new storage variables in the\\n * proxied contract.\\n *\\n * NOTE: Only the admin can call this function. See {ProxyAdmin-upgradeAndCall}.\\n */\\n function upgradeToAndCall(address newImplementation, bytes calldata data) external payable ifAdmin {\\n _upgradeToAndCall(newImplementation, data, true);\\n }\\n\\n /**\\n * @dev Returns the current admin.\\n */\\n function _admin() internal view virtual returns (address) {\\n return _getAdmin();\\n }\\n\\n /**\\n * @dev Makes sure the admin cannot access the fallback function. See {Proxy-_beforeFallback}.\\n */\\n function _beforeFallback() internal virtual override {\\n require(msg.sender != _getAdmin(), \\\"TransparentUpgradeableProxy: admin cannot fallback to proxy target\\\");\\n super._beforeFallback();\\n }\\n}\\n\",\"keccak256\":\"0x93a67a0f612ea3ff2a76315e138a6a88267270a1379d3cc7be52845fbbe611e2\",\"license\":\"GPL-3.0\"}},\"version\":1}", + "bytecode": "0x6080604052604051620010bb380380620010bb8339810160408190526200002691620004d8565b828162000036828260006200009a565b5062000066905060017fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6104620005b8565b6000805160206200107483398151915214620000865762000086620005da565b6200009182620000d7565b50505062000643565b620000a58362000132565b600082511180620000b35750805b15620000d257620000d083836200017460201b6200028c1760201c565b505b505050565b7f7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f62000102620001a5565b604080516001600160a01b03928316815291841660208301520160405180910390a16200012f81620001de565b50565b6200013d8162000293565b6040516001600160a01b038216907fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b90600090a250565b60606200019c8383604051806060016040528060278152602001620010946027913962000347565b90505b92915050565b6000620001cf6000805160206200107483398151915260001b6200042f60201b6200022e1760201c565b546001600160a01b0316919050565b6001600160a01b038116620002495760405162461bcd60e51b815260206004820152602660248201527f455243313936373a206e65772061646d696e20697320746865207a65726f206160448201526564647265737360d01b60648201526084015b60405180910390fd5b80620002726000805160206200107483398151915260001b6200042f60201b6200022e1760201c565b80546001600160a01b0319166001600160a01b039290921691909117905550565b620002a9816200043260201b620002b81760201c565b6200030d5760405162461bcd60e51b815260206004820152602d60248201527f455243313936373a206e657720696d706c656d656e746174696f6e206973206e60448201526c1bdd08184818dbdb9d1c9858dd609a1b606482015260840162000240565b80620002727f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc60001b6200042f60201b6200022e1760201c565b60606001600160a01b0384163b620003b15760405162461bcd60e51b815260206004820152602660248201527f416464726573733a2064656c65676174652063616c6c20746f206e6f6e2d636f6044820152651b9d1c9858dd60d21b606482015260840162000240565b600080856001600160a01b031685604051620003ce9190620005f0565b600060405180830381855af49150503d80600081146200040b576040519150601f19603f3d011682016040523d82523d6000602084013e62000410565b606091505b5090925090506200042382828662000441565b925050505b9392505050565b90565b6001600160a01b03163b151590565b606083156200045257508162000428565b825115620004635782518084602001fd5b8160405162461bcd60e51b81526004016200024091906200060e565b80516001600160a01b03811681146200049757600080fd5b919050565b634e487b7160e01b600052604160045260246000fd5b60005b83811015620004cf578181015183820152602001620004b5565b50506000910152565b600080600060608486031215620004ee57600080fd5b620004f9846200047f565b925062000509602085016200047f565b60408501519092506001600160401b03808211156200052757600080fd5b818601915086601f8301126200053c57600080fd5b8151818111156200055157620005516200049c565b604051601f8201601f19908116603f011681019083821181831017156200057c576200057c6200049c565b816040528281528960208487010111156200059657600080fd5b620005a9836020830160208801620004b2565b80955050505050509250925092565b818103818111156200019f57634e487b7160e01b600052601160045260246000fd5b634e487b7160e01b600052600160045260246000fd5b6000825162000604818460208701620004b2565b9190910192915050565b60208152600082518060208401526200062f816040850160208701620004b2565b601f01601f19169190910160400192915050565b610a2180620006536000396000f3fe60806040526004361061005e5760003560e01c80635c60da1b116100435780635c60da1b146100a85780638f283970146100e6578063f851a440146101065761006d565b80633659cfe6146100755780634f1ef286146100955761006d565b3661006d5761006b61011b565b005b61006b61011b565b34801561008157600080fd5b5061006b610090366004610895565b610135565b61006b6100a33660046108b0565b61017f565b3480156100b457600080fd5b506100bd6101f3565b60405173ffffffffffffffffffffffffffffffffffffffff909116815260200160405180910390f35b3480156100f257600080fd5b5061006b610101366004610895565b610231565b34801561011257600080fd5b506100bd61025e565b6101236102d4565b61013361012e6103ab565b6103b5565b565b61013d6103d9565b73ffffffffffffffffffffffffffffffffffffffff1633036101775761017481604051806020016040528060008152506000610419565b50565b61017461011b565b6101876103d9565b73ffffffffffffffffffffffffffffffffffffffff1633036101eb576101e68383838080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525060019250610419915050565b505050565b6101e661011b565b60006101fd6103d9565b73ffffffffffffffffffffffffffffffffffffffff163303610226576102216103ab565b905090565b61022e61011b565b90565b6102396103d9565b73ffffffffffffffffffffffffffffffffffffffff1633036101775761017481610444565b60006102686103d9565b73ffffffffffffffffffffffffffffffffffffffff163303610226576102216103d9565b60606102b183836040518060600160405280602781526020016109c5602791396104a5565b9392505050565b73ffffffffffffffffffffffffffffffffffffffff163b151590565b6102dc6103d9565b73ffffffffffffffffffffffffffffffffffffffff163303610133576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604260248201527f5472616e73706172656e745570677261646561626c6550726f78793a2061646d60448201527f696e2063616e6e6f742066616c6c6261636b20746f2070726f7879207461726760648201527f6574000000000000000000000000000000000000000000000000000000000000608482015260a4015b60405180910390fd5b60006102216105cd565b3660008037600080366000845af43d6000803e8080156103d4573d6000f35b3d6000fd5b60007fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035b5473ffffffffffffffffffffffffffffffffffffffff16919050565b610422836105f5565b60008251118061042f5750805b156101e65761043e838361028c565b50505050565b7f7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f61046d6103d9565b6040805173ffffffffffffffffffffffffffffffffffffffff928316815291841660208301520160405180910390a161017481610642565b606073ffffffffffffffffffffffffffffffffffffffff84163b61054b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f416464726573733a2064656c65676174652063616c6c20746f206e6f6e2d636f60448201527f6e7472616374000000000000000000000000000000000000000000000000000060648201526084016103a2565b6000808573ffffffffffffffffffffffffffffffffffffffff16856040516105739190610957565b600060405180830381855af49150503d80600081146105ae576040519150601f19603f3d011682016040523d82523d6000602084013e6105b3565b606091505b50915091506105c382828661074e565b9695505050505050565b60007f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc6103fd565b6105fe816107a1565b60405173ffffffffffffffffffffffffffffffffffffffff8216907fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b90600090a250565b73ffffffffffffffffffffffffffffffffffffffff81166106e5576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f455243313936373a206e65772061646d696e20697320746865207a65726f206160448201527f646472657373000000000000000000000000000000000000000000000000000060648201526084016103a2565b807fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035b80547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff9290921691909117905550565b6060831561075d5750816102b1565b82511561076d5782518084602001fd5b816040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016103a29190610973565b73ffffffffffffffffffffffffffffffffffffffff81163b610845576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602d60248201527f455243313936373a206e657720696d706c656d656e746174696f6e206973206e60448201527f6f74206120636f6e74726163740000000000000000000000000000000000000060648201526084016103a2565b807f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc610708565b803573ffffffffffffffffffffffffffffffffffffffff8116811461089057600080fd5b919050565b6000602082840312156108a757600080fd5b6102b18261086c565b6000806000604084860312156108c557600080fd5b6108ce8461086c565b9250602084013567ffffffffffffffff808211156108eb57600080fd5b818601915086601f8301126108ff57600080fd5b81358181111561090e57600080fd5b87602082850101111561092057600080fd5b6020830194508093505050509250925092565b60005b8381101561094e578181015183820152602001610936565b50506000910152565b60008251610969818460208701610933565b9190910192915050565b6020815260008251806020840152610992816040850160208701610933565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016919091016040019291505056fe416464726573733a206c6f772d6c6576656c2064656c65676174652063616c6c206661696c6564a2646970667358221220e96638b07fb1675d93a95c49e417bc8111448b23a59918698cdcd8fd488dd7cf64736f6c63430008110033b53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103416464726573733a206c6f772d6c6576656c2064656c65676174652063616c6c206661696c6564", + "deployedBytecode": "0x60806040526004361061005e5760003560e01c80635c60da1b116100435780635c60da1b146100a85780638f283970146100e6578063f851a440146101065761006d565b80633659cfe6146100755780634f1ef286146100955761006d565b3661006d5761006b61011b565b005b61006b61011b565b34801561008157600080fd5b5061006b610090366004610895565b610135565b61006b6100a33660046108b0565b61017f565b3480156100b457600080fd5b506100bd6101f3565b60405173ffffffffffffffffffffffffffffffffffffffff909116815260200160405180910390f35b3480156100f257600080fd5b5061006b610101366004610895565b610231565b34801561011257600080fd5b506100bd61025e565b6101236102d4565b61013361012e6103ab565b6103b5565b565b61013d6103d9565b73ffffffffffffffffffffffffffffffffffffffff1633036101775761017481604051806020016040528060008152506000610419565b50565b61017461011b565b6101876103d9565b73ffffffffffffffffffffffffffffffffffffffff1633036101eb576101e68383838080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525060019250610419915050565b505050565b6101e661011b565b60006101fd6103d9565b73ffffffffffffffffffffffffffffffffffffffff163303610226576102216103ab565b905090565b61022e61011b565b90565b6102396103d9565b73ffffffffffffffffffffffffffffffffffffffff1633036101775761017481610444565b60006102686103d9565b73ffffffffffffffffffffffffffffffffffffffff163303610226576102216103d9565b60606102b183836040518060600160405280602781526020016109c5602791396104a5565b9392505050565b73ffffffffffffffffffffffffffffffffffffffff163b151590565b6102dc6103d9565b73ffffffffffffffffffffffffffffffffffffffff163303610133576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604260248201527f5472616e73706172656e745570677261646561626c6550726f78793a2061646d60448201527f696e2063616e6e6f742066616c6c6261636b20746f2070726f7879207461726760648201527f6574000000000000000000000000000000000000000000000000000000000000608482015260a4015b60405180910390fd5b60006102216105cd565b3660008037600080366000845af43d6000803e8080156103d4573d6000f35b3d6000fd5b60007fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035b5473ffffffffffffffffffffffffffffffffffffffff16919050565b610422836105f5565b60008251118061042f5750805b156101e65761043e838361028c565b50505050565b7f7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f61046d6103d9565b6040805173ffffffffffffffffffffffffffffffffffffffff928316815291841660208301520160405180910390a161017481610642565b606073ffffffffffffffffffffffffffffffffffffffff84163b61054b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f416464726573733a2064656c65676174652063616c6c20746f206e6f6e2d636f60448201527f6e7472616374000000000000000000000000000000000000000000000000000060648201526084016103a2565b6000808573ffffffffffffffffffffffffffffffffffffffff16856040516105739190610957565b600060405180830381855af49150503d80600081146105ae576040519150601f19603f3d011682016040523d82523d6000602084013e6105b3565b606091505b50915091506105c382828661074e565b9695505050505050565b60007f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc6103fd565b6105fe816107a1565b60405173ffffffffffffffffffffffffffffffffffffffff8216907fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b90600090a250565b73ffffffffffffffffffffffffffffffffffffffff81166106e5576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f455243313936373a206e65772061646d696e20697320746865207a65726f206160448201527f646472657373000000000000000000000000000000000000000000000000000060648201526084016103a2565b807fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035b80547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff9290921691909117905550565b6060831561075d5750816102b1565b82511561076d5782518084602001fd5b816040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016103a29190610973565b73ffffffffffffffffffffffffffffffffffffffff81163b610845576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602d60248201527f455243313936373a206e657720696d706c656d656e746174696f6e206973206e60448201527f6f74206120636f6e74726163740000000000000000000000000000000000000060648201526084016103a2565b807f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc610708565b803573ffffffffffffffffffffffffffffffffffffffff8116811461089057600080fd5b919050565b6000602082840312156108a757600080fd5b6102b18261086c565b6000806000604084860312156108c557600080fd5b6108ce8461086c565b9250602084013567ffffffffffffffff808211156108eb57600080fd5b818601915086601f8301126108ff57600080fd5b81358181111561090e57600080fd5b87602082850101111561092057600080fd5b6020830194508093505050509250925092565b60005b8381101561094e578181015183820152602001610936565b50506000910152565b60008251610969818460208701610933565b9190910192915050565b6020815260008251806020840152610992816040850160208701610933565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016919091016040019291505056fe416464726573733a206c6f772d6c6576656c2064656c65676174652063616c6c206661696c6564a2646970667358221220e96638b07fb1675d93a95c49e417bc8111448b23a59918698cdcd8fd488dd7cf64736f6c63430008110033", + "devdoc": { + "details": "This contract implements a proxy that is upgradeable by an admin. It is fully forked from OpenZeppelin `TransparentUpgradeableProxy` To avoid https://medium.com/nomic-labs-blog/malicious-backdoors-in-ethereum-proxies-62629adf3357[proxy selector clashing], which can potentially be used in an attack, this contract uses the https://blog.openzeppelin.com/the-transparent-proxy-pattern/[transparent proxy pattern]. This pattern implies two things that go hand in hand: 1. If any account other than the admin calls the proxy, the call will be forwarded to the implementation, even if that call matches one of the admin functions exposed by the proxy itself. 2. If the admin calls the proxy, it can access the admin functions, but its calls will never be forwarded to the implementation. If the admin tries to call a function on the implementation it will fail with an error that says \"admin cannot fallback to proxy target\". These properties mean that the admin account can only be used for admin actions like upgrading the proxy or changing the admin, so it's best if it's a dedicated account that is not used for anything else. This will avoid headaches due to sudden errors when trying to call a function from the proxy implementation. Our recommendation is for the dedicated account to be an instance of the {ProxyAdmin} contract. If set up this way, you should think of the `ProxyAdmin` instance as the real administrative interface of your proxy.", + "kind": "dev", + "methods": { + "admin()": { + "details": "Returns the current admin. NOTE: Only the admin can call this function. See {ProxyAdmin-getProxyAdmin}. TIP: To get this value clients can read directly from the storage slot shown below (specified by EIP1967) using the https://eth.wiki/json-rpc/API#eth_getstorageat[`eth_getStorageAt`] RPC call. `0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103`" + }, + "changeAdmin(address)": { + "details": "Changes the admin of the proxy. Emits an {AdminChanged} event. NOTE: Only the admin can call this function. See {ProxyAdmin-changeProxyAdmin}." + }, + "constructor": { + "details": "Initializes an upgradeable proxy managed by `_admin`, backed by the implementation at `_logic`, and optionally initialized with `_data` as explained in {ERC1967Proxy-constructor}." + }, + "implementation()": { + "details": "Returns the current implementation. NOTE: Only the admin can call this function. See {ProxyAdmin-getProxyImplementation}. TIP: To get this value clients can read directly from the storage slot shown below (specified by EIP1967) using the https://eth.wiki/json-rpc/API#eth_getstorageat[`eth_getStorageAt`] RPC call. `0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc`" + }, + "upgradeTo(address)": { + "details": "Upgrade the implementation of the proxy. NOTE: Only the admin can call this function. See {ProxyAdmin-upgrade}." + }, + "upgradeToAndCall(address,bytes)": { + "details": "Upgrade the implementation of the proxy, and then call a function from the new implementation as specified by `data`, which should be an encoded function call. This is useful to initialize new storage variables in the proxied contract. NOTE: Only the admin can call this function. See {ProxyAdmin-upgradeAndCall}." + } + }, + "version": 1 + }, + "userdoc": { + "kind": "user", + "methods": {}, + "version": 1 + }, + "storageLayout": { + "storage": [], + "types": null + } +} \ No newline at end of file diff --git a/deployments/arbitrum/solcInputs/871924e0c138825a2736b76def8fef8d.json b/deployments/arbitrum/solcInputs/871924e0c138825a2736b76def8fef8d.json new file mode 100644 index 00000000..57454028 --- /dev/null +++ b/deployments/arbitrum/solcInputs/871924e0c138825a2736b76def8fef8d.json @@ -0,0 +1,562 @@ +{ + "language": "Solidity", + "sources": { + "@chainlink/contracts/src/v0.8/interfaces/AggregatorV3Interface.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.0;\n\ninterface AggregatorV3Interface {\n\n function decimals()\n external\n view\n returns (\n uint8\n );\n\n function description()\n external\n view\n returns (\n string memory\n );\n\n function version()\n external\n view\n returns (\n uint256\n );\n\n // getRoundData and latestRoundData should both raise \"No data present\"\n // if they do not have data to report, instead of returning unset values\n // which could be misinterpreted as actual reported values.\n function getRoundData(\n uint80 _roundId\n )\n external\n view\n returns (\n uint80 roundId,\n int256 answer,\n uint256 startedAt,\n uint256 updatedAt,\n uint80 answeredInRound\n );\n\n function latestRoundData()\n external\n view\n returns (\n uint80 roundId,\n int256 answer,\n uint256 startedAt,\n uint256 updatedAt,\n uint80 answeredInRound\n );\n\n}\n" + }, + "@openzeppelin/contracts-upgradeable/access/AccessControlEnumerableUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.5.0) (access/AccessControlEnumerable.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./IAccessControlEnumerableUpgradeable.sol\";\nimport \"./AccessControlUpgradeable.sol\";\nimport \"../utils/structs/EnumerableSetUpgradeable.sol\";\nimport \"../proxy/utils/Initializable.sol\";\n\n/**\n * @dev Extension of {AccessControl} that allows enumerating the members of each role.\n */\nabstract contract AccessControlEnumerableUpgradeable is Initializable, IAccessControlEnumerableUpgradeable, AccessControlUpgradeable {\n function __AccessControlEnumerable_init() internal onlyInitializing {\n }\n\n function __AccessControlEnumerable_init_unchained() internal onlyInitializing {\n }\n using EnumerableSetUpgradeable for EnumerableSetUpgradeable.AddressSet;\n\n mapping(bytes32 => EnumerableSetUpgradeable.AddressSet) private _roleMembers;\n\n /**\n * @dev See {IERC165-supportsInterface}.\n */\n function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {\n return interfaceId == type(IAccessControlEnumerableUpgradeable).interfaceId || super.supportsInterface(interfaceId);\n }\n\n /**\n * @dev Returns one of the accounts that have `role`. `index` must be a\n * value between 0 and {getRoleMemberCount}, non-inclusive.\n *\n * Role bearers are not sorted in any particular way, and their ordering may\n * change at any point.\n *\n * WARNING: When using {getRoleMember} and {getRoleMemberCount}, make sure\n * you perform all queries on the same block. See the following\n * https://forum.openzeppelin.com/t/iterating-over-elements-on-enumerableset-in-openzeppelin-contracts/2296[forum post]\n * for more information.\n */\n function getRoleMember(bytes32 role, uint256 index) public view virtual override returns (address) {\n return _roleMembers[role].at(index);\n }\n\n /**\n * @dev Returns the number of accounts that have `role`. Can be used\n * together with {getRoleMember} to enumerate all bearers of a role.\n */\n function getRoleMemberCount(bytes32 role) public view virtual override returns (uint256) {\n return _roleMembers[role].length();\n }\n\n /**\n * @dev Overload {_grantRole} to track enumerable memberships\n */\n function _grantRole(bytes32 role, address account) internal virtual override {\n super._grantRole(role, account);\n _roleMembers[role].add(account);\n }\n\n /**\n * @dev Overload {_revokeRole} to track enumerable memberships\n */\n function _revokeRole(bytes32 role, address account) internal virtual override {\n super._revokeRole(role, account);\n _roleMembers[role].remove(account);\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[49] private __gap;\n}\n" + }, + "@openzeppelin/contracts-upgradeable/access/AccessControlUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (access/AccessControl.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./IAccessControlUpgradeable.sol\";\nimport \"../utils/ContextUpgradeable.sol\";\nimport \"../utils/StringsUpgradeable.sol\";\nimport \"../utils/introspection/ERC165Upgradeable.sol\";\nimport \"../proxy/utils/Initializable.sol\";\n\n/**\n * @dev Contract module that allows children to implement role-based access\n * control mechanisms. This is a lightweight version that doesn't allow enumerating role\n * members except through off-chain means by accessing the contract event logs. Some\n * applications may benefit from on-chain enumerability, for those cases see\n * {AccessControlEnumerable}.\n *\n * Roles are referred to by their `bytes32` identifier. These should be exposed\n * in the external API and be unique. The best way to achieve this is by\n * using `public constant` hash digests:\n *\n * ```\n * bytes32 public constant MY_ROLE = keccak256(\"MY_ROLE\");\n * ```\n *\n * Roles can be used to represent a set of permissions. To restrict access to a\n * function call, use {hasRole}:\n *\n * ```\n * function foo() public {\n * require(hasRole(MY_ROLE, msg.sender));\n * ...\n * }\n * ```\n *\n * Roles can be granted and revoked dynamically via the {grantRole} and\n * {revokeRole} functions. Each role has an associated admin role, and only\n * accounts that have a role's admin role can call {grantRole} and {revokeRole}.\n *\n * By default, the admin role for all roles is `DEFAULT_ADMIN_ROLE`, which means\n * that only accounts with this role will be able to grant or revoke other\n * roles. More complex role relationships can be created by using\n * {_setRoleAdmin}.\n *\n * WARNING: The `DEFAULT_ADMIN_ROLE` is also its own admin: it has permission to\n * grant and revoke this role. Extra precautions should be taken to secure\n * accounts that have been granted it.\n */\nabstract contract AccessControlUpgradeable is Initializable, ContextUpgradeable, IAccessControlUpgradeable, ERC165Upgradeable {\n function __AccessControl_init() internal onlyInitializing {\n }\n\n function __AccessControl_init_unchained() internal onlyInitializing {\n }\n struct RoleData {\n mapping(address => bool) members;\n bytes32 adminRole;\n }\n\n mapping(bytes32 => RoleData) private _roles;\n\n bytes32 public constant DEFAULT_ADMIN_ROLE = 0x00;\n\n /**\n * @dev Modifier that checks that an account has a specific role. Reverts\n * with a standardized message including the required role.\n *\n * The format of the revert reason is given by the following regular expression:\n *\n * /^AccessControl: account (0x[0-9a-f]{40}) is missing role (0x[0-9a-f]{64})$/\n *\n * _Available since v4.1._\n */\n modifier onlyRole(bytes32 role) {\n _checkRole(role);\n _;\n }\n\n /**\n * @dev See {IERC165-supportsInterface}.\n */\n function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {\n return interfaceId == type(IAccessControlUpgradeable).interfaceId || super.supportsInterface(interfaceId);\n }\n\n /**\n * @dev Returns `true` if `account` has been granted `role`.\n */\n function hasRole(bytes32 role, address account) public view virtual override returns (bool) {\n return _roles[role].members[account];\n }\n\n /**\n * @dev Revert with a standard message if `_msgSender()` is missing `role`.\n * Overriding this function changes the behavior of the {onlyRole} modifier.\n *\n * Format of the revert message is described in {_checkRole}.\n *\n * _Available since v4.6._\n */\n function _checkRole(bytes32 role) internal view virtual {\n _checkRole(role, _msgSender());\n }\n\n /**\n * @dev Revert with a standard message if `account` is missing `role`.\n *\n * The format of the revert reason is given by the following regular expression:\n *\n * /^AccessControl: account (0x[0-9a-f]{40}) is missing role (0x[0-9a-f]{64})$/\n */\n function _checkRole(bytes32 role, address account) internal view virtual {\n if (!hasRole(role, account)) {\n revert(\n string(\n abi.encodePacked(\n \"AccessControl: account \",\n StringsUpgradeable.toHexString(uint160(account), 20),\n \" is missing role \",\n StringsUpgradeable.toHexString(uint256(role), 32)\n )\n )\n );\n }\n }\n\n /**\n * @dev Returns the admin role that controls `role`. See {grantRole} and\n * {revokeRole}.\n *\n * To change a role's admin, use {_setRoleAdmin}.\n */\n function getRoleAdmin(bytes32 role) public view virtual override returns (bytes32) {\n return _roles[role].adminRole;\n }\n\n /**\n * @dev Grants `role` to `account`.\n *\n * If `account` had not been already granted `role`, emits a {RoleGranted}\n * event.\n *\n * Requirements:\n *\n * - the caller must have ``role``'s admin role.\n *\n * May emit a {RoleGranted} event.\n */\n function grantRole(bytes32 role, address account) public virtual override onlyRole(getRoleAdmin(role)) {\n _grantRole(role, account);\n }\n\n /**\n * @dev Revokes `role` from `account`.\n *\n * If `account` had been granted `role`, emits a {RoleRevoked} event.\n *\n * Requirements:\n *\n * - the caller must have ``role``'s admin role.\n *\n * May emit a {RoleRevoked} event.\n */\n function revokeRole(bytes32 role, address account) public virtual override onlyRole(getRoleAdmin(role)) {\n _revokeRole(role, account);\n }\n\n /**\n * @dev Revokes `role` from the calling account.\n *\n * Roles are often managed via {grantRole} and {revokeRole}: this function's\n * purpose is to provide a mechanism for accounts to lose their privileges\n * if they are compromised (such as when a trusted device is misplaced).\n *\n * If the calling account had been revoked `role`, emits a {RoleRevoked}\n * event.\n *\n * Requirements:\n *\n * - the caller must be `account`.\n *\n * May emit a {RoleRevoked} event.\n */\n function renounceRole(bytes32 role, address account) public virtual override {\n require(account == _msgSender(), \"AccessControl: can only renounce roles for self\");\n\n _revokeRole(role, account);\n }\n\n /**\n * @dev Grants `role` to `account`.\n *\n * If `account` had not been already granted `role`, emits a {RoleGranted}\n * event. Note that unlike {grantRole}, this function doesn't perform any\n * checks on the calling account.\n *\n * May emit a {RoleGranted} event.\n *\n * [WARNING]\n * ====\n * This function should only be called from the constructor when setting\n * up the initial roles for the system.\n *\n * Using this function in any other way is effectively circumventing the admin\n * system imposed by {AccessControl}.\n * ====\n *\n * NOTE: This function is deprecated in favor of {_grantRole}.\n */\n function _setupRole(bytes32 role, address account) internal virtual {\n _grantRole(role, account);\n }\n\n /**\n * @dev Sets `adminRole` as ``role``'s admin role.\n *\n * Emits a {RoleAdminChanged} event.\n */\n function _setRoleAdmin(bytes32 role, bytes32 adminRole) internal virtual {\n bytes32 previousAdminRole = getRoleAdmin(role);\n _roles[role].adminRole = adminRole;\n emit RoleAdminChanged(role, previousAdminRole, adminRole);\n }\n\n /**\n * @dev Grants `role` to `account`.\n *\n * Internal function without access restriction.\n *\n * May emit a {RoleGranted} event.\n */\n function _grantRole(bytes32 role, address account) internal virtual {\n if (!hasRole(role, account)) {\n _roles[role].members[account] = true;\n emit RoleGranted(role, account, _msgSender());\n }\n }\n\n /**\n * @dev Revokes `role` from `account`.\n *\n * Internal function without access restriction.\n *\n * May emit a {RoleRevoked} event.\n */\n function _revokeRole(bytes32 role, address account) internal virtual {\n if (hasRole(role, account)) {\n _roles[role].members[account] = false;\n emit RoleRevoked(role, account, _msgSender());\n }\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[49] private __gap;\n}\n" + }, + "@openzeppelin/contracts-upgradeable/access/IAccessControlEnumerableUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (access/IAccessControlEnumerable.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./IAccessControlUpgradeable.sol\";\n\n/**\n * @dev External interface of AccessControlEnumerable declared to support ERC165 detection.\n */\ninterface IAccessControlEnumerableUpgradeable is IAccessControlUpgradeable {\n /**\n * @dev Returns one of the accounts that have `role`. `index` must be a\n * value between 0 and {getRoleMemberCount}, non-inclusive.\n *\n * Role bearers are not sorted in any particular way, and their ordering may\n * change at any point.\n *\n * WARNING: When using {getRoleMember} and {getRoleMemberCount}, make sure\n * you perform all queries on the same block. See the following\n * https://forum.openzeppelin.com/t/iterating-over-elements-on-enumerableset-in-openzeppelin-contracts/2296[forum post]\n * for more information.\n */\n function getRoleMember(bytes32 role, uint256 index) external view returns (address);\n\n /**\n * @dev Returns the number of accounts that have `role`. Can be used\n * together with {getRoleMember} to enumerate all bearers of a role.\n */\n function getRoleMemberCount(bytes32 role) external view returns (uint256);\n}\n" + }, + "@openzeppelin/contracts-upgradeable/access/IAccessControlUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (access/IAccessControl.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev External interface of AccessControl declared to support ERC165 detection.\n */\ninterface IAccessControlUpgradeable {\n /**\n * @dev Emitted when `newAdminRole` is set as ``role``'s admin role, replacing `previousAdminRole`\n *\n * `DEFAULT_ADMIN_ROLE` is the starting admin for all roles, despite\n * {RoleAdminChanged} not being emitted signaling this.\n *\n * _Available since v3.1._\n */\n event RoleAdminChanged(bytes32 indexed role, bytes32 indexed previousAdminRole, bytes32 indexed newAdminRole);\n\n /**\n * @dev Emitted when `account` is granted `role`.\n *\n * `sender` is the account that originated the contract call, an admin role\n * bearer except when using {AccessControl-_setupRole}.\n */\n event RoleGranted(bytes32 indexed role, address indexed account, address indexed sender);\n\n /**\n * @dev Emitted when `account` is revoked `role`.\n *\n * `sender` is the account that originated the contract call:\n * - if using `revokeRole`, it is the admin role bearer\n * - if using `renounceRole`, it is the role bearer (i.e. `account`)\n */\n event RoleRevoked(bytes32 indexed role, address indexed account, address indexed sender);\n\n /**\n * @dev Returns `true` if `account` has been granted `role`.\n */\n function hasRole(bytes32 role, address account) external view returns (bool);\n\n /**\n * @dev Returns the admin role that controls `role`. See {grantRole} and\n * {revokeRole}.\n *\n * To change a role's admin, use {AccessControl-_setRoleAdmin}.\n */\n function getRoleAdmin(bytes32 role) external view returns (bytes32);\n\n /**\n * @dev Grants `role` to `account`.\n *\n * If `account` had not been already granted `role`, emits a {RoleGranted}\n * event.\n *\n * Requirements:\n *\n * - the caller must have ``role``'s admin role.\n */\n function grantRole(bytes32 role, address account) external;\n\n /**\n * @dev Revokes `role` from `account`.\n *\n * If `account` had been granted `role`, emits a {RoleRevoked} event.\n *\n * Requirements:\n *\n * - the caller must have ``role``'s admin role.\n */\n function revokeRole(bytes32 role, address account) external;\n\n /**\n * @dev Revokes `role` from the calling account.\n *\n * Roles are often managed via {grantRole} and {revokeRole}: this function's\n * purpose is to provide a mechanism for accounts to lose their privileges\n * if they are compromised (such as when a trusted device is misplaced).\n *\n * If the calling account had been granted `role`, emits a {RoleRevoked}\n * event.\n *\n * Requirements:\n *\n * - the caller must be `account`.\n */\n function renounceRole(bytes32 role, address account) external;\n}\n" + }, + "@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (access/Ownable.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../utils/ContextUpgradeable.sol\";\nimport \"../proxy/utils/Initializable.sol\";\n\n/**\n * @dev Contract module which provides a basic access control mechanism, where\n * there is an account (an owner) that can be granted exclusive access to\n * specific functions.\n *\n * By default, the owner account will be the one that deploys the contract. This\n * can later be changed with {transferOwnership}.\n *\n * This module is used through inheritance. It will make available the modifier\n * `onlyOwner`, which can be applied to your functions to restrict their use to\n * the owner.\n */\nabstract contract OwnableUpgradeable is Initializable, ContextUpgradeable {\n address private _owner;\n\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\n\n /**\n * @dev Initializes the contract setting the deployer as the initial owner.\n */\n function __Ownable_init() internal onlyInitializing {\n __Ownable_init_unchained();\n }\n\n function __Ownable_init_unchained() internal onlyInitializing {\n _transferOwnership(_msgSender());\n }\n\n /**\n * @dev Throws if called by any account other than the owner.\n */\n modifier onlyOwner() {\n _checkOwner();\n _;\n }\n\n /**\n * @dev Returns the address of the current owner.\n */\n function owner() public view virtual returns (address) {\n return _owner;\n }\n\n /**\n * @dev Throws if the sender is not the owner.\n */\n function _checkOwner() internal view virtual {\n require(owner() == _msgSender(), \"Ownable: caller is not the owner\");\n }\n\n /**\n * @dev Leaves the contract without owner. It will not be possible to call\n * `onlyOwner` functions anymore. Can only be called by the current owner.\n *\n * NOTE: Renouncing ownership will leave the contract without an owner,\n * thereby removing any functionality that is only available to the owner.\n */\n function renounceOwnership() public virtual onlyOwner {\n _transferOwnership(address(0));\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Can only be called by the current owner.\n */\n function transferOwnership(address newOwner) public virtual onlyOwner {\n require(newOwner != address(0), \"Ownable: new owner is the zero address\");\n _transferOwnership(newOwner);\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Internal function without access restriction.\n */\n function _transferOwnership(address newOwner) internal virtual {\n address oldOwner = _owner;\n _owner = newOwner;\n emit OwnershipTransferred(oldOwner, newOwner);\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[49] private __gap;\n}\n" + }, + "@openzeppelin/contracts-upgradeable/interfaces/IERC721MetadataUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (interfaces/IERC721Metadata.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../token/ERC721/extensions/IERC721MetadataUpgradeable.sol\";\n" + }, + "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (proxy/utils/Initializable.sol)\n\npragma solidity ^0.8.2;\n\nimport \"../../utils/AddressUpgradeable.sol\";\n\n/**\n * @dev This is a base contract to aid in writing upgradeable contracts, or any kind of contract that will be deployed\n * behind a proxy. Since proxied contracts do not make use of a constructor, it's common to move constructor logic to an\n * external initializer function, usually called `initialize`. It then becomes necessary to protect this initializer\n * function so it can only be called once. The {initializer} modifier provided by this contract will have this effect.\n *\n * The initialization functions use a version number. Once a version number is used, it is consumed and cannot be\n * reused. This mechanism prevents re-execution of each \"step\" but allows the creation of new initialization steps in\n * case an upgrade adds a module that needs to be initialized.\n *\n * For example:\n *\n * [.hljs-theme-light.nopadding]\n * ```\n * contract MyToken is ERC20Upgradeable {\n * function initialize() initializer public {\n * __ERC20_init(\"MyToken\", \"MTK\");\n * }\n * }\n * contract MyTokenV2 is MyToken, ERC20PermitUpgradeable {\n * function initializeV2() reinitializer(2) public {\n * __ERC20Permit_init(\"MyToken\");\n * }\n * }\n * ```\n *\n * TIP: To avoid leaving the proxy in an uninitialized state, the initializer function should be called as early as\n * possible by providing the encoded function call as the `_data` argument to {ERC1967Proxy-constructor}.\n *\n * CAUTION: When used with inheritance, manual care must be taken to not invoke a parent initializer twice, or to ensure\n * that all initializers are idempotent. This is not verified automatically as constructors are by Solidity.\n *\n * [CAUTION]\n * ====\n * Avoid leaving a contract uninitialized.\n *\n * An uninitialized contract can be taken over by an attacker. This applies to both a proxy and its implementation\n * contract, which may impact the proxy. To prevent the implementation contract from being used, you should invoke\n * the {_disableInitializers} function in the constructor to automatically lock it when it is deployed:\n *\n * [.hljs-theme-light.nopadding]\n * ```\n * /// @custom:oz-upgrades-unsafe-allow constructor\n * constructor() {\n * _disableInitializers();\n * }\n * ```\n * ====\n */\nabstract contract Initializable {\n /**\n * @dev Indicates that the contract has been initialized.\n * @custom:oz-retyped-from bool\n */\n uint8 private _initialized;\n\n /**\n * @dev Indicates that the contract is in the process of being initialized.\n */\n bool private _initializing;\n\n /**\n * @dev Triggered when the contract has been initialized or reinitialized.\n */\n event Initialized(uint8 version);\n\n /**\n * @dev A modifier that defines a protected initializer function that can be invoked at most once. In its scope,\n * `onlyInitializing` functions can be used to initialize parent contracts. Equivalent to `reinitializer(1)`.\n */\n modifier initializer() {\n bool isTopLevelCall = !_initializing;\n require(\n (isTopLevelCall && _initialized < 1) || (!AddressUpgradeable.isContract(address(this)) && _initialized == 1),\n \"Initializable: contract is already initialized\"\n );\n _initialized = 1;\n if (isTopLevelCall) {\n _initializing = true;\n }\n _;\n if (isTopLevelCall) {\n _initializing = false;\n emit Initialized(1);\n }\n }\n\n /**\n * @dev A modifier that defines a protected reinitializer function that can be invoked at most once, and only if the\n * contract hasn't been initialized to a greater version before. In its scope, `onlyInitializing` functions can be\n * used to initialize parent contracts.\n *\n * `initializer` is equivalent to `reinitializer(1)`, so a reinitializer may be used after the original\n * initialization step. This is essential to configure modules that are added through upgrades and that require\n * initialization.\n *\n * Note that versions can jump in increments greater than 1; this implies that if multiple reinitializers coexist in\n * a contract, executing them in the right order is up to the developer or operator.\n */\n modifier reinitializer(uint8 version) {\n require(!_initializing && _initialized < version, \"Initializable: contract is already initialized\");\n _initialized = version;\n _initializing = true;\n _;\n _initializing = false;\n emit Initialized(version);\n }\n\n /**\n * @dev Modifier to protect an initialization function so that it can only be invoked by functions with the\n * {initializer} and {reinitializer} modifiers, directly or indirectly.\n */\n modifier onlyInitializing() {\n require(_initializing, \"Initializable: contract is not initializing\");\n _;\n }\n\n /**\n * @dev Locks the contract, preventing any future reinitialization. This cannot be part of an initializer call.\n * Calling this in the constructor of a contract will prevent that contract from being initialized or reinitialized\n * to any version. It is recommended to use this to lock implementation contracts that are designed to be called\n * through proxies.\n */\n function _disableInitializers() internal virtual {\n require(!_initializing, \"Initializable: contract is initializing\");\n if (_initialized < type(uint8).max) {\n _initialized = type(uint8).max;\n emit Initialized(type(uint8).max);\n }\n }\n}\n" + }, + "@openzeppelin/contracts-upgradeable/security/PausableUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (security/Pausable.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../utils/ContextUpgradeable.sol\";\nimport \"../proxy/utils/Initializable.sol\";\n\n/**\n * @dev Contract module which allows children to implement an emergency stop\n * mechanism that can be triggered by an authorized account.\n *\n * This module is used through inheritance. It will make available the\n * modifiers `whenNotPaused` and `whenPaused`, which can be applied to\n * the functions of your contract. Note that they will not be pausable by\n * simply including this module, only once the modifiers are put in place.\n */\nabstract contract PausableUpgradeable is Initializable, ContextUpgradeable {\n /**\n * @dev Emitted when the pause is triggered by `account`.\n */\n event Paused(address account);\n\n /**\n * @dev Emitted when the pause is lifted by `account`.\n */\n event Unpaused(address account);\n\n bool private _paused;\n\n /**\n * @dev Initializes the contract in unpaused state.\n */\n function __Pausable_init() internal onlyInitializing {\n __Pausable_init_unchained();\n }\n\n function __Pausable_init_unchained() internal onlyInitializing {\n _paused = false;\n }\n\n /**\n * @dev Modifier to make a function callable only when the contract is not paused.\n *\n * Requirements:\n *\n * - The contract must not be paused.\n */\n modifier whenNotPaused() {\n _requireNotPaused();\n _;\n }\n\n /**\n * @dev Modifier to make a function callable only when the contract is paused.\n *\n * Requirements:\n *\n * - The contract must be paused.\n */\n modifier whenPaused() {\n _requirePaused();\n _;\n }\n\n /**\n * @dev Returns true if the contract is paused, and false otherwise.\n */\n function paused() public view virtual returns (bool) {\n return _paused;\n }\n\n /**\n * @dev Throws if the contract is paused.\n */\n function _requireNotPaused() internal view virtual {\n require(!paused(), \"Pausable: paused\");\n }\n\n /**\n * @dev Throws if the contract is not paused.\n */\n function _requirePaused() internal view virtual {\n require(paused(), \"Pausable: not paused\");\n }\n\n /**\n * @dev Triggers stopped state.\n *\n * Requirements:\n *\n * - The contract must not be paused.\n */\n function _pause() internal virtual whenNotPaused {\n _paused = true;\n emit Paused(_msgSender());\n }\n\n /**\n * @dev Returns to normal state.\n *\n * Requirements:\n *\n * - The contract must be paused.\n */\n function _unpause() internal virtual whenPaused {\n _paused = false;\n emit Unpaused(_msgSender());\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[49] private __gap;\n}\n" + }, + "@openzeppelin/contracts-upgradeable/security/ReentrancyGuardUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (security/ReentrancyGuard.sol)\n\npragma solidity ^0.8.0;\nimport \"../proxy/utils/Initializable.sol\";\n\n/**\n * @dev Contract module that helps prevent reentrant calls to a function.\n *\n * Inheriting from `ReentrancyGuard` will make the {nonReentrant} modifier\n * available, which can be applied to functions to make sure there are no nested\n * (reentrant) calls to them.\n *\n * Note that because there is a single `nonReentrant` guard, functions marked as\n * `nonReentrant` may not call one another. This can be worked around by making\n * those functions `private`, and then adding `external` `nonReentrant` entry\n * points to them.\n *\n * TIP: If you would like to learn more about reentrancy and alternative ways\n * to protect against it, check out our blog post\n * https://blog.openzeppelin.com/reentrancy-after-istanbul/[Reentrancy After Istanbul].\n */\nabstract contract ReentrancyGuardUpgradeable is Initializable {\n // Booleans are more expensive than uint256 or any type that takes up a full\n // word because each write operation emits an extra SLOAD to first read the\n // slot's contents, replace the bits taken up by the boolean, and then write\n // back. This is the compiler's defense against contract upgrades and\n // pointer aliasing, and it cannot be disabled.\n\n // The values being non-zero value makes deployment a bit more expensive,\n // but in exchange the refund on every call to nonReentrant will be lower in\n // amount. Since refunds are capped to a percentage of the total\n // transaction's gas, it is best to keep them low in cases like this one, to\n // increase the likelihood of the full refund coming into effect.\n uint256 private constant _NOT_ENTERED = 1;\n uint256 private constant _ENTERED = 2;\n\n uint256 private _status;\n\n function __ReentrancyGuard_init() internal onlyInitializing {\n __ReentrancyGuard_init_unchained();\n }\n\n function __ReentrancyGuard_init_unchained() internal onlyInitializing {\n _status = _NOT_ENTERED;\n }\n\n /**\n * @dev Prevents a contract from calling itself, directly or indirectly.\n * Calling a `nonReentrant` function from another `nonReentrant`\n * function is not supported. It is possible to prevent this from happening\n * by making the `nonReentrant` function external, and making it call a\n * `private` function that does the actual work.\n */\n modifier nonReentrant() {\n // On the first call to nonReentrant, _notEntered will be true\n require(_status != _ENTERED, \"ReentrancyGuard: reentrant call\");\n\n // Any calls to nonReentrant after this point will fail\n _status = _ENTERED;\n\n _;\n\n // By storing the original value once again, a refund is triggered (see\n // https://eips.ethereum.org/EIPS/eip-2200)\n _status = _NOT_ENTERED;\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[49] private __gap;\n}\n" + }, + "@openzeppelin/contracts-upgradeable/token/ERC20/ERC20Upgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (token/ERC20/ERC20.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./IERC20Upgradeable.sol\";\nimport \"./extensions/IERC20MetadataUpgradeable.sol\";\nimport \"../../utils/ContextUpgradeable.sol\";\nimport \"../../proxy/utils/Initializable.sol\";\n\n/**\n * @dev Implementation of the {IERC20} interface.\n *\n * This implementation is agnostic to the way tokens are created. This means\n * that a supply mechanism has to be added in a derived contract using {_mint}.\n * For a generic mechanism see {ERC20PresetMinterPauser}.\n *\n * TIP: For a detailed writeup see our guide\n * https://forum.zeppelin.solutions/t/how-to-implement-erc20-supply-mechanisms/226[How\n * to implement supply mechanisms].\n *\n * We have followed general OpenZeppelin Contracts guidelines: functions revert\n * instead returning `false` on failure. This behavior is nonetheless\n * conventional and does not conflict with the expectations of ERC20\n * applications.\n *\n * Additionally, an {Approval} event is emitted on calls to {transferFrom}.\n * This allows applications to reconstruct the allowance for all accounts just\n * by listening to said events. Other implementations of the EIP may not emit\n * these events, as it isn't required by the specification.\n *\n * Finally, the non-standard {decreaseAllowance} and {increaseAllowance}\n * functions have been added to mitigate the well-known issues around setting\n * allowances. See {IERC20-approve}.\n */\ncontract ERC20Upgradeable is Initializable, ContextUpgradeable, IERC20Upgradeable, IERC20MetadataUpgradeable {\n mapping(address => uint256) private _balances;\n\n mapping(address => mapping(address => uint256)) private _allowances;\n\n uint256 private _totalSupply;\n\n string private _name;\n string private _symbol;\n\n /**\n * @dev Sets the values for {name} and {symbol}.\n *\n * The default value of {decimals} is 18. To select a different value for\n * {decimals} you should overload it.\n *\n * All two of these values are immutable: they can only be set once during\n * construction.\n */\n function __ERC20_init(string memory name_, string memory symbol_) internal onlyInitializing {\n __ERC20_init_unchained(name_, symbol_);\n }\n\n function __ERC20_init_unchained(string memory name_, string memory symbol_) internal onlyInitializing {\n _name = name_;\n _symbol = symbol_;\n }\n\n /**\n * @dev Returns the name of the token.\n */\n function name() public view virtual override returns (string memory) {\n return _name;\n }\n\n /**\n * @dev Returns the symbol of the token, usually a shorter version of the\n * name.\n */\n function symbol() public view virtual override returns (string memory) {\n return _symbol;\n }\n\n /**\n * @dev Returns the number of decimals used to get its user representation.\n * For example, if `decimals` equals `2`, a balance of `505` tokens should\n * be displayed to a user as `5.05` (`505 / 10 ** 2`).\n *\n * Tokens usually opt for a value of 18, imitating the relationship between\n * Ether and Wei. This is the value {ERC20} uses, unless this function is\n * overridden;\n *\n * NOTE: This information is only used for _display_ purposes: it in\n * no way affects any of the arithmetic of the contract, including\n * {IERC20-balanceOf} and {IERC20-transfer}.\n */\n function decimals() public view virtual override returns (uint8) {\n return 18;\n }\n\n /**\n * @dev See {IERC20-totalSupply}.\n */\n function totalSupply() public view virtual override returns (uint256) {\n return _totalSupply;\n }\n\n /**\n * @dev See {IERC20-balanceOf}.\n */\n function balanceOf(address account) public view virtual override returns (uint256) {\n return _balances[account];\n }\n\n /**\n * @dev See {IERC20-transfer}.\n *\n * Requirements:\n *\n * - `to` cannot be the zero address.\n * - the caller must have a balance of at least `amount`.\n */\n function transfer(address to, uint256 amount) public virtual override returns (bool) {\n address owner = _msgSender();\n _transfer(owner, to, amount);\n return true;\n }\n\n /**\n * @dev See {IERC20-allowance}.\n */\n function allowance(address owner, address spender) public view virtual override returns (uint256) {\n return _allowances[owner][spender];\n }\n\n /**\n * @dev See {IERC20-approve}.\n *\n * NOTE: If `amount` is the maximum `uint256`, the allowance is not updated on\n * `transferFrom`. This is semantically equivalent to an infinite approval.\n *\n * Requirements:\n *\n * - `spender` cannot be the zero address.\n */\n function approve(address spender, uint256 amount) public virtual override returns (bool) {\n address owner = _msgSender();\n _approve(owner, spender, amount);\n return true;\n }\n\n /**\n * @dev See {IERC20-transferFrom}.\n *\n * Emits an {Approval} event indicating the updated allowance. This is not\n * required by the EIP. See the note at the beginning of {ERC20}.\n *\n * NOTE: Does not update the allowance if the current allowance\n * is the maximum `uint256`.\n *\n * Requirements:\n *\n * - `from` and `to` cannot be the zero address.\n * - `from` must have a balance of at least `amount`.\n * - the caller must have allowance for ``from``'s tokens of at least\n * `amount`.\n */\n function transferFrom(\n address from,\n address to,\n uint256 amount\n ) public virtual override returns (bool) {\n address spender = _msgSender();\n _spendAllowance(from, spender, amount);\n _transfer(from, to, amount);\n return true;\n }\n\n /**\n * @dev Atomically increases the allowance granted to `spender` by the caller.\n *\n * This is an alternative to {approve} that can be used as a mitigation for\n * problems described in {IERC20-approve}.\n *\n * Emits an {Approval} event indicating the updated allowance.\n *\n * Requirements:\n *\n * - `spender` cannot be the zero address.\n */\n function increaseAllowance(address spender, uint256 addedValue) public virtual returns (bool) {\n address owner = _msgSender();\n _approve(owner, spender, allowance(owner, spender) + addedValue);\n return true;\n }\n\n /**\n * @dev Atomically decreases the allowance granted to `spender` by the caller.\n *\n * This is an alternative to {approve} that can be used as a mitigation for\n * problems described in {IERC20-approve}.\n *\n * Emits an {Approval} event indicating the updated allowance.\n *\n * Requirements:\n *\n * - `spender` cannot be the zero address.\n * - `spender` must have allowance for the caller of at least\n * `subtractedValue`.\n */\n function decreaseAllowance(address spender, uint256 subtractedValue) public virtual returns (bool) {\n address owner = _msgSender();\n uint256 currentAllowance = allowance(owner, spender);\n require(currentAllowance >= subtractedValue, \"ERC20: decreased allowance below zero\");\n unchecked {\n _approve(owner, spender, currentAllowance - subtractedValue);\n }\n\n return true;\n }\n\n /**\n * @dev Moves `amount` of tokens from `from` to `to`.\n *\n * This internal function is equivalent to {transfer}, and can be used to\n * e.g. implement automatic token fees, slashing mechanisms, etc.\n *\n * Emits a {Transfer} event.\n *\n * Requirements:\n *\n * - `from` cannot be the zero address.\n * - `to` cannot be the zero address.\n * - `from` must have a balance of at least `amount`.\n */\n function _transfer(\n address from,\n address to,\n uint256 amount\n ) internal virtual {\n require(from != address(0), \"ERC20: transfer from the zero address\");\n require(to != address(0), \"ERC20: transfer to the zero address\");\n\n _beforeTokenTransfer(from, to, amount);\n\n uint256 fromBalance = _balances[from];\n require(fromBalance >= amount, \"ERC20: transfer amount exceeds balance\");\n unchecked {\n _balances[from] = fromBalance - amount;\n }\n _balances[to] += amount;\n\n emit Transfer(from, to, amount);\n\n _afterTokenTransfer(from, to, amount);\n }\n\n /** @dev Creates `amount` tokens and assigns them to `account`, increasing\n * the total supply.\n *\n * Emits a {Transfer} event with `from` set to the zero address.\n *\n * Requirements:\n *\n * - `account` cannot be the zero address.\n */\n function _mint(address account, uint256 amount) internal virtual {\n require(account != address(0), \"ERC20: mint to the zero address\");\n\n _beforeTokenTransfer(address(0), account, amount);\n\n _totalSupply += amount;\n _balances[account] += amount;\n emit Transfer(address(0), account, amount);\n\n _afterTokenTransfer(address(0), account, amount);\n }\n\n /**\n * @dev Destroys `amount` tokens from `account`, reducing the\n * total supply.\n *\n * Emits a {Transfer} event with `to` set to the zero address.\n *\n * Requirements:\n *\n * - `account` cannot be the zero address.\n * - `account` must have at least `amount` tokens.\n */\n function _burn(address account, uint256 amount) internal virtual {\n require(account != address(0), \"ERC20: burn from the zero address\");\n\n _beforeTokenTransfer(account, address(0), amount);\n\n uint256 accountBalance = _balances[account];\n require(accountBalance >= amount, \"ERC20: burn amount exceeds balance\");\n unchecked {\n _balances[account] = accountBalance - amount;\n }\n _totalSupply -= amount;\n\n emit Transfer(account, address(0), amount);\n\n _afterTokenTransfer(account, address(0), amount);\n }\n\n /**\n * @dev Sets `amount` as the allowance of `spender` over the `owner` s tokens.\n *\n * This internal function is equivalent to `approve`, and can be used to\n * e.g. set automatic allowances for certain subsystems, etc.\n *\n * Emits an {Approval} event.\n *\n * Requirements:\n *\n * - `owner` cannot be the zero address.\n * - `spender` cannot be the zero address.\n */\n function _approve(\n address owner,\n address spender,\n uint256 amount\n ) internal virtual {\n require(owner != address(0), \"ERC20: approve from the zero address\");\n require(spender != address(0), \"ERC20: approve to the zero address\");\n\n _allowances[owner][spender] = amount;\n emit Approval(owner, spender, amount);\n }\n\n /**\n * @dev Updates `owner` s allowance for `spender` based on spent `amount`.\n *\n * Does not update the allowance amount in case of infinite allowance.\n * Revert if not enough allowance is available.\n *\n * Might emit an {Approval} event.\n */\n function _spendAllowance(\n address owner,\n address spender,\n uint256 amount\n ) internal virtual {\n uint256 currentAllowance = allowance(owner, spender);\n if (currentAllowance != type(uint256).max) {\n require(currentAllowance >= amount, \"ERC20: insufficient allowance\");\n unchecked {\n _approve(owner, spender, currentAllowance - amount);\n }\n }\n }\n\n /**\n * @dev Hook that is called before any transfer of tokens. This includes\n * minting and burning.\n *\n * Calling conditions:\n *\n * - when `from` and `to` are both non-zero, `amount` of ``from``'s tokens\n * will be transferred to `to`.\n * - when `from` is zero, `amount` tokens will be minted for `to`.\n * - when `to` is zero, `amount` of ``from``'s tokens will be burned.\n * - `from` and `to` are never both zero.\n *\n * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].\n */\n function _beforeTokenTransfer(\n address from,\n address to,\n uint256 amount\n ) internal virtual {}\n\n /**\n * @dev Hook that is called after any transfer of tokens. This includes\n * minting and burning.\n *\n * Calling conditions:\n *\n * - when `from` and `to` are both non-zero, `amount` of ``from``'s tokens\n * has been transferred to `to`.\n * - when `from` is zero, `amount` tokens have been minted for `to`.\n * - when `to` is zero, `amount` of ``from``'s tokens have been burned.\n * - `from` and `to` are never both zero.\n *\n * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].\n */\n function _afterTokenTransfer(\n address from,\n address to,\n uint256 amount\n ) internal virtual {}\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[45] private __gap;\n}\n" + }, + "@openzeppelin/contracts-upgradeable/token/ERC20/extensions/draft-ERC20PermitUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.6.0) (token/ERC20/extensions/draft-ERC20Permit.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./draft-IERC20PermitUpgradeable.sol\";\nimport \"../ERC20Upgradeable.sol\";\nimport \"../../../utils/cryptography/draft-EIP712Upgradeable.sol\";\nimport \"../../../utils/cryptography/ECDSAUpgradeable.sol\";\nimport \"../../../utils/CountersUpgradeable.sol\";\nimport \"../../../proxy/utils/Initializable.sol\";\n\n/**\n * @dev Implementation of the ERC20 Permit extension allowing approvals to be made via signatures, as defined in\n * https://eips.ethereum.org/EIPS/eip-2612[EIP-2612].\n *\n * Adds the {permit} method, which can be used to change an account's ERC20 allowance (see {IERC20-allowance}) by\n * presenting a message signed by the account. By not relying on `{IERC20-approve}`, the token holder account doesn't\n * need to send a transaction, and thus is not required to hold Ether at all.\n *\n * _Available since v3.4._\n *\n * @custom:storage-size 51\n */\nabstract contract ERC20PermitUpgradeable is Initializable, ERC20Upgradeable, IERC20PermitUpgradeable, EIP712Upgradeable {\n using CountersUpgradeable for CountersUpgradeable.Counter;\n\n mapping(address => CountersUpgradeable.Counter) private _nonces;\n\n // solhint-disable-next-line var-name-mixedcase\n bytes32 private constant _PERMIT_TYPEHASH =\n keccak256(\"Permit(address owner,address spender,uint256 value,uint256 nonce,uint256 deadline)\");\n /**\n * @dev In previous versions `_PERMIT_TYPEHASH` was declared as `immutable`.\n * However, to ensure consistency with the upgradeable transpiler, we will continue\n * to reserve a slot.\n * @custom:oz-renamed-from _PERMIT_TYPEHASH\n */\n // solhint-disable-next-line var-name-mixedcase\n bytes32 private _PERMIT_TYPEHASH_DEPRECATED_SLOT;\n\n /**\n * @dev Initializes the {EIP712} domain separator using the `name` parameter, and setting `version` to `\"1\"`.\n *\n * It's a good idea to use the same `name` that is defined as the ERC20 token name.\n */\n function __ERC20Permit_init(string memory name) internal onlyInitializing {\n __EIP712_init_unchained(name, \"1\");\n }\n\n function __ERC20Permit_init_unchained(string memory) internal onlyInitializing {}\n\n /**\n * @dev See {IERC20Permit-permit}.\n */\n function permit(\n address owner,\n address spender,\n uint256 value,\n uint256 deadline,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) public virtual override {\n require(block.timestamp <= deadline, \"ERC20Permit: expired deadline\");\n\n bytes32 structHash = keccak256(abi.encode(_PERMIT_TYPEHASH, owner, spender, value, _useNonce(owner), deadline));\n\n bytes32 hash = _hashTypedDataV4(structHash);\n\n address signer = ECDSAUpgradeable.recover(hash, v, r, s);\n require(signer == owner, \"ERC20Permit: invalid signature\");\n\n _approve(owner, spender, value);\n }\n\n /**\n * @dev See {IERC20Permit-nonces}.\n */\n function nonces(address owner) public view virtual override returns (uint256) {\n return _nonces[owner].current();\n }\n\n /**\n * @dev See {IERC20Permit-DOMAIN_SEPARATOR}.\n */\n // solhint-disable-next-line func-name-mixedcase\n function DOMAIN_SEPARATOR() external view override returns (bytes32) {\n return _domainSeparatorV4();\n }\n\n /**\n * @dev \"Consume a nonce\": return the current value and increment.\n *\n * _Available since v4.1._\n */\n function _useNonce(address owner) internal virtual returns (uint256 current) {\n CountersUpgradeable.Counter storage nonce = _nonces[owner];\n current = nonce.current();\n nonce.increment();\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[49] private __gap;\n}\n" + }, + "@openzeppelin/contracts-upgradeable/token/ERC20/extensions/draft-IERC20PermitUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (token/ERC20/extensions/draft-IERC20Permit.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Interface of the ERC20 Permit extension allowing approvals to be made via signatures, as defined in\n * https://eips.ethereum.org/EIPS/eip-2612[EIP-2612].\n *\n * Adds the {permit} method, which can be used to change an account's ERC20 allowance (see {IERC20-allowance}) by\n * presenting a message signed by the account. By not relying on {IERC20-approve}, the token holder account doesn't\n * need to send a transaction, and thus is not required to hold Ether at all.\n */\ninterface IERC20PermitUpgradeable {\n /**\n * @dev Sets `value` as the allowance of `spender` over ``owner``'s tokens,\n * given ``owner``'s signed approval.\n *\n * IMPORTANT: The same issues {IERC20-approve} has related to transaction\n * ordering also apply here.\n *\n * Emits an {Approval} event.\n *\n * Requirements:\n *\n * - `spender` cannot be the zero address.\n * - `deadline` must be a timestamp in the future.\n * - `v`, `r` and `s` must be a valid `secp256k1` signature from `owner`\n * over the EIP712-formatted function arguments.\n * - the signature must use ``owner``'s current nonce (see {nonces}).\n *\n * For more information on the signature format, see the\n * https://eips.ethereum.org/EIPS/eip-2612#specification[relevant EIP\n * section].\n */\n function permit(\n address owner,\n address spender,\n uint256 value,\n uint256 deadline,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) external;\n\n /**\n * @dev Returns the current nonce for `owner`. This value must be\n * included whenever a signature is generated for {permit}.\n *\n * Every successful call to {permit} increases ``owner``'s nonce by one. This\n * prevents a signature from being used multiple times.\n */\n function nonces(address owner) external view returns (uint256);\n\n /**\n * @dev Returns the domain separator used in the encoding of the signature for {permit}, as defined by {EIP712}.\n */\n // solhint-disable-next-line func-name-mixedcase\n function DOMAIN_SEPARATOR() external view returns (bytes32);\n}\n" + }, + "@openzeppelin/contracts-upgradeable/token/ERC20/extensions/IERC20MetadataUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (token/ERC20/extensions/IERC20Metadata.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../IERC20Upgradeable.sol\";\n\n/**\n * @dev Interface for the optional metadata functions from the ERC20 standard.\n *\n * _Available since v4.1._\n */\ninterface IERC20MetadataUpgradeable is IERC20Upgradeable {\n /**\n * @dev Returns the name of the token.\n */\n function name() external view returns (string memory);\n\n /**\n * @dev Returns the symbol of the token.\n */\n function symbol() external view returns (string memory);\n\n /**\n * @dev Returns the decimals places of the token.\n */\n function decimals() external view returns (uint8);\n}\n" + }, + "@openzeppelin/contracts-upgradeable/token/ERC20/IERC20Upgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.6.0) (token/ERC20/IERC20.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Interface of the ERC20 standard as defined in the EIP.\n */\ninterface IERC20Upgradeable {\n /**\n * @dev Emitted when `value` tokens are moved from one account (`from`) to\n * another (`to`).\n *\n * Note that `value` may be zero.\n */\n event Transfer(address indexed from, address indexed to, uint256 value);\n\n /**\n * @dev Emitted when the allowance of a `spender` for an `owner` is set by\n * a call to {approve}. `value` is the new allowance.\n */\n event Approval(address indexed owner, address indexed spender, uint256 value);\n\n /**\n * @dev Returns the amount of tokens in existence.\n */\n function totalSupply() external view returns (uint256);\n\n /**\n * @dev Returns the amount of tokens owned by `account`.\n */\n function balanceOf(address account) external view returns (uint256);\n\n /**\n * @dev Moves `amount` tokens from the caller's account to `to`.\n *\n * Returns a boolean value indicating whether the operation succeeded.\n *\n * Emits a {Transfer} event.\n */\n function transfer(address to, uint256 amount) external returns (bool);\n\n /**\n * @dev Returns the remaining number of tokens that `spender` will be\n * allowed to spend on behalf of `owner` through {transferFrom}. This is\n * zero by default.\n *\n * This value changes when {approve} or {transferFrom} are called.\n */\n function allowance(address owner, address spender) external view returns (uint256);\n\n /**\n * @dev Sets `amount` as the allowance of `spender` over the caller's tokens.\n *\n * Returns a boolean value indicating whether the operation succeeded.\n *\n * IMPORTANT: Beware that changing an allowance with this method brings the risk\n * that someone may use both the old and the new allowance by unfortunate\n * transaction ordering. One possible solution to mitigate this race\n * condition is to first reduce the spender's allowance to 0 and set the\n * desired value afterwards:\n * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729\n *\n * Emits an {Approval} event.\n */\n function approve(address spender, uint256 amount) external returns (bool);\n\n /**\n * @dev Moves `amount` tokens from `from` to `to` using the\n * allowance mechanism. `amount` is then deducted from the caller's\n * allowance.\n *\n * Returns a boolean value indicating whether the operation succeeded.\n *\n * Emits a {Transfer} event.\n */\n function transferFrom(\n address from,\n address to,\n uint256 amount\n ) external returns (bool);\n}\n" + }, + "@openzeppelin/contracts-upgradeable/token/ERC721/extensions/IERC721MetadataUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (token/ERC721/extensions/IERC721Metadata.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../IERC721Upgradeable.sol\";\n\n/**\n * @title ERC-721 Non-Fungible Token Standard, optional metadata extension\n * @dev See https://eips.ethereum.org/EIPS/eip-721\n */\ninterface IERC721MetadataUpgradeable is IERC721Upgradeable {\n /**\n * @dev Returns the token collection name.\n */\n function name() external view returns (string memory);\n\n /**\n * @dev Returns the token collection symbol.\n */\n function symbol() external view returns (string memory);\n\n /**\n * @dev Returns the Uniform Resource Identifier (URI) for `tokenId` token.\n */\n function tokenURI(uint256 tokenId) external view returns (string memory);\n}\n" + }, + "@openzeppelin/contracts-upgradeable/token/ERC721/IERC721ReceiverUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.6.0) (token/ERC721/IERC721Receiver.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @title ERC721 token receiver interface\n * @dev Interface for any contract that wants to support safeTransfers\n * from ERC721 asset contracts.\n */\ninterface IERC721ReceiverUpgradeable {\n /**\n * @dev Whenever an {IERC721} `tokenId` token is transferred to this contract via {IERC721-safeTransferFrom}\n * by `operator` from `from`, this function is called.\n *\n * It must return its Solidity selector to confirm the token transfer.\n * If any other value is returned or the interface is not implemented by the recipient, the transfer will be reverted.\n *\n * The selector can be obtained in Solidity with `IERC721Receiver.onERC721Received.selector`.\n */\n function onERC721Received(\n address operator,\n address from,\n uint256 tokenId,\n bytes calldata data\n ) external returns (bytes4);\n}\n" + }, + "@openzeppelin/contracts-upgradeable/token/ERC721/IERC721Upgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (token/ERC721/IERC721.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../../utils/introspection/IERC165Upgradeable.sol\";\n\n/**\n * @dev Required interface of an ERC721 compliant contract.\n */\ninterface IERC721Upgradeable is IERC165Upgradeable {\n /**\n * @dev Emitted when `tokenId` token is transferred from `from` to `to`.\n */\n event Transfer(address indexed from, address indexed to, uint256 indexed tokenId);\n\n /**\n * @dev Emitted when `owner` enables `approved` to manage the `tokenId` token.\n */\n event Approval(address indexed owner, address indexed approved, uint256 indexed tokenId);\n\n /**\n * @dev Emitted when `owner` enables or disables (`approved`) `operator` to manage all of its assets.\n */\n event ApprovalForAll(address indexed owner, address indexed operator, bool approved);\n\n /**\n * @dev Returns the number of tokens in ``owner``'s account.\n */\n function balanceOf(address owner) external view returns (uint256 balance);\n\n /**\n * @dev Returns the owner of the `tokenId` token.\n *\n * Requirements:\n *\n * - `tokenId` must exist.\n */\n function ownerOf(uint256 tokenId) external view returns (address owner);\n\n /**\n * @dev Safely transfers `tokenId` token from `from` to `to`.\n *\n * Requirements:\n *\n * - `from` cannot be the zero address.\n * - `to` cannot be the zero address.\n * - `tokenId` token must exist and be owned by `from`.\n * - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}.\n * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.\n *\n * Emits a {Transfer} event.\n */\n function safeTransferFrom(\n address from,\n address to,\n uint256 tokenId,\n bytes calldata data\n ) external;\n\n /**\n * @dev Safely transfers `tokenId` token from `from` to `to`, checking first that contract recipients\n * are aware of the ERC721 protocol to prevent tokens from being forever locked.\n *\n * Requirements:\n *\n * - `from` cannot be the zero address.\n * - `to` cannot be the zero address.\n * - `tokenId` token must exist and be owned by `from`.\n * - If the caller is not `from`, it must have been allowed to move this token by either {approve} or {setApprovalForAll}.\n * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.\n *\n * Emits a {Transfer} event.\n */\n function safeTransferFrom(\n address from,\n address to,\n uint256 tokenId\n ) external;\n\n /**\n * @dev Transfers `tokenId` token from `from` to `to`.\n *\n * WARNING: Usage of this method is discouraged, use {safeTransferFrom} whenever possible.\n *\n * Requirements:\n *\n * - `from` cannot be the zero address.\n * - `to` cannot be the zero address.\n * - `tokenId` token must be owned by `from`.\n * - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}.\n *\n * Emits a {Transfer} event.\n */\n function transferFrom(\n address from,\n address to,\n uint256 tokenId\n ) external;\n\n /**\n * @dev Gives permission to `to` to transfer `tokenId` token to another account.\n * The approval is cleared when the token is transferred.\n *\n * Only a single account can be approved at a time, so approving the zero address clears previous approvals.\n *\n * Requirements:\n *\n * - The caller must own the token or be an approved operator.\n * - `tokenId` must exist.\n *\n * Emits an {Approval} event.\n */\n function approve(address to, uint256 tokenId) external;\n\n /**\n * @dev Approve or remove `operator` as an operator for the caller.\n * Operators can call {transferFrom} or {safeTransferFrom} for any token owned by the caller.\n *\n * Requirements:\n *\n * - The `operator` cannot be the caller.\n *\n * Emits an {ApprovalForAll} event.\n */\n function setApprovalForAll(address operator, bool _approved) external;\n\n /**\n * @dev Returns the account approved for `tokenId` token.\n *\n * Requirements:\n *\n * - `tokenId` must exist.\n */\n function getApproved(uint256 tokenId) external view returns (address operator);\n\n /**\n * @dev Returns if the `operator` is allowed to manage all of the assets of `owner`.\n *\n * See {setApprovalForAll}\n */\n function isApprovedForAll(address owner, address operator) external view returns (bool);\n}\n" + }, + "@openzeppelin/contracts-upgradeable/utils/AddressUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (utils/Address.sol)\n\npragma solidity ^0.8.1;\n\n/**\n * @dev Collection of functions related to the address type\n */\nlibrary AddressUpgradeable {\n /**\n * @dev Returns true if `account` is a contract.\n *\n * [IMPORTANT]\n * ====\n * It is unsafe to assume that an address for which this function returns\n * false is an externally-owned account (EOA) and not a contract.\n *\n * Among others, `isContract` will return false for the following\n * types of addresses:\n *\n * - an externally-owned account\n * - a contract in construction\n * - an address where a contract will be created\n * - an address where a contract lived, but was destroyed\n * ====\n *\n * [IMPORTANT]\n * ====\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\n *\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\n * constructor.\n * ====\n */\n function isContract(address account) internal view returns (bool) {\n // This method relies on extcodesize/address.code.length, which returns 0\n // for contracts in construction, since the code is only stored at the end\n // of the constructor execution.\n\n return account.code.length > 0;\n }\n\n /**\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\n * `recipient`, forwarding all available gas and reverting on errors.\n *\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\n * imposed by `transfer`, making them unable to receive funds via\n * `transfer`. {sendValue} removes this limitation.\n *\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\n *\n * IMPORTANT: because control is transferred to `recipient`, care must be\n * taken to not create reentrancy vulnerabilities. Consider using\n * {ReentrancyGuard} or the\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\n */\n function sendValue(address payable recipient, uint256 amount) internal {\n require(address(this).balance >= amount, \"Address: insufficient balance\");\n\n (bool success, ) = recipient.call{value: amount}(\"\");\n require(success, \"Address: unable to send value, recipient may have reverted\");\n }\n\n /**\n * @dev Performs a Solidity function call using a low level `call`. A\n * plain `call` is an unsafe replacement for a function call: use this\n * function instead.\n *\n * If `target` reverts with a revert reason, it is bubbled up by this\n * function (like regular Solidity function calls).\n *\n * Returns the raw returned data. To convert to the expected return value,\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\n *\n * Requirements:\n *\n * - `target` must be a contract.\n * - calling `target` with `data` must not revert.\n *\n * _Available since v3.1._\n */\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionCall(target, data, \"Address: low-level call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\n * `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, 0, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but also transferring `value` wei to `target`.\n *\n * Requirements:\n *\n * - the calling contract must have an ETH balance of at least `value`.\n * - the called Solidity function must be `payable`.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, value, \"Address: low-level call with value failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\n * with `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(address(this).balance >= value, \"Address: insufficient balance for call\");\n require(isContract(target), \"Address: call to non-contract\");\n\n (bool success, bytes memory returndata) = target.call{value: value}(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\n return functionStaticCall(target, data, \"Address: low-level static call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal view returns (bytes memory) {\n require(isContract(target), \"Address: static call to non-contract\");\n\n (bool success, bytes memory returndata) = target.staticcall(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the\n * revert reason using the provided one.\n *\n * _Available since v4.3._\n */\n function verifyCallResult(\n bool success,\n bytes memory returndata,\n string memory errorMessage\n ) internal pure returns (bytes memory) {\n if (success) {\n return returndata;\n } else {\n // Look for revert reason and bubble it up if present\n if (returndata.length > 0) {\n // The easiest way to bubble the revert reason is using memory via assembly\n /// @solidity memory-safe-assembly\n assembly {\n let returndata_size := mload(returndata)\n revert(add(32, returndata), returndata_size)\n }\n } else {\n revert(errorMessage);\n }\n }\n }\n}\n" + }, + "@openzeppelin/contracts-upgradeable/utils/ContextUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)\n\npragma solidity ^0.8.0;\nimport \"../proxy/utils/Initializable.sol\";\n\n/**\n * @dev Provides information about the current execution context, including the\n * sender of the transaction and its data. While these are generally available\n * via msg.sender and msg.data, they should not be accessed in such a direct\n * manner, since when dealing with meta-transactions the account sending and\n * paying for execution may not be the actual sender (as far as an application\n * is concerned).\n *\n * This contract is only required for intermediate, library-like contracts.\n */\nabstract contract ContextUpgradeable is Initializable {\n function __Context_init() internal onlyInitializing {\n }\n\n function __Context_init_unchained() internal onlyInitializing {\n }\n function _msgSender() internal view virtual returns (address) {\n return msg.sender;\n }\n\n function _msgData() internal view virtual returns (bytes calldata) {\n return msg.data;\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[50] private __gap;\n}\n" + }, + "@openzeppelin/contracts-upgradeable/utils/CountersUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (utils/Counters.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @title Counters\n * @author Matt Condon (@shrugs)\n * @dev Provides counters that can only be incremented, decremented or reset. This can be used e.g. to track the number\n * of elements in a mapping, issuing ERC721 ids, or counting request ids.\n *\n * Include with `using Counters for Counters.Counter;`\n */\nlibrary CountersUpgradeable {\n struct Counter {\n // This variable should never be directly accessed by users of the library: interactions must be restricted to\n // the library's function. As of Solidity v0.5.2, this cannot be enforced, though there is a proposal to add\n // this feature: see https://github.com/ethereum/solidity/issues/4637\n uint256 _value; // default: 0\n }\n\n function current(Counter storage counter) internal view returns (uint256) {\n return counter._value;\n }\n\n function increment(Counter storage counter) internal {\n unchecked {\n counter._value += 1;\n }\n }\n\n function decrement(Counter storage counter) internal {\n uint256 value = counter._value;\n require(value > 0, \"Counter: decrement overflow\");\n unchecked {\n counter._value = value - 1;\n }\n }\n\n function reset(Counter storage counter) internal {\n counter._value = 0;\n }\n}\n" + }, + "@openzeppelin/contracts-upgradeable/utils/cryptography/draft-EIP712Upgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (utils/cryptography/draft-EIP712.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./ECDSAUpgradeable.sol\";\nimport \"../../proxy/utils/Initializable.sol\";\n\n/**\n * @dev https://eips.ethereum.org/EIPS/eip-712[EIP 712] is a standard for hashing and signing of typed structured data.\n *\n * The encoding specified in the EIP is very generic, and such a generic implementation in Solidity is not feasible,\n * thus this contract does not implement the encoding itself. Protocols need to implement the type-specific encoding\n * they need in their contracts using a combination of `abi.encode` and `keccak256`.\n *\n * This contract implements the EIP 712 domain separator ({_domainSeparatorV4}) that is used as part of the encoding\n * scheme, and the final step of the encoding to obtain the message digest that is then signed via ECDSA\n * ({_hashTypedDataV4}).\n *\n * The implementation of the domain separator was designed to be as efficient as possible while still properly updating\n * the chain id to protect against replay attacks on an eventual fork of the chain.\n *\n * NOTE: This contract implements the version of the encoding known as \"v4\", as implemented by the JSON RPC method\n * https://docs.metamask.io/guide/signing-data.html[`eth_signTypedDataV4` in MetaMask].\n *\n * _Available since v3.4._\n *\n * @custom:storage-size 52\n */\nabstract contract EIP712Upgradeable is Initializable {\n /* solhint-disable var-name-mixedcase */\n bytes32 private _HASHED_NAME;\n bytes32 private _HASHED_VERSION;\n bytes32 private constant _TYPE_HASH = keccak256(\"EIP712Domain(string name,string version,uint256 chainId,address verifyingContract)\");\n\n /* solhint-enable var-name-mixedcase */\n\n /**\n * @dev Initializes the domain separator and parameter caches.\n *\n * The meaning of `name` and `version` is specified in\n * https://eips.ethereum.org/EIPS/eip-712#definition-of-domainseparator[EIP 712]:\n *\n * - `name`: the user readable name of the signing domain, i.e. the name of the DApp or the protocol.\n * - `version`: the current major version of the signing domain.\n *\n * NOTE: These parameters cannot be changed except through a xref:learn::upgrading-smart-contracts.adoc[smart\n * contract upgrade].\n */\n function __EIP712_init(string memory name, string memory version) internal onlyInitializing {\n __EIP712_init_unchained(name, version);\n }\n\n function __EIP712_init_unchained(string memory name, string memory version) internal onlyInitializing {\n bytes32 hashedName = keccak256(bytes(name));\n bytes32 hashedVersion = keccak256(bytes(version));\n _HASHED_NAME = hashedName;\n _HASHED_VERSION = hashedVersion;\n }\n\n /**\n * @dev Returns the domain separator for the current chain.\n */\n function _domainSeparatorV4() internal view returns (bytes32) {\n return _buildDomainSeparator(_TYPE_HASH, _EIP712NameHash(), _EIP712VersionHash());\n }\n\n function _buildDomainSeparator(\n bytes32 typeHash,\n bytes32 nameHash,\n bytes32 versionHash\n ) private view returns (bytes32) {\n return keccak256(abi.encode(typeHash, nameHash, versionHash, block.chainid, address(this)));\n }\n\n /**\n * @dev Given an already https://eips.ethereum.org/EIPS/eip-712#definition-of-hashstruct[hashed struct], this\n * function returns the hash of the fully encoded EIP712 message for this domain.\n *\n * This hash can be used together with {ECDSA-recover} to obtain the signer of a message. For example:\n *\n * ```solidity\n * bytes32 digest = _hashTypedDataV4(keccak256(abi.encode(\n * keccak256(\"Mail(address to,string contents)\"),\n * mailTo,\n * keccak256(bytes(mailContents))\n * )));\n * address signer = ECDSA.recover(digest, signature);\n * ```\n */\n function _hashTypedDataV4(bytes32 structHash) internal view virtual returns (bytes32) {\n return ECDSAUpgradeable.toTypedDataHash(_domainSeparatorV4(), structHash);\n }\n\n /**\n * @dev The hash of the name parameter for the EIP712 domain.\n *\n * NOTE: This function reads from storage by default, but can be redefined to return a constant value if gas costs\n * are a concern.\n */\n function _EIP712NameHash() internal virtual view returns (bytes32) {\n return _HASHED_NAME;\n }\n\n /**\n * @dev The hash of the version parameter for the EIP712 domain.\n *\n * NOTE: This function reads from storage by default, but can be redefined to return a constant value if gas costs\n * are a concern.\n */\n function _EIP712VersionHash() internal virtual view returns (bytes32) {\n return _HASHED_VERSION;\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[50] private __gap;\n}\n" + }, + "@openzeppelin/contracts-upgradeable/utils/cryptography/ECDSAUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (utils/cryptography/ECDSA.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../StringsUpgradeable.sol\";\n\n/**\n * @dev Elliptic Curve Digital Signature Algorithm (ECDSA) operations.\n *\n * These functions can be used to verify that a message was signed by the holder\n * of the private keys of a given address.\n */\nlibrary ECDSAUpgradeable {\n enum RecoverError {\n NoError,\n InvalidSignature,\n InvalidSignatureLength,\n InvalidSignatureS,\n InvalidSignatureV\n }\n\n function _throwError(RecoverError error) private pure {\n if (error == RecoverError.NoError) {\n return; // no error: do nothing\n } else if (error == RecoverError.InvalidSignature) {\n revert(\"ECDSA: invalid signature\");\n } else if (error == RecoverError.InvalidSignatureLength) {\n revert(\"ECDSA: invalid signature length\");\n } else if (error == RecoverError.InvalidSignatureS) {\n revert(\"ECDSA: invalid signature 's' value\");\n } else if (error == RecoverError.InvalidSignatureV) {\n revert(\"ECDSA: invalid signature 'v' value\");\n }\n }\n\n /**\n * @dev Returns the address that signed a hashed message (`hash`) with\n * `signature` or error string. This address can then be used for verification purposes.\n *\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\n * this function rejects them by requiring the `s` value to be in the lower\n * half order, and the `v` value to be either 27 or 28.\n *\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\n * verification to be secure: it is possible to craft signatures that\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\n * this is by receiving a hash of the original message (which may otherwise\n * be too long), and then calling {toEthSignedMessageHash} on it.\n *\n * Documentation for signature generation:\n * - with https://web3js.readthedocs.io/en/v1.3.4/web3-eth-accounts.html#sign[Web3.js]\n * - with https://docs.ethers.io/v5/api/signer/#Signer-signMessage[ethers]\n *\n * _Available since v4.3._\n */\n function tryRecover(bytes32 hash, bytes memory signature) internal pure returns (address, RecoverError) {\n // Check the signature length\n // - case 65: r,s,v signature (standard)\n // - case 64: r,vs signature (cf https://eips.ethereum.org/EIPS/eip-2098) _Available since v4.1._\n if (signature.length == 65) {\n bytes32 r;\n bytes32 s;\n uint8 v;\n // ecrecover takes the signature parameters, and the only way to get them\n // currently is to use assembly.\n /// @solidity memory-safe-assembly\n assembly {\n r := mload(add(signature, 0x20))\n s := mload(add(signature, 0x40))\n v := byte(0, mload(add(signature, 0x60)))\n }\n return tryRecover(hash, v, r, s);\n } else if (signature.length == 64) {\n bytes32 r;\n bytes32 vs;\n // ecrecover takes the signature parameters, and the only way to get them\n // currently is to use assembly.\n /// @solidity memory-safe-assembly\n assembly {\n r := mload(add(signature, 0x20))\n vs := mload(add(signature, 0x40))\n }\n return tryRecover(hash, r, vs);\n } else {\n return (address(0), RecoverError.InvalidSignatureLength);\n }\n }\n\n /**\n * @dev Returns the address that signed a hashed message (`hash`) with\n * `signature`. This address can then be used for verification purposes.\n *\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\n * this function rejects them by requiring the `s` value to be in the lower\n * half order, and the `v` value to be either 27 or 28.\n *\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\n * verification to be secure: it is possible to craft signatures that\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\n * this is by receiving a hash of the original message (which may otherwise\n * be too long), and then calling {toEthSignedMessageHash} on it.\n */\n function recover(bytes32 hash, bytes memory signature) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, signature);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Overload of {ECDSA-tryRecover} that receives the `r` and `vs` short-signature fields separately.\n *\n * See https://eips.ethereum.org/EIPS/eip-2098[EIP-2098 short signatures]\n *\n * _Available since v4.3._\n */\n function tryRecover(\n bytes32 hash,\n bytes32 r,\n bytes32 vs\n ) internal pure returns (address, RecoverError) {\n bytes32 s = vs & bytes32(0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff);\n uint8 v = uint8((uint256(vs) >> 255) + 27);\n return tryRecover(hash, v, r, s);\n }\n\n /**\n * @dev Overload of {ECDSA-recover} that receives the `r and `vs` short-signature fields separately.\n *\n * _Available since v4.2._\n */\n function recover(\n bytes32 hash,\n bytes32 r,\n bytes32 vs\n ) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, r, vs);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Overload of {ECDSA-tryRecover} that receives the `v`,\n * `r` and `s` signature fields separately.\n *\n * _Available since v4.3._\n */\n function tryRecover(\n bytes32 hash,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) internal pure returns (address, RecoverError) {\n // EIP-2 still allows signature malleability for ecrecover(). Remove this possibility and make the signature\n // unique. Appendix F in the Ethereum Yellow paper (https://ethereum.github.io/yellowpaper/paper.pdf), defines\n // the valid range for s in (301): 0 < s < secp256k1n ÷ 2 + 1, and for v in (302): v ∈ {27, 28}. Most\n // signatures from current libraries generate a unique signature with an s-value in the lower half order.\n //\n // If your library generates malleable signatures, such as s-values in the upper range, calculate a new s-value\n // with 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141 - s1 and flip v from 27 to 28 or\n // vice versa. If your library also generates signatures with 0/1 for v instead 27/28, add 27 to v to accept\n // these malleable signatures as well.\n if (uint256(s) > 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D576E7357A4501DDFE92F46681B20A0) {\n return (address(0), RecoverError.InvalidSignatureS);\n }\n if (v != 27 && v != 28) {\n return (address(0), RecoverError.InvalidSignatureV);\n }\n\n // If the signature is valid (and not malleable), return the signer address\n address signer = ecrecover(hash, v, r, s);\n if (signer == address(0)) {\n return (address(0), RecoverError.InvalidSignature);\n }\n\n return (signer, RecoverError.NoError);\n }\n\n /**\n * @dev Overload of {ECDSA-recover} that receives the `v`,\n * `r` and `s` signature fields separately.\n */\n function recover(\n bytes32 hash,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, v, r, s);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Returns an Ethereum Signed Message, created from a `hash`. This\n * produces hash corresponding to the one signed with the\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\n * JSON-RPC method as part of EIP-191.\n *\n * See {recover}.\n */\n function toEthSignedMessageHash(bytes32 hash) internal pure returns (bytes32) {\n // 32 is the length in bytes of hash,\n // enforced by the type signature above\n return keccak256(abi.encodePacked(\"\\x19Ethereum Signed Message:\\n32\", hash));\n }\n\n /**\n * @dev Returns an Ethereum Signed Message, created from `s`. This\n * produces hash corresponding to the one signed with the\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\n * JSON-RPC method as part of EIP-191.\n *\n * See {recover}.\n */\n function toEthSignedMessageHash(bytes memory s) internal pure returns (bytes32) {\n return keccak256(abi.encodePacked(\"\\x19Ethereum Signed Message:\\n\", StringsUpgradeable.toString(s.length), s));\n }\n\n /**\n * @dev Returns an Ethereum Signed Typed Data, created from a\n * `domainSeparator` and a `structHash`. This produces hash corresponding\n * to the one signed with the\n * https://eips.ethereum.org/EIPS/eip-712[`eth_signTypedData`]\n * JSON-RPC method as part of EIP-712.\n *\n * See {recover}.\n */\n function toTypedDataHash(bytes32 domainSeparator, bytes32 structHash) internal pure returns (bytes32) {\n return keccak256(abi.encodePacked(\"\\x19\\x01\", domainSeparator, structHash));\n }\n}\n" + }, + "@openzeppelin/contracts-upgradeable/utils/introspection/ERC165Upgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (utils/introspection/ERC165.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./IERC165Upgradeable.sol\";\nimport \"../../proxy/utils/Initializable.sol\";\n\n/**\n * @dev Implementation of the {IERC165} interface.\n *\n * Contracts that want to implement ERC165 should inherit from this contract and override {supportsInterface} to check\n * for the additional interface id that will be supported. For example:\n *\n * ```solidity\n * function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {\n * return interfaceId == type(MyInterface).interfaceId || super.supportsInterface(interfaceId);\n * }\n * ```\n *\n * Alternatively, {ERC165Storage} provides an easier to use but more expensive implementation.\n */\nabstract contract ERC165Upgradeable is Initializable, IERC165Upgradeable {\n function __ERC165_init() internal onlyInitializing {\n }\n\n function __ERC165_init_unchained() internal onlyInitializing {\n }\n /**\n * @dev See {IERC165-supportsInterface}.\n */\n function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {\n return interfaceId == type(IERC165Upgradeable).interfaceId;\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[50] private __gap;\n}\n" + }, + "@openzeppelin/contracts-upgradeable/utils/introspection/IERC165Upgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (utils/introspection/IERC165.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Interface of the ERC165 standard, as defined in the\n * https://eips.ethereum.org/EIPS/eip-165[EIP].\n *\n * Implementers can declare support of contract interfaces, which can then be\n * queried by others ({ERC165Checker}).\n *\n * For an implementation, see {ERC165}.\n */\ninterface IERC165Upgradeable {\n /**\n * @dev Returns true if this contract implements the interface defined by\n * `interfaceId`. See the corresponding\n * https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified[EIP section]\n * to learn more about how these ids are created.\n *\n * This function call must use less than 30 000 gas.\n */\n function supportsInterface(bytes4 interfaceId) external view returns (bool);\n}\n" + }, + "@openzeppelin/contracts-upgradeable/utils/StringsUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (utils/Strings.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev String operations.\n */\nlibrary StringsUpgradeable {\n bytes16 private constant _HEX_SYMBOLS = \"0123456789abcdef\";\n uint8 private constant _ADDRESS_LENGTH = 20;\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` decimal representation.\n */\n function toString(uint256 value) internal pure returns (string memory) {\n // Inspired by OraclizeAPI's implementation - MIT licence\n // https://github.com/oraclize/ethereum-api/blob/b42146b063c7d6ee1358846c198246239e9360e8/oraclizeAPI_0.4.25.sol\n\n if (value == 0) {\n return \"0\";\n }\n uint256 temp = value;\n uint256 digits;\n while (temp != 0) {\n digits++;\n temp /= 10;\n }\n bytes memory buffer = new bytes(digits);\n while (value != 0) {\n digits -= 1;\n buffer[digits] = bytes1(uint8(48 + uint256(value % 10)));\n value /= 10;\n }\n return string(buffer);\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation.\n */\n function toHexString(uint256 value) internal pure returns (string memory) {\n if (value == 0) {\n return \"0x00\";\n }\n uint256 temp = value;\n uint256 length = 0;\n while (temp != 0) {\n length++;\n temp >>= 8;\n }\n return toHexString(value, length);\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length.\n */\n function toHexString(uint256 value, uint256 length) internal pure returns (string memory) {\n bytes memory buffer = new bytes(2 * length + 2);\n buffer[0] = \"0\";\n buffer[1] = \"x\";\n for (uint256 i = 2 * length + 1; i > 1; --i) {\n buffer[i] = _HEX_SYMBOLS[value & 0xf];\n value >>= 4;\n }\n require(value == 0, \"Strings: hex length insufficient\");\n return string(buffer);\n }\n\n /**\n * @dev Converts an `address` with fixed length of 20 bytes to its not checksummed ASCII `string` hexadecimal representation.\n */\n function toHexString(address addr) internal pure returns (string memory) {\n return toHexString(uint256(uint160(addr)), _ADDRESS_LENGTH);\n }\n}\n" + }, + "@openzeppelin/contracts-upgradeable/utils/structs/EnumerableSetUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (utils/structs/EnumerableSet.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Library for managing\n * https://en.wikipedia.org/wiki/Set_(abstract_data_type)[sets] of primitive\n * types.\n *\n * Sets have the following properties:\n *\n * - Elements are added, removed, and checked for existence in constant time\n * (O(1)).\n * - Elements are enumerated in O(n). No guarantees are made on the ordering.\n *\n * ```\n * contract Example {\n * // Add the library methods\n * using EnumerableSet for EnumerableSet.AddressSet;\n *\n * // Declare a set state variable\n * EnumerableSet.AddressSet private mySet;\n * }\n * ```\n *\n * As of v3.3.0, sets of type `bytes32` (`Bytes32Set`), `address` (`AddressSet`)\n * and `uint256` (`UintSet`) are supported.\n *\n * [WARNING]\n * ====\n * Trying to delete such a structure from storage will likely result in data corruption, rendering the structure unusable.\n * See https://github.com/ethereum/solidity/pull/11843[ethereum/solidity#11843] for more info.\n *\n * In order to clean an EnumerableSet, you can either remove all elements one by one or create a fresh instance using an array of EnumerableSet.\n * ====\n */\nlibrary EnumerableSetUpgradeable {\n // To implement this library for multiple types with as little code\n // repetition as possible, we write it in terms of a generic Set type with\n // bytes32 values.\n // The Set implementation uses private functions, and user-facing\n // implementations (such as AddressSet) are just wrappers around the\n // underlying Set.\n // This means that we can only create new EnumerableSets for types that fit\n // in bytes32.\n\n struct Set {\n // Storage of set values\n bytes32[] _values;\n // Position of the value in the `values` array, plus 1 because index 0\n // means a value is not in the set.\n mapping(bytes32 => uint256) _indexes;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function _add(Set storage set, bytes32 value) private returns (bool) {\n if (!_contains(set, value)) {\n set._values.push(value);\n // The value is stored at length-1, but we add 1 to all indexes\n // and use 0 as a sentinel value\n set._indexes[value] = set._values.length;\n return true;\n } else {\n return false;\n }\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function _remove(Set storage set, bytes32 value) private returns (bool) {\n // We read and store the value's index to prevent multiple reads from the same storage slot\n uint256 valueIndex = set._indexes[value];\n\n if (valueIndex != 0) {\n // Equivalent to contains(set, value)\n // To delete an element from the _values array in O(1), we swap the element to delete with the last one in\n // the array, and then remove the last element (sometimes called as 'swap and pop').\n // This modifies the order of the array, as noted in {at}.\n\n uint256 toDeleteIndex = valueIndex - 1;\n uint256 lastIndex = set._values.length - 1;\n\n if (lastIndex != toDeleteIndex) {\n bytes32 lastValue = set._values[lastIndex];\n\n // Move the last value to the index where the value to delete is\n set._values[toDeleteIndex] = lastValue;\n // Update the index for the moved value\n set._indexes[lastValue] = valueIndex; // Replace lastValue's index to valueIndex\n }\n\n // Delete the slot where the moved value was stored\n set._values.pop();\n\n // Delete the index for the deleted slot\n delete set._indexes[value];\n\n return true;\n } else {\n return false;\n }\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function _contains(Set storage set, bytes32 value) private view returns (bool) {\n return set._indexes[value] != 0;\n }\n\n /**\n * @dev Returns the number of values on the set. O(1).\n */\n function _length(Set storage set) private view returns (uint256) {\n return set._values.length;\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function _at(Set storage set, uint256 index) private view returns (bytes32) {\n return set._values[index];\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function _values(Set storage set) private view returns (bytes32[] memory) {\n return set._values;\n }\n\n // Bytes32Set\n\n struct Bytes32Set {\n Set _inner;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function add(Bytes32Set storage set, bytes32 value) internal returns (bool) {\n return _add(set._inner, value);\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function remove(Bytes32Set storage set, bytes32 value) internal returns (bool) {\n return _remove(set._inner, value);\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function contains(Bytes32Set storage set, bytes32 value) internal view returns (bool) {\n return _contains(set._inner, value);\n }\n\n /**\n * @dev Returns the number of values in the set. O(1).\n */\n function length(Bytes32Set storage set) internal view returns (uint256) {\n return _length(set._inner);\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function at(Bytes32Set storage set, uint256 index) internal view returns (bytes32) {\n return _at(set._inner, index);\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function values(Bytes32Set storage set) internal view returns (bytes32[] memory) {\n return _values(set._inner);\n }\n\n // AddressSet\n\n struct AddressSet {\n Set _inner;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function add(AddressSet storage set, address value) internal returns (bool) {\n return _add(set._inner, bytes32(uint256(uint160(value))));\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function remove(AddressSet storage set, address value) internal returns (bool) {\n return _remove(set._inner, bytes32(uint256(uint160(value))));\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function contains(AddressSet storage set, address value) internal view returns (bool) {\n return _contains(set._inner, bytes32(uint256(uint160(value))));\n }\n\n /**\n * @dev Returns the number of values in the set. O(1).\n */\n function length(AddressSet storage set) internal view returns (uint256) {\n return _length(set._inner);\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function at(AddressSet storage set, uint256 index) internal view returns (address) {\n return address(uint160(uint256(_at(set._inner, index))));\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function values(AddressSet storage set) internal view returns (address[] memory) {\n bytes32[] memory store = _values(set._inner);\n address[] memory result;\n\n /// @solidity memory-safe-assembly\n assembly {\n result := store\n }\n\n return result;\n }\n\n // UintSet\n\n struct UintSet {\n Set _inner;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function add(UintSet storage set, uint256 value) internal returns (bool) {\n return _add(set._inner, bytes32(value));\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function remove(UintSet storage set, uint256 value) internal returns (bool) {\n return _remove(set._inner, bytes32(value));\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function contains(UintSet storage set, uint256 value) internal view returns (bool) {\n return _contains(set._inner, bytes32(value));\n }\n\n /**\n * @dev Returns the number of values on the set. O(1).\n */\n function length(UintSet storage set) internal view returns (uint256) {\n return _length(set._inner);\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function at(UintSet storage set, uint256 index) internal view returns (uint256) {\n return uint256(_at(set._inner, index));\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function values(UintSet storage set) internal view returns (uint256[] memory) {\n bytes32[] memory store = _values(set._inner);\n uint256[] memory result;\n\n /// @solidity memory-safe-assembly\n assembly {\n result := store\n }\n\n return result;\n }\n}\n" + }, + "@openzeppelin/contracts/access/Ownable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (access/Ownable.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../utils/Context.sol\";\n\n/**\n * @dev Contract module which provides a basic access control mechanism, where\n * there is an account (an owner) that can be granted exclusive access to\n * specific functions.\n *\n * By default, the owner account will be the one that deploys the contract. This\n * can later be changed with {transferOwnership}.\n *\n * This module is used through inheritance. It will make available the modifier\n * `onlyOwner`, which can be applied to your functions to restrict their use to\n * the owner.\n */\nabstract contract Ownable is Context {\n address private _owner;\n\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\n\n /**\n * @dev Initializes the contract setting the deployer as the initial owner.\n */\n constructor() {\n _transferOwnership(_msgSender());\n }\n\n /**\n * @dev Throws if called by any account other than the owner.\n */\n modifier onlyOwner() {\n _checkOwner();\n _;\n }\n\n /**\n * @dev Returns the address of the current owner.\n */\n function owner() public view virtual returns (address) {\n return _owner;\n }\n\n /**\n * @dev Throws if the sender is not the owner.\n */\n function _checkOwner() internal view virtual {\n require(owner() == _msgSender(), \"Ownable: caller is not the owner\");\n }\n\n /**\n * @dev Leaves the contract without owner. It will not be possible to call\n * `onlyOwner` functions anymore. Can only be called by the current owner.\n *\n * NOTE: Renouncing ownership will leave the contract without an owner,\n * thereby removing any functionality that is only available to the owner.\n */\n function renounceOwnership() public virtual onlyOwner {\n _transferOwnership(address(0));\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Can only be called by the current owner.\n */\n function transferOwnership(address newOwner) public virtual onlyOwner {\n require(newOwner != address(0), \"Ownable: new owner is the zero address\");\n _transferOwnership(newOwner);\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Internal function without access restriction.\n */\n function _transferOwnership(address newOwner) internal virtual {\n address oldOwner = _owner;\n _owner = newOwner;\n emit OwnershipTransferred(oldOwner, newOwner);\n }\n}\n" + }, + "@openzeppelin/contracts/interfaces/draft-IERC1822.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.5.0) (interfaces/draft-IERC1822.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev ERC1822: Universal Upgradeable Proxy Standard (UUPS) documents a method for upgradeability through a simplified\n * proxy whose upgrades are fully controlled by the current implementation.\n */\ninterface IERC1822Proxiable {\n /**\n * @dev Returns the storage slot that the proxiable contract assumes is being used to store the implementation\n * address.\n *\n * IMPORTANT: A proxy pointing at a proxiable contract should not be considered proxiable itself, because this risks\n * bricking a proxy that upgrades to it, by delegating to itself until out of gas. Thus it is critical that this\n * function revert if invoked through a proxy.\n */\n function proxiableUUID() external view returns (bytes32);\n}\n" + }, + "@openzeppelin/contracts/interfaces/IERC3156FlashBorrower.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (interfaces/IERC3156FlashBorrower.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Interface of the ERC3156 FlashBorrower, as defined in\n * https://eips.ethereum.org/EIPS/eip-3156[ERC-3156].\n *\n * _Available since v4.1._\n */\ninterface IERC3156FlashBorrower {\n /**\n * @dev Receive a flash loan.\n * @param initiator The initiator of the loan.\n * @param token The loan currency.\n * @param amount The amount of tokens lent.\n * @param fee The additional amount of tokens to repay.\n * @param data Arbitrary data structure, intended to contain user-defined parameters.\n * @return The keccak256 hash of \"IERC3156FlashBorrower.onFlashLoan\"\n */\n function onFlashLoan(\n address initiator,\n address token,\n uint256 amount,\n uint256 fee,\n bytes calldata data\n ) external returns (bytes32);\n}\n" + }, + "@openzeppelin/contracts/interfaces/IERC3156FlashLender.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (interfaces/IERC3156FlashLender.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./IERC3156FlashBorrower.sol\";\n\n/**\n * @dev Interface of the ERC3156 FlashLender, as defined in\n * https://eips.ethereum.org/EIPS/eip-3156[ERC-3156].\n *\n * _Available since v4.1._\n */\ninterface IERC3156FlashLender {\n /**\n * @dev The amount of currency available to be lended.\n * @param token The loan currency.\n * @return The amount of `token` that can be borrowed.\n */\n function maxFlashLoan(address token) external view returns (uint256);\n\n /**\n * @dev The fee to be charged for a given loan.\n * @param token The loan currency.\n * @param amount The amount of tokens lent.\n * @return The amount of `token` to be charged for the loan, on top of the returned principal.\n */\n function flashFee(address token, uint256 amount) external view returns (uint256);\n\n /**\n * @dev Initiate a flash loan.\n * @param receiver The receiver of the tokens in the loan, and the receiver of the callback.\n * @param token The loan currency.\n * @param amount The amount of tokens lent.\n * @param data Arbitrary data structure, intended to contain user-defined parameters.\n */\n function flashLoan(\n IERC3156FlashBorrower receiver,\n address token,\n uint256 amount,\n bytes calldata data\n ) external returns (bool);\n}\n" + }, + "@openzeppelin/contracts/interfaces/IERC721Metadata.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (interfaces/IERC721Metadata.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../token/ERC721/extensions/IERC721Metadata.sol\";\n" + }, + "@openzeppelin/contracts/proxy/beacon/IBeacon.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (proxy/beacon/IBeacon.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev This is the interface that {BeaconProxy} expects of its beacon.\n */\ninterface IBeacon {\n /**\n * @dev Must return an address that can be used as a delegate call target.\n *\n * {BeaconProxy} will check that this address is a contract.\n */\n function implementation() external view returns (address);\n}\n" + }, + "@openzeppelin/contracts/proxy/ERC1967/ERC1967Proxy.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (proxy/ERC1967/ERC1967Proxy.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../Proxy.sol\";\nimport \"./ERC1967Upgrade.sol\";\n\n/**\n * @dev This contract implements an upgradeable proxy. It is upgradeable because calls are delegated to an\n * implementation address that can be changed. This address is stored in storage in the location specified by\n * https://eips.ethereum.org/EIPS/eip-1967[EIP1967], so that it doesn't conflict with the storage layout of the\n * implementation behind the proxy.\n */\ncontract ERC1967Proxy is Proxy, ERC1967Upgrade {\n /**\n * @dev Initializes the upgradeable proxy with an initial implementation specified by `_logic`.\n *\n * If `_data` is nonempty, it's used as data in a delegate call to `_logic`. This will typically be an encoded\n * function call, and allows initializing the storage of the proxy like a Solidity constructor.\n */\n constructor(address _logic, bytes memory _data) payable {\n _upgradeToAndCall(_logic, _data, false);\n }\n\n /**\n * @dev Returns the current implementation address.\n */\n function _implementation() internal view virtual override returns (address impl) {\n return ERC1967Upgrade._getImplementation();\n }\n}\n" + }, + "@openzeppelin/contracts/proxy/ERC1967/ERC1967Upgrade.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.5.0) (proxy/ERC1967/ERC1967Upgrade.sol)\n\npragma solidity ^0.8.2;\n\nimport \"../beacon/IBeacon.sol\";\nimport \"../../interfaces/draft-IERC1822.sol\";\nimport \"../../utils/Address.sol\";\nimport \"../../utils/StorageSlot.sol\";\n\n/**\n * @dev This abstract contract provides getters and event emitting update functions for\n * https://eips.ethereum.org/EIPS/eip-1967[EIP1967] slots.\n *\n * _Available since v4.1._\n *\n * @custom:oz-upgrades-unsafe-allow delegatecall\n */\nabstract contract ERC1967Upgrade {\n // This is the keccak-256 hash of \"eip1967.proxy.rollback\" subtracted by 1\n bytes32 private constant _ROLLBACK_SLOT = 0x4910fdfa16fed3260ed0e7147f7cc6da11a60208b5b9406d12a635614ffd9143;\n\n /**\n * @dev Storage slot with the address of the current implementation.\n * This is the keccak-256 hash of \"eip1967.proxy.implementation\" subtracted by 1, and is\n * validated in the constructor.\n */\n bytes32 internal constant _IMPLEMENTATION_SLOT = 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc;\n\n /**\n * @dev Emitted when the implementation is upgraded.\n */\n event Upgraded(address indexed implementation);\n\n /**\n * @dev Returns the current implementation address.\n */\n function _getImplementation() internal view returns (address) {\n return StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value;\n }\n\n /**\n * @dev Stores a new address in the EIP1967 implementation slot.\n */\n function _setImplementation(address newImplementation) private {\n require(Address.isContract(newImplementation), \"ERC1967: new implementation is not a contract\");\n StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value = newImplementation;\n }\n\n /**\n * @dev Perform implementation upgrade\n *\n * Emits an {Upgraded} event.\n */\n function _upgradeTo(address newImplementation) internal {\n _setImplementation(newImplementation);\n emit Upgraded(newImplementation);\n }\n\n /**\n * @dev Perform implementation upgrade with additional setup call.\n *\n * Emits an {Upgraded} event.\n */\n function _upgradeToAndCall(\n address newImplementation,\n bytes memory data,\n bool forceCall\n ) internal {\n _upgradeTo(newImplementation);\n if (data.length > 0 || forceCall) {\n Address.functionDelegateCall(newImplementation, data);\n }\n }\n\n /**\n * @dev Perform implementation upgrade with security checks for UUPS proxies, and additional setup call.\n *\n * Emits an {Upgraded} event.\n */\n function _upgradeToAndCallUUPS(\n address newImplementation,\n bytes memory data,\n bool forceCall\n ) internal {\n // Upgrades from old implementations will perform a rollback test. This test requires the new\n // implementation to upgrade back to the old, non-ERC1822 compliant, implementation. Removing\n // this special case will break upgrade paths from old UUPS implementation to new ones.\n if (StorageSlot.getBooleanSlot(_ROLLBACK_SLOT).value) {\n _setImplementation(newImplementation);\n } else {\n try IERC1822Proxiable(newImplementation).proxiableUUID() returns (bytes32 slot) {\n require(slot == _IMPLEMENTATION_SLOT, \"ERC1967Upgrade: unsupported proxiableUUID\");\n } catch {\n revert(\"ERC1967Upgrade: new implementation is not UUPS\");\n }\n _upgradeToAndCall(newImplementation, data, forceCall);\n }\n }\n\n /**\n * @dev Storage slot with the admin of the contract.\n * This is the keccak-256 hash of \"eip1967.proxy.admin\" subtracted by 1, and is\n * validated in the constructor.\n */\n bytes32 internal constant _ADMIN_SLOT = 0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103;\n\n /**\n * @dev Emitted when the admin account has changed.\n */\n event AdminChanged(address previousAdmin, address newAdmin);\n\n /**\n * @dev Returns the current admin.\n */\n function _getAdmin() internal view returns (address) {\n return StorageSlot.getAddressSlot(_ADMIN_SLOT).value;\n }\n\n /**\n * @dev Stores a new address in the EIP1967 admin slot.\n */\n function _setAdmin(address newAdmin) private {\n require(newAdmin != address(0), \"ERC1967: new admin is the zero address\");\n StorageSlot.getAddressSlot(_ADMIN_SLOT).value = newAdmin;\n }\n\n /**\n * @dev Changes the admin of the proxy.\n *\n * Emits an {AdminChanged} event.\n */\n function _changeAdmin(address newAdmin) internal {\n emit AdminChanged(_getAdmin(), newAdmin);\n _setAdmin(newAdmin);\n }\n\n /**\n * @dev The storage slot of the UpgradeableBeacon contract which defines the implementation for this proxy.\n * This is bytes32(uint256(keccak256('eip1967.proxy.beacon')) - 1)) and is validated in the constructor.\n */\n bytes32 internal constant _BEACON_SLOT = 0xa3f0ad74e5423aebfd80d3ef4346578335a9a72aeaee59ff6cb3582b35133d50;\n\n /**\n * @dev Emitted when the beacon is upgraded.\n */\n event BeaconUpgraded(address indexed beacon);\n\n /**\n * @dev Returns the current beacon.\n */\n function _getBeacon() internal view returns (address) {\n return StorageSlot.getAddressSlot(_BEACON_SLOT).value;\n }\n\n /**\n * @dev Stores a new beacon in the EIP1967 beacon slot.\n */\n function _setBeacon(address newBeacon) private {\n require(Address.isContract(newBeacon), \"ERC1967: new beacon is not a contract\");\n require(\n Address.isContract(IBeacon(newBeacon).implementation()),\n \"ERC1967: beacon implementation is not a contract\"\n );\n StorageSlot.getAddressSlot(_BEACON_SLOT).value = newBeacon;\n }\n\n /**\n * @dev Perform beacon upgrade with additional setup call. Note: This upgrades the address of the beacon, it does\n * not upgrade the implementation contained in the beacon (see {UpgradeableBeacon-_setImplementation} for that).\n *\n * Emits a {BeaconUpgraded} event.\n */\n function _upgradeBeaconToAndCall(\n address newBeacon,\n bytes memory data,\n bool forceCall\n ) internal {\n _setBeacon(newBeacon);\n emit BeaconUpgraded(newBeacon);\n if (data.length > 0 || forceCall) {\n Address.functionDelegateCall(IBeacon(newBeacon).implementation(), data);\n }\n }\n}\n" + }, + "@openzeppelin/contracts/proxy/Proxy.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.6.0) (proxy/Proxy.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev This abstract contract provides a fallback function that delegates all calls to another contract using the EVM\n * instruction `delegatecall`. We refer to the second contract as the _implementation_ behind the proxy, and it has to\n * be specified by overriding the virtual {_implementation} function.\n *\n * Additionally, delegation to the implementation can be triggered manually through the {_fallback} function, or to a\n * different contract through the {_delegate} function.\n *\n * The success and return data of the delegated call will be returned back to the caller of the proxy.\n */\nabstract contract Proxy {\n /**\n * @dev Delegates the current call to `implementation`.\n *\n * This function does not return to its internal call site, it will return directly to the external caller.\n */\n function _delegate(address implementation) internal virtual {\n assembly {\n // Copy msg.data. We take full control of memory in this inline assembly\n // block because it will not return to Solidity code. We overwrite the\n // Solidity scratch pad at memory position 0.\n calldatacopy(0, 0, calldatasize())\n\n // Call the implementation.\n // out and outsize are 0 because we don't know the size yet.\n let result := delegatecall(gas(), implementation, 0, calldatasize(), 0, 0)\n\n // Copy the returned data.\n returndatacopy(0, 0, returndatasize())\n\n switch result\n // delegatecall returns 0 on error.\n case 0 {\n revert(0, returndatasize())\n }\n default {\n return(0, returndatasize())\n }\n }\n }\n\n /**\n * @dev This is a virtual function that should be overridden so it returns the address to which the fallback function\n * and {_fallback} should delegate.\n */\n function _implementation() internal view virtual returns (address);\n\n /**\n * @dev Delegates the current call to the address returned by `_implementation()`.\n *\n * This function does not return to its internal call site, it will return directly to the external caller.\n */\n function _fallback() internal virtual {\n _beforeFallback();\n _delegate(_implementation());\n }\n\n /**\n * @dev Fallback function that delegates calls to the address returned by `_implementation()`. Will run if no other\n * function in the contract matches the call data.\n */\n fallback() external payable virtual {\n _fallback();\n }\n\n /**\n * @dev Fallback function that delegates calls to the address returned by `_implementation()`. Will run if call data\n * is empty.\n */\n receive() external payable virtual {\n _fallback();\n }\n\n /**\n * @dev Hook that is called before falling back to the implementation. Can happen as part of a manual `_fallback`\n * call, or as part of the Solidity `fallback` or `receive` functions.\n *\n * If overridden should call `super._beforeFallback()`.\n */\n function _beforeFallback() internal virtual {}\n}\n" + }, + "@openzeppelin/contracts/token/ERC20/ERC20.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (token/ERC20/ERC20.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./IERC20.sol\";\nimport \"./extensions/IERC20Metadata.sol\";\nimport \"../../utils/Context.sol\";\n\n/**\n * @dev Implementation of the {IERC20} interface.\n *\n * This implementation is agnostic to the way tokens are created. This means\n * that a supply mechanism has to be added in a derived contract using {_mint}.\n * For a generic mechanism see {ERC20PresetMinterPauser}.\n *\n * TIP: For a detailed writeup see our guide\n * https://forum.zeppelin.solutions/t/how-to-implement-erc20-supply-mechanisms/226[How\n * to implement supply mechanisms].\n *\n * We have followed general OpenZeppelin Contracts guidelines: functions revert\n * instead returning `false` on failure. This behavior is nonetheless\n * conventional and does not conflict with the expectations of ERC20\n * applications.\n *\n * Additionally, an {Approval} event is emitted on calls to {transferFrom}.\n * This allows applications to reconstruct the allowance for all accounts just\n * by listening to said events. Other implementations of the EIP may not emit\n * these events, as it isn't required by the specification.\n *\n * Finally, the non-standard {decreaseAllowance} and {increaseAllowance}\n * functions have been added to mitigate the well-known issues around setting\n * allowances. See {IERC20-approve}.\n */\ncontract ERC20 is Context, IERC20, IERC20Metadata {\n mapping(address => uint256) private _balances;\n\n mapping(address => mapping(address => uint256)) private _allowances;\n\n uint256 private _totalSupply;\n\n string private _name;\n string private _symbol;\n\n /**\n * @dev Sets the values for {name} and {symbol}.\n *\n * The default value of {decimals} is 18. To select a different value for\n * {decimals} you should overload it.\n *\n * All two of these values are immutable: they can only be set once during\n * construction.\n */\n constructor(string memory name_, string memory symbol_) {\n _name = name_;\n _symbol = symbol_;\n }\n\n /**\n * @dev Returns the name of the token.\n */\n function name() public view virtual override returns (string memory) {\n return _name;\n }\n\n /**\n * @dev Returns the symbol of the token, usually a shorter version of the\n * name.\n */\n function symbol() public view virtual override returns (string memory) {\n return _symbol;\n }\n\n /**\n * @dev Returns the number of decimals used to get its user representation.\n * For example, if `decimals` equals `2`, a balance of `505` tokens should\n * be displayed to a user as `5.05` (`505 / 10 ** 2`).\n *\n * Tokens usually opt for a value of 18, imitating the relationship between\n * Ether and Wei. This is the value {ERC20} uses, unless this function is\n * overridden;\n *\n * NOTE: This information is only used for _display_ purposes: it in\n * no way affects any of the arithmetic of the contract, including\n * {IERC20-balanceOf} and {IERC20-transfer}.\n */\n function decimals() public view virtual override returns (uint8) {\n return 18;\n }\n\n /**\n * @dev See {IERC20-totalSupply}.\n */\n function totalSupply() public view virtual override returns (uint256) {\n return _totalSupply;\n }\n\n /**\n * @dev See {IERC20-balanceOf}.\n */\n function balanceOf(address account) public view virtual override returns (uint256) {\n return _balances[account];\n }\n\n /**\n * @dev See {IERC20-transfer}.\n *\n * Requirements:\n *\n * - `to` cannot be the zero address.\n * - the caller must have a balance of at least `amount`.\n */\n function transfer(address to, uint256 amount) public virtual override returns (bool) {\n address owner = _msgSender();\n _transfer(owner, to, amount);\n return true;\n }\n\n /**\n * @dev See {IERC20-allowance}.\n */\n function allowance(address owner, address spender) public view virtual override returns (uint256) {\n return _allowances[owner][spender];\n }\n\n /**\n * @dev See {IERC20-approve}.\n *\n * NOTE: If `amount` is the maximum `uint256`, the allowance is not updated on\n * `transferFrom`. This is semantically equivalent to an infinite approval.\n *\n * Requirements:\n *\n * - `spender` cannot be the zero address.\n */\n function approve(address spender, uint256 amount) public virtual override returns (bool) {\n address owner = _msgSender();\n _approve(owner, spender, amount);\n return true;\n }\n\n /**\n * @dev See {IERC20-transferFrom}.\n *\n * Emits an {Approval} event indicating the updated allowance. This is not\n * required by the EIP. See the note at the beginning of {ERC20}.\n *\n * NOTE: Does not update the allowance if the current allowance\n * is the maximum `uint256`.\n *\n * Requirements:\n *\n * - `from` and `to` cannot be the zero address.\n * - `from` must have a balance of at least `amount`.\n * - the caller must have allowance for ``from``'s tokens of at least\n * `amount`.\n */\n function transferFrom(\n address from,\n address to,\n uint256 amount\n ) public virtual override returns (bool) {\n address spender = _msgSender();\n _spendAllowance(from, spender, amount);\n _transfer(from, to, amount);\n return true;\n }\n\n /**\n * @dev Atomically increases the allowance granted to `spender` by the caller.\n *\n * This is an alternative to {approve} that can be used as a mitigation for\n * problems described in {IERC20-approve}.\n *\n * Emits an {Approval} event indicating the updated allowance.\n *\n * Requirements:\n *\n * - `spender` cannot be the zero address.\n */\n function increaseAllowance(address spender, uint256 addedValue) public virtual returns (bool) {\n address owner = _msgSender();\n _approve(owner, spender, allowance(owner, spender) + addedValue);\n return true;\n }\n\n /**\n * @dev Atomically decreases the allowance granted to `spender` by the caller.\n *\n * This is an alternative to {approve} that can be used as a mitigation for\n * problems described in {IERC20-approve}.\n *\n * Emits an {Approval} event indicating the updated allowance.\n *\n * Requirements:\n *\n * - `spender` cannot be the zero address.\n * - `spender` must have allowance for the caller of at least\n * `subtractedValue`.\n */\n function decreaseAllowance(address spender, uint256 subtractedValue) public virtual returns (bool) {\n address owner = _msgSender();\n uint256 currentAllowance = allowance(owner, spender);\n require(currentAllowance >= subtractedValue, \"ERC20: decreased allowance below zero\");\n unchecked {\n _approve(owner, spender, currentAllowance - subtractedValue);\n }\n\n return true;\n }\n\n /**\n * @dev Moves `amount` of tokens from `from` to `to`.\n *\n * This internal function is equivalent to {transfer}, and can be used to\n * e.g. implement automatic token fees, slashing mechanisms, etc.\n *\n * Emits a {Transfer} event.\n *\n * Requirements:\n *\n * - `from` cannot be the zero address.\n * - `to` cannot be the zero address.\n * - `from` must have a balance of at least `amount`.\n */\n function _transfer(\n address from,\n address to,\n uint256 amount\n ) internal virtual {\n require(from != address(0), \"ERC20: transfer from the zero address\");\n require(to != address(0), \"ERC20: transfer to the zero address\");\n\n _beforeTokenTransfer(from, to, amount);\n\n uint256 fromBalance = _balances[from];\n require(fromBalance >= amount, \"ERC20: transfer amount exceeds balance\");\n unchecked {\n _balances[from] = fromBalance - amount;\n }\n _balances[to] += amount;\n\n emit Transfer(from, to, amount);\n\n _afterTokenTransfer(from, to, amount);\n }\n\n /** @dev Creates `amount` tokens and assigns them to `account`, increasing\n * the total supply.\n *\n * Emits a {Transfer} event with `from` set to the zero address.\n *\n * Requirements:\n *\n * - `account` cannot be the zero address.\n */\n function _mint(address account, uint256 amount) internal virtual {\n require(account != address(0), \"ERC20: mint to the zero address\");\n\n _beforeTokenTransfer(address(0), account, amount);\n\n _totalSupply += amount;\n _balances[account] += amount;\n emit Transfer(address(0), account, amount);\n\n _afterTokenTransfer(address(0), account, amount);\n }\n\n /**\n * @dev Destroys `amount` tokens from `account`, reducing the\n * total supply.\n *\n * Emits a {Transfer} event with `to` set to the zero address.\n *\n * Requirements:\n *\n * - `account` cannot be the zero address.\n * - `account` must have at least `amount` tokens.\n */\n function _burn(address account, uint256 amount) internal virtual {\n require(account != address(0), \"ERC20: burn from the zero address\");\n\n _beforeTokenTransfer(account, address(0), amount);\n\n uint256 accountBalance = _balances[account];\n require(accountBalance >= amount, \"ERC20: burn amount exceeds balance\");\n unchecked {\n _balances[account] = accountBalance - amount;\n }\n _totalSupply -= amount;\n\n emit Transfer(account, address(0), amount);\n\n _afterTokenTransfer(account, address(0), amount);\n }\n\n /**\n * @dev Sets `amount` as the allowance of `spender` over the `owner` s tokens.\n *\n * This internal function is equivalent to `approve`, and can be used to\n * e.g. set automatic allowances for certain subsystems, etc.\n *\n * Emits an {Approval} event.\n *\n * Requirements:\n *\n * - `owner` cannot be the zero address.\n * - `spender` cannot be the zero address.\n */\n function _approve(\n address owner,\n address spender,\n uint256 amount\n ) internal virtual {\n require(owner != address(0), \"ERC20: approve from the zero address\");\n require(spender != address(0), \"ERC20: approve to the zero address\");\n\n _allowances[owner][spender] = amount;\n emit Approval(owner, spender, amount);\n }\n\n /**\n * @dev Updates `owner` s allowance for `spender` based on spent `amount`.\n *\n * Does not update the allowance amount in case of infinite allowance.\n * Revert if not enough allowance is available.\n *\n * Might emit an {Approval} event.\n */\n function _spendAllowance(\n address owner,\n address spender,\n uint256 amount\n ) internal virtual {\n uint256 currentAllowance = allowance(owner, spender);\n if (currentAllowance != type(uint256).max) {\n require(currentAllowance >= amount, \"ERC20: insufficient allowance\");\n unchecked {\n _approve(owner, spender, currentAllowance - amount);\n }\n }\n }\n\n /**\n * @dev Hook that is called before any transfer of tokens. This includes\n * minting and burning.\n *\n * Calling conditions:\n *\n * - when `from` and `to` are both non-zero, `amount` of ``from``'s tokens\n * will be transferred to `to`.\n * - when `from` is zero, `amount` tokens will be minted for `to`.\n * - when `to` is zero, `amount` of ``from``'s tokens will be burned.\n * - `from` and `to` are never both zero.\n *\n * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].\n */\n function _beforeTokenTransfer(\n address from,\n address to,\n uint256 amount\n ) internal virtual {}\n\n /**\n * @dev Hook that is called after any transfer of tokens. This includes\n * minting and burning.\n *\n * Calling conditions:\n *\n * - when `from` and `to` are both non-zero, `amount` of ``from``'s tokens\n * has been transferred to `to`.\n * - when `from` is zero, `amount` tokens have been minted for `to`.\n * - when `to` is zero, `amount` of ``from``'s tokens have been burned.\n * - `from` and `to` are never both zero.\n *\n * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].\n */\n function _afterTokenTransfer(\n address from,\n address to,\n uint256 amount\n ) internal virtual {}\n}\n" + }, + "@openzeppelin/contracts/token/ERC20/extensions/draft-ERC20Permit.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.6.0) (token/ERC20/extensions/draft-ERC20Permit.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./draft-IERC20Permit.sol\";\nimport \"../ERC20.sol\";\nimport \"../../../utils/cryptography/draft-EIP712.sol\";\nimport \"../../../utils/cryptography/ECDSA.sol\";\nimport \"../../../utils/Counters.sol\";\n\n/**\n * @dev Implementation of the ERC20 Permit extension allowing approvals to be made via signatures, as defined in\n * https://eips.ethereum.org/EIPS/eip-2612[EIP-2612].\n *\n * Adds the {permit} method, which can be used to change an account's ERC20 allowance (see {IERC20-allowance}) by\n * presenting a message signed by the account. By not relying on `{IERC20-approve}`, the token holder account doesn't\n * need to send a transaction, and thus is not required to hold Ether at all.\n *\n * _Available since v3.4._\n */\nabstract contract ERC20Permit is ERC20, IERC20Permit, EIP712 {\n using Counters for Counters.Counter;\n\n mapping(address => Counters.Counter) private _nonces;\n\n // solhint-disable-next-line var-name-mixedcase\n bytes32 private constant _PERMIT_TYPEHASH =\n keccak256(\"Permit(address owner,address spender,uint256 value,uint256 nonce,uint256 deadline)\");\n /**\n * @dev In previous versions `_PERMIT_TYPEHASH` was declared as `immutable`.\n * However, to ensure consistency with the upgradeable transpiler, we will continue\n * to reserve a slot.\n * @custom:oz-renamed-from _PERMIT_TYPEHASH\n */\n // solhint-disable-next-line var-name-mixedcase\n bytes32 private _PERMIT_TYPEHASH_DEPRECATED_SLOT;\n\n /**\n * @dev Initializes the {EIP712} domain separator using the `name` parameter, and setting `version` to `\"1\"`.\n *\n * It's a good idea to use the same `name` that is defined as the ERC20 token name.\n */\n constructor(string memory name) EIP712(name, \"1\") {}\n\n /**\n * @dev See {IERC20Permit-permit}.\n */\n function permit(\n address owner,\n address spender,\n uint256 value,\n uint256 deadline,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) public virtual override {\n require(block.timestamp <= deadline, \"ERC20Permit: expired deadline\");\n\n bytes32 structHash = keccak256(abi.encode(_PERMIT_TYPEHASH, owner, spender, value, _useNonce(owner), deadline));\n\n bytes32 hash = _hashTypedDataV4(structHash);\n\n address signer = ECDSA.recover(hash, v, r, s);\n require(signer == owner, \"ERC20Permit: invalid signature\");\n\n _approve(owner, spender, value);\n }\n\n /**\n * @dev See {IERC20Permit-nonces}.\n */\n function nonces(address owner) public view virtual override returns (uint256) {\n return _nonces[owner].current();\n }\n\n /**\n * @dev See {IERC20Permit-DOMAIN_SEPARATOR}.\n */\n // solhint-disable-next-line func-name-mixedcase\n function DOMAIN_SEPARATOR() external view override returns (bytes32) {\n return _domainSeparatorV4();\n }\n\n /**\n * @dev \"Consume a nonce\": return the current value and increment.\n *\n * _Available since v4.1._\n */\n function _useNonce(address owner) internal virtual returns (uint256 current) {\n Counters.Counter storage nonce = _nonces[owner];\n current = nonce.current();\n nonce.increment();\n }\n}\n" + }, + "@openzeppelin/contracts/token/ERC20/extensions/draft-IERC20Permit.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (token/ERC20/extensions/draft-IERC20Permit.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Interface of the ERC20 Permit extension allowing approvals to be made via signatures, as defined in\n * https://eips.ethereum.org/EIPS/eip-2612[EIP-2612].\n *\n * Adds the {permit} method, which can be used to change an account's ERC20 allowance (see {IERC20-allowance}) by\n * presenting a message signed by the account. By not relying on {IERC20-approve}, the token holder account doesn't\n * need to send a transaction, and thus is not required to hold Ether at all.\n */\ninterface IERC20Permit {\n /**\n * @dev Sets `value` as the allowance of `spender` over ``owner``'s tokens,\n * given ``owner``'s signed approval.\n *\n * IMPORTANT: The same issues {IERC20-approve} has related to transaction\n * ordering also apply here.\n *\n * Emits an {Approval} event.\n *\n * Requirements:\n *\n * - `spender` cannot be the zero address.\n * - `deadline` must be a timestamp in the future.\n * - `v`, `r` and `s` must be a valid `secp256k1` signature from `owner`\n * over the EIP712-formatted function arguments.\n * - the signature must use ``owner``'s current nonce (see {nonces}).\n *\n * For more information on the signature format, see the\n * https://eips.ethereum.org/EIPS/eip-2612#specification[relevant EIP\n * section].\n */\n function permit(\n address owner,\n address spender,\n uint256 value,\n uint256 deadline,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) external;\n\n /**\n * @dev Returns the current nonce for `owner`. This value must be\n * included whenever a signature is generated for {permit}.\n *\n * Every successful call to {permit} increases ``owner``'s nonce by one. This\n * prevents a signature from being used multiple times.\n */\n function nonces(address owner) external view returns (uint256);\n\n /**\n * @dev Returns the domain separator used in the encoding of the signature for {permit}, as defined by {EIP712}.\n */\n // solhint-disable-next-line func-name-mixedcase\n function DOMAIN_SEPARATOR() external view returns (bytes32);\n}\n" + }, + "@openzeppelin/contracts/token/ERC20/extensions/IERC20Metadata.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (token/ERC20/extensions/IERC20Metadata.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../IERC20.sol\";\n\n/**\n * @dev Interface for the optional metadata functions from the ERC20 standard.\n *\n * _Available since v4.1._\n */\ninterface IERC20Metadata is IERC20 {\n /**\n * @dev Returns the name of the token.\n */\n function name() external view returns (string memory);\n\n /**\n * @dev Returns the symbol of the token.\n */\n function symbol() external view returns (string memory);\n\n /**\n * @dev Returns the decimals places of the token.\n */\n function decimals() external view returns (uint8);\n}\n" + }, + "@openzeppelin/contracts/token/ERC20/IERC20.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.6.0) (token/ERC20/IERC20.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Interface of the ERC20 standard as defined in the EIP.\n */\ninterface IERC20 {\n /**\n * @dev Emitted when `value` tokens are moved from one account (`from`) to\n * another (`to`).\n *\n * Note that `value` may be zero.\n */\n event Transfer(address indexed from, address indexed to, uint256 value);\n\n /**\n * @dev Emitted when the allowance of a `spender` for an `owner` is set by\n * a call to {approve}. `value` is the new allowance.\n */\n event Approval(address indexed owner, address indexed spender, uint256 value);\n\n /**\n * @dev Returns the amount of tokens in existence.\n */\n function totalSupply() external view returns (uint256);\n\n /**\n * @dev Returns the amount of tokens owned by `account`.\n */\n function balanceOf(address account) external view returns (uint256);\n\n /**\n * @dev Moves `amount` tokens from the caller's account to `to`.\n *\n * Returns a boolean value indicating whether the operation succeeded.\n *\n * Emits a {Transfer} event.\n */\n function transfer(address to, uint256 amount) external returns (bool);\n\n /**\n * @dev Returns the remaining number of tokens that `spender` will be\n * allowed to spend on behalf of `owner` through {transferFrom}. This is\n * zero by default.\n *\n * This value changes when {approve} or {transferFrom} are called.\n */\n function allowance(address owner, address spender) external view returns (uint256);\n\n /**\n * @dev Sets `amount` as the allowance of `spender` over the caller's tokens.\n *\n * Returns a boolean value indicating whether the operation succeeded.\n *\n * IMPORTANT: Beware that changing an allowance with this method brings the risk\n * that someone may use both the old and the new allowance by unfortunate\n * transaction ordering. One possible solution to mitigate this race\n * condition is to first reduce the spender's allowance to 0 and set the\n * desired value afterwards:\n * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729\n *\n * Emits an {Approval} event.\n */\n function approve(address spender, uint256 amount) external returns (bool);\n\n /**\n * @dev Moves `amount` tokens from `from` to `to` using the\n * allowance mechanism. `amount` is then deducted from the caller's\n * allowance.\n *\n * Returns a boolean value indicating whether the operation succeeded.\n *\n * Emits a {Transfer} event.\n */\n function transferFrom(\n address from,\n address to,\n uint256 amount\n ) external returns (bool);\n}\n" + }, + "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (token/ERC20/utils/SafeERC20.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../IERC20.sol\";\nimport \"../extensions/draft-IERC20Permit.sol\";\nimport \"../../../utils/Address.sol\";\n\n/**\n * @title SafeERC20\n * @dev Wrappers around ERC20 operations that throw on failure (when the token\n * contract returns false). Tokens that return no value (and instead revert or\n * throw on failure) are also supported, non-reverting calls are assumed to be\n * successful.\n * To use this library you can add a `using SafeERC20 for IERC20;` statement to your contract,\n * which allows you to call the safe operations as `token.safeTransfer(...)`, etc.\n */\nlibrary SafeERC20 {\n using Address for address;\n\n function safeTransfer(\n IERC20 token,\n address to,\n uint256 value\n ) internal {\n _callOptionalReturn(token, abi.encodeWithSelector(token.transfer.selector, to, value));\n }\n\n function safeTransferFrom(\n IERC20 token,\n address from,\n address to,\n uint256 value\n ) internal {\n _callOptionalReturn(token, abi.encodeWithSelector(token.transferFrom.selector, from, to, value));\n }\n\n /**\n * @dev Deprecated. This function has issues similar to the ones found in\n * {IERC20-approve}, and its usage is discouraged.\n *\n * Whenever possible, use {safeIncreaseAllowance} and\n * {safeDecreaseAllowance} instead.\n */\n function safeApprove(\n IERC20 token,\n address spender,\n uint256 value\n ) internal {\n // safeApprove should only be called when setting an initial allowance,\n // or when resetting it to zero. To increase and decrease it, use\n // 'safeIncreaseAllowance' and 'safeDecreaseAllowance'\n require(\n (value == 0) || (token.allowance(address(this), spender) == 0),\n \"SafeERC20: approve from non-zero to non-zero allowance\"\n );\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, value));\n }\n\n function safeIncreaseAllowance(\n IERC20 token,\n address spender,\n uint256 value\n ) internal {\n uint256 newAllowance = token.allowance(address(this), spender) + value;\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));\n }\n\n function safeDecreaseAllowance(\n IERC20 token,\n address spender,\n uint256 value\n ) internal {\n unchecked {\n uint256 oldAllowance = token.allowance(address(this), spender);\n require(oldAllowance >= value, \"SafeERC20: decreased allowance below zero\");\n uint256 newAllowance = oldAllowance - value;\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));\n }\n }\n\n function safePermit(\n IERC20Permit token,\n address owner,\n address spender,\n uint256 value,\n uint256 deadline,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) internal {\n uint256 nonceBefore = token.nonces(owner);\n token.permit(owner, spender, value, deadline, v, r, s);\n uint256 nonceAfter = token.nonces(owner);\n require(nonceAfter == nonceBefore + 1, \"SafeERC20: permit did not succeed\");\n }\n\n /**\n * @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement\n * on the return value: the return value is optional (but if data is returned, it must not be false).\n * @param token The token targeted by the call.\n * @param data The call data (encoded using abi.encode or one of its variants).\n */\n function _callOptionalReturn(IERC20 token, bytes memory data) private {\n // We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since\n // we're implementing it ourselves. We use {Address.functionCall} to perform this call, which verifies that\n // the target address contains contract code and also asserts for success in the low-level call.\n\n bytes memory returndata = address(token).functionCall(data, \"SafeERC20: low-level call failed\");\n if (returndata.length > 0) {\n // Return data is optional\n require(abi.decode(returndata, (bool)), \"SafeERC20: ERC20 operation did not succeed\");\n }\n }\n}\n" + }, + "@openzeppelin/contracts/token/ERC721/extensions/IERC721Metadata.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (token/ERC721/extensions/IERC721Metadata.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../IERC721.sol\";\n\n/**\n * @title ERC-721 Non-Fungible Token Standard, optional metadata extension\n * @dev See https://eips.ethereum.org/EIPS/eip-721\n */\ninterface IERC721Metadata is IERC721 {\n /**\n * @dev Returns the token collection name.\n */\n function name() external view returns (string memory);\n\n /**\n * @dev Returns the token collection symbol.\n */\n function symbol() external view returns (string memory);\n\n /**\n * @dev Returns the Uniform Resource Identifier (URI) for `tokenId` token.\n */\n function tokenURI(uint256 tokenId) external view returns (string memory);\n}\n" + }, + "@openzeppelin/contracts/token/ERC721/IERC721.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (token/ERC721/IERC721.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../../utils/introspection/IERC165.sol\";\n\n/**\n * @dev Required interface of an ERC721 compliant contract.\n */\ninterface IERC721 is IERC165 {\n /**\n * @dev Emitted when `tokenId` token is transferred from `from` to `to`.\n */\n event Transfer(address indexed from, address indexed to, uint256 indexed tokenId);\n\n /**\n * @dev Emitted when `owner` enables `approved` to manage the `tokenId` token.\n */\n event Approval(address indexed owner, address indexed approved, uint256 indexed tokenId);\n\n /**\n * @dev Emitted when `owner` enables or disables (`approved`) `operator` to manage all of its assets.\n */\n event ApprovalForAll(address indexed owner, address indexed operator, bool approved);\n\n /**\n * @dev Returns the number of tokens in ``owner``'s account.\n */\n function balanceOf(address owner) external view returns (uint256 balance);\n\n /**\n * @dev Returns the owner of the `tokenId` token.\n *\n * Requirements:\n *\n * - `tokenId` must exist.\n */\n function ownerOf(uint256 tokenId) external view returns (address owner);\n\n /**\n * @dev Safely transfers `tokenId` token from `from` to `to`.\n *\n * Requirements:\n *\n * - `from` cannot be the zero address.\n * - `to` cannot be the zero address.\n * - `tokenId` token must exist and be owned by `from`.\n * - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}.\n * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.\n *\n * Emits a {Transfer} event.\n */\n function safeTransferFrom(\n address from,\n address to,\n uint256 tokenId,\n bytes calldata data\n ) external;\n\n /**\n * @dev Safely transfers `tokenId` token from `from` to `to`, checking first that contract recipients\n * are aware of the ERC721 protocol to prevent tokens from being forever locked.\n *\n * Requirements:\n *\n * - `from` cannot be the zero address.\n * - `to` cannot be the zero address.\n * - `tokenId` token must exist and be owned by `from`.\n * - If the caller is not `from`, it must have been allowed to move this token by either {approve} or {setApprovalForAll}.\n * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.\n *\n * Emits a {Transfer} event.\n */\n function safeTransferFrom(\n address from,\n address to,\n uint256 tokenId\n ) external;\n\n /**\n * @dev Transfers `tokenId` token from `from` to `to`.\n *\n * WARNING: Usage of this method is discouraged, use {safeTransferFrom} whenever possible.\n *\n * Requirements:\n *\n * - `from` cannot be the zero address.\n * - `to` cannot be the zero address.\n * - `tokenId` token must be owned by `from`.\n * - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}.\n *\n * Emits a {Transfer} event.\n */\n function transferFrom(\n address from,\n address to,\n uint256 tokenId\n ) external;\n\n /**\n * @dev Gives permission to `to` to transfer `tokenId` token to another account.\n * The approval is cleared when the token is transferred.\n *\n * Only a single account can be approved at a time, so approving the zero address clears previous approvals.\n *\n * Requirements:\n *\n * - The caller must own the token or be an approved operator.\n * - `tokenId` must exist.\n *\n * Emits an {Approval} event.\n */\n function approve(address to, uint256 tokenId) external;\n\n /**\n * @dev Approve or remove `operator` as an operator for the caller.\n * Operators can call {transferFrom} or {safeTransferFrom} for any token owned by the caller.\n *\n * Requirements:\n *\n * - The `operator` cannot be the caller.\n *\n * Emits an {ApprovalForAll} event.\n */\n function setApprovalForAll(address operator, bool _approved) external;\n\n /**\n * @dev Returns the account approved for `tokenId` token.\n *\n * Requirements:\n *\n * - `tokenId` must exist.\n */\n function getApproved(uint256 tokenId) external view returns (address operator);\n\n /**\n * @dev Returns if the `operator` is allowed to manage all of the assets of `owner`.\n *\n * See {setApprovalForAll}\n */\n function isApprovedForAll(address owner, address operator) external view returns (bool);\n}\n" + }, + "@openzeppelin/contracts/utils/Address.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (utils/Address.sol)\n\npragma solidity ^0.8.1;\n\n/**\n * @dev Collection of functions related to the address type\n */\nlibrary Address {\n /**\n * @dev Returns true if `account` is a contract.\n *\n * [IMPORTANT]\n * ====\n * It is unsafe to assume that an address for which this function returns\n * false is an externally-owned account (EOA) and not a contract.\n *\n * Among others, `isContract` will return false for the following\n * types of addresses:\n *\n * - an externally-owned account\n * - a contract in construction\n * - an address where a contract will be created\n * - an address where a contract lived, but was destroyed\n * ====\n *\n * [IMPORTANT]\n * ====\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\n *\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\n * constructor.\n * ====\n */\n function isContract(address account) internal view returns (bool) {\n // This method relies on extcodesize/address.code.length, which returns 0\n // for contracts in construction, since the code is only stored at the end\n // of the constructor execution.\n\n return account.code.length > 0;\n }\n\n /**\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\n * `recipient`, forwarding all available gas and reverting on errors.\n *\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\n * imposed by `transfer`, making them unable to receive funds via\n * `transfer`. {sendValue} removes this limitation.\n *\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\n *\n * IMPORTANT: because control is transferred to `recipient`, care must be\n * taken to not create reentrancy vulnerabilities. Consider using\n * {ReentrancyGuard} or the\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\n */\n function sendValue(address payable recipient, uint256 amount) internal {\n require(address(this).balance >= amount, \"Address: insufficient balance\");\n\n (bool success, ) = recipient.call{value: amount}(\"\");\n require(success, \"Address: unable to send value, recipient may have reverted\");\n }\n\n /**\n * @dev Performs a Solidity function call using a low level `call`. A\n * plain `call` is an unsafe replacement for a function call: use this\n * function instead.\n *\n * If `target` reverts with a revert reason, it is bubbled up by this\n * function (like regular Solidity function calls).\n *\n * Returns the raw returned data. To convert to the expected return value,\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\n *\n * Requirements:\n *\n * - `target` must be a contract.\n * - calling `target` with `data` must not revert.\n *\n * _Available since v3.1._\n */\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionCall(target, data, \"Address: low-level call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\n * `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, 0, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but also transferring `value` wei to `target`.\n *\n * Requirements:\n *\n * - the calling contract must have an ETH balance of at least `value`.\n * - the called Solidity function must be `payable`.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, value, \"Address: low-level call with value failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\n * with `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(address(this).balance >= value, \"Address: insufficient balance for call\");\n require(isContract(target), \"Address: call to non-contract\");\n\n (bool success, bytes memory returndata) = target.call{value: value}(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\n return functionStaticCall(target, data, \"Address: low-level static call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal view returns (bytes memory) {\n require(isContract(target), \"Address: static call to non-contract\");\n\n (bool success, bytes memory returndata) = target.staticcall(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a delegate call.\n *\n * _Available since v3.4._\n */\n function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionDelegateCall(target, data, \"Address: low-level delegate call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a delegate call.\n *\n * _Available since v3.4._\n */\n function functionDelegateCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(isContract(target), \"Address: delegate call to non-contract\");\n\n (bool success, bytes memory returndata) = target.delegatecall(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the\n * revert reason using the provided one.\n *\n * _Available since v4.3._\n */\n function verifyCallResult(\n bool success,\n bytes memory returndata,\n string memory errorMessage\n ) internal pure returns (bytes memory) {\n if (success) {\n return returndata;\n } else {\n // Look for revert reason and bubble it up if present\n if (returndata.length > 0) {\n // The easiest way to bubble the revert reason is using memory via assembly\n /// @solidity memory-safe-assembly\n assembly {\n let returndata_size := mload(returndata)\n revert(add(32, returndata), returndata_size)\n }\n } else {\n revert(errorMessage);\n }\n }\n }\n}\n" + }, + "@openzeppelin/contracts/utils/Context.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Provides information about the current execution context, including the\n * sender of the transaction and its data. While these are generally available\n * via msg.sender and msg.data, they should not be accessed in such a direct\n * manner, since when dealing with meta-transactions the account sending and\n * paying for execution may not be the actual sender (as far as an application\n * is concerned).\n *\n * This contract is only required for intermediate, library-like contracts.\n */\nabstract contract Context {\n function _msgSender() internal view virtual returns (address) {\n return msg.sender;\n }\n\n function _msgData() internal view virtual returns (bytes calldata) {\n return msg.data;\n }\n}\n" + }, + "@openzeppelin/contracts/utils/Counters.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (utils/Counters.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @title Counters\n * @author Matt Condon (@shrugs)\n * @dev Provides counters that can only be incremented, decremented or reset. This can be used e.g. to track the number\n * of elements in a mapping, issuing ERC721 ids, or counting request ids.\n *\n * Include with `using Counters for Counters.Counter;`\n */\nlibrary Counters {\n struct Counter {\n // This variable should never be directly accessed by users of the library: interactions must be restricted to\n // the library's function. As of Solidity v0.5.2, this cannot be enforced, though there is a proposal to add\n // this feature: see https://github.com/ethereum/solidity/issues/4637\n uint256 _value; // default: 0\n }\n\n function current(Counter storage counter) internal view returns (uint256) {\n return counter._value;\n }\n\n function increment(Counter storage counter) internal {\n unchecked {\n counter._value += 1;\n }\n }\n\n function decrement(Counter storage counter) internal {\n uint256 value = counter._value;\n require(value > 0, \"Counter: decrement overflow\");\n unchecked {\n counter._value = value - 1;\n }\n }\n\n function reset(Counter storage counter) internal {\n counter._value = 0;\n }\n}\n" + }, + "@openzeppelin/contracts/utils/cryptography/draft-EIP712.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (utils/cryptography/draft-EIP712.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./ECDSA.sol\";\n\n/**\n * @dev https://eips.ethereum.org/EIPS/eip-712[EIP 712] is a standard for hashing and signing of typed structured data.\n *\n * The encoding specified in the EIP is very generic, and such a generic implementation in Solidity is not feasible,\n * thus this contract does not implement the encoding itself. Protocols need to implement the type-specific encoding\n * they need in their contracts using a combination of `abi.encode` and `keccak256`.\n *\n * This contract implements the EIP 712 domain separator ({_domainSeparatorV4}) that is used as part of the encoding\n * scheme, and the final step of the encoding to obtain the message digest that is then signed via ECDSA\n * ({_hashTypedDataV4}).\n *\n * The implementation of the domain separator was designed to be as efficient as possible while still properly updating\n * the chain id to protect against replay attacks on an eventual fork of the chain.\n *\n * NOTE: This contract implements the version of the encoding known as \"v4\", as implemented by the JSON RPC method\n * https://docs.metamask.io/guide/signing-data.html[`eth_signTypedDataV4` in MetaMask].\n *\n * _Available since v3.4._\n */\nabstract contract EIP712 {\n /* solhint-disable var-name-mixedcase */\n // Cache the domain separator as an immutable value, but also store the chain id that it corresponds to, in order to\n // invalidate the cached domain separator if the chain id changes.\n bytes32 private immutable _CACHED_DOMAIN_SEPARATOR;\n uint256 private immutable _CACHED_CHAIN_ID;\n address private immutable _CACHED_THIS;\n\n bytes32 private immutable _HASHED_NAME;\n bytes32 private immutable _HASHED_VERSION;\n bytes32 private immutable _TYPE_HASH;\n\n /* solhint-enable var-name-mixedcase */\n\n /**\n * @dev Initializes the domain separator and parameter caches.\n *\n * The meaning of `name` and `version` is specified in\n * https://eips.ethereum.org/EIPS/eip-712#definition-of-domainseparator[EIP 712]:\n *\n * - `name`: the user readable name of the signing domain, i.e. the name of the DApp or the protocol.\n * - `version`: the current major version of the signing domain.\n *\n * NOTE: These parameters cannot be changed except through a xref:learn::upgrading-smart-contracts.adoc[smart\n * contract upgrade].\n */\n constructor(string memory name, string memory version) {\n bytes32 hashedName = keccak256(bytes(name));\n bytes32 hashedVersion = keccak256(bytes(version));\n bytes32 typeHash = keccak256(\n \"EIP712Domain(string name,string version,uint256 chainId,address verifyingContract)\"\n );\n _HASHED_NAME = hashedName;\n _HASHED_VERSION = hashedVersion;\n _CACHED_CHAIN_ID = block.chainid;\n _CACHED_DOMAIN_SEPARATOR = _buildDomainSeparator(typeHash, hashedName, hashedVersion);\n _CACHED_THIS = address(this);\n _TYPE_HASH = typeHash;\n }\n\n /**\n * @dev Returns the domain separator for the current chain.\n */\n function _domainSeparatorV4() internal view returns (bytes32) {\n if (address(this) == _CACHED_THIS && block.chainid == _CACHED_CHAIN_ID) {\n return _CACHED_DOMAIN_SEPARATOR;\n } else {\n return _buildDomainSeparator(_TYPE_HASH, _HASHED_NAME, _HASHED_VERSION);\n }\n }\n\n function _buildDomainSeparator(\n bytes32 typeHash,\n bytes32 nameHash,\n bytes32 versionHash\n ) private view returns (bytes32) {\n return keccak256(abi.encode(typeHash, nameHash, versionHash, block.chainid, address(this)));\n }\n\n /**\n * @dev Given an already https://eips.ethereum.org/EIPS/eip-712#definition-of-hashstruct[hashed struct], this\n * function returns the hash of the fully encoded EIP712 message for this domain.\n *\n * This hash can be used together with {ECDSA-recover} to obtain the signer of a message. For example:\n *\n * ```solidity\n * bytes32 digest = _hashTypedDataV4(keccak256(abi.encode(\n * keccak256(\"Mail(address to,string contents)\"),\n * mailTo,\n * keccak256(bytes(mailContents))\n * )));\n * address signer = ECDSA.recover(digest, signature);\n * ```\n */\n function _hashTypedDataV4(bytes32 structHash) internal view virtual returns (bytes32) {\n return ECDSA.toTypedDataHash(_domainSeparatorV4(), structHash);\n }\n}\n" + }, + "@openzeppelin/contracts/utils/cryptography/ECDSA.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (utils/cryptography/ECDSA.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../Strings.sol\";\n\n/**\n * @dev Elliptic Curve Digital Signature Algorithm (ECDSA) operations.\n *\n * These functions can be used to verify that a message was signed by the holder\n * of the private keys of a given address.\n */\nlibrary ECDSA {\n enum RecoverError {\n NoError,\n InvalidSignature,\n InvalidSignatureLength,\n InvalidSignatureS,\n InvalidSignatureV\n }\n\n function _throwError(RecoverError error) private pure {\n if (error == RecoverError.NoError) {\n return; // no error: do nothing\n } else if (error == RecoverError.InvalidSignature) {\n revert(\"ECDSA: invalid signature\");\n } else if (error == RecoverError.InvalidSignatureLength) {\n revert(\"ECDSA: invalid signature length\");\n } else if (error == RecoverError.InvalidSignatureS) {\n revert(\"ECDSA: invalid signature 's' value\");\n } else if (error == RecoverError.InvalidSignatureV) {\n revert(\"ECDSA: invalid signature 'v' value\");\n }\n }\n\n /**\n * @dev Returns the address that signed a hashed message (`hash`) with\n * `signature` or error string. This address can then be used for verification purposes.\n *\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\n * this function rejects them by requiring the `s` value to be in the lower\n * half order, and the `v` value to be either 27 or 28.\n *\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\n * verification to be secure: it is possible to craft signatures that\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\n * this is by receiving a hash of the original message (which may otherwise\n * be too long), and then calling {toEthSignedMessageHash} on it.\n *\n * Documentation for signature generation:\n * - with https://web3js.readthedocs.io/en/v1.3.4/web3-eth-accounts.html#sign[Web3.js]\n * - with https://docs.ethers.io/v5/api/signer/#Signer-signMessage[ethers]\n *\n * _Available since v4.3._\n */\n function tryRecover(bytes32 hash, bytes memory signature) internal pure returns (address, RecoverError) {\n // Check the signature length\n // - case 65: r,s,v signature (standard)\n // - case 64: r,vs signature (cf https://eips.ethereum.org/EIPS/eip-2098) _Available since v4.1._\n if (signature.length == 65) {\n bytes32 r;\n bytes32 s;\n uint8 v;\n // ecrecover takes the signature parameters, and the only way to get them\n // currently is to use assembly.\n /// @solidity memory-safe-assembly\n assembly {\n r := mload(add(signature, 0x20))\n s := mload(add(signature, 0x40))\n v := byte(0, mload(add(signature, 0x60)))\n }\n return tryRecover(hash, v, r, s);\n } else if (signature.length == 64) {\n bytes32 r;\n bytes32 vs;\n // ecrecover takes the signature parameters, and the only way to get them\n // currently is to use assembly.\n /// @solidity memory-safe-assembly\n assembly {\n r := mload(add(signature, 0x20))\n vs := mload(add(signature, 0x40))\n }\n return tryRecover(hash, r, vs);\n } else {\n return (address(0), RecoverError.InvalidSignatureLength);\n }\n }\n\n /**\n * @dev Returns the address that signed a hashed message (`hash`) with\n * `signature`. This address can then be used for verification purposes.\n *\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\n * this function rejects them by requiring the `s` value to be in the lower\n * half order, and the `v` value to be either 27 or 28.\n *\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\n * verification to be secure: it is possible to craft signatures that\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\n * this is by receiving a hash of the original message (which may otherwise\n * be too long), and then calling {toEthSignedMessageHash} on it.\n */\n function recover(bytes32 hash, bytes memory signature) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, signature);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Overload of {ECDSA-tryRecover} that receives the `r` and `vs` short-signature fields separately.\n *\n * See https://eips.ethereum.org/EIPS/eip-2098[EIP-2098 short signatures]\n *\n * _Available since v4.3._\n */\n function tryRecover(\n bytes32 hash,\n bytes32 r,\n bytes32 vs\n ) internal pure returns (address, RecoverError) {\n bytes32 s = vs & bytes32(0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff);\n uint8 v = uint8((uint256(vs) >> 255) + 27);\n return tryRecover(hash, v, r, s);\n }\n\n /**\n * @dev Overload of {ECDSA-recover} that receives the `r and `vs` short-signature fields separately.\n *\n * _Available since v4.2._\n */\n function recover(\n bytes32 hash,\n bytes32 r,\n bytes32 vs\n ) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, r, vs);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Overload of {ECDSA-tryRecover} that receives the `v`,\n * `r` and `s` signature fields separately.\n *\n * _Available since v4.3._\n */\n function tryRecover(\n bytes32 hash,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) internal pure returns (address, RecoverError) {\n // EIP-2 still allows signature malleability for ecrecover(). Remove this possibility and make the signature\n // unique. Appendix F in the Ethereum Yellow paper (https://ethereum.github.io/yellowpaper/paper.pdf), defines\n // the valid range for s in (301): 0 < s < secp256k1n ÷ 2 + 1, and for v in (302): v ∈ {27, 28}. Most\n // signatures from current libraries generate a unique signature with an s-value in the lower half order.\n //\n // If your library generates malleable signatures, such as s-values in the upper range, calculate a new s-value\n // with 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141 - s1 and flip v from 27 to 28 or\n // vice versa. If your library also generates signatures with 0/1 for v instead 27/28, add 27 to v to accept\n // these malleable signatures as well.\n if (uint256(s) > 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D576E7357A4501DDFE92F46681B20A0) {\n return (address(0), RecoverError.InvalidSignatureS);\n }\n if (v != 27 && v != 28) {\n return (address(0), RecoverError.InvalidSignatureV);\n }\n\n // If the signature is valid (and not malleable), return the signer address\n address signer = ecrecover(hash, v, r, s);\n if (signer == address(0)) {\n return (address(0), RecoverError.InvalidSignature);\n }\n\n return (signer, RecoverError.NoError);\n }\n\n /**\n * @dev Overload of {ECDSA-recover} that receives the `v`,\n * `r` and `s` signature fields separately.\n */\n function recover(\n bytes32 hash,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, v, r, s);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Returns an Ethereum Signed Message, created from a `hash`. This\n * produces hash corresponding to the one signed with the\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\n * JSON-RPC method as part of EIP-191.\n *\n * See {recover}.\n */\n function toEthSignedMessageHash(bytes32 hash) internal pure returns (bytes32) {\n // 32 is the length in bytes of hash,\n // enforced by the type signature above\n return keccak256(abi.encodePacked(\"\\x19Ethereum Signed Message:\\n32\", hash));\n }\n\n /**\n * @dev Returns an Ethereum Signed Message, created from `s`. This\n * produces hash corresponding to the one signed with the\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\n * JSON-RPC method as part of EIP-191.\n *\n * See {recover}.\n */\n function toEthSignedMessageHash(bytes memory s) internal pure returns (bytes32) {\n return keccak256(abi.encodePacked(\"\\x19Ethereum Signed Message:\\n\", Strings.toString(s.length), s));\n }\n\n /**\n * @dev Returns an Ethereum Signed Typed Data, created from a\n * `domainSeparator` and a `structHash`. This produces hash corresponding\n * to the one signed with the\n * https://eips.ethereum.org/EIPS/eip-712[`eth_signTypedData`]\n * JSON-RPC method as part of EIP-712.\n *\n * See {recover}.\n */\n function toTypedDataHash(bytes32 domainSeparator, bytes32 structHash) internal pure returns (bytes32) {\n return keccak256(abi.encodePacked(\"\\x19\\x01\", domainSeparator, structHash));\n }\n}\n" + }, + "@openzeppelin/contracts/utils/introspection/IERC165.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (utils/introspection/IERC165.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Interface of the ERC165 standard, as defined in the\n * https://eips.ethereum.org/EIPS/eip-165[EIP].\n *\n * Implementers can declare support of contract interfaces, which can then be\n * queried by others ({ERC165Checker}).\n *\n * For an implementation, see {ERC165}.\n */\ninterface IERC165 {\n /**\n * @dev Returns true if this contract implements the interface defined by\n * `interfaceId`. See the corresponding\n * https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified[EIP section]\n * to learn more about how these ids are created.\n *\n * This function call must use less than 30 000 gas.\n */\n function supportsInterface(bytes4 interfaceId) external view returns (bool);\n}\n" + }, + "@openzeppelin/contracts/utils/StorageSlot.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (utils/StorageSlot.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Library for reading and writing primitive types to specific storage slots.\n *\n * Storage slots are often used to avoid storage conflict when dealing with upgradeable contracts.\n * This library helps with reading and writing to such slots without the need for inline assembly.\n *\n * The functions in this library return Slot structs that contain a `value` member that can be used to read or write.\n *\n * Example usage to set ERC1967 implementation slot:\n * ```\n * contract ERC1967 {\n * bytes32 internal constant _IMPLEMENTATION_SLOT = 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc;\n *\n * function _getImplementation() internal view returns (address) {\n * return StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value;\n * }\n *\n * function _setImplementation(address newImplementation) internal {\n * require(Address.isContract(newImplementation), \"ERC1967: new implementation is not a contract\");\n * StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value = newImplementation;\n * }\n * }\n * ```\n *\n * _Available since v4.1 for `address`, `bool`, `bytes32`, and `uint256`._\n */\nlibrary StorageSlot {\n struct AddressSlot {\n address value;\n }\n\n struct BooleanSlot {\n bool value;\n }\n\n struct Bytes32Slot {\n bytes32 value;\n }\n\n struct Uint256Slot {\n uint256 value;\n }\n\n /**\n * @dev Returns an `AddressSlot` with member `value` located at `slot`.\n */\n function getAddressSlot(bytes32 slot) internal pure returns (AddressSlot storage r) {\n /// @solidity memory-safe-assembly\n assembly {\n r.slot := slot\n }\n }\n\n /**\n * @dev Returns an `BooleanSlot` with member `value` located at `slot`.\n */\n function getBooleanSlot(bytes32 slot) internal pure returns (BooleanSlot storage r) {\n /// @solidity memory-safe-assembly\n assembly {\n r.slot := slot\n }\n }\n\n /**\n * @dev Returns an `Bytes32Slot` with member `value` located at `slot`.\n */\n function getBytes32Slot(bytes32 slot) internal pure returns (Bytes32Slot storage r) {\n /// @solidity memory-safe-assembly\n assembly {\n r.slot := slot\n }\n }\n\n /**\n * @dev Returns an `Uint256Slot` with member `value` located at `slot`.\n */\n function getUint256Slot(bytes32 slot) internal pure returns (Uint256Slot storage r) {\n /// @solidity memory-safe-assembly\n assembly {\n r.slot := slot\n }\n }\n}\n" + }, + "@openzeppelin/contracts/utils/Strings.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (utils/Strings.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev String operations.\n */\nlibrary Strings {\n bytes16 private constant _HEX_SYMBOLS = \"0123456789abcdef\";\n uint8 private constant _ADDRESS_LENGTH = 20;\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` decimal representation.\n */\n function toString(uint256 value) internal pure returns (string memory) {\n // Inspired by OraclizeAPI's implementation - MIT licence\n // https://github.com/oraclize/ethereum-api/blob/b42146b063c7d6ee1358846c198246239e9360e8/oraclizeAPI_0.4.25.sol\n\n if (value == 0) {\n return \"0\";\n }\n uint256 temp = value;\n uint256 digits;\n while (temp != 0) {\n digits++;\n temp /= 10;\n }\n bytes memory buffer = new bytes(digits);\n while (value != 0) {\n digits -= 1;\n buffer[digits] = bytes1(uint8(48 + uint256(value % 10)));\n value /= 10;\n }\n return string(buffer);\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation.\n */\n function toHexString(uint256 value) internal pure returns (string memory) {\n if (value == 0) {\n return \"0x00\";\n }\n uint256 temp = value;\n uint256 length = 0;\n while (temp != 0) {\n length++;\n temp >>= 8;\n }\n return toHexString(value, length);\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length.\n */\n function toHexString(uint256 value, uint256 length) internal pure returns (string memory) {\n bytes memory buffer = new bytes(2 * length + 2);\n buffer[0] = \"0\";\n buffer[1] = \"x\";\n for (uint256 i = 2 * length + 1; i > 1; --i) {\n buffer[i] = _HEX_SYMBOLS[value & 0xf];\n value >>= 4;\n }\n require(value == 0, \"Strings: hex length insufficient\");\n return string(buffer);\n }\n\n /**\n * @dev Converts an `address` with fixed length of 20 bytes to its not checksummed ASCII `string` hexadecimal representation.\n */\n function toHexString(address addr) internal pure returns (string memory) {\n return toHexString(uint256(uint160(addr)), _ADDRESS_LENGTH);\n }\n}\n" + }, + "contracts/agToken/AgEUR.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\nimport \"../interfaces/IAgToken.sol\";\nimport \"../interfaces/coreModule/IStableMaster.sol\";\nimport \"../interfaces/ITreasury.sol\";\nimport \"@openzeppelin/contracts-upgradeable/token/ERC20/extensions/draft-ERC20PermitUpgradeable.sol\";\n\n/// @title AgEUR\n/// @author Angle Labs, Inc.\n/// @notice Base contract for agEUR, Angle's Euro stablecoin\n/// @dev This contract is an upgraded version of the agEUR contract that was first deployed on Ethereum mainnet\ncontract AgEUR is IAgToken, ERC20PermitUpgradeable {\n // ================================= REFERENCES ================================\n\n /// @notice Reference to the `StableMaster` contract associated to agEUR\n address public stableMaster;\n\n /// @custom:oz-upgrades-unsafe-allow constructor\n constructor() initializer {}\n\n // ============================== ADDED PARAMETERS =============================\n\n /// @inheritdoc IAgToken\n mapping(address => bool) public isMinter;\n /// @notice Reference to the treasury contract which can grant minting rights\n address public treasury;\n /// @notice Boolean used to check whether the contract had been reinitialized after an upgrade\n bool public treasuryInitialized;\n\n // =================================== EVENTS ==================================\n\n event TreasuryUpdated(address indexed _treasury);\n event MinterToggled(address indexed minter);\n\n // =================================== ERRORS ==================================\n\n error BurnAmountExceedsAllowance();\n error InvalidSender();\n error InvalidTreasury();\n error NotGovernor();\n error NotMinter();\n error NotTreasury();\n error TreasuryAlreadyInitialized();\n\n // ================================= MODIFIERS =================================\n\n /// @notice Checks to see if it is the `Treasury` calling this contract\n modifier onlyTreasury() {\n if (msg.sender != treasury) revert NotTreasury();\n _;\n }\n\n /// @notice Checks whether the sender has the minting right\n modifier onlyMinter() {\n if (!isMinter[msg.sender]) revert NotMinter();\n _;\n }\n\n // ============================= EXTERNAL FUNCTION =============================\n\n /// @notice Allows anyone to burn stablecoins\n /// @param amount Amount of stablecoins to burn\n /// @dev This function can typically be called if there is a settlement mechanism to burn stablecoins\n function burnStablecoin(uint256 amount) external {\n _burn(msg.sender, amount);\n }\n\n // ========================= MINTER ROLE ONLY FUNCTIONS ========================\n\n /// @inheritdoc IAgToken\n function burnSelf(uint256 amount, address burner) external onlyMinter {\n _burn(burner, amount);\n }\n\n /// @inheritdoc IAgToken\n function burnFrom(uint256 amount, address burner, address sender) external onlyMinter {\n if (burner != sender) {\n uint256 currentAllowance = allowance(burner, sender);\n if (currentAllowance < amount) revert BurnAmountExceedsAllowance();\n _approve(burner, sender, currentAllowance - amount);\n }\n _burn(burner, amount);\n }\n\n /// @inheritdoc IAgToken\n function mint(address account, uint256 amount) external onlyMinter {\n _mint(account, amount);\n }\n\n // ========================== TREASURY ONLY FUNCTIONS ==========================\n\n /// @inheritdoc IAgToken\n function addMinter(address minter) external onlyTreasury {\n isMinter[minter] = true;\n emit MinterToggled(minter);\n }\n\n /// @inheritdoc IAgToken\n function removeMinter(address minter) external {\n if (msg.sender != minter && msg.sender != address(treasury)) revert InvalidSender();\n isMinter[minter] = false;\n emit MinterToggled(minter);\n }\n\n /// @inheritdoc IAgToken\n function setTreasury(address _treasury) external onlyTreasury {\n treasury = _treasury;\n emit TreasuryUpdated(_treasury);\n }\n}\n" + }, + "contracts/agToken/AgToken.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\n/*\n * █ \n ***** ▓▓▓ \n * ▓▓▓▓▓▓▓ \n * ///. ▓▓▓▓▓▓▓▓▓▓▓▓▓ \n ***** //////// ▓▓▓▓▓▓▓ \n * ///////////// ▓▓▓ \n ▓▓ ////////////////// █ ▓▓ \n ▓▓ ▓▓ /////////////////////// ▓▓ ▓▓ \n ▓▓ ▓▓ //////////////////////////// ▓▓ ▓▓ \n ▓▓ ▓▓ /////////▓▓▓///////▓▓▓///////// ▓▓ ▓▓ \n ▓▓ ,////////////////////////////////////// ▓▓ ▓▓ \n ▓▓ ////////////////////////////////////////// ▓▓ \n ▓▓ //////////////////////▓▓▓▓///////////////////// \n ,//////////////////////////////////////////////////// \n .////////////////////////////////////////////////////////// \n .//////////////////////////██.,//////////////////////////█ \n .//////////////////////████..,./////////////////////██ \n ...////////////////███████.....,.////////////////███ \n ,.,////////////████████ ........,///////////████ \n .,.,//////█████████ ,.......///////████ \n ,..//████████ ........./████ \n ..,██████ .....,███ \n .██ ,.,█ \n \n \n \n ▓▓ ▓▓▓▓▓▓▓▓▓▓ ▓▓▓▓▓▓▓▓▓▓ ▓▓ ▓▓▓▓▓▓▓▓▓▓ \n ▓▓▓▓▓▓ ▓▓▓ ▓▓▓ ▓▓▓ ▓▓ ▓▓ ▓▓▓▓ \n ▓▓▓ ▓▓▓ ▓▓▓ ▓▓▓ ▓▓▓ ▓▓▓ ▓▓ ▓▓▓▓▓ \n ▓▓▓ ▓▓ ▓▓▓ ▓▓▓ ▓▓▓▓▓▓▓▓▓▓ ▓▓▓▓▓▓▓▓▓▓ ▓▓▓▓▓▓▓▓▓▓ \n*/\n\nimport \"../interfaces/IAgToken.sol\";\nimport \"../interfaces/ITreasury.sol\";\nimport \"@openzeppelin/contracts-upgradeable/token/ERC20/extensions/draft-ERC20PermitUpgradeable.sol\";\n\n/// @title AgToken\n/// @author Angle Labs, Inc.\n/// @notice Base contract for Angle agTokens on Ethereum and on other chains\n/// @dev By default, agTokens are ERC-20 tokens with 18 decimals\ncontract AgToken is IAgToken, ERC20PermitUpgradeable {\n // =========================== PARAMETERS / VARIABLES ==========================\n\n /// @inheritdoc IAgToken\n mapping(address => bool) public isMinter;\n /// @notice Reference to the treasury contract which can grant minting rights\n address public treasury;\n\n // =================================== EVENTS ==================================\n\n event TreasuryUpdated(address indexed _treasury);\n event MinterToggled(address indexed minter);\n\n // =================================== ERRORS ==================================\n\n error BurnAmountExceedsAllowance();\n error InvalidSender();\n error InvalidTreasury();\n error NotMinter();\n error NotTreasury();\n\n // ================================ CONSTRUCTOR ================================\n\n /// @custom:oz-upgrades-unsafe-allow constructor\n constructor() initializer {}\n\n /// @notice Initializes the `AgToken` contract\n function initialize(string memory name_, string memory symbol_, address _treasury) external {\n _initialize(name_, symbol_, _treasury);\n }\n\n /// @notice Initializes the contract\n function _initialize(string memory name_, string memory symbol_, address _treasury) internal virtual initializer {\n if (address(ITreasury(_treasury).stablecoin()) != address(this)) revert InvalidTreasury();\n __ERC20Permit_init(name_);\n __ERC20_init(name_, symbol_);\n treasury = _treasury;\n emit TreasuryUpdated(_treasury);\n }\n\n // ================================= MODIFIERS =================================\n\n /// @notice Checks to see if it is the `Treasury` calling this contract\n modifier onlyTreasury() {\n if (msg.sender != treasury) revert NotTreasury();\n _;\n }\n\n /// @notice Checks whether the sender has the minting right\n modifier onlyMinter() {\n if (!isMinter[msg.sender]) revert NotMinter();\n _;\n }\n\n // ============================= EXTERNAL FUNCTION =============================\n\n /// @notice Allows anyone to burn stablecoins\n /// @param amount Amount of stablecoins to burn\n /// @dev This function can typically be called if there is a settlement mechanism to burn stablecoins\n function burnStablecoin(uint256 amount) external {\n _burn(msg.sender, amount);\n }\n\n // ========================= MINTER ROLE ONLY FUNCTIONS ========================\n\n /// @inheritdoc IAgToken\n function burnSelf(uint256 amount, address burner) external onlyMinter {\n _burn(burner, amount);\n }\n\n /// @inheritdoc IAgToken\n function burnFrom(uint256 amount, address burner, address sender) external onlyMinter {\n if (burner != sender) {\n uint256 currentAllowance = allowance(burner, sender);\n if (currentAllowance < amount) revert BurnAmountExceedsAllowance();\n _approve(burner, sender, currentAllowance - amount);\n }\n _burn(burner, amount);\n }\n\n /// @inheritdoc IAgToken\n function mint(address account, uint256 amount) external onlyMinter {\n _mint(account, amount);\n }\n\n // ========================== GOVERNANCE ONLY FUNCTIONS ==========================\n\n /// @inheritdoc IAgToken\n function addMinter(address minter) external onlyTreasury {\n isMinter[minter] = true;\n emit MinterToggled(minter);\n }\n\n /// @inheritdoc IAgToken\n function removeMinter(address minter) external {\n if (msg.sender != address(treasury) && msg.sender != minter) revert InvalidSender();\n isMinter[minter] = false;\n emit MinterToggled(minter);\n }\n\n /// @inheritdoc IAgToken\n function setTreasury(address _treasury) external virtual onlyTreasury {\n treasury = _treasury;\n emit TreasuryUpdated(_treasury);\n }\n}\n" + }, + "contracts/agToken/AgTokenSideChainMultiBridge.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\nimport \"./AgToken.sol\";\nimport \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\nimport \"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\";\n\n/// @title AgTokenSideChainMultiBridge\n/// @author Angle Labs, Inc.\n/// @notice Contract for Angle agTokens on other chains than Ethereum mainnet\n/// @dev This contract supports bridge tokens having a minting right on the stablecoin (also referred to as the canonical\n/// or the native token)\ncontract AgTokenSideChainMultiBridge is AgToken {\n using SafeERC20 for IERC20;\n\n /// @notice Base used for fee computation\n uint256 public constant BASE_PARAMS = 1e9;\n\n // =============================== BRIDGING DATA ===============================\n\n /// @notice Struct with some data about a specific bridge token\n struct BridgeDetails {\n // Limit on the balance of bridge token held by the contract: it is designed\n // to reduce the exposure of the system to hacks\n uint256 limit;\n // Limit on the hourly volume of token minted through this bridge\n // Technically the limit over a rolling hour is hourlyLimit x2 as hourly limit\n // is enforced only between x:00 and x+1:00\n uint256 hourlyLimit;\n // Fee taken for swapping in and out the token\n uint64 fee;\n // Whether the associated token is allowed or not\n bool allowed;\n // Whether swapping in and out from the associated token is paused or not\n bool paused;\n }\n\n /// @notice Maps a bridge token to data\n mapping(address => BridgeDetails) public bridges;\n /// @notice List of all bridge tokens\n address[] public bridgeTokensList;\n /// @notice Maps a bridge token to the associated hourly volume\n mapping(address => mapping(uint256 => uint256)) public usage;\n /// @notice Maps an address to whether it is exempt of fees for when it comes to swapping in and out\n mapping(address => uint256) public isFeeExempt;\n /// @notice Limit to the amount of tokens that can be sent from that chain to another chain\n uint256 public chainTotalHourlyLimit;\n /// @notice Usage per hour on that chain. Maps an hourly timestamp to the total volume swapped out on the chain\n mapping(uint256 => uint256) public chainTotalUsage;\n\n // =================================== EVENTS ==================================\n\n event BridgeTokenAdded(address indexed bridgeToken, uint256 limit, uint256 hourlyLimit, uint64 fee, bool paused);\n event BridgeTokenToggled(address indexed bridgeToken, bool toggleStatus);\n event BridgeTokenRemoved(address indexed bridgeToken);\n event BridgeTokenFeeUpdated(address indexed bridgeToken, uint64 fee);\n event BridgeTokenLimitUpdated(address indexed bridgeToken, uint256 limit);\n event BridgeTokenHourlyLimitUpdated(address indexed bridgeToken, uint256 hourlyLimit);\n event HourlyLimitUpdated(uint256 hourlyLimit);\n event Recovered(address indexed token, address indexed to, uint256 amount);\n event FeeToggled(address indexed theAddress, uint256 toggleStatus);\n\n // =================================== ERRORS ==================================\n\n error AssetStillControlledInReserves();\n error HourlyLimitExceeded();\n error InvalidToken();\n error NotGovernor();\n error NotGovernorOrGuardian();\n error TooBigAmount();\n error TooHighParameterValue();\n error ZeroAddress();\n\n // ================================= MODIFIERS =================================\n\n /// @notice Checks whether the `msg.sender` has the governor role or not\n modifier onlyGovernor() {\n if (!ITreasury(treasury).isGovernor(msg.sender)) revert NotGovernor();\n _;\n }\n\n /// @notice Checks whether the `msg.sender` has the governor role or the guardian role\n modifier onlyGovernorOrGuardian() {\n if (!ITreasury(treasury).isGovernorOrGuardian(msg.sender)) revert NotGovernorOrGuardian();\n _;\n }\n\n // ===================== EXTERNAL PERMISSIONLESS FUNCTIONS =====================\n\n /// @notice Returns the list of all supported bridge tokens\n /// @dev Helpful for UIs\n function allBridgeTokens() external view returns (address[] memory) {\n return bridgeTokensList;\n }\n\n /// @notice Returns the current volume for a bridge, for the current hour\n /// @param bridgeToken Bridge used to mint\n /// @dev Helpful for UIs\n function currentUsage(address bridgeToken) external view returns (uint256) {\n return usage[bridgeToken][block.timestamp / 3600];\n }\n\n /// @notice Returns the current total volume on the chain for the current hour\n /// @dev Helpful for UIs\n function currentTotalUsage() external view returns (uint256) {\n return chainTotalUsage[block.timestamp / 3600];\n }\n\n /// @notice Mints the canonical token from a supported bridge token\n /// @param bridgeToken Bridge token to use to mint\n /// @param amount Amount of bridge tokens to send\n /// @param to Address to which the stablecoin should be sent\n /// @return Amount of the canonical stablecoin actually minted\n /// @dev Some fees may be taken by the protocol depending on the token used and on the address calling\n function swapIn(address bridgeToken, uint256 amount, address to) external returns (uint256) {\n BridgeDetails memory bridgeDetails = bridges[bridgeToken];\n if (!bridgeDetails.allowed || bridgeDetails.paused) revert InvalidToken();\n uint256 balance = IERC20(bridgeToken).balanceOf(address(this));\n if (balance + amount > bridgeDetails.limit) {\n // In case someone maliciously sends tokens to this contract\n // Or the limit changes\n if (bridgeDetails.limit > balance) amount = bridgeDetails.limit - balance;\n else {\n amount = 0;\n }\n }\n\n // Checking requirement on the hourly volume\n uint256 hour = block.timestamp / 3600;\n uint256 hourlyUsage = usage[bridgeToken][hour];\n if (hourlyUsage + amount > bridgeDetails.hourlyLimit) {\n // Edge case when the hourly limit changes\n amount = bridgeDetails.hourlyLimit > hourlyUsage ? bridgeDetails.hourlyLimit - hourlyUsage : 0;\n }\n usage[bridgeToken][hour] = hourlyUsage + amount;\n\n IERC20(bridgeToken).safeTransferFrom(msg.sender, address(this), amount);\n uint256 canonicalOut = amount;\n // Computing fees\n if (isFeeExempt[msg.sender] == 0) {\n canonicalOut -= (canonicalOut * bridgeDetails.fee) / BASE_PARAMS;\n }\n _mint(to, canonicalOut);\n return canonicalOut;\n }\n\n /// @notice Burns the canonical token in exchange for a bridge token\n /// @param bridgeToken Bridge token required\n /// @param amount Amount of canonical tokens to burn\n /// @param to Address to which the bridge token should be sent\n /// @return Amount of bridge tokens actually sent back\n /// @dev Some fees may be taken by the protocol depending on the token used and on the address calling\n function swapOut(address bridgeToken, uint256 amount, address to) external returns (uint256) {\n BridgeDetails memory bridgeDetails = bridges[bridgeToken];\n if (!bridgeDetails.allowed || bridgeDetails.paused) revert InvalidToken();\n\n uint256 hour = block.timestamp / 3600;\n uint256 hourlyUsage = chainTotalUsage[hour] + amount;\n // If the amount being swapped out exceeds the limit, we revert\n // We don't want to change the amount being swapped out.\n // The user can decide to send another tx with the correct amount to reach the limit\n if (hourlyUsage > chainTotalHourlyLimit) revert HourlyLimitExceeded();\n chainTotalUsage[hour] = hourlyUsage;\n\n _burn(msg.sender, amount);\n uint256 bridgeOut = amount;\n if (isFeeExempt[msg.sender] == 0) {\n bridgeOut -= (bridgeOut * bridgeDetails.fee) / BASE_PARAMS;\n }\n IERC20(bridgeToken).safeTransfer(to, bridgeOut);\n return bridgeOut;\n }\n\n // ============================ GOVERNANCE FUNCTIONS ===========================\n\n /// @notice Adds support for a bridge token\n /// @param bridgeToken Bridge token to add: it should be a version of the stablecoin from another bridge\n /// @param limit Limit on the balance of bridge token this contract could hold\n /// @param hourlyLimit Limit on the hourly volume for this bridge\n /// @param paused Whether swapping for this token should be paused or not\n /// @param fee Fee taken upon swapping for or against this token\n function addBridgeToken(\n address bridgeToken,\n uint256 limit,\n uint256 hourlyLimit,\n uint64 fee,\n bool paused\n ) external onlyGovernor {\n if (bridges[bridgeToken].allowed || bridgeToken == address(0)) revert InvalidToken();\n if (fee > BASE_PARAMS) revert TooHighParameterValue();\n BridgeDetails memory _bridge;\n _bridge.limit = limit;\n _bridge.hourlyLimit = hourlyLimit;\n _bridge.paused = paused;\n _bridge.fee = fee;\n _bridge.allowed = true;\n bridges[bridgeToken] = _bridge;\n bridgeTokensList.push(bridgeToken);\n emit BridgeTokenAdded(bridgeToken, limit, hourlyLimit, fee, paused);\n }\n\n /// @notice Removes support for a token\n /// @param bridgeToken Address of the bridge token to remove support for\n function removeBridgeToken(address bridgeToken) external onlyGovernor {\n if (IERC20(bridgeToken).balanceOf(address(this)) != 0) revert AssetStillControlledInReserves();\n delete bridges[bridgeToken];\n // Deletion from `bridgeTokensList` loop\n uint256 bridgeTokensListLength = bridgeTokensList.length;\n for (uint256 i; i < bridgeTokensListLength - 1; ++i) {\n if (bridgeTokensList[i] == bridgeToken) {\n // Replace the `bridgeToken` to remove with the last of the list\n bridgeTokensList[i] = bridgeTokensList[bridgeTokensListLength - 1];\n break;\n }\n }\n // Remove last element in array\n bridgeTokensList.pop();\n emit BridgeTokenRemoved(bridgeToken);\n }\n\n /// @notice Recovers any ERC20 token\n /// @dev Can be used to withdraw bridge tokens for them to be de-bridged on mainnet\n function recoverERC20(address tokenAddress, address to, uint256 amountToRecover) external onlyGovernor {\n IERC20(tokenAddress).safeTransfer(to, amountToRecover);\n emit Recovered(tokenAddress, to, amountToRecover);\n }\n\n /// @notice Updates the `limit` amount for `bridgeToken`\n function setLimit(address bridgeToken, uint256 limit) external onlyGovernorOrGuardian {\n if (!bridges[bridgeToken].allowed) revert InvalidToken();\n bridges[bridgeToken].limit = limit;\n emit BridgeTokenLimitUpdated(bridgeToken, limit);\n }\n\n /// @notice Updates the `hourlyLimit` amount for `bridgeToken`\n function setHourlyLimit(address bridgeToken, uint256 hourlyLimit) external onlyGovernorOrGuardian {\n if (!bridges[bridgeToken].allowed) revert InvalidToken();\n bridges[bridgeToken].hourlyLimit = hourlyLimit;\n emit BridgeTokenHourlyLimitUpdated(bridgeToken, hourlyLimit);\n }\n\n /// @notice Updates the `chainTotalHourlyLimit` amount\n function setChainTotalHourlyLimit(uint256 hourlyLimit) external onlyGovernorOrGuardian {\n chainTotalHourlyLimit = hourlyLimit;\n emit HourlyLimitUpdated(hourlyLimit);\n }\n\n /// @notice Updates the `fee` value for `bridgeToken`\n function setSwapFee(address bridgeToken, uint64 fee) external onlyGovernorOrGuardian {\n if (!bridges[bridgeToken].allowed) revert InvalidToken();\n if (fee > BASE_PARAMS) revert TooHighParameterValue();\n bridges[bridgeToken].fee = fee;\n emit BridgeTokenFeeUpdated(bridgeToken, fee);\n }\n\n /// @notice Pauses or unpauses swapping in and out for a token\n function toggleBridge(address bridgeToken) external onlyGovernorOrGuardian {\n if (!bridges[bridgeToken].allowed) revert InvalidToken();\n bool pausedStatus = bridges[bridgeToken].paused;\n bridges[bridgeToken].paused = !pausedStatus;\n emit BridgeTokenToggled(bridgeToken, !pausedStatus);\n }\n\n /// @notice Toggles fees for the address `theAddress`\n function toggleFeesForAddress(address theAddress) external onlyGovernorOrGuardian {\n uint256 feeExemptStatus = 1 - isFeeExempt[theAddress];\n isFeeExempt[theAddress] = feeExemptStatus;\n emit FeeToggled(theAddress, feeExemptStatus);\n }\n}\n" + }, + "contracts/agToken/layerZero/LayerZeroBridge.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.12;\n\nimport \"./utils/OFTCore.sol\";\nimport \"@openzeppelin/contracts-upgradeable/security/PausableUpgradeable.sol\";\nimport \"@openzeppelin/contracts/token/ERC20/extensions/draft-IERC20Permit.sol\";\n\n/// @title LayerZeroBridge\n/// @author Angle Labs, Inc., forked from https://github.com/LayerZero-Labs/solidity-examples/blob/main/contracts/token/oft/OFT.sol\n/// @notice Contract to be deployed on Ethereum for bridging an AgToken using a bridge intermediate token and LayerZero\ncontract LayerZeroBridge is OFTCore, PausableUpgradeable {\n /// @notice Name of the contract for indexing purposes\n string public name;\n\n /// @notice Address of the bridgeable token\n /// @dev Immutable\n IERC20 public canonicalToken;\n\n /// @notice Maps an address to the amount of token bridged but not received\n mapping(address => uint256) public balanceOf;\n\n // ================================ CONSTRUCTOR ================================\n /// @notice Initializes the contract\n /// @param _name Name of the token corresponding to this contract\n /// @param _lzEndpoint Layer zero endpoint to pass messages\n /// @param _treasury Address of the treasury contract used for access control\n function initialize(string memory _name, address _lzEndpoint, address _treasury) external initializer {\n __LzAppUpgradeable_init(_lzEndpoint, _treasury);\n name = _name;\n canonicalToken = IERC20(address(ITreasury(_treasury).stablecoin()));\n }\n\n /// @custom:oz-upgrades-unsafe-allow constructor\n constructor() initializer {}\n\n // ===================== EXTERNAL PERMISSIONLESS FUNCTIONS =====================\n\n /// @inheritdoc OFTCore\n function sendWithPermit(\n uint16 _dstChainId,\n bytes memory _toAddress,\n uint256 _amount,\n address payable _refundAddress,\n address _zroPaymentAddress,\n bytes memory _adapterParams,\n uint256 deadline,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) public payable override {\n IERC20Permit(address(canonicalToken)).permit(msg.sender, address(this), _amount, deadline, v, r, s);\n send(_dstChainId, _toAddress, _amount, _refundAddress, _zroPaymentAddress, _adapterParams);\n }\n\n /// @inheritdoc OFTCore\n function withdraw(uint256 amount, address recipient) external override returns (uint256) {\n return _withdraw(amount, msg.sender, recipient);\n }\n\n /// @notice Withdraws amount of `token` from the contract and sends it to the recipient\n /// @param amount Amount to withdraw\n /// @param recipient Address to withdraw for\n /// @return The amount of canonical token sent\n function withdrawFor(uint256 amount, address recipient) external returns (uint256) {\n return _withdraw(amount, recipient, recipient);\n }\n\n // ============================= INTERNAL FUNCTIONS ============================\n\n /// @notice Withdraws `amount` from the balance of the `from` address and sends these tokens to the `to` address\n /// @dev It's important to make sure that `from` is either the `msg.sender` or that `from` and `to` are the same\n /// addresses\n function _withdraw(uint256 amount, address from, address to) internal whenNotPaused returns (uint256) {\n balanceOf[from] -= amount; // Will overflow if the amount is too big\n canonicalToken.transfer(to, amount);\n return amount;\n }\n\n /// @inheritdoc OFTCore\n function _debitFrom(uint16, bytes memory, uint256 _amount) internal override whenNotPaused returns (uint256) {\n // No need to use safeTransferFrom as we know this implementation reverts on failure\n canonicalToken.transferFrom(msg.sender, address(this), _amount);\n return _amount;\n }\n\n /// @inheritdoc OFTCore\n function _debitCreditFrom(uint16, bytes memory, uint256 _amount) internal override whenNotPaused returns (uint256) {\n balanceOf[msg.sender] -= _amount;\n return _amount;\n }\n\n /// @inheritdoc OFTCore\n function _creditTo(uint16, address _toAddress, uint256 _amount) internal override whenNotPaused returns (uint256) {\n // Should never revert as all the LayerZero bridge tokens come from\n // this contract\n uint256 balance = canonicalToken.balanceOf(address(this));\n if (balance < _amount) {\n balanceOf[_toAddress] = _amount - balance;\n if (balance != 0) canonicalToken.transfer(_toAddress, balance);\n } else {\n canonicalToken.transfer(_toAddress, _amount);\n }\n return _amount;\n }\n\n // =============================== VIEW FUNCTIONS ==============================\n\n /// @inheritdoc ERC165Upgradeable\n function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {\n return interfaceId == type(IOFTCore).interfaceId || super.supportsInterface(interfaceId);\n }\n\n // ============================ GOVERNANCE FUNCTIONS ===========================\n\n /// @notice Pauses bridging through the contract\n /// @param pause Future pause status\n function pauseSendTokens(bool pause) external onlyGovernorOrGuardian {\n pause ? _pause() : _unpause();\n }\n\n /// @notice Decreases the balance of an address\n /// @param amount Amount to withdraw from balance\n /// @param recipient Address to withdraw from\n function sweep(uint256 amount, address recipient) external onlyGovernorOrGuardian {\n balanceOf[recipient] -= amount; // Will overflow if the amount is too big\n }\n\n uint256[47] private __gap;\n}\n" + }, + "contracts/agToken/layerZero/LayerZeroBridgeToken.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.12;\n\nimport \"./utils/OFTCore.sol\";\nimport \"../../interfaces/IAgTokenSideChainMultiBridge.sol\";\nimport \"@openzeppelin/contracts-upgradeable/security/PausableUpgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/token/ERC20/ERC20Upgradeable.sol\";\n\n/// @title LayerZeroBridgeToken\n/// @author Angle Labs, Inc., forked from https://github.com/LayerZero-Labs/solidity-examples/blob/main/contracts/token/oft/OFT.sol\n/// @notice Contract to be deployed on a L2/sidechain for bridging an AgToken using a bridge intermediate token and LayerZero\ncontract LayerZeroBridgeToken is OFTCore, ERC20Upgradeable, PausableUpgradeable {\n /// @notice Address of the bridgeable token\n /// @dev Immutable\n IAgTokenSideChainMultiBridge public canonicalToken;\n\n // =================================== ERROR ===================================\n\n error InvalidAllowance();\n\n // ================================ CONSTRUCTOR ================================\n\n /// @notice Initializes the contract\n /// @param _name Name of the token corresponding to this contract\n /// @param _symbol Symbol of the token corresponding to this contract\n /// @param _lzEndpoint Layer zero endpoint to pass messages\n /// @param _treasury Address of the treasury contract used for access control\n /// @param initialSupply Initial supply to mint to the canonical token address\n /// @dev The initial supply corresponds to the initial amount that could be bridged using this OFT\n function initialize(\n string memory _name,\n string memory _symbol,\n address _lzEndpoint,\n address _treasury,\n uint256 initialSupply\n ) external initializer {\n __ERC20_init_unchained(_name, _symbol);\n __LzAppUpgradeable_init(_lzEndpoint, _treasury);\n\n canonicalToken = IAgTokenSideChainMultiBridge(address(ITreasury(_treasury).stablecoin()));\n _approve(address(this), address(canonicalToken), type(uint256).max);\n _mint(address(canonicalToken), initialSupply);\n }\n\n /// @custom:oz-upgrades-unsafe-allow constructor\n constructor() initializer {}\n\n // ===================== EXTERNAL PERMISSIONLESS FUNCTIONS =====================\n\n /// @inheritdoc OFTCore\n function sendWithPermit(\n uint16 _dstChainId,\n bytes memory _toAddress,\n uint256 _amount,\n address payable _refundAddress,\n address _zroPaymentAddress,\n bytes memory _adapterParams,\n uint256 deadline,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) public payable override {\n canonicalToken.permit(msg.sender, address(this), _amount, deadline, v, r, s);\n send(_dstChainId, _toAddress, _amount, _refundAddress, _zroPaymentAddress, _adapterParams);\n }\n\n /// @inheritdoc OFTCore\n function withdraw(uint256 amount, address recipient) external override returns (uint256 amountMinted) {\n // Does not check allowances as transfers from `msg.sender`\n _transfer(msg.sender, address(this), amount);\n amountMinted = canonicalToken.swapIn(address(this), amount, recipient);\n uint256 leftover = balanceOf(address(this));\n if (leftover != 0) {\n _transfer(address(this), msg.sender, leftover);\n }\n }\n\n // ============================= INTERNAL FUNCTIONS ============================\n\n /// @inheritdoc OFTCore\n function _debitFrom(\n uint16,\n bytes memory,\n uint256 _amount\n ) internal override whenNotPaused returns (uint256 amountSwapped) {\n // No need to use safeTransferFrom as we know this implementation reverts on failure\n canonicalToken.transferFrom(msg.sender, address(this), _amount);\n\n // Swap canonical for this bridge token. There may be some fees\n amountSwapped = canonicalToken.swapOut(address(this), _amount, address(this));\n _burn(address(this), amountSwapped);\n }\n\n /// @inheritdoc OFTCore\n function _debitCreditFrom(uint16, bytes memory, uint256 _amount) internal override whenNotPaused returns (uint256) {\n _burn(msg.sender, _amount);\n return _amount;\n }\n\n /// @inheritdoc OFTCore\n function _creditTo(\n uint16,\n address _toAddress,\n uint256 _amount\n ) internal override whenNotPaused returns (uint256 amountMinted) {\n _mint(address(this), _amount);\n amountMinted = canonicalToken.swapIn(address(this), _amount, _toAddress);\n uint256 leftover = balanceOf(address(this));\n if (leftover != 0) {\n _transfer(address(this), _toAddress, leftover);\n }\n }\n\n // =============================== VIEW FUNCTIONS ==============================\n\n /// @inheritdoc ERC165Upgradeable\n function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {\n return\n interfaceId == type(IOFT).interfaceId ||\n interfaceId == type(IERC20).interfaceId ||\n super.supportsInterface(interfaceId);\n }\n\n // ============================ GOVERNANCE FUNCTIONS ===========================\n\n /// @notice Mints the intermediate contract to the `canonicalToken`\n /// @dev Used to increase the bridging capacity\n function mint(uint256 amount) external onlyGovernorOrGuardian {\n _mint(address(canonicalToken), amount);\n }\n\n /// @notice Burns the intermediate contract from the `canonicalToken`\n /// @dev Used to decrease the bridging capacity\n function burn(uint256 amount) external onlyGovernorOrGuardian {\n _burn(address(canonicalToken), amount);\n }\n\n /// @notice Increases allowance of the `canonicalToken`\n function setupAllowance() public onlyGovernorOrGuardian {\n _approve(address(this), address(canonicalToken), type(uint256).max);\n }\n\n /// @notice Pauses bridging through the contract\n /// @param pause Future pause status\n function pauseSendTokens(bool pause) external onlyGovernorOrGuardian {\n pause ? _pause() : _unpause();\n }\n\n uint256[49] private __gap;\n}\n" + }, + "contracts/agToken/layerZero/utils/IOFTCore.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.12;\n\nimport \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\nimport \"@openzeppelin/contracts/utils/introspection/IERC165.sol\";\n\n/**\n * @dev Interface of the IOFT core standard\n * @dev Forked from https://github.com/LayerZero-Labs/solidity-examples/blob/main/contracts/token/oft/IOFTCore.sol\n */\ninterface IOFTCore is IERC165 {\n /// @notice Estimates send token `_tokenId` to (`_dstChainId`, `_toAddress`)\n /// @param _dstChainId L0 defined chain id to send tokens too\n /// @param _toAddress dynamic bytes array which contains the address to whom you are sending tokens to on the dstChain\n /// @param _amount amount of the tokens to transfer\n /// @param _useZro indicates to use zro to pay L0 fees\n /// @param _adapterParams flexible bytes array to indicate messaging adapter services in L0\n function estimateSendFee(\n uint16 _dstChainId,\n bytes calldata _toAddress,\n uint256 _amount,\n bool _useZro,\n bytes calldata _adapterParams\n ) external view returns (uint256 nativeFee, uint256 zroFee);\n\n /// @notice Sends `_amount` amount of token to (`_dstChainId`, `_toAddress`)\n /// @param _dstChainId the destination chain identifier\n /// @param _toAddress can be any size depending on the `dstChainId`.\n /// @param _amount the quantity of tokens in wei\n /// @param _refundAddress the address LayerZero refunds if too much message fee is sent\n /// @param _zroPaymentAddress set to address(0x0) if not paying in ZRO (LayerZero Token)\n /// @param _adapterParams is a flexible bytes array to indicate messaging adapter services\n function send(\n uint16 _dstChainId,\n bytes calldata _toAddress,\n uint256 _amount,\n address payable _refundAddress,\n address _zroPaymentAddress,\n bytes calldata _adapterParams\n ) external payable;\n\n /// @notice Sends `_amount` amount of credit to (`_dstChainId`, `_toAddress`)\n /// @param _dstChainId the destination chain identifier\n /// @param _toAddress can be any size depending on the `dstChainId`.\n /// @param _amount the quantity of credit to send in wei\n /// @param _refundAddress the address LayerZero refunds if too much message fee is sent\n /// @param _zroPaymentAddress set to address(0x0) if not paying in ZRO (LayerZero Token)\n /// @param _adapterParams is a flexible bytes array to indicate messaging adapter services\n function sendCredit(\n uint16 _dstChainId,\n bytes calldata _toAddress,\n uint256 _amount,\n address payable _refundAddress,\n address _zroPaymentAddress,\n bytes calldata _adapterParams\n ) external payable;\n\n /// @notice Sends `_amount` amount of token to (`_dstChainId`, `_toAddress`)\n /// @param _dstChainId The destination chain identifier\n /// @param _toAddress Can be any size depending on the `dstChainId`.\n /// @param _amount Quantity of tokens in wei\n /// @param _refundAddress Address LayerZero refunds if too much message fee is sent\n /// @param _zroPaymentAddress Set to address(0x0) if not paying in ZRO (LayerZero Token)\n /// @param _adapterParams Flexible bytes array to indicate messaging adapter services\n /// @param deadline Deadline parameter for the signature to be valid\n /// @dev The `v`, `r`, and `s` parameters are used as signature data\n function sendWithPermit(\n uint16 _dstChainId,\n bytes memory _toAddress,\n uint256 _amount,\n address payable _refundAddress,\n address _zroPaymentAddress,\n bytes memory _adapterParams,\n uint256 deadline,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) external payable;\n\n /// @notice Withdraws amount of canonical token from the `msg.sender` balance and sends it to the recipient\n /// @param amount Amount to withdraw\n /// @param recipient Address to send the canonical token to\n /// @return The amount of canonical token sent\n function withdraw(uint256 amount, address recipient) external returns (uint256);\n\n /// @dev Emitted when `_amount` tokens are moved from the `_sender` to (`_dstChainId`, `_toAddress`)\n /// `_nonce` is the outbound nonce\n event SendToChain(\n address indexed _sender,\n uint16 indexed _dstChainId,\n bytes indexed _toAddress,\n uint256 _amount,\n uint64 _nonce\n );\n\n /// @dev Emitted when `_amount` tokens are received from `_srcChainId` into the `_toAddress` on the local chain.\n /// `_nonce` is the inbound nonce.\n event ReceiveFromChain(\n uint16 indexed _srcChainId,\n bytes indexed _srcAddress,\n address indexed _toAddress,\n uint256 _amount,\n uint64 _nonce\n );\n}\n\n/// @dev Interface of the OFT standard\ninterface IOFT is IOFTCore, IERC20 {\n\n}\n" + }, + "contracts/agToken/layerZero/utils/NonblockingLzApp.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.12;\n\nimport \"@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol\";\nimport \"../../../interfaces/external/layerZero/ILayerZeroReceiver.sol\";\nimport \"../../../interfaces/external/layerZero/ILayerZeroUserApplicationConfig.sol\";\nimport \"../../../interfaces/external/layerZero/ILayerZeroEndpoint.sol\";\nimport \"../../../interfaces/ITreasury.sol\";\n\n/// @title NonblockingLzApp\n/// @author Angle Labs, Inc., forked from https://github.com/LayerZero-Labs/solidity-examples/\n/// @notice Base contract for bridging using LayerZero\nabstract contract NonblockingLzApp is Initializable, ILayerZeroReceiver, ILayerZeroUserApplicationConfig {\n /// @notice Layer Zero endpoint\n ILayerZeroEndpoint public lzEndpoint;\n\n /// @notice Maps chainIds to failed messages to retry them\n mapping(uint16 => mapping(bytes => mapping(uint64 => bytes32))) public failedMessages;\n\n /// @notice Maps chainIds to their OFT address\n mapping(uint16 => bytes) public trustedRemoteLookup;\n\n /// @notice Reference to the treasury contract to fetch access control\n address public treasury;\n\n /// @notice Maps pairs of (`to` chain, `packetType`) to the minimum amount of gas needed on the destination chain\n mapping(uint16 => mapping(uint16 => uint256)) public minDstGasLookup;\n\n /// @notice For future LayerZero compatibility\n address public precrime;\n\n // ================================== Events ===================================\n\n event SetTrustedRemote(uint16 _srcChainId, bytes _srcAddress);\n event MessageFailed(uint16 _srcChainId, bytes _srcAddress, uint64 _nonce, bytes _payload);\n\n // =============================== Errors ================================\n\n error NotGovernor();\n error NotGovernorOrGuardian();\n error InsufficientGas();\n error InvalidEndpoint();\n error InvalidSource();\n error InvalidCaller();\n error InvalidParams();\n error InvalidPayload();\n error ZeroAddress();\n\n // ============================= Constructor ===================================\n\n //solhint-disable-next-line\n function __LzAppUpgradeable_init(address _endpoint, address _treasury) internal {\n if (_endpoint == address(0) || _treasury == address(0)) revert ZeroAddress();\n lzEndpoint = ILayerZeroEndpoint(_endpoint);\n treasury = _treasury;\n }\n\n // =============================== Modifiers ===================================\n\n /// @notice Checks whether the `msg.sender` has the governor role or the guardian role\n modifier onlyGovernorOrGuardian() {\n if (!ITreasury(treasury).isGovernorOrGuardian(msg.sender)) revert NotGovernorOrGuardian();\n _;\n }\n\n // ==================== External Permissionless Functions ======================\n\n /// @notice Receives a message from the LZ endpoint and process it\n /// @param _srcChainId ChainId of the source chain - LayerZero standard\n /// @param _srcAddress Sender of the source chain\n /// @param _nonce Nounce of the message\n /// @param _payload Data: recipient address and amount\n function lzReceive(\n uint16 _srcChainId,\n bytes memory _srcAddress,\n uint64 _nonce,\n bytes memory _payload\n ) public virtual override {\n // lzReceive must be called by the endpoint for security\n if (msg.sender != address(lzEndpoint)) revert InvalidEndpoint();\n\n bytes memory trustedRemote = trustedRemoteLookup[_srcChainId];\n // if will still block the message pathway from (srcChainId, srcAddress). should not receive message from untrusted remote.\n if (_srcAddress.length != trustedRemote.length || keccak256(_srcAddress) != keccak256(trustedRemote))\n revert InvalidSource();\n\n _blockingLzReceive(_srcChainId, _srcAddress, _nonce, _payload);\n }\n\n /// @notice Retries a message that previously failed and was stored\n /// @param _srcChainId ChainId of the source chain - LayerZero standard\n /// @param _srcAddress Sender of the source chain\n /// @param _nonce Nounce of the message\n /// @param _payload Data: recipient address and amount\n function retryMessage(\n uint16 _srcChainId,\n bytes memory _srcAddress,\n uint64 _nonce,\n bytes memory _payload\n ) public payable virtual {\n // assert there is message to retry\n bytes32 payloadHash = failedMessages[_srcChainId][_srcAddress][_nonce];\n if (payloadHash == bytes32(0) || keccak256(_payload) != payloadHash) revert InvalidPayload();\n // clear the stored message\n failedMessages[_srcChainId][_srcAddress][_nonce] = bytes32(0);\n // execute the message. revert if it fails again\n _nonblockingLzReceive(_srcChainId, _srcAddress, _nonce, _payload);\n }\n\n // ============================= Internal Functions ===================================\n\n /// @notice Handles message receptions in a non blocking way\n /// @param _srcChainId ChainId of the source chain - LayerZero standard\n /// @param _srcAddress Sender of the source chain\n /// @param _nonce Nounce of the message\n /// @param _payload Data: recipient address and amount\n /// @dev public for the needs of try / catch but effectively internal\n function nonblockingLzReceive(\n uint16 _srcChainId,\n bytes memory _srcAddress,\n uint64 _nonce,\n bytes memory _payload\n ) public virtual {\n // only internal transaction\n if (msg.sender != address(this)) revert InvalidCaller();\n _nonblockingLzReceive(_srcChainId, _srcAddress, _nonce, _payload);\n }\n\n /// @notice Handles message receptions in a non blocking way\n /// @param _srcChainId ChainId of the source chain - LayerZero standard\n /// @param _srcAddress Sender of the source chain\n /// @param _nonce Nounce of the message\n /// @param _payload Data: recipient address and amount\n function _nonblockingLzReceive(\n uint16 _srcChainId,\n bytes memory _srcAddress,\n uint64 _nonce,\n bytes memory _payload\n ) internal virtual;\n\n /// @notice Handles message receptions in a blocking way\n /// @param _srcChainId ChainId of the source chain - LayerZero standard\n /// @param _srcAddress Sender of the source chain\n /// @param _nonce Nounce of the message\n /// @param _payload Data: recipient address and amount\n function _blockingLzReceive(\n uint16 _srcChainId,\n bytes memory _srcAddress,\n uint64 _nonce,\n bytes memory _payload\n ) internal {\n // try-catch all errors/exceptions\n try this.nonblockingLzReceive(_srcChainId, _srcAddress, _nonce, _payload) {\n // do nothing\n } catch {\n // error / exception\n failedMessages[_srcChainId][_srcAddress][_nonce] = keccak256(_payload);\n emit MessageFailed(_srcChainId, _srcAddress, _nonce, _payload);\n }\n }\n\n /// @notice Sends a message to the LZ endpoint and process it\n /// @param _dstChainId L0 defined chain id to send tokens too\n /// @param _payload Data: recipient address and amount\n /// @param _refundAddress Address LayerZero refunds if too much message fee is sent\n /// @param _zroPaymentAddress Set to address(0x0) if not paying in ZRO (LayerZero Token)\n /// @param _adapterParams Flexible bytes array to indicate messaging adapter services in L0\n function _lzSend(\n uint16 _dstChainId,\n bytes memory _payload,\n address payable _refundAddress,\n address _zroPaymentAddress,\n bytes memory _adapterParams\n ) internal virtual {\n bytes memory trustedRemote = trustedRemoteLookup[_dstChainId];\n if (trustedRemote.length == 0) revert InvalidSource();\n //solhint-disable-next-line\n lzEndpoint.send{ value: msg.value }(\n _dstChainId,\n trustedRemote,\n _payload,\n _refundAddress,\n _zroPaymentAddress,\n _adapterParams\n );\n }\n\n /// @notice Checks the gas limit of a given transaction\n function _checkGasLimit(\n uint16 _dstChainId,\n uint16 _type,\n bytes memory _adapterParams,\n uint256 _extraGas\n ) internal view virtual {\n uint256 minGasLimit = minDstGasLookup[_dstChainId][_type] + _extraGas;\n if (minGasLimit == 0 || minGasLimit > _getGasLimit(_adapterParams)) revert InsufficientGas();\n }\n\n /// @notice Gets the gas limit from the `_adapterParams` parameter\n function _getGasLimit(bytes memory _adapterParams) internal pure virtual returns (uint256 gasLimit) {\n if (_adapterParams.length < 34) revert InvalidParams();\n // solhint-disable-next-line\n assembly {\n gasLimit := mload(add(_adapterParams, 34))\n }\n }\n\n // ======================= Governance Functions ================================\n\n /// @notice Sets the corresponding address on an other chain.\n /// @param _srcChainId ChainId of the source chain - LayerZero standard\n /// @param _srcAddress Address on the source chain\n /// @dev Used for both receiving and sending message\n /// @dev There can only be one trusted source per chain\n /// @dev Allows owner to set it multiple times.\n function setTrustedRemote(uint16 _srcChainId, bytes calldata _srcAddress) external onlyGovernorOrGuardian {\n trustedRemoteLookup[_srcChainId] = _srcAddress;\n emit SetTrustedRemote(_srcChainId, _srcAddress);\n }\n\n /// @notice Fetches the default LZ config\n function getConfig(\n uint16 _version,\n uint16 _chainId,\n address,\n uint256 _configType\n ) external view returns (bytes memory) {\n return lzEndpoint.getConfig(_version, _chainId, address(this), _configType);\n }\n\n /// @notice Overrides the default LZ config\n function setConfig(\n uint16 _version,\n uint16 _chainId,\n uint256 _configType,\n bytes calldata _config\n ) external override onlyGovernorOrGuardian {\n lzEndpoint.setConfig(_version, _chainId, _configType, _config);\n }\n\n /// @notice Overrides the default LZ config\n function setSendVersion(uint16 _version) external override onlyGovernorOrGuardian {\n lzEndpoint.setSendVersion(_version);\n }\n\n /// @notice Overrides the default LZ config\n function setReceiveVersion(uint16 _version) external override onlyGovernorOrGuardian {\n lzEndpoint.setReceiveVersion(_version);\n }\n\n /// @notice Unpauses the receive functionalities\n function forceResumeReceive(\n uint16 _srcChainId,\n bytes calldata _srcAddress\n ) external override onlyGovernorOrGuardian {\n lzEndpoint.forceResumeReceive(_srcChainId, _srcAddress);\n }\n\n /// @notice Sets the minimum gas parameter for a packet type on a given chain\n function setMinDstGas(uint16 _dstChainId, uint16 _packetType, uint256 _minGas) external onlyGovernorOrGuardian {\n if (_minGas == 0) revert InvalidParams();\n minDstGasLookup[_dstChainId][_packetType] = _minGas;\n }\n\n /// @notice Sets the precrime variable\n function setPrecrime(address _precrime) external onlyGovernorOrGuardian {\n precrime = _precrime;\n }\n\n // ======================= View Functions ================================\n\n /// @notice Checks if the `_srcAddress` corresponds to the trusted source\n function isTrustedRemote(uint16 _srcChainId, bytes calldata _srcAddress) external view returns (bool) {\n bytes memory trustedSource = trustedRemoteLookup[_srcChainId];\n return keccak256(trustedSource) == keccak256(_srcAddress);\n }\n\n uint256[44] private __gap;\n}\n" + }, + "contracts/agToken/layerZero/utils/OFTCore.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.12;\n\nimport \"./NonblockingLzApp.sol\";\nimport \"./IOFTCore.sol\";\nimport \"@openzeppelin/contracts-upgradeable/utils/introspection/ERC165Upgradeable.sol\";\n\n/// @title OFTCore\n/// @author Forked from https://github.com/LayerZero-Labs/solidity-examples/blob/main/contracts/token/oft/OFTCore.sol\n/// but with slight modifications from the Angle Labs, Inc. which added return values to the `_creditTo` and `_debitFrom` functions\n/// @notice Base contract for bridging using LayerZero\nabstract contract OFTCore is NonblockingLzApp, ERC165Upgradeable, IOFTCore {\n /// @notice Amount of additional gas specified\n uint256 public constant EXTRA_GAS = 200000;\n /// @notice Packet type for token transfer\n uint16 public constant PT_SEND = 0;\n\n /// @notice Whether to use custom parameters in transactions\n uint8 public useCustomAdapterParams;\n\n // ==================== External Permissionless Functions ======================\n\n /// @inheritdoc IOFTCore\n function sendWithPermit(\n uint16 _dstChainId,\n bytes memory _toAddress,\n uint256 _amount,\n address payable _refundAddress,\n address _zroPaymentAddress,\n bytes memory _adapterParams,\n uint256 deadline,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) public payable virtual;\n\n /// @inheritdoc IOFTCore\n function send(\n uint16 _dstChainId,\n bytes memory _toAddress,\n uint256 _amount,\n address payable _refundAddress,\n address _zroPaymentAddress,\n bytes memory _adapterParams\n ) public payable virtual {\n _checkAdapterParams(_dstChainId, PT_SEND, _adapterParams, EXTRA_GAS);\n _amount = _debitFrom(_dstChainId, _toAddress, _amount);\n\n bytes memory payload = abi.encode(_toAddress, _amount);\n _lzSend(_dstChainId, payload, _refundAddress, _zroPaymentAddress, _adapterParams);\n\n uint64 nonce = lzEndpoint.getOutboundNonce(_dstChainId, address(this));\n emit SendToChain(msg.sender, _dstChainId, _toAddress, _amount, nonce);\n }\n\n /// @inheritdoc IOFTCore\n function sendCredit(\n uint16 _dstChainId,\n bytes memory _toAddress,\n uint256 _amount,\n address payable _refundAddress,\n address _zroPaymentAddress,\n bytes memory _adapterParams\n ) public payable virtual {\n _checkAdapterParams(_dstChainId, PT_SEND, _adapterParams, EXTRA_GAS);\n _amount = _debitCreditFrom(_dstChainId, _toAddress, _amount);\n\n _send(_dstChainId, _toAddress, _amount, _refundAddress, _zroPaymentAddress, _adapterParams);\n }\n\n /// @inheritdoc IOFTCore\n function withdraw(uint256 amount, address recipient) external virtual returns (uint256);\n\n /// @notice Sets whether custom adapter parameters can be used or not\n function setUseCustomAdapterParams(uint8 _useCustomAdapterParams) public virtual onlyGovernorOrGuardian {\n useCustomAdapterParams = _useCustomAdapterParams;\n }\n\n // =========================== Internal Functions ==============================\n\n /// @notice Internal function to send `_amount` amount of token to (`_dstChainId`, `_toAddress`)\n /// @param _dstChainId the destination chain identifier\n /// @param _toAddress can be any size depending on the `dstChainId`.\n /// @param _amount the quantity of tokens in wei\n /// @param _refundAddress the address LayerZero refunds if too much message fee is sent\n /// @param _zroPaymentAddress set to address(0x0) if not paying in ZRO (LayerZero Token)\n /// @param _adapterParams is a flexible bytes array to indicate messaging adapter services\n /// @dev Accounting and checks should be performed beforehand\n function _send(\n uint16 _dstChainId,\n bytes memory _toAddress,\n uint256 _amount,\n address payable _refundAddress,\n address _zroPaymentAddress,\n bytes memory _adapterParams\n ) internal {\n bytes memory payload = abi.encode(_toAddress, _amount);\n _lzSend(_dstChainId, payload, _refundAddress, _zroPaymentAddress, _adapterParams);\n\n uint64 nonce = lzEndpoint.getOutboundNonce(_dstChainId, address(this));\n emit SendToChain(msg.sender, _dstChainId, _toAddress, _amount, nonce);\n }\n\n /// @inheritdoc NonblockingLzApp\n function _nonblockingLzReceive(\n uint16 _srcChainId,\n bytes memory _srcAddress,\n uint64 _nonce,\n bytes memory _payload\n ) internal virtual override {\n // decode and load the toAddress\n (bytes memory toAddressBytes, uint256 amount) = abi.decode(_payload, (bytes, uint256));\n address toAddress;\n //solhint-disable-next-line\n assembly {\n toAddress := mload(add(toAddressBytes, 20))\n }\n amount = _creditTo(_srcChainId, toAddress, amount);\n\n emit ReceiveFromChain(_srcChainId, _srcAddress, toAddress, amount, _nonce);\n }\n\n /// @notice Checks the adapter parameters given during the smart contract call\n function _checkAdapterParams(\n uint16 _dstChainId,\n uint16 _pkType,\n bytes memory _adapterParams,\n uint256 _extraGas\n ) internal virtual {\n if (useCustomAdapterParams > 0) _checkGasLimit(_dstChainId, _pkType, _adapterParams, _extraGas);\n else if (_adapterParams.length != 0) revert InvalidParams();\n }\n\n /// @notice Makes accountability when bridging from this contract using canonical token\n /// @param _dstChainId ChainId of the destination chain - LayerZero standard\n /// @param _toAddress Recipient on the destination chain\n /// @param _amount Amount to bridge\n function _debitFrom(\n uint16 _dstChainId,\n bytes memory _toAddress,\n uint256 _amount\n ) internal virtual returns (uint256);\n\n /// @notice Makes accountability when bridging from this contract's credit\n /// @param _dstChainId ChainId of the destination chain - LayerZero standard\n /// @param _toAddress Recipient on the destination chain\n /// @param _amount Amount to bridge\n function _debitCreditFrom(\n uint16 _dstChainId,\n bytes memory _toAddress,\n uint256 _amount\n ) internal virtual returns (uint256);\n\n /// @notice Makes accountability when bridging to this contract\n /// @param _srcChainId ChainId of the source chain - LayerZero standard\n /// @param _toAddress Recipient on this chain\n /// @param _amount Amount to bridge\n function _creditTo(uint16 _srcChainId, address _toAddress, uint256 _amount) internal virtual returns (uint256);\n\n // ========================== View Functions ===================================\n\n /// @inheritdoc ERC165Upgradeable\n function supportsInterface(\n bytes4 interfaceId\n ) public view virtual override(ERC165Upgradeable, IERC165) returns (bool) {\n return interfaceId == type(IOFTCore).interfaceId || super.supportsInterface(interfaceId);\n }\n\n /// @inheritdoc IOFTCore\n function estimateSendFee(\n uint16 _dstChainId,\n bytes memory _toAddress,\n uint256 _amount,\n bool _useZro,\n bytes memory _adapterParams\n ) public view virtual override returns (uint256 nativeFee, uint256 zroFee) {\n // mock the payload for send()\n bytes memory payload = abi.encode(_toAddress, _amount);\n return lzEndpoint.estimateFees(_dstChainId, address(this), payload, _useZro, _adapterParams);\n }\n\n uint256[49] private __gap;\n}\n" + }, + "contracts/agToken/polygon/TokenPolygonUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.12;\n\nimport \"./utils/ERC20UpgradeableCustom.sol\";\nimport \"@openzeppelin/contracts-upgradeable/access/AccessControlUpgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/utils/cryptography/draft-EIP712Upgradeable.sol\";\nimport \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\nimport \"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\";\n\nimport \"../../interfaces/IAgToken.sol\";\nimport \"../../interfaces/ITreasury.sol\";\n\ninterface IChildToken {\n function deposit(address user, bytes calldata depositData) external;\n\n function withdraw(uint256 amount) external;\n}\n\ncontract TokenPolygonUpgradeable is\n Initializable,\n ERC20UpgradeableCustom,\n AccessControlUpgradeable,\n EIP712Upgradeable,\n IChildToken\n{\n bytes32 public constant DEPOSITOR_ROLE = keccak256(\"DEPOSITOR_ROLE\");\n\n /// @dev Emitted when the child chain manager changes\n event ChildChainManagerAdded(address newAddress);\n event ChildChainManagerRevoked(address oldAddress);\n\n constructor() initializer {}\n\n function initialize(\n string memory _name,\n string memory _symbol,\n address childChainManager,\n address guardian\n ) public initializer {\n __ERC20_init(_name, _symbol);\n __AccessControl_init();\n _setupRole(DEFAULT_ADMIN_ROLE, guardian);\n _setupRole(DEPOSITOR_ROLE, childChainManager);\n __EIP712_init(_name, \"1\");\n }\n\n /**\n * @notice Called when the bridge has tokens to mint\n * @param user Address to mint the token to\n * @param depositData Encoded amount to mint\n */\n function deposit(address user, bytes calldata depositData) external override {\n require(hasRole(DEPOSITOR_ROLE, msg.sender));\n uint256 amount = abi.decode(depositData, (uint256));\n _mint(user, amount);\n }\n\n /**\n * @notice Called when user wants to withdraw tokens back to root chain\n * @dev Should burn user's tokens. This transaction will be verified when exiting on root chain\n * @param amount Amount of tokens to withdraw\n */\n function withdraw(uint256 amount) external override {\n _burn(_msgSender(), amount);\n }\n\n // =============================================================================\n // ======================= New data added for the upgrade ======================\n // =============================================================================\n\n mapping(address => bool) public isMinter;\n /// @notice Reference to the treasury contract which can grant minting rights\n address public treasury;\n /// @notice Boolean to check whether the contract has been reinitialized after its upgrade\n bool public treasuryInitialized;\n\n using SafeERC20 for IERC20;\n\n /// @notice Base used for fee computation\n uint256 public constant BASE_PARAMS = 10 ** 9;\n\n // =============================== Bridging Data ===============================\n\n /// @notice Struct with some data about a specific bridge token\n struct BridgeDetails {\n // Limit on the balance of bridge token held by the contract: it is designed\n // to reduce the exposure of the system to hacks\n uint256 limit;\n // Limit on the hourly volume of token minted through this bridge\n // Technically the limit over a rolling hour is hourlyLimit x2 as hourly limit\n // is enforced only between x:00 and x+1:00\n uint256 hourlyLimit;\n // Fee taken for swapping in and out the token\n uint64 fee;\n // Whether the associated token is allowed or not\n bool allowed;\n // Whether swapping in and out from the associated token is paused or not\n bool paused;\n }\n\n /// @notice Maps a bridge token to data\n mapping(address => BridgeDetails) public bridges;\n /// @notice List of all bridge tokens\n address[] public bridgeTokensList;\n /// @notice Maps a bridge token to the associated hourly volume\n mapping(address => mapping(uint256 => uint256)) public usage;\n /// @notice Maps an address to whether it is exempt of fees for when it comes to swapping in and out\n mapping(address => uint256) public isFeeExempt;\n /// @notice Limit to the amount of tokens that can be sent from that chain to another chain\n uint256 public chainTotalHourlyLimit;\n /// @notice Usage per hour on that chain. Maps an hourly timestamp to the total volume swapped out on the chain\n mapping(uint256 => uint256) public chainTotalUsage;\n\n uint256[42] private __gap;\n\n // ================================== Events ===================================\n\n event BridgeTokenAdded(address indexed bridgeToken, uint256 limit, uint256 hourlyLimit, uint64 fee, bool paused);\n event BridgeTokenToggled(address indexed bridgeToken, bool toggleStatus);\n event BridgeTokenRemoved(address indexed bridgeToken);\n event BridgeTokenFeeUpdated(address indexed bridgeToken, uint64 fee);\n event BridgeTokenLimitUpdated(address indexed bridgeToken, uint256 limit);\n event BridgeTokenHourlyLimitUpdated(address indexed bridgeToken, uint256 hourlyLimit);\n event HourlyLimitUpdated(uint256 hourlyLimit);\n event FeeToggled(address indexed theAddress, uint256 toggleStatus);\n event KeeperToggled(address indexed keeper, bool toggleStatus);\n event MinterToggled(address indexed minter);\n event Recovered(address indexed token, address indexed to, uint256 amount);\n event TreasuryUpdated(address indexed _treasury);\n\n // ================================== Errors ===================================\n\n error AssetStillControlledInReserves();\n error BurnAmountExceedsAllowance();\n error HourlyLimitExceeded();\n error InvalidSender();\n error InvalidToken();\n error InvalidTreasury();\n error NotGovernor();\n error NotGovernorOrGuardian();\n error NotMinter();\n error NotTreasury();\n error TooBigAmount();\n error TooHighParameterValue();\n error TreasuryAlreadyInitialized();\n error ZeroAddress();\n\n /// @notice Checks to see if it is the `Treasury` calling this contract\n /// @dev There is no Access Control here, because it can be handled cheaply through this modifier\n modifier onlyTreasury() {\n if (msg.sender != treasury) revert NotTreasury();\n _;\n }\n\n /// @notice Checks whether the sender has the minting right\n modifier onlyMinter() {\n if (!isMinter[msg.sender]) revert NotMinter();\n _;\n }\n\n /// @notice Checks whether the `msg.sender` has the governor role or not\n modifier onlyGovernor() {\n if (!ITreasury(treasury).isGovernor(msg.sender)) revert NotGovernor();\n _;\n }\n\n /// @notice Checks whether the `msg.sender` has the governor role or the guardian role\n modifier onlyGovernorOrGuardian() {\n if (!ITreasury(treasury).isGovernorOrGuardian(msg.sender)) revert NotGovernorOrGuardian();\n _;\n }\n\n /// @notice Sets up the treasury contract on Polygon after the upgrade\n /// @param _treasury Address of the treasury contract\n function setUpTreasury(address _treasury) external {\n // Only governor on Polygon\n if (msg.sender != 0xdA2D2f638D6fcbE306236583845e5822554c02EA) revert NotGovernor();\n if (address(ITreasury(_treasury).stablecoin()) != address(this)) revert InvalidTreasury();\n if (treasuryInitialized) revert TreasuryAlreadyInitialized();\n treasury = _treasury;\n treasuryInitialized = true;\n emit TreasuryUpdated(_treasury);\n }\n\n // =========================== External Function ===============================\n\n /// @notice Allows anyone to burn agToken without redeeming collateral back\n /// @param amount Amount of stablecoins to burn\n /// @dev This function can typically be called if there is a settlement mechanism to burn stablecoins\n function burnStablecoin(uint256 amount) external {\n _burnCustom(msg.sender, amount);\n }\n\n // ======================= Minter Role Only Functions ==========================\n\n function burnSelf(uint256 amount, address burner) external onlyMinter {\n _burnCustom(burner, amount);\n }\n\n function burnFrom(uint256 amount, address burner, address sender) external onlyMinter {\n _burnFromNoRedeem(amount, burner, sender);\n }\n\n function mint(address account, uint256 amount) external onlyMinter {\n _mint(account, amount);\n }\n\n // ======================= Treasury Only Functions =============================\n\n function addMinter(address minter) external onlyTreasury {\n isMinter[minter] = true;\n emit MinterToggled(minter);\n }\n\n function removeMinter(address minter) external {\n if (msg.sender != address(treasury) && msg.sender != minter) revert InvalidSender();\n isMinter[minter] = false;\n emit MinterToggled(minter);\n }\n\n function setTreasury(address _treasury) external onlyTreasury {\n treasury = _treasury;\n emit TreasuryUpdated(_treasury);\n }\n\n // ============================ Internal Function ==============================\n\n /// @notice Internal version of the function `burnFromNoRedeem`\n /// @param amount Amount to burn\n /// @dev It is at the level of this function that allowance checks are performed\n function _burnFromNoRedeem(uint256 amount, address burner, address sender) internal {\n if (burner != sender) {\n uint256 currentAllowance = allowance(burner, sender);\n if (currentAllowance < amount) revert BurnAmountExceedsAllowance();\n _approve(burner, sender, currentAllowance - amount);\n }\n _burnCustom(burner, amount);\n }\n\n // ==================== External Permissionless Functions ======================\n\n /// @notice Returns the list of all supported bridge tokens\n /// @dev Helpful for UIs\n function allBridgeTokens() external view returns (address[] memory) {\n return bridgeTokensList;\n }\n\n /// @notice Returns the current volume for a bridge, for the current hour\n /// @dev Helpful for UIs\n function currentUsage(address bridge) external view returns (uint256) {\n return usage[bridge][block.timestamp / 3600];\n }\n\n /// @notice Returns the current total volume on the chain for the current hour\n /// @dev Helpful for UIs\n function currentTotalUsage() external view returns (uint256) {\n return chainTotalUsage[block.timestamp / 3600];\n }\n\n /// @notice Mints the canonical token from a supported bridge token\n /// @param bridgeToken Bridge token to use to mint\n /// @param amount Amount of bridge tokens to send\n /// @param to Address to which the stablecoin should be sent\n /// @dev Some fees may be taken by the protocol depending on the token used and on the address calling\n function swapIn(address bridgeToken, uint256 amount, address to) external returns (uint256) {\n BridgeDetails memory bridgeDetails = bridges[bridgeToken];\n if (!bridgeDetails.allowed || bridgeDetails.paused) revert InvalidToken();\n uint256 balance = IERC20(bridgeToken).balanceOf(address(this));\n if (balance + amount > bridgeDetails.limit) {\n // In case someone maliciously sends tokens to this contract\n // Or the limit changes\n if (bridgeDetails.limit > balance) amount = bridgeDetails.limit - balance;\n else {\n amount = 0;\n }\n }\n\n // Checking requirement on the hourly volume\n uint256 hour = block.timestamp / 3600;\n uint256 hourlyUsage = usage[bridgeToken][hour] + amount;\n if (hourlyUsage > bridgeDetails.hourlyLimit) {\n // Edge case when the hourly limit changes\n if (bridgeDetails.hourlyLimit > usage[bridgeToken][hour])\n amount = bridgeDetails.hourlyLimit - usage[bridgeToken][hour];\n else {\n amount = 0;\n }\n }\n usage[bridgeToken][hour] += amount;\n\n IERC20(bridgeToken).safeTransferFrom(msg.sender, address(this), amount);\n uint256 canonicalOut = amount;\n // Computing fees\n if (isFeeExempt[msg.sender] == 0) {\n canonicalOut -= (canonicalOut * bridgeDetails.fee) / BASE_PARAMS;\n }\n _mint(to, canonicalOut);\n return canonicalOut;\n }\n\n /// @notice Burns the canonical token in exchange for a bridge token\n /// @param bridgeToken Bridge token required\n /// @param amount Amount of canonical tokens to burn\n /// @param to Address to which the bridge token should be sent\n /// @dev Some fees may be taken by the protocol depending on the token used and on the address calling\n function swapOut(address bridgeToken, uint256 amount, address to) external returns (uint256) {\n BridgeDetails memory bridgeDetails = bridges[bridgeToken];\n if (!bridgeDetails.allowed || bridgeDetails.paused) revert InvalidToken();\n\n uint256 hour = block.timestamp / 3600;\n uint256 hourlyUsage = chainTotalUsage[hour] + amount;\n // If the amount being swapped out exceeds the limit, we revert\n // We don't want to change the amount being swapped out.\n // The user can decide to send another tx with the correct amount to reach the limit\n if (hourlyUsage > chainTotalHourlyLimit) revert HourlyLimitExceeded();\n chainTotalUsage[hour] = hourlyUsage;\n\n _burnCustom(msg.sender, amount);\n uint256 bridgeOut = amount;\n if (isFeeExempt[msg.sender] == 0) {\n bridgeOut -= (bridgeOut * bridgeDetails.fee) / BASE_PARAMS;\n }\n IERC20(bridgeToken).safeTransfer(to, bridgeOut);\n return bridgeOut;\n }\n\n // ======================= Governance Functions ================================\n\n /// @notice Adds support for a bridge token\n /// @param bridgeToken Bridge token to add: it should be a version of the stablecoin from another bridge\n /// @param limit Limit on the balance of bridge token this contract could hold\n /// @param hourlyLimit Limit on the hourly volume for this bridge\n /// @param paused Whether swapping for this token should be paused or not\n /// @param fee Fee taken upon swapping for or against this token\n function addBridgeToken(\n address bridgeToken,\n uint256 limit,\n uint256 hourlyLimit,\n uint64 fee,\n bool paused\n ) external onlyGovernor {\n if (bridges[bridgeToken].allowed || bridgeToken == address(0)) revert InvalidToken();\n if (fee > BASE_PARAMS) revert TooHighParameterValue();\n BridgeDetails memory _bridge;\n _bridge.limit = limit;\n _bridge.hourlyLimit = hourlyLimit;\n _bridge.paused = paused;\n _bridge.fee = fee;\n _bridge.allowed = true;\n bridges[bridgeToken] = _bridge;\n bridgeTokensList.push(bridgeToken);\n emit BridgeTokenAdded(bridgeToken, limit, hourlyLimit, fee, paused);\n }\n\n /// @notice Removes support for a token\n /// @param bridgeToken Address of the bridge token to remove support for\n function removeBridgeToken(address bridgeToken) external onlyGovernor {\n if (IERC20(bridgeToken).balanceOf(address(this)) != 0) revert AssetStillControlledInReserves();\n delete bridges[bridgeToken];\n // Deletion from `bridgeTokensList` loop\n uint256 bridgeTokensListLength = bridgeTokensList.length;\n for (uint256 i; i < bridgeTokensListLength - 1; ++i) {\n if (bridgeTokensList[i] == bridgeToken) {\n // Replace the `bridgeToken` to remove with the last of the list\n bridgeTokensList[i] = bridgeTokensList[bridgeTokensListLength - 1];\n break;\n }\n }\n // Remove last element in array\n bridgeTokensList.pop();\n emit BridgeTokenRemoved(bridgeToken);\n }\n\n /// @notice Recovers any ERC20 token\n /// @dev Can be used to withdraw bridge tokens for them to be de-bridged on mainnet\n function recoverERC20(address tokenAddress, address to, uint256 amountToRecover) external onlyGovernor {\n IERC20(tokenAddress).safeTransfer(to, amountToRecover);\n emit Recovered(tokenAddress, to, amountToRecover);\n }\n\n /// @notice Updates the `limit` amount for `bridgeToken`\n function setLimit(address bridgeToken, uint256 limit) external onlyGovernorOrGuardian {\n if (!bridges[bridgeToken].allowed) revert InvalidToken();\n bridges[bridgeToken].limit = limit;\n emit BridgeTokenLimitUpdated(bridgeToken, limit);\n }\n\n /// @notice Updates the `hourlyLimit` amount for `bridgeToken`\n function setHourlyLimit(address bridgeToken, uint256 hourlyLimit) external onlyGovernorOrGuardian {\n if (!bridges[bridgeToken].allowed) revert InvalidToken();\n bridges[bridgeToken].hourlyLimit = hourlyLimit;\n emit BridgeTokenHourlyLimitUpdated(bridgeToken, hourlyLimit);\n }\n\n /// @notice Updates the `chainTotalHourlyLimit` amount\n function setChainTotalHourlyLimit(uint256 hourlyLimit) external onlyGovernorOrGuardian {\n chainTotalHourlyLimit = hourlyLimit;\n emit HourlyLimitUpdated(hourlyLimit);\n }\n\n /// @notice Updates the `fee` value for `bridgeToken`\n function setSwapFee(address bridgeToken, uint64 fee) external onlyGovernorOrGuardian {\n if (!bridges[bridgeToken].allowed) revert InvalidToken();\n if (fee > BASE_PARAMS) revert TooHighParameterValue();\n bridges[bridgeToken].fee = fee;\n emit BridgeTokenFeeUpdated(bridgeToken, fee);\n }\n\n /// @notice Pauses or unpauses swapping in and out for a token\n function toggleBridge(address bridgeToken) external onlyGovernorOrGuardian {\n if (!bridges[bridgeToken].allowed) revert InvalidToken();\n bool pausedStatus = bridges[bridgeToken].paused;\n bridges[bridgeToken].paused = !pausedStatus;\n emit BridgeTokenToggled(bridgeToken, !pausedStatus);\n }\n\n /// @notice Toggles fees for the address `theAddress`\n function toggleFeesForAddress(address theAddress) external onlyGovernorOrGuardian {\n uint256 feeExemptStatus = 1 - isFeeExempt[theAddress];\n isFeeExempt[theAddress] = feeExemptStatus;\n emit FeeToggled(theAddress, feeExemptStatus);\n }\n}\n" + }, + "contracts/agToken/polygon/utils/ERC20UpgradeableCustom.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (token/ERC20/ERC20.sol)\n\npragma solidity ^0.8.0;\n\nimport \"@openzeppelin/contracts-upgradeable/token/ERC20/IERC20Upgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/token/ERC20/extensions/IERC20MetadataUpgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/utils/ContextUpgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol\";\n\n/**\n * @dev Implementation of the {IERC20} interface modified by Angle Labs, Inc.\n *\n * This implementation has a custom burn function to avoid having a {Transfer} event to the zero address\n * in some specific burn cases to avoid having Polygon PoS bridge catching this event\n *\n * TIP: For a detailed writeup see our guide\n * https://forum.zeppelin.solutions/t/how-to-implement-erc20-supply-mechanisms/226[How\n * to implement supply mechanisms].\n *\n * We have followed general OpenZeppelin Contracts guidelines: functions revert\n * instead returning `false` on failure. This behavior is nonetheless\n * conventional and does not conflict with the expectations of ERC20\n * applications.\n *\n * Additionally, an {Approval} event is emitted on calls to {transferFrom}.\n * This allows applications to reconstruct the allowance for all accounts just\n * by listening to said events. Other implementations of the EIP may not emit\n * these events, as it isn't required by the specification.\n *\n * Finally, the non-standard {decreaseAllowance} and {increaseAllowance}\n * functions have been added to mitigate the well-known issues around setting\n * allowances. See {IERC20-approve}.\n */\ncontract ERC20UpgradeableCustom is Initializable, ContextUpgradeable, IERC20Upgradeable, IERC20MetadataUpgradeable {\n mapping(address => uint256) private _balances;\n\n mapping(address => mapping(address => uint256)) private _allowances;\n\n uint256 private _totalSupply;\n\n string private _name;\n string private _symbol;\n\n /**\n * @dev Sets the values for {name} and {symbol}.\n *\n * The default value of {decimals} is 18. To select a different value for\n * {decimals} you should overload it.\n *\n * All two of these values are immutable: they can only be set once during\n * construction.\n */\n //solhint-disable-next-line\n function __ERC20_init(string memory name_, string memory symbol_) internal onlyInitializing {\n __Context_init_unchained();\n __ERC20_init_unchained(name_, symbol_);\n }\n\n //solhint-disable-next-line\n function __ERC20_init_unchained(string memory name_, string memory symbol_) internal onlyInitializing {\n _name = name_;\n _symbol = symbol_;\n }\n\n /**\n * @dev Returns the name of the token.\n */\n function name() public view virtual override returns (string memory) {\n return _name;\n }\n\n /**\n * @dev Returns the symbol of the token, usually a shorter version of the\n * name.\n */\n function symbol() public view virtual override returns (string memory) {\n return _symbol;\n }\n\n /**\n * @dev Returns the number of decimals used to get its user representation.\n * For example, if `decimals` equals `2`, a balance of `505` tokens should\n * be displayed to a user as `5.05` (`505 / 10 ** 2`).\n *\n * Tokens usually opt for a value of 18, imitating the relationship between\n * Ether and Wei. This is the value {ERC20} uses, unless this function is\n * overridden;\n *\n * NOTE: This information is only used for _display_ purposes: it in\n * no way affects any of the arithmetic of the contract, including\n * {IERC20-balanceOf} and {IERC20-transfer}.\n */\n function decimals() public view virtual override returns (uint8) {\n return 18;\n }\n\n /**\n * @dev See {IERC20-totalSupply}.\n */\n function totalSupply() public view virtual override returns (uint256) {\n return _totalSupply;\n }\n\n /**\n * @dev See {IERC20-balanceOf}.\n */\n function balanceOf(address account) public view virtual override returns (uint256) {\n return _balances[account];\n }\n\n /**\n * @dev See {IERC20-transfer}.\n *\n * Requirements:\n *\n * - `recipient` cannot be the zero address.\n * - the caller must have a balance of at least `amount`.\n */\n function transfer(address recipient, uint256 amount) public virtual override returns (bool) {\n _transfer(_msgSender(), recipient, amount);\n return true;\n }\n\n /**\n * @dev See {IERC20-allowance}.\n */\n function allowance(address owner, address spender) public view virtual override returns (uint256) {\n return _allowances[owner][spender];\n }\n\n /**\n * @dev See {IERC20-approve}.\n *\n * Requirements:\n *\n * - `spender` cannot be the zero address.\n */\n function approve(address spender, uint256 amount) public virtual override returns (bool) {\n _approve(_msgSender(), spender, amount);\n return true;\n }\n\n /**\n * @dev See {IERC20-transferFrom}.\n *\n * Emits an {Approval} event indicating the updated allowance. This is not\n * required by the EIP. See the note at the beginning of {ERC20}.\n *\n * Requirements:\n *\n * - `sender` and `recipient` cannot be the zero address.\n * - `sender` must have a balance of at least `amount`.\n * - the caller must have allowance for `sender`'s tokens of at least\n * `amount`.\n */\n function transferFrom(address sender, address recipient, uint256 amount) public virtual override returns (bool) {\n _transfer(sender, recipient, amount);\n\n uint256 currentAllowance = _allowances[sender][_msgSender()];\n require(currentAllowance >= amount, \"ERC20: transfer amount exceeds allowance\");\n unchecked {\n _approve(sender, _msgSender(), currentAllowance - amount);\n }\n\n return true;\n }\n\n /**\n * @dev Atomically increases the allowance granted to `spender` by the caller.\n *\n * This is an alternative to {approve} that can be used as a mitigation for\n * problems described in {IERC20-approve}.\n *\n * Emits an {Approval} event indicating the updated allowance.\n *\n * Requirements:\n *\n * - `spender` cannot be the zero address.\n */\n function increaseAllowance(address spender, uint256 addedValue) public virtual returns (bool) {\n _approve(_msgSender(), spender, _allowances[_msgSender()][spender] + addedValue);\n return true;\n }\n\n /**\n * @dev Atomically decreases the allowance granted to `spender` by the caller.\n *\n * This is an alternative to {approve} that can be used as a mitigation for\n * problems described in {IERC20-approve}.\n *\n * Emits an {Approval} event indicating the updated allowance.\n *\n * Requirements:\n *\n * - `spender` cannot be the zero address.\n * - `spender` must have allowance for the caller of at least\n * `subtractedValue`.\n */\n function decreaseAllowance(address spender, uint256 subtractedValue) public virtual returns (bool) {\n uint256 currentAllowance = _allowances[_msgSender()][spender];\n require(currentAllowance >= subtractedValue, \"ERC20: decreased allowance below zero\");\n unchecked {\n _approve(_msgSender(), spender, currentAllowance - subtractedValue);\n }\n\n return true;\n }\n\n /**\n * @dev Moves `amount` of tokens from `sender` to `recipient`.\n *\n * This internal function is equivalent to {transfer}, and can be used to\n * e.g. implement automatic token fees, slashing mechanisms, etc.\n *\n * Emits a {Transfer} event.\n *\n * Requirements:\n *\n * - `sender` cannot be the zero address.\n * - `recipient` cannot be the zero address.\n * - `sender` must have a balance of at least `amount`.\n */\n function _transfer(address sender, address recipient, uint256 amount) internal virtual {\n require(sender != address(0), \"ERC20: transfer from the zero address\");\n require(recipient != address(0), \"ERC20: transfer to the zero address\");\n\n _beforeTokenTransfer(sender, recipient, amount);\n\n uint256 senderBalance = _balances[sender];\n require(senderBalance >= amount, \"ERC20: transfer amount exceeds balance\");\n unchecked {\n _balances[sender] = senderBalance - amount;\n }\n _balances[recipient] += amount;\n\n emit Transfer(sender, recipient, amount);\n\n _afterTokenTransfer(sender, recipient, amount);\n }\n\n /** @dev Creates `amount` tokens and assigns them to `account`, increasing\n * the total supply.\n *\n * Emits a {Transfer} event with `from` set to the zero address.\n *\n * Requirements:\n *\n * - `account` cannot be the zero address.\n */\n function _mint(address account, uint256 amount) internal virtual {\n require(account != address(0), \"ERC20: mint to the zero address\");\n\n _beforeTokenTransfer(address(0), account, amount);\n\n _totalSupply += amount;\n _balances[account] += amount;\n emit Transfer(address(0), account, amount);\n\n _afterTokenTransfer(address(0), account, amount);\n }\n\n /**\n * @dev Destroys `amount` tokens from `account`, reducing the\n * total supply.\n *\n * Emits a {Transfer} event with `to` set to the zero address.\n *\n * Requirements:\n *\n * - `account` cannot be the zero address.\n * - `account` must have at least `amount` tokens.\n */\n function _burn(address account, uint256 amount) internal virtual {\n require(account != address(0), \"ERC20: burn from the zero address\");\n\n _beforeTokenTransfer(account, address(0), amount);\n\n uint256 accountBalance = _balances[account];\n require(accountBalance >= amount, \"ERC20: burn amount exceeds balance\");\n unchecked {\n _balances[account] = accountBalance - amount;\n }\n _totalSupply -= amount;\n\n emit Transfer(account, address(0), amount);\n\n _afterTokenTransfer(account, address(0), amount);\n }\n\n /**\n * @dev Destroys `amount` tokens from `account`, reducing the\n * total supply.\n *\n * Contrary to the other `burn` function, the {Transfer} event is not to the zero address\n * but rather to this address: the reason is that not all burn events should be caught up\n * by the PoS bridge\n *\n * Requirements:\n *\n * - `account` cannot be the zero address.\n * - `account` must have at least `amount` tokens.\n */\n function _burnCustom(address account, uint256 amount) internal virtual {\n require(account != address(0), \"ERC20: burn from the zero address\");\n\n _beforeTokenTransfer(account, address(0), amount);\n\n uint256 accountBalance = _balances[account];\n require(accountBalance >= amount, \"ERC20: burn amount exceeds balance\");\n unchecked {\n _balances[account] = accountBalance - amount;\n }\n _totalSupply -= amount;\n\n emit Transfer(account, address(this), amount);\n\n _afterTokenTransfer(account, address(0), amount);\n }\n\n /**\n * @dev Sets `amount` as the allowance of `spender` over the `owner` s tokens.\n *\n * This internal function is equivalent to `approve`, and can be used to\n * e.g. set automatic allowances for certain subsystems, etc.\n *\n * Emits an {Approval} event.\n *\n * Requirements:\n *\n * - `owner` cannot be the zero address.\n * - `spender` cannot be the zero address.\n */\n function _approve(address owner, address spender, uint256 amount) internal virtual {\n require(owner != address(0), \"ERC20: approve from the zero address\");\n require(spender != address(0), \"ERC20: approve to the zero address\");\n\n _allowances[owner][spender] = amount;\n emit Approval(owner, spender, amount);\n }\n\n /**\n * @dev Hook that is called before any transfer of tokens. This includes\n * minting and burning.\n *\n * Calling conditions:\n *\n * - when `from` and `to` are both non-zero, `amount` of `from`'s tokens\n * will be transferred to `to`.\n * - when `from` is zero, `amount` tokens will be minted for `to`.\n * - when `to` is zero, `amount` of `from`'s tokens will be burned.\n * - `from` and `to` are never both zero.\n *\n * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].\n */\n function _beforeTokenTransfer(address from, address to, uint256 amount) internal virtual {}\n\n /**\n * @dev Hook that is called after any transfer of tokens. This includes\n * minting and burning.\n *\n * Calling conditions:\n *\n * - when `from` and `to` are both non-zero, `amount` of `from`'s tokens\n * has been transferred to `to`.\n * - when `from` is zero, `amount` tokens have been minted for `to`.\n * - when `to` is zero, `amount` of `from`'s tokens have been burned.\n * - `from` and `to` are never both zero.\n *\n * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].\n */\n function _afterTokenTransfer(address from, address to, uint256 amount) internal virtual {}\n\n uint256[45] private __gap;\n}\n" + }, + "contracts/coreBorrow/CoreBorrow.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\n/*\n * █ \n ***** ▓▓▓ \n * ▓▓▓▓▓▓▓ \n * ///. ▓▓▓▓▓▓▓▓▓▓▓▓▓ \n ***** //////// ▓▓▓▓▓▓▓ \n * ///////////// ▓▓▓ \n ▓▓ ////////////////// █ ▓▓ \n ▓▓ ▓▓ /////////////////////// ▓▓ ▓▓ \n ▓▓ ▓▓ //////////////////////////// ▓▓ ▓▓ \n ▓▓ ▓▓ /////////▓▓▓///////▓▓▓///////// ▓▓ ▓▓ \n ▓▓ ,////////////////////////////////////// ▓▓ ▓▓ \n ▓▓ ////////////////////////////////////////// ▓▓ \n ▓▓ //////////////////////▓▓▓▓///////////////////// \n ,//////////////////////////////////////////////////// \n .////////////////////////////////////////////////////////// \n .//////////////////////////██.,//////////////////////////█ \n .//////////////////////████..,./////////////////////██ \n ...////////////////███████.....,.////////////////███ \n ,.,////////////████████ ........,///////////████ \n .,.,//////█████████ ,.......///////████ \n ,..//████████ ........./████ \n ..,██████ .....,███ \n .██ ,.,█ \n \n \n \n ▓▓ ▓▓▓▓▓▓▓▓▓▓ ▓▓▓▓▓▓▓▓▓▓ ▓▓ ▓▓▓▓▓▓▓▓▓▓ \n ▓▓▓▓▓▓ ▓▓▓ ▓▓▓ ▓▓▓ ▓▓ ▓▓ ▓▓▓▓ \n ▓▓▓ ▓▓▓ ▓▓▓ ▓▓▓ ▓▓▓ ▓▓▓ ▓▓ ▓▓▓▓▓ \n ▓▓▓ ▓▓ ▓▓▓ ▓▓▓ ▓▓▓▓▓▓▓▓▓▓ ▓▓▓▓▓▓▓▓▓▓ ▓▓▓▓▓▓▓▓▓▓ \n*/\n\npragma solidity ^0.8.12;\n\nimport \"@openzeppelin/contracts-upgradeable/access/AccessControlEnumerableUpgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol\";\n\nimport \"../interfaces/ICoreBorrow.sol\";\nimport \"../interfaces/IFlashAngle.sol\";\nimport \"../interfaces/ITreasury.sol\";\n\n/// @title CoreBorrow\n/// @author Angle Labs, Inc.\n/// @notice Core contract of the borrowing module. This contract handles the access control across all contracts\n/// (it is read by all treasury contracts), and manages the `flashLoanModule`. It has no minting rights over the\n/// stablecoin contracts\ncontract CoreBorrow is ICoreBorrow, Initializable, AccessControlEnumerableUpgradeable {\n /// @notice Role for guardians\n bytes32 public constant GUARDIAN_ROLE = keccak256(\"GUARDIAN_ROLE\");\n /// @notice Role for governors\n bytes32 public constant GOVERNOR_ROLE = keccak256(\"GOVERNOR_ROLE\");\n /// @notice Role for treasury contract\n bytes32 public constant FLASHLOANER_TREASURY_ROLE = keccak256(\"FLASHLOANER_TREASURY_ROLE\");\n\n // ============================= Reference =====================================\n\n /// @notice Reference to the `flashLoanModule` with minting rights over the different stablecoins of the protocol\n address public flashLoanModule;\n\n // =============================== Events ======================================\n\n event FlashLoanModuleUpdated(address indexed _flashloanModule);\n event CoreUpdated(address indexed _core);\n\n // =============================== Errors ======================================\n\n error InvalidCore();\n error IncompatibleGovernorAndGuardian();\n error NotEnoughGovernorsLeft();\n error ZeroAddress();\n\n /// @notice Initializes the `CoreBorrow` contract and the access control of the borrowing module\n /// @param governor Address of the governor of the Angle Protocol\n /// @param guardian Guardian address of the protocol\n function initialize(address governor, address guardian) public initializer {\n if (governor == address(0) || guardian == address(0)) revert ZeroAddress();\n if (governor == guardian) revert IncompatibleGovernorAndGuardian();\n _setupRole(GOVERNOR_ROLE, governor);\n _setupRole(GUARDIAN_ROLE, guardian);\n _setupRole(GUARDIAN_ROLE, governor);\n _setRoleAdmin(GUARDIAN_ROLE, GOVERNOR_ROLE);\n _setRoleAdmin(GOVERNOR_ROLE, GOVERNOR_ROLE);\n _setRoleAdmin(FLASHLOANER_TREASURY_ROLE, GOVERNOR_ROLE);\n }\n\n /// @custom:oz-upgrades-unsafe-allow constructor\n constructor() initializer {}\n\n // =========================== View Functions ==================================\n\n /// @inheritdoc ICoreBorrow\n function isFlashLoanerTreasury(address treasury) external view returns (bool) {\n return hasRole(FLASHLOANER_TREASURY_ROLE, treasury);\n }\n\n /// @inheritdoc ICoreBorrow\n function isGovernor(address admin) external view returns (bool) {\n return hasRole(GOVERNOR_ROLE, admin);\n }\n\n /// @inheritdoc ICoreBorrow\n function isGovernorOrGuardian(address admin) external view returns (bool) {\n return hasRole(GUARDIAN_ROLE, admin);\n }\n\n // =========================== Governor Functions ==============================\n\n /// @notice Grants the `FLASHLOANER_TREASURY_ROLE` to a `treasury` contract\n /// @param treasury Contract to grant the role to\n /// @dev This function can be used to allow flash loans on a stablecoin of the protocol\n function addFlashLoanerTreasuryRole(address treasury) external {\n grantRole(FLASHLOANER_TREASURY_ROLE, treasury);\n address _flashLoanModule = flashLoanModule;\n if (_flashLoanModule != address(0)) {\n // This call will revert if `treasury` is the zero address or if it is not linked\n // to this `CoreBorrow` contract\n ITreasury(treasury).setFlashLoanModule(_flashLoanModule);\n IFlashAngle(_flashLoanModule).addStablecoinSupport(treasury);\n }\n }\n\n /// @notice Adds a governor in the protocol\n /// @param governor Address to grant the role to\n /// @dev It is necessary to call this function to grant a governor role to make sure\n /// all governors also have the guardian role\n function addGovernor(address governor) external {\n grantRole(GOVERNOR_ROLE, governor);\n grantRole(GUARDIAN_ROLE, governor);\n }\n\n /// @notice Revokes the flash loan ability for a stablecoin\n /// @param treasury Treasury address associated with the stablecoin for which flash loans\n /// should no longer be available\n function removeFlashLoanerTreasuryRole(address treasury) external {\n revokeRole(FLASHLOANER_TREASURY_ROLE, treasury);\n ITreasury(treasury).setFlashLoanModule(address(0));\n address _flashLoanModule = flashLoanModule;\n if (_flashLoanModule != address(0)) {\n IFlashAngle(flashLoanModule).removeStablecoinSupport(treasury);\n }\n }\n\n /// @notice Revokes a governor from the protocol\n /// @param governor Address to remove the role to\n /// @dev It is necessary to call this function to remove a governor role to make sure\n /// the address also loses its guardian role\n function removeGovernor(address governor) external {\n if (getRoleMemberCount(GOVERNOR_ROLE) <= 1) revert NotEnoughGovernorsLeft();\n revokeRole(GUARDIAN_ROLE, governor);\n revokeRole(GOVERNOR_ROLE, governor);\n }\n\n /// @notice Changes the `flashLoanModule` of the protocol\n /// @param _flashLoanModule Address of the new flash loan module\n function setFlashLoanModule(address _flashLoanModule) external onlyRole(GOVERNOR_ROLE) {\n if (_flashLoanModule != address(0)) {\n if (address(IFlashAngle(_flashLoanModule).core()) != address(this)) revert InvalidCore();\n }\n uint256 count = getRoleMemberCount(FLASHLOANER_TREASURY_ROLE);\n for (uint256 i; i < count; ++i) {\n ITreasury(getRoleMember(FLASHLOANER_TREASURY_ROLE, i)).setFlashLoanModule(_flashLoanModule);\n }\n flashLoanModule = _flashLoanModule;\n emit FlashLoanModuleUpdated(_flashLoanModule);\n }\n\n /// @notice Changes the core contract of the protocol\n /// @param _core New core contract\n /// @dev This function verifies that all governors of the current core contract are also governors\n /// of the new core contract. It also notifies the `flashLoanModule` of the change.\n /// @dev Governance wishing to change the core contract should also make sure to call `setCore`\n /// in the different treasury contracts\n function setCore(ICoreBorrow _core) external onlyRole(GOVERNOR_ROLE) {\n uint256 count = getRoleMemberCount(GOVERNOR_ROLE);\n bool success;\n for (uint256 i; i < count; ++i) {\n success = _core.isGovernor(getRoleMember(GOVERNOR_ROLE, i));\n if (!success) break;\n }\n if (!success) revert InvalidCore();\n address _flashLoanModule = flashLoanModule;\n if (_flashLoanModule != address(0)) IFlashAngle(_flashLoanModule).setCore(address(_core));\n emit CoreUpdated(address(_core));\n }\n}\n" + }, + "contracts/deprecated/AgTokenIntermediateUpgrade.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\nimport \"../interfaces/IAgToken.sol\";\nimport \"../interfaces/coreModule/IStableMaster.sol\";\n// OpenZeppelin may update its version of the ERC20PermitUpgradeable token\nimport \"@openzeppelin/contracts-upgradeable/token/ERC20/extensions/draft-ERC20PermitUpgradeable.sol\";\n\n/// @title AgTokenIntermediateUpgrade\n/// @author Angle Labs, Inc.\n/// @notice Base contract for agToken, that is to say Angle's stablecoins\n/// @dev This contract is used to create and handle the stablecoins of Angle protocol\n/// @dev It is still possible for any address to burn its agTokens without redeeming collateral in exchange\n/// @dev This contract is the upgraded version of the AgToken that was first deployed on Ethereum mainnet and is used to\n/// add other minters as needed by AMOs\ncontract AgTokenIntermediateUpgrade is ERC20PermitUpgradeable {\n // ========================= References to other contracts =====================\n\n /// @notice Reference to the `StableMaster` contract associated to this `AgToken`\n address public stableMaster;\n\n // ============================= Constructor ===================================\n\n /// @notice Initializes the `AgToken` contract\n /// @param name_ Name of the token\n /// @param symbol_ Symbol of the token\n /// @param stableMaster_ Reference to the `StableMaster` contract associated to this agToken\n /// @dev By default, agTokens are ERC-20 tokens with 18 decimals\n function initialize(string memory name_, string memory symbol_, address stableMaster_) external initializer {\n __ERC20Permit_init(name_);\n __ERC20_init(name_, symbol_);\n require(stableMaster_ != address(0), \"0\");\n stableMaster = stableMaster_;\n }\n\n /// @custom:oz-upgrades-unsafe-allow constructor\n constructor() initializer {}\n\n // ======= Added Parameters and Variables from the first implementation ========\n\n /// @notice Checks whether an address has the right to mint agTokens\n mapping(address => bool) public isMinter;\n\n // =============================== Added Events ================================\n\n event MinterToggled(address indexed minter);\n\n // =============================== Setup Function ==============================\n\n /// @notice Sets up the minter role and gives it to the governor\n /// @dev This function just has to be called once\n function setUpMinter() external {\n address governor = 0xdC4e6DFe07EFCa50a197DF15D9200883eF4Eb1c8;\n require(msg.sender == governor);\n isMinter[governor] = true;\n emit MinterToggled(governor);\n }\n\n // =============================== Modifiers ===================================\n\n /// @notice Checks whether the sender has the minting right\n modifier onlyMinter() {\n require(isMinter[msg.sender] || msg.sender == stableMaster, \"35\");\n _;\n }\n\n // ========================= External Functions ================================\n // The following functions allow anyone to burn stablecoins without redeeming collateral\n // in exchange for that\n\n /// @notice Destroys `amount` token from the caller without giving collateral back\n /// @param amount Amount to burn\n /// @param poolManager Reference to the `PoolManager` contract for which the `stocksUsers` will\n /// need to be updated\n /// @dev When calling this function, people should specify the `poolManager` for which they want to decrease\n /// the `stocksUsers`: this is a way for the protocol to maintain healthy accounting variables\n function burnNoRedeem(uint256 amount, address poolManager) external {\n _burn(msg.sender, amount);\n IStableMaster(stableMaster).updateStocksUsers(amount, poolManager);\n }\n\n /// @notice Burns `amount` of agToken on behalf of another account without redeeming collateral back\n /// @param account Account to burn on behalf of\n /// @param amount Amount to burn\n /// @param poolManager Reference to the `PoolManager` contract for which the `stocksUsers` will need to be updated\n function burnFromNoRedeem(address account, uint256 amount, address poolManager) external {\n _burnFromNoRedeem(amount, account, msg.sender);\n IStableMaster(stableMaster).updateStocksUsers(amount, poolManager);\n }\n\n // ======================= Minter Role Only Functions ==========================\n\n /// @notice Burns `amount` tokens from a `burner` address\n /// @param amount Amount of tokens to burn\n /// @param burner Address to burn from\n /// @dev This method is to be called by a contract with a minter right on the AgToken after being\n /// requested to do so by an address willing to burn tokens from its address\n function burnSelf(uint256 amount, address burner) external onlyMinter {\n _burn(burner, amount);\n }\n\n /// @notice Burns `amount` tokens from a `burner` address after being asked to by `sender`\n /// @param amount Amount of tokens to burn\n /// @param burner Address to burn from\n /// @param sender Address which requested the burn from `burner`\n /// @dev This method is to be called by a contract with the minter right after being requested\n /// to do so by a `sender` address willing to burn tokens from another `burner` address\n /// @dev The method checks the allowance between the `sender` and the `burner`\n function burnFrom(uint256 amount, address burner, address sender) external onlyMinter {\n _burnFromNoRedeem(amount, burner, sender);\n }\n\n /// @notice Lets the `StableMaster` contract or another whitelisted contract mint agTokens\n /// @param account Address to mint to\n /// @param amount Amount to mint\n /// @dev The contracts allowed to issue agTokens are the `StableMaster` contract, `VaultManager` contracts\n /// associated to this stablecoin as well as the flash loan module (if activated) and potentially contracts\n /// whitelisted by governance\n function mint(address account, uint256 amount) external onlyMinter {\n _mint(account, amount);\n }\n\n // ======================= Minter Only Functions ===============================\n\n /// @notice Adds a minter in the contract\n /// @param minter Minter address to add\n function addMinter(address minter) external onlyMinter {\n isMinter[minter] = true;\n emit MinterToggled(minter);\n }\n\n /// @notice Removes a minter from the contract\n /// @param minter Minter address to remove\n /// @dev This function can at the moment only be called by a minter wishing to revoke itself\n function removeMinter(address minter) external {\n require(msg.sender == minter && isMinter[msg.sender], \"36\");\n isMinter[minter] = false;\n emit MinterToggled(minter);\n }\n\n // ============================ Internal Function ==============================\n\n /// @notice Internal version of the function `burnFromNoRedeem`\n /// @param amount Amount to burn\n /// @dev It is at the level of this function that allowance checks are performed\n function _burnFromNoRedeem(uint256 amount, address burner, address sender) internal {\n if (burner != sender) {\n uint256 currentAllowance = allowance(burner, sender);\n require(currentAllowance >= amount, \"23\");\n _approve(burner, sender, currentAllowance - amount);\n }\n _burn(burner, amount);\n }\n}\n" + }, + "contracts/deprecated/layerZero/OldLayerZeroBridgeToken.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.12;\n\nimport \"./OldOFTCore.sol\";\nimport \"../../interfaces/IAgTokenSideChainMultiBridge.sol\";\nimport \"@openzeppelin/contracts-upgradeable/security/PausableUpgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/token/ERC20/ERC20Upgradeable.sol\";\n\n/// @title LayerZeroBridgeToken\n/// @author Angle Labs, Inc., forked from https://github.com/LayerZero-Labs/solidity-examples/blob/main/contracts/token/oft/OFT.sol\n/// @notice Contract to be deployed on a L2/sidechain for bridging an AgToken using a bridge intermediate token and LayerZero\ncontract OldLayerZeroBridgeToken is OldOFTCore, ERC20Upgradeable, PausableUpgradeable {\n /// @notice Address of the bridgeable token\n /// @dev Immutable\n IAgTokenSideChainMultiBridge public canonicalToken;\n\n // =============================== Errors ================================\n\n error InvalidAllowance();\n\n // ============================= Constructor ===================================\n\n /// @notice Initializes the contract\n /// @param _name Name of the token corresponding to this contract\n /// @param _symbol Symbol of the token corresponding to this contract\n /// @param _lzEndpoint Layer zero endpoint to pass messages\n /// @param _treasury Address of the treasury contract used for access control\n /// @param initialSupply Initial supply to mint to the canonical token address\n /// @dev The initial supply corresponds to the initial amount that could be bridged using this OFT\n function initialize(\n string memory _name,\n string memory _symbol,\n address _lzEndpoint,\n address _treasury,\n uint256 initialSupply\n ) external initializer {\n __ERC20_init_unchained(_name, _symbol);\n __LzAppUpgradeable_init(_lzEndpoint, _treasury);\n\n canonicalToken = IAgTokenSideChainMultiBridge(address(ITreasury(_treasury).stablecoin()));\n _approve(address(this), address(canonicalToken), type(uint256).max);\n _mint(address(canonicalToken), initialSupply);\n }\n\n /// @custom:oz-upgrades-unsafe-allow constructor\n constructor() initializer {}\n\n // ==================== External Permissionless Functions ======================\n\n function sendWithPermit(\n uint16 _dstChainId,\n bytes memory _toAddress,\n uint256 _amount,\n address payable _refundAddress,\n address _zroPaymentAddress,\n bytes memory _adapterParams,\n uint256 deadline,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) public payable override {\n canonicalToken.permit(msg.sender, address(this), _amount, deadline, v, r, s);\n send(_dstChainId, _toAddress, _amount, _refundAddress, _zroPaymentAddress, _adapterParams);\n }\n\n function withdraw(uint256 amount, address recipient) external override returns (uint256 amountMinted) {\n // Does not check allowances as transfers from `msg.sender`\n _transfer(msg.sender, address(this), amount);\n amountMinted = canonicalToken.swapIn(address(this), amount, recipient);\n uint256 leftover = balanceOf(address(this));\n if (leftover != 0) {\n _transfer(address(this), msg.sender, leftover);\n }\n }\n\n // ============================= Internal Functions ===================================\n\n function _debitFrom(\n uint16,\n bytes memory,\n uint256 _amount\n ) internal override whenNotPaused returns (uint256 amountSwapped) {\n // No need to use safeTransferFrom as we know this implementation reverts on failure\n canonicalToken.transferFrom(msg.sender, address(this), _amount);\n\n // Swap canonical for this bridge token. There may be some fees\n amountSwapped = canonicalToken.swapOut(address(this), _amount, address(this));\n _burn(address(this), amountSwapped);\n }\n\n function _debitCreditFrom(uint16, bytes memory, uint256 _amount) internal override whenNotPaused returns (uint256) {\n _burn(msg.sender, _amount);\n return _amount;\n }\n\n function _creditTo(\n uint16,\n address _toAddress,\n uint256 _amount\n ) internal override whenNotPaused returns (uint256 amountMinted) {\n _mint(address(this), _amount);\n amountMinted = canonicalToken.swapIn(address(this), _amount, _toAddress);\n uint256 leftover = balanceOf(address(this));\n if (leftover != 0) {\n _transfer(address(this), _toAddress, leftover);\n }\n }\n\n // ======================= View Functions ================================\n\n /// @inheritdoc ERC165Upgradeable\n function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {\n return\n interfaceId == type(IOFT).interfaceId ||\n interfaceId == type(IERC20).interfaceId ||\n super.supportsInterface(interfaceId);\n }\n\n // ======================= Governance Functions ================================\n\n /// @notice Mints the intermediate contract to the `canonicalToken`\n /// @dev Used to increase the bridging capacity\n function mint(uint256 amount) external onlyGovernorOrGuardian {\n _mint(address(canonicalToken), amount);\n }\n\n /// @notice Burns the intermediate contract from the `canonicalToken`\n /// @dev Used to decrease the bridging capacity\n function burn(uint256 amount) external onlyGovernorOrGuardian {\n _burn(address(canonicalToken), amount);\n }\n\n /// @notice Increases allowance of the `canonicalToken`\n function setupAllowance() public onlyGovernorOrGuardian {\n _approve(address(this), address(canonicalToken), type(uint256).max);\n }\n\n /// @notice Pauses bridging through the contract\n /// @param pause Future pause status\n function pauseSendTokens(bool pause) external onlyGovernorOrGuardian {\n pause ? _pause() : _unpause();\n }\n\n uint256[49] private __gap;\n}\n" + }, + "contracts/deprecated/layerZero/OldNonblockingLzApp.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.12;\n\nimport \"@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol\";\nimport \"../../interfaces/external/layerZero/ILayerZeroReceiver.sol\";\nimport \"../../interfaces/external/layerZero/ILayerZeroUserApplicationConfig.sol\";\nimport \"../../interfaces/external/layerZero/ILayerZeroEndpoint.sol\";\nimport \"../../interfaces/ITreasury.sol\";\n\n/// @title OldNonblockingLzApp\n/// @author Angle Labs, Inc., forked from https://github.com/LayerZero-Labs/solidity-examples/\n/// @notice Base contract for bridging using LayerZero\nabstract contract OldNonblockingLzApp is Initializable, ILayerZeroReceiver, ILayerZeroUserApplicationConfig {\n /// @notice Layer Zero endpoint\n ILayerZeroEndpoint public lzEndpoint;\n\n /// @notice Maps chainIds to failed messages to retry them\n mapping(uint16 => mapping(bytes => mapping(uint64 => bytes32))) public failedMessages;\n\n /// @notice Maps chainIds to their OFT address\n mapping(uint16 => bytes) public trustedRemoteLookup;\n\n /// @notice Reference to the treasury contract to fetch access control\n address public treasury;\n\n // ================================== Events ===================================\n\n event SetTrustedRemote(uint16 _srcChainId, bytes _srcAddress);\n event MessageFailed(uint16 _srcChainId, bytes _srcAddress, uint64 _nonce, bytes _payload);\n\n // =============================== Errors ================================\n\n error NotGovernor();\n error NotGovernorOrGuardian();\n error InsufficientGas();\n error InvalidEndpoint();\n error InvalidSource();\n error InvalidCaller();\n error InvalidParams();\n error InvalidPayload();\n error ZeroAddress();\n\n // ============================= Constructor ===================================\n\n //solhint-disable-next-line\n function __LzAppUpgradeable_init(address _endpoint, address _treasury) internal {\n if (_endpoint == address(0) || _treasury == address(0)) revert ZeroAddress();\n lzEndpoint = ILayerZeroEndpoint(_endpoint);\n treasury = _treasury;\n }\n\n // =============================== Modifiers ===================================\n\n /// @notice Checks whether the `msg.sender` has the governor role or the guardian role\n modifier onlyGovernorOrGuardian() {\n if (!ITreasury(treasury).isGovernorOrGuardian(msg.sender)) revert NotGovernorOrGuardian();\n _;\n }\n\n // ==================== External Permissionless Functions ======================\n\n /// @notice Receives a message from the LZ endpoint and process it\n /// @param _srcChainId ChainId of the source chain - LayerZero standard\n /// @param _srcAddress Sender of the source chain\n /// @param _nonce Nounce of the message\n /// @param _payload Data: recipient address and amount\n function lzReceive(\n uint16 _srcChainId,\n bytes memory _srcAddress,\n uint64 _nonce,\n bytes memory _payload\n ) public virtual override {\n // lzReceive must be called by the endpoint for security\n if (msg.sender != address(lzEndpoint)) revert InvalidEndpoint();\n\n bytes memory trustedRemote = trustedRemoteLookup[_srcChainId];\n // if will still block the message pathway from (srcChainId, srcAddress). should not receive message from untrusted remote.\n if (_srcAddress.length != trustedRemote.length || keccak256(_srcAddress) != keccak256(trustedRemote))\n revert InvalidSource();\n\n _blockingLzReceive(_srcChainId, _srcAddress, _nonce, _payload);\n }\n\n /// @notice Retries a message that previously failed and was stored\n /// @param _srcChainId ChainId of the source chain - LayerZero standard\n /// @param _srcAddress Sender of the source chain\n /// @param _nonce Nounce of the message\n /// @param _payload Data: recipient address and amount\n function retryMessage(\n uint16 _srcChainId,\n bytes memory _srcAddress,\n uint64 _nonce,\n bytes memory _payload\n ) public payable virtual {\n // assert there is message to retry\n bytes32 payloadHash = failedMessages[_srcChainId][_srcAddress][_nonce];\n if (payloadHash == bytes32(0) || keccak256(_payload) != payloadHash) revert InvalidPayload();\n // clear the stored message\n failedMessages[_srcChainId][_srcAddress][_nonce] = bytes32(0);\n // execute the message. revert if it fails again\n _nonblockingLzReceive(_srcChainId, _srcAddress, _nonce, _payload);\n }\n\n // ============================= Internal Functions ===================================\n\n /// @notice Handles message receptions in a non blocking way\n /// @param _srcChainId ChainId of the source chain - LayerZero standard\n /// @param _srcAddress Sender of the source chain\n /// @param _nonce Nounce of the message\n /// @param _payload Data: recipient address and amount\n /// @dev public for the needs of try / catch but effectively internal\n function nonblockingLzReceive(\n uint16 _srcChainId,\n bytes memory _srcAddress,\n uint64 _nonce,\n bytes memory _payload\n ) public virtual {\n // only internal transaction\n if (msg.sender != address(this)) revert InvalidCaller();\n _nonblockingLzReceive(_srcChainId, _srcAddress, _nonce, _payload);\n }\n\n /// @notice Handles message receptions in a non blocking way\n /// @param _srcChainId ChainId of the source chain - LayerZero standard\n /// @param _srcAddress Sender of the source chain\n /// @param _nonce Nounce of the message\n /// @param _payload Data: recipient address and amount\n function _nonblockingLzReceive(\n uint16 _srcChainId,\n bytes memory _srcAddress,\n uint64 _nonce,\n bytes memory _payload\n ) internal virtual;\n\n /// @notice Handles message receptions in a blocking way\n /// @param _srcChainId ChainId of the source chain - LayerZero standard\n /// @param _srcAddress Sender of the source chain\n /// @param _nonce Nounce of the message\n /// @param _payload Data: recipient address and amount\n function _blockingLzReceive(\n uint16 _srcChainId,\n bytes memory _srcAddress,\n uint64 _nonce,\n bytes memory _payload\n ) internal {\n // try-catch all errors/exceptions\n try this.nonblockingLzReceive(_srcChainId, _srcAddress, _nonce, _payload) {\n // do nothing\n } catch {\n // error / exception\n failedMessages[_srcChainId][_srcAddress][_nonce] = keccak256(_payload);\n emit MessageFailed(_srcChainId, _srcAddress, _nonce, _payload);\n }\n }\n\n /// @notice Sends a message to the LZ endpoint and process it\n /// @param _dstChainId L0 defined chain id to send tokens too\n /// @param _payload Data: recipient address and amount\n /// @param _refundAddress Address LayerZero refunds if too much message fee is sent\n /// @param _zroPaymentAddress Set to address(0x0) if not paying in ZRO (LayerZero Token)\n /// @param _adapterParams Flexible bytes array to indicate messaging adapter services in L0\n function _lzSend(\n uint16 _dstChainId,\n bytes memory _payload,\n address payable _refundAddress,\n address _zroPaymentAddress,\n bytes memory _adapterParams\n ) internal virtual {\n bytes memory trustedRemote = trustedRemoteLookup[_dstChainId];\n if (trustedRemote.length == 0) revert InvalidSource();\n //solhint-disable-next-line\n lzEndpoint.send{ value: msg.value }(\n _dstChainId,\n trustedRemote,\n _payload,\n _refundAddress,\n _zroPaymentAddress,\n _adapterParams\n );\n }\n\n // ======================= Governance Functions ================================\n\n /// @notice Sets the corresponding address on an other chain.\n /// @param _srcChainId ChainId of the source chain - LayerZero standard\n /// @param _srcAddress Address on the source chain\n /// @dev Used for both receiving and sending message\n /// @dev There can only be one trusted source per chain\n /// @dev Allows owner to set it multiple times.\n function setTrustedRemote(uint16 _srcChainId, bytes calldata _srcAddress) external onlyGovernorOrGuardian {\n trustedRemoteLookup[_srcChainId] = _srcAddress;\n emit SetTrustedRemote(_srcChainId, _srcAddress);\n }\n\n /// @notice Fetches the default LZ config\n function getConfig(\n uint16 _version,\n uint16 _chainId,\n address,\n uint256 _configType\n ) external view returns (bytes memory) {\n return lzEndpoint.getConfig(_version, _chainId, address(this), _configType);\n }\n\n /// @notice Overrides the default LZ config\n function setConfig(\n uint16 _version,\n uint16 _chainId,\n uint256 _configType,\n bytes calldata _config\n ) external override onlyGovernorOrGuardian {\n lzEndpoint.setConfig(_version, _chainId, _configType, _config);\n }\n\n /// @notice Overrides the default LZ config\n function setSendVersion(uint16 _version) external override onlyGovernorOrGuardian {\n lzEndpoint.setSendVersion(_version);\n }\n\n /// @notice Overrides the default LZ config\n function setReceiveVersion(uint16 _version) external override onlyGovernorOrGuardian {\n lzEndpoint.setReceiveVersion(_version);\n }\n\n /// @notice Unpauses the receive functionalities\n function forceResumeReceive(\n uint16 _srcChainId,\n bytes calldata _srcAddress\n ) external override onlyGovernorOrGuardian {\n lzEndpoint.forceResumeReceive(_srcChainId, _srcAddress);\n }\n\n // ======================= View Functions ================================\n\n /// @notice Checks if the `_srcAddress` corresponds to the trusted source\n function isTrustedRemote(uint16 _srcChainId, bytes calldata _srcAddress) external view returns (bool) {\n bytes memory trustedSource = trustedRemoteLookup[_srcChainId];\n return keccak256(trustedSource) == keccak256(_srcAddress);\n }\n\n uint256[46] private __gap;\n}\n" + }, + "contracts/deprecated/layerZero/OldOFTCore.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.12;\n\nimport \"./OldNonblockingLzApp.sol\";\nimport \"../../agToken/layerZero/utils/IOFTCore.sol\";\nimport \"@openzeppelin/contracts-upgradeable/utils/introspection/ERC165Upgradeable.sol\";\n\n/// @title OFTCore\n/// @author Forked from https://github.com/LayerZero-Labs/solidity-examples/blob/main/contracts/token/oft/OFTCore.sol\n/// but with slight modifications from the Angle Labs, Inc. which added return values to the `_creditTo` and `_debitFrom` functions\n/// @notice Base contract for bridging using LayerZero\nabstract contract OldOFTCore is OldNonblockingLzApp, ERC165Upgradeable, IOFTCore {\n // ==================== External Permissionless Functions ======================\n\n /// @inheritdoc IOFTCore\n function sendWithPermit(\n uint16 _dstChainId,\n bytes memory _toAddress,\n uint256 _amount,\n address payable _refundAddress,\n address _zroPaymentAddress,\n bytes memory _adapterParams,\n uint256 deadline,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) public payable virtual;\n\n /// @inheritdoc IOFTCore\n function send(\n uint16 _dstChainId,\n bytes memory _toAddress,\n uint256 _amount,\n address payable _refundAddress,\n address _zroPaymentAddress,\n bytes memory _adapterParams\n ) public payable virtual {\n _amount = _debitFrom(_dstChainId, _toAddress, _amount);\n\n bytes memory payload = abi.encode(_toAddress, _amount);\n _lzSend(_dstChainId, payload, _refundAddress, _zroPaymentAddress, _adapterParams);\n\n uint64 nonce = lzEndpoint.getOutboundNonce(_dstChainId, address(this));\n emit SendToChain(msg.sender, _dstChainId, _toAddress, _amount, nonce);\n }\n\n /// @inheritdoc IOFTCore\n function sendCredit(\n uint16 _dstChainId,\n bytes memory _toAddress,\n uint256 _amount,\n address payable _refundAddress,\n address _zroPaymentAddress,\n bytes memory _adapterParams\n ) public payable virtual {\n _amount = _debitCreditFrom(_dstChainId, _toAddress, _amount);\n\n _send(_dstChainId, _toAddress, _amount, _refundAddress, _zroPaymentAddress, _adapterParams);\n }\n\n /// @inheritdoc IOFTCore\n function withdraw(uint256 amount, address recipient) external virtual returns (uint256);\n\n // =========================== Internal Functions ==============================\n\n /// @notice Internal function to send `_amount` amount of token to (`_dstChainId`, `_toAddress`)\n /// @param _dstChainId the destination chain identifier\n /// @param _toAddress can be any size depending on the `dstChainId`.\n /// @param _amount the quantity of tokens in wei\n /// @param _refundAddress the address LayerZero refunds if too much message fee is sent\n /// @param _zroPaymentAddress set to address(0x0) if not paying in ZRO (LayerZero Token)\n /// @param _adapterParams is a flexible bytes array to indicate messaging adapter services\n /// @dev Accounting and checks should be performed beforehand\n function _send(\n uint16 _dstChainId,\n bytes memory _toAddress,\n uint256 _amount,\n address payable _refundAddress,\n address _zroPaymentAddress,\n bytes memory _adapterParams\n ) internal {\n bytes memory payload = abi.encode(_toAddress, _amount);\n _lzSend(_dstChainId, payload, _refundAddress, _zroPaymentAddress, _adapterParams);\n\n uint64 nonce = lzEndpoint.getOutboundNonce(_dstChainId, address(this));\n emit SendToChain(msg.sender, _dstChainId, _toAddress, _amount, nonce);\n }\n\n function _nonblockingLzReceive(\n uint16 _srcChainId,\n bytes memory _srcAddress,\n uint64 _nonce,\n bytes memory _payload\n ) internal virtual override {\n // decode and load the toAddress\n (bytes memory toAddressBytes, uint256 amount) = abi.decode(_payload, (bytes, uint256));\n address toAddress;\n //solhint-disable-next-line\n assembly {\n toAddress := mload(add(toAddressBytes, 20))\n }\n amount = _creditTo(_srcChainId, toAddress, amount);\n\n emit ReceiveFromChain(_srcChainId, _srcAddress, toAddress, amount, _nonce);\n }\n\n /// @notice Makes accountability when bridging from this contract using canonical token\n /// @param _dstChainId ChainId of the destination chain - LayerZero standard\n /// @param _toAddress Recipient on the destination chain\n /// @param _amount Amount to bridge\n function _debitFrom(\n uint16 _dstChainId,\n bytes memory _toAddress,\n uint256 _amount\n ) internal virtual returns (uint256);\n\n /// @notice Makes accountability when bridging from this contract's credit\n /// @param _dstChainId ChainId of the destination chain - LayerZero standard\n /// @param _toAddress Recipient on the destination chain\n /// @param _amount Amount to bridge\n function _debitCreditFrom(\n uint16 _dstChainId,\n bytes memory _toAddress,\n uint256 _amount\n ) internal virtual returns (uint256);\n\n /// @notice Makes accountability when bridging to this contract\n /// @param _srcChainId ChainId of the source chain - LayerZero standard\n /// @param _toAddress Recipient on this chain\n /// @param _amount Amount to bridge\n function _creditTo(uint16 _srcChainId, address _toAddress, uint256 _amount) internal virtual returns (uint256);\n\n // ========================== View Functions ===================================\n\n /// @inheritdoc ERC165Upgradeable\n function supportsInterface(\n bytes4 interfaceId\n ) public view virtual override(ERC165Upgradeable, IERC165) returns (bool) {\n return interfaceId == type(IOFTCore).interfaceId || super.supportsInterface(interfaceId);\n }\n\n /// @inheritdoc IOFTCore\n function estimateSendFee(\n uint16 _dstChainId,\n bytes memory _toAddress,\n uint256 _amount,\n bool _useZro,\n bytes memory _adapterParams\n ) public view virtual override returns (uint256 nativeFee, uint256 zroFee) {\n // mock the payload for send()\n bytes memory payload = abi.encode(_toAddress, _amount);\n return lzEndpoint.estimateFees(_dstChainId, address(this), payload, _useZro, _adapterParams);\n }\n\n uint256[50] private __gap;\n}\n" + }, + "contracts/deprecated/OldAgEUR.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\nimport \"../interfaces/IAgToken.sol\";\nimport \"../interfaces/coreModule/IStableMaster.sol\";\nimport \"../interfaces/ITreasury.sol\";\n// OpenZeppelin may update its version of the ERC20PermitUpgradeable token\nimport \"@openzeppelin/contracts-upgradeable/token/ERC20/extensions/draft-ERC20PermitUpgradeable.sol\";\n\n/// @title AgToken\n/// @author Angle Labs, Inc.\n/// @notice Base contract for agToken, that is to say Angle's stablecoins\n/// @dev This contract is used to create and handle the stablecoins of Angle protocol\n/// @dev It is still possible for any address to burn its agTokens without redeeming collateral in exchange\n/// @dev This contract is the upgraded version of the AgToken that was first deployed on Ethereum mainnet\ncontract OldAgEUR is IAgToken, ERC20PermitUpgradeable {\n // ========================= References to other contracts =====================\n\n /// @notice Reference to the `StableMaster` contract associated to this `AgToken`\n address public stableMaster;\n\n // ============================= Constructor ===================================\n\n /// @notice Initializes the `AgToken` contract\n /// @param name_ Name of the token\n /// @param symbol_ Symbol of the token\n /// @param stableMaster_ Reference to the `StableMaster` contract associated to this agToken\n /// @dev By default, agTokens are ERC-20 tokens with 18 decimals\n function initialize(string memory name_, string memory symbol_, address stableMaster_) external initializer {\n __ERC20Permit_init(name_);\n __ERC20_init(name_, symbol_);\n require(stableMaster_ != address(0), \"0\");\n stableMaster = stableMaster_;\n }\n\n /// @custom:oz-upgrades-unsafe-allow constructor\n constructor() initializer {}\n\n // ======= Added Parameters and Variables from the first implementation ========\n\n /// @inheritdoc IAgToken\n mapping(address => bool) public isMinter;\n /// @notice Reference to the treasury contract which can grant minting rights\n address public treasury;\n /// @notice Boolean to check whether the contract has been reinitialized after its upgrade\n bool public treasuryInitialized;\n\n // =============================== Added Events ================================\n\n event TreasuryUpdated(address indexed _treasury);\n event MinterToggled(address indexed minter);\n\n // =============================== Added Errors ================================\n\n error BurnAmountExceedsAllowance();\n error InvalidSender();\n error InvalidTreasury();\n error NotGovernor();\n error NotMinter();\n error NotTreasury();\n error TreasuryAlreadyInitialized();\n\n // =============================== Setup Function ==============================\n\n /// @notice Sets up the treasury contract in this AgToken contract\n /// @param _treasury Treasury contract to add\n /// @dev The address calling this function has to be hard-coded in the contract\n /// @dev Can be called only once\n function setUpTreasury(address _treasury) external {\n // Only governor\n if (msg.sender != 0xdC4e6DFe07EFCa50a197DF15D9200883eF4Eb1c8) revert NotGovernor();\n if (address(ITreasury(_treasury).stablecoin()) != address(this)) revert InvalidTreasury();\n if (treasuryInitialized) revert TreasuryAlreadyInitialized();\n treasury = _treasury;\n treasuryInitialized = true;\n isMinter[stableMaster] = true;\n emit TreasuryUpdated(_treasury);\n }\n\n // =============================== Modifiers ===================================\n\n /// @notice Checks to see if it is the `Treasury` calling this contract\n /// @dev There is no Access Control here, because it can be handled cheaply through this modifier\n modifier onlyTreasury() {\n if (msg.sender != treasury) revert NotTreasury();\n _;\n }\n\n /// @notice Checks whether the sender has the minting right\n modifier onlyMinter() {\n if (!isMinter[msg.sender]) revert NotMinter();\n _;\n }\n\n // ========================= External Functions ================================\n // The following functions allow anyone to burn stablecoins without redeeming collateral\n // in exchange for that\n\n /// @notice Destroys `amount` token from the caller without giving collateral back\n /// @param amount Amount to burn\n /// @param poolManager Reference to the `PoolManager` contract for which the `stocksUsers` will\n /// need to be updated\n /// @dev When calling this function, people should specify the `poolManager` for which they want to decrease\n /// the `stocksUsers`: this is a way for the protocol to maintain healthy accounting variables\n function burnNoRedeem(uint256 amount, address poolManager) external {\n _burn(msg.sender, amount);\n IStableMaster(stableMaster).updateStocksUsers(amount, poolManager);\n }\n\n /// @notice Burns `amount` of agToken on behalf of another account without redeeming collateral back\n /// @param account Account to burn on behalf of\n /// @param amount Amount to burn\n /// @param poolManager Reference to the `PoolManager` contract for which the `stocksUsers` will need to be updated\n function burnFromNoRedeem(address account, uint256 amount, address poolManager) external {\n _burnFromNoRedeem(amount, account, msg.sender);\n IStableMaster(stableMaster).updateStocksUsers(amount, poolManager);\n }\n\n /// @notice Allows anyone to burn agToken without redeeming collateral back\n /// @param amount Amount of stablecoins to burn\n /// @dev This function can typically be called if there is a settlement mechanism to burn stablecoins\n function burnStablecoin(uint256 amount) external {\n _burn(msg.sender, amount);\n }\n\n // ======================= Minter Role Only Functions ==========================\n\n /// @inheritdoc IAgToken\n function burnSelf(uint256 amount, address burner) external onlyMinter {\n _burn(burner, amount);\n }\n\n /// @inheritdoc IAgToken\n function burnFrom(uint256 amount, address burner, address sender) external onlyMinter {\n _burnFromNoRedeem(amount, burner, sender);\n }\n\n /// @inheritdoc IAgToken\n function mint(address account, uint256 amount) external onlyMinter {\n _mint(account, amount);\n }\n\n // ======================= Treasury Only Functions =============================\n\n /// @inheritdoc IAgToken\n function addMinter(address minter) external onlyTreasury {\n isMinter[minter] = true;\n emit MinterToggled(minter);\n }\n\n /// @inheritdoc IAgToken\n function removeMinter(address minter) external {\n // The `treasury` contract cannot remove the `stableMaster`\n if (msg.sender != minter && (msg.sender != address(treasury) || minter == stableMaster)) revert InvalidSender();\n isMinter[minter] = false;\n emit MinterToggled(minter);\n }\n\n /// @inheritdoc IAgToken\n function setTreasury(address _treasury) external onlyTreasury {\n treasury = _treasury;\n emit TreasuryUpdated(_treasury);\n }\n\n // ============================ Internal Function ==============================\n\n /// @notice Internal version of the function `burnFromNoRedeem`\n /// @param amount Amount to burn\n /// @dev It is at the level of this function that allowance checks are performed\n function _burnFromNoRedeem(uint256 amount, address burner, address sender) internal {\n if (burner != sender) {\n uint256 currentAllowance = allowance(burner, sender);\n if (currentAllowance < amount) revert BurnAmountExceedsAllowance();\n _approve(burner, sender, currentAllowance - amount);\n }\n _burn(burner, amount);\n }\n}\n" + }, + "contracts/deprecated/OldAngleHelpers.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\nimport \"../interfaces/IAngleRouter.sol\";\nimport \"../interfaces/coreModule/IAgTokenMainnet.sol\";\nimport \"../interfaces/coreModule/ICore.sol\";\nimport \"../interfaces/coreModule/IOracleCore.sol\";\nimport \"../interfaces/coreModule/IPerpetualManager.sol\";\nimport \"../interfaces/coreModule/IPoolManager.sol\";\nimport \"../interfaces/coreModule/IStableMaster.sol\";\nimport \"@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol\";\nimport \"../interfaces/IVaultManager.sol\";\n\npragma solidity ^0.8.12;\n\nstruct Parameters {\n SLPData slpData;\n MintBurnData feeData;\n PerpetualManagerFeeData perpFeeData;\n PerpetualManagerParamData perpParam;\n}\n\nstruct PerpetualManagerFeeData {\n uint64[] xHAFeesDeposit;\n uint64[] yHAFeesDeposit;\n uint64[] xHAFeesWithdraw;\n uint64[] yHAFeesWithdraw;\n uint64 haBonusMalusDeposit;\n uint64 haBonusMalusWithdraw;\n}\n\nstruct PerpetualManagerParamData {\n uint64 maintenanceMargin;\n uint64 maxLeverage;\n uint64 targetHAHedge;\n uint64 limitHAHedge;\n uint64 lockTime;\n}\n\nstruct CollateralAddresses {\n address stableMaster;\n address poolManager;\n address perpetualManager;\n address sanToken;\n address oracle;\n address gauge;\n address feeManager;\n address[] strategies;\n}\n\n/// @title AngleHelpers\n/// @author Angle Labs, Inc.\n/// @notice Contract with view functions designed to facilitate integrations on the Core module of the Angle Protocol\n/// @dev This contract only contains view functions to be queried off-chain. It was thus not optimized for gas consumption\ncontract OldAngleHelpers is Initializable {\n // ======================== Helper View Functions ==============================\n\n /// @notice Gives the amount of `agToken` you'd be getting if you were executing in the same block a mint transaction\n /// with `amount` of `collateral` in the Core module of the Angle protocol as well as the value of the fees\n /// (in `BASE_PARAMS`) that would be applied during the mint\n /// @return Amount of `agToken` that would be obtained with a mint transaction in the same block\n /// @return Percentage of fees that would be taken during a mint transaction in the same block\n /// @dev This function reverts if the mint transaction was to revert in the same conditions (without taking into account\n /// potential approval problems to the `StableMaster` contract)\n function previewMintAndFees(\n uint256 amount,\n address agToken,\n address collateral\n ) external view returns (uint256, uint256) {\n return _previewMintAndFees(amount, agToken, collateral);\n }\n\n /// @notice Gives the amount of `collateral` you'd be getting if you were executing in the same block a burn transaction\n /// with `amount` of `agToken` in the Core module of the Angle protocol as well as the value of the fees\n /// (in `BASE_PARAMS`) that would be applied during the burn\n /// @return Amount of `collateral` that would be obtained with a burn transaction in the same block\n /// @return Percentage of fees that would be taken during a burn transaction in the same block\n /// @dev This function reverts if the burn transaction was to revert in the same conditions (without taking into account\n /// potential approval problems to the `StableMaster` contract or agToken balance prior to the call)\n function previewBurnAndFees(\n uint256 amount,\n address agToken,\n address collateral\n ) external view returns (uint256, uint256) {\n return _previewBurnAndFees(amount, agToken, collateral);\n }\n\n /// @notice Returns all the addresses associated to the (`agToken`,`collateral`) pair given\n /// @return addresses A struct with all the addresses associated in the Core module\n function getCollateralAddresses(\n address agToken,\n address collateral\n ) external view returns (CollateralAddresses memory addresses) {\n address stableMaster = IAgTokenMainnet(agToken).stableMaster();\n (address poolManager, address perpetualManager, address sanToken, address gauge) = ROUTER.mapPoolManagers(\n stableMaster,\n collateral\n );\n (, , , IOracleCore oracle, , , , , ) = IStableMaster(stableMaster).collateralMap(poolManager);\n addresses.stableMaster = stableMaster;\n addresses.poolManager = poolManager;\n addresses.perpetualManager = perpetualManager;\n addresses.sanToken = sanToken;\n addresses.gauge = gauge;\n addresses.oracle = address(oracle);\n addresses.feeManager = IPoolManager(poolManager).feeManager();\n\n uint256 length = 0;\n while (true) {\n try IPoolManager(poolManager).strategyList(length) returns (address) {\n length += 1;\n } catch {\n break;\n }\n }\n address[] memory strategies = new address[](length);\n for (uint256 i; i < length; ++i) {\n strategies[i] = IPoolManager(poolManager).strategyList(i);\n }\n addresses.strategies = strategies;\n }\n\n /// @notice Gets the addresses of all the `StableMaster` contracts and their associated `AgToken` addresses\n /// @return List of the `StableMaster` addresses of the Angle protocol\n /// @return List of the `AgToken` addresses of the protocol\n /// @dev The place of an agToken address in the list is the same as the corresponding `StableMaster` address\n function getStablecoinAddresses() external view returns (address[] memory, address[] memory) {\n address[] memory stableMasterAddresses = CORE.stablecoinList();\n address[] memory agTokenAddresses = new address[](stableMasterAddresses.length);\n for (uint256 i; i < stableMasterAddresses.length; ++i) {\n agTokenAddresses[i] = IStableMaster(stableMasterAddresses[i]).agToken();\n }\n return (stableMasterAddresses, agTokenAddresses);\n }\n\n /// @notice Returns most of the governance parameters associated to the (`agToken`,`collateral`) pair given\n /// @return params Struct with most of the parameters in the `StableMaster` and `PerpetualManager` contracts\n /// @dev Check out the struct `Parameters` for the meaning of the return values\n function getCollateralParameters(\n address agToken,\n address collateral\n ) external view returns (Parameters memory params) {\n (address stableMaster, address poolManager) = _getStableMasterAndPoolManager(agToken, collateral);\n (\n ,\n ,\n IPerpetualManager perpetualManager,\n ,\n ,\n ,\n ,\n SLPData memory slpData,\n MintBurnData memory feeData\n ) = IStableMaster(stableMaster).collateralMap(poolManager);\n\n params.slpData = slpData;\n params.feeData = feeData;\n params.perpParam.maintenanceMargin = perpetualManager.maintenanceMargin();\n params.perpParam.maxLeverage = perpetualManager.maxLeverage();\n params.perpParam.targetHAHedge = perpetualManager.targetHAHedge();\n params.perpParam.limitHAHedge = perpetualManager.limitHAHedge();\n params.perpParam.lockTime = perpetualManager.lockTime();\n\n params.perpFeeData.haBonusMalusDeposit = perpetualManager.haBonusMalusDeposit();\n params.perpFeeData.haBonusMalusWithdraw = perpetualManager.haBonusMalusWithdraw();\n\n uint256 length = 0;\n while (true) {\n try perpetualManager.xHAFeesDeposit(length) returns (uint64) {\n length += 1;\n } catch {\n break;\n }\n }\n uint64[] memory data = new uint64[](length);\n uint64[] memory data2 = new uint64[](length);\n for (uint256 i; i < length; ++i) {\n data[i] = perpetualManager.xHAFeesDeposit(i);\n data2[i] = perpetualManager.yHAFeesDeposit(i);\n }\n params.perpFeeData.xHAFeesDeposit = data;\n params.perpFeeData.yHAFeesDeposit = data2;\n\n length = 0;\n while (true) {\n try perpetualManager.xHAFeesWithdraw(length) returns (uint64) {\n length += 1;\n } catch {\n break;\n }\n }\n data = new uint64[](length);\n data2 = new uint64[](length);\n for (uint256 i; i < length; ++i) {\n data[i] = perpetualManager.xHAFeesWithdraw(i);\n data2[i] = perpetualManager.yHAFeesWithdraw(i);\n }\n params.perpFeeData.xHAFeesWithdraw = data;\n params.perpFeeData.yHAFeesWithdraw = data2;\n }\n\n /// @notice Returns the address of the poolManager associated to an (`agToken`, `collateral`) pair\n /// in the Core module of the protocol\n function getPoolManager(address agToken, address collateral) public view returns (address poolManager) {\n (, poolManager) = _getStableMasterAndPoolManager(agToken, collateral);\n }\n\n // ======================== Replica Functions ==================================\n // These replicate what is done in the other contracts of the protocol\n\n function _previewBurnAndFees(\n uint256 amount,\n address agToken,\n address collateral\n ) internal view returns (uint256 amountForUserInCollat, uint256 feePercent) {\n (address stableMaster, address poolManager) = _getStableMasterAndPoolManager(agToken, collateral);\n (\n address token,\n ,\n IPerpetualManager perpetualManager,\n IOracleCore oracle,\n uint256 stocksUsers,\n ,\n uint256 collatBase,\n ,\n MintBurnData memory feeData\n ) = IStableMaster(stableMaster).collateralMap(poolManager);\n if (token == address(0) || IStableMaster(stableMaster).paused(keccak256(abi.encodePacked(STABLE, poolManager))))\n revert NotInitialized();\n if (amount > stocksUsers) revert InvalidAmount();\n\n if (feeData.xFeeBurn.length == 1) {\n feePercent = feeData.yFeeBurn[0];\n } else {\n bytes memory data = abi.encode(address(perpetualManager), feeData.targetHAHedge);\n uint64 hedgeRatio = _computeHedgeRatio(stocksUsers - amount, data);\n feePercent = _piecewiseLinear(hedgeRatio, feeData.xFeeBurn, feeData.yFeeBurn);\n }\n feePercent = (feePercent * feeData.bonusMalusBurn) / BASE_PARAMS;\n\n amountForUserInCollat = (amount * (BASE_PARAMS - feePercent) * collatBase) / (oracle.readUpper() * BASE_PARAMS);\n }\n\n function _previewMintAndFees(\n uint256 amount,\n address agToken,\n address collateral\n ) internal view returns (uint256 amountForUserInStable, uint256 feePercent) {\n (address stableMaster, address poolManager) = _getStableMasterAndPoolManager(agToken, collateral);\n (\n address token,\n ,\n IPerpetualManager perpetualManager,\n IOracleCore oracle,\n uint256 stocksUsers,\n ,\n ,\n ,\n MintBurnData memory feeData\n ) = IStableMaster(stableMaster).collateralMap(poolManager);\n if (token == address(0) || IStableMaster(stableMaster).paused(keccak256(abi.encodePacked(STABLE, poolManager))))\n revert NotInitialized();\n\n amountForUserInStable = oracle.readQuoteLower(amount);\n\n if (feeData.xFeeMint.length == 1) feePercent = feeData.yFeeMint[0];\n else {\n bytes memory data = abi.encode(address(perpetualManager), feeData.targetHAHedge);\n uint64 hedgeRatio = _computeHedgeRatio(amountForUserInStable + stocksUsers, data);\n feePercent = _piecewiseLinear(hedgeRatio, feeData.xFeeMint, feeData.yFeeMint);\n }\n feePercent = (feePercent * feeData.bonusMalusMint) / BASE_PARAMS;\n\n amountForUserInStable = (amountForUserInStable * (BASE_PARAMS - feePercent)) / BASE_PARAMS;\n if (stocksUsers + amountForUserInStable > feeData.capOnStableMinted) revert InvalidAmount();\n }\n\n // ======================== Utility Functions ==================================\n // These utility functions are taken from other contracts of the protocol\n\n function _computeHedgeRatio(uint256 newStocksUsers, bytes memory data) internal view returns (uint64 ratio) {\n (address perpetualManager, uint64 targetHAHedge) = abi.decode(data, (address, uint64));\n uint256 totalHedgeAmount = IPerpetualManager(perpetualManager).totalHedgeAmount();\n newStocksUsers = (targetHAHedge * newStocksUsers) / BASE_PARAMS;\n if (newStocksUsers > totalHedgeAmount) ratio = uint64((totalHedgeAmount * BASE_PARAMS) / newStocksUsers);\n else ratio = uint64(BASE_PARAMS);\n }\n\n function _piecewiseLinear(uint64 x, uint64[] memory xArray, uint64[] memory yArray) internal pure returns (uint64) {\n if (x >= xArray[xArray.length - 1]) {\n return yArray[xArray.length - 1];\n } else if (x <= xArray[0]) {\n return yArray[0];\n } else {\n uint256 lower;\n uint256 upper = xArray.length - 1;\n uint256 mid;\n while (upper - lower > 1) {\n mid = lower + (upper - lower) / 2;\n if (xArray[mid] <= x) {\n lower = mid;\n } else {\n upper = mid;\n }\n }\n if (yArray[upper] > yArray[lower]) {\n return\n yArray[lower] +\n ((yArray[upper] - yArray[lower]) * (x - xArray[lower])) /\n (xArray[upper] - xArray[lower]);\n } else {\n return\n yArray[lower] -\n ((yArray[lower] - yArray[upper]) * (x - xArray[lower])) /\n (xArray[upper] - xArray[lower]);\n }\n }\n }\n\n function _getStableMasterAndPoolManager(\n address agToken,\n address collateral\n ) internal view returns (address stableMaster, address poolManager) {\n stableMaster = IAgTokenMainnet(agToken).stableMaster();\n (poolManager, , , ) = ROUTER.mapPoolManagers(stableMaster, collateral);\n }\n\n // ====================== Constants and Initializers ===========================\n\n IAngleRouter public constant ROUTER = IAngleRouter(0xBB755240596530be0c1DE5DFD77ec6398471561d);\n ICore public constant CORE = ICore(0x61ed74de9Ca5796cF2F8fD60D54160D47E30B7c3);\n\n bytes32 public constant STABLE = keccak256(\"STABLE\");\n uint256 public constant BASE_PARAMS = 10 ** 9;\n\n error NotInitialized();\n error InvalidAmount();\n\n /// @custom:oz-upgrades-unsafe-allow constructor\n constructor() initializer {}\n}\n" + }, + "contracts/deprecated/vaultManager/OldVaultManagerERC721.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\nimport \"./OldVaultManagerStorage.sol\";\n\n/// @title VaultManagerERC721\n/// @author Angle Labs, Inc.\n/// @dev Base ERC721 Implementation of VaultManager\nabstract contract OldVaultManagerERC721 is IERC721MetadataUpgradeable, OldVaultManagerStorage {\n using SafeERC20 for IERC20;\n using Address for address;\n\n /// @inheritdoc IERC721MetadataUpgradeable\n string public name;\n /// @inheritdoc IERC721MetadataUpgradeable\n string public symbol;\n\n // ================================= MODIFIERS =================================\n\n /// @notice Checks if the person interacting with the vault with `vaultID` is approved\n /// @param caller Address of the person seeking to interact with the vault\n /// @param vaultID ID of the concerned vault\n modifier onlyApprovedOrOwner(address caller, uint256 vaultID) {\n if (!_isApprovedOrOwner(caller, vaultID)) revert NotApproved();\n _;\n }\n\n // ================================ ERC721 LOGIC ===============================\n\n /// @notice Checks whether a given address is approved for a vault or owns this vault\n /// @param spender Address for which vault ownership should be checked\n /// @param vaultID ID of the vault to check\n /// @return Whether the `spender` address owns or is approved for `vaultID`\n function isApprovedOrOwner(address spender, uint256 vaultID) external view returns (bool) {\n return _isApprovedOrOwner(spender, vaultID);\n }\n\n /// @inheritdoc IERC721MetadataUpgradeable\n function tokenURI(uint256 vaultID) external view returns (string memory) {\n if (!_exists(vaultID)) revert NonexistentVault();\n // There is no vault with `vaultID` equal to 0, so the following variable is\n // always greater than zero\n uint256 temp = vaultID;\n uint256 digits;\n while (temp != 0) {\n digits++;\n temp /= 10;\n }\n bytes memory buffer = new bytes(digits);\n while (vaultID != 0) {\n digits -= 1;\n buffer[digits] = bytes1(uint8(48 + uint256(vaultID % 10)));\n vaultID /= 10;\n }\n return bytes(_baseURI).length > 0 ? string(abi.encodePacked(_baseURI, string(buffer))) : \"\";\n }\n\n /// @inheritdoc IERC721Upgradeable\n function balanceOf(address owner) external view returns (uint256) {\n if (owner == address(0)) revert ZeroAddress();\n return _balances[owner];\n }\n\n /// @inheritdoc IERC721Upgradeable\n function ownerOf(uint256 vaultID) external view returns (address) {\n return _ownerOf(vaultID);\n }\n\n /// @inheritdoc IERC721Upgradeable\n function approve(address to, uint256 vaultID) external {\n address owner = _ownerOf(vaultID);\n if (to == owner) revert ApprovalToOwner();\n if (msg.sender != owner && !isApprovedForAll(owner, msg.sender)) revert NotApproved();\n\n _approve(to, vaultID);\n }\n\n /// @inheritdoc IERC721Upgradeable\n function getApproved(uint256 vaultID) external view returns (address) {\n if (!_exists(vaultID)) revert NonexistentVault();\n return _getApproved(vaultID);\n }\n\n /// @inheritdoc IERC721Upgradeable\n function setApprovalForAll(address operator, bool approved) external {\n _setApprovalForAll(msg.sender, operator, approved);\n }\n\n /// @inheritdoc IERC721Upgradeable\n function isApprovedForAll(address owner, address operator) public view returns (bool) {\n return _operatorApprovals[owner][operator] == 1;\n }\n\n /// @inheritdoc IERC721Upgradeable\n function transferFrom(address from, address to, uint256 vaultID) external onlyApprovedOrOwner(msg.sender, vaultID) {\n _transfer(from, to, vaultID);\n }\n\n /// @inheritdoc IERC721Upgradeable\n function safeTransferFrom(address from, address to, uint256 vaultID) external {\n safeTransferFrom(from, to, vaultID, \"\");\n }\n\n /// @inheritdoc IERC721Upgradeable\n function safeTransferFrom(\n address from,\n address to,\n uint256 vaultID,\n bytes memory _data\n ) public onlyApprovedOrOwner(msg.sender, vaultID) {\n _safeTransfer(from, to, vaultID, _data);\n }\n\n // ================================ ERC165 LOGIC ===============================\n\n /// @inheritdoc IERC165Upgradeable\n function supportsInterface(bytes4 interfaceId) external pure returns (bool) {\n return\n interfaceId == type(IERC721MetadataUpgradeable).interfaceId ||\n interfaceId == type(IERC721Upgradeable).interfaceId ||\n interfaceId == type(IVaultManager).interfaceId ||\n interfaceId == type(IERC165Upgradeable).interfaceId;\n }\n\n // ================== INTERNAL FUNCTIONS FOR THE ERC721 LOGIC ==================\n\n /// @notice Internal version of the `ownerOf` function\n function _ownerOf(uint256 vaultID) internal view returns (address owner) {\n owner = _owners[vaultID];\n if (owner == address(0)) revert NonexistentVault();\n }\n\n /// @notice Internal version of the `getApproved` function\n function _getApproved(uint256 vaultID) internal view returns (address) {\n return _vaultApprovals[vaultID];\n }\n\n /// @notice Internal version of the `safeTransferFrom` function (with the data parameter)\n function _safeTransfer(address from, address to, uint256 vaultID, bytes memory _data) internal {\n _transfer(from, to, vaultID);\n if (!_checkOnERC721Received(from, to, vaultID, _data)) revert NonERC721Receiver();\n }\n\n /// @notice Checks whether a vault exists\n /// @param vaultID ID of the vault to check\n /// @return Whether `vaultID` has been created\n function _exists(uint256 vaultID) internal view returns (bool) {\n return _owners[vaultID] != address(0);\n }\n\n /// @notice Internal version of the `isApprovedOrOwner` function\n function _isApprovedOrOwner(address spender, uint256 vaultID) internal view returns (bool) {\n // The following checks if the vault exists\n address owner = _ownerOf(vaultID);\n return (spender == owner || _getApproved(vaultID) == spender || _operatorApprovals[owner][spender] == 1);\n }\n\n /// @notice Internal version of the `createVault` function\n /// Mints `vaultID` and transfers it to `to`\n /// @dev This method is equivalent to the `_safeMint` method used in OpenZeppelin ERC721 contract\n /// @dev Emits a {Transfer} event\n function _mint(address to) internal returns (uint256 vaultID) {\n if (whitelistingActivated && (isWhitelisted[to] != 1 || isWhitelisted[msg.sender] != 1))\n revert NotWhitelisted();\n if (to == address(0)) revert ZeroAddress();\n\n unchecked {\n vaultIDCount += 1;\n }\n\n vaultID = vaultIDCount;\n _beforeTokenTransfer(address(0), to, vaultID);\n\n unchecked {\n _balances[to] += 1;\n }\n\n _owners[vaultID] = to;\n emit Transfer(address(0), to, vaultID);\n if (!_checkOnERC721Received(address(0), to, vaultID, \"\")) revert NonERC721Receiver();\n }\n\n /// @notice Destroys `vaultID`\n /// @dev `vaultID` must exist\n /// @dev Emits a {Transfer} event\n function _burn(uint256 vaultID) internal {\n address owner = _ownerOf(vaultID);\n\n _beforeTokenTransfer(owner, address(0), vaultID);\n // Clear approvals\n _approve(address(0), vaultID);\n // The following line cannot underflow as the owner's balance is necessarily\n // greater than 1\n unchecked {\n _balances[owner] -= 1;\n }\n delete _owners[vaultID];\n delete vaultData[vaultID];\n\n emit Transfer(owner, address(0), vaultID);\n }\n\n /// @notice Transfers `vaultID` from `from` to `to` as opposed to {transferFrom},\n /// this imposes no restrictions on msg.sender\n /// @dev `to` cannot be the zero address and `perpetualID` must be owned by `from`\n /// @dev Emits a {Transfer} event\n /// @dev A whitelist check is performed if necessary on the `to` address\n function _transfer(address from, address to, uint256 vaultID) internal {\n if (_ownerOf(vaultID) != from) revert NotApproved();\n if (to == address(0)) revert ZeroAddress();\n if (whitelistingActivated && isWhitelisted[to] != 1) revert NotWhitelisted();\n\n _beforeTokenTransfer(from, to, vaultID);\n\n // Clear approvals from the previous owner\n _approve(address(0), vaultID);\n unchecked {\n _balances[from] -= 1;\n _balances[to] += 1;\n }\n _owners[vaultID] = to;\n\n emit Transfer(from, to, vaultID);\n }\n\n /// @notice Approves `to` to operate on `vaultID`\n function _approve(address to, uint256 vaultID) internal {\n _vaultApprovals[vaultID] = to;\n emit Approval(_ownerOf(vaultID), to, vaultID);\n }\n\n /// @notice Internal version of the `setApprovalForAll` function\n /// @dev It contains an `approver` field to be used in case someone signs a permit for a particular\n /// address, and this signature is given to the contract by another address (like a router)\n function _setApprovalForAll(address approver, address operator, bool approved) internal {\n if (operator == approver) revert ApprovalToCaller();\n uint256 approval = approved ? 1 : 0;\n _operatorApprovals[approver][operator] = approval;\n emit ApprovalForAll(approver, operator, approved);\n }\n\n /// @notice Internal function to invoke {IERC721Receiver-onERC721Received} on a target address\n /// The call is not executed if the target address is not a contract\n /// @param from Address representing the previous owner of the given token ID\n /// @param to Target address that will receive the tokens\n /// @param vaultID ID of the token to be transferred\n /// @param _data Bytes optional data to send along with the call\n /// @return Bool whether the call correctly returned the expected value\n function _checkOnERC721Received(\n address from,\n address to,\n uint256 vaultID,\n bytes memory _data\n ) private returns (bool) {\n if (to.isContract()) {\n try IERC721ReceiverUpgradeable(to).onERC721Received(msg.sender, from, vaultID, _data) returns (\n bytes4 retval\n ) {\n return retval == IERC721ReceiverUpgradeable.onERC721Received.selector;\n } catch (bytes memory reason) {\n if (reason.length == 0) {\n revert NonERC721Receiver();\n } else {\n // solhint-disable-next-line no-inline-assembly\n assembly {\n revert(add(32, reason), mload(reason))\n }\n }\n }\n } else {\n return true;\n }\n }\n\n /// @notice Hook that is called before any token transfer. This includes minting and burning.\n /// Calling conditions:\n ///\n /// - When `from` and `to` are both non-zero, `from`'s `vaultID` will be\n /// transferred to `to`.\n /// - When `from` is zero, `vaultID` will be minted for `to`.\n /// - When `to` is zero, `from`'s `vaultID` will be burned.\n /// - `from` and `to` are never both zero.\n function _beforeTokenTransfer(address from, address to, uint256 vaultID) internal virtual {}\n}\n" + }, + "contracts/deprecated/vaultManager/OldVaultManagerPermit.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\nimport \"./OldVaultManagerERC721.sol\";\nimport \"../../interfaces/external/IERC1271.sol\";\n\n/// @title VaultManagerPermit\n/// @author Angle Labs, Inc.\n/// @dev Base Implementation of permit functions for the `VaultManager` contract\nabstract contract OldVaultManagerPermit is Initializable, OldVaultManagerERC721 {\n using Address for address;\n\n mapping(address => uint256) private _nonces;\n /* solhint-disable var-name-mixedcase */\n bytes32 private _HASHED_NAME;\n bytes32 private _HASHED_VERSION;\n bytes32 private _PERMIT_TYPEHASH;\n /* solhint-enable var-name-mixedcase */\n\n error ExpiredDeadline();\n error InvalidSignature();\n\n //solhint-disable-next-line\n function __ERC721Permit_init(string memory _name) internal onlyInitializing {\n _PERMIT_TYPEHASH = keccak256(\n \"Permit(address owner,address spender,bool approved,uint256 nonce,uint256 deadline)\"\n );\n _HASHED_NAME = keccak256(bytes(_name));\n _HASHED_VERSION = keccak256(bytes(\"1\"));\n }\n\n /// @notice Allows an address to give or revoke approval for all its vaults to another address\n /// @param owner Address signing the permit and giving (or revoking) its approval for all the controlled vaults\n /// @param spender Address to give approval to\n /// @param approved Whether to give or revoke the approval\n /// @param deadline Deadline parameter for the signature to be valid\n /// @dev The `v`, `r`, and `s` parameters are used as signature data\n function permit(\n address owner,\n address spender,\n bool approved,\n uint256 deadline,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) external {\n if (block.timestamp > deadline) revert ExpiredDeadline();\n // Additional signature checks performed in the `ECDSAUpgradeable.recover` function\n if (uint256(s) > 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D576E7357A4501DDFE92F46681B20A0 || (v != 27 && v != 28))\n revert InvalidSignature();\n\n bytes32 digest = keccak256(\n abi.encodePacked(\n \"\\x19\\x01\",\n _domainSeparatorV4(),\n keccak256(\n abi.encode(\n _PERMIT_TYPEHASH,\n // 0x3f43a9c6bafb5c7aab4e0cfe239dc5d4c15caf0381c6104188191f78a6640bd8,\n owner,\n spender,\n approved,\n _useNonce(owner),\n deadline\n )\n )\n )\n );\n if (owner.isContract()) {\n if (IERC1271(owner).isValidSignature(digest, abi.encodePacked(r, s, v)) != 0x1626ba7e)\n revert InvalidSignature();\n } else {\n address signer = ecrecover(digest, v, r, s);\n if (signer != owner || signer == address(0)) revert InvalidSignature();\n }\n\n _setApprovalForAll(owner, spender, approved);\n }\n\n /// @notice Returns the current nonce for an `owner` address\n function nonces(address owner) public view returns (uint256) {\n return _nonces[owner];\n }\n\n /// @notice Returns the domain separator for the current chain.\n // solhint-disable-next-line func-name-mixedcase\n function DOMAIN_SEPARATOR() external view returns (bytes32) {\n return _domainSeparatorV4();\n }\n\n /// @notice Internal version of the `DOMAIN_SEPARATOR` function\n function _domainSeparatorV4() internal view returns (bytes32) {\n return\n keccak256(\n abi.encode(\n // keccak256('EIP712Domain(string name,string version,uint256 chainId,address verifyingContract)')\n 0x8b73c3c69bb8fe3d512ecc4cf759cc79239f7b179b0ffacaa9a75d522b39400f,\n _HASHED_NAME,\n _HASHED_VERSION,\n block.chainid,\n address(this)\n )\n );\n }\n\n /// @notice Consumes a nonce for an address: returns the current value and increments it\n function _useNonce(address owner) internal returns (uint256 current) {\n current = _nonces[owner];\n _nonces[owner] = current + 1;\n }\n\n uint256[49] private __gap;\n}\n" + }, + "contracts/deprecated/vaultManager/OldVaultManagerStorage.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\nimport \"@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/token/ERC20/extensions/draft-IERC20PermitUpgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/token/ERC721/IERC721ReceiverUpgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/interfaces/IERC721MetadataUpgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/utils/introspection/IERC165Upgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/utils/AddressUpgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/security/ReentrancyGuardUpgradeable.sol\";\nimport \"@openzeppelin/contracts/token/ERC20/extensions/IERC20Metadata.sol\";\nimport \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\nimport \"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\";\n\nimport \"../../interfaces/IAgToken.sol\";\nimport \"../../interfaces/IOracle.sol\";\nimport \"../../interfaces/ISwapper.sol\";\nimport \"../../interfaces/ITreasury.sol\";\nimport \"../../interfaces/IVaultManager.sol\";\nimport \"../../interfaces/governance/IVeBoostProxy.sol\";\n\n/// @title VaultManagerStorage\n/// @author Angle Labs, Inc.\n/// @dev Variables, references, parameters and events needed in the `VaultManager` contract\n// solhint-disable-next-line max-states-count\ncontract OldVaultManagerStorage is IVaultManagerStorage, Initializable, ReentrancyGuardUpgradeable {\n /// @notice Base used for parameter computation: almost all the parameters of this contract are set in `BASE_PARAMS`\n uint256 public constant BASE_PARAMS = 10 ** 9;\n /// @notice Base used for interest rate computation\n uint256 public constant BASE_INTEREST = 10 ** 27;\n /// @notice Used for interest rate computation\n uint256 public constant HALF_BASE_INTEREST = 10 ** 27 / 2;\n\n // ================================= REFERENCES ================================\n\n /// @inheritdoc IVaultManagerStorage\n ITreasury public treasury;\n /// @inheritdoc IVaultManagerStorage\n IERC20 public collateral;\n /// @inheritdoc IVaultManagerStorage\n IAgToken public stablecoin;\n /// @inheritdoc IVaultManagerStorage\n IOracle public oracle;\n /// @notice Reference to the contract which computes adjusted veANGLE balances for liquidators boosts\n IVeBoostProxy public veBoostProxy;\n /// @notice Base of the collateral\n uint256 internal _collatBase;\n\n // ================================= PARAMETERS ================================\n // Unless specified otherwise, parameters of this contract are expressed in `BASE_PARAMS`\n\n /// @notice Maximum amount of stablecoins that can be issued with this contract (in `BASE_TOKENS`). This parameter should\n /// not be bigger than `type(uint256).max / BASE_INTEREST` otherwise there may be some overflows in the `increaseDebt` function\n uint256 public debtCeiling;\n /// @notice Threshold veANGLE balance values for the computation of the boost for liquidators: the length of this array\n /// should normally be 2. The base of the x-values in this array should be `BASE_TOKENS`\n uint256[] public xLiquidationBoost;\n /// @notice Values of the liquidation boost at the threshold values of x\n uint256[] public yLiquidationBoost;\n /// @inheritdoc IVaultManagerStorage\n uint64 public collateralFactor;\n /// @notice Maximum Health factor at which a vault can end up after a liquidation (unless it's fully liquidated)\n uint64 public targetHealthFactor;\n /// @notice Upfront fee taken when borrowing stablecoins: this fee is optional and should in practice not be used\n uint64 public borrowFee;\n /// @notice Upfront fee taken when repaying stablecoins: this fee is optional as well. It should be smaller\n /// than the liquidation surcharge (cf below) to avoid exploits where people voluntarily get liquidated at a 0\n /// discount to pay smaller repaying fees\n uint64 public repayFee;\n /// @notice Per second interest taken to borrowers taking agToken loans. Contrarily to other parameters, it is set in `BASE_INTEREST`\n /// that is to say in base 10**27\n uint64 public interestRate;\n /// @notice Fee taken by the protocol during a liquidation. Technically, this value is not the fee per se, it's 1 - fee.\n /// For instance for a 2% fee, `liquidationSurcharge` should be 98%\n uint64 public liquidationSurcharge;\n /// @notice Maximum discount given to liquidators\n uint64 public maxLiquidationDiscount;\n /// @notice Whether whitelisting is required to own a vault or not\n bool public whitelistingActivated;\n /// @notice Whether the contract is paused or not\n bool public paused;\n\n // ================================= VARIABLES =================================\n\n /// @notice Timestamp at which the `interestAccumulator` was updated\n uint256 public lastInterestAccumulatorUpdated;\n /// @inheritdoc IVaultManagerStorage\n uint256 public interestAccumulator;\n /// @inheritdoc IVaultManagerStorage\n uint256 public totalNormalizedDebt;\n /// @notice Surplus accumulated by the contract: surplus is always in stablecoins, and is then reset\n /// when the value is communicated to the treasury contract\n uint256 public surplus;\n /// @notice Bad debt made from liquidated vaults which ended up having no collateral and a positive amount\n /// of stablecoins\n uint256 public badDebt;\n\n // ================================== MAPPINGS =================================\n\n /// @inheritdoc IVaultManagerStorage\n mapping(uint256 => Vault) public vaultData;\n /// @notice Maps an address to 1 if it's whitelisted and can open or own a vault\n mapping(address => uint256) public isWhitelisted;\n\n // ================================ ERC721 DATA ================================\n\n /// @inheritdoc IVaultManagerStorage\n uint256 public vaultIDCount;\n\n /// @notice URI\n string internal _baseURI;\n\n // Mapping from `vaultID` to owner address\n mapping(uint256 => address) internal _owners;\n\n // Mapping from owner address to vault owned count\n mapping(address => uint256) internal _balances;\n\n // Mapping from `vaultID` to approved address\n mapping(uint256 => address) internal _vaultApprovals;\n\n // Mapping from owner to operator approvals\n mapping(address => mapping(address => uint256)) internal _operatorApprovals;\n\n uint256[50] private __gap;\n\n // =================================== EVENTS ==================================\n\n event AccruedToTreasury(uint256 surplusEndValue, uint256 badDebtEndValue);\n event CollateralAmountUpdated(uint256 vaultID, uint256 collateralAmount, uint8 isIncrease);\n event InterestAccumulatorUpdated(uint256 value, uint256 timestamp);\n event InternalDebtUpdated(uint256 vaultID, uint256 internalAmount, uint8 isIncrease);\n event FiledUint64(uint64 param, bytes32 what);\n event DebtCeilingUpdated(uint256 debtCeiling);\n event LiquidationBoostParametersUpdated(address indexed _veBoostProxy, uint256[] xBoost, uint256[] yBoost);\n event LiquidatedVaults(uint256[] vaultIDs);\n event DebtTransferred(uint256 srcVaultID, uint256 dstVaultID, address dstVaultManager, uint256 amount);\n\n // =================================== ERRORS ==================================\n\n error ApprovalToOwner();\n error ApprovalToCaller();\n error DustyLeftoverAmount();\n error DebtCeilingExceeded();\n error HealthyVault();\n error IncompatibleLengths();\n error InsolventVault();\n error InvalidParameterValue();\n error InvalidParameterType();\n error InvalidSetOfParameters();\n error InvalidTreasury();\n error NonERC721Receiver();\n error NonexistentVault();\n error NotApproved();\n error NotGovernor();\n error NotGovernorOrGuardian();\n error NotTreasury();\n error NotWhitelisted();\n error NotVaultManager();\n error Paused();\n error TooHighParameterValue();\n error TooSmallParameterValue();\n error ZeroAddress();\n\n /// @custom:oz-upgrades-unsafe-allow constructor\n constructor() initializer {}\n}\n" + }, + "contracts/external/ProxyAdmin.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\nimport \"./TransparentUpgradeableProxy.sol\";\nimport \"@openzeppelin/contracts/access/Ownable.sol\";\n\n/**\n * @dev This is an auxiliary contract meant to be assigned as the admin of a {TransparentUpgradeableProxy}. For an\n * explanation of why you would want to use this see the documentation for {TransparentUpgradeableProxy}.\n * This contract was fully forked from OpenZeppelin `ProxyAdmin`\n */\ncontract ProxyAdmin is Ownable {\n /**\n * @dev Returns the current implementation of `proxy`.\n *\n * Requirements:\n *\n * - This contract must be the admin of `proxy`.\n */\n function getProxyImplementation(TransparentUpgradeableProxy proxy) public view virtual returns (address) {\n // We need to manually run the static call since the getter cannot be flagged as view\n // bytes4(keccak256(\"implementation()\")) == 0x5c60da1b\n (bool success, bytes memory returndata) = address(proxy).staticcall(hex\"5c60da1b\");\n require(success);\n return abi.decode(returndata, (address));\n }\n\n /**\n * @dev Returns the current admin of `proxy`.\n *\n * Requirements:\n *\n * - This contract must be the admin of `proxy`.\n */\n function getProxyAdmin(TransparentUpgradeableProxy proxy) public view virtual returns (address) {\n // We need to manually run the static call since the getter cannot be flagged as view\n // bytes4(keccak256(\"admin()\")) == 0xf851a440\n (bool success, bytes memory returndata) = address(proxy).staticcall(hex\"f851a440\");\n require(success);\n return abi.decode(returndata, (address));\n }\n\n /**\n * @dev Changes the admin of `proxy` to `newAdmin`.\n *\n * Requirements:\n *\n * - This contract must be the current admin of `proxy`.\n */\n function changeProxyAdmin(TransparentUpgradeableProxy proxy, address newAdmin) public virtual onlyOwner {\n proxy.changeAdmin(newAdmin);\n }\n\n /**\n * @dev Upgrades `proxy` to `implementation`. See {TransparentUpgradeableProxy-upgradeTo}.\n *\n * Requirements:\n *\n * - This contract must be the admin of `proxy`.\n */\n function upgrade(TransparentUpgradeableProxy proxy, address implementation) public virtual onlyOwner {\n proxy.upgradeTo(implementation);\n }\n\n /**\n * @dev Upgrades `proxy` to `implementation` and calls a function on the new implementation. See\n * {TransparentUpgradeableProxy-upgradeToAndCall}.\n *\n * Requirements:\n *\n * - This contract must be the admin of `proxy`.\n */\n function upgradeAndCall(\n TransparentUpgradeableProxy proxy,\n address implementation,\n bytes memory data\n ) public payable virtual onlyOwner {\n proxy.upgradeToAndCall{ value: msg.value }(implementation, data);\n }\n}\n" + }, + "contracts/external/TransparentUpgradeableProxy.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\nimport \"@openzeppelin/contracts/proxy/ERC1967/ERC1967Proxy.sol\";\n\n/**\n * @dev This contract implements a proxy that is upgradeable by an admin. It is fully forked from OpenZeppelin\n * `TransparentUpgradeableProxy`\n *\n * To avoid https://medium.com/nomic-labs-blog/malicious-backdoors-in-ethereum-proxies-62629adf3357[proxy selector\n * clashing], which can potentially be used in an attack, this contract uses the\n * https://blog.openzeppelin.com/the-transparent-proxy-pattern/[transparent proxy pattern]. This pattern implies two\n * things that go hand in hand:\n *\n * 1. If any account other than the admin calls the proxy, the call will be forwarded to the implementation, even if\n * that call matches one of the admin functions exposed by the proxy itself.\n * 2. If the admin calls the proxy, it can access the admin functions, but its calls will never be forwarded to the\n * implementation. If the admin tries to call a function on the implementation it will fail with an error that says\n * \"admin cannot fallback to proxy target\".\n *\n * These properties mean that the admin account can only be used for admin actions like upgrading the proxy or changing\n * the admin, so it's best if it's a dedicated account that is not used for anything else. This will avoid headaches due\n * to sudden errors when trying to call a function from the proxy implementation.\n *\n * Our recommendation is for the dedicated account to be an instance of the {ProxyAdmin} contract. If set up this way,\n * you should think of the `ProxyAdmin` instance as the real administrative interface of your proxy.\n */\ncontract TransparentUpgradeableProxy is ERC1967Proxy {\n /**\n * @dev Initializes an upgradeable proxy managed by `_admin`, backed by the implementation at `_logic`, and\n * optionally initialized with `_data` as explained in {ERC1967Proxy-constructor}.\n */\n constructor(address _logic, address admin_, bytes memory _data) payable ERC1967Proxy(_logic, _data) {\n assert(_ADMIN_SLOT == bytes32(uint256(keccak256(\"eip1967.proxy.admin\")) - 1));\n _changeAdmin(admin_);\n }\n\n /**\n * @dev Modifier used internally that will delegate the call to the implementation unless the sender is the admin.\n */\n modifier ifAdmin() {\n if (msg.sender == _getAdmin()) {\n _;\n } else {\n _fallback();\n }\n }\n\n /**\n * @dev Returns the current admin.\n *\n * NOTE: Only the admin can call this function. See {ProxyAdmin-getProxyAdmin}.\n *\n * TIP: To get this value clients can read directly from the storage slot shown below (specified by EIP1967) using the\n * https://eth.wiki/json-rpc/API#eth_getstorageat[`eth_getStorageAt`] RPC call.\n * `0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103`\n */\n function admin() external ifAdmin returns (address admin_) {\n admin_ = _getAdmin();\n }\n\n /**\n * @dev Returns the current implementation.\n *\n * NOTE: Only the admin can call this function. See {ProxyAdmin-getProxyImplementation}.\n *\n * TIP: To get this value clients can read directly from the storage slot shown below (specified by EIP1967) using the\n * https://eth.wiki/json-rpc/API#eth_getstorageat[`eth_getStorageAt`] RPC call.\n * `0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc`\n */\n function implementation() external ifAdmin returns (address implementation_) {\n implementation_ = _implementation();\n }\n\n /**\n * @dev Changes the admin of the proxy.\n *\n * Emits an {AdminChanged} event.\n *\n * NOTE: Only the admin can call this function. See {ProxyAdmin-changeProxyAdmin}.\n */\n function changeAdmin(address newAdmin) external virtual ifAdmin {\n _changeAdmin(newAdmin);\n }\n\n /**\n * @dev Upgrade the implementation of the proxy.\n *\n * NOTE: Only the admin can call this function. See {ProxyAdmin-upgrade}.\n */\n function upgradeTo(address newImplementation) external ifAdmin {\n _upgradeToAndCall(newImplementation, bytes(\"\"), false);\n }\n\n /**\n * @dev Upgrade the implementation of the proxy, and then call a function from the new implementation as specified\n * by `data`, which should be an encoded function call. This is useful to initialize new storage variables in the\n * proxied contract.\n *\n * NOTE: Only the admin can call this function. See {ProxyAdmin-upgradeAndCall}.\n */\n function upgradeToAndCall(address newImplementation, bytes calldata data) external payable ifAdmin {\n _upgradeToAndCall(newImplementation, data, true);\n }\n\n /**\n * @dev Returns the current admin.\n */\n function _admin() internal view virtual returns (address) {\n return _getAdmin();\n }\n\n /**\n * @dev Makes sure the admin cannot access the fallback function. See {Proxy-_beforeFallback}.\n */\n function _beforeFallback() internal virtual override {\n require(msg.sender != _getAdmin(), \"TransparentUpgradeableProxy: admin cannot fallback to proxy target\");\n super._beforeFallback();\n }\n}\n" + }, + "contracts/flashloan/FlashAngle.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\nimport \"@openzeppelin/contracts-upgradeable/security/ReentrancyGuardUpgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol\";\nimport \"@openzeppelin/contracts/interfaces/IERC3156FlashBorrower.sol\";\nimport \"@openzeppelin/contracts/interfaces/IERC3156FlashLender.sol\";\nimport \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\nimport \"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\";\n\nimport \"../interfaces/IAgToken.sol\";\nimport \"../interfaces/ICoreBorrow.sol\";\nimport \"../interfaces/IFlashAngle.sol\";\nimport \"../interfaces/ITreasury.sol\";\n\n/// @title FlashAngle\n/// @author Angle Labs, Inc.\n/// @notice Contract to take flash loans on top of several AgToken contracts\ncontract FlashAngle is IERC3156FlashLender, IFlashAngle, Initializable, ReentrancyGuardUpgradeable {\n using SafeERC20 for IERC20;\n /// @notice Base used for parameter computation\n uint256 public constant BASE_PARAMS = 10 ** 9;\n /// @notice Success message received when calling a `FlashBorrower` contract\n bytes32 public constant CALLBACK_SUCCESS = keccak256(\"ERC3156FlashBorrower.onFlashLoan\");\n\n /// @notice Struct encoding for a given stablecoin the parameters\n struct StablecoinData {\n // Maximum amount borrowable for this stablecoin\n uint256 maxBorrowable;\n // Flash loan fee taken by the protocol for a flash loan on this stablecoin\n uint64 flashLoanFee;\n // Treasury address responsible of the stablecoin\n address treasury;\n }\n\n // ======================= Parameters and References ===========================\n\n /// @notice Maps a stablecoin to the data and parameters for flash loans\n mapping(IAgToken => StablecoinData) public stablecoinMap;\n /// @inheritdoc IFlashAngle\n ICoreBorrow public core;\n\n // =============================== Event =======================================\n\n event FlashLoan(address indexed stablecoin, uint256 amount, IERC3156FlashBorrower indexed receiver);\n event FlashLoanParametersUpdated(IAgToken indexed stablecoin, uint64 _flashLoanFee, uint256 _maxBorrowable);\n\n // =============================== Errors ======================================\n\n error InvalidReturnMessage();\n error NotCore();\n error NotGovernorOrGuardian();\n error NotTreasury();\n error TooBigAmount();\n error TooHighParameterValue();\n error UnsupportedStablecoin();\n error ZeroAddress();\n\n /// @notice Initializes the contract\n /// @param _core Core address handling this module\n function initialize(ICoreBorrow _core) public initializer {\n if (address(_core) == address(0)) revert ZeroAddress();\n core = _core;\n }\n\n /// @custom:oz-upgrades-unsafe-allow constructor\n constructor() initializer {}\n\n // =================================== Modifiers ===============================\n\n /// @notice Checks whether the sender is the core contract\n modifier onlyCore() {\n if (msg.sender != address(core)) revert NotCore();\n _;\n }\n\n /// @notice Checks whether a given stablecoin has been initialized in this contract\n /// @param stablecoin Stablecoin to check\n /// @dev To check whether a stablecoin has been initialized, we just need to check whether its associated\n /// `treasury` address is not null in the `stablecoinMap`. This is what's checked in the `CoreBorrow` contract\n /// when adding support for a stablecoin\n modifier onlyExistingStablecoin(IAgToken stablecoin) {\n if (stablecoinMap[stablecoin].treasury == address(0)) revert UnsupportedStablecoin();\n _;\n }\n\n // ================================ ERC3156 Spec ===============================\n\n /// @inheritdoc IERC3156FlashLender\n function flashFee(address token, uint256 amount) external view returns (uint256) {\n return _flashFee(token, amount);\n }\n\n /// @inheritdoc IERC3156FlashLender\n function maxFlashLoan(address token) external view returns (uint256) {\n // It will be 0 anyway if the token was not added\n return stablecoinMap[IAgToken(token)].maxBorrowable;\n }\n\n /// @inheritdoc IERC3156FlashLender\n function flashLoan(\n IERC3156FlashBorrower receiver,\n address token,\n uint256 amount,\n bytes calldata data\n ) external nonReentrant returns (bool) {\n uint256 fee = _flashFee(token, amount);\n if (amount > stablecoinMap[IAgToken(token)].maxBorrowable) revert TooBigAmount();\n IAgToken(token).mint(address(receiver), amount);\n if (receiver.onFlashLoan(msg.sender, token, amount, fee, data) != CALLBACK_SUCCESS)\n revert InvalidReturnMessage();\n // Token must be an agToken here so normally no need to use `safeTransferFrom`, but out of safety\n // and in case governance whitelists an agToken which does not have a correct implementation, we prefer\n // to use `safeTransferFrom` here\n IERC20(token).safeTransferFrom(address(receiver), address(this), amount + fee);\n IAgToken(token).burnSelf(amount, address(this));\n emit FlashLoan(token, amount, receiver);\n return true;\n }\n\n /// @notice Internal function to compute the fee induced for taking a flash loan of `amount` of `token`\n /// @param token The loan currency\n /// @param amount The amount of tokens lent\n /// @dev This function will revert if the `token` requested is not whitelisted here\n function _flashFee(\n address token,\n uint256 amount\n ) internal view onlyExistingStablecoin(IAgToken(token)) returns (uint256) {\n return (amount * stablecoinMap[IAgToken(token)].flashLoanFee) / BASE_PARAMS;\n }\n\n // ============================ Treasury Only Function =========================\n\n /// @inheritdoc IFlashAngle\n function accrueInterestToTreasury(IAgToken stablecoin) external returns (uint256 balance) {\n address treasury = stablecoinMap[stablecoin].treasury;\n if (msg.sender != treasury) revert NotTreasury();\n balance = stablecoin.balanceOf(address(this));\n IERC20(address(stablecoin)).safeTransfer(treasury, balance);\n }\n\n // =========================== Governance Only Function ========================\n\n /// @notice Sets the parameters for a given stablecoin\n /// @param stablecoin Stablecoin to change the parameters for\n /// @param _flashLoanFee New flash loan fee for this stablecoin\n /// @param _maxBorrowable Maximum amount that can be borrowed in a single flash loan\n /// @dev Setting a `maxBorrowable` parameter equal to 0 is a way to pause the functionality\n /// @dev Parameters can only be modified for whitelisted stablecoins\n function setFlashLoanParameters(\n IAgToken stablecoin,\n uint64 _flashLoanFee,\n uint256 _maxBorrowable\n ) external onlyExistingStablecoin(stablecoin) {\n if (!core.isGovernorOrGuardian(msg.sender)) revert NotGovernorOrGuardian();\n if (_flashLoanFee > BASE_PARAMS) revert TooHighParameterValue();\n stablecoinMap[stablecoin].flashLoanFee = _flashLoanFee;\n stablecoinMap[stablecoin].maxBorrowable = _maxBorrowable;\n emit FlashLoanParametersUpdated(stablecoin, _flashLoanFee, _maxBorrowable);\n }\n\n // =========================== CoreBorrow Only Functions =======================\n\n /// @inheritdoc IFlashAngle\n function addStablecoinSupport(address _treasury) external onlyCore {\n stablecoinMap[IAgToken(ITreasury(_treasury).stablecoin())].treasury = _treasury;\n }\n\n /// @inheritdoc IFlashAngle\n function removeStablecoinSupport(address _treasury) external onlyCore {\n delete stablecoinMap[IAgToken(ITreasury(_treasury).stablecoin())];\n }\n\n /// @inheritdoc IFlashAngle\n function setCore(address _core) external onlyCore {\n core = ICoreBorrow(_core);\n }\n}\n" + }, + "contracts/interfaces/coreModule/IAgTokenMainnet.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\n/// @title IAgTokenMainnet\n/// @author Angle Labs, Inc.\ninterface IAgTokenMainnet {\n function stableMaster() external view returns (address);\n}\n" + }, + "contracts/interfaces/coreModule/ICore.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\n/// @title ICore\n/// @author Angle Labs, Inc.\ninterface ICore {\n function stablecoinList() external view returns (address[] memory);\n}\n" + }, + "contracts/interfaces/coreModule/ILiquidityGauge.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\ninterface ILiquidityGauge {\n function deposit(\n uint256 _value,\n address _addr,\n // solhint-disable-next-line\n bool _claim_rewards\n ) external;\n\n function withdraw(\n uint256 _value,\n // solhint-disable-next-line\n bool _claim_rewards\n ) external;\n\n // solhint-disable-next-line\n function claim_rewards(address _addr, address _receiver) external;\n\n // solhint-disable-next-line\n function claimable_reward(address _addr, address _reward_token) external view returns (uint256 amount);\n}\n" + }, + "contracts/interfaces/coreModule/IOracleCore.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\n/// @title IOracleCore\n/// @author Angle Labs, Inc.\ninterface IOracleCore {\n function readUpper() external view returns (uint256);\n\n function readQuoteLower(uint256 baseAmount) external view returns (uint256);\n}\n" + }, + "contracts/interfaces/coreModule/IPerpetualManager.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\n/// @title IPerpetualManager\n/// @author Angle Labs, Inc.\ninterface IPerpetualManager {\n function totalHedgeAmount() external view returns (uint256);\n\n function maintenanceMargin() external view returns (uint64);\n\n function maxLeverage() external view returns (uint64);\n\n function targetHAHedge() external view returns (uint64);\n\n function limitHAHedge() external view returns (uint64);\n\n function lockTime() external view returns (uint64);\n\n function haBonusMalusDeposit() external view returns (uint64);\n\n function haBonusMalusWithdraw() external view returns (uint64);\n\n function xHAFeesDeposit(uint256) external view returns (uint64);\n\n function yHAFeesDeposit(uint256) external view returns (uint64);\n\n function xHAFeesWithdraw(uint256) external view returns (uint64);\n\n function yHAFeesWithdraw(uint256) external view returns (uint64);\n}\n" + }, + "contracts/interfaces/coreModule/IPoolManager.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\n/// @title IPoolManager\n/// @author Angle Labs, Inc.\ninterface IPoolManager {\n function feeManager() external view returns (address);\n\n function strategyList(uint256) external view returns (address);\n}\n" + }, + "contracts/interfaces/coreModule/IStableMaster.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\nimport \"./IPerpetualManager.sol\";\nimport \"./IOracleCore.sol\";\n\n// Struct to handle all the parameters to manage the fees\n// related to a given collateral pool (associated to the stablecoin)\nstruct MintBurnData {\n // Values of the thresholds to compute the minting fees\n // depending on HA hedge (scaled by `BASE_PARAMS`)\n uint64[] xFeeMint;\n // Values of the fees at thresholds (scaled by `BASE_PARAMS`)\n uint64[] yFeeMint;\n // Values of the thresholds to compute the burning fees\n // depending on HA hedge (scaled by `BASE_PARAMS`)\n uint64[] xFeeBurn;\n // Values of the fees at thresholds (scaled by `BASE_PARAMS`)\n uint64[] yFeeBurn;\n // Max proportion of collateral from users that can be covered by HAs\n // It is exactly the same as the parameter of the same name in `PerpetualManager`, whenever one is updated\n // the other changes accordingly\n uint64 targetHAHedge;\n // Minting fees correction set by the `FeeManager` contract: they are going to be multiplied\n // to the value of the fees computed using the hedge curve\n // Scaled by `BASE_PARAMS`\n uint64 bonusMalusMint;\n // Burning fees correction set by the `FeeManager` contract: they are going to be multiplied\n // to the value of the fees computed using the hedge curve\n // Scaled by `BASE_PARAMS`\n uint64 bonusMalusBurn;\n // Parameter used to limit the number of stablecoins that can be issued using the concerned collateral\n uint256 capOnStableMinted;\n}\n\n// Struct to handle all the variables and parameters to handle SLPs in the protocol\n// including the fraction of interests they receive or the fees to be distributed to\n// them\nstruct SLPData {\n // Last timestamp at which the `sanRate` has been updated for SLPs\n uint256 lastBlockUpdated;\n // Fees accumulated from previous blocks and to be distributed to SLPs\n uint256 lockedInterests;\n // Max interests used to update the `sanRate` in a single block\n // Should be in collateral token base\n uint256 maxInterestsDistributed;\n // Amount of fees left aside for SLPs and that will be distributed\n // when the protocol is collateralized back again\n uint256 feesAside;\n // Part of the fees normally going to SLPs that is left aside\n // before the protocol is collateralized back again (depends on collateral ratio)\n // Updated by keepers and scaled by `BASE_PARAMS`\n uint64 slippageFee;\n // Portion of the fees from users minting and burning\n // that goes to SLPs (the rest goes to surplus)\n uint64 feesForSLPs;\n // Slippage factor that's applied to SLPs exiting (depends on collateral ratio)\n // If `slippage = BASE_PARAMS`, SLPs can get nothing, if `slippage = 0` they get their full claim\n // Updated by keepers and scaled by `BASE_PARAMS`\n uint64 slippage;\n // Portion of the interests from lending\n // that goes to SLPs (the rest goes to surplus)\n uint64 interestsForSLPs;\n}\n\n/// @title IStableMaster\n/// @author Angle Labs, Inc.\ninterface IStableMaster {\n function agToken() external view returns (address);\n\n function updateStocksUsers(uint256 amount, address poolManager) external;\n\n function collateralMap(\n address poolManager\n )\n external\n view\n returns (\n address token,\n address sanToken,\n IPerpetualManager perpetualManager,\n IOracleCore oracle,\n uint256 stocksUsers,\n uint256 sanRate,\n uint256 collatBase,\n SLPData memory slpData,\n MintBurnData memory feeData\n );\n\n function paused(bytes32) external view returns (bool);\n\n function deposit(uint256 amount, address user, address poolManager) external;\n\n function withdraw(uint256 amount, address burner, address dest, address poolManager) external;\n}\n" + }, + "contracts/interfaces/external/create2/ImmutableCreate2Factory.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\ninterface ImmutableCreate2Factory {\n function safeCreate2(bytes32 salt, bytes memory initCode) external payable returns (address deploymentAddress);\n\n function findCreate2Address(\n bytes32 salt,\n bytes calldata initCode\n ) external view returns (address deploymentAddress);\n\n function findCreate2AddressViaHash(\n bytes32 salt,\n bytes32 initCodeHash\n ) external view returns (address deploymentAddress);\n}\n" + }, + "contracts/interfaces/external/IERC1271.sol": { + "content": "// SPDX-License-Identifier: GPL-2.0-or-later\npragma solidity ^0.8.12;\n\n/// @title Interface for verifying contract-based account signatures\n/// @notice Interface that verifies provided signature for the data\n/// @dev Interface defined by EIP-1271\ninterface IERC1271 {\n /// @notice Returns whether the provided signature is valid for the provided data\n /// @dev MUST return the bytes4 magic value 0x1626ba7e when function passes.\n /// MUST NOT modify state (using STATICCALL for solc < 0.5, view modifier for solc > 0.5).\n /// MUST allow external calls.\n /// @param hash Hash of the data to be signed\n /// @param signature Signature byte array associated with _data\n /// @return magicValue The bytes4 magic value 0x1626ba7e\n function isValidSignature(bytes32 hash, bytes memory signature) external view returns (bytes4 magicValue);\n}\n" + }, + "contracts/interfaces/external/IERC4626.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\npragma solidity >=0.8.0;\n\nimport \"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\";\nimport \"@openzeppelin/contracts/token/ERC20/ERC20.sol\";\n\n/// @notice Minimal IERC4646 tokenized Vault interface.\n/// @author Forked from Solmate (https://github.com/Rari-Capital/solmate/blob/main/src/mixins/ERC4626.sol)\n/// @dev Do not use in production! ERC-4626 is still in the review stage and is subject to change.\ninterface IERC4626 {\n event Deposit(address indexed from, address indexed to, uint256 amount, uint256 shares);\n event Withdraw(address indexed from, address indexed to, uint256 amount, uint256 shares);\n\n /// @notice Transfers a given amount of asset to the reactor and mint shares accordingly\n /// @param amount Given amount of asset\n /// @param to Address to mint shares to\n /// @return shares Amount of shares minted to `to`\n function deposit(uint256 amount, address to) external returns (uint256 shares);\n\n /// @notice Mints a given amount of shares to the reactor and transfer assets accordingly\n /// @param shares Given amount of shares\n /// @param to Address to mint shares to\n /// @return amount Amount of `asset` taken to the `msg.sender` to mint `shares`\n function mint(uint256 shares, address to) external returns (uint256 amount);\n\n /// @notice Transfers a given amount of asset from the reactor and burn shares accordingly\n /// @param amount Given amount of asset\n /// @param to Address to transfer assets to\n /// @param from Address to burn shares from\n /// @return shares Amount of shares burnt in the operation\n function withdraw(uint256 amount, address to, address from) external returns (uint256 shares);\n\n /// @notice Burns a given amount of shares to the reactor and transfer assets accordingly\n /// @param shares Given amount of shares\n /// @param to Address to transfer assets to\n /// @param from Address to burn shares from\n /// @return amount Amount of assets redeemed in the operation\n function redeem(uint256 shares, address to, address from) external returns (uint256 amount);\n\n /// @notice Returns the total assets managed by this reactor\n function totalAssets() external view returns (uint256);\n\n /// @notice Converts an amount of assets to the corresponding amount of reactor shares\n /// @param assets Amount of asset to convert\n /// @return Shares corresponding to the amount of assets obtained\n function convertToShares(uint256 assets) external view returns (uint256);\n\n /// @notice Converts an amount of shares to its current value in asset\n /// @param shares Amount of shares to convert\n /// @return Amount of assets corresponding to the amount of assets given\n function convertToAssets(uint256 shares) external view returns (uint256);\n\n /// @notice Computes how many shares one would get by depositing `assets`\n /// @param assets Amount of asset to convert\n function previewDeposit(uint256 assets) external view returns (uint256);\n\n /// @notice Computes how many assets one would need to mint `shares`\n /// @param shares Amount of shares required\n function previewMint(uint256 shares) external view returns (uint256);\n\n /// @notice Computes how many shares one would need to withdraw assets\n /// @param assets Amount of asset to withdraw\n function previewWithdraw(uint256 assets) external view returns (uint256);\n\n /// @notice Computes how many assets one would get by burning shares\n /// @param shares Amount of shares to burn\n function previewRedeem(uint256 shares) external view returns (uint256);\n\n /// @notice Max deposit allowed for a user\n /// @param user Address of the user to check\n function maxDeposit(address user) external returns (uint256);\n\n /// @notice Max mint allowed for a user\n /// @param user Address of the user to check\n function maxMint(address user) external returns (uint256);\n\n /// @notice Max withdraw allowed for a user\n /// @param user Address of the user to check\n function maxWithdraw(address user) external returns (uint256);\n\n /// @notice Max redeem allowed for a user\n /// @param user Address of the user to check\n function maxRedeem(address user) external returns (uint256);\n}\n" + }, + "contracts/interfaces/external/IWETH9.sol": { + "content": "// SPDX-License-Identifier: GPL-2.0-or-later\npragma solidity ^0.8.12;\n\nimport \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\n\n/// @title Interface for WETH9\ninterface IWETH9 is IERC20 {\n /// @notice Deposit ether to get wrapped ether\n function deposit() external payable;\n\n /// @notice Withdraw wrapped ether to get ether\n function withdraw(uint256) external;\n}\n" + }, + "contracts/interfaces/external/layerZero/ILayerZeroEndpoint.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity >=0.5.0;\n\nimport \"./ILayerZeroUserApplicationConfig.sol\";\n\ninterface ILayerZeroEndpoint is ILayerZeroUserApplicationConfig {\n // @notice send a LayerZero message to the specified address at a LayerZero endpoint.\n // @param _dstChainId - the destination chain identifier\n // @param _destination - the address on destination chain (in bytes). address length/format may vary by chains\n // @param _payload - a custom bytes payload to send to the destination contract\n // @param _refundAddress - if the source transaction is cheaper than the amount of value passed, refund the additional amount to this address\n // @param _zroPaymentAddress - the address of the ZRO token holder who would pay for the transaction\n // @param _adapterParams - parameters for custom functionality. e.g. receive airdropped native gas from the relayer on destination\n function send(\n uint16 _dstChainId,\n bytes calldata _destination,\n bytes calldata _payload,\n address payable _refundAddress,\n address _zroPaymentAddress,\n bytes calldata _adapterParams\n ) external payable;\n\n // @notice used by the messaging library to publish verified payload\n // @param _srcChainId - the source chain identifier\n // @param _srcAddress - the source contract (as bytes) at the source chain\n // @param _dstAddress - the address on destination chain\n // @param _nonce - the unbound message ordering nonce\n // @param _gasLimit - the gas limit for external contract execution\n // @param _payload - verified payload to send to the destination contract\n function receivePayload(\n uint16 _srcChainId,\n bytes calldata _srcAddress,\n address _dstAddress,\n uint64 _nonce,\n uint256 _gasLimit,\n bytes calldata _payload\n ) external;\n\n // @notice get the inboundNonce of a lzApp from a source chain which could be EVM or non-EVM chain\n // @param _srcChainId - the source chain identifier\n // @param _srcAddress - the source chain contract address\n function getInboundNonce(uint16 _srcChainId, bytes calldata _srcAddress) external view returns (uint64);\n\n // @notice get the outboundNonce from this source chain which, consequently, is always an EVM\n // @param _srcAddress - the source chain contract address\n function getOutboundNonce(uint16 _dstChainId, address _srcAddress) external view returns (uint64);\n\n // @notice gets a quote in source native gas, for the amount that send() requires to pay for message delivery\n // @param _dstChainId - the destination chain identifier\n // @param _userApplication - the user app address on this EVM chain\n // @param _payload - the custom message to send over LayerZero\n // @param _payInZRO - if false, user app pays the protocol fee in native token\n // @param _adapterParam - parameters for the adapter service, e.g. send some dust native token to dstChain\n function estimateFees(\n uint16 _dstChainId,\n address _userApplication,\n bytes calldata _payload,\n bool _payInZRO,\n bytes calldata _adapterParam\n ) external view returns (uint256 nativeFee, uint256 zroFee);\n\n // @notice get this Endpoint's immutable source identifier\n function getChainId() external view returns (uint16);\n\n // @notice the interface to retry failed message on this Endpoint destination\n // @param _srcChainId - the source chain identifier\n // @param _srcAddress - the source chain contract address\n // @param _payload - the payload to be retried\n function retryPayload(uint16 _srcChainId, bytes calldata _srcAddress, bytes calldata _payload) external;\n\n // @notice query if any STORED payload (message blocking) at the endpoint.\n // @param _srcChainId - the source chain identifier\n // @param _srcAddress - the source chain contract address\n function hasStoredPayload(uint16 _srcChainId, bytes calldata _srcAddress) external view returns (bool);\n\n // @notice query if the _libraryAddress is valid for sending msgs.\n // @param _userApplication - the user app address on this EVM chain\n function getSendLibraryAddress(address _userApplication) external view returns (address);\n\n // @notice query if the _libraryAddress is valid for receiving msgs.\n // @param _userApplication - the user app address on this EVM chain\n function getReceiveLibraryAddress(address _userApplication) external view returns (address);\n\n // @notice query if the non-reentrancy guard for send() is on\n // @return true if the guard is on. false otherwise\n function isSendingPayload() external view returns (bool);\n\n // @notice query if the non-reentrancy guard for receive() is on\n // @return true if the guard is on. false otherwise\n function isReceivingPayload() external view returns (bool);\n\n // @notice get the configuration of the LayerZero messaging library of the specified version\n // @param _version - messaging library version\n // @param _chainId - the chainId for the pending config change\n // @param _userApplication - the contract address of the user application\n // @param _configType - type of configuration. every messaging library has its own convention.\n function getConfig(\n uint16 _version,\n uint16 _chainId,\n address _userApplication,\n uint256 _configType\n ) external view returns (bytes memory);\n\n // @notice get the send() LayerZero messaging library version\n // @param _userApplication - the contract address of the user application\n function getSendVersion(address _userApplication) external view returns (uint16);\n\n // @notice get the lzReceive() LayerZero messaging library version\n // @param _userApplication - the contract address of the user application\n function getReceiveVersion(address _userApplication) external view returns (uint16);\n}\n" + }, + "contracts/interfaces/external/layerZero/ILayerZeroReceiver.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity >=0.5.0;\n\ninterface ILayerZeroReceiver {\n // @notice LayerZero endpoint will invoke this function to deliver the message on the destination\n // @param _srcChainId - the source endpoint identifier\n // @param _srcAddress - the source sending contract address from the source chain\n // @param _nonce - the ordered message nonce\n // @param _payload - the signed payload is the UA bytes has encoded to be sent\n function lzReceive(uint16 _srcChainId, bytes calldata _srcAddress, uint64 _nonce, bytes calldata _payload) external;\n}\n" + }, + "contracts/interfaces/external/layerZero/ILayerZeroUserApplicationConfig.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity >=0.5.0;\n\ninterface ILayerZeroUserApplicationConfig {\n // @notice set the configuration of the LayerZero messaging library of the specified version\n // @param _version - messaging library version\n // @param _chainId - the chainId for the pending config change\n // @param _configType - type of configuration. every messaging library has its own convention.\n // @param _config - configuration in the bytes. can encode arbitrary content.\n function setConfig(uint16 _version, uint16 _chainId, uint256 _configType, bytes calldata _config) external;\n\n // @notice set the send() LayerZero messaging library version to _version\n // @param _version - new messaging library version\n function setSendVersion(uint16 _version) external;\n\n // @notice set the lzReceive() LayerZero messaging library version to _version\n // @param _version - new messaging library version\n function setReceiveVersion(uint16 _version) external;\n\n // @notice Only when the UA needs to resume the message flow in blocking mode and clear the stored payload\n // @param _srcChainId - the chainId of the source chain\n // @param _srcAddress - the contract address of the source contract at the source chain\n function forceResumeReceive(uint16 _srcChainId, bytes calldata _srcAddress) external;\n}\n" + }, + "contracts/interfaces/external/lido/IStETH.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\n/// @title IStETH\n/// @author Angle Labs, Inc.\n/// @notice Interface for the `StETH` contract\n/// @dev This interface only contains functions of the `StETH` which are called by other contracts\n/// of this module\ninterface IStETH {\n function getPooledEthByShares(uint256 _sharesAmount) external view returns (uint256);\n\n event Submitted(address sender, uint256 amount, address referral);\n\n function submit(address) external payable returns (uint256);\n\n function getSharesByPooledEth(uint256 _ethAmount) external view returns (uint256);\n}\n" + }, + "contracts/interfaces/external/lido/IWStETH.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\n/// @title IWStETH\n/// @author Angle Labs, Inc.\n/// @notice Interface for the `WStETH` contract\n/// @dev This interface only contains functions of the `WStETH` which are called by other contracts\n/// of this module\ninterface IWStETH {\n function wrap(uint256 _stETHAmount) external returns (uint256);\n\n function stETH() external view returns (address);\n}\n" + }, + "contracts/interfaces/external/uniswap/IUniswapRouter.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\nstruct ExactInputParams {\n bytes path;\n address recipient;\n uint256 deadline;\n uint256 amountIn;\n uint256 amountOutMinimum;\n}\n\n/// @title Router token swapping functionality\n/// @notice Functions for swapping tokens via Uniswap V3\ninterface IUniswapV3Router {\n /// @notice Swaps `amountIn` of one token for as much as possible of another along the specified path\n /// @param params The parameters necessary for the multi-hop swap, encoded as `ExactInputParams` in calldata\n /// @return amountOut The amount of the received token\n function exactInput(ExactInputParams calldata params) external payable returns (uint256 amountOut);\n}\n\n/// @title Router for price estimation functionality\n/// @notice Functions for getting the price of one token with respect to another using Uniswap V2\n/// @dev This interface is only used for non critical elements of the protocol\ninterface IUniswapV2Router {\n /// @notice Given an input asset amount, returns the maximum output amount of the\n /// other asset (accounting for fees) given reserves.\n /// @param path Addresses of the pools used to get prices\n function getAmountsOut(uint256 amountIn, address[] calldata path) external view returns (uint256[] memory amounts);\n\n function swapExactTokensForTokens(\n uint256 swapAmount,\n uint256 minExpected,\n address[] calldata path,\n address receiver,\n uint256 swapDeadline\n ) external;\n}\n" + }, + "contracts/interfaces/external/uniswap/IUniswapV3Pool.sol": { + "content": "// SPDX-License-Identifier: GPL-2.0-or-later\npragma solidity >=0.5.0;\n\n/// @title Pool state that never changes\n/// @notice These parameters are fixed for a pool forever, i.e., the methods will always return the same values\ninterface IUniswapV3Pool {\n /// @notice The first of the two tokens of the pool, sorted by address\n /// @return The token contract address\n function token0() external view returns (address);\n\n /// @notice The second of the two tokens of the pool, sorted by address\n /// @return The token contract address\n function token1() external view returns (address);\n}\n" + }, + "contracts/interfaces/governance/IVeBoostProxy.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\n/// @title IVeBoostProxy\n/// @author Angle Labs, Inc.\n/// @notice Interface for the `VeBoostProxy` contract\n/// @dev This interface only contains functions of the contract which are called by other contracts\n/// of this module\n/// @dev The `veBoostProxy` contract used by Angle is a full fork of Curve Finance implementation\ninterface IVeBoostProxy {\n /// @notice Reads the adjusted veANGLE balance of an address (adjusted by delegation)\n //solhint-disable-next-line\n function adjusted_balance_of(address) external view returns (uint256);\n}\n" + }, + "contracts/interfaces/IAgToken.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\nimport \"@openzeppelin/contracts-upgradeable/token/ERC20/IERC20Upgradeable.sol\";\n\n/// @title IAgToken\n/// @author Angle Labs, Inc.\n/// @notice Interface for the stablecoins `AgToken` contracts\n/// @dev This interface only contains functions of the `AgToken` contract which are called by other contracts\n/// of this module or of the first module of the Angle Protocol\ninterface IAgToken is IERC20Upgradeable {\n // ======================= Minter Role Only Functions ===========================\n\n /// @notice Lets the `StableMaster` contract or another whitelisted contract mint agTokens\n /// @param account Address to mint to\n /// @param amount Amount to mint\n /// @dev The contracts allowed to issue agTokens are the `StableMaster` contract, `VaultManager` contracts\n /// associated to this stablecoin as well as the flash loan module (if activated) and potentially contracts\n /// whitelisted by governance\n function mint(address account, uint256 amount) external;\n\n /// @notice Burns `amount` tokens from a `burner` address after being asked to by `sender`\n /// @param amount Amount of tokens to burn\n /// @param burner Address to burn from\n /// @param sender Address which requested the burn from `burner`\n /// @dev This method is to be called by a contract with the minter right after being requested\n /// to do so by a `sender` address willing to burn tokens from another `burner` address\n /// @dev The method checks the allowance between the `sender` and the `burner`\n function burnFrom(uint256 amount, address burner, address sender) external;\n\n /// @notice Burns `amount` tokens from a `burner` address\n /// @param amount Amount of tokens to burn\n /// @param burner Address to burn from\n /// @dev This method is to be called by a contract with a minter right on the AgToken after being\n /// requested to do so by an address willing to burn tokens from its address\n function burnSelf(uint256 amount, address burner) external;\n\n // ========================= Treasury Only Functions ===========================\n\n /// @notice Adds a minter in the contract\n /// @param minter Minter address to add\n /// @dev Zero address checks are performed directly in the `Treasury` contract\n function addMinter(address minter) external;\n\n /// @notice Removes a minter from the contract\n /// @param minter Minter address to remove\n /// @dev This function can also be called by a minter wishing to revoke itself\n function removeMinter(address minter) external;\n\n /// @notice Sets a new treasury contract\n /// @param _treasury New treasury address\n function setTreasury(address _treasury) external;\n\n // ========================= External functions ================================\n\n /// @notice Checks whether an address has the right to mint agTokens\n /// @param minter Address for which the minting right should be checked\n /// @return Whether the address has the right to mint agTokens or not\n function isMinter(address minter) external view returns (bool);\n\n /// @notice Get the associated treasury\n function treasury() external view returns (address);\n}\n" + }, + "contracts/interfaces/IAgTokenSideChainMultiBridge.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\nimport \"@openzeppelin/contracts-upgradeable/token/ERC20/extensions/draft-IERC20PermitUpgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/token/ERC20/IERC20Upgradeable.sol\";\n\n/// @title IAgTokenSideChainMultiBridge\n/// @author Angle Labs, Inc.\n/// @notice Interface for the canonical `AgToken` contracts\n/// @dev This interface only contains functions useful for bridge tokens to interact with the canonical token\ninterface IAgTokenSideChainMultiBridge is IERC20PermitUpgradeable, IERC20Upgradeable {\n /// @notice Mints the canonical token from a supported bridge token\n /// @param bridgeToken Bridge token to use to mint\n /// @param amount Amount of bridge tokens to send\n /// @param to Address to which the stablecoin should be sent\n /// @return Amount of the canonical stablecoin actually minted\n /// @dev Some fees may be taken by the protocol depending on the token used and on the address calling\n function swapIn(address bridgeToken, uint256 amount, address to) external returns (uint256);\n\n /// @notice Burns the canonical token in exchange for a bridge token\n /// @param bridgeToken Bridge token required\n /// @param amount Amount of canonical tokens to burn\n /// @param to Address to which the bridge token should be sent\n /// @return Amount of bridge tokens actually sent back\n /// @dev Some fees may be taken by the protocol depending on the token used and on the address calling\n function swapOut(address bridgeToken, uint256 amount, address to) external returns (uint256);\n}\n" + }, + "contracts/interfaces/IAngleRouter.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\n/// @title IAngleRouter\n/// @author Angle Labs, Inc.\n/// @notice Interface for the `AngleRouter` contract\n/// @dev This interface only contains functions of the `AngleRouter01` contract which are called by other contracts\n/// of this module\ninterface IAngleRouter {\n function mint(\n address user,\n uint256 amount,\n uint256 minStableAmount,\n address stablecoin,\n address collateral\n ) external;\n\n function burn(address user, uint256 amount, uint256 minAmountOut, address stablecoin, address collateral) external;\n\n function mapPoolManagers(\n address stableMaster,\n address collateral\n ) external view returns (address poolManager, address perpetualManager, address sanToken, address gauge);\n}\n" + }, + "contracts/interfaces/IAngleRouterSidechain.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\n/// @notice Action types\nenum ActionType {\n transfer,\n wrap,\n wrapNative,\n sweep,\n sweepNative,\n unwrap,\n unwrapNative,\n swapIn,\n swapOut,\n uniswapV3,\n oneInch,\n claimRewards,\n gaugeDeposit,\n borrower\n}\n\n/// @notice Data needed to get permits\nstruct PermitType {\n address token;\n address owner;\n uint256 value;\n uint256 deadline;\n uint8 v;\n bytes32 r;\n bytes32 s;\n}\n\n/// @title IAngleRouterSidechain\n/// @author Angle Labs, Inc.\n/// @notice Interface for the `AngleRouter` contract on other chains\ninterface IAngleRouterSidechain {\n function mixer(PermitType[] memory paramsPermit, ActionType[] memory actions, bytes[] calldata data) external;\n}\n" + }, + "contracts/interfaces/ICoreBorrow.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\n/// @title ICoreBorrow\n/// @author Angle Labs, Inc.\n/// @notice Interface for the `CoreBorrow` contract\n/// @dev This interface only contains functions of the `CoreBorrow` contract which are called by other contracts\n/// of this module\ninterface ICoreBorrow {\n /// @notice Checks if an address corresponds to a treasury of a stablecoin with a flash loan\n /// module initialized on it\n /// @param treasury Address to check\n /// @return Whether the address has the `FLASHLOANER_TREASURY_ROLE` or not\n function isFlashLoanerTreasury(address treasury) external view returns (bool);\n\n /// @notice Checks whether an address is governor of the Angle Protocol or not\n /// @param admin Address to check\n /// @return Whether the address has the `GOVERNOR_ROLE` or not\n function isGovernor(address admin) external view returns (bool);\n\n /// @notice Checks whether an address is governor or a guardian of the Angle Protocol or not\n /// @param admin Address to check\n /// @return Whether the address has the `GUARDIAN_ROLE` or not\n /// @dev Governance should make sure when adding a governor to also give this governor the guardian\n /// role by calling the `addGovernor` function\n function isGovernorOrGuardian(address admin) external view returns (bool);\n}\n" + }, + "contracts/interfaces/IFlashAngle.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\nimport \"./IAgToken.sol\";\nimport \"./ICoreBorrow.sol\";\n\n/// @title IFlashAngle\n/// @author Angle Labs, Inc.\n/// @notice Interface for the `FlashAngle` contract\n/// @dev This interface only contains functions of the contract which are called by other contracts\n/// of this module\ninterface IFlashAngle {\n /// @notice Reference to the `CoreBorrow` contract managing the FlashLoan module\n function core() external view returns (ICoreBorrow);\n\n /// @notice Sends the fees taken from flash loans to the treasury contract associated to the stablecoin\n /// @param stablecoin Stablecoin from which profits should be sent\n /// @return balance Amount of profits sent\n /// @dev This function can only be called by the treasury contract\n function accrueInterestToTreasury(IAgToken stablecoin) external returns (uint256 balance);\n\n /// @notice Adds support for a stablecoin\n /// @param _treasury Treasury associated to the stablecoin to add support for\n /// @dev This function can only be called by the `CoreBorrow` contract\n function addStablecoinSupport(address _treasury) external;\n\n /// @notice Removes support for a stablecoin\n /// @param _treasury Treasury associated to the stablecoin to remove support for\n /// @dev This function can only be called by the `CoreBorrow` contract\n function removeStablecoinSupport(address _treasury) external;\n\n /// @notice Sets a new core contract\n /// @param _core Core contract address to set\n /// @dev This function can only be called by the `CoreBorrow` contract\n function setCore(address _core) external;\n}\n" + }, + "contracts/interfaces/IKeeperRegistry.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\nimport \"@openzeppelin/contracts-upgradeable/token/ERC20/IERC20Upgradeable.sol\";\n\n/// @title IKeeperRegistry\n/// @author Angle Labs, Inc.\ninterface IKeeperRegistry {\n /// @notice Checks whether an address is whitelisted during oracle updates\n /// @param caller Address for which the whitelist should be checked\n /// @return Whether the address is trusted or not\n function isTrusted(address caller) external view returns (bool);\n}\n" + }, + "contracts/interfaces/ILiquidityGauge.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.7;\n\ninterface ILiquidityGauge {\n function deposit(\n uint256 _value,\n address _addr,\n // solhint-disable-next-line\n bool _claim_rewards\n ) external;\n\n function withdraw(\n uint256 _value,\n // solhint-disable-next-line\n bool _claim_rewards\n ) external;\n\n // solhint-disable-next-line\n function claim_rewards(address _addr, address _receiver) external;\n\n // solhint-disable-next-line\n function claimable_reward(address _addr, address _reward_token) external view returns (uint256 amount);\n\n /// @dev Only for testing purposes\n // solhint-disable-next-line\n function deposit_reward_token(address _rewardToken, uint256 _amount) external;\n}\n" + }, + "contracts/interfaces/IOracle.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\nimport \"./ITreasury.sol\";\nimport \"@chainlink/contracts/src/v0.8/interfaces/AggregatorV3Interface.sol\";\n\n/// @title IOracle\n/// @author Angle Labs, Inc.\n/// @notice Interface for the `Oracle` contract\n/// @dev This interface only contains functions of the contract which are called by other contracts\n/// of this module\ninterface IOracle {\n /// @notice Reads the rate from the Chainlink circuit and other data provided\n /// @return quoteAmount The current rate between the in-currency and out-currency in the base\n /// of the out currency\n /// @dev For instance if the out currency is EUR (and hence agEUR), then the base of the returned\n /// value is 10**18\n function read() external view returns (uint256);\n\n /// @notice Changes the treasury contract\n /// @param _treasury Address of the new treasury contract\n /// @dev This function can be called by an approved `VaultManager` contract which can call\n /// this function after being requested to do so by a `treasury` contract\n /// @dev In some situations (like reactor contracts), the `VaultManager` may not directly be linked\n /// to the `oracle` contract and as such we may need governors to be able to call this function as well\n function setTreasury(address _treasury) external;\n\n /// @notice Reference to the `treasury` contract handling this `VaultManager`\n function treasury() external view returns (ITreasury treasury);\n\n /// @notice Array with the list of Chainlink feeds in the order in which they are read\n function circuitChainlink() external view returns (AggregatorV3Interface[] memory);\n}\n" + }, + "contracts/interfaces/ISwapper.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\nimport \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\n\n/// @title ISwapper\n/// @author Angle Labs, Inc.\n/// @notice Interface for Swapper contracts\n/// @dev This interface defines the key functions `Swapper` contracts should have when interacting with\n/// Angle\ninterface ISwapper {\n /// @notice Notifies a contract that an address should be given `outToken` from `inToken`\n /// @param inToken Address of the token received\n /// @param outToken Address of the token to obtain\n /// @param outTokenRecipient Address to which the outToken should be sent\n /// @param outTokenOwed Minimum amount of outToken the `outTokenRecipient` address should have at the end of the call\n /// @param inTokenObtained Amount of collateral obtained by a related address prior\n /// to the call to this function\n /// @param data Extra data needed (to encode Uniswap swaps for instance)\n function swap(\n IERC20 inToken,\n IERC20 outToken,\n address outTokenRecipient,\n uint256 outTokenOwed,\n uint256 inTokenObtained,\n bytes calldata data\n ) external;\n}\n" + }, + "contracts/interfaces/ITreasury.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\nimport \"./IAgToken.sol\";\nimport \"./ICoreBorrow.sol\";\nimport \"./IFlashAngle.sol\";\n\n/// @title ITreasury\n/// @author Angle Labs, Inc.\n/// @notice Interface for the `Treasury` contract\n/// @dev This interface only contains functions of the `Treasury` which are called by other contracts\n/// of this module\ninterface ITreasury {\n /// @notice Stablecoin handled by this `treasury` contract\n function stablecoin() external view returns (IAgToken);\n\n /// @notice Checks whether a given address has the governor role\n /// @param admin Address to check\n /// @return Whether the address has the governor role\n /// @dev Access control is only kept in the `CoreBorrow` contract\n function isGovernor(address admin) external view returns (bool);\n\n /// @notice Checks whether a given address has the guardian or the governor role\n /// @param admin Address to check\n /// @return Whether the address has the guardian or the governor role\n /// @dev Access control is only kept in the `CoreBorrow` contract which means that this function\n /// queries the `CoreBorrow` contract\n function isGovernorOrGuardian(address admin) external view returns (bool);\n\n /// @notice Checks whether a given address has well been initialized in this contract\n /// as a `VaultManager`\n /// @param _vaultManager Address to check\n /// @return Whether the address has been initialized or not\n function isVaultManager(address _vaultManager) external view returns (bool);\n\n /// @notice Sets a new flash loan module for this stablecoin\n /// @param _flashLoanModule Reference to the new flash loan module\n /// @dev This function removes the minting right to the old flash loan module and grants\n /// it to the new module\n function setFlashLoanModule(address _flashLoanModule) external;\n\n /// @notice Gets the vault manager list\n function vaultManagerList(uint256 i) external returns (address);\n}\n" + }, + "contracts/interfaces/IVaultManager.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\nimport \"@openzeppelin/contracts/interfaces/IERC721Metadata.sol\";\nimport \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\nimport \"./ITreasury.sol\";\nimport \"./IOracle.sol\";\n\n// ========================= Key Structs and Enums =============================\n\n/// @notice Parameters associated to a given `VaultManager` contract: these all correspond\n/// to parameters which signification is detailed in the `VaultManagerStorage` file\nstruct VaultParameters {\n uint256 debtCeiling;\n uint64 collateralFactor;\n uint64 targetHealthFactor;\n uint64 interestRate;\n uint64 liquidationSurcharge;\n uint64 maxLiquidationDiscount;\n bool whitelistingActivated;\n uint256 baseBoost;\n}\n\n/// @notice Data stored to track someone's loan (or equivalently called position)\nstruct Vault {\n // Amount of collateral deposited in the vault, in collateral decimals. For example, if the collateral\n // is USDC with 6 decimals, then `collateralAmount` will be in base 10**6\n uint256 collateralAmount;\n // Normalized value of the debt (that is to say of the stablecoins borrowed). It is expressed\n // in the base of Angle stablecoins (i.e. `BASE_TOKENS = 10**18`)\n uint256 normalizedDebt;\n}\n\n/// @notice For a given `vaultID`, this encodes a liquidation opportunity that is to say details about the maximum\n/// amount that could be repaid by liquidating the position\n/// @dev All the values are null in the case of a vault which cannot be liquidated under these conditions\nstruct LiquidationOpportunity {\n // Maximum stablecoin amount that can be repaid upon liquidating the vault\n uint256 maxStablecoinAmountToRepay;\n // Collateral amount given to the person in the case where the maximum amount to repay is given\n uint256 maxCollateralAmountGiven;\n // Threshold value of stablecoin amount to repay: it is ok for a liquidator to repay below threshold,\n // but if this threshold is non null and the liquidator wants to repay more than threshold, it should repay\n // the max stablecoin amount given in this vault\n uint256 thresholdRepayAmount;\n // Discount proposed to the liquidator on the collateral\n uint256 discount;\n // Amount of debt in the vault\n uint256 currentDebt;\n}\n\n/// @notice Data stored during a liquidation process to keep in memory what's due to a liquidator and some\n/// essential data for vaults being liquidated\nstruct LiquidatorData {\n // Current amount of stablecoins the liquidator should give to the contract\n uint256 stablecoinAmountToReceive;\n // Current amount of collateral the contract should give to the liquidator\n uint256 collateralAmountToGive;\n // Bad debt accrued across the liquidation process\n uint256 badDebtFromLiquidation;\n // Oracle value (in stablecoin base) at the time of the liquidation\n uint256 oracleValue;\n // Value of the `interestAccumulator` at the time of the call\n uint256 newInterestAccumulator;\n}\n\n/// @notice Data to track during a series of action the amount to give or receive in stablecoins and collateral\n/// to the caller or associated addresses\nstruct PaymentData {\n // Stablecoin amount the contract should give\n uint256 stablecoinAmountToGive;\n // Stablecoin amount owed to the contract\n uint256 stablecoinAmountToReceive;\n // Collateral amount the contract should give\n uint256 collateralAmountToGive;\n // Collateral amount owed to the contract\n uint256 collateralAmountToReceive;\n}\n\n/// @notice Actions possible when composing calls to the different entry functions proposed\nenum ActionType {\n createVault,\n closeVault,\n addCollateral,\n removeCollateral,\n repayDebt,\n borrow,\n getDebtIn,\n permit\n}\n\n// ========================= Interfaces =============================\n\n/// @title IVaultManagerFunctions\n/// @author Angle Labs, Inc.\n/// @notice Interface for the `VaultManager` contract\n/// @dev This interface only contains functions of the contract which are called by other contracts\n/// of this module (without getters)\ninterface IVaultManagerFunctions {\n /// @notice Accrues interest accumulated across all vaults to the surplus and sends the surplus to the treasury\n /// @return surplusValue Value of the surplus communicated to the `Treasury`\n /// @return badDebtValue Value of the bad debt communicated to the `Treasury`\n /// @dev `surplus` and `badDebt` should be reset to 0 once their current value have been given to the `treasury` contract\n function accrueInterestToTreasury() external returns (uint256 surplusValue, uint256 badDebtValue);\n\n /// @notice Removes debt from a vault after being requested to do so by another `VaultManager` contract\n /// @param vaultID ID of the vault to remove debt from\n /// @param amountStablecoins Amount of stablecoins to remove from the debt: this amount is to be converted to an\n /// internal debt amount\n /// @param senderBorrowFee Borrowing fees from the contract which requested this: this is to make sure that people are not\n /// arbitraging difference in minting fees\n /// @param senderRepayFee Repay fees from the contract which requested this: this is to make sure that people are not arbitraging\n /// differences in repay fees\n /// @dev This function can only be called from a vaultManager registered in the same Treasury\n function getDebtOut(\n uint256 vaultID,\n uint256 amountStablecoins,\n uint256 senderBorrowFee,\n uint256 senderRepayFee\n ) external;\n\n /// @notice Gets the current debt of a vault\n /// @param vaultID ID of the vault to check\n /// @return Debt of the vault\n function getVaultDebt(uint256 vaultID) external view returns (uint256);\n\n /// @notice Gets the total debt across all vaults\n /// @return Total debt across all vaults, taking into account the interest accumulated\n /// over time\n function getTotalDebt() external view returns (uint256);\n\n /// @notice Sets the treasury contract\n /// @param _treasury New treasury contract\n /// @dev All required checks when setting up a treasury contract are performed in the contract\n /// calling this function\n function setTreasury(address _treasury) external;\n\n /// @notice Creates a vault\n /// @param toVault Address for which the va\n /// @return vaultID ID of the vault created\n /// @dev This function just creates the vault without doing any collateral or\n function createVault(address toVault) external returns (uint256);\n\n /// @notice Allows composability between calls to the different entry points of this module. Any user calling\n /// this function can perform any of the allowed actions in the order of their choice\n /// @param actions Set of actions to perform\n /// @param datas Data to be decoded for each action: it can include like the `vaultID` or the `stablecoinAmount` to borrow\n /// @param from Address from which stablecoins will be taken if one action includes burning stablecoins. This address\n /// should either be the `msg.sender` or be approved by the latter\n /// @param to Address to which stablecoins and/or collateral will be sent in case of\n /// @param who Address of the contract to handle in case of repayment of stablecoins from received collateral\n /// @param repayData Data to pass to the repayment contract in case of\n /// @return paymentData Struct containing the accounting changes from the protocol's perspective (like how much of collateral\n /// or how much has been received). Note that the values in the struct are not aggregated and you could have in the output\n /// a positive amount of stablecoins to receive as well as a positive amount of stablecoins to give\n /// @dev This function is optimized to reduce gas cost due to payment from or to the user and that expensive calls\n /// or computations (like `oracleValue`) are done only once\n /// @dev When specifying `vaultID` in `data`, it is important to know that if you specify `vaultID = 0`, it will simply\n /// use the latest `vaultID`. This is the default behavior, and unless you're engaging into some complex protocol actions\n /// it is encouraged to use `vaultID = 0` only when the first action of the batch is `createVault`\n function angle(\n ActionType[] memory actions,\n bytes[] memory datas,\n address from,\n address to,\n address who,\n bytes memory repayData\n ) external returns (PaymentData memory paymentData);\n\n /// @notice This function is a wrapper built on top of the function above. It enables users to interact with the contract\n /// without having to provide `who` and `repayData` parameters\n function angle(\n ActionType[] memory actions,\n bytes[] memory datas,\n address from,\n address to\n ) external returns (PaymentData memory paymentData);\n\n /// @notice Initializes the `VaultManager` contract\n /// @param _treasury Treasury address handling the contract\n /// @param _collateral Collateral supported by this contract\n /// @param _oracle Oracle contract used\n /// @param _symbol Symbol used to define the `VaultManager` name and symbol\n /// @dev The parameters and the oracle are the only elements which could be modified once the\n /// contract has been initialized\n /// @dev For the contract to be fully initialized, governance needs to set the parameters for the liquidation\n /// boost\n function initialize(\n ITreasury _treasury,\n IERC20 _collateral,\n IOracle _oracle,\n VaultParameters calldata params,\n string memory _symbol\n ) external;\n\n /// @notice Minimum amount of debt a vault can have, expressed in `BASE_TOKENS` that is to say the base of the agTokens\n function dust() external view returns (uint256);\n\n /// @notice Pauses external permissionless functions of the contract\n function togglePause() external;\n}\n\n/// @title IVaultManagerStorage\n/// @author Angle Labs, Inc.\n/// @notice Interface for the `VaultManager` contract\n/// @dev This interface contains getters of the contract's public variables used by other contracts\n/// of this module\ninterface IVaultManagerStorage {\n /// @notice Encodes the maximum ratio stablecoin/collateral a vault can have before being liquidated. It's what\n /// determines the minimum collateral ratio of a position\n function collateralFactor() external view returns (uint64);\n\n /// @notice Stablecoin handled by this contract. Another `VaultManager` contract could have\n /// the same rights as this `VaultManager` on the stablecoin contract\n function stablecoin() external view returns (IAgToken);\n\n /// @notice Reference to the `treasury` contract handling this `VaultManager`\n function treasury() external view returns (ITreasury);\n\n /// @notice Oracle contract to get access to the price of the collateral with respect to the stablecoin\n function oracle() external view returns (IOracle);\n\n /// @notice The `interestAccumulator` variable keeps track of the interest that should accrue to the protocol.\n /// The stored value is not necessarily the true value: this one is recomputed every time an action takes place\n /// within the protocol. It is in base `BASE_INTEREST`\n function interestAccumulator() external view returns (uint256);\n\n /// @notice Reference to the collateral handled by this `VaultManager`\n function collateral() external view returns (IERC20);\n\n /// @notice Total normalized amount of stablecoins borrowed, not taking into account the potential bad debt accumulated\n /// This value is expressed in the base of Angle stablecoins (`BASE_TOKENS = 10**18`)\n function totalNormalizedDebt() external view returns (uint256);\n\n /// @notice Maximum amount of stablecoins that can be issued with this contract. It is expressed in `BASE_TOKENS`\n function debtCeiling() external view returns (uint256);\n\n /// @notice Maps a `vaultID` to its data (namely collateral amount and normalized debt)\n function vaultData(uint256 vaultID) external view returns (uint256 collateralAmount, uint256 normalizedDebt);\n\n /// @notice ID of the last vault created. The `vaultIDCount` variables serves as a counter to generate a unique\n /// `vaultID` for each vault: it is like `tokenID` in basic ERC721 contracts\n function vaultIDCount() external view returns (uint256);\n}\n\n/// @title IVaultManager\n/// @author Angle Labs, Inc.\n/// @notice Interface for the `VaultManager` contract\ninterface IVaultManager is IVaultManagerFunctions, IVaultManagerStorage, IERC721Metadata {\n function isApprovedOrOwner(address spender, uint256 vaultID) external view returns (bool);\n}\n\n/// @title IVaultManagerListing\n/// @author Angle Labs, Inc.\n/// @notice Interface for the `VaultManagerListing` contract\ninterface IVaultManagerListing is IVaultManager {\n /// @notice Get the collateral owned by `user` in the contract\n /// @dev This function effectively sums the collateral amounts of all the vaults owned by `user`\n function getUserCollateral(address user) external view returns (uint256);\n}\n" + }, + "contracts/keeperMulticall/KeeperMulticall.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\nimport \"@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/access/AccessControlUpgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol\";\nimport \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\nimport \"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\";\nimport \"./RevertReasonParser.sol\";\n\n/// @title KeeperMulticall\n/// @notice Allows an authorized caller (keeper) to execute multiple actions in a single tx.\n/// @author Angle Labs, Inc.\n/// @dev Special features:\n/// - ability to pay the miner (for private Flashbots transactions)\n/// - swap tokens through 1inch\n/// @dev Tx need to be encoded as an array of Action. The flag `isDelegateCall` is used for calling functions within this same contract\ncontract KeeperMulticall is Initializable, AccessControlUpgradeable {\n using SafeERC20 for IERC20;\n\n bytes32 public constant KEEPER_ROLE = keccak256(\"KEEPER_ROLE\");\n\n //solhint-disable-next-line\n address private constant _oneInch = 0x1111111254fb6c44bAC0beD2854e76F90643097d;\n\n struct Action {\n address target;\n bytes data;\n bool isDelegateCall;\n }\n\n event LogAction(address indexed target, bytes data);\n event SentToMiner(uint256 indexed value);\n event Recovered(address indexed tokenAddress, address indexed to, uint256 amount);\n\n error AmountOutTooLow(uint256 amount, uint256 min);\n error BalanceTooLow();\n error FlashbotsErrorPayingMiner(uint256 value);\n error IncompatibleLengths();\n error RevertBytes();\n error WrongAmount();\n error ZeroAddress();\n\n constructor() initializer {}\n\n function initialize(address keeper) external initializer {\n __AccessControl_init();\n\n _setupRole(KEEPER_ROLE, keeper);\n _setRoleAdmin(KEEPER_ROLE, KEEPER_ROLE);\n }\n\n /// @notice Allows an authorized keeper to execute multiple actions in a single step\n /// @param actions Actions to be executed\n /// @param percentageToMiner Percentage to pay to miner expressed in bps (10000)\n /// @dev This is the main entry point for actions to be executed. The `isDelegateCall` flag is used for calling function inside this `KeeperMulticall` contract,\n /// if we call other contracts, the flag should be false\n function executeActions(\n Action[] memory actions,\n uint256 percentageToMiner\n ) external payable onlyRole(KEEPER_ROLE) returns (bytes[] memory) {\n uint256 numberOfActions = actions.length;\n if (numberOfActions == 0) revert IncompatibleLengths();\n\n bytes[] memory returnValues = new bytes[](numberOfActions + 1);\n\n uint256 balanceBefore = address(this).balance;\n\n for (uint256 i; i < numberOfActions; ++i) {\n returnValues[i] = _executeAction(actions[i]);\n }\n\n if (percentageToMiner != 0) {\n if (percentageToMiner >= 10000) revert WrongAmount();\n uint256 balanceAfter = address(this).balance;\n if (balanceAfter > balanceBefore) {\n uint256 amountToMiner = ((balanceAfter - balanceBefore) * percentageToMiner) / 10000;\n returnValues[numberOfActions] = payFlashbots(amountToMiner);\n }\n }\n\n return returnValues;\n }\n\n /// @notice Gets the action address and data and executes it\n /// @param action Action to be executed\n function _executeAction(Action memory action) internal returns (bytes memory) {\n bool success;\n bytes memory response;\n\n if (action.isDelegateCall) {\n //solhint-disable-next-line\n (success, response) = action.target.delegatecall(action.data);\n } else {\n //solhint-disable-next-line\n (success, response) = action.target.call(action.data);\n }\n\n require(success, RevertReasonParser.parse(response, \"action reverted: \"));\n emit LogAction(action.target, action.data);\n return response;\n }\n\n /// @notice Ability to pay miner directly. Used for Flashbots to execute private transactions\n /// @param value Value to be sent\n function payFlashbots(uint256 value) public payable onlyRole(KEEPER_ROLE) returns (bytes memory) {\n //solhint-disable-next-line\n (bool success, bytes memory response) = block.coinbase.call{ value: value }(\"\");\n if (!success) revert FlashbotsErrorPayingMiner(value);\n emit SentToMiner(value);\n return response;\n }\n\n /// @notice Used to check the balances the token holds for each token. If we don't have enough of a token, we revert the tx\n /// @param tokens Array of tokens to check\n /// @param minBalances Array of balances for each token\n function finalBalanceCheck(IERC20[] memory tokens, uint256[] memory minBalances) external view returns (bool) {\n uint256 tokensLength = tokens.length;\n if (tokensLength == 0 || tokensLength != minBalances.length) revert IncompatibleLengths();\n\n for (uint256 i; i < tokensLength; ++i) {\n if (address(tokens[i]) == 0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE) {\n if (address(this).balance < minBalances[i]) revert BalanceTooLow();\n } else {\n if (tokens[i].balanceOf(address(this)) < minBalances[i]) revert BalanceTooLow();\n }\n }\n\n return true;\n }\n\n /// @notice Swap token to another through 1Inch\n /// @param minAmountOut Minimum amount of `out` token to receive for the swap to happen\n /// @param payload Bytes needed for 1Inch API\n function swapToken(uint256 minAmountOut, bytes memory payload) external onlyRole(KEEPER_ROLE) {\n //solhint-disable-next-line\n (bool success, bytes memory result) = _oneInch.call(payload);\n if (!success) _revertBytes(result);\n\n uint256 amountOut = abi.decode(result, (uint256));\n if (amountOut < minAmountOut) revert AmountOutTooLow(amountOut, minAmountOut);\n }\n\n /// @notice Copied from 1Inch contract, used to revert if there is an error\n function _revertBytes(bytes memory errMsg) internal pure {\n if (errMsg.length != 0) {\n //solhint-disable-next-line\n assembly {\n revert(add(32, errMsg), mload(errMsg))\n }\n }\n revert RevertBytes();\n }\n\n /// @notice Approve a `spender` for `token`\n /// @param token Address of the token to approve\n /// @param spender Address of the spender to approve\n /// @param amount Amount to approve\n function approve(IERC20 token, address spender, uint256 amount) external onlyRole(KEEPER_ROLE) {\n uint256 currentAllowance = token.allowance(address(this), spender);\n if (currentAllowance < amount) {\n token.safeIncreaseAllowance(spender, amount - currentAllowance);\n } else if (currentAllowance > amount) {\n token.safeDecreaseAllowance(spender, currentAllowance - amount);\n }\n }\n\n receive() external payable {}\n\n /// @notice Withdraw stuck funds\n /// @param token Address of the token to recover\n /// @param receiver Address where to send the tokens\n /// @param amount Amount to recover\n function withdrawStuckFunds(address token, address receiver, uint256 amount) external onlyRole(KEEPER_ROLE) {\n if (receiver == address(0)) revert ZeroAddress();\n if (token == 0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE) {\n payable(receiver).transfer(amount);\n } else {\n IERC20(token).safeTransfer(receiver, amount);\n }\n\n emit Recovered(token, receiver, amount);\n }\n}\n" + }, + "contracts/keeperMulticall/MulticallWithFailure.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.12;\n\n/// @title MultiCallWithFailure\n/// @author Angle Labs, Inc.\n/// @notice Multicall contract allowing subcalls to fail without reverting the entire call\ncontract MultiCallWithFailure {\n error SubcallFailed();\n\n struct Call {\n address target;\n bytes data;\n bool canFail;\n }\n\n function multiCall(Call[] memory calls) external view returns (bytes[] memory) {\n bytes[] memory results = new bytes[](calls.length);\n\n for (uint256 i; i < calls.length; ++i) {\n (bool success, bytes memory result) = calls[i].target.staticcall(calls[i].data);\n if (!calls[i].canFail) {\n if (!success) {\n revert SubcallFailed();\n }\n }\n results[i] = result;\n }\n\n return results;\n }\n}\n" + }, + "contracts/keeperMulticall/RevertReasonParser.sol": { + "content": "// SPDX-License-Identifier: GNU-3\n\npragma solidity ^0.8.12;\n\n/// @title RevertReasonParser\n/// @author 1Inch team, taken from:\n/// - https://docs.1inch.io/docs/limit-order-protocol/smart-contract/libraries/RevertReasonParser/\n/// - https://etherscan.io/address/0x1111111254fb6c44bAC0beD2854e76F90643097d#code\nlibrary RevertReasonParser {\n bytes4 private constant _PANIC_SELECTOR = bytes4(keccak256(\"Panic(uint256)\"));\n bytes4 private constant _ERROR_SELECTOR = bytes4(keccak256(\"Error(string)\"));\n\n function parse(bytes memory data, string memory prefix) internal pure returns (string memory) {\n if (data.length >= 4) {\n bytes4 selector;\n //solhint-disable-next-line\n assembly {\n selector := mload(add(data, 0x20))\n }\n\n // 68 = 4-byte selector + 32 bytes offset + 32 bytes length\n if (selector == _ERROR_SELECTOR && data.length >= 68) {\n uint256 offset;\n bytes memory reason;\n // solhint-disable no-inline-assembly\n assembly {\n // 36 = 32 bytes data length + 4-byte selector\n offset := mload(add(data, 36))\n reason := add(data, add(36, offset))\n }\n /*\n revert reason is padded up to 32 bytes with ABI encoder: Error(string)\n also sometimes there is extra 32 bytes of zeros padded in the end:\n https://github.com/ethereum/solidity/issues/10170\n because of that we can't check for equality and instead check\n that offset + string length + extra 36 bytes is less than overall data length\n */\n require(data.length >= 36 + offset + reason.length, \"Invalid revert reason\");\n return string(abi.encodePacked(prefix, \"Error(\", reason, \")\"));\n }\n // 36 = 4-byte selector + 32 bytes integer\n else if (selector == _PANIC_SELECTOR && data.length == 36) {\n uint256 code;\n // solhint-disable no-inline-assembly\n assembly {\n // 36 = 32 bytes data length + 4-byte selector\n code := mload(add(data, 36))\n }\n return string(abi.encodePacked(prefix, \"Panic(\", _toHex(code), \")\"));\n }\n }\n\n return string(abi.encodePacked(prefix, \"Unknown(\", _toHex(data), \")\"));\n }\n\n function _toHex(uint256 value) private pure returns (string memory) {\n return _toHex(abi.encodePacked(value));\n }\n\n function _toHex(bytes memory data) private pure returns (string memory) {\n bytes16 alphabet = 0x30313233343536373839616263646566;\n bytes memory str = new bytes(2 + data.length * 2);\n str[0] = \"0\";\n str[1] = \"x\";\n for (uint256 i; i < data.length; ++i) {\n str[2 * i + 2] = alphabet[uint8(data[i] >> 4)];\n str[2 * i + 3] = alphabet[uint8(data[i] & 0x0f)];\n }\n return string(str);\n }\n}\n" + }, + "contracts/mock/Mock1Inch.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.12;\n\nimport \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\nimport \"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\";\n\ncontract Mock1Inch {\n using SafeERC20 for IERC20;\n\n function swap(address tokenIn, uint256 amountIn, address to, address tokenOut, uint256 amountOut) external {\n IERC20(tokenIn).safeTransferFrom(msg.sender, to, amountIn);\n if (tokenOut == 0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE) {\n //solhint-disable-next-line\n (bool sent, bytes memory data) = msg.sender.call{ value: amountOut }(\"\");\n data;\n require(sent, \"Failed to send Ether\");\n } else {\n IERC20(tokenOut).safeTransferFrom(to, msg.sender, amountOut);\n }\n }\n\n receive() external payable {}\n}\n" + }, + "contracts/mock/MockAnything.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.12;\n\ncontract MockAnything {\n uint256 public stateVar = 1;\n\n error CustomError();\n error CustomErrorWithValue(uint256);\n\n function fail(uint256 value) external view returns (uint256) {\n stateVar;\n if (value < 10) {\n revert CustomError();\n }\n if (value < 20) {\n revert CustomErrorWithValue(value);\n }\n return value + 1;\n }\n\n function modifyState(uint256 value) external {\n stateVar = value;\n }\n}\n" + }, + "contracts/mock/MockChainlinkOracle.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.7;\n\ninterface MockAggregatorV3Interface {\n function decimals() external view returns (uint8);\n\n function description() external view returns (string memory);\n\n function version() external view returns (uint256);\n\n function getRoundData(\n uint80 _roundId\n )\n external\n view\n returns (uint80 roundId, int256 answer, uint256 startedAt, uint256 updatedAt, uint80 answeredInRound);\n\n function latestRoundData()\n external\n view\n returns (uint80 roundId, int256 answer, uint256 startedAt, uint256 updatedAt, uint80 answeredInRound);\n}\n\ncontract MockChainlinkOracle is MockAggregatorV3Interface {\n uint80 public roundId = 0;\n uint8 public keyDecimals = 0;\n\n struct Entry {\n uint80 roundId;\n int256 answer;\n uint256 startedAt;\n uint256 updatedAt;\n uint80 answeredInRound;\n }\n\n mapping(uint256 => Entry) public entries;\n\n bool public latestRoundDataShouldRevert;\n\n string public desc;\n\n constructor() {}\n\n // Mock setup function\n function setLatestAnswer(int256 answer, uint256 timestamp) external {\n roundId++;\n entries[roundId] = Entry({\n roundId: roundId,\n answer: answer,\n startedAt: timestamp,\n updatedAt: timestamp,\n answeredInRound: roundId\n });\n }\n\n function setLatestAnswerWithRound(int256 answer, uint256 timestamp, uint80 _roundId) external {\n roundId = _roundId;\n entries[roundId] = Entry({\n roundId: roundId,\n answer: answer,\n startedAt: timestamp,\n updatedAt: timestamp,\n answeredInRound: roundId\n });\n }\n\n function setLatestAnswerRevert(int256 answer, uint256 timestamp) external {\n roundId++;\n entries[roundId] = Entry({\n roundId: roundId,\n answer: answer,\n startedAt: timestamp,\n updatedAt: timestamp,\n answeredInRound: roundId - 1\n });\n }\n\n function setLatestRoundDataShouldRevert(bool _shouldRevert) external {\n latestRoundDataShouldRevert = _shouldRevert;\n }\n\n function setDecimals(uint8 _decimals) external {\n keyDecimals = _decimals;\n }\n\n function setDescritpion(string memory _desc) external {\n desc = _desc;\n }\n\n function description() external view override returns (string memory) {\n return desc;\n }\n\n function version() external view override returns (uint256) {\n roundId;\n return 0;\n }\n\n function latestRoundData() external view override returns (uint80, int256, uint256, uint256, uint80) {\n if (latestRoundDataShouldRevert) {\n revert(\"latestRoundData reverted\");\n }\n return getRoundData(uint80(roundId));\n }\n\n function decimals() external view override returns (uint8) {\n return keyDecimals;\n }\n\n function getRoundData(uint80 _roundId) public view override returns (uint80, int256, uint256, uint256, uint80) {\n Entry memory entry = entries[_roundId];\n // Emulate a Chainlink aggregator\n require(entry.updatedAt > 0, \"No data present\");\n return (entry.roundId, entry.answer, entry.startedAt, entry.updatedAt, entry.answeredInRound);\n }\n}\n" + }, + "contracts/mock/MockCoreBorrow.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\nimport \"../interfaces/ICoreBorrow.sol\";\nimport \"../interfaces/IFlashAngle.sol\";\nimport \"../interfaces/ITreasury.sol\";\n\ncontract MockCoreBorrow is ICoreBorrow {\n mapping(address => bool) public flashLoaners;\n mapping(address => bool) public governors;\n mapping(address => bool) public guardians;\n\n function isFlashLoanerTreasury(address treasury) external view override returns (bool) {\n return flashLoaners[treasury];\n }\n\n function isGovernor(address admin) external view override returns (bool) {\n return governors[admin];\n }\n\n function isGovernorOrGuardian(address admin) external view override returns (bool) {\n return governors[admin] || guardians[admin];\n }\n\n function toggleGovernor(address admin) external {\n governors[admin] = !governors[admin];\n }\n\n function toggleGuardian(address admin) external {\n guardians[admin] = !guardians[admin];\n }\n\n function toggleFlashLoaners(address admin) external {\n flashLoaners[admin] = !flashLoaners[admin];\n }\n\n function addStablecoinSupport(IFlashAngle flashAngle, address _treasury) external {\n flashAngle.addStablecoinSupport(_treasury);\n }\n\n function removeStablecoinSupport(IFlashAngle flashAngle, address _treasury) external {\n flashAngle.removeStablecoinSupport(_treasury);\n }\n\n function setCore(IFlashAngle flashAngle, address _core) external {\n flashAngle.setCore(_core);\n }\n\n function setFlashLoanModule(ITreasury _treasury, address _flashLoanModule) external {\n _treasury.setFlashLoanModule(_flashLoanModule);\n }\n}\n" + }, + "contracts/mock/MockERC1271.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.12;\n\nimport \"../interfaces/external/IERC1271.sol\";\n\ncontract MockERC1271 is IERC1271 {\n uint256 public mode = 0;\n\n function setMode(uint256 _mode) public {\n mode = _mode;\n }\n\n /// @notice Returns whether the provided signature is valid for the provided data\n /// @dev MUST return the bytes4 magic value 0x1626ba7e when function passes.\n /// MUST NOT modify state (using STATICCALL for solc < 0.5, view modifier for solc > 0.5).\n /// MUST allow external calls.\n /// @return magicValue The bytes4 magic value 0x1626ba7e\n function isValidSignature(bytes32, bytes memory) external view returns (bytes4 magicValue) {\n if (mode == 1) magicValue = 0x1626ba7e;\n }\n}\n" + }, + "contracts/mock/MockERC721Receiver.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (token/ERC721/utils/ERC721Holder.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Implementation of the {IERC721Receiver} interface.\n *\n * Accepts all token transfers.\n * Make sure the contract is able to use its token with {IERC721-safeTransferFrom}, {IERC721-approve} or {IERC721-setApprovalForAll}.\n */\ncontract MockERC721Receiver {\n uint256 public mode = 0;\n\n function setMode(uint256 _mode) public {\n mode = _mode;\n }\n\n function onERC721Received(address, address, uint256, bytes memory) public view returns (bytes4) {\n require(mode != 1, \"0x1111111\");\n if (mode == 2) return this.setMode.selector;\n return this.onERC721Received.selector;\n }\n}\n" + }, + "contracts/mock/MockEulerPool.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\nimport \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\n\ncontract MockEulerPool {\n IERC20 public collateral;\n uint256 public poolSize;\n //solhint-disable-next-line\n uint256 public MAX_SANE_AMOUNT;\n\n mapping(address => uint256) public users;\n uint256 public interestRateAccumulator;\n\n constructor(IERC20 collateral_, uint256 poolSize_) {\n collateral = collateral_;\n poolSize = poolSize_;\n interestRateAccumulator = 10 ** 18;\n MAX_SANE_AMOUNT = type(uint112).max;\n }\n\n function setPoolSize(uint256 poolSize_) external {\n uint256 balance = collateral.balanceOf(address(this));\n poolSize = poolSize_;\n if (balance > poolSize_) collateral.transfer(msg.sender, balance - poolSize_);\n if (balance < poolSize_) collateral.transferFrom(msg.sender, address(this), poolSize_ - balance);\n }\n\n function setInterestRateAccumulator(uint256 interestRateAccumulator_) external {\n interestRateAccumulator = interestRateAccumulator_;\n }\n\n //solhint-disable-next-line\n function setMAXSANEAMOUNT(uint256 MAX_SANE_AMOUNT_) external {\n MAX_SANE_AMOUNT = MAX_SANE_AMOUNT_;\n }\n\n function balanceOfUnderlying(address account) external view returns (uint256) {\n return (users[account] * interestRateAccumulator) / 10 ** 18;\n }\n\n function deposit(uint256, uint256 amount) external {\n users[msg.sender] += (amount * 10 ** 18) / interestRateAccumulator;\n poolSize += amount;\n collateral.transferFrom(msg.sender, address(this), amount);\n }\n\n function withdraw(uint256, uint256 amount) external {\n if (amount == type(uint256).max) amount = (users[msg.sender] * interestRateAccumulator) / 10 ** 18;\n\n require(amount <= poolSize, \"4\");\n users[msg.sender] -= (amount * 10 ** 18) / interestRateAccumulator;\n collateral.transfer(msg.sender, amount);\n }\n}\n" + }, + "contracts/mock/MockFlashLoanModule.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\nimport \"../interfaces/IFlashAngle.sol\";\nimport \"../interfaces/ICoreBorrow.sol\";\n\ncontract MockFlashLoanModule is IFlashAngle {\n ICoreBorrow public override core;\n mapping(address => bool) public stablecoinsSupported;\n mapping(IAgToken => uint256) public interestAccrued;\n uint256 public surplusValue;\n\n constructor(ICoreBorrow _core) {\n core = _core;\n }\n\n function accrueInterestToTreasury(IAgToken stablecoin) external override returns (uint256 balance) {\n balance = surplusValue;\n interestAccrued[stablecoin] += balance;\n }\n\n function addStablecoinSupport(address _treasury) external override {\n stablecoinsSupported[_treasury] = true;\n }\n\n function removeStablecoinSupport(address _treasury) external override {\n stablecoinsSupported[_treasury] = false;\n }\n\n function setCore(address _core) external override {\n core = ICoreBorrow(_core);\n }\n\n function setSurplusValue(uint256 _surplusValue) external {\n surplusValue = _surplusValue;\n }\n}\n" + }, + "contracts/mock/MockFlashLoanReceiver.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.7;\n\nimport \"@openzeppelin/contracts/token/ERC20/ERC20.sol\";\n\nimport \"@openzeppelin/contracts/interfaces/IERC3156FlashBorrower.sol\";\n\nimport \"@openzeppelin/contracts/interfaces/IERC3156FlashLender.sol\";\n\ncontract MockFlashLoanReceiver is IERC3156FlashBorrower {\n bytes32 public constant CALLBACK_SUCCESS = keccak256(\"ERC3156FlashBorrower.onFlashLoan\");\n\n constructor() {}\n\n function onFlashLoan(\n address,\n address token,\n uint256 amount,\n uint256 fee,\n bytes calldata data\n ) external override returns (bytes32) {\n IERC20(token).approve(msg.sender, amount + fee);\n if (amount >= 10 ** 21) return keccak256(\"error\");\n if (amount == 2 * 10 ** 18) {\n IERC3156FlashLender(msg.sender).flashLoan(IERC3156FlashBorrower(address(this)), token, amount, data);\n return keccak256(\"reentrant\");\n } else return CALLBACK_SUCCESS;\n }\n}\n" + }, + "contracts/mock/MockInterestRateComputer.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\ncontract MockInterestRateComputer {\n uint256 public interestRate;\n uint256 public interestAccumulator;\n uint256 public immutable baseInterest;\n uint256 public immutable halfBase;\n\n uint256 public constant WEEK = 7 * 86400;\n\n constructor(uint256 _baseInterest, uint256 _interestRate) {\n interestAccumulator = _baseInterest;\n baseInterest = _baseInterest;\n halfBase = _baseInterest / 2;\n interestRate = _interestRate;\n }\n\n function _calculateAngle(uint256 exp, uint256 _interestAccumulator) internal view returns (uint256) {\n uint256 ratePerSecond = interestRate;\n if (exp == 0 || ratePerSecond == 0) return _interestAccumulator;\n uint256 expMinusOne = exp - 1;\n uint256 expMinusTwo = exp > 2 ? exp - 2 : 0;\n uint256 basePowerTwo = (ratePerSecond * ratePerSecond) / baseInterest;\n uint256 basePowerThree = (basePowerTwo * ratePerSecond) / baseInterest;\n uint256 secondTerm = (exp * expMinusOne * basePowerTwo) / 2;\n uint256 thirdTerm = (exp * expMinusOne * expMinusTwo * basePowerThree) / 6;\n return (_interestAccumulator * (baseInterest + ratePerSecond * exp + secondTerm + thirdTerm)) / baseInterest;\n }\n\n function _calculateAave(uint256 exp, uint256 _interestAccumulator) internal view returns (uint256) {\n uint256 ratePerSecond = interestRate;\n if (exp == 0 || ratePerSecond == 0) return _interestAccumulator;\n uint256 expMinusOne = exp - 1;\n uint256 expMinusTwo = exp > 2 ? exp - 2 : 0;\n uint256 basePowerTwo = (ratePerSecond * ratePerSecond + halfBase) / baseInterest;\n uint256 basePowerThree = (basePowerTwo * ratePerSecond + halfBase) / baseInterest;\n uint256 secondTerm = (exp * expMinusOne * basePowerTwo) / 2;\n uint256 thirdTerm = (exp * expMinusOne * expMinusTwo * basePowerThree) / 6;\n return (_interestAccumulator * (baseInterest + ratePerSecond * exp + secondTerm + thirdTerm)) / baseInterest;\n }\n\n function _calculateCompound(uint256 exp, uint256 _interestAccumulator) internal view returns (uint256) {\n return _interestAccumulator * (baseInterest + interestRate * exp);\n }\n\n function _rpow(uint256 x, uint256 n, uint256 base) internal pure returns (uint256 z) {\n //solhint-disable-next-line\n assembly {\n switch x\n case 0 {\n switch n\n case 0 {\n z := base\n }\n default {\n z := 0\n }\n }\n default {\n switch mod(n, 2)\n case 0 {\n z := base\n }\n default {\n z := x\n }\n let half := div(base, 2) // for rounding.\n for {\n n := div(n, 2)\n } n {\n n := div(n, 2)\n } {\n let xx := mul(x, x)\n if iszero(eq(div(xx, x), x)) {\n revert(0, 0)\n }\n let xxRound := add(xx, half)\n if lt(xxRound, xx) {\n revert(0, 0)\n }\n x := div(xxRound, base)\n if mod(n, 2) {\n let zx := mul(z, x)\n if and(iszero(iszero(x)), iszero(eq(div(zx, x), z))) {\n revert(0, 0)\n }\n let zxRound := add(zx, half)\n if lt(zxRound, zx) {\n revert(0, 0)\n }\n z := div(zxRound, base)\n }\n }\n }\n }\n }\n\n function _calculateMaker(uint256 delta, uint256 _interestAccumulator) internal view returns (uint256) {\n return (_rpow(baseInterest + interestRate, delta, baseInterest) * _interestAccumulator) / baseInterest;\n }\n\n function calculateAngle(uint256 delta) external view returns (uint256) {\n return _calculateAngle(delta, interestAccumulator);\n }\n\n function calculateAave(uint256 delta) external view returns (uint256) {\n return _calculateAave(delta, interestAccumulator);\n }\n\n function calculateMaker(uint256 delta) external view returns (uint256) {\n return _calculateMaker(delta, interestAccumulator);\n }\n\n function calculateAngle1Year() external view returns (uint256) {\n uint256 _interestAccumulator = interestAccumulator;\n for (uint256 i; i < 52; ++i) {\n _interestAccumulator = _calculateAngle(WEEK, _interestAccumulator);\n }\n return _interestAccumulator;\n }\n\n function calculateAave1Year() external view returns (uint256) {\n uint256 _interestAccumulator = interestAccumulator;\n for (uint256 i; i < 52; ++i) {\n _interestAccumulator = _calculateAave(WEEK, _interestAccumulator);\n }\n return _interestAccumulator;\n }\n\n function calculateMaker1Year() external view returns (uint256) {\n uint256 _interestAccumulator = interestAccumulator;\n for (uint256 i; i < 52; ++i) {\n _interestAccumulator = _calculateMaker(WEEK, _interestAccumulator);\n }\n return _interestAccumulator;\n }\n\n function calculateAngle1YearDirect() external view returns (uint256) {\n uint256 _interestAccumulator = interestAccumulator;\n _interestAccumulator = _calculateAngle(52 * WEEK, _interestAccumulator);\n\n return _interestAccumulator;\n }\n\n function calculateAave1YearDirect() external view returns (uint256) {\n uint256 _interestAccumulator = interestAccumulator;\n _interestAccumulator = _calculateAave(52 * WEEK, _interestAccumulator);\n\n return _interestAccumulator;\n }\n\n function calculateMaker1YearDirect() external view returns (uint256) {\n uint256 _interestAccumulator = interestAccumulator;\n _interestAccumulator = _calculateMaker(52 * WEEK, _interestAccumulator);\n\n return _interestAccumulator;\n }\n\n function calculateCompound1YearDirect() external view returns (uint256) {\n uint256 _interestAccumulator = interestAccumulator;\n _interestAccumulator = _calculateCompound(52 * WEEK, _interestAccumulator);\n\n return _interestAccumulator;\n }\n}\n" + }, + "contracts/mock/MockKeeperMulticall.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.12;\n\nimport \"@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/access/AccessControlUpgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol\";\nimport \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\nimport \"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\";\n\ncontract MockKeeperMulticall is Initializable, AccessControlUpgradeable {\n using SafeERC20 for IERC20;\n\n bytes32 public constant KEEPER_ROLE = keccak256(\"KEEPER_ROLE\");\n\n //solhint-disable-next-line\n address private constant _oneInch = 0x1111111254fb6c44bAC0beD2854e76F90643097d;\n\n struct Action {\n address target;\n bytes data;\n bool isDelegateCall;\n }\n\n event LogAction(address indexed target, bytes data);\n event SentToMiner(uint256 indexed value);\n event Recovered(address indexed tokenAddress, address indexed to, uint256 amount);\n\n error AmountOutTooLow(uint256 amount, uint256 min);\n error BalanceTooLow();\n error FlashbotsErrorPayingMiner(uint256 value);\n error IncompatibleLengths();\n error RevertBytes();\n error ZeroAddress();\n\n constructor() initializer {}\n\n function initialize(address keeper) public initializer {\n __AccessControl_init();\n\n _setupRole(KEEPER_ROLE, keeper);\n _setRoleAdmin(KEEPER_ROLE, KEEPER_ROLE);\n }\n}\n\ncontract MockKeeperMulticall2 {\n uint256 public varTest = 1;\n\n bytes32 public constant KEEPER_ROLE = keccak256(\"KEEPER_ROLE\");\n\n //solhint-disable-next-line\n address private constant _oneInch = 0x1111111254fb6c44bAC0beD2854e76F90643097d;\n\n struct Action {\n address target;\n bytes data;\n bool isDelegateCall;\n }\n\n event LogAction(address indexed target, bytes data);\n event SentToMiner(uint256 indexed value);\n event Recovered(address indexed tokenAddress, address indexed to, uint256 amount);\n\n error AmountOutTooLow(uint256 amount, uint256 min);\n error BalanceTooLow();\n error FlashbotsErrorPayingMiner(uint256 value);\n error IncompatibleLengths();\n error RevertBytes();\n error ZeroAddress();\n\n function functionTest() external pure returns (bool) {\n return true;\n }\n}\n" + }, + "contracts/mock/MockLayerZero.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\ninterface ILzApp {\n function lzReceive(uint16 _srcChainId, bytes memory _srcAddress, uint64 _nonce, bytes memory _payload) external;\n}\n\ncontract MockLayerZero {\n mapping(uint16 => uint256) public counters;\n uint256 public config;\n mapping(uint16 => uint64) public outboundNonce;\n uint256 public resumeReceived;\n uint256 public sendVersion;\n uint256 public receiveVersion;\n\n /// @notice Initiate with a fixe change rate\n constructor() {}\n\n function send(\n uint16 _dstChainId,\n bytes calldata,\n bytes calldata,\n address,\n address,\n bytes calldata\n ) external payable {\n counters[_dstChainId] += 1;\n }\n\n function getOutboundNonce(uint16 _dstChainId, address) external view returns (uint64) {\n return outboundNonce[_dstChainId];\n }\n\n function setOutBoundNonce(uint16 _from, uint64 value) external {\n outboundNonce[_from] = value;\n }\n\n function lzReceive(\n address lzApp,\n uint16 _srcChainId,\n bytes memory _srcAddress,\n uint64 _nonce,\n bytes memory _payload\n ) public {\n ILzApp(lzApp).lzReceive(_srcChainId, _srcAddress, _nonce, _payload);\n }\n\n function estimateFees(\n uint16,\n address,\n bytes calldata,\n bool,\n bytes calldata\n ) external pure returns (uint256 nativeFee, uint256 zroFee) {\n return (123, 456);\n }\n\n function setConfig(uint16, uint16, uint256 _configType, bytes calldata) external {\n config = _configType;\n }\n\n function getConfig(uint16, uint16, address, uint256) external view returns (bytes memory) {\n return abi.encodePacked(config);\n }\n\n function setSendVersion(uint16 _version) external {\n sendVersion = _version;\n }\n\n function setReceiveVersion(uint16 _version) external {\n receiveVersion = _version;\n }\n\n function forceResumeReceive(uint16, bytes calldata) external {\n resumeReceived = 1 - resumeReceived;\n }\n}\n" + }, + "contracts/mock/MockLiquidityGauge.sol": { + "content": "// SPDX-License-Identifier: UNLICENSED\npragma solidity ^0.8.12;\n\nimport { ILiquidityGauge } from \"../interfaces/coreModule/ILiquidityGauge.sol\";\nimport \"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\";\nimport \"@openzeppelin/contracts/token/ERC20/ERC20.sol\";\n\ncontract MockLiquidityGauge is ILiquidityGauge, ERC20 {\n using SafeERC20 for IERC20;\n\n IERC20 internal _ANGLE = IERC20(0x31429d1856aD1377A8A0079410B297e1a9e214c2);\n IERC20 internal _token;\n mapping(address => uint256) public rewards;\n\n constructor(string memory name_, string memory symbol_, address token_) ERC20(name_, symbol_) {\n _token = IERC20(token_);\n }\n\n function deposit(\n uint256 _value,\n address _addr,\n // solhint-disable-next-line\n bool\n ) external {\n _token.safeTransferFrom(msg.sender, address(this), _value);\n _mint(_addr, _value);\n }\n\n function withdraw(\n uint256 _value,\n // solhint-disable-next-line\n bool\n ) external {\n _burn(msg.sender, _value);\n _token.safeTransfer(msg.sender, _value);\n }\n\n // solhint-disable-next-line\n function claim_rewards(address _addr, address _receiver) external {\n if (_receiver == address(0)) _receiver = _addr;\n _ANGLE.safeTransfer(_receiver, rewards[_addr]);\n rewards[_addr] = 0;\n }\n\n // solhint-disable-next-line\n function claimable_reward(address _addr, address) external view returns (uint256 amount) {\n return rewards[_addr];\n }\n\n function setReward(address receiver_, uint256 amount) external {\n rewards[receiver_] = amount;\n }\n}\n" + }, + "contracts/mock/MockOracle.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.7;\n\nimport \"../interfaces/IOracle.sol\";\n\ncontract MockOracle is IOracle {\n event Update(uint256 _peg);\n\n ITreasury public treasury;\n\n uint256 public base = 1 ether;\n uint256 public precision = 1 ether;\n uint256 public rate;\n bool public outdated;\n\n /// @notice Initiate with a fixe change rate\n constructor(uint256 rate_, ITreasury _treasury) {\n rate = rate_;\n treasury = _treasury;\n }\n\n /// @notice Mock read\n function read() external view override returns (uint256) {\n return rate;\n }\n\n /// @notice change oracle rate\n function update(uint256 newRate) external {\n rate = newRate;\n }\n\n function setTreasury(address _treasury) external override {\n treasury = ITreasury(_treasury);\n }\n\n function circuitChainlink() external pure override returns (AggregatorV3Interface[] memory) {}\n}\n" + }, + "contracts/mock/MockPolygonAgEUR.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.12;\n\nimport \"../agToken/polygon/utils/ERC20UpgradeableCustom.sol\";\nimport \"@openzeppelin/contracts-upgradeable/access/AccessControlUpgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/utils/cryptography/draft-EIP712Upgradeable.sol\";\nimport \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\nimport \"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\";\n\nimport \"../interfaces/IAgToken.sol\";\nimport \"../interfaces/ITreasury.sol\";\n\ninterface IChildToken {\n function deposit(address user, bytes calldata depositData) external;\n\n function withdraw(uint256 amount) external;\n}\n\ncontract MockPolygonAgEUR is\n Initializable,\n ERC20UpgradeableCustom,\n AccessControlUpgradeable,\n EIP712Upgradeable,\n IChildToken\n{\n bytes32 public constant DEPOSITOR_ROLE = keccak256(\"DEPOSITOR_ROLE\");\n\n /// @dev Emitted when the child chain manager changes\n event ChildChainManagerAdded(address newAddress);\n event ChildChainManagerRevoked(address oldAddress);\n\n constructor() initializer {}\n\n function initialize(\n string memory _name,\n string memory _symbol,\n address childChainManager,\n address guardian\n ) public initializer {\n __ERC20_init(_name, _symbol);\n __AccessControl_init();\n _setupRole(DEFAULT_ADMIN_ROLE, guardian);\n _setupRole(DEPOSITOR_ROLE, childChainManager);\n __EIP712_init(_name, \"1\");\n }\n\n /**\n * @notice Called when the bridge has tokens to mint\n * @param user Address to mint the token to\n * @param depositData Encoded amount to mint\n */\n function deposit(address user, bytes calldata depositData) external override {\n require(hasRole(DEPOSITOR_ROLE, msg.sender));\n uint256 amount = abi.decode(depositData, (uint256));\n _mint(user, amount);\n }\n\n /**\n * @notice Called when user wants to withdraw tokens back to root chain\n * @dev Should burn user's tokens. This transaction will be verified when exiting on root chain\n * @param amount Amount of tokens to withdraw\n */\n function withdraw(uint256 amount) external override {\n _burn(_msgSender(), amount);\n }\n\n // =============================================================================\n // ======================= New data added for the upgrade ======================\n // =============================================================================\n\n mapping(address => bool) public isMinter;\n /// @notice Reference to the treasury contract which can grant minting rights\n address public treasury;\n /// @notice Boolean to check whether the contract has been reinitialized after its upgrade\n bool public treasuryInitialized;\n\n using SafeERC20 for IERC20;\n\n /// @notice Base used for fee computation\n uint256 public constant BASE_PARAMS = 10 ** 9;\n\n // =============================== Bridging Data ===============================\n\n /// @notice Struct with some data about a specific bridge token\n struct BridgeDetails {\n // Limit on the balance of bridge token held by the contract: it is designed\n // to reduce the exposure of the system to hacks\n uint256 limit;\n // Limit on the hourly volume of token minted through this bridge\n // Technically the limit over a rolling hour is hourlyLimit x2 as hourly limit\n // is enforced only between x:00 and x+1:00\n uint256 hourlyLimit;\n // Fee taken for swapping in and out the token\n uint64 fee;\n // Whether the associated token is allowed or not\n bool allowed;\n // Whether swapping in and out from the associated token is paused or not\n bool paused;\n }\n\n /// @notice Maps a bridge token to data\n mapping(address => BridgeDetails) public bridges;\n /// @notice List of all bridge tokens\n address[] public bridgeTokensList;\n /// @notice Maps a bridge token to the associated hourly volume\n mapping(address => mapping(uint256 => uint256)) public usage;\n /// @notice Maps an address to whether it is exempt of fees for when it comes to swapping in and out\n mapping(address => uint256) public isFeeExempt;\n\n uint256[44] private __gap;\n\n // ================================== Events ===================================\n\n event BridgeTokenAdded(address indexed bridgeToken, uint256 limit, uint256 hourlyLimit, uint64 fee, bool paused);\n event BridgeTokenToggled(address indexed bridgeToken, bool toggleStatus);\n event BridgeTokenRemoved(address indexed bridgeToken);\n event BridgeTokenFeeUpdated(address indexed bridgeToken, uint64 fee);\n event BridgeTokenLimitUpdated(address indexed bridgeToken, uint256 limit);\n event BridgeTokenHourlyLimitUpdated(address indexed bridgeToken, uint256 hourlyLimit);\n event HourlyLimitUpdated(uint256 hourlyLimit);\n event FeeToggled(address indexed theAddress, uint256 toggleStatus);\n event KeeperToggled(address indexed keeper, bool toggleStatus);\n event MinterToggled(address indexed minter);\n event Recovered(address indexed token, address indexed to, uint256 amount);\n event TreasuryUpdated(address indexed _treasury);\n\n // ================================== Errors ===================================\n\n error AssetStillControlledInReserves();\n error BurnAmountExceedsAllowance();\n error HourlyLimitExceeded();\n error InvalidSender();\n error InvalidToken();\n error InvalidTreasury();\n error NotGovernor();\n error NotGovernorOrGuardian();\n error NotMinter();\n error NotTreasury();\n error TooBigAmount();\n error TooHighParameterValue();\n error TreasuryAlreadyInitialized();\n error ZeroAddress();\n\n /// @notice Checks to see if it is the `Treasury` calling this contract\n /// @dev There is no Access Control here, because it can be handled cheaply through this modifier\n modifier onlyTreasury() {\n if (msg.sender != treasury) revert NotTreasury();\n _;\n }\n\n /// @notice Checks whether the sender has the minting right\n modifier onlyMinter() {\n if (!isMinter[msg.sender]) revert NotMinter();\n _;\n }\n\n /// @notice Checks whether the `msg.sender` has the governor role or not\n modifier onlyGovernor() {\n if (!ITreasury(treasury).isGovernor(msg.sender)) revert NotGovernor();\n _;\n }\n\n /// @notice Checks whether the `msg.sender` has the governor role or the guardian role\n modifier onlyGovernorOrGuardian() {\n if (!ITreasury(treasury).isGovernorOrGuardian(msg.sender)) revert NotGovernorOrGuardian();\n _;\n }\n\n /// @notice Sets up the treasury contract on Polygon after the upgrade\n /// @param _treasury Address of the treasury contract\n function setUpTreasury(address _treasury) external {\n // Only governor on Polygon\n if (msg.sender != 0xdA2D2f638D6fcbE306236583845e5822554c02EA) revert NotGovernor();\n if (address(ITreasury(_treasury).stablecoin()) != address(this)) revert InvalidTreasury();\n if (treasuryInitialized) revert TreasuryAlreadyInitialized();\n treasury = _treasury;\n treasuryInitialized = true;\n emit TreasuryUpdated(_treasury);\n }\n\n // =========================== External Function ===============================\n\n /// @notice Allows anyone to burn agToken without redeeming collateral back\n /// @param amount Amount of stablecoins to burn\n /// @dev This function can typically be called if there is a settlement mechanism to burn stablecoins\n function burnStablecoin(uint256 amount) external {\n _burnCustom(msg.sender, amount);\n }\n\n // ======================= Minter Role Only Functions ==========================\n\n function burnSelf(uint256 amount, address burner) external onlyMinter {\n _burnCustom(burner, amount);\n }\n\n function burnFrom(uint256 amount, address burner, address sender) external onlyMinter {\n _burnFromNoRedeem(amount, burner, sender);\n }\n\n function mint(address account, uint256 amount) external onlyMinter {\n _mint(account, amount);\n }\n\n // ======================= Treasury Only Functions =============================\n\n function addMinter(address minter) external onlyTreasury {\n isMinter[minter] = true;\n emit MinterToggled(minter);\n }\n\n function removeMinter(address minter) external {\n if (msg.sender != address(treasury) && msg.sender != minter) revert InvalidSender();\n isMinter[minter] = false;\n emit MinterToggled(minter);\n }\n\n function setTreasury(address _treasury) external onlyTreasury {\n treasury = _treasury;\n emit TreasuryUpdated(_treasury);\n }\n\n // ============================ Internal Function ==============================\n\n /// @notice Internal version of the function `burnFromNoRedeem`\n /// @param amount Amount to burn\n /// @dev It is at the level of this function that allowance checks are performed\n function _burnFromNoRedeem(uint256 amount, address burner, address sender) internal {\n if (burner != sender) {\n uint256 currentAllowance = allowance(burner, sender);\n if (currentAllowance < amount) revert BurnAmountExceedsAllowance();\n _approve(burner, sender, currentAllowance - amount);\n }\n _burnCustom(burner, amount);\n }\n\n // ==================== External Permissionless Functions ======================\n\n /// @notice Returns the list of all supported bridge tokens\n /// @dev Helpful for UIs\n function allBridgeTokens() external view returns (address[] memory) {\n return bridgeTokensList;\n }\n\n /// @notice Returns the current volume for a bridge, for the current hour\n /// @dev Helpful for UIs\n function currentUsage(address bridge) external view returns (uint256) {\n return usage[bridge][block.timestamp / 3600];\n }\n\n /// @notice Mints the canonical token from a supported bridge token\n /// @param bridgeToken Bridge token to use to mint\n /// @param amount Amount of bridge tokens to send\n /// @param to Address to which the stablecoin should be sent\n /// @dev Some fees may be taken by the protocol depending on the token used and on the address calling\n function swapIn(address bridgeToken, uint256 amount, address to) external returns (uint256) {\n BridgeDetails memory bridgeDetails = bridges[bridgeToken];\n if (!bridgeDetails.allowed || bridgeDetails.paused) revert InvalidToken();\n uint256 balance = IERC20(bridgeToken).balanceOf(address(this));\n if (balance + amount > bridgeDetails.limit) {\n // In case someone maliciously sends tokens to this contract\n // Or the limit changes\n if (bridgeDetails.limit > balance) amount = bridgeDetails.limit - balance;\n else {\n amount = 0;\n }\n }\n\n // Checking requirement on the hourly volume\n uint256 hour = block.timestamp / 3600;\n uint256 hourlyUsage = usage[bridgeToken][hour] + amount;\n if (hourlyUsage > bridgeDetails.hourlyLimit) {\n // Edge case when the hourly limit changes\n if (bridgeDetails.hourlyLimit > usage[bridgeToken][hour])\n amount = bridgeDetails.hourlyLimit - usage[bridgeToken][hour];\n else {\n amount = 0;\n }\n }\n usage[bridgeToken][hour] = usage[bridgeToken][hour] + amount;\n\n IERC20(bridgeToken).safeTransferFrom(msg.sender, address(this), amount);\n uint256 canonicalOut = amount;\n // Computing fees\n if (isFeeExempt[msg.sender] == 0) {\n canonicalOut -= (canonicalOut * bridgeDetails.fee) / BASE_PARAMS;\n }\n _mint(to, canonicalOut);\n return canonicalOut;\n }\n\n /// @notice Burns the canonical token in exchange for a bridge token\n /// @param bridgeToken Bridge token required\n /// @param amount Amount of canonical tokens to burn\n /// @param to Address to which the bridge token should be sent\n /// @dev Some fees may be taken by the protocol depending on the token used and on the address calling\n function swapOut(address bridgeToken, uint256 amount, address to) external returns (uint256) {\n BridgeDetails memory bridgeDetails = bridges[bridgeToken];\n if (!bridgeDetails.allowed || bridgeDetails.paused) revert InvalidToken();\n\n _burnCustom(msg.sender, amount);\n uint256 bridgeOut = amount;\n if (isFeeExempt[msg.sender] == 0) {\n bridgeOut -= (bridgeOut * bridgeDetails.fee) / BASE_PARAMS;\n }\n IERC20(bridgeToken).safeTransfer(to, bridgeOut);\n return bridgeOut;\n }\n\n // ======================= Governance Functions ================================\n\n /// @notice Adds support for a bridge token\n /// @param bridgeToken Bridge token to add: it should be a version of the stablecoin from another bridge\n /// @param limit Limit on the balance of bridge token this contract could hold\n /// @param hourlyLimit Limit on the hourly volume for this bridge\n /// @param paused Whether swapping for this token should be paused or not\n /// @param fee Fee taken upon swapping for or against this token\n function addBridgeToken(\n address bridgeToken,\n uint256 limit,\n uint256 hourlyLimit,\n uint64 fee,\n bool paused\n ) external onlyGovernor {\n if (bridges[bridgeToken].allowed || bridgeToken == address(0)) revert InvalidToken();\n if (fee > BASE_PARAMS) revert TooHighParameterValue();\n BridgeDetails memory _bridge;\n _bridge.limit = limit;\n _bridge.hourlyLimit = hourlyLimit;\n _bridge.paused = paused;\n _bridge.fee = fee;\n _bridge.allowed = true;\n bridges[bridgeToken] = _bridge;\n bridgeTokensList.push(bridgeToken);\n emit BridgeTokenAdded(bridgeToken, limit, hourlyLimit, fee, paused);\n }\n\n /// @notice Removes support for a token\n /// @param bridgeToken Address of the bridge token to remove support for\n function removeBridgeToken(address bridgeToken) external onlyGovernor {\n if (IERC20(bridgeToken).balanceOf(address(this)) != 0) revert AssetStillControlledInReserves();\n delete bridges[bridgeToken];\n // Deletion from `bridgeTokensList` loop\n uint256 bridgeTokensListLength = bridgeTokensList.length;\n for (uint256 i; i < bridgeTokensListLength - 1; ++i) {\n if (bridgeTokensList[i] == bridgeToken) {\n // Replace the `bridgeToken` to remove with the last of the list\n bridgeTokensList[i] = bridgeTokensList[bridgeTokensListLength - 1];\n break;\n }\n }\n // Remove last element in array\n bridgeTokensList.pop();\n emit BridgeTokenRemoved(bridgeToken);\n }\n\n /// @notice Recovers any ERC20 token\n /// @dev Can be used to withdraw bridge tokens for them to be de-bridged on mainnet\n function recoverERC20(address tokenAddress, address to, uint256 amountToRecover) external onlyGovernor {\n IERC20(tokenAddress).safeTransfer(to, amountToRecover);\n emit Recovered(tokenAddress, to, amountToRecover);\n }\n\n /// @notice Updates the `limit` amount for `bridgeToken`\n function setLimit(address bridgeToken, uint256 limit) external onlyGovernorOrGuardian {\n if (!bridges[bridgeToken].allowed) revert InvalidToken();\n bridges[bridgeToken].limit = limit;\n emit BridgeTokenLimitUpdated(bridgeToken, limit);\n }\n\n /// @notice Updates the `hourlyLimit` amount for `bridgeToken`\n function setHourlyLimit(address bridgeToken, uint256 hourlyLimit) external onlyGovernorOrGuardian {\n if (!bridges[bridgeToken].allowed) revert InvalidToken();\n bridges[bridgeToken].hourlyLimit = hourlyLimit;\n emit BridgeTokenHourlyLimitUpdated(bridgeToken, hourlyLimit);\n }\n\n /// @notice Updates the `fee` value for `bridgeToken`\n function setSwapFee(address bridgeToken, uint64 fee) external onlyGovernorOrGuardian {\n if (!bridges[bridgeToken].allowed) revert InvalidToken();\n if (fee > BASE_PARAMS) revert TooHighParameterValue();\n bridges[bridgeToken].fee = fee;\n emit BridgeTokenFeeUpdated(bridgeToken, fee);\n }\n\n /// @notice Pauses or unpauses swapping in and out for a token\n function toggleBridge(address bridgeToken) external onlyGovernorOrGuardian {\n if (!bridges[bridgeToken].allowed) revert InvalidToken();\n bool pausedStatus = bridges[bridgeToken].paused;\n bridges[bridgeToken].paused = !pausedStatus;\n emit BridgeTokenToggled(bridgeToken, !pausedStatus);\n }\n\n /// @notice Toggles fees for the address `theAddress`\n function toggleFeesForAddress(address theAddress) external onlyGovernorOrGuardian {\n uint256 feeExemptStatus = 1 - isFeeExempt[theAddress];\n isFeeExempt[theAddress] = feeExemptStatus;\n emit FeeToggled(theAddress, feeExemptStatus);\n }\n}\n" + }, + "contracts/mock/MockRouter.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\nimport \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\nimport \"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\";\n\nimport \"../interfaces/IAngleRouter.sol\";\nimport \"../interfaces/external/uniswap/IUniswapRouter.sol\";\nimport \"../interfaces/external/lido/IWStETH.sol\";\n\ncontract MockRouter is IUniswapV3Router, IWStETH {\n using SafeERC20 for IERC20;\n\n uint256 public counterAngleMint;\n uint256 public counterAngleBurn;\n uint256 public counter1Inch;\n uint256 public counterUni;\n uint256 public counterWrap;\n uint256 public counterMixer;\n uint256 public amountOutUni;\n uint256 public multiplierMintBurn;\n uint256 public stETHMultiplier;\n address public inToken;\n address public outToken;\n\n address public stETH;\n\n /// @notice Action types\n enum ActionType {\n transfer,\n wrap,\n wrapNative,\n sweep,\n sweepNative,\n unwrap,\n unwrapNative,\n swapIn,\n swapOut,\n uniswapV3,\n oneInch,\n claimRewards,\n gaugeDeposit,\n borrower\n }\n\n /// @notice Data needed to get permits\n struct PermitType {\n address token;\n address owner;\n uint256 value;\n uint256 deadline;\n uint8 v;\n bytes32 r;\n bytes32 s;\n }\n\n constructor() {}\n\n function mint(address user, uint256 amount, uint256, address stablecoin, address collateral) external {\n counterAngleMint += 1;\n IERC20(collateral).safeTransferFrom(msg.sender, address(this), amount);\n IERC20(stablecoin).safeTransfer(user, (amount * 10 ** 9) / multiplierMintBurn);\n }\n\n function setStETH(address _stETH) external {\n stETH = _stETH;\n }\n\n function burn(address user, uint256 amount, uint256, address stablecoin, address collateral) external {\n counterAngleBurn += 1;\n IERC20(stablecoin).safeTransferFrom(msg.sender, address(this), amount);\n IERC20(collateral).safeTransfer(user, (amount * multiplierMintBurn) / 10 ** 9);\n }\n\n function mixer(\n PermitType[] memory paramsPermit,\n ActionType[] memory actions,\n bytes[] calldata data\n ) public payable virtual {\n paramsPermit;\n counterMixer += 1;\n for (uint256 i; i < actions.length; ++i) {\n if (actions[i] == ActionType.transfer) {\n (address transferToken, uint256 amount) = abi.decode(data[i], (address, uint256));\n IERC20(transferToken).safeTransferFrom(msg.sender, address(this), amount);\n }\n }\n }\n\n function wrap(uint256 amount) external returns (uint256 amountOut) {\n amountOut = (amount * stETHMultiplier) / 10 ** 9;\n counterWrap += 1;\n IERC20(stETH).safeTransferFrom(msg.sender, address(this), amount);\n IERC20(outToken).safeTransfer(msg.sender, amountOut);\n }\n\n function oneInch(uint256 amountIn) external returns (uint256 amountOut) {\n counter1Inch += 1;\n amountOut = (amountOutUni * amountIn) / 10 ** 9;\n IERC20(inToken).safeTransferFrom(msg.sender, address(this), amountIn);\n IERC20(outToken).safeTransfer(msg.sender, amountOut);\n }\n\n function oneInchReverts() external {\n counter1Inch += 1;\n revert(\"wrong swap\");\n }\n\n function oneInchRevertsWithoutMessage() external {\n counter1Inch += 1;\n require(false);\n }\n\n function exactInput(ExactInputParams calldata params) external payable returns (uint256 amountOut) {\n counterUni += 1;\n amountOut = (params.amountIn * amountOutUni) / 10 ** 9;\n IERC20(inToken).safeTransferFrom(msg.sender, address(this), params.amountIn);\n IERC20(outToken).safeTransfer(params.recipient, amountOut);\n require(amountOut >= params.amountOutMinimum);\n }\n\n function setMultipliers(uint256 a, uint256 b) external {\n amountOutUni = a;\n multiplierMintBurn = b;\n }\n\n function setStETHMultiplier(uint256 value) external {\n stETHMultiplier = value;\n }\n\n function setInOut(address _collateral, address _stablecoin) external {\n inToken = _collateral;\n outToken = _stablecoin;\n }\n}\n" + }, + "contracts/mock/MockSidechainAgEUR.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\nimport \"../agToken/AgToken.sol\";\nimport \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\nimport \"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\";\n\n/// @title AgTokenSideChainMultiBridge\n/// @author Angle Labs, Inc.\n/// @notice Contract for Angle agTokens on other chains than Ethereum mainnet\n/// @dev This contract supports bridge tokens having a minting right on the stablecoin (also referred to as the canonical\n/// or the native token)\n/// @dev References:\n/// - FRAX implementation: https://polygonscan.com/address/0x45c32fA6DF82ead1e2EF74d17b76547EDdFaFF89#code\n/// - QiDAO implementation: https://snowtrace.io/address/0x5c49b268c9841AFF1Cc3B0a418ff5c3442eE3F3b#code\ncontract MockSidechainAgEUR is AgToken {\n using SafeERC20 for IERC20;\n\n /// @notice Base used for fee computation\n uint256 public constant BASE_PARAMS = 10 ** 9;\n\n // =============================== Bridging Data ===============================\n\n /// @notice Struct with some data about a specific bridge token\n struct BridgeDetails {\n // Limit on the balance of bridge token held by the contract: it is designed\n // to reduce the exposure of the system to hacks\n uint256 limit;\n // Limit on the hourly volume of token minted through this bridge\n // Technically the limit over a rolling hour is hourlyLimit x2 as hourly limit\n // is enforced only between x:00 and x+1:00\n uint256 hourlyLimit;\n // Fee taken for swapping in and out the token\n uint64 fee;\n // Whether the associated token is allowed or not\n bool allowed;\n // Whether swapping in and out from the associated token is paused or not\n bool paused;\n }\n\n /// @notice Maps a bridge token to data\n mapping(address => BridgeDetails) public bridges;\n /// @notice List of all bridge tokens\n address[] public bridgeTokensList;\n /// @notice Maps a bridge token to the associated hourly volume\n mapping(address => mapping(uint256 => uint256)) public usage;\n /// @notice Maps an address to whether it is exempt of fees for when it comes to swapping in and out\n mapping(address => uint256) public isFeeExempt;\n\n // ================================== Events ===================================\n\n event BridgeTokenAdded(address indexed bridgeToken, uint256 limit, uint256 hourlyLimit, uint64 fee, bool paused);\n event BridgeTokenToggled(address indexed bridgeToken, bool toggleStatus);\n event BridgeTokenRemoved(address indexed bridgeToken);\n event BridgeTokenFeeUpdated(address indexed bridgeToken, uint64 fee);\n event BridgeTokenLimitUpdated(address indexed bridgeToken, uint256 limit);\n event BridgeTokenHourlyLimitUpdated(address indexed bridgeToken, uint256 hourlyLimit);\n event HourlyLimitUpdated(uint256 hourlyLimit);\n event Recovered(address indexed token, address indexed to, uint256 amount);\n event FeeToggled(address indexed theAddress, uint256 toggleStatus);\n\n // =============================== Errors ================================\n\n error AssetStillControlledInReserves();\n error HourlyLimitExceeded();\n error InvalidToken();\n error NotGovernor();\n error NotGovernorOrGuardian();\n error TooBigAmount();\n error TooHighParameterValue();\n error ZeroAddress();\n\n // ============================= Constructor ===================================\n\n /// @notice Checks whether the `msg.sender` has the governor role or not\n modifier onlyGovernor() {\n if (!ITreasury(treasury).isGovernor(msg.sender)) revert NotGovernor();\n _;\n }\n\n /// @notice Checks whether the `msg.sender` has the governor role or the guardian role\n modifier onlyGovernorOrGuardian() {\n if (!ITreasury(treasury).isGovernorOrGuardian(msg.sender)) revert NotGovernorOrGuardian();\n _;\n }\n\n // ==================== External Permissionless Functions ======================\n\n /// @notice Returns the list of all supported bridge tokens\n /// @dev Helpful for UIs\n function allBridgeTokens() external view returns (address[] memory) {\n return bridgeTokensList;\n }\n\n /// @notice Returns the current volume for a bridge, for the current hour\n /// @param bridgeToken Bridge used to mint\n /// @dev Helpful for UIs\n function currentUsage(address bridgeToken) external view returns (uint256) {\n return usage[bridgeToken][block.timestamp / 3600];\n }\n\n /// @notice Mints the canonical token from a supported bridge token\n /// @param bridgeToken Bridge token to use to mint\n /// @param amount Amount of bridge tokens to send\n /// @param to Address to which the stablecoin should be sent\n /// @return Amount of the canonical stablecoin actually minted\n /// @dev Some fees may be taken by the protocol depending on the token used and on the address calling\n function swapIn(address bridgeToken, uint256 amount, address to) external returns (uint256) {\n BridgeDetails memory bridgeDetails = bridges[bridgeToken];\n if (!bridgeDetails.allowed || bridgeDetails.paused) revert InvalidToken();\n uint256 balance = IERC20(bridgeToken).balanceOf(address(this));\n if (balance + amount > bridgeDetails.limit) {\n // In case someone maliciously sends tokens to this contract\n // Or the limit changes\n if (bridgeDetails.limit > balance) amount = bridgeDetails.limit - balance;\n else {\n amount = 0;\n }\n }\n\n // Checking requirement on the hourly volume\n uint256 hour = block.timestamp / 3600;\n uint256 hourlyUsage = usage[bridgeToken][hour] + amount;\n if (hourlyUsage > bridgeDetails.hourlyLimit) {\n // Edge case when the hourly limit changes\n if (bridgeDetails.hourlyLimit > usage[bridgeToken][hour])\n amount = bridgeDetails.hourlyLimit - usage[bridgeToken][hour];\n else {\n amount = 0;\n }\n }\n usage[bridgeToken][hour] = usage[bridgeToken][hour] + amount;\n\n IERC20(bridgeToken).safeTransferFrom(msg.sender, address(this), amount);\n uint256 canonicalOut = amount;\n // Computing fees\n if (isFeeExempt[msg.sender] == 0) {\n canonicalOut -= (canonicalOut * bridgeDetails.fee) / BASE_PARAMS;\n }\n _mint(to, canonicalOut);\n return canonicalOut;\n }\n\n /// @notice Burns the canonical token in exchange for a bridge token\n /// @param bridgeToken Bridge token required\n /// @param amount Amount of canonical tokens to burn\n /// @param to Address to which the bridge token should be sent\n /// @return Amount of bridge tokens actually sent back\n /// @dev Some fees may be taken by the protocol depending on the token used and on the address calling\n function swapOut(address bridgeToken, uint256 amount, address to) external returns (uint256) {\n BridgeDetails memory bridgeDetails = bridges[bridgeToken];\n if (!bridgeDetails.allowed || bridgeDetails.paused) revert InvalidToken();\n\n _burn(msg.sender, amount);\n uint256 bridgeOut = amount;\n if (isFeeExempt[msg.sender] == 0) {\n bridgeOut -= (bridgeOut * bridgeDetails.fee) / BASE_PARAMS;\n }\n IERC20(bridgeToken).safeTransfer(to, bridgeOut);\n return bridgeOut;\n }\n\n // ======================= Governance Functions ================================\n\n /// @notice Adds support for a bridge token\n /// @param bridgeToken Bridge token to add: it should be a version of the stablecoin from another bridge\n /// @param limit Limit on the balance of bridge token this contract could hold\n /// @param hourlyLimit Limit on the hourly volume for this bridge\n /// @param paused Whether swapping for this token should be paused or not\n /// @param fee Fee taken upon swapping for or against this token\n function addBridgeToken(\n address bridgeToken,\n uint256 limit,\n uint256 hourlyLimit,\n uint64 fee,\n bool paused\n ) external onlyGovernor {\n if (bridges[bridgeToken].allowed || bridgeToken == address(0)) revert InvalidToken();\n if (fee > BASE_PARAMS) revert TooHighParameterValue();\n BridgeDetails memory _bridge;\n _bridge.limit = limit;\n _bridge.hourlyLimit = hourlyLimit;\n _bridge.paused = paused;\n _bridge.fee = fee;\n _bridge.allowed = true;\n bridges[bridgeToken] = _bridge;\n bridgeTokensList.push(bridgeToken);\n emit BridgeTokenAdded(bridgeToken, limit, hourlyLimit, fee, paused);\n }\n\n /// @notice Removes support for a token\n /// @param bridgeToken Address of the bridge token to remove support for\n function removeBridgeToken(address bridgeToken) external onlyGovernor {\n if (IERC20(bridgeToken).balanceOf(address(this)) != 0) revert AssetStillControlledInReserves();\n delete bridges[bridgeToken];\n // Deletion from `bridgeTokensList` loop\n uint256 bridgeTokensListLength = bridgeTokensList.length;\n for (uint256 i; i < bridgeTokensListLength - 1; ++i) {\n if (bridgeTokensList[i] == bridgeToken) {\n // Replace the `bridgeToken` to remove with the last of the list\n bridgeTokensList[i] = bridgeTokensList[bridgeTokensListLength - 1];\n break;\n }\n }\n // Remove last element in array\n bridgeTokensList.pop();\n emit BridgeTokenRemoved(bridgeToken);\n }\n\n /// @notice Recovers any ERC20 token\n /// @dev Can be used to withdraw bridge tokens for them to be de-bridged on mainnet\n function recoverERC20(address tokenAddress, address to, uint256 amountToRecover) external onlyGovernor {\n IERC20(tokenAddress).safeTransfer(to, amountToRecover);\n emit Recovered(tokenAddress, to, amountToRecover);\n }\n\n /// @notice Updates the `limit` amount for `bridgeToken`\n function setLimit(address bridgeToken, uint256 limit) external onlyGovernorOrGuardian {\n if (!bridges[bridgeToken].allowed) revert InvalidToken();\n bridges[bridgeToken].limit = limit;\n emit BridgeTokenLimitUpdated(bridgeToken, limit);\n }\n\n /// @notice Updates the `hourlyLimit` amount for `bridgeToken`\n function setHourlyLimit(address bridgeToken, uint256 hourlyLimit) external onlyGovernorOrGuardian {\n if (!bridges[bridgeToken].allowed) revert InvalidToken();\n bridges[bridgeToken].hourlyLimit = hourlyLimit;\n emit BridgeTokenHourlyLimitUpdated(bridgeToken, hourlyLimit);\n }\n\n /// @notice Updates the `fee` value for `bridgeToken`\n function setSwapFee(address bridgeToken, uint64 fee) external onlyGovernorOrGuardian {\n if (!bridges[bridgeToken].allowed) revert InvalidToken();\n if (fee > BASE_PARAMS) revert TooHighParameterValue();\n bridges[bridgeToken].fee = fee;\n emit BridgeTokenFeeUpdated(bridgeToken, fee);\n }\n\n /// @notice Pauses or unpauses swapping in and out for a token\n function toggleBridge(address bridgeToken) external onlyGovernorOrGuardian {\n if (!bridges[bridgeToken].allowed) revert InvalidToken();\n bool pausedStatus = bridges[bridgeToken].paused;\n bridges[bridgeToken].paused = !pausedStatus;\n emit BridgeTokenToggled(bridgeToken, !pausedStatus);\n }\n\n /// @notice Toggles fees for the address `theAddress`\n function toggleFeesForAddress(address theAddress) external onlyGovernorOrGuardian {\n uint256 feeExemptStatus = 1 - isFeeExempt[theAddress];\n isFeeExempt[theAddress] = feeExemptStatus;\n emit FeeToggled(theAddress, feeExemptStatus);\n }\n}\n" + }, + "contracts/mock/MockStableMaster.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\nimport \"../interfaces/IAgToken.sol\";\nimport \"./MockToken.sol\";\nimport \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\nimport \"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\";\nimport { SLPData, MintBurnData } from \"../interfaces/coreModule/IStableMaster.sol\";\n\n// All the details about a collateral that are going to be stored in `StableMaster`\nstruct Collateral {\n // Interface for the token accepted by the underlying `PoolManager` contract\n IERC20 token;\n // Reference to the `SanToken` for the pool\n MockToken sanToken;\n // Reference to the `PerpetualManager` for the pool\n address perpetualManager;\n // Adress of the oracle for the change rate between\n // collateral and the corresponding stablecoin\n address oracle;\n // Amount of collateral in the reserves that comes from users\n // converted in stablecoin value. Updated at minting and burning.\n // A `stocksUsers` of 10 for a collateral type means that overall the balance of the collateral from users\n // that minted/burnt stablecoins using this collateral is worth 10 of stablecoins\n uint256 stocksUsers;\n // Exchange rate between sanToken and collateral\n uint256 sanRate;\n // Base used in the collateral implementation (ERC20 decimal)\n uint256 collatBase;\n // Parameters for SLPs and update of the `sanRate`\n SLPData slpData;\n // All the fees parameters\n MintBurnData feeData;\n}\n\ncontract MockStableMaster {\n mapping(address => uint256) public poolManagerMap;\n\n constructor() {}\n\n function updateStocksUsers(uint256 amount, address poolManager) external {\n poolManagerMap[poolManager] += amount;\n }\n\n function burnSelf(IAgToken agToken, uint256 amount, address burner) external {\n agToken.burnSelf(amount, burner);\n }\n\n function burnFrom(IAgToken agToken, uint256 amount, address burner, address sender) external {\n agToken.burnFrom(amount, burner, sender);\n }\n\n function mint(IAgToken agToken, address account, uint256 amount) external {\n agToken.mint(account, amount);\n }\n}\n\ncontract MockStableMasterSanWrapper is MockStableMaster {\n using SafeERC20 for IERC20;\n\n /// @notice Maps a `PoolManager` contract handling a collateral for this stablecoin to the properties of the struct above\n mapping(address => Collateral) public collateralMap;\n\n constructor() MockStableMaster() {}\n\n uint256 internal constant _BASE_TOKENS = 10 ** 18;\n uint256 internal constant _BASE_PARAMS = 10 ** 9;\n IERC20 public token;\n\n function deposit(uint256 assets, address receiver, address poolManager) external {\n token.safeTransferFrom(msg.sender, address(this), assets);\n Collateral storage col = collateralMap[poolManager];\n _updateSanRate(col);\n uint256 amount = (assets * _BASE_TOKENS) / col.sanRate;\n col.sanToken.mint(receiver, amount);\n }\n\n function withdraw(uint256 assets, address sender, address receiver, address poolManager) external {\n Collateral storage col = collateralMap[poolManager];\n _updateSanRate(col);\n col.sanToken.burn(sender, assets);\n // Computing the amount of collateral to give back to the SLP depending on slippage and on the `sanRate`\n uint256 redeemInC = (assets * (_BASE_PARAMS - col.slpData.slippage) * col.sanRate) /\n (_BASE_TOKENS * _BASE_PARAMS);\n token.safeTransfer(receiver, redeemInC);\n }\n\n function setPoolManagerToken(address, address token_) external {\n token = MockToken(token_);\n }\n\n function setPoolManagerSanToken(address poolManager, address sanToken_) external {\n Collateral storage col = collateralMap[poolManager];\n col.sanToken = MockToken(sanToken_);\n }\n\n function setSanRate(address poolManager, uint256 sanRate_) external {\n Collateral storage col = collateralMap[poolManager];\n col.sanRate = sanRate_;\n }\n\n function _updateSanRate(Collateral storage col) internal {\n uint256 _lockedInterests = col.slpData.lockedInterests;\n // Checking if the `sanRate` has been updated in the current block using past block fees\n // This is a way to prevent flash loans attacks when an important amount of fees are going to be distributed\n // in a block: fees are stored but will just be distributed to SLPs who will be here during next blocks\n if (block.timestamp != col.slpData.lastBlockUpdated && _lockedInterests > 0) {\n uint256 sanMint = col.sanToken.totalSupply();\n if (sanMint != 0) {\n // Checking if the update is too important and should be made in multiple blocks\n if (_lockedInterests > col.slpData.maxInterestsDistributed) {\n // `sanRate` is expressed in `BASE_TOKENS`\n col.sanRate += (col.slpData.maxInterestsDistributed * 10 ** 18) / sanMint;\n _lockedInterests -= col.slpData.maxInterestsDistributed;\n } else {\n col.sanRate += (_lockedInterests * 10 ** 18) / sanMint;\n _lockedInterests = 0;\n }\n } else {\n _lockedInterests = 0;\n }\n }\n col.slpData.lockedInterests = _lockedInterests;\n col.slpData.lastBlockUpdated = block.timestamp;\n }\n\n // copy paste from the deployed contract\n function estimateSanRate(address poolManager) external view returns (uint256 sanRate, uint64 slippage) {\n Collateral memory col = collateralMap[poolManager];\n uint256 _lockedInterests = col.slpData.lockedInterests;\n // Checking if the `sanRate` has been updated in the current block using past block fees\n // This is a way to prevent flash loans attacks when an important amount of fees are going to be distributed\n // in a block: fees are stored but will just be distributed to SLPs who will be here during next blocks\n if (block.timestamp != col.slpData.lastBlockUpdated && _lockedInterests > 0) {\n uint256 sanMint = col.sanToken.totalSupply();\n if (sanMint != 0) {\n // Checking if the update is too important and should be made in multiple blocks\n if (_lockedInterests > col.slpData.maxInterestsDistributed) {\n // `sanRate` is expressed in `BASE_TOKENS`\n col.sanRate += (col.slpData.maxInterestsDistributed * 10 ** 18) / sanMint;\n _lockedInterests -= col.slpData.maxInterestsDistributed;\n } else {\n col.sanRate += (_lockedInterests * 10 ** 18) / sanMint;\n _lockedInterests = 0;\n }\n } else {\n _lockedInterests = 0;\n }\n }\n return (col.sanRate, col.slpData.slippage);\n }\n\n function setSLPData(\n address poolManager,\n uint256 lockedInterests,\n uint256 maxInterestsDistributed,\n uint64 slippage\n ) external {\n Collateral storage col = collateralMap[poolManager];\n col.slpData.lockedInterests = lockedInterests;\n col.slpData.maxInterestsDistributed = maxInterestsDistributed;\n col.slpData.slippage = slippage;\n }\n}\n" + }, + "contracts/mock/MockSwapper.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\nimport \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\nimport \"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\";\n\nimport \"../interfaces/ISwapper.sol\";\n\ncontract MockSwapper is ISwapper {\n bytes32 public constant CALLBACK_SUCCESS = keccak256(\"ERC3156FlashBorrower.onFlashLoan\");\n\n uint256 public counter;\n\n constructor() {}\n\n function swap(IERC20, IERC20, address, uint256, uint256, bytes calldata data) external {\n counter += 1;\n data;\n }\n}\n\ncontract MockSwapperWithSwap is ISwapper {\n using SafeERC20 for IERC20;\n bytes32 public constant CALLBACK_SUCCESS = keccak256(\"ERC3156FlashBorrower.onFlashLoan\");\n\n uint256 public counter;\n\n constructor() {}\n\n function swap(\n IERC20,\n IERC20 outToken,\n address outTokenRecipient,\n uint256 outTokenOwed,\n uint256,\n bytes calldata data\n ) external {\n counter += 1;\n outToken.safeTransfer(outTokenRecipient, outTokenOwed);\n\n data;\n }\n}\n" + }, + "contracts/mock/MockSwapperSidechain.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\nimport \"../swapper/Swapper.sol\";\n\n/// @title MockSwapperSidechain\n/// @author Angle Labs, Inc.\ncontract MockSwapperSidechain is Swapper {\n error NotImplemented();\n\n /// @notice Constructor of the contract\n /// @param _core Core address\n /// @param _uniV3Router UniswapV3 Router address\n /// @param _oneInch 1Inch Router address\n /// @param _angleRouter AngleRouter contract address\n constructor(\n ICoreBorrow _core,\n IUniswapV3Router _uniV3Router,\n address _oneInch,\n IAngleRouterSidechain _angleRouter\n ) Swapper(_core, _uniV3Router, _oneInch, _angleRouter) {}\n\n function _swapLeverage(bytes memory) internal pure override returns (uint256) {\n revert NotImplemented();\n }\n}\n" + }, + "contracts/mock/MockToken.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.7;\n\nimport \"@openzeppelin/contracts/token/ERC20/ERC20.sol\";\n\ncontract MockToken is ERC20 {\n event Minting(address indexed _to, address indexed _minter, uint256 _amount);\n\n event Burning(address indexed _from, address indexed _burner, uint256 _amount);\n\n uint8 internal _decimal;\n mapping(address => bool) public minters;\n address public treasury;\n\n constructor(string memory name_, string memory symbol_, uint8 decimal_) ERC20(name_, symbol_) {\n _decimal = decimal_;\n }\n\n function decimals() public view override returns (uint8) {\n return _decimal;\n }\n\n function mint(address account, uint256 amount) external {\n _mint(account, amount);\n emit Minting(account, msg.sender, amount);\n }\n\n function burn(address account, uint256 amount) public {\n _burn(account, amount);\n emit Burning(account, msg.sender, amount);\n }\n\n function setAllowance(address from, address to) public {\n _approve(from, to, type(uint256).max);\n }\n\n function burnSelf(uint256 amount, address account) public {\n _burn(account, amount);\n emit Burning(account, msg.sender, amount);\n }\n\n function addMinter(address minter) public {\n minters[minter] = true;\n }\n\n function removeMinter(address minter) public {\n minters[minter] = false;\n }\n\n function setTreasury(address _treasury) public {\n treasury = _treasury;\n }\n}\n" + }, + "contracts/mock/MockTokenPermit.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.7;\n\nimport \"@openzeppelin/contracts/token/ERC20/extensions/draft-ERC20Permit.sol\";\nimport \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\nimport \"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\";\n\ncontract MockTokenPermit is ERC20Permit {\n using SafeERC20 for IERC20;\n event Minting(address indexed _to, address indexed _minter, uint256 _amount);\n\n event Burning(address indexed _from, address indexed _burner, uint256 _amount);\n\n uint8 internal _decimal;\n mapping(address => bool) public minters;\n address public treasury;\n uint256 public fees;\n\n bool public reverts;\n\n constructor(string memory name_, string memory symbol_, uint8 decimal_) ERC20Permit(name_) ERC20(name_, symbol_) {\n _decimal = decimal_;\n }\n\n function decimals() public view override returns (uint8) {\n return _decimal;\n }\n\n function mint(address account, uint256 amount) external {\n _mint(account, amount);\n emit Minting(account, msg.sender, amount);\n }\n\n function burn(address account, uint256 amount) public {\n _burn(account, amount);\n emit Burning(account, msg.sender, amount);\n }\n\n function setAllowance(address from, address to) public {\n _approve(from, to, type(uint256).max);\n }\n\n function burnSelf(uint256 amount, address account) public {\n _burn(account, amount);\n emit Burning(account, msg.sender, amount);\n }\n\n function addMinter(address minter) public {\n minters[minter] = true;\n }\n\n function removeMinter(address minter) public {\n minters[minter] = false;\n }\n\n function setTreasury(address _treasury) public {\n treasury = _treasury;\n }\n\n function setFees(uint256 _fees) public {\n fees = _fees;\n }\n\n function recoverERC20(IERC20 token, address to, uint256 amount) external {\n token.safeTransfer(to, amount);\n }\n\n function swapIn(address bridgeToken, uint256 amount, address to) external returns (uint256) {\n require(!reverts);\n\n IERC20(bridgeToken).safeTransferFrom(msg.sender, address(this), amount);\n uint256 canonicalOut = amount;\n canonicalOut -= (canonicalOut * fees) / 10 ** 9;\n _mint(to, canonicalOut);\n return canonicalOut;\n }\n\n function swapOut(address bridgeToken, uint256 amount, address to) external returns (uint256) {\n require(!reverts);\n _burn(msg.sender, amount);\n uint256 bridgeOut = amount;\n bridgeOut -= (bridgeOut * fees) / 10 ** 9;\n IERC20(bridgeToken).safeTransfer(to, bridgeOut);\n return bridgeOut;\n }\n}\n" + }, + "contracts/mock/MockTreasury.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\nimport \"../interfaces/ITreasury.sol\";\nimport \"../interfaces/IFlashAngle.sol\";\nimport \"../interfaces/IVaultManager.sol\";\n\ncontract MockTreasury is ITreasury {\n IAgToken public override stablecoin;\n address public governor;\n address public guardian;\n address public vaultManager1;\n address public vaultManager2;\n address public flashLoanModule;\n address[] public vaultManagerList;\n\n constructor(\n IAgToken _stablecoin,\n address _governor,\n address _guardian,\n address _vaultManager1,\n address _vaultManager2,\n address _flashLoanModule\n ) {\n stablecoin = _stablecoin;\n governor = _governor;\n guardian = _guardian;\n vaultManager1 = _vaultManager1;\n vaultManager2 = _vaultManager2;\n flashLoanModule = _flashLoanModule;\n }\n\n function isGovernor(address admin) external view override returns (bool) {\n return (admin == governor);\n }\n\n function isGovernorOrGuardian(address admin) external view override returns (bool) {\n return (admin == governor || admin == guardian);\n }\n\n function isVaultManager(address _vaultManager) external view override returns (bool) {\n return (_vaultManager == vaultManager1 || _vaultManager == vaultManager2);\n }\n\n function setStablecoin(IAgToken _stablecoin) external {\n stablecoin = _stablecoin;\n }\n\n function setFlashLoanModule(address _flashLoanModule) external override {\n flashLoanModule = _flashLoanModule;\n }\n\n function setGovernor(address _governor) external {\n governor = _governor;\n }\n\n function setVaultManager(address _vaultManager) external {\n vaultManager1 = _vaultManager;\n }\n\n function setVaultManager2(address _vaultManager) external {\n vaultManager2 = _vaultManager;\n }\n\n function setTreasury(address _agTokenOrVaultManager, address _treasury) external {\n IAgToken(_agTokenOrVaultManager).setTreasury(_treasury);\n }\n\n function addMinter(IAgToken _agToken, address _minter) external {\n _agToken.addMinter(_minter);\n }\n\n function removeMinter(IAgToken _agToken, address _minter) external {\n _agToken.removeMinter(_minter);\n }\n\n function accrueInterestToTreasury(IFlashAngle flashAngle) external returns (uint256 balance) {\n balance = flashAngle.accrueInterestToTreasury(stablecoin);\n }\n\n function accrueInterestToTreasuryVaultManager(IVaultManager _vaultManager) external returns (uint256, uint256) {\n return _vaultManager.accrueInterestToTreasury();\n }\n}\n" + }, + "contracts/mock/MockUniswapV3Pool.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.7;\n\ncontract MockUniswapV3Pool {\n address public token0;\n address public token1;\n uint32 public constant EPOCH_DURATION = 24 * 3600 * 7;\n\n function setToken(address token, uint256 who) external {\n if (who == 0) token0 = token;\n else token1 = token;\n }\n\n function round(uint256 amount) external pure returns (uint256) {\n return (amount / EPOCH_DURATION) * EPOCH_DURATION;\n }\n}\n" + }, + "contracts/mock/MockVaultManager.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\nimport \"../interfaces/IVaultManager.sol\";\nimport \"../interfaces/ITreasury.sol\";\nimport \"@openzeppelin/contracts/token/ERC20/ERC20.sol\";\n\ncontract MockVaultManager {\n ITreasury public treasury;\n mapping(uint256 => Vault) public vaultData;\n mapping(uint256 => address) public ownerOf;\n uint256 public surplus;\n uint256 public badDebt;\n IAgToken public token;\n address public oracle = address(this);\n\n address public governor;\n address public collateral;\n address public stablecoin;\n uint256 public oracleValue;\n uint256 public interestAccumulator;\n uint256 public collateralFactor;\n uint256 public totalNormalizedDebt;\n\n constructor(address _treasury) {\n treasury = ITreasury(_treasury);\n }\n\n function accrueInterestToTreasury() external returns (uint256, uint256) {\n // Avoid the function to be view\n if (surplus >= badDebt) {\n token.mint(msg.sender, surplus - badDebt);\n }\n return (surplus, badDebt);\n }\n\n function read() external view returns (uint256) {\n return oracleValue;\n }\n\n function setParams(\n address _governor,\n address _collateral,\n address _stablecoin,\n uint256 _oracleValue,\n uint256 _interestAccumulator,\n uint256 _collateralFactor,\n uint256 _totalNormalizedDebt\n ) external {\n governor = _governor;\n collateral = _collateral;\n stablecoin = _stablecoin;\n interestAccumulator = _interestAccumulator;\n collateralFactor = _collateralFactor;\n totalNormalizedDebt = _totalNormalizedDebt;\n oracleValue = _oracleValue;\n }\n\n function setOwner(uint256 vaultID, address owner) external virtual {\n ownerOf[vaultID] = owner;\n }\n\n function setVaultData(uint256 normalizedDebt, uint256 collateralAmount, uint256 vaultID) external {\n vaultData[vaultID].normalizedDebt = normalizedDebt;\n vaultData[vaultID].collateralAmount = collateralAmount;\n }\n\n function isGovernor(address admin) external view returns (bool) {\n return admin == governor;\n }\n\n function setSurplusBadDebt(uint256 _surplus, uint256 _badDebt, IAgToken _token) external {\n surplus = _surplus;\n badDebt = _badDebt;\n token = _token;\n }\n\n function getDebtOut(uint256 vaultID, uint256 amountStablecoins, uint256 senderBorrowFee) external {}\n\n function setTreasury(address _treasury) external {\n treasury = ITreasury(_treasury);\n }\n\n function getVaultDebt(uint256 vaultID) external view returns (uint256) {\n vaultID;\n token;\n return 0;\n }\n\n function createVault(address toVault) external view returns (uint256) {\n toVault;\n token;\n return 0;\n }\n}\n\ncontract MockVaultManagerListing is MockVaultManager {\n // @notice Mapping from owner address to all his vaults\n mapping(address => uint256[]) internal _ownerListVaults;\n\n constructor(address _treasury) MockVaultManager(_treasury) {}\n\n function getUserVaults(address owner) public view returns (uint256[] memory) {\n return _ownerListVaults[owner];\n }\n\n function getUserCollateral(address owner) public view returns (uint256 totalCollateral) {\n uint256[] memory vaultList = _ownerListVaults[owner];\n uint256 vaultListLength = vaultList.length;\n for (uint256 k; k < vaultListLength; ++k) {\n totalCollateral += vaultData[vaultList[k]].collateralAmount;\n }\n return totalCollateral;\n }\n\n function setOwner(uint256 vaultID, address owner) external override {\n if (ownerOf[vaultID] != address(0)) _removeVaultFromList(ownerOf[vaultID], vaultID);\n _ownerListVaults[owner].push(vaultID);\n ownerOf[vaultID] = owner;\n }\n\n /// @notice Remove `vaultID` from `user` stroed vault list\n /// @param user Address to look out for the vault list\n /// @param vaultID VaultId to remove from the list\n /// @dev The vault is necessarily in the list\n function _removeVaultFromList(address user, uint256 vaultID) internal {\n uint256[] storage vaultList = _ownerListVaults[user];\n uint256 vaultListLength = vaultList.length;\n for (uint256 i; i < vaultListLength - 1; ++i) {\n if (vaultList[i] == vaultID) {\n vaultList[i] = vaultList[vaultListLength - 1];\n break;\n }\n }\n vaultList.pop();\n }\n}\n" + }, + "contracts/mock/MockVeBoostProxy.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\nimport \"../interfaces/governance/IVeBoostProxy.sol\";\n\ncontract MockVeBoostProxy is IVeBoostProxy {\n //solhint-disable-next-line\n mapping(address => uint256) public adjusted_balance_of;\n\n constructor() {}\n\n function setBalance(address concerned, uint256 balance) external {\n adjusted_balance_of[concerned] = balance;\n }\n}\n" + }, + "contracts/oracle/BaseOracleChainlinkMulti.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\n/*\n * █ \n ***** ▓▓▓ \n * ▓▓▓▓▓▓▓ \n * ///. ▓▓▓▓▓▓▓▓▓▓▓▓▓ \n ***** //////// ▓▓▓▓▓▓▓ \n * ///////////// ▓▓▓ \n ▓▓ ////////////////// █ ▓▓ \n ▓▓ ▓▓ /////////////////////// ▓▓ ▓▓ \n ▓▓ ▓▓ //////////////////////////// ▓▓ ▓▓ \n ▓▓ ▓▓ /////////▓▓▓///////▓▓▓///////// ▓▓ ▓▓ \n ▓▓ ,////////////////////////////////////// ▓▓ ▓▓ \n ▓▓ ////////////////////////////////////////// ▓▓ \n ▓▓ //////////////////////▓▓▓▓///////////////////// \n ,//////////////////////////////////////////////////// \n .////////////////////////////////////////////////////////// \n .//////////////////////////██.,//////////////////////////█ \n .//////////////////////████..,./////////////////////██ \n ...////////////////███████.....,.////////////////███ \n ,.,////////////████████ ........,///////////████ \n .,.,//////█████████ ,.......///////████ \n ,..//████████ ........./████ \n ..,██████ .....,███ \n .██ ,.,█ \n \n \n \n ▓▓ ▓▓▓▓▓▓▓▓▓▓ ▓▓▓▓▓▓▓▓▓▓ ▓▓ ▓▓▓▓▓▓▓▓▓▓ \n ▓▓▓▓▓▓ ▓▓▓ ▓▓▓ ▓▓▓ ▓▓ ▓▓ ▓▓▓▓ \n ▓▓▓ ▓▓▓ ▓▓▓ ▓▓▓ ▓▓▓ ▓▓▓ ▓▓ ▓▓▓▓▓ \n ▓▓▓ ▓▓ ▓▓▓ ▓▓▓ ▓▓▓▓▓▓▓▓▓▓ ▓▓▓▓▓▓▓▓▓▓ ▓▓▓▓▓▓▓▓▓▓ \n*/\n\npragma solidity ^0.8.12;\n\nimport \"@chainlink/contracts/src/v0.8/interfaces/AggregatorV3Interface.sol\";\n\nimport \"../interfaces/IOracle.sol\";\nimport \"../interfaces/ITreasury.sol\";\n\n/// @title BaseOracleChainlinkMulti\n/// @author Angle Labs, Inc.\n/// @notice Base Contract to be overriden by all contracts of the protocol\n/// @dev This base contract concerns an oracle that uses Chainlink with multiple pools to read from\n/// @dev All gas-efficient implementation of the `OracleChainlinkMulti` contract should inherit from this\nabstract contract BaseOracleChainlinkMulti is IOracle {\n // ========================= Parameters and References =========================\n\n /// @inheritdoc IOracle\n ITreasury public override treasury;\n /// @notice Represent the maximum amount of time (in seconds) between each Chainlink update\n /// before the price feed is considered stale\n uint32 public stalePeriod;\n\n // =================================== Event ===================================\n\n event StalePeriodUpdated(uint32 _stalePeriod);\n\n // =================================== Errors ===================================\n\n error InvalidChainlinkRate();\n error NotGovernorOrGuardian();\n error NotVaultManagerOrGovernor();\n\n /// @notice Constructor for an oracle using Chainlink with multiple pools to read from\n /// @param _stalePeriod Minimum feed update frequency for the oracle to not revert\n /// @param _treasury Treasury associated to the VaultManager which reads from this feed\n constructor(uint32 _stalePeriod, address _treasury) {\n stalePeriod = _stalePeriod;\n treasury = ITreasury(_treasury);\n }\n\n // ============================= Reading Oracles ===============================\n\n /// @inheritdoc IOracle\n function read() external view virtual override returns (uint256 quoteAmount);\n\n /// @inheritdoc IOracle\n function circuitChainlink() public view virtual returns (AggregatorV3Interface[] memory);\n\n /// @notice Reads a Chainlink feed using a quote amount and converts the quote amount to\n /// the out-currency\n /// @param quoteAmount The amount for which to compute the price expressed with base decimal\n /// @param feed Chainlink feed to query\n /// @param multiplied Whether the ratio outputted by Chainlink should be multiplied or divided\n /// to the `quoteAmount`\n /// @param decimals Number of decimals of the corresponding Chainlink pair\n /// @return The `quoteAmount` converted in out-currency\n function _readChainlinkFeed(\n uint256 quoteAmount,\n AggregatorV3Interface feed,\n uint8 multiplied,\n uint256 decimals\n ) internal view returns (uint256) {\n (uint80 roundId, int256 ratio, , uint256 updatedAt, uint80 answeredInRound) = feed.latestRoundData();\n if (ratio <= 0 || roundId > answeredInRound || block.timestamp - updatedAt > stalePeriod)\n revert InvalidChainlinkRate();\n uint256 castedRatio = uint256(ratio);\n // Checking whether we should multiply or divide by the ratio computed\n if (multiplied == 1) return (quoteAmount * castedRatio) / (10 ** decimals);\n else return (quoteAmount * (10 ** decimals)) / castedRatio;\n }\n\n // ======================= Governance Related Functions ========================\n\n /// @notice Changes the stale period\n /// @param _stalePeriod New stale period (in seconds)\n function changeStalePeriod(uint32 _stalePeriod) external {\n if (!treasury.isGovernorOrGuardian(msg.sender)) revert NotGovernorOrGuardian();\n stalePeriod = _stalePeriod;\n emit StalePeriodUpdated(_stalePeriod);\n }\n\n /// @inheritdoc IOracle\n function setTreasury(address _treasury) external override {\n if (!treasury.isVaultManager(msg.sender) && !treasury.isGovernor(msg.sender))\n revert NotVaultManagerOrGovernor();\n treasury = ITreasury(_treasury);\n }\n}\n" + }, + "contracts/oracle/BaseOracleChainlinkMultiTwoFeeds.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\nimport \"@chainlink/contracts/src/v0.8/interfaces/AggregatorV3Interface.sol\";\n\nimport \"./BaseOracleChainlinkMulti.sol\";\n\n/// @title BaseOracleChainlinkMultiTwoFeeds\n/// @author Angle Labs, Inc.\n/// @notice Base contract for an oracle that reads into two Chainlink feeds (including an EUR/USD feed) which both have\n/// 8 decimals\nabstract contract BaseOracleChainlinkMultiTwoFeeds is BaseOracleChainlinkMulti {\n constructor(uint32 _stalePeriod, address _treasury) BaseOracleChainlinkMulti(_stalePeriod, _treasury) {}\n\n /// @notice Returns the quote amount of the oracle contract\n function _getQuoteAmount() internal view virtual returns (uint256) {\n return 10 ** 18;\n }\n\n /// @inheritdoc IOracle\n function read() external view virtual override returns (uint256 quoteAmount) {\n quoteAmount = _getQuoteAmount();\n AggregatorV3Interface[] memory _circuitChainlink = circuitChainlink();\n uint8[2] memory circuitChainIsMultiplied = [1, 0];\n uint8[2] memory chainlinkDecimals = [8, 8];\n uint256 circuitLength = _circuitChainlink.length;\n for (uint256 i; i < circuitLength; ++i) {\n quoteAmount = _readChainlinkFeed(\n quoteAmount,\n _circuitChainlink[i],\n circuitChainIsMultiplied[i],\n chainlinkDecimals[i]\n );\n }\n }\n}\n" + }, + "contracts/oracle/BaseOracleChainlinkOneFeed.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\nimport \"@chainlink/contracts/src/v0.8/interfaces/AggregatorV3Interface.sol\";\n\nimport \"./BaseOracleChainlinkMulti.sol\";\n\n/// @title BaseOracleChainlinkOneFeed\n/// @author Angle Labs, Inc.\n/// @notice Base contract for an oracle that reads into one Chainlink feeds with 8 decimals\nabstract contract BaseOracleChainlinkOneFeed is BaseOracleChainlinkMulti {\n constructor(uint32 _stalePeriod, address _treasury) BaseOracleChainlinkMulti(_stalePeriod, _treasury) {}\n\n /// @notice Returns the quote amount of the oracle contract\n function _getQuoteAmount() internal view virtual returns (uint256) {\n return 10 ** 18;\n }\n\n /// @inheritdoc IOracle\n function read() external view virtual override returns (uint256 quoteAmount) {\n AggregatorV3Interface[] memory _circuitChainlink = circuitChainlink();\n quoteAmount = _readChainlinkFeed(_getQuoteAmount(), _circuitChainlink[0], 1, 8);\n }\n}\n" + }, + "contracts/oracle/implementations/arbitrum/EUR/OracleBTCEURChainlinkArbitrum.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\nimport \"@chainlink/contracts/src/v0.8/interfaces/AggregatorV3Interface.sol\";\n\nimport \"../../../BaseOracleChainlinkMultiTwoFeeds.sol\";\n\n/// @title OracleBTCEURChainlinkArbitrum\n/// @author Angle Labs, Inc.\n/// @notice Gives the price of BTC in Euro in base 18\n/// @dev This contract is built to be deployed on Arbitrum\ncontract OracleBTCEURChainlinkArbitrum is BaseOracleChainlinkMultiTwoFeeds {\n string public constant DESCRIPTION = \"BTC/EUR Oracle\";\n\n constructor(uint32 _stalePeriod, address _treasury) BaseOracleChainlinkMultiTwoFeeds(_stalePeriod, _treasury) {}\n\n /// @inheritdoc IOracle\n function circuitChainlink() public pure override returns (AggregatorV3Interface[] memory) {\n AggregatorV3Interface[] memory _circuitChainlink = new AggregatorV3Interface[](2);\n // Oracle BTC/USD\n _circuitChainlink[0] = AggregatorV3Interface(0x6ce185860a4963106506C203335A2910413708e9);\n // Oracle EUR/USD\n _circuitChainlink[1] = AggregatorV3Interface(0xA14d53bC1F1c0F31B4aA3BD109344E5009051a84);\n return _circuitChainlink;\n }\n}\n" + }, + "contracts/oracle/implementations/arbitrum/EUR/OracleETHEURChainlinkArbitrum.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\nimport \"@chainlink/contracts/src/v0.8/interfaces/AggregatorV3Interface.sol\";\n\nimport \"../../../BaseOracleChainlinkMultiTwoFeeds.sol\";\n\n/// @title OracleETHEURChainlinkArbitrum\n/// @author Angle Labs, Inc.\n/// @notice Gives the price of ETH in Euro in base 18\n/// @dev This contract is built to be deployed on Arbitrum\ncontract OracleETHEURChainlinkArbitrum is BaseOracleChainlinkMultiTwoFeeds {\n string public constant DESCRIPTION = \"ETH/EUR Oracle\";\n\n constructor(uint32 _stalePeriod, address _treasury) BaseOracleChainlinkMultiTwoFeeds(_stalePeriod, _treasury) {}\n\n /// @inheritdoc IOracle\n function circuitChainlink() public pure override returns (AggregatorV3Interface[] memory) {\n AggregatorV3Interface[] memory _circuitChainlink = new AggregatorV3Interface[](2);\n // Oracle ETH/USD\n _circuitChainlink[0] = AggregatorV3Interface(0x639Fe6ab55C921f74e7fac1ee960C0B6293ba612);\n // Oracle EUR/USD\n _circuitChainlink[1] = AggregatorV3Interface(0xA14d53bC1F1c0F31B4aA3BD109344E5009051a84);\n return _circuitChainlink;\n }\n}\n" + }, + "contracts/oracle/implementations/arbitrum/EUR/OracleUSDCEURChainlinkArbitrum.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\nimport \"@chainlink/contracts/src/v0.8/interfaces/AggregatorV3Interface.sol\";\n\nimport \"../../../BaseOracleChainlinkMultiTwoFeeds.sol\";\n\n/// @title OracleUSDCEURChainlinkArbitrum\n/// @author Angle Labs, Inc.\n/// @notice Gives the price of USDC in Euro in base 18\n/// @dev This contract is built to be deployed on Arbitrum\ncontract OracleUSDCEURChainlinkArbitrum is BaseOracleChainlinkMultiTwoFeeds {\n string public constant DESCRIPTION = \"USDC/EUR Oracle\";\n\n constructor(uint32 _stalePeriod, address _treasury) BaseOracleChainlinkMultiTwoFeeds(_stalePeriod, _treasury) {}\n\n /// @inheritdoc IOracle\n function circuitChainlink() public pure override returns (AggregatorV3Interface[] memory) {\n AggregatorV3Interface[] memory _circuitChainlink = new AggregatorV3Interface[](2);\n // Oracle ETH/USD\n _circuitChainlink[0] = AggregatorV3Interface(0x50834F3163758fcC1Df9973b6e91f0F0F0434aD3);\n // Oracle EUR/USD\n _circuitChainlink[1] = AggregatorV3Interface(0xA14d53bC1F1c0F31B4aA3BD109344E5009051a84);\n return _circuitChainlink;\n }\n}\n" + }, + "contracts/oracle/implementations/avalanche/EUR/OracleAVAXEURChainlinkAvalanche.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\nimport \"@chainlink/contracts/src/v0.8/interfaces/AggregatorV3Interface.sol\";\n\nimport \"../../../BaseOracleChainlinkMultiTwoFeeds.sol\";\n\n/// @title OracleAVAXEURChainlinkAvalanche\n/// @author Angle Labs, Inc.\n/// @notice Gives the price of AVAX in Euro in base 18\n/// @dev This contract is built to be deployed on Avalanche\ncontract OracleAVAXEURChainlinkAvalanche is BaseOracleChainlinkMultiTwoFeeds {\n string public constant DESCRIPTION = \"AVAX/EUR Oracle\";\n\n constructor(uint32 _stalePeriod, address _treasury) BaseOracleChainlinkMultiTwoFeeds(_stalePeriod, _treasury) {}\n\n /// @inheritdoc IOracle\n function circuitChainlink() public pure override returns (AggregatorV3Interface[] memory) {\n AggregatorV3Interface[] memory _circuitChainlink = new AggregatorV3Interface[](2);\n // Oracle AVAX/USD\n _circuitChainlink[0] = AggregatorV3Interface(0x0A77230d17318075983913bC2145DB16C7366156);\n // Oracle EUR/USD\n _circuitChainlink[1] = AggregatorV3Interface(0x192f2DBA961Bb0277520C082d6bfa87D5961333E);\n return _circuitChainlink;\n }\n}\n" + }, + "contracts/oracle/implementations/avalanche/EUR/OracleUSDCEURChainlinkAvalanche.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\nimport \"@chainlink/contracts/src/v0.8/interfaces/AggregatorV3Interface.sol\";\n\nimport \"../../../BaseOracleChainlinkMultiTwoFeeds.sol\";\n\n/// @title OracleUSDCEURChainlinkAvalanche\n/// @author Angle Labs, Inc.\n/// @notice Gives the price of USDC in Euro in base 18\n/// @dev This contract is built to be deployed on Avalanche\ncontract OracleUSDCEURChainlinkAvalanche is BaseOracleChainlinkMultiTwoFeeds {\n string public constant DESCRIPTION = \"USDC/EUR Oracle\";\n\n constructor(uint32 _stalePeriod, address _treasury) BaseOracleChainlinkMultiTwoFeeds(_stalePeriod, _treasury) {}\n\n /// @inheritdoc IOracle\n function circuitChainlink() public pure override returns (AggregatorV3Interface[] memory) {\n AggregatorV3Interface[] memory _circuitChainlink = new AggregatorV3Interface[](2);\n // Oracle USDC/USD\n _circuitChainlink[0] = AggregatorV3Interface(0xF096872672F44d6EBA71458D74fe67F9a77a23B9);\n // Oracle EUR/USD\n _circuitChainlink[1] = AggregatorV3Interface(0x192f2DBA961Bb0277520C082d6bfa87D5961333E);\n return _circuitChainlink;\n }\n}\n" + }, + "contracts/oracle/implementations/mainnet/EUR/OracleBTCEURChainlink.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\nimport \"@chainlink/contracts/src/v0.8/interfaces/AggregatorV3Interface.sol\";\n\nimport \"../../../BaseOracleChainlinkMultiTwoFeeds.sol\";\n\n/// @title OracleBTCEURChainlink\n/// @author Angle Labs, Inc.\n/// @notice Gives the price of BTC in Euro in base 18\ncontract OracleBTCEURChainlink is BaseOracleChainlinkMultiTwoFeeds {\n string public constant DESCRIPTION = \"BTC/EUR Oracle\";\n\n constructor(uint32 _stalePeriod, address _treasury) BaseOracleChainlinkMultiTwoFeeds(_stalePeriod, _treasury) {}\n\n /// @inheritdoc IOracle\n function circuitChainlink() public pure override returns (AggregatorV3Interface[] memory) {\n AggregatorV3Interface[] memory _circuitChainlink = new AggregatorV3Interface[](2);\n // Oracle BTC/USD\n _circuitChainlink[0] = AggregatorV3Interface(0xF4030086522a5bEEa4988F8cA5B36dbC97BeE88c);\n // Oracle EUR/USD\n _circuitChainlink[1] = AggregatorV3Interface(0xb49f677943BC038e9857d61E7d053CaA2C1734C1);\n return _circuitChainlink;\n }\n}\n" + }, + "contracts/oracle/implementations/mainnet/EUR/OracleCBETHEURChainlink.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\nimport \"@chainlink/contracts/src/v0.8/interfaces/AggregatorV3Interface.sol\";\n\nimport \"../../../BaseOracleChainlinkMultiTwoFeeds.sol\";\n\n/// @title OracleCBETHEURChainlink\n/// @author Angle Labs, Inc.\n/// @notice Gives the price of cbETH in Euro in base 18\ncontract OracleCBETHEURChainlink is BaseOracleChainlinkMultiTwoFeeds {\n string public constant DESCRIPTION = \"cbETH/EUR Oracle\";\n\n constructor(uint32 _stalePeriod, address _treasury) BaseOracleChainlinkMultiTwoFeeds(_stalePeriod, _treasury) {}\n\n /// @inheritdoc IOracle\n function circuitChainlink() public pure override returns (AggregatorV3Interface[] memory) {\n AggregatorV3Interface[] memory _circuitChainlink = new AggregatorV3Interface[](3);\n // Oracle cbETH/ETH\n _circuitChainlink[0] = AggregatorV3Interface(0xF017fcB346A1885194689bA23Eff2fE6fA5C483b);\n // Oracle ETH/USD\n _circuitChainlink[1] = AggregatorV3Interface(0x5f4eC3Df9cbd43714FE2740f5E3616155c5b8419);\n // Oracle EUR/USD\n _circuitChainlink[2] = AggregatorV3Interface(0xb49f677943BC038e9857d61E7d053CaA2C1734C1);\n return _circuitChainlink;\n }\n\n /// @inheritdoc BaseOracleChainlinkMultiTwoFeeds\n function read() external view virtual override returns (uint256 quoteAmount) {\n quoteAmount = _getQuoteAmount();\n AggregatorV3Interface[] memory _circuitChainlink = circuitChainlink();\n uint8[3] memory circuitChainIsMultiplied = [1, 1, 0];\n uint8[3] memory chainlinkDecimals = [18, 8, 8];\n uint256 circuitLength = _circuitChainlink.length;\n for (uint256 i; i < circuitLength; ++i) {\n quoteAmount = _readChainlinkFeed(\n quoteAmount,\n _circuitChainlink[i],\n circuitChainIsMultiplied[i],\n chainlinkDecimals[i]\n );\n }\n }\n}\n" + }, + "contracts/oracle/implementations/mainnet/EUR/OracleETHEURChainlink.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\nimport \"@chainlink/contracts/src/v0.8/interfaces/AggregatorV3Interface.sol\";\n\nimport \"../../../BaseOracleChainlinkMultiTwoFeeds.sol\";\n\n/// @title OracleETHEURChainlink\n/// @author Angle Labs, Inc.\n/// @notice Gives the price of ETH in Euro in base 18\ncontract OracleETHEURChainlink is BaseOracleChainlinkMultiTwoFeeds {\n string public constant DESCRIPTION = \"ETH/EUR Oracle\";\n\n constructor(uint32 _stalePeriod, address _treasury) BaseOracleChainlinkMultiTwoFeeds(_stalePeriod, _treasury) {}\n\n /// @inheritdoc IOracle\n function circuitChainlink() public pure override returns (AggregatorV3Interface[] memory) {\n AggregatorV3Interface[] memory _circuitChainlink = new AggregatorV3Interface[](2);\n // Oracle ETH/USD\n _circuitChainlink[0] = AggregatorV3Interface(0x5f4eC3Df9cbd43714FE2740f5E3616155c5b8419);\n // Oracle EUR/USD\n _circuitChainlink[1] = AggregatorV3Interface(0xb49f677943BC038e9857d61E7d053CaA2C1734C1);\n return _circuitChainlink;\n }\n}\n" + }, + "contracts/oracle/implementations/mainnet/EUR/OracleHIGHEURChainlink.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\nimport \"@chainlink/contracts/src/v0.8/interfaces/AggregatorV3Interface.sol\";\n\nimport \"../../../BaseOracleChainlinkMultiTwoFeeds.sol\";\n\n/// @title OracleHIGHEURChainlink\n/// @author Angle Labs, Inc.\n/// @notice Gives the price of HIGH in Euro in base 18\ncontract OracleHIGHEURChainlink is BaseOracleChainlinkMultiTwoFeeds {\n string public constant DESCRIPTION = \"HIGH/EUR Oracle\";\n\n constructor(uint32 _stalePeriod, address _treasury) BaseOracleChainlinkMultiTwoFeeds(_stalePeriod, _treasury) {}\n\n /// @inheritdoc IOracle\n function circuitChainlink() public pure override returns (AggregatorV3Interface[] memory) {\n AggregatorV3Interface[] memory _circuitChainlink = new AggregatorV3Interface[](1);\n // Oracle HIGH/EUR\n _circuitChainlink[0] = AggregatorV3Interface(0x9E8E794ad6Ecdb6d5c7eaBE059D30E907F58859b);\n return _circuitChainlink;\n }\n\n /// @inheritdoc BaseOracleChainlinkMultiTwoFeeds\n function read() external view override returns (uint256 quoteAmount) {\n quoteAmount = _readChainlinkFeed(_getQuoteAmount(), circuitChainlink()[0], 1, 8);\n }\n}\n" + }, + "contracts/oracle/implementations/mainnet/EUR/OracleIB01EURChainlink.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\nimport \"@chainlink/contracts/src/v0.8/interfaces/AggregatorV3Interface.sol\";\n\nimport \"../../../BaseOracleChainlinkMultiTwoFeeds.sol\";\n\n/// @title OracleIB01EURChainlink\n/// @author Angle Labs, Inc.\n/// @notice Gives the price of IB01 in Euro in base 18\ncontract OracleIB01EURChainlink is BaseOracleChainlinkMultiTwoFeeds {\n string public constant DESCRIPTION = \"IB01/EUR Oracle\";\n\n constructor(uint32 _stalePeriod, address _treasury) BaseOracleChainlinkMultiTwoFeeds(_stalePeriod, _treasury) {}\n\n /// @inheritdoc IOracle\n function circuitChainlink() public pure override returns (AggregatorV3Interface[] memory) {\n AggregatorV3Interface[] memory _circuitChainlink = new AggregatorV3Interface[](2);\n // Oracle IB01/USD\n _circuitChainlink[0] = AggregatorV3Interface(0x32d1463EB53b73C095625719Afa544D5426354cB);\n // Oracle EUR/USD\n _circuitChainlink[1] = AggregatorV3Interface(0xb49f677943BC038e9857d61E7d053CaA2C1734C1);\n return _circuitChainlink;\n }\n}\n" + }, + "contracts/oracle/implementations/mainnet/EUR/OracleLUSDEURChainlink.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\nimport \"@chainlink/contracts/src/v0.8/interfaces/AggregatorV3Interface.sol\";\n\nimport \"../../../BaseOracleChainlinkMultiTwoFeeds.sol\";\n\n/// @title OracleLUSDEURChainlink\n/// @author Angle Labs, Inc.\n/// @notice Gives the price of LUSD in Euro in base 18\ncontract OracleLUSDEURChainlink is BaseOracleChainlinkMultiTwoFeeds {\n string public constant DESCRIPTION = \"LUSD/EUR Oracle\";\n\n constructor(uint32 _stalePeriod, address _treasury) BaseOracleChainlinkMultiTwoFeeds(_stalePeriod, _treasury) {}\n\n /// @inheritdoc IOracle\n function circuitChainlink() public pure override returns (AggregatorV3Interface[] memory) {\n AggregatorV3Interface[] memory _circuitChainlink = new AggregatorV3Interface[](2);\n // Oracle LUSD/USD\n _circuitChainlink[0] = AggregatorV3Interface(0x3D7aE7E594f2f2091Ad8798313450130d0Aba3a0);\n // Oracle EUR/USD\n _circuitChainlink[1] = AggregatorV3Interface(0xb49f677943BC038e9857d61E7d053CaA2C1734C1);\n return _circuitChainlink;\n }\n}\n" + }, + "contracts/oracle/implementations/mainnet/EUR/OracleUSDCEURChainlink.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\nimport \"@chainlink/contracts/src/v0.8/interfaces/AggregatorV3Interface.sol\";\n\nimport \"../../../BaseOracleChainlinkMultiTwoFeeds.sol\";\n\n/// @title OracleUSDCEURChainlink\n/// @author Angle Labs, Inc.\n/// @notice Gives the price of USDC in Euro in base 18\ncontract OracleUSDCEURChainlink is BaseOracleChainlinkMultiTwoFeeds {\n string public constant DESCRIPTION = \"USDC/EUR Oracle\";\n\n constructor(uint32 _stalePeriod, address _treasury) BaseOracleChainlinkMultiTwoFeeds(_stalePeriod, _treasury) {}\n\n /// @inheritdoc IOracle\n function circuitChainlink() public pure override returns (AggregatorV3Interface[] memory) {\n AggregatorV3Interface[] memory _circuitChainlink = new AggregatorV3Interface[](2);\n // Oracle USDC/USD\n _circuitChainlink[0] = AggregatorV3Interface(0x8fFfFfd4AfB6115b954Bd326cbe7B4BA576818f6);\n // Oracle EUR/USD\n _circuitChainlink[1] = AggregatorV3Interface(0xb49f677943BC038e9857d61E7d053CaA2C1734C1);\n return _circuitChainlink;\n }\n}\n" + }, + "contracts/oracle/implementations/mainnet/EUR/OracleWSTETHEURChainlink.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\nimport \"@chainlink/contracts/src/v0.8/interfaces/AggregatorV3Interface.sol\";\n\nimport \"../../../BaseOracleChainlinkMultiTwoFeeds.sol\";\nimport \"../../../../interfaces/external/lido/IStETH.sol\";\n\n/// @title OracleWSTETHEURChainlink\n/// @author Angle Labs, Inc.\n/// @notice Gives the price of wSTETH in Euro in base 18\ncontract OracleWSTETHEURChainlink is BaseOracleChainlinkMultiTwoFeeds {\n string public constant DESCRIPTION = \"wSTETH/EUR Oracle\";\n IStETH public constant STETH = IStETH(0xae7ab96520DE3A18E5e111B5EaAb095312D7fE84);\n\n constructor(uint32 _stalePeriod, address _treasury) BaseOracleChainlinkMultiTwoFeeds(_stalePeriod, _treasury) {}\n\n /// @inheritdoc IOracle\n function circuitChainlink() public pure override returns (AggregatorV3Interface[] memory) {\n AggregatorV3Interface[] memory _circuitChainlink = new AggregatorV3Interface[](2);\n // Oracle stETH/USD\n _circuitChainlink[0] = AggregatorV3Interface(0xCfE54B5cD566aB89272946F602D76Ea879CAb4a8);\n // Oracle EUR/USD\n _circuitChainlink[1] = AggregatorV3Interface(0xb49f677943BC038e9857d61E7d053CaA2C1734C1);\n return _circuitChainlink;\n }\n\n /// @inheritdoc BaseOracleChainlinkMultiTwoFeeds\n function _getQuoteAmount() internal view override returns (uint256) {\n return STETH.getPooledEthByShares(1 ether);\n }\n}\n" + }, + "contracts/oracle/implementations/mainnet/USD/OracleWSTETHUSDChainlink.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\nimport \"@chainlink/contracts/src/v0.8/interfaces/AggregatorV3Interface.sol\";\n\nimport \"../../../BaseOracleChainlinkOneFeed.sol\";\nimport \"../../../../interfaces/external/lido/IStETH.sol\";\n\n/// @title OracleWSTETHUSDChainlink\n/// @author Angle Labs, Inc.\n/// @notice Gives the price of wSTETH in USD in base 18\ncontract OracleWSTETHUSDChainlink is BaseOracleChainlinkOneFeed {\n string public constant DESCRIPTION = \"wSTETH/USD Oracle\";\n IStETH public constant STETH = IStETH(0xae7ab96520DE3A18E5e111B5EaAb095312D7fE84);\n\n constructor(uint32 _stalePeriod, address _treasury) BaseOracleChainlinkOneFeed(_stalePeriod, _treasury) {}\n\n /// @inheritdoc IOracle\n function circuitChainlink() public pure override returns (AggregatorV3Interface[] memory) {\n AggregatorV3Interface[] memory _circuitChainlink = new AggregatorV3Interface[](1);\n // Oracle stETH/USD\n _circuitChainlink[0] = AggregatorV3Interface(0xCfE54B5cD566aB89272946F602D76Ea879CAb4a8);\n return _circuitChainlink;\n }\n\n /// @inheritdoc BaseOracleChainlinkOneFeed\n function _getQuoteAmount() internal view override returns (uint256) {\n return STETH.getPooledEthByShares(1 ether);\n }\n}\n" + }, + "contracts/oracle/implementations/mainnet/XAU/OracleETHXAUChainlink.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\nimport \"@chainlink/contracts/src/v0.8/interfaces/AggregatorV3Interface.sol\";\n\nimport \"../../../BaseOracleChainlinkMultiTwoFeeds.sol\";\n\n/// @title OracleETHXAUChainlink\n/// @author Angle Labs, Inc.\n/// @notice Gives the price of ETH in XAU in base 18\ncontract OracleETHXAUChainlink is BaseOracleChainlinkMultiTwoFeeds {\n string public constant DESCRIPTION = \"ETH/GOLD Oracle\";\n\n constructor(uint32 _stalePeriod, address _treasury) BaseOracleChainlinkMultiTwoFeeds(_stalePeriod, _treasury) {}\n\n /// @inheritdoc IOracle\n function circuitChainlink() public pure override returns (AggregatorV3Interface[] memory) {\n AggregatorV3Interface[] memory _circuitChainlink = new AggregatorV3Interface[](2);\n // Oracle ETH/USD\n _circuitChainlink[0] = AggregatorV3Interface(0x5f4eC3Df9cbd43714FE2740f5E3616155c5b8419);\n // Oracle XAU/USD\n _circuitChainlink[1] = AggregatorV3Interface(0x214eD9Da11D2fbe465a6fc601a91E62EbEc1a0D6);\n return _circuitChainlink;\n }\n}\n" + }, + "contracts/oracle/implementations/mainnet/XAU/OracleLUSDXAUChainlink.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\nimport \"@chainlink/contracts/src/v0.8/interfaces/AggregatorV3Interface.sol\";\n\nimport \"../../../BaseOracleChainlinkMultiTwoFeeds.sol\";\n\n/// @title OracleLUSDXAUChainlink\n/// @author Angle Labs, Inc.\n/// @notice Gives the price of LUSD in XAU in base 18\ncontract OracleLUSDXAUChainlink is BaseOracleChainlinkMultiTwoFeeds {\n string public constant DESCRIPTION = \"LUSD/GOLD Oracle\";\n\n constructor(uint32 _stalePeriod, address _treasury) BaseOracleChainlinkMultiTwoFeeds(_stalePeriod, _treasury) {}\n\n /// @inheritdoc IOracle\n function circuitChainlink() public pure override returns (AggregatorV3Interface[] memory) {\n AggregatorV3Interface[] memory _circuitChainlink = new AggregatorV3Interface[](2);\n // Oracle LUSD/USD\n _circuitChainlink[0] = AggregatorV3Interface(0x3D7aE7E594f2f2091Ad8798313450130d0Aba3a0);\n // Oracle XAU/USD\n _circuitChainlink[1] = AggregatorV3Interface(0x214eD9Da11D2fbe465a6fc601a91E62EbEc1a0D6);\n return _circuitChainlink;\n }\n}\n" + }, + "contracts/oracle/implementations/mainnet/XAU/OracleUSDCXAUChainlink.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\nimport \"@chainlink/contracts/src/v0.8/interfaces/AggregatorV3Interface.sol\";\n\nimport \"../../../BaseOracleChainlinkMultiTwoFeeds.sol\";\n\n/// @title OracleUSDCXAUChainlink\n/// @author Angle Labs, Inc.\n/// @notice Gives the price of USDC in XAU in base 18\ncontract OracleUSDCXAUChainlink is BaseOracleChainlinkMultiTwoFeeds {\n string public constant DESCRIPTION = \"USDC/GOLD Oracle\";\n\n constructor(uint32 _stalePeriod, address _treasury) BaseOracleChainlinkMultiTwoFeeds(_stalePeriod, _treasury) {}\n\n /// @inheritdoc IOracle\n function circuitChainlink() public pure override returns (AggregatorV3Interface[] memory) {\n AggregatorV3Interface[] memory _circuitChainlink = new AggregatorV3Interface[](2);\n // Oracle USDC/USD\n _circuitChainlink[0] = AggregatorV3Interface(0x8fFfFfd4AfB6115b954Bd326cbe7B4BA576818f6);\n // Oracle XAU/USD\n _circuitChainlink[1] = AggregatorV3Interface(0x214eD9Da11D2fbe465a6fc601a91E62EbEc1a0D6);\n return _circuitChainlink;\n }\n}\n" + }, + "contracts/oracle/implementations/mainnet/XAU/OracleWSTETHXAUChainlink.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\nimport \"@chainlink/contracts/src/v0.8/interfaces/AggregatorV3Interface.sol\";\n\nimport \"../../../BaseOracleChainlinkMultiTwoFeeds.sol\";\nimport \"../../../../interfaces/external/lido/IStETH.sol\";\n\n/// @title OracleWSTETHXAUChainlink\n/// @author Angle Labs, Inc.\n/// @notice Gives the price of wSTETH in XAU in base 18\ncontract OracleWSTETHXAUChainlink is BaseOracleChainlinkMultiTwoFeeds {\n string public constant DESCRIPTION = \"wSTETH/XAU Oracle\";\n IStETH public constant STETH = IStETH(0xae7ab96520DE3A18E5e111B5EaAb095312D7fE84);\n\n constructor(uint32 _stalePeriod, address _treasury) BaseOracleChainlinkMultiTwoFeeds(_stalePeriod, _treasury) {}\n\n /// @inheritdoc IOracle\n function circuitChainlink() public pure override returns (AggregatorV3Interface[] memory) {\n AggregatorV3Interface[] memory _circuitChainlink = new AggregatorV3Interface[](2);\n // Oracle stETH/USD\n _circuitChainlink[0] = AggregatorV3Interface(0xCfE54B5cD566aB89272946F602D76Ea879CAb4a8);\n // Oracle XAU/USD\n _circuitChainlink[1] = AggregatorV3Interface(0x214eD9Da11D2fbe465a6fc601a91E62EbEc1a0D6);\n return _circuitChainlink;\n }\n\n /// @inheritdoc BaseOracleChainlinkMultiTwoFeeds\n function _getQuoteAmount() internal view override returns (uint256) {\n return STETH.getPooledEthByShares(1 ether);\n }\n}\n" + }, + "contracts/oracle/implementations/optimism/EUR/OracleETHEURChainlinkOptimism.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\nimport \"@chainlink/contracts/src/v0.8/interfaces/AggregatorV3Interface.sol\";\n\nimport \"../../../BaseOracleChainlinkMultiTwoFeeds.sol\";\n\n/// @title OracleETHEURChainlinkOptimism\n/// @author Angle Labs, Inc.\n/// @notice Gives the price of ETH in Euro in base 18\n/// @dev This contract is built to be deployed on Optimism\ncontract OracleETHEURChainlinkOptimism is BaseOracleChainlinkMultiTwoFeeds {\n string public constant DESCRIPTION = \"ETH/EUR Oracle\";\n\n constructor(uint32 _stalePeriod, address _treasury) BaseOracleChainlinkMultiTwoFeeds(_stalePeriod, _treasury) {}\n\n /// @inheritdoc IOracle\n function circuitChainlink() public pure override returns (AggregatorV3Interface[] memory) {\n AggregatorV3Interface[] memory _circuitChainlink = new AggregatorV3Interface[](2);\n // Oracle ETH/USD\n _circuitChainlink[0] = AggregatorV3Interface(0x13e3Ee699D1909E989722E753853AE30b17e08c5);\n // Oracle EUR/USD\n _circuitChainlink[1] = AggregatorV3Interface(0x3626369857A10CcC6cc3A6e4f5C2f5984a519F20);\n return _circuitChainlink;\n }\n}\n" + }, + "contracts/oracle/implementations/optimism/EUR/OracleOPEURChainlinkOptimism.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\nimport \"@chainlink/contracts/src/v0.8/interfaces/AggregatorV3Interface.sol\";\n\nimport \"../../../BaseOracleChainlinkMultiTwoFeeds.sol\";\n\n/// @title OracleOPEURChainlinkOptimism\n/// @author Angle Labs, Inc.\n/// @notice Gives the price of OP in Euro in base 18\n/// @dev This contract is built to be deployed on Optimism\ncontract OracleOPEURChainlinkOptimism is BaseOracleChainlinkMultiTwoFeeds {\n string public constant DESCRIPTION = \"OP/EUR Oracle\";\n\n constructor(uint32 _stalePeriod, address _treasury) BaseOracleChainlinkMultiTwoFeeds(_stalePeriod, _treasury) {}\n\n /// @inheritdoc IOracle\n function circuitChainlink() public pure override returns (AggregatorV3Interface[] memory) {\n AggregatorV3Interface[] memory _circuitChainlink = new AggregatorV3Interface[](2);\n // Oracle OP/USD\n _circuitChainlink[0] = AggregatorV3Interface(0x0D276FC14719f9292D5C1eA2198673d1f4269246);\n // Oracle EUR/USD\n _circuitChainlink[1] = AggregatorV3Interface(0x3626369857A10CcC6cc3A6e4f5C2f5984a519F20);\n return _circuitChainlink;\n }\n}\n" + }, + "contracts/oracle/implementations/optimism/EUR/OracleUSDCEURChainlinkOptimism.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\nimport \"@chainlink/contracts/src/v0.8/interfaces/AggregatorV3Interface.sol\";\n\nimport \"../../../BaseOracleChainlinkMultiTwoFeeds.sol\";\n\n/// @title OracleUSDCEURChainlinkOptimism\n/// @author Angle Labs, Inc.\n/// @notice Gives the price of USDC in Euro in base 18\n/// @dev This contract is built to be deployed on Optimism\ncontract OracleUSDCEURChainlinkOptimism is BaseOracleChainlinkMultiTwoFeeds {\n string public constant DESCRIPTION = \"USDC/EUR Oracle\";\n\n constructor(uint32 _stalePeriod, address _treasury) BaseOracleChainlinkMultiTwoFeeds(_stalePeriod, _treasury) {}\n\n /// @inheritdoc IOracle\n function circuitChainlink() public pure override returns (AggregatorV3Interface[] memory) {\n AggregatorV3Interface[] memory _circuitChainlink = new AggregatorV3Interface[](2);\n // Oracle USDC/USD\n _circuitChainlink[0] = AggregatorV3Interface(0x16a9FA2FDa030272Ce99B29CF780dFA30361E0f3);\n // Oracle EUR/USD\n _circuitChainlink[1] = AggregatorV3Interface(0x3626369857A10CcC6cc3A6e4f5C2f5984a519F20);\n return _circuitChainlink;\n }\n}\n" + }, + "contracts/oracle/implementations/polygon/EUR/OracleBTCEURChainlinkPolygon.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\nimport \"@chainlink/contracts/src/v0.8/interfaces/AggregatorV3Interface.sol\";\n\nimport \"../../../BaseOracleChainlinkMultiTwoFeeds.sol\";\n\n/// @title OracleBTCEURChainlinkPolygon\n/// @author Angle Labs, Inc.\n/// @notice Gives the price of BTC in Euro in base 18\n/// @dev This contract is built to be deployed on Polygon\ncontract OracleBTCEURChainlinkPolygon is BaseOracleChainlinkMultiTwoFeeds {\n string public constant DESCRIPTION = \"BTC/EUR Oracle\";\n\n constructor(uint32 _stalePeriod, address _treasury) BaseOracleChainlinkMultiTwoFeeds(_stalePeriod, _treasury) {}\n\n /// @inheritdoc IOracle\n function circuitChainlink() public pure override returns (AggregatorV3Interface[] memory) {\n AggregatorV3Interface[] memory _circuitChainlink = new AggregatorV3Interface[](2);\n // Oracle BTC/USD\n _circuitChainlink[0] = AggregatorV3Interface(0xc907E116054Ad103354f2D350FD2514433D57F6f);\n // Oracle EUR/USD\n _circuitChainlink[1] = AggregatorV3Interface(0x73366Fe0AA0Ded304479862808e02506FE556a98);\n return _circuitChainlink;\n }\n}\n" + }, + "contracts/oracle/implementations/polygon/EUR/OracleETHEURChainlinkPolygon.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\nimport \"@chainlink/contracts/src/v0.8/interfaces/AggregatorV3Interface.sol\";\n\nimport \"../../../BaseOracleChainlinkMultiTwoFeeds.sol\";\n\n/// @title OracleETHEURChainlinkPolygon\n/// @author Angle Labs, Inc.\n/// @notice Gives the price of ETH in Euro in base 18\n/// @dev This contract is built to be deployed on Polygon\ncontract OracleETHEURChainlinkPolygon is BaseOracleChainlinkMultiTwoFeeds {\n string public constant DESCRIPTION = \"ETH/EUR Oracle\";\n\n constructor(uint32 _stalePeriod, address _treasury) BaseOracleChainlinkMultiTwoFeeds(_stalePeriod, _treasury) {}\n\n /// @inheritdoc IOracle\n function circuitChainlink() public pure override returns (AggregatorV3Interface[] memory) {\n AggregatorV3Interface[] memory _circuitChainlink = new AggregatorV3Interface[](2);\n // Oracle ETH/USD\n _circuitChainlink[0] = AggregatorV3Interface(0xF9680D99D6C9589e2a93a78A04A279e509205945);\n // Oracle EUR/USD\n _circuitChainlink[1] = AggregatorV3Interface(0x73366Fe0AA0Ded304479862808e02506FE556a98);\n return _circuitChainlink;\n }\n}\n" + }, + "contracts/oracle/implementations/polygon/EUR/OracleMAIEURChainlinkPolygon.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\nimport \"@chainlink/contracts/src/v0.8/interfaces/AggregatorV3Interface.sol\";\n\nimport \"../../../BaseOracleChainlinkMultiTwoFeeds.sol\";\n\n/// @title OracleMAIEURChainlinkPolygon\n/// @author Angle Labs, Inc.\n/// @notice Gives the price of MAI in Euro in base 18\n/// @dev This contract is built to be deployed on Polygon\ncontract OracleMAIEURChainlinkPolygon is BaseOracleChainlinkMultiTwoFeeds {\n string public constant DESCRIPTION = \"MAI/EUR Oracle\";\n\n constructor(uint32 _stalePeriod, address _treasury) BaseOracleChainlinkMultiTwoFeeds(_stalePeriod, _treasury) {}\n\n /// @inheritdoc IOracle\n function circuitChainlink() public pure override returns (AggregatorV3Interface[] memory) {\n AggregatorV3Interface[] memory _circuitChainlink = new AggregatorV3Interface[](2);\n // Oracle MAI/USD\n _circuitChainlink[0] = AggregatorV3Interface(0xd8d483d813547CfB624b8Dc33a00F2fcbCd2D428);\n // Oracle EUR/USD\n _circuitChainlink[1] = AggregatorV3Interface(0x73366Fe0AA0Ded304479862808e02506FE556a98);\n return _circuitChainlink;\n }\n}\n" + }, + "contracts/oracle/implementations/polygon/EUR/OracleMATICEURChainlinkPolygon.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\nimport \"@chainlink/contracts/src/v0.8/interfaces/AggregatorV3Interface.sol\";\n\nimport \"../../../BaseOracleChainlinkMultiTwoFeeds.sol\";\n\n/// @title OracleMATICEURChainlinkPolygon\n/// @author Angle Labs, Inc.\n/// @notice Gives the price of MATIC in Euro in base 18\n/// @dev This contract is built to be deployed on Polygon\ncontract OracleMATICEURChainlinkPolygon is BaseOracleChainlinkMultiTwoFeeds {\n string public constant DESCRIPTION = \"MATIC/EUR Oracle\";\n\n constructor(uint32 _stalePeriod, address _treasury) BaseOracleChainlinkMultiTwoFeeds(_stalePeriod, _treasury) {}\n\n /// @inheritdoc IOracle\n function circuitChainlink() public pure override returns (AggregatorV3Interface[] memory) {\n AggregatorV3Interface[] memory _circuitChainlink = new AggregatorV3Interface[](2);\n // Oracle MATIC/USD\n _circuitChainlink[0] = AggregatorV3Interface(0xAB594600376Ec9fD91F8e885dADF0CE036862dE0);\n // Oracle EUR/USD\n _circuitChainlink[1] = AggregatorV3Interface(0x73366Fe0AA0Ded304479862808e02506FE556a98);\n return _circuitChainlink;\n }\n}\n" + }, + "contracts/oracle/implementations/polygon/EUR/OracleUSDCEURChainlinkPolygon.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\nimport \"../../../BaseOracleChainlinkMultiTwoFeeds.sol\";\n\n/// @title OracleUSDCEURChainlinkPolygon\n/// @author Angle Labs, Inc.\n/// @notice Gives the price of USDC in Euro in base 18\n/// @dev This contract is built to be deployed on Polygon\ncontract OracleUSDCEURChainlinkPolygon is BaseOracleChainlinkMultiTwoFeeds {\n string public constant DESCRIPTION = \"USDC/EUR Oracle\";\n\n constructor(uint32 _stalePeriod, address _treasury) BaseOracleChainlinkMultiTwoFeeds(_stalePeriod, _treasury) {}\n\n /// @inheritdoc IOracle\n function circuitChainlink() public pure override returns (AggregatorV3Interface[] memory) {\n AggregatorV3Interface[] memory _circuitChainlink = new AggregatorV3Interface[](2);\n // Oracle USDC/USD\n _circuitChainlink[0] = AggregatorV3Interface(0xfE4A8cc5b5B2366C1B58Bea3858e81843581b2F7);\n // Oracle EUR/USD\n _circuitChainlink[1] = AggregatorV3Interface(0x73366Fe0AA0Ded304479862808e02506FE556a98);\n return _circuitChainlink;\n }\n}\n" + }, + "contracts/oracle/implementations/polygon/XAU/OracleETHXAUChainlinkPolygon.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\nimport \"@chainlink/contracts/src/v0.8/interfaces/AggregatorV3Interface.sol\";\n\nimport \"../../../BaseOracleChainlinkMultiTwoFeeds.sol\";\n\n/// @title OracleETHXAUChainlinkPolygon\n/// @author Angle Labs, Inc.\n/// @notice Gives the price of ETH in XAU in base 18\n/// @dev This contract is built to be deployed on Polygon\ncontract OracleETHXAUChainlinkPolygon is BaseOracleChainlinkMultiTwoFeeds {\n string public constant DESCRIPTION = \"ETH/GOLD Oracle\";\n\n constructor(uint32 _stalePeriod, address _treasury) BaseOracleChainlinkMultiTwoFeeds(_stalePeriod, _treasury) {}\n\n /// @inheritdoc IOracle\n function circuitChainlink() public pure override returns (AggregatorV3Interface[] memory) {\n AggregatorV3Interface[] memory _circuitChainlink = new AggregatorV3Interface[](2);\n // Oracle ETH/USD\n _circuitChainlink[0] = AggregatorV3Interface(0xF9680D99D6C9589e2a93a78A04A279e509205945);\n // Oracle XAU/USD\n _circuitChainlink[1] = AggregatorV3Interface(0x0C466540B2ee1a31b441671eac0ca886e051E410);\n return _circuitChainlink;\n }\n}\n" + }, + "contracts/oracle/KeeperRegistry.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\nimport \"@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol\";\nimport \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\nimport \"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\";\n\nimport \"../interfaces/ICoreBorrow.sol\";\nimport \"../interfaces/IKeeperRegistry.sol\";\n\n/// @title KeeperRegistry\n/// @notice Maintains a mapping of keepers authorized to use the core module just after oracle updates\n/// @author Angle Labs, Inc.\ncontract KeeperRegistry is Initializable, IKeeperRegistry {\n using SafeERC20 for IERC20;\n\n /// @notice Contract handling access control\n ICoreBorrow public coreBorrow;\n\n /// @notice Trusted EOAs - needs to be tx.origin\n mapping(address => uint256) public trusted;\n\n uint256[48] private __gap;\n\n // =================================== EVENTS ==================================\n\n event TrustedToggled(address indexed wallet, bool trust);\n\n // =================================== ERRORS ==================================\n\n error NotGovernorOrGuardian();\n error NotTrusted();\n error ZeroAddress();\n\n // ================================= MODIFIERS =================================\n\n /// @notice Checks whether the `msg.sender` has the governor role or the guardian role\n modifier onlyGovernorOrGuardian() {\n if (!coreBorrow.isGovernorOrGuardian(msg.sender)) revert NotGovernorOrGuardian();\n _;\n }\n\n // ================================ CONSTRUCTOR ================================\n\n constructor() initializer {}\n\n function initialize(ICoreBorrow _coreBorrow) public initializer {\n if (address(_coreBorrow) == address(0)) revert ZeroAddress();\n coreBorrow = _coreBorrow;\n }\n\n // =============================== MAIN FUNCTIONS ==============================\n\n /// @notice Adds or removes a trusted keeper bot\n function toggleTrusted(address eoa) external onlyGovernorOrGuardian {\n uint256 trustedStatus = 1 - trusted[eoa];\n trusted[eoa] = trustedStatus;\n emit TrustedToggled(eoa, trustedStatus == 1);\n }\n\n /// @inheritdoc IKeeperRegistry\n function isTrusted(address caller) external view returns (bool) {\n return trusted[caller] == 1;\n }\n}\n" + }, + "contracts/oracle/OracleChainlinkMulti.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\nimport \"@chainlink/contracts/src/v0.8/interfaces/AggregatorV3Interface.sol\";\n\nimport \"./BaseOracleChainlinkMulti.sol\";\n\n/// @title OracleChainlinkMulti\n/// @author Angle Labs, Inc.\n/// @notice Oracle contract, one contract is deployed per collateral/stablecoin pair\n/// @dev This contract concerns an oracle that uses Chainlink with multiple pools to read from\n/// @dev Typically we expect to use this contract to read like the ETH/USD and then USD/EUR feed\ncontract OracleChainlinkMulti is BaseOracleChainlinkMulti {\n // ========================= Parameters and References =========================\n\n /// @notice Chainlink pools, the order of the pools has to be the order in which they are read for the computation\n /// of the price\n AggregatorV3Interface[] internal _circuitChainlink;\n /// @notice Whether each rate for the pairs in `circuitChainlink` should be multiplied or divided\n uint8[] public circuitChainIsMultiplied;\n /// @notice Decimals for each Chainlink pairs\n uint8[] public chainlinkDecimals;\n /// @notice Unit of the stablecoin\n uint256 public immutable outBase;\n /// @notice Description of the assets concerned by the oracle and the price outputted\n string public description;\n\n // ===================================== Error =================================\n\n error IncompatibleLengths();\n\n /// @notice Constructor for an oracle using Chainlink with multiple pools to read from\n /// @param circuitChainlink_ Chainlink pool addresses (in order)\n /// @param _circuitChainIsMultiplied Whether we should multiply or divide by this rate\n /// @param _outBase Unit of the stablecoin (or the out asset) associated to the oracle\n /// @param _stalePeriod Minimum feed update frequency for the oracle to not revert\n /// @param _treasury Treasury associated to the VaultManager which reads from this feed\n /// @param _description Description of the assets concerned by the oracle\n /// @dev For instance, if this oracle is supposed to give the price of ETH in EUR, and if the agEUR\n /// stablecoin associated to EUR has 18 decimals, then `outBase` should be 10**18\n constructor(\n address[] memory circuitChainlink_,\n uint8[] memory _circuitChainIsMultiplied,\n uint256 _outBase,\n uint32 _stalePeriod,\n address _treasury,\n string memory _description\n ) BaseOracleChainlinkMulti(_stalePeriod, _treasury) {\n outBase = _outBase;\n description = _description;\n uint256 circuitLength = circuitChainlink_.length;\n if (circuitLength == 0 || circuitLength != _circuitChainIsMultiplied.length) revert IncompatibleLengths();\n for (uint256 i; i < circuitLength; ++i) {\n AggregatorV3Interface _pool = AggregatorV3Interface(circuitChainlink_[i]);\n _circuitChainlink.push(_pool);\n chainlinkDecimals.push(_pool.decimals());\n }\n circuitChainIsMultiplied = _circuitChainIsMultiplied;\n }\n\n // ============================= Reading Oracles ===============================\n\n /// @inheritdoc IOracle\n function circuitChainlink() public view override returns (AggregatorV3Interface[] memory) {\n return _circuitChainlink;\n }\n\n /// @inheritdoc IOracle\n function read() external view override returns (uint256 quoteAmount) {\n quoteAmount = outBase;\n uint256 circuitLength = _circuitChainlink.length;\n for (uint256 i; i < circuitLength; ++i) {\n quoteAmount = _readChainlinkFeed(\n quoteAmount,\n _circuitChainlink[i],\n circuitChainIsMultiplied[i],\n chainlinkDecimals[i]\n );\n }\n }\n}\n" + }, + "contracts/settlement/Settlement.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\nimport \"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\";\nimport \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\nimport \"@openzeppelin/contracts/token/ERC20/extensions/IERC20Metadata.sol\";\n\nimport \"../interfaces/IAgToken.sol\";\nimport \"../interfaces/ISwapper.sol\";\nimport \"../interfaces/IVaultManager.sol\";\n\n/// @title Settlement\n/// @author Angle Labs, Inc.\n/// @notice Settlement Contract for a VaultManager\n/// @dev This settlement contract should be activated by a careful governance which needs to have performed\n/// some key operations before activating this contract\n/// @dev In case of global settlement, there should be one settlement contract per `VaultManager`\ncontract Settlement {\n using SafeERC20 for IERC20;\n\n /// @notice Base used for parameter computation\n uint256 public constant BASE_PARAMS = 10 ** 9;\n /// @notice Base used for interest computation\n uint256 public constant BASE_INTEREST = 10 ** 27;\n /// @notice Base used for exchange rate computation. It is assumed\n /// that stablecoins have this base\n uint256 public constant BASE_STABLECOIN = 10 ** 18;\n /// @notice Duration of the claim period for over-collateralized vaults\n uint256 public constant OVER_COLLATERALIZED_CLAIM_DURATION = 3 * 24 * 3600;\n\n // =============== Immutable references set in the constructor =================\n\n /// @notice `VaultManager` of this settlement contract\n IVaultManager public immutable vaultManager;\n /// @notice Reference to the stablecoin supported by the `VaultManager` contract\n IAgToken public immutable stablecoin;\n /// @notice Reference to the collateral supported by the `VaultManager`\n IERC20 public immutable collateral;\n /// @notice Base of the collateral\n uint256 internal immutable _collatBase;\n\n // ================ Variables frozen at settlement activation ==================\n\n /// @notice Value of the oracle for the collateral/stablecoin pair\n uint256 public oracleValue;\n /// @notice Value of the interest accumulator at settlement activation\n uint256 public interestAccumulator;\n /// @notice Timestamp at which settlement was activated\n uint256 public activationTimestamp;\n /// @notice Collateral factor of the `VaultManager`\n uint64 public collateralFactor;\n\n // =================== Variables updated during the process ====================\n\n /// @notice How much collateral you can get from stablecoins\n uint256 public collateralStablecoinExchangeRate;\n /// @notice Amount of collateral that will be left over at the end of the process\n uint256 public leftOverCollateral;\n /// @notice Whether the `collateralStablecoinExchangeRate` has been computed\n bool public exchangeRateComputed;\n /// @notice Maps a vault to 1 if it was claimed by its owner\n mapping(uint256 => uint256) public vaultCheck;\n\n // ================================ Events =====================================\n\n event GlobalClaimPeriodActivated(uint256 _collateralStablecoinExchangeRate);\n event Recovered(address indexed tokenAddress, address indexed to, uint256 amount);\n event SettlementActivated(uint256 startTimestamp);\n event VaultClaimed(uint256 vaultID, uint256 stablecoinAmount, uint256 collateralAmount);\n\n // ================================ Errors =====================================\n\n error GlobalClaimPeriodNotStarted();\n error InsolventVault();\n error NotGovernor();\n error NotOwner();\n error RestrictedClaimPeriodNotEnded();\n error SettlementNotInitialized();\n error VaultAlreadyClaimed();\n\n /// @notice Constructor of the contract\n /// @param _vaultManager Address of the `VaultManager` associated to this `Settlement` contract\n /// @dev Out of safety, this constructor reads values from the `VaultManager` contract directly\n constructor(IVaultManager _vaultManager) {\n vaultManager = _vaultManager;\n stablecoin = _vaultManager.stablecoin();\n collateral = _vaultManager.collateral();\n _collatBase = 10 ** (IERC20Metadata(address(collateral)).decimals());\n }\n\n /// @notice Checks whether the `msg.sender` has the governor role or not\n modifier onlyGovernor() {\n if (!(vaultManager.treasury().isGovernor(msg.sender))) revert NotGovernor();\n _;\n }\n\n /// @notice Activates the settlement contract\n /// @dev When calling this function governance should make sure to have:\n /// 1. Accrued the interest rate on the contract\n /// 2. Paused the contract\n /// 3. Recovered all the collateral available in the `VaultManager` contract either\n /// by doing a contract upgrade or by calling a `recoverERC20` method if supported\n function activateSettlement() external onlyGovernor {\n oracleValue = (vaultManager.oracle()).read();\n interestAccumulator = vaultManager.interestAccumulator();\n activationTimestamp = block.timestamp;\n collateralFactor = vaultManager.collateralFactor();\n emit SettlementActivated(block.timestamp);\n }\n\n /// @notice Allows the owner of an over-collateralized vault to claim its collateral upon bringing back all owed stablecoins\n /// @param vaultID ID of the vault to claim\n /// @param to Address to which collateral should be sent\n /// @param who Address which should be notified if needed of the transfer of stablecoins and collateral\n /// @param data Data to pass to the `who` contract for it to successfully give the correct amount of stablecoins\n /// to the `msg.sender` address\n /// @return Amount of collateral sent to the `to` address\n /// @return Amount of stablecoins sent to the contract\n /// @dev Claiming can only happen short after settlement activation\n /// @dev A vault cannot be claimed twice and only the owner of the vault can claim it (regardless of the approval logic)\n /// @dev Only over-collateralized vaults can be claimed from this medium\n function claimOverCollateralizedVault(\n uint256 vaultID,\n address to,\n address who,\n bytes memory data\n ) external returns (uint256, uint256) {\n if (activationTimestamp == 0 || block.timestamp > activationTimestamp + OVER_COLLATERALIZED_CLAIM_DURATION)\n revert SettlementNotInitialized();\n if (vaultCheck[vaultID] == 1) revert VaultAlreadyClaimed();\n if (vaultManager.ownerOf(vaultID) != msg.sender) revert NotOwner();\n (uint256 collateralAmount, uint256 normalizedDebt) = vaultManager.vaultData(vaultID);\n uint256 vaultDebt = (normalizedDebt * interestAccumulator) / BASE_INTEREST;\n if (collateralAmount * oracleValue * collateralFactor < vaultDebt * BASE_PARAMS * _collatBase)\n revert InsolventVault();\n vaultCheck[vaultID] = 1;\n emit VaultClaimed(vaultID, vaultDebt, collateralAmount);\n return _handleRepay(collateralAmount, vaultDebt, to, who, data);\n }\n\n /// @notice Activates the global claim period by setting the `collateralStablecoinExchangeRate` which is going to\n /// dictate how much of collateral will be recoverable for each stablecoin\n /// @dev This function can only be called by the governor in order to allow it in case multiple settlements happen across\n /// different `VaultManager` to rebalance the amount of stablecoins on each to make sure that across all settlement contracts\n /// a similar value of collateral can be obtained against a similar value of stablecoins\n function activateGlobalClaimPeriod() external onlyGovernor {\n if (activationTimestamp == 0 || block.timestamp <= activationTimestamp + OVER_COLLATERALIZED_CLAIM_DURATION)\n revert RestrictedClaimPeriodNotEnded();\n uint256 collateralBalance = collateral.balanceOf(address(this));\n uint256 leftOverDebt = (vaultManager.totalNormalizedDebt() * interestAccumulator) / BASE_INTEREST;\n uint256 stablecoinBalance = stablecoin.balanceOf(address(this));\n // How much 1 of stablecoin will give you in collateral\n uint256 _collateralStablecoinExchangeRate;\n\n if (stablecoinBalance < leftOverDebt) {\n // The left over debt is the total debt minus the stablecoins which have already been accumulated\n // in the first phase\n leftOverDebt -= stablecoinBalance;\n // If you control all the debt, then you are entitled to get all the collateral left in the protocol\n _collateralStablecoinExchangeRate = (collateralBalance * BASE_STABLECOIN) / leftOverDebt;\n // But at the same time, you cannot get more collateral than the value of the stablecoins you brought\n uint256 maxExchangeRate = (BASE_STABLECOIN * _collatBase) / oracleValue;\n if (_collateralStablecoinExchangeRate >= maxExchangeRate) {\n // In this situation, we're sure that `leftOverCollateral` will be positive: governance should be wary\n // to call `recoverERC20` short after though as there's nothing that is going to prevent people to redeem\n // more stablecoins than the `leftOverDebt`\n leftOverCollateral = collateralBalance - (leftOverDebt * _collatBase) / oracleValue;\n _collateralStablecoinExchangeRate = maxExchangeRate;\n }\n }\n exchangeRateComputed = true;\n // In the else case where there is no debt left, you cannot get anything from your stablecoins\n // and so the `collateralStablecoinExchangeRate` is null\n collateralStablecoinExchangeRate = _collateralStablecoinExchangeRate;\n emit GlobalClaimPeriodActivated(_collateralStablecoinExchangeRate);\n }\n\n /// @notice Allows to claim collateral from stablecoins\n /// @param to Address to which collateral should be sent\n /// @param who Address which should be notified if needed of the transfer of stablecoins and collateral\n /// @param data Data to pass to the `who` contract for it to successfully give the correct amount of stablecoins\n /// to the `msg.sender` address\n /// @return Amount of collateral sent to the `to` address\n /// @return Amount of stablecoins sent to the contract\n /// @dev This function reverts if the `collateralStablecoinExchangeRate` is null and hence if the global claim period has\n /// not been activated\n function claimCollateralFromStablecoins(\n uint256 stablecoinAmount,\n address to,\n address who,\n bytes memory data\n ) external returns (uint256, uint256) {\n if (!exchangeRateComputed) revert GlobalClaimPeriodNotStarted();\n return\n _handleRepay(\n (stablecoinAmount * collateralStablecoinExchangeRate) / BASE_STABLECOIN,\n stablecoinAmount,\n to,\n who,\n data\n );\n }\n\n /// @notice Handles the simultaneous repayment of stablecoins with a transfer of collateral\n /// @param collateralAmountToGive Amount of collateral the contract should give\n /// @param stableAmountToRepay Amount of stablecoins the contract should burn from the call\n /// @param to Address to which stablecoins should be sent\n /// @param who Address which should be notified if needed of the transfer\n /// @param data Data to pass to the `who` contract for it to successfully give the correct amount of stablecoins\n /// to the `msg.sender` address\n /// @dev This function allows for capital-efficient claims of collateral from stablecoins\n function _handleRepay(\n uint256 collateralAmountToGive,\n uint256 stableAmountToRepay,\n address to,\n address who,\n bytes memory data\n ) internal returns (uint256, uint256) {\n collateral.safeTransfer(to, collateralAmountToGive);\n if (data.length != 0) {\n ISwapper(who).swap(\n collateral,\n IERC20(address(stablecoin)),\n msg.sender,\n stableAmountToRepay,\n collateralAmountToGive,\n data\n );\n }\n stablecoin.transferFrom(msg.sender, address(this), stableAmountToRepay);\n return (collateralAmountToGive, stableAmountToRepay);\n }\n\n /// @notice Recovers leftover tokens from the contract or tokens that were mistakenly sent to the contract\n /// @param tokenAddress Address of the token to recover\n /// @param to Address to send the remaining tokens to\n /// @param amountToRecover Amount to recover from the contract\n /// @dev Governors cannot recover more collateral than what would be leftover from the contract\n /// @dev This function can be used to rebalance stablecoin balances across different settlement contracts\n /// to make sure every stablecoin can be redeemed for the same value of collateral\n /// @dev It can also be used to recover tokens that are mistakenly sent to this contract\n function recoverERC20(address tokenAddress, address to, uint256 amountToRecover) external onlyGovernor {\n if (tokenAddress == address(collateral)) {\n if (!exchangeRateComputed) revert GlobalClaimPeriodNotStarted();\n leftOverCollateral -= amountToRecover;\n collateral.safeTransfer(to, amountToRecover);\n } else {\n IERC20(tokenAddress).safeTransfer(to, amountToRecover);\n }\n emit Recovered(tokenAddress, to, amountToRecover);\n }\n}\n" + }, + "contracts/swapper/Swapper.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\n/*\n * █ \n ***** ▓▓▓ \n * ▓▓▓▓▓▓▓ \n * ///. ▓▓▓▓▓▓▓▓▓▓▓▓▓ \n ***** //////// ▓▓▓▓▓▓▓ \n * ///////////// ▓▓▓ \n ▓▓ ////////////////// █ ▓▓ \n ▓▓ ▓▓ /////////////////////// ▓▓ ▓▓ \n ▓▓ ▓▓ //////////////////////////// ▓▓ ▓▓ \n ▓▓ ▓▓ /////////▓▓▓///////▓▓▓///////// ▓▓ ▓▓ \n ▓▓ ,////////////////////////////////////// ▓▓ ▓▓ \n ▓▓ ////////////////////////////////////////// ▓▓ \n ▓▓ //////////////////////▓▓▓▓///////////////////// \n ,//////////////////////////////////////////////////// \n .////////////////////////////////////////////////////////// \n .//////////////////////////██.,//////////////////////////█ \n .//////////////////////████..,./////////////////////██ \n ...////////////////███████.....,.////////////////███ \n ,.,////////////████████ ........,///////////████ \n .,.,//////█████████ ,.......///////████ \n ,..//████████ ........./████ \n ..,██████ .....,███ \n .██ ,.,█ \n \n \n \n ▓▓ ▓▓▓▓▓▓▓▓▓▓ ▓▓▓▓▓▓▓▓▓▓ ▓▓ ▓▓▓▓▓▓▓▓▓▓ \n ▓▓▓▓▓▓ ▓▓▓ ▓▓▓ ▓▓▓ ▓▓ ▓▓ ▓▓▓▓ \n ▓▓▓ ▓▓▓ ▓▓▓ ▓▓▓ ▓▓▓ ▓▓▓ ▓▓ ▓▓▓▓▓ \n ▓▓▓ ▓▓ ▓▓▓ ▓▓▓ ▓▓▓▓▓▓▓▓▓▓ ▓▓▓▓▓▓▓▓▓▓ ▓▓▓▓▓▓▓▓▓▓ \n*/\n\npragma solidity ^0.8.12;\n\nimport \"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\";\nimport \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\n\nimport \"../interfaces/IAngleRouterSidechain.sol\";\nimport \"../interfaces/ICoreBorrow.sol\";\nimport \"../interfaces/ISwapper.sol\";\nimport \"../interfaces/external/lido/IWStETH.sol\";\nimport \"../interfaces/external/uniswap/IUniswapRouter.sol\";\n\n// ==================================== ENUM ===================================\n\n/// @notice All possible swaps\nenum SwapType {\n UniswapV3,\n oneInch,\n AngleRouter,\n Leverage,\n None\n}\n\n/// @title Swapper\n/// @author Angle Labs, Inc.\n/// @notice Swapper contract facilitating interactions with Angle VaultManager contracts, notably\n/// liquidation and leverage transactions\ncontract Swapper is ISwapper {\n using SafeERC20 for IERC20;\n\n // ===================== CONSTANTS AND IMMUTABLE VARIABLES =====================\n\n /// @notice Reference to the `CoreBorrow` contract of the module which handles all AccessControl logic\n ICoreBorrow public immutable core;\n /// @notice Uniswap Router contract\n IUniswapV3Router public immutable uniV3Router;\n /// @notice 1inch Router\n address public immutable oneInch;\n /// @notice AngleRouter\n IAngleRouterSidechain public immutable angleRouter;\n\n // =================================== ERRORS ==================================\n\n error EmptyReturnMessage();\n error IncompatibleLengths();\n error NotGovernorOrGuardian();\n error TooSmallAmountOut();\n error ZeroAddress();\n\n /// @notice Constructor of the contract\n /// @param _core Core address\n /// @param _uniV3Router UniswapV3 Router address\n /// @param _oneInch 1inch Router address\n /// @param _angleRouter AngleRouter contract address\n constructor(\n ICoreBorrow _core,\n IUniswapV3Router _uniV3Router,\n address _oneInch,\n IAngleRouterSidechain _angleRouter\n ) {\n if (address(_core) == address(0) || _oneInch == address(0) || address(_angleRouter) == address(0))\n revert ZeroAddress();\n core = _core;\n uniV3Router = _uniV3Router;\n oneInch = _oneInch;\n angleRouter = _angleRouter;\n }\n\n // ========================= EXTERNAL ACCESS FUNCTIONS =========================\n\n /// @inheritdoc ISwapper\n /// @dev This function swaps the `inToken` to the `outToken` by doing a UniV3 swap, a 1inch swap or by interacting\n /// with the `AngleRouter` contract\n /// @dev One slippage check is performed at the end of the call\n /// @dev In this implementation, the function tries to make sure that the `outTokenRecipient` address has at the end\n /// of the call `outTokenOwed`, leftover tokens are sent to a `to` address which by default is the `outTokenRecipient`\n function swap(\n IERC20 inToken,\n IERC20 outToken,\n address outTokenRecipient,\n uint256 outTokenOwed,\n uint256 inTokenObtained,\n bytes memory data\n ) external {\n // Address to receive the surplus amount of token at the end of the call\n address to;\n // For slippage protection, it is checked at the end of the call\n uint256 minAmountOut;\n // Type of the swap to execute: if `swapType == 4`, then it is optional to swap\n uint256 swapType;\n // We're reusing the `data` variable (it can be `path` on UniswapV3, a payload for 1inch or like encoded actions\n // for a router call)\n (to, minAmountOut, swapType, data) = abi.decode(data, (address, uint256, uint256, bytes));\n\n to = (to == address(0)) ? outTokenRecipient : to;\n\n _swap(inToken, inTokenObtained, SwapType(swapType), data);\n\n // A final slippage check is performed after the swaps\n uint256 outTokenBalance = outToken.balanceOf(address(this));\n if (outTokenBalance < minAmountOut) revert TooSmallAmountOut();\n\n // The `outTokenRecipient` may already have enough in balance, in which case there's no need to transfer\n // to this address the token and everything can be given to the `to` address\n uint256 outTokenBalanceRecipient = outToken.balanceOf(outTokenRecipient);\n if (outTokenBalanceRecipient >= outTokenOwed || to == outTokenRecipient)\n outToken.safeTransfer(to, outTokenBalance);\n else {\n // The `outTokenRecipient` should receive the delta to make sure its end balance is equal to `outTokenOwed`\n // Any leftover in this case is sent to the `to` address\n // The function reverts if it did not obtain more than `outTokenOwed - outTokenBalanceRecipient` from the swap\n outToken.safeTransfer(outTokenRecipient, outTokenOwed - outTokenBalanceRecipient);\n outToken.safeTransfer(to, outTokenBalanceRecipient + outTokenBalance - outTokenOwed);\n }\n // Reusing the `inTokenObtained` variable for the `inToken` balance\n // Sending back the remaining amount of inTokens to the `to` address: it is possible that not the full `inTokenObtained`\n // is swapped to `outToken` if we're using the `1inch` payload\n inTokenObtained = inToken.balanceOf(address(this));\n if (inTokenObtained != 0) inToken.safeTransfer(to, inTokenObtained);\n }\n\n // ============================ GOVERNANCE FUNCTION ============================\n\n /// @notice Changes allowances of this contract for different tokens\n /// @param tokens Addresses of the tokens to allow\n /// @param spenders Addresses to allow transfer\n /// @param amounts Amounts to allow\n function changeAllowance(\n IERC20[] calldata tokens,\n address[] calldata spenders,\n uint256[] calldata amounts\n ) external {\n if (!core.isGovernorOrGuardian(msg.sender)) revert NotGovernorOrGuardian();\n uint256 tokensLength = tokens.length;\n if (tokensLength != spenders.length || tokensLength != amounts.length) revert IncompatibleLengths();\n for (uint256 i; i < tokensLength; ++i) {\n _changeAllowance(tokens[i], spenders[i], amounts[i]);\n }\n }\n\n // ========================= INTERNAL UTILITY FUNCTIONS ========================\n\n /// @notice Internal version of the `_changeAllowance` function\n function _changeAllowance(IERC20 token, address spender, uint256 amount) internal {\n uint256 currentAllowance = token.allowance(address(this), spender);\n // In case `currentAllowance < type(uint256).max / 2` and we want to increase it:\n // Do nothing (to handle tokens that need reapprovals to 0 and save gas)\n if (currentAllowance < amount && currentAllowance < type(uint256).max / 2) {\n token.safeIncreaseAllowance(spender, amount - currentAllowance);\n } else if (currentAllowance > amount) {\n token.safeDecreaseAllowance(spender, currentAllowance - amount);\n }\n }\n\n /// @notice Checks the allowance for a contract and updates it to the max if it is not big enough\n /// @param token Token for which allowance should be checked\n /// @param spender Address to grant allowance to\n /// @param amount Minimum amount of tokens needed for the allowance\n function _checkAllowance(IERC20 token, address spender, uint256 amount) internal {\n uint256 currentAllowance = token.allowance(address(this), spender);\n if (currentAllowance < amount) token.safeIncreaseAllowance(spender, type(uint256).max - currentAllowance);\n }\n\n /// @notice Performs a swap using either Uniswap, 1inch. This function can also stake stETH to wstETH\n /// @param inToken Token to swap\n /// @param amount Amount of tokens to swap\n /// @param swapType Type of the swap to perform\n /// @param args Extra args for the swap: in the case of Uniswap it should be a path, for 1inch it should be\n /// a payload\n /// @dev This function does nothing if `swapType` is None and it simply passes on the `amount` it received\n /// @dev No slippage is specified in the actions given here as a final slippage check is performed\n /// after the call to this function\n function _swap(IERC20 inToken, uint256 amount, SwapType swapType, bytes memory args) internal {\n if (swapType == SwapType.UniswapV3) _swapOnUniswapV3(inToken, amount, args);\n else if (swapType == SwapType.oneInch) _swapOn1inch(inToken, args);\n else if (swapType == SwapType.AngleRouter) _angleRouterActions(inToken, args);\n else if (swapType == SwapType.Leverage) _swapLeverage(args);\n }\n\n /// @notice Performs a UniswapV3 swap\n /// @param inToken Token to swap\n /// @param amount Amount of tokens to swap\n /// @param path Path for the UniswapV3 swap: this encodes the out token that is going to be obtained\n /// @dev This function does not check the out token obtained here: if it is wrongly specified, either\n /// the `swap` function could fail or these tokens could stay on the contract\n function _swapOnUniswapV3(IERC20 inToken, uint256 amount, bytes memory path) internal returns (uint256 amountOut) {\n // We need more than `amount` of allowance to the contract\n _checkAllowance(inToken, address(uniV3Router), amount);\n amountOut = uniV3Router.exactInput(ExactInputParams(path, address(this), block.timestamp, amount, 0));\n }\n\n /// @notice Allows to swap any token to an accepted collateral via 1inch API\n /// @param inToken Token received for the 1inch swap\n /// @param payload Bytes needed for 1inch API\n function _swapOn1inch(IERC20 inToken, bytes memory payload) internal returns (uint256 amountOut) {\n _changeAllowance(inToken, oneInch, type(uint256).max);\n //solhint-disable-next-line\n (bool success, bytes memory result) = oneInch.call(payload);\n if (!success) _revertBytes(result);\n amountOut = abi.decode(result, (uint256));\n }\n\n /// @notice Performs actions with the router contract of the protocol on the corresponding chain\n /// @param inToken Token concerned by the action and for which\n function _angleRouterActions(IERC20 inToken, bytes memory args) internal {\n (ActionType[] memory actions, bytes[] memory actionData) = abi.decode(args, (ActionType[], bytes[]));\n _changeAllowance(inToken, address(angleRouter), type(uint256).max);\n PermitType[] memory permits;\n angleRouter.mixer(permits, actions, actionData);\n }\n\n /// @notice Allows to take leverage or deleverage via a specific contract\n /// @param payload Bytes needed for 1inch API\n /// @dev This function is to be implemented if the swapper concerns a token that requires some actions\n /// not supported by 1inch or UniV3\n function _swapLeverage(bytes memory payload) internal virtual returns (uint256 amountOut) {}\n\n /// @notice Internal function used for error handling\n /// @param errMsg Error message received\n function _revertBytes(bytes memory errMsg) internal pure {\n if (errMsg.length != 0) {\n //solhint-disable-next-line\n assembly {\n revert(add(32, errMsg), mload(errMsg))\n }\n }\n revert EmptyReturnMessage();\n }\n}\n" + }, + "contracts/treasury/Treasury.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\n/*\n * █ \n ***** ▓▓▓ \n * ▓▓▓▓▓▓▓ \n * ///. ▓▓▓▓▓▓▓▓▓▓▓▓▓ \n ***** //////// ▓▓▓▓▓▓▓ \n * ///////////// ▓▓▓ \n ▓▓ ////////////////// █ ▓▓ \n ▓▓ ▓▓ /////////////////////// ▓▓ ▓▓ \n ▓▓ ▓▓ //////////////////////////// ▓▓ ▓▓ \n ▓▓ ▓▓ /////////▓▓▓///////▓▓▓///////// ▓▓ ▓▓ \n ▓▓ ,////////////////////////////////////// ▓▓ ▓▓ \n ▓▓ ////////////////////////////////////////// ▓▓ \n ▓▓ //////////////////////▓▓▓▓///////////////////// \n ,//////////////////////////////////////////////////// \n .////////////////////////////////////////////////////////// \n .//////////////////////////██.,//////////////////////////█ \n .//////////////////////████..,./////////////////////██ \n ...////////////////███████.....,.////////////////███ \n ,.,////////////████████ ........,///////////████ \n .,.,//////█████████ ,.......///////████ \n ,..//████████ ........./████ \n ..,██████ .....,███ \n .██ ,.,█ \n \n \n \n ▓▓ ▓▓▓▓▓▓▓▓▓▓ ▓▓▓▓▓▓▓▓▓▓ ▓▓ ▓▓▓▓▓▓▓▓▓▓ \n ▓▓▓▓▓▓ ▓▓▓ ▓▓▓ ▓▓▓ ▓▓ ▓▓ ▓▓▓▓ \n ▓▓▓ ▓▓▓ ▓▓▓ ▓▓▓ ▓▓▓ ▓▓▓ ▓▓ ▓▓▓▓▓ \n ▓▓▓ ▓▓ ▓▓▓ ▓▓▓ ▓▓▓▓▓▓▓▓▓▓ ▓▓▓▓▓▓▓▓▓▓ ▓▓▓▓▓▓▓▓▓▓ \n*/\n\npragma solidity ^0.8.12;\n\nimport \"@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol\";\nimport \"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\";\nimport \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\n\nimport \"../interfaces/IAgToken.sol\";\nimport \"../interfaces/ICoreBorrow.sol\";\nimport \"../interfaces/IFlashAngle.sol\";\nimport \"../interfaces/ITreasury.sol\";\nimport \"../interfaces/IVaultManager.sol\";\n\n/// @title Treasury\n/// @author Angle Labs, Inc.\n/// @notice Treasury of Angle Borrowing Module doing the accounting across all VaultManagers for\n/// a given stablecoin\ncontract Treasury is ITreasury, Initializable {\n using SafeERC20 for IERC20;\n\n /// @notice Base used for parameter computation\n uint256 public constant BASE_9 = 1e9;\n\n // ================================= REFERENCES ================================\n\n /// @notice Reference to the `CoreBorrow` contract of the module which handles all AccessControl logic\n ICoreBorrow public core;\n /// @notice Flash Loan Module with a minter right on the stablecoin\n IFlashAngle public flashLoanModule;\n /// @inheritdoc ITreasury\n IAgToken public stablecoin;\n /// @notice Address responsible for handling the surplus made by the treasury\n address public surplusManager;\n /// @notice List of the accepted `VaultManager` of the protocol\n address[] public vaultManagerList;\n /// @notice Maps an address to 1 if it was initialized as a `VaultManager` contract\n mapping(address => uint256) public vaultManagerMap;\n\n // ================================= VARIABLES =================================\n\n /// @notice Amount of bad debt (unbacked stablecoin) accumulated across all `VaultManager` contracts\n /// linked to this stablecoin\n uint256 public badDebt;\n /// @notice Surplus amount accumulated by the contract waiting to be distributed to governance. Technically\n /// only a share of this `surplusBuffer` will go to governance. Once a share of the surplus buffer has been\n /// given to governance, then this surplus is reset\n uint256 public surplusBuffer;\n\n // ================================= PARAMETER =================================\n\n /// @notice Share of the `surplusBuffer` distributed to governance (in `BASE_9`)\n uint64 public surplusForGovernance;\n\n // =================================== EVENTS ==================================\n\n event BadDebtUpdated(uint256 badDebtValue);\n event CoreUpdated(address indexed _core);\n event NewTreasurySet(address indexed _treasury);\n event Recovered(address indexed token, address indexed to, uint256 amount);\n event SurplusBufferUpdated(uint256 surplusBufferValue);\n event SurplusForGovernanceUpdated(uint64 _surplusForGovernance);\n event SurplusManagerUpdated(address indexed _surplusManager);\n event VaultManagerToggled(address indexed vaultManager);\n\n // =================================== ERRORS ==================================\n\n error AlreadyVaultManager();\n error InvalidAddress();\n error InvalidTreasury();\n error NotCore();\n error NotGovernor();\n error NotVaultManager();\n error RightsNotRemoved();\n error TooBigAmount();\n error TooHighParameterValue();\n error ZeroAddress();\n\n // ================================== MODIFIER =================================\n\n /// @notice Checks whether the `msg.sender` has the governor role or not\n modifier onlyGovernor() {\n if (!core.isGovernor(msg.sender)) revert NotGovernor();\n _;\n }\n\n /// @notice Initializes the treasury contract\n /// @param _core Address of the `CoreBorrow` contract of the module\n /// @param _stablecoin Address of the stablecoin\n function initialize(ICoreBorrow _core, IAgToken _stablecoin) public virtual initializer {\n if (address(_stablecoin) == address(0) || address(_core) == address(0)) revert ZeroAddress();\n core = _core;\n stablecoin = _stablecoin;\n }\n\n /// @custom:oz-upgrades-unsafe-allow constructor\n constructor() initializer {}\n\n // =============================== VIEW FUNCTIONS ==============================\n\n /// @inheritdoc ITreasury\n function isGovernor(address admin) external view returns (bool) {\n return core.isGovernor(admin);\n }\n\n /// @inheritdoc ITreasury\n function isGovernorOrGuardian(address admin) external view returns (bool) {\n return core.isGovernorOrGuardian(admin);\n }\n\n /// @inheritdoc ITreasury\n function isVaultManager(address _vaultManager) external view returns (bool) {\n return vaultManagerMap[_vaultManager] == 1;\n }\n\n // ===================== EXTERNAL PERMISSIONLESS FUNCTIONS =====================\n\n /// @notice Fetches the surplus accrued across all the `VaultManager` contracts controlled by this\n /// `Treasury` contract as well as from the fees of the `FlashLoan` module\n /// @return Surplus buffer value at the end of the call\n /// @return Bad debt value at the end of the call\n /// @dev This function pools surplus and bad debt across all contracts and then updates the `surplusBuffer`\n /// (or the `badDebt` if more losses were made than profits)\n function fetchSurplusFromAll() external returns (uint256, uint256) {\n return _fetchSurplusFromAll();\n }\n\n /// @notice Fetches the surplus accrued in the flash loan module and updates the `surplusBuffer`\n /// @return Surplus buffer value at the end of the call\n /// @return Bad debt value at the end of the call\n /// @dev This function fails if the `flashLoanModule` has not been initialized yet\n function fetchSurplusFromFlashLoan() external returns (uint256, uint256) {\n uint256 surplusBufferValue = surplusBuffer + flashLoanModule.accrueInterestToTreasury(stablecoin);\n return _updateSurplusAndBadDebt(surplusBufferValue, badDebt);\n }\n\n /// @notice Pushes the surplus buffer to the `surplusManager` contract\n /// @return governanceAllocation Amount transferred to governance\n /// @dev It makes sure to fetch the surplus from all the contracts handled by this treasury to avoid\n /// the situation where rewards are still distributed to governance even though a `VaultManager` has made\n /// a big loss\n /// @dev Typically this function is to be called once every week by a keeper to distribute rewards to veANGLE\n /// holders\n /// @dev `stablecoin` must be an AgToken and hence `transfer` reverts if the call is not successful\n function pushSurplus() external returns (uint256 governanceAllocation) {\n address _surplusManager = surplusManager;\n if (_surplusManager == address(0)) {\n revert ZeroAddress();\n }\n (uint256 surplusBufferValue, ) = _fetchSurplusFromAll();\n surplusBuffer = 0;\n emit SurplusBufferUpdated(0);\n governanceAllocation = (surplusForGovernance * surplusBufferValue) / BASE_9;\n stablecoin.transfer(_surplusManager, governanceAllocation);\n }\n\n /// @notice Updates the bad debt of the protocol in case where the protocol has accumulated some revenue\n /// from an external source\n /// @param amount Amount to reduce the bad debt of\n /// @return badDebtValue Value of the bad debt at the end of the call\n /// @dev If the protocol has made a loss and managed to make some profits to recover for this loss (through\n /// a program like Olympus Pro), then this function needs to be called\n /// @dev `badDebt` is simply reduced here by burning stablecoins\n /// @dev It is impossible to burn more than the `badDebt` otherwise this function could be used to manipulate\n /// the `surplusBuffer` and hence the amount going to governance\n function updateBadDebt(uint256 amount) external returns (uint256 badDebtValue) {\n stablecoin.burnSelf(amount, address(this));\n badDebtValue = badDebt - amount;\n badDebt = badDebtValue;\n emit BadDebtUpdated(badDebtValue);\n }\n\n // ========================= INTERNAL UTILITY FUNCTIONS ========================\n\n /// @notice Internal version of the `fetchSurplusFromAll` function\n function _fetchSurplusFromAll() internal returns (uint256 surplusBufferValue, uint256 badDebtValue) {\n (surplusBufferValue, badDebtValue) = _fetchSurplusFromList(vaultManagerList);\n // It will fail anyway if the `flashLoanModule` is the zero address\n if (address(flashLoanModule) != address(0))\n surplusBufferValue += flashLoanModule.accrueInterestToTreasury(stablecoin);\n (surplusBufferValue, badDebtValue) = _updateSurplusAndBadDebt(surplusBufferValue, badDebtValue);\n }\n\n /// @notice Fetches the surplus from a list of `VaultManager` addresses without modifying the\n /// `surplusBuffer` and `badDebtValue`\n /// @return surplusBufferValue Value the `surplusBuffer` should have after the call if it was updated\n /// @return badDebtValue Value the `badDebt` should have after the call if it was updated\n /// @dev This internal function is never to be called alone, and should always be called in conjunction\n /// with the `_updateSurplusAndBadDebt` function\n function _fetchSurplusFromList(\n address[] memory vaultManagers\n ) internal returns (uint256 surplusBufferValue, uint256 badDebtValue) {\n badDebtValue = badDebt;\n surplusBufferValue = surplusBuffer;\n uint256 newSurplus;\n uint256 newBadDebt;\n uint256 vaultManagersLength = vaultManagers.length;\n for (uint256 i; i < vaultManagersLength; ++i) {\n (newSurplus, newBadDebt) = IVaultManager(vaultManagers[i]).accrueInterestToTreasury();\n surplusBufferValue += newSurplus;\n badDebtValue += newBadDebt;\n }\n }\n\n /// @notice Updates the `surplusBuffer` and the `badDebt` from updated values after calling the flash loan module\n /// and/or a list of `VaultManager` contracts\n /// @param surplusBufferValue Value of the surplus buffer after the calls to the different modules\n /// @param badDebtValue Value of the bad debt after the calls to the different modules\n /// @return Value of the `surplusBuffer` corrected from the `badDebt`\n /// @return Value of the `badDebt` corrected from the `surplusBuffer` and from the surplus the treasury had accumulated\n /// previously\n /// @dev When calling this function, it is possible that there is a positive `surplusBufferValue` and `badDebtValue`,\n /// this function tries to reconcile both values and makes sure that we either have surplus or bad debt but not both\n /// at the same time\n function _updateSurplusAndBadDebt(\n uint256 surplusBufferValue,\n uint256 badDebtValue\n ) internal returns (uint256, uint256) {\n if (badDebtValue != 0) {\n // If we have bad debt we need to burn stablecoins that accrued to the protocol\n // We still need to make sure that we're not burning too much or as much as we can if the debt is big\n uint256 balance = stablecoin.balanceOf(address(this));\n // We are going to burn `min(balance, badDebtValue)`\n uint256 toBurn = balance <= badDebtValue ? balance : badDebtValue;\n stablecoin.burnSelf(toBurn, address(this));\n // If we burned more than `surplusBuffer`, we set surplus to 0. It means we had to tap into Treasury reserve\n surplusBufferValue = toBurn >= surplusBufferValue ? 0 : surplusBufferValue - toBurn;\n badDebtValue -= toBurn;\n // Note here that the stablecoin balance is necessarily greater than the surplus buffer, and so if\n // `surplusBuffer >= toBurn`, then `badDebtValue = toBurn`\n }\n surplusBuffer = surplusBufferValue;\n badDebt = badDebtValue;\n emit SurplusBufferUpdated(surplusBufferValue);\n emit BadDebtUpdated(badDebtValue);\n return (surplusBufferValue, badDebtValue);\n }\n\n /// @notice Adds a new `VaultManager`\n /// @param vaultManager `VaultManager` contract to add\n /// @dev This contract should have already been initialized with a correct treasury address\n /// @dev It's this function that gives the minter right to the `VaultManager`\n function _addVaultManager(address vaultManager) internal virtual {\n if (vaultManagerMap[vaultManager] == 1) revert AlreadyVaultManager();\n if (address(IVaultManager(vaultManager).treasury()) != address(this)) revert InvalidTreasury();\n vaultManagerMap[vaultManager] = 1;\n vaultManagerList.push(vaultManager);\n emit VaultManagerToggled(vaultManager);\n stablecoin.addMinter(vaultManager);\n }\n\n // ============================= GOVERNOR FUNCTIONS ============================\n\n /// @notice Adds a new minter for the stablecoin\n /// @param minter Minter address to add\n function addMinter(address minter) external virtual onlyGovernor {\n if (minter == address(0)) revert ZeroAddress();\n stablecoin.addMinter(minter);\n }\n\n /// @notice External wrapper for `_addVaultManager`\n function addVaultManager(address vaultManager) external virtual onlyGovernor {\n _addVaultManager(vaultManager);\n }\n\n /// @notice Removes a minter from the stablecoin contract\n /// @param minter Minter address to remove\n function removeMinter(address minter) external virtual onlyGovernor {\n // To remove the minter role to a `VaultManager` you have to go through the `removeVaultManager` function\n if (vaultManagerMap[minter] == 1) revert InvalidAddress();\n stablecoin.removeMinter(minter);\n }\n\n /// @notice Removes a `VaultManager`\n /// @param vaultManager `VaultManager` contract to remove\n /// @dev A removed `VaultManager` loses its minter right on the stablecoin\n function removeVaultManager(address vaultManager) external onlyGovernor {\n if (vaultManagerMap[vaultManager] != 1) revert NotVaultManager();\n delete vaultManagerMap[vaultManager];\n // deletion from `vaultManagerList` loop\n uint256 vaultManagerListLength = vaultManagerList.length;\n for (uint256 i; i < vaultManagerListLength - 1; ++i) {\n if (vaultManagerList[i] == vaultManager) {\n // replace the `VaultManager` to remove with the last of the list\n vaultManagerList[i] = vaultManagerList[vaultManagerListLength - 1];\n break;\n }\n }\n // remove last element in array\n vaultManagerList.pop();\n emit VaultManagerToggled(vaultManager);\n stablecoin.removeMinter(vaultManager);\n }\n\n /// @notice Allows to recover any ERC20 token, including the stablecoin handled by this contract, and to send it\n /// to a contract\n /// @param tokenAddress Address of the token to recover\n /// @param to Address of the contract to send collateral to\n /// @param amountToRecover Amount of collateral to transfer\n /// @dev It is impossible to recover the stablecoin of the protocol if there is some bad debt for it\n /// @dev In this case, the function makes sure to fetch the surplus/bad debt from all the `VaultManager` contracts\n /// and from the flash loan module\n /// @dev If the token to recover is the stablecoin, tokens recovered are fetched\n /// from the surplus and not from the `surplusBuffer`\n function recoverERC20(address tokenAddress, address to, uint256 amountToRecover) external onlyGovernor {\n // Cannot recover stablecoin if badDebt or tap into the surplus buffer\n if (tokenAddress == address(stablecoin)) {\n _fetchSurplusFromAll();\n // If balance is non zero then this means, after the call to `fetchSurplusFromAll` that\n // bad debt is necessarily null\n uint256 balance = stablecoin.balanceOf(address(this));\n if (amountToRecover + surplusBuffer > balance) revert TooBigAmount();\n stablecoin.transfer(to, amountToRecover);\n } else {\n IERC20(tokenAddress).safeTransfer(to, amountToRecover);\n }\n emit Recovered(tokenAddress, to, amountToRecover);\n }\n\n /// @notice Changes the treasury contract and communicates this change to all `VaultManager` contract\n /// @param _treasury New treasury address for this stablecoin\n /// @dev This function is basically a way to remove rights to this contract and grant them to a new one\n /// @dev It could be used to set a new core contract\n function setTreasury(address _treasury) external virtual onlyGovernor {\n if (ITreasury(_treasury).stablecoin() != stablecoin) revert InvalidTreasury();\n // Flash loan role should be removed before calling this function\n if (core.isFlashLoanerTreasury(address(this))) revert RightsNotRemoved();\n emit NewTreasurySet(_treasury);\n uint256 vaultManagerListLength = vaultManagerList.length;\n for (uint256 i; i < vaultManagerListLength; ++i) {\n IVaultManager(vaultManagerList[i]).setTreasury(_treasury);\n }\n // A `TreasuryUpdated` event is triggered in the stablecoin\n stablecoin.setTreasury(_treasury);\n }\n\n /// @notice Sets the `surplusForGovernance` parameter\n /// @param _surplusForGovernance New value of the parameter\n /// @dev To pause surplus distribution, governance needs to set a zero value for `surplusForGovernance`\n /// which means\n function setSurplusForGovernance(uint64 _surplusForGovernance) external onlyGovernor {\n if (_surplusForGovernance > BASE_9) revert TooHighParameterValue();\n surplusForGovernance = _surplusForGovernance;\n emit SurplusForGovernanceUpdated(_surplusForGovernance);\n }\n\n /// @notice Sets the `surplusManager` contract responsible for handling the surplus of the\n /// protocol\n /// @param _surplusManager New address responsible for handling the surplus\n function setSurplusManager(address _surplusManager) external onlyGovernor {\n if (_surplusManager == address(0)) revert ZeroAddress();\n surplusManager = _surplusManager;\n emit SurplusManagerUpdated(_surplusManager);\n }\n\n /// @notice Sets a new `core` contract\n /// @dev This function should typically be called on all treasury contracts after the `setCore`\n /// function has been called on the `CoreBorrow` contract\n /// @dev One sanity check that can be performed here is to verify whether at least the governor\n /// calling the contract is still a governor in the new core\n function setCore(ICoreBorrow _core) external onlyGovernor {\n if (!_core.isGovernor(msg.sender)) revert NotGovernor();\n core = ICoreBorrow(_core);\n emit CoreUpdated(address(_core));\n }\n\n /// @inheritdoc ITreasury\n function setFlashLoanModule(address _flashLoanModule) external {\n if (msg.sender != address(core)) revert NotCore();\n address oldFlashLoanModule = address(flashLoanModule);\n flashLoanModule = IFlashAngle(_flashLoanModule);\n if (oldFlashLoanModule != address(0)) {\n stablecoin.removeMinter(oldFlashLoanModule);\n }\n // We may want to cancel the module\n if (_flashLoanModule != address(0)) {\n stablecoin.addMinter(_flashLoanModule);\n }\n }\n}\n" + }, + "contracts/ui-helpers/AngleBorrowHelpers.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\n/*\n * █ \n ***** ▓▓▓ \n * ▓▓▓▓▓▓▓ \n * ///. ▓▓▓▓▓▓▓▓▓▓▓▓▓ \n ***** //////// ▓▓▓▓▓▓▓ \n * ///////////// ▓▓▓ \n ▓▓ ////////////////// █ ▓▓ \n ▓▓ ▓▓ /////////////////////// ▓▓ ▓▓ \n ▓▓ ▓▓ //////////////////////////// ▓▓ ▓▓ \n ▓▓ ▓▓ /////////▓▓▓///////▓▓▓///////// ▓▓ ▓▓ \n ▓▓ ,////////////////////////////////////// ▓▓ ▓▓ \n ▓▓ ////////////////////////////////////////// ▓▓ \n ▓▓ //////////////////////▓▓▓▓///////////////////// \n ,//////////////////////////////////////////////////// \n .////////////////////////////////////////////////////////// \n .//////////////////////////██.,//////////////////////////█ \n .//////////////////////████..,./////////////////////██ \n ...////////////////███████.....,.////////////////███ \n ,.,////////////████████ ........,///////////████ \n .,.,//////█████████ ,.......///////████ \n ,..//████████ ........./████ \n ..,██████ .....,███ \n .██ ,.,█ \n \n \n \n ▓▓ ▓▓▓▓▓▓▓▓▓▓ ▓▓▓▓▓▓▓▓▓▓ ▓▓ ▓▓▓▓▓▓▓▓▓▓ \n ▓▓▓▓▓▓ ▓▓▓ ▓▓▓ ▓▓▓ ▓▓ ▓▓ ▓▓▓▓ \n ▓▓▓ ▓▓▓ ▓▓▓ ▓▓▓ ▓▓▓ ▓▓▓ ▓▓ ▓▓▓▓▓ \n ▓▓▓ ▓▓ ▓▓▓ ▓▓▓ ▓▓▓▓▓▓▓▓▓▓ ▓▓▓▓▓▓▓▓▓▓ ▓▓▓▓▓▓▓▓▓▓ \n*/\n\nimport \"@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol\";\nimport \"../interfaces/IVaultManager.sol\";\n\npragma solidity ^0.8.12;\n\n/// @title AngleBorrowHelpers\n/// @author Angle Labs, Inc.\n/// @notice Contract with view functions designed to facilitate integrations on the Borrow module of the Angle Protocol\n/// @dev This contract only contains view functions to be queried off-chain. It was thus not optimized for gas consumption\ncontract AngleBorrowHelpers is Initializable {\n /// @notice Returns all the vaults owned or controlled (under the form of approval) by an address\n /// @param vaultManager VaultManager address to query vaultIDs on\n /// @param spender Address for which vault ownerships should be checked\n /// @return List of `vaultID` controlled by this address\n /// @return Count of vaults owned by the address\n /// @dev This function is never to be called on-chain since it iterates over all vaultIDs. It is here\n /// to reduce dependency on an external graph to link an ID to its owner\n function getControlledVaults(\n IVaultManager vaultManager,\n address spender\n ) external view returns (uint256[] memory, uint256) {\n uint256 arraySize = vaultManager.vaultIDCount();\n uint256[] memory vaultsControlled = new uint256[](arraySize);\n uint256 count;\n for (uint256 i = 1; i <= arraySize; ++i) {\n try vaultManager.isApprovedOrOwner(spender, i) returns (bool _isApprovedOrOwner) {\n if (_isApprovedOrOwner) {\n vaultsControlled[count] = i;\n count += 1;\n }\n } catch {\n continue;\n } // This happens if nobody owns the vaultID=i (if there has been a burn)\n }\n return (vaultsControlled, count);\n }\n\n /// @custom:oz-upgrades-unsafe-allow constructor\n constructor() initializer {}\n}\n" + }, + "contracts/ui-helpers/AngleHelpers.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\nimport \"../interfaces/IAngleRouter.sol\";\nimport \"../interfaces/coreModule/IAgTokenMainnet.sol\";\nimport \"../interfaces/coreModule/ICore.sol\";\nimport \"../interfaces/coreModule/IOracleCore.sol\";\nimport \"../interfaces/coreModule/IPerpetualManager.sol\";\nimport \"../interfaces/coreModule/IPoolManager.sol\";\nimport \"../interfaces/coreModule/IStableMaster.sol\";\nimport \"./AngleBorrowHelpers.sol\";\n\npragma solidity ^0.8.12;\n\nstruct Parameters {\n SLPData slpData;\n MintBurnData feeData;\n PerpetualManagerFeeData perpFeeData;\n PerpetualManagerParamData perpParam;\n}\n\nstruct PerpetualManagerFeeData {\n uint64[] xHAFeesDeposit;\n uint64[] yHAFeesDeposit;\n uint64[] xHAFeesWithdraw;\n uint64[] yHAFeesWithdraw;\n uint64 haBonusMalusDeposit;\n uint64 haBonusMalusWithdraw;\n}\n\nstruct PerpetualManagerParamData {\n uint64 maintenanceMargin;\n uint64 maxLeverage;\n uint64 targetHAHedge;\n uint64 limitHAHedge;\n uint64 lockTime;\n}\n\nstruct CollateralAddresses {\n address stableMaster;\n address poolManager;\n address perpetualManager;\n address sanToken;\n address oracle;\n address gauge;\n address feeManager;\n address[] strategies;\n}\n\n/// @title AngleHelpers\n/// @author Angle Labs, Inc.\n/// @notice Contract with view functions designed to facilitate integrations on the Core and Borrow module of the Angle Protocol\n/// @dev This contract only contains view functions to be queried off-chain. It was thus not optimized for gas consumption\ncontract AngleHelpers is AngleBorrowHelpers {\n // =========================== HELPER VIEW FUNCTIONS ===========================\n\n /// @notice Gives the amount of `agToken` you'd be getting if you were executing in the same block a mint transaction\n /// with `amount` of `collateral` in the Core module of the Angle protocol as well as the value of the fees\n /// (in `BASE_PARAMS`) that would be applied during the mint\n /// @return Amount of `agToken` that would be obtained with a mint transaction in the same block\n /// @return Percentage of fees that would be taken during a mint transaction in the same block\n /// @dev This function reverts if the mint transaction was to revert in the same conditions (without taking into account\n /// potential approval problems to the `StableMaster` contract)\n function previewMintAndFees(\n uint256 amount,\n address agToken,\n address collateral\n ) external view returns (uint256, uint256) {\n return _previewMintAndFees(amount, agToken, collateral);\n }\n\n /// @notice Gives the amount of `collateral` you'd be getting if you were executing in the same block a burn transaction\n /// with `amount` of `agToken` in the Core module of the Angle protocol as well as the value of the fees\n /// (in `BASE_PARAMS`) that would be applied during the burn\n /// @return Amount of `collateral` that would be obtained with a burn transaction in the same block\n /// @return Percentage of fees that would be taken during a burn transaction in the same block\n /// @dev This function reverts if the burn transaction was to revert in the same conditions (without taking into account\n /// potential approval problems to the `StableMaster` contract or agToken balance prior to the call)\n function previewBurnAndFees(\n uint256 amount,\n address agToken,\n address collateral\n ) external view returns (uint256, uint256) {\n return _previewBurnAndFees(amount, agToken, collateral);\n }\n\n /// @notice Returns all the addresses associated to the (`agToken`,`collateral`) pair given\n /// @return addresses A struct with all the addresses associated in the Core module\n function getCollateralAddresses(\n address agToken,\n address collateral\n ) external view returns (CollateralAddresses memory addresses) {\n address stableMaster = IAgTokenMainnet(agToken).stableMaster();\n (address poolManager, address perpetualManager, address sanToken, address gauge) = ROUTER.mapPoolManagers(\n stableMaster,\n collateral\n );\n (, , , IOracleCore oracle, , , , , ) = IStableMaster(stableMaster).collateralMap(poolManager);\n addresses.stableMaster = stableMaster;\n addresses.poolManager = poolManager;\n addresses.perpetualManager = perpetualManager;\n addresses.sanToken = sanToken;\n addresses.gauge = gauge;\n addresses.oracle = address(oracle);\n addresses.feeManager = IPoolManager(poolManager).feeManager();\n\n uint256 length;\n while (true) {\n try IPoolManager(poolManager).strategyList(length) returns (address) {\n length += 1;\n } catch {\n break;\n }\n }\n address[] memory strategies = new address[](length);\n for (uint256 i; i < length; ++i) {\n strategies[i] = IPoolManager(poolManager).strategyList(i);\n }\n addresses.strategies = strategies;\n }\n\n /// @notice Gets the addresses of all the `StableMaster` contracts and their associated `AgToken` addresses\n /// @return List of the `StableMaster` addresses of the Angle protocol\n /// @return List of the `AgToken` addresses of the protocol\n /// @dev The place of an agToken address in the list is the same as the corresponding `StableMaster` address\n function getStablecoinAddresses() external view returns (address[] memory, address[] memory) {\n address[] memory stableMasterAddresses = CORE.stablecoinList();\n address[] memory agTokenAddresses = new address[](stableMasterAddresses.length);\n for (uint256 i; i < stableMasterAddresses.length; ++i) {\n agTokenAddresses[i] = IStableMaster(stableMasterAddresses[i]).agToken();\n }\n return (stableMasterAddresses, agTokenAddresses);\n }\n\n /// @notice Returns most of the governance parameters associated to the (`agToken`,`collateral`) pair given\n /// @return params Struct with most of the parameters in the `StableMaster` and `PerpetualManager` contracts\n /// @dev Check out the struct `Parameters` for the meaning of the return values\n function getCollateralParameters(\n address agToken,\n address collateral\n ) external view returns (Parameters memory params) {\n (address stableMaster, address poolManager) = _getStableMasterAndPoolManager(agToken, collateral);\n (\n ,\n ,\n IPerpetualManager perpetualManager,\n ,\n ,\n ,\n ,\n SLPData memory slpData,\n MintBurnData memory feeData\n ) = IStableMaster(stableMaster).collateralMap(poolManager);\n\n params.slpData = slpData;\n params.feeData = feeData;\n params.perpParam.maintenanceMargin = perpetualManager.maintenanceMargin();\n params.perpParam.maxLeverage = perpetualManager.maxLeverage();\n params.perpParam.targetHAHedge = perpetualManager.targetHAHedge();\n params.perpParam.limitHAHedge = perpetualManager.limitHAHedge();\n params.perpParam.lockTime = perpetualManager.lockTime();\n\n params.perpFeeData.haBonusMalusDeposit = perpetualManager.haBonusMalusDeposit();\n params.perpFeeData.haBonusMalusWithdraw = perpetualManager.haBonusMalusWithdraw();\n\n uint256 length;\n while (true) {\n try perpetualManager.xHAFeesDeposit(length) returns (uint64) {\n length += 1;\n } catch {\n break;\n }\n }\n uint64[] memory data = new uint64[](length);\n uint64[] memory data2 = new uint64[](length);\n for (uint256 i; i < length; ++i) {\n data[i] = perpetualManager.xHAFeesDeposit(i);\n data2[i] = perpetualManager.yHAFeesDeposit(i);\n }\n params.perpFeeData.xHAFeesDeposit = data;\n params.perpFeeData.yHAFeesDeposit = data2;\n\n length = 0;\n while (true) {\n try perpetualManager.xHAFeesWithdraw(length) returns (uint64) {\n length += 1;\n } catch {\n break;\n }\n }\n data = new uint64[](length);\n data2 = new uint64[](length);\n for (uint256 i; i < length; ++i) {\n data[i] = perpetualManager.xHAFeesWithdraw(i);\n data2[i] = perpetualManager.yHAFeesWithdraw(i);\n }\n params.perpFeeData.xHAFeesWithdraw = data;\n params.perpFeeData.yHAFeesWithdraw = data2;\n }\n\n /// @notice Returns the address of the poolManager associated to an (`agToken`, `collateral`) pair\n /// in the Core module of the protocol\n function getPoolManager(address agToken, address collateral) public view returns (address poolManager) {\n (, poolManager) = _getStableMasterAndPoolManager(agToken, collateral);\n }\n\n // ============================= REPLICA FUNCTIONS =============================\n // These replicate what is done in the other contracts of the protocol\n\n function _previewBurnAndFees(\n uint256 amount,\n address agToken,\n address collateral\n ) internal view returns (uint256 amountForUserInCollat, uint256 feePercent) {\n (address stableMaster, address poolManager) = _getStableMasterAndPoolManager(agToken, collateral);\n (\n address token,\n ,\n IPerpetualManager perpetualManager,\n IOracleCore oracle,\n uint256 stocksUsers,\n ,\n uint256 collatBase,\n ,\n MintBurnData memory feeData\n ) = IStableMaster(stableMaster).collateralMap(poolManager);\n if (token == address(0) || IStableMaster(stableMaster).paused(keccak256(abi.encodePacked(STABLE, poolManager))))\n revert NotInitialized();\n if (amount > stocksUsers) revert InvalidAmount();\n\n if (feeData.xFeeBurn.length == 1) {\n feePercent = feeData.yFeeBurn[0];\n } else {\n bytes memory data = abi.encode(address(perpetualManager), feeData.targetHAHedge);\n uint64 hedgeRatio = _computeHedgeRatio(stocksUsers - amount, data);\n feePercent = _piecewiseLinear(hedgeRatio, feeData.xFeeBurn, feeData.yFeeBurn);\n }\n feePercent = (feePercent * feeData.bonusMalusBurn) / BASE_PARAMS;\n\n amountForUserInCollat = (amount * (BASE_PARAMS - feePercent) * collatBase) / (oracle.readUpper() * BASE_PARAMS);\n }\n\n function _previewMintAndFees(\n uint256 amount,\n address agToken,\n address collateral\n ) internal view returns (uint256 amountForUserInStable, uint256 feePercent) {\n (address stableMaster, address poolManager) = _getStableMasterAndPoolManager(agToken, collateral);\n (\n address token,\n ,\n IPerpetualManager perpetualManager,\n IOracleCore oracle,\n uint256 stocksUsers,\n ,\n ,\n ,\n MintBurnData memory feeData\n ) = IStableMaster(stableMaster).collateralMap(poolManager);\n if (token == address(0) || IStableMaster(stableMaster).paused(keccak256(abi.encodePacked(STABLE, poolManager))))\n revert NotInitialized();\n\n amountForUserInStable = oracle.readQuoteLower(amount);\n\n if (feeData.xFeeMint.length == 1) feePercent = feeData.yFeeMint[0];\n else {\n bytes memory data = abi.encode(address(perpetualManager), feeData.targetHAHedge);\n uint64 hedgeRatio = _computeHedgeRatio(amountForUserInStable + stocksUsers, data);\n feePercent = _piecewiseLinear(hedgeRatio, feeData.xFeeMint, feeData.yFeeMint);\n }\n feePercent = (feePercent * feeData.bonusMalusMint) / BASE_PARAMS;\n\n amountForUserInStable = (amountForUserInStable * (BASE_PARAMS - feePercent)) / BASE_PARAMS;\n if (stocksUsers + amountForUserInStable > feeData.capOnStableMinted) revert InvalidAmount();\n }\n\n // ============================= UTILITY FUNCTIONS =============================\n // These utility functions are taken from other contracts of the protocol\n\n function _computeHedgeRatio(uint256 newStocksUsers, bytes memory data) internal view returns (uint64 ratio) {\n (address perpetualManager, uint64 targetHAHedge) = abi.decode(data, (address, uint64));\n uint256 totalHedgeAmount = IPerpetualManager(perpetualManager).totalHedgeAmount();\n newStocksUsers = (targetHAHedge * newStocksUsers) / BASE_PARAMS;\n if (newStocksUsers > totalHedgeAmount) ratio = uint64((totalHedgeAmount * BASE_PARAMS) / newStocksUsers);\n else ratio = uint64(BASE_PARAMS);\n }\n\n function _piecewiseLinear(uint64 x, uint64[] memory xArray, uint64[] memory yArray) internal pure returns (uint64) {\n if (x >= xArray[xArray.length - 1]) {\n return yArray[xArray.length - 1];\n } else if (x <= xArray[0]) {\n return yArray[0];\n } else {\n uint256 lower;\n uint256 upper = xArray.length - 1;\n uint256 mid;\n while (upper - lower > 1) {\n mid = lower + (upper - lower) / 2;\n if (xArray[mid] <= x) {\n lower = mid;\n } else {\n upper = mid;\n }\n }\n if (yArray[upper] > yArray[lower]) {\n return\n yArray[lower] +\n ((yArray[upper] - yArray[lower]) * (x - xArray[lower])) /\n (xArray[upper] - xArray[lower]);\n } else {\n return\n yArray[lower] -\n ((yArray[lower] - yArray[upper]) * (x - xArray[lower])) /\n (xArray[upper] - xArray[lower]);\n }\n }\n }\n\n function _getStableMasterAndPoolManager(\n address agToken,\n address collateral\n ) internal view returns (address stableMaster, address poolManager) {\n stableMaster = IAgTokenMainnet(agToken).stableMaster();\n (poolManager, , , ) = ROUTER.mapPoolManagers(stableMaster, collateral);\n }\n\n // ========================= CONSTANTS AND INITIALIZERS ========================\n\n IAngleRouter public constant ROUTER = IAngleRouter(0xBB755240596530be0c1DE5DFD77ec6398471561d);\n ICore public constant CORE = ICore(0x61ed74de9Ca5796cF2F8fD60D54160D47E30B7c3);\n\n bytes32 public constant STABLE = keccak256(\"STABLE\");\n uint256 public constant BASE_PARAMS = 10 ** 9;\n\n error NotInitialized();\n error InvalidAmount();\n}\n" + }, + "contracts/utils/Constants.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\nerror InsufficientAssets();\n\n/// @title Constants\n/// @author Angle Labs, Inc.\n/// @notice Constants and errors for Angle Protocol contracts\ncontract Constants {\n uint256 internal constant _BASE_9 = 1e9;\n uint256 internal constant _BASE_18 = 1e18;\n uint256 internal constant _BASE_27 = 1e27;\n uint256 internal constant _BASE_36 = 1e36;\n}\n" + }, + "contracts/vaultManager/VaultManagerERC721.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\nimport \"./VaultManagerStorage.sol\";\n\n/// @title VaultManagerERC721\n/// @author Angle Labs, Inc.\n/// @dev Base ERC721 Implementation of VaultManager\nabstract contract VaultManagerERC721 is IERC721MetadataUpgradeable, VaultManagerStorage {\n using SafeERC20 for IERC20;\n using Address for address;\n\n /// @inheritdoc IERC721MetadataUpgradeable\n string public name;\n /// @inheritdoc IERC721MetadataUpgradeable\n string public symbol;\n\n // ================================= MODIFIERS =================================\n\n /// @notice Checks if the person interacting with the vault with `vaultID` is approved\n /// @param caller Address of the person seeking to interact with the vault\n /// @param vaultID ID of the concerned vault\n modifier onlyApprovedOrOwner(address caller, uint256 vaultID) {\n if (!_isApprovedOrOwner(caller, vaultID)) revert NotApproved();\n _;\n }\n\n // ================================ ERC721 LOGIC ===============================\n\n /// @notice Checks whether a given address is approved for a vault or owns this vault\n /// @param spender Address for which vault ownership should be checked\n /// @param vaultID ID of the vault to check\n /// @return Whether the `spender` address owns or is approved for `vaultID`\n function isApprovedOrOwner(address spender, uint256 vaultID) external view returns (bool) {\n return _isApprovedOrOwner(spender, vaultID);\n }\n\n /// @inheritdoc IERC721MetadataUpgradeable\n function tokenURI(uint256 vaultID) external view returns (string memory) {\n if (!_exists(vaultID)) revert NonexistentVault();\n // There is no vault with `vaultID` equal to 0, so the following variable is\n // always greater than zero\n uint256 temp = vaultID;\n uint256 digits;\n while (temp != 0) {\n ++digits;\n temp /= 10;\n }\n bytes memory buffer = new bytes(digits);\n while (vaultID != 0) {\n digits -= 1;\n buffer[digits] = bytes1(uint8(48 + uint256(vaultID % 10)));\n vaultID /= 10;\n }\n return bytes(_baseURI).length != 0 ? string(abi.encodePacked(_baseURI, string(buffer))) : \"\";\n }\n\n /// @inheritdoc IERC721Upgradeable\n function balanceOf(address owner) external view returns (uint256) {\n if (owner == address(0)) revert ZeroAddress();\n return _balances[owner];\n }\n\n /// @inheritdoc IERC721Upgradeable\n function ownerOf(uint256 vaultID) external view returns (address) {\n return _ownerOf(vaultID);\n }\n\n /// @inheritdoc IERC721Upgradeable\n function approve(address to, uint256 vaultID) external {\n address owner = _ownerOf(vaultID);\n if (to == owner) revert ApprovalToOwner();\n if (msg.sender != owner && !isApprovedForAll(owner, msg.sender)) revert NotApproved();\n\n _approve(to, vaultID);\n }\n\n /// @inheritdoc IERC721Upgradeable\n function getApproved(uint256 vaultID) external view returns (address) {\n if (!_exists(vaultID)) revert NonexistentVault();\n return _getApproved(vaultID);\n }\n\n /// @inheritdoc IERC721Upgradeable\n function setApprovalForAll(address operator, bool approved) external {\n _setApprovalForAll(msg.sender, operator, approved);\n }\n\n /// @inheritdoc IERC721Upgradeable\n function isApprovedForAll(address owner, address operator) public view returns (bool) {\n return _operatorApprovals[owner][operator] == 1;\n }\n\n /// @inheritdoc IERC721Upgradeable\n function transferFrom(address from, address to, uint256 vaultID) external onlyApprovedOrOwner(msg.sender, vaultID) {\n _transfer(from, to, vaultID);\n }\n\n /// @inheritdoc IERC721Upgradeable\n function safeTransferFrom(address from, address to, uint256 vaultID) external {\n safeTransferFrom(from, to, vaultID, \"\");\n }\n\n /// @inheritdoc IERC721Upgradeable\n function safeTransferFrom(\n address from,\n address to,\n uint256 vaultID,\n bytes memory _data\n ) public onlyApprovedOrOwner(msg.sender, vaultID) {\n _safeTransfer(from, to, vaultID, _data);\n }\n\n // ================================ ERC165 LOGIC ===============================\n\n /// @inheritdoc IERC165Upgradeable\n function supportsInterface(bytes4 interfaceId) external pure returns (bool) {\n return\n interfaceId == type(IERC721MetadataUpgradeable).interfaceId ||\n interfaceId == type(IERC721Upgradeable).interfaceId ||\n interfaceId == type(IVaultManager).interfaceId ||\n interfaceId == type(IERC165Upgradeable).interfaceId;\n }\n\n // ================== INTERNAL FUNCTIONS FOR THE ERC721 LOGIC ==================\n\n /// @notice Internal version of the `ownerOf` function\n function _ownerOf(uint256 vaultID) internal view returns (address owner) {\n owner = _owners[vaultID];\n if (owner == address(0)) revert NonexistentVault();\n }\n\n /// @notice Internal version of the `getApproved` function\n function _getApproved(uint256 vaultID) internal view returns (address) {\n return _vaultApprovals[vaultID];\n }\n\n /// @notice Internal version of the `safeTransferFrom` function (with the data parameter)\n function _safeTransfer(address from, address to, uint256 vaultID, bytes memory _data) internal {\n _transfer(from, to, vaultID);\n if (!_checkOnERC721Received(from, to, vaultID, _data)) revert NonERC721Receiver();\n }\n\n /// @notice Checks whether a vault exists\n /// @param vaultID ID of the vault to check\n /// @return Whether `vaultID` has been created\n function _exists(uint256 vaultID) internal view returns (bool) {\n return _owners[vaultID] != address(0);\n }\n\n /// @notice Internal version of the `isApprovedOrOwner` function\n function _isApprovedOrOwner(address spender, uint256 vaultID) internal view returns (bool) {\n // The following checks if the vault exists\n address owner = _ownerOf(vaultID);\n return (spender == owner || _getApproved(vaultID) == spender || _operatorApprovals[owner][spender] == 1);\n }\n\n /// @notice Internal version of the `createVault` function\n /// Mints `vaultID` and transfers it to `to`\n /// @dev This method is equivalent to the `_safeMint` method used in OpenZeppelin ERC721 contract\n /// @dev Emits a {Transfer} event\n function _mint(address to) internal returns (uint256 vaultID) {\n if (to == address(0)) revert ZeroAddress();\n\n unchecked {\n vaultIDCount += 1;\n }\n\n vaultID = vaultIDCount;\n _beforeTokenTransfer(address(0), to, vaultID);\n\n unchecked {\n _balances[to] += 1;\n }\n\n _owners[vaultID] = to;\n emit Transfer(address(0), to, vaultID);\n if (!_checkOnERC721Received(address(0), to, vaultID, \"\")) revert NonERC721Receiver();\n }\n\n /// @notice Destroys `vaultID`\n /// @dev `vaultID` must exist\n /// @dev Emits a {Transfer} event\n function _burn(uint256 vaultID) internal {\n address owner = _ownerOf(vaultID);\n\n _beforeTokenTransfer(owner, address(0), vaultID);\n // Clear approvals\n _approve(address(0), vaultID);\n // The following line cannot underflow as the owner's balance is necessarily\n // greater than 1\n unchecked {\n _balances[owner] -= 1;\n }\n delete _owners[vaultID];\n delete vaultData[vaultID];\n\n emit Transfer(owner, address(0), vaultID);\n }\n\n /// @notice Transfers `vaultID` from `from` to `to` as opposed to {transferFrom},\n /// this imposes no restrictions on msg.sender\n /// @dev `to` cannot be the zero address and `perpetualID` must be owned by `from`\n /// @dev Emits a {Transfer} event\n function _transfer(address from, address to, uint256 vaultID) internal {\n if (_ownerOf(vaultID) != from) revert NotApproved();\n if (to == address(0)) revert ZeroAddress();\n\n _beforeTokenTransfer(from, to, vaultID);\n\n // Clear approvals from the previous owner\n _approve(address(0), vaultID);\n unchecked {\n _balances[from] -= 1;\n _balances[to] += 1;\n }\n _owners[vaultID] = to;\n\n emit Transfer(from, to, vaultID);\n }\n\n /// @notice Approves `to` to operate on `vaultID`\n function _approve(address to, uint256 vaultID) internal {\n _vaultApprovals[vaultID] = to;\n emit Approval(_ownerOf(vaultID), to, vaultID);\n }\n\n /// @notice Internal version of the `setApprovalForAll` function\n /// @dev It contains an `approver` field to be used in case someone signs a permit for a particular\n /// address, and this signature is given to the contract by another address (like a router)\n function _setApprovalForAll(address approver, address operator, bool approved) internal {\n if (operator == approver) revert ApprovalToCaller();\n uint256 approval = approved ? 1 : 0;\n _operatorApprovals[approver][operator] = approval;\n emit ApprovalForAll(approver, operator, approved);\n }\n\n /// @notice Internal function to invoke {IERC721Receiver-onERC721Received} on a target address\n /// The call is not executed if the target address is not a contract\n /// @param from Address representing the previous owner of the given token ID\n /// @param to Target address that will receive the tokens\n /// @param vaultID ID of the token to be transferred\n /// @param _data Bytes optional data to send along with the call\n /// @return Bool whether the call correctly returned the expected value\n function _checkOnERC721Received(\n address from,\n address to,\n uint256 vaultID,\n bytes memory _data\n ) private returns (bool) {\n if (to.isContract()) {\n try IERC721ReceiverUpgradeable(to).onERC721Received(msg.sender, from, vaultID, _data) returns (\n bytes4 retval\n ) {\n return retval == IERC721ReceiverUpgradeable.onERC721Received.selector;\n } catch (bytes memory reason) {\n if (reason.length == 0) {\n revert NonERC721Receiver();\n } else {\n // solhint-disable-next-line no-inline-assembly\n assembly {\n revert(add(32, reason), mload(reason))\n }\n }\n }\n } else {\n return true;\n }\n }\n\n /// @notice Hook that is called before any token transfer. This includes minting and burning.\n /// Calling conditions:\n ///\n /// - When `from` and `to` are both non-zero, `from`'s `vaultID` will be\n /// transferred to `to`.\n /// - When `from` is zero, `vaultID` will be minted for `to`.\n /// - When `to` is zero, `from`'s `vaultID` will be burned.\n /// - `from` and `to` are never both zero.\n function _beforeTokenTransfer(address from, address to, uint256 vaultID) internal virtual {}\n\n /// @notice Get `whitelistingActivated` in storage only if needed\n function _whitelistingActivated() internal view virtual returns (bool) {\n return whitelistingActivated;\n }\n}\n" + }, + "contracts/vaultManager/VaultManagerPermit.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\nimport \"./VaultManagerERC721.sol\";\nimport \"../interfaces/external/IERC1271.sol\";\n\n/// @title VaultManagerPermit\n/// @author Angle Labs, Inc.\n/// @dev Base Implementation of permit functions for the `VaultManager` contract\nabstract contract VaultManagerPermit is Initializable, VaultManagerERC721 {\n using Address for address;\n\n mapping(address => uint256) private _nonces;\n /* solhint-disable var-name-mixedcase */\n bytes32 private _HASHED_NAME;\n bytes32 private _HASHED_VERSION;\n bytes32 private _PERMIT_TYPEHASH;\n /* solhint-enable var-name-mixedcase */\n\n error ExpiredDeadline();\n error InvalidSignature();\n\n //solhint-disable-next-line\n function __ERC721Permit_init(string memory _name) internal onlyInitializing {\n _PERMIT_TYPEHASH = keccak256(\n \"Permit(address owner,address spender,bool approved,uint256 nonce,uint256 deadline)\"\n );\n _HASHED_NAME = keccak256(bytes(_name));\n _HASHED_VERSION = keccak256(bytes(\"1\"));\n }\n\n /// @notice Allows an address to give or revoke approval for all its vaults to another address\n /// @param owner Address signing the permit and giving (or revoking) its approval for all the controlled vaults\n /// @param spender Address to give approval to\n /// @param approved Whether to give or revoke the approval\n /// @param deadline Deadline parameter for the signature to be valid\n /// @dev The `v`, `r`, and `s` parameters are used as signature data\n function permit(\n address owner,\n address spender,\n bool approved,\n uint256 deadline,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) external {\n if (block.timestamp > deadline) revert ExpiredDeadline();\n // Additional signature checks performed in the `ECDSAUpgradeable.recover` function\n if (uint256(s) > 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D576E7357A4501DDFE92F46681B20A0 || (v != 27 && v != 28))\n revert InvalidSignature();\n\n bytes32 digest = keccak256(\n abi.encodePacked(\n \"\\x19\\x01\",\n _domainSeparatorV4(),\n keccak256(\n abi.encode(\n _PERMIT_TYPEHASH,\n // 0x3f43a9c6bafb5c7aab4e0cfe239dc5d4c15caf0381c6104188191f78a6640bd8,\n owner,\n spender,\n approved,\n _useNonce(owner),\n deadline\n )\n )\n )\n );\n if (owner.isContract()) {\n if (IERC1271(owner).isValidSignature(digest, abi.encodePacked(r, s, v)) != 0x1626ba7e)\n revert InvalidSignature();\n } else {\n address signer = ecrecover(digest, v, r, s);\n if (signer != owner || signer == address(0)) revert InvalidSignature();\n }\n\n _setApprovalForAll(owner, spender, approved);\n }\n\n /// @notice Returns the current nonce for an `owner` address\n function nonces(address owner) public view returns (uint256) {\n return _nonces[owner];\n }\n\n /// @notice Returns the domain separator for the current chain.\n // solhint-disable-next-line func-name-mixedcase\n function DOMAIN_SEPARATOR() external view returns (bytes32) {\n return _domainSeparatorV4();\n }\n\n /// @notice Internal version of the `DOMAIN_SEPARATOR` function\n function _domainSeparatorV4() internal view returns (bytes32) {\n return\n keccak256(\n abi.encode(\n // keccak256('EIP712Domain(string name,string version,uint256 chainId,address verifyingContract)')\n 0x8b73c3c69bb8fe3d512ecc4cf759cc79239f7b179b0ffacaa9a75d522b39400f,\n _HASHED_NAME,\n _HASHED_VERSION,\n block.chainid,\n address(this)\n )\n );\n }\n\n /// @notice Consumes a nonce for an address: returns the current value and increments it\n function _useNonce(address owner) internal returns (uint256 current) {\n current = _nonces[owner];\n _nonces[owner] = current + 1;\n }\n\n uint256[49] private __gap;\n}\n" + }, + "contracts/vaultManager/VaultManagerStorage.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\nimport \"@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/token/ERC20/extensions/draft-IERC20PermitUpgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/token/ERC721/IERC721ReceiverUpgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/interfaces/IERC721MetadataUpgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/utils/introspection/IERC165Upgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/utils/AddressUpgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/security/ReentrancyGuardUpgradeable.sol\";\nimport \"@openzeppelin/contracts/token/ERC20/extensions/IERC20Metadata.sol\";\nimport \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\nimport \"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\";\n\nimport \"../interfaces/IAgToken.sol\";\nimport \"../interfaces/IOracle.sol\";\nimport \"../interfaces/ISwapper.sol\";\nimport \"../interfaces/ITreasury.sol\";\nimport \"../interfaces/IVaultManager.sol\";\nimport \"../interfaces/governance/IVeBoostProxy.sol\";\n\n/// @title VaultManagerStorage\n/// @author Angle Labs, Inc.\n/// @dev Variables, references, parameters and events needed in the `VaultManager` contract\n// solhint-disable-next-line max-states-count\ncontract VaultManagerStorage is IVaultManagerStorage, Initializable, ReentrancyGuardUpgradeable {\n /// @notice Base used for parameter computation: almost all the parameters of this contract are set in `BASE_PARAMS`\n uint256 public constant BASE_PARAMS = 10 ** 9;\n /// @notice Base used for interest rate computation\n uint256 public constant BASE_INTEREST = 10 ** 27;\n /// @notice Used for interest rate computation\n uint256 public constant HALF_BASE_INTEREST = 10 ** 27 / 2;\n\n // ================================= REFERENCES ================================\n\n /// @inheritdoc IVaultManagerStorage\n ITreasury public treasury;\n /// @inheritdoc IVaultManagerStorage\n IERC20 public collateral;\n /// @inheritdoc IVaultManagerStorage\n IAgToken public stablecoin;\n /// @inheritdoc IVaultManagerStorage\n IOracle public oracle;\n /// @notice Reference to the contract which computes adjusted veANGLE balances for liquidators boosts\n IVeBoostProxy public veBoostProxy;\n /// @notice Base of the collateral\n uint256 internal _collatBase;\n\n // ================================= PARAMETERS ================================\n // Unless specified otherwise, parameters of this contract are expressed in `BASE_PARAMS`\n\n /// @notice Maximum amount of stablecoins that can be issued with this contract (in `BASE_TOKENS`). This parameter should\n /// not be bigger than `type(uint256).max / BASE_INTEREST` otherwise there may be some overflows in the `increaseDebt` function\n uint256 public debtCeiling;\n /// @notice Threshold veANGLE balance values for the computation of the boost for liquidators: the length of this array\n /// should normally be 2. The base of the x-values in this array should be `BASE_TOKENS`\n uint256[] public xLiquidationBoost;\n /// @notice Values of the liquidation boost at the threshold values of x\n uint256[] public yLiquidationBoost;\n /// @inheritdoc IVaultManagerStorage\n uint64 public collateralFactor;\n /// @notice Maximum Health factor at which a vault can end up after a liquidation (unless it's fully liquidated)\n uint64 public targetHealthFactor;\n /// @notice Upfront fee taken when borrowing stablecoins: this fee is optional and should in practice not be used\n uint64 public borrowFee;\n /// @notice Upfront fee taken when repaying stablecoins: this fee is optional as well. It should be smaller\n /// than the liquidation surcharge (cf below) to avoid exploits where people voluntarily get liquidated at a 0\n /// discount to pay smaller repaying fees\n uint64 public repayFee;\n /// @notice Per second interest taken to borrowers taking agToken loans. Contrarily to other parameters, it is set in `BASE_INTEREST`\n /// that is to say in base 10**27\n uint64 public interestRate;\n /// @notice Fee taken by the protocol during a liquidation. Technically, this value is not the fee per se, it's 1 - fee.\n /// For instance for a 2% fee, `liquidationSurcharge` should be 98%\n uint64 public liquidationSurcharge;\n /// @notice Maximum discount given to liquidators\n uint64 public maxLiquidationDiscount;\n /// @notice Whether whitelisting is required to own a vault or not\n bool public whitelistingActivated;\n /// @notice Whether the contract is paused or not\n bool public paused;\n\n // ================================= VARIABLES =================================\n\n /// @notice Timestamp at which the `interestAccumulator` was updated\n uint256 public lastInterestAccumulatorUpdated;\n /// @inheritdoc IVaultManagerStorage\n uint256 public interestAccumulator;\n /// @inheritdoc IVaultManagerStorage\n uint256 public totalNormalizedDebt;\n /// @notice Surplus accumulated by the contract: surplus is always in stablecoins, and is then reset\n /// when the value is communicated to the treasury contract\n uint256 public surplus;\n /// @notice Bad debt made from liquidated vaults which ended up having no collateral and a positive amount\n /// of stablecoins\n uint256 public badDebt;\n\n // ================================== MAPPINGS =================================\n\n /// @inheritdoc IVaultManagerStorage\n mapping(uint256 => Vault) public vaultData;\n /// @notice Maps an address to 1 if it's whitelisted and can open or own a vault\n mapping(address => uint256) public isWhitelisted;\n\n // ================================ ERC721 DATA ================================\n\n /// @inheritdoc IVaultManagerStorage\n uint256 public vaultIDCount;\n\n /// @notice URI\n string internal _baseURI;\n\n // Mapping from `vaultID` to owner address\n mapping(uint256 => address) internal _owners;\n\n // Mapping from owner address to vault owned count\n mapping(address => uint256) internal _balances;\n\n // Mapping from `vaultID` to approved address\n mapping(uint256 => address) internal _vaultApprovals;\n\n // Mapping from owner to operator approvals\n mapping(address => mapping(address => uint256)) internal _operatorApprovals;\n\n uint256[50] private __gap;\n\n // =================================== EVENTS ==================================\n\n event AccruedToTreasury(uint256 surplusEndValue, uint256 badDebtEndValue);\n event CollateralAmountUpdated(uint256 vaultID, uint256 collateralAmount, uint8 isIncrease);\n event InterestAccumulatorUpdated(uint256 value, uint256 timestamp);\n event InternalDebtUpdated(uint256 vaultID, uint256 internalAmount, uint8 isIncrease);\n event FiledUint64(uint64 param, bytes32 what);\n event DebtCeilingUpdated(uint256 debtCeiling);\n event LiquidationBoostParametersUpdated(address indexed _veBoostProxy, uint256[] xBoost, uint256[] yBoost);\n event LiquidatedVaults(uint256[] vaultIDs);\n event DebtTransferred(uint256 srcVaultID, uint256 dstVaultID, address dstVaultManager, uint256 amount);\n\n // =================================== ERRORS ==================================\n\n error ApprovalToOwner();\n error ApprovalToCaller();\n error DustyLeftoverAmount();\n error DebtCeilingExceeded();\n error HealthyVault();\n error IncompatibleLengths();\n error InsolventVault();\n error InvalidParameterValue();\n error InvalidParameterType();\n error InvalidSetOfParameters();\n error InvalidTreasury();\n error NonERC721Receiver();\n error NonexistentVault();\n error NotApproved();\n error NotGovernor();\n error NotGovernorOrGuardian();\n error NotTreasury();\n error NotWhitelisted();\n error NotVaultManager();\n error Paused();\n error TooHighParameterValue();\n error TooSmallParameterValue();\n error ZeroAddress();\n\n /// @custom:oz-upgrades-unsafe-allow constructor\n constructor() initializer {}\n}\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 1000000 + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers", + "metadata", + "devdoc", + "userdoc", + "storageLayout", + "evm.gasEstimates", + "devdoc", + "userdoc" + ], + "": [ + "ast" + ] + } + }, + "metadata": { + "useLiteralContent": true + } + } +} \ No newline at end of file diff --git a/deployments/avalanche/AgTokenSideChainMultiBridge_Implementation.json b/deployments/avalanche/AgTokenSideChainMultiBridge_Implementation.json index e2940287..b05b9ac9 100644 --- a/deployments/avalanche/AgTokenSideChainMultiBridge_Implementation.json +++ b/deployments/avalanche/AgTokenSideChainMultiBridge_Implementation.json @@ -1,5 +1,5 @@ { - "address": "0x97B6897AAd7aBa3861c04C0e6388Fc02AF1F227f", + "address": "0x2878596427bfA6b52Fa6D93B519A0c610bbDf00a", "abi": [ { "inputs": [], @@ -249,6 +249,19 @@ "name": "HourlyLimitUpdated", "type": "event" }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint8", + "name": "version", + "type": "uint8" + } + ], + "name": "Initialized", + "type": "event" + }, { "anonymous": false, "inputs": [ @@ -1111,7 +1124,7 @@ "inputs": [ { "internalType": "address", - "name": "recipient", + "name": "to", "type": "address" }, { @@ -1135,12 +1148,12 @@ "inputs": [ { "internalType": "address", - "name": "sender", + "name": "from", "type": "address" }, { "internalType": "address", - "name": "recipient", + "name": "to", "type": "address" }, { @@ -1198,31 +1211,44 @@ "type": "function" } ], - "transactionHash": "0xda21441225104011a2fb2954d723f224e4d88e347a065acd0d5c98b8017240af", + "transactionHash": "0xed965a6f5293226d4d1846355e1c89d5b1abbf18980780fde17e1ce2061f1dfe", "receipt": { "to": null, "from": "0xfdA462548Ce04282f4B6D6619823a7C64Fdc0185", - "contractAddress": "0x97B6897AAd7aBa3861c04C0e6388Fc02AF1F227f", - "transactionIndex": 8, - "gasUsed": "4004920", - "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", - "blockHash": "0x198f79dd1dfa918c3de3973fd716e7daa95e6323e16c066375e9bfaca76c69a6", - "transactionHash": "0xda21441225104011a2fb2954d723f224e4d88e347a065acd0d5c98b8017240af", - "logs": [], - "blockNumber": 20878154, - "cumulativeGasUsed": "4934398", + "contractAddress": "0x2878596427bfA6b52Fa6D93B519A0c610bbDf00a", + "transactionIndex": 7, + "gasUsed": "3964995", + "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000080000000000000000000000000000000000000000800000400000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "blockHash": "0x6409a22b94e89537a64822c74625daf61332893b7351625bf98d9dec6fb153cf", + "transactionHash": "0xed965a6f5293226d4d1846355e1c89d5b1abbf18980780fde17e1ce2061f1dfe", + "logs": [ + { + "transactionIndex": 7, + "blockNumber": 40179207, + "transactionHash": "0xed965a6f5293226d4d1846355e1c89d5b1abbf18980780fde17e1ce2061f1dfe", + "address": "0x2878596427bfA6b52Fa6D93B519A0c610bbDf00a", + "topics": [ + "0x7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb3847402498" + ], + "data": "0x0000000000000000000000000000000000000000000000000000000000000001", + "logIndex": 21, + "blockHash": "0x6409a22b94e89537a64822c74625daf61332893b7351625bf98d9dec6fb153cf" + } + ], + "blockNumber": 40179207, + "cumulativeGasUsed": "4802125", "status": 1, "byzantium": true }, "args": [], - "numDeployments": 1, - "solcInputHash": "c738595b9b57358bae83408c8b980d54", - "metadata": "{\"compiler\":{\"version\":\"0.8.12+commit.f00d7308\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[],\"name\":\"AssetStillControlledInReserves\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"BurnAmountExceedsAllowance\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"HourlyLimitExceeded\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidSender\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidToken\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidTreasury\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"NotGovernor\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"NotGovernorOrGuardian\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"NotMinter\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"NotTreasury\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"TooBigAmount\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"TooHighParameterValue\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ZeroAddress\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"spender\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"}],\"name\":\"Approval\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"bridgeToken\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"limit\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"hourlyLimit\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"fee\",\"type\":\"uint64\"},{\"indexed\":false,\"internalType\":\"bool\",\"name\":\"paused\",\"type\":\"bool\"}],\"name\":\"BridgeTokenAdded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"bridgeToken\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"fee\",\"type\":\"uint64\"}],\"name\":\"BridgeTokenFeeUpdated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"bridgeToken\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"hourlyLimit\",\"type\":\"uint256\"}],\"name\":\"BridgeTokenHourlyLimitUpdated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"bridgeToken\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"limit\",\"type\":\"uint256\"}],\"name\":\"BridgeTokenLimitUpdated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"bridgeToken\",\"type\":\"address\"}],\"name\":\"BridgeTokenRemoved\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"bridgeToken\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"bool\",\"name\":\"toggleStatus\",\"type\":\"bool\"}],\"name\":\"BridgeTokenToggled\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"theAddress\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"toggleStatus\",\"type\":\"uint256\"}],\"name\":\"FeeToggled\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"hourlyLimit\",\"type\":\"uint256\"}],\"name\":\"HourlyLimitUpdated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"minter\",\"type\":\"address\"}],\"name\":\"MinterToggled\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"Recovered\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"}],\"name\":\"Transfer\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"_treasury\",\"type\":\"address\"}],\"name\":\"TreasuryUpdated\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"BASE_PARAMS\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"DOMAIN_SEPARATOR\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"bridgeToken\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"limit\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"hourlyLimit\",\"type\":\"uint256\"},{\"internalType\":\"uint64\",\"name\":\"fee\",\"type\":\"uint64\"},{\"internalType\":\"bool\",\"name\":\"paused\",\"type\":\"bool\"}],\"name\":\"addBridgeToken\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"minter\",\"type\":\"address\"}],\"name\":\"addMinter\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"allBridgeTokens\",\"outputs\":[{\"internalType\":\"address[]\",\"name\":\"\",\"type\":\"address[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"spender\",\"type\":\"address\"}],\"name\":\"allowance\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"spender\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"approve\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"}],\"name\":\"balanceOf\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"name\":\"bridgeTokensList\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"bridges\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"limit\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"hourlyLimit\",\"type\":\"uint256\"},{\"internalType\":\"uint64\",\"name\":\"fee\",\"type\":\"uint64\"},{\"internalType\":\"bool\",\"name\":\"allowed\",\"type\":\"bool\"},{\"internalType\":\"bool\",\"name\":\"paused\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"burner\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"}],\"name\":\"burnFrom\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"burner\",\"type\":\"address\"}],\"name\":\"burnSelf\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"burnStablecoin\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"chainTotalHourlyLimit\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"name\":\"chainTotalUsage\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"currentTotalUsage\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"bridgeToken\",\"type\":\"address\"}],\"name\":\"currentUsage\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"decimals\",\"outputs\":[{\"internalType\":\"uint8\",\"name\":\"\",\"type\":\"uint8\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"spender\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"subtractedValue\",\"type\":\"uint256\"}],\"name\":\"decreaseAllowance\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"spender\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"addedValue\",\"type\":\"uint256\"}],\"name\":\"increaseAllowance\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"string\",\"name\":\"name_\",\"type\":\"string\"},{\"internalType\":\"string\",\"name\":\"symbol_\",\"type\":\"string\"},{\"internalType\":\"address\",\"name\":\"_treasury\",\"type\":\"address\"}],\"name\":\"initialize\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"isFeeExempt\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"isMinter\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"mint\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"name\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"}],\"name\":\"nonces\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"spender\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"deadline\",\"type\":\"uint256\"},{\"internalType\":\"uint8\",\"name\":\"v\",\"type\":\"uint8\"},{\"internalType\":\"bytes32\",\"name\":\"r\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32\",\"name\":\"s\",\"type\":\"bytes32\"}],\"name\":\"permit\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"tokenAddress\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amountToRecover\",\"type\":\"uint256\"}],\"name\":\"recoverERC20\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"bridgeToken\",\"type\":\"address\"}],\"name\":\"removeBridgeToken\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"minter\",\"type\":\"address\"}],\"name\":\"removeMinter\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"hourlyLimit\",\"type\":\"uint256\"}],\"name\":\"setChainTotalHourlyLimit\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"bridgeToken\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"hourlyLimit\",\"type\":\"uint256\"}],\"name\":\"setHourlyLimit\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"bridgeToken\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"limit\",\"type\":\"uint256\"}],\"name\":\"setLimit\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"bridgeToken\",\"type\":\"address\"},{\"internalType\":\"uint64\",\"name\":\"fee\",\"type\":\"uint64\"}],\"name\":\"setSwapFee\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_treasury\",\"type\":\"address\"}],\"name\":\"setTreasury\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"bridgeToken\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"swapIn\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"bridgeToken\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"swapOut\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"symbol\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"bridgeToken\",\"type\":\"address\"}],\"name\":\"toggleBridge\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"theAddress\",\"type\":\"address\"}],\"name\":\"toggleFeesForAddress\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"totalSupply\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"recipient\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"transfer\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"recipient\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"transferFrom\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"treasury\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"name\":\"usage\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"}],\"devdoc\":{\"author\":\"Angle Core Team\",\"details\":\"This contract supports bridge tokens having a minting right on the stablecoin (also referred to as the canonical or the native token)References: - FRAX implementation: https://polygonscan.com/address/0x45c32fA6DF82ead1e2EF74d17b76547EDdFaFF89#code - QiDAO implementation: https://snowtrace.io/address/0x5c49b268c9841AFF1Cc3B0a418ff5c3442eE3F3b#code\",\"kind\":\"dev\",\"methods\":{\"DOMAIN_SEPARATOR()\":{\"details\":\"See {IERC20Permit-DOMAIN_SEPARATOR}.\"},\"addBridgeToken(address,uint256,uint256,uint64,bool)\":{\"params\":{\"bridgeToken\":\"Bridge token to add: it should be a version of the stablecoin from another bridge\",\"fee\":\"Fee taken upon swapping for or against this token\",\"hourlyLimit\":\"Limit on the hourly volume for this bridge\",\"limit\":\"Limit on the balance of bridge token this contract could hold\",\"paused\":\"Whether swapping for this token should be paused or not\"}},\"addMinter(address)\":{\"details\":\"Zero address checks are performed directly in the `Treasury` contract\",\"params\":{\"minter\":\"Minter address to add\"}},\"allBridgeTokens()\":{\"details\":\"Helpful for UIs\"},\"allowance(address,address)\":{\"details\":\"See {IERC20-allowance}.\"},\"approve(address,uint256)\":{\"details\":\"See {IERC20-approve}. Requirements: - `spender` cannot be the zero address.\"},\"balanceOf(address)\":{\"details\":\"See {IERC20-balanceOf}.\"},\"burnFrom(uint256,address,address)\":{\"details\":\"This method is to be called by a contract with the minter right after being requested to do so by a `sender` address willing to burn tokens from another `burner` addressThe method checks the allowance between the `sender` and the `burner`\",\"params\":{\"amount\":\"Amount of tokens to burn\",\"burner\":\"Address to burn from\",\"sender\":\"Address which requested the burn from `burner`\"}},\"burnSelf(uint256,address)\":{\"details\":\"This method is to be called by a contract with a minter right on the AgToken after being requested to do so by an address willing to burn tokens from its address\",\"params\":{\"amount\":\"Amount of tokens to burn\",\"burner\":\"Address to burn from\"}},\"burnStablecoin(uint256)\":{\"details\":\"This function can typically be called if there is a settlement mechanism to burn stablecoins\",\"params\":{\"amount\":\"Amount of stablecoins to burn\"}},\"currentTotalUsage()\":{\"details\":\"Helpful for UIs\"},\"currentUsage(address)\":{\"details\":\"Helpful for UIs\",\"params\":{\"bridgeToken\":\"Bridge used to mint\"}},\"decimals()\":{\"details\":\"Returns the number of decimals used to get its user representation. For example, if `decimals` equals `2`, a balance of `505` tokens should be displayed to a user as `5.05` (`505 / 10 ** 2`). Tokens usually opt for a value of 18, imitating the relationship between Ether and Wei. This is the value {ERC20} uses, unless this function is overridden; NOTE: This information is only used for _display_ purposes: it in no way affects any of the arithmetic of the contract, including {IERC20-balanceOf} and {IERC20-transfer}.\"},\"decreaseAllowance(address,uint256)\":{\"details\":\"Atomically decreases the allowance granted to `spender` by the caller. This is an alternative to {approve} that can be used as a mitigation for problems described in {IERC20-approve}. Emits an {Approval} event indicating the updated allowance. Requirements: - `spender` cannot be the zero address. - `spender` must have allowance for the caller of at least `subtractedValue`.\"},\"increaseAllowance(address,uint256)\":{\"details\":\"Atomically increases the allowance granted to `spender` by the caller. This is an alternative to {approve} that can be used as a mitigation for problems described in {IERC20-approve}. Emits an {Approval} event indicating the updated allowance. Requirements: - `spender` cannot be the zero address.\"},\"initialize(string,string,address)\":{\"details\":\"By default, agTokens are ERC-20 tokens with 18 decimals\",\"params\":{\"_treasury\":\"Reference to the `Treasury` contract associated to this agToken\",\"name_\":\"Name of the token\",\"symbol_\":\"Symbol of the token\"}},\"mint(address,uint256)\":{\"details\":\"The contracts allowed to issue agTokens are the `StableMaster` contract, `VaultManager` contracts associated to this stablecoin as well as the flash loan module (if activated) and potentially contracts whitelisted by governance\",\"params\":{\"account\":\"Address to mint to\",\"amount\":\"Amount to mint\"}},\"name()\":{\"details\":\"Returns the name of the token.\"},\"nonces(address)\":{\"details\":\"See {IERC20Permit-nonces}.\"},\"permit(address,address,uint256,uint256,uint8,bytes32,bytes32)\":{\"details\":\"See {IERC20Permit-permit}.\"},\"recoverERC20(address,address,uint256)\":{\"details\":\"Can be used to withdraw bridge tokens for them to be de-bridged on mainnet\"},\"removeBridgeToken(address)\":{\"params\":{\"bridgeToken\":\"Address of the bridge token to remove support for\"}},\"removeMinter(address)\":{\"details\":\"This function can also be called by a minter wishing to revoke itself\",\"params\":{\"minter\":\"Minter address to remove\"}},\"setTreasury(address)\":{\"params\":{\"_treasury\":\"New treasury address\"}},\"swapIn(address,uint256,address)\":{\"details\":\"Some fees may be taken by the protocol depending on the token used and on the address calling\",\"params\":{\"amount\":\"Amount of bridge tokens to send\",\"bridgeToken\":\"Bridge token to use to mint\",\"to\":\"Address to which the stablecoin should be sent\"},\"returns\":{\"_0\":\"Amount of the canonical stablecoin actually minted\"}},\"swapOut(address,uint256,address)\":{\"details\":\"Some fees may be taken by the protocol depending on the token used and on the address calling\",\"params\":{\"amount\":\"Amount of canonical tokens to burn\",\"bridgeToken\":\"Bridge token required\",\"to\":\"Address to which the bridge token should be sent\"},\"returns\":{\"_0\":\"Amount of bridge tokens actually sent back\"}},\"symbol()\":{\"details\":\"Returns the symbol of the token, usually a shorter version of the name.\"},\"totalSupply()\":{\"details\":\"See {IERC20-totalSupply}.\"},\"transfer(address,uint256)\":{\"details\":\"See {IERC20-transfer}. Requirements: - `recipient` cannot be the zero address. - the caller must have a balance of at least `amount`.\"},\"transferFrom(address,address,uint256)\":{\"details\":\"See {IERC20-transferFrom}. Emits an {Approval} event indicating the updated allowance. This is not required by the EIP. See the note at the beginning of {ERC20}. Requirements: - `sender` and `recipient` cannot be the zero address. - `sender` must have a balance of at least `amount`. - the caller must have allowance for ``sender``'s tokens of at least `amount`.\"}},\"title\":\"AgTokenSideChainMultiBridge\",\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{\"BASE_PARAMS()\":{\"notice\":\"Base used for fee computation\"},\"addBridgeToken(address,uint256,uint256,uint64,bool)\":{\"notice\":\"Adds support for a bridge token\"},\"addMinter(address)\":{\"notice\":\"Adds a minter in the contract\"},\"allBridgeTokens()\":{\"notice\":\"Returns the list of all supported bridge tokens\"},\"bridgeTokensList(uint256)\":{\"notice\":\"List of all bridge tokens\"},\"bridges(address)\":{\"notice\":\"Maps a bridge token to data\"},\"burnFrom(uint256,address,address)\":{\"notice\":\"Burns `amount` tokens from a `burner` address after being asked to by `sender`\"},\"burnSelf(uint256,address)\":{\"notice\":\"Burns `amount` tokens from a `burner` address\"},\"burnStablecoin(uint256)\":{\"notice\":\"Allows anyone to burn agToken without redeeming collateral back\"},\"chainTotalHourlyLimit()\":{\"notice\":\"Limit to the amount of tokens that can be sent from that chain to another chain\"},\"chainTotalUsage(uint256)\":{\"notice\":\"Usage per hour on that chain. Maps an hourly timestamp to the total volume swapped out on the chain\"},\"currentTotalUsage()\":{\"notice\":\"Returns the current total volume on the chain for the current hour\"},\"currentUsage(address)\":{\"notice\":\"Returns the current volume for a bridge, for the current hour\"},\"initialize(string,string,address)\":{\"notice\":\"Initializes the `AgToken` contract\"},\"isFeeExempt(address)\":{\"notice\":\"Maps an address to whether it is exempt of fees for when it comes to swapping in and out\"},\"isMinter(address)\":{\"notice\":\"Checks whether an address has the right to mint agTokens\"},\"mint(address,uint256)\":{\"notice\":\"Lets the `StableMaster` contract or another whitelisted contract mint agTokens\"},\"recoverERC20(address,address,uint256)\":{\"notice\":\"Recovers any ERC20 token\"},\"removeBridgeToken(address)\":{\"notice\":\"Removes support for a token\"},\"removeMinter(address)\":{\"notice\":\"Removes a minter from the contract\"},\"setChainTotalHourlyLimit(uint256)\":{\"notice\":\"Updates the `chainTotalHourlyLimit` amount\"},\"setHourlyLimit(address,uint256)\":{\"notice\":\"Updates the `hourlyLimit` amount for `bridgeToken`\"},\"setLimit(address,uint256)\":{\"notice\":\"Updates the `limit` amount for `bridgeToken`\"},\"setSwapFee(address,uint64)\":{\"notice\":\"Updates the `fee` value for `bridgeToken`\"},\"setTreasury(address)\":{\"notice\":\"Sets a new treasury contract\"},\"swapIn(address,uint256,address)\":{\"notice\":\"Mints the canonical token from a supported bridge token\"},\"swapOut(address,uint256,address)\":{\"notice\":\"Burns the canonical token in exchange for a bridge token\"},\"toggleBridge(address)\":{\"notice\":\"Pauses or unpauses swapping in and out for a token\"},\"toggleFeesForAddress(address)\":{\"notice\":\"Toggles fees for the address `theAddress`\"},\"treasury()\":{\"notice\":\"Reference to the treasury contract which can grant minting rights\"},\"usage(address,uint256)\":{\"notice\":\"Maps a bridge token to the associated hourly volume\"}},\"notice\":\"Contract for Angle agTokens on other chains than Ethereum mainnet\",\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/agToken/AgTokenSideChainMultiBridge.sol\":\"AgTokenSideChainMultiBridge\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":1000000},\"remappings\":[]},\"sources\":{\"@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (proxy/utils/Initializable.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../../utils/AddressUpgradeable.sol\\\";\\n\\n/**\\n * @dev This is a base contract to aid in writing upgradeable contracts, or any kind of contract that will be deployed\\n * behind a proxy. Since a proxied contract can't have a constructor, it's common to move constructor logic to an\\n * external initializer function, usually called `initialize`. It then becomes necessary to protect this initializer\\n * function so it can only be called once. The {initializer} modifier provided by this contract will have this effect.\\n *\\n * TIP: To avoid leaving the proxy in an uninitialized state, the initializer function should be called as early as\\n * possible by providing the encoded function call as the `_data` argument to {ERC1967Proxy-constructor}.\\n *\\n * CAUTION: When used with inheritance, manual care must be taken to not invoke a parent initializer twice, or to ensure\\n * that all initializers are idempotent. This is not verified automatically as constructors are by Solidity.\\n *\\n * [CAUTION]\\n * ====\\n * Avoid leaving a contract uninitialized.\\n *\\n * An uninitialized contract can be taken over by an attacker. This applies to both a proxy and its implementation\\n * contract, which may impact the proxy. To initialize the implementation contract, you can either invoke the\\n * initializer manually, or you can include a constructor to automatically mark it as initialized when it is deployed:\\n *\\n * [.hljs-theme-light.nopadding]\\n * ```\\n * /// @custom:oz-upgrades-unsafe-allow constructor\\n * constructor() initializer {}\\n * ```\\n * ====\\n */\\nabstract contract Initializable {\\n /**\\n * @dev Indicates that the contract has been initialized.\\n */\\n bool private _initialized;\\n\\n /**\\n * @dev Indicates that the contract is in the process of being initialized.\\n */\\n bool private _initializing;\\n\\n /**\\n * @dev Modifier to protect an initializer function from being invoked twice.\\n */\\n modifier initializer() {\\n // If the contract is initializing we ignore whether _initialized is set in order to support multiple\\n // inheritance patterns, but we only do this in the context of a constructor, because in other contexts the\\n // contract may have been reentered.\\n require(_initializing ? _isConstructor() : !_initialized, \\\"Initializable: contract is already initialized\\\");\\n\\n bool isTopLevelCall = !_initializing;\\n if (isTopLevelCall) {\\n _initializing = true;\\n _initialized = true;\\n }\\n\\n _;\\n\\n if (isTopLevelCall) {\\n _initializing = false;\\n }\\n }\\n\\n /**\\n * @dev Modifier to protect an initialization function so that it can only be invoked by functions with the\\n * {initializer} modifier, directly or indirectly.\\n */\\n modifier onlyInitializing() {\\n require(_initializing, \\\"Initializable: contract is not initializing\\\");\\n _;\\n }\\n\\n function _isConstructor() private view returns (bool) {\\n return !AddressUpgradeable.isContract(address(this));\\n }\\n}\\n\",\"keccak256\":\"0x68861bcc80cacbd498efde75aab6c74a486cc48262660d326c8d7530d9752097\",\"license\":\"MIT\"},\"@openzeppelin/contracts-upgradeable/token/ERC20/ERC20Upgradeable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (token/ERC20/ERC20.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"./IERC20Upgradeable.sol\\\";\\nimport \\\"./extensions/IERC20MetadataUpgradeable.sol\\\";\\nimport \\\"../../utils/ContextUpgradeable.sol\\\";\\nimport \\\"../../proxy/utils/Initializable.sol\\\";\\n\\n/**\\n * @dev Implementation of the {IERC20} interface.\\n *\\n * This implementation is agnostic to the way tokens are created. This means\\n * that a supply mechanism has to be added in a derived contract using {_mint}.\\n * For a generic mechanism see {ERC20PresetMinterPauser}.\\n *\\n * TIP: For a detailed writeup see our guide\\n * https://forum.zeppelin.solutions/t/how-to-implement-erc20-supply-mechanisms/226[How\\n * to implement supply mechanisms].\\n *\\n * We have followed general OpenZeppelin Contracts guidelines: functions revert\\n * instead returning `false` on failure. This behavior is nonetheless\\n * conventional and does not conflict with the expectations of ERC20\\n * applications.\\n *\\n * Additionally, an {Approval} event is emitted on calls to {transferFrom}.\\n * This allows applications to reconstruct the allowance for all accounts just\\n * by listening to said events. Other implementations of the EIP may not emit\\n * these events, as it isn't required by the specification.\\n *\\n * Finally, the non-standard {decreaseAllowance} and {increaseAllowance}\\n * functions have been added to mitigate the well-known issues around setting\\n * allowances. See {IERC20-approve}.\\n */\\ncontract ERC20Upgradeable is Initializable, ContextUpgradeable, IERC20Upgradeable, IERC20MetadataUpgradeable {\\n mapping(address => uint256) private _balances;\\n\\n mapping(address => mapping(address => uint256)) private _allowances;\\n\\n uint256 private _totalSupply;\\n\\n string private _name;\\n string private _symbol;\\n\\n /**\\n * @dev Sets the values for {name} and {symbol}.\\n *\\n * The default value of {decimals} is 18. To select a different value for\\n * {decimals} you should overload it.\\n *\\n * All two of these values are immutable: they can only be set once during\\n * construction.\\n */\\n function __ERC20_init(string memory name_, string memory symbol_) internal onlyInitializing {\\n __Context_init_unchained();\\n __ERC20_init_unchained(name_, symbol_);\\n }\\n\\n function __ERC20_init_unchained(string memory name_, string memory symbol_) internal onlyInitializing {\\n _name = name_;\\n _symbol = symbol_;\\n }\\n\\n /**\\n * @dev Returns the name of the token.\\n */\\n function name() public view virtual override returns (string memory) {\\n return _name;\\n }\\n\\n /**\\n * @dev Returns the symbol of the token, usually a shorter version of the\\n * name.\\n */\\n function symbol() public view virtual override returns (string memory) {\\n return _symbol;\\n }\\n\\n /**\\n * @dev Returns the number of decimals used to get its user representation.\\n * For example, if `decimals` equals `2`, a balance of `505` tokens should\\n * be displayed to a user as `5.05` (`505 / 10 ** 2`).\\n *\\n * Tokens usually opt for a value of 18, imitating the relationship between\\n * Ether and Wei. This is the value {ERC20} uses, unless this function is\\n * overridden;\\n *\\n * NOTE: This information is only used for _display_ purposes: it in\\n * no way affects any of the arithmetic of the contract, including\\n * {IERC20-balanceOf} and {IERC20-transfer}.\\n */\\n function decimals() public view virtual override returns (uint8) {\\n return 18;\\n }\\n\\n /**\\n * @dev See {IERC20-totalSupply}.\\n */\\n function totalSupply() public view virtual override returns (uint256) {\\n return _totalSupply;\\n }\\n\\n /**\\n * @dev See {IERC20-balanceOf}.\\n */\\n function balanceOf(address account) public view virtual override returns (uint256) {\\n return _balances[account];\\n }\\n\\n /**\\n * @dev See {IERC20-transfer}.\\n *\\n * Requirements:\\n *\\n * - `recipient` cannot be the zero address.\\n * - the caller must have a balance of at least `amount`.\\n */\\n function transfer(address recipient, uint256 amount) public virtual override returns (bool) {\\n _transfer(_msgSender(), recipient, amount);\\n return true;\\n }\\n\\n /**\\n * @dev See {IERC20-allowance}.\\n */\\n function allowance(address owner, address spender) public view virtual override returns (uint256) {\\n return _allowances[owner][spender];\\n }\\n\\n /**\\n * @dev See {IERC20-approve}.\\n *\\n * Requirements:\\n *\\n * - `spender` cannot be the zero address.\\n */\\n function approve(address spender, uint256 amount) public virtual override returns (bool) {\\n _approve(_msgSender(), spender, amount);\\n return true;\\n }\\n\\n /**\\n * @dev See {IERC20-transferFrom}.\\n *\\n * Emits an {Approval} event indicating the updated allowance. This is not\\n * required by the EIP. See the note at the beginning of {ERC20}.\\n *\\n * Requirements:\\n *\\n * - `sender` and `recipient` cannot be the zero address.\\n * - `sender` must have a balance of at least `amount`.\\n * - the caller must have allowance for ``sender``'s tokens of at least\\n * `amount`.\\n */\\n function transferFrom(\\n address sender,\\n address recipient,\\n uint256 amount\\n ) public virtual override returns (bool) {\\n _transfer(sender, recipient, amount);\\n\\n uint256 currentAllowance = _allowances[sender][_msgSender()];\\n require(currentAllowance >= amount, \\\"ERC20: transfer amount exceeds allowance\\\");\\n unchecked {\\n _approve(sender, _msgSender(), currentAllowance - amount);\\n }\\n\\n return true;\\n }\\n\\n /**\\n * @dev Atomically increases the allowance granted to `spender` by the caller.\\n *\\n * This is an alternative to {approve} that can be used as a mitigation for\\n * problems described in {IERC20-approve}.\\n *\\n * Emits an {Approval} event indicating the updated allowance.\\n *\\n * Requirements:\\n *\\n * - `spender` cannot be the zero address.\\n */\\n function increaseAllowance(address spender, uint256 addedValue) public virtual returns (bool) {\\n _approve(_msgSender(), spender, _allowances[_msgSender()][spender] + addedValue);\\n return true;\\n }\\n\\n /**\\n * @dev Atomically decreases the allowance granted to `spender` by the caller.\\n *\\n * This is an alternative to {approve} that can be used as a mitigation for\\n * problems described in {IERC20-approve}.\\n *\\n * Emits an {Approval} event indicating the updated allowance.\\n *\\n * Requirements:\\n *\\n * - `spender` cannot be the zero address.\\n * - `spender` must have allowance for the caller of at least\\n * `subtractedValue`.\\n */\\n function decreaseAllowance(address spender, uint256 subtractedValue) public virtual returns (bool) {\\n uint256 currentAllowance = _allowances[_msgSender()][spender];\\n require(currentAllowance >= subtractedValue, \\\"ERC20: decreased allowance below zero\\\");\\n unchecked {\\n _approve(_msgSender(), spender, currentAllowance - subtractedValue);\\n }\\n\\n return true;\\n }\\n\\n /**\\n * @dev Moves `amount` of tokens from `sender` to `recipient`.\\n *\\n * This internal function is equivalent to {transfer}, and can be used to\\n * e.g. implement automatic token fees, slashing mechanisms, etc.\\n *\\n * Emits a {Transfer} event.\\n *\\n * Requirements:\\n *\\n * - `sender` cannot be the zero address.\\n * - `recipient` cannot be the zero address.\\n * - `sender` must have a balance of at least `amount`.\\n */\\n function _transfer(\\n address sender,\\n address recipient,\\n uint256 amount\\n ) internal virtual {\\n require(sender != address(0), \\\"ERC20: transfer from the zero address\\\");\\n require(recipient != address(0), \\\"ERC20: transfer to the zero address\\\");\\n\\n _beforeTokenTransfer(sender, recipient, amount);\\n\\n uint256 senderBalance = _balances[sender];\\n require(senderBalance >= amount, \\\"ERC20: transfer amount exceeds balance\\\");\\n unchecked {\\n _balances[sender] = senderBalance - amount;\\n }\\n _balances[recipient] += amount;\\n\\n emit Transfer(sender, recipient, amount);\\n\\n _afterTokenTransfer(sender, recipient, amount);\\n }\\n\\n /** @dev Creates `amount` tokens and assigns them to `account`, increasing\\n * the total supply.\\n *\\n * Emits a {Transfer} event with `from` set to the zero address.\\n *\\n * Requirements:\\n *\\n * - `account` cannot be the zero address.\\n */\\n function _mint(address account, uint256 amount) internal virtual {\\n require(account != address(0), \\\"ERC20: mint to the zero address\\\");\\n\\n _beforeTokenTransfer(address(0), account, amount);\\n\\n _totalSupply += amount;\\n _balances[account] += amount;\\n emit Transfer(address(0), account, amount);\\n\\n _afterTokenTransfer(address(0), account, amount);\\n }\\n\\n /**\\n * @dev Destroys `amount` tokens from `account`, reducing the\\n * total supply.\\n *\\n * Emits a {Transfer} event with `to` set to the zero address.\\n *\\n * Requirements:\\n *\\n * - `account` cannot be the zero address.\\n * - `account` must have at least `amount` tokens.\\n */\\n function _burn(address account, uint256 amount) internal virtual {\\n require(account != address(0), \\\"ERC20: burn from the zero address\\\");\\n\\n _beforeTokenTransfer(account, address(0), amount);\\n\\n uint256 accountBalance = _balances[account];\\n require(accountBalance >= amount, \\\"ERC20: burn amount exceeds balance\\\");\\n unchecked {\\n _balances[account] = accountBalance - amount;\\n }\\n _totalSupply -= amount;\\n\\n emit Transfer(account, address(0), amount);\\n\\n _afterTokenTransfer(account, address(0), amount);\\n }\\n\\n /**\\n * @dev Sets `amount` as the allowance of `spender` over the `owner` s tokens.\\n *\\n * This internal function is equivalent to `approve`, and can be used to\\n * e.g. set automatic allowances for certain subsystems, etc.\\n *\\n * Emits an {Approval} event.\\n *\\n * Requirements:\\n *\\n * - `owner` cannot be the zero address.\\n * - `spender` cannot be the zero address.\\n */\\n function _approve(\\n address owner,\\n address spender,\\n uint256 amount\\n ) internal virtual {\\n require(owner != address(0), \\\"ERC20: approve from the zero address\\\");\\n require(spender != address(0), \\\"ERC20: approve to the zero address\\\");\\n\\n _allowances[owner][spender] = amount;\\n emit Approval(owner, spender, amount);\\n }\\n\\n /**\\n * @dev Hook that is called before any transfer of tokens. This includes\\n * minting and burning.\\n *\\n * Calling conditions:\\n *\\n * - when `from` and `to` are both non-zero, `amount` of ``from``'s tokens\\n * will be transferred to `to`.\\n * - when `from` is zero, `amount` tokens will be minted for `to`.\\n * - when `to` is zero, `amount` of ``from``'s tokens will be burned.\\n * - `from` and `to` are never both zero.\\n *\\n * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].\\n */\\n function _beforeTokenTransfer(\\n address from,\\n address to,\\n uint256 amount\\n ) internal virtual {}\\n\\n /**\\n * @dev Hook that is called after any transfer of tokens. This includes\\n * minting and burning.\\n *\\n * Calling conditions:\\n *\\n * - when `from` and `to` are both non-zero, `amount` of ``from``'s tokens\\n * has been transferred to `to`.\\n * - when `from` is zero, `amount` tokens have been minted for `to`.\\n * - when `to` is zero, `amount` of ``from``'s tokens have been burned.\\n * - `from` and `to` are never both zero.\\n *\\n * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].\\n */\\n function _afterTokenTransfer(\\n address from,\\n address to,\\n uint256 amount\\n ) internal virtual {}\\n uint256[45] private __gap;\\n}\\n\",\"keccak256\":\"0x23a373902059fb51db98e32e13f89a0ef0c570039081a1345022e66bc7e315d4\",\"license\":\"MIT\"},\"@openzeppelin/contracts-upgradeable/token/ERC20/IERC20Upgradeable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (token/ERC20/IERC20.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Interface of the ERC20 standard as defined in the EIP.\\n */\\ninterface IERC20Upgradeable {\\n /**\\n * @dev Returns the amount of tokens in existence.\\n */\\n function totalSupply() external view returns (uint256);\\n\\n /**\\n * @dev Returns the amount of tokens owned by `account`.\\n */\\n function balanceOf(address account) external view returns (uint256);\\n\\n /**\\n * @dev Moves `amount` tokens from the caller's account to `recipient`.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * Emits a {Transfer} event.\\n */\\n function transfer(address recipient, uint256 amount) external returns (bool);\\n\\n /**\\n * @dev Returns the remaining number of tokens that `spender` will be\\n * allowed to spend on behalf of `owner` through {transferFrom}. This is\\n * zero by default.\\n *\\n * This value changes when {approve} or {transferFrom} are called.\\n */\\n function allowance(address owner, address spender) external view returns (uint256);\\n\\n /**\\n * @dev Sets `amount` as the allowance of `spender` over the caller's tokens.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * IMPORTANT: Beware that changing an allowance with this method brings the risk\\n * that someone may use both the old and the new allowance by unfortunate\\n * transaction ordering. One possible solution to mitigate this race\\n * condition is to first reduce the spender's allowance to 0 and set the\\n * desired value afterwards:\\n * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729\\n *\\n * Emits an {Approval} event.\\n */\\n function approve(address spender, uint256 amount) external returns (bool);\\n\\n /**\\n * @dev Moves `amount` tokens from `sender` to `recipient` using the\\n * allowance mechanism. `amount` is then deducted from the caller's\\n * allowance.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * Emits a {Transfer} event.\\n */\\n function transferFrom(\\n address sender,\\n address recipient,\\n uint256 amount\\n ) external returns (bool);\\n\\n /**\\n * @dev Emitted when `value` tokens are moved from one account (`from`) to\\n * another (`to`).\\n *\\n * Note that `value` may be zero.\\n */\\n event Transfer(address indexed from, address indexed to, uint256 value);\\n\\n /**\\n * @dev Emitted when the allowance of a `spender` for an `owner` is set by\\n * a call to {approve}. `value` is the new allowance.\\n */\\n event Approval(address indexed owner, address indexed spender, uint256 value);\\n}\\n\",\"keccak256\":\"0x5ca0eb1120133a6d0799752532d4638048391823a2b623c4fe9ff46e262266fb\",\"license\":\"MIT\"},\"@openzeppelin/contracts-upgradeable/token/ERC20/extensions/IERC20MetadataUpgradeable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (token/ERC20/extensions/IERC20Metadata.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../IERC20Upgradeable.sol\\\";\\n\\n/**\\n * @dev Interface for the optional metadata functions from the ERC20 standard.\\n *\\n * _Available since v4.1._\\n */\\ninterface IERC20MetadataUpgradeable is IERC20Upgradeable {\\n /**\\n * @dev Returns the name of the token.\\n */\\n function name() external view returns (string memory);\\n\\n /**\\n * @dev Returns the symbol of the token.\\n */\\n function symbol() external view returns (string memory);\\n\\n /**\\n * @dev Returns the decimals places of the token.\\n */\\n function decimals() external view returns (uint8);\\n}\\n\",\"keccak256\":\"0x605434219ebbe4653f703640f06969faa5a1d78f0bfef878e5ddbb1ca369ceeb\",\"license\":\"MIT\"},\"@openzeppelin/contracts-upgradeable/token/ERC20/extensions/draft-ERC20PermitUpgradeable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (token/ERC20/extensions/draft-ERC20Permit.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"./draft-IERC20PermitUpgradeable.sol\\\";\\nimport \\\"../ERC20Upgradeable.sol\\\";\\nimport \\\"../../../utils/cryptography/draft-EIP712Upgradeable.sol\\\";\\nimport \\\"../../../utils/cryptography/ECDSAUpgradeable.sol\\\";\\nimport \\\"../../../utils/CountersUpgradeable.sol\\\";\\nimport \\\"../../../proxy/utils/Initializable.sol\\\";\\n\\n/**\\n * @dev Implementation of the ERC20 Permit extension allowing approvals to be made via signatures, as defined in\\n * https://eips.ethereum.org/EIPS/eip-2612[EIP-2612].\\n *\\n * Adds the {permit} method, which can be used to change an account's ERC20 allowance (see {IERC20-allowance}) by\\n * presenting a message signed by the account. By not relying on `{IERC20-approve}`, the token holder account doesn't\\n * need to send a transaction, and thus is not required to hold Ether at all.\\n *\\n * _Available since v3.4._\\n */\\nabstract contract ERC20PermitUpgradeable is Initializable, ERC20Upgradeable, IERC20PermitUpgradeable, EIP712Upgradeable {\\n using CountersUpgradeable for CountersUpgradeable.Counter;\\n\\n mapping(address => CountersUpgradeable.Counter) private _nonces;\\n\\n // solhint-disable-next-line var-name-mixedcase\\n bytes32 private _PERMIT_TYPEHASH;\\n\\n /**\\n * @dev Initializes the {EIP712} domain separator using the `name` parameter, and setting `version` to `\\\"1\\\"`.\\n *\\n * It's a good idea to use the same `name` that is defined as the ERC20 token name.\\n */\\n function __ERC20Permit_init(string memory name) internal onlyInitializing {\\n __Context_init_unchained();\\n __EIP712_init_unchained(name, \\\"1\\\");\\n __ERC20Permit_init_unchained(name);\\n }\\n\\n function __ERC20Permit_init_unchained(string memory name) internal onlyInitializing {\\n _PERMIT_TYPEHASH = keccak256(\\\"Permit(address owner,address spender,uint256 value,uint256 nonce,uint256 deadline)\\\");}\\n\\n /**\\n * @dev See {IERC20Permit-permit}.\\n */\\n function permit(\\n address owner,\\n address spender,\\n uint256 value,\\n uint256 deadline,\\n uint8 v,\\n bytes32 r,\\n bytes32 s\\n ) public virtual override {\\n require(block.timestamp <= deadline, \\\"ERC20Permit: expired deadline\\\");\\n\\n bytes32 structHash = keccak256(abi.encode(_PERMIT_TYPEHASH, owner, spender, value, _useNonce(owner), deadline));\\n\\n bytes32 hash = _hashTypedDataV4(structHash);\\n\\n address signer = ECDSAUpgradeable.recover(hash, v, r, s);\\n require(signer == owner, \\\"ERC20Permit: invalid signature\\\");\\n\\n _approve(owner, spender, value);\\n }\\n\\n /**\\n * @dev See {IERC20Permit-nonces}.\\n */\\n function nonces(address owner) public view virtual override returns (uint256) {\\n return _nonces[owner].current();\\n }\\n\\n /**\\n * @dev See {IERC20Permit-DOMAIN_SEPARATOR}.\\n */\\n // solhint-disable-next-line func-name-mixedcase\\n function DOMAIN_SEPARATOR() external view override returns (bytes32) {\\n return _domainSeparatorV4();\\n }\\n\\n /**\\n * @dev \\\"Consume a nonce\\\": return the current value and increment.\\n *\\n * _Available since v4.1._\\n */\\n function _useNonce(address owner) internal virtual returns (uint256 current) {\\n CountersUpgradeable.Counter storage nonce = _nonces[owner];\\n current = nonce.current();\\n nonce.increment();\\n }\\n uint256[49] private __gap;\\n}\\n\",\"keccak256\":\"0x7fb71e823080ba5e320f036c7dbda29f3676f3d516db4dcdb8b0adbfbae5d830\",\"license\":\"MIT\"},\"@openzeppelin/contracts-upgradeable/token/ERC20/extensions/draft-IERC20PermitUpgradeable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (token/ERC20/extensions/draft-IERC20Permit.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Interface of the ERC20 Permit extension allowing approvals to be made via signatures, as defined in\\n * https://eips.ethereum.org/EIPS/eip-2612[EIP-2612].\\n *\\n * Adds the {permit} method, which can be used to change an account's ERC20 allowance (see {IERC20-allowance}) by\\n * presenting a message signed by the account. By not relying on {IERC20-approve}, the token holder account doesn't\\n * need to send a transaction, and thus is not required to hold Ether at all.\\n */\\ninterface IERC20PermitUpgradeable {\\n /**\\n * @dev Sets `value` as the allowance of `spender` over ``owner``'s tokens,\\n * given ``owner``'s signed approval.\\n *\\n * IMPORTANT: The same issues {IERC20-approve} has related to transaction\\n * ordering also apply here.\\n *\\n * Emits an {Approval} event.\\n *\\n * Requirements:\\n *\\n * - `spender` cannot be the zero address.\\n * - `deadline` must be a timestamp in the future.\\n * - `v`, `r` and `s` must be a valid `secp256k1` signature from `owner`\\n * over the EIP712-formatted function arguments.\\n * - the signature must use ``owner``'s current nonce (see {nonces}).\\n *\\n * For more information on the signature format, see the\\n * https://eips.ethereum.org/EIPS/eip-2612#specification[relevant EIP\\n * section].\\n */\\n function permit(\\n address owner,\\n address spender,\\n uint256 value,\\n uint256 deadline,\\n uint8 v,\\n bytes32 r,\\n bytes32 s\\n ) external;\\n\\n /**\\n * @dev Returns the current nonce for `owner`. This value must be\\n * included whenever a signature is generated for {permit}.\\n *\\n * Every successful call to {permit} increases ``owner``'s nonce by one. This\\n * prevents a signature from being used multiple times.\\n */\\n function nonces(address owner) external view returns (uint256);\\n\\n /**\\n * @dev Returns the domain separator used in the encoding of the signature for {permit}, as defined by {EIP712}.\\n */\\n // solhint-disable-next-line func-name-mixedcase\\n function DOMAIN_SEPARATOR() external view returns (bytes32);\\n}\\n\",\"keccak256\":\"0xcc70d8e2281fb3ff69e8ab242500f10142cd0a7fa8dd9e45882be270d4d09024\",\"license\":\"MIT\"},\"@openzeppelin/contracts-upgradeable/utils/AddressUpgradeable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (utils/Address.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Collection of functions related to the address type\\n */\\nlibrary AddressUpgradeable {\\n /**\\n * @dev Returns true if `account` is a contract.\\n *\\n * [IMPORTANT]\\n * ====\\n * It is unsafe to assume that an address for which this function returns\\n * false is an externally-owned account (EOA) and not a contract.\\n *\\n * Among others, `isContract` will return false for the following\\n * types of addresses:\\n *\\n * - an externally-owned account\\n * - a contract in construction\\n * - an address where a contract will be created\\n * - an address where a contract lived, but was destroyed\\n * ====\\n */\\n function isContract(address account) internal view returns (bool) {\\n // This method relies on extcodesize, which returns 0 for contracts in\\n // construction, since the code is only stored at the end of the\\n // constructor execution.\\n\\n uint256 size;\\n assembly {\\n size := extcodesize(account)\\n }\\n return size > 0;\\n }\\n\\n /**\\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\\n * `recipient`, forwarding all available gas and reverting on errors.\\n *\\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\\n * imposed by `transfer`, making them unable to receive funds via\\n * `transfer`. {sendValue} removes this limitation.\\n *\\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\\n *\\n * IMPORTANT: because control is transferred to `recipient`, care must be\\n * taken to not create reentrancy vulnerabilities. Consider using\\n * {ReentrancyGuard} or the\\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\\n */\\n function sendValue(address payable recipient, uint256 amount) internal {\\n require(address(this).balance >= amount, \\\"Address: insufficient balance\\\");\\n\\n (bool success, ) = recipient.call{value: amount}(\\\"\\\");\\n require(success, \\\"Address: unable to send value, recipient may have reverted\\\");\\n }\\n\\n /**\\n * @dev Performs a Solidity function call using a low level `call`. A\\n * plain `call` is an unsafe replacement for a function call: use this\\n * function instead.\\n *\\n * If `target` reverts with a revert reason, it is bubbled up by this\\n * function (like regular Solidity function calls).\\n *\\n * Returns the raw returned data. To convert to the expected return value,\\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\\n *\\n * Requirements:\\n *\\n * - `target` must be a contract.\\n * - calling `target` with `data` must not revert.\\n *\\n * _Available since v3.1._\\n */\\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\\n return functionCall(target, data, \\\"Address: low-level call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\\n * `errorMessage` as a fallback revert reason when `target` reverts.\\n *\\n * _Available since v3.1._\\n */\\n function functionCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n return functionCallWithValue(target, data, 0, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but also transferring `value` wei to `target`.\\n *\\n * Requirements:\\n *\\n * - the calling contract must have an ETH balance of at least `value`.\\n * - the called Solidity function must be `payable`.\\n *\\n * _Available since v3.1._\\n */\\n function functionCallWithValue(\\n address target,\\n bytes memory data,\\n uint256 value\\n ) internal returns (bytes memory) {\\n return functionCallWithValue(target, data, value, \\\"Address: low-level call with value failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\\n * with `errorMessage` as a fallback revert reason when `target` reverts.\\n *\\n * _Available since v3.1._\\n */\\n function functionCallWithValue(\\n address target,\\n bytes memory data,\\n uint256 value,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n require(address(this).balance >= value, \\\"Address: insufficient balance for call\\\");\\n require(isContract(target), \\\"Address: call to non-contract\\\");\\n\\n (bool success, bytes memory returndata) = target.call{value: value}(data);\\n return verifyCallResult(success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but performing a static call.\\n *\\n * _Available since v3.3._\\n */\\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\\n return functionStaticCall(target, data, \\\"Address: low-level static call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\\n * but performing a static call.\\n *\\n * _Available since v3.3._\\n */\\n function functionStaticCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal view returns (bytes memory) {\\n require(isContract(target), \\\"Address: static call to non-contract\\\");\\n\\n (bool success, bytes memory returndata) = target.staticcall(data);\\n return verifyCallResult(success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the\\n * revert reason using the provided one.\\n *\\n * _Available since v4.3._\\n */\\n function verifyCallResult(\\n bool success,\\n bytes memory returndata,\\n string memory errorMessage\\n ) internal pure returns (bytes memory) {\\n if (success) {\\n return returndata;\\n } else {\\n // Look for revert reason and bubble it up if present\\n if (returndata.length > 0) {\\n // The easiest way to bubble the revert reason is using memory via assembly\\n\\n assembly {\\n let returndata_size := mload(returndata)\\n revert(add(32, returndata), returndata_size)\\n }\\n } else {\\n revert(errorMessage);\\n }\\n }\\n }\\n}\\n\",\"keccak256\":\"0x3f0f878c796dfc7feba6d3c4e3e526c14c7deae8b7bfc71088e3f38fab0d77b3\",\"license\":\"MIT\"},\"@openzeppelin/contracts-upgradeable/utils/ContextUpgradeable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)\\n\\npragma solidity ^0.8.0;\\nimport \\\"../proxy/utils/Initializable.sol\\\";\\n\\n/**\\n * @dev Provides information about the current execution context, including the\\n * sender of the transaction and its data. While these are generally available\\n * via msg.sender and msg.data, they should not be accessed in such a direct\\n * manner, since when dealing with meta-transactions the account sending and\\n * paying for execution may not be the actual sender (as far as an application\\n * is concerned).\\n *\\n * This contract is only required for intermediate, library-like contracts.\\n */\\nabstract contract ContextUpgradeable is Initializable {\\n function __Context_init() internal onlyInitializing {\\n __Context_init_unchained();\\n }\\n\\n function __Context_init_unchained() internal onlyInitializing {\\n }\\n function _msgSender() internal view virtual returns (address) {\\n return msg.sender;\\n }\\n\\n function _msgData() internal view virtual returns (bytes calldata) {\\n return msg.data;\\n }\\n uint256[50] private __gap;\\n}\\n\",\"keccak256\":\"0x0b0d548f6381370d394f7a434f994dc678b3ef3e755de106109d61343a685ea7\",\"license\":\"MIT\"},\"@openzeppelin/contracts-upgradeable/utils/CountersUpgradeable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (utils/Counters.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @title Counters\\n * @author Matt Condon (@shrugs)\\n * @dev Provides counters that can only be incremented, decremented or reset. This can be used e.g. to track the number\\n * of elements in a mapping, issuing ERC721 ids, or counting request ids.\\n *\\n * Include with `using Counters for Counters.Counter;`\\n */\\nlibrary CountersUpgradeable {\\n struct Counter {\\n // This variable should never be directly accessed by users of the library: interactions must be restricted to\\n // the library's function. As of Solidity v0.5.2, this cannot be enforced, though there is a proposal to add\\n // this feature: see https://github.com/ethereum/solidity/issues/4637\\n uint256 _value; // default: 0\\n }\\n\\n function current(Counter storage counter) internal view returns (uint256) {\\n return counter._value;\\n }\\n\\n function increment(Counter storage counter) internal {\\n unchecked {\\n counter._value += 1;\\n }\\n }\\n\\n function decrement(Counter storage counter) internal {\\n uint256 value = counter._value;\\n require(value > 0, \\\"Counter: decrement overflow\\\");\\n unchecked {\\n counter._value = value - 1;\\n }\\n }\\n\\n function reset(Counter storage counter) internal {\\n counter._value = 0;\\n }\\n}\\n\",\"keccak256\":\"0x798741e231b22b81e2dd2eddaaf8832dee4baf5cd8e2dbaa5c1dd12a1c053c4d\",\"license\":\"MIT\"},\"@openzeppelin/contracts-upgradeable/utils/StringsUpgradeable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (utils/Strings.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev String operations.\\n */\\nlibrary StringsUpgradeable {\\n bytes16 private constant _HEX_SYMBOLS = \\\"0123456789abcdef\\\";\\n\\n /**\\n * @dev Converts a `uint256` to its ASCII `string` decimal representation.\\n */\\n function toString(uint256 value) internal pure returns (string memory) {\\n // Inspired by OraclizeAPI's implementation - MIT licence\\n // https://github.com/oraclize/ethereum-api/blob/b42146b063c7d6ee1358846c198246239e9360e8/oraclizeAPI_0.4.25.sol\\n\\n if (value == 0) {\\n return \\\"0\\\";\\n }\\n uint256 temp = value;\\n uint256 digits;\\n while (temp != 0) {\\n digits++;\\n temp /= 10;\\n }\\n bytes memory buffer = new bytes(digits);\\n while (value != 0) {\\n digits -= 1;\\n buffer[digits] = bytes1(uint8(48 + uint256(value % 10)));\\n value /= 10;\\n }\\n return string(buffer);\\n }\\n\\n /**\\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation.\\n */\\n function toHexString(uint256 value) internal pure returns (string memory) {\\n if (value == 0) {\\n return \\\"0x00\\\";\\n }\\n uint256 temp = value;\\n uint256 length = 0;\\n while (temp != 0) {\\n length++;\\n temp >>= 8;\\n }\\n return toHexString(value, length);\\n }\\n\\n /**\\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length.\\n */\\n function toHexString(uint256 value, uint256 length) internal pure returns (string memory) {\\n bytes memory buffer = new bytes(2 * length + 2);\\n buffer[0] = \\\"0\\\";\\n buffer[1] = \\\"x\\\";\\n for (uint256 i = 2 * length + 1; i > 1; --i) {\\n buffer[i] = _HEX_SYMBOLS[value & 0xf];\\n value >>= 4;\\n }\\n require(value == 0, \\\"Strings: hex length insufficient\\\");\\n return string(buffer);\\n }\\n}\\n\",\"keccak256\":\"0x398d3323c1932a5986bf36be7c57593e121e69d5db5b6574b4ee0d031443de37\",\"license\":\"MIT\"},\"@openzeppelin/contracts-upgradeable/utils/cryptography/ECDSAUpgradeable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (utils/cryptography/ECDSA.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../StringsUpgradeable.sol\\\";\\n\\n/**\\n * @dev Elliptic Curve Digital Signature Algorithm (ECDSA) operations.\\n *\\n * These functions can be used to verify that a message was signed by the holder\\n * of the private keys of a given address.\\n */\\nlibrary ECDSAUpgradeable {\\n enum RecoverError {\\n NoError,\\n InvalidSignature,\\n InvalidSignatureLength,\\n InvalidSignatureS,\\n InvalidSignatureV\\n }\\n\\n function _throwError(RecoverError error) private pure {\\n if (error == RecoverError.NoError) {\\n return; // no error: do nothing\\n } else if (error == RecoverError.InvalidSignature) {\\n revert(\\\"ECDSA: invalid signature\\\");\\n } else if (error == RecoverError.InvalidSignatureLength) {\\n revert(\\\"ECDSA: invalid signature length\\\");\\n } else if (error == RecoverError.InvalidSignatureS) {\\n revert(\\\"ECDSA: invalid signature 's' value\\\");\\n } else if (error == RecoverError.InvalidSignatureV) {\\n revert(\\\"ECDSA: invalid signature 'v' value\\\");\\n }\\n }\\n\\n /**\\n * @dev Returns the address that signed a hashed message (`hash`) with\\n * `signature` or error string. This address can then be used for verification purposes.\\n *\\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\\n * this function rejects them by requiring the `s` value to be in the lower\\n * half order, and the `v` value to be either 27 or 28.\\n *\\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\\n * verification to be secure: it is possible to craft signatures that\\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\\n * this is by receiving a hash of the original message (which may otherwise\\n * be too long), and then calling {toEthSignedMessageHash} on it.\\n *\\n * Documentation for signature generation:\\n * - with https://web3js.readthedocs.io/en/v1.3.4/web3-eth-accounts.html#sign[Web3.js]\\n * - with https://docs.ethers.io/v5/api/signer/#Signer-signMessage[ethers]\\n *\\n * _Available since v4.3._\\n */\\n function tryRecover(bytes32 hash, bytes memory signature) internal pure returns (address, RecoverError) {\\n // Check the signature length\\n // - case 65: r,s,v signature (standard)\\n // - case 64: r,vs signature (cf https://eips.ethereum.org/EIPS/eip-2098) _Available since v4.1._\\n if (signature.length == 65) {\\n bytes32 r;\\n bytes32 s;\\n uint8 v;\\n // ecrecover takes the signature parameters, and the only way to get them\\n // currently is to use assembly.\\n assembly {\\n r := mload(add(signature, 0x20))\\n s := mload(add(signature, 0x40))\\n v := byte(0, mload(add(signature, 0x60)))\\n }\\n return tryRecover(hash, v, r, s);\\n } else if (signature.length == 64) {\\n bytes32 r;\\n bytes32 vs;\\n // ecrecover takes the signature parameters, and the only way to get them\\n // currently is to use assembly.\\n assembly {\\n r := mload(add(signature, 0x20))\\n vs := mload(add(signature, 0x40))\\n }\\n return tryRecover(hash, r, vs);\\n } else {\\n return (address(0), RecoverError.InvalidSignatureLength);\\n }\\n }\\n\\n /**\\n * @dev Returns the address that signed a hashed message (`hash`) with\\n * `signature`. This address can then be used for verification purposes.\\n *\\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\\n * this function rejects them by requiring the `s` value to be in the lower\\n * half order, and the `v` value to be either 27 or 28.\\n *\\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\\n * verification to be secure: it is possible to craft signatures that\\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\\n * this is by receiving a hash of the original message (which may otherwise\\n * be too long), and then calling {toEthSignedMessageHash} on it.\\n */\\n function recover(bytes32 hash, bytes memory signature) internal pure returns (address) {\\n (address recovered, RecoverError error) = tryRecover(hash, signature);\\n _throwError(error);\\n return recovered;\\n }\\n\\n /**\\n * @dev Overload of {ECDSA-tryRecover} that receives the `r` and `vs` short-signature fields separately.\\n *\\n * See https://eips.ethereum.org/EIPS/eip-2098[EIP-2098 short signatures]\\n *\\n * _Available since v4.3._\\n */\\n function tryRecover(\\n bytes32 hash,\\n bytes32 r,\\n bytes32 vs\\n ) internal pure returns (address, RecoverError) {\\n bytes32 s;\\n uint8 v;\\n assembly {\\n s := and(vs, 0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff)\\n v := add(shr(255, vs), 27)\\n }\\n return tryRecover(hash, v, r, s);\\n }\\n\\n /**\\n * @dev Overload of {ECDSA-recover} that receives the `r and `vs` short-signature fields separately.\\n *\\n * _Available since v4.2._\\n */\\n function recover(\\n bytes32 hash,\\n bytes32 r,\\n bytes32 vs\\n ) internal pure returns (address) {\\n (address recovered, RecoverError error) = tryRecover(hash, r, vs);\\n _throwError(error);\\n return recovered;\\n }\\n\\n /**\\n * @dev Overload of {ECDSA-tryRecover} that receives the `v`,\\n * `r` and `s` signature fields separately.\\n *\\n * _Available since v4.3._\\n */\\n function tryRecover(\\n bytes32 hash,\\n uint8 v,\\n bytes32 r,\\n bytes32 s\\n ) internal pure returns (address, RecoverError) {\\n // EIP-2 still allows signature malleability for ecrecover(). Remove this possibility and make the signature\\n // unique. Appendix F in the Ethereum Yellow paper (https://ethereum.github.io/yellowpaper/paper.pdf), defines\\n // the valid range for s in (301): 0 < s < secp256k1n \\u00f7 2 + 1, and for v in (302): v \\u2208 {27, 28}. Most\\n // signatures from current libraries generate a unique signature with an s-value in the lower half order.\\n //\\n // If your library generates malleable signatures, such as s-values in the upper range, calculate a new s-value\\n // with 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141 - s1 and flip v from 27 to 28 or\\n // vice versa. If your library also generates signatures with 0/1 for v instead 27/28, add 27 to v to accept\\n // these malleable signatures as well.\\n if (uint256(s) > 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D576E7357A4501DDFE92F46681B20A0) {\\n return (address(0), RecoverError.InvalidSignatureS);\\n }\\n if (v != 27 && v != 28) {\\n return (address(0), RecoverError.InvalidSignatureV);\\n }\\n\\n // If the signature is valid (and not malleable), return the signer address\\n address signer = ecrecover(hash, v, r, s);\\n if (signer == address(0)) {\\n return (address(0), RecoverError.InvalidSignature);\\n }\\n\\n return (signer, RecoverError.NoError);\\n }\\n\\n /**\\n * @dev Overload of {ECDSA-recover} that receives the `v`,\\n * `r` and `s` signature fields separately.\\n */\\n function recover(\\n bytes32 hash,\\n uint8 v,\\n bytes32 r,\\n bytes32 s\\n ) internal pure returns (address) {\\n (address recovered, RecoverError error) = tryRecover(hash, v, r, s);\\n _throwError(error);\\n return recovered;\\n }\\n\\n /**\\n * @dev Returns an Ethereum Signed Message, created from a `hash`. This\\n * produces hash corresponding to the one signed with the\\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\\n * JSON-RPC method as part of EIP-191.\\n *\\n * See {recover}.\\n */\\n function toEthSignedMessageHash(bytes32 hash) internal pure returns (bytes32) {\\n // 32 is the length in bytes of hash,\\n // enforced by the type signature above\\n return keccak256(abi.encodePacked(\\\"\\\\x19Ethereum Signed Message:\\\\n32\\\", hash));\\n }\\n\\n /**\\n * @dev Returns an Ethereum Signed Message, created from `s`. This\\n * produces hash corresponding to the one signed with the\\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\\n * JSON-RPC method as part of EIP-191.\\n *\\n * See {recover}.\\n */\\n function toEthSignedMessageHash(bytes memory s) internal pure returns (bytes32) {\\n return keccak256(abi.encodePacked(\\\"\\\\x19Ethereum Signed Message:\\\\n\\\", StringsUpgradeable.toString(s.length), s));\\n }\\n\\n /**\\n * @dev Returns an Ethereum Signed Typed Data, created from a\\n * `domainSeparator` and a `structHash`. This produces hash corresponding\\n * to the one signed with the\\n * https://eips.ethereum.org/EIPS/eip-712[`eth_signTypedData`]\\n * JSON-RPC method as part of EIP-712.\\n *\\n * See {recover}.\\n */\\n function toTypedDataHash(bytes32 domainSeparator, bytes32 structHash) internal pure returns (bytes32) {\\n return keccak256(abi.encodePacked(\\\"\\\\x19\\\\x01\\\", domainSeparator, structHash));\\n }\\n}\\n\",\"keccak256\":\"0x1762ac67d230279d7fb183567ce22bbe202054ce08f94224d8794f9d19546d51\",\"license\":\"MIT\"},\"@openzeppelin/contracts-upgradeable/utils/cryptography/draft-EIP712Upgradeable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (utils/cryptography/draft-EIP712.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"./ECDSAUpgradeable.sol\\\";\\nimport \\\"../../proxy/utils/Initializable.sol\\\";\\n\\n/**\\n * @dev https://eips.ethereum.org/EIPS/eip-712[EIP 712] is a standard for hashing and signing of typed structured data.\\n *\\n * The encoding specified in the EIP is very generic, and such a generic implementation in Solidity is not feasible,\\n * thus this contract does not implement the encoding itself. Protocols need to implement the type-specific encoding\\n * they need in their contracts using a combination of `abi.encode` and `keccak256`.\\n *\\n * This contract implements the EIP 712 domain separator ({_domainSeparatorV4}) that is used as part of the encoding\\n * scheme, and the final step of the encoding to obtain the message digest that is then signed via ECDSA\\n * ({_hashTypedDataV4}).\\n *\\n * The implementation of the domain separator was designed to be as efficient as possible while still properly updating\\n * the chain id to protect against replay attacks on an eventual fork of the chain.\\n *\\n * NOTE: This contract implements the version of the encoding known as \\\"v4\\\", as implemented by the JSON RPC method\\n * https://docs.metamask.io/guide/signing-data.html[`eth_signTypedDataV4` in MetaMask].\\n *\\n * _Available since v3.4._\\n */\\nabstract contract EIP712Upgradeable is Initializable {\\n /* solhint-disable var-name-mixedcase */\\n bytes32 private _HASHED_NAME;\\n bytes32 private _HASHED_VERSION;\\n bytes32 private constant _TYPE_HASH = keccak256(\\\"EIP712Domain(string name,string version,uint256 chainId,address verifyingContract)\\\");\\n\\n /* solhint-enable var-name-mixedcase */\\n\\n /**\\n * @dev Initializes the domain separator and parameter caches.\\n *\\n * The meaning of `name` and `version` is specified in\\n * https://eips.ethereum.org/EIPS/eip-712#definition-of-domainseparator[EIP 712]:\\n *\\n * - `name`: the user readable name of the signing domain, i.e. the name of the DApp or the protocol.\\n * - `version`: the current major version of the signing domain.\\n *\\n * NOTE: These parameters cannot be changed except through a xref:learn::upgrading-smart-contracts.adoc[smart\\n * contract upgrade].\\n */\\n function __EIP712_init(string memory name, string memory version) internal onlyInitializing {\\n __EIP712_init_unchained(name, version);\\n }\\n\\n function __EIP712_init_unchained(string memory name, string memory version) internal onlyInitializing {\\n bytes32 hashedName = keccak256(bytes(name));\\n bytes32 hashedVersion = keccak256(bytes(version));\\n _HASHED_NAME = hashedName;\\n _HASHED_VERSION = hashedVersion;\\n }\\n\\n /**\\n * @dev Returns the domain separator for the current chain.\\n */\\n function _domainSeparatorV4() internal view returns (bytes32) {\\n return _buildDomainSeparator(_TYPE_HASH, _EIP712NameHash(), _EIP712VersionHash());\\n }\\n\\n function _buildDomainSeparator(\\n bytes32 typeHash,\\n bytes32 nameHash,\\n bytes32 versionHash\\n ) private view returns (bytes32) {\\n return keccak256(abi.encode(typeHash, nameHash, versionHash, block.chainid, address(this)));\\n }\\n\\n /**\\n * @dev Given an already https://eips.ethereum.org/EIPS/eip-712#definition-of-hashstruct[hashed struct], this\\n * function returns the hash of the fully encoded EIP712 message for this domain.\\n *\\n * This hash can be used together with {ECDSA-recover} to obtain the signer of a message. For example:\\n *\\n * ```solidity\\n * bytes32 digest = _hashTypedDataV4(keccak256(abi.encode(\\n * keccak256(\\\"Mail(address to,string contents)\\\"),\\n * mailTo,\\n * keccak256(bytes(mailContents))\\n * )));\\n * address signer = ECDSA.recover(digest, signature);\\n * ```\\n */\\n function _hashTypedDataV4(bytes32 structHash) internal view virtual returns (bytes32) {\\n return ECDSAUpgradeable.toTypedDataHash(_domainSeparatorV4(), structHash);\\n }\\n\\n /**\\n * @dev The hash of the name parameter for the EIP712 domain.\\n *\\n * NOTE: This function reads from storage by default, but can be redefined to return a constant value if gas costs\\n * are a concern.\\n */\\n function _EIP712NameHash() internal virtual view returns (bytes32) {\\n return _HASHED_NAME;\\n }\\n\\n /**\\n * @dev The hash of the version parameter for the EIP712 domain.\\n *\\n * NOTE: This function reads from storage by default, but can be redefined to return a constant value if gas costs\\n * are a concern.\\n */\\n function _EIP712VersionHash() internal virtual view returns (bytes32) {\\n return _HASHED_VERSION;\\n }\\n uint256[50] private __gap;\\n}\\n\",\"keccak256\":\"0x92e61d8dd5ba90b513769c06da820e0a8f5d93810a9c6d5207308af345815011\",\"license\":\"MIT\"},\"@openzeppelin/contracts/token/ERC20/IERC20.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (token/ERC20/IERC20.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Interface of the ERC20 standard as defined in the EIP.\\n */\\ninterface IERC20 {\\n /**\\n * @dev Returns the amount of tokens in existence.\\n */\\n function totalSupply() external view returns (uint256);\\n\\n /**\\n * @dev Returns the amount of tokens owned by `account`.\\n */\\n function balanceOf(address account) external view returns (uint256);\\n\\n /**\\n * @dev Moves `amount` tokens from the caller's account to `recipient`.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * Emits a {Transfer} event.\\n */\\n function transfer(address recipient, uint256 amount) external returns (bool);\\n\\n /**\\n * @dev Returns the remaining number of tokens that `spender` will be\\n * allowed to spend on behalf of `owner` through {transferFrom}. This is\\n * zero by default.\\n *\\n * This value changes when {approve} or {transferFrom} are called.\\n */\\n function allowance(address owner, address spender) external view returns (uint256);\\n\\n /**\\n * @dev Sets `amount` as the allowance of `spender` over the caller's tokens.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * IMPORTANT: Beware that changing an allowance with this method brings the risk\\n * that someone may use both the old and the new allowance by unfortunate\\n * transaction ordering. One possible solution to mitigate this race\\n * condition is to first reduce the spender's allowance to 0 and set the\\n * desired value afterwards:\\n * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729\\n *\\n * Emits an {Approval} event.\\n */\\n function approve(address spender, uint256 amount) external returns (bool);\\n\\n /**\\n * @dev Moves `amount` tokens from `sender` to `recipient` using the\\n * allowance mechanism. `amount` is then deducted from the caller's\\n * allowance.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * Emits a {Transfer} event.\\n */\\n function transferFrom(\\n address sender,\\n address recipient,\\n uint256 amount\\n ) external returns (bool);\\n\\n /**\\n * @dev Emitted when `value` tokens are moved from one account (`from`) to\\n * another (`to`).\\n *\\n * Note that `value` may be zero.\\n */\\n event Transfer(address indexed from, address indexed to, uint256 value);\\n\\n /**\\n * @dev Emitted when the allowance of a `spender` for an `owner` is set by\\n * a call to {approve}. `value` is the new allowance.\\n */\\n event Approval(address indexed owner, address indexed spender, uint256 value);\\n}\\n\",\"keccak256\":\"0x61437cb513a887a1bbad006e7b1c8b414478427d33de47c5600af3c748f108da\",\"license\":\"MIT\"},\"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (token/ERC20/utils/SafeERC20.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../IERC20.sol\\\";\\nimport \\\"../../../utils/Address.sol\\\";\\n\\n/**\\n * @title SafeERC20\\n * @dev Wrappers around ERC20 operations that throw on failure (when the token\\n * contract returns false). Tokens that return no value (and instead revert or\\n * throw on failure) are also supported, non-reverting calls are assumed to be\\n * successful.\\n * To use this library you can add a `using SafeERC20 for IERC20;` statement to your contract,\\n * which allows you to call the safe operations as `token.safeTransfer(...)`, etc.\\n */\\nlibrary SafeERC20 {\\n using Address for address;\\n\\n function safeTransfer(\\n IERC20 token,\\n address to,\\n uint256 value\\n ) internal {\\n _callOptionalReturn(token, abi.encodeWithSelector(token.transfer.selector, to, value));\\n }\\n\\n function safeTransferFrom(\\n IERC20 token,\\n address from,\\n address to,\\n uint256 value\\n ) internal {\\n _callOptionalReturn(token, abi.encodeWithSelector(token.transferFrom.selector, from, to, value));\\n }\\n\\n /**\\n * @dev Deprecated. This function has issues similar to the ones found in\\n * {IERC20-approve}, and its usage is discouraged.\\n *\\n * Whenever possible, use {safeIncreaseAllowance} and\\n * {safeDecreaseAllowance} instead.\\n */\\n function safeApprove(\\n IERC20 token,\\n address spender,\\n uint256 value\\n ) internal {\\n // safeApprove should only be called when setting an initial allowance,\\n // or when resetting it to zero. To increase and decrease it, use\\n // 'safeIncreaseAllowance' and 'safeDecreaseAllowance'\\n require(\\n (value == 0) || (token.allowance(address(this), spender) == 0),\\n \\\"SafeERC20: approve from non-zero to non-zero allowance\\\"\\n );\\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, value));\\n }\\n\\n function safeIncreaseAllowance(\\n IERC20 token,\\n address spender,\\n uint256 value\\n ) internal {\\n uint256 newAllowance = token.allowance(address(this), spender) + value;\\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));\\n }\\n\\n function safeDecreaseAllowance(\\n IERC20 token,\\n address spender,\\n uint256 value\\n ) internal {\\n unchecked {\\n uint256 oldAllowance = token.allowance(address(this), spender);\\n require(oldAllowance >= value, \\\"SafeERC20: decreased allowance below zero\\\");\\n uint256 newAllowance = oldAllowance - value;\\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));\\n }\\n }\\n\\n /**\\n * @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement\\n * on the return value: the return value is optional (but if data is returned, it must not be false).\\n * @param token The token targeted by the call.\\n * @param data The call data (encoded using abi.encode or one of its variants).\\n */\\n function _callOptionalReturn(IERC20 token, bytes memory data) private {\\n // We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since\\n // we're implementing it ourselves. We use {Address.functionCall} to perform this call, which verifies that\\n // the target address contains contract code and also asserts for success in the low-level call.\\n\\n bytes memory returndata = address(token).functionCall(data, \\\"SafeERC20: low-level call failed\\\");\\n if (returndata.length > 0) {\\n // Return data is optional\\n require(abi.decode(returndata, (bool)), \\\"SafeERC20: ERC20 operation did not succeed\\\");\\n }\\n }\\n}\\n\",\"keccak256\":\"0xc3d946432c0ddbb1f846a0d3985be71299df331b91d06732152117f62f0be2b5\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/Address.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (utils/Address.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Collection of functions related to the address type\\n */\\nlibrary Address {\\n /**\\n * @dev Returns true if `account` is a contract.\\n *\\n * [IMPORTANT]\\n * ====\\n * It is unsafe to assume that an address for which this function returns\\n * false is an externally-owned account (EOA) and not a contract.\\n *\\n * Among others, `isContract` will return false for the following\\n * types of addresses:\\n *\\n * - an externally-owned account\\n * - a contract in construction\\n * - an address where a contract will be created\\n * - an address where a contract lived, but was destroyed\\n * ====\\n */\\n function isContract(address account) internal view returns (bool) {\\n // This method relies on extcodesize, which returns 0 for contracts in\\n // construction, since the code is only stored at the end of the\\n // constructor execution.\\n\\n uint256 size;\\n assembly {\\n size := extcodesize(account)\\n }\\n return size > 0;\\n }\\n\\n /**\\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\\n * `recipient`, forwarding all available gas and reverting on errors.\\n *\\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\\n * imposed by `transfer`, making them unable to receive funds via\\n * `transfer`. {sendValue} removes this limitation.\\n *\\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\\n *\\n * IMPORTANT: because control is transferred to `recipient`, care must be\\n * taken to not create reentrancy vulnerabilities. Consider using\\n * {ReentrancyGuard} or the\\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\\n */\\n function sendValue(address payable recipient, uint256 amount) internal {\\n require(address(this).balance >= amount, \\\"Address: insufficient balance\\\");\\n\\n (bool success, ) = recipient.call{value: amount}(\\\"\\\");\\n require(success, \\\"Address: unable to send value, recipient may have reverted\\\");\\n }\\n\\n /**\\n * @dev Performs a Solidity function call using a low level `call`. A\\n * plain `call` is an unsafe replacement for a function call: use this\\n * function instead.\\n *\\n * If `target` reverts with a revert reason, it is bubbled up by this\\n * function (like regular Solidity function calls).\\n *\\n * Returns the raw returned data. To convert to the expected return value,\\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\\n *\\n * Requirements:\\n *\\n * - `target` must be a contract.\\n * - calling `target` with `data` must not revert.\\n *\\n * _Available since v3.1._\\n */\\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\\n return functionCall(target, data, \\\"Address: low-level call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\\n * `errorMessage` as a fallback revert reason when `target` reverts.\\n *\\n * _Available since v3.1._\\n */\\n function functionCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n return functionCallWithValue(target, data, 0, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but also transferring `value` wei to `target`.\\n *\\n * Requirements:\\n *\\n * - the calling contract must have an ETH balance of at least `value`.\\n * - the called Solidity function must be `payable`.\\n *\\n * _Available since v3.1._\\n */\\n function functionCallWithValue(\\n address target,\\n bytes memory data,\\n uint256 value\\n ) internal returns (bytes memory) {\\n return functionCallWithValue(target, data, value, \\\"Address: low-level call with value failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\\n * with `errorMessage` as a fallback revert reason when `target` reverts.\\n *\\n * _Available since v3.1._\\n */\\n function functionCallWithValue(\\n address target,\\n bytes memory data,\\n uint256 value,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n require(address(this).balance >= value, \\\"Address: insufficient balance for call\\\");\\n require(isContract(target), \\\"Address: call to non-contract\\\");\\n\\n (bool success, bytes memory returndata) = target.call{value: value}(data);\\n return verifyCallResult(success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but performing a static call.\\n *\\n * _Available since v3.3._\\n */\\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\\n return functionStaticCall(target, data, \\\"Address: low-level static call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\\n * but performing a static call.\\n *\\n * _Available since v3.3._\\n */\\n function functionStaticCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal view returns (bytes memory) {\\n require(isContract(target), \\\"Address: static call to non-contract\\\");\\n\\n (bool success, bytes memory returndata) = target.staticcall(data);\\n return verifyCallResult(success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but performing a delegate call.\\n *\\n * _Available since v3.4._\\n */\\n function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {\\n return functionDelegateCall(target, data, \\\"Address: low-level delegate call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\\n * but performing a delegate call.\\n *\\n * _Available since v3.4._\\n */\\n function functionDelegateCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n require(isContract(target), \\\"Address: delegate call to non-contract\\\");\\n\\n (bool success, bytes memory returndata) = target.delegatecall(data);\\n return verifyCallResult(success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the\\n * revert reason using the provided one.\\n *\\n * _Available since v4.3._\\n */\\n function verifyCallResult(\\n bool success,\\n bytes memory returndata,\\n string memory errorMessage\\n ) internal pure returns (bytes memory) {\\n if (success) {\\n return returndata;\\n } else {\\n // Look for revert reason and bubble it up if present\\n if (returndata.length > 0) {\\n // The easiest way to bubble the revert reason is using memory via assembly\\n\\n assembly {\\n let returndata_size := mload(returndata)\\n revert(add(32, returndata), returndata_size)\\n }\\n } else {\\n revert(errorMessage);\\n }\\n }\\n }\\n}\\n\",\"keccak256\":\"0x51b758a8815ecc9596c66c37d56b1d33883a444631a3f916b9fe65cb863ef7c4\",\"license\":\"MIT\"},\"contracts/agToken/AgTokenSideChainMultiBridge.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-3.0\\n\\npragma solidity 0.8.12;\\n\\nimport \\\"./BaseAgTokenSideChain.sol\\\";\\nimport \\\"@openzeppelin/contracts/token/ERC20/IERC20.sol\\\";\\nimport \\\"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\\\";\\n\\n/// @title AgTokenSideChainMultiBridge\\n/// @author Angle Core Team\\n/// @notice Contract for Angle agTokens on other chains than Ethereum mainnet\\n/// @dev This contract supports bridge tokens having a minting right on the stablecoin (also referred to as the canonical\\n/// or the native token)\\n/// @dev References:\\n/// - FRAX implementation: https://polygonscan.com/address/0x45c32fA6DF82ead1e2EF74d17b76547EDdFaFF89#code\\n/// - QiDAO implementation: https://snowtrace.io/address/0x5c49b268c9841AFF1Cc3B0a418ff5c3442eE3F3b#code\\ncontract AgTokenSideChainMultiBridge is BaseAgTokenSideChain {\\n using SafeERC20 for IERC20;\\n\\n /// @notice Base used for fee computation\\n uint256 public constant BASE_PARAMS = 10**9;\\n\\n // =============================== Bridging Data ===============================\\n\\n /// @notice Struct with some data about a specific bridge token\\n struct BridgeDetails {\\n // Limit on the balance of bridge token held by the contract: it is designed\\n // to reduce the exposure of the system to hacks\\n uint256 limit;\\n // Limit on the hourly volume of token minted through this bridge\\n // Technically the limit over a rolling hour is hourlyLimit x2 as hourly limit\\n // is enforced only between x:00 and x+1:00\\n uint256 hourlyLimit;\\n // Fee taken for swapping in and out the token\\n uint64 fee;\\n // Whether the associated token is allowed or not\\n bool allowed;\\n // Whether swapping in and out from the associated token is paused or not\\n bool paused;\\n }\\n\\n /// @notice Maps a bridge token to data\\n mapping(address => BridgeDetails) public bridges;\\n /// @notice List of all bridge tokens\\n address[] public bridgeTokensList;\\n /// @notice Maps a bridge token to the associated hourly volume\\n mapping(address => mapping(uint256 => uint256)) public usage;\\n /// @notice Maps an address to whether it is exempt of fees for when it comes to swapping in and out\\n mapping(address => uint256) public isFeeExempt;\\n /// @notice Limit to the amount of tokens that can be sent from that chain to another chain\\n uint256 public chainTotalHourlyLimit;\\n /// @notice Usage per hour on that chain. Maps an hourly timestamp to the total volume swapped out on the chain\\n mapping(uint256 => uint256) public chainTotalUsage;\\n\\n // ================================== Events ===================================\\n\\n event BridgeTokenAdded(address indexed bridgeToken, uint256 limit, uint256 hourlyLimit, uint64 fee, bool paused);\\n event BridgeTokenToggled(address indexed bridgeToken, bool toggleStatus);\\n event BridgeTokenRemoved(address indexed bridgeToken);\\n event BridgeTokenFeeUpdated(address indexed bridgeToken, uint64 fee);\\n event BridgeTokenLimitUpdated(address indexed bridgeToken, uint256 limit);\\n event BridgeTokenHourlyLimitUpdated(address indexed bridgeToken, uint256 hourlyLimit);\\n event HourlyLimitUpdated(uint256 hourlyLimit);\\n event Recovered(address indexed token, address indexed to, uint256 amount);\\n event FeeToggled(address indexed theAddress, uint256 toggleStatus);\\n\\n // =============================== Errors ================================\\n\\n error AssetStillControlledInReserves();\\n error HourlyLimitExceeded();\\n error InvalidToken();\\n error NotGovernor();\\n error NotGovernorOrGuardian();\\n error TooBigAmount();\\n error TooHighParameterValue();\\n error ZeroAddress();\\n\\n // ============================= Constructor ===================================\\n\\n /// @notice Initializes the `AgToken` contract\\n /// @param name_ Name of the token\\n /// @param symbol_ Symbol of the token\\n /// @param _treasury Reference to the `Treasury` contract associated to this agToken\\n /// @dev By default, agTokens are ERC-20 tokens with 18 decimals\\n function initialize(\\n string memory name_,\\n string memory symbol_,\\n address _treasury\\n ) external {\\n _initialize(name_, symbol_, _treasury);\\n }\\n\\n // =============================== Modifiers ===================================\\n\\n /// @notice Checks whether the `msg.sender` has the governor role or not\\n modifier onlyGovernor() {\\n if (!ITreasury(treasury).isGovernor(msg.sender)) revert NotGovernor();\\n _;\\n }\\n\\n /// @notice Checks whether the `msg.sender` has the governor role or the guardian role\\n modifier onlyGovernorOrGuardian() {\\n if (!ITreasury(treasury).isGovernorOrGuardian(msg.sender)) revert NotGovernorOrGuardian();\\n _;\\n }\\n\\n // ==================== External Permissionless Functions ======================\\n\\n /// @notice Returns the list of all supported bridge tokens\\n /// @dev Helpful for UIs\\n function allBridgeTokens() external view returns (address[] memory) {\\n return bridgeTokensList;\\n }\\n\\n /// @notice Returns the current volume for a bridge, for the current hour\\n /// @param bridgeToken Bridge used to mint\\n /// @dev Helpful for UIs\\n function currentUsage(address bridgeToken) external view returns (uint256) {\\n return usage[bridgeToken][block.timestamp / 3600];\\n }\\n\\n /// @notice Returns the current total volume on the chain for the current hour\\n /// @dev Helpful for UIs\\n function currentTotalUsage() external view returns (uint256) {\\n return chainTotalUsage[block.timestamp / 3600];\\n }\\n\\n /// @notice Mints the canonical token from a supported bridge token\\n /// @param bridgeToken Bridge token to use to mint\\n /// @param amount Amount of bridge tokens to send\\n /// @param to Address to which the stablecoin should be sent\\n /// @return Amount of the canonical stablecoin actually minted\\n /// @dev Some fees may be taken by the protocol depending on the token used and on the address calling\\n function swapIn(\\n address bridgeToken,\\n uint256 amount,\\n address to\\n ) external returns (uint256) {\\n BridgeDetails memory bridgeDetails = bridges[bridgeToken];\\n if (!bridgeDetails.allowed || bridgeDetails.paused) revert InvalidToken();\\n uint256 balance = IERC20(bridgeToken).balanceOf(address(this));\\n if (balance + amount > bridgeDetails.limit) {\\n // In case someone maliciously sends tokens to this contract\\n // Or the limit changes\\n if (bridgeDetails.limit > balance) amount = bridgeDetails.limit - balance;\\n else {\\n amount = 0;\\n }\\n }\\n\\n // Checking requirement on the hourly volume\\n uint256 hour = block.timestamp / 3600;\\n uint256 hourlyUsage = usage[bridgeToken][hour] + amount;\\n if (hourlyUsage > bridgeDetails.hourlyLimit) {\\n // Edge case when the hourly limit changes\\n if (bridgeDetails.hourlyLimit > usage[bridgeToken][hour])\\n amount = bridgeDetails.hourlyLimit - usage[bridgeToken][hour];\\n else {\\n amount = 0;\\n }\\n }\\n usage[bridgeToken][hour] = usage[bridgeToken][hour] + amount;\\n\\n IERC20(bridgeToken).safeTransferFrom(msg.sender, address(this), amount);\\n uint256 canonicalOut = amount;\\n // Computing fees\\n if (isFeeExempt[msg.sender] == 0) {\\n canonicalOut -= (canonicalOut * bridgeDetails.fee) / BASE_PARAMS;\\n }\\n _mint(to, canonicalOut);\\n return canonicalOut;\\n }\\n\\n /// @notice Burns the canonical token in exchange for a bridge token\\n /// @param bridgeToken Bridge token required\\n /// @param amount Amount of canonical tokens to burn\\n /// @param to Address to which the bridge token should be sent\\n /// @return Amount of bridge tokens actually sent back\\n /// @dev Some fees may be taken by the protocol depending on the token used and on the address calling\\n function swapOut(\\n address bridgeToken,\\n uint256 amount,\\n address to\\n ) external returns (uint256) {\\n BridgeDetails memory bridgeDetails = bridges[bridgeToken];\\n if (!bridgeDetails.allowed || bridgeDetails.paused) revert InvalidToken();\\n\\n uint256 hour = block.timestamp / 3600;\\n uint256 hourlyUsage = chainTotalUsage[hour] + amount;\\n // If the amount being swapped out exceeds the limit, we revert\\n // We don't want to change the amount being swapped out.\\n // The user can decide to send another tx with the correct amount to reach the limit\\n if (hourlyUsage > chainTotalHourlyLimit) revert HourlyLimitExceeded();\\n chainTotalUsage[hour] = hourlyUsage;\\n\\n _burn(msg.sender, amount);\\n uint256 bridgeOut = amount;\\n if (isFeeExempt[msg.sender] == 0) {\\n bridgeOut -= (bridgeOut * bridgeDetails.fee) / BASE_PARAMS;\\n }\\n IERC20(bridgeToken).safeTransfer(to, bridgeOut);\\n return bridgeOut;\\n }\\n\\n // ======================= Governance Functions ================================\\n\\n /// @notice Adds support for a bridge token\\n /// @param bridgeToken Bridge token to add: it should be a version of the stablecoin from another bridge\\n /// @param limit Limit on the balance of bridge token this contract could hold\\n /// @param hourlyLimit Limit on the hourly volume for this bridge\\n /// @param paused Whether swapping for this token should be paused or not\\n /// @param fee Fee taken upon swapping for or against this token\\n function addBridgeToken(\\n address bridgeToken,\\n uint256 limit,\\n uint256 hourlyLimit,\\n uint64 fee,\\n bool paused\\n ) external onlyGovernor {\\n if (bridges[bridgeToken].allowed || bridgeToken == address(0)) revert InvalidToken();\\n if (fee > BASE_PARAMS) revert TooHighParameterValue();\\n BridgeDetails memory _bridge;\\n _bridge.limit = limit;\\n _bridge.hourlyLimit = hourlyLimit;\\n _bridge.paused = paused;\\n _bridge.fee = fee;\\n _bridge.allowed = true;\\n bridges[bridgeToken] = _bridge;\\n bridgeTokensList.push(bridgeToken);\\n emit BridgeTokenAdded(bridgeToken, limit, hourlyLimit, fee, paused);\\n }\\n\\n /// @notice Removes support for a token\\n /// @param bridgeToken Address of the bridge token to remove support for\\n function removeBridgeToken(address bridgeToken) external onlyGovernor {\\n if (IERC20(bridgeToken).balanceOf(address(this)) != 0) revert AssetStillControlledInReserves();\\n delete bridges[bridgeToken];\\n // Deletion from `bridgeTokensList` loop\\n uint256 bridgeTokensListLength = bridgeTokensList.length;\\n for (uint256 i = 0; i < bridgeTokensListLength - 1; i++) {\\n if (bridgeTokensList[i] == bridgeToken) {\\n // Replace the `bridgeToken` to remove with the last of the list\\n bridgeTokensList[i] = bridgeTokensList[bridgeTokensListLength - 1];\\n break;\\n }\\n }\\n // Remove last element in array\\n bridgeTokensList.pop();\\n emit BridgeTokenRemoved(bridgeToken);\\n }\\n\\n /// @notice Recovers any ERC20 token\\n /// @dev Can be used to withdraw bridge tokens for them to be de-bridged on mainnet\\n function recoverERC20(\\n address tokenAddress,\\n address to,\\n uint256 amountToRecover\\n ) external onlyGovernor {\\n IERC20(tokenAddress).safeTransfer(to, amountToRecover);\\n emit Recovered(tokenAddress, to, amountToRecover);\\n }\\n\\n /// @notice Updates the `limit` amount for `bridgeToken`\\n function setLimit(address bridgeToken, uint256 limit) external onlyGovernorOrGuardian {\\n if (!bridges[bridgeToken].allowed) revert InvalidToken();\\n bridges[bridgeToken].limit = limit;\\n emit BridgeTokenLimitUpdated(bridgeToken, limit);\\n }\\n\\n /// @notice Updates the `hourlyLimit` amount for `bridgeToken`\\n function setHourlyLimit(address bridgeToken, uint256 hourlyLimit) external onlyGovernorOrGuardian {\\n if (!bridges[bridgeToken].allowed) revert InvalidToken();\\n bridges[bridgeToken].hourlyLimit = hourlyLimit;\\n emit BridgeTokenHourlyLimitUpdated(bridgeToken, hourlyLimit);\\n }\\n\\n /// @notice Updates the `chainTotalHourlyLimit` amount\\n function setChainTotalHourlyLimit(uint256 hourlyLimit) external onlyGovernorOrGuardian {\\n chainTotalHourlyLimit = hourlyLimit;\\n emit HourlyLimitUpdated(hourlyLimit);\\n }\\n\\n /// @notice Updates the `fee` value for `bridgeToken`\\n function setSwapFee(address bridgeToken, uint64 fee) external onlyGovernorOrGuardian {\\n if (!bridges[bridgeToken].allowed) revert InvalidToken();\\n if (fee > BASE_PARAMS) revert TooHighParameterValue();\\n bridges[bridgeToken].fee = fee;\\n emit BridgeTokenFeeUpdated(bridgeToken, fee);\\n }\\n\\n /// @notice Pauses or unpauses swapping in and out for a token\\n function toggleBridge(address bridgeToken) external onlyGovernorOrGuardian {\\n if (!bridges[bridgeToken].allowed) revert InvalidToken();\\n bool pausedStatus = bridges[bridgeToken].paused;\\n bridges[bridgeToken].paused = !pausedStatus;\\n emit BridgeTokenToggled(bridgeToken, !pausedStatus);\\n }\\n\\n /// @notice Toggles fees for the address `theAddress`\\n function toggleFeesForAddress(address theAddress) external onlyGovernorOrGuardian {\\n uint256 feeExemptStatus = 1 - isFeeExempt[theAddress];\\n isFeeExempt[theAddress] = feeExemptStatus;\\n emit FeeToggled(theAddress, feeExemptStatus);\\n }\\n}\\n\",\"keccak256\":\"0xf2f2d77a9504fa20ef62faae227c548cc32d8f796ef427864ec79580617d0cb3\",\"license\":\"GPL-3.0\"},\"contracts/agToken/BaseAgTokenSideChain.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-3.0\\n\\npragma solidity 0.8.12;\\n\\nimport \\\"../interfaces/IAgToken.sol\\\";\\nimport \\\"../interfaces/ITreasury.sol\\\";\\nimport \\\"@openzeppelin/contracts-upgradeable/token/ERC20/extensions/draft-ERC20PermitUpgradeable.sol\\\";\\n\\n/// @title BaseAgTokenSideChain\\n/// @author Angle Core Team\\n/// @notice Base Contract for Angle agTokens on other chains than Ethereum mainnet\\n/// @dev This type of contract can be used to create and handle the stablecoins of Angle protocol in different chains than Ethereum\\ncontract BaseAgTokenSideChain is IAgToken, ERC20PermitUpgradeable {\\n // ======================= Parameters and Variables ============================\\n\\n /// @inheritdoc IAgToken\\n mapping(address => bool) public isMinter;\\n /// @notice Reference to the treasury contract which can grant minting rights\\n address public treasury;\\n\\n // ================================== Events ===================================\\n\\n event TreasuryUpdated(address indexed _treasury);\\n event MinterToggled(address indexed minter);\\n\\n // =============================== Errors ================================\\n\\n error BurnAmountExceedsAllowance();\\n error InvalidSender();\\n error InvalidTreasury();\\n error NotMinter();\\n error NotTreasury();\\n\\n // ============================= Constructor ===================================\\n\\n /// @notice Initializes the contract\\n /// @param name_ Name of the token\\n /// @param symbol_ Symbol of the token\\n /// @param _treasury Reference to the `Treasury` contract associated to this agToken implementation\\n /// @dev By default, agTokens are ERC-20 tokens with 18 decimals\\n function _initialize(\\n string memory name_,\\n string memory symbol_,\\n address _treasury\\n ) internal initializer {\\n __ERC20Permit_init(name_);\\n __ERC20_init(name_, symbol_);\\n if (address(ITreasury(_treasury).stablecoin()) != address(this)) revert InvalidTreasury();\\n treasury = _treasury;\\n emit TreasuryUpdated(address(_treasury));\\n }\\n\\n /// @custom:oz-upgrades-unsafe-allow constructor\\n constructor() initializer {}\\n\\n // =============================== Modifiers ===================================\\n\\n /// @notice Checks to see if it is the `Treasury` calling this contract\\n /// @dev There is no Access Control here, because it can be handled cheaply through this modifier\\n modifier onlyTreasury() {\\n if (msg.sender != address(treasury)) revert NotTreasury();\\n _;\\n }\\n\\n /// @notice Checks whether the sender has the minting right\\n modifier onlyMinter() {\\n if (!isMinter[msg.sender]) revert NotMinter();\\n _;\\n }\\n\\n // =========================== External Function ===============================\\n\\n /// @notice Allows anyone to burn agToken without redeeming collateral back\\n /// @param amount Amount of stablecoins to burn\\n /// @dev This function can typically be called if there is a settlement mechanism to burn stablecoins\\n function burnStablecoin(uint256 amount) external {\\n _burn(msg.sender, amount);\\n }\\n\\n // ======================= Minter Role Only Functions ==========================\\n\\n /// @inheritdoc IAgToken\\n function burnSelf(uint256 amount, address burner) external onlyMinter {\\n _burn(burner, amount);\\n }\\n\\n /// @inheritdoc IAgToken\\n function burnFrom(\\n uint256 amount,\\n address burner,\\n address sender\\n ) external onlyMinter {\\n _burnFromNoRedeem(amount, burner, sender);\\n }\\n\\n /// @inheritdoc IAgToken\\n function mint(address account, uint256 amount) external onlyMinter {\\n _mint(account, amount);\\n }\\n\\n // ======================= Treasury Only Functions =============================\\n\\n /// @inheritdoc IAgToken\\n function addMinter(address minter) external onlyTreasury {\\n isMinter[minter] = true;\\n emit MinterToggled(minter);\\n }\\n\\n /// @inheritdoc IAgToken\\n function removeMinter(address minter) external {\\n if (msg.sender != address(treasury) && msg.sender != minter) revert InvalidSender();\\n isMinter[minter] = false;\\n emit MinterToggled(minter);\\n }\\n\\n /// @inheritdoc IAgToken\\n function setTreasury(address _treasury) external onlyTreasury {\\n treasury = _treasury;\\n emit TreasuryUpdated(_treasury);\\n }\\n\\n // ============================ Internal Function ==============================\\n\\n /// @notice Internal version of the function `burnFromNoRedeem`\\n /// @param amount Amount to burn\\n /// @dev It is at the level of this function that allowance checks are performed\\n function _burnFromNoRedeem(\\n uint256 amount,\\n address burner,\\n address sender\\n ) internal {\\n if (burner != sender) {\\n uint256 currentAllowance = allowance(burner, sender);\\n if (currentAllowance < amount) revert BurnAmountExceedsAllowance();\\n _approve(burner, sender, currentAllowance - amount);\\n }\\n _burn(burner, amount);\\n }\\n}\\n\",\"keccak256\":\"0xf54ef7218eba0e71f2b57da57956646f0227356fc18a55c8984f6c6a8f592077\",\"license\":\"GPL-3.0\"},\"contracts/interfaces/IAgToken.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-3.0\\n\\npragma solidity 0.8.12;\\n\\nimport \\\"@openzeppelin/contracts-upgradeable/token/ERC20/IERC20Upgradeable.sol\\\";\\n\\n/// @title IAgToken\\n/// @author Angle Core Team\\n/// @notice Interface for the stablecoins `AgToken` contracts\\n/// @dev This interface only contains functions of the `AgToken` contract which are called by other contracts\\n/// of this module or of the first module of the Angle Protocol\\ninterface IAgToken is IERC20Upgradeable {\\n // ======================= Minter Role Only Functions ===========================\\n\\n /// @notice Lets the `StableMaster` contract or another whitelisted contract mint agTokens\\n /// @param account Address to mint to\\n /// @param amount Amount to mint\\n /// @dev The contracts allowed to issue agTokens are the `StableMaster` contract, `VaultManager` contracts\\n /// associated to this stablecoin as well as the flash loan module (if activated) and potentially contracts\\n /// whitelisted by governance\\n function mint(address account, uint256 amount) external;\\n\\n /// @notice Burns `amount` tokens from a `burner` address after being asked to by `sender`\\n /// @param amount Amount of tokens to burn\\n /// @param burner Address to burn from\\n /// @param sender Address which requested the burn from `burner`\\n /// @dev This method is to be called by a contract with the minter right after being requested\\n /// to do so by a `sender` address willing to burn tokens from another `burner` address\\n /// @dev The method checks the allowance between the `sender` and the `burner`\\n function burnFrom(\\n uint256 amount,\\n address burner,\\n address sender\\n ) external;\\n\\n /// @notice Burns `amount` tokens from a `burner` address\\n /// @param amount Amount of tokens to burn\\n /// @param burner Address to burn from\\n /// @dev This method is to be called by a contract with a minter right on the AgToken after being\\n /// requested to do so by an address willing to burn tokens from its address\\n function burnSelf(uint256 amount, address burner) external;\\n\\n // ========================= Treasury Only Functions ===========================\\n\\n /// @notice Adds a minter in the contract\\n /// @param minter Minter address to add\\n /// @dev Zero address checks are performed directly in the `Treasury` contract\\n function addMinter(address minter) external;\\n\\n /// @notice Removes a minter from the contract\\n /// @param minter Minter address to remove\\n /// @dev This function can also be called by a minter wishing to revoke itself\\n function removeMinter(address minter) external;\\n\\n /// @notice Sets a new treasury contract\\n /// @param _treasury New treasury address\\n function setTreasury(address _treasury) external;\\n\\n // ========================= External functions ================================\\n\\n /// @notice Checks whether an address has the right to mint agTokens\\n /// @param minter Address for which the minting right should be checked\\n /// @return Whether the address has the right to mint agTokens or not\\n function isMinter(address minter) external view returns (bool);\\n}\\n\",\"keccak256\":\"0xcd50d86128e457543483981ea6127cb8dac03584b919614352aa89d7e991405c\",\"license\":\"GPL-3.0\"},\"contracts/interfaces/ICoreBorrow.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-3.0\\n\\npragma solidity 0.8.12;\\n\\n/// @title ICoreBorrow\\n/// @author Angle Core Team\\n/// @notice Interface for the `CoreBorrow` contract\\n/// @dev This interface only contains functions of the `CoreBorrow` contract which are called by other contracts\\n/// of this module\\ninterface ICoreBorrow {\\n /// @notice Checks if an address corresponds to a treasury of a stablecoin with a flash loan\\n /// module initialized on it\\n /// @param treasury Address to check\\n /// @return Whether the address has the `FLASHLOANER_TREASURY_ROLE` or not\\n function isFlashLoanerTreasury(address treasury) external view returns (bool);\\n\\n /// @notice Checks whether an address is governor of the Angle Protocol or not\\n /// @param admin Address to check\\n /// @return Whether the address has the `GOVERNOR_ROLE` or not\\n function isGovernor(address admin) external view returns (bool);\\n\\n /// @notice Checks whether an address is governor or a guardian of the Angle Protocol or not\\n /// @param admin Address to check\\n /// @return Whether the address has the `GUARDIAN_ROLE` or not\\n /// @dev Governance should make sure when adding a governor to also give this governor the guardian\\n /// role by calling the `addGovernor` function\\n function isGovernorOrGuardian(address admin) external view returns (bool);\\n}\\n\",\"keccak256\":\"0x25b65b3f506ca91745a444502a36f0556585d82d9d60f4bd32fbcaabc12840d4\",\"license\":\"GPL-3.0\"},\"contracts/interfaces/IFlashAngle.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-3.0\\n\\npragma solidity 0.8.12;\\n\\nimport \\\"./IAgToken.sol\\\";\\nimport \\\"./ICoreBorrow.sol\\\";\\n\\n/// @title IFlashAngle\\n/// @author Angle Core Team\\n/// @notice Interface for the `FlashAngle` contract\\n/// @dev This interface only contains functions of the contract which are called by other contracts\\n/// of this module\\ninterface IFlashAngle {\\n /// @notice Reference to the `CoreBorrow` contract managing the FlashLoan module\\n function core() external view returns (ICoreBorrow);\\n\\n /// @notice Sends the fees taken from flash loans to the treasury contract associated to the stablecoin\\n /// @param stablecoin Stablecoin from which profits should be sent\\n /// @return balance Amount of profits sent\\n /// @dev This function can only be called by the treasury contract\\n function accrueInterestToTreasury(IAgToken stablecoin) external returns (uint256 balance);\\n\\n /// @notice Adds support for a stablecoin\\n /// @param _treasury Treasury associated to the stablecoin to add support for\\n /// @dev This function can only be called by the `CoreBorrow` contract\\n function addStablecoinSupport(address _treasury) external;\\n\\n /// @notice Removes support for a stablecoin\\n /// @param _treasury Treasury associated to the stablecoin to remove support for\\n /// @dev This function can only be called by the `CoreBorrow` contract\\n function removeStablecoinSupport(address _treasury) external;\\n\\n /// @notice Sets a new core contract\\n /// @param _core Core contract address to set\\n /// @dev This function can only be called by the `CoreBorrow` contract\\n function setCore(address _core) external;\\n}\\n\",\"keccak256\":\"0xc17654e512897efe41e3f1173c07dd4676e8c699a72b859d14b473d1e8300e45\",\"license\":\"GPL-3.0\"},\"contracts/interfaces/ITreasury.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-3.0\\n\\npragma solidity 0.8.12;\\n\\nimport \\\"./IAgToken.sol\\\";\\nimport \\\"./ICoreBorrow.sol\\\";\\nimport \\\"./IFlashAngle.sol\\\";\\n\\n/// @title ITreasury\\n/// @author Angle Core Team\\n/// @notice Interface for the `Treasury` contract\\n/// @dev This interface only contains functions of the `Treasury` which are called by other contracts\\n/// of this module\\ninterface ITreasury {\\n /// @notice Stablecoin handled by this `treasury` contract\\n function stablecoin() external view returns (IAgToken);\\n\\n /// @notice Checks whether a given address has the governor role\\n /// @param admin Address to check\\n /// @return Whether the address has the governor role\\n /// @dev Access control is only kept in the `CoreBorrow` contract\\n function isGovernor(address admin) external view returns (bool);\\n\\n /// @notice Checks whether a given address has the guardian or the governor role\\n /// @param admin Address to check\\n /// @return Whether the address has the guardian or the governor role\\n /// @dev Access control is only kept in the `CoreBorrow` contract which means that this function\\n /// queries the `CoreBorrow` contract\\n function isGovernorOrGuardian(address admin) external view returns (bool);\\n\\n /// @notice Checks whether a given address has well been initialized in this contract\\n /// as a `VaultManager``\\n /// @param _vaultManager Address to check\\n /// @return Whether the address has been initialized or not\\n function isVaultManager(address _vaultManager) external view returns (bool);\\n\\n /// @notice Sets a new flash loan module for this stablecoin\\n /// @param _flashLoanModule Reference to the new flash loan module\\n /// @dev This function removes the minting right to the old flash loan module and grants\\n /// it to the new module\\n function setFlashLoanModule(address _flashLoanModule) external;\\n}\\n\",\"keccak256\":\"0xced9b7256fcbedc75682037e11ce51fe9116e5604794b8545e00dea0607629cc\",\"license\":\"GPL-3.0\"}},\"version\":1}", - "bytecode": "0x60806040523480156200001157600080fd5b50600054610100900460ff166200002f5760005460ff161562000039565b62000039620000de565b620000a15760405162461bcd60e51b815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201526d191e481a5b9a5d1a585b1a5e995960921b606482015260840160405180910390fd5b600054610100900460ff16158015620000c4576000805461ffff19166101011790555b8015620000d7576000805461ff00191690555b5062000102565b6000620000f630620000fc60201b620027c81760201c565b15905090565b3b151590565b61479b80620001126000396000f3fe608060405234801561001057600080fd5b50600436106102ff5760003560e01c806361d027b31161019c5780639f48118f116100ee578063ced67f0c11610097578063dd62ed3e11610071578063dd62ed3e14610724578063e3e286551461076a578063f0f442601461077d57600080fd5b8063ced67f0c1461066b578063d44ad63f146106fe578063d505accf1461071157600080fd5b8063aa271e1a116100c8578063aa271e1a14610620578063ba330bd714610643578063cd4839ca1461065657600080fd5b80639f48118f146105ef578063a457c2d7146105fa578063a9059cbb1461060d57600080fd5b80637ecebe001161015057806395d89b411161012a57806395d89b41146105c1578063983b2d56146105c95780639e4e0dae146105dc57600080fd5b80637ecebe00146105705780638933fb791461058357806390218cff146105ae57600080fd5b80637334d020116101815780637334d020146105425780637d4c9c2d146105555780637d74e25f1461056857600080fd5b806361d027b3146104c757806370a082311461050c57600080fd5b80633092afd511610255578063395093511161020957806340c10f19116101e357806340c10f19146104815780634dc32fcc146104945780635bfbec96146104a757600080fd5b8063395093511461043b5780633a55f89d1461044e5780633f4218e01461046157600080fd5b8063350ebe041161023a578063350ebe041461040d5780633644e5151461042057806336db43b51461042857600080fd5b80633092afd5146103eb578063313ce567146103fe57600080fd5b8063151dd755116102b757806323b872dd1161029157806323b872dd146103b25780632b471d8e146103c55780632e403e14146103d857600080fd5b8063151dd7551461038057806318160ddd146103a15780632342fb0e146103a957600080fd5b80630919a951116102e85780630919a95114610337578063095ea7b31461034a5780631171bda91461036d57600080fd5b806306fdde0314610304578063077f224a14610322575b600080fd5b61030c610790565b604051610319919061404a565b60405180910390f35b610335610330366004614197565b610822565b005b61033561034536600461420f565b610832565b61035d61035836600461422c565b610995565b6040519015158152602001610319565b61033561037b366004614258565b6109ab565b61039361038e366004614299565b610b00565b604051908152602001610319565b603554610393565b61039360d25481565b61035d6103c0366004614258565b610e51565b6103356103d33660046142d0565b610f3c565b6103356103e636600461420f565b610f93565b6103356103f936600461420f565b611345565b60405160128152602001610319565b61033561041b366004614300565b61142e565b610393611482565b61033561043636600461422c565b611491565b61035d61044936600461422c565b611621565b61033561045c366004614337565b61166a565b61039361046f36600461420f565b60d16020526000908152604090205481565b61033561048f36600461422c565b61176d565b6103936104a236600461420f565b6117c0565b6103936104b5366004614337565b60d36020526000908152604090205481565b60cd546104e79073ffffffffffffffffffffffffffffffffffffffff1681565b60405173ffffffffffffffffffffffffffffffffffffffff9091168152602001610319565b61039361051a36600461420f565b73ffffffffffffffffffffffffffffffffffffffff1660009081526033602052604090205490565b61033561055036600461422c565b611808565b61033561056336600461437b565b61199b565b610393611d03565b61039361057e36600461420f565b611d28565b61039361059136600461422c565b60d060209081526000928352604080842090915290825290205481565b6103356105bc366004614337565b611d55565b61030c611d62565b6103356105d736600461420f565b611d71565b6103356105ea3660046143d8565b611e39565b610393633b9aca0081565b61035d61060836600461422c565b612045565b61035d61061b36600461422c565b61211d565b61035d61062e36600461420f565b60cc6020526000908152604090205460ff1681565b6104e7610651366004614337565b61212a565b61065e612161565b604051610319919061440d565b6106c561067936600461420f565b60ce6020526000908152604090208054600182015460029092015490919067ffffffffffffffff81169060ff680100000000000000008204811691690100000000000000000090041685565b60408051958652602086019490945267ffffffffffffffff9092169284019290925290151560608301521515608082015260a001610319565b61039361070c366004614299565b6121cf565b61033561071f366004614467565b612393565b6103936107323660046144de565b73ffffffffffffffffffffffffffffffffffffffff918216600090815260346020908152604080832093909416825291909152205490565b61033561077836600461420f565b612534565b61033561078b36600461420f565b612708565b60606036805461079f9061450c565b80601f01602080910402602001604051908101604052809291908181526020018280546107cb9061450c565b80156108185780601f106107ed57610100808354040283529160200191610818565b820191906000526020600020905b8154815290600101906020018083116107fb57829003601f168201915b5050505050905090565b61082d8383836127ce565b505050565b60cd546040517f521d4de900000000000000000000000000000000000000000000000000000000815233600482015273ffffffffffffffffffffffffffffffffffffffff9091169063521d4de990602401602060405180830381865afa1580156108a0573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906108c4919061455a565b6108fa576040517f99e120bc00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff8116600090815260d1602052604081205461092b9060016145a6565b73ffffffffffffffffffffffffffffffffffffffff8316600081815260d160205260409081902083905551919250907f979ef83e7e7a87cb48064e296dd7e997870d50f43acf8d7ad221313526c8ca0f906109899084815260200190565b60405180910390a25050565b60006109a2338484612a3f565b50600192915050565b60cd546040517fe43581b800000000000000000000000000000000000000000000000000000000815233600482015273ffffffffffffffffffffffffffffffffffffffff9091169063e43581b890602401602060405180830381865afa158015610a19573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610a3d919061455a565b610a73576040517fee3675d400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b610a9473ffffffffffffffffffffffffffffffffffffffff84168383612bea565b8173ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff167ffff3b3844276f57024e0b42afec1a37f75db36511e43819a4f2a63ab7862b64883604051610af391815260200190565b60405180910390a3505050565b73ffffffffffffffffffffffffffffffffffffffff8316600090815260ce60209081526040808320815160a081018352815481526001820154938101939093526002015467ffffffffffffffff81169183019190915260ff680100000000000000008204811615801560608501526901000000000000000000909204161515608083015280610b90575080608001515b15610bc7576040517fc1ab6dc100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015260009073ffffffffffffffffffffffffffffffffffffffff8716906370a0823190602401602060405180830381865afa158015610c34573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610c5891906145bd565b8251909150610c6786836145d6565b1115610c8f578151811015610c8a578151610c839082906145a6565b9450610c8f565b600094505b6000610c9d610e10426145ee565b73ffffffffffffffffffffffffffffffffffffffff8816600090815260d06020908152604080832084845290915281205491925090610cdd9088906145d6565b90508360200151811115610d715773ffffffffffffffffffffffffffffffffffffffff8816600090815260d060209081526040808320858452825290912054908501511115610d6c5773ffffffffffffffffffffffffffffffffffffffff8816600090815260d06020908152604080832085845282529091205490850151610d6591906145a6565b9650610d71565b600096505b73ffffffffffffffffffffffffffffffffffffffff8816600090815260d060209081526040808320858452909152902054610dad9088906145d6565b73ffffffffffffffffffffffffffffffffffffffff8916600081815260d060209081526040808320878452909152902091909155610ded9033308a612cbe565b33600090815260d160205260409020548790610e3957633b9aca00856040015167ffffffffffffffff1682610e229190614629565b610e2c91906145ee565b610e3690826145a6565b90505b610e438782612d1c565b9450505050505b9392505050565b6000610e5e848484612e3c565b73ffffffffffffffffffffffffffffffffffffffff8416600090815260346020908152604080832033845290915290205482811015610f24576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602860248201527f45524332303a207472616e7366657220616d6f756e742065786365656473206160448201527f6c6c6f77616e636500000000000000000000000000000000000000000000000060648201526084015b60405180910390fd5b610f318533858403612a3f565b506001949350505050565b33600090815260cc602052604090205460ff16610f85576040517ff8d2906c00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b610f8f81836130ef565b5050565b60cd546040517fe43581b800000000000000000000000000000000000000000000000000000000815233600482015273ffffffffffffffffffffffffffffffffffffffff9091169063e43581b890602401602060405180830381865afa158015611001573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611025919061455a565b61105b576040517fee3675d400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015273ffffffffffffffffffffffffffffffffffffffff8216906370a0823190602401602060405180830381865afa1580156110c5573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906110e991906145bd565b15611120576040517f2ef630ec00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff8116600090815260ce602052604081208181556001810182905560020180547fffffffffffffffffffffffffffffffffffffffffffff0000000000000000000016905560cf54905b6111886001836145a6565b811015611296578273ffffffffffffffffffffffffffffffffffffffff1660cf82815481106111b9576111b9614666565b60009182526020909120015473ffffffffffffffffffffffffffffffffffffffff1614156112845760cf6111ee6001846145a6565b815481106111fe576111fe614666565b60009182526020909120015460cf805473ffffffffffffffffffffffffffffffffffffffff909216918390811061123757611237614666565b9060005260206000200160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550611296565b8061128e81614695565b91505061117d565b5060cf8054806112a8576112a86146ce565b60008281526020812082017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff90810180547fffffffffffffffffffffffff000000000000000000000000000000000000000016905590910190915560405173ffffffffffffffffffffffffffffffffffffffff8416917f5c95b49c4d59d97a2f044167723f29c74b30f99702e3fd406c3830160aa9ccb891a25050565b60cd5473ffffffffffffffffffffffffffffffffffffffff16331480159061138357503373ffffffffffffffffffffffffffffffffffffffff821614155b156113ba576040517fddb5de5e00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff8116600081815260cc602052604080822080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00169055517f98c15241d6c02bc5ee0b780e11b3ea737a2defd9d04877edbe9f9497065bd02f9190a250565b33600090815260cc602052604090205460ff16611477576040517ff8d2906c00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b61082d8383836132dc565b600061148c613397565b905090565b60cd546040517f521d4de900000000000000000000000000000000000000000000000000000000815233600482015273ffffffffffffffffffffffffffffffffffffffff9091169063521d4de990602401602060405180830381865afa1580156114ff573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611523919061455a565b611559576040517f99e120bc00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff8216600090815260ce602052604090206002015468010000000000000000900460ff166115c7576040517fc1ab6dc100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff8216600081815260ce602052604090819020839055517fe7b113fba37131b6396680a0c55790a697ec975e198ff8cfd89dac90a6379e61906109899084815260200190565b33600081815260346020908152604080832073ffffffffffffffffffffffffffffffffffffffff8716845290915281205490916109a29185906116659086906145d6565b612a3f565b60cd546040517f521d4de900000000000000000000000000000000000000000000000000000000815233600482015273ffffffffffffffffffffffffffffffffffffffff9091169063521d4de990602401602060405180830381865afa1580156116d8573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906116fc919061455a565b611732576040517f99e120bc00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60d28190556040518181527fc3b69829afe2345596a02c8b587d41f796ba0094481d899e1b2e07b7532a1e219060200160405180910390a150565b33600090815260cc602052604090205460ff166117b6576040517ff8d2906c00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b610f8f8282612d1c565b73ffffffffffffffffffffffffffffffffffffffff8116600090815260d060205260408120816117f2610e10426145ee565b8152602001908152602001600020549050919050565b60cd546040517f521d4de900000000000000000000000000000000000000000000000000000000815233600482015273ffffffffffffffffffffffffffffffffffffffff9091169063521d4de990602401602060405180830381865afa158015611876573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061189a919061455a565b6118d0576040517f99e120bc00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff8216600090815260ce602052604090206002015468010000000000000000900460ff1661193e576040517fc1ab6dc100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff8216600081815260ce602052604090819020600101839055517fe13ac9338b2ee623233f83c1b3ceab16490fa3e3737fac7f0970d0830a9f4871906109899084815260200190565b60cd546040517fe43581b800000000000000000000000000000000000000000000000000000000815233600482015273ffffffffffffffffffffffffffffffffffffffff9091169063e43581b890602401602060405180830381865afa158015611a09573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611a2d919061455a565b611a63576040517fee3675d400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff8516600090815260ce602052604090206002015468010000000000000000900460ff1680611aba575073ffffffffffffffffffffffffffffffffffffffff8516155b15611af1576040517fc1ab6dc100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b633b9aca008267ffffffffffffffff161115611b39576040517feca1d2c600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040805160a08101825260008082526020820181905291810182905260608101829052608081019190915284815260208082018581528315156080840190815267ffffffffffffffff808716604080870191825260016060880181815273ffffffffffffffffffffffffffffffffffffffff8e16600081815260ce9099528389208a5181559751888401559351600290970180549151965115156901000000000000000000027fffffffffffffffffffffffffffffffffffffffffffff00ffffffffffffffffff97151568010000000000000000027fffffffffffffffffffffffffffffffffffffffffffffff000000000000000000909316989096169790971717949094169290921790935560cf805492830181559093527facb8d954e2cfef495862221e91bd7523613cf8808827cb33edfe4904cc51bf290180547fffffffffffffffffffffffff0000000000000000000000000000000000000000168217905590517f53087ff85d80a7671594bd2e86b92af22e0b3c2c441c8033bba7399b7b5cbe2390611cf3908890889088908890938452602084019290925267ffffffffffffffff1660408301521515606082015260800190565b60405180910390a2505050505050565b600060d381611d14610e10426145ee565b815260200190815260200160002054905090565b73ffffffffffffffffffffffffffffffffffffffff81166000908152609960205260408120545b92915050565b611d5f33826130ef565b50565b60606037805461079f9061450c565b60cd5473ffffffffffffffffffffffffffffffffffffffff163314611dc2576040517fb90cdbb100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff8116600081815260cc602052604080822080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00166001179055517f98c15241d6c02bc5ee0b780e11b3ea737a2defd9d04877edbe9f9497065bd02f9190a250565b60cd546040517f521d4de900000000000000000000000000000000000000000000000000000000815233600482015273ffffffffffffffffffffffffffffffffffffffff9091169063521d4de990602401602060405180830381865afa158015611ea7573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611ecb919061455a565b611f01576040517f99e120bc00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff8216600090815260ce602052604090206002015468010000000000000000900460ff16611f6f576040517fc1ab6dc100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b633b9aca008167ffffffffffffffff161115611fb7576040517feca1d2c600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff8216600081815260ce602090815260409182902060020180547fffffffffffffffffffffffffffffffffffffffffffffffff00000000000000001667ffffffffffffffff861690811790915591519182527f901f9de19b475adc8da4110434b8df940dce085afd05e2281c86807f3a899d299101610989565b33600090815260346020908152604080832073ffffffffffffffffffffffffffffffffffffffff8616845290915281205482811015612106576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602560248201527f45524332303a2064656372656173656420616c6c6f77616e63652062656c6f7760448201527f207a65726f0000000000000000000000000000000000000000000000000000006064820152608401610f1b565b6121133385858403612a3f565b5060019392505050565b60006109a2338484612e3c565b60cf818154811061213a57600080fd5b60009182526020909120015473ffffffffffffffffffffffffffffffffffffffff16905081565b606060cf80548060200260200160405190810160405280929190818152602001828054801561081857602002820191906000526020600020905b815473ffffffffffffffffffffffffffffffffffffffff16815260019091019060200180831161219b575050505050905090565b73ffffffffffffffffffffffffffffffffffffffff8316600090815260ce60209081526040808320815160a081018352815481526001820154938101939093526002015467ffffffffffffffff81169183019190915260ff68010000000000000000820481161580156060850152690100000000000000000090920416151560808301528061225f575080608001515b15612296576040517fc1ab6dc100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60006122a4610e10426145ee565b600081815260d36020526040812054919250906122c29087906145d6565b905060d254811115612300576040517f6d43d1ac00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600082815260d36020526040902081905561231b33876130ef565b33600090815260d16020526040902054869061236757633b9aca00846040015167ffffffffffffffff16826123509190614629565b61235a91906145ee565b61236490826145a6565b90505b61238873ffffffffffffffffffffffffffffffffffffffff89168783612bea565b979650505050505050565b834211156123fd576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f45524332305065726d69743a206578706972656420646561646c696e650000006044820152606401610f1b565b6000609a5488888861240e8c613412565b60408051602081019690965273ffffffffffffffffffffffffffffffffffffffff94851690860152929091166060840152608083015260a082015260c0810186905260e001604051602081830303815290604052805190602001209050600061247682613447565b90506000612486828787876134b0565b90508973ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff161461251d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601e60248201527f45524332305065726d69743a20696e76616c6964207369676e617475726500006044820152606401610f1b565b6125288a8a8a612a3f565b50505050505050505050565b60cd546040517f521d4de900000000000000000000000000000000000000000000000000000000815233600482015273ffffffffffffffffffffffffffffffffffffffff9091169063521d4de990602401602060405180830381865afa1580156125a2573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906125c6919061455a565b6125fc576040517f99e120bc00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff8116600090815260ce602052604090206002015468010000000000000000900460ff1661266a576040517fc1ab6dc100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff8116600081815260ce602090815260409182902060020180547fffffffffffffffffffffffffffffffffffffffffffff00ffffffffffffffffff811669010000000000000000009182900460ff16801592830291909117909255925192835292917ff7c93079dcbf699749d66345a351afab7d24219bb1d915c9f4fc4cf03f00d3979101610989565b60cd5473ffffffffffffffffffffffffffffffffffffffff163314612759576040517fb90cdbb100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60cd80547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83169081179091556040517f7dae230f18360d76a040c81f050aa14eb9d6dc7901b20fc5d855e2a20fe814d190600090a250565b3b151590565b600054610100900460ff166127e95760005460ff16156127ed565b303b155b612879576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201527f647920696e697469616c697a65640000000000000000000000000000000000006064820152608401610f1b565b600054610100900460ff161580156128b857600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0000166101011790555b6128c1846134d8565b6128cb84846135bf565b3073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1663e9cbd8226040518163ffffffff1660e01b8152600401602060405180830381865afa15801561292d573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061295191906146fd565b73ffffffffffffffffffffffffffffffffffffffff161461299e576040517f14bcf5c800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60cd80547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff84169081179091556040517f7dae230f18360d76a040c81f050aa14eb9d6dc7901b20fc5d855e2a20fe814d190600090a28015612a3957600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff1690555b50505050565b73ffffffffffffffffffffffffffffffffffffffff8316612ae1576040517f08c379a0000000000000000000000000000000000000000000000000000000008152602060048201526024808201527f45524332303a20617070726f76652066726f6d20746865207a65726f2061646460448201527f72657373000000000000000000000000000000000000000000000000000000006064820152608401610f1b565b73ffffffffffffffffffffffffffffffffffffffff8216612b84576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602260248201527f45524332303a20617070726f766520746f20746865207a65726f20616464726560448201527f73730000000000000000000000000000000000000000000000000000000000006064820152608401610f1b565b73ffffffffffffffffffffffffffffffffffffffff83811660008181526034602090815260408083209487168084529482529182902085905590518481527f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b9259101610af3565b60405173ffffffffffffffffffffffffffffffffffffffff831660248201526044810182905261082d9084907fa9059cbb00000000000000000000000000000000000000000000000000000000906064015b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff0000000000000000000000000000000000000000000000000000000090931692909217909152613668565b60405173ffffffffffffffffffffffffffffffffffffffff80851660248301528316604482015260648101829052612a399085907f23b872dd0000000000000000000000000000000000000000000000000000000090608401612c3c565b73ffffffffffffffffffffffffffffffffffffffff8216612d99576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601f60248201527f45524332303a206d696e7420746f20746865207a65726f2061646472657373006044820152606401610f1b565b8060356000828254612dab91906145d6565b909155505073ffffffffffffffffffffffffffffffffffffffff821660009081526033602052604081208054839290612de59084906145d6565b909155505060405181815273ffffffffffffffffffffffffffffffffffffffff8316906000907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef9060200160405180910390a35050565b73ffffffffffffffffffffffffffffffffffffffff8316612edf576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602560248201527f45524332303a207472616e736665722066726f6d20746865207a65726f20616460448201527f64726573730000000000000000000000000000000000000000000000000000006064820152608401610f1b565b73ffffffffffffffffffffffffffffffffffffffff8216612f82576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602360248201527f45524332303a207472616e7366657220746f20746865207a65726f206164647260448201527f65737300000000000000000000000000000000000000000000000000000000006064820152608401610f1b565b73ffffffffffffffffffffffffffffffffffffffff831660009081526033602052604090205481811015613038576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f45524332303a207472616e7366657220616d6f756e742065786365656473206260448201527f616c616e636500000000000000000000000000000000000000000000000000006064820152608401610f1b565b73ffffffffffffffffffffffffffffffffffffffff80851660009081526033602052604080822085850390559185168152908120805484929061307c9084906145d6565b925050819055508273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef846040516130e291815260200190565b60405180910390a3612a39565b73ffffffffffffffffffffffffffffffffffffffff8216613192576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602160248201527f45524332303a206275726e2066726f6d20746865207a65726f2061646472657360448201527f73000000000000000000000000000000000000000000000000000000000000006064820152608401610f1b565b73ffffffffffffffffffffffffffffffffffffffff821660009081526033602052604090205481811015613248576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602260248201527f45524332303a206275726e20616d6f756e7420657863656564732062616c616e60448201527f63650000000000000000000000000000000000000000000000000000000000006064820152608401610f1b565b73ffffffffffffffffffffffffffffffffffffffff831660009081526033602052604081208383039055603580548492906132849084906145a6565b909155505060405182815260009073ffffffffffffffffffffffffffffffffffffffff8516907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef9060200160405180910390a3505050565b8073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff161461338d5773ffffffffffffffffffffffffffffffffffffffff8281166000908152603460209081526040808320938516835292905220548381101561337c576040517f715ec26c00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b61338b838361166587856145a6565b505b61082d82846130ef565b600061148c7f8b73c3c69bb8fe3d512ecc4cf759cc79239f7b179b0ffacaa9a75d522b39400f6133c660655490565b6066546040805160208101859052908101839052606081018290524660808201523060a082015260009060c0016040516020818303038152906040528051906020012090509392505050565b73ffffffffffffffffffffffffffffffffffffffff811660009081526099602052604090208054600181018255905b50919050565b6000611d4f613454613397565b836040517f19010000000000000000000000000000000000000000000000000000000000006020820152602281018390526042810182905260009060620160405160208183030381529060405280519060200120905092915050565b60008060006134c187878787613774565b915091506134ce8161388c565b5095945050505050565b600054610100900460ff1661356f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201527f6e697469616c697a696e670000000000000000000000000000000000000000006064820152608401610f1b565b613577613ae5565b6135b6816040518060400160405280600181526020017f3100000000000000000000000000000000000000000000000000000000000000815250613b7e565b611d5f81613c2f565b600054610100900460ff16613656576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201527f6e697469616c697a696e670000000000000000000000000000000000000000006064820152608401610f1b565b61365e613ae5565b610f8f8282613ced565b60006136ca826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c65648152508573ffffffffffffffffffffffffffffffffffffffff16613dab9092919063ffffffff16565b80519091501561082d57808060200190518101906136e8919061455a565b61082d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e60448201527f6f742073756363656564000000000000000000000000000000000000000000006064820152608401610f1b565b6000807f7fffffffffffffffffffffffffffffff5d576e7357a4501ddfe92f46681b20a08311156137ab5750600090506003613883565b8460ff16601b141580156137c357508460ff16601c14155b156137d45750600090506004613883565b6040805160008082526020820180845289905260ff881692820192909252606081018690526080810185905260019060a0016020604051602081039080840390855afa158015613828573d6000803e3d6000fd5b50506040517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0015191505073ffffffffffffffffffffffffffffffffffffffff811661387c57600060019250925050613883565b9150600090505b94509492505050565b60008160048111156138a0576138a061471a565b14156138a95750565b60018160048111156138bd576138bd61471a565b1415613925576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601860248201527f45434453413a20696e76616c6964207369676e617475726500000000000000006044820152606401610f1b565b60028160048111156139395761393961471a565b14156139a1576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601f60248201527f45434453413a20696e76616c6964207369676e6174757265206c656e677468006044820152606401610f1b565b60038160048111156139b5576139b561471a565b1415613a43576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602260248201527f45434453413a20696e76616c6964207369676e6174757265202773272076616c60448201527f75650000000000000000000000000000000000000000000000000000000000006064820152608401610f1b565b6004816004811115613a5757613a5761471a565b1415611d5f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602260248201527f45434453413a20696e76616c6964207369676e6174757265202776272076616c60448201527f75650000000000000000000000000000000000000000000000000000000000006064820152608401610f1b565b600054610100900460ff16613b7c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201527f6e697469616c697a696e670000000000000000000000000000000000000000006064820152608401610f1b565b565b600054610100900460ff16613c15576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201527f6e697469616c697a696e670000000000000000000000000000000000000000006064820152608401610f1b565b815160209283012081519190920120606591909155606655565b600054610100900460ff16613cc6576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201527f6e697469616c697a696e670000000000000000000000000000000000000000006064820152608401610f1b565b507f6e71edae12b1b97f4d1f60370fef10105fa2faae0126114a169c64845d6126c9609a55565b600054610100900460ff16613d84576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201527f6e697469616c697a696e670000000000000000000000000000000000000000006064820152608401610f1b565b8151613d97906036906020850190613f85565b50805161082d906037906020840190613f85565b6060613dba8484600085613dc2565b949350505050565b606082471015613e54576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f60448201527f722063616c6c00000000000000000000000000000000000000000000000000006064820152608401610f1b565b843b613ebc576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006044820152606401610f1b565b6000808673ffffffffffffffffffffffffffffffffffffffff168587604051613ee59190614749565b60006040518083038185875af1925050503d8060008114613f22576040519150601f19603f3d011682016040523d82523d6000602084013e613f27565b606091505b509150915061238882828660608315613f41575081610e4a565b825115613f515782518084602001fd5b816040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610f1b919061404a565b828054613f919061450c565b90600052602060002090601f016020900481019282613fb35760008555613ff9565b82601f10613fcc57805160ff1916838001178555613ff9565b82800160010185558215613ff9579182015b82811115613ff9578251825591602001919060010190613fde565b50614005929150614009565b5090565b5b80821115614005576000815560010161400a565b60005b83811015614039578181015183820152602001614021565b83811115612a395750506000910152565b602081526000825180602084015261406981604085016020870161401e565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169190910160400192915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b600082601f8301126140db57600080fd5b813567ffffffffffffffff808211156140f6576140f661409b565b604051601f83017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0908116603f0116810190828211818310171561413c5761413c61409b565b8160405283815286602085880101111561415557600080fd5b836020870160208301376000602085830101528094505050505092915050565b73ffffffffffffffffffffffffffffffffffffffff81168114611d5f57600080fd5b6000806000606084860312156141ac57600080fd5b833567ffffffffffffffff808211156141c457600080fd5b6141d0878388016140ca565b945060208601359150808211156141e657600080fd5b506141f3868287016140ca565b925050604084013561420481614175565b809150509250925092565b60006020828403121561422157600080fd5b8135610e4a81614175565b6000806040838503121561423f57600080fd5b823561424a81614175565b946020939093013593505050565b60008060006060848603121561426d57600080fd5b833561427881614175565b9250602084013561428881614175565b929592945050506040919091013590565b6000806000606084860312156142ae57600080fd5b83356142b981614175565b925060208401359150604084013561420481614175565b600080604083850312156142e357600080fd5b8235915060208301356142f581614175565b809150509250929050565b60008060006060848603121561431557600080fd5b83359250602084013561432781614175565b9150604084013561420481614175565b60006020828403121561434957600080fd5b5035919050565b803567ffffffffffffffff8116811461436857600080fd5b919050565b8015158114611d5f57600080fd5b600080600080600060a0868803121561439357600080fd5b853561439e81614175565b945060208601359350604086013592506143ba60608701614350565b915060808601356143ca8161436d565b809150509295509295909350565b600080604083850312156143eb57600080fd5b82356143f681614175565b915061440460208401614350565b90509250929050565b6020808252825182820181905260009190848201906040850190845b8181101561445b57835173ffffffffffffffffffffffffffffffffffffffff1683529284019291840191600101614429565b50909695505050505050565b600080600080600080600060e0888a03121561448257600080fd5b873561448d81614175565b9650602088013561449d81614175565b95506040880135945060608801359350608088013560ff811681146144c157600080fd5b9699959850939692959460a0840135945060c09093013592915050565b600080604083850312156144f157600080fd5b82356144fc81614175565b915060208301356142f581614175565b600181811c9082168061452057607f821691505b60208210811415613441577f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b60006020828403121561456c57600080fd5b8151610e4a8161436d565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b6000828210156145b8576145b8614577565b500390565b6000602082840312156145cf57600080fd5b5051919050565b600082198211156145e9576145e9614577565b500190565b600082614624577f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b500490565b6000817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff048311821515161561466157614661614577565b500290565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8214156146c7576146c7614577565b5060010190565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603160045260246000fd5b60006020828403121561470f57600080fd5b8151610e4a81614175565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b6000825161475b81846020870161401e565b919091019291505056fea2646970667358221220103b8d652dd7975983cef70f41cb81056a0bf607243b7332223b4013506c7eb664736f6c634300080c0033", - "deployedBytecode": "0x608060405234801561001057600080fd5b50600436106102ff5760003560e01c806361d027b31161019c5780639f48118f116100ee578063ced67f0c11610097578063dd62ed3e11610071578063dd62ed3e14610724578063e3e286551461076a578063f0f442601461077d57600080fd5b8063ced67f0c1461066b578063d44ad63f146106fe578063d505accf1461071157600080fd5b8063aa271e1a116100c8578063aa271e1a14610620578063ba330bd714610643578063cd4839ca1461065657600080fd5b80639f48118f146105ef578063a457c2d7146105fa578063a9059cbb1461060d57600080fd5b80637ecebe001161015057806395d89b411161012a57806395d89b41146105c1578063983b2d56146105c95780639e4e0dae146105dc57600080fd5b80637ecebe00146105705780638933fb791461058357806390218cff146105ae57600080fd5b80637334d020116101815780637334d020146105425780637d4c9c2d146105555780637d74e25f1461056857600080fd5b806361d027b3146104c757806370a082311461050c57600080fd5b80633092afd511610255578063395093511161020957806340c10f19116101e357806340c10f19146104815780634dc32fcc146104945780635bfbec96146104a757600080fd5b8063395093511461043b5780633a55f89d1461044e5780633f4218e01461046157600080fd5b8063350ebe041161023a578063350ebe041461040d5780633644e5151461042057806336db43b51461042857600080fd5b80633092afd5146103eb578063313ce567146103fe57600080fd5b8063151dd755116102b757806323b872dd1161029157806323b872dd146103b25780632b471d8e146103c55780632e403e14146103d857600080fd5b8063151dd7551461038057806318160ddd146103a15780632342fb0e146103a957600080fd5b80630919a951116102e85780630919a95114610337578063095ea7b31461034a5780631171bda91461036d57600080fd5b806306fdde0314610304578063077f224a14610322575b600080fd5b61030c610790565b604051610319919061404a565b60405180910390f35b610335610330366004614197565b610822565b005b61033561034536600461420f565b610832565b61035d61035836600461422c565b610995565b6040519015158152602001610319565b61033561037b366004614258565b6109ab565b61039361038e366004614299565b610b00565b604051908152602001610319565b603554610393565b61039360d25481565b61035d6103c0366004614258565b610e51565b6103356103d33660046142d0565b610f3c565b6103356103e636600461420f565b610f93565b6103356103f936600461420f565b611345565b60405160128152602001610319565b61033561041b366004614300565b61142e565b610393611482565b61033561043636600461422c565b611491565b61035d61044936600461422c565b611621565b61033561045c366004614337565b61166a565b61039361046f36600461420f565b60d16020526000908152604090205481565b61033561048f36600461422c565b61176d565b6103936104a236600461420f565b6117c0565b6103936104b5366004614337565b60d36020526000908152604090205481565b60cd546104e79073ffffffffffffffffffffffffffffffffffffffff1681565b60405173ffffffffffffffffffffffffffffffffffffffff9091168152602001610319565b61039361051a36600461420f565b73ffffffffffffffffffffffffffffffffffffffff1660009081526033602052604090205490565b61033561055036600461422c565b611808565b61033561056336600461437b565b61199b565b610393611d03565b61039361057e36600461420f565b611d28565b61039361059136600461422c565b60d060209081526000928352604080842090915290825290205481565b6103356105bc366004614337565b611d55565b61030c611d62565b6103356105d736600461420f565b611d71565b6103356105ea3660046143d8565b611e39565b610393633b9aca0081565b61035d61060836600461422c565b612045565b61035d61061b36600461422c565b61211d565b61035d61062e36600461420f565b60cc6020526000908152604090205460ff1681565b6104e7610651366004614337565b61212a565b61065e612161565b604051610319919061440d565b6106c561067936600461420f565b60ce6020526000908152604090208054600182015460029092015490919067ffffffffffffffff81169060ff680100000000000000008204811691690100000000000000000090041685565b60408051958652602086019490945267ffffffffffffffff9092169284019290925290151560608301521515608082015260a001610319565b61039361070c366004614299565b6121cf565b61033561071f366004614467565b612393565b6103936107323660046144de565b73ffffffffffffffffffffffffffffffffffffffff918216600090815260346020908152604080832093909416825291909152205490565b61033561077836600461420f565b612534565b61033561078b36600461420f565b612708565b60606036805461079f9061450c565b80601f01602080910402602001604051908101604052809291908181526020018280546107cb9061450c565b80156108185780601f106107ed57610100808354040283529160200191610818565b820191906000526020600020905b8154815290600101906020018083116107fb57829003601f168201915b5050505050905090565b61082d8383836127ce565b505050565b60cd546040517f521d4de900000000000000000000000000000000000000000000000000000000815233600482015273ffffffffffffffffffffffffffffffffffffffff9091169063521d4de990602401602060405180830381865afa1580156108a0573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906108c4919061455a565b6108fa576040517f99e120bc00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff8116600090815260d1602052604081205461092b9060016145a6565b73ffffffffffffffffffffffffffffffffffffffff8316600081815260d160205260409081902083905551919250907f979ef83e7e7a87cb48064e296dd7e997870d50f43acf8d7ad221313526c8ca0f906109899084815260200190565b60405180910390a25050565b60006109a2338484612a3f565b50600192915050565b60cd546040517fe43581b800000000000000000000000000000000000000000000000000000000815233600482015273ffffffffffffffffffffffffffffffffffffffff9091169063e43581b890602401602060405180830381865afa158015610a19573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610a3d919061455a565b610a73576040517fee3675d400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b610a9473ffffffffffffffffffffffffffffffffffffffff84168383612bea565b8173ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff167ffff3b3844276f57024e0b42afec1a37f75db36511e43819a4f2a63ab7862b64883604051610af391815260200190565b60405180910390a3505050565b73ffffffffffffffffffffffffffffffffffffffff8316600090815260ce60209081526040808320815160a081018352815481526001820154938101939093526002015467ffffffffffffffff81169183019190915260ff680100000000000000008204811615801560608501526901000000000000000000909204161515608083015280610b90575080608001515b15610bc7576040517fc1ab6dc100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015260009073ffffffffffffffffffffffffffffffffffffffff8716906370a0823190602401602060405180830381865afa158015610c34573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610c5891906145bd565b8251909150610c6786836145d6565b1115610c8f578151811015610c8a578151610c839082906145a6565b9450610c8f565b600094505b6000610c9d610e10426145ee565b73ffffffffffffffffffffffffffffffffffffffff8816600090815260d06020908152604080832084845290915281205491925090610cdd9088906145d6565b90508360200151811115610d715773ffffffffffffffffffffffffffffffffffffffff8816600090815260d060209081526040808320858452825290912054908501511115610d6c5773ffffffffffffffffffffffffffffffffffffffff8816600090815260d06020908152604080832085845282529091205490850151610d6591906145a6565b9650610d71565b600096505b73ffffffffffffffffffffffffffffffffffffffff8816600090815260d060209081526040808320858452909152902054610dad9088906145d6565b73ffffffffffffffffffffffffffffffffffffffff8916600081815260d060209081526040808320878452909152902091909155610ded9033308a612cbe565b33600090815260d160205260409020548790610e3957633b9aca00856040015167ffffffffffffffff1682610e229190614629565b610e2c91906145ee565b610e3690826145a6565b90505b610e438782612d1c565b9450505050505b9392505050565b6000610e5e848484612e3c565b73ffffffffffffffffffffffffffffffffffffffff8416600090815260346020908152604080832033845290915290205482811015610f24576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602860248201527f45524332303a207472616e7366657220616d6f756e742065786365656473206160448201527f6c6c6f77616e636500000000000000000000000000000000000000000000000060648201526084015b60405180910390fd5b610f318533858403612a3f565b506001949350505050565b33600090815260cc602052604090205460ff16610f85576040517ff8d2906c00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b610f8f81836130ef565b5050565b60cd546040517fe43581b800000000000000000000000000000000000000000000000000000000815233600482015273ffffffffffffffffffffffffffffffffffffffff9091169063e43581b890602401602060405180830381865afa158015611001573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611025919061455a565b61105b576040517fee3675d400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015273ffffffffffffffffffffffffffffffffffffffff8216906370a0823190602401602060405180830381865afa1580156110c5573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906110e991906145bd565b15611120576040517f2ef630ec00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff8116600090815260ce602052604081208181556001810182905560020180547fffffffffffffffffffffffffffffffffffffffffffff0000000000000000000016905560cf54905b6111886001836145a6565b811015611296578273ffffffffffffffffffffffffffffffffffffffff1660cf82815481106111b9576111b9614666565b60009182526020909120015473ffffffffffffffffffffffffffffffffffffffff1614156112845760cf6111ee6001846145a6565b815481106111fe576111fe614666565b60009182526020909120015460cf805473ffffffffffffffffffffffffffffffffffffffff909216918390811061123757611237614666565b9060005260206000200160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550611296565b8061128e81614695565b91505061117d565b5060cf8054806112a8576112a86146ce565b60008281526020812082017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff90810180547fffffffffffffffffffffffff000000000000000000000000000000000000000016905590910190915560405173ffffffffffffffffffffffffffffffffffffffff8416917f5c95b49c4d59d97a2f044167723f29c74b30f99702e3fd406c3830160aa9ccb891a25050565b60cd5473ffffffffffffffffffffffffffffffffffffffff16331480159061138357503373ffffffffffffffffffffffffffffffffffffffff821614155b156113ba576040517fddb5de5e00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff8116600081815260cc602052604080822080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00169055517f98c15241d6c02bc5ee0b780e11b3ea737a2defd9d04877edbe9f9497065bd02f9190a250565b33600090815260cc602052604090205460ff16611477576040517ff8d2906c00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b61082d8383836132dc565b600061148c613397565b905090565b60cd546040517f521d4de900000000000000000000000000000000000000000000000000000000815233600482015273ffffffffffffffffffffffffffffffffffffffff9091169063521d4de990602401602060405180830381865afa1580156114ff573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611523919061455a565b611559576040517f99e120bc00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff8216600090815260ce602052604090206002015468010000000000000000900460ff166115c7576040517fc1ab6dc100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff8216600081815260ce602052604090819020839055517fe7b113fba37131b6396680a0c55790a697ec975e198ff8cfd89dac90a6379e61906109899084815260200190565b33600081815260346020908152604080832073ffffffffffffffffffffffffffffffffffffffff8716845290915281205490916109a29185906116659086906145d6565b612a3f565b60cd546040517f521d4de900000000000000000000000000000000000000000000000000000000815233600482015273ffffffffffffffffffffffffffffffffffffffff9091169063521d4de990602401602060405180830381865afa1580156116d8573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906116fc919061455a565b611732576040517f99e120bc00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60d28190556040518181527fc3b69829afe2345596a02c8b587d41f796ba0094481d899e1b2e07b7532a1e219060200160405180910390a150565b33600090815260cc602052604090205460ff166117b6576040517ff8d2906c00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b610f8f8282612d1c565b73ffffffffffffffffffffffffffffffffffffffff8116600090815260d060205260408120816117f2610e10426145ee565b8152602001908152602001600020549050919050565b60cd546040517f521d4de900000000000000000000000000000000000000000000000000000000815233600482015273ffffffffffffffffffffffffffffffffffffffff9091169063521d4de990602401602060405180830381865afa158015611876573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061189a919061455a565b6118d0576040517f99e120bc00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff8216600090815260ce602052604090206002015468010000000000000000900460ff1661193e576040517fc1ab6dc100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff8216600081815260ce602052604090819020600101839055517fe13ac9338b2ee623233f83c1b3ceab16490fa3e3737fac7f0970d0830a9f4871906109899084815260200190565b60cd546040517fe43581b800000000000000000000000000000000000000000000000000000000815233600482015273ffffffffffffffffffffffffffffffffffffffff9091169063e43581b890602401602060405180830381865afa158015611a09573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611a2d919061455a565b611a63576040517fee3675d400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff8516600090815260ce602052604090206002015468010000000000000000900460ff1680611aba575073ffffffffffffffffffffffffffffffffffffffff8516155b15611af1576040517fc1ab6dc100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b633b9aca008267ffffffffffffffff161115611b39576040517feca1d2c600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040805160a08101825260008082526020820181905291810182905260608101829052608081019190915284815260208082018581528315156080840190815267ffffffffffffffff808716604080870191825260016060880181815273ffffffffffffffffffffffffffffffffffffffff8e16600081815260ce9099528389208a5181559751888401559351600290970180549151965115156901000000000000000000027fffffffffffffffffffffffffffffffffffffffffffff00ffffffffffffffffff97151568010000000000000000027fffffffffffffffffffffffffffffffffffffffffffffff000000000000000000909316989096169790971717949094169290921790935560cf805492830181559093527facb8d954e2cfef495862221e91bd7523613cf8808827cb33edfe4904cc51bf290180547fffffffffffffffffffffffff0000000000000000000000000000000000000000168217905590517f53087ff85d80a7671594bd2e86b92af22e0b3c2c441c8033bba7399b7b5cbe2390611cf3908890889088908890938452602084019290925267ffffffffffffffff1660408301521515606082015260800190565b60405180910390a2505050505050565b600060d381611d14610e10426145ee565b815260200190815260200160002054905090565b73ffffffffffffffffffffffffffffffffffffffff81166000908152609960205260408120545b92915050565b611d5f33826130ef565b50565b60606037805461079f9061450c565b60cd5473ffffffffffffffffffffffffffffffffffffffff163314611dc2576040517fb90cdbb100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff8116600081815260cc602052604080822080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00166001179055517f98c15241d6c02bc5ee0b780e11b3ea737a2defd9d04877edbe9f9497065bd02f9190a250565b60cd546040517f521d4de900000000000000000000000000000000000000000000000000000000815233600482015273ffffffffffffffffffffffffffffffffffffffff9091169063521d4de990602401602060405180830381865afa158015611ea7573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611ecb919061455a565b611f01576040517f99e120bc00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff8216600090815260ce602052604090206002015468010000000000000000900460ff16611f6f576040517fc1ab6dc100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b633b9aca008167ffffffffffffffff161115611fb7576040517feca1d2c600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff8216600081815260ce602090815260409182902060020180547fffffffffffffffffffffffffffffffffffffffffffffffff00000000000000001667ffffffffffffffff861690811790915591519182527f901f9de19b475adc8da4110434b8df940dce085afd05e2281c86807f3a899d299101610989565b33600090815260346020908152604080832073ffffffffffffffffffffffffffffffffffffffff8616845290915281205482811015612106576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602560248201527f45524332303a2064656372656173656420616c6c6f77616e63652062656c6f7760448201527f207a65726f0000000000000000000000000000000000000000000000000000006064820152608401610f1b565b6121133385858403612a3f565b5060019392505050565b60006109a2338484612e3c565b60cf818154811061213a57600080fd5b60009182526020909120015473ffffffffffffffffffffffffffffffffffffffff16905081565b606060cf80548060200260200160405190810160405280929190818152602001828054801561081857602002820191906000526020600020905b815473ffffffffffffffffffffffffffffffffffffffff16815260019091019060200180831161219b575050505050905090565b73ffffffffffffffffffffffffffffffffffffffff8316600090815260ce60209081526040808320815160a081018352815481526001820154938101939093526002015467ffffffffffffffff81169183019190915260ff68010000000000000000820481161580156060850152690100000000000000000090920416151560808301528061225f575080608001515b15612296576040517fc1ab6dc100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60006122a4610e10426145ee565b600081815260d36020526040812054919250906122c29087906145d6565b905060d254811115612300576040517f6d43d1ac00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600082815260d36020526040902081905561231b33876130ef565b33600090815260d16020526040902054869061236757633b9aca00846040015167ffffffffffffffff16826123509190614629565b61235a91906145ee565b61236490826145a6565b90505b61238873ffffffffffffffffffffffffffffffffffffffff89168783612bea565b979650505050505050565b834211156123fd576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f45524332305065726d69743a206578706972656420646561646c696e650000006044820152606401610f1b565b6000609a5488888861240e8c613412565b60408051602081019690965273ffffffffffffffffffffffffffffffffffffffff94851690860152929091166060840152608083015260a082015260c0810186905260e001604051602081830303815290604052805190602001209050600061247682613447565b90506000612486828787876134b0565b90508973ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff161461251d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601e60248201527f45524332305065726d69743a20696e76616c6964207369676e617475726500006044820152606401610f1b565b6125288a8a8a612a3f565b50505050505050505050565b60cd546040517f521d4de900000000000000000000000000000000000000000000000000000000815233600482015273ffffffffffffffffffffffffffffffffffffffff9091169063521d4de990602401602060405180830381865afa1580156125a2573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906125c6919061455a565b6125fc576040517f99e120bc00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff8116600090815260ce602052604090206002015468010000000000000000900460ff1661266a576040517fc1ab6dc100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff8116600081815260ce602090815260409182902060020180547fffffffffffffffffffffffffffffffffffffffffffff00ffffffffffffffffff811669010000000000000000009182900460ff16801592830291909117909255925192835292917ff7c93079dcbf699749d66345a351afab7d24219bb1d915c9f4fc4cf03f00d3979101610989565b60cd5473ffffffffffffffffffffffffffffffffffffffff163314612759576040517fb90cdbb100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60cd80547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83169081179091556040517f7dae230f18360d76a040c81f050aa14eb9d6dc7901b20fc5d855e2a20fe814d190600090a250565b3b151590565b600054610100900460ff166127e95760005460ff16156127ed565b303b155b612879576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201527f647920696e697469616c697a65640000000000000000000000000000000000006064820152608401610f1b565b600054610100900460ff161580156128b857600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0000166101011790555b6128c1846134d8565b6128cb84846135bf565b3073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1663e9cbd8226040518163ffffffff1660e01b8152600401602060405180830381865afa15801561292d573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061295191906146fd565b73ffffffffffffffffffffffffffffffffffffffff161461299e576040517f14bcf5c800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60cd80547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff84169081179091556040517f7dae230f18360d76a040c81f050aa14eb9d6dc7901b20fc5d855e2a20fe814d190600090a28015612a3957600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff1690555b50505050565b73ffffffffffffffffffffffffffffffffffffffff8316612ae1576040517f08c379a0000000000000000000000000000000000000000000000000000000008152602060048201526024808201527f45524332303a20617070726f76652066726f6d20746865207a65726f2061646460448201527f72657373000000000000000000000000000000000000000000000000000000006064820152608401610f1b565b73ffffffffffffffffffffffffffffffffffffffff8216612b84576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602260248201527f45524332303a20617070726f766520746f20746865207a65726f20616464726560448201527f73730000000000000000000000000000000000000000000000000000000000006064820152608401610f1b565b73ffffffffffffffffffffffffffffffffffffffff83811660008181526034602090815260408083209487168084529482529182902085905590518481527f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b9259101610af3565b60405173ffffffffffffffffffffffffffffffffffffffff831660248201526044810182905261082d9084907fa9059cbb00000000000000000000000000000000000000000000000000000000906064015b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff0000000000000000000000000000000000000000000000000000000090931692909217909152613668565b60405173ffffffffffffffffffffffffffffffffffffffff80851660248301528316604482015260648101829052612a399085907f23b872dd0000000000000000000000000000000000000000000000000000000090608401612c3c565b73ffffffffffffffffffffffffffffffffffffffff8216612d99576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601f60248201527f45524332303a206d696e7420746f20746865207a65726f2061646472657373006044820152606401610f1b565b8060356000828254612dab91906145d6565b909155505073ffffffffffffffffffffffffffffffffffffffff821660009081526033602052604081208054839290612de59084906145d6565b909155505060405181815273ffffffffffffffffffffffffffffffffffffffff8316906000907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef9060200160405180910390a35050565b73ffffffffffffffffffffffffffffffffffffffff8316612edf576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602560248201527f45524332303a207472616e736665722066726f6d20746865207a65726f20616460448201527f64726573730000000000000000000000000000000000000000000000000000006064820152608401610f1b565b73ffffffffffffffffffffffffffffffffffffffff8216612f82576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602360248201527f45524332303a207472616e7366657220746f20746865207a65726f206164647260448201527f65737300000000000000000000000000000000000000000000000000000000006064820152608401610f1b565b73ffffffffffffffffffffffffffffffffffffffff831660009081526033602052604090205481811015613038576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f45524332303a207472616e7366657220616d6f756e742065786365656473206260448201527f616c616e636500000000000000000000000000000000000000000000000000006064820152608401610f1b565b73ffffffffffffffffffffffffffffffffffffffff80851660009081526033602052604080822085850390559185168152908120805484929061307c9084906145d6565b925050819055508273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef846040516130e291815260200190565b60405180910390a3612a39565b73ffffffffffffffffffffffffffffffffffffffff8216613192576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602160248201527f45524332303a206275726e2066726f6d20746865207a65726f2061646472657360448201527f73000000000000000000000000000000000000000000000000000000000000006064820152608401610f1b565b73ffffffffffffffffffffffffffffffffffffffff821660009081526033602052604090205481811015613248576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602260248201527f45524332303a206275726e20616d6f756e7420657863656564732062616c616e60448201527f63650000000000000000000000000000000000000000000000000000000000006064820152608401610f1b565b73ffffffffffffffffffffffffffffffffffffffff831660009081526033602052604081208383039055603580548492906132849084906145a6565b909155505060405182815260009073ffffffffffffffffffffffffffffffffffffffff8516907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef9060200160405180910390a3505050565b8073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff161461338d5773ffffffffffffffffffffffffffffffffffffffff8281166000908152603460209081526040808320938516835292905220548381101561337c576040517f715ec26c00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b61338b838361166587856145a6565b505b61082d82846130ef565b600061148c7f8b73c3c69bb8fe3d512ecc4cf759cc79239f7b179b0ffacaa9a75d522b39400f6133c660655490565b6066546040805160208101859052908101839052606081018290524660808201523060a082015260009060c0016040516020818303038152906040528051906020012090509392505050565b73ffffffffffffffffffffffffffffffffffffffff811660009081526099602052604090208054600181018255905b50919050565b6000611d4f613454613397565b836040517f19010000000000000000000000000000000000000000000000000000000000006020820152602281018390526042810182905260009060620160405160208183030381529060405280519060200120905092915050565b60008060006134c187878787613774565b915091506134ce8161388c565b5095945050505050565b600054610100900460ff1661356f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201527f6e697469616c697a696e670000000000000000000000000000000000000000006064820152608401610f1b565b613577613ae5565b6135b6816040518060400160405280600181526020017f3100000000000000000000000000000000000000000000000000000000000000815250613b7e565b611d5f81613c2f565b600054610100900460ff16613656576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201527f6e697469616c697a696e670000000000000000000000000000000000000000006064820152608401610f1b565b61365e613ae5565b610f8f8282613ced565b60006136ca826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c65648152508573ffffffffffffffffffffffffffffffffffffffff16613dab9092919063ffffffff16565b80519091501561082d57808060200190518101906136e8919061455a565b61082d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e60448201527f6f742073756363656564000000000000000000000000000000000000000000006064820152608401610f1b565b6000807f7fffffffffffffffffffffffffffffff5d576e7357a4501ddfe92f46681b20a08311156137ab5750600090506003613883565b8460ff16601b141580156137c357508460ff16601c14155b156137d45750600090506004613883565b6040805160008082526020820180845289905260ff881692820192909252606081018690526080810185905260019060a0016020604051602081039080840390855afa158015613828573d6000803e3d6000fd5b50506040517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0015191505073ffffffffffffffffffffffffffffffffffffffff811661387c57600060019250925050613883565b9150600090505b94509492505050565b60008160048111156138a0576138a061471a565b14156138a95750565b60018160048111156138bd576138bd61471a565b1415613925576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601860248201527f45434453413a20696e76616c6964207369676e617475726500000000000000006044820152606401610f1b565b60028160048111156139395761393961471a565b14156139a1576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601f60248201527f45434453413a20696e76616c6964207369676e6174757265206c656e677468006044820152606401610f1b565b60038160048111156139b5576139b561471a565b1415613a43576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602260248201527f45434453413a20696e76616c6964207369676e6174757265202773272076616c60448201527f75650000000000000000000000000000000000000000000000000000000000006064820152608401610f1b565b6004816004811115613a5757613a5761471a565b1415611d5f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602260248201527f45434453413a20696e76616c6964207369676e6174757265202776272076616c60448201527f75650000000000000000000000000000000000000000000000000000000000006064820152608401610f1b565b600054610100900460ff16613b7c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201527f6e697469616c697a696e670000000000000000000000000000000000000000006064820152608401610f1b565b565b600054610100900460ff16613c15576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201527f6e697469616c697a696e670000000000000000000000000000000000000000006064820152608401610f1b565b815160209283012081519190920120606591909155606655565b600054610100900460ff16613cc6576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201527f6e697469616c697a696e670000000000000000000000000000000000000000006064820152608401610f1b565b507f6e71edae12b1b97f4d1f60370fef10105fa2faae0126114a169c64845d6126c9609a55565b600054610100900460ff16613d84576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201527f6e697469616c697a696e670000000000000000000000000000000000000000006064820152608401610f1b565b8151613d97906036906020850190613f85565b50805161082d906037906020840190613f85565b6060613dba8484600085613dc2565b949350505050565b606082471015613e54576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f60448201527f722063616c6c00000000000000000000000000000000000000000000000000006064820152608401610f1b565b843b613ebc576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006044820152606401610f1b565b6000808673ffffffffffffffffffffffffffffffffffffffff168587604051613ee59190614749565b60006040518083038185875af1925050503d8060008114613f22576040519150601f19603f3d011682016040523d82523d6000602084013e613f27565b606091505b509150915061238882828660608315613f41575081610e4a565b825115613f515782518084602001fd5b816040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610f1b919061404a565b828054613f919061450c565b90600052602060002090601f016020900481019282613fb35760008555613ff9565b82601f10613fcc57805160ff1916838001178555613ff9565b82800160010185558215613ff9579182015b82811115613ff9578251825591602001919060010190613fde565b50614005929150614009565b5090565b5b80821115614005576000815560010161400a565b60005b83811015614039578181015183820152602001614021565b83811115612a395750506000910152565b602081526000825180602084015261406981604085016020870161401e565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169190910160400192915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b600082601f8301126140db57600080fd5b813567ffffffffffffffff808211156140f6576140f661409b565b604051601f83017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0908116603f0116810190828211818310171561413c5761413c61409b565b8160405283815286602085880101111561415557600080fd5b836020870160208301376000602085830101528094505050505092915050565b73ffffffffffffffffffffffffffffffffffffffff81168114611d5f57600080fd5b6000806000606084860312156141ac57600080fd5b833567ffffffffffffffff808211156141c457600080fd5b6141d0878388016140ca565b945060208601359150808211156141e657600080fd5b506141f3868287016140ca565b925050604084013561420481614175565b809150509250925092565b60006020828403121561422157600080fd5b8135610e4a81614175565b6000806040838503121561423f57600080fd5b823561424a81614175565b946020939093013593505050565b60008060006060848603121561426d57600080fd5b833561427881614175565b9250602084013561428881614175565b929592945050506040919091013590565b6000806000606084860312156142ae57600080fd5b83356142b981614175565b925060208401359150604084013561420481614175565b600080604083850312156142e357600080fd5b8235915060208301356142f581614175565b809150509250929050565b60008060006060848603121561431557600080fd5b83359250602084013561432781614175565b9150604084013561420481614175565b60006020828403121561434957600080fd5b5035919050565b803567ffffffffffffffff8116811461436857600080fd5b919050565b8015158114611d5f57600080fd5b600080600080600060a0868803121561439357600080fd5b853561439e81614175565b945060208601359350604086013592506143ba60608701614350565b915060808601356143ca8161436d565b809150509295509295909350565b600080604083850312156143eb57600080fd5b82356143f681614175565b915061440460208401614350565b90509250929050565b6020808252825182820181905260009190848201906040850190845b8181101561445b57835173ffffffffffffffffffffffffffffffffffffffff1683529284019291840191600101614429565b50909695505050505050565b600080600080600080600060e0888a03121561448257600080fd5b873561448d81614175565b9650602088013561449d81614175565b95506040880135945060608801359350608088013560ff811681146144c157600080fd5b9699959850939692959460a0840135945060c09093013592915050565b600080604083850312156144f157600080fd5b82356144fc81614175565b915060208301356142f581614175565b600181811c9082168061452057607f821691505b60208210811415613441577f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b60006020828403121561456c57600080fd5b8151610e4a8161436d565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b6000828210156145b8576145b8614577565b500390565b6000602082840312156145cf57600080fd5b5051919050565b600082198211156145e9576145e9614577565b500190565b600082614624577f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b500490565b6000817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff048311821515161561466157614661614577565b500290565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8214156146c7576146c7614577565b5060010190565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603160045260246000fd5b60006020828403121561470f57600080fd5b8151610e4a81614175565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b6000825161475b81846020870161401e565b919091019291505056fea2646970667358221220103b8d652dd7975983cef70f41cb81056a0bf607243b7332223b4013506c7eb664736f6c634300080c0033", + "numDeployments": 2, + "solcInputHash": "871924e0c138825a2736b76def8fef8d", + "metadata": "{\"compiler\":{\"version\":\"0.8.17+commit.8df45f5f\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[],\"name\":\"AssetStillControlledInReserves\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"BurnAmountExceedsAllowance\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"HourlyLimitExceeded\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidSender\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidToken\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidTreasury\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"NotGovernor\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"NotGovernorOrGuardian\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"NotMinter\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"NotTreasury\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"TooBigAmount\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"TooHighParameterValue\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ZeroAddress\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"spender\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"}],\"name\":\"Approval\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"bridgeToken\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"limit\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"hourlyLimit\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"fee\",\"type\":\"uint64\"},{\"indexed\":false,\"internalType\":\"bool\",\"name\":\"paused\",\"type\":\"bool\"}],\"name\":\"BridgeTokenAdded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"bridgeToken\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"fee\",\"type\":\"uint64\"}],\"name\":\"BridgeTokenFeeUpdated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"bridgeToken\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"hourlyLimit\",\"type\":\"uint256\"}],\"name\":\"BridgeTokenHourlyLimitUpdated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"bridgeToken\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"limit\",\"type\":\"uint256\"}],\"name\":\"BridgeTokenLimitUpdated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"bridgeToken\",\"type\":\"address\"}],\"name\":\"BridgeTokenRemoved\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"bridgeToken\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"bool\",\"name\":\"toggleStatus\",\"type\":\"bool\"}],\"name\":\"BridgeTokenToggled\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"theAddress\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"toggleStatus\",\"type\":\"uint256\"}],\"name\":\"FeeToggled\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"hourlyLimit\",\"type\":\"uint256\"}],\"name\":\"HourlyLimitUpdated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint8\",\"name\":\"version\",\"type\":\"uint8\"}],\"name\":\"Initialized\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"minter\",\"type\":\"address\"}],\"name\":\"MinterToggled\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"Recovered\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"}],\"name\":\"Transfer\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"_treasury\",\"type\":\"address\"}],\"name\":\"TreasuryUpdated\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"BASE_PARAMS\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"DOMAIN_SEPARATOR\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"bridgeToken\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"limit\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"hourlyLimit\",\"type\":\"uint256\"},{\"internalType\":\"uint64\",\"name\":\"fee\",\"type\":\"uint64\"},{\"internalType\":\"bool\",\"name\":\"paused\",\"type\":\"bool\"}],\"name\":\"addBridgeToken\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"minter\",\"type\":\"address\"}],\"name\":\"addMinter\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"allBridgeTokens\",\"outputs\":[{\"internalType\":\"address[]\",\"name\":\"\",\"type\":\"address[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"spender\",\"type\":\"address\"}],\"name\":\"allowance\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"spender\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"approve\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"}],\"name\":\"balanceOf\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"name\":\"bridgeTokensList\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"bridges\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"limit\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"hourlyLimit\",\"type\":\"uint256\"},{\"internalType\":\"uint64\",\"name\":\"fee\",\"type\":\"uint64\"},{\"internalType\":\"bool\",\"name\":\"allowed\",\"type\":\"bool\"},{\"internalType\":\"bool\",\"name\":\"paused\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"burner\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"}],\"name\":\"burnFrom\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"burner\",\"type\":\"address\"}],\"name\":\"burnSelf\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"burnStablecoin\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"chainTotalHourlyLimit\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"name\":\"chainTotalUsage\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"currentTotalUsage\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"bridgeToken\",\"type\":\"address\"}],\"name\":\"currentUsage\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"decimals\",\"outputs\":[{\"internalType\":\"uint8\",\"name\":\"\",\"type\":\"uint8\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"spender\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"subtractedValue\",\"type\":\"uint256\"}],\"name\":\"decreaseAllowance\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"spender\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"addedValue\",\"type\":\"uint256\"}],\"name\":\"increaseAllowance\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"string\",\"name\":\"name_\",\"type\":\"string\"},{\"internalType\":\"string\",\"name\":\"symbol_\",\"type\":\"string\"},{\"internalType\":\"address\",\"name\":\"_treasury\",\"type\":\"address\"}],\"name\":\"initialize\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"isFeeExempt\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"isMinter\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"mint\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"name\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"}],\"name\":\"nonces\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"spender\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"deadline\",\"type\":\"uint256\"},{\"internalType\":\"uint8\",\"name\":\"v\",\"type\":\"uint8\"},{\"internalType\":\"bytes32\",\"name\":\"r\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32\",\"name\":\"s\",\"type\":\"bytes32\"}],\"name\":\"permit\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"tokenAddress\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amountToRecover\",\"type\":\"uint256\"}],\"name\":\"recoverERC20\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"bridgeToken\",\"type\":\"address\"}],\"name\":\"removeBridgeToken\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"minter\",\"type\":\"address\"}],\"name\":\"removeMinter\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"hourlyLimit\",\"type\":\"uint256\"}],\"name\":\"setChainTotalHourlyLimit\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"bridgeToken\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"hourlyLimit\",\"type\":\"uint256\"}],\"name\":\"setHourlyLimit\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"bridgeToken\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"limit\",\"type\":\"uint256\"}],\"name\":\"setLimit\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"bridgeToken\",\"type\":\"address\"},{\"internalType\":\"uint64\",\"name\":\"fee\",\"type\":\"uint64\"}],\"name\":\"setSwapFee\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_treasury\",\"type\":\"address\"}],\"name\":\"setTreasury\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"bridgeToken\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"swapIn\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"bridgeToken\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"swapOut\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"symbol\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"bridgeToken\",\"type\":\"address\"}],\"name\":\"toggleBridge\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"theAddress\",\"type\":\"address\"}],\"name\":\"toggleFeesForAddress\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"totalSupply\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"transfer\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"transferFrom\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"treasury\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"name\":\"usage\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"}],\"devdoc\":{\"author\":\"Angle Labs, Inc.\",\"details\":\"This contract supports bridge tokens having a minting right on the stablecoin (also referred to as the canonical or the native token)\",\"kind\":\"dev\",\"methods\":{\"DOMAIN_SEPARATOR()\":{\"details\":\"See {IERC20Permit-DOMAIN_SEPARATOR}.\"},\"addBridgeToken(address,uint256,uint256,uint64,bool)\":{\"params\":{\"bridgeToken\":\"Bridge token to add: it should be a version of the stablecoin from another bridge\",\"fee\":\"Fee taken upon swapping for or against this token\",\"hourlyLimit\":\"Limit on the hourly volume for this bridge\",\"limit\":\"Limit on the balance of bridge token this contract could hold\",\"paused\":\"Whether swapping for this token should be paused or not\"}},\"addMinter(address)\":{\"details\":\"Zero address checks are performed directly in the `Treasury` contract\",\"params\":{\"minter\":\"Minter address to add\"}},\"allBridgeTokens()\":{\"details\":\"Helpful for UIs\"},\"allowance(address,address)\":{\"details\":\"See {IERC20-allowance}.\"},\"approve(address,uint256)\":{\"details\":\"See {IERC20-approve}. NOTE: If `amount` is the maximum `uint256`, the allowance is not updated on `transferFrom`. This is semantically equivalent to an infinite approval. Requirements: - `spender` cannot be the zero address.\"},\"balanceOf(address)\":{\"details\":\"See {IERC20-balanceOf}.\"},\"burnFrom(uint256,address,address)\":{\"details\":\"This method is to be called by a contract with the minter right after being requested to do so by a `sender` address willing to burn tokens from another `burner` addressThe method checks the allowance between the `sender` and the `burner`\",\"params\":{\"amount\":\"Amount of tokens to burn\",\"burner\":\"Address to burn from\",\"sender\":\"Address which requested the burn from `burner`\"}},\"burnSelf(uint256,address)\":{\"details\":\"This method is to be called by a contract with a minter right on the AgToken after being requested to do so by an address willing to burn tokens from its address\",\"params\":{\"amount\":\"Amount of tokens to burn\",\"burner\":\"Address to burn from\"}},\"burnStablecoin(uint256)\":{\"details\":\"This function can typically be called if there is a settlement mechanism to burn stablecoins\",\"params\":{\"amount\":\"Amount of stablecoins to burn\"}},\"currentTotalUsage()\":{\"details\":\"Helpful for UIs\"},\"currentUsage(address)\":{\"details\":\"Helpful for UIs\",\"params\":{\"bridgeToken\":\"Bridge used to mint\"}},\"decimals()\":{\"details\":\"Returns the number of decimals used to get its user representation. For example, if `decimals` equals `2`, a balance of `505` tokens should be displayed to a user as `5.05` (`505 / 10 ** 2`). Tokens usually opt for a value of 18, imitating the relationship between Ether and Wei. This is the value {ERC20} uses, unless this function is overridden; NOTE: This information is only used for _display_ purposes: it in no way affects any of the arithmetic of the contract, including {IERC20-balanceOf} and {IERC20-transfer}.\"},\"decreaseAllowance(address,uint256)\":{\"details\":\"Atomically decreases the allowance granted to `spender` by the caller. This is an alternative to {approve} that can be used as a mitigation for problems described in {IERC20-approve}. Emits an {Approval} event indicating the updated allowance. Requirements: - `spender` cannot be the zero address. - `spender` must have allowance for the caller of at least `subtractedValue`.\"},\"increaseAllowance(address,uint256)\":{\"details\":\"Atomically increases the allowance granted to `spender` by the caller. This is an alternative to {approve} that can be used as a mitigation for problems described in {IERC20-approve}. Emits an {Approval} event indicating the updated allowance. Requirements: - `spender` cannot be the zero address.\"},\"mint(address,uint256)\":{\"details\":\"The contracts allowed to issue agTokens are the `StableMaster` contract, `VaultManager` contracts associated to this stablecoin as well as the flash loan module (if activated) and potentially contracts whitelisted by governance\",\"params\":{\"account\":\"Address to mint to\",\"amount\":\"Amount to mint\"}},\"name()\":{\"details\":\"Returns the name of the token.\"},\"nonces(address)\":{\"details\":\"See {IERC20Permit-nonces}.\"},\"permit(address,address,uint256,uint256,uint8,bytes32,bytes32)\":{\"details\":\"See {IERC20Permit-permit}.\"},\"recoverERC20(address,address,uint256)\":{\"details\":\"Can be used to withdraw bridge tokens for them to be de-bridged on mainnet\"},\"removeBridgeToken(address)\":{\"params\":{\"bridgeToken\":\"Address of the bridge token to remove support for\"}},\"removeMinter(address)\":{\"details\":\"This function can also be called by a minter wishing to revoke itself\",\"params\":{\"minter\":\"Minter address to remove\"}},\"setTreasury(address)\":{\"params\":{\"_treasury\":\"New treasury address\"}},\"swapIn(address,uint256,address)\":{\"details\":\"Some fees may be taken by the protocol depending on the token used and on the address calling\",\"params\":{\"amount\":\"Amount of bridge tokens to send\",\"bridgeToken\":\"Bridge token to use to mint\",\"to\":\"Address to which the stablecoin should be sent\"},\"returns\":{\"_0\":\"Amount of the canonical stablecoin actually minted\"}},\"swapOut(address,uint256,address)\":{\"details\":\"Some fees may be taken by the protocol depending on the token used and on the address calling\",\"params\":{\"amount\":\"Amount of canonical tokens to burn\",\"bridgeToken\":\"Bridge token required\",\"to\":\"Address to which the bridge token should be sent\"},\"returns\":{\"_0\":\"Amount of bridge tokens actually sent back\"}},\"symbol()\":{\"details\":\"Returns the symbol of the token, usually a shorter version of the name.\"},\"totalSupply()\":{\"details\":\"See {IERC20-totalSupply}.\"},\"transfer(address,uint256)\":{\"details\":\"See {IERC20-transfer}. Requirements: - `to` cannot be the zero address. - the caller must have a balance of at least `amount`.\"},\"transferFrom(address,address,uint256)\":{\"details\":\"See {IERC20-transferFrom}. Emits an {Approval} event indicating the updated allowance. This is not required by the EIP. See the note at the beginning of {ERC20}. NOTE: Does not update the allowance if the current allowance is the maximum `uint256`. Requirements: - `from` and `to` cannot be the zero address. - `from` must have a balance of at least `amount`. - the caller must have allowance for ``from``'s tokens of at least `amount`.\"}},\"title\":\"AgTokenSideChainMultiBridge\",\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{\"BASE_PARAMS()\":{\"notice\":\"Base used for fee computation\"},\"addBridgeToken(address,uint256,uint256,uint64,bool)\":{\"notice\":\"Adds support for a bridge token\"},\"addMinter(address)\":{\"notice\":\"Adds a minter in the contract\"},\"allBridgeTokens()\":{\"notice\":\"Returns the list of all supported bridge tokens\"},\"bridgeTokensList(uint256)\":{\"notice\":\"List of all bridge tokens\"},\"bridges(address)\":{\"notice\":\"Maps a bridge token to data\"},\"burnFrom(uint256,address,address)\":{\"notice\":\"Burns `amount` tokens from a `burner` address after being asked to by `sender`\"},\"burnSelf(uint256,address)\":{\"notice\":\"Burns `amount` tokens from a `burner` address\"},\"burnStablecoin(uint256)\":{\"notice\":\"Allows anyone to burn stablecoins\"},\"chainTotalHourlyLimit()\":{\"notice\":\"Limit to the amount of tokens that can be sent from that chain to another chain\"},\"chainTotalUsage(uint256)\":{\"notice\":\"Usage per hour on that chain. Maps an hourly timestamp to the total volume swapped out on the chain\"},\"currentTotalUsage()\":{\"notice\":\"Returns the current total volume on the chain for the current hour\"},\"currentUsage(address)\":{\"notice\":\"Returns the current volume for a bridge, for the current hour\"},\"initialize(string,string,address)\":{\"notice\":\"Initializes the `AgToken` contract\"},\"isFeeExempt(address)\":{\"notice\":\"Maps an address to whether it is exempt of fees for when it comes to swapping in and out\"},\"isMinter(address)\":{\"notice\":\"Checks whether an address has the right to mint agTokens\"},\"mint(address,uint256)\":{\"notice\":\"Lets the `StableMaster` contract or another whitelisted contract mint agTokens\"},\"recoverERC20(address,address,uint256)\":{\"notice\":\"Recovers any ERC20 token\"},\"removeBridgeToken(address)\":{\"notice\":\"Removes support for a token\"},\"removeMinter(address)\":{\"notice\":\"Removes a minter from the contract\"},\"setChainTotalHourlyLimit(uint256)\":{\"notice\":\"Updates the `chainTotalHourlyLimit` amount\"},\"setHourlyLimit(address,uint256)\":{\"notice\":\"Updates the `hourlyLimit` amount for `bridgeToken`\"},\"setLimit(address,uint256)\":{\"notice\":\"Updates the `limit` amount for `bridgeToken`\"},\"setSwapFee(address,uint64)\":{\"notice\":\"Updates the `fee` value for `bridgeToken`\"},\"setTreasury(address)\":{\"notice\":\"Sets a new treasury contract\"},\"swapIn(address,uint256,address)\":{\"notice\":\"Mints the canonical token from a supported bridge token\"},\"swapOut(address,uint256,address)\":{\"notice\":\"Burns the canonical token in exchange for a bridge token\"},\"toggleBridge(address)\":{\"notice\":\"Pauses or unpauses swapping in and out for a token\"},\"toggleFeesForAddress(address)\":{\"notice\":\"Toggles fees for the address `theAddress`\"},\"treasury()\":{\"notice\":\"Reference to the treasury contract which can grant minting rights\"},\"usage(address,uint256)\":{\"notice\":\"Maps a bridge token to the associated hourly volume\"}},\"notice\":\"Contract for Angle agTokens on other chains than Ethereum mainnet\",\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/agToken/AgTokenSideChainMultiBridge.sol\":\"AgTokenSideChainMultiBridge\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":1000000},\"remappings\":[]},\"sources\":{\"@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.7.0) (proxy/utils/Initializable.sol)\\n\\npragma solidity ^0.8.2;\\n\\nimport \\\"../../utils/AddressUpgradeable.sol\\\";\\n\\n/**\\n * @dev This is a base contract to aid in writing upgradeable contracts, or any kind of contract that will be deployed\\n * behind a proxy. Since proxied contracts do not make use of a constructor, it's common to move constructor logic to an\\n * external initializer function, usually called `initialize`. It then becomes necessary to protect this initializer\\n * function so it can only be called once. The {initializer} modifier provided by this contract will have this effect.\\n *\\n * The initialization functions use a version number. Once a version number is used, it is consumed and cannot be\\n * reused. This mechanism prevents re-execution of each \\\"step\\\" but allows the creation of new initialization steps in\\n * case an upgrade adds a module that needs to be initialized.\\n *\\n * For example:\\n *\\n * [.hljs-theme-light.nopadding]\\n * ```\\n * contract MyToken is ERC20Upgradeable {\\n * function initialize() initializer public {\\n * __ERC20_init(\\\"MyToken\\\", \\\"MTK\\\");\\n * }\\n * }\\n * contract MyTokenV2 is MyToken, ERC20PermitUpgradeable {\\n * function initializeV2() reinitializer(2) public {\\n * __ERC20Permit_init(\\\"MyToken\\\");\\n * }\\n * }\\n * ```\\n *\\n * TIP: To avoid leaving the proxy in an uninitialized state, the initializer function should be called as early as\\n * possible by providing the encoded function call as the `_data` argument to {ERC1967Proxy-constructor}.\\n *\\n * CAUTION: When used with inheritance, manual care must be taken to not invoke a parent initializer twice, or to ensure\\n * that all initializers are idempotent. This is not verified automatically as constructors are by Solidity.\\n *\\n * [CAUTION]\\n * ====\\n * Avoid leaving a contract uninitialized.\\n *\\n * An uninitialized contract can be taken over by an attacker. This applies to both a proxy and its implementation\\n * contract, which may impact the proxy. To prevent the implementation contract from being used, you should invoke\\n * the {_disableInitializers} function in the constructor to automatically lock it when it is deployed:\\n *\\n * [.hljs-theme-light.nopadding]\\n * ```\\n * /// @custom:oz-upgrades-unsafe-allow constructor\\n * constructor() {\\n * _disableInitializers();\\n * }\\n * ```\\n * ====\\n */\\nabstract contract Initializable {\\n /**\\n * @dev Indicates that the contract has been initialized.\\n * @custom:oz-retyped-from bool\\n */\\n uint8 private _initialized;\\n\\n /**\\n * @dev Indicates that the contract is in the process of being initialized.\\n */\\n bool private _initializing;\\n\\n /**\\n * @dev Triggered when the contract has been initialized or reinitialized.\\n */\\n event Initialized(uint8 version);\\n\\n /**\\n * @dev A modifier that defines a protected initializer function that can be invoked at most once. In its scope,\\n * `onlyInitializing` functions can be used to initialize parent contracts. Equivalent to `reinitializer(1)`.\\n */\\n modifier initializer() {\\n bool isTopLevelCall = !_initializing;\\n require(\\n (isTopLevelCall && _initialized < 1) || (!AddressUpgradeable.isContract(address(this)) && _initialized == 1),\\n \\\"Initializable: contract is already initialized\\\"\\n );\\n _initialized = 1;\\n if (isTopLevelCall) {\\n _initializing = true;\\n }\\n _;\\n if (isTopLevelCall) {\\n _initializing = false;\\n emit Initialized(1);\\n }\\n }\\n\\n /**\\n * @dev A modifier that defines a protected reinitializer function that can be invoked at most once, and only if the\\n * contract hasn't been initialized to a greater version before. In its scope, `onlyInitializing` functions can be\\n * used to initialize parent contracts.\\n *\\n * `initializer` is equivalent to `reinitializer(1)`, so a reinitializer may be used after the original\\n * initialization step. This is essential to configure modules that are added through upgrades and that require\\n * initialization.\\n *\\n * Note that versions can jump in increments greater than 1; this implies that if multiple reinitializers coexist in\\n * a contract, executing them in the right order is up to the developer or operator.\\n */\\n modifier reinitializer(uint8 version) {\\n require(!_initializing && _initialized < version, \\\"Initializable: contract is already initialized\\\");\\n _initialized = version;\\n _initializing = true;\\n _;\\n _initializing = false;\\n emit Initialized(version);\\n }\\n\\n /**\\n * @dev Modifier to protect an initialization function so that it can only be invoked by functions with the\\n * {initializer} and {reinitializer} modifiers, directly or indirectly.\\n */\\n modifier onlyInitializing() {\\n require(_initializing, \\\"Initializable: contract is not initializing\\\");\\n _;\\n }\\n\\n /**\\n * @dev Locks the contract, preventing any future reinitialization. This cannot be part of an initializer call.\\n * Calling this in the constructor of a contract will prevent that contract from being initialized or reinitialized\\n * to any version. It is recommended to use this to lock implementation contracts that are designed to be called\\n * through proxies.\\n */\\n function _disableInitializers() internal virtual {\\n require(!_initializing, \\\"Initializable: contract is initializing\\\");\\n if (_initialized < type(uint8).max) {\\n _initialized = type(uint8).max;\\n emit Initialized(type(uint8).max);\\n }\\n }\\n}\\n\",\"keccak256\":\"0x0203dcadc5737d9ef2c211d6fa15d18ebc3b30dfa51903b64870b01a062b0b4e\",\"license\":\"MIT\"},\"@openzeppelin/contracts-upgradeable/token/ERC20/ERC20Upgradeable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.7.0) (token/ERC20/ERC20.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"./IERC20Upgradeable.sol\\\";\\nimport \\\"./extensions/IERC20MetadataUpgradeable.sol\\\";\\nimport \\\"../../utils/ContextUpgradeable.sol\\\";\\nimport \\\"../../proxy/utils/Initializable.sol\\\";\\n\\n/**\\n * @dev Implementation of the {IERC20} interface.\\n *\\n * This implementation is agnostic to the way tokens are created. This means\\n * that a supply mechanism has to be added in a derived contract using {_mint}.\\n * For a generic mechanism see {ERC20PresetMinterPauser}.\\n *\\n * TIP: For a detailed writeup see our guide\\n * https://forum.zeppelin.solutions/t/how-to-implement-erc20-supply-mechanisms/226[How\\n * to implement supply mechanisms].\\n *\\n * We have followed general OpenZeppelin Contracts guidelines: functions revert\\n * instead returning `false` on failure. This behavior is nonetheless\\n * conventional and does not conflict with the expectations of ERC20\\n * applications.\\n *\\n * Additionally, an {Approval} event is emitted on calls to {transferFrom}.\\n * This allows applications to reconstruct the allowance for all accounts just\\n * by listening to said events. Other implementations of the EIP may not emit\\n * these events, as it isn't required by the specification.\\n *\\n * Finally, the non-standard {decreaseAllowance} and {increaseAllowance}\\n * functions have been added to mitigate the well-known issues around setting\\n * allowances. See {IERC20-approve}.\\n */\\ncontract ERC20Upgradeable is Initializable, ContextUpgradeable, IERC20Upgradeable, IERC20MetadataUpgradeable {\\n mapping(address => uint256) private _balances;\\n\\n mapping(address => mapping(address => uint256)) private _allowances;\\n\\n uint256 private _totalSupply;\\n\\n string private _name;\\n string private _symbol;\\n\\n /**\\n * @dev Sets the values for {name} and {symbol}.\\n *\\n * The default value of {decimals} is 18. To select a different value for\\n * {decimals} you should overload it.\\n *\\n * All two of these values are immutable: they can only be set once during\\n * construction.\\n */\\n function __ERC20_init(string memory name_, string memory symbol_) internal onlyInitializing {\\n __ERC20_init_unchained(name_, symbol_);\\n }\\n\\n function __ERC20_init_unchained(string memory name_, string memory symbol_) internal onlyInitializing {\\n _name = name_;\\n _symbol = symbol_;\\n }\\n\\n /**\\n * @dev Returns the name of the token.\\n */\\n function name() public view virtual override returns (string memory) {\\n return _name;\\n }\\n\\n /**\\n * @dev Returns the symbol of the token, usually a shorter version of the\\n * name.\\n */\\n function symbol() public view virtual override returns (string memory) {\\n return _symbol;\\n }\\n\\n /**\\n * @dev Returns the number of decimals used to get its user representation.\\n * For example, if `decimals` equals `2`, a balance of `505` tokens should\\n * be displayed to a user as `5.05` (`505 / 10 ** 2`).\\n *\\n * Tokens usually opt for a value of 18, imitating the relationship between\\n * Ether and Wei. This is the value {ERC20} uses, unless this function is\\n * overridden;\\n *\\n * NOTE: This information is only used for _display_ purposes: it in\\n * no way affects any of the arithmetic of the contract, including\\n * {IERC20-balanceOf} and {IERC20-transfer}.\\n */\\n function decimals() public view virtual override returns (uint8) {\\n return 18;\\n }\\n\\n /**\\n * @dev See {IERC20-totalSupply}.\\n */\\n function totalSupply() public view virtual override returns (uint256) {\\n return _totalSupply;\\n }\\n\\n /**\\n * @dev See {IERC20-balanceOf}.\\n */\\n function balanceOf(address account) public view virtual override returns (uint256) {\\n return _balances[account];\\n }\\n\\n /**\\n * @dev See {IERC20-transfer}.\\n *\\n * Requirements:\\n *\\n * - `to` cannot be the zero address.\\n * - the caller must have a balance of at least `amount`.\\n */\\n function transfer(address to, uint256 amount) public virtual override returns (bool) {\\n address owner = _msgSender();\\n _transfer(owner, to, amount);\\n return true;\\n }\\n\\n /**\\n * @dev See {IERC20-allowance}.\\n */\\n function allowance(address owner, address spender) public view virtual override returns (uint256) {\\n return _allowances[owner][spender];\\n }\\n\\n /**\\n * @dev See {IERC20-approve}.\\n *\\n * NOTE: If `amount` is the maximum `uint256`, the allowance is not updated on\\n * `transferFrom`. This is semantically equivalent to an infinite approval.\\n *\\n * Requirements:\\n *\\n * - `spender` cannot be the zero address.\\n */\\n function approve(address spender, uint256 amount) public virtual override returns (bool) {\\n address owner = _msgSender();\\n _approve(owner, spender, amount);\\n return true;\\n }\\n\\n /**\\n * @dev See {IERC20-transferFrom}.\\n *\\n * Emits an {Approval} event indicating the updated allowance. This is not\\n * required by the EIP. See the note at the beginning of {ERC20}.\\n *\\n * NOTE: Does not update the allowance if the current allowance\\n * is the maximum `uint256`.\\n *\\n * Requirements:\\n *\\n * - `from` and `to` cannot be the zero address.\\n * - `from` must have a balance of at least `amount`.\\n * - the caller must have allowance for ``from``'s tokens of at least\\n * `amount`.\\n */\\n function transferFrom(\\n address from,\\n address to,\\n uint256 amount\\n ) public virtual override returns (bool) {\\n address spender = _msgSender();\\n _spendAllowance(from, spender, amount);\\n _transfer(from, to, amount);\\n return true;\\n }\\n\\n /**\\n * @dev Atomically increases the allowance granted to `spender` by the caller.\\n *\\n * This is an alternative to {approve} that can be used as a mitigation for\\n * problems described in {IERC20-approve}.\\n *\\n * Emits an {Approval} event indicating the updated allowance.\\n *\\n * Requirements:\\n *\\n * - `spender` cannot be the zero address.\\n */\\n function increaseAllowance(address spender, uint256 addedValue) public virtual returns (bool) {\\n address owner = _msgSender();\\n _approve(owner, spender, allowance(owner, spender) + addedValue);\\n return true;\\n }\\n\\n /**\\n * @dev Atomically decreases the allowance granted to `spender` by the caller.\\n *\\n * This is an alternative to {approve} that can be used as a mitigation for\\n * problems described in {IERC20-approve}.\\n *\\n * Emits an {Approval} event indicating the updated allowance.\\n *\\n * Requirements:\\n *\\n * - `spender` cannot be the zero address.\\n * - `spender` must have allowance for the caller of at least\\n * `subtractedValue`.\\n */\\n function decreaseAllowance(address spender, uint256 subtractedValue) public virtual returns (bool) {\\n address owner = _msgSender();\\n uint256 currentAllowance = allowance(owner, spender);\\n require(currentAllowance >= subtractedValue, \\\"ERC20: decreased allowance below zero\\\");\\n unchecked {\\n _approve(owner, spender, currentAllowance - subtractedValue);\\n }\\n\\n return true;\\n }\\n\\n /**\\n * @dev Moves `amount` of tokens from `from` to `to`.\\n *\\n * This internal function is equivalent to {transfer}, and can be used to\\n * e.g. implement automatic token fees, slashing mechanisms, etc.\\n *\\n * Emits a {Transfer} event.\\n *\\n * Requirements:\\n *\\n * - `from` cannot be the zero address.\\n * - `to` cannot be the zero address.\\n * - `from` must have a balance of at least `amount`.\\n */\\n function _transfer(\\n address from,\\n address to,\\n uint256 amount\\n ) internal virtual {\\n require(from != address(0), \\\"ERC20: transfer from the zero address\\\");\\n require(to != address(0), \\\"ERC20: transfer to the zero address\\\");\\n\\n _beforeTokenTransfer(from, to, amount);\\n\\n uint256 fromBalance = _balances[from];\\n require(fromBalance >= amount, \\\"ERC20: transfer amount exceeds balance\\\");\\n unchecked {\\n _balances[from] = fromBalance - amount;\\n }\\n _balances[to] += amount;\\n\\n emit Transfer(from, to, amount);\\n\\n _afterTokenTransfer(from, to, amount);\\n }\\n\\n /** @dev Creates `amount` tokens and assigns them to `account`, increasing\\n * the total supply.\\n *\\n * Emits a {Transfer} event with `from` set to the zero address.\\n *\\n * Requirements:\\n *\\n * - `account` cannot be the zero address.\\n */\\n function _mint(address account, uint256 amount) internal virtual {\\n require(account != address(0), \\\"ERC20: mint to the zero address\\\");\\n\\n _beforeTokenTransfer(address(0), account, amount);\\n\\n _totalSupply += amount;\\n _balances[account] += amount;\\n emit Transfer(address(0), account, amount);\\n\\n _afterTokenTransfer(address(0), account, amount);\\n }\\n\\n /**\\n * @dev Destroys `amount` tokens from `account`, reducing the\\n * total supply.\\n *\\n * Emits a {Transfer} event with `to` set to the zero address.\\n *\\n * Requirements:\\n *\\n * - `account` cannot be the zero address.\\n * - `account` must have at least `amount` tokens.\\n */\\n function _burn(address account, uint256 amount) internal virtual {\\n require(account != address(0), \\\"ERC20: burn from the zero address\\\");\\n\\n _beforeTokenTransfer(account, address(0), amount);\\n\\n uint256 accountBalance = _balances[account];\\n require(accountBalance >= amount, \\\"ERC20: burn amount exceeds balance\\\");\\n unchecked {\\n _balances[account] = accountBalance - amount;\\n }\\n _totalSupply -= amount;\\n\\n emit Transfer(account, address(0), amount);\\n\\n _afterTokenTransfer(account, address(0), amount);\\n }\\n\\n /**\\n * @dev Sets `amount` as the allowance of `spender` over the `owner` s tokens.\\n *\\n * This internal function is equivalent to `approve`, and can be used to\\n * e.g. set automatic allowances for certain subsystems, etc.\\n *\\n * Emits an {Approval} event.\\n *\\n * Requirements:\\n *\\n * - `owner` cannot be the zero address.\\n * - `spender` cannot be the zero address.\\n */\\n function _approve(\\n address owner,\\n address spender,\\n uint256 amount\\n ) internal virtual {\\n require(owner != address(0), \\\"ERC20: approve from the zero address\\\");\\n require(spender != address(0), \\\"ERC20: approve to the zero address\\\");\\n\\n _allowances[owner][spender] = amount;\\n emit Approval(owner, spender, amount);\\n }\\n\\n /**\\n * @dev Updates `owner` s allowance for `spender` based on spent `amount`.\\n *\\n * Does not update the allowance amount in case of infinite allowance.\\n * Revert if not enough allowance is available.\\n *\\n * Might emit an {Approval} event.\\n */\\n function _spendAllowance(\\n address owner,\\n address spender,\\n uint256 amount\\n ) internal virtual {\\n uint256 currentAllowance = allowance(owner, spender);\\n if (currentAllowance != type(uint256).max) {\\n require(currentAllowance >= amount, \\\"ERC20: insufficient allowance\\\");\\n unchecked {\\n _approve(owner, spender, currentAllowance - amount);\\n }\\n }\\n }\\n\\n /**\\n * @dev Hook that is called before any transfer of tokens. This includes\\n * minting and burning.\\n *\\n * Calling conditions:\\n *\\n * - when `from` and `to` are both non-zero, `amount` of ``from``'s tokens\\n * will be transferred to `to`.\\n * - when `from` is zero, `amount` tokens will be minted for `to`.\\n * - when `to` is zero, `amount` of ``from``'s tokens will be burned.\\n * - `from` and `to` are never both zero.\\n *\\n * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].\\n */\\n function _beforeTokenTransfer(\\n address from,\\n address to,\\n uint256 amount\\n ) internal virtual {}\\n\\n /**\\n * @dev Hook that is called after any transfer of tokens. This includes\\n * minting and burning.\\n *\\n * Calling conditions:\\n *\\n * - when `from` and `to` are both non-zero, `amount` of ``from``'s tokens\\n * has been transferred to `to`.\\n * - when `from` is zero, `amount` tokens have been minted for `to`.\\n * - when `to` is zero, `amount` of ``from``'s tokens have been burned.\\n * - `from` and `to` are never both zero.\\n *\\n * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].\\n */\\n function _afterTokenTransfer(\\n address from,\\n address to,\\n uint256 amount\\n ) internal virtual {}\\n\\n /**\\n * @dev This empty reserved space is put in place to allow future versions to add new\\n * variables without shifting down storage in the inheritance chain.\\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\\n */\\n uint256[45] private __gap;\\n}\\n\",\"keccak256\":\"0x7c7ac0bc6c340a7f320524b9a4b4b079ee9da3c51258080d4bab237f329a427c\",\"license\":\"MIT\"},\"@openzeppelin/contracts-upgradeable/token/ERC20/IERC20Upgradeable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.6.0) (token/ERC20/IERC20.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Interface of the ERC20 standard as defined in the EIP.\\n */\\ninterface IERC20Upgradeable {\\n /**\\n * @dev Emitted when `value` tokens are moved from one account (`from`) to\\n * another (`to`).\\n *\\n * Note that `value` may be zero.\\n */\\n event Transfer(address indexed from, address indexed to, uint256 value);\\n\\n /**\\n * @dev Emitted when the allowance of a `spender` for an `owner` is set by\\n * a call to {approve}. `value` is the new allowance.\\n */\\n event Approval(address indexed owner, address indexed spender, uint256 value);\\n\\n /**\\n * @dev Returns the amount of tokens in existence.\\n */\\n function totalSupply() external view returns (uint256);\\n\\n /**\\n * @dev Returns the amount of tokens owned by `account`.\\n */\\n function balanceOf(address account) external view returns (uint256);\\n\\n /**\\n * @dev Moves `amount` tokens from the caller's account to `to`.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * Emits a {Transfer} event.\\n */\\n function transfer(address to, uint256 amount) external returns (bool);\\n\\n /**\\n * @dev Returns the remaining number of tokens that `spender` will be\\n * allowed to spend on behalf of `owner` through {transferFrom}. This is\\n * zero by default.\\n *\\n * This value changes when {approve} or {transferFrom} are called.\\n */\\n function allowance(address owner, address spender) external view returns (uint256);\\n\\n /**\\n * @dev Sets `amount` as the allowance of `spender` over the caller's tokens.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * IMPORTANT: Beware that changing an allowance with this method brings the risk\\n * that someone may use both the old and the new allowance by unfortunate\\n * transaction ordering. One possible solution to mitigate this race\\n * condition is to first reduce the spender's allowance to 0 and set the\\n * desired value afterwards:\\n * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729\\n *\\n * Emits an {Approval} event.\\n */\\n function approve(address spender, uint256 amount) external returns (bool);\\n\\n /**\\n * @dev Moves `amount` tokens from `from` to `to` using the\\n * allowance mechanism. `amount` is then deducted from the caller's\\n * allowance.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * Emits a {Transfer} event.\\n */\\n function transferFrom(\\n address from,\\n address to,\\n uint256 amount\\n ) external returns (bool);\\n}\\n\",\"keccak256\":\"0x4e733d3164f73f461eaf9d8087a7ad1ea180bdc8ba0d3d61b0e1ae16d8e63dff\",\"license\":\"MIT\"},\"@openzeppelin/contracts-upgradeable/token/ERC20/extensions/IERC20MetadataUpgradeable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (token/ERC20/extensions/IERC20Metadata.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../IERC20Upgradeable.sol\\\";\\n\\n/**\\n * @dev Interface for the optional metadata functions from the ERC20 standard.\\n *\\n * _Available since v4.1._\\n */\\ninterface IERC20MetadataUpgradeable is IERC20Upgradeable {\\n /**\\n * @dev Returns the name of the token.\\n */\\n function name() external view returns (string memory);\\n\\n /**\\n * @dev Returns the symbol of the token.\\n */\\n function symbol() external view returns (string memory);\\n\\n /**\\n * @dev Returns the decimals places of the token.\\n */\\n function decimals() external view returns (uint8);\\n}\\n\",\"keccak256\":\"0x605434219ebbe4653f703640f06969faa5a1d78f0bfef878e5ddbb1ca369ceeb\",\"license\":\"MIT\"},\"@openzeppelin/contracts-upgradeable/token/ERC20/extensions/draft-ERC20PermitUpgradeable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.6.0) (token/ERC20/extensions/draft-ERC20Permit.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"./draft-IERC20PermitUpgradeable.sol\\\";\\nimport \\\"../ERC20Upgradeable.sol\\\";\\nimport \\\"../../../utils/cryptography/draft-EIP712Upgradeable.sol\\\";\\nimport \\\"../../../utils/cryptography/ECDSAUpgradeable.sol\\\";\\nimport \\\"../../../utils/CountersUpgradeable.sol\\\";\\nimport \\\"../../../proxy/utils/Initializable.sol\\\";\\n\\n/**\\n * @dev Implementation of the ERC20 Permit extension allowing approvals to be made via signatures, as defined in\\n * https://eips.ethereum.org/EIPS/eip-2612[EIP-2612].\\n *\\n * Adds the {permit} method, which can be used to change an account's ERC20 allowance (see {IERC20-allowance}) by\\n * presenting a message signed by the account. By not relying on `{IERC20-approve}`, the token holder account doesn't\\n * need to send a transaction, and thus is not required to hold Ether at all.\\n *\\n * _Available since v3.4._\\n *\\n * @custom:storage-size 51\\n */\\nabstract contract ERC20PermitUpgradeable is Initializable, ERC20Upgradeable, IERC20PermitUpgradeable, EIP712Upgradeable {\\n using CountersUpgradeable for CountersUpgradeable.Counter;\\n\\n mapping(address => CountersUpgradeable.Counter) private _nonces;\\n\\n // solhint-disable-next-line var-name-mixedcase\\n bytes32 private constant _PERMIT_TYPEHASH =\\n keccak256(\\\"Permit(address owner,address spender,uint256 value,uint256 nonce,uint256 deadline)\\\");\\n /**\\n * @dev In previous versions `_PERMIT_TYPEHASH` was declared as `immutable`.\\n * However, to ensure consistency with the upgradeable transpiler, we will continue\\n * to reserve a slot.\\n * @custom:oz-renamed-from _PERMIT_TYPEHASH\\n */\\n // solhint-disable-next-line var-name-mixedcase\\n bytes32 private _PERMIT_TYPEHASH_DEPRECATED_SLOT;\\n\\n /**\\n * @dev Initializes the {EIP712} domain separator using the `name` parameter, and setting `version` to `\\\"1\\\"`.\\n *\\n * It's a good idea to use the same `name` that is defined as the ERC20 token name.\\n */\\n function __ERC20Permit_init(string memory name) internal onlyInitializing {\\n __EIP712_init_unchained(name, \\\"1\\\");\\n }\\n\\n function __ERC20Permit_init_unchained(string memory) internal onlyInitializing {}\\n\\n /**\\n * @dev See {IERC20Permit-permit}.\\n */\\n function permit(\\n address owner,\\n address spender,\\n uint256 value,\\n uint256 deadline,\\n uint8 v,\\n bytes32 r,\\n bytes32 s\\n ) public virtual override {\\n require(block.timestamp <= deadline, \\\"ERC20Permit: expired deadline\\\");\\n\\n bytes32 structHash = keccak256(abi.encode(_PERMIT_TYPEHASH, owner, spender, value, _useNonce(owner), deadline));\\n\\n bytes32 hash = _hashTypedDataV4(structHash);\\n\\n address signer = ECDSAUpgradeable.recover(hash, v, r, s);\\n require(signer == owner, \\\"ERC20Permit: invalid signature\\\");\\n\\n _approve(owner, spender, value);\\n }\\n\\n /**\\n * @dev See {IERC20Permit-nonces}.\\n */\\n function nonces(address owner) public view virtual override returns (uint256) {\\n return _nonces[owner].current();\\n }\\n\\n /**\\n * @dev See {IERC20Permit-DOMAIN_SEPARATOR}.\\n */\\n // solhint-disable-next-line func-name-mixedcase\\n function DOMAIN_SEPARATOR() external view override returns (bytes32) {\\n return _domainSeparatorV4();\\n }\\n\\n /**\\n * @dev \\\"Consume a nonce\\\": return the current value and increment.\\n *\\n * _Available since v4.1._\\n */\\n function _useNonce(address owner) internal virtual returns (uint256 current) {\\n CountersUpgradeable.Counter storage nonce = _nonces[owner];\\n current = nonce.current();\\n nonce.increment();\\n }\\n\\n /**\\n * @dev This empty reserved space is put in place to allow future versions to add new\\n * variables without shifting down storage in the inheritance chain.\\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\\n */\\n uint256[49] private __gap;\\n}\\n\",\"keccak256\":\"0x564385ebed633694decce3e13d687f3ac7e8eaef64f7a504bfb3f03ad210601f\",\"license\":\"MIT\"},\"@openzeppelin/contracts-upgradeable/token/ERC20/extensions/draft-IERC20PermitUpgradeable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (token/ERC20/extensions/draft-IERC20Permit.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Interface of the ERC20 Permit extension allowing approvals to be made via signatures, as defined in\\n * https://eips.ethereum.org/EIPS/eip-2612[EIP-2612].\\n *\\n * Adds the {permit} method, which can be used to change an account's ERC20 allowance (see {IERC20-allowance}) by\\n * presenting a message signed by the account. By not relying on {IERC20-approve}, the token holder account doesn't\\n * need to send a transaction, and thus is not required to hold Ether at all.\\n */\\ninterface IERC20PermitUpgradeable {\\n /**\\n * @dev Sets `value` as the allowance of `spender` over ``owner``'s tokens,\\n * given ``owner``'s signed approval.\\n *\\n * IMPORTANT: The same issues {IERC20-approve} has related to transaction\\n * ordering also apply here.\\n *\\n * Emits an {Approval} event.\\n *\\n * Requirements:\\n *\\n * - `spender` cannot be the zero address.\\n * - `deadline` must be a timestamp in the future.\\n * - `v`, `r` and `s` must be a valid `secp256k1` signature from `owner`\\n * over the EIP712-formatted function arguments.\\n * - the signature must use ``owner``'s current nonce (see {nonces}).\\n *\\n * For more information on the signature format, see the\\n * https://eips.ethereum.org/EIPS/eip-2612#specification[relevant EIP\\n * section].\\n */\\n function permit(\\n address owner,\\n address spender,\\n uint256 value,\\n uint256 deadline,\\n uint8 v,\\n bytes32 r,\\n bytes32 s\\n ) external;\\n\\n /**\\n * @dev Returns the current nonce for `owner`. This value must be\\n * included whenever a signature is generated for {permit}.\\n *\\n * Every successful call to {permit} increases ``owner``'s nonce by one. This\\n * prevents a signature from being used multiple times.\\n */\\n function nonces(address owner) external view returns (uint256);\\n\\n /**\\n * @dev Returns the domain separator used in the encoding of the signature for {permit}, as defined by {EIP712}.\\n */\\n // solhint-disable-next-line func-name-mixedcase\\n function DOMAIN_SEPARATOR() external view returns (bytes32);\\n}\\n\",\"keccak256\":\"0xcc70d8e2281fb3ff69e8ab242500f10142cd0a7fa8dd9e45882be270d4d09024\",\"license\":\"MIT\"},\"@openzeppelin/contracts-upgradeable/utils/AddressUpgradeable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.7.0) (utils/Address.sol)\\n\\npragma solidity ^0.8.1;\\n\\n/**\\n * @dev Collection of functions related to the address type\\n */\\nlibrary AddressUpgradeable {\\n /**\\n * @dev Returns true if `account` is a contract.\\n *\\n * [IMPORTANT]\\n * ====\\n * It is unsafe to assume that an address for which this function returns\\n * false is an externally-owned account (EOA) and not a contract.\\n *\\n * Among others, `isContract` will return false for the following\\n * types of addresses:\\n *\\n * - an externally-owned account\\n * - a contract in construction\\n * - an address where a contract will be created\\n * - an address where a contract lived, but was destroyed\\n * ====\\n *\\n * [IMPORTANT]\\n * ====\\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\\n *\\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\\n * constructor.\\n * ====\\n */\\n function isContract(address account) internal view returns (bool) {\\n // This method relies on extcodesize/address.code.length, which returns 0\\n // for contracts in construction, since the code is only stored at the end\\n // of the constructor execution.\\n\\n return account.code.length > 0;\\n }\\n\\n /**\\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\\n * `recipient`, forwarding all available gas and reverting on errors.\\n *\\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\\n * imposed by `transfer`, making them unable to receive funds via\\n * `transfer`. {sendValue} removes this limitation.\\n *\\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\\n *\\n * IMPORTANT: because control is transferred to `recipient`, care must be\\n * taken to not create reentrancy vulnerabilities. Consider using\\n * {ReentrancyGuard} or the\\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\\n */\\n function sendValue(address payable recipient, uint256 amount) internal {\\n require(address(this).balance >= amount, \\\"Address: insufficient balance\\\");\\n\\n (bool success, ) = recipient.call{value: amount}(\\\"\\\");\\n require(success, \\\"Address: unable to send value, recipient may have reverted\\\");\\n }\\n\\n /**\\n * @dev Performs a Solidity function call using a low level `call`. A\\n * plain `call` is an unsafe replacement for a function call: use this\\n * function instead.\\n *\\n * If `target` reverts with a revert reason, it is bubbled up by this\\n * function (like regular Solidity function calls).\\n *\\n * Returns the raw returned data. To convert to the expected return value,\\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\\n *\\n * Requirements:\\n *\\n * - `target` must be a contract.\\n * - calling `target` with `data` must not revert.\\n *\\n * _Available since v3.1._\\n */\\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\\n return functionCall(target, data, \\\"Address: low-level call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\\n * `errorMessage` as a fallback revert reason when `target` reverts.\\n *\\n * _Available since v3.1._\\n */\\n function functionCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n return functionCallWithValue(target, data, 0, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but also transferring `value` wei to `target`.\\n *\\n * Requirements:\\n *\\n * - the calling contract must have an ETH balance of at least `value`.\\n * - the called Solidity function must be `payable`.\\n *\\n * _Available since v3.1._\\n */\\n function functionCallWithValue(\\n address target,\\n bytes memory data,\\n uint256 value\\n ) internal returns (bytes memory) {\\n return functionCallWithValue(target, data, value, \\\"Address: low-level call with value failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\\n * with `errorMessage` as a fallback revert reason when `target` reverts.\\n *\\n * _Available since v3.1._\\n */\\n function functionCallWithValue(\\n address target,\\n bytes memory data,\\n uint256 value,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n require(address(this).balance >= value, \\\"Address: insufficient balance for call\\\");\\n require(isContract(target), \\\"Address: call to non-contract\\\");\\n\\n (bool success, bytes memory returndata) = target.call{value: value}(data);\\n return verifyCallResult(success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but performing a static call.\\n *\\n * _Available since v3.3._\\n */\\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\\n return functionStaticCall(target, data, \\\"Address: low-level static call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\\n * but performing a static call.\\n *\\n * _Available since v3.3._\\n */\\n function functionStaticCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal view returns (bytes memory) {\\n require(isContract(target), \\\"Address: static call to non-contract\\\");\\n\\n (bool success, bytes memory returndata) = target.staticcall(data);\\n return verifyCallResult(success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the\\n * revert reason using the provided one.\\n *\\n * _Available since v4.3._\\n */\\n function verifyCallResult(\\n bool success,\\n bytes memory returndata,\\n string memory errorMessage\\n ) internal pure returns (bytes memory) {\\n if (success) {\\n return returndata;\\n } else {\\n // Look for revert reason and bubble it up if present\\n if (returndata.length > 0) {\\n // The easiest way to bubble the revert reason is using memory via assembly\\n /// @solidity memory-safe-assembly\\n assembly {\\n let returndata_size := mload(returndata)\\n revert(add(32, returndata), returndata_size)\\n }\\n } else {\\n revert(errorMessage);\\n }\\n }\\n }\\n}\\n\",\"keccak256\":\"0x611aa3f23e59cfdd1863c536776407b3e33d695152a266fa7cfb34440a29a8a3\",\"license\":\"MIT\"},\"@openzeppelin/contracts-upgradeable/utils/ContextUpgradeable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)\\n\\npragma solidity ^0.8.0;\\nimport \\\"../proxy/utils/Initializable.sol\\\";\\n\\n/**\\n * @dev Provides information about the current execution context, including the\\n * sender of the transaction and its data. While these are generally available\\n * via msg.sender and msg.data, they should not be accessed in such a direct\\n * manner, since when dealing with meta-transactions the account sending and\\n * paying for execution may not be the actual sender (as far as an application\\n * is concerned).\\n *\\n * This contract is only required for intermediate, library-like contracts.\\n */\\nabstract contract ContextUpgradeable is Initializable {\\n function __Context_init() internal onlyInitializing {\\n }\\n\\n function __Context_init_unchained() internal onlyInitializing {\\n }\\n function _msgSender() internal view virtual returns (address) {\\n return msg.sender;\\n }\\n\\n function _msgData() internal view virtual returns (bytes calldata) {\\n return msg.data;\\n }\\n\\n /**\\n * @dev This empty reserved space is put in place to allow future versions to add new\\n * variables without shifting down storage in the inheritance chain.\\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\\n */\\n uint256[50] private __gap;\\n}\\n\",\"keccak256\":\"0x963ea7f0b48b032eef72fe3a7582edf78408d6f834115b9feadd673a4d5bd149\",\"license\":\"MIT\"},\"@openzeppelin/contracts-upgradeable/utils/CountersUpgradeable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (utils/Counters.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @title Counters\\n * @author Matt Condon (@shrugs)\\n * @dev Provides counters that can only be incremented, decremented or reset. This can be used e.g. to track the number\\n * of elements in a mapping, issuing ERC721 ids, or counting request ids.\\n *\\n * Include with `using Counters for Counters.Counter;`\\n */\\nlibrary CountersUpgradeable {\\n struct Counter {\\n // This variable should never be directly accessed by users of the library: interactions must be restricted to\\n // the library's function. As of Solidity v0.5.2, this cannot be enforced, though there is a proposal to add\\n // this feature: see https://github.com/ethereum/solidity/issues/4637\\n uint256 _value; // default: 0\\n }\\n\\n function current(Counter storage counter) internal view returns (uint256) {\\n return counter._value;\\n }\\n\\n function increment(Counter storage counter) internal {\\n unchecked {\\n counter._value += 1;\\n }\\n }\\n\\n function decrement(Counter storage counter) internal {\\n uint256 value = counter._value;\\n require(value > 0, \\\"Counter: decrement overflow\\\");\\n unchecked {\\n counter._value = value - 1;\\n }\\n }\\n\\n function reset(Counter storage counter) internal {\\n counter._value = 0;\\n }\\n}\\n\",\"keccak256\":\"0x798741e231b22b81e2dd2eddaaf8832dee4baf5cd8e2dbaa5c1dd12a1c053c4d\",\"license\":\"MIT\"},\"@openzeppelin/contracts-upgradeable/utils/StringsUpgradeable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.7.0) (utils/Strings.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev String operations.\\n */\\nlibrary StringsUpgradeable {\\n bytes16 private constant _HEX_SYMBOLS = \\\"0123456789abcdef\\\";\\n uint8 private constant _ADDRESS_LENGTH = 20;\\n\\n /**\\n * @dev Converts a `uint256` to its ASCII `string` decimal representation.\\n */\\n function toString(uint256 value) internal pure returns (string memory) {\\n // Inspired by OraclizeAPI's implementation - MIT licence\\n // https://github.com/oraclize/ethereum-api/blob/b42146b063c7d6ee1358846c198246239e9360e8/oraclizeAPI_0.4.25.sol\\n\\n if (value == 0) {\\n return \\\"0\\\";\\n }\\n uint256 temp = value;\\n uint256 digits;\\n while (temp != 0) {\\n digits++;\\n temp /= 10;\\n }\\n bytes memory buffer = new bytes(digits);\\n while (value != 0) {\\n digits -= 1;\\n buffer[digits] = bytes1(uint8(48 + uint256(value % 10)));\\n value /= 10;\\n }\\n return string(buffer);\\n }\\n\\n /**\\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation.\\n */\\n function toHexString(uint256 value) internal pure returns (string memory) {\\n if (value == 0) {\\n return \\\"0x00\\\";\\n }\\n uint256 temp = value;\\n uint256 length = 0;\\n while (temp != 0) {\\n length++;\\n temp >>= 8;\\n }\\n return toHexString(value, length);\\n }\\n\\n /**\\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length.\\n */\\n function toHexString(uint256 value, uint256 length) internal pure returns (string memory) {\\n bytes memory buffer = new bytes(2 * length + 2);\\n buffer[0] = \\\"0\\\";\\n buffer[1] = \\\"x\\\";\\n for (uint256 i = 2 * length + 1; i > 1; --i) {\\n buffer[i] = _HEX_SYMBOLS[value & 0xf];\\n value >>= 4;\\n }\\n require(value == 0, \\\"Strings: hex length insufficient\\\");\\n return string(buffer);\\n }\\n\\n /**\\n * @dev Converts an `address` with fixed length of 20 bytes to its not checksummed ASCII `string` hexadecimal representation.\\n */\\n function toHexString(address addr) internal pure returns (string memory) {\\n return toHexString(uint256(uint160(addr)), _ADDRESS_LENGTH);\\n }\\n}\\n\",\"keccak256\":\"0xea5339a7fff0ed42b45be56a88efdd0b2ddde9fa480dc99fef9a6a4c5b776863\",\"license\":\"MIT\"},\"@openzeppelin/contracts-upgradeable/utils/cryptography/ECDSAUpgradeable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.7.0) (utils/cryptography/ECDSA.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../StringsUpgradeable.sol\\\";\\n\\n/**\\n * @dev Elliptic Curve Digital Signature Algorithm (ECDSA) operations.\\n *\\n * These functions can be used to verify that a message was signed by the holder\\n * of the private keys of a given address.\\n */\\nlibrary ECDSAUpgradeable {\\n enum RecoverError {\\n NoError,\\n InvalidSignature,\\n InvalidSignatureLength,\\n InvalidSignatureS,\\n InvalidSignatureV\\n }\\n\\n function _throwError(RecoverError error) private pure {\\n if (error == RecoverError.NoError) {\\n return; // no error: do nothing\\n } else if (error == RecoverError.InvalidSignature) {\\n revert(\\\"ECDSA: invalid signature\\\");\\n } else if (error == RecoverError.InvalidSignatureLength) {\\n revert(\\\"ECDSA: invalid signature length\\\");\\n } else if (error == RecoverError.InvalidSignatureS) {\\n revert(\\\"ECDSA: invalid signature 's' value\\\");\\n } else if (error == RecoverError.InvalidSignatureV) {\\n revert(\\\"ECDSA: invalid signature 'v' value\\\");\\n }\\n }\\n\\n /**\\n * @dev Returns the address that signed a hashed message (`hash`) with\\n * `signature` or error string. This address can then be used for verification purposes.\\n *\\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\\n * this function rejects them by requiring the `s` value to be in the lower\\n * half order, and the `v` value to be either 27 or 28.\\n *\\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\\n * verification to be secure: it is possible to craft signatures that\\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\\n * this is by receiving a hash of the original message (which may otherwise\\n * be too long), and then calling {toEthSignedMessageHash} on it.\\n *\\n * Documentation for signature generation:\\n * - with https://web3js.readthedocs.io/en/v1.3.4/web3-eth-accounts.html#sign[Web3.js]\\n * - with https://docs.ethers.io/v5/api/signer/#Signer-signMessage[ethers]\\n *\\n * _Available since v4.3._\\n */\\n function tryRecover(bytes32 hash, bytes memory signature) internal pure returns (address, RecoverError) {\\n // Check the signature length\\n // - case 65: r,s,v signature (standard)\\n // - case 64: r,vs signature (cf https://eips.ethereum.org/EIPS/eip-2098) _Available since v4.1._\\n if (signature.length == 65) {\\n bytes32 r;\\n bytes32 s;\\n uint8 v;\\n // ecrecover takes the signature parameters, and the only way to get them\\n // currently is to use assembly.\\n /// @solidity memory-safe-assembly\\n assembly {\\n r := mload(add(signature, 0x20))\\n s := mload(add(signature, 0x40))\\n v := byte(0, mload(add(signature, 0x60)))\\n }\\n return tryRecover(hash, v, r, s);\\n } else if (signature.length == 64) {\\n bytes32 r;\\n bytes32 vs;\\n // ecrecover takes the signature parameters, and the only way to get them\\n // currently is to use assembly.\\n /// @solidity memory-safe-assembly\\n assembly {\\n r := mload(add(signature, 0x20))\\n vs := mload(add(signature, 0x40))\\n }\\n return tryRecover(hash, r, vs);\\n } else {\\n return (address(0), RecoverError.InvalidSignatureLength);\\n }\\n }\\n\\n /**\\n * @dev Returns the address that signed a hashed message (`hash`) with\\n * `signature`. This address can then be used for verification purposes.\\n *\\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\\n * this function rejects them by requiring the `s` value to be in the lower\\n * half order, and the `v` value to be either 27 or 28.\\n *\\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\\n * verification to be secure: it is possible to craft signatures that\\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\\n * this is by receiving a hash of the original message (which may otherwise\\n * be too long), and then calling {toEthSignedMessageHash} on it.\\n */\\n function recover(bytes32 hash, bytes memory signature) internal pure returns (address) {\\n (address recovered, RecoverError error) = tryRecover(hash, signature);\\n _throwError(error);\\n return recovered;\\n }\\n\\n /**\\n * @dev Overload of {ECDSA-tryRecover} that receives the `r` and `vs` short-signature fields separately.\\n *\\n * See https://eips.ethereum.org/EIPS/eip-2098[EIP-2098 short signatures]\\n *\\n * _Available since v4.3._\\n */\\n function tryRecover(\\n bytes32 hash,\\n bytes32 r,\\n bytes32 vs\\n ) internal pure returns (address, RecoverError) {\\n bytes32 s = vs & bytes32(0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff);\\n uint8 v = uint8((uint256(vs) >> 255) + 27);\\n return tryRecover(hash, v, r, s);\\n }\\n\\n /**\\n * @dev Overload of {ECDSA-recover} that receives the `r and `vs` short-signature fields separately.\\n *\\n * _Available since v4.2._\\n */\\n function recover(\\n bytes32 hash,\\n bytes32 r,\\n bytes32 vs\\n ) internal pure returns (address) {\\n (address recovered, RecoverError error) = tryRecover(hash, r, vs);\\n _throwError(error);\\n return recovered;\\n }\\n\\n /**\\n * @dev Overload of {ECDSA-tryRecover} that receives the `v`,\\n * `r` and `s` signature fields separately.\\n *\\n * _Available since v4.3._\\n */\\n function tryRecover(\\n bytes32 hash,\\n uint8 v,\\n bytes32 r,\\n bytes32 s\\n ) internal pure returns (address, RecoverError) {\\n // EIP-2 still allows signature malleability for ecrecover(). Remove this possibility and make the signature\\n // unique. Appendix F in the Ethereum Yellow paper (https://ethereum.github.io/yellowpaper/paper.pdf), defines\\n // the valid range for s in (301): 0 < s < secp256k1n \\u00f7 2 + 1, and for v in (302): v \\u2208 {27, 28}. Most\\n // signatures from current libraries generate a unique signature with an s-value in the lower half order.\\n //\\n // If your library generates malleable signatures, such as s-values in the upper range, calculate a new s-value\\n // with 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141 - s1 and flip v from 27 to 28 or\\n // vice versa. If your library also generates signatures with 0/1 for v instead 27/28, add 27 to v to accept\\n // these malleable signatures as well.\\n if (uint256(s) > 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D576E7357A4501DDFE92F46681B20A0) {\\n return (address(0), RecoverError.InvalidSignatureS);\\n }\\n if (v != 27 && v != 28) {\\n return (address(0), RecoverError.InvalidSignatureV);\\n }\\n\\n // If the signature is valid (and not malleable), return the signer address\\n address signer = ecrecover(hash, v, r, s);\\n if (signer == address(0)) {\\n return (address(0), RecoverError.InvalidSignature);\\n }\\n\\n return (signer, RecoverError.NoError);\\n }\\n\\n /**\\n * @dev Overload of {ECDSA-recover} that receives the `v`,\\n * `r` and `s` signature fields separately.\\n */\\n function recover(\\n bytes32 hash,\\n uint8 v,\\n bytes32 r,\\n bytes32 s\\n ) internal pure returns (address) {\\n (address recovered, RecoverError error) = tryRecover(hash, v, r, s);\\n _throwError(error);\\n return recovered;\\n }\\n\\n /**\\n * @dev Returns an Ethereum Signed Message, created from a `hash`. This\\n * produces hash corresponding to the one signed with the\\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\\n * JSON-RPC method as part of EIP-191.\\n *\\n * See {recover}.\\n */\\n function toEthSignedMessageHash(bytes32 hash) internal pure returns (bytes32) {\\n // 32 is the length in bytes of hash,\\n // enforced by the type signature above\\n return keccak256(abi.encodePacked(\\\"\\\\x19Ethereum Signed Message:\\\\n32\\\", hash));\\n }\\n\\n /**\\n * @dev Returns an Ethereum Signed Message, created from `s`. This\\n * produces hash corresponding to the one signed with the\\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\\n * JSON-RPC method as part of EIP-191.\\n *\\n * See {recover}.\\n */\\n function toEthSignedMessageHash(bytes memory s) internal pure returns (bytes32) {\\n return keccak256(abi.encodePacked(\\\"\\\\x19Ethereum Signed Message:\\\\n\\\", StringsUpgradeable.toString(s.length), s));\\n }\\n\\n /**\\n * @dev Returns an Ethereum Signed Typed Data, created from a\\n * `domainSeparator` and a `structHash`. This produces hash corresponding\\n * to the one signed with the\\n * https://eips.ethereum.org/EIPS/eip-712[`eth_signTypedData`]\\n * JSON-RPC method as part of EIP-712.\\n *\\n * See {recover}.\\n */\\n function toTypedDataHash(bytes32 domainSeparator, bytes32 structHash) internal pure returns (bytes32) {\\n return keccak256(abi.encodePacked(\\\"\\\\x19\\\\x01\\\", domainSeparator, structHash));\\n }\\n}\\n\",\"keccak256\":\"0xe8c62ca00ed2d0a4d9b7e3c4bf7d62c821618b2cdb3c844da91a1193986851bf\",\"license\":\"MIT\"},\"@openzeppelin/contracts-upgradeable/utils/cryptography/draft-EIP712Upgradeable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (utils/cryptography/draft-EIP712.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"./ECDSAUpgradeable.sol\\\";\\nimport \\\"../../proxy/utils/Initializable.sol\\\";\\n\\n/**\\n * @dev https://eips.ethereum.org/EIPS/eip-712[EIP 712] is a standard for hashing and signing of typed structured data.\\n *\\n * The encoding specified in the EIP is very generic, and such a generic implementation in Solidity is not feasible,\\n * thus this contract does not implement the encoding itself. Protocols need to implement the type-specific encoding\\n * they need in their contracts using a combination of `abi.encode` and `keccak256`.\\n *\\n * This contract implements the EIP 712 domain separator ({_domainSeparatorV4}) that is used as part of the encoding\\n * scheme, and the final step of the encoding to obtain the message digest that is then signed via ECDSA\\n * ({_hashTypedDataV4}).\\n *\\n * The implementation of the domain separator was designed to be as efficient as possible while still properly updating\\n * the chain id to protect against replay attacks on an eventual fork of the chain.\\n *\\n * NOTE: This contract implements the version of the encoding known as \\\"v4\\\", as implemented by the JSON RPC method\\n * https://docs.metamask.io/guide/signing-data.html[`eth_signTypedDataV4` in MetaMask].\\n *\\n * _Available since v3.4._\\n *\\n * @custom:storage-size 52\\n */\\nabstract contract EIP712Upgradeable is Initializable {\\n /* solhint-disable var-name-mixedcase */\\n bytes32 private _HASHED_NAME;\\n bytes32 private _HASHED_VERSION;\\n bytes32 private constant _TYPE_HASH = keccak256(\\\"EIP712Domain(string name,string version,uint256 chainId,address verifyingContract)\\\");\\n\\n /* solhint-enable var-name-mixedcase */\\n\\n /**\\n * @dev Initializes the domain separator and parameter caches.\\n *\\n * The meaning of `name` and `version` is specified in\\n * https://eips.ethereum.org/EIPS/eip-712#definition-of-domainseparator[EIP 712]:\\n *\\n * - `name`: the user readable name of the signing domain, i.e. the name of the DApp or the protocol.\\n * - `version`: the current major version of the signing domain.\\n *\\n * NOTE: These parameters cannot be changed except through a xref:learn::upgrading-smart-contracts.adoc[smart\\n * contract upgrade].\\n */\\n function __EIP712_init(string memory name, string memory version) internal onlyInitializing {\\n __EIP712_init_unchained(name, version);\\n }\\n\\n function __EIP712_init_unchained(string memory name, string memory version) internal onlyInitializing {\\n bytes32 hashedName = keccak256(bytes(name));\\n bytes32 hashedVersion = keccak256(bytes(version));\\n _HASHED_NAME = hashedName;\\n _HASHED_VERSION = hashedVersion;\\n }\\n\\n /**\\n * @dev Returns the domain separator for the current chain.\\n */\\n function _domainSeparatorV4() internal view returns (bytes32) {\\n return _buildDomainSeparator(_TYPE_HASH, _EIP712NameHash(), _EIP712VersionHash());\\n }\\n\\n function _buildDomainSeparator(\\n bytes32 typeHash,\\n bytes32 nameHash,\\n bytes32 versionHash\\n ) private view returns (bytes32) {\\n return keccak256(abi.encode(typeHash, nameHash, versionHash, block.chainid, address(this)));\\n }\\n\\n /**\\n * @dev Given an already https://eips.ethereum.org/EIPS/eip-712#definition-of-hashstruct[hashed struct], this\\n * function returns the hash of the fully encoded EIP712 message for this domain.\\n *\\n * This hash can be used together with {ECDSA-recover} to obtain the signer of a message. For example:\\n *\\n * ```solidity\\n * bytes32 digest = _hashTypedDataV4(keccak256(abi.encode(\\n * keccak256(\\\"Mail(address to,string contents)\\\"),\\n * mailTo,\\n * keccak256(bytes(mailContents))\\n * )));\\n * address signer = ECDSA.recover(digest, signature);\\n * ```\\n */\\n function _hashTypedDataV4(bytes32 structHash) internal view virtual returns (bytes32) {\\n return ECDSAUpgradeable.toTypedDataHash(_domainSeparatorV4(), structHash);\\n }\\n\\n /**\\n * @dev The hash of the name parameter for the EIP712 domain.\\n *\\n * NOTE: This function reads from storage by default, but can be redefined to return a constant value if gas costs\\n * are a concern.\\n */\\n function _EIP712NameHash() internal virtual view returns (bytes32) {\\n return _HASHED_NAME;\\n }\\n\\n /**\\n * @dev The hash of the version parameter for the EIP712 domain.\\n *\\n * NOTE: This function reads from storage by default, but can be redefined to return a constant value if gas costs\\n * are a concern.\\n */\\n function _EIP712VersionHash() internal virtual view returns (bytes32) {\\n return _HASHED_VERSION;\\n }\\n\\n /**\\n * @dev This empty reserved space is put in place to allow future versions to add new\\n * variables without shifting down storage in the inheritance chain.\\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\\n */\\n uint256[50] private __gap;\\n}\\n\",\"keccak256\":\"0xaf5a96100f421d61693605349511e43221d3c2e47d4b3efa87af2b936e2567fc\",\"license\":\"MIT\"},\"@openzeppelin/contracts/token/ERC20/IERC20.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.6.0) (token/ERC20/IERC20.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Interface of the ERC20 standard as defined in the EIP.\\n */\\ninterface IERC20 {\\n /**\\n * @dev Emitted when `value` tokens are moved from one account (`from`) to\\n * another (`to`).\\n *\\n * Note that `value` may be zero.\\n */\\n event Transfer(address indexed from, address indexed to, uint256 value);\\n\\n /**\\n * @dev Emitted when the allowance of a `spender` for an `owner` is set by\\n * a call to {approve}. `value` is the new allowance.\\n */\\n event Approval(address indexed owner, address indexed spender, uint256 value);\\n\\n /**\\n * @dev Returns the amount of tokens in existence.\\n */\\n function totalSupply() external view returns (uint256);\\n\\n /**\\n * @dev Returns the amount of tokens owned by `account`.\\n */\\n function balanceOf(address account) external view returns (uint256);\\n\\n /**\\n * @dev Moves `amount` tokens from the caller's account to `to`.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * Emits a {Transfer} event.\\n */\\n function transfer(address to, uint256 amount) external returns (bool);\\n\\n /**\\n * @dev Returns the remaining number of tokens that `spender` will be\\n * allowed to spend on behalf of `owner` through {transferFrom}. This is\\n * zero by default.\\n *\\n * This value changes when {approve} or {transferFrom} are called.\\n */\\n function allowance(address owner, address spender) external view returns (uint256);\\n\\n /**\\n * @dev Sets `amount` as the allowance of `spender` over the caller's tokens.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * IMPORTANT: Beware that changing an allowance with this method brings the risk\\n * that someone may use both the old and the new allowance by unfortunate\\n * transaction ordering. One possible solution to mitigate this race\\n * condition is to first reduce the spender's allowance to 0 and set the\\n * desired value afterwards:\\n * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729\\n *\\n * Emits an {Approval} event.\\n */\\n function approve(address spender, uint256 amount) external returns (bool);\\n\\n /**\\n * @dev Moves `amount` tokens from `from` to `to` using the\\n * allowance mechanism. `amount` is then deducted from the caller's\\n * allowance.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * Emits a {Transfer} event.\\n */\\n function transferFrom(\\n address from,\\n address to,\\n uint256 amount\\n ) external returns (bool);\\n}\\n\",\"keccak256\":\"0x9750c6b834f7b43000631af5cc30001c5f547b3ceb3635488f140f60e897ea6b\",\"license\":\"MIT\"},\"@openzeppelin/contracts/token/ERC20/extensions/draft-IERC20Permit.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (token/ERC20/extensions/draft-IERC20Permit.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Interface of the ERC20 Permit extension allowing approvals to be made via signatures, as defined in\\n * https://eips.ethereum.org/EIPS/eip-2612[EIP-2612].\\n *\\n * Adds the {permit} method, which can be used to change an account's ERC20 allowance (see {IERC20-allowance}) by\\n * presenting a message signed by the account. By not relying on {IERC20-approve}, the token holder account doesn't\\n * need to send a transaction, and thus is not required to hold Ether at all.\\n */\\ninterface IERC20Permit {\\n /**\\n * @dev Sets `value` as the allowance of `spender` over ``owner``'s tokens,\\n * given ``owner``'s signed approval.\\n *\\n * IMPORTANT: The same issues {IERC20-approve} has related to transaction\\n * ordering also apply here.\\n *\\n * Emits an {Approval} event.\\n *\\n * Requirements:\\n *\\n * - `spender` cannot be the zero address.\\n * - `deadline` must be a timestamp in the future.\\n * - `v`, `r` and `s` must be a valid `secp256k1` signature from `owner`\\n * over the EIP712-formatted function arguments.\\n * - the signature must use ``owner``'s current nonce (see {nonces}).\\n *\\n * For more information on the signature format, see the\\n * https://eips.ethereum.org/EIPS/eip-2612#specification[relevant EIP\\n * section].\\n */\\n function permit(\\n address owner,\\n address spender,\\n uint256 value,\\n uint256 deadline,\\n uint8 v,\\n bytes32 r,\\n bytes32 s\\n ) external;\\n\\n /**\\n * @dev Returns the current nonce for `owner`. This value must be\\n * included whenever a signature is generated for {permit}.\\n *\\n * Every successful call to {permit} increases ``owner``'s nonce by one. This\\n * prevents a signature from being used multiple times.\\n */\\n function nonces(address owner) external view returns (uint256);\\n\\n /**\\n * @dev Returns the domain separator used in the encoding of the signature for {permit}, as defined by {EIP712}.\\n */\\n // solhint-disable-next-line func-name-mixedcase\\n function DOMAIN_SEPARATOR() external view returns (bytes32);\\n}\\n\",\"keccak256\":\"0xf41ca991f30855bf80ffd11e9347856a517b977f0a6c2d52e6421a99b7840329\",\"license\":\"MIT\"},\"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.7.0) (token/ERC20/utils/SafeERC20.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../IERC20.sol\\\";\\nimport \\\"../extensions/draft-IERC20Permit.sol\\\";\\nimport \\\"../../../utils/Address.sol\\\";\\n\\n/**\\n * @title SafeERC20\\n * @dev Wrappers around ERC20 operations that throw on failure (when the token\\n * contract returns false). Tokens that return no value (and instead revert or\\n * throw on failure) are also supported, non-reverting calls are assumed to be\\n * successful.\\n * To use this library you can add a `using SafeERC20 for IERC20;` statement to your contract,\\n * which allows you to call the safe operations as `token.safeTransfer(...)`, etc.\\n */\\nlibrary SafeERC20 {\\n using Address for address;\\n\\n function safeTransfer(\\n IERC20 token,\\n address to,\\n uint256 value\\n ) internal {\\n _callOptionalReturn(token, abi.encodeWithSelector(token.transfer.selector, to, value));\\n }\\n\\n function safeTransferFrom(\\n IERC20 token,\\n address from,\\n address to,\\n uint256 value\\n ) internal {\\n _callOptionalReturn(token, abi.encodeWithSelector(token.transferFrom.selector, from, to, value));\\n }\\n\\n /**\\n * @dev Deprecated. This function has issues similar to the ones found in\\n * {IERC20-approve}, and its usage is discouraged.\\n *\\n * Whenever possible, use {safeIncreaseAllowance} and\\n * {safeDecreaseAllowance} instead.\\n */\\n function safeApprove(\\n IERC20 token,\\n address spender,\\n uint256 value\\n ) internal {\\n // safeApprove should only be called when setting an initial allowance,\\n // or when resetting it to zero. To increase and decrease it, use\\n // 'safeIncreaseAllowance' and 'safeDecreaseAllowance'\\n require(\\n (value == 0) || (token.allowance(address(this), spender) == 0),\\n \\\"SafeERC20: approve from non-zero to non-zero allowance\\\"\\n );\\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, value));\\n }\\n\\n function safeIncreaseAllowance(\\n IERC20 token,\\n address spender,\\n uint256 value\\n ) internal {\\n uint256 newAllowance = token.allowance(address(this), spender) + value;\\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));\\n }\\n\\n function safeDecreaseAllowance(\\n IERC20 token,\\n address spender,\\n uint256 value\\n ) internal {\\n unchecked {\\n uint256 oldAllowance = token.allowance(address(this), spender);\\n require(oldAllowance >= value, \\\"SafeERC20: decreased allowance below zero\\\");\\n uint256 newAllowance = oldAllowance - value;\\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));\\n }\\n }\\n\\n function safePermit(\\n IERC20Permit token,\\n address owner,\\n address spender,\\n uint256 value,\\n uint256 deadline,\\n uint8 v,\\n bytes32 r,\\n bytes32 s\\n ) internal {\\n uint256 nonceBefore = token.nonces(owner);\\n token.permit(owner, spender, value, deadline, v, r, s);\\n uint256 nonceAfter = token.nonces(owner);\\n require(nonceAfter == nonceBefore + 1, \\\"SafeERC20: permit did not succeed\\\");\\n }\\n\\n /**\\n * @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement\\n * on the return value: the return value is optional (but if data is returned, it must not be false).\\n * @param token The token targeted by the call.\\n * @param data The call data (encoded using abi.encode or one of its variants).\\n */\\n function _callOptionalReturn(IERC20 token, bytes memory data) private {\\n // We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since\\n // we're implementing it ourselves. We use {Address.functionCall} to perform this call, which verifies that\\n // the target address contains contract code and also asserts for success in the low-level call.\\n\\n bytes memory returndata = address(token).functionCall(data, \\\"SafeERC20: low-level call failed\\\");\\n if (returndata.length > 0) {\\n // Return data is optional\\n require(abi.decode(returndata, (bool)), \\\"SafeERC20: ERC20 operation did not succeed\\\");\\n }\\n }\\n}\\n\",\"keccak256\":\"0x032807210d1d7d218963d7355d62e021a84bf1b3339f4f50be2f63b53cccaf29\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/Address.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.7.0) (utils/Address.sol)\\n\\npragma solidity ^0.8.1;\\n\\n/**\\n * @dev Collection of functions related to the address type\\n */\\nlibrary Address {\\n /**\\n * @dev Returns true if `account` is a contract.\\n *\\n * [IMPORTANT]\\n * ====\\n * It is unsafe to assume that an address for which this function returns\\n * false is an externally-owned account (EOA) and not a contract.\\n *\\n * Among others, `isContract` will return false for the following\\n * types of addresses:\\n *\\n * - an externally-owned account\\n * - a contract in construction\\n * - an address where a contract will be created\\n * - an address where a contract lived, but was destroyed\\n * ====\\n *\\n * [IMPORTANT]\\n * ====\\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\\n *\\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\\n * constructor.\\n * ====\\n */\\n function isContract(address account) internal view returns (bool) {\\n // This method relies on extcodesize/address.code.length, which returns 0\\n // for contracts in construction, since the code is only stored at the end\\n // of the constructor execution.\\n\\n return account.code.length > 0;\\n }\\n\\n /**\\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\\n * `recipient`, forwarding all available gas and reverting on errors.\\n *\\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\\n * imposed by `transfer`, making them unable to receive funds via\\n * `transfer`. {sendValue} removes this limitation.\\n *\\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\\n *\\n * IMPORTANT: because control is transferred to `recipient`, care must be\\n * taken to not create reentrancy vulnerabilities. Consider using\\n * {ReentrancyGuard} or the\\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\\n */\\n function sendValue(address payable recipient, uint256 amount) internal {\\n require(address(this).balance >= amount, \\\"Address: insufficient balance\\\");\\n\\n (bool success, ) = recipient.call{value: amount}(\\\"\\\");\\n require(success, \\\"Address: unable to send value, recipient may have reverted\\\");\\n }\\n\\n /**\\n * @dev Performs a Solidity function call using a low level `call`. A\\n * plain `call` is an unsafe replacement for a function call: use this\\n * function instead.\\n *\\n * If `target` reverts with a revert reason, it is bubbled up by this\\n * function (like regular Solidity function calls).\\n *\\n * Returns the raw returned data. To convert to the expected return value,\\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\\n *\\n * Requirements:\\n *\\n * - `target` must be a contract.\\n * - calling `target` with `data` must not revert.\\n *\\n * _Available since v3.1._\\n */\\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\\n return functionCall(target, data, \\\"Address: low-level call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\\n * `errorMessage` as a fallback revert reason when `target` reverts.\\n *\\n * _Available since v3.1._\\n */\\n function functionCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n return functionCallWithValue(target, data, 0, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but also transferring `value` wei to `target`.\\n *\\n * Requirements:\\n *\\n * - the calling contract must have an ETH balance of at least `value`.\\n * - the called Solidity function must be `payable`.\\n *\\n * _Available since v3.1._\\n */\\n function functionCallWithValue(\\n address target,\\n bytes memory data,\\n uint256 value\\n ) internal returns (bytes memory) {\\n return functionCallWithValue(target, data, value, \\\"Address: low-level call with value failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\\n * with `errorMessage` as a fallback revert reason when `target` reverts.\\n *\\n * _Available since v3.1._\\n */\\n function functionCallWithValue(\\n address target,\\n bytes memory data,\\n uint256 value,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n require(address(this).balance >= value, \\\"Address: insufficient balance for call\\\");\\n require(isContract(target), \\\"Address: call to non-contract\\\");\\n\\n (bool success, bytes memory returndata) = target.call{value: value}(data);\\n return verifyCallResult(success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but performing a static call.\\n *\\n * _Available since v3.3._\\n */\\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\\n return functionStaticCall(target, data, \\\"Address: low-level static call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\\n * but performing a static call.\\n *\\n * _Available since v3.3._\\n */\\n function functionStaticCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal view returns (bytes memory) {\\n require(isContract(target), \\\"Address: static call to non-contract\\\");\\n\\n (bool success, bytes memory returndata) = target.staticcall(data);\\n return verifyCallResult(success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but performing a delegate call.\\n *\\n * _Available since v3.4._\\n */\\n function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {\\n return functionDelegateCall(target, data, \\\"Address: low-level delegate call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\\n * but performing a delegate call.\\n *\\n * _Available since v3.4._\\n */\\n function functionDelegateCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n require(isContract(target), \\\"Address: delegate call to non-contract\\\");\\n\\n (bool success, bytes memory returndata) = target.delegatecall(data);\\n return verifyCallResult(success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the\\n * revert reason using the provided one.\\n *\\n * _Available since v4.3._\\n */\\n function verifyCallResult(\\n bool success,\\n bytes memory returndata,\\n string memory errorMessage\\n ) internal pure returns (bytes memory) {\\n if (success) {\\n return returndata;\\n } else {\\n // Look for revert reason and bubble it up if present\\n if (returndata.length > 0) {\\n // The easiest way to bubble the revert reason is using memory via assembly\\n /// @solidity memory-safe-assembly\\n assembly {\\n let returndata_size := mload(returndata)\\n revert(add(32, returndata), returndata_size)\\n }\\n } else {\\n revert(errorMessage);\\n }\\n }\\n }\\n}\\n\",\"keccak256\":\"0xd6153ce99bcdcce22b124f755e72553295be6abcd63804cfdffceb188b8bef10\",\"license\":\"MIT\"},\"contracts/agToken/AgToken.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-3.0\\n\\npragma solidity ^0.8.12;\\n\\n/*\\n * \\u2588 \\n ***** \\u2593\\u2593\\u2593 \\n * \\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593 \\n * ///. \\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593 \\n ***** //////// \\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593 \\n * ///////////// \\u2593\\u2593\\u2593 \\n \\u2593\\u2593 ////////////////// \\u2588 \\u2593\\u2593 \\n \\u2593\\u2593 \\u2593\\u2593 /////////////////////// \\u2593\\u2593 \\u2593\\u2593 \\n \\u2593\\u2593 \\u2593\\u2593 //////////////////////////// \\u2593\\u2593 \\u2593\\u2593 \\n \\u2593\\u2593 \\u2593\\u2593 /////////\\u2593\\u2593\\u2593///////\\u2593\\u2593\\u2593///////// \\u2593\\u2593 \\u2593\\u2593 \\n \\u2593\\u2593 ,////////////////////////////////////// \\u2593\\u2593 \\u2593\\u2593 \\n \\u2593\\u2593 ////////////////////////////////////////// \\u2593\\u2593 \\n \\u2593\\u2593 //////////////////////\\u2593\\u2593\\u2593\\u2593///////////////////// \\n ,//////////////////////////////////////////////////// \\n .////////////////////////////////////////////////////////// \\n .//////////////////////////\\u2588\\u2588.,//////////////////////////\\u2588 \\n .//////////////////////\\u2588\\u2588\\u2588\\u2588..,./////////////////////\\u2588\\u2588 \\n ...////////////////\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588.....,.////////////////\\u2588\\u2588\\u2588 \\n ,.,////////////\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588 ........,///////////\\u2588\\u2588\\u2588\\u2588 \\n .,.,//////\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588 ,.......///////\\u2588\\u2588\\u2588\\u2588 \\n ,..//\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588 ........./\\u2588\\u2588\\u2588\\u2588 \\n ..,\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588 .....,\\u2588\\u2588\\u2588 \\n .\\u2588\\u2588 ,.,\\u2588 \\n \\n \\n \\n \\u2593\\u2593 \\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593 \\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593 \\u2593\\u2593 \\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593 \\n \\u2593\\u2593\\u2593\\u2593\\u2593\\u2593 \\u2593\\u2593\\u2593 \\u2593\\u2593\\u2593 \\u2593\\u2593\\u2593 \\u2593\\u2593 \\u2593\\u2593 \\u2593\\u2593\\u2593\\u2593 \\n \\u2593\\u2593\\u2593 \\u2593\\u2593\\u2593 \\u2593\\u2593\\u2593 \\u2593\\u2593\\u2593 \\u2593\\u2593\\u2593 \\u2593\\u2593\\u2593 \\u2593\\u2593 \\u2593\\u2593\\u2593\\u2593\\u2593 \\n \\u2593\\u2593\\u2593 \\u2593\\u2593 \\u2593\\u2593\\u2593 \\u2593\\u2593\\u2593 \\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593 \\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593 \\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593 \\n*/\\n\\nimport \\\"../interfaces/IAgToken.sol\\\";\\nimport \\\"../interfaces/ITreasury.sol\\\";\\nimport \\\"@openzeppelin/contracts-upgradeable/token/ERC20/extensions/draft-ERC20PermitUpgradeable.sol\\\";\\n\\n/// @title AgToken\\n/// @author Angle Labs, Inc.\\n/// @notice Base contract for Angle agTokens on Ethereum and on other chains\\n/// @dev By default, agTokens are ERC-20 tokens with 18 decimals\\ncontract AgToken is IAgToken, ERC20PermitUpgradeable {\\n // =========================== PARAMETERS / VARIABLES ==========================\\n\\n /// @inheritdoc IAgToken\\n mapping(address => bool) public isMinter;\\n /// @notice Reference to the treasury contract which can grant minting rights\\n address public treasury;\\n\\n // =================================== EVENTS ==================================\\n\\n event TreasuryUpdated(address indexed _treasury);\\n event MinterToggled(address indexed minter);\\n\\n // =================================== ERRORS ==================================\\n\\n error BurnAmountExceedsAllowance();\\n error InvalidSender();\\n error InvalidTreasury();\\n error NotMinter();\\n error NotTreasury();\\n\\n // ================================ CONSTRUCTOR ================================\\n\\n /// @custom:oz-upgrades-unsafe-allow constructor\\n constructor() initializer {}\\n\\n /// @notice Initializes the `AgToken` contract\\n function initialize(string memory name_, string memory symbol_, address _treasury) external {\\n _initialize(name_, symbol_, _treasury);\\n }\\n\\n /// @notice Initializes the contract\\n function _initialize(string memory name_, string memory symbol_, address _treasury) internal virtual initializer {\\n if (address(ITreasury(_treasury).stablecoin()) != address(this)) revert InvalidTreasury();\\n __ERC20Permit_init(name_);\\n __ERC20_init(name_, symbol_);\\n treasury = _treasury;\\n emit TreasuryUpdated(_treasury);\\n }\\n\\n // ================================= MODIFIERS =================================\\n\\n /// @notice Checks to see if it is the `Treasury` calling this contract\\n modifier onlyTreasury() {\\n if (msg.sender != treasury) revert NotTreasury();\\n _;\\n }\\n\\n /// @notice Checks whether the sender has the minting right\\n modifier onlyMinter() {\\n if (!isMinter[msg.sender]) revert NotMinter();\\n _;\\n }\\n\\n // ============================= EXTERNAL FUNCTION =============================\\n\\n /// @notice Allows anyone to burn stablecoins\\n /// @param amount Amount of stablecoins to burn\\n /// @dev This function can typically be called if there is a settlement mechanism to burn stablecoins\\n function burnStablecoin(uint256 amount) external {\\n _burn(msg.sender, amount);\\n }\\n\\n // ========================= MINTER ROLE ONLY FUNCTIONS ========================\\n\\n /// @inheritdoc IAgToken\\n function burnSelf(uint256 amount, address burner) external onlyMinter {\\n _burn(burner, amount);\\n }\\n\\n /// @inheritdoc IAgToken\\n function burnFrom(uint256 amount, address burner, address sender) external onlyMinter {\\n if (burner != sender) {\\n uint256 currentAllowance = allowance(burner, sender);\\n if (currentAllowance < amount) revert BurnAmountExceedsAllowance();\\n _approve(burner, sender, currentAllowance - amount);\\n }\\n _burn(burner, amount);\\n }\\n\\n /// @inheritdoc IAgToken\\n function mint(address account, uint256 amount) external onlyMinter {\\n _mint(account, amount);\\n }\\n\\n // ========================== GOVERNANCE ONLY FUNCTIONS ==========================\\n\\n /// @inheritdoc IAgToken\\n function addMinter(address minter) external onlyTreasury {\\n isMinter[minter] = true;\\n emit MinterToggled(minter);\\n }\\n\\n /// @inheritdoc IAgToken\\n function removeMinter(address minter) external {\\n if (msg.sender != address(treasury) && msg.sender != minter) revert InvalidSender();\\n isMinter[minter] = false;\\n emit MinterToggled(minter);\\n }\\n\\n /// @inheritdoc IAgToken\\n function setTreasury(address _treasury) external virtual onlyTreasury {\\n treasury = _treasury;\\n emit TreasuryUpdated(_treasury);\\n }\\n}\\n\",\"keccak256\":\"0x671d54d7840179050e859cf09662fe0e2c34cfaf5ec3782148d6c29e77c54d17\",\"license\":\"GPL-3.0\"},\"contracts/agToken/AgTokenSideChainMultiBridge.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-3.0\\n\\npragma solidity ^0.8.12;\\n\\nimport \\\"./AgToken.sol\\\";\\nimport \\\"@openzeppelin/contracts/token/ERC20/IERC20.sol\\\";\\nimport \\\"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\\\";\\n\\n/// @title AgTokenSideChainMultiBridge\\n/// @author Angle Labs, Inc.\\n/// @notice Contract for Angle agTokens on other chains than Ethereum mainnet\\n/// @dev This contract supports bridge tokens having a minting right on the stablecoin (also referred to as the canonical\\n/// or the native token)\\ncontract AgTokenSideChainMultiBridge is AgToken {\\n using SafeERC20 for IERC20;\\n\\n /// @notice Base used for fee computation\\n uint256 public constant BASE_PARAMS = 1e9;\\n\\n // =============================== BRIDGING DATA ===============================\\n\\n /// @notice Struct with some data about a specific bridge token\\n struct BridgeDetails {\\n // Limit on the balance of bridge token held by the contract: it is designed\\n // to reduce the exposure of the system to hacks\\n uint256 limit;\\n // Limit on the hourly volume of token minted through this bridge\\n // Technically the limit over a rolling hour is hourlyLimit x2 as hourly limit\\n // is enforced only between x:00 and x+1:00\\n uint256 hourlyLimit;\\n // Fee taken for swapping in and out the token\\n uint64 fee;\\n // Whether the associated token is allowed or not\\n bool allowed;\\n // Whether swapping in and out from the associated token is paused or not\\n bool paused;\\n }\\n\\n /// @notice Maps a bridge token to data\\n mapping(address => BridgeDetails) public bridges;\\n /// @notice List of all bridge tokens\\n address[] public bridgeTokensList;\\n /// @notice Maps a bridge token to the associated hourly volume\\n mapping(address => mapping(uint256 => uint256)) public usage;\\n /// @notice Maps an address to whether it is exempt of fees for when it comes to swapping in and out\\n mapping(address => uint256) public isFeeExempt;\\n /// @notice Limit to the amount of tokens that can be sent from that chain to another chain\\n uint256 public chainTotalHourlyLimit;\\n /// @notice Usage per hour on that chain. Maps an hourly timestamp to the total volume swapped out on the chain\\n mapping(uint256 => uint256) public chainTotalUsage;\\n\\n // =================================== EVENTS ==================================\\n\\n event BridgeTokenAdded(address indexed bridgeToken, uint256 limit, uint256 hourlyLimit, uint64 fee, bool paused);\\n event BridgeTokenToggled(address indexed bridgeToken, bool toggleStatus);\\n event BridgeTokenRemoved(address indexed bridgeToken);\\n event BridgeTokenFeeUpdated(address indexed bridgeToken, uint64 fee);\\n event BridgeTokenLimitUpdated(address indexed bridgeToken, uint256 limit);\\n event BridgeTokenHourlyLimitUpdated(address indexed bridgeToken, uint256 hourlyLimit);\\n event HourlyLimitUpdated(uint256 hourlyLimit);\\n event Recovered(address indexed token, address indexed to, uint256 amount);\\n event FeeToggled(address indexed theAddress, uint256 toggleStatus);\\n\\n // =================================== ERRORS ==================================\\n\\n error AssetStillControlledInReserves();\\n error HourlyLimitExceeded();\\n error InvalidToken();\\n error NotGovernor();\\n error NotGovernorOrGuardian();\\n error TooBigAmount();\\n error TooHighParameterValue();\\n error ZeroAddress();\\n\\n // ================================= MODIFIERS =================================\\n\\n /// @notice Checks whether the `msg.sender` has the governor role or not\\n modifier onlyGovernor() {\\n if (!ITreasury(treasury).isGovernor(msg.sender)) revert NotGovernor();\\n _;\\n }\\n\\n /// @notice Checks whether the `msg.sender` has the governor role or the guardian role\\n modifier onlyGovernorOrGuardian() {\\n if (!ITreasury(treasury).isGovernorOrGuardian(msg.sender)) revert NotGovernorOrGuardian();\\n _;\\n }\\n\\n // ===================== EXTERNAL PERMISSIONLESS FUNCTIONS =====================\\n\\n /// @notice Returns the list of all supported bridge tokens\\n /// @dev Helpful for UIs\\n function allBridgeTokens() external view returns (address[] memory) {\\n return bridgeTokensList;\\n }\\n\\n /// @notice Returns the current volume for a bridge, for the current hour\\n /// @param bridgeToken Bridge used to mint\\n /// @dev Helpful for UIs\\n function currentUsage(address bridgeToken) external view returns (uint256) {\\n return usage[bridgeToken][block.timestamp / 3600];\\n }\\n\\n /// @notice Returns the current total volume on the chain for the current hour\\n /// @dev Helpful for UIs\\n function currentTotalUsage() external view returns (uint256) {\\n return chainTotalUsage[block.timestamp / 3600];\\n }\\n\\n /// @notice Mints the canonical token from a supported bridge token\\n /// @param bridgeToken Bridge token to use to mint\\n /// @param amount Amount of bridge tokens to send\\n /// @param to Address to which the stablecoin should be sent\\n /// @return Amount of the canonical stablecoin actually minted\\n /// @dev Some fees may be taken by the protocol depending on the token used and on the address calling\\n function swapIn(address bridgeToken, uint256 amount, address to) external returns (uint256) {\\n BridgeDetails memory bridgeDetails = bridges[bridgeToken];\\n if (!bridgeDetails.allowed || bridgeDetails.paused) revert InvalidToken();\\n uint256 balance = IERC20(bridgeToken).balanceOf(address(this));\\n if (balance + amount > bridgeDetails.limit) {\\n // In case someone maliciously sends tokens to this contract\\n // Or the limit changes\\n if (bridgeDetails.limit > balance) amount = bridgeDetails.limit - balance;\\n else {\\n amount = 0;\\n }\\n }\\n\\n // Checking requirement on the hourly volume\\n uint256 hour = block.timestamp / 3600;\\n uint256 hourlyUsage = usage[bridgeToken][hour];\\n if (hourlyUsage + amount > bridgeDetails.hourlyLimit) {\\n // Edge case when the hourly limit changes\\n amount = bridgeDetails.hourlyLimit > hourlyUsage ? bridgeDetails.hourlyLimit - hourlyUsage : 0;\\n }\\n usage[bridgeToken][hour] = hourlyUsage + amount;\\n\\n IERC20(bridgeToken).safeTransferFrom(msg.sender, address(this), amount);\\n uint256 canonicalOut = amount;\\n // Computing fees\\n if (isFeeExempt[msg.sender] == 0) {\\n canonicalOut -= (canonicalOut * bridgeDetails.fee) / BASE_PARAMS;\\n }\\n _mint(to, canonicalOut);\\n return canonicalOut;\\n }\\n\\n /// @notice Burns the canonical token in exchange for a bridge token\\n /// @param bridgeToken Bridge token required\\n /// @param amount Amount of canonical tokens to burn\\n /// @param to Address to which the bridge token should be sent\\n /// @return Amount of bridge tokens actually sent back\\n /// @dev Some fees may be taken by the protocol depending on the token used and on the address calling\\n function swapOut(address bridgeToken, uint256 amount, address to) external returns (uint256) {\\n BridgeDetails memory bridgeDetails = bridges[bridgeToken];\\n if (!bridgeDetails.allowed || bridgeDetails.paused) revert InvalidToken();\\n\\n uint256 hour = block.timestamp / 3600;\\n uint256 hourlyUsage = chainTotalUsage[hour] + amount;\\n // If the amount being swapped out exceeds the limit, we revert\\n // We don't want to change the amount being swapped out.\\n // The user can decide to send another tx with the correct amount to reach the limit\\n if (hourlyUsage > chainTotalHourlyLimit) revert HourlyLimitExceeded();\\n chainTotalUsage[hour] = hourlyUsage;\\n\\n _burn(msg.sender, amount);\\n uint256 bridgeOut = amount;\\n if (isFeeExempt[msg.sender] == 0) {\\n bridgeOut -= (bridgeOut * bridgeDetails.fee) / BASE_PARAMS;\\n }\\n IERC20(bridgeToken).safeTransfer(to, bridgeOut);\\n return bridgeOut;\\n }\\n\\n // ============================ GOVERNANCE FUNCTIONS ===========================\\n\\n /// @notice Adds support for a bridge token\\n /// @param bridgeToken Bridge token to add: it should be a version of the stablecoin from another bridge\\n /// @param limit Limit on the balance of bridge token this contract could hold\\n /// @param hourlyLimit Limit on the hourly volume for this bridge\\n /// @param paused Whether swapping for this token should be paused or not\\n /// @param fee Fee taken upon swapping for or against this token\\n function addBridgeToken(\\n address bridgeToken,\\n uint256 limit,\\n uint256 hourlyLimit,\\n uint64 fee,\\n bool paused\\n ) external onlyGovernor {\\n if (bridges[bridgeToken].allowed || bridgeToken == address(0)) revert InvalidToken();\\n if (fee > BASE_PARAMS) revert TooHighParameterValue();\\n BridgeDetails memory _bridge;\\n _bridge.limit = limit;\\n _bridge.hourlyLimit = hourlyLimit;\\n _bridge.paused = paused;\\n _bridge.fee = fee;\\n _bridge.allowed = true;\\n bridges[bridgeToken] = _bridge;\\n bridgeTokensList.push(bridgeToken);\\n emit BridgeTokenAdded(bridgeToken, limit, hourlyLimit, fee, paused);\\n }\\n\\n /// @notice Removes support for a token\\n /// @param bridgeToken Address of the bridge token to remove support for\\n function removeBridgeToken(address bridgeToken) external onlyGovernor {\\n if (IERC20(bridgeToken).balanceOf(address(this)) != 0) revert AssetStillControlledInReserves();\\n delete bridges[bridgeToken];\\n // Deletion from `bridgeTokensList` loop\\n uint256 bridgeTokensListLength = bridgeTokensList.length;\\n for (uint256 i; i < bridgeTokensListLength - 1; ++i) {\\n if (bridgeTokensList[i] == bridgeToken) {\\n // Replace the `bridgeToken` to remove with the last of the list\\n bridgeTokensList[i] = bridgeTokensList[bridgeTokensListLength - 1];\\n break;\\n }\\n }\\n // Remove last element in array\\n bridgeTokensList.pop();\\n emit BridgeTokenRemoved(bridgeToken);\\n }\\n\\n /// @notice Recovers any ERC20 token\\n /// @dev Can be used to withdraw bridge tokens for them to be de-bridged on mainnet\\n function recoverERC20(address tokenAddress, address to, uint256 amountToRecover) external onlyGovernor {\\n IERC20(tokenAddress).safeTransfer(to, amountToRecover);\\n emit Recovered(tokenAddress, to, amountToRecover);\\n }\\n\\n /// @notice Updates the `limit` amount for `bridgeToken`\\n function setLimit(address bridgeToken, uint256 limit) external onlyGovernorOrGuardian {\\n if (!bridges[bridgeToken].allowed) revert InvalidToken();\\n bridges[bridgeToken].limit = limit;\\n emit BridgeTokenLimitUpdated(bridgeToken, limit);\\n }\\n\\n /// @notice Updates the `hourlyLimit` amount for `bridgeToken`\\n function setHourlyLimit(address bridgeToken, uint256 hourlyLimit) external onlyGovernorOrGuardian {\\n if (!bridges[bridgeToken].allowed) revert InvalidToken();\\n bridges[bridgeToken].hourlyLimit = hourlyLimit;\\n emit BridgeTokenHourlyLimitUpdated(bridgeToken, hourlyLimit);\\n }\\n\\n /// @notice Updates the `chainTotalHourlyLimit` amount\\n function setChainTotalHourlyLimit(uint256 hourlyLimit) external onlyGovernorOrGuardian {\\n chainTotalHourlyLimit = hourlyLimit;\\n emit HourlyLimitUpdated(hourlyLimit);\\n }\\n\\n /// @notice Updates the `fee` value for `bridgeToken`\\n function setSwapFee(address bridgeToken, uint64 fee) external onlyGovernorOrGuardian {\\n if (!bridges[bridgeToken].allowed) revert InvalidToken();\\n if (fee > BASE_PARAMS) revert TooHighParameterValue();\\n bridges[bridgeToken].fee = fee;\\n emit BridgeTokenFeeUpdated(bridgeToken, fee);\\n }\\n\\n /// @notice Pauses or unpauses swapping in and out for a token\\n function toggleBridge(address bridgeToken) external onlyGovernorOrGuardian {\\n if (!bridges[bridgeToken].allowed) revert InvalidToken();\\n bool pausedStatus = bridges[bridgeToken].paused;\\n bridges[bridgeToken].paused = !pausedStatus;\\n emit BridgeTokenToggled(bridgeToken, !pausedStatus);\\n }\\n\\n /// @notice Toggles fees for the address `theAddress`\\n function toggleFeesForAddress(address theAddress) external onlyGovernorOrGuardian {\\n uint256 feeExemptStatus = 1 - isFeeExempt[theAddress];\\n isFeeExempt[theAddress] = feeExemptStatus;\\n emit FeeToggled(theAddress, feeExemptStatus);\\n }\\n}\\n\",\"keccak256\":\"0x9782497e84a1dc4bc468778ede4aceb35cebf74e4159e2af8f469f49312c3841\",\"license\":\"GPL-3.0\"},\"contracts/interfaces/IAgToken.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-3.0\\n\\npragma solidity ^0.8.12;\\n\\nimport \\\"@openzeppelin/contracts-upgradeable/token/ERC20/IERC20Upgradeable.sol\\\";\\n\\n/// @title IAgToken\\n/// @author Angle Labs, Inc.\\n/// @notice Interface for the stablecoins `AgToken` contracts\\n/// @dev This interface only contains functions of the `AgToken` contract which are called by other contracts\\n/// of this module or of the first module of the Angle Protocol\\ninterface IAgToken is IERC20Upgradeable {\\n // ======================= Minter Role Only Functions ===========================\\n\\n /// @notice Lets the `StableMaster` contract or another whitelisted contract mint agTokens\\n /// @param account Address to mint to\\n /// @param amount Amount to mint\\n /// @dev The contracts allowed to issue agTokens are the `StableMaster` contract, `VaultManager` contracts\\n /// associated to this stablecoin as well as the flash loan module (if activated) and potentially contracts\\n /// whitelisted by governance\\n function mint(address account, uint256 amount) external;\\n\\n /// @notice Burns `amount` tokens from a `burner` address after being asked to by `sender`\\n /// @param amount Amount of tokens to burn\\n /// @param burner Address to burn from\\n /// @param sender Address which requested the burn from `burner`\\n /// @dev This method is to be called by a contract with the minter right after being requested\\n /// to do so by a `sender` address willing to burn tokens from another `burner` address\\n /// @dev The method checks the allowance between the `sender` and the `burner`\\n function burnFrom(uint256 amount, address burner, address sender) external;\\n\\n /// @notice Burns `amount` tokens from a `burner` address\\n /// @param amount Amount of tokens to burn\\n /// @param burner Address to burn from\\n /// @dev This method is to be called by a contract with a minter right on the AgToken after being\\n /// requested to do so by an address willing to burn tokens from its address\\n function burnSelf(uint256 amount, address burner) external;\\n\\n // ========================= Treasury Only Functions ===========================\\n\\n /// @notice Adds a minter in the contract\\n /// @param minter Minter address to add\\n /// @dev Zero address checks are performed directly in the `Treasury` contract\\n function addMinter(address minter) external;\\n\\n /// @notice Removes a minter from the contract\\n /// @param minter Minter address to remove\\n /// @dev This function can also be called by a minter wishing to revoke itself\\n function removeMinter(address minter) external;\\n\\n /// @notice Sets a new treasury contract\\n /// @param _treasury New treasury address\\n function setTreasury(address _treasury) external;\\n\\n // ========================= External functions ================================\\n\\n /// @notice Checks whether an address has the right to mint agTokens\\n /// @param minter Address for which the minting right should be checked\\n /// @return Whether the address has the right to mint agTokens or not\\n function isMinter(address minter) external view returns (bool);\\n\\n /// @notice Get the associated treasury\\n function treasury() external view returns (address);\\n}\\n\",\"keccak256\":\"0x0c83efcfc1fb9ae9ba830f7b89e3dab9abf6ad7a6205a31aa35fbccaa837dcdc\",\"license\":\"GPL-3.0\"},\"contracts/interfaces/ICoreBorrow.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-3.0\\n\\npragma solidity ^0.8.12;\\n\\n/// @title ICoreBorrow\\n/// @author Angle Labs, Inc.\\n/// @notice Interface for the `CoreBorrow` contract\\n/// @dev This interface only contains functions of the `CoreBorrow` contract which are called by other contracts\\n/// of this module\\ninterface ICoreBorrow {\\n /// @notice Checks if an address corresponds to a treasury of a stablecoin with a flash loan\\n /// module initialized on it\\n /// @param treasury Address to check\\n /// @return Whether the address has the `FLASHLOANER_TREASURY_ROLE` or not\\n function isFlashLoanerTreasury(address treasury) external view returns (bool);\\n\\n /// @notice Checks whether an address is governor of the Angle Protocol or not\\n /// @param admin Address to check\\n /// @return Whether the address has the `GOVERNOR_ROLE` or not\\n function isGovernor(address admin) external view returns (bool);\\n\\n /// @notice Checks whether an address is governor or a guardian of the Angle Protocol or not\\n /// @param admin Address to check\\n /// @return Whether the address has the `GUARDIAN_ROLE` or not\\n /// @dev Governance should make sure when adding a governor to also give this governor the guardian\\n /// role by calling the `addGovernor` function\\n function isGovernorOrGuardian(address admin) external view returns (bool);\\n}\\n\",\"keccak256\":\"0x10249210cbf522775f040baf981d7d037472168ce2746d87473ac7c29a34e62e\",\"license\":\"GPL-3.0\"},\"contracts/interfaces/IFlashAngle.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-3.0\\n\\npragma solidity ^0.8.12;\\n\\nimport \\\"./IAgToken.sol\\\";\\nimport \\\"./ICoreBorrow.sol\\\";\\n\\n/// @title IFlashAngle\\n/// @author Angle Labs, Inc.\\n/// @notice Interface for the `FlashAngle` contract\\n/// @dev This interface only contains functions of the contract which are called by other contracts\\n/// of this module\\ninterface IFlashAngle {\\n /// @notice Reference to the `CoreBorrow` contract managing the FlashLoan module\\n function core() external view returns (ICoreBorrow);\\n\\n /// @notice Sends the fees taken from flash loans to the treasury contract associated to the stablecoin\\n /// @param stablecoin Stablecoin from which profits should be sent\\n /// @return balance Amount of profits sent\\n /// @dev This function can only be called by the treasury contract\\n function accrueInterestToTreasury(IAgToken stablecoin) external returns (uint256 balance);\\n\\n /// @notice Adds support for a stablecoin\\n /// @param _treasury Treasury associated to the stablecoin to add support for\\n /// @dev This function can only be called by the `CoreBorrow` contract\\n function addStablecoinSupport(address _treasury) external;\\n\\n /// @notice Removes support for a stablecoin\\n /// @param _treasury Treasury associated to the stablecoin to remove support for\\n /// @dev This function can only be called by the `CoreBorrow` contract\\n function removeStablecoinSupport(address _treasury) external;\\n\\n /// @notice Sets a new core contract\\n /// @param _core Core contract address to set\\n /// @dev This function can only be called by the `CoreBorrow` contract\\n function setCore(address _core) external;\\n}\\n\",\"keccak256\":\"0x39b0097f695b9e934bccdc72676c91513f1077cc5d0fd151908fd25a7c5cfbe4\",\"license\":\"GPL-3.0\"},\"contracts/interfaces/ITreasury.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-3.0\\n\\npragma solidity ^0.8.12;\\n\\nimport \\\"./IAgToken.sol\\\";\\nimport \\\"./ICoreBorrow.sol\\\";\\nimport \\\"./IFlashAngle.sol\\\";\\n\\n/// @title ITreasury\\n/// @author Angle Labs, Inc.\\n/// @notice Interface for the `Treasury` contract\\n/// @dev This interface only contains functions of the `Treasury` which are called by other contracts\\n/// of this module\\ninterface ITreasury {\\n /// @notice Stablecoin handled by this `treasury` contract\\n function stablecoin() external view returns (IAgToken);\\n\\n /// @notice Checks whether a given address has the governor role\\n /// @param admin Address to check\\n /// @return Whether the address has the governor role\\n /// @dev Access control is only kept in the `CoreBorrow` contract\\n function isGovernor(address admin) external view returns (bool);\\n\\n /// @notice Checks whether a given address has the guardian or the governor role\\n /// @param admin Address to check\\n /// @return Whether the address has the guardian or the governor role\\n /// @dev Access control is only kept in the `CoreBorrow` contract which means that this function\\n /// queries the `CoreBorrow` contract\\n function isGovernorOrGuardian(address admin) external view returns (bool);\\n\\n /// @notice Checks whether a given address has well been initialized in this contract\\n /// as a `VaultManager`\\n /// @param _vaultManager Address to check\\n /// @return Whether the address has been initialized or not\\n function isVaultManager(address _vaultManager) external view returns (bool);\\n\\n /// @notice Sets a new flash loan module for this stablecoin\\n /// @param _flashLoanModule Reference to the new flash loan module\\n /// @dev This function removes the minting right to the old flash loan module and grants\\n /// it to the new module\\n function setFlashLoanModule(address _flashLoanModule) external;\\n\\n /// @notice Gets the vault manager list\\n function vaultManagerList(uint256 i) external returns (address);\\n}\\n\",\"keccak256\":\"0x06c2f781c08732ce1b5845c083af5742716245baa6c519bd737f32b230a884c1\",\"license\":\"GPL-3.0\"}},\"version\":1}", + "bytecode": "0x60806040523480156200001157600080fd5b50600054610100900460ff1615808015620000335750600054600160ff909116105b8062000063575062000050306200013d60201b6200273a1760201c565b15801562000063575060005460ff166001145b620000cb5760405162461bcd60e51b815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201526d191e481a5b9a5d1a585b1a5e995960921b606482015260840160405180910390fd5b6000805460ff191660011790558015620000ef576000805461ff0019166101001790555b801562000136576000805461ff0019169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15b506200014c565b6001600160a01b03163b151590565b6146d0806200015c6000396000f3fe608060405234801561001057600080fd5b50600436106102ff5760003560e01c806361d027b31161019c5780639f48118f116100ee578063ced67f0c11610097578063dd62ed3e11610071578063dd62ed3e14610724578063e3e286551461076a578063f0f442601461077d57600080fd5b8063ced67f0c1461066b578063d44ad63f146106fe578063d505accf1461071157600080fd5b8063aa271e1a116100c8578063aa271e1a14610620578063ba330bd714610643578063cd4839ca1461065657600080fd5b80639f48118f146105ef578063a457c2d7146105fa578063a9059cbb1461060d57600080fd5b80637ecebe001161015057806395d89b411161012a57806395d89b41146105c1578063983b2d56146105c95780639e4e0dae146105dc57600080fd5b80637ecebe00146105705780638933fb791461058357806390218cff146105ae57600080fd5b80637334d020116101815780637334d020146105425780637d4c9c2d146105555780637d74e25f1461056857600080fd5b806361d027b3146104c757806370a082311461050c57600080fd5b80633092afd511610255578063395093511161020957806340c10f19116101e357806340c10f19146104815780634dc32fcc146104945780635bfbec96146104a757600080fd5b8063395093511461043b5780633a55f89d1461044e5780633f4218e01461046157600080fd5b8063350ebe041161023a578063350ebe041461040d5780633644e5151461042057806336db43b51461042857600080fd5b80633092afd5146103eb578063313ce567146103fe57600080fd5b8063151dd755116102b757806323b872dd1161029157806323b872dd146103b25780632b471d8e146103c55780632e403e14146103d857600080fd5b8063151dd7551461038057806318160ddd146103a15780632342fb0e146103a957600080fd5b80630919a951116102e85780630919a95114610337578063095ea7b31461034a5780631171bda91461036d57600080fd5b806306fdde0314610304578063077f224a14610322575b600080fd5b61030c610790565b6040516103199190613e48565b60405180910390f35b610335610330366004613f95565b610822565b005b61033561034536600461400d565b610832565b61035d61035836600461402a565b610995565b6040519015158152602001610319565b61033561037b366004614056565b6109af565b61039361038e366004614097565b610b04565b604051908152602001610319565b603554610393565b61039360d25481565b61035d6103c0366004614056565b610dbe565b6103356103d33660046140ce565b610de2565b6103356103e636600461400d565b610e39565b6103356103f936600461400d565b6111e8565b60405160128152602001610319565b61033561041b3660046140fe565b6112d1565b6103936113da565b61033561043636600461402a565b6113e9565b61035d61044936600461402a565b611579565b61033561045c366004614135565b6115c0565b61039361046f36600461400d565b60d16020526000908152604090205481565b61033561048f36600461402a565b6116c3565b6103936104a236600461400d565b611716565b6103936104b5366004614135565b60d36020526000908152604090205481565b60cd546104e79073ffffffffffffffffffffffffffffffffffffffff1681565b60405173ffffffffffffffffffffffffffffffffffffffff9091168152602001610319565b61039361051a36600461400d565b73ffffffffffffffffffffffffffffffffffffffff1660009081526033602052604090205490565b61033561055036600461402a565b61175e565b610335610563366004614179565b6118f1565b610393611c59565b61039361057e36600461400d565b611c7e565b61039361059136600461402a565b60d060209081526000928352604080842090915290825290205481565b6103356105bc366004614135565b611ca9565b61030c611cb6565b6103356105d736600461400d565b611cc5565b6103356105ea3660046141d6565b611d8d565b610393633b9aca0081565b61035d61060836600461402a565b611f99565b61035d61061b36600461402a565b61206f565b61035d61062e36600461400d565b60cc6020526000908152604090205460ff1681565b6104e7610651366004614135565b61207d565b61065e6120b4565b604051610319919061420b565b6106c561067936600461400d565b60ce6020526000908152604090208054600182015460029092015490919067ffffffffffffffff81169060ff680100000000000000008204811691690100000000000000000090041685565b60408051958652602086019490945267ffffffffffffffff9092169284019290925290151560608301521515608082015260a001610319565b61039361070c366004614097565b612122565b61033561071f366004614265565b6122e7565b6103936107323660046142dc565b73ffffffffffffffffffffffffffffffffffffffff918216600090815260346020908152604080832093909416825291909152205490565b61033561077836600461400d565b6124a6565b61033561078b36600461400d565b61267a565b60606036805461079f9061430a565b80601f01602080910402602001604051908101604052809291908181526020018280546107cb9061430a565b80156108185780601f106107ed57610100808354040283529160200191610818565b820191906000526020600020905b8154815290600101906020018083116107fb57829003601f168201915b5050505050905090565b61082d838383612756565b505050565b60cd546040517f521d4de900000000000000000000000000000000000000000000000000000000815233600482015273ffffffffffffffffffffffffffffffffffffffff9091169063521d4de990602401602060405180830381865afa1580156108a0573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906108c49190614357565b6108fa576040517f99e120bc00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff8116600090815260d1602052604081205461092b9060016143a3565b73ffffffffffffffffffffffffffffffffffffffff8316600081815260d160205260409081902083905551919250907f979ef83e7e7a87cb48064e296dd7e997870d50f43acf8d7ad221313526c8ca0f906109899084815260200190565b60405180910390a25050565b6000336109a3818585612a35565b60019150505b92915050565b60cd546040517fe43581b800000000000000000000000000000000000000000000000000000000815233600482015273ffffffffffffffffffffffffffffffffffffffff9091169063e43581b890602401602060405180830381865afa158015610a1d573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610a419190614357565b610a77576040517fee3675d400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b610a9873ffffffffffffffffffffffffffffffffffffffff84168383612be0565b8173ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff167ffff3b3844276f57024e0b42afec1a37f75db36511e43819a4f2a63ab7862b64883604051610af791815260200190565b60405180910390a3505050565b73ffffffffffffffffffffffffffffffffffffffff8316600090815260ce60209081526040808320815160a081018352815481526001820154938101939093526002015467ffffffffffffffff81169183019190915260ff680100000000000000008204811615801560608501526901000000000000000000909204161515608083015280610b94575080608001515b15610bcb576040517fc1ab6dc100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015260009073ffffffffffffffffffffffffffffffffffffffff8716906370a0823190602401602060405180830381865afa158015610c38573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610c5c91906143b6565b8251909150610c6b86836143cf565b1115610c93578151811015610c8e578151610c879082906143a3565b9450610c93565b600094505b6000610ca1610e10426143e2565b73ffffffffffffffffffffffffffffffffffffffff8816600090815260d0602090815260408083208484528252909120549085015191925090610ce488836143cf565b1115610d0f5780846020015111610cfc576000610d0c565b808460200151610d0c91906143a3565b96505b610d1987826143cf565b73ffffffffffffffffffffffffffffffffffffffff8916600081815260d060209081526040808320878452909152902091909155610d599033308a612cb4565b33600090815260d16020526040812054889103610da657633b9aca00856040015167ffffffffffffffff1682610d8f919061441d565b610d9991906143e2565b610da390826143a3565b90505b610db08782612d12565b9450505050505b9392505050565b600033610dcc858285612e32565b610dd7858585612f03565b506001949350505050565b33600090815260cc602052604090205460ff16610e2b576040517ff8d2906c00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b610e3581836131b6565b5050565b60cd546040517fe43581b800000000000000000000000000000000000000000000000000000000815233600482015273ffffffffffffffffffffffffffffffffffffffff9091169063e43581b890602401602060405180830381865afa158015610ea7573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610ecb9190614357565b610f01576040517fee3675d400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015273ffffffffffffffffffffffffffffffffffffffff8216906370a0823190602401602060405180830381865afa158015610f6b573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610f8f91906143b6565b15610fc6576040517f2ef630ec00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff8116600090815260ce602052604081208181556001810182905560020180547fffffffffffffffffffffffffffffffffffffffffffff0000000000000000000016905560cf54905b61102e6001836143a3565b811015611139578273ffffffffffffffffffffffffffffffffffffffff1660cf828154811061105f5761105f614434565b60009182526020909120015473ffffffffffffffffffffffffffffffffffffffff16036111295760cf6110936001846143a3565b815481106110a3576110a3614434565b60009182526020909120015460cf805473ffffffffffffffffffffffffffffffffffffffff90921691839081106110dc576110dc614434565b9060005260206000200160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550611139565b61113281614463565b9050611023565b5060cf80548061114b5761114b61449b565b60008281526020812082017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff90810180547fffffffffffffffffffffffff000000000000000000000000000000000000000016905590910190915560405173ffffffffffffffffffffffffffffffffffffffff8416917f5c95b49c4d59d97a2f044167723f29c74b30f99702e3fd406c3830160aa9ccb891a25050565b60cd5473ffffffffffffffffffffffffffffffffffffffff16331480159061122657503373ffffffffffffffffffffffffffffffffffffffff821614155b1561125d576040517fddb5de5e00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff8116600081815260cc602052604080822080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00169055517f98c15241d6c02bc5ee0b780e11b3ea737a2defd9d04877edbe9f9497065bd02f9190a250565b33600090815260cc602052604090205460ff1661131a576040517ff8d2906c00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff16146113d05773ffffffffffffffffffffffffffffffffffffffff828116600090815260346020908152604080832093851683529290522054838110156113ba576040517f715ec26c00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6113ce83836113c987856143a3565b612a35565b505b61082d82846131b6565b60006113e46133a3565b905090565b60cd546040517f521d4de900000000000000000000000000000000000000000000000000000000815233600482015273ffffffffffffffffffffffffffffffffffffffff9091169063521d4de990602401602060405180830381865afa158015611457573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061147b9190614357565b6114b1576040517f99e120bc00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff8216600090815260ce602052604090206002015468010000000000000000900460ff1661151f576040517fc1ab6dc100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff8216600081815260ce602052604090819020839055517fe7b113fba37131b6396680a0c55790a697ec975e198ff8cfd89dac90a6379e61906109899084815260200190565b33600081815260346020908152604080832073ffffffffffffffffffffffffffffffffffffffff871684529091528120549091906109a390829086906113c99087906143cf565b60cd546040517f521d4de900000000000000000000000000000000000000000000000000000000815233600482015273ffffffffffffffffffffffffffffffffffffffff9091169063521d4de990602401602060405180830381865afa15801561162e573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906116529190614357565b611688576040517f99e120bc00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60d28190556040518181527fc3b69829afe2345596a02c8b587d41f796ba0094481d899e1b2e07b7532a1e219060200160405180910390a150565b33600090815260cc602052604090205460ff1661170c576040517ff8d2906c00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b610e358282612d12565b73ffffffffffffffffffffffffffffffffffffffff8116600090815260d06020526040812081611748610e10426143e2565b8152602001908152602001600020549050919050565b60cd546040517f521d4de900000000000000000000000000000000000000000000000000000000815233600482015273ffffffffffffffffffffffffffffffffffffffff9091169063521d4de990602401602060405180830381865afa1580156117cc573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906117f09190614357565b611826576040517f99e120bc00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff8216600090815260ce602052604090206002015468010000000000000000900460ff16611894576040517fc1ab6dc100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff8216600081815260ce602052604090819020600101839055517fe13ac9338b2ee623233f83c1b3ceab16490fa3e3737fac7f0970d0830a9f4871906109899084815260200190565b60cd546040517fe43581b800000000000000000000000000000000000000000000000000000000815233600482015273ffffffffffffffffffffffffffffffffffffffff9091169063e43581b890602401602060405180830381865afa15801561195f573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906119839190614357565b6119b9576040517fee3675d400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff8516600090815260ce602052604090206002015468010000000000000000900460ff1680611a10575073ffffffffffffffffffffffffffffffffffffffff8516155b15611a47576040517fc1ab6dc100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b633b9aca008267ffffffffffffffff161115611a8f576040517feca1d2c600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040805160a08101825260008082526020820181905291810182905260608101829052608081019190915284815260208082018581528315156080840190815267ffffffffffffffff808716604080870191825260016060880181815273ffffffffffffffffffffffffffffffffffffffff8e16600081815260ce9099528389208a5181559751888401559351600290970180549151965115156901000000000000000000027fffffffffffffffffffffffffffffffffffffffffffff00ffffffffffffffffff97151568010000000000000000027fffffffffffffffffffffffffffffffffffffffffffffff000000000000000000909316989096169790971717949094169290921790935560cf805492830181559093527facb8d954e2cfef495862221e91bd7523613cf8808827cb33edfe4904cc51bf290180547fffffffffffffffffffffffff0000000000000000000000000000000000000000168217905590517f53087ff85d80a7671594bd2e86b92af22e0b3c2c441c8033bba7399b7b5cbe2390611c49908890889088908890938452602084019290925267ffffffffffffffff1660408301521515606082015260800190565b60405180910390a2505050505050565b600060d381611c6a610e10426143e2565b815260200190815260200160002054905090565b73ffffffffffffffffffffffffffffffffffffffff81166000908152609960205260408120546109a9565b611cb333826131b6565b50565b60606037805461079f9061430a565b60cd5473ffffffffffffffffffffffffffffffffffffffff163314611d16576040517fb90cdbb100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff8116600081815260cc602052604080822080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00166001179055517f98c15241d6c02bc5ee0b780e11b3ea737a2defd9d04877edbe9f9497065bd02f9190a250565b60cd546040517f521d4de900000000000000000000000000000000000000000000000000000000815233600482015273ffffffffffffffffffffffffffffffffffffffff9091169063521d4de990602401602060405180830381865afa158015611dfb573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611e1f9190614357565b611e55576040517f99e120bc00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff8216600090815260ce602052604090206002015468010000000000000000900460ff16611ec3576040517fc1ab6dc100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b633b9aca008167ffffffffffffffff161115611f0b576040517feca1d2c600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff8216600081815260ce602090815260409182902060020180547fffffffffffffffffffffffffffffffffffffffffffffffff00000000000000001667ffffffffffffffff861690811790915591519182527f901f9de19b475adc8da4110434b8df940dce085afd05e2281c86807f3a899d299101610989565b33600081815260346020908152604080832073ffffffffffffffffffffffffffffffffffffffff8716845290915281205490919083811015612062576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602560248201527f45524332303a2064656372656173656420616c6c6f77616e63652062656c6f7760448201527f207a65726f00000000000000000000000000000000000000000000000000000060648201526084015b60405180910390fd5b610dd78286868403612a35565b6000336109a3818585612f03565b60cf818154811061208d57600080fd5b60009182526020909120015473ffffffffffffffffffffffffffffffffffffffff16905081565b606060cf80548060200260200160405190810160405280929190818152602001828054801561081857602002820191906000526020600020905b815473ffffffffffffffffffffffffffffffffffffffff1681526001909101906020018083116120ee575050505050905090565b73ffffffffffffffffffffffffffffffffffffffff8316600090815260ce60209081526040808320815160a081018352815481526001820154938101939093526002015467ffffffffffffffff81169183019190915260ff6801000000000000000082048116158015606085015269010000000000000000009092041615156080830152806121b2575080608001515b156121e9576040517fc1ab6dc100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60006121f7610e10426143e2565b600081815260d36020526040812054919250906122159087906143cf565b905060d254811115612253576040517f6d43d1ac00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600082815260d36020526040902081905561226e33876131b6565b33600090815260d160205260408120548791036122bb57633b9aca00846040015167ffffffffffffffff16826122a4919061441d565b6122ae91906143e2565b6122b890826143a3565b90505b6122dc73ffffffffffffffffffffffffffffffffffffffff89168783612be0565b979650505050505050565b83421115612351576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f45524332305065726d69743a206578706972656420646561646c696e650000006044820152606401612059565b60007f6e71edae12b1b97f4d1f60370fef10105fa2faae0126114a169c64845d6126c98888886123808c61341e565b60408051602081019690965273ffffffffffffffffffffffffffffffffffffffff94851690860152929091166060840152608083015260a082015260c0810186905260e00160405160208183030381529060405280519060200120905060006123e882613453565b905060006123f8828787876134bc565b90508973ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff161461248f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601e60248201527f45524332305065726d69743a20696e76616c6964207369676e617475726500006044820152606401612059565b61249a8a8a8a612a35565b50505050505050505050565b60cd546040517f521d4de900000000000000000000000000000000000000000000000000000000815233600482015273ffffffffffffffffffffffffffffffffffffffff9091169063521d4de990602401602060405180830381865afa158015612514573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906125389190614357565b61256e576040517f99e120bc00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff8116600090815260ce602052604090206002015468010000000000000000900460ff166125dc576040517fc1ab6dc100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff8116600081815260ce602090815260409182902060020180547fffffffffffffffffffffffffffffffffffffffffffff00ffffffffffffffffff811669010000000000000000009182900460ff16801592830291909117909255925192835292917ff7c93079dcbf699749d66345a351afab7d24219bb1d915c9f4fc4cf03f00d3979101610989565b60cd5473ffffffffffffffffffffffffffffffffffffffff1633146126cb576040517fb90cdbb100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60cd80547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83169081179091556040517f7dae230f18360d76a040c81f050aa14eb9d6dc7901b20fc5d855e2a20fe814d190600090a250565b73ffffffffffffffffffffffffffffffffffffffff163b151590565b600054610100900460ff16158080156127765750600054600160ff909116105b806127905750303b158015612790575060005460ff166001145b61281c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201527f647920696e697469616c697a65640000000000000000000000000000000000006064820152608401612059565b600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00166001179055801561287a57600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff166101001790555b3073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1663e9cbd8226040518163ffffffff1660e01b8152600401602060405180830381865afa1580156128dc573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061290091906144ca565b73ffffffffffffffffffffffffffffffffffffffff161461294d576040517f14bcf5c800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b612956846134e4565b61296084846135ba565b60cd80547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff84169081179091556040517f7dae230f18360d76a040c81f050aa14eb9d6dc7901b20fc5d855e2a20fe814d190600090a28015612a2f57600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15b50505050565b73ffffffffffffffffffffffffffffffffffffffff8316612ad7576040517f08c379a0000000000000000000000000000000000000000000000000000000008152602060048201526024808201527f45524332303a20617070726f76652066726f6d20746865207a65726f2061646460448201527f72657373000000000000000000000000000000000000000000000000000000006064820152608401612059565b73ffffffffffffffffffffffffffffffffffffffff8216612b7a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602260248201527f45524332303a20617070726f766520746f20746865207a65726f20616464726560448201527f73730000000000000000000000000000000000000000000000000000000000006064820152608401612059565b73ffffffffffffffffffffffffffffffffffffffff83811660008181526034602090815260408083209487168084529482529182902085905590518481527f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b9259101610af7565b60405173ffffffffffffffffffffffffffffffffffffffff831660248201526044810182905261082d9084907fa9059cbb00000000000000000000000000000000000000000000000000000000906064015b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff000000000000000000000000000000000000000000000000000000009093169290921790915261365b565b60405173ffffffffffffffffffffffffffffffffffffffff80851660248301528316604482015260648101829052612a2f9085907f23b872dd0000000000000000000000000000000000000000000000000000000090608401612c32565b73ffffffffffffffffffffffffffffffffffffffff8216612d8f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601f60248201527f45524332303a206d696e7420746f20746865207a65726f2061646472657373006044820152606401612059565b8060356000828254612da191906143cf565b909155505073ffffffffffffffffffffffffffffffffffffffff821660009081526033602052604081208054839290612ddb9084906143cf565b909155505060405181815273ffffffffffffffffffffffffffffffffffffffff8316906000907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef9060200160405180910390a35050565b73ffffffffffffffffffffffffffffffffffffffff8381166000908152603460209081526040808320938616835292905220547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8114612a2f5781811015612ef6576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f45524332303a20696e73756666696369656e7420616c6c6f77616e63650000006044820152606401612059565b612a2f8484848403612a35565b73ffffffffffffffffffffffffffffffffffffffff8316612fa6576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602560248201527f45524332303a207472616e736665722066726f6d20746865207a65726f20616460448201527f64726573730000000000000000000000000000000000000000000000000000006064820152608401612059565b73ffffffffffffffffffffffffffffffffffffffff8216613049576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602360248201527f45524332303a207472616e7366657220746f20746865207a65726f206164647260448201527f65737300000000000000000000000000000000000000000000000000000000006064820152608401612059565b73ffffffffffffffffffffffffffffffffffffffff8316600090815260336020526040902054818110156130ff576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f45524332303a207472616e7366657220616d6f756e742065786365656473206260448201527f616c616e636500000000000000000000000000000000000000000000000000006064820152608401612059565b73ffffffffffffffffffffffffffffffffffffffff8085166000908152603360205260408082208585039055918516815290812080548492906131439084906143cf565b925050819055508273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef846040516131a991815260200190565b60405180910390a3612a2f565b73ffffffffffffffffffffffffffffffffffffffff8216613259576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602160248201527f45524332303a206275726e2066726f6d20746865207a65726f2061646472657360448201527f73000000000000000000000000000000000000000000000000000000000000006064820152608401612059565b73ffffffffffffffffffffffffffffffffffffffff82166000908152603360205260409020548181101561330f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602260248201527f45524332303a206275726e20616d6f756e7420657863656564732062616c616e60448201527f63650000000000000000000000000000000000000000000000000000000000006064820152608401612059565b73ffffffffffffffffffffffffffffffffffffffff8316600090815260336020526040812083830390556035805484929061334b9084906143a3565b909155505060405182815260009073ffffffffffffffffffffffffffffffffffffffff8516907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef9060200160405180910390a3505050565b60006113e47f8b73c3c69bb8fe3d512ecc4cf759cc79239f7b179b0ffacaa9a75d522b39400f6133d260655490565b6066546040805160208101859052908101839052606081018290524660808201523060a082015260009060c0016040516020818303038152906040528051906020012090509392505050565b73ffffffffffffffffffffffffffffffffffffffff811660009081526099602052604090208054600181018255905b50919050565b60006109a96134606133a3565b836040517f19010000000000000000000000000000000000000000000000000000000000006020820152602281018390526042810182905260009060620160405160208183030381529060405280519060200120905092915050565b60008060006134cd87878787613767565b915091506134da8161387f565b5095945050505050565b600054610100900460ff1661357b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201527f6e697469616c697a696e670000000000000000000000000000000000000000006064820152608401612059565b611cb3816040518060400160405280600181526020017f3100000000000000000000000000000000000000000000000000000000000000815250613ad3565b600054610100900460ff16613651576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201527f6e697469616c697a696e670000000000000000000000000000000000000000006064820152608401612059565b610e358282613b84565b60006136bd826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c65648152508573ffffffffffffffffffffffffffffffffffffffff16613c349092919063ffffffff16565b80519091501561082d57808060200190518101906136db9190614357565b61082d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e60448201527f6f742073756363656564000000000000000000000000000000000000000000006064820152608401612059565b6000807f7fffffffffffffffffffffffffffffff5d576e7357a4501ddfe92f46681b20a083111561379e5750600090506003613876565b8460ff16601b141580156137b657508460ff16601c14155b156137c75750600090506004613876565b6040805160008082526020820180845289905260ff881692820192909252606081018690526080810185905260019060a0016020604051602081039080840390855afa15801561381b573d6000803e3d6000fd5b50506040517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0015191505073ffffffffffffffffffffffffffffffffffffffff811661386f57600060019250925050613876565b9150600090505b94509492505050565b6000816004811115613893576138936144e7565b0361389b5750565b60018160048111156138af576138af6144e7565b03613916576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601860248201527f45434453413a20696e76616c6964207369676e617475726500000000000000006044820152606401612059565b600281600481111561392a5761392a6144e7565b03613991576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601f60248201527f45434453413a20696e76616c6964207369676e6174757265206c656e677468006044820152606401612059565b60038160048111156139a5576139a56144e7565b03613a32576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602260248201527f45434453413a20696e76616c6964207369676e6174757265202773272076616c60448201527f75650000000000000000000000000000000000000000000000000000000000006064820152608401612059565b6004816004811115613a4657613a466144e7565b03611cb3576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602260248201527f45434453413a20696e76616c6964207369676e6174757265202776272076616c60448201527f75650000000000000000000000000000000000000000000000000000000000006064820152608401612059565b600054610100900460ff16613b6a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201527f6e697469616c697a696e670000000000000000000000000000000000000000006064820152608401612059565b815160209283012081519190920120606591909155606655565b600054610100900460ff16613c1b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201527f6e697469616c697a696e670000000000000000000000000000000000000000006064820152608401612059565b6036613c278382614564565b50603761082d8282614564565b6060613c438484600085613c4b565b949350505050565b606082471015613cdd576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f60448201527f722063616c6c00000000000000000000000000000000000000000000000000006064820152608401612059565b73ffffffffffffffffffffffffffffffffffffffff85163b613d5b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006044820152606401612059565b6000808673ffffffffffffffffffffffffffffffffffffffff168587604051613d84919061467e565b60006040518083038185875af1925050503d8060008114613dc1576040519150601f19603f3d011682016040523d82523d6000602084013e613dc6565b606091505b50915091506122dc82828660608315613de0575081610db7565b825115613df05782518084602001fd5b816040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016120599190613e48565b60005b83811015613e3f578181015183820152602001613e27565b50506000910152565b6020815260008251806020840152613e67816040850160208701613e24565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169190910160400192915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b600082601f830112613ed957600080fd5b813567ffffffffffffffff80821115613ef457613ef4613e99565b604051601f83017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0908116603f01168101908282118183101715613f3a57613f3a613e99565b81604052838152866020858801011115613f5357600080fd5b836020870160208301376000602085830101528094505050505092915050565b73ffffffffffffffffffffffffffffffffffffffff81168114611cb357600080fd5b600080600060608486031215613faa57600080fd5b833567ffffffffffffffff80821115613fc257600080fd5b613fce87838801613ec8565b94506020860135915080821115613fe457600080fd5b50613ff186828701613ec8565b925050604084013561400281613f73565b809150509250925092565b60006020828403121561401f57600080fd5b8135610db781613f73565b6000806040838503121561403d57600080fd5b823561404881613f73565b946020939093013593505050565b60008060006060848603121561406b57600080fd5b833561407681613f73565b9250602084013561408681613f73565b929592945050506040919091013590565b6000806000606084860312156140ac57600080fd5b83356140b781613f73565b925060208401359150604084013561400281613f73565b600080604083850312156140e157600080fd5b8235915060208301356140f381613f73565b809150509250929050565b60008060006060848603121561411357600080fd5b83359250602084013561412581613f73565b9150604084013561400281613f73565b60006020828403121561414757600080fd5b5035919050565b803567ffffffffffffffff8116811461416657600080fd5b919050565b8015158114611cb357600080fd5b600080600080600060a0868803121561419157600080fd5b853561419c81613f73565b945060208601359350604086013592506141b86060870161414e565b915060808601356141c88161416b565b809150509295509295909350565b600080604083850312156141e957600080fd5b82356141f481613f73565b91506142026020840161414e565b90509250929050565b6020808252825182820181905260009190848201906040850190845b8181101561425957835173ffffffffffffffffffffffffffffffffffffffff1683529284019291840191600101614227565b50909695505050505050565b600080600080600080600060e0888a03121561428057600080fd5b873561428b81613f73565b9650602088013561429b81613f73565b95506040880135945060608801359350608088013560ff811681146142bf57600080fd5b9699959850939692959460a0840135945060c09093013592915050565b600080604083850312156142ef57600080fd5b82356142fa81613f73565b915060208301356140f381613f73565b600181811c9082168061431e57607f821691505b60208210810361344d577f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b60006020828403121561436957600080fd5b8151610db78161416b565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b818103818111156109a9576109a9614374565b6000602082840312156143c857600080fd5b5051919050565b808201808211156109a9576109a9614374565b600082614418577f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b500490565b80820281158282048414176109a9576109a9614374565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff820361449457614494614374565b5060010190565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603160045260246000fd5b6000602082840312156144dc57600080fd5b8151610db781613f73565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b601f82111561082d57600081815260208120601f850160051c8101602086101561453d5750805b601f850160051c820191505b8181101561455c57828155600101614549565b505050505050565b815167ffffffffffffffff81111561457e5761457e613e99565b6145928161458c845461430a565b84614516565b602080601f8311600181146145e557600084156145af5750858301515b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600386901b1c1916600185901b17855561455c565b6000858152602081207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08616915b8281101561463257888601518255948401946001909101908401614613565b508582101561466e57878501517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600388901b60f8161c191681555b5050505050600190811b01905550565b60008251614690818460208701613e24565b919091019291505056fea2646970667358221220f2eb02bac1667a72be85ab617a5b5aa3d8f7a9b09b4d1fde9756b7a5636daf2164736f6c63430008110033", + "deployedBytecode": "0x608060405234801561001057600080fd5b50600436106102ff5760003560e01c806361d027b31161019c5780639f48118f116100ee578063ced67f0c11610097578063dd62ed3e11610071578063dd62ed3e14610724578063e3e286551461076a578063f0f442601461077d57600080fd5b8063ced67f0c1461066b578063d44ad63f146106fe578063d505accf1461071157600080fd5b8063aa271e1a116100c8578063aa271e1a14610620578063ba330bd714610643578063cd4839ca1461065657600080fd5b80639f48118f146105ef578063a457c2d7146105fa578063a9059cbb1461060d57600080fd5b80637ecebe001161015057806395d89b411161012a57806395d89b41146105c1578063983b2d56146105c95780639e4e0dae146105dc57600080fd5b80637ecebe00146105705780638933fb791461058357806390218cff146105ae57600080fd5b80637334d020116101815780637334d020146105425780637d4c9c2d146105555780637d74e25f1461056857600080fd5b806361d027b3146104c757806370a082311461050c57600080fd5b80633092afd511610255578063395093511161020957806340c10f19116101e357806340c10f19146104815780634dc32fcc146104945780635bfbec96146104a757600080fd5b8063395093511461043b5780633a55f89d1461044e5780633f4218e01461046157600080fd5b8063350ebe041161023a578063350ebe041461040d5780633644e5151461042057806336db43b51461042857600080fd5b80633092afd5146103eb578063313ce567146103fe57600080fd5b8063151dd755116102b757806323b872dd1161029157806323b872dd146103b25780632b471d8e146103c55780632e403e14146103d857600080fd5b8063151dd7551461038057806318160ddd146103a15780632342fb0e146103a957600080fd5b80630919a951116102e85780630919a95114610337578063095ea7b31461034a5780631171bda91461036d57600080fd5b806306fdde0314610304578063077f224a14610322575b600080fd5b61030c610790565b6040516103199190613e48565b60405180910390f35b610335610330366004613f95565b610822565b005b61033561034536600461400d565b610832565b61035d61035836600461402a565b610995565b6040519015158152602001610319565b61033561037b366004614056565b6109af565b61039361038e366004614097565b610b04565b604051908152602001610319565b603554610393565b61039360d25481565b61035d6103c0366004614056565b610dbe565b6103356103d33660046140ce565b610de2565b6103356103e636600461400d565b610e39565b6103356103f936600461400d565b6111e8565b60405160128152602001610319565b61033561041b3660046140fe565b6112d1565b6103936113da565b61033561043636600461402a565b6113e9565b61035d61044936600461402a565b611579565b61033561045c366004614135565b6115c0565b61039361046f36600461400d565b60d16020526000908152604090205481565b61033561048f36600461402a565b6116c3565b6103936104a236600461400d565b611716565b6103936104b5366004614135565b60d36020526000908152604090205481565b60cd546104e79073ffffffffffffffffffffffffffffffffffffffff1681565b60405173ffffffffffffffffffffffffffffffffffffffff9091168152602001610319565b61039361051a36600461400d565b73ffffffffffffffffffffffffffffffffffffffff1660009081526033602052604090205490565b61033561055036600461402a565b61175e565b610335610563366004614179565b6118f1565b610393611c59565b61039361057e36600461400d565b611c7e565b61039361059136600461402a565b60d060209081526000928352604080842090915290825290205481565b6103356105bc366004614135565b611ca9565b61030c611cb6565b6103356105d736600461400d565b611cc5565b6103356105ea3660046141d6565b611d8d565b610393633b9aca0081565b61035d61060836600461402a565b611f99565b61035d61061b36600461402a565b61206f565b61035d61062e36600461400d565b60cc6020526000908152604090205460ff1681565b6104e7610651366004614135565b61207d565b61065e6120b4565b604051610319919061420b565b6106c561067936600461400d565b60ce6020526000908152604090208054600182015460029092015490919067ffffffffffffffff81169060ff680100000000000000008204811691690100000000000000000090041685565b60408051958652602086019490945267ffffffffffffffff9092169284019290925290151560608301521515608082015260a001610319565b61039361070c366004614097565b612122565b61033561071f366004614265565b6122e7565b6103936107323660046142dc565b73ffffffffffffffffffffffffffffffffffffffff918216600090815260346020908152604080832093909416825291909152205490565b61033561077836600461400d565b6124a6565b61033561078b36600461400d565b61267a565b60606036805461079f9061430a565b80601f01602080910402602001604051908101604052809291908181526020018280546107cb9061430a565b80156108185780601f106107ed57610100808354040283529160200191610818565b820191906000526020600020905b8154815290600101906020018083116107fb57829003601f168201915b5050505050905090565b61082d838383612756565b505050565b60cd546040517f521d4de900000000000000000000000000000000000000000000000000000000815233600482015273ffffffffffffffffffffffffffffffffffffffff9091169063521d4de990602401602060405180830381865afa1580156108a0573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906108c49190614357565b6108fa576040517f99e120bc00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff8116600090815260d1602052604081205461092b9060016143a3565b73ffffffffffffffffffffffffffffffffffffffff8316600081815260d160205260409081902083905551919250907f979ef83e7e7a87cb48064e296dd7e997870d50f43acf8d7ad221313526c8ca0f906109899084815260200190565b60405180910390a25050565b6000336109a3818585612a35565b60019150505b92915050565b60cd546040517fe43581b800000000000000000000000000000000000000000000000000000000815233600482015273ffffffffffffffffffffffffffffffffffffffff9091169063e43581b890602401602060405180830381865afa158015610a1d573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610a419190614357565b610a77576040517fee3675d400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b610a9873ffffffffffffffffffffffffffffffffffffffff84168383612be0565b8173ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff167ffff3b3844276f57024e0b42afec1a37f75db36511e43819a4f2a63ab7862b64883604051610af791815260200190565b60405180910390a3505050565b73ffffffffffffffffffffffffffffffffffffffff8316600090815260ce60209081526040808320815160a081018352815481526001820154938101939093526002015467ffffffffffffffff81169183019190915260ff680100000000000000008204811615801560608501526901000000000000000000909204161515608083015280610b94575080608001515b15610bcb576040517fc1ab6dc100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015260009073ffffffffffffffffffffffffffffffffffffffff8716906370a0823190602401602060405180830381865afa158015610c38573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610c5c91906143b6565b8251909150610c6b86836143cf565b1115610c93578151811015610c8e578151610c879082906143a3565b9450610c93565b600094505b6000610ca1610e10426143e2565b73ffffffffffffffffffffffffffffffffffffffff8816600090815260d0602090815260408083208484528252909120549085015191925090610ce488836143cf565b1115610d0f5780846020015111610cfc576000610d0c565b808460200151610d0c91906143a3565b96505b610d1987826143cf565b73ffffffffffffffffffffffffffffffffffffffff8916600081815260d060209081526040808320878452909152902091909155610d599033308a612cb4565b33600090815260d16020526040812054889103610da657633b9aca00856040015167ffffffffffffffff1682610d8f919061441d565b610d9991906143e2565b610da390826143a3565b90505b610db08782612d12565b9450505050505b9392505050565b600033610dcc858285612e32565b610dd7858585612f03565b506001949350505050565b33600090815260cc602052604090205460ff16610e2b576040517ff8d2906c00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b610e3581836131b6565b5050565b60cd546040517fe43581b800000000000000000000000000000000000000000000000000000000815233600482015273ffffffffffffffffffffffffffffffffffffffff9091169063e43581b890602401602060405180830381865afa158015610ea7573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610ecb9190614357565b610f01576040517fee3675d400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015273ffffffffffffffffffffffffffffffffffffffff8216906370a0823190602401602060405180830381865afa158015610f6b573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610f8f91906143b6565b15610fc6576040517f2ef630ec00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff8116600090815260ce602052604081208181556001810182905560020180547fffffffffffffffffffffffffffffffffffffffffffff0000000000000000000016905560cf54905b61102e6001836143a3565b811015611139578273ffffffffffffffffffffffffffffffffffffffff1660cf828154811061105f5761105f614434565b60009182526020909120015473ffffffffffffffffffffffffffffffffffffffff16036111295760cf6110936001846143a3565b815481106110a3576110a3614434565b60009182526020909120015460cf805473ffffffffffffffffffffffffffffffffffffffff90921691839081106110dc576110dc614434565b9060005260206000200160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550611139565b61113281614463565b9050611023565b5060cf80548061114b5761114b61449b565b60008281526020812082017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff90810180547fffffffffffffffffffffffff000000000000000000000000000000000000000016905590910190915560405173ffffffffffffffffffffffffffffffffffffffff8416917f5c95b49c4d59d97a2f044167723f29c74b30f99702e3fd406c3830160aa9ccb891a25050565b60cd5473ffffffffffffffffffffffffffffffffffffffff16331480159061122657503373ffffffffffffffffffffffffffffffffffffffff821614155b1561125d576040517fddb5de5e00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff8116600081815260cc602052604080822080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00169055517f98c15241d6c02bc5ee0b780e11b3ea737a2defd9d04877edbe9f9497065bd02f9190a250565b33600090815260cc602052604090205460ff1661131a576040517ff8d2906c00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff16146113d05773ffffffffffffffffffffffffffffffffffffffff828116600090815260346020908152604080832093851683529290522054838110156113ba576040517f715ec26c00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6113ce83836113c987856143a3565b612a35565b505b61082d82846131b6565b60006113e46133a3565b905090565b60cd546040517f521d4de900000000000000000000000000000000000000000000000000000000815233600482015273ffffffffffffffffffffffffffffffffffffffff9091169063521d4de990602401602060405180830381865afa158015611457573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061147b9190614357565b6114b1576040517f99e120bc00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff8216600090815260ce602052604090206002015468010000000000000000900460ff1661151f576040517fc1ab6dc100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff8216600081815260ce602052604090819020839055517fe7b113fba37131b6396680a0c55790a697ec975e198ff8cfd89dac90a6379e61906109899084815260200190565b33600081815260346020908152604080832073ffffffffffffffffffffffffffffffffffffffff871684529091528120549091906109a390829086906113c99087906143cf565b60cd546040517f521d4de900000000000000000000000000000000000000000000000000000000815233600482015273ffffffffffffffffffffffffffffffffffffffff9091169063521d4de990602401602060405180830381865afa15801561162e573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906116529190614357565b611688576040517f99e120bc00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60d28190556040518181527fc3b69829afe2345596a02c8b587d41f796ba0094481d899e1b2e07b7532a1e219060200160405180910390a150565b33600090815260cc602052604090205460ff1661170c576040517ff8d2906c00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b610e358282612d12565b73ffffffffffffffffffffffffffffffffffffffff8116600090815260d06020526040812081611748610e10426143e2565b8152602001908152602001600020549050919050565b60cd546040517f521d4de900000000000000000000000000000000000000000000000000000000815233600482015273ffffffffffffffffffffffffffffffffffffffff9091169063521d4de990602401602060405180830381865afa1580156117cc573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906117f09190614357565b611826576040517f99e120bc00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff8216600090815260ce602052604090206002015468010000000000000000900460ff16611894576040517fc1ab6dc100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff8216600081815260ce602052604090819020600101839055517fe13ac9338b2ee623233f83c1b3ceab16490fa3e3737fac7f0970d0830a9f4871906109899084815260200190565b60cd546040517fe43581b800000000000000000000000000000000000000000000000000000000815233600482015273ffffffffffffffffffffffffffffffffffffffff9091169063e43581b890602401602060405180830381865afa15801561195f573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906119839190614357565b6119b9576040517fee3675d400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff8516600090815260ce602052604090206002015468010000000000000000900460ff1680611a10575073ffffffffffffffffffffffffffffffffffffffff8516155b15611a47576040517fc1ab6dc100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b633b9aca008267ffffffffffffffff161115611a8f576040517feca1d2c600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040805160a08101825260008082526020820181905291810182905260608101829052608081019190915284815260208082018581528315156080840190815267ffffffffffffffff808716604080870191825260016060880181815273ffffffffffffffffffffffffffffffffffffffff8e16600081815260ce9099528389208a5181559751888401559351600290970180549151965115156901000000000000000000027fffffffffffffffffffffffffffffffffffffffffffff00ffffffffffffffffff97151568010000000000000000027fffffffffffffffffffffffffffffffffffffffffffffff000000000000000000909316989096169790971717949094169290921790935560cf805492830181559093527facb8d954e2cfef495862221e91bd7523613cf8808827cb33edfe4904cc51bf290180547fffffffffffffffffffffffff0000000000000000000000000000000000000000168217905590517f53087ff85d80a7671594bd2e86b92af22e0b3c2c441c8033bba7399b7b5cbe2390611c49908890889088908890938452602084019290925267ffffffffffffffff1660408301521515606082015260800190565b60405180910390a2505050505050565b600060d381611c6a610e10426143e2565b815260200190815260200160002054905090565b73ffffffffffffffffffffffffffffffffffffffff81166000908152609960205260408120546109a9565b611cb333826131b6565b50565b60606037805461079f9061430a565b60cd5473ffffffffffffffffffffffffffffffffffffffff163314611d16576040517fb90cdbb100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff8116600081815260cc602052604080822080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00166001179055517f98c15241d6c02bc5ee0b780e11b3ea737a2defd9d04877edbe9f9497065bd02f9190a250565b60cd546040517f521d4de900000000000000000000000000000000000000000000000000000000815233600482015273ffffffffffffffffffffffffffffffffffffffff9091169063521d4de990602401602060405180830381865afa158015611dfb573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611e1f9190614357565b611e55576040517f99e120bc00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff8216600090815260ce602052604090206002015468010000000000000000900460ff16611ec3576040517fc1ab6dc100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b633b9aca008167ffffffffffffffff161115611f0b576040517feca1d2c600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff8216600081815260ce602090815260409182902060020180547fffffffffffffffffffffffffffffffffffffffffffffffff00000000000000001667ffffffffffffffff861690811790915591519182527f901f9de19b475adc8da4110434b8df940dce085afd05e2281c86807f3a899d299101610989565b33600081815260346020908152604080832073ffffffffffffffffffffffffffffffffffffffff8716845290915281205490919083811015612062576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602560248201527f45524332303a2064656372656173656420616c6c6f77616e63652062656c6f7760448201527f207a65726f00000000000000000000000000000000000000000000000000000060648201526084015b60405180910390fd5b610dd78286868403612a35565b6000336109a3818585612f03565b60cf818154811061208d57600080fd5b60009182526020909120015473ffffffffffffffffffffffffffffffffffffffff16905081565b606060cf80548060200260200160405190810160405280929190818152602001828054801561081857602002820191906000526020600020905b815473ffffffffffffffffffffffffffffffffffffffff1681526001909101906020018083116120ee575050505050905090565b73ffffffffffffffffffffffffffffffffffffffff8316600090815260ce60209081526040808320815160a081018352815481526001820154938101939093526002015467ffffffffffffffff81169183019190915260ff6801000000000000000082048116158015606085015269010000000000000000009092041615156080830152806121b2575080608001515b156121e9576040517fc1ab6dc100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60006121f7610e10426143e2565b600081815260d36020526040812054919250906122159087906143cf565b905060d254811115612253576040517f6d43d1ac00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600082815260d36020526040902081905561226e33876131b6565b33600090815260d160205260408120548791036122bb57633b9aca00846040015167ffffffffffffffff16826122a4919061441d565b6122ae91906143e2565b6122b890826143a3565b90505b6122dc73ffffffffffffffffffffffffffffffffffffffff89168783612be0565b979650505050505050565b83421115612351576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f45524332305065726d69743a206578706972656420646561646c696e650000006044820152606401612059565b60007f6e71edae12b1b97f4d1f60370fef10105fa2faae0126114a169c64845d6126c98888886123808c61341e565b60408051602081019690965273ffffffffffffffffffffffffffffffffffffffff94851690860152929091166060840152608083015260a082015260c0810186905260e00160405160208183030381529060405280519060200120905060006123e882613453565b905060006123f8828787876134bc565b90508973ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff161461248f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601e60248201527f45524332305065726d69743a20696e76616c6964207369676e617475726500006044820152606401612059565b61249a8a8a8a612a35565b50505050505050505050565b60cd546040517f521d4de900000000000000000000000000000000000000000000000000000000815233600482015273ffffffffffffffffffffffffffffffffffffffff9091169063521d4de990602401602060405180830381865afa158015612514573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906125389190614357565b61256e576040517f99e120bc00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff8116600090815260ce602052604090206002015468010000000000000000900460ff166125dc576040517fc1ab6dc100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff8116600081815260ce602090815260409182902060020180547fffffffffffffffffffffffffffffffffffffffffffff00ffffffffffffffffff811669010000000000000000009182900460ff16801592830291909117909255925192835292917ff7c93079dcbf699749d66345a351afab7d24219bb1d915c9f4fc4cf03f00d3979101610989565b60cd5473ffffffffffffffffffffffffffffffffffffffff1633146126cb576040517fb90cdbb100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60cd80547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83169081179091556040517f7dae230f18360d76a040c81f050aa14eb9d6dc7901b20fc5d855e2a20fe814d190600090a250565b73ffffffffffffffffffffffffffffffffffffffff163b151590565b600054610100900460ff16158080156127765750600054600160ff909116105b806127905750303b158015612790575060005460ff166001145b61281c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201527f647920696e697469616c697a65640000000000000000000000000000000000006064820152608401612059565b600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00166001179055801561287a57600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff166101001790555b3073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1663e9cbd8226040518163ffffffff1660e01b8152600401602060405180830381865afa1580156128dc573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061290091906144ca565b73ffffffffffffffffffffffffffffffffffffffff161461294d576040517f14bcf5c800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b612956846134e4565b61296084846135ba565b60cd80547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff84169081179091556040517f7dae230f18360d76a040c81f050aa14eb9d6dc7901b20fc5d855e2a20fe814d190600090a28015612a2f57600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15b50505050565b73ffffffffffffffffffffffffffffffffffffffff8316612ad7576040517f08c379a0000000000000000000000000000000000000000000000000000000008152602060048201526024808201527f45524332303a20617070726f76652066726f6d20746865207a65726f2061646460448201527f72657373000000000000000000000000000000000000000000000000000000006064820152608401612059565b73ffffffffffffffffffffffffffffffffffffffff8216612b7a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602260248201527f45524332303a20617070726f766520746f20746865207a65726f20616464726560448201527f73730000000000000000000000000000000000000000000000000000000000006064820152608401612059565b73ffffffffffffffffffffffffffffffffffffffff83811660008181526034602090815260408083209487168084529482529182902085905590518481527f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b9259101610af7565b60405173ffffffffffffffffffffffffffffffffffffffff831660248201526044810182905261082d9084907fa9059cbb00000000000000000000000000000000000000000000000000000000906064015b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff000000000000000000000000000000000000000000000000000000009093169290921790915261365b565b60405173ffffffffffffffffffffffffffffffffffffffff80851660248301528316604482015260648101829052612a2f9085907f23b872dd0000000000000000000000000000000000000000000000000000000090608401612c32565b73ffffffffffffffffffffffffffffffffffffffff8216612d8f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601f60248201527f45524332303a206d696e7420746f20746865207a65726f2061646472657373006044820152606401612059565b8060356000828254612da191906143cf565b909155505073ffffffffffffffffffffffffffffffffffffffff821660009081526033602052604081208054839290612ddb9084906143cf565b909155505060405181815273ffffffffffffffffffffffffffffffffffffffff8316906000907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef9060200160405180910390a35050565b73ffffffffffffffffffffffffffffffffffffffff8381166000908152603460209081526040808320938616835292905220547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8114612a2f5781811015612ef6576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f45524332303a20696e73756666696369656e7420616c6c6f77616e63650000006044820152606401612059565b612a2f8484848403612a35565b73ffffffffffffffffffffffffffffffffffffffff8316612fa6576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602560248201527f45524332303a207472616e736665722066726f6d20746865207a65726f20616460448201527f64726573730000000000000000000000000000000000000000000000000000006064820152608401612059565b73ffffffffffffffffffffffffffffffffffffffff8216613049576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602360248201527f45524332303a207472616e7366657220746f20746865207a65726f206164647260448201527f65737300000000000000000000000000000000000000000000000000000000006064820152608401612059565b73ffffffffffffffffffffffffffffffffffffffff8316600090815260336020526040902054818110156130ff576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f45524332303a207472616e7366657220616d6f756e742065786365656473206260448201527f616c616e636500000000000000000000000000000000000000000000000000006064820152608401612059565b73ffffffffffffffffffffffffffffffffffffffff8085166000908152603360205260408082208585039055918516815290812080548492906131439084906143cf565b925050819055508273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef846040516131a991815260200190565b60405180910390a3612a2f565b73ffffffffffffffffffffffffffffffffffffffff8216613259576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602160248201527f45524332303a206275726e2066726f6d20746865207a65726f2061646472657360448201527f73000000000000000000000000000000000000000000000000000000000000006064820152608401612059565b73ffffffffffffffffffffffffffffffffffffffff82166000908152603360205260409020548181101561330f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602260248201527f45524332303a206275726e20616d6f756e7420657863656564732062616c616e60448201527f63650000000000000000000000000000000000000000000000000000000000006064820152608401612059565b73ffffffffffffffffffffffffffffffffffffffff8316600090815260336020526040812083830390556035805484929061334b9084906143a3565b909155505060405182815260009073ffffffffffffffffffffffffffffffffffffffff8516907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef9060200160405180910390a3505050565b60006113e47f8b73c3c69bb8fe3d512ecc4cf759cc79239f7b179b0ffacaa9a75d522b39400f6133d260655490565b6066546040805160208101859052908101839052606081018290524660808201523060a082015260009060c0016040516020818303038152906040528051906020012090509392505050565b73ffffffffffffffffffffffffffffffffffffffff811660009081526099602052604090208054600181018255905b50919050565b60006109a96134606133a3565b836040517f19010000000000000000000000000000000000000000000000000000000000006020820152602281018390526042810182905260009060620160405160208183030381529060405280519060200120905092915050565b60008060006134cd87878787613767565b915091506134da8161387f565b5095945050505050565b600054610100900460ff1661357b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201527f6e697469616c697a696e670000000000000000000000000000000000000000006064820152608401612059565b611cb3816040518060400160405280600181526020017f3100000000000000000000000000000000000000000000000000000000000000815250613ad3565b600054610100900460ff16613651576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201527f6e697469616c697a696e670000000000000000000000000000000000000000006064820152608401612059565b610e358282613b84565b60006136bd826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c65648152508573ffffffffffffffffffffffffffffffffffffffff16613c349092919063ffffffff16565b80519091501561082d57808060200190518101906136db9190614357565b61082d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e60448201527f6f742073756363656564000000000000000000000000000000000000000000006064820152608401612059565b6000807f7fffffffffffffffffffffffffffffff5d576e7357a4501ddfe92f46681b20a083111561379e5750600090506003613876565b8460ff16601b141580156137b657508460ff16601c14155b156137c75750600090506004613876565b6040805160008082526020820180845289905260ff881692820192909252606081018690526080810185905260019060a0016020604051602081039080840390855afa15801561381b573d6000803e3d6000fd5b50506040517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0015191505073ffffffffffffffffffffffffffffffffffffffff811661386f57600060019250925050613876565b9150600090505b94509492505050565b6000816004811115613893576138936144e7565b0361389b5750565b60018160048111156138af576138af6144e7565b03613916576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601860248201527f45434453413a20696e76616c6964207369676e617475726500000000000000006044820152606401612059565b600281600481111561392a5761392a6144e7565b03613991576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601f60248201527f45434453413a20696e76616c6964207369676e6174757265206c656e677468006044820152606401612059565b60038160048111156139a5576139a56144e7565b03613a32576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602260248201527f45434453413a20696e76616c6964207369676e6174757265202773272076616c60448201527f75650000000000000000000000000000000000000000000000000000000000006064820152608401612059565b6004816004811115613a4657613a466144e7565b03611cb3576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602260248201527f45434453413a20696e76616c6964207369676e6174757265202776272076616c60448201527f75650000000000000000000000000000000000000000000000000000000000006064820152608401612059565b600054610100900460ff16613b6a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201527f6e697469616c697a696e670000000000000000000000000000000000000000006064820152608401612059565b815160209283012081519190920120606591909155606655565b600054610100900460ff16613c1b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201527f6e697469616c697a696e670000000000000000000000000000000000000000006064820152608401612059565b6036613c278382614564565b50603761082d8282614564565b6060613c438484600085613c4b565b949350505050565b606082471015613cdd576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f60448201527f722063616c6c00000000000000000000000000000000000000000000000000006064820152608401612059565b73ffffffffffffffffffffffffffffffffffffffff85163b613d5b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006044820152606401612059565b6000808673ffffffffffffffffffffffffffffffffffffffff168587604051613d84919061467e565b60006040518083038185875af1925050503d8060008114613dc1576040519150601f19603f3d011682016040523d82523d6000602084013e613dc6565b606091505b50915091506122dc82828660608315613de0575081610db7565b825115613df05782518084602001fd5b816040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016120599190613e48565b60005b83811015613e3f578181015183820152602001613e27565b50506000910152565b6020815260008251806020840152613e67816040850160208701613e24565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169190910160400192915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b600082601f830112613ed957600080fd5b813567ffffffffffffffff80821115613ef457613ef4613e99565b604051601f83017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0908116603f01168101908282118183101715613f3a57613f3a613e99565b81604052838152866020858801011115613f5357600080fd5b836020870160208301376000602085830101528094505050505092915050565b73ffffffffffffffffffffffffffffffffffffffff81168114611cb357600080fd5b600080600060608486031215613faa57600080fd5b833567ffffffffffffffff80821115613fc257600080fd5b613fce87838801613ec8565b94506020860135915080821115613fe457600080fd5b50613ff186828701613ec8565b925050604084013561400281613f73565b809150509250925092565b60006020828403121561401f57600080fd5b8135610db781613f73565b6000806040838503121561403d57600080fd5b823561404881613f73565b946020939093013593505050565b60008060006060848603121561406b57600080fd5b833561407681613f73565b9250602084013561408681613f73565b929592945050506040919091013590565b6000806000606084860312156140ac57600080fd5b83356140b781613f73565b925060208401359150604084013561400281613f73565b600080604083850312156140e157600080fd5b8235915060208301356140f381613f73565b809150509250929050565b60008060006060848603121561411357600080fd5b83359250602084013561412581613f73565b9150604084013561400281613f73565b60006020828403121561414757600080fd5b5035919050565b803567ffffffffffffffff8116811461416657600080fd5b919050565b8015158114611cb357600080fd5b600080600080600060a0868803121561419157600080fd5b853561419c81613f73565b945060208601359350604086013592506141b86060870161414e565b915060808601356141c88161416b565b809150509295509295909350565b600080604083850312156141e957600080fd5b82356141f481613f73565b91506142026020840161414e565b90509250929050565b6020808252825182820181905260009190848201906040850190845b8181101561425957835173ffffffffffffffffffffffffffffffffffffffff1683529284019291840191600101614227565b50909695505050505050565b600080600080600080600060e0888a03121561428057600080fd5b873561428b81613f73565b9650602088013561429b81613f73565b95506040880135945060608801359350608088013560ff811681146142bf57600080fd5b9699959850939692959460a0840135945060c09093013592915050565b600080604083850312156142ef57600080fd5b82356142fa81613f73565b915060208301356140f381613f73565b600181811c9082168061431e57607f821691505b60208210810361344d577f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b60006020828403121561436957600080fd5b8151610db78161416b565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b818103818111156109a9576109a9614374565b6000602082840312156143c857600080fd5b5051919050565b808201808211156109a9576109a9614374565b600082614418577f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b500490565b80820281158282048414176109a9576109a9614374565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff820361449457614494614374565b5060010190565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603160045260246000fd5b6000602082840312156144dc57600080fd5b8151610db781613f73565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b601f82111561082d57600081815260208120601f850160051c8101602086101561453d5750805b601f850160051c820191505b8181101561455c57828155600101614549565b505050505050565b815167ffffffffffffffff81111561457e5761457e613e99565b6145928161458c845461430a565b84614516565b602080601f8311600181146145e557600084156145af5750858301515b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600386901b1c1916600185901b17855561455c565b6000858152602081207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08616915b8281101561463257888601518255948401946001909101908401614613565b508582101561466e57878501517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600388901b60f8161c191681555b5050505050600190811b01905550565b60008251614690818460208701613e24565b919091019291505056fea2646970667358221220f2eb02bac1667a72be85ab617a5b5aa3d8f7a9b09b4d1fde9756b7a5636daf2164736f6c63430008110033", "devdoc": { - "author": "Angle Core Team", - "details": "This contract supports bridge tokens having a minting right on the stablecoin (also referred to as the canonical or the native token)References: - FRAX implementation: https://polygonscan.com/address/0x45c32fA6DF82ead1e2EF74d17b76547EDdFaFF89#code - QiDAO implementation: https://snowtrace.io/address/0x5c49b268c9841AFF1Cc3B0a418ff5c3442eE3F3b#code", + "author": "Angle Labs, Inc.", + "details": "This contract supports bridge tokens having a minting right on the stablecoin (also referred to as the canonical or the native token)", "kind": "dev", "methods": { "DOMAIN_SEPARATOR()": { @@ -1250,7 +1276,7 @@ "details": "See {IERC20-allowance}." }, "approve(address,uint256)": { - "details": "See {IERC20-approve}. Requirements: - `spender` cannot be the zero address." + "details": "See {IERC20-approve}. NOTE: If `amount` is the maximum `uint256`, the allowance is not updated on `transferFrom`. This is semantically equivalent to an infinite approval. Requirements: - `spender` cannot be the zero address." }, "balanceOf(address)": { "details": "See {IERC20-balanceOf}." @@ -1294,14 +1320,6 @@ "increaseAllowance(address,uint256)": { "details": "Atomically increases the allowance granted to `spender` by the caller. This is an alternative to {approve} that can be used as a mitigation for problems described in {IERC20-approve}. Emits an {Approval} event indicating the updated allowance. Requirements: - `spender` cannot be the zero address." }, - "initialize(string,string,address)": { - "details": "By default, agTokens are ERC-20 tokens with 18 decimals", - "params": { - "_treasury": "Reference to the `Treasury` contract associated to this agToken", - "name_": "Name of the token", - "symbol_": "Symbol of the token" - } - }, "mint(address,uint256)": { "details": "The contracts allowed to issue agTokens are the `StableMaster` contract, `VaultManager` contracts associated to this stablecoin as well as the flash loan module (if activated) and potentially contracts whitelisted by governance", "params": { @@ -1366,10 +1384,10 @@ "details": "See {IERC20-totalSupply}." }, "transfer(address,uint256)": { - "details": "See {IERC20-transfer}. Requirements: - `recipient` cannot be the zero address. - the caller must have a balance of at least `amount`." + "details": "See {IERC20-transfer}. Requirements: - `to` cannot be the zero address. - the caller must have a balance of at least `amount`." }, "transferFrom(address,address,uint256)": { - "details": "See {IERC20-transferFrom}. Emits an {Approval} event indicating the updated allowance. This is not required by the EIP. See the note at the beginning of {ERC20}. Requirements: - `sender` and `recipient` cannot be the zero address. - `sender` must have a balance of at least `amount`. - the caller must have allowance for ``sender``'s tokens of at least `amount`." + "details": "See {IERC20-transferFrom}. Emits an {Approval} event indicating the updated allowance. This is not required by the EIP. See the note at the beginning of {ERC20}. NOTE: Does not update the allowance if the current allowance is the maximum `uint256`. Requirements: - `from` and `to` cannot be the zero address. - `from` must have a balance of at least `amount`. - the caller must have allowance for ``from``'s tokens of at least `amount`." } }, "title": "AgTokenSideChainMultiBridge", @@ -1403,7 +1421,7 @@ "notice": "Burns `amount` tokens from a `burner` address" }, "burnStablecoin(uint256)": { - "notice": "Allows anyone to burn agToken without redeeming collateral back" + "notice": "Allows anyone to burn stablecoins" }, "chainTotalHourlyLimit()": { "notice": "Limit to the amount of tokens that can be sent from that chain to another chain" @@ -1478,15 +1496,15 @@ "storageLayout": { "storage": [ { - "astId": 772, + "astId": 770, "contract": "contracts/agToken/AgTokenSideChainMultiBridge.sol:AgTokenSideChainMultiBridge", "label": "_initialized", "offset": 0, "slot": "0", - "type": "t_bool" + "type": "t_uint8" }, { - "astId": 775, + "astId": 773, "contract": "contracts/agToken/AgTokenSideChainMultiBridge.sol:AgTokenSideChainMultiBridge", "label": "_initializing", "offset": 1, @@ -1494,7 +1512,7 @@ "type": "t_bool" }, { - "astId": 2592, + "astId": 2486, "contract": "contracts/agToken/AgTokenSideChainMultiBridge.sol:AgTokenSideChainMultiBridge", "label": "__gap", "offset": 0, @@ -1502,7 +1520,7 @@ "type": "t_array(t_uint256)50_storage" }, { - "astId": 1029, + "astId": 1119, "contract": "contracts/agToken/AgTokenSideChainMultiBridge.sol:AgTokenSideChainMultiBridge", "label": "_balances", "offset": 0, @@ -1510,7 +1528,7 @@ "type": "t_mapping(t_address,t_uint256)" }, { - "astId": 1035, + "astId": 1125, "contract": "contracts/agToken/AgTokenSideChainMultiBridge.sol:AgTokenSideChainMultiBridge", "label": "_allowances", "offset": 0, @@ -1518,7 +1536,7 @@ "type": "t_mapping(t_address,t_mapping(t_address,t_uint256))" }, { - "astId": 1037, + "astId": 1127, "contract": "contracts/agToken/AgTokenSideChainMultiBridge.sol:AgTokenSideChainMultiBridge", "label": "_totalSupply", "offset": 0, @@ -1526,7 +1544,7 @@ "type": "t_uint256" }, { - "astId": 1039, + "astId": 1129, "contract": "contracts/agToken/AgTokenSideChainMultiBridge.sol:AgTokenSideChainMultiBridge", "label": "_name", "offset": 0, @@ -1534,7 +1552,7 @@ "type": "t_string_storage" }, { - "astId": 1041, + "astId": 1131, "contract": "contracts/agToken/AgTokenSideChainMultiBridge.sol:AgTokenSideChainMultiBridge", "label": "_symbol", "offset": 0, @@ -1542,7 +1560,7 @@ "type": "t_string_storage" }, { - "astId": 1582, + "astId": 1710, "contract": "contracts/agToken/AgTokenSideChainMultiBridge.sol:AgTokenSideChainMultiBridge", "label": "__gap", "offset": 0, @@ -1550,7 +1568,7 @@ "type": "t_array(t_uint256)45_storage" }, { - "astId": 3269, + "astId": 3203, "contract": "contracts/agToken/AgTokenSideChainMultiBridge.sol:AgTokenSideChainMultiBridge", "label": "_HASHED_NAME", "offset": 0, @@ -1558,7 +1576,7 @@ "type": "t_bytes32" }, { - "astId": 3271, + "astId": 3205, "contract": "contracts/agToken/AgTokenSideChainMultiBridge.sol:AgTokenSideChainMultiBridge", "label": "_HASHED_VERSION", "offset": 0, @@ -1566,7 +1584,7 @@ "type": "t_bytes32" }, { - "astId": 3408, + "astId": 3343, "contract": "contracts/agToken/AgTokenSideChainMultiBridge.sol:AgTokenSideChainMultiBridge", "label": "__gap", "offset": 0, @@ -1574,23 +1592,23 @@ "type": "t_array(t_uint256)50_storage" }, { - "astId": 1712, + "astId": 1840, "contract": "contracts/agToken/AgTokenSideChainMultiBridge.sol:AgTokenSideChainMultiBridge", "label": "_nonces", "offset": 0, "slot": "153", - "type": "t_mapping(t_address,t_struct(Counter)2599_storage)" + "type": "t_mapping(t_address,t_struct(Counter)2493_storage)" }, { - "astId": 1714, + "astId": 1848, "contract": "contracts/agToken/AgTokenSideChainMultiBridge.sol:AgTokenSideChainMultiBridge", - "label": "_PERMIT_TYPEHASH", + "label": "_PERMIT_TYPEHASH_DEPRECATED_SLOT", "offset": 0, "slot": "154", "type": "t_bytes32" }, { - "astId": 1882, + "astId": 2004, "contract": "contracts/agToken/AgTokenSideChainMultiBridge.sol:AgTokenSideChainMultiBridge", "label": "__gap", "offset": 0, @@ -1598,7 +1616,7 @@ "type": "t_array(t_uint256)49_storage" }, { - "astId": 8835, + "astId": 7427, "contract": "contracts/agToken/AgTokenSideChainMultiBridge.sol:AgTokenSideChainMultiBridge", "label": "isMinter", "offset": 0, @@ -1606,7 +1624,7 @@ "type": "t_mapping(t_address,t_bool)" }, { - "astId": 8838, + "astId": 7430, "contract": "contracts/agToken/AgTokenSideChainMultiBridge.sol:AgTokenSideChainMultiBridge", "label": "treasury", "offset": 0, @@ -1614,15 +1632,15 @@ "type": "t_address" }, { - "astId": 7979, + "astId": 7739, "contract": "contracts/agToken/AgTokenSideChainMultiBridge.sol:AgTokenSideChainMultiBridge", "label": "bridges", "offset": 0, "slot": "206", - "type": "t_mapping(t_address,t_struct(BridgeDetails)7973_storage)" + "type": "t_mapping(t_address,t_struct(BridgeDetails)7733_storage)" }, { - "astId": 7983, + "astId": 7743, "contract": "contracts/agToken/AgTokenSideChainMultiBridge.sol:AgTokenSideChainMultiBridge", "label": "bridgeTokensList", "offset": 0, @@ -1630,7 +1648,7 @@ "type": "t_array(t_address)dyn_storage" }, { - "astId": 7990, + "astId": 7750, "contract": "contracts/agToken/AgTokenSideChainMultiBridge.sol:AgTokenSideChainMultiBridge", "label": "usage", "offset": 0, @@ -1638,7 +1656,7 @@ "type": "t_mapping(t_address,t_mapping(t_uint256,t_uint256))" }, { - "astId": 7995, + "astId": 7755, "contract": "contracts/agToken/AgTokenSideChainMultiBridge.sol:AgTokenSideChainMultiBridge", "label": "isFeeExempt", "offset": 0, @@ -1646,7 +1664,7 @@ "type": "t_mapping(t_address,t_uint256)" }, { - "astId": 7998, + "astId": 7758, "contract": "contracts/agToken/AgTokenSideChainMultiBridge.sol:AgTokenSideChainMultiBridge", "label": "chainTotalHourlyLimit", "offset": 0, @@ -1654,7 +1672,7 @@ "type": "t_uint256" }, { - "astId": 8003, + "astId": 7763, "contract": "contracts/agToken/AgTokenSideChainMultiBridge.sol:AgTokenSideChainMultiBridge", "label": "chainTotalUsage", "offset": 0, @@ -1723,19 +1741,19 @@ "numberOfBytes": "32", "value": "t_mapping(t_uint256,t_uint256)" }, - "t_mapping(t_address,t_struct(BridgeDetails)7973_storage)": { + "t_mapping(t_address,t_struct(BridgeDetails)7733_storage)": { "encoding": "mapping", "key": "t_address", "label": "mapping(address => struct AgTokenSideChainMultiBridge.BridgeDetails)", "numberOfBytes": "32", - "value": "t_struct(BridgeDetails)7973_storage" + "value": "t_struct(BridgeDetails)7733_storage" }, - "t_mapping(t_address,t_struct(Counter)2599_storage)": { + "t_mapping(t_address,t_struct(Counter)2493_storage)": { "encoding": "mapping", "key": "t_address", "label": "mapping(address => struct CountersUpgradeable.Counter)", "numberOfBytes": "32", - "value": "t_struct(Counter)2599_storage" + "value": "t_struct(Counter)2493_storage" }, "t_mapping(t_address,t_uint256)": { "encoding": "mapping", @@ -1756,12 +1774,12 @@ "label": "string", "numberOfBytes": "32" }, - "t_struct(BridgeDetails)7973_storage": { + "t_struct(BridgeDetails)7733_storage": { "encoding": "inplace", "label": "struct AgTokenSideChainMultiBridge.BridgeDetails", "members": [ { - "astId": 7964, + "astId": 7724, "contract": "contracts/agToken/AgTokenSideChainMultiBridge.sol:AgTokenSideChainMultiBridge", "label": "limit", "offset": 0, @@ -1769,7 +1787,7 @@ "type": "t_uint256" }, { - "astId": 7966, + "astId": 7726, "contract": "contracts/agToken/AgTokenSideChainMultiBridge.sol:AgTokenSideChainMultiBridge", "label": "hourlyLimit", "offset": 0, @@ -1777,7 +1795,7 @@ "type": "t_uint256" }, { - "astId": 7968, + "astId": 7728, "contract": "contracts/agToken/AgTokenSideChainMultiBridge.sol:AgTokenSideChainMultiBridge", "label": "fee", "offset": 0, @@ -1785,7 +1803,7 @@ "type": "t_uint64" }, { - "astId": 7970, + "astId": 7730, "contract": "contracts/agToken/AgTokenSideChainMultiBridge.sol:AgTokenSideChainMultiBridge", "label": "allowed", "offset": 8, @@ -1793,7 +1811,7 @@ "type": "t_bool" }, { - "astId": 7972, + "astId": 7732, "contract": "contracts/agToken/AgTokenSideChainMultiBridge.sol:AgTokenSideChainMultiBridge", "label": "paused", "offset": 9, @@ -1803,12 +1821,12 @@ ], "numberOfBytes": "96" }, - "t_struct(Counter)2599_storage": { + "t_struct(Counter)2493_storage": { "encoding": "inplace", "label": "struct CountersUpgradeable.Counter", "members": [ { - "astId": 2598, + "astId": 2492, "contract": "contracts/agToken/AgTokenSideChainMultiBridge.sol:AgTokenSideChainMultiBridge", "label": "_value", "offset": 0, @@ -1827,6 +1845,11 @@ "encoding": "inplace", "label": "uint64", "numberOfBytes": "8" + }, + "t_uint8": { + "encoding": "inplace", + "label": "uint8", + "numberOfBytes": "1" } } } diff --git a/deployments/avalanche/CoreBorrowTest.json b/deployments/avalanche/CoreBorrowTest.json new file mode 100644 index 00000000..7bf6f1ee --- /dev/null +++ b/deployments/avalanche/CoreBorrowTest.json @@ -0,0 +1,325 @@ +{ + "address": "0xE8426450d46F4ED4e667e96C7Ea53bAe518FF8eb", + "abi": [ + { + "inputs": [ + { + "internalType": "address", + "name": "_logic", + "type": "address" + }, + { + "internalType": "address", + "name": "admin_", + "type": "address" + }, + { + "internalType": "bytes", + "name": "_data", + "type": "bytes" + } + ], + "stateMutability": "payable", + "type": "constructor" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "previousAdmin", + "type": "address" + }, + { + "indexed": false, + "internalType": "address", + "name": "newAdmin", + "type": "address" + } + ], + "name": "AdminChanged", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "beacon", + "type": "address" + } + ], + "name": "BeaconUpgraded", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "implementation", + "type": "address" + } + ], + "name": "Upgraded", + "type": "event" + }, + { + "stateMutability": "payable", + "type": "fallback" + }, + { + "inputs": [], + "name": "admin", + "outputs": [ + { + "internalType": "address", + "name": "admin_", + "type": "address" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "newAdmin", + "type": "address" + } + ], + "name": "changeAdmin", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "implementation", + "outputs": [ + { + "internalType": "address", + "name": "implementation_", + "type": "address" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "newImplementation", + "type": "address" + } + ], + "name": "upgradeTo", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "newImplementation", + "type": "address" + }, + { + "internalType": "bytes", + "name": "data", + "type": "bytes" + } + ], + "name": "upgradeToAndCall", + "outputs": [], + "stateMutability": "payable", + "type": "function" + }, + { + "stateMutability": "payable", + "type": "receive" + } + ], + "transactionHash": "0x2d6e0a217b96d3dffd069fa64ea57bb8f857dcfa57c54b4391ce6c0e33ec7c7f", + "receipt": { + "to": null, + "from": "0xfdA462548Ce04282f4B6D6619823a7C64Fdc0185", + "contractAddress": "0xE8426450d46F4ED4e667e96C7Ea53bAe518FF8eb", + "transactionIndex": 12, + "gasUsed": "1037362", + "logsBloom": "0x00080004000000000800000400000800480000000000000000000000200000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000020000400000000000000800000000800000000000000000000000000000000000020000000000000000200000000003000000000000000000804000000000000000000000000000000000000000000000000000001000000000001000000020020000000000008000000010000800000400000100040000000220000000800000000000000000000000040400000000000000000000000000040000", + "blockHash": "0xc14711e885c08e349e202c4dbaaf16c40568fb145b901bce8d24c2019c63df3e", + "transactionHash": "0x2d6e0a217b96d3dffd069fa64ea57bb8f857dcfa57c54b4391ce6c0e33ec7c7f", + "logs": [ + { + "transactionIndex": 12, + "blockNumber": 40179204, + "transactionHash": "0x2d6e0a217b96d3dffd069fa64ea57bb8f857dcfa57c54b4391ce6c0e33ec7c7f", + "address": "0xE8426450d46F4ED4e667e96C7Ea53bAe518FF8eb", + "topics": [ + "0xbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b", + "0x0000000000000000000000001033dd8415a282db52f14902e91de6e91868ac6d" + ], + "data": "0x", + "logIndex": 25, + "blockHash": "0xc14711e885c08e349e202c4dbaaf16c40568fb145b901bce8d24c2019c63df3e" + }, + { + "transactionIndex": 12, + "blockNumber": 40179204, + "transactionHash": "0x2d6e0a217b96d3dffd069fa64ea57bb8f857dcfa57c54b4391ce6c0e33ec7c7f", + "address": "0xE8426450d46F4ED4e667e96C7Ea53bAe518FF8eb", + "topics": [ + "0x2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d", + "0x7935bd0ae54bc31f548c14dba4d37c5c64b3f8ca900cb468fb8abd54d5894f55", + "0x000000000000000000000000fda462548ce04282f4b6d6619823a7c64fdc0185", + "0x000000000000000000000000fda462548ce04282f4b6d6619823a7c64fdc0185" + ], + "data": "0x", + "logIndex": 26, + "blockHash": "0xc14711e885c08e349e202c4dbaaf16c40568fb145b901bce8d24c2019c63df3e" + }, + { + "transactionIndex": 12, + "blockNumber": 40179204, + "transactionHash": "0x2d6e0a217b96d3dffd069fa64ea57bb8f857dcfa57c54b4391ce6c0e33ec7c7f", + "address": "0xE8426450d46F4ED4e667e96C7Ea53bAe518FF8eb", + "topics": [ + "0x2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d", + "0x55435dd261a4b9b3364963f7738a7a662ad9c84396d64be3365284bb7f0a5041", + "0x000000000000000000000000ccd44983f597ae4d4e2b70cf979597d63a10870d", + "0x000000000000000000000000fda462548ce04282f4b6d6619823a7c64fdc0185" + ], + "data": "0x", + "logIndex": 27, + "blockHash": "0xc14711e885c08e349e202c4dbaaf16c40568fb145b901bce8d24c2019c63df3e" + }, + { + "transactionIndex": 12, + "blockNumber": 40179204, + "transactionHash": "0x2d6e0a217b96d3dffd069fa64ea57bb8f857dcfa57c54b4391ce6c0e33ec7c7f", + "address": "0xE8426450d46F4ED4e667e96C7Ea53bAe518FF8eb", + "topics": [ + "0x2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d", + "0x55435dd261a4b9b3364963f7738a7a662ad9c84396d64be3365284bb7f0a5041", + "0x000000000000000000000000fda462548ce04282f4b6d6619823a7c64fdc0185", + "0x000000000000000000000000fda462548ce04282f4b6d6619823a7c64fdc0185" + ], + "data": "0x", + "logIndex": 28, + "blockHash": "0xc14711e885c08e349e202c4dbaaf16c40568fb145b901bce8d24c2019c63df3e" + }, + { + "transactionIndex": 12, + "blockNumber": 40179204, + "transactionHash": "0x2d6e0a217b96d3dffd069fa64ea57bb8f857dcfa57c54b4391ce6c0e33ec7c7f", + "address": "0xE8426450d46F4ED4e667e96C7Ea53bAe518FF8eb", + "topics": [ + "0xbd79b86ffe0ab8e8776151514217cd7cacd52c909f66475c3af44e129f0b00ff", + "0x55435dd261a4b9b3364963f7738a7a662ad9c84396d64be3365284bb7f0a5041", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x7935bd0ae54bc31f548c14dba4d37c5c64b3f8ca900cb468fb8abd54d5894f55" + ], + "data": "0x", + "logIndex": 29, + "blockHash": "0xc14711e885c08e349e202c4dbaaf16c40568fb145b901bce8d24c2019c63df3e" + }, + { + "transactionIndex": 12, + "blockNumber": 40179204, + "transactionHash": "0x2d6e0a217b96d3dffd069fa64ea57bb8f857dcfa57c54b4391ce6c0e33ec7c7f", + "address": "0xE8426450d46F4ED4e667e96C7Ea53bAe518FF8eb", + "topics": [ + "0xbd79b86ffe0ab8e8776151514217cd7cacd52c909f66475c3af44e129f0b00ff", + "0x7935bd0ae54bc31f548c14dba4d37c5c64b3f8ca900cb468fb8abd54d5894f55", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x7935bd0ae54bc31f548c14dba4d37c5c64b3f8ca900cb468fb8abd54d5894f55" + ], + "data": "0x", + "logIndex": 30, + "blockHash": "0xc14711e885c08e349e202c4dbaaf16c40568fb145b901bce8d24c2019c63df3e" + }, + { + "transactionIndex": 12, + "blockNumber": 40179204, + "transactionHash": "0x2d6e0a217b96d3dffd069fa64ea57bb8f857dcfa57c54b4391ce6c0e33ec7c7f", + "address": "0xE8426450d46F4ED4e667e96C7Ea53bAe518FF8eb", + "topics": [ + "0xbd79b86ffe0ab8e8776151514217cd7cacd52c909f66475c3af44e129f0b00ff", + "0x0ae0130c6b34f32239dfe5e419a3fbd7546b44e99783257f2d93526d5a936d46", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x7935bd0ae54bc31f548c14dba4d37c5c64b3f8ca900cb468fb8abd54d5894f55" + ], + "data": "0x", + "logIndex": 31, + "blockHash": "0xc14711e885c08e349e202c4dbaaf16c40568fb145b901bce8d24c2019c63df3e" + }, + { + "transactionIndex": 12, + "blockNumber": 40179204, + "transactionHash": "0x2d6e0a217b96d3dffd069fa64ea57bb8f857dcfa57c54b4391ce6c0e33ec7c7f", + "address": "0xE8426450d46F4ED4e667e96C7Ea53bAe518FF8eb", + "topics": [ + "0x7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f" + ], + "data": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000007ab641e661a9728913a44e06f6a4879481142ddb", + "logIndex": 32, + "blockHash": "0xc14711e885c08e349e202c4dbaaf16c40568fb145b901bce8d24c2019c63df3e" + } + ], + "blockNumber": 40179204, + "cumulativeGasUsed": "3695475", + "status": 1, + "byzantium": true + }, + "args": [ + "0x1033dD8415A282Db52f14902E91DE6e91868aC6D", + "0x7AB641E661a9728913A44e06f6a4879481142DDb", + "0x485cc955000000000000000000000000fda462548ce04282f4b6d6619823a7c64fdc0185000000000000000000000000ccd44983f597ae4d4e2b70cf979597d63a10870d" + ], + "numDeployments": 1, + "solcInputHash": "871924e0c138825a2736b76def8fef8d", + "metadata": "{\"compiler\":{\"version\":\"0.8.17+commit.8df45f5f\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_logic\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"admin_\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"_data\",\"type\":\"bytes\"}],\"stateMutability\":\"payable\",\"type\":\"constructor\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"previousAdmin\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"newAdmin\",\"type\":\"address\"}],\"name\":\"AdminChanged\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"beacon\",\"type\":\"address\"}],\"name\":\"BeaconUpgraded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"implementation\",\"type\":\"address\"}],\"name\":\"Upgraded\",\"type\":\"event\"},{\"stateMutability\":\"payable\",\"type\":\"fallback\"},{\"inputs\":[],\"name\":\"admin\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"admin_\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newAdmin\",\"type\":\"address\"}],\"name\":\"changeAdmin\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"implementation\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"implementation_\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newImplementation\",\"type\":\"address\"}],\"name\":\"upgradeTo\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newImplementation\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"}],\"name\":\"upgradeToAndCall\",\"outputs\":[],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"stateMutability\":\"payable\",\"type\":\"receive\"}],\"devdoc\":{\"details\":\"This contract implements a proxy that is upgradeable by an admin. It is fully forked from OpenZeppelin `TransparentUpgradeableProxy` To avoid https://medium.com/nomic-labs-blog/malicious-backdoors-in-ethereum-proxies-62629adf3357[proxy selector clashing], which can potentially be used in an attack, this contract uses the https://blog.openzeppelin.com/the-transparent-proxy-pattern/[transparent proxy pattern]. This pattern implies two things that go hand in hand: 1. If any account other than the admin calls the proxy, the call will be forwarded to the implementation, even if that call matches one of the admin functions exposed by the proxy itself. 2. If the admin calls the proxy, it can access the admin functions, but its calls will never be forwarded to the implementation. If the admin tries to call a function on the implementation it will fail with an error that says \\\"admin cannot fallback to proxy target\\\". These properties mean that the admin account can only be used for admin actions like upgrading the proxy or changing the admin, so it's best if it's a dedicated account that is not used for anything else. This will avoid headaches due to sudden errors when trying to call a function from the proxy implementation. Our recommendation is for the dedicated account to be an instance of the {ProxyAdmin} contract. If set up this way, you should think of the `ProxyAdmin` instance as the real administrative interface of your proxy.\",\"kind\":\"dev\",\"methods\":{\"admin()\":{\"details\":\"Returns the current admin. NOTE: Only the admin can call this function. See {ProxyAdmin-getProxyAdmin}. TIP: To get this value clients can read directly from the storage slot shown below (specified by EIP1967) using the https://eth.wiki/json-rpc/API#eth_getstorageat[`eth_getStorageAt`] RPC call. `0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103`\"},\"changeAdmin(address)\":{\"details\":\"Changes the admin of the proxy. Emits an {AdminChanged} event. NOTE: Only the admin can call this function. See {ProxyAdmin-changeProxyAdmin}.\"},\"constructor\":{\"details\":\"Initializes an upgradeable proxy managed by `_admin`, backed by the implementation at `_logic`, and optionally initialized with `_data` as explained in {ERC1967Proxy-constructor}.\"},\"implementation()\":{\"details\":\"Returns the current implementation. NOTE: Only the admin can call this function. See {ProxyAdmin-getProxyImplementation}. TIP: To get this value clients can read directly from the storage slot shown below (specified by EIP1967) using the https://eth.wiki/json-rpc/API#eth_getstorageat[`eth_getStorageAt`] RPC call. `0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc`\"},\"upgradeTo(address)\":{\"details\":\"Upgrade the implementation of the proxy. NOTE: Only the admin can call this function. See {ProxyAdmin-upgrade}.\"},\"upgradeToAndCall(address,bytes)\":{\"details\":\"Upgrade the implementation of the proxy, and then call a function from the new implementation as specified by `data`, which should be an encoded function call. This is useful to initialize new storage variables in the proxied contract. NOTE: Only the admin can call this function. See {ProxyAdmin-upgradeAndCall}.\"}},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/external/TransparentUpgradeableProxy.sol\":\"TransparentUpgradeableProxy\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":1000000},\"remappings\":[]},\"sources\":{\"@openzeppelin/contracts/interfaces/draft-IERC1822.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.5.0) (interfaces/draft-IERC1822.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev ERC1822: Universal Upgradeable Proxy Standard (UUPS) documents a method for upgradeability through a simplified\\n * proxy whose upgrades are fully controlled by the current implementation.\\n */\\ninterface IERC1822Proxiable {\\n /**\\n * @dev Returns the storage slot that the proxiable contract assumes is being used to store the implementation\\n * address.\\n *\\n * IMPORTANT: A proxy pointing at a proxiable contract should not be considered proxiable itself, because this risks\\n * bricking a proxy that upgrades to it, by delegating to itself until out of gas. Thus it is critical that this\\n * function revert if invoked through a proxy.\\n */\\n function proxiableUUID() external view returns (bytes32);\\n}\\n\",\"keccak256\":\"0x1d4afe6cb24200cc4545eed814ecf5847277dfe5d613a1707aad5fceecebcfff\",\"license\":\"MIT\"},\"@openzeppelin/contracts/proxy/ERC1967/ERC1967Proxy.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.7.0) (proxy/ERC1967/ERC1967Proxy.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../Proxy.sol\\\";\\nimport \\\"./ERC1967Upgrade.sol\\\";\\n\\n/**\\n * @dev This contract implements an upgradeable proxy. It is upgradeable because calls are delegated to an\\n * implementation address that can be changed. This address is stored in storage in the location specified by\\n * https://eips.ethereum.org/EIPS/eip-1967[EIP1967], so that it doesn't conflict with the storage layout of the\\n * implementation behind the proxy.\\n */\\ncontract ERC1967Proxy is Proxy, ERC1967Upgrade {\\n /**\\n * @dev Initializes the upgradeable proxy with an initial implementation specified by `_logic`.\\n *\\n * If `_data` is nonempty, it's used as data in a delegate call to `_logic`. This will typically be an encoded\\n * function call, and allows initializing the storage of the proxy like a Solidity constructor.\\n */\\n constructor(address _logic, bytes memory _data) payable {\\n _upgradeToAndCall(_logic, _data, false);\\n }\\n\\n /**\\n * @dev Returns the current implementation address.\\n */\\n function _implementation() internal view virtual override returns (address impl) {\\n return ERC1967Upgrade._getImplementation();\\n }\\n}\\n\",\"keccak256\":\"0xa2b22da3032e50b55f95ec1d13336102d675f341167aa76db571ef7f8bb7975d\",\"license\":\"MIT\"},\"@openzeppelin/contracts/proxy/ERC1967/ERC1967Upgrade.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.5.0) (proxy/ERC1967/ERC1967Upgrade.sol)\\n\\npragma solidity ^0.8.2;\\n\\nimport \\\"../beacon/IBeacon.sol\\\";\\nimport \\\"../../interfaces/draft-IERC1822.sol\\\";\\nimport \\\"../../utils/Address.sol\\\";\\nimport \\\"../../utils/StorageSlot.sol\\\";\\n\\n/**\\n * @dev This abstract contract provides getters and event emitting update functions for\\n * https://eips.ethereum.org/EIPS/eip-1967[EIP1967] slots.\\n *\\n * _Available since v4.1._\\n *\\n * @custom:oz-upgrades-unsafe-allow delegatecall\\n */\\nabstract contract ERC1967Upgrade {\\n // This is the keccak-256 hash of \\\"eip1967.proxy.rollback\\\" subtracted by 1\\n bytes32 private constant _ROLLBACK_SLOT = 0x4910fdfa16fed3260ed0e7147f7cc6da11a60208b5b9406d12a635614ffd9143;\\n\\n /**\\n * @dev Storage slot with the address of the current implementation.\\n * This is the keccak-256 hash of \\\"eip1967.proxy.implementation\\\" subtracted by 1, and is\\n * validated in the constructor.\\n */\\n bytes32 internal constant _IMPLEMENTATION_SLOT = 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc;\\n\\n /**\\n * @dev Emitted when the implementation is upgraded.\\n */\\n event Upgraded(address indexed implementation);\\n\\n /**\\n * @dev Returns the current implementation address.\\n */\\n function _getImplementation() internal view returns (address) {\\n return StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value;\\n }\\n\\n /**\\n * @dev Stores a new address in the EIP1967 implementation slot.\\n */\\n function _setImplementation(address newImplementation) private {\\n require(Address.isContract(newImplementation), \\\"ERC1967: new implementation is not a contract\\\");\\n StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value = newImplementation;\\n }\\n\\n /**\\n * @dev Perform implementation upgrade\\n *\\n * Emits an {Upgraded} event.\\n */\\n function _upgradeTo(address newImplementation) internal {\\n _setImplementation(newImplementation);\\n emit Upgraded(newImplementation);\\n }\\n\\n /**\\n * @dev Perform implementation upgrade with additional setup call.\\n *\\n * Emits an {Upgraded} event.\\n */\\n function _upgradeToAndCall(\\n address newImplementation,\\n bytes memory data,\\n bool forceCall\\n ) internal {\\n _upgradeTo(newImplementation);\\n if (data.length > 0 || forceCall) {\\n Address.functionDelegateCall(newImplementation, data);\\n }\\n }\\n\\n /**\\n * @dev Perform implementation upgrade with security checks for UUPS proxies, and additional setup call.\\n *\\n * Emits an {Upgraded} event.\\n */\\n function _upgradeToAndCallUUPS(\\n address newImplementation,\\n bytes memory data,\\n bool forceCall\\n ) internal {\\n // Upgrades from old implementations will perform a rollback test. This test requires the new\\n // implementation to upgrade back to the old, non-ERC1822 compliant, implementation. Removing\\n // this special case will break upgrade paths from old UUPS implementation to new ones.\\n if (StorageSlot.getBooleanSlot(_ROLLBACK_SLOT).value) {\\n _setImplementation(newImplementation);\\n } else {\\n try IERC1822Proxiable(newImplementation).proxiableUUID() returns (bytes32 slot) {\\n require(slot == _IMPLEMENTATION_SLOT, \\\"ERC1967Upgrade: unsupported proxiableUUID\\\");\\n } catch {\\n revert(\\\"ERC1967Upgrade: new implementation is not UUPS\\\");\\n }\\n _upgradeToAndCall(newImplementation, data, forceCall);\\n }\\n }\\n\\n /**\\n * @dev Storage slot with the admin of the contract.\\n * This is the keccak-256 hash of \\\"eip1967.proxy.admin\\\" subtracted by 1, and is\\n * validated in the constructor.\\n */\\n bytes32 internal constant _ADMIN_SLOT = 0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103;\\n\\n /**\\n * @dev Emitted when the admin account has changed.\\n */\\n event AdminChanged(address previousAdmin, address newAdmin);\\n\\n /**\\n * @dev Returns the current admin.\\n */\\n function _getAdmin() internal view returns (address) {\\n return StorageSlot.getAddressSlot(_ADMIN_SLOT).value;\\n }\\n\\n /**\\n * @dev Stores a new address in the EIP1967 admin slot.\\n */\\n function _setAdmin(address newAdmin) private {\\n require(newAdmin != address(0), \\\"ERC1967: new admin is the zero address\\\");\\n StorageSlot.getAddressSlot(_ADMIN_SLOT).value = newAdmin;\\n }\\n\\n /**\\n * @dev Changes the admin of the proxy.\\n *\\n * Emits an {AdminChanged} event.\\n */\\n function _changeAdmin(address newAdmin) internal {\\n emit AdminChanged(_getAdmin(), newAdmin);\\n _setAdmin(newAdmin);\\n }\\n\\n /**\\n * @dev The storage slot of the UpgradeableBeacon contract which defines the implementation for this proxy.\\n * This is bytes32(uint256(keccak256('eip1967.proxy.beacon')) - 1)) and is validated in the constructor.\\n */\\n bytes32 internal constant _BEACON_SLOT = 0xa3f0ad74e5423aebfd80d3ef4346578335a9a72aeaee59ff6cb3582b35133d50;\\n\\n /**\\n * @dev Emitted when the beacon is upgraded.\\n */\\n event BeaconUpgraded(address indexed beacon);\\n\\n /**\\n * @dev Returns the current beacon.\\n */\\n function _getBeacon() internal view returns (address) {\\n return StorageSlot.getAddressSlot(_BEACON_SLOT).value;\\n }\\n\\n /**\\n * @dev Stores a new beacon in the EIP1967 beacon slot.\\n */\\n function _setBeacon(address newBeacon) private {\\n require(Address.isContract(newBeacon), \\\"ERC1967: new beacon is not a contract\\\");\\n require(\\n Address.isContract(IBeacon(newBeacon).implementation()),\\n \\\"ERC1967: beacon implementation is not a contract\\\"\\n );\\n StorageSlot.getAddressSlot(_BEACON_SLOT).value = newBeacon;\\n }\\n\\n /**\\n * @dev Perform beacon upgrade with additional setup call. Note: This upgrades the address of the beacon, it does\\n * not upgrade the implementation contained in the beacon (see {UpgradeableBeacon-_setImplementation} for that).\\n *\\n * Emits a {BeaconUpgraded} event.\\n */\\n function _upgradeBeaconToAndCall(\\n address newBeacon,\\n bytes memory data,\\n bool forceCall\\n ) internal {\\n _setBeacon(newBeacon);\\n emit BeaconUpgraded(newBeacon);\\n if (data.length > 0 || forceCall) {\\n Address.functionDelegateCall(IBeacon(newBeacon).implementation(), data);\\n }\\n }\\n}\\n\",\"keccak256\":\"0xabf3f59bc0e5423eae45e459dbe92e7052c6983628d39008590edc852a62f94a\",\"license\":\"MIT\"},\"@openzeppelin/contracts/proxy/Proxy.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.6.0) (proxy/Proxy.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev This abstract contract provides a fallback function that delegates all calls to another contract using the EVM\\n * instruction `delegatecall`. We refer to the second contract as the _implementation_ behind the proxy, and it has to\\n * be specified by overriding the virtual {_implementation} function.\\n *\\n * Additionally, delegation to the implementation can be triggered manually through the {_fallback} function, or to a\\n * different contract through the {_delegate} function.\\n *\\n * The success and return data of the delegated call will be returned back to the caller of the proxy.\\n */\\nabstract contract Proxy {\\n /**\\n * @dev Delegates the current call to `implementation`.\\n *\\n * This function does not return to its internal call site, it will return directly to the external caller.\\n */\\n function _delegate(address implementation) internal virtual {\\n assembly {\\n // Copy msg.data. We take full control of memory in this inline assembly\\n // block because it will not return to Solidity code. We overwrite the\\n // Solidity scratch pad at memory position 0.\\n calldatacopy(0, 0, calldatasize())\\n\\n // Call the implementation.\\n // out and outsize are 0 because we don't know the size yet.\\n let result := delegatecall(gas(), implementation, 0, calldatasize(), 0, 0)\\n\\n // Copy the returned data.\\n returndatacopy(0, 0, returndatasize())\\n\\n switch result\\n // delegatecall returns 0 on error.\\n case 0 {\\n revert(0, returndatasize())\\n }\\n default {\\n return(0, returndatasize())\\n }\\n }\\n }\\n\\n /**\\n * @dev This is a virtual function that should be overridden so it returns the address to which the fallback function\\n * and {_fallback} should delegate.\\n */\\n function _implementation() internal view virtual returns (address);\\n\\n /**\\n * @dev Delegates the current call to the address returned by `_implementation()`.\\n *\\n * This function does not return to its internal call site, it will return directly to the external caller.\\n */\\n function _fallback() internal virtual {\\n _beforeFallback();\\n _delegate(_implementation());\\n }\\n\\n /**\\n * @dev Fallback function that delegates calls to the address returned by `_implementation()`. Will run if no other\\n * function in the contract matches the call data.\\n */\\n fallback() external payable virtual {\\n _fallback();\\n }\\n\\n /**\\n * @dev Fallback function that delegates calls to the address returned by `_implementation()`. Will run if call data\\n * is empty.\\n */\\n receive() external payable virtual {\\n _fallback();\\n }\\n\\n /**\\n * @dev Hook that is called before falling back to the implementation. Can happen as part of a manual `_fallback`\\n * call, or as part of the Solidity `fallback` or `receive` functions.\\n *\\n * If overridden should call `super._beforeFallback()`.\\n */\\n function _beforeFallback() internal virtual {}\\n}\\n\",\"keccak256\":\"0xc130fe33f1b2132158531a87734153293f6d07bc263ff4ac90e85da9c82c0e27\",\"license\":\"MIT\"},\"@openzeppelin/contracts/proxy/beacon/IBeacon.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (proxy/beacon/IBeacon.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev This is the interface that {BeaconProxy} expects of its beacon.\\n */\\ninterface IBeacon {\\n /**\\n * @dev Must return an address that can be used as a delegate call target.\\n *\\n * {BeaconProxy} will check that this address is a contract.\\n */\\n function implementation() external view returns (address);\\n}\\n\",\"keccak256\":\"0xd50a3421ac379ccb1be435fa646d66a65c986b4924f0849839f08692f39dde61\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/Address.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.7.0) (utils/Address.sol)\\n\\npragma solidity ^0.8.1;\\n\\n/**\\n * @dev Collection of functions related to the address type\\n */\\nlibrary Address {\\n /**\\n * @dev Returns true if `account` is a contract.\\n *\\n * [IMPORTANT]\\n * ====\\n * It is unsafe to assume that an address for which this function returns\\n * false is an externally-owned account (EOA) and not a contract.\\n *\\n * Among others, `isContract` will return false for the following\\n * types of addresses:\\n *\\n * - an externally-owned account\\n * - a contract in construction\\n * - an address where a contract will be created\\n * - an address where a contract lived, but was destroyed\\n * ====\\n *\\n * [IMPORTANT]\\n * ====\\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\\n *\\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\\n * constructor.\\n * ====\\n */\\n function isContract(address account) internal view returns (bool) {\\n // This method relies on extcodesize/address.code.length, which returns 0\\n // for contracts in construction, since the code is only stored at the end\\n // of the constructor execution.\\n\\n return account.code.length > 0;\\n }\\n\\n /**\\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\\n * `recipient`, forwarding all available gas and reverting on errors.\\n *\\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\\n * imposed by `transfer`, making them unable to receive funds via\\n * `transfer`. {sendValue} removes this limitation.\\n *\\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\\n *\\n * IMPORTANT: because control is transferred to `recipient`, care must be\\n * taken to not create reentrancy vulnerabilities. Consider using\\n * {ReentrancyGuard} or the\\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\\n */\\n function sendValue(address payable recipient, uint256 amount) internal {\\n require(address(this).balance >= amount, \\\"Address: insufficient balance\\\");\\n\\n (bool success, ) = recipient.call{value: amount}(\\\"\\\");\\n require(success, \\\"Address: unable to send value, recipient may have reverted\\\");\\n }\\n\\n /**\\n * @dev Performs a Solidity function call using a low level `call`. A\\n * plain `call` is an unsafe replacement for a function call: use this\\n * function instead.\\n *\\n * If `target` reverts with a revert reason, it is bubbled up by this\\n * function (like regular Solidity function calls).\\n *\\n * Returns the raw returned data. To convert to the expected return value,\\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\\n *\\n * Requirements:\\n *\\n * - `target` must be a contract.\\n * - calling `target` with `data` must not revert.\\n *\\n * _Available since v3.1._\\n */\\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\\n return functionCall(target, data, \\\"Address: low-level call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\\n * `errorMessage` as a fallback revert reason when `target` reverts.\\n *\\n * _Available since v3.1._\\n */\\n function functionCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n return functionCallWithValue(target, data, 0, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but also transferring `value` wei to `target`.\\n *\\n * Requirements:\\n *\\n * - the calling contract must have an ETH balance of at least `value`.\\n * - the called Solidity function must be `payable`.\\n *\\n * _Available since v3.1._\\n */\\n function functionCallWithValue(\\n address target,\\n bytes memory data,\\n uint256 value\\n ) internal returns (bytes memory) {\\n return functionCallWithValue(target, data, value, \\\"Address: low-level call with value failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\\n * with `errorMessage` as a fallback revert reason when `target` reverts.\\n *\\n * _Available since v3.1._\\n */\\n function functionCallWithValue(\\n address target,\\n bytes memory data,\\n uint256 value,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n require(address(this).balance >= value, \\\"Address: insufficient balance for call\\\");\\n require(isContract(target), \\\"Address: call to non-contract\\\");\\n\\n (bool success, bytes memory returndata) = target.call{value: value}(data);\\n return verifyCallResult(success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but performing a static call.\\n *\\n * _Available since v3.3._\\n */\\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\\n return functionStaticCall(target, data, \\\"Address: low-level static call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\\n * but performing a static call.\\n *\\n * _Available since v3.3._\\n */\\n function functionStaticCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal view returns (bytes memory) {\\n require(isContract(target), \\\"Address: static call to non-contract\\\");\\n\\n (bool success, bytes memory returndata) = target.staticcall(data);\\n return verifyCallResult(success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but performing a delegate call.\\n *\\n * _Available since v3.4._\\n */\\n function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {\\n return functionDelegateCall(target, data, \\\"Address: low-level delegate call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\\n * but performing a delegate call.\\n *\\n * _Available since v3.4._\\n */\\n function functionDelegateCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n require(isContract(target), \\\"Address: delegate call to non-contract\\\");\\n\\n (bool success, bytes memory returndata) = target.delegatecall(data);\\n return verifyCallResult(success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the\\n * revert reason using the provided one.\\n *\\n * _Available since v4.3._\\n */\\n function verifyCallResult(\\n bool success,\\n bytes memory returndata,\\n string memory errorMessage\\n ) internal pure returns (bytes memory) {\\n if (success) {\\n return returndata;\\n } else {\\n // Look for revert reason and bubble it up if present\\n if (returndata.length > 0) {\\n // The easiest way to bubble the revert reason is using memory via assembly\\n /// @solidity memory-safe-assembly\\n assembly {\\n let returndata_size := mload(returndata)\\n revert(add(32, returndata), returndata_size)\\n }\\n } else {\\n revert(errorMessage);\\n }\\n }\\n }\\n}\\n\",\"keccak256\":\"0xd6153ce99bcdcce22b124f755e72553295be6abcd63804cfdffceb188b8bef10\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/StorageSlot.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.7.0) (utils/StorageSlot.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Library for reading and writing primitive types to specific storage slots.\\n *\\n * Storage slots are often used to avoid storage conflict when dealing with upgradeable contracts.\\n * This library helps with reading and writing to such slots without the need for inline assembly.\\n *\\n * The functions in this library return Slot structs that contain a `value` member that can be used to read or write.\\n *\\n * Example usage to set ERC1967 implementation slot:\\n * ```\\n * contract ERC1967 {\\n * bytes32 internal constant _IMPLEMENTATION_SLOT = 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc;\\n *\\n * function _getImplementation() internal view returns (address) {\\n * return StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value;\\n * }\\n *\\n * function _setImplementation(address newImplementation) internal {\\n * require(Address.isContract(newImplementation), \\\"ERC1967: new implementation is not a contract\\\");\\n * StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value = newImplementation;\\n * }\\n * }\\n * ```\\n *\\n * _Available since v4.1 for `address`, `bool`, `bytes32`, and `uint256`._\\n */\\nlibrary StorageSlot {\\n struct AddressSlot {\\n address value;\\n }\\n\\n struct BooleanSlot {\\n bool value;\\n }\\n\\n struct Bytes32Slot {\\n bytes32 value;\\n }\\n\\n struct Uint256Slot {\\n uint256 value;\\n }\\n\\n /**\\n * @dev Returns an `AddressSlot` with member `value` located at `slot`.\\n */\\n function getAddressSlot(bytes32 slot) internal pure returns (AddressSlot storage r) {\\n /// @solidity memory-safe-assembly\\n assembly {\\n r.slot := slot\\n }\\n }\\n\\n /**\\n * @dev Returns an `BooleanSlot` with member `value` located at `slot`.\\n */\\n function getBooleanSlot(bytes32 slot) internal pure returns (BooleanSlot storage r) {\\n /// @solidity memory-safe-assembly\\n assembly {\\n r.slot := slot\\n }\\n }\\n\\n /**\\n * @dev Returns an `Bytes32Slot` with member `value` located at `slot`.\\n */\\n function getBytes32Slot(bytes32 slot) internal pure returns (Bytes32Slot storage r) {\\n /// @solidity memory-safe-assembly\\n assembly {\\n r.slot := slot\\n }\\n }\\n\\n /**\\n * @dev Returns an `Uint256Slot` with member `value` located at `slot`.\\n */\\n function getUint256Slot(bytes32 slot) internal pure returns (Uint256Slot storage r) {\\n /// @solidity memory-safe-assembly\\n assembly {\\n r.slot := slot\\n }\\n }\\n}\\n\",\"keccak256\":\"0xd5c50c54bf02740ebd122ff06832546cb5fa84486d52695a9ccfd11666e0c81d\",\"license\":\"MIT\"},\"contracts/external/TransparentUpgradeableProxy.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-3.0\\n\\npragma solidity ^0.8.12;\\n\\nimport \\\"@openzeppelin/contracts/proxy/ERC1967/ERC1967Proxy.sol\\\";\\n\\n/**\\n * @dev This contract implements a proxy that is upgradeable by an admin. It is fully forked from OpenZeppelin\\n * `TransparentUpgradeableProxy`\\n *\\n * To avoid https://medium.com/nomic-labs-blog/malicious-backdoors-in-ethereum-proxies-62629adf3357[proxy selector\\n * clashing], which can potentially be used in an attack, this contract uses the\\n * https://blog.openzeppelin.com/the-transparent-proxy-pattern/[transparent proxy pattern]. This pattern implies two\\n * things that go hand in hand:\\n *\\n * 1. If any account other than the admin calls the proxy, the call will be forwarded to the implementation, even if\\n * that call matches one of the admin functions exposed by the proxy itself.\\n * 2. If the admin calls the proxy, it can access the admin functions, but its calls will never be forwarded to the\\n * implementation. If the admin tries to call a function on the implementation it will fail with an error that says\\n * \\\"admin cannot fallback to proxy target\\\".\\n *\\n * These properties mean that the admin account can only be used for admin actions like upgrading the proxy or changing\\n * the admin, so it's best if it's a dedicated account that is not used for anything else. This will avoid headaches due\\n * to sudden errors when trying to call a function from the proxy implementation.\\n *\\n * Our recommendation is for the dedicated account to be an instance of the {ProxyAdmin} contract. If set up this way,\\n * you should think of the `ProxyAdmin` instance as the real administrative interface of your proxy.\\n */\\ncontract TransparentUpgradeableProxy is ERC1967Proxy {\\n /**\\n * @dev Initializes an upgradeable proxy managed by `_admin`, backed by the implementation at `_logic`, and\\n * optionally initialized with `_data` as explained in {ERC1967Proxy-constructor}.\\n */\\n constructor(address _logic, address admin_, bytes memory _data) payable ERC1967Proxy(_logic, _data) {\\n assert(_ADMIN_SLOT == bytes32(uint256(keccak256(\\\"eip1967.proxy.admin\\\")) - 1));\\n _changeAdmin(admin_);\\n }\\n\\n /**\\n * @dev Modifier used internally that will delegate the call to the implementation unless the sender is the admin.\\n */\\n modifier ifAdmin() {\\n if (msg.sender == _getAdmin()) {\\n _;\\n } else {\\n _fallback();\\n }\\n }\\n\\n /**\\n * @dev Returns the current admin.\\n *\\n * NOTE: Only the admin can call this function. See {ProxyAdmin-getProxyAdmin}.\\n *\\n * TIP: To get this value clients can read directly from the storage slot shown below (specified by EIP1967) using the\\n * https://eth.wiki/json-rpc/API#eth_getstorageat[`eth_getStorageAt`] RPC call.\\n * `0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103`\\n */\\n function admin() external ifAdmin returns (address admin_) {\\n admin_ = _getAdmin();\\n }\\n\\n /**\\n * @dev Returns the current implementation.\\n *\\n * NOTE: Only the admin can call this function. See {ProxyAdmin-getProxyImplementation}.\\n *\\n * TIP: To get this value clients can read directly from the storage slot shown below (specified by EIP1967) using the\\n * https://eth.wiki/json-rpc/API#eth_getstorageat[`eth_getStorageAt`] RPC call.\\n * `0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc`\\n */\\n function implementation() external ifAdmin returns (address implementation_) {\\n implementation_ = _implementation();\\n }\\n\\n /**\\n * @dev Changes the admin of the proxy.\\n *\\n * Emits an {AdminChanged} event.\\n *\\n * NOTE: Only the admin can call this function. See {ProxyAdmin-changeProxyAdmin}.\\n */\\n function changeAdmin(address newAdmin) external virtual ifAdmin {\\n _changeAdmin(newAdmin);\\n }\\n\\n /**\\n * @dev Upgrade the implementation of the proxy.\\n *\\n * NOTE: Only the admin can call this function. See {ProxyAdmin-upgrade}.\\n */\\n function upgradeTo(address newImplementation) external ifAdmin {\\n _upgradeToAndCall(newImplementation, bytes(\\\"\\\"), false);\\n }\\n\\n /**\\n * @dev Upgrade the implementation of the proxy, and then call a function from the new implementation as specified\\n * by `data`, which should be an encoded function call. This is useful to initialize new storage variables in the\\n * proxied contract.\\n *\\n * NOTE: Only the admin can call this function. See {ProxyAdmin-upgradeAndCall}.\\n */\\n function upgradeToAndCall(address newImplementation, bytes calldata data) external payable ifAdmin {\\n _upgradeToAndCall(newImplementation, data, true);\\n }\\n\\n /**\\n * @dev Returns the current admin.\\n */\\n function _admin() internal view virtual returns (address) {\\n return _getAdmin();\\n }\\n\\n /**\\n * @dev Makes sure the admin cannot access the fallback function. See {Proxy-_beforeFallback}.\\n */\\n function _beforeFallback() internal virtual override {\\n require(msg.sender != _getAdmin(), \\\"TransparentUpgradeableProxy: admin cannot fallback to proxy target\\\");\\n super._beforeFallback();\\n }\\n}\\n\",\"keccak256\":\"0x93a67a0f612ea3ff2a76315e138a6a88267270a1379d3cc7be52845fbbe611e2\",\"license\":\"GPL-3.0\"}},\"version\":1}", + "bytecode": "0x6080604052604051620010bb380380620010bb8339810160408190526200002691620004d8565b828162000036828260006200009a565b5062000066905060017fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6104620005b8565b6000805160206200107483398151915214620000865762000086620005da565b6200009182620000d7565b50505062000643565b620000a58362000132565b600082511180620000b35750805b15620000d257620000d083836200017460201b6200028c1760201c565b505b505050565b7f7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f62000102620001a5565b604080516001600160a01b03928316815291841660208301520160405180910390a16200012f81620001de565b50565b6200013d8162000293565b6040516001600160a01b038216907fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b90600090a250565b60606200019c8383604051806060016040528060278152602001620010946027913962000347565b90505b92915050565b6000620001cf6000805160206200107483398151915260001b6200042f60201b6200022e1760201c565b546001600160a01b0316919050565b6001600160a01b038116620002495760405162461bcd60e51b815260206004820152602660248201527f455243313936373a206e65772061646d696e20697320746865207a65726f206160448201526564647265737360d01b60648201526084015b60405180910390fd5b80620002726000805160206200107483398151915260001b6200042f60201b6200022e1760201c565b80546001600160a01b0319166001600160a01b039290921691909117905550565b620002a9816200043260201b620002b81760201c565b6200030d5760405162461bcd60e51b815260206004820152602d60248201527f455243313936373a206e657720696d706c656d656e746174696f6e206973206e60448201526c1bdd08184818dbdb9d1c9858dd609a1b606482015260840162000240565b80620002727f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc60001b6200042f60201b6200022e1760201c565b60606001600160a01b0384163b620003b15760405162461bcd60e51b815260206004820152602660248201527f416464726573733a2064656c65676174652063616c6c20746f206e6f6e2d636f6044820152651b9d1c9858dd60d21b606482015260840162000240565b600080856001600160a01b031685604051620003ce9190620005f0565b600060405180830381855af49150503d80600081146200040b576040519150601f19603f3d011682016040523d82523d6000602084013e62000410565b606091505b5090925090506200042382828662000441565b925050505b9392505050565b90565b6001600160a01b03163b151590565b606083156200045257508162000428565b825115620004635782518084602001fd5b8160405162461bcd60e51b81526004016200024091906200060e565b80516001600160a01b03811681146200049757600080fd5b919050565b634e487b7160e01b600052604160045260246000fd5b60005b83811015620004cf578181015183820152602001620004b5565b50506000910152565b600080600060608486031215620004ee57600080fd5b620004f9846200047f565b925062000509602085016200047f565b60408501519092506001600160401b03808211156200052757600080fd5b818601915086601f8301126200053c57600080fd5b8151818111156200055157620005516200049c565b604051601f8201601f19908116603f011681019083821181831017156200057c576200057c6200049c565b816040528281528960208487010111156200059657600080fd5b620005a9836020830160208801620004b2565b80955050505050509250925092565b818103818111156200019f57634e487b7160e01b600052601160045260246000fd5b634e487b7160e01b600052600160045260246000fd5b6000825162000604818460208701620004b2565b9190910192915050565b60208152600082518060208401526200062f816040850160208701620004b2565b601f01601f19169190910160400192915050565b610a2180620006536000396000f3fe60806040526004361061005e5760003560e01c80635c60da1b116100435780635c60da1b146100a85780638f283970146100e6578063f851a440146101065761006d565b80633659cfe6146100755780634f1ef286146100955761006d565b3661006d5761006b61011b565b005b61006b61011b565b34801561008157600080fd5b5061006b610090366004610895565b610135565b61006b6100a33660046108b0565b61017f565b3480156100b457600080fd5b506100bd6101f3565b60405173ffffffffffffffffffffffffffffffffffffffff909116815260200160405180910390f35b3480156100f257600080fd5b5061006b610101366004610895565b610231565b34801561011257600080fd5b506100bd61025e565b6101236102d4565b61013361012e6103ab565b6103b5565b565b61013d6103d9565b73ffffffffffffffffffffffffffffffffffffffff1633036101775761017481604051806020016040528060008152506000610419565b50565b61017461011b565b6101876103d9565b73ffffffffffffffffffffffffffffffffffffffff1633036101eb576101e68383838080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525060019250610419915050565b505050565b6101e661011b565b60006101fd6103d9565b73ffffffffffffffffffffffffffffffffffffffff163303610226576102216103ab565b905090565b61022e61011b565b90565b6102396103d9565b73ffffffffffffffffffffffffffffffffffffffff1633036101775761017481610444565b60006102686103d9565b73ffffffffffffffffffffffffffffffffffffffff163303610226576102216103d9565b60606102b183836040518060600160405280602781526020016109c5602791396104a5565b9392505050565b73ffffffffffffffffffffffffffffffffffffffff163b151590565b6102dc6103d9565b73ffffffffffffffffffffffffffffffffffffffff163303610133576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604260248201527f5472616e73706172656e745570677261646561626c6550726f78793a2061646d60448201527f696e2063616e6e6f742066616c6c6261636b20746f2070726f7879207461726760648201527f6574000000000000000000000000000000000000000000000000000000000000608482015260a4015b60405180910390fd5b60006102216105cd565b3660008037600080366000845af43d6000803e8080156103d4573d6000f35b3d6000fd5b60007fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035b5473ffffffffffffffffffffffffffffffffffffffff16919050565b610422836105f5565b60008251118061042f5750805b156101e65761043e838361028c565b50505050565b7f7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f61046d6103d9565b6040805173ffffffffffffffffffffffffffffffffffffffff928316815291841660208301520160405180910390a161017481610642565b606073ffffffffffffffffffffffffffffffffffffffff84163b61054b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f416464726573733a2064656c65676174652063616c6c20746f206e6f6e2d636f60448201527f6e7472616374000000000000000000000000000000000000000000000000000060648201526084016103a2565b6000808573ffffffffffffffffffffffffffffffffffffffff16856040516105739190610957565b600060405180830381855af49150503d80600081146105ae576040519150601f19603f3d011682016040523d82523d6000602084013e6105b3565b606091505b50915091506105c382828661074e565b9695505050505050565b60007f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc6103fd565b6105fe816107a1565b60405173ffffffffffffffffffffffffffffffffffffffff8216907fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b90600090a250565b73ffffffffffffffffffffffffffffffffffffffff81166106e5576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f455243313936373a206e65772061646d696e20697320746865207a65726f206160448201527f646472657373000000000000000000000000000000000000000000000000000060648201526084016103a2565b807fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035b80547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff9290921691909117905550565b6060831561075d5750816102b1565b82511561076d5782518084602001fd5b816040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016103a29190610973565b73ffffffffffffffffffffffffffffffffffffffff81163b610845576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602d60248201527f455243313936373a206e657720696d706c656d656e746174696f6e206973206e60448201527f6f74206120636f6e74726163740000000000000000000000000000000000000060648201526084016103a2565b807f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc610708565b803573ffffffffffffffffffffffffffffffffffffffff8116811461089057600080fd5b919050565b6000602082840312156108a757600080fd5b6102b18261086c565b6000806000604084860312156108c557600080fd5b6108ce8461086c565b9250602084013567ffffffffffffffff808211156108eb57600080fd5b818601915086601f8301126108ff57600080fd5b81358181111561090e57600080fd5b87602082850101111561092057600080fd5b6020830194508093505050509250925092565b60005b8381101561094e578181015183820152602001610936565b50506000910152565b60008251610969818460208701610933565b9190910192915050565b6020815260008251806020840152610992816040850160208701610933565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016919091016040019291505056fe416464726573733a206c6f772d6c6576656c2064656c65676174652063616c6c206661696c6564a2646970667358221220e96638b07fb1675d93a95c49e417bc8111448b23a59918698cdcd8fd488dd7cf64736f6c63430008110033b53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103416464726573733a206c6f772d6c6576656c2064656c65676174652063616c6c206661696c6564", + "deployedBytecode": "0x60806040526004361061005e5760003560e01c80635c60da1b116100435780635c60da1b146100a85780638f283970146100e6578063f851a440146101065761006d565b80633659cfe6146100755780634f1ef286146100955761006d565b3661006d5761006b61011b565b005b61006b61011b565b34801561008157600080fd5b5061006b610090366004610895565b610135565b61006b6100a33660046108b0565b61017f565b3480156100b457600080fd5b506100bd6101f3565b60405173ffffffffffffffffffffffffffffffffffffffff909116815260200160405180910390f35b3480156100f257600080fd5b5061006b610101366004610895565b610231565b34801561011257600080fd5b506100bd61025e565b6101236102d4565b61013361012e6103ab565b6103b5565b565b61013d6103d9565b73ffffffffffffffffffffffffffffffffffffffff1633036101775761017481604051806020016040528060008152506000610419565b50565b61017461011b565b6101876103d9565b73ffffffffffffffffffffffffffffffffffffffff1633036101eb576101e68383838080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525060019250610419915050565b505050565b6101e661011b565b60006101fd6103d9565b73ffffffffffffffffffffffffffffffffffffffff163303610226576102216103ab565b905090565b61022e61011b565b90565b6102396103d9565b73ffffffffffffffffffffffffffffffffffffffff1633036101775761017481610444565b60006102686103d9565b73ffffffffffffffffffffffffffffffffffffffff163303610226576102216103d9565b60606102b183836040518060600160405280602781526020016109c5602791396104a5565b9392505050565b73ffffffffffffffffffffffffffffffffffffffff163b151590565b6102dc6103d9565b73ffffffffffffffffffffffffffffffffffffffff163303610133576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604260248201527f5472616e73706172656e745570677261646561626c6550726f78793a2061646d60448201527f696e2063616e6e6f742066616c6c6261636b20746f2070726f7879207461726760648201527f6574000000000000000000000000000000000000000000000000000000000000608482015260a4015b60405180910390fd5b60006102216105cd565b3660008037600080366000845af43d6000803e8080156103d4573d6000f35b3d6000fd5b60007fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035b5473ffffffffffffffffffffffffffffffffffffffff16919050565b610422836105f5565b60008251118061042f5750805b156101e65761043e838361028c565b50505050565b7f7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f61046d6103d9565b6040805173ffffffffffffffffffffffffffffffffffffffff928316815291841660208301520160405180910390a161017481610642565b606073ffffffffffffffffffffffffffffffffffffffff84163b61054b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f416464726573733a2064656c65676174652063616c6c20746f206e6f6e2d636f60448201527f6e7472616374000000000000000000000000000000000000000000000000000060648201526084016103a2565b6000808573ffffffffffffffffffffffffffffffffffffffff16856040516105739190610957565b600060405180830381855af49150503d80600081146105ae576040519150601f19603f3d011682016040523d82523d6000602084013e6105b3565b606091505b50915091506105c382828661074e565b9695505050505050565b60007f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc6103fd565b6105fe816107a1565b60405173ffffffffffffffffffffffffffffffffffffffff8216907fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b90600090a250565b73ffffffffffffffffffffffffffffffffffffffff81166106e5576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f455243313936373a206e65772061646d696e20697320746865207a65726f206160448201527f646472657373000000000000000000000000000000000000000000000000000060648201526084016103a2565b807fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035b80547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff9290921691909117905550565b6060831561075d5750816102b1565b82511561076d5782518084602001fd5b816040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016103a29190610973565b73ffffffffffffffffffffffffffffffffffffffff81163b610845576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602d60248201527f455243313936373a206e657720696d706c656d656e746174696f6e206973206e60448201527f6f74206120636f6e74726163740000000000000000000000000000000000000060648201526084016103a2565b807f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc610708565b803573ffffffffffffffffffffffffffffffffffffffff8116811461089057600080fd5b919050565b6000602082840312156108a757600080fd5b6102b18261086c565b6000806000604084860312156108c557600080fd5b6108ce8461086c565b9250602084013567ffffffffffffffff808211156108eb57600080fd5b818601915086601f8301126108ff57600080fd5b81358181111561090e57600080fd5b87602082850101111561092057600080fd5b6020830194508093505050509250925092565b60005b8381101561094e578181015183820152602001610936565b50506000910152565b60008251610969818460208701610933565b9190910192915050565b6020815260008251806020840152610992816040850160208701610933565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016919091016040019291505056fe416464726573733a206c6f772d6c6576656c2064656c65676174652063616c6c206661696c6564a2646970667358221220e96638b07fb1675d93a95c49e417bc8111448b23a59918698cdcd8fd488dd7cf64736f6c63430008110033", + "devdoc": { + "details": "This contract implements a proxy that is upgradeable by an admin. It is fully forked from OpenZeppelin `TransparentUpgradeableProxy` To avoid https://medium.com/nomic-labs-blog/malicious-backdoors-in-ethereum-proxies-62629adf3357[proxy selector clashing], which can potentially be used in an attack, this contract uses the https://blog.openzeppelin.com/the-transparent-proxy-pattern/[transparent proxy pattern]. This pattern implies two things that go hand in hand: 1. If any account other than the admin calls the proxy, the call will be forwarded to the implementation, even if that call matches one of the admin functions exposed by the proxy itself. 2. If the admin calls the proxy, it can access the admin functions, but its calls will never be forwarded to the implementation. If the admin tries to call a function on the implementation it will fail with an error that says \"admin cannot fallback to proxy target\". These properties mean that the admin account can only be used for admin actions like upgrading the proxy or changing the admin, so it's best if it's a dedicated account that is not used for anything else. This will avoid headaches due to sudden errors when trying to call a function from the proxy implementation. Our recommendation is for the dedicated account to be an instance of the {ProxyAdmin} contract. If set up this way, you should think of the `ProxyAdmin` instance as the real administrative interface of your proxy.", + "kind": "dev", + "methods": { + "admin()": { + "details": "Returns the current admin. NOTE: Only the admin can call this function. See {ProxyAdmin-getProxyAdmin}. TIP: To get this value clients can read directly from the storage slot shown below (specified by EIP1967) using the https://eth.wiki/json-rpc/API#eth_getstorageat[`eth_getStorageAt`] RPC call. `0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103`" + }, + "changeAdmin(address)": { + "details": "Changes the admin of the proxy. Emits an {AdminChanged} event. NOTE: Only the admin can call this function. See {ProxyAdmin-changeProxyAdmin}." + }, + "constructor": { + "details": "Initializes an upgradeable proxy managed by `_admin`, backed by the implementation at `_logic`, and optionally initialized with `_data` as explained in {ERC1967Proxy-constructor}." + }, + "implementation()": { + "details": "Returns the current implementation. NOTE: Only the admin can call this function. See {ProxyAdmin-getProxyImplementation}. TIP: To get this value clients can read directly from the storage slot shown below (specified by EIP1967) using the https://eth.wiki/json-rpc/API#eth_getstorageat[`eth_getStorageAt`] RPC call. `0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc`" + }, + "upgradeTo(address)": { + "details": "Upgrade the implementation of the proxy. NOTE: Only the admin can call this function. See {ProxyAdmin-upgrade}." + }, + "upgradeToAndCall(address,bytes)": { + "details": "Upgrade the implementation of the proxy, and then call a function from the new implementation as specified by `data`, which should be an encoded function call. This is useful to initialize new storage variables in the proxied contract. NOTE: Only the admin can call this function. See {ProxyAdmin-upgradeAndCall}." + } + }, + "version": 1 + }, + "userdoc": { + "kind": "user", + "methods": {}, + "version": 1 + }, + "storageLayout": { + "storage": [], + "types": null + } +} \ No newline at end of file diff --git a/deployments/avalanche/LayerZeroBridge_USD.json b/deployments/avalanche/LayerZeroBridge_USD.json new file mode 100644 index 00000000..77a375a9 --- /dev/null +++ b/deployments/avalanche/LayerZeroBridge_USD.json @@ -0,0 +1,275 @@ +{ + "address": "0xC492fBAe68cE6C5E14C7ed5cd8a59babD5c90e4C", + "abi": [ + { + "inputs": [ + { + "internalType": "address", + "name": "_logic", + "type": "address" + }, + { + "internalType": "address", + "name": "admin_", + "type": "address" + }, + { + "internalType": "bytes", + "name": "_data", + "type": "bytes" + } + ], + "stateMutability": "payable", + "type": "constructor" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "previousAdmin", + "type": "address" + }, + { + "indexed": false, + "internalType": "address", + "name": "newAdmin", + "type": "address" + } + ], + "name": "AdminChanged", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "beacon", + "type": "address" + } + ], + "name": "BeaconUpgraded", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "implementation", + "type": "address" + } + ], + "name": "Upgraded", + "type": "event" + }, + { + "stateMutability": "payable", + "type": "fallback" + }, + { + "inputs": [], + "name": "admin", + "outputs": [ + { + "internalType": "address", + "name": "admin_", + "type": "address" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "newAdmin", + "type": "address" + } + ], + "name": "changeAdmin", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "implementation", + "outputs": [ + { + "internalType": "address", + "name": "implementation_", + "type": "address" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "newImplementation", + "type": "address" + } + ], + "name": "upgradeTo", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "newImplementation", + "type": "address" + }, + { + "internalType": "bytes", + "name": "data", + "type": "bytes" + } + ], + "name": "upgradeToAndCall", + "outputs": [], + "stateMutability": "payable", + "type": "function" + }, + { + "stateMutability": "payable", + "type": "receive" + } + ], + "transactionHash": "0x8c319abaebcdabe6a49616731e8b17adc415a8e0547b123317ff9bf8917dd7b8", + "receipt": { + "to": null, + "from": "0xfdA462548Ce04282f4B6D6619823a7C64Fdc0185", + "contractAddress": "0xC492fBAe68cE6C5E14C7ed5cd8a59babD5c90e4C", + "transactionIndex": 5, + "gasUsed": "849932", + "logsBloom": "0x00000002000000000000000000000000400000000000000000000000000000000000000000000000000000000000000000000000000040000040000000200000000004000000000000000008000002000000000000000000000008010500000000000000020000000000000000800800000000800000000000000010000000000400000000000000000000000000000000000000020080000000000000800000020000000000000000000000000400000000000000000000000000000000000000000022000000000000000000040000000000040400000000000000000020000010000000000000000000000000000000000000000000000000000000000000", + "blockHash": "0xaf7b2b31860efe2826e751268ffaa5ab5ec4a39714a60d78bf36b3142c42355f", + "transactionHash": "0x8c319abaebcdabe6a49616731e8b17adc415a8e0547b123317ff9bf8917dd7b8", + "logs": [ + { + "transactionIndex": 5, + "blockNumber": 40179222, + "transactionHash": "0x8c319abaebcdabe6a49616731e8b17adc415a8e0547b123317ff9bf8917dd7b8", + "address": "0xC492fBAe68cE6C5E14C7ed5cd8a59babD5c90e4C", + "topics": [ + "0xbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b", + "0x0000000000000000000000002904a4d96f88ad4bd548507ba139e892083894f7" + ], + "data": "0x", + "logIndex": 3, + "blockHash": "0xaf7b2b31860efe2826e751268ffaa5ab5ec4a39714a60d78bf36b3142c42355f" + }, + { + "transactionIndex": 5, + "blockNumber": 40179222, + "transactionHash": "0x8c319abaebcdabe6a49616731e8b17adc415a8e0547b123317ff9bf8917dd7b8", + "address": "0xC492fBAe68cE6C5E14C7ed5cd8a59babD5c90e4C", + "topics": [ + "0x8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925", + "0x000000000000000000000000c492fbae68ce6c5e14c7ed5cd8a59babd5c90e4c", + "0x0000000000000000000000000000206329b97db379d5e1bf586bbdb969c63274" + ], + "data": "0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", + "logIndex": 4, + "blockHash": "0xaf7b2b31860efe2826e751268ffaa5ab5ec4a39714a60d78bf36b3142c42355f" + }, + { + "transactionIndex": 5, + "blockNumber": 40179222, + "transactionHash": "0x8c319abaebcdabe6a49616731e8b17adc415a8e0547b123317ff9bf8917dd7b8", + "address": "0xC492fBAe68cE6C5E14C7ed5cd8a59babD5c90e4C", + "topics": [ + "0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000206329b97db379d5e1bf586bbdb969c63274" + ], + "data": "0x0000000000000000000000000000000000000000000000000000000000000000", + "logIndex": 5, + "blockHash": "0xaf7b2b31860efe2826e751268ffaa5ab5ec4a39714a60d78bf36b3142c42355f" + }, + { + "transactionIndex": 5, + "blockNumber": 40179222, + "transactionHash": "0x8c319abaebcdabe6a49616731e8b17adc415a8e0547b123317ff9bf8917dd7b8", + "address": "0xC492fBAe68cE6C5E14C7ed5cd8a59babD5c90e4C", + "topics": [ + "0x7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb3847402498" + ], + "data": "0x0000000000000000000000000000000000000000000000000000000000000001", + "logIndex": 6, + "blockHash": "0xaf7b2b31860efe2826e751268ffaa5ab5ec4a39714a60d78bf36b3142c42355f" + }, + { + "transactionIndex": 5, + "blockNumber": 40179222, + "transactionHash": "0x8c319abaebcdabe6a49616731e8b17adc415a8e0547b123317ff9bf8917dd7b8", + "address": "0xC492fBAe68cE6C5E14C7ed5cd8a59babD5c90e4C", + "topics": [ + "0x7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f" + ], + "data": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000007ab641e661a9728913a44e06f6a4879481142ddb", + "logIndex": 7, + "blockHash": "0xaf7b2b31860efe2826e751268ffaa5ab5ec4a39714a60d78bf36b3142c42355f" + } + ], + "blockNumber": 40179222, + "cumulativeGasUsed": "1077047", + "status": 1, + "byzantium": true + }, + "args": [ + "0x2904A4d96f88ad4bD548507BA139E892083894F7", + "0x7AB641E661a9728913A44e06f6a4879481142DDb", + "0xc9aba0aa00000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000000e00000000000000000000000003c2269811836af69497e5f486a85d7316753cf62000000000000000000000000de725566fa2bafd175066943d8d50ae762058e92000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000164c617965725a65726f204272696467652061675553440000000000000000000000000000000000000000000000000000000000000000000000000000000000084c5a2d6167555344000000000000000000000000000000000000000000000000" + ], + "numDeployments": 1, + "solcInputHash": "871924e0c138825a2736b76def8fef8d", + "metadata": "{\"compiler\":{\"version\":\"0.8.17+commit.8df45f5f\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_logic\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"admin_\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"_data\",\"type\":\"bytes\"}],\"stateMutability\":\"payable\",\"type\":\"constructor\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"previousAdmin\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"newAdmin\",\"type\":\"address\"}],\"name\":\"AdminChanged\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"beacon\",\"type\":\"address\"}],\"name\":\"BeaconUpgraded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"implementation\",\"type\":\"address\"}],\"name\":\"Upgraded\",\"type\":\"event\"},{\"stateMutability\":\"payable\",\"type\":\"fallback\"},{\"inputs\":[],\"name\":\"admin\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"admin_\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newAdmin\",\"type\":\"address\"}],\"name\":\"changeAdmin\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"implementation\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"implementation_\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newImplementation\",\"type\":\"address\"}],\"name\":\"upgradeTo\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newImplementation\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"}],\"name\":\"upgradeToAndCall\",\"outputs\":[],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"stateMutability\":\"payable\",\"type\":\"receive\"}],\"devdoc\":{\"details\":\"This contract implements a proxy that is upgradeable by an admin. It is fully forked from OpenZeppelin `TransparentUpgradeableProxy` To avoid https://medium.com/nomic-labs-blog/malicious-backdoors-in-ethereum-proxies-62629adf3357[proxy selector clashing], which can potentially be used in an attack, this contract uses the https://blog.openzeppelin.com/the-transparent-proxy-pattern/[transparent proxy pattern]. This pattern implies two things that go hand in hand: 1. If any account other than the admin calls the proxy, the call will be forwarded to the implementation, even if that call matches one of the admin functions exposed by the proxy itself. 2. If the admin calls the proxy, it can access the admin functions, but its calls will never be forwarded to the implementation. If the admin tries to call a function on the implementation it will fail with an error that says \\\"admin cannot fallback to proxy target\\\". These properties mean that the admin account can only be used for admin actions like upgrading the proxy or changing the admin, so it's best if it's a dedicated account that is not used for anything else. This will avoid headaches due to sudden errors when trying to call a function from the proxy implementation. Our recommendation is for the dedicated account to be an instance of the {ProxyAdmin} contract. If set up this way, you should think of the `ProxyAdmin` instance as the real administrative interface of your proxy.\",\"kind\":\"dev\",\"methods\":{\"admin()\":{\"details\":\"Returns the current admin. NOTE: Only the admin can call this function. See {ProxyAdmin-getProxyAdmin}. TIP: To get this value clients can read directly from the storage slot shown below (specified by EIP1967) using the https://eth.wiki/json-rpc/API#eth_getstorageat[`eth_getStorageAt`] RPC call. `0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103`\"},\"changeAdmin(address)\":{\"details\":\"Changes the admin of the proxy. Emits an {AdminChanged} event. NOTE: Only the admin can call this function. See {ProxyAdmin-changeProxyAdmin}.\"},\"constructor\":{\"details\":\"Initializes an upgradeable proxy managed by `_admin`, backed by the implementation at `_logic`, and optionally initialized with `_data` as explained in {ERC1967Proxy-constructor}.\"},\"implementation()\":{\"details\":\"Returns the current implementation. NOTE: Only the admin can call this function. See {ProxyAdmin-getProxyImplementation}. TIP: To get this value clients can read directly from the storage slot shown below (specified by EIP1967) using the https://eth.wiki/json-rpc/API#eth_getstorageat[`eth_getStorageAt`] RPC call. `0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc`\"},\"upgradeTo(address)\":{\"details\":\"Upgrade the implementation of the proxy. NOTE: Only the admin can call this function. See {ProxyAdmin-upgrade}.\"},\"upgradeToAndCall(address,bytes)\":{\"details\":\"Upgrade the implementation of the proxy, and then call a function from the new implementation as specified by `data`, which should be an encoded function call. This is useful to initialize new storage variables in the proxied contract. NOTE: Only the admin can call this function. See {ProxyAdmin-upgradeAndCall}.\"}},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/external/TransparentUpgradeableProxy.sol\":\"TransparentUpgradeableProxy\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":1000000},\"remappings\":[]},\"sources\":{\"@openzeppelin/contracts/interfaces/draft-IERC1822.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.5.0) (interfaces/draft-IERC1822.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev ERC1822: Universal Upgradeable Proxy Standard (UUPS) documents a method for upgradeability through a simplified\\n * proxy whose upgrades are fully controlled by the current implementation.\\n */\\ninterface IERC1822Proxiable {\\n /**\\n * @dev Returns the storage slot that the proxiable contract assumes is being used to store the implementation\\n * address.\\n *\\n * IMPORTANT: A proxy pointing at a proxiable contract should not be considered proxiable itself, because this risks\\n * bricking a proxy that upgrades to it, by delegating to itself until out of gas. Thus it is critical that this\\n * function revert if invoked through a proxy.\\n */\\n function proxiableUUID() external view returns (bytes32);\\n}\\n\",\"keccak256\":\"0x1d4afe6cb24200cc4545eed814ecf5847277dfe5d613a1707aad5fceecebcfff\",\"license\":\"MIT\"},\"@openzeppelin/contracts/proxy/ERC1967/ERC1967Proxy.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.7.0) (proxy/ERC1967/ERC1967Proxy.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../Proxy.sol\\\";\\nimport \\\"./ERC1967Upgrade.sol\\\";\\n\\n/**\\n * @dev This contract implements an upgradeable proxy. It is upgradeable because calls are delegated to an\\n * implementation address that can be changed. This address is stored in storage in the location specified by\\n * https://eips.ethereum.org/EIPS/eip-1967[EIP1967], so that it doesn't conflict with the storage layout of the\\n * implementation behind the proxy.\\n */\\ncontract ERC1967Proxy is Proxy, ERC1967Upgrade {\\n /**\\n * @dev Initializes the upgradeable proxy with an initial implementation specified by `_logic`.\\n *\\n * If `_data` is nonempty, it's used as data in a delegate call to `_logic`. This will typically be an encoded\\n * function call, and allows initializing the storage of the proxy like a Solidity constructor.\\n */\\n constructor(address _logic, bytes memory _data) payable {\\n _upgradeToAndCall(_logic, _data, false);\\n }\\n\\n /**\\n * @dev Returns the current implementation address.\\n */\\n function _implementation() internal view virtual override returns (address impl) {\\n return ERC1967Upgrade._getImplementation();\\n }\\n}\\n\",\"keccak256\":\"0xa2b22da3032e50b55f95ec1d13336102d675f341167aa76db571ef7f8bb7975d\",\"license\":\"MIT\"},\"@openzeppelin/contracts/proxy/ERC1967/ERC1967Upgrade.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.5.0) (proxy/ERC1967/ERC1967Upgrade.sol)\\n\\npragma solidity ^0.8.2;\\n\\nimport \\\"../beacon/IBeacon.sol\\\";\\nimport \\\"../../interfaces/draft-IERC1822.sol\\\";\\nimport \\\"../../utils/Address.sol\\\";\\nimport \\\"../../utils/StorageSlot.sol\\\";\\n\\n/**\\n * @dev This abstract contract provides getters and event emitting update functions for\\n * https://eips.ethereum.org/EIPS/eip-1967[EIP1967] slots.\\n *\\n * _Available since v4.1._\\n *\\n * @custom:oz-upgrades-unsafe-allow delegatecall\\n */\\nabstract contract ERC1967Upgrade {\\n // This is the keccak-256 hash of \\\"eip1967.proxy.rollback\\\" subtracted by 1\\n bytes32 private constant _ROLLBACK_SLOT = 0x4910fdfa16fed3260ed0e7147f7cc6da11a60208b5b9406d12a635614ffd9143;\\n\\n /**\\n * @dev Storage slot with the address of the current implementation.\\n * This is the keccak-256 hash of \\\"eip1967.proxy.implementation\\\" subtracted by 1, and is\\n * validated in the constructor.\\n */\\n bytes32 internal constant _IMPLEMENTATION_SLOT = 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc;\\n\\n /**\\n * @dev Emitted when the implementation is upgraded.\\n */\\n event Upgraded(address indexed implementation);\\n\\n /**\\n * @dev Returns the current implementation address.\\n */\\n function _getImplementation() internal view returns (address) {\\n return StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value;\\n }\\n\\n /**\\n * @dev Stores a new address in the EIP1967 implementation slot.\\n */\\n function _setImplementation(address newImplementation) private {\\n require(Address.isContract(newImplementation), \\\"ERC1967: new implementation is not a contract\\\");\\n StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value = newImplementation;\\n }\\n\\n /**\\n * @dev Perform implementation upgrade\\n *\\n * Emits an {Upgraded} event.\\n */\\n function _upgradeTo(address newImplementation) internal {\\n _setImplementation(newImplementation);\\n emit Upgraded(newImplementation);\\n }\\n\\n /**\\n * @dev Perform implementation upgrade with additional setup call.\\n *\\n * Emits an {Upgraded} event.\\n */\\n function _upgradeToAndCall(\\n address newImplementation,\\n bytes memory data,\\n bool forceCall\\n ) internal {\\n _upgradeTo(newImplementation);\\n if (data.length > 0 || forceCall) {\\n Address.functionDelegateCall(newImplementation, data);\\n }\\n }\\n\\n /**\\n * @dev Perform implementation upgrade with security checks for UUPS proxies, and additional setup call.\\n *\\n * Emits an {Upgraded} event.\\n */\\n function _upgradeToAndCallUUPS(\\n address newImplementation,\\n bytes memory data,\\n bool forceCall\\n ) internal {\\n // Upgrades from old implementations will perform a rollback test. This test requires the new\\n // implementation to upgrade back to the old, non-ERC1822 compliant, implementation. Removing\\n // this special case will break upgrade paths from old UUPS implementation to new ones.\\n if (StorageSlot.getBooleanSlot(_ROLLBACK_SLOT).value) {\\n _setImplementation(newImplementation);\\n } else {\\n try IERC1822Proxiable(newImplementation).proxiableUUID() returns (bytes32 slot) {\\n require(slot == _IMPLEMENTATION_SLOT, \\\"ERC1967Upgrade: unsupported proxiableUUID\\\");\\n } catch {\\n revert(\\\"ERC1967Upgrade: new implementation is not UUPS\\\");\\n }\\n _upgradeToAndCall(newImplementation, data, forceCall);\\n }\\n }\\n\\n /**\\n * @dev Storage slot with the admin of the contract.\\n * This is the keccak-256 hash of \\\"eip1967.proxy.admin\\\" subtracted by 1, and is\\n * validated in the constructor.\\n */\\n bytes32 internal constant _ADMIN_SLOT = 0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103;\\n\\n /**\\n * @dev Emitted when the admin account has changed.\\n */\\n event AdminChanged(address previousAdmin, address newAdmin);\\n\\n /**\\n * @dev Returns the current admin.\\n */\\n function _getAdmin() internal view returns (address) {\\n return StorageSlot.getAddressSlot(_ADMIN_SLOT).value;\\n }\\n\\n /**\\n * @dev Stores a new address in the EIP1967 admin slot.\\n */\\n function _setAdmin(address newAdmin) private {\\n require(newAdmin != address(0), \\\"ERC1967: new admin is the zero address\\\");\\n StorageSlot.getAddressSlot(_ADMIN_SLOT).value = newAdmin;\\n }\\n\\n /**\\n * @dev Changes the admin of the proxy.\\n *\\n * Emits an {AdminChanged} event.\\n */\\n function _changeAdmin(address newAdmin) internal {\\n emit AdminChanged(_getAdmin(), newAdmin);\\n _setAdmin(newAdmin);\\n }\\n\\n /**\\n * @dev The storage slot of the UpgradeableBeacon contract which defines the implementation for this proxy.\\n * This is bytes32(uint256(keccak256('eip1967.proxy.beacon')) - 1)) and is validated in the constructor.\\n */\\n bytes32 internal constant _BEACON_SLOT = 0xa3f0ad74e5423aebfd80d3ef4346578335a9a72aeaee59ff6cb3582b35133d50;\\n\\n /**\\n * @dev Emitted when the beacon is upgraded.\\n */\\n event BeaconUpgraded(address indexed beacon);\\n\\n /**\\n * @dev Returns the current beacon.\\n */\\n function _getBeacon() internal view returns (address) {\\n return StorageSlot.getAddressSlot(_BEACON_SLOT).value;\\n }\\n\\n /**\\n * @dev Stores a new beacon in the EIP1967 beacon slot.\\n */\\n function _setBeacon(address newBeacon) private {\\n require(Address.isContract(newBeacon), \\\"ERC1967: new beacon is not a contract\\\");\\n require(\\n Address.isContract(IBeacon(newBeacon).implementation()),\\n \\\"ERC1967: beacon implementation is not a contract\\\"\\n );\\n StorageSlot.getAddressSlot(_BEACON_SLOT).value = newBeacon;\\n }\\n\\n /**\\n * @dev Perform beacon upgrade with additional setup call. Note: This upgrades the address of the beacon, it does\\n * not upgrade the implementation contained in the beacon (see {UpgradeableBeacon-_setImplementation} for that).\\n *\\n * Emits a {BeaconUpgraded} event.\\n */\\n function _upgradeBeaconToAndCall(\\n address newBeacon,\\n bytes memory data,\\n bool forceCall\\n ) internal {\\n _setBeacon(newBeacon);\\n emit BeaconUpgraded(newBeacon);\\n if (data.length > 0 || forceCall) {\\n Address.functionDelegateCall(IBeacon(newBeacon).implementation(), data);\\n }\\n }\\n}\\n\",\"keccak256\":\"0xabf3f59bc0e5423eae45e459dbe92e7052c6983628d39008590edc852a62f94a\",\"license\":\"MIT\"},\"@openzeppelin/contracts/proxy/Proxy.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.6.0) (proxy/Proxy.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev This abstract contract provides a fallback function that delegates all calls to another contract using the EVM\\n * instruction `delegatecall`. We refer to the second contract as the _implementation_ behind the proxy, and it has to\\n * be specified by overriding the virtual {_implementation} function.\\n *\\n * Additionally, delegation to the implementation can be triggered manually through the {_fallback} function, or to a\\n * different contract through the {_delegate} function.\\n *\\n * The success and return data of the delegated call will be returned back to the caller of the proxy.\\n */\\nabstract contract Proxy {\\n /**\\n * @dev Delegates the current call to `implementation`.\\n *\\n * This function does not return to its internal call site, it will return directly to the external caller.\\n */\\n function _delegate(address implementation) internal virtual {\\n assembly {\\n // Copy msg.data. We take full control of memory in this inline assembly\\n // block because it will not return to Solidity code. We overwrite the\\n // Solidity scratch pad at memory position 0.\\n calldatacopy(0, 0, calldatasize())\\n\\n // Call the implementation.\\n // out and outsize are 0 because we don't know the size yet.\\n let result := delegatecall(gas(), implementation, 0, calldatasize(), 0, 0)\\n\\n // Copy the returned data.\\n returndatacopy(0, 0, returndatasize())\\n\\n switch result\\n // delegatecall returns 0 on error.\\n case 0 {\\n revert(0, returndatasize())\\n }\\n default {\\n return(0, returndatasize())\\n }\\n }\\n }\\n\\n /**\\n * @dev This is a virtual function that should be overridden so it returns the address to which the fallback function\\n * and {_fallback} should delegate.\\n */\\n function _implementation() internal view virtual returns (address);\\n\\n /**\\n * @dev Delegates the current call to the address returned by `_implementation()`.\\n *\\n * This function does not return to its internal call site, it will return directly to the external caller.\\n */\\n function _fallback() internal virtual {\\n _beforeFallback();\\n _delegate(_implementation());\\n }\\n\\n /**\\n * @dev Fallback function that delegates calls to the address returned by `_implementation()`. Will run if no other\\n * function in the contract matches the call data.\\n */\\n fallback() external payable virtual {\\n _fallback();\\n }\\n\\n /**\\n * @dev Fallback function that delegates calls to the address returned by `_implementation()`. Will run if call data\\n * is empty.\\n */\\n receive() external payable virtual {\\n _fallback();\\n }\\n\\n /**\\n * @dev Hook that is called before falling back to the implementation. Can happen as part of a manual `_fallback`\\n * call, or as part of the Solidity `fallback` or `receive` functions.\\n *\\n * If overridden should call `super._beforeFallback()`.\\n */\\n function _beforeFallback() internal virtual {}\\n}\\n\",\"keccak256\":\"0xc130fe33f1b2132158531a87734153293f6d07bc263ff4ac90e85da9c82c0e27\",\"license\":\"MIT\"},\"@openzeppelin/contracts/proxy/beacon/IBeacon.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (proxy/beacon/IBeacon.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev This is the interface that {BeaconProxy} expects of its beacon.\\n */\\ninterface IBeacon {\\n /**\\n * @dev Must return an address that can be used as a delegate call target.\\n *\\n * {BeaconProxy} will check that this address is a contract.\\n */\\n function implementation() external view returns (address);\\n}\\n\",\"keccak256\":\"0xd50a3421ac379ccb1be435fa646d66a65c986b4924f0849839f08692f39dde61\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/Address.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.7.0) (utils/Address.sol)\\n\\npragma solidity ^0.8.1;\\n\\n/**\\n * @dev Collection of functions related to the address type\\n */\\nlibrary Address {\\n /**\\n * @dev Returns true if `account` is a contract.\\n *\\n * [IMPORTANT]\\n * ====\\n * It is unsafe to assume that an address for which this function returns\\n * false is an externally-owned account (EOA) and not a contract.\\n *\\n * Among others, `isContract` will return false for the following\\n * types of addresses:\\n *\\n * - an externally-owned account\\n * - a contract in construction\\n * - an address where a contract will be created\\n * - an address where a contract lived, but was destroyed\\n * ====\\n *\\n * [IMPORTANT]\\n * ====\\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\\n *\\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\\n * constructor.\\n * ====\\n */\\n function isContract(address account) internal view returns (bool) {\\n // This method relies on extcodesize/address.code.length, which returns 0\\n // for contracts in construction, since the code is only stored at the end\\n // of the constructor execution.\\n\\n return account.code.length > 0;\\n }\\n\\n /**\\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\\n * `recipient`, forwarding all available gas and reverting on errors.\\n *\\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\\n * imposed by `transfer`, making them unable to receive funds via\\n * `transfer`. {sendValue} removes this limitation.\\n *\\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\\n *\\n * IMPORTANT: because control is transferred to `recipient`, care must be\\n * taken to not create reentrancy vulnerabilities. Consider using\\n * {ReentrancyGuard} or the\\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\\n */\\n function sendValue(address payable recipient, uint256 amount) internal {\\n require(address(this).balance >= amount, \\\"Address: insufficient balance\\\");\\n\\n (bool success, ) = recipient.call{value: amount}(\\\"\\\");\\n require(success, \\\"Address: unable to send value, recipient may have reverted\\\");\\n }\\n\\n /**\\n * @dev Performs a Solidity function call using a low level `call`. A\\n * plain `call` is an unsafe replacement for a function call: use this\\n * function instead.\\n *\\n * If `target` reverts with a revert reason, it is bubbled up by this\\n * function (like regular Solidity function calls).\\n *\\n * Returns the raw returned data. To convert to the expected return value,\\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\\n *\\n * Requirements:\\n *\\n * - `target` must be a contract.\\n * - calling `target` with `data` must not revert.\\n *\\n * _Available since v3.1._\\n */\\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\\n return functionCall(target, data, \\\"Address: low-level call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\\n * `errorMessage` as a fallback revert reason when `target` reverts.\\n *\\n * _Available since v3.1._\\n */\\n function functionCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n return functionCallWithValue(target, data, 0, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but also transferring `value` wei to `target`.\\n *\\n * Requirements:\\n *\\n * - the calling contract must have an ETH balance of at least `value`.\\n * - the called Solidity function must be `payable`.\\n *\\n * _Available since v3.1._\\n */\\n function functionCallWithValue(\\n address target,\\n bytes memory data,\\n uint256 value\\n ) internal returns (bytes memory) {\\n return functionCallWithValue(target, data, value, \\\"Address: low-level call with value failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\\n * with `errorMessage` as a fallback revert reason when `target` reverts.\\n *\\n * _Available since v3.1._\\n */\\n function functionCallWithValue(\\n address target,\\n bytes memory data,\\n uint256 value,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n require(address(this).balance >= value, \\\"Address: insufficient balance for call\\\");\\n require(isContract(target), \\\"Address: call to non-contract\\\");\\n\\n (bool success, bytes memory returndata) = target.call{value: value}(data);\\n return verifyCallResult(success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but performing a static call.\\n *\\n * _Available since v3.3._\\n */\\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\\n return functionStaticCall(target, data, \\\"Address: low-level static call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\\n * but performing a static call.\\n *\\n * _Available since v3.3._\\n */\\n function functionStaticCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal view returns (bytes memory) {\\n require(isContract(target), \\\"Address: static call to non-contract\\\");\\n\\n (bool success, bytes memory returndata) = target.staticcall(data);\\n return verifyCallResult(success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but performing a delegate call.\\n *\\n * _Available since v3.4._\\n */\\n function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {\\n return functionDelegateCall(target, data, \\\"Address: low-level delegate call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\\n * but performing a delegate call.\\n *\\n * _Available since v3.4._\\n */\\n function functionDelegateCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n require(isContract(target), \\\"Address: delegate call to non-contract\\\");\\n\\n (bool success, bytes memory returndata) = target.delegatecall(data);\\n return verifyCallResult(success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the\\n * revert reason using the provided one.\\n *\\n * _Available since v4.3._\\n */\\n function verifyCallResult(\\n bool success,\\n bytes memory returndata,\\n string memory errorMessage\\n ) internal pure returns (bytes memory) {\\n if (success) {\\n return returndata;\\n } else {\\n // Look for revert reason and bubble it up if present\\n if (returndata.length > 0) {\\n // The easiest way to bubble the revert reason is using memory via assembly\\n /// @solidity memory-safe-assembly\\n assembly {\\n let returndata_size := mload(returndata)\\n revert(add(32, returndata), returndata_size)\\n }\\n } else {\\n revert(errorMessage);\\n }\\n }\\n }\\n}\\n\",\"keccak256\":\"0xd6153ce99bcdcce22b124f755e72553295be6abcd63804cfdffceb188b8bef10\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/StorageSlot.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.7.0) (utils/StorageSlot.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Library for reading and writing primitive types to specific storage slots.\\n *\\n * Storage slots are often used to avoid storage conflict when dealing with upgradeable contracts.\\n * This library helps with reading and writing to such slots without the need for inline assembly.\\n *\\n * The functions in this library return Slot structs that contain a `value` member that can be used to read or write.\\n *\\n * Example usage to set ERC1967 implementation slot:\\n * ```\\n * contract ERC1967 {\\n * bytes32 internal constant _IMPLEMENTATION_SLOT = 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc;\\n *\\n * function _getImplementation() internal view returns (address) {\\n * return StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value;\\n * }\\n *\\n * function _setImplementation(address newImplementation) internal {\\n * require(Address.isContract(newImplementation), \\\"ERC1967: new implementation is not a contract\\\");\\n * StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value = newImplementation;\\n * }\\n * }\\n * ```\\n *\\n * _Available since v4.1 for `address`, `bool`, `bytes32`, and `uint256`._\\n */\\nlibrary StorageSlot {\\n struct AddressSlot {\\n address value;\\n }\\n\\n struct BooleanSlot {\\n bool value;\\n }\\n\\n struct Bytes32Slot {\\n bytes32 value;\\n }\\n\\n struct Uint256Slot {\\n uint256 value;\\n }\\n\\n /**\\n * @dev Returns an `AddressSlot` with member `value` located at `slot`.\\n */\\n function getAddressSlot(bytes32 slot) internal pure returns (AddressSlot storage r) {\\n /// @solidity memory-safe-assembly\\n assembly {\\n r.slot := slot\\n }\\n }\\n\\n /**\\n * @dev Returns an `BooleanSlot` with member `value` located at `slot`.\\n */\\n function getBooleanSlot(bytes32 slot) internal pure returns (BooleanSlot storage r) {\\n /// @solidity memory-safe-assembly\\n assembly {\\n r.slot := slot\\n }\\n }\\n\\n /**\\n * @dev Returns an `Bytes32Slot` with member `value` located at `slot`.\\n */\\n function getBytes32Slot(bytes32 slot) internal pure returns (Bytes32Slot storage r) {\\n /// @solidity memory-safe-assembly\\n assembly {\\n r.slot := slot\\n }\\n }\\n\\n /**\\n * @dev Returns an `Uint256Slot` with member `value` located at `slot`.\\n */\\n function getUint256Slot(bytes32 slot) internal pure returns (Uint256Slot storage r) {\\n /// @solidity memory-safe-assembly\\n assembly {\\n r.slot := slot\\n }\\n }\\n}\\n\",\"keccak256\":\"0xd5c50c54bf02740ebd122ff06832546cb5fa84486d52695a9ccfd11666e0c81d\",\"license\":\"MIT\"},\"contracts/external/TransparentUpgradeableProxy.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-3.0\\n\\npragma solidity ^0.8.12;\\n\\nimport \\\"@openzeppelin/contracts/proxy/ERC1967/ERC1967Proxy.sol\\\";\\n\\n/**\\n * @dev This contract implements a proxy that is upgradeable by an admin. It is fully forked from OpenZeppelin\\n * `TransparentUpgradeableProxy`\\n *\\n * To avoid https://medium.com/nomic-labs-blog/malicious-backdoors-in-ethereum-proxies-62629adf3357[proxy selector\\n * clashing], which can potentially be used in an attack, this contract uses the\\n * https://blog.openzeppelin.com/the-transparent-proxy-pattern/[transparent proxy pattern]. This pattern implies two\\n * things that go hand in hand:\\n *\\n * 1. If any account other than the admin calls the proxy, the call will be forwarded to the implementation, even if\\n * that call matches one of the admin functions exposed by the proxy itself.\\n * 2. If the admin calls the proxy, it can access the admin functions, but its calls will never be forwarded to the\\n * implementation. If the admin tries to call a function on the implementation it will fail with an error that says\\n * \\\"admin cannot fallback to proxy target\\\".\\n *\\n * These properties mean that the admin account can only be used for admin actions like upgrading the proxy or changing\\n * the admin, so it's best if it's a dedicated account that is not used for anything else. This will avoid headaches due\\n * to sudden errors when trying to call a function from the proxy implementation.\\n *\\n * Our recommendation is for the dedicated account to be an instance of the {ProxyAdmin} contract. If set up this way,\\n * you should think of the `ProxyAdmin` instance as the real administrative interface of your proxy.\\n */\\ncontract TransparentUpgradeableProxy is ERC1967Proxy {\\n /**\\n * @dev Initializes an upgradeable proxy managed by `_admin`, backed by the implementation at `_logic`, and\\n * optionally initialized with `_data` as explained in {ERC1967Proxy-constructor}.\\n */\\n constructor(address _logic, address admin_, bytes memory _data) payable ERC1967Proxy(_logic, _data) {\\n assert(_ADMIN_SLOT == bytes32(uint256(keccak256(\\\"eip1967.proxy.admin\\\")) - 1));\\n _changeAdmin(admin_);\\n }\\n\\n /**\\n * @dev Modifier used internally that will delegate the call to the implementation unless the sender is the admin.\\n */\\n modifier ifAdmin() {\\n if (msg.sender == _getAdmin()) {\\n _;\\n } else {\\n _fallback();\\n }\\n }\\n\\n /**\\n * @dev Returns the current admin.\\n *\\n * NOTE: Only the admin can call this function. See {ProxyAdmin-getProxyAdmin}.\\n *\\n * TIP: To get this value clients can read directly from the storage slot shown below (specified by EIP1967) using the\\n * https://eth.wiki/json-rpc/API#eth_getstorageat[`eth_getStorageAt`] RPC call.\\n * `0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103`\\n */\\n function admin() external ifAdmin returns (address admin_) {\\n admin_ = _getAdmin();\\n }\\n\\n /**\\n * @dev Returns the current implementation.\\n *\\n * NOTE: Only the admin can call this function. See {ProxyAdmin-getProxyImplementation}.\\n *\\n * TIP: To get this value clients can read directly from the storage slot shown below (specified by EIP1967) using the\\n * https://eth.wiki/json-rpc/API#eth_getstorageat[`eth_getStorageAt`] RPC call.\\n * `0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc`\\n */\\n function implementation() external ifAdmin returns (address implementation_) {\\n implementation_ = _implementation();\\n }\\n\\n /**\\n * @dev Changes the admin of the proxy.\\n *\\n * Emits an {AdminChanged} event.\\n *\\n * NOTE: Only the admin can call this function. See {ProxyAdmin-changeProxyAdmin}.\\n */\\n function changeAdmin(address newAdmin) external virtual ifAdmin {\\n _changeAdmin(newAdmin);\\n }\\n\\n /**\\n * @dev Upgrade the implementation of the proxy.\\n *\\n * NOTE: Only the admin can call this function. See {ProxyAdmin-upgrade}.\\n */\\n function upgradeTo(address newImplementation) external ifAdmin {\\n _upgradeToAndCall(newImplementation, bytes(\\\"\\\"), false);\\n }\\n\\n /**\\n * @dev Upgrade the implementation of the proxy, and then call a function from the new implementation as specified\\n * by `data`, which should be an encoded function call. This is useful to initialize new storage variables in the\\n * proxied contract.\\n *\\n * NOTE: Only the admin can call this function. See {ProxyAdmin-upgradeAndCall}.\\n */\\n function upgradeToAndCall(address newImplementation, bytes calldata data) external payable ifAdmin {\\n _upgradeToAndCall(newImplementation, data, true);\\n }\\n\\n /**\\n * @dev Returns the current admin.\\n */\\n function _admin() internal view virtual returns (address) {\\n return _getAdmin();\\n }\\n\\n /**\\n * @dev Makes sure the admin cannot access the fallback function. See {Proxy-_beforeFallback}.\\n */\\n function _beforeFallback() internal virtual override {\\n require(msg.sender != _getAdmin(), \\\"TransparentUpgradeableProxy: admin cannot fallback to proxy target\\\");\\n super._beforeFallback();\\n }\\n}\\n\",\"keccak256\":\"0x93a67a0f612ea3ff2a76315e138a6a88267270a1379d3cc7be52845fbbe611e2\",\"license\":\"GPL-3.0\"}},\"version\":1}", + "bytecode": "0x6080604052604051620010bb380380620010bb8339810160408190526200002691620004d8565b828162000036828260006200009a565b5062000066905060017fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6104620005b8565b6000805160206200107483398151915214620000865762000086620005da565b6200009182620000d7565b50505062000643565b620000a58362000132565b600082511180620000b35750805b15620000d257620000d083836200017460201b6200028c1760201c565b505b505050565b7f7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f62000102620001a5565b604080516001600160a01b03928316815291841660208301520160405180910390a16200012f81620001de565b50565b6200013d8162000293565b6040516001600160a01b038216907fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b90600090a250565b60606200019c8383604051806060016040528060278152602001620010946027913962000347565b90505b92915050565b6000620001cf6000805160206200107483398151915260001b6200042f60201b6200022e1760201c565b546001600160a01b0316919050565b6001600160a01b038116620002495760405162461bcd60e51b815260206004820152602660248201527f455243313936373a206e65772061646d696e20697320746865207a65726f206160448201526564647265737360d01b60648201526084015b60405180910390fd5b80620002726000805160206200107483398151915260001b6200042f60201b6200022e1760201c565b80546001600160a01b0319166001600160a01b039290921691909117905550565b620002a9816200043260201b620002b81760201c565b6200030d5760405162461bcd60e51b815260206004820152602d60248201527f455243313936373a206e657720696d706c656d656e746174696f6e206973206e60448201526c1bdd08184818dbdb9d1c9858dd609a1b606482015260840162000240565b80620002727f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc60001b6200042f60201b6200022e1760201c565b60606001600160a01b0384163b620003b15760405162461bcd60e51b815260206004820152602660248201527f416464726573733a2064656c65676174652063616c6c20746f206e6f6e2d636f6044820152651b9d1c9858dd60d21b606482015260840162000240565b600080856001600160a01b031685604051620003ce9190620005f0565b600060405180830381855af49150503d80600081146200040b576040519150601f19603f3d011682016040523d82523d6000602084013e62000410565b606091505b5090925090506200042382828662000441565b925050505b9392505050565b90565b6001600160a01b03163b151590565b606083156200045257508162000428565b825115620004635782518084602001fd5b8160405162461bcd60e51b81526004016200024091906200060e565b80516001600160a01b03811681146200049757600080fd5b919050565b634e487b7160e01b600052604160045260246000fd5b60005b83811015620004cf578181015183820152602001620004b5565b50506000910152565b600080600060608486031215620004ee57600080fd5b620004f9846200047f565b925062000509602085016200047f565b60408501519092506001600160401b03808211156200052757600080fd5b818601915086601f8301126200053c57600080fd5b8151818111156200055157620005516200049c565b604051601f8201601f19908116603f011681019083821181831017156200057c576200057c6200049c565b816040528281528960208487010111156200059657600080fd5b620005a9836020830160208801620004b2565b80955050505050509250925092565b818103818111156200019f57634e487b7160e01b600052601160045260246000fd5b634e487b7160e01b600052600160045260246000fd5b6000825162000604818460208701620004b2565b9190910192915050565b60208152600082518060208401526200062f816040850160208701620004b2565b601f01601f19169190910160400192915050565b610a2180620006536000396000f3fe60806040526004361061005e5760003560e01c80635c60da1b116100435780635c60da1b146100a85780638f283970146100e6578063f851a440146101065761006d565b80633659cfe6146100755780634f1ef286146100955761006d565b3661006d5761006b61011b565b005b61006b61011b565b34801561008157600080fd5b5061006b610090366004610895565b610135565b61006b6100a33660046108b0565b61017f565b3480156100b457600080fd5b506100bd6101f3565b60405173ffffffffffffffffffffffffffffffffffffffff909116815260200160405180910390f35b3480156100f257600080fd5b5061006b610101366004610895565b610231565b34801561011257600080fd5b506100bd61025e565b6101236102d4565b61013361012e6103ab565b6103b5565b565b61013d6103d9565b73ffffffffffffffffffffffffffffffffffffffff1633036101775761017481604051806020016040528060008152506000610419565b50565b61017461011b565b6101876103d9565b73ffffffffffffffffffffffffffffffffffffffff1633036101eb576101e68383838080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525060019250610419915050565b505050565b6101e661011b565b60006101fd6103d9565b73ffffffffffffffffffffffffffffffffffffffff163303610226576102216103ab565b905090565b61022e61011b565b90565b6102396103d9565b73ffffffffffffffffffffffffffffffffffffffff1633036101775761017481610444565b60006102686103d9565b73ffffffffffffffffffffffffffffffffffffffff163303610226576102216103d9565b60606102b183836040518060600160405280602781526020016109c5602791396104a5565b9392505050565b73ffffffffffffffffffffffffffffffffffffffff163b151590565b6102dc6103d9565b73ffffffffffffffffffffffffffffffffffffffff163303610133576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604260248201527f5472616e73706172656e745570677261646561626c6550726f78793a2061646d60448201527f696e2063616e6e6f742066616c6c6261636b20746f2070726f7879207461726760648201527f6574000000000000000000000000000000000000000000000000000000000000608482015260a4015b60405180910390fd5b60006102216105cd565b3660008037600080366000845af43d6000803e8080156103d4573d6000f35b3d6000fd5b60007fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035b5473ffffffffffffffffffffffffffffffffffffffff16919050565b610422836105f5565b60008251118061042f5750805b156101e65761043e838361028c565b50505050565b7f7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f61046d6103d9565b6040805173ffffffffffffffffffffffffffffffffffffffff928316815291841660208301520160405180910390a161017481610642565b606073ffffffffffffffffffffffffffffffffffffffff84163b61054b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f416464726573733a2064656c65676174652063616c6c20746f206e6f6e2d636f60448201527f6e7472616374000000000000000000000000000000000000000000000000000060648201526084016103a2565b6000808573ffffffffffffffffffffffffffffffffffffffff16856040516105739190610957565b600060405180830381855af49150503d80600081146105ae576040519150601f19603f3d011682016040523d82523d6000602084013e6105b3565b606091505b50915091506105c382828661074e565b9695505050505050565b60007f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc6103fd565b6105fe816107a1565b60405173ffffffffffffffffffffffffffffffffffffffff8216907fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b90600090a250565b73ffffffffffffffffffffffffffffffffffffffff81166106e5576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f455243313936373a206e65772061646d696e20697320746865207a65726f206160448201527f646472657373000000000000000000000000000000000000000000000000000060648201526084016103a2565b807fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035b80547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff9290921691909117905550565b6060831561075d5750816102b1565b82511561076d5782518084602001fd5b816040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016103a29190610973565b73ffffffffffffffffffffffffffffffffffffffff81163b610845576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602d60248201527f455243313936373a206e657720696d706c656d656e746174696f6e206973206e60448201527f6f74206120636f6e74726163740000000000000000000000000000000000000060648201526084016103a2565b807f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc610708565b803573ffffffffffffffffffffffffffffffffffffffff8116811461089057600080fd5b919050565b6000602082840312156108a757600080fd5b6102b18261086c565b6000806000604084860312156108c557600080fd5b6108ce8461086c565b9250602084013567ffffffffffffffff808211156108eb57600080fd5b818601915086601f8301126108ff57600080fd5b81358181111561090e57600080fd5b87602082850101111561092057600080fd5b6020830194508093505050509250925092565b60005b8381101561094e578181015183820152602001610936565b50506000910152565b60008251610969818460208701610933565b9190910192915050565b6020815260008251806020840152610992816040850160208701610933565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016919091016040019291505056fe416464726573733a206c6f772d6c6576656c2064656c65676174652063616c6c206661696c6564a2646970667358221220e96638b07fb1675d93a95c49e417bc8111448b23a59918698cdcd8fd488dd7cf64736f6c63430008110033b53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103416464726573733a206c6f772d6c6576656c2064656c65676174652063616c6c206661696c6564", + "deployedBytecode": "0x60806040526004361061005e5760003560e01c80635c60da1b116100435780635c60da1b146100a85780638f283970146100e6578063f851a440146101065761006d565b80633659cfe6146100755780634f1ef286146100955761006d565b3661006d5761006b61011b565b005b61006b61011b565b34801561008157600080fd5b5061006b610090366004610895565b610135565b61006b6100a33660046108b0565b61017f565b3480156100b457600080fd5b506100bd6101f3565b60405173ffffffffffffffffffffffffffffffffffffffff909116815260200160405180910390f35b3480156100f257600080fd5b5061006b610101366004610895565b610231565b34801561011257600080fd5b506100bd61025e565b6101236102d4565b61013361012e6103ab565b6103b5565b565b61013d6103d9565b73ffffffffffffffffffffffffffffffffffffffff1633036101775761017481604051806020016040528060008152506000610419565b50565b61017461011b565b6101876103d9565b73ffffffffffffffffffffffffffffffffffffffff1633036101eb576101e68383838080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525060019250610419915050565b505050565b6101e661011b565b60006101fd6103d9565b73ffffffffffffffffffffffffffffffffffffffff163303610226576102216103ab565b905090565b61022e61011b565b90565b6102396103d9565b73ffffffffffffffffffffffffffffffffffffffff1633036101775761017481610444565b60006102686103d9565b73ffffffffffffffffffffffffffffffffffffffff163303610226576102216103d9565b60606102b183836040518060600160405280602781526020016109c5602791396104a5565b9392505050565b73ffffffffffffffffffffffffffffffffffffffff163b151590565b6102dc6103d9565b73ffffffffffffffffffffffffffffffffffffffff163303610133576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604260248201527f5472616e73706172656e745570677261646561626c6550726f78793a2061646d60448201527f696e2063616e6e6f742066616c6c6261636b20746f2070726f7879207461726760648201527f6574000000000000000000000000000000000000000000000000000000000000608482015260a4015b60405180910390fd5b60006102216105cd565b3660008037600080366000845af43d6000803e8080156103d4573d6000f35b3d6000fd5b60007fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035b5473ffffffffffffffffffffffffffffffffffffffff16919050565b610422836105f5565b60008251118061042f5750805b156101e65761043e838361028c565b50505050565b7f7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f61046d6103d9565b6040805173ffffffffffffffffffffffffffffffffffffffff928316815291841660208301520160405180910390a161017481610642565b606073ffffffffffffffffffffffffffffffffffffffff84163b61054b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f416464726573733a2064656c65676174652063616c6c20746f206e6f6e2d636f60448201527f6e7472616374000000000000000000000000000000000000000000000000000060648201526084016103a2565b6000808573ffffffffffffffffffffffffffffffffffffffff16856040516105739190610957565b600060405180830381855af49150503d80600081146105ae576040519150601f19603f3d011682016040523d82523d6000602084013e6105b3565b606091505b50915091506105c382828661074e565b9695505050505050565b60007f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc6103fd565b6105fe816107a1565b60405173ffffffffffffffffffffffffffffffffffffffff8216907fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b90600090a250565b73ffffffffffffffffffffffffffffffffffffffff81166106e5576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f455243313936373a206e65772061646d696e20697320746865207a65726f206160448201527f646472657373000000000000000000000000000000000000000000000000000060648201526084016103a2565b807fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035b80547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff9290921691909117905550565b6060831561075d5750816102b1565b82511561076d5782518084602001fd5b816040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016103a29190610973565b73ffffffffffffffffffffffffffffffffffffffff81163b610845576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602d60248201527f455243313936373a206e657720696d706c656d656e746174696f6e206973206e60448201527f6f74206120636f6e74726163740000000000000000000000000000000000000060648201526084016103a2565b807f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc610708565b803573ffffffffffffffffffffffffffffffffffffffff8116811461089057600080fd5b919050565b6000602082840312156108a757600080fd5b6102b18261086c565b6000806000604084860312156108c557600080fd5b6108ce8461086c565b9250602084013567ffffffffffffffff808211156108eb57600080fd5b818601915086601f8301126108ff57600080fd5b81358181111561090e57600080fd5b87602082850101111561092057600080fd5b6020830194508093505050509250925092565b60005b8381101561094e578181015183820152602001610936565b50506000910152565b60008251610969818460208701610933565b9190910192915050565b6020815260008251806020840152610992816040850160208701610933565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016919091016040019291505056fe416464726573733a206c6f772d6c6576656c2064656c65676174652063616c6c206661696c6564a2646970667358221220e96638b07fb1675d93a95c49e417bc8111448b23a59918698cdcd8fd488dd7cf64736f6c63430008110033", + "devdoc": { + "details": "This contract implements a proxy that is upgradeable by an admin. It is fully forked from OpenZeppelin `TransparentUpgradeableProxy` To avoid https://medium.com/nomic-labs-blog/malicious-backdoors-in-ethereum-proxies-62629adf3357[proxy selector clashing], which can potentially be used in an attack, this contract uses the https://blog.openzeppelin.com/the-transparent-proxy-pattern/[transparent proxy pattern]. This pattern implies two things that go hand in hand: 1. If any account other than the admin calls the proxy, the call will be forwarded to the implementation, even if that call matches one of the admin functions exposed by the proxy itself. 2. If the admin calls the proxy, it can access the admin functions, but its calls will never be forwarded to the implementation. If the admin tries to call a function on the implementation it will fail with an error that says \"admin cannot fallback to proxy target\". These properties mean that the admin account can only be used for admin actions like upgrading the proxy or changing the admin, so it's best if it's a dedicated account that is not used for anything else. This will avoid headaches due to sudden errors when trying to call a function from the proxy implementation. Our recommendation is for the dedicated account to be an instance of the {ProxyAdmin} contract. If set up this way, you should think of the `ProxyAdmin` instance as the real administrative interface of your proxy.", + "kind": "dev", + "methods": { + "admin()": { + "details": "Returns the current admin. NOTE: Only the admin can call this function. See {ProxyAdmin-getProxyAdmin}. TIP: To get this value clients can read directly from the storage slot shown below (specified by EIP1967) using the https://eth.wiki/json-rpc/API#eth_getstorageat[`eth_getStorageAt`] RPC call. `0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103`" + }, + "changeAdmin(address)": { + "details": "Changes the admin of the proxy. Emits an {AdminChanged} event. NOTE: Only the admin can call this function. See {ProxyAdmin-changeProxyAdmin}." + }, + "constructor": { + "details": "Initializes an upgradeable proxy managed by `_admin`, backed by the implementation at `_logic`, and optionally initialized with `_data` as explained in {ERC1967Proxy-constructor}." + }, + "implementation()": { + "details": "Returns the current implementation. NOTE: Only the admin can call this function. See {ProxyAdmin-getProxyImplementation}. TIP: To get this value clients can read directly from the storage slot shown below (specified by EIP1967) using the https://eth.wiki/json-rpc/API#eth_getstorageat[`eth_getStorageAt`] RPC call. `0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc`" + }, + "upgradeTo(address)": { + "details": "Upgrade the implementation of the proxy. NOTE: Only the admin can call this function. See {ProxyAdmin-upgrade}." + }, + "upgradeToAndCall(address,bytes)": { + "details": "Upgrade the implementation of the proxy, and then call a function from the new implementation as specified by `data`, which should be an encoded function call. This is useful to initialize new storage variables in the proxied contract. NOTE: Only the admin can call this function. See {ProxyAdmin-upgradeAndCall}." + } + }, + "version": 1 + }, + "userdoc": { + "kind": "user", + "methods": {}, + "version": 1 + }, + "storageLayout": { + "storage": [], + "types": null + } +} \ No newline at end of file diff --git a/deployments/avalanche/Treasury_USD.json b/deployments/avalanche/Treasury_USD.json new file mode 100644 index 00000000..19e37bd1 --- /dev/null +++ b/deployments/avalanche/Treasury_USD.json @@ -0,0 +1,235 @@ +{ + "address": "0xdE725566Fa2bAfd175066943D8D50ae762058e92", + "abi": [ + { + "inputs": [ + { + "internalType": "address", + "name": "_logic", + "type": "address" + }, + { + "internalType": "address", + "name": "admin_", + "type": "address" + }, + { + "internalType": "bytes", + "name": "_data", + "type": "bytes" + } + ], + "stateMutability": "payable", + "type": "constructor" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "previousAdmin", + "type": "address" + }, + { + "indexed": false, + "internalType": "address", + "name": "newAdmin", + "type": "address" + } + ], + "name": "AdminChanged", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "beacon", + "type": "address" + } + ], + "name": "BeaconUpgraded", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "implementation", + "type": "address" + } + ], + "name": "Upgraded", + "type": "event" + }, + { + "stateMutability": "payable", + "type": "fallback" + }, + { + "inputs": [], + "name": "admin", + "outputs": [ + { + "internalType": "address", + "name": "admin_", + "type": "address" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "newAdmin", + "type": "address" + } + ], + "name": "changeAdmin", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "implementation", + "outputs": [ + { + "internalType": "address", + "name": "implementation_", + "type": "address" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "newImplementation", + "type": "address" + } + ], + "name": "upgradeTo", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "newImplementation", + "type": "address" + }, + { + "internalType": "bytes", + "name": "data", + "type": "bytes" + } + ], + "name": "upgradeToAndCall", + "outputs": [], + "stateMutability": "payable", + "type": "function" + }, + { + "stateMutability": "payable", + "type": "receive" + } + ], + "transactionHash": "0x33f138264780bc8a03bf6f94c788b5f277a498b875c9d63490886614c52797b0", + "receipt": { + "to": null, + "from": "0xfdA462548Ce04282f4B6D6619823a7C64Fdc0185", + "contractAddress": "0xdE725566Fa2bAfd175066943D8D50ae762058e92", + "transactionIndex": 7, + "gasUsed": "734966", + "logsBloom": "0x00000000000000000000000000000000400000000000000000000000000000000000000000000000000000800000000000002000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000000000000800000000000000000000004000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000200000200000000000000000020000000000000000000000000000000000400000000000000002000000000000000000000000000000000000000000000000000000000000000000000", + "blockHash": "0x6b49af3a19b73bfc98ff209ee2b4a118a806363fda33c97b6929227759f7eb81", + "transactionHash": "0x33f138264780bc8a03bf6f94c788b5f277a498b875c9d63490886614c52797b0", + "logs": [ + { + "transactionIndex": 7, + "blockNumber": 40179216, + "transactionHash": "0x33f138264780bc8a03bf6f94c788b5f277a498b875c9d63490886614c52797b0", + "address": "0xdE725566Fa2bAfd175066943D8D50ae762058e92", + "topics": [ + "0xbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b", + "0x00000000000000000000000016cd38b1b54e7abf307cb2697e2d9321e843d5aa" + ], + "data": "0x", + "logIndex": 25, + "blockHash": "0x6b49af3a19b73bfc98ff209ee2b4a118a806363fda33c97b6929227759f7eb81" + }, + { + "transactionIndex": 7, + "blockNumber": 40179216, + "transactionHash": "0x33f138264780bc8a03bf6f94c788b5f277a498b875c9d63490886614c52797b0", + "address": "0xdE725566Fa2bAfd175066943D8D50ae762058e92", + "topics": [ + "0x7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f" + ], + "data": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000007ab641e661a9728913a44e06f6a4879481142ddb", + "logIndex": 26, + "blockHash": "0x6b49af3a19b73bfc98ff209ee2b4a118a806363fda33c97b6929227759f7eb81" + } + ], + "blockNumber": 40179216, + "cumulativeGasUsed": "2017149", + "status": 1, + "byzantium": true + }, + "args": [ + "0x16cd38b1B54E7abf307Cb2697E2D9321e843d5AA", + "0x7AB641E661a9728913A44e06f6a4879481142DDb", + "0x485cc955000000000000000000000000e8426450d46f4ed4e667e96c7ea53bae518ff8eb0000000000000000000000000000206329b97db379d5e1bf586bbdb969c63274" + ], + "numDeployments": 1, + "solcInputHash": "871924e0c138825a2736b76def8fef8d", + "metadata": "{\"compiler\":{\"version\":\"0.8.17+commit.8df45f5f\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_logic\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"admin_\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"_data\",\"type\":\"bytes\"}],\"stateMutability\":\"payable\",\"type\":\"constructor\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"previousAdmin\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"newAdmin\",\"type\":\"address\"}],\"name\":\"AdminChanged\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"beacon\",\"type\":\"address\"}],\"name\":\"BeaconUpgraded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"implementation\",\"type\":\"address\"}],\"name\":\"Upgraded\",\"type\":\"event\"},{\"stateMutability\":\"payable\",\"type\":\"fallback\"},{\"inputs\":[],\"name\":\"admin\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"admin_\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newAdmin\",\"type\":\"address\"}],\"name\":\"changeAdmin\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"implementation\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"implementation_\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newImplementation\",\"type\":\"address\"}],\"name\":\"upgradeTo\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newImplementation\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"}],\"name\":\"upgradeToAndCall\",\"outputs\":[],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"stateMutability\":\"payable\",\"type\":\"receive\"}],\"devdoc\":{\"details\":\"This contract implements a proxy that is upgradeable by an admin. It is fully forked from OpenZeppelin `TransparentUpgradeableProxy` To avoid https://medium.com/nomic-labs-blog/malicious-backdoors-in-ethereum-proxies-62629adf3357[proxy selector clashing], which can potentially be used in an attack, this contract uses the https://blog.openzeppelin.com/the-transparent-proxy-pattern/[transparent proxy pattern]. This pattern implies two things that go hand in hand: 1. If any account other than the admin calls the proxy, the call will be forwarded to the implementation, even if that call matches one of the admin functions exposed by the proxy itself. 2. If the admin calls the proxy, it can access the admin functions, but its calls will never be forwarded to the implementation. If the admin tries to call a function on the implementation it will fail with an error that says \\\"admin cannot fallback to proxy target\\\". These properties mean that the admin account can only be used for admin actions like upgrading the proxy or changing the admin, so it's best if it's a dedicated account that is not used for anything else. This will avoid headaches due to sudden errors when trying to call a function from the proxy implementation. Our recommendation is for the dedicated account to be an instance of the {ProxyAdmin} contract. If set up this way, you should think of the `ProxyAdmin` instance as the real administrative interface of your proxy.\",\"kind\":\"dev\",\"methods\":{\"admin()\":{\"details\":\"Returns the current admin. NOTE: Only the admin can call this function. See {ProxyAdmin-getProxyAdmin}. TIP: To get this value clients can read directly from the storage slot shown below (specified by EIP1967) using the https://eth.wiki/json-rpc/API#eth_getstorageat[`eth_getStorageAt`] RPC call. `0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103`\"},\"changeAdmin(address)\":{\"details\":\"Changes the admin of the proxy. Emits an {AdminChanged} event. NOTE: Only the admin can call this function. See {ProxyAdmin-changeProxyAdmin}.\"},\"constructor\":{\"details\":\"Initializes an upgradeable proxy managed by `_admin`, backed by the implementation at `_logic`, and optionally initialized with `_data` as explained in {ERC1967Proxy-constructor}.\"},\"implementation()\":{\"details\":\"Returns the current implementation. NOTE: Only the admin can call this function. See {ProxyAdmin-getProxyImplementation}. TIP: To get this value clients can read directly from the storage slot shown below (specified by EIP1967) using the https://eth.wiki/json-rpc/API#eth_getstorageat[`eth_getStorageAt`] RPC call. `0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc`\"},\"upgradeTo(address)\":{\"details\":\"Upgrade the implementation of the proxy. NOTE: Only the admin can call this function. See {ProxyAdmin-upgrade}.\"},\"upgradeToAndCall(address,bytes)\":{\"details\":\"Upgrade the implementation of the proxy, and then call a function from the new implementation as specified by `data`, which should be an encoded function call. This is useful to initialize new storage variables in the proxied contract. NOTE: Only the admin can call this function. See {ProxyAdmin-upgradeAndCall}.\"}},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/external/TransparentUpgradeableProxy.sol\":\"TransparentUpgradeableProxy\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":1000000},\"remappings\":[]},\"sources\":{\"@openzeppelin/contracts/interfaces/draft-IERC1822.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.5.0) (interfaces/draft-IERC1822.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev ERC1822: Universal Upgradeable Proxy Standard (UUPS) documents a method for upgradeability through a simplified\\n * proxy whose upgrades are fully controlled by the current implementation.\\n */\\ninterface IERC1822Proxiable {\\n /**\\n * @dev Returns the storage slot that the proxiable contract assumes is being used to store the implementation\\n * address.\\n *\\n * IMPORTANT: A proxy pointing at a proxiable contract should not be considered proxiable itself, because this risks\\n * bricking a proxy that upgrades to it, by delegating to itself until out of gas. Thus it is critical that this\\n * function revert if invoked through a proxy.\\n */\\n function proxiableUUID() external view returns (bytes32);\\n}\\n\",\"keccak256\":\"0x1d4afe6cb24200cc4545eed814ecf5847277dfe5d613a1707aad5fceecebcfff\",\"license\":\"MIT\"},\"@openzeppelin/contracts/proxy/ERC1967/ERC1967Proxy.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.7.0) (proxy/ERC1967/ERC1967Proxy.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../Proxy.sol\\\";\\nimport \\\"./ERC1967Upgrade.sol\\\";\\n\\n/**\\n * @dev This contract implements an upgradeable proxy. It is upgradeable because calls are delegated to an\\n * implementation address that can be changed. This address is stored in storage in the location specified by\\n * https://eips.ethereum.org/EIPS/eip-1967[EIP1967], so that it doesn't conflict with the storage layout of the\\n * implementation behind the proxy.\\n */\\ncontract ERC1967Proxy is Proxy, ERC1967Upgrade {\\n /**\\n * @dev Initializes the upgradeable proxy with an initial implementation specified by `_logic`.\\n *\\n * If `_data` is nonempty, it's used as data in a delegate call to `_logic`. This will typically be an encoded\\n * function call, and allows initializing the storage of the proxy like a Solidity constructor.\\n */\\n constructor(address _logic, bytes memory _data) payable {\\n _upgradeToAndCall(_logic, _data, false);\\n }\\n\\n /**\\n * @dev Returns the current implementation address.\\n */\\n function _implementation() internal view virtual override returns (address impl) {\\n return ERC1967Upgrade._getImplementation();\\n }\\n}\\n\",\"keccak256\":\"0xa2b22da3032e50b55f95ec1d13336102d675f341167aa76db571ef7f8bb7975d\",\"license\":\"MIT\"},\"@openzeppelin/contracts/proxy/ERC1967/ERC1967Upgrade.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.5.0) (proxy/ERC1967/ERC1967Upgrade.sol)\\n\\npragma solidity ^0.8.2;\\n\\nimport \\\"../beacon/IBeacon.sol\\\";\\nimport \\\"../../interfaces/draft-IERC1822.sol\\\";\\nimport \\\"../../utils/Address.sol\\\";\\nimport \\\"../../utils/StorageSlot.sol\\\";\\n\\n/**\\n * @dev This abstract contract provides getters and event emitting update functions for\\n * https://eips.ethereum.org/EIPS/eip-1967[EIP1967] slots.\\n *\\n * _Available since v4.1._\\n *\\n * @custom:oz-upgrades-unsafe-allow delegatecall\\n */\\nabstract contract ERC1967Upgrade {\\n // This is the keccak-256 hash of \\\"eip1967.proxy.rollback\\\" subtracted by 1\\n bytes32 private constant _ROLLBACK_SLOT = 0x4910fdfa16fed3260ed0e7147f7cc6da11a60208b5b9406d12a635614ffd9143;\\n\\n /**\\n * @dev Storage slot with the address of the current implementation.\\n * This is the keccak-256 hash of \\\"eip1967.proxy.implementation\\\" subtracted by 1, and is\\n * validated in the constructor.\\n */\\n bytes32 internal constant _IMPLEMENTATION_SLOT = 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc;\\n\\n /**\\n * @dev Emitted when the implementation is upgraded.\\n */\\n event Upgraded(address indexed implementation);\\n\\n /**\\n * @dev Returns the current implementation address.\\n */\\n function _getImplementation() internal view returns (address) {\\n return StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value;\\n }\\n\\n /**\\n * @dev Stores a new address in the EIP1967 implementation slot.\\n */\\n function _setImplementation(address newImplementation) private {\\n require(Address.isContract(newImplementation), \\\"ERC1967: new implementation is not a contract\\\");\\n StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value = newImplementation;\\n }\\n\\n /**\\n * @dev Perform implementation upgrade\\n *\\n * Emits an {Upgraded} event.\\n */\\n function _upgradeTo(address newImplementation) internal {\\n _setImplementation(newImplementation);\\n emit Upgraded(newImplementation);\\n }\\n\\n /**\\n * @dev Perform implementation upgrade with additional setup call.\\n *\\n * Emits an {Upgraded} event.\\n */\\n function _upgradeToAndCall(\\n address newImplementation,\\n bytes memory data,\\n bool forceCall\\n ) internal {\\n _upgradeTo(newImplementation);\\n if (data.length > 0 || forceCall) {\\n Address.functionDelegateCall(newImplementation, data);\\n }\\n }\\n\\n /**\\n * @dev Perform implementation upgrade with security checks for UUPS proxies, and additional setup call.\\n *\\n * Emits an {Upgraded} event.\\n */\\n function _upgradeToAndCallUUPS(\\n address newImplementation,\\n bytes memory data,\\n bool forceCall\\n ) internal {\\n // Upgrades from old implementations will perform a rollback test. This test requires the new\\n // implementation to upgrade back to the old, non-ERC1822 compliant, implementation. Removing\\n // this special case will break upgrade paths from old UUPS implementation to new ones.\\n if (StorageSlot.getBooleanSlot(_ROLLBACK_SLOT).value) {\\n _setImplementation(newImplementation);\\n } else {\\n try IERC1822Proxiable(newImplementation).proxiableUUID() returns (bytes32 slot) {\\n require(slot == _IMPLEMENTATION_SLOT, \\\"ERC1967Upgrade: unsupported proxiableUUID\\\");\\n } catch {\\n revert(\\\"ERC1967Upgrade: new implementation is not UUPS\\\");\\n }\\n _upgradeToAndCall(newImplementation, data, forceCall);\\n }\\n }\\n\\n /**\\n * @dev Storage slot with the admin of the contract.\\n * This is the keccak-256 hash of \\\"eip1967.proxy.admin\\\" subtracted by 1, and is\\n * validated in the constructor.\\n */\\n bytes32 internal constant _ADMIN_SLOT = 0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103;\\n\\n /**\\n * @dev Emitted when the admin account has changed.\\n */\\n event AdminChanged(address previousAdmin, address newAdmin);\\n\\n /**\\n * @dev Returns the current admin.\\n */\\n function _getAdmin() internal view returns (address) {\\n return StorageSlot.getAddressSlot(_ADMIN_SLOT).value;\\n }\\n\\n /**\\n * @dev Stores a new address in the EIP1967 admin slot.\\n */\\n function _setAdmin(address newAdmin) private {\\n require(newAdmin != address(0), \\\"ERC1967: new admin is the zero address\\\");\\n StorageSlot.getAddressSlot(_ADMIN_SLOT).value = newAdmin;\\n }\\n\\n /**\\n * @dev Changes the admin of the proxy.\\n *\\n * Emits an {AdminChanged} event.\\n */\\n function _changeAdmin(address newAdmin) internal {\\n emit AdminChanged(_getAdmin(), newAdmin);\\n _setAdmin(newAdmin);\\n }\\n\\n /**\\n * @dev The storage slot of the UpgradeableBeacon contract which defines the implementation for this proxy.\\n * This is bytes32(uint256(keccak256('eip1967.proxy.beacon')) - 1)) and is validated in the constructor.\\n */\\n bytes32 internal constant _BEACON_SLOT = 0xa3f0ad74e5423aebfd80d3ef4346578335a9a72aeaee59ff6cb3582b35133d50;\\n\\n /**\\n * @dev Emitted when the beacon is upgraded.\\n */\\n event BeaconUpgraded(address indexed beacon);\\n\\n /**\\n * @dev Returns the current beacon.\\n */\\n function _getBeacon() internal view returns (address) {\\n return StorageSlot.getAddressSlot(_BEACON_SLOT).value;\\n }\\n\\n /**\\n * @dev Stores a new beacon in the EIP1967 beacon slot.\\n */\\n function _setBeacon(address newBeacon) private {\\n require(Address.isContract(newBeacon), \\\"ERC1967: new beacon is not a contract\\\");\\n require(\\n Address.isContract(IBeacon(newBeacon).implementation()),\\n \\\"ERC1967: beacon implementation is not a contract\\\"\\n );\\n StorageSlot.getAddressSlot(_BEACON_SLOT).value = newBeacon;\\n }\\n\\n /**\\n * @dev Perform beacon upgrade with additional setup call. Note: This upgrades the address of the beacon, it does\\n * not upgrade the implementation contained in the beacon (see {UpgradeableBeacon-_setImplementation} for that).\\n *\\n * Emits a {BeaconUpgraded} event.\\n */\\n function _upgradeBeaconToAndCall(\\n address newBeacon,\\n bytes memory data,\\n bool forceCall\\n ) internal {\\n _setBeacon(newBeacon);\\n emit BeaconUpgraded(newBeacon);\\n if (data.length > 0 || forceCall) {\\n Address.functionDelegateCall(IBeacon(newBeacon).implementation(), data);\\n }\\n }\\n}\\n\",\"keccak256\":\"0xabf3f59bc0e5423eae45e459dbe92e7052c6983628d39008590edc852a62f94a\",\"license\":\"MIT\"},\"@openzeppelin/contracts/proxy/Proxy.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.6.0) (proxy/Proxy.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev This abstract contract provides a fallback function that delegates all calls to another contract using the EVM\\n * instruction `delegatecall`. We refer to the second contract as the _implementation_ behind the proxy, and it has to\\n * be specified by overriding the virtual {_implementation} function.\\n *\\n * Additionally, delegation to the implementation can be triggered manually through the {_fallback} function, or to a\\n * different contract through the {_delegate} function.\\n *\\n * The success and return data of the delegated call will be returned back to the caller of the proxy.\\n */\\nabstract contract Proxy {\\n /**\\n * @dev Delegates the current call to `implementation`.\\n *\\n * This function does not return to its internal call site, it will return directly to the external caller.\\n */\\n function _delegate(address implementation) internal virtual {\\n assembly {\\n // Copy msg.data. We take full control of memory in this inline assembly\\n // block because it will not return to Solidity code. We overwrite the\\n // Solidity scratch pad at memory position 0.\\n calldatacopy(0, 0, calldatasize())\\n\\n // Call the implementation.\\n // out and outsize are 0 because we don't know the size yet.\\n let result := delegatecall(gas(), implementation, 0, calldatasize(), 0, 0)\\n\\n // Copy the returned data.\\n returndatacopy(0, 0, returndatasize())\\n\\n switch result\\n // delegatecall returns 0 on error.\\n case 0 {\\n revert(0, returndatasize())\\n }\\n default {\\n return(0, returndatasize())\\n }\\n }\\n }\\n\\n /**\\n * @dev This is a virtual function that should be overridden so it returns the address to which the fallback function\\n * and {_fallback} should delegate.\\n */\\n function _implementation() internal view virtual returns (address);\\n\\n /**\\n * @dev Delegates the current call to the address returned by `_implementation()`.\\n *\\n * This function does not return to its internal call site, it will return directly to the external caller.\\n */\\n function _fallback() internal virtual {\\n _beforeFallback();\\n _delegate(_implementation());\\n }\\n\\n /**\\n * @dev Fallback function that delegates calls to the address returned by `_implementation()`. Will run if no other\\n * function in the contract matches the call data.\\n */\\n fallback() external payable virtual {\\n _fallback();\\n }\\n\\n /**\\n * @dev Fallback function that delegates calls to the address returned by `_implementation()`. Will run if call data\\n * is empty.\\n */\\n receive() external payable virtual {\\n _fallback();\\n }\\n\\n /**\\n * @dev Hook that is called before falling back to the implementation. Can happen as part of a manual `_fallback`\\n * call, or as part of the Solidity `fallback` or `receive` functions.\\n *\\n * If overridden should call `super._beforeFallback()`.\\n */\\n function _beforeFallback() internal virtual {}\\n}\\n\",\"keccak256\":\"0xc130fe33f1b2132158531a87734153293f6d07bc263ff4ac90e85da9c82c0e27\",\"license\":\"MIT\"},\"@openzeppelin/contracts/proxy/beacon/IBeacon.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (proxy/beacon/IBeacon.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev This is the interface that {BeaconProxy} expects of its beacon.\\n */\\ninterface IBeacon {\\n /**\\n * @dev Must return an address that can be used as a delegate call target.\\n *\\n * {BeaconProxy} will check that this address is a contract.\\n */\\n function implementation() external view returns (address);\\n}\\n\",\"keccak256\":\"0xd50a3421ac379ccb1be435fa646d66a65c986b4924f0849839f08692f39dde61\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/Address.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.7.0) (utils/Address.sol)\\n\\npragma solidity ^0.8.1;\\n\\n/**\\n * @dev Collection of functions related to the address type\\n */\\nlibrary Address {\\n /**\\n * @dev Returns true if `account` is a contract.\\n *\\n * [IMPORTANT]\\n * ====\\n * It is unsafe to assume that an address for which this function returns\\n * false is an externally-owned account (EOA) and not a contract.\\n *\\n * Among others, `isContract` will return false for the following\\n * types of addresses:\\n *\\n * - an externally-owned account\\n * - a contract in construction\\n * - an address where a contract will be created\\n * - an address where a contract lived, but was destroyed\\n * ====\\n *\\n * [IMPORTANT]\\n * ====\\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\\n *\\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\\n * constructor.\\n * ====\\n */\\n function isContract(address account) internal view returns (bool) {\\n // This method relies on extcodesize/address.code.length, which returns 0\\n // for contracts in construction, since the code is only stored at the end\\n // of the constructor execution.\\n\\n return account.code.length > 0;\\n }\\n\\n /**\\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\\n * `recipient`, forwarding all available gas and reverting on errors.\\n *\\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\\n * imposed by `transfer`, making them unable to receive funds via\\n * `transfer`. {sendValue} removes this limitation.\\n *\\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\\n *\\n * IMPORTANT: because control is transferred to `recipient`, care must be\\n * taken to not create reentrancy vulnerabilities. Consider using\\n * {ReentrancyGuard} or the\\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\\n */\\n function sendValue(address payable recipient, uint256 amount) internal {\\n require(address(this).balance >= amount, \\\"Address: insufficient balance\\\");\\n\\n (bool success, ) = recipient.call{value: amount}(\\\"\\\");\\n require(success, \\\"Address: unable to send value, recipient may have reverted\\\");\\n }\\n\\n /**\\n * @dev Performs a Solidity function call using a low level `call`. A\\n * plain `call` is an unsafe replacement for a function call: use this\\n * function instead.\\n *\\n * If `target` reverts with a revert reason, it is bubbled up by this\\n * function (like regular Solidity function calls).\\n *\\n * Returns the raw returned data. To convert to the expected return value,\\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\\n *\\n * Requirements:\\n *\\n * - `target` must be a contract.\\n * - calling `target` with `data` must not revert.\\n *\\n * _Available since v3.1._\\n */\\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\\n return functionCall(target, data, \\\"Address: low-level call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\\n * `errorMessage` as a fallback revert reason when `target` reverts.\\n *\\n * _Available since v3.1._\\n */\\n function functionCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n return functionCallWithValue(target, data, 0, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but also transferring `value` wei to `target`.\\n *\\n * Requirements:\\n *\\n * - the calling contract must have an ETH balance of at least `value`.\\n * - the called Solidity function must be `payable`.\\n *\\n * _Available since v3.1._\\n */\\n function functionCallWithValue(\\n address target,\\n bytes memory data,\\n uint256 value\\n ) internal returns (bytes memory) {\\n return functionCallWithValue(target, data, value, \\\"Address: low-level call with value failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\\n * with `errorMessage` as a fallback revert reason when `target` reverts.\\n *\\n * _Available since v3.1._\\n */\\n function functionCallWithValue(\\n address target,\\n bytes memory data,\\n uint256 value,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n require(address(this).balance >= value, \\\"Address: insufficient balance for call\\\");\\n require(isContract(target), \\\"Address: call to non-contract\\\");\\n\\n (bool success, bytes memory returndata) = target.call{value: value}(data);\\n return verifyCallResult(success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but performing a static call.\\n *\\n * _Available since v3.3._\\n */\\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\\n return functionStaticCall(target, data, \\\"Address: low-level static call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\\n * but performing a static call.\\n *\\n * _Available since v3.3._\\n */\\n function functionStaticCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal view returns (bytes memory) {\\n require(isContract(target), \\\"Address: static call to non-contract\\\");\\n\\n (bool success, bytes memory returndata) = target.staticcall(data);\\n return verifyCallResult(success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but performing a delegate call.\\n *\\n * _Available since v3.4._\\n */\\n function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {\\n return functionDelegateCall(target, data, \\\"Address: low-level delegate call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\\n * but performing a delegate call.\\n *\\n * _Available since v3.4._\\n */\\n function functionDelegateCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n require(isContract(target), \\\"Address: delegate call to non-contract\\\");\\n\\n (bool success, bytes memory returndata) = target.delegatecall(data);\\n return verifyCallResult(success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the\\n * revert reason using the provided one.\\n *\\n * _Available since v4.3._\\n */\\n function verifyCallResult(\\n bool success,\\n bytes memory returndata,\\n string memory errorMessage\\n ) internal pure returns (bytes memory) {\\n if (success) {\\n return returndata;\\n } else {\\n // Look for revert reason and bubble it up if present\\n if (returndata.length > 0) {\\n // The easiest way to bubble the revert reason is using memory via assembly\\n /// @solidity memory-safe-assembly\\n assembly {\\n let returndata_size := mload(returndata)\\n revert(add(32, returndata), returndata_size)\\n }\\n } else {\\n revert(errorMessage);\\n }\\n }\\n }\\n}\\n\",\"keccak256\":\"0xd6153ce99bcdcce22b124f755e72553295be6abcd63804cfdffceb188b8bef10\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/StorageSlot.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.7.0) (utils/StorageSlot.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Library for reading and writing primitive types to specific storage slots.\\n *\\n * Storage slots are often used to avoid storage conflict when dealing with upgradeable contracts.\\n * This library helps with reading and writing to such slots without the need for inline assembly.\\n *\\n * The functions in this library return Slot structs that contain a `value` member that can be used to read or write.\\n *\\n * Example usage to set ERC1967 implementation slot:\\n * ```\\n * contract ERC1967 {\\n * bytes32 internal constant _IMPLEMENTATION_SLOT = 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc;\\n *\\n * function _getImplementation() internal view returns (address) {\\n * return StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value;\\n * }\\n *\\n * function _setImplementation(address newImplementation) internal {\\n * require(Address.isContract(newImplementation), \\\"ERC1967: new implementation is not a contract\\\");\\n * StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value = newImplementation;\\n * }\\n * }\\n * ```\\n *\\n * _Available since v4.1 for `address`, `bool`, `bytes32`, and `uint256`._\\n */\\nlibrary StorageSlot {\\n struct AddressSlot {\\n address value;\\n }\\n\\n struct BooleanSlot {\\n bool value;\\n }\\n\\n struct Bytes32Slot {\\n bytes32 value;\\n }\\n\\n struct Uint256Slot {\\n uint256 value;\\n }\\n\\n /**\\n * @dev Returns an `AddressSlot` with member `value` located at `slot`.\\n */\\n function getAddressSlot(bytes32 slot) internal pure returns (AddressSlot storage r) {\\n /// @solidity memory-safe-assembly\\n assembly {\\n r.slot := slot\\n }\\n }\\n\\n /**\\n * @dev Returns an `BooleanSlot` with member `value` located at `slot`.\\n */\\n function getBooleanSlot(bytes32 slot) internal pure returns (BooleanSlot storage r) {\\n /// @solidity memory-safe-assembly\\n assembly {\\n r.slot := slot\\n }\\n }\\n\\n /**\\n * @dev Returns an `Bytes32Slot` with member `value` located at `slot`.\\n */\\n function getBytes32Slot(bytes32 slot) internal pure returns (Bytes32Slot storage r) {\\n /// @solidity memory-safe-assembly\\n assembly {\\n r.slot := slot\\n }\\n }\\n\\n /**\\n * @dev Returns an `Uint256Slot` with member `value` located at `slot`.\\n */\\n function getUint256Slot(bytes32 slot) internal pure returns (Uint256Slot storage r) {\\n /// @solidity memory-safe-assembly\\n assembly {\\n r.slot := slot\\n }\\n }\\n}\\n\",\"keccak256\":\"0xd5c50c54bf02740ebd122ff06832546cb5fa84486d52695a9ccfd11666e0c81d\",\"license\":\"MIT\"},\"contracts/external/TransparentUpgradeableProxy.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-3.0\\n\\npragma solidity ^0.8.12;\\n\\nimport \\\"@openzeppelin/contracts/proxy/ERC1967/ERC1967Proxy.sol\\\";\\n\\n/**\\n * @dev This contract implements a proxy that is upgradeable by an admin. It is fully forked from OpenZeppelin\\n * `TransparentUpgradeableProxy`\\n *\\n * To avoid https://medium.com/nomic-labs-blog/malicious-backdoors-in-ethereum-proxies-62629adf3357[proxy selector\\n * clashing], which can potentially be used in an attack, this contract uses the\\n * https://blog.openzeppelin.com/the-transparent-proxy-pattern/[transparent proxy pattern]. This pattern implies two\\n * things that go hand in hand:\\n *\\n * 1. If any account other than the admin calls the proxy, the call will be forwarded to the implementation, even if\\n * that call matches one of the admin functions exposed by the proxy itself.\\n * 2. If the admin calls the proxy, it can access the admin functions, but its calls will never be forwarded to the\\n * implementation. If the admin tries to call a function on the implementation it will fail with an error that says\\n * \\\"admin cannot fallback to proxy target\\\".\\n *\\n * These properties mean that the admin account can only be used for admin actions like upgrading the proxy or changing\\n * the admin, so it's best if it's a dedicated account that is not used for anything else. This will avoid headaches due\\n * to sudden errors when trying to call a function from the proxy implementation.\\n *\\n * Our recommendation is for the dedicated account to be an instance of the {ProxyAdmin} contract. If set up this way,\\n * you should think of the `ProxyAdmin` instance as the real administrative interface of your proxy.\\n */\\ncontract TransparentUpgradeableProxy is ERC1967Proxy {\\n /**\\n * @dev Initializes an upgradeable proxy managed by `_admin`, backed by the implementation at `_logic`, and\\n * optionally initialized with `_data` as explained in {ERC1967Proxy-constructor}.\\n */\\n constructor(address _logic, address admin_, bytes memory _data) payable ERC1967Proxy(_logic, _data) {\\n assert(_ADMIN_SLOT == bytes32(uint256(keccak256(\\\"eip1967.proxy.admin\\\")) - 1));\\n _changeAdmin(admin_);\\n }\\n\\n /**\\n * @dev Modifier used internally that will delegate the call to the implementation unless the sender is the admin.\\n */\\n modifier ifAdmin() {\\n if (msg.sender == _getAdmin()) {\\n _;\\n } else {\\n _fallback();\\n }\\n }\\n\\n /**\\n * @dev Returns the current admin.\\n *\\n * NOTE: Only the admin can call this function. See {ProxyAdmin-getProxyAdmin}.\\n *\\n * TIP: To get this value clients can read directly from the storage slot shown below (specified by EIP1967) using the\\n * https://eth.wiki/json-rpc/API#eth_getstorageat[`eth_getStorageAt`] RPC call.\\n * `0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103`\\n */\\n function admin() external ifAdmin returns (address admin_) {\\n admin_ = _getAdmin();\\n }\\n\\n /**\\n * @dev Returns the current implementation.\\n *\\n * NOTE: Only the admin can call this function. See {ProxyAdmin-getProxyImplementation}.\\n *\\n * TIP: To get this value clients can read directly from the storage slot shown below (specified by EIP1967) using the\\n * https://eth.wiki/json-rpc/API#eth_getstorageat[`eth_getStorageAt`] RPC call.\\n * `0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc`\\n */\\n function implementation() external ifAdmin returns (address implementation_) {\\n implementation_ = _implementation();\\n }\\n\\n /**\\n * @dev Changes the admin of the proxy.\\n *\\n * Emits an {AdminChanged} event.\\n *\\n * NOTE: Only the admin can call this function. See {ProxyAdmin-changeProxyAdmin}.\\n */\\n function changeAdmin(address newAdmin) external virtual ifAdmin {\\n _changeAdmin(newAdmin);\\n }\\n\\n /**\\n * @dev Upgrade the implementation of the proxy.\\n *\\n * NOTE: Only the admin can call this function. See {ProxyAdmin-upgrade}.\\n */\\n function upgradeTo(address newImplementation) external ifAdmin {\\n _upgradeToAndCall(newImplementation, bytes(\\\"\\\"), false);\\n }\\n\\n /**\\n * @dev Upgrade the implementation of the proxy, and then call a function from the new implementation as specified\\n * by `data`, which should be an encoded function call. This is useful to initialize new storage variables in the\\n * proxied contract.\\n *\\n * NOTE: Only the admin can call this function. See {ProxyAdmin-upgradeAndCall}.\\n */\\n function upgradeToAndCall(address newImplementation, bytes calldata data) external payable ifAdmin {\\n _upgradeToAndCall(newImplementation, data, true);\\n }\\n\\n /**\\n * @dev Returns the current admin.\\n */\\n function _admin() internal view virtual returns (address) {\\n return _getAdmin();\\n }\\n\\n /**\\n * @dev Makes sure the admin cannot access the fallback function. See {Proxy-_beforeFallback}.\\n */\\n function _beforeFallback() internal virtual override {\\n require(msg.sender != _getAdmin(), \\\"TransparentUpgradeableProxy: admin cannot fallback to proxy target\\\");\\n super._beforeFallback();\\n }\\n}\\n\",\"keccak256\":\"0x93a67a0f612ea3ff2a76315e138a6a88267270a1379d3cc7be52845fbbe611e2\",\"license\":\"GPL-3.0\"}},\"version\":1}", + "bytecode": "0x6080604052604051620010bb380380620010bb8339810160408190526200002691620004d8565b828162000036828260006200009a565b5062000066905060017fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6104620005b8565b6000805160206200107483398151915214620000865762000086620005da565b6200009182620000d7565b50505062000643565b620000a58362000132565b600082511180620000b35750805b15620000d257620000d083836200017460201b6200028c1760201c565b505b505050565b7f7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f62000102620001a5565b604080516001600160a01b03928316815291841660208301520160405180910390a16200012f81620001de565b50565b6200013d8162000293565b6040516001600160a01b038216907fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b90600090a250565b60606200019c8383604051806060016040528060278152602001620010946027913962000347565b90505b92915050565b6000620001cf6000805160206200107483398151915260001b6200042f60201b6200022e1760201c565b546001600160a01b0316919050565b6001600160a01b038116620002495760405162461bcd60e51b815260206004820152602660248201527f455243313936373a206e65772061646d696e20697320746865207a65726f206160448201526564647265737360d01b60648201526084015b60405180910390fd5b80620002726000805160206200107483398151915260001b6200042f60201b6200022e1760201c565b80546001600160a01b0319166001600160a01b039290921691909117905550565b620002a9816200043260201b620002b81760201c565b6200030d5760405162461bcd60e51b815260206004820152602d60248201527f455243313936373a206e657720696d706c656d656e746174696f6e206973206e60448201526c1bdd08184818dbdb9d1c9858dd609a1b606482015260840162000240565b80620002727f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc60001b6200042f60201b6200022e1760201c565b60606001600160a01b0384163b620003b15760405162461bcd60e51b815260206004820152602660248201527f416464726573733a2064656c65676174652063616c6c20746f206e6f6e2d636f6044820152651b9d1c9858dd60d21b606482015260840162000240565b600080856001600160a01b031685604051620003ce9190620005f0565b600060405180830381855af49150503d80600081146200040b576040519150601f19603f3d011682016040523d82523d6000602084013e62000410565b606091505b5090925090506200042382828662000441565b925050505b9392505050565b90565b6001600160a01b03163b151590565b606083156200045257508162000428565b825115620004635782518084602001fd5b8160405162461bcd60e51b81526004016200024091906200060e565b80516001600160a01b03811681146200049757600080fd5b919050565b634e487b7160e01b600052604160045260246000fd5b60005b83811015620004cf578181015183820152602001620004b5565b50506000910152565b600080600060608486031215620004ee57600080fd5b620004f9846200047f565b925062000509602085016200047f565b60408501519092506001600160401b03808211156200052757600080fd5b818601915086601f8301126200053c57600080fd5b8151818111156200055157620005516200049c565b604051601f8201601f19908116603f011681019083821181831017156200057c576200057c6200049c565b816040528281528960208487010111156200059657600080fd5b620005a9836020830160208801620004b2565b80955050505050509250925092565b818103818111156200019f57634e487b7160e01b600052601160045260246000fd5b634e487b7160e01b600052600160045260246000fd5b6000825162000604818460208701620004b2565b9190910192915050565b60208152600082518060208401526200062f816040850160208701620004b2565b601f01601f19169190910160400192915050565b610a2180620006536000396000f3fe60806040526004361061005e5760003560e01c80635c60da1b116100435780635c60da1b146100a85780638f283970146100e6578063f851a440146101065761006d565b80633659cfe6146100755780634f1ef286146100955761006d565b3661006d5761006b61011b565b005b61006b61011b565b34801561008157600080fd5b5061006b610090366004610895565b610135565b61006b6100a33660046108b0565b61017f565b3480156100b457600080fd5b506100bd6101f3565b60405173ffffffffffffffffffffffffffffffffffffffff909116815260200160405180910390f35b3480156100f257600080fd5b5061006b610101366004610895565b610231565b34801561011257600080fd5b506100bd61025e565b6101236102d4565b61013361012e6103ab565b6103b5565b565b61013d6103d9565b73ffffffffffffffffffffffffffffffffffffffff1633036101775761017481604051806020016040528060008152506000610419565b50565b61017461011b565b6101876103d9565b73ffffffffffffffffffffffffffffffffffffffff1633036101eb576101e68383838080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525060019250610419915050565b505050565b6101e661011b565b60006101fd6103d9565b73ffffffffffffffffffffffffffffffffffffffff163303610226576102216103ab565b905090565b61022e61011b565b90565b6102396103d9565b73ffffffffffffffffffffffffffffffffffffffff1633036101775761017481610444565b60006102686103d9565b73ffffffffffffffffffffffffffffffffffffffff163303610226576102216103d9565b60606102b183836040518060600160405280602781526020016109c5602791396104a5565b9392505050565b73ffffffffffffffffffffffffffffffffffffffff163b151590565b6102dc6103d9565b73ffffffffffffffffffffffffffffffffffffffff163303610133576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604260248201527f5472616e73706172656e745570677261646561626c6550726f78793a2061646d60448201527f696e2063616e6e6f742066616c6c6261636b20746f2070726f7879207461726760648201527f6574000000000000000000000000000000000000000000000000000000000000608482015260a4015b60405180910390fd5b60006102216105cd565b3660008037600080366000845af43d6000803e8080156103d4573d6000f35b3d6000fd5b60007fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035b5473ffffffffffffffffffffffffffffffffffffffff16919050565b610422836105f5565b60008251118061042f5750805b156101e65761043e838361028c565b50505050565b7f7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f61046d6103d9565b6040805173ffffffffffffffffffffffffffffffffffffffff928316815291841660208301520160405180910390a161017481610642565b606073ffffffffffffffffffffffffffffffffffffffff84163b61054b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f416464726573733a2064656c65676174652063616c6c20746f206e6f6e2d636f60448201527f6e7472616374000000000000000000000000000000000000000000000000000060648201526084016103a2565b6000808573ffffffffffffffffffffffffffffffffffffffff16856040516105739190610957565b600060405180830381855af49150503d80600081146105ae576040519150601f19603f3d011682016040523d82523d6000602084013e6105b3565b606091505b50915091506105c382828661074e565b9695505050505050565b60007f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc6103fd565b6105fe816107a1565b60405173ffffffffffffffffffffffffffffffffffffffff8216907fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b90600090a250565b73ffffffffffffffffffffffffffffffffffffffff81166106e5576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f455243313936373a206e65772061646d696e20697320746865207a65726f206160448201527f646472657373000000000000000000000000000000000000000000000000000060648201526084016103a2565b807fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035b80547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff9290921691909117905550565b6060831561075d5750816102b1565b82511561076d5782518084602001fd5b816040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016103a29190610973565b73ffffffffffffffffffffffffffffffffffffffff81163b610845576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602d60248201527f455243313936373a206e657720696d706c656d656e746174696f6e206973206e60448201527f6f74206120636f6e74726163740000000000000000000000000000000000000060648201526084016103a2565b807f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc610708565b803573ffffffffffffffffffffffffffffffffffffffff8116811461089057600080fd5b919050565b6000602082840312156108a757600080fd5b6102b18261086c565b6000806000604084860312156108c557600080fd5b6108ce8461086c565b9250602084013567ffffffffffffffff808211156108eb57600080fd5b818601915086601f8301126108ff57600080fd5b81358181111561090e57600080fd5b87602082850101111561092057600080fd5b6020830194508093505050509250925092565b60005b8381101561094e578181015183820152602001610936565b50506000910152565b60008251610969818460208701610933565b9190910192915050565b6020815260008251806020840152610992816040850160208701610933565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016919091016040019291505056fe416464726573733a206c6f772d6c6576656c2064656c65676174652063616c6c206661696c6564a2646970667358221220e96638b07fb1675d93a95c49e417bc8111448b23a59918698cdcd8fd488dd7cf64736f6c63430008110033b53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103416464726573733a206c6f772d6c6576656c2064656c65676174652063616c6c206661696c6564", + "deployedBytecode": "0x60806040526004361061005e5760003560e01c80635c60da1b116100435780635c60da1b146100a85780638f283970146100e6578063f851a440146101065761006d565b80633659cfe6146100755780634f1ef286146100955761006d565b3661006d5761006b61011b565b005b61006b61011b565b34801561008157600080fd5b5061006b610090366004610895565b610135565b61006b6100a33660046108b0565b61017f565b3480156100b457600080fd5b506100bd6101f3565b60405173ffffffffffffffffffffffffffffffffffffffff909116815260200160405180910390f35b3480156100f257600080fd5b5061006b610101366004610895565b610231565b34801561011257600080fd5b506100bd61025e565b6101236102d4565b61013361012e6103ab565b6103b5565b565b61013d6103d9565b73ffffffffffffffffffffffffffffffffffffffff1633036101775761017481604051806020016040528060008152506000610419565b50565b61017461011b565b6101876103d9565b73ffffffffffffffffffffffffffffffffffffffff1633036101eb576101e68383838080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525060019250610419915050565b505050565b6101e661011b565b60006101fd6103d9565b73ffffffffffffffffffffffffffffffffffffffff163303610226576102216103ab565b905090565b61022e61011b565b90565b6102396103d9565b73ffffffffffffffffffffffffffffffffffffffff1633036101775761017481610444565b60006102686103d9565b73ffffffffffffffffffffffffffffffffffffffff163303610226576102216103d9565b60606102b183836040518060600160405280602781526020016109c5602791396104a5565b9392505050565b73ffffffffffffffffffffffffffffffffffffffff163b151590565b6102dc6103d9565b73ffffffffffffffffffffffffffffffffffffffff163303610133576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604260248201527f5472616e73706172656e745570677261646561626c6550726f78793a2061646d60448201527f696e2063616e6e6f742066616c6c6261636b20746f2070726f7879207461726760648201527f6574000000000000000000000000000000000000000000000000000000000000608482015260a4015b60405180910390fd5b60006102216105cd565b3660008037600080366000845af43d6000803e8080156103d4573d6000f35b3d6000fd5b60007fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035b5473ffffffffffffffffffffffffffffffffffffffff16919050565b610422836105f5565b60008251118061042f5750805b156101e65761043e838361028c565b50505050565b7f7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f61046d6103d9565b6040805173ffffffffffffffffffffffffffffffffffffffff928316815291841660208301520160405180910390a161017481610642565b606073ffffffffffffffffffffffffffffffffffffffff84163b61054b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f416464726573733a2064656c65676174652063616c6c20746f206e6f6e2d636f60448201527f6e7472616374000000000000000000000000000000000000000000000000000060648201526084016103a2565b6000808573ffffffffffffffffffffffffffffffffffffffff16856040516105739190610957565b600060405180830381855af49150503d80600081146105ae576040519150601f19603f3d011682016040523d82523d6000602084013e6105b3565b606091505b50915091506105c382828661074e565b9695505050505050565b60007f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc6103fd565b6105fe816107a1565b60405173ffffffffffffffffffffffffffffffffffffffff8216907fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b90600090a250565b73ffffffffffffffffffffffffffffffffffffffff81166106e5576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f455243313936373a206e65772061646d696e20697320746865207a65726f206160448201527f646472657373000000000000000000000000000000000000000000000000000060648201526084016103a2565b807fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035b80547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff9290921691909117905550565b6060831561075d5750816102b1565b82511561076d5782518084602001fd5b816040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016103a29190610973565b73ffffffffffffffffffffffffffffffffffffffff81163b610845576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602d60248201527f455243313936373a206e657720696d706c656d656e746174696f6e206973206e60448201527f6f74206120636f6e74726163740000000000000000000000000000000000000060648201526084016103a2565b807f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc610708565b803573ffffffffffffffffffffffffffffffffffffffff8116811461089057600080fd5b919050565b6000602082840312156108a757600080fd5b6102b18261086c565b6000806000604084860312156108c557600080fd5b6108ce8461086c565b9250602084013567ffffffffffffffff808211156108eb57600080fd5b818601915086601f8301126108ff57600080fd5b81358181111561090e57600080fd5b87602082850101111561092057600080fd5b6020830194508093505050509250925092565b60005b8381101561094e578181015183820152602001610936565b50506000910152565b60008251610969818460208701610933565b9190910192915050565b6020815260008251806020840152610992816040850160208701610933565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016919091016040019291505056fe416464726573733a206c6f772d6c6576656c2064656c65676174652063616c6c206661696c6564a2646970667358221220e96638b07fb1675d93a95c49e417bc8111448b23a59918698cdcd8fd488dd7cf64736f6c63430008110033", + "devdoc": { + "details": "This contract implements a proxy that is upgradeable by an admin. It is fully forked from OpenZeppelin `TransparentUpgradeableProxy` To avoid https://medium.com/nomic-labs-blog/malicious-backdoors-in-ethereum-proxies-62629adf3357[proxy selector clashing], which can potentially be used in an attack, this contract uses the https://blog.openzeppelin.com/the-transparent-proxy-pattern/[transparent proxy pattern]. This pattern implies two things that go hand in hand: 1. If any account other than the admin calls the proxy, the call will be forwarded to the implementation, even if that call matches one of the admin functions exposed by the proxy itself. 2. If the admin calls the proxy, it can access the admin functions, but its calls will never be forwarded to the implementation. If the admin tries to call a function on the implementation it will fail with an error that says \"admin cannot fallback to proxy target\". These properties mean that the admin account can only be used for admin actions like upgrading the proxy or changing the admin, so it's best if it's a dedicated account that is not used for anything else. This will avoid headaches due to sudden errors when trying to call a function from the proxy implementation. Our recommendation is for the dedicated account to be an instance of the {ProxyAdmin} contract. If set up this way, you should think of the `ProxyAdmin` instance as the real administrative interface of your proxy.", + "kind": "dev", + "methods": { + "admin()": { + "details": "Returns the current admin. NOTE: Only the admin can call this function. See {ProxyAdmin-getProxyAdmin}. TIP: To get this value clients can read directly from the storage slot shown below (specified by EIP1967) using the https://eth.wiki/json-rpc/API#eth_getstorageat[`eth_getStorageAt`] RPC call. `0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103`" + }, + "changeAdmin(address)": { + "details": "Changes the admin of the proxy. Emits an {AdminChanged} event. NOTE: Only the admin can call this function. See {ProxyAdmin-changeProxyAdmin}." + }, + "constructor": { + "details": "Initializes an upgradeable proxy managed by `_admin`, backed by the implementation at `_logic`, and optionally initialized with `_data` as explained in {ERC1967Proxy-constructor}." + }, + "implementation()": { + "details": "Returns the current implementation. NOTE: Only the admin can call this function. See {ProxyAdmin-getProxyImplementation}. TIP: To get this value clients can read directly from the storage slot shown below (specified by EIP1967) using the https://eth.wiki/json-rpc/API#eth_getstorageat[`eth_getStorageAt`] RPC call. `0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc`" + }, + "upgradeTo(address)": { + "details": "Upgrade the implementation of the proxy. NOTE: Only the admin can call this function. See {ProxyAdmin-upgrade}." + }, + "upgradeToAndCall(address,bytes)": { + "details": "Upgrade the implementation of the proxy, and then call a function from the new implementation as specified by `data`, which should be an encoded function call. This is useful to initialize new storage variables in the proxied contract. NOTE: Only the admin can call this function. See {ProxyAdmin-upgradeAndCall}." + } + }, + "version": 1 + }, + "userdoc": { + "kind": "user", + "methods": {}, + "version": 1 + }, + "storageLayout": { + "storage": [], + "types": null + } +} \ No newline at end of file diff --git a/deployments/avalanche/solcInputs/871924e0c138825a2736b76def8fef8d.json b/deployments/avalanche/solcInputs/871924e0c138825a2736b76def8fef8d.json new file mode 100644 index 00000000..57454028 --- /dev/null +++ b/deployments/avalanche/solcInputs/871924e0c138825a2736b76def8fef8d.json @@ -0,0 +1,562 @@ +{ + "language": "Solidity", + "sources": { + "@chainlink/contracts/src/v0.8/interfaces/AggregatorV3Interface.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.0;\n\ninterface AggregatorV3Interface {\n\n function decimals()\n external\n view\n returns (\n uint8\n );\n\n function description()\n external\n view\n returns (\n string memory\n );\n\n function version()\n external\n view\n returns (\n uint256\n );\n\n // getRoundData and latestRoundData should both raise \"No data present\"\n // if they do not have data to report, instead of returning unset values\n // which could be misinterpreted as actual reported values.\n function getRoundData(\n uint80 _roundId\n )\n external\n view\n returns (\n uint80 roundId,\n int256 answer,\n uint256 startedAt,\n uint256 updatedAt,\n uint80 answeredInRound\n );\n\n function latestRoundData()\n external\n view\n returns (\n uint80 roundId,\n int256 answer,\n uint256 startedAt,\n uint256 updatedAt,\n uint80 answeredInRound\n );\n\n}\n" + }, + "@openzeppelin/contracts-upgradeable/access/AccessControlEnumerableUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.5.0) (access/AccessControlEnumerable.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./IAccessControlEnumerableUpgradeable.sol\";\nimport \"./AccessControlUpgradeable.sol\";\nimport \"../utils/structs/EnumerableSetUpgradeable.sol\";\nimport \"../proxy/utils/Initializable.sol\";\n\n/**\n * @dev Extension of {AccessControl} that allows enumerating the members of each role.\n */\nabstract contract AccessControlEnumerableUpgradeable is Initializable, IAccessControlEnumerableUpgradeable, AccessControlUpgradeable {\n function __AccessControlEnumerable_init() internal onlyInitializing {\n }\n\n function __AccessControlEnumerable_init_unchained() internal onlyInitializing {\n }\n using EnumerableSetUpgradeable for EnumerableSetUpgradeable.AddressSet;\n\n mapping(bytes32 => EnumerableSetUpgradeable.AddressSet) private _roleMembers;\n\n /**\n * @dev See {IERC165-supportsInterface}.\n */\n function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {\n return interfaceId == type(IAccessControlEnumerableUpgradeable).interfaceId || super.supportsInterface(interfaceId);\n }\n\n /**\n * @dev Returns one of the accounts that have `role`. `index` must be a\n * value between 0 and {getRoleMemberCount}, non-inclusive.\n *\n * Role bearers are not sorted in any particular way, and their ordering may\n * change at any point.\n *\n * WARNING: When using {getRoleMember} and {getRoleMemberCount}, make sure\n * you perform all queries on the same block. See the following\n * https://forum.openzeppelin.com/t/iterating-over-elements-on-enumerableset-in-openzeppelin-contracts/2296[forum post]\n * for more information.\n */\n function getRoleMember(bytes32 role, uint256 index) public view virtual override returns (address) {\n return _roleMembers[role].at(index);\n }\n\n /**\n * @dev Returns the number of accounts that have `role`. Can be used\n * together with {getRoleMember} to enumerate all bearers of a role.\n */\n function getRoleMemberCount(bytes32 role) public view virtual override returns (uint256) {\n return _roleMembers[role].length();\n }\n\n /**\n * @dev Overload {_grantRole} to track enumerable memberships\n */\n function _grantRole(bytes32 role, address account) internal virtual override {\n super._grantRole(role, account);\n _roleMembers[role].add(account);\n }\n\n /**\n * @dev Overload {_revokeRole} to track enumerable memberships\n */\n function _revokeRole(bytes32 role, address account) internal virtual override {\n super._revokeRole(role, account);\n _roleMembers[role].remove(account);\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[49] private __gap;\n}\n" + }, + "@openzeppelin/contracts-upgradeable/access/AccessControlUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (access/AccessControl.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./IAccessControlUpgradeable.sol\";\nimport \"../utils/ContextUpgradeable.sol\";\nimport \"../utils/StringsUpgradeable.sol\";\nimport \"../utils/introspection/ERC165Upgradeable.sol\";\nimport \"../proxy/utils/Initializable.sol\";\n\n/**\n * @dev Contract module that allows children to implement role-based access\n * control mechanisms. This is a lightweight version that doesn't allow enumerating role\n * members except through off-chain means by accessing the contract event logs. Some\n * applications may benefit from on-chain enumerability, for those cases see\n * {AccessControlEnumerable}.\n *\n * Roles are referred to by their `bytes32` identifier. These should be exposed\n * in the external API and be unique. The best way to achieve this is by\n * using `public constant` hash digests:\n *\n * ```\n * bytes32 public constant MY_ROLE = keccak256(\"MY_ROLE\");\n * ```\n *\n * Roles can be used to represent a set of permissions. To restrict access to a\n * function call, use {hasRole}:\n *\n * ```\n * function foo() public {\n * require(hasRole(MY_ROLE, msg.sender));\n * ...\n * }\n * ```\n *\n * Roles can be granted and revoked dynamically via the {grantRole} and\n * {revokeRole} functions. Each role has an associated admin role, and only\n * accounts that have a role's admin role can call {grantRole} and {revokeRole}.\n *\n * By default, the admin role for all roles is `DEFAULT_ADMIN_ROLE`, which means\n * that only accounts with this role will be able to grant or revoke other\n * roles. More complex role relationships can be created by using\n * {_setRoleAdmin}.\n *\n * WARNING: The `DEFAULT_ADMIN_ROLE` is also its own admin: it has permission to\n * grant and revoke this role. Extra precautions should be taken to secure\n * accounts that have been granted it.\n */\nabstract contract AccessControlUpgradeable is Initializable, ContextUpgradeable, IAccessControlUpgradeable, ERC165Upgradeable {\n function __AccessControl_init() internal onlyInitializing {\n }\n\n function __AccessControl_init_unchained() internal onlyInitializing {\n }\n struct RoleData {\n mapping(address => bool) members;\n bytes32 adminRole;\n }\n\n mapping(bytes32 => RoleData) private _roles;\n\n bytes32 public constant DEFAULT_ADMIN_ROLE = 0x00;\n\n /**\n * @dev Modifier that checks that an account has a specific role. Reverts\n * with a standardized message including the required role.\n *\n * The format of the revert reason is given by the following regular expression:\n *\n * /^AccessControl: account (0x[0-9a-f]{40}) is missing role (0x[0-9a-f]{64})$/\n *\n * _Available since v4.1._\n */\n modifier onlyRole(bytes32 role) {\n _checkRole(role);\n _;\n }\n\n /**\n * @dev See {IERC165-supportsInterface}.\n */\n function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {\n return interfaceId == type(IAccessControlUpgradeable).interfaceId || super.supportsInterface(interfaceId);\n }\n\n /**\n * @dev Returns `true` if `account` has been granted `role`.\n */\n function hasRole(bytes32 role, address account) public view virtual override returns (bool) {\n return _roles[role].members[account];\n }\n\n /**\n * @dev Revert with a standard message if `_msgSender()` is missing `role`.\n * Overriding this function changes the behavior of the {onlyRole} modifier.\n *\n * Format of the revert message is described in {_checkRole}.\n *\n * _Available since v4.6._\n */\n function _checkRole(bytes32 role) internal view virtual {\n _checkRole(role, _msgSender());\n }\n\n /**\n * @dev Revert with a standard message if `account` is missing `role`.\n *\n * The format of the revert reason is given by the following regular expression:\n *\n * /^AccessControl: account (0x[0-9a-f]{40}) is missing role (0x[0-9a-f]{64})$/\n */\n function _checkRole(bytes32 role, address account) internal view virtual {\n if (!hasRole(role, account)) {\n revert(\n string(\n abi.encodePacked(\n \"AccessControl: account \",\n StringsUpgradeable.toHexString(uint160(account), 20),\n \" is missing role \",\n StringsUpgradeable.toHexString(uint256(role), 32)\n )\n )\n );\n }\n }\n\n /**\n * @dev Returns the admin role that controls `role`. See {grantRole} and\n * {revokeRole}.\n *\n * To change a role's admin, use {_setRoleAdmin}.\n */\n function getRoleAdmin(bytes32 role) public view virtual override returns (bytes32) {\n return _roles[role].adminRole;\n }\n\n /**\n * @dev Grants `role` to `account`.\n *\n * If `account` had not been already granted `role`, emits a {RoleGranted}\n * event.\n *\n * Requirements:\n *\n * - the caller must have ``role``'s admin role.\n *\n * May emit a {RoleGranted} event.\n */\n function grantRole(bytes32 role, address account) public virtual override onlyRole(getRoleAdmin(role)) {\n _grantRole(role, account);\n }\n\n /**\n * @dev Revokes `role` from `account`.\n *\n * If `account` had been granted `role`, emits a {RoleRevoked} event.\n *\n * Requirements:\n *\n * - the caller must have ``role``'s admin role.\n *\n * May emit a {RoleRevoked} event.\n */\n function revokeRole(bytes32 role, address account) public virtual override onlyRole(getRoleAdmin(role)) {\n _revokeRole(role, account);\n }\n\n /**\n * @dev Revokes `role` from the calling account.\n *\n * Roles are often managed via {grantRole} and {revokeRole}: this function's\n * purpose is to provide a mechanism for accounts to lose their privileges\n * if they are compromised (such as when a trusted device is misplaced).\n *\n * If the calling account had been revoked `role`, emits a {RoleRevoked}\n * event.\n *\n * Requirements:\n *\n * - the caller must be `account`.\n *\n * May emit a {RoleRevoked} event.\n */\n function renounceRole(bytes32 role, address account) public virtual override {\n require(account == _msgSender(), \"AccessControl: can only renounce roles for self\");\n\n _revokeRole(role, account);\n }\n\n /**\n * @dev Grants `role` to `account`.\n *\n * If `account` had not been already granted `role`, emits a {RoleGranted}\n * event. Note that unlike {grantRole}, this function doesn't perform any\n * checks on the calling account.\n *\n * May emit a {RoleGranted} event.\n *\n * [WARNING]\n * ====\n * This function should only be called from the constructor when setting\n * up the initial roles for the system.\n *\n * Using this function in any other way is effectively circumventing the admin\n * system imposed by {AccessControl}.\n * ====\n *\n * NOTE: This function is deprecated in favor of {_grantRole}.\n */\n function _setupRole(bytes32 role, address account) internal virtual {\n _grantRole(role, account);\n }\n\n /**\n * @dev Sets `adminRole` as ``role``'s admin role.\n *\n * Emits a {RoleAdminChanged} event.\n */\n function _setRoleAdmin(bytes32 role, bytes32 adminRole) internal virtual {\n bytes32 previousAdminRole = getRoleAdmin(role);\n _roles[role].adminRole = adminRole;\n emit RoleAdminChanged(role, previousAdminRole, adminRole);\n }\n\n /**\n * @dev Grants `role` to `account`.\n *\n * Internal function without access restriction.\n *\n * May emit a {RoleGranted} event.\n */\n function _grantRole(bytes32 role, address account) internal virtual {\n if (!hasRole(role, account)) {\n _roles[role].members[account] = true;\n emit RoleGranted(role, account, _msgSender());\n }\n }\n\n /**\n * @dev Revokes `role` from `account`.\n *\n * Internal function without access restriction.\n *\n * May emit a {RoleRevoked} event.\n */\n function _revokeRole(bytes32 role, address account) internal virtual {\n if (hasRole(role, account)) {\n _roles[role].members[account] = false;\n emit RoleRevoked(role, account, _msgSender());\n }\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[49] private __gap;\n}\n" + }, + "@openzeppelin/contracts-upgradeable/access/IAccessControlEnumerableUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (access/IAccessControlEnumerable.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./IAccessControlUpgradeable.sol\";\n\n/**\n * @dev External interface of AccessControlEnumerable declared to support ERC165 detection.\n */\ninterface IAccessControlEnumerableUpgradeable is IAccessControlUpgradeable {\n /**\n * @dev Returns one of the accounts that have `role`. `index` must be a\n * value between 0 and {getRoleMemberCount}, non-inclusive.\n *\n * Role bearers are not sorted in any particular way, and their ordering may\n * change at any point.\n *\n * WARNING: When using {getRoleMember} and {getRoleMemberCount}, make sure\n * you perform all queries on the same block. See the following\n * https://forum.openzeppelin.com/t/iterating-over-elements-on-enumerableset-in-openzeppelin-contracts/2296[forum post]\n * for more information.\n */\n function getRoleMember(bytes32 role, uint256 index) external view returns (address);\n\n /**\n * @dev Returns the number of accounts that have `role`. Can be used\n * together with {getRoleMember} to enumerate all bearers of a role.\n */\n function getRoleMemberCount(bytes32 role) external view returns (uint256);\n}\n" + }, + "@openzeppelin/contracts-upgradeable/access/IAccessControlUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (access/IAccessControl.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev External interface of AccessControl declared to support ERC165 detection.\n */\ninterface IAccessControlUpgradeable {\n /**\n * @dev Emitted when `newAdminRole` is set as ``role``'s admin role, replacing `previousAdminRole`\n *\n * `DEFAULT_ADMIN_ROLE` is the starting admin for all roles, despite\n * {RoleAdminChanged} not being emitted signaling this.\n *\n * _Available since v3.1._\n */\n event RoleAdminChanged(bytes32 indexed role, bytes32 indexed previousAdminRole, bytes32 indexed newAdminRole);\n\n /**\n * @dev Emitted when `account` is granted `role`.\n *\n * `sender` is the account that originated the contract call, an admin role\n * bearer except when using {AccessControl-_setupRole}.\n */\n event RoleGranted(bytes32 indexed role, address indexed account, address indexed sender);\n\n /**\n * @dev Emitted when `account` is revoked `role`.\n *\n * `sender` is the account that originated the contract call:\n * - if using `revokeRole`, it is the admin role bearer\n * - if using `renounceRole`, it is the role bearer (i.e. `account`)\n */\n event RoleRevoked(bytes32 indexed role, address indexed account, address indexed sender);\n\n /**\n * @dev Returns `true` if `account` has been granted `role`.\n */\n function hasRole(bytes32 role, address account) external view returns (bool);\n\n /**\n * @dev Returns the admin role that controls `role`. See {grantRole} and\n * {revokeRole}.\n *\n * To change a role's admin, use {AccessControl-_setRoleAdmin}.\n */\n function getRoleAdmin(bytes32 role) external view returns (bytes32);\n\n /**\n * @dev Grants `role` to `account`.\n *\n * If `account` had not been already granted `role`, emits a {RoleGranted}\n * event.\n *\n * Requirements:\n *\n * - the caller must have ``role``'s admin role.\n */\n function grantRole(bytes32 role, address account) external;\n\n /**\n * @dev Revokes `role` from `account`.\n *\n * If `account` had been granted `role`, emits a {RoleRevoked} event.\n *\n * Requirements:\n *\n * - the caller must have ``role``'s admin role.\n */\n function revokeRole(bytes32 role, address account) external;\n\n /**\n * @dev Revokes `role` from the calling account.\n *\n * Roles are often managed via {grantRole} and {revokeRole}: this function's\n * purpose is to provide a mechanism for accounts to lose their privileges\n * if they are compromised (such as when a trusted device is misplaced).\n *\n * If the calling account had been granted `role`, emits a {RoleRevoked}\n * event.\n *\n * Requirements:\n *\n * - the caller must be `account`.\n */\n function renounceRole(bytes32 role, address account) external;\n}\n" + }, + "@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (access/Ownable.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../utils/ContextUpgradeable.sol\";\nimport \"../proxy/utils/Initializable.sol\";\n\n/**\n * @dev Contract module which provides a basic access control mechanism, where\n * there is an account (an owner) that can be granted exclusive access to\n * specific functions.\n *\n * By default, the owner account will be the one that deploys the contract. This\n * can later be changed with {transferOwnership}.\n *\n * This module is used through inheritance. It will make available the modifier\n * `onlyOwner`, which can be applied to your functions to restrict their use to\n * the owner.\n */\nabstract contract OwnableUpgradeable is Initializable, ContextUpgradeable {\n address private _owner;\n\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\n\n /**\n * @dev Initializes the contract setting the deployer as the initial owner.\n */\n function __Ownable_init() internal onlyInitializing {\n __Ownable_init_unchained();\n }\n\n function __Ownable_init_unchained() internal onlyInitializing {\n _transferOwnership(_msgSender());\n }\n\n /**\n * @dev Throws if called by any account other than the owner.\n */\n modifier onlyOwner() {\n _checkOwner();\n _;\n }\n\n /**\n * @dev Returns the address of the current owner.\n */\n function owner() public view virtual returns (address) {\n return _owner;\n }\n\n /**\n * @dev Throws if the sender is not the owner.\n */\n function _checkOwner() internal view virtual {\n require(owner() == _msgSender(), \"Ownable: caller is not the owner\");\n }\n\n /**\n * @dev Leaves the contract without owner. It will not be possible to call\n * `onlyOwner` functions anymore. Can only be called by the current owner.\n *\n * NOTE: Renouncing ownership will leave the contract without an owner,\n * thereby removing any functionality that is only available to the owner.\n */\n function renounceOwnership() public virtual onlyOwner {\n _transferOwnership(address(0));\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Can only be called by the current owner.\n */\n function transferOwnership(address newOwner) public virtual onlyOwner {\n require(newOwner != address(0), \"Ownable: new owner is the zero address\");\n _transferOwnership(newOwner);\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Internal function without access restriction.\n */\n function _transferOwnership(address newOwner) internal virtual {\n address oldOwner = _owner;\n _owner = newOwner;\n emit OwnershipTransferred(oldOwner, newOwner);\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[49] private __gap;\n}\n" + }, + "@openzeppelin/contracts-upgradeable/interfaces/IERC721MetadataUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (interfaces/IERC721Metadata.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../token/ERC721/extensions/IERC721MetadataUpgradeable.sol\";\n" + }, + "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (proxy/utils/Initializable.sol)\n\npragma solidity ^0.8.2;\n\nimport \"../../utils/AddressUpgradeable.sol\";\n\n/**\n * @dev This is a base contract to aid in writing upgradeable contracts, or any kind of contract that will be deployed\n * behind a proxy. Since proxied contracts do not make use of a constructor, it's common to move constructor logic to an\n * external initializer function, usually called `initialize`. It then becomes necessary to protect this initializer\n * function so it can only be called once. The {initializer} modifier provided by this contract will have this effect.\n *\n * The initialization functions use a version number. Once a version number is used, it is consumed and cannot be\n * reused. This mechanism prevents re-execution of each \"step\" but allows the creation of new initialization steps in\n * case an upgrade adds a module that needs to be initialized.\n *\n * For example:\n *\n * [.hljs-theme-light.nopadding]\n * ```\n * contract MyToken is ERC20Upgradeable {\n * function initialize() initializer public {\n * __ERC20_init(\"MyToken\", \"MTK\");\n * }\n * }\n * contract MyTokenV2 is MyToken, ERC20PermitUpgradeable {\n * function initializeV2() reinitializer(2) public {\n * __ERC20Permit_init(\"MyToken\");\n * }\n * }\n * ```\n *\n * TIP: To avoid leaving the proxy in an uninitialized state, the initializer function should be called as early as\n * possible by providing the encoded function call as the `_data` argument to {ERC1967Proxy-constructor}.\n *\n * CAUTION: When used with inheritance, manual care must be taken to not invoke a parent initializer twice, or to ensure\n * that all initializers are idempotent. This is not verified automatically as constructors are by Solidity.\n *\n * [CAUTION]\n * ====\n * Avoid leaving a contract uninitialized.\n *\n * An uninitialized contract can be taken over by an attacker. This applies to both a proxy and its implementation\n * contract, which may impact the proxy. To prevent the implementation contract from being used, you should invoke\n * the {_disableInitializers} function in the constructor to automatically lock it when it is deployed:\n *\n * [.hljs-theme-light.nopadding]\n * ```\n * /// @custom:oz-upgrades-unsafe-allow constructor\n * constructor() {\n * _disableInitializers();\n * }\n * ```\n * ====\n */\nabstract contract Initializable {\n /**\n * @dev Indicates that the contract has been initialized.\n * @custom:oz-retyped-from bool\n */\n uint8 private _initialized;\n\n /**\n * @dev Indicates that the contract is in the process of being initialized.\n */\n bool private _initializing;\n\n /**\n * @dev Triggered when the contract has been initialized or reinitialized.\n */\n event Initialized(uint8 version);\n\n /**\n * @dev A modifier that defines a protected initializer function that can be invoked at most once. In its scope,\n * `onlyInitializing` functions can be used to initialize parent contracts. Equivalent to `reinitializer(1)`.\n */\n modifier initializer() {\n bool isTopLevelCall = !_initializing;\n require(\n (isTopLevelCall && _initialized < 1) || (!AddressUpgradeable.isContract(address(this)) && _initialized == 1),\n \"Initializable: contract is already initialized\"\n );\n _initialized = 1;\n if (isTopLevelCall) {\n _initializing = true;\n }\n _;\n if (isTopLevelCall) {\n _initializing = false;\n emit Initialized(1);\n }\n }\n\n /**\n * @dev A modifier that defines a protected reinitializer function that can be invoked at most once, and only if the\n * contract hasn't been initialized to a greater version before. In its scope, `onlyInitializing` functions can be\n * used to initialize parent contracts.\n *\n * `initializer` is equivalent to `reinitializer(1)`, so a reinitializer may be used after the original\n * initialization step. This is essential to configure modules that are added through upgrades and that require\n * initialization.\n *\n * Note that versions can jump in increments greater than 1; this implies that if multiple reinitializers coexist in\n * a contract, executing them in the right order is up to the developer or operator.\n */\n modifier reinitializer(uint8 version) {\n require(!_initializing && _initialized < version, \"Initializable: contract is already initialized\");\n _initialized = version;\n _initializing = true;\n _;\n _initializing = false;\n emit Initialized(version);\n }\n\n /**\n * @dev Modifier to protect an initialization function so that it can only be invoked by functions with the\n * {initializer} and {reinitializer} modifiers, directly or indirectly.\n */\n modifier onlyInitializing() {\n require(_initializing, \"Initializable: contract is not initializing\");\n _;\n }\n\n /**\n * @dev Locks the contract, preventing any future reinitialization. This cannot be part of an initializer call.\n * Calling this in the constructor of a contract will prevent that contract from being initialized or reinitialized\n * to any version. It is recommended to use this to lock implementation contracts that are designed to be called\n * through proxies.\n */\n function _disableInitializers() internal virtual {\n require(!_initializing, \"Initializable: contract is initializing\");\n if (_initialized < type(uint8).max) {\n _initialized = type(uint8).max;\n emit Initialized(type(uint8).max);\n }\n }\n}\n" + }, + "@openzeppelin/contracts-upgradeable/security/PausableUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (security/Pausable.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../utils/ContextUpgradeable.sol\";\nimport \"../proxy/utils/Initializable.sol\";\n\n/**\n * @dev Contract module which allows children to implement an emergency stop\n * mechanism that can be triggered by an authorized account.\n *\n * This module is used through inheritance. It will make available the\n * modifiers `whenNotPaused` and `whenPaused`, which can be applied to\n * the functions of your contract. Note that they will not be pausable by\n * simply including this module, only once the modifiers are put in place.\n */\nabstract contract PausableUpgradeable is Initializable, ContextUpgradeable {\n /**\n * @dev Emitted when the pause is triggered by `account`.\n */\n event Paused(address account);\n\n /**\n * @dev Emitted when the pause is lifted by `account`.\n */\n event Unpaused(address account);\n\n bool private _paused;\n\n /**\n * @dev Initializes the contract in unpaused state.\n */\n function __Pausable_init() internal onlyInitializing {\n __Pausable_init_unchained();\n }\n\n function __Pausable_init_unchained() internal onlyInitializing {\n _paused = false;\n }\n\n /**\n * @dev Modifier to make a function callable only when the contract is not paused.\n *\n * Requirements:\n *\n * - The contract must not be paused.\n */\n modifier whenNotPaused() {\n _requireNotPaused();\n _;\n }\n\n /**\n * @dev Modifier to make a function callable only when the contract is paused.\n *\n * Requirements:\n *\n * - The contract must be paused.\n */\n modifier whenPaused() {\n _requirePaused();\n _;\n }\n\n /**\n * @dev Returns true if the contract is paused, and false otherwise.\n */\n function paused() public view virtual returns (bool) {\n return _paused;\n }\n\n /**\n * @dev Throws if the contract is paused.\n */\n function _requireNotPaused() internal view virtual {\n require(!paused(), \"Pausable: paused\");\n }\n\n /**\n * @dev Throws if the contract is not paused.\n */\n function _requirePaused() internal view virtual {\n require(paused(), \"Pausable: not paused\");\n }\n\n /**\n * @dev Triggers stopped state.\n *\n * Requirements:\n *\n * - The contract must not be paused.\n */\n function _pause() internal virtual whenNotPaused {\n _paused = true;\n emit Paused(_msgSender());\n }\n\n /**\n * @dev Returns to normal state.\n *\n * Requirements:\n *\n * - The contract must be paused.\n */\n function _unpause() internal virtual whenPaused {\n _paused = false;\n emit Unpaused(_msgSender());\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[49] private __gap;\n}\n" + }, + "@openzeppelin/contracts-upgradeable/security/ReentrancyGuardUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (security/ReentrancyGuard.sol)\n\npragma solidity ^0.8.0;\nimport \"../proxy/utils/Initializable.sol\";\n\n/**\n * @dev Contract module that helps prevent reentrant calls to a function.\n *\n * Inheriting from `ReentrancyGuard` will make the {nonReentrant} modifier\n * available, which can be applied to functions to make sure there are no nested\n * (reentrant) calls to them.\n *\n * Note that because there is a single `nonReentrant` guard, functions marked as\n * `nonReentrant` may not call one another. This can be worked around by making\n * those functions `private`, and then adding `external` `nonReentrant` entry\n * points to them.\n *\n * TIP: If you would like to learn more about reentrancy and alternative ways\n * to protect against it, check out our blog post\n * https://blog.openzeppelin.com/reentrancy-after-istanbul/[Reentrancy After Istanbul].\n */\nabstract contract ReentrancyGuardUpgradeable is Initializable {\n // Booleans are more expensive than uint256 or any type that takes up a full\n // word because each write operation emits an extra SLOAD to first read the\n // slot's contents, replace the bits taken up by the boolean, and then write\n // back. This is the compiler's defense against contract upgrades and\n // pointer aliasing, and it cannot be disabled.\n\n // The values being non-zero value makes deployment a bit more expensive,\n // but in exchange the refund on every call to nonReentrant will be lower in\n // amount. Since refunds are capped to a percentage of the total\n // transaction's gas, it is best to keep them low in cases like this one, to\n // increase the likelihood of the full refund coming into effect.\n uint256 private constant _NOT_ENTERED = 1;\n uint256 private constant _ENTERED = 2;\n\n uint256 private _status;\n\n function __ReentrancyGuard_init() internal onlyInitializing {\n __ReentrancyGuard_init_unchained();\n }\n\n function __ReentrancyGuard_init_unchained() internal onlyInitializing {\n _status = _NOT_ENTERED;\n }\n\n /**\n * @dev Prevents a contract from calling itself, directly or indirectly.\n * Calling a `nonReentrant` function from another `nonReentrant`\n * function is not supported. It is possible to prevent this from happening\n * by making the `nonReentrant` function external, and making it call a\n * `private` function that does the actual work.\n */\n modifier nonReentrant() {\n // On the first call to nonReentrant, _notEntered will be true\n require(_status != _ENTERED, \"ReentrancyGuard: reentrant call\");\n\n // Any calls to nonReentrant after this point will fail\n _status = _ENTERED;\n\n _;\n\n // By storing the original value once again, a refund is triggered (see\n // https://eips.ethereum.org/EIPS/eip-2200)\n _status = _NOT_ENTERED;\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[49] private __gap;\n}\n" + }, + "@openzeppelin/contracts-upgradeable/token/ERC20/ERC20Upgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (token/ERC20/ERC20.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./IERC20Upgradeable.sol\";\nimport \"./extensions/IERC20MetadataUpgradeable.sol\";\nimport \"../../utils/ContextUpgradeable.sol\";\nimport \"../../proxy/utils/Initializable.sol\";\n\n/**\n * @dev Implementation of the {IERC20} interface.\n *\n * This implementation is agnostic to the way tokens are created. This means\n * that a supply mechanism has to be added in a derived contract using {_mint}.\n * For a generic mechanism see {ERC20PresetMinterPauser}.\n *\n * TIP: For a detailed writeup see our guide\n * https://forum.zeppelin.solutions/t/how-to-implement-erc20-supply-mechanisms/226[How\n * to implement supply mechanisms].\n *\n * We have followed general OpenZeppelin Contracts guidelines: functions revert\n * instead returning `false` on failure. This behavior is nonetheless\n * conventional and does not conflict with the expectations of ERC20\n * applications.\n *\n * Additionally, an {Approval} event is emitted on calls to {transferFrom}.\n * This allows applications to reconstruct the allowance for all accounts just\n * by listening to said events. Other implementations of the EIP may not emit\n * these events, as it isn't required by the specification.\n *\n * Finally, the non-standard {decreaseAllowance} and {increaseAllowance}\n * functions have been added to mitigate the well-known issues around setting\n * allowances. See {IERC20-approve}.\n */\ncontract ERC20Upgradeable is Initializable, ContextUpgradeable, IERC20Upgradeable, IERC20MetadataUpgradeable {\n mapping(address => uint256) private _balances;\n\n mapping(address => mapping(address => uint256)) private _allowances;\n\n uint256 private _totalSupply;\n\n string private _name;\n string private _symbol;\n\n /**\n * @dev Sets the values for {name} and {symbol}.\n *\n * The default value of {decimals} is 18. To select a different value for\n * {decimals} you should overload it.\n *\n * All two of these values are immutable: they can only be set once during\n * construction.\n */\n function __ERC20_init(string memory name_, string memory symbol_) internal onlyInitializing {\n __ERC20_init_unchained(name_, symbol_);\n }\n\n function __ERC20_init_unchained(string memory name_, string memory symbol_) internal onlyInitializing {\n _name = name_;\n _symbol = symbol_;\n }\n\n /**\n * @dev Returns the name of the token.\n */\n function name() public view virtual override returns (string memory) {\n return _name;\n }\n\n /**\n * @dev Returns the symbol of the token, usually a shorter version of the\n * name.\n */\n function symbol() public view virtual override returns (string memory) {\n return _symbol;\n }\n\n /**\n * @dev Returns the number of decimals used to get its user representation.\n * For example, if `decimals` equals `2`, a balance of `505` tokens should\n * be displayed to a user as `5.05` (`505 / 10 ** 2`).\n *\n * Tokens usually opt for a value of 18, imitating the relationship between\n * Ether and Wei. This is the value {ERC20} uses, unless this function is\n * overridden;\n *\n * NOTE: This information is only used for _display_ purposes: it in\n * no way affects any of the arithmetic of the contract, including\n * {IERC20-balanceOf} and {IERC20-transfer}.\n */\n function decimals() public view virtual override returns (uint8) {\n return 18;\n }\n\n /**\n * @dev See {IERC20-totalSupply}.\n */\n function totalSupply() public view virtual override returns (uint256) {\n return _totalSupply;\n }\n\n /**\n * @dev See {IERC20-balanceOf}.\n */\n function balanceOf(address account) public view virtual override returns (uint256) {\n return _balances[account];\n }\n\n /**\n * @dev See {IERC20-transfer}.\n *\n * Requirements:\n *\n * - `to` cannot be the zero address.\n * - the caller must have a balance of at least `amount`.\n */\n function transfer(address to, uint256 amount) public virtual override returns (bool) {\n address owner = _msgSender();\n _transfer(owner, to, amount);\n return true;\n }\n\n /**\n * @dev See {IERC20-allowance}.\n */\n function allowance(address owner, address spender) public view virtual override returns (uint256) {\n return _allowances[owner][spender];\n }\n\n /**\n * @dev See {IERC20-approve}.\n *\n * NOTE: If `amount` is the maximum `uint256`, the allowance is not updated on\n * `transferFrom`. This is semantically equivalent to an infinite approval.\n *\n * Requirements:\n *\n * - `spender` cannot be the zero address.\n */\n function approve(address spender, uint256 amount) public virtual override returns (bool) {\n address owner = _msgSender();\n _approve(owner, spender, amount);\n return true;\n }\n\n /**\n * @dev See {IERC20-transferFrom}.\n *\n * Emits an {Approval} event indicating the updated allowance. This is not\n * required by the EIP. See the note at the beginning of {ERC20}.\n *\n * NOTE: Does not update the allowance if the current allowance\n * is the maximum `uint256`.\n *\n * Requirements:\n *\n * - `from` and `to` cannot be the zero address.\n * - `from` must have a balance of at least `amount`.\n * - the caller must have allowance for ``from``'s tokens of at least\n * `amount`.\n */\n function transferFrom(\n address from,\n address to,\n uint256 amount\n ) public virtual override returns (bool) {\n address spender = _msgSender();\n _spendAllowance(from, spender, amount);\n _transfer(from, to, amount);\n return true;\n }\n\n /**\n * @dev Atomically increases the allowance granted to `spender` by the caller.\n *\n * This is an alternative to {approve} that can be used as a mitigation for\n * problems described in {IERC20-approve}.\n *\n * Emits an {Approval} event indicating the updated allowance.\n *\n * Requirements:\n *\n * - `spender` cannot be the zero address.\n */\n function increaseAllowance(address spender, uint256 addedValue) public virtual returns (bool) {\n address owner = _msgSender();\n _approve(owner, spender, allowance(owner, spender) + addedValue);\n return true;\n }\n\n /**\n * @dev Atomically decreases the allowance granted to `spender` by the caller.\n *\n * This is an alternative to {approve} that can be used as a mitigation for\n * problems described in {IERC20-approve}.\n *\n * Emits an {Approval} event indicating the updated allowance.\n *\n * Requirements:\n *\n * - `spender` cannot be the zero address.\n * - `spender` must have allowance for the caller of at least\n * `subtractedValue`.\n */\n function decreaseAllowance(address spender, uint256 subtractedValue) public virtual returns (bool) {\n address owner = _msgSender();\n uint256 currentAllowance = allowance(owner, spender);\n require(currentAllowance >= subtractedValue, \"ERC20: decreased allowance below zero\");\n unchecked {\n _approve(owner, spender, currentAllowance - subtractedValue);\n }\n\n return true;\n }\n\n /**\n * @dev Moves `amount` of tokens from `from` to `to`.\n *\n * This internal function is equivalent to {transfer}, and can be used to\n * e.g. implement automatic token fees, slashing mechanisms, etc.\n *\n * Emits a {Transfer} event.\n *\n * Requirements:\n *\n * - `from` cannot be the zero address.\n * - `to` cannot be the zero address.\n * - `from` must have a balance of at least `amount`.\n */\n function _transfer(\n address from,\n address to,\n uint256 amount\n ) internal virtual {\n require(from != address(0), \"ERC20: transfer from the zero address\");\n require(to != address(0), \"ERC20: transfer to the zero address\");\n\n _beforeTokenTransfer(from, to, amount);\n\n uint256 fromBalance = _balances[from];\n require(fromBalance >= amount, \"ERC20: transfer amount exceeds balance\");\n unchecked {\n _balances[from] = fromBalance - amount;\n }\n _balances[to] += amount;\n\n emit Transfer(from, to, amount);\n\n _afterTokenTransfer(from, to, amount);\n }\n\n /** @dev Creates `amount` tokens and assigns them to `account`, increasing\n * the total supply.\n *\n * Emits a {Transfer} event with `from` set to the zero address.\n *\n * Requirements:\n *\n * - `account` cannot be the zero address.\n */\n function _mint(address account, uint256 amount) internal virtual {\n require(account != address(0), \"ERC20: mint to the zero address\");\n\n _beforeTokenTransfer(address(0), account, amount);\n\n _totalSupply += amount;\n _balances[account] += amount;\n emit Transfer(address(0), account, amount);\n\n _afterTokenTransfer(address(0), account, amount);\n }\n\n /**\n * @dev Destroys `amount` tokens from `account`, reducing the\n * total supply.\n *\n * Emits a {Transfer} event with `to` set to the zero address.\n *\n * Requirements:\n *\n * - `account` cannot be the zero address.\n * - `account` must have at least `amount` tokens.\n */\n function _burn(address account, uint256 amount) internal virtual {\n require(account != address(0), \"ERC20: burn from the zero address\");\n\n _beforeTokenTransfer(account, address(0), amount);\n\n uint256 accountBalance = _balances[account];\n require(accountBalance >= amount, \"ERC20: burn amount exceeds balance\");\n unchecked {\n _balances[account] = accountBalance - amount;\n }\n _totalSupply -= amount;\n\n emit Transfer(account, address(0), amount);\n\n _afterTokenTransfer(account, address(0), amount);\n }\n\n /**\n * @dev Sets `amount` as the allowance of `spender` over the `owner` s tokens.\n *\n * This internal function is equivalent to `approve`, and can be used to\n * e.g. set automatic allowances for certain subsystems, etc.\n *\n * Emits an {Approval} event.\n *\n * Requirements:\n *\n * - `owner` cannot be the zero address.\n * - `spender` cannot be the zero address.\n */\n function _approve(\n address owner,\n address spender,\n uint256 amount\n ) internal virtual {\n require(owner != address(0), \"ERC20: approve from the zero address\");\n require(spender != address(0), \"ERC20: approve to the zero address\");\n\n _allowances[owner][spender] = amount;\n emit Approval(owner, spender, amount);\n }\n\n /**\n * @dev Updates `owner` s allowance for `spender` based on spent `amount`.\n *\n * Does not update the allowance amount in case of infinite allowance.\n * Revert if not enough allowance is available.\n *\n * Might emit an {Approval} event.\n */\n function _spendAllowance(\n address owner,\n address spender,\n uint256 amount\n ) internal virtual {\n uint256 currentAllowance = allowance(owner, spender);\n if (currentAllowance != type(uint256).max) {\n require(currentAllowance >= amount, \"ERC20: insufficient allowance\");\n unchecked {\n _approve(owner, spender, currentAllowance - amount);\n }\n }\n }\n\n /**\n * @dev Hook that is called before any transfer of tokens. This includes\n * minting and burning.\n *\n * Calling conditions:\n *\n * - when `from` and `to` are both non-zero, `amount` of ``from``'s tokens\n * will be transferred to `to`.\n * - when `from` is zero, `amount` tokens will be minted for `to`.\n * - when `to` is zero, `amount` of ``from``'s tokens will be burned.\n * - `from` and `to` are never both zero.\n *\n * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].\n */\n function _beforeTokenTransfer(\n address from,\n address to,\n uint256 amount\n ) internal virtual {}\n\n /**\n * @dev Hook that is called after any transfer of tokens. This includes\n * minting and burning.\n *\n * Calling conditions:\n *\n * - when `from` and `to` are both non-zero, `amount` of ``from``'s tokens\n * has been transferred to `to`.\n * - when `from` is zero, `amount` tokens have been minted for `to`.\n * - when `to` is zero, `amount` of ``from``'s tokens have been burned.\n * - `from` and `to` are never both zero.\n *\n * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].\n */\n function _afterTokenTransfer(\n address from,\n address to,\n uint256 amount\n ) internal virtual {}\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[45] private __gap;\n}\n" + }, + "@openzeppelin/contracts-upgradeable/token/ERC20/extensions/draft-ERC20PermitUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.6.0) (token/ERC20/extensions/draft-ERC20Permit.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./draft-IERC20PermitUpgradeable.sol\";\nimport \"../ERC20Upgradeable.sol\";\nimport \"../../../utils/cryptography/draft-EIP712Upgradeable.sol\";\nimport \"../../../utils/cryptography/ECDSAUpgradeable.sol\";\nimport \"../../../utils/CountersUpgradeable.sol\";\nimport \"../../../proxy/utils/Initializable.sol\";\n\n/**\n * @dev Implementation of the ERC20 Permit extension allowing approvals to be made via signatures, as defined in\n * https://eips.ethereum.org/EIPS/eip-2612[EIP-2612].\n *\n * Adds the {permit} method, which can be used to change an account's ERC20 allowance (see {IERC20-allowance}) by\n * presenting a message signed by the account. By not relying on `{IERC20-approve}`, the token holder account doesn't\n * need to send a transaction, and thus is not required to hold Ether at all.\n *\n * _Available since v3.4._\n *\n * @custom:storage-size 51\n */\nabstract contract ERC20PermitUpgradeable is Initializable, ERC20Upgradeable, IERC20PermitUpgradeable, EIP712Upgradeable {\n using CountersUpgradeable for CountersUpgradeable.Counter;\n\n mapping(address => CountersUpgradeable.Counter) private _nonces;\n\n // solhint-disable-next-line var-name-mixedcase\n bytes32 private constant _PERMIT_TYPEHASH =\n keccak256(\"Permit(address owner,address spender,uint256 value,uint256 nonce,uint256 deadline)\");\n /**\n * @dev In previous versions `_PERMIT_TYPEHASH` was declared as `immutable`.\n * However, to ensure consistency with the upgradeable transpiler, we will continue\n * to reserve a slot.\n * @custom:oz-renamed-from _PERMIT_TYPEHASH\n */\n // solhint-disable-next-line var-name-mixedcase\n bytes32 private _PERMIT_TYPEHASH_DEPRECATED_SLOT;\n\n /**\n * @dev Initializes the {EIP712} domain separator using the `name` parameter, and setting `version` to `\"1\"`.\n *\n * It's a good idea to use the same `name` that is defined as the ERC20 token name.\n */\n function __ERC20Permit_init(string memory name) internal onlyInitializing {\n __EIP712_init_unchained(name, \"1\");\n }\n\n function __ERC20Permit_init_unchained(string memory) internal onlyInitializing {}\n\n /**\n * @dev See {IERC20Permit-permit}.\n */\n function permit(\n address owner,\n address spender,\n uint256 value,\n uint256 deadline,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) public virtual override {\n require(block.timestamp <= deadline, \"ERC20Permit: expired deadline\");\n\n bytes32 structHash = keccak256(abi.encode(_PERMIT_TYPEHASH, owner, spender, value, _useNonce(owner), deadline));\n\n bytes32 hash = _hashTypedDataV4(structHash);\n\n address signer = ECDSAUpgradeable.recover(hash, v, r, s);\n require(signer == owner, \"ERC20Permit: invalid signature\");\n\n _approve(owner, spender, value);\n }\n\n /**\n * @dev See {IERC20Permit-nonces}.\n */\n function nonces(address owner) public view virtual override returns (uint256) {\n return _nonces[owner].current();\n }\n\n /**\n * @dev See {IERC20Permit-DOMAIN_SEPARATOR}.\n */\n // solhint-disable-next-line func-name-mixedcase\n function DOMAIN_SEPARATOR() external view override returns (bytes32) {\n return _domainSeparatorV4();\n }\n\n /**\n * @dev \"Consume a nonce\": return the current value and increment.\n *\n * _Available since v4.1._\n */\n function _useNonce(address owner) internal virtual returns (uint256 current) {\n CountersUpgradeable.Counter storage nonce = _nonces[owner];\n current = nonce.current();\n nonce.increment();\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[49] private __gap;\n}\n" + }, + "@openzeppelin/contracts-upgradeable/token/ERC20/extensions/draft-IERC20PermitUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (token/ERC20/extensions/draft-IERC20Permit.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Interface of the ERC20 Permit extension allowing approvals to be made via signatures, as defined in\n * https://eips.ethereum.org/EIPS/eip-2612[EIP-2612].\n *\n * Adds the {permit} method, which can be used to change an account's ERC20 allowance (see {IERC20-allowance}) by\n * presenting a message signed by the account. By not relying on {IERC20-approve}, the token holder account doesn't\n * need to send a transaction, and thus is not required to hold Ether at all.\n */\ninterface IERC20PermitUpgradeable {\n /**\n * @dev Sets `value` as the allowance of `spender` over ``owner``'s tokens,\n * given ``owner``'s signed approval.\n *\n * IMPORTANT: The same issues {IERC20-approve} has related to transaction\n * ordering also apply here.\n *\n * Emits an {Approval} event.\n *\n * Requirements:\n *\n * - `spender` cannot be the zero address.\n * - `deadline` must be a timestamp in the future.\n * - `v`, `r` and `s` must be a valid `secp256k1` signature from `owner`\n * over the EIP712-formatted function arguments.\n * - the signature must use ``owner``'s current nonce (see {nonces}).\n *\n * For more information on the signature format, see the\n * https://eips.ethereum.org/EIPS/eip-2612#specification[relevant EIP\n * section].\n */\n function permit(\n address owner,\n address spender,\n uint256 value,\n uint256 deadline,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) external;\n\n /**\n * @dev Returns the current nonce for `owner`. This value must be\n * included whenever a signature is generated for {permit}.\n *\n * Every successful call to {permit} increases ``owner``'s nonce by one. This\n * prevents a signature from being used multiple times.\n */\n function nonces(address owner) external view returns (uint256);\n\n /**\n * @dev Returns the domain separator used in the encoding of the signature for {permit}, as defined by {EIP712}.\n */\n // solhint-disable-next-line func-name-mixedcase\n function DOMAIN_SEPARATOR() external view returns (bytes32);\n}\n" + }, + "@openzeppelin/contracts-upgradeable/token/ERC20/extensions/IERC20MetadataUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (token/ERC20/extensions/IERC20Metadata.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../IERC20Upgradeable.sol\";\n\n/**\n * @dev Interface for the optional metadata functions from the ERC20 standard.\n *\n * _Available since v4.1._\n */\ninterface IERC20MetadataUpgradeable is IERC20Upgradeable {\n /**\n * @dev Returns the name of the token.\n */\n function name() external view returns (string memory);\n\n /**\n * @dev Returns the symbol of the token.\n */\n function symbol() external view returns (string memory);\n\n /**\n * @dev Returns the decimals places of the token.\n */\n function decimals() external view returns (uint8);\n}\n" + }, + "@openzeppelin/contracts-upgradeable/token/ERC20/IERC20Upgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.6.0) (token/ERC20/IERC20.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Interface of the ERC20 standard as defined in the EIP.\n */\ninterface IERC20Upgradeable {\n /**\n * @dev Emitted when `value` tokens are moved from one account (`from`) to\n * another (`to`).\n *\n * Note that `value` may be zero.\n */\n event Transfer(address indexed from, address indexed to, uint256 value);\n\n /**\n * @dev Emitted when the allowance of a `spender` for an `owner` is set by\n * a call to {approve}. `value` is the new allowance.\n */\n event Approval(address indexed owner, address indexed spender, uint256 value);\n\n /**\n * @dev Returns the amount of tokens in existence.\n */\n function totalSupply() external view returns (uint256);\n\n /**\n * @dev Returns the amount of tokens owned by `account`.\n */\n function balanceOf(address account) external view returns (uint256);\n\n /**\n * @dev Moves `amount` tokens from the caller's account to `to`.\n *\n * Returns a boolean value indicating whether the operation succeeded.\n *\n * Emits a {Transfer} event.\n */\n function transfer(address to, uint256 amount) external returns (bool);\n\n /**\n * @dev Returns the remaining number of tokens that `spender` will be\n * allowed to spend on behalf of `owner` through {transferFrom}. This is\n * zero by default.\n *\n * This value changes when {approve} or {transferFrom} are called.\n */\n function allowance(address owner, address spender) external view returns (uint256);\n\n /**\n * @dev Sets `amount` as the allowance of `spender` over the caller's tokens.\n *\n * Returns a boolean value indicating whether the operation succeeded.\n *\n * IMPORTANT: Beware that changing an allowance with this method brings the risk\n * that someone may use both the old and the new allowance by unfortunate\n * transaction ordering. One possible solution to mitigate this race\n * condition is to first reduce the spender's allowance to 0 and set the\n * desired value afterwards:\n * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729\n *\n * Emits an {Approval} event.\n */\n function approve(address spender, uint256 amount) external returns (bool);\n\n /**\n * @dev Moves `amount` tokens from `from` to `to` using the\n * allowance mechanism. `amount` is then deducted from the caller's\n * allowance.\n *\n * Returns a boolean value indicating whether the operation succeeded.\n *\n * Emits a {Transfer} event.\n */\n function transferFrom(\n address from,\n address to,\n uint256 amount\n ) external returns (bool);\n}\n" + }, + "@openzeppelin/contracts-upgradeable/token/ERC721/extensions/IERC721MetadataUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (token/ERC721/extensions/IERC721Metadata.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../IERC721Upgradeable.sol\";\n\n/**\n * @title ERC-721 Non-Fungible Token Standard, optional metadata extension\n * @dev See https://eips.ethereum.org/EIPS/eip-721\n */\ninterface IERC721MetadataUpgradeable is IERC721Upgradeable {\n /**\n * @dev Returns the token collection name.\n */\n function name() external view returns (string memory);\n\n /**\n * @dev Returns the token collection symbol.\n */\n function symbol() external view returns (string memory);\n\n /**\n * @dev Returns the Uniform Resource Identifier (URI) for `tokenId` token.\n */\n function tokenURI(uint256 tokenId) external view returns (string memory);\n}\n" + }, + "@openzeppelin/contracts-upgradeable/token/ERC721/IERC721ReceiverUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.6.0) (token/ERC721/IERC721Receiver.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @title ERC721 token receiver interface\n * @dev Interface for any contract that wants to support safeTransfers\n * from ERC721 asset contracts.\n */\ninterface IERC721ReceiverUpgradeable {\n /**\n * @dev Whenever an {IERC721} `tokenId` token is transferred to this contract via {IERC721-safeTransferFrom}\n * by `operator` from `from`, this function is called.\n *\n * It must return its Solidity selector to confirm the token transfer.\n * If any other value is returned or the interface is not implemented by the recipient, the transfer will be reverted.\n *\n * The selector can be obtained in Solidity with `IERC721Receiver.onERC721Received.selector`.\n */\n function onERC721Received(\n address operator,\n address from,\n uint256 tokenId,\n bytes calldata data\n ) external returns (bytes4);\n}\n" + }, + "@openzeppelin/contracts-upgradeable/token/ERC721/IERC721Upgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (token/ERC721/IERC721.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../../utils/introspection/IERC165Upgradeable.sol\";\n\n/**\n * @dev Required interface of an ERC721 compliant contract.\n */\ninterface IERC721Upgradeable is IERC165Upgradeable {\n /**\n * @dev Emitted when `tokenId` token is transferred from `from` to `to`.\n */\n event Transfer(address indexed from, address indexed to, uint256 indexed tokenId);\n\n /**\n * @dev Emitted when `owner` enables `approved` to manage the `tokenId` token.\n */\n event Approval(address indexed owner, address indexed approved, uint256 indexed tokenId);\n\n /**\n * @dev Emitted when `owner` enables or disables (`approved`) `operator` to manage all of its assets.\n */\n event ApprovalForAll(address indexed owner, address indexed operator, bool approved);\n\n /**\n * @dev Returns the number of tokens in ``owner``'s account.\n */\n function balanceOf(address owner) external view returns (uint256 balance);\n\n /**\n * @dev Returns the owner of the `tokenId` token.\n *\n * Requirements:\n *\n * - `tokenId` must exist.\n */\n function ownerOf(uint256 tokenId) external view returns (address owner);\n\n /**\n * @dev Safely transfers `tokenId` token from `from` to `to`.\n *\n * Requirements:\n *\n * - `from` cannot be the zero address.\n * - `to` cannot be the zero address.\n * - `tokenId` token must exist and be owned by `from`.\n * - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}.\n * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.\n *\n * Emits a {Transfer} event.\n */\n function safeTransferFrom(\n address from,\n address to,\n uint256 tokenId,\n bytes calldata data\n ) external;\n\n /**\n * @dev Safely transfers `tokenId` token from `from` to `to`, checking first that contract recipients\n * are aware of the ERC721 protocol to prevent tokens from being forever locked.\n *\n * Requirements:\n *\n * - `from` cannot be the zero address.\n * - `to` cannot be the zero address.\n * - `tokenId` token must exist and be owned by `from`.\n * - If the caller is not `from`, it must have been allowed to move this token by either {approve} or {setApprovalForAll}.\n * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.\n *\n * Emits a {Transfer} event.\n */\n function safeTransferFrom(\n address from,\n address to,\n uint256 tokenId\n ) external;\n\n /**\n * @dev Transfers `tokenId` token from `from` to `to`.\n *\n * WARNING: Usage of this method is discouraged, use {safeTransferFrom} whenever possible.\n *\n * Requirements:\n *\n * - `from` cannot be the zero address.\n * - `to` cannot be the zero address.\n * - `tokenId` token must be owned by `from`.\n * - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}.\n *\n * Emits a {Transfer} event.\n */\n function transferFrom(\n address from,\n address to,\n uint256 tokenId\n ) external;\n\n /**\n * @dev Gives permission to `to` to transfer `tokenId` token to another account.\n * The approval is cleared when the token is transferred.\n *\n * Only a single account can be approved at a time, so approving the zero address clears previous approvals.\n *\n * Requirements:\n *\n * - The caller must own the token or be an approved operator.\n * - `tokenId` must exist.\n *\n * Emits an {Approval} event.\n */\n function approve(address to, uint256 tokenId) external;\n\n /**\n * @dev Approve or remove `operator` as an operator for the caller.\n * Operators can call {transferFrom} or {safeTransferFrom} for any token owned by the caller.\n *\n * Requirements:\n *\n * - The `operator` cannot be the caller.\n *\n * Emits an {ApprovalForAll} event.\n */\n function setApprovalForAll(address operator, bool _approved) external;\n\n /**\n * @dev Returns the account approved for `tokenId` token.\n *\n * Requirements:\n *\n * - `tokenId` must exist.\n */\n function getApproved(uint256 tokenId) external view returns (address operator);\n\n /**\n * @dev Returns if the `operator` is allowed to manage all of the assets of `owner`.\n *\n * See {setApprovalForAll}\n */\n function isApprovedForAll(address owner, address operator) external view returns (bool);\n}\n" + }, + "@openzeppelin/contracts-upgradeable/utils/AddressUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (utils/Address.sol)\n\npragma solidity ^0.8.1;\n\n/**\n * @dev Collection of functions related to the address type\n */\nlibrary AddressUpgradeable {\n /**\n * @dev Returns true if `account` is a contract.\n *\n * [IMPORTANT]\n * ====\n * It is unsafe to assume that an address for which this function returns\n * false is an externally-owned account (EOA) and not a contract.\n *\n * Among others, `isContract` will return false for the following\n * types of addresses:\n *\n * - an externally-owned account\n * - a contract in construction\n * - an address where a contract will be created\n * - an address where a contract lived, but was destroyed\n * ====\n *\n * [IMPORTANT]\n * ====\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\n *\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\n * constructor.\n * ====\n */\n function isContract(address account) internal view returns (bool) {\n // This method relies on extcodesize/address.code.length, which returns 0\n // for contracts in construction, since the code is only stored at the end\n // of the constructor execution.\n\n return account.code.length > 0;\n }\n\n /**\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\n * `recipient`, forwarding all available gas and reverting on errors.\n *\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\n * imposed by `transfer`, making them unable to receive funds via\n * `transfer`. {sendValue} removes this limitation.\n *\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\n *\n * IMPORTANT: because control is transferred to `recipient`, care must be\n * taken to not create reentrancy vulnerabilities. Consider using\n * {ReentrancyGuard} or the\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\n */\n function sendValue(address payable recipient, uint256 amount) internal {\n require(address(this).balance >= amount, \"Address: insufficient balance\");\n\n (bool success, ) = recipient.call{value: amount}(\"\");\n require(success, \"Address: unable to send value, recipient may have reverted\");\n }\n\n /**\n * @dev Performs a Solidity function call using a low level `call`. A\n * plain `call` is an unsafe replacement for a function call: use this\n * function instead.\n *\n * If `target` reverts with a revert reason, it is bubbled up by this\n * function (like regular Solidity function calls).\n *\n * Returns the raw returned data. To convert to the expected return value,\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\n *\n * Requirements:\n *\n * - `target` must be a contract.\n * - calling `target` with `data` must not revert.\n *\n * _Available since v3.1._\n */\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionCall(target, data, \"Address: low-level call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\n * `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, 0, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but also transferring `value` wei to `target`.\n *\n * Requirements:\n *\n * - the calling contract must have an ETH balance of at least `value`.\n * - the called Solidity function must be `payable`.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, value, \"Address: low-level call with value failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\n * with `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(address(this).balance >= value, \"Address: insufficient balance for call\");\n require(isContract(target), \"Address: call to non-contract\");\n\n (bool success, bytes memory returndata) = target.call{value: value}(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\n return functionStaticCall(target, data, \"Address: low-level static call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal view returns (bytes memory) {\n require(isContract(target), \"Address: static call to non-contract\");\n\n (bool success, bytes memory returndata) = target.staticcall(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the\n * revert reason using the provided one.\n *\n * _Available since v4.3._\n */\n function verifyCallResult(\n bool success,\n bytes memory returndata,\n string memory errorMessage\n ) internal pure returns (bytes memory) {\n if (success) {\n return returndata;\n } else {\n // Look for revert reason and bubble it up if present\n if (returndata.length > 0) {\n // The easiest way to bubble the revert reason is using memory via assembly\n /// @solidity memory-safe-assembly\n assembly {\n let returndata_size := mload(returndata)\n revert(add(32, returndata), returndata_size)\n }\n } else {\n revert(errorMessage);\n }\n }\n }\n}\n" + }, + "@openzeppelin/contracts-upgradeable/utils/ContextUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)\n\npragma solidity ^0.8.0;\nimport \"../proxy/utils/Initializable.sol\";\n\n/**\n * @dev Provides information about the current execution context, including the\n * sender of the transaction and its data. While these are generally available\n * via msg.sender and msg.data, they should not be accessed in such a direct\n * manner, since when dealing with meta-transactions the account sending and\n * paying for execution may not be the actual sender (as far as an application\n * is concerned).\n *\n * This contract is only required for intermediate, library-like contracts.\n */\nabstract contract ContextUpgradeable is Initializable {\n function __Context_init() internal onlyInitializing {\n }\n\n function __Context_init_unchained() internal onlyInitializing {\n }\n function _msgSender() internal view virtual returns (address) {\n return msg.sender;\n }\n\n function _msgData() internal view virtual returns (bytes calldata) {\n return msg.data;\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[50] private __gap;\n}\n" + }, + "@openzeppelin/contracts-upgradeable/utils/CountersUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (utils/Counters.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @title Counters\n * @author Matt Condon (@shrugs)\n * @dev Provides counters that can only be incremented, decremented or reset. This can be used e.g. to track the number\n * of elements in a mapping, issuing ERC721 ids, or counting request ids.\n *\n * Include with `using Counters for Counters.Counter;`\n */\nlibrary CountersUpgradeable {\n struct Counter {\n // This variable should never be directly accessed by users of the library: interactions must be restricted to\n // the library's function. As of Solidity v0.5.2, this cannot be enforced, though there is a proposal to add\n // this feature: see https://github.com/ethereum/solidity/issues/4637\n uint256 _value; // default: 0\n }\n\n function current(Counter storage counter) internal view returns (uint256) {\n return counter._value;\n }\n\n function increment(Counter storage counter) internal {\n unchecked {\n counter._value += 1;\n }\n }\n\n function decrement(Counter storage counter) internal {\n uint256 value = counter._value;\n require(value > 0, \"Counter: decrement overflow\");\n unchecked {\n counter._value = value - 1;\n }\n }\n\n function reset(Counter storage counter) internal {\n counter._value = 0;\n }\n}\n" + }, + "@openzeppelin/contracts-upgradeable/utils/cryptography/draft-EIP712Upgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (utils/cryptography/draft-EIP712.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./ECDSAUpgradeable.sol\";\nimport \"../../proxy/utils/Initializable.sol\";\n\n/**\n * @dev https://eips.ethereum.org/EIPS/eip-712[EIP 712] is a standard for hashing and signing of typed structured data.\n *\n * The encoding specified in the EIP is very generic, and such a generic implementation in Solidity is not feasible,\n * thus this contract does not implement the encoding itself. Protocols need to implement the type-specific encoding\n * they need in their contracts using a combination of `abi.encode` and `keccak256`.\n *\n * This contract implements the EIP 712 domain separator ({_domainSeparatorV4}) that is used as part of the encoding\n * scheme, and the final step of the encoding to obtain the message digest that is then signed via ECDSA\n * ({_hashTypedDataV4}).\n *\n * The implementation of the domain separator was designed to be as efficient as possible while still properly updating\n * the chain id to protect against replay attacks on an eventual fork of the chain.\n *\n * NOTE: This contract implements the version of the encoding known as \"v4\", as implemented by the JSON RPC method\n * https://docs.metamask.io/guide/signing-data.html[`eth_signTypedDataV4` in MetaMask].\n *\n * _Available since v3.4._\n *\n * @custom:storage-size 52\n */\nabstract contract EIP712Upgradeable is Initializable {\n /* solhint-disable var-name-mixedcase */\n bytes32 private _HASHED_NAME;\n bytes32 private _HASHED_VERSION;\n bytes32 private constant _TYPE_HASH = keccak256(\"EIP712Domain(string name,string version,uint256 chainId,address verifyingContract)\");\n\n /* solhint-enable var-name-mixedcase */\n\n /**\n * @dev Initializes the domain separator and parameter caches.\n *\n * The meaning of `name` and `version` is specified in\n * https://eips.ethereum.org/EIPS/eip-712#definition-of-domainseparator[EIP 712]:\n *\n * - `name`: the user readable name of the signing domain, i.e. the name of the DApp or the protocol.\n * - `version`: the current major version of the signing domain.\n *\n * NOTE: These parameters cannot be changed except through a xref:learn::upgrading-smart-contracts.adoc[smart\n * contract upgrade].\n */\n function __EIP712_init(string memory name, string memory version) internal onlyInitializing {\n __EIP712_init_unchained(name, version);\n }\n\n function __EIP712_init_unchained(string memory name, string memory version) internal onlyInitializing {\n bytes32 hashedName = keccak256(bytes(name));\n bytes32 hashedVersion = keccak256(bytes(version));\n _HASHED_NAME = hashedName;\n _HASHED_VERSION = hashedVersion;\n }\n\n /**\n * @dev Returns the domain separator for the current chain.\n */\n function _domainSeparatorV4() internal view returns (bytes32) {\n return _buildDomainSeparator(_TYPE_HASH, _EIP712NameHash(), _EIP712VersionHash());\n }\n\n function _buildDomainSeparator(\n bytes32 typeHash,\n bytes32 nameHash,\n bytes32 versionHash\n ) private view returns (bytes32) {\n return keccak256(abi.encode(typeHash, nameHash, versionHash, block.chainid, address(this)));\n }\n\n /**\n * @dev Given an already https://eips.ethereum.org/EIPS/eip-712#definition-of-hashstruct[hashed struct], this\n * function returns the hash of the fully encoded EIP712 message for this domain.\n *\n * This hash can be used together with {ECDSA-recover} to obtain the signer of a message. For example:\n *\n * ```solidity\n * bytes32 digest = _hashTypedDataV4(keccak256(abi.encode(\n * keccak256(\"Mail(address to,string contents)\"),\n * mailTo,\n * keccak256(bytes(mailContents))\n * )));\n * address signer = ECDSA.recover(digest, signature);\n * ```\n */\n function _hashTypedDataV4(bytes32 structHash) internal view virtual returns (bytes32) {\n return ECDSAUpgradeable.toTypedDataHash(_domainSeparatorV4(), structHash);\n }\n\n /**\n * @dev The hash of the name parameter for the EIP712 domain.\n *\n * NOTE: This function reads from storage by default, but can be redefined to return a constant value if gas costs\n * are a concern.\n */\n function _EIP712NameHash() internal virtual view returns (bytes32) {\n return _HASHED_NAME;\n }\n\n /**\n * @dev The hash of the version parameter for the EIP712 domain.\n *\n * NOTE: This function reads from storage by default, but can be redefined to return a constant value if gas costs\n * are a concern.\n */\n function _EIP712VersionHash() internal virtual view returns (bytes32) {\n return _HASHED_VERSION;\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[50] private __gap;\n}\n" + }, + "@openzeppelin/contracts-upgradeable/utils/cryptography/ECDSAUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (utils/cryptography/ECDSA.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../StringsUpgradeable.sol\";\n\n/**\n * @dev Elliptic Curve Digital Signature Algorithm (ECDSA) operations.\n *\n * These functions can be used to verify that a message was signed by the holder\n * of the private keys of a given address.\n */\nlibrary ECDSAUpgradeable {\n enum RecoverError {\n NoError,\n InvalidSignature,\n InvalidSignatureLength,\n InvalidSignatureS,\n InvalidSignatureV\n }\n\n function _throwError(RecoverError error) private pure {\n if (error == RecoverError.NoError) {\n return; // no error: do nothing\n } else if (error == RecoverError.InvalidSignature) {\n revert(\"ECDSA: invalid signature\");\n } else if (error == RecoverError.InvalidSignatureLength) {\n revert(\"ECDSA: invalid signature length\");\n } else if (error == RecoverError.InvalidSignatureS) {\n revert(\"ECDSA: invalid signature 's' value\");\n } else if (error == RecoverError.InvalidSignatureV) {\n revert(\"ECDSA: invalid signature 'v' value\");\n }\n }\n\n /**\n * @dev Returns the address that signed a hashed message (`hash`) with\n * `signature` or error string. This address can then be used for verification purposes.\n *\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\n * this function rejects them by requiring the `s` value to be in the lower\n * half order, and the `v` value to be either 27 or 28.\n *\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\n * verification to be secure: it is possible to craft signatures that\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\n * this is by receiving a hash of the original message (which may otherwise\n * be too long), and then calling {toEthSignedMessageHash} on it.\n *\n * Documentation for signature generation:\n * - with https://web3js.readthedocs.io/en/v1.3.4/web3-eth-accounts.html#sign[Web3.js]\n * - with https://docs.ethers.io/v5/api/signer/#Signer-signMessage[ethers]\n *\n * _Available since v4.3._\n */\n function tryRecover(bytes32 hash, bytes memory signature) internal pure returns (address, RecoverError) {\n // Check the signature length\n // - case 65: r,s,v signature (standard)\n // - case 64: r,vs signature (cf https://eips.ethereum.org/EIPS/eip-2098) _Available since v4.1._\n if (signature.length == 65) {\n bytes32 r;\n bytes32 s;\n uint8 v;\n // ecrecover takes the signature parameters, and the only way to get them\n // currently is to use assembly.\n /// @solidity memory-safe-assembly\n assembly {\n r := mload(add(signature, 0x20))\n s := mload(add(signature, 0x40))\n v := byte(0, mload(add(signature, 0x60)))\n }\n return tryRecover(hash, v, r, s);\n } else if (signature.length == 64) {\n bytes32 r;\n bytes32 vs;\n // ecrecover takes the signature parameters, and the only way to get them\n // currently is to use assembly.\n /// @solidity memory-safe-assembly\n assembly {\n r := mload(add(signature, 0x20))\n vs := mload(add(signature, 0x40))\n }\n return tryRecover(hash, r, vs);\n } else {\n return (address(0), RecoverError.InvalidSignatureLength);\n }\n }\n\n /**\n * @dev Returns the address that signed a hashed message (`hash`) with\n * `signature`. This address can then be used for verification purposes.\n *\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\n * this function rejects them by requiring the `s` value to be in the lower\n * half order, and the `v` value to be either 27 or 28.\n *\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\n * verification to be secure: it is possible to craft signatures that\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\n * this is by receiving a hash of the original message (which may otherwise\n * be too long), and then calling {toEthSignedMessageHash} on it.\n */\n function recover(bytes32 hash, bytes memory signature) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, signature);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Overload of {ECDSA-tryRecover} that receives the `r` and `vs` short-signature fields separately.\n *\n * See https://eips.ethereum.org/EIPS/eip-2098[EIP-2098 short signatures]\n *\n * _Available since v4.3._\n */\n function tryRecover(\n bytes32 hash,\n bytes32 r,\n bytes32 vs\n ) internal pure returns (address, RecoverError) {\n bytes32 s = vs & bytes32(0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff);\n uint8 v = uint8((uint256(vs) >> 255) + 27);\n return tryRecover(hash, v, r, s);\n }\n\n /**\n * @dev Overload of {ECDSA-recover} that receives the `r and `vs` short-signature fields separately.\n *\n * _Available since v4.2._\n */\n function recover(\n bytes32 hash,\n bytes32 r,\n bytes32 vs\n ) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, r, vs);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Overload of {ECDSA-tryRecover} that receives the `v`,\n * `r` and `s` signature fields separately.\n *\n * _Available since v4.3._\n */\n function tryRecover(\n bytes32 hash,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) internal pure returns (address, RecoverError) {\n // EIP-2 still allows signature malleability for ecrecover(). Remove this possibility and make the signature\n // unique. Appendix F in the Ethereum Yellow paper (https://ethereum.github.io/yellowpaper/paper.pdf), defines\n // the valid range for s in (301): 0 < s < secp256k1n ÷ 2 + 1, and for v in (302): v ∈ {27, 28}. Most\n // signatures from current libraries generate a unique signature with an s-value in the lower half order.\n //\n // If your library generates malleable signatures, such as s-values in the upper range, calculate a new s-value\n // with 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141 - s1 and flip v from 27 to 28 or\n // vice versa. If your library also generates signatures with 0/1 for v instead 27/28, add 27 to v to accept\n // these malleable signatures as well.\n if (uint256(s) > 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D576E7357A4501DDFE92F46681B20A0) {\n return (address(0), RecoverError.InvalidSignatureS);\n }\n if (v != 27 && v != 28) {\n return (address(0), RecoverError.InvalidSignatureV);\n }\n\n // If the signature is valid (and not malleable), return the signer address\n address signer = ecrecover(hash, v, r, s);\n if (signer == address(0)) {\n return (address(0), RecoverError.InvalidSignature);\n }\n\n return (signer, RecoverError.NoError);\n }\n\n /**\n * @dev Overload of {ECDSA-recover} that receives the `v`,\n * `r` and `s` signature fields separately.\n */\n function recover(\n bytes32 hash,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, v, r, s);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Returns an Ethereum Signed Message, created from a `hash`. This\n * produces hash corresponding to the one signed with the\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\n * JSON-RPC method as part of EIP-191.\n *\n * See {recover}.\n */\n function toEthSignedMessageHash(bytes32 hash) internal pure returns (bytes32) {\n // 32 is the length in bytes of hash,\n // enforced by the type signature above\n return keccak256(abi.encodePacked(\"\\x19Ethereum Signed Message:\\n32\", hash));\n }\n\n /**\n * @dev Returns an Ethereum Signed Message, created from `s`. This\n * produces hash corresponding to the one signed with the\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\n * JSON-RPC method as part of EIP-191.\n *\n * See {recover}.\n */\n function toEthSignedMessageHash(bytes memory s) internal pure returns (bytes32) {\n return keccak256(abi.encodePacked(\"\\x19Ethereum Signed Message:\\n\", StringsUpgradeable.toString(s.length), s));\n }\n\n /**\n * @dev Returns an Ethereum Signed Typed Data, created from a\n * `domainSeparator` and a `structHash`. This produces hash corresponding\n * to the one signed with the\n * https://eips.ethereum.org/EIPS/eip-712[`eth_signTypedData`]\n * JSON-RPC method as part of EIP-712.\n *\n * See {recover}.\n */\n function toTypedDataHash(bytes32 domainSeparator, bytes32 structHash) internal pure returns (bytes32) {\n return keccak256(abi.encodePacked(\"\\x19\\x01\", domainSeparator, structHash));\n }\n}\n" + }, + "@openzeppelin/contracts-upgradeable/utils/introspection/ERC165Upgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (utils/introspection/ERC165.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./IERC165Upgradeable.sol\";\nimport \"../../proxy/utils/Initializable.sol\";\n\n/**\n * @dev Implementation of the {IERC165} interface.\n *\n * Contracts that want to implement ERC165 should inherit from this contract and override {supportsInterface} to check\n * for the additional interface id that will be supported. For example:\n *\n * ```solidity\n * function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {\n * return interfaceId == type(MyInterface).interfaceId || super.supportsInterface(interfaceId);\n * }\n * ```\n *\n * Alternatively, {ERC165Storage} provides an easier to use but more expensive implementation.\n */\nabstract contract ERC165Upgradeable is Initializable, IERC165Upgradeable {\n function __ERC165_init() internal onlyInitializing {\n }\n\n function __ERC165_init_unchained() internal onlyInitializing {\n }\n /**\n * @dev See {IERC165-supportsInterface}.\n */\n function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {\n return interfaceId == type(IERC165Upgradeable).interfaceId;\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[50] private __gap;\n}\n" + }, + "@openzeppelin/contracts-upgradeable/utils/introspection/IERC165Upgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (utils/introspection/IERC165.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Interface of the ERC165 standard, as defined in the\n * https://eips.ethereum.org/EIPS/eip-165[EIP].\n *\n * Implementers can declare support of contract interfaces, which can then be\n * queried by others ({ERC165Checker}).\n *\n * For an implementation, see {ERC165}.\n */\ninterface IERC165Upgradeable {\n /**\n * @dev Returns true if this contract implements the interface defined by\n * `interfaceId`. See the corresponding\n * https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified[EIP section]\n * to learn more about how these ids are created.\n *\n * This function call must use less than 30 000 gas.\n */\n function supportsInterface(bytes4 interfaceId) external view returns (bool);\n}\n" + }, + "@openzeppelin/contracts-upgradeable/utils/StringsUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (utils/Strings.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev String operations.\n */\nlibrary StringsUpgradeable {\n bytes16 private constant _HEX_SYMBOLS = \"0123456789abcdef\";\n uint8 private constant _ADDRESS_LENGTH = 20;\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` decimal representation.\n */\n function toString(uint256 value) internal pure returns (string memory) {\n // Inspired by OraclizeAPI's implementation - MIT licence\n // https://github.com/oraclize/ethereum-api/blob/b42146b063c7d6ee1358846c198246239e9360e8/oraclizeAPI_0.4.25.sol\n\n if (value == 0) {\n return \"0\";\n }\n uint256 temp = value;\n uint256 digits;\n while (temp != 0) {\n digits++;\n temp /= 10;\n }\n bytes memory buffer = new bytes(digits);\n while (value != 0) {\n digits -= 1;\n buffer[digits] = bytes1(uint8(48 + uint256(value % 10)));\n value /= 10;\n }\n return string(buffer);\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation.\n */\n function toHexString(uint256 value) internal pure returns (string memory) {\n if (value == 0) {\n return \"0x00\";\n }\n uint256 temp = value;\n uint256 length = 0;\n while (temp != 0) {\n length++;\n temp >>= 8;\n }\n return toHexString(value, length);\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length.\n */\n function toHexString(uint256 value, uint256 length) internal pure returns (string memory) {\n bytes memory buffer = new bytes(2 * length + 2);\n buffer[0] = \"0\";\n buffer[1] = \"x\";\n for (uint256 i = 2 * length + 1; i > 1; --i) {\n buffer[i] = _HEX_SYMBOLS[value & 0xf];\n value >>= 4;\n }\n require(value == 0, \"Strings: hex length insufficient\");\n return string(buffer);\n }\n\n /**\n * @dev Converts an `address` with fixed length of 20 bytes to its not checksummed ASCII `string` hexadecimal representation.\n */\n function toHexString(address addr) internal pure returns (string memory) {\n return toHexString(uint256(uint160(addr)), _ADDRESS_LENGTH);\n }\n}\n" + }, + "@openzeppelin/contracts-upgradeable/utils/structs/EnumerableSetUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (utils/structs/EnumerableSet.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Library for managing\n * https://en.wikipedia.org/wiki/Set_(abstract_data_type)[sets] of primitive\n * types.\n *\n * Sets have the following properties:\n *\n * - Elements are added, removed, and checked for existence in constant time\n * (O(1)).\n * - Elements are enumerated in O(n). No guarantees are made on the ordering.\n *\n * ```\n * contract Example {\n * // Add the library methods\n * using EnumerableSet for EnumerableSet.AddressSet;\n *\n * // Declare a set state variable\n * EnumerableSet.AddressSet private mySet;\n * }\n * ```\n *\n * As of v3.3.0, sets of type `bytes32` (`Bytes32Set`), `address` (`AddressSet`)\n * and `uint256` (`UintSet`) are supported.\n *\n * [WARNING]\n * ====\n * Trying to delete such a structure from storage will likely result in data corruption, rendering the structure unusable.\n * See https://github.com/ethereum/solidity/pull/11843[ethereum/solidity#11843] for more info.\n *\n * In order to clean an EnumerableSet, you can either remove all elements one by one or create a fresh instance using an array of EnumerableSet.\n * ====\n */\nlibrary EnumerableSetUpgradeable {\n // To implement this library for multiple types with as little code\n // repetition as possible, we write it in terms of a generic Set type with\n // bytes32 values.\n // The Set implementation uses private functions, and user-facing\n // implementations (such as AddressSet) are just wrappers around the\n // underlying Set.\n // This means that we can only create new EnumerableSets for types that fit\n // in bytes32.\n\n struct Set {\n // Storage of set values\n bytes32[] _values;\n // Position of the value in the `values` array, plus 1 because index 0\n // means a value is not in the set.\n mapping(bytes32 => uint256) _indexes;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function _add(Set storage set, bytes32 value) private returns (bool) {\n if (!_contains(set, value)) {\n set._values.push(value);\n // The value is stored at length-1, but we add 1 to all indexes\n // and use 0 as a sentinel value\n set._indexes[value] = set._values.length;\n return true;\n } else {\n return false;\n }\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function _remove(Set storage set, bytes32 value) private returns (bool) {\n // We read and store the value's index to prevent multiple reads from the same storage slot\n uint256 valueIndex = set._indexes[value];\n\n if (valueIndex != 0) {\n // Equivalent to contains(set, value)\n // To delete an element from the _values array in O(1), we swap the element to delete with the last one in\n // the array, and then remove the last element (sometimes called as 'swap and pop').\n // This modifies the order of the array, as noted in {at}.\n\n uint256 toDeleteIndex = valueIndex - 1;\n uint256 lastIndex = set._values.length - 1;\n\n if (lastIndex != toDeleteIndex) {\n bytes32 lastValue = set._values[lastIndex];\n\n // Move the last value to the index where the value to delete is\n set._values[toDeleteIndex] = lastValue;\n // Update the index for the moved value\n set._indexes[lastValue] = valueIndex; // Replace lastValue's index to valueIndex\n }\n\n // Delete the slot where the moved value was stored\n set._values.pop();\n\n // Delete the index for the deleted slot\n delete set._indexes[value];\n\n return true;\n } else {\n return false;\n }\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function _contains(Set storage set, bytes32 value) private view returns (bool) {\n return set._indexes[value] != 0;\n }\n\n /**\n * @dev Returns the number of values on the set. O(1).\n */\n function _length(Set storage set) private view returns (uint256) {\n return set._values.length;\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function _at(Set storage set, uint256 index) private view returns (bytes32) {\n return set._values[index];\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function _values(Set storage set) private view returns (bytes32[] memory) {\n return set._values;\n }\n\n // Bytes32Set\n\n struct Bytes32Set {\n Set _inner;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function add(Bytes32Set storage set, bytes32 value) internal returns (bool) {\n return _add(set._inner, value);\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function remove(Bytes32Set storage set, bytes32 value) internal returns (bool) {\n return _remove(set._inner, value);\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function contains(Bytes32Set storage set, bytes32 value) internal view returns (bool) {\n return _contains(set._inner, value);\n }\n\n /**\n * @dev Returns the number of values in the set. O(1).\n */\n function length(Bytes32Set storage set) internal view returns (uint256) {\n return _length(set._inner);\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function at(Bytes32Set storage set, uint256 index) internal view returns (bytes32) {\n return _at(set._inner, index);\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function values(Bytes32Set storage set) internal view returns (bytes32[] memory) {\n return _values(set._inner);\n }\n\n // AddressSet\n\n struct AddressSet {\n Set _inner;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function add(AddressSet storage set, address value) internal returns (bool) {\n return _add(set._inner, bytes32(uint256(uint160(value))));\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function remove(AddressSet storage set, address value) internal returns (bool) {\n return _remove(set._inner, bytes32(uint256(uint160(value))));\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function contains(AddressSet storage set, address value) internal view returns (bool) {\n return _contains(set._inner, bytes32(uint256(uint160(value))));\n }\n\n /**\n * @dev Returns the number of values in the set. O(1).\n */\n function length(AddressSet storage set) internal view returns (uint256) {\n return _length(set._inner);\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function at(AddressSet storage set, uint256 index) internal view returns (address) {\n return address(uint160(uint256(_at(set._inner, index))));\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function values(AddressSet storage set) internal view returns (address[] memory) {\n bytes32[] memory store = _values(set._inner);\n address[] memory result;\n\n /// @solidity memory-safe-assembly\n assembly {\n result := store\n }\n\n return result;\n }\n\n // UintSet\n\n struct UintSet {\n Set _inner;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function add(UintSet storage set, uint256 value) internal returns (bool) {\n return _add(set._inner, bytes32(value));\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function remove(UintSet storage set, uint256 value) internal returns (bool) {\n return _remove(set._inner, bytes32(value));\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function contains(UintSet storage set, uint256 value) internal view returns (bool) {\n return _contains(set._inner, bytes32(value));\n }\n\n /**\n * @dev Returns the number of values on the set. O(1).\n */\n function length(UintSet storage set) internal view returns (uint256) {\n return _length(set._inner);\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function at(UintSet storage set, uint256 index) internal view returns (uint256) {\n return uint256(_at(set._inner, index));\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function values(UintSet storage set) internal view returns (uint256[] memory) {\n bytes32[] memory store = _values(set._inner);\n uint256[] memory result;\n\n /// @solidity memory-safe-assembly\n assembly {\n result := store\n }\n\n return result;\n }\n}\n" + }, + "@openzeppelin/contracts/access/Ownable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (access/Ownable.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../utils/Context.sol\";\n\n/**\n * @dev Contract module which provides a basic access control mechanism, where\n * there is an account (an owner) that can be granted exclusive access to\n * specific functions.\n *\n * By default, the owner account will be the one that deploys the contract. This\n * can later be changed with {transferOwnership}.\n *\n * This module is used through inheritance. It will make available the modifier\n * `onlyOwner`, which can be applied to your functions to restrict their use to\n * the owner.\n */\nabstract contract Ownable is Context {\n address private _owner;\n\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\n\n /**\n * @dev Initializes the contract setting the deployer as the initial owner.\n */\n constructor() {\n _transferOwnership(_msgSender());\n }\n\n /**\n * @dev Throws if called by any account other than the owner.\n */\n modifier onlyOwner() {\n _checkOwner();\n _;\n }\n\n /**\n * @dev Returns the address of the current owner.\n */\n function owner() public view virtual returns (address) {\n return _owner;\n }\n\n /**\n * @dev Throws if the sender is not the owner.\n */\n function _checkOwner() internal view virtual {\n require(owner() == _msgSender(), \"Ownable: caller is not the owner\");\n }\n\n /**\n * @dev Leaves the contract without owner. It will not be possible to call\n * `onlyOwner` functions anymore. Can only be called by the current owner.\n *\n * NOTE: Renouncing ownership will leave the contract without an owner,\n * thereby removing any functionality that is only available to the owner.\n */\n function renounceOwnership() public virtual onlyOwner {\n _transferOwnership(address(0));\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Can only be called by the current owner.\n */\n function transferOwnership(address newOwner) public virtual onlyOwner {\n require(newOwner != address(0), \"Ownable: new owner is the zero address\");\n _transferOwnership(newOwner);\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Internal function without access restriction.\n */\n function _transferOwnership(address newOwner) internal virtual {\n address oldOwner = _owner;\n _owner = newOwner;\n emit OwnershipTransferred(oldOwner, newOwner);\n }\n}\n" + }, + "@openzeppelin/contracts/interfaces/draft-IERC1822.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.5.0) (interfaces/draft-IERC1822.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev ERC1822: Universal Upgradeable Proxy Standard (UUPS) documents a method for upgradeability through a simplified\n * proxy whose upgrades are fully controlled by the current implementation.\n */\ninterface IERC1822Proxiable {\n /**\n * @dev Returns the storage slot that the proxiable contract assumes is being used to store the implementation\n * address.\n *\n * IMPORTANT: A proxy pointing at a proxiable contract should not be considered proxiable itself, because this risks\n * bricking a proxy that upgrades to it, by delegating to itself until out of gas. Thus it is critical that this\n * function revert if invoked through a proxy.\n */\n function proxiableUUID() external view returns (bytes32);\n}\n" + }, + "@openzeppelin/contracts/interfaces/IERC3156FlashBorrower.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (interfaces/IERC3156FlashBorrower.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Interface of the ERC3156 FlashBorrower, as defined in\n * https://eips.ethereum.org/EIPS/eip-3156[ERC-3156].\n *\n * _Available since v4.1._\n */\ninterface IERC3156FlashBorrower {\n /**\n * @dev Receive a flash loan.\n * @param initiator The initiator of the loan.\n * @param token The loan currency.\n * @param amount The amount of tokens lent.\n * @param fee The additional amount of tokens to repay.\n * @param data Arbitrary data structure, intended to contain user-defined parameters.\n * @return The keccak256 hash of \"IERC3156FlashBorrower.onFlashLoan\"\n */\n function onFlashLoan(\n address initiator,\n address token,\n uint256 amount,\n uint256 fee,\n bytes calldata data\n ) external returns (bytes32);\n}\n" + }, + "@openzeppelin/contracts/interfaces/IERC3156FlashLender.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (interfaces/IERC3156FlashLender.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./IERC3156FlashBorrower.sol\";\n\n/**\n * @dev Interface of the ERC3156 FlashLender, as defined in\n * https://eips.ethereum.org/EIPS/eip-3156[ERC-3156].\n *\n * _Available since v4.1._\n */\ninterface IERC3156FlashLender {\n /**\n * @dev The amount of currency available to be lended.\n * @param token The loan currency.\n * @return The amount of `token` that can be borrowed.\n */\n function maxFlashLoan(address token) external view returns (uint256);\n\n /**\n * @dev The fee to be charged for a given loan.\n * @param token The loan currency.\n * @param amount The amount of tokens lent.\n * @return The amount of `token` to be charged for the loan, on top of the returned principal.\n */\n function flashFee(address token, uint256 amount) external view returns (uint256);\n\n /**\n * @dev Initiate a flash loan.\n * @param receiver The receiver of the tokens in the loan, and the receiver of the callback.\n * @param token The loan currency.\n * @param amount The amount of tokens lent.\n * @param data Arbitrary data structure, intended to contain user-defined parameters.\n */\n function flashLoan(\n IERC3156FlashBorrower receiver,\n address token,\n uint256 amount,\n bytes calldata data\n ) external returns (bool);\n}\n" + }, + "@openzeppelin/contracts/interfaces/IERC721Metadata.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (interfaces/IERC721Metadata.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../token/ERC721/extensions/IERC721Metadata.sol\";\n" + }, + "@openzeppelin/contracts/proxy/beacon/IBeacon.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (proxy/beacon/IBeacon.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev This is the interface that {BeaconProxy} expects of its beacon.\n */\ninterface IBeacon {\n /**\n * @dev Must return an address that can be used as a delegate call target.\n *\n * {BeaconProxy} will check that this address is a contract.\n */\n function implementation() external view returns (address);\n}\n" + }, + "@openzeppelin/contracts/proxy/ERC1967/ERC1967Proxy.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (proxy/ERC1967/ERC1967Proxy.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../Proxy.sol\";\nimport \"./ERC1967Upgrade.sol\";\n\n/**\n * @dev This contract implements an upgradeable proxy. It is upgradeable because calls are delegated to an\n * implementation address that can be changed. This address is stored in storage in the location specified by\n * https://eips.ethereum.org/EIPS/eip-1967[EIP1967], so that it doesn't conflict with the storage layout of the\n * implementation behind the proxy.\n */\ncontract ERC1967Proxy is Proxy, ERC1967Upgrade {\n /**\n * @dev Initializes the upgradeable proxy with an initial implementation specified by `_logic`.\n *\n * If `_data` is nonempty, it's used as data in a delegate call to `_logic`. This will typically be an encoded\n * function call, and allows initializing the storage of the proxy like a Solidity constructor.\n */\n constructor(address _logic, bytes memory _data) payable {\n _upgradeToAndCall(_logic, _data, false);\n }\n\n /**\n * @dev Returns the current implementation address.\n */\n function _implementation() internal view virtual override returns (address impl) {\n return ERC1967Upgrade._getImplementation();\n }\n}\n" + }, + "@openzeppelin/contracts/proxy/ERC1967/ERC1967Upgrade.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.5.0) (proxy/ERC1967/ERC1967Upgrade.sol)\n\npragma solidity ^0.8.2;\n\nimport \"../beacon/IBeacon.sol\";\nimport \"../../interfaces/draft-IERC1822.sol\";\nimport \"../../utils/Address.sol\";\nimport \"../../utils/StorageSlot.sol\";\n\n/**\n * @dev This abstract contract provides getters and event emitting update functions for\n * https://eips.ethereum.org/EIPS/eip-1967[EIP1967] slots.\n *\n * _Available since v4.1._\n *\n * @custom:oz-upgrades-unsafe-allow delegatecall\n */\nabstract contract ERC1967Upgrade {\n // This is the keccak-256 hash of \"eip1967.proxy.rollback\" subtracted by 1\n bytes32 private constant _ROLLBACK_SLOT = 0x4910fdfa16fed3260ed0e7147f7cc6da11a60208b5b9406d12a635614ffd9143;\n\n /**\n * @dev Storage slot with the address of the current implementation.\n * This is the keccak-256 hash of \"eip1967.proxy.implementation\" subtracted by 1, and is\n * validated in the constructor.\n */\n bytes32 internal constant _IMPLEMENTATION_SLOT = 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc;\n\n /**\n * @dev Emitted when the implementation is upgraded.\n */\n event Upgraded(address indexed implementation);\n\n /**\n * @dev Returns the current implementation address.\n */\n function _getImplementation() internal view returns (address) {\n return StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value;\n }\n\n /**\n * @dev Stores a new address in the EIP1967 implementation slot.\n */\n function _setImplementation(address newImplementation) private {\n require(Address.isContract(newImplementation), \"ERC1967: new implementation is not a contract\");\n StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value = newImplementation;\n }\n\n /**\n * @dev Perform implementation upgrade\n *\n * Emits an {Upgraded} event.\n */\n function _upgradeTo(address newImplementation) internal {\n _setImplementation(newImplementation);\n emit Upgraded(newImplementation);\n }\n\n /**\n * @dev Perform implementation upgrade with additional setup call.\n *\n * Emits an {Upgraded} event.\n */\n function _upgradeToAndCall(\n address newImplementation,\n bytes memory data,\n bool forceCall\n ) internal {\n _upgradeTo(newImplementation);\n if (data.length > 0 || forceCall) {\n Address.functionDelegateCall(newImplementation, data);\n }\n }\n\n /**\n * @dev Perform implementation upgrade with security checks for UUPS proxies, and additional setup call.\n *\n * Emits an {Upgraded} event.\n */\n function _upgradeToAndCallUUPS(\n address newImplementation,\n bytes memory data,\n bool forceCall\n ) internal {\n // Upgrades from old implementations will perform a rollback test. This test requires the new\n // implementation to upgrade back to the old, non-ERC1822 compliant, implementation. Removing\n // this special case will break upgrade paths from old UUPS implementation to new ones.\n if (StorageSlot.getBooleanSlot(_ROLLBACK_SLOT).value) {\n _setImplementation(newImplementation);\n } else {\n try IERC1822Proxiable(newImplementation).proxiableUUID() returns (bytes32 slot) {\n require(slot == _IMPLEMENTATION_SLOT, \"ERC1967Upgrade: unsupported proxiableUUID\");\n } catch {\n revert(\"ERC1967Upgrade: new implementation is not UUPS\");\n }\n _upgradeToAndCall(newImplementation, data, forceCall);\n }\n }\n\n /**\n * @dev Storage slot with the admin of the contract.\n * This is the keccak-256 hash of \"eip1967.proxy.admin\" subtracted by 1, and is\n * validated in the constructor.\n */\n bytes32 internal constant _ADMIN_SLOT = 0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103;\n\n /**\n * @dev Emitted when the admin account has changed.\n */\n event AdminChanged(address previousAdmin, address newAdmin);\n\n /**\n * @dev Returns the current admin.\n */\n function _getAdmin() internal view returns (address) {\n return StorageSlot.getAddressSlot(_ADMIN_SLOT).value;\n }\n\n /**\n * @dev Stores a new address in the EIP1967 admin slot.\n */\n function _setAdmin(address newAdmin) private {\n require(newAdmin != address(0), \"ERC1967: new admin is the zero address\");\n StorageSlot.getAddressSlot(_ADMIN_SLOT).value = newAdmin;\n }\n\n /**\n * @dev Changes the admin of the proxy.\n *\n * Emits an {AdminChanged} event.\n */\n function _changeAdmin(address newAdmin) internal {\n emit AdminChanged(_getAdmin(), newAdmin);\n _setAdmin(newAdmin);\n }\n\n /**\n * @dev The storage slot of the UpgradeableBeacon contract which defines the implementation for this proxy.\n * This is bytes32(uint256(keccak256('eip1967.proxy.beacon')) - 1)) and is validated in the constructor.\n */\n bytes32 internal constant _BEACON_SLOT = 0xa3f0ad74e5423aebfd80d3ef4346578335a9a72aeaee59ff6cb3582b35133d50;\n\n /**\n * @dev Emitted when the beacon is upgraded.\n */\n event BeaconUpgraded(address indexed beacon);\n\n /**\n * @dev Returns the current beacon.\n */\n function _getBeacon() internal view returns (address) {\n return StorageSlot.getAddressSlot(_BEACON_SLOT).value;\n }\n\n /**\n * @dev Stores a new beacon in the EIP1967 beacon slot.\n */\n function _setBeacon(address newBeacon) private {\n require(Address.isContract(newBeacon), \"ERC1967: new beacon is not a contract\");\n require(\n Address.isContract(IBeacon(newBeacon).implementation()),\n \"ERC1967: beacon implementation is not a contract\"\n );\n StorageSlot.getAddressSlot(_BEACON_SLOT).value = newBeacon;\n }\n\n /**\n * @dev Perform beacon upgrade with additional setup call. Note: This upgrades the address of the beacon, it does\n * not upgrade the implementation contained in the beacon (see {UpgradeableBeacon-_setImplementation} for that).\n *\n * Emits a {BeaconUpgraded} event.\n */\n function _upgradeBeaconToAndCall(\n address newBeacon,\n bytes memory data,\n bool forceCall\n ) internal {\n _setBeacon(newBeacon);\n emit BeaconUpgraded(newBeacon);\n if (data.length > 0 || forceCall) {\n Address.functionDelegateCall(IBeacon(newBeacon).implementation(), data);\n }\n }\n}\n" + }, + "@openzeppelin/contracts/proxy/Proxy.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.6.0) (proxy/Proxy.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev This abstract contract provides a fallback function that delegates all calls to another contract using the EVM\n * instruction `delegatecall`. We refer to the second contract as the _implementation_ behind the proxy, and it has to\n * be specified by overriding the virtual {_implementation} function.\n *\n * Additionally, delegation to the implementation can be triggered manually through the {_fallback} function, or to a\n * different contract through the {_delegate} function.\n *\n * The success and return data of the delegated call will be returned back to the caller of the proxy.\n */\nabstract contract Proxy {\n /**\n * @dev Delegates the current call to `implementation`.\n *\n * This function does not return to its internal call site, it will return directly to the external caller.\n */\n function _delegate(address implementation) internal virtual {\n assembly {\n // Copy msg.data. We take full control of memory in this inline assembly\n // block because it will not return to Solidity code. We overwrite the\n // Solidity scratch pad at memory position 0.\n calldatacopy(0, 0, calldatasize())\n\n // Call the implementation.\n // out and outsize are 0 because we don't know the size yet.\n let result := delegatecall(gas(), implementation, 0, calldatasize(), 0, 0)\n\n // Copy the returned data.\n returndatacopy(0, 0, returndatasize())\n\n switch result\n // delegatecall returns 0 on error.\n case 0 {\n revert(0, returndatasize())\n }\n default {\n return(0, returndatasize())\n }\n }\n }\n\n /**\n * @dev This is a virtual function that should be overridden so it returns the address to which the fallback function\n * and {_fallback} should delegate.\n */\n function _implementation() internal view virtual returns (address);\n\n /**\n * @dev Delegates the current call to the address returned by `_implementation()`.\n *\n * This function does not return to its internal call site, it will return directly to the external caller.\n */\n function _fallback() internal virtual {\n _beforeFallback();\n _delegate(_implementation());\n }\n\n /**\n * @dev Fallback function that delegates calls to the address returned by `_implementation()`. Will run if no other\n * function in the contract matches the call data.\n */\n fallback() external payable virtual {\n _fallback();\n }\n\n /**\n * @dev Fallback function that delegates calls to the address returned by `_implementation()`. Will run if call data\n * is empty.\n */\n receive() external payable virtual {\n _fallback();\n }\n\n /**\n * @dev Hook that is called before falling back to the implementation. Can happen as part of a manual `_fallback`\n * call, or as part of the Solidity `fallback` or `receive` functions.\n *\n * If overridden should call `super._beforeFallback()`.\n */\n function _beforeFallback() internal virtual {}\n}\n" + }, + "@openzeppelin/contracts/token/ERC20/ERC20.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (token/ERC20/ERC20.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./IERC20.sol\";\nimport \"./extensions/IERC20Metadata.sol\";\nimport \"../../utils/Context.sol\";\n\n/**\n * @dev Implementation of the {IERC20} interface.\n *\n * This implementation is agnostic to the way tokens are created. This means\n * that a supply mechanism has to be added in a derived contract using {_mint}.\n * For a generic mechanism see {ERC20PresetMinterPauser}.\n *\n * TIP: For a detailed writeup see our guide\n * https://forum.zeppelin.solutions/t/how-to-implement-erc20-supply-mechanisms/226[How\n * to implement supply mechanisms].\n *\n * We have followed general OpenZeppelin Contracts guidelines: functions revert\n * instead returning `false` on failure. This behavior is nonetheless\n * conventional and does not conflict with the expectations of ERC20\n * applications.\n *\n * Additionally, an {Approval} event is emitted on calls to {transferFrom}.\n * This allows applications to reconstruct the allowance for all accounts just\n * by listening to said events. Other implementations of the EIP may not emit\n * these events, as it isn't required by the specification.\n *\n * Finally, the non-standard {decreaseAllowance} and {increaseAllowance}\n * functions have been added to mitigate the well-known issues around setting\n * allowances. See {IERC20-approve}.\n */\ncontract ERC20 is Context, IERC20, IERC20Metadata {\n mapping(address => uint256) private _balances;\n\n mapping(address => mapping(address => uint256)) private _allowances;\n\n uint256 private _totalSupply;\n\n string private _name;\n string private _symbol;\n\n /**\n * @dev Sets the values for {name} and {symbol}.\n *\n * The default value of {decimals} is 18. To select a different value for\n * {decimals} you should overload it.\n *\n * All two of these values are immutable: they can only be set once during\n * construction.\n */\n constructor(string memory name_, string memory symbol_) {\n _name = name_;\n _symbol = symbol_;\n }\n\n /**\n * @dev Returns the name of the token.\n */\n function name() public view virtual override returns (string memory) {\n return _name;\n }\n\n /**\n * @dev Returns the symbol of the token, usually a shorter version of the\n * name.\n */\n function symbol() public view virtual override returns (string memory) {\n return _symbol;\n }\n\n /**\n * @dev Returns the number of decimals used to get its user representation.\n * For example, if `decimals` equals `2`, a balance of `505` tokens should\n * be displayed to a user as `5.05` (`505 / 10 ** 2`).\n *\n * Tokens usually opt for a value of 18, imitating the relationship between\n * Ether and Wei. This is the value {ERC20} uses, unless this function is\n * overridden;\n *\n * NOTE: This information is only used for _display_ purposes: it in\n * no way affects any of the arithmetic of the contract, including\n * {IERC20-balanceOf} and {IERC20-transfer}.\n */\n function decimals() public view virtual override returns (uint8) {\n return 18;\n }\n\n /**\n * @dev See {IERC20-totalSupply}.\n */\n function totalSupply() public view virtual override returns (uint256) {\n return _totalSupply;\n }\n\n /**\n * @dev See {IERC20-balanceOf}.\n */\n function balanceOf(address account) public view virtual override returns (uint256) {\n return _balances[account];\n }\n\n /**\n * @dev See {IERC20-transfer}.\n *\n * Requirements:\n *\n * - `to` cannot be the zero address.\n * - the caller must have a balance of at least `amount`.\n */\n function transfer(address to, uint256 amount) public virtual override returns (bool) {\n address owner = _msgSender();\n _transfer(owner, to, amount);\n return true;\n }\n\n /**\n * @dev See {IERC20-allowance}.\n */\n function allowance(address owner, address spender) public view virtual override returns (uint256) {\n return _allowances[owner][spender];\n }\n\n /**\n * @dev See {IERC20-approve}.\n *\n * NOTE: If `amount` is the maximum `uint256`, the allowance is not updated on\n * `transferFrom`. This is semantically equivalent to an infinite approval.\n *\n * Requirements:\n *\n * - `spender` cannot be the zero address.\n */\n function approve(address spender, uint256 amount) public virtual override returns (bool) {\n address owner = _msgSender();\n _approve(owner, spender, amount);\n return true;\n }\n\n /**\n * @dev See {IERC20-transferFrom}.\n *\n * Emits an {Approval} event indicating the updated allowance. This is not\n * required by the EIP. See the note at the beginning of {ERC20}.\n *\n * NOTE: Does not update the allowance if the current allowance\n * is the maximum `uint256`.\n *\n * Requirements:\n *\n * - `from` and `to` cannot be the zero address.\n * - `from` must have a balance of at least `amount`.\n * - the caller must have allowance for ``from``'s tokens of at least\n * `amount`.\n */\n function transferFrom(\n address from,\n address to,\n uint256 amount\n ) public virtual override returns (bool) {\n address spender = _msgSender();\n _spendAllowance(from, spender, amount);\n _transfer(from, to, amount);\n return true;\n }\n\n /**\n * @dev Atomically increases the allowance granted to `spender` by the caller.\n *\n * This is an alternative to {approve} that can be used as a mitigation for\n * problems described in {IERC20-approve}.\n *\n * Emits an {Approval} event indicating the updated allowance.\n *\n * Requirements:\n *\n * - `spender` cannot be the zero address.\n */\n function increaseAllowance(address spender, uint256 addedValue) public virtual returns (bool) {\n address owner = _msgSender();\n _approve(owner, spender, allowance(owner, spender) + addedValue);\n return true;\n }\n\n /**\n * @dev Atomically decreases the allowance granted to `spender` by the caller.\n *\n * This is an alternative to {approve} that can be used as a mitigation for\n * problems described in {IERC20-approve}.\n *\n * Emits an {Approval} event indicating the updated allowance.\n *\n * Requirements:\n *\n * - `spender` cannot be the zero address.\n * - `spender` must have allowance for the caller of at least\n * `subtractedValue`.\n */\n function decreaseAllowance(address spender, uint256 subtractedValue) public virtual returns (bool) {\n address owner = _msgSender();\n uint256 currentAllowance = allowance(owner, spender);\n require(currentAllowance >= subtractedValue, \"ERC20: decreased allowance below zero\");\n unchecked {\n _approve(owner, spender, currentAllowance - subtractedValue);\n }\n\n return true;\n }\n\n /**\n * @dev Moves `amount` of tokens from `from` to `to`.\n *\n * This internal function is equivalent to {transfer}, and can be used to\n * e.g. implement automatic token fees, slashing mechanisms, etc.\n *\n * Emits a {Transfer} event.\n *\n * Requirements:\n *\n * - `from` cannot be the zero address.\n * - `to` cannot be the zero address.\n * - `from` must have a balance of at least `amount`.\n */\n function _transfer(\n address from,\n address to,\n uint256 amount\n ) internal virtual {\n require(from != address(0), \"ERC20: transfer from the zero address\");\n require(to != address(0), \"ERC20: transfer to the zero address\");\n\n _beforeTokenTransfer(from, to, amount);\n\n uint256 fromBalance = _balances[from];\n require(fromBalance >= amount, \"ERC20: transfer amount exceeds balance\");\n unchecked {\n _balances[from] = fromBalance - amount;\n }\n _balances[to] += amount;\n\n emit Transfer(from, to, amount);\n\n _afterTokenTransfer(from, to, amount);\n }\n\n /** @dev Creates `amount` tokens and assigns them to `account`, increasing\n * the total supply.\n *\n * Emits a {Transfer} event with `from` set to the zero address.\n *\n * Requirements:\n *\n * - `account` cannot be the zero address.\n */\n function _mint(address account, uint256 amount) internal virtual {\n require(account != address(0), \"ERC20: mint to the zero address\");\n\n _beforeTokenTransfer(address(0), account, amount);\n\n _totalSupply += amount;\n _balances[account] += amount;\n emit Transfer(address(0), account, amount);\n\n _afterTokenTransfer(address(0), account, amount);\n }\n\n /**\n * @dev Destroys `amount` tokens from `account`, reducing the\n * total supply.\n *\n * Emits a {Transfer} event with `to` set to the zero address.\n *\n * Requirements:\n *\n * - `account` cannot be the zero address.\n * - `account` must have at least `amount` tokens.\n */\n function _burn(address account, uint256 amount) internal virtual {\n require(account != address(0), \"ERC20: burn from the zero address\");\n\n _beforeTokenTransfer(account, address(0), amount);\n\n uint256 accountBalance = _balances[account];\n require(accountBalance >= amount, \"ERC20: burn amount exceeds balance\");\n unchecked {\n _balances[account] = accountBalance - amount;\n }\n _totalSupply -= amount;\n\n emit Transfer(account, address(0), amount);\n\n _afterTokenTransfer(account, address(0), amount);\n }\n\n /**\n * @dev Sets `amount` as the allowance of `spender` over the `owner` s tokens.\n *\n * This internal function is equivalent to `approve`, and can be used to\n * e.g. set automatic allowances for certain subsystems, etc.\n *\n * Emits an {Approval} event.\n *\n * Requirements:\n *\n * - `owner` cannot be the zero address.\n * - `spender` cannot be the zero address.\n */\n function _approve(\n address owner,\n address spender,\n uint256 amount\n ) internal virtual {\n require(owner != address(0), \"ERC20: approve from the zero address\");\n require(spender != address(0), \"ERC20: approve to the zero address\");\n\n _allowances[owner][spender] = amount;\n emit Approval(owner, spender, amount);\n }\n\n /**\n * @dev Updates `owner` s allowance for `spender` based on spent `amount`.\n *\n * Does not update the allowance amount in case of infinite allowance.\n * Revert if not enough allowance is available.\n *\n * Might emit an {Approval} event.\n */\n function _spendAllowance(\n address owner,\n address spender,\n uint256 amount\n ) internal virtual {\n uint256 currentAllowance = allowance(owner, spender);\n if (currentAllowance != type(uint256).max) {\n require(currentAllowance >= amount, \"ERC20: insufficient allowance\");\n unchecked {\n _approve(owner, spender, currentAllowance - amount);\n }\n }\n }\n\n /**\n * @dev Hook that is called before any transfer of tokens. This includes\n * minting and burning.\n *\n * Calling conditions:\n *\n * - when `from` and `to` are both non-zero, `amount` of ``from``'s tokens\n * will be transferred to `to`.\n * - when `from` is zero, `amount` tokens will be minted for `to`.\n * - when `to` is zero, `amount` of ``from``'s tokens will be burned.\n * - `from` and `to` are never both zero.\n *\n * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].\n */\n function _beforeTokenTransfer(\n address from,\n address to,\n uint256 amount\n ) internal virtual {}\n\n /**\n * @dev Hook that is called after any transfer of tokens. This includes\n * minting and burning.\n *\n * Calling conditions:\n *\n * - when `from` and `to` are both non-zero, `amount` of ``from``'s tokens\n * has been transferred to `to`.\n * - when `from` is zero, `amount` tokens have been minted for `to`.\n * - when `to` is zero, `amount` of ``from``'s tokens have been burned.\n * - `from` and `to` are never both zero.\n *\n * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].\n */\n function _afterTokenTransfer(\n address from,\n address to,\n uint256 amount\n ) internal virtual {}\n}\n" + }, + "@openzeppelin/contracts/token/ERC20/extensions/draft-ERC20Permit.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.6.0) (token/ERC20/extensions/draft-ERC20Permit.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./draft-IERC20Permit.sol\";\nimport \"../ERC20.sol\";\nimport \"../../../utils/cryptography/draft-EIP712.sol\";\nimport \"../../../utils/cryptography/ECDSA.sol\";\nimport \"../../../utils/Counters.sol\";\n\n/**\n * @dev Implementation of the ERC20 Permit extension allowing approvals to be made via signatures, as defined in\n * https://eips.ethereum.org/EIPS/eip-2612[EIP-2612].\n *\n * Adds the {permit} method, which can be used to change an account's ERC20 allowance (see {IERC20-allowance}) by\n * presenting a message signed by the account. By not relying on `{IERC20-approve}`, the token holder account doesn't\n * need to send a transaction, and thus is not required to hold Ether at all.\n *\n * _Available since v3.4._\n */\nabstract contract ERC20Permit is ERC20, IERC20Permit, EIP712 {\n using Counters for Counters.Counter;\n\n mapping(address => Counters.Counter) private _nonces;\n\n // solhint-disable-next-line var-name-mixedcase\n bytes32 private constant _PERMIT_TYPEHASH =\n keccak256(\"Permit(address owner,address spender,uint256 value,uint256 nonce,uint256 deadline)\");\n /**\n * @dev In previous versions `_PERMIT_TYPEHASH` was declared as `immutable`.\n * However, to ensure consistency with the upgradeable transpiler, we will continue\n * to reserve a slot.\n * @custom:oz-renamed-from _PERMIT_TYPEHASH\n */\n // solhint-disable-next-line var-name-mixedcase\n bytes32 private _PERMIT_TYPEHASH_DEPRECATED_SLOT;\n\n /**\n * @dev Initializes the {EIP712} domain separator using the `name` parameter, and setting `version` to `\"1\"`.\n *\n * It's a good idea to use the same `name` that is defined as the ERC20 token name.\n */\n constructor(string memory name) EIP712(name, \"1\") {}\n\n /**\n * @dev See {IERC20Permit-permit}.\n */\n function permit(\n address owner,\n address spender,\n uint256 value,\n uint256 deadline,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) public virtual override {\n require(block.timestamp <= deadline, \"ERC20Permit: expired deadline\");\n\n bytes32 structHash = keccak256(abi.encode(_PERMIT_TYPEHASH, owner, spender, value, _useNonce(owner), deadline));\n\n bytes32 hash = _hashTypedDataV4(structHash);\n\n address signer = ECDSA.recover(hash, v, r, s);\n require(signer == owner, \"ERC20Permit: invalid signature\");\n\n _approve(owner, spender, value);\n }\n\n /**\n * @dev See {IERC20Permit-nonces}.\n */\n function nonces(address owner) public view virtual override returns (uint256) {\n return _nonces[owner].current();\n }\n\n /**\n * @dev See {IERC20Permit-DOMAIN_SEPARATOR}.\n */\n // solhint-disable-next-line func-name-mixedcase\n function DOMAIN_SEPARATOR() external view override returns (bytes32) {\n return _domainSeparatorV4();\n }\n\n /**\n * @dev \"Consume a nonce\": return the current value and increment.\n *\n * _Available since v4.1._\n */\n function _useNonce(address owner) internal virtual returns (uint256 current) {\n Counters.Counter storage nonce = _nonces[owner];\n current = nonce.current();\n nonce.increment();\n }\n}\n" + }, + "@openzeppelin/contracts/token/ERC20/extensions/draft-IERC20Permit.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (token/ERC20/extensions/draft-IERC20Permit.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Interface of the ERC20 Permit extension allowing approvals to be made via signatures, as defined in\n * https://eips.ethereum.org/EIPS/eip-2612[EIP-2612].\n *\n * Adds the {permit} method, which can be used to change an account's ERC20 allowance (see {IERC20-allowance}) by\n * presenting a message signed by the account. By not relying on {IERC20-approve}, the token holder account doesn't\n * need to send a transaction, and thus is not required to hold Ether at all.\n */\ninterface IERC20Permit {\n /**\n * @dev Sets `value` as the allowance of `spender` over ``owner``'s tokens,\n * given ``owner``'s signed approval.\n *\n * IMPORTANT: The same issues {IERC20-approve} has related to transaction\n * ordering also apply here.\n *\n * Emits an {Approval} event.\n *\n * Requirements:\n *\n * - `spender` cannot be the zero address.\n * - `deadline` must be a timestamp in the future.\n * - `v`, `r` and `s` must be a valid `secp256k1` signature from `owner`\n * over the EIP712-formatted function arguments.\n * - the signature must use ``owner``'s current nonce (see {nonces}).\n *\n * For more information on the signature format, see the\n * https://eips.ethereum.org/EIPS/eip-2612#specification[relevant EIP\n * section].\n */\n function permit(\n address owner,\n address spender,\n uint256 value,\n uint256 deadline,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) external;\n\n /**\n * @dev Returns the current nonce for `owner`. This value must be\n * included whenever a signature is generated for {permit}.\n *\n * Every successful call to {permit} increases ``owner``'s nonce by one. This\n * prevents a signature from being used multiple times.\n */\n function nonces(address owner) external view returns (uint256);\n\n /**\n * @dev Returns the domain separator used in the encoding of the signature for {permit}, as defined by {EIP712}.\n */\n // solhint-disable-next-line func-name-mixedcase\n function DOMAIN_SEPARATOR() external view returns (bytes32);\n}\n" + }, + "@openzeppelin/contracts/token/ERC20/extensions/IERC20Metadata.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (token/ERC20/extensions/IERC20Metadata.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../IERC20.sol\";\n\n/**\n * @dev Interface for the optional metadata functions from the ERC20 standard.\n *\n * _Available since v4.1._\n */\ninterface IERC20Metadata is IERC20 {\n /**\n * @dev Returns the name of the token.\n */\n function name() external view returns (string memory);\n\n /**\n * @dev Returns the symbol of the token.\n */\n function symbol() external view returns (string memory);\n\n /**\n * @dev Returns the decimals places of the token.\n */\n function decimals() external view returns (uint8);\n}\n" + }, + "@openzeppelin/contracts/token/ERC20/IERC20.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.6.0) (token/ERC20/IERC20.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Interface of the ERC20 standard as defined in the EIP.\n */\ninterface IERC20 {\n /**\n * @dev Emitted when `value` tokens are moved from one account (`from`) to\n * another (`to`).\n *\n * Note that `value` may be zero.\n */\n event Transfer(address indexed from, address indexed to, uint256 value);\n\n /**\n * @dev Emitted when the allowance of a `spender` for an `owner` is set by\n * a call to {approve}. `value` is the new allowance.\n */\n event Approval(address indexed owner, address indexed spender, uint256 value);\n\n /**\n * @dev Returns the amount of tokens in existence.\n */\n function totalSupply() external view returns (uint256);\n\n /**\n * @dev Returns the amount of tokens owned by `account`.\n */\n function balanceOf(address account) external view returns (uint256);\n\n /**\n * @dev Moves `amount` tokens from the caller's account to `to`.\n *\n * Returns a boolean value indicating whether the operation succeeded.\n *\n * Emits a {Transfer} event.\n */\n function transfer(address to, uint256 amount) external returns (bool);\n\n /**\n * @dev Returns the remaining number of tokens that `spender` will be\n * allowed to spend on behalf of `owner` through {transferFrom}. This is\n * zero by default.\n *\n * This value changes when {approve} or {transferFrom} are called.\n */\n function allowance(address owner, address spender) external view returns (uint256);\n\n /**\n * @dev Sets `amount` as the allowance of `spender` over the caller's tokens.\n *\n * Returns a boolean value indicating whether the operation succeeded.\n *\n * IMPORTANT: Beware that changing an allowance with this method brings the risk\n * that someone may use both the old and the new allowance by unfortunate\n * transaction ordering. One possible solution to mitigate this race\n * condition is to first reduce the spender's allowance to 0 and set the\n * desired value afterwards:\n * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729\n *\n * Emits an {Approval} event.\n */\n function approve(address spender, uint256 amount) external returns (bool);\n\n /**\n * @dev Moves `amount` tokens from `from` to `to` using the\n * allowance mechanism. `amount` is then deducted from the caller's\n * allowance.\n *\n * Returns a boolean value indicating whether the operation succeeded.\n *\n * Emits a {Transfer} event.\n */\n function transferFrom(\n address from,\n address to,\n uint256 amount\n ) external returns (bool);\n}\n" + }, + "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (token/ERC20/utils/SafeERC20.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../IERC20.sol\";\nimport \"../extensions/draft-IERC20Permit.sol\";\nimport \"../../../utils/Address.sol\";\n\n/**\n * @title SafeERC20\n * @dev Wrappers around ERC20 operations that throw on failure (when the token\n * contract returns false). Tokens that return no value (and instead revert or\n * throw on failure) are also supported, non-reverting calls are assumed to be\n * successful.\n * To use this library you can add a `using SafeERC20 for IERC20;` statement to your contract,\n * which allows you to call the safe operations as `token.safeTransfer(...)`, etc.\n */\nlibrary SafeERC20 {\n using Address for address;\n\n function safeTransfer(\n IERC20 token,\n address to,\n uint256 value\n ) internal {\n _callOptionalReturn(token, abi.encodeWithSelector(token.transfer.selector, to, value));\n }\n\n function safeTransferFrom(\n IERC20 token,\n address from,\n address to,\n uint256 value\n ) internal {\n _callOptionalReturn(token, abi.encodeWithSelector(token.transferFrom.selector, from, to, value));\n }\n\n /**\n * @dev Deprecated. This function has issues similar to the ones found in\n * {IERC20-approve}, and its usage is discouraged.\n *\n * Whenever possible, use {safeIncreaseAllowance} and\n * {safeDecreaseAllowance} instead.\n */\n function safeApprove(\n IERC20 token,\n address spender,\n uint256 value\n ) internal {\n // safeApprove should only be called when setting an initial allowance,\n // or when resetting it to zero. To increase and decrease it, use\n // 'safeIncreaseAllowance' and 'safeDecreaseAllowance'\n require(\n (value == 0) || (token.allowance(address(this), spender) == 0),\n \"SafeERC20: approve from non-zero to non-zero allowance\"\n );\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, value));\n }\n\n function safeIncreaseAllowance(\n IERC20 token,\n address spender,\n uint256 value\n ) internal {\n uint256 newAllowance = token.allowance(address(this), spender) + value;\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));\n }\n\n function safeDecreaseAllowance(\n IERC20 token,\n address spender,\n uint256 value\n ) internal {\n unchecked {\n uint256 oldAllowance = token.allowance(address(this), spender);\n require(oldAllowance >= value, \"SafeERC20: decreased allowance below zero\");\n uint256 newAllowance = oldAllowance - value;\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));\n }\n }\n\n function safePermit(\n IERC20Permit token,\n address owner,\n address spender,\n uint256 value,\n uint256 deadline,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) internal {\n uint256 nonceBefore = token.nonces(owner);\n token.permit(owner, spender, value, deadline, v, r, s);\n uint256 nonceAfter = token.nonces(owner);\n require(nonceAfter == nonceBefore + 1, \"SafeERC20: permit did not succeed\");\n }\n\n /**\n * @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement\n * on the return value: the return value is optional (but if data is returned, it must not be false).\n * @param token The token targeted by the call.\n * @param data The call data (encoded using abi.encode or one of its variants).\n */\n function _callOptionalReturn(IERC20 token, bytes memory data) private {\n // We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since\n // we're implementing it ourselves. We use {Address.functionCall} to perform this call, which verifies that\n // the target address contains contract code and also asserts for success in the low-level call.\n\n bytes memory returndata = address(token).functionCall(data, \"SafeERC20: low-level call failed\");\n if (returndata.length > 0) {\n // Return data is optional\n require(abi.decode(returndata, (bool)), \"SafeERC20: ERC20 operation did not succeed\");\n }\n }\n}\n" + }, + "@openzeppelin/contracts/token/ERC721/extensions/IERC721Metadata.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (token/ERC721/extensions/IERC721Metadata.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../IERC721.sol\";\n\n/**\n * @title ERC-721 Non-Fungible Token Standard, optional metadata extension\n * @dev See https://eips.ethereum.org/EIPS/eip-721\n */\ninterface IERC721Metadata is IERC721 {\n /**\n * @dev Returns the token collection name.\n */\n function name() external view returns (string memory);\n\n /**\n * @dev Returns the token collection symbol.\n */\n function symbol() external view returns (string memory);\n\n /**\n * @dev Returns the Uniform Resource Identifier (URI) for `tokenId` token.\n */\n function tokenURI(uint256 tokenId) external view returns (string memory);\n}\n" + }, + "@openzeppelin/contracts/token/ERC721/IERC721.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (token/ERC721/IERC721.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../../utils/introspection/IERC165.sol\";\n\n/**\n * @dev Required interface of an ERC721 compliant contract.\n */\ninterface IERC721 is IERC165 {\n /**\n * @dev Emitted when `tokenId` token is transferred from `from` to `to`.\n */\n event Transfer(address indexed from, address indexed to, uint256 indexed tokenId);\n\n /**\n * @dev Emitted when `owner` enables `approved` to manage the `tokenId` token.\n */\n event Approval(address indexed owner, address indexed approved, uint256 indexed tokenId);\n\n /**\n * @dev Emitted when `owner` enables or disables (`approved`) `operator` to manage all of its assets.\n */\n event ApprovalForAll(address indexed owner, address indexed operator, bool approved);\n\n /**\n * @dev Returns the number of tokens in ``owner``'s account.\n */\n function balanceOf(address owner) external view returns (uint256 balance);\n\n /**\n * @dev Returns the owner of the `tokenId` token.\n *\n * Requirements:\n *\n * - `tokenId` must exist.\n */\n function ownerOf(uint256 tokenId) external view returns (address owner);\n\n /**\n * @dev Safely transfers `tokenId` token from `from` to `to`.\n *\n * Requirements:\n *\n * - `from` cannot be the zero address.\n * - `to` cannot be the zero address.\n * - `tokenId` token must exist and be owned by `from`.\n * - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}.\n * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.\n *\n * Emits a {Transfer} event.\n */\n function safeTransferFrom(\n address from,\n address to,\n uint256 tokenId,\n bytes calldata data\n ) external;\n\n /**\n * @dev Safely transfers `tokenId` token from `from` to `to`, checking first that contract recipients\n * are aware of the ERC721 protocol to prevent tokens from being forever locked.\n *\n * Requirements:\n *\n * - `from` cannot be the zero address.\n * - `to` cannot be the zero address.\n * - `tokenId` token must exist and be owned by `from`.\n * - If the caller is not `from`, it must have been allowed to move this token by either {approve} or {setApprovalForAll}.\n * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.\n *\n * Emits a {Transfer} event.\n */\n function safeTransferFrom(\n address from,\n address to,\n uint256 tokenId\n ) external;\n\n /**\n * @dev Transfers `tokenId` token from `from` to `to`.\n *\n * WARNING: Usage of this method is discouraged, use {safeTransferFrom} whenever possible.\n *\n * Requirements:\n *\n * - `from` cannot be the zero address.\n * - `to` cannot be the zero address.\n * - `tokenId` token must be owned by `from`.\n * - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}.\n *\n * Emits a {Transfer} event.\n */\n function transferFrom(\n address from,\n address to,\n uint256 tokenId\n ) external;\n\n /**\n * @dev Gives permission to `to` to transfer `tokenId` token to another account.\n * The approval is cleared when the token is transferred.\n *\n * Only a single account can be approved at a time, so approving the zero address clears previous approvals.\n *\n * Requirements:\n *\n * - The caller must own the token or be an approved operator.\n * - `tokenId` must exist.\n *\n * Emits an {Approval} event.\n */\n function approve(address to, uint256 tokenId) external;\n\n /**\n * @dev Approve or remove `operator` as an operator for the caller.\n * Operators can call {transferFrom} or {safeTransferFrom} for any token owned by the caller.\n *\n * Requirements:\n *\n * - The `operator` cannot be the caller.\n *\n * Emits an {ApprovalForAll} event.\n */\n function setApprovalForAll(address operator, bool _approved) external;\n\n /**\n * @dev Returns the account approved for `tokenId` token.\n *\n * Requirements:\n *\n * - `tokenId` must exist.\n */\n function getApproved(uint256 tokenId) external view returns (address operator);\n\n /**\n * @dev Returns if the `operator` is allowed to manage all of the assets of `owner`.\n *\n * See {setApprovalForAll}\n */\n function isApprovedForAll(address owner, address operator) external view returns (bool);\n}\n" + }, + "@openzeppelin/contracts/utils/Address.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (utils/Address.sol)\n\npragma solidity ^0.8.1;\n\n/**\n * @dev Collection of functions related to the address type\n */\nlibrary Address {\n /**\n * @dev Returns true if `account` is a contract.\n *\n * [IMPORTANT]\n * ====\n * It is unsafe to assume that an address for which this function returns\n * false is an externally-owned account (EOA) and not a contract.\n *\n * Among others, `isContract` will return false for the following\n * types of addresses:\n *\n * - an externally-owned account\n * - a contract in construction\n * - an address where a contract will be created\n * - an address where a contract lived, but was destroyed\n * ====\n *\n * [IMPORTANT]\n * ====\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\n *\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\n * constructor.\n * ====\n */\n function isContract(address account) internal view returns (bool) {\n // This method relies on extcodesize/address.code.length, which returns 0\n // for contracts in construction, since the code is only stored at the end\n // of the constructor execution.\n\n return account.code.length > 0;\n }\n\n /**\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\n * `recipient`, forwarding all available gas and reverting on errors.\n *\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\n * imposed by `transfer`, making them unable to receive funds via\n * `transfer`. {sendValue} removes this limitation.\n *\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\n *\n * IMPORTANT: because control is transferred to `recipient`, care must be\n * taken to not create reentrancy vulnerabilities. Consider using\n * {ReentrancyGuard} or the\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\n */\n function sendValue(address payable recipient, uint256 amount) internal {\n require(address(this).balance >= amount, \"Address: insufficient balance\");\n\n (bool success, ) = recipient.call{value: amount}(\"\");\n require(success, \"Address: unable to send value, recipient may have reverted\");\n }\n\n /**\n * @dev Performs a Solidity function call using a low level `call`. A\n * plain `call` is an unsafe replacement for a function call: use this\n * function instead.\n *\n * If `target` reverts with a revert reason, it is bubbled up by this\n * function (like regular Solidity function calls).\n *\n * Returns the raw returned data. To convert to the expected return value,\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\n *\n * Requirements:\n *\n * - `target` must be a contract.\n * - calling `target` with `data` must not revert.\n *\n * _Available since v3.1._\n */\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionCall(target, data, \"Address: low-level call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\n * `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, 0, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but also transferring `value` wei to `target`.\n *\n * Requirements:\n *\n * - the calling contract must have an ETH balance of at least `value`.\n * - the called Solidity function must be `payable`.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, value, \"Address: low-level call with value failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\n * with `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(address(this).balance >= value, \"Address: insufficient balance for call\");\n require(isContract(target), \"Address: call to non-contract\");\n\n (bool success, bytes memory returndata) = target.call{value: value}(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\n return functionStaticCall(target, data, \"Address: low-level static call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal view returns (bytes memory) {\n require(isContract(target), \"Address: static call to non-contract\");\n\n (bool success, bytes memory returndata) = target.staticcall(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a delegate call.\n *\n * _Available since v3.4._\n */\n function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionDelegateCall(target, data, \"Address: low-level delegate call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a delegate call.\n *\n * _Available since v3.4._\n */\n function functionDelegateCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(isContract(target), \"Address: delegate call to non-contract\");\n\n (bool success, bytes memory returndata) = target.delegatecall(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the\n * revert reason using the provided one.\n *\n * _Available since v4.3._\n */\n function verifyCallResult(\n bool success,\n bytes memory returndata,\n string memory errorMessage\n ) internal pure returns (bytes memory) {\n if (success) {\n return returndata;\n } else {\n // Look for revert reason and bubble it up if present\n if (returndata.length > 0) {\n // The easiest way to bubble the revert reason is using memory via assembly\n /// @solidity memory-safe-assembly\n assembly {\n let returndata_size := mload(returndata)\n revert(add(32, returndata), returndata_size)\n }\n } else {\n revert(errorMessage);\n }\n }\n }\n}\n" + }, + "@openzeppelin/contracts/utils/Context.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Provides information about the current execution context, including the\n * sender of the transaction and its data. While these are generally available\n * via msg.sender and msg.data, they should not be accessed in such a direct\n * manner, since when dealing with meta-transactions the account sending and\n * paying for execution may not be the actual sender (as far as an application\n * is concerned).\n *\n * This contract is only required for intermediate, library-like contracts.\n */\nabstract contract Context {\n function _msgSender() internal view virtual returns (address) {\n return msg.sender;\n }\n\n function _msgData() internal view virtual returns (bytes calldata) {\n return msg.data;\n }\n}\n" + }, + "@openzeppelin/contracts/utils/Counters.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (utils/Counters.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @title Counters\n * @author Matt Condon (@shrugs)\n * @dev Provides counters that can only be incremented, decremented or reset. This can be used e.g. to track the number\n * of elements in a mapping, issuing ERC721 ids, or counting request ids.\n *\n * Include with `using Counters for Counters.Counter;`\n */\nlibrary Counters {\n struct Counter {\n // This variable should never be directly accessed by users of the library: interactions must be restricted to\n // the library's function. As of Solidity v0.5.2, this cannot be enforced, though there is a proposal to add\n // this feature: see https://github.com/ethereum/solidity/issues/4637\n uint256 _value; // default: 0\n }\n\n function current(Counter storage counter) internal view returns (uint256) {\n return counter._value;\n }\n\n function increment(Counter storage counter) internal {\n unchecked {\n counter._value += 1;\n }\n }\n\n function decrement(Counter storage counter) internal {\n uint256 value = counter._value;\n require(value > 0, \"Counter: decrement overflow\");\n unchecked {\n counter._value = value - 1;\n }\n }\n\n function reset(Counter storage counter) internal {\n counter._value = 0;\n }\n}\n" + }, + "@openzeppelin/contracts/utils/cryptography/draft-EIP712.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (utils/cryptography/draft-EIP712.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./ECDSA.sol\";\n\n/**\n * @dev https://eips.ethereum.org/EIPS/eip-712[EIP 712] is a standard for hashing and signing of typed structured data.\n *\n * The encoding specified in the EIP is very generic, and such a generic implementation in Solidity is not feasible,\n * thus this contract does not implement the encoding itself. Protocols need to implement the type-specific encoding\n * they need in their contracts using a combination of `abi.encode` and `keccak256`.\n *\n * This contract implements the EIP 712 domain separator ({_domainSeparatorV4}) that is used as part of the encoding\n * scheme, and the final step of the encoding to obtain the message digest that is then signed via ECDSA\n * ({_hashTypedDataV4}).\n *\n * The implementation of the domain separator was designed to be as efficient as possible while still properly updating\n * the chain id to protect against replay attacks on an eventual fork of the chain.\n *\n * NOTE: This contract implements the version of the encoding known as \"v4\", as implemented by the JSON RPC method\n * https://docs.metamask.io/guide/signing-data.html[`eth_signTypedDataV4` in MetaMask].\n *\n * _Available since v3.4._\n */\nabstract contract EIP712 {\n /* solhint-disable var-name-mixedcase */\n // Cache the domain separator as an immutable value, but also store the chain id that it corresponds to, in order to\n // invalidate the cached domain separator if the chain id changes.\n bytes32 private immutable _CACHED_DOMAIN_SEPARATOR;\n uint256 private immutable _CACHED_CHAIN_ID;\n address private immutable _CACHED_THIS;\n\n bytes32 private immutable _HASHED_NAME;\n bytes32 private immutable _HASHED_VERSION;\n bytes32 private immutable _TYPE_HASH;\n\n /* solhint-enable var-name-mixedcase */\n\n /**\n * @dev Initializes the domain separator and parameter caches.\n *\n * The meaning of `name` and `version` is specified in\n * https://eips.ethereum.org/EIPS/eip-712#definition-of-domainseparator[EIP 712]:\n *\n * - `name`: the user readable name of the signing domain, i.e. the name of the DApp or the protocol.\n * - `version`: the current major version of the signing domain.\n *\n * NOTE: These parameters cannot be changed except through a xref:learn::upgrading-smart-contracts.adoc[smart\n * contract upgrade].\n */\n constructor(string memory name, string memory version) {\n bytes32 hashedName = keccak256(bytes(name));\n bytes32 hashedVersion = keccak256(bytes(version));\n bytes32 typeHash = keccak256(\n \"EIP712Domain(string name,string version,uint256 chainId,address verifyingContract)\"\n );\n _HASHED_NAME = hashedName;\n _HASHED_VERSION = hashedVersion;\n _CACHED_CHAIN_ID = block.chainid;\n _CACHED_DOMAIN_SEPARATOR = _buildDomainSeparator(typeHash, hashedName, hashedVersion);\n _CACHED_THIS = address(this);\n _TYPE_HASH = typeHash;\n }\n\n /**\n * @dev Returns the domain separator for the current chain.\n */\n function _domainSeparatorV4() internal view returns (bytes32) {\n if (address(this) == _CACHED_THIS && block.chainid == _CACHED_CHAIN_ID) {\n return _CACHED_DOMAIN_SEPARATOR;\n } else {\n return _buildDomainSeparator(_TYPE_HASH, _HASHED_NAME, _HASHED_VERSION);\n }\n }\n\n function _buildDomainSeparator(\n bytes32 typeHash,\n bytes32 nameHash,\n bytes32 versionHash\n ) private view returns (bytes32) {\n return keccak256(abi.encode(typeHash, nameHash, versionHash, block.chainid, address(this)));\n }\n\n /**\n * @dev Given an already https://eips.ethereum.org/EIPS/eip-712#definition-of-hashstruct[hashed struct], this\n * function returns the hash of the fully encoded EIP712 message for this domain.\n *\n * This hash can be used together with {ECDSA-recover} to obtain the signer of a message. For example:\n *\n * ```solidity\n * bytes32 digest = _hashTypedDataV4(keccak256(abi.encode(\n * keccak256(\"Mail(address to,string contents)\"),\n * mailTo,\n * keccak256(bytes(mailContents))\n * )));\n * address signer = ECDSA.recover(digest, signature);\n * ```\n */\n function _hashTypedDataV4(bytes32 structHash) internal view virtual returns (bytes32) {\n return ECDSA.toTypedDataHash(_domainSeparatorV4(), structHash);\n }\n}\n" + }, + "@openzeppelin/contracts/utils/cryptography/ECDSA.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (utils/cryptography/ECDSA.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../Strings.sol\";\n\n/**\n * @dev Elliptic Curve Digital Signature Algorithm (ECDSA) operations.\n *\n * These functions can be used to verify that a message was signed by the holder\n * of the private keys of a given address.\n */\nlibrary ECDSA {\n enum RecoverError {\n NoError,\n InvalidSignature,\n InvalidSignatureLength,\n InvalidSignatureS,\n InvalidSignatureV\n }\n\n function _throwError(RecoverError error) private pure {\n if (error == RecoverError.NoError) {\n return; // no error: do nothing\n } else if (error == RecoverError.InvalidSignature) {\n revert(\"ECDSA: invalid signature\");\n } else if (error == RecoverError.InvalidSignatureLength) {\n revert(\"ECDSA: invalid signature length\");\n } else if (error == RecoverError.InvalidSignatureS) {\n revert(\"ECDSA: invalid signature 's' value\");\n } else if (error == RecoverError.InvalidSignatureV) {\n revert(\"ECDSA: invalid signature 'v' value\");\n }\n }\n\n /**\n * @dev Returns the address that signed a hashed message (`hash`) with\n * `signature` or error string. This address can then be used for verification purposes.\n *\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\n * this function rejects them by requiring the `s` value to be in the lower\n * half order, and the `v` value to be either 27 or 28.\n *\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\n * verification to be secure: it is possible to craft signatures that\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\n * this is by receiving a hash of the original message (which may otherwise\n * be too long), and then calling {toEthSignedMessageHash} on it.\n *\n * Documentation for signature generation:\n * - with https://web3js.readthedocs.io/en/v1.3.4/web3-eth-accounts.html#sign[Web3.js]\n * - with https://docs.ethers.io/v5/api/signer/#Signer-signMessage[ethers]\n *\n * _Available since v4.3._\n */\n function tryRecover(bytes32 hash, bytes memory signature) internal pure returns (address, RecoverError) {\n // Check the signature length\n // - case 65: r,s,v signature (standard)\n // - case 64: r,vs signature (cf https://eips.ethereum.org/EIPS/eip-2098) _Available since v4.1._\n if (signature.length == 65) {\n bytes32 r;\n bytes32 s;\n uint8 v;\n // ecrecover takes the signature parameters, and the only way to get them\n // currently is to use assembly.\n /// @solidity memory-safe-assembly\n assembly {\n r := mload(add(signature, 0x20))\n s := mload(add(signature, 0x40))\n v := byte(0, mload(add(signature, 0x60)))\n }\n return tryRecover(hash, v, r, s);\n } else if (signature.length == 64) {\n bytes32 r;\n bytes32 vs;\n // ecrecover takes the signature parameters, and the only way to get them\n // currently is to use assembly.\n /// @solidity memory-safe-assembly\n assembly {\n r := mload(add(signature, 0x20))\n vs := mload(add(signature, 0x40))\n }\n return tryRecover(hash, r, vs);\n } else {\n return (address(0), RecoverError.InvalidSignatureLength);\n }\n }\n\n /**\n * @dev Returns the address that signed a hashed message (`hash`) with\n * `signature`. This address can then be used for verification purposes.\n *\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\n * this function rejects them by requiring the `s` value to be in the lower\n * half order, and the `v` value to be either 27 or 28.\n *\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\n * verification to be secure: it is possible to craft signatures that\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\n * this is by receiving a hash of the original message (which may otherwise\n * be too long), and then calling {toEthSignedMessageHash} on it.\n */\n function recover(bytes32 hash, bytes memory signature) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, signature);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Overload of {ECDSA-tryRecover} that receives the `r` and `vs` short-signature fields separately.\n *\n * See https://eips.ethereum.org/EIPS/eip-2098[EIP-2098 short signatures]\n *\n * _Available since v4.3._\n */\n function tryRecover(\n bytes32 hash,\n bytes32 r,\n bytes32 vs\n ) internal pure returns (address, RecoverError) {\n bytes32 s = vs & bytes32(0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff);\n uint8 v = uint8((uint256(vs) >> 255) + 27);\n return tryRecover(hash, v, r, s);\n }\n\n /**\n * @dev Overload of {ECDSA-recover} that receives the `r and `vs` short-signature fields separately.\n *\n * _Available since v4.2._\n */\n function recover(\n bytes32 hash,\n bytes32 r,\n bytes32 vs\n ) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, r, vs);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Overload of {ECDSA-tryRecover} that receives the `v`,\n * `r` and `s` signature fields separately.\n *\n * _Available since v4.3._\n */\n function tryRecover(\n bytes32 hash,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) internal pure returns (address, RecoverError) {\n // EIP-2 still allows signature malleability for ecrecover(). Remove this possibility and make the signature\n // unique. Appendix F in the Ethereum Yellow paper (https://ethereum.github.io/yellowpaper/paper.pdf), defines\n // the valid range for s in (301): 0 < s < secp256k1n ÷ 2 + 1, and for v in (302): v ∈ {27, 28}. Most\n // signatures from current libraries generate a unique signature with an s-value in the lower half order.\n //\n // If your library generates malleable signatures, such as s-values in the upper range, calculate a new s-value\n // with 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141 - s1 and flip v from 27 to 28 or\n // vice versa. If your library also generates signatures with 0/1 for v instead 27/28, add 27 to v to accept\n // these malleable signatures as well.\n if (uint256(s) > 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D576E7357A4501DDFE92F46681B20A0) {\n return (address(0), RecoverError.InvalidSignatureS);\n }\n if (v != 27 && v != 28) {\n return (address(0), RecoverError.InvalidSignatureV);\n }\n\n // If the signature is valid (and not malleable), return the signer address\n address signer = ecrecover(hash, v, r, s);\n if (signer == address(0)) {\n return (address(0), RecoverError.InvalidSignature);\n }\n\n return (signer, RecoverError.NoError);\n }\n\n /**\n * @dev Overload of {ECDSA-recover} that receives the `v`,\n * `r` and `s` signature fields separately.\n */\n function recover(\n bytes32 hash,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, v, r, s);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Returns an Ethereum Signed Message, created from a `hash`. This\n * produces hash corresponding to the one signed with the\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\n * JSON-RPC method as part of EIP-191.\n *\n * See {recover}.\n */\n function toEthSignedMessageHash(bytes32 hash) internal pure returns (bytes32) {\n // 32 is the length in bytes of hash,\n // enforced by the type signature above\n return keccak256(abi.encodePacked(\"\\x19Ethereum Signed Message:\\n32\", hash));\n }\n\n /**\n * @dev Returns an Ethereum Signed Message, created from `s`. This\n * produces hash corresponding to the one signed with the\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\n * JSON-RPC method as part of EIP-191.\n *\n * See {recover}.\n */\n function toEthSignedMessageHash(bytes memory s) internal pure returns (bytes32) {\n return keccak256(abi.encodePacked(\"\\x19Ethereum Signed Message:\\n\", Strings.toString(s.length), s));\n }\n\n /**\n * @dev Returns an Ethereum Signed Typed Data, created from a\n * `domainSeparator` and a `structHash`. This produces hash corresponding\n * to the one signed with the\n * https://eips.ethereum.org/EIPS/eip-712[`eth_signTypedData`]\n * JSON-RPC method as part of EIP-712.\n *\n * See {recover}.\n */\n function toTypedDataHash(bytes32 domainSeparator, bytes32 structHash) internal pure returns (bytes32) {\n return keccak256(abi.encodePacked(\"\\x19\\x01\", domainSeparator, structHash));\n }\n}\n" + }, + "@openzeppelin/contracts/utils/introspection/IERC165.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (utils/introspection/IERC165.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Interface of the ERC165 standard, as defined in the\n * https://eips.ethereum.org/EIPS/eip-165[EIP].\n *\n * Implementers can declare support of contract interfaces, which can then be\n * queried by others ({ERC165Checker}).\n *\n * For an implementation, see {ERC165}.\n */\ninterface IERC165 {\n /**\n * @dev Returns true if this contract implements the interface defined by\n * `interfaceId`. See the corresponding\n * https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified[EIP section]\n * to learn more about how these ids are created.\n *\n * This function call must use less than 30 000 gas.\n */\n function supportsInterface(bytes4 interfaceId) external view returns (bool);\n}\n" + }, + "@openzeppelin/contracts/utils/StorageSlot.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (utils/StorageSlot.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Library for reading and writing primitive types to specific storage slots.\n *\n * Storage slots are often used to avoid storage conflict when dealing with upgradeable contracts.\n * This library helps with reading and writing to such slots without the need for inline assembly.\n *\n * The functions in this library return Slot structs that contain a `value` member that can be used to read or write.\n *\n * Example usage to set ERC1967 implementation slot:\n * ```\n * contract ERC1967 {\n * bytes32 internal constant _IMPLEMENTATION_SLOT = 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc;\n *\n * function _getImplementation() internal view returns (address) {\n * return StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value;\n * }\n *\n * function _setImplementation(address newImplementation) internal {\n * require(Address.isContract(newImplementation), \"ERC1967: new implementation is not a contract\");\n * StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value = newImplementation;\n * }\n * }\n * ```\n *\n * _Available since v4.1 for `address`, `bool`, `bytes32`, and `uint256`._\n */\nlibrary StorageSlot {\n struct AddressSlot {\n address value;\n }\n\n struct BooleanSlot {\n bool value;\n }\n\n struct Bytes32Slot {\n bytes32 value;\n }\n\n struct Uint256Slot {\n uint256 value;\n }\n\n /**\n * @dev Returns an `AddressSlot` with member `value` located at `slot`.\n */\n function getAddressSlot(bytes32 slot) internal pure returns (AddressSlot storage r) {\n /// @solidity memory-safe-assembly\n assembly {\n r.slot := slot\n }\n }\n\n /**\n * @dev Returns an `BooleanSlot` with member `value` located at `slot`.\n */\n function getBooleanSlot(bytes32 slot) internal pure returns (BooleanSlot storage r) {\n /// @solidity memory-safe-assembly\n assembly {\n r.slot := slot\n }\n }\n\n /**\n * @dev Returns an `Bytes32Slot` with member `value` located at `slot`.\n */\n function getBytes32Slot(bytes32 slot) internal pure returns (Bytes32Slot storage r) {\n /// @solidity memory-safe-assembly\n assembly {\n r.slot := slot\n }\n }\n\n /**\n * @dev Returns an `Uint256Slot` with member `value` located at `slot`.\n */\n function getUint256Slot(bytes32 slot) internal pure returns (Uint256Slot storage r) {\n /// @solidity memory-safe-assembly\n assembly {\n r.slot := slot\n }\n }\n}\n" + }, + "@openzeppelin/contracts/utils/Strings.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (utils/Strings.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev String operations.\n */\nlibrary Strings {\n bytes16 private constant _HEX_SYMBOLS = \"0123456789abcdef\";\n uint8 private constant _ADDRESS_LENGTH = 20;\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` decimal representation.\n */\n function toString(uint256 value) internal pure returns (string memory) {\n // Inspired by OraclizeAPI's implementation - MIT licence\n // https://github.com/oraclize/ethereum-api/blob/b42146b063c7d6ee1358846c198246239e9360e8/oraclizeAPI_0.4.25.sol\n\n if (value == 0) {\n return \"0\";\n }\n uint256 temp = value;\n uint256 digits;\n while (temp != 0) {\n digits++;\n temp /= 10;\n }\n bytes memory buffer = new bytes(digits);\n while (value != 0) {\n digits -= 1;\n buffer[digits] = bytes1(uint8(48 + uint256(value % 10)));\n value /= 10;\n }\n return string(buffer);\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation.\n */\n function toHexString(uint256 value) internal pure returns (string memory) {\n if (value == 0) {\n return \"0x00\";\n }\n uint256 temp = value;\n uint256 length = 0;\n while (temp != 0) {\n length++;\n temp >>= 8;\n }\n return toHexString(value, length);\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length.\n */\n function toHexString(uint256 value, uint256 length) internal pure returns (string memory) {\n bytes memory buffer = new bytes(2 * length + 2);\n buffer[0] = \"0\";\n buffer[1] = \"x\";\n for (uint256 i = 2 * length + 1; i > 1; --i) {\n buffer[i] = _HEX_SYMBOLS[value & 0xf];\n value >>= 4;\n }\n require(value == 0, \"Strings: hex length insufficient\");\n return string(buffer);\n }\n\n /**\n * @dev Converts an `address` with fixed length of 20 bytes to its not checksummed ASCII `string` hexadecimal representation.\n */\n function toHexString(address addr) internal pure returns (string memory) {\n return toHexString(uint256(uint160(addr)), _ADDRESS_LENGTH);\n }\n}\n" + }, + "contracts/agToken/AgEUR.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\nimport \"../interfaces/IAgToken.sol\";\nimport \"../interfaces/coreModule/IStableMaster.sol\";\nimport \"../interfaces/ITreasury.sol\";\nimport \"@openzeppelin/contracts-upgradeable/token/ERC20/extensions/draft-ERC20PermitUpgradeable.sol\";\n\n/// @title AgEUR\n/// @author Angle Labs, Inc.\n/// @notice Base contract for agEUR, Angle's Euro stablecoin\n/// @dev This contract is an upgraded version of the agEUR contract that was first deployed on Ethereum mainnet\ncontract AgEUR is IAgToken, ERC20PermitUpgradeable {\n // ================================= REFERENCES ================================\n\n /// @notice Reference to the `StableMaster` contract associated to agEUR\n address public stableMaster;\n\n /// @custom:oz-upgrades-unsafe-allow constructor\n constructor() initializer {}\n\n // ============================== ADDED PARAMETERS =============================\n\n /// @inheritdoc IAgToken\n mapping(address => bool) public isMinter;\n /// @notice Reference to the treasury contract which can grant minting rights\n address public treasury;\n /// @notice Boolean used to check whether the contract had been reinitialized after an upgrade\n bool public treasuryInitialized;\n\n // =================================== EVENTS ==================================\n\n event TreasuryUpdated(address indexed _treasury);\n event MinterToggled(address indexed minter);\n\n // =================================== ERRORS ==================================\n\n error BurnAmountExceedsAllowance();\n error InvalidSender();\n error InvalidTreasury();\n error NotGovernor();\n error NotMinter();\n error NotTreasury();\n error TreasuryAlreadyInitialized();\n\n // ================================= MODIFIERS =================================\n\n /// @notice Checks to see if it is the `Treasury` calling this contract\n modifier onlyTreasury() {\n if (msg.sender != treasury) revert NotTreasury();\n _;\n }\n\n /// @notice Checks whether the sender has the minting right\n modifier onlyMinter() {\n if (!isMinter[msg.sender]) revert NotMinter();\n _;\n }\n\n // ============================= EXTERNAL FUNCTION =============================\n\n /// @notice Allows anyone to burn stablecoins\n /// @param amount Amount of stablecoins to burn\n /// @dev This function can typically be called if there is a settlement mechanism to burn stablecoins\n function burnStablecoin(uint256 amount) external {\n _burn(msg.sender, amount);\n }\n\n // ========================= MINTER ROLE ONLY FUNCTIONS ========================\n\n /// @inheritdoc IAgToken\n function burnSelf(uint256 amount, address burner) external onlyMinter {\n _burn(burner, amount);\n }\n\n /// @inheritdoc IAgToken\n function burnFrom(uint256 amount, address burner, address sender) external onlyMinter {\n if (burner != sender) {\n uint256 currentAllowance = allowance(burner, sender);\n if (currentAllowance < amount) revert BurnAmountExceedsAllowance();\n _approve(burner, sender, currentAllowance - amount);\n }\n _burn(burner, amount);\n }\n\n /// @inheritdoc IAgToken\n function mint(address account, uint256 amount) external onlyMinter {\n _mint(account, amount);\n }\n\n // ========================== TREASURY ONLY FUNCTIONS ==========================\n\n /// @inheritdoc IAgToken\n function addMinter(address minter) external onlyTreasury {\n isMinter[minter] = true;\n emit MinterToggled(minter);\n }\n\n /// @inheritdoc IAgToken\n function removeMinter(address minter) external {\n if (msg.sender != minter && msg.sender != address(treasury)) revert InvalidSender();\n isMinter[minter] = false;\n emit MinterToggled(minter);\n }\n\n /// @inheritdoc IAgToken\n function setTreasury(address _treasury) external onlyTreasury {\n treasury = _treasury;\n emit TreasuryUpdated(_treasury);\n }\n}\n" + }, + "contracts/agToken/AgToken.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\n/*\n * █ \n ***** ▓▓▓ \n * ▓▓▓▓▓▓▓ \n * ///. ▓▓▓▓▓▓▓▓▓▓▓▓▓ \n ***** //////// ▓▓▓▓▓▓▓ \n * ///////////// ▓▓▓ \n ▓▓ ////////////////// █ ▓▓ \n ▓▓ ▓▓ /////////////////////// ▓▓ ▓▓ \n ▓▓ ▓▓ //////////////////////////// ▓▓ ▓▓ \n ▓▓ ▓▓ /////////▓▓▓///////▓▓▓///////// ▓▓ ▓▓ \n ▓▓ ,////////////////////////////////////// ▓▓ ▓▓ \n ▓▓ ////////////////////////////////////////// ▓▓ \n ▓▓ //////////////////////▓▓▓▓///////////////////// \n ,//////////////////////////////////////////////////// \n .////////////////////////////////////////////////////////// \n .//////////////////////////██.,//////////////////////////█ \n .//////////////////////████..,./////////////////////██ \n ...////////////////███████.....,.////////////////███ \n ,.,////////////████████ ........,///////////████ \n .,.,//////█████████ ,.......///////████ \n ,..//████████ ........./████ \n ..,██████ .....,███ \n .██ ,.,█ \n \n \n \n ▓▓ ▓▓▓▓▓▓▓▓▓▓ ▓▓▓▓▓▓▓▓▓▓ ▓▓ ▓▓▓▓▓▓▓▓▓▓ \n ▓▓▓▓▓▓ ▓▓▓ ▓▓▓ ▓▓▓ ▓▓ ▓▓ ▓▓▓▓ \n ▓▓▓ ▓▓▓ ▓▓▓ ▓▓▓ ▓▓▓ ▓▓▓ ▓▓ ▓▓▓▓▓ \n ▓▓▓ ▓▓ ▓▓▓ ▓▓▓ ▓▓▓▓▓▓▓▓▓▓ ▓▓▓▓▓▓▓▓▓▓ ▓▓▓▓▓▓▓▓▓▓ \n*/\n\nimport \"../interfaces/IAgToken.sol\";\nimport \"../interfaces/ITreasury.sol\";\nimport \"@openzeppelin/contracts-upgradeable/token/ERC20/extensions/draft-ERC20PermitUpgradeable.sol\";\n\n/// @title AgToken\n/// @author Angle Labs, Inc.\n/// @notice Base contract for Angle agTokens on Ethereum and on other chains\n/// @dev By default, agTokens are ERC-20 tokens with 18 decimals\ncontract AgToken is IAgToken, ERC20PermitUpgradeable {\n // =========================== PARAMETERS / VARIABLES ==========================\n\n /// @inheritdoc IAgToken\n mapping(address => bool) public isMinter;\n /// @notice Reference to the treasury contract which can grant minting rights\n address public treasury;\n\n // =================================== EVENTS ==================================\n\n event TreasuryUpdated(address indexed _treasury);\n event MinterToggled(address indexed minter);\n\n // =================================== ERRORS ==================================\n\n error BurnAmountExceedsAllowance();\n error InvalidSender();\n error InvalidTreasury();\n error NotMinter();\n error NotTreasury();\n\n // ================================ CONSTRUCTOR ================================\n\n /// @custom:oz-upgrades-unsafe-allow constructor\n constructor() initializer {}\n\n /// @notice Initializes the `AgToken` contract\n function initialize(string memory name_, string memory symbol_, address _treasury) external {\n _initialize(name_, symbol_, _treasury);\n }\n\n /// @notice Initializes the contract\n function _initialize(string memory name_, string memory symbol_, address _treasury) internal virtual initializer {\n if (address(ITreasury(_treasury).stablecoin()) != address(this)) revert InvalidTreasury();\n __ERC20Permit_init(name_);\n __ERC20_init(name_, symbol_);\n treasury = _treasury;\n emit TreasuryUpdated(_treasury);\n }\n\n // ================================= MODIFIERS =================================\n\n /// @notice Checks to see if it is the `Treasury` calling this contract\n modifier onlyTreasury() {\n if (msg.sender != treasury) revert NotTreasury();\n _;\n }\n\n /// @notice Checks whether the sender has the minting right\n modifier onlyMinter() {\n if (!isMinter[msg.sender]) revert NotMinter();\n _;\n }\n\n // ============================= EXTERNAL FUNCTION =============================\n\n /// @notice Allows anyone to burn stablecoins\n /// @param amount Amount of stablecoins to burn\n /// @dev This function can typically be called if there is a settlement mechanism to burn stablecoins\n function burnStablecoin(uint256 amount) external {\n _burn(msg.sender, amount);\n }\n\n // ========================= MINTER ROLE ONLY FUNCTIONS ========================\n\n /// @inheritdoc IAgToken\n function burnSelf(uint256 amount, address burner) external onlyMinter {\n _burn(burner, amount);\n }\n\n /// @inheritdoc IAgToken\n function burnFrom(uint256 amount, address burner, address sender) external onlyMinter {\n if (burner != sender) {\n uint256 currentAllowance = allowance(burner, sender);\n if (currentAllowance < amount) revert BurnAmountExceedsAllowance();\n _approve(burner, sender, currentAllowance - amount);\n }\n _burn(burner, amount);\n }\n\n /// @inheritdoc IAgToken\n function mint(address account, uint256 amount) external onlyMinter {\n _mint(account, amount);\n }\n\n // ========================== GOVERNANCE ONLY FUNCTIONS ==========================\n\n /// @inheritdoc IAgToken\n function addMinter(address minter) external onlyTreasury {\n isMinter[minter] = true;\n emit MinterToggled(minter);\n }\n\n /// @inheritdoc IAgToken\n function removeMinter(address minter) external {\n if (msg.sender != address(treasury) && msg.sender != minter) revert InvalidSender();\n isMinter[minter] = false;\n emit MinterToggled(minter);\n }\n\n /// @inheritdoc IAgToken\n function setTreasury(address _treasury) external virtual onlyTreasury {\n treasury = _treasury;\n emit TreasuryUpdated(_treasury);\n }\n}\n" + }, + "contracts/agToken/AgTokenSideChainMultiBridge.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\nimport \"./AgToken.sol\";\nimport \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\nimport \"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\";\n\n/// @title AgTokenSideChainMultiBridge\n/// @author Angle Labs, Inc.\n/// @notice Contract for Angle agTokens on other chains than Ethereum mainnet\n/// @dev This contract supports bridge tokens having a minting right on the stablecoin (also referred to as the canonical\n/// or the native token)\ncontract AgTokenSideChainMultiBridge is AgToken {\n using SafeERC20 for IERC20;\n\n /// @notice Base used for fee computation\n uint256 public constant BASE_PARAMS = 1e9;\n\n // =============================== BRIDGING DATA ===============================\n\n /// @notice Struct with some data about a specific bridge token\n struct BridgeDetails {\n // Limit on the balance of bridge token held by the contract: it is designed\n // to reduce the exposure of the system to hacks\n uint256 limit;\n // Limit on the hourly volume of token minted through this bridge\n // Technically the limit over a rolling hour is hourlyLimit x2 as hourly limit\n // is enforced only between x:00 and x+1:00\n uint256 hourlyLimit;\n // Fee taken for swapping in and out the token\n uint64 fee;\n // Whether the associated token is allowed or not\n bool allowed;\n // Whether swapping in and out from the associated token is paused or not\n bool paused;\n }\n\n /// @notice Maps a bridge token to data\n mapping(address => BridgeDetails) public bridges;\n /// @notice List of all bridge tokens\n address[] public bridgeTokensList;\n /// @notice Maps a bridge token to the associated hourly volume\n mapping(address => mapping(uint256 => uint256)) public usage;\n /// @notice Maps an address to whether it is exempt of fees for when it comes to swapping in and out\n mapping(address => uint256) public isFeeExempt;\n /// @notice Limit to the amount of tokens that can be sent from that chain to another chain\n uint256 public chainTotalHourlyLimit;\n /// @notice Usage per hour on that chain. Maps an hourly timestamp to the total volume swapped out on the chain\n mapping(uint256 => uint256) public chainTotalUsage;\n\n // =================================== EVENTS ==================================\n\n event BridgeTokenAdded(address indexed bridgeToken, uint256 limit, uint256 hourlyLimit, uint64 fee, bool paused);\n event BridgeTokenToggled(address indexed bridgeToken, bool toggleStatus);\n event BridgeTokenRemoved(address indexed bridgeToken);\n event BridgeTokenFeeUpdated(address indexed bridgeToken, uint64 fee);\n event BridgeTokenLimitUpdated(address indexed bridgeToken, uint256 limit);\n event BridgeTokenHourlyLimitUpdated(address indexed bridgeToken, uint256 hourlyLimit);\n event HourlyLimitUpdated(uint256 hourlyLimit);\n event Recovered(address indexed token, address indexed to, uint256 amount);\n event FeeToggled(address indexed theAddress, uint256 toggleStatus);\n\n // =================================== ERRORS ==================================\n\n error AssetStillControlledInReserves();\n error HourlyLimitExceeded();\n error InvalidToken();\n error NotGovernor();\n error NotGovernorOrGuardian();\n error TooBigAmount();\n error TooHighParameterValue();\n error ZeroAddress();\n\n // ================================= MODIFIERS =================================\n\n /// @notice Checks whether the `msg.sender` has the governor role or not\n modifier onlyGovernor() {\n if (!ITreasury(treasury).isGovernor(msg.sender)) revert NotGovernor();\n _;\n }\n\n /// @notice Checks whether the `msg.sender` has the governor role or the guardian role\n modifier onlyGovernorOrGuardian() {\n if (!ITreasury(treasury).isGovernorOrGuardian(msg.sender)) revert NotGovernorOrGuardian();\n _;\n }\n\n // ===================== EXTERNAL PERMISSIONLESS FUNCTIONS =====================\n\n /// @notice Returns the list of all supported bridge tokens\n /// @dev Helpful for UIs\n function allBridgeTokens() external view returns (address[] memory) {\n return bridgeTokensList;\n }\n\n /// @notice Returns the current volume for a bridge, for the current hour\n /// @param bridgeToken Bridge used to mint\n /// @dev Helpful for UIs\n function currentUsage(address bridgeToken) external view returns (uint256) {\n return usage[bridgeToken][block.timestamp / 3600];\n }\n\n /// @notice Returns the current total volume on the chain for the current hour\n /// @dev Helpful for UIs\n function currentTotalUsage() external view returns (uint256) {\n return chainTotalUsage[block.timestamp / 3600];\n }\n\n /// @notice Mints the canonical token from a supported bridge token\n /// @param bridgeToken Bridge token to use to mint\n /// @param amount Amount of bridge tokens to send\n /// @param to Address to which the stablecoin should be sent\n /// @return Amount of the canonical stablecoin actually minted\n /// @dev Some fees may be taken by the protocol depending on the token used and on the address calling\n function swapIn(address bridgeToken, uint256 amount, address to) external returns (uint256) {\n BridgeDetails memory bridgeDetails = bridges[bridgeToken];\n if (!bridgeDetails.allowed || bridgeDetails.paused) revert InvalidToken();\n uint256 balance = IERC20(bridgeToken).balanceOf(address(this));\n if (balance + amount > bridgeDetails.limit) {\n // In case someone maliciously sends tokens to this contract\n // Or the limit changes\n if (bridgeDetails.limit > balance) amount = bridgeDetails.limit - balance;\n else {\n amount = 0;\n }\n }\n\n // Checking requirement on the hourly volume\n uint256 hour = block.timestamp / 3600;\n uint256 hourlyUsage = usage[bridgeToken][hour];\n if (hourlyUsage + amount > bridgeDetails.hourlyLimit) {\n // Edge case when the hourly limit changes\n amount = bridgeDetails.hourlyLimit > hourlyUsage ? bridgeDetails.hourlyLimit - hourlyUsage : 0;\n }\n usage[bridgeToken][hour] = hourlyUsage + amount;\n\n IERC20(bridgeToken).safeTransferFrom(msg.sender, address(this), amount);\n uint256 canonicalOut = amount;\n // Computing fees\n if (isFeeExempt[msg.sender] == 0) {\n canonicalOut -= (canonicalOut * bridgeDetails.fee) / BASE_PARAMS;\n }\n _mint(to, canonicalOut);\n return canonicalOut;\n }\n\n /// @notice Burns the canonical token in exchange for a bridge token\n /// @param bridgeToken Bridge token required\n /// @param amount Amount of canonical tokens to burn\n /// @param to Address to which the bridge token should be sent\n /// @return Amount of bridge tokens actually sent back\n /// @dev Some fees may be taken by the protocol depending on the token used and on the address calling\n function swapOut(address bridgeToken, uint256 amount, address to) external returns (uint256) {\n BridgeDetails memory bridgeDetails = bridges[bridgeToken];\n if (!bridgeDetails.allowed || bridgeDetails.paused) revert InvalidToken();\n\n uint256 hour = block.timestamp / 3600;\n uint256 hourlyUsage = chainTotalUsage[hour] + amount;\n // If the amount being swapped out exceeds the limit, we revert\n // We don't want to change the amount being swapped out.\n // The user can decide to send another tx with the correct amount to reach the limit\n if (hourlyUsage > chainTotalHourlyLimit) revert HourlyLimitExceeded();\n chainTotalUsage[hour] = hourlyUsage;\n\n _burn(msg.sender, amount);\n uint256 bridgeOut = amount;\n if (isFeeExempt[msg.sender] == 0) {\n bridgeOut -= (bridgeOut * bridgeDetails.fee) / BASE_PARAMS;\n }\n IERC20(bridgeToken).safeTransfer(to, bridgeOut);\n return bridgeOut;\n }\n\n // ============================ GOVERNANCE FUNCTIONS ===========================\n\n /// @notice Adds support for a bridge token\n /// @param bridgeToken Bridge token to add: it should be a version of the stablecoin from another bridge\n /// @param limit Limit on the balance of bridge token this contract could hold\n /// @param hourlyLimit Limit on the hourly volume for this bridge\n /// @param paused Whether swapping for this token should be paused or not\n /// @param fee Fee taken upon swapping for or against this token\n function addBridgeToken(\n address bridgeToken,\n uint256 limit,\n uint256 hourlyLimit,\n uint64 fee,\n bool paused\n ) external onlyGovernor {\n if (bridges[bridgeToken].allowed || bridgeToken == address(0)) revert InvalidToken();\n if (fee > BASE_PARAMS) revert TooHighParameterValue();\n BridgeDetails memory _bridge;\n _bridge.limit = limit;\n _bridge.hourlyLimit = hourlyLimit;\n _bridge.paused = paused;\n _bridge.fee = fee;\n _bridge.allowed = true;\n bridges[bridgeToken] = _bridge;\n bridgeTokensList.push(bridgeToken);\n emit BridgeTokenAdded(bridgeToken, limit, hourlyLimit, fee, paused);\n }\n\n /// @notice Removes support for a token\n /// @param bridgeToken Address of the bridge token to remove support for\n function removeBridgeToken(address bridgeToken) external onlyGovernor {\n if (IERC20(bridgeToken).balanceOf(address(this)) != 0) revert AssetStillControlledInReserves();\n delete bridges[bridgeToken];\n // Deletion from `bridgeTokensList` loop\n uint256 bridgeTokensListLength = bridgeTokensList.length;\n for (uint256 i; i < bridgeTokensListLength - 1; ++i) {\n if (bridgeTokensList[i] == bridgeToken) {\n // Replace the `bridgeToken` to remove with the last of the list\n bridgeTokensList[i] = bridgeTokensList[bridgeTokensListLength - 1];\n break;\n }\n }\n // Remove last element in array\n bridgeTokensList.pop();\n emit BridgeTokenRemoved(bridgeToken);\n }\n\n /// @notice Recovers any ERC20 token\n /// @dev Can be used to withdraw bridge tokens for them to be de-bridged on mainnet\n function recoverERC20(address tokenAddress, address to, uint256 amountToRecover) external onlyGovernor {\n IERC20(tokenAddress).safeTransfer(to, amountToRecover);\n emit Recovered(tokenAddress, to, amountToRecover);\n }\n\n /// @notice Updates the `limit` amount for `bridgeToken`\n function setLimit(address bridgeToken, uint256 limit) external onlyGovernorOrGuardian {\n if (!bridges[bridgeToken].allowed) revert InvalidToken();\n bridges[bridgeToken].limit = limit;\n emit BridgeTokenLimitUpdated(bridgeToken, limit);\n }\n\n /// @notice Updates the `hourlyLimit` amount for `bridgeToken`\n function setHourlyLimit(address bridgeToken, uint256 hourlyLimit) external onlyGovernorOrGuardian {\n if (!bridges[bridgeToken].allowed) revert InvalidToken();\n bridges[bridgeToken].hourlyLimit = hourlyLimit;\n emit BridgeTokenHourlyLimitUpdated(bridgeToken, hourlyLimit);\n }\n\n /// @notice Updates the `chainTotalHourlyLimit` amount\n function setChainTotalHourlyLimit(uint256 hourlyLimit) external onlyGovernorOrGuardian {\n chainTotalHourlyLimit = hourlyLimit;\n emit HourlyLimitUpdated(hourlyLimit);\n }\n\n /// @notice Updates the `fee` value for `bridgeToken`\n function setSwapFee(address bridgeToken, uint64 fee) external onlyGovernorOrGuardian {\n if (!bridges[bridgeToken].allowed) revert InvalidToken();\n if (fee > BASE_PARAMS) revert TooHighParameterValue();\n bridges[bridgeToken].fee = fee;\n emit BridgeTokenFeeUpdated(bridgeToken, fee);\n }\n\n /// @notice Pauses or unpauses swapping in and out for a token\n function toggleBridge(address bridgeToken) external onlyGovernorOrGuardian {\n if (!bridges[bridgeToken].allowed) revert InvalidToken();\n bool pausedStatus = bridges[bridgeToken].paused;\n bridges[bridgeToken].paused = !pausedStatus;\n emit BridgeTokenToggled(bridgeToken, !pausedStatus);\n }\n\n /// @notice Toggles fees for the address `theAddress`\n function toggleFeesForAddress(address theAddress) external onlyGovernorOrGuardian {\n uint256 feeExemptStatus = 1 - isFeeExempt[theAddress];\n isFeeExempt[theAddress] = feeExemptStatus;\n emit FeeToggled(theAddress, feeExemptStatus);\n }\n}\n" + }, + "contracts/agToken/layerZero/LayerZeroBridge.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.12;\n\nimport \"./utils/OFTCore.sol\";\nimport \"@openzeppelin/contracts-upgradeable/security/PausableUpgradeable.sol\";\nimport \"@openzeppelin/contracts/token/ERC20/extensions/draft-IERC20Permit.sol\";\n\n/// @title LayerZeroBridge\n/// @author Angle Labs, Inc., forked from https://github.com/LayerZero-Labs/solidity-examples/blob/main/contracts/token/oft/OFT.sol\n/// @notice Contract to be deployed on Ethereum for bridging an AgToken using a bridge intermediate token and LayerZero\ncontract LayerZeroBridge is OFTCore, PausableUpgradeable {\n /// @notice Name of the contract for indexing purposes\n string public name;\n\n /// @notice Address of the bridgeable token\n /// @dev Immutable\n IERC20 public canonicalToken;\n\n /// @notice Maps an address to the amount of token bridged but not received\n mapping(address => uint256) public balanceOf;\n\n // ================================ CONSTRUCTOR ================================\n /// @notice Initializes the contract\n /// @param _name Name of the token corresponding to this contract\n /// @param _lzEndpoint Layer zero endpoint to pass messages\n /// @param _treasury Address of the treasury contract used for access control\n function initialize(string memory _name, address _lzEndpoint, address _treasury) external initializer {\n __LzAppUpgradeable_init(_lzEndpoint, _treasury);\n name = _name;\n canonicalToken = IERC20(address(ITreasury(_treasury).stablecoin()));\n }\n\n /// @custom:oz-upgrades-unsafe-allow constructor\n constructor() initializer {}\n\n // ===================== EXTERNAL PERMISSIONLESS FUNCTIONS =====================\n\n /// @inheritdoc OFTCore\n function sendWithPermit(\n uint16 _dstChainId,\n bytes memory _toAddress,\n uint256 _amount,\n address payable _refundAddress,\n address _zroPaymentAddress,\n bytes memory _adapterParams,\n uint256 deadline,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) public payable override {\n IERC20Permit(address(canonicalToken)).permit(msg.sender, address(this), _amount, deadline, v, r, s);\n send(_dstChainId, _toAddress, _amount, _refundAddress, _zroPaymentAddress, _adapterParams);\n }\n\n /// @inheritdoc OFTCore\n function withdraw(uint256 amount, address recipient) external override returns (uint256) {\n return _withdraw(amount, msg.sender, recipient);\n }\n\n /// @notice Withdraws amount of `token` from the contract and sends it to the recipient\n /// @param amount Amount to withdraw\n /// @param recipient Address to withdraw for\n /// @return The amount of canonical token sent\n function withdrawFor(uint256 amount, address recipient) external returns (uint256) {\n return _withdraw(amount, recipient, recipient);\n }\n\n // ============================= INTERNAL FUNCTIONS ============================\n\n /// @notice Withdraws `amount` from the balance of the `from` address and sends these tokens to the `to` address\n /// @dev It's important to make sure that `from` is either the `msg.sender` or that `from` and `to` are the same\n /// addresses\n function _withdraw(uint256 amount, address from, address to) internal whenNotPaused returns (uint256) {\n balanceOf[from] -= amount; // Will overflow if the amount is too big\n canonicalToken.transfer(to, amount);\n return amount;\n }\n\n /// @inheritdoc OFTCore\n function _debitFrom(uint16, bytes memory, uint256 _amount) internal override whenNotPaused returns (uint256) {\n // No need to use safeTransferFrom as we know this implementation reverts on failure\n canonicalToken.transferFrom(msg.sender, address(this), _amount);\n return _amount;\n }\n\n /// @inheritdoc OFTCore\n function _debitCreditFrom(uint16, bytes memory, uint256 _amount) internal override whenNotPaused returns (uint256) {\n balanceOf[msg.sender] -= _amount;\n return _amount;\n }\n\n /// @inheritdoc OFTCore\n function _creditTo(uint16, address _toAddress, uint256 _amount) internal override whenNotPaused returns (uint256) {\n // Should never revert as all the LayerZero bridge tokens come from\n // this contract\n uint256 balance = canonicalToken.balanceOf(address(this));\n if (balance < _amount) {\n balanceOf[_toAddress] = _amount - balance;\n if (balance != 0) canonicalToken.transfer(_toAddress, balance);\n } else {\n canonicalToken.transfer(_toAddress, _amount);\n }\n return _amount;\n }\n\n // =============================== VIEW FUNCTIONS ==============================\n\n /// @inheritdoc ERC165Upgradeable\n function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {\n return interfaceId == type(IOFTCore).interfaceId || super.supportsInterface(interfaceId);\n }\n\n // ============================ GOVERNANCE FUNCTIONS ===========================\n\n /// @notice Pauses bridging through the contract\n /// @param pause Future pause status\n function pauseSendTokens(bool pause) external onlyGovernorOrGuardian {\n pause ? _pause() : _unpause();\n }\n\n /// @notice Decreases the balance of an address\n /// @param amount Amount to withdraw from balance\n /// @param recipient Address to withdraw from\n function sweep(uint256 amount, address recipient) external onlyGovernorOrGuardian {\n balanceOf[recipient] -= amount; // Will overflow if the amount is too big\n }\n\n uint256[47] private __gap;\n}\n" + }, + "contracts/agToken/layerZero/LayerZeroBridgeToken.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.12;\n\nimport \"./utils/OFTCore.sol\";\nimport \"../../interfaces/IAgTokenSideChainMultiBridge.sol\";\nimport \"@openzeppelin/contracts-upgradeable/security/PausableUpgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/token/ERC20/ERC20Upgradeable.sol\";\n\n/// @title LayerZeroBridgeToken\n/// @author Angle Labs, Inc., forked from https://github.com/LayerZero-Labs/solidity-examples/blob/main/contracts/token/oft/OFT.sol\n/// @notice Contract to be deployed on a L2/sidechain for bridging an AgToken using a bridge intermediate token and LayerZero\ncontract LayerZeroBridgeToken is OFTCore, ERC20Upgradeable, PausableUpgradeable {\n /// @notice Address of the bridgeable token\n /// @dev Immutable\n IAgTokenSideChainMultiBridge public canonicalToken;\n\n // =================================== ERROR ===================================\n\n error InvalidAllowance();\n\n // ================================ CONSTRUCTOR ================================\n\n /// @notice Initializes the contract\n /// @param _name Name of the token corresponding to this contract\n /// @param _symbol Symbol of the token corresponding to this contract\n /// @param _lzEndpoint Layer zero endpoint to pass messages\n /// @param _treasury Address of the treasury contract used for access control\n /// @param initialSupply Initial supply to mint to the canonical token address\n /// @dev The initial supply corresponds to the initial amount that could be bridged using this OFT\n function initialize(\n string memory _name,\n string memory _symbol,\n address _lzEndpoint,\n address _treasury,\n uint256 initialSupply\n ) external initializer {\n __ERC20_init_unchained(_name, _symbol);\n __LzAppUpgradeable_init(_lzEndpoint, _treasury);\n\n canonicalToken = IAgTokenSideChainMultiBridge(address(ITreasury(_treasury).stablecoin()));\n _approve(address(this), address(canonicalToken), type(uint256).max);\n _mint(address(canonicalToken), initialSupply);\n }\n\n /// @custom:oz-upgrades-unsafe-allow constructor\n constructor() initializer {}\n\n // ===================== EXTERNAL PERMISSIONLESS FUNCTIONS =====================\n\n /// @inheritdoc OFTCore\n function sendWithPermit(\n uint16 _dstChainId,\n bytes memory _toAddress,\n uint256 _amount,\n address payable _refundAddress,\n address _zroPaymentAddress,\n bytes memory _adapterParams,\n uint256 deadline,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) public payable override {\n canonicalToken.permit(msg.sender, address(this), _amount, deadline, v, r, s);\n send(_dstChainId, _toAddress, _amount, _refundAddress, _zroPaymentAddress, _adapterParams);\n }\n\n /// @inheritdoc OFTCore\n function withdraw(uint256 amount, address recipient) external override returns (uint256 amountMinted) {\n // Does not check allowances as transfers from `msg.sender`\n _transfer(msg.sender, address(this), amount);\n amountMinted = canonicalToken.swapIn(address(this), amount, recipient);\n uint256 leftover = balanceOf(address(this));\n if (leftover != 0) {\n _transfer(address(this), msg.sender, leftover);\n }\n }\n\n // ============================= INTERNAL FUNCTIONS ============================\n\n /// @inheritdoc OFTCore\n function _debitFrom(\n uint16,\n bytes memory,\n uint256 _amount\n ) internal override whenNotPaused returns (uint256 amountSwapped) {\n // No need to use safeTransferFrom as we know this implementation reverts on failure\n canonicalToken.transferFrom(msg.sender, address(this), _amount);\n\n // Swap canonical for this bridge token. There may be some fees\n amountSwapped = canonicalToken.swapOut(address(this), _amount, address(this));\n _burn(address(this), amountSwapped);\n }\n\n /// @inheritdoc OFTCore\n function _debitCreditFrom(uint16, bytes memory, uint256 _amount) internal override whenNotPaused returns (uint256) {\n _burn(msg.sender, _amount);\n return _amount;\n }\n\n /// @inheritdoc OFTCore\n function _creditTo(\n uint16,\n address _toAddress,\n uint256 _amount\n ) internal override whenNotPaused returns (uint256 amountMinted) {\n _mint(address(this), _amount);\n amountMinted = canonicalToken.swapIn(address(this), _amount, _toAddress);\n uint256 leftover = balanceOf(address(this));\n if (leftover != 0) {\n _transfer(address(this), _toAddress, leftover);\n }\n }\n\n // =============================== VIEW FUNCTIONS ==============================\n\n /// @inheritdoc ERC165Upgradeable\n function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {\n return\n interfaceId == type(IOFT).interfaceId ||\n interfaceId == type(IERC20).interfaceId ||\n super.supportsInterface(interfaceId);\n }\n\n // ============================ GOVERNANCE FUNCTIONS ===========================\n\n /// @notice Mints the intermediate contract to the `canonicalToken`\n /// @dev Used to increase the bridging capacity\n function mint(uint256 amount) external onlyGovernorOrGuardian {\n _mint(address(canonicalToken), amount);\n }\n\n /// @notice Burns the intermediate contract from the `canonicalToken`\n /// @dev Used to decrease the bridging capacity\n function burn(uint256 amount) external onlyGovernorOrGuardian {\n _burn(address(canonicalToken), amount);\n }\n\n /// @notice Increases allowance of the `canonicalToken`\n function setupAllowance() public onlyGovernorOrGuardian {\n _approve(address(this), address(canonicalToken), type(uint256).max);\n }\n\n /// @notice Pauses bridging through the contract\n /// @param pause Future pause status\n function pauseSendTokens(bool pause) external onlyGovernorOrGuardian {\n pause ? _pause() : _unpause();\n }\n\n uint256[49] private __gap;\n}\n" + }, + "contracts/agToken/layerZero/utils/IOFTCore.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.12;\n\nimport \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\nimport \"@openzeppelin/contracts/utils/introspection/IERC165.sol\";\n\n/**\n * @dev Interface of the IOFT core standard\n * @dev Forked from https://github.com/LayerZero-Labs/solidity-examples/blob/main/contracts/token/oft/IOFTCore.sol\n */\ninterface IOFTCore is IERC165 {\n /// @notice Estimates send token `_tokenId` to (`_dstChainId`, `_toAddress`)\n /// @param _dstChainId L0 defined chain id to send tokens too\n /// @param _toAddress dynamic bytes array which contains the address to whom you are sending tokens to on the dstChain\n /// @param _amount amount of the tokens to transfer\n /// @param _useZro indicates to use zro to pay L0 fees\n /// @param _adapterParams flexible bytes array to indicate messaging adapter services in L0\n function estimateSendFee(\n uint16 _dstChainId,\n bytes calldata _toAddress,\n uint256 _amount,\n bool _useZro,\n bytes calldata _adapterParams\n ) external view returns (uint256 nativeFee, uint256 zroFee);\n\n /// @notice Sends `_amount` amount of token to (`_dstChainId`, `_toAddress`)\n /// @param _dstChainId the destination chain identifier\n /// @param _toAddress can be any size depending on the `dstChainId`.\n /// @param _amount the quantity of tokens in wei\n /// @param _refundAddress the address LayerZero refunds if too much message fee is sent\n /// @param _zroPaymentAddress set to address(0x0) if not paying in ZRO (LayerZero Token)\n /// @param _adapterParams is a flexible bytes array to indicate messaging adapter services\n function send(\n uint16 _dstChainId,\n bytes calldata _toAddress,\n uint256 _amount,\n address payable _refundAddress,\n address _zroPaymentAddress,\n bytes calldata _adapterParams\n ) external payable;\n\n /// @notice Sends `_amount` amount of credit to (`_dstChainId`, `_toAddress`)\n /// @param _dstChainId the destination chain identifier\n /// @param _toAddress can be any size depending on the `dstChainId`.\n /// @param _amount the quantity of credit to send in wei\n /// @param _refundAddress the address LayerZero refunds if too much message fee is sent\n /// @param _zroPaymentAddress set to address(0x0) if not paying in ZRO (LayerZero Token)\n /// @param _adapterParams is a flexible bytes array to indicate messaging adapter services\n function sendCredit(\n uint16 _dstChainId,\n bytes calldata _toAddress,\n uint256 _amount,\n address payable _refundAddress,\n address _zroPaymentAddress,\n bytes calldata _adapterParams\n ) external payable;\n\n /// @notice Sends `_amount` amount of token to (`_dstChainId`, `_toAddress`)\n /// @param _dstChainId The destination chain identifier\n /// @param _toAddress Can be any size depending on the `dstChainId`.\n /// @param _amount Quantity of tokens in wei\n /// @param _refundAddress Address LayerZero refunds if too much message fee is sent\n /// @param _zroPaymentAddress Set to address(0x0) if not paying in ZRO (LayerZero Token)\n /// @param _adapterParams Flexible bytes array to indicate messaging adapter services\n /// @param deadline Deadline parameter for the signature to be valid\n /// @dev The `v`, `r`, and `s` parameters are used as signature data\n function sendWithPermit(\n uint16 _dstChainId,\n bytes memory _toAddress,\n uint256 _amount,\n address payable _refundAddress,\n address _zroPaymentAddress,\n bytes memory _adapterParams,\n uint256 deadline,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) external payable;\n\n /// @notice Withdraws amount of canonical token from the `msg.sender` balance and sends it to the recipient\n /// @param amount Amount to withdraw\n /// @param recipient Address to send the canonical token to\n /// @return The amount of canonical token sent\n function withdraw(uint256 amount, address recipient) external returns (uint256);\n\n /// @dev Emitted when `_amount` tokens are moved from the `_sender` to (`_dstChainId`, `_toAddress`)\n /// `_nonce` is the outbound nonce\n event SendToChain(\n address indexed _sender,\n uint16 indexed _dstChainId,\n bytes indexed _toAddress,\n uint256 _amount,\n uint64 _nonce\n );\n\n /// @dev Emitted when `_amount` tokens are received from `_srcChainId` into the `_toAddress` on the local chain.\n /// `_nonce` is the inbound nonce.\n event ReceiveFromChain(\n uint16 indexed _srcChainId,\n bytes indexed _srcAddress,\n address indexed _toAddress,\n uint256 _amount,\n uint64 _nonce\n );\n}\n\n/// @dev Interface of the OFT standard\ninterface IOFT is IOFTCore, IERC20 {\n\n}\n" + }, + "contracts/agToken/layerZero/utils/NonblockingLzApp.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.12;\n\nimport \"@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol\";\nimport \"../../../interfaces/external/layerZero/ILayerZeroReceiver.sol\";\nimport \"../../../interfaces/external/layerZero/ILayerZeroUserApplicationConfig.sol\";\nimport \"../../../interfaces/external/layerZero/ILayerZeroEndpoint.sol\";\nimport \"../../../interfaces/ITreasury.sol\";\n\n/// @title NonblockingLzApp\n/// @author Angle Labs, Inc., forked from https://github.com/LayerZero-Labs/solidity-examples/\n/// @notice Base contract for bridging using LayerZero\nabstract contract NonblockingLzApp is Initializable, ILayerZeroReceiver, ILayerZeroUserApplicationConfig {\n /// @notice Layer Zero endpoint\n ILayerZeroEndpoint public lzEndpoint;\n\n /// @notice Maps chainIds to failed messages to retry them\n mapping(uint16 => mapping(bytes => mapping(uint64 => bytes32))) public failedMessages;\n\n /// @notice Maps chainIds to their OFT address\n mapping(uint16 => bytes) public trustedRemoteLookup;\n\n /// @notice Reference to the treasury contract to fetch access control\n address public treasury;\n\n /// @notice Maps pairs of (`to` chain, `packetType`) to the minimum amount of gas needed on the destination chain\n mapping(uint16 => mapping(uint16 => uint256)) public minDstGasLookup;\n\n /// @notice For future LayerZero compatibility\n address public precrime;\n\n // ================================== Events ===================================\n\n event SetTrustedRemote(uint16 _srcChainId, bytes _srcAddress);\n event MessageFailed(uint16 _srcChainId, bytes _srcAddress, uint64 _nonce, bytes _payload);\n\n // =============================== Errors ================================\n\n error NotGovernor();\n error NotGovernorOrGuardian();\n error InsufficientGas();\n error InvalidEndpoint();\n error InvalidSource();\n error InvalidCaller();\n error InvalidParams();\n error InvalidPayload();\n error ZeroAddress();\n\n // ============================= Constructor ===================================\n\n //solhint-disable-next-line\n function __LzAppUpgradeable_init(address _endpoint, address _treasury) internal {\n if (_endpoint == address(0) || _treasury == address(0)) revert ZeroAddress();\n lzEndpoint = ILayerZeroEndpoint(_endpoint);\n treasury = _treasury;\n }\n\n // =============================== Modifiers ===================================\n\n /// @notice Checks whether the `msg.sender` has the governor role or the guardian role\n modifier onlyGovernorOrGuardian() {\n if (!ITreasury(treasury).isGovernorOrGuardian(msg.sender)) revert NotGovernorOrGuardian();\n _;\n }\n\n // ==================== External Permissionless Functions ======================\n\n /// @notice Receives a message from the LZ endpoint and process it\n /// @param _srcChainId ChainId of the source chain - LayerZero standard\n /// @param _srcAddress Sender of the source chain\n /// @param _nonce Nounce of the message\n /// @param _payload Data: recipient address and amount\n function lzReceive(\n uint16 _srcChainId,\n bytes memory _srcAddress,\n uint64 _nonce,\n bytes memory _payload\n ) public virtual override {\n // lzReceive must be called by the endpoint for security\n if (msg.sender != address(lzEndpoint)) revert InvalidEndpoint();\n\n bytes memory trustedRemote = trustedRemoteLookup[_srcChainId];\n // if will still block the message pathway from (srcChainId, srcAddress). should not receive message from untrusted remote.\n if (_srcAddress.length != trustedRemote.length || keccak256(_srcAddress) != keccak256(trustedRemote))\n revert InvalidSource();\n\n _blockingLzReceive(_srcChainId, _srcAddress, _nonce, _payload);\n }\n\n /// @notice Retries a message that previously failed and was stored\n /// @param _srcChainId ChainId of the source chain - LayerZero standard\n /// @param _srcAddress Sender of the source chain\n /// @param _nonce Nounce of the message\n /// @param _payload Data: recipient address and amount\n function retryMessage(\n uint16 _srcChainId,\n bytes memory _srcAddress,\n uint64 _nonce,\n bytes memory _payload\n ) public payable virtual {\n // assert there is message to retry\n bytes32 payloadHash = failedMessages[_srcChainId][_srcAddress][_nonce];\n if (payloadHash == bytes32(0) || keccak256(_payload) != payloadHash) revert InvalidPayload();\n // clear the stored message\n failedMessages[_srcChainId][_srcAddress][_nonce] = bytes32(0);\n // execute the message. revert if it fails again\n _nonblockingLzReceive(_srcChainId, _srcAddress, _nonce, _payload);\n }\n\n // ============================= Internal Functions ===================================\n\n /// @notice Handles message receptions in a non blocking way\n /// @param _srcChainId ChainId of the source chain - LayerZero standard\n /// @param _srcAddress Sender of the source chain\n /// @param _nonce Nounce of the message\n /// @param _payload Data: recipient address and amount\n /// @dev public for the needs of try / catch but effectively internal\n function nonblockingLzReceive(\n uint16 _srcChainId,\n bytes memory _srcAddress,\n uint64 _nonce,\n bytes memory _payload\n ) public virtual {\n // only internal transaction\n if (msg.sender != address(this)) revert InvalidCaller();\n _nonblockingLzReceive(_srcChainId, _srcAddress, _nonce, _payload);\n }\n\n /// @notice Handles message receptions in a non blocking way\n /// @param _srcChainId ChainId of the source chain - LayerZero standard\n /// @param _srcAddress Sender of the source chain\n /// @param _nonce Nounce of the message\n /// @param _payload Data: recipient address and amount\n function _nonblockingLzReceive(\n uint16 _srcChainId,\n bytes memory _srcAddress,\n uint64 _nonce,\n bytes memory _payload\n ) internal virtual;\n\n /// @notice Handles message receptions in a blocking way\n /// @param _srcChainId ChainId of the source chain - LayerZero standard\n /// @param _srcAddress Sender of the source chain\n /// @param _nonce Nounce of the message\n /// @param _payload Data: recipient address and amount\n function _blockingLzReceive(\n uint16 _srcChainId,\n bytes memory _srcAddress,\n uint64 _nonce,\n bytes memory _payload\n ) internal {\n // try-catch all errors/exceptions\n try this.nonblockingLzReceive(_srcChainId, _srcAddress, _nonce, _payload) {\n // do nothing\n } catch {\n // error / exception\n failedMessages[_srcChainId][_srcAddress][_nonce] = keccak256(_payload);\n emit MessageFailed(_srcChainId, _srcAddress, _nonce, _payload);\n }\n }\n\n /// @notice Sends a message to the LZ endpoint and process it\n /// @param _dstChainId L0 defined chain id to send tokens too\n /// @param _payload Data: recipient address and amount\n /// @param _refundAddress Address LayerZero refunds if too much message fee is sent\n /// @param _zroPaymentAddress Set to address(0x0) if not paying in ZRO (LayerZero Token)\n /// @param _adapterParams Flexible bytes array to indicate messaging adapter services in L0\n function _lzSend(\n uint16 _dstChainId,\n bytes memory _payload,\n address payable _refundAddress,\n address _zroPaymentAddress,\n bytes memory _adapterParams\n ) internal virtual {\n bytes memory trustedRemote = trustedRemoteLookup[_dstChainId];\n if (trustedRemote.length == 0) revert InvalidSource();\n //solhint-disable-next-line\n lzEndpoint.send{ value: msg.value }(\n _dstChainId,\n trustedRemote,\n _payload,\n _refundAddress,\n _zroPaymentAddress,\n _adapterParams\n );\n }\n\n /// @notice Checks the gas limit of a given transaction\n function _checkGasLimit(\n uint16 _dstChainId,\n uint16 _type,\n bytes memory _adapterParams,\n uint256 _extraGas\n ) internal view virtual {\n uint256 minGasLimit = minDstGasLookup[_dstChainId][_type] + _extraGas;\n if (minGasLimit == 0 || minGasLimit > _getGasLimit(_adapterParams)) revert InsufficientGas();\n }\n\n /// @notice Gets the gas limit from the `_adapterParams` parameter\n function _getGasLimit(bytes memory _adapterParams) internal pure virtual returns (uint256 gasLimit) {\n if (_adapterParams.length < 34) revert InvalidParams();\n // solhint-disable-next-line\n assembly {\n gasLimit := mload(add(_adapterParams, 34))\n }\n }\n\n // ======================= Governance Functions ================================\n\n /// @notice Sets the corresponding address on an other chain.\n /// @param _srcChainId ChainId of the source chain - LayerZero standard\n /// @param _srcAddress Address on the source chain\n /// @dev Used for both receiving and sending message\n /// @dev There can only be one trusted source per chain\n /// @dev Allows owner to set it multiple times.\n function setTrustedRemote(uint16 _srcChainId, bytes calldata _srcAddress) external onlyGovernorOrGuardian {\n trustedRemoteLookup[_srcChainId] = _srcAddress;\n emit SetTrustedRemote(_srcChainId, _srcAddress);\n }\n\n /// @notice Fetches the default LZ config\n function getConfig(\n uint16 _version,\n uint16 _chainId,\n address,\n uint256 _configType\n ) external view returns (bytes memory) {\n return lzEndpoint.getConfig(_version, _chainId, address(this), _configType);\n }\n\n /// @notice Overrides the default LZ config\n function setConfig(\n uint16 _version,\n uint16 _chainId,\n uint256 _configType,\n bytes calldata _config\n ) external override onlyGovernorOrGuardian {\n lzEndpoint.setConfig(_version, _chainId, _configType, _config);\n }\n\n /// @notice Overrides the default LZ config\n function setSendVersion(uint16 _version) external override onlyGovernorOrGuardian {\n lzEndpoint.setSendVersion(_version);\n }\n\n /// @notice Overrides the default LZ config\n function setReceiveVersion(uint16 _version) external override onlyGovernorOrGuardian {\n lzEndpoint.setReceiveVersion(_version);\n }\n\n /// @notice Unpauses the receive functionalities\n function forceResumeReceive(\n uint16 _srcChainId,\n bytes calldata _srcAddress\n ) external override onlyGovernorOrGuardian {\n lzEndpoint.forceResumeReceive(_srcChainId, _srcAddress);\n }\n\n /// @notice Sets the minimum gas parameter for a packet type on a given chain\n function setMinDstGas(uint16 _dstChainId, uint16 _packetType, uint256 _minGas) external onlyGovernorOrGuardian {\n if (_minGas == 0) revert InvalidParams();\n minDstGasLookup[_dstChainId][_packetType] = _minGas;\n }\n\n /// @notice Sets the precrime variable\n function setPrecrime(address _precrime) external onlyGovernorOrGuardian {\n precrime = _precrime;\n }\n\n // ======================= View Functions ================================\n\n /// @notice Checks if the `_srcAddress` corresponds to the trusted source\n function isTrustedRemote(uint16 _srcChainId, bytes calldata _srcAddress) external view returns (bool) {\n bytes memory trustedSource = trustedRemoteLookup[_srcChainId];\n return keccak256(trustedSource) == keccak256(_srcAddress);\n }\n\n uint256[44] private __gap;\n}\n" + }, + "contracts/agToken/layerZero/utils/OFTCore.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.12;\n\nimport \"./NonblockingLzApp.sol\";\nimport \"./IOFTCore.sol\";\nimport \"@openzeppelin/contracts-upgradeable/utils/introspection/ERC165Upgradeable.sol\";\n\n/// @title OFTCore\n/// @author Forked from https://github.com/LayerZero-Labs/solidity-examples/blob/main/contracts/token/oft/OFTCore.sol\n/// but with slight modifications from the Angle Labs, Inc. which added return values to the `_creditTo` and `_debitFrom` functions\n/// @notice Base contract for bridging using LayerZero\nabstract contract OFTCore is NonblockingLzApp, ERC165Upgradeable, IOFTCore {\n /// @notice Amount of additional gas specified\n uint256 public constant EXTRA_GAS = 200000;\n /// @notice Packet type for token transfer\n uint16 public constant PT_SEND = 0;\n\n /// @notice Whether to use custom parameters in transactions\n uint8 public useCustomAdapterParams;\n\n // ==================== External Permissionless Functions ======================\n\n /// @inheritdoc IOFTCore\n function sendWithPermit(\n uint16 _dstChainId,\n bytes memory _toAddress,\n uint256 _amount,\n address payable _refundAddress,\n address _zroPaymentAddress,\n bytes memory _adapterParams,\n uint256 deadline,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) public payable virtual;\n\n /// @inheritdoc IOFTCore\n function send(\n uint16 _dstChainId,\n bytes memory _toAddress,\n uint256 _amount,\n address payable _refundAddress,\n address _zroPaymentAddress,\n bytes memory _adapterParams\n ) public payable virtual {\n _checkAdapterParams(_dstChainId, PT_SEND, _adapterParams, EXTRA_GAS);\n _amount = _debitFrom(_dstChainId, _toAddress, _amount);\n\n bytes memory payload = abi.encode(_toAddress, _amount);\n _lzSend(_dstChainId, payload, _refundAddress, _zroPaymentAddress, _adapterParams);\n\n uint64 nonce = lzEndpoint.getOutboundNonce(_dstChainId, address(this));\n emit SendToChain(msg.sender, _dstChainId, _toAddress, _amount, nonce);\n }\n\n /// @inheritdoc IOFTCore\n function sendCredit(\n uint16 _dstChainId,\n bytes memory _toAddress,\n uint256 _amount,\n address payable _refundAddress,\n address _zroPaymentAddress,\n bytes memory _adapterParams\n ) public payable virtual {\n _checkAdapterParams(_dstChainId, PT_SEND, _adapterParams, EXTRA_GAS);\n _amount = _debitCreditFrom(_dstChainId, _toAddress, _amount);\n\n _send(_dstChainId, _toAddress, _amount, _refundAddress, _zroPaymentAddress, _adapterParams);\n }\n\n /// @inheritdoc IOFTCore\n function withdraw(uint256 amount, address recipient) external virtual returns (uint256);\n\n /// @notice Sets whether custom adapter parameters can be used or not\n function setUseCustomAdapterParams(uint8 _useCustomAdapterParams) public virtual onlyGovernorOrGuardian {\n useCustomAdapterParams = _useCustomAdapterParams;\n }\n\n // =========================== Internal Functions ==============================\n\n /// @notice Internal function to send `_amount` amount of token to (`_dstChainId`, `_toAddress`)\n /// @param _dstChainId the destination chain identifier\n /// @param _toAddress can be any size depending on the `dstChainId`.\n /// @param _amount the quantity of tokens in wei\n /// @param _refundAddress the address LayerZero refunds if too much message fee is sent\n /// @param _zroPaymentAddress set to address(0x0) if not paying in ZRO (LayerZero Token)\n /// @param _adapterParams is a flexible bytes array to indicate messaging adapter services\n /// @dev Accounting and checks should be performed beforehand\n function _send(\n uint16 _dstChainId,\n bytes memory _toAddress,\n uint256 _amount,\n address payable _refundAddress,\n address _zroPaymentAddress,\n bytes memory _adapterParams\n ) internal {\n bytes memory payload = abi.encode(_toAddress, _amount);\n _lzSend(_dstChainId, payload, _refundAddress, _zroPaymentAddress, _adapterParams);\n\n uint64 nonce = lzEndpoint.getOutboundNonce(_dstChainId, address(this));\n emit SendToChain(msg.sender, _dstChainId, _toAddress, _amount, nonce);\n }\n\n /// @inheritdoc NonblockingLzApp\n function _nonblockingLzReceive(\n uint16 _srcChainId,\n bytes memory _srcAddress,\n uint64 _nonce,\n bytes memory _payload\n ) internal virtual override {\n // decode and load the toAddress\n (bytes memory toAddressBytes, uint256 amount) = abi.decode(_payload, (bytes, uint256));\n address toAddress;\n //solhint-disable-next-line\n assembly {\n toAddress := mload(add(toAddressBytes, 20))\n }\n amount = _creditTo(_srcChainId, toAddress, amount);\n\n emit ReceiveFromChain(_srcChainId, _srcAddress, toAddress, amount, _nonce);\n }\n\n /// @notice Checks the adapter parameters given during the smart contract call\n function _checkAdapterParams(\n uint16 _dstChainId,\n uint16 _pkType,\n bytes memory _adapterParams,\n uint256 _extraGas\n ) internal virtual {\n if (useCustomAdapterParams > 0) _checkGasLimit(_dstChainId, _pkType, _adapterParams, _extraGas);\n else if (_adapterParams.length != 0) revert InvalidParams();\n }\n\n /// @notice Makes accountability when bridging from this contract using canonical token\n /// @param _dstChainId ChainId of the destination chain - LayerZero standard\n /// @param _toAddress Recipient on the destination chain\n /// @param _amount Amount to bridge\n function _debitFrom(\n uint16 _dstChainId,\n bytes memory _toAddress,\n uint256 _amount\n ) internal virtual returns (uint256);\n\n /// @notice Makes accountability when bridging from this contract's credit\n /// @param _dstChainId ChainId of the destination chain - LayerZero standard\n /// @param _toAddress Recipient on the destination chain\n /// @param _amount Amount to bridge\n function _debitCreditFrom(\n uint16 _dstChainId,\n bytes memory _toAddress,\n uint256 _amount\n ) internal virtual returns (uint256);\n\n /// @notice Makes accountability when bridging to this contract\n /// @param _srcChainId ChainId of the source chain - LayerZero standard\n /// @param _toAddress Recipient on this chain\n /// @param _amount Amount to bridge\n function _creditTo(uint16 _srcChainId, address _toAddress, uint256 _amount) internal virtual returns (uint256);\n\n // ========================== View Functions ===================================\n\n /// @inheritdoc ERC165Upgradeable\n function supportsInterface(\n bytes4 interfaceId\n ) public view virtual override(ERC165Upgradeable, IERC165) returns (bool) {\n return interfaceId == type(IOFTCore).interfaceId || super.supportsInterface(interfaceId);\n }\n\n /// @inheritdoc IOFTCore\n function estimateSendFee(\n uint16 _dstChainId,\n bytes memory _toAddress,\n uint256 _amount,\n bool _useZro,\n bytes memory _adapterParams\n ) public view virtual override returns (uint256 nativeFee, uint256 zroFee) {\n // mock the payload for send()\n bytes memory payload = abi.encode(_toAddress, _amount);\n return lzEndpoint.estimateFees(_dstChainId, address(this), payload, _useZro, _adapterParams);\n }\n\n uint256[49] private __gap;\n}\n" + }, + "contracts/agToken/polygon/TokenPolygonUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.12;\n\nimport \"./utils/ERC20UpgradeableCustom.sol\";\nimport \"@openzeppelin/contracts-upgradeable/access/AccessControlUpgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/utils/cryptography/draft-EIP712Upgradeable.sol\";\nimport \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\nimport \"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\";\n\nimport \"../../interfaces/IAgToken.sol\";\nimport \"../../interfaces/ITreasury.sol\";\n\ninterface IChildToken {\n function deposit(address user, bytes calldata depositData) external;\n\n function withdraw(uint256 amount) external;\n}\n\ncontract TokenPolygonUpgradeable is\n Initializable,\n ERC20UpgradeableCustom,\n AccessControlUpgradeable,\n EIP712Upgradeable,\n IChildToken\n{\n bytes32 public constant DEPOSITOR_ROLE = keccak256(\"DEPOSITOR_ROLE\");\n\n /// @dev Emitted when the child chain manager changes\n event ChildChainManagerAdded(address newAddress);\n event ChildChainManagerRevoked(address oldAddress);\n\n constructor() initializer {}\n\n function initialize(\n string memory _name,\n string memory _symbol,\n address childChainManager,\n address guardian\n ) public initializer {\n __ERC20_init(_name, _symbol);\n __AccessControl_init();\n _setupRole(DEFAULT_ADMIN_ROLE, guardian);\n _setupRole(DEPOSITOR_ROLE, childChainManager);\n __EIP712_init(_name, \"1\");\n }\n\n /**\n * @notice Called when the bridge has tokens to mint\n * @param user Address to mint the token to\n * @param depositData Encoded amount to mint\n */\n function deposit(address user, bytes calldata depositData) external override {\n require(hasRole(DEPOSITOR_ROLE, msg.sender));\n uint256 amount = abi.decode(depositData, (uint256));\n _mint(user, amount);\n }\n\n /**\n * @notice Called when user wants to withdraw tokens back to root chain\n * @dev Should burn user's tokens. This transaction will be verified when exiting on root chain\n * @param amount Amount of tokens to withdraw\n */\n function withdraw(uint256 amount) external override {\n _burn(_msgSender(), amount);\n }\n\n // =============================================================================\n // ======================= New data added for the upgrade ======================\n // =============================================================================\n\n mapping(address => bool) public isMinter;\n /// @notice Reference to the treasury contract which can grant minting rights\n address public treasury;\n /// @notice Boolean to check whether the contract has been reinitialized after its upgrade\n bool public treasuryInitialized;\n\n using SafeERC20 for IERC20;\n\n /// @notice Base used for fee computation\n uint256 public constant BASE_PARAMS = 10 ** 9;\n\n // =============================== Bridging Data ===============================\n\n /// @notice Struct with some data about a specific bridge token\n struct BridgeDetails {\n // Limit on the balance of bridge token held by the contract: it is designed\n // to reduce the exposure of the system to hacks\n uint256 limit;\n // Limit on the hourly volume of token minted through this bridge\n // Technically the limit over a rolling hour is hourlyLimit x2 as hourly limit\n // is enforced only between x:00 and x+1:00\n uint256 hourlyLimit;\n // Fee taken for swapping in and out the token\n uint64 fee;\n // Whether the associated token is allowed or not\n bool allowed;\n // Whether swapping in and out from the associated token is paused or not\n bool paused;\n }\n\n /// @notice Maps a bridge token to data\n mapping(address => BridgeDetails) public bridges;\n /// @notice List of all bridge tokens\n address[] public bridgeTokensList;\n /// @notice Maps a bridge token to the associated hourly volume\n mapping(address => mapping(uint256 => uint256)) public usage;\n /// @notice Maps an address to whether it is exempt of fees for when it comes to swapping in and out\n mapping(address => uint256) public isFeeExempt;\n /// @notice Limit to the amount of tokens that can be sent from that chain to another chain\n uint256 public chainTotalHourlyLimit;\n /// @notice Usage per hour on that chain. Maps an hourly timestamp to the total volume swapped out on the chain\n mapping(uint256 => uint256) public chainTotalUsage;\n\n uint256[42] private __gap;\n\n // ================================== Events ===================================\n\n event BridgeTokenAdded(address indexed bridgeToken, uint256 limit, uint256 hourlyLimit, uint64 fee, bool paused);\n event BridgeTokenToggled(address indexed bridgeToken, bool toggleStatus);\n event BridgeTokenRemoved(address indexed bridgeToken);\n event BridgeTokenFeeUpdated(address indexed bridgeToken, uint64 fee);\n event BridgeTokenLimitUpdated(address indexed bridgeToken, uint256 limit);\n event BridgeTokenHourlyLimitUpdated(address indexed bridgeToken, uint256 hourlyLimit);\n event HourlyLimitUpdated(uint256 hourlyLimit);\n event FeeToggled(address indexed theAddress, uint256 toggleStatus);\n event KeeperToggled(address indexed keeper, bool toggleStatus);\n event MinterToggled(address indexed minter);\n event Recovered(address indexed token, address indexed to, uint256 amount);\n event TreasuryUpdated(address indexed _treasury);\n\n // ================================== Errors ===================================\n\n error AssetStillControlledInReserves();\n error BurnAmountExceedsAllowance();\n error HourlyLimitExceeded();\n error InvalidSender();\n error InvalidToken();\n error InvalidTreasury();\n error NotGovernor();\n error NotGovernorOrGuardian();\n error NotMinter();\n error NotTreasury();\n error TooBigAmount();\n error TooHighParameterValue();\n error TreasuryAlreadyInitialized();\n error ZeroAddress();\n\n /// @notice Checks to see if it is the `Treasury` calling this contract\n /// @dev There is no Access Control here, because it can be handled cheaply through this modifier\n modifier onlyTreasury() {\n if (msg.sender != treasury) revert NotTreasury();\n _;\n }\n\n /// @notice Checks whether the sender has the minting right\n modifier onlyMinter() {\n if (!isMinter[msg.sender]) revert NotMinter();\n _;\n }\n\n /// @notice Checks whether the `msg.sender` has the governor role or not\n modifier onlyGovernor() {\n if (!ITreasury(treasury).isGovernor(msg.sender)) revert NotGovernor();\n _;\n }\n\n /// @notice Checks whether the `msg.sender` has the governor role or the guardian role\n modifier onlyGovernorOrGuardian() {\n if (!ITreasury(treasury).isGovernorOrGuardian(msg.sender)) revert NotGovernorOrGuardian();\n _;\n }\n\n /// @notice Sets up the treasury contract on Polygon after the upgrade\n /// @param _treasury Address of the treasury contract\n function setUpTreasury(address _treasury) external {\n // Only governor on Polygon\n if (msg.sender != 0xdA2D2f638D6fcbE306236583845e5822554c02EA) revert NotGovernor();\n if (address(ITreasury(_treasury).stablecoin()) != address(this)) revert InvalidTreasury();\n if (treasuryInitialized) revert TreasuryAlreadyInitialized();\n treasury = _treasury;\n treasuryInitialized = true;\n emit TreasuryUpdated(_treasury);\n }\n\n // =========================== External Function ===============================\n\n /// @notice Allows anyone to burn agToken without redeeming collateral back\n /// @param amount Amount of stablecoins to burn\n /// @dev This function can typically be called if there is a settlement mechanism to burn stablecoins\n function burnStablecoin(uint256 amount) external {\n _burnCustom(msg.sender, amount);\n }\n\n // ======================= Minter Role Only Functions ==========================\n\n function burnSelf(uint256 amount, address burner) external onlyMinter {\n _burnCustom(burner, amount);\n }\n\n function burnFrom(uint256 amount, address burner, address sender) external onlyMinter {\n _burnFromNoRedeem(amount, burner, sender);\n }\n\n function mint(address account, uint256 amount) external onlyMinter {\n _mint(account, amount);\n }\n\n // ======================= Treasury Only Functions =============================\n\n function addMinter(address minter) external onlyTreasury {\n isMinter[minter] = true;\n emit MinterToggled(minter);\n }\n\n function removeMinter(address minter) external {\n if (msg.sender != address(treasury) && msg.sender != minter) revert InvalidSender();\n isMinter[minter] = false;\n emit MinterToggled(minter);\n }\n\n function setTreasury(address _treasury) external onlyTreasury {\n treasury = _treasury;\n emit TreasuryUpdated(_treasury);\n }\n\n // ============================ Internal Function ==============================\n\n /// @notice Internal version of the function `burnFromNoRedeem`\n /// @param amount Amount to burn\n /// @dev It is at the level of this function that allowance checks are performed\n function _burnFromNoRedeem(uint256 amount, address burner, address sender) internal {\n if (burner != sender) {\n uint256 currentAllowance = allowance(burner, sender);\n if (currentAllowance < amount) revert BurnAmountExceedsAllowance();\n _approve(burner, sender, currentAllowance - amount);\n }\n _burnCustom(burner, amount);\n }\n\n // ==================== External Permissionless Functions ======================\n\n /// @notice Returns the list of all supported bridge tokens\n /// @dev Helpful for UIs\n function allBridgeTokens() external view returns (address[] memory) {\n return bridgeTokensList;\n }\n\n /// @notice Returns the current volume for a bridge, for the current hour\n /// @dev Helpful for UIs\n function currentUsage(address bridge) external view returns (uint256) {\n return usage[bridge][block.timestamp / 3600];\n }\n\n /// @notice Returns the current total volume on the chain for the current hour\n /// @dev Helpful for UIs\n function currentTotalUsage() external view returns (uint256) {\n return chainTotalUsage[block.timestamp / 3600];\n }\n\n /// @notice Mints the canonical token from a supported bridge token\n /// @param bridgeToken Bridge token to use to mint\n /// @param amount Amount of bridge tokens to send\n /// @param to Address to which the stablecoin should be sent\n /// @dev Some fees may be taken by the protocol depending on the token used and on the address calling\n function swapIn(address bridgeToken, uint256 amount, address to) external returns (uint256) {\n BridgeDetails memory bridgeDetails = bridges[bridgeToken];\n if (!bridgeDetails.allowed || bridgeDetails.paused) revert InvalidToken();\n uint256 balance = IERC20(bridgeToken).balanceOf(address(this));\n if (balance + amount > bridgeDetails.limit) {\n // In case someone maliciously sends tokens to this contract\n // Or the limit changes\n if (bridgeDetails.limit > balance) amount = bridgeDetails.limit - balance;\n else {\n amount = 0;\n }\n }\n\n // Checking requirement on the hourly volume\n uint256 hour = block.timestamp / 3600;\n uint256 hourlyUsage = usage[bridgeToken][hour] + amount;\n if (hourlyUsage > bridgeDetails.hourlyLimit) {\n // Edge case when the hourly limit changes\n if (bridgeDetails.hourlyLimit > usage[bridgeToken][hour])\n amount = bridgeDetails.hourlyLimit - usage[bridgeToken][hour];\n else {\n amount = 0;\n }\n }\n usage[bridgeToken][hour] += amount;\n\n IERC20(bridgeToken).safeTransferFrom(msg.sender, address(this), amount);\n uint256 canonicalOut = amount;\n // Computing fees\n if (isFeeExempt[msg.sender] == 0) {\n canonicalOut -= (canonicalOut * bridgeDetails.fee) / BASE_PARAMS;\n }\n _mint(to, canonicalOut);\n return canonicalOut;\n }\n\n /// @notice Burns the canonical token in exchange for a bridge token\n /// @param bridgeToken Bridge token required\n /// @param amount Amount of canonical tokens to burn\n /// @param to Address to which the bridge token should be sent\n /// @dev Some fees may be taken by the protocol depending on the token used and on the address calling\n function swapOut(address bridgeToken, uint256 amount, address to) external returns (uint256) {\n BridgeDetails memory bridgeDetails = bridges[bridgeToken];\n if (!bridgeDetails.allowed || bridgeDetails.paused) revert InvalidToken();\n\n uint256 hour = block.timestamp / 3600;\n uint256 hourlyUsage = chainTotalUsage[hour] + amount;\n // If the amount being swapped out exceeds the limit, we revert\n // We don't want to change the amount being swapped out.\n // The user can decide to send another tx with the correct amount to reach the limit\n if (hourlyUsage > chainTotalHourlyLimit) revert HourlyLimitExceeded();\n chainTotalUsage[hour] = hourlyUsage;\n\n _burnCustom(msg.sender, amount);\n uint256 bridgeOut = amount;\n if (isFeeExempt[msg.sender] == 0) {\n bridgeOut -= (bridgeOut * bridgeDetails.fee) / BASE_PARAMS;\n }\n IERC20(bridgeToken).safeTransfer(to, bridgeOut);\n return bridgeOut;\n }\n\n // ======================= Governance Functions ================================\n\n /// @notice Adds support for a bridge token\n /// @param bridgeToken Bridge token to add: it should be a version of the stablecoin from another bridge\n /// @param limit Limit on the balance of bridge token this contract could hold\n /// @param hourlyLimit Limit on the hourly volume for this bridge\n /// @param paused Whether swapping for this token should be paused or not\n /// @param fee Fee taken upon swapping for or against this token\n function addBridgeToken(\n address bridgeToken,\n uint256 limit,\n uint256 hourlyLimit,\n uint64 fee,\n bool paused\n ) external onlyGovernor {\n if (bridges[bridgeToken].allowed || bridgeToken == address(0)) revert InvalidToken();\n if (fee > BASE_PARAMS) revert TooHighParameterValue();\n BridgeDetails memory _bridge;\n _bridge.limit = limit;\n _bridge.hourlyLimit = hourlyLimit;\n _bridge.paused = paused;\n _bridge.fee = fee;\n _bridge.allowed = true;\n bridges[bridgeToken] = _bridge;\n bridgeTokensList.push(bridgeToken);\n emit BridgeTokenAdded(bridgeToken, limit, hourlyLimit, fee, paused);\n }\n\n /// @notice Removes support for a token\n /// @param bridgeToken Address of the bridge token to remove support for\n function removeBridgeToken(address bridgeToken) external onlyGovernor {\n if (IERC20(bridgeToken).balanceOf(address(this)) != 0) revert AssetStillControlledInReserves();\n delete bridges[bridgeToken];\n // Deletion from `bridgeTokensList` loop\n uint256 bridgeTokensListLength = bridgeTokensList.length;\n for (uint256 i; i < bridgeTokensListLength - 1; ++i) {\n if (bridgeTokensList[i] == bridgeToken) {\n // Replace the `bridgeToken` to remove with the last of the list\n bridgeTokensList[i] = bridgeTokensList[bridgeTokensListLength - 1];\n break;\n }\n }\n // Remove last element in array\n bridgeTokensList.pop();\n emit BridgeTokenRemoved(bridgeToken);\n }\n\n /// @notice Recovers any ERC20 token\n /// @dev Can be used to withdraw bridge tokens for them to be de-bridged on mainnet\n function recoverERC20(address tokenAddress, address to, uint256 amountToRecover) external onlyGovernor {\n IERC20(tokenAddress).safeTransfer(to, amountToRecover);\n emit Recovered(tokenAddress, to, amountToRecover);\n }\n\n /// @notice Updates the `limit` amount for `bridgeToken`\n function setLimit(address bridgeToken, uint256 limit) external onlyGovernorOrGuardian {\n if (!bridges[bridgeToken].allowed) revert InvalidToken();\n bridges[bridgeToken].limit = limit;\n emit BridgeTokenLimitUpdated(bridgeToken, limit);\n }\n\n /// @notice Updates the `hourlyLimit` amount for `bridgeToken`\n function setHourlyLimit(address bridgeToken, uint256 hourlyLimit) external onlyGovernorOrGuardian {\n if (!bridges[bridgeToken].allowed) revert InvalidToken();\n bridges[bridgeToken].hourlyLimit = hourlyLimit;\n emit BridgeTokenHourlyLimitUpdated(bridgeToken, hourlyLimit);\n }\n\n /// @notice Updates the `chainTotalHourlyLimit` amount\n function setChainTotalHourlyLimit(uint256 hourlyLimit) external onlyGovernorOrGuardian {\n chainTotalHourlyLimit = hourlyLimit;\n emit HourlyLimitUpdated(hourlyLimit);\n }\n\n /// @notice Updates the `fee` value for `bridgeToken`\n function setSwapFee(address bridgeToken, uint64 fee) external onlyGovernorOrGuardian {\n if (!bridges[bridgeToken].allowed) revert InvalidToken();\n if (fee > BASE_PARAMS) revert TooHighParameterValue();\n bridges[bridgeToken].fee = fee;\n emit BridgeTokenFeeUpdated(bridgeToken, fee);\n }\n\n /// @notice Pauses or unpauses swapping in and out for a token\n function toggleBridge(address bridgeToken) external onlyGovernorOrGuardian {\n if (!bridges[bridgeToken].allowed) revert InvalidToken();\n bool pausedStatus = bridges[bridgeToken].paused;\n bridges[bridgeToken].paused = !pausedStatus;\n emit BridgeTokenToggled(bridgeToken, !pausedStatus);\n }\n\n /// @notice Toggles fees for the address `theAddress`\n function toggleFeesForAddress(address theAddress) external onlyGovernorOrGuardian {\n uint256 feeExemptStatus = 1 - isFeeExempt[theAddress];\n isFeeExempt[theAddress] = feeExemptStatus;\n emit FeeToggled(theAddress, feeExemptStatus);\n }\n}\n" + }, + "contracts/agToken/polygon/utils/ERC20UpgradeableCustom.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (token/ERC20/ERC20.sol)\n\npragma solidity ^0.8.0;\n\nimport \"@openzeppelin/contracts-upgradeable/token/ERC20/IERC20Upgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/token/ERC20/extensions/IERC20MetadataUpgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/utils/ContextUpgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol\";\n\n/**\n * @dev Implementation of the {IERC20} interface modified by Angle Labs, Inc.\n *\n * This implementation has a custom burn function to avoid having a {Transfer} event to the zero address\n * in some specific burn cases to avoid having Polygon PoS bridge catching this event\n *\n * TIP: For a detailed writeup see our guide\n * https://forum.zeppelin.solutions/t/how-to-implement-erc20-supply-mechanisms/226[How\n * to implement supply mechanisms].\n *\n * We have followed general OpenZeppelin Contracts guidelines: functions revert\n * instead returning `false` on failure. This behavior is nonetheless\n * conventional and does not conflict with the expectations of ERC20\n * applications.\n *\n * Additionally, an {Approval} event is emitted on calls to {transferFrom}.\n * This allows applications to reconstruct the allowance for all accounts just\n * by listening to said events. Other implementations of the EIP may not emit\n * these events, as it isn't required by the specification.\n *\n * Finally, the non-standard {decreaseAllowance} and {increaseAllowance}\n * functions have been added to mitigate the well-known issues around setting\n * allowances. See {IERC20-approve}.\n */\ncontract ERC20UpgradeableCustom is Initializable, ContextUpgradeable, IERC20Upgradeable, IERC20MetadataUpgradeable {\n mapping(address => uint256) private _balances;\n\n mapping(address => mapping(address => uint256)) private _allowances;\n\n uint256 private _totalSupply;\n\n string private _name;\n string private _symbol;\n\n /**\n * @dev Sets the values for {name} and {symbol}.\n *\n * The default value of {decimals} is 18. To select a different value for\n * {decimals} you should overload it.\n *\n * All two of these values are immutable: they can only be set once during\n * construction.\n */\n //solhint-disable-next-line\n function __ERC20_init(string memory name_, string memory symbol_) internal onlyInitializing {\n __Context_init_unchained();\n __ERC20_init_unchained(name_, symbol_);\n }\n\n //solhint-disable-next-line\n function __ERC20_init_unchained(string memory name_, string memory symbol_) internal onlyInitializing {\n _name = name_;\n _symbol = symbol_;\n }\n\n /**\n * @dev Returns the name of the token.\n */\n function name() public view virtual override returns (string memory) {\n return _name;\n }\n\n /**\n * @dev Returns the symbol of the token, usually a shorter version of the\n * name.\n */\n function symbol() public view virtual override returns (string memory) {\n return _symbol;\n }\n\n /**\n * @dev Returns the number of decimals used to get its user representation.\n * For example, if `decimals` equals `2`, a balance of `505` tokens should\n * be displayed to a user as `5.05` (`505 / 10 ** 2`).\n *\n * Tokens usually opt for a value of 18, imitating the relationship between\n * Ether and Wei. This is the value {ERC20} uses, unless this function is\n * overridden;\n *\n * NOTE: This information is only used for _display_ purposes: it in\n * no way affects any of the arithmetic of the contract, including\n * {IERC20-balanceOf} and {IERC20-transfer}.\n */\n function decimals() public view virtual override returns (uint8) {\n return 18;\n }\n\n /**\n * @dev See {IERC20-totalSupply}.\n */\n function totalSupply() public view virtual override returns (uint256) {\n return _totalSupply;\n }\n\n /**\n * @dev See {IERC20-balanceOf}.\n */\n function balanceOf(address account) public view virtual override returns (uint256) {\n return _balances[account];\n }\n\n /**\n * @dev See {IERC20-transfer}.\n *\n * Requirements:\n *\n * - `recipient` cannot be the zero address.\n * - the caller must have a balance of at least `amount`.\n */\n function transfer(address recipient, uint256 amount) public virtual override returns (bool) {\n _transfer(_msgSender(), recipient, amount);\n return true;\n }\n\n /**\n * @dev See {IERC20-allowance}.\n */\n function allowance(address owner, address spender) public view virtual override returns (uint256) {\n return _allowances[owner][spender];\n }\n\n /**\n * @dev See {IERC20-approve}.\n *\n * Requirements:\n *\n * - `spender` cannot be the zero address.\n */\n function approve(address spender, uint256 amount) public virtual override returns (bool) {\n _approve(_msgSender(), spender, amount);\n return true;\n }\n\n /**\n * @dev See {IERC20-transferFrom}.\n *\n * Emits an {Approval} event indicating the updated allowance. This is not\n * required by the EIP. See the note at the beginning of {ERC20}.\n *\n * Requirements:\n *\n * - `sender` and `recipient` cannot be the zero address.\n * - `sender` must have a balance of at least `amount`.\n * - the caller must have allowance for `sender`'s tokens of at least\n * `amount`.\n */\n function transferFrom(address sender, address recipient, uint256 amount) public virtual override returns (bool) {\n _transfer(sender, recipient, amount);\n\n uint256 currentAllowance = _allowances[sender][_msgSender()];\n require(currentAllowance >= amount, \"ERC20: transfer amount exceeds allowance\");\n unchecked {\n _approve(sender, _msgSender(), currentAllowance - amount);\n }\n\n return true;\n }\n\n /**\n * @dev Atomically increases the allowance granted to `spender` by the caller.\n *\n * This is an alternative to {approve} that can be used as a mitigation for\n * problems described in {IERC20-approve}.\n *\n * Emits an {Approval} event indicating the updated allowance.\n *\n * Requirements:\n *\n * - `spender` cannot be the zero address.\n */\n function increaseAllowance(address spender, uint256 addedValue) public virtual returns (bool) {\n _approve(_msgSender(), spender, _allowances[_msgSender()][spender] + addedValue);\n return true;\n }\n\n /**\n * @dev Atomically decreases the allowance granted to `spender` by the caller.\n *\n * This is an alternative to {approve} that can be used as a mitigation for\n * problems described in {IERC20-approve}.\n *\n * Emits an {Approval} event indicating the updated allowance.\n *\n * Requirements:\n *\n * - `spender` cannot be the zero address.\n * - `spender` must have allowance for the caller of at least\n * `subtractedValue`.\n */\n function decreaseAllowance(address spender, uint256 subtractedValue) public virtual returns (bool) {\n uint256 currentAllowance = _allowances[_msgSender()][spender];\n require(currentAllowance >= subtractedValue, \"ERC20: decreased allowance below zero\");\n unchecked {\n _approve(_msgSender(), spender, currentAllowance - subtractedValue);\n }\n\n return true;\n }\n\n /**\n * @dev Moves `amount` of tokens from `sender` to `recipient`.\n *\n * This internal function is equivalent to {transfer}, and can be used to\n * e.g. implement automatic token fees, slashing mechanisms, etc.\n *\n * Emits a {Transfer} event.\n *\n * Requirements:\n *\n * - `sender` cannot be the zero address.\n * - `recipient` cannot be the zero address.\n * - `sender` must have a balance of at least `amount`.\n */\n function _transfer(address sender, address recipient, uint256 amount) internal virtual {\n require(sender != address(0), \"ERC20: transfer from the zero address\");\n require(recipient != address(0), \"ERC20: transfer to the zero address\");\n\n _beforeTokenTransfer(sender, recipient, amount);\n\n uint256 senderBalance = _balances[sender];\n require(senderBalance >= amount, \"ERC20: transfer amount exceeds balance\");\n unchecked {\n _balances[sender] = senderBalance - amount;\n }\n _balances[recipient] += amount;\n\n emit Transfer(sender, recipient, amount);\n\n _afterTokenTransfer(sender, recipient, amount);\n }\n\n /** @dev Creates `amount` tokens and assigns them to `account`, increasing\n * the total supply.\n *\n * Emits a {Transfer} event with `from` set to the zero address.\n *\n * Requirements:\n *\n * - `account` cannot be the zero address.\n */\n function _mint(address account, uint256 amount) internal virtual {\n require(account != address(0), \"ERC20: mint to the zero address\");\n\n _beforeTokenTransfer(address(0), account, amount);\n\n _totalSupply += amount;\n _balances[account] += amount;\n emit Transfer(address(0), account, amount);\n\n _afterTokenTransfer(address(0), account, amount);\n }\n\n /**\n * @dev Destroys `amount` tokens from `account`, reducing the\n * total supply.\n *\n * Emits a {Transfer} event with `to` set to the zero address.\n *\n * Requirements:\n *\n * - `account` cannot be the zero address.\n * - `account` must have at least `amount` tokens.\n */\n function _burn(address account, uint256 amount) internal virtual {\n require(account != address(0), \"ERC20: burn from the zero address\");\n\n _beforeTokenTransfer(account, address(0), amount);\n\n uint256 accountBalance = _balances[account];\n require(accountBalance >= amount, \"ERC20: burn amount exceeds balance\");\n unchecked {\n _balances[account] = accountBalance - amount;\n }\n _totalSupply -= amount;\n\n emit Transfer(account, address(0), amount);\n\n _afterTokenTransfer(account, address(0), amount);\n }\n\n /**\n * @dev Destroys `amount` tokens from `account`, reducing the\n * total supply.\n *\n * Contrary to the other `burn` function, the {Transfer} event is not to the zero address\n * but rather to this address: the reason is that not all burn events should be caught up\n * by the PoS bridge\n *\n * Requirements:\n *\n * - `account` cannot be the zero address.\n * - `account` must have at least `amount` tokens.\n */\n function _burnCustom(address account, uint256 amount) internal virtual {\n require(account != address(0), \"ERC20: burn from the zero address\");\n\n _beforeTokenTransfer(account, address(0), amount);\n\n uint256 accountBalance = _balances[account];\n require(accountBalance >= amount, \"ERC20: burn amount exceeds balance\");\n unchecked {\n _balances[account] = accountBalance - amount;\n }\n _totalSupply -= amount;\n\n emit Transfer(account, address(this), amount);\n\n _afterTokenTransfer(account, address(0), amount);\n }\n\n /**\n * @dev Sets `amount` as the allowance of `spender` over the `owner` s tokens.\n *\n * This internal function is equivalent to `approve`, and can be used to\n * e.g. set automatic allowances for certain subsystems, etc.\n *\n * Emits an {Approval} event.\n *\n * Requirements:\n *\n * - `owner` cannot be the zero address.\n * - `spender` cannot be the zero address.\n */\n function _approve(address owner, address spender, uint256 amount) internal virtual {\n require(owner != address(0), \"ERC20: approve from the zero address\");\n require(spender != address(0), \"ERC20: approve to the zero address\");\n\n _allowances[owner][spender] = amount;\n emit Approval(owner, spender, amount);\n }\n\n /**\n * @dev Hook that is called before any transfer of tokens. This includes\n * minting and burning.\n *\n * Calling conditions:\n *\n * - when `from` and `to` are both non-zero, `amount` of `from`'s tokens\n * will be transferred to `to`.\n * - when `from` is zero, `amount` tokens will be minted for `to`.\n * - when `to` is zero, `amount` of `from`'s tokens will be burned.\n * - `from` and `to` are never both zero.\n *\n * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].\n */\n function _beforeTokenTransfer(address from, address to, uint256 amount) internal virtual {}\n\n /**\n * @dev Hook that is called after any transfer of tokens. This includes\n * minting and burning.\n *\n * Calling conditions:\n *\n * - when `from` and `to` are both non-zero, `amount` of `from`'s tokens\n * has been transferred to `to`.\n * - when `from` is zero, `amount` tokens have been minted for `to`.\n * - when `to` is zero, `amount` of `from`'s tokens have been burned.\n * - `from` and `to` are never both zero.\n *\n * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].\n */\n function _afterTokenTransfer(address from, address to, uint256 amount) internal virtual {}\n\n uint256[45] private __gap;\n}\n" + }, + "contracts/coreBorrow/CoreBorrow.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\n/*\n * █ \n ***** ▓▓▓ \n * ▓▓▓▓▓▓▓ \n * ///. ▓▓▓▓▓▓▓▓▓▓▓▓▓ \n ***** //////// ▓▓▓▓▓▓▓ \n * ///////////// ▓▓▓ \n ▓▓ ////////////////// █ ▓▓ \n ▓▓ ▓▓ /////////////////////// ▓▓ ▓▓ \n ▓▓ ▓▓ //////////////////////////// ▓▓ ▓▓ \n ▓▓ ▓▓ /////////▓▓▓///////▓▓▓///////// ▓▓ ▓▓ \n ▓▓ ,////////////////////////////////////// ▓▓ ▓▓ \n ▓▓ ////////////////////////////////////////// ▓▓ \n ▓▓ //////////////////////▓▓▓▓///////////////////// \n ,//////////////////////////////////////////////////// \n .////////////////////////////////////////////////////////// \n .//////////////////////////██.,//////////////////////////█ \n .//////////////////////████..,./////////////////////██ \n ...////////////////███████.....,.////////////////███ \n ,.,////////////████████ ........,///////////████ \n .,.,//////█████████ ,.......///////████ \n ,..//████████ ........./████ \n ..,██████ .....,███ \n .██ ,.,█ \n \n \n \n ▓▓ ▓▓▓▓▓▓▓▓▓▓ ▓▓▓▓▓▓▓▓▓▓ ▓▓ ▓▓▓▓▓▓▓▓▓▓ \n ▓▓▓▓▓▓ ▓▓▓ ▓▓▓ ▓▓▓ ▓▓ ▓▓ ▓▓▓▓ \n ▓▓▓ ▓▓▓ ▓▓▓ ▓▓▓ ▓▓▓ ▓▓▓ ▓▓ ▓▓▓▓▓ \n ▓▓▓ ▓▓ ▓▓▓ ▓▓▓ ▓▓▓▓▓▓▓▓▓▓ ▓▓▓▓▓▓▓▓▓▓ ▓▓▓▓▓▓▓▓▓▓ \n*/\n\npragma solidity ^0.8.12;\n\nimport \"@openzeppelin/contracts-upgradeable/access/AccessControlEnumerableUpgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol\";\n\nimport \"../interfaces/ICoreBorrow.sol\";\nimport \"../interfaces/IFlashAngle.sol\";\nimport \"../interfaces/ITreasury.sol\";\n\n/// @title CoreBorrow\n/// @author Angle Labs, Inc.\n/// @notice Core contract of the borrowing module. This contract handles the access control across all contracts\n/// (it is read by all treasury contracts), and manages the `flashLoanModule`. It has no minting rights over the\n/// stablecoin contracts\ncontract CoreBorrow is ICoreBorrow, Initializable, AccessControlEnumerableUpgradeable {\n /// @notice Role for guardians\n bytes32 public constant GUARDIAN_ROLE = keccak256(\"GUARDIAN_ROLE\");\n /// @notice Role for governors\n bytes32 public constant GOVERNOR_ROLE = keccak256(\"GOVERNOR_ROLE\");\n /// @notice Role for treasury contract\n bytes32 public constant FLASHLOANER_TREASURY_ROLE = keccak256(\"FLASHLOANER_TREASURY_ROLE\");\n\n // ============================= Reference =====================================\n\n /// @notice Reference to the `flashLoanModule` with minting rights over the different stablecoins of the protocol\n address public flashLoanModule;\n\n // =============================== Events ======================================\n\n event FlashLoanModuleUpdated(address indexed _flashloanModule);\n event CoreUpdated(address indexed _core);\n\n // =============================== Errors ======================================\n\n error InvalidCore();\n error IncompatibleGovernorAndGuardian();\n error NotEnoughGovernorsLeft();\n error ZeroAddress();\n\n /// @notice Initializes the `CoreBorrow` contract and the access control of the borrowing module\n /// @param governor Address of the governor of the Angle Protocol\n /// @param guardian Guardian address of the protocol\n function initialize(address governor, address guardian) public initializer {\n if (governor == address(0) || guardian == address(0)) revert ZeroAddress();\n if (governor == guardian) revert IncompatibleGovernorAndGuardian();\n _setupRole(GOVERNOR_ROLE, governor);\n _setupRole(GUARDIAN_ROLE, guardian);\n _setupRole(GUARDIAN_ROLE, governor);\n _setRoleAdmin(GUARDIAN_ROLE, GOVERNOR_ROLE);\n _setRoleAdmin(GOVERNOR_ROLE, GOVERNOR_ROLE);\n _setRoleAdmin(FLASHLOANER_TREASURY_ROLE, GOVERNOR_ROLE);\n }\n\n /// @custom:oz-upgrades-unsafe-allow constructor\n constructor() initializer {}\n\n // =========================== View Functions ==================================\n\n /// @inheritdoc ICoreBorrow\n function isFlashLoanerTreasury(address treasury) external view returns (bool) {\n return hasRole(FLASHLOANER_TREASURY_ROLE, treasury);\n }\n\n /// @inheritdoc ICoreBorrow\n function isGovernor(address admin) external view returns (bool) {\n return hasRole(GOVERNOR_ROLE, admin);\n }\n\n /// @inheritdoc ICoreBorrow\n function isGovernorOrGuardian(address admin) external view returns (bool) {\n return hasRole(GUARDIAN_ROLE, admin);\n }\n\n // =========================== Governor Functions ==============================\n\n /// @notice Grants the `FLASHLOANER_TREASURY_ROLE` to a `treasury` contract\n /// @param treasury Contract to grant the role to\n /// @dev This function can be used to allow flash loans on a stablecoin of the protocol\n function addFlashLoanerTreasuryRole(address treasury) external {\n grantRole(FLASHLOANER_TREASURY_ROLE, treasury);\n address _flashLoanModule = flashLoanModule;\n if (_flashLoanModule != address(0)) {\n // This call will revert if `treasury` is the zero address or if it is not linked\n // to this `CoreBorrow` contract\n ITreasury(treasury).setFlashLoanModule(_flashLoanModule);\n IFlashAngle(_flashLoanModule).addStablecoinSupport(treasury);\n }\n }\n\n /// @notice Adds a governor in the protocol\n /// @param governor Address to grant the role to\n /// @dev It is necessary to call this function to grant a governor role to make sure\n /// all governors also have the guardian role\n function addGovernor(address governor) external {\n grantRole(GOVERNOR_ROLE, governor);\n grantRole(GUARDIAN_ROLE, governor);\n }\n\n /// @notice Revokes the flash loan ability for a stablecoin\n /// @param treasury Treasury address associated with the stablecoin for which flash loans\n /// should no longer be available\n function removeFlashLoanerTreasuryRole(address treasury) external {\n revokeRole(FLASHLOANER_TREASURY_ROLE, treasury);\n ITreasury(treasury).setFlashLoanModule(address(0));\n address _flashLoanModule = flashLoanModule;\n if (_flashLoanModule != address(0)) {\n IFlashAngle(flashLoanModule).removeStablecoinSupport(treasury);\n }\n }\n\n /// @notice Revokes a governor from the protocol\n /// @param governor Address to remove the role to\n /// @dev It is necessary to call this function to remove a governor role to make sure\n /// the address also loses its guardian role\n function removeGovernor(address governor) external {\n if (getRoleMemberCount(GOVERNOR_ROLE) <= 1) revert NotEnoughGovernorsLeft();\n revokeRole(GUARDIAN_ROLE, governor);\n revokeRole(GOVERNOR_ROLE, governor);\n }\n\n /// @notice Changes the `flashLoanModule` of the protocol\n /// @param _flashLoanModule Address of the new flash loan module\n function setFlashLoanModule(address _flashLoanModule) external onlyRole(GOVERNOR_ROLE) {\n if (_flashLoanModule != address(0)) {\n if (address(IFlashAngle(_flashLoanModule).core()) != address(this)) revert InvalidCore();\n }\n uint256 count = getRoleMemberCount(FLASHLOANER_TREASURY_ROLE);\n for (uint256 i; i < count; ++i) {\n ITreasury(getRoleMember(FLASHLOANER_TREASURY_ROLE, i)).setFlashLoanModule(_flashLoanModule);\n }\n flashLoanModule = _flashLoanModule;\n emit FlashLoanModuleUpdated(_flashLoanModule);\n }\n\n /// @notice Changes the core contract of the protocol\n /// @param _core New core contract\n /// @dev This function verifies that all governors of the current core contract are also governors\n /// of the new core contract. It also notifies the `flashLoanModule` of the change.\n /// @dev Governance wishing to change the core contract should also make sure to call `setCore`\n /// in the different treasury contracts\n function setCore(ICoreBorrow _core) external onlyRole(GOVERNOR_ROLE) {\n uint256 count = getRoleMemberCount(GOVERNOR_ROLE);\n bool success;\n for (uint256 i; i < count; ++i) {\n success = _core.isGovernor(getRoleMember(GOVERNOR_ROLE, i));\n if (!success) break;\n }\n if (!success) revert InvalidCore();\n address _flashLoanModule = flashLoanModule;\n if (_flashLoanModule != address(0)) IFlashAngle(_flashLoanModule).setCore(address(_core));\n emit CoreUpdated(address(_core));\n }\n}\n" + }, + "contracts/deprecated/AgTokenIntermediateUpgrade.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\nimport \"../interfaces/IAgToken.sol\";\nimport \"../interfaces/coreModule/IStableMaster.sol\";\n// OpenZeppelin may update its version of the ERC20PermitUpgradeable token\nimport \"@openzeppelin/contracts-upgradeable/token/ERC20/extensions/draft-ERC20PermitUpgradeable.sol\";\n\n/// @title AgTokenIntermediateUpgrade\n/// @author Angle Labs, Inc.\n/// @notice Base contract for agToken, that is to say Angle's stablecoins\n/// @dev This contract is used to create and handle the stablecoins of Angle protocol\n/// @dev It is still possible for any address to burn its agTokens without redeeming collateral in exchange\n/// @dev This contract is the upgraded version of the AgToken that was first deployed on Ethereum mainnet and is used to\n/// add other minters as needed by AMOs\ncontract AgTokenIntermediateUpgrade is ERC20PermitUpgradeable {\n // ========================= References to other contracts =====================\n\n /// @notice Reference to the `StableMaster` contract associated to this `AgToken`\n address public stableMaster;\n\n // ============================= Constructor ===================================\n\n /// @notice Initializes the `AgToken` contract\n /// @param name_ Name of the token\n /// @param symbol_ Symbol of the token\n /// @param stableMaster_ Reference to the `StableMaster` contract associated to this agToken\n /// @dev By default, agTokens are ERC-20 tokens with 18 decimals\n function initialize(string memory name_, string memory symbol_, address stableMaster_) external initializer {\n __ERC20Permit_init(name_);\n __ERC20_init(name_, symbol_);\n require(stableMaster_ != address(0), \"0\");\n stableMaster = stableMaster_;\n }\n\n /// @custom:oz-upgrades-unsafe-allow constructor\n constructor() initializer {}\n\n // ======= Added Parameters and Variables from the first implementation ========\n\n /// @notice Checks whether an address has the right to mint agTokens\n mapping(address => bool) public isMinter;\n\n // =============================== Added Events ================================\n\n event MinterToggled(address indexed minter);\n\n // =============================== Setup Function ==============================\n\n /// @notice Sets up the minter role and gives it to the governor\n /// @dev This function just has to be called once\n function setUpMinter() external {\n address governor = 0xdC4e6DFe07EFCa50a197DF15D9200883eF4Eb1c8;\n require(msg.sender == governor);\n isMinter[governor] = true;\n emit MinterToggled(governor);\n }\n\n // =============================== Modifiers ===================================\n\n /// @notice Checks whether the sender has the minting right\n modifier onlyMinter() {\n require(isMinter[msg.sender] || msg.sender == stableMaster, \"35\");\n _;\n }\n\n // ========================= External Functions ================================\n // The following functions allow anyone to burn stablecoins without redeeming collateral\n // in exchange for that\n\n /// @notice Destroys `amount` token from the caller without giving collateral back\n /// @param amount Amount to burn\n /// @param poolManager Reference to the `PoolManager` contract for which the `stocksUsers` will\n /// need to be updated\n /// @dev When calling this function, people should specify the `poolManager` for which they want to decrease\n /// the `stocksUsers`: this is a way for the protocol to maintain healthy accounting variables\n function burnNoRedeem(uint256 amount, address poolManager) external {\n _burn(msg.sender, amount);\n IStableMaster(stableMaster).updateStocksUsers(amount, poolManager);\n }\n\n /// @notice Burns `amount` of agToken on behalf of another account without redeeming collateral back\n /// @param account Account to burn on behalf of\n /// @param amount Amount to burn\n /// @param poolManager Reference to the `PoolManager` contract for which the `stocksUsers` will need to be updated\n function burnFromNoRedeem(address account, uint256 amount, address poolManager) external {\n _burnFromNoRedeem(amount, account, msg.sender);\n IStableMaster(stableMaster).updateStocksUsers(amount, poolManager);\n }\n\n // ======================= Minter Role Only Functions ==========================\n\n /// @notice Burns `amount` tokens from a `burner` address\n /// @param amount Amount of tokens to burn\n /// @param burner Address to burn from\n /// @dev This method is to be called by a contract with a minter right on the AgToken after being\n /// requested to do so by an address willing to burn tokens from its address\n function burnSelf(uint256 amount, address burner) external onlyMinter {\n _burn(burner, amount);\n }\n\n /// @notice Burns `amount` tokens from a `burner` address after being asked to by `sender`\n /// @param amount Amount of tokens to burn\n /// @param burner Address to burn from\n /// @param sender Address which requested the burn from `burner`\n /// @dev This method is to be called by a contract with the minter right after being requested\n /// to do so by a `sender` address willing to burn tokens from another `burner` address\n /// @dev The method checks the allowance between the `sender` and the `burner`\n function burnFrom(uint256 amount, address burner, address sender) external onlyMinter {\n _burnFromNoRedeem(amount, burner, sender);\n }\n\n /// @notice Lets the `StableMaster` contract or another whitelisted contract mint agTokens\n /// @param account Address to mint to\n /// @param amount Amount to mint\n /// @dev The contracts allowed to issue agTokens are the `StableMaster` contract, `VaultManager` contracts\n /// associated to this stablecoin as well as the flash loan module (if activated) and potentially contracts\n /// whitelisted by governance\n function mint(address account, uint256 amount) external onlyMinter {\n _mint(account, amount);\n }\n\n // ======================= Minter Only Functions ===============================\n\n /// @notice Adds a minter in the contract\n /// @param minter Minter address to add\n function addMinter(address minter) external onlyMinter {\n isMinter[minter] = true;\n emit MinterToggled(minter);\n }\n\n /// @notice Removes a minter from the contract\n /// @param minter Minter address to remove\n /// @dev This function can at the moment only be called by a minter wishing to revoke itself\n function removeMinter(address minter) external {\n require(msg.sender == minter && isMinter[msg.sender], \"36\");\n isMinter[minter] = false;\n emit MinterToggled(minter);\n }\n\n // ============================ Internal Function ==============================\n\n /// @notice Internal version of the function `burnFromNoRedeem`\n /// @param amount Amount to burn\n /// @dev It is at the level of this function that allowance checks are performed\n function _burnFromNoRedeem(uint256 amount, address burner, address sender) internal {\n if (burner != sender) {\n uint256 currentAllowance = allowance(burner, sender);\n require(currentAllowance >= amount, \"23\");\n _approve(burner, sender, currentAllowance - amount);\n }\n _burn(burner, amount);\n }\n}\n" + }, + "contracts/deprecated/layerZero/OldLayerZeroBridgeToken.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.12;\n\nimport \"./OldOFTCore.sol\";\nimport \"../../interfaces/IAgTokenSideChainMultiBridge.sol\";\nimport \"@openzeppelin/contracts-upgradeable/security/PausableUpgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/token/ERC20/ERC20Upgradeable.sol\";\n\n/// @title LayerZeroBridgeToken\n/// @author Angle Labs, Inc., forked from https://github.com/LayerZero-Labs/solidity-examples/blob/main/contracts/token/oft/OFT.sol\n/// @notice Contract to be deployed on a L2/sidechain for bridging an AgToken using a bridge intermediate token and LayerZero\ncontract OldLayerZeroBridgeToken is OldOFTCore, ERC20Upgradeable, PausableUpgradeable {\n /// @notice Address of the bridgeable token\n /// @dev Immutable\n IAgTokenSideChainMultiBridge public canonicalToken;\n\n // =============================== Errors ================================\n\n error InvalidAllowance();\n\n // ============================= Constructor ===================================\n\n /// @notice Initializes the contract\n /// @param _name Name of the token corresponding to this contract\n /// @param _symbol Symbol of the token corresponding to this contract\n /// @param _lzEndpoint Layer zero endpoint to pass messages\n /// @param _treasury Address of the treasury contract used for access control\n /// @param initialSupply Initial supply to mint to the canonical token address\n /// @dev The initial supply corresponds to the initial amount that could be bridged using this OFT\n function initialize(\n string memory _name,\n string memory _symbol,\n address _lzEndpoint,\n address _treasury,\n uint256 initialSupply\n ) external initializer {\n __ERC20_init_unchained(_name, _symbol);\n __LzAppUpgradeable_init(_lzEndpoint, _treasury);\n\n canonicalToken = IAgTokenSideChainMultiBridge(address(ITreasury(_treasury).stablecoin()));\n _approve(address(this), address(canonicalToken), type(uint256).max);\n _mint(address(canonicalToken), initialSupply);\n }\n\n /// @custom:oz-upgrades-unsafe-allow constructor\n constructor() initializer {}\n\n // ==================== External Permissionless Functions ======================\n\n function sendWithPermit(\n uint16 _dstChainId,\n bytes memory _toAddress,\n uint256 _amount,\n address payable _refundAddress,\n address _zroPaymentAddress,\n bytes memory _adapterParams,\n uint256 deadline,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) public payable override {\n canonicalToken.permit(msg.sender, address(this), _amount, deadline, v, r, s);\n send(_dstChainId, _toAddress, _amount, _refundAddress, _zroPaymentAddress, _adapterParams);\n }\n\n function withdraw(uint256 amount, address recipient) external override returns (uint256 amountMinted) {\n // Does not check allowances as transfers from `msg.sender`\n _transfer(msg.sender, address(this), amount);\n amountMinted = canonicalToken.swapIn(address(this), amount, recipient);\n uint256 leftover = balanceOf(address(this));\n if (leftover != 0) {\n _transfer(address(this), msg.sender, leftover);\n }\n }\n\n // ============================= Internal Functions ===================================\n\n function _debitFrom(\n uint16,\n bytes memory,\n uint256 _amount\n ) internal override whenNotPaused returns (uint256 amountSwapped) {\n // No need to use safeTransferFrom as we know this implementation reverts on failure\n canonicalToken.transferFrom(msg.sender, address(this), _amount);\n\n // Swap canonical for this bridge token. There may be some fees\n amountSwapped = canonicalToken.swapOut(address(this), _amount, address(this));\n _burn(address(this), amountSwapped);\n }\n\n function _debitCreditFrom(uint16, bytes memory, uint256 _amount) internal override whenNotPaused returns (uint256) {\n _burn(msg.sender, _amount);\n return _amount;\n }\n\n function _creditTo(\n uint16,\n address _toAddress,\n uint256 _amount\n ) internal override whenNotPaused returns (uint256 amountMinted) {\n _mint(address(this), _amount);\n amountMinted = canonicalToken.swapIn(address(this), _amount, _toAddress);\n uint256 leftover = balanceOf(address(this));\n if (leftover != 0) {\n _transfer(address(this), _toAddress, leftover);\n }\n }\n\n // ======================= View Functions ================================\n\n /// @inheritdoc ERC165Upgradeable\n function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {\n return\n interfaceId == type(IOFT).interfaceId ||\n interfaceId == type(IERC20).interfaceId ||\n super.supportsInterface(interfaceId);\n }\n\n // ======================= Governance Functions ================================\n\n /// @notice Mints the intermediate contract to the `canonicalToken`\n /// @dev Used to increase the bridging capacity\n function mint(uint256 amount) external onlyGovernorOrGuardian {\n _mint(address(canonicalToken), amount);\n }\n\n /// @notice Burns the intermediate contract from the `canonicalToken`\n /// @dev Used to decrease the bridging capacity\n function burn(uint256 amount) external onlyGovernorOrGuardian {\n _burn(address(canonicalToken), amount);\n }\n\n /// @notice Increases allowance of the `canonicalToken`\n function setupAllowance() public onlyGovernorOrGuardian {\n _approve(address(this), address(canonicalToken), type(uint256).max);\n }\n\n /// @notice Pauses bridging through the contract\n /// @param pause Future pause status\n function pauseSendTokens(bool pause) external onlyGovernorOrGuardian {\n pause ? _pause() : _unpause();\n }\n\n uint256[49] private __gap;\n}\n" + }, + "contracts/deprecated/layerZero/OldNonblockingLzApp.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.12;\n\nimport \"@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol\";\nimport \"../../interfaces/external/layerZero/ILayerZeroReceiver.sol\";\nimport \"../../interfaces/external/layerZero/ILayerZeroUserApplicationConfig.sol\";\nimport \"../../interfaces/external/layerZero/ILayerZeroEndpoint.sol\";\nimport \"../../interfaces/ITreasury.sol\";\n\n/// @title OldNonblockingLzApp\n/// @author Angle Labs, Inc., forked from https://github.com/LayerZero-Labs/solidity-examples/\n/// @notice Base contract for bridging using LayerZero\nabstract contract OldNonblockingLzApp is Initializable, ILayerZeroReceiver, ILayerZeroUserApplicationConfig {\n /// @notice Layer Zero endpoint\n ILayerZeroEndpoint public lzEndpoint;\n\n /// @notice Maps chainIds to failed messages to retry them\n mapping(uint16 => mapping(bytes => mapping(uint64 => bytes32))) public failedMessages;\n\n /// @notice Maps chainIds to their OFT address\n mapping(uint16 => bytes) public trustedRemoteLookup;\n\n /// @notice Reference to the treasury contract to fetch access control\n address public treasury;\n\n // ================================== Events ===================================\n\n event SetTrustedRemote(uint16 _srcChainId, bytes _srcAddress);\n event MessageFailed(uint16 _srcChainId, bytes _srcAddress, uint64 _nonce, bytes _payload);\n\n // =============================== Errors ================================\n\n error NotGovernor();\n error NotGovernorOrGuardian();\n error InsufficientGas();\n error InvalidEndpoint();\n error InvalidSource();\n error InvalidCaller();\n error InvalidParams();\n error InvalidPayload();\n error ZeroAddress();\n\n // ============================= Constructor ===================================\n\n //solhint-disable-next-line\n function __LzAppUpgradeable_init(address _endpoint, address _treasury) internal {\n if (_endpoint == address(0) || _treasury == address(0)) revert ZeroAddress();\n lzEndpoint = ILayerZeroEndpoint(_endpoint);\n treasury = _treasury;\n }\n\n // =============================== Modifiers ===================================\n\n /// @notice Checks whether the `msg.sender` has the governor role or the guardian role\n modifier onlyGovernorOrGuardian() {\n if (!ITreasury(treasury).isGovernorOrGuardian(msg.sender)) revert NotGovernorOrGuardian();\n _;\n }\n\n // ==================== External Permissionless Functions ======================\n\n /// @notice Receives a message from the LZ endpoint and process it\n /// @param _srcChainId ChainId of the source chain - LayerZero standard\n /// @param _srcAddress Sender of the source chain\n /// @param _nonce Nounce of the message\n /// @param _payload Data: recipient address and amount\n function lzReceive(\n uint16 _srcChainId,\n bytes memory _srcAddress,\n uint64 _nonce,\n bytes memory _payload\n ) public virtual override {\n // lzReceive must be called by the endpoint for security\n if (msg.sender != address(lzEndpoint)) revert InvalidEndpoint();\n\n bytes memory trustedRemote = trustedRemoteLookup[_srcChainId];\n // if will still block the message pathway from (srcChainId, srcAddress). should not receive message from untrusted remote.\n if (_srcAddress.length != trustedRemote.length || keccak256(_srcAddress) != keccak256(trustedRemote))\n revert InvalidSource();\n\n _blockingLzReceive(_srcChainId, _srcAddress, _nonce, _payload);\n }\n\n /// @notice Retries a message that previously failed and was stored\n /// @param _srcChainId ChainId of the source chain - LayerZero standard\n /// @param _srcAddress Sender of the source chain\n /// @param _nonce Nounce of the message\n /// @param _payload Data: recipient address and amount\n function retryMessage(\n uint16 _srcChainId,\n bytes memory _srcAddress,\n uint64 _nonce,\n bytes memory _payload\n ) public payable virtual {\n // assert there is message to retry\n bytes32 payloadHash = failedMessages[_srcChainId][_srcAddress][_nonce];\n if (payloadHash == bytes32(0) || keccak256(_payload) != payloadHash) revert InvalidPayload();\n // clear the stored message\n failedMessages[_srcChainId][_srcAddress][_nonce] = bytes32(0);\n // execute the message. revert if it fails again\n _nonblockingLzReceive(_srcChainId, _srcAddress, _nonce, _payload);\n }\n\n // ============================= Internal Functions ===================================\n\n /// @notice Handles message receptions in a non blocking way\n /// @param _srcChainId ChainId of the source chain - LayerZero standard\n /// @param _srcAddress Sender of the source chain\n /// @param _nonce Nounce of the message\n /// @param _payload Data: recipient address and amount\n /// @dev public for the needs of try / catch but effectively internal\n function nonblockingLzReceive(\n uint16 _srcChainId,\n bytes memory _srcAddress,\n uint64 _nonce,\n bytes memory _payload\n ) public virtual {\n // only internal transaction\n if (msg.sender != address(this)) revert InvalidCaller();\n _nonblockingLzReceive(_srcChainId, _srcAddress, _nonce, _payload);\n }\n\n /// @notice Handles message receptions in a non blocking way\n /// @param _srcChainId ChainId of the source chain - LayerZero standard\n /// @param _srcAddress Sender of the source chain\n /// @param _nonce Nounce of the message\n /// @param _payload Data: recipient address and amount\n function _nonblockingLzReceive(\n uint16 _srcChainId,\n bytes memory _srcAddress,\n uint64 _nonce,\n bytes memory _payload\n ) internal virtual;\n\n /// @notice Handles message receptions in a blocking way\n /// @param _srcChainId ChainId of the source chain - LayerZero standard\n /// @param _srcAddress Sender of the source chain\n /// @param _nonce Nounce of the message\n /// @param _payload Data: recipient address and amount\n function _blockingLzReceive(\n uint16 _srcChainId,\n bytes memory _srcAddress,\n uint64 _nonce,\n bytes memory _payload\n ) internal {\n // try-catch all errors/exceptions\n try this.nonblockingLzReceive(_srcChainId, _srcAddress, _nonce, _payload) {\n // do nothing\n } catch {\n // error / exception\n failedMessages[_srcChainId][_srcAddress][_nonce] = keccak256(_payload);\n emit MessageFailed(_srcChainId, _srcAddress, _nonce, _payload);\n }\n }\n\n /// @notice Sends a message to the LZ endpoint and process it\n /// @param _dstChainId L0 defined chain id to send tokens too\n /// @param _payload Data: recipient address and amount\n /// @param _refundAddress Address LayerZero refunds if too much message fee is sent\n /// @param _zroPaymentAddress Set to address(0x0) if not paying in ZRO (LayerZero Token)\n /// @param _adapterParams Flexible bytes array to indicate messaging adapter services in L0\n function _lzSend(\n uint16 _dstChainId,\n bytes memory _payload,\n address payable _refundAddress,\n address _zroPaymentAddress,\n bytes memory _adapterParams\n ) internal virtual {\n bytes memory trustedRemote = trustedRemoteLookup[_dstChainId];\n if (trustedRemote.length == 0) revert InvalidSource();\n //solhint-disable-next-line\n lzEndpoint.send{ value: msg.value }(\n _dstChainId,\n trustedRemote,\n _payload,\n _refundAddress,\n _zroPaymentAddress,\n _adapterParams\n );\n }\n\n // ======================= Governance Functions ================================\n\n /// @notice Sets the corresponding address on an other chain.\n /// @param _srcChainId ChainId of the source chain - LayerZero standard\n /// @param _srcAddress Address on the source chain\n /// @dev Used for both receiving and sending message\n /// @dev There can only be one trusted source per chain\n /// @dev Allows owner to set it multiple times.\n function setTrustedRemote(uint16 _srcChainId, bytes calldata _srcAddress) external onlyGovernorOrGuardian {\n trustedRemoteLookup[_srcChainId] = _srcAddress;\n emit SetTrustedRemote(_srcChainId, _srcAddress);\n }\n\n /// @notice Fetches the default LZ config\n function getConfig(\n uint16 _version,\n uint16 _chainId,\n address,\n uint256 _configType\n ) external view returns (bytes memory) {\n return lzEndpoint.getConfig(_version, _chainId, address(this), _configType);\n }\n\n /// @notice Overrides the default LZ config\n function setConfig(\n uint16 _version,\n uint16 _chainId,\n uint256 _configType,\n bytes calldata _config\n ) external override onlyGovernorOrGuardian {\n lzEndpoint.setConfig(_version, _chainId, _configType, _config);\n }\n\n /// @notice Overrides the default LZ config\n function setSendVersion(uint16 _version) external override onlyGovernorOrGuardian {\n lzEndpoint.setSendVersion(_version);\n }\n\n /// @notice Overrides the default LZ config\n function setReceiveVersion(uint16 _version) external override onlyGovernorOrGuardian {\n lzEndpoint.setReceiveVersion(_version);\n }\n\n /// @notice Unpauses the receive functionalities\n function forceResumeReceive(\n uint16 _srcChainId,\n bytes calldata _srcAddress\n ) external override onlyGovernorOrGuardian {\n lzEndpoint.forceResumeReceive(_srcChainId, _srcAddress);\n }\n\n // ======================= View Functions ================================\n\n /// @notice Checks if the `_srcAddress` corresponds to the trusted source\n function isTrustedRemote(uint16 _srcChainId, bytes calldata _srcAddress) external view returns (bool) {\n bytes memory trustedSource = trustedRemoteLookup[_srcChainId];\n return keccak256(trustedSource) == keccak256(_srcAddress);\n }\n\n uint256[46] private __gap;\n}\n" + }, + "contracts/deprecated/layerZero/OldOFTCore.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.12;\n\nimport \"./OldNonblockingLzApp.sol\";\nimport \"../../agToken/layerZero/utils/IOFTCore.sol\";\nimport \"@openzeppelin/contracts-upgradeable/utils/introspection/ERC165Upgradeable.sol\";\n\n/// @title OFTCore\n/// @author Forked from https://github.com/LayerZero-Labs/solidity-examples/blob/main/contracts/token/oft/OFTCore.sol\n/// but with slight modifications from the Angle Labs, Inc. which added return values to the `_creditTo` and `_debitFrom` functions\n/// @notice Base contract for bridging using LayerZero\nabstract contract OldOFTCore is OldNonblockingLzApp, ERC165Upgradeable, IOFTCore {\n // ==================== External Permissionless Functions ======================\n\n /// @inheritdoc IOFTCore\n function sendWithPermit(\n uint16 _dstChainId,\n bytes memory _toAddress,\n uint256 _amount,\n address payable _refundAddress,\n address _zroPaymentAddress,\n bytes memory _adapterParams,\n uint256 deadline,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) public payable virtual;\n\n /// @inheritdoc IOFTCore\n function send(\n uint16 _dstChainId,\n bytes memory _toAddress,\n uint256 _amount,\n address payable _refundAddress,\n address _zroPaymentAddress,\n bytes memory _adapterParams\n ) public payable virtual {\n _amount = _debitFrom(_dstChainId, _toAddress, _amount);\n\n bytes memory payload = abi.encode(_toAddress, _amount);\n _lzSend(_dstChainId, payload, _refundAddress, _zroPaymentAddress, _adapterParams);\n\n uint64 nonce = lzEndpoint.getOutboundNonce(_dstChainId, address(this));\n emit SendToChain(msg.sender, _dstChainId, _toAddress, _amount, nonce);\n }\n\n /// @inheritdoc IOFTCore\n function sendCredit(\n uint16 _dstChainId,\n bytes memory _toAddress,\n uint256 _amount,\n address payable _refundAddress,\n address _zroPaymentAddress,\n bytes memory _adapterParams\n ) public payable virtual {\n _amount = _debitCreditFrom(_dstChainId, _toAddress, _amount);\n\n _send(_dstChainId, _toAddress, _amount, _refundAddress, _zroPaymentAddress, _adapterParams);\n }\n\n /// @inheritdoc IOFTCore\n function withdraw(uint256 amount, address recipient) external virtual returns (uint256);\n\n // =========================== Internal Functions ==============================\n\n /// @notice Internal function to send `_amount` amount of token to (`_dstChainId`, `_toAddress`)\n /// @param _dstChainId the destination chain identifier\n /// @param _toAddress can be any size depending on the `dstChainId`.\n /// @param _amount the quantity of tokens in wei\n /// @param _refundAddress the address LayerZero refunds if too much message fee is sent\n /// @param _zroPaymentAddress set to address(0x0) if not paying in ZRO (LayerZero Token)\n /// @param _adapterParams is a flexible bytes array to indicate messaging adapter services\n /// @dev Accounting and checks should be performed beforehand\n function _send(\n uint16 _dstChainId,\n bytes memory _toAddress,\n uint256 _amount,\n address payable _refundAddress,\n address _zroPaymentAddress,\n bytes memory _adapterParams\n ) internal {\n bytes memory payload = abi.encode(_toAddress, _amount);\n _lzSend(_dstChainId, payload, _refundAddress, _zroPaymentAddress, _adapterParams);\n\n uint64 nonce = lzEndpoint.getOutboundNonce(_dstChainId, address(this));\n emit SendToChain(msg.sender, _dstChainId, _toAddress, _amount, nonce);\n }\n\n function _nonblockingLzReceive(\n uint16 _srcChainId,\n bytes memory _srcAddress,\n uint64 _nonce,\n bytes memory _payload\n ) internal virtual override {\n // decode and load the toAddress\n (bytes memory toAddressBytes, uint256 amount) = abi.decode(_payload, (bytes, uint256));\n address toAddress;\n //solhint-disable-next-line\n assembly {\n toAddress := mload(add(toAddressBytes, 20))\n }\n amount = _creditTo(_srcChainId, toAddress, amount);\n\n emit ReceiveFromChain(_srcChainId, _srcAddress, toAddress, amount, _nonce);\n }\n\n /// @notice Makes accountability when bridging from this contract using canonical token\n /// @param _dstChainId ChainId of the destination chain - LayerZero standard\n /// @param _toAddress Recipient on the destination chain\n /// @param _amount Amount to bridge\n function _debitFrom(\n uint16 _dstChainId,\n bytes memory _toAddress,\n uint256 _amount\n ) internal virtual returns (uint256);\n\n /// @notice Makes accountability when bridging from this contract's credit\n /// @param _dstChainId ChainId of the destination chain - LayerZero standard\n /// @param _toAddress Recipient on the destination chain\n /// @param _amount Amount to bridge\n function _debitCreditFrom(\n uint16 _dstChainId,\n bytes memory _toAddress,\n uint256 _amount\n ) internal virtual returns (uint256);\n\n /// @notice Makes accountability when bridging to this contract\n /// @param _srcChainId ChainId of the source chain - LayerZero standard\n /// @param _toAddress Recipient on this chain\n /// @param _amount Amount to bridge\n function _creditTo(uint16 _srcChainId, address _toAddress, uint256 _amount) internal virtual returns (uint256);\n\n // ========================== View Functions ===================================\n\n /// @inheritdoc ERC165Upgradeable\n function supportsInterface(\n bytes4 interfaceId\n ) public view virtual override(ERC165Upgradeable, IERC165) returns (bool) {\n return interfaceId == type(IOFTCore).interfaceId || super.supportsInterface(interfaceId);\n }\n\n /// @inheritdoc IOFTCore\n function estimateSendFee(\n uint16 _dstChainId,\n bytes memory _toAddress,\n uint256 _amount,\n bool _useZro,\n bytes memory _adapterParams\n ) public view virtual override returns (uint256 nativeFee, uint256 zroFee) {\n // mock the payload for send()\n bytes memory payload = abi.encode(_toAddress, _amount);\n return lzEndpoint.estimateFees(_dstChainId, address(this), payload, _useZro, _adapterParams);\n }\n\n uint256[50] private __gap;\n}\n" + }, + "contracts/deprecated/OldAgEUR.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\nimport \"../interfaces/IAgToken.sol\";\nimport \"../interfaces/coreModule/IStableMaster.sol\";\nimport \"../interfaces/ITreasury.sol\";\n// OpenZeppelin may update its version of the ERC20PermitUpgradeable token\nimport \"@openzeppelin/contracts-upgradeable/token/ERC20/extensions/draft-ERC20PermitUpgradeable.sol\";\n\n/// @title AgToken\n/// @author Angle Labs, Inc.\n/// @notice Base contract for agToken, that is to say Angle's stablecoins\n/// @dev This contract is used to create and handle the stablecoins of Angle protocol\n/// @dev It is still possible for any address to burn its agTokens without redeeming collateral in exchange\n/// @dev This contract is the upgraded version of the AgToken that was first deployed on Ethereum mainnet\ncontract OldAgEUR is IAgToken, ERC20PermitUpgradeable {\n // ========================= References to other contracts =====================\n\n /// @notice Reference to the `StableMaster` contract associated to this `AgToken`\n address public stableMaster;\n\n // ============================= Constructor ===================================\n\n /// @notice Initializes the `AgToken` contract\n /// @param name_ Name of the token\n /// @param symbol_ Symbol of the token\n /// @param stableMaster_ Reference to the `StableMaster` contract associated to this agToken\n /// @dev By default, agTokens are ERC-20 tokens with 18 decimals\n function initialize(string memory name_, string memory symbol_, address stableMaster_) external initializer {\n __ERC20Permit_init(name_);\n __ERC20_init(name_, symbol_);\n require(stableMaster_ != address(0), \"0\");\n stableMaster = stableMaster_;\n }\n\n /// @custom:oz-upgrades-unsafe-allow constructor\n constructor() initializer {}\n\n // ======= Added Parameters and Variables from the first implementation ========\n\n /// @inheritdoc IAgToken\n mapping(address => bool) public isMinter;\n /// @notice Reference to the treasury contract which can grant minting rights\n address public treasury;\n /// @notice Boolean to check whether the contract has been reinitialized after its upgrade\n bool public treasuryInitialized;\n\n // =============================== Added Events ================================\n\n event TreasuryUpdated(address indexed _treasury);\n event MinterToggled(address indexed minter);\n\n // =============================== Added Errors ================================\n\n error BurnAmountExceedsAllowance();\n error InvalidSender();\n error InvalidTreasury();\n error NotGovernor();\n error NotMinter();\n error NotTreasury();\n error TreasuryAlreadyInitialized();\n\n // =============================== Setup Function ==============================\n\n /// @notice Sets up the treasury contract in this AgToken contract\n /// @param _treasury Treasury contract to add\n /// @dev The address calling this function has to be hard-coded in the contract\n /// @dev Can be called only once\n function setUpTreasury(address _treasury) external {\n // Only governor\n if (msg.sender != 0xdC4e6DFe07EFCa50a197DF15D9200883eF4Eb1c8) revert NotGovernor();\n if (address(ITreasury(_treasury).stablecoin()) != address(this)) revert InvalidTreasury();\n if (treasuryInitialized) revert TreasuryAlreadyInitialized();\n treasury = _treasury;\n treasuryInitialized = true;\n isMinter[stableMaster] = true;\n emit TreasuryUpdated(_treasury);\n }\n\n // =============================== Modifiers ===================================\n\n /// @notice Checks to see if it is the `Treasury` calling this contract\n /// @dev There is no Access Control here, because it can be handled cheaply through this modifier\n modifier onlyTreasury() {\n if (msg.sender != treasury) revert NotTreasury();\n _;\n }\n\n /// @notice Checks whether the sender has the minting right\n modifier onlyMinter() {\n if (!isMinter[msg.sender]) revert NotMinter();\n _;\n }\n\n // ========================= External Functions ================================\n // The following functions allow anyone to burn stablecoins without redeeming collateral\n // in exchange for that\n\n /// @notice Destroys `amount` token from the caller without giving collateral back\n /// @param amount Amount to burn\n /// @param poolManager Reference to the `PoolManager` contract for which the `stocksUsers` will\n /// need to be updated\n /// @dev When calling this function, people should specify the `poolManager` for which they want to decrease\n /// the `stocksUsers`: this is a way for the protocol to maintain healthy accounting variables\n function burnNoRedeem(uint256 amount, address poolManager) external {\n _burn(msg.sender, amount);\n IStableMaster(stableMaster).updateStocksUsers(amount, poolManager);\n }\n\n /// @notice Burns `amount` of agToken on behalf of another account without redeeming collateral back\n /// @param account Account to burn on behalf of\n /// @param amount Amount to burn\n /// @param poolManager Reference to the `PoolManager` contract for which the `stocksUsers` will need to be updated\n function burnFromNoRedeem(address account, uint256 amount, address poolManager) external {\n _burnFromNoRedeem(amount, account, msg.sender);\n IStableMaster(stableMaster).updateStocksUsers(amount, poolManager);\n }\n\n /// @notice Allows anyone to burn agToken without redeeming collateral back\n /// @param amount Amount of stablecoins to burn\n /// @dev This function can typically be called if there is a settlement mechanism to burn stablecoins\n function burnStablecoin(uint256 amount) external {\n _burn(msg.sender, amount);\n }\n\n // ======================= Minter Role Only Functions ==========================\n\n /// @inheritdoc IAgToken\n function burnSelf(uint256 amount, address burner) external onlyMinter {\n _burn(burner, amount);\n }\n\n /// @inheritdoc IAgToken\n function burnFrom(uint256 amount, address burner, address sender) external onlyMinter {\n _burnFromNoRedeem(amount, burner, sender);\n }\n\n /// @inheritdoc IAgToken\n function mint(address account, uint256 amount) external onlyMinter {\n _mint(account, amount);\n }\n\n // ======================= Treasury Only Functions =============================\n\n /// @inheritdoc IAgToken\n function addMinter(address minter) external onlyTreasury {\n isMinter[minter] = true;\n emit MinterToggled(minter);\n }\n\n /// @inheritdoc IAgToken\n function removeMinter(address minter) external {\n // The `treasury` contract cannot remove the `stableMaster`\n if (msg.sender != minter && (msg.sender != address(treasury) || minter == stableMaster)) revert InvalidSender();\n isMinter[minter] = false;\n emit MinterToggled(minter);\n }\n\n /// @inheritdoc IAgToken\n function setTreasury(address _treasury) external onlyTreasury {\n treasury = _treasury;\n emit TreasuryUpdated(_treasury);\n }\n\n // ============================ Internal Function ==============================\n\n /// @notice Internal version of the function `burnFromNoRedeem`\n /// @param amount Amount to burn\n /// @dev It is at the level of this function that allowance checks are performed\n function _burnFromNoRedeem(uint256 amount, address burner, address sender) internal {\n if (burner != sender) {\n uint256 currentAllowance = allowance(burner, sender);\n if (currentAllowance < amount) revert BurnAmountExceedsAllowance();\n _approve(burner, sender, currentAllowance - amount);\n }\n _burn(burner, amount);\n }\n}\n" + }, + "contracts/deprecated/OldAngleHelpers.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\nimport \"../interfaces/IAngleRouter.sol\";\nimport \"../interfaces/coreModule/IAgTokenMainnet.sol\";\nimport \"../interfaces/coreModule/ICore.sol\";\nimport \"../interfaces/coreModule/IOracleCore.sol\";\nimport \"../interfaces/coreModule/IPerpetualManager.sol\";\nimport \"../interfaces/coreModule/IPoolManager.sol\";\nimport \"../interfaces/coreModule/IStableMaster.sol\";\nimport \"@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol\";\nimport \"../interfaces/IVaultManager.sol\";\n\npragma solidity ^0.8.12;\n\nstruct Parameters {\n SLPData slpData;\n MintBurnData feeData;\n PerpetualManagerFeeData perpFeeData;\n PerpetualManagerParamData perpParam;\n}\n\nstruct PerpetualManagerFeeData {\n uint64[] xHAFeesDeposit;\n uint64[] yHAFeesDeposit;\n uint64[] xHAFeesWithdraw;\n uint64[] yHAFeesWithdraw;\n uint64 haBonusMalusDeposit;\n uint64 haBonusMalusWithdraw;\n}\n\nstruct PerpetualManagerParamData {\n uint64 maintenanceMargin;\n uint64 maxLeverage;\n uint64 targetHAHedge;\n uint64 limitHAHedge;\n uint64 lockTime;\n}\n\nstruct CollateralAddresses {\n address stableMaster;\n address poolManager;\n address perpetualManager;\n address sanToken;\n address oracle;\n address gauge;\n address feeManager;\n address[] strategies;\n}\n\n/// @title AngleHelpers\n/// @author Angle Labs, Inc.\n/// @notice Contract with view functions designed to facilitate integrations on the Core module of the Angle Protocol\n/// @dev This contract only contains view functions to be queried off-chain. It was thus not optimized for gas consumption\ncontract OldAngleHelpers is Initializable {\n // ======================== Helper View Functions ==============================\n\n /// @notice Gives the amount of `agToken` you'd be getting if you were executing in the same block a mint transaction\n /// with `amount` of `collateral` in the Core module of the Angle protocol as well as the value of the fees\n /// (in `BASE_PARAMS`) that would be applied during the mint\n /// @return Amount of `agToken` that would be obtained with a mint transaction in the same block\n /// @return Percentage of fees that would be taken during a mint transaction in the same block\n /// @dev This function reverts if the mint transaction was to revert in the same conditions (without taking into account\n /// potential approval problems to the `StableMaster` contract)\n function previewMintAndFees(\n uint256 amount,\n address agToken,\n address collateral\n ) external view returns (uint256, uint256) {\n return _previewMintAndFees(amount, agToken, collateral);\n }\n\n /// @notice Gives the amount of `collateral` you'd be getting if you were executing in the same block a burn transaction\n /// with `amount` of `agToken` in the Core module of the Angle protocol as well as the value of the fees\n /// (in `BASE_PARAMS`) that would be applied during the burn\n /// @return Amount of `collateral` that would be obtained with a burn transaction in the same block\n /// @return Percentage of fees that would be taken during a burn transaction in the same block\n /// @dev This function reverts if the burn transaction was to revert in the same conditions (without taking into account\n /// potential approval problems to the `StableMaster` contract or agToken balance prior to the call)\n function previewBurnAndFees(\n uint256 amount,\n address agToken,\n address collateral\n ) external view returns (uint256, uint256) {\n return _previewBurnAndFees(amount, agToken, collateral);\n }\n\n /// @notice Returns all the addresses associated to the (`agToken`,`collateral`) pair given\n /// @return addresses A struct with all the addresses associated in the Core module\n function getCollateralAddresses(\n address agToken,\n address collateral\n ) external view returns (CollateralAddresses memory addresses) {\n address stableMaster = IAgTokenMainnet(agToken).stableMaster();\n (address poolManager, address perpetualManager, address sanToken, address gauge) = ROUTER.mapPoolManagers(\n stableMaster,\n collateral\n );\n (, , , IOracleCore oracle, , , , , ) = IStableMaster(stableMaster).collateralMap(poolManager);\n addresses.stableMaster = stableMaster;\n addresses.poolManager = poolManager;\n addresses.perpetualManager = perpetualManager;\n addresses.sanToken = sanToken;\n addresses.gauge = gauge;\n addresses.oracle = address(oracle);\n addresses.feeManager = IPoolManager(poolManager).feeManager();\n\n uint256 length = 0;\n while (true) {\n try IPoolManager(poolManager).strategyList(length) returns (address) {\n length += 1;\n } catch {\n break;\n }\n }\n address[] memory strategies = new address[](length);\n for (uint256 i; i < length; ++i) {\n strategies[i] = IPoolManager(poolManager).strategyList(i);\n }\n addresses.strategies = strategies;\n }\n\n /// @notice Gets the addresses of all the `StableMaster` contracts and their associated `AgToken` addresses\n /// @return List of the `StableMaster` addresses of the Angle protocol\n /// @return List of the `AgToken` addresses of the protocol\n /// @dev The place of an agToken address in the list is the same as the corresponding `StableMaster` address\n function getStablecoinAddresses() external view returns (address[] memory, address[] memory) {\n address[] memory stableMasterAddresses = CORE.stablecoinList();\n address[] memory agTokenAddresses = new address[](stableMasterAddresses.length);\n for (uint256 i; i < stableMasterAddresses.length; ++i) {\n agTokenAddresses[i] = IStableMaster(stableMasterAddresses[i]).agToken();\n }\n return (stableMasterAddresses, agTokenAddresses);\n }\n\n /// @notice Returns most of the governance parameters associated to the (`agToken`,`collateral`) pair given\n /// @return params Struct with most of the parameters in the `StableMaster` and `PerpetualManager` contracts\n /// @dev Check out the struct `Parameters` for the meaning of the return values\n function getCollateralParameters(\n address agToken,\n address collateral\n ) external view returns (Parameters memory params) {\n (address stableMaster, address poolManager) = _getStableMasterAndPoolManager(agToken, collateral);\n (\n ,\n ,\n IPerpetualManager perpetualManager,\n ,\n ,\n ,\n ,\n SLPData memory slpData,\n MintBurnData memory feeData\n ) = IStableMaster(stableMaster).collateralMap(poolManager);\n\n params.slpData = slpData;\n params.feeData = feeData;\n params.perpParam.maintenanceMargin = perpetualManager.maintenanceMargin();\n params.perpParam.maxLeverage = perpetualManager.maxLeverage();\n params.perpParam.targetHAHedge = perpetualManager.targetHAHedge();\n params.perpParam.limitHAHedge = perpetualManager.limitHAHedge();\n params.perpParam.lockTime = perpetualManager.lockTime();\n\n params.perpFeeData.haBonusMalusDeposit = perpetualManager.haBonusMalusDeposit();\n params.perpFeeData.haBonusMalusWithdraw = perpetualManager.haBonusMalusWithdraw();\n\n uint256 length = 0;\n while (true) {\n try perpetualManager.xHAFeesDeposit(length) returns (uint64) {\n length += 1;\n } catch {\n break;\n }\n }\n uint64[] memory data = new uint64[](length);\n uint64[] memory data2 = new uint64[](length);\n for (uint256 i; i < length; ++i) {\n data[i] = perpetualManager.xHAFeesDeposit(i);\n data2[i] = perpetualManager.yHAFeesDeposit(i);\n }\n params.perpFeeData.xHAFeesDeposit = data;\n params.perpFeeData.yHAFeesDeposit = data2;\n\n length = 0;\n while (true) {\n try perpetualManager.xHAFeesWithdraw(length) returns (uint64) {\n length += 1;\n } catch {\n break;\n }\n }\n data = new uint64[](length);\n data2 = new uint64[](length);\n for (uint256 i; i < length; ++i) {\n data[i] = perpetualManager.xHAFeesWithdraw(i);\n data2[i] = perpetualManager.yHAFeesWithdraw(i);\n }\n params.perpFeeData.xHAFeesWithdraw = data;\n params.perpFeeData.yHAFeesWithdraw = data2;\n }\n\n /// @notice Returns the address of the poolManager associated to an (`agToken`, `collateral`) pair\n /// in the Core module of the protocol\n function getPoolManager(address agToken, address collateral) public view returns (address poolManager) {\n (, poolManager) = _getStableMasterAndPoolManager(agToken, collateral);\n }\n\n // ======================== Replica Functions ==================================\n // These replicate what is done in the other contracts of the protocol\n\n function _previewBurnAndFees(\n uint256 amount,\n address agToken,\n address collateral\n ) internal view returns (uint256 amountForUserInCollat, uint256 feePercent) {\n (address stableMaster, address poolManager) = _getStableMasterAndPoolManager(agToken, collateral);\n (\n address token,\n ,\n IPerpetualManager perpetualManager,\n IOracleCore oracle,\n uint256 stocksUsers,\n ,\n uint256 collatBase,\n ,\n MintBurnData memory feeData\n ) = IStableMaster(stableMaster).collateralMap(poolManager);\n if (token == address(0) || IStableMaster(stableMaster).paused(keccak256(abi.encodePacked(STABLE, poolManager))))\n revert NotInitialized();\n if (amount > stocksUsers) revert InvalidAmount();\n\n if (feeData.xFeeBurn.length == 1) {\n feePercent = feeData.yFeeBurn[0];\n } else {\n bytes memory data = abi.encode(address(perpetualManager), feeData.targetHAHedge);\n uint64 hedgeRatio = _computeHedgeRatio(stocksUsers - amount, data);\n feePercent = _piecewiseLinear(hedgeRatio, feeData.xFeeBurn, feeData.yFeeBurn);\n }\n feePercent = (feePercent * feeData.bonusMalusBurn) / BASE_PARAMS;\n\n amountForUserInCollat = (amount * (BASE_PARAMS - feePercent) * collatBase) / (oracle.readUpper() * BASE_PARAMS);\n }\n\n function _previewMintAndFees(\n uint256 amount,\n address agToken,\n address collateral\n ) internal view returns (uint256 amountForUserInStable, uint256 feePercent) {\n (address stableMaster, address poolManager) = _getStableMasterAndPoolManager(agToken, collateral);\n (\n address token,\n ,\n IPerpetualManager perpetualManager,\n IOracleCore oracle,\n uint256 stocksUsers,\n ,\n ,\n ,\n MintBurnData memory feeData\n ) = IStableMaster(stableMaster).collateralMap(poolManager);\n if (token == address(0) || IStableMaster(stableMaster).paused(keccak256(abi.encodePacked(STABLE, poolManager))))\n revert NotInitialized();\n\n amountForUserInStable = oracle.readQuoteLower(amount);\n\n if (feeData.xFeeMint.length == 1) feePercent = feeData.yFeeMint[0];\n else {\n bytes memory data = abi.encode(address(perpetualManager), feeData.targetHAHedge);\n uint64 hedgeRatio = _computeHedgeRatio(amountForUserInStable + stocksUsers, data);\n feePercent = _piecewiseLinear(hedgeRatio, feeData.xFeeMint, feeData.yFeeMint);\n }\n feePercent = (feePercent * feeData.bonusMalusMint) / BASE_PARAMS;\n\n amountForUserInStable = (amountForUserInStable * (BASE_PARAMS - feePercent)) / BASE_PARAMS;\n if (stocksUsers + amountForUserInStable > feeData.capOnStableMinted) revert InvalidAmount();\n }\n\n // ======================== Utility Functions ==================================\n // These utility functions are taken from other contracts of the protocol\n\n function _computeHedgeRatio(uint256 newStocksUsers, bytes memory data) internal view returns (uint64 ratio) {\n (address perpetualManager, uint64 targetHAHedge) = abi.decode(data, (address, uint64));\n uint256 totalHedgeAmount = IPerpetualManager(perpetualManager).totalHedgeAmount();\n newStocksUsers = (targetHAHedge * newStocksUsers) / BASE_PARAMS;\n if (newStocksUsers > totalHedgeAmount) ratio = uint64((totalHedgeAmount * BASE_PARAMS) / newStocksUsers);\n else ratio = uint64(BASE_PARAMS);\n }\n\n function _piecewiseLinear(uint64 x, uint64[] memory xArray, uint64[] memory yArray) internal pure returns (uint64) {\n if (x >= xArray[xArray.length - 1]) {\n return yArray[xArray.length - 1];\n } else if (x <= xArray[0]) {\n return yArray[0];\n } else {\n uint256 lower;\n uint256 upper = xArray.length - 1;\n uint256 mid;\n while (upper - lower > 1) {\n mid = lower + (upper - lower) / 2;\n if (xArray[mid] <= x) {\n lower = mid;\n } else {\n upper = mid;\n }\n }\n if (yArray[upper] > yArray[lower]) {\n return\n yArray[lower] +\n ((yArray[upper] - yArray[lower]) * (x - xArray[lower])) /\n (xArray[upper] - xArray[lower]);\n } else {\n return\n yArray[lower] -\n ((yArray[lower] - yArray[upper]) * (x - xArray[lower])) /\n (xArray[upper] - xArray[lower]);\n }\n }\n }\n\n function _getStableMasterAndPoolManager(\n address agToken,\n address collateral\n ) internal view returns (address stableMaster, address poolManager) {\n stableMaster = IAgTokenMainnet(agToken).stableMaster();\n (poolManager, , , ) = ROUTER.mapPoolManagers(stableMaster, collateral);\n }\n\n // ====================== Constants and Initializers ===========================\n\n IAngleRouter public constant ROUTER = IAngleRouter(0xBB755240596530be0c1DE5DFD77ec6398471561d);\n ICore public constant CORE = ICore(0x61ed74de9Ca5796cF2F8fD60D54160D47E30B7c3);\n\n bytes32 public constant STABLE = keccak256(\"STABLE\");\n uint256 public constant BASE_PARAMS = 10 ** 9;\n\n error NotInitialized();\n error InvalidAmount();\n\n /// @custom:oz-upgrades-unsafe-allow constructor\n constructor() initializer {}\n}\n" + }, + "contracts/deprecated/vaultManager/OldVaultManagerERC721.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\nimport \"./OldVaultManagerStorage.sol\";\n\n/// @title VaultManagerERC721\n/// @author Angle Labs, Inc.\n/// @dev Base ERC721 Implementation of VaultManager\nabstract contract OldVaultManagerERC721 is IERC721MetadataUpgradeable, OldVaultManagerStorage {\n using SafeERC20 for IERC20;\n using Address for address;\n\n /// @inheritdoc IERC721MetadataUpgradeable\n string public name;\n /// @inheritdoc IERC721MetadataUpgradeable\n string public symbol;\n\n // ================================= MODIFIERS =================================\n\n /// @notice Checks if the person interacting with the vault with `vaultID` is approved\n /// @param caller Address of the person seeking to interact with the vault\n /// @param vaultID ID of the concerned vault\n modifier onlyApprovedOrOwner(address caller, uint256 vaultID) {\n if (!_isApprovedOrOwner(caller, vaultID)) revert NotApproved();\n _;\n }\n\n // ================================ ERC721 LOGIC ===============================\n\n /// @notice Checks whether a given address is approved for a vault or owns this vault\n /// @param spender Address for which vault ownership should be checked\n /// @param vaultID ID of the vault to check\n /// @return Whether the `spender` address owns or is approved for `vaultID`\n function isApprovedOrOwner(address spender, uint256 vaultID) external view returns (bool) {\n return _isApprovedOrOwner(spender, vaultID);\n }\n\n /// @inheritdoc IERC721MetadataUpgradeable\n function tokenURI(uint256 vaultID) external view returns (string memory) {\n if (!_exists(vaultID)) revert NonexistentVault();\n // There is no vault with `vaultID` equal to 0, so the following variable is\n // always greater than zero\n uint256 temp = vaultID;\n uint256 digits;\n while (temp != 0) {\n digits++;\n temp /= 10;\n }\n bytes memory buffer = new bytes(digits);\n while (vaultID != 0) {\n digits -= 1;\n buffer[digits] = bytes1(uint8(48 + uint256(vaultID % 10)));\n vaultID /= 10;\n }\n return bytes(_baseURI).length > 0 ? string(abi.encodePacked(_baseURI, string(buffer))) : \"\";\n }\n\n /// @inheritdoc IERC721Upgradeable\n function balanceOf(address owner) external view returns (uint256) {\n if (owner == address(0)) revert ZeroAddress();\n return _balances[owner];\n }\n\n /// @inheritdoc IERC721Upgradeable\n function ownerOf(uint256 vaultID) external view returns (address) {\n return _ownerOf(vaultID);\n }\n\n /// @inheritdoc IERC721Upgradeable\n function approve(address to, uint256 vaultID) external {\n address owner = _ownerOf(vaultID);\n if (to == owner) revert ApprovalToOwner();\n if (msg.sender != owner && !isApprovedForAll(owner, msg.sender)) revert NotApproved();\n\n _approve(to, vaultID);\n }\n\n /// @inheritdoc IERC721Upgradeable\n function getApproved(uint256 vaultID) external view returns (address) {\n if (!_exists(vaultID)) revert NonexistentVault();\n return _getApproved(vaultID);\n }\n\n /// @inheritdoc IERC721Upgradeable\n function setApprovalForAll(address operator, bool approved) external {\n _setApprovalForAll(msg.sender, operator, approved);\n }\n\n /// @inheritdoc IERC721Upgradeable\n function isApprovedForAll(address owner, address operator) public view returns (bool) {\n return _operatorApprovals[owner][operator] == 1;\n }\n\n /// @inheritdoc IERC721Upgradeable\n function transferFrom(address from, address to, uint256 vaultID) external onlyApprovedOrOwner(msg.sender, vaultID) {\n _transfer(from, to, vaultID);\n }\n\n /// @inheritdoc IERC721Upgradeable\n function safeTransferFrom(address from, address to, uint256 vaultID) external {\n safeTransferFrom(from, to, vaultID, \"\");\n }\n\n /// @inheritdoc IERC721Upgradeable\n function safeTransferFrom(\n address from,\n address to,\n uint256 vaultID,\n bytes memory _data\n ) public onlyApprovedOrOwner(msg.sender, vaultID) {\n _safeTransfer(from, to, vaultID, _data);\n }\n\n // ================================ ERC165 LOGIC ===============================\n\n /// @inheritdoc IERC165Upgradeable\n function supportsInterface(bytes4 interfaceId) external pure returns (bool) {\n return\n interfaceId == type(IERC721MetadataUpgradeable).interfaceId ||\n interfaceId == type(IERC721Upgradeable).interfaceId ||\n interfaceId == type(IVaultManager).interfaceId ||\n interfaceId == type(IERC165Upgradeable).interfaceId;\n }\n\n // ================== INTERNAL FUNCTIONS FOR THE ERC721 LOGIC ==================\n\n /// @notice Internal version of the `ownerOf` function\n function _ownerOf(uint256 vaultID) internal view returns (address owner) {\n owner = _owners[vaultID];\n if (owner == address(0)) revert NonexistentVault();\n }\n\n /// @notice Internal version of the `getApproved` function\n function _getApproved(uint256 vaultID) internal view returns (address) {\n return _vaultApprovals[vaultID];\n }\n\n /// @notice Internal version of the `safeTransferFrom` function (with the data parameter)\n function _safeTransfer(address from, address to, uint256 vaultID, bytes memory _data) internal {\n _transfer(from, to, vaultID);\n if (!_checkOnERC721Received(from, to, vaultID, _data)) revert NonERC721Receiver();\n }\n\n /// @notice Checks whether a vault exists\n /// @param vaultID ID of the vault to check\n /// @return Whether `vaultID` has been created\n function _exists(uint256 vaultID) internal view returns (bool) {\n return _owners[vaultID] != address(0);\n }\n\n /// @notice Internal version of the `isApprovedOrOwner` function\n function _isApprovedOrOwner(address spender, uint256 vaultID) internal view returns (bool) {\n // The following checks if the vault exists\n address owner = _ownerOf(vaultID);\n return (spender == owner || _getApproved(vaultID) == spender || _operatorApprovals[owner][spender] == 1);\n }\n\n /// @notice Internal version of the `createVault` function\n /// Mints `vaultID` and transfers it to `to`\n /// @dev This method is equivalent to the `_safeMint` method used in OpenZeppelin ERC721 contract\n /// @dev Emits a {Transfer} event\n function _mint(address to) internal returns (uint256 vaultID) {\n if (whitelistingActivated && (isWhitelisted[to] != 1 || isWhitelisted[msg.sender] != 1))\n revert NotWhitelisted();\n if (to == address(0)) revert ZeroAddress();\n\n unchecked {\n vaultIDCount += 1;\n }\n\n vaultID = vaultIDCount;\n _beforeTokenTransfer(address(0), to, vaultID);\n\n unchecked {\n _balances[to] += 1;\n }\n\n _owners[vaultID] = to;\n emit Transfer(address(0), to, vaultID);\n if (!_checkOnERC721Received(address(0), to, vaultID, \"\")) revert NonERC721Receiver();\n }\n\n /// @notice Destroys `vaultID`\n /// @dev `vaultID` must exist\n /// @dev Emits a {Transfer} event\n function _burn(uint256 vaultID) internal {\n address owner = _ownerOf(vaultID);\n\n _beforeTokenTransfer(owner, address(0), vaultID);\n // Clear approvals\n _approve(address(0), vaultID);\n // The following line cannot underflow as the owner's balance is necessarily\n // greater than 1\n unchecked {\n _balances[owner] -= 1;\n }\n delete _owners[vaultID];\n delete vaultData[vaultID];\n\n emit Transfer(owner, address(0), vaultID);\n }\n\n /// @notice Transfers `vaultID` from `from` to `to` as opposed to {transferFrom},\n /// this imposes no restrictions on msg.sender\n /// @dev `to` cannot be the zero address and `perpetualID` must be owned by `from`\n /// @dev Emits a {Transfer} event\n /// @dev A whitelist check is performed if necessary on the `to` address\n function _transfer(address from, address to, uint256 vaultID) internal {\n if (_ownerOf(vaultID) != from) revert NotApproved();\n if (to == address(0)) revert ZeroAddress();\n if (whitelistingActivated && isWhitelisted[to] != 1) revert NotWhitelisted();\n\n _beforeTokenTransfer(from, to, vaultID);\n\n // Clear approvals from the previous owner\n _approve(address(0), vaultID);\n unchecked {\n _balances[from] -= 1;\n _balances[to] += 1;\n }\n _owners[vaultID] = to;\n\n emit Transfer(from, to, vaultID);\n }\n\n /// @notice Approves `to` to operate on `vaultID`\n function _approve(address to, uint256 vaultID) internal {\n _vaultApprovals[vaultID] = to;\n emit Approval(_ownerOf(vaultID), to, vaultID);\n }\n\n /// @notice Internal version of the `setApprovalForAll` function\n /// @dev It contains an `approver` field to be used in case someone signs a permit for a particular\n /// address, and this signature is given to the contract by another address (like a router)\n function _setApprovalForAll(address approver, address operator, bool approved) internal {\n if (operator == approver) revert ApprovalToCaller();\n uint256 approval = approved ? 1 : 0;\n _operatorApprovals[approver][operator] = approval;\n emit ApprovalForAll(approver, operator, approved);\n }\n\n /// @notice Internal function to invoke {IERC721Receiver-onERC721Received} on a target address\n /// The call is not executed if the target address is not a contract\n /// @param from Address representing the previous owner of the given token ID\n /// @param to Target address that will receive the tokens\n /// @param vaultID ID of the token to be transferred\n /// @param _data Bytes optional data to send along with the call\n /// @return Bool whether the call correctly returned the expected value\n function _checkOnERC721Received(\n address from,\n address to,\n uint256 vaultID,\n bytes memory _data\n ) private returns (bool) {\n if (to.isContract()) {\n try IERC721ReceiverUpgradeable(to).onERC721Received(msg.sender, from, vaultID, _data) returns (\n bytes4 retval\n ) {\n return retval == IERC721ReceiverUpgradeable.onERC721Received.selector;\n } catch (bytes memory reason) {\n if (reason.length == 0) {\n revert NonERC721Receiver();\n } else {\n // solhint-disable-next-line no-inline-assembly\n assembly {\n revert(add(32, reason), mload(reason))\n }\n }\n }\n } else {\n return true;\n }\n }\n\n /// @notice Hook that is called before any token transfer. This includes minting and burning.\n /// Calling conditions:\n ///\n /// - When `from` and `to` are both non-zero, `from`'s `vaultID` will be\n /// transferred to `to`.\n /// - When `from` is zero, `vaultID` will be minted for `to`.\n /// - When `to` is zero, `from`'s `vaultID` will be burned.\n /// - `from` and `to` are never both zero.\n function _beforeTokenTransfer(address from, address to, uint256 vaultID) internal virtual {}\n}\n" + }, + "contracts/deprecated/vaultManager/OldVaultManagerPermit.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\nimport \"./OldVaultManagerERC721.sol\";\nimport \"../../interfaces/external/IERC1271.sol\";\n\n/// @title VaultManagerPermit\n/// @author Angle Labs, Inc.\n/// @dev Base Implementation of permit functions for the `VaultManager` contract\nabstract contract OldVaultManagerPermit is Initializable, OldVaultManagerERC721 {\n using Address for address;\n\n mapping(address => uint256) private _nonces;\n /* solhint-disable var-name-mixedcase */\n bytes32 private _HASHED_NAME;\n bytes32 private _HASHED_VERSION;\n bytes32 private _PERMIT_TYPEHASH;\n /* solhint-enable var-name-mixedcase */\n\n error ExpiredDeadline();\n error InvalidSignature();\n\n //solhint-disable-next-line\n function __ERC721Permit_init(string memory _name) internal onlyInitializing {\n _PERMIT_TYPEHASH = keccak256(\n \"Permit(address owner,address spender,bool approved,uint256 nonce,uint256 deadline)\"\n );\n _HASHED_NAME = keccak256(bytes(_name));\n _HASHED_VERSION = keccak256(bytes(\"1\"));\n }\n\n /// @notice Allows an address to give or revoke approval for all its vaults to another address\n /// @param owner Address signing the permit and giving (or revoking) its approval for all the controlled vaults\n /// @param spender Address to give approval to\n /// @param approved Whether to give or revoke the approval\n /// @param deadline Deadline parameter for the signature to be valid\n /// @dev The `v`, `r`, and `s` parameters are used as signature data\n function permit(\n address owner,\n address spender,\n bool approved,\n uint256 deadline,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) external {\n if (block.timestamp > deadline) revert ExpiredDeadline();\n // Additional signature checks performed in the `ECDSAUpgradeable.recover` function\n if (uint256(s) > 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D576E7357A4501DDFE92F46681B20A0 || (v != 27 && v != 28))\n revert InvalidSignature();\n\n bytes32 digest = keccak256(\n abi.encodePacked(\n \"\\x19\\x01\",\n _domainSeparatorV4(),\n keccak256(\n abi.encode(\n _PERMIT_TYPEHASH,\n // 0x3f43a9c6bafb5c7aab4e0cfe239dc5d4c15caf0381c6104188191f78a6640bd8,\n owner,\n spender,\n approved,\n _useNonce(owner),\n deadline\n )\n )\n )\n );\n if (owner.isContract()) {\n if (IERC1271(owner).isValidSignature(digest, abi.encodePacked(r, s, v)) != 0x1626ba7e)\n revert InvalidSignature();\n } else {\n address signer = ecrecover(digest, v, r, s);\n if (signer != owner || signer == address(0)) revert InvalidSignature();\n }\n\n _setApprovalForAll(owner, spender, approved);\n }\n\n /// @notice Returns the current nonce for an `owner` address\n function nonces(address owner) public view returns (uint256) {\n return _nonces[owner];\n }\n\n /// @notice Returns the domain separator for the current chain.\n // solhint-disable-next-line func-name-mixedcase\n function DOMAIN_SEPARATOR() external view returns (bytes32) {\n return _domainSeparatorV4();\n }\n\n /// @notice Internal version of the `DOMAIN_SEPARATOR` function\n function _domainSeparatorV4() internal view returns (bytes32) {\n return\n keccak256(\n abi.encode(\n // keccak256('EIP712Domain(string name,string version,uint256 chainId,address verifyingContract)')\n 0x8b73c3c69bb8fe3d512ecc4cf759cc79239f7b179b0ffacaa9a75d522b39400f,\n _HASHED_NAME,\n _HASHED_VERSION,\n block.chainid,\n address(this)\n )\n );\n }\n\n /// @notice Consumes a nonce for an address: returns the current value and increments it\n function _useNonce(address owner) internal returns (uint256 current) {\n current = _nonces[owner];\n _nonces[owner] = current + 1;\n }\n\n uint256[49] private __gap;\n}\n" + }, + "contracts/deprecated/vaultManager/OldVaultManagerStorage.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\nimport \"@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/token/ERC20/extensions/draft-IERC20PermitUpgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/token/ERC721/IERC721ReceiverUpgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/interfaces/IERC721MetadataUpgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/utils/introspection/IERC165Upgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/utils/AddressUpgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/security/ReentrancyGuardUpgradeable.sol\";\nimport \"@openzeppelin/contracts/token/ERC20/extensions/IERC20Metadata.sol\";\nimport \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\nimport \"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\";\n\nimport \"../../interfaces/IAgToken.sol\";\nimport \"../../interfaces/IOracle.sol\";\nimport \"../../interfaces/ISwapper.sol\";\nimport \"../../interfaces/ITreasury.sol\";\nimport \"../../interfaces/IVaultManager.sol\";\nimport \"../../interfaces/governance/IVeBoostProxy.sol\";\n\n/// @title VaultManagerStorage\n/// @author Angle Labs, Inc.\n/// @dev Variables, references, parameters and events needed in the `VaultManager` contract\n// solhint-disable-next-line max-states-count\ncontract OldVaultManagerStorage is IVaultManagerStorage, Initializable, ReentrancyGuardUpgradeable {\n /// @notice Base used for parameter computation: almost all the parameters of this contract are set in `BASE_PARAMS`\n uint256 public constant BASE_PARAMS = 10 ** 9;\n /// @notice Base used for interest rate computation\n uint256 public constant BASE_INTEREST = 10 ** 27;\n /// @notice Used for interest rate computation\n uint256 public constant HALF_BASE_INTEREST = 10 ** 27 / 2;\n\n // ================================= REFERENCES ================================\n\n /// @inheritdoc IVaultManagerStorage\n ITreasury public treasury;\n /// @inheritdoc IVaultManagerStorage\n IERC20 public collateral;\n /// @inheritdoc IVaultManagerStorage\n IAgToken public stablecoin;\n /// @inheritdoc IVaultManagerStorage\n IOracle public oracle;\n /// @notice Reference to the contract which computes adjusted veANGLE balances for liquidators boosts\n IVeBoostProxy public veBoostProxy;\n /// @notice Base of the collateral\n uint256 internal _collatBase;\n\n // ================================= PARAMETERS ================================\n // Unless specified otherwise, parameters of this contract are expressed in `BASE_PARAMS`\n\n /// @notice Maximum amount of stablecoins that can be issued with this contract (in `BASE_TOKENS`). This parameter should\n /// not be bigger than `type(uint256).max / BASE_INTEREST` otherwise there may be some overflows in the `increaseDebt` function\n uint256 public debtCeiling;\n /// @notice Threshold veANGLE balance values for the computation of the boost for liquidators: the length of this array\n /// should normally be 2. The base of the x-values in this array should be `BASE_TOKENS`\n uint256[] public xLiquidationBoost;\n /// @notice Values of the liquidation boost at the threshold values of x\n uint256[] public yLiquidationBoost;\n /// @inheritdoc IVaultManagerStorage\n uint64 public collateralFactor;\n /// @notice Maximum Health factor at which a vault can end up after a liquidation (unless it's fully liquidated)\n uint64 public targetHealthFactor;\n /// @notice Upfront fee taken when borrowing stablecoins: this fee is optional and should in practice not be used\n uint64 public borrowFee;\n /// @notice Upfront fee taken when repaying stablecoins: this fee is optional as well. It should be smaller\n /// than the liquidation surcharge (cf below) to avoid exploits where people voluntarily get liquidated at a 0\n /// discount to pay smaller repaying fees\n uint64 public repayFee;\n /// @notice Per second interest taken to borrowers taking agToken loans. Contrarily to other parameters, it is set in `BASE_INTEREST`\n /// that is to say in base 10**27\n uint64 public interestRate;\n /// @notice Fee taken by the protocol during a liquidation. Technically, this value is not the fee per se, it's 1 - fee.\n /// For instance for a 2% fee, `liquidationSurcharge` should be 98%\n uint64 public liquidationSurcharge;\n /// @notice Maximum discount given to liquidators\n uint64 public maxLiquidationDiscount;\n /// @notice Whether whitelisting is required to own a vault or not\n bool public whitelistingActivated;\n /// @notice Whether the contract is paused or not\n bool public paused;\n\n // ================================= VARIABLES =================================\n\n /// @notice Timestamp at which the `interestAccumulator` was updated\n uint256 public lastInterestAccumulatorUpdated;\n /// @inheritdoc IVaultManagerStorage\n uint256 public interestAccumulator;\n /// @inheritdoc IVaultManagerStorage\n uint256 public totalNormalizedDebt;\n /// @notice Surplus accumulated by the contract: surplus is always in stablecoins, and is then reset\n /// when the value is communicated to the treasury contract\n uint256 public surplus;\n /// @notice Bad debt made from liquidated vaults which ended up having no collateral and a positive amount\n /// of stablecoins\n uint256 public badDebt;\n\n // ================================== MAPPINGS =================================\n\n /// @inheritdoc IVaultManagerStorage\n mapping(uint256 => Vault) public vaultData;\n /// @notice Maps an address to 1 if it's whitelisted and can open or own a vault\n mapping(address => uint256) public isWhitelisted;\n\n // ================================ ERC721 DATA ================================\n\n /// @inheritdoc IVaultManagerStorage\n uint256 public vaultIDCount;\n\n /// @notice URI\n string internal _baseURI;\n\n // Mapping from `vaultID` to owner address\n mapping(uint256 => address) internal _owners;\n\n // Mapping from owner address to vault owned count\n mapping(address => uint256) internal _balances;\n\n // Mapping from `vaultID` to approved address\n mapping(uint256 => address) internal _vaultApprovals;\n\n // Mapping from owner to operator approvals\n mapping(address => mapping(address => uint256)) internal _operatorApprovals;\n\n uint256[50] private __gap;\n\n // =================================== EVENTS ==================================\n\n event AccruedToTreasury(uint256 surplusEndValue, uint256 badDebtEndValue);\n event CollateralAmountUpdated(uint256 vaultID, uint256 collateralAmount, uint8 isIncrease);\n event InterestAccumulatorUpdated(uint256 value, uint256 timestamp);\n event InternalDebtUpdated(uint256 vaultID, uint256 internalAmount, uint8 isIncrease);\n event FiledUint64(uint64 param, bytes32 what);\n event DebtCeilingUpdated(uint256 debtCeiling);\n event LiquidationBoostParametersUpdated(address indexed _veBoostProxy, uint256[] xBoost, uint256[] yBoost);\n event LiquidatedVaults(uint256[] vaultIDs);\n event DebtTransferred(uint256 srcVaultID, uint256 dstVaultID, address dstVaultManager, uint256 amount);\n\n // =================================== ERRORS ==================================\n\n error ApprovalToOwner();\n error ApprovalToCaller();\n error DustyLeftoverAmount();\n error DebtCeilingExceeded();\n error HealthyVault();\n error IncompatibleLengths();\n error InsolventVault();\n error InvalidParameterValue();\n error InvalidParameterType();\n error InvalidSetOfParameters();\n error InvalidTreasury();\n error NonERC721Receiver();\n error NonexistentVault();\n error NotApproved();\n error NotGovernor();\n error NotGovernorOrGuardian();\n error NotTreasury();\n error NotWhitelisted();\n error NotVaultManager();\n error Paused();\n error TooHighParameterValue();\n error TooSmallParameterValue();\n error ZeroAddress();\n\n /// @custom:oz-upgrades-unsafe-allow constructor\n constructor() initializer {}\n}\n" + }, + "contracts/external/ProxyAdmin.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\nimport \"./TransparentUpgradeableProxy.sol\";\nimport \"@openzeppelin/contracts/access/Ownable.sol\";\n\n/**\n * @dev This is an auxiliary contract meant to be assigned as the admin of a {TransparentUpgradeableProxy}. For an\n * explanation of why you would want to use this see the documentation for {TransparentUpgradeableProxy}.\n * This contract was fully forked from OpenZeppelin `ProxyAdmin`\n */\ncontract ProxyAdmin is Ownable {\n /**\n * @dev Returns the current implementation of `proxy`.\n *\n * Requirements:\n *\n * - This contract must be the admin of `proxy`.\n */\n function getProxyImplementation(TransparentUpgradeableProxy proxy) public view virtual returns (address) {\n // We need to manually run the static call since the getter cannot be flagged as view\n // bytes4(keccak256(\"implementation()\")) == 0x5c60da1b\n (bool success, bytes memory returndata) = address(proxy).staticcall(hex\"5c60da1b\");\n require(success);\n return abi.decode(returndata, (address));\n }\n\n /**\n * @dev Returns the current admin of `proxy`.\n *\n * Requirements:\n *\n * - This contract must be the admin of `proxy`.\n */\n function getProxyAdmin(TransparentUpgradeableProxy proxy) public view virtual returns (address) {\n // We need to manually run the static call since the getter cannot be flagged as view\n // bytes4(keccak256(\"admin()\")) == 0xf851a440\n (bool success, bytes memory returndata) = address(proxy).staticcall(hex\"f851a440\");\n require(success);\n return abi.decode(returndata, (address));\n }\n\n /**\n * @dev Changes the admin of `proxy` to `newAdmin`.\n *\n * Requirements:\n *\n * - This contract must be the current admin of `proxy`.\n */\n function changeProxyAdmin(TransparentUpgradeableProxy proxy, address newAdmin) public virtual onlyOwner {\n proxy.changeAdmin(newAdmin);\n }\n\n /**\n * @dev Upgrades `proxy` to `implementation`. See {TransparentUpgradeableProxy-upgradeTo}.\n *\n * Requirements:\n *\n * - This contract must be the admin of `proxy`.\n */\n function upgrade(TransparentUpgradeableProxy proxy, address implementation) public virtual onlyOwner {\n proxy.upgradeTo(implementation);\n }\n\n /**\n * @dev Upgrades `proxy` to `implementation` and calls a function on the new implementation. See\n * {TransparentUpgradeableProxy-upgradeToAndCall}.\n *\n * Requirements:\n *\n * - This contract must be the admin of `proxy`.\n */\n function upgradeAndCall(\n TransparentUpgradeableProxy proxy,\n address implementation,\n bytes memory data\n ) public payable virtual onlyOwner {\n proxy.upgradeToAndCall{ value: msg.value }(implementation, data);\n }\n}\n" + }, + "contracts/external/TransparentUpgradeableProxy.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\nimport \"@openzeppelin/contracts/proxy/ERC1967/ERC1967Proxy.sol\";\n\n/**\n * @dev This contract implements a proxy that is upgradeable by an admin. It is fully forked from OpenZeppelin\n * `TransparentUpgradeableProxy`\n *\n * To avoid https://medium.com/nomic-labs-blog/malicious-backdoors-in-ethereum-proxies-62629adf3357[proxy selector\n * clashing], which can potentially be used in an attack, this contract uses the\n * https://blog.openzeppelin.com/the-transparent-proxy-pattern/[transparent proxy pattern]. This pattern implies two\n * things that go hand in hand:\n *\n * 1. If any account other than the admin calls the proxy, the call will be forwarded to the implementation, even if\n * that call matches one of the admin functions exposed by the proxy itself.\n * 2. If the admin calls the proxy, it can access the admin functions, but its calls will never be forwarded to the\n * implementation. If the admin tries to call a function on the implementation it will fail with an error that says\n * \"admin cannot fallback to proxy target\".\n *\n * These properties mean that the admin account can only be used for admin actions like upgrading the proxy or changing\n * the admin, so it's best if it's a dedicated account that is not used for anything else. This will avoid headaches due\n * to sudden errors when trying to call a function from the proxy implementation.\n *\n * Our recommendation is for the dedicated account to be an instance of the {ProxyAdmin} contract. If set up this way,\n * you should think of the `ProxyAdmin` instance as the real administrative interface of your proxy.\n */\ncontract TransparentUpgradeableProxy is ERC1967Proxy {\n /**\n * @dev Initializes an upgradeable proxy managed by `_admin`, backed by the implementation at `_logic`, and\n * optionally initialized with `_data` as explained in {ERC1967Proxy-constructor}.\n */\n constructor(address _logic, address admin_, bytes memory _data) payable ERC1967Proxy(_logic, _data) {\n assert(_ADMIN_SLOT == bytes32(uint256(keccak256(\"eip1967.proxy.admin\")) - 1));\n _changeAdmin(admin_);\n }\n\n /**\n * @dev Modifier used internally that will delegate the call to the implementation unless the sender is the admin.\n */\n modifier ifAdmin() {\n if (msg.sender == _getAdmin()) {\n _;\n } else {\n _fallback();\n }\n }\n\n /**\n * @dev Returns the current admin.\n *\n * NOTE: Only the admin can call this function. See {ProxyAdmin-getProxyAdmin}.\n *\n * TIP: To get this value clients can read directly from the storage slot shown below (specified by EIP1967) using the\n * https://eth.wiki/json-rpc/API#eth_getstorageat[`eth_getStorageAt`] RPC call.\n * `0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103`\n */\n function admin() external ifAdmin returns (address admin_) {\n admin_ = _getAdmin();\n }\n\n /**\n * @dev Returns the current implementation.\n *\n * NOTE: Only the admin can call this function. See {ProxyAdmin-getProxyImplementation}.\n *\n * TIP: To get this value clients can read directly from the storage slot shown below (specified by EIP1967) using the\n * https://eth.wiki/json-rpc/API#eth_getstorageat[`eth_getStorageAt`] RPC call.\n * `0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc`\n */\n function implementation() external ifAdmin returns (address implementation_) {\n implementation_ = _implementation();\n }\n\n /**\n * @dev Changes the admin of the proxy.\n *\n * Emits an {AdminChanged} event.\n *\n * NOTE: Only the admin can call this function. See {ProxyAdmin-changeProxyAdmin}.\n */\n function changeAdmin(address newAdmin) external virtual ifAdmin {\n _changeAdmin(newAdmin);\n }\n\n /**\n * @dev Upgrade the implementation of the proxy.\n *\n * NOTE: Only the admin can call this function. See {ProxyAdmin-upgrade}.\n */\n function upgradeTo(address newImplementation) external ifAdmin {\n _upgradeToAndCall(newImplementation, bytes(\"\"), false);\n }\n\n /**\n * @dev Upgrade the implementation of the proxy, and then call a function from the new implementation as specified\n * by `data`, which should be an encoded function call. This is useful to initialize new storage variables in the\n * proxied contract.\n *\n * NOTE: Only the admin can call this function. See {ProxyAdmin-upgradeAndCall}.\n */\n function upgradeToAndCall(address newImplementation, bytes calldata data) external payable ifAdmin {\n _upgradeToAndCall(newImplementation, data, true);\n }\n\n /**\n * @dev Returns the current admin.\n */\n function _admin() internal view virtual returns (address) {\n return _getAdmin();\n }\n\n /**\n * @dev Makes sure the admin cannot access the fallback function. See {Proxy-_beforeFallback}.\n */\n function _beforeFallback() internal virtual override {\n require(msg.sender != _getAdmin(), \"TransparentUpgradeableProxy: admin cannot fallback to proxy target\");\n super._beforeFallback();\n }\n}\n" + }, + "contracts/flashloan/FlashAngle.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\nimport \"@openzeppelin/contracts-upgradeable/security/ReentrancyGuardUpgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol\";\nimport \"@openzeppelin/contracts/interfaces/IERC3156FlashBorrower.sol\";\nimport \"@openzeppelin/contracts/interfaces/IERC3156FlashLender.sol\";\nimport \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\nimport \"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\";\n\nimport \"../interfaces/IAgToken.sol\";\nimport \"../interfaces/ICoreBorrow.sol\";\nimport \"../interfaces/IFlashAngle.sol\";\nimport \"../interfaces/ITreasury.sol\";\n\n/// @title FlashAngle\n/// @author Angle Labs, Inc.\n/// @notice Contract to take flash loans on top of several AgToken contracts\ncontract FlashAngle is IERC3156FlashLender, IFlashAngle, Initializable, ReentrancyGuardUpgradeable {\n using SafeERC20 for IERC20;\n /// @notice Base used for parameter computation\n uint256 public constant BASE_PARAMS = 10 ** 9;\n /// @notice Success message received when calling a `FlashBorrower` contract\n bytes32 public constant CALLBACK_SUCCESS = keccak256(\"ERC3156FlashBorrower.onFlashLoan\");\n\n /// @notice Struct encoding for a given stablecoin the parameters\n struct StablecoinData {\n // Maximum amount borrowable for this stablecoin\n uint256 maxBorrowable;\n // Flash loan fee taken by the protocol for a flash loan on this stablecoin\n uint64 flashLoanFee;\n // Treasury address responsible of the stablecoin\n address treasury;\n }\n\n // ======================= Parameters and References ===========================\n\n /// @notice Maps a stablecoin to the data and parameters for flash loans\n mapping(IAgToken => StablecoinData) public stablecoinMap;\n /// @inheritdoc IFlashAngle\n ICoreBorrow public core;\n\n // =============================== Event =======================================\n\n event FlashLoan(address indexed stablecoin, uint256 amount, IERC3156FlashBorrower indexed receiver);\n event FlashLoanParametersUpdated(IAgToken indexed stablecoin, uint64 _flashLoanFee, uint256 _maxBorrowable);\n\n // =============================== Errors ======================================\n\n error InvalidReturnMessage();\n error NotCore();\n error NotGovernorOrGuardian();\n error NotTreasury();\n error TooBigAmount();\n error TooHighParameterValue();\n error UnsupportedStablecoin();\n error ZeroAddress();\n\n /// @notice Initializes the contract\n /// @param _core Core address handling this module\n function initialize(ICoreBorrow _core) public initializer {\n if (address(_core) == address(0)) revert ZeroAddress();\n core = _core;\n }\n\n /// @custom:oz-upgrades-unsafe-allow constructor\n constructor() initializer {}\n\n // =================================== Modifiers ===============================\n\n /// @notice Checks whether the sender is the core contract\n modifier onlyCore() {\n if (msg.sender != address(core)) revert NotCore();\n _;\n }\n\n /// @notice Checks whether a given stablecoin has been initialized in this contract\n /// @param stablecoin Stablecoin to check\n /// @dev To check whether a stablecoin has been initialized, we just need to check whether its associated\n /// `treasury` address is not null in the `stablecoinMap`. This is what's checked in the `CoreBorrow` contract\n /// when adding support for a stablecoin\n modifier onlyExistingStablecoin(IAgToken stablecoin) {\n if (stablecoinMap[stablecoin].treasury == address(0)) revert UnsupportedStablecoin();\n _;\n }\n\n // ================================ ERC3156 Spec ===============================\n\n /// @inheritdoc IERC3156FlashLender\n function flashFee(address token, uint256 amount) external view returns (uint256) {\n return _flashFee(token, amount);\n }\n\n /// @inheritdoc IERC3156FlashLender\n function maxFlashLoan(address token) external view returns (uint256) {\n // It will be 0 anyway if the token was not added\n return stablecoinMap[IAgToken(token)].maxBorrowable;\n }\n\n /// @inheritdoc IERC3156FlashLender\n function flashLoan(\n IERC3156FlashBorrower receiver,\n address token,\n uint256 amount,\n bytes calldata data\n ) external nonReentrant returns (bool) {\n uint256 fee = _flashFee(token, amount);\n if (amount > stablecoinMap[IAgToken(token)].maxBorrowable) revert TooBigAmount();\n IAgToken(token).mint(address(receiver), amount);\n if (receiver.onFlashLoan(msg.sender, token, amount, fee, data) != CALLBACK_SUCCESS)\n revert InvalidReturnMessage();\n // Token must be an agToken here so normally no need to use `safeTransferFrom`, but out of safety\n // and in case governance whitelists an agToken which does not have a correct implementation, we prefer\n // to use `safeTransferFrom` here\n IERC20(token).safeTransferFrom(address(receiver), address(this), amount + fee);\n IAgToken(token).burnSelf(amount, address(this));\n emit FlashLoan(token, amount, receiver);\n return true;\n }\n\n /// @notice Internal function to compute the fee induced for taking a flash loan of `amount` of `token`\n /// @param token The loan currency\n /// @param amount The amount of tokens lent\n /// @dev This function will revert if the `token` requested is not whitelisted here\n function _flashFee(\n address token,\n uint256 amount\n ) internal view onlyExistingStablecoin(IAgToken(token)) returns (uint256) {\n return (amount * stablecoinMap[IAgToken(token)].flashLoanFee) / BASE_PARAMS;\n }\n\n // ============================ Treasury Only Function =========================\n\n /// @inheritdoc IFlashAngle\n function accrueInterestToTreasury(IAgToken stablecoin) external returns (uint256 balance) {\n address treasury = stablecoinMap[stablecoin].treasury;\n if (msg.sender != treasury) revert NotTreasury();\n balance = stablecoin.balanceOf(address(this));\n IERC20(address(stablecoin)).safeTransfer(treasury, balance);\n }\n\n // =========================== Governance Only Function ========================\n\n /// @notice Sets the parameters for a given stablecoin\n /// @param stablecoin Stablecoin to change the parameters for\n /// @param _flashLoanFee New flash loan fee for this stablecoin\n /// @param _maxBorrowable Maximum amount that can be borrowed in a single flash loan\n /// @dev Setting a `maxBorrowable` parameter equal to 0 is a way to pause the functionality\n /// @dev Parameters can only be modified for whitelisted stablecoins\n function setFlashLoanParameters(\n IAgToken stablecoin,\n uint64 _flashLoanFee,\n uint256 _maxBorrowable\n ) external onlyExistingStablecoin(stablecoin) {\n if (!core.isGovernorOrGuardian(msg.sender)) revert NotGovernorOrGuardian();\n if (_flashLoanFee > BASE_PARAMS) revert TooHighParameterValue();\n stablecoinMap[stablecoin].flashLoanFee = _flashLoanFee;\n stablecoinMap[stablecoin].maxBorrowable = _maxBorrowable;\n emit FlashLoanParametersUpdated(stablecoin, _flashLoanFee, _maxBorrowable);\n }\n\n // =========================== CoreBorrow Only Functions =======================\n\n /// @inheritdoc IFlashAngle\n function addStablecoinSupport(address _treasury) external onlyCore {\n stablecoinMap[IAgToken(ITreasury(_treasury).stablecoin())].treasury = _treasury;\n }\n\n /// @inheritdoc IFlashAngle\n function removeStablecoinSupport(address _treasury) external onlyCore {\n delete stablecoinMap[IAgToken(ITreasury(_treasury).stablecoin())];\n }\n\n /// @inheritdoc IFlashAngle\n function setCore(address _core) external onlyCore {\n core = ICoreBorrow(_core);\n }\n}\n" + }, + "contracts/interfaces/coreModule/IAgTokenMainnet.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\n/// @title IAgTokenMainnet\n/// @author Angle Labs, Inc.\ninterface IAgTokenMainnet {\n function stableMaster() external view returns (address);\n}\n" + }, + "contracts/interfaces/coreModule/ICore.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\n/// @title ICore\n/// @author Angle Labs, Inc.\ninterface ICore {\n function stablecoinList() external view returns (address[] memory);\n}\n" + }, + "contracts/interfaces/coreModule/ILiquidityGauge.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\ninterface ILiquidityGauge {\n function deposit(\n uint256 _value,\n address _addr,\n // solhint-disable-next-line\n bool _claim_rewards\n ) external;\n\n function withdraw(\n uint256 _value,\n // solhint-disable-next-line\n bool _claim_rewards\n ) external;\n\n // solhint-disable-next-line\n function claim_rewards(address _addr, address _receiver) external;\n\n // solhint-disable-next-line\n function claimable_reward(address _addr, address _reward_token) external view returns (uint256 amount);\n}\n" + }, + "contracts/interfaces/coreModule/IOracleCore.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\n/// @title IOracleCore\n/// @author Angle Labs, Inc.\ninterface IOracleCore {\n function readUpper() external view returns (uint256);\n\n function readQuoteLower(uint256 baseAmount) external view returns (uint256);\n}\n" + }, + "contracts/interfaces/coreModule/IPerpetualManager.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\n/// @title IPerpetualManager\n/// @author Angle Labs, Inc.\ninterface IPerpetualManager {\n function totalHedgeAmount() external view returns (uint256);\n\n function maintenanceMargin() external view returns (uint64);\n\n function maxLeverage() external view returns (uint64);\n\n function targetHAHedge() external view returns (uint64);\n\n function limitHAHedge() external view returns (uint64);\n\n function lockTime() external view returns (uint64);\n\n function haBonusMalusDeposit() external view returns (uint64);\n\n function haBonusMalusWithdraw() external view returns (uint64);\n\n function xHAFeesDeposit(uint256) external view returns (uint64);\n\n function yHAFeesDeposit(uint256) external view returns (uint64);\n\n function xHAFeesWithdraw(uint256) external view returns (uint64);\n\n function yHAFeesWithdraw(uint256) external view returns (uint64);\n}\n" + }, + "contracts/interfaces/coreModule/IPoolManager.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\n/// @title IPoolManager\n/// @author Angle Labs, Inc.\ninterface IPoolManager {\n function feeManager() external view returns (address);\n\n function strategyList(uint256) external view returns (address);\n}\n" + }, + "contracts/interfaces/coreModule/IStableMaster.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\nimport \"./IPerpetualManager.sol\";\nimport \"./IOracleCore.sol\";\n\n// Struct to handle all the parameters to manage the fees\n// related to a given collateral pool (associated to the stablecoin)\nstruct MintBurnData {\n // Values of the thresholds to compute the minting fees\n // depending on HA hedge (scaled by `BASE_PARAMS`)\n uint64[] xFeeMint;\n // Values of the fees at thresholds (scaled by `BASE_PARAMS`)\n uint64[] yFeeMint;\n // Values of the thresholds to compute the burning fees\n // depending on HA hedge (scaled by `BASE_PARAMS`)\n uint64[] xFeeBurn;\n // Values of the fees at thresholds (scaled by `BASE_PARAMS`)\n uint64[] yFeeBurn;\n // Max proportion of collateral from users that can be covered by HAs\n // It is exactly the same as the parameter of the same name in `PerpetualManager`, whenever one is updated\n // the other changes accordingly\n uint64 targetHAHedge;\n // Minting fees correction set by the `FeeManager` contract: they are going to be multiplied\n // to the value of the fees computed using the hedge curve\n // Scaled by `BASE_PARAMS`\n uint64 bonusMalusMint;\n // Burning fees correction set by the `FeeManager` contract: they are going to be multiplied\n // to the value of the fees computed using the hedge curve\n // Scaled by `BASE_PARAMS`\n uint64 bonusMalusBurn;\n // Parameter used to limit the number of stablecoins that can be issued using the concerned collateral\n uint256 capOnStableMinted;\n}\n\n// Struct to handle all the variables and parameters to handle SLPs in the protocol\n// including the fraction of interests they receive or the fees to be distributed to\n// them\nstruct SLPData {\n // Last timestamp at which the `sanRate` has been updated for SLPs\n uint256 lastBlockUpdated;\n // Fees accumulated from previous blocks and to be distributed to SLPs\n uint256 lockedInterests;\n // Max interests used to update the `sanRate` in a single block\n // Should be in collateral token base\n uint256 maxInterestsDistributed;\n // Amount of fees left aside for SLPs and that will be distributed\n // when the protocol is collateralized back again\n uint256 feesAside;\n // Part of the fees normally going to SLPs that is left aside\n // before the protocol is collateralized back again (depends on collateral ratio)\n // Updated by keepers and scaled by `BASE_PARAMS`\n uint64 slippageFee;\n // Portion of the fees from users minting and burning\n // that goes to SLPs (the rest goes to surplus)\n uint64 feesForSLPs;\n // Slippage factor that's applied to SLPs exiting (depends on collateral ratio)\n // If `slippage = BASE_PARAMS`, SLPs can get nothing, if `slippage = 0` they get their full claim\n // Updated by keepers and scaled by `BASE_PARAMS`\n uint64 slippage;\n // Portion of the interests from lending\n // that goes to SLPs (the rest goes to surplus)\n uint64 interestsForSLPs;\n}\n\n/// @title IStableMaster\n/// @author Angle Labs, Inc.\ninterface IStableMaster {\n function agToken() external view returns (address);\n\n function updateStocksUsers(uint256 amount, address poolManager) external;\n\n function collateralMap(\n address poolManager\n )\n external\n view\n returns (\n address token,\n address sanToken,\n IPerpetualManager perpetualManager,\n IOracleCore oracle,\n uint256 stocksUsers,\n uint256 sanRate,\n uint256 collatBase,\n SLPData memory slpData,\n MintBurnData memory feeData\n );\n\n function paused(bytes32) external view returns (bool);\n\n function deposit(uint256 amount, address user, address poolManager) external;\n\n function withdraw(uint256 amount, address burner, address dest, address poolManager) external;\n}\n" + }, + "contracts/interfaces/external/create2/ImmutableCreate2Factory.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\ninterface ImmutableCreate2Factory {\n function safeCreate2(bytes32 salt, bytes memory initCode) external payable returns (address deploymentAddress);\n\n function findCreate2Address(\n bytes32 salt,\n bytes calldata initCode\n ) external view returns (address deploymentAddress);\n\n function findCreate2AddressViaHash(\n bytes32 salt,\n bytes32 initCodeHash\n ) external view returns (address deploymentAddress);\n}\n" + }, + "contracts/interfaces/external/IERC1271.sol": { + "content": "// SPDX-License-Identifier: GPL-2.0-or-later\npragma solidity ^0.8.12;\n\n/// @title Interface for verifying contract-based account signatures\n/// @notice Interface that verifies provided signature for the data\n/// @dev Interface defined by EIP-1271\ninterface IERC1271 {\n /// @notice Returns whether the provided signature is valid for the provided data\n /// @dev MUST return the bytes4 magic value 0x1626ba7e when function passes.\n /// MUST NOT modify state (using STATICCALL for solc < 0.5, view modifier for solc > 0.5).\n /// MUST allow external calls.\n /// @param hash Hash of the data to be signed\n /// @param signature Signature byte array associated with _data\n /// @return magicValue The bytes4 magic value 0x1626ba7e\n function isValidSignature(bytes32 hash, bytes memory signature) external view returns (bytes4 magicValue);\n}\n" + }, + "contracts/interfaces/external/IERC4626.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\npragma solidity >=0.8.0;\n\nimport \"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\";\nimport \"@openzeppelin/contracts/token/ERC20/ERC20.sol\";\n\n/// @notice Minimal IERC4646 tokenized Vault interface.\n/// @author Forked from Solmate (https://github.com/Rari-Capital/solmate/blob/main/src/mixins/ERC4626.sol)\n/// @dev Do not use in production! ERC-4626 is still in the review stage and is subject to change.\ninterface IERC4626 {\n event Deposit(address indexed from, address indexed to, uint256 amount, uint256 shares);\n event Withdraw(address indexed from, address indexed to, uint256 amount, uint256 shares);\n\n /// @notice Transfers a given amount of asset to the reactor and mint shares accordingly\n /// @param amount Given amount of asset\n /// @param to Address to mint shares to\n /// @return shares Amount of shares minted to `to`\n function deposit(uint256 amount, address to) external returns (uint256 shares);\n\n /// @notice Mints a given amount of shares to the reactor and transfer assets accordingly\n /// @param shares Given amount of shares\n /// @param to Address to mint shares to\n /// @return amount Amount of `asset` taken to the `msg.sender` to mint `shares`\n function mint(uint256 shares, address to) external returns (uint256 amount);\n\n /// @notice Transfers a given amount of asset from the reactor and burn shares accordingly\n /// @param amount Given amount of asset\n /// @param to Address to transfer assets to\n /// @param from Address to burn shares from\n /// @return shares Amount of shares burnt in the operation\n function withdraw(uint256 amount, address to, address from) external returns (uint256 shares);\n\n /// @notice Burns a given amount of shares to the reactor and transfer assets accordingly\n /// @param shares Given amount of shares\n /// @param to Address to transfer assets to\n /// @param from Address to burn shares from\n /// @return amount Amount of assets redeemed in the operation\n function redeem(uint256 shares, address to, address from) external returns (uint256 amount);\n\n /// @notice Returns the total assets managed by this reactor\n function totalAssets() external view returns (uint256);\n\n /// @notice Converts an amount of assets to the corresponding amount of reactor shares\n /// @param assets Amount of asset to convert\n /// @return Shares corresponding to the amount of assets obtained\n function convertToShares(uint256 assets) external view returns (uint256);\n\n /// @notice Converts an amount of shares to its current value in asset\n /// @param shares Amount of shares to convert\n /// @return Amount of assets corresponding to the amount of assets given\n function convertToAssets(uint256 shares) external view returns (uint256);\n\n /// @notice Computes how many shares one would get by depositing `assets`\n /// @param assets Amount of asset to convert\n function previewDeposit(uint256 assets) external view returns (uint256);\n\n /// @notice Computes how many assets one would need to mint `shares`\n /// @param shares Amount of shares required\n function previewMint(uint256 shares) external view returns (uint256);\n\n /// @notice Computes how many shares one would need to withdraw assets\n /// @param assets Amount of asset to withdraw\n function previewWithdraw(uint256 assets) external view returns (uint256);\n\n /// @notice Computes how many assets one would get by burning shares\n /// @param shares Amount of shares to burn\n function previewRedeem(uint256 shares) external view returns (uint256);\n\n /// @notice Max deposit allowed for a user\n /// @param user Address of the user to check\n function maxDeposit(address user) external returns (uint256);\n\n /// @notice Max mint allowed for a user\n /// @param user Address of the user to check\n function maxMint(address user) external returns (uint256);\n\n /// @notice Max withdraw allowed for a user\n /// @param user Address of the user to check\n function maxWithdraw(address user) external returns (uint256);\n\n /// @notice Max redeem allowed for a user\n /// @param user Address of the user to check\n function maxRedeem(address user) external returns (uint256);\n}\n" + }, + "contracts/interfaces/external/IWETH9.sol": { + "content": "// SPDX-License-Identifier: GPL-2.0-or-later\npragma solidity ^0.8.12;\n\nimport \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\n\n/// @title Interface for WETH9\ninterface IWETH9 is IERC20 {\n /// @notice Deposit ether to get wrapped ether\n function deposit() external payable;\n\n /// @notice Withdraw wrapped ether to get ether\n function withdraw(uint256) external;\n}\n" + }, + "contracts/interfaces/external/layerZero/ILayerZeroEndpoint.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity >=0.5.0;\n\nimport \"./ILayerZeroUserApplicationConfig.sol\";\n\ninterface ILayerZeroEndpoint is ILayerZeroUserApplicationConfig {\n // @notice send a LayerZero message to the specified address at a LayerZero endpoint.\n // @param _dstChainId - the destination chain identifier\n // @param _destination - the address on destination chain (in bytes). address length/format may vary by chains\n // @param _payload - a custom bytes payload to send to the destination contract\n // @param _refundAddress - if the source transaction is cheaper than the amount of value passed, refund the additional amount to this address\n // @param _zroPaymentAddress - the address of the ZRO token holder who would pay for the transaction\n // @param _adapterParams - parameters for custom functionality. e.g. receive airdropped native gas from the relayer on destination\n function send(\n uint16 _dstChainId,\n bytes calldata _destination,\n bytes calldata _payload,\n address payable _refundAddress,\n address _zroPaymentAddress,\n bytes calldata _adapterParams\n ) external payable;\n\n // @notice used by the messaging library to publish verified payload\n // @param _srcChainId - the source chain identifier\n // @param _srcAddress - the source contract (as bytes) at the source chain\n // @param _dstAddress - the address on destination chain\n // @param _nonce - the unbound message ordering nonce\n // @param _gasLimit - the gas limit for external contract execution\n // @param _payload - verified payload to send to the destination contract\n function receivePayload(\n uint16 _srcChainId,\n bytes calldata _srcAddress,\n address _dstAddress,\n uint64 _nonce,\n uint256 _gasLimit,\n bytes calldata _payload\n ) external;\n\n // @notice get the inboundNonce of a lzApp from a source chain which could be EVM or non-EVM chain\n // @param _srcChainId - the source chain identifier\n // @param _srcAddress - the source chain contract address\n function getInboundNonce(uint16 _srcChainId, bytes calldata _srcAddress) external view returns (uint64);\n\n // @notice get the outboundNonce from this source chain which, consequently, is always an EVM\n // @param _srcAddress - the source chain contract address\n function getOutboundNonce(uint16 _dstChainId, address _srcAddress) external view returns (uint64);\n\n // @notice gets a quote in source native gas, for the amount that send() requires to pay for message delivery\n // @param _dstChainId - the destination chain identifier\n // @param _userApplication - the user app address on this EVM chain\n // @param _payload - the custom message to send over LayerZero\n // @param _payInZRO - if false, user app pays the protocol fee in native token\n // @param _adapterParam - parameters for the adapter service, e.g. send some dust native token to dstChain\n function estimateFees(\n uint16 _dstChainId,\n address _userApplication,\n bytes calldata _payload,\n bool _payInZRO,\n bytes calldata _adapterParam\n ) external view returns (uint256 nativeFee, uint256 zroFee);\n\n // @notice get this Endpoint's immutable source identifier\n function getChainId() external view returns (uint16);\n\n // @notice the interface to retry failed message on this Endpoint destination\n // @param _srcChainId - the source chain identifier\n // @param _srcAddress - the source chain contract address\n // @param _payload - the payload to be retried\n function retryPayload(uint16 _srcChainId, bytes calldata _srcAddress, bytes calldata _payload) external;\n\n // @notice query if any STORED payload (message blocking) at the endpoint.\n // @param _srcChainId - the source chain identifier\n // @param _srcAddress - the source chain contract address\n function hasStoredPayload(uint16 _srcChainId, bytes calldata _srcAddress) external view returns (bool);\n\n // @notice query if the _libraryAddress is valid for sending msgs.\n // @param _userApplication - the user app address on this EVM chain\n function getSendLibraryAddress(address _userApplication) external view returns (address);\n\n // @notice query if the _libraryAddress is valid for receiving msgs.\n // @param _userApplication - the user app address on this EVM chain\n function getReceiveLibraryAddress(address _userApplication) external view returns (address);\n\n // @notice query if the non-reentrancy guard for send() is on\n // @return true if the guard is on. false otherwise\n function isSendingPayload() external view returns (bool);\n\n // @notice query if the non-reentrancy guard for receive() is on\n // @return true if the guard is on. false otherwise\n function isReceivingPayload() external view returns (bool);\n\n // @notice get the configuration of the LayerZero messaging library of the specified version\n // @param _version - messaging library version\n // @param _chainId - the chainId for the pending config change\n // @param _userApplication - the contract address of the user application\n // @param _configType - type of configuration. every messaging library has its own convention.\n function getConfig(\n uint16 _version,\n uint16 _chainId,\n address _userApplication,\n uint256 _configType\n ) external view returns (bytes memory);\n\n // @notice get the send() LayerZero messaging library version\n // @param _userApplication - the contract address of the user application\n function getSendVersion(address _userApplication) external view returns (uint16);\n\n // @notice get the lzReceive() LayerZero messaging library version\n // @param _userApplication - the contract address of the user application\n function getReceiveVersion(address _userApplication) external view returns (uint16);\n}\n" + }, + "contracts/interfaces/external/layerZero/ILayerZeroReceiver.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity >=0.5.0;\n\ninterface ILayerZeroReceiver {\n // @notice LayerZero endpoint will invoke this function to deliver the message on the destination\n // @param _srcChainId - the source endpoint identifier\n // @param _srcAddress - the source sending contract address from the source chain\n // @param _nonce - the ordered message nonce\n // @param _payload - the signed payload is the UA bytes has encoded to be sent\n function lzReceive(uint16 _srcChainId, bytes calldata _srcAddress, uint64 _nonce, bytes calldata _payload) external;\n}\n" + }, + "contracts/interfaces/external/layerZero/ILayerZeroUserApplicationConfig.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity >=0.5.0;\n\ninterface ILayerZeroUserApplicationConfig {\n // @notice set the configuration of the LayerZero messaging library of the specified version\n // @param _version - messaging library version\n // @param _chainId - the chainId for the pending config change\n // @param _configType - type of configuration. every messaging library has its own convention.\n // @param _config - configuration in the bytes. can encode arbitrary content.\n function setConfig(uint16 _version, uint16 _chainId, uint256 _configType, bytes calldata _config) external;\n\n // @notice set the send() LayerZero messaging library version to _version\n // @param _version - new messaging library version\n function setSendVersion(uint16 _version) external;\n\n // @notice set the lzReceive() LayerZero messaging library version to _version\n // @param _version - new messaging library version\n function setReceiveVersion(uint16 _version) external;\n\n // @notice Only when the UA needs to resume the message flow in blocking mode and clear the stored payload\n // @param _srcChainId - the chainId of the source chain\n // @param _srcAddress - the contract address of the source contract at the source chain\n function forceResumeReceive(uint16 _srcChainId, bytes calldata _srcAddress) external;\n}\n" + }, + "contracts/interfaces/external/lido/IStETH.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\n/// @title IStETH\n/// @author Angle Labs, Inc.\n/// @notice Interface for the `StETH` contract\n/// @dev This interface only contains functions of the `StETH` which are called by other contracts\n/// of this module\ninterface IStETH {\n function getPooledEthByShares(uint256 _sharesAmount) external view returns (uint256);\n\n event Submitted(address sender, uint256 amount, address referral);\n\n function submit(address) external payable returns (uint256);\n\n function getSharesByPooledEth(uint256 _ethAmount) external view returns (uint256);\n}\n" + }, + "contracts/interfaces/external/lido/IWStETH.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\n/// @title IWStETH\n/// @author Angle Labs, Inc.\n/// @notice Interface for the `WStETH` contract\n/// @dev This interface only contains functions of the `WStETH` which are called by other contracts\n/// of this module\ninterface IWStETH {\n function wrap(uint256 _stETHAmount) external returns (uint256);\n\n function stETH() external view returns (address);\n}\n" + }, + "contracts/interfaces/external/uniswap/IUniswapRouter.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\nstruct ExactInputParams {\n bytes path;\n address recipient;\n uint256 deadline;\n uint256 amountIn;\n uint256 amountOutMinimum;\n}\n\n/// @title Router token swapping functionality\n/// @notice Functions for swapping tokens via Uniswap V3\ninterface IUniswapV3Router {\n /// @notice Swaps `amountIn` of one token for as much as possible of another along the specified path\n /// @param params The parameters necessary for the multi-hop swap, encoded as `ExactInputParams` in calldata\n /// @return amountOut The amount of the received token\n function exactInput(ExactInputParams calldata params) external payable returns (uint256 amountOut);\n}\n\n/// @title Router for price estimation functionality\n/// @notice Functions for getting the price of one token with respect to another using Uniswap V2\n/// @dev This interface is only used for non critical elements of the protocol\ninterface IUniswapV2Router {\n /// @notice Given an input asset amount, returns the maximum output amount of the\n /// other asset (accounting for fees) given reserves.\n /// @param path Addresses of the pools used to get prices\n function getAmountsOut(uint256 amountIn, address[] calldata path) external view returns (uint256[] memory amounts);\n\n function swapExactTokensForTokens(\n uint256 swapAmount,\n uint256 minExpected,\n address[] calldata path,\n address receiver,\n uint256 swapDeadline\n ) external;\n}\n" + }, + "contracts/interfaces/external/uniswap/IUniswapV3Pool.sol": { + "content": "// SPDX-License-Identifier: GPL-2.0-or-later\npragma solidity >=0.5.0;\n\n/// @title Pool state that never changes\n/// @notice These parameters are fixed for a pool forever, i.e., the methods will always return the same values\ninterface IUniswapV3Pool {\n /// @notice The first of the two tokens of the pool, sorted by address\n /// @return The token contract address\n function token0() external view returns (address);\n\n /// @notice The second of the two tokens of the pool, sorted by address\n /// @return The token contract address\n function token1() external view returns (address);\n}\n" + }, + "contracts/interfaces/governance/IVeBoostProxy.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\n/// @title IVeBoostProxy\n/// @author Angle Labs, Inc.\n/// @notice Interface for the `VeBoostProxy` contract\n/// @dev This interface only contains functions of the contract which are called by other contracts\n/// of this module\n/// @dev The `veBoostProxy` contract used by Angle is a full fork of Curve Finance implementation\ninterface IVeBoostProxy {\n /// @notice Reads the adjusted veANGLE balance of an address (adjusted by delegation)\n //solhint-disable-next-line\n function adjusted_balance_of(address) external view returns (uint256);\n}\n" + }, + "contracts/interfaces/IAgToken.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\nimport \"@openzeppelin/contracts-upgradeable/token/ERC20/IERC20Upgradeable.sol\";\n\n/// @title IAgToken\n/// @author Angle Labs, Inc.\n/// @notice Interface for the stablecoins `AgToken` contracts\n/// @dev This interface only contains functions of the `AgToken` contract which are called by other contracts\n/// of this module or of the first module of the Angle Protocol\ninterface IAgToken is IERC20Upgradeable {\n // ======================= Minter Role Only Functions ===========================\n\n /// @notice Lets the `StableMaster` contract or another whitelisted contract mint agTokens\n /// @param account Address to mint to\n /// @param amount Amount to mint\n /// @dev The contracts allowed to issue agTokens are the `StableMaster` contract, `VaultManager` contracts\n /// associated to this stablecoin as well as the flash loan module (if activated) and potentially contracts\n /// whitelisted by governance\n function mint(address account, uint256 amount) external;\n\n /// @notice Burns `amount` tokens from a `burner` address after being asked to by `sender`\n /// @param amount Amount of tokens to burn\n /// @param burner Address to burn from\n /// @param sender Address which requested the burn from `burner`\n /// @dev This method is to be called by a contract with the minter right after being requested\n /// to do so by a `sender` address willing to burn tokens from another `burner` address\n /// @dev The method checks the allowance between the `sender` and the `burner`\n function burnFrom(uint256 amount, address burner, address sender) external;\n\n /// @notice Burns `amount` tokens from a `burner` address\n /// @param amount Amount of tokens to burn\n /// @param burner Address to burn from\n /// @dev This method is to be called by a contract with a minter right on the AgToken after being\n /// requested to do so by an address willing to burn tokens from its address\n function burnSelf(uint256 amount, address burner) external;\n\n // ========================= Treasury Only Functions ===========================\n\n /// @notice Adds a minter in the contract\n /// @param minter Minter address to add\n /// @dev Zero address checks are performed directly in the `Treasury` contract\n function addMinter(address minter) external;\n\n /// @notice Removes a minter from the contract\n /// @param minter Minter address to remove\n /// @dev This function can also be called by a minter wishing to revoke itself\n function removeMinter(address minter) external;\n\n /// @notice Sets a new treasury contract\n /// @param _treasury New treasury address\n function setTreasury(address _treasury) external;\n\n // ========================= External functions ================================\n\n /// @notice Checks whether an address has the right to mint agTokens\n /// @param minter Address for which the minting right should be checked\n /// @return Whether the address has the right to mint agTokens or not\n function isMinter(address minter) external view returns (bool);\n\n /// @notice Get the associated treasury\n function treasury() external view returns (address);\n}\n" + }, + "contracts/interfaces/IAgTokenSideChainMultiBridge.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\nimport \"@openzeppelin/contracts-upgradeable/token/ERC20/extensions/draft-IERC20PermitUpgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/token/ERC20/IERC20Upgradeable.sol\";\n\n/// @title IAgTokenSideChainMultiBridge\n/// @author Angle Labs, Inc.\n/// @notice Interface for the canonical `AgToken` contracts\n/// @dev This interface only contains functions useful for bridge tokens to interact with the canonical token\ninterface IAgTokenSideChainMultiBridge is IERC20PermitUpgradeable, IERC20Upgradeable {\n /// @notice Mints the canonical token from a supported bridge token\n /// @param bridgeToken Bridge token to use to mint\n /// @param amount Amount of bridge tokens to send\n /// @param to Address to which the stablecoin should be sent\n /// @return Amount of the canonical stablecoin actually minted\n /// @dev Some fees may be taken by the protocol depending on the token used and on the address calling\n function swapIn(address bridgeToken, uint256 amount, address to) external returns (uint256);\n\n /// @notice Burns the canonical token in exchange for a bridge token\n /// @param bridgeToken Bridge token required\n /// @param amount Amount of canonical tokens to burn\n /// @param to Address to which the bridge token should be sent\n /// @return Amount of bridge tokens actually sent back\n /// @dev Some fees may be taken by the protocol depending on the token used and on the address calling\n function swapOut(address bridgeToken, uint256 amount, address to) external returns (uint256);\n}\n" + }, + "contracts/interfaces/IAngleRouter.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\n/// @title IAngleRouter\n/// @author Angle Labs, Inc.\n/// @notice Interface for the `AngleRouter` contract\n/// @dev This interface only contains functions of the `AngleRouter01` contract which are called by other contracts\n/// of this module\ninterface IAngleRouter {\n function mint(\n address user,\n uint256 amount,\n uint256 minStableAmount,\n address stablecoin,\n address collateral\n ) external;\n\n function burn(address user, uint256 amount, uint256 minAmountOut, address stablecoin, address collateral) external;\n\n function mapPoolManagers(\n address stableMaster,\n address collateral\n ) external view returns (address poolManager, address perpetualManager, address sanToken, address gauge);\n}\n" + }, + "contracts/interfaces/IAngleRouterSidechain.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\n/// @notice Action types\nenum ActionType {\n transfer,\n wrap,\n wrapNative,\n sweep,\n sweepNative,\n unwrap,\n unwrapNative,\n swapIn,\n swapOut,\n uniswapV3,\n oneInch,\n claimRewards,\n gaugeDeposit,\n borrower\n}\n\n/// @notice Data needed to get permits\nstruct PermitType {\n address token;\n address owner;\n uint256 value;\n uint256 deadline;\n uint8 v;\n bytes32 r;\n bytes32 s;\n}\n\n/// @title IAngleRouterSidechain\n/// @author Angle Labs, Inc.\n/// @notice Interface for the `AngleRouter` contract on other chains\ninterface IAngleRouterSidechain {\n function mixer(PermitType[] memory paramsPermit, ActionType[] memory actions, bytes[] calldata data) external;\n}\n" + }, + "contracts/interfaces/ICoreBorrow.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\n/// @title ICoreBorrow\n/// @author Angle Labs, Inc.\n/// @notice Interface for the `CoreBorrow` contract\n/// @dev This interface only contains functions of the `CoreBorrow` contract which are called by other contracts\n/// of this module\ninterface ICoreBorrow {\n /// @notice Checks if an address corresponds to a treasury of a stablecoin with a flash loan\n /// module initialized on it\n /// @param treasury Address to check\n /// @return Whether the address has the `FLASHLOANER_TREASURY_ROLE` or not\n function isFlashLoanerTreasury(address treasury) external view returns (bool);\n\n /// @notice Checks whether an address is governor of the Angle Protocol or not\n /// @param admin Address to check\n /// @return Whether the address has the `GOVERNOR_ROLE` or not\n function isGovernor(address admin) external view returns (bool);\n\n /// @notice Checks whether an address is governor or a guardian of the Angle Protocol or not\n /// @param admin Address to check\n /// @return Whether the address has the `GUARDIAN_ROLE` or not\n /// @dev Governance should make sure when adding a governor to also give this governor the guardian\n /// role by calling the `addGovernor` function\n function isGovernorOrGuardian(address admin) external view returns (bool);\n}\n" + }, + "contracts/interfaces/IFlashAngle.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\nimport \"./IAgToken.sol\";\nimport \"./ICoreBorrow.sol\";\n\n/// @title IFlashAngle\n/// @author Angle Labs, Inc.\n/// @notice Interface for the `FlashAngle` contract\n/// @dev This interface only contains functions of the contract which are called by other contracts\n/// of this module\ninterface IFlashAngle {\n /// @notice Reference to the `CoreBorrow` contract managing the FlashLoan module\n function core() external view returns (ICoreBorrow);\n\n /// @notice Sends the fees taken from flash loans to the treasury contract associated to the stablecoin\n /// @param stablecoin Stablecoin from which profits should be sent\n /// @return balance Amount of profits sent\n /// @dev This function can only be called by the treasury contract\n function accrueInterestToTreasury(IAgToken stablecoin) external returns (uint256 balance);\n\n /// @notice Adds support for a stablecoin\n /// @param _treasury Treasury associated to the stablecoin to add support for\n /// @dev This function can only be called by the `CoreBorrow` contract\n function addStablecoinSupport(address _treasury) external;\n\n /// @notice Removes support for a stablecoin\n /// @param _treasury Treasury associated to the stablecoin to remove support for\n /// @dev This function can only be called by the `CoreBorrow` contract\n function removeStablecoinSupport(address _treasury) external;\n\n /// @notice Sets a new core contract\n /// @param _core Core contract address to set\n /// @dev This function can only be called by the `CoreBorrow` contract\n function setCore(address _core) external;\n}\n" + }, + "contracts/interfaces/IKeeperRegistry.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\nimport \"@openzeppelin/contracts-upgradeable/token/ERC20/IERC20Upgradeable.sol\";\n\n/// @title IKeeperRegistry\n/// @author Angle Labs, Inc.\ninterface IKeeperRegistry {\n /// @notice Checks whether an address is whitelisted during oracle updates\n /// @param caller Address for which the whitelist should be checked\n /// @return Whether the address is trusted or not\n function isTrusted(address caller) external view returns (bool);\n}\n" + }, + "contracts/interfaces/ILiquidityGauge.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.7;\n\ninterface ILiquidityGauge {\n function deposit(\n uint256 _value,\n address _addr,\n // solhint-disable-next-line\n bool _claim_rewards\n ) external;\n\n function withdraw(\n uint256 _value,\n // solhint-disable-next-line\n bool _claim_rewards\n ) external;\n\n // solhint-disable-next-line\n function claim_rewards(address _addr, address _receiver) external;\n\n // solhint-disable-next-line\n function claimable_reward(address _addr, address _reward_token) external view returns (uint256 amount);\n\n /// @dev Only for testing purposes\n // solhint-disable-next-line\n function deposit_reward_token(address _rewardToken, uint256 _amount) external;\n}\n" + }, + "contracts/interfaces/IOracle.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\nimport \"./ITreasury.sol\";\nimport \"@chainlink/contracts/src/v0.8/interfaces/AggregatorV3Interface.sol\";\n\n/// @title IOracle\n/// @author Angle Labs, Inc.\n/// @notice Interface for the `Oracle` contract\n/// @dev This interface only contains functions of the contract which are called by other contracts\n/// of this module\ninterface IOracle {\n /// @notice Reads the rate from the Chainlink circuit and other data provided\n /// @return quoteAmount The current rate between the in-currency and out-currency in the base\n /// of the out currency\n /// @dev For instance if the out currency is EUR (and hence agEUR), then the base of the returned\n /// value is 10**18\n function read() external view returns (uint256);\n\n /// @notice Changes the treasury contract\n /// @param _treasury Address of the new treasury contract\n /// @dev This function can be called by an approved `VaultManager` contract which can call\n /// this function after being requested to do so by a `treasury` contract\n /// @dev In some situations (like reactor contracts), the `VaultManager` may not directly be linked\n /// to the `oracle` contract and as such we may need governors to be able to call this function as well\n function setTreasury(address _treasury) external;\n\n /// @notice Reference to the `treasury` contract handling this `VaultManager`\n function treasury() external view returns (ITreasury treasury);\n\n /// @notice Array with the list of Chainlink feeds in the order in which they are read\n function circuitChainlink() external view returns (AggregatorV3Interface[] memory);\n}\n" + }, + "contracts/interfaces/ISwapper.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\nimport \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\n\n/// @title ISwapper\n/// @author Angle Labs, Inc.\n/// @notice Interface for Swapper contracts\n/// @dev This interface defines the key functions `Swapper` contracts should have when interacting with\n/// Angle\ninterface ISwapper {\n /// @notice Notifies a contract that an address should be given `outToken` from `inToken`\n /// @param inToken Address of the token received\n /// @param outToken Address of the token to obtain\n /// @param outTokenRecipient Address to which the outToken should be sent\n /// @param outTokenOwed Minimum amount of outToken the `outTokenRecipient` address should have at the end of the call\n /// @param inTokenObtained Amount of collateral obtained by a related address prior\n /// to the call to this function\n /// @param data Extra data needed (to encode Uniswap swaps for instance)\n function swap(\n IERC20 inToken,\n IERC20 outToken,\n address outTokenRecipient,\n uint256 outTokenOwed,\n uint256 inTokenObtained,\n bytes calldata data\n ) external;\n}\n" + }, + "contracts/interfaces/ITreasury.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\nimport \"./IAgToken.sol\";\nimport \"./ICoreBorrow.sol\";\nimport \"./IFlashAngle.sol\";\n\n/// @title ITreasury\n/// @author Angle Labs, Inc.\n/// @notice Interface for the `Treasury` contract\n/// @dev This interface only contains functions of the `Treasury` which are called by other contracts\n/// of this module\ninterface ITreasury {\n /// @notice Stablecoin handled by this `treasury` contract\n function stablecoin() external view returns (IAgToken);\n\n /// @notice Checks whether a given address has the governor role\n /// @param admin Address to check\n /// @return Whether the address has the governor role\n /// @dev Access control is only kept in the `CoreBorrow` contract\n function isGovernor(address admin) external view returns (bool);\n\n /// @notice Checks whether a given address has the guardian or the governor role\n /// @param admin Address to check\n /// @return Whether the address has the guardian or the governor role\n /// @dev Access control is only kept in the `CoreBorrow` contract which means that this function\n /// queries the `CoreBorrow` contract\n function isGovernorOrGuardian(address admin) external view returns (bool);\n\n /// @notice Checks whether a given address has well been initialized in this contract\n /// as a `VaultManager`\n /// @param _vaultManager Address to check\n /// @return Whether the address has been initialized or not\n function isVaultManager(address _vaultManager) external view returns (bool);\n\n /// @notice Sets a new flash loan module for this stablecoin\n /// @param _flashLoanModule Reference to the new flash loan module\n /// @dev This function removes the minting right to the old flash loan module and grants\n /// it to the new module\n function setFlashLoanModule(address _flashLoanModule) external;\n\n /// @notice Gets the vault manager list\n function vaultManagerList(uint256 i) external returns (address);\n}\n" + }, + "contracts/interfaces/IVaultManager.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\nimport \"@openzeppelin/contracts/interfaces/IERC721Metadata.sol\";\nimport \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\nimport \"./ITreasury.sol\";\nimport \"./IOracle.sol\";\n\n// ========================= Key Structs and Enums =============================\n\n/// @notice Parameters associated to a given `VaultManager` contract: these all correspond\n/// to parameters which signification is detailed in the `VaultManagerStorage` file\nstruct VaultParameters {\n uint256 debtCeiling;\n uint64 collateralFactor;\n uint64 targetHealthFactor;\n uint64 interestRate;\n uint64 liquidationSurcharge;\n uint64 maxLiquidationDiscount;\n bool whitelistingActivated;\n uint256 baseBoost;\n}\n\n/// @notice Data stored to track someone's loan (or equivalently called position)\nstruct Vault {\n // Amount of collateral deposited in the vault, in collateral decimals. For example, if the collateral\n // is USDC with 6 decimals, then `collateralAmount` will be in base 10**6\n uint256 collateralAmount;\n // Normalized value of the debt (that is to say of the stablecoins borrowed). It is expressed\n // in the base of Angle stablecoins (i.e. `BASE_TOKENS = 10**18`)\n uint256 normalizedDebt;\n}\n\n/// @notice For a given `vaultID`, this encodes a liquidation opportunity that is to say details about the maximum\n/// amount that could be repaid by liquidating the position\n/// @dev All the values are null in the case of a vault which cannot be liquidated under these conditions\nstruct LiquidationOpportunity {\n // Maximum stablecoin amount that can be repaid upon liquidating the vault\n uint256 maxStablecoinAmountToRepay;\n // Collateral amount given to the person in the case where the maximum amount to repay is given\n uint256 maxCollateralAmountGiven;\n // Threshold value of stablecoin amount to repay: it is ok for a liquidator to repay below threshold,\n // but if this threshold is non null and the liquidator wants to repay more than threshold, it should repay\n // the max stablecoin amount given in this vault\n uint256 thresholdRepayAmount;\n // Discount proposed to the liquidator on the collateral\n uint256 discount;\n // Amount of debt in the vault\n uint256 currentDebt;\n}\n\n/// @notice Data stored during a liquidation process to keep in memory what's due to a liquidator and some\n/// essential data for vaults being liquidated\nstruct LiquidatorData {\n // Current amount of stablecoins the liquidator should give to the contract\n uint256 stablecoinAmountToReceive;\n // Current amount of collateral the contract should give to the liquidator\n uint256 collateralAmountToGive;\n // Bad debt accrued across the liquidation process\n uint256 badDebtFromLiquidation;\n // Oracle value (in stablecoin base) at the time of the liquidation\n uint256 oracleValue;\n // Value of the `interestAccumulator` at the time of the call\n uint256 newInterestAccumulator;\n}\n\n/// @notice Data to track during a series of action the amount to give or receive in stablecoins and collateral\n/// to the caller or associated addresses\nstruct PaymentData {\n // Stablecoin amount the contract should give\n uint256 stablecoinAmountToGive;\n // Stablecoin amount owed to the contract\n uint256 stablecoinAmountToReceive;\n // Collateral amount the contract should give\n uint256 collateralAmountToGive;\n // Collateral amount owed to the contract\n uint256 collateralAmountToReceive;\n}\n\n/// @notice Actions possible when composing calls to the different entry functions proposed\nenum ActionType {\n createVault,\n closeVault,\n addCollateral,\n removeCollateral,\n repayDebt,\n borrow,\n getDebtIn,\n permit\n}\n\n// ========================= Interfaces =============================\n\n/// @title IVaultManagerFunctions\n/// @author Angle Labs, Inc.\n/// @notice Interface for the `VaultManager` contract\n/// @dev This interface only contains functions of the contract which are called by other contracts\n/// of this module (without getters)\ninterface IVaultManagerFunctions {\n /// @notice Accrues interest accumulated across all vaults to the surplus and sends the surplus to the treasury\n /// @return surplusValue Value of the surplus communicated to the `Treasury`\n /// @return badDebtValue Value of the bad debt communicated to the `Treasury`\n /// @dev `surplus` and `badDebt` should be reset to 0 once their current value have been given to the `treasury` contract\n function accrueInterestToTreasury() external returns (uint256 surplusValue, uint256 badDebtValue);\n\n /// @notice Removes debt from a vault after being requested to do so by another `VaultManager` contract\n /// @param vaultID ID of the vault to remove debt from\n /// @param amountStablecoins Amount of stablecoins to remove from the debt: this amount is to be converted to an\n /// internal debt amount\n /// @param senderBorrowFee Borrowing fees from the contract which requested this: this is to make sure that people are not\n /// arbitraging difference in minting fees\n /// @param senderRepayFee Repay fees from the contract which requested this: this is to make sure that people are not arbitraging\n /// differences in repay fees\n /// @dev This function can only be called from a vaultManager registered in the same Treasury\n function getDebtOut(\n uint256 vaultID,\n uint256 amountStablecoins,\n uint256 senderBorrowFee,\n uint256 senderRepayFee\n ) external;\n\n /// @notice Gets the current debt of a vault\n /// @param vaultID ID of the vault to check\n /// @return Debt of the vault\n function getVaultDebt(uint256 vaultID) external view returns (uint256);\n\n /// @notice Gets the total debt across all vaults\n /// @return Total debt across all vaults, taking into account the interest accumulated\n /// over time\n function getTotalDebt() external view returns (uint256);\n\n /// @notice Sets the treasury contract\n /// @param _treasury New treasury contract\n /// @dev All required checks when setting up a treasury contract are performed in the contract\n /// calling this function\n function setTreasury(address _treasury) external;\n\n /// @notice Creates a vault\n /// @param toVault Address for which the va\n /// @return vaultID ID of the vault created\n /// @dev This function just creates the vault without doing any collateral or\n function createVault(address toVault) external returns (uint256);\n\n /// @notice Allows composability between calls to the different entry points of this module. Any user calling\n /// this function can perform any of the allowed actions in the order of their choice\n /// @param actions Set of actions to perform\n /// @param datas Data to be decoded for each action: it can include like the `vaultID` or the `stablecoinAmount` to borrow\n /// @param from Address from which stablecoins will be taken if one action includes burning stablecoins. This address\n /// should either be the `msg.sender` or be approved by the latter\n /// @param to Address to which stablecoins and/or collateral will be sent in case of\n /// @param who Address of the contract to handle in case of repayment of stablecoins from received collateral\n /// @param repayData Data to pass to the repayment contract in case of\n /// @return paymentData Struct containing the accounting changes from the protocol's perspective (like how much of collateral\n /// or how much has been received). Note that the values in the struct are not aggregated and you could have in the output\n /// a positive amount of stablecoins to receive as well as a positive amount of stablecoins to give\n /// @dev This function is optimized to reduce gas cost due to payment from or to the user and that expensive calls\n /// or computations (like `oracleValue`) are done only once\n /// @dev When specifying `vaultID` in `data`, it is important to know that if you specify `vaultID = 0`, it will simply\n /// use the latest `vaultID`. This is the default behavior, and unless you're engaging into some complex protocol actions\n /// it is encouraged to use `vaultID = 0` only when the first action of the batch is `createVault`\n function angle(\n ActionType[] memory actions,\n bytes[] memory datas,\n address from,\n address to,\n address who,\n bytes memory repayData\n ) external returns (PaymentData memory paymentData);\n\n /// @notice This function is a wrapper built on top of the function above. It enables users to interact with the contract\n /// without having to provide `who` and `repayData` parameters\n function angle(\n ActionType[] memory actions,\n bytes[] memory datas,\n address from,\n address to\n ) external returns (PaymentData memory paymentData);\n\n /// @notice Initializes the `VaultManager` contract\n /// @param _treasury Treasury address handling the contract\n /// @param _collateral Collateral supported by this contract\n /// @param _oracle Oracle contract used\n /// @param _symbol Symbol used to define the `VaultManager` name and symbol\n /// @dev The parameters and the oracle are the only elements which could be modified once the\n /// contract has been initialized\n /// @dev For the contract to be fully initialized, governance needs to set the parameters for the liquidation\n /// boost\n function initialize(\n ITreasury _treasury,\n IERC20 _collateral,\n IOracle _oracle,\n VaultParameters calldata params,\n string memory _symbol\n ) external;\n\n /// @notice Minimum amount of debt a vault can have, expressed in `BASE_TOKENS` that is to say the base of the agTokens\n function dust() external view returns (uint256);\n\n /// @notice Pauses external permissionless functions of the contract\n function togglePause() external;\n}\n\n/// @title IVaultManagerStorage\n/// @author Angle Labs, Inc.\n/// @notice Interface for the `VaultManager` contract\n/// @dev This interface contains getters of the contract's public variables used by other contracts\n/// of this module\ninterface IVaultManagerStorage {\n /// @notice Encodes the maximum ratio stablecoin/collateral a vault can have before being liquidated. It's what\n /// determines the minimum collateral ratio of a position\n function collateralFactor() external view returns (uint64);\n\n /// @notice Stablecoin handled by this contract. Another `VaultManager` contract could have\n /// the same rights as this `VaultManager` on the stablecoin contract\n function stablecoin() external view returns (IAgToken);\n\n /// @notice Reference to the `treasury` contract handling this `VaultManager`\n function treasury() external view returns (ITreasury);\n\n /// @notice Oracle contract to get access to the price of the collateral with respect to the stablecoin\n function oracle() external view returns (IOracle);\n\n /// @notice The `interestAccumulator` variable keeps track of the interest that should accrue to the protocol.\n /// The stored value is not necessarily the true value: this one is recomputed every time an action takes place\n /// within the protocol. It is in base `BASE_INTEREST`\n function interestAccumulator() external view returns (uint256);\n\n /// @notice Reference to the collateral handled by this `VaultManager`\n function collateral() external view returns (IERC20);\n\n /// @notice Total normalized amount of stablecoins borrowed, not taking into account the potential bad debt accumulated\n /// This value is expressed in the base of Angle stablecoins (`BASE_TOKENS = 10**18`)\n function totalNormalizedDebt() external view returns (uint256);\n\n /// @notice Maximum amount of stablecoins that can be issued with this contract. It is expressed in `BASE_TOKENS`\n function debtCeiling() external view returns (uint256);\n\n /// @notice Maps a `vaultID` to its data (namely collateral amount and normalized debt)\n function vaultData(uint256 vaultID) external view returns (uint256 collateralAmount, uint256 normalizedDebt);\n\n /// @notice ID of the last vault created. The `vaultIDCount` variables serves as a counter to generate a unique\n /// `vaultID` for each vault: it is like `tokenID` in basic ERC721 contracts\n function vaultIDCount() external view returns (uint256);\n}\n\n/// @title IVaultManager\n/// @author Angle Labs, Inc.\n/// @notice Interface for the `VaultManager` contract\ninterface IVaultManager is IVaultManagerFunctions, IVaultManagerStorage, IERC721Metadata {\n function isApprovedOrOwner(address spender, uint256 vaultID) external view returns (bool);\n}\n\n/// @title IVaultManagerListing\n/// @author Angle Labs, Inc.\n/// @notice Interface for the `VaultManagerListing` contract\ninterface IVaultManagerListing is IVaultManager {\n /// @notice Get the collateral owned by `user` in the contract\n /// @dev This function effectively sums the collateral amounts of all the vaults owned by `user`\n function getUserCollateral(address user) external view returns (uint256);\n}\n" + }, + "contracts/keeperMulticall/KeeperMulticall.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\nimport \"@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/access/AccessControlUpgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol\";\nimport \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\nimport \"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\";\nimport \"./RevertReasonParser.sol\";\n\n/// @title KeeperMulticall\n/// @notice Allows an authorized caller (keeper) to execute multiple actions in a single tx.\n/// @author Angle Labs, Inc.\n/// @dev Special features:\n/// - ability to pay the miner (for private Flashbots transactions)\n/// - swap tokens through 1inch\n/// @dev Tx need to be encoded as an array of Action. The flag `isDelegateCall` is used for calling functions within this same contract\ncontract KeeperMulticall is Initializable, AccessControlUpgradeable {\n using SafeERC20 for IERC20;\n\n bytes32 public constant KEEPER_ROLE = keccak256(\"KEEPER_ROLE\");\n\n //solhint-disable-next-line\n address private constant _oneInch = 0x1111111254fb6c44bAC0beD2854e76F90643097d;\n\n struct Action {\n address target;\n bytes data;\n bool isDelegateCall;\n }\n\n event LogAction(address indexed target, bytes data);\n event SentToMiner(uint256 indexed value);\n event Recovered(address indexed tokenAddress, address indexed to, uint256 amount);\n\n error AmountOutTooLow(uint256 amount, uint256 min);\n error BalanceTooLow();\n error FlashbotsErrorPayingMiner(uint256 value);\n error IncompatibleLengths();\n error RevertBytes();\n error WrongAmount();\n error ZeroAddress();\n\n constructor() initializer {}\n\n function initialize(address keeper) external initializer {\n __AccessControl_init();\n\n _setupRole(KEEPER_ROLE, keeper);\n _setRoleAdmin(KEEPER_ROLE, KEEPER_ROLE);\n }\n\n /// @notice Allows an authorized keeper to execute multiple actions in a single step\n /// @param actions Actions to be executed\n /// @param percentageToMiner Percentage to pay to miner expressed in bps (10000)\n /// @dev This is the main entry point for actions to be executed. The `isDelegateCall` flag is used for calling function inside this `KeeperMulticall` contract,\n /// if we call other contracts, the flag should be false\n function executeActions(\n Action[] memory actions,\n uint256 percentageToMiner\n ) external payable onlyRole(KEEPER_ROLE) returns (bytes[] memory) {\n uint256 numberOfActions = actions.length;\n if (numberOfActions == 0) revert IncompatibleLengths();\n\n bytes[] memory returnValues = new bytes[](numberOfActions + 1);\n\n uint256 balanceBefore = address(this).balance;\n\n for (uint256 i; i < numberOfActions; ++i) {\n returnValues[i] = _executeAction(actions[i]);\n }\n\n if (percentageToMiner != 0) {\n if (percentageToMiner >= 10000) revert WrongAmount();\n uint256 balanceAfter = address(this).balance;\n if (balanceAfter > balanceBefore) {\n uint256 amountToMiner = ((balanceAfter - balanceBefore) * percentageToMiner) / 10000;\n returnValues[numberOfActions] = payFlashbots(amountToMiner);\n }\n }\n\n return returnValues;\n }\n\n /// @notice Gets the action address and data and executes it\n /// @param action Action to be executed\n function _executeAction(Action memory action) internal returns (bytes memory) {\n bool success;\n bytes memory response;\n\n if (action.isDelegateCall) {\n //solhint-disable-next-line\n (success, response) = action.target.delegatecall(action.data);\n } else {\n //solhint-disable-next-line\n (success, response) = action.target.call(action.data);\n }\n\n require(success, RevertReasonParser.parse(response, \"action reverted: \"));\n emit LogAction(action.target, action.data);\n return response;\n }\n\n /// @notice Ability to pay miner directly. Used for Flashbots to execute private transactions\n /// @param value Value to be sent\n function payFlashbots(uint256 value) public payable onlyRole(KEEPER_ROLE) returns (bytes memory) {\n //solhint-disable-next-line\n (bool success, bytes memory response) = block.coinbase.call{ value: value }(\"\");\n if (!success) revert FlashbotsErrorPayingMiner(value);\n emit SentToMiner(value);\n return response;\n }\n\n /// @notice Used to check the balances the token holds for each token. If we don't have enough of a token, we revert the tx\n /// @param tokens Array of tokens to check\n /// @param minBalances Array of balances for each token\n function finalBalanceCheck(IERC20[] memory tokens, uint256[] memory minBalances) external view returns (bool) {\n uint256 tokensLength = tokens.length;\n if (tokensLength == 0 || tokensLength != minBalances.length) revert IncompatibleLengths();\n\n for (uint256 i; i < tokensLength; ++i) {\n if (address(tokens[i]) == 0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE) {\n if (address(this).balance < minBalances[i]) revert BalanceTooLow();\n } else {\n if (tokens[i].balanceOf(address(this)) < minBalances[i]) revert BalanceTooLow();\n }\n }\n\n return true;\n }\n\n /// @notice Swap token to another through 1Inch\n /// @param minAmountOut Minimum amount of `out` token to receive for the swap to happen\n /// @param payload Bytes needed for 1Inch API\n function swapToken(uint256 minAmountOut, bytes memory payload) external onlyRole(KEEPER_ROLE) {\n //solhint-disable-next-line\n (bool success, bytes memory result) = _oneInch.call(payload);\n if (!success) _revertBytes(result);\n\n uint256 amountOut = abi.decode(result, (uint256));\n if (amountOut < minAmountOut) revert AmountOutTooLow(amountOut, minAmountOut);\n }\n\n /// @notice Copied from 1Inch contract, used to revert if there is an error\n function _revertBytes(bytes memory errMsg) internal pure {\n if (errMsg.length != 0) {\n //solhint-disable-next-line\n assembly {\n revert(add(32, errMsg), mload(errMsg))\n }\n }\n revert RevertBytes();\n }\n\n /// @notice Approve a `spender` for `token`\n /// @param token Address of the token to approve\n /// @param spender Address of the spender to approve\n /// @param amount Amount to approve\n function approve(IERC20 token, address spender, uint256 amount) external onlyRole(KEEPER_ROLE) {\n uint256 currentAllowance = token.allowance(address(this), spender);\n if (currentAllowance < amount) {\n token.safeIncreaseAllowance(spender, amount - currentAllowance);\n } else if (currentAllowance > amount) {\n token.safeDecreaseAllowance(spender, currentAllowance - amount);\n }\n }\n\n receive() external payable {}\n\n /// @notice Withdraw stuck funds\n /// @param token Address of the token to recover\n /// @param receiver Address where to send the tokens\n /// @param amount Amount to recover\n function withdrawStuckFunds(address token, address receiver, uint256 amount) external onlyRole(KEEPER_ROLE) {\n if (receiver == address(0)) revert ZeroAddress();\n if (token == 0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE) {\n payable(receiver).transfer(amount);\n } else {\n IERC20(token).safeTransfer(receiver, amount);\n }\n\n emit Recovered(token, receiver, amount);\n }\n}\n" + }, + "contracts/keeperMulticall/MulticallWithFailure.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.12;\n\n/// @title MultiCallWithFailure\n/// @author Angle Labs, Inc.\n/// @notice Multicall contract allowing subcalls to fail without reverting the entire call\ncontract MultiCallWithFailure {\n error SubcallFailed();\n\n struct Call {\n address target;\n bytes data;\n bool canFail;\n }\n\n function multiCall(Call[] memory calls) external view returns (bytes[] memory) {\n bytes[] memory results = new bytes[](calls.length);\n\n for (uint256 i; i < calls.length; ++i) {\n (bool success, bytes memory result) = calls[i].target.staticcall(calls[i].data);\n if (!calls[i].canFail) {\n if (!success) {\n revert SubcallFailed();\n }\n }\n results[i] = result;\n }\n\n return results;\n }\n}\n" + }, + "contracts/keeperMulticall/RevertReasonParser.sol": { + "content": "// SPDX-License-Identifier: GNU-3\n\npragma solidity ^0.8.12;\n\n/// @title RevertReasonParser\n/// @author 1Inch team, taken from:\n/// - https://docs.1inch.io/docs/limit-order-protocol/smart-contract/libraries/RevertReasonParser/\n/// - https://etherscan.io/address/0x1111111254fb6c44bAC0beD2854e76F90643097d#code\nlibrary RevertReasonParser {\n bytes4 private constant _PANIC_SELECTOR = bytes4(keccak256(\"Panic(uint256)\"));\n bytes4 private constant _ERROR_SELECTOR = bytes4(keccak256(\"Error(string)\"));\n\n function parse(bytes memory data, string memory prefix) internal pure returns (string memory) {\n if (data.length >= 4) {\n bytes4 selector;\n //solhint-disable-next-line\n assembly {\n selector := mload(add(data, 0x20))\n }\n\n // 68 = 4-byte selector + 32 bytes offset + 32 bytes length\n if (selector == _ERROR_SELECTOR && data.length >= 68) {\n uint256 offset;\n bytes memory reason;\n // solhint-disable no-inline-assembly\n assembly {\n // 36 = 32 bytes data length + 4-byte selector\n offset := mload(add(data, 36))\n reason := add(data, add(36, offset))\n }\n /*\n revert reason is padded up to 32 bytes with ABI encoder: Error(string)\n also sometimes there is extra 32 bytes of zeros padded in the end:\n https://github.com/ethereum/solidity/issues/10170\n because of that we can't check for equality and instead check\n that offset + string length + extra 36 bytes is less than overall data length\n */\n require(data.length >= 36 + offset + reason.length, \"Invalid revert reason\");\n return string(abi.encodePacked(prefix, \"Error(\", reason, \")\"));\n }\n // 36 = 4-byte selector + 32 bytes integer\n else if (selector == _PANIC_SELECTOR && data.length == 36) {\n uint256 code;\n // solhint-disable no-inline-assembly\n assembly {\n // 36 = 32 bytes data length + 4-byte selector\n code := mload(add(data, 36))\n }\n return string(abi.encodePacked(prefix, \"Panic(\", _toHex(code), \")\"));\n }\n }\n\n return string(abi.encodePacked(prefix, \"Unknown(\", _toHex(data), \")\"));\n }\n\n function _toHex(uint256 value) private pure returns (string memory) {\n return _toHex(abi.encodePacked(value));\n }\n\n function _toHex(bytes memory data) private pure returns (string memory) {\n bytes16 alphabet = 0x30313233343536373839616263646566;\n bytes memory str = new bytes(2 + data.length * 2);\n str[0] = \"0\";\n str[1] = \"x\";\n for (uint256 i; i < data.length; ++i) {\n str[2 * i + 2] = alphabet[uint8(data[i] >> 4)];\n str[2 * i + 3] = alphabet[uint8(data[i] & 0x0f)];\n }\n return string(str);\n }\n}\n" + }, + "contracts/mock/Mock1Inch.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.12;\n\nimport \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\nimport \"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\";\n\ncontract Mock1Inch {\n using SafeERC20 for IERC20;\n\n function swap(address tokenIn, uint256 amountIn, address to, address tokenOut, uint256 amountOut) external {\n IERC20(tokenIn).safeTransferFrom(msg.sender, to, amountIn);\n if (tokenOut == 0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE) {\n //solhint-disable-next-line\n (bool sent, bytes memory data) = msg.sender.call{ value: amountOut }(\"\");\n data;\n require(sent, \"Failed to send Ether\");\n } else {\n IERC20(tokenOut).safeTransferFrom(to, msg.sender, amountOut);\n }\n }\n\n receive() external payable {}\n}\n" + }, + "contracts/mock/MockAnything.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.12;\n\ncontract MockAnything {\n uint256 public stateVar = 1;\n\n error CustomError();\n error CustomErrorWithValue(uint256);\n\n function fail(uint256 value) external view returns (uint256) {\n stateVar;\n if (value < 10) {\n revert CustomError();\n }\n if (value < 20) {\n revert CustomErrorWithValue(value);\n }\n return value + 1;\n }\n\n function modifyState(uint256 value) external {\n stateVar = value;\n }\n}\n" + }, + "contracts/mock/MockChainlinkOracle.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.7;\n\ninterface MockAggregatorV3Interface {\n function decimals() external view returns (uint8);\n\n function description() external view returns (string memory);\n\n function version() external view returns (uint256);\n\n function getRoundData(\n uint80 _roundId\n )\n external\n view\n returns (uint80 roundId, int256 answer, uint256 startedAt, uint256 updatedAt, uint80 answeredInRound);\n\n function latestRoundData()\n external\n view\n returns (uint80 roundId, int256 answer, uint256 startedAt, uint256 updatedAt, uint80 answeredInRound);\n}\n\ncontract MockChainlinkOracle is MockAggregatorV3Interface {\n uint80 public roundId = 0;\n uint8 public keyDecimals = 0;\n\n struct Entry {\n uint80 roundId;\n int256 answer;\n uint256 startedAt;\n uint256 updatedAt;\n uint80 answeredInRound;\n }\n\n mapping(uint256 => Entry) public entries;\n\n bool public latestRoundDataShouldRevert;\n\n string public desc;\n\n constructor() {}\n\n // Mock setup function\n function setLatestAnswer(int256 answer, uint256 timestamp) external {\n roundId++;\n entries[roundId] = Entry({\n roundId: roundId,\n answer: answer,\n startedAt: timestamp,\n updatedAt: timestamp,\n answeredInRound: roundId\n });\n }\n\n function setLatestAnswerWithRound(int256 answer, uint256 timestamp, uint80 _roundId) external {\n roundId = _roundId;\n entries[roundId] = Entry({\n roundId: roundId,\n answer: answer,\n startedAt: timestamp,\n updatedAt: timestamp,\n answeredInRound: roundId\n });\n }\n\n function setLatestAnswerRevert(int256 answer, uint256 timestamp) external {\n roundId++;\n entries[roundId] = Entry({\n roundId: roundId,\n answer: answer,\n startedAt: timestamp,\n updatedAt: timestamp,\n answeredInRound: roundId - 1\n });\n }\n\n function setLatestRoundDataShouldRevert(bool _shouldRevert) external {\n latestRoundDataShouldRevert = _shouldRevert;\n }\n\n function setDecimals(uint8 _decimals) external {\n keyDecimals = _decimals;\n }\n\n function setDescritpion(string memory _desc) external {\n desc = _desc;\n }\n\n function description() external view override returns (string memory) {\n return desc;\n }\n\n function version() external view override returns (uint256) {\n roundId;\n return 0;\n }\n\n function latestRoundData() external view override returns (uint80, int256, uint256, uint256, uint80) {\n if (latestRoundDataShouldRevert) {\n revert(\"latestRoundData reverted\");\n }\n return getRoundData(uint80(roundId));\n }\n\n function decimals() external view override returns (uint8) {\n return keyDecimals;\n }\n\n function getRoundData(uint80 _roundId) public view override returns (uint80, int256, uint256, uint256, uint80) {\n Entry memory entry = entries[_roundId];\n // Emulate a Chainlink aggregator\n require(entry.updatedAt > 0, \"No data present\");\n return (entry.roundId, entry.answer, entry.startedAt, entry.updatedAt, entry.answeredInRound);\n }\n}\n" + }, + "contracts/mock/MockCoreBorrow.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\nimport \"../interfaces/ICoreBorrow.sol\";\nimport \"../interfaces/IFlashAngle.sol\";\nimport \"../interfaces/ITreasury.sol\";\n\ncontract MockCoreBorrow is ICoreBorrow {\n mapping(address => bool) public flashLoaners;\n mapping(address => bool) public governors;\n mapping(address => bool) public guardians;\n\n function isFlashLoanerTreasury(address treasury) external view override returns (bool) {\n return flashLoaners[treasury];\n }\n\n function isGovernor(address admin) external view override returns (bool) {\n return governors[admin];\n }\n\n function isGovernorOrGuardian(address admin) external view override returns (bool) {\n return governors[admin] || guardians[admin];\n }\n\n function toggleGovernor(address admin) external {\n governors[admin] = !governors[admin];\n }\n\n function toggleGuardian(address admin) external {\n guardians[admin] = !guardians[admin];\n }\n\n function toggleFlashLoaners(address admin) external {\n flashLoaners[admin] = !flashLoaners[admin];\n }\n\n function addStablecoinSupport(IFlashAngle flashAngle, address _treasury) external {\n flashAngle.addStablecoinSupport(_treasury);\n }\n\n function removeStablecoinSupport(IFlashAngle flashAngle, address _treasury) external {\n flashAngle.removeStablecoinSupport(_treasury);\n }\n\n function setCore(IFlashAngle flashAngle, address _core) external {\n flashAngle.setCore(_core);\n }\n\n function setFlashLoanModule(ITreasury _treasury, address _flashLoanModule) external {\n _treasury.setFlashLoanModule(_flashLoanModule);\n }\n}\n" + }, + "contracts/mock/MockERC1271.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.12;\n\nimport \"../interfaces/external/IERC1271.sol\";\n\ncontract MockERC1271 is IERC1271 {\n uint256 public mode = 0;\n\n function setMode(uint256 _mode) public {\n mode = _mode;\n }\n\n /// @notice Returns whether the provided signature is valid for the provided data\n /// @dev MUST return the bytes4 magic value 0x1626ba7e when function passes.\n /// MUST NOT modify state (using STATICCALL for solc < 0.5, view modifier for solc > 0.5).\n /// MUST allow external calls.\n /// @return magicValue The bytes4 magic value 0x1626ba7e\n function isValidSignature(bytes32, bytes memory) external view returns (bytes4 magicValue) {\n if (mode == 1) magicValue = 0x1626ba7e;\n }\n}\n" + }, + "contracts/mock/MockERC721Receiver.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (token/ERC721/utils/ERC721Holder.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Implementation of the {IERC721Receiver} interface.\n *\n * Accepts all token transfers.\n * Make sure the contract is able to use its token with {IERC721-safeTransferFrom}, {IERC721-approve} or {IERC721-setApprovalForAll}.\n */\ncontract MockERC721Receiver {\n uint256 public mode = 0;\n\n function setMode(uint256 _mode) public {\n mode = _mode;\n }\n\n function onERC721Received(address, address, uint256, bytes memory) public view returns (bytes4) {\n require(mode != 1, \"0x1111111\");\n if (mode == 2) return this.setMode.selector;\n return this.onERC721Received.selector;\n }\n}\n" + }, + "contracts/mock/MockEulerPool.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\nimport \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\n\ncontract MockEulerPool {\n IERC20 public collateral;\n uint256 public poolSize;\n //solhint-disable-next-line\n uint256 public MAX_SANE_AMOUNT;\n\n mapping(address => uint256) public users;\n uint256 public interestRateAccumulator;\n\n constructor(IERC20 collateral_, uint256 poolSize_) {\n collateral = collateral_;\n poolSize = poolSize_;\n interestRateAccumulator = 10 ** 18;\n MAX_SANE_AMOUNT = type(uint112).max;\n }\n\n function setPoolSize(uint256 poolSize_) external {\n uint256 balance = collateral.balanceOf(address(this));\n poolSize = poolSize_;\n if (balance > poolSize_) collateral.transfer(msg.sender, balance - poolSize_);\n if (balance < poolSize_) collateral.transferFrom(msg.sender, address(this), poolSize_ - balance);\n }\n\n function setInterestRateAccumulator(uint256 interestRateAccumulator_) external {\n interestRateAccumulator = interestRateAccumulator_;\n }\n\n //solhint-disable-next-line\n function setMAXSANEAMOUNT(uint256 MAX_SANE_AMOUNT_) external {\n MAX_SANE_AMOUNT = MAX_SANE_AMOUNT_;\n }\n\n function balanceOfUnderlying(address account) external view returns (uint256) {\n return (users[account] * interestRateAccumulator) / 10 ** 18;\n }\n\n function deposit(uint256, uint256 amount) external {\n users[msg.sender] += (amount * 10 ** 18) / interestRateAccumulator;\n poolSize += amount;\n collateral.transferFrom(msg.sender, address(this), amount);\n }\n\n function withdraw(uint256, uint256 amount) external {\n if (amount == type(uint256).max) amount = (users[msg.sender] * interestRateAccumulator) / 10 ** 18;\n\n require(amount <= poolSize, \"4\");\n users[msg.sender] -= (amount * 10 ** 18) / interestRateAccumulator;\n collateral.transfer(msg.sender, amount);\n }\n}\n" + }, + "contracts/mock/MockFlashLoanModule.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\nimport \"../interfaces/IFlashAngle.sol\";\nimport \"../interfaces/ICoreBorrow.sol\";\n\ncontract MockFlashLoanModule is IFlashAngle {\n ICoreBorrow public override core;\n mapping(address => bool) public stablecoinsSupported;\n mapping(IAgToken => uint256) public interestAccrued;\n uint256 public surplusValue;\n\n constructor(ICoreBorrow _core) {\n core = _core;\n }\n\n function accrueInterestToTreasury(IAgToken stablecoin) external override returns (uint256 balance) {\n balance = surplusValue;\n interestAccrued[stablecoin] += balance;\n }\n\n function addStablecoinSupport(address _treasury) external override {\n stablecoinsSupported[_treasury] = true;\n }\n\n function removeStablecoinSupport(address _treasury) external override {\n stablecoinsSupported[_treasury] = false;\n }\n\n function setCore(address _core) external override {\n core = ICoreBorrow(_core);\n }\n\n function setSurplusValue(uint256 _surplusValue) external {\n surplusValue = _surplusValue;\n }\n}\n" + }, + "contracts/mock/MockFlashLoanReceiver.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.7;\n\nimport \"@openzeppelin/contracts/token/ERC20/ERC20.sol\";\n\nimport \"@openzeppelin/contracts/interfaces/IERC3156FlashBorrower.sol\";\n\nimport \"@openzeppelin/contracts/interfaces/IERC3156FlashLender.sol\";\n\ncontract MockFlashLoanReceiver is IERC3156FlashBorrower {\n bytes32 public constant CALLBACK_SUCCESS = keccak256(\"ERC3156FlashBorrower.onFlashLoan\");\n\n constructor() {}\n\n function onFlashLoan(\n address,\n address token,\n uint256 amount,\n uint256 fee,\n bytes calldata data\n ) external override returns (bytes32) {\n IERC20(token).approve(msg.sender, amount + fee);\n if (amount >= 10 ** 21) return keccak256(\"error\");\n if (amount == 2 * 10 ** 18) {\n IERC3156FlashLender(msg.sender).flashLoan(IERC3156FlashBorrower(address(this)), token, amount, data);\n return keccak256(\"reentrant\");\n } else return CALLBACK_SUCCESS;\n }\n}\n" + }, + "contracts/mock/MockInterestRateComputer.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\ncontract MockInterestRateComputer {\n uint256 public interestRate;\n uint256 public interestAccumulator;\n uint256 public immutable baseInterest;\n uint256 public immutable halfBase;\n\n uint256 public constant WEEK = 7 * 86400;\n\n constructor(uint256 _baseInterest, uint256 _interestRate) {\n interestAccumulator = _baseInterest;\n baseInterest = _baseInterest;\n halfBase = _baseInterest / 2;\n interestRate = _interestRate;\n }\n\n function _calculateAngle(uint256 exp, uint256 _interestAccumulator) internal view returns (uint256) {\n uint256 ratePerSecond = interestRate;\n if (exp == 0 || ratePerSecond == 0) return _interestAccumulator;\n uint256 expMinusOne = exp - 1;\n uint256 expMinusTwo = exp > 2 ? exp - 2 : 0;\n uint256 basePowerTwo = (ratePerSecond * ratePerSecond) / baseInterest;\n uint256 basePowerThree = (basePowerTwo * ratePerSecond) / baseInterest;\n uint256 secondTerm = (exp * expMinusOne * basePowerTwo) / 2;\n uint256 thirdTerm = (exp * expMinusOne * expMinusTwo * basePowerThree) / 6;\n return (_interestAccumulator * (baseInterest + ratePerSecond * exp + secondTerm + thirdTerm)) / baseInterest;\n }\n\n function _calculateAave(uint256 exp, uint256 _interestAccumulator) internal view returns (uint256) {\n uint256 ratePerSecond = interestRate;\n if (exp == 0 || ratePerSecond == 0) return _interestAccumulator;\n uint256 expMinusOne = exp - 1;\n uint256 expMinusTwo = exp > 2 ? exp - 2 : 0;\n uint256 basePowerTwo = (ratePerSecond * ratePerSecond + halfBase) / baseInterest;\n uint256 basePowerThree = (basePowerTwo * ratePerSecond + halfBase) / baseInterest;\n uint256 secondTerm = (exp * expMinusOne * basePowerTwo) / 2;\n uint256 thirdTerm = (exp * expMinusOne * expMinusTwo * basePowerThree) / 6;\n return (_interestAccumulator * (baseInterest + ratePerSecond * exp + secondTerm + thirdTerm)) / baseInterest;\n }\n\n function _calculateCompound(uint256 exp, uint256 _interestAccumulator) internal view returns (uint256) {\n return _interestAccumulator * (baseInterest + interestRate * exp);\n }\n\n function _rpow(uint256 x, uint256 n, uint256 base) internal pure returns (uint256 z) {\n //solhint-disable-next-line\n assembly {\n switch x\n case 0 {\n switch n\n case 0 {\n z := base\n }\n default {\n z := 0\n }\n }\n default {\n switch mod(n, 2)\n case 0 {\n z := base\n }\n default {\n z := x\n }\n let half := div(base, 2) // for rounding.\n for {\n n := div(n, 2)\n } n {\n n := div(n, 2)\n } {\n let xx := mul(x, x)\n if iszero(eq(div(xx, x), x)) {\n revert(0, 0)\n }\n let xxRound := add(xx, half)\n if lt(xxRound, xx) {\n revert(0, 0)\n }\n x := div(xxRound, base)\n if mod(n, 2) {\n let zx := mul(z, x)\n if and(iszero(iszero(x)), iszero(eq(div(zx, x), z))) {\n revert(0, 0)\n }\n let zxRound := add(zx, half)\n if lt(zxRound, zx) {\n revert(0, 0)\n }\n z := div(zxRound, base)\n }\n }\n }\n }\n }\n\n function _calculateMaker(uint256 delta, uint256 _interestAccumulator) internal view returns (uint256) {\n return (_rpow(baseInterest + interestRate, delta, baseInterest) * _interestAccumulator) / baseInterest;\n }\n\n function calculateAngle(uint256 delta) external view returns (uint256) {\n return _calculateAngle(delta, interestAccumulator);\n }\n\n function calculateAave(uint256 delta) external view returns (uint256) {\n return _calculateAave(delta, interestAccumulator);\n }\n\n function calculateMaker(uint256 delta) external view returns (uint256) {\n return _calculateMaker(delta, interestAccumulator);\n }\n\n function calculateAngle1Year() external view returns (uint256) {\n uint256 _interestAccumulator = interestAccumulator;\n for (uint256 i; i < 52; ++i) {\n _interestAccumulator = _calculateAngle(WEEK, _interestAccumulator);\n }\n return _interestAccumulator;\n }\n\n function calculateAave1Year() external view returns (uint256) {\n uint256 _interestAccumulator = interestAccumulator;\n for (uint256 i; i < 52; ++i) {\n _interestAccumulator = _calculateAave(WEEK, _interestAccumulator);\n }\n return _interestAccumulator;\n }\n\n function calculateMaker1Year() external view returns (uint256) {\n uint256 _interestAccumulator = interestAccumulator;\n for (uint256 i; i < 52; ++i) {\n _interestAccumulator = _calculateMaker(WEEK, _interestAccumulator);\n }\n return _interestAccumulator;\n }\n\n function calculateAngle1YearDirect() external view returns (uint256) {\n uint256 _interestAccumulator = interestAccumulator;\n _interestAccumulator = _calculateAngle(52 * WEEK, _interestAccumulator);\n\n return _interestAccumulator;\n }\n\n function calculateAave1YearDirect() external view returns (uint256) {\n uint256 _interestAccumulator = interestAccumulator;\n _interestAccumulator = _calculateAave(52 * WEEK, _interestAccumulator);\n\n return _interestAccumulator;\n }\n\n function calculateMaker1YearDirect() external view returns (uint256) {\n uint256 _interestAccumulator = interestAccumulator;\n _interestAccumulator = _calculateMaker(52 * WEEK, _interestAccumulator);\n\n return _interestAccumulator;\n }\n\n function calculateCompound1YearDirect() external view returns (uint256) {\n uint256 _interestAccumulator = interestAccumulator;\n _interestAccumulator = _calculateCompound(52 * WEEK, _interestAccumulator);\n\n return _interestAccumulator;\n }\n}\n" + }, + "contracts/mock/MockKeeperMulticall.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.12;\n\nimport \"@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/access/AccessControlUpgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol\";\nimport \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\nimport \"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\";\n\ncontract MockKeeperMulticall is Initializable, AccessControlUpgradeable {\n using SafeERC20 for IERC20;\n\n bytes32 public constant KEEPER_ROLE = keccak256(\"KEEPER_ROLE\");\n\n //solhint-disable-next-line\n address private constant _oneInch = 0x1111111254fb6c44bAC0beD2854e76F90643097d;\n\n struct Action {\n address target;\n bytes data;\n bool isDelegateCall;\n }\n\n event LogAction(address indexed target, bytes data);\n event SentToMiner(uint256 indexed value);\n event Recovered(address indexed tokenAddress, address indexed to, uint256 amount);\n\n error AmountOutTooLow(uint256 amount, uint256 min);\n error BalanceTooLow();\n error FlashbotsErrorPayingMiner(uint256 value);\n error IncompatibleLengths();\n error RevertBytes();\n error ZeroAddress();\n\n constructor() initializer {}\n\n function initialize(address keeper) public initializer {\n __AccessControl_init();\n\n _setupRole(KEEPER_ROLE, keeper);\n _setRoleAdmin(KEEPER_ROLE, KEEPER_ROLE);\n }\n}\n\ncontract MockKeeperMulticall2 {\n uint256 public varTest = 1;\n\n bytes32 public constant KEEPER_ROLE = keccak256(\"KEEPER_ROLE\");\n\n //solhint-disable-next-line\n address private constant _oneInch = 0x1111111254fb6c44bAC0beD2854e76F90643097d;\n\n struct Action {\n address target;\n bytes data;\n bool isDelegateCall;\n }\n\n event LogAction(address indexed target, bytes data);\n event SentToMiner(uint256 indexed value);\n event Recovered(address indexed tokenAddress, address indexed to, uint256 amount);\n\n error AmountOutTooLow(uint256 amount, uint256 min);\n error BalanceTooLow();\n error FlashbotsErrorPayingMiner(uint256 value);\n error IncompatibleLengths();\n error RevertBytes();\n error ZeroAddress();\n\n function functionTest() external pure returns (bool) {\n return true;\n }\n}\n" + }, + "contracts/mock/MockLayerZero.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\ninterface ILzApp {\n function lzReceive(uint16 _srcChainId, bytes memory _srcAddress, uint64 _nonce, bytes memory _payload) external;\n}\n\ncontract MockLayerZero {\n mapping(uint16 => uint256) public counters;\n uint256 public config;\n mapping(uint16 => uint64) public outboundNonce;\n uint256 public resumeReceived;\n uint256 public sendVersion;\n uint256 public receiveVersion;\n\n /// @notice Initiate with a fixe change rate\n constructor() {}\n\n function send(\n uint16 _dstChainId,\n bytes calldata,\n bytes calldata,\n address,\n address,\n bytes calldata\n ) external payable {\n counters[_dstChainId] += 1;\n }\n\n function getOutboundNonce(uint16 _dstChainId, address) external view returns (uint64) {\n return outboundNonce[_dstChainId];\n }\n\n function setOutBoundNonce(uint16 _from, uint64 value) external {\n outboundNonce[_from] = value;\n }\n\n function lzReceive(\n address lzApp,\n uint16 _srcChainId,\n bytes memory _srcAddress,\n uint64 _nonce,\n bytes memory _payload\n ) public {\n ILzApp(lzApp).lzReceive(_srcChainId, _srcAddress, _nonce, _payload);\n }\n\n function estimateFees(\n uint16,\n address,\n bytes calldata,\n bool,\n bytes calldata\n ) external pure returns (uint256 nativeFee, uint256 zroFee) {\n return (123, 456);\n }\n\n function setConfig(uint16, uint16, uint256 _configType, bytes calldata) external {\n config = _configType;\n }\n\n function getConfig(uint16, uint16, address, uint256) external view returns (bytes memory) {\n return abi.encodePacked(config);\n }\n\n function setSendVersion(uint16 _version) external {\n sendVersion = _version;\n }\n\n function setReceiveVersion(uint16 _version) external {\n receiveVersion = _version;\n }\n\n function forceResumeReceive(uint16, bytes calldata) external {\n resumeReceived = 1 - resumeReceived;\n }\n}\n" + }, + "contracts/mock/MockLiquidityGauge.sol": { + "content": "// SPDX-License-Identifier: UNLICENSED\npragma solidity ^0.8.12;\n\nimport { ILiquidityGauge } from \"../interfaces/coreModule/ILiquidityGauge.sol\";\nimport \"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\";\nimport \"@openzeppelin/contracts/token/ERC20/ERC20.sol\";\n\ncontract MockLiquidityGauge is ILiquidityGauge, ERC20 {\n using SafeERC20 for IERC20;\n\n IERC20 internal _ANGLE = IERC20(0x31429d1856aD1377A8A0079410B297e1a9e214c2);\n IERC20 internal _token;\n mapping(address => uint256) public rewards;\n\n constructor(string memory name_, string memory symbol_, address token_) ERC20(name_, symbol_) {\n _token = IERC20(token_);\n }\n\n function deposit(\n uint256 _value,\n address _addr,\n // solhint-disable-next-line\n bool\n ) external {\n _token.safeTransferFrom(msg.sender, address(this), _value);\n _mint(_addr, _value);\n }\n\n function withdraw(\n uint256 _value,\n // solhint-disable-next-line\n bool\n ) external {\n _burn(msg.sender, _value);\n _token.safeTransfer(msg.sender, _value);\n }\n\n // solhint-disable-next-line\n function claim_rewards(address _addr, address _receiver) external {\n if (_receiver == address(0)) _receiver = _addr;\n _ANGLE.safeTransfer(_receiver, rewards[_addr]);\n rewards[_addr] = 0;\n }\n\n // solhint-disable-next-line\n function claimable_reward(address _addr, address) external view returns (uint256 amount) {\n return rewards[_addr];\n }\n\n function setReward(address receiver_, uint256 amount) external {\n rewards[receiver_] = amount;\n }\n}\n" + }, + "contracts/mock/MockOracle.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.7;\n\nimport \"../interfaces/IOracle.sol\";\n\ncontract MockOracle is IOracle {\n event Update(uint256 _peg);\n\n ITreasury public treasury;\n\n uint256 public base = 1 ether;\n uint256 public precision = 1 ether;\n uint256 public rate;\n bool public outdated;\n\n /// @notice Initiate with a fixe change rate\n constructor(uint256 rate_, ITreasury _treasury) {\n rate = rate_;\n treasury = _treasury;\n }\n\n /// @notice Mock read\n function read() external view override returns (uint256) {\n return rate;\n }\n\n /// @notice change oracle rate\n function update(uint256 newRate) external {\n rate = newRate;\n }\n\n function setTreasury(address _treasury) external override {\n treasury = ITreasury(_treasury);\n }\n\n function circuitChainlink() external pure override returns (AggregatorV3Interface[] memory) {}\n}\n" + }, + "contracts/mock/MockPolygonAgEUR.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.12;\n\nimport \"../agToken/polygon/utils/ERC20UpgradeableCustom.sol\";\nimport \"@openzeppelin/contracts-upgradeable/access/AccessControlUpgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/utils/cryptography/draft-EIP712Upgradeable.sol\";\nimport \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\nimport \"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\";\n\nimport \"../interfaces/IAgToken.sol\";\nimport \"../interfaces/ITreasury.sol\";\n\ninterface IChildToken {\n function deposit(address user, bytes calldata depositData) external;\n\n function withdraw(uint256 amount) external;\n}\n\ncontract MockPolygonAgEUR is\n Initializable,\n ERC20UpgradeableCustom,\n AccessControlUpgradeable,\n EIP712Upgradeable,\n IChildToken\n{\n bytes32 public constant DEPOSITOR_ROLE = keccak256(\"DEPOSITOR_ROLE\");\n\n /// @dev Emitted when the child chain manager changes\n event ChildChainManagerAdded(address newAddress);\n event ChildChainManagerRevoked(address oldAddress);\n\n constructor() initializer {}\n\n function initialize(\n string memory _name,\n string memory _symbol,\n address childChainManager,\n address guardian\n ) public initializer {\n __ERC20_init(_name, _symbol);\n __AccessControl_init();\n _setupRole(DEFAULT_ADMIN_ROLE, guardian);\n _setupRole(DEPOSITOR_ROLE, childChainManager);\n __EIP712_init(_name, \"1\");\n }\n\n /**\n * @notice Called when the bridge has tokens to mint\n * @param user Address to mint the token to\n * @param depositData Encoded amount to mint\n */\n function deposit(address user, bytes calldata depositData) external override {\n require(hasRole(DEPOSITOR_ROLE, msg.sender));\n uint256 amount = abi.decode(depositData, (uint256));\n _mint(user, amount);\n }\n\n /**\n * @notice Called when user wants to withdraw tokens back to root chain\n * @dev Should burn user's tokens. This transaction will be verified when exiting on root chain\n * @param amount Amount of tokens to withdraw\n */\n function withdraw(uint256 amount) external override {\n _burn(_msgSender(), amount);\n }\n\n // =============================================================================\n // ======================= New data added for the upgrade ======================\n // =============================================================================\n\n mapping(address => bool) public isMinter;\n /// @notice Reference to the treasury contract which can grant minting rights\n address public treasury;\n /// @notice Boolean to check whether the contract has been reinitialized after its upgrade\n bool public treasuryInitialized;\n\n using SafeERC20 for IERC20;\n\n /// @notice Base used for fee computation\n uint256 public constant BASE_PARAMS = 10 ** 9;\n\n // =============================== Bridging Data ===============================\n\n /// @notice Struct with some data about a specific bridge token\n struct BridgeDetails {\n // Limit on the balance of bridge token held by the contract: it is designed\n // to reduce the exposure of the system to hacks\n uint256 limit;\n // Limit on the hourly volume of token minted through this bridge\n // Technically the limit over a rolling hour is hourlyLimit x2 as hourly limit\n // is enforced only between x:00 and x+1:00\n uint256 hourlyLimit;\n // Fee taken for swapping in and out the token\n uint64 fee;\n // Whether the associated token is allowed or not\n bool allowed;\n // Whether swapping in and out from the associated token is paused or not\n bool paused;\n }\n\n /// @notice Maps a bridge token to data\n mapping(address => BridgeDetails) public bridges;\n /// @notice List of all bridge tokens\n address[] public bridgeTokensList;\n /// @notice Maps a bridge token to the associated hourly volume\n mapping(address => mapping(uint256 => uint256)) public usage;\n /// @notice Maps an address to whether it is exempt of fees for when it comes to swapping in and out\n mapping(address => uint256) public isFeeExempt;\n\n uint256[44] private __gap;\n\n // ================================== Events ===================================\n\n event BridgeTokenAdded(address indexed bridgeToken, uint256 limit, uint256 hourlyLimit, uint64 fee, bool paused);\n event BridgeTokenToggled(address indexed bridgeToken, bool toggleStatus);\n event BridgeTokenRemoved(address indexed bridgeToken);\n event BridgeTokenFeeUpdated(address indexed bridgeToken, uint64 fee);\n event BridgeTokenLimitUpdated(address indexed bridgeToken, uint256 limit);\n event BridgeTokenHourlyLimitUpdated(address indexed bridgeToken, uint256 hourlyLimit);\n event HourlyLimitUpdated(uint256 hourlyLimit);\n event FeeToggled(address indexed theAddress, uint256 toggleStatus);\n event KeeperToggled(address indexed keeper, bool toggleStatus);\n event MinterToggled(address indexed minter);\n event Recovered(address indexed token, address indexed to, uint256 amount);\n event TreasuryUpdated(address indexed _treasury);\n\n // ================================== Errors ===================================\n\n error AssetStillControlledInReserves();\n error BurnAmountExceedsAllowance();\n error HourlyLimitExceeded();\n error InvalidSender();\n error InvalidToken();\n error InvalidTreasury();\n error NotGovernor();\n error NotGovernorOrGuardian();\n error NotMinter();\n error NotTreasury();\n error TooBigAmount();\n error TooHighParameterValue();\n error TreasuryAlreadyInitialized();\n error ZeroAddress();\n\n /// @notice Checks to see if it is the `Treasury` calling this contract\n /// @dev There is no Access Control here, because it can be handled cheaply through this modifier\n modifier onlyTreasury() {\n if (msg.sender != treasury) revert NotTreasury();\n _;\n }\n\n /// @notice Checks whether the sender has the minting right\n modifier onlyMinter() {\n if (!isMinter[msg.sender]) revert NotMinter();\n _;\n }\n\n /// @notice Checks whether the `msg.sender` has the governor role or not\n modifier onlyGovernor() {\n if (!ITreasury(treasury).isGovernor(msg.sender)) revert NotGovernor();\n _;\n }\n\n /// @notice Checks whether the `msg.sender` has the governor role or the guardian role\n modifier onlyGovernorOrGuardian() {\n if (!ITreasury(treasury).isGovernorOrGuardian(msg.sender)) revert NotGovernorOrGuardian();\n _;\n }\n\n /// @notice Sets up the treasury contract on Polygon after the upgrade\n /// @param _treasury Address of the treasury contract\n function setUpTreasury(address _treasury) external {\n // Only governor on Polygon\n if (msg.sender != 0xdA2D2f638D6fcbE306236583845e5822554c02EA) revert NotGovernor();\n if (address(ITreasury(_treasury).stablecoin()) != address(this)) revert InvalidTreasury();\n if (treasuryInitialized) revert TreasuryAlreadyInitialized();\n treasury = _treasury;\n treasuryInitialized = true;\n emit TreasuryUpdated(_treasury);\n }\n\n // =========================== External Function ===============================\n\n /// @notice Allows anyone to burn agToken without redeeming collateral back\n /// @param amount Amount of stablecoins to burn\n /// @dev This function can typically be called if there is a settlement mechanism to burn stablecoins\n function burnStablecoin(uint256 amount) external {\n _burnCustom(msg.sender, amount);\n }\n\n // ======================= Minter Role Only Functions ==========================\n\n function burnSelf(uint256 amount, address burner) external onlyMinter {\n _burnCustom(burner, amount);\n }\n\n function burnFrom(uint256 amount, address burner, address sender) external onlyMinter {\n _burnFromNoRedeem(amount, burner, sender);\n }\n\n function mint(address account, uint256 amount) external onlyMinter {\n _mint(account, amount);\n }\n\n // ======================= Treasury Only Functions =============================\n\n function addMinter(address minter) external onlyTreasury {\n isMinter[minter] = true;\n emit MinterToggled(minter);\n }\n\n function removeMinter(address minter) external {\n if (msg.sender != address(treasury) && msg.sender != minter) revert InvalidSender();\n isMinter[minter] = false;\n emit MinterToggled(minter);\n }\n\n function setTreasury(address _treasury) external onlyTreasury {\n treasury = _treasury;\n emit TreasuryUpdated(_treasury);\n }\n\n // ============================ Internal Function ==============================\n\n /// @notice Internal version of the function `burnFromNoRedeem`\n /// @param amount Amount to burn\n /// @dev It is at the level of this function that allowance checks are performed\n function _burnFromNoRedeem(uint256 amount, address burner, address sender) internal {\n if (burner != sender) {\n uint256 currentAllowance = allowance(burner, sender);\n if (currentAllowance < amount) revert BurnAmountExceedsAllowance();\n _approve(burner, sender, currentAllowance - amount);\n }\n _burnCustom(burner, amount);\n }\n\n // ==================== External Permissionless Functions ======================\n\n /// @notice Returns the list of all supported bridge tokens\n /// @dev Helpful for UIs\n function allBridgeTokens() external view returns (address[] memory) {\n return bridgeTokensList;\n }\n\n /// @notice Returns the current volume for a bridge, for the current hour\n /// @dev Helpful for UIs\n function currentUsage(address bridge) external view returns (uint256) {\n return usage[bridge][block.timestamp / 3600];\n }\n\n /// @notice Mints the canonical token from a supported bridge token\n /// @param bridgeToken Bridge token to use to mint\n /// @param amount Amount of bridge tokens to send\n /// @param to Address to which the stablecoin should be sent\n /// @dev Some fees may be taken by the protocol depending on the token used and on the address calling\n function swapIn(address bridgeToken, uint256 amount, address to) external returns (uint256) {\n BridgeDetails memory bridgeDetails = bridges[bridgeToken];\n if (!bridgeDetails.allowed || bridgeDetails.paused) revert InvalidToken();\n uint256 balance = IERC20(bridgeToken).balanceOf(address(this));\n if (balance + amount > bridgeDetails.limit) {\n // In case someone maliciously sends tokens to this contract\n // Or the limit changes\n if (bridgeDetails.limit > balance) amount = bridgeDetails.limit - balance;\n else {\n amount = 0;\n }\n }\n\n // Checking requirement on the hourly volume\n uint256 hour = block.timestamp / 3600;\n uint256 hourlyUsage = usage[bridgeToken][hour] + amount;\n if (hourlyUsage > bridgeDetails.hourlyLimit) {\n // Edge case when the hourly limit changes\n if (bridgeDetails.hourlyLimit > usage[bridgeToken][hour])\n amount = bridgeDetails.hourlyLimit - usage[bridgeToken][hour];\n else {\n amount = 0;\n }\n }\n usage[bridgeToken][hour] = usage[bridgeToken][hour] + amount;\n\n IERC20(bridgeToken).safeTransferFrom(msg.sender, address(this), amount);\n uint256 canonicalOut = amount;\n // Computing fees\n if (isFeeExempt[msg.sender] == 0) {\n canonicalOut -= (canonicalOut * bridgeDetails.fee) / BASE_PARAMS;\n }\n _mint(to, canonicalOut);\n return canonicalOut;\n }\n\n /// @notice Burns the canonical token in exchange for a bridge token\n /// @param bridgeToken Bridge token required\n /// @param amount Amount of canonical tokens to burn\n /// @param to Address to which the bridge token should be sent\n /// @dev Some fees may be taken by the protocol depending on the token used and on the address calling\n function swapOut(address bridgeToken, uint256 amount, address to) external returns (uint256) {\n BridgeDetails memory bridgeDetails = bridges[bridgeToken];\n if (!bridgeDetails.allowed || bridgeDetails.paused) revert InvalidToken();\n\n _burnCustom(msg.sender, amount);\n uint256 bridgeOut = amount;\n if (isFeeExempt[msg.sender] == 0) {\n bridgeOut -= (bridgeOut * bridgeDetails.fee) / BASE_PARAMS;\n }\n IERC20(bridgeToken).safeTransfer(to, bridgeOut);\n return bridgeOut;\n }\n\n // ======================= Governance Functions ================================\n\n /// @notice Adds support for a bridge token\n /// @param bridgeToken Bridge token to add: it should be a version of the stablecoin from another bridge\n /// @param limit Limit on the balance of bridge token this contract could hold\n /// @param hourlyLimit Limit on the hourly volume for this bridge\n /// @param paused Whether swapping for this token should be paused or not\n /// @param fee Fee taken upon swapping for or against this token\n function addBridgeToken(\n address bridgeToken,\n uint256 limit,\n uint256 hourlyLimit,\n uint64 fee,\n bool paused\n ) external onlyGovernor {\n if (bridges[bridgeToken].allowed || bridgeToken == address(0)) revert InvalidToken();\n if (fee > BASE_PARAMS) revert TooHighParameterValue();\n BridgeDetails memory _bridge;\n _bridge.limit = limit;\n _bridge.hourlyLimit = hourlyLimit;\n _bridge.paused = paused;\n _bridge.fee = fee;\n _bridge.allowed = true;\n bridges[bridgeToken] = _bridge;\n bridgeTokensList.push(bridgeToken);\n emit BridgeTokenAdded(bridgeToken, limit, hourlyLimit, fee, paused);\n }\n\n /// @notice Removes support for a token\n /// @param bridgeToken Address of the bridge token to remove support for\n function removeBridgeToken(address bridgeToken) external onlyGovernor {\n if (IERC20(bridgeToken).balanceOf(address(this)) != 0) revert AssetStillControlledInReserves();\n delete bridges[bridgeToken];\n // Deletion from `bridgeTokensList` loop\n uint256 bridgeTokensListLength = bridgeTokensList.length;\n for (uint256 i; i < bridgeTokensListLength - 1; ++i) {\n if (bridgeTokensList[i] == bridgeToken) {\n // Replace the `bridgeToken` to remove with the last of the list\n bridgeTokensList[i] = bridgeTokensList[bridgeTokensListLength - 1];\n break;\n }\n }\n // Remove last element in array\n bridgeTokensList.pop();\n emit BridgeTokenRemoved(bridgeToken);\n }\n\n /// @notice Recovers any ERC20 token\n /// @dev Can be used to withdraw bridge tokens for them to be de-bridged on mainnet\n function recoverERC20(address tokenAddress, address to, uint256 amountToRecover) external onlyGovernor {\n IERC20(tokenAddress).safeTransfer(to, amountToRecover);\n emit Recovered(tokenAddress, to, amountToRecover);\n }\n\n /// @notice Updates the `limit` amount for `bridgeToken`\n function setLimit(address bridgeToken, uint256 limit) external onlyGovernorOrGuardian {\n if (!bridges[bridgeToken].allowed) revert InvalidToken();\n bridges[bridgeToken].limit = limit;\n emit BridgeTokenLimitUpdated(bridgeToken, limit);\n }\n\n /// @notice Updates the `hourlyLimit` amount for `bridgeToken`\n function setHourlyLimit(address bridgeToken, uint256 hourlyLimit) external onlyGovernorOrGuardian {\n if (!bridges[bridgeToken].allowed) revert InvalidToken();\n bridges[bridgeToken].hourlyLimit = hourlyLimit;\n emit BridgeTokenHourlyLimitUpdated(bridgeToken, hourlyLimit);\n }\n\n /// @notice Updates the `fee` value for `bridgeToken`\n function setSwapFee(address bridgeToken, uint64 fee) external onlyGovernorOrGuardian {\n if (!bridges[bridgeToken].allowed) revert InvalidToken();\n if (fee > BASE_PARAMS) revert TooHighParameterValue();\n bridges[bridgeToken].fee = fee;\n emit BridgeTokenFeeUpdated(bridgeToken, fee);\n }\n\n /// @notice Pauses or unpauses swapping in and out for a token\n function toggleBridge(address bridgeToken) external onlyGovernorOrGuardian {\n if (!bridges[bridgeToken].allowed) revert InvalidToken();\n bool pausedStatus = bridges[bridgeToken].paused;\n bridges[bridgeToken].paused = !pausedStatus;\n emit BridgeTokenToggled(bridgeToken, !pausedStatus);\n }\n\n /// @notice Toggles fees for the address `theAddress`\n function toggleFeesForAddress(address theAddress) external onlyGovernorOrGuardian {\n uint256 feeExemptStatus = 1 - isFeeExempt[theAddress];\n isFeeExempt[theAddress] = feeExemptStatus;\n emit FeeToggled(theAddress, feeExemptStatus);\n }\n}\n" + }, + "contracts/mock/MockRouter.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\nimport \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\nimport \"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\";\n\nimport \"../interfaces/IAngleRouter.sol\";\nimport \"../interfaces/external/uniswap/IUniswapRouter.sol\";\nimport \"../interfaces/external/lido/IWStETH.sol\";\n\ncontract MockRouter is IUniswapV3Router, IWStETH {\n using SafeERC20 for IERC20;\n\n uint256 public counterAngleMint;\n uint256 public counterAngleBurn;\n uint256 public counter1Inch;\n uint256 public counterUni;\n uint256 public counterWrap;\n uint256 public counterMixer;\n uint256 public amountOutUni;\n uint256 public multiplierMintBurn;\n uint256 public stETHMultiplier;\n address public inToken;\n address public outToken;\n\n address public stETH;\n\n /// @notice Action types\n enum ActionType {\n transfer,\n wrap,\n wrapNative,\n sweep,\n sweepNative,\n unwrap,\n unwrapNative,\n swapIn,\n swapOut,\n uniswapV3,\n oneInch,\n claimRewards,\n gaugeDeposit,\n borrower\n }\n\n /// @notice Data needed to get permits\n struct PermitType {\n address token;\n address owner;\n uint256 value;\n uint256 deadline;\n uint8 v;\n bytes32 r;\n bytes32 s;\n }\n\n constructor() {}\n\n function mint(address user, uint256 amount, uint256, address stablecoin, address collateral) external {\n counterAngleMint += 1;\n IERC20(collateral).safeTransferFrom(msg.sender, address(this), amount);\n IERC20(stablecoin).safeTransfer(user, (amount * 10 ** 9) / multiplierMintBurn);\n }\n\n function setStETH(address _stETH) external {\n stETH = _stETH;\n }\n\n function burn(address user, uint256 amount, uint256, address stablecoin, address collateral) external {\n counterAngleBurn += 1;\n IERC20(stablecoin).safeTransferFrom(msg.sender, address(this), amount);\n IERC20(collateral).safeTransfer(user, (amount * multiplierMintBurn) / 10 ** 9);\n }\n\n function mixer(\n PermitType[] memory paramsPermit,\n ActionType[] memory actions,\n bytes[] calldata data\n ) public payable virtual {\n paramsPermit;\n counterMixer += 1;\n for (uint256 i; i < actions.length; ++i) {\n if (actions[i] == ActionType.transfer) {\n (address transferToken, uint256 amount) = abi.decode(data[i], (address, uint256));\n IERC20(transferToken).safeTransferFrom(msg.sender, address(this), amount);\n }\n }\n }\n\n function wrap(uint256 amount) external returns (uint256 amountOut) {\n amountOut = (amount * stETHMultiplier) / 10 ** 9;\n counterWrap += 1;\n IERC20(stETH).safeTransferFrom(msg.sender, address(this), amount);\n IERC20(outToken).safeTransfer(msg.sender, amountOut);\n }\n\n function oneInch(uint256 amountIn) external returns (uint256 amountOut) {\n counter1Inch += 1;\n amountOut = (amountOutUni * amountIn) / 10 ** 9;\n IERC20(inToken).safeTransferFrom(msg.sender, address(this), amountIn);\n IERC20(outToken).safeTransfer(msg.sender, amountOut);\n }\n\n function oneInchReverts() external {\n counter1Inch += 1;\n revert(\"wrong swap\");\n }\n\n function oneInchRevertsWithoutMessage() external {\n counter1Inch += 1;\n require(false);\n }\n\n function exactInput(ExactInputParams calldata params) external payable returns (uint256 amountOut) {\n counterUni += 1;\n amountOut = (params.amountIn * amountOutUni) / 10 ** 9;\n IERC20(inToken).safeTransferFrom(msg.sender, address(this), params.amountIn);\n IERC20(outToken).safeTransfer(params.recipient, amountOut);\n require(amountOut >= params.amountOutMinimum);\n }\n\n function setMultipliers(uint256 a, uint256 b) external {\n amountOutUni = a;\n multiplierMintBurn = b;\n }\n\n function setStETHMultiplier(uint256 value) external {\n stETHMultiplier = value;\n }\n\n function setInOut(address _collateral, address _stablecoin) external {\n inToken = _collateral;\n outToken = _stablecoin;\n }\n}\n" + }, + "contracts/mock/MockSidechainAgEUR.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\nimport \"../agToken/AgToken.sol\";\nimport \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\nimport \"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\";\n\n/// @title AgTokenSideChainMultiBridge\n/// @author Angle Labs, Inc.\n/// @notice Contract for Angle agTokens on other chains than Ethereum mainnet\n/// @dev This contract supports bridge tokens having a minting right on the stablecoin (also referred to as the canonical\n/// or the native token)\n/// @dev References:\n/// - FRAX implementation: https://polygonscan.com/address/0x45c32fA6DF82ead1e2EF74d17b76547EDdFaFF89#code\n/// - QiDAO implementation: https://snowtrace.io/address/0x5c49b268c9841AFF1Cc3B0a418ff5c3442eE3F3b#code\ncontract MockSidechainAgEUR is AgToken {\n using SafeERC20 for IERC20;\n\n /// @notice Base used for fee computation\n uint256 public constant BASE_PARAMS = 10 ** 9;\n\n // =============================== Bridging Data ===============================\n\n /// @notice Struct with some data about a specific bridge token\n struct BridgeDetails {\n // Limit on the balance of bridge token held by the contract: it is designed\n // to reduce the exposure of the system to hacks\n uint256 limit;\n // Limit on the hourly volume of token minted through this bridge\n // Technically the limit over a rolling hour is hourlyLimit x2 as hourly limit\n // is enforced only between x:00 and x+1:00\n uint256 hourlyLimit;\n // Fee taken for swapping in and out the token\n uint64 fee;\n // Whether the associated token is allowed or not\n bool allowed;\n // Whether swapping in and out from the associated token is paused or not\n bool paused;\n }\n\n /// @notice Maps a bridge token to data\n mapping(address => BridgeDetails) public bridges;\n /// @notice List of all bridge tokens\n address[] public bridgeTokensList;\n /// @notice Maps a bridge token to the associated hourly volume\n mapping(address => mapping(uint256 => uint256)) public usage;\n /// @notice Maps an address to whether it is exempt of fees for when it comes to swapping in and out\n mapping(address => uint256) public isFeeExempt;\n\n // ================================== Events ===================================\n\n event BridgeTokenAdded(address indexed bridgeToken, uint256 limit, uint256 hourlyLimit, uint64 fee, bool paused);\n event BridgeTokenToggled(address indexed bridgeToken, bool toggleStatus);\n event BridgeTokenRemoved(address indexed bridgeToken);\n event BridgeTokenFeeUpdated(address indexed bridgeToken, uint64 fee);\n event BridgeTokenLimitUpdated(address indexed bridgeToken, uint256 limit);\n event BridgeTokenHourlyLimitUpdated(address indexed bridgeToken, uint256 hourlyLimit);\n event HourlyLimitUpdated(uint256 hourlyLimit);\n event Recovered(address indexed token, address indexed to, uint256 amount);\n event FeeToggled(address indexed theAddress, uint256 toggleStatus);\n\n // =============================== Errors ================================\n\n error AssetStillControlledInReserves();\n error HourlyLimitExceeded();\n error InvalidToken();\n error NotGovernor();\n error NotGovernorOrGuardian();\n error TooBigAmount();\n error TooHighParameterValue();\n error ZeroAddress();\n\n // ============================= Constructor ===================================\n\n /// @notice Checks whether the `msg.sender` has the governor role or not\n modifier onlyGovernor() {\n if (!ITreasury(treasury).isGovernor(msg.sender)) revert NotGovernor();\n _;\n }\n\n /// @notice Checks whether the `msg.sender` has the governor role or the guardian role\n modifier onlyGovernorOrGuardian() {\n if (!ITreasury(treasury).isGovernorOrGuardian(msg.sender)) revert NotGovernorOrGuardian();\n _;\n }\n\n // ==================== External Permissionless Functions ======================\n\n /// @notice Returns the list of all supported bridge tokens\n /// @dev Helpful for UIs\n function allBridgeTokens() external view returns (address[] memory) {\n return bridgeTokensList;\n }\n\n /// @notice Returns the current volume for a bridge, for the current hour\n /// @param bridgeToken Bridge used to mint\n /// @dev Helpful for UIs\n function currentUsage(address bridgeToken) external view returns (uint256) {\n return usage[bridgeToken][block.timestamp / 3600];\n }\n\n /// @notice Mints the canonical token from a supported bridge token\n /// @param bridgeToken Bridge token to use to mint\n /// @param amount Amount of bridge tokens to send\n /// @param to Address to which the stablecoin should be sent\n /// @return Amount of the canonical stablecoin actually minted\n /// @dev Some fees may be taken by the protocol depending on the token used and on the address calling\n function swapIn(address bridgeToken, uint256 amount, address to) external returns (uint256) {\n BridgeDetails memory bridgeDetails = bridges[bridgeToken];\n if (!bridgeDetails.allowed || bridgeDetails.paused) revert InvalidToken();\n uint256 balance = IERC20(bridgeToken).balanceOf(address(this));\n if (balance + amount > bridgeDetails.limit) {\n // In case someone maliciously sends tokens to this contract\n // Or the limit changes\n if (bridgeDetails.limit > balance) amount = bridgeDetails.limit - balance;\n else {\n amount = 0;\n }\n }\n\n // Checking requirement on the hourly volume\n uint256 hour = block.timestamp / 3600;\n uint256 hourlyUsage = usage[bridgeToken][hour] + amount;\n if (hourlyUsage > bridgeDetails.hourlyLimit) {\n // Edge case when the hourly limit changes\n if (bridgeDetails.hourlyLimit > usage[bridgeToken][hour])\n amount = bridgeDetails.hourlyLimit - usage[bridgeToken][hour];\n else {\n amount = 0;\n }\n }\n usage[bridgeToken][hour] = usage[bridgeToken][hour] + amount;\n\n IERC20(bridgeToken).safeTransferFrom(msg.sender, address(this), amount);\n uint256 canonicalOut = amount;\n // Computing fees\n if (isFeeExempt[msg.sender] == 0) {\n canonicalOut -= (canonicalOut * bridgeDetails.fee) / BASE_PARAMS;\n }\n _mint(to, canonicalOut);\n return canonicalOut;\n }\n\n /// @notice Burns the canonical token in exchange for a bridge token\n /// @param bridgeToken Bridge token required\n /// @param amount Amount of canonical tokens to burn\n /// @param to Address to which the bridge token should be sent\n /// @return Amount of bridge tokens actually sent back\n /// @dev Some fees may be taken by the protocol depending on the token used and on the address calling\n function swapOut(address bridgeToken, uint256 amount, address to) external returns (uint256) {\n BridgeDetails memory bridgeDetails = bridges[bridgeToken];\n if (!bridgeDetails.allowed || bridgeDetails.paused) revert InvalidToken();\n\n _burn(msg.sender, amount);\n uint256 bridgeOut = amount;\n if (isFeeExempt[msg.sender] == 0) {\n bridgeOut -= (bridgeOut * bridgeDetails.fee) / BASE_PARAMS;\n }\n IERC20(bridgeToken).safeTransfer(to, bridgeOut);\n return bridgeOut;\n }\n\n // ======================= Governance Functions ================================\n\n /// @notice Adds support for a bridge token\n /// @param bridgeToken Bridge token to add: it should be a version of the stablecoin from another bridge\n /// @param limit Limit on the balance of bridge token this contract could hold\n /// @param hourlyLimit Limit on the hourly volume for this bridge\n /// @param paused Whether swapping for this token should be paused or not\n /// @param fee Fee taken upon swapping for or against this token\n function addBridgeToken(\n address bridgeToken,\n uint256 limit,\n uint256 hourlyLimit,\n uint64 fee,\n bool paused\n ) external onlyGovernor {\n if (bridges[bridgeToken].allowed || bridgeToken == address(0)) revert InvalidToken();\n if (fee > BASE_PARAMS) revert TooHighParameterValue();\n BridgeDetails memory _bridge;\n _bridge.limit = limit;\n _bridge.hourlyLimit = hourlyLimit;\n _bridge.paused = paused;\n _bridge.fee = fee;\n _bridge.allowed = true;\n bridges[bridgeToken] = _bridge;\n bridgeTokensList.push(bridgeToken);\n emit BridgeTokenAdded(bridgeToken, limit, hourlyLimit, fee, paused);\n }\n\n /// @notice Removes support for a token\n /// @param bridgeToken Address of the bridge token to remove support for\n function removeBridgeToken(address bridgeToken) external onlyGovernor {\n if (IERC20(bridgeToken).balanceOf(address(this)) != 0) revert AssetStillControlledInReserves();\n delete bridges[bridgeToken];\n // Deletion from `bridgeTokensList` loop\n uint256 bridgeTokensListLength = bridgeTokensList.length;\n for (uint256 i; i < bridgeTokensListLength - 1; ++i) {\n if (bridgeTokensList[i] == bridgeToken) {\n // Replace the `bridgeToken` to remove with the last of the list\n bridgeTokensList[i] = bridgeTokensList[bridgeTokensListLength - 1];\n break;\n }\n }\n // Remove last element in array\n bridgeTokensList.pop();\n emit BridgeTokenRemoved(bridgeToken);\n }\n\n /// @notice Recovers any ERC20 token\n /// @dev Can be used to withdraw bridge tokens for them to be de-bridged on mainnet\n function recoverERC20(address tokenAddress, address to, uint256 amountToRecover) external onlyGovernor {\n IERC20(tokenAddress).safeTransfer(to, amountToRecover);\n emit Recovered(tokenAddress, to, amountToRecover);\n }\n\n /// @notice Updates the `limit` amount for `bridgeToken`\n function setLimit(address bridgeToken, uint256 limit) external onlyGovernorOrGuardian {\n if (!bridges[bridgeToken].allowed) revert InvalidToken();\n bridges[bridgeToken].limit = limit;\n emit BridgeTokenLimitUpdated(bridgeToken, limit);\n }\n\n /// @notice Updates the `hourlyLimit` amount for `bridgeToken`\n function setHourlyLimit(address bridgeToken, uint256 hourlyLimit) external onlyGovernorOrGuardian {\n if (!bridges[bridgeToken].allowed) revert InvalidToken();\n bridges[bridgeToken].hourlyLimit = hourlyLimit;\n emit BridgeTokenHourlyLimitUpdated(bridgeToken, hourlyLimit);\n }\n\n /// @notice Updates the `fee` value for `bridgeToken`\n function setSwapFee(address bridgeToken, uint64 fee) external onlyGovernorOrGuardian {\n if (!bridges[bridgeToken].allowed) revert InvalidToken();\n if (fee > BASE_PARAMS) revert TooHighParameterValue();\n bridges[bridgeToken].fee = fee;\n emit BridgeTokenFeeUpdated(bridgeToken, fee);\n }\n\n /// @notice Pauses or unpauses swapping in and out for a token\n function toggleBridge(address bridgeToken) external onlyGovernorOrGuardian {\n if (!bridges[bridgeToken].allowed) revert InvalidToken();\n bool pausedStatus = bridges[bridgeToken].paused;\n bridges[bridgeToken].paused = !pausedStatus;\n emit BridgeTokenToggled(bridgeToken, !pausedStatus);\n }\n\n /// @notice Toggles fees for the address `theAddress`\n function toggleFeesForAddress(address theAddress) external onlyGovernorOrGuardian {\n uint256 feeExemptStatus = 1 - isFeeExempt[theAddress];\n isFeeExempt[theAddress] = feeExemptStatus;\n emit FeeToggled(theAddress, feeExemptStatus);\n }\n}\n" + }, + "contracts/mock/MockStableMaster.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\nimport \"../interfaces/IAgToken.sol\";\nimport \"./MockToken.sol\";\nimport \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\nimport \"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\";\nimport { SLPData, MintBurnData } from \"../interfaces/coreModule/IStableMaster.sol\";\n\n// All the details about a collateral that are going to be stored in `StableMaster`\nstruct Collateral {\n // Interface for the token accepted by the underlying `PoolManager` contract\n IERC20 token;\n // Reference to the `SanToken` for the pool\n MockToken sanToken;\n // Reference to the `PerpetualManager` for the pool\n address perpetualManager;\n // Adress of the oracle for the change rate between\n // collateral and the corresponding stablecoin\n address oracle;\n // Amount of collateral in the reserves that comes from users\n // converted in stablecoin value. Updated at minting and burning.\n // A `stocksUsers` of 10 for a collateral type means that overall the balance of the collateral from users\n // that minted/burnt stablecoins using this collateral is worth 10 of stablecoins\n uint256 stocksUsers;\n // Exchange rate between sanToken and collateral\n uint256 sanRate;\n // Base used in the collateral implementation (ERC20 decimal)\n uint256 collatBase;\n // Parameters for SLPs and update of the `sanRate`\n SLPData slpData;\n // All the fees parameters\n MintBurnData feeData;\n}\n\ncontract MockStableMaster {\n mapping(address => uint256) public poolManagerMap;\n\n constructor() {}\n\n function updateStocksUsers(uint256 amount, address poolManager) external {\n poolManagerMap[poolManager] += amount;\n }\n\n function burnSelf(IAgToken agToken, uint256 amount, address burner) external {\n agToken.burnSelf(amount, burner);\n }\n\n function burnFrom(IAgToken agToken, uint256 amount, address burner, address sender) external {\n agToken.burnFrom(amount, burner, sender);\n }\n\n function mint(IAgToken agToken, address account, uint256 amount) external {\n agToken.mint(account, amount);\n }\n}\n\ncontract MockStableMasterSanWrapper is MockStableMaster {\n using SafeERC20 for IERC20;\n\n /// @notice Maps a `PoolManager` contract handling a collateral for this stablecoin to the properties of the struct above\n mapping(address => Collateral) public collateralMap;\n\n constructor() MockStableMaster() {}\n\n uint256 internal constant _BASE_TOKENS = 10 ** 18;\n uint256 internal constant _BASE_PARAMS = 10 ** 9;\n IERC20 public token;\n\n function deposit(uint256 assets, address receiver, address poolManager) external {\n token.safeTransferFrom(msg.sender, address(this), assets);\n Collateral storage col = collateralMap[poolManager];\n _updateSanRate(col);\n uint256 amount = (assets * _BASE_TOKENS) / col.sanRate;\n col.sanToken.mint(receiver, amount);\n }\n\n function withdraw(uint256 assets, address sender, address receiver, address poolManager) external {\n Collateral storage col = collateralMap[poolManager];\n _updateSanRate(col);\n col.sanToken.burn(sender, assets);\n // Computing the amount of collateral to give back to the SLP depending on slippage and on the `sanRate`\n uint256 redeemInC = (assets * (_BASE_PARAMS - col.slpData.slippage) * col.sanRate) /\n (_BASE_TOKENS * _BASE_PARAMS);\n token.safeTransfer(receiver, redeemInC);\n }\n\n function setPoolManagerToken(address, address token_) external {\n token = MockToken(token_);\n }\n\n function setPoolManagerSanToken(address poolManager, address sanToken_) external {\n Collateral storage col = collateralMap[poolManager];\n col.sanToken = MockToken(sanToken_);\n }\n\n function setSanRate(address poolManager, uint256 sanRate_) external {\n Collateral storage col = collateralMap[poolManager];\n col.sanRate = sanRate_;\n }\n\n function _updateSanRate(Collateral storage col) internal {\n uint256 _lockedInterests = col.slpData.lockedInterests;\n // Checking if the `sanRate` has been updated in the current block using past block fees\n // This is a way to prevent flash loans attacks when an important amount of fees are going to be distributed\n // in a block: fees are stored but will just be distributed to SLPs who will be here during next blocks\n if (block.timestamp != col.slpData.lastBlockUpdated && _lockedInterests > 0) {\n uint256 sanMint = col.sanToken.totalSupply();\n if (sanMint != 0) {\n // Checking if the update is too important and should be made in multiple blocks\n if (_lockedInterests > col.slpData.maxInterestsDistributed) {\n // `sanRate` is expressed in `BASE_TOKENS`\n col.sanRate += (col.slpData.maxInterestsDistributed * 10 ** 18) / sanMint;\n _lockedInterests -= col.slpData.maxInterestsDistributed;\n } else {\n col.sanRate += (_lockedInterests * 10 ** 18) / sanMint;\n _lockedInterests = 0;\n }\n } else {\n _lockedInterests = 0;\n }\n }\n col.slpData.lockedInterests = _lockedInterests;\n col.slpData.lastBlockUpdated = block.timestamp;\n }\n\n // copy paste from the deployed contract\n function estimateSanRate(address poolManager) external view returns (uint256 sanRate, uint64 slippage) {\n Collateral memory col = collateralMap[poolManager];\n uint256 _lockedInterests = col.slpData.lockedInterests;\n // Checking if the `sanRate` has been updated in the current block using past block fees\n // This is a way to prevent flash loans attacks when an important amount of fees are going to be distributed\n // in a block: fees are stored but will just be distributed to SLPs who will be here during next blocks\n if (block.timestamp != col.slpData.lastBlockUpdated && _lockedInterests > 0) {\n uint256 sanMint = col.sanToken.totalSupply();\n if (sanMint != 0) {\n // Checking if the update is too important and should be made in multiple blocks\n if (_lockedInterests > col.slpData.maxInterestsDistributed) {\n // `sanRate` is expressed in `BASE_TOKENS`\n col.sanRate += (col.slpData.maxInterestsDistributed * 10 ** 18) / sanMint;\n _lockedInterests -= col.slpData.maxInterestsDistributed;\n } else {\n col.sanRate += (_lockedInterests * 10 ** 18) / sanMint;\n _lockedInterests = 0;\n }\n } else {\n _lockedInterests = 0;\n }\n }\n return (col.sanRate, col.slpData.slippage);\n }\n\n function setSLPData(\n address poolManager,\n uint256 lockedInterests,\n uint256 maxInterestsDistributed,\n uint64 slippage\n ) external {\n Collateral storage col = collateralMap[poolManager];\n col.slpData.lockedInterests = lockedInterests;\n col.slpData.maxInterestsDistributed = maxInterestsDistributed;\n col.slpData.slippage = slippage;\n }\n}\n" + }, + "contracts/mock/MockSwapper.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\nimport \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\nimport \"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\";\n\nimport \"../interfaces/ISwapper.sol\";\n\ncontract MockSwapper is ISwapper {\n bytes32 public constant CALLBACK_SUCCESS = keccak256(\"ERC3156FlashBorrower.onFlashLoan\");\n\n uint256 public counter;\n\n constructor() {}\n\n function swap(IERC20, IERC20, address, uint256, uint256, bytes calldata data) external {\n counter += 1;\n data;\n }\n}\n\ncontract MockSwapperWithSwap is ISwapper {\n using SafeERC20 for IERC20;\n bytes32 public constant CALLBACK_SUCCESS = keccak256(\"ERC3156FlashBorrower.onFlashLoan\");\n\n uint256 public counter;\n\n constructor() {}\n\n function swap(\n IERC20,\n IERC20 outToken,\n address outTokenRecipient,\n uint256 outTokenOwed,\n uint256,\n bytes calldata data\n ) external {\n counter += 1;\n outToken.safeTransfer(outTokenRecipient, outTokenOwed);\n\n data;\n }\n}\n" + }, + "contracts/mock/MockSwapperSidechain.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\nimport \"../swapper/Swapper.sol\";\n\n/// @title MockSwapperSidechain\n/// @author Angle Labs, Inc.\ncontract MockSwapperSidechain is Swapper {\n error NotImplemented();\n\n /// @notice Constructor of the contract\n /// @param _core Core address\n /// @param _uniV3Router UniswapV3 Router address\n /// @param _oneInch 1Inch Router address\n /// @param _angleRouter AngleRouter contract address\n constructor(\n ICoreBorrow _core,\n IUniswapV3Router _uniV3Router,\n address _oneInch,\n IAngleRouterSidechain _angleRouter\n ) Swapper(_core, _uniV3Router, _oneInch, _angleRouter) {}\n\n function _swapLeverage(bytes memory) internal pure override returns (uint256) {\n revert NotImplemented();\n }\n}\n" + }, + "contracts/mock/MockToken.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.7;\n\nimport \"@openzeppelin/contracts/token/ERC20/ERC20.sol\";\n\ncontract MockToken is ERC20 {\n event Minting(address indexed _to, address indexed _minter, uint256 _amount);\n\n event Burning(address indexed _from, address indexed _burner, uint256 _amount);\n\n uint8 internal _decimal;\n mapping(address => bool) public minters;\n address public treasury;\n\n constructor(string memory name_, string memory symbol_, uint8 decimal_) ERC20(name_, symbol_) {\n _decimal = decimal_;\n }\n\n function decimals() public view override returns (uint8) {\n return _decimal;\n }\n\n function mint(address account, uint256 amount) external {\n _mint(account, amount);\n emit Minting(account, msg.sender, amount);\n }\n\n function burn(address account, uint256 amount) public {\n _burn(account, amount);\n emit Burning(account, msg.sender, amount);\n }\n\n function setAllowance(address from, address to) public {\n _approve(from, to, type(uint256).max);\n }\n\n function burnSelf(uint256 amount, address account) public {\n _burn(account, amount);\n emit Burning(account, msg.sender, amount);\n }\n\n function addMinter(address minter) public {\n minters[minter] = true;\n }\n\n function removeMinter(address minter) public {\n minters[minter] = false;\n }\n\n function setTreasury(address _treasury) public {\n treasury = _treasury;\n }\n}\n" + }, + "contracts/mock/MockTokenPermit.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.7;\n\nimport \"@openzeppelin/contracts/token/ERC20/extensions/draft-ERC20Permit.sol\";\nimport \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\nimport \"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\";\n\ncontract MockTokenPermit is ERC20Permit {\n using SafeERC20 for IERC20;\n event Minting(address indexed _to, address indexed _minter, uint256 _amount);\n\n event Burning(address indexed _from, address indexed _burner, uint256 _amount);\n\n uint8 internal _decimal;\n mapping(address => bool) public minters;\n address public treasury;\n uint256 public fees;\n\n bool public reverts;\n\n constructor(string memory name_, string memory symbol_, uint8 decimal_) ERC20Permit(name_) ERC20(name_, symbol_) {\n _decimal = decimal_;\n }\n\n function decimals() public view override returns (uint8) {\n return _decimal;\n }\n\n function mint(address account, uint256 amount) external {\n _mint(account, amount);\n emit Minting(account, msg.sender, amount);\n }\n\n function burn(address account, uint256 amount) public {\n _burn(account, amount);\n emit Burning(account, msg.sender, amount);\n }\n\n function setAllowance(address from, address to) public {\n _approve(from, to, type(uint256).max);\n }\n\n function burnSelf(uint256 amount, address account) public {\n _burn(account, amount);\n emit Burning(account, msg.sender, amount);\n }\n\n function addMinter(address minter) public {\n minters[minter] = true;\n }\n\n function removeMinter(address minter) public {\n minters[minter] = false;\n }\n\n function setTreasury(address _treasury) public {\n treasury = _treasury;\n }\n\n function setFees(uint256 _fees) public {\n fees = _fees;\n }\n\n function recoverERC20(IERC20 token, address to, uint256 amount) external {\n token.safeTransfer(to, amount);\n }\n\n function swapIn(address bridgeToken, uint256 amount, address to) external returns (uint256) {\n require(!reverts);\n\n IERC20(bridgeToken).safeTransferFrom(msg.sender, address(this), amount);\n uint256 canonicalOut = amount;\n canonicalOut -= (canonicalOut * fees) / 10 ** 9;\n _mint(to, canonicalOut);\n return canonicalOut;\n }\n\n function swapOut(address bridgeToken, uint256 amount, address to) external returns (uint256) {\n require(!reverts);\n _burn(msg.sender, amount);\n uint256 bridgeOut = amount;\n bridgeOut -= (bridgeOut * fees) / 10 ** 9;\n IERC20(bridgeToken).safeTransfer(to, bridgeOut);\n return bridgeOut;\n }\n}\n" + }, + "contracts/mock/MockTreasury.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\nimport \"../interfaces/ITreasury.sol\";\nimport \"../interfaces/IFlashAngle.sol\";\nimport \"../interfaces/IVaultManager.sol\";\n\ncontract MockTreasury is ITreasury {\n IAgToken public override stablecoin;\n address public governor;\n address public guardian;\n address public vaultManager1;\n address public vaultManager2;\n address public flashLoanModule;\n address[] public vaultManagerList;\n\n constructor(\n IAgToken _stablecoin,\n address _governor,\n address _guardian,\n address _vaultManager1,\n address _vaultManager2,\n address _flashLoanModule\n ) {\n stablecoin = _stablecoin;\n governor = _governor;\n guardian = _guardian;\n vaultManager1 = _vaultManager1;\n vaultManager2 = _vaultManager2;\n flashLoanModule = _flashLoanModule;\n }\n\n function isGovernor(address admin) external view override returns (bool) {\n return (admin == governor);\n }\n\n function isGovernorOrGuardian(address admin) external view override returns (bool) {\n return (admin == governor || admin == guardian);\n }\n\n function isVaultManager(address _vaultManager) external view override returns (bool) {\n return (_vaultManager == vaultManager1 || _vaultManager == vaultManager2);\n }\n\n function setStablecoin(IAgToken _stablecoin) external {\n stablecoin = _stablecoin;\n }\n\n function setFlashLoanModule(address _flashLoanModule) external override {\n flashLoanModule = _flashLoanModule;\n }\n\n function setGovernor(address _governor) external {\n governor = _governor;\n }\n\n function setVaultManager(address _vaultManager) external {\n vaultManager1 = _vaultManager;\n }\n\n function setVaultManager2(address _vaultManager) external {\n vaultManager2 = _vaultManager;\n }\n\n function setTreasury(address _agTokenOrVaultManager, address _treasury) external {\n IAgToken(_agTokenOrVaultManager).setTreasury(_treasury);\n }\n\n function addMinter(IAgToken _agToken, address _minter) external {\n _agToken.addMinter(_minter);\n }\n\n function removeMinter(IAgToken _agToken, address _minter) external {\n _agToken.removeMinter(_minter);\n }\n\n function accrueInterestToTreasury(IFlashAngle flashAngle) external returns (uint256 balance) {\n balance = flashAngle.accrueInterestToTreasury(stablecoin);\n }\n\n function accrueInterestToTreasuryVaultManager(IVaultManager _vaultManager) external returns (uint256, uint256) {\n return _vaultManager.accrueInterestToTreasury();\n }\n}\n" + }, + "contracts/mock/MockUniswapV3Pool.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.7;\n\ncontract MockUniswapV3Pool {\n address public token0;\n address public token1;\n uint32 public constant EPOCH_DURATION = 24 * 3600 * 7;\n\n function setToken(address token, uint256 who) external {\n if (who == 0) token0 = token;\n else token1 = token;\n }\n\n function round(uint256 amount) external pure returns (uint256) {\n return (amount / EPOCH_DURATION) * EPOCH_DURATION;\n }\n}\n" + }, + "contracts/mock/MockVaultManager.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\nimport \"../interfaces/IVaultManager.sol\";\nimport \"../interfaces/ITreasury.sol\";\nimport \"@openzeppelin/contracts/token/ERC20/ERC20.sol\";\n\ncontract MockVaultManager {\n ITreasury public treasury;\n mapping(uint256 => Vault) public vaultData;\n mapping(uint256 => address) public ownerOf;\n uint256 public surplus;\n uint256 public badDebt;\n IAgToken public token;\n address public oracle = address(this);\n\n address public governor;\n address public collateral;\n address public stablecoin;\n uint256 public oracleValue;\n uint256 public interestAccumulator;\n uint256 public collateralFactor;\n uint256 public totalNormalizedDebt;\n\n constructor(address _treasury) {\n treasury = ITreasury(_treasury);\n }\n\n function accrueInterestToTreasury() external returns (uint256, uint256) {\n // Avoid the function to be view\n if (surplus >= badDebt) {\n token.mint(msg.sender, surplus - badDebt);\n }\n return (surplus, badDebt);\n }\n\n function read() external view returns (uint256) {\n return oracleValue;\n }\n\n function setParams(\n address _governor,\n address _collateral,\n address _stablecoin,\n uint256 _oracleValue,\n uint256 _interestAccumulator,\n uint256 _collateralFactor,\n uint256 _totalNormalizedDebt\n ) external {\n governor = _governor;\n collateral = _collateral;\n stablecoin = _stablecoin;\n interestAccumulator = _interestAccumulator;\n collateralFactor = _collateralFactor;\n totalNormalizedDebt = _totalNormalizedDebt;\n oracleValue = _oracleValue;\n }\n\n function setOwner(uint256 vaultID, address owner) external virtual {\n ownerOf[vaultID] = owner;\n }\n\n function setVaultData(uint256 normalizedDebt, uint256 collateralAmount, uint256 vaultID) external {\n vaultData[vaultID].normalizedDebt = normalizedDebt;\n vaultData[vaultID].collateralAmount = collateralAmount;\n }\n\n function isGovernor(address admin) external view returns (bool) {\n return admin == governor;\n }\n\n function setSurplusBadDebt(uint256 _surplus, uint256 _badDebt, IAgToken _token) external {\n surplus = _surplus;\n badDebt = _badDebt;\n token = _token;\n }\n\n function getDebtOut(uint256 vaultID, uint256 amountStablecoins, uint256 senderBorrowFee) external {}\n\n function setTreasury(address _treasury) external {\n treasury = ITreasury(_treasury);\n }\n\n function getVaultDebt(uint256 vaultID) external view returns (uint256) {\n vaultID;\n token;\n return 0;\n }\n\n function createVault(address toVault) external view returns (uint256) {\n toVault;\n token;\n return 0;\n }\n}\n\ncontract MockVaultManagerListing is MockVaultManager {\n // @notice Mapping from owner address to all his vaults\n mapping(address => uint256[]) internal _ownerListVaults;\n\n constructor(address _treasury) MockVaultManager(_treasury) {}\n\n function getUserVaults(address owner) public view returns (uint256[] memory) {\n return _ownerListVaults[owner];\n }\n\n function getUserCollateral(address owner) public view returns (uint256 totalCollateral) {\n uint256[] memory vaultList = _ownerListVaults[owner];\n uint256 vaultListLength = vaultList.length;\n for (uint256 k; k < vaultListLength; ++k) {\n totalCollateral += vaultData[vaultList[k]].collateralAmount;\n }\n return totalCollateral;\n }\n\n function setOwner(uint256 vaultID, address owner) external override {\n if (ownerOf[vaultID] != address(0)) _removeVaultFromList(ownerOf[vaultID], vaultID);\n _ownerListVaults[owner].push(vaultID);\n ownerOf[vaultID] = owner;\n }\n\n /// @notice Remove `vaultID` from `user` stroed vault list\n /// @param user Address to look out for the vault list\n /// @param vaultID VaultId to remove from the list\n /// @dev The vault is necessarily in the list\n function _removeVaultFromList(address user, uint256 vaultID) internal {\n uint256[] storage vaultList = _ownerListVaults[user];\n uint256 vaultListLength = vaultList.length;\n for (uint256 i; i < vaultListLength - 1; ++i) {\n if (vaultList[i] == vaultID) {\n vaultList[i] = vaultList[vaultListLength - 1];\n break;\n }\n }\n vaultList.pop();\n }\n}\n" + }, + "contracts/mock/MockVeBoostProxy.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\nimport \"../interfaces/governance/IVeBoostProxy.sol\";\n\ncontract MockVeBoostProxy is IVeBoostProxy {\n //solhint-disable-next-line\n mapping(address => uint256) public adjusted_balance_of;\n\n constructor() {}\n\n function setBalance(address concerned, uint256 balance) external {\n adjusted_balance_of[concerned] = balance;\n }\n}\n" + }, + "contracts/oracle/BaseOracleChainlinkMulti.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\n/*\n * █ \n ***** ▓▓▓ \n * ▓▓▓▓▓▓▓ \n * ///. ▓▓▓▓▓▓▓▓▓▓▓▓▓ \n ***** //////// ▓▓▓▓▓▓▓ \n * ///////////// ▓▓▓ \n ▓▓ ////////////////// █ ▓▓ \n ▓▓ ▓▓ /////////////////////// ▓▓ ▓▓ \n ▓▓ ▓▓ //////////////////////////// ▓▓ ▓▓ \n ▓▓ ▓▓ /////////▓▓▓///////▓▓▓///////// ▓▓ ▓▓ \n ▓▓ ,////////////////////////////////////// ▓▓ ▓▓ \n ▓▓ ////////////////////////////////////////// ▓▓ \n ▓▓ //////////////////////▓▓▓▓///////////////////// \n ,//////////////////////////////////////////////////// \n .////////////////////////////////////////////////////////// \n .//////////////////////////██.,//////////////////////////█ \n .//////////////////////████..,./////////////////////██ \n ...////////////////███████.....,.////////////////███ \n ,.,////////////████████ ........,///////////████ \n .,.,//////█████████ ,.......///////████ \n ,..//████████ ........./████ \n ..,██████ .....,███ \n .██ ,.,█ \n \n \n \n ▓▓ ▓▓▓▓▓▓▓▓▓▓ ▓▓▓▓▓▓▓▓▓▓ ▓▓ ▓▓▓▓▓▓▓▓▓▓ \n ▓▓▓▓▓▓ ▓▓▓ ▓▓▓ ▓▓▓ ▓▓ ▓▓ ▓▓▓▓ \n ▓▓▓ ▓▓▓ ▓▓▓ ▓▓▓ ▓▓▓ ▓▓▓ ▓▓ ▓▓▓▓▓ \n ▓▓▓ ▓▓ ▓▓▓ ▓▓▓ ▓▓▓▓▓▓▓▓▓▓ ▓▓▓▓▓▓▓▓▓▓ ▓▓▓▓▓▓▓▓▓▓ \n*/\n\npragma solidity ^0.8.12;\n\nimport \"@chainlink/contracts/src/v0.8/interfaces/AggregatorV3Interface.sol\";\n\nimport \"../interfaces/IOracle.sol\";\nimport \"../interfaces/ITreasury.sol\";\n\n/// @title BaseOracleChainlinkMulti\n/// @author Angle Labs, Inc.\n/// @notice Base Contract to be overriden by all contracts of the protocol\n/// @dev This base contract concerns an oracle that uses Chainlink with multiple pools to read from\n/// @dev All gas-efficient implementation of the `OracleChainlinkMulti` contract should inherit from this\nabstract contract BaseOracleChainlinkMulti is IOracle {\n // ========================= Parameters and References =========================\n\n /// @inheritdoc IOracle\n ITreasury public override treasury;\n /// @notice Represent the maximum amount of time (in seconds) between each Chainlink update\n /// before the price feed is considered stale\n uint32 public stalePeriod;\n\n // =================================== Event ===================================\n\n event StalePeriodUpdated(uint32 _stalePeriod);\n\n // =================================== Errors ===================================\n\n error InvalidChainlinkRate();\n error NotGovernorOrGuardian();\n error NotVaultManagerOrGovernor();\n\n /// @notice Constructor for an oracle using Chainlink with multiple pools to read from\n /// @param _stalePeriod Minimum feed update frequency for the oracle to not revert\n /// @param _treasury Treasury associated to the VaultManager which reads from this feed\n constructor(uint32 _stalePeriod, address _treasury) {\n stalePeriod = _stalePeriod;\n treasury = ITreasury(_treasury);\n }\n\n // ============================= Reading Oracles ===============================\n\n /// @inheritdoc IOracle\n function read() external view virtual override returns (uint256 quoteAmount);\n\n /// @inheritdoc IOracle\n function circuitChainlink() public view virtual returns (AggregatorV3Interface[] memory);\n\n /// @notice Reads a Chainlink feed using a quote amount and converts the quote amount to\n /// the out-currency\n /// @param quoteAmount The amount for which to compute the price expressed with base decimal\n /// @param feed Chainlink feed to query\n /// @param multiplied Whether the ratio outputted by Chainlink should be multiplied or divided\n /// to the `quoteAmount`\n /// @param decimals Number of decimals of the corresponding Chainlink pair\n /// @return The `quoteAmount` converted in out-currency\n function _readChainlinkFeed(\n uint256 quoteAmount,\n AggregatorV3Interface feed,\n uint8 multiplied,\n uint256 decimals\n ) internal view returns (uint256) {\n (uint80 roundId, int256 ratio, , uint256 updatedAt, uint80 answeredInRound) = feed.latestRoundData();\n if (ratio <= 0 || roundId > answeredInRound || block.timestamp - updatedAt > stalePeriod)\n revert InvalidChainlinkRate();\n uint256 castedRatio = uint256(ratio);\n // Checking whether we should multiply or divide by the ratio computed\n if (multiplied == 1) return (quoteAmount * castedRatio) / (10 ** decimals);\n else return (quoteAmount * (10 ** decimals)) / castedRatio;\n }\n\n // ======================= Governance Related Functions ========================\n\n /// @notice Changes the stale period\n /// @param _stalePeriod New stale period (in seconds)\n function changeStalePeriod(uint32 _stalePeriod) external {\n if (!treasury.isGovernorOrGuardian(msg.sender)) revert NotGovernorOrGuardian();\n stalePeriod = _stalePeriod;\n emit StalePeriodUpdated(_stalePeriod);\n }\n\n /// @inheritdoc IOracle\n function setTreasury(address _treasury) external override {\n if (!treasury.isVaultManager(msg.sender) && !treasury.isGovernor(msg.sender))\n revert NotVaultManagerOrGovernor();\n treasury = ITreasury(_treasury);\n }\n}\n" + }, + "contracts/oracle/BaseOracleChainlinkMultiTwoFeeds.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\nimport \"@chainlink/contracts/src/v0.8/interfaces/AggregatorV3Interface.sol\";\n\nimport \"./BaseOracleChainlinkMulti.sol\";\n\n/// @title BaseOracleChainlinkMultiTwoFeeds\n/// @author Angle Labs, Inc.\n/// @notice Base contract for an oracle that reads into two Chainlink feeds (including an EUR/USD feed) which both have\n/// 8 decimals\nabstract contract BaseOracleChainlinkMultiTwoFeeds is BaseOracleChainlinkMulti {\n constructor(uint32 _stalePeriod, address _treasury) BaseOracleChainlinkMulti(_stalePeriod, _treasury) {}\n\n /// @notice Returns the quote amount of the oracle contract\n function _getQuoteAmount() internal view virtual returns (uint256) {\n return 10 ** 18;\n }\n\n /// @inheritdoc IOracle\n function read() external view virtual override returns (uint256 quoteAmount) {\n quoteAmount = _getQuoteAmount();\n AggregatorV3Interface[] memory _circuitChainlink = circuitChainlink();\n uint8[2] memory circuitChainIsMultiplied = [1, 0];\n uint8[2] memory chainlinkDecimals = [8, 8];\n uint256 circuitLength = _circuitChainlink.length;\n for (uint256 i; i < circuitLength; ++i) {\n quoteAmount = _readChainlinkFeed(\n quoteAmount,\n _circuitChainlink[i],\n circuitChainIsMultiplied[i],\n chainlinkDecimals[i]\n );\n }\n }\n}\n" + }, + "contracts/oracle/BaseOracleChainlinkOneFeed.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\nimport \"@chainlink/contracts/src/v0.8/interfaces/AggregatorV3Interface.sol\";\n\nimport \"./BaseOracleChainlinkMulti.sol\";\n\n/// @title BaseOracleChainlinkOneFeed\n/// @author Angle Labs, Inc.\n/// @notice Base contract for an oracle that reads into one Chainlink feeds with 8 decimals\nabstract contract BaseOracleChainlinkOneFeed is BaseOracleChainlinkMulti {\n constructor(uint32 _stalePeriod, address _treasury) BaseOracleChainlinkMulti(_stalePeriod, _treasury) {}\n\n /// @notice Returns the quote amount of the oracle contract\n function _getQuoteAmount() internal view virtual returns (uint256) {\n return 10 ** 18;\n }\n\n /// @inheritdoc IOracle\n function read() external view virtual override returns (uint256 quoteAmount) {\n AggregatorV3Interface[] memory _circuitChainlink = circuitChainlink();\n quoteAmount = _readChainlinkFeed(_getQuoteAmount(), _circuitChainlink[0], 1, 8);\n }\n}\n" + }, + "contracts/oracle/implementations/arbitrum/EUR/OracleBTCEURChainlinkArbitrum.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\nimport \"@chainlink/contracts/src/v0.8/interfaces/AggregatorV3Interface.sol\";\n\nimport \"../../../BaseOracleChainlinkMultiTwoFeeds.sol\";\n\n/// @title OracleBTCEURChainlinkArbitrum\n/// @author Angle Labs, Inc.\n/// @notice Gives the price of BTC in Euro in base 18\n/// @dev This contract is built to be deployed on Arbitrum\ncontract OracleBTCEURChainlinkArbitrum is BaseOracleChainlinkMultiTwoFeeds {\n string public constant DESCRIPTION = \"BTC/EUR Oracle\";\n\n constructor(uint32 _stalePeriod, address _treasury) BaseOracleChainlinkMultiTwoFeeds(_stalePeriod, _treasury) {}\n\n /// @inheritdoc IOracle\n function circuitChainlink() public pure override returns (AggregatorV3Interface[] memory) {\n AggregatorV3Interface[] memory _circuitChainlink = new AggregatorV3Interface[](2);\n // Oracle BTC/USD\n _circuitChainlink[0] = AggregatorV3Interface(0x6ce185860a4963106506C203335A2910413708e9);\n // Oracle EUR/USD\n _circuitChainlink[1] = AggregatorV3Interface(0xA14d53bC1F1c0F31B4aA3BD109344E5009051a84);\n return _circuitChainlink;\n }\n}\n" + }, + "contracts/oracle/implementations/arbitrum/EUR/OracleETHEURChainlinkArbitrum.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\nimport \"@chainlink/contracts/src/v0.8/interfaces/AggregatorV3Interface.sol\";\n\nimport \"../../../BaseOracleChainlinkMultiTwoFeeds.sol\";\n\n/// @title OracleETHEURChainlinkArbitrum\n/// @author Angle Labs, Inc.\n/// @notice Gives the price of ETH in Euro in base 18\n/// @dev This contract is built to be deployed on Arbitrum\ncontract OracleETHEURChainlinkArbitrum is BaseOracleChainlinkMultiTwoFeeds {\n string public constant DESCRIPTION = \"ETH/EUR Oracle\";\n\n constructor(uint32 _stalePeriod, address _treasury) BaseOracleChainlinkMultiTwoFeeds(_stalePeriod, _treasury) {}\n\n /// @inheritdoc IOracle\n function circuitChainlink() public pure override returns (AggregatorV3Interface[] memory) {\n AggregatorV3Interface[] memory _circuitChainlink = new AggregatorV3Interface[](2);\n // Oracle ETH/USD\n _circuitChainlink[0] = AggregatorV3Interface(0x639Fe6ab55C921f74e7fac1ee960C0B6293ba612);\n // Oracle EUR/USD\n _circuitChainlink[1] = AggregatorV3Interface(0xA14d53bC1F1c0F31B4aA3BD109344E5009051a84);\n return _circuitChainlink;\n }\n}\n" + }, + "contracts/oracle/implementations/arbitrum/EUR/OracleUSDCEURChainlinkArbitrum.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\nimport \"@chainlink/contracts/src/v0.8/interfaces/AggregatorV3Interface.sol\";\n\nimport \"../../../BaseOracleChainlinkMultiTwoFeeds.sol\";\n\n/// @title OracleUSDCEURChainlinkArbitrum\n/// @author Angle Labs, Inc.\n/// @notice Gives the price of USDC in Euro in base 18\n/// @dev This contract is built to be deployed on Arbitrum\ncontract OracleUSDCEURChainlinkArbitrum is BaseOracleChainlinkMultiTwoFeeds {\n string public constant DESCRIPTION = \"USDC/EUR Oracle\";\n\n constructor(uint32 _stalePeriod, address _treasury) BaseOracleChainlinkMultiTwoFeeds(_stalePeriod, _treasury) {}\n\n /// @inheritdoc IOracle\n function circuitChainlink() public pure override returns (AggregatorV3Interface[] memory) {\n AggregatorV3Interface[] memory _circuitChainlink = new AggregatorV3Interface[](2);\n // Oracle ETH/USD\n _circuitChainlink[0] = AggregatorV3Interface(0x50834F3163758fcC1Df9973b6e91f0F0F0434aD3);\n // Oracle EUR/USD\n _circuitChainlink[1] = AggregatorV3Interface(0xA14d53bC1F1c0F31B4aA3BD109344E5009051a84);\n return _circuitChainlink;\n }\n}\n" + }, + "contracts/oracle/implementations/avalanche/EUR/OracleAVAXEURChainlinkAvalanche.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\nimport \"@chainlink/contracts/src/v0.8/interfaces/AggregatorV3Interface.sol\";\n\nimport \"../../../BaseOracleChainlinkMultiTwoFeeds.sol\";\n\n/// @title OracleAVAXEURChainlinkAvalanche\n/// @author Angle Labs, Inc.\n/// @notice Gives the price of AVAX in Euro in base 18\n/// @dev This contract is built to be deployed on Avalanche\ncontract OracleAVAXEURChainlinkAvalanche is BaseOracleChainlinkMultiTwoFeeds {\n string public constant DESCRIPTION = \"AVAX/EUR Oracle\";\n\n constructor(uint32 _stalePeriod, address _treasury) BaseOracleChainlinkMultiTwoFeeds(_stalePeriod, _treasury) {}\n\n /// @inheritdoc IOracle\n function circuitChainlink() public pure override returns (AggregatorV3Interface[] memory) {\n AggregatorV3Interface[] memory _circuitChainlink = new AggregatorV3Interface[](2);\n // Oracle AVAX/USD\n _circuitChainlink[0] = AggregatorV3Interface(0x0A77230d17318075983913bC2145DB16C7366156);\n // Oracle EUR/USD\n _circuitChainlink[1] = AggregatorV3Interface(0x192f2DBA961Bb0277520C082d6bfa87D5961333E);\n return _circuitChainlink;\n }\n}\n" + }, + "contracts/oracle/implementations/avalanche/EUR/OracleUSDCEURChainlinkAvalanche.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\nimport \"@chainlink/contracts/src/v0.8/interfaces/AggregatorV3Interface.sol\";\n\nimport \"../../../BaseOracleChainlinkMultiTwoFeeds.sol\";\n\n/// @title OracleUSDCEURChainlinkAvalanche\n/// @author Angle Labs, Inc.\n/// @notice Gives the price of USDC in Euro in base 18\n/// @dev This contract is built to be deployed on Avalanche\ncontract OracleUSDCEURChainlinkAvalanche is BaseOracleChainlinkMultiTwoFeeds {\n string public constant DESCRIPTION = \"USDC/EUR Oracle\";\n\n constructor(uint32 _stalePeriod, address _treasury) BaseOracleChainlinkMultiTwoFeeds(_stalePeriod, _treasury) {}\n\n /// @inheritdoc IOracle\n function circuitChainlink() public pure override returns (AggregatorV3Interface[] memory) {\n AggregatorV3Interface[] memory _circuitChainlink = new AggregatorV3Interface[](2);\n // Oracle USDC/USD\n _circuitChainlink[0] = AggregatorV3Interface(0xF096872672F44d6EBA71458D74fe67F9a77a23B9);\n // Oracle EUR/USD\n _circuitChainlink[1] = AggregatorV3Interface(0x192f2DBA961Bb0277520C082d6bfa87D5961333E);\n return _circuitChainlink;\n }\n}\n" + }, + "contracts/oracle/implementations/mainnet/EUR/OracleBTCEURChainlink.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\nimport \"@chainlink/contracts/src/v0.8/interfaces/AggregatorV3Interface.sol\";\n\nimport \"../../../BaseOracleChainlinkMultiTwoFeeds.sol\";\n\n/// @title OracleBTCEURChainlink\n/// @author Angle Labs, Inc.\n/// @notice Gives the price of BTC in Euro in base 18\ncontract OracleBTCEURChainlink is BaseOracleChainlinkMultiTwoFeeds {\n string public constant DESCRIPTION = \"BTC/EUR Oracle\";\n\n constructor(uint32 _stalePeriod, address _treasury) BaseOracleChainlinkMultiTwoFeeds(_stalePeriod, _treasury) {}\n\n /// @inheritdoc IOracle\n function circuitChainlink() public pure override returns (AggregatorV3Interface[] memory) {\n AggregatorV3Interface[] memory _circuitChainlink = new AggregatorV3Interface[](2);\n // Oracle BTC/USD\n _circuitChainlink[0] = AggregatorV3Interface(0xF4030086522a5bEEa4988F8cA5B36dbC97BeE88c);\n // Oracle EUR/USD\n _circuitChainlink[1] = AggregatorV3Interface(0xb49f677943BC038e9857d61E7d053CaA2C1734C1);\n return _circuitChainlink;\n }\n}\n" + }, + "contracts/oracle/implementations/mainnet/EUR/OracleCBETHEURChainlink.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\nimport \"@chainlink/contracts/src/v0.8/interfaces/AggregatorV3Interface.sol\";\n\nimport \"../../../BaseOracleChainlinkMultiTwoFeeds.sol\";\n\n/// @title OracleCBETHEURChainlink\n/// @author Angle Labs, Inc.\n/// @notice Gives the price of cbETH in Euro in base 18\ncontract OracleCBETHEURChainlink is BaseOracleChainlinkMultiTwoFeeds {\n string public constant DESCRIPTION = \"cbETH/EUR Oracle\";\n\n constructor(uint32 _stalePeriod, address _treasury) BaseOracleChainlinkMultiTwoFeeds(_stalePeriod, _treasury) {}\n\n /// @inheritdoc IOracle\n function circuitChainlink() public pure override returns (AggregatorV3Interface[] memory) {\n AggregatorV3Interface[] memory _circuitChainlink = new AggregatorV3Interface[](3);\n // Oracle cbETH/ETH\n _circuitChainlink[0] = AggregatorV3Interface(0xF017fcB346A1885194689bA23Eff2fE6fA5C483b);\n // Oracle ETH/USD\n _circuitChainlink[1] = AggregatorV3Interface(0x5f4eC3Df9cbd43714FE2740f5E3616155c5b8419);\n // Oracle EUR/USD\n _circuitChainlink[2] = AggregatorV3Interface(0xb49f677943BC038e9857d61E7d053CaA2C1734C1);\n return _circuitChainlink;\n }\n\n /// @inheritdoc BaseOracleChainlinkMultiTwoFeeds\n function read() external view virtual override returns (uint256 quoteAmount) {\n quoteAmount = _getQuoteAmount();\n AggregatorV3Interface[] memory _circuitChainlink = circuitChainlink();\n uint8[3] memory circuitChainIsMultiplied = [1, 1, 0];\n uint8[3] memory chainlinkDecimals = [18, 8, 8];\n uint256 circuitLength = _circuitChainlink.length;\n for (uint256 i; i < circuitLength; ++i) {\n quoteAmount = _readChainlinkFeed(\n quoteAmount,\n _circuitChainlink[i],\n circuitChainIsMultiplied[i],\n chainlinkDecimals[i]\n );\n }\n }\n}\n" + }, + "contracts/oracle/implementations/mainnet/EUR/OracleETHEURChainlink.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\nimport \"@chainlink/contracts/src/v0.8/interfaces/AggregatorV3Interface.sol\";\n\nimport \"../../../BaseOracleChainlinkMultiTwoFeeds.sol\";\n\n/// @title OracleETHEURChainlink\n/// @author Angle Labs, Inc.\n/// @notice Gives the price of ETH in Euro in base 18\ncontract OracleETHEURChainlink is BaseOracleChainlinkMultiTwoFeeds {\n string public constant DESCRIPTION = \"ETH/EUR Oracle\";\n\n constructor(uint32 _stalePeriod, address _treasury) BaseOracleChainlinkMultiTwoFeeds(_stalePeriod, _treasury) {}\n\n /// @inheritdoc IOracle\n function circuitChainlink() public pure override returns (AggregatorV3Interface[] memory) {\n AggregatorV3Interface[] memory _circuitChainlink = new AggregatorV3Interface[](2);\n // Oracle ETH/USD\n _circuitChainlink[0] = AggregatorV3Interface(0x5f4eC3Df9cbd43714FE2740f5E3616155c5b8419);\n // Oracle EUR/USD\n _circuitChainlink[1] = AggregatorV3Interface(0xb49f677943BC038e9857d61E7d053CaA2C1734C1);\n return _circuitChainlink;\n }\n}\n" + }, + "contracts/oracle/implementations/mainnet/EUR/OracleHIGHEURChainlink.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\nimport \"@chainlink/contracts/src/v0.8/interfaces/AggregatorV3Interface.sol\";\n\nimport \"../../../BaseOracleChainlinkMultiTwoFeeds.sol\";\n\n/// @title OracleHIGHEURChainlink\n/// @author Angle Labs, Inc.\n/// @notice Gives the price of HIGH in Euro in base 18\ncontract OracleHIGHEURChainlink is BaseOracleChainlinkMultiTwoFeeds {\n string public constant DESCRIPTION = \"HIGH/EUR Oracle\";\n\n constructor(uint32 _stalePeriod, address _treasury) BaseOracleChainlinkMultiTwoFeeds(_stalePeriod, _treasury) {}\n\n /// @inheritdoc IOracle\n function circuitChainlink() public pure override returns (AggregatorV3Interface[] memory) {\n AggregatorV3Interface[] memory _circuitChainlink = new AggregatorV3Interface[](1);\n // Oracle HIGH/EUR\n _circuitChainlink[0] = AggregatorV3Interface(0x9E8E794ad6Ecdb6d5c7eaBE059D30E907F58859b);\n return _circuitChainlink;\n }\n\n /// @inheritdoc BaseOracleChainlinkMultiTwoFeeds\n function read() external view override returns (uint256 quoteAmount) {\n quoteAmount = _readChainlinkFeed(_getQuoteAmount(), circuitChainlink()[0], 1, 8);\n }\n}\n" + }, + "contracts/oracle/implementations/mainnet/EUR/OracleIB01EURChainlink.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\nimport \"@chainlink/contracts/src/v0.8/interfaces/AggregatorV3Interface.sol\";\n\nimport \"../../../BaseOracleChainlinkMultiTwoFeeds.sol\";\n\n/// @title OracleIB01EURChainlink\n/// @author Angle Labs, Inc.\n/// @notice Gives the price of IB01 in Euro in base 18\ncontract OracleIB01EURChainlink is BaseOracleChainlinkMultiTwoFeeds {\n string public constant DESCRIPTION = \"IB01/EUR Oracle\";\n\n constructor(uint32 _stalePeriod, address _treasury) BaseOracleChainlinkMultiTwoFeeds(_stalePeriod, _treasury) {}\n\n /// @inheritdoc IOracle\n function circuitChainlink() public pure override returns (AggregatorV3Interface[] memory) {\n AggregatorV3Interface[] memory _circuitChainlink = new AggregatorV3Interface[](2);\n // Oracle IB01/USD\n _circuitChainlink[0] = AggregatorV3Interface(0x32d1463EB53b73C095625719Afa544D5426354cB);\n // Oracle EUR/USD\n _circuitChainlink[1] = AggregatorV3Interface(0xb49f677943BC038e9857d61E7d053CaA2C1734C1);\n return _circuitChainlink;\n }\n}\n" + }, + "contracts/oracle/implementations/mainnet/EUR/OracleLUSDEURChainlink.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\nimport \"@chainlink/contracts/src/v0.8/interfaces/AggregatorV3Interface.sol\";\n\nimport \"../../../BaseOracleChainlinkMultiTwoFeeds.sol\";\n\n/// @title OracleLUSDEURChainlink\n/// @author Angle Labs, Inc.\n/// @notice Gives the price of LUSD in Euro in base 18\ncontract OracleLUSDEURChainlink is BaseOracleChainlinkMultiTwoFeeds {\n string public constant DESCRIPTION = \"LUSD/EUR Oracle\";\n\n constructor(uint32 _stalePeriod, address _treasury) BaseOracleChainlinkMultiTwoFeeds(_stalePeriod, _treasury) {}\n\n /// @inheritdoc IOracle\n function circuitChainlink() public pure override returns (AggregatorV3Interface[] memory) {\n AggregatorV3Interface[] memory _circuitChainlink = new AggregatorV3Interface[](2);\n // Oracle LUSD/USD\n _circuitChainlink[0] = AggregatorV3Interface(0x3D7aE7E594f2f2091Ad8798313450130d0Aba3a0);\n // Oracle EUR/USD\n _circuitChainlink[1] = AggregatorV3Interface(0xb49f677943BC038e9857d61E7d053CaA2C1734C1);\n return _circuitChainlink;\n }\n}\n" + }, + "contracts/oracle/implementations/mainnet/EUR/OracleUSDCEURChainlink.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\nimport \"@chainlink/contracts/src/v0.8/interfaces/AggregatorV3Interface.sol\";\n\nimport \"../../../BaseOracleChainlinkMultiTwoFeeds.sol\";\n\n/// @title OracleUSDCEURChainlink\n/// @author Angle Labs, Inc.\n/// @notice Gives the price of USDC in Euro in base 18\ncontract OracleUSDCEURChainlink is BaseOracleChainlinkMultiTwoFeeds {\n string public constant DESCRIPTION = \"USDC/EUR Oracle\";\n\n constructor(uint32 _stalePeriod, address _treasury) BaseOracleChainlinkMultiTwoFeeds(_stalePeriod, _treasury) {}\n\n /// @inheritdoc IOracle\n function circuitChainlink() public pure override returns (AggregatorV3Interface[] memory) {\n AggregatorV3Interface[] memory _circuitChainlink = new AggregatorV3Interface[](2);\n // Oracle USDC/USD\n _circuitChainlink[0] = AggregatorV3Interface(0x8fFfFfd4AfB6115b954Bd326cbe7B4BA576818f6);\n // Oracle EUR/USD\n _circuitChainlink[1] = AggregatorV3Interface(0xb49f677943BC038e9857d61E7d053CaA2C1734C1);\n return _circuitChainlink;\n }\n}\n" + }, + "contracts/oracle/implementations/mainnet/EUR/OracleWSTETHEURChainlink.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\nimport \"@chainlink/contracts/src/v0.8/interfaces/AggregatorV3Interface.sol\";\n\nimport \"../../../BaseOracleChainlinkMultiTwoFeeds.sol\";\nimport \"../../../../interfaces/external/lido/IStETH.sol\";\n\n/// @title OracleWSTETHEURChainlink\n/// @author Angle Labs, Inc.\n/// @notice Gives the price of wSTETH in Euro in base 18\ncontract OracleWSTETHEURChainlink is BaseOracleChainlinkMultiTwoFeeds {\n string public constant DESCRIPTION = \"wSTETH/EUR Oracle\";\n IStETH public constant STETH = IStETH(0xae7ab96520DE3A18E5e111B5EaAb095312D7fE84);\n\n constructor(uint32 _stalePeriod, address _treasury) BaseOracleChainlinkMultiTwoFeeds(_stalePeriod, _treasury) {}\n\n /// @inheritdoc IOracle\n function circuitChainlink() public pure override returns (AggregatorV3Interface[] memory) {\n AggregatorV3Interface[] memory _circuitChainlink = new AggregatorV3Interface[](2);\n // Oracle stETH/USD\n _circuitChainlink[0] = AggregatorV3Interface(0xCfE54B5cD566aB89272946F602D76Ea879CAb4a8);\n // Oracle EUR/USD\n _circuitChainlink[1] = AggregatorV3Interface(0xb49f677943BC038e9857d61E7d053CaA2C1734C1);\n return _circuitChainlink;\n }\n\n /// @inheritdoc BaseOracleChainlinkMultiTwoFeeds\n function _getQuoteAmount() internal view override returns (uint256) {\n return STETH.getPooledEthByShares(1 ether);\n }\n}\n" + }, + "contracts/oracle/implementations/mainnet/USD/OracleWSTETHUSDChainlink.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\nimport \"@chainlink/contracts/src/v0.8/interfaces/AggregatorV3Interface.sol\";\n\nimport \"../../../BaseOracleChainlinkOneFeed.sol\";\nimport \"../../../../interfaces/external/lido/IStETH.sol\";\n\n/// @title OracleWSTETHUSDChainlink\n/// @author Angle Labs, Inc.\n/// @notice Gives the price of wSTETH in USD in base 18\ncontract OracleWSTETHUSDChainlink is BaseOracleChainlinkOneFeed {\n string public constant DESCRIPTION = \"wSTETH/USD Oracle\";\n IStETH public constant STETH = IStETH(0xae7ab96520DE3A18E5e111B5EaAb095312D7fE84);\n\n constructor(uint32 _stalePeriod, address _treasury) BaseOracleChainlinkOneFeed(_stalePeriod, _treasury) {}\n\n /// @inheritdoc IOracle\n function circuitChainlink() public pure override returns (AggregatorV3Interface[] memory) {\n AggregatorV3Interface[] memory _circuitChainlink = new AggregatorV3Interface[](1);\n // Oracle stETH/USD\n _circuitChainlink[0] = AggregatorV3Interface(0xCfE54B5cD566aB89272946F602D76Ea879CAb4a8);\n return _circuitChainlink;\n }\n\n /// @inheritdoc BaseOracleChainlinkOneFeed\n function _getQuoteAmount() internal view override returns (uint256) {\n return STETH.getPooledEthByShares(1 ether);\n }\n}\n" + }, + "contracts/oracle/implementations/mainnet/XAU/OracleETHXAUChainlink.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\nimport \"@chainlink/contracts/src/v0.8/interfaces/AggregatorV3Interface.sol\";\n\nimport \"../../../BaseOracleChainlinkMultiTwoFeeds.sol\";\n\n/// @title OracleETHXAUChainlink\n/// @author Angle Labs, Inc.\n/// @notice Gives the price of ETH in XAU in base 18\ncontract OracleETHXAUChainlink is BaseOracleChainlinkMultiTwoFeeds {\n string public constant DESCRIPTION = \"ETH/GOLD Oracle\";\n\n constructor(uint32 _stalePeriod, address _treasury) BaseOracleChainlinkMultiTwoFeeds(_stalePeriod, _treasury) {}\n\n /// @inheritdoc IOracle\n function circuitChainlink() public pure override returns (AggregatorV3Interface[] memory) {\n AggregatorV3Interface[] memory _circuitChainlink = new AggregatorV3Interface[](2);\n // Oracle ETH/USD\n _circuitChainlink[0] = AggregatorV3Interface(0x5f4eC3Df9cbd43714FE2740f5E3616155c5b8419);\n // Oracle XAU/USD\n _circuitChainlink[1] = AggregatorV3Interface(0x214eD9Da11D2fbe465a6fc601a91E62EbEc1a0D6);\n return _circuitChainlink;\n }\n}\n" + }, + "contracts/oracle/implementations/mainnet/XAU/OracleLUSDXAUChainlink.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\nimport \"@chainlink/contracts/src/v0.8/interfaces/AggregatorV3Interface.sol\";\n\nimport \"../../../BaseOracleChainlinkMultiTwoFeeds.sol\";\n\n/// @title OracleLUSDXAUChainlink\n/// @author Angle Labs, Inc.\n/// @notice Gives the price of LUSD in XAU in base 18\ncontract OracleLUSDXAUChainlink is BaseOracleChainlinkMultiTwoFeeds {\n string public constant DESCRIPTION = \"LUSD/GOLD Oracle\";\n\n constructor(uint32 _stalePeriod, address _treasury) BaseOracleChainlinkMultiTwoFeeds(_stalePeriod, _treasury) {}\n\n /// @inheritdoc IOracle\n function circuitChainlink() public pure override returns (AggregatorV3Interface[] memory) {\n AggregatorV3Interface[] memory _circuitChainlink = new AggregatorV3Interface[](2);\n // Oracle LUSD/USD\n _circuitChainlink[0] = AggregatorV3Interface(0x3D7aE7E594f2f2091Ad8798313450130d0Aba3a0);\n // Oracle XAU/USD\n _circuitChainlink[1] = AggregatorV3Interface(0x214eD9Da11D2fbe465a6fc601a91E62EbEc1a0D6);\n return _circuitChainlink;\n }\n}\n" + }, + "contracts/oracle/implementations/mainnet/XAU/OracleUSDCXAUChainlink.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\nimport \"@chainlink/contracts/src/v0.8/interfaces/AggregatorV3Interface.sol\";\n\nimport \"../../../BaseOracleChainlinkMultiTwoFeeds.sol\";\n\n/// @title OracleUSDCXAUChainlink\n/// @author Angle Labs, Inc.\n/// @notice Gives the price of USDC in XAU in base 18\ncontract OracleUSDCXAUChainlink is BaseOracleChainlinkMultiTwoFeeds {\n string public constant DESCRIPTION = \"USDC/GOLD Oracle\";\n\n constructor(uint32 _stalePeriod, address _treasury) BaseOracleChainlinkMultiTwoFeeds(_stalePeriod, _treasury) {}\n\n /// @inheritdoc IOracle\n function circuitChainlink() public pure override returns (AggregatorV3Interface[] memory) {\n AggregatorV3Interface[] memory _circuitChainlink = new AggregatorV3Interface[](2);\n // Oracle USDC/USD\n _circuitChainlink[0] = AggregatorV3Interface(0x8fFfFfd4AfB6115b954Bd326cbe7B4BA576818f6);\n // Oracle XAU/USD\n _circuitChainlink[1] = AggregatorV3Interface(0x214eD9Da11D2fbe465a6fc601a91E62EbEc1a0D6);\n return _circuitChainlink;\n }\n}\n" + }, + "contracts/oracle/implementations/mainnet/XAU/OracleWSTETHXAUChainlink.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\nimport \"@chainlink/contracts/src/v0.8/interfaces/AggregatorV3Interface.sol\";\n\nimport \"../../../BaseOracleChainlinkMultiTwoFeeds.sol\";\nimport \"../../../../interfaces/external/lido/IStETH.sol\";\n\n/// @title OracleWSTETHXAUChainlink\n/// @author Angle Labs, Inc.\n/// @notice Gives the price of wSTETH in XAU in base 18\ncontract OracleWSTETHXAUChainlink is BaseOracleChainlinkMultiTwoFeeds {\n string public constant DESCRIPTION = \"wSTETH/XAU Oracle\";\n IStETH public constant STETH = IStETH(0xae7ab96520DE3A18E5e111B5EaAb095312D7fE84);\n\n constructor(uint32 _stalePeriod, address _treasury) BaseOracleChainlinkMultiTwoFeeds(_stalePeriod, _treasury) {}\n\n /// @inheritdoc IOracle\n function circuitChainlink() public pure override returns (AggregatorV3Interface[] memory) {\n AggregatorV3Interface[] memory _circuitChainlink = new AggregatorV3Interface[](2);\n // Oracle stETH/USD\n _circuitChainlink[0] = AggregatorV3Interface(0xCfE54B5cD566aB89272946F602D76Ea879CAb4a8);\n // Oracle XAU/USD\n _circuitChainlink[1] = AggregatorV3Interface(0x214eD9Da11D2fbe465a6fc601a91E62EbEc1a0D6);\n return _circuitChainlink;\n }\n\n /// @inheritdoc BaseOracleChainlinkMultiTwoFeeds\n function _getQuoteAmount() internal view override returns (uint256) {\n return STETH.getPooledEthByShares(1 ether);\n }\n}\n" + }, + "contracts/oracle/implementations/optimism/EUR/OracleETHEURChainlinkOptimism.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\nimport \"@chainlink/contracts/src/v0.8/interfaces/AggregatorV3Interface.sol\";\n\nimport \"../../../BaseOracleChainlinkMultiTwoFeeds.sol\";\n\n/// @title OracleETHEURChainlinkOptimism\n/// @author Angle Labs, Inc.\n/// @notice Gives the price of ETH in Euro in base 18\n/// @dev This contract is built to be deployed on Optimism\ncontract OracleETHEURChainlinkOptimism is BaseOracleChainlinkMultiTwoFeeds {\n string public constant DESCRIPTION = \"ETH/EUR Oracle\";\n\n constructor(uint32 _stalePeriod, address _treasury) BaseOracleChainlinkMultiTwoFeeds(_stalePeriod, _treasury) {}\n\n /// @inheritdoc IOracle\n function circuitChainlink() public pure override returns (AggregatorV3Interface[] memory) {\n AggregatorV3Interface[] memory _circuitChainlink = new AggregatorV3Interface[](2);\n // Oracle ETH/USD\n _circuitChainlink[0] = AggregatorV3Interface(0x13e3Ee699D1909E989722E753853AE30b17e08c5);\n // Oracle EUR/USD\n _circuitChainlink[1] = AggregatorV3Interface(0x3626369857A10CcC6cc3A6e4f5C2f5984a519F20);\n return _circuitChainlink;\n }\n}\n" + }, + "contracts/oracle/implementations/optimism/EUR/OracleOPEURChainlinkOptimism.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\nimport \"@chainlink/contracts/src/v0.8/interfaces/AggregatorV3Interface.sol\";\n\nimport \"../../../BaseOracleChainlinkMultiTwoFeeds.sol\";\n\n/// @title OracleOPEURChainlinkOptimism\n/// @author Angle Labs, Inc.\n/// @notice Gives the price of OP in Euro in base 18\n/// @dev This contract is built to be deployed on Optimism\ncontract OracleOPEURChainlinkOptimism is BaseOracleChainlinkMultiTwoFeeds {\n string public constant DESCRIPTION = \"OP/EUR Oracle\";\n\n constructor(uint32 _stalePeriod, address _treasury) BaseOracleChainlinkMultiTwoFeeds(_stalePeriod, _treasury) {}\n\n /// @inheritdoc IOracle\n function circuitChainlink() public pure override returns (AggregatorV3Interface[] memory) {\n AggregatorV3Interface[] memory _circuitChainlink = new AggregatorV3Interface[](2);\n // Oracle OP/USD\n _circuitChainlink[0] = AggregatorV3Interface(0x0D276FC14719f9292D5C1eA2198673d1f4269246);\n // Oracle EUR/USD\n _circuitChainlink[1] = AggregatorV3Interface(0x3626369857A10CcC6cc3A6e4f5C2f5984a519F20);\n return _circuitChainlink;\n }\n}\n" + }, + "contracts/oracle/implementations/optimism/EUR/OracleUSDCEURChainlinkOptimism.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\nimport \"@chainlink/contracts/src/v0.8/interfaces/AggregatorV3Interface.sol\";\n\nimport \"../../../BaseOracleChainlinkMultiTwoFeeds.sol\";\n\n/// @title OracleUSDCEURChainlinkOptimism\n/// @author Angle Labs, Inc.\n/// @notice Gives the price of USDC in Euro in base 18\n/// @dev This contract is built to be deployed on Optimism\ncontract OracleUSDCEURChainlinkOptimism is BaseOracleChainlinkMultiTwoFeeds {\n string public constant DESCRIPTION = \"USDC/EUR Oracle\";\n\n constructor(uint32 _stalePeriod, address _treasury) BaseOracleChainlinkMultiTwoFeeds(_stalePeriod, _treasury) {}\n\n /// @inheritdoc IOracle\n function circuitChainlink() public pure override returns (AggregatorV3Interface[] memory) {\n AggregatorV3Interface[] memory _circuitChainlink = new AggregatorV3Interface[](2);\n // Oracle USDC/USD\n _circuitChainlink[0] = AggregatorV3Interface(0x16a9FA2FDa030272Ce99B29CF780dFA30361E0f3);\n // Oracle EUR/USD\n _circuitChainlink[1] = AggregatorV3Interface(0x3626369857A10CcC6cc3A6e4f5C2f5984a519F20);\n return _circuitChainlink;\n }\n}\n" + }, + "contracts/oracle/implementations/polygon/EUR/OracleBTCEURChainlinkPolygon.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\nimport \"@chainlink/contracts/src/v0.8/interfaces/AggregatorV3Interface.sol\";\n\nimport \"../../../BaseOracleChainlinkMultiTwoFeeds.sol\";\n\n/// @title OracleBTCEURChainlinkPolygon\n/// @author Angle Labs, Inc.\n/// @notice Gives the price of BTC in Euro in base 18\n/// @dev This contract is built to be deployed on Polygon\ncontract OracleBTCEURChainlinkPolygon is BaseOracleChainlinkMultiTwoFeeds {\n string public constant DESCRIPTION = \"BTC/EUR Oracle\";\n\n constructor(uint32 _stalePeriod, address _treasury) BaseOracleChainlinkMultiTwoFeeds(_stalePeriod, _treasury) {}\n\n /// @inheritdoc IOracle\n function circuitChainlink() public pure override returns (AggregatorV3Interface[] memory) {\n AggregatorV3Interface[] memory _circuitChainlink = new AggregatorV3Interface[](2);\n // Oracle BTC/USD\n _circuitChainlink[0] = AggregatorV3Interface(0xc907E116054Ad103354f2D350FD2514433D57F6f);\n // Oracle EUR/USD\n _circuitChainlink[1] = AggregatorV3Interface(0x73366Fe0AA0Ded304479862808e02506FE556a98);\n return _circuitChainlink;\n }\n}\n" + }, + "contracts/oracle/implementations/polygon/EUR/OracleETHEURChainlinkPolygon.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\nimport \"@chainlink/contracts/src/v0.8/interfaces/AggregatorV3Interface.sol\";\n\nimport \"../../../BaseOracleChainlinkMultiTwoFeeds.sol\";\n\n/// @title OracleETHEURChainlinkPolygon\n/// @author Angle Labs, Inc.\n/// @notice Gives the price of ETH in Euro in base 18\n/// @dev This contract is built to be deployed on Polygon\ncontract OracleETHEURChainlinkPolygon is BaseOracleChainlinkMultiTwoFeeds {\n string public constant DESCRIPTION = \"ETH/EUR Oracle\";\n\n constructor(uint32 _stalePeriod, address _treasury) BaseOracleChainlinkMultiTwoFeeds(_stalePeriod, _treasury) {}\n\n /// @inheritdoc IOracle\n function circuitChainlink() public pure override returns (AggregatorV3Interface[] memory) {\n AggregatorV3Interface[] memory _circuitChainlink = new AggregatorV3Interface[](2);\n // Oracle ETH/USD\n _circuitChainlink[0] = AggregatorV3Interface(0xF9680D99D6C9589e2a93a78A04A279e509205945);\n // Oracle EUR/USD\n _circuitChainlink[1] = AggregatorV3Interface(0x73366Fe0AA0Ded304479862808e02506FE556a98);\n return _circuitChainlink;\n }\n}\n" + }, + "contracts/oracle/implementations/polygon/EUR/OracleMAIEURChainlinkPolygon.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\nimport \"@chainlink/contracts/src/v0.8/interfaces/AggregatorV3Interface.sol\";\n\nimport \"../../../BaseOracleChainlinkMultiTwoFeeds.sol\";\n\n/// @title OracleMAIEURChainlinkPolygon\n/// @author Angle Labs, Inc.\n/// @notice Gives the price of MAI in Euro in base 18\n/// @dev This contract is built to be deployed on Polygon\ncontract OracleMAIEURChainlinkPolygon is BaseOracleChainlinkMultiTwoFeeds {\n string public constant DESCRIPTION = \"MAI/EUR Oracle\";\n\n constructor(uint32 _stalePeriod, address _treasury) BaseOracleChainlinkMultiTwoFeeds(_stalePeriod, _treasury) {}\n\n /// @inheritdoc IOracle\n function circuitChainlink() public pure override returns (AggregatorV3Interface[] memory) {\n AggregatorV3Interface[] memory _circuitChainlink = new AggregatorV3Interface[](2);\n // Oracle MAI/USD\n _circuitChainlink[0] = AggregatorV3Interface(0xd8d483d813547CfB624b8Dc33a00F2fcbCd2D428);\n // Oracle EUR/USD\n _circuitChainlink[1] = AggregatorV3Interface(0x73366Fe0AA0Ded304479862808e02506FE556a98);\n return _circuitChainlink;\n }\n}\n" + }, + "contracts/oracle/implementations/polygon/EUR/OracleMATICEURChainlinkPolygon.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\nimport \"@chainlink/contracts/src/v0.8/interfaces/AggregatorV3Interface.sol\";\n\nimport \"../../../BaseOracleChainlinkMultiTwoFeeds.sol\";\n\n/// @title OracleMATICEURChainlinkPolygon\n/// @author Angle Labs, Inc.\n/// @notice Gives the price of MATIC in Euro in base 18\n/// @dev This contract is built to be deployed on Polygon\ncontract OracleMATICEURChainlinkPolygon is BaseOracleChainlinkMultiTwoFeeds {\n string public constant DESCRIPTION = \"MATIC/EUR Oracle\";\n\n constructor(uint32 _stalePeriod, address _treasury) BaseOracleChainlinkMultiTwoFeeds(_stalePeriod, _treasury) {}\n\n /// @inheritdoc IOracle\n function circuitChainlink() public pure override returns (AggregatorV3Interface[] memory) {\n AggregatorV3Interface[] memory _circuitChainlink = new AggregatorV3Interface[](2);\n // Oracle MATIC/USD\n _circuitChainlink[0] = AggregatorV3Interface(0xAB594600376Ec9fD91F8e885dADF0CE036862dE0);\n // Oracle EUR/USD\n _circuitChainlink[1] = AggregatorV3Interface(0x73366Fe0AA0Ded304479862808e02506FE556a98);\n return _circuitChainlink;\n }\n}\n" + }, + "contracts/oracle/implementations/polygon/EUR/OracleUSDCEURChainlinkPolygon.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\nimport \"../../../BaseOracleChainlinkMultiTwoFeeds.sol\";\n\n/// @title OracleUSDCEURChainlinkPolygon\n/// @author Angle Labs, Inc.\n/// @notice Gives the price of USDC in Euro in base 18\n/// @dev This contract is built to be deployed on Polygon\ncontract OracleUSDCEURChainlinkPolygon is BaseOracleChainlinkMultiTwoFeeds {\n string public constant DESCRIPTION = \"USDC/EUR Oracle\";\n\n constructor(uint32 _stalePeriod, address _treasury) BaseOracleChainlinkMultiTwoFeeds(_stalePeriod, _treasury) {}\n\n /// @inheritdoc IOracle\n function circuitChainlink() public pure override returns (AggregatorV3Interface[] memory) {\n AggregatorV3Interface[] memory _circuitChainlink = new AggregatorV3Interface[](2);\n // Oracle USDC/USD\n _circuitChainlink[0] = AggregatorV3Interface(0xfE4A8cc5b5B2366C1B58Bea3858e81843581b2F7);\n // Oracle EUR/USD\n _circuitChainlink[1] = AggregatorV3Interface(0x73366Fe0AA0Ded304479862808e02506FE556a98);\n return _circuitChainlink;\n }\n}\n" + }, + "contracts/oracle/implementations/polygon/XAU/OracleETHXAUChainlinkPolygon.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\nimport \"@chainlink/contracts/src/v0.8/interfaces/AggregatorV3Interface.sol\";\n\nimport \"../../../BaseOracleChainlinkMultiTwoFeeds.sol\";\n\n/// @title OracleETHXAUChainlinkPolygon\n/// @author Angle Labs, Inc.\n/// @notice Gives the price of ETH in XAU in base 18\n/// @dev This contract is built to be deployed on Polygon\ncontract OracleETHXAUChainlinkPolygon is BaseOracleChainlinkMultiTwoFeeds {\n string public constant DESCRIPTION = \"ETH/GOLD Oracle\";\n\n constructor(uint32 _stalePeriod, address _treasury) BaseOracleChainlinkMultiTwoFeeds(_stalePeriod, _treasury) {}\n\n /// @inheritdoc IOracle\n function circuitChainlink() public pure override returns (AggregatorV3Interface[] memory) {\n AggregatorV3Interface[] memory _circuitChainlink = new AggregatorV3Interface[](2);\n // Oracle ETH/USD\n _circuitChainlink[0] = AggregatorV3Interface(0xF9680D99D6C9589e2a93a78A04A279e509205945);\n // Oracle XAU/USD\n _circuitChainlink[1] = AggregatorV3Interface(0x0C466540B2ee1a31b441671eac0ca886e051E410);\n return _circuitChainlink;\n }\n}\n" + }, + "contracts/oracle/KeeperRegistry.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\nimport \"@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol\";\nimport \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\nimport \"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\";\n\nimport \"../interfaces/ICoreBorrow.sol\";\nimport \"../interfaces/IKeeperRegistry.sol\";\n\n/// @title KeeperRegistry\n/// @notice Maintains a mapping of keepers authorized to use the core module just after oracle updates\n/// @author Angle Labs, Inc.\ncontract KeeperRegistry is Initializable, IKeeperRegistry {\n using SafeERC20 for IERC20;\n\n /// @notice Contract handling access control\n ICoreBorrow public coreBorrow;\n\n /// @notice Trusted EOAs - needs to be tx.origin\n mapping(address => uint256) public trusted;\n\n uint256[48] private __gap;\n\n // =================================== EVENTS ==================================\n\n event TrustedToggled(address indexed wallet, bool trust);\n\n // =================================== ERRORS ==================================\n\n error NotGovernorOrGuardian();\n error NotTrusted();\n error ZeroAddress();\n\n // ================================= MODIFIERS =================================\n\n /// @notice Checks whether the `msg.sender` has the governor role or the guardian role\n modifier onlyGovernorOrGuardian() {\n if (!coreBorrow.isGovernorOrGuardian(msg.sender)) revert NotGovernorOrGuardian();\n _;\n }\n\n // ================================ CONSTRUCTOR ================================\n\n constructor() initializer {}\n\n function initialize(ICoreBorrow _coreBorrow) public initializer {\n if (address(_coreBorrow) == address(0)) revert ZeroAddress();\n coreBorrow = _coreBorrow;\n }\n\n // =============================== MAIN FUNCTIONS ==============================\n\n /// @notice Adds or removes a trusted keeper bot\n function toggleTrusted(address eoa) external onlyGovernorOrGuardian {\n uint256 trustedStatus = 1 - trusted[eoa];\n trusted[eoa] = trustedStatus;\n emit TrustedToggled(eoa, trustedStatus == 1);\n }\n\n /// @inheritdoc IKeeperRegistry\n function isTrusted(address caller) external view returns (bool) {\n return trusted[caller] == 1;\n }\n}\n" + }, + "contracts/oracle/OracleChainlinkMulti.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\nimport \"@chainlink/contracts/src/v0.8/interfaces/AggregatorV3Interface.sol\";\n\nimport \"./BaseOracleChainlinkMulti.sol\";\n\n/// @title OracleChainlinkMulti\n/// @author Angle Labs, Inc.\n/// @notice Oracle contract, one contract is deployed per collateral/stablecoin pair\n/// @dev This contract concerns an oracle that uses Chainlink with multiple pools to read from\n/// @dev Typically we expect to use this contract to read like the ETH/USD and then USD/EUR feed\ncontract OracleChainlinkMulti is BaseOracleChainlinkMulti {\n // ========================= Parameters and References =========================\n\n /// @notice Chainlink pools, the order of the pools has to be the order in which they are read for the computation\n /// of the price\n AggregatorV3Interface[] internal _circuitChainlink;\n /// @notice Whether each rate for the pairs in `circuitChainlink` should be multiplied or divided\n uint8[] public circuitChainIsMultiplied;\n /// @notice Decimals for each Chainlink pairs\n uint8[] public chainlinkDecimals;\n /// @notice Unit of the stablecoin\n uint256 public immutable outBase;\n /// @notice Description of the assets concerned by the oracle and the price outputted\n string public description;\n\n // ===================================== Error =================================\n\n error IncompatibleLengths();\n\n /// @notice Constructor for an oracle using Chainlink with multiple pools to read from\n /// @param circuitChainlink_ Chainlink pool addresses (in order)\n /// @param _circuitChainIsMultiplied Whether we should multiply or divide by this rate\n /// @param _outBase Unit of the stablecoin (or the out asset) associated to the oracle\n /// @param _stalePeriod Minimum feed update frequency for the oracle to not revert\n /// @param _treasury Treasury associated to the VaultManager which reads from this feed\n /// @param _description Description of the assets concerned by the oracle\n /// @dev For instance, if this oracle is supposed to give the price of ETH in EUR, and if the agEUR\n /// stablecoin associated to EUR has 18 decimals, then `outBase` should be 10**18\n constructor(\n address[] memory circuitChainlink_,\n uint8[] memory _circuitChainIsMultiplied,\n uint256 _outBase,\n uint32 _stalePeriod,\n address _treasury,\n string memory _description\n ) BaseOracleChainlinkMulti(_stalePeriod, _treasury) {\n outBase = _outBase;\n description = _description;\n uint256 circuitLength = circuitChainlink_.length;\n if (circuitLength == 0 || circuitLength != _circuitChainIsMultiplied.length) revert IncompatibleLengths();\n for (uint256 i; i < circuitLength; ++i) {\n AggregatorV3Interface _pool = AggregatorV3Interface(circuitChainlink_[i]);\n _circuitChainlink.push(_pool);\n chainlinkDecimals.push(_pool.decimals());\n }\n circuitChainIsMultiplied = _circuitChainIsMultiplied;\n }\n\n // ============================= Reading Oracles ===============================\n\n /// @inheritdoc IOracle\n function circuitChainlink() public view override returns (AggregatorV3Interface[] memory) {\n return _circuitChainlink;\n }\n\n /// @inheritdoc IOracle\n function read() external view override returns (uint256 quoteAmount) {\n quoteAmount = outBase;\n uint256 circuitLength = _circuitChainlink.length;\n for (uint256 i; i < circuitLength; ++i) {\n quoteAmount = _readChainlinkFeed(\n quoteAmount,\n _circuitChainlink[i],\n circuitChainIsMultiplied[i],\n chainlinkDecimals[i]\n );\n }\n }\n}\n" + }, + "contracts/settlement/Settlement.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\nimport \"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\";\nimport \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\nimport \"@openzeppelin/contracts/token/ERC20/extensions/IERC20Metadata.sol\";\n\nimport \"../interfaces/IAgToken.sol\";\nimport \"../interfaces/ISwapper.sol\";\nimport \"../interfaces/IVaultManager.sol\";\n\n/// @title Settlement\n/// @author Angle Labs, Inc.\n/// @notice Settlement Contract for a VaultManager\n/// @dev This settlement contract should be activated by a careful governance which needs to have performed\n/// some key operations before activating this contract\n/// @dev In case of global settlement, there should be one settlement contract per `VaultManager`\ncontract Settlement {\n using SafeERC20 for IERC20;\n\n /// @notice Base used for parameter computation\n uint256 public constant BASE_PARAMS = 10 ** 9;\n /// @notice Base used for interest computation\n uint256 public constant BASE_INTEREST = 10 ** 27;\n /// @notice Base used for exchange rate computation. It is assumed\n /// that stablecoins have this base\n uint256 public constant BASE_STABLECOIN = 10 ** 18;\n /// @notice Duration of the claim period for over-collateralized vaults\n uint256 public constant OVER_COLLATERALIZED_CLAIM_DURATION = 3 * 24 * 3600;\n\n // =============== Immutable references set in the constructor =================\n\n /// @notice `VaultManager` of this settlement contract\n IVaultManager public immutable vaultManager;\n /// @notice Reference to the stablecoin supported by the `VaultManager` contract\n IAgToken public immutable stablecoin;\n /// @notice Reference to the collateral supported by the `VaultManager`\n IERC20 public immutable collateral;\n /// @notice Base of the collateral\n uint256 internal immutable _collatBase;\n\n // ================ Variables frozen at settlement activation ==================\n\n /// @notice Value of the oracle for the collateral/stablecoin pair\n uint256 public oracleValue;\n /// @notice Value of the interest accumulator at settlement activation\n uint256 public interestAccumulator;\n /// @notice Timestamp at which settlement was activated\n uint256 public activationTimestamp;\n /// @notice Collateral factor of the `VaultManager`\n uint64 public collateralFactor;\n\n // =================== Variables updated during the process ====================\n\n /// @notice How much collateral you can get from stablecoins\n uint256 public collateralStablecoinExchangeRate;\n /// @notice Amount of collateral that will be left over at the end of the process\n uint256 public leftOverCollateral;\n /// @notice Whether the `collateralStablecoinExchangeRate` has been computed\n bool public exchangeRateComputed;\n /// @notice Maps a vault to 1 if it was claimed by its owner\n mapping(uint256 => uint256) public vaultCheck;\n\n // ================================ Events =====================================\n\n event GlobalClaimPeriodActivated(uint256 _collateralStablecoinExchangeRate);\n event Recovered(address indexed tokenAddress, address indexed to, uint256 amount);\n event SettlementActivated(uint256 startTimestamp);\n event VaultClaimed(uint256 vaultID, uint256 stablecoinAmount, uint256 collateralAmount);\n\n // ================================ Errors =====================================\n\n error GlobalClaimPeriodNotStarted();\n error InsolventVault();\n error NotGovernor();\n error NotOwner();\n error RestrictedClaimPeriodNotEnded();\n error SettlementNotInitialized();\n error VaultAlreadyClaimed();\n\n /// @notice Constructor of the contract\n /// @param _vaultManager Address of the `VaultManager` associated to this `Settlement` contract\n /// @dev Out of safety, this constructor reads values from the `VaultManager` contract directly\n constructor(IVaultManager _vaultManager) {\n vaultManager = _vaultManager;\n stablecoin = _vaultManager.stablecoin();\n collateral = _vaultManager.collateral();\n _collatBase = 10 ** (IERC20Metadata(address(collateral)).decimals());\n }\n\n /// @notice Checks whether the `msg.sender` has the governor role or not\n modifier onlyGovernor() {\n if (!(vaultManager.treasury().isGovernor(msg.sender))) revert NotGovernor();\n _;\n }\n\n /// @notice Activates the settlement contract\n /// @dev When calling this function governance should make sure to have:\n /// 1. Accrued the interest rate on the contract\n /// 2. Paused the contract\n /// 3. Recovered all the collateral available in the `VaultManager` contract either\n /// by doing a contract upgrade or by calling a `recoverERC20` method if supported\n function activateSettlement() external onlyGovernor {\n oracleValue = (vaultManager.oracle()).read();\n interestAccumulator = vaultManager.interestAccumulator();\n activationTimestamp = block.timestamp;\n collateralFactor = vaultManager.collateralFactor();\n emit SettlementActivated(block.timestamp);\n }\n\n /// @notice Allows the owner of an over-collateralized vault to claim its collateral upon bringing back all owed stablecoins\n /// @param vaultID ID of the vault to claim\n /// @param to Address to which collateral should be sent\n /// @param who Address which should be notified if needed of the transfer of stablecoins and collateral\n /// @param data Data to pass to the `who` contract for it to successfully give the correct amount of stablecoins\n /// to the `msg.sender` address\n /// @return Amount of collateral sent to the `to` address\n /// @return Amount of stablecoins sent to the contract\n /// @dev Claiming can only happen short after settlement activation\n /// @dev A vault cannot be claimed twice and only the owner of the vault can claim it (regardless of the approval logic)\n /// @dev Only over-collateralized vaults can be claimed from this medium\n function claimOverCollateralizedVault(\n uint256 vaultID,\n address to,\n address who,\n bytes memory data\n ) external returns (uint256, uint256) {\n if (activationTimestamp == 0 || block.timestamp > activationTimestamp + OVER_COLLATERALIZED_CLAIM_DURATION)\n revert SettlementNotInitialized();\n if (vaultCheck[vaultID] == 1) revert VaultAlreadyClaimed();\n if (vaultManager.ownerOf(vaultID) != msg.sender) revert NotOwner();\n (uint256 collateralAmount, uint256 normalizedDebt) = vaultManager.vaultData(vaultID);\n uint256 vaultDebt = (normalizedDebt * interestAccumulator) / BASE_INTEREST;\n if (collateralAmount * oracleValue * collateralFactor < vaultDebt * BASE_PARAMS * _collatBase)\n revert InsolventVault();\n vaultCheck[vaultID] = 1;\n emit VaultClaimed(vaultID, vaultDebt, collateralAmount);\n return _handleRepay(collateralAmount, vaultDebt, to, who, data);\n }\n\n /// @notice Activates the global claim period by setting the `collateralStablecoinExchangeRate` which is going to\n /// dictate how much of collateral will be recoverable for each stablecoin\n /// @dev This function can only be called by the governor in order to allow it in case multiple settlements happen across\n /// different `VaultManager` to rebalance the amount of stablecoins on each to make sure that across all settlement contracts\n /// a similar value of collateral can be obtained against a similar value of stablecoins\n function activateGlobalClaimPeriod() external onlyGovernor {\n if (activationTimestamp == 0 || block.timestamp <= activationTimestamp + OVER_COLLATERALIZED_CLAIM_DURATION)\n revert RestrictedClaimPeriodNotEnded();\n uint256 collateralBalance = collateral.balanceOf(address(this));\n uint256 leftOverDebt = (vaultManager.totalNormalizedDebt() * interestAccumulator) / BASE_INTEREST;\n uint256 stablecoinBalance = stablecoin.balanceOf(address(this));\n // How much 1 of stablecoin will give you in collateral\n uint256 _collateralStablecoinExchangeRate;\n\n if (stablecoinBalance < leftOverDebt) {\n // The left over debt is the total debt minus the stablecoins which have already been accumulated\n // in the first phase\n leftOverDebt -= stablecoinBalance;\n // If you control all the debt, then you are entitled to get all the collateral left in the protocol\n _collateralStablecoinExchangeRate = (collateralBalance * BASE_STABLECOIN) / leftOverDebt;\n // But at the same time, you cannot get more collateral than the value of the stablecoins you brought\n uint256 maxExchangeRate = (BASE_STABLECOIN * _collatBase) / oracleValue;\n if (_collateralStablecoinExchangeRate >= maxExchangeRate) {\n // In this situation, we're sure that `leftOverCollateral` will be positive: governance should be wary\n // to call `recoverERC20` short after though as there's nothing that is going to prevent people to redeem\n // more stablecoins than the `leftOverDebt`\n leftOverCollateral = collateralBalance - (leftOverDebt * _collatBase) / oracleValue;\n _collateralStablecoinExchangeRate = maxExchangeRate;\n }\n }\n exchangeRateComputed = true;\n // In the else case where there is no debt left, you cannot get anything from your stablecoins\n // and so the `collateralStablecoinExchangeRate` is null\n collateralStablecoinExchangeRate = _collateralStablecoinExchangeRate;\n emit GlobalClaimPeriodActivated(_collateralStablecoinExchangeRate);\n }\n\n /// @notice Allows to claim collateral from stablecoins\n /// @param to Address to which collateral should be sent\n /// @param who Address which should be notified if needed of the transfer of stablecoins and collateral\n /// @param data Data to pass to the `who` contract for it to successfully give the correct amount of stablecoins\n /// to the `msg.sender` address\n /// @return Amount of collateral sent to the `to` address\n /// @return Amount of stablecoins sent to the contract\n /// @dev This function reverts if the `collateralStablecoinExchangeRate` is null and hence if the global claim period has\n /// not been activated\n function claimCollateralFromStablecoins(\n uint256 stablecoinAmount,\n address to,\n address who,\n bytes memory data\n ) external returns (uint256, uint256) {\n if (!exchangeRateComputed) revert GlobalClaimPeriodNotStarted();\n return\n _handleRepay(\n (stablecoinAmount * collateralStablecoinExchangeRate) / BASE_STABLECOIN,\n stablecoinAmount,\n to,\n who,\n data\n );\n }\n\n /// @notice Handles the simultaneous repayment of stablecoins with a transfer of collateral\n /// @param collateralAmountToGive Amount of collateral the contract should give\n /// @param stableAmountToRepay Amount of stablecoins the contract should burn from the call\n /// @param to Address to which stablecoins should be sent\n /// @param who Address which should be notified if needed of the transfer\n /// @param data Data to pass to the `who` contract for it to successfully give the correct amount of stablecoins\n /// to the `msg.sender` address\n /// @dev This function allows for capital-efficient claims of collateral from stablecoins\n function _handleRepay(\n uint256 collateralAmountToGive,\n uint256 stableAmountToRepay,\n address to,\n address who,\n bytes memory data\n ) internal returns (uint256, uint256) {\n collateral.safeTransfer(to, collateralAmountToGive);\n if (data.length != 0) {\n ISwapper(who).swap(\n collateral,\n IERC20(address(stablecoin)),\n msg.sender,\n stableAmountToRepay,\n collateralAmountToGive,\n data\n );\n }\n stablecoin.transferFrom(msg.sender, address(this), stableAmountToRepay);\n return (collateralAmountToGive, stableAmountToRepay);\n }\n\n /// @notice Recovers leftover tokens from the contract or tokens that were mistakenly sent to the contract\n /// @param tokenAddress Address of the token to recover\n /// @param to Address to send the remaining tokens to\n /// @param amountToRecover Amount to recover from the contract\n /// @dev Governors cannot recover more collateral than what would be leftover from the contract\n /// @dev This function can be used to rebalance stablecoin balances across different settlement contracts\n /// to make sure every stablecoin can be redeemed for the same value of collateral\n /// @dev It can also be used to recover tokens that are mistakenly sent to this contract\n function recoverERC20(address tokenAddress, address to, uint256 amountToRecover) external onlyGovernor {\n if (tokenAddress == address(collateral)) {\n if (!exchangeRateComputed) revert GlobalClaimPeriodNotStarted();\n leftOverCollateral -= amountToRecover;\n collateral.safeTransfer(to, amountToRecover);\n } else {\n IERC20(tokenAddress).safeTransfer(to, amountToRecover);\n }\n emit Recovered(tokenAddress, to, amountToRecover);\n }\n}\n" + }, + "contracts/swapper/Swapper.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\n/*\n * █ \n ***** ▓▓▓ \n * ▓▓▓▓▓▓▓ \n * ///. ▓▓▓▓▓▓▓▓▓▓▓▓▓ \n ***** //////// ▓▓▓▓▓▓▓ \n * ///////////// ▓▓▓ \n ▓▓ ////////////////// █ ▓▓ \n ▓▓ ▓▓ /////////////////////// ▓▓ ▓▓ \n ▓▓ ▓▓ //////////////////////////// ▓▓ ▓▓ \n ▓▓ ▓▓ /////////▓▓▓///////▓▓▓///////// ▓▓ ▓▓ \n ▓▓ ,////////////////////////////////////// ▓▓ ▓▓ \n ▓▓ ////////////////////////////////////////// ▓▓ \n ▓▓ //////////////////////▓▓▓▓///////////////////// \n ,//////////////////////////////////////////////////// \n .////////////////////////////////////////////////////////// \n .//////////////////////////██.,//////////////////////////█ \n .//////////////////////████..,./////////////////////██ \n ...////////////////███████.....,.////////////////███ \n ,.,////////////████████ ........,///////////████ \n .,.,//////█████████ ,.......///////████ \n ,..//████████ ........./████ \n ..,██████ .....,███ \n .██ ,.,█ \n \n \n \n ▓▓ ▓▓▓▓▓▓▓▓▓▓ ▓▓▓▓▓▓▓▓▓▓ ▓▓ ▓▓▓▓▓▓▓▓▓▓ \n ▓▓▓▓▓▓ ▓▓▓ ▓▓▓ ▓▓▓ ▓▓ ▓▓ ▓▓▓▓ \n ▓▓▓ ▓▓▓ ▓▓▓ ▓▓▓ ▓▓▓ ▓▓▓ ▓▓ ▓▓▓▓▓ \n ▓▓▓ ▓▓ ▓▓▓ ▓▓▓ ▓▓▓▓▓▓▓▓▓▓ ▓▓▓▓▓▓▓▓▓▓ ▓▓▓▓▓▓▓▓▓▓ \n*/\n\npragma solidity ^0.8.12;\n\nimport \"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\";\nimport \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\n\nimport \"../interfaces/IAngleRouterSidechain.sol\";\nimport \"../interfaces/ICoreBorrow.sol\";\nimport \"../interfaces/ISwapper.sol\";\nimport \"../interfaces/external/lido/IWStETH.sol\";\nimport \"../interfaces/external/uniswap/IUniswapRouter.sol\";\n\n// ==================================== ENUM ===================================\n\n/// @notice All possible swaps\nenum SwapType {\n UniswapV3,\n oneInch,\n AngleRouter,\n Leverage,\n None\n}\n\n/// @title Swapper\n/// @author Angle Labs, Inc.\n/// @notice Swapper contract facilitating interactions with Angle VaultManager contracts, notably\n/// liquidation and leverage transactions\ncontract Swapper is ISwapper {\n using SafeERC20 for IERC20;\n\n // ===================== CONSTANTS AND IMMUTABLE VARIABLES =====================\n\n /// @notice Reference to the `CoreBorrow` contract of the module which handles all AccessControl logic\n ICoreBorrow public immutable core;\n /// @notice Uniswap Router contract\n IUniswapV3Router public immutable uniV3Router;\n /// @notice 1inch Router\n address public immutable oneInch;\n /// @notice AngleRouter\n IAngleRouterSidechain public immutable angleRouter;\n\n // =================================== ERRORS ==================================\n\n error EmptyReturnMessage();\n error IncompatibleLengths();\n error NotGovernorOrGuardian();\n error TooSmallAmountOut();\n error ZeroAddress();\n\n /// @notice Constructor of the contract\n /// @param _core Core address\n /// @param _uniV3Router UniswapV3 Router address\n /// @param _oneInch 1inch Router address\n /// @param _angleRouter AngleRouter contract address\n constructor(\n ICoreBorrow _core,\n IUniswapV3Router _uniV3Router,\n address _oneInch,\n IAngleRouterSidechain _angleRouter\n ) {\n if (address(_core) == address(0) || _oneInch == address(0) || address(_angleRouter) == address(0))\n revert ZeroAddress();\n core = _core;\n uniV3Router = _uniV3Router;\n oneInch = _oneInch;\n angleRouter = _angleRouter;\n }\n\n // ========================= EXTERNAL ACCESS FUNCTIONS =========================\n\n /// @inheritdoc ISwapper\n /// @dev This function swaps the `inToken` to the `outToken` by doing a UniV3 swap, a 1inch swap or by interacting\n /// with the `AngleRouter` contract\n /// @dev One slippage check is performed at the end of the call\n /// @dev In this implementation, the function tries to make sure that the `outTokenRecipient` address has at the end\n /// of the call `outTokenOwed`, leftover tokens are sent to a `to` address which by default is the `outTokenRecipient`\n function swap(\n IERC20 inToken,\n IERC20 outToken,\n address outTokenRecipient,\n uint256 outTokenOwed,\n uint256 inTokenObtained,\n bytes memory data\n ) external {\n // Address to receive the surplus amount of token at the end of the call\n address to;\n // For slippage protection, it is checked at the end of the call\n uint256 minAmountOut;\n // Type of the swap to execute: if `swapType == 4`, then it is optional to swap\n uint256 swapType;\n // We're reusing the `data` variable (it can be `path` on UniswapV3, a payload for 1inch or like encoded actions\n // for a router call)\n (to, minAmountOut, swapType, data) = abi.decode(data, (address, uint256, uint256, bytes));\n\n to = (to == address(0)) ? outTokenRecipient : to;\n\n _swap(inToken, inTokenObtained, SwapType(swapType), data);\n\n // A final slippage check is performed after the swaps\n uint256 outTokenBalance = outToken.balanceOf(address(this));\n if (outTokenBalance < minAmountOut) revert TooSmallAmountOut();\n\n // The `outTokenRecipient` may already have enough in balance, in which case there's no need to transfer\n // to this address the token and everything can be given to the `to` address\n uint256 outTokenBalanceRecipient = outToken.balanceOf(outTokenRecipient);\n if (outTokenBalanceRecipient >= outTokenOwed || to == outTokenRecipient)\n outToken.safeTransfer(to, outTokenBalance);\n else {\n // The `outTokenRecipient` should receive the delta to make sure its end balance is equal to `outTokenOwed`\n // Any leftover in this case is sent to the `to` address\n // The function reverts if it did not obtain more than `outTokenOwed - outTokenBalanceRecipient` from the swap\n outToken.safeTransfer(outTokenRecipient, outTokenOwed - outTokenBalanceRecipient);\n outToken.safeTransfer(to, outTokenBalanceRecipient + outTokenBalance - outTokenOwed);\n }\n // Reusing the `inTokenObtained` variable for the `inToken` balance\n // Sending back the remaining amount of inTokens to the `to` address: it is possible that not the full `inTokenObtained`\n // is swapped to `outToken` if we're using the `1inch` payload\n inTokenObtained = inToken.balanceOf(address(this));\n if (inTokenObtained != 0) inToken.safeTransfer(to, inTokenObtained);\n }\n\n // ============================ GOVERNANCE FUNCTION ============================\n\n /// @notice Changes allowances of this contract for different tokens\n /// @param tokens Addresses of the tokens to allow\n /// @param spenders Addresses to allow transfer\n /// @param amounts Amounts to allow\n function changeAllowance(\n IERC20[] calldata tokens,\n address[] calldata spenders,\n uint256[] calldata amounts\n ) external {\n if (!core.isGovernorOrGuardian(msg.sender)) revert NotGovernorOrGuardian();\n uint256 tokensLength = tokens.length;\n if (tokensLength != spenders.length || tokensLength != amounts.length) revert IncompatibleLengths();\n for (uint256 i; i < tokensLength; ++i) {\n _changeAllowance(tokens[i], spenders[i], amounts[i]);\n }\n }\n\n // ========================= INTERNAL UTILITY FUNCTIONS ========================\n\n /// @notice Internal version of the `_changeAllowance` function\n function _changeAllowance(IERC20 token, address spender, uint256 amount) internal {\n uint256 currentAllowance = token.allowance(address(this), spender);\n // In case `currentAllowance < type(uint256).max / 2` and we want to increase it:\n // Do nothing (to handle tokens that need reapprovals to 0 and save gas)\n if (currentAllowance < amount && currentAllowance < type(uint256).max / 2) {\n token.safeIncreaseAllowance(spender, amount - currentAllowance);\n } else if (currentAllowance > amount) {\n token.safeDecreaseAllowance(spender, currentAllowance - amount);\n }\n }\n\n /// @notice Checks the allowance for a contract and updates it to the max if it is not big enough\n /// @param token Token for which allowance should be checked\n /// @param spender Address to grant allowance to\n /// @param amount Minimum amount of tokens needed for the allowance\n function _checkAllowance(IERC20 token, address spender, uint256 amount) internal {\n uint256 currentAllowance = token.allowance(address(this), spender);\n if (currentAllowance < amount) token.safeIncreaseAllowance(spender, type(uint256).max - currentAllowance);\n }\n\n /// @notice Performs a swap using either Uniswap, 1inch. This function can also stake stETH to wstETH\n /// @param inToken Token to swap\n /// @param amount Amount of tokens to swap\n /// @param swapType Type of the swap to perform\n /// @param args Extra args for the swap: in the case of Uniswap it should be a path, for 1inch it should be\n /// a payload\n /// @dev This function does nothing if `swapType` is None and it simply passes on the `amount` it received\n /// @dev No slippage is specified in the actions given here as a final slippage check is performed\n /// after the call to this function\n function _swap(IERC20 inToken, uint256 amount, SwapType swapType, bytes memory args) internal {\n if (swapType == SwapType.UniswapV3) _swapOnUniswapV3(inToken, amount, args);\n else if (swapType == SwapType.oneInch) _swapOn1inch(inToken, args);\n else if (swapType == SwapType.AngleRouter) _angleRouterActions(inToken, args);\n else if (swapType == SwapType.Leverage) _swapLeverage(args);\n }\n\n /// @notice Performs a UniswapV3 swap\n /// @param inToken Token to swap\n /// @param amount Amount of tokens to swap\n /// @param path Path for the UniswapV3 swap: this encodes the out token that is going to be obtained\n /// @dev This function does not check the out token obtained here: if it is wrongly specified, either\n /// the `swap` function could fail or these tokens could stay on the contract\n function _swapOnUniswapV3(IERC20 inToken, uint256 amount, bytes memory path) internal returns (uint256 amountOut) {\n // We need more than `amount` of allowance to the contract\n _checkAllowance(inToken, address(uniV3Router), amount);\n amountOut = uniV3Router.exactInput(ExactInputParams(path, address(this), block.timestamp, amount, 0));\n }\n\n /// @notice Allows to swap any token to an accepted collateral via 1inch API\n /// @param inToken Token received for the 1inch swap\n /// @param payload Bytes needed for 1inch API\n function _swapOn1inch(IERC20 inToken, bytes memory payload) internal returns (uint256 amountOut) {\n _changeAllowance(inToken, oneInch, type(uint256).max);\n //solhint-disable-next-line\n (bool success, bytes memory result) = oneInch.call(payload);\n if (!success) _revertBytes(result);\n amountOut = abi.decode(result, (uint256));\n }\n\n /// @notice Performs actions with the router contract of the protocol on the corresponding chain\n /// @param inToken Token concerned by the action and for which\n function _angleRouterActions(IERC20 inToken, bytes memory args) internal {\n (ActionType[] memory actions, bytes[] memory actionData) = abi.decode(args, (ActionType[], bytes[]));\n _changeAllowance(inToken, address(angleRouter), type(uint256).max);\n PermitType[] memory permits;\n angleRouter.mixer(permits, actions, actionData);\n }\n\n /// @notice Allows to take leverage or deleverage via a specific contract\n /// @param payload Bytes needed for 1inch API\n /// @dev This function is to be implemented if the swapper concerns a token that requires some actions\n /// not supported by 1inch or UniV3\n function _swapLeverage(bytes memory payload) internal virtual returns (uint256 amountOut) {}\n\n /// @notice Internal function used for error handling\n /// @param errMsg Error message received\n function _revertBytes(bytes memory errMsg) internal pure {\n if (errMsg.length != 0) {\n //solhint-disable-next-line\n assembly {\n revert(add(32, errMsg), mload(errMsg))\n }\n }\n revert EmptyReturnMessage();\n }\n}\n" + }, + "contracts/treasury/Treasury.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\n/*\n * █ \n ***** ▓▓▓ \n * ▓▓▓▓▓▓▓ \n * ///. ▓▓▓▓▓▓▓▓▓▓▓▓▓ \n ***** //////// ▓▓▓▓▓▓▓ \n * ///////////// ▓▓▓ \n ▓▓ ////////////////// █ ▓▓ \n ▓▓ ▓▓ /////////////////////// ▓▓ ▓▓ \n ▓▓ ▓▓ //////////////////////////// ▓▓ ▓▓ \n ▓▓ ▓▓ /////////▓▓▓///////▓▓▓///////// ▓▓ ▓▓ \n ▓▓ ,////////////////////////////////////// ▓▓ ▓▓ \n ▓▓ ////////////////////////////////////////// ▓▓ \n ▓▓ //////////////////////▓▓▓▓///////////////////// \n ,//////////////////////////////////////////////////// \n .////////////////////////////////////////////////////////// \n .//////////////////////////██.,//////////////////////////█ \n .//////////////////////████..,./////////////////////██ \n ...////////////////███████.....,.////////////////███ \n ,.,////////////████████ ........,///////////████ \n .,.,//////█████████ ,.......///////████ \n ,..//████████ ........./████ \n ..,██████ .....,███ \n .██ ,.,█ \n \n \n \n ▓▓ ▓▓▓▓▓▓▓▓▓▓ ▓▓▓▓▓▓▓▓▓▓ ▓▓ ▓▓▓▓▓▓▓▓▓▓ \n ▓▓▓▓▓▓ ▓▓▓ ▓▓▓ ▓▓▓ ▓▓ ▓▓ ▓▓▓▓ \n ▓▓▓ ▓▓▓ ▓▓▓ ▓▓▓ ▓▓▓ ▓▓▓ ▓▓ ▓▓▓▓▓ \n ▓▓▓ ▓▓ ▓▓▓ ▓▓▓ ▓▓▓▓▓▓▓▓▓▓ ▓▓▓▓▓▓▓▓▓▓ ▓▓▓▓▓▓▓▓▓▓ \n*/\n\npragma solidity ^0.8.12;\n\nimport \"@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol\";\nimport \"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\";\nimport \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\n\nimport \"../interfaces/IAgToken.sol\";\nimport \"../interfaces/ICoreBorrow.sol\";\nimport \"../interfaces/IFlashAngle.sol\";\nimport \"../interfaces/ITreasury.sol\";\nimport \"../interfaces/IVaultManager.sol\";\n\n/// @title Treasury\n/// @author Angle Labs, Inc.\n/// @notice Treasury of Angle Borrowing Module doing the accounting across all VaultManagers for\n/// a given stablecoin\ncontract Treasury is ITreasury, Initializable {\n using SafeERC20 for IERC20;\n\n /// @notice Base used for parameter computation\n uint256 public constant BASE_9 = 1e9;\n\n // ================================= REFERENCES ================================\n\n /// @notice Reference to the `CoreBorrow` contract of the module which handles all AccessControl logic\n ICoreBorrow public core;\n /// @notice Flash Loan Module with a minter right on the stablecoin\n IFlashAngle public flashLoanModule;\n /// @inheritdoc ITreasury\n IAgToken public stablecoin;\n /// @notice Address responsible for handling the surplus made by the treasury\n address public surplusManager;\n /// @notice List of the accepted `VaultManager` of the protocol\n address[] public vaultManagerList;\n /// @notice Maps an address to 1 if it was initialized as a `VaultManager` contract\n mapping(address => uint256) public vaultManagerMap;\n\n // ================================= VARIABLES =================================\n\n /// @notice Amount of bad debt (unbacked stablecoin) accumulated across all `VaultManager` contracts\n /// linked to this stablecoin\n uint256 public badDebt;\n /// @notice Surplus amount accumulated by the contract waiting to be distributed to governance. Technically\n /// only a share of this `surplusBuffer` will go to governance. Once a share of the surplus buffer has been\n /// given to governance, then this surplus is reset\n uint256 public surplusBuffer;\n\n // ================================= PARAMETER =================================\n\n /// @notice Share of the `surplusBuffer` distributed to governance (in `BASE_9`)\n uint64 public surplusForGovernance;\n\n // =================================== EVENTS ==================================\n\n event BadDebtUpdated(uint256 badDebtValue);\n event CoreUpdated(address indexed _core);\n event NewTreasurySet(address indexed _treasury);\n event Recovered(address indexed token, address indexed to, uint256 amount);\n event SurplusBufferUpdated(uint256 surplusBufferValue);\n event SurplusForGovernanceUpdated(uint64 _surplusForGovernance);\n event SurplusManagerUpdated(address indexed _surplusManager);\n event VaultManagerToggled(address indexed vaultManager);\n\n // =================================== ERRORS ==================================\n\n error AlreadyVaultManager();\n error InvalidAddress();\n error InvalidTreasury();\n error NotCore();\n error NotGovernor();\n error NotVaultManager();\n error RightsNotRemoved();\n error TooBigAmount();\n error TooHighParameterValue();\n error ZeroAddress();\n\n // ================================== MODIFIER =================================\n\n /// @notice Checks whether the `msg.sender` has the governor role or not\n modifier onlyGovernor() {\n if (!core.isGovernor(msg.sender)) revert NotGovernor();\n _;\n }\n\n /// @notice Initializes the treasury contract\n /// @param _core Address of the `CoreBorrow` contract of the module\n /// @param _stablecoin Address of the stablecoin\n function initialize(ICoreBorrow _core, IAgToken _stablecoin) public virtual initializer {\n if (address(_stablecoin) == address(0) || address(_core) == address(0)) revert ZeroAddress();\n core = _core;\n stablecoin = _stablecoin;\n }\n\n /// @custom:oz-upgrades-unsafe-allow constructor\n constructor() initializer {}\n\n // =============================== VIEW FUNCTIONS ==============================\n\n /// @inheritdoc ITreasury\n function isGovernor(address admin) external view returns (bool) {\n return core.isGovernor(admin);\n }\n\n /// @inheritdoc ITreasury\n function isGovernorOrGuardian(address admin) external view returns (bool) {\n return core.isGovernorOrGuardian(admin);\n }\n\n /// @inheritdoc ITreasury\n function isVaultManager(address _vaultManager) external view returns (bool) {\n return vaultManagerMap[_vaultManager] == 1;\n }\n\n // ===================== EXTERNAL PERMISSIONLESS FUNCTIONS =====================\n\n /// @notice Fetches the surplus accrued across all the `VaultManager` contracts controlled by this\n /// `Treasury` contract as well as from the fees of the `FlashLoan` module\n /// @return Surplus buffer value at the end of the call\n /// @return Bad debt value at the end of the call\n /// @dev This function pools surplus and bad debt across all contracts and then updates the `surplusBuffer`\n /// (or the `badDebt` if more losses were made than profits)\n function fetchSurplusFromAll() external returns (uint256, uint256) {\n return _fetchSurplusFromAll();\n }\n\n /// @notice Fetches the surplus accrued in the flash loan module and updates the `surplusBuffer`\n /// @return Surplus buffer value at the end of the call\n /// @return Bad debt value at the end of the call\n /// @dev This function fails if the `flashLoanModule` has not been initialized yet\n function fetchSurplusFromFlashLoan() external returns (uint256, uint256) {\n uint256 surplusBufferValue = surplusBuffer + flashLoanModule.accrueInterestToTreasury(stablecoin);\n return _updateSurplusAndBadDebt(surplusBufferValue, badDebt);\n }\n\n /// @notice Pushes the surplus buffer to the `surplusManager` contract\n /// @return governanceAllocation Amount transferred to governance\n /// @dev It makes sure to fetch the surplus from all the contracts handled by this treasury to avoid\n /// the situation where rewards are still distributed to governance even though a `VaultManager` has made\n /// a big loss\n /// @dev Typically this function is to be called once every week by a keeper to distribute rewards to veANGLE\n /// holders\n /// @dev `stablecoin` must be an AgToken and hence `transfer` reverts if the call is not successful\n function pushSurplus() external returns (uint256 governanceAllocation) {\n address _surplusManager = surplusManager;\n if (_surplusManager == address(0)) {\n revert ZeroAddress();\n }\n (uint256 surplusBufferValue, ) = _fetchSurplusFromAll();\n surplusBuffer = 0;\n emit SurplusBufferUpdated(0);\n governanceAllocation = (surplusForGovernance * surplusBufferValue) / BASE_9;\n stablecoin.transfer(_surplusManager, governanceAllocation);\n }\n\n /// @notice Updates the bad debt of the protocol in case where the protocol has accumulated some revenue\n /// from an external source\n /// @param amount Amount to reduce the bad debt of\n /// @return badDebtValue Value of the bad debt at the end of the call\n /// @dev If the protocol has made a loss and managed to make some profits to recover for this loss (through\n /// a program like Olympus Pro), then this function needs to be called\n /// @dev `badDebt` is simply reduced here by burning stablecoins\n /// @dev It is impossible to burn more than the `badDebt` otherwise this function could be used to manipulate\n /// the `surplusBuffer` and hence the amount going to governance\n function updateBadDebt(uint256 amount) external returns (uint256 badDebtValue) {\n stablecoin.burnSelf(amount, address(this));\n badDebtValue = badDebt - amount;\n badDebt = badDebtValue;\n emit BadDebtUpdated(badDebtValue);\n }\n\n // ========================= INTERNAL UTILITY FUNCTIONS ========================\n\n /// @notice Internal version of the `fetchSurplusFromAll` function\n function _fetchSurplusFromAll() internal returns (uint256 surplusBufferValue, uint256 badDebtValue) {\n (surplusBufferValue, badDebtValue) = _fetchSurplusFromList(vaultManagerList);\n // It will fail anyway if the `flashLoanModule` is the zero address\n if (address(flashLoanModule) != address(0))\n surplusBufferValue += flashLoanModule.accrueInterestToTreasury(stablecoin);\n (surplusBufferValue, badDebtValue) = _updateSurplusAndBadDebt(surplusBufferValue, badDebtValue);\n }\n\n /// @notice Fetches the surplus from a list of `VaultManager` addresses without modifying the\n /// `surplusBuffer` and `badDebtValue`\n /// @return surplusBufferValue Value the `surplusBuffer` should have after the call if it was updated\n /// @return badDebtValue Value the `badDebt` should have after the call if it was updated\n /// @dev This internal function is never to be called alone, and should always be called in conjunction\n /// with the `_updateSurplusAndBadDebt` function\n function _fetchSurplusFromList(\n address[] memory vaultManagers\n ) internal returns (uint256 surplusBufferValue, uint256 badDebtValue) {\n badDebtValue = badDebt;\n surplusBufferValue = surplusBuffer;\n uint256 newSurplus;\n uint256 newBadDebt;\n uint256 vaultManagersLength = vaultManagers.length;\n for (uint256 i; i < vaultManagersLength; ++i) {\n (newSurplus, newBadDebt) = IVaultManager(vaultManagers[i]).accrueInterestToTreasury();\n surplusBufferValue += newSurplus;\n badDebtValue += newBadDebt;\n }\n }\n\n /// @notice Updates the `surplusBuffer` and the `badDebt` from updated values after calling the flash loan module\n /// and/or a list of `VaultManager` contracts\n /// @param surplusBufferValue Value of the surplus buffer after the calls to the different modules\n /// @param badDebtValue Value of the bad debt after the calls to the different modules\n /// @return Value of the `surplusBuffer` corrected from the `badDebt`\n /// @return Value of the `badDebt` corrected from the `surplusBuffer` and from the surplus the treasury had accumulated\n /// previously\n /// @dev When calling this function, it is possible that there is a positive `surplusBufferValue` and `badDebtValue`,\n /// this function tries to reconcile both values and makes sure that we either have surplus or bad debt but not both\n /// at the same time\n function _updateSurplusAndBadDebt(\n uint256 surplusBufferValue,\n uint256 badDebtValue\n ) internal returns (uint256, uint256) {\n if (badDebtValue != 0) {\n // If we have bad debt we need to burn stablecoins that accrued to the protocol\n // We still need to make sure that we're not burning too much or as much as we can if the debt is big\n uint256 balance = stablecoin.balanceOf(address(this));\n // We are going to burn `min(balance, badDebtValue)`\n uint256 toBurn = balance <= badDebtValue ? balance : badDebtValue;\n stablecoin.burnSelf(toBurn, address(this));\n // If we burned more than `surplusBuffer`, we set surplus to 0. It means we had to tap into Treasury reserve\n surplusBufferValue = toBurn >= surplusBufferValue ? 0 : surplusBufferValue - toBurn;\n badDebtValue -= toBurn;\n // Note here that the stablecoin balance is necessarily greater than the surplus buffer, and so if\n // `surplusBuffer >= toBurn`, then `badDebtValue = toBurn`\n }\n surplusBuffer = surplusBufferValue;\n badDebt = badDebtValue;\n emit SurplusBufferUpdated(surplusBufferValue);\n emit BadDebtUpdated(badDebtValue);\n return (surplusBufferValue, badDebtValue);\n }\n\n /// @notice Adds a new `VaultManager`\n /// @param vaultManager `VaultManager` contract to add\n /// @dev This contract should have already been initialized with a correct treasury address\n /// @dev It's this function that gives the minter right to the `VaultManager`\n function _addVaultManager(address vaultManager) internal virtual {\n if (vaultManagerMap[vaultManager] == 1) revert AlreadyVaultManager();\n if (address(IVaultManager(vaultManager).treasury()) != address(this)) revert InvalidTreasury();\n vaultManagerMap[vaultManager] = 1;\n vaultManagerList.push(vaultManager);\n emit VaultManagerToggled(vaultManager);\n stablecoin.addMinter(vaultManager);\n }\n\n // ============================= GOVERNOR FUNCTIONS ============================\n\n /// @notice Adds a new minter for the stablecoin\n /// @param minter Minter address to add\n function addMinter(address minter) external virtual onlyGovernor {\n if (minter == address(0)) revert ZeroAddress();\n stablecoin.addMinter(minter);\n }\n\n /// @notice External wrapper for `_addVaultManager`\n function addVaultManager(address vaultManager) external virtual onlyGovernor {\n _addVaultManager(vaultManager);\n }\n\n /// @notice Removes a minter from the stablecoin contract\n /// @param minter Minter address to remove\n function removeMinter(address minter) external virtual onlyGovernor {\n // To remove the minter role to a `VaultManager` you have to go through the `removeVaultManager` function\n if (vaultManagerMap[minter] == 1) revert InvalidAddress();\n stablecoin.removeMinter(minter);\n }\n\n /// @notice Removes a `VaultManager`\n /// @param vaultManager `VaultManager` contract to remove\n /// @dev A removed `VaultManager` loses its minter right on the stablecoin\n function removeVaultManager(address vaultManager) external onlyGovernor {\n if (vaultManagerMap[vaultManager] != 1) revert NotVaultManager();\n delete vaultManagerMap[vaultManager];\n // deletion from `vaultManagerList` loop\n uint256 vaultManagerListLength = vaultManagerList.length;\n for (uint256 i; i < vaultManagerListLength - 1; ++i) {\n if (vaultManagerList[i] == vaultManager) {\n // replace the `VaultManager` to remove with the last of the list\n vaultManagerList[i] = vaultManagerList[vaultManagerListLength - 1];\n break;\n }\n }\n // remove last element in array\n vaultManagerList.pop();\n emit VaultManagerToggled(vaultManager);\n stablecoin.removeMinter(vaultManager);\n }\n\n /// @notice Allows to recover any ERC20 token, including the stablecoin handled by this contract, and to send it\n /// to a contract\n /// @param tokenAddress Address of the token to recover\n /// @param to Address of the contract to send collateral to\n /// @param amountToRecover Amount of collateral to transfer\n /// @dev It is impossible to recover the stablecoin of the protocol if there is some bad debt for it\n /// @dev In this case, the function makes sure to fetch the surplus/bad debt from all the `VaultManager` contracts\n /// and from the flash loan module\n /// @dev If the token to recover is the stablecoin, tokens recovered are fetched\n /// from the surplus and not from the `surplusBuffer`\n function recoverERC20(address tokenAddress, address to, uint256 amountToRecover) external onlyGovernor {\n // Cannot recover stablecoin if badDebt or tap into the surplus buffer\n if (tokenAddress == address(stablecoin)) {\n _fetchSurplusFromAll();\n // If balance is non zero then this means, after the call to `fetchSurplusFromAll` that\n // bad debt is necessarily null\n uint256 balance = stablecoin.balanceOf(address(this));\n if (amountToRecover + surplusBuffer > balance) revert TooBigAmount();\n stablecoin.transfer(to, amountToRecover);\n } else {\n IERC20(tokenAddress).safeTransfer(to, amountToRecover);\n }\n emit Recovered(tokenAddress, to, amountToRecover);\n }\n\n /// @notice Changes the treasury contract and communicates this change to all `VaultManager` contract\n /// @param _treasury New treasury address for this stablecoin\n /// @dev This function is basically a way to remove rights to this contract and grant them to a new one\n /// @dev It could be used to set a new core contract\n function setTreasury(address _treasury) external virtual onlyGovernor {\n if (ITreasury(_treasury).stablecoin() != stablecoin) revert InvalidTreasury();\n // Flash loan role should be removed before calling this function\n if (core.isFlashLoanerTreasury(address(this))) revert RightsNotRemoved();\n emit NewTreasurySet(_treasury);\n uint256 vaultManagerListLength = vaultManagerList.length;\n for (uint256 i; i < vaultManagerListLength; ++i) {\n IVaultManager(vaultManagerList[i]).setTreasury(_treasury);\n }\n // A `TreasuryUpdated` event is triggered in the stablecoin\n stablecoin.setTreasury(_treasury);\n }\n\n /// @notice Sets the `surplusForGovernance` parameter\n /// @param _surplusForGovernance New value of the parameter\n /// @dev To pause surplus distribution, governance needs to set a zero value for `surplusForGovernance`\n /// which means\n function setSurplusForGovernance(uint64 _surplusForGovernance) external onlyGovernor {\n if (_surplusForGovernance > BASE_9) revert TooHighParameterValue();\n surplusForGovernance = _surplusForGovernance;\n emit SurplusForGovernanceUpdated(_surplusForGovernance);\n }\n\n /// @notice Sets the `surplusManager` contract responsible for handling the surplus of the\n /// protocol\n /// @param _surplusManager New address responsible for handling the surplus\n function setSurplusManager(address _surplusManager) external onlyGovernor {\n if (_surplusManager == address(0)) revert ZeroAddress();\n surplusManager = _surplusManager;\n emit SurplusManagerUpdated(_surplusManager);\n }\n\n /// @notice Sets a new `core` contract\n /// @dev This function should typically be called on all treasury contracts after the `setCore`\n /// function has been called on the `CoreBorrow` contract\n /// @dev One sanity check that can be performed here is to verify whether at least the governor\n /// calling the contract is still a governor in the new core\n function setCore(ICoreBorrow _core) external onlyGovernor {\n if (!_core.isGovernor(msg.sender)) revert NotGovernor();\n core = ICoreBorrow(_core);\n emit CoreUpdated(address(_core));\n }\n\n /// @inheritdoc ITreasury\n function setFlashLoanModule(address _flashLoanModule) external {\n if (msg.sender != address(core)) revert NotCore();\n address oldFlashLoanModule = address(flashLoanModule);\n flashLoanModule = IFlashAngle(_flashLoanModule);\n if (oldFlashLoanModule != address(0)) {\n stablecoin.removeMinter(oldFlashLoanModule);\n }\n // We may want to cancel the module\n if (_flashLoanModule != address(0)) {\n stablecoin.addMinter(_flashLoanModule);\n }\n }\n}\n" + }, + "contracts/ui-helpers/AngleBorrowHelpers.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\n/*\n * █ \n ***** ▓▓▓ \n * ▓▓▓▓▓▓▓ \n * ///. ▓▓▓▓▓▓▓▓▓▓▓▓▓ \n ***** //////// ▓▓▓▓▓▓▓ \n * ///////////// ▓▓▓ \n ▓▓ ////////////////// █ ▓▓ \n ▓▓ ▓▓ /////////////////////// ▓▓ ▓▓ \n ▓▓ ▓▓ //////////////////////////// ▓▓ ▓▓ \n ▓▓ ▓▓ /////////▓▓▓///////▓▓▓///////// ▓▓ ▓▓ \n ▓▓ ,////////////////////////////////////// ▓▓ ▓▓ \n ▓▓ ////////////////////////////////////////// ▓▓ \n ▓▓ //////////////////////▓▓▓▓///////////////////// \n ,//////////////////////////////////////////////////// \n .////////////////////////////////////////////////////////// \n .//////////////////////////██.,//////////////////////////█ \n .//////////////////////████..,./////////////////////██ \n ...////////////////███████.....,.////////////////███ \n ,.,////////////████████ ........,///////////████ \n .,.,//////█████████ ,.......///////████ \n ,..//████████ ........./████ \n ..,██████ .....,███ \n .██ ,.,█ \n \n \n \n ▓▓ ▓▓▓▓▓▓▓▓▓▓ ▓▓▓▓▓▓▓▓▓▓ ▓▓ ▓▓▓▓▓▓▓▓▓▓ \n ▓▓▓▓▓▓ ▓▓▓ ▓▓▓ ▓▓▓ ▓▓ ▓▓ ▓▓▓▓ \n ▓▓▓ ▓▓▓ ▓▓▓ ▓▓▓ ▓▓▓ ▓▓▓ ▓▓ ▓▓▓▓▓ \n ▓▓▓ ▓▓ ▓▓▓ ▓▓▓ ▓▓▓▓▓▓▓▓▓▓ ▓▓▓▓▓▓▓▓▓▓ ▓▓▓▓▓▓▓▓▓▓ \n*/\n\nimport \"@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol\";\nimport \"../interfaces/IVaultManager.sol\";\n\npragma solidity ^0.8.12;\n\n/// @title AngleBorrowHelpers\n/// @author Angle Labs, Inc.\n/// @notice Contract with view functions designed to facilitate integrations on the Borrow module of the Angle Protocol\n/// @dev This contract only contains view functions to be queried off-chain. It was thus not optimized for gas consumption\ncontract AngleBorrowHelpers is Initializable {\n /// @notice Returns all the vaults owned or controlled (under the form of approval) by an address\n /// @param vaultManager VaultManager address to query vaultIDs on\n /// @param spender Address for which vault ownerships should be checked\n /// @return List of `vaultID` controlled by this address\n /// @return Count of vaults owned by the address\n /// @dev This function is never to be called on-chain since it iterates over all vaultIDs. It is here\n /// to reduce dependency on an external graph to link an ID to its owner\n function getControlledVaults(\n IVaultManager vaultManager,\n address spender\n ) external view returns (uint256[] memory, uint256) {\n uint256 arraySize = vaultManager.vaultIDCount();\n uint256[] memory vaultsControlled = new uint256[](arraySize);\n uint256 count;\n for (uint256 i = 1; i <= arraySize; ++i) {\n try vaultManager.isApprovedOrOwner(spender, i) returns (bool _isApprovedOrOwner) {\n if (_isApprovedOrOwner) {\n vaultsControlled[count] = i;\n count += 1;\n }\n } catch {\n continue;\n } // This happens if nobody owns the vaultID=i (if there has been a burn)\n }\n return (vaultsControlled, count);\n }\n\n /// @custom:oz-upgrades-unsafe-allow constructor\n constructor() initializer {}\n}\n" + }, + "contracts/ui-helpers/AngleHelpers.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\nimport \"../interfaces/IAngleRouter.sol\";\nimport \"../interfaces/coreModule/IAgTokenMainnet.sol\";\nimport \"../interfaces/coreModule/ICore.sol\";\nimport \"../interfaces/coreModule/IOracleCore.sol\";\nimport \"../interfaces/coreModule/IPerpetualManager.sol\";\nimport \"../interfaces/coreModule/IPoolManager.sol\";\nimport \"../interfaces/coreModule/IStableMaster.sol\";\nimport \"./AngleBorrowHelpers.sol\";\n\npragma solidity ^0.8.12;\n\nstruct Parameters {\n SLPData slpData;\n MintBurnData feeData;\n PerpetualManagerFeeData perpFeeData;\n PerpetualManagerParamData perpParam;\n}\n\nstruct PerpetualManagerFeeData {\n uint64[] xHAFeesDeposit;\n uint64[] yHAFeesDeposit;\n uint64[] xHAFeesWithdraw;\n uint64[] yHAFeesWithdraw;\n uint64 haBonusMalusDeposit;\n uint64 haBonusMalusWithdraw;\n}\n\nstruct PerpetualManagerParamData {\n uint64 maintenanceMargin;\n uint64 maxLeverage;\n uint64 targetHAHedge;\n uint64 limitHAHedge;\n uint64 lockTime;\n}\n\nstruct CollateralAddresses {\n address stableMaster;\n address poolManager;\n address perpetualManager;\n address sanToken;\n address oracle;\n address gauge;\n address feeManager;\n address[] strategies;\n}\n\n/// @title AngleHelpers\n/// @author Angle Labs, Inc.\n/// @notice Contract with view functions designed to facilitate integrations on the Core and Borrow module of the Angle Protocol\n/// @dev This contract only contains view functions to be queried off-chain. It was thus not optimized for gas consumption\ncontract AngleHelpers is AngleBorrowHelpers {\n // =========================== HELPER VIEW FUNCTIONS ===========================\n\n /// @notice Gives the amount of `agToken` you'd be getting if you were executing in the same block a mint transaction\n /// with `amount` of `collateral` in the Core module of the Angle protocol as well as the value of the fees\n /// (in `BASE_PARAMS`) that would be applied during the mint\n /// @return Amount of `agToken` that would be obtained with a mint transaction in the same block\n /// @return Percentage of fees that would be taken during a mint transaction in the same block\n /// @dev This function reverts if the mint transaction was to revert in the same conditions (without taking into account\n /// potential approval problems to the `StableMaster` contract)\n function previewMintAndFees(\n uint256 amount,\n address agToken,\n address collateral\n ) external view returns (uint256, uint256) {\n return _previewMintAndFees(amount, agToken, collateral);\n }\n\n /// @notice Gives the amount of `collateral` you'd be getting if you were executing in the same block a burn transaction\n /// with `amount` of `agToken` in the Core module of the Angle protocol as well as the value of the fees\n /// (in `BASE_PARAMS`) that would be applied during the burn\n /// @return Amount of `collateral` that would be obtained with a burn transaction in the same block\n /// @return Percentage of fees that would be taken during a burn transaction in the same block\n /// @dev This function reverts if the burn transaction was to revert in the same conditions (without taking into account\n /// potential approval problems to the `StableMaster` contract or agToken balance prior to the call)\n function previewBurnAndFees(\n uint256 amount,\n address agToken,\n address collateral\n ) external view returns (uint256, uint256) {\n return _previewBurnAndFees(amount, agToken, collateral);\n }\n\n /// @notice Returns all the addresses associated to the (`agToken`,`collateral`) pair given\n /// @return addresses A struct with all the addresses associated in the Core module\n function getCollateralAddresses(\n address agToken,\n address collateral\n ) external view returns (CollateralAddresses memory addresses) {\n address stableMaster = IAgTokenMainnet(agToken).stableMaster();\n (address poolManager, address perpetualManager, address sanToken, address gauge) = ROUTER.mapPoolManagers(\n stableMaster,\n collateral\n );\n (, , , IOracleCore oracle, , , , , ) = IStableMaster(stableMaster).collateralMap(poolManager);\n addresses.stableMaster = stableMaster;\n addresses.poolManager = poolManager;\n addresses.perpetualManager = perpetualManager;\n addresses.sanToken = sanToken;\n addresses.gauge = gauge;\n addresses.oracle = address(oracle);\n addresses.feeManager = IPoolManager(poolManager).feeManager();\n\n uint256 length;\n while (true) {\n try IPoolManager(poolManager).strategyList(length) returns (address) {\n length += 1;\n } catch {\n break;\n }\n }\n address[] memory strategies = new address[](length);\n for (uint256 i; i < length; ++i) {\n strategies[i] = IPoolManager(poolManager).strategyList(i);\n }\n addresses.strategies = strategies;\n }\n\n /// @notice Gets the addresses of all the `StableMaster` contracts and their associated `AgToken` addresses\n /// @return List of the `StableMaster` addresses of the Angle protocol\n /// @return List of the `AgToken` addresses of the protocol\n /// @dev The place of an agToken address in the list is the same as the corresponding `StableMaster` address\n function getStablecoinAddresses() external view returns (address[] memory, address[] memory) {\n address[] memory stableMasterAddresses = CORE.stablecoinList();\n address[] memory agTokenAddresses = new address[](stableMasterAddresses.length);\n for (uint256 i; i < stableMasterAddresses.length; ++i) {\n agTokenAddresses[i] = IStableMaster(stableMasterAddresses[i]).agToken();\n }\n return (stableMasterAddresses, agTokenAddresses);\n }\n\n /// @notice Returns most of the governance parameters associated to the (`agToken`,`collateral`) pair given\n /// @return params Struct with most of the parameters in the `StableMaster` and `PerpetualManager` contracts\n /// @dev Check out the struct `Parameters` for the meaning of the return values\n function getCollateralParameters(\n address agToken,\n address collateral\n ) external view returns (Parameters memory params) {\n (address stableMaster, address poolManager) = _getStableMasterAndPoolManager(agToken, collateral);\n (\n ,\n ,\n IPerpetualManager perpetualManager,\n ,\n ,\n ,\n ,\n SLPData memory slpData,\n MintBurnData memory feeData\n ) = IStableMaster(stableMaster).collateralMap(poolManager);\n\n params.slpData = slpData;\n params.feeData = feeData;\n params.perpParam.maintenanceMargin = perpetualManager.maintenanceMargin();\n params.perpParam.maxLeverage = perpetualManager.maxLeverage();\n params.perpParam.targetHAHedge = perpetualManager.targetHAHedge();\n params.perpParam.limitHAHedge = perpetualManager.limitHAHedge();\n params.perpParam.lockTime = perpetualManager.lockTime();\n\n params.perpFeeData.haBonusMalusDeposit = perpetualManager.haBonusMalusDeposit();\n params.perpFeeData.haBonusMalusWithdraw = perpetualManager.haBonusMalusWithdraw();\n\n uint256 length;\n while (true) {\n try perpetualManager.xHAFeesDeposit(length) returns (uint64) {\n length += 1;\n } catch {\n break;\n }\n }\n uint64[] memory data = new uint64[](length);\n uint64[] memory data2 = new uint64[](length);\n for (uint256 i; i < length; ++i) {\n data[i] = perpetualManager.xHAFeesDeposit(i);\n data2[i] = perpetualManager.yHAFeesDeposit(i);\n }\n params.perpFeeData.xHAFeesDeposit = data;\n params.perpFeeData.yHAFeesDeposit = data2;\n\n length = 0;\n while (true) {\n try perpetualManager.xHAFeesWithdraw(length) returns (uint64) {\n length += 1;\n } catch {\n break;\n }\n }\n data = new uint64[](length);\n data2 = new uint64[](length);\n for (uint256 i; i < length; ++i) {\n data[i] = perpetualManager.xHAFeesWithdraw(i);\n data2[i] = perpetualManager.yHAFeesWithdraw(i);\n }\n params.perpFeeData.xHAFeesWithdraw = data;\n params.perpFeeData.yHAFeesWithdraw = data2;\n }\n\n /// @notice Returns the address of the poolManager associated to an (`agToken`, `collateral`) pair\n /// in the Core module of the protocol\n function getPoolManager(address agToken, address collateral) public view returns (address poolManager) {\n (, poolManager) = _getStableMasterAndPoolManager(agToken, collateral);\n }\n\n // ============================= REPLICA FUNCTIONS =============================\n // These replicate what is done in the other contracts of the protocol\n\n function _previewBurnAndFees(\n uint256 amount,\n address agToken,\n address collateral\n ) internal view returns (uint256 amountForUserInCollat, uint256 feePercent) {\n (address stableMaster, address poolManager) = _getStableMasterAndPoolManager(agToken, collateral);\n (\n address token,\n ,\n IPerpetualManager perpetualManager,\n IOracleCore oracle,\n uint256 stocksUsers,\n ,\n uint256 collatBase,\n ,\n MintBurnData memory feeData\n ) = IStableMaster(stableMaster).collateralMap(poolManager);\n if (token == address(0) || IStableMaster(stableMaster).paused(keccak256(abi.encodePacked(STABLE, poolManager))))\n revert NotInitialized();\n if (amount > stocksUsers) revert InvalidAmount();\n\n if (feeData.xFeeBurn.length == 1) {\n feePercent = feeData.yFeeBurn[0];\n } else {\n bytes memory data = abi.encode(address(perpetualManager), feeData.targetHAHedge);\n uint64 hedgeRatio = _computeHedgeRatio(stocksUsers - amount, data);\n feePercent = _piecewiseLinear(hedgeRatio, feeData.xFeeBurn, feeData.yFeeBurn);\n }\n feePercent = (feePercent * feeData.bonusMalusBurn) / BASE_PARAMS;\n\n amountForUserInCollat = (amount * (BASE_PARAMS - feePercent) * collatBase) / (oracle.readUpper() * BASE_PARAMS);\n }\n\n function _previewMintAndFees(\n uint256 amount,\n address agToken,\n address collateral\n ) internal view returns (uint256 amountForUserInStable, uint256 feePercent) {\n (address stableMaster, address poolManager) = _getStableMasterAndPoolManager(agToken, collateral);\n (\n address token,\n ,\n IPerpetualManager perpetualManager,\n IOracleCore oracle,\n uint256 stocksUsers,\n ,\n ,\n ,\n MintBurnData memory feeData\n ) = IStableMaster(stableMaster).collateralMap(poolManager);\n if (token == address(0) || IStableMaster(stableMaster).paused(keccak256(abi.encodePacked(STABLE, poolManager))))\n revert NotInitialized();\n\n amountForUserInStable = oracle.readQuoteLower(amount);\n\n if (feeData.xFeeMint.length == 1) feePercent = feeData.yFeeMint[0];\n else {\n bytes memory data = abi.encode(address(perpetualManager), feeData.targetHAHedge);\n uint64 hedgeRatio = _computeHedgeRatio(amountForUserInStable + stocksUsers, data);\n feePercent = _piecewiseLinear(hedgeRatio, feeData.xFeeMint, feeData.yFeeMint);\n }\n feePercent = (feePercent * feeData.bonusMalusMint) / BASE_PARAMS;\n\n amountForUserInStable = (amountForUserInStable * (BASE_PARAMS - feePercent)) / BASE_PARAMS;\n if (stocksUsers + amountForUserInStable > feeData.capOnStableMinted) revert InvalidAmount();\n }\n\n // ============================= UTILITY FUNCTIONS =============================\n // These utility functions are taken from other contracts of the protocol\n\n function _computeHedgeRatio(uint256 newStocksUsers, bytes memory data) internal view returns (uint64 ratio) {\n (address perpetualManager, uint64 targetHAHedge) = abi.decode(data, (address, uint64));\n uint256 totalHedgeAmount = IPerpetualManager(perpetualManager).totalHedgeAmount();\n newStocksUsers = (targetHAHedge * newStocksUsers) / BASE_PARAMS;\n if (newStocksUsers > totalHedgeAmount) ratio = uint64((totalHedgeAmount * BASE_PARAMS) / newStocksUsers);\n else ratio = uint64(BASE_PARAMS);\n }\n\n function _piecewiseLinear(uint64 x, uint64[] memory xArray, uint64[] memory yArray) internal pure returns (uint64) {\n if (x >= xArray[xArray.length - 1]) {\n return yArray[xArray.length - 1];\n } else if (x <= xArray[0]) {\n return yArray[0];\n } else {\n uint256 lower;\n uint256 upper = xArray.length - 1;\n uint256 mid;\n while (upper - lower > 1) {\n mid = lower + (upper - lower) / 2;\n if (xArray[mid] <= x) {\n lower = mid;\n } else {\n upper = mid;\n }\n }\n if (yArray[upper] > yArray[lower]) {\n return\n yArray[lower] +\n ((yArray[upper] - yArray[lower]) * (x - xArray[lower])) /\n (xArray[upper] - xArray[lower]);\n } else {\n return\n yArray[lower] -\n ((yArray[lower] - yArray[upper]) * (x - xArray[lower])) /\n (xArray[upper] - xArray[lower]);\n }\n }\n }\n\n function _getStableMasterAndPoolManager(\n address agToken,\n address collateral\n ) internal view returns (address stableMaster, address poolManager) {\n stableMaster = IAgTokenMainnet(agToken).stableMaster();\n (poolManager, , , ) = ROUTER.mapPoolManagers(stableMaster, collateral);\n }\n\n // ========================= CONSTANTS AND INITIALIZERS ========================\n\n IAngleRouter public constant ROUTER = IAngleRouter(0xBB755240596530be0c1DE5DFD77ec6398471561d);\n ICore public constant CORE = ICore(0x61ed74de9Ca5796cF2F8fD60D54160D47E30B7c3);\n\n bytes32 public constant STABLE = keccak256(\"STABLE\");\n uint256 public constant BASE_PARAMS = 10 ** 9;\n\n error NotInitialized();\n error InvalidAmount();\n}\n" + }, + "contracts/utils/Constants.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\nerror InsufficientAssets();\n\n/// @title Constants\n/// @author Angle Labs, Inc.\n/// @notice Constants and errors for Angle Protocol contracts\ncontract Constants {\n uint256 internal constant _BASE_9 = 1e9;\n uint256 internal constant _BASE_18 = 1e18;\n uint256 internal constant _BASE_27 = 1e27;\n uint256 internal constant _BASE_36 = 1e36;\n}\n" + }, + "contracts/vaultManager/VaultManagerERC721.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\nimport \"./VaultManagerStorage.sol\";\n\n/// @title VaultManagerERC721\n/// @author Angle Labs, Inc.\n/// @dev Base ERC721 Implementation of VaultManager\nabstract contract VaultManagerERC721 is IERC721MetadataUpgradeable, VaultManagerStorage {\n using SafeERC20 for IERC20;\n using Address for address;\n\n /// @inheritdoc IERC721MetadataUpgradeable\n string public name;\n /// @inheritdoc IERC721MetadataUpgradeable\n string public symbol;\n\n // ================================= MODIFIERS =================================\n\n /// @notice Checks if the person interacting with the vault with `vaultID` is approved\n /// @param caller Address of the person seeking to interact with the vault\n /// @param vaultID ID of the concerned vault\n modifier onlyApprovedOrOwner(address caller, uint256 vaultID) {\n if (!_isApprovedOrOwner(caller, vaultID)) revert NotApproved();\n _;\n }\n\n // ================================ ERC721 LOGIC ===============================\n\n /// @notice Checks whether a given address is approved for a vault or owns this vault\n /// @param spender Address for which vault ownership should be checked\n /// @param vaultID ID of the vault to check\n /// @return Whether the `spender` address owns or is approved for `vaultID`\n function isApprovedOrOwner(address spender, uint256 vaultID) external view returns (bool) {\n return _isApprovedOrOwner(spender, vaultID);\n }\n\n /// @inheritdoc IERC721MetadataUpgradeable\n function tokenURI(uint256 vaultID) external view returns (string memory) {\n if (!_exists(vaultID)) revert NonexistentVault();\n // There is no vault with `vaultID` equal to 0, so the following variable is\n // always greater than zero\n uint256 temp = vaultID;\n uint256 digits;\n while (temp != 0) {\n ++digits;\n temp /= 10;\n }\n bytes memory buffer = new bytes(digits);\n while (vaultID != 0) {\n digits -= 1;\n buffer[digits] = bytes1(uint8(48 + uint256(vaultID % 10)));\n vaultID /= 10;\n }\n return bytes(_baseURI).length != 0 ? string(abi.encodePacked(_baseURI, string(buffer))) : \"\";\n }\n\n /// @inheritdoc IERC721Upgradeable\n function balanceOf(address owner) external view returns (uint256) {\n if (owner == address(0)) revert ZeroAddress();\n return _balances[owner];\n }\n\n /// @inheritdoc IERC721Upgradeable\n function ownerOf(uint256 vaultID) external view returns (address) {\n return _ownerOf(vaultID);\n }\n\n /// @inheritdoc IERC721Upgradeable\n function approve(address to, uint256 vaultID) external {\n address owner = _ownerOf(vaultID);\n if (to == owner) revert ApprovalToOwner();\n if (msg.sender != owner && !isApprovedForAll(owner, msg.sender)) revert NotApproved();\n\n _approve(to, vaultID);\n }\n\n /// @inheritdoc IERC721Upgradeable\n function getApproved(uint256 vaultID) external view returns (address) {\n if (!_exists(vaultID)) revert NonexistentVault();\n return _getApproved(vaultID);\n }\n\n /// @inheritdoc IERC721Upgradeable\n function setApprovalForAll(address operator, bool approved) external {\n _setApprovalForAll(msg.sender, operator, approved);\n }\n\n /// @inheritdoc IERC721Upgradeable\n function isApprovedForAll(address owner, address operator) public view returns (bool) {\n return _operatorApprovals[owner][operator] == 1;\n }\n\n /// @inheritdoc IERC721Upgradeable\n function transferFrom(address from, address to, uint256 vaultID) external onlyApprovedOrOwner(msg.sender, vaultID) {\n _transfer(from, to, vaultID);\n }\n\n /// @inheritdoc IERC721Upgradeable\n function safeTransferFrom(address from, address to, uint256 vaultID) external {\n safeTransferFrom(from, to, vaultID, \"\");\n }\n\n /// @inheritdoc IERC721Upgradeable\n function safeTransferFrom(\n address from,\n address to,\n uint256 vaultID,\n bytes memory _data\n ) public onlyApprovedOrOwner(msg.sender, vaultID) {\n _safeTransfer(from, to, vaultID, _data);\n }\n\n // ================================ ERC165 LOGIC ===============================\n\n /// @inheritdoc IERC165Upgradeable\n function supportsInterface(bytes4 interfaceId) external pure returns (bool) {\n return\n interfaceId == type(IERC721MetadataUpgradeable).interfaceId ||\n interfaceId == type(IERC721Upgradeable).interfaceId ||\n interfaceId == type(IVaultManager).interfaceId ||\n interfaceId == type(IERC165Upgradeable).interfaceId;\n }\n\n // ================== INTERNAL FUNCTIONS FOR THE ERC721 LOGIC ==================\n\n /// @notice Internal version of the `ownerOf` function\n function _ownerOf(uint256 vaultID) internal view returns (address owner) {\n owner = _owners[vaultID];\n if (owner == address(0)) revert NonexistentVault();\n }\n\n /// @notice Internal version of the `getApproved` function\n function _getApproved(uint256 vaultID) internal view returns (address) {\n return _vaultApprovals[vaultID];\n }\n\n /// @notice Internal version of the `safeTransferFrom` function (with the data parameter)\n function _safeTransfer(address from, address to, uint256 vaultID, bytes memory _data) internal {\n _transfer(from, to, vaultID);\n if (!_checkOnERC721Received(from, to, vaultID, _data)) revert NonERC721Receiver();\n }\n\n /// @notice Checks whether a vault exists\n /// @param vaultID ID of the vault to check\n /// @return Whether `vaultID` has been created\n function _exists(uint256 vaultID) internal view returns (bool) {\n return _owners[vaultID] != address(0);\n }\n\n /// @notice Internal version of the `isApprovedOrOwner` function\n function _isApprovedOrOwner(address spender, uint256 vaultID) internal view returns (bool) {\n // The following checks if the vault exists\n address owner = _ownerOf(vaultID);\n return (spender == owner || _getApproved(vaultID) == spender || _operatorApprovals[owner][spender] == 1);\n }\n\n /// @notice Internal version of the `createVault` function\n /// Mints `vaultID` and transfers it to `to`\n /// @dev This method is equivalent to the `_safeMint` method used in OpenZeppelin ERC721 contract\n /// @dev Emits a {Transfer} event\n function _mint(address to) internal returns (uint256 vaultID) {\n if (to == address(0)) revert ZeroAddress();\n\n unchecked {\n vaultIDCount += 1;\n }\n\n vaultID = vaultIDCount;\n _beforeTokenTransfer(address(0), to, vaultID);\n\n unchecked {\n _balances[to] += 1;\n }\n\n _owners[vaultID] = to;\n emit Transfer(address(0), to, vaultID);\n if (!_checkOnERC721Received(address(0), to, vaultID, \"\")) revert NonERC721Receiver();\n }\n\n /// @notice Destroys `vaultID`\n /// @dev `vaultID` must exist\n /// @dev Emits a {Transfer} event\n function _burn(uint256 vaultID) internal {\n address owner = _ownerOf(vaultID);\n\n _beforeTokenTransfer(owner, address(0), vaultID);\n // Clear approvals\n _approve(address(0), vaultID);\n // The following line cannot underflow as the owner's balance is necessarily\n // greater than 1\n unchecked {\n _balances[owner] -= 1;\n }\n delete _owners[vaultID];\n delete vaultData[vaultID];\n\n emit Transfer(owner, address(0), vaultID);\n }\n\n /// @notice Transfers `vaultID` from `from` to `to` as opposed to {transferFrom},\n /// this imposes no restrictions on msg.sender\n /// @dev `to` cannot be the zero address and `perpetualID` must be owned by `from`\n /// @dev Emits a {Transfer} event\n function _transfer(address from, address to, uint256 vaultID) internal {\n if (_ownerOf(vaultID) != from) revert NotApproved();\n if (to == address(0)) revert ZeroAddress();\n\n _beforeTokenTransfer(from, to, vaultID);\n\n // Clear approvals from the previous owner\n _approve(address(0), vaultID);\n unchecked {\n _balances[from] -= 1;\n _balances[to] += 1;\n }\n _owners[vaultID] = to;\n\n emit Transfer(from, to, vaultID);\n }\n\n /// @notice Approves `to` to operate on `vaultID`\n function _approve(address to, uint256 vaultID) internal {\n _vaultApprovals[vaultID] = to;\n emit Approval(_ownerOf(vaultID), to, vaultID);\n }\n\n /// @notice Internal version of the `setApprovalForAll` function\n /// @dev It contains an `approver` field to be used in case someone signs a permit for a particular\n /// address, and this signature is given to the contract by another address (like a router)\n function _setApprovalForAll(address approver, address operator, bool approved) internal {\n if (operator == approver) revert ApprovalToCaller();\n uint256 approval = approved ? 1 : 0;\n _operatorApprovals[approver][operator] = approval;\n emit ApprovalForAll(approver, operator, approved);\n }\n\n /// @notice Internal function to invoke {IERC721Receiver-onERC721Received} on a target address\n /// The call is not executed if the target address is not a contract\n /// @param from Address representing the previous owner of the given token ID\n /// @param to Target address that will receive the tokens\n /// @param vaultID ID of the token to be transferred\n /// @param _data Bytes optional data to send along with the call\n /// @return Bool whether the call correctly returned the expected value\n function _checkOnERC721Received(\n address from,\n address to,\n uint256 vaultID,\n bytes memory _data\n ) private returns (bool) {\n if (to.isContract()) {\n try IERC721ReceiverUpgradeable(to).onERC721Received(msg.sender, from, vaultID, _data) returns (\n bytes4 retval\n ) {\n return retval == IERC721ReceiverUpgradeable.onERC721Received.selector;\n } catch (bytes memory reason) {\n if (reason.length == 0) {\n revert NonERC721Receiver();\n } else {\n // solhint-disable-next-line no-inline-assembly\n assembly {\n revert(add(32, reason), mload(reason))\n }\n }\n }\n } else {\n return true;\n }\n }\n\n /// @notice Hook that is called before any token transfer. This includes minting and burning.\n /// Calling conditions:\n ///\n /// - When `from` and `to` are both non-zero, `from`'s `vaultID` will be\n /// transferred to `to`.\n /// - When `from` is zero, `vaultID` will be minted for `to`.\n /// - When `to` is zero, `from`'s `vaultID` will be burned.\n /// - `from` and `to` are never both zero.\n function _beforeTokenTransfer(address from, address to, uint256 vaultID) internal virtual {}\n\n /// @notice Get `whitelistingActivated` in storage only if needed\n function _whitelistingActivated() internal view virtual returns (bool) {\n return whitelistingActivated;\n }\n}\n" + }, + "contracts/vaultManager/VaultManagerPermit.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\nimport \"./VaultManagerERC721.sol\";\nimport \"../interfaces/external/IERC1271.sol\";\n\n/// @title VaultManagerPermit\n/// @author Angle Labs, Inc.\n/// @dev Base Implementation of permit functions for the `VaultManager` contract\nabstract contract VaultManagerPermit is Initializable, VaultManagerERC721 {\n using Address for address;\n\n mapping(address => uint256) private _nonces;\n /* solhint-disable var-name-mixedcase */\n bytes32 private _HASHED_NAME;\n bytes32 private _HASHED_VERSION;\n bytes32 private _PERMIT_TYPEHASH;\n /* solhint-enable var-name-mixedcase */\n\n error ExpiredDeadline();\n error InvalidSignature();\n\n //solhint-disable-next-line\n function __ERC721Permit_init(string memory _name) internal onlyInitializing {\n _PERMIT_TYPEHASH = keccak256(\n \"Permit(address owner,address spender,bool approved,uint256 nonce,uint256 deadline)\"\n );\n _HASHED_NAME = keccak256(bytes(_name));\n _HASHED_VERSION = keccak256(bytes(\"1\"));\n }\n\n /// @notice Allows an address to give or revoke approval for all its vaults to another address\n /// @param owner Address signing the permit and giving (or revoking) its approval for all the controlled vaults\n /// @param spender Address to give approval to\n /// @param approved Whether to give or revoke the approval\n /// @param deadline Deadline parameter for the signature to be valid\n /// @dev The `v`, `r`, and `s` parameters are used as signature data\n function permit(\n address owner,\n address spender,\n bool approved,\n uint256 deadline,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) external {\n if (block.timestamp > deadline) revert ExpiredDeadline();\n // Additional signature checks performed in the `ECDSAUpgradeable.recover` function\n if (uint256(s) > 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D576E7357A4501DDFE92F46681B20A0 || (v != 27 && v != 28))\n revert InvalidSignature();\n\n bytes32 digest = keccak256(\n abi.encodePacked(\n \"\\x19\\x01\",\n _domainSeparatorV4(),\n keccak256(\n abi.encode(\n _PERMIT_TYPEHASH,\n // 0x3f43a9c6bafb5c7aab4e0cfe239dc5d4c15caf0381c6104188191f78a6640bd8,\n owner,\n spender,\n approved,\n _useNonce(owner),\n deadline\n )\n )\n )\n );\n if (owner.isContract()) {\n if (IERC1271(owner).isValidSignature(digest, abi.encodePacked(r, s, v)) != 0x1626ba7e)\n revert InvalidSignature();\n } else {\n address signer = ecrecover(digest, v, r, s);\n if (signer != owner || signer == address(0)) revert InvalidSignature();\n }\n\n _setApprovalForAll(owner, spender, approved);\n }\n\n /// @notice Returns the current nonce for an `owner` address\n function nonces(address owner) public view returns (uint256) {\n return _nonces[owner];\n }\n\n /// @notice Returns the domain separator for the current chain.\n // solhint-disable-next-line func-name-mixedcase\n function DOMAIN_SEPARATOR() external view returns (bytes32) {\n return _domainSeparatorV4();\n }\n\n /// @notice Internal version of the `DOMAIN_SEPARATOR` function\n function _domainSeparatorV4() internal view returns (bytes32) {\n return\n keccak256(\n abi.encode(\n // keccak256('EIP712Domain(string name,string version,uint256 chainId,address verifyingContract)')\n 0x8b73c3c69bb8fe3d512ecc4cf759cc79239f7b179b0ffacaa9a75d522b39400f,\n _HASHED_NAME,\n _HASHED_VERSION,\n block.chainid,\n address(this)\n )\n );\n }\n\n /// @notice Consumes a nonce for an address: returns the current value and increments it\n function _useNonce(address owner) internal returns (uint256 current) {\n current = _nonces[owner];\n _nonces[owner] = current + 1;\n }\n\n uint256[49] private __gap;\n}\n" + }, + "contracts/vaultManager/VaultManagerStorage.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\nimport \"@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/token/ERC20/extensions/draft-IERC20PermitUpgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/token/ERC721/IERC721ReceiverUpgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/interfaces/IERC721MetadataUpgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/utils/introspection/IERC165Upgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/utils/AddressUpgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/security/ReentrancyGuardUpgradeable.sol\";\nimport \"@openzeppelin/contracts/token/ERC20/extensions/IERC20Metadata.sol\";\nimport \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\nimport \"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\";\n\nimport \"../interfaces/IAgToken.sol\";\nimport \"../interfaces/IOracle.sol\";\nimport \"../interfaces/ISwapper.sol\";\nimport \"../interfaces/ITreasury.sol\";\nimport \"../interfaces/IVaultManager.sol\";\nimport \"../interfaces/governance/IVeBoostProxy.sol\";\n\n/// @title VaultManagerStorage\n/// @author Angle Labs, Inc.\n/// @dev Variables, references, parameters and events needed in the `VaultManager` contract\n// solhint-disable-next-line max-states-count\ncontract VaultManagerStorage is IVaultManagerStorage, Initializable, ReentrancyGuardUpgradeable {\n /// @notice Base used for parameter computation: almost all the parameters of this contract are set in `BASE_PARAMS`\n uint256 public constant BASE_PARAMS = 10 ** 9;\n /// @notice Base used for interest rate computation\n uint256 public constant BASE_INTEREST = 10 ** 27;\n /// @notice Used for interest rate computation\n uint256 public constant HALF_BASE_INTEREST = 10 ** 27 / 2;\n\n // ================================= REFERENCES ================================\n\n /// @inheritdoc IVaultManagerStorage\n ITreasury public treasury;\n /// @inheritdoc IVaultManagerStorage\n IERC20 public collateral;\n /// @inheritdoc IVaultManagerStorage\n IAgToken public stablecoin;\n /// @inheritdoc IVaultManagerStorage\n IOracle public oracle;\n /// @notice Reference to the contract which computes adjusted veANGLE balances for liquidators boosts\n IVeBoostProxy public veBoostProxy;\n /// @notice Base of the collateral\n uint256 internal _collatBase;\n\n // ================================= PARAMETERS ================================\n // Unless specified otherwise, parameters of this contract are expressed in `BASE_PARAMS`\n\n /// @notice Maximum amount of stablecoins that can be issued with this contract (in `BASE_TOKENS`). This parameter should\n /// not be bigger than `type(uint256).max / BASE_INTEREST` otherwise there may be some overflows in the `increaseDebt` function\n uint256 public debtCeiling;\n /// @notice Threshold veANGLE balance values for the computation of the boost for liquidators: the length of this array\n /// should normally be 2. The base of the x-values in this array should be `BASE_TOKENS`\n uint256[] public xLiquidationBoost;\n /// @notice Values of the liquidation boost at the threshold values of x\n uint256[] public yLiquidationBoost;\n /// @inheritdoc IVaultManagerStorage\n uint64 public collateralFactor;\n /// @notice Maximum Health factor at which a vault can end up after a liquidation (unless it's fully liquidated)\n uint64 public targetHealthFactor;\n /// @notice Upfront fee taken when borrowing stablecoins: this fee is optional and should in practice not be used\n uint64 public borrowFee;\n /// @notice Upfront fee taken when repaying stablecoins: this fee is optional as well. It should be smaller\n /// than the liquidation surcharge (cf below) to avoid exploits where people voluntarily get liquidated at a 0\n /// discount to pay smaller repaying fees\n uint64 public repayFee;\n /// @notice Per second interest taken to borrowers taking agToken loans. Contrarily to other parameters, it is set in `BASE_INTEREST`\n /// that is to say in base 10**27\n uint64 public interestRate;\n /// @notice Fee taken by the protocol during a liquidation. Technically, this value is not the fee per se, it's 1 - fee.\n /// For instance for a 2% fee, `liquidationSurcharge` should be 98%\n uint64 public liquidationSurcharge;\n /// @notice Maximum discount given to liquidators\n uint64 public maxLiquidationDiscount;\n /// @notice Whether whitelisting is required to own a vault or not\n bool public whitelistingActivated;\n /// @notice Whether the contract is paused or not\n bool public paused;\n\n // ================================= VARIABLES =================================\n\n /// @notice Timestamp at which the `interestAccumulator` was updated\n uint256 public lastInterestAccumulatorUpdated;\n /// @inheritdoc IVaultManagerStorage\n uint256 public interestAccumulator;\n /// @inheritdoc IVaultManagerStorage\n uint256 public totalNormalizedDebt;\n /// @notice Surplus accumulated by the contract: surplus is always in stablecoins, and is then reset\n /// when the value is communicated to the treasury contract\n uint256 public surplus;\n /// @notice Bad debt made from liquidated vaults which ended up having no collateral and a positive amount\n /// of stablecoins\n uint256 public badDebt;\n\n // ================================== MAPPINGS =================================\n\n /// @inheritdoc IVaultManagerStorage\n mapping(uint256 => Vault) public vaultData;\n /// @notice Maps an address to 1 if it's whitelisted and can open or own a vault\n mapping(address => uint256) public isWhitelisted;\n\n // ================================ ERC721 DATA ================================\n\n /// @inheritdoc IVaultManagerStorage\n uint256 public vaultIDCount;\n\n /// @notice URI\n string internal _baseURI;\n\n // Mapping from `vaultID` to owner address\n mapping(uint256 => address) internal _owners;\n\n // Mapping from owner address to vault owned count\n mapping(address => uint256) internal _balances;\n\n // Mapping from `vaultID` to approved address\n mapping(uint256 => address) internal _vaultApprovals;\n\n // Mapping from owner to operator approvals\n mapping(address => mapping(address => uint256)) internal _operatorApprovals;\n\n uint256[50] private __gap;\n\n // =================================== EVENTS ==================================\n\n event AccruedToTreasury(uint256 surplusEndValue, uint256 badDebtEndValue);\n event CollateralAmountUpdated(uint256 vaultID, uint256 collateralAmount, uint8 isIncrease);\n event InterestAccumulatorUpdated(uint256 value, uint256 timestamp);\n event InternalDebtUpdated(uint256 vaultID, uint256 internalAmount, uint8 isIncrease);\n event FiledUint64(uint64 param, bytes32 what);\n event DebtCeilingUpdated(uint256 debtCeiling);\n event LiquidationBoostParametersUpdated(address indexed _veBoostProxy, uint256[] xBoost, uint256[] yBoost);\n event LiquidatedVaults(uint256[] vaultIDs);\n event DebtTransferred(uint256 srcVaultID, uint256 dstVaultID, address dstVaultManager, uint256 amount);\n\n // =================================== ERRORS ==================================\n\n error ApprovalToOwner();\n error ApprovalToCaller();\n error DustyLeftoverAmount();\n error DebtCeilingExceeded();\n error HealthyVault();\n error IncompatibleLengths();\n error InsolventVault();\n error InvalidParameterValue();\n error InvalidParameterType();\n error InvalidSetOfParameters();\n error InvalidTreasury();\n error NonERC721Receiver();\n error NonexistentVault();\n error NotApproved();\n error NotGovernor();\n error NotGovernorOrGuardian();\n error NotTreasury();\n error NotWhitelisted();\n error NotVaultManager();\n error Paused();\n error TooHighParameterValue();\n error TooSmallParameterValue();\n error ZeroAddress();\n\n /// @custom:oz-upgrades-unsafe-allow constructor\n constructor() initializer {}\n}\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 1000000 + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers", + "metadata", + "devdoc", + "userdoc", + "storageLayout", + "evm.gasEstimates", + "devdoc", + "userdoc" + ], + "": [ + "ast" + ] + } + }, + "metadata": { + "useLiteralContent": true + } + } +} \ No newline at end of file diff --git a/deployments/base/AgTokenSideChainMultiBridge_Implementation.json b/deployments/base/AgTokenSideChainMultiBridge_Implementation.json index 58ecf00c..e03c0f73 100644 --- a/deployments/base/AgTokenSideChainMultiBridge_Implementation.json +++ b/deployments/base/AgTokenSideChainMultiBridge_Implementation.json @@ -1,5 +1,5 @@ { - "address": "0x5adDc89785D75C86aB939E9e15bfBBb7Fc086A87", + "address": "0x366CEE609A64037a4910868c5b3cd62b9D019695", "abi": [ { "inputs": [], @@ -1211,44 +1211,44 @@ "type": "function" } ], - "transactionHash": "0x25e3ea4b79da9f711305879e9ce0d815a5a84e42e87b2b482af017bca45cbdfb", + "transactionHash": "0x62588941a8108d8b4f245bdd1b14e3645df272719f9e5912b3ac65cd4d58005a", "receipt": { "to": null, "from": "0xfdA462548Ce04282f4B6D6619823a7C64Fdc0185", - "contractAddress": "0x5adDc89785D75C86aB939E9e15bfBBb7Fc086A87", - "transactionIndex": 4, - "gasUsed": "3970836", - "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000080000000000000000000000000000000000000000000000000000000000000000000000000080000000000000000000000000000000000000000000000400000008000000000000000000000000000000000000000000000000010000040000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", - "blockHash": "0xca6b02be69a57ca8f009a8ffb6a69879b2a2da18f97f4a07b59a52f95db25a2f", - "transactionHash": "0x25e3ea4b79da9f711305879e9ce0d815a5a84e42e87b2b482af017bca45cbdfb", + "contractAddress": "0x366CEE609A64037a4910868c5b3cd62b9D019695", + "transactionIndex": 8, + "gasUsed": "3964995", + "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000000000000000000080000000000000000000000000000000000000000000001400000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "blockHash": "0x8a86dfc13c9bd3ad445e97532223d127279aa152958da4527eeaff84e439efe5", + "transactionHash": "0x62588941a8108d8b4f245bdd1b14e3645df272719f9e5912b3ac65cd4d58005a", "logs": [ { - "transactionIndex": 4, - "blockNumber": 2190485, - "transactionHash": "0x25e3ea4b79da9f711305879e9ce0d815a5a84e42e87b2b482af017bca45cbdfb", - "address": "0x5adDc89785D75C86aB939E9e15bfBBb7Fc086A87", + "transactionIndex": 8, + "blockNumber": 9043234, + "transactionHash": "0x62588941a8108d8b4f245bdd1b14e3645df272719f9e5912b3ac65cd4d58005a", + "address": "0x366CEE609A64037a4910868c5b3cd62b9D019695", "topics": [ "0x7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb3847402498" ], "data": "0x0000000000000000000000000000000000000000000000000000000000000001", - "logIndex": 16, - "blockHash": "0xca6b02be69a57ca8f009a8ffb6a69879b2a2da18f97f4a07b59a52f95db25a2f" + "logIndex": 6, + "blockHash": "0x8a86dfc13c9bd3ad445e97532223d127279aa152958da4527eeaff84e439efe5" } ], - "blockNumber": 2190485, - "cumulativeGasUsed": "4378897", + "blockNumber": 9043234, + "cumulativeGasUsed": "4703429", "status": 1, "byzantium": true }, "args": [], - "numDeployments": 1, - "solcInputHash": "5b32b398159a217fe332309d645e3f53", - "metadata": "{\"compiler\":{\"version\":\"0.8.17+commit.8df45f5f\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[],\"name\":\"AssetStillControlledInReserves\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"BurnAmountExceedsAllowance\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"HourlyLimitExceeded\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidSender\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidToken\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidTreasury\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"NotGovernor\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"NotGovernorOrGuardian\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"NotMinter\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"NotTreasury\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"TooBigAmount\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"TooHighParameterValue\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ZeroAddress\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"spender\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"}],\"name\":\"Approval\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"bridgeToken\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"limit\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"hourlyLimit\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"fee\",\"type\":\"uint64\"},{\"indexed\":false,\"internalType\":\"bool\",\"name\":\"paused\",\"type\":\"bool\"}],\"name\":\"BridgeTokenAdded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"bridgeToken\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"fee\",\"type\":\"uint64\"}],\"name\":\"BridgeTokenFeeUpdated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"bridgeToken\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"hourlyLimit\",\"type\":\"uint256\"}],\"name\":\"BridgeTokenHourlyLimitUpdated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"bridgeToken\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"limit\",\"type\":\"uint256\"}],\"name\":\"BridgeTokenLimitUpdated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"bridgeToken\",\"type\":\"address\"}],\"name\":\"BridgeTokenRemoved\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"bridgeToken\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"bool\",\"name\":\"toggleStatus\",\"type\":\"bool\"}],\"name\":\"BridgeTokenToggled\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"theAddress\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"toggleStatus\",\"type\":\"uint256\"}],\"name\":\"FeeToggled\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"hourlyLimit\",\"type\":\"uint256\"}],\"name\":\"HourlyLimitUpdated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint8\",\"name\":\"version\",\"type\":\"uint8\"}],\"name\":\"Initialized\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"minter\",\"type\":\"address\"}],\"name\":\"MinterToggled\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"Recovered\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"}],\"name\":\"Transfer\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"_treasury\",\"type\":\"address\"}],\"name\":\"TreasuryUpdated\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"BASE_PARAMS\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"DOMAIN_SEPARATOR\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"bridgeToken\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"limit\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"hourlyLimit\",\"type\":\"uint256\"},{\"internalType\":\"uint64\",\"name\":\"fee\",\"type\":\"uint64\"},{\"internalType\":\"bool\",\"name\":\"paused\",\"type\":\"bool\"}],\"name\":\"addBridgeToken\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"minter\",\"type\":\"address\"}],\"name\":\"addMinter\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"allBridgeTokens\",\"outputs\":[{\"internalType\":\"address[]\",\"name\":\"\",\"type\":\"address[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"spender\",\"type\":\"address\"}],\"name\":\"allowance\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"spender\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"approve\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"}],\"name\":\"balanceOf\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"name\":\"bridgeTokensList\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"bridges\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"limit\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"hourlyLimit\",\"type\":\"uint256\"},{\"internalType\":\"uint64\",\"name\":\"fee\",\"type\":\"uint64\"},{\"internalType\":\"bool\",\"name\":\"allowed\",\"type\":\"bool\"},{\"internalType\":\"bool\",\"name\":\"paused\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"burner\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"}],\"name\":\"burnFrom\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"burner\",\"type\":\"address\"}],\"name\":\"burnSelf\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"burnStablecoin\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"chainTotalHourlyLimit\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"name\":\"chainTotalUsage\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"currentTotalUsage\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"bridgeToken\",\"type\":\"address\"}],\"name\":\"currentUsage\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"decimals\",\"outputs\":[{\"internalType\":\"uint8\",\"name\":\"\",\"type\":\"uint8\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"spender\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"subtractedValue\",\"type\":\"uint256\"}],\"name\":\"decreaseAllowance\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"spender\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"addedValue\",\"type\":\"uint256\"}],\"name\":\"increaseAllowance\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"string\",\"name\":\"name_\",\"type\":\"string\"},{\"internalType\":\"string\",\"name\":\"symbol_\",\"type\":\"string\"},{\"internalType\":\"address\",\"name\":\"_treasury\",\"type\":\"address\"}],\"name\":\"initialize\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"isFeeExempt\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"isMinter\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"mint\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"name\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"}],\"name\":\"nonces\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"spender\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"deadline\",\"type\":\"uint256\"},{\"internalType\":\"uint8\",\"name\":\"v\",\"type\":\"uint8\"},{\"internalType\":\"bytes32\",\"name\":\"r\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32\",\"name\":\"s\",\"type\":\"bytes32\"}],\"name\":\"permit\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"tokenAddress\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amountToRecover\",\"type\":\"uint256\"}],\"name\":\"recoverERC20\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"bridgeToken\",\"type\":\"address\"}],\"name\":\"removeBridgeToken\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"minter\",\"type\":\"address\"}],\"name\":\"removeMinter\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"hourlyLimit\",\"type\":\"uint256\"}],\"name\":\"setChainTotalHourlyLimit\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"bridgeToken\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"hourlyLimit\",\"type\":\"uint256\"}],\"name\":\"setHourlyLimit\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"bridgeToken\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"limit\",\"type\":\"uint256\"}],\"name\":\"setLimit\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"bridgeToken\",\"type\":\"address\"},{\"internalType\":\"uint64\",\"name\":\"fee\",\"type\":\"uint64\"}],\"name\":\"setSwapFee\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_treasury\",\"type\":\"address\"}],\"name\":\"setTreasury\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"bridgeToken\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"swapIn\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"bridgeToken\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"swapOut\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"symbol\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"bridgeToken\",\"type\":\"address\"}],\"name\":\"toggleBridge\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"theAddress\",\"type\":\"address\"}],\"name\":\"toggleFeesForAddress\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"totalSupply\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"transfer\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"transferFrom\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"treasury\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"name\":\"usage\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"}],\"devdoc\":{\"author\":\"Angle Labs, Inc.\",\"details\":\"This contract supports bridge tokens having a minting right on the stablecoin (also referred to as the canonical or the native token)References: - FRAX implementation: https://polygonscan.com/address/0x45c32fA6DF82ead1e2EF74d17b76547EDdFaFF89#code - QiDAO implementation: https://snowtrace.io/address/0x5c49b268c9841AFF1Cc3B0a418ff5c3442eE3F3b#code\",\"kind\":\"dev\",\"methods\":{\"DOMAIN_SEPARATOR()\":{\"details\":\"See {IERC20Permit-DOMAIN_SEPARATOR}.\"},\"addBridgeToken(address,uint256,uint256,uint64,bool)\":{\"params\":{\"bridgeToken\":\"Bridge token to add: it should be a version of the stablecoin from another bridge\",\"fee\":\"Fee taken upon swapping for or against this token\",\"hourlyLimit\":\"Limit on the hourly volume for this bridge\",\"limit\":\"Limit on the balance of bridge token this contract could hold\",\"paused\":\"Whether swapping for this token should be paused or not\"}},\"addMinter(address)\":{\"details\":\"Zero address checks are performed directly in the `Treasury` contract\",\"params\":{\"minter\":\"Minter address to add\"}},\"allBridgeTokens()\":{\"details\":\"Helpful for UIs\"},\"allowance(address,address)\":{\"details\":\"See {IERC20-allowance}.\"},\"approve(address,uint256)\":{\"details\":\"See {IERC20-approve}. NOTE: If `amount` is the maximum `uint256`, the allowance is not updated on `transferFrom`. This is semantically equivalent to an infinite approval. Requirements: - `spender` cannot be the zero address.\"},\"balanceOf(address)\":{\"details\":\"See {IERC20-balanceOf}.\"},\"burnFrom(uint256,address,address)\":{\"details\":\"This method is to be called by a contract with the minter right after being requested to do so by a `sender` address willing to burn tokens from another `burner` addressThe method checks the allowance between the `sender` and the `burner`\",\"params\":{\"amount\":\"Amount of tokens to burn\",\"burner\":\"Address to burn from\",\"sender\":\"Address which requested the burn from `burner`\"}},\"burnSelf(uint256,address)\":{\"details\":\"This method is to be called by a contract with a minter right on the AgToken after being requested to do so by an address willing to burn tokens from its address\",\"params\":{\"amount\":\"Amount of tokens to burn\",\"burner\":\"Address to burn from\"}},\"burnStablecoin(uint256)\":{\"details\":\"This function can typically be called if there is a settlement mechanism to burn stablecoins\",\"params\":{\"amount\":\"Amount of stablecoins to burn\"}},\"currentTotalUsage()\":{\"details\":\"Helpful for UIs\"},\"currentUsage(address)\":{\"details\":\"Helpful for UIs\",\"params\":{\"bridgeToken\":\"Bridge used to mint\"}},\"decimals()\":{\"details\":\"Returns the number of decimals used to get its user representation. For example, if `decimals` equals `2`, a balance of `505` tokens should be displayed to a user as `5.05` (`505 / 10 ** 2`). Tokens usually opt for a value of 18, imitating the relationship between Ether and Wei. This is the value {ERC20} uses, unless this function is overridden; NOTE: This information is only used for _display_ purposes: it in no way affects any of the arithmetic of the contract, including {IERC20-balanceOf} and {IERC20-transfer}.\"},\"decreaseAllowance(address,uint256)\":{\"details\":\"Atomically decreases the allowance granted to `spender` by the caller. This is an alternative to {approve} that can be used as a mitigation for problems described in {IERC20-approve}. Emits an {Approval} event indicating the updated allowance. Requirements: - `spender` cannot be the zero address. - `spender` must have allowance for the caller of at least `subtractedValue`.\"},\"increaseAllowance(address,uint256)\":{\"details\":\"Atomically increases the allowance granted to `spender` by the caller. This is an alternative to {approve} that can be used as a mitigation for problems described in {IERC20-approve}. Emits an {Approval} event indicating the updated allowance. Requirements: - `spender` cannot be the zero address.\"},\"initialize(string,string,address)\":{\"details\":\"By default, agTokens are ERC-20 tokens with 18 decimals\",\"params\":{\"_treasury\":\"Reference to the `Treasury` contract associated to this agToken\",\"name_\":\"Name of the token\",\"symbol_\":\"Symbol of the token\"}},\"mint(address,uint256)\":{\"details\":\"The contracts allowed to issue agTokens are the `StableMaster` contract, `VaultManager` contracts associated to this stablecoin as well as the flash loan module (if activated) and potentially contracts whitelisted by governance\",\"params\":{\"account\":\"Address to mint to\",\"amount\":\"Amount to mint\"}},\"name()\":{\"details\":\"Returns the name of the token.\"},\"nonces(address)\":{\"details\":\"See {IERC20Permit-nonces}.\"},\"permit(address,address,uint256,uint256,uint8,bytes32,bytes32)\":{\"details\":\"See {IERC20Permit-permit}.\"},\"recoverERC20(address,address,uint256)\":{\"details\":\"Can be used to withdraw bridge tokens for them to be de-bridged on mainnet\"},\"removeBridgeToken(address)\":{\"params\":{\"bridgeToken\":\"Address of the bridge token to remove support for\"}},\"removeMinter(address)\":{\"details\":\"This function can also be called by a minter wishing to revoke itself\",\"params\":{\"minter\":\"Minter address to remove\"}},\"setTreasury(address)\":{\"params\":{\"_treasury\":\"New treasury address\"}},\"swapIn(address,uint256,address)\":{\"details\":\"Some fees may be taken by the protocol depending on the token used and on the address calling\",\"params\":{\"amount\":\"Amount of bridge tokens to send\",\"bridgeToken\":\"Bridge token to use to mint\",\"to\":\"Address to which the stablecoin should be sent\"},\"returns\":{\"_0\":\"Amount of the canonical stablecoin actually minted\"}},\"swapOut(address,uint256,address)\":{\"details\":\"Some fees may be taken by the protocol depending on the token used and on the address calling\",\"params\":{\"amount\":\"Amount of canonical tokens to burn\",\"bridgeToken\":\"Bridge token required\",\"to\":\"Address to which the bridge token should be sent\"},\"returns\":{\"_0\":\"Amount of bridge tokens actually sent back\"}},\"symbol()\":{\"details\":\"Returns the symbol of the token, usually a shorter version of the name.\"},\"totalSupply()\":{\"details\":\"See {IERC20-totalSupply}.\"},\"transfer(address,uint256)\":{\"details\":\"See {IERC20-transfer}. Requirements: - `to` cannot be the zero address. - the caller must have a balance of at least `amount`.\"},\"transferFrom(address,address,uint256)\":{\"details\":\"See {IERC20-transferFrom}. Emits an {Approval} event indicating the updated allowance. This is not required by the EIP. See the note at the beginning of {ERC20}. NOTE: Does not update the allowance if the current allowance is the maximum `uint256`. Requirements: - `from` and `to` cannot be the zero address. - `from` must have a balance of at least `amount`. - the caller must have allowance for ``from``'s tokens of at least `amount`.\"}},\"title\":\"AgTokenSideChainMultiBridge\",\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{\"BASE_PARAMS()\":{\"notice\":\"Base used for fee computation\"},\"addBridgeToken(address,uint256,uint256,uint64,bool)\":{\"notice\":\"Adds support for a bridge token\"},\"addMinter(address)\":{\"notice\":\"Adds a minter in the contract\"},\"allBridgeTokens()\":{\"notice\":\"Returns the list of all supported bridge tokens\"},\"bridgeTokensList(uint256)\":{\"notice\":\"List of all bridge tokens\"},\"bridges(address)\":{\"notice\":\"Maps a bridge token to data\"},\"burnFrom(uint256,address,address)\":{\"notice\":\"Burns `amount` tokens from a `burner` address after being asked to by `sender`\"},\"burnSelf(uint256,address)\":{\"notice\":\"Burns `amount` tokens from a `burner` address\"},\"burnStablecoin(uint256)\":{\"notice\":\"Allows anyone to burn agToken without redeeming collateral back\"},\"chainTotalHourlyLimit()\":{\"notice\":\"Limit to the amount of tokens that can be sent from that chain to another chain\"},\"chainTotalUsage(uint256)\":{\"notice\":\"Usage per hour on that chain. Maps an hourly timestamp to the total volume swapped out on the chain\"},\"currentTotalUsage()\":{\"notice\":\"Returns the current total volume on the chain for the current hour\"},\"currentUsage(address)\":{\"notice\":\"Returns the current volume for a bridge, for the current hour\"},\"initialize(string,string,address)\":{\"notice\":\"Initializes the `AgToken` contract\"},\"isFeeExempt(address)\":{\"notice\":\"Maps an address to whether it is exempt of fees for when it comes to swapping in and out\"},\"isMinter(address)\":{\"notice\":\"Checks whether an address has the right to mint agTokens\"},\"mint(address,uint256)\":{\"notice\":\"Lets the `StableMaster` contract or another whitelisted contract mint agTokens\"},\"recoverERC20(address,address,uint256)\":{\"notice\":\"Recovers any ERC20 token\"},\"removeBridgeToken(address)\":{\"notice\":\"Removes support for a token\"},\"removeMinter(address)\":{\"notice\":\"Removes a minter from the contract\"},\"setChainTotalHourlyLimit(uint256)\":{\"notice\":\"Updates the `chainTotalHourlyLimit` amount\"},\"setHourlyLimit(address,uint256)\":{\"notice\":\"Updates the `hourlyLimit` amount for `bridgeToken`\"},\"setLimit(address,uint256)\":{\"notice\":\"Updates the `limit` amount for `bridgeToken`\"},\"setSwapFee(address,uint64)\":{\"notice\":\"Updates the `fee` value for `bridgeToken`\"},\"setTreasury(address)\":{\"notice\":\"Sets a new treasury contract\"},\"swapIn(address,uint256,address)\":{\"notice\":\"Mints the canonical token from a supported bridge token\"},\"swapOut(address,uint256,address)\":{\"notice\":\"Burns the canonical token in exchange for a bridge token\"},\"toggleBridge(address)\":{\"notice\":\"Pauses or unpauses swapping in and out for a token\"},\"toggleFeesForAddress(address)\":{\"notice\":\"Toggles fees for the address `theAddress`\"},\"treasury()\":{\"notice\":\"Reference to the treasury contract which can grant minting rights\"},\"usage(address,uint256)\":{\"notice\":\"Maps a bridge token to the associated hourly volume\"}},\"notice\":\"Contract for Angle agTokens on other chains than Ethereum mainnet\",\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/agToken/AgTokenSideChainMultiBridge.sol\":\"AgTokenSideChainMultiBridge\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":1000000},\"remappings\":[]},\"sources\":{\"@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.7.0) (proxy/utils/Initializable.sol)\\n\\npragma solidity ^0.8.2;\\n\\nimport \\\"../../utils/AddressUpgradeable.sol\\\";\\n\\n/**\\n * @dev This is a base contract to aid in writing upgradeable contracts, or any kind of contract that will be deployed\\n * behind a proxy. Since proxied contracts do not make use of a constructor, it's common to move constructor logic to an\\n * external initializer function, usually called `initialize`. It then becomes necessary to protect this initializer\\n * function so it can only be called once. The {initializer} modifier provided by this contract will have this effect.\\n *\\n * The initialization functions use a version number. Once a version number is used, it is consumed and cannot be\\n * reused. This mechanism prevents re-execution of each \\\"step\\\" but allows the creation of new initialization steps in\\n * case an upgrade adds a module that needs to be initialized.\\n *\\n * For example:\\n *\\n * [.hljs-theme-light.nopadding]\\n * ```\\n * contract MyToken is ERC20Upgradeable {\\n * function initialize() initializer public {\\n * __ERC20_init(\\\"MyToken\\\", \\\"MTK\\\");\\n * }\\n * }\\n * contract MyTokenV2 is MyToken, ERC20PermitUpgradeable {\\n * function initializeV2() reinitializer(2) public {\\n * __ERC20Permit_init(\\\"MyToken\\\");\\n * }\\n * }\\n * ```\\n *\\n * TIP: To avoid leaving the proxy in an uninitialized state, the initializer function should be called as early as\\n * possible by providing the encoded function call as the `_data` argument to {ERC1967Proxy-constructor}.\\n *\\n * CAUTION: When used with inheritance, manual care must be taken to not invoke a parent initializer twice, or to ensure\\n * that all initializers are idempotent. This is not verified automatically as constructors are by Solidity.\\n *\\n * [CAUTION]\\n * ====\\n * Avoid leaving a contract uninitialized.\\n *\\n * An uninitialized contract can be taken over by an attacker. This applies to both a proxy and its implementation\\n * contract, which may impact the proxy. To prevent the implementation contract from being used, you should invoke\\n * the {_disableInitializers} function in the constructor to automatically lock it when it is deployed:\\n *\\n * [.hljs-theme-light.nopadding]\\n * ```\\n * /// @custom:oz-upgrades-unsafe-allow constructor\\n * constructor() {\\n * _disableInitializers();\\n * }\\n * ```\\n * ====\\n */\\nabstract contract Initializable {\\n /**\\n * @dev Indicates that the contract has been initialized.\\n * @custom:oz-retyped-from bool\\n */\\n uint8 private _initialized;\\n\\n /**\\n * @dev Indicates that the contract is in the process of being initialized.\\n */\\n bool private _initializing;\\n\\n /**\\n * @dev Triggered when the contract has been initialized or reinitialized.\\n */\\n event Initialized(uint8 version);\\n\\n /**\\n * @dev A modifier that defines a protected initializer function that can be invoked at most once. In its scope,\\n * `onlyInitializing` functions can be used to initialize parent contracts. Equivalent to `reinitializer(1)`.\\n */\\n modifier initializer() {\\n bool isTopLevelCall = !_initializing;\\n require(\\n (isTopLevelCall && _initialized < 1) || (!AddressUpgradeable.isContract(address(this)) && _initialized == 1),\\n \\\"Initializable: contract is already initialized\\\"\\n );\\n _initialized = 1;\\n if (isTopLevelCall) {\\n _initializing = true;\\n }\\n _;\\n if (isTopLevelCall) {\\n _initializing = false;\\n emit Initialized(1);\\n }\\n }\\n\\n /**\\n * @dev A modifier that defines a protected reinitializer function that can be invoked at most once, and only if the\\n * contract hasn't been initialized to a greater version before. In its scope, `onlyInitializing` functions can be\\n * used to initialize parent contracts.\\n *\\n * `initializer` is equivalent to `reinitializer(1)`, so a reinitializer may be used after the original\\n * initialization step. This is essential to configure modules that are added through upgrades and that require\\n * initialization.\\n *\\n * Note that versions can jump in increments greater than 1; this implies that if multiple reinitializers coexist in\\n * a contract, executing them in the right order is up to the developer or operator.\\n */\\n modifier reinitializer(uint8 version) {\\n require(!_initializing && _initialized < version, \\\"Initializable: contract is already initialized\\\");\\n _initialized = version;\\n _initializing = true;\\n _;\\n _initializing = false;\\n emit Initialized(version);\\n }\\n\\n /**\\n * @dev Modifier to protect an initialization function so that it can only be invoked by functions with the\\n * {initializer} and {reinitializer} modifiers, directly or indirectly.\\n */\\n modifier onlyInitializing() {\\n require(_initializing, \\\"Initializable: contract is not initializing\\\");\\n _;\\n }\\n\\n /**\\n * @dev Locks the contract, preventing any future reinitialization. This cannot be part of an initializer call.\\n * Calling this in the constructor of a contract will prevent that contract from being initialized or reinitialized\\n * to any version. It is recommended to use this to lock implementation contracts that are designed to be called\\n * through proxies.\\n */\\n function _disableInitializers() internal virtual {\\n require(!_initializing, \\\"Initializable: contract is initializing\\\");\\n if (_initialized < type(uint8).max) {\\n _initialized = type(uint8).max;\\n emit Initialized(type(uint8).max);\\n }\\n }\\n}\\n\",\"keccak256\":\"0x0203dcadc5737d9ef2c211d6fa15d18ebc3b30dfa51903b64870b01a062b0b4e\",\"license\":\"MIT\"},\"@openzeppelin/contracts-upgradeable/token/ERC20/ERC20Upgradeable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.7.0) (token/ERC20/ERC20.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"./IERC20Upgradeable.sol\\\";\\nimport \\\"./extensions/IERC20MetadataUpgradeable.sol\\\";\\nimport \\\"../../utils/ContextUpgradeable.sol\\\";\\nimport \\\"../../proxy/utils/Initializable.sol\\\";\\n\\n/**\\n * @dev Implementation of the {IERC20} interface.\\n *\\n * This implementation is agnostic to the way tokens are created. This means\\n * that a supply mechanism has to be added in a derived contract using {_mint}.\\n * For a generic mechanism see {ERC20PresetMinterPauser}.\\n *\\n * TIP: For a detailed writeup see our guide\\n * https://forum.zeppelin.solutions/t/how-to-implement-erc20-supply-mechanisms/226[How\\n * to implement supply mechanisms].\\n *\\n * We have followed general OpenZeppelin Contracts guidelines: functions revert\\n * instead returning `false` on failure. This behavior is nonetheless\\n * conventional and does not conflict with the expectations of ERC20\\n * applications.\\n *\\n * Additionally, an {Approval} event is emitted on calls to {transferFrom}.\\n * This allows applications to reconstruct the allowance for all accounts just\\n * by listening to said events. Other implementations of the EIP may not emit\\n * these events, as it isn't required by the specification.\\n *\\n * Finally, the non-standard {decreaseAllowance} and {increaseAllowance}\\n * functions have been added to mitigate the well-known issues around setting\\n * allowances. See {IERC20-approve}.\\n */\\ncontract ERC20Upgradeable is Initializable, ContextUpgradeable, IERC20Upgradeable, IERC20MetadataUpgradeable {\\n mapping(address => uint256) private _balances;\\n\\n mapping(address => mapping(address => uint256)) private _allowances;\\n\\n uint256 private _totalSupply;\\n\\n string private _name;\\n string private _symbol;\\n\\n /**\\n * @dev Sets the values for {name} and {symbol}.\\n *\\n * The default value of {decimals} is 18. To select a different value for\\n * {decimals} you should overload it.\\n *\\n * All two of these values are immutable: they can only be set once during\\n * construction.\\n */\\n function __ERC20_init(string memory name_, string memory symbol_) internal onlyInitializing {\\n __ERC20_init_unchained(name_, symbol_);\\n }\\n\\n function __ERC20_init_unchained(string memory name_, string memory symbol_) internal onlyInitializing {\\n _name = name_;\\n _symbol = symbol_;\\n }\\n\\n /**\\n * @dev Returns the name of the token.\\n */\\n function name() public view virtual override returns (string memory) {\\n return _name;\\n }\\n\\n /**\\n * @dev Returns the symbol of the token, usually a shorter version of the\\n * name.\\n */\\n function symbol() public view virtual override returns (string memory) {\\n return _symbol;\\n }\\n\\n /**\\n * @dev Returns the number of decimals used to get its user representation.\\n * For example, if `decimals` equals `2`, a balance of `505` tokens should\\n * be displayed to a user as `5.05` (`505 / 10 ** 2`).\\n *\\n * Tokens usually opt for a value of 18, imitating the relationship between\\n * Ether and Wei. This is the value {ERC20} uses, unless this function is\\n * overridden;\\n *\\n * NOTE: This information is only used for _display_ purposes: it in\\n * no way affects any of the arithmetic of the contract, including\\n * {IERC20-balanceOf} and {IERC20-transfer}.\\n */\\n function decimals() public view virtual override returns (uint8) {\\n return 18;\\n }\\n\\n /**\\n * @dev See {IERC20-totalSupply}.\\n */\\n function totalSupply() public view virtual override returns (uint256) {\\n return _totalSupply;\\n }\\n\\n /**\\n * @dev See {IERC20-balanceOf}.\\n */\\n function balanceOf(address account) public view virtual override returns (uint256) {\\n return _balances[account];\\n }\\n\\n /**\\n * @dev See {IERC20-transfer}.\\n *\\n * Requirements:\\n *\\n * - `to` cannot be the zero address.\\n * - the caller must have a balance of at least `amount`.\\n */\\n function transfer(address to, uint256 amount) public virtual override returns (bool) {\\n address owner = _msgSender();\\n _transfer(owner, to, amount);\\n return true;\\n }\\n\\n /**\\n * @dev See {IERC20-allowance}.\\n */\\n function allowance(address owner, address spender) public view virtual override returns (uint256) {\\n return _allowances[owner][spender];\\n }\\n\\n /**\\n * @dev See {IERC20-approve}.\\n *\\n * NOTE: If `amount` is the maximum `uint256`, the allowance is not updated on\\n * `transferFrom`. This is semantically equivalent to an infinite approval.\\n *\\n * Requirements:\\n *\\n * - `spender` cannot be the zero address.\\n */\\n function approve(address spender, uint256 amount) public virtual override returns (bool) {\\n address owner = _msgSender();\\n _approve(owner, spender, amount);\\n return true;\\n }\\n\\n /**\\n * @dev See {IERC20-transferFrom}.\\n *\\n * Emits an {Approval} event indicating the updated allowance. This is not\\n * required by the EIP. See the note at the beginning of {ERC20}.\\n *\\n * NOTE: Does not update the allowance if the current allowance\\n * is the maximum `uint256`.\\n *\\n * Requirements:\\n *\\n * - `from` and `to` cannot be the zero address.\\n * - `from` must have a balance of at least `amount`.\\n * - the caller must have allowance for ``from``'s tokens of at least\\n * `amount`.\\n */\\n function transferFrom(\\n address from,\\n address to,\\n uint256 amount\\n ) public virtual override returns (bool) {\\n address spender = _msgSender();\\n _spendAllowance(from, spender, amount);\\n _transfer(from, to, amount);\\n return true;\\n }\\n\\n /**\\n * @dev Atomically increases the allowance granted to `spender` by the caller.\\n *\\n * This is an alternative to {approve} that can be used as a mitigation for\\n * problems described in {IERC20-approve}.\\n *\\n * Emits an {Approval} event indicating the updated allowance.\\n *\\n * Requirements:\\n *\\n * - `spender` cannot be the zero address.\\n */\\n function increaseAllowance(address spender, uint256 addedValue) public virtual returns (bool) {\\n address owner = _msgSender();\\n _approve(owner, spender, allowance(owner, spender) + addedValue);\\n return true;\\n }\\n\\n /**\\n * @dev Atomically decreases the allowance granted to `spender` by the caller.\\n *\\n * This is an alternative to {approve} that can be used as a mitigation for\\n * problems described in {IERC20-approve}.\\n *\\n * Emits an {Approval} event indicating the updated allowance.\\n *\\n * Requirements:\\n *\\n * - `spender` cannot be the zero address.\\n * - `spender` must have allowance for the caller of at least\\n * `subtractedValue`.\\n */\\n function decreaseAllowance(address spender, uint256 subtractedValue) public virtual returns (bool) {\\n address owner = _msgSender();\\n uint256 currentAllowance = allowance(owner, spender);\\n require(currentAllowance >= subtractedValue, \\\"ERC20: decreased allowance below zero\\\");\\n unchecked {\\n _approve(owner, spender, currentAllowance - subtractedValue);\\n }\\n\\n return true;\\n }\\n\\n /**\\n * @dev Moves `amount` of tokens from `from` to `to`.\\n *\\n * This internal function is equivalent to {transfer}, and can be used to\\n * e.g. implement automatic token fees, slashing mechanisms, etc.\\n *\\n * Emits a {Transfer} event.\\n *\\n * Requirements:\\n *\\n * - `from` cannot be the zero address.\\n * - `to` cannot be the zero address.\\n * - `from` must have a balance of at least `amount`.\\n */\\n function _transfer(\\n address from,\\n address to,\\n uint256 amount\\n ) internal virtual {\\n require(from != address(0), \\\"ERC20: transfer from the zero address\\\");\\n require(to != address(0), \\\"ERC20: transfer to the zero address\\\");\\n\\n _beforeTokenTransfer(from, to, amount);\\n\\n uint256 fromBalance = _balances[from];\\n require(fromBalance >= amount, \\\"ERC20: transfer amount exceeds balance\\\");\\n unchecked {\\n _balances[from] = fromBalance - amount;\\n }\\n _balances[to] += amount;\\n\\n emit Transfer(from, to, amount);\\n\\n _afterTokenTransfer(from, to, amount);\\n }\\n\\n /** @dev Creates `amount` tokens and assigns them to `account`, increasing\\n * the total supply.\\n *\\n * Emits a {Transfer} event with `from` set to the zero address.\\n *\\n * Requirements:\\n *\\n * - `account` cannot be the zero address.\\n */\\n function _mint(address account, uint256 amount) internal virtual {\\n require(account != address(0), \\\"ERC20: mint to the zero address\\\");\\n\\n _beforeTokenTransfer(address(0), account, amount);\\n\\n _totalSupply += amount;\\n _balances[account] += amount;\\n emit Transfer(address(0), account, amount);\\n\\n _afterTokenTransfer(address(0), account, amount);\\n }\\n\\n /**\\n * @dev Destroys `amount` tokens from `account`, reducing the\\n * total supply.\\n *\\n * Emits a {Transfer} event with `to` set to the zero address.\\n *\\n * Requirements:\\n *\\n * - `account` cannot be the zero address.\\n * - `account` must have at least `amount` tokens.\\n */\\n function _burn(address account, uint256 amount) internal virtual {\\n require(account != address(0), \\\"ERC20: burn from the zero address\\\");\\n\\n _beforeTokenTransfer(account, address(0), amount);\\n\\n uint256 accountBalance = _balances[account];\\n require(accountBalance >= amount, \\\"ERC20: burn amount exceeds balance\\\");\\n unchecked {\\n _balances[account] = accountBalance - amount;\\n }\\n _totalSupply -= amount;\\n\\n emit Transfer(account, address(0), amount);\\n\\n _afterTokenTransfer(account, address(0), amount);\\n }\\n\\n /**\\n * @dev Sets `amount` as the allowance of `spender` over the `owner` s tokens.\\n *\\n * This internal function is equivalent to `approve`, and can be used to\\n * e.g. set automatic allowances for certain subsystems, etc.\\n *\\n * Emits an {Approval} event.\\n *\\n * Requirements:\\n *\\n * - `owner` cannot be the zero address.\\n * - `spender` cannot be the zero address.\\n */\\n function _approve(\\n address owner,\\n address spender,\\n uint256 amount\\n ) internal virtual {\\n require(owner != address(0), \\\"ERC20: approve from the zero address\\\");\\n require(spender != address(0), \\\"ERC20: approve to the zero address\\\");\\n\\n _allowances[owner][spender] = amount;\\n emit Approval(owner, spender, amount);\\n }\\n\\n /**\\n * @dev Updates `owner` s allowance for `spender` based on spent `amount`.\\n *\\n * Does not update the allowance amount in case of infinite allowance.\\n * Revert if not enough allowance is available.\\n *\\n * Might emit an {Approval} event.\\n */\\n function _spendAllowance(\\n address owner,\\n address spender,\\n uint256 amount\\n ) internal virtual {\\n uint256 currentAllowance = allowance(owner, spender);\\n if (currentAllowance != type(uint256).max) {\\n require(currentAllowance >= amount, \\\"ERC20: insufficient allowance\\\");\\n unchecked {\\n _approve(owner, spender, currentAllowance - amount);\\n }\\n }\\n }\\n\\n /**\\n * @dev Hook that is called before any transfer of tokens. This includes\\n * minting and burning.\\n *\\n * Calling conditions:\\n *\\n * - when `from` and `to` are both non-zero, `amount` of ``from``'s tokens\\n * will be transferred to `to`.\\n * - when `from` is zero, `amount` tokens will be minted for `to`.\\n * - when `to` is zero, `amount` of ``from``'s tokens will be burned.\\n * - `from` and `to` are never both zero.\\n *\\n * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].\\n */\\n function _beforeTokenTransfer(\\n address from,\\n address to,\\n uint256 amount\\n ) internal virtual {}\\n\\n /**\\n * @dev Hook that is called after any transfer of tokens. This includes\\n * minting and burning.\\n *\\n * Calling conditions:\\n *\\n * - when `from` and `to` are both non-zero, `amount` of ``from``'s tokens\\n * has been transferred to `to`.\\n * - when `from` is zero, `amount` tokens have been minted for `to`.\\n * - when `to` is zero, `amount` of ``from``'s tokens have been burned.\\n * - `from` and `to` are never both zero.\\n *\\n * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].\\n */\\n function _afterTokenTransfer(\\n address from,\\n address to,\\n uint256 amount\\n ) internal virtual {}\\n\\n /**\\n * @dev This empty reserved space is put in place to allow future versions to add new\\n * variables without shifting down storage in the inheritance chain.\\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\\n */\\n uint256[45] private __gap;\\n}\\n\",\"keccak256\":\"0x7c7ac0bc6c340a7f320524b9a4b4b079ee9da3c51258080d4bab237f329a427c\",\"license\":\"MIT\"},\"@openzeppelin/contracts-upgradeable/token/ERC20/IERC20Upgradeable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.6.0) (token/ERC20/IERC20.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Interface of the ERC20 standard as defined in the EIP.\\n */\\ninterface IERC20Upgradeable {\\n /**\\n * @dev Emitted when `value` tokens are moved from one account (`from`) to\\n * another (`to`).\\n *\\n * Note that `value` may be zero.\\n */\\n event Transfer(address indexed from, address indexed to, uint256 value);\\n\\n /**\\n * @dev Emitted when the allowance of a `spender` for an `owner` is set by\\n * a call to {approve}. `value` is the new allowance.\\n */\\n event Approval(address indexed owner, address indexed spender, uint256 value);\\n\\n /**\\n * @dev Returns the amount of tokens in existence.\\n */\\n function totalSupply() external view returns (uint256);\\n\\n /**\\n * @dev Returns the amount of tokens owned by `account`.\\n */\\n function balanceOf(address account) external view returns (uint256);\\n\\n /**\\n * @dev Moves `amount` tokens from the caller's account to `to`.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * Emits a {Transfer} event.\\n */\\n function transfer(address to, uint256 amount) external returns (bool);\\n\\n /**\\n * @dev Returns the remaining number of tokens that `spender` will be\\n * allowed to spend on behalf of `owner` through {transferFrom}. This is\\n * zero by default.\\n *\\n * This value changes when {approve} or {transferFrom} are called.\\n */\\n function allowance(address owner, address spender) external view returns (uint256);\\n\\n /**\\n * @dev Sets `amount` as the allowance of `spender` over the caller's tokens.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * IMPORTANT: Beware that changing an allowance with this method brings the risk\\n * that someone may use both the old and the new allowance by unfortunate\\n * transaction ordering. One possible solution to mitigate this race\\n * condition is to first reduce the spender's allowance to 0 and set the\\n * desired value afterwards:\\n * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729\\n *\\n * Emits an {Approval} event.\\n */\\n function approve(address spender, uint256 amount) external returns (bool);\\n\\n /**\\n * @dev Moves `amount` tokens from `from` to `to` using the\\n * allowance mechanism. `amount` is then deducted from the caller's\\n * allowance.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * Emits a {Transfer} event.\\n */\\n function transferFrom(\\n address from,\\n address to,\\n uint256 amount\\n ) external returns (bool);\\n}\\n\",\"keccak256\":\"0x4e733d3164f73f461eaf9d8087a7ad1ea180bdc8ba0d3d61b0e1ae16d8e63dff\",\"license\":\"MIT\"},\"@openzeppelin/contracts-upgradeable/token/ERC20/extensions/IERC20MetadataUpgradeable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (token/ERC20/extensions/IERC20Metadata.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../IERC20Upgradeable.sol\\\";\\n\\n/**\\n * @dev Interface for the optional metadata functions from the ERC20 standard.\\n *\\n * _Available since v4.1._\\n */\\ninterface IERC20MetadataUpgradeable is IERC20Upgradeable {\\n /**\\n * @dev Returns the name of the token.\\n */\\n function name() external view returns (string memory);\\n\\n /**\\n * @dev Returns the symbol of the token.\\n */\\n function symbol() external view returns (string memory);\\n\\n /**\\n * @dev Returns the decimals places of the token.\\n */\\n function decimals() external view returns (uint8);\\n}\\n\",\"keccak256\":\"0x605434219ebbe4653f703640f06969faa5a1d78f0bfef878e5ddbb1ca369ceeb\",\"license\":\"MIT\"},\"@openzeppelin/contracts-upgradeable/token/ERC20/extensions/draft-ERC20PermitUpgradeable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.6.0) (token/ERC20/extensions/draft-ERC20Permit.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"./draft-IERC20PermitUpgradeable.sol\\\";\\nimport \\\"../ERC20Upgradeable.sol\\\";\\nimport \\\"../../../utils/cryptography/draft-EIP712Upgradeable.sol\\\";\\nimport \\\"../../../utils/cryptography/ECDSAUpgradeable.sol\\\";\\nimport \\\"../../../utils/CountersUpgradeable.sol\\\";\\nimport \\\"../../../proxy/utils/Initializable.sol\\\";\\n\\n/**\\n * @dev Implementation of the ERC20 Permit extension allowing approvals to be made via signatures, as defined in\\n * https://eips.ethereum.org/EIPS/eip-2612[EIP-2612].\\n *\\n * Adds the {permit} method, which can be used to change an account's ERC20 allowance (see {IERC20-allowance}) by\\n * presenting a message signed by the account. By not relying on `{IERC20-approve}`, the token holder account doesn't\\n * need to send a transaction, and thus is not required to hold Ether at all.\\n *\\n * _Available since v3.4._\\n *\\n * @custom:storage-size 51\\n */\\nabstract contract ERC20PermitUpgradeable is Initializable, ERC20Upgradeable, IERC20PermitUpgradeable, EIP712Upgradeable {\\n using CountersUpgradeable for CountersUpgradeable.Counter;\\n\\n mapping(address => CountersUpgradeable.Counter) private _nonces;\\n\\n // solhint-disable-next-line var-name-mixedcase\\n bytes32 private constant _PERMIT_TYPEHASH =\\n keccak256(\\\"Permit(address owner,address spender,uint256 value,uint256 nonce,uint256 deadline)\\\");\\n /**\\n * @dev In previous versions `_PERMIT_TYPEHASH` was declared as `immutable`.\\n * However, to ensure consistency with the upgradeable transpiler, we will continue\\n * to reserve a slot.\\n * @custom:oz-renamed-from _PERMIT_TYPEHASH\\n */\\n // solhint-disable-next-line var-name-mixedcase\\n bytes32 private _PERMIT_TYPEHASH_DEPRECATED_SLOT;\\n\\n /**\\n * @dev Initializes the {EIP712} domain separator using the `name` parameter, and setting `version` to `\\\"1\\\"`.\\n *\\n * It's a good idea to use the same `name` that is defined as the ERC20 token name.\\n */\\n function __ERC20Permit_init(string memory name) internal onlyInitializing {\\n __EIP712_init_unchained(name, \\\"1\\\");\\n }\\n\\n function __ERC20Permit_init_unchained(string memory) internal onlyInitializing {}\\n\\n /**\\n * @dev See {IERC20Permit-permit}.\\n */\\n function permit(\\n address owner,\\n address spender,\\n uint256 value,\\n uint256 deadline,\\n uint8 v,\\n bytes32 r,\\n bytes32 s\\n ) public virtual override {\\n require(block.timestamp <= deadline, \\\"ERC20Permit: expired deadline\\\");\\n\\n bytes32 structHash = keccak256(abi.encode(_PERMIT_TYPEHASH, owner, spender, value, _useNonce(owner), deadline));\\n\\n bytes32 hash = _hashTypedDataV4(structHash);\\n\\n address signer = ECDSAUpgradeable.recover(hash, v, r, s);\\n require(signer == owner, \\\"ERC20Permit: invalid signature\\\");\\n\\n _approve(owner, spender, value);\\n }\\n\\n /**\\n * @dev See {IERC20Permit-nonces}.\\n */\\n function nonces(address owner) public view virtual override returns (uint256) {\\n return _nonces[owner].current();\\n }\\n\\n /**\\n * @dev See {IERC20Permit-DOMAIN_SEPARATOR}.\\n */\\n // solhint-disable-next-line func-name-mixedcase\\n function DOMAIN_SEPARATOR() external view override returns (bytes32) {\\n return _domainSeparatorV4();\\n }\\n\\n /**\\n * @dev \\\"Consume a nonce\\\": return the current value and increment.\\n *\\n * _Available since v4.1._\\n */\\n function _useNonce(address owner) internal virtual returns (uint256 current) {\\n CountersUpgradeable.Counter storage nonce = _nonces[owner];\\n current = nonce.current();\\n nonce.increment();\\n }\\n\\n /**\\n * @dev This empty reserved space is put in place to allow future versions to add new\\n * variables without shifting down storage in the inheritance chain.\\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\\n */\\n uint256[49] private __gap;\\n}\\n\",\"keccak256\":\"0x564385ebed633694decce3e13d687f3ac7e8eaef64f7a504bfb3f03ad210601f\",\"license\":\"MIT\"},\"@openzeppelin/contracts-upgradeable/token/ERC20/extensions/draft-IERC20PermitUpgradeable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (token/ERC20/extensions/draft-IERC20Permit.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Interface of the ERC20 Permit extension allowing approvals to be made via signatures, as defined in\\n * https://eips.ethereum.org/EIPS/eip-2612[EIP-2612].\\n *\\n * Adds the {permit} method, which can be used to change an account's ERC20 allowance (see {IERC20-allowance}) by\\n * presenting a message signed by the account. By not relying on {IERC20-approve}, the token holder account doesn't\\n * need to send a transaction, and thus is not required to hold Ether at all.\\n */\\ninterface IERC20PermitUpgradeable {\\n /**\\n * @dev Sets `value` as the allowance of `spender` over ``owner``'s tokens,\\n * given ``owner``'s signed approval.\\n *\\n * IMPORTANT: The same issues {IERC20-approve} has related to transaction\\n * ordering also apply here.\\n *\\n * Emits an {Approval} event.\\n *\\n * Requirements:\\n *\\n * - `spender` cannot be the zero address.\\n * - `deadline` must be a timestamp in the future.\\n * - `v`, `r` and `s` must be a valid `secp256k1` signature from `owner`\\n * over the EIP712-formatted function arguments.\\n * - the signature must use ``owner``'s current nonce (see {nonces}).\\n *\\n * For more information on the signature format, see the\\n * https://eips.ethereum.org/EIPS/eip-2612#specification[relevant EIP\\n * section].\\n */\\n function permit(\\n address owner,\\n address spender,\\n uint256 value,\\n uint256 deadline,\\n uint8 v,\\n bytes32 r,\\n bytes32 s\\n ) external;\\n\\n /**\\n * @dev Returns the current nonce for `owner`. This value must be\\n * included whenever a signature is generated for {permit}.\\n *\\n * Every successful call to {permit} increases ``owner``'s nonce by one. This\\n * prevents a signature from being used multiple times.\\n */\\n function nonces(address owner) external view returns (uint256);\\n\\n /**\\n * @dev Returns the domain separator used in the encoding of the signature for {permit}, as defined by {EIP712}.\\n */\\n // solhint-disable-next-line func-name-mixedcase\\n function DOMAIN_SEPARATOR() external view returns (bytes32);\\n}\\n\",\"keccak256\":\"0xcc70d8e2281fb3ff69e8ab242500f10142cd0a7fa8dd9e45882be270d4d09024\",\"license\":\"MIT\"},\"@openzeppelin/contracts-upgradeable/utils/AddressUpgradeable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.7.0) (utils/Address.sol)\\n\\npragma solidity ^0.8.1;\\n\\n/**\\n * @dev Collection of functions related to the address type\\n */\\nlibrary AddressUpgradeable {\\n /**\\n * @dev Returns true if `account` is a contract.\\n *\\n * [IMPORTANT]\\n * ====\\n * It is unsafe to assume that an address for which this function returns\\n * false is an externally-owned account (EOA) and not a contract.\\n *\\n * Among others, `isContract` will return false for the following\\n * types of addresses:\\n *\\n * - an externally-owned account\\n * - a contract in construction\\n * - an address where a contract will be created\\n * - an address where a contract lived, but was destroyed\\n * ====\\n *\\n * [IMPORTANT]\\n * ====\\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\\n *\\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\\n * constructor.\\n * ====\\n */\\n function isContract(address account) internal view returns (bool) {\\n // This method relies on extcodesize/address.code.length, which returns 0\\n // for contracts in construction, since the code is only stored at the end\\n // of the constructor execution.\\n\\n return account.code.length > 0;\\n }\\n\\n /**\\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\\n * `recipient`, forwarding all available gas and reverting on errors.\\n *\\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\\n * imposed by `transfer`, making them unable to receive funds via\\n * `transfer`. {sendValue} removes this limitation.\\n *\\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\\n *\\n * IMPORTANT: because control is transferred to `recipient`, care must be\\n * taken to not create reentrancy vulnerabilities. Consider using\\n * {ReentrancyGuard} or the\\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\\n */\\n function sendValue(address payable recipient, uint256 amount) internal {\\n require(address(this).balance >= amount, \\\"Address: insufficient balance\\\");\\n\\n (bool success, ) = recipient.call{value: amount}(\\\"\\\");\\n require(success, \\\"Address: unable to send value, recipient may have reverted\\\");\\n }\\n\\n /**\\n * @dev Performs a Solidity function call using a low level `call`. A\\n * plain `call` is an unsafe replacement for a function call: use this\\n * function instead.\\n *\\n * If `target` reverts with a revert reason, it is bubbled up by this\\n * function (like regular Solidity function calls).\\n *\\n * Returns the raw returned data. To convert to the expected return value,\\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\\n *\\n * Requirements:\\n *\\n * - `target` must be a contract.\\n * - calling `target` with `data` must not revert.\\n *\\n * _Available since v3.1._\\n */\\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\\n return functionCall(target, data, \\\"Address: low-level call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\\n * `errorMessage` as a fallback revert reason when `target` reverts.\\n *\\n * _Available since v3.1._\\n */\\n function functionCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n return functionCallWithValue(target, data, 0, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but also transferring `value` wei to `target`.\\n *\\n * Requirements:\\n *\\n * - the calling contract must have an ETH balance of at least `value`.\\n * - the called Solidity function must be `payable`.\\n *\\n * _Available since v3.1._\\n */\\n function functionCallWithValue(\\n address target,\\n bytes memory data,\\n uint256 value\\n ) internal returns (bytes memory) {\\n return functionCallWithValue(target, data, value, \\\"Address: low-level call with value failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\\n * with `errorMessage` as a fallback revert reason when `target` reverts.\\n *\\n * _Available since v3.1._\\n */\\n function functionCallWithValue(\\n address target,\\n bytes memory data,\\n uint256 value,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n require(address(this).balance >= value, \\\"Address: insufficient balance for call\\\");\\n require(isContract(target), \\\"Address: call to non-contract\\\");\\n\\n (bool success, bytes memory returndata) = target.call{value: value}(data);\\n return verifyCallResult(success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but performing a static call.\\n *\\n * _Available since v3.3._\\n */\\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\\n return functionStaticCall(target, data, \\\"Address: low-level static call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\\n * but performing a static call.\\n *\\n * _Available since v3.3._\\n */\\n function functionStaticCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal view returns (bytes memory) {\\n require(isContract(target), \\\"Address: static call to non-contract\\\");\\n\\n (bool success, bytes memory returndata) = target.staticcall(data);\\n return verifyCallResult(success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the\\n * revert reason using the provided one.\\n *\\n * _Available since v4.3._\\n */\\n function verifyCallResult(\\n bool success,\\n bytes memory returndata,\\n string memory errorMessage\\n ) internal pure returns (bytes memory) {\\n if (success) {\\n return returndata;\\n } else {\\n // Look for revert reason and bubble it up if present\\n if (returndata.length > 0) {\\n // The easiest way to bubble the revert reason is using memory via assembly\\n /// @solidity memory-safe-assembly\\n assembly {\\n let returndata_size := mload(returndata)\\n revert(add(32, returndata), returndata_size)\\n }\\n } else {\\n revert(errorMessage);\\n }\\n }\\n }\\n}\\n\",\"keccak256\":\"0x611aa3f23e59cfdd1863c536776407b3e33d695152a266fa7cfb34440a29a8a3\",\"license\":\"MIT\"},\"@openzeppelin/contracts-upgradeable/utils/ContextUpgradeable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)\\n\\npragma solidity ^0.8.0;\\nimport \\\"../proxy/utils/Initializable.sol\\\";\\n\\n/**\\n * @dev Provides information about the current execution context, including the\\n * sender of the transaction and its data. While these are generally available\\n * via msg.sender and msg.data, they should not be accessed in such a direct\\n * manner, since when dealing with meta-transactions the account sending and\\n * paying for execution may not be the actual sender (as far as an application\\n * is concerned).\\n *\\n * This contract is only required for intermediate, library-like contracts.\\n */\\nabstract contract ContextUpgradeable is Initializable {\\n function __Context_init() internal onlyInitializing {\\n }\\n\\n function __Context_init_unchained() internal onlyInitializing {\\n }\\n function _msgSender() internal view virtual returns (address) {\\n return msg.sender;\\n }\\n\\n function _msgData() internal view virtual returns (bytes calldata) {\\n return msg.data;\\n }\\n\\n /**\\n * @dev This empty reserved space is put in place to allow future versions to add new\\n * variables without shifting down storage in the inheritance chain.\\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\\n */\\n uint256[50] private __gap;\\n}\\n\",\"keccak256\":\"0x963ea7f0b48b032eef72fe3a7582edf78408d6f834115b9feadd673a4d5bd149\",\"license\":\"MIT\"},\"@openzeppelin/contracts-upgradeable/utils/CountersUpgradeable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (utils/Counters.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @title Counters\\n * @author Matt Condon (@shrugs)\\n * @dev Provides counters that can only be incremented, decremented or reset. This can be used e.g. to track the number\\n * of elements in a mapping, issuing ERC721 ids, or counting request ids.\\n *\\n * Include with `using Counters for Counters.Counter;`\\n */\\nlibrary CountersUpgradeable {\\n struct Counter {\\n // This variable should never be directly accessed by users of the library: interactions must be restricted to\\n // the library's function. As of Solidity v0.5.2, this cannot be enforced, though there is a proposal to add\\n // this feature: see https://github.com/ethereum/solidity/issues/4637\\n uint256 _value; // default: 0\\n }\\n\\n function current(Counter storage counter) internal view returns (uint256) {\\n return counter._value;\\n }\\n\\n function increment(Counter storage counter) internal {\\n unchecked {\\n counter._value += 1;\\n }\\n }\\n\\n function decrement(Counter storage counter) internal {\\n uint256 value = counter._value;\\n require(value > 0, \\\"Counter: decrement overflow\\\");\\n unchecked {\\n counter._value = value - 1;\\n }\\n }\\n\\n function reset(Counter storage counter) internal {\\n counter._value = 0;\\n }\\n}\\n\",\"keccak256\":\"0x798741e231b22b81e2dd2eddaaf8832dee4baf5cd8e2dbaa5c1dd12a1c053c4d\",\"license\":\"MIT\"},\"@openzeppelin/contracts-upgradeable/utils/StringsUpgradeable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.7.0) (utils/Strings.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev String operations.\\n */\\nlibrary StringsUpgradeable {\\n bytes16 private constant _HEX_SYMBOLS = \\\"0123456789abcdef\\\";\\n uint8 private constant _ADDRESS_LENGTH = 20;\\n\\n /**\\n * @dev Converts a `uint256` to its ASCII `string` decimal representation.\\n */\\n function toString(uint256 value) internal pure returns (string memory) {\\n // Inspired by OraclizeAPI's implementation - MIT licence\\n // https://github.com/oraclize/ethereum-api/blob/b42146b063c7d6ee1358846c198246239e9360e8/oraclizeAPI_0.4.25.sol\\n\\n if (value == 0) {\\n return \\\"0\\\";\\n }\\n uint256 temp = value;\\n uint256 digits;\\n while (temp != 0) {\\n digits++;\\n temp /= 10;\\n }\\n bytes memory buffer = new bytes(digits);\\n while (value != 0) {\\n digits -= 1;\\n buffer[digits] = bytes1(uint8(48 + uint256(value % 10)));\\n value /= 10;\\n }\\n return string(buffer);\\n }\\n\\n /**\\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation.\\n */\\n function toHexString(uint256 value) internal pure returns (string memory) {\\n if (value == 0) {\\n return \\\"0x00\\\";\\n }\\n uint256 temp = value;\\n uint256 length = 0;\\n while (temp != 0) {\\n length++;\\n temp >>= 8;\\n }\\n return toHexString(value, length);\\n }\\n\\n /**\\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length.\\n */\\n function toHexString(uint256 value, uint256 length) internal pure returns (string memory) {\\n bytes memory buffer = new bytes(2 * length + 2);\\n buffer[0] = \\\"0\\\";\\n buffer[1] = \\\"x\\\";\\n for (uint256 i = 2 * length + 1; i > 1; --i) {\\n buffer[i] = _HEX_SYMBOLS[value & 0xf];\\n value >>= 4;\\n }\\n require(value == 0, \\\"Strings: hex length insufficient\\\");\\n return string(buffer);\\n }\\n\\n /**\\n * @dev Converts an `address` with fixed length of 20 bytes to its not checksummed ASCII `string` hexadecimal representation.\\n */\\n function toHexString(address addr) internal pure returns (string memory) {\\n return toHexString(uint256(uint160(addr)), _ADDRESS_LENGTH);\\n }\\n}\\n\",\"keccak256\":\"0xea5339a7fff0ed42b45be56a88efdd0b2ddde9fa480dc99fef9a6a4c5b776863\",\"license\":\"MIT\"},\"@openzeppelin/contracts-upgradeable/utils/cryptography/ECDSAUpgradeable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.7.0) (utils/cryptography/ECDSA.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../StringsUpgradeable.sol\\\";\\n\\n/**\\n * @dev Elliptic Curve Digital Signature Algorithm (ECDSA) operations.\\n *\\n * These functions can be used to verify that a message was signed by the holder\\n * of the private keys of a given address.\\n */\\nlibrary ECDSAUpgradeable {\\n enum RecoverError {\\n NoError,\\n InvalidSignature,\\n InvalidSignatureLength,\\n InvalidSignatureS,\\n InvalidSignatureV\\n }\\n\\n function _throwError(RecoverError error) private pure {\\n if (error == RecoverError.NoError) {\\n return; // no error: do nothing\\n } else if (error == RecoverError.InvalidSignature) {\\n revert(\\\"ECDSA: invalid signature\\\");\\n } else if (error == RecoverError.InvalidSignatureLength) {\\n revert(\\\"ECDSA: invalid signature length\\\");\\n } else if (error == RecoverError.InvalidSignatureS) {\\n revert(\\\"ECDSA: invalid signature 's' value\\\");\\n } else if (error == RecoverError.InvalidSignatureV) {\\n revert(\\\"ECDSA: invalid signature 'v' value\\\");\\n }\\n }\\n\\n /**\\n * @dev Returns the address that signed a hashed message (`hash`) with\\n * `signature` or error string. This address can then be used for verification purposes.\\n *\\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\\n * this function rejects them by requiring the `s` value to be in the lower\\n * half order, and the `v` value to be either 27 or 28.\\n *\\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\\n * verification to be secure: it is possible to craft signatures that\\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\\n * this is by receiving a hash of the original message (which may otherwise\\n * be too long), and then calling {toEthSignedMessageHash} on it.\\n *\\n * Documentation for signature generation:\\n * - with https://web3js.readthedocs.io/en/v1.3.4/web3-eth-accounts.html#sign[Web3.js]\\n * - with https://docs.ethers.io/v5/api/signer/#Signer-signMessage[ethers]\\n *\\n * _Available since v4.3._\\n */\\n function tryRecover(bytes32 hash, bytes memory signature) internal pure returns (address, RecoverError) {\\n // Check the signature length\\n // - case 65: r,s,v signature (standard)\\n // - case 64: r,vs signature (cf https://eips.ethereum.org/EIPS/eip-2098) _Available since v4.1._\\n if (signature.length == 65) {\\n bytes32 r;\\n bytes32 s;\\n uint8 v;\\n // ecrecover takes the signature parameters, and the only way to get them\\n // currently is to use assembly.\\n /// @solidity memory-safe-assembly\\n assembly {\\n r := mload(add(signature, 0x20))\\n s := mload(add(signature, 0x40))\\n v := byte(0, mload(add(signature, 0x60)))\\n }\\n return tryRecover(hash, v, r, s);\\n } else if (signature.length == 64) {\\n bytes32 r;\\n bytes32 vs;\\n // ecrecover takes the signature parameters, and the only way to get them\\n // currently is to use assembly.\\n /// @solidity memory-safe-assembly\\n assembly {\\n r := mload(add(signature, 0x20))\\n vs := mload(add(signature, 0x40))\\n }\\n return tryRecover(hash, r, vs);\\n } else {\\n return (address(0), RecoverError.InvalidSignatureLength);\\n }\\n }\\n\\n /**\\n * @dev Returns the address that signed a hashed message (`hash`) with\\n * `signature`. This address can then be used for verification purposes.\\n *\\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\\n * this function rejects them by requiring the `s` value to be in the lower\\n * half order, and the `v` value to be either 27 or 28.\\n *\\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\\n * verification to be secure: it is possible to craft signatures that\\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\\n * this is by receiving a hash of the original message (which may otherwise\\n * be too long), and then calling {toEthSignedMessageHash} on it.\\n */\\n function recover(bytes32 hash, bytes memory signature) internal pure returns (address) {\\n (address recovered, RecoverError error) = tryRecover(hash, signature);\\n _throwError(error);\\n return recovered;\\n }\\n\\n /**\\n * @dev Overload of {ECDSA-tryRecover} that receives the `r` and `vs` short-signature fields separately.\\n *\\n * See https://eips.ethereum.org/EIPS/eip-2098[EIP-2098 short signatures]\\n *\\n * _Available since v4.3._\\n */\\n function tryRecover(\\n bytes32 hash,\\n bytes32 r,\\n bytes32 vs\\n ) internal pure returns (address, RecoverError) {\\n bytes32 s = vs & bytes32(0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff);\\n uint8 v = uint8((uint256(vs) >> 255) + 27);\\n return tryRecover(hash, v, r, s);\\n }\\n\\n /**\\n * @dev Overload of {ECDSA-recover} that receives the `r and `vs` short-signature fields separately.\\n *\\n * _Available since v4.2._\\n */\\n function recover(\\n bytes32 hash,\\n bytes32 r,\\n bytes32 vs\\n ) internal pure returns (address) {\\n (address recovered, RecoverError error) = tryRecover(hash, r, vs);\\n _throwError(error);\\n return recovered;\\n }\\n\\n /**\\n * @dev Overload of {ECDSA-tryRecover} that receives the `v`,\\n * `r` and `s` signature fields separately.\\n *\\n * _Available since v4.3._\\n */\\n function tryRecover(\\n bytes32 hash,\\n uint8 v,\\n bytes32 r,\\n bytes32 s\\n ) internal pure returns (address, RecoverError) {\\n // EIP-2 still allows signature malleability for ecrecover(). Remove this possibility and make the signature\\n // unique. Appendix F in the Ethereum Yellow paper (https://ethereum.github.io/yellowpaper/paper.pdf), defines\\n // the valid range for s in (301): 0 < s < secp256k1n \\u00f7 2 + 1, and for v in (302): v \\u2208 {27, 28}. Most\\n // signatures from current libraries generate a unique signature with an s-value in the lower half order.\\n //\\n // If your library generates malleable signatures, such as s-values in the upper range, calculate a new s-value\\n // with 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141 - s1 and flip v from 27 to 28 or\\n // vice versa. If your library also generates signatures with 0/1 for v instead 27/28, add 27 to v to accept\\n // these malleable signatures as well.\\n if (uint256(s) > 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D576E7357A4501DDFE92F46681B20A0) {\\n return (address(0), RecoverError.InvalidSignatureS);\\n }\\n if (v != 27 && v != 28) {\\n return (address(0), RecoverError.InvalidSignatureV);\\n }\\n\\n // If the signature is valid (and not malleable), return the signer address\\n address signer = ecrecover(hash, v, r, s);\\n if (signer == address(0)) {\\n return (address(0), RecoverError.InvalidSignature);\\n }\\n\\n return (signer, RecoverError.NoError);\\n }\\n\\n /**\\n * @dev Overload of {ECDSA-recover} that receives the `v`,\\n * `r` and `s` signature fields separately.\\n */\\n function recover(\\n bytes32 hash,\\n uint8 v,\\n bytes32 r,\\n bytes32 s\\n ) internal pure returns (address) {\\n (address recovered, RecoverError error) = tryRecover(hash, v, r, s);\\n _throwError(error);\\n return recovered;\\n }\\n\\n /**\\n * @dev Returns an Ethereum Signed Message, created from a `hash`. This\\n * produces hash corresponding to the one signed with the\\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\\n * JSON-RPC method as part of EIP-191.\\n *\\n * See {recover}.\\n */\\n function toEthSignedMessageHash(bytes32 hash) internal pure returns (bytes32) {\\n // 32 is the length in bytes of hash,\\n // enforced by the type signature above\\n return keccak256(abi.encodePacked(\\\"\\\\x19Ethereum Signed Message:\\\\n32\\\", hash));\\n }\\n\\n /**\\n * @dev Returns an Ethereum Signed Message, created from `s`. This\\n * produces hash corresponding to the one signed with the\\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\\n * JSON-RPC method as part of EIP-191.\\n *\\n * See {recover}.\\n */\\n function toEthSignedMessageHash(bytes memory s) internal pure returns (bytes32) {\\n return keccak256(abi.encodePacked(\\\"\\\\x19Ethereum Signed Message:\\\\n\\\", StringsUpgradeable.toString(s.length), s));\\n }\\n\\n /**\\n * @dev Returns an Ethereum Signed Typed Data, created from a\\n * `domainSeparator` and a `structHash`. This produces hash corresponding\\n * to the one signed with the\\n * https://eips.ethereum.org/EIPS/eip-712[`eth_signTypedData`]\\n * JSON-RPC method as part of EIP-712.\\n *\\n * See {recover}.\\n */\\n function toTypedDataHash(bytes32 domainSeparator, bytes32 structHash) internal pure returns (bytes32) {\\n return keccak256(abi.encodePacked(\\\"\\\\x19\\\\x01\\\", domainSeparator, structHash));\\n }\\n}\\n\",\"keccak256\":\"0xe8c62ca00ed2d0a4d9b7e3c4bf7d62c821618b2cdb3c844da91a1193986851bf\",\"license\":\"MIT\"},\"@openzeppelin/contracts-upgradeable/utils/cryptography/draft-EIP712Upgradeable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (utils/cryptography/draft-EIP712.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"./ECDSAUpgradeable.sol\\\";\\nimport \\\"../../proxy/utils/Initializable.sol\\\";\\n\\n/**\\n * @dev https://eips.ethereum.org/EIPS/eip-712[EIP 712] is a standard for hashing and signing of typed structured data.\\n *\\n * The encoding specified in the EIP is very generic, and such a generic implementation in Solidity is not feasible,\\n * thus this contract does not implement the encoding itself. Protocols need to implement the type-specific encoding\\n * they need in their contracts using a combination of `abi.encode` and `keccak256`.\\n *\\n * This contract implements the EIP 712 domain separator ({_domainSeparatorV4}) that is used as part of the encoding\\n * scheme, and the final step of the encoding to obtain the message digest that is then signed via ECDSA\\n * ({_hashTypedDataV4}).\\n *\\n * The implementation of the domain separator was designed to be as efficient as possible while still properly updating\\n * the chain id to protect against replay attacks on an eventual fork of the chain.\\n *\\n * NOTE: This contract implements the version of the encoding known as \\\"v4\\\", as implemented by the JSON RPC method\\n * https://docs.metamask.io/guide/signing-data.html[`eth_signTypedDataV4` in MetaMask].\\n *\\n * _Available since v3.4._\\n *\\n * @custom:storage-size 52\\n */\\nabstract contract EIP712Upgradeable is Initializable {\\n /* solhint-disable var-name-mixedcase */\\n bytes32 private _HASHED_NAME;\\n bytes32 private _HASHED_VERSION;\\n bytes32 private constant _TYPE_HASH = keccak256(\\\"EIP712Domain(string name,string version,uint256 chainId,address verifyingContract)\\\");\\n\\n /* solhint-enable var-name-mixedcase */\\n\\n /**\\n * @dev Initializes the domain separator and parameter caches.\\n *\\n * The meaning of `name` and `version` is specified in\\n * https://eips.ethereum.org/EIPS/eip-712#definition-of-domainseparator[EIP 712]:\\n *\\n * - `name`: the user readable name of the signing domain, i.e. the name of the DApp or the protocol.\\n * - `version`: the current major version of the signing domain.\\n *\\n * NOTE: These parameters cannot be changed except through a xref:learn::upgrading-smart-contracts.adoc[smart\\n * contract upgrade].\\n */\\n function __EIP712_init(string memory name, string memory version) internal onlyInitializing {\\n __EIP712_init_unchained(name, version);\\n }\\n\\n function __EIP712_init_unchained(string memory name, string memory version) internal onlyInitializing {\\n bytes32 hashedName = keccak256(bytes(name));\\n bytes32 hashedVersion = keccak256(bytes(version));\\n _HASHED_NAME = hashedName;\\n _HASHED_VERSION = hashedVersion;\\n }\\n\\n /**\\n * @dev Returns the domain separator for the current chain.\\n */\\n function _domainSeparatorV4() internal view returns (bytes32) {\\n return _buildDomainSeparator(_TYPE_HASH, _EIP712NameHash(), _EIP712VersionHash());\\n }\\n\\n function _buildDomainSeparator(\\n bytes32 typeHash,\\n bytes32 nameHash,\\n bytes32 versionHash\\n ) private view returns (bytes32) {\\n return keccak256(abi.encode(typeHash, nameHash, versionHash, block.chainid, address(this)));\\n }\\n\\n /**\\n * @dev Given an already https://eips.ethereum.org/EIPS/eip-712#definition-of-hashstruct[hashed struct], this\\n * function returns the hash of the fully encoded EIP712 message for this domain.\\n *\\n * This hash can be used together with {ECDSA-recover} to obtain the signer of a message. For example:\\n *\\n * ```solidity\\n * bytes32 digest = _hashTypedDataV4(keccak256(abi.encode(\\n * keccak256(\\\"Mail(address to,string contents)\\\"),\\n * mailTo,\\n * keccak256(bytes(mailContents))\\n * )));\\n * address signer = ECDSA.recover(digest, signature);\\n * ```\\n */\\n function _hashTypedDataV4(bytes32 structHash) internal view virtual returns (bytes32) {\\n return ECDSAUpgradeable.toTypedDataHash(_domainSeparatorV4(), structHash);\\n }\\n\\n /**\\n * @dev The hash of the name parameter for the EIP712 domain.\\n *\\n * NOTE: This function reads from storage by default, but can be redefined to return a constant value if gas costs\\n * are a concern.\\n */\\n function _EIP712NameHash() internal virtual view returns (bytes32) {\\n return _HASHED_NAME;\\n }\\n\\n /**\\n * @dev The hash of the version parameter for the EIP712 domain.\\n *\\n * NOTE: This function reads from storage by default, but can be redefined to return a constant value if gas costs\\n * are a concern.\\n */\\n function _EIP712VersionHash() internal virtual view returns (bytes32) {\\n return _HASHED_VERSION;\\n }\\n\\n /**\\n * @dev This empty reserved space is put in place to allow future versions to add new\\n * variables without shifting down storage in the inheritance chain.\\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\\n */\\n uint256[50] private __gap;\\n}\\n\",\"keccak256\":\"0xaf5a96100f421d61693605349511e43221d3c2e47d4b3efa87af2b936e2567fc\",\"license\":\"MIT\"},\"@openzeppelin/contracts/token/ERC20/IERC20.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.6.0) (token/ERC20/IERC20.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Interface of the ERC20 standard as defined in the EIP.\\n */\\ninterface IERC20 {\\n /**\\n * @dev Emitted when `value` tokens are moved from one account (`from`) to\\n * another (`to`).\\n *\\n * Note that `value` may be zero.\\n */\\n event Transfer(address indexed from, address indexed to, uint256 value);\\n\\n /**\\n * @dev Emitted when the allowance of a `spender` for an `owner` is set by\\n * a call to {approve}. `value` is the new allowance.\\n */\\n event Approval(address indexed owner, address indexed spender, uint256 value);\\n\\n /**\\n * @dev Returns the amount of tokens in existence.\\n */\\n function totalSupply() external view returns (uint256);\\n\\n /**\\n * @dev Returns the amount of tokens owned by `account`.\\n */\\n function balanceOf(address account) external view returns (uint256);\\n\\n /**\\n * @dev Moves `amount` tokens from the caller's account to `to`.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * Emits a {Transfer} event.\\n */\\n function transfer(address to, uint256 amount) external returns (bool);\\n\\n /**\\n * @dev Returns the remaining number of tokens that `spender` will be\\n * allowed to spend on behalf of `owner` through {transferFrom}. This is\\n * zero by default.\\n *\\n * This value changes when {approve} or {transferFrom} are called.\\n */\\n function allowance(address owner, address spender) external view returns (uint256);\\n\\n /**\\n * @dev Sets `amount` as the allowance of `spender` over the caller's tokens.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * IMPORTANT: Beware that changing an allowance with this method brings the risk\\n * that someone may use both the old and the new allowance by unfortunate\\n * transaction ordering. One possible solution to mitigate this race\\n * condition is to first reduce the spender's allowance to 0 and set the\\n * desired value afterwards:\\n * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729\\n *\\n * Emits an {Approval} event.\\n */\\n function approve(address spender, uint256 amount) external returns (bool);\\n\\n /**\\n * @dev Moves `amount` tokens from `from` to `to` using the\\n * allowance mechanism. `amount` is then deducted from the caller's\\n * allowance.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * Emits a {Transfer} event.\\n */\\n function transferFrom(\\n address from,\\n address to,\\n uint256 amount\\n ) external returns (bool);\\n}\\n\",\"keccak256\":\"0x9750c6b834f7b43000631af5cc30001c5f547b3ceb3635488f140f60e897ea6b\",\"license\":\"MIT\"},\"@openzeppelin/contracts/token/ERC20/extensions/draft-IERC20Permit.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (token/ERC20/extensions/draft-IERC20Permit.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Interface of the ERC20 Permit extension allowing approvals to be made via signatures, as defined in\\n * https://eips.ethereum.org/EIPS/eip-2612[EIP-2612].\\n *\\n * Adds the {permit} method, which can be used to change an account's ERC20 allowance (see {IERC20-allowance}) by\\n * presenting a message signed by the account. By not relying on {IERC20-approve}, the token holder account doesn't\\n * need to send a transaction, and thus is not required to hold Ether at all.\\n */\\ninterface IERC20Permit {\\n /**\\n * @dev Sets `value` as the allowance of `spender` over ``owner``'s tokens,\\n * given ``owner``'s signed approval.\\n *\\n * IMPORTANT: The same issues {IERC20-approve} has related to transaction\\n * ordering also apply here.\\n *\\n * Emits an {Approval} event.\\n *\\n * Requirements:\\n *\\n * - `spender` cannot be the zero address.\\n * - `deadline` must be a timestamp in the future.\\n * - `v`, `r` and `s` must be a valid `secp256k1` signature from `owner`\\n * over the EIP712-formatted function arguments.\\n * - the signature must use ``owner``'s current nonce (see {nonces}).\\n *\\n * For more information on the signature format, see the\\n * https://eips.ethereum.org/EIPS/eip-2612#specification[relevant EIP\\n * section].\\n */\\n function permit(\\n address owner,\\n address spender,\\n uint256 value,\\n uint256 deadline,\\n uint8 v,\\n bytes32 r,\\n bytes32 s\\n ) external;\\n\\n /**\\n * @dev Returns the current nonce for `owner`. This value must be\\n * included whenever a signature is generated for {permit}.\\n *\\n * Every successful call to {permit} increases ``owner``'s nonce by one. This\\n * prevents a signature from being used multiple times.\\n */\\n function nonces(address owner) external view returns (uint256);\\n\\n /**\\n * @dev Returns the domain separator used in the encoding of the signature for {permit}, as defined by {EIP712}.\\n */\\n // solhint-disable-next-line func-name-mixedcase\\n function DOMAIN_SEPARATOR() external view returns (bytes32);\\n}\\n\",\"keccak256\":\"0xf41ca991f30855bf80ffd11e9347856a517b977f0a6c2d52e6421a99b7840329\",\"license\":\"MIT\"},\"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.7.0) (token/ERC20/utils/SafeERC20.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../IERC20.sol\\\";\\nimport \\\"../extensions/draft-IERC20Permit.sol\\\";\\nimport \\\"../../../utils/Address.sol\\\";\\n\\n/**\\n * @title SafeERC20\\n * @dev Wrappers around ERC20 operations that throw on failure (when the token\\n * contract returns false). Tokens that return no value (and instead revert or\\n * throw on failure) are also supported, non-reverting calls are assumed to be\\n * successful.\\n * To use this library you can add a `using SafeERC20 for IERC20;` statement to your contract,\\n * which allows you to call the safe operations as `token.safeTransfer(...)`, etc.\\n */\\nlibrary SafeERC20 {\\n using Address for address;\\n\\n function safeTransfer(\\n IERC20 token,\\n address to,\\n uint256 value\\n ) internal {\\n _callOptionalReturn(token, abi.encodeWithSelector(token.transfer.selector, to, value));\\n }\\n\\n function safeTransferFrom(\\n IERC20 token,\\n address from,\\n address to,\\n uint256 value\\n ) internal {\\n _callOptionalReturn(token, abi.encodeWithSelector(token.transferFrom.selector, from, to, value));\\n }\\n\\n /**\\n * @dev Deprecated. This function has issues similar to the ones found in\\n * {IERC20-approve}, and its usage is discouraged.\\n *\\n * Whenever possible, use {safeIncreaseAllowance} and\\n * {safeDecreaseAllowance} instead.\\n */\\n function safeApprove(\\n IERC20 token,\\n address spender,\\n uint256 value\\n ) internal {\\n // safeApprove should only be called when setting an initial allowance,\\n // or when resetting it to zero. To increase and decrease it, use\\n // 'safeIncreaseAllowance' and 'safeDecreaseAllowance'\\n require(\\n (value == 0) || (token.allowance(address(this), spender) == 0),\\n \\\"SafeERC20: approve from non-zero to non-zero allowance\\\"\\n );\\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, value));\\n }\\n\\n function safeIncreaseAllowance(\\n IERC20 token,\\n address spender,\\n uint256 value\\n ) internal {\\n uint256 newAllowance = token.allowance(address(this), spender) + value;\\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));\\n }\\n\\n function safeDecreaseAllowance(\\n IERC20 token,\\n address spender,\\n uint256 value\\n ) internal {\\n unchecked {\\n uint256 oldAllowance = token.allowance(address(this), spender);\\n require(oldAllowance >= value, \\\"SafeERC20: decreased allowance below zero\\\");\\n uint256 newAllowance = oldAllowance - value;\\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));\\n }\\n }\\n\\n function safePermit(\\n IERC20Permit token,\\n address owner,\\n address spender,\\n uint256 value,\\n uint256 deadline,\\n uint8 v,\\n bytes32 r,\\n bytes32 s\\n ) internal {\\n uint256 nonceBefore = token.nonces(owner);\\n token.permit(owner, spender, value, deadline, v, r, s);\\n uint256 nonceAfter = token.nonces(owner);\\n require(nonceAfter == nonceBefore + 1, \\\"SafeERC20: permit did not succeed\\\");\\n }\\n\\n /**\\n * @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement\\n * on the return value: the return value is optional (but if data is returned, it must not be false).\\n * @param token The token targeted by the call.\\n * @param data The call data (encoded using abi.encode or one of its variants).\\n */\\n function _callOptionalReturn(IERC20 token, bytes memory data) private {\\n // We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since\\n // we're implementing it ourselves. We use {Address.functionCall} to perform this call, which verifies that\\n // the target address contains contract code and also asserts for success in the low-level call.\\n\\n bytes memory returndata = address(token).functionCall(data, \\\"SafeERC20: low-level call failed\\\");\\n if (returndata.length > 0) {\\n // Return data is optional\\n require(abi.decode(returndata, (bool)), \\\"SafeERC20: ERC20 operation did not succeed\\\");\\n }\\n }\\n}\\n\",\"keccak256\":\"0x032807210d1d7d218963d7355d62e021a84bf1b3339f4f50be2f63b53cccaf29\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/Address.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.7.0) (utils/Address.sol)\\n\\npragma solidity ^0.8.1;\\n\\n/**\\n * @dev Collection of functions related to the address type\\n */\\nlibrary Address {\\n /**\\n * @dev Returns true if `account` is a contract.\\n *\\n * [IMPORTANT]\\n * ====\\n * It is unsafe to assume that an address for which this function returns\\n * false is an externally-owned account (EOA) and not a contract.\\n *\\n * Among others, `isContract` will return false for the following\\n * types of addresses:\\n *\\n * - an externally-owned account\\n * - a contract in construction\\n * - an address where a contract will be created\\n * - an address where a contract lived, but was destroyed\\n * ====\\n *\\n * [IMPORTANT]\\n * ====\\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\\n *\\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\\n * constructor.\\n * ====\\n */\\n function isContract(address account) internal view returns (bool) {\\n // This method relies on extcodesize/address.code.length, which returns 0\\n // for contracts in construction, since the code is only stored at the end\\n // of the constructor execution.\\n\\n return account.code.length > 0;\\n }\\n\\n /**\\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\\n * `recipient`, forwarding all available gas and reverting on errors.\\n *\\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\\n * imposed by `transfer`, making them unable to receive funds via\\n * `transfer`. {sendValue} removes this limitation.\\n *\\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\\n *\\n * IMPORTANT: because control is transferred to `recipient`, care must be\\n * taken to not create reentrancy vulnerabilities. Consider using\\n * {ReentrancyGuard} or the\\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\\n */\\n function sendValue(address payable recipient, uint256 amount) internal {\\n require(address(this).balance >= amount, \\\"Address: insufficient balance\\\");\\n\\n (bool success, ) = recipient.call{value: amount}(\\\"\\\");\\n require(success, \\\"Address: unable to send value, recipient may have reverted\\\");\\n }\\n\\n /**\\n * @dev Performs a Solidity function call using a low level `call`. A\\n * plain `call` is an unsafe replacement for a function call: use this\\n * function instead.\\n *\\n * If `target` reverts with a revert reason, it is bubbled up by this\\n * function (like regular Solidity function calls).\\n *\\n * Returns the raw returned data. To convert to the expected return value,\\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\\n *\\n * Requirements:\\n *\\n * - `target` must be a contract.\\n * - calling `target` with `data` must not revert.\\n *\\n * _Available since v3.1._\\n */\\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\\n return functionCall(target, data, \\\"Address: low-level call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\\n * `errorMessage` as a fallback revert reason when `target` reverts.\\n *\\n * _Available since v3.1._\\n */\\n function functionCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n return functionCallWithValue(target, data, 0, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but also transferring `value` wei to `target`.\\n *\\n * Requirements:\\n *\\n * - the calling contract must have an ETH balance of at least `value`.\\n * - the called Solidity function must be `payable`.\\n *\\n * _Available since v3.1._\\n */\\n function functionCallWithValue(\\n address target,\\n bytes memory data,\\n uint256 value\\n ) internal returns (bytes memory) {\\n return functionCallWithValue(target, data, value, \\\"Address: low-level call with value failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\\n * with `errorMessage` as a fallback revert reason when `target` reverts.\\n *\\n * _Available since v3.1._\\n */\\n function functionCallWithValue(\\n address target,\\n bytes memory data,\\n uint256 value,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n require(address(this).balance >= value, \\\"Address: insufficient balance for call\\\");\\n require(isContract(target), \\\"Address: call to non-contract\\\");\\n\\n (bool success, bytes memory returndata) = target.call{value: value}(data);\\n return verifyCallResult(success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but performing a static call.\\n *\\n * _Available since v3.3._\\n */\\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\\n return functionStaticCall(target, data, \\\"Address: low-level static call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\\n * but performing a static call.\\n *\\n * _Available since v3.3._\\n */\\n function functionStaticCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal view returns (bytes memory) {\\n require(isContract(target), \\\"Address: static call to non-contract\\\");\\n\\n (bool success, bytes memory returndata) = target.staticcall(data);\\n return verifyCallResult(success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but performing a delegate call.\\n *\\n * _Available since v3.4._\\n */\\n function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {\\n return functionDelegateCall(target, data, \\\"Address: low-level delegate call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\\n * but performing a delegate call.\\n *\\n * _Available since v3.4._\\n */\\n function functionDelegateCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n require(isContract(target), \\\"Address: delegate call to non-contract\\\");\\n\\n (bool success, bytes memory returndata) = target.delegatecall(data);\\n return verifyCallResult(success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the\\n * revert reason using the provided one.\\n *\\n * _Available since v4.3._\\n */\\n function verifyCallResult(\\n bool success,\\n bytes memory returndata,\\n string memory errorMessage\\n ) internal pure returns (bytes memory) {\\n if (success) {\\n return returndata;\\n } else {\\n // Look for revert reason and bubble it up if present\\n if (returndata.length > 0) {\\n // The easiest way to bubble the revert reason is using memory via assembly\\n /// @solidity memory-safe-assembly\\n assembly {\\n let returndata_size := mload(returndata)\\n revert(add(32, returndata), returndata_size)\\n }\\n } else {\\n revert(errorMessage);\\n }\\n }\\n }\\n}\\n\",\"keccak256\":\"0xd6153ce99bcdcce22b124f755e72553295be6abcd63804cfdffceb188b8bef10\",\"license\":\"MIT\"},\"contracts/agToken/AgTokenSideChainMultiBridge.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-3.0\\n\\npragma solidity ^0.8.12;\\n\\nimport \\\"./BaseAgTokenSideChain.sol\\\";\\nimport \\\"@openzeppelin/contracts/token/ERC20/IERC20.sol\\\";\\nimport \\\"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\\\";\\n\\n/// @title AgTokenSideChainMultiBridge\\n/// @author Angle Labs, Inc.\\n/// @notice Contract for Angle agTokens on other chains than Ethereum mainnet\\n/// @dev This contract supports bridge tokens having a minting right on the stablecoin (also referred to as the canonical\\n/// or the native token)\\n/// @dev References:\\n/// - FRAX implementation: https://polygonscan.com/address/0x45c32fA6DF82ead1e2EF74d17b76547EDdFaFF89#code\\n/// - QiDAO implementation: https://snowtrace.io/address/0x5c49b268c9841AFF1Cc3B0a418ff5c3442eE3F3b#code\\ncontract AgTokenSideChainMultiBridge is BaseAgTokenSideChain {\\n using SafeERC20 for IERC20;\\n\\n /// @notice Base used for fee computation\\n uint256 public constant BASE_PARAMS = 10**9;\\n\\n // =============================== Bridging Data ===============================\\n\\n /// @notice Struct with some data about a specific bridge token\\n struct BridgeDetails {\\n // Limit on the balance of bridge token held by the contract: it is designed\\n // to reduce the exposure of the system to hacks\\n uint256 limit;\\n // Limit on the hourly volume of token minted through this bridge\\n // Technically the limit over a rolling hour is hourlyLimit x2 as hourly limit\\n // is enforced only between x:00 and x+1:00\\n uint256 hourlyLimit;\\n // Fee taken for swapping in and out the token\\n uint64 fee;\\n // Whether the associated token is allowed or not\\n bool allowed;\\n // Whether swapping in and out from the associated token is paused or not\\n bool paused;\\n }\\n\\n /// @notice Maps a bridge token to data\\n mapping(address => BridgeDetails) public bridges;\\n /// @notice List of all bridge tokens\\n address[] public bridgeTokensList;\\n /// @notice Maps a bridge token to the associated hourly volume\\n mapping(address => mapping(uint256 => uint256)) public usage;\\n /// @notice Maps an address to whether it is exempt of fees for when it comes to swapping in and out\\n mapping(address => uint256) public isFeeExempt;\\n /// @notice Limit to the amount of tokens that can be sent from that chain to another chain\\n uint256 public chainTotalHourlyLimit;\\n /// @notice Usage per hour on that chain. Maps an hourly timestamp to the total volume swapped out on the chain\\n mapping(uint256 => uint256) public chainTotalUsage;\\n\\n // ================================== Events ===================================\\n\\n event BridgeTokenAdded(address indexed bridgeToken, uint256 limit, uint256 hourlyLimit, uint64 fee, bool paused);\\n event BridgeTokenToggled(address indexed bridgeToken, bool toggleStatus);\\n event BridgeTokenRemoved(address indexed bridgeToken);\\n event BridgeTokenFeeUpdated(address indexed bridgeToken, uint64 fee);\\n event BridgeTokenLimitUpdated(address indexed bridgeToken, uint256 limit);\\n event BridgeTokenHourlyLimitUpdated(address indexed bridgeToken, uint256 hourlyLimit);\\n event HourlyLimitUpdated(uint256 hourlyLimit);\\n event Recovered(address indexed token, address indexed to, uint256 amount);\\n event FeeToggled(address indexed theAddress, uint256 toggleStatus);\\n\\n // =============================== Errors ================================\\n\\n error AssetStillControlledInReserves();\\n error HourlyLimitExceeded();\\n error InvalidToken();\\n error NotGovernor();\\n error NotGovernorOrGuardian();\\n error TooBigAmount();\\n error TooHighParameterValue();\\n error ZeroAddress();\\n\\n // ============================= Constructor ===================================\\n\\n /// @notice Initializes the `AgToken` contract\\n /// @param name_ Name of the token\\n /// @param symbol_ Symbol of the token\\n /// @param _treasury Reference to the `Treasury` contract associated to this agToken\\n /// @dev By default, agTokens are ERC-20 tokens with 18 decimals\\n function initialize(\\n string memory name_,\\n string memory symbol_,\\n address _treasury\\n ) external {\\n _initialize(name_, symbol_, _treasury);\\n }\\n\\n // =============================== Modifiers ===================================\\n\\n /// @notice Checks whether the `msg.sender` has the governor role or not\\n modifier onlyGovernor() {\\n if (!ITreasury(treasury).isGovernor(msg.sender)) revert NotGovernor();\\n _;\\n }\\n\\n /// @notice Checks whether the `msg.sender` has the governor role or the guardian role\\n modifier onlyGovernorOrGuardian() {\\n if (!ITreasury(treasury).isGovernorOrGuardian(msg.sender)) revert NotGovernorOrGuardian();\\n _;\\n }\\n\\n // ==================== External Permissionless Functions ======================\\n\\n /// @notice Returns the list of all supported bridge tokens\\n /// @dev Helpful for UIs\\n function allBridgeTokens() external view returns (address[] memory) {\\n return bridgeTokensList;\\n }\\n\\n /// @notice Returns the current volume for a bridge, for the current hour\\n /// @param bridgeToken Bridge used to mint\\n /// @dev Helpful for UIs\\n function currentUsage(address bridgeToken) external view returns (uint256) {\\n return usage[bridgeToken][block.timestamp / 3600];\\n }\\n\\n /// @notice Returns the current total volume on the chain for the current hour\\n /// @dev Helpful for UIs\\n function currentTotalUsage() external view returns (uint256) {\\n return chainTotalUsage[block.timestamp / 3600];\\n }\\n\\n /// @notice Mints the canonical token from a supported bridge token\\n /// @param bridgeToken Bridge token to use to mint\\n /// @param amount Amount of bridge tokens to send\\n /// @param to Address to which the stablecoin should be sent\\n /// @return Amount of the canonical stablecoin actually minted\\n /// @dev Some fees may be taken by the protocol depending on the token used and on the address calling\\n function swapIn(\\n address bridgeToken,\\n uint256 amount,\\n address to\\n ) external returns (uint256) {\\n BridgeDetails memory bridgeDetails = bridges[bridgeToken];\\n if (!bridgeDetails.allowed || bridgeDetails.paused) revert InvalidToken();\\n uint256 balance = IERC20(bridgeToken).balanceOf(address(this));\\n if (balance + amount > bridgeDetails.limit) {\\n // In case someone maliciously sends tokens to this contract\\n // Or the limit changes\\n if (bridgeDetails.limit > balance) amount = bridgeDetails.limit - balance;\\n else {\\n amount = 0;\\n }\\n }\\n\\n // Checking requirement on the hourly volume\\n uint256 hour = block.timestamp / 3600;\\n uint256 hourlyUsage = usage[bridgeToken][hour];\\n if (hourlyUsage + amount > bridgeDetails.hourlyLimit) {\\n // Edge case when the hourly limit changes\\n amount = bridgeDetails.hourlyLimit > hourlyUsage ? bridgeDetails.hourlyLimit - hourlyUsage : 0;\\n }\\n usage[bridgeToken][hour] = hourlyUsage + amount;\\n\\n IERC20(bridgeToken).safeTransferFrom(msg.sender, address(this), amount);\\n uint256 canonicalOut = amount;\\n // Computing fees\\n if (isFeeExempt[msg.sender] == 0) {\\n canonicalOut -= (canonicalOut * bridgeDetails.fee) / BASE_PARAMS;\\n }\\n _mint(to, canonicalOut);\\n return canonicalOut;\\n }\\n\\n /// @notice Burns the canonical token in exchange for a bridge token\\n /// @param bridgeToken Bridge token required\\n /// @param amount Amount of canonical tokens to burn\\n /// @param to Address to which the bridge token should be sent\\n /// @return Amount of bridge tokens actually sent back\\n /// @dev Some fees may be taken by the protocol depending on the token used and on the address calling\\n function swapOut(\\n address bridgeToken,\\n uint256 amount,\\n address to\\n ) external returns (uint256) {\\n BridgeDetails memory bridgeDetails = bridges[bridgeToken];\\n if (!bridgeDetails.allowed || bridgeDetails.paused) revert InvalidToken();\\n\\n uint256 hour = block.timestamp / 3600;\\n uint256 hourlyUsage = chainTotalUsage[hour] + amount;\\n // If the amount being swapped out exceeds the limit, we revert\\n // We don't want to change the amount being swapped out.\\n // The user can decide to send another tx with the correct amount to reach the limit\\n if (hourlyUsage > chainTotalHourlyLimit) revert HourlyLimitExceeded();\\n chainTotalUsage[hour] = hourlyUsage;\\n\\n _burn(msg.sender, amount);\\n uint256 bridgeOut = amount;\\n if (isFeeExempt[msg.sender] == 0) {\\n bridgeOut -= (bridgeOut * bridgeDetails.fee) / BASE_PARAMS;\\n }\\n IERC20(bridgeToken).safeTransfer(to, bridgeOut);\\n return bridgeOut;\\n }\\n\\n // ======================= Governance Functions ================================\\n\\n /// @notice Adds support for a bridge token\\n /// @param bridgeToken Bridge token to add: it should be a version of the stablecoin from another bridge\\n /// @param limit Limit on the balance of bridge token this contract could hold\\n /// @param hourlyLimit Limit on the hourly volume for this bridge\\n /// @param paused Whether swapping for this token should be paused or not\\n /// @param fee Fee taken upon swapping for or against this token\\n function addBridgeToken(\\n address bridgeToken,\\n uint256 limit,\\n uint256 hourlyLimit,\\n uint64 fee,\\n bool paused\\n ) external onlyGovernor {\\n if (bridges[bridgeToken].allowed || bridgeToken == address(0)) revert InvalidToken();\\n if (fee > BASE_PARAMS) revert TooHighParameterValue();\\n BridgeDetails memory _bridge;\\n _bridge.limit = limit;\\n _bridge.hourlyLimit = hourlyLimit;\\n _bridge.paused = paused;\\n _bridge.fee = fee;\\n _bridge.allowed = true;\\n bridges[bridgeToken] = _bridge;\\n bridgeTokensList.push(bridgeToken);\\n emit BridgeTokenAdded(bridgeToken, limit, hourlyLimit, fee, paused);\\n }\\n\\n /// @notice Removes support for a token\\n /// @param bridgeToken Address of the bridge token to remove support for\\n function removeBridgeToken(address bridgeToken) external onlyGovernor {\\n if (IERC20(bridgeToken).balanceOf(address(this)) != 0) revert AssetStillControlledInReserves();\\n delete bridges[bridgeToken];\\n // Deletion from `bridgeTokensList` loop\\n uint256 bridgeTokensListLength = bridgeTokensList.length;\\n for (uint256 i; i < bridgeTokensListLength - 1; ++i) {\\n if (bridgeTokensList[i] == bridgeToken) {\\n // Replace the `bridgeToken` to remove with the last of the list\\n bridgeTokensList[i] = bridgeTokensList[bridgeTokensListLength - 1];\\n break;\\n }\\n }\\n // Remove last element in array\\n bridgeTokensList.pop();\\n emit BridgeTokenRemoved(bridgeToken);\\n }\\n\\n /// @notice Recovers any ERC20 token\\n /// @dev Can be used to withdraw bridge tokens for them to be de-bridged on mainnet\\n function recoverERC20(\\n address tokenAddress,\\n address to,\\n uint256 amountToRecover\\n ) external onlyGovernor {\\n IERC20(tokenAddress).safeTransfer(to, amountToRecover);\\n emit Recovered(tokenAddress, to, amountToRecover);\\n }\\n\\n /// @notice Updates the `limit` amount for `bridgeToken`\\n function setLimit(address bridgeToken, uint256 limit) external onlyGovernorOrGuardian {\\n if (!bridges[bridgeToken].allowed) revert InvalidToken();\\n bridges[bridgeToken].limit = limit;\\n emit BridgeTokenLimitUpdated(bridgeToken, limit);\\n }\\n\\n /// @notice Updates the `hourlyLimit` amount for `bridgeToken`\\n function setHourlyLimit(address bridgeToken, uint256 hourlyLimit) external onlyGovernorOrGuardian {\\n if (!bridges[bridgeToken].allowed) revert InvalidToken();\\n bridges[bridgeToken].hourlyLimit = hourlyLimit;\\n emit BridgeTokenHourlyLimitUpdated(bridgeToken, hourlyLimit);\\n }\\n\\n /// @notice Updates the `chainTotalHourlyLimit` amount\\n function setChainTotalHourlyLimit(uint256 hourlyLimit) external onlyGovernorOrGuardian {\\n chainTotalHourlyLimit = hourlyLimit;\\n emit HourlyLimitUpdated(hourlyLimit);\\n }\\n\\n /// @notice Updates the `fee` value for `bridgeToken`\\n function setSwapFee(address bridgeToken, uint64 fee) external onlyGovernorOrGuardian {\\n if (!bridges[bridgeToken].allowed) revert InvalidToken();\\n if (fee > BASE_PARAMS) revert TooHighParameterValue();\\n bridges[bridgeToken].fee = fee;\\n emit BridgeTokenFeeUpdated(bridgeToken, fee);\\n }\\n\\n /// @notice Pauses or unpauses swapping in and out for a token\\n function toggleBridge(address bridgeToken) external onlyGovernorOrGuardian {\\n if (!bridges[bridgeToken].allowed) revert InvalidToken();\\n bool pausedStatus = bridges[bridgeToken].paused;\\n bridges[bridgeToken].paused = !pausedStatus;\\n emit BridgeTokenToggled(bridgeToken, !pausedStatus);\\n }\\n\\n /// @notice Toggles fees for the address `theAddress`\\n function toggleFeesForAddress(address theAddress) external onlyGovernorOrGuardian {\\n uint256 feeExemptStatus = 1 - isFeeExempt[theAddress];\\n isFeeExempt[theAddress] = feeExemptStatus;\\n emit FeeToggled(theAddress, feeExemptStatus);\\n }\\n}\\n\",\"keccak256\":\"0x03d7733482f57983ff12e1ea50ad9f7ba089f747e566c11d27ee199c59ff229c\",\"license\":\"GPL-3.0\"},\"contracts/agToken/BaseAgTokenSideChain.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-3.0\\n\\npragma solidity ^0.8.12;\\n\\n/*\\n * \\u2588 \\n ***** \\u2593\\u2593\\u2593 \\n * \\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593 \\n * ///. \\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593 \\n ***** //////// \\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593 \\n * ///////////// \\u2593\\u2593\\u2593 \\n \\u2593\\u2593 ////////////////// \\u2588 \\u2593\\u2593 \\n \\u2593\\u2593 \\u2593\\u2593 /////////////////////// \\u2593\\u2593 \\u2593\\u2593 \\n \\u2593\\u2593 \\u2593\\u2593 //////////////////////////// \\u2593\\u2593 \\u2593\\u2593 \\n \\u2593\\u2593 \\u2593\\u2593 /////////\\u2593\\u2593\\u2593///////\\u2593\\u2593\\u2593///////// \\u2593\\u2593 \\u2593\\u2593 \\n \\u2593\\u2593 ,////////////////////////////////////// \\u2593\\u2593 \\u2593\\u2593 \\n \\u2593\\u2593 ////////////////////////////////////////// \\u2593\\u2593 \\n \\u2593\\u2593 //////////////////////\\u2593\\u2593\\u2593\\u2593///////////////////// \\n ,//////////////////////////////////////////////////// \\n .////////////////////////////////////////////////////////// \\n .//////////////////////////\\u2588\\u2588.,//////////////////////////\\u2588 \\n .//////////////////////\\u2588\\u2588\\u2588\\u2588..,./////////////////////\\u2588\\u2588 \\n ...////////////////\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588.....,.////////////////\\u2588\\u2588\\u2588 \\n ,.,////////////\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588 ........,///////////\\u2588\\u2588\\u2588\\u2588 \\n .,.,//////\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588 ,.......///////\\u2588\\u2588\\u2588\\u2588 \\n ,..//\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588 ........./\\u2588\\u2588\\u2588\\u2588 \\n ..,\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588 .....,\\u2588\\u2588\\u2588 \\n .\\u2588\\u2588 ,.,\\u2588 \\n \\n \\n \\n \\u2593\\u2593 \\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593 \\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593 \\u2593\\u2593 \\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593 \\n \\u2593\\u2593\\u2593\\u2593\\u2593\\u2593 \\u2593\\u2593\\u2593 \\u2593\\u2593\\u2593 \\u2593\\u2593\\u2593 \\u2593\\u2593 \\u2593\\u2593 \\u2593\\u2593\\u2593\\u2593 \\n \\u2593\\u2593\\u2593 \\u2593\\u2593\\u2593 \\u2593\\u2593\\u2593 \\u2593\\u2593\\u2593 \\u2593\\u2593\\u2593 \\u2593\\u2593\\u2593 \\u2593\\u2593 \\u2593\\u2593\\u2593\\u2593\\u2593 \\n \\u2593\\u2593\\u2593 \\u2593\\u2593 \\u2593\\u2593\\u2593 \\u2593\\u2593\\u2593 \\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593 \\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593 \\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593 \\n*/\\n\\nimport \\\"../interfaces/IAgToken.sol\\\";\\nimport \\\"../interfaces/ITreasury.sol\\\";\\nimport \\\"@openzeppelin/contracts-upgradeable/token/ERC20/extensions/draft-ERC20PermitUpgradeable.sol\\\";\\n\\n/// @title BaseAgTokenSideChain\\n/// @author Angle Labs, Inc.\\n/// @notice Base contract for Angle agTokens on Ethereum and on other chains\\n/// @dev By default, agTokens are ERC-20 tokens with 18 decimals\\ncontract BaseAgTokenSideChain is IAgToken, ERC20PermitUpgradeable {\\n // =========================== PARAMETERS / VARIABLES ==========================\\n\\n /// @inheritdoc IAgToken\\n mapping(address => bool) public isMinter;\\n /// @notice Reference to the treasury contract which can grant minting rights\\n address public treasury;\\n\\n // =================================== EVENTS ==================================\\n\\n event TreasuryUpdated(address indexed _treasury);\\n event MinterToggled(address indexed minter);\\n\\n // =================================== ERRORS ==================================\\n\\n error BurnAmountExceedsAllowance();\\n error InvalidSender();\\n error InvalidTreasury();\\n error NotMinter();\\n error NotTreasury();\\n\\n // ================================ CONSTRUCTOR ================================\\n\\n /// @notice Wraps `_initializeBase` for `BaseAgTokenSideChain` and makes a safety check\\n /// on `_treasury`\\n function _initialize(string memory name_, string memory symbol_, address _treasury) internal virtual initializer {\\n if (address(ITreasury(_treasury).stablecoin()) != address(this)) revert InvalidTreasury();\\n _initializeBase(name_, symbol_, _treasury);\\n }\\n\\n /// @custom:oz-upgrades-unsafe-allow constructor\\n constructor() initializer {}\\n\\n /// @notice Initializes the contract\\n /// @param name_ Name of the token\\n /// @param symbol_ Symbol of the token\\n /// @param _treasury Reference to the `Treasury` contract associated to this agToken implementation\\n function _initializeBase(string memory name_, string memory symbol_, address _treasury) internal virtual {\\n __ERC20Permit_init(name_);\\n __ERC20_init(name_, symbol_);\\n treasury = _treasury;\\n emit TreasuryUpdated(address(_treasury));\\n }\\n\\n // ================================= MODIFIERS =================================\\n\\n /// @notice Checks to see if it is the `Treasury` calling this contract\\n /// @dev There is no Access Control here, because it can be handled cheaply through this modifier\\n modifier onlyTreasury() {\\n if (msg.sender != address(treasury)) revert NotTreasury();\\n _;\\n }\\n\\n /// @notice Checks whether the sender has the minting right\\n modifier onlyMinter() {\\n if (!isMinter[msg.sender]) revert NotMinter();\\n _;\\n }\\n\\n // ============================= EXTERNAL FUNCTION =============================\\n\\n /// @notice Allows anyone to burn agToken without redeeming collateral back\\n /// @param amount Amount of stablecoins to burn\\n /// @dev This function can typically be called if there is a settlement mechanism to burn stablecoins\\n function burnStablecoin(uint256 amount) external {\\n _burn(msg.sender, amount);\\n }\\n\\n // ========================= MINTER ROLE ONLY FUNCTIONS ========================\\n\\n /// @inheritdoc IAgToken\\n function burnSelf(uint256 amount, address burner) external onlyMinter {\\n _burn(burner, amount);\\n }\\n\\n /// @inheritdoc IAgToken\\n function burnFrom(uint256 amount, address burner, address sender) external onlyMinter {\\n _burnFromNoRedeem(amount, burner, sender);\\n }\\n\\n /// @inheritdoc IAgToken\\n function mint(address account, uint256 amount) external onlyMinter {\\n _mint(account, amount);\\n }\\n\\n // ========================== TREASURY ONLY FUNCTIONS ==========================\\n\\n /// @inheritdoc IAgToken\\n function addMinter(address minter) external onlyTreasury {\\n isMinter[minter] = true;\\n emit MinterToggled(minter);\\n }\\n\\n /// @inheritdoc IAgToken\\n function removeMinter(address minter) external {\\n if (msg.sender != address(treasury) && msg.sender != minter) revert InvalidSender();\\n isMinter[minter] = false;\\n emit MinterToggled(minter);\\n }\\n\\n /// @inheritdoc IAgToken\\n function setTreasury(address _treasury) external virtual onlyTreasury {\\n treasury = _treasury;\\n emit TreasuryUpdated(_treasury);\\n }\\n\\n // ============================= INTERNAL FUNCTION =============================\\n\\n /// @notice Internal version of the function `burnFromNoRedeem`\\n /// @param amount Amount to burn\\n /// @dev It is at the level of this function that allowance checks are performed\\n function _burnFromNoRedeem(uint256 amount, address burner, address sender) internal {\\n if (burner != sender) {\\n uint256 currentAllowance = allowance(burner, sender);\\n if (currentAllowance < amount) revert BurnAmountExceedsAllowance();\\n _approve(burner, sender, currentAllowance - amount);\\n }\\n _burn(burner, amount);\\n }\\n}\\n\",\"keccak256\":\"0x3a120df43d66baf21914de14312a36c51fb22d7d10b7ef704ff0ec847c128943\",\"license\":\"GPL-3.0\"},\"contracts/interfaces/IAgToken.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-3.0\\n\\npragma solidity ^0.8.12;\\n\\nimport \\\"@openzeppelin/contracts-upgradeable/token/ERC20/IERC20Upgradeable.sol\\\";\\n\\n/// @title IAgToken\\n/// @author Angle Labs, Inc.\\n/// @notice Interface for the stablecoins `AgToken` contracts\\n/// @dev This interface only contains functions of the `AgToken` contract which are called by other contracts\\n/// of this module or of the first module of the Angle Protocol\\ninterface IAgToken is IERC20Upgradeable {\\n // ======================= Minter Role Only Functions ===========================\\n\\n /// @notice Lets the `StableMaster` contract or another whitelisted contract mint agTokens\\n /// @param account Address to mint to\\n /// @param amount Amount to mint\\n /// @dev The contracts allowed to issue agTokens are the `StableMaster` contract, `VaultManager` contracts\\n /// associated to this stablecoin as well as the flash loan module (if activated) and potentially contracts\\n /// whitelisted by governance\\n function mint(address account, uint256 amount) external;\\n\\n /// @notice Burns `amount` tokens from a `burner` address after being asked to by `sender`\\n /// @param amount Amount of tokens to burn\\n /// @param burner Address to burn from\\n /// @param sender Address which requested the burn from `burner`\\n /// @dev This method is to be called by a contract with the minter right after being requested\\n /// to do so by a `sender` address willing to burn tokens from another `burner` address\\n /// @dev The method checks the allowance between the `sender` and the `burner`\\n function burnFrom(\\n uint256 amount,\\n address burner,\\n address sender\\n ) external;\\n\\n /// @notice Burns `amount` tokens from a `burner` address\\n /// @param amount Amount of tokens to burn\\n /// @param burner Address to burn from\\n /// @dev This method is to be called by a contract with a minter right on the AgToken after being\\n /// requested to do so by an address willing to burn tokens from its address\\n function burnSelf(uint256 amount, address burner) external;\\n\\n // ========================= Treasury Only Functions ===========================\\n\\n /// @notice Adds a minter in the contract\\n /// @param minter Minter address to add\\n /// @dev Zero address checks are performed directly in the `Treasury` contract\\n function addMinter(address minter) external;\\n\\n /// @notice Removes a minter from the contract\\n /// @param minter Minter address to remove\\n /// @dev This function can also be called by a minter wishing to revoke itself\\n function removeMinter(address minter) external;\\n\\n /// @notice Sets a new treasury contract\\n /// @param _treasury New treasury address\\n function setTreasury(address _treasury) external;\\n\\n // ========================= External functions ================================\\n\\n /// @notice Checks whether an address has the right to mint agTokens\\n /// @param minter Address for which the minting right should be checked\\n /// @return Whether the address has the right to mint agTokens or not\\n function isMinter(address minter) external view returns (bool);\\n\\n /// @notice Get the associated treasury\\n function treasury() external view returns (address);\\n}\\n\",\"keccak256\":\"0xd671dbd00b28a86b839fd455ada4d1ef9203694d06142be76853e00a91f80b5f\",\"license\":\"GPL-3.0\"},\"contracts/interfaces/ICoreBorrow.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-3.0\\n\\npragma solidity ^0.8.12;\\n\\n/// @title ICoreBorrow\\n/// @author Angle Labs, Inc.\\n/// @notice Interface for the `CoreBorrow` contract\\n/// @dev This interface only contains functions of the `CoreBorrow` contract which are called by other contracts\\n/// of this module\\ninterface ICoreBorrow {\\n /// @notice Checks if an address corresponds to a treasury of a stablecoin with a flash loan\\n /// module initialized on it\\n /// @param treasury Address to check\\n /// @return Whether the address has the `FLASHLOANER_TREASURY_ROLE` or not\\n function isFlashLoanerTreasury(address treasury) external view returns (bool);\\n\\n /// @notice Checks whether an address is governor of the Angle Protocol or not\\n /// @param admin Address to check\\n /// @return Whether the address has the `GOVERNOR_ROLE` or not\\n function isGovernor(address admin) external view returns (bool);\\n\\n /// @notice Checks whether an address is governor or a guardian of the Angle Protocol or not\\n /// @param admin Address to check\\n /// @return Whether the address has the `GUARDIAN_ROLE` or not\\n /// @dev Governance should make sure when adding a governor to also give this governor the guardian\\n /// role by calling the `addGovernor` function\\n function isGovernorOrGuardian(address admin) external view returns (bool);\\n}\\n\",\"keccak256\":\"0x10249210cbf522775f040baf981d7d037472168ce2746d87473ac7c29a34e62e\",\"license\":\"GPL-3.0\"},\"contracts/interfaces/IFlashAngle.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-3.0\\n\\npragma solidity ^0.8.12;\\n\\nimport \\\"./IAgToken.sol\\\";\\nimport \\\"./ICoreBorrow.sol\\\";\\n\\n/// @title IFlashAngle\\n/// @author Angle Labs, Inc.\\n/// @notice Interface for the `FlashAngle` contract\\n/// @dev This interface only contains functions of the contract which are called by other contracts\\n/// of this module\\ninterface IFlashAngle {\\n /// @notice Reference to the `CoreBorrow` contract managing the FlashLoan module\\n function core() external view returns (ICoreBorrow);\\n\\n /// @notice Sends the fees taken from flash loans to the treasury contract associated to the stablecoin\\n /// @param stablecoin Stablecoin from which profits should be sent\\n /// @return balance Amount of profits sent\\n /// @dev This function can only be called by the treasury contract\\n function accrueInterestToTreasury(IAgToken stablecoin) external returns (uint256 balance);\\n\\n /// @notice Adds support for a stablecoin\\n /// @param _treasury Treasury associated to the stablecoin to add support for\\n /// @dev This function can only be called by the `CoreBorrow` contract\\n function addStablecoinSupport(address _treasury) external;\\n\\n /// @notice Removes support for a stablecoin\\n /// @param _treasury Treasury associated to the stablecoin to remove support for\\n /// @dev This function can only be called by the `CoreBorrow` contract\\n function removeStablecoinSupport(address _treasury) external;\\n\\n /// @notice Sets a new core contract\\n /// @param _core Core contract address to set\\n /// @dev This function can only be called by the `CoreBorrow` contract\\n function setCore(address _core) external;\\n}\\n\",\"keccak256\":\"0x39b0097f695b9e934bccdc72676c91513f1077cc5d0fd151908fd25a7c5cfbe4\",\"license\":\"GPL-3.0\"},\"contracts/interfaces/ITreasury.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-3.0\\n\\npragma solidity ^0.8.12;\\n\\nimport \\\"./IAgToken.sol\\\";\\nimport \\\"./ICoreBorrow.sol\\\";\\nimport \\\"./IFlashAngle.sol\\\";\\n\\n/// @title ITreasury\\n/// @author Angle Labs, Inc.\\n/// @notice Interface for the `Treasury` contract\\n/// @dev This interface only contains functions of the `Treasury` which are called by other contracts\\n/// of this module\\ninterface ITreasury {\\n /// @notice Stablecoin handled by this `treasury` contract\\n function stablecoin() external view returns (IAgToken);\\n\\n /// @notice Checks whether a given address has the governor role\\n /// @param admin Address to check\\n /// @return Whether the address has the governor role\\n /// @dev Access control is only kept in the `CoreBorrow` contract\\n function isGovernor(address admin) external view returns (bool);\\n\\n /// @notice Checks whether a given address has the guardian or the governor role\\n /// @param admin Address to check\\n /// @return Whether the address has the guardian or the governor role\\n /// @dev Access control is only kept in the `CoreBorrow` contract which means that this function\\n /// queries the `CoreBorrow` contract\\n function isGovernorOrGuardian(address admin) external view returns (bool);\\n\\n /// @notice Checks whether a given address has well been initialized in this contract\\n /// as a `VaultManager`\\n /// @param _vaultManager Address to check\\n /// @return Whether the address has been initialized or not\\n function isVaultManager(address _vaultManager) external view returns (bool);\\n\\n /// @notice Sets a new flash loan module for this stablecoin\\n /// @param _flashLoanModule Reference to the new flash loan module\\n /// @dev This function removes the minting right to the old flash loan module and grants\\n /// it to the new module\\n function setFlashLoanModule(address _flashLoanModule) external;\\n\\n /// @notice Gets the vault manager list\\n function vaultManagerList(uint256 i) external returns (address);\\n}\\n\",\"keccak256\":\"0x06c2f781c08732ce1b5845c083af5742716245baa6c519bd737f32b230a884c1\",\"license\":\"GPL-3.0\"}},\"version\":1}", - "bytecode": "0x60806040523480156200001157600080fd5b50600054610100900460ff1615808015620000335750600054600160ff909116105b8062000063575062000050306200013d60201b6200268a1760201c565b15801562000063575060005460ff166001145b620000cb5760405162461bcd60e51b815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201526d191e481a5b9a5d1a585b1a5e995960921b606482015260840160405180910390fd5b6000805460ff191660011790558015620000ef576000805461ff0019166101001790555b801562000136576000805461ff0019169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15b506200014c565b6001600160a01b03163b151590565b6146eb806200015c6000396000f3fe608060405234801561001057600080fd5b50600436106102ff5760003560e01c806361d027b31161019c5780639f48118f116100ee578063ced67f0c11610097578063dd62ed3e11610071578063dd62ed3e14610724578063e3e286551461076a578063f0f442601461077d57600080fd5b8063ced67f0c1461066b578063d44ad63f146106fe578063d505accf1461071157600080fd5b8063aa271e1a116100c8578063aa271e1a14610620578063ba330bd714610643578063cd4839ca1461065657600080fd5b80639f48118f146105ef578063a457c2d7146105fa578063a9059cbb1461060d57600080fd5b80637ecebe001161015057806395d89b411161012a57806395d89b41146105c1578063983b2d56146105c95780639e4e0dae146105dc57600080fd5b80637ecebe00146105705780638933fb791461058357806390218cff146105ae57600080fd5b80637334d020116101815780637334d020146105425780637d4c9c2d146105555780637d74e25f1461056857600080fd5b806361d027b3146104c757806370a082311461050c57600080fd5b80633092afd511610255578063395093511161020957806340c10f19116101e357806340c10f19146104815780634dc32fcc146104945780635bfbec96146104a757600080fd5b8063395093511461043b5780633a55f89d1461044e5780633f4218e01461046157600080fd5b8063350ebe041161023a578063350ebe041461040d5780633644e5151461042057806336db43b51461042857600080fd5b80633092afd5146103eb578063313ce567146103fe57600080fd5b8063151dd755116102b757806323b872dd1161029157806323b872dd146103b25780632b471d8e146103c55780632e403e14146103d857600080fd5b8063151dd7551461038057806318160ddd146103a15780632342fb0e146103a957600080fd5b80630919a951116102e85780630919a95114610337578063095ea7b31461034a5780631171bda91461036d57600080fd5b806306fdde0314610304578063077f224a14610322575b600080fd5b61030c610790565b6040516103199190613e63565b60405180910390f35b610335610330366004613fb0565b610822565b005b610335610345366004614028565b610832565b61035d610358366004614045565b610995565b6040519015158152602001610319565b61033561037b366004614071565b6109af565b61039361038e3660046140b2565b610b04565b604051908152602001610319565b603554610393565b61039360d25481565b61035d6103c0366004614071565b610dbe565b6103356103d33660046140e9565b610de2565b6103356103e6366004614028565b610e39565b6103356103f9366004614028565b6111e8565b60405160128152602001610319565b61033561041b366004614119565b6112d1565b610393611325565b610335610436366004614045565b611334565b61035d610449366004614045565b6114c4565b61033561045c366004614150565b611510565b61039361046f366004614028565b60d16020526000908152604090205481565b61033561048f366004614045565b611613565b6103936104a2366004614028565b611666565b6103936104b5366004614150565b60d36020526000908152604090205481565b60cd546104e79073ffffffffffffffffffffffffffffffffffffffff1681565b60405173ffffffffffffffffffffffffffffffffffffffff9091168152602001610319565b61039361051a366004614028565b73ffffffffffffffffffffffffffffffffffffffff1660009081526033602052604090205490565b610335610550366004614045565b6116ae565b610335610563366004614194565b611841565b610393611ba9565b61039361057e366004614028565b611bce565b610393610591366004614045565b60d060209081526000928352604080842090915290825290205481565b6103356105bc366004614150565b611bf9565b61030c611c06565b6103356105d7366004614028565b611c15565b6103356105ea3660046141f1565b611cdd565b610393633b9aca0081565b61035d610608366004614045565b611ee9565b61035d61061b366004614045565b611fbf565b61035d61062e366004614028565b60cc6020526000908152604090205460ff1681565b6104e7610651366004614150565b611fcd565b61065e612004565b6040516103199190614226565b6106c5610679366004614028565b60ce6020526000908152604090208054600182015460029092015490919067ffffffffffffffff81169060ff680100000000000000008204811691690100000000000000000090041685565b60408051958652602086019490945267ffffffffffffffff9092169284019290925290151560608301521515608082015260a001610319565b61039361070c3660046140b2565b612072565b61033561071f366004614280565b612237565b6103936107323660046142f7565b73ffffffffffffffffffffffffffffffffffffffff918216600090815260346020908152604080832093909416825291909152205490565b610335610778366004614028565b6123f6565b61033561078b366004614028565b6125ca565b60606036805461079f90614325565b80601f01602080910402602001604051908101604052809291908181526020018280546107cb90614325565b80156108185780601f106107ed57610100808354040283529160200191610818565b820191906000526020600020905b8154815290600101906020018083116107fb57829003601f168201915b5050505050905090565b61082d8383836126a6565b505050565b60cd546040517f521d4de900000000000000000000000000000000000000000000000000000000815233600482015273ffffffffffffffffffffffffffffffffffffffff9091169063521d4de990602401602060405180830381865afa1580156108a0573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906108c49190614372565b6108fa576040517f99e120bc00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff8116600090815260d1602052604081205461092b9060016143be565b73ffffffffffffffffffffffffffffffffffffffff8316600081815260d160205260409081902083905551919250907f979ef83e7e7a87cb48064e296dd7e997870d50f43acf8d7ad221313526c8ca0f906109899084815260200190565b60405180910390a25050565b6000336109a3818585612911565b60019150505b92915050565b60cd546040517fe43581b800000000000000000000000000000000000000000000000000000000815233600482015273ffffffffffffffffffffffffffffffffffffffff9091169063e43581b890602401602060405180830381865afa158015610a1d573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610a419190614372565b610a77576040517fee3675d400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b610a9873ffffffffffffffffffffffffffffffffffffffff84168383612abc565b8173ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff167ffff3b3844276f57024e0b42afec1a37f75db36511e43819a4f2a63ab7862b64883604051610af791815260200190565b60405180910390a3505050565b73ffffffffffffffffffffffffffffffffffffffff8316600090815260ce60209081526040808320815160a081018352815481526001820154938101939093526002015467ffffffffffffffff81169183019190915260ff680100000000000000008204811615801560608501526901000000000000000000909204161515608083015280610b94575080608001515b15610bcb576040517fc1ab6dc100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015260009073ffffffffffffffffffffffffffffffffffffffff8716906370a0823190602401602060405180830381865afa158015610c38573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610c5c91906143d1565b8251909150610c6b86836143ea565b1115610c93578151811015610c8e578151610c879082906143be565b9450610c93565b600094505b6000610ca1610e10426143fd565b73ffffffffffffffffffffffffffffffffffffffff8816600090815260d0602090815260408083208484528252909120549085015191925090610ce488836143ea565b1115610d0f5780846020015111610cfc576000610d0c565b808460200151610d0c91906143be565b96505b610d1987826143ea565b73ffffffffffffffffffffffffffffffffffffffff8916600081815260d060209081526040808320878452909152902091909155610d599033308a612b90565b33600090815260d16020526040812054889103610da657633b9aca00856040015167ffffffffffffffff1682610d8f9190614438565b610d9991906143fd565b610da390826143be565b90505b610db08782612bee565b9450505050505b9392505050565b600033610dcc858285612d0e565b610dd7858585612ddf565b506001949350505050565b33600090815260cc602052604090205460ff16610e2b576040517ff8d2906c00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b610e358183613092565b5050565b60cd546040517fe43581b800000000000000000000000000000000000000000000000000000000815233600482015273ffffffffffffffffffffffffffffffffffffffff9091169063e43581b890602401602060405180830381865afa158015610ea7573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610ecb9190614372565b610f01576040517fee3675d400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015273ffffffffffffffffffffffffffffffffffffffff8216906370a0823190602401602060405180830381865afa158015610f6b573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610f8f91906143d1565b15610fc6576040517f2ef630ec00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff8116600090815260ce602052604081208181556001810182905560020180547fffffffffffffffffffffffffffffffffffffffffffff0000000000000000000016905560cf54905b61102e6001836143be565b811015611139578273ffffffffffffffffffffffffffffffffffffffff1660cf828154811061105f5761105f61444f565b60009182526020909120015473ffffffffffffffffffffffffffffffffffffffff16036111295760cf6110936001846143be565b815481106110a3576110a361444f565b60009182526020909120015460cf805473ffffffffffffffffffffffffffffffffffffffff90921691839081106110dc576110dc61444f565b9060005260206000200160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550611139565b6111328161447e565b9050611023565b5060cf80548061114b5761114b6144b6565b60008281526020812082017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff90810180547fffffffffffffffffffffffff000000000000000000000000000000000000000016905590910190915560405173ffffffffffffffffffffffffffffffffffffffff8416917f5c95b49c4d59d97a2f044167723f29c74b30f99702e3fd406c3830160aa9ccb891a25050565b60cd5473ffffffffffffffffffffffffffffffffffffffff16331480159061122657503373ffffffffffffffffffffffffffffffffffffffff821614155b1561125d576040517fddb5de5e00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff8116600081815260cc602052604080822080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00169055517f98c15241d6c02bc5ee0b780e11b3ea737a2defd9d04877edbe9f9497065bd02f9190a250565b33600090815260cc602052604090205460ff1661131a576040517ff8d2906c00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b61082d83838361327f565b600061132f61333a565b905090565b60cd546040517f521d4de900000000000000000000000000000000000000000000000000000000815233600482015273ffffffffffffffffffffffffffffffffffffffff9091169063521d4de990602401602060405180830381865afa1580156113a2573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906113c69190614372565b6113fc576040517f99e120bc00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff8216600090815260ce602052604090206002015468010000000000000000900460ff1661146a576040517fc1ab6dc100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff8216600081815260ce602052604090819020839055517fe7b113fba37131b6396680a0c55790a697ec975e198ff8cfd89dac90a6379e61906109899084815260200190565b33600081815260346020908152604080832073ffffffffffffffffffffffffffffffffffffffff871684529091528120549091906109a3908290869061150b9087906143ea565b612911565b60cd546040517f521d4de900000000000000000000000000000000000000000000000000000000815233600482015273ffffffffffffffffffffffffffffffffffffffff9091169063521d4de990602401602060405180830381865afa15801561157e573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906115a29190614372565b6115d8576040517f99e120bc00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60d28190556040518181527fc3b69829afe2345596a02c8b587d41f796ba0094481d899e1b2e07b7532a1e219060200160405180910390a150565b33600090815260cc602052604090205460ff1661165c576040517ff8d2906c00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b610e358282612bee565b73ffffffffffffffffffffffffffffffffffffffff8116600090815260d06020526040812081611698610e10426143fd565b8152602001908152602001600020549050919050565b60cd546040517f521d4de900000000000000000000000000000000000000000000000000000000815233600482015273ffffffffffffffffffffffffffffffffffffffff9091169063521d4de990602401602060405180830381865afa15801561171c573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906117409190614372565b611776576040517f99e120bc00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff8216600090815260ce602052604090206002015468010000000000000000900460ff166117e4576040517fc1ab6dc100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff8216600081815260ce602052604090819020600101839055517fe13ac9338b2ee623233f83c1b3ceab16490fa3e3737fac7f0970d0830a9f4871906109899084815260200190565b60cd546040517fe43581b800000000000000000000000000000000000000000000000000000000815233600482015273ffffffffffffffffffffffffffffffffffffffff9091169063e43581b890602401602060405180830381865afa1580156118af573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906118d39190614372565b611909576040517fee3675d400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff8516600090815260ce602052604090206002015468010000000000000000900460ff1680611960575073ffffffffffffffffffffffffffffffffffffffff8516155b15611997576040517fc1ab6dc100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b633b9aca008267ffffffffffffffff1611156119df576040517feca1d2c600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040805160a08101825260008082526020820181905291810182905260608101829052608081019190915284815260208082018581528315156080840190815267ffffffffffffffff808716604080870191825260016060880181815273ffffffffffffffffffffffffffffffffffffffff8e16600081815260ce9099528389208a5181559751888401559351600290970180549151965115156901000000000000000000027fffffffffffffffffffffffffffffffffffffffffffff00ffffffffffffffffff97151568010000000000000000027fffffffffffffffffffffffffffffffffffffffffffffff000000000000000000909316989096169790971717949094169290921790935560cf805492830181559093527facb8d954e2cfef495862221e91bd7523613cf8808827cb33edfe4904cc51bf290180547fffffffffffffffffffffffff0000000000000000000000000000000000000000168217905590517f53087ff85d80a7671594bd2e86b92af22e0b3c2c441c8033bba7399b7b5cbe2390611b99908890889088908890938452602084019290925267ffffffffffffffff1660408301521515606082015260800190565b60405180910390a2505050505050565b600060d381611bba610e10426143fd565b815260200190815260200160002054905090565b73ffffffffffffffffffffffffffffffffffffffff81166000908152609960205260408120546109a9565b611c033382613092565b50565b60606037805461079f90614325565b60cd5473ffffffffffffffffffffffffffffffffffffffff163314611c66576040517fb90cdbb100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff8116600081815260cc602052604080822080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00166001179055517f98c15241d6c02bc5ee0b780e11b3ea737a2defd9d04877edbe9f9497065bd02f9190a250565b60cd546040517f521d4de900000000000000000000000000000000000000000000000000000000815233600482015273ffffffffffffffffffffffffffffffffffffffff9091169063521d4de990602401602060405180830381865afa158015611d4b573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611d6f9190614372565b611da5576040517f99e120bc00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff8216600090815260ce602052604090206002015468010000000000000000900460ff16611e13576040517fc1ab6dc100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b633b9aca008167ffffffffffffffff161115611e5b576040517feca1d2c600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff8216600081815260ce602090815260409182902060020180547fffffffffffffffffffffffffffffffffffffffffffffffff00000000000000001667ffffffffffffffff861690811790915591519182527f901f9de19b475adc8da4110434b8df940dce085afd05e2281c86807f3a899d299101610989565b33600081815260346020908152604080832073ffffffffffffffffffffffffffffffffffffffff8716845290915281205490919083811015611fb2576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602560248201527f45524332303a2064656372656173656420616c6c6f77616e63652062656c6f7760448201527f207a65726f00000000000000000000000000000000000000000000000000000060648201526084015b60405180910390fd5b610dd78286868403612911565b6000336109a3818585612ddf565b60cf8181548110611fdd57600080fd5b60009182526020909120015473ffffffffffffffffffffffffffffffffffffffff16905081565b606060cf80548060200260200160405190810160405280929190818152602001828054801561081857602002820191906000526020600020905b815473ffffffffffffffffffffffffffffffffffffffff16815260019091019060200180831161203e575050505050905090565b73ffffffffffffffffffffffffffffffffffffffff8316600090815260ce60209081526040808320815160a081018352815481526001820154938101939093526002015467ffffffffffffffff81169183019190915260ff680100000000000000008204811615801560608501526901000000000000000000909204161515608083015280612102575080608001515b15612139576040517fc1ab6dc100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000612147610e10426143fd565b600081815260d36020526040812054919250906121659087906143ea565b905060d2548111156121a3576040517f6d43d1ac00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600082815260d3602052604090208190556121be3387613092565b33600090815260d1602052604081205487910361220b57633b9aca00846040015167ffffffffffffffff16826121f49190614438565b6121fe91906143fd565b61220890826143be565b90505b61222c73ffffffffffffffffffffffffffffffffffffffff89168783612abc565b979650505050505050565b834211156122a1576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f45524332305065726d69743a206578706972656420646561646c696e650000006044820152606401611fa9565b60007f6e71edae12b1b97f4d1f60370fef10105fa2faae0126114a169c64845d6126c98888886122d08c6133b5565b60408051602081019690965273ffffffffffffffffffffffffffffffffffffffff94851690860152929091166060840152608083015260a082015260c0810186905260e0016040516020818303038152906040528051906020012090506000612338826133ea565b9050600061234882878787613453565b90508973ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16146123df576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601e60248201527f45524332305065726d69743a20696e76616c6964207369676e617475726500006044820152606401611fa9565b6123ea8a8a8a612911565b50505050505050505050565b60cd546040517f521d4de900000000000000000000000000000000000000000000000000000000815233600482015273ffffffffffffffffffffffffffffffffffffffff9091169063521d4de990602401602060405180830381865afa158015612464573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906124889190614372565b6124be576040517f99e120bc00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff8116600090815260ce602052604090206002015468010000000000000000900460ff1661252c576040517fc1ab6dc100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff8116600081815260ce602090815260409182902060020180547fffffffffffffffffffffffffffffffffffffffffffff00ffffffffffffffffff811669010000000000000000009182900460ff16801592830291909117909255925192835292917ff7c93079dcbf699749d66345a351afab7d24219bb1d915c9f4fc4cf03f00d3979101610989565b60cd5473ffffffffffffffffffffffffffffffffffffffff16331461261b576040517fb90cdbb100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60cd80547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83169081179091556040517f7dae230f18360d76a040c81f050aa14eb9d6dc7901b20fc5d855e2a20fe814d190600090a250565b73ffffffffffffffffffffffffffffffffffffffff163b151590565b600054610100900460ff16158080156126c65750600054600160ff909116105b806126e05750303b1580156126e0575060005460ff166001145b61276c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201527f647920696e697469616c697a65640000000000000000000000000000000000006064820152608401611fa9565b600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0016600117905580156127ca57600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff166101001790555b3073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1663e9cbd8226040518163ffffffff1660e01b8152600401602060405180830381865afa15801561282c573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061285091906144e5565b73ffffffffffffffffffffffffffffffffffffffff161461289d576040517f14bcf5c800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6128a884848461347b565b801561290b57600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15b50505050565b73ffffffffffffffffffffffffffffffffffffffff83166129b3576040517f08c379a0000000000000000000000000000000000000000000000000000000008152602060048201526024808201527f45524332303a20617070726f76652066726f6d20746865207a65726f2061646460448201527f72657373000000000000000000000000000000000000000000000000000000006064820152608401611fa9565b73ffffffffffffffffffffffffffffffffffffffff8216612a56576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602260248201527f45524332303a20617070726f766520746f20746865207a65726f20616464726560448201527f73730000000000000000000000000000000000000000000000000000000000006064820152608401611fa9565b73ffffffffffffffffffffffffffffffffffffffff83811660008181526034602090815260408083209487168084529482529182902085905590518481527f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b9259101610af7565b60405173ffffffffffffffffffffffffffffffffffffffff831660248201526044810182905261082d9084907fa9059cbb00000000000000000000000000000000000000000000000000000000906064015b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff00000000000000000000000000000000000000000000000000000000909316929092179091526134ff565b60405173ffffffffffffffffffffffffffffffffffffffff8085166024830152831660448201526064810182905261290b9085907f23b872dd0000000000000000000000000000000000000000000000000000000090608401612b0e565b73ffffffffffffffffffffffffffffffffffffffff8216612c6b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601f60248201527f45524332303a206d696e7420746f20746865207a65726f2061646472657373006044820152606401611fa9565b8060356000828254612c7d91906143ea565b909155505073ffffffffffffffffffffffffffffffffffffffff821660009081526033602052604081208054839290612cb79084906143ea565b909155505060405181815273ffffffffffffffffffffffffffffffffffffffff8316906000907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef9060200160405180910390a35050565b73ffffffffffffffffffffffffffffffffffffffff8381166000908152603460209081526040808320938616835292905220547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff811461290b5781811015612dd2576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f45524332303a20696e73756666696369656e7420616c6c6f77616e63650000006044820152606401611fa9565b61290b8484848403612911565b73ffffffffffffffffffffffffffffffffffffffff8316612e82576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602560248201527f45524332303a207472616e736665722066726f6d20746865207a65726f20616460448201527f64726573730000000000000000000000000000000000000000000000000000006064820152608401611fa9565b73ffffffffffffffffffffffffffffffffffffffff8216612f25576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602360248201527f45524332303a207472616e7366657220746f20746865207a65726f206164647260448201527f65737300000000000000000000000000000000000000000000000000000000006064820152608401611fa9565b73ffffffffffffffffffffffffffffffffffffffff831660009081526033602052604090205481811015612fdb576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f45524332303a207472616e7366657220616d6f756e742065786365656473206260448201527f616c616e636500000000000000000000000000000000000000000000000000006064820152608401611fa9565b73ffffffffffffffffffffffffffffffffffffffff80851660009081526033602052604080822085850390559185168152908120805484929061301f9084906143ea565b925050819055508273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef8460405161308591815260200190565b60405180910390a361290b565b73ffffffffffffffffffffffffffffffffffffffff8216613135576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602160248201527f45524332303a206275726e2066726f6d20746865207a65726f2061646472657360448201527f73000000000000000000000000000000000000000000000000000000000000006064820152608401611fa9565b73ffffffffffffffffffffffffffffffffffffffff8216600090815260336020526040902054818110156131eb576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602260248201527f45524332303a206275726e20616d6f756e7420657863656564732062616c616e60448201527f63650000000000000000000000000000000000000000000000000000000000006064820152608401611fa9565b73ffffffffffffffffffffffffffffffffffffffff831660009081526033602052604081208383039055603580548492906132279084906143be565b909155505060405182815260009073ffffffffffffffffffffffffffffffffffffffff8516907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef9060200160405180910390a3505050565b8073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff16146133305773ffffffffffffffffffffffffffffffffffffffff8281166000908152603460209081526040808320938516835292905220548381101561331f576040517f715ec26c00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b61332e838361150b87856143be565b505b61082d8284613092565b600061132f7f8b73c3c69bb8fe3d512ecc4cf759cc79239f7b179b0ffacaa9a75d522b39400f61336960655490565b6066546040805160208101859052908101839052606081018290524660808201523060a082015260009060c0016040516020818303038152906040528051906020012090509392505050565b73ffffffffffffffffffffffffffffffffffffffff811660009081526099602052604090208054600181018255905b50919050565b60006109a96133f761333a565b836040517f19010000000000000000000000000000000000000000000000000000000000006020820152602281018390526042810182905260009060620160405160208183030381529060405280519060200120905092915050565b60008060006134648787878761360b565b9150915061347181613723565b5095945050505050565b61348483613977565b61348e8383613a4d565b60cd80547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83169081179091556040517f7dae230f18360d76a040c81f050aa14eb9d6dc7901b20fc5d855e2a20fe814d190600090a2505050565b6000613561826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c65648152508573ffffffffffffffffffffffffffffffffffffffff16613aee9092919063ffffffff16565b80519091501561082d578080602001905181019061357f9190614372565b61082d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e60448201527f6f742073756363656564000000000000000000000000000000000000000000006064820152608401611fa9565b6000807f7fffffffffffffffffffffffffffffff5d576e7357a4501ddfe92f46681b20a0831115613642575060009050600361371a565b8460ff16601b1415801561365a57508460ff16601c14155b1561366b575060009050600461371a565b6040805160008082526020820180845289905260ff881692820192909252606081018690526080810185905260019060a0016020604051602081039080840390855afa1580156136bf573d6000803e3d6000fd5b50506040517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0015191505073ffffffffffffffffffffffffffffffffffffffff81166137135760006001925092505061371a565b9150600090505b94509492505050565b600081600481111561373757613737614502565b0361373f5750565b600181600481111561375357613753614502565b036137ba576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601860248201527f45434453413a20696e76616c6964207369676e617475726500000000000000006044820152606401611fa9565b60028160048111156137ce576137ce614502565b03613835576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601f60248201527f45434453413a20696e76616c6964207369676e6174757265206c656e677468006044820152606401611fa9565b600381600481111561384957613849614502565b036138d6576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602260248201527f45434453413a20696e76616c6964207369676e6174757265202773272076616c60448201527f75650000000000000000000000000000000000000000000000000000000000006064820152608401611fa9565b60048160048111156138ea576138ea614502565b03611c03576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602260248201527f45434453413a20696e76616c6964207369676e6174757265202776272076616c60448201527f75650000000000000000000000000000000000000000000000000000000000006064820152608401611fa9565b600054610100900460ff16613a0e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201527f6e697469616c697a696e670000000000000000000000000000000000000000006064820152608401611fa9565b611c03816040518060400160405280600181526020017f3100000000000000000000000000000000000000000000000000000000000000815250613b05565b600054610100900460ff16613ae4576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201527f6e697469616c697a696e670000000000000000000000000000000000000000006064820152608401611fa9565b610e358282613bb6565b6060613afd8484600085613c66565b949350505050565b600054610100900460ff16613b9c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201527f6e697469616c697a696e670000000000000000000000000000000000000000006064820152608401611fa9565b815160209283012081519190920120606591909155606655565b600054610100900460ff16613c4d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201527f6e697469616c697a696e670000000000000000000000000000000000000000006064820152608401611fa9565b6036613c59838261457f565b50603761082d828261457f565b606082471015613cf8576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f60448201527f722063616c6c00000000000000000000000000000000000000000000000000006064820152608401611fa9565b73ffffffffffffffffffffffffffffffffffffffff85163b613d76576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006044820152606401611fa9565b6000808673ffffffffffffffffffffffffffffffffffffffff168587604051613d9f9190614699565b60006040518083038185875af1925050503d8060008114613ddc576040519150601f19603f3d011682016040523d82523d6000602084013e613de1565b606091505b509150915061222c82828660608315613dfb575081610db7565b825115613e0b5782518084602001fd5b816040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611fa99190613e63565b60005b83811015613e5a578181015183820152602001613e42565b50506000910152565b6020815260008251806020840152613e82816040850160208701613e3f565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169190910160400192915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b600082601f830112613ef457600080fd5b813567ffffffffffffffff80821115613f0f57613f0f613eb4565b604051601f83017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0908116603f01168101908282118183101715613f5557613f55613eb4565b81604052838152866020858801011115613f6e57600080fd5b836020870160208301376000602085830101528094505050505092915050565b73ffffffffffffffffffffffffffffffffffffffff81168114611c0357600080fd5b600080600060608486031215613fc557600080fd5b833567ffffffffffffffff80821115613fdd57600080fd5b613fe987838801613ee3565b94506020860135915080821115613fff57600080fd5b5061400c86828701613ee3565b925050604084013561401d81613f8e565b809150509250925092565b60006020828403121561403a57600080fd5b8135610db781613f8e565b6000806040838503121561405857600080fd5b823561406381613f8e565b946020939093013593505050565b60008060006060848603121561408657600080fd5b833561409181613f8e565b925060208401356140a181613f8e565b929592945050506040919091013590565b6000806000606084860312156140c757600080fd5b83356140d281613f8e565b925060208401359150604084013561401d81613f8e565b600080604083850312156140fc57600080fd5b82359150602083013561410e81613f8e565b809150509250929050565b60008060006060848603121561412e57600080fd5b83359250602084013561414081613f8e565b9150604084013561401d81613f8e565b60006020828403121561416257600080fd5b5035919050565b803567ffffffffffffffff8116811461418157600080fd5b919050565b8015158114611c0357600080fd5b600080600080600060a086880312156141ac57600080fd5b85356141b781613f8e565b945060208601359350604086013592506141d360608701614169565b915060808601356141e381614186565b809150509295509295909350565b6000806040838503121561420457600080fd5b823561420f81613f8e565b915061421d60208401614169565b90509250929050565b6020808252825182820181905260009190848201906040850190845b8181101561427457835173ffffffffffffffffffffffffffffffffffffffff1683529284019291840191600101614242565b50909695505050505050565b600080600080600080600060e0888a03121561429b57600080fd5b87356142a681613f8e565b965060208801356142b681613f8e565b95506040880135945060608801359350608088013560ff811681146142da57600080fd5b9699959850939692959460a0840135945060c09093013592915050565b6000806040838503121561430a57600080fd5b823561431581613f8e565b9150602083013561410e81613f8e565b600181811c9082168061433957607f821691505b6020821081036133e4577f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b60006020828403121561438457600080fd5b8151610db781614186565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b818103818111156109a9576109a961438f565b6000602082840312156143e357600080fd5b5051919050565b808201808211156109a9576109a961438f565b600082614433577f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b500490565b80820281158282048414176109a9576109a961438f565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82036144af576144af61438f565b5060010190565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603160045260246000fd5b6000602082840312156144f757600080fd5b8151610db781613f8e565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b601f82111561082d57600081815260208120601f850160051c810160208610156145585750805b601f850160051c820191505b8181101561457757828155600101614564565b505050505050565b815167ffffffffffffffff81111561459957614599613eb4565b6145ad816145a78454614325565b84614531565b602080601f83116001811461460057600084156145ca5750858301515b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600386901b1c1916600185901b178555614577565b6000858152602081207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08616915b8281101561464d5788860151825594840194600190910190840161462e565b508582101561468957878501517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600388901b60f8161c191681555b5050505050600190811b01905550565b600082516146ab818460208701613e3f565b919091019291505056fea264697066735822122063a1b6264cdcf054e5097307e409d188b47c62ad909903d6edaf55a3d2b19dee64736f6c63430008110033", - "deployedBytecode": "0x608060405234801561001057600080fd5b50600436106102ff5760003560e01c806361d027b31161019c5780639f48118f116100ee578063ced67f0c11610097578063dd62ed3e11610071578063dd62ed3e14610724578063e3e286551461076a578063f0f442601461077d57600080fd5b8063ced67f0c1461066b578063d44ad63f146106fe578063d505accf1461071157600080fd5b8063aa271e1a116100c8578063aa271e1a14610620578063ba330bd714610643578063cd4839ca1461065657600080fd5b80639f48118f146105ef578063a457c2d7146105fa578063a9059cbb1461060d57600080fd5b80637ecebe001161015057806395d89b411161012a57806395d89b41146105c1578063983b2d56146105c95780639e4e0dae146105dc57600080fd5b80637ecebe00146105705780638933fb791461058357806390218cff146105ae57600080fd5b80637334d020116101815780637334d020146105425780637d4c9c2d146105555780637d74e25f1461056857600080fd5b806361d027b3146104c757806370a082311461050c57600080fd5b80633092afd511610255578063395093511161020957806340c10f19116101e357806340c10f19146104815780634dc32fcc146104945780635bfbec96146104a757600080fd5b8063395093511461043b5780633a55f89d1461044e5780633f4218e01461046157600080fd5b8063350ebe041161023a578063350ebe041461040d5780633644e5151461042057806336db43b51461042857600080fd5b80633092afd5146103eb578063313ce567146103fe57600080fd5b8063151dd755116102b757806323b872dd1161029157806323b872dd146103b25780632b471d8e146103c55780632e403e14146103d857600080fd5b8063151dd7551461038057806318160ddd146103a15780632342fb0e146103a957600080fd5b80630919a951116102e85780630919a95114610337578063095ea7b31461034a5780631171bda91461036d57600080fd5b806306fdde0314610304578063077f224a14610322575b600080fd5b61030c610790565b6040516103199190613e63565b60405180910390f35b610335610330366004613fb0565b610822565b005b610335610345366004614028565b610832565b61035d610358366004614045565b610995565b6040519015158152602001610319565b61033561037b366004614071565b6109af565b61039361038e3660046140b2565b610b04565b604051908152602001610319565b603554610393565b61039360d25481565b61035d6103c0366004614071565b610dbe565b6103356103d33660046140e9565b610de2565b6103356103e6366004614028565b610e39565b6103356103f9366004614028565b6111e8565b60405160128152602001610319565b61033561041b366004614119565b6112d1565b610393611325565b610335610436366004614045565b611334565b61035d610449366004614045565b6114c4565b61033561045c366004614150565b611510565b61039361046f366004614028565b60d16020526000908152604090205481565b61033561048f366004614045565b611613565b6103936104a2366004614028565b611666565b6103936104b5366004614150565b60d36020526000908152604090205481565b60cd546104e79073ffffffffffffffffffffffffffffffffffffffff1681565b60405173ffffffffffffffffffffffffffffffffffffffff9091168152602001610319565b61039361051a366004614028565b73ffffffffffffffffffffffffffffffffffffffff1660009081526033602052604090205490565b610335610550366004614045565b6116ae565b610335610563366004614194565b611841565b610393611ba9565b61039361057e366004614028565b611bce565b610393610591366004614045565b60d060209081526000928352604080842090915290825290205481565b6103356105bc366004614150565b611bf9565b61030c611c06565b6103356105d7366004614028565b611c15565b6103356105ea3660046141f1565b611cdd565b610393633b9aca0081565b61035d610608366004614045565b611ee9565b61035d61061b366004614045565b611fbf565b61035d61062e366004614028565b60cc6020526000908152604090205460ff1681565b6104e7610651366004614150565b611fcd565b61065e612004565b6040516103199190614226565b6106c5610679366004614028565b60ce6020526000908152604090208054600182015460029092015490919067ffffffffffffffff81169060ff680100000000000000008204811691690100000000000000000090041685565b60408051958652602086019490945267ffffffffffffffff9092169284019290925290151560608301521515608082015260a001610319565b61039361070c3660046140b2565b612072565b61033561071f366004614280565b612237565b6103936107323660046142f7565b73ffffffffffffffffffffffffffffffffffffffff918216600090815260346020908152604080832093909416825291909152205490565b610335610778366004614028565b6123f6565b61033561078b366004614028565b6125ca565b60606036805461079f90614325565b80601f01602080910402602001604051908101604052809291908181526020018280546107cb90614325565b80156108185780601f106107ed57610100808354040283529160200191610818565b820191906000526020600020905b8154815290600101906020018083116107fb57829003601f168201915b5050505050905090565b61082d8383836126a6565b505050565b60cd546040517f521d4de900000000000000000000000000000000000000000000000000000000815233600482015273ffffffffffffffffffffffffffffffffffffffff9091169063521d4de990602401602060405180830381865afa1580156108a0573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906108c49190614372565b6108fa576040517f99e120bc00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff8116600090815260d1602052604081205461092b9060016143be565b73ffffffffffffffffffffffffffffffffffffffff8316600081815260d160205260409081902083905551919250907f979ef83e7e7a87cb48064e296dd7e997870d50f43acf8d7ad221313526c8ca0f906109899084815260200190565b60405180910390a25050565b6000336109a3818585612911565b60019150505b92915050565b60cd546040517fe43581b800000000000000000000000000000000000000000000000000000000815233600482015273ffffffffffffffffffffffffffffffffffffffff9091169063e43581b890602401602060405180830381865afa158015610a1d573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610a419190614372565b610a77576040517fee3675d400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b610a9873ffffffffffffffffffffffffffffffffffffffff84168383612abc565b8173ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff167ffff3b3844276f57024e0b42afec1a37f75db36511e43819a4f2a63ab7862b64883604051610af791815260200190565b60405180910390a3505050565b73ffffffffffffffffffffffffffffffffffffffff8316600090815260ce60209081526040808320815160a081018352815481526001820154938101939093526002015467ffffffffffffffff81169183019190915260ff680100000000000000008204811615801560608501526901000000000000000000909204161515608083015280610b94575080608001515b15610bcb576040517fc1ab6dc100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015260009073ffffffffffffffffffffffffffffffffffffffff8716906370a0823190602401602060405180830381865afa158015610c38573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610c5c91906143d1565b8251909150610c6b86836143ea565b1115610c93578151811015610c8e578151610c879082906143be565b9450610c93565b600094505b6000610ca1610e10426143fd565b73ffffffffffffffffffffffffffffffffffffffff8816600090815260d0602090815260408083208484528252909120549085015191925090610ce488836143ea565b1115610d0f5780846020015111610cfc576000610d0c565b808460200151610d0c91906143be565b96505b610d1987826143ea565b73ffffffffffffffffffffffffffffffffffffffff8916600081815260d060209081526040808320878452909152902091909155610d599033308a612b90565b33600090815260d16020526040812054889103610da657633b9aca00856040015167ffffffffffffffff1682610d8f9190614438565b610d9991906143fd565b610da390826143be565b90505b610db08782612bee565b9450505050505b9392505050565b600033610dcc858285612d0e565b610dd7858585612ddf565b506001949350505050565b33600090815260cc602052604090205460ff16610e2b576040517ff8d2906c00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b610e358183613092565b5050565b60cd546040517fe43581b800000000000000000000000000000000000000000000000000000000815233600482015273ffffffffffffffffffffffffffffffffffffffff9091169063e43581b890602401602060405180830381865afa158015610ea7573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610ecb9190614372565b610f01576040517fee3675d400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015273ffffffffffffffffffffffffffffffffffffffff8216906370a0823190602401602060405180830381865afa158015610f6b573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610f8f91906143d1565b15610fc6576040517f2ef630ec00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff8116600090815260ce602052604081208181556001810182905560020180547fffffffffffffffffffffffffffffffffffffffffffff0000000000000000000016905560cf54905b61102e6001836143be565b811015611139578273ffffffffffffffffffffffffffffffffffffffff1660cf828154811061105f5761105f61444f565b60009182526020909120015473ffffffffffffffffffffffffffffffffffffffff16036111295760cf6110936001846143be565b815481106110a3576110a361444f565b60009182526020909120015460cf805473ffffffffffffffffffffffffffffffffffffffff90921691839081106110dc576110dc61444f565b9060005260206000200160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550611139565b6111328161447e565b9050611023565b5060cf80548061114b5761114b6144b6565b60008281526020812082017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff90810180547fffffffffffffffffffffffff000000000000000000000000000000000000000016905590910190915560405173ffffffffffffffffffffffffffffffffffffffff8416917f5c95b49c4d59d97a2f044167723f29c74b30f99702e3fd406c3830160aa9ccb891a25050565b60cd5473ffffffffffffffffffffffffffffffffffffffff16331480159061122657503373ffffffffffffffffffffffffffffffffffffffff821614155b1561125d576040517fddb5de5e00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff8116600081815260cc602052604080822080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00169055517f98c15241d6c02bc5ee0b780e11b3ea737a2defd9d04877edbe9f9497065bd02f9190a250565b33600090815260cc602052604090205460ff1661131a576040517ff8d2906c00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b61082d83838361327f565b600061132f61333a565b905090565b60cd546040517f521d4de900000000000000000000000000000000000000000000000000000000815233600482015273ffffffffffffffffffffffffffffffffffffffff9091169063521d4de990602401602060405180830381865afa1580156113a2573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906113c69190614372565b6113fc576040517f99e120bc00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff8216600090815260ce602052604090206002015468010000000000000000900460ff1661146a576040517fc1ab6dc100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff8216600081815260ce602052604090819020839055517fe7b113fba37131b6396680a0c55790a697ec975e198ff8cfd89dac90a6379e61906109899084815260200190565b33600081815260346020908152604080832073ffffffffffffffffffffffffffffffffffffffff871684529091528120549091906109a3908290869061150b9087906143ea565b612911565b60cd546040517f521d4de900000000000000000000000000000000000000000000000000000000815233600482015273ffffffffffffffffffffffffffffffffffffffff9091169063521d4de990602401602060405180830381865afa15801561157e573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906115a29190614372565b6115d8576040517f99e120bc00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60d28190556040518181527fc3b69829afe2345596a02c8b587d41f796ba0094481d899e1b2e07b7532a1e219060200160405180910390a150565b33600090815260cc602052604090205460ff1661165c576040517ff8d2906c00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b610e358282612bee565b73ffffffffffffffffffffffffffffffffffffffff8116600090815260d06020526040812081611698610e10426143fd565b8152602001908152602001600020549050919050565b60cd546040517f521d4de900000000000000000000000000000000000000000000000000000000815233600482015273ffffffffffffffffffffffffffffffffffffffff9091169063521d4de990602401602060405180830381865afa15801561171c573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906117409190614372565b611776576040517f99e120bc00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff8216600090815260ce602052604090206002015468010000000000000000900460ff166117e4576040517fc1ab6dc100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff8216600081815260ce602052604090819020600101839055517fe13ac9338b2ee623233f83c1b3ceab16490fa3e3737fac7f0970d0830a9f4871906109899084815260200190565b60cd546040517fe43581b800000000000000000000000000000000000000000000000000000000815233600482015273ffffffffffffffffffffffffffffffffffffffff9091169063e43581b890602401602060405180830381865afa1580156118af573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906118d39190614372565b611909576040517fee3675d400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff8516600090815260ce602052604090206002015468010000000000000000900460ff1680611960575073ffffffffffffffffffffffffffffffffffffffff8516155b15611997576040517fc1ab6dc100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b633b9aca008267ffffffffffffffff1611156119df576040517feca1d2c600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040805160a08101825260008082526020820181905291810182905260608101829052608081019190915284815260208082018581528315156080840190815267ffffffffffffffff808716604080870191825260016060880181815273ffffffffffffffffffffffffffffffffffffffff8e16600081815260ce9099528389208a5181559751888401559351600290970180549151965115156901000000000000000000027fffffffffffffffffffffffffffffffffffffffffffff00ffffffffffffffffff97151568010000000000000000027fffffffffffffffffffffffffffffffffffffffffffffff000000000000000000909316989096169790971717949094169290921790935560cf805492830181559093527facb8d954e2cfef495862221e91bd7523613cf8808827cb33edfe4904cc51bf290180547fffffffffffffffffffffffff0000000000000000000000000000000000000000168217905590517f53087ff85d80a7671594bd2e86b92af22e0b3c2c441c8033bba7399b7b5cbe2390611b99908890889088908890938452602084019290925267ffffffffffffffff1660408301521515606082015260800190565b60405180910390a2505050505050565b600060d381611bba610e10426143fd565b815260200190815260200160002054905090565b73ffffffffffffffffffffffffffffffffffffffff81166000908152609960205260408120546109a9565b611c033382613092565b50565b60606037805461079f90614325565b60cd5473ffffffffffffffffffffffffffffffffffffffff163314611c66576040517fb90cdbb100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff8116600081815260cc602052604080822080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00166001179055517f98c15241d6c02bc5ee0b780e11b3ea737a2defd9d04877edbe9f9497065bd02f9190a250565b60cd546040517f521d4de900000000000000000000000000000000000000000000000000000000815233600482015273ffffffffffffffffffffffffffffffffffffffff9091169063521d4de990602401602060405180830381865afa158015611d4b573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611d6f9190614372565b611da5576040517f99e120bc00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff8216600090815260ce602052604090206002015468010000000000000000900460ff16611e13576040517fc1ab6dc100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b633b9aca008167ffffffffffffffff161115611e5b576040517feca1d2c600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff8216600081815260ce602090815260409182902060020180547fffffffffffffffffffffffffffffffffffffffffffffffff00000000000000001667ffffffffffffffff861690811790915591519182527f901f9de19b475adc8da4110434b8df940dce085afd05e2281c86807f3a899d299101610989565b33600081815260346020908152604080832073ffffffffffffffffffffffffffffffffffffffff8716845290915281205490919083811015611fb2576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602560248201527f45524332303a2064656372656173656420616c6c6f77616e63652062656c6f7760448201527f207a65726f00000000000000000000000000000000000000000000000000000060648201526084015b60405180910390fd5b610dd78286868403612911565b6000336109a3818585612ddf565b60cf8181548110611fdd57600080fd5b60009182526020909120015473ffffffffffffffffffffffffffffffffffffffff16905081565b606060cf80548060200260200160405190810160405280929190818152602001828054801561081857602002820191906000526020600020905b815473ffffffffffffffffffffffffffffffffffffffff16815260019091019060200180831161203e575050505050905090565b73ffffffffffffffffffffffffffffffffffffffff8316600090815260ce60209081526040808320815160a081018352815481526001820154938101939093526002015467ffffffffffffffff81169183019190915260ff680100000000000000008204811615801560608501526901000000000000000000909204161515608083015280612102575080608001515b15612139576040517fc1ab6dc100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000612147610e10426143fd565b600081815260d36020526040812054919250906121659087906143ea565b905060d2548111156121a3576040517f6d43d1ac00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600082815260d3602052604090208190556121be3387613092565b33600090815260d1602052604081205487910361220b57633b9aca00846040015167ffffffffffffffff16826121f49190614438565b6121fe91906143fd565b61220890826143be565b90505b61222c73ffffffffffffffffffffffffffffffffffffffff89168783612abc565b979650505050505050565b834211156122a1576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f45524332305065726d69743a206578706972656420646561646c696e650000006044820152606401611fa9565b60007f6e71edae12b1b97f4d1f60370fef10105fa2faae0126114a169c64845d6126c98888886122d08c6133b5565b60408051602081019690965273ffffffffffffffffffffffffffffffffffffffff94851690860152929091166060840152608083015260a082015260c0810186905260e0016040516020818303038152906040528051906020012090506000612338826133ea565b9050600061234882878787613453565b90508973ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16146123df576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601e60248201527f45524332305065726d69743a20696e76616c6964207369676e617475726500006044820152606401611fa9565b6123ea8a8a8a612911565b50505050505050505050565b60cd546040517f521d4de900000000000000000000000000000000000000000000000000000000815233600482015273ffffffffffffffffffffffffffffffffffffffff9091169063521d4de990602401602060405180830381865afa158015612464573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906124889190614372565b6124be576040517f99e120bc00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff8116600090815260ce602052604090206002015468010000000000000000900460ff1661252c576040517fc1ab6dc100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff8116600081815260ce602090815260409182902060020180547fffffffffffffffffffffffffffffffffffffffffffff00ffffffffffffffffff811669010000000000000000009182900460ff16801592830291909117909255925192835292917ff7c93079dcbf699749d66345a351afab7d24219bb1d915c9f4fc4cf03f00d3979101610989565b60cd5473ffffffffffffffffffffffffffffffffffffffff16331461261b576040517fb90cdbb100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60cd80547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83169081179091556040517f7dae230f18360d76a040c81f050aa14eb9d6dc7901b20fc5d855e2a20fe814d190600090a250565b73ffffffffffffffffffffffffffffffffffffffff163b151590565b600054610100900460ff16158080156126c65750600054600160ff909116105b806126e05750303b1580156126e0575060005460ff166001145b61276c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201527f647920696e697469616c697a65640000000000000000000000000000000000006064820152608401611fa9565b600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0016600117905580156127ca57600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff166101001790555b3073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1663e9cbd8226040518163ffffffff1660e01b8152600401602060405180830381865afa15801561282c573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061285091906144e5565b73ffffffffffffffffffffffffffffffffffffffff161461289d576040517f14bcf5c800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6128a884848461347b565b801561290b57600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15b50505050565b73ffffffffffffffffffffffffffffffffffffffff83166129b3576040517f08c379a0000000000000000000000000000000000000000000000000000000008152602060048201526024808201527f45524332303a20617070726f76652066726f6d20746865207a65726f2061646460448201527f72657373000000000000000000000000000000000000000000000000000000006064820152608401611fa9565b73ffffffffffffffffffffffffffffffffffffffff8216612a56576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602260248201527f45524332303a20617070726f766520746f20746865207a65726f20616464726560448201527f73730000000000000000000000000000000000000000000000000000000000006064820152608401611fa9565b73ffffffffffffffffffffffffffffffffffffffff83811660008181526034602090815260408083209487168084529482529182902085905590518481527f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b9259101610af7565b60405173ffffffffffffffffffffffffffffffffffffffff831660248201526044810182905261082d9084907fa9059cbb00000000000000000000000000000000000000000000000000000000906064015b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff00000000000000000000000000000000000000000000000000000000909316929092179091526134ff565b60405173ffffffffffffffffffffffffffffffffffffffff8085166024830152831660448201526064810182905261290b9085907f23b872dd0000000000000000000000000000000000000000000000000000000090608401612b0e565b73ffffffffffffffffffffffffffffffffffffffff8216612c6b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601f60248201527f45524332303a206d696e7420746f20746865207a65726f2061646472657373006044820152606401611fa9565b8060356000828254612c7d91906143ea565b909155505073ffffffffffffffffffffffffffffffffffffffff821660009081526033602052604081208054839290612cb79084906143ea565b909155505060405181815273ffffffffffffffffffffffffffffffffffffffff8316906000907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef9060200160405180910390a35050565b73ffffffffffffffffffffffffffffffffffffffff8381166000908152603460209081526040808320938616835292905220547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff811461290b5781811015612dd2576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f45524332303a20696e73756666696369656e7420616c6c6f77616e63650000006044820152606401611fa9565b61290b8484848403612911565b73ffffffffffffffffffffffffffffffffffffffff8316612e82576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602560248201527f45524332303a207472616e736665722066726f6d20746865207a65726f20616460448201527f64726573730000000000000000000000000000000000000000000000000000006064820152608401611fa9565b73ffffffffffffffffffffffffffffffffffffffff8216612f25576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602360248201527f45524332303a207472616e7366657220746f20746865207a65726f206164647260448201527f65737300000000000000000000000000000000000000000000000000000000006064820152608401611fa9565b73ffffffffffffffffffffffffffffffffffffffff831660009081526033602052604090205481811015612fdb576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f45524332303a207472616e7366657220616d6f756e742065786365656473206260448201527f616c616e636500000000000000000000000000000000000000000000000000006064820152608401611fa9565b73ffffffffffffffffffffffffffffffffffffffff80851660009081526033602052604080822085850390559185168152908120805484929061301f9084906143ea565b925050819055508273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef8460405161308591815260200190565b60405180910390a361290b565b73ffffffffffffffffffffffffffffffffffffffff8216613135576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602160248201527f45524332303a206275726e2066726f6d20746865207a65726f2061646472657360448201527f73000000000000000000000000000000000000000000000000000000000000006064820152608401611fa9565b73ffffffffffffffffffffffffffffffffffffffff8216600090815260336020526040902054818110156131eb576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602260248201527f45524332303a206275726e20616d6f756e7420657863656564732062616c616e60448201527f63650000000000000000000000000000000000000000000000000000000000006064820152608401611fa9565b73ffffffffffffffffffffffffffffffffffffffff831660009081526033602052604081208383039055603580548492906132279084906143be565b909155505060405182815260009073ffffffffffffffffffffffffffffffffffffffff8516907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef9060200160405180910390a3505050565b8073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff16146133305773ffffffffffffffffffffffffffffffffffffffff8281166000908152603460209081526040808320938516835292905220548381101561331f576040517f715ec26c00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b61332e838361150b87856143be565b505b61082d8284613092565b600061132f7f8b73c3c69bb8fe3d512ecc4cf759cc79239f7b179b0ffacaa9a75d522b39400f61336960655490565b6066546040805160208101859052908101839052606081018290524660808201523060a082015260009060c0016040516020818303038152906040528051906020012090509392505050565b73ffffffffffffffffffffffffffffffffffffffff811660009081526099602052604090208054600181018255905b50919050565b60006109a96133f761333a565b836040517f19010000000000000000000000000000000000000000000000000000000000006020820152602281018390526042810182905260009060620160405160208183030381529060405280519060200120905092915050565b60008060006134648787878761360b565b9150915061347181613723565b5095945050505050565b61348483613977565b61348e8383613a4d565b60cd80547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83169081179091556040517f7dae230f18360d76a040c81f050aa14eb9d6dc7901b20fc5d855e2a20fe814d190600090a2505050565b6000613561826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c65648152508573ffffffffffffffffffffffffffffffffffffffff16613aee9092919063ffffffff16565b80519091501561082d578080602001905181019061357f9190614372565b61082d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e60448201527f6f742073756363656564000000000000000000000000000000000000000000006064820152608401611fa9565b6000807f7fffffffffffffffffffffffffffffff5d576e7357a4501ddfe92f46681b20a0831115613642575060009050600361371a565b8460ff16601b1415801561365a57508460ff16601c14155b1561366b575060009050600461371a565b6040805160008082526020820180845289905260ff881692820192909252606081018690526080810185905260019060a0016020604051602081039080840390855afa1580156136bf573d6000803e3d6000fd5b50506040517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0015191505073ffffffffffffffffffffffffffffffffffffffff81166137135760006001925092505061371a565b9150600090505b94509492505050565b600081600481111561373757613737614502565b0361373f5750565b600181600481111561375357613753614502565b036137ba576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601860248201527f45434453413a20696e76616c6964207369676e617475726500000000000000006044820152606401611fa9565b60028160048111156137ce576137ce614502565b03613835576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601f60248201527f45434453413a20696e76616c6964207369676e6174757265206c656e677468006044820152606401611fa9565b600381600481111561384957613849614502565b036138d6576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602260248201527f45434453413a20696e76616c6964207369676e6174757265202773272076616c60448201527f75650000000000000000000000000000000000000000000000000000000000006064820152608401611fa9565b60048160048111156138ea576138ea614502565b03611c03576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602260248201527f45434453413a20696e76616c6964207369676e6174757265202776272076616c60448201527f75650000000000000000000000000000000000000000000000000000000000006064820152608401611fa9565b600054610100900460ff16613a0e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201527f6e697469616c697a696e670000000000000000000000000000000000000000006064820152608401611fa9565b611c03816040518060400160405280600181526020017f3100000000000000000000000000000000000000000000000000000000000000815250613b05565b600054610100900460ff16613ae4576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201527f6e697469616c697a696e670000000000000000000000000000000000000000006064820152608401611fa9565b610e358282613bb6565b6060613afd8484600085613c66565b949350505050565b600054610100900460ff16613b9c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201527f6e697469616c697a696e670000000000000000000000000000000000000000006064820152608401611fa9565b815160209283012081519190920120606591909155606655565b600054610100900460ff16613c4d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201527f6e697469616c697a696e670000000000000000000000000000000000000000006064820152608401611fa9565b6036613c59838261457f565b50603761082d828261457f565b606082471015613cf8576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f60448201527f722063616c6c00000000000000000000000000000000000000000000000000006064820152608401611fa9565b73ffffffffffffffffffffffffffffffffffffffff85163b613d76576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006044820152606401611fa9565b6000808673ffffffffffffffffffffffffffffffffffffffff168587604051613d9f9190614699565b60006040518083038185875af1925050503d8060008114613ddc576040519150601f19603f3d011682016040523d82523d6000602084013e613de1565b606091505b509150915061222c82828660608315613dfb575081610db7565b825115613e0b5782518084602001fd5b816040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611fa99190613e63565b60005b83811015613e5a578181015183820152602001613e42565b50506000910152565b6020815260008251806020840152613e82816040850160208701613e3f565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169190910160400192915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b600082601f830112613ef457600080fd5b813567ffffffffffffffff80821115613f0f57613f0f613eb4565b604051601f83017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0908116603f01168101908282118183101715613f5557613f55613eb4565b81604052838152866020858801011115613f6e57600080fd5b836020870160208301376000602085830101528094505050505092915050565b73ffffffffffffffffffffffffffffffffffffffff81168114611c0357600080fd5b600080600060608486031215613fc557600080fd5b833567ffffffffffffffff80821115613fdd57600080fd5b613fe987838801613ee3565b94506020860135915080821115613fff57600080fd5b5061400c86828701613ee3565b925050604084013561401d81613f8e565b809150509250925092565b60006020828403121561403a57600080fd5b8135610db781613f8e565b6000806040838503121561405857600080fd5b823561406381613f8e565b946020939093013593505050565b60008060006060848603121561408657600080fd5b833561409181613f8e565b925060208401356140a181613f8e565b929592945050506040919091013590565b6000806000606084860312156140c757600080fd5b83356140d281613f8e565b925060208401359150604084013561401d81613f8e565b600080604083850312156140fc57600080fd5b82359150602083013561410e81613f8e565b809150509250929050565b60008060006060848603121561412e57600080fd5b83359250602084013561414081613f8e565b9150604084013561401d81613f8e565b60006020828403121561416257600080fd5b5035919050565b803567ffffffffffffffff8116811461418157600080fd5b919050565b8015158114611c0357600080fd5b600080600080600060a086880312156141ac57600080fd5b85356141b781613f8e565b945060208601359350604086013592506141d360608701614169565b915060808601356141e381614186565b809150509295509295909350565b6000806040838503121561420457600080fd5b823561420f81613f8e565b915061421d60208401614169565b90509250929050565b6020808252825182820181905260009190848201906040850190845b8181101561427457835173ffffffffffffffffffffffffffffffffffffffff1683529284019291840191600101614242565b50909695505050505050565b600080600080600080600060e0888a03121561429b57600080fd5b87356142a681613f8e565b965060208801356142b681613f8e565b95506040880135945060608801359350608088013560ff811681146142da57600080fd5b9699959850939692959460a0840135945060c09093013592915050565b6000806040838503121561430a57600080fd5b823561431581613f8e565b9150602083013561410e81613f8e565b600181811c9082168061433957607f821691505b6020821081036133e4577f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b60006020828403121561438457600080fd5b8151610db781614186565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b818103818111156109a9576109a961438f565b6000602082840312156143e357600080fd5b5051919050565b808201808211156109a9576109a961438f565b600082614433577f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b500490565b80820281158282048414176109a9576109a961438f565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82036144af576144af61438f565b5060010190565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603160045260246000fd5b6000602082840312156144f757600080fd5b8151610db781613f8e565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b601f82111561082d57600081815260208120601f850160051c810160208610156145585750805b601f850160051c820191505b8181101561457757828155600101614564565b505050505050565b815167ffffffffffffffff81111561459957614599613eb4565b6145ad816145a78454614325565b84614531565b602080601f83116001811461460057600084156145ca5750858301515b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600386901b1c1916600185901b178555614577565b6000858152602081207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08616915b8281101561464d5788860151825594840194600190910190840161462e565b508582101561468957878501517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600388901b60f8161c191681555b5050505050600190811b01905550565b600082516146ab818460208701613e3f565b919091019291505056fea264697066735822122063a1b6264cdcf054e5097307e409d188b47c62ad909903d6edaf55a3d2b19dee64736f6c63430008110033", + "numDeployments": 2, + "solcInputHash": "871924e0c138825a2736b76def8fef8d", + "metadata": "{\"compiler\":{\"version\":\"0.8.17+commit.8df45f5f\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[],\"name\":\"AssetStillControlledInReserves\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"BurnAmountExceedsAllowance\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"HourlyLimitExceeded\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidSender\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidToken\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidTreasury\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"NotGovernor\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"NotGovernorOrGuardian\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"NotMinter\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"NotTreasury\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"TooBigAmount\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"TooHighParameterValue\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ZeroAddress\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"spender\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"}],\"name\":\"Approval\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"bridgeToken\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"limit\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"hourlyLimit\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"fee\",\"type\":\"uint64\"},{\"indexed\":false,\"internalType\":\"bool\",\"name\":\"paused\",\"type\":\"bool\"}],\"name\":\"BridgeTokenAdded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"bridgeToken\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"fee\",\"type\":\"uint64\"}],\"name\":\"BridgeTokenFeeUpdated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"bridgeToken\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"hourlyLimit\",\"type\":\"uint256\"}],\"name\":\"BridgeTokenHourlyLimitUpdated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"bridgeToken\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"limit\",\"type\":\"uint256\"}],\"name\":\"BridgeTokenLimitUpdated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"bridgeToken\",\"type\":\"address\"}],\"name\":\"BridgeTokenRemoved\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"bridgeToken\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"bool\",\"name\":\"toggleStatus\",\"type\":\"bool\"}],\"name\":\"BridgeTokenToggled\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"theAddress\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"toggleStatus\",\"type\":\"uint256\"}],\"name\":\"FeeToggled\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"hourlyLimit\",\"type\":\"uint256\"}],\"name\":\"HourlyLimitUpdated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint8\",\"name\":\"version\",\"type\":\"uint8\"}],\"name\":\"Initialized\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"minter\",\"type\":\"address\"}],\"name\":\"MinterToggled\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"Recovered\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"}],\"name\":\"Transfer\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"_treasury\",\"type\":\"address\"}],\"name\":\"TreasuryUpdated\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"BASE_PARAMS\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"DOMAIN_SEPARATOR\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"bridgeToken\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"limit\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"hourlyLimit\",\"type\":\"uint256\"},{\"internalType\":\"uint64\",\"name\":\"fee\",\"type\":\"uint64\"},{\"internalType\":\"bool\",\"name\":\"paused\",\"type\":\"bool\"}],\"name\":\"addBridgeToken\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"minter\",\"type\":\"address\"}],\"name\":\"addMinter\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"allBridgeTokens\",\"outputs\":[{\"internalType\":\"address[]\",\"name\":\"\",\"type\":\"address[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"spender\",\"type\":\"address\"}],\"name\":\"allowance\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"spender\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"approve\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"}],\"name\":\"balanceOf\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"name\":\"bridgeTokensList\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"bridges\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"limit\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"hourlyLimit\",\"type\":\"uint256\"},{\"internalType\":\"uint64\",\"name\":\"fee\",\"type\":\"uint64\"},{\"internalType\":\"bool\",\"name\":\"allowed\",\"type\":\"bool\"},{\"internalType\":\"bool\",\"name\":\"paused\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"burner\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"}],\"name\":\"burnFrom\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"burner\",\"type\":\"address\"}],\"name\":\"burnSelf\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"burnStablecoin\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"chainTotalHourlyLimit\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"name\":\"chainTotalUsage\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"currentTotalUsage\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"bridgeToken\",\"type\":\"address\"}],\"name\":\"currentUsage\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"decimals\",\"outputs\":[{\"internalType\":\"uint8\",\"name\":\"\",\"type\":\"uint8\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"spender\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"subtractedValue\",\"type\":\"uint256\"}],\"name\":\"decreaseAllowance\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"spender\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"addedValue\",\"type\":\"uint256\"}],\"name\":\"increaseAllowance\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"string\",\"name\":\"name_\",\"type\":\"string\"},{\"internalType\":\"string\",\"name\":\"symbol_\",\"type\":\"string\"},{\"internalType\":\"address\",\"name\":\"_treasury\",\"type\":\"address\"}],\"name\":\"initialize\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"isFeeExempt\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"isMinter\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"mint\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"name\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"}],\"name\":\"nonces\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"spender\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"deadline\",\"type\":\"uint256\"},{\"internalType\":\"uint8\",\"name\":\"v\",\"type\":\"uint8\"},{\"internalType\":\"bytes32\",\"name\":\"r\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32\",\"name\":\"s\",\"type\":\"bytes32\"}],\"name\":\"permit\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"tokenAddress\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amountToRecover\",\"type\":\"uint256\"}],\"name\":\"recoverERC20\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"bridgeToken\",\"type\":\"address\"}],\"name\":\"removeBridgeToken\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"minter\",\"type\":\"address\"}],\"name\":\"removeMinter\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"hourlyLimit\",\"type\":\"uint256\"}],\"name\":\"setChainTotalHourlyLimit\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"bridgeToken\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"hourlyLimit\",\"type\":\"uint256\"}],\"name\":\"setHourlyLimit\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"bridgeToken\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"limit\",\"type\":\"uint256\"}],\"name\":\"setLimit\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"bridgeToken\",\"type\":\"address\"},{\"internalType\":\"uint64\",\"name\":\"fee\",\"type\":\"uint64\"}],\"name\":\"setSwapFee\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_treasury\",\"type\":\"address\"}],\"name\":\"setTreasury\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"bridgeToken\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"swapIn\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"bridgeToken\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"swapOut\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"symbol\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"bridgeToken\",\"type\":\"address\"}],\"name\":\"toggleBridge\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"theAddress\",\"type\":\"address\"}],\"name\":\"toggleFeesForAddress\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"totalSupply\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"transfer\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"transferFrom\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"treasury\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"name\":\"usage\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"}],\"devdoc\":{\"author\":\"Angle Labs, Inc.\",\"details\":\"This contract supports bridge tokens having a minting right on the stablecoin (also referred to as the canonical or the native token)\",\"kind\":\"dev\",\"methods\":{\"DOMAIN_SEPARATOR()\":{\"details\":\"See {IERC20Permit-DOMAIN_SEPARATOR}.\"},\"addBridgeToken(address,uint256,uint256,uint64,bool)\":{\"params\":{\"bridgeToken\":\"Bridge token to add: it should be a version of the stablecoin from another bridge\",\"fee\":\"Fee taken upon swapping for or against this token\",\"hourlyLimit\":\"Limit on the hourly volume for this bridge\",\"limit\":\"Limit on the balance of bridge token this contract could hold\",\"paused\":\"Whether swapping for this token should be paused or not\"}},\"addMinter(address)\":{\"details\":\"Zero address checks are performed directly in the `Treasury` contract\",\"params\":{\"minter\":\"Minter address to add\"}},\"allBridgeTokens()\":{\"details\":\"Helpful for UIs\"},\"allowance(address,address)\":{\"details\":\"See {IERC20-allowance}.\"},\"approve(address,uint256)\":{\"details\":\"See {IERC20-approve}. NOTE: If `amount` is the maximum `uint256`, the allowance is not updated on `transferFrom`. This is semantically equivalent to an infinite approval. Requirements: - `spender` cannot be the zero address.\"},\"balanceOf(address)\":{\"details\":\"See {IERC20-balanceOf}.\"},\"burnFrom(uint256,address,address)\":{\"details\":\"This method is to be called by a contract with the minter right after being requested to do so by a `sender` address willing to burn tokens from another `burner` addressThe method checks the allowance between the `sender` and the `burner`\",\"params\":{\"amount\":\"Amount of tokens to burn\",\"burner\":\"Address to burn from\",\"sender\":\"Address which requested the burn from `burner`\"}},\"burnSelf(uint256,address)\":{\"details\":\"This method is to be called by a contract with a minter right on the AgToken after being requested to do so by an address willing to burn tokens from its address\",\"params\":{\"amount\":\"Amount of tokens to burn\",\"burner\":\"Address to burn from\"}},\"burnStablecoin(uint256)\":{\"details\":\"This function can typically be called if there is a settlement mechanism to burn stablecoins\",\"params\":{\"amount\":\"Amount of stablecoins to burn\"}},\"currentTotalUsage()\":{\"details\":\"Helpful for UIs\"},\"currentUsage(address)\":{\"details\":\"Helpful for UIs\",\"params\":{\"bridgeToken\":\"Bridge used to mint\"}},\"decimals()\":{\"details\":\"Returns the number of decimals used to get its user representation. For example, if `decimals` equals `2`, a balance of `505` tokens should be displayed to a user as `5.05` (`505 / 10 ** 2`). Tokens usually opt for a value of 18, imitating the relationship between Ether and Wei. This is the value {ERC20} uses, unless this function is overridden; NOTE: This information is only used for _display_ purposes: it in no way affects any of the arithmetic of the contract, including {IERC20-balanceOf} and {IERC20-transfer}.\"},\"decreaseAllowance(address,uint256)\":{\"details\":\"Atomically decreases the allowance granted to `spender` by the caller. This is an alternative to {approve} that can be used as a mitigation for problems described in {IERC20-approve}. Emits an {Approval} event indicating the updated allowance. Requirements: - `spender` cannot be the zero address. - `spender` must have allowance for the caller of at least `subtractedValue`.\"},\"increaseAllowance(address,uint256)\":{\"details\":\"Atomically increases the allowance granted to `spender` by the caller. This is an alternative to {approve} that can be used as a mitigation for problems described in {IERC20-approve}. Emits an {Approval} event indicating the updated allowance. Requirements: - `spender` cannot be the zero address.\"},\"mint(address,uint256)\":{\"details\":\"The contracts allowed to issue agTokens are the `StableMaster` contract, `VaultManager` contracts associated to this stablecoin as well as the flash loan module (if activated) and potentially contracts whitelisted by governance\",\"params\":{\"account\":\"Address to mint to\",\"amount\":\"Amount to mint\"}},\"name()\":{\"details\":\"Returns the name of the token.\"},\"nonces(address)\":{\"details\":\"See {IERC20Permit-nonces}.\"},\"permit(address,address,uint256,uint256,uint8,bytes32,bytes32)\":{\"details\":\"See {IERC20Permit-permit}.\"},\"recoverERC20(address,address,uint256)\":{\"details\":\"Can be used to withdraw bridge tokens for them to be de-bridged on mainnet\"},\"removeBridgeToken(address)\":{\"params\":{\"bridgeToken\":\"Address of the bridge token to remove support for\"}},\"removeMinter(address)\":{\"details\":\"This function can also be called by a minter wishing to revoke itself\",\"params\":{\"minter\":\"Minter address to remove\"}},\"setTreasury(address)\":{\"params\":{\"_treasury\":\"New treasury address\"}},\"swapIn(address,uint256,address)\":{\"details\":\"Some fees may be taken by the protocol depending on the token used and on the address calling\",\"params\":{\"amount\":\"Amount of bridge tokens to send\",\"bridgeToken\":\"Bridge token to use to mint\",\"to\":\"Address to which the stablecoin should be sent\"},\"returns\":{\"_0\":\"Amount of the canonical stablecoin actually minted\"}},\"swapOut(address,uint256,address)\":{\"details\":\"Some fees may be taken by the protocol depending on the token used and on the address calling\",\"params\":{\"amount\":\"Amount of canonical tokens to burn\",\"bridgeToken\":\"Bridge token required\",\"to\":\"Address to which the bridge token should be sent\"},\"returns\":{\"_0\":\"Amount of bridge tokens actually sent back\"}},\"symbol()\":{\"details\":\"Returns the symbol of the token, usually a shorter version of the name.\"},\"totalSupply()\":{\"details\":\"See {IERC20-totalSupply}.\"},\"transfer(address,uint256)\":{\"details\":\"See {IERC20-transfer}. Requirements: - `to` cannot be the zero address. - the caller must have a balance of at least `amount`.\"},\"transferFrom(address,address,uint256)\":{\"details\":\"See {IERC20-transferFrom}. Emits an {Approval} event indicating the updated allowance. This is not required by the EIP. See the note at the beginning of {ERC20}. NOTE: Does not update the allowance if the current allowance is the maximum `uint256`. Requirements: - `from` and `to` cannot be the zero address. - `from` must have a balance of at least `amount`. - the caller must have allowance for ``from``'s tokens of at least `amount`.\"}},\"title\":\"AgTokenSideChainMultiBridge\",\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{\"BASE_PARAMS()\":{\"notice\":\"Base used for fee computation\"},\"addBridgeToken(address,uint256,uint256,uint64,bool)\":{\"notice\":\"Adds support for a bridge token\"},\"addMinter(address)\":{\"notice\":\"Adds a minter in the contract\"},\"allBridgeTokens()\":{\"notice\":\"Returns the list of all supported bridge tokens\"},\"bridgeTokensList(uint256)\":{\"notice\":\"List of all bridge tokens\"},\"bridges(address)\":{\"notice\":\"Maps a bridge token to data\"},\"burnFrom(uint256,address,address)\":{\"notice\":\"Burns `amount` tokens from a `burner` address after being asked to by `sender`\"},\"burnSelf(uint256,address)\":{\"notice\":\"Burns `amount` tokens from a `burner` address\"},\"burnStablecoin(uint256)\":{\"notice\":\"Allows anyone to burn stablecoins\"},\"chainTotalHourlyLimit()\":{\"notice\":\"Limit to the amount of tokens that can be sent from that chain to another chain\"},\"chainTotalUsage(uint256)\":{\"notice\":\"Usage per hour on that chain. Maps an hourly timestamp to the total volume swapped out on the chain\"},\"currentTotalUsage()\":{\"notice\":\"Returns the current total volume on the chain for the current hour\"},\"currentUsage(address)\":{\"notice\":\"Returns the current volume for a bridge, for the current hour\"},\"initialize(string,string,address)\":{\"notice\":\"Initializes the `AgToken` contract\"},\"isFeeExempt(address)\":{\"notice\":\"Maps an address to whether it is exempt of fees for when it comes to swapping in and out\"},\"isMinter(address)\":{\"notice\":\"Checks whether an address has the right to mint agTokens\"},\"mint(address,uint256)\":{\"notice\":\"Lets the `StableMaster` contract or another whitelisted contract mint agTokens\"},\"recoverERC20(address,address,uint256)\":{\"notice\":\"Recovers any ERC20 token\"},\"removeBridgeToken(address)\":{\"notice\":\"Removes support for a token\"},\"removeMinter(address)\":{\"notice\":\"Removes a minter from the contract\"},\"setChainTotalHourlyLimit(uint256)\":{\"notice\":\"Updates the `chainTotalHourlyLimit` amount\"},\"setHourlyLimit(address,uint256)\":{\"notice\":\"Updates the `hourlyLimit` amount for `bridgeToken`\"},\"setLimit(address,uint256)\":{\"notice\":\"Updates the `limit` amount for `bridgeToken`\"},\"setSwapFee(address,uint64)\":{\"notice\":\"Updates the `fee` value for `bridgeToken`\"},\"setTreasury(address)\":{\"notice\":\"Sets a new treasury contract\"},\"swapIn(address,uint256,address)\":{\"notice\":\"Mints the canonical token from a supported bridge token\"},\"swapOut(address,uint256,address)\":{\"notice\":\"Burns the canonical token in exchange for a bridge token\"},\"toggleBridge(address)\":{\"notice\":\"Pauses or unpauses swapping in and out for a token\"},\"toggleFeesForAddress(address)\":{\"notice\":\"Toggles fees for the address `theAddress`\"},\"treasury()\":{\"notice\":\"Reference to the treasury contract which can grant minting rights\"},\"usage(address,uint256)\":{\"notice\":\"Maps a bridge token to the associated hourly volume\"}},\"notice\":\"Contract for Angle agTokens on other chains than Ethereum mainnet\",\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/agToken/AgTokenSideChainMultiBridge.sol\":\"AgTokenSideChainMultiBridge\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":1000000},\"remappings\":[]},\"sources\":{\"@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.7.0) (proxy/utils/Initializable.sol)\\n\\npragma solidity ^0.8.2;\\n\\nimport \\\"../../utils/AddressUpgradeable.sol\\\";\\n\\n/**\\n * @dev This is a base contract to aid in writing upgradeable contracts, or any kind of contract that will be deployed\\n * behind a proxy. Since proxied contracts do not make use of a constructor, it's common to move constructor logic to an\\n * external initializer function, usually called `initialize`. It then becomes necessary to protect this initializer\\n * function so it can only be called once. The {initializer} modifier provided by this contract will have this effect.\\n *\\n * The initialization functions use a version number. Once a version number is used, it is consumed and cannot be\\n * reused. This mechanism prevents re-execution of each \\\"step\\\" but allows the creation of new initialization steps in\\n * case an upgrade adds a module that needs to be initialized.\\n *\\n * For example:\\n *\\n * [.hljs-theme-light.nopadding]\\n * ```\\n * contract MyToken is ERC20Upgradeable {\\n * function initialize() initializer public {\\n * __ERC20_init(\\\"MyToken\\\", \\\"MTK\\\");\\n * }\\n * }\\n * contract MyTokenV2 is MyToken, ERC20PermitUpgradeable {\\n * function initializeV2() reinitializer(2) public {\\n * __ERC20Permit_init(\\\"MyToken\\\");\\n * }\\n * }\\n * ```\\n *\\n * TIP: To avoid leaving the proxy in an uninitialized state, the initializer function should be called as early as\\n * possible by providing the encoded function call as the `_data` argument to {ERC1967Proxy-constructor}.\\n *\\n * CAUTION: When used with inheritance, manual care must be taken to not invoke a parent initializer twice, or to ensure\\n * that all initializers are idempotent. This is not verified automatically as constructors are by Solidity.\\n *\\n * [CAUTION]\\n * ====\\n * Avoid leaving a contract uninitialized.\\n *\\n * An uninitialized contract can be taken over by an attacker. This applies to both a proxy and its implementation\\n * contract, which may impact the proxy. To prevent the implementation contract from being used, you should invoke\\n * the {_disableInitializers} function in the constructor to automatically lock it when it is deployed:\\n *\\n * [.hljs-theme-light.nopadding]\\n * ```\\n * /// @custom:oz-upgrades-unsafe-allow constructor\\n * constructor() {\\n * _disableInitializers();\\n * }\\n * ```\\n * ====\\n */\\nabstract contract Initializable {\\n /**\\n * @dev Indicates that the contract has been initialized.\\n * @custom:oz-retyped-from bool\\n */\\n uint8 private _initialized;\\n\\n /**\\n * @dev Indicates that the contract is in the process of being initialized.\\n */\\n bool private _initializing;\\n\\n /**\\n * @dev Triggered when the contract has been initialized or reinitialized.\\n */\\n event Initialized(uint8 version);\\n\\n /**\\n * @dev A modifier that defines a protected initializer function that can be invoked at most once. In its scope,\\n * `onlyInitializing` functions can be used to initialize parent contracts. Equivalent to `reinitializer(1)`.\\n */\\n modifier initializer() {\\n bool isTopLevelCall = !_initializing;\\n require(\\n (isTopLevelCall && _initialized < 1) || (!AddressUpgradeable.isContract(address(this)) && _initialized == 1),\\n \\\"Initializable: contract is already initialized\\\"\\n );\\n _initialized = 1;\\n if (isTopLevelCall) {\\n _initializing = true;\\n }\\n _;\\n if (isTopLevelCall) {\\n _initializing = false;\\n emit Initialized(1);\\n }\\n }\\n\\n /**\\n * @dev A modifier that defines a protected reinitializer function that can be invoked at most once, and only if the\\n * contract hasn't been initialized to a greater version before. In its scope, `onlyInitializing` functions can be\\n * used to initialize parent contracts.\\n *\\n * `initializer` is equivalent to `reinitializer(1)`, so a reinitializer may be used after the original\\n * initialization step. This is essential to configure modules that are added through upgrades and that require\\n * initialization.\\n *\\n * Note that versions can jump in increments greater than 1; this implies that if multiple reinitializers coexist in\\n * a contract, executing them in the right order is up to the developer or operator.\\n */\\n modifier reinitializer(uint8 version) {\\n require(!_initializing && _initialized < version, \\\"Initializable: contract is already initialized\\\");\\n _initialized = version;\\n _initializing = true;\\n _;\\n _initializing = false;\\n emit Initialized(version);\\n }\\n\\n /**\\n * @dev Modifier to protect an initialization function so that it can only be invoked by functions with the\\n * {initializer} and {reinitializer} modifiers, directly or indirectly.\\n */\\n modifier onlyInitializing() {\\n require(_initializing, \\\"Initializable: contract is not initializing\\\");\\n _;\\n }\\n\\n /**\\n * @dev Locks the contract, preventing any future reinitialization. This cannot be part of an initializer call.\\n * Calling this in the constructor of a contract will prevent that contract from being initialized or reinitialized\\n * to any version. It is recommended to use this to lock implementation contracts that are designed to be called\\n * through proxies.\\n */\\n function _disableInitializers() internal virtual {\\n require(!_initializing, \\\"Initializable: contract is initializing\\\");\\n if (_initialized < type(uint8).max) {\\n _initialized = type(uint8).max;\\n emit Initialized(type(uint8).max);\\n }\\n }\\n}\\n\",\"keccak256\":\"0x0203dcadc5737d9ef2c211d6fa15d18ebc3b30dfa51903b64870b01a062b0b4e\",\"license\":\"MIT\"},\"@openzeppelin/contracts-upgradeable/token/ERC20/ERC20Upgradeable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.7.0) (token/ERC20/ERC20.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"./IERC20Upgradeable.sol\\\";\\nimport \\\"./extensions/IERC20MetadataUpgradeable.sol\\\";\\nimport \\\"../../utils/ContextUpgradeable.sol\\\";\\nimport \\\"../../proxy/utils/Initializable.sol\\\";\\n\\n/**\\n * @dev Implementation of the {IERC20} interface.\\n *\\n * This implementation is agnostic to the way tokens are created. This means\\n * that a supply mechanism has to be added in a derived contract using {_mint}.\\n * For a generic mechanism see {ERC20PresetMinterPauser}.\\n *\\n * TIP: For a detailed writeup see our guide\\n * https://forum.zeppelin.solutions/t/how-to-implement-erc20-supply-mechanisms/226[How\\n * to implement supply mechanisms].\\n *\\n * We have followed general OpenZeppelin Contracts guidelines: functions revert\\n * instead returning `false` on failure. This behavior is nonetheless\\n * conventional and does not conflict with the expectations of ERC20\\n * applications.\\n *\\n * Additionally, an {Approval} event is emitted on calls to {transferFrom}.\\n * This allows applications to reconstruct the allowance for all accounts just\\n * by listening to said events. Other implementations of the EIP may not emit\\n * these events, as it isn't required by the specification.\\n *\\n * Finally, the non-standard {decreaseAllowance} and {increaseAllowance}\\n * functions have been added to mitigate the well-known issues around setting\\n * allowances. See {IERC20-approve}.\\n */\\ncontract ERC20Upgradeable is Initializable, ContextUpgradeable, IERC20Upgradeable, IERC20MetadataUpgradeable {\\n mapping(address => uint256) private _balances;\\n\\n mapping(address => mapping(address => uint256)) private _allowances;\\n\\n uint256 private _totalSupply;\\n\\n string private _name;\\n string private _symbol;\\n\\n /**\\n * @dev Sets the values for {name} and {symbol}.\\n *\\n * The default value of {decimals} is 18. To select a different value for\\n * {decimals} you should overload it.\\n *\\n * All two of these values are immutable: they can only be set once during\\n * construction.\\n */\\n function __ERC20_init(string memory name_, string memory symbol_) internal onlyInitializing {\\n __ERC20_init_unchained(name_, symbol_);\\n }\\n\\n function __ERC20_init_unchained(string memory name_, string memory symbol_) internal onlyInitializing {\\n _name = name_;\\n _symbol = symbol_;\\n }\\n\\n /**\\n * @dev Returns the name of the token.\\n */\\n function name() public view virtual override returns (string memory) {\\n return _name;\\n }\\n\\n /**\\n * @dev Returns the symbol of the token, usually a shorter version of the\\n * name.\\n */\\n function symbol() public view virtual override returns (string memory) {\\n return _symbol;\\n }\\n\\n /**\\n * @dev Returns the number of decimals used to get its user representation.\\n * For example, if `decimals` equals `2`, a balance of `505` tokens should\\n * be displayed to a user as `5.05` (`505 / 10 ** 2`).\\n *\\n * Tokens usually opt for a value of 18, imitating the relationship between\\n * Ether and Wei. This is the value {ERC20} uses, unless this function is\\n * overridden;\\n *\\n * NOTE: This information is only used for _display_ purposes: it in\\n * no way affects any of the arithmetic of the contract, including\\n * {IERC20-balanceOf} and {IERC20-transfer}.\\n */\\n function decimals() public view virtual override returns (uint8) {\\n return 18;\\n }\\n\\n /**\\n * @dev See {IERC20-totalSupply}.\\n */\\n function totalSupply() public view virtual override returns (uint256) {\\n return _totalSupply;\\n }\\n\\n /**\\n * @dev See {IERC20-balanceOf}.\\n */\\n function balanceOf(address account) public view virtual override returns (uint256) {\\n return _balances[account];\\n }\\n\\n /**\\n * @dev See {IERC20-transfer}.\\n *\\n * Requirements:\\n *\\n * - `to` cannot be the zero address.\\n * - the caller must have a balance of at least `amount`.\\n */\\n function transfer(address to, uint256 amount) public virtual override returns (bool) {\\n address owner = _msgSender();\\n _transfer(owner, to, amount);\\n return true;\\n }\\n\\n /**\\n * @dev See {IERC20-allowance}.\\n */\\n function allowance(address owner, address spender) public view virtual override returns (uint256) {\\n return _allowances[owner][spender];\\n }\\n\\n /**\\n * @dev See {IERC20-approve}.\\n *\\n * NOTE: If `amount` is the maximum `uint256`, the allowance is not updated on\\n * `transferFrom`. This is semantically equivalent to an infinite approval.\\n *\\n * Requirements:\\n *\\n * - `spender` cannot be the zero address.\\n */\\n function approve(address spender, uint256 amount) public virtual override returns (bool) {\\n address owner = _msgSender();\\n _approve(owner, spender, amount);\\n return true;\\n }\\n\\n /**\\n * @dev See {IERC20-transferFrom}.\\n *\\n * Emits an {Approval} event indicating the updated allowance. This is not\\n * required by the EIP. See the note at the beginning of {ERC20}.\\n *\\n * NOTE: Does not update the allowance if the current allowance\\n * is the maximum `uint256`.\\n *\\n * Requirements:\\n *\\n * - `from` and `to` cannot be the zero address.\\n * - `from` must have a balance of at least `amount`.\\n * - the caller must have allowance for ``from``'s tokens of at least\\n * `amount`.\\n */\\n function transferFrom(\\n address from,\\n address to,\\n uint256 amount\\n ) public virtual override returns (bool) {\\n address spender = _msgSender();\\n _spendAllowance(from, spender, amount);\\n _transfer(from, to, amount);\\n return true;\\n }\\n\\n /**\\n * @dev Atomically increases the allowance granted to `spender` by the caller.\\n *\\n * This is an alternative to {approve} that can be used as a mitigation for\\n * problems described in {IERC20-approve}.\\n *\\n * Emits an {Approval} event indicating the updated allowance.\\n *\\n * Requirements:\\n *\\n * - `spender` cannot be the zero address.\\n */\\n function increaseAllowance(address spender, uint256 addedValue) public virtual returns (bool) {\\n address owner = _msgSender();\\n _approve(owner, spender, allowance(owner, spender) + addedValue);\\n return true;\\n }\\n\\n /**\\n * @dev Atomically decreases the allowance granted to `spender` by the caller.\\n *\\n * This is an alternative to {approve} that can be used as a mitigation for\\n * problems described in {IERC20-approve}.\\n *\\n * Emits an {Approval} event indicating the updated allowance.\\n *\\n * Requirements:\\n *\\n * - `spender` cannot be the zero address.\\n * - `spender` must have allowance for the caller of at least\\n * `subtractedValue`.\\n */\\n function decreaseAllowance(address spender, uint256 subtractedValue) public virtual returns (bool) {\\n address owner = _msgSender();\\n uint256 currentAllowance = allowance(owner, spender);\\n require(currentAllowance >= subtractedValue, \\\"ERC20: decreased allowance below zero\\\");\\n unchecked {\\n _approve(owner, spender, currentAllowance - subtractedValue);\\n }\\n\\n return true;\\n }\\n\\n /**\\n * @dev Moves `amount` of tokens from `from` to `to`.\\n *\\n * This internal function is equivalent to {transfer}, and can be used to\\n * e.g. implement automatic token fees, slashing mechanisms, etc.\\n *\\n * Emits a {Transfer} event.\\n *\\n * Requirements:\\n *\\n * - `from` cannot be the zero address.\\n * - `to` cannot be the zero address.\\n * - `from` must have a balance of at least `amount`.\\n */\\n function _transfer(\\n address from,\\n address to,\\n uint256 amount\\n ) internal virtual {\\n require(from != address(0), \\\"ERC20: transfer from the zero address\\\");\\n require(to != address(0), \\\"ERC20: transfer to the zero address\\\");\\n\\n _beforeTokenTransfer(from, to, amount);\\n\\n uint256 fromBalance = _balances[from];\\n require(fromBalance >= amount, \\\"ERC20: transfer amount exceeds balance\\\");\\n unchecked {\\n _balances[from] = fromBalance - amount;\\n }\\n _balances[to] += amount;\\n\\n emit Transfer(from, to, amount);\\n\\n _afterTokenTransfer(from, to, amount);\\n }\\n\\n /** @dev Creates `amount` tokens and assigns them to `account`, increasing\\n * the total supply.\\n *\\n * Emits a {Transfer} event with `from` set to the zero address.\\n *\\n * Requirements:\\n *\\n * - `account` cannot be the zero address.\\n */\\n function _mint(address account, uint256 amount) internal virtual {\\n require(account != address(0), \\\"ERC20: mint to the zero address\\\");\\n\\n _beforeTokenTransfer(address(0), account, amount);\\n\\n _totalSupply += amount;\\n _balances[account] += amount;\\n emit Transfer(address(0), account, amount);\\n\\n _afterTokenTransfer(address(0), account, amount);\\n }\\n\\n /**\\n * @dev Destroys `amount` tokens from `account`, reducing the\\n * total supply.\\n *\\n * Emits a {Transfer} event with `to` set to the zero address.\\n *\\n * Requirements:\\n *\\n * - `account` cannot be the zero address.\\n * - `account` must have at least `amount` tokens.\\n */\\n function _burn(address account, uint256 amount) internal virtual {\\n require(account != address(0), \\\"ERC20: burn from the zero address\\\");\\n\\n _beforeTokenTransfer(account, address(0), amount);\\n\\n uint256 accountBalance = _balances[account];\\n require(accountBalance >= amount, \\\"ERC20: burn amount exceeds balance\\\");\\n unchecked {\\n _balances[account] = accountBalance - amount;\\n }\\n _totalSupply -= amount;\\n\\n emit Transfer(account, address(0), amount);\\n\\n _afterTokenTransfer(account, address(0), amount);\\n }\\n\\n /**\\n * @dev Sets `amount` as the allowance of `spender` over the `owner` s tokens.\\n *\\n * This internal function is equivalent to `approve`, and can be used to\\n * e.g. set automatic allowances for certain subsystems, etc.\\n *\\n * Emits an {Approval} event.\\n *\\n * Requirements:\\n *\\n * - `owner` cannot be the zero address.\\n * - `spender` cannot be the zero address.\\n */\\n function _approve(\\n address owner,\\n address spender,\\n uint256 amount\\n ) internal virtual {\\n require(owner != address(0), \\\"ERC20: approve from the zero address\\\");\\n require(spender != address(0), \\\"ERC20: approve to the zero address\\\");\\n\\n _allowances[owner][spender] = amount;\\n emit Approval(owner, spender, amount);\\n }\\n\\n /**\\n * @dev Updates `owner` s allowance for `spender` based on spent `amount`.\\n *\\n * Does not update the allowance amount in case of infinite allowance.\\n * Revert if not enough allowance is available.\\n *\\n * Might emit an {Approval} event.\\n */\\n function _spendAllowance(\\n address owner,\\n address spender,\\n uint256 amount\\n ) internal virtual {\\n uint256 currentAllowance = allowance(owner, spender);\\n if (currentAllowance != type(uint256).max) {\\n require(currentAllowance >= amount, \\\"ERC20: insufficient allowance\\\");\\n unchecked {\\n _approve(owner, spender, currentAllowance - amount);\\n }\\n }\\n }\\n\\n /**\\n * @dev Hook that is called before any transfer of tokens. This includes\\n * minting and burning.\\n *\\n * Calling conditions:\\n *\\n * - when `from` and `to` are both non-zero, `amount` of ``from``'s tokens\\n * will be transferred to `to`.\\n * - when `from` is zero, `amount` tokens will be minted for `to`.\\n * - when `to` is zero, `amount` of ``from``'s tokens will be burned.\\n * - `from` and `to` are never both zero.\\n *\\n * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].\\n */\\n function _beforeTokenTransfer(\\n address from,\\n address to,\\n uint256 amount\\n ) internal virtual {}\\n\\n /**\\n * @dev Hook that is called after any transfer of tokens. This includes\\n * minting and burning.\\n *\\n * Calling conditions:\\n *\\n * - when `from` and `to` are both non-zero, `amount` of ``from``'s tokens\\n * has been transferred to `to`.\\n * - when `from` is zero, `amount` tokens have been minted for `to`.\\n * - when `to` is zero, `amount` of ``from``'s tokens have been burned.\\n * - `from` and `to` are never both zero.\\n *\\n * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].\\n */\\n function _afterTokenTransfer(\\n address from,\\n address to,\\n uint256 amount\\n ) internal virtual {}\\n\\n /**\\n * @dev This empty reserved space is put in place to allow future versions to add new\\n * variables without shifting down storage in the inheritance chain.\\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\\n */\\n uint256[45] private __gap;\\n}\\n\",\"keccak256\":\"0x7c7ac0bc6c340a7f320524b9a4b4b079ee9da3c51258080d4bab237f329a427c\",\"license\":\"MIT\"},\"@openzeppelin/contracts-upgradeable/token/ERC20/IERC20Upgradeable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.6.0) (token/ERC20/IERC20.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Interface of the ERC20 standard as defined in the EIP.\\n */\\ninterface IERC20Upgradeable {\\n /**\\n * @dev Emitted when `value` tokens are moved from one account (`from`) to\\n * another (`to`).\\n *\\n * Note that `value` may be zero.\\n */\\n event Transfer(address indexed from, address indexed to, uint256 value);\\n\\n /**\\n * @dev Emitted when the allowance of a `spender` for an `owner` is set by\\n * a call to {approve}. `value` is the new allowance.\\n */\\n event Approval(address indexed owner, address indexed spender, uint256 value);\\n\\n /**\\n * @dev Returns the amount of tokens in existence.\\n */\\n function totalSupply() external view returns (uint256);\\n\\n /**\\n * @dev Returns the amount of tokens owned by `account`.\\n */\\n function balanceOf(address account) external view returns (uint256);\\n\\n /**\\n * @dev Moves `amount` tokens from the caller's account to `to`.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * Emits a {Transfer} event.\\n */\\n function transfer(address to, uint256 amount) external returns (bool);\\n\\n /**\\n * @dev Returns the remaining number of tokens that `spender` will be\\n * allowed to spend on behalf of `owner` through {transferFrom}. This is\\n * zero by default.\\n *\\n * This value changes when {approve} or {transferFrom} are called.\\n */\\n function allowance(address owner, address spender) external view returns (uint256);\\n\\n /**\\n * @dev Sets `amount` as the allowance of `spender` over the caller's tokens.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * IMPORTANT: Beware that changing an allowance with this method brings the risk\\n * that someone may use both the old and the new allowance by unfortunate\\n * transaction ordering. One possible solution to mitigate this race\\n * condition is to first reduce the spender's allowance to 0 and set the\\n * desired value afterwards:\\n * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729\\n *\\n * Emits an {Approval} event.\\n */\\n function approve(address spender, uint256 amount) external returns (bool);\\n\\n /**\\n * @dev Moves `amount` tokens from `from` to `to` using the\\n * allowance mechanism. `amount` is then deducted from the caller's\\n * allowance.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * Emits a {Transfer} event.\\n */\\n function transferFrom(\\n address from,\\n address to,\\n uint256 amount\\n ) external returns (bool);\\n}\\n\",\"keccak256\":\"0x4e733d3164f73f461eaf9d8087a7ad1ea180bdc8ba0d3d61b0e1ae16d8e63dff\",\"license\":\"MIT\"},\"@openzeppelin/contracts-upgradeable/token/ERC20/extensions/IERC20MetadataUpgradeable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (token/ERC20/extensions/IERC20Metadata.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../IERC20Upgradeable.sol\\\";\\n\\n/**\\n * @dev Interface for the optional metadata functions from the ERC20 standard.\\n *\\n * _Available since v4.1._\\n */\\ninterface IERC20MetadataUpgradeable is IERC20Upgradeable {\\n /**\\n * @dev Returns the name of the token.\\n */\\n function name() external view returns (string memory);\\n\\n /**\\n * @dev Returns the symbol of the token.\\n */\\n function symbol() external view returns (string memory);\\n\\n /**\\n * @dev Returns the decimals places of the token.\\n */\\n function decimals() external view returns (uint8);\\n}\\n\",\"keccak256\":\"0x605434219ebbe4653f703640f06969faa5a1d78f0bfef878e5ddbb1ca369ceeb\",\"license\":\"MIT\"},\"@openzeppelin/contracts-upgradeable/token/ERC20/extensions/draft-ERC20PermitUpgradeable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.6.0) (token/ERC20/extensions/draft-ERC20Permit.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"./draft-IERC20PermitUpgradeable.sol\\\";\\nimport \\\"../ERC20Upgradeable.sol\\\";\\nimport \\\"../../../utils/cryptography/draft-EIP712Upgradeable.sol\\\";\\nimport \\\"../../../utils/cryptography/ECDSAUpgradeable.sol\\\";\\nimport \\\"../../../utils/CountersUpgradeable.sol\\\";\\nimport \\\"../../../proxy/utils/Initializable.sol\\\";\\n\\n/**\\n * @dev Implementation of the ERC20 Permit extension allowing approvals to be made via signatures, as defined in\\n * https://eips.ethereum.org/EIPS/eip-2612[EIP-2612].\\n *\\n * Adds the {permit} method, which can be used to change an account's ERC20 allowance (see {IERC20-allowance}) by\\n * presenting a message signed by the account. By not relying on `{IERC20-approve}`, the token holder account doesn't\\n * need to send a transaction, and thus is not required to hold Ether at all.\\n *\\n * _Available since v3.4._\\n *\\n * @custom:storage-size 51\\n */\\nabstract contract ERC20PermitUpgradeable is Initializable, ERC20Upgradeable, IERC20PermitUpgradeable, EIP712Upgradeable {\\n using CountersUpgradeable for CountersUpgradeable.Counter;\\n\\n mapping(address => CountersUpgradeable.Counter) private _nonces;\\n\\n // solhint-disable-next-line var-name-mixedcase\\n bytes32 private constant _PERMIT_TYPEHASH =\\n keccak256(\\\"Permit(address owner,address spender,uint256 value,uint256 nonce,uint256 deadline)\\\");\\n /**\\n * @dev In previous versions `_PERMIT_TYPEHASH` was declared as `immutable`.\\n * However, to ensure consistency with the upgradeable transpiler, we will continue\\n * to reserve a slot.\\n * @custom:oz-renamed-from _PERMIT_TYPEHASH\\n */\\n // solhint-disable-next-line var-name-mixedcase\\n bytes32 private _PERMIT_TYPEHASH_DEPRECATED_SLOT;\\n\\n /**\\n * @dev Initializes the {EIP712} domain separator using the `name` parameter, and setting `version` to `\\\"1\\\"`.\\n *\\n * It's a good idea to use the same `name` that is defined as the ERC20 token name.\\n */\\n function __ERC20Permit_init(string memory name) internal onlyInitializing {\\n __EIP712_init_unchained(name, \\\"1\\\");\\n }\\n\\n function __ERC20Permit_init_unchained(string memory) internal onlyInitializing {}\\n\\n /**\\n * @dev See {IERC20Permit-permit}.\\n */\\n function permit(\\n address owner,\\n address spender,\\n uint256 value,\\n uint256 deadline,\\n uint8 v,\\n bytes32 r,\\n bytes32 s\\n ) public virtual override {\\n require(block.timestamp <= deadline, \\\"ERC20Permit: expired deadline\\\");\\n\\n bytes32 structHash = keccak256(abi.encode(_PERMIT_TYPEHASH, owner, spender, value, _useNonce(owner), deadline));\\n\\n bytes32 hash = _hashTypedDataV4(structHash);\\n\\n address signer = ECDSAUpgradeable.recover(hash, v, r, s);\\n require(signer == owner, \\\"ERC20Permit: invalid signature\\\");\\n\\n _approve(owner, spender, value);\\n }\\n\\n /**\\n * @dev See {IERC20Permit-nonces}.\\n */\\n function nonces(address owner) public view virtual override returns (uint256) {\\n return _nonces[owner].current();\\n }\\n\\n /**\\n * @dev See {IERC20Permit-DOMAIN_SEPARATOR}.\\n */\\n // solhint-disable-next-line func-name-mixedcase\\n function DOMAIN_SEPARATOR() external view override returns (bytes32) {\\n return _domainSeparatorV4();\\n }\\n\\n /**\\n * @dev \\\"Consume a nonce\\\": return the current value and increment.\\n *\\n * _Available since v4.1._\\n */\\n function _useNonce(address owner) internal virtual returns (uint256 current) {\\n CountersUpgradeable.Counter storage nonce = _nonces[owner];\\n current = nonce.current();\\n nonce.increment();\\n }\\n\\n /**\\n * @dev This empty reserved space is put in place to allow future versions to add new\\n * variables without shifting down storage in the inheritance chain.\\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\\n */\\n uint256[49] private __gap;\\n}\\n\",\"keccak256\":\"0x564385ebed633694decce3e13d687f3ac7e8eaef64f7a504bfb3f03ad210601f\",\"license\":\"MIT\"},\"@openzeppelin/contracts-upgradeable/token/ERC20/extensions/draft-IERC20PermitUpgradeable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (token/ERC20/extensions/draft-IERC20Permit.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Interface of the ERC20 Permit extension allowing approvals to be made via signatures, as defined in\\n * https://eips.ethereum.org/EIPS/eip-2612[EIP-2612].\\n *\\n * Adds the {permit} method, which can be used to change an account's ERC20 allowance (see {IERC20-allowance}) by\\n * presenting a message signed by the account. By not relying on {IERC20-approve}, the token holder account doesn't\\n * need to send a transaction, and thus is not required to hold Ether at all.\\n */\\ninterface IERC20PermitUpgradeable {\\n /**\\n * @dev Sets `value` as the allowance of `spender` over ``owner``'s tokens,\\n * given ``owner``'s signed approval.\\n *\\n * IMPORTANT: The same issues {IERC20-approve} has related to transaction\\n * ordering also apply here.\\n *\\n * Emits an {Approval} event.\\n *\\n * Requirements:\\n *\\n * - `spender` cannot be the zero address.\\n * - `deadline` must be a timestamp in the future.\\n * - `v`, `r` and `s` must be a valid `secp256k1` signature from `owner`\\n * over the EIP712-formatted function arguments.\\n * - the signature must use ``owner``'s current nonce (see {nonces}).\\n *\\n * For more information on the signature format, see the\\n * https://eips.ethereum.org/EIPS/eip-2612#specification[relevant EIP\\n * section].\\n */\\n function permit(\\n address owner,\\n address spender,\\n uint256 value,\\n uint256 deadline,\\n uint8 v,\\n bytes32 r,\\n bytes32 s\\n ) external;\\n\\n /**\\n * @dev Returns the current nonce for `owner`. This value must be\\n * included whenever a signature is generated for {permit}.\\n *\\n * Every successful call to {permit} increases ``owner``'s nonce by one. This\\n * prevents a signature from being used multiple times.\\n */\\n function nonces(address owner) external view returns (uint256);\\n\\n /**\\n * @dev Returns the domain separator used in the encoding of the signature for {permit}, as defined by {EIP712}.\\n */\\n // solhint-disable-next-line func-name-mixedcase\\n function DOMAIN_SEPARATOR() external view returns (bytes32);\\n}\\n\",\"keccak256\":\"0xcc70d8e2281fb3ff69e8ab242500f10142cd0a7fa8dd9e45882be270d4d09024\",\"license\":\"MIT\"},\"@openzeppelin/contracts-upgradeable/utils/AddressUpgradeable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.7.0) (utils/Address.sol)\\n\\npragma solidity ^0.8.1;\\n\\n/**\\n * @dev Collection of functions related to the address type\\n */\\nlibrary AddressUpgradeable {\\n /**\\n * @dev Returns true if `account` is a contract.\\n *\\n * [IMPORTANT]\\n * ====\\n * It is unsafe to assume that an address for which this function returns\\n * false is an externally-owned account (EOA) and not a contract.\\n *\\n * Among others, `isContract` will return false for the following\\n * types of addresses:\\n *\\n * - an externally-owned account\\n * - a contract in construction\\n * - an address where a contract will be created\\n * - an address where a contract lived, but was destroyed\\n * ====\\n *\\n * [IMPORTANT]\\n * ====\\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\\n *\\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\\n * constructor.\\n * ====\\n */\\n function isContract(address account) internal view returns (bool) {\\n // This method relies on extcodesize/address.code.length, which returns 0\\n // for contracts in construction, since the code is only stored at the end\\n // of the constructor execution.\\n\\n return account.code.length > 0;\\n }\\n\\n /**\\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\\n * `recipient`, forwarding all available gas and reverting on errors.\\n *\\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\\n * imposed by `transfer`, making them unable to receive funds via\\n * `transfer`. {sendValue} removes this limitation.\\n *\\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\\n *\\n * IMPORTANT: because control is transferred to `recipient`, care must be\\n * taken to not create reentrancy vulnerabilities. Consider using\\n * {ReentrancyGuard} or the\\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\\n */\\n function sendValue(address payable recipient, uint256 amount) internal {\\n require(address(this).balance >= amount, \\\"Address: insufficient balance\\\");\\n\\n (bool success, ) = recipient.call{value: amount}(\\\"\\\");\\n require(success, \\\"Address: unable to send value, recipient may have reverted\\\");\\n }\\n\\n /**\\n * @dev Performs a Solidity function call using a low level `call`. A\\n * plain `call` is an unsafe replacement for a function call: use this\\n * function instead.\\n *\\n * If `target` reverts with a revert reason, it is bubbled up by this\\n * function (like regular Solidity function calls).\\n *\\n * Returns the raw returned data. To convert to the expected return value,\\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\\n *\\n * Requirements:\\n *\\n * - `target` must be a contract.\\n * - calling `target` with `data` must not revert.\\n *\\n * _Available since v3.1._\\n */\\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\\n return functionCall(target, data, \\\"Address: low-level call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\\n * `errorMessage` as a fallback revert reason when `target` reverts.\\n *\\n * _Available since v3.1._\\n */\\n function functionCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n return functionCallWithValue(target, data, 0, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but also transferring `value` wei to `target`.\\n *\\n * Requirements:\\n *\\n * - the calling contract must have an ETH balance of at least `value`.\\n * - the called Solidity function must be `payable`.\\n *\\n * _Available since v3.1._\\n */\\n function functionCallWithValue(\\n address target,\\n bytes memory data,\\n uint256 value\\n ) internal returns (bytes memory) {\\n return functionCallWithValue(target, data, value, \\\"Address: low-level call with value failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\\n * with `errorMessage` as a fallback revert reason when `target` reverts.\\n *\\n * _Available since v3.1._\\n */\\n function functionCallWithValue(\\n address target,\\n bytes memory data,\\n uint256 value,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n require(address(this).balance >= value, \\\"Address: insufficient balance for call\\\");\\n require(isContract(target), \\\"Address: call to non-contract\\\");\\n\\n (bool success, bytes memory returndata) = target.call{value: value}(data);\\n return verifyCallResult(success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but performing a static call.\\n *\\n * _Available since v3.3._\\n */\\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\\n return functionStaticCall(target, data, \\\"Address: low-level static call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\\n * but performing a static call.\\n *\\n * _Available since v3.3._\\n */\\n function functionStaticCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal view returns (bytes memory) {\\n require(isContract(target), \\\"Address: static call to non-contract\\\");\\n\\n (bool success, bytes memory returndata) = target.staticcall(data);\\n return verifyCallResult(success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the\\n * revert reason using the provided one.\\n *\\n * _Available since v4.3._\\n */\\n function verifyCallResult(\\n bool success,\\n bytes memory returndata,\\n string memory errorMessage\\n ) internal pure returns (bytes memory) {\\n if (success) {\\n return returndata;\\n } else {\\n // Look for revert reason and bubble it up if present\\n if (returndata.length > 0) {\\n // The easiest way to bubble the revert reason is using memory via assembly\\n /// @solidity memory-safe-assembly\\n assembly {\\n let returndata_size := mload(returndata)\\n revert(add(32, returndata), returndata_size)\\n }\\n } else {\\n revert(errorMessage);\\n }\\n }\\n }\\n}\\n\",\"keccak256\":\"0x611aa3f23e59cfdd1863c536776407b3e33d695152a266fa7cfb34440a29a8a3\",\"license\":\"MIT\"},\"@openzeppelin/contracts-upgradeable/utils/ContextUpgradeable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)\\n\\npragma solidity ^0.8.0;\\nimport \\\"../proxy/utils/Initializable.sol\\\";\\n\\n/**\\n * @dev Provides information about the current execution context, including the\\n * sender of the transaction and its data. While these are generally available\\n * via msg.sender and msg.data, they should not be accessed in such a direct\\n * manner, since when dealing with meta-transactions the account sending and\\n * paying for execution may not be the actual sender (as far as an application\\n * is concerned).\\n *\\n * This contract is only required for intermediate, library-like contracts.\\n */\\nabstract contract ContextUpgradeable is Initializable {\\n function __Context_init() internal onlyInitializing {\\n }\\n\\n function __Context_init_unchained() internal onlyInitializing {\\n }\\n function _msgSender() internal view virtual returns (address) {\\n return msg.sender;\\n }\\n\\n function _msgData() internal view virtual returns (bytes calldata) {\\n return msg.data;\\n }\\n\\n /**\\n * @dev This empty reserved space is put in place to allow future versions to add new\\n * variables without shifting down storage in the inheritance chain.\\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\\n */\\n uint256[50] private __gap;\\n}\\n\",\"keccak256\":\"0x963ea7f0b48b032eef72fe3a7582edf78408d6f834115b9feadd673a4d5bd149\",\"license\":\"MIT\"},\"@openzeppelin/contracts-upgradeable/utils/CountersUpgradeable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (utils/Counters.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @title Counters\\n * @author Matt Condon (@shrugs)\\n * @dev Provides counters that can only be incremented, decremented or reset. This can be used e.g. to track the number\\n * of elements in a mapping, issuing ERC721 ids, or counting request ids.\\n *\\n * Include with `using Counters for Counters.Counter;`\\n */\\nlibrary CountersUpgradeable {\\n struct Counter {\\n // This variable should never be directly accessed by users of the library: interactions must be restricted to\\n // the library's function. As of Solidity v0.5.2, this cannot be enforced, though there is a proposal to add\\n // this feature: see https://github.com/ethereum/solidity/issues/4637\\n uint256 _value; // default: 0\\n }\\n\\n function current(Counter storage counter) internal view returns (uint256) {\\n return counter._value;\\n }\\n\\n function increment(Counter storage counter) internal {\\n unchecked {\\n counter._value += 1;\\n }\\n }\\n\\n function decrement(Counter storage counter) internal {\\n uint256 value = counter._value;\\n require(value > 0, \\\"Counter: decrement overflow\\\");\\n unchecked {\\n counter._value = value - 1;\\n }\\n }\\n\\n function reset(Counter storage counter) internal {\\n counter._value = 0;\\n }\\n}\\n\",\"keccak256\":\"0x798741e231b22b81e2dd2eddaaf8832dee4baf5cd8e2dbaa5c1dd12a1c053c4d\",\"license\":\"MIT\"},\"@openzeppelin/contracts-upgradeable/utils/StringsUpgradeable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.7.0) (utils/Strings.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev String operations.\\n */\\nlibrary StringsUpgradeable {\\n bytes16 private constant _HEX_SYMBOLS = \\\"0123456789abcdef\\\";\\n uint8 private constant _ADDRESS_LENGTH = 20;\\n\\n /**\\n * @dev Converts a `uint256` to its ASCII `string` decimal representation.\\n */\\n function toString(uint256 value) internal pure returns (string memory) {\\n // Inspired by OraclizeAPI's implementation - MIT licence\\n // https://github.com/oraclize/ethereum-api/blob/b42146b063c7d6ee1358846c198246239e9360e8/oraclizeAPI_0.4.25.sol\\n\\n if (value == 0) {\\n return \\\"0\\\";\\n }\\n uint256 temp = value;\\n uint256 digits;\\n while (temp != 0) {\\n digits++;\\n temp /= 10;\\n }\\n bytes memory buffer = new bytes(digits);\\n while (value != 0) {\\n digits -= 1;\\n buffer[digits] = bytes1(uint8(48 + uint256(value % 10)));\\n value /= 10;\\n }\\n return string(buffer);\\n }\\n\\n /**\\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation.\\n */\\n function toHexString(uint256 value) internal pure returns (string memory) {\\n if (value == 0) {\\n return \\\"0x00\\\";\\n }\\n uint256 temp = value;\\n uint256 length = 0;\\n while (temp != 0) {\\n length++;\\n temp >>= 8;\\n }\\n return toHexString(value, length);\\n }\\n\\n /**\\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length.\\n */\\n function toHexString(uint256 value, uint256 length) internal pure returns (string memory) {\\n bytes memory buffer = new bytes(2 * length + 2);\\n buffer[0] = \\\"0\\\";\\n buffer[1] = \\\"x\\\";\\n for (uint256 i = 2 * length + 1; i > 1; --i) {\\n buffer[i] = _HEX_SYMBOLS[value & 0xf];\\n value >>= 4;\\n }\\n require(value == 0, \\\"Strings: hex length insufficient\\\");\\n return string(buffer);\\n }\\n\\n /**\\n * @dev Converts an `address` with fixed length of 20 bytes to its not checksummed ASCII `string` hexadecimal representation.\\n */\\n function toHexString(address addr) internal pure returns (string memory) {\\n return toHexString(uint256(uint160(addr)), _ADDRESS_LENGTH);\\n }\\n}\\n\",\"keccak256\":\"0xea5339a7fff0ed42b45be56a88efdd0b2ddde9fa480dc99fef9a6a4c5b776863\",\"license\":\"MIT\"},\"@openzeppelin/contracts-upgradeable/utils/cryptography/ECDSAUpgradeable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.7.0) (utils/cryptography/ECDSA.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../StringsUpgradeable.sol\\\";\\n\\n/**\\n * @dev Elliptic Curve Digital Signature Algorithm (ECDSA) operations.\\n *\\n * These functions can be used to verify that a message was signed by the holder\\n * of the private keys of a given address.\\n */\\nlibrary ECDSAUpgradeable {\\n enum RecoverError {\\n NoError,\\n InvalidSignature,\\n InvalidSignatureLength,\\n InvalidSignatureS,\\n InvalidSignatureV\\n }\\n\\n function _throwError(RecoverError error) private pure {\\n if (error == RecoverError.NoError) {\\n return; // no error: do nothing\\n } else if (error == RecoverError.InvalidSignature) {\\n revert(\\\"ECDSA: invalid signature\\\");\\n } else if (error == RecoverError.InvalidSignatureLength) {\\n revert(\\\"ECDSA: invalid signature length\\\");\\n } else if (error == RecoverError.InvalidSignatureS) {\\n revert(\\\"ECDSA: invalid signature 's' value\\\");\\n } else if (error == RecoverError.InvalidSignatureV) {\\n revert(\\\"ECDSA: invalid signature 'v' value\\\");\\n }\\n }\\n\\n /**\\n * @dev Returns the address that signed a hashed message (`hash`) with\\n * `signature` or error string. This address can then be used for verification purposes.\\n *\\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\\n * this function rejects them by requiring the `s` value to be in the lower\\n * half order, and the `v` value to be either 27 or 28.\\n *\\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\\n * verification to be secure: it is possible to craft signatures that\\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\\n * this is by receiving a hash of the original message (which may otherwise\\n * be too long), and then calling {toEthSignedMessageHash} on it.\\n *\\n * Documentation for signature generation:\\n * - with https://web3js.readthedocs.io/en/v1.3.4/web3-eth-accounts.html#sign[Web3.js]\\n * - with https://docs.ethers.io/v5/api/signer/#Signer-signMessage[ethers]\\n *\\n * _Available since v4.3._\\n */\\n function tryRecover(bytes32 hash, bytes memory signature) internal pure returns (address, RecoverError) {\\n // Check the signature length\\n // - case 65: r,s,v signature (standard)\\n // - case 64: r,vs signature (cf https://eips.ethereum.org/EIPS/eip-2098) _Available since v4.1._\\n if (signature.length == 65) {\\n bytes32 r;\\n bytes32 s;\\n uint8 v;\\n // ecrecover takes the signature parameters, and the only way to get them\\n // currently is to use assembly.\\n /// @solidity memory-safe-assembly\\n assembly {\\n r := mload(add(signature, 0x20))\\n s := mload(add(signature, 0x40))\\n v := byte(0, mload(add(signature, 0x60)))\\n }\\n return tryRecover(hash, v, r, s);\\n } else if (signature.length == 64) {\\n bytes32 r;\\n bytes32 vs;\\n // ecrecover takes the signature parameters, and the only way to get them\\n // currently is to use assembly.\\n /// @solidity memory-safe-assembly\\n assembly {\\n r := mload(add(signature, 0x20))\\n vs := mload(add(signature, 0x40))\\n }\\n return tryRecover(hash, r, vs);\\n } else {\\n return (address(0), RecoverError.InvalidSignatureLength);\\n }\\n }\\n\\n /**\\n * @dev Returns the address that signed a hashed message (`hash`) with\\n * `signature`. This address can then be used for verification purposes.\\n *\\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\\n * this function rejects them by requiring the `s` value to be in the lower\\n * half order, and the `v` value to be either 27 or 28.\\n *\\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\\n * verification to be secure: it is possible to craft signatures that\\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\\n * this is by receiving a hash of the original message (which may otherwise\\n * be too long), and then calling {toEthSignedMessageHash} on it.\\n */\\n function recover(bytes32 hash, bytes memory signature) internal pure returns (address) {\\n (address recovered, RecoverError error) = tryRecover(hash, signature);\\n _throwError(error);\\n return recovered;\\n }\\n\\n /**\\n * @dev Overload of {ECDSA-tryRecover} that receives the `r` and `vs` short-signature fields separately.\\n *\\n * See https://eips.ethereum.org/EIPS/eip-2098[EIP-2098 short signatures]\\n *\\n * _Available since v4.3._\\n */\\n function tryRecover(\\n bytes32 hash,\\n bytes32 r,\\n bytes32 vs\\n ) internal pure returns (address, RecoverError) {\\n bytes32 s = vs & bytes32(0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff);\\n uint8 v = uint8((uint256(vs) >> 255) + 27);\\n return tryRecover(hash, v, r, s);\\n }\\n\\n /**\\n * @dev Overload of {ECDSA-recover} that receives the `r and `vs` short-signature fields separately.\\n *\\n * _Available since v4.2._\\n */\\n function recover(\\n bytes32 hash,\\n bytes32 r,\\n bytes32 vs\\n ) internal pure returns (address) {\\n (address recovered, RecoverError error) = tryRecover(hash, r, vs);\\n _throwError(error);\\n return recovered;\\n }\\n\\n /**\\n * @dev Overload of {ECDSA-tryRecover} that receives the `v`,\\n * `r` and `s` signature fields separately.\\n *\\n * _Available since v4.3._\\n */\\n function tryRecover(\\n bytes32 hash,\\n uint8 v,\\n bytes32 r,\\n bytes32 s\\n ) internal pure returns (address, RecoverError) {\\n // EIP-2 still allows signature malleability for ecrecover(). Remove this possibility and make the signature\\n // unique. Appendix F in the Ethereum Yellow paper (https://ethereum.github.io/yellowpaper/paper.pdf), defines\\n // the valid range for s in (301): 0 < s < secp256k1n \\u00f7 2 + 1, and for v in (302): v \\u2208 {27, 28}. Most\\n // signatures from current libraries generate a unique signature with an s-value in the lower half order.\\n //\\n // If your library generates malleable signatures, such as s-values in the upper range, calculate a new s-value\\n // with 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141 - s1 and flip v from 27 to 28 or\\n // vice versa. If your library also generates signatures with 0/1 for v instead 27/28, add 27 to v to accept\\n // these malleable signatures as well.\\n if (uint256(s) > 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D576E7357A4501DDFE92F46681B20A0) {\\n return (address(0), RecoverError.InvalidSignatureS);\\n }\\n if (v != 27 && v != 28) {\\n return (address(0), RecoverError.InvalidSignatureV);\\n }\\n\\n // If the signature is valid (and not malleable), return the signer address\\n address signer = ecrecover(hash, v, r, s);\\n if (signer == address(0)) {\\n return (address(0), RecoverError.InvalidSignature);\\n }\\n\\n return (signer, RecoverError.NoError);\\n }\\n\\n /**\\n * @dev Overload of {ECDSA-recover} that receives the `v`,\\n * `r` and `s` signature fields separately.\\n */\\n function recover(\\n bytes32 hash,\\n uint8 v,\\n bytes32 r,\\n bytes32 s\\n ) internal pure returns (address) {\\n (address recovered, RecoverError error) = tryRecover(hash, v, r, s);\\n _throwError(error);\\n return recovered;\\n }\\n\\n /**\\n * @dev Returns an Ethereum Signed Message, created from a `hash`. This\\n * produces hash corresponding to the one signed with the\\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\\n * JSON-RPC method as part of EIP-191.\\n *\\n * See {recover}.\\n */\\n function toEthSignedMessageHash(bytes32 hash) internal pure returns (bytes32) {\\n // 32 is the length in bytes of hash,\\n // enforced by the type signature above\\n return keccak256(abi.encodePacked(\\\"\\\\x19Ethereum Signed Message:\\\\n32\\\", hash));\\n }\\n\\n /**\\n * @dev Returns an Ethereum Signed Message, created from `s`. This\\n * produces hash corresponding to the one signed with the\\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\\n * JSON-RPC method as part of EIP-191.\\n *\\n * See {recover}.\\n */\\n function toEthSignedMessageHash(bytes memory s) internal pure returns (bytes32) {\\n return keccak256(abi.encodePacked(\\\"\\\\x19Ethereum Signed Message:\\\\n\\\", StringsUpgradeable.toString(s.length), s));\\n }\\n\\n /**\\n * @dev Returns an Ethereum Signed Typed Data, created from a\\n * `domainSeparator` and a `structHash`. This produces hash corresponding\\n * to the one signed with the\\n * https://eips.ethereum.org/EIPS/eip-712[`eth_signTypedData`]\\n * JSON-RPC method as part of EIP-712.\\n *\\n * See {recover}.\\n */\\n function toTypedDataHash(bytes32 domainSeparator, bytes32 structHash) internal pure returns (bytes32) {\\n return keccak256(abi.encodePacked(\\\"\\\\x19\\\\x01\\\", domainSeparator, structHash));\\n }\\n}\\n\",\"keccak256\":\"0xe8c62ca00ed2d0a4d9b7e3c4bf7d62c821618b2cdb3c844da91a1193986851bf\",\"license\":\"MIT\"},\"@openzeppelin/contracts-upgradeable/utils/cryptography/draft-EIP712Upgradeable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (utils/cryptography/draft-EIP712.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"./ECDSAUpgradeable.sol\\\";\\nimport \\\"../../proxy/utils/Initializable.sol\\\";\\n\\n/**\\n * @dev https://eips.ethereum.org/EIPS/eip-712[EIP 712] is a standard for hashing and signing of typed structured data.\\n *\\n * The encoding specified in the EIP is very generic, and such a generic implementation in Solidity is not feasible,\\n * thus this contract does not implement the encoding itself. Protocols need to implement the type-specific encoding\\n * they need in their contracts using a combination of `abi.encode` and `keccak256`.\\n *\\n * This contract implements the EIP 712 domain separator ({_domainSeparatorV4}) that is used as part of the encoding\\n * scheme, and the final step of the encoding to obtain the message digest that is then signed via ECDSA\\n * ({_hashTypedDataV4}).\\n *\\n * The implementation of the domain separator was designed to be as efficient as possible while still properly updating\\n * the chain id to protect against replay attacks on an eventual fork of the chain.\\n *\\n * NOTE: This contract implements the version of the encoding known as \\\"v4\\\", as implemented by the JSON RPC method\\n * https://docs.metamask.io/guide/signing-data.html[`eth_signTypedDataV4` in MetaMask].\\n *\\n * _Available since v3.4._\\n *\\n * @custom:storage-size 52\\n */\\nabstract contract EIP712Upgradeable is Initializable {\\n /* solhint-disable var-name-mixedcase */\\n bytes32 private _HASHED_NAME;\\n bytes32 private _HASHED_VERSION;\\n bytes32 private constant _TYPE_HASH = keccak256(\\\"EIP712Domain(string name,string version,uint256 chainId,address verifyingContract)\\\");\\n\\n /* solhint-enable var-name-mixedcase */\\n\\n /**\\n * @dev Initializes the domain separator and parameter caches.\\n *\\n * The meaning of `name` and `version` is specified in\\n * https://eips.ethereum.org/EIPS/eip-712#definition-of-domainseparator[EIP 712]:\\n *\\n * - `name`: the user readable name of the signing domain, i.e. the name of the DApp or the protocol.\\n * - `version`: the current major version of the signing domain.\\n *\\n * NOTE: These parameters cannot be changed except through a xref:learn::upgrading-smart-contracts.adoc[smart\\n * contract upgrade].\\n */\\n function __EIP712_init(string memory name, string memory version) internal onlyInitializing {\\n __EIP712_init_unchained(name, version);\\n }\\n\\n function __EIP712_init_unchained(string memory name, string memory version) internal onlyInitializing {\\n bytes32 hashedName = keccak256(bytes(name));\\n bytes32 hashedVersion = keccak256(bytes(version));\\n _HASHED_NAME = hashedName;\\n _HASHED_VERSION = hashedVersion;\\n }\\n\\n /**\\n * @dev Returns the domain separator for the current chain.\\n */\\n function _domainSeparatorV4() internal view returns (bytes32) {\\n return _buildDomainSeparator(_TYPE_HASH, _EIP712NameHash(), _EIP712VersionHash());\\n }\\n\\n function _buildDomainSeparator(\\n bytes32 typeHash,\\n bytes32 nameHash,\\n bytes32 versionHash\\n ) private view returns (bytes32) {\\n return keccak256(abi.encode(typeHash, nameHash, versionHash, block.chainid, address(this)));\\n }\\n\\n /**\\n * @dev Given an already https://eips.ethereum.org/EIPS/eip-712#definition-of-hashstruct[hashed struct], this\\n * function returns the hash of the fully encoded EIP712 message for this domain.\\n *\\n * This hash can be used together with {ECDSA-recover} to obtain the signer of a message. For example:\\n *\\n * ```solidity\\n * bytes32 digest = _hashTypedDataV4(keccak256(abi.encode(\\n * keccak256(\\\"Mail(address to,string contents)\\\"),\\n * mailTo,\\n * keccak256(bytes(mailContents))\\n * )));\\n * address signer = ECDSA.recover(digest, signature);\\n * ```\\n */\\n function _hashTypedDataV4(bytes32 structHash) internal view virtual returns (bytes32) {\\n return ECDSAUpgradeable.toTypedDataHash(_domainSeparatorV4(), structHash);\\n }\\n\\n /**\\n * @dev The hash of the name parameter for the EIP712 domain.\\n *\\n * NOTE: This function reads from storage by default, but can be redefined to return a constant value if gas costs\\n * are a concern.\\n */\\n function _EIP712NameHash() internal virtual view returns (bytes32) {\\n return _HASHED_NAME;\\n }\\n\\n /**\\n * @dev The hash of the version parameter for the EIP712 domain.\\n *\\n * NOTE: This function reads from storage by default, but can be redefined to return a constant value if gas costs\\n * are a concern.\\n */\\n function _EIP712VersionHash() internal virtual view returns (bytes32) {\\n return _HASHED_VERSION;\\n }\\n\\n /**\\n * @dev This empty reserved space is put in place to allow future versions to add new\\n * variables without shifting down storage in the inheritance chain.\\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\\n */\\n uint256[50] private __gap;\\n}\\n\",\"keccak256\":\"0xaf5a96100f421d61693605349511e43221d3c2e47d4b3efa87af2b936e2567fc\",\"license\":\"MIT\"},\"@openzeppelin/contracts/token/ERC20/IERC20.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.6.0) (token/ERC20/IERC20.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Interface of the ERC20 standard as defined in the EIP.\\n */\\ninterface IERC20 {\\n /**\\n * @dev Emitted when `value` tokens are moved from one account (`from`) to\\n * another (`to`).\\n *\\n * Note that `value` may be zero.\\n */\\n event Transfer(address indexed from, address indexed to, uint256 value);\\n\\n /**\\n * @dev Emitted when the allowance of a `spender` for an `owner` is set by\\n * a call to {approve}. `value` is the new allowance.\\n */\\n event Approval(address indexed owner, address indexed spender, uint256 value);\\n\\n /**\\n * @dev Returns the amount of tokens in existence.\\n */\\n function totalSupply() external view returns (uint256);\\n\\n /**\\n * @dev Returns the amount of tokens owned by `account`.\\n */\\n function balanceOf(address account) external view returns (uint256);\\n\\n /**\\n * @dev Moves `amount` tokens from the caller's account to `to`.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * Emits a {Transfer} event.\\n */\\n function transfer(address to, uint256 amount) external returns (bool);\\n\\n /**\\n * @dev Returns the remaining number of tokens that `spender` will be\\n * allowed to spend on behalf of `owner` through {transferFrom}. This is\\n * zero by default.\\n *\\n * This value changes when {approve} or {transferFrom} are called.\\n */\\n function allowance(address owner, address spender) external view returns (uint256);\\n\\n /**\\n * @dev Sets `amount` as the allowance of `spender` over the caller's tokens.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * IMPORTANT: Beware that changing an allowance with this method brings the risk\\n * that someone may use both the old and the new allowance by unfortunate\\n * transaction ordering. One possible solution to mitigate this race\\n * condition is to first reduce the spender's allowance to 0 and set the\\n * desired value afterwards:\\n * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729\\n *\\n * Emits an {Approval} event.\\n */\\n function approve(address spender, uint256 amount) external returns (bool);\\n\\n /**\\n * @dev Moves `amount` tokens from `from` to `to` using the\\n * allowance mechanism. `amount` is then deducted from the caller's\\n * allowance.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * Emits a {Transfer} event.\\n */\\n function transferFrom(\\n address from,\\n address to,\\n uint256 amount\\n ) external returns (bool);\\n}\\n\",\"keccak256\":\"0x9750c6b834f7b43000631af5cc30001c5f547b3ceb3635488f140f60e897ea6b\",\"license\":\"MIT\"},\"@openzeppelin/contracts/token/ERC20/extensions/draft-IERC20Permit.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (token/ERC20/extensions/draft-IERC20Permit.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Interface of the ERC20 Permit extension allowing approvals to be made via signatures, as defined in\\n * https://eips.ethereum.org/EIPS/eip-2612[EIP-2612].\\n *\\n * Adds the {permit} method, which can be used to change an account's ERC20 allowance (see {IERC20-allowance}) by\\n * presenting a message signed by the account. By not relying on {IERC20-approve}, the token holder account doesn't\\n * need to send a transaction, and thus is not required to hold Ether at all.\\n */\\ninterface IERC20Permit {\\n /**\\n * @dev Sets `value` as the allowance of `spender` over ``owner``'s tokens,\\n * given ``owner``'s signed approval.\\n *\\n * IMPORTANT: The same issues {IERC20-approve} has related to transaction\\n * ordering also apply here.\\n *\\n * Emits an {Approval} event.\\n *\\n * Requirements:\\n *\\n * - `spender` cannot be the zero address.\\n * - `deadline` must be a timestamp in the future.\\n * - `v`, `r` and `s` must be a valid `secp256k1` signature from `owner`\\n * over the EIP712-formatted function arguments.\\n * - the signature must use ``owner``'s current nonce (see {nonces}).\\n *\\n * For more information on the signature format, see the\\n * https://eips.ethereum.org/EIPS/eip-2612#specification[relevant EIP\\n * section].\\n */\\n function permit(\\n address owner,\\n address spender,\\n uint256 value,\\n uint256 deadline,\\n uint8 v,\\n bytes32 r,\\n bytes32 s\\n ) external;\\n\\n /**\\n * @dev Returns the current nonce for `owner`. This value must be\\n * included whenever a signature is generated for {permit}.\\n *\\n * Every successful call to {permit} increases ``owner``'s nonce by one. This\\n * prevents a signature from being used multiple times.\\n */\\n function nonces(address owner) external view returns (uint256);\\n\\n /**\\n * @dev Returns the domain separator used in the encoding of the signature for {permit}, as defined by {EIP712}.\\n */\\n // solhint-disable-next-line func-name-mixedcase\\n function DOMAIN_SEPARATOR() external view returns (bytes32);\\n}\\n\",\"keccak256\":\"0xf41ca991f30855bf80ffd11e9347856a517b977f0a6c2d52e6421a99b7840329\",\"license\":\"MIT\"},\"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.7.0) (token/ERC20/utils/SafeERC20.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../IERC20.sol\\\";\\nimport \\\"../extensions/draft-IERC20Permit.sol\\\";\\nimport \\\"../../../utils/Address.sol\\\";\\n\\n/**\\n * @title SafeERC20\\n * @dev Wrappers around ERC20 operations that throw on failure (when the token\\n * contract returns false). Tokens that return no value (and instead revert or\\n * throw on failure) are also supported, non-reverting calls are assumed to be\\n * successful.\\n * To use this library you can add a `using SafeERC20 for IERC20;` statement to your contract,\\n * which allows you to call the safe operations as `token.safeTransfer(...)`, etc.\\n */\\nlibrary SafeERC20 {\\n using Address for address;\\n\\n function safeTransfer(\\n IERC20 token,\\n address to,\\n uint256 value\\n ) internal {\\n _callOptionalReturn(token, abi.encodeWithSelector(token.transfer.selector, to, value));\\n }\\n\\n function safeTransferFrom(\\n IERC20 token,\\n address from,\\n address to,\\n uint256 value\\n ) internal {\\n _callOptionalReturn(token, abi.encodeWithSelector(token.transferFrom.selector, from, to, value));\\n }\\n\\n /**\\n * @dev Deprecated. This function has issues similar to the ones found in\\n * {IERC20-approve}, and its usage is discouraged.\\n *\\n * Whenever possible, use {safeIncreaseAllowance} and\\n * {safeDecreaseAllowance} instead.\\n */\\n function safeApprove(\\n IERC20 token,\\n address spender,\\n uint256 value\\n ) internal {\\n // safeApprove should only be called when setting an initial allowance,\\n // or when resetting it to zero. To increase and decrease it, use\\n // 'safeIncreaseAllowance' and 'safeDecreaseAllowance'\\n require(\\n (value == 0) || (token.allowance(address(this), spender) == 0),\\n \\\"SafeERC20: approve from non-zero to non-zero allowance\\\"\\n );\\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, value));\\n }\\n\\n function safeIncreaseAllowance(\\n IERC20 token,\\n address spender,\\n uint256 value\\n ) internal {\\n uint256 newAllowance = token.allowance(address(this), spender) + value;\\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));\\n }\\n\\n function safeDecreaseAllowance(\\n IERC20 token,\\n address spender,\\n uint256 value\\n ) internal {\\n unchecked {\\n uint256 oldAllowance = token.allowance(address(this), spender);\\n require(oldAllowance >= value, \\\"SafeERC20: decreased allowance below zero\\\");\\n uint256 newAllowance = oldAllowance - value;\\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));\\n }\\n }\\n\\n function safePermit(\\n IERC20Permit token,\\n address owner,\\n address spender,\\n uint256 value,\\n uint256 deadline,\\n uint8 v,\\n bytes32 r,\\n bytes32 s\\n ) internal {\\n uint256 nonceBefore = token.nonces(owner);\\n token.permit(owner, spender, value, deadline, v, r, s);\\n uint256 nonceAfter = token.nonces(owner);\\n require(nonceAfter == nonceBefore + 1, \\\"SafeERC20: permit did not succeed\\\");\\n }\\n\\n /**\\n * @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement\\n * on the return value: the return value is optional (but if data is returned, it must not be false).\\n * @param token The token targeted by the call.\\n * @param data The call data (encoded using abi.encode or one of its variants).\\n */\\n function _callOptionalReturn(IERC20 token, bytes memory data) private {\\n // We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since\\n // we're implementing it ourselves. We use {Address.functionCall} to perform this call, which verifies that\\n // the target address contains contract code and also asserts for success in the low-level call.\\n\\n bytes memory returndata = address(token).functionCall(data, \\\"SafeERC20: low-level call failed\\\");\\n if (returndata.length > 0) {\\n // Return data is optional\\n require(abi.decode(returndata, (bool)), \\\"SafeERC20: ERC20 operation did not succeed\\\");\\n }\\n }\\n}\\n\",\"keccak256\":\"0x032807210d1d7d218963d7355d62e021a84bf1b3339f4f50be2f63b53cccaf29\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/Address.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.7.0) (utils/Address.sol)\\n\\npragma solidity ^0.8.1;\\n\\n/**\\n * @dev Collection of functions related to the address type\\n */\\nlibrary Address {\\n /**\\n * @dev Returns true if `account` is a contract.\\n *\\n * [IMPORTANT]\\n * ====\\n * It is unsafe to assume that an address for which this function returns\\n * false is an externally-owned account (EOA) and not a contract.\\n *\\n * Among others, `isContract` will return false for the following\\n * types of addresses:\\n *\\n * - an externally-owned account\\n * - a contract in construction\\n * - an address where a contract will be created\\n * - an address where a contract lived, but was destroyed\\n * ====\\n *\\n * [IMPORTANT]\\n * ====\\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\\n *\\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\\n * constructor.\\n * ====\\n */\\n function isContract(address account) internal view returns (bool) {\\n // This method relies on extcodesize/address.code.length, which returns 0\\n // for contracts in construction, since the code is only stored at the end\\n // of the constructor execution.\\n\\n return account.code.length > 0;\\n }\\n\\n /**\\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\\n * `recipient`, forwarding all available gas and reverting on errors.\\n *\\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\\n * imposed by `transfer`, making them unable to receive funds via\\n * `transfer`. {sendValue} removes this limitation.\\n *\\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\\n *\\n * IMPORTANT: because control is transferred to `recipient`, care must be\\n * taken to not create reentrancy vulnerabilities. Consider using\\n * {ReentrancyGuard} or the\\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\\n */\\n function sendValue(address payable recipient, uint256 amount) internal {\\n require(address(this).balance >= amount, \\\"Address: insufficient balance\\\");\\n\\n (bool success, ) = recipient.call{value: amount}(\\\"\\\");\\n require(success, \\\"Address: unable to send value, recipient may have reverted\\\");\\n }\\n\\n /**\\n * @dev Performs a Solidity function call using a low level `call`. A\\n * plain `call` is an unsafe replacement for a function call: use this\\n * function instead.\\n *\\n * If `target` reverts with a revert reason, it is bubbled up by this\\n * function (like regular Solidity function calls).\\n *\\n * Returns the raw returned data. To convert to the expected return value,\\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\\n *\\n * Requirements:\\n *\\n * - `target` must be a contract.\\n * - calling `target` with `data` must not revert.\\n *\\n * _Available since v3.1._\\n */\\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\\n return functionCall(target, data, \\\"Address: low-level call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\\n * `errorMessage` as a fallback revert reason when `target` reverts.\\n *\\n * _Available since v3.1._\\n */\\n function functionCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n return functionCallWithValue(target, data, 0, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but also transferring `value` wei to `target`.\\n *\\n * Requirements:\\n *\\n * - the calling contract must have an ETH balance of at least `value`.\\n * - the called Solidity function must be `payable`.\\n *\\n * _Available since v3.1._\\n */\\n function functionCallWithValue(\\n address target,\\n bytes memory data,\\n uint256 value\\n ) internal returns (bytes memory) {\\n return functionCallWithValue(target, data, value, \\\"Address: low-level call with value failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\\n * with `errorMessage` as a fallback revert reason when `target` reverts.\\n *\\n * _Available since v3.1._\\n */\\n function functionCallWithValue(\\n address target,\\n bytes memory data,\\n uint256 value,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n require(address(this).balance >= value, \\\"Address: insufficient balance for call\\\");\\n require(isContract(target), \\\"Address: call to non-contract\\\");\\n\\n (bool success, bytes memory returndata) = target.call{value: value}(data);\\n return verifyCallResult(success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but performing a static call.\\n *\\n * _Available since v3.3._\\n */\\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\\n return functionStaticCall(target, data, \\\"Address: low-level static call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\\n * but performing a static call.\\n *\\n * _Available since v3.3._\\n */\\n function functionStaticCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal view returns (bytes memory) {\\n require(isContract(target), \\\"Address: static call to non-contract\\\");\\n\\n (bool success, bytes memory returndata) = target.staticcall(data);\\n return verifyCallResult(success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but performing a delegate call.\\n *\\n * _Available since v3.4._\\n */\\n function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {\\n return functionDelegateCall(target, data, \\\"Address: low-level delegate call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\\n * but performing a delegate call.\\n *\\n * _Available since v3.4._\\n */\\n function functionDelegateCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n require(isContract(target), \\\"Address: delegate call to non-contract\\\");\\n\\n (bool success, bytes memory returndata) = target.delegatecall(data);\\n return verifyCallResult(success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the\\n * revert reason using the provided one.\\n *\\n * _Available since v4.3._\\n */\\n function verifyCallResult(\\n bool success,\\n bytes memory returndata,\\n string memory errorMessage\\n ) internal pure returns (bytes memory) {\\n if (success) {\\n return returndata;\\n } else {\\n // Look for revert reason and bubble it up if present\\n if (returndata.length > 0) {\\n // The easiest way to bubble the revert reason is using memory via assembly\\n /// @solidity memory-safe-assembly\\n assembly {\\n let returndata_size := mload(returndata)\\n revert(add(32, returndata), returndata_size)\\n }\\n } else {\\n revert(errorMessage);\\n }\\n }\\n }\\n}\\n\",\"keccak256\":\"0xd6153ce99bcdcce22b124f755e72553295be6abcd63804cfdffceb188b8bef10\",\"license\":\"MIT\"},\"contracts/agToken/AgToken.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-3.0\\n\\npragma solidity ^0.8.12;\\n\\n/*\\n * \\u2588 \\n ***** \\u2593\\u2593\\u2593 \\n * \\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593 \\n * ///. \\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593 \\n ***** //////// \\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593 \\n * ///////////// \\u2593\\u2593\\u2593 \\n \\u2593\\u2593 ////////////////// \\u2588 \\u2593\\u2593 \\n \\u2593\\u2593 \\u2593\\u2593 /////////////////////// \\u2593\\u2593 \\u2593\\u2593 \\n \\u2593\\u2593 \\u2593\\u2593 //////////////////////////// \\u2593\\u2593 \\u2593\\u2593 \\n \\u2593\\u2593 \\u2593\\u2593 /////////\\u2593\\u2593\\u2593///////\\u2593\\u2593\\u2593///////// \\u2593\\u2593 \\u2593\\u2593 \\n \\u2593\\u2593 ,////////////////////////////////////// \\u2593\\u2593 \\u2593\\u2593 \\n \\u2593\\u2593 ////////////////////////////////////////// \\u2593\\u2593 \\n \\u2593\\u2593 //////////////////////\\u2593\\u2593\\u2593\\u2593///////////////////// \\n ,//////////////////////////////////////////////////// \\n .////////////////////////////////////////////////////////// \\n .//////////////////////////\\u2588\\u2588.,//////////////////////////\\u2588 \\n .//////////////////////\\u2588\\u2588\\u2588\\u2588..,./////////////////////\\u2588\\u2588 \\n ...////////////////\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588.....,.////////////////\\u2588\\u2588\\u2588 \\n ,.,////////////\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588 ........,///////////\\u2588\\u2588\\u2588\\u2588 \\n .,.,//////\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588 ,.......///////\\u2588\\u2588\\u2588\\u2588 \\n ,..//\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588 ........./\\u2588\\u2588\\u2588\\u2588 \\n ..,\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588 .....,\\u2588\\u2588\\u2588 \\n .\\u2588\\u2588 ,.,\\u2588 \\n \\n \\n \\n \\u2593\\u2593 \\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593 \\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593 \\u2593\\u2593 \\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593 \\n \\u2593\\u2593\\u2593\\u2593\\u2593\\u2593 \\u2593\\u2593\\u2593 \\u2593\\u2593\\u2593 \\u2593\\u2593\\u2593 \\u2593\\u2593 \\u2593\\u2593 \\u2593\\u2593\\u2593\\u2593 \\n \\u2593\\u2593\\u2593 \\u2593\\u2593\\u2593 \\u2593\\u2593\\u2593 \\u2593\\u2593\\u2593 \\u2593\\u2593\\u2593 \\u2593\\u2593\\u2593 \\u2593\\u2593 \\u2593\\u2593\\u2593\\u2593\\u2593 \\n \\u2593\\u2593\\u2593 \\u2593\\u2593 \\u2593\\u2593\\u2593 \\u2593\\u2593\\u2593 \\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593 \\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593 \\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593 \\n*/\\n\\nimport \\\"../interfaces/IAgToken.sol\\\";\\nimport \\\"../interfaces/ITreasury.sol\\\";\\nimport \\\"@openzeppelin/contracts-upgradeable/token/ERC20/extensions/draft-ERC20PermitUpgradeable.sol\\\";\\n\\n/// @title AgToken\\n/// @author Angle Labs, Inc.\\n/// @notice Base contract for Angle agTokens on Ethereum and on other chains\\n/// @dev By default, agTokens are ERC-20 tokens with 18 decimals\\ncontract AgToken is IAgToken, ERC20PermitUpgradeable {\\n // =========================== PARAMETERS / VARIABLES ==========================\\n\\n /// @inheritdoc IAgToken\\n mapping(address => bool) public isMinter;\\n /// @notice Reference to the treasury contract which can grant minting rights\\n address public treasury;\\n\\n // =================================== EVENTS ==================================\\n\\n event TreasuryUpdated(address indexed _treasury);\\n event MinterToggled(address indexed minter);\\n\\n // =================================== ERRORS ==================================\\n\\n error BurnAmountExceedsAllowance();\\n error InvalidSender();\\n error InvalidTreasury();\\n error NotMinter();\\n error NotTreasury();\\n\\n // ================================ CONSTRUCTOR ================================\\n\\n /// @custom:oz-upgrades-unsafe-allow constructor\\n constructor() initializer {}\\n\\n /// @notice Initializes the `AgToken` contract\\n function initialize(string memory name_, string memory symbol_, address _treasury) external {\\n _initialize(name_, symbol_, _treasury);\\n }\\n\\n /// @notice Initializes the contract\\n function _initialize(string memory name_, string memory symbol_, address _treasury) internal virtual initializer {\\n if (address(ITreasury(_treasury).stablecoin()) != address(this)) revert InvalidTreasury();\\n __ERC20Permit_init(name_);\\n __ERC20_init(name_, symbol_);\\n treasury = _treasury;\\n emit TreasuryUpdated(_treasury);\\n }\\n\\n // ================================= MODIFIERS =================================\\n\\n /// @notice Checks to see if it is the `Treasury` calling this contract\\n modifier onlyTreasury() {\\n if (msg.sender != treasury) revert NotTreasury();\\n _;\\n }\\n\\n /// @notice Checks whether the sender has the minting right\\n modifier onlyMinter() {\\n if (!isMinter[msg.sender]) revert NotMinter();\\n _;\\n }\\n\\n // ============================= EXTERNAL FUNCTION =============================\\n\\n /// @notice Allows anyone to burn stablecoins\\n /// @param amount Amount of stablecoins to burn\\n /// @dev This function can typically be called if there is a settlement mechanism to burn stablecoins\\n function burnStablecoin(uint256 amount) external {\\n _burn(msg.sender, amount);\\n }\\n\\n // ========================= MINTER ROLE ONLY FUNCTIONS ========================\\n\\n /// @inheritdoc IAgToken\\n function burnSelf(uint256 amount, address burner) external onlyMinter {\\n _burn(burner, amount);\\n }\\n\\n /// @inheritdoc IAgToken\\n function burnFrom(uint256 amount, address burner, address sender) external onlyMinter {\\n if (burner != sender) {\\n uint256 currentAllowance = allowance(burner, sender);\\n if (currentAllowance < amount) revert BurnAmountExceedsAllowance();\\n _approve(burner, sender, currentAllowance - amount);\\n }\\n _burn(burner, amount);\\n }\\n\\n /// @inheritdoc IAgToken\\n function mint(address account, uint256 amount) external onlyMinter {\\n _mint(account, amount);\\n }\\n\\n // ========================== GOVERNANCE ONLY FUNCTIONS ==========================\\n\\n /// @inheritdoc IAgToken\\n function addMinter(address minter) external onlyTreasury {\\n isMinter[minter] = true;\\n emit MinterToggled(minter);\\n }\\n\\n /// @inheritdoc IAgToken\\n function removeMinter(address minter) external {\\n if (msg.sender != address(treasury) && msg.sender != minter) revert InvalidSender();\\n isMinter[minter] = false;\\n emit MinterToggled(minter);\\n }\\n\\n /// @inheritdoc IAgToken\\n function setTreasury(address _treasury) external virtual onlyTreasury {\\n treasury = _treasury;\\n emit TreasuryUpdated(_treasury);\\n }\\n}\\n\",\"keccak256\":\"0x671d54d7840179050e859cf09662fe0e2c34cfaf5ec3782148d6c29e77c54d17\",\"license\":\"GPL-3.0\"},\"contracts/agToken/AgTokenSideChainMultiBridge.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-3.0\\n\\npragma solidity ^0.8.12;\\n\\nimport \\\"./AgToken.sol\\\";\\nimport \\\"@openzeppelin/contracts/token/ERC20/IERC20.sol\\\";\\nimport \\\"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\\\";\\n\\n/// @title AgTokenSideChainMultiBridge\\n/// @author Angle Labs, Inc.\\n/// @notice Contract for Angle agTokens on other chains than Ethereum mainnet\\n/// @dev This contract supports bridge tokens having a minting right on the stablecoin (also referred to as the canonical\\n/// or the native token)\\ncontract AgTokenSideChainMultiBridge is AgToken {\\n using SafeERC20 for IERC20;\\n\\n /// @notice Base used for fee computation\\n uint256 public constant BASE_PARAMS = 1e9;\\n\\n // =============================== BRIDGING DATA ===============================\\n\\n /// @notice Struct with some data about a specific bridge token\\n struct BridgeDetails {\\n // Limit on the balance of bridge token held by the contract: it is designed\\n // to reduce the exposure of the system to hacks\\n uint256 limit;\\n // Limit on the hourly volume of token minted through this bridge\\n // Technically the limit over a rolling hour is hourlyLimit x2 as hourly limit\\n // is enforced only between x:00 and x+1:00\\n uint256 hourlyLimit;\\n // Fee taken for swapping in and out the token\\n uint64 fee;\\n // Whether the associated token is allowed or not\\n bool allowed;\\n // Whether swapping in and out from the associated token is paused or not\\n bool paused;\\n }\\n\\n /// @notice Maps a bridge token to data\\n mapping(address => BridgeDetails) public bridges;\\n /// @notice List of all bridge tokens\\n address[] public bridgeTokensList;\\n /// @notice Maps a bridge token to the associated hourly volume\\n mapping(address => mapping(uint256 => uint256)) public usage;\\n /// @notice Maps an address to whether it is exempt of fees for when it comes to swapping in and out\\n mapping(address => uint256) public isFeeExempt;\\n /// @notice Limit to the amount of tokens that can be sent from that chain to another chain\\n uint256 public chainTotalHourlyLimit;\\n /// @notice Usage per hour on that chain. Maps an hourly timestamp to the total volume swapped out on the chain\\n mapping(uint256 => uint256) public chainTotalUsage;\\n\\n // =================================== EVENTS ==================================\\n\\n event BridgeTokenAdded(address indexed bridgeToken, uint256 limit, uint256 hourlyLimit, uint64 fee, bool paused);\\n event BridgeTokenToggled(address indexed bridgeToken, bool toggleStatus);\\n event BridgeTokenRemoved(address indexed bridgeToken);\\n event BridgeTokenFeeUpdated(address indexed bridgeToken, uint64 fee);\\n event BridgeTokenLimitUpdated(address indexed bridgeToken, uint256 limit);\\n event BridgeTokenHourlyLimitUpdated(address indexed bridgeToken, uint256 hourlyLimit);\\n event HourlyLimitUpdated(uint256 hourlyLimit);\\n event Recovered(address indexed token, address indexed to, uint256 amount);\\n event FeeToggled(address indexed theAddress, uint256 toggleStatus);\\n\\n // =================================== ERRORS ==================================\\n\\n error AssetStillControlledInReserves();\\n error HourlyLimitExceeded();\\n error InvalidToken();\\n error NotGovernor();\\n error NotGovernorOrGuardian();\\n error TooBigAmount();\\n error TooHighParameterValue();\\n error ZeroAddress();\\n\\n // ================================= MODIFIERS =================================\\n\\n /// @notice Checks whether the `msg.sender` has the governor role or not\\n modifier onlyGovernor() {\\n if (!ITreasury(treasury).isGovernor(msg.sender)) revert NotGovernor();\\n _;\\n }\\n\\n /// @notice Checks whether the `msg.sender` has the governor role or the guardian role\\n modifier onlyGovernorOrGuardian() {\\n if (!ITreasury(treasury).isGovernorOrGuardian(msg.sender)) revert NotGovernorOrGuardian();\\n _;\\n }\\n\\n // ===================== EXTERNAL PERMISSIONLESS FUNCTIONS =====================\\n\\n /// @notice Returns the list of all supported bridge tokens\\n /// @dev Helpful for UIs\\n function allBridgeTokens() external view returns (address[] memory) {\\n return bridgeTokensList;\\n }\\n\\n /// @notice Returns the current volume for a bridge, for the current hour\\n /// @param bridgeToken Bridge used to mint\\n /// @dev Helpful for UIs\\n function currentUsage(address bridgeToken) external view returns (uint256) {\\n return usage[bridgeToken][block.timestamp / 3600];\\n }\\n\\n /// @notice Returns the current total volume on the chain for the current hour\\n /// @dev Helpful for UIs\\n function currentTotalUsage() external view returns (uint256) {\\n return chainTotalUsage[block.timestamp / 3600];\\n }\\n\\n /// @notice Mints the canonical token from a supported bridge token\\n /// @param bridgeToken Bridge token to use to mint\\n /// @param amount Amount of bridge tokens to send\\n /// @param to Address to which the stablecoin should be sent\\n /// @return Amount of the canonical stablecoin actually minted\\n /// @dev Some fees may be taken by the protocol depending on the token used and on the address calling\\n function swapIn(address bridgeToken, uint256 amount, address to) external returns (uint256) {\\n BridgeDetails memory bridgeDetails = bridges[bridgeToken];\\n if (!bridgeDetails.allowed || bridgeDetails.paused) revert InvalidToken();\\n uint256 balance = IERC20(bridgeToken).balanceOf(address(this));\\n if (balance + amount > bridgeDetails.limit) {\\n // In case someone maliciously sends tokens to this contract\\n // Or the limit changes\\n if (bridgeDetails.limit > balance) amount = bridgeDetails.limit - balance;\\n else {\\n amount = 0;\\n }\\n }\\n\\n // Checking requirement on the hourly volume\\n uint256 hour = block.timestamp / 3600;\\n uint256 hourlyUsage = usage[bridgeToken][hour];\\n if (hourlyUsage + amount > bridgeDetails.hourlyLimit) {\\n // Edge case when the hourly limit changes\\n amount = bridgeDetails.hourlyLimit > hourlyUsage ? bridgeDetails.hourlyLimit - hourlyUsage : 0;\\n }\\n usage[bridgeToken][hour] = hourlyUsage + amount;\\n\\n IERC20(bridgeToken).safeTransferFrom(msg.sender, address(this), amount);\\n uint256 canonicalOut = amount;\\n // Computing fees\\n if (isFeeExempt[msg.sender] == 0) {\\n canonicalOut -= (canonicalOut * bridgeDetails.fee) / BASE_PARAMS;\\n }\\n _mint(to, canonicalOut);\\n return canonicalOut;\\n }\\n\\n /// @notice Burns the canonical token in exchange for a bridge token\\n /// @param bridgeToken Bridge token required\\n /// @param amount Amount of canonical tokens to burn\\n /// @param to Address to which the bridge token should be sent\\n /// @return Amount of bridge tokens actually sent back\\n /// @dev Some fees may be taken by the protocol depending on the token used and on the address calling\\n function swapOut(address bridgeToken, uint256 amount, address to) external returns (uint256) {\\n BridgeDetails memory bridgeDetails = bridges[bridgeToken];\\n if (!bridgeDetails.allowed || bridgeDetails.paused) revert InvalidToken();\\n\\n uint256 hour = block.timestamp / 3600;\\n uint256 hourlyUsage = chainTotalUsage[hour] + amount;\\n // If the amount being swapped out exceeds the limit, we revert\\n // We don't want to change the amount being swapped out.\\n // The user can decide to send another tx with the correct amount to reach the limit\\n if (hourlyUsage > chainTotalHourlyLimit) revert HourlyLimitExceeded();\\n chainTotalUsage[hour] = hourlyUsage;\\n\\n _burn(msg.sender, amount);\\n uint256 bridgeOut = amount;\\n if (isFeeExempt[msg.sender] == 0) {\\n bridgeOut -= (bridgeOut * bridgeDetails.fee) / BASE_PARAMS;\\n }\\n IERC20(bridgeToken).safeTransfer(to, bridgeOut);\\n return bridgeOut;\\n }\\n\\n // ============================ GOVERNANCE FUNCTIONS ===========================\\n\\n /// @notice Adds support for a bridge token\\n /// @param bridgeToken Bridge token to add: it should be a version of the stablecoin from another bridge\\n /// @param limit Limit on the balance of bridge token this contract could hold\\n /// @param hourlyLimit Limit on the hourly volume for this bridge\\n /// @param paused Whether swapping for this token should be paused or not\\n /// @param fee Fee taken upon swapping for or against this token\\n function addBridgeToken(\\n address bridgeToken,\\n uint256 limit,\\n uint256 hourlyLimit,\\n uint64 fee,\\n bool paused\\n ) external onlyGovernor {\\n if (bridges[bridgeToken].allowed || bridgeToken == address(0)) revert InvalidToken();\\n if (fee > BASE_PARAMS) revert TooHighParameterValue();\\n BridgeDetails memory _bridge;\\n _bridge.limit = limit;\\n _bridge.hourlyLimit = hourlyLimit;\\n _bridge.paused = paused;\\n _bridge.fee = fee;\\n _bridge.allowed = true;\\n bridges[bridgeToken] = _bridge;\\n bridgeTokensList.push(bridgeToken);\\n emit BridgeTokenAdded(bridgeToken, limit, hourlyLimit, fee, paused);\\n }\\n\\n /// @notice Removes support for a token\\n /// @param bridgeToken Address of the bridge token to remove support for\\n function removeBridgeToken(address bridgeToken) external onlyGovernor {\\n if (IERC20(bridgeToken).balanceOf(address(this)) != 0) revert AssetStillControlledInReserves();\\n delete bridges[bridgeToken];\\n // Deletion from `bridgeTokensList` loop\\n uint256 bridgeTokensListLength = bridgeTokensList.length;\\n for (uint256 i; i < bridgeTokensListLength - 1; ++i) {\\n if (bridgeTokensList[i] == bridgeToken) {\\n // Replace the `bridgeToken` to remove with the last of the list\\n bridgeTokensList[i] = bridgeTokensList[bridgeTokensListLength - 1];\\n break;\\n }\\n }\\n // Remove last element in array\\n bridgeTokensList.pop();\\n emit BridgeTokenRemoved(bridgeToken);\\n }\\n\\n /// @notice Recovers any ERC20 token\\n /// @dev Can be used to withdraw bridge tokens for them to be de-bridged on mainnet\\n function recoverERC20(address tokenAddress, address to, uint256 amountToRecover) external onlyGovernor {\\n IERC20(tokenAddress).safeTransfer(to, amountToRecover);\\n emit Recovered(tokenAddress, to, amountToRecover);\\n }\\n\\n /// @notice Updates the `limit` amount for `bridgeToken`\\n function setLimit(address bridgeToken, uint256 limit) external onlyGovernorOrGuardian {\\n if (!bridges[bridgeToken].allowed) revert InvalidToken();\\n bridges[bridgeToken].limit = limit;\\n emit BridgeTokenLimitUpdated(bridgeToken, limit);\\n }\\n\\n /// @notice Updates the `hourlyLimit` amount for `bridgeToken`\\n function setHourlyLimit(address bridgeToken, uint256 hourlyLimit) external onlyGovernorOrGuardian {\\n if (!bridges[bridgeToken].allowed) revert InvalidToken();\\n bridges[bridgeToken].hourlyLimit = hourlyLimit;\\n emit BridgeTokenHourlyLimitUpdated(bridgeToken, hourlyLimit);\\n }\\n\\n /// @notice Updates the `chainTotalHourlyLimit` amount\\n function setChainTotalHourlyLimit(uint256 hourlyLimit) external onlyGovernorOrGuardian {\\n chainTotalHourlyLimit = hourlyLimit;\\n emit HourlyLimitUpdated(hourlyLimit);\\n }\\n\\n /// @notice Updates the `fee` value for `bridgeToken`\\n function setSwapFee(address bridgeToken, uint64 fee) external onlyGovernorOrGuardian {\\n if (!bridges[bridgeToken].allowed) revert InvalidToken();\\n if (fee > BASE_PARAMS) revert TooHighParameterValue();\\n bridges[bridgeToken].fee = fee;\\n emit BridgeTokenFeeUpdated(bridgeToken, fee);\\n }\\n\\n /// @notice Pauses or unpauses swapping in and out for a token\\n function toggleBridge(address bridgeToken) external onlyGovernorOrGuardian {\\n if (!bridges[bridgeToken].allowed) revert InvalidToken();\\n bool pausedStatus = bridges[bridgeToken].paused;\\n bridges[bridgeToken].paused = !pausedStatus;\\n emit BridgeTokenToggled(bridgeToken, !pausedStatus);\\n }\\n\\n /// @notice Toggles fees for the address `theAddress`\\n function toggleFeesForAddress(address theAddress) external onlyGovernorOrGuardian {\\n uint256 feeExemptStatus = 1 - isFeeExempt[theAddress];\\n isFeeExempt[theAddress] = feeExemptStatus;\\n emit FeeToggled(theAddress, feeExemptStatus);\\n }\\n}\\n\",\"keccak256\":\"0x9782497e84a1dc4bc468778ede4aceb35cebf74e4159e2af8f469f49312c3841\",\"license\":\"GPL-3.0\"},\"contracts/interfaces/IAgToken.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-3.0\\n\\npragma solidity ^0.8.12;\\n\\nimport \\\"@openzeppelin/contracts-upgradeable/token/ERC20/IERC20Upgradeable.sol\\\";\\n\\n/// @title IAgToken\\n/// @author Angle Labs, Inc.\\n/// @notice Interface for the stablecoins `AgToken` contracts\\n/// @dev This interface only contains functions of the `AgToken` contract which are called by other contracts\\n/// of this module or of the first module of the Angle Protocol\\ninterface IAgToken is IERC20Upgradeable {\\n // ======================= Minter Role Only Functions ===========================\\n\\n /// @notice Lets the `StableMaster` contract or another whitelisted contract mint agTokens\\n /// @param account Address to mint to\\n /// @param amount Amount to mint\\n /// @dev The contracts allowed to issue agTokens are the `StableMaster` contract, `VaultManager` contracts\\n /// associated to this stablecoin as well as the flash loan module (if activated) and potentially contracts\\n /// whitelisted by governance\\n function mint(address account, uint256 amount) external;\\n\\n /// @notice Burns `amount` tokens from a `burner` address after being asked to by `sender`\\n /// @param amount Amount of tokens to burn\\n /// @param burner Address to burn from\\n /// @param sender Address which requested the burn from `burner`\\n /// @dev This method is to be called by a contract with the minter right after being requested\\n /// to do so by a `sender` address willing to burn tokens from another `burner` address\\n /// @dev The method checks the allowance between the `sender` and the `burner`\\n function burnFrom(uint256 amount, address burner, address sender) external;\\n\\n /// @notice Burns `amount` tokens from a `burner` address\\n /// @param amount Amount of tokens to burn\\n /// @param burner Address to burn from\\n /// @dev This method is to be called by a contract with a minter right on the AgToken after being\\n /// requested to do so by an address willing to burn tokens from its address\\n function burnSelf(uint256 amount, address burner) external;\\n\\n // ========================= Treasury Only Functions ===========================\\n\\n /// @notice Adds a minter in the contract\\n /// @param minter Minter address to add\\n /// @dev Zero address checks are performed directly in the `Treasury` contract\\n function addMinter(address minter) external;\\n\\n /// @notice Removes a minter from the contract\\n /// @param minter Minter address to remove\\n /// @dev This function can also be called by a minter wishing to revoke itself\\n function removeMinter(address minter) external;\\n\\n /// @notice Sets a new treasury contract\\n /// @param _treasury New treasury address\\n function setTreasury(address _treasury) external;\\n\\n // ========================= External functions ================================\\n\\n /// @notice Checks whether an address has the right to mint agTokens\\n /// @param minter Address for which the minting right should be checked\\n /// @return Whether the address has the right to mint agTokens or not\\n function isMinter(address minter) external view returns (bool);\\n\\n /// @notice Get the associated treasury\\n function treasury() external view returns (address);\\n}\\n\",\"keccak256\":\"0x0c83efcfc1fb9ae9ba830f7b89e3dab9abf6ad7a6205a31aa35fbccaa837dcdc\",\"license\":\"GPL-3.0\"},\"contracts/interfaces/ICoreBorrow.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-3.0\\n\\npragma solidity ^0.8.12;\\n\\n/// @title ICoreBorrow\\n/// @author Angle Labs, Inc.\\n/// @notice Interface for the `CoreBorrow` contract\\n/// @dev This interface only contains functions of the `CoreBorrow` contract which are called by other contracts\\n/// of this module\\ninterface ICoreBorrow {\\n /// @notice Checks if an address corresponds to a treasury of a stablecoin with a flash loan\\n /// module initialized on it\\n /// @param treasury Address to check\\n /// @return Whether the address has the `FLASHLOANER_TREASURY_ROLE` or not\\n function isFlashLoanerTreasury(address treasury) external view returns (bool);\\n\\n /// @notice Checks whether an address is governor of the Angle Protocol or not\\n /// @param admin Address to check\\n /// @return Whether the address has the `GOVERNOR_ROLE` or not\\n function isGovernor(address admin) external view returns (bool);\\n\\n /// @notice Checks whether an address is governor or a guardian of the Angle Protocol or not\\n /// @param admin Address to check\\n /// @return Whether the address has the `GUARDIAN_ROLE` or not\\n /// @dev Governance should make sure when adding a governor to also give this governor the guardian\\n /// role by calling the `addGovernor` function\\n function isGovernorOrGuardian(address admin) external view returns (bool);\\n}\\n\",\"keccak256\":\"0x10249210cbf522775f040baf981d7d037472168ce2746d87473ac7c29a34e62e\",\"license\":\"GPL-3.0\"},\"contracts/interfaces/IFlashAngle.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-3.0\\n\\npragma solidity ^0.8.12;\\n\\nimport \\\"./IAgToken.sol\\\";\\nimport \\\"./ICoreBorrow.sol\\\";\\n\\n/// @title IFlashAngle\\n/// @author Angle Labs, Inc.\\n/// @notice Interface for the `FlashAngle` contract\\n/// @dev This interface only contains functions of the contract which are called by other contracts\\n/// of this module\\ninterface IFlashAngle {\\n /// @notice Reference to the `CoreBorrow` contract managing the FlashLoan module\\n function core() external view returns (ICoreBorrow);\\n\\n /// @notice Sends the fees taken from flash loans to the treasury contract associated to the stablecoin\\n /// @param stablecoin Stablecoin from which profits should be sent\\n /// @return balance Amount of profits sent\\n /// @dev This function can only be called by the treasury contract\\n function accrueInterestToTreasury(IAgToken stablecoin) external returns (uint256 balance);\\n\\n /// @notice Adds support for a stablecoin\\n /// @param _treasury Treasury associated to the stablecoin to add support for\\n /// @dev This function can only be called by the `CoreBorrow` contract\\n function addStablecoinSupport(address _treasury) external;\\n\\n /// @notice Removes support for a stablecoin\\n /// @param _treasury Treasury associated to the stablecoin to remove support for\\n /// @dev This function can only be called by the `CoreBorrow` contract\\n function removeStablecoinSupport(address _treasury) external;\\n\\n /// @notice Sets a new core contract\\n /// @param _core Core contract address to set\\n /// @dev This function can only be called by the `CoreBorrow` contract\\n function setCore(address _core) external;\\n}\\n\",\"keccak256\":\"0x39b0097f695b9e934bccdc72676c91513f1077cc5d0fd151908fd25a7c5cfbe4\",\"license\":\"GPL-3.0\"},\"contracts/interfaces/ITreasury.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-3.0\\n\\npragma solidity ^0.8.12;\\n\\nimport \\\"./IAgToken.sol\\\";\\nimport \\\"./ICoreBorrow.sol\\\";\\nimport \\\"./IFlashAngle.sol\\\";\\n\\n/// @title ITreasury\\n/// @author Angle Labs, Inc.\\n/// @notice Interface for the `Treasury` contract\\n/// @dev This interface only contains functions of the `Treasury` which are called by other contracts\\n/// of this module\\ninterface ITreasury {\\n /// @notice Stablecoin handled by this `treasury` contract\\n function stablecoin() external view returns (IAgToken);\\n\\n /// @notice Checks whether a given address has the governor role\\n /// @param admin Address to check\\n /// @return Whether the address has the governor role\\n /// @dev Access control is only kept in the `CoreBorrow` contract\\n function isGovernor(address admin) external view returns (bool);\\n\\n /// @notice Checks whether a given address has the guardian or the governor role\\n /// @param admin Address to check\\n /// @return Whether the address has the guardian or the governor role\\n /// @dev Access control is only kept in the `CoreBorrow` contract which means that this function\\n /// queries the `CoreBorrow` contract\\n function isGovernorOrGuardian(address admin) external view returns (bool);\\n\\n /// @notice Checks whether a given address has well been initialized in this contract\\n /// as a `VaultManager`\\n /// @param _vaultManager Address to check\\n /// @return Whether the address has been initialized or not\\n function isVaultManager(address _vaultManager) external view returns (bool);\\n\\n /// @notice Sets a new flash loan module for this stablecoin\\n /// @param _flashLoanModule Reference to the new flash loan module\\n /// @dev This function removes the minting right to the old flash loan module and grants\\n /// it to the new module\\n function setFlashLoanModule(address _flashLoanModule) external;\\n\\n /// @notice Gets the vault manager list\\n function vaultManagerList(uint256 i) external returns (address);\\n}\\n\",\"keccak256\":\"0x06c2f781c08732ce1b5845c083af5742716245baa6c519bd737f32b230a884c1\",\"license\":\"GPL-3.0\"}},\"version\":1}", + "bytecode": "0x60806040523480156200001157600080fd5b50600054610100900460ff1615808015620000335750600054600160ff909116105b8062000063575062000050306200013d60201b6200273a1760201c565b15801562000063575060005460ff166001145b620000cb5760405162461bcd60e51b815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201526d191e481a5b9a5d1a585b1a5e995960921b606482015260840160405180910390fd5b6000805460ff191660011790558015620000ef576000805461ff0019166101001790555b801562000136576000805461ff0019169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15b506200014c565b6001600160a01b03163b151590565b6146d0806200015c6000396000f3fe608060405234801561001057600080fd5b50600436106102ff5760003560e01c806361d027b31161019c5780639f48118f116100ee578063ced67f0c11610097578063dd62ed3e11610071578063dd62ed3e14610724578063e3e286551461076a578063f0f442601461077d57600080fd5b8063ced67f0c1461066b578063d44ad63f146106fe578063d505accf1461071157600080fd5b8063aa271e1a116100c8578063aa271e1a14610620578063ba330bd714610643578063cd4839ca1461065657600080fd5b80639f48118f146105ef578063a457c2d7146105fa578063a9059cbb1461060d57600080fd5b80637ecebe001161015057806395d89b411161012a57806395d89b41146105c1578063983b2d56146105c95780639e4e0dae146105dc57600080fd5b80637ecebe00146105705780638933fb791461058357806390218cff146105ae57600080fd5b80637334d020116101815780637334d020146105425780637d4c9c2d146105555780637d74e25f1461056857600080fd5b806361d027b3146104c757806370a082311461050c57600080fd5b80633092afd511610255578063395093511161020957806340c10f19116101e357806340c10f19146104815780634dc32fcc146104945780635bfbec96146104a757600080fd5b8063395093511461043b5780633a55f89d1461044e5780633f4218e01461046157600080fd5b8063350ebe041161023a578063350ebe041461040d5780633644e5151461042057806336db43b51461042857600080fd5b80633092afd5146103eb578063313ce567146103fe57600080fd5b8063151dd755116102b757806323b872dd1161029157806323b872dd146103b25780632b471d8e146103c55780632e403e14146103d857600080fd5b8063151dd7551461038057806318160ddd146103a15780632342fb0e146103a957600080fd5b80630919a951116102e85780630919a95114610337578063095ea7b31461034a5780631171bda91461036d57600080fd5b806306fdde0314610304578063077f224a14610322575b600080fd5b61030c610790565b6040516103199190613e48565b60405180910390f35b610335610330366004613f95565b610822565b005b61033561034536600461400d565b610832565b61035d61035836600461402a565b610995565b6040519015158152602001610319565b61033561037b366004614056565b6109af565b61039361038e366004614097565b610b04565b604051908152602001610319565b603554610393565b61039360d25481565b61035d6103c0366004614056565b610dbe565b6103356103d33660046140ce565b610de2565b6103356103e636600461400d565b610e39565b6103356103f936600461400d565b6111e8565b60405160128152602001610319565b61033561041b3660046140fe565b6112d1565b6103936113da565b61033561043636600461402a565b6113e9565b61035d61044936600461402a565b611579565b61033561045c366004614135565b6115c0565b61039361046f36600461400d565b60d16020526000908152604090205481565b61033561048f36600461402a565b6116c3565b6103936104a236600461400d565b611716565b6103936104b5366004614135565b60d36020526000908152604090205481565b60cd546104e79073ffffffffffffffffffffffffffffffffffffffff1681565b60405173ffffffffffffffffffffffffffffffffffffffff9091168152602001610319565b61039361051a36600461400d565b73ffffffffffffffffffffffffffffffffffffffff1660009081526033602052604090205490565b61033561055036600461402a565b61175e565b610335610563366004614179565b6118f1565b610393611c59565b61039361057e36600461400d565b611c7e565b61039361059136600461402a565b60d060209081526000928352604080842090915290825290205481565b6103356105bc366004614135565b611ca9565b61030c611cb6565b6103356105d736600461400d565b611cc5565b6103356105ea3660046141d6565b611d8d565b610393633b9aca0081565b61035d61060836600461402a565b611f99565b61035d61061b36600461402a565b61206f565b61035d61062e36600461400d565b60cc6020526000908152604090205460ff1681565b6104e7610651366004614135565b61207d565b61065e6120b4565b604051610319919061420b565b6106c561067936600461400d565b60ce6020526000908152604090208054600182015460029092015490919067ffffffffffffffff81169060ff680100000000000000008204811691690100000000000000000090041685565b60408051958652602086019490945267ffffffffffffffff9092169284019290925290151560608301521515608082015260a001610319565b61039361070c366004614097565b612122565b61033561071f366004614265565b6122e7565b6103936107323660046142dc565b73ffffffffffffffffffffffffffffffffffffffff918216600090815260346020908152604080832093909416825291909152205490565b61033561077836600461400d565b6124a6565b61033561078b36600461400d565b61267a565b60606036805461079f9061430a565b80601f01602080910402602001604051908101604052809291908181526020018280546107cb9061430a565b80156108185780601f106107ed57610100808354040283529160200191610818565b820191906000526020600020905b8154815290600101906020018083116107fb57829003601f168201915b5050505050905090565b61082d838383612756565b505050565b60cd546040517f521d4de900000000000000000000000000000000000000000000000000000000815233600482015273ffffffffffffffffffffffffffffffffffffffff9091169063521d4de990602401602060405180830381865afa1580156108a0573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906108c49190614357565b6108fa576040517f99e120bc00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff8116600090815260d1602052604081205461092b9060016143a3565b73ffffffffffffffffffffffffffffffffffffffff8316600081815260d160205260409081902083905551919250907f979ef83e7e7a87cb48064e296dd7e997870d50f43acf8d7ad221313526c8ca0f906109899084815260200190565b60405180910390a25050565b6000336109a3818585612a35565b60019150505b92915050565b60cd546040517fe43581b800000000000000000000000000000000000000000000000000000000815233600482015273ffffffffffffffffffffffffffffffffffffffff9091169063e43581b890602401602060405180830381865afa158015610a1d573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610a419190614357565b610a77576040517fee3675d400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b610a9873ffffffffffffffffffffffffffffffffffffffff84168383612be0565b8173ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff167ffff3b3844276f57024e0b42afec1a37f75db36511e43819a4f2a63ab7862b64883604051610af791815260200190565b60405180910390a3505050565b73ffffffffffffffffffffffffffffffffffffffff8316600090815260ce60209081526040808320815160a081018352815481526001820154938101939093526002015467ffffffffffffffff81169183019190915260ff680100000000000000008204811615801560608501526901000000000000000000909204161515608083015280610b94575080608001515b15610bcb576040517fc1ab6dc100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015260009073ffffffffffffffffffffffffffffffffffffffff8716906370a0823190602401602060405180830381865afa158015610c38573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610c5c91906143b6565b8251909150610c6b86836143cf565b1115610c93578151811015610c8e578151610c879082906143a3565b9450610c93565b600094505b6000610ca1610e10426143e2565b73ffffffffffffffffffffffffffffffffffffffff8816600090815260d0602090815260408083208484528252909120549085015191925090610ce488836143cf565b1115610d0f5780846020015111610cfc576000610d0c565b808460200151610d0c91906143a3565b96505b610d1987826143cf565b73ffffffffffffffffffffffffffffffffffffffff8916600081815260d060209081526040808320878452909152902091909155610d599033308a612cb4565b33600090815260d16020526040812054889103610da657633b9aca00856040015167ffffffffffffffff1682610d8f919061441d565b610d9991906143e2565b610da390826143a3565b90505b610db08782612d12565b9450505050505b9392505050565b600033610dcc858285612e32565b610dd7858585612f03565b506001949350505050565b33600090815260cc602052604090205460ff16610e2b576040517ff8d2906c00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b610e3581836131b6565b5050565b60cd546040517fe43581b800000000000000000000000000000000000000000000000000000000815233600482015273ffffffffffffffffffffffffffffffffffffffff9091169063e43581b890602401602060405180830381865afa158015610ea7573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610ecb9190614357565b610f01576040517fee3675d400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015273ffffffffffffffffffffffffffffffffffffffff8216906370a0823190602401602060405180830381865afa158015610f6b573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610f8f91906143b6565b15610fc6576040517f2ef630ec00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff8116600090815260ce602052604081208181556001810182905560020180547fffffffffffffffffffffffffffffffffffffffffffff0000000000000000000016905560cf54905b61102e6001836143a3565b811015611139578273ffffffffffffffffffffffffffffffffffffffff1660cf828154811061105f5761105f614434565b60009182526020909120015473ffffffffffffffffffffffffffffffffffffffff16036111295760cf6110936001846143a3565b815481106110a3576110a3614434565b60009182526020909120015460cf805473ffffffffffffffffffffffffffffffffffffffff90921691839081106110dc576110dc614434565b9060005260206000200160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550611139565b61113281614463565b9050611023565b5060cf80548061114b5761114b61449b565b60008281526020812082017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff90810180547fffffffffffffffffffffffff000000000000000000000000000000000000000016905590910190915560405173ffffffffffffffffffffffffffffffffffffffff8416917f5c95b49c4d59d97a2f044167723f29c74b30f99702e3fd406c3830160aa9ccb891a25050565b60cd5473ffffffffffffffffffffffffffffffffffffffff16331480159061122657503373ffffffffffffffffffffffffffffffffffffffff821614155b1561125d576040517fddb5de5e00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff8116600081815260cc602052604080822080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00169055517f98c15241d6c02bc5ee0b780e11b3ea737a2defd9d04877edbe9f9497065bd02f9190a250565b33600090815260cc602052604090205460ff1661131a576040517ff8d2906c00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff16146113d05773ffffffffffffffffffffffffffffffffffffffff828116600090815260346020908152604080832093851683529290522054838110156113ba576040517f715ec26c00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6113ce83836113c987856143a3565b612a35565b505b61082d82846131b6565b60006113e46133a3565b905090565b60cd546040517f521d4de900000000000000000000000000000000000000000000000000000000815233600482015273ffffffffffffffffffffffffffffffffffffffff9091169063521d4de990602401602060405180830381865afa158015611457573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061147b9190614357565b6114b1576040517f99e120bc00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff8216600090815260ce602052604090206002015468010000000000000000900460ff1661151f576040517fc1ab6dc100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff8216600081815260ce602052604090819020839055517fe7b113fba37131b6396680a0c55790a697ec975e198ff8cfd89dac90a6379e61906109899084815260200190565b33600081815260346020908152604080832073ffffffffffffffffffffffffffffffffffffffff871684529091528120549091906109a390829086906113c99087906143cf565b60cd546040517f521d4de900000000000000000000000000000000000000000000000000000000815233600482015273ffffffffffffffffffffffffffffffffffffffff9091169063521d4de990602401602060405180830381865afa15801561162e573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906116529190614357565b611688576040517f99e120bc00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60d28190556040518181527fc3b69829afe2345596a02c8b587d41f796ba0094481d899e1b2e07b7532a1e219060200160405180910390a150565b33600090815260cc602052604090205460ff1661170c576040517ff8d2906c00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b610e358282612d12565b73ffffffffffffffffffffffffffffffffffffffff8116600090815260d06020526040812081611748610e10426143e2565b8152602001908152602001600020549050919050565b60cd546040517f521d4de900000000000000000000000000000000000000000000000000000000815233600482015273ffffffffffffffffffffffffffffffffffffffff9091169063521d4de990602401602060405180830381865afa1580156117cc573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906117f09190614357565b611826576040517f99e120bc00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff8216600090815260ce602052604090206002015468010000000000000000900460ff16611894576040517fc1ab6dc100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff8216600081815260ce602052604090819020600101839055517fe13ac9338b2ee623233f83c1b3ceab16490fa3e3737fac7f0970d0830a9f4871906109899084815260200190565b60cd546040517fe43581b800000000000000000000000000000000000000000000000000000000815233600482015273ffffffffffffffffffffffffffffffffffffffff9091169063e43581b890602401602060405180830381865afa15801561195f573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906119839190614357565b6119b9576040517fee3675d400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff8516600090815260ce602052604090206002015468010000000000000000900460ff1680611a10575073ffffffffffffffffffffffffffffffffffffffff8516155b15611a47576040517fc1ab6dc100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b633b9aca008267ffffffffffffffff161115611a8f576040517feca1d2c600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040805160a08101825260008082526020820181905291810182905260608101829052608081019190915284815260208082018581528315156080840190815267ffffffffffffffff808716604080870191825260016060880181815273ffffffffffffffffffffffffffffffffffffffff8e16600081815260ce9099528389208a5181559751888401559351600290970180549151965115156901000000000000000000027fffffffffffffffffffffffffffffffffffffffffffff00ffffffffffffffffff97151568010000000000000000027fffffffffffffffffffffffffffffffffffffffffffffff000000000000000000909316989096169790971717949094169290921790935560cf805492830181559093527facb8d954e2cfef495862221e91bd7523613cf8808827cb33edfe4904cc51bf290180547fffffffffffffffffffffffff0000000000000000000000000000000000000000168217905590517f53087ff85d80a7671594bd2e86b92af22e0b3c2c441c8033bba7399b7b5cbe2390611c49908890889088908890938452602084019290925267ffffffffffffffff1660408301521515606082015260800190565b60405180910390a2505050505050565b600060d381611c6a610e10426143e2565b815260200190815260200160002054905090565b73ffffffffffffffffffffffffffffffffffffffff81166000908152609960205260408120546109a9565b611cb333826131b6565b50565b60606037805461079f9061430a565b60cd5473ffffffffffffffffffffffffffffffffffffffff163314611d16576040517fb90cdbb100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff8116600081815260cc602052604080822080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00166001179055517f98c15241d6c02bc5ee0b780e11b3ea737a2defd9d04877edbe9f9497065bd02f9190a250565b60cd546040517f521d4de900000000000000000000000000000000000000000000000000000000815233600482015273ffffffffffffffffffffffffffffffffffffffff9091169063521d4de990602401602060405180830381865afa158015611dfb573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611e1f9190614357565b611e55576040517f99e120bc00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff8216600090815260ce602052604090206002015468010000000000000000900460ff16611ec3576040517fc1ab6dc100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b633b9aca008167ffffffffffffffff161115611f0b576040517feca1d2c600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff8216600081815260ce602090815260409182902060020180547fffffffffffffffffffffffffffffffffffffffffffffffff00000000000000001667ffffffffffffffff861690811790915591519182527f901f9de19b475adc8da4110434b8df940dce085afd05e2281c86807f3a899d299101610989565b33600081815260346020908152604080832073ffffffffffffffffffffffffffffffffffffffff8716845290915281205490919083811015612062576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602560248201527f45524332303a2064656372656173656420616c6c6f77616e63652062656c6f7760448201527f207a65726f00000000000000000000000000000000000000000000000000000060648201526084015b60405180910390fd5b610dd78286868403612a35565b6000336109a3818585612f03565b60cf818154811061208d57600080fd5b60009182526020909120015473ffffffffffffffffffffffffffffffffffffffff16905081565b606060cf80548060200260200160405190810160405280929190818152602001828054801561081857602002820191906000526020600020905b815473ffffffffffffffffffffffffffffffffffffffff1681526001909101906020018083116120ee575050505050905090565b73ffffffffffffffffffffffffffffffffffffffff8316600090815260ce60209081526040808320815160a081018352815481526001820154938101939093526002015467ffffffffffffffff81169183019190915260ff6801000000000000000082048116158015606085015269010000000000000000009092041615156080830152806121b2575080608001515b156121e9576040517fc1ab6dc100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60006121f7610e10426143e2565b600081815260d36020526040812054919250906122159087906143cf565b905060d254811115612253576040517f6d43d1ac00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600082815260d36020526040902081905561226e33876131b6565b33600090815260d160205260408120548791036122bb57633b9aca00846040015167ffffffffffffffff16826122a4919061441d565b6122ae91906143e2565b6122b890826143a3565b90505b6122dc73ffffffffffffffffffffffffffffffffffffffff89168783612be0565b979650505050505050565b83421115612351576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f45524332305065726d69743a206578706972656420646561646c696e650000006044820152606401612059565b60007f6e71edae12b1b97f4d1f60370fef10105fa2faae0126114a169c64845d6126c98888886123808c61341e565b60408051602081019690965273ffffffffffffffffffffffffffffffffffffffff94851690860152929091166060840152608083015260a082015260c0810186905260e00160405160208183030381529060405280519060200120905060006123e882613453565b905060006123f8828787876134bc565b90508973ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff161461248f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601e60248201527f45524332305065726d69743a20696e76616c6964207369676e617475726500006044820152606401612059565b61249a8a8a8a612a35565b50505050505050505050565b60cd546040517f521d4de900000000000000000000000000000000000000000000000000000000815233600482015273ffffffffffffffffffffffffffffffffffffffff9091169063521d4de990602401602060405180830381865afa158015612514573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906125389190614357565b61256e576040517f99e120bc00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff8116600090815260ce602052604090206002015468010000000000000000900460ff166125dc576040517fc1ab6dc100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff8116600081815260ce602090815260409182902060020180547fffffffffffffffffffffffffffffffffffffffffffff00ffffffffffffffffff811669010000000000000000009182900460ff16801592830291909117909255925192835292917ff7c93079dcbf699749d66345a351afab7d24219bb1d915c9f4fc4cf03f00d3979101610989565b60cd5473ffffffffffffffffffffffffffffffffffffffff1633146126cb576040517fb90cdbb100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60cd80547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83169081179091556040517f7dae230f18360d76a040c81f050aa14eb9d6dc7901b20fc5d855e2a20fe814d190600090a250565b73ffffffffffffffffffffffffffffffffffffffff163b151590565b600054610100900460ff16158080156127765750600054600160ff909116105b806127905750303b158015612790575060005460ff166001145b61281c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201527f647920696e697469616c697a65640000000000000000000000000000000000006064820152608401612059565b600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00166001179055801561287a57600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff166101001790555b3073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1663e9cbd8226040518163ffffffff1660e01b8152600401602060405180830381865afa1580156128dc573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061290091906144ca565b73ffffffffffffffffffffffffffffffffffffffff161461294d576040517f14bcf5c800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b612956846134e4565b61296084846135ba565b60cd80547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff84169081179091556040517f7dae230f18360d76a040c81f050aa14eb9d6dc7901b20fc5d855e2a20fe814d190600090a28015612a2f57600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15b50505050565b73ffffffffffffffffffffffffffffffffffffffff8316612ad7576040517f08c379a0000000000000000000000000000000000000000000000000000000008152602060048201526024808201527f45524332303a20617070726f76652066726f6d20746865207a65726f2061646460448201527f72657373000000000000000000000000000000000000000000000000000000006064820152608401612059565b73ffffffffffffffffffffffffffffffffffffffff8216612b7a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602260248201527f45524332303a20617070726f766520746f20746865207a65726f20616464726560448201527f73730000000000000000000000000000000000000000000000000000000000006064820152608401612059565b73ffffffffffffffffffffffffffffffffffffffff83811660008181526034602090815260408083209487168084529482529182902085905590518481527f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b9259101610af7565b60405173ffffffffffffffffffffffffffffffffffffffff831660248201526044810182905261082d9084907fa9059cbb00000000000000000000000000000000000000000000000000000000906064015b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff000000000000000000000000000000000000000000000000000000009093169290921790915261365b565b60405173ffffffffffffffffffffffffffffffffffffffff80851660248301528316604482015260648101829052612a2f9085907f23b872dd0000000000000000000000000000000000000000000000000000000090608401612c32565b73ffffffffffffffffffffffffffffffffffffffff8216612d8f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601f60248201527f45524332303a206d696e7420746f20746865207a65726f2061646472657373006044820152606401612059565b8060356000828254612da191906143cf565b909155505073ffffffffffffffffffffffffffffffffffffffff821660009081526033602052604081208054839290612ddb9084906143cf565b909155505060405181815273ffffffffffffffffffffffffffffffffffffffff8316906000907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef9060200160405180910390a35050565b73ffffffffffffffffffffffffffffffffffffffff8381166000908152603460209081526040808320938616835292905220547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8114612a2f5781811015612ef6576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f45524332303a20696e73756666696369656e7420616c6c6f77616e63650000006044820152606401612059565b612a2f8484848403612a35565b73ffffffffffffffffffffffffffffffffffffffff8316612fa6576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602560248201527f45524332303a207472616e736665722066726f6d20746865207a65726f20616460448201527f64726573730000000000000000000000000000000000000000000000000000006064820152608401612059565b73ffffffffffffffffffffffffffffffffffffffff8216613049576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602360248201527f45524332303a207472616e7366657220746f20746865207a65726f206164647260448201527f65737300000000000000000000000000000000000000000000000000000000006064820152608401612059565b73ffffffffffffffffffffffffffffffffffffffff8316600090815260336020526040902054818110156130ff576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f45524332303a207472616e7366657220616d6f756e742065786365656473206260448201527f616c616e636500000000000000000000000000000000000000000000000000006064820152608401612059565b73ffffffffffffffffffffffffffffffffffffffff8085166000908152603360205260408082208585039055918516815290812080548492906131439084906143cf565b925050819055508273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef846040516131a991815260200190565b60405180910390a3612a2f565b73ffffffffffffffffffffffffffffffffffffffff8216613259576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602160248201527f45524332303a206275726e2066726f6d20746865207a65726f2061646472657360448201527f73000000000000000000000000000000000000000000000000000000000000006064820152608401612059565b73ffffffffffffffffffffffffffffffffffffffff82166000908152603360205260409020548181101561330f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602260248201527f45524332303a206275726e20616d6f756e7420657863656564732062616c616e60448201527f63650000000000000000000000000000000000000000000000000000000000006064820152608401612059565b73ffffffffffffffffffffffffffffffffffffffff8316600090815260336020526040812083830390556035805484929061334b9084906143a3565b909155505060405182815260009073ffffffffffffffffffffffffffffffffffffffff8516907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef9060200160405180910390a3505050565b60006113e47f8b73c3c69bb8fe3d512ecc4cf759cc79239f7b179b0ffacaa9a75d522b39400f6133d260655490565b6066546040805160208101859052908101839052606081018290524660808201523060a082015260009060c0016040516020818303038152906040528051906020012090509392505050565b73ffffffffffffffffffffffffffffffffffffffff811660009081526099602052604090208054600181018255905b50919050565b60006109a96134606133a3565b836040517f19010000000000000000000000000000000000000000000000000000000000006020820152602281018390526042810182905260009060620160405160208183030381529060405280519060200120905092915050565b60008060006134cd87878787613767565b915091506134da8161387f565b5095945050505050565b600054610100900460ff1661357b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201527f6e697469616c697a696e670000000000000000000000000000000000000000006064820152608401612059565b611cb3816040518060400160405280600181526020017f3100000000000000000000000000000000000000000000000000000000000000815250613ad3565b600054610100900460ff16613651576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201527f6e697469616c697a696e670000000000000000000000000000000000000000006064820152608401612059565b610e358282613b84565b60006136bd826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c65648152508573ffffffffffffffffffffffffffffffffffffffff16613c349092919063ffffffff16565b80519091501561082d57808060200190518101906136db9190614357565b61082d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e60448201527f6f742073756363656564000000000000000000000000000000000000000000006064820152608401612059565b6000807f7fffffffffffffffffffffffffffffff5d576e7357a4501ddfe92f46681b20a083111561379e5750600090506003613876565b8460ff16601b141580156137b657508460ff16601c14155b156137c75750600090506004613876565b6040805160008082526020820180845289905260ff881692820192909252606081018690526080810185905260019060a0016020604051602081039080840390855afa15801561381b573d6000803e3d6000fd5b50506040517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0015191505073ffffffffffffffffffffffffffffffffffffffff811661386f57600060019250925050613876565b9150600090505b94509492505050565b6000816004811115613893576138936144e7565b0361389b5750565b60018160048111156138af576138af6144e7565b03613916576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601860248201527f45434453413a20696e76616c6964207369676e617475726500000000000000006044820152606401612059565b600281600481111561392a5761392a6144e7565b03613991576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601f60248201527f45434453413a20696e76616c6964207369676e6174757265206c656e677468006044820152606401612059565b60038160048111156139a5576139a56144e7565b03613a32576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602260248201527f45434453413a20696e76616c6964207369676e6174757265202773272076616c60448201527f75650000000000000000000000000000000000000000000000000000000000006064820152608401612059565b6004816004811115613a4657613a466144e7565b03611cb3576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602260248201527f45434453413a20696e76616c6964207369676e6174757265202776272076616c60448201527f75650000000000000000000000000000000000000000000000000000000000006064820152608401612059565b600054610100900460ff16613b6a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201527f6e697469616c697a696e670000000000000000000000000000000000000000006064820152608401612059565b815160209283012081519190920120606591909155606655565b600054610100900460ff16613c1b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201527f6e697469616c697a696e670000000000000000000000000000000000000000006064820152608401612059565b6036613c278382614564565b50603761082d8282614564565b6060613c438484600085613c4b565b949350505050565b606082471015613cdd576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f60448201527f722063616c6c00000000000000000000000000000000000000000000000000006064820152608401612059565b73ffffffffffffffffffffffffffffffffffffffff85163b613d5b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006044820152606401612059565b6000808673ffffffffffffffffffffffffffffffffffffffff168587604051613d84919061467e565b60006040518083038185875af1925050503d8060008114613dc1576040519150601f19603f3d011682016040523d82523d6000602084013e613dc6565b606091505b50915091506122dc82828660608315613de0575081610db7565b825115613df05782518084602001fd5b816040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016120599190613e48565b60005b83811015613e3f578181015183820152602001613e27565b50506000910152565b6020815260008251806020840152613e67816040850160208701613e24565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169190910160400192915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b600082601f830112613ed957600080fd5b813567ffffffffffffffff80821115613ef457613ef4613e99565b604051601f83017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0908116603f01168101908282118183101715613f3a57613f3a613e99565b81604052838152866020858801011115613f5357600080fd5b836020870160208301376000602085830101528094505050505092915050565b73ffffffffffffffffffffffffffffffffffffffff81168114611cb357600080fd5b600080600060608486031215613faa57600080fd5b833567ffffffffffffffff80821115613fc257600080fd5b613fce87838801613ec8565b94506020860135915080821115613fe457600080fd5b50613ff186828701613ec8565b925050604084013561400281613f73565b809150509250925092565b60006020828403121561401f57600080fd5b8135610db781613f73565b6000806040838503121561403d57600080fd5b823561404881613f73565b946020939093013593505050565b60008060006060848603121561406b57600080fd5b833561407681613f73565b9250602084013561408681613f73565b929592945050506040919091013590565b6000806000606084860312156140ac57600080fd5b83356140b781613f73565b925060208401359150604084013561400281613f73565b600080604083850312156140e157600080fd5b8235915060208301356140f381613f73565b809150509250929050565b60008060006060848603121561411357600080fd5b83359250602084013561412581613f73565b9150604084013561400281613f73565b60006020828403121561414757600080fd5b5035919050565b803567ffffffffffffffff8116811461416657600080fd5b919050565b8015158114611cb357600080fd5b600080600080600060a0868803121561419157600080fd5b853561419c81613f73565b945060208601359350604086013592506141b86060870161414e565b915060808601356141c88161416b565b809150509295509295909350565b600080604083850312156141e957600080fd5b82356141f481613f73565b91506142026020840161414e565b90509250929050565b6020808252825182820181905260009190848201906040850190845b8181101561425957835173ffffffffffffffffffffffffffffffffffffffff1683529284019291840191600101614227565b50909695505050505050565b600080600080600080600060e0888a03121561428057600080fd5b873561428b81613f73565b9650602088013561429b81613f73565b95506040880135945060608801359350608088013560ff811681146142bf57600080fd5b9699959850939692959460a0840135945060c09093013592915050565b600080604083850312156142ef57600080fd5b82356142fa81613f73565b915060208301356140f381613f73565b600181811c9082168061431e57607f821691505b60208210810361344d577f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b60006020828403121561436957600080fd5b8151610db78161416b565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b818103818111156109a9576109a9614374565b6000602082840312156143c857600080fd5b5051919050565b808201808211156109a9576109a9614374565b600082614418577f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b500490565b80820281158282048414176109a9576109a9614374565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff820361449457614494614374565b5060010190565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603160045260246000fd5b6000602082840312156144dc57600080fd5b8151610db781613f73565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b601f82111561082d57600081815260208120601f850160051c8101602086101561453d5750805b601f850160051c820191505b8181101561455c57828155600101614549565b505050505050565b815167ffffffffffffffff81111561457e5761457e613e99565b6145928161458c845461430a565b84614516565b602080601f8311600181146145e557600084156145af5750858301515b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600386901b1c1916600185901b17855561455c565b6000858152602081207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08616915b8281101561463257888601518255948401946001909101908401614613565b508582101561466e57878501517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600388901b60f8161c191681555b5050505050600190811b01905550565b60008251614690818460208701613e24565b919091019291505056fea2646970667358221220f2eb02bac1667a72be85ab617a5b5aa3d8f7a9b09b4d1fde9756b7a5636daf2164736f6c63430008110033", + "deployedBytecode": "0x608060405234801561001057600080fd5b50600436106102ff5760003560e01c806361d027b31161019c5780639f48118f116100ee578063ced67f0c11610097578063dd62ed3e11610071578063dd62ed3e14610724578063e3e286551461076a578063f0f442601461077d57600080fd5b8063ced67f0c1461066b578063d44ad63f146106fe578063d505accf1461071157600080fd5b8063aa271e1a116100c8578063aa271e1a14610620578063ba330bd714610643578063cd4839ca1461065657600080fd5b80639f48118f146105ef578063a457c2d7146105fa578063a9059cbb1461060d57600080fd5b80637ecebe001161015057806395d89b411161012a57806395d89b41146105c1578063983b2d56146105c95780639e4e0dae146105dc57600080fd5b80637ecebe00146105705780638933fb791461058357806390218cff146105ae57600080fd5b80637334d020116101815780637334d020146105425780637d4c9c2d146105555780637d74e25f1461056857600080fd5b806361d027b3146104c757806370a082311461050c57600080fd5b80633092afd511610255578063395093511161020957806340c10f19116101e357806340c10f19146104815780634dc32fcc146104945780635bfbec96146104a757600080fd5b8063395093511461043b5780633a55f89d1461044e5780633f4218e01461046157600080fd5b8063350ebe041161023a578063350ebe041461040d5780633644e5151461042057806336db43b51461042857600080fd5b80633092afd5146103eb578063313ce567146103fe57600080fd5b8063151dd755116102b757806323b872dd1161029157806323b872dd146103b25780632b471d8e146103c55780632e403e14146103d857600080fd5b8063151dd7551461038057806318160ddd146103a15780632342fb0e146103a957600080fd5b80630919a951116102e85780630919a95114610337578063095ea7b31461034a5780631171bda91461036d57600080fd5b806306fdde0314610304578063077f224a14610322575b600080fd5b61030c610790565b6040516103199190613e48565b60405180910390f35b610335610330366004613f95565b610822565b005b61033561034536600461400d565b610832565b61035d61035836600461402a565b610995565b6040519015158152602001610319565b61033561037b366004614056565b6109af565b61039361038e366004614097565b610b04565b604051908152602001610319565b603554610393565b61039360d25481565b61035d6103c0366004614056565b610dbe565b6103356103d33660046140ce565b610de2565b6103356103e636600461400d565b610e39565b6103356103f936600461400d565b6111e8565b60405160128152602001610319565b61033561041b3660046140fe565b6112d1565b6103936113da565b61033561043636600461402a565b6113e9565b61035d61044936600461402a565b611579565b61033561045c366004614135565b6115c0565b61039361046f36600461400d565b60d16020526000908152604090205481565b61033561048f36600461402a565b6116c3565b6103936104a236600461400d565b611716565b6103936104b5366004614135565b60d36020526000908152604090205481565b60cd546104e79073ffffffffffffffffffffffffffffffffffffffff1681565b60405173ffffffffffffffffffffffffffffffffffffffff9091168152602001610319565b61039361051a36600461400d565b73ffffffffffffffffffffffffffffffffffffffff1660009081526033602052604090205490565b61033561055036600461402a565b61175e565b610335610563366004614179565b6118f1565b610393611c59565b61039361057e36600461400d565b611c7e565b61039361059136600461402a565b60d060209081526000928352604080842090915290825290205481565b6103356105bc366004614135565b611ca9565b61030c611cb6565b6103356105d736600461400d565b611cc5565b6103356105ea3660046141d6565b611d8d565b610393633b9aca0081565b61035d61060836600461402a565b611f99565b61035d61061b36600461402a565b61206f565b61035d61062e36600461400d565b60cc6020526000908152604090205460ff1681565b6104e7610651366004614135565b61207d565b61065e6120b4565b604051610319919061420b565b6106c561067936600461400d565b60ce6020526000908152604090208054600182015460029092015490919067ffffffffffffffff81169060ff680100000000000000008204811691690100000000000000000090041685565b60408051958652602086019490945267ffffffffffffffff9092169284019290925290151560608301521515608082015260a001610319565b61039361070c366004614097565b612122565b61033561071f366004614265565b6122e7565b6103936107323660046142dc565b73ffffffffffffffffffffffffffffffffffffffff918216600090815260346020908152604080832093909416825291909152205490565b61033561077836600461400d565b6124a6565b61033561078b36600461400d565b61267a565b60606036805461079f9061430a565b80601f01602080910402602001604051908101604052809291908181526020018280546107cb9061430a565b80156108185780601f106107ed57610100808354040283529160200191610818565b820191906000526020600020905b8154815290600101906020018083116107fb57829003601f168201915b5050505050905090565b61082d838383612756565b505050565b60cd546040517f521d4de900000000000000000000000000000000000000000000000000000000815233600482015273ffffffffffffffffffffffffffffffffffffffff9091169063521d4de990602401602060405180830381865afa1580156108a0573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906108c49190614357565b6108fa576040517f99e120bc00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff8116600090815260d1602052604081205461092b9060016143a3565b73ffffffffffffffffffffffffffffffffffffffff8316600081815260d160205260409081902083905551919250907f979ef83e7e7a87cb48064e296dd7e997870d50f43acf8d7ad221313526c8ca0f906109899084815260200190565b60405180910390a25050565b6000336109a3818585612a35565b60019150505b92915050565b60cd546040517fe43581b800000000000000000000000000000000000000000000000000000000815233600482015273ffffffffffffffffffffffffffffffffffffffff9091169063e43581b890602401602060405180830381865afa158015610a1d573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610a419190614357565b610a77576040517fee3675d400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b610a9873ffffffffffffffffffffffffffffffffffffffff84168383612be0565b8173ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff167ffff3b3844276f57024e0b42afec1a37f75db36511e43819a4f2a63ab7862b64883604051610af791815260200190565b60405180910390a3505050565b73ffffffffffffffffffffffffffffffffffffffff8316600090815260ce60209081526040808320815160a081018352815481526001820154938101939093526002015467ffffffffffffffff81169183019190915260ff680100000000000000008204811615801560608501526901000000000000000000909204161515608083015280610b94575080608001515b15610bcb576040517fc1ab6dc100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015260009073ffffffffffffffffffffffffffffffffffffffff8716906370a0823190602401602060405180830381865afa158015610c38573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610c5c91906143b6565b8251909150610c6b86836143cf565b1115610c93578151811015610c8e578151610c879082906143a3565b9450610c93565b600094505b6000610ca1610e10426143e2565b73ffffffffffffffffffffffffffffffffffffffff8816600090815260d0602090815260408083208484528252909120549085015191925090610ce488836143cf565b1115610d0f5780846020015111610cfc576000610d0c565b808460200151610d0c91906143a3565b96505b610d1987826143cf565b73ffffffffffffffffffffffffffffffffffffffff8916600081815260d060209081526040808320878452909152902091909155610d599033308a612cb4565b33600090815260d16020526040812054889103610da657633b9aca00856040015167ffffffffffffffff1682610d8f919061441d565b610d9991906143e2565b610da390826143a3565b90505b610db08782612d12565b9450505050505b9392505050565b600033610dcc858285612e32565b610dd7858585612f03565b506001949350505050565b33600090815260cc602052604090205460ff16610e2b576040517ff8d2906c00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b610e3581836131b6565b5050565b60cd546040517fe43581b800000000000000000000000000000000000000000000000000000000815233600482015273ffffffffffffffffffffffffffffffffffffffff9091169063e43581b890602401602060405180830381865afa158015610ea7573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610ecb9190614357565b610f01576040517fee3675d400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015273ffffffffffffffffffffffffffffffffffffffff8216906370a0823190602401602060405180830381865afa158015610f6b573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610f8f91906143b6565b15610fc6576040517f2ef630ec00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff8116600090815260ce602052604081208181556001810182905560020180547fffffffffffffffffffffffffffffffffffffffffffff0000000000000000000016905560cf54905b61102e6001836143a3565b811015611139578273ffffffffffffffffffffffffffffffffffffffff1660cf828154811061105f5761105f614434565b60009182526020909120015473ffffffffffffffffffffffffffffffffffffffff16036111295760cf6110936001846143a3565b815481106110a3576110a3614434565b60009182526020909120015460cf805473ffffffffffffffffffffffffffffffffffffffff90921691839081106110dc576110dc614434565b9060005260206000200160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550611139565b61113281614463565b9050611023565b5060cf80548061114b5761114b61449b565b60008281526020812082017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff90810180547fffffffffffffffffffffffff000000000000000000000000000000000000000016905590910190915560405173ffffffffffffffffffffffffffffffffffffffff8416917f5c95b49c4d59d97a2f044167723f29c74b30f99702e3fd406c3830160aa9ccb891a25050565b60cd5473ffffffffffffffffffffffffffffffffffffffff16331480159061122657503373ffffffffffffffffffffffffffffffffffffffff821614155b1561125d576040517fddb5de5e00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff8116600081815260cc602052604080822080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00169055517f98c15241d6c02bc5ee0b780e11b3ea737a2defd9d04877edbe9f9497065bd02f9190a250565b33600090815260cc602052604090205460ff1661131a576040517ff8d2906c00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff16146113d05773ffffffffffffffffffffffffffffffffffffffff828116600090815260346020908152604080832093851683529290522054838110156113ba576040517f715ec26c00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6113ce83836113c987856143a3565b612a35565b505b61082d82846131b6565b60006113e46133a3565b905090565b60cd546040517f521d4de900000000000000000000000000000000000000000000000000000000815233600482015273ffffffffffffffffffffffffffffffffffffffff9091169063521d4de990602401602060405180830381865afa158015611457573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061147b9190614357565b6114b1576040517f99e120bc00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff8216600090815260ce602052604090206002015468010000000000000000900460ff1661151f576040517fc1ab6dc100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff8216600081815260ce602052604090819020839055517fe7b113fba37131b6396680a0c55790a697ec975e198ff8cfd89dac90a6379e61906109899084815260200190565b33600081815260346020908152604080832073ffffffffffffffffffffffffffffffffffffffff871684529091528120549091906109a390829086906113c99087906143cf565b60cd546040517f521d4de900000000000000000000000000000000000000000000000000000000815233600482015273ffffffffffffffffffffffffffffffffffffffff9091169063521d4de990602401602060405180830381865afa15801561162e573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906116529190614357565b611688576040517f99e120bc00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60d28190556040518181527fc3b69829afe2345596a02c8b587d41f796ba0094481d899e1b2e07b7532a1e219060200160405180910390a150565b33600090815260cc602052604090205460ff1661170c576040517ff8d2906c00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b610e358282612d12565b73ffffffffffffffffffffffffffffffffffffffff8116600090815260d06020526040812081611748610e10426143e2565b8152602001908152602001600020549050919050565b60cd546040517f521d4de900000000000000000000000000000000000000000000000000000000815233600482015273ffffffffffffffffffffffffffffffffffffffff9091169063521d4de990602401602060405180830381865afa1580156117cc573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906117f09190614357565b611826576040517f99e120bc00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff8216600090815260ce602052604090206002015468010000000000000000900460ff16611894576040517fc1ab6dc100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff8216600081815260ce602052604090819020600101839055517fe13ac9338b2ee623233f83c1b3ceab16490fa3e3737fac7f0970d0830a9f4871906109899084815260200190565b60cd546040517fe43581b800000000000000000000000000000000000000000000000000000000815233600482015273ffffffffffffffffffffffffffffffffffffffff9091169063e43581b890602401602060405180830381865afa15801561195f573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906119839190614357565b6119b9576040517fee3675d400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff8516600090815260ce602052604090206002015468010000000000000000900460ff1680611a10575073ffffffffffffffffffffffffffffffffffffffff8516155b15611a47576040517fc1ab6dc100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b633b9aca008267ffffffffffffffff161115611a8f576040517feca1d2c600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040805160a08101825260008082526020820181905291810182905260608101829052608081019190915284815260208082018581528315156080840190815267ffffffffffffffff808716604080870191825260016060880181815273ffffffffffffffffffffffffffffffffffffffff8e16600081815260ce9099528389208a5181559751888401559351600290970180549151965115156901000000000000000000027fffffffffffffffffffffffffffffffffffffffffffff00ffffffffffffffffff97151568010000000000000000027fffffffffffffffffffffffffffffffffffffffffffffff000000000000000000909316989096169790971717949094169290921790935560cf805492830181559093527facb8d954e2cfef495862221e91bd7523613cf8808827cb33edfe4904cc51bf290180547fffffffffffffffffffffffff0000000000000000000000000000000000000000168217905590517f53087ff85d80a7671594bd2e86b92af22e0b3c2c441c8033bba7399b7b5cbe2390611c49908890889088908890938452602084019290925267ffffffffffffffff1660408301521515606082015260800190565b60405180910390a2505050505050565b600060d381611c6a610e10426143e2565b815260200190815260200160002054905090565b73ffffffffffffffffffffffffffffffffffffffff81166000908152609960205260408120546109a9565b611cb333826131b6565b50565b60606037805461079f9061430a565b60cd5473ffffffffffffffffffffffffffffffffffffffff163314611d16576040517fb90cdbb100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff8116600081815260cc602052604080822080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00166001179055517f98c15241d6c02bc5ee0b780e11b3ea737a2defd9d04877edbe9f9497065bd02f9190a250565b60cd546040517f521d4de900000000000000000000000000000000000000000000000000000000815233600482015273ffffffffffffffffffffffffffffffffffffffff9091169063521d4de990602401602060405180830381865afa158015611dfb573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611e1f9190614357565b611e55576040517f99e120bc00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff8216600090815260ce602052604090206002015468010000000000000000900460ff16611ec3576040517fc1ab6dc100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b633b9aca008167ffffffffffffffff161115611f0b576040517feca1d2c600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff8216600081815260ce602090815260409182902060020180547fffffffffffffffffffffffffffffffffffffffffffffffff00000000000000001667ffffffffffffffff861690811790915591519182527f901f9de19b475adc8da4110434b8df940dce085afd05e2281c86807f3a899d299101610989565b33600081815260346020908152604080832073ffffffffffffffffffffffffffffffffffffffff8716845290915281205490919083811015612062576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602560248201527f45524332303a2064656372656173656420616c6c6f77616e63652062656c6f7760448201527f207a65726f00000000000000000000000000000000000000000000000000000060648201526084015b60405180910390fd5b610dd78286868403612a35565b6000336109a3818585612f03565b60cf818154811061208d57600080fd5b60009182526020909120015473ffffffffffffffffffffffffffffffffffffffff16905081565b606060cf80548060200260200160405190810160405280929190818152602001828054801561081857602002820191906000526020600020905b815473ffffffffffffffffffffffffffffffffffffffff1681526001909101906020018083116120ee575050505050905090565b73ffffffffffffffffffffffffffffffffffffffff8316600090815260ce60209081526040808320815160a081018352815481526001820154938101939093526002015467ffffffffffffffff81169183019190915260ff6801000000000000000082048116158015606085015269010000000000000000009092041615156080830152806121b2575080608001515b156121e9576040517fc1ab6dc100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60006121f7610e10426143e2565b600081815260d36020526040812054919250906122159087906143cf565b905060d254811115612253576040517f6d43d1ac00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600082815260d36020526040902081905561226e33876131b6565b33600090815260d160205260408120548791036122bb57633b9aca00846040015167ffffffffffffffff16826122a4919061441d565b6122ae91906143e2565b6122b890826143a3565b90505b6122dc73ffffffffffffffffffffffffffffffffffffffff89168783612be0565b979650505050505050565b83421115612351576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f45524332305065726d69743a206578706972656420646561646c696e650000006044820152606401612059565b60007f6e71edae12b1b97f4d1f60370fef10105fa2faae0126114a169c64845d6126c98888886123808c61341e565b60408051602081019690965273ffffffffffffffffffffffffffffffffffffffff94851690860152929091166060840152608083015260a082015260c0810186905260e00160405160208183030381529060405280519060200120905060006123e882613453565b905060006123f8828787876134bc565b90508973ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff161461248f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601e60248201527f45524332305065726d69743a20696e76616c6964207369676e617475726500006044820152606401612059565b61249a8a8a8a612a35565b50505050505050505050565b60cd546040517f521d4de900000000000000000000000000000000000000000000000000000000815233600482015273ffffffffffffffffffffffffffffffffffffffff9091169063521d4de990602401602060405180830381865afa158015612514573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906125389190614357565b61256e576040517f99e120bc00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff8116600090815260ce602052604090206002015468010000000000000000900460ff166125dc576040517fc1ab6dc100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff8116600081815260ce602090815260409182902060020180547fffffffffffffffffffffffffffffffffffffffffffff00ffffffffffffffffff811669010000000000000000009182900460ff16801592830291909117909255925192835292917ff7c93079dcbf699749d66345a351afab7d24219bb1d915c9f4fc4cf03f00d3979101610989565b60cd5473ffffffffffffffffffffffffffffffffffffffff1633146126cb576040517fb90cdbb100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60cd80547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83169081179091556040517f7dae230f18360d76a040c81f050aa14eb9d6dc7901b20fc5d855e2a20fe814d190600090a250565b73ffffffffffffffffffffffffffffffffffffffff163b151590565b600054610100900460ff16158080156127765750600054600160ff909116105b806127905750303b158015612790575060005460ff166001145b61281c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201527f647920696e697469616c697a65640000000000000000000000000000000000006064820152608401612059565b600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00166001179055801561287a57600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff166101001790555b3073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1663e9cbd8226040518163ffffffff1660e01b8152600401602060405180830381865afa1580156128dc573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061290091906144ca565b73ffffffffffffffffffffffffffffffffffffffff161461294d576040517f14bcf5c800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b612956846134e4565b61296084846135ba565b60cd80547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff84169081179091556040517f7dae230f18360d76a040c81f050aa14eb9d6dc7901b20fc5d855e2a20fe814d190600090a28015612a2f57600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15b50505050565b73ffffffffffffffffffffffffffffffffffffffff8316612ad7576040517f08c379a0000000000000000000000000000000000000000000000000000000008152602060048201526024808201527f45524332303a20617070726f76652066726f6d20746865207a65726f2061646460448201527f72657373000000000000000000000000000000000000000000000000000000006064820152608401612059565b73ffffffffffffffffffffffffffffffffffffffff8216612b7a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602260248201527f45524332303a20617070726f766520746f20746865207a65726f20616464726560448201527f73730000000000000000000000000000000000000000000000000000000000006064820152608401612059565b73ffffffffffffffffffffffffffffffffffffffff83811660008181526034602090815260408083209487168084529482529182902085905590518481527f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b9259101610af7565b60405173ffffffffffffffffffffffffffffffffffffffff831660248201526044810182905261082d9084907fa9059cbb00000000000000000000000000000000000000000000000000000000906064015b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff000000000000000000000000000000000000000000000000000000009093169290921790915261365b565b60405173ffffffffffffffffffffffffffffffffffffffff80851660248301528316604482015260648101829052612a2f9085907f23b872dd0000000000000000000000000000000000000000000000000000000090608401612c32565b73ffffffffffffffffffffffffffffffffffffffff8216612d8f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601f60248201527f45524332303a206d696e7420746f20746865207a65726f2061646472657373006044820152606401612059565b8060356000828254612da191906143cf565b909155505073ffffffffffffffffffffffffffffffffffffffff821660009081526033602052604081208054839290612ddb9084906143cf565b909155505060405181815273ffffffffffffffffffffffffffffffffffffffff8316906000907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef9060200160405180910390a35050565b73ffffffffffffffffffffffffffffffffffffffff8381166000908152603460209081526040808320938616835292905220547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8114612a2f5781811015612ef6576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f45524332303a20696e73756666696369656e7420616c6c6f77616e63650000006044820152606401612059565b612a2f8484848403612a35565b73ffffffffffffffffffffffffffffffffffffffff8316612fa6576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602560248201527f45524332303a207472616e736665722066726f6d20746865207a65726f20616460448201527f64726573730000000000000000000000000000000000000000000000000000006064820152608401612059565b73ffffffffffffffffffffffffffffffffffffffff8216613049576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602360248201527f45524332303a207472616e7366657220746f20746865207a65726f206164647260448201527f65737300000000000000000000000000000000000000000000000000000000006064820152608401612059565b73ffffffffffffffffffffffffffffffffffffffff8316600090815260336020526040902054818110156130ff576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f45524332303a207472616e7366657220616d6f756e742065786365656473206260448201527f616c616e636500000000000000000000000000000000000000000000000000006064820152608401612059565b73ffffffffffffffffffffffffffffffffffffffff8085166000908152603360205260408082208585039055918516815290812080548492906131439084906143cf565b925050819055508273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef846040516131a991815260200190565b60405180910390a3612a2f565b73ffffffffffffffffffffffffffffffffffffffff8216613259576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602160248201527f45524332303a206275726e2066726f6d20746865207a65726f2061646472657360448201527f73000000000000000000000000000000000000000000000000000000000000006064820152608401612059565b73ffffffffffffffffffffffffffffffffffffffff82166000908152603360205260409020548181101561330f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602260248201527f45524332303a206275726e20616d6f756e7420657863656564732062616c616e60448201527f63650000000000000000000000000000000000000000000000000000000000006064820152608401612059565b73ffffffffffffffffffffffffffffffffffffffff8316600090815260336020526040812083830390556035805484929061334b9084906143a3565b909155505060405182815260009073ffffffffffffffffffffffffffffffffffffffff8516907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef9060200160405180910390a3505050565b60006113e47f8b73c3c69bb8fe3d512ecc4cf759cc79239f7b179b0ffacaa9a75d522b39400f6133d260655490565b6066546040805160208101859052908101839052606081018290524660808201523060a082015260009060c0016040516020818303038152906040528051906020012090509392505050565b73ffffffffffffffffffffffffffffffffffffffff811660009081526099602052604090208054600181018255905b50919050565b60006109a96134606133a3565b836040517f19010000000000000000000000000000000000000000000000000000000000006020820152602281018390526042810182905260009060620160405160208183030381529060405280519060200120905092915050565b60008060006134cd87878787613767565b915091506134da8161387f565b5095945050505050565b600054610100900460ff1661357b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201527f6e697469616c697a696e670000000000000000000000000000000000000000006064820152608401612059565b611cb3816040518060400160405280600181526020017f3100000000000000000000000000000000000000000000000000000000000000815250613ad3565b600054610100900460ff16613651576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201527f6e697469616c697a696e670000000000000000000000000000000000000000006064820152608401612059565b610e358282613b84565b60006136bd826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c65648152508573ffffffffffffffffffffffffffffffffffffffff16613c349092919063ffffffff16565b80519091501561082d57808060200190518101906136db9190614357565b61082d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e60448201527f6f742073756363656564000000000000000000000000000000000000000000006064820152608401612059565b6000807f7fffffffffffffffffffffffffffffff5d576e7357a4501ddfe92f46681b20a083111561379e5750600090506003613876565b8460ff16601b141580156137b657508460ff16601c14155b156137c75750600090506004613876565b6040805160008082526020820180845289905260ff881692820192909252606081018690526080810185905260019060a0016020604051602081039080840390855afa15801561381b573d6000803e3d6000fd5b50506040517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0015191505073ffffffffffffffffffffffffffffffffffffffff811661386f57600060019250925050613876565b9150600090505b94509492505050565b6000816004811115613893576138936144e7565b0361389b5750565b60018160048111156138af576138af6144e7565b03613916576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601860248201527f45434453413a20696e76616c6964207369676e617475726500000000000000006044820152606401612059565b600281600481111561392a5761392a6144e7565b03613991576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601f60248201527f45434453413a20696e76616c6964207369676e6174757265206c656e677468006044820152606401612059565b60038160048111156139a5576139a56144e7565b03613a32576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602260248201527f45434453413a20696e76616c6964207369676e6174757265202773272076616c60448201527f75650000000000000000000000000000000000000000000000000000000000006064820152608401612059565b6004816004811115613a4657613a466144e7565b03611cb3576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602260248201527f45434453413a20696e76616c6964207369676e6174757265202776272076616c60448201527f75650000000000000000000000000000000000000000000000000000000000006064820152608401612059565b600054610100900460ff16613b6a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201527f6e697469616c697a696e670000000000000000000000000000000000000000006064820152608401612059565b815160209283012081519190920120606591909155606655565b600054610100900460ff16613c1b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201527f6e697469616c697a696e670000000000000000000000000000000000000000006064820152608401612059565b6036613c278382614564565b50603761082d8282614564565b6060613c438484600085613c4b565b949350505050565b606082471015613cdd576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f60448201527f722063616c6c00000000000000000000000000000000000000000000000000006064820152608401612059565b73ffffffffffffffffffffffffffffffffffffffff85163b613d5b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006044820152606401612059565b6000808673ffffffffffffffffffffffffffffffffffffffff168587604051613d84919061467e565b60006040518083038185875af1925050503d8060008114613dc1576040519150601f19603f3d011682016040523d82523d6000602084013e613dc6565b606091505b50915091506122dc82828660608315613de0575081610db7565b825115613df05782518084602001fd5b816040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016120599190613e48565b60005b83811015613e3f578181015183820152602001613e27565b50506000910152565b6020815260008251806020840152613e67816040850160208701613e24565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169190910160400192915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b600082601f830112613ed957600080fd5b813567ffffffffffffffff80821115613ef457613ef4613e99565b604051601f83017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0908116603f01168101908282118183101715613f3a57613f3a613e99565b81604052838152866020858801011115613f5357600080fd5b836020870160208301376000602085830101528094505050505092915050565b73ffffffffffffffffffffffffffffffffffffffff81168114611cb357600080fd5b600080600060608486031215613faa57600080fd5b833567ffffffffffffffff80821115613fc257600080fd5b613fce87838801613ec8565b94506020860135915080821115613fe457600080fd5b50613ff186828701613ec8565b925050604084013561400281613f73565b809150509250925092565b60006020828403121561401f57600080fd5b8135610db781613f73565b6000806040838503121561403d57600080fd5b823561404881613f73565b946020939093013593505050565b60008060006060848603121561406b57600080fd5b833561407681613f73565b9250602084013561408681613f73565b929592945050506040919091013590565b6000806000606084860312156140ac57600080fd5b83356140b781613f73565b925060208401359150604084013561400281613f73565b600080604083850312156140e157600080fd5b8235915060208301356140f381613f73565b809150509250929050565b60008060006060848603121561411357600080fd5b83359250602084013561412581613f73565b9150604084013561400281613f73565b60006020828403121561414757600080fd5b5035919050565b803567ffffffffffffffff8116811461416657600080fd5b919050565b8015158114611cb357600080fd5b600080600080600060a0868803121561419157600080fd5b853561419c81613f73565b945060208601359350604086013592506141b86060870161414e565b915060808601356141c88161416b565b809150509295509295909350565b600080604083850312156141e957600080fd5b82356141f481613f73565b91506142026020840161414e565b90509250929050565b6020808252825182820181905260009190848201906040850190845b8181101561425957835173ffffffffffffffffffffffffffffffffffffffff1683529284019291840191600101614227565b50909695505050505050565b600080600080600080600060e0888a03121561428057600080fd5b873561428b81613f73565b9650602088013561429b81613f73565b95506040880135945060608801359350608088013560ff811681146142bf57600080fd5b9699959850939692959460a0840135945060c09093013592915050565b600080604083850312156142ef57600080fd5b82356142fa81613f73565b915060208301356140f381613f73565b600181811c9082168061431e57607f821691505b60208210810361344d577f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b60006020828403121561436957600080fd5b8151610db78161416b565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b818103818111156109a9576109a9614374565b6000602082840312156143c857600080fd5b5051919050565b808201808211156109a9576109a9614374565b600082614418577f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b500490565b80820281158282048414176109a9576109a9614374565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff820361449457614494614374565b5060010190565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603160045260246000fd5b6000602082840312156144dc57600080fd5b8151610db781613f73565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b601f82111561082d57600081815260208120601f850160051c8101602086101561453d5750805b601f850160051c820191505b8181101561455c57828155600101614549565b505050505050565b815167ffffffffffffffff81111561457e5761457e613e99565b6145928161458c845461430a565b84614516565b602080601f8311600181146145e557600084156145af5750858301515b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600386901b1c1916600185901b17855561455c565b6000858152602081207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08616915b8281101561463257888601518255948401946001909101908401614613565b508582101561466e57878501517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600388901b60f8161c191681555b5050505050600190811b01905550565b60008251614690818460208701613e24565b919091019291505056fea2646970667358221220f2eb02bac1667a72be85ab617a5b5aa3d8f7a9b09b4d1fde9756b7a5636daf2164736f6c63430008110033", "devdoc": { "author": "Angle Labs, Inc.", - "details": "This contract supports bridge tokens having a minting right on the stablecoin (also referred to as the canonical or the native token)References: - FRAX implementation: https://polygonscan.com/address/0x45c32fA6DF82ead1e2EF74d17b76547EDdFaFF89#code - QiDAO implementation: https://snowtrace.io/address/0x5c49b268c9841AFF1Cc3B0a418ff5c3442eE3F3b#code", + "details": "This contract supports bridge tokens having a minting right on the stablecoin (also referred to as the canonical or the native token)", "kind": "dev", "methods": { "DOMAIN_SEPARATOR()": { @@ -1320,14 +1320,6 @@ "increaseAllowance(address,uint256)": { "details": "Atomically increases the allowance granted to `spender` by the caller. This is an alternative to {approve} that can be used as a mitigation for problems described in {IERC20-approve}. Emits an {Approval} event indicating the updated allowance. Requirements: - `spender` cannot be the zero address." }, - "initialize(string,string,address)": { - "details": "By default, agTokens are ERC-20 tokens with 18 decimals", - "params": { - "_treasury": "Reference to the `Treasury` contract associated to this agToken", - "name_": "Name of the token", - "symbol_": "Symbol of the token" - } - }, "mint(address,uint256)": { "details": "The contracts allowed to issue agTokens are the `StableMaster` contract, `VaultManager` contracts associated to this stablecoin as well as the flash loan module (if activated) and potentially contracts whitelisted by governance", "params": { @@ -1429,7 +1421,7 @@ "notice": "Burns `amount` tokens from a `burner` address" }, "burnStablecoin(uint256)": { - "notice": "Allows anyone to burn agToken without redeeming collateral back" + "notice": "Allows anyone to burn stablecoins" }, "chainTotalHourlyLimit()": { "notice": "Limit to the amount of tokens that can be sent from that chain to another chain" @@ -1624,7 +1616,7 @@ "type": "t_array(t_uint256)49_storage" }, { - "astId": 8510, + "astId": 7427, "contract": "contracts/agToken/AgTokenSideChainMultiBridge.sol:AgTokenSideChainMultiBridge", "label": "isMinter", "offset": 0, @@ -1632,7 +1624,7 @@ "type": "t_mapping(t_address,t_bool)" }, { - "astId": 8513, + "astId": 7430, "contract": "contracts/agToken/AgTokenSideChainMultiBridge.sol:AgTokenSideChainMultiBridge", "label": "treasury", "offset": 0, @@ -1640,15 +1632,15 @@ "type": "t_address" }, { - "astId": 7671, + "astId": 7739, "contract": "contracts/agToken/AgTokenSideChainMultiBridge.sol:AgTokenSideChainMultiBridge", "label": "bridges", "offset": 0, "slot": "206", - "type": "t_mapping(t_address,t_struct(BridgeDetails)7665_storage)" + "type": "t_mapping(t_address,t_struct(BridgeDetails)7733_storage)" }, { - "astId": 7675, + "astId": 7743, "contract": "contracts/agToken/AgTokenSideChainMultiBridge.sol:AgTokenSideChainMultiBridge", "label": "bridgeTokensList", "offset": 0, @@ -1656,7 +1648,7 @@ "type": "t_array(t_address)dyn_storage" }, { - "astId": 7682, + "astId": 7750, "contract": "contracts/agToken/AgTokenSideChainMultiBridge.sol:AgTokenSideChainMultiBridge", "label": "usage", "offset": 0, @@ -1664,7 +1656,7 @@ "type": "t_mapping(t_address,t_mapping(t_uint256,t_uint256))" }, { - "astId": 7687, + "astId": 7755, "contract": "contracts/agToken/AgTokenSideChainMultiBridge.sol:AgTokenSideChainMultiBridge", "label": "isFeeExempt", "offset": 0, @@ -1672,7 +1664,7 @@ "type": "t_mapping(t_address,t_uint256)" }, { - "astId": 7690, + "astId": 7758, "contract": "contracts/agToken/AgTokenSideChainMultiBridge.sol:AgTokenSideChainMultiBridge", "label": "chainTotalHourlyLimit", "offset": 0, @@ -1680,7 +1672,7 @@ "type": "t_uint256" }, { - "astId": 7695, + "astId": 7763, "contract": "contracts/agToken/AgTokenSideChainMultiBridge.sol:AgTokenSideChainMultiBridge", "label": "chainTotalUsage", "offset": 0, @@ -1749,12 +1741,12 @@ "numberOfBytes": "32", "value": "t_mapping(t_uint256,t_uint256)" }, - "t_mapping(t_address,t_struct(BridgeDetails)7665_storage)": { + "t_mapping(t_address,t_struct(BridgeDetails)7733_storage)": { "encoding": "mapping", "key": "t_address", "label": "mapping(address => struct AgTokenSideChainMultiBridge.BridgeDetails)", "numberOfBytes": "32", - "value": "t_struct(BridgeDetails)7665_storage" + "value": "t_struct(BridgeDetails)7733_storage" }, "t_mapping(t_address,t_struct(Counter)2493_storage)": { "encoding": "mapping", @@ -1782,12 +1774,12 @@ "label": "string", "numberOfBytes": "32" }, - "t_struct(BridgeDetails)7665_storage": { + "t_struct(BridgeDetails)7733_storage": { "encoding": "inplace", "label": "struct AgTokenSideChainMultiBridge.BridgeDetails", "members": [ { - "astId": 7656, + "astId": 7724, "contract": "contracts/agToken/AgTokenSideChainMultiBridge.sol:AgTokenSideChainMultiBridge", "label": "limit", "offset": 0, @@ -1795,7 +1787,7 @@ "type": "t_uint256" }, { - "astId": 7658, + "astId": 7726, "contract": "contracts/agToken/AgTokenSideChainMultiBridge.sol:AgTokenSideChainMultiBridge", "label": "hourlyLimit", "offset": 0, @@ -1803,7 +1795,7 @@ "type": "t_uint256" }, { - "astId": 7660, + "astId": 7728, "contract": "contracts/agToken/AgTokenSideChainMultiBridge.sol:AgTokenSideChainMultiBridge", "label": "fee", "offset": 0, @@ -1811,7 +1803,7 @@ "type": "t_uint64" }, { - "astId": 7662, + "astId": 7730, "contract": "contracts/agToken/AgTokenSideChainMultiBridge.sol:AgTokenSideChainMultiBridge", "label": "allowed", "offset": 8, @@ -1819,7 +1811,7 @@ "type": "t_bool" }, { - "astId": 7664, + "astId": 7732, "contract": "contracts/agToken/AgTokenSideChainMultiBridge.sol:AgTokenSideChainMultiBridge", "label": "paused", "offset": 9, diff --git a/deployments/base/CoreBorrowTest.json b/deployments/base/CoreBorrowTest.json new file mode 100644 index 00000000..a2605515 --- /dev/null +++ b/deployments/base/CoreBorrowTest.json @@ -0,0 +1,337 @@ +{ + "address": "0xA6a505Eeb4e1e93052c48126f2d42ef6694A651D", + "abi": [ + { + "inputs": [ + { + "internalType": "address", + "name": "_logic", + "type": "address" + }, + { + "internalType": "address", + "name": "admin_", + "type": "address" + }, + { + "internalType": "bytes", + "name": "_data", + "type": "bytes" + } + ], + "stateMutability": "payable", + "type": "constructor" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "previousAdmin", + "type": "address" + }, + { + "indexed": false, + "internalType": "address", + "name": "newAdmin", + "type": "address" + } + ], + "name": "AdminChanged", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "beacon", + "type": "address" + } + ], + "name": "BeaconUpgraded", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "implementation", + "type": "address" + } + ], + "name": "Upgraded", + "type": "event" + }, + { + "stateMutability": "payable", + "type": "fallback" + }, + { + "inputs": [], + "name": "admin", + "outputs": [ + { + "internalType": "address", + "name": "admin_", + "type": "address" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "newAdmin", + "type": "address" + } + ], + "name": "changeAdmin", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "implementation", + "outputs": [ + { + "internalType": "address", + "name": "implementation_", + "type": "address" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "newImplementation", + "type": "address" + } + ], + "name": "upgradeTo", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "newImplementation", + "type": "address" + }, + { + "internalType": "bytes", + "name": "data", + "type": "bytes" + } + ], + "name": "upgradeToAndCall", + "outputs": [], + "stateMutability": "payable", + "type": "function" + }, + { + "stateMutability": "payable", + "type": "receive" + } + ], + "transactionHash": "0xf1b1e215c2677e3417847268ed08234b54cd73ab46e5a4e240be48047e1b3377", + "receipt": { + "to": null, + "from": "0xfdA462548Ce04282f4B6D6619823a7C64Fdc0185", + "contractAddress": "0xA6a505Eeb4e1e93052c48126f2d42ef6694A651D", + "transactionIndex": 2, + "gasUsed": "1038543", + "logsBloom": "0x00000004000000000800000400000000480000000000000000000000200000000000000200000000000400000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000000080000000000000000000020000400000000000000800000000800000000000000000000000000000000000000000004000000000000000000003000080080000000000804000000000000000000010000000000400000000000000000000001000001000001000000020020000100000008000040000000800000400000100000000010020000000800000000000000000000000000400000000000000000000000000040000", + "blockHash": "0x79d3c0edb0afb44688195d2aae2423f942d536623cab44dbdb80d089cf37bb7f", + "transactionHash": "0xf1b1e215c2677e3417847268ed08234b54cd73ab46e5a4e240be48047e1b3377", + "logs": [ + { + "transactionIndex": 2, + "blockNumber": 9043231, + "transactionHash": "0xf1b1e215c2677e3417847268ed08234b54cd73ab46e5a4e240be48047e1b3377", + "address": "0xA6a505Eeb4e1e93052c48126f2d42ef6694A651D", + "topics": [ + "0xbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b", + "0x00000000000000000000000059153e939c5b4721543251ff3049ea04c755373b" + ], + "data": "0x", + "logIndex": 0, + "blockHash": "0x79d3c0edb0afb44688195d2aae2423f942d536623cab44dbdb80d089cf37bb7f" + }, + { + "transactionIndex": 2, + "blockNumber": 9043231, + "transactionHash": "0xf1b1e215c2677e3417847268ed08234b54cd73ab46e5a4e240be48047e1b3377", + "address": "0xA6a505Eeb4e1e93052c48126f2d42ef6694A651D", + "topics": [ + "0x2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d", + "0x7935bd0ae54bc31f548c14dba4d37c5c64b3f8ca900cb468fb8abd54d5894f55", + "0x000000000000000000000000fda462548ce04282f4b6d6619823a7c64fdc0185", + "0x000000000000000000000000fda462548ce04282f4b6d6619823a7c64fdc0185" + ], + "data": "0x", + "logIndex": 1, + "blockHash": "0x79d3c0edb0afb44688195d2aae2423f942d536623cab44dbdb80d089cf37bb7f" + }, + { + "transactionIndex": 2, + "blockNumber": 9043231, + "transactionHash": "0xf1b1e215c2677e3417847268ed08234b54cd73ab46e5a4e240be48047e1b3377", + "address": "0xA6a505Eeb4e1e93052c48126f2d42ef6694A651D", + "topics": [ + "0x2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d", + "0x55435dd261a4b9b3364963f7738a7a662ad9c84396d64be3365284bb7f0a5041", + "0x000000000000000000000000e4bb74804edf5280c9203f034036f7cb15196078", + "0x000000000000000000000000fda462548ce04282f4b6d6619823a7c64fdc0185" + ], + "data": "0x", + "logIndex": 2, + "blockHash": "0x79d3c0edb0afb44688195d2aae2423f942d536623cab44dbdb80d089cf37bb7f" + }, + { + "transactionIndex": 2, + "blockNumber": 9043231, + "transactionHash": "0xf1b1e215c2677e3417847268ed08234b54cd73ab46e5a4e240be48047e1b3377", + "address": "0xA6a505Eeb4e1e93052c48126f2d42ef6694A651D", + "topics": [ + "0x2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d", + "0x55435dd261a4b9b3364963f7738a7a662ad9c84396d64be3365284bb7f0a5041", + "0x000000000000000000000000fda462548ce04282f4b6d6619823a7c64fdc0185", + "0x000000000000000000000000fda462548ce04282f4b6d6619823a7c64fdc0185" + ], + "data": "0x", + "logIndex": 3, + "blockHash": "0x79d3c0edb0afb44688195d2aae2423f942d536623cab44dbdb80d089cf37bb7f" + }, + { + "transactionIndex": 2, + "blockNumber": 9043231, + "transactionHash": "0xf1b1e215c2677e3417847268ed08234b54cd73ab46e5a4e240be48047e1b3377", + "address": "0xA6a505Eeb4e1e93052c48126f2d42ef6694A651D", + "topics": [ + "0xbd79b86ffe0ab8e8776151514217cd7cacd52c909f66475c3af44e129f0b00ff", + "0x55435dd261a4b9b3364963f7738a7a662ad9c84396d64be3365284bb7f0a5041", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x7935bd0ae54bc31f548c14dba4d37c5c64b3f8ca900cb468fb8abd54d5894f55" + ], + "data": "0x", + "logIndex": 4, + "blockHash": "0x79d3c0edb0afb44688195d2aae2423f942d536623cab44dbdb80d089cf37bb7f" + }, + { + "transactionIndex": 2, + "blockNumber": 9043231, + "transactionHash": "0xf1b1e215c2677e3417847268ed08234b54cd73ab46e5a4e240be48047e1b3377", + "address": "0xA6a505Eeb4e1e93052c48126f2d42ef6694A651D", + "topics": [ + "0xbd79b86ffe0ab8e8776151514217cd7cacd52c909f66475c3af44e129f0b00ff", + "0x7935bd0ae54bc31f548c14dba4d37c5c64b3f8ca900cb468fb8abd54d5894f55", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x7935bd0ae54bc31f548c14dba4d37c5c64b3f8ca900cb468fb8abd54d5894f55" + ], + "data": "0x", + "logIndex": 5, + "blockHash": "0x79d3c0edb0afb44688195d2aae2423f942d536623cab44dbdb80d089cf37bb7f" + }, + { + "transactionIndex": 2, + "blockNumber": 9043231, + "transactionHash": "0xf1b1e215c2677e3417847268ed08234b54cd73ab46e5a4e240be48047e1b3377", + "address": "0xA6a505Eeb4e1e93052c48126f2d42ef6694A651D", + "topics": [ + "0xbd79b86ffe0ab8e8776151514217cd7cacd52c909f66475c3af44e129f0b00ff", + "0x0ae0130c6b34f32239dfe5e419a3fbd7546b44e99783257f2d93526d5a936d46", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x7935bd0ae54bc31f548c14dba4d37c5c64b3f8ca900cb468fb8abd54d5894f55" + ], + "data": "0x", + "logIndex": 6, + "blockHash": "0x79d3c0edb0afb44688195d2aae2423f942d536623cab44dbdb80d089cf37bb7f" + }, + { + "transactionIndex": 2, + "blockNumber": 9043231, + "transactionHash": "0xf1b1e215c2677e3417847268ed08234b54cd73ab46e5a4e240be48047e1b3377", + "address": "0xA6a505Eeb4e1e93052c48126f2d42ef6694A651D", + "topics": [ + "0x7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb3847402498" + ], + "data": "0x0000000000000000000000000000000000000000000000000000000000000001", + "logIndex": 7, + "blockHash": "0x79d3c0edb0afb44688195d2aae2423f942d536623cab44dbdb80d089cf37bb7f" + }, + { + "transactionIndex": 2, + "blockNumber": 9043231, + "transactionHash": "0xf1b1e215c2677e3417847268ed08234b54cd73ab46e5a4e240be48047e1b3377", + "address": "0xA6a505Eeb4e1e93052c48126f2d42ef6694A651D", + "topics": [ + "0x7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f" + ], + "data": "0x000000000000000000000000000000000000000000000000000000000000000000000000000000000000000031429d1856ad1377a8a0079410b297e1a9e214c2", + "logIndex": 8, + "blockHash": "0x79d3c0edb0afb44688195d2aae2423f942d536623cab44dbdb80d089cf37bb7f" + } + ], + "blockNumber": 9043231, + "cumulativeGasUsed": "1107448", + "status": 1, + "byzantium": true + }, + "args": [ + "0x59153e939c5b4721543251ff3049Ea04c755373B", + "0x31429d1856aD1377A8A0079410B297e1a9e214c2", + "0x485cc955000000000000000000000000fda462548ce04282f4b6d6619823a7c64fdc0185000000000000000000000000e4bb74804edf5280c9203f034036f7cb15196078" + ], + "numDeployments": 1, + "solcInputHash": "871924e0c138825a2736b76def8fef8d", + "metadata": "{\"compiler\":{\"version\":\"0.8.17+commit.8df45f5f\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_logic\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"admin_\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"_data\",\"type\":\"bytes\"}],\"stateMutability\":\"payable\",\"type\":\"constructor\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"previousAdmin\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"newAdmin\",\"type\":\"address\"}],\"name\":\"AdminChanged\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"beacon\",\"type\":\"address\"}],\"name\":\"BeaconUpgraded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"implementation\",\"type\":\"address\"}],\"name\":\"Upgraded\",\"type\":\"event\"},{\"stateMutability\":\"payable\",\"type\":\"fallback\"},{\"inputs\":[],\"name\":\"admin\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"admin_\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newAdmin\",\"type\":\"address\"}],\"name\":\"changeAdmin\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"implementation\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"implementation_\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newImplementation\",\"type\":\"address\"}],\"name\":\"upgradeTo\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newImplementation\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"}],\"name\":\"upgradeToAndCall\",\"outputs\":[],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"stateMutability\":\"payable\",\"type\":\"receive\"}],\"devdoc\":{\"details\":\"This contract implements a proxy that is upgradeable by an admin. It is fully forked from OpenZeppelin `TransparentUpgradeableProxy` To avoid https://medium.com/nomic-labs-blog/malicious-backdoors-in-ethereum-proxies-62629adf3357[proxy selector clashing], which can potentially be used in an attack, this contract uses the https://blog.openzeppelin.com/the-transparent-proxy-pattern/[transparent proxy pattern]. This pattern implies two things that go hand in hand: 1. If any account other than the admin calls the proxy, the call will be forwarded to the implementation, even if that call matches one of the admin functions exposed by the proxy itself. 2. If the admin calls the proxy, it can access the admin functions, but its calls will never be forwarded to the implementation. If the admin tries to call a function on the implementation it will fail with an error that says \\\"admin cannot fallback to proxy target\\\". These properties mean that the admin account can only be used for admin actions like upgrading the proxy or changing the admin, so it's best if it's a dedicated account that is not used for anything else. This will avoid headaches due to sudden errors when trying to call a function from the proxy implementation. Our recommendation is for the dedicated account to be an instance of the {ProxyAdmin} contract. If set up this way, you should think of the `ProxyAdmin` instance as the real administrative interface of your proxy.\",\"kind\":\"dev\",\"methods\":{\"admin()\":{\"details\":\"Returns the current admin. NOTE: Only the admin can call this function. See {ProxyAdmin-getProxyAdmin}. TIP: To get this value clients can read directly from the storage slot shown below (specified by EIP1967) using the https://eth.wiki/json-rpc/API#eth_getstorageat[`eth_getStorageAt`] RPC call. `0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103`\"},\"changeAdmin(address)\":{\"details\":\"Changes the admin of the proxy. Emits an {AdminChanged} event. NOTE: Only the admin can call this function. See {ProxyAdmin-changeProxyAdmin}.\"},\"constructor\":{\"details\":\"Initializes an upgradeable proxy managed by `_admin`, backed by the implementation at `_logic`, and optionally initialized with `_data` as explained in {ERC1967Proxy-constructor}.\"},\"implementation()\":{\"details\":\"Returns the current implementation. NOTE: Only the admin can call this function. See {ProxyAdmin-getProxyImplementation}. TIP: To get this value clients can read directly from the storage slot shown below (specified by EIP1967) using the https://eth.wiki/json-rpc/API#eth_getstorageat[`eth_getStorageAt`] RPC call. `0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc`\"},\"upgradeTo(address)\":{\"details\":\"Upgrade the implementation of the proxy. NOTE: Only the admin can call this function. See {ProxyAdmin-upgrade}.\"},\"upgradeToAndCall(address,bytes)\":{\"details\":\"Upgrade the implementation of the proxy, and then call a function from the new implementation as specified by `data`, which should be an encoded function call. This is useful to initialize new storage variables in the proxied contract. NOTE: Only the admin can call this function. See {ProxyAdmin-upgradeAndCall}.\"}},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/external/TransparentUpgradeableProxy.sol\":\"TransparentUpgradeableProxy\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":1000000},\"remappings\":[]},\"sources\":{\"@openzeppelin/contracts/interfaces/draft-IERC1822.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.5.0) (interfaces/draft-IERC1822.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev ERC1822: Universal Upgradeable Proxy Standard (UUPS) documents a method for upgradeability through a simplified\\n * proxy whose upgrades are fully controlled by the current implementation.\\n */\\ninterface IERC1822Proxiable {\\n /**\\n * @dev Returns the storage slot that the proxiable contract assumes is being used to store the implementation\\n * address.\\n *\\n * IMPORTANT: A proxy pointing at a proxiable contract should not be considered proxiable itself, because this risks\\n * bricking a proxy that upgrades to it, by delegating to itself until out of gas. Thus it is critical that this\\n * function revert if invoked through a proxy.\\n */\\n function proxiableUUID() external view returns (bytes32);\\n}\\n\",\"keccak256\":\"0x1d4afe6cb24200cc4545eed814ecf5847277dfe5d613a1707aad5fceecebcfff\",\"license\":\"MIT\"},\"@openzeppelin/contracts/proxy/ERC1967/ERC1967Proxy.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.7.0) (proxy/ERC1967/ERC1967Proxy.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../Proxy.sol\\\";\\nimport \\\"./ERC1967Upgrade.sol\\\";\\n\\n/**\\n * @dev This contract implements an upgradeable proxy. It is upgradeable because calls are delegated to an\\n * implementation address that can be changed. This address is stored in storage in the location specified by\\n * https://eips.ethereum.org/EIPS/eip-1967[EIP1967], so that it doesn't conflict with the storage layout of the\\n * implementation behind the proxy.\\n */\\ncontract ERC1967Proxy is Proxy, ERC1967Upgrade {\\n /**\\n * @dev Initializes the upgradeable proxy with an initial implementation specified by `_logic`.\\n *\\n * If `_data` is nonempty, it's used as data in a delegate call to `_logic`. This will typically be an encoded\\n * function call, and allows initializing the storage of the proxy like a Solidity constructor.\\n */\\n constructor(address _logic, bytes memory _data) payable {\\n _upgradeToAndCall(_logic, _data, false);\\n }\\n\\n /**\\n * @dev Returns the current implementation address.\\n */\\n function _implementation() internal view virtual override returns (address impl) {\\n return ERC1967Upgrade._getImplementation();\\n }\\n}\\n\",\"keccak256\":\"0xa2b22da3032e50b55f95ec1d13336102d675f341167aa76db571ef7f8bb7975d\",\"license\":\"MIT\"},\"@openzeppelin/contracts/proxy/ERC1967/ERC1967Upgrade.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.5.0) (proxy/ERC1967/ERC1967Upgrade.sol)\\n\\npragma solidity ^0.8.2;\\n\\nimport \\\"../beacon/IBeacon.sol\\\";\\nimport \\\"../../interfaces/draft-IERC1822.sol\\\";\\nimport \\\"../../utils/Address.sol\\\";\\nimport \\\"../../utils/StorageSlot.sol\\\";\\n\\n/**\\n * @dev This abstract contract provides getters and event emitting update functions for\\n * https://eips.ethereum.org/EIPS/eip-1967[EIP1967] slots.\\n *\\n * _Available since v4.1._\\n *\\n * @custom:oz-upgrades-unsafe-allow delegatecall\\n */\\nabstract contract ERC1967Upgrade {\\n // This is the keccak-256 hash of \\\"eip1967.proxy.rollback\\\" subtracted by 1\\n bytes32 private constant _ROLLBACK_SLOT = 0x4910fdfa16fed3260ed0e7147f7cc6da11a60208b5b9406d12a635614ffd9143;\\n\\n /**\\n * @dev Storage slot with the address of the current implementation.\\n * This is the keccak-256 hash of \\\"eip1967.proxy.implementation\\\" subtracted by 1, and is\\n * validated in the constructor.\\n */\\n bytes32 internal constant _IMPLEMENTATION_SLOT = 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc;\\n\\n /**\\n * @dev Emitted when the implementation is upgraded.\\n */\\n event Upgraded(address indexed implementation);\\n\\n /**\\n * @dev Returns the current implementation address.\\n */\\n function _getImplementation() internal view returns (address) {\\n return StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value;\\n }\\n\\n /**\\n * @dev Stores a new address in the EIP1967 implementation slot.\\n */\\n function _setImplementation(address newImplementation) private {\\n require(Address.isContract(newImplementation), \\\"ERC1967: new implementation is not a contract\\\");\\n StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value = newImplementation;\\n }\\n\\n /**\\n * @dev Perform implementation upgrade\\n *\\n * Emits an {Upgraded} event.\\n */\\n function _upgradeTo(address newImplementation) internal {\\n _setImplementation(newImplementation);\\n emit Upgraded(newImplementation);\\n }\\n\\n /**\\n * @dev Perform implementation upgrade with additional setup call.\\n *\\n * Emits an {Upgraded} event.\\n */\\n function _upgradeToAndCall(\\n address newImplementation,\\n bytes memory data,\\n bool forceCall\\n ) internal {\\n _upgradeTo(newImplementation);\\n if (data.length > 0 || forceCall) {\\n Address.functionDelegateCall(newImplementation, data);\\n }\\n }\\n\\n /**\\n * @dev Perform implementation upgrade with security checks for UUPS proxies, and additional setup call.\\n *\\n * Emits an {Upgraded} event.\\n */\\n function _upgradeToAndCallUUPS(\\n address newImplementation,\\n bytes memory data,\\n bool forceCall\\n ) internal {\\n // Upgrades from old implementations will perform a rollback test. This test requires the new\\n // implementation to upgrade back to the old, non-ERC1822 compliant, implementation. Removing\\n // this special case will break upgrade paths from old UUPS implementation to new ones.\\n if (StorageSlot.getBooleanSlot(_ROLLBACK_SLOT).value) {\\n _setImplementation(newImplementation);\\n } else {\\n try IERC1822Proxiable(newImplementation).proxiableUUID() returns (bytes32 slot) {\\n require(slot == _IMPLEMENTATION_SLOT, \\\"ERC1967Upgrade: unsupported proxiableUUID\\\");\\n } catch {\\n revert(\\\"ERC1967Upgrade: new implementation is not UUPS\\\");\\n }\\n _upgradeToAndCall(newImplementation, data, forceCall);\\n }\\n }\\n\\n /**\\n * @dev Storage slot with the admin of the contract.\\n * This is the keccak-256 hash of \\\"eip1967.proxy.admin\\\" subtracted by 1, and is\\n * validated in the constructor.\\n */\\n bytes32 internal constant _ADMIN_SLOT = 0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103;\\n\\n /**\\n * @dev Emitted when the admin account has changed.\\n */\\n event AdminChanged(address previousAdmin, address newAdmin);\\n\\n /**\\n * @dev Returns the current admin.\\n */\\n function _getAdmin() internal view returns (address) {\\n return StorageSlot.getAddressSlot(_ADMIN_SLOT).value;\\n }\\n\\n /**\\n * @dev Stores a new address in the EIP1967 admin slot.\\n */\\n function _setAdmin(address newAdmin) private {\\n require(newAdmin != address(0), \\\"ERC1967: new admin is the zero address\\\");\\n StorageSlot.getAddressSlot(_ADMIN_SLOT).value = newAdmin;\\n }\\n\\n /**\\n * @dev Changes the admin of the proxy.\\n *\\n * Emits an {AdminChanged} event.\\n */\\n function _changeAdmin(address newAdmin) internal {\\n emit AdminChanged(_getAdmin(), newAdmin);\\n _setAdmin(newAdmin);\\n }\\n\\n /**\\n * @dev The storage slot of the UpgradeableBeacon contract which defines the implementation for this proxy.\\n * This is bytes32(uint256(keccak256('eip1967.proxy.beacon')) - 1)) and is validated in the constructor.\\n */\\n bytes32 internal constant _BEACON_SLOT = 0xa3f0ad74e5423aebfd80d3ef4346578335a9a72aeaee59ff6cb3582b35133d50;\\n\\n /**\\n * @dev Emitted when the beacon is upgraded.\\n */\\n event BeaconUpgraded(address indexed beacon);\\n\\n /**\\n * @dev Returns the current beacon.\\n */\\n function _getBeacon() internal view returns (address) {\\n return StorageSlot.getAddressSlot(_BEACON_SLOT).value;\\n }\\n\\n /**\\n * @dev Stores a new beacon in the EIP1967 beacon slot.\\n */\\n function _setBeacon(address newBeacon) private {\\n require(Address.isContract(newBeacon), \\\"ERC1967: new beacon is not a contract\\\");\\n require(\\n Address.isContract(IBeacon(newBeacon).implementation()),\\n \\\"ERC1967: beacon implementation is not a contract\\\"\\n );\\n StorageSlot.getAddressSlot(_BEACON_SLOT).value = newBeacon;\\n }\\n\\n /**\\n * @dev Perform beacon upgrade with additional setup call. Note: This upgrades the address of the beacon, it does\\n * not upgrade the implementation contained in the beacon (see {UpgradeableBeacon-_setImplementation} for that).\\n *\\n * Emits a {BeaconUpgraded} event.\\n */\\n function _upgradeBeaconToAndCall(\\n address newBeacon,\\n bytes memory data,\\n bool forceCall\\n ) internal {\\n _setBeacon(newBeacon);\\n emit BeaconUpgraded(newBeacon);\\n if (data.length > 0 || forceCall) {\\n Address.functionDelegateCall(IBeacon(newBeacon).implementation(), data);\\n }\\n }\\n}\\n\",\"keccak256\":\"0xabf3f59bc0e5423eae45e459dbe92e7052c6983628d39008590edc852a62f94a\",\"license\":\"MIT\"},\"@openzeppelin/contracts/proxy/Proxy.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.6.0) (proxy/Proxy.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev This abstract contract provides a fallback function that delegates all calls to another contract using the EVM\\n * instruction `delegatecall`. We refer to the second contract as the _implementation_ behind the proxy, and it has to\\n * be specified by overriding the virtual {_implementation} function.\\n *\\n * Additionally, delegation to the implementation can be triggered manually through the {_fallback} function, or to a\\n * different contract through the {_delegate} function.\\n *\\n * The success and return data of the delegated call will be returned back to the caller of the proxy.\\n */\\nabstract contract Proxy {\\n /**\\n * @dev Delegates the current call to `implementation`.\\n *\\n * This function does not return to its internal call site, it will return directly to the external caller.\\n */\\n function _delegate(address implementation) internal virtual {\\n assembly {\\n // Copy msg.data. We take full control of memory in this inline assembly\\n // block because it will not return to Solidity code. We overwrite the\\n // Solidity scratch pad at memory position 0.\\n calldatacopy(0, 0, calldatasize())\\n\\n // Call the implementation.\\n // out and outsize are 0 because we don't know the size yet.\\n let result := delegatecall(gas(), implementation, 0, calldatasize(), 0, 0)\\n\\n // Copy the returned data.\\n returndatacopy(0, 0, returndatasize())\\n\\n switch result\\n // delegatecall returns 0 on error.\\n case 0 {\\n revert(0, returndatasize())\\n }\\n default {\\n return(0, returndatasize())\\n }\\n }\\n }\\n\\n /**\\n * @dev This is a virtual function that should be overridden so it returns the address to which the fallback function\\n * and {_fallback} should delegate.\\n */\\n function _implementation() internal view virtual returns (address);\\n\\n /**\\n * @dev Delegates the current call to the address returned by `_implementation()`.\\n *\\n * This function does not return to its internal call site, it will return directly to the external caller.\\n */\\n function _fallback() internal virtual {\\n _beforeFallback();\\n _delegate(_implementation());\\n }\\n\\n /**\\n * @dev Fallback function that delegates calls to the address returned by `_implementation()`. Will run if no other\\n * function in the contract matches the call data.\\n */\\n fallback() external payable virtual {\\n _fallback();\\n }\\n\\n /**\\n * @dev Fallback function that delegates calls to the address returned by `_implementation()`. Will run if call data\\n * is empty.\\n */\\n receive() external payable virtual {\\n _fallback();\\n }\\n\\n /**\\n * @dev Hook that is called before falling back to the implementation. Can happen as part of a manual `_fallback`\\n * call, or as part of the Solidity `fallback` or `receive` functions.\\n *\\n * If overridden should call `super._beforeFallback()`.\\n */\\n function _beforeFallback() internal virtual {}\\n}\\n\",\"keccak256\":\"0xc130fe33f1b2132158531a87734153293f6d07bc263ff4ac90e85da9c82c0e27\",\"license\":\"MIT\"},\"@openzeppelin/contracts/proxy/beacon/IBeacon.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (proxy/beacon/IBeacon.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev This is the interface that {BeaconProxy} expects of its beacon.\\n */\\ninterface IBeacon {\\n /**\\n * @dev Must return an address that can be used as a delegate call target.\\n *\\n * {BeaconProxy} will check that this address is a contract.\\n */\\n function implementation() external view returns (address);\\n}\\n\",\"keccak256\":\"0xd50a3421ac379ccb1be435fa646d66a65c986b4924f0849839f08692f39dde61\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/Address.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.7.0) (utils/Address.sol)\\n\\npragma solidity ^0.8.1;\\n\\n/**\\n * @dev Collection of functions related to the address type\\n */\\nlibrary Address {\\n /**\\n * @dev Returns true if `account` is a contract.\\n *\\n * [IMPORTANT]\\n * ====\\n * It is unsafe to assume that an address for which this function returns\\n * false is an externally-owned account (EOA) and not a contract.\\n *\\n * Among others, `isContract` will return false for the following\\n * types of addresses:\\n *\\n * - an externally-owned account\\n * - a contract in construction\\n * - an address where a contract will be created\\n * - an address where a contract lived, but was destroyed\\n * ====\\n *\\n * [IMPORTANT]\\n * ====\\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\\n *\\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\\n * constructor.\\n * ====\\n */\\n function isContract(address account) internal view returns (bool) {\\n // This method relies on extcodesize/address.code.length, which returns 0\\n // for contracts in construction, since the code is only stored at the end\\n // of the constructor execution.\\n\\n return account.code.length > 0;\\n }\\n\\n /**\\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\\n * `recipient`, forwarding all available gas and reverting on errors.\\n *\\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\\n * imposed by `transfer`, making them unable to receive funds via\\n * `transfer`. {sendValue} removes this limitation.\\n *\\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\\n *\\n * IMPORTANT: because control is transferred to `recipient`, care must be\\n * taken to not create reentrancy vulnerabilities. Consider using\\n * {ReentrancyGuard} or the\\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\\n */\\n function sendValue(address payable recipient, uint256 amount) internal {\\n require(address(this).balance >= amount, \\\"Address: insufficient balance\\\");\\n\\n (bool success, ) = recipient.call{value: amount}(\\\"\\\");\\n require(success, \\\"Address: unable to send value, recipient may have reverted\\\");\\n }\\n\\n /**\\n * @dev Performs a Solidity function call using a low level `call`. A\\n * plain `call` is an unsafe replacement for a function call: use this\\n * function instead.\\n *\\n * If `target` reverts with a revert reason, it is bubbled up by this\\n * function (like regular Solidity function calls).\\n *\\n * Returns the raw returned data. To convert to the expected return value,\\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\\n *\\n * Requirements:\\n *\\n * - `target` must be a contract.\\n * - calling `target` with `data` must not revert.\\n *\\n * _Available since v3.1._\\n */\\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\\n return functionCall(target, data, \\\"Address: low-level call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\\n * `errorMessage` as a fallback revert reason when `target` reverts.\\n *\\n * _Available since v3.1._\\n */\\n function functionCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n return functionCallWithValue(target, data, 0, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but also transferring `value` wei to `target`.\\n *\\n * Requirements:\\n *\\n * - the calling contract must have an ETH balance of at least `value`.\\n * - the called Solidity function must be `payable`.\\n *\\n * _Available since v3.1._\\n */\\n function functionCallWithValue(\\n address target,\\n bytes memory data,\\n uint256 value\\n ) internal returns (bytes memory) {\\n return functionCallWithValue(target, data, value, \\\"Address: low-level call with value failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\\n * with `errorMessage` as a fallback revert reason when `target` reverts.\\n *\\n * _Available since v3.1._\\n */\\n function functionCallWithValue(\\n address target,\\n bytes memory data,\\n uint256 value,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n require(address(this).balance >= value, \\\"Address: insufficient balance for call\\\");\\n require(isContract(target), \\\"Address: call to non-contract\\\");\\n\\n (bool success, bytes memory returndata) = target.call{value: value}(data);\\n return verifyCallResult(success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but performing a static call.\\n *\\n * _Available since v3.3._\\n */\\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\\n return functionStaticCall(target, data, \\\"Address: low-level static call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\\n * but performing a static call.\\n *\\n * _Available since v3.3._\\n */\\n function functionStaticCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal view returns (bytes memory) {\\n require(isContract(target), \\\"Address: static call to non-contract\\\");\\n\\n (bool success, bytes memory returndata) = target.staticcall(data);\\n return verifyCallResult(success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but performing a delegate call.\\n *\\n * _Available since v3.4._\\n */\\n function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {\\n return functionDelegateCall(target, data, \\\"Address: low-level delegate call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\\n * but performing a delegate call.\\n *\\n * _Available since v3.4._\\n */\\n function functionDelegateCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n require(isContract(target), \\\"Address: delegate call to non-contract\\\");\\n\\n (bool success, bytes memory returndata) = target.delegatecall(data);\\n return verifyCallResult(success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the\\n * revert reason using the provided one.\\n *\\n * _Available since v4.3._\\n */\\n function verifyCallResult(\\n bool success,\\n bytes memory returndata,\\n string memory errorMessage\\n ) internal pure returns (bytes memory) {\\n if (success) {\\n return returndata;\\n } else {\\n // Look for revert reason and bubble it up if present\\n if (returndata.length > 0) {\\n // The easiest way to bubble the revert reason is using memory via assembly\\n /// @solidity memory-safe-assembly\\n assembly {\\n let returndata_size := mload(returndata)\\n revert(add(32, returndata), returndata_size)\\n }\\n } else {\\n revert(errorMessage);\\n }\\n }\\n }\\n}\\n\",\"keccak256\":\"0xd6153ce99bcdcce22b124f755e72553295be6abcd63804cfdffceb188b8bef10\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/StorageSlot.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.7.0) (utils/StorageSlot.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Library for reading and writing primitive types to specific storage slots.\\n *\\n * Storage slots are often used to avoid storage conflict when dealing with upgradeable contracts.\\n * This library helps with reading and writing to such slots without the need for inline assembly.\\n *\\n * The functions in this library return Slot structs that contain a `value` member that can be used to read or write.\\n *\\n * Example usage to set ERC1967 implementation slot:\\n * ```\\n * contract ERC1967 {\\n * bytes32 internal constant _IMPLEMENTATION_SLOT = 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc;\\n *\\n * function _getImplementation() internal view returns (address) {\\n * return StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value;\\n * }\\n *\\n * function _setImplementation(address newImplementation) internal {\\n * require(Address.isContract(newImplementation), \\\"ERC1967: new implementation is not a contract\\\");\\n * StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value = newImplementation;\\n * }\\n * }\\n * ```\\n *\\n * _Available since v4.1 for `address`, `bool`, `bytes32`, and `uint256`._\\n */\\nlibrary StorageSlot {\\n struct AddressSlot {\\n address value;\\n }\\n\\n struct BooleanSlot {\\n bool value;\\n }\\n\\n struct Bytes32Slot {\\n bytes32 value;\\n }\\n\\n struct Uint256Slot {\\n uint256 value;\\n }\\n\\n /**\\n * @dev Returns an `AddressSlot` with member `value` located at `slot`.\\n */\\n function getAddressSlot(bytes32 slot) internal pure returns (AddressSlot storage r) {\\n /// @solidity memory-safe-assembly\\n assembly {\\n r.slot := slot\\n }\\n }\\n\\n /**\\n * @dev Returns an `BooleanSlot` with member `value` located at `slot`.\\n */\\n function getBooleanSlot(bytes32 slot) internal pure returns (BooleanSlot storage r) {\\n /// @solidity memory-safe-assembly\\n assembly {\\n r.slot := slot\\n }\\n }\\n\\n /**\\n * @dev Returns an `Bytes32Slot` with member `value` located at `slot`.\\n */\\n function getBytes32Slot(bytes32 slot) internal pure returns (Bytes32Slot storage r) {\\n /// @solidity memory-safe-assembly\\n assembly {\\n r.slot := slot\\n }\\n }\\n\\n /**\\n * @dev Returns an `Uint256Slot` with member `value` located at `slot`.\\n */\\n function getUint256Slot(bytes32 slot) internal pure returns (Uint256Slot storage r) {\\n /// @solidity memory-safe-assembly\\n assembly {\\n r.slot := slot\\n }\\n }\\n}\\n\",\"keccak256\":\"0xd5c50c54bf02740ebd122ff06832546cb5fa84486d52695a9ccfd11666e0c81d\",\"license\":\"MIT\"},\"contracts/external/TransparentUpgradeableProxy.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-3.0\\n\\npragma solidity ^0.8.12;\\n\\nimport \\\"@openzeppelin/contracts/proxy/ERC1967/ERC1967Proxy.sol\\\";\\n\\n/**\\n * @dev This contract implements a proxy that is upgradeable by an admin. It is fully forked from OpenZeppelin\\n * `TransparentUpgradeableProxy`\\n *\\n * To avoid https://medium.com/nomic-labs-blog/malicious-backdoors-in-ethereum-proxies-62629adf3357[proxy selector\\n * clashing], which can potentially be used in an attack, this contract uses the\\n * https://blog.openzeppelin.com/the-transparent-proxy-pattern/[transparent proxy pattern]. This pattern implies two\\n * things that go hand in hand:\\n *\\n * 1. If any account other than the admin calls the proxy, the call will be forwarded to the implementation, even if\\n * that call matches one of the admin functions exposed by the proxy itself.\\n * 2. If the admin calls the proxy, it can access the admin functions, but its calls will never be forwarded to the\\n * implementation. If the admin tries to call a function on the implementation it will fail with an error that says\\n * \\\"admin cannot fallback to proxy target\\\".\\n *\\n * These properties mean that the admin account can only be used for admin actions like upgrading the proxy or changing\\n * the admin, so it's best if it's a dedicated account that is not used for anything else. This will avoid headaches due\\n * to sudden errors when trying to call a function from the proxy implementation.\\n *\\n * Our recommendation is for the dedicated account to be an instance of the {ProxyAdmin} contract. If set up this way,\\n * you should think of the `ProxyAdmin` instance as the real administrative interface of your proxy.\\n */\\ncontract TransparentUpgradeableProxy is ERC1967Proxy {\\n /**\\n * @dev Initializes an upgradeable proxy managed by `_admin`, backed by the implementation at `_logic`, and\\n * optionally initialized with `_data` as explained in {ERC1967Proxy-constructor}.\\n */\\n constructor(address _logic, address admin_, bytes memory _data) payable ERC1967Proxy(_logic, _data) {\\n assert(_ADMIN_SLOT == bytes32(uint256(keccak256(\\\"eip1967.proxy.admin\\\")) - 1));\\n _changeAdmin(admin_);\\n }\\n\\n /**\\n * @dev Modifier used internally that will delegate the call to the implementation unless the sender is the admin.\\n */\\n modifier ifAdmin() {\\n if (msg.sender == _getAdmin()) {\\n _;\\n } else {\\n _fallback();\\n }\\n }\\n\\n /**\\n * @dev Returns the current admin.\\n *\\n * NOTE: Only the admin can call this function. See {ProxyAdmin-getProxyAdmin}.\\n *\\n * TIP: To get this value clients can read directly from the storage slot shown below (specified by EIP1967) using the\\n * https://eth.wiki/json-rpc/API#eth_getstorageat[`eth_getStorageAt`] RPC call.\\n * `0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103`\\n */\\n function admin() external ifAdmin returns (address admin_) {\\n admin_ = _getAdmin();\\n }\\n\\n /**\\n * @dev Returns the current implementation.\\n *\\n * NOTE: Only the admin can call this function. See {ProxyAdmin-getProxyImplementation}.\\n *\\n * TIP: To get this value clients can read directly from the storage slot shown below (specified by EIP1967) using the\\n * https://eth.wiki/json-rpc/API#eth_getstorageat[`eth_getStorageAt`] RPC call.\\n * `0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc`\\n */\\n function implementation() external ifAdmin returns (address implementation_) {\\n implementation_ = _implementation();\\n }\\n\\n /**\\n * @dev Changes the admin of the proxy.\\n *\\n * Emits an {AdminChanged} event.\\n *\\n * NOTE: Only the admin can call this function. See {ProxyAdmin-changeProxyAdmin}.\\n */\\n function changeAdmin(address newAdmin) external virtual ifAdmin {\\n _changeAdmin(newAdmin);\\n }\\n\\n /**\\n * @dev Upgrade the implementation of the proxy.\\n *\\n * NOTE: Only the admin can call this function. See {ProxyAdmin-upgrade}.\\n */\\n function upgradeTo(address newImplementation) external ifAdmin {\\n _upgradeToAndCall(newImplementation, bytes(\\\"\\\"), false);\\n }\\n\\n /**\\n * @dev Upgrade the implementation of the proxy, and then call a function from the new implementation as specified\\n * by `data`, which should be an encoded function call. This is useful to initialize new storage variables in the\\n * proxied contract.\\n *\\n * NOTE: Only the admin can call this function. See {ProxyAdmin-upgradeAndCall}.\\n */\\n function upgradeToAndCall(address newImplementation, bytes calldata data) external payable ifAdmin {\\n _upgradeToAndCall(newImplementation, data, true);\\n }\\n\\n /**\\n * @dev Returns the current admin.\\n */\\n function _admin() internal view virtual returns (address) {\\n return _getAdmin();\\n }\\n\\n /**\\n * @dev Makes sure the admin cannot access the fallback function. See {Proxy-_beforeFallback}.\\n */\\n function _beforeFallback() internal virtual override {\\n require(msg.sender != _getAdmin(), \\\"TransparentUpgradeableProxy: admin cannot fallback to proxy target\\\");\\n super._beforeFallback();\\n }\\n}\\n\",\"keccak256\":\"0x93a67a0f612ea3ff2a76315e138a6a88267270a1379d3cc7be52845fbbe611e2\",\"license\":\"GPL-3.0\"}},\"version\":1}", + "bytecode": "0x6080604052604051620010bb380380620010bb8339810160408190526200002691620004d8565b828162000036828260006200009a565b5062000066905060017fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6104620005b8565b6000805160206200107483398151915214620000865762000086620005da565b6200009182620000d7565b50505062000643565b620000a58362000132565b600082511180620000b35750805b15620000d257620000d083836200017460201b6200028c1760201c565b505b505050565b7f7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f62000102620001a5565b604080516001600160a01b03928316815291841660208301520160405180910390a16200012f81620001de565b50565b6200013d8162000293565b6040516001600160a01b038216907fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b90600090a250565b60606200019c8383604051806060016040528060278152602001620010946027913962000347565b90505b92915050565b6000620001cf6000805160206200107483398151915260001b6200042f60201b6200022e1760201c565b546001600160a01b0316919050565b6001600160a01b038116620002495760405162461bcd60e51b815260206004820152602660248201527f455243313936373a206e65772061646d696e20697320746865207a65726f206160448201526564647265737360d01b60648201526084015b60405180910390fd5b80620002726000805160206200107483398151915260001b6200042f60201b6200022e1760201c565b80546001600160a01b0319166001600160a01b039290921691909117905550565b620002a9816200043260201b620002b81760201c565b6200030d5760405162461bcd60e51b815260206004820152602d60248201527f455243313936373a206e657720696d706c656d656e746174696f6e206973206e60448201526c1bdd08184818dbdb9d1c9858dd609a1b606482015260840162000240565b80620002727f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc60001b6200042f60201b6200022e1760201c565b60606001600160a01b0384163b620003b15760405162461bcd60e51b815260206004820152602660248201527f416464726573733a2064656c65676174652063616c6c20746f206e6f6e2d636f6044820152651b9d1c9858dd60d21b606482015260840162000240565b600080856001600160a01b031685604051620003ce9190620005f0565b600060405180830381855af49150503d80600081146200040b576040519150601f19603f3d011682016040523d82523d6000602084013e62000410565b606091505b5090925090506200042382828662000441565b925050505b9392505050565b90565b6001600160a01b03163b151590565b606083156200045257508162000428565b825115620004635782518084602001fd5b8160405162461bcd60e51b81526004016200024091906200060e565b80516001600160a01b03811681146200049757600080fd5b919050565b634e487b7160e01b600052604160045260246000fd5b60005b83811015620004cf578181015183820152602001620004b5565b50506000910152565b600080600060608486031215620004ee57600080fd5b620004f9846200047f565b925062000509602085016200047f565b60408501519092506001600160401b03808211156200052757600080fd5b818601915086601f8301126200053c57600080fd5b8151818111156200055157620005516200049c565b604051601f8201601f19908116603f011681019083821181831017156200057c576200057c6200049c565b816040528281528960208487010111156200059657600080fd5b620005a9836020830160208801620004b2565b80955050505050509250925092565b818103818111156200019f57634e487b7160e01b600052601160045260246000fd5b634e487b7160e01b600052600160045260246000fd5b6000825162000604818460208701620004b2565b9190910192915050565b60208152600082518060208401526200062f816040850160208701620004b2565b601f01601f19169190910160400192915050565b610a2180620006536000396000f3fe60806040526004361061005e5760003560e01c80635c60da1b116100435780635c60da1b146100a85780638f283970146100e6578063f851a440146101065761006d565b80633659cfe6146100755780634f1ef286146100955761006d565b3661006d5761006b61011b565b005b61006b61011b565b34801561008157600080fd5b5061006b610090366004610895565b610135565b61006b6100a33660046108b0565b61017f565b3480156100b457600080fd5b506100bd6101f3565b60405173ffffffffffffffffffffffffffffffffffffffff909116815260200160405180910390f35b3480156100f257600080fd5b5061006b610101366004610895565b610231565b34801561011257600080fd5b506100bd61025e565b6101236102d4565b61013361012e6103ab565b6103b5565b565b61013d6103d9565b73ffffffffffffffffffffffffffffffffffffffff1633036101775761017481604051806020016040528060008152506000610419565b50565b61017461011b565b6101876103d9565b73ffffffffffffffffffffffffffffffffffffffff1633036101eb576101e68383838080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525060019250610419915050565b505050565b6101e661011b565b60006101fd6103d9565b73ffffffffffffffffffffffffffffffffffffffff163303610226576102216103ab565b905090565b61022e61011b565b90565b6102396103d9565b73ffffffffffffffffffffffffffffffffffffffff1633036101775761017481610444565b60006102686103d9565b73ffffffffffffffffffffffffffffffffffffffff163303610226576102216103d9565b60606102b183836040518060600160405280602781526020016109c5602791396104a5565b9392505050565b73ffffffffffffffffffffffffffffffffffffffff163b151590565b6102dc6103d9565b73ffffffffffffffffffffffffffffffffffffffff163303610133576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604260248201527f5472616e73706172656e745570677261646561626c6550726f78793a2061646d60448201527f696e2063616e6e6f742066616c6c6261636b20746f2070726f7879207461726760648201527f6574000000000000000000000000000000000000000000000000000000000000608482015260a4015b60405180910390fd5b60006102216105cd565b3660008037600080366000845af43d6000803e8080156103d4573d6000f35b3d6000fd5b60007fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035b5473ffffffffffffffffffffffffffffffffffffffff16919050565b610422836105f5565b60008251118061042f5750805b156101e65761043e838361028c565b50505050565b7f7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f61046d6103d9565b6040805173ffffffffffffffffffffffffffffffffffffffff928316815291841660208301520160405180910390a161017481610642565b606073ffffffffffffffffffffffffffffffffffffffff84163b61054b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f416464726573733a2064656c65676174652063616c6c20746f206e6f6e2d636f60448201527f6e7472616374000000000000000000000000000000000000000000000000000060648201526084016103a2565b6000808573ffffffffffffffffffffffffffffffffffffffff16856040516105739190610957565b600060405180830381855af49150503d80600081146105ae576040519150601f19603f3d011682016040523d82523d6000602084013e6105b3565b606091505b50915091506105c382828661074e565b9695505050505050565b60007f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc6103fd565b6105fe816107a1565b60405173ffffffffffffffffffffffffffffffffffffffff8216907fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b90600090a250565b73ffffffffffffffffffffffffffffffffffffffff81166106e5576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f455243313936373a206e65772061646d696e20697320746865207a65726f206160448201527f646472657373000000000000000000000000000000000000000000000000000060648201526084016103a2565b807fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035b80547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff9290921691909117905550565b6060831561075d5750816102b1565b82511561076d5782518084602001fd5b816040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016103a29190610973565b73ffffffffffffffffffffffffffffffffffffffff81163b610845576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602d60248201527f455243313936373a206e657720696d706c656d656e746174696f6e206973206e60448201527f6f74206120636f6e74726163740000000000000000000000000000000000000060648201526084016103a2565b807f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc610708565b803573ffffffffffffffffffffffffffffffffffffffff8116811461089057600080fd5b919050565b6000602082840312156108a757600080fd5b6102b18261086c565b6000806000604084860312156108c557600080fd5b6108ce8461086c565b9250602084013567ffffffffffffffff808211156108eb57600080fd5b818601915086601f8301126108ff57600080fd5b81358181111561090e57600080fd5b87602082850101111561092057600080fd5b6020830194508093505050509250925092565b60005b8381101561094e578181015183820152602001610936565b50506000910152565b60008251610969818460208701610933565b9190910192915050565b6020815260008251806020840152610992816040850160208701610933565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016919091016040019291505056fe416464726573733a206c6f772d6c6576656c2064656c65676174652063616c6c206661696c6564a2646970667358221220e96638b07fb1675d93a95c49e417bc8111448b23a59918698cdcd8fd488dd7cf64736f6c63430008110033b53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103416464726573733a206c6f772d6c6576656c2064656c65676174652063616c6c206661696c6564", + "deployedBytecode": "0x60806040526004361061005e5760003560e01c80635c60da1b116100435780635c60da1b146100a85780638f283970146100e6578063f851a440146101065761006d565b80633659cfe6146100755780634f1ef286146100955761006d565b3661006d5761006b61011b565b005b61006b61011b565b34801561008157600080fd5b5061006b610090366004610895565b610135565b61006b6100a33660046108b0565b61017f565b3480156100b457600080fd5b506100bd6101f3565b60405173ffffffffffffffffffffffffffffffffffffffff909116815260200160405180910390f35b3480156100f257600080fd5b5061006b610101366004610895565b610231565b34801561011257600080fd5b506100bd61025e565b6101236102d4565b61013361012e6103ab565b6103b5565b565b61013d6103d9565b73ffffffffffffffffffffffffffffffffffffffff1633036101775761017481604051806020016040528060008152506000610419565b50565b61017461011b565b6101876103d9565b73ffffffffffffffffffffffffffffffffffffffff1633036101eb576101e68383838080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525060019250610419915050565b505050565b6101e661011b565b60006101fd6103d9565b73ffffffffffffffffffffffffffffffffffffffff163303610226576102216103ab565b905090565b61022e61011b565b90565b6102396103d9565b73ffffffffffffffffffffffffffffffffffffffff1633036101775761017481610444565b60006102686103d9565b73ffffffffffffffffffffffffffffffffffffffff163303610226576102216103d9565b60606102b183836040518060600160405280602781526020016109c5602791396104a5565b9392505050565b73ffffffffffffffffffffffffffffffffffffffff163b151590565b6102dc6103d9565b73ffffffffffffffffffffffffffffffffffffffff163303610133576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604260248201527f5472616e73706172656e745570677261646561626c6550726f78793a2061646d60448201527f696e2063616e6e6f742066616c6c6261636b20746f2070726f7879207461726760648201527f6574000000000000000000000000000000000000000000000000000000000000608482015260a4015b60405180910390fd5b60006102216105cd565b3660008037600080366000845af43d6000803e8080156103d4573d6000f35b3d6000fd5b60007fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035b5473ffffffffffffffffffffffffffffffffffffffff16919050565b610422836105f5565b60008251118061042f5750805b156101e65761043e838361028c565b50505050565b7f7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f61046d6103d9565b6040805173ffffffffffffffffffffffffffffffffffffffff928316815291841660208301520160405180910390a161017481610642565b606073ffffffffffffffffffffffffffffffffffffffff84163b61054b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f416464726573733a2064656c65676174652063616c6c20746f206e6f6e2d636f60448201527f6e7472616374000000000000000000000000000000000000000000000000000060648201526084016103a2565b6000808573ffffffffffffffffffffffffffffffffffffffff16856040516105739190610957565b600060405180830381855af49150503d80600081146105ae576040519150601f19603f3d011682016040523d82523d6000602084013e6105b3565b606091505b50915091506105c382828661074e565b9695505050505050565b60007f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc6103fd565b6105fe816107a1565b60405173ffffffffffffffffffffffffffffffffffffffff8216907fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b90600090a250565b73ffffffffffffffffffffffffffffffffffffffff81166106e5576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f455243313936373a206e65772061646d696e20697320746865207a65726f206160448201527f646472657373000000000000000000000000000000000000000000000000000060648201526084016103a2565b807fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035b80547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff9290921691909117905550565b6060831561075d5750816102b1565b82511561076d5782518084602001fd5b816040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016103a29190610973565b73ffffffffffffffffffffffffffffffffffffffff81163b610845576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602d60248201527f455243313936373a206e657720696d706c656d656e746174696f6e206973206e60448201527f6f74206120636f6e74726163740000000000000000000000000000000000000060648201526084016103a2565b807f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc610708565b803573ffffffffffffffffffffffffffffffffffffffff8116811461089057600080fd5b919050565b6000602082840312156108a757600080fd5b6102b18261086c565b6000806000604084860312156108c557600080fd5b6108ce8461086c565b9250602084013567ffffffffffffffff808211156108eb57600080fd5b818601915086601f8301126108ff57600080fd5b81358181111561090e57600080fd5b87602082850101111561092057600080fd5b6020830194508093505050509250925092565b60005b8381101561094e578181015183820152602001610936565b50506000910152565b60008251610969818460208701610933565b9190910192915050565b6020815260008251806020840152610992816040850160208701610933565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016919091016040019291505056fe416464726573733a206c6f772d6c6576656c2064656c65676174652063616c6c206661696c6564a2646970667358221220e96638b07fb1675d93a95c49e417bc8111448b23a59918698cdcd8fd488dd7cf64736f6c63430008110033", + "devdoc": { + "details": "This contract implements a proxy that is upgradeable by an admin. It is fully forked from OpenZeppelin `TransparentUpgradeableProxy` To avoid https://medium.com/nomic-labs-blog/malicious-backdoors-in-ethereum-proxies-62629adf3357[proxy selector clashing], which can potentially be used in an attack, this contract uses the https://blog.openzeppelin.com/the-transparent-proxy-pattern/[transparent proxy pattern]. This pattern implies two things that go hand in hand: 1. If any account other than the admin calls the proxy, the call will be forwarded to the implementation, even if that call matches one of the admin functions exposed by the proxy itself. 2. If the admin calls the proxy, it can access the admin functions, but its calls will never be forwarded to the implementation. If the admin tries to call a function on the implementation it will fail with an error that says \"admin cannot fallback to proxy target\". These properties mean that the admin account can only be used for admin actions like upgrading the proxy or changing the admin, so it's best if it's a dedicated account that is not used for anything else. This will avoid headaches due to sudden errors when trying to call a function from the proxy implementation. Our recommendation is for the dedicated account to be an instance of the {ProxyAdmin} contract. If set up this way, you should think of the `ProxyAdmin` instance as the real administrative interface of your proxy.", + "kind": "dev", + "methods": { + "admin()": { + "details": "Returns the current admin. NOTE: Only the admin can call this function. See {ProxyAdmin-getProxyAdmin}. TIP: To get this value clients can read directly from the storage slot shown below (specified by EIP1967) using the https://eth.wiki/json-rpc/API#eth_getstorageat[`eth_getStorageAt`] RPC call. `0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103`" + }, + "changeAdmin(address)": { + "details": "Changes the admin of the proxy. Emits an {AdminChanged} event. NOTE: Only the admin can call this function. See {ProxyAdmin-changeProxyAdmin}." + }, + "constructor": { + "details": "Initializes an upgradeable proxy managed by `_admin`, backed by the implementation at `_logic`, and optionally initialized with `_data` as explained in {ERC1967Proxy-constructor}." + }, + "implementation()": { + "details": "Returns the current implementation. NOTE: Only the admin can call this function. See {ProxyAdmin-getProxyImplementation}. TIP: To get this value clients can read directly from the storage slot shown below (specified by EIP1967) using the https://eth.wiki/json-rpc/API#eth_getstorageat[`eth_getStorageAt`] RPC call. `0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc`" + }, + "upgradeTo(address)": { + "details": "Upgrade the implementation of the proxy. NOTE: Only the admin can call this function. See {ProxyAdmin-upgrade}." + }, + "upgradeToAndCall(address,bytes)": { + "details": "Upgrade the implementation of the proxy, and then call a function from the new implementation as specified by `data`, which should be an encoded function call. This is useful to initialize new storage variables in the proxied contract. NOTE: Only the admin can call this function. See {ProxyAdmin-upgradeAndCall}." + } + }, + "version": 1 + }, + "userdoc": { + "kind": "user", + "methods": {}, + "version": 1 + }, + "storageLayout": { + "storage": [], + "types": null + } +} \ No newline at end of file diff --git a/deployments/base/LayerZeroBridge_USD.json b/deployments/base/LayerZeroBridge_USD.json new file mode 100644 index 00000000..92439336 --- /dev/null +++ b/deployments/base/LayerZeroBridge_USD.json @@ -0,0 +1,275 @@ +{ + "address": "0x1A42a30dCbA20A22b69C40098d89cB7304f429B9", + "abi": [ + { + "inputs": [ + { + "internalType": "address", + "name": "_logic", + "type": "address" + }, + { + "internalType": "address", + "name": "admin_", + "type": "address" + }, + { + "internalType": "bytes", + "name": "_data", + "type": "bytes" + } + ], + "stateMutability": "payable", + "type": "constructor" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "previousAdmin", + "type": "address" + }, + { + "indexed": false, + "internalType": "address", + "name": "newAdmin", + "type": "address" + } + ], + "name": "AdminChanged", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "beacon", + "type": "address" + } + ], + "name": "BeaconUpgraded", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "implementation", + "type": "address" + } + ], + "name": "Upgraded", + "type": "event" + }, + { + "stateMutability": "payable", + "type": "fallback" + }, + { + "inputs": [], + "name": "admin", + "outputs": [ + { + "internalType": "address", + "name": "admin_", + "type": "address" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "newAdmin", + "type": "address" + } + ], + "name": "changeAdmin", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "implementation", + "outputs": [ + { + "internalType": "address", + "name": "implementation_", + "type": "address" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "newImplementation", + "type": "address" + } + ], + "name": "upgradeTo", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "newImplementation", + "type": "address" + }, + { + "internalType": "bytes", + "name": "data", + "type": "bytes" + } + ], + "name": "upgradeToAndCall", + "outputs": [], + "stateMutability": "payable", + "type": "function" + }, + { + "stateMutability": "payable", + "type": "receive" + } + ], + "transactionHash": "0xd26ab0bf877baa4560b4b7b182edf97da997cefb7879a03d2327ee492a509242", + "receipt": { + "to": null, + "from": "0xfdA462548Ce04282f4B6D6619823a7C64Fdc0185", + "contractAddress": "0x1A42a30dCbA20A22b69C40098d89cB7304f429B9", + "transactionIndex": 2, + "gasUsed": "849908", + "logsBloom": "0x00000000000000000000000000000000400000000000000800000000000000000000000000000000000000000000000000000000000000000000000000200000000004000010000000000008000002000000000000000000000000000500000000000000020000000000000000000800000400804000000000020010000000000000000000000000000000000000000000000000000080000040000000800000020000000000000000000000000400000000000000000000000000000000000000000022000000000000010000240000000000000400000000000000000020000010000000000000000000000000000000080000000000000000000000000000", + "blockHash": "0xb92bcbb02ff2a360bfaa0dd066958645e3dbcd37fafb4e35e5e48e750f79cfa9", + "transactionHash": "0xd26ab0bf877baa4560b4b7b182edf97da997cefb7879a03d2327ee492a509242", + "logs": [ + { + "transactionIndex": 2, + "blockNumber": 9051442, + "transactionHash": "0xd26ab0bf877baa4560b4b7b182edf97da997cefb7879a03d2327ee492a509242", + "address": "0x1A42a30dCbA20A22b69C40098d89cB7304f429B9", + "topics": [ + "0xbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b", + "0x0000000000000000000000000d710512e100c171139d2cf5708f22c680eccf52" + ], + "data": "0x", + "logIndex": 2, + "blockHash": "0xb92bcbb02ff2a360bfaa0dd066958645e3dbcd37fafb4e35e5e48e750f79cfa9" + }, + { + "transactionIndex": 2, + "blockNumber": 9051442, + "transactionHash": "0xd26ab0bf877baa4560b4b7b182edf97da997cefb7879a03d2327ee492a509242", + "address": "0x1A42a30dCbA20A22b69C40098d89cB7304f429B9", + "topics": [ + "0x8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925", + "0x0000000000000000000000001a42a30dcba20a22b69c40098d89cb7304f429b9", + "0x0000000000000000000000000000206329b97db379d5e1bf586bbdb969c63274" + ], + "data": "0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", + "logIndex": 3, + "blockHash": "0xb92bcbb02ff2a360bfaa0dd066958645e3dbcd37fafb4e35e5e48e750f79cfa9" + }, + { + "transactionIndex": 2, + "blockNumber": 9051442, + "transactionHash": "0xd26ab0bf877baa4560b4b7b182edf97da997cefb7879a03d2327ee492a509242", + "address": "0x1A42a30dCbA20A22b69C40098d89cB7304f429B9", + "topics": [ + "0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000206329b97db379d5e1bf586bbdb969c63274" + ], + "data": "0x0000000000000000000000000000000000000000000000000000000000000000", + "logIndex": 4, + "blockHash": "0xb92bcbb02ff2a360bfaa0dd066958645e3dbcd37fafb4e35e5e48e750f79cfa9" + }, + { + "transactionIndex": 2, + "blockNumber": 9051442, + "transactionHash": "0xd26ab0bf877baa4560b4b7b182edf97da997cefb7879a03d2327ee492a509242", + "address": "0x1A42a30dCbA20A22b69C40098d89cB7304f429B9", + "topics": [ + "0x7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb3847402498" + ], + "data": "0x0000000000000000000000000000000000000000000000000000000000000001", + "logIndex": 5, + "blockHash": "0xb92bcbb02ff2a360bfaa0dd066958645e3dbcd37fafb4e35e5e48e750f79cfa9" + }, + { + "transactionIndex": 2, + "blockNumber": 9051442, + "transactionHash": "0xd26ab0bf877baa4560b4b7b182edf97da997cefb7879a03d2327ee492a509242", + "address": "0x1A42a30dCbA20A22b69C40098d89cB7304f429B9", + "topics": [ + "0x7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f" + ], + "data": "0x000000000000000000000000000000000000000000000000000000000000000000000000000000000000000031429d1856ad1377a8a0079410b297e1a9e214c2", + "logIndex": 6, + "blockHash": "0xb92bcbb02ff2a360bfaa0dd066958645e3dbcd37fafb4e35e5e48e750f79cfa9" + } + ], + "blockNumber": 9051442, + "cumulativeGasUsed": "1652317", + "status": 1, + "byzantium": true + }, + "args": [ + "0x0D710512E100C171139D2Cf5708f22C680eccF52", + "0x31429d1856aD1377A8A0079410B297e1a9e214c2", + "0xc9aba0aa00000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000000e0000000000000000000000000b6319cc6c8c27a8f5daf0dd3df91ea35c4720dd7000000000000000000000000dd6a0a00fe3353e813f3b3864694d55d2a7ce11c000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000164c617965725a65726f204272696467652061675553440000000000000000000000000000000000000000000000000000000000000000000000000000000000084c5a2d6167555344000000000000000000000000000000000000000000000000" + ], + "numDeployments": 1, + "solcInputHash": "871924e0c138825a2736b76def8fef8d", + "metadata": "{\"compiler\":{\"version\":\"0.8.17+commit.8df45f5f\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_logic\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"admin_\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"_data\",\"type\":\"bytes\"}],\"stateMutability\":\"payable\",\"type\":\"constructor\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"previousAdmin\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"newAdmin\",\"type\":\"address\"}],\"name\":\"AdminChanged\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"beacon\",\"type\":\"address\"}],\"name\":\"BeaconUpgraded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"implementation\",\"type\":\"address\"}],\"name\":\"Upgraded\",\"type\":\"event\"},{\"stateMutability\":\"payable\",\"type\":\"fallback\"},{\"inputs\":[],\"name\":\"admin\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"admin_\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newAdmin\",\"type\":\"address\"}],\"name\":\"changeAdmin\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"implementation\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"implementation_\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newImplementation\",\"type\":\"address\"}],\"name\":\"upgradeTo\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newImplementation\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"}],\"name\":\"upgradeToAndCall\",\"outputs\":[],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"stateMutability\":\"payable\",\"type\":\"receive\"}],\"devdoc\":{\"details\":\"This contract implements a proxy that is upgradeable by an admin. It is fully forked from OpenZeppelin `TransparentUpgradeableProxy` To avoid https://medium.com/nomic-labs-blog/malicious-backdoors-in-ethereum-proxies-62629adf3357[proxy selector clashing], which can potentially be used in an attack, this contract uses the https://blog.openzeppelin.com/the-transparent-proxy-pattern/[transparent proxy pattern]. This pattern implies two things that go hand in hand: 1. If any account other than the admin calls the proxy, the call will be forwarded to the implementation, even if that call matches one of the admin functions exposed by the proxy itself. 2. If the admin calls the proxy, it can access the admin functions, but its calls will never be forwarded to the implementation. If the admin tries to call a function on the implementation it will fail with an error that says \\\"admin cannot fallback to proxy target\\\". These properties mean that the admin account can only be used for admin actions like upgrading the proxy or changing the admin, so it's best if it's a dedicated account that is not used for anything else. This will avoid headaches due to sudden errors when trying to call a function from the proxy implementation. Our recommendation is for the dedicated account to be an instance of the {ProxyAdmin} contract. If set up this way, you should think of the `ProxyAdmin` instance as the real administrative interface of your proxy.\",\"kind\":\"dev\",\"methods\":{\"admin()\":{\"details\":\"Returns the current admin. NOTE: Only the admin can call this function. See {ProxyAdmin-getProxyAdmin}. TIP: To get this value clients can read directly from the storage slot shown below (specified by EIP1967) using the https://eth.wiki/json-rpc/API#eth_getstorageat[`eth_getStorageAt`] RPC call. `0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103`\"},\"changeAdmin(address)\":{\"details\":\"Changes the admin of the proxy. Emits an {AdminChanged} event. NOTE: Only the admin can call this function. See {ProxyAdmin-changeProxyAdmin}.\"},\"constructor\":{\"details\":\"Initializes an upgradeable proxy managed by `_admin`, backed by the implementation at `_logic`, and optionally initialized with `_data` as explained in {ERC1967Proxy-constructor}.\"},\"implementation()\":{\"details\":\"Returns the current implementation. NOTE: Only the admin can call this function. See {ProxyAdmin-getProxyImplementation}. TIP: To get this value clients can read directly from the storage slot shown below (specified by EIP1967) using the https://eth.wiki/json-rpc/API#eth_getstorageat[`eth_getStorageAt`] RPC call. `0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc`\"},\"upgradeTo(address)\":{\"details\":\"Upgrade the implementation of the proxy. NOTE: Only the admin can call this function. See {ProxyAdmin-upgrade}.\"},\"upgradeToAndCall(address,bytes)\":{\"details\":\"Upgrade the implementation of the proxy, and then call a function from the new implementation as specified by `data`, which should be an encoded function call. This is useful to initialize new storage variables in the proxied contract. NOTE: Only the admin can call this function. See {ProxyAdmin-upgradeAndCall}.\"}},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/external/TransparentUpgradeableProxy.sol\":\"TransparentUpgradeableProxy\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":1000000},\"remappings\":[]},\"sources\":{\"@openzeppelin/contracts/interfaces/draft-IERC1822.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.5.0) (interfaces/draft-IERC1822.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev ERC1822: Universal Upgradeable Proxy Standard (UUPS) documents a method for upgradeability through a simplified\\n * proxy whose upgrades are fully controlled by the current implementation.\\n */\\ninterface IERC1822Proxiable {\\n /**\\n * @dev Returns the storage slot that the proxiable contract assumes is being used to store the implementation\\n * address.\\n *\\n * IMPORTANT: A proxy pointing at a proxiable contract should not be considered proxiable itself, because this risks\\n * bricking a proxy that upgrades to it, by delegating to itself until out of gas. Thus it is critical that this\\n * function revert if invoked through a proxy.\\n */\\n function proxiableUUID() external view returns (bytes32);\\n}\\n\",\"keccak256\":\"0x1d4afe6cb24200cc4545eed814ecf5847277dfe5d613a1707aad5fceecebcfff\",\"license\":\"MIT\"},\"@openzeppelin/contracts/proxy/ERC1967/ERC1967Proxy.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.7.0) (proxy/ERC1967/ERC1967Proxy.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../Proxy.sol\\\";\\nimport \\\"./ERC1967Upgrade.sol\\\";\\n\\n/**\\n * @dev This contract implements an upgradeable proxy. It is upgradeable because calls are delegated to an\\n * implementation address that can be changed. This address is stored in storage in the location specified by\\n * https://eips.ethereum.org/EIPS/eip-1967[EIP1967], so that it doesn't conflict with the storage layout of the\\n * implementation behind the proxy.\\n */\\ncontract ERC1967Proxy is Proxy, ERC1967Upgrade {\\n /**\\n * @dev Initializes the upgradeable proxy with an initial implementation specified by `_logic`.\\n *\\n * If `_data` is nonempty, it's used as data in a delegate call to `_logic`. This will typically be an encoded\\n * function call, and allows initializing the storage of the proxy like a Solidity constructor.\\n */\\n constructor(address _logic, bytes memory _data) payable {\\n _upgradeToAndCall(_logic, _data, false);\\n }\\n\\n /**\\n * @dev Returns the current implementation address.\\n */\\n function _implementation() internal view virtual override returns (address impl) {\\n return ERC1967Upgrade._getImplementation();\\n }\\n}\\n\",\"keccak256\":\"0xa2b22da3032e50b55f95ec1d13336102d675f341167aa76db571ef7f8bb7975d\",\"license\":\"MIT\"},\"@openzeppelin/contracts/proxy/ERC1967/ERC1967Upgrade.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.5.0) (proxy/ERC1967/ERC1967Upgrade.sol)\\n\\npragma solidity ^0.8.2;\\n\\nimport \\\"../beacon/IBeacon.sol\\\";\\nimport \\\"../../interfaces/draft-IERC1822.sol\\\";\\nimport \\\"../../utils/Address.sol\\\";\\nimport \\\"../../utils/StorageSlot.sol\\\";\\n\\n/**\\n * @dev This abstract contract provides getters and event emitting update functions for\\n * https://eips.ethereum.org/EIPS/eip-1967[EIP1967] slots.\\n *\\n * _Available since v4.1._\\n *\\n * @custom:oz-upgrades-unsafe-allow delegatecall\\n */\\nabstract contract ERC1967Upgrade {\\n // This is the keccak-256 hash of \\\"eip1967.proxy.rollback\\\" subtracted by 1\\n bytes32 private constant _ROLLBACK_SLOT = 0x4910fdfa16fed3260ed0e7147f7cc6da11a60208b5b9406d12a635614ffd9143;\\n\\n /**\\n * @dev Storage slot with the address of the current implementation.\\n * This is the keccak-256 hash of \\\"eip1967.proxy.implementation\\\" subtracted by 1, and is\\n * validated in the constructor.\\n */\\n bytes32 internal constant _IMPLEMENTATION_SLOT = 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc;\\n\\n /**\\n * @dev Emitted when the implementation is upgraded.\\n */\\n event Upgraded(address indexed implementation);\\n\\n /**\\n * @dev Returns the current implementation address.\\n */\\n function _getImplementation() internal view returns (address) {\\n return StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value;\\n }\\n\\n /**\\n * @dev Stores a new address in the EIP1967 implementation slot.\\n */\\n function _setImplementation(address newImplementation) private {\\n require(Address.isContract(newImplementation), \\\"ERC1967: new implementation is not a contract\\\");\\n StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value = newImplementation;\\n }\\n\\n /**\\n * @dev Perform implementation upgrade\\n *\\n * Emits an {Upgraded} event.\\n */\\n function _upgradeTo(address newImplementation) internal {\\n _setImplementation(newImplementation);\\n emit Upgraded(newImplementation);\\n }\\n\\n /**\\n * @dev Perform implementation upgrade with additional setup call.\\n *\\n * Emits an {Upgraded} event.\\n */\\n function _upgradeToAndCall(\\n address newImplementation,\\n bytes memory data,\\n bool forceCall\\n ) internal {\\n _upgradeTo(newImplementation);\\n if (data.length > 0 || forceCall) {\\n Address.functionDelegateCall(newImplementation, data);\\n }\\n }\\n\\n /**\\n * @dev Perform implementation upgrade with security checks for UUPS proxies, and additional setup call.\\n *\\n * Emits an {Upgraded} event.\\n */\\n function _upgradeToAndCallUUPS(\\n address newImplementation,\\n bytes memory data,\\n bool forceCall\\n ) internal {\\n // Upgrades from old implementations will perform a rollback test. This test requires the new\\n // implementation to upgrade back to the old, non-ERC1822 compliant, implementation. Removing\\n // this special case will break upgrade paths from old UUPS implementation to new ones.\\n if (StorageSlot.getBooleanSlot(_ROLLBACK_SLOT).value) {\\n _setImplementation(newImplementation);\\n } else {\\n try IERC1822Proxiable(newImplementation).proxiableUUID() returns (bytes32 slot) {\\n require(slot == _IMPLEMENTATION_SLOT, \\\"ERC1967Upgrade: unsupported proxiableUUID\\\");\\n } catch {\\n revert(\\\"ERC1967Upgrade: new implementation is not UUPS\\\");\\n }\\n _upgradeToAndCall(newImplementation, data, forceCall);\\n }\\n }\\n\\n /**\\n * @dev Storage slot with the admin of the contract.\\n * This is the keccak-256 hash of \\\"eip1967.proxy.admin\\\" subtracted by 1, and is\\n * validated in the constructor.\\n */\\n bytes32 internal constant _ADMIN_SLOT = 0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103;\\n\\n /**\\n * @dev Emitted when the admin account has changed.\\n */\\n event AdminChanged(address previousAdmin, address newAdmin);\\n\\n /**\\n * @dev Returns the current admin.\\n */\\n function _getAdmin() internal view returns (address) {\\n return StorageSlot.getAddressSlot(_ADMIN_SLOT).value;\\n }\\n\\n /**\\n * @dev Stores a new address in the EIP1967 admin slot.\\n */\\n function _setAdmin(address newAdmin) private {\\n require(newAdmin != address(0), \\\"ERC1967: new admin is the zero address\\\");\\n StorageSlot.getAddressSlot(_ADMIN_SLOT).value = newAdmin;\\n }\\n\\n /**\\n * @dev Changes the admin of the proxy.\\n *\\n * Emits an {AdminChanged} event.\\n */\\n function _changeAdmin(address newAdmin) internal {\\n emit AdminChanged(_getAdmin(), newAdmin);\\n _setAdmin(newAdmin);\\n }\\n\\n /**\\n * @dev The storage slot of the UpgradeableBeacon contract which defines the implementation for this proxy.\\n * This is bytes32(uint256(keccak256('eip1967.proxy.beacon')) - 1)) and is validated in the constructor.\\n */\\n bytes32 internal constant _BEACON_SLOT = 0xa3f0ad74e5423aebfd80d3ef4346578335a9a72aeaee59ff6cb3582b35133d50;\\n\\n /**\\n * @dev Emitted when the beacon is upgraded.\\n */\\n event BeaconUpgraded(address indexed beacon);\\n\\n /**\\n * @dev Returns the current beacon.\\n */\\n function _getBeacon() internal view returns (address) {\\n return StorageSlot.getAddressSlot(_BEACON_SLOT).value;\\n }\\n\\n /**\\n * @dev Stores a new beacon in the EIP1967 beacon slot.\\n */\\n function _setBeacon(address newBeacon) private {\\n require(Address.isContract(newBeacon), \\\"ERC1967: new beacon is not a contract\\\");\\n require(\\n Address.isContract(IBeacon(newBeacon).implementation()),\\n \\\"ERC1967: beacon implementation is not a contract\\\"\\n );\\n StorageSlot.getAddressSlot(_BEACON_SLOT).value = newBeacon;\\n }\\n\\n /**\\n * @dev Perform beacon upgrade with additional setup call. Note: This upgrades the address of the beacon, it does\\n * not upgrade the implementation contained in the beacon (see {UpgradeableBeacon-_setImplementation} for that).\\n *\\n * Emits a {BeaconUpgraded} event.\\n */\\n function _upgradeBeaconToAndCall(\\n address newBeacon,\\n bytes memory data,\\n bool forceCall\\n ) internal {\\n _setBeacon(newBeacon);\\n emit BeaconUpgraded(newBeacon);\\n if (data.length > 0 || forceCall) {\\n Address.functionDelegateCall(IBeacon(newBeacon).implementation(), data);\\n }\\n }\\n}\\n\",\"keccak256\":\"0xabf3f59bc0e5423eae45e459dbe92e7052c6983628d39008590edc852a62f94a\",\"license\":\"MIT\"},\"@openzeppelin/contracts/proxy/Proxy.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.6.0) (proxy/Proxy.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev This abstract contract provides a fallback function that delegates all calls to another contract using the EVM\\n * instruction `delegatecall`. We refer to the second contract as the _implementation_ behind the proxy, and it has to\\n * be specified by overriding the virtual {_implementation} function.\\n *\\n * Additionally, delegation to the implementation can be triggered manually through the {_fallback} function, or to a\\n * different contract through the {_delegate} function.\\n *\\n * The success and return data of the delegated call will be returned back to the caller of the proxy.\\n */\\nabstract contract Proxy {\\n /**\\n * @dev Delegates the current call to `implementation`.\\n *\\n * This function does not return to its internal call site, it will return directly to the external caller.\\n */\\n function _delegate(address implementation) internal virtual {\\n assembly {\\n // Copy msg.data. We take full control of memory in this inline assembly\\n // block because it will not return to Solidity code. We overwrite the\\n // Solidity scratch pad at memory position 0.\\n calldatacopy(0, 0, calldatasize())\\n\\n // Call the implementation.\\n // out and outsize are 0 because we don't know the size yet.\\n let result := delegatecall(gas(), implementation, 0, calldatasize(), 0, 0)\\n\\n // Copy the returned data.\\n returndatacopy(0, 0, returndatasize())\\n\\n switch result\\n // delegatecall returns 0 on error.\\n case 0 {\\n revert(0, returndatasize())\\n }\\n default {\\n return(0, returndatasize())\\n }\\n }\\n }\\n\\n /**\\n * @dev This is a virtual function that should be overridden so it returns the address to which the fallback function\\n * and {_fallback} should delegate.\\n */\\n function _implementation() internal view virtual returns (address);\\n\\n /**\\n * @dev Delegates the current call to the address returned by `_implementation()`.\\n *\\n * This function does not return to its internal call site, it will return directly to the external caller.\\n */\\n function _fallback() internal virtual {\\n _beforeFallback();\\n _delegate(_implementation());\\n }\\n\\n /**\\n * @dev Fallback function that delegates calls to the address returned by `_implementation()`. Will run if no other\\n * function in the contract matches the call data.\\n */\\n fallback() external payable virtual {\\n _fallback();\\n }\\n\\n /**\\n * @dev Fallback function that delegates calls to the address returned by `_implementation()`. Will run if call data\\n * is empty.\\n */\\n receive() external payable virtual {\\n _fallback();\\n }\\n\\n /**\\n * @dev Hook that is called before falling back to the implementation. Can happen as part of a manual `_fallback`\\n * call, or as part of the Solidity `fallback` or `receive` functions.\\n *\\n * If overridden should call `super._beforeFallback()`.\\n */\\n function _beforeFallback() internal virtual {}\\n}\\n\",\"keccak256\":\"0xc130fe33f1b2132158531a87734153293f6d07bc263ff4ac90e85da9c82c0e27\",\"license\":\"MIT\"},\"@openzeppelin/contracts/proxy/beacon/IBeacon.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (proxy/beacon/IBeacon.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev This is the interface that {BeaconProxy} expects of its beacon.\\n */\\ninterface IBeacon {\\n /**\\n * @dev Must return an address that can be used as a delegate call target.\\n *\\n * {BeaconProxy} will check that this address is a contract.\\n */\\n function implementation() external view returns (address);\\n}\\n\",\"keccak256\":\"0xd50a3421ac379ccb1be435fa646d66a65c986b4924f0849839f08692f39dde61\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/Address.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.7.0) (utils/Address.sol)\\n\\npragma solidity ^0.8.1;\\n\\n/**\\n * @dev Collection of functions related to the address type\\n */\\nlibrary Address {\\n /**\\n * @dev Returns true if `account` is a contract.\\n *\\n * [IMPORTANT]\\n * ====\\n * It is unsafe to assume that an address for which this function returns\\n * false is an externally-owned account (EOA) and not a contract.\\n *\\n * Among others, `isContract` will return false for the following\\n * types of addresses:\\n *\\n * - an externally-owned account\\n * - a contract in construction\\n * - an address where a contract will be created\\n * - an address where a contract lived, but was destroyed\\n * ====\\n *\\n * [IMPORTANT]\\n * ====\\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\\n *\\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\\n * constructor.\\n * ====\\n */\\n function isContract(address account) internal view returns (bool) {\\n // This method relies on extcodesize/address.code.length, which returns 0\\n // for contracts in construction, since the code is only stored at the end\\n // of the constructor execution.\\n\\n return account.code.length > 0;\\n }\\n\\n /**\\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\\n * `recipient`, forwarding all available gas and reverting on errors.\\n *\\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\\n * imposed by `transfer`, making them unable to receive funds via\\n * `transfer`. {sendValue} removes this limitation.\\n *\\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\\n *\\n * IMPORTANT: because control is transferred to `recipient`, care must be\\n * taken to not create reentrancy vulnerabilities. Consider using\\n * {ReentrancyGuard} or the\\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\\n */\\n function sendValue(address payable recipient, uint256 amount) internal {\\n require(address(this).balance >= amount, \\\"Address: insufficient balance\\\");\\n\\n (bool success, ) = recipient.call{value: amount}(\\\"\\\");\\n require(success, \\\"Address: unable to send value, recipient may have reverted\\\");\\n }\\n\\n /**\\n * @dev Performs a Solidity function call using a low level `call`. A\\n * plain `call` is an unsafe replacement for a function call: use this\\n * function instead.\\n *\\n * If `target` reverts with a revert reason, it is bubbled up by this\\n * function (like regular Solidity function calls).\\n *\\n * Returns the raw returned data. To convert to the expected return value,\\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\\n *\\n * Requirements:\\n *\\n * - `target` must be a contract.\\n * - calling `target` with `data` must not revert.\\n *\\n * _Available since v3.1._\\n */\\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\\n return functionCall(target, data, \\\"Address: low-level call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\\n * `errorMessage` as a fallback revert reason when `target` reverts.\\n *\\n * _Available since v3.1._\\n */\\n function functionCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n return functionCallWithValue(target, data, 0, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but also transferring `value` wei to `target`.\\n *\\n * Requirements:\\n *\\n * - the calling contract must have an ETH balance of at least `value`.\\n * - the called Solidity function must be `payable`.\\n *\\n * _Available since v3.1._\\n */\\n function functionCallWithValue(\\n address target,\\n bytes memory data,\\n uint256 value\\n ) internal returns (bytes memory) {\\n return functionCallWithValue(target, data, value, \\\"Address: low-level call with value failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\\n * with `errorMessage` as a fallback revert reason when `target` reverts.\\n *\\n * _Available since v3.1._\\n */\\n function functionCallWithValue(\\n address target,\\n bytes memory data,\\n uint256 value,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n require(address(this).balance >= value, \\\"Address: insufficient balance for call\\\");\\n require(isContract(target), \\\"Address: call to non-contract\\\");\\n\\n (bool success, bytes memory returndata) = target.call{value: value}(data);\\n return verifyCallResult(success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but performing a static call.\\n *\\n * _Available since v3.3._\\n */\\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\\n return functionStaticCall(target, data, \\\"Address: low-level static call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\\n * but performing a static call.\\n *\\n * _Available since v3.3._\\n */\\n function functionStaticCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal view returns (bytes memory) {\\n require(isContract(target), \\\"Address: static call to non-contract\\\");\\n\\n (bool success, bytes memory returndata) = target.staticcall(data);\\n return verifyCallResult(success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but performing a delegate call.\\n *\\n * _Available since v3.4._\\n */\\n function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {\\n return functionDelegateCall(target, data, \\\"Address: low-level delegate call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\\n * but performing a delegate call.\\n *\\n * _Available since v3.4._\\n */\\n function functionDelegateCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n require(isContract(target), \\\"Address: delegate call to non-contract\\\");\\n\\n (bool success, bytes memory returndata) = target.delegatecall(data);\\n return verifyCallResult(success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the\\n * revert reason using the provided one.\\n *\\n * _Available since v4.3._\\n */\\n function verifyCallResult(\\n bool success,\\n bytes memory returndata,\\n string memory errorMessage\\n ) internal pure returns (bytes memory) {\\n if (success) {\\n return returndata;\\n } else {\\n // Look for revert reason and bubble it up if present\\n if (returndata.length > 0) {\\n // The easiest way to bubble the revert reason is using memory via assembly\\n /// @solidity memory-safe-assembly\\n assembly {\\n let returndata_size := mload(returndata)\\n revert(add(32, returndata), returndata_size)\\n }\\n } else {\\n revert(errorMessage);\\n }\\n }\\n }\\n}\\n\",\"keccak256\":\"0xd6153ce99bcdcce22b124f755e72553295be6abcd63804cfdffceb188b8bef10\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/StorageSlot.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.7.0) (utils/StorageSlot.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Library for reading and writing primitive types to specific storage slots.\\n *\\n * Storage slots are often used to avoid storage conflict when dealing with upgradeable contracts.\\n * This library helps with reading and writing to such slots without the need for inline assembly.\\n *\\n * The functions in this library return Slot structs that contain a `value` member that can be used to read or write.\\n *\\n * Example usage to set ERC1967 implementation slot:\\n * ```\\n * contract ERC1967 {\\n * bytes32 internal constant _IMPLEMENTATION_SLOT = 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc;\\n *\\n * function _getImplementation() internal view returns (address) {\\n * return StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value;\\n * }\\n *\\n * function _setImplementation(address newImplementation) internal {\\n * require(Address.isContract(newImplementation), \\\"ERC1967: new implementation is not a contract\\\");\\n * StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value = newImplementation;\\n * }\\n * }\\n * ```\\n *\\n * _Available since v4.1 for `address`, `bool`, `bytes32`, and `uint256`._\\n */\\nlibrary StorageSlot {\\n struct AddressSlot {\\n address value;\\n }\\n\\n struct BooleanSlot {\\n bool value;\\n }\\n\\n struct Bytes32Slot {\\n bytes32 value;\\n }\\n\\n struct Uint256Slot {\\n uint256 value;\\n }\\n\\n /**\\n * @dev Returns an `AddressSlot` with member `value` located at `slot`.\\n */\\n function getAddressSlot(bytes32 slot) internal pure returns (AddressSlot storage r) {\\n /// @solidity memory-safe-assembly\\n assembly {\\n r.slot := slot\\n }\\n }\\n\\n /**\\n * @dev Returns an `BooleanSlot` with member `value` located at `slot`.\\n */\\n function getBooleanSlot(bytes32 slot) internal pure returns (BooleanSlot storage r) {\\n /// @solidity memory-safe-assembly\\n assembly {\\n r.slot := slot\\n }\\n }\\n\\n /**\\n * @dev Returns an `Bytes32Slot` with member `value` located at `slot`.\\n */\\n function getBytes32Slot(bytes32 slot) internal pure returns (Bytes32Slot storage r) {\\n /// @solidity memory-safe-assembly\\n assembly {\\n r.slot := slot\\n }\\n }\\n\\n /**\\n * @dev Returns an `Uint256Slot` with member `value` located at `slot`.\\n */\\n function getUint256Slot(bytes32 slot) internal pure returns (Uint256Slot storage r) {\\n /// @solidity memory-safe-assembly\\n assembly {\\n r.slot := slot\\n }\\n }\\n}\\n\",\"keccak256\":\"0xd5c50c54bf02740ebd122ff06832546cb5fa84486d52695a9ccfd11666e0c81d\",\"license\":\"MIT\"},\"contracts/external/TransparentUpgradeableProxy.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-3.0\\n\\npragma solidity ^0.8.12;\\n\\nimport \\\"@openzeppelin/contracts/proxy/ERC1967/ERC1967Proxy.sol\\\";\\n\\n/**\\n * @dev This contract implements a proxy that is upgradeable by an admin. It is fully forked from OpenZeppelin\\n * `TransparentUpgradeableProxy`\\n *\\n * To avoid https://medium.com/nomic-labs-blog/malicious-backdoors-in-ethereum-proxies-62629adf3357[proxy selector\\n * clashing], which can potentially be used in an attack, this contract uses the\\n * https://blog.openzeppelin.com/the-transparent-proxy-pattern/[transparent proxy pattern]. This pattern implies two\\n * things that go hand in hand:\\n *\\n * 1. If any account other than the admin calls the proxy, the call will be forwarded to the implementation, even if\\n * that call matches one of the admin functions exposed by the proxy itself.\\n * 2. If the admin calls the proxy, it can access the admin functions, but its calls will never be forwarded to the\\n * implementation. If the admin tries to call a function on the implementation it will fail with an error that says\\n * \\\"admin cannot fallback to proxy target\\\".\\n *\\n * These properties mean that the admin account can only be used for admin actions like upgrading the proxy or changing\\n * the admin, so it's best if it's a dedicated account that is not used for anything else. This will avoid headaches due\\n * to sudden errors when trying to call a function from the proxy implementation.\\n *\\n * Our recommendation is for the dedicated account to be an instance of the {ProxyAdmin} contract. If set up this way,\\n * you should think of the `ProxyAdmin` instance as the real administrative interface of your proxy.\\n */\\ncontract TransparentUpgradeableProxy is ERC1967Proxy {\\n /**\\n * @dev Initializes an upgradeable proxy managed by `_admin`, backed by the implementation at `_logic`, and\\n * optionally initialized with `_data` as explained in {ERC1967Proxy-constructor}.\\n */\\n constructor(address _logic, address admin_, bytes memory _data) payable ERC1967Proxy(_logic, _data) {\\n assert(_ADMIN_SLOT == bytes32(uint256(keccak256(\\\"eip1967.proxy.admin\\\")) - 1));\\n _changeAdmin(admin_);\\n }\\n\\n /**\\n * @dev Modifier used internally that will delegate the call to the implementation unless the sender is the admin.\\n */\\n modifier ifAdmin() {\\n if (msg.sender == _getAdmin()) {\\n _;\\n } else {\\n _fallback();\\n }\\n }\\n\\n /**\\n * @dev Returns the current admin.\\n *\\n * NOTE: Only the admin can call this function. See {ProxyAdmin-getProxyAdmin}.\\n *\\n * TIP: To get this value clients can read directly from the storage slot shown below (specified by EIP1967) using the\\n * https://eth.wiki/json-rpc/API#eth_getstorageat[`eth_getStorageAt`] RPC call.\\n * `0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103`\\n */\\n function admin() external ifAdmin returns (address admin_) {\\n admin_ = _getAdmin();\\n }\\n\\n /**\\n * @dev Returns the current implementation.\\n *\\n * NOTE: Only the admin can call this function. See {ProxyAdmin-getProxyImplementation}.\\n *\\n * TIP: To get this value clients can read directly from the storage slot shown below (specified by EIP1967) using the\\n * https://eth.wiki/json-rpc/API#eth_getstorageat[`eth_getStorageAt`] RPC call.\\n * `0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc`\\n */\\n function implementation() external ifAdmin returns (address implementation_) {\\n implementation_ = _implementation();\\n }\\n\\n /**\\n * @dev Changes the admin of the proxy.\\n *\\n * Emits an {AdminChanged} event.\\n *\\n * NOTE: Only the admin can call this function. See {ProxyAdmin-changeProxyAdmin}.\\n */\\n function changeAdmin(address newAdmin) external virtual ifAdmin {\\n _changeAdmin(newAdmin);\\n }\\n\\n /**\\n * @dev Upgrade the implementation of the proxy.\\n *\\n * NOTE: Only the admin can call this function. See {ProxyAdmin-upgrade}.\\n */\\n function upgradeTo(address newImplementation) external ifAdmin {\\n _upgradeToAndCall(newImplementation, bytes(\\\"\\\"), false);\\n }\\n\\n /**\\n * @dev Upgrade the implementation of the proxy, and then call a function from the new implementation as specified\\n * by `data`, which should be an encoded function call. This is useful to initialize new storage variables in the\\n * proxied contract.\\n *\\n * NOTE: Only the admin can call this function. See {ProxyAdmin-upgradeAndCall}.\\n */\\n function upgradeToAndCall(address newImplementation, bytes calldata data) external payable ifAdmin {\\n _upgradeToAndCall(newImplementation, data, true);\\n }\\n\\n /**\\n * @dev Returns the current admin.\\n */\\n function _admin() internal view virtual returns (address) {\\n return _getAdmin();\\n }\\n\\n /**\\n * @dev Makes sure the admin cannot access the fallback function. See {Proxy-_beforeFallback}.\\n */\\n function _beforeFallback() internal virtual override {\\n require(msg.sender != _getAdmin(), \\\"TransparentUpgradeableProxy: admin cannot fallback to proxy target\\\");\\n super._beforeFallback();\\n }\\n}\\n\",\"keccak256\":\"0x93a67a0f612ea3ff2a76315e138a6a88267270a1379d3cc7be52845fbbe611e2\",\"license\":\"GPL-3.0\"}},\"version\":1}", + "bytecode": "0x6080604052604051620010bb380380620010bb8339810160408190526200002691620004d8565b828162000036828260006200009a565b5062000066905060017fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6104620005b8565b6000805160206200107483398151915214620000865762000086620005da565b6200009182620000d7565b50505062000643565b620000a58362000132565b600082511180620000b35750805b15620000d257620000d083836200017460201b6200028c1760201c565b505b505050565b7f7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f62000102620001a5565b604080516001600160a01b03928316815291841660208301520160405180910390a16200012f81620001de565b50565b6200013d8162000293565b6040516001600160a01b038216907fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b90600090a250565b60606200019c8383604051806060016040528060278152602001620010946027913962000347565b90505b92915050565b6000620001cf6000805160206200107483398151915260001b6200042f60201b6200022e1760201c565b546001600160a01b0316919050565b6001600160a01b038116620002495760405162461bcd60e51b815260206004820152602660248201527f455243313936373a206e65772061646d696e20697320746865207a65726f206160448201526564647265737360d01b60648201526084015b60405180910390fd5b80620002726000805160206200107483398151915260001b6200042f60201b6200022e1760201c565b80546001600160a01b0319166001600160a01b039290921691909117905550565b620002a9816200043260201b620002b81760201c565b6200030d5760405162461bcd60e51b815260206004820152602d60248201527f455243313936373a206e657720696d706c656d656e746174696f6e206973206e60448201526c1bdd08184818dbdb9d1c9858dd609a1b606482015260840162000240565b80620002727f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc60001b6200042f60201b6200022e1760201c565b60606001600160a01b0384163b620003b15760405162461bcd60e51b815260206004820152602660248201527f416464726573733a2064656c65676174652063616c6c20746f206e6f6e2d636f6044820152651b9d1c9858dd60d21b606482015260840162000240565b600080856001600160a01b031685604051620003ce9190620005f0565b600060405180830381855af49150503d80600081146200040b576040519150601f19603f3d011682016040523d82523d6000602084013e62000410565b606091505b5090925090506200042382828662000441565b925050505b9392505050565b90565b6001600160a01b03163b151590565b606083156200045257508162000428565b825115620004635782518084602001fd5b8160405162461bcd60e51b81526004016200024091906200060e565b80516001600160a01b03811681146200049757600080fd5b919050565b634e487b7160e01b600052604160045260246000fd5b60005b83811015620004cf578181015183820152602001620004b5565b50506000910152565b600080600060608486031215620004ee57600080fd5b620004f9846200047f565b925062000509602085016200047f565b60408501519092506001600160401b03808211156200052757600080fd5b818601915086601f8301126200053c57600080fd5b8151818111156200055157620005516200049c565b604051601f8201601f19908116603f011681019083821181831017156200057c576200057c6200049c565b816040528281528960208487010111156200059657600080fd5b620005a9836020830160208801620004b2565b80955050505050509250925092565b818103818111156200019f57634e487b7160e01b600052601160045260246000fd5b634e487b7160e01b600052600160045260246000fd5b6000825162000604818460208701620004b2565b9190910192915050565b60208152600082518060208401526200062f816040850160208701620004b2565b601f01601f19169190910160400192915050565b610a2180620006536000396000f3fe60806040526004361061005e5760003560e01c80635c60da1b116100435780635c60da1b146100a85780638f283970146100e6578063f851a440146101065761006d565b80633659cfe6146100755780634f1ef286146100955761006d565b3661006d5761006b61011b565b005b61006b61011b565b34801561008157600080fd5b5061006b610090366004610895565b610135565b61006b6100a33660046108b0565b61017f565b3480156100b457600080fd5b506100bd6101f3565b60405173ffffffffffffffffffffffffffffffffffffffff909116815260200160405180910390f35b3480156100f257600080fd5b5061006b610101366004610895565b610231565b34801561011257600080fd5b506100bd61025e565b6101236102d4565b61013361012e6103ab565b6103b5565b565b61013d6103d9565b73ffffffffffffffffffffffffffffffffffffffff1633036101775761017481604051806020016040528060008152506000610419565b50565b61017461011b565b6101876103d9565b73ffffffffffffffffffffffffffffffffffffffff1633036101eb576101e68383838080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525060019250610419915050565b505050565b6101e661011b565b60006101fd6103d9565b73ffffffffffffffffffffffffffffffffffffffff163303610226576102216103ab565b905090565b61022e61011b565b90565b6102396103d9565b73ffffffffffffffffffffffffffffffffffffffff1633036101775761017481610444565b60006102686103d9565b73ffffffffffffffffffffffffffffffffffffffff163303610226576102216103d9565b60606102b183836040518060600160405280602781526020016109c5602791396104a5565b9392505050565b73ffffffffffffffffffffffffffffffffffffffff163b151590565b6102dc6103d9565b73ffffffffffffffffffffffffffffffffffffffff163303610133576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604260248201527f5472616e73706172656e745570677261646561626c6550726f78793a2061646d60448201527f696e2063616e6e6f742066616c6c6261636b20746f2070726f7879207461726760648201527f6574000000000000000000000000000000000000000000000000000000000000608482015260a4015b60405180910390fd5b60006102216105cd565b3660008037600080366000845af43d6000803e8080156103d4573d6000f35b3d6000fd5b60007fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035b5473ffffffffffffffffffffffffffffffffffffffff16919050565b610422836105f5565b60008251118061042f5750805b156101e65761043e838361028c565b50505050565b7f7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f61046d6103d9565b6040805173ffffffffffffffffffffffffffffffffffffffff928316815291841660208301520160405180910390a161017481610642565b606073ffffffffffffffffffffffffffffffffffffffff84163b61054b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f416464726573733a2064656c65676174652063616c6c20746f206e6f6e2d636f60448201527f6e7472616374000000000000000000000000000000000000000000000000000060648201526084016103a2565b6000808573ffffffffffffffffffffffffffffffffffffffff16856040516105739190610957565b600060405180830381855af49150503d80600081146105ae576040519150601f19603f3d011682016040523d82523d6000602084013e6105b3565b606091505b50915091506105c382828661074e565b9695505050505050565b60007f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc6103fd565b6105fe816107a1565b60405173ffffffffffffffffffffffffffffffffffffffff8216907fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b90600090a250565b73ffffffffffffffffffffffffffffffffffffffff81166106e5576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f455243313936373a206e65772061646d696e20697320746865207a65726f206160448201527f646472657373000000000000000000000000000000000000000000000000000060648201526084016103a2565b807fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035b80547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff9290921691909117905550565b6060831561075d5750816102b1565b82511561076d5782518084602001fd5b816040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016103a29190610973565b73ffffffffffffffffffffffffffffffffffffffff81163b610845576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602d60248201527f455243313936373a206e657720696d706c656d656e746174696f6e206973206e60448201527f6f74206120636f6e74726163740000000000000000000000000000000000000060648201526084016103a2565b807f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc610708565b803573ffffffffffffffffffffffffffffffffffffffff8116811461089057600080fd5b919050565b6000602082840312156108a757600080fd5b6102b18261086c565b6000806000604084860312156108c557600080fd5b6108ce8461086c565b9250602084013567ffffffffffffffff808211156108eb57600080fd5b818601915086601f8301126108ff57600080fd5b81358181111561090e57600080fd5b87602082850101111561092057600080fd5b6020830194508093505050509250925092565b60005b8381101561094e578181015183820152602001610936565b50506000910152565b60008251610969818460208701610933565b9190910192915050565b6020815260008251806020840152610992816040850160208701610933565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016919091016040019291505056fe416464726573733a206c6f772d6c6576656c2064656c65676174652063616c6c206661696c6564a2646970667358221220e96638b07fb1675d93a95c49e417bc8111448b23a59918698cdcd8fd488dd7cf64736f6c63430008110033b53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103416464726573733a206c6f772d6c6576656c2064656c65676174652063616c6c206661696c6564", + "deployedBytecode": "0x60806040526004361061005e5760003560e01c80635c60da1b116100435780635c60da1b146100a85780638f283970146100e6578063f851a440146101065761006d565b80633659cfe6146100755780634f1ef286146100955761006d565b3661006d5761006b61011b565b005b61006b61011b565b34801561008157600080fd5b5061006b610090366004610895565b610135565b61006b6100a33660046108b0565b61017f565b3480156100b457600080fd5b506100bd6101f3565b60405173ffffffffffffffffffffffffffffffffffffffff909116815260200160405180910390f35b3480156100f257600080fd5b5061006b610101366004610895565b610231565b34801561011257600080fd5b506100bd61025e565b6101236102d4565b61013361012e6103ab565b6103b5565b565b61013d6103d9565b73ffffffffffffffffffffffffffffffffffffffff1633036101775761017481604051806020016040528060008152506000610419565b50565b61017461011b565b6101876103d9565b73ffffffffffffffffffffffffffffffffffffffff1633036101eb576101e68383838080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525060019250610419915050565b505050565b6101e661011b565b60006101fd6103d9565b73ffffffffffffffffffffffffffffffffffffffff163303610226576102216103ab565b905090565b61022e61011b565b90565b6102396103d9565b73ffffffffffffffffffffffffffffffffffffffff1633036101775761017481610444565b60006102686103d9565b73ffffffffffffffffffffffffffffffffffffffff163303610226576102216103d9565b60606102b183836040518060600160405280602781526020016109c5602791396104a5565b9392505050565b73ffffffffffffffffffffffffffffffffffffffff163b151590565b6102dc6103d9565b73ffffffffffffffffffffffffffffffffffffffff163303610133576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604260248201527f5472616e73706172656e745570677261646561626c6550726f78793a2061646d60448201527f696e2063616e6e6f742066616c6c6261636b20746f2070726f7879207461726760648201527f6574000000000000000000000000000000000000000000000000000000000000608482015260a4015b60405180910390fd5b60006102216105cd565b3660008037600080366000845af43d6000803e8080156103d4573d6000f35b3d6000fd5b60007fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035b5473ffffffffffffffffffffffffffffffffffffffff16919050565b610422836105f5565b60008251118061042f5750805b156101e65761043e838361028c565b50505050565b7f7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f61046d6103d9565b6040805173ffffffffffffffffffffffffffffffffffffffff928316815291841660208301520160405180910390a161017481610642565b606073ffffffffffffffffffffffffffffffffffffffff84163b61054b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f416464726573733a2064656c65676174652063616c6c20746f206e6f6e2d636f60448201527f6e7472616374000000000000000000000000000000000000000000000000000060648201526084016103a2565b6000808573ffffffffffffffffffffffffffffffffffffffff16856040516105739190610957565b600060405180830381855af49150503d80600081146105ae576040519150601f19603f3d011682016040523d82523d6000602084013e6105b3565b606091505b50915091506105c382828661074e565b9695505050505050565b60007f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc6103fd565b6105fe816107a1565b60405173ffffffffffffffffffffffffffffffffffffffff8216907fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b90600090a250565b73ffffffffffffffffffffffffffffffffffffffff81166106e5576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f455243313936373a206e65772061646d696e20697320746865207a65726f206160448201527f646472657373000000000000000000000000000000000000000000000000000060648201526084016103a2565b807fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035b80547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff9290921691909117905550565b6060831561075d5750816102b1565b82511561076d5782518084602001fd5b816040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016103a29190610973565b73ffffffffffffffffffffffffffffffffffffffff81163b610845576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602d60248201527f455243313936373a206e657720696d706c656d656e746174696f6e206973206e60448201527f6f74206120636f6e74726163740000000000000000000000000000000000000060648201526084016103a2565b807f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc610708565b803573ffffffffffffffffffffffffffffffffffffffff8116811461089057600080fd5b919050565b6000602082840312156108a757600080fd5b6102b18261086c565b6000806000604084860312156108c557600080fd5b6108ce8461086c565b9250602084013567ffffffffffffffff808211156108eb57600080fd5b818601915086601f8301126108ff57600080fd5b81358181111561090e57600080fd5b87602082850101111561092057600080fd5b6020830194508093505050509250925092565b60005b8381101561094e578181015183820152602001610936565b50506000910152565b60008251610969818460208701610933565b9190910192915050565b6020815260008251806020840152610992816040850160208701610933565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016919091016040019291505056fe416464726573733a206c6f772d6c6576656c2064656c65676174652063616c6c206661696c6564a2646970667358221220e96638b07fb1675d93a95c49e417bc8111448b23a59918698cdcd8fd488dd7cf64736f6c63430008110033", + "devdoc": { + "details": "This contract implements a proxy that is upgradeable by an admin. It is fully forked from OpenZeppelin `TransparentUpgradeableProxy` To avoid https://medium.com/nomic-labs-blog/malicious-backdoors-in-ethereum-proxies-62629adf3357[proxy selector clashing], which can potentially be used in an attack, this contract uses the https://blog.openzeppelin.com/the-transparent-proxy-pattern/[transparent proxy pattern]. This pattern implies two things that go hand in hand: 1. If any account other than the admin calls the proxy, the call will be forwarded to the implementation, even if that call matches one of the admin functions exposed by the proxy itself. 2. If the admin calls the proxy, it can access the admin functions, but its calls will never be forwarded to the implementation. If the admin tries to call a function on the implementation it will fail with an error that says \"admin cannot fallback to proxy target\". These properties mean that the admin account can only be used for admin actions like upgrading the proxy or changing the admin, so it's best if it's a dedicated account that is not used for anything else. This will avoid headaches due to sudden errors when trying to call a function from the proxy implementation. Our recommendation is for the dedicated account to be an instance of the {ProxyAdmin} contract. If set up this way, you should think of the `ProxyAdmin` instance as the real administrative interface of your proxy.", + "kind": "dev", + "methods": { + "admin()": { + "details": "Returns the current admin. NOTE: Only the admin can call this function. See {ProxyAdmin-getProxyAdmin}. TIP: To get this value clients can read directly from the storage slot shown below (specified by EIP1967) using the https://eth.wiki/json-rpc/API#eth_getstorageat[`eth_getStorageAt`] RPC call. `0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103`" + }, + "changeAdmin(address)": { + "details": "Changes the admin of the proxy. Emits an {AdminChanged} event. NOTE: Only the admin can call this function. See {ProxyAdmin-changeProxyAdmin}." + }, + "constructor": { + "details": "Initializes an upgradeable proxy managed by `_admin`, backed by the implementation at `_logic`, and optionally initialized with `_data` as explained in {ERC1967Proxy-constructor}." + }, + "implementation()": { + "details": "Returns the current implementation. NOTE: Only the admin can call this function. See {ProxyAdmin-getProxyImplementation}. TIP: To get this value clients can read directly from the storage slot shown below (specified by EIP1967) using the https://eth.wiki/json-rpc/API#eth_getstorageat[`eth_getStorageAt`] RPC call. `0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc`" + }, + "upgradeTo(address)": { + "details": "Upgrade the implementation of the proxy. NOTE: Only the admin can call this function. See {ProxyAdmin-upgrade}." + }, + "upgradeToAndCall(address,bytes)": { + "details": "Upgrade the implementation of the proxy, and then call a function from the new implementation as specified by `data`, which should be an encoded function call. This is useful to initialize new storage variables in the proxied contract. NOTE: Only the admin can call this function. See {ProxyAdmin-upgradeAndCall}." + } + }, + "version": 1 + }, + "userdoc": { + "kind": "user", + "methods": {}, + "version": 1 + }, + "storageLayout": { + "storage": [], + "types": null + } +} \ No newline at end of file diff --git a/deployments/base/LayerZeroBridge_USD_Old.json b/deployments/base/LayerZeroBridge_USD_Old.json new file mode 100644 index 00000000..6bf6c4e8 --- /dev/null +++ b/deployments/base/LayerZeroBridge_USD_Old.json @@ -0,0 +1,275 @@ +{ + "address": "0x6f5E42BE8d24255A376FffA8a3FFFAe8A77B8C6f", + "abi": [ + { + "inputs": [ + { + "internalType": "address", + "name": "_logic", + "type": "address" + }, + { + "internalType": "address", + "name": "admin_", + "type": "address" + }, + { + "internalType": "bytes", + "name": "_data", + "type": "bytes" + } + ], + "stateMutability": "payable", + "type": "constructor" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "previousAdmin", + "type": "address" + }, + { + "indexed": false, + "internalType": "address", + "name": "newAdmin", + "type": "address" + } + ], + "name": "AdminChanged", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "beacon", + "type": "address" + } + ], + "name": "BeaconUpgraded", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "implementation", + "type": "address" + } + ], + "name": "Upgraded", + "type": "event" + }, + { + "stateMutability": "payable", + "type": "fallback" + }, + { + "inputs": [], + "name": "admin", + "outputs": [ + { + "internalType": "address", + "name": "admin_", + "type": "address" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "newAdmin", + "type": "address" + } + ], + "name": "changeAdmin", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "implementation", + "outputs": [ + { + "internalType": "address", + "name": "implementation_", + "type": "address" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "newImplementation", + "type": "address" + } + ], + "name": "upgradeTo", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "newImplementation", + "type": "address" + }, + { + "internalType": "bytes", + "name": "data", + "type": "bytes" + } + ], + "name": "upgradeToAndCall", + "outputs": [], + "stateMutability": "payable", + "type": "function" + }, + { + "stateMutability": "payable", + "type": "receive" + } + ], + "transactionHash": "0x0afb18eef6b8084a61c1383e63048b27e23ece71ccfe8b43e06eeffd269583a7", + "receipt": { + "to": null, + "from": "0xfdA462548Ce04282f4B6D6619823a7C64Fdc0185", + "contractAddress": "0x6f5E42BE8d24255A376FffA8a3FFFAe8A77B8C6f", + "transactionIndex": 4, + "gasUsed": "849908", + "logsBloom": "0x00000000000002000000000000000000400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000200000000004000000000000000008000002000000000000000000000000000500000000000000020000000000000000000800000400800000000000020010000000000000000000000000000000000000000000000000000080000040000000800000020000000000000000000000000400000000000000000000000000000000000000800022000000000000000800040000000000000404000000000000000020000010010000000000000000000000000000000000000040000000000000000000", + "blockHash": "0x3f87b4e5ee71cce4114cab1f63fb8014fa522c3ec3eec9865862124e8f36526b", + "transactionHash": "0x0afb18eef6b8084a61c1383e63048b27e23ece71ccfe8b43e06eeffd269583a7", + "logs": [ + { + "transactionIndex": 4, + "blockNumber": 9043252, + "transactionHash": "0x0afb18eef6b8084a61c1383e63048b27e23ece71ccfe8b43e06eeffd269583a7", + "address": "0x6f5E42BE8d24255A376FffA8a3FFFAe8A77B8C6f", + "topics": [ + "0xbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b", + "0x0000000000000000000000000d710512e100c171139d2cf5708f22c680eccf52" + ], + "data": "0x", + "logIndex": 0, + "blockHash": "0x3f87b4e5ee71cce4114cab1f63fb8014fa522c3ec3eec9865862124e8f36526b" + }, + { + "transactionIndex": 4, + "blockNumber": 9043252, + "transactionHash": "0x0afb18eef6b8084a61c1383e63048b27e23ece71ccfe8b43e06eeffd269583a7", + "address": "0x6f5E42BE8d24255A376FffA8a3FFFAe8A77B8C6f", + "topics": [ + "0x8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925", + "0x0000000000000000000000006f5e42be8d24255a376fffa8a3fffae8a77b8c6f", + "0x0000000000000000000000000000206329b97db379d5e1bf586bbdb969c63274" + ], + "data": "0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", + "logIndex": 1, + "blockHash": "0x3f87b4e5ee71cce4114cab1f63fb8014fa522c3ec3eec9865862124e8f36526b" + }, + { + "transactionIndex": 4, + "blockNumber": 9043252, + "transactionHash": "0x0afb18eef6b8084a61c1383e63048b27e23ece71ccfe8b43e06eeffd269583a7", + "address": "0x6f5E42BE8d24255A376FffA8a3FFFAe8A77B8C6f", + "topics": [ + "0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000206329b97db379d5e1bf586bbdb969c63274" + ], + "data": "0x0000000000000000000000000000000000000000000000000000000000000000", + "logIndex": 2, + "blockHash": "0x3f87b4e5ee71cce4114cab1f63fb8014fa522c3ec3eec9865862124e8f36526b" + }, + { + "transactionIndex": 4, + "blockNumber": 9043252, + "transactionHash": "0x0afb18eef6b8084a61c1383e63048b27e23ece71ccfe8b43e06eeffd269583a7", + "address": "0x6f5E42BE8d24255A376FffA8a3FFFAe8A77B8C6f", + "topics": [ + "0x7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb3847402498" + ], + "data": "0x0000000000000000000000000000000000000000000000000000000000000001", + "logIndex": 3, + "blockHash": "0x3f87b4e5ee71cce4114cab1f63fb8014fa522c3ec3eec9865862124e8f36526b" + }, + { + "transactionIndex": 4, + "blockNumber": 9043252, + "transactionHash": "0x0afb18eef6b8084a61c1383e63048b27e23ece71ccfe8b43e06eeffd269583a7", + "address": "0x6f5E42BE8d24255A376FffA8a3FFFAe8A77B8C6f", + "topics": [ + "0x7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f" + ], + "data": "0x000000000000000000000000000000000000000000000000000000000000000000000000000000000000000031429d1856ad1377a8a0079410b297e1a9e214c2", + "logIndex": 4, + "blockHash": "0x3f87b4e5ee71cce4114cab1f63fb8014fa522c3ec3eec9865862124e8f36526b" + } + ], + "blockNumber": 9043252, + "cumulativeGasUsed": "961805", + "status": 1, + "byzantium": true + }, + "args": [ + "0x0D710512E100C171139D2Cf5708f22C680eccF52", + "0x31429d1856aD1377A8A0079410B297e1a9e214c2", + "0xc9aba0aa00000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000000e000000000000000000000000066a71dcef29a0ffbdbe3c6a460a3b5bc225cd675000000000000000000000000dd6a0a00fe3353e813f3b3864694d55d2a7ce11c000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000164c617965725a65726f204272696467652061675553440000000000000000000000000000000000000000000000000000000000000000000000000000000000084c5a2d6167555344000000000000000000000000000000000000000000000000" + ], + "numDeployments": 1, + "solcInputHash": "871924e0c138825a2736b76def8fef8d", + "metadata": "{\"compiler\":{\"version\":\"0.8.17+commit.8df45f5f\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_logic\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"admin_\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"_data\",\"type\":\"bytes\"}],\"stateMutability\":\"payable\",\"type\":\"constructor\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"previousAdmin\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"newAdmin\",\"type\":\"address\"}],\"name\":\"AdminChanged\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"beacon\",\"type\":\"address\"}],\"name\":\"BeaconUpgraded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"implementation\",\"type\":\"address\"}],\"name\":\"Upgraded\",\"type\":\"event\"},{\"stateMutability\":\"payable\",\"type\":\"fallback\"},{\"inputs\":[],\"name\":\"admin\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"admin_\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newAdmin\",\"type\":\"address\"}],\"name\":\"changeAdmin\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"implementation\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"implementation_\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newImplementation\",\"type\":\"address\"}],\"name\":\"upgradeTo\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newImplementation\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"}],\"name\":\"upgradeToAndCall\",\"outputs\":[],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"stateMutability\":\"payable\",\"type\":\"receive\"}],\"devdoc\":{\"details\":\"This contract implements a proxy that is upgradeable by an admin. It is fully forked from OpenZeppelin `TransparentUpgradeableProxy` To avoid https://medium.com/nomic-labs-blog/malicious-backdoors-in-ethereum-proxies-62629adf3357[proxy selector clashing], which can potentially be used in an attack, this contract uses the https://blog.openzeppelin.com/the-transparent-proxy-pattern/[transparent proxy pattern]. This pattern implies two things that go hand in hand: 1. If any account other than the admin calls the proxy, the call will be forwarded to the implementation, even if that call matches one of the admin functions exposed by the proxy itself. 2. If the admin calls the proxy, it can access the admin functions, but its calls will never be forwarded to the implementation. If the admin tries to call a function on the implementation it will fail with an error that says \\\"admin cannot fallback to proxy target\\\". These properties mean that the admin account can only be used for admin actions like upgrading the proxy or changing the admin, so it's best if it's a dedicated account that is not used for anything else. This will avoid headaches due to sudden errors when trying to call a function from the proxy implementation. Our recommendation is for the dedicated account to be an instance of the {ProxyAdmin} contract. If set up this way, you should think of the `ProxyAdmin` instance as the real administrative interface of your proxy.\",\"kind\":\"dev\",\"methods\":{\"admin()\":{\"details\":\"Returns the current admin. NOTE: Only the admin can call this function. See {ProxyAdmin-getProxyAdmin}. TIP: To get this value clients can read directly from the storage slot shown below (specified by EIP1967) using the https://eth.wiki/json-rpc/API#eth_getstorageat[`eth_getStorageAt`] RPC call. `0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103`\"},\"changeAdmin(address)\":{\"details\":\"Changes the admin of the proxy. Emits an {AdminChanged} event. NOTE: Only the admin can call this function. See {ProxyAdmin-changeProxyAdmin}.\"},\"constructor\":{\"details\":\"Initializes an upgradeable proxy managed by `_admin`, backed by the implementation at `_logic`, and optionally initialized with `_data` as explained in {ERC1967Proxy-constructor}.\"},\"implementation()\":{\"details\":\"Returns the current implementation. NOTE: Only the admin can call this function. See {ProxyAdmin-getProxyImplementation}. TIP: To get this value clients can read directly from the storage slot shown below (specified by EIP1967) using the https://eth.wiki/json-rpc/API#eth_getstorageat[`eth_getStorageAt`] RPC call. `0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc`\"},\"upgradeTo(address)\":{\"details\":\"Upgrade the implementation of the proxy. NOTE: Only the admin can call this function. See {ProxyAdmin-upgrade}.\"},\"upgradeToAndCall(address,bytes)\":{\"details\":\"Upgrade the implementation of the proxy, and then call a function from the new implementation as specified by `data`, which should be an encoded function call. This is useful to initialize new storage variables in the proxied contract. NOTE: Only the admin can call this function. See {ProxyAdmin-upgradeAndCall}.\"}},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/external/TransparentUpgradeableProxy.sol\":\"TransparentUpgradeableProxy\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":1000000},\"remappings\":[]},\"sources\":{\"@openzeppelin/contracts/interfaces/draft-IERC1822.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.5.0) (interfaces/draft-IERC1822.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev ERC1822: Universal Upgradeable Proxy Standard (UUPS) documents a method for upgradeability through a simplified\\n * proxy whose upgrades are fully controlled by the current implementation.\\n */\\ninterface IERC1822Proxiable {\\n /**\\n * @dev Returns the storage slot that the proxiable contract assumes is being used to store the implementation\\n * address.\\n *\\n * IMPORTANT: A proxy pointing at a proxiable contract should not be considered proxiable itself, because this risks\\n * bricking a proxy that upgrades to it, by delegating to itself until out of gas. Thus it is critical that this\\n * function revert if invoked through a proxy.\\n */\\n function proxiableUUID() external view returns (bytes32);\\n}\\n\",\"keccak256\":\"0x1d4afe6cb24200cc4545eed814ecf5847277dfe5d613a1707aad5fceecebcfff\",\"license\":\"MIT\"},\"@openzeppelin/contracts/proxy/ERC1967/ERC1967Proxy.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.7.0) (proxy/ERC1967/ERC1967Proxy.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../Proxy.sol\\\";\\nimport \\\"./ERC1967Upgrade.sol\\\";\\n\\n/**\\n * @dev This contract implements an upgradeable proxy. It is upgradeable because calls are delegated to an\\n * implementation address that can be changed. This address is stored in storage in the location specified by\\n * https://eips.ethereum.org/EIPS/eip-1967[EIP1967], so that it doesn't conflict with the storage layout of the\\n * implementation behind the proxy.\\n */\\ncontract ERC1967Proxy is Proxy, ERC1967Upgrade {\\n /**\\n * @dev Initializes the upgradeable proxy with an initial implementation specified by `_logic`.\\n *\\n * If `_data` is nonempty, it's used as data in a delegate call to `_logic`. This will typically be an encoded\\n * function call, and allows initializing the storage of the proxy like a Solidity constructor.\\n */\\n constructor(address _logic, bytes memory _data) payable {\\n _upgradeToAndCall(_logic, _data, false);\\n }\\n\\n /**\\n * @dev Returns the current implementation address.\\n */\\n function _implementation() internal view virtual override returns (address impl) {\\n return ERC1967Upgrade._getImplementation();\\n }\\n}\\n\",\"keccak256\":\"0xa2b22da3032e50b55f95ec1d13336102d675f341167aa76db571ef7f8bb7975d\",\"license\":\"MIT\"},\"@openzeppelin/contracts/proxy/ERC1967/ERC1967Upgrade.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.5.0) (proxy/ERC1967/ERC1967Upgrade.sol)\\n\\npragma solidity ^0.8.2;\\n\\nimport \\\"../beacon/IBeacon.sol\\\";\\nimport \\\"../../interfaces/draft-IERC1822.sol\\\";\\nimport \\\"../../utils/Address.sol\\\";\\nimport \\\"../../utils/StorageSlot.sol\\\";\\n\\n/**\\n * @dev This abstract contract provides getters and event emitting update functions for\\n * https://eips.ethereum.org/EIPS/eip-1967[EIP1967] slots.\\n *\\n * _Available since v4.1._\\n *\\n * @custom:oz-upgrades-unsafe-allow delegatecall\\n */\\nabstract contract ERC1967Upgrade {\\n // This is the keccak-256 hash of \\\"eip1967.proxy.rollback\\\" subtracted by 1\\n bytes32 private constant _ROLLBACK_SLOT = 0x4910fdfa16fed3260ed0e7147f7cc6da11a60208b5b9406d12a635614ffd9143;\\n\\n /**\\n * @dev Storage slot with the address of the current implementation.\\n * This is the keccak-256 hash of \\\"eip1967.proxy.implementation\\\" subtracted by 1, and is\\n * validated in the constructor.\\n */\\n bytes32 internal constant _IMPLEMENTATION_SLOT = 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc;\\n\\n /**\\n * @dev Emitted when the implementation is upgraded.\\n */\\n event Upgraded(address indexed implementation);\\n\\n /**\\n * @dev Returns the current implementation address.\\n */\\n function _getImplementation() internal view returns (address) {\\n return StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value;\\n }\\n\\n /**\\n * @dev Stores a new address in the EIP1967 implementation slot.\\n */\\n function _setImplementation(address newImplementation) private {\\n require(Address.isContract(newImplementation), \\\"ERC1967: new implementation is not a contract\\\");\\n StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value = newImplementation;\\n }\\n\\n /**\\n * @dev Perform implementation upgrade\\n *\\n * Emits an {Upgraded} event.\\n */\\n function _upgradeTo(address newImplementation) internal {\\n _setImplementation(newImplementation);\\n emit Upgraded(newImplementation);\\n }\\n\\n /**\\n * @dev Perform implementation upgrade with additional setup call.\\n *\\n * Emits an {Upgraded} event.\\n */\\n function _upgradeToAndCall(\\n address newImplementation,\\n bytes memory data,\\n bool forceCall\\n ) internal {\\n _upgradeTo(newImplementation);\\n if (data.length > 0 || forceCall) {\\n Address.functionDelegateCall(newImplementation, data);\\n }\\n }\\n\\n /**\\n * @dev Perform implementation upgrade with security checks for UUPS proxies, and additional setup call.\\n *\\n * Emits an {Upgraded} event.\\n */\\n function _upgradeToAndCallUUPS(\\n address newImplementation,\\n bytes memory data,\\n bool forceCall\\n ) internal {\\n // Upgrades from old implementations will perform a rollback test. This test requires the new\\n // implementation to upgrade back to the old, non-ERC1822 compliant, implementation. Removing\\n // this special case will break upgrade paths from old UUPS implementation to new ones.\\n if (StorageSlot.getBooleanSlot(_ROLLBACK_SLOT).value) {\\n _setImplementation(newImplementation);\\n } else {\\n try IERC1822Proxiable(newImplementation).proxiableUUID() returns (bytes32 slot) {\\n require(slot == _IMPLEMENTATION_SLOT, \\\"ERC1967Upgrade: unsupported proxiableUUID\\\");\\n } catch {\\n revert(\\\"ERC1967Upgrade: new implementation is not UUPS\\\");\\n }\\n _upgradeToAndCall(newImplementation, data, forceCall);\\n }\\n }\\n\\n /**\\n * @dev Storage slot with the admin of the contract.\\n * This is the keccak-256 hash of \\\"eip1967.proxy.admin\\\" subtracted by 1, and is\\n * validated in the constructor.\\n */\\n bytes32 internal constant _ADMIN_SLOT = 0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103;\\n\\n /**\\n * @dev Emitted when the admin account has changed.\\n */\\n event AdminChanged(address previousAdmin, address newAdmin);\\n\\n /**\\n * @dev Returns the current admin.\\n */\\n function _getAdmin() internal view returns (address) {\\n return StorageSlot.getAddressSlot(_ADMIN_SLOT).value;\\n }\\n\\n /**\\n * @dev Stores a new address in the EIP1967 admin slot.\\n */\\n function _setAdmin(address newAdmin) private {\\n require(newAdmin != address(0), \\\"ERC1967: new admin is the zero address\\\");\\n StorageSlot.getAddressSlot(_ADMIN_SLOT).value = newAdmin;\\n }\\n\\n /**\\n * @dev Changes the admin of the proxy.\\n *\\n * Emits an {AdminChanged} event.\\n */\\n function _changeAdmin(address newAdmin) internal {\\n emit AdminChanged(_getAdmin(), newAdmin);\\n _setAdmin(newAdmin);\\n }\\n\\n /**\\n * @dev The storage slot of the UpgradeableBeacon contract which defines the implementation for this proxy.\\n * This is bytes32(uint256(keccak256('eip1967.proxy.beacon')) - 1)) and is validated in the constructor.\\n */\\n bytes32 internal constant _BEACON_SLOT = 0xa3f0ad74e5423aebfd80d3ef4346578335a9a72aeaee59ff6cb3582b35133d50;\\n\\n /**\\n * @dev Emitted when the beacon is upgraded.\\n */\\n event BeaconUpgraded(address indexed beacon);\\n\\n /**\\n * @dev Returns the current beacon.\\n */\\n function _getBeacon() internal view returns (address) {\\n return StorageSlot.getAddressSlot(_BEACON_SLOT).value;\\n }\\n\\n /**\\n * @dev Stores a new beacon in the EIP1967 beacon slot.\\n */\\n function _setBeacon(address newBeacon) private {\\n require(Address.isContract(newBeacon), \\\"ERC1967: new beacon is not a contract\\\");\\n require(\\n Address.isContract(IBeacon(newBeacon).implementation()),\\n \\\"ERC1967: beacon implementation is not a contract\\\"\\n );\\n StorageSlot.getAddressSlot(_BEACON_SLOT).value = newBeacon;\\n }\\n\\n /**\\n * @dev Perform beacon upgrade with additional setup call. Note: This upgrades the address of the beacon, it does\\n * not upgrade the implementation contained in the beacon (see {UpgradeableBeacon-_setImplementation} for that).\\n *\\n * Emits a {BeaconUpgraded} event.\\n */\\n function _upgradeBeaconToAndCall(\\n address newBeacon,\\n bytes memory data,\\n bool forceCall\\n ) internal {\\n _setBeacon(newBeacon);\\n emit BeaconUpgraded(newBeacon);\\n if (data.length > 0 || forceCall) {\\n Address.functionDelegateCall(IBeacon(newBeacon).implementation(), data);\\n }\\n }\\n}\\n\",\"keccak256\":\"0xabf3f59bc0e5423eae45e459dbe92e7052c6983628d39008590edc852a62f94a\",\"license\":\"MIT\"},\"@openzeppelin/contracts/proxy/Proxy.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.6.0) (proxy/Proxy.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev This abstract contract provides a fallback function that delegates all calls to another contract using the EVM\\n * instruction `delegatecall`. We refer to the second contract as the _implementation_ behind the proxy, and it has to\\n * be specified by overriding the virtual {_implementation} function.\\n *\\n * Additionally, delegation to the implementation can be triggered manually through the {_fallback} function, or to a\\n * different contract through the {_delegate} function.\\n *\\n * The success and return data of the delegated call will be returned back to the caller of the proxy.\\n */\\nabstract contract Proxy {\\n /**\\n * @dev Delegates the current call to `implementation`.\\n *\\n * This function does not return to its internal call site, it will return directly to the external caller.\\n */\\n function _delegate(address implementation) internal virtual {\\n assembly {\\n // Copy msg.data. We take full control of memory in this inline assembly\\n // block because it will not return to Solidity code. We overwrite the\\n // Solidity scratch pad at memory position 0.\\n calldatacopy(0, 0, calldatasize())\\n\\n // Call the implementation.\\n // out and outsize are 0 because we don't know the size yet.\\n let result := delegatecall(gas(), implementation, 0, calldatasize(), 0, 0)\\n\\n // Copy the returned data.\\n returndatacopy(0, 0, returndatasize())\\n\\n switch result\\n // delegatecall returns 0 on error.\\n case 0 {\\n revert(0, returndatasize())\\n }\\n default {\\n return(0, returndatasize())\\n }\\n }\\n }\\n\\n /**\\n * @dev This is a virtual function that should be overridden so it returns the address to which the fallback function\\n * and {_fallback} should delegate.\\n */\\n function _implementation() internal view virtual returns (address);\\n\\n /**\\n * @dev Delegates the current call to the address returned by `_implementation()`.\\n *\\n * This function does not return to its internal call site, it will return directly to the external caller.\\n */\\n function _fallback() internal virtual {\\n _beforeFallback();\\n _delegate(_implementation());\\n }\\n\\n /**\\n * @dev Fallback function that delegates calls to the address returned by `_implementation()`. Will run if no other\\n * function in the contract matches the call data.\\n */\\n fallback() external payable virtual {\\n _fallback();\\n }\\n\\n /**\\n * @dev Fallback function that delegates calls to the address returned by `_implementation()`. Will run if call data\\n * is empty.\\n */\\n receive() external payable virtual {\\n _fallback();\\n }\\n\\n /**\\n * @dev Hook that is called before falling back to the implementation. Can happen as part of a manual `_fallback`\\n * call, or as part of the Solidity `fallback` or `receive` functions.\\n *\\n * If overridden should call `super._beforeFallback()`.\\n */\\n function _beforeFallback() internal virtual {}\\n}\\n\",\"keccak256\":\"0xc130fe33f1b2132158531a87734153293f6d07bc263ff4ac90e85da9c82c0e27\",\"license\":\"MIT\"},\"@openzeppelin/contracts/proxy/beacon/IBeacon.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (proxy/beacon/IBeacon.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev This is the interface that {BeaconProxy} expects of its beacon.\\n */\\ninterface IBeacon {\\n /**\\n * @dev Must return an address that can be used as a delegate call target.\\n *\\n * {BeaconProxy} will check that this address is a contract.\\n */\\n function implementation() external view returns (address);\\n}\\n\",\"keccak256\":\"0xd50a3421ac379ccb1be435fa646d66a65c986b4924f0849839f08692f39dde61\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/Address.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.7.0) (utils/Address.sol)\\n\\npragma solidity ^0.8.1;\\n\\n/**\\n * @dev Collection of functions related to the address type\\n */\\nlibrary Address {\\n /**\\n * @dev Returns true if `account` is a contract.\\n *\\n * [IMPORTANT]\\n * ====\\n * It is unsafe to assume that an address for which this function returns\\n * false is an externally-owned account (EOA) and not a contract.\\n *\\n * Among others, `isContract` will return false for the following\\n * types of addresses:\\n *\\n * - an externally-owned account\\n * - a contract in construction\\n * - an address where a contract will be created\\n * - an address where a contract lived, but was destroyed\\n * ====\\n *\\n * [IMPORTANT]\\n * ====\\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\\n *\\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\\n * constructor.\\n * ====\\n */\\n function isContract(address account) internal view returns (bool) {\\n // This method relies on extcodesize/address.code.length, which returns 0\\n // for contracts in construction, since the code is only stored at the end\\n // of the constructor execution.\\n\\n return account.code.length > 0;\\n }\\n\\n /**\\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\\n * `recipient`, forwarding all available gas and reverting on errors.\\n *\\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\\n * imposed by `transfer`, making them unable to receive funds via\\n * `transfer`. {sendValue} removes this limitation.\\n *\\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\\n *\\n * IMPORTANT: because control is transferred to `recipient`, care must be\\n * taken to not create reentrancy vulnerabilities. Consider using\\n * {ReentrancyGuard} or the\\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\\n */\\n function sendValue(address payable recipient, uint256 amount) internal {\\n require(address(this).balance >= amount, \\\"Address: insufficient balance\\\");\\n\\n (bool success, ) = recipient.call{value: amount}(\\\"\\\");\\n require(success, \\\"Address: unable to send value, recipient may have reverted\\\");\\n }\\n\\n /**\\n * @dev Performs a Solidity function call using a low level `call`. A\\n * plain `call` is an unsafe replacement for a function call: use this\\n * function instead.\\n *\\n * If `target` reverts with a revert reason, it is bubbled up by this\\n * function (like regular Solidity function calls).\\n *\\n * Returns the raw returned data. To convert to the expected return value,\\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\\n *\\n * Requirements:\\n *\\n * - `target` must be a contract.\\n * - calling `target` with `data` must not revert.\\n *\\n * _Available since v3.1._\\n */\\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\\n return functionCall(target, data, \\\"Address: low-level call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\\n * `errorMessage` as a fallback revert reason when `target` reverts.\\n *\\n * _Available since v3.1._\\n */\\n function functionCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n return functionCallWithValue(target, data, 0, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but also transferring `value` wei to `target`.\\n *\\n * Requirements:\\n *\\n * - the calling contract must have an ETH balance of at least `value`.\\n * - the called Solidity function must be `payable`.\\n *\\n * _Available since v3.1._\\n */\\n function functionCallWithValue(\\n address target,\\n bytes memory data,\\n uint256 value\\n ) internal returns (bytes memory) {\\n return functionCallWithValue(target, data, value, \\\"Address: low-level call with value failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\\n * with `errorMessage` as a fallback revert reason when `target` reverts.\\n *\\n * _Available since v3.1._\\n */\\n function functionCallWithValue(\\n address target,\\n bytes memory data,\\n uint256 value,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n require(address(this).balance >= value, \\\"Address: insufficient balance for call\\\");\\n require(isContract(target), \\\"Address: call to non-contract\\\");\\n\\n (bool success, bytes memory returndata) = target.call{value: value}(data);\\n return verifyCallResult(success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but performing a static call.\\n *\\n * _Available since v3.3._\\n */\\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\\n return functionStaticCall(target, data, \\\"Address: low-level static call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\\n * but performing a static call.\\n *\\n * _Available since v3.3._\\n */\\n function functionStaticCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal view returns (bytes memory) {\\n require(isContract(target), \\\"Address: static call to non-contract\\\");\\n\\n (bool success, bytes memory returndata) = target.staticcall(data);\\n return verifyCallResult(success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but performing a delegate call.\\n *\\n * _Available since v3.4._\\n */\\n function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {\\n return functionDelegateCall(target, data, \\\"Address: low-level delegate call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\\n * but performing a delegate call.\\n *\\n * _Available since v3.4._\\n */\\n function functionDelegateCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n require(isContract(target), \\\"Address: delegate call to non-contract\\\");\\n\\n (bool success, bytes memory returndata) = target.delegatecall(data);\\n return verifyCallResult(success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the\\n * revert reason using the provided one.\\n *\\n * _Available since v4.3._\\n */\\n function verifyCallResult(\\n bool success,\\n bytes memory returndata,\\n string memory errorMessage\\n ) internal pure returns (bytes memory) {\\n if (success) {\\n return returndata;\\n } else {\\n // Look for revert reason and bubble it up if present\\n if (returndata.length > 0) {\\n // The easiest way to bubble the revert reason is using memory via assembly\\n /// @solidity memory-safe-assembly\\n assembly {\\n let returndata_size := mload(returndata)\\n revert(add(32, returndata), returndata_size)\\n }\\n } else {\\n revert(errorMessage);\\n }\\n }\\n }\\n}\\n\",\"keccak256\":\"0xd6153ce99bcdcce22b124f755e72553295be6abcd63804cfdffceb188b8bef10\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/StorageSlot.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.7.0) (utils/StorageSlot.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Library for reading and writing primitive types to specific storage slots.\\n *\\n * Storage slots are often used to avoid storage conflict when dealing with upgradeable contracts.\\n * This library helps with reading and writing to such slots without the need for inline assembly.\\n *\\n * The functions in this library return Slot structs that contain a `value` member that can be used to read or write.\\n *\\n * Example usage to set ERC1967 implementation slot:\\n * ```\\n * contract ERC1967 {\\n * bytes32 internal constant _IMPLEMENTATION_SLOT = 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc;\\n *\\n * function _getImplementation() internal view returns (address) {\\n * return StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value;\\n * }\\n *\\n * function _setImplementation(address newImplementation) internal {\\n * require(Address.isContract(newImplementation), \\\"ERC1967: new implementation is not a contract\\\");\\n * StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value = newImplementation;\\n * }\\n * }\\n * ```\\n *\\n * _Available since v4.1 for `address`, `bool`, `bytes32`, and `uint256`._\\n */\\nlibrary StorageSlot {\\n struct AddressSlot {\\n address value;\\n }\\n\\n struct BooleanSlot {\\n bool value;\\n }\\n\\n struct Bytes32Slot {\\n bytes32 value;\\n }\\n\\n struct Uint256Slot {\\n uint256 value;\\n }\\n\\n /**\\n * @dev Returns an `AddressSlot` with member `value` located at `slot`.\\n */\\n function getAddressSlot(bytes32 slot) internal pure returns (AddressSlot storage r) {\\n /// @solidity memory-safe-assembly\\n assembly {\\n r.slot := slot\\n }\\n }\\n\\n /**\\n * @dev Returns an `BooleanSlot` with member `value` located at `slot`.\\n */\\n function getBooleanSlot(bytes32 slot) internal pure returns (BooleanSlot storage r) {\\n /// @solidity memory-safe-assembly\\n assembly {\\n r.slot := slot\\n }\\n }\\n\\n /**\\n * @dev Returns an `Bytes32Slot` with member `value` located at `slot`.\\n */\\n function getBytes32Slot(bytes32 slot) internal pure returns (Bytes32Slot storage r) {\\n /// @solidity memory-safe-assembly\\n assembly {\\n r.slot := slot\\n }\\n }\\n\\n /**\\n * @dev Returns an `Uint256Slot` with member `value` located at `slot`.\\n */\\n function getUint256Slot(bytes32 slot) internal pure returns (Uint256Slot storage r) {\\n /// @solidity memory-safe-assembly\\n assembly {\\n r.slot := slot\\n }\\n }\\n}\\n\",\"keccak256\":\"0xd5c50c54bf02740ebd122ff06832546cb5fa84486d52695a9ccfd11666e0c81d\",\"license\":\"MIT\"},\"contracts/external/TransparentUpgradeableProxy.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-3.0\\n\\npragma solidity ^0.8.12;\\n\\nimport \\\"@openzeppelin/contracts/proxy/ERC1967/ERC1967Proxy.sol\\\";\\n\\n/**\\n * @dev This contract implements a proxy that is upgradeable by an admin. It is fully forked from OpenZeppelin\\n * `TransparentUpgradeableProxy`\\n *\\n * To avoid https://medium.com/nomic-labs-blog/malicious-backdoors-in-ethereum-proxies-62629adf3357[proxy selector\\n * clashing], which can potentially be used in an attack, this contract uses the\\n * https://blog.openzeppelin.com/the-transparent-proxy-pattern/[transparent proxy pattern]. This pattern implies two\\n * things that go hand in hand:\\n *\\n * 1. If any account other than the admin calls the proxy, the call will be forwarded to the implementation, even if\\n * that call matches one of the admin functions exposed by the proxy itself.\\n * 2. If the admin calls the proxy, it can access the admin functions, but its calls will never be forwarded to the\\n * implementation. If the admin tries to call a function on the implementation it will fail with an error that says\\n * \\\"admin cannot fallback to proxy target\\\".\\n *\\n * These properties mean that the admin account can only be used for admin actions like upgrading the proxy or changing\\n * the admin, so it's best if it's a dedicated account that is not used for anything else. This will avoid headaches due\\n * to sudden errors when trying to call a function from the proxy implementation.\\n *\\n * Our recommendation is for the dedicated account to be an instance of the {ProxyAdmin} contract. If set up this way,\\n * you should think of the `ProxyAdmin` instance as the real administrative interface of your proxy.\\n */\\ncontract TransparentUpgradeableProxy is ERC1967Proxy {\\n /**\\n * @dev Initializes an upgradeable proxy managed by `_admin`, backed by the implementation at `_logic`, and\\n * optionally initialized with `_data` as explained in {ERC1967Proxy-constructor}.\\n */\\n constructor(address _logic, address admin_, bytes memory _data) payable ERC1967Proxy(_logic, _data) {\\n assert(_ADMIN_SLOT == bytes32(uint256(keccak256(\\\"eip1967.proxy.admin\\\")) - 1));\\n _changeAdmin(admin_);\\n }\\n\\n /**\\n * @dev Modifier used internally that will delegate the call to the implementation unless the sender is the admin.\\n */\\n modifier ifAdmin() {\\n if (msg.sender == _getAdmin()) {\\n _;\\n } else {\\n _fallback();\\n }\\n }\\n\\n /**\\n * @dev Returns the current admin.\\n *\\n * NOTE: Only the admin can call this function. See {ProxyAdmin-getProxyAdmin}.\\n *\\n * TIP: To get this value clients can read directly from the storage slot shown below (specified by EIP1967) using the\\n * https://eth.wiki/json-rpc/API#eth_getstorageat[`eth_getStorageAt`] RPC call.\\n * `0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103`\\n */\\n function admin() external ifAdmin returns (address admin_) {\\n admin_ = _getAdmin();\\n }\\n\\n /**\\n * @dev Returns the current implementation.\\n *\\n * NOTE: Only the admin can call this function. See {ProxyAdmin-getProxyImplementation}.\\n *\\n * TIP: To get this value clients can read directly from the storage slot shown below (specified by EIP1967) using the\\n * https://eth.wiki/json-rpc/API#eth_getstorageat[`eth_getStorageAt`] RPC call.\\n * `0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc`\\n */\\n function implementation() external ifAdmin returns (address implementation_) {\\n implementation_ = _implementation();\\n }\\n\\n /**\\n * @dev Changes the admin of the proxy.\\n *\\n * Emits an {AdminChanged} event.\\n *\\n * NOTE: Only the admin can call this function. See {ProxyAdmin-changeProxyAdmin}.\\n */\\n function changeAdmin(address newAdmin) external virtual ifAdmin {\\n _changeAdmin(newAdmin);\\n }\\n\\n /**\\n * @dev Upgrade the implementation of the proxy.\\n *\\n * NOTE: Only the admin can call this function. See {ProxyAdmin-upgrade}.\\n */\\n function upgradeTo(address newImplementation) external ifAdmin {\\n _upgradeToAndCall(newImplementation, bytes(\\\"\\\"), false);\\n }\\n\\n /**\\n * @dev Upgrade the implementation of the proxy, and then call a function from the new implementation as specified\\n * by `data`, which should be an encoded function call. This is useful to initialize new storage variables in the\\n * proxied contract.\\n *\\n * NOTE: Only the admin can call this function. See {ProxyAdmin-upgradeAndCall}.\\n */\\n function upgradeToAndCall(address newImplementation, bytes calldata data) external payable ifAdmin {\\n _upgradeToAndCall(newImplementation, data, true);\\n }\\n\\n /**\\n * @dev Returns the current admin.\\n */\\n function _admin() internal view virtual returns (address) {\\n return _getAdmin();\\n }\\n\\n /**\\n * @dev Makes sure the admin cannot access the fallback function. See {Proxy-_beforeFallback}.\\n */\\n function _beforeFallback() internal virtual override {\\n require(msg.sender != _getAdmin(), \\\"TransparentUpgradeableProxy: admin cannot fallback to proxy target\\\");\\n super._beforeFallback();\\n }\\n}\\n\",\"keccak256\":\"0x93a67a0f612ea3ff2a76315e138a6a88267270a1379d3cc7be52845fbbe611e2\",\"license\":\"GPL-3.0\"}},\"version\":1}", + "bytecode": "0x6080604052604051620010bb380380620010bb8339810160408190526200002691620004d8565b828162000036828260006200009a565b5062000066905060017fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6104620005b8565b6000805160206200107483398151915214620000865762000086620005da565b6200009182620000d7565b50505062000643565b620000a58362000132565b600082511180620000b35750805b15620000d257620000d083836200017460201b6200028c1760201c565b505b505050565b7f7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f62000102620001a5565b604080516001600160a01b03928316815291841660208301520160405180910390a16200012f81620001de565b50565b6200013d8162000293565b6040516001600160a01b038216907fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b90600090a250565b60606200019c8383604051806060016040528060278152602001620010946027913962000347565b90505b92915050565b6000620001cf6000805160206200107483398151915260001b6200042f60201b6200022e1760201c565b546001600160a01b0316919050565b6001600160a01b038116620002495760405162461bcd60e51b815260206004820152602660248201527f455243313936373a206e65772061646d696e20697320746865207a65726f206160448201526564647265737360d01b60648201526084015b60405180910390fd5b80620002726000805160206200107483398151915260001b6200042f60201b6200022e1760201c565b80546001600160a01b0319166001600160a01b039290921691909117905550565b620002a9816200043260201b620002b81760201c565b6200030d5760405162461bcd60e51b815260206004820152602d60248201527f455243313936373a206e657720696d706c656d656e746174696f6e206973206e60448201526c1bdd08184818dbdb9d1c9858dd609a1b606482015260840162000240565b80620002727f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc60001b6200042f60201b6200022e1760201c565b60606001600160a01b0384163b620003b15760405162461bcd60e51b815260206004820152602660248201527f416464726573733a2064656c65676174652063616c6c20746f206e6f6e2d636f6044820152651b9d1c9858dd60d21b606482015260840162000240565b600080856001600160a01b031685604051620003ce9190620005f0565b600060405180830381855af49150503d80600081146200040b576040519150601f19603f3d011682016040523d82523d6000602084013e62000410565b606091505b5090925090506200042382828662000441565b925050505b9392505050565b90565b6001600160a01b03163b151590565b606083156200045257508162000428565b825115620004635782518084602001fd5b8160405162461bcd60e51b81526004016200024091906200060e565b80516001600160a01b03811681146200049757600080fd5b919050565b634e487b7160e01b600052604160045260246000fd5b60005b83811015620004cf578181015183820152602001620004b5565b50506000910152565b600080600060608486031215620004ee57600080fd5b620004f9846200047f565b925062000509602085016200047f565b60408501519092506001600160401b03808211156200052757600080fd5b818601915086601f8301126200053c57600080fd5b8151818111156200055157620005516200049c565b604051601f8201601f19908116603f011681019083821181831017156200057c576200057c6200049c565b816040528281528960208487010111156200059657600080fd5b620005a9836020830160208801620004b2565b80955050505050509250925092565b818103818111156200019f57634e487b7160e01b600052601160045260246000fd5b634e487b7160e01b600052600160045260246000fd5b6000825162000604818460208701620004b2565b9190910192915050565b60208152600082518060208401526200062f816040850160208701620004b2565b601f01601f19169190910160400192915050565b610a2180620006536000396000f3fe60806040526004361061005e5760003560e01c80635c60da1b116100435780635c60da1b146100a85780638f283970146100e6578063f851a440146101065761006d565b80633659cfe6146100755780634f1ef286146100955761006d565b3661006d5761006b61011b565b005b61006b61011b565b34801561008157600080fd5b5061006b610090366004610895565b610135565b61006b6100a33660046108b0565b61017f565b3480156100b457600080fd5b506100bd6101f3565b60405173ffffffffffffffffffffffffffffffffffffffff909116815260200160405180910390f35b3480156100f257600080fd5b5061006b610101366004610895565b610231565b34801561011257600080fd5b506100bd61025e565b6101236102d4565b61013361012e6103ab565b6103b5565b565b61013d6103d9565b73ffffffffffffffffffffffffffffffffffffffff1633036101775761017481604051806020016040528060008152506000610419565b50565b61017461011b565b6101876103d9565b73ffffffffffffffffffffffffffffffffffffffff1633036101eb576101e68383838080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525060019250610419915050565b505050565b6101e661011b565b60006101fd6103d9565b73ffffffffffffffffffffffffffffffffffffffff163303610226576102216103ab565b905090565b61022e61011b565b90565b6102396103d9565b73ffffffffffffffffffffffffffffffffffffffff1633036101775761017481610444565b60006102686103d9565b73ffffffffffffffffffffffffffffffffffffffff163303610226576102216103d9565b60606102b183836040518060600160405280602781526020016109c5602791396104a5565b9392505050565b73ffffffffffffffffffffffffffffffffffffffff163b151590565b6102dc6103d9565b73ffffffffffffffffffffffffffffffffffffffff163303610133576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604260248201527f5472616e73706172656e745570677261646561626c6550726f78793a2061646d60448201527f696e2063616e6e6f742066616c6c6261636b20746f2070726f7879207461726760648201527f6574000000000000000000000000000000000000000000000000000000000000608482015260a4015b60405180910390fd5b60006102216105cd565b3660008037600080366000845af43d6000803e8080156103d4573d6000f35b3d6000fd5b60007fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035b5473ffffffffffffffffffffffffffffffffffffffff16919050565b610422836105f5565b60008251118061042f5750805b156101e65761043e838361028c565b50505050565b7f7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f61046d6103d9565b6040805173ffffffffffffffffffffffffffffffffffffffff928316815291841660208301520160405180910390a161017481610642565b606073ffffffffffffffffffffffffffffffffffffffff84163b61054b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f416464726573733a2064656c65676174652063616c6c20746f206e6f6e2d636f60448201527f6e7472616374000000000000000000000000000000000000000000000000000060648201526084016103a2565b6000808573ffffffffffffffffffffffffffffffffffffffff16856040516105739190610957565b600060405180830381855af49150503d80600081146105ae576040519150601f19603f3d011682016040523d82523d6000602084013e6105b3565b606091505b50915091506105c382828661074e565b9695505050505050565b60007f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc6103fd565b6105fe816107a1565b60405173ffffffffffffffffffffffffffffffffffffffff8216907fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b90600090a250565b73ffffffffffffffffffffffffffffffffffffffff81166106e5576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f455243313936373a206e65772061646d696e20697320746865207a65726f206160448201527f646472657373000000000000000000000000000000000000000000000000000060648201526084016103a2565b807fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035b80547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff9290921691909117905550565b6060831561075d5750816102b1565b82511561076d5782518084602001fd5b816040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016103a29190610973565b73ffffffffffffffffffffffffffffffffffffffff81163b610845576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602d60248201527f455243313936373a206e657720696d706c656d656e746174696f6e206973206e60448201527f6f74206120636f6e74726163740000000000000000000000000000000000000060648201526084016103a2565b807f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc610708565b803573ffffffffffffffffffffffffffffffffffffffff8116811461089057600080fd5b919050565b6000602082840312156108a757600080fd5b6102b18261086c565b6000806000604084860312156108c557600080fd5b6108ce8461086c565b9250602084013567ffffffffffffffff808211156108eb57600080fd5b818601915086601f8301126108ff57600080fd5b81358181111561090e57600080fd5b87602082850101111561092057600080fd5b6020830194508093505050509250925092565b60005b8381101561094e578181015183820152602001610936565b50506000910152565b60008251610969818460208701610933565b9190910192915050565b6020815260008251806020840152610992816040850160208701610933565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016919091016040019291505056fe416464726573733a206c6f772d6c6576656c2064656c65676174652063616c6c206661696c6564a2646970667358221220e96638b07fb1675d93a95c49e417bc8111448b23a59918698cdcd8fd488dd7cf64736f6c63430008110033b53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103416464726573733a206c6f772d6c6576656c2064656c65676174652063616c6c206661696c6564", + "deployedBytecode": "0x60806040526004361061005e5760003560e01c80635c60da1b116100435780635c60da1b146100a85780638f283970146100e6578063f851a440146101065761006d565b80633659cfe6146100755780634f1ef286146100955761006d565b3661006d5761006b61011b565b005b61006b61011b565b34801561008157600080fd5b5061006b610090366004610895565b610135565b61006b6100a33660046108b0565b61017f565b3480156100b457600080fd5b506100bd6101f3565b60405173ffffffffffffffffffffffffffffffffffffffff909116815260200160405180910390f35b3480156100f257600080fd5b5061006b610101366004610895565b610231565b34801561011257600080fd5b506100bd61025e565b6101236102d4565b61013361012e6103ab565b6103b5565b565b61013d6103d9565b73ffffffffffffffffffffffffffffffffffffffff1633036101775761017481604051806020016040528060008152506000610419565b50565b61017461011b565b6101876103d9565b73ffffffffffffffffffffffffffffffffffffffff1633036101eb576101e68383838080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525060019250610419915050565b505050565b6101e661011b565b60006101fd6103d9565b73ffffffffffffffffffffffffffffffffffffffff163303610226576102216103ab565b905090565b61022e61011b565b90565b6102396103d9565b73ffffffffffffffffffffffffffffffffffffffff1633036101775761017481610444565b60006102686103d9565b73ffffffffffffffffffffffffffffffffffffffff163303610226576102216103d9565b60606102b183836040518060600160405280602781526020016109c5602791396104a5565b9392505050565b73ffffffffffffffffffffffffffffffffffffffff163b151590565b6102dc6103d9565b73ffffffffffffffffffffffffffffffffffffffff163303610133576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604260248201527f5472616e73706172656e745570677261646561626c6550726f78793a2061646d60448201527f696e2063616e6e6f742066616c6c6261636b20746f2070726f7879207461726760648201527f6574000000000000000000000000000000000000000000000000000000000000608482015260a4015b60405180910390fd5b60006102216105cd565b3660008037600080366000845af43d6000803e8080156103d4573d6000f35b3d6000fd5b60007fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035b5473ffffffffffffffffffffffffffffffffffffffff16919050565b610422836105f5565b60008251118061042f5750805b156101e65761043e838361028c565b50505050565b7f7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f61046d6103d9565b6040805173ffffffffffffffffffffffffffffffffffffffff928316815291841660208301520160405180910390a161017481610642565b606073ffffffffffffffffffffffffffffffffffffffff84163b61054b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f416464726573733a2064656c65676174652063616c6c20746f206e6f6e2d636f60448201527f6e7472616374000000000000000000000000000000000000000000000000000060648201526084016103a2565b6000808573ffffffffffffffffffffffffffffffffffffffff16856040516105739190610957565b600060405180830381855af49150503d80600081146105ae576040519150601f19603f3d011682016040523d82523d6000602084013e6105b3565b606091505b50915091506105c382828661074e565b9695505050505050565b60007f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc6103fd565b6105fe816107a1565b60405173ffffffffffffffffffffffffffffffffffffffff8216907fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b90600090a250565b73ffffffffffffffffffffffffffffffffffffffff81166106e5576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f455243313936373a206e65772061646d696e20697320746865207a65726f206160448201527f646472657373000000000000000000000000000000000000000000000000000060648201526084016103a2565b807fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035b80547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff9290921691909117905550565b6060831561075d5750816102b1565b82511561076d5782518084602001fd5b816040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016103a29190610973565b73ffffffffffffffffffffffffffffffffffffffff81163b610845576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602d60248201527f455243313936373a206e657720696d706c656d656e746174696f6e206973206e60448201527f6f74206120636f6e74726163740000000000000000000000000000000000000060648201526084016103a2565b807f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc610708565b803573ffffffffffffffffffffffffffffffffffffffff8116811461089057600080fd5b919050565b6000602082840312156108a757600080fd5b6102b18261086c565b6000806000604084860312156108c557600080fd5b6108ce8461086c565b9250602084013567ffffffffffffffff808211156108eb57600080fd5b818601915086601f8301126108ff57600080fd5b81358181111561090e57600080fd5b87602082850101111561092057600080fd5b6020830194508093505050509250925092565b60005b8381101561094e578181015183820152602001610936565b50506000910152565b60008251610969818460208701610933565b9190910192915050565b6020815260008251806020840152610992816040850160208701610933565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016919091016040019291505056fe416464726573733a206c6f772d6c6576656c2064656c65676174652063616c6c206661696c6564a2646970667358221220e96638b07fb1675d93a95c49e417bc8111448b23a59918698cdcd8fd488dd7cf64736f6c63430008110033", + "devdoc": { + "details": "This contract implements a proxy that is upgradeable by an admin. It is fully forked from OpenZeppelin `TransparentUpgradeableProxy` To avoid https://medium.com/nomic-labs-blog/malicious-backdoors-in-ethereum-proxies-62629adf3357[proxy selector clashing], which can potentially be used in an attack, this contract uses the https://blog.openzeppelin.com/the-transparent-proxy-pattern/[transparent proxy pattern]. This pattern implies two things that go hand in hand: 1. If any account other than the admin calls the proxy, the call will be forwarded to the implementation, even if that call matches one of the admin functions exposed by the proxy itself. 2. If the admin calls the proxy, it can access the admin functions, but its calls will never be forwarded to the implementation. If the admin tries to call a function on the implementation it will fail with an error that says \"admin cannot fallback to proxy target\". These properties mean that the admin account can only be used for admin actions like upgrading the proxy or changing the admin, so it's best if it's a dedicated account that is not used for anything else. This will avoid headaches due to sudden errors when trying to call a function from the proxy implementation. Our recommendation is for the dedicated account to be an instance of the {ProxyAdmin} contract. If set up this way, you should think of the `ProxyAdmin` instance as the real administrative interface of your proxy.", + "kind": "dev", + "methods": { + "admin()": { + "details": "Returns the current admin. NOTE: Only the admin can call this function. See {ProxyAdmin-getProxyAdmin}. TIP: To get this value clients can read directly from the storage slot shown below (specified by EIP1967) using the https://eth.wiki/json-rpc/API#eth_getstorageat[`eth_getStorageAt`] RPC call. `0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103`" + }, + "changeAdmin(address)": { + "details": "Changes the admin of the proxy. Emits an {AdminChanged} event. NOTE: Only the admin can call this function. See {ProxyAdmin-changeProxyAdmin}." + }, + "constructor": { + "details": "Initializes an upgradeable proxy managed by `_admin`, backed by the implementation at `_logic`, and optionally initialized with `_data` as explained in {ERC1967Proxy-constructor}." + }, + "implementation()": { + "details": "Returns the current implementation. NOTE: Only the admin can call this function. See {ProxyAdmin-getProxyImplementation}. TIP: To get this value clients can read directly from the storage slot shown below (specified by EIP1967) using the https://eth.wiki/json-rpc/API#eth_getstorageat[`eth_getStorageAt`] RPC call. `0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc`" + }, + "upgradeTo(address)": { + "details": "Upgrade the implementation of the proxy. NOTE: Only the admin can call this function. See {ProxyAdmin-upgrade}." + }, + "upgradeToAndCall(address,bytes)": { + "details": "Upgrade the implementation of the proxy, and then call a function from the new implementation as specified by `data`, which should be an encoded function call. This is useful to initialize new storage variables in the proxied contract. NOTE: Only the admin can call this function. See {ProxyAdmin-upgradeAndCall}." + } + }, + "version": 1 + }, + "userdoc": { + "kind": "user", + "methods": {}, + "version": 1 + }, + "storageLayout": { + "storage": [], + "types": null + } +} \ No newline at end of file diff --git a/deployments/base/Treasury_USD.json b/deployments/base/Treasury_USD.json new file mode 100644 index 00000000..94c4d75b --- /dev/null +++ b/deployments/base/Treasury_USD.json @@ -0,0 +1,247 @@ +{ + "address": "0xdD6A0A00fE3353e813F3B3864694D55D2a7cE11C", + "abi": [ + { + "inputs": [ + { + "internalType": "address", + "name": "_logic", + "type": "address" + }, + { + "internalType": "address", + "name": "admin_", + "type": "address" + }, + { + "internalType": "bytes", + "name": "_data", + "type": "bytes" + } + ], + "stateMutability": "payable", + "type": "constructor" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "previousAdmin", + "type": "address" + }, + { + "indexed": false, + "internalType": "address", + "name": "newAdmin", + "type": "address" + } + ], + "name": "AdminChanged", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "beacon", + "type": "address" + } + ], + "name": "BeaconUpgraded", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "implementation", + "type": "address" + } + ], + "name": "Upgraded", + "type": "event" + }, + { + "stateMutability": "payable", + "type": "fallback" + }, + { + "inputs": [], + "name": "admin", + "outputs": [ + { + "internalType": "address", + "name": "admin_", + "type": "address" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "newAdmin", + "type": "address" + } + ], + "name": "changeAdmin", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "implementation", + "outputs": [ + { + "internalType": "address", + "name": "implementation_", + "type": "address" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "newImplementation", + "type": "address" + } + ], + "name": "upgradeTo", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "newImplementation", + "type": "address" + }, + { + "internalType": "bytes", + "name": "data", + "type": "bytes" + } + ], + "name": "upgradeToAndCall", + "outputs": [], + "stateMutability": "payable", + "type": "function" + }, + { + "stateMutability": "payable", + "type": "receive" + } + ], + "transactionHash": "0xfa7b7fbd07fb32abe952ab35abd693c1e6ba5b58b069a38a5caf0998fe59df09", + "receipt": { + "to": null, + "from": "0xfdA462548Ce04282f4B6D6619823a7C64Fdc0185", + "contractAddress": "0xdD6A0A00fE3353e813F3B3864694D55D2a7cE11C", + "transactionIndex": 2, + "gasUsed": "736150", + "logsBloom": "0x00000000000000000000000000000000400000000000000000000000000000000000000008000000000000000000000000000000000000020000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000010000000000000000000000000000000080000000000000800000000000000000000000000000000400000000000000000000000000000000000000000020000000000010000000040000000000000400000000000000000000000000008000000000000000000000000000000000000008000000000000000000", + "blockHash": "0x80c59ddae8d0b912e1a4dc2fb387670c83f544917cf03ce5a068c862a3881230", + "transactionHash": "0xfa7b7fbd07fb32abe952ab35abd693c1e6ba5b58b069a38a5caf0998fe59df09", + "logs": [ + { + "transactionIndex": 2, + "blockNumber": 9043246, + "transactionHash": "0xfa7b7fbd07fb32abe952ab35abd693c1e6ba5b58b069a38a5caf0998fe59df09", + "address": "0xdD6A0A00fE3353e813F3B3864694D55D2a7cE11C", + "topics": [ + "0xbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b", + "0x0000000000000000000000001a7e4e63778b4f12a199c062f3efdd288afcbce8" + ], + "data": "0x", + "logIndex": 0, + "blockHash": "0x80c59ddae8d0b912e1a4dc2fb387670c83f544917cf03ce5a068c862a3881230" + }, + { + "transactionIndex": 2, + "blockNumber": 9043246, + "transactionHash": "0xfa7b7fbd07fb32abe952ab35abd693c1e6ba5b58b069a38a5caf0998fe59df09", + "address": "0xdD6A0A00fE3353e813F3B3864694D55D2a7cE11C", + "topics": [ + "0x7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb3847402498" + ], + "data": "0x0000000000000000000000000000000000000000000000000000000000000001", + "logIndex": 1, + "blockHash": "0x80c59ddae8d0b912e1a4dc2fb387670c83f544917cf03ce5a068c862a3881230" + }, + { + "transactionIndex": 2, + "blockNumber": 9043246, + "transactionHash": "0xfa7b7fbd07fb32abe952ab35abd693c1e6ba5b58b069a38a5caf0998fe59df09", + "address": "0xdD6A0A00fE3353e813F3B3864694D55D2a7cE11C", + "topics": [ + "0x7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f" + ], + "data": "0x000000000000000000000000000000000000000000000000000000000000000000000000000000000000000031429d1856ad1377a8a0079410b297e1a9e214c2", + "logIndex": 2, + "blockHash": "0x80c59ddae8d0b912e1a4dc2fb387670c83f544917cf03ce5a068c862a3881230" + } + ], + "blockNumber": 9043246, + "cumulativeGasUsed": "805055", + "status": 1, + "byzantium": true + }, + "args": [ + "0x1a7e4e63778B4f12a199C062f3eFdD288afCBce8", + "0x31429d1856aD1377A8A0079410B297e1a9e214c2", + "0x485cc955000000000000000000000000a6a505eeb4e1e93052c48126f2d42ef6694a651d0000000000000000000000000000206329b97db379d5e1bf586bbdb969c63274" + ], + "numDeployments": 1, + "solcInputHash": "871924e0c138825a2736b76def8fef8d", + "metadata": "{\"compiler\":{\"version\":\"0.8.17+commit.8df45f5f\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_logic\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"admin_\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"_data\",\"type\":\"bytes\"}],\"stateMutability\":\"payable\",\"type\":\"constructor\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"previousAdmin\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"newAdmin\",\"type\":\"address\"}],\"name\":\"AdminChanged\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"beacon\",\"type\":\"address\"}],\"name\":\"BeaconUpgraded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"implementation\",\"type\":\"address\"}],\"name\":\"Upgraded\",\"type\":\"event\"},{\"stateMutability\":\"payable\",\"type\":\"fallback\"},{\"inputs\":[],\"name\":\"admin\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"admin_\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newAdmin\",\"type\":\"address\"}],\"name\":\"changeAdmin\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"implementation\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"implementation_\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newImplementation\",\"type\":\"address\"}],\"name\":\"upgradeTo\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newImplementation\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"}],\"name\":\"upgradeToAndCall\",\"outputs\":[],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"stateMutability\":\"payable\",\"type\":\"receive\"}],\"devdoc\":{\"details\":\"This contract implements a proxy that is upgradeable by an admin. It is fully forked from OpenZeppelin `TransparentUpgradeableProxy` To avoid https://medium.com/nomic-labs-blog/malicious-backdoors-in-ethereum-proxies-62629adf3357[proxy selector clashing], which can potentially be used in an attack, this contract uses the https://blog.openzeppelin.com/the-transparent-proxy-pattern/[transparent proxy pattern]. This pattern implies two things that go hand in hand: 1. If any account other than the admin calls the proxy, the call will be forwarded to the implementation, even if that call matches one of the admin functions exposed by the proxy itself. 2. If the admin calls the proxy, it can access the admin functions, but its calls will never be forwarded to the implementation. If the admin tries to call a function on the implementation it will fail with an error that says \\\"admin cannot fallback to proxy target\\\". These properties mean that the admin account can only be used for admin actions like upgrading the proxy or changing the admin, so it's best if it's a dedicated account that is not used for anything else. This will avoid headaches due to sudden errors when trying to call a function from the proxy implementation. Our recommendation is for the dedicated account to be an instance of the {ProxyAdmin} contract. If set up this way, you should think of the `ProxyAdmin` instance as the real administrative interface of your proxy.\",\"kind\":\"dev\",\"methods\":{\"admin()\":{\"details\":\"Returns the current admin. NOTE: Only the admin can call this function. See {ProxyAdmin-getProxyAdmin}. TIP: To get this value clients can read directly from the storage slot shown below (specified by EIP1967) using the https://eth.wiki/json-rpc/API#eth_getstorageat[`eth_getStorageAt`] RPC call. `0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103`\"},\"changeAdmin(address)\":{\"details\":\"Changes the admin of the proxy. Emits an {AdminChanged} event. NOTE: Only the admin can call this function. See {ProxyAdmin-changeProxyAdmin}.\"},\"constructor\":{\"details\":\"Initializes an upgradeable proxy managed by `_admin`, backed by the implementation at `_logic`, and optionally initialized with `_data` as explained in {ERC1967Proxy-constructor}.\"},\"implementation()\":{\"details\":\"Returns the current implementation. NOTE: Only the admin can call this function. See {ProxyAdmin-getProxyImplementation}. TIP: To get this value clients can read directly from the storage slot shown below (specified by EIP1967) using the https://eth.wiki/json-rpc/API#eth_getstorageat[`eth_getStorageAt`] RPC call. `0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc`\"},\"upgradeTo(address)\":{\"details\":\"Upgrade the implementation of the proxy. NOTE: Only the admin can call this function. See {ProxyAdmin-upgrade}.\"},\"upgradeToAndCall(address,bytes)\":{\"details\":\"Upgrade the implementation of the proxy, and then call a function from the new implementation as specified by `data`, which should be an encoded function call. This is useful to initialize new storage variables in the proxied contract. NOTE: Only the admin can call this function. See {ProxyAdmin-upgradeAndCall}.\"}},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/external/TransparentUpgradeableProxy.sol\":\"TransparentUpgradeableProxy\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":1000000},\"remappings\":[]},\"sources\":{\"@openzeppelin/contracts/interfaces/draft-IERC1822.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.5.0) (interfaces/draft-IERC1822.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev ERC1822: Universal Upgradeable Proxy Standard (UUPS) documents a method for upgradeability through a simplified\\n * proxy whose upgrades are fully controlled by the current implementation.\\n */\\ninterface IERC1822Proxiable {\\n /**\\n * @dev Returns the storage slot that the proxiable contract assumes is being used to store the implementation\\n * address.\\n *\\n * IMPORTANT: A proxy pointing at a proxiable contract should not be considered proxiable itself, because this risks\\n * bricking a proxy that upgrades to it, by delegating to itself until out of gas. Thus it is critical that this\\n * function revert if invoked through a proxy.\\n */\\n function proxiableUUID() external view returns (bytes32);\\n}\\n\",\"keccak256\":\"0x1d4afe6cb24200cc4545eed814ecf5847277dfe5d613a1707aad5fceecebcfff\",\"license\":\"MIT\"},\"@openzeppelin/contracts/proxy/ERC1967/ERC1967Proxy.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.7.0) (proxy/ERC1967/ERC1967Proxy.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../Proxy.sol\\\";\\nimport \\\"./ERC1967Upgrade.sol\\\";\\n\\n/**\\n * @dev This contract implements an upgradeable proxy. It is upgradeable because calls are delegated to an\\n * implementation address that can be changed. This address is stored in storage in the location specified by\\n * https://eips.ethereum.org/EIPS/eip-1967[EIP1967], so that it doesn't conflict with the storage layout of the\\n * implementation behind the proxy.\\n */\\ncontract ERC1967Proxy is Proxy, ERC1967Upgrade {\\n /**\\n * @dev Initializes the upgradeable proxy with an initial implementation specified by `_logic`.\\n *\\n * If `_data` is nonempty, it's used as data in a delegate call to `_logic`. This will typically be an encoded\\n * function call, and allows initializing the storage of the proxy like a Solidity constructor.\\n */\\n constructor(address _logic, bytes memory _data) payable {\\n _upgradeToAndCall(_logic, _data, false);\\n }\\n\\n /**\\n * @dev Returns the current implementation address.\\n */\\n function _implementation() internal view virtual override returns (address impl) {\\n return ERC1967Upgrade._getImplementation();\\n }\\n}\\n\",\"keccak256\":\"0xa2b22da3032e50b55f95ec1d13336102d675f341167aa76db571ef7f8bb7975d\",\"license\":\"MIT\"},\"@openzeppelin/contracts/proxy/ERC1967/ERC1967Upgrade.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.5.0) (proxy/ERC1967/ERC1967Upgrade.sol)\\n\\npragma solidity ^0.8.2;\\n\\nimport \\\"../beacon/IBeacon.sol\\\";\\nimport \\\"../../interfaces/draft-IERC1822.sol\\\";\\nimport \\\"../../utils/Address.sol\\\";\\nimport \\\"../../utils/StorageSlot.sol\\\";\\n\\n/**\\n * @dev This abstract contract provides getters and event emitting update functions for\\n * https://eips.ethereum.org/EIPS/eip-1967[EIP1967] slots.\\n *\\n * _Available since v4.1._\\n *\\n * @custom:oz-upgrades-unsafe-allow delegatecall\\n */\\nabstract contract ERC1967Upgrade {\\n // This is the keccak-256 hash of \\\"eip1967.proxy.rollback\\\" subtracted by 1\\n bytes32 private constant _ROLLBACK_SLOT = 0x4910fdfa16fed3260ed0e7147f7cc6da11a60208b5b9406d12a635614ffd9143;\\n\\n /**\\n * @dev Storage slot with the address of the current implementation.\\n * This is the keccak-256 hash of \\\"eip1967.proxy.implementation\\\" subtracted by 1, and is\\n * validated in the constructor.\\n */\\n bytes32 internal constant _IMPLEMENTATION_SLOT = 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc;\\n\\n /**\\n * @dev Emitted when the implementation is upgraded.\\n */\\n event Upgraded(address indexed implementation);\\n\\n /**\\n * @dev Returns the current implementation address.\\n */\\n function _getImplementation() internal view returns (address) {\\n return StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value;\\n }\\n\\n /**\\n * @dev Stores a new address in the EIP1967 implementation slot.\\n */\\n function _setImplementation(address newImplementation) private {\\n require(Address.isContract(newImplementation), \\\"ERC1967: new implementation is not a contract\\\");\\n StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value = newImplementation;\\n }\\n\\n /**\\n * @dev Perform implementation upgrade\\n *\\n * Emits an {Upgraded} event.\\n */\\n function _upgradeTo(address newImplementation) internal {\\n _setImplementation(newImplementation);\\n emit Upgraded(newImplementation);\\n }\\n\\n /**\\n * @dev Perform implementation upgrade with additional setup call.\\n *\\n * Emits an {Upgraded} event.\\n */\\n function _upgradeToAndCall(\\n address newImplementation,\\n bytes memory data,\\n bool forceCall\\n ) internal {\\n _upgradeTo(newImplementation);\\n if (data.length > 0 || forceCall) {\\n Address.functionDelegateCall(newImplementation, data);\\n }\\n }\\n\\n /**\\n * @dev Perform implementation upgrade with security checks for UUPS proxies, and additional setup call.\\n *\\n * Emits an {Upgraded} event.\\n */\\n function _upgradeToAndCallUUPS(\\n address newImplementation,\\n bytes memory data,\\n bool forceCall\\n ) internal {\\n // Upgrades from old implementations will perform a rollback test. This test requires the new\\n // implementation to upgrade back to the old, non-ERC1822 compliant, implementation. Removing\\n // this special case will break upgrade paths from old UUPS implementation to new ones.\\n if (StorageSlot.getBooleanSlot(_ROLLBACK_SLOT).value) {\\n _setImplementation(newImplementation);\\n } else {\\n try IERC1822Proxiable(newImplementation).proxiableUUID() returns (bytes32 slot) {\\n require(slot == _IMPLEMENTATION_SLOT, \\\"ERC1967Upgrade: unsupported proxiableUUID\\\");\\n } catch {\\n revert(\\\"ERC1967Upgrade: new implementation is not UUPS\\\");\\n }\\n _upgradeToAndCall(newImplementation, data, forceCall);\\n }\\n }\\n\\n /**\\n * @dev Storage slot with the admin of the contract.\\n * This is the keccak-256 hash of \\\"eip1967.proxy.admin\\\" subtracted by 1, and is\\n * validated in the constructor.\\n */\\n bytes32 internal constant _ADMIN_SLOT = 0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103;\\n\\n /**\\n * @dev Emitted when the admin account has changed.\\n */\\n event AdminChanged(address previousAdmin, address newAdmin);\\n\\n /**\\n * @dev Returns the current admin.\\n */\\n function _getAdmin() internal view returns (address) {\\n return StorageSlot.getAddressSlot(_ADMIN_SLOT).value;\\n }\\n\\n /**\\n * @dev Stores a new address in the EIP1967 admin slot.\\n */\\n function _setAdmin(address newAdmin) private {\\n require(newAdmin != address(0), \\\"ERC1967: new admin is the zero address\\\");\\n StorageSlot.getAddressSlot(_ADMIN_SLOT).value = newAdmin;\\n }\\n\\n /**\\n * @dev Changes the admin of the proxy.\\n *\\n * Emits an {AdminChanged} event.\\n */\\n function _changeAdmin(address newAdmin) internal {\\n emit AdminChanged(_getAdmin(), newAdmin);\\n _setAdmin(newAdmin);\\n }\\n\\n /**\\n * @dev The storage slot of the UpgradeableBeacon contract which defines the implementation for this proxy.\\n * This is bytes32(uint256(keccak256('eip1967.proxy.beacon')) - 1)) and is validated in the constructor.\\n */\\n bytes32 internal constant _BEACON_SLOT = 0xa3f0ad74e5423aebfd80d3ef4346578335a9a72aeaee59ff6cb3582b35133d50;\\n\\n /**\\n * @dev Emitted when the beacon is upgraded.\\n */\\n event BeaconUpgraded(address indexed beacon);\\n\\n /**\\n * @dev Returns the current beacon.\\n */\\n function _getBeacon() internal view returns (address) {\\n return StorageSlot.getAddressSlot(_BEACON_SLOT).value;\\n }\\n\\n /**\\n * @dev Stores a new beacon in the EIP1967 beacon slot.\\n */\\n function _setBeacon(address newBeacon) private {\\n require(Address.isContract(newBeacon), \\\"ERC1967: new beacon is not a contract\\\");\\n require(\\n Address.isContract(IBeacon(newBeacon).implementation()),\\n \\\"ERC1967: beacon implementation is not a contract\\\"\\n );\\n StorageSlot.getAddressSlot(_BEACON_SLOT).value = newBeacon;\\n }\\n\\n /**\\n * @dev Perform beacon upgrade with additional setup call. Note: This upgrades the address of the beacon, it does\\n * not upgrade the implementation contained in the beacon (see {UpgradeableBeacon-_setImplementation} for that).\\n *\\n * Emits a {BeaconUpgraded} event.\\n */\\n function _upgradeBeaconToAndCall(\\n address newBeacon,\\n bytes memory data,\\n bool forceCall\\n ) internal {\\n _setBeacon(newBeacon);\\n emit BeaconUpgraded(newBeacon);\\n if (data.length > 0 || forceCall) {\\n Address.functionDelegateCall(IBeacon(newBeacon).implementation(), data);\\n }\\n }\\n}\\n\",\"keccak256\":\"0xabf3f59bc0e5423eae45e459dbe92e7052c6983628d39008590edc852a62f94a\",\"license\":\"MIT\"},\"@openzeppelin/contracts/proxy/Proxy.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.6.0) (proxy/Proxy.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev This abstract contract provides a fallback function that delegates all calls to another contract using the EVM\\n * instruction `delegatecall`. We refer to the second contract as the _implementation_ behind the proxy, and it has to\\n * be specified by overriding the virtual {_implementation} function.\\n *\\n * Additionally, delegation to the implementation can be triggered manually through the {_fallback} function, or to a\\n * different contract through the {_delegate} function.\\n *\\n * The success and return data of the delegated call will be returned back to the caller of the proxy.\\n */\\nabstract contract Proxy {\\n /**\\n * @dev Delegates the current call to `implementation`.\\n *\\n * This function does not return to its internal call site, it will return directly to the external caller.\\n */\\n function _delegate(address implementation) internal virtual {\\n assembly {\\n // Copy msg.data. We take full control of memory in this inline assembly\\n // block because it will not return to Solidity code. We overwrite the\\n // Solidity scratch pad at memory position 0.\\n calldatacopy(0, 0, calldatasize())\\n\\n // Call the implementation.\\n // out and outsize are 0 because we don't know the size yet.\\n let result := delegatecall(gas(), implementation, 0, calldatasize(), 0, 0)\\n\\n // Copy the returned data.\\n returndatacopy(0, 0, returndatasize())\\n\\n switch result\\n // delegatecall returns 0 on error.\\n case 0 {\\n revert(0, returndatasize())\\n }\\n default {\\n return(0, returndatasize())\\n }\\n }\\n }\\n\\n /**\\n * @dev This is a virtual function that should be overridden so it returns the address to which the fallback function\\n * and {_fallback} should delegate.\\n */\\n function _implementation() internal view virtual returns (address);\\n\\n /**\\n * @dev Delegates the current call to the address returned by `_implementation()`.\\n *\\n * This function does not return to its internal call site, it will return directly to the external caller.\\n */\\n function _fallback() internal virtual {\\n _beforeFallback();\\n _delegate(_implementation());\\n }\\n\\n /**\\n * @dev Fallback function that delegates calls to the address returned by `_implementation()`. Will run if no other\\n * function in the contract matches the call data.\\n */\\n fallback() external payable virtual {\\n _fallback();\\n }\\n\\n /**\\n * @dev Fallback function that delegates calls to the address returned by `_implementation()`. Will run if call data\\n * is empty.\\n */\\n receive() external payable virtual {\\n _fallback();\\n }\\n\\n /**\\n * @dev Hook that is called before falling back to the implementation. Can happen as part of a manual `_fallback`\\n * call, or as part of the Solidity `fallback` or `receive` functions.\\n *\\n * If overridden should call `super._beforeFallback()`.\\n */\\n function _beforeFallback() internal virtual {}\\n}\\n\",\"keccak256\":\"0xc130fe33f1b2132158531a87734153293f6d07bc263ff4ac90e85da9c82c0e27\",\"license\":\"MIT\"},\"@openzeppelin/contracts/proxy/beacon/IBeacon.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (proxy/beacon/IBeacon.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev This is the interface that {BeaconProxy} expects of its beacon.\\n */\\ninterface IBeacon {\\n /**\\n * @dev Must return an address that can be used as a delegate call target.\\n *\\n * {BeaconProxy} will check that this address is a contract.\\n */\\n function implementation() external view returns (address);\\n}\\n\",\"keccak256\":\"0xd50a3421ac379ccb1be435fa646d66a65c986b4924f0849839f08692f39dde61\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/Address.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.7.0) (utils/Address.sol)\\n\\npragma solidity ^0.8.1;\\n\\n/**\\n * @dev Collection of functions related to the address type\\n */\\nlibrary Address {\\n /**\\n * @dev Returns true if `account` is a contract.\\n *\\n * [IMPORTANT]\\n * ====\\n * It is unsafe to assume that an address for which this function returns\\n * false is an externally-owned account (EOA) and not a contract.\\n *\\n * Among others, `isContract` will return false for the following\\n * types of addresses:\\n *\\n * - an externally-owned account\\n * - a contract in construction\\n * - an address where a contract will be created\\n * - an address where a contract lived, but was destroyed\\n * ====\\n *\\n * [IMPORTANT]\\n * ====\\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\\n *\\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\\n * constructor.\\n * ====\\n */\\n function isContract(address account) internal view returns (bool) {\\n // This method relies on extcodesize/address.code.length, which returns 0\\n // for contracts in construction, since the code is only stored at the end\\n // of the constructor execution.\\n\\n return account.code.length > 0;\\n }\\n\\n /**\\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\\n * `recipient`, forwarding all available gas and reverting on errors.\\n *\\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\\n * imposed by `transfer`, making them unable to receive funds via\\n * `transfer`. {sendValue} removes this limitation.\\n *\\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\\n *\\n * IMPORTANT: because control is transferred to `recipient`, care must be\\n * taken to not create reentrancy vulnerabilities. Consider using\\n * {ReentrancyGuard} or the\\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\\n */\\n function sendValue(address payable recipient, uint256 amount) internal {\\n require(address(this).balance >= amount, \\\"Address: insufficient balance\\\");\\n\\n (bool success, ) = recipient.call{value: amount}(\\\"\\\");\\n require(success, \\\"Address: unable to send value, recipient may have reverted\\\");\\n }\\n\\n /**\\n * @dev Performs a Solidity function call using a low level `call`. A\\n * plain `call` is an unsafe replacement for a function call: use this\\n * function instead.\\n *\\n * If `target` reverts with a revert reason, it is bubbled up by this\\n * function (like regular Solidity function calls).\\n *\\n * Returns the raw returned data. To convert to the expected return value,\\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\\n *\\n * Requirements:\\n *\\n * - `target` must be a contract.\\n * - calling `target` with `data` must not revert.\\n *\\n * _Available since v3.1._\\n */\\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\\n return functionCall(target, data, \\\"Address: low-level call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\\n * `errorMessage` as a fallback revert reason when `target` reverts.\\n *\\n * _Available since v3.1._\\n */\\n function functionCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n return functionCallWithValue(target, data, 0, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but also transferring `value` wei to `target`.\\n *\\n * Requirements:\\n *\\n * - the calling contract must have an ETH balance of at least `value`.\\n * - the called Solidity function must be `payable`.\\n *\\n * _Available since v3.1._\\n */\\n function functionCallWithValue(\\n address target,\\n bytes memory data,\\n uint256 value\\n ) internal returns (bytes memory) {\\n return functionCallWithValue(target, data, value, \\\"Address: low-level call with value failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\\n * with `errorMessage` as a fallback revert reason when `target` reverts.\\n *\\n * _Available since v3.1._\\n */\\n function functionCallWithValue(\\n address target,\\n bytes memory data,\\n uint256 value,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n require(address(this).balance >= value, \\\"Address: insufficient balance for call\\\");\\n require(isContract(target), \\\"Address: call to non-contract\\\");\\n\\n (bool success, bytes memory returndata) = target.call{value: value}(data);\\n return verifyCallResult(success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but performing a static call.\\n *\\n * _Available since v3.3._\\n */\\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\\n return functionStaticCall(target, data, \\\"Address: low-level static call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\\n * but performing a static call.\\n *\\n * _Available since v3.3._\\n */\\n function functionStaticCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal view returns (bytes memory) {\\n require(isContract(target), \\\"Address: static call to non-contract\\\");\\n\\n (bool success, bytes memory returndata) = target.staticcall(data);\\n return verifyCallResult(success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but performing a delegate call.\\n *\\n * _Available since v3.4._\\n */\\n function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {\\n return functionDelegateCall(target, data, \\\"Address: low-level delegate call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\\n * but performing a delegate call.\\n *\\n * _Available since v3.4._\\n */\\n function functionDelegateCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n require(isContract(target), \\\"Address: delegate call to non-contract\\\");\\n\\n (bool success, bytes memory returndata) = target.delegatecall(data);\\n return verifyCallResult(success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the\\n * revert reason using the provided one.\\n *\\n * _Available since v4.3._\\n */\\n function verifyCallResult(\\n bool success,\\n bytes memory returndata,\\n string memory errorMessage\\n ) internal pure returns (bytes memory) {\\n if (success) {\\n return returndata;\\n } else {\\n // Look for revert reason and bubble it up if present\\n if (returndata.length > 0) {\\n // The easiest way to bubble the revert reason is using memory via assembly\\n /// @solidity memory-safe-assembly\\n assembly {\\n let returndata_size := mload(returndata)\\n revert(add(32, returndata), returndata_size)\\n }\\n } else {\\n revert(errorMessage);\\n }\\n }\\n }\\n}\\n\",\"keccak256\":\"0xd6153ce99bcdcce22b124f755e72553295be6abcd63804cfdffceb188b8bef10\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/StorageSlot.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.7.0) (utils/StorageSlot.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Library for reading and writing primitive types to specific storage slots.\\n *\\n * Storage slots are often used to avoid storage conflict when dealing with upgradeable contracts.\\n * This library helps with reading and writing to such slots without the need for inline assembly.\\n *\\n * The functions in this library return Slot structs that contain a `value` member that can be used to read or write.\\n *\\n * Example usage to set ERC1967 implementation slot:\\n * ```\\n * contract ERC1967 {\\n * bytes32 internal constant _IMPLEMENTATION_SLOT = 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc;\\n *\\n * function _getImplementation() internal view returns (address) {\\n * return StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value;\\n * }\\n *\\n * function _setImplementation(address newImplementation) internal {\\n * require(Address.isContract(newImplementation), \\\"ERC1967: new implementation is not a contract\\\");\\n * StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value = newImplementation;\\n * }\\n * }\\n * ```\\n *\\n * _Available since v4.1 for `address`, `bool`, `bytes32`, and `uint256`._\\n */\\nlibrary StorageSlot {\\n struct AddressSlot {\\n address value;\\n }\\n\\n struct BooleanSlot {\\n bool value;\\n }\\n\\n struct Bytes32Slot {\\n bytes32 value;\\n }\\n\\n struct Uint256Slot {\\n uint256 value;\\n }\\n\\n /**\\n * @dev Returns an `AddressSlot` with member `value` located at `slot`.\\n */\\n function getAddressSlot(bytes32 slot) internal pure returns (AddressSlot storage r) {\\n /// @solidity memory-safe-assembly\\n assembly {\\n r.slot := slot\\n }\\n }\\n\\n /**\\n * @dev Returns an `BooleanSlot` with member `value` located at `slot`.\\n */\\n function getBooleanSlot(bytes32 slot) internal pure returns (BooleanSlot storage r) {\\n /// @solidity memory-safe-assembly\\n assembly {\\n r.slot := slot\\n }\\n }\\n\\n /**\\n * @dev Returns an `Bytes32Slot` with member `value` located at `slot`.\\n */\\n function getBytes32Slot(bytes32 slot) internal pure returns (Bytes32Slot storage r) {\\n /// @solidity memory-safe-assembly\\n assembly {\\n r.slot := slot\\n }\\n }\\n\\n /**\\n * @dev Returns an `Uint256Slot` with member `value` located at `slot`.\\n */\\n function getUint256Slot(bytes32 slot) internal pure returns (Uint256Slot storage r) {\\n /// @solidity memory-safe-assembly\\n assembly {\\n r.slot := slot\\n }\\n }\\n}\\n\",\"keccak256\":\"0xd5c50c54bf02740ebd122ff06832546cb5fa84486d52695a9ccfd11666e0c81d\",\"license\":\"MIT\"},\"contracts/external/TransparentUpgradeableProxy.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-3.0\\n\\npragma solidity ^0.8.12;\\n\\nimport \\\"@openzeppelin/contracts/proxy/ERC1967/ERC1967Proxy.sol\\\";\\n\\n/**\\n * @dev This contract implements a proxy that is upgradeable by an admin. It is fully forked from OpenZeppelin\\n * `TransparentUpgradeableProxy`\\n *\\n * To avoid https://medium.com/nomic-labs-blog/malicious-backdoors-in-ethereum-proxies-62629adf3357[proxy selector\\n * clashing], which can potentially be used in an attack, this contract uses the\\n * https://blog.openzeppelin.com/the-transparent-proxy-pattern/[transparent proxy pattern]. This pattern implies two\\n * things that go hand in hand:\\n *\\n * 1. If any account other than the admin calls the proxy, the call will be forwarded to the implementation, even if\\n * that call matches one of the admin functions exposed by the proxy itself.\\n * 2. If the admin calls the proxy, it can access the admin functions, but its calls will never be forwarded to the\\n * implementation. If the admin tries to call a function on the implementation it will fail with an error that says\\n * \\\"admin cannot fallback to proxy target\\\".\\n *\\n * These properties mean that the admin account can only be used for admin actions like upgrading the proxy or changing\\n * the admin, so it's best if it's a dedicated account that is not used for anything else. This will avoid headaches due\\n * to sudden errors when trying to call a function from the proxy implementation.\\n *\\n * Our recommendation is for the dedicated account to be an instance of the {ProxyAdmin} contract. If set up this way,\\n * you should think of the `ProxyAdmin` instance as the real administrative interface of your proxy.\\n */\\ncontract TransparentUpgradeableProxy is ERC1967Proxy {\\n /**\\n * @dev Initializes an upgradeable proxy managed by `_admin`, backed by the implementation at `_logic`, and\\n * optionally initialized with `_data` as explained in {ERC1967Proxy-constructor}.\\n */\\n constructor(address _logic, address admin_, bytes memory _data) payable ERC1967Proxy(_logic, _data) {\\n assert(_ADMIN_SLOT == bytes32(uint256(keccak256(\\\"eip1967.proxy.admin\\\")) - 1));\\n _changeAdmin(admin_);\\n }\\n\\n /**\\n * @dev Modifier used internally that will delegate the call to the implementation unless the sender is the admin.\\n */\\n modifier ifAdmin() {\\n if (msg.sender == _getAdmin()) {\\n _;\\n } else {\\n _fallback();\\n }\\n }\\n\\n /**\\n * @dev Returns the current admin.\\n *\\n * NOTE: Only the admin can call this function. See {ProxyAdmin-getProxyAdmin}.\\n *\\n * TIP: To get this value clients can read directly from the storage slot shown below (specified by EIP1967) using the\\n * https://eth.wiki/json-rpc/API#eth_getstorageat[`eth_getStorageAt`] RPC call.\\n * `0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103`\\n */\\n function admin() external ifAdmin returns (address admin_) {\\n admin_ = _getAdmin();\\n }\\n\\n /**\\n * @dev Returns the current implementation.\\n *\\n * NOTE: Only the admin can call this function. See {ProxyAdmin-getProxyImplementation}.\\n *\\n * TIP: To get this value clients can read directly from the storage slot shown below (specified by EIP1967) using the\\n * https://eth.wiki/json-rpc/API#eth_getstorageat[`eth_getStorageAt`] RPC call.\\n * `0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc`\\n */\\n function implementation() external ifAdmin returns (address implementation_) {\\n implementation_ = _implementation();\\n }\\n\\n /**\\n * @dev Changes the admin of the proxy.\\n *\\n * Emits an {AdminChanged} event.\\n *\\n * NOTE: Only the admin can call this function. See {ProxyAdmin-changeProxyAdmin}.\\n */\\n function changeAdmin(address newAdmin) external virtual ifAdmin {\\n _changeAdmin(newAdmin);\\n }\\n\\n /**\\n * @dev Upgrade the implementation of the proxy.\\n *\\n * NOTE: Only the admin can call this function. See {ProxyAdmin-upgrade}.\\n */\\n function upgradeTo(address newImplementation) external ifAdmin {\\n _upgradeToAndCall(newImplementation, bytes(\\\"\\\"), false);\\n }\\n\\n /**\\n * @dev Upgrade the implementation of the proxy, and then call a function from the new implementation as specified\\n * by `data`, which should be an encoded function call. This is useful to initialize new storage variables in the\\n * proxied contract.\\n *\\n * NOTE: Only the admin can call this function. See {ProxyAdmin-upgradeAndCall}.\\n */\\n function upgradeToAndCall(address newImplementation, bytes calldata data) external payable ifAdmin {\\n _upgradeToAndCall(newImplementation, data, true);\\n }\\n\\n /**\\n * @dev Returns the current admin.\\n */\\n function _admin() internal view virtual returns (address) {\\n return _getAdmin();\\n }\\n\\n /**\\n * @dev Makes sure the admin cannot access the fallback function. See {Proxy-_beforeFallback}.\\n */\\n function _beforeFallback() internal virtual override {\\n require(msg.sender != _getAdmin(), \\\"TransparentUpgradeableProxy: admin cannot fallback to proxy target\\\");\\n super._beforeFallback();\\n }\\n}\\n\",\"keccak256\":\"0x93a67a0f612ea3ff2a76315e138a6a88267270a1379d3cc7be52845fbbe611e2\",\"license\":\"GPL-3.0\"}},\"version\":1}", + "bytecode": "0x6080604052604051620010bb380380620010bb8339810160408190526200002691620004d8565b828162000036828260006200009a565b5062000066905060017fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6104620005b8565b6000805160206200107483398151915214620000865762000086620005da565b6200009182620000d7565b50505062000643565b620000a58362000132565b600082511180620000b35750805b15620000d257620000d083836200017460201b6200028c1760201c565b505b505050565b7f7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f62000102620001a5565b604080516001600160a01b03928316815291841660208301520160405180910390a16200012f81620001de565b50565b6200013d8162000293565b6040516001600160a01b038216907fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b90600090a250565b60606200019c8383604051806060016040528060278152602001620010946027913962000347565b90505b92915050565b6000620001cf6000805160206200107483398151915260001b6200042f60201b6200022e1760201c565b546001600160a01b0316919050565b6001600160a01b038116620002495760405162461bcd60e51b815260206004820152602660248201527f455243313936373a206e65772061646d696e20697320746865207a65726f206160448201526564647265737360d01b60648201526084015b60405180910390fd5b80620002726000805160206200107483398151915260001b6200042f60201b6200022e1760201c565b80546001600160a01b0319166001600160a01b039290921691909117905550565b620002a9816200043260201b620002b81760201c565b6200030d5760405162461bcd60e51b815260206004820152602d60248201527f455243313936373a206e657720696d706c656d656e746174696f6e206973206e60448201526c1bdd08184818dbdb9d1c9858dd609a1b606482015260840162000240565b80620002727f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc60001b6200042f60201b6200022e1760201c565b60606001600160a01b0384163b620003b15760405162461bcd60e51b815260206004820152602660248201527f416464726573733a2064656c65676174652063616c6c20746f206e6f6e2d636f6044820152651b9d1c9858dd60d21b606482015260840162000240565b600080856001600160a01b031685604051620003ce9190620005f0565b600060405180830381855af49150503d80600081146200040b576040519150601f19603f3d011682016040523d82523d6000602084013e62000410565b606091505b5090925090506200042382828662000441565b925050505b9392505050565b90565b6001600160a01b03163b151590565b606083156200045257508162000428565b825115620004635782518084602001fd5b8160405162461bcd60e51b81526004016200024091906200060e565b80516001600160a01b03811681146200049757600080fd5b919050565b634e487b7160e01b600052604160045260246000fd5b60005b83811015620004cf578181015183820152602001620004b5565b50506000910152565b600080600060608486031215620004ee57600080fd5b620004f9846200047f565b925062000509602085016200047f565b60408501519092506001600160401b03808211156200052757600080fd5b818601915086601f8301126200053c57600080fd5b8151818111156200055157620005516200049c565b604051601f8201601f19908116603f011681019083821181831017156200057c576200057c6200049c565b816040528281528960208487010111156200059657600080fd5b620005a9836020830160208801620004b2565b80955050505050509250925092565b818103818111156200019f57634e487b7160e01b600052601160045260246000fd5b634e487b7160e01b600052600160045260246000fd5b6000825162000604818460208701620004b2565b9190910192915050565b60208152600082518060208401526200062f816040850160208701620004b2565b601f01601f19169190910160400192915050565b610a2180620006536000396000f3fe60806040526004361061005e5760003560e01c80635c60da1b116100435780635c60da1b146100a85780638f283970146100e6578063f851a440146101065761006d565b80633659cfe6146100755780634f1ef286146100955761006d565b3661006d5761006b61011b565b005b61006b61011b565b34801561008157600080fd5b5061006b610090366004610895565b610135565b61006b6100a33660046108b0565b61017f565b3480156100b457600080fd5b506100bd6101f3565b60405173ffffffffffffffffffffffffffffffffffffffff909116815260200160405180910390f35b3480156100f257600080fd5b5061006b610101366004610895565b610231565b34801561011257600080fd5b506100bd61025e565b6101236102d4565b61013361012e6103ab565b6103b5565b565b61013d6103d9565b73ffffffffffffffffffffffffffffffffffffffff1633036101775761017481604051806020016040528060008152506000610419565b50565b61017461011b565b6101876103d9565b73ffffffffffffffffffffffffffffffffffffffff1633036101eb576101e68383838080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525060019250610419915050565b505050565b6101e661011b565b60006101fd6103d9565b73ffffffffffffffffffffffffffffffffffffffff163303610226576102216103ab565b905090565b61022e61011b565b90565b6102396103d9565b73ffffffffffffffffffffffffffffffffffffffff1633036101775761017481610444565b60006102686103d9565b73ffffffffffffffffffffffffffffffffffffffff163303610226576102216103d9565b60606102b183836040518060600160405280602781526020016109c5602791396104a5565b9392505050565b73ffffffffffffffffffffffffffffffffffffffff163b151590565b6102dc6103d9565b73ffffffffffffffffffffffffffffffffffffffff163303610133576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604260248201527f5472616e73706172656e745570677261646561626c6550726f78793a2061646d60448201527f696e2063616e6e6f742066616c6c6261636b20746f2070726f7879207461726760648201527f6574000000000000000000000000000000000000000000000000000000000000608482015260a4015b60405180910390fd5b60006102216105cd565b3660008037600080366000845af43d6000803e8080156103d4573d6000f35b3d6000fd5b60007fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035b5473ffffffffffffffffffffffffffffffffffffffff16919050565b610422836105f5565b60008251118061042f5750805b156101e65761043e838361028c565b50505050565b7f7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f61046d6103d9565b6040805173ffffffffffffffffffffffffffffffffffffffff928316815291841660208301520160405180910390a161017481610642565b606073ffffffffffffffffffffffffffffffffffffffff84163b61054b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f416464726573733a2064656c65676174652063616c6c20746f206e6f6e2d636f60448201527f6e7472616374000000000000000000000000000000000000000000000000000060648201526084016103a2565b6000808573ffffffffffffffffffffffffffffffffffffffff16856040516105739190610957565b600060405180830381855af49150503d80600081146105ae576040519150601f19603f3d011682016040523d82523d6000602084013e6105b3565b606091505b50915091506105c382828661074e565b9695505050505050565b60007f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc6103fd565b6105fe816107a1565b60405173ffffffffffffffffffffffffffffffffffffffff8216907fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b90600090a250565b73ffffffffffffffffffffffffffffffffffffffff81166106e5576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f455243313936373a206e65772061646d696e20697320746865207a65726f206160448201527f646472657373000000000000000000000000000000000000000000000000000060648201526084016103a2565b807fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035b80547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff9290921691909117905550565b6060831561075d5750816102b1565b82511561076d5782518084602001fd5b816040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016103a29190610973565b73ffffffffffffffffffffffffffffffffffffffff81163b610845576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602d60248201527f455243313936373a206e657720696d706c656d656e746174696f6e206973206e60448201527f6f74206120636f6e74726163740000000000000000000000000000000000000060648201526084016103a2565b807f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc610708565b803573ffffffffffffffffffffffffffffffffffffffff8116811461089057600080fd5b919050565b6000602082840312156108a757600080fd5b6102b18261086c565b6000806000604084860312156108c557600080fd5b6108ce8461086c565b9250602084013567ffffffffffffffff808211156108eb57600080fd5b818601915086601f8301126108ff57600080fd5b81358181111561090e57600080fd5b87602082850101111561092057600080fd5b6020830194508093505050509250925092565b60005b8381101561094e578181015183820152602001610936565b50506000910152565b60008251610969818460208701610933565b9190910192915050565b6020815260008251806020840152610992816040850160208701610933565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016919091016040019291505056fe416464726573733a206c6f772d6c6576656c2064656c65676174652063616c6c206661696c6564a2646970667358221220e96638b07fb1675d93a95c49e417bc8111448b23a59918698cdcd8fd488dd7cf64736f6c63430008110033b53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103416464726573733a206c6f772d6c6576656c2064656c65676174652063616c6c206661696c6564", + "deployedBytecode": "0x60806040526004361061005e5760003560e01c80635c60da1b116100435780635c60da1b146100a85780638f283970146100e6578063f851a440146101065761006d565b80633659cfe6146100755780634f1ef286146100955761006d565b3661006d5761006b61011b565b005b61006b61011b565b34801561008157600080fd5b5061006b610090366004610895565b610135565b61006b6100a33660046108b0565b61017f565b3480156100b457600080fd5b506100bd6101f3565b60405173ffffffffffffffffffffffffffffffffffffffff909116815260200160405180910390f35b3480156100f257600080fd5b5061006b610101366004610895565b610231565b34801561011257600080fd5b506100bd61025e565b6101236102d4565b61013361012e6103ab565b6103b5565b565b61013d6103d9565b73ffffffffffffffffffffffffffffffffffffffff1633036101775761017481604051806020016040528060008152506000610419565b50565b61017461011b565b6101876103d9565b73ffffffffffffffffffffffffffffffffffffffff1633036101eb576101e68383838080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525060019250610419915050565b505050565b6101e661011b565b60006101fd6103d9565b73ffffffffffffffffffffffffffffffffffffffff163303610226576102216103ab565b905090565b61022e61011b565b90565b6102396103d9565b73ffffffffffffffffffffffffffffffffffffffff1633036101775761017481610444565b60006102686103d9565b73ffffffffffffffffffffffffffffffffffffffff163303610226576102216103d9565b60606102b183836040518060600160405280602781526020016109c5602791396104a5565b9392505050565b73ffffffffffffffffffffffffffffffffffffffff163b151590565b6102dc6103d9565b73ffffffffffffffffffffffffffffffffffffffff163303610133576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604260248201527f5472616e73706172656e745570677261646561626c6550726f78793a2061646d60448201527f696e2063616e6e6f742066616c6c6261636b20746f2070726f7879207461726760648201527f6574000000000000000000000000000000000000000000000000000000000000608482015260a4015b60405180910390fd5b60006102216105cd565b3660008037600080366000845af43d6000803e8080156103d4573d6000f35b3d6000fd5b60007fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035b5473ffffffffffffffffffffffffffffffffffffffff16919050565b610422836105f5565b60008251118061042f5750805b156101e65761043e838361028c565b50505050565b7f7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f61046d6103d9565b6040805173ffffffffffffffffffffffffffffffffffffffff928316815291841660208301520160405180910390a161017481610642565b606073ffffffffffffffffffffffffffffffffffffffff84163b61054b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f416464726573733a2064656c65676174652063616c6c20746f206e6f6e2d636f60448201527f6e7472616374000000000000000000000000000000000000000000000000000060648201526084016103a2565b6000808573ffffffffffffffffffffffffffffffffffffffff16856040516105739190610957565b600060405180830381855af49150503d80600081146105ae576040519150601f19603f3d011682016040523d82523d6000602084013e6105b3565b606091505b50915091506105c382828661074e565b9695505050505050565b60007f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc6103fd565b6105fe816107a1565b60405173ffffffffffffffffffffffffffffffffffffffff8216907fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b90600090a250565b73ffffffffffffffffffffffffffffffffffffffff81166106e5576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f455243313936373a206e65772061646d696e20697320746865207a65726f206160448201527f646472657373000000000000000000000000000000000000000000000000000060648201526084016103a2565b807fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035b80547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff9290921691909117905550565b6060831561075d5750816102b1565b82511561076d5782518084602001fd5b816040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016103a29190610973565b73ffffffffffffffffffffffffffffffffffffffff81163b610845576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602d60248201527f455243313936373a206e657720696d706c656d656e746174696f6e206973206e60448201527f6f74206120636f6e74726163740000000000000000000000000000000000000060648201526084016103a2565b807f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc610708565b803573ffffffffffffffffffffffffffffffffffffffff8116811461089057600080fd5b919050565b6000602082840312156108a757600080fd5b6102b18261086c565b6000806000604084860312156108c557600080fd5b6108ce8461086c565b9250602084013567ffffffffffffffff808211156108eb57600080fd5b818601915086601f8301126108ff57600080fd5b81358181111561090e57600080fd5b87602082850101111561092057600080fd5b6020830194508093505050509250925092565b60005b8381101561094e578181015183820152602001610936565b50506000910152565b60008251610969818460208701610933565b9190910192915050565b6020815260008251806020840152610992816040850160208701610933565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016919091016040019291505056fe416464726573733a206c6f772d6c6576656c2064656c65676174652063616c6c206661696c6564a2646970667358221220e96638b07fb1675d93a95c49e417bc8111448b23a59918698cdcd8fd488dd7cf64736f6c63430008110033", + "devdoc": { + "details": "This contract implements a proxy that is upgradeable by an admin. It is fully forked from OpenZeppelin `TransparentUpgradeableProxy` To avoid https://medium.com/nomic-labs-blog/malicious-backdoors-in-ethereum-proxies-62629adf3357[proxy selector clashing], which can potentially be used in an attack, this contract uses the https://blog.openzeppelin.com/the-transparent-proxy-pattern/[transparent proxy pattern]. This pattern implies two things that go hand in hand: 1. If any account other than the admin calls the proxy, the call will be forwarded to the implementation, even if that call matches one of the admin functions exposed by the proxy itself. 2. If the admin calls the proxy, it can access the admin functions, but its calls will never be forwarded to the implementation. If the admin tries to call a function on the implementation it will fail with an error that says \"admin cannot fallback to proxy target\". These properties mean that the admin account can only be used for admin actions like upgrading the proxy or changing the admin, so it's best if it's a dedicated account that is not used for anything else. This will avoid headaches due to sudden errors when trying to call a function from the proxy implementation. Our recommendation is for the dedicated account to be an instance of the {ProxyAdmin} contract. If set up this way, you should think of the `ProxyAdmin` instance as the real administrative interface of your proxy.", + "kind": "dev", + "methods": { + "admin()": { + "details": "Returns the current admin. NOTE: Only the admin can call this function. See {ProxyAdmin-getProxyAdmin}. TIP: To get this value clients can read directly from the storage slot shown below (specified by EIP1967) using the https://eth.wiki/json-rpc/API#eth_getstorageat[`eth_getStorageAt`] RPC call. `0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103`" + }, + "changeAdmin(address)": { + "details": "Changes the admin of the proxy. Emits an {AdminChanged} event. NOTE: Only the admin can call this function. See {ProxyAdmin-changeProxyAdmin}." + }, + "constructor": { + "details": "Initializes an upgradeable proxy managed by `_admin`, backed by the implementation at `_logic`, and optionally initialized with `_data` as explained in {ERC1967Proxy-constructor}." + }, + "implementation()": { + "details": "Returns the current implementation. NOTE: Only the admin can call this function. See {ProxyAdmin-getProxyImplementation}. TIP: To get this value clients can read directly from the storage slot shown below (specified by EIP1967) using the https://eth.wiki/json-rpc/API#eth_getstorageat[`eth_getStorageAt`] RPC call. `0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc`" + }, + "upgradeTo(address)": { + "details": "Upgrade the implementation of the proxy. NOTE: Only the admin can call this function. See {ProxyAdmin-upgrade}." + }, + "upgradeToAndCall(address,bytes)": { + "details": "Upgrade the implementation of the proxy, and then call a function from the new implementation as specified by `data`, which should be an encoded function call. This is useful to initialize new storage variables in the proxied contract. NOTE: Only the admin can call this function. See {ProxyAdmin-upgradeAndCall}." + } + }, + "version": 1 + }, + "userdoc": { + "kind": "user", + "methods": {}, + "version": 1 + }, + "storageLayout": { + "storage": [], + "types": null + } +} \ No newline at end of file diff --git a/deployments/base/solcInputs/871924e0c138825a2736b76def8fef8d.json b/deployments/base/solcInputs/871924e0c138825a2736b76def8fef8d.json new file mode 100644 index 00000000..57454028 --- /dev/null +++ b/deployments/base/solcInputs/871924e0c138825a2736b76def8fef8d.json @@ -0,0 +1,562 @@ +{ + "language": "Solidity", + "sources": { + "@chainlink/contracts/src/v0.8/interfaces/AggregatorV3Interface.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.0;\n\ninterface AggregatorV3Interface {\n\n function decimals()\n external\n view\n returns (\n uint8\n );\n\n function description()\n external\n view\n returns (\n string memory\n );\n\n function version()\n external\n view\n returns (\n uint256\n );\n\n // getRoundData and latestRoundData should both raise \"No data present\"\n // if they do not have data to report, instead of returning unset values\n // which could be misinterpreted as actual reported values.\n function getRoundData(\n uint80 _roundId\n )\n external\n view\n returns (\n uint80 roundId,\n int256 answer,\n uint256 startedAt,\n uint256 updatedAt,\n uint80 answeredInRound\n );\n\n function latestRoundData()\n external\n view\n returns (\n uint80 roundId,\n int256 answer,\n uint256 startedAt,\n uint256 updatedAt,\n uint80 answeredInRound\n );\n\n}\n" + }, + "@openzeppelin/contracts-upgradeable/access/AccessControlEnumerableUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.5.0) (access/AccessControlEnumerable.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./IAccessControlEnumerableUpgradeable.sol\";\nimport \"./AccessControlUpgradeable.sol\";\nimport \"../utils/structs/EnumerableSetUpgradeable.sol\";\nimport \"../proxy/utils/Initializable.sol\";\n\n/**\n * @dev Extension of {AccessControl} that allows enumerating the members of each role.\n */\nabstract contract AccessControlEnumerableUpgradeable is Initializable, IAccessControlEnumerableUpgradeable, AccessControlUpgradeable {\n function __AccessControlEnumerable_init() internal onlyInitializing {\n }\n\n function __AccessControlEnumerable_init_unchained() internal onlyInitializing {\n }\n using EnumerableSetUpgradeable for EnumerableSetUpgradeable.AddressSet;\n\n mapping(bytes32 => EnumerableSetUpgradeable.AddressSet) private _roleMembers;\n\n /**\n * @dev See {IERC165-supportsInterface}.\n */\n function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {\n return interfaceId == type(IAccessControlEnumerableUpgradeable).interfaceId || super.supportsInterface(interfaceId);\n }\n\n /**\n * @dev Returns one of the accounts that have `role`. `index` must be a\n * value between 0 and {getRoleMemberCount}, non-inclusive.\n *\n * Role bearers are not sorted in any particular way, and their ordering may\n * change at any point.\n *\n * WARNING: When using {getRoleMember} and {getRoleMemberCount}, make sure\n * you perform all queries on the same block. See the following\n * https://forum.openzeppelin.com/t/iterating-over-elements-on-enumerableset-in-openzeppelin-contracts/2296[forum post]\n * for more information.\n */\n function getRoleMember(bytes32 role, uint256 index) public view virtual override returns (address) {\n return _roleMembers[role].at(index);\n }\n\n /**\n * @dev Returns the number of accounts that have `role`. Can be used\n * together with {getRoleMember} to enumerate all bearers of a role.\n */\n function getRoleMemberCount(bytes32 role) public view virtual override returns (uint256) {\n return _roleMembers[role].length();\n }\n\n /**\n * @dev Overload {_grantRole} to track enumerable memberships\n */\n function _grantRole(bytes32 role, address account) internal virtual override {\n super._grantRole(role, account);\n _roleMembers[role].add(account);\n }\n\n /**\n * @dev Overload {_revokeRole} to track enumerable memberships\n */\n function _revokeRole(bytes32 role, address account) internal virtual override {\n super._revokeRole(role, account);\n _roleMembers[role].remove(account);\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[49] private __gap;\n}\n" + }, + "@openzeppelin/contracts-upgradeable/access/AccessControlUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (access/AccessControl.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./IAccessControlUpgradeable.sol\";\nimport \"../utils/ContextUpgradeable.sol\";\nimport \"../utils/StringsUpgradeable.sol\";\nimport \"../utils/introspection/ERC165Upgradeable.sol\";\nimport \"../proxy/utils/Initializable.sol\";\n\n/**\n * @dev Contract module that allows children to implement role-based access\n * control mechanisms. This is a lightweight version that doesn't allow enumerating role\n * members except through off-chain means by accessing the contract event logs. Some\n * applications may benefit from on-chain enumerability, for those cases see\n * {AccessControlEnumerable}.\n *\n * Roles are referred to by their `bytes32` identifier. These should be exposed\n * in the external API and be unique. The best way to achieve this is by\n * using `public constant` hash digests:\n *\n * ```\n * bytes32 public constant MY_ROLE = keccak256(\"MY_ROLE\");\n * ```\n *\n * Roles can be used to represent a set of permissions. To restrict access to a\n * function call, use {hasRole}:\n *\n * ```\n * function foo() public {\n * require(hasRole(MY_ROLE, msg.sender));\n * ...\n * }\n * ```\n *\n * Roles can be granted and revoked dynamically via the {grantRole} and\n * {revokeRole} functions. Each role has an associated admin role, and only\n * accounts that have a role's admin role can call {grantRole} and {revokeRole}.\n *\n * By default, the admin role for all roles is `DEFAULT_ADMIN_ROLE`, which means\n * that only accounts with this role will be able to grant or revoke other\n * roles. More complex role relationships can be created by using\n * {_setRoleAdmin}.\n *\n * WARNING: The `DEFAULT_ADMIN_ROLE` is also its own admin: it has permission to\n * grant and revoke this role. Extra precautions should be taken to secure\n * accounts that have been granted it.\n */\nabstract contract AccessControlUpgradeable is Initializable, ContextUpgradeable, IAccessControlUpgradeable, ERC165Upgradeable {\n function __AccessControl_init() internal onlyInitializing {\n }\n\n function __AccessControl_init_unchained() internal onlyInitializing {\n }\n struct RoleData {\n mapping(address => bool) members;\n bytes32 adminRole;\n }\n\n mapping(bytes32 => RoleData) private _roles;\n\n bytes32 public constant DEFAULT_ADMIN_ROLE = 0x00;\n\n /**\n * @dev Modifier that checks that an account has a specific role. Reverts\n * with a standardized message including the required role.\n *\n * The format of the revert reason is given by the following regular expression:\n *\n * /^AccessControl: account (0x[0-9a-f]{40}) is missing role (0x[0-9a-f]{64})$/\n *\n * _Available since v4.1._\n */\n modifier onlyRole(bytes32 role) {\n _checkRole(role);\n _;\n }\n\n /**\n * @dev See {IERC165-supportsInterface}.\n */\n function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {\n return interfaceId == type(IAccessControlUpgradeable).interfaceId || super.supportsInterface(interfaceId);\n }\n\n /**\n * @dev Returns `true` if `account` has been granted `role`.\n */\n function hasRole(bytes32 role, address account) public view virtual override returns (bool) {\n return _roles[role].members[account];\n }\n\n /**\n * @dev Revert with a standard message if `_msgSender()` is missing `role`.\n * Overriding this function changes the behavior of the {onlyRole} modifier.\n *\n * Format of the revert message is described in {_checkRole}.\n *\n * _Available since v4.6._\n */\n function _checkRole(bytes32 role) internal view virtual {\n _checkRole(role, _msgSender());\n }\n\n /**\n * @dev Revert with a standard message if `account` is missing `role`.\n *\n * The format of the revert reason is given by the following regular expression:\n *\n * /^AccessControl: account (0x[0-9a-f]{40}) is missing role (0x[0-9a-f]{64})$/\n */\n function _checkRole(bytes32 role, address account) internal view virtual {\n if (!hasRole(role, account)) {\n revert(\n string(\n abi.encodePacked(\n \"AccessControl: account \",\n StringsUpgradeable.toHexString(uint160(account), 20),\n \" is missing role \",\n StringsUpgradeable.toHexString(uint256(role), 32)\n )\n )\n );\n }\n }\n\n /**\n * @dev Returns the admin role that controls `role`. See {grantRole} and\n * {revokeRole}.\n *\n * To change a role's admin, use {_setRoleAdmin}.\n */\n function getRoleAdmin(bytes32 role) public view virtual override returns (bytes32) {\n return _roles[role].adminRole;\n }\n\n /**\n * @dev Grants `role` to `account`.\n *\n * If `account` had not been already granted `role`, emits a {RoleGranted}\n * event.\n *\n * Requirements:\n *\n * - the caller must have ``role``'s admin role.\n *\n * May emit a {RoleGranted} event.\n */\n function grantRole(bytes32 role, address account) public virtual override onlyRole(getRoleAdmin(role)) {\n _grantRole(role, account);\n }\n\n /**\n * @dev Revokes `role` from `account`.\n *\n * If `account` had been granted `role`, emits a {RoleRevoked} event.\n *\n * Requirements:\n *\n * - the caller must have ``role``'s admin role.\n *\n * May emit a {RoleRevoked} event.\n */\n function revokeRole(bytes32 role, address account) public virtual override onlyRole(getRoleAdmin(role)) {\n _revokeRole(role, account);\n }\n\n /**\n * @dev Revokes `role` from the calling account.\n *\n * Roles are often managed via {grantRole} and {revokeRole}: this function's\n * purpose is to provide a mechanism for accounts to lose their privileges\n * if they are compromised (such as when a trusted device is misplaced).\n *\n * If the calling account had been revoked `role`, emits a {RoleRevoked}\n * event.\n *\n * Requirements:\n *\n * - the caller must be `account`.\n *\n * May emit a {RoleRevoked} event.\n */\n function renounceRole(bytes32 role, address account) public virtual override {\n require(account == _msgSender(), \"AccessControl: can only renounce roles for self\");\n\n _revokeRole(role, account);\n }\n\n /**\n * @dev Grants `role` to `account`.\n *\n * If `account` had not been already granted `role`, emits a {RoleGranted}\n * event. Note that unlike {grantRole}, this function doesn't perform any\n * checks on the calling account.\n *\n * May emit a {RoleGranted} event.\n *\n * [WARNING]\n * ====\n * This function should only be called from the constructor when setting\n * up the initial roles for the system.\n *\n * Using this function in any other way is effectively circumventing the admin\n * system imposed by {AccessControl}.\n * ====\n *\n * NOTE: This function is deprecated in favor of {_grantRole}.\n */\n function _setupRole(bytes32 role, address account) internal virtual {\n _grantRole(role, account);\n }\n\n /**\n * @dev Sets `adminRole` as ``role``'s admin role.\n *\n * Emits a {RoleAdminChanged} event.\n */\n function _setRoleAdmin(bytes32 role, bytes32 adminRole) internal virtual {\n bytes32 previousAdminRole = getRoleAdmin(role);\n _roles[role].adminRole = adminRole;\n emit RoleAdminChanged(role, previousAdminRole, adminRole);\n }\n\n /**\n * @dev Grants `role` to `account`.\n *\n * Internal function without access restriction.\n *\n * May emit a {RoleGranted} event.\n */\n function _grantRole(bytes32 role, address account) internal virtual {\n if (!hasRole(role, account)) {\n _roles[role].members[account] = true;\n emit RoleGranted(role, account, _msgSender());\n }\n }\n\n /**\n * @dev Revokes `role` from `account`.\n *\n * Internal function without access restriction.\n *\n * May emit a {RoleRevoked} event.\n */\n function _revokeRole(bytes32 role, address account) internal virtual {\n if (hasRole(role, account)) {\n _roles[role].members[account] = false;\n emit RoleRevoked(role, account, _msgSender());\n }\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[49] private __gap;\n}\n" + }, + "@openzeppelin/contracts-upgradeable/access/IAccessControlEnumerableUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (access/IAccessControlEnumerable.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./IAccessControlUpgradeable.sol\";\n\n/**\n * @dev External interface of AccessControlEnumerable declared to support ERC165 detection.\n */\ninterface IAccessControlEnumerableUpgradeable is IAccessControlUpgradeable {\n /**\n * @dev Returns one of the accounts that have `role`. `index` must be a\n * value between 0 and {getRoleMemberCount}, non-inclusive.\n *\n * Role bearers are not sorted in any particular way, and their ordering may\n * change at any point.\n *\n * WARNING: When using {getRoleMember} and {getRoleMemberCount}, make sure\n * you perform all queries on the same block. See the following\n * https://forum.openzeppelin.com/t/iterating-over-elements-on-enumerableset-in-openzeppelin-contracts/2296[forum post]\n * for more information.\n */\n function getRoleMember(bytes32 role, uint256 index) external view returns (address);\n\n /**\n * @dev Returns the number of accounts that have `role`. Can be used\n * together with {getRoleMember} to enumerate all bearers of a role.\n */\n function getRoleMemberCount(bytes32 role) external view returns (uint256);\n}\n" + }, + "@openzeppelin/contracts-upgradeable/access/IAccessControlUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (access/IAccessControl.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev External interface of AccessControl declared to support ERC165 detection.\n */\ninterface IAccessControlUpgradeable {\n /**\n * @dev Emitted when `newAdminRole` is set as ``role``'s admin role, replacing `previousAdminRole`\n *\n * `DEFAULT_ADMIN_ROLE` is the starting admin for all roles, despite\n * {RoleAdminChanged} not being emitted signaling this.\n *\n * _Available since v3.1._\n */\n event RoleAdminChanged(bytes32 indexed role, bytes32 indexed previousAdminRole, bytes32 indexed newAdminRole);\n\n /**\n * @dev Emitted when `account` is granted `role`.\n *\n * `sender` is the account that originated the contract call, an admin role\n * bearer except when using {AccessControl-_setupRole}.\n */\n event RoleGranted(bytes32 indexed role, address indexed account, address indexed sender);\n\n /**\n * @dev Emitted when `account` is revoked `role`.\n *\n * `sender` is the account that originated the contract call:\n * - if using `revokeRole`, it is the admin role bearer\n * - if using `renounceRole`, it is the role bearer (i.e. `account`)\n */\n event RoleRevoked(bytes32 indexed role, address indexed account, address indexed sender);\n\n /**\n * @dev Returns `true` if `account` has been granted `role`.\n */\n function hasRole(bytes32 role, address account) external view returns (bool);\n\n /**\n * @dev Returns the admin role that controls `role`. See {grantRole} and\n * {revokeRole}.\n *\n * To change a role's admin, use {AccessControl-_setRoleAdmin}.\n */\n function getRoleAdmin(bytes32 role) external view returns (bytes32);\n\n /**\n * @dev Grants `role` to `account`.\n *\n * If `account` had not been already granted `role`, emits a {RoleGranted}\n * event.\n *\n * Requirements:\n *\n * - the caller must have ``role``'s admin role.\n */\n function grantRole(bytes32 role, address account) external;\n\n /**\n * @dev Revokes `role` from `account`.\n *\n * If `account` had been granted `role`, emits a {RoleRevoked} event.\n *\n * Requirements:\n *\n * - the caller must have ``role``'s admin role.\n */\n function revokeRole(bytes32 role, address account) external;\n\n /**\n * @dev Revokes `role` from the calling account.\n *\n * Roles are often managed via {grantRole} and {revokeRole}: this function's\n * purpose is to provide a mechanism for accounts to lose their privileges\n * if they are compromised (such as when a trusted device is misplaced).\n *\n * If the calling account had been granted `role`, emits a {RoleRevoked}\n * event.\n *\n * Requirements:\n *\n * - the caller must be `account`.\n */\n function renounceRole(bytes32 role, address account) external;\n}\n" + }, + "@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (access/Ownable.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../utils/ContextUpgradeable.sol\";\nimport \"../proxy/utils/Initializable.sol\";\n\n/**\n * @dev Contract module which provides a basic access control mechanism, where\n * there is an account (an owner) that can be granted exclusive access to\n * specific functions.\n *\n * By default, the owner account will be the one that deploys the contract. This\n * can later be changed with {transferOwnership}.\n *\n * This module is used through inheritance. It will make available the modifier\n * `onlyOwner`, which can be applied to your functions to restrict their use to\n * the owner.\n */\nabstract contract OwnableUpgradeable is Initializable, ContextUpgradeable {\n address private _owner;\n\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\n\n /**\n * @dev Initializes the contract setting the deployer as the initial owner.\n */\n function __Ownable_init() internal onlyInitializing {\n __Ownable_init_unchained();\n }\n\n function __Ownable_init_unchained() internal onlyInitializing {\n _transferOwnership(_msgSender());\n }\n\n /**\n * @dev Throws if called by any account other than the owner.\n */\n modifier onlyOwner() {\n _checkOwner();\n _;\n }\n\n /**\n * @dev Returns the address of the current owner.\n */\n function owner() public view virtual returns (address) {\n return _owner;\n }\n\n /**\n * @dev Throws if the sender is not the owner.\n */\n function _checkOwner() internal view virtual {\n require(owner() == _msgSender(), \"Ownable: caller is not the owner\");\n }\n\n /**\n * @dev Leaves the contract without owner. It will not be possible to call\n * `onlyOwner` functions anymore. Can only be called by the current owner.\n *\n * NOTE: Renouncing ownership will leave the contract without an owner,\n * thereby removing any functionality that is only available to the owner.\n */\n function renounceOwnership() public virtual onlyOwner {\n _transferOwnership(address(0));\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Can only be called by the current owner.\n */\n function transferOwnership(address newOwner) public virtual onlyOwner {\n require(newOwner != address(0), \"Ownable: new owner is the zero address\");\n _transferOwnership(newOwner);\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Internal function without access restriction.\n */\n function _transferOwnership(address newOwner) internal virtual {\n address oldOwner = _owner;\n _owner = newOwner;\n emit OwnershipTransferred(oldOwner, newOwner);\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[49] private __gap;\n}\n" + }, + "@openzeppelin/contracts-upgradeable/interfaces/IERC721MetadataUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (interfaces/IERC721Metadata.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../token/ERC721/extensions/IERC721MetadataUpgradeable.sol\";\n" + }, + "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (proxy/utils/Initializable.sol)\n\npragma solidity ^0.8.2;\n\nimport \"../../utils/AddressUpgradeable.sol\";\n\n/**\n * @dev This is a base contract to aid in writing upgradeable contracts, or any kind of contract that will be deployed\n * behind a proxy. Since proxied contracts do not make use of a constructor, it's common to move constructor logic to an\n * external initializer function, usually called `initialize`. It then becomes necessary to protect this initializer\n * function so it can only be called once. The {initializer} modifier provided by this contract will have this effect.\n *\n * The initialization functions use a version number. Once a version number is used, it is consumed and cannot be\n * reused. This mechanism prevents re-execution of each \"step\" but allows the creation of new initialization steps in\n * case an upgrade adds a module that needs to be initialized.\n *\n * For example:\n *\n * [.hljs-theme-light.nopadding]\n * ```\n * contract MyToken is ERC20Upgradeable {\n * function initialize() initializer public {\n * __ERC20_init(\"MyToken\", \"MTK\");\n * }\n * }\n * contract MyTokenV2 is MyToken, ERC20PermitUpgradeable {\n * function initializeV2() reinitializer(2) public {\n * __ERC20Permit_init(\"MyToken\");\n * }\n * }\n * ```\n *\n * TIP: To avoid leaving the proxy in an uninitialized state, the initializer function should be called as early as\n * possible by providing the encoded function call as the `_data` argument to {ERC1967Proxy-constructor}.\n *\n * CAUTION: When used with inheritance, manual care must be taken to not invoke a parent initializer twice, or to ensure\n * that all initializers are idempotent. This is not verified automatically as constructors are by Solidity.\n *\n * [CAUTION]\n * ====\n * Avoid leaving a contract uninitialized.\n *\n * An uninitialized contract can be taken over by an attacker. This applies to both a proxy and its implementation\n * contract, which may impact the proxy. To prevent the implementation contract from being used, you should invoke\n * the {_disableInitializers} function in the constructor to automatically lock it when it is deployed:\n *\n * [.hljs-theme-light.nopadding]\n * ```\n * /// @custom:oz-upgrades-unsafe-allow constructor\n * constructor() {\n * _disableInitializers();\n * }\n * ```\n * ====\n */\nabstract contract Initializable {\n /**\n * @dev Indicates that the contract has been initialized.\n * @custom:oz-retyped-from bool\n */\n uint8 private _initialized;\n\n /**\n * @dev Indicates that the contract is in the process of being initialized.\n */\n bool private _initializing;\n\n /**\n * @dev Triggered when the contract has been initialized or reinitialized.\n */\n event Initialized(uint8 version);\n\n /**\n * @dev A modifier that defines a protected initializer function that can be invoked at most once. In its scope,\n * `onlyInitializing` functions can be used to initialize parent contracts. Equivalent to `reinitializer(1)`.\n */\n modifier initializer() {\n bool isTopLevelCall = !_initializing;\n require(\n (isTopLevelCall && _initialized < 1) || (!AddressUpgradeable.isContract(address(this)) && _initialized == 1),\n \"Initializable: contract is already initialized\"\n );\n _initialized = 1;\n if (isTopLevelCall) {\n _initializing = true;\n }\n _;\n if (isTopLevelCall) {\n _initializing = false;\n emit Initialized(1);\n }\n }\n\n /**\n * @dev A modifier that defines a protected reinitializer function that can be invoked at most once, and only if the\n * contract hasn't been initialized to a greater version before. In its scope, `onlyInitializing` functions can be\n * used to initialize parent contracts.\n *\n * `initializer` is equivalent to `reinitializer(1)`, so a reinitializer may be used after the original\n * initialization step. This is essential to configure modules that are added through upgrades and that require\n * initialization.\n *\n * Note that versions can jump in increments greater than 1; this implies that if multiple reinitializers coexist in\n * a contract, executing them in the right order is up to the developer or operator.\n */\n modifier reinitializer(uint8 version) {\n require(!_initializing && _initialized < version, \"Initializable: contract is already initialized\");\n _initialized = version;\n _initializing = true;\n _;\n _initializing = false;\n emit Initialized(version);\n }\n\n /**\n * @dev Modifier to protect an initialization function so that it can only be invoked by functions with the\n * {initializer} and {reinitializer} modifiers, directly or indirectly.\n */\n modifier onlyInitializing() {\n require(_initializing, \"Initializable: contract is not initializing\");\n _;\n }\n\n /**\n * @dev Locks the contract, preventing any future reinitialization. This cannot be part of an initializer call.\n * Calling this in the constructor of a contract will prevent that contract from being initialized or reinitialized\n * to any version. It is recommended to use this to lock implementation contracts that are designed to be called\n * through proxies.\n */\n function _disableInitializers() internal virtual {\n require(!_initializing, \"Initializable: contract is initializing\");\n if (_initialized < type(uint8).max) {\n _initialized = type(uint8).max;\n emit Initialized(type(uint8).max);\n }\n }\n}\n" + }, + "@openzeppelin/contracts-upgradeable/security/PausableUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (security/Pausable.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../utils/ContextUpgradeable.sol\";\nimport \"../proxy/utils/Initializable.sol\";\n\n/**\n * @dev Contract module which allows children to implement an emergency stop\n * mechanism that can be triggered by an authorized account.\n *\n * This module is used through inheritance. It will make available the\n * modifiers `whenNotPaused` and `whenPaused`, which can be applied to\n * the functions of your contract. Note that they will not be pausable by\n * simply including this module, only once the modifiers are put in place.\n */\nabstract contract PausableUpgradeable is Initializable, ContextUpgradeable {\n /**\n * @dev Emitted when the pause is triggered by `account`.\n */\n event Paused(address account);\n\n /**\n * @dev Emitted when the pause is lifted by `account`.\n */\n event Unpaused(address account);\n\n bool private _paused;\n\n /**\n * @dev Initializes the contract in unpaused state.\n */\n function __Pausable_init() internal onlyInitializing {\n __Pausable_init_unchained();\n }\n\n function __Pausable_init_unchained() internal onlyInitializing {\n _paused = false;\n }\n\n /**\n * @dev Modifier to make a function callable only when the contract is not paused.\n *\n * Requirements:\n *\n * - The contract must not be paused.\n */\n modifier whenNotPaused() {\n _requireNotPaused();\n _;\n }\n\n /**\n * @dev Modifier to make a function callable only when the contract is paused.\n *\n * Requirements:\n *\n * - The contract must be paused.\n */\n modifier whenPaused() {\n _requirePaused();\n _;\n }\n\n /**\n * @dev Returns true if the contract is paused, and false otherwise.\n */\n function paused() public view virtual returns (bool) {\n return _paused;\n }\n\n /**\n * @dev Throws if the contract is paused.\n */\n function _requireNotPaused() internal view virtual {\n require(!paused(), \"Pausable: paused\");\n }\n\n /**\n * @dev Throws if the contract is not paused.\n */\n function _requirePaused() internal view virtual {\n require(paused(), \"Pausable: not paused\");\n }\n\n /**\n * @dev Triggers stopped state.\n *\n * Requirements:\n *\n * - The contract must not be paused.\n */\n function _pause() internal virtual whenNotPaused {\n _paused = true;\n emit Paused(_msgSender());\n }\n\n /**\n * @dev Returns to normal state.\n *\n * Requirements:\n *\n * - The contract must be paused.\n */\n function _unpause() internal virtual whenPaused {\n _paused = false;\n emit Unpaused(_msgSender());\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[49] private __gap;\n}\n" + }, + "@openzeppelin/contracts-upgradeable/security/ReentrancyGuardUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (security/ReentrancyGuard.sol)\n\npragma solidity ^0.8.0;\nimport \"../proxy/utils/Initializable.sol\";\n\n/**\n * @dev Contract module that helps prevent reentrant calls to a function.\n *\n * Inheriting from `ReentrancyGuard` will make the {nonReentrant} modifier\n * available, which can be applied to functions to make sure there are no nested\n * (reentrant) calls to them.\n *\n * Note that because there is a single `nonReentrant` guard, functions marked as\n * `nonReentrant` may not call one another. This can be worked around by making\n * those functions `private`, and then adding `external` `nonReentrant` entry\n * points to them.\n *\n * TIP: If you would like to learn more about reentrancy and alternative ways\n * to protect against it, check out our blog post\n * https://blog.openzeppelin.com/reentrancy-after-istanbul/[Reentrancy After Istanbul].\n */\nabstract contract ReentrancyGuardUpgradeable is Initializable {\n // Booleans are more expensive than uint256 or any type that takes up a full\n // word because each write operation emits an extra SLOAD to first read the\n // slot's contents, replace the bits taken up by the boolean, and then write\n // back. This is the compiler's defense against contract upgrades and\n // pointer aliasing, and it cannot be disabled.\n\n // The values being non-zero value makes deployment a bit more expensive,\n // but in exchange the refund on every call to nonReentrant will be lower in\n // amount. Since refunds are capped to a percentage of the total\n // transaction's gas, it is best to keep them low in cases like this one, to\n // increase the likelihood of the full refund coming into effect.\n uint256 private constant _NOT_ENTERED = 1;\n uint256 private constant _ENTERED = 2;\n\n uint256 private _status;\n\n function __ReentrancyGuard_init() internal onlyInitializing {\n __ReentrancyGuard_init_unchained();\n }\n\n function __ReentrancyGuard_init_unchained() internal onlyInitializing {\n _status = _NOT_ENTERED;\n }\n\n /**\n * @dev Prevents a contract from calling itself, directly or indirectly.\n * Calling a `nonReentrant` function from another `nonReentrant`\n * function is not supported. It is possible to prevent this from happening\n * by making the `nonReentrant` function external, and making it call a\n * `private` function that does the actual work.\n */\n modifier nonReentrant() {\n // On the first call to nonReentrant, _notEntered will be true\n require(_status != _ENTERED, \"ReentrancyGuard: reentrant call\");\n\n // Any calls to nonReentrant after this point will fail\n _status = _ENTERED;\n\n _;\n\n // By storing the original value once again, a refund is triggered (see\n // https://eips.ethereum.org/EIPS/eip-2200)\n _status = _NOT_ENTERED;\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[49] private __gap;\n}\n" + }, + "@openzeppelin/contracts-upgradeable/token/ERC20/ERC20Upgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (token/ERC20/ERC20.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./IERC20Upgradeable.sol\";\nimport \"./extensions/IERC20MetadataUpgradeable.sol\";\nimport \"../../utils/ContextUpgradeable.sol\";\nimport \"../../proxy/utils/Initializable.sol\";\n\n/**\n * @dev Implementation of the {IERC20} interface.\n *\n * This implementation is agnostic to the way tokens are created. This means\n * that a supply mechanism has to be added in a derived contract using {_mint}.\n * For a generic mechanism see {ERC20PresetMinterPauser}.\n *\n * TIP: For a detailed writeup see our guide\n * https://forum.zeppelin.solutions/t/how-to-implement-erc20-supply-mechanisms/226[How\n * to implement supply mechanisms].\n *\n * We have followed general OpenZeppelin Contracts guidelines: functions revert\n * instead returning `false` on failure. This behavior is nonetheless\n * conventional and does not conflict with the expectations of ERC20\n * applications.\n *\n * Additionally, an {Approval} event is emitted on calls to {transferFrom}.\n * This allows applications to reconstruct the allowance for all accounts just\n * by listening to said events. Other implementations of the EIP may not emit\n * these events, as it isn't required by the specification.\n *\n * Finally, the non-standard {decreaseAllowance} and {increaseAllowance}\n * functions have been added to mitigate the well-known issues around setting\n * allowances. See {IERC20-approve}.\n */\ncontract ERC20Upgradeable is Initializable, ContextUpgradeable, IERC20Upgradeable, IERC20MetadataUpgradeable {\n mapping(address => uint256) private _balances;\n\n mapping(address => mapping(address => uint256)) private _allowances;\n\n uint256 private _totalSupply;\n\n string private _name;\n string private _symbol;\n\n /**\n * @dev Sets the values for {name} and {symbol}.\n *\n * The default value of {decimals} is 18. To select a different value for\n * {decimals} you should overload it.\n *\n * All two of these values are immutable: they can only be set once during\n * construction.\n */\n function __ERC20_init(string memory name_, string memory symbol_) internal onlyInitializing {\n __ERC20_init_unchained(name_, symbol_);\n }\n\n function __ERC20_init_unchained(string memory name_, string memory symbol_) internal onlyInitializing {\n _name = name_;\n _symbol = symbol_;\n }\n\n /**\n * @dev Returns the name of the token.\n */\n function name() public view virtual override returns (string memory) {\n return _name;\n }\n\n /**\n * @dev Returns the symbol of the token, usually a shorter version of the\n * name.\n */\n function symbol() public view virtual override returns (string memory) {\n return _symbol;\n }\n\n /**\n * @dev Returns the number of decimals used to get its user representation.\n * For example, if `decimals` equals `2`, a balance of `505` tokens should\n * be displayed to a user as `5.05` (`505 / 10 ** 2`).\n *\n * Tokens usually opt for a value of 18, imitating the relationship between\n * Ether and Wei. This is the value {ERC20} uses, unless this function is\n * overridden;\n *\n * NOTE: This information is only used for _display_ purposes: it in\n * no way affects any of the arithmetic of the contract, including\n * {IERC20-balanceOf} and {IERC20-transfer}.\n */\n function decimals() public view virtual override returns (uint8) {\n return 18;\n }\n\n /**\n * @dev See {IERC20-totalSupply}.\n */\n function totalSupply() public view virtual override returns (uint256) {\n return _totalSupply;\n }\n\n /**\n * @dev See {IERC20-balanceOf}.\n */\n function balanceOf(address account) public view virtual override returns (uint256) {\n return _balances[account];\n }\n\n /**\n * @dev See {IERC20-transfer}.\n *\n * Requirements:\n *\n * - `to` cannot be the zero address.\n * - the caller must have a balance of at least `amount`.\n */\n function transfer(address to, uint256 amount) public virtual override returns (bool) {\n address owner = _msgSender();\n _transfer(owner, to, amount);\n return true;\n }\n\n /**\n * @dev See {IERC20-allowance}.\n */\n function allowance(address owner, address spender) public view virtual override returns (uint256) {\n return _allowances[owner][spender];\n }\n\n /**\n * @dev See {IERC20-approve}.\n *\n * NOTE: If `amount` is the maximum `uint256`, the allowance is not updated on\n * `transferFrom`. This is semantically equivalent to an infinite approval.\n *\n * Requirements:\n *\n * - `spender` cannot be the zero address.\n */\n function approve(address spender, uint256 amount) public virtual override returns (bool) {\n address owner = _msgSender();\n _approve(owner, spender, amount);\n return true;\n }\n\n /**\n * @dev See {IERC20-transferFrom}.\n *\n * Emits an {Approval} event indicating the updated allowance. This is not\n * required by the EIP. See the note at the beginning of {ERC20}.\n *\n * NOTE: Does not update the allowance if the current allowance\n * is the maximum `uint256`.\n *\n * Requirements:\n *\n * - `from` and `to` cannot be the zero address.\n * - `from` must have a balance of at least `amount`.\n * - the caller must have allowance for ``from``'s tokens of at least\n * `amount`.\n */\n function transferFrom(\n address from,\n address to,\n uint256 amount\n ) public virtual override returns (bool) {\n address spender = _msgSender();\n _spendAllowance(from, spender, amount);\n _transfer(from, to, amount);\n return true;\n }\n\n /**\n * @dev Atomically increases the allowance granted to `spender` by the caller.\n *\n * This is an alternative to {approve} that can be used as a mitigation for\n * problems described in {IERC20-approve}.\n *\n * Emits an {Approval} event indicating the updated allowance.\n *\n * Requirements:\n *\n * - `spender` cannot be the zero address.\n */\n function increaseAllowance(address spender, uint256 addedValue) public virtual returns (bool) {\n address owner = _msgSender();\n _approve(owner, spender, allowance(owner, spender) + addedValue);\n return true;\n }\n\n /**\n * @dev Atomically decreases the allowance granted to `spender` by the caller.\n *\n * This is an alternative to {approve} that can be used as a mitigation for\n * problems described in {IERC20-approve}.\n *\n * Emits an {Approval} event indicating the updated allowance.\n *\n * Requirements:\n *\n * - `spender` cannot be the zero address.\n * - `spender` must have allowance for the caller of at least\n * `subtractedValue`.\n */\n function decreaseAllowance(address spender, uint256 subtractedValue) public virtual returns (bool) {\n address owner = _msgSender();\n uint256 currentAllowance = allowance(owner, spender);\n require(currentAllowance >= subtractedValue, \"ERC20: decreased allowance below zero\");\n unchecked {\n _approve(owner, spender, currentAllowance - subtractedValue);\n }\n\n return true;\n }\n\n /**\n * @dev Moves `amount` of tokens from `from` to `to`.\n *\n * This internal function is equivalent to {transfer}, and can be used to\n * e.g. implement automatic token fees, slashing mechanisms, etc.\n *\n * Emits a {Transfer} event.\n *\n * Requirements:\n *\n * - `from` cannot be the zero address.\n * - `to` cannot be the zero address.\n * - `from` must have a balance of at least `amount`.\n */\n function _transfer(\n address from,\n address to,\n uint256 amount\n ) internal virtual {\n require(from != address(0), \"ERC20: transfer from the zero address\");\n require(to != address(0), \"ERC20: transfer to the zero address\");\n\n _beforeTokenTransfer(from, to, amount);\n\n uint256 fromBalance = _balances[from];\n require(fromBalance >= amount, \"ERC20: transfer amount exceeds balance\");\n unchecked {\n _balances[from] = fromBalance - amount;\n }\n _balances[to] += amount;\n\n emit Transfer(from, to, amount);\n\n _afterTokenTransfer(from, to, amount);\n }\n\n /** @dev Creates `amount` tokens and assigns them to `account`, increasing\n * the total supply.\n *\n * Emits a {Transfer} event with `from` set to the zero address.\n *\n * Requirements:\n *\n * - `account` cannot be the zero address.\n */\n function _mint(address account, uint256 amount) internal virtual {\n require(account != address(0), \"ERC20: mint to the zero address\");\n\n _beforeTokenTransfer(address(0), account, amount);\n\n _totalSupply += amount;\n _balances[account] += amount;\n emit Transfer(address(0), account, amount);\n\n _afterTokenTransfer(address(0), account, amount);\n }\n\n /**\n * @dev Destroys `amount` tokens from `account`, reducing the\n * total supply.\n *\n * Emits a {Transfer} event with `to` set to the zero address.\n *\n * Requirements:\n *\n * - `account` cannot be the zero address.\n * - `account` must have at least `amount` tokens.\n */\n function _burn(address account, uint256 amount) internal virtual {\n require(account != address(0), \"ERC20: burn from the zero address\");\n\n _beforeTokenTransfer(account, address(0), amount);\n\n uint256 accountBalance = _balances[account];\n require(accountBalance >= amount, \"ERC20: burn amount exceeds balance\");\n unchecked {\n _balances[account] = accountBalance - amount;\n }\n _totalSupply -= amount;\n\n emit Transfer(account, address(0), amount);\n\n _afterTokenTransfer(account, address(0), amount);\n }\n\n /**\n * @dev Sets `amount` as the allowance of `spender` over the `owner` s tokens.\n *\n * This internal function is equivalent to `approve`, and can be used to\n * e.g. set automatic allowances for certain subsystems, etc.\n *\n * Emits an {Approval} event.\n *\n * Requirements:\n *\n * - `owner` cannot be the zero address.\n * - `spender` cannot be the zero address.\n */\n function _approve(\n address owner,\n address spender,\n uint256 amount\n ) internal virtual {\n require(owner != address(0), \"ERC20: approve from the zero address\");\n require(spender != address(0), \"ERC20: approve to the zero address\");\n\n _allowances[owner][spender] = amount;\n emit Approval(owner, spender, amount);\n }\n\n /**\n * @dev Updates `owner` s allowance for `spender` based on spent `amount`.\n *\n * Does not update the allowance amount in case of infinite allowance.\n * Revert if not enough allowance is available.\n *\n * Might emit an {Approval} event.\n */\n function _spendAllowance(\n address owner,\n address spender,\n uint256 amount\n ) internal virtual {\n uint256 currentAllowance = allowance(owner, spender);\n if (currentAllowance != type(uint256).max) {\n require(currentAllowance >= amount, \"ERC20: insufficient allowance\");\n unchecked {\n _approve(owner, spender, currentAllowance - amount);\n }\n }\n }\n\n /**\n * @dev Hook that is called before any transfer of tokens. This includes\n * minting and burning.\n *\n * Calling conditions:\n *\n * - when `from` and `to` are both non-zero, `amount` of ``from``'s tokens\n * will be transferred to `to`.\n * - when `from` is zero, `amount` tokens will be minted for `to`.\n * - when `to` is zero, `amount` of ``from``'s tokens will be burned.\n * - `from` and `to` are never both zero.\n *\n * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].\n */\n function _beforeTokenTransfer(\n address from,\n address to,\n uint256 amount\n ) internal virtual {}\n\n /**\n * @dev Hook that is called after any transfer of tokens. This includes\n * minting and burning.\n *\n * Calling conditions:\n *\n * - when `from` and `to` are both non-zero, `amount` of ``from``'s tokens\n * has been transferred to `to`.\n * - when `from` is zero, `amount` tokens have been minted for `to`.\n * - when `to` is zero, `amount` of ``from``'s tokens have been burned.\n * - `from` and `to` are never both zero.\n *\n * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].\n */\n function _afterTokenTransfer(\n address from,\n address to,\n uint256 amount\n ) internal virtual {}\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[45] private __gap;\n}\n" + }, + "@openzeppelin/contracts-upgradeable/token/ERC20/extensions/draft-ERC20PermitUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.6.0) (token/ERC20/extensions/draft-ERC20Permit.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./draft-IERC20PermitUpgradeable.sol\";\nimport \"../ERC20Upgradeable.sol\";\nimport \"../../../utils/cryptography/draft-EIP712Upgradeable.sol\";\nimport \"../../../utils/cryptography/ECDSAUpgradeable.sol\";\nimport \"../../../utils/CountersUpgradeable.sol\";\nimport \"../../../proxy/utils/Initializable.sol\";\n\n/**\n * @dev Implementation of the ERC20 Permit extension allowing approvals to be made via signatures, as defined in\n * https://eips.ethereum.org/EIPS/eip-2612[EIP-2612].\n *\n * Adds the {permit} method, which can be used to change an account's ERC20 allowance (see {IERC20-allowance}) by\n * presenting a message signed by the account. By not relying on `{IERC20-approve}`, the token holder account doesn't\n * need to send a transaction, and thus is not required to hold Ether at all.\n *\n * _Available since v3.4._\n *\n * @custom:storage-size 51\n */\nabstract contract ERC20PermitUpgradeable is Initializable, ERC20Upgradeable, IERC20PermitUpgradeable, EIP712Upgradeable {\n using CountersUpgradeable for CountersUpgradeable.Counter;\n\n mapping(address => CountersUpgradeable.Counter) private _nonces;\n\n // solhint-disable-next-line var-name-mixedcase\n bytes32 private constant _PERMIT_TYPEHASH =\n keccak256(\"Permit(address owner,address spender,uint256 value,uint256 nonce,uint256 deadline)\");\n /**\n * @dev In previous versions `_PERMIT_TYPEHASH` was declared as `immutable`.\n * However, to ensure consistency with the upgradeable transpiler, we will continue\n * to reserve a slot.\n * @custom:oz-renamed-from _PERMIT_TYPEHASH\n */\n // solhint-disable-next-line var-name-mixedcase\n bytes32 private _PERMIT_TYPEHASH_DEPRECATED_SLOT;\n\n /**\n * @dev Initializes the {EIP712} domain separator using the `name` parameter, and setting `version` to `\"1\"`.\n *\n * It's a good idea to use the same `name` that is defined as the ERC20 token name.\n */\n function __ERC20Permit_init(string memory name) internal onlyInitializing {\n __EIP712_init_unchained(name, \"1\");\n }\n\n function __ERC20Permit_init_unchained(string memory) internal onlyInitializing {}\n\n /**\n * @dev See {IERC20Permit-permit}.\n */\n function permit(\n address owner,\n address spender,\n uint256 value,\n uint256 deadline,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) public virtual override {\n require(block.timestamp <= deadline, \"ERC20Permit: expired deadline\");\n\n bytes32 structHash = keccak256(abi.encode(_PERMIT_TYPEHASH, owner, spender, value, _useNonce(owner), deadline));\n\n bytes32 hash = _hashTypedDataV4(structHash);\n\n address signer = ECDSAUpgradeable.recover(hash, v, r, s);\n require(signer == owner, \"ERC20Permit: invalid signature\");\n\n _approve(owner, spender, value);\n }\n\n /**\n * @dev See {IERC20Permit-nonces}.\n */\n function nonces(address owner) public view virtual override returns (uint256) {\n return _nonces[owner].current();\n }\n\n /**\n * @dev See {IERC20Permit-DOMAIN_SEPARATOR}.\n */\n // solhint-disable-next-line func-name-mixedcase\n function DOMAIN_SEPARATOR() external view override returns (bytes32) {\n return _domainSeparatorV4();\n }\n\n /**\n * @dev \"Consume a nonce\": return the current value and increment.\n *\n * _Available since v4.1._\n */\n function _useNonce(address owner) internal virtual returns (uint256 current) {\n CountersUpgradeable.Counter storage nonce = _nonces[owner];\n current = nonce.current();\n nonce.increment();\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[49] private __gap;\n}\n" + }, + "@openzeppelin/contracts-upgradeable/token/ERC20/extensions/draft-IERC20PermitUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (token/ERC20/extensions/draft-IERC20Permit.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Interface of the ERC20 Permit extension allowing approvals to be made via signatures, as defined in\n * https://eips.ethereum.org/EIPS/eip-2612[EIP-2612].\n *\n * Adds the {permit} method, which can be used to change an account's ERC20 allowance (see {IERC20-allowance}) by\n * presenting a message signed by the account. By not relying on {IERC20-approve}, the token holder account doesn't\n * need to send a transaction, and thus is not required to hold Ether at all.\n */\ninterface IERC20PermitUpgradeable {\n /**\n * @dev Sets `value` as the allowance of `spender` over ``owner``'s tokens,\n * given ``owner``'s signed approval.\n *\n * IMPORTANT: The same issues {IERC20-approve} has related to transaction\n * ordering also apply here.\n *\n * Emits an {Approval} event.\n *\n * Requirements:\n *\n * - `spender` cannot be the zero address.\n * - `deadline` must be a timestamp in the future.\n * - `v`, `r` and `s` must be a valid `secp256k1` signature from `owner`\n * over the EIP712-formatted function arguments.\n * - the signature must use ``owner``'s current nonce (see {nonces}).\n *\n * For more information on the signature format, see the\n * https://eips.ethereum.org/EIPS/eip-2612#specification[relevant EIP\n * section].\n */\n function permit(\n address owner,\n address spender,\n uint256 value,\n uint256 deadline,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) external;\n\n /**\n * @dev Returns the current nonce for `owner`. This value must be\n * included whenever a signature is generated for {permit}.\n *\n * Every successful call to {permit} increases ``owner``'s nonce by one. This\n * prevents a signature from being used multiple times.\n */\n function nonces(address owner) external view returns (uint256);\n\n /**\n * @dev Returns the domain separator used in the encoding of the signature for {permit}, as defined by {EIP712}.\n */\n // solhint-disable-next-line func-name-mixedcase\n function DOMAIN_SEPARATOR() external view returns (bytes32);\n}\n" + }, + "@openzeppelin/contracts-upgradeable/token/ERC20/extensions/IERC20MetadataUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (token/ERC20/extensions/IERC20Metadata.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../IERC20Upgradeable.sol\";\n\n/**\n * @dev Interface for the optional metadata functions from the ERC20 standard.\n *\n * _Available since v4.1._\n */\ninterface IERC20MetadataUpgradeable is IERC20Upgradeable {\n /**\n * @dev Returns the name of the token.\n */\n function name() external view returns (string memory);\n\n /**\n * @dev Returns the symbol of the token.\n */\n function symbol() external view returns (string memory);\n\n /**\n * @dev Returns the decimals places of the token.\n */\n function decimals() external view returns (uint8);\n}\n" + }, + "@openzeppelin/contracts-upgradeable/token/ERC20/IERC20Upgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.6.0) (token/ERC20/IERC20.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Interface of the ERC20 standard as defined in the EIP.\n */\ninterface IERC20Upgradeable {\n /**\n * @dev Emitted when `value` tokens are moved from one account (`from`) to\n * another (`to`).\n *\n * Note that `value` may be zero.\n */\n event Transfer(address indexed from, address indexed to, uint256 value);\n\n /**\n * @dev Emitted when the allowance of a `spender` for an `owner` is set by\n * a call to {approve}. `value` is the new allowance.\n */\n event Approval(address indexed owner, address indexed spender, uint256 value);\n\n /**\n * @dev Returns the amount of tokens in existence.\n */\n function totalSupply() external view returns (uint256);\n\n /**\n * @dev Returns the amount of tokens owned by `account`.\n */\n function balanceOf(address account) external view returns (uint256);\n\n /**\n * @dev Moves `amount` tokens from the caller's account to `to`.\n *\n * Returns a boolean value indicating whether the operation succeeded.\n *\n * Emits a {Transfer} event.\n */\n function transfer(address to, uint256 amount) external returns (bool);\n\n /**\n * @dev Returns the remaining number of tokens that `spender` will be\n * allowed to spend on behalf of `owner` through {transferFrom}. This is\n * zero by default.\n *\n * This value changes when {approve} or {transferFrom} are called.\n */\n function allowance(address owner, address spender) external view returns (uint256);\n\n /**\n * @dev Sets `amount` as the allowance of `spender` over the caller's tokens.\n *\n * Returns a boolean value indicating whether the operation succeeded.\n *\n * IMPORTANT: Beware that changing an allowance with this method brings the risk\n * that someone may use both the old and the new allowance by unfortunate\n * transaction ordering. One possible solution to mitigate this race\n * condition is to first reduce the spender's allowance to 0 and set the\n * desired value afterwards:\n * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729\n *\n * Emits an {Approval} event.\n */\n function approve(address spender, uint256 amount) external returns (bool);\n\n /**\n * @dev Moves `amount` tokens from `from` to `to` using the\n * allowance mechanism. `amount` is then deducted from the caller's\n * allowance.\n *\n * Returns a boolean value indicating whether the operation succeeded.\n *\n * Emits a {Transfer} event.\n */\n function transferFrom(\n address from,\n address to,\n uint256 amount\n ) external returns (bool);\n}\n" + }, + "@openzeppelin/contracts-upgradeable/token/ERC721/extensions/IERC721MetadataUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (token/ERC721/extensions/IERC721Metadata.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../IERC721Upgradeable.sol\";\n\n/**\n * @title ERC-721 Non-Fungible Token Standard, optional metadata extension\n * @dev See https://eips.ethereum.org/EIPS/eip-721\n */\ninterface IERC721MetadataUpgradeable is IERC721Upgradeable {\n /**\n * @dev Returns the token collection name.\n */\n function name() external view returns (string memory);\n\n /**\n * @dev Returns the token collection symbol.\n */\n function symbol() external view returns (string memory);\n\n /**\n * @dev Returns the Uniform Resource Identifier (URI) for `tokenId` token.\n */\n function tokenURI(uint256 tokenId) external view returns (string memory);\n}\n" + }, + "@openzeppelin/contracts-upgradeable/token/ERC721/IERC721ReceiverUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.6.0) (token/ERC721/IERC721Receiver.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @title ERC721 token receiver interface\n * @dev Interface for any contract that wants to support safeTransfers\n * from ERC721 asset contracts.\n */\ninterface IERC721ReceiverUpgradeable {\n /**\n * @dev Whenever an {IERC721} `tokenId` token is transferred to this contract via {IERC721-safeTransferFrom}\n * by `operator` from `from`, this function is called.\n *\n * It must return its Solidity selector to confirm the token transfer.\n * If any other value is returned or the interface is not implemented by the recipient, the transfer will be reverted.\n *\n * The selector can be obtained in Solidity with `IERC721Receiver.onERC721Received.selector`.\n */\n function onERC721Received(\n address operator,\n address from,\n uint256 tokenId,\n bytes calldata data\n ) external returns (bytes4);\n}\n" + }, + "@openzeppelin/contracts-upgradeable/token/ERC721/IERC721Upgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (token/ERC721/IERC721.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../../utils/introspection/IERC165Upgradeable.sol\";\n\n/**\n * @dev Required interface of an ERC721 compliant contract.\n */\ninterface IERC721Upgradeable is IERC165Upgradeable {\n /**\n * @dev Emitted when `tokenId` token is transferred from `from` to `to`.\n */\n event Transfer(address indexed from, address indexed to, uint256 indexed tokenId);\n\n /**\n * @dev Emitted when `owner` enables `approved` to manage the `tokenId` token.\n */\n event Approval(address indexed owner, address indexed approved, uint256 indexed tokenId);\n\n /**\n * @dev Emitted when `owner` enables or disables (`approved`) `operator` to manage all of its assets.\n */\n event ApprovalForAll(address indexed owner, address indexed operator, bool approved);\n\n /**\n * @dev Returns the number of tokens in ``owner``'s account.\n */\n function balanceOf(address owner) external view returns (uint256 balance);\n\n /**\n * @dev Returns the owner of the `tokenId` token.\n *\n * Requirements:\n *\n * - `tokenId` must exist.\n */\n function ownerOf(uint256 tokenId) external view returns (address owner);\n\n /**\n * @dev Safely transfers `tokenId` token from `from` to `to`.\n *\n * Requirements:\n *\n * - `from` cannot be the zero address.\n * - `to` cannot be the zero address.\n * - `tokenId` token must exist and be owned by `from`.\n * - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}.\n * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.\n *\n * Emits a {Transfer} event.\n */\n function safeTransferFrom(\n address from,\n address to,\n uint256 tokenId,\n bytes calldata data\n ) external;\n\n /**\n * @dev Safely transfers `tokenId` token from `from` to `to`, checking first that contract recipients\n * are aware of the ERC721 protocol to prevent tokens from being forever locked.\n *\n * Requirements:\n *\n * - `from` cannot be the zero address.\n * - `to` cannot be the zero address.\n * - `tokenId` token must exist and be owned by `from`.\n * - If the caller is not `from`, it must have been allowed to move this token by either {approve} or {setApprovalForAll}.\n * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.\n *\n * Emits a {Transfer} event.\n */\n function safeTransferFrom(\n address from,\n address to,\n uint256 tokenId\n ) external;\n\n /**\n * @dev Transfers `tokenId` token from `from` to `to`.\n *\n * WARNING: Usage of this method is discouraged, use {safeTransferFrom} whenever possible.\n *\n * Requirements:\n *\n * - `from` cannot be the zero address.\n * - `to` cannot be the zero address.\n * - `tokenId` token must be owned by `from`.\n * - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}.\n *\n * Emits a {Transfer} event.\n */\n function transferFrom(\n address from,\n address to,\n uint256 tokenId\n ) external;\n\n /**\n * @dev Gives permission to `to` to transfer `tokenId` token to another account.\n * The approval is cleared when the token is transferred.\n *\n * Only a single account can be approved at a time, so approving the zero address clears previous approvals.\n *\n * Requirements:\n *\n * - The caller must own the token or be an approved operator.\n * - `tokenId` must exist.\n *\n * Emits an {Approval} event.\n */\n function approve(address to, uint256 tokenId) external;\n\n /**\n * @dev Approve or remove `operator` as an operator for the caller.\n * Operators can call {transferFrom} or {safeTransferFrom} for any token owned by the caller.\n *\n * Requirements:\n *\n * - The `operator` cannot be the caller.\n *\n * Emits an {ApprovalForAll} event.\n */\n function setApprovalForAll(address operator, bool _approved) external;\n\n /**\n * @dev Returns the account approved for `tokenId` token.\n *\n * Requirements:\n *\n * - `tokenId` must exist.\n */\n function getApproved(uint256 tokenId) external view returns (address operator);\n\n /**\n * @dev Returns if the `operator` is allowed to manage all of the assets of `owner`.\n *\n * See {setApprovalForAll}\n */\n function isApprovedForAll(address owner, address operator) external view returns (bool);\n}\n" + }, + "@openzeppelin/contracts-upgradeable/utils/AddressUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (utils/Address.sol)\n\npragma solidity ^0.8.1;\n\n/**\n * @dev Collection of functions related to the address type\n */\nlibrary AddressUpgradeable {\n /**\n * @dev Returns true if `account` is a contract.\n *\n * [IMPORTANT]\n * ====\n * It is unsafe to assume that an address for which this function returns\n * false is an externally-owned account (EOA) and not a contract.\n *\n * Among others, `isContract` will return false for the following\n * types of addresses:\n *\n * - an externally-owned account\n * - a contract in construction\n * - an address where a contract will be created\n * - an address where a contract lived, but was destroyed\n * ====\n *\n * [IMPORTANT]\n * ====\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\n *\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\n * constructor.\n * ====\n */\n function isContract(address account) internal view returns (bool) {\n // This method relies on extcodesize/address.code.length, which returns 0\n // for contracts in construction, since the code is only stored at the end\n // of the constructor execution.\n\n return account.code.length > 0;\n }\n\n /**\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\n * `recipient`, forwarding all available gas and reverting on errors.\n *\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\n * imposed by `transfer`, making them unable to receive funds via\n * `transfer`. {sendValue} removes this limitation.\n *\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\n *\n * IMPORTANT: because control is transferred to `recipient`, care must be\n * taken to not create reentrancy vulnerabilities. Consider using\n * {ReentrancyGuard} or the\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\n */\n function sendValue(address payable recipient, uint256 amount) internal {\n require(address(this).balance >= amount, \"Address: insufficient balance\");\n\n (bool success, ) = recipient.call{value: amount}(\"\");\n require(success, \"Address: unable to send value, recipient may have reverted\");\n }\n\n /**\n * @dev Performs a Solidity function call using a low level `call`. A\n * plain `call` is an unsafe replacement for a function call: use this\n * function instead.\n *\n * If `target` reverts with a revert reason, it is bubbled up by this\n * function (like regular Solidity function calls).\n *\n * Returns the raw returned data. To convert to the expected return value,\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\n *\n * Requirements:\n *\n * - `target` must be a contract.\n * - calling `target` with `data` must not revert.\n *\n * _Available since v3.1._\n */\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionCall(target, data, \"Address: low-level call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\n * `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, 0, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but also transferring `value` wei to `target`.\n *\n * Requirements:\n *\n * - the calling contract must have an ETH balance of at least `value`.\n * - the called Solidity function must be `payable`.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, value, \"Address: low-level call with value failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\n * with `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(address(this).balance >= value, \"Address: insufficient balance for call\");\n require(isContract(target), \"Address: call to non-contract\");\n\n (bool success, bytes memory returndata) = target.call{value: value}(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\n return functionStaticCall(target, data, \"Address: low-level static call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal view returns (bytes memory) {\n require(isContract(target), \"Address: static call to non-contract\");\n\n (bool success, bytes memory returndata) = target.staticcall(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the\n * revert reason using the provided one.\n *\n * _Available since v4.3._\n */\n function verifyCallResult(\n bool success,\n bytes memory returndata,\n string memory errorMessage\n ) internal pure returns (bytes memory) {\n if (success) {\n return returndata;\n } else {\n // Look for revert reason and bubble it up if present\n if (returndata.length > 0) {\n // The easiest way to bubble the revert reason is using memory via assembly\n /// @solidity memory-safe-assembly\n assembly {\n let returndata_size := mload(returndata)\n revert(add(32, returndata), returndata_size)\n }\n } else {\n revert(errorMessage);\n }\n }\n }\n}\n" + }, + "@openzeppelin/contracts-upgradeable/utils/ContextUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)\n\npragma solidity ^0.8.0;\nimport \"../proxy/utils/Initializable.sol\";\n\n/**\n * @dev Provides information about the current execution context, including the\n * sender of the transaction and its data. While these are generally available\n * via msg.sender and msg.data, they should not be accessed in such a direct\n * manner, since when dealing with meta-transactions the account sending and\n * paying for execution may not be the actual sender (as far as an application\n * is concerned).\n *\n * This contract is only required for intermediate, library-like contracts.\n */\nabstract contract ContextUpgradeable is Initializable {\n function __Context_init() internal onlyInitializing {\n }\n\n function __Context_init_unchained() internal onlyInitializing {\n }\n function _msgSender() internal view virtual returns (address) {\n return msg.sender;\n }\n\n function _msgData() internal view virtual returns (bytes calldata) {\n return msg.data;\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[50] private __gap;\n}\n" + }, + "@openzeppelin/contracts-upgradeable/utils/CountersUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (utils/Counters.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @title Counters\n * @author Matt Condon (@shrugs)\n * @dev Provides counters that can only be incremented, decremented or reset. This can be used e.g. to track the number\n * of elements in a mapping, issuing ERC721 ids, or counting request ids.\n *\n * Include with `using Counters for Counters.Counter;`\n */\nlibrary CountersUpgradeable {\n struct Counter {\n // This variable should never be directly accessed by users of the library: interactions must be restricted to\n // the library's function. As of Solidity v0.5.2, this cannot be enforced, though there is a proposal to add\n // this feature: see https://github.com/ethereum/solidity/issues/4637\n uint256 _value; // default: 0\n }\n\n function current(Counter storage counter) internal view returns (uint256) {\n return counter._value;\n }\n\n function increment(Counter storage counter) internal {\n unchecked {\n counter._value += 1;\n }\n }\n\n function decrement(Counter storage counter) internal {\n uint256 value = counter._value;\n require(value > 0, \"Counter: decrement overflow\");\n unchecked {\n counter._value = value - 1;\n }\n }\n\n function reset(Counter storage counter) internal {\n counter._value = 0;\n }\n}\n" + }, + "@openzeppelin/contracts-upgradeable/utils/cryptography/draft-EIP712Upgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (utils/cryptography/draft-EIP712.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./ECDSAUpgradeable.sol\";\nimport \"../../proxy/utils/Initializable.sol\";\n\n/**\n * @dev https://eips.ethereum.org/EIPS/eip-712[EIP 712] is a standard for hashing and signing of typed structured data.\n *\n * The encoding specified in the EIP is very generic, and such a generic implementation in Solidity is not feasible,\n * thus this contract does not implement the encoding itself. Protocols need to implement the type-specific encoding\n * they need in their contracts using a combination of `abi.encode` and `keccak256`.\n *\n * This contract implements the EIP 712 domain separator ({_domainSeparatorV4}) that is used as part of the encoding\n * scheme, and the final step of the encoding to obtain the message digest that is then signed via ECDSA\n * ({_hashTypedDataV4}).\n *\n * The implementation of the domain separator was designed to be as efficient as possible while still properly updating\n * the chain id to protect against replay attacks on an eventual fork of the chain.\n *\n * NOTE: This contract implements the version of the encoding known as \"v4\", as implemented by the JSON RPC method\n * https://docs.metamask.io/guide/signing-data.html[`eth_signTypedDataV4` in MetaMask].\n *\n * _Available since v3.4._\n *\n * @custom:storage-size 52\n */\nabstract contract EIP712Upgradeable is Initializable {\n /* solhint-disable var-name-mixedcase */\n bytes32 private _HASHED_NAME;\n bytes32 private _HASHED_VERSION;\n bytes32 private constant _TYPE_HASH = keccak256(\"EIP712Domain(string name,string version,uint256 chainId,address verifyingContract)\");\n\n /* solhint-enable var-name-mixedcase */\n\n /**\n * @dev Initializes the domain separator and parameter caches.\n *\n * The meaning of `name` and `version` is specified in\n * https://eips.ethereum.org/EIPS/eip-712#definition-of-domainseparator[EIP 712]:\n *\n * - `name`: the user readable name of the signing domain, i.e. the name of the DApp or the protocol.\n * - `version`: the current major version of the signing domain.\n *\n * NOTE: These parameters cannot be changed except through a xref:learn::upgrading-smart-contracts.adoc[smart\n * contract upgrade].\n */\n function __EIP712_init(string memory name, string memory version) internal onlyInitializing {\n __EIP712_init_unchained(name, version);\n }\n\n function __EIP712_init_unchained(string memory name, string memory version) internal onlyInitializing {\n bytes32 hashedName = keccak256(bytes(name));\n bytes32 hashedVersion = keccak256(bytes(version));\n _HASHED_NAME = hashedName;\n _HASHED_VERSION = hashedVersion;\n }\n\n /**\n * @dev Returns the domain separator for the current chain.\n */\n function _domainSeparatorV4() internal view returns (bytes32) {\n return _buildDomainSeparator(_TYPE_HASH, _EIP712NameHash(), _EIP712VersionHash());\n }\n\n function _buildDomainSeparator(\n bytes32 typeHash,\n bytes32 nameHash,\n bytes32 versionHash\n ) private view returns (bytes32) {\n return keccak256(abi.encode(typeHash, nameHash, versionHash, block.chainid, address(this)));\n }\n\n /**\n * @dev Given an already https://eips.ethereum.org/EIPS/eip-712#definition-of-hashstruct[hashed struct], this\n * function returns the hash of the fully encoded EIP712 message for this domain.\n *\n * This hash can be used together with {ECDSA-recover} to obtain the signer of a message. For example:\n *\n * ```solidity\n * bytes32 digest = _hashTypedDataV4(keccak256(abi.encode(\n * keccak256(\"Mail(address to,string contents)\"),\n * mailTo,\n * keccak256(bytes(mailContents))\n * )));\n * address signer = ECDSA.recover(digest, signature);\n * ```\n */\n function _hashTypedDataV4(bytes32 structHash) internal view virtual returns (bytes32) {\n return ECDSAUpgradeable.toTypedDataHash(_domainSeparatorV4(), structHash);\n }\n\n /**\n * @dev The hash of the name parameter for the EIP712 domain.\n *\n * NOTE: This function reads from storage by default, but can be redefined to return a constant value if gas costs\n * are a concern.\n */\n function _EIP712NameHash() internal virtual view returns (bytes32) {\n return _HASHED_NAME;\n }\n\n /**\n * @dev The hash of the version parameter for the EIP712 domain.\n *\n * NOTE: This function reads from storage by default, but can be redefined to return a constant value if gas costs\n * are a concern.\n */\n function _EIP712VersionHash() internal virtual view returns (bytes32) {\n return _HASHED_VERSION;\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[50] private __gap;\n}\n" + }, + "@openzeppelin/contracts-upgradeable/utils/cryptography/ECDSAUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (utils/cryptography/ECDSA.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../StringsUpgradeable.sol\";\n\n/**\n * @dev Elliptic Curve Digital Signature Algorithm (ECDSA) operations.\n *\n * These functions can be used to verify that a message was signed by the holder\n * of the private keys of a given address.\n */\nlibrary ECDSAUpgradeable {\n enum RecoverError {\n NoError,\n InvalidSignature,\n InvalidSignatureLength,\n InvalidSignatureS,\n InvalidSignatureV\n }\n\n function _throwError(RecoverError error) private pure {\n if (error == RecoverError.NoError) {\n return; // no error: do nothing\n } else if (error == RecoverError.InvalidSignature) {\n revert(\"ECDSA: invalid signature\");\n } else if (error == RecoverError.InvalidSignatureLength) {\n revert(\"ECDSA: invalid signature length\");\n } else if (error == RecoverError.InvalidSignatureS) {\n revert(\"ECDSA: invalid signature 's' value\");\n } else if (error == RecoverError.InvalidSignatureV) {\n revert(\"ECDSA: invalid signature 'v' value\");\n }\n }\n\n /**\n * @dev Returns the address that signed a hashed message (`hash`) with\n * `signature` or error string. This address can then be used for verification purposes.\n *\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\n * this function rejects them by requiring the `s` value to be in the lower\n * half order, and the `v` value to be either 27 or 28.\n *\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\n * verification to be secure: it is possible to craft signatures that\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\n * this is by receiving a hash of the original message (which may otherwise\n * be too long), and then calling {toEthSignedMessageHash} on it.\n *\n * Documentation for signature generation:\n * - with https://web3js.readthedocs.io/en/v1.3.4/web3-eth-accounts.html#sign[Web3.js]\n * - with https://docs.ethers.io/v5/api/signer/#Signer-signMessage[ethers]\n *\n * _Available since v4.3._\n */\n function tryRecover(bytes32 hash, bytes memory signature) internal pure returns (address, RecoverError) {\n // Check the signature length\n // - case 65: r,s,v signature (standard)\n // - case 64: r,vs signature (cf https://eips.ethereum.org/EIPS/eip-2098) _Available since v4.1._\n if (signature.length == 65) {\n bytes32 r;\n bytes32 s;\n uint8 v;\n // ecrecover takes the signature parameters, and the only way to get them\n // currently is to use assembly.\n /// @solidity memory-safe-assembly\n assembly {\n r := mload(add(signature, 0x20))\n s := mload(add(signature, 0x40))\n v := byte(0, mload(add(signature, 0x60)))\n }\n return tryRecover(hash, v, r, s);\n } else if (signature.length == 64) {\n bytes32 r;\n bytes32 vs;\n // ecrecover takes the signature parameters, and the only way to get them\n // currently is to use assembly.\n /// @solidity memory-safe-assembly\n assembly {\n r := mload(add(signature, 0x20))\n vs := mload(add(signature, 0x40))\n }\n return tryRecover(hash, r, vs);\n } else {\n return (address(0), RecoverError.InvalidSignatureLength);\n }\n }\n\n /**\n * @dev Returns the address that signed a hashed message (`hash`) with\n * `signature`. This address can then be used for verification purposes.\n *\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\n * this function rejects them by requiring the `s` value to be in the lower\n * half order, and the `v` value to be either 27 or 28.\n *\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\n * verification to be secure: it is possible to craft signatures that\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\n * this is by receiving a hash of the original message (which may otherwise\n * be too long), and then calling {toEthSignedMessageHash} on it.\n */\n function recover(bytes32 hash, bytes memory signature) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, signature);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Overload of {ECDSA-tryRecover} that receives the `r` and `vs` short-signature fields separately.\n *\n * See https://eips.ethereum.org/EIPS/eip-2098[EIP-2098 short signatures]\n *\n * _Available since v4.3._\n */\n function tryRecover(\n bytes32 hash,\n bytes32 r,\n bytes32 vs\n ) internal pure returns (address, RecoverError) {\n bytes32 s = vs & bytes32(0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff);\n uint8 v = uint8((uint256(vs) >> 255) + 27);\n return tryRecover(hash, v, r, s);\n }\n\n /**\n * @dev Overload of {ECDSA-recover} that receives the `r and `vs` short-signature fields separately.\n *\n * _Available since v4.2._\n */\n function recover(\n bytes32 hash,\n bytes32 r,\n bytes32 vs\n ) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, r, vs);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Overload of {ECDSA-tryRecover} that receives the `v`,\n * `r` and `s` signature fields separately.\n *\n * _Available since v4.3._\n */\n function tryRecover(\n bytes32 hash,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) internal pure returns (address, RecoverError) {\n // EIP-2 still allows signature malleability for ecrecover(). Remove this possibility and make the signature\n // unique. Appendix F in the Ethereum Yellow paper (https://ethereum.github.io/yellowpaper/paper.pdf), defines\n // the valid range for s in (301): 0 < s < secp256k1n ÷ 2 + 1, and for v in (302): v ∈ {27, 28}. Most\n // signatures from current libraries generate a unique signature with an s-value in the lower half order.\n //\n // If your library generates malleable signatures, such as s-values in the upper range, calculate a new s-value\n // with 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141 - s1 and flip v from 27 to 28 or\n // vice versa. If your library also generates signatures with 0/1 for v instead 27/28, add 27 to v to accept\n // these malleable signatures as well.\n if (uint256(s) > 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D576E7357A4501DDFE92F46681B20A0) {\n return (address(0), RecoverError.InvalidSignatureS);\n }\n if (v != 27 && v != 28) {\n return (address(0), RecoverError.InvalidSignatureV);\n }\n\n // If the signature is valid (and not malleable), return the signer address\n address signer = ecrecover(hash, v, r, s);\n if (signer == address(0)) {\n return (address(0), RecoverError.InvalidSignature);\n }\n\n return (signer, RecoverError.NoError);\n }\n\n /**\n * @dev Overload of {ECDSA-recover} that receives the `v`,\n * `r` and `s` signature fields separately.\n */\n function recover(\n bytes32 hash,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, v, r, s);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Returns an Ethereum Signed Message, created from a `hash`. This\n * produces hash corresponding to the one signed with the\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\n * JSON-RPC method as part of EIP-191.\n *\n * See {recover}.\n */\n function toEthSignedMessageHash(bytes32 hash) internal pure returns (bytes32) {\n // 32 is the length in bytes of hash,\n // enforced by the type signature above\n return keccak256(abi.encodePacked(\"\\x19Ethereum Signed Message:\\n32\", hash));\n }\n\n /**\n * @dev Returns an Ethereum Signed Message, created from `s`. This\n * produces hash corresponding to the one signed with the\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\n * JSON-RPC method as part of EIP-191.\n *\n * See {recover}.\n */\n function toEthSignedMessageHash(bytes memory s) internal pure returns (bytes32) {\n return keccak256(abi.encodePacked(\"\\x19Ethereum Signed Message:\\n\", StringsUpgradeable.toString(s.length), s));\n }\n\n /**\n * @dev Returns an Ethereum Signed Typed Data, created from a\n * `domainSeparator` and a `structHash`. This produces hash corresponding\n * to the one signed with the\n * https://eips.ethereum.org/EIPS/eip-712[`eth_signTypedData`]\n * JSON-RPC method as part of EIP-712.\n *\n * See {recover}.\n */\n function toTypedDataHash(bytes32 domainSeparator, bytes32 structHash) internal pure returns (bytes32) {\n return keccak256(abi.encodePacked(\"\\x19\\x01\", domainSeparator, structHash));\n }\n}\n" + }, + "@openzeppelin/contracts-upgradeable/utils/introspection/ERC165Upgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (utils/introspection/ERC165.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./IERC165Upgradeable.sol\";\nimport \"../../proxy/utils/Initializable.sol\";\n\n/**\n * @dev Implementation of the {IERC165} interface.\n *\n * Contracts that want to implement ERC165 should inherit from this contract and override {supportsInterface} to check\n * for the additional interface id that will be supported. For example:\n *\n * ```solidity\n * function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {\n * return interfaceId == type(MyInterface).interfaceId || super.supportsInterface(interfaceId);\n * }\n * ```\n *\n * Alternatively, {ERC165Storage} provides an easier to use but more expensive implementation.\n */\nabstract contract ERC165Upgradeable is Initializable, IERC165Upgradeable {\n function __ERC165_init() internal onlyInitializing {\n }\n\n function __ERC165_init_unchained() internal onlyInitializing {\n }\n /**\n * @dev See {IERC165-supportsInterface}.\n */\n function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {\n return interfaceId == type(IERC165Upgradeable).interfaceId;\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[50] private __gap;\n}\n" + }, + "@openzeppelin/contracts-upgradeable/utils/introspection/IERC165Upgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (utils/introspection/IERC165.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Interface of the ERC165 standard, as defined in the\n * https://eips.ethereum.org/EIPS/eip-165[EIP].\n *\n * Implementers can declare support of contract interfaces, which can then be\n * queried by others ({ERC165Checker}).\n *\n * For an implementation, see {ERC165}.\n */\ninterface IERC165Upgradeable {\n /**\n * @dev Returns true if this contract implements the interface defined by\n * `interfaceId`. See the corresponding\n * https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified[EIP section]\n * to learn more about how these ids are created.\n *\n * This function call must use less than 30 000 gas.\n */\n function supportsInterface(bytes4 interfaceId) external view returns (bool);\n}\n" + }, + "@openzeppelin/contracts-upgradeable/utils/StringsUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (utils/Strings.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev String operations.\n */\nlibrary StringsUpgradeable {\n bytes16 private constant _HEX_SYMBOLS = \"0123456789abcdef\";\n uint8 private constant _ADDRESS_LENGTH = 20;\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` decimal representation.\n */\n function toString(uint256 value) internal pure returns (string memory) {\n // Inspired by OraclizeAPI's implementation - MIT licence\n // https://github.com/oraclize/ethereum-api/blob/b42146b063c7d6ee1358846c198246239e9360e8/oraclizeAPI_0.4.25.sol\n\n if (value == 0) {\n return \"0\";\n }\n uint256 temp = value;\n uint256 digits;\n while (temp != 0) {\n digits++;\n temp /= 10;\n }\n bytes memory buffer = new bytes(digits);\n while (value != 0) {\n digits -= 1;\n buffer[digits] = bytes1(uint8(48 + uint256(value % 10)));\n value /= 10;\n }\n return string(buffer);\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation.\n */\n function toHexString(uint256 value) internal pure returns (string memory) {\n if (value == 0) {\n return \"0x00\";\n }\n uint256 temp = value;\n uint256 length = 0;\n while (temp != 0) {\n length++;\n temp >>= 8;\n }\n return toHexString(value, length);\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length.\n */\n function toHexString(uint256 value, uint256 length) internal pure returns (string memory) {\n bytes memory buffer = new bytes(2 * length + 2);\n buffer[0] = \"0\";\n buffer[1] = \"x\";\n for (uint256 i = 2 * length + 1; i > 1; --i) {\n buffer[i] = _HEX_SYMBOLS[value & 0xf];\n value >>= 4;\n }\n require(value == 0, \"Strings: hex length insufficient\");\n return string(buffer);\n }\n\n /**\n * @dev Converts an `address` with fixed length of 20 bytes to its not checksummed ASCII `string` hexadecimal representation.\n */\n function toHexString(address addr) internal pure returns (string memory) {\n return toHexString(uint256(uint160(addr)), _ADDRESS_LENGTH);\n }\n}\n" + }, + "@openzeppelin/contracts-upgradeable/utils/structs/EnumerableSetUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (utils/structs/EnumerableSet.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Library for managing\n * https://en.wikipedia.org/wiki/Set_(abstract_data_type)[sets] of primitive\n * types.\n *\n * Sets have the following properties:\n *\n * - Elements are added, removed, and checked for existence in constant time\n * (O(1)).\n * - Elements are enumerated in O(n). No guarantees are made on the ordering.\n *\n * ```\n * contract Example {\n * // Add the library methods\n * using EnumerableSet for EnumerableSet.AddressSet;\n *\n * // Declare a set state variable\n * EnumerableSet.AddressSet private mySet;\n * }\n * ```\n *\n * As of v3.3.0, sets of type `bytes32` (`Bytes32Set`), `address` (`AddressSet`)\n * and `uint256` (`UintSet`) are supported.\n *\n * [WARNING]\n * ====\n * Trying to delete such a structure from storage will likely result in data corruption, rendering the structure unusable.\n * See https://github.com/ethereum/solidity/pull/11843[ethereum/solidity#11843] for more info.\n *\n * In order to clean an EnumerableSet, you can either remove all elements one by one or create a fresh instance using an array of EnumerableSet.\n * ====\n */\nlibrary EnumerableSetUpgradeable {\n // To implement this library for multiple types with as little code\n // repetition as possible, we write it in terms of a generic Set type with\n // bytes32 values.\n // The Set implementation uses private functions, and user-facing\n // implementations (such as AddressSet) are just wrappers around the\n // underlying Set.\n // This means that we can only create new EnumerableSets for types that fit\n // in bytes32.\n\n struct Set {\n // Storage of set values\n bytes32[] _values;\n // Position of the value in the `values` array, plus 1 because index 0\n // means a value is not in the set.\n mapping(bytes32 => uint256) _indexes;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function _add(Set storage set, bytes32 value) private returns (bool) {\n if (!_contains(set, value)) {\n set._values.push(value);\n // The value is stored at length-1, but we add 1 to all indexes\n // and use 0 as a sentinel value\n set._indexes[value] = set._values.length;\n return true;\n } else {\n return false;\n }\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function _remove(Set storage set, bytes32 value) private returns (bool) {\n // We read and store the value's index to prevent multiple reads from the same storage slot\n uint256 valueIndex = set._indexes[value];\n\n if (valueIndex != 0) {\n // Equivalent to contains(set, value)\n // To delete an element from the _values array in O(1), we swap the element to delete with the last one in\n // the array, and then remove the last element (sometimes called as 'swap and pop').\n // This modifies the order of the array, as noted in {at}.\n\n uint256 toDeleteIndex = valueIndex - 1;\n uint256 lastIndex = set._values.length - 1;\n\n if (lastIndex != toDeleteIndex) {\n bytes32 lastValue = set._values[lastIndex];\n\n // Move the last value to the index where the value to delete is\n set._values[toDeleteIndex] = lastValue;\n // Update the index for the moved value\n set._indexes[lastValue] = valueIndex; // Replace lastValue's index to valueIndex\n }\n\n // Delete the slot where the moved value was stored\n set._values.pop();\n\n // Delete the index for the deleted slot\n delete set._indexes[value];\n\n return true;\n } else {\n return false;\n }\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function _contains(Set storage set, bytes32 value) private view returns (bool) {\n return set._indexes[value] != 0;\n }\n\n /**\n * @dev Returns the number of values on the set. O(1).\n */\n function _length(Set storage set) private view returns (uint256) {\n return set._values.length;\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function _at(Set storage set, uint256 index) private view returns (bytes32) {\n return set._values[index];\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function _values(Set storage set) private view returns (bytes32[] memory) {\n return set._values;\n }\n\n // Bytes32Set\n\n struct Bytes32Set {\n Set _inner;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function add(Bytes32Set storage set, bytes32 value) internal returns (bool) {\n return _add(set._inner, value);\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function remove(Bytes32Set storage set, bytes32 value) internal returns (bool) {\n return _remove(set._inner, value);\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function contains(Bytes32Set storage set, bytes32 value) internal view returns (bool) {\n return _contains(set._inner, value);\n }\n\n /**\n * @dev Returns the number of values in the set. O(1).\n */\n function length(Bytes32Set storage set) internal view returns (uint256) {\n return _length(set._inner);\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function at(Bytes32Set storage set, uint256 index) internal view returns (bytes32) {\n return _at(set._inner, index);\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function values(Bytes32Set storage set) internal view returns (bytes32[] memory) {\n return _values(set._inner);\n }\n\n // AddressSet\n\n struct AddressSet {\n Set _inner;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function add(AddressSet storage set, address value) internal returns (bool) {\n return _add(set._inner, bytes32(uint256(uint160(value))));\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function remove(AddressSet storage set, address value) internal returns (bool) {\n return _remove(set._inner, bytes32(uint256(uint160(value))));\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function contains(AddressSet storage set, address value) internal view returns (bool) {\n return _contains(set._inner, bytes32(uint256(uint160(value))));\n }\n\n /**\n * @dev Returns the number of values in the set. O(1).\n */\n function length(AddressSet storage set) internal view returns (uint256) {\n return _length(set._inner);\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function at(AddressSet storage set, uint256 index) internal view returns (address) {\n return address(uint160(uint256(_at(set._inner, index))));\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function values(AddressSet storage set) internal view returns (address[] memory) {\n bytes32[] memory store = _values(set._inner);\n address[] memory result;\n\n /// @solidity memory-safe-assembly\n assembly {\n result := store\n }\n\n return result;\n }\n\n // UintSet\n\n struct UintSet {\n Set _inner;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function add(UintSet storage set, uint256 value) internal returns (bool) {\n return _add(set._inner, bytes32(value));\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function remove(UintSet storage set, uint256 value) internal returns (bool) {\n return _remove(set._inner, bytes32(value));\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function contains(UintSet storage set, uint256 value) internal view returns (bool) {\n return _contains(set._inner, bytes32(value));\n }\n\n /**\n * @dev Returns the number of values on the set. O(1).\n */\n function length(UintSet storage set) internal view returns (uint256) {\n return _length(set._inner);\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function at(UintSet storage set, uint256 index) internal view returns (uint256) {\n return uint256(_at(set._inner, index));\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function values(UintSet storage set) internal view returns (uint256[] memory) {\n bytes32[] memory store = _values(set._inner);\n uint256[] memory result;\n\n /// @solidity memory-safe-assembly\n assembly {\n result := store\n }\n\n return result;\n }\n}\n" + }, + "@openzeppelin/contracts/access/Ownable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (access/Ownable.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../utils/Context.sol\";\n\n/**\n * @dev Contract module which provides a basic access control mechanism, where\n * there is an account (an owner) that can be granted exclusive access to\n * specific functions.\n *\n * By default, the owner account will be the one that deploys the contract. This\n * can later be changed with {transferOwnership}.\n *\n * This module is used through inheritance. It will make available the modifier\n * `onlyOwner`, which can be applied to your functions to restrict their use to\n * the owner.\n */\nabstract contract Ownable is Context {\n address private _owner;\n\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\n\n /**\n * @dev Initializes the contract setting the deployer as the initial owner.\n */\n constructor() {\n _transferOwnership(_msgSender());\n }\n\n /**\n * @dev Throws if called by any account other than the owner.\n */\n modifier onlyOwner() {\n _checkOwner();\n _;\n }\n\n /**\n * @dev Returns the address of the current owner.\n */\n function owner() public view virtual returns (address) {\n return _owner;\n }\n\n /**\n * @dev Throws if the sender is not the owner.\n */\n function _checkOwner() internal view virtual {\n require(owner() == _msgSender(), \"Ownable: caller is not the owner\");\n }\n\n /**\n * @dev Leaves the contract without owner. It will not be possible to call\n * `onlyOwner` functions anymore. Can only be called by the current owner.\n *\n * NOTE: Renouncing ownership will leave the contract without an owner,\n * thereby removing any functionality that is only available to the owner.\n */\n function renounceOwnership() public virtual onlyOwner {\n _transferOwnership(address(0));\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Can only be called by the current owner.\n */\n function transferOwnership(address newOwner) public virtual onlyOwner {\n require(newOwner != address(0), \"Ownable: new owner is the zero address\");\n _transferOwnership(newOwner);\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Internal function without access restriction.\n */\n function _transferOwnership(address newOwner) internal virtual {\n address oldOwner = _owner;\n _owner = newOwner;\n emit OwnershipTransferred(oldOwner, newOwner);\n }\n}\n" + }, + "@openzeppelin/contracts/interfaces/draft-IERC1822.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.5.0) (interfaces/draft-IERC1822.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev ERC1822: Universal Upgradeable Proxy Standard (UUPS) documents a method for upgradeability through a simplified\n * proxy whose upgrades are fully controlled by the current implementation.\n */\ninterface IERC1822Proxiable {\n /**\n * @dev Returns the storage slot that the proxiable contract assumes is being used to store the implementation\n * address.\n *\n * IMPORTANT: A proxy pointing at a proxiable contract should not be considered proxiable itself, because this risks\n * bricking a proxy that upgrades to it, by delegating to itself until out of gas. Thus it is critical that this\n * function revert if invoked through a proxy.\n */\n function proxiableUUID() external view returns (bytes32);\n}\n" + }, + "@openzeppelin/contracts/interfaces/IERC3156FlashBorrower.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (interfaces/IERC3156FlashBorrower.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Interface of the ERC3156 FlashBorrower, as defined in\n * https://eips.ethereum.org/EIPS/eip-3156[ERC-3156].\n *\n * _Available since v4.1._\n */\ninterface IERC3156FlashBorrower {\n /**\n * @dev Receive a flash loan.\n * @param initiator The initiator of the loan.\n * @param token The loan currency.\n * @param amount The amount of tokens lent.\n * @param fee The additional amount of tokens to repay.\n * @param data Arbitrary data structure, intended to contain user-defined parameters.\n * @return The keccak256 hash of \"IERC3156FlashBorrower.onFlashLoan\"\n */\n function onFlashLoan(\n address initiator,\n address token,\n uint256 amount,\n uint256 fee,\n bytes calldata data\n ) external returns (bytes32);\n}\n" + }, + "@openzeppelin/contracts/interfaces/IERC3156FlashLender.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (interfaces/IERC3156FlashLender.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./IERC3156FlashBorrower.sol\";\n\n/**\n * @dev Interface of the ERC3156 FlashLender, as defined in\n * https://eips.ethereum.org/EIPS/eip-3156[ERC-3156].\n *\n * _Available since v4.1._\n */\ninterface IERC3156FlashLender {\n /**\n * @dev The amount of currency available to be lended.\n * @param token The loan currency.\n * @return The amount of `token` that can be borrowed.\n */\n function maxFlashLoan(address token) external view returns (uint256);\n\n /**\n * @dev The fee to be charged for a given loan.\n * @param token The loan currency.\n * @param amount The amount of tokens lent.\n * @return The amount of `token` to be charged for the loan, on top of the returned principal.\n */\n function flashFee(address token, uint256 amount) external view returns (uint256);\n\n /**\n * @dev Initiate a flash loan.\n * @param receiver The receiver of the tokens in the loan, and the receiver of the callback.\n * @param token The loan currency.\n * @param amount The amount of tokens lent.\n * @param data Arbitrary data structure, intended to contain user-defined parameters.\n */\n function flashLoan(\n IERC3156FlashBorrower receiver,\n address token,\n uint256 amount,\n bytes calldata data\n ) external returns (bool);\n}\n" + }, + "@openzeppelin/contracts/interfaces/IERC721Metadata.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (interfaces/IERC721Metadata.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../token/ERC721/extensions/IERC721Metadata.sol\";\n" + }, + "@openzeppelin/contracts/proxy/beacon/IBeacon.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (proxy/beacon/IBeacon.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev This is the interface that {BeaconProxy} expects of its beacon.\n */\ninterface IBeacon {\n /**\n * @dev Must return an address that can be used as a delegate call target.\n *\n * {BeaconProxy} will check that this address is a contract.\n */\n function implementation() external view returns (address);\n}\n" + }, + "@openzeppelin/contracts/proxy/ERC1967/ERC1967Proxy.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (proxy/ERC1967/ERC1967Proxy.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../Proxy.sol\";\nimport \"./ERC1967Upgrade.sol\";\n\n/**\n * @dev This contract implements an upgradeable proxy. It is upgradeable because calls are delegated to an\n * implementation address that can be changed. This address is stored in storage in the location specified by\n * https://eips.ethereum.org/EIPS/eip-1967[EIP1967], so that it doesn't conflict with the storage layout of the\n * implementation behind the proxy.\n */\ncontract ERC1967Proxy is Proxy, ERC1967Upgrade {\n /**\n * @dev Initializes the upgradeable proxy with an initial implementation specified by `_logic`.\n *\n * If `_data` is nonempty, it's used as data in a delegate call to `_logic`. This will typically be an encoded\n * function call, and allows initializing the storage of the proxy like a Solidity constructor.\n */\n constructor(address _logic, bytes memory _data) payable {\n _upgradeToAndCall(_logic, _data, false);\n }\n\n /**\n * @dev Returns the current implementation address.\n */\n function _implementation() internal view virtual override returns (address impl) {\n return ERC1967Upgrade._getImplementation();\n }\n}\n" + }, + "@openzeppelin/contracts/proxy/ERC1967/ERC1967Upgrade.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.5.0) (proxy/ERC1967/ERC1967Upgrade.sol)\n\npragma solidity ^0.8.2;\n\nimport \"../beacon/IBeacon.sol\";\nimport \"../../interfaces/draft-IERC1822.sol\";\nimport \"../../utils/Address.sol\";\nimport \"../../utils/StorageSlot.sol\";\n\n/**\n * @dev This abstract contract provides getters and event emitting update functions for\n * https://eips.ethereum.org/EIPS/eip-1967[EIP1967] slots.\n *\n * _Available since v4.1._\n *\n * @custom:oz-upgrades-unsafe-allow delegatecall\n */\nabstract contract ERC1967Upgrade {\n // This is the keccak-256 hash of \"eip1967.proxy.rollback\" subtracted by 1\n bytes32 private constant _ROLLBACK_SLOT = 0x4910fdfa16fed3260ed0e7147f7cc6da11a60208b5b9406d12a635614ffd9143;\n\n /**\n * @dev Storage slot with the address of the current implementation.\n * This is the keccak-256 hash of \"eip1967.proxy.implementation\" subtracted by 1, and is\n * validated in the constructor.\n */\n bytes32 internal constant _IMPLEMENTATION_SLOT = 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc;\n\n /**\n * @dev Emitted when the implementation is upgraded.\n */\n event Upgraded(address indexed implementation);\n\n /**\n * @dev Returns the current implementation address.\n */\n function _getImplementation() internal view returns (address) {\n return StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value;\n }\n\n /**\n * @dev Stores a new address in the EIP1967 implementation slot.\n */\n function _setImplementation(address newImplementation) private {\n require(Address.isContract(newImplementation), \"ERC1967: new implementation is not a contract\");\n StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value = newImplementation;\n }\n\n /**\n * @dev Perform implementation upgrade\n *\n * Emits an {Upgraded} event.\n */\n function _upgradeTo(address newImplementation) internal {\n _setImplementation(newImplementation);\n emit Upgraded(newImplementation);\n }\n\n /**\n * @dev Perform implementation upgrade with additional setup call.\n *\n * Emits an {Upgraded} event.\n */\n function _upgradeToAndCall(\n address newImplementation,\n bytes memory data,\n bool forceCall\n ) internal {\n _upgradeTo(newImplementation);\n if (data.length > 0 || forceCall) {\n Address.functionDelegateCall(newImplementation, data);\n }\n }\n\n /**\n * @dev Perform implementation upgrade with security checks for UUPS proxies, and additional setup call.\n *\n * Emits an {Upgraded} event.\n */\n function _upgradeToAndCallUUPS(\n address newImplementation,\n bytes memory data,\n bool forceCall\n ) internal {\n // Upgrades from old implementations will perform a rollback test. This test requires the new\n // implementation to upgrade back to the old, non-ERC1822 compliant, implementation. Removing\n // this special case will break upgrade paths from old UUPS implementation to new ones.\n if (StorageSlot.getBooleanSlot(_ROLLBACK_SLOT).value) {\n _setImplementation(newImplementation);\n } else {\n try IERC1822Proxiable(newImplementation).proxiableUUID() returns (bytes32 slot) {\n require(slot == _IMPLEMENTATION_SLOT, \"ERC1967Upgrade: unsupported proxiableUUID\");\n } catch {\n revert(\"ERC1967Upgrade: new implementation is not UUPS\");\n }\n _upgradeToAndCall(newImplementation, data, forceCall);\n }\n }\n\n /**\n * @dev Storage slot with the admin of the contract.\n * This is the keccak-256 hash of \"eip1967.proxy.admin\" subtracted by 1, and is\n * validated in the constructor.\n */\n bytes32 internal constant _ADMIN_SLOT = 0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103;\n\n /**\n * @dev Emitted when the admin account has changed.\n */\n event AdminChanged(address previousAdmin, address newAdmin);\n\n /**\n * @dev Returns the current admin.\n */\n function _getAdmin() internal view returns (address) {\n return StorageSlot.getAddressSlot(_ADMIN_SLOT).value;\n }\n\n /**\n * @dev Stores a new address in the EIP1967 admin slot.\n */\n function _setAdmin(address newAdmin) private {\n require(newAdmin != address(0), \"ERC1967: new admin is the zero address\");\n StorageSlot.getAddressSlot(_ADMIN_SLOT).value = newAdmin;\n }\n\n /**\n * @dev Changes the admin of the proxy.\n *\n * Emits an {AdminChanged} event.\n */\n function _changeAdmin(address newAdmin) internal {\n emit AdminChanged(_getAdmin(), newAdmin);\n _setAdmin(newAdmin);\n }\n\n /**\n * @dev The storage slot of the UpgradeableBeacon contract which defines the implementation for this proxy.\n * This is bytes32(uint256(keccak256('eip1967.proxy.beacon')) - 1)) and is validated in the constructor.\n */\n bytes32 internal constant _BEACON_SLOT = 0xa3f0ad74e5423aebfd80d3ef4346578335a9a72aeaee59ff6cb3582b35133d50;\n\n /**\n * @dev Emitted when the beacon is upgraded.\n */\n event BeaconUpgraded(address indexed beacon);\n\n /**\n * @dev Returns the current beacon.\n */\n function _getBeacon() internal view returns (address) {\n return StorageSlot.getAddressSlot(_BEACON_SLOT).value;\n }\n\n /**\n * @dev Stores a new beacon in the EIP1967 beacon slot.\n */\n function _setBeacon(address newBeacon) private {\n require(Address.isContract(newBeacon), \"ERC1967: new beacon is not a contract\");\n require(\n Address.isContract(IBeacon(newBeacon).implementation()),\n \"ERC1967: beacon implementation is not a contract\"\n );\n StorageSlot.getAddressSlot(_BEACON_SLOT).value = newBeacon;\n }\n\n /**\n * @dev Perform beacon upgrade with additional setup call. Note: This upgrades the address of the beacon, it does\n * not upgrade the implementation contained in the beacon (see {UpgradeableBeacon-_setImplementation} for that).\n *\n * Emits a {BeaconUpgraded} event.\n */\n function _upgradeBeaconToAndCall(\n address newBeacon,\n bytes memory data,\n bool forceCall\n ) internal {\n _setBeacon(newBeacon);\n emit BeaconUpgraded(newBeacon);\n if (data.length > 0 || forceCall) {\n Address.functionDelegateCall(IBeacon(newBeacon).implementation(), data);\n }\n }\n}\n" + }, + "@openzeppelin/contracts/proxy/Proxy.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.6.0) (proxy/Proxy.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev This abstract contract provides a fallback function that delegates all calls to another contract using the EVM\n * instruction `delegatecall`. We refer to the second contract as the _implementation_ behind the proxy, and it has to\n * be specified by overriding the virtual {_implementation} function.\n *\n * Additionally, delegation to the implementation can be triggered manually through the {_fallback} function, or to a\n * different contract through the {_delegate} function.\n *\n * The success and return data of the delegated call will be returned back to the caller of the proxy.\n */\nabstract contract Proxy {\n /**\n * @dev Delegates the current call to `implementation`.\n *\n * This function does not return to its internal call site, it will return directly to the external caller.\n */\n function _delegate(address implementation) internal virtual {\n assembly {\n // Copy msg.data. We take full control of memory in this inline assembly\n // block because it will not return to Solidity code. We overwrite the\n // Solidity scratch pad at memory position 0.\n calldatacopy(0, 0, calldatasize())\n\n // Call the implementation.\n // out and outsize are 0 because we don't know the size yet.\n let result := delegatecall(gas(), implementation, 0, calldatasize(), 0, 0)\n\n // Copy the returned data.\n returndatacopy(0, 0, returndatasize())\n\n switch result\n // delegatecall returns 0 on error.\n case 0 {\n revert(0, returndatasize())\n }\n default {\n return(0, returndatasize())\n }\n }\n }\n\n /**\n * @dev This is a virtual function that should be overridden so it returns the address to which the fallback function\n * and {_fallback} should delegate.\n */\n function _implementation() internal view virtual returns (address);\n\n /**\n * @dev Delegates the current call to the address returned by `_implementation()`.\n *\n * This function does not return to its internal call site, it will return directly to the external caller.\n */\n function _fallback() internal virtual {\n _beforeFallback();\n _delegate(_implementation());\n }\n\n /**\n * @dev Fallback function that delegates calls to the address returned by `_implementation()`. Will run if no other\n * function in the contract matches the call data.\n */\n fallback() external payable virtual {\n _fallback();\n }\n\n /**\n * @dev Fallback function that delegates calls to the address returned by `_implementation()`. Will run if call data\n * is empty.\n */\n receive() external payable virtual {\n _fallback();\n }\n\n /**\n * @dev Hook that is called before falling back to the implementation. Can happen as part of a manual `_fallback`\n * call, or as part of the Solidity `fallback` or `receive` functions.\n *\n * If overridden should call `super._beforeFallback()`.\n */\n function _beforeFallback() internal virtual {}\n}\n" + }, + "@openzeppelin/contracts/token/ERC20/ERC20.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (token/ERC20/ERC20.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./IERC20.sol\";\nimport \"./extensions/IERC20Metadata.sol\";\nimport \"../../utils/Context.sol\";\n\n/**\n * @dev Implementation of the {IERC20} interface.\n *\n * This implementation is agnostic to the way tokens are created. This means\n * that a supply mechanism has to be added in a derived contract using {_mint}.\n * For a generic mechanism see {ERC20PresetMinterPauser}.\n *\n * TIP: For a detailed writeup see our guide\n * https://forum.zeppelin.solutions/t/how-to-implement-erc20-supply-mechanisms/226[How\n * to implement supply mechanisms].\n *\n * We have followed general OpenZeppelin Contracts guidelines: functions revert\n * instead returning `false` on failure. This behavior is nonetheless\n * conventional and does not conflict with the expectations of ERC20\n * applications.\n *\n * Additionally, an {Approval} event is emitted on calls to {transferFrom}.\n * This allows applications to reconstruct the allowance for all accounts just\n * by listening to said events. Other implementations of the EIP may not emit\n * these events, as it isn't required by the specification.\n *\n * Finally, the non-standard {decreaseAllowance} and {increaseAllowance}\n * functions have been added to mitigate the well-known issues around setting\n * allowances. See {IERC20-approve}.\n */\ncontract ERC20 is Context, IERC20, IERC20Metadata {\n mapping(address => uint256) private _balances;\n\n mapping(address => mapping(address => uint256)) private _allowances;\n\n uint256 private _totalSupply;\n\n string private _name;\n string private _symbol;\n\n /**\n * @dev Sets the values for {name} and {symbol}.\n *\n * The default value of {decimals} is 18. To select a different value for\n * {decimals} you should overload it.\n *\n * All two of these values are immutable: they can only be set once during\n * construction.\n */\n constructor(string memory name_, string memory symbol_) {\n _name = name_;\n _symbol = symbol_;\n }\n\n /**\n * @dev Returns the name of the token.\n */\n function name() public view virtual override returns (string memory) {\n return _name;\n }\n\n /**\n * @dev Returns the symbol of the token, usually a shorter version of the\n * name.\n */\n function symbol() public view virtual override returns (string memory) {\n return _symbol;\n }\n\n /**\n * @dev Returns the number of decimals used to get its user representation.\n * For example, if `decimals` equals `2`, a balance of `505` tokens should\n * be displayed to a user as `5.05` (`505 / 10 ** 2`).\n *\n * Tokens usually opt for a value of 18, imitating the relationship between\n * Ether and Wei. This is the value {ERC20} uses, unless this function is\n * overridden;\n *\n * NOTE: This information is only used for _display_ purposes: it in\n * no way affects any of the arithmetic of the contract, including\n * {IERC20-balanceOf} and {IERC20-transfer}.\n */\n function decimals() public view virtual override returns (uint8) {\n return 18;\n }\n\n /**\n * @dev See {IERC20-totalSupply}.\n */\n function totalSupply() public view virtual override returns (uint256) {\n return _totalSupply;\n }\n\n /**\n * @dev See {IERC20-balanceOf}.\n */\n function balanceOf(address account) public view virtual override returns (uint256) {\n return _balances[account];\n }\n\n /**\n * @dev See {IERC20-transfer}.\n *\n * Requirements:\n *\n * - `to` cannot be the zero address.\n * - the caller must have a balance of at least `amount`.\n */\n function transfer(address to, uint256 amount) public virtual override returns (bool) {\n address owner = _msgSender();\n _transfer(owner, to, amount);\n return true;\n }\n\n /**\n * @dev See {IERC20-allowance}.\n */\n function allowance(address owner, address spender) public view virtual override returns (uint256) {\n return _allowances[owner][spender];\n }\n\n /**\n * @dev See {IERC20-approve}.\n *\n * NOTE: If `amount` is the maximum `uint256`, the allowance is not updated on\n * `transferFrom`. This is semantically equivalent to an infinite approval.\n *\n * Requirements:\n *\n * - `spender` cannot be the zero address.\n */\n function approve(address spender, uint256 amount) public virtual override returns (bool) {\n address owner = _msgSender();\n _approve(owner, spender, amount);\n return true;\n }\n\n /**\n * @dev See {IERC20-transferFrom}.\n *\n * Emits an {Approval} event indicating the updated allowance. This is not\n * required by the EIP. See the note at the beginning of {ERC20}.\n *\n * NOTE: Does not update the allowance if the current allowance\n * is the maximum `uint256`.\n *\n * Requirements:\n *\n * - `from` and `to` cannot be the zero address.\n * - `from` must have a balance of at least `amount`.\n * - the caller must have allowance for ``from``'s tokens of at least\n * `amount`.\n */\n function transferFrom(\n address from,\n address to,\n uint256 amount\n ) public virtual override returns (bool) {\n address spender = _msgSender();\n _spendAllowance(from, spender, amount);\n _transfer(from, to, amount);\n return true;\n }\n\n /**\n * @dev Atomically increases the allowance granted to `spender` by the caller.\n *\n * This is an alternative to {approve} that can be used as a mitigation for\n * problems described in {IERC20-approve}.\n *\n * Emits an {Approval} event indicating the updated allowance.\n *\n * Requirements:\n *\n * - `spender` cannot be the zero address.\n */\n function increaseAllowance(address spender, uint256 addedValue) public virtual returns (bool) {\n address owner = _msgSender();\n _approve(owner, spender, allowance(owner, spender) + addedValue);\n return true;\n }\n\n /**\n * @dev Atomically decreases the allowance granted to `spender` by the caller.\n *\n * This is an alternative to {approve} that can be used as a mitigation for\n * problems described in {IERC20-approve}.\n *\n * Emits an {Approval} event indicating the updated allowance.\n *\n * Requirements:\n *\n * - `spender` cannot be the zero address.\n * - `spender` must have allowance for the caller of at least\n * `subtractedValue`.\n */\n function decreaseAllowance(address spender, uint256 subtractedValue) public virtual returns (bool) {\n address owner = _msgSender();\n uint256 currentAllowance = allowance(owner, spender);\n require(currentAllowance >= subtractedValue, \"ERC20: decreased allowance below zero\");\n unchecked {\n _approve(owner, spender, currentAllowance - subtractedValue);\n }\n\n return true;\n }\n\n /**\n * @dev Moves `amount` of tokens from `from` to `to`.\n *\n * This internal function is equivalent to {transfer}, and can be used to\n * e.g. implement automatic token fees, slashing mechanisms, etc.\n *\n * Emits a {Transfer} event.\n *\n * Requirements:\n *\n * - `from` cannot be the zero address.\n * - `to` cannot be the zero address.\n * - `from` must have a balance of at least `amount`.\n */\n function _transfer(\n address from,\n address to,\n uint256 amount\n ) internal virtual {\n require(from != address(0), \"ERC20: transfer from the zero address\");\n require(to != address(0), \"ERC20: transfer to the zero address\");\n\n _beforeTokenTransfer(from, to, amount);\n\n uint256 fromBalance = _balances[from];\n require(fromBalance >= amount, \"ERC20: transfer amount exceeds balance\");\n unchecked {\n _balances[from] = fromBalance - amount;\n }\n _balances[to] += amount;\n\n emit Transfer(from, to, amount);\n\n _afterTokenTransfer(from, to, amount);\n }\n\n /** @dev Creates `amount` tokens and assigns them to `account`, increasing\n * the total supply.\n *\n * Emits a {Transfer} event with `from` set to the zero address.\n *\n * Requirements:\n *\n * - `account` cannot be the zero address.\n */\n function _mint(address account, uint256 amount) internal virtual {\n require(account != address(0), \"ERC20: mint to the zero address\");\n\n _beforeTokenTransfer(address(0), account, amount);\n\n _totalSupply += amount;\n _balances[account] += amount;\n emit Transfer(address(0), account, amount);\n\n _afterTokenTransfer(address(0), account, amount);\n }\n\n /**\n * @dev Destroys `amount` tokens from `account`, reducing the\n * total supply.\n *\n * Emits a {Transfer} event with `to` set to the zero address.\n *\n * Requirements:\n *\n * - `account` cannot be the zero address.\n * - `account` must have at least `amount` tokens.\n */\n function _burn(address account, uint256 amount) internal virtual {\n require(account != address(0), \"ERC20: burn from the zero address\");\n\n _beforeTokenTransfer(account, address(0), amount);\n\n uint256 accountBalance = _balances[account];\n require(accountBalance >= amount, \"ERC20: burn amount exceeds balance\");\n unchecked {\n _balances[account] = accountBalance - amount;\n }\n _totalSupply -= amount;\n\n emit Transfer(account, address(0), amount);\n\n _afterTokenTransfer(account, address(0), amount);\n }\n\n /**\n * @dev Sets `amount` as the allowance of `spender` over the `owner` s tokens.\n *\n * This internal function is equivalent to `approve`, and can be used to\n * e.g. set automatic allowances for certain subsystems, etc.\n *\n * Emits an {Approval} event.\n *\n * Requirements:\n *\n * - `owner` cannot be the zero address.\n * - `spender` cannot be the zero address.\n */\n function _approve(\n address owner,\n address spender,\n uint256 amount\n ) internal virtual {\n require(owner != address(0), \"ERC20: approve from the zero address\");\n require(spender != address(0), \"ERC20: approve to the zero address\");\n\n _allowances[owner][spender] = amount;\n emit Approval(owner, spender, amount);\n }\n\n /**\n * @dev Updates `owner` s allowance for `spender` based on spent `amount`.\n *\n * Does not update the allowance amount in case of infinite allowance.\n * Revert if not enough allowance is available.\n *\n * Might emit an {Approval} event.\n */\n function _spendAllowance(\n address owner,\n address spender,\n uint256 amount\n ) internal virtual {\n uint256 currentAllowance = allowance(owner, spender);\n if (currentAllowance != type(uint256).max) {\n require(currentAllowance >= amount, \"ERC20: insufficient allowance\");\n unchecked {\n _approve(owner, spender, currentAllowance - amount);\n }\n }\n }\n\n /**\n * @dev Hook that is called before any transfer of tokens. This includes\n * minting and burning.\n *\n * Calling conditions:\n *\n * - when `from` and `to` are both non-zero, `amount` of ``from``'s tokens\n * will be transferred to `to`.\n * - when `from` is zero, `amount` tokens will be minted for `to`.\n * - when `to` is zero, `amount` of ``from``'s tokens will be burned.\n * - `from` and `to` are never both zero.\n *\n * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].\n */\n function _beforeTokenTransfer(\n address from,\n address to,\n uint256 amount\n ) internal virtual {}\n\n /**\n * @dev Hook that is called after any transfer of tokens. This includes\n * minting and burning.\n *\n * Calling conditions:\n *\n * - when `from` and `to` are both non-zero, `amount` of ``from``'s tokens\n * has been transferred to `to`.\n * - when `from` is zero, `amount` tokens have been minted for `to`.\n * - when `to` is zero, `amount` of ``from``'s tokens have been burned.\n * - `from` and `to` are never both zero.\n *\n * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].\n */\n function _afterTokenTransfer(\n address from,\n address to,\n uint256 amount\n ) internal virtual {}\n}\n" + }, + "@openzeppelin/contracts/token/ERC20/extensions/draft-ERC20Permit.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.6.0) (token/ERC20/extensions/draft-ERC20Permit.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./draft-IERC20Permit.sol\";\nimport \"../ERC20.sol\";\nimport \"../../../utils/cryptography/draft-EIP712.sol\";\nimport \"../../../utils/cryptography/ECDSA.sol\";\nimport \"../../../utils/Counters.sol\";\n\n/**\n * @dev Implementation of the ERC20 Permit extension allowing approvals to be made via signatures, as defined in\n * https://eips.ethereum.org/EIPS/eip-2612[EIP-2612].\n *\n * Adds the {permit} method, which can be used to change an account's ERC20 allowance (see {IERC20-allowance}) by\n * presenting a message signed by the account. By not relying on `{IERC20-approve}`, the token holder account doesn't\n * need to send a transaction, and thus is not required to hold Ether at all.\n *\n * _Available since v3.4._\n */\nabstract contract ERC20Permit is ERC20, IERC20Permit, EIP712 {\n using Counters for Counters.Counter;\n\n mapping(address => Counters.Counter) private _nonces;\n\n // solhint-disable-next-line var-name-mixedcase\n bytes32 private constant _PERMIT_TYPEHASH =\n keccak256(\"Permit(address owner,address spender,uint256 value,uint256 nonce,uint256 deadline)\");\n /**\n * @dev In previous versions `_PERMIT_TYPEHASH` was declared as `immutable`.\n * However, to ensure consistency with the upgradeable transpiler, we will continue\n * to reserve a slot.\n * @custom:oz-renamed-from _PERMIT_TYPEHASH\n */\n // solhint-disable-next-line var-name-mixedcase\n bytes32 private _PERMIT_TYPEHASH_DEPRECATED_SLOT;\n\n /**\n * @dev Initializes the {EIP712} domain separator using the `name` parameter, and setting `version` to `\"1\"`.\n *\n * It's a good idea to use the same `name` that is defined as the ERC20 token name.\n */\n constructor(string memory name) EIP712(name, \"1\") {}\n\n /**\n * @dev See {IERC20Permit-permit}.\n */\n function permit(\n address owner,\n address spender,\n uint256 value,\n uint256 deadline,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) public virtual override {\n require(block.timestamp <= deadline, \"ERC20Permit: expired deadline\");\n\n bytes32 structHash = keccak256(abi.encode(_PERMIT_TYPEHASH, owner, spender, value, _useNonce(owner), deadline));\n\n bytes32 hash = _hashTypedDataV4(structHash);\n\n address signer = ECDSA.recover(hash, v, r, s);\n require(signer == owner, \"ERC20Permit: invalid signature\");\n\n _approve(owner, spender, value);\n }\n\n /**\n * @dev See {IERC20Permit-nonces}.\n */\n function nonces(address owner) public view virtual override returns (uint256) {\n return _nonces[owner].current();\n }\n\n /**\n * @dev See {IERC20Permit-DOMAIN_SEPARATOR}.\n */\n // solhint-disable-next-line func-name-mixedcase\n function DOMAIN_SEPARATOR() external view override returns (bytes32) {\n return _domainSeparatorV4();\n }\n\n /**\n * @dev \"Consume a nonce\": return the current value and increment.\n *\n * _Available since v4.1._\n */\n function _useNonce(address owner) internal virtual returns (uint256 current) {\n Counters.Counter storage nonce = _nonces[owner];\n current = nonce.current();\n nonce.increment();\n }\n}\n" + }, + "@openzeppelin/contracts/token/ERC20/extensions/draft-IERC20Permit.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (token/ERC20/extensions/draft-IERC20Permit.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Interface of the ERC20 Permit extension allowing approvals to be made via signatures, as defined in\n * https://eips.ethereum.org/EIPS/eip-2612[EIP-2612].\n *\n * Adds the {permit} method, which can be used to change an account's ERC20 allowance (see {IERC20-allowance}) by\n * presenting a message signed by the account. By not relying on {IERC20-approve}, the token holder account doesn't\n * need to send a transaction, and thus is not required to hold Ether at all.\n */\ninterface IERC20Permit {\n /**\n * @dev Sets `value` as the allowance of `spender` over ``owner``'s tokens,\n * given ``owner``'s signed approval.\n *\n * IMPORTANT: The same issues {IERC20-approve} has related to transaction\n * ordering also apply here.\n *\n * Emits an {Approval} event.\n *\n * Requirements:\n *\n * - `spender` cannot be the zero address.\n * - `deadline` must be a timestamp in the future.\n * - `v`, `r` and `s` must be a valid `secp256k1` signature from `owner`\n * over the EIP712-formatted function arguments.\n * - the signature must use ``owner``'s current nonce (see {nonces}).\n *\n * For more information on the signature format, see the\n * https://eips.ethereum.org/EIPS/eip-2612#specification[relevant EIP\n * section].\n */\n function permit(\n address owner,\n address spender,\n uint256 value,\n uint256 deadline,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) external;\n\n /**\n * @dev Returns the current nonce for `owner`. This value must be\n * included whenever a signature is generated for {permit}.\n *\n * Every successful call to {permit} increases ``owner``'s nonce by one. This\n * prevents a signature from being used multiple times.\n */\n function nonces(address owner) external view returns (uint256);\n\n /**\n * @dev Returns the domain separator used in the encoding of the signature for {permit}, as defined by {EIP712}.\n */\n // solhint-disable-next-line func-name-mixedcase\n function DOMAIN_SEPARATOR() external view returns (bytes32);\n}\n" + }, + "@openzeppelin/contracts/token/ERC20/extensions/IERC20Metadata.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (token/ERC20/extensions/IERC20Metadata.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../IERC20.sol\";\n\n/**\n * @dev Interface for the optional metadata functions from the ERC20 standard.\n *\n * _Available since v4.1._\n */\ninterface IERC20Metadata is IERC20 {\n /**\n * @dev Returns the name of the token.\n */\n function name() external view returns (string memory);\n\n /**\n * @dev Returns the symbol of the token.\n */\n function symbol() external view returns (string memory);\n\n /**\n * @dev Returns the decimals places of the token.\n */\n function decimals() external view returns (uint8);\n}\n" + }, + "@openzeppelin/contracts/token/ERC20/IERC20.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.6.0) (token/ERC20/IERC20.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Interface of the ERC20 standard as defined in the EIP.\n */\ninterface IERC20 {\n /**\n * @dev Emitted when `value` tokens are moved from one account (`from`) to\n * another (`to`).\n *\n * Note that `value` may be zero.\n */\n event Transfer(address indexed from, address indexed to, uint256 value);\n\n /**\n * @dev Emitted when the allowance of a `spender` for an `owner` is set by\n * a call to {approve}. `value` is the new allowance.\n */\n event Approval(address indexed owner, address indexed spender, uint256 value);\n\n /**\n * @dev Returns the amount of tokens in existence.\n */\n function totalSupply() external view returns (uint256);\n\n /**\n * @dev Returns the amount of tokens owned by `account`.\n */\n function balanceOf(address account) external view returns (uint256);\n\n /**\n * @dev Moves `amount` tokens from the caller's account to `to`.\n *\n * Returns a boolean value indicating whether the operation succeeded.\n *\n * Emits a {Transfer} event.\n */\n function transfer(address to, uint256 amount) external returns (bool);\n\n /**\n * @dev Returns the remaining number of tokens that `spender` will be\n * allowed to spend on behalf of `owner` through {transferFrom}. This is\n * zero by default.\n *\n * This value changes when {approve} or {transferFrom} are called.\n */\n function allowance(address owner, address spender) external view returns (uint256);\n\n /**\n * @dev Sets `amount` as the allowance of `spender` over the caller's tokens.\n *\n * Returns a boolean value indicating whether the operation succeeded.\n *\n * IMPORTANT: Beware that changing an allowance with this method brings the risk\n * that someone may use both the old and the new allowance by unfortunate\n * transaction ordering. One possible solution to mitigate this race\n * condition is to first reduce the spender's allowance to 0 and set the\n * desired value afterwards:\n * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729\n *\n * Emits an {Approval} event.\n */\n function approve(address spender, uint256 amount) external returns (bool);\n\n /**\n * @dev Moves `amount` tokens from `from` to `to` using the\n * allowance mechanism. `amount` is then deducted from the caller's\n * allowance.\n *\n * Returns a boolean value indicating whether the operation succeeded.\n *\n * Emits a {Transfer} event.\n */\n function transferFrom(\n address from,\n address to,\n uint256 amount\n ) external returns (bool);\n}\n" + }, + "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (token/ERC20/utils/SafeERC20.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../IERC20.sol\";\nimport \"../extensions/draft-IERC20Permit.sol\";\nimport \"../../../utils/Address.sol\";\n\n/**\n * @title SafeERC20\n * @dev Wrappers around ERC20 operations that throw on failure (when the token\n * contract returns false). Tokens that return no value (and instead revert or\n * throw on failure) are also supported, non-reverting calls are assumed to be\n * successful.\n * To use this library you can add a `using SafeERC20 for IERC20;` statement to your contract,\n * which allows you to call the safe operations as `token.safeTransfer(...)`, etc.\n */\nlibrary SafeERC20 {\n using Address for address;\n\n function safeTransfer(\n IERC20 token,\n address to,\n uint256 value\n ) internal {\n _callOptionalReturn(token, abi.encodeWithSelector(token.transfer.selector, to, value));\n }\n\n function safeTransferFrom(\n IERC20 token,\n address from,\n address to,\n uint256 value\n ) internal {\n _callOptionalReturn(token, abi.encodeWithSelector(token.transferFrom.selector, from, to, value));\n }\n\n /**\n * @dev Deprecated. This function has issues similar to the ones found in\n * {IERC20-approve}, and its usage is discouraged.\n *\n * Whenever possible, use {safeIncreaseAllowance} and\n * {safeDecreaseAllowance} instead.\n */\n function safeApprove(\n IERC20 token,\n address spender,\n uint256 value\n ) internal {\n // safeApprove should only be called when setting an initial allowance,\n // or when resetting it to zero. To increase and decrease it, use\n // 'safeIncreaseAllowance' and 'safeDecreaseAllowance'\n require(\n (value == 0) || (token.allowance(address(this), spender) == 0),\n \"SafeERC20: approve from non-zero to non-zero allowance\"\n );\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, value));\n }\n\n function safeIncreaseAllowance(\n IERC20 token,\n address spender,\n uint256 value\n ) internal {\n uint256 newAllowance = token.allowance(address(this), spender) + value;\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));\n }\n\n function safeDecreaseAllowance(\n IERC20 token,\n address spender,\n uint256 value\n ) internal {\n unchecked {\n uint256 oldAllowance = token.allowance(address(this), spender);\n require(oldAllowance >= value, \"SafeERC20: decreased allowance below zero\");\n uint256 newAllowance = oldAllowance - value;\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));\n }\n }\n\n function safePermit(\n IERC20Permit token,\n address owner,\n address spender,\n uint256 value,\n uint256 deadline,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) internal {\n uint256 nonceBefore = token.nonces(owner);\n token.permit(owner, spender, value, deadline, v, r, s);\n uint256 nonceAfter = token.nonces(owner);\n require(nonceAfter == nonceBefore + 1, \"SafeERC20: permit did not succeed\");\n }\n\n /**\n * @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement\n * on the return value: the return value is optional (but if data is returned, it must not be false).\n * @param token The token targeted by the call.\n * @param data The call data (encoded using abi.encode or one of its variants).\n */\n function _callOptionalReturn(IERC20 token, bytes memory data) private {\n // We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since\n // we're implementing it ourselves. We use {Address.functionCall} to perform this call, which verifies that\n // the target address contains contract code and also asserts for success in the low-level call.\n\n bytes memory returndata = address(token).functionCall(data, \"SafeERC20: low-level call failed\");\n if (returndata.length > 0) {\n // Return data is optional\n require(abi.decode(returndata, (bool)), \"SafeERC20: ERC20 operation did not succeed\");\n }\n }\n}\n" + }, + "@openzeppelin/contracts/token/ERC721/extensions/IERC721Metadata.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (token/ERC721/extensions/IERC721Metadata.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../IERC721.sol\";\n\n/**\n * @title ERC-721 Non-Fungible Token Standard, optional metadata extension\n * @dev See https://eips.ethereum.org/EIPS/eip-721\n */\ninterface IERC721Metadata is IERC721 {\n /**\n * @dev Returns the token collection name.\n */\n function name() external view returns (string memory);\n\n /**\n * @dev Returns the token collection symbol.\n */\n function symbol() external view returns (string memory);\n\n /**\n * @dev Returns the Uniform Resource Identifier (URI) for `tokenId` token.\n */\n function tokenURI(uint256 tokenId) external view returns (string memory);\n}\n" + }, + "@openzeppelin/contracts/token/ERC721/IERC721.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (token/ERC721/IERC721.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../../utils/introspection/IERC165.sol\";\n\n/**\n * @dev Required interface of an ERC721 compliant contract.\n */\ninterface IERC721 is IERC165 {\n /**\n * @dev Emitted when `tokenId` token is transferred from `from` to `to`.\n */\n event Transfer(address indexed from, address indexed to, uint256 indexed tokenId);\n\n /**\n * @dev Emitted when `owner` enables `approved` to manage the `tokenId` token.\n */\n event Approval(address indexed owner, address indexed approved, uint256 indexed tokenId);\n\n /**\n * @dev Emitted when `owner` enables or disables (`approved`) `operator` to manage all of its assets.\n */\n event ApprovalForAll(address indexed owner, address indexed operator, bool approved);\n\n /**\n * @dev Returns the number of tokens in ``owner``'s account.\n */\n function balanceOf(address owner) external view returns (uint256 balance);\n\n /**\n * @dev Returns the owner of the `tokenId` token.\n *\n * Requirements:\n *\n * - `tokenId` must exist.\n */\n function ownerOf(uint256 tokenId) external view returns (address owner);\n\n /**\n * @dev Safely transfers `tokenId` token from `from` to `to`.\n *\n * Requirements:\n *\n * - `from` cannot be the zero address.\n * - `to` cannot be the zero address.\n * - `tokenId` token must exist and be owned by `from`.\n * - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}.\n * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.\n *\n * Emits a {Transfer} event.\n */\n function safeTransferFrom(\n address from,\n address to,\n uint256 tokenId,\n bytes calldata data\n ) external;\n\n /**\n * @dev Safely transfers `tokenId` token from `from` to `to`, checking first that contract recipients\n * are aware of the ERC721 protocol to prevent tokens from being forever locked.\n *\n * Requirements:\n *\n * - `from` cannot be the zero address.\n * - `to` cannot be the zero address.\n * - `tokenId` token must exist and be owned by `from`.\n * - If the caller is not `from`, it must have been allowed to move this token by either {approve} or {setApprovalForAll}.\n * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.\n *\n * Emits a {Transfer} event.\n */\n function safeTransferFrom(\n address from,\n address to,\n uint256 tokenId\n ) external;\n\n /**\n * @dev Transfers `tokenId` token from `from` to `to`.\n *\n * WARNING: Usage of this method is discouraged, use {safeTransferFrom} whenever possible.\n *\n * Requirements:\n *\n * - `from` cannot be the zero address.\n * - `to` cannot be the zero address.\n * - `tokenId` token must be owned by `from`.\n * - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}.\n *\n * Emits a {Transfer} event.\n */\n function transferFrom(\n address from,\n address to,\n uint256 tokenId\n ) external;\n\n /**\n * @dev Gives permission to `to` to transfer `tokenId` token to another account.\n * The approval is cleared when the token is transferred.\n *\n * Only a single account can be approved at a time, so approving the zero address clears previous approvals.\n *\n * Requirements:\n *\n * - The caller must own the token or be an approved operator.\n * - `tokenId` must exist.\n *\n * Emits an {Approval} event.\n */\n function approve(address to, uint256 tokenId) external;\n\n /**\n * @dev Approve or remove `operator` as an operator for the caller.\n * Operators can call {transferFrom} or {safeTransferFrom} for any token owned by the caller.\n *\n * Requirements:\n *\n * - The `operator` cannot be the caller.\n *\n * Emits an {ApprovalForAll} event.\n */\n function setApprovalForAll(address operator, bool _approved) external;\n\n /**\n * @dev Returns the account approved for `tokenId` token.\n *\n * Requirements:\n *\n * - `tokenId` must exist.\n */\n function getApproved(uint256 tokenId) external view returns (address operator);\n\n /**\n * @dev Returns if the `operator` is allowed to manage all of the assets of `owner`.\n *\n * See {setApprovalForAll}\n */\n function isApprovedForAll(address owner, address operator) external view returns (bool);\n}\n" + }, + "@openzeppelin/contracts/utils/Address.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (utils/Address.sol)\n\npragma solidity ^0.8.1;\n\n/**\n * @dev Collection of functions related to the address type\n */\nlibrary Address {\n /**\n * @dev Returns true if `account` is a contract.\n *\n * [IMPORTANT]\n * ====\n * It is unsafe to assume that an address for which this function returns\n * false is an externally-owned account (EOA) and not a contract.\n *\n * Among others, `isContract` will return false for the following\n * types of addresses:\n *\n * - an externally-owned account\n * - a contract in construction\n * - an address where a contract will be created\n * - an address where a contract lived, but was destroyed\n * ====\n *\n * [IMPORTANT]\n * ====\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\n *\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\n * constructor.\n * ====\n */\n function isContract(address account) internal view returns (bool) {\n // This method relies on extcodesize/address.code.length, which returns 0\n // for contracts in construction, since the code is only stored at the end\n // of the constructor execution.\n\n return account.code.length > 0;\n }\n\n /**\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\n * `recipient`, forwarding all available gas and reverting on errors.\n *\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\n * imposed by `transfer`, making them unable to receive funds via\n * `transfer`. {sendValue} removes this limitation.\n *\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\n *\n * IMPORTANT: because control is transferred to `recipient`, care must be\n * taken to not create reentrancy vulnerabilities. Consider using\n * {ReentrancyGuard} or the\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\n */\n function sendValue(address payable recipient, uint256 amount) internal {\n require(address(this).balance >= amount, \"Address: insufficient balance\");\n\n (bool success, ) = recipient.call{value: amount}(\"\");\n require(success, \"Address: unable to send value, recipient may have reverted\");\n }\n\n /**\n * @dev Performs a Solidity function call using a low level `call`. A\n * plain `call` is an unsafe replacement for a function call: use this\n * function instead.\n *\n * If `target` reverts with a revert reason, it is bubbled up by this\n * function (like regular Solidity function calls).\n *\n * Returns the raw returned data. To convert to the expected return value,\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\n *\n * Requirements:\n *\n * - `target` must be a contract.\n * - calling `target` with `data` must not revert.\n *\n * _Available since v3.1._\n */\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionCall(target, data, \"Address: low-level call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\n * `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, 0, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but also transferring `value` wei to `target`.\n *\n * Requirements:\n *\n * - the calling contract must have an ETH balance of at least `value`.\n * - the called Solidity function must be `payable`.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, value, \"Address: low-level call with value failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\n * with `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(address(this).balance >= value, \"Address: insufficient balance for call\");\n require(isContract(target), \"Address: call to non-contract\");\n\n (bool success, bytes memory returndata) = target.call{value: value}(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\n return functionStaticCall(target, data, \"Address: low-level static call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal view returns (bytes memory) {\n require(isContract(target), \"Address: static call to non-contract\");\n\n (bool success, bytes memory returndata) = target.staticcall(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a delegate call.\n *\n * _Available since v3.4._\n */\n function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionDelegateCall(target, data, \"Address: low-level delegate call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a delegate call.\n *\n * _Available since v3.4._\n */\n function functionDelegateCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(isContract(target), \"Address: delegate call to non-contract\");\n\n (bool success, bytes memory returndata) = target.delegatecall(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the\n * revert reason using the provided one.\n *\n * _Available since v4.3._\n */\n function verifyCallResult(\n bool success,\n bytes memory returndata,\n string memory errorMessage\n ) internal pure returns (bytes memory) {\n if (success) {\n return returndata;\n } else {\n // Look for revert reason and bubble it up if present\n if (returndata.length > 0) {\n // The easiest way to bubble the revert reason is using memory via assembly\n /// @solidity memory-safe-assembly\n assembly {\n let returndata_size := mload(returndata)\n revert(add(32, returndata), returndata_size)\n }\n } else {\n revert(errorMessage);\n }\n }\n }\n}\n" + }, + "@openzeppelin/contracts/utils/Context.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Provides information about the current execution context, including the\n * sender of the transaction and its data. While these are generally available\n * via msg.sender and msg.data, they should not be accessed in such a direct\n * manner, since when dealing with meta-transactions the account sending and\n * paying for execution may not be the actual sender (as far as an application\n * is concerned).\n *\n * This contract is only required for intermediate, library-like contracts.\n */\nabstract contract Context {\n function _msgSender() internal view virtual returns (address) {\n return msg.sender;\n }\n\n function _msgData() internal view virtual returns (bytes calldata) {\n return msg.data;\n }\n}\n" + }, + "@openzeppelin/contracts/utils/Counters.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (utils/Counters.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @title Counters\n * @author Matt Condon (@shrugs)\n * @dev Provides counters that can only be incremented, decremented or reset. This can be used e.g. to track the number\n * of elements in a mapping, issuing ERC721 ids, or counting request ids.\n *\n * Include with `using Counters for Counters.Counter;`\n */\nlibrary Counters {\n struct Counter {\n // This variable should never be directly accessed by users of the library: interactions must be restricted to\n // the library's function. As of Solidity v0.5.2, this cannot be enforced, though there is a proposal to add\n // this feature: see https://github.com/ethereum/solidity/issues/4637\n uint256 _value; // default: 0\n }\n\n function current(Counter storage counter) internal view returns (uint256) {\n return counter._value;\n }\n\n function increment(Counter storage counter) internal {\n unchecked {\n counter._value += 1;\n }\n }\n\n function decrement(Counter storage counter) internal {\n uint256 value = counter._value;\n require(value > 0, \"Counter: decrement overflow\");\n unchecked {\n counter._value = value - 1;\n }\n }\n\n function reset(Counter storage counter) internal {\n counter._value = 0;\n }\n}\n" + }, + "@openzeppelin/contracts/utils/cryptography/draft-EIP712.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (utils/cryptography/draft-EIP712.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./ECDSA.sol\";\n\n/**\n * @dev https://eips.ethereum.org/EIPS/eip-712[EIP 712] is a standard for hashing and signing of typed structured data.\n *\n * The encoding specified in the EIP is very generic, and such a generic implementation in Solidity is not feasible,\n * thus this contract does not implement the encoding itself. Protocols need to implement the type-specific encoding\n * they need in their contracts using a combination of `abi.encode` and `keccak256`.\n *\n * This contract implements the EIP 712 domain separator ({_domainSeparatorV4}) that is used as part of the encoding\n * scheme, and the final step of the encoding to obtain the message digest that is then signed via ECDSA\n * ({_hashTypedDataV4}).\n *\n * The implementation of the domain separator was designed to be as efficient as possible while still properly updating\n * the chain id to protect against replay attacks on an eventual fork of the chain.\n *\n * NOTE: This contract implements the version of the encoding known as \"v4\", as implemented by the JSON RPC method\n * https://docs.metamask.io/guide/signing-data.html[`eth_signTypedDataV4` in MetaMask].\n *\n * _Available since v3.4._\n */\nabstract contract EIP712 {\n /* solhint-disable var-name-mixedcase */\n // Cache the domain separator as an immutable value, but also store the chain id that it corresponds to, in order to\n // invalidate the cached domain separator if the chain id changes.\n bytes32 private immutable _CACHED_DOMAIN_SEPARATOR;\n uint256 private immutable _CACHED_CHAIN_ID;\n address private immutable _CACHED_THIS;\n\n bytes32 private immutable _HASHED_NAME;\n bytes32 private immutable _HASHED_VERSION;\n bytes32 private immutable _TYPE_HASH;\n\n /* solhint-enable var-name-mixedcase */\n\n /**\n * @dev Initializes the domain separator and parameter caches.\n *\n * The meaning of `name` and `version` is specified in\n * https://eips.ethereum.org/EIPS/eip-712#definition-of-domainseparator[EIP 712]:\n *\n * - `name`: the user readable name of the signing domain, i.e. the name of the DApp or the protocol.\n * - `version`: the current major version of the signing domain.\n *\n * NOTE: These parameters cannot be changed except through a xref:learn::upgrading-smart-contracts.adoc[smart\n * contract upgrade].\n */\n constructor(string memory name, string memory version) {\n bytes32 hashedName = keccak256(bytes(name));\n bytes32 hashedVersion = keccak256(bytes(version));\n bytes32 typeHash = keccak256(\n \"EIP712Domain(string name,string version,uint256 chainId,address verifyingContract)\"\n );\n _HASHED_NAME = hashedName;\n _HASHED_VERSION = hashedVersion;\n _CACHED_CHAIN_ID = block.chainid;\n _CACHED_DOMAIN_SEPARATOR = _buildDomainSeparator(typeHash, hashedName, hashedVersion);\n _CACHED_THIS = address(this);\n _TYPE_HASH = typeHash;\n }\n\n /**\n * @dev Returns the domain separator for the current chain.\n */\n function _domainSeparatorV4() internal view returns (bytes32) {\n if (address(this) == _CACHED_THIS && block.chainid == _CACHED_CHAIN_ID) {\n return _CACHED_DOMAIN_SEPARATOR;\n } else {\n return _buildDomainSeparator(_TYPE_HASH, _HASHED_NAME, _HASHED_VERSION);\n }\n }\n\n function _buildDomainSeparator(\n bytes32 typeHash,\n bytes32 nameHash,\n bytes32 versionHash\n ) private view returns (bytes32) {\n return keccak256(abi.encode(typeHash, nameHash, versionHash, block.chainid, address(this)));\n }\n\n /**\n * @dev Given an already https://eips.ethereum.org/EIPS/eip-712#definition-of-hashstruct[hashed struct], this\n * function returns the hash of the fully encoded EIP712 message for this domain.\n *\n * This hash can be used together with {ECDSA-recover} to obtain the signer of a message. For example:\n *\n * ```solidity\n * bytes32 digest = _hashTypedDataV4(keccak256(abi.encode(\n * keccak256(\"Mail(address to,string contents)\"),\n * mailTo,\n * keccak256(bytes(mailContents))\n * )));\n * address signer = ECDSA.recover(digest, signature);\n * ```\n */\n function _hashTypedDataV4(bytes32 structHash) internal view virtual returns (bytes32) {\n return ECDSA.toTypedDataHash(_domainSeparatorV4(), structHash);\n }\n}\n" + }, + "@openzeppelin/contracts/utils/cryptography/ECDSA.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (utils/cryptography/ECDSA.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../Strings.sol\";\n\n/**\n * @dev Elliptic Curve Digital Signature Algorithm (ECDSA) operations.\n *\n * These functions can be used to verify that a message was signed by the holder\n * of the private keys of a given address.\n */\nlibrary ECDSA {\n enum RecoverError {\n NoError,\n InvalidSignature,\n InvalidSignatureLength,\n InvalidSignatureS,\n InvalidSignatureV\n }\n\n function _throwError(RecoverError error) private pure {\n if (error == RecoverError.NoError) {\n return; // no error: do nothing\n } else if (error == RecoverError.InvalidSignature) {\n revert(\"ECDSA: invalid signature\");\n } else if (error == RecoverError.InvalidSignatureLength) {\n revert(\"ECDSA: invalid signature length\");\n } else if (error == RecoverError.InvalidSignatureS) {\n revert(\"ECDSA: invalid signature 's' value\");\n } else if (error == RecoverError.InvalidSignatureV) {\n revert(\"ECDSA: invalid signature 'v' value\");\n }\n }\n\n /**\n * @dev Returns the address that signed a hashed message (`hash`) with\n * `signature` or error string. This address can then be used for verification purposes.\n *\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\n * this function rejects them by requiring the `s` value to be in the lower\n * half order, and the `v` value to be either 27 or 28.\n *\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\n * verification to be secure: it is possible to craft signatures that\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\n * this is by receiving a hash of the original message (which may otherwise\n * be too long), and then calling {toEthSignedMessageHash} on it.\n *\n * Documentation for signature generation:\n * - with https://web3js.readthedocs.io/en/v1.3.4/web3-eth-accounts.html#sign[Web3.js]\n * - with https://docs.ethers.io/v5/api/signer/#Signer-signMessage[ethers]\n *\n * _Available since v4.3._\n */\n function tryRecover(bytes32 hash, bytes memory signature) internal pure returns (address, RecoverError) {\n // Check the signature length\n // - case 65: r,s,v signature (standard)\n // - case 64: r,vs signature (cf https://eips.ethereum.org/EIPS/eip-2098) _Available since v4.1._\n if (signature.length == 65) {\n bytes32 r;\n bytes32 s;\n uint8 v;\n // ecrecover takes the signature parameters, and the only way to get them\n // currently is to use assembly.\n /// @solidity memory-safe-assembly\n assembly {\n r := mload(add(signature, 0x20))\n s := mload(add(signature, 0x40))\n v := byte(0, mload(add(signature, 0x60)))\n }\n return tryRecover(hash, v, r, s);\n } else if (signature.length == 64) {\n bytes32 r;\n bytes32 vs;\n // ecrecover takes the signature parameters, and the only way to get them\n // currently is to use assembly.\n /// @solidity memory-safe-assembly\n assembly {\n r := mload(add(signature, 0x20))\n vs := mload(add(signature, 0x40))\n }\n return tryRecover(hash, r, vs);\n } else {\n return (address(0), RecoverError.InvalidSignatureLength);\n }\n }\n\n /**\n * @dev Returns the address that signed a hashed message (`hash`) with\n * `signature`. This address can then be used for verification purposes.\n *\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\n * this function rejects them by requiring the `s` value to be in the lower\n * half order, and the `v` value to be either 27 or 28.\n *\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\n * verification to be secure: it is possible to craft signatures that\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\n * this is by receiving a hash of the original message (which may otherwise\n * be too long), and then calling {toEthSignedMessageHash} on it.\n */\n function recover(bytes32 hash, bytes memory signature) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, signature);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Overload of {ECDSA-tryRecover} that receives the `r` and `vs` short-signature fields separately.\n *\n * See https://eips.ethereum.org/EIPS/eip-2098[EIP-2098 short signatures]\n *\n * _Available since v4.3._\n */\n function tryRecover(\n bytes32 hash,\n bytes32 r,\n bytes32 vs\n ) internal pure returns (address, RecoverError) {\n bytes32 s = vs & bytes32(0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff);\n uint8 v = uint8((uint256(vs) >> 255) + 27);\n return tryRecover(hash, v, r, s);\n }\n\n /**\n * @dev Overload of {ECDSA-recover} that receives the `r and `vs` short-signature fields separately.\n *\n * _Available since v4.2._\n */\n function recover(\n bytes32 hash,\n bytes32 r,\n bytes32 vs\n ) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, r, vs);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Overload of {ECDSA-tryRecover} that receives the `v`,\n * `r` and `s` signature fields separately.\n *\n * _Available since v4.3._\n */\n function tryRecover(\n bytes32 hash,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) internal pure returns (address, RecoverError) {\n // EIP-2 still allows signature malleability for ecrecover(). Remove this possibility and make the signature\n // unique. Appendix F in the Ethereum Yellow paper (https://ethereum.github.io/yellowpaper/paper.pdf), defines\n // the valid range for s in (301): 0 < s < secp256k1n ÷ 2 + 1, and for v in (302): v ∈ {27, 28}. Most\n // signatures from current libraries generate a unique signature with an s-value in the lower half order.\n //\n // If your library generates malleable signatures, such as s-values in the upper range, calculate a new s-value\n // with 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141 - s1 and flip v from 27 to 28 or\n // vice versa. If your library also generates signatures with 0/1 for v instead 27/28, add 27 to v to accept\n // these malleable signatures as well.\n if (uint256(s) > 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D576E7357A4501DDFE92F46681B20A0) {\n return (address(0), RecoverError.InvalidSignatureS);\n }\n if (v != 27 && v != 28) {\n return (address(0), RecoverError.InvalidSignatureV);\n }\n\n // If the signature is valid (and not malleable), return the signer address\n address signer = ecrecover(hash, v, r, s);\n if (signer == address(0)) {\n return (address(0), RecoverError.InvalidSignature);\n }\n\n return (signer, RecoverError.NoError);\n }\n\n /**\n * @dev Overload of {ECDSA-recover} that receives the `v`,\n * `r` and `s` signature fields separately.\n */\n function recover(\n bytes32 hash,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, v, r, s);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Returns an Ethereum Signed Message, created from a `hash`. This\n * produces hash corresponding to the one signed with the\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\n * JSON-RPC method as part of EIP-191.\n *\n * See {recover}.\n */\n function toEthSignedMessageHash(bytes32 hash) internal pure returns (bytes32) {\n // 32 is the length in bytes of hash,\n // enforced by the type signature above\n return keccak256(abi.encodePacked(\"\\x19Ethereum Signed Message:\\n32\", hash));\n }\n\n /**\n * @dev Returns an Ethereum Signed Message, created from `s`. This\n * produces hash corresponding to the one signed with the\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\n * JSON-RPC method as part of EIP-191.\n *\n * See {recover}.\n */\n function toEthSignedMessageHash(bytes memory s) internal pure returns (bytes32) {\n return keccak256(abi.encodePacked(\"\\x19Ethereum Signed Message:\\n\", Strings.toString(s.length), s));\n }\n\n /**\n * @dev Returns an Ethereum Signed Typed Data, created from a\n * `domainSeparator` and a `structHash`. This produces hash corresponding\n * to the one signed with the\n * https://eips.ethereum.org/EIPS/eip-712[`eth_signTypedData`]\n * JSON-RPC method as part of EIP-712.\n *\n * See {recover}.\n */\n function toTypedDataHash(bytes32 domainSeparator, bytes32 structHash) internal pure returns (bytes32) {\n return keccak256(abi.encodePacked(\"\\x19\\x01\", domainSeparator, structHash));\n }\n}\n" + }, + "@openzeppelin/contracts/utils/introspection/IERC165.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (utils/introspection/IERC165.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Interface of the ERC165 standard, as defined in the\n * https://eips.ethereum.org/EIPS/eip-165[EIP].\n *\n * Implementers can declare support of contract interfaces, which can then be\n * queried by others ({ERC165Checker}).\n *\n * For an implementation, see {ERC165}.\n */\ninterface IERC165 {\n /**\n * @dev Returns true if this contract implements the interface defined by\n * `interfaceId`. See the corresponding\n * https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified[EIP section]\n * to learn more about how these ids are created.\n *\n * This function call must use less than 30 000 gas.\n */\n function supportsInterface(bytes4 interfaceId) external view returns (bool);\n}\n" + }, + "@openzeppelin/contracts/utils/StorageSlot.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (utils/StorageSlot.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Library for reading and writing primitive types to specific storage slots.\n *\n * Storage slots are often used to avoid storage conflict when dealing with upgradeable contracts.\n * This library helps with reading and writing to such slots without the need for inline assembly.\n *\n * The functions in this library return Slot structs that contain a `value` member that can be used to read or write.\n *\n * Example usage to set ERC1967 implementation slot:\n * ```\n * contract ERC1967 {\n * bytes32 internal constant _IMPLEMENTATION_SLOT = 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc;\n *\n * function _getImplementation() internal view returns (address) {\n * return StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value;\n * }\n *\n * function _setImplementation(address newImplementation) internal {\n * require(Address.isContract(newImplementation), \"ERC1967: new implementation is not a contract\");\n * StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value = newImplementation;\n * }\n * }\n * ```\n *\n * _Available since v4.1 for `address`, `bool`, `bytes32`, and `uint256`._\n */\nlibrary StorageSlot {\n struct AddressSlot {\n address value;\n }\n\n struct BooleanSlot {\n bool value;\n }\n\n struct Bytes32Slot {\n bytes32 value;\n }\n\n struct Uint256Slot {\n uint256 value;\n }\n\n /**\n * @dev Returns an `AddressSlot` with member `value` located at `slot`.\n */\n function getAddressSlot(bytes32 slot) internal pure returns (AddressSlot storage r) {\n /// @solidity memory-safe-assembly\n assembly {\n r.slot := slot\n }\n }\n\n /**\n * @dev Returns an `BooleanSlot` with member `value` located at `slot`.\n */\n function getBooleanSlot(bytes32 slot) internal pure returns (BooleanSlot storage r) {\n /// @solidity memory-safe-assembly\n assembly {\n r.slot := slot\n }\n }\n\n /**\n * @dev Returns an `Bytes32Slot` with member `value` located at `slot`.\n */\n function getBytes32Slot(bytes32 slot) internal pure returns (Bytes32Slot storage r) {\n /// @solidity memory-safe-assembly\n assembly {\n r.slot := slot\n }\n }\n\n /**\n * @dev Returns an `Uint256Slot` with member `value` located at `slot`.\n */\n function getUint256Slot(bytes32 slot) internal pure returns (Uint256Slot storage r) {\n /// @solidity memory-safe-assembly\n assembly {\n r.slot := slot\n }\n }\n}\n" + }, + "@openzeppelin/contracts/utils/Strings.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (utils/Strings.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev String operations.\n */\nlibrary Strings {\n bytes16 private constant _HEX_SYMBOLS = \"0123456789abcdef\";\n uint8 private constant _ADDRESS_LENGTH = 20;\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` decimal representation.\n */\n function toString(uint256 value) internal pure returns (string memory) {\n // Inspired by OraclizeAPI's implementation - MIT licence\n // https://github.com/oraclize/ethereum-api/blob/b42146b063c7d6ee1358846c198246239e9360e8/oraclizeAPI_0.4.25.sol\n\n if (value == 0) {\n return \"0\";\n }\n uint256 temp = value;\n uint256 digits;\n while (temp != 0) {\n digits++;\n temp /= 10;\n }\n bytes memory buffer = new bytes(digits);\n while (value != 0) {\n digits -= 1;\n buffer[digits] = bytes1(uint8(48 + uint256(value % 10)));\n value /= 10;\n }\n return string(buffer);\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation.\n */\n function toHexString(uint256 value) internal pure returns (string memory) {\n if (value == 0) {\n return \"0x00\";\n }\n uint256 temp = value;\n uint256 length = 0;\n while (temp != 0) {\n length++;\n temp >>= 8;\n }\n return toHexString(value, length);\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length.\n */\n function toHexString(uint256 value, uint256 length) internal pure returns (string memory) {\n bytes memory buffer = new bytes(2 * length + 2);\n buffer[0] = \"0\";\n buffer[1] = \"x\";\n for (uint256 i = 2 * length + 1; i > 1; --i) {\n buffer[i] = _HEX_SYMBOLS[value & 0xf];\n value >>= 4;\n }\n require(value == 0, \"Strings: hex length insufficient\");\n return string(buffer);\n }\n\n /**\n * @dev Converts an `address` with fixed length of 20 bytes to its not checksummed ASCII `string` hexadecimal representation.\n */\n function toHexString(address addr) internal pure returns (string memory) {\n return toHexString(uint256(uint160(addr)), _ADDRESS_LENGTH);\n }\n}\n" + }, + "contracts/agToken/AgEUR.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\nimport \"../interfaces/IAgToken.sol\";\nimport \"../interfaces/coreModule/IStableMaster.sol\";\nimport \"../interfaces/ITreasury.sol\";\nimport \"@openzeppelin/contracts-upgradeable/token/ERC20/extensions/draft-ERC20PermitUpgradeable.sol\";\n\n/// @title AgEUR\n/// @author Angle Labs, Inc.\n/// @notice Base contract for agEUR, Angle's Euro stablecoin\n/// @dev This contract is an upgraded version of the agEUR contract that was first deployed on Ethereum mainnet\ncontract AgEUR is IAgToken, ERC20PermitUpgradeable {\n // ================================= REFERENCES ================================\n\n /// @notice Reference to the `StableMaster` contract associated to agEUR\n address public stableMaster;\n\n /// @custom:oz-upgrades-unsafe-allow constructor\n constructor() initializer {}\n\n // ============================== ADDED PARAMETERS =============================\n\n /// @inheritdoc IAgToken\n mapping(address => bool) public isMinter;\n /// @notice Reference to the treasury contract which can grant minting rights\n address public treasury;\n /// @notice Boolean used to check whether the contract had been reinitialized after an upgrade\n bool public treasuryInitialized;\n\n // =================================== EVENTS ==================================\n\n event TreasuryUpdated(address indexed _treasury);\n event MinterToggled(address indexed minter);\n\n // =================================== ERRORS ==================================\n\n error BurnAmountExceedsAllowance();\n error InvalidSender();\n error InvalidTreasury();\n error NotGovernor();\n error NotMinter();\n error NotTreasury();\n error TreasuryAlreadyInitialized();\n\n // ================================= MODIFIERS =================================\n\n /// @notice Checks to see if it is the `Treasury` calling this contract\n modifier onlyTreasury() {\n if (msg.sender != treasury) revert NotTreasury();\n _;\n }\n\n /// @notice Checks whether the sender has the minting right\n modifier onlyMinter() {\n if (!isMinter[msg.sender]) revert NotMinter();\n _;\n }\n\n // ============================= EXTERNAL FUNCTION =============================\n\n /// @notice Allows anyone to burn stablecoins\n /// @param amount Amount of stablecoins to burn\n /// @dev This function can typically be called if there is a settlement mechanism to burn stablecoins\n function burnStablecoin(uint256 amount) external {\n _burn(msg.sender, amount);\n }\n\n // ========================= MINTER ROLE ONLY FUNCTIONS ========================\n\n /// @inheritdoc IAgToken\n function burnSelf(uint256 amount, address burner) external onlyMinter {\n _burn(burner, amount);\n }\n\n /// @inheritdoc IAgToken\n function burnFrom(uint256 amount, address burner, address sender) external onlyMinter {\n if (burner != sender) {\n uint256 currentAllowance = allowance(burner, sender);\n if (currentAllowance < amount) revert BurnAmountExceedsAllowance();\n _approve(burner, sender, currentAllowance - amount);\n }\n _burn(burner, amount);\n }\n\n /// @inheritdoc IAgToken\n function mint(address account, uint256 amount) external onlyMinter {\n _mint(account, amount);\n }\n\n // ========================== TREASURY ONLY FUNCTIONS ==========================\n\n /// @inheritdoc IAgToken\n function addMinter(address minter) external onlyTreasury {\n isMinter[minter] = true;\n emit MinterToggled(minter);\n }\n\n /// @inheritdoc IAgToken\n function removeMinter(address minter) external {\n if (msg.sender != minter && msg.sender != address(treasury)) revert InvalidSender();\n isMinter[minter] = false;\n emit MinterToggled(minter);\n }\n\n /// @inheritdoc IAgToken\n function setTreasury(address _treasury) external onlyTreasury {\n treasury = _treasury;\n emit TreasuryUpdated(_treasury);\n }\n}\n" + }, + "contracts/agToken/AgToken.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\n/*\n * █ \n ***** ▓▓▓ \n * ▓▓▓▓▓▓▓ \n * ///. ▓▓▓▓▓▓▓▓▓▓▓▓▓ \n ***** //////// ▓▓▓▓▓▓▓ \n * ///////////// ▓▓▓ \n ▓▓ ////////////////// █ ▓▓ \n ▓▓ ▓▓ /////////////////////// ▓▓ ▓▓ \n ▓▓ ▓▓ //////////////////////////// ▓▓ ▓▓ \n ▓▓ ▓▓ /////////▓▓▓///////▓▓▓///////// ▓▓ ▓▓ \n ▓▓ ,////////////////////////////////////// ▓▓ ▓▓ \n ▓▓ ////////////////////////////////////////// ▓▓ \n ▓▓ //////////////////////▓▓▓▓///////////////////// \n ,//////////////////////////////////////////////////// \n .////////////////////////////////////////////////////////// \n .//////////////////////////██.,//////////////////////////█ \n .//////////////////////████..,./////////////////////██ \n ...////////////////███████.....,.////////////////███ \n ,.,////////////████████ ........,///////////████ \n .,.,//////█████████ ,.......///////████ \n ,..//████████ ........./████ \n ..,██████ .....,███ \n .██ ,.,█ \n \n \n \n ▓▓ ▓▓▓▓▓▓▓▓▓▓ ▓▓▓▓▓▓▓▓▓▓ ▓▓ ▓▓▓▓▓▓▓▓▓▓ \n ▓▓▓▓▓▓ ▓▓▓ ▓▓▓ ▓▓▓ ▓▓ ▓▓ ▓▓▓▓ \n ▓▓▓ ▓▓▓ ▓▓▓ ▓▓▓ ▓▓▓ ▓▓▓ ▓▓ ▓▓▓▓▓ \n ▓▓▓ ▓▓ ▓▓▓ ▓▓▓ ▓▓▓▓▓▓▓▓▓▓ ▓▓▓▓▓▓▓▓▓▓ ▓▓▓▓▓▓▓▓▓▓ \n*/\n\nimport \"../interfaces/IAgToken.sol\";\nimport \"../interfaces/ITreasury.sol\";\nimport \"@openzeppelin/contracts-upgradeable/token/ERC20/extensions/draft-ERC20PermitUpgradeable.sol\";\n\n/// @title AgToken\n/// @author Angle Labs, Inc.\n/// @notice Base contract for Angle agTokens on Ethereum and on other chains\n/// @dev By default, agTokens are ERC-20 tokens with 18 decimals\ncontract AgToken is IAgToken, ERC20PermitUpgradeable {\n // =========================== PARAMETERS / VARIABLES ==========================\n\n /// @inheritdoc IAgToken\n mapping(address => bool) public isMinter;\n /// @notice Reference to the treasury contract which can grant minting rights\n address public treasury;\n\n // =================================== EVENTS ==================================\n\n event TreasuryUpdated(address indexed _treasury);\n event MinterToggled(address indexed minter);\n\n // =================================== ERRORS ==================================\n\n error BurnAmountExceedsAllowance();\n error InvalidSender();\n error InvalidTreasury();\n error NotMinter();\n error NotTreasury();\n\n // ================================ CONSTRUCTOR ================================\n\n /// @custom:oz-upgrades-unsafe-allow constructor\n constructor() initializer {}\n\n /// @notice Initializes the `AgToken` contract\n function initialize(string memory name_, string memory symbol_, address _treasury) external {\n _initialize(name_, symbol_, _treasury);\n }\n\n /// @notice Initializes the contract\n function _initialize(string memory name_, string memory symbol_, address _treasury) internal virtual initializer {\n if (address(ITreasury(_treasury).stablecoin()) != address(this)) revert InvalidTreasury();\n __ERC20Permit_init(name_);\n __ERC20_init(name_, symbol_);\n treasury = _treasury;\n emit TreasuryUpdated(_treasury);\n }\n\n // ================================= MODIFIERS =================================\n\n /// @notice Checks to see if it is the `Treasury` calling this contract\n modifier onlyTreasury() {\n if (msg.sender != treasury) revert NotTreasury();\n _;\n }\n\n /// @notice Checks whether the sender has the minting right\n modifier onlyMinter() {\n if (!isMinter[msg.sender]) revert NotMinter();\n _;\n }\n\n // ============================= EXTERNAL FUNCTION =============================\n\n /// @notice Allows anyone to burn stablecoins\n /// @param amount Amount of stablecoins to burn\n /// @dev This function can typically be called if there is a settlement mechanism to burn stablecoins\n function burnStablecoin(uint256 amount) external {\n _burn(msg.sender, amount);\n }\n\n // ========================= MINTER ROLE ONLY FUNCTIONS ========================\n\n /// @inheritdoc IAgToken\n function burnSelf(uint256 amount, address burner) external onlyMinter {\n _burn(burner, amount);\n }\n\n /// @inheritdoc IAgToken\n function burnFrom(uint256 amount, address burner, address sender) external onlyMinter {\n if (burner != sender) {\n uint256 currentAllowance = allowance(burner, sender);\n if (currentAllowance < amount) revert BurnAmountExceedsAllowance();\n _approve(burner, sender, currentAllowance - amount);\n }\n _burn(burner, amount);\n }\n\n /// @inheritdoc IAgToken\n function mint(address account, uint256 amount) external onlyMinter {\n _mint(account, amount);\n }\n\n // ========================== GOVERNANCE ONLY FUNCTIONS ==========================\n\n /// @inheritdoc IAgToken\n function addMinter(address minter) external onlyTreasury {\n isMinter[minter] = true;\n emit MinterToggled(minter);\n }\n\n /// @inheritdoc IAgToken\n function removeMinter(address minter) external {\n if (msg.sender != address(treasury) && msg.sender != minter) revert InvalidSender();\n isMinter[minter] = false;\n emit MinterToggled(minter);\n }\n\n /// @inheritdoc IAgToken\n function setTreasury(address _treasury) external virtual onlyTreasury {\n treasury = _treasury;\n emit TreasuryUpdated(_treasury);\n }\n}\n" + }, + "contracts/agToken/AgTokenSideChainMultiBridge.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\nimport \"./AgToken.sol\";\nimport \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\nimport \"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\";\n\n/// @title AgTokenSideChainMultiBridge\n/// @author Angle Labs, Inc.\n/// @notice Contract for Angle agTokens on other chains than Ethereum mainnet\n/// @dev This contract supports bridge tokens having a minting right on the stablecoin (also referred to as the canonical\n/// or the native token)\ncontract AgTokenSideChainMultiBridge is AgToken {\n using SafeERC20 for IERC20;\n\n /// @notice Base used for fee computation\n uint256 public constant BASE_PARAMS = 1e9;\n\n // =============================== BRIDGING DATA ===============================\n\n /// @notice Struct with some data about a specific bridge token\n struct BridgeDetails {\n // Limit on the balance of bridge token held by the contract: it is designed\n // to reduce the exposure of the system to hacks\n uint256 limit;\n // Limit on the hourly volume of token minted through this bridge\n // Technically the limit over a rolling hour is hourlyLimit x2 as hourly limit\n // is enforced only between x:00 and x+1:00\n uint256 hourlyLimit;\n // Fee taken for swapping in and out the token\n uint64 fee;\n // Whether the associated token is allowed or not\n bool allowed;\n // Whether swapping in and out from the associated token is paused or not\n bool paused;\n }\n\n /// @notice Maps a bridge token to data\n mapping(address => BridgeDetails) public bridges;\n /// @notice List of all bridge tokens\n address[] public bridgeTokensList;\n /// @notice Maps a bridge token to the associated hourly volume\n mapping(address => mapping(uint256 => uint256)) public usage;\n /// @notice Maps an address to whether it is exempt of fees for when it comes to swapping in and out\n mapping(address => uint256) public isFeeExempt;\n /// @notice Limit to the amount of tokens that can be sent from that chain to another chain\n uint256 public chainTotalHourlyLimit;\n /// @notice Usage per hour on that chain. Maps an hourly timestamp to the total volume swapped out on the chain\n mapping(uint256 => uint256) public chainTotalUsage;\n\n // =================================== EVENTS ==================================\n\n event BridgeTokenAdded(address indexed bridgeToken, uint256 limit, uint256 hourlyLimit, uint64 fee, bool paused);\n event BridgeTokenToggled(address indexed bridgeToken, bool toggleStatus);\n event BridgeTokenRemoved(address indexed bridgeToken);\n event BridgeTokenFeeUpdated(address indexed bridgeToken, uint64 fee);\n event BridgeTokenLimitUpdated(address indexed bridgeToken, uint256 limit);\n event BridgeTokenHourlyLimitUpdated(address indexed bridgeToken, uint256 hourlyLimit);\n event HourlyLimitUpdated(uint256 hourlyLimit);\n event Recovered(address indexed token, address indexed to, uint256 amount);\n event FeeToggled(address indexed theAddress, uint256 toggleStatus);\n\n // =================================== ERRORS ==================================\n\n error AssetStillControlledInReserves();\n error HourlyLimitExceeded();\n error InvalidToken();\n error NotGovernor();\n error NotGovernorOrGuardian();\n error TooBigAmount();\n error TooHighParameterValue();\n error ZeroAddress();\n\n // ================================= MODIFIERS =================================\n\n /// @notice Checks whether the `msg.sender` has the governor role or not\n modifier onlyGovernor() {\n if (!ITreasury(treasury).isGovernor(msg.sender)) revert NotGovernor();\n _;\n }\n\n /// @notice Checks whether the `msg.sender` has the governor role or the guardian role\n modifier onlyGovernorOrGuardian() {\n if (!ITreasury(treasury).isGovernorOrGuardian(msg.sender)) revert NotGovernorOrGuardian();\n _;\n }\n\n // ===================== EXTERNAL PERMISSIONLESS FUNCTIONS =====================\n\n /// @notice Returns the list of all supported bridge tokens\n /// @dev Helpful for UIs\n function allBridgeTokens() external view returns (address[] memory) {\n return bridgeTokensList;\n }\n\n /// @notice Returns the current volume for a bridge, for the current hour\n /// @param bridgeToken Bridge used to mint\n /// @dev Helpful for UIs\n function currentUsage(address bridgeToken) external view returns (uint256) {\n return usage[bridgeToken][block.timestamp / 3600];\n }\n\n /// @notice Returns the current total volume on the chain for the current hour\n /// @dev Helpful for UIs\n function currentTotalUsage() external view returns (uint256) {\n return chainTotalUsage[block.timestamp / 3600];\n }\n\n /// @notice Mints the canonical token from a supported bridge token\n /// @param bridgeToken Bridge token to use to mint\n /// @param amount Amount of bridge tokens to send\n /// @param to Address to which the stablecoin should be sent\n /// @return Amount of the canonical stablecoin actually minted\n /// @dev Some fees may be taken by the protocol depending on the token used and on the address calling\n function swapIn(address bridgeToken, uint256 amount, address to) external returns (uint256) {\n BridgeDetails memory bridgeDetails = bridges[bridgeToken];\n if (!bridgeDetails.allowed || bridgeDetails.paused) revert InvalidToken();\n uint256 balance = IERC20(bridgeToken).balanceOf(address(this));\n if (balance + amount > bridgeDetails.limit) {\n // In case someone maliciously sends tokens to this contract\n // Or the limit changes\n if (bridgeDetails.limit > balance) amount = bridgeDetails.limit - balance;\n else {\n amount = 0;\n }\n }\n\n // Checking requirement on the hourly volume\n uint256 hour = block.timestamp / 3600;\n uint256 hourlyUsage = usage[bridgeToken][hour];\n if (hourlyUsage + amount > bridgeDetails.hourlyLimit) {\n // Edge case when the hourly limit changes\n amount = bridgeDetails.hourlyLimit > hourlyUsage ? bridgeDetails.hourlyLimit - hourlyUsage : 0;\n }\n usage[bridgeToken][hour] = hourlyUsage + amount;\n\n IERC20(bridgeToken).safeTransferFrom(msg.sender, address(this), amount);\n uint256 canonicalOut = amount;\n // Computing fees\n if (isFeeExempt[msg.sender] == 0) {\n canonicalOut -= (canonicalOut * bridgeDetails.fee) / BASE_PARAMS;\n }\n _mint(to, canonicalOut);\n return canonicalOut;\n }\n\n /// @notice Burns the canonical token in exchange for a bridge token\n /// @param bridgeToken Bridge token required\n /// @param amount Amount of canonical tokens to burn\n /// @param to Address to which the bridge token should be sent\n /// @return Amount of bridge tokens actually sent back\n /// @dev Some fees may be taken by the protocol depending on the token used and on the address calling\n function swapOut(address bridgeToken, uint256 amount, address to) external returns (uint256) {\n BridgeDetails memory bridgeDetails = bridges[bridgeToken];\n if (!bridgeDetails.allowed || bridgeDetails.paused) revert InvalidToken();\n\n uint256 hour = block.timestamp / 3600;\n uint256 hourlyUsage = chainTotalUsage[hour] + amount;\n // If the amount being swapped out exceeds the limit, we revert\n // We don't want to change the amount being swapped out.\n // The user can decide to send another tx with the correct amount to reach the limit\n if (hourlyUsage > chainTotalHourlyLimit) revert HourlyLimitExceeded();\n chainTotalUsage[hour] = hourlyUsage;\n\n _burn(msg.sender, amount);\n uint256 bridgeOut = amount;\n if (isFeeExempt[msg.sender] == 0) {\n bridgeOut -= (bridgeOut * bridgeDetails.fee) / BASE_PARAMS;\n }\n IERC20(bridgeToken).safeTransfer(to, bridgeOut);\n return bridgeOut;\n }\n\n // ============================ GOVERNANCE FUNCTIONS ===========================\n\n /// @notice Adds support for a bridge token\n /// @param bridgeToken Bridge token to add: it should be a version of the stablecoin from another bridge\n /// @param limit Limit on the balance of bridge token this contract could hold\n /// @param hourlyLimit Limit on the hourly volume for this bridge\n /// @param paused Whether swapping for this token should be paused or not\n /// @param fee Fee taken upon swapping for or against this token\n function addBridgeToken(\n address bridgeToken,\n uint256 limit,\n uint256 hourlyLimit,\n uint64 fee,\n bool paused\n ) external onlyGovernor {\n if (bridges[bridgeToken].allowed || bridgeToken == address(0)) revert InvalidToken();\n if (fee > BASE_PARAMS) revert TooHighParameterValue();\n BridgeDetails memory _bridge;\n _bridge.limit = limit;\n _bridge.hourlyLimit = hourlyLimit;\n _bridge.paused = paused;\n _bridge.fee = fee;\n _bridge.allowed = true;\n bridges[bridgeToken] = _bridge;\n bridgeTokensList.push(bridgeToken);\n emit BridgeTokenAdded(bridgeToken, limit, hourlyLimit, fee, paused);\n }\n\n /// @notice Removes support for a token\n /// @param bridgeToken Address of the bridge token to remove support for\n function removeBridgeToken(address bridgeToken) external onlyGovernor {\n if (IERC20(bridgeToken).balanceOf(address(this)) != 0) revert AssetStillControlledInReserves();\n delete bridges[bridgeToken];\n // Deletion from `bridgeTokensList` loop\n uint256 bridgeTokensListLength = bridgeTokensList.length;\n for (uint256 i; i < bridgeTokensListLength - 1; ++i) {\n if (bridgeTokensList[i] == bridgeToken) {\n // Replace the `bridgeToken` to remove with the last of the list\n bridgeTokensList[i] = bridgeTokensList[bridgeTokensListLength - 1];\n break;\n }\n }\n // Remove last element in array\n bridgeTokensList.pop();\n emit BridgeTokenRemoved(bridgeToken);\n }\n\n /// @notice Recovers any ERC20 token\n /// @dev Can be used to withdraw bridge tokens for them to be de-bridged on mainnet\n function recoverERC20(address tokenAddress, address to, uint256 amountToRecover) external onlyGovernor {\n IERC20(tokenAddress).safeTransfer(to, amountToRecover);\n emit Recovered(tokenAddress, to, amountToRecover);\n }\n\n /// @notice Updates the `limit` amount for `bridgeToken`\n function setLimit(address bridgeToken, uint256 limit) external onlyGovernorOrGuardian {\n if (!bridges[bridgeToken].allowed) revert InvalidToken();\n bridges[bridgeToken].limit = limit;\n emit BridgeTokenLimitUpdated(bridgeToken, limit);\n }\n\n /// @notice Updates the `hourlyLimit` amount for `bridgeToken`\n function setHourlyLimit(address bridgeToken, uint256 hourlyLimit) external onlyGovernorOrGuardian {\n if (!bridges[bridgeToken].allowed) revert InvalidToken();\n bridges[bridgeToken].hourlyLimit = hourlyLimit;\n emit BridgeTokenHourlyLimitUpdated(bridgeToken, hourlyLimit);\n }\n\n /// @notice Updates the `chainTotalHourlyLimit` amount\n function setChainTotalHourlyLimit(uint256 hourlyLimit) external onlyGovernorOrGuardian {\n chainTotalHourlyLimit = hourlyLimit;\n emit HourlyLimitUpdated(hourlyLimit);\n }\n\n /// @notice Updates the `fee` value for `bridgeToken`\n function setSwapFee(address bridgeToken, uint64 fee) external onlyGovernorOrGuardian {\n if (!bridges[bridgeToken].allowed) revert InvalidToken();\n if (fee > BASE_PARAMS) revert TooHighParameterValue();\n bridges[bridgeToken].fee = fee;\n emit BridgeTokenFeeUpdated(bridgeToken, fee);\n }\n\n /// @notice Pauses or unpauses swapping in and out for a token\n function toggleBridge(address bridgeToken) external onlyGovernorOrGuardian {\n if (!bridges[bridgeToken].allowed) revert InvalidToken();\n bool pausedStatus = bridges[bridgeToken].paused;\n bridges[bridgeToken].paused = !pausedStatus;\n emit BridgeTokenToggled(bridgeToken, !pausedStatus);\n }\n\n /// @notice Toggles fees for the address `theAddress`\n function toggleFeesForAddress(address theAddress) external onlyGovernorOrGuardian {\n uint256 feeExemptStatus = 1 - isFeeExempt[theAddress];\n isFeeExempt[theAddress] = feeExemptStatus;\n emit FeeToggled(theAddress, feeExemptStatus);\n }\n}\n" + }, + "contracts/agToken/layerZero/LayerZeroBridge.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.12;\n\nimport \"./utils/OFTCore.sol\";\nimport \"@openzeppelin/contracts-upgradeable/security/PausableUpgradeable.sol\";\nimport \"@openzeppelin/contracts/token/ERC20/extensions/draft-IERC20Permit.sol\";\n\n/// @title LayerZeroBridge\n/// @author Angle Labs, Inc., forked from https://github.com/LayerZero-Labs/solidity-examples/blob/main/contracts/token/oft/OFT.sol\n/// @notice Contract to be deployed on Ethereum for bridging an AgToken using a bridge intermediate token and LayerZero\ncontract LayerZeroBridge is OFTCore, PausableUpgradeable {\n /// @notice Name of the contract for indexing purposes\n string public name;\n\n /// @notice Address of the bridgeable token\n /// @dev Immutable\n IERC20 public canonicalToken;\n\n /// @notice Maps an address to the amount of token bridged but not received\n mapping(address => uint256) public balanceOf;\n\n // ================================ CONSTRUCTOR ================================\n /// @notice Initializes the contract\n /// @param _name Name of the token corresponding to this contract\n /// @param _lzEndpoint Layer zero endpoint to pass messages\n /// @param _treasury Address of the treasury contract used for access control\n function initialize(string memory _name, address _lzEndpoint, address _treasury) external initializer {\n __LzAppUpgradeable_init(_lzEndpoint, _treasury);\n name = _name;\n canonicalToken = IERC20(address(ITreasury(_treasury).stablecoin()));\n }\n\n /// @custom:oz-upgrades-unsafe-allow constructor\n constructor() initializer {}\n\n // ===================== EXTERNAL PERMISSIONLESS FUNCTIONS =====================\n\n /// @inheritdoc OFTCore\n function sendWithPermit(\n uint16 _dstChainId,\n bytes memory _toAddress,\n uint256 _amount,\n address payable _refundAddress,\n address _zroPaymentAddress,\n bytes memory _adapterParams,\n uint256 deadline,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) public payable override {\n IERC20Permit(address(canonicalToken)).permit(msg.sender, address(this), _amount, deadline, v, r, s);\n send(_dstChainId, _toAddress, _amount, _refundAddress, _zroPaymentAddress, _adapterParams);\n }\n\n /// @inheritdoc OFTCore\n function withdraw(uint256 amount, address recipient) external override returns (uint256) {\n return _withdraw(amount, msg.sender, recipient);\n }\n\n /// @notice Withdraws amount of `token` from the contract and sends it to the recipient\n /// @param amount Amount to withdraw\n /// @param recipient Address to withdraw for\n /// @return The amount of canonical token sent\n function withdrawFor(uint256 amount, address recipient) external returns (uint256) {\n return _withdraw(amount, recipient, recipient);\n }\n\n // ============================= INTERNAL FUNCTIONS ============================\n\n /// @notice Withdraws `amount` from the balance of the `from` address and sends these tokens to the `to` address\n /// @dev It's important to make sure that `from` is either the `msg.sender` or that `from` and `to` are the same\n /// addresses\n function _withdraw(uint256 amount, address from, address to) internal whenNotPaused returns (uint256) {\n balanceOf[from] -= amount; // Will overflow if the amount is too big\n canonicalToken.transfer(to, amount);\n return amount;\n }\n\n /// @inheritdoc OFTCore\n function _debitFrom(uint16, bytes memory, uint256 _amount) internal override whenNotPaused returns (uint256) {\n // No need to use safeTransferFrom as we know this implementation reverts on failure\n canonicalToken.transferFrom(msg.sender, address(this), _amount);\n return _amount;\n }\n\n /// @inheritdoc OFTCore\n function _debitCreditFrom(uint16, bytes memory, uint256 _amount) internal override whenNotPaused returns (uint256) {\n balanceOf[msg.sender] -= _amount;\n return _amount;\n }\n\n /// @inheritdoc OFTCore\n function _creditTo(uint16, address _toAddress, uint256 _amount) internal override whenNotPaused returns (uint256) {\n // Should never revert as all the LayerZero bridge tokens come from\n // this contract\n uint256 balance = canonicalToken.balanceOf(address(this));\n if (balance < _amount) {\n balanceOf[_toAddress] = _amount - balance;\n if (balance != 0) canonicalToken.transfer(_toAddress, balance);\n } else {\n canonicalToken.transfer(_toAddress, _amount);\n }\n return _amount;\n }\n\n // =============================== VIEW FUNCTIONS ==============================\n\n /// @inheritdoc ERC165Upgradeable\n function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {\n return interfaceId == type(IOFTCore).interfaceId || super.supportsInterface(interfaceId);\n }\n\n // ============================ GOVERNANCE FUNCTIONS ===========================\n\n /// @notice Pauses bridging through the contract\n /// @param pause Future pause status\n function pauseSendTokens(bool pause) external onlyGovernorOrGuardian {\n pause ? _pause() : _unpause();\n }\n\n /// @notice Decreases the balance of an address\n /// @param amount Amount to withdraw from balance\n /// @param recipient Address to withdraw from\n function sweep(uint256 amount, address recipient) external onlyGovernorOrGuardian {\n balanceOf[recipient] -= amount; // Will overflow if the amount is too big\n }\n\n uint256[47] private __gap;\n}\n" + }, + "contracts/agToken/layerZero/LayerZeroBridgeToken.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.12;\n\nimport \"./utils/OFTCore.sol\";\nimport \"../../interfaces/IAgTokenSideChainMultiBridge.sol\";\nimport \"@openzeppelin/contracts-upgradeable/security/PausableUpgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/token/ERC20/ERC20Upgradeable.sol\";\n\n/// @title LayerZeroBridgeToken\n/// @author Angle Labs, Inc., forked from https://github.com/LayerZero-Labs/solidity-examples/blob/main/contracts/token/oft/OFT.sol\n/// @notice Contract to be deployed on a L2/sidechain for bridging an AgToken using a bridge intermediate token and LayerZero\ncontract LayerZeroBridgeToken is OFTCore, ERC20Upgradeable, PausableUpgradeable {\n /// @notice Address of the bridgeable token\n /// @dev Immutable\n IAgTokenSideChainMultiBridge public canonicalToken;\n\n // =================================== ERROR ===================================\n\n error InvalidAllowance();\n\n // ================================ CONSTRUCTOR ================================\n\n /// @notice Initializes the contract\n /// @param _name Name of the token corresponding to this contract\n /// @param _symbol Symbol of the token corresponding to this contract\n /// @param _lzEndpoint Layer zero endpoint to pass messages\n /// @param _treasury Address of the treasury contract used for access control\n /// @param initialSupply Initial supply to mint to the canonical token address\n /// @dev The initial supply corresponds to the initial amount that could be bridged using this OFT\n function initialize(\n string memory _name,\n string memory _symbol,\n address _lzEndpoint,\n address _treasury,\n uint256 initialSupply\n ) external initializer {\n __ERC20_init_unchained(_name, _symbol);\n __LzAppUpgradeable_init(_lzEndpoint, _treasury);\n\n canonicalToken = IAgTokenSideChainMultiBridge(address(ITreasury(_treasury).stablecoin()));\n _approve(address(this), address(canonicalToken), type(uint256).max);\n _mint(address(canonicalToken), initialSupply);\n }\n\n /// @custom:oz-upgrades-unsafe-allow constructor\n constructor() initializer {}\n\n // ===================== EXTERNAL PERMISSIONLESS FUNCTIONS =====================\n\n /// @inheritdoc OFTCore\n function sendWithPermit(\n uint16 _dstChainId,\n bytes memory _toAddress,\n uint256 _amount,\n address payable _refundAddress,\n address _zroPaymentAddress,\n bytes memory _adapterParams,\n uint256 deadline,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) public payable override {\n canonicalToken.permit(msg.sender, address(this), _amount, deadline, v, r, s);\n send(_dstChainId, _toAddress, _amount, _refundAddress, _zroPaymentAddress, _adapterParams);\n }\n\n /// @inheritdoc OFTCore\n function withdraw(uint256 amount, address recipient) external override returns (uint256 amountMinted) {\n // Does not check allowances as transfers from `msg.sender`\n _transfer(msg.sender, address(this), amount);\n amountMinted = canonicalToken.swapIn(address(this), amount, recipient);\n uint256 leftover = balanceOf(address(this));\n if (leftover != 0) {\n _transfer(address(this), msg.sender, leftover);\n }\n }\n\n // ============================= INTERNAL FUNCTIONS ============================\n\n /// @inheritdoc OFTCore\n function _debitFrom(\n uint16,\n bytes memory,\n uint256 _amount\n ) internal override whenNotPaused returns (uint256 amountSwapped) {\n // No need to use safeTransferFrom as we know this implementation reverts on failure\n canonicalToken.transferFrom(msg.sender, address(this), _amount);\n\n // Swap canonical for this bridge token. There may be some fees\n amountSwapped = canonicalToken.swapOut(address(this), _amount, address(this));\n _burn(address(this), amountSwapped);\n }\n\n /// @inheritdoc OFTCore\n function _debitCreditFrom(uint16, bytes memory, uint256 _amount) internal override whenNotPaused returns (uint256) {\n _burn(msg.sender, _amount);\n return _amount;\n }\n\n /// @inheritdoc OFTCore\n function _creditTo(\n uint16,\n address _toAddress,\n uint256 _amount\n ) internal override whenNotPaused returns (uint256 amountMinted) {\n _mint(address(this), _amount);\n amountMinted = canonicalToken.swapIn(address(this), _amount, _toAddress);\n uint256 leftover = balanceOf(address(this));\n if (leftover != 0) {\n _transfer(address(this), _toAddress, leftover);\n }\n }\n\n // =============================== VIEW FUNCTIONS ==============================\n\n /// @inheritdoc ERC165Upgradeable\n function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {\n return\n interfaceId == type(IOFT).interfaceId ||\n interfaceId == type(IERC20).interfaceId ||\n super.supportsInterface(interfaceId);\n }\n\n // ============================ GOVERNANCE FUNCTIONS ===========================\n\n /// @notice Mints the intermediate contract to the `canonicalToken`\n /// @dev Used to increase the bridging capacity\n function mint(uint256 amount) external onlyGovernorOrGuardian {\n _mint(address(canonicalToken), amount);\n }\n\n /// @notice Burns the intermediate contract from the `canonicalToken`\n /// @dev Used to decrease the bridging capacity\n function burn(uint256 amount) external onlyGovernorOrGuardian {\n _burn(address(canonicalToken), amount);\n }\n\n /// @notice Increases allowance of the `canonicalToken`\n function setupAllowance() public onlyGovernorOrGuardian {\n _approve(address(this), address(canonicalToken), type(uint256).max);\n }\n\n /// @notice Pauses bridging through the contract\n /// @param pause Future pause status\n function pauseSendTokens(bool pause) external onlyGovernorOrGuardian {\n pause ? _pause() : _unpause();\n }\n\n uint256[49] private __gap;\n}\n" + }, + "contracts/agToken/layerZero/utils/IOFTCore.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.12;\n\nimport \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\nimport \"@openzeppelin/contracts/utils/introspection/IERC165.sol\";\n\n/**\n * @dev Interface of the IOFT core standard\n * @dev Forked from https://github.com/LayerZero-Labs/solidity-examples/blob/main/contracts/token/oft/IOFTCore.sol\n */\ninterface IOFTCore is IERC165 {\n /// @notice Estimates send token `_tokenId` to (`_dstChainId`, `_toAddress`)\n /// @param _dstChainId L0 defined chain id to send tokens too\n /// @param _toAddress dynamic bytes array which contains the address to whom you are sending tokens to on the dstChain\n /// @param _amount amount of the tokens to transfer\n /// @param _useZro indicates to use zro to pay L0 fees\n /// @param _adapterParams flexible bytes array to indicate messaging adapter services in L0\n function estimateSendFee(\n uint16 _dstChainId,\n bytes calldata _toAddress,\n uint256 _amount,\n bool _useZro,\n bytes calldata _adapterParams\n ) external view returns (uint256 nativeFee, uint256 zroFee);\n\n /// @notice Sends `_amount` amount of token to (`_dstChainId`, `_toAddress`)\n /// @param _dstChainId the destination chain identifier\n /// @param _toAddress can be any size depending on the `dstChainId`.\n /// @param _amount the quantity of tokens in wei\n /// @param _refundAddress the address LayerZero refunds if too much message fee is sent\n /// @param _zroPaymentAddress set to address(0x0) if not paying in ZRO (LayerZero Token)\n /// @param _adapterParams is a flexible bytes array to indicate messaging adapter services\n function send(\n uint16 _dstChainId,\n bytes calldata _toAddress,\n uint256 _amount,\n address payable _refundAddress,\n address _zroPaymentAddress,\n bytes calldata _adapterParams\n ) external payable;\n\n /// @notice Sends `_amount` amount of credit to (`_dstChainId`, `_toAddress`)\n /// @param _dstChainId the destination chain identifier\n /// @param _toAddress can be any size depending on the `dstChainId`.\n /// @param _amount the quantity of credit to send in wei\n /// @param _refundAddress the address LayerZero refunds if too much message fee is sent\n /// @param _zroPaymentAddress set to address(0x0) if not paying in ZRO (LayerZero Token)\n /// @param _adapterParams is a flexible bytes array to indicate messaging adapter services\n function sendCredit(\n uint16 _dstChainId,\n bytes calldata _toAddress,\n uint256 _amount,\n address payable _refundAddress,\n address _zroPaymentAddress,\n bytes calldata _adapterParams\n ) external payable;\n\n /// @notice Sends `_amount` amount of token to (`_dstChainId`, `_toAddress`)\n /// @param _dstChainId The destination chain identifier\n /// @param _toAddress Can be any size depending on the `dstChainId`.\n /// @param _amount Quantity of tokens in wei\n /// @param _refundAddress Address LayerZero refunds if too much message fee is sent\n /// @param _zroPaymentAddress Set to address(0x0) if not paying in ZRO (LayerZero Token)\n /// @param _adapterParams Flexible bytes array to indicate messaging adapter services\n /// @param deadline Deadline parameter for the signature to be valid\n /// @dev The `v`, `r`, and `s` parameters are used as signature data\n function sendWithPermit(\n uint16 _dstChainId,\n bytes memory _toAddress,\n uint256 _amount,\n address payable _refundAddress,\n address _zroPaymentAddress,\n bytes memory _adapterParams,\n uint256 deadline,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) external payable;\n\n /// @notice Withdraws amount of canonical token from the `msg.sender` balance and sends it to the recipient\n /// @param amount Amount to withdraw\n /// @param recipient Address to send the canonical token to\n /// @return The amount of canonical token sent\n function withdraw(uint256 amount, address recipient) external returns (uint256);\n\n /// @dev Emitted when `_amount` tokens are moved from the `_sender` to (`_dstChainId`, `_toAddress`)\n /// `_nonce` is the outbound nonce\n event SendToChain(\n address indexed _sender,\n uint16 indexed _dstChainId,\n bytes indexed _toAddress,\n uint256 _amount,\n uint64 _nonce\n );\n\n /// @dev Emitted when `_amount` tokens are received from `_srcChainId` into the `_toAddress` on the local chain.\n /// `_nonce` is the inbound nonce.\n event ReceiveFromChain(\n uint16 indexed _srcChainId,\n bytes indexed _srcAddress,\n address indexed _toAddress,\n uint256 _amount,\n uint64 _nonce\n );\n}\n\n/// @dev Interface of the OFT standard\ninterface IOFT is IOFTCore, IERC20 {\n\n}\n" + }, + "contracts/agToken/layerZero/utils/NonblockingLzApp.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.12;\n\nimport \"@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol\";\nimport \"../../../interfaces/external/layerZero/ILayerZeroReceiver.sol\";\nimport \"../../../interfaces/external/layerZero/ILayerZeroUserApplicationConfig.sol\";\nimport \"../../../interfaces/external/layerZero/ILayerZeroEndpoint.sol\";\nimport \"../../../interfaces/ITreasury.sol\";\n\n/// @title NonblockingLzApp\n/// @author Angle Labs, Inc., forked from https://github.com/LayerZero-Labs/solidity-examples/\n/// @notice Base contract for bridging using LayerZero\nabstract contract NonblockingLzApp is Initializable, ILayerZeroReceiver, ILayerZeroUserApplicationConfig {\n /// @notice Layer Zero endpoint\n ILayerZeroEndpoint public lzEndpoint;\n\n /// @notice Maps chainIds to failed messages to retry them\n mapping(uint16 => mapping(bytes => mapping(uint64 => bytes32))) public failedMessages;\n\n /// @notice Maps chainIds to their OFT address\n mapping(uint16 => bytes) public trustedRemoteLookup;\n\n /// @notice Reference to the treasury contract to fetch access control\n address public treasury;\n\n /// @notice Maps pairs of (`to` chain, `packetType`) to the minimum amount of gas needed on the destination chain\n mapping(uint16 => mapping(uint16 => uint256)) public minDstGasLookup;\n\n /// @notice For future LayerZero compatibility\n address public precrime;\n\n // ================================== Events ===================================\n\n event SetTrustedRemote(uint16 _srcChainId, bytes _srcAddress);\n event MessageFailed(uint16 _srcChainId, bytes _srcAddress, uint64 _nonce, bytes _payload);\n\n // =============================== Errors ================================\n\n error NotGovernor();\n error NotGovernorOrGuardian();\n error InsufficientGas();\n error InvalidEndpoint();\n error InvalidSource();\n error InvalidCaller();\n error InvalidParams();\n error InvalidPayload();\n error ZeroAddress();\n\n // ============================= Constructor ===================================\n\n //solhint-disable-next-line\n function __LzAppUpgradeable_init(address _endpoint, address _treasury) internal {\n if (_endpoint == address(0) || _treasury == address(0)) revert ZeroAddress();\n lzEndpoint = ILayerZeroEndpoint(_endpoint);\n treasury = _treasury;\n }\n\n // =============================== Modifiers ===================================\n\n /// @notice Checks whether the `msg.sender` has the governor role or the guardian role\n modifier onlyGovernorOrGuardian() {\n if (!ITreasury(treasury).isGovernorOrGuardian(msg.sender)) revert NotGovernorOrGuardian();\n _;\n }\n\n // ==================== External Permissionless Functions ======================\n\n /// @notice Receives a message from the LZ endpoint and process it\n /// @param _srcChainId ChainId of the source chain - LayerZero standard\n /// @param _srcAddress Sender of the source chain\n /// @param _nonce Nounce of the message\n /// @param _payload Data: recipient address and amount\n function lzReceive(\n uint16 _srcChainId,\n bytes memory _srcAddress,\n uint64 _nonce,\n bytes memory _payload\n ) public virtual override {\n // lzReceive must be called by the endpoint for security\n if (msg.sender != address(lzEndpoint)) revert InvalidEndpoint();\n\n bytes memory trustedRemote = trustedRemoteLookup[_srcChainId];\n // if will still block the message pathway from (srcChainId, srcAddress). should not receive message from untrusted remote.\n if (_srcAddress.length != trustedRemote.length || keccak256(_srcAddress) != keccak256(trustedRemote))\n revert InvalidSource();\n\n _blockingLzReceive(_srcChainId, _srcAddress, _nonce, _payload);\n }\n\n /// @notice Retries a message that previously failed and was stored\n /// @param _srcChainId ChainId of the source chain - LayerZero standard\n /// @param _srcAddress Sender of the source chain\n /// @param _nonce Nounce of the message\n /// @param _payload Data: recipient address and amount\n function retryMessage(\n uint16 _srcChainId,\n bytes memory _srcAddress,\n uint64 _nonce,\n bytes memory _payload\n ) public payable virtual {\n // assert there is message to retry\n bytes32 payloadHash = failedMessages[_srcChainId][_srcAddress][_nonce];\n if (payloadHash == bytes32(0) || keccak256(_payload) != payloadHash) revert InvalidPayload();\n // clear the stored message\n failedMessages[_srcChainId][_srcAddress][_nonce] = bytes32(0);\n // execute the message. revert if it fails again\n _nonblockingLzReceive(_srcChainId, _srcAddress, _nonce, _payload);\n }\n\n // ============================= Internal Functions ===================================\n\n /// @notice Handles message receptions in a non blocking way\n /// @param _srcChainId ChainId of the source chain - LayerZero standard\n /// @param _srcAddress Sender of the source chain\n /// @param _nonce Nounce of the message\n /// @param _payload Data: recipient address and amount\n /// @dev public for the needs of try / catch but effectively internal\n function nonblockingLzReceive(\n uint16 _srcChainId,\n bytes memory _srcAddress,\n uint64 _nonce,\n bytes memory _payload\n ) public virtual {\n // only internal transaction\n if (msg.sender != address(this)) revert InvalidCaller();\n _nonblockingLzReceive(_srcChainId, _srcAddress, _nonce, _payload);\n }\n\n /// @notice Handles message receptions in a non blocking way\n /// @param _srcChainId ChainId of the source chain - LayerZero standard\n /// @param _srcAddress Sender of the source chain\n /// @param _nonce Nounce of the message\n /// @param _payload Data: recipient address and amount\n function _nonblockingLzReceive(\n uint16 _srcChainId,\n bytes memory _srcAddress,\n uint64 _nonce,\n bytes memory _payload\n ) internal virtual;\n\n /// @notice Handles message receptions in a blocking way\n /// @param _srcChainId ChainId of the source chain - LayerZero standard\n /// @param _srcAddress Sender of the source chain\n /// @param _nonce Nounce of the message\n /// @param _payload Data: recipient address and amount\n function _blockingLzReceive(\n uint16 _srcChainId,\n bytes memory _srcAddress,\n uint64 _nonce,\n bytes memory _payload\n ) internal {\n // try-catch all errors/exceptions\n try this.nonblockingLzReceive(_srcChainId, _srcAddress, _nonce, _payload) {\n // do nothing\n } catch {\n // error / exception\n failedMessages[_srcChainId][_srcAddress][_nonce] = keccak256(_payload);\n emit MessageFailed(_srcChainId, _srcAddress, _nonce, _payload);\n }\n }\n\n /// @notice Sends a message to the LZ endpoint and process it\n /// @param _dstChainId L0 defined chain id to send tokens too\n /// @param _payload Data: recipient address and amount\n /// @param _refundAddress Address LayerZero refunds if too much message fee is sent\n /// @param _zroPaymentAddress Set to address(0x0) if not paying in ZRO (LayerZero Token)\n /// @param _adapterParams Flexible bytes array to indicate messaging adapter services in L0\n function _lzSend(\n uint16 _dstChainId,\n bytes memory _payload,\n address payable _refundAddress,\n address _zroPaymentAddress,\n bytes memory _adapterParams\n ) internal virtual {\n bytes memory trustedRemote = trustedRemoteLookup[_dstChainId];\n if (trustedRemote.length == 0) revert InvalidSource();\n //solhint-disable-next-line\n lzEndpoint.send{ value: msg.value }(\n _dstChainId,\n trustedRemote,\n _payload,\n _refundAddress,\n _zroPaymentAddress,\n _adapterParams\n );\n }\n\n /// @notice Checks the gas limit of a given transaction\n function _checkGasLimit(\n uint16 _dstChainId,\n uint16 _type,\n bytes memory _adapterParams,\n uint256 _extraGas\n ) internal view virtual {\n uint256 minGasLimit = minDstGasLookup[_dstChainId][_type] + _extraGas;\n if (minGasLimit == 0 || minGasLimit > _getGasLimit(_adapterParams)) revert InsufficientGas();\n }\n\n /// @notice Gets the gas limit from the `_adapterParams` parameter\n function _getGasLimit(bytes memory _adapterParams) internal pure virtual returns (uint256 gasLimit) {\n if (_adapterParams.length < 34) revert InvalidParams();\n // solhint-disable-next-line\n assembly {\n gasLimit := mload(add(_adapterParams, 34))\n }\n }\n\n // ======================= Governance Functions ================================\n\n /// @notice Sets the corresponding address on an other chain.\n /// @param _srcChainId ChainId of the source chain - LayerZero standard\n /// @param _srcAddress Address on the source chain\n /// @dev Used for both receiving and sending message\n /// @dev There can only be one trusted source per chain\n /// @dev Allows owner to set it multiple times.\n function setTrustedRemote(uint16 _srcChainId, bytes calldata _srcAddress) external onlyGovernorOrGuardian {\n trustedRemoteLookup[_srcChainId] = _srcAddress;\n emit SetTrustedRemote(_srcChainId, _srcAddress);\n }\n\n /// @notice Fetches the default LZ config\n function getConfig(\n uint16 _version,\n uint16 _chainId,\n address,\n uint256 _configType\n ) external view returns (bytes memory) {\n return lzEndpoint.getConfig(_version, _chainId, address(this), _configType);\n }\n\n /// @notice Overrides the default LZ config\n function setConfig(\n uint16 _version,\n uint16 _chainId,\n uint256 _configType,\n bytes calldata _config\n ) external override onlyGovernorOrGuardian {\n lzEndpoint.setConfig(_version, _chainId, _configType, _config);\n }\n\n /// @notice Overrides the default LZ config\n function setSendVersion(uint16 _version) external override onlyGovernorOrGuardian {\n lzEndpoint.setSendVersion(_version);\n }\n\n /// @notice Overrides the default LZ config\n function setReceiveVersion(uint16 _version) external override onlyGovernorOrGuardian {\n lzEndpoint.setReceiveVersion(_version);\n }\n\n /// @notice Unpauses the receive functionalities\n function forceResumeReceive(\n uint16 _srcChainId,\n bytes calldata _srcAddress\n ) external override onlyGovernorOrGuardian {\n lzEndpoint.forceResumeReceive(_srcChainId, _srcAddress);\n }\n\n /// @notice Sets the minimum gas parameter for a packet type on a given chain\n function setMinDstGas(uint16 _dstChainId, uint16 _packetType, uint256 _minGas) external onlyGovernorOrGuardian {\n if (_minGas == 0) revert InvalidParams();\n minDstGasLookup[_dstChainId][_packetType] = _minGas;\n }\n\n /// @notice Sets the precrime variable\n function setPrecrime(address _precrime) external onlyGovernorOrGuardian {\n precrime = _precrime;\n }\n\n // ======================= View Functions ================================\n\n /// @notice Checks if the `_srcAddress` corresponds to the trusted source\n function isTrustedRemote(uint16 _srcChainId, bytes calldata _srcAddress) external view returns (bool) {\n bytes memory trustedSource = trustedRemoteLookup[_srcChainId];\n return keccak256(trustedSource) == keccak256(_srcAddress);\n }\n\n uint256[44] private __gap;\n}\n" + }, + "contracts/agToken/layerZero/utils/OFTCore.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.12;\n\nimport \"./NonblockingLzApp.sol\";\nimport \"./IOFTCore.sol\";\nimport \"@openzeppelin/contracts-upgradeable/utils/introspection/ERC165Upgradeable.sol\";\n\n/// @title OFTCore\n/// @author Forked from https://github.com/LayerZero-Labs/solidity-examples/blob/main/contracts/token/oft/OFTCore.sol\n/// but with slight modifications from the Angle Labs, Inc. which added return values to the `_creditTo` and `_debitFrom` functions\n/// @notice Base contract for bridging using LayerZero\nabstract contract OFTCore is NonblockingLzApp, ERC165Upgradeable, IOFTCore {\n /// @notice Amount of additional gas specified\n uint256 public constant EXTRA_GAS = 200000;\n /// @notice Packet type for token transfer\n uint16 public constant PT_SEND = 0;\n\n /// @notice Whether to use custom parameters in transactions\n uint8 public useCustomAdapterParams;\n\n // ==================== External Permissionless Functions ======================\n\n /// @inheritdoc IOFTCore\n function sendWithPermit(\n uint16 _dstChainId,\n bytes memory _toAddress,\n uint256 _amount,\n address payable _refundAddress,\n address _zroPaymentAddress,\n bytes memory _adapterParams,\n uint256 deadline,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) public payable virtual;\n\n /// @inheritdoc IOFTCore\n function send(\n uint16 _dstChainId,\n bytes memory _toAddress,\n uint256 _amount,\n address payable _refundAddress,\n address _zroPaymentAddress,\n bytes memory _adapterParams\n ) public payable virtual {\n _checkAdapterParams(_dstChainId, PT_SEND, _adapterParams, EXTRA_GAS);\n _amount = _debitFrom(_dstChainId, _toAddress, _amount);\n\n bytes memory payload = abi.encode(_toAddress, _amount);\n _lzSend(_dstChainId, payload, _refundAddress, _zroPaymentAddress, _adapterParams);\n\n uint64 nonce = lzEndpoint.getOutboundNonce(_dstChainId, address(this));\n emit SendToChain(msg.sender, _dstChainId, _toAddress, _amount, nonce);\n }\n\n /// @inheritdoc IOFTCore\n function sendCredit(\n uint16 _dstChainId,\n bytes memory _toAddress,\n uint256 _amount,\n address payable _refundAddress,\n address _zroPaymentAddress,\n bytes memory _adapterParams\n ) public payable virtual {\n _checkAdapterParams(_dstChainId, PT_SEND, _adapterParams, EXTRA_GAS);\n _amount = _debitCreditFrom(_dstChainId, _toAddress, _amount);\n\n _send(_dstChainId, _toAddress, _amount, _refundAddress, _zroPaymentAddress, _adapterParams);\n }\n\n /// @inheritdoc IOFTCore\n function withdraw(uint256 amount, address recipient) external virtual returns (uint256);\n\n /// @notice Sets whether custom adapter parameters can be used or not\n function setUseCustomAdapterParams(uint8 _useCustomAdapterParams) public virtual onlyGovernorOrGuardian {\n useCustomAdapterParams = _useCustomAdapterParams;\n }\n\n // =========================== Internal Functions ==============================\n\n /// @notice Internal function to send `_amount` amount of token to (`_dstChainId`, `_toAddress`)\n /// @param _dstChainId the destination chain identifier\n /// @param _toAddress can be any size depending on the `dstChainId`.\n /// @param _amount the quantity of tokens in wei\n /// @param _refundAddress the address LayerZero refunds if too much message fee is sent\n /// @param _zroPaymentAddress set to address(0x0) if not paying in ZRO (LayerZero Token)\n /// @param _adapterParams is a flexible bytes array to indicate messaging adapter services\n /// @dev Accounting and checks should be performed beforehand\n function _send(\n uint16 _dstChainId,\n bytes memory _toAddress,\n uint256 _amount,\n address payable _refundAddress,\n address _zroPaymentAddress,\n bytes memory _adapterParams\n ) internal {\n bytes memory payload = abi.encode(_toAddress, _amount);\n _lzSend(_dstChainId, payload, _refundAddress, _zroPaymentAddress, _adapterParams);\n\n uint64 nonce = lzEndpoint.getOutboundNonce(_dstChainId, address(this));\n emit SendToChain(msg.sender, _dstChainId, _toAddress, _amount, nonce);\n }\n\n /// @inheritdoc NonblockingLzApp\n function _nonblockingLzReceive(\n uint16 _srcChainId,\n bytes memory _srcAddress,\n uint64 _nonce,\n bytes memory _payload\n ) internal virtual override {\n // decode and load the toAddress\n (bytes memory toAddressBytes, uint256 amount) = abi.decode(_payload, (bytes, uint256));\n address toAddress;\n //solhint-disable-next-line\n assembly {\n toAddress := mload(add(toAddressBytes, 20))\n }\n amount = _creditTo(_srcChainId, toAddress, amount);\n\n emit ReceiveFromChain(_srcChainId, _srcAddress, toAddress, amount, _nonce);\n }\n\n /// @notice Checks the adapter parameters given during the smart contract call\n function _checkAdapterParams(\n uint16 _dstChainId,\n uint16 _pkType,\n bytes memory _adapterParams,\n uint256 _extraGas\n ) internal virtual {\n if (useCustomAdapterParams > 0) _checkGasLimit(_dstChainId, _pkType, _adapterParams, _extraGas);\n else if (_adapterParams.length != 0) revert InvalidParams();\n }\n\n /// @notice Makes accountability when bridging from this contract using canonical token\n /// @param _dstChainId ChainId of the destination chain - LayerZero standard\n /// @param _toAddress Recipient on the destination chain\n /// @param _amount Amount to bridge\n function _debitFrom(\n uint16 _dstChainId,\n bytes memory _toAddress,\n uint256 _amount\n ) internal virtual returns (uint256);\n\n /// @notice Makes accountability when bridging from this contract's credit\n /// @param _dstChainId ChainId of the destination chain - LayerZero standard\n /// @param _toAddress Recipient on the destination chain\n /// @param _amount Amount to bridge\n function _debitCreditFrom(\n uint16 _dstChainId,\n bytes memory _toAddress,\n uint256 _amount\n ) internal virtual returns (uint256);\n\n /// @notice Makes accountability when bridging to this contract\n /// @param _srcChainId ChainId of the source chain - LayerZero standard\n /// @param _toAddress Recipient on this chain\n /// @param _amount Amount to bridge\n function _creditTo(uint16 _srcChainId, address _toAddress, uint256 _amount) internal virtual returns (uint256);\n\n // ========================== View Functions ===================================\n\n /// @inheritdoc ERC165Upgradeable\n function supportsInterface(\n bytes4 interfaceId\n ) public view virtual override(ERC165Upgradeable, IERC165) returns (bool) {\n return interfaceId == type(IOFTCore).interfaceId || super.supportsInterface(interfaceId);\n }\n\n /// @inheritdoc IOFTCore\n function estimateSendFee(\n uint16 _dstChainId,\n bytes memory _toAddress,\n uint256 _amount,\n bool _useZro,\n bytes memory _adapterParams\n ) public view virtual override returns (uint256 nativeFee, uint256 zroFee) {\n // mock the payload for send()\n bytes memory payload = abi.encode(_toAddress, _amount);\n return lzEndpoint.estimateFees(_dstChainId, address(this), payload, _useZro, _adapterParams);\n }\n\n uint256[49] private __gap;\n}\n" + }, + "contracts/agToken/polygon/TokenPolygonUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.12;\n\nimport \"./utils/ERC20UpgradeableCustom.sol\";\nimport \"@openzeppelin/contracts-upgradeable/access/AccessControlUpgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/utils/cryptography/draft-EIP712Upgradeable.sol\";\nimport \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\nimport \"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\";\n\nimport \"../../interfaces/IAgToken.sol\";\nimport \"../../interfaces/ITreasury.sol\";\n\ninterface IChildToken {\n function deposit(address user, bytes calldata depositData) external;\n\n function withdraw(uint256 amount) external;\n}\n\ncontract TokenPolygonUpgradeable is\n Initializable,\n ERC20UpgradeableCustom,\n AccessControlUpgradeable,\n EIP712Upgradeable,\n IChildToken\n{\n bytes32 public constant DEPOSITOR_ROLE = keccak256(\"DEPOSITOR_ROLE\");\n\n /// @dev Emitted when the child chain manager changes\n event ChildChainManagerAdded(address newAddress);\n event ChildChainManagerRevoked(address oldAddress);\n\n constructor() initializer {}\n\n function initialize(\n string memory _name,\n string memory _symbol,\n address childChainManager,\n address guardian\n ) public initializer {\n __ERC20_init(_name, _symbol);\n __AccessControl_init();\n _setupRole(DEFAULT_ADMIN_ROLE, guardian);\n _setupRole(DEPOSITOR_ROLE, childChainManager);\n __EIP712_init(_name, \"1\");\n }\n\n /**\n * @notice Called when the bridge has tokens to mint\n * @param user Address to mint the token to\n * @param depositData Encoded amount to mint\n */\n function deposit(address user, bytes calldata depositData) external override {\n require(hasRole(DEPOSITOR_ROLE, msg.sender));\n uint256 amount = abi.decode(depositData, (uint256));\n _mint(user, amount);\n }\n\n /**\n * @notice Called when user wants to withdraw tokens back to root chain\n * @dev Should burn user's tokens. This transaction will be verified when exiting on root chain\n * @param amount Amount of tokens to withdraw\n */\n function withdraw(uint256 amount) external override {\n _burn(_msgSender(), amount);\n }\n\n // =============================================================================\n // ======================= New data added for the upgrade ======================\n // =============================================================================\n\n mapping(address => bool) public isMinter;\n /// @notice Reference to the treasury contract which can grant minting rights\n address public treasury;\n /// @notice Boolean to check whether the contract has been reinitialized after its upgrade\n bool public treasuryInitialized;\n\n using SafeERC20 for IERC20;\n\n /// @notice Base used for fee computation\n uint256 public constant BASE_PARAMS = 10 ** 9;\n\n // =============================== Bridging Data ===============================\n\n /// @notice Struct with some data about a specific bridge token\n struct BridgeDetails {\n // Limit on the balance of bridge token held by the contract: it is designed\n // to reduce the exposure of the system to hacks\n uint256 limit;\n // Limit on the hourly volume of token minted through this bridge\n // Technically the limit over a rolling hour is hourlyLimit x2 as hourly limit\n // is enforced only between x:00 and x+1:00\n uint256 hourlyLimit;\n // Fee taken for swapping in and out the token\n uint64 fee;\n // Whether the associated token is allowed or not\n bool allowed;\n // Whether swapping in and out from the associated token is paused or not\n bool paused;\n }\n\n /// @notice Maps a bridge token to data\n mapping(address => BridgeDetails) public bridges;\n /// @notice List of all bridge tokens\n address[] public bridgeTokensList;\n /// @notice Maps a bridge token to the associated hourly volume\n mapping(address => mapping(uint256 => uint256)) public usage;\n /// @notice Maps an address to whether it is exempt of fees for when it comes to swapping in and out\n mapping(address => uint256) public isFeeExempt;\n /// @notice Limit to the amount of tokens that can be sent from that chain to another chain\n uint256 public chainTotalHourlyLimit;\n /// @notice Usage per hour on that chain. Maps an hourly timestamp to the total volume swapped out on the chain\n mapping(uint256 => uint256) public chainTotalUsage;\n\n uint256[42] private __gap;\n\n // ================================== Events ===================================\n\n event BridgeTokenAdded(address indexed bridgeToken, uint256 limit, uint256 hourlyLimit, uint64 fee, bool paused);\n event BridgeTokenToggled(address indexed bridgeToken, bool toggleStatus);\n event BridgeTokenRemoved(address indexed bridgeToken);\n event BridgeTokenFeeUpdated(address indexed bridgeToken, uint64 fee);\n event BridgeTokenLimitUpdated(address indexed bridgeToken, uint256 limit);\n event BridgeTokenHourlyLimitUpdated(address indexed bridgeToken, uint256 hourlyLimit);\n event HourlyLimitUpdated(uint256 hourlyLimit);\n event FeeToggled(address indexed theAddress, uint256 toggleStatus);\n event KeeperToggled(address indexed keeper, bool toggleStatus);\n event MinterToggled(address indexed minter);\n event Recovered(address indexed token, address indexed to, uint256 amount);\n event TreasuryUpdated(address indexed _treasury);\n\n // ================================== Errors ===================================\n\n error AssetStillControlledInReserves();\n error BurnAmountExceedsAllowance();\n error HourlyLimitExceeded();\n error InvalidSender();\n error InvalidToken();\n error InvalidTreasury();\n error NotGovernor();\n error NotGovernorOrGuardian();\n error NotMinter();\n error NotTreasury();\n error TooBigAmount();\n error TooHighParameterValue();\n error TreasuryAlreadyInitialized();\n error ZeroAddress();\n\n /// @notice Checks to see if it is the `Treasury` calling this contract\n /// @dev There is no Access Control here, because it can be handled cheaply through this modifier\n modifier onlyTreasury() {\n if (msg.sender != treasury) revert NotTreasury();\n _;\n }\n\n /// @notice Checks whether the sender has the minting right\n modifier onlyMinter() {\n if (!isMinter[msg.sender]) revert NotMinter();\n _;\n }\n\n /// @notice Checks whether the `msg.sender` has the governor role or not\n modifier onlyGovernor() {\n if (!ITreasury(treasury).isGovernor(msg.sender)) revert NotGovernor();\n _;\n }\n\n /// @notice Checks whether the `msg.sender` has the governor role or the guardian role\n modifier onlyGovernorOrGuardian() {\n if (!ITreasury(treasury).isGovernorOrGuardian(msg.sender)) revert NotGovernorOrGuardian();\n _;\n }\n\n /// @notice Sets up the treasury contract on Polygon after the upgrade\n /// @param _treasury Address of the treasury contract\n function setUpTreasury(address _treasury) external {\n // Only governor on Polygon\n if (msg.sender != 0xdA2D2f638D6fcbE306236583845e5822554c02EA) revert NotGovernor();\n if (address(ITreasury(_treasury).stablecoin()) != address(this)) revert InvalidTreasury();\n if (treasuryInitialized) revert TreasuryAlreadyInitialized();\n treasury = _treasury;\n treasuryInitialized = true;\n emit TreasuryUpdated(_treasury);\n }\n\n // =========================== External Function ===============================\n\n /// @notice Allows anyone to burn agToken without redeeming collateral back\n /// @param amount Amount of stablecoins to burn\n /// @dev This function can typically be called if there is a settlement mechanism to burn stablecoins\n function burnStablecoin(uint256 amount) external {\n _burnCustom(msg.sender, amount);\n }\n\n // ======================= Minter Role Only Functions ==========================\n\n function burnSelf(uint256 amount, address burner) external onlyMinter {\n _burnCustom(burner, amount);\n }\n\n function burnFrom(uint256 amount, address burner, address sender) external onlyMinter {\n _burnFromNoRedeem(amount, burner, sender);\n }\n\n function mint(address account, uint256 amount) external onlyMinter {\n _mint(account, amount);\n }\n\n // ======================= Treasury Only Functions =============================\n\n function addMinter(address minter) external onlyTreasury {\n isMinter[minter] = true;\n emit MinterToggled(minter);\n }\n\n function removeMinter(address minter) external {\n if (msg.sender != address(treasury) && msg.sender != minter) revert InvalidSender();\n isMinter[minter] = false;\n emit MinterToggled(minter);\n }\n\n function setTreasury(address _treasury) external onlyTreasury {\n treasury = _treasury;\n emit TreasuryUpdated(_treasury);\n }\n\n // ============================ Internal Function ==============================\n\n /// @notice Internal version of the function `burnFromNoRedeem`\n /// @param amount Amount to burn\n /// @dev It is at the level of this function that allowance checks are performed\n function _burnFromNoRedeem(uint256 amount, address burner, address sender) internal {\n if (burner != sender) {\n uint256 currentAllowance = allowance(burner, sender);\n if (currentAllowance < amount) revert BurnAmountExceedsAllowance();\n _approve(burner, sender, currentAllowance - amount);\n }\n _burnCustom(burner, amount);\n }\n\n // ==================== External Permissionless Functions ======================\n\n /// @notice Returns the list of all supported bridge tokens\n /// @dev Helpful for UIs\n function allBridgeTokens() external view returns (address[] memory) {\n return bridgeTokensList;\n }\n\n /// @notice Returns the current volume for a bridge, for the current hour\n /// @dev Helpful for UIs\n function currentUsage(address bridge) external view returns (uint256) {\n return usage[bridge][block.timestamp / 3600];\n }\n\n /// @notice Returns the current total volume on the chain for the current hour\n /// @dev Helpful for UIs\n function currentTotalUsage() external view returns (uint256) {\n return chainTotalUsage[block.timestamp / 3600];\n }\n\n /// @notice Mints the canonical token from a supported bridge token\n /// @param bridgeToken Bridge token to use to mint\n /// @param amount Amount of bridge tokens to send\n /// @param to Address to which the stablecoin should be sent\n /// @dev Some fees may be taken by the protocol depending on the token used and on the address calling\n function swapIn(address bridgeToken, uint256 amount, address to) external returns (uint256) {\n BridgeDetails memory bridgeDetails = bridges[bridgeToken];\n if (!bridgeDetails.allowed || bridgeDetails.paused) revert InvalidToken();\n uint256 balance = IERC20(bridgeToken).balanceOf(address(this));\n if (balance + amount > bridgeDetails.limit) {\n // In case someone maliciously sends tokens to this contract\n // Or the limit changes\n if (bridgeDetails.limit > balance) amount = bridgeDetails.limit - balance;\n else {\n amount = 0;\n }\n }\n\n // Checking requirement on the hourly volume\n uint256 hour = block.timestamp / 3600;\n uint256 hourlyUsage = usage[bridgeToken][hour] + amount;\n if (hourlyUsage > bridgeDetails.hourlyLimit) {\n // Edge case when the hourly limit changes\n if (bridgeDetails.hourlyLimit > usage[bridgeToken][hour])\n amount = bridgeDetails.hourlyLimit - usage[bridgeToken][hour];\n else {\n amount = 0;\n }\n }\n usage[bridgeToken][hour] += amount;\n\n IERC20(bridgeToken).safeTransferFrom(msg.sender, address(this), amount);\n uint256 canonicalOut = amount;\n // Computing fees\n if (isFeeExempt[msg.sender] == 0) {\n canonicalOut -= (canonicalOut * bridgeDetails.fee) / BASE_PARAMS;\n }\n _mint(to, canonicalOut);\n return canonicalOut;\n }\n\n /// @notice Burns the canonical token in exchange for a bridge token\n /// @param bridgeToken Bridge token required\n /// @param amount Amount of canonical tokens to burn\n /// @param to Address to which the bridge token should be sent\n /// @dev Some fees may be taken by the protocol depending on the token used and on the address calling\n function swapOut(address bridgeToken, uint256 amount, address to) external returns (uint256) {\n BridgeDetails memory bridgeDetails = bridges[bridgeToken];\n if (!bridgeDetails.allowed || bridgeDetails.paused) revert InvalidToken();\n\n uint256 hour = block.timestamp / 3600;\n uint256 hourlyUsage = chainTotalUsage[hour] + amount;\n // If the amount being swapped out exceeds the limit, we revert\n // We don't want to change the amount being swapped out.\n // The user can decide to send another tx with the correct amount to reach the limit\n if (hourlyUsage > chainTotalHourlyLimit) revert HourlyLimitExceeded();\n chainTotalUsage[hour] = hourlyUsage;\n\n _burnCustom(msg.sender, amount);\n uint256 bridgeOut = amount;\n if (isFeeExempt[msg.sender] == 0) {\n bridgeOut -= (bridgeOut * bridgeDetails.fee) / BASE_PARAMS;\n }\n IERC20(bridgeToken).safeTransfer(to, bridgeOut);\n return bridgeOut;\n }\n\n // ======================= Governance Functions ================================\n\n /// @notice Adds support for a bridge token\n /// @param bridgeToken Bridge token to add: it should be a version of the stablecoin from another bridge\n /// @param limit Limit on the balance of bridge token this contract could hold\n /// @param hourlyLimit Limit on the hourly volume for this bridge\n /// @param paused Whether swapping for this token should be paused or not\n /// @param fee Fee taken upon swapping for or against this token\n function addBridgeToken(\n address bridgeToken,\n uint256 limit,\n uint256 hourlyLimit,\n uint64 fee,\n bool paused\n ) external onlyGovernor {\n if (bridges[bridgeToken].allowed || bridgeToken == address(0)) revert InvalidToken();\n if (fee > BASE_PARAMS) revert TooHighParameterValue();\n BridgeDetails memory _bridge;\n _bridge.limit = limit;\n _bridge.hourlyLimit = hourlyLimit;\n _bridge.paused = paused;\n _bridge.fee = fee;\n _bridge.allowed = true;\n bridges[bridgeToken] = _bridge;\n bridgeTokensList.push(bridgeToken);\n emit BridgeTokenAdded(bridgeToken, limit, hourlyLimit, fee, paused);\n }\n\n /// @notice Removes support for a token\n /// @param bridgeToken Address of the bridge token to remove support for\n function removeBridgeToken(address bridgeToken) external onlyGovernor {\n if (IERC20(bridgeToken).balanceOf(address(this)) != 0) revert AssetStillControlledInReserves();\n delete bridges[bridgeToken];\n // Deletion from `bridgeTokensList` loop\n uint256 bridgeTokensListLength = bridgeTokensList.length;\n for (uint256 i; i < bridgeTokensListLength - 1; ++i) {\n if (bridgeTokensList[i] == bridgeToken) {\n // Replace the `bridgeToken` to remove with the last of the list\n bridgeTokensList[i] = bridgeTokensList[bridgeTokensListLength - 1];\n break;\n }\n }\n // Remove last element in array\n bridgeTokensList.pop();\n emit BridgeTokenRemoved(bridgeToken);\n }\n\n /// @notice Recovers any ERC20 token\n /// @dev Can be used to withdraw bridge tokens for them to be de-bridged on mainnet\n function recoverERC20(address tokenAddress, address to, uint256 amountToRecover) external onlyGovernor {\n IERC20(tokenAddress).safeTransfer(to, amountToRecover);\n emit Recovered(tokenAddress, to, amountToRecover);\n }\n\n /// @notice Updates the `limit` amount for `bridgeToken`\n function setLimit(address bridgeToken, uint256 limit) external onlyGovernorOrGuardian {\n if (!bridges[bridgeToken].allowed) revert InvalidToken();\n bridges[bridgeToken].limit = limit;\n emit BridgeTokenLimitUpdated(bridgeToken, limit);\n }\n\n /// @notice Updates the `hourlyLimit` amount for `bridgeToken`\n function setHourlyLimit(address bridgeToken, uint256 hourlyLimit) external onlyGovernorOrGuardian {\n if (!bridges[bridgeToken].allowed) revert InvalidToken();\n bridges[bridgeToken].hourlyLimit = hourlyLimit;\n emit BridgeTokenHourlyLimitUpdated(bridgeToken, hourlyLimit);\n }\n\n /// @notice Updates the `chainTotalHourlyLimit` amount\n function setChainTotalHourlyLimit(uint256 hourlyLimit) external onlyGovernorOrGuardian {\n chainTotalHourlyLimit = hourlyLimit;\n emit HourlyLimitUpdated(hourlyLimit);\n }\n\n /// @notice Updates the `fee` value for `bridgeToken`\n function setSwapFee(address bridgeToken, uint64 fee) external onlyGovernorOrGuardian {\n if (!bridges[bridgeToken].allowed) revert InvalidToken();\n if (fee > BASE_PARAMS) revert TooHighParameterValue();\n bridges[bridgeToken].fee = fee;\n emit BridgeTokenFeeUpdated(bridgeToken, fee);\n }\n\n /// @notice Pauses or unpauses swapping in and out for a token\n function toggleBridge(address bridgeToken) external onlyGovernorOrGuardian {\n if (!bridges[bridgeToken].allowed) revert InvalidToken();\n bool pausedStatus = bridges[bridgeToken].paused;\n bridges[bridgeToken].paused = !pausedStatus;\n emit BridgeTokenToggled(bridgeToken, !pausedStatus);\n }\n\n /// @notice Toggles fees for the address `theAddress`\n function toggleFeesForAddress(address theAddress) external onlyGovernorOrGuardian {\n uint256 feeExemptStatus = 1 - isFeeExempt[theAddress];\n isFeeExempt[theAddress] = feeExemptStatus;\n emit FeeToggled(theAddress, feeExemptStatus);\n }\n}\n" + }, + "contracts/agToken/polygon/utils/ERC20UpgradeableCustom.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (token/ERC20/ERC20.sol)\n\npragma solidity ^0.8.0;\n\nimport \"@openzeppelin/contracts-upgradeable/token/ERC20/IERC20Upgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/token/ERC20/extensions/IERC20MetadataUpgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/utils/ContextUpgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol\";\n\n/**\n * @dev Implementation of the {IERC20} interface modified by Angle Labs, Inc.\n *\n * This implementation has a custom burn function to avoid having a {Transfer} event to the zero address\n * in some specific burn cases to avoid having Polygon PoS bridge catching this event\n *\n * TIP: For a detailed writeup see our guide\n * https://forum.zeppelin.solutions/t/how-to-implement-erc20-supply-mechanisms/226[How\n * to implement supply mechanisms].\n *\n * We have followed general OpenZeppelin Contracts guidelines: functions revert\n * instead returning `false` on failure. This behavior is nonetheless\n * conventional and does not conflict with the expectations of ERC20\n * applications.\n *\n * Additionally, an {Approval} event is emitted on calls to {transferFrom}.\n * This allows applications to reconstruct the allowance for all accounts just\n * by listening to said events. Other implementations of the EIP may not emit\n * these events, as it isn't required by the specification.\n *\n * Finally, the non-standard {decreaseAllowance} and {increaseAllowance}\n * functions have been added to mitigate the well-known issues around setting\n * allowances. See {IERC20-approve}.\n */\ncontract ERC20UpgradeableCustom is Initializable, ContextUpgradeable, IERC20Upgradeable, IERC20MetadataUpgradeable {\n mapping(address => uint256) private _balances;\n\n mapping(address => mapping(address => uint256)) private _allowances;\n\n uint256 private _totalSupply;\n\n string private _name;\n string private _symbol;\n\n /**\n * @dev Sets the values for {name} and {symbol}.\n *\n * The default value of {decimals} is 18. To select a different value for\n * {decimals} you should overload it.\n *\n * All two of these values are immutable: they can only be set once during\n * construction.\n */\n //solhint-disable-next-line\n function __ERC20_init(string memory name_, string memory symbol_) internal onlyInitializing {\n __Context_init_unchained();\n __ERC20_init_unchained(name_, symbol_);\n }\n\n //solhint-disable-next-line\n function __ERC20_init_unchained(string memory name_, string memory symbol_) internal onlyInitializing {\n _name = name_;\n _symbol = symbol_;\n }\n\n /**\n * @dev Returns the name of the token.\n */\n function name() public view virtual override returns (string memory) {\n return _name;\n }\n\n /**\n * @dev Returns the symbol of the token, usually a shorter version of the\n * name.\n */\n function symbol() public view virtual override returns (string memory) {\n return _symbol;\n }\n\n /**\n * @dev Returns the number of decimals used to get its user representation.\n * For example, if `decimals` equals `2`, a balance of `505` tokens should\n * be displayed to a user as `5.05` (`505 / 10 ** 2`).\n *\n * Tokens usually opt for a value of 18, imitating the relationship between\n * Ether and Wei. This is the value {ERC20} uses, unless this function is\n * overridden;\n *\n * NOTE: This information is only used for _display_ purposes: it in\n * no way affects any of the arithmetic of the contract, including\n * {IERC20-balanceOf} and {IERC20-transfer}.\n */\n function decimals() public view virtual override returns (uint8) {\n return 18;\n }\n\n /**\n * @dev See {IERC20-totalSupply}.\n */\n function totalSupply() public view virtual override returns (uint256) {\n return _totalSupply;\n }\n\n /**\n * @dev See {IERC20-balanceOf}.\n */\n function balanceOf(address account) public view virtual override returns (uint256) {\n return _balances[account];\n }\n\n /**\n * @dev See {IERC20-transfer}.\n *\n * Requirements:\n *\n * - `recipient` cannot be the zero address.\n * - the caller must have a balance of at least `amount`.\n */\n function transfer(address recipient, uint256 amount) public virtual override returns (bool) {\n _transfer(_msgSender(), recipient, amount);\n return true;\n }\n\n /**\n * @dev See {IERC20-allowance}.\n */\n function allowance(address owner, address spender) public view virtual override returns (uint256) {\n return _allowances[owner][spender];\n }\n\n /**\n * @dev See {IERC20-approve}.\n *\n * Requirements:\n *\n * - `spender` cannot be the zero address.\n */\n function approve(address spender, uint256 amount) public virtual override returns (bool) {\n _approve(_msgSender(), spender, amount);\n return true;\n }\n\n /**\n * @dev See {IERC20-transferFrom}.\n *\n * Emits an {Approval} event indicating the updated allowance. This is not\n * required by the EIP. See the note at the beginning of {ERC20}.\n *\n * Requirements:\n *\n * - `sender` and `recipient` cannot be the zero address.\n * - `sender` must have a balance of at least `amount`.\n * - the caller must have allowance for `sender`'s tokens of at least\n * `amount`.\n */\n function transferFrom(address sender, address recipient, uint256 amount) public virtual override returns (bool) {\n _transfer(sender, recipient, amount);\n\n uint256 currentAllowance = _allowances[sender][_msgSender()];\n require(currentAllowance >= amount, \"ERC20: transfer amount exceeds allowance\");\n unchecked {\n _approve(sender, _msgSender(), currentAllowance - amount);\n }\n\n return true;\n }\n\n /**\n * @dev Atomically increases the allowance granted to `spender` by the caller.\n *\n * This is an alternative to {approve} that can be used as a mitigation for\n * problems described in {IERC20-approve}.\n *\n * Emits an {Approval} event indicating the updated allowance.\n *\n * Requirements:\n *\n * - `spender` cannot be the zero address.\n */\n function increaseAllowance(address spender, uint256 addedValue) public virtual returns (bool) {\n _approve(_msgSender(), spender, _allowances[_msgSender()][spender] + addedValue);\n return true;\n }\n\n /**\n * @dev Atomically decreases the allowance granted to `spender` by the caller.\n *\n * This is an alternative to {approve} that can be used as a mitigation for\n * problems described in {IERC20-approve}.\n *\n * Emits an {Approval} event indicating the updated allowance.\n *\n * Requirements:\n *\n * - `spender` cannot be the zero address.\n * - `spender` must have allowance for the caller of at least\n * `subtractedValue`.\n */\n function decreaseAllowance(address spender, uint256 subtractedValue) public virtual returns (bool) {\n uint256 currentAllowance = _allowances[_msgSender()][spender];\n require(currentAllowance >= subtractedValue, \"ERC20: decreased allowance below zero\");\n unchecked {\n _approve(_msgSender(), spender, currentAllowance - subtractedValue);\n }\n\n return true;\n }\n\n /**\n * @dev Moves `amount` of tokens from `sender` to `recipient`.\n *\n * This internal function is equivalent to {transfer}, and can be used to\n * e.g. implement automatic token fees, slashing mechanisms, etc.\n *\n * Emits a {Transfer} event.\n *\n * Requirements:\n *\n * - `sender` cannot be the zero address.\n * - `recipient` cannot be the zero address.\n * - `sender` must have a balance of at least `amount`.\n */\n function _transfer(address sender, address recipient, uint256 amount) internal virtual {\n require(sender != address(0), \"ERC20: transfer from the zero address\");\n require(recipient != address(0), \"ERC20: transfer to the zero address\");\n\n _beforeTokenTransfer(sender, recipient, amount);\n\n uint256 senderBalance = _balances[sender];\n require(senderBalance >= amount, \"ERC20: transfer amount exceeds balance\");\n unchecked {\n _balances[sender] = senderBalance - amount;\n }\n _balances[recipient] += amount;\n\n emit Transfer(sender, recipient, amount);\n\n _afterTokenTransfer(sender, recipient, amount);\n }\n\n /** @dev Creates `amount` tokens and assigns them to `account`, increasing\n * the total supply.\n *\n * Emits a {Transfer} event with `from` set to the zero address.\n *\n * Requirements:\n *\n * - `account` cannot be the zero address.\n */\n function _mint(address account, uint256 amount) internal virtual {\n require(account != address(0), \"ERC20: mint to the zero address\");\n\n _beforeTokenTransfer(address(0), account, amount);\n\n _totalSupply += amount;\n _balances[account] += amount;\n emit Transfer(address(0), account, amount);\n\n _afterTokenTransfer(address(0), account, amount);\n }\n\n /**\n * @dev Destroys `amount` tokens from `account`, reducing the\n * total supply.\n *\n * Emits a {Transfer} event with `to` set to the zero address.\n *\n * Requirements:\n *\n * - `account` cannot be the zero address.\n * - `account` must have at least `amount` tokens.\n */\n function _burn(address account, uint256 amount) internal virtual {\n require(account != address(0), \"ERC20: burn from the zero address\");\n\n _beforeTokenTransfer(account, address(0), amount);\n\n uint256 accountBalance = _balances[account];\n require(accountBalance >= amount, \"ERC20: burn amount exceeds balance\");\n unchecked {\n _balances[account] = accountBalance - amount;\n }\n _totalSupply -= amount;\n\n emit Transfer(account, address(0), amount);\n\n _afterTokenTransfer(account, address(0), amount);\n }\n\n /**\n * @dev Destroys `amount` tokens from `account`, reducing the\n * total supply.\n *\n * Contrary to the other `burn` function, the {Transfer} event is not to the zero address\n * but rather to this address: the reason is that not all burn events should be caught up\n * by the PoS bridge\n *\n * Requirements:\n *\n * - `account` cannot be the zero address.\n * - `account` must have at least `amount` tokens.\n */\n function _burnCustom(address account, uint256 amount) internal virtual {\n require(account != address(0), \"ERC20: burn from the zero address\");\n\n _beforeTokenTransfer(account, address(0), amount);\n\n uint256 accountBalance = _balances[account];\n require(accountBalance >= amount, \"ERC20: burn amount exceeds balance\");\n unchecked {\n _balances[account] = accountBalance - amount;\n }\n _totalSupply -= amount;\n\n emit Transfer(account, address(this), amount);\n\n _afterTokenTransfer(account, address(0), amount);\n }\n\n /**\n * @dev Sets `amount` as the allowance of `spender` over the `owner` s tokens.\n *\n * This internal function is equivalent to `approve`, and can be used to\n * e.g. set automatic allowances for certain subsystems, etc.\n *\n * Emits an {Approval} event.\n *\n * Requirements:\n *\n * - `owner` cannot be the zero address.\n * - `spender` cannot be the zero address.\n */\n function _approve(address owner, address spender, uint256 amount) internal virtual {\n require(owner != address(0), \"ERC20: approve from the zero address\");\n require(spender != address(0), \"ERC20: approve to the zero address\");\n\n _allowances[owner][spender] = amount;\n emit Approval(owner, spender, amount);\n }\n\n /**\n * @dev Hook that is called before any transfer of tokens. This includes\n * minting and burning.\n *\n * Calling conditions:\n *\n * - when `from` and `to` are both non-zero, `amount` of `from`'s tokens\n * will be transferred to `to`.\n * - when `from` is zero, `amount` tokens will be minted for `to`.\n * - when `to` is zero, `amount` of `from`'s tokens will be burned.\n * - `from` and `to` are never both zero.\n *\n * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].\n */\n function _beforeTokenTransfer(address from, address to, uint256 amount) internal virtual {}\n\n /**\n * @dev Hook that is called after any transfer of tokens. This includes\n * minting and burning.\n *\n * Calling conditions:\n *\n * - when `from` and `to` are both non-zero, `amount` of `from`'s tokens\n * has been transferred to `to`.\n * - when `from` is zero, `amount` tokens have been minted for `to`.\n * - when `to` is zero, `amount` of `from`'s tokens have been burned.\n * - `from` and `to` are never both zero.\n *\n * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].\n */\n function _afterTokenTransfer(address from, address to, uint256 amount) internal virtual {}\n\n uint256[45] private __gap;\n}\n" + }, + "contracts/coreBorrow/CoreBorrow.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\n/*\n * █ \n ***** ▓▓▓ \n * ▓▓▓▓▓▓▓ \n * ///. ▓▓▓▓▓▓▓▓▓▓▓▓▓ \n ***** //////// ▓▓▓▓▓▓▓ \n * ///////////// ▓▓▓ \n ▓▓ ////////////////// █ ▓▓ \n ▓▓ ▓▓ /////////////////////// ▓▓ ▓▓ \n ▓▓ ▓▓ //////////////////////////// ▓▓ ▓▓ \n ▓▓ ▓▓ /////////▓▓▓///////▓▓▓///////// ▓▓ ▓▓ \n ▓▓ ,////////////////////////////////////// ▓▓ ▓▓ \n ▓▓ ////////////////////////////////////////// ▓▓ \n ▓▓ //////////////////////▓▓▓▓///////////////////// \n ,//////////////////////////////////////////////////// \n .////////////////////////////////////////////////////////// \n .//////////////////////////██.,//////////////////////////█ \n .//////////////////////████..,./////////////////////██ \n ...////////////////███████.....,.////////////////███ \n ,.,////////////████████ ........,///////////████ \n .,.,//////█████████ ,.......///////████ \n ,..//████████ ........./████ \n ..,██████ .....,███ \n .██ ,.,█ \n \n \n \n ▓▓ ▓▓▓▓▓▓▓▓▓▓ ▓▓▓▓▓▓▓▓▓▓ ▓▓ ▓▓▓▓▓▓▓▓▓▓ \n ▓▓▓▓▓▓ ▓▓▓ ▓▓▓ ▓▓▓ ▓▓ ▓▓ ▓▓▓▓ \n ▓▓▓ ▓▓▓ ▓▓▓ ▓▓▓ ▓▓▓ ▓▓▓ ▓▓ ▓▓▓▓▓ \n ▓▓▓ ▓▓ ▓▓▓ ▓▓▓ ▓▓▓▓▓▓▓▓▓▓ ▓▓▓▓▓▓▓▓▓▓ ▓▓▓▓▓▓▓▓▓▓ \n*/\n\npragma solidity ^0.8.12;\n\nimport \"@openzeppelin/contracts-upgradeable/access/AccessControlEnumerableUpgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol\";\n\nimport \"../interfaces/ICoreBorrow.sol\";\nimport \"../interfaces/IFlashAngle.sol\";\nimport \"../interfaces/ITreasury.sol\";\n\n/// @title CoreBorrow\n/// @author Angle Labs, Inc.\n/// @notice Core contract of the borrowing module. This contract handles the access control across all contracts\n/// (it is read by all treasury contracts), and manages the `flashLoanModule`. It has no minting rights over the\n/// stablecoin contracts\ncontract CoreBorrow is ICoreBorrow, Initializable, AccessControlEnumerableUpgradeable {\n /// @notice Role for guardians\n bytes32 public constant GUARDIAN_ROLE = keccak256(\"GUARDIAN_ROLE\");\n /// @notice Role for governors\n bytes32 public constant GOVERNOR_ROLE = keccak256(\"GOVERNOR_ROLE\");\n /// @notice Role for treasury contract\n bytes32 public constant FLASHLOANER_TREASURY_ROLE = keccak256(\"FLASHLOANER_TREASURY_ROLE\");\n\n // ============================= Reference =====================================\n\n /// @notice Reference to the `flashLoanModule` with minting rights over the different stablecoins of the protocol\n address public flashLoanModule;\n\n // =============================== Events ======================================\n\n event FlashLoanModuleUpdated(address indexed _flashloanModule);\n event CoreUpdated(address indexed _core);\n\n // =============================== Errors ======================================\n\n error InvalidCore();\n error IncompatibleGovernorAndGuardian();\n error NotEnoughGovernorsLeft();\n error ZeroAddress();\n\n /// @notice Initializes the `CoreBorrow` contract and the access control of the borrowing module\n /// @param governor Address of the governor of the Angle Protocol\n /// @param guardian Guardian address of the protocol\n function initialize(address governor, address guardian) public initializer {\n if (governor == address(0) || guardian == address(0)) revert ZeroAddress();\n if (governor == guardian) revert IncompatibleGovernorAndGuardian();\n _setupRole(GOVERNOR_ROLE, governor);\n _setupRole(GUARDIAN_ROLE, guardian);\n _setupRole(GUARDIAN_ROLE, governor);\n _setRoleAdmin(GUARDIAN_ROLE, GOVERNOR_ROLE);\n _setRoleAdmin(GOVERNOR_ROLE, GOVERNOR_ROLE);\n _setRoleAdmin(FLASHLOANER_TREASURY_ROLE, GOVERNOR_ROLE);\n }\n\n /// @custom:oz-upgrades-unsafe-allow constructor\n constructor() initializer {}\n\n // =========================== View Functions ==================================\n\n /// @inheritdoc ICoreBorrow\n function isFlashLoanerTreasury(address treasury) external view returns (bool) {\n return hasRole(FLASHLOANER_TREASURY_ROLE, treasury);\n }\n\n /// @inheritdoc ICoreBorrow\n function isGovernor(address admin) external view returns (bool) {\n return hasRole(GOVERNOR_ROLE, admin);\n }\n\n /// @inheritdoc ICoreBorrow\n function isGovernorOrGuardian(address admin) external view returns (bool) {\n return hasRole(GUARDIAN_ROLE, admin);\n }\n\n // =========================== Governor Functions ==============================\n\n /// @notice Grants the `FLASHLOANER_TREASURY_ROLE` to a `treasury` contract\n /// @param treasury Contract to grant the role to\n /// @dev This function can be used to allow flash loans on a stablecoin of the protocol\n function addFlashLoanerTreasuryRole(address treasury) external {\n grantRole(FLASHLOANER_TREASURY_ROLE, treasury);\n address _flashLoanModule = flashLoanModule;\n if (_flashLoanModule != address(0)) {\n // This call will revert if `treasury` is the zero address or if it is not linked\n // to this `CoreBorrow` contract\n ITreasury(treasury).setFlashLoanModule(_flashLoanModule);\n IFlashAngle(_flashLoanModule).addStablecoinSupport(treasury);\n }\n }\n\n /// @notice Adds a governor in the protocol\n /// @param governor Address to grant the role to\n /// @dev It is necessary to call this function to grant a governor role to make sure\n /// all governors also have the guardian role\n function addGovernor(address governor) external {\n grantRole(GOVERNOR_ROLE, governor);\n grantRole(GUARDIAN_ROLE, governor);\n }\n\n /// @notice Revokes the flash loan ability for a stablecoin\n /// @param treasury Treasury address associated with the stablecoin for which flash loans\n /// should no longer be available\n function removeFlashLoanerTreasuryRole(address treasury) external {\n revokeRole(FLASHLOANER_TREASURY_ROLE, treasury);\n ITreasury(treasury).setFlashLoanModule(address(0));\n address _flashLoanModule = flashLoanModule;\n if (_flashLoanModule != address(0)) {\n IFlashAngle(flashLoanModule).removeStablecoinSupport(treasury);\n }\n }\n\n /// @notice Revokes a governor from the protocol\n /// @param governor Address to remove the role to\n /// @dev It is necessary to call this function to remove a governor role to make sure\n /// the address also loses its guardian role\n function removeGovernor(address governor) external {\n if (getRoleMemberCount(GOVERNOR_ROLE) <= 1) revert NotEnoughGovernorsLeft();\n revokeRole(GUARDIAN_ROLE, governor);\n revokeRole(GOVERNOR_ROLE, governor);\n }\n\n /// @notice Changes the `flashLoanModule` of the protocol\n /// @param _flashLoanModule Address of the new flash loan module\n function setFlashLoanModule(address _flashLoanModule) external onlyRole(GOVERNOR_ROLE) {\n if (_flashLoanModule != address(0)) {\n if (address(IFlashAngle(_flashLoanModule).core()) != address(this)) revert InvalidCore();\n }\n uint256 count = getRoleMemberCount(FLASHLOANER_TREASURY_ROLE);\n for (uint256 i; i < count; ++i) {\n ITreasury(getRoleMember(FLASHLOANER_TREASURY_ROLE, i)).setFlashLoanModule(_flashLoanModule);\n }\n flashLoanModule = _flashLoanModule;\n emit FlashLoanModuleUpdated(_flashLoanModule);\n }\n\n /// @notice Changes the core contract of the protocol\n /// @param _core New core contract\n /// @dev This function verifies that all governors of the current core contract are also governors\n /// of the new core contract. It also notifies the `flashLoanModule` of the change.\n /// @dev Governance wishing to change the core contract should also make sure to call `setCore`\n /// in the different treasury contracts\n function setCore(ICoreBorrow _core) external onlyRole(GOVERNOR_ROLE) {\n uint256 count = getRoleMemberCount(GOVERNOR_ROLE);\n bool success;\n for (uint256 i; i < count; ++i) {\n success = _core.isGovernor(getRoleMember(GOVERNOR_ROLE, i));\n if (!success) break;\n }\n if (!success) revert InvalidCore();\n address _flashLoanModule = flashLoanModule;\n if (_flashLoanModule != address(0)) IFlashAngle(_flashLoanModule).setCore(address(_core));\n emit CoreUpdated(address(_core));\n }\n}\n" + }, + "contracts/deprecated/AgTokenIntermediateUpgrade.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\nimport \"../interfaces/IAgToken.sol\";\nimport \"../interfaces/coreModule/IStableMaster.sol\";\n// OpenZeppelin may update its version of the ERC20PermitUpgradeable token\nimport \"@openzeppelin/contracts-upgradeable/token/ERC20/extensions/draft-ERC20PermitUpgradeable.sol\";\n\n/// @title AgTokenIntermediateUpgrade\n/// @author Angle Labs, Inc.\n/// @notice Base contract for agToken, that is to say Angle's stablecoins\n/// @dev This contract is used to create and handle the stablecoins of Angle protocol\n/// @dev It is still possible for any address to burn its agTokens without redeeming collateral in exchange\n/// @dev This contract is the upgraded version of the AgToken that was first deployed on Ethereum mainnet and is used to\n/// add other minters as needed by AMOs\ncontract AgTokenIntermediateUpgrade is ERC20PermitUpgradeable {\n // ========================= References to other contracts =====================\n\n /// @notice Reference to the `StableMaster` contract associated to this `AgToken`\n address public stableMaster;\n\n // ============================= Constructor ===================================\n\n /// @notice Initializes the `AgToken` contract\n /// @param name_ Name of the token\n /// @param symbol_ Symbol of the token\n /// @param stableMaster_ Reference to the `StableMaster` contract associated to this agToken\n /// @dev By default, agTokens are ERC-20 tokens with 18 decimals\n function initialize(string memory name_, string memory symbol_, address stableMaster_) external initializer {\n __ERC20Permit_init(name_);\n __ERC20_init(name_, symbol_);\n require(stableMaster_ != address(0), \"0\");\n stableMaster = stableMaster_;\n }\n\n /// @custom:oz-upgrades-unsafe-allow constructor\n constructor() initializer {}\n\n // ======= Added Parameters and Variables from the first implementation ========\n\n /// @notice Checks whether an address has the right to mint agTokens\n mapping(address => bool) public isMinter;\n\n // =============================== Added Events ================================\n\n event MinterToggled(address indexed minter);\n\n // =============================== Setup Function ==============================\n\n /// @notice Sets up the minter role and gives it to the governor\n /// @dev This function just has to be called once\n function setUpMinter() external {\n address governor = 0xdC4e6DFe07EFCa50a197DF15D9200883eF4Eb1c8;\n require(msg.sender == governor);\n isMinter[governor] = true;\n emit MinterToggled(governor);\n }\n\n // =============================== Modifiers ===================================\n\n /// @notice Checks whether the sender has the minting right\n modifier onlyMinter() {\n require(isMinter[msg.sender] || msg.sender == stableMaster, \"35\");\n _;\n }\n\n // ========================= External Functions ================================\n // The following functions allow anyone to burn stablecoins without redeeming collateral\n // in exchange for that\n\n /// @notice Destroys `amount` token from the caller without giving collateral back\n /// @param amount Amount to burn\n /// @param poolManager Reference to the `PoolManager` contract for which the `stocksUsers` will\n /// need to be updated\n /// @dev When calling this function, people should specify the `poolManager` for which they want to decrease\n /// the `stocksUsers`: this is a way for the protocol to maintain healthy accounting variables\n function burnNoRedeem(uint256 amount, address poolManager) external {\n _burn(msg.sender, amount);\n IStableMaster(stableMaster).updateStocksUsers(amount, poolManager);\n }\n\n /// @notice Burns `amount` of agToken on behalf of another account without redeeming collateral back\n /// @param account Account to burn on behalf of\n /// @param amount Amount to burn\n /// @param poolManager Reference to the `PoolManager` contract for which the `stocksUsers` will need to be updated\n function burnFromNoRedeem(address account, uint256 amount, address poolManager) external {\n _burnFromNoRedeem(amount, account, msg.sender);\n IStableMaster(stableMaster).updateStocksUsers(amount, poolManager);\n }\n\n // ======================= Minter Role Only Functions ==========================\n\n /// @notice Burns `amount` tokens from a `burner` address\n /// @param amount Amount of tokens to burn\n /// @param burner Address to burn from\n /// @dev This method is to be called by a contract with a minter right on the AgToken after being\n /// requested to do so by an address willing to burn tokens from its address\n function burnSelf(uint256 amount, address burner) external onlyMinter {\n _burn(burner, amount);\n }\n\n /// @notice Burns `amount` tokens from a `burner` address after being asked to by `sender`\n /// @param amount Amount of tokens to burn\n /// @param burner Address to burn from\n /// @param sender Address which requested the burn from `burner`\n /// @dev This method is to be called by a contract with the minter right after being requested\n /// to do so by a `sender` address willing to burn tokens from another `burner` address\n /// @dev The method checks the allowance between the `sender` and the `burner`\n function burnFrom(uint256 amount, address burner, address sender) external onlyMinter {\n _burnFromNoRedeem(amount, burner, sender);\n }\n\n /// @notice Lets the `StableMaster` contract or another whitelisted contract mint agTokens\n /// @param account Address to mint to\n /// @param amount Amount to mint\n /// @dev The contracts allowed to issue agTokens are the `StableMaster` contract, `VaultManager` contracts\n /// associated to this stablecoin as well as the flash loan module (if activated) and potentially contracts\n /// whitelisted by governance\n function mint(address account, uint256 amount) external onlyMinter {\n _mint(account, amount);\n }\n\n // ======================= Minter Only Functions ===============================\n\n /// @notice Adds a minter in the contract\n /// @param minter Minter address to add\n function addMinter(address minter) external onlyMinter {\n isMinter[minter] = true;\n emit MinterToggled(minter);\n }\n\n /// @notice Removes a minter from the contract\n /// @param minter Minter address to remove\n /// @dev This function can at the moment only be called by a minter wishing to revoke itself\n function removeMinter(address minter) external {\n require(msg.sender == minter && isMinter[msg.sender], \"36\");\n isMinter[minter] = false;\n emit MinterToggled(minter);\n }\n\n // ============================ Internal Function ==============================\n\n /// @notice Internal version of the function `burnFromNoRedeem`\n /// @param amount Amount to burn\n /// @dev It is at the level of this function that allowance checks are performed\n function _burnFromNoRedeem(uint256 amount, address burner, address sender) internal {\n if (burner != sender) {\n uint256 currentAllowance = allowance(burner, sender);\n require(currentAllowance >= amount, \"23\");\n _approve(burner, sender, currentAllowance - amount);\n }\n _burn(burner, amount);\n }\n}\n" + }, + "contracts/deprecated/layerZero/OldLayerZeroBridgeToken.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.12;\n\nimport \"./OldOFTCore.sol\";\nimport \"../../interfaces/IAgTokenSideChainMultiBridge.sol\";\nimport \"@openzeppelin/contracts-upgradeable/security/PausableUpgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/token/ERC20/ERC20Upgradeable.sol\";\n\n/// @title LayerZeroBridgeToken\n/// @author Angle Labs, Inc., forked from https://github.com/LayerZero-Labs/solidity-examples/blob/main/contracts/token/oft/OFT.sol\n/// @notice Contract to be deployed on a L2/sidechain for bridging an AgToken using a bridge intermediate token and LayerZero\ncontract OldLayerZeroBridgeToken is OldOFTCore, ERC20Upgradeable, PausableUpgradeable {\n /// @notice Address of the bridgeable token\n /// @dev Immutable\n IAgTokenSideChainMultiBridge public canonicalToken;\n\n // =============================== Errors ================================\n\n error InvalidAllowance();\n\n // ============================= Constructor ===================================\n\n /// @notice Initializes the contract\n /// @param _name Name of the token corresponding to this contract\n /// @param _symbol Symbol of the token corresponding to this contract\n /// @param _lzEndpoint Layer zero endpoint to pass messages\n /// @param _treasury Address of the treasury contract used for access control\n /// @param initialSupply Initial supply to mint to the canonical token address\n /// @dev The initial supply corresponds to the initial amount that could be bridged using this OFT\n function initialize(\n string memory _name,\n string memory _symbol,\n address _lzEndpoint,\n address _treasury,\n uint256 initialSupply\n ) external initializer {\n __ERC20_init_unchained(_name, _symbol);\n __LzAppUpgradeable_init(_lzEndpoint, _treasury);\n\n canonicalToken = IAgTokenSideChainMultiBridge(address(ITreasury(_treasury).stablecoin()));\n _approve(address(this), address(canonicalToken), type(uint256).max);\n _mint(address(canonicalToken), initialSupply);\n }\n\n /// @custom:oz-upgrades-unsafe-allow constructor\n constructor() initializer {}\n\n // ==================== External Permissionless Functions ======================\n\n function sendWithPermit(\n uint16 _dstChainId,\n bytes memory _toAddress,\n uint256 _amount,\n address payable _refundAddress,\n address _zroPaymentAddress,\n bytes memory _adapterParams,\n uint256 deadline,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) public payable override {\n canonicalToken.permit(msg.sender, address(this), _amount, deadline, v, r, s);\n send(_dstChainId, _toAddress, _amount, _refundAddress, _zroPaymentAddress, _adapterParams);\n }\n\n function withdraw(uint256 amount, address recipient) external override returns (uint256 amountMinted) {\n // Does not check allowances as transfers from `msg.sender`\n _transfer(msg.sender, address(this), amount);\n amountMinted = canonicalToken.swapIn(address(this), amount, recipient);\n uint256 leftover = balanceOf(address(this));\n if (leftover != 0) {\n _transfer(address(this), msg.sender, leftover);\n }\n }\n\n // ============================= Internal Functions ===================================\n\n function _debitFrom(\n uint16,\n bytes memory,\n uint256 _amount\n ) internal override whenNotPaused returns (uint256 amountSwapped) {\n // No need to use safeTransferFrom as we know this implementation reverts on failure\n canonicalToken.transferFrom(msg.sender, address(this), _amount);\n\n // Swap canonical for this bridge token. There may be some fees\n amountSwapped = canonicalToken.swapOut(address(this), _amount, address(this));\n _burn(address(this), amountSwapped);\n }\n\n function _debitCreditFrom(uint16, bytes memory, uint256 _amount) internal override whenNotPaused returns (uint256) {\n _burn(msg.sender, _amount);\n return _amount;\n }\n\n function _creditTo(\n uint16,\n address _toAddress,\n uint256 _amount\n ) internal override whenNotPaused returns (uint256 amountMinted) {\n _mint(address(this), _amount);\n amountMinted = canonicalToken.swapIn(address(this), _amount, _toAddress);\n uint256 leftover = balanceOf(address(this));\n if (leftover != 0) {\n _transfer(address(this), _toAddress, leftover);\n }\n }\n\n // ======================= View Functions ================================\n\n /// @inheritdoc ERC165Upgradeable\n function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {\n return\n interfaceId == type(IOFT).interfaceId ||\n interfaceId == type(IERC20).interfaceId ||\n super.supportsInterface(interfaceId);\n }\n\n // ======================= Governance Functions ================================\n\n /// @notice Mints the intermediate contract to the `canonicalToken`\n /// @dev Used to increase the bridging capacity\n function mint(uint256 amount) external onlyGovernorOrGuardian {\n _mint(address(canonicalToken), amount);\n }\n\n /// @notice Burns the intermediate contract from the `canonicalToken`\n /// @dev Used to decrease the bridging capacity\n function burn(uint256 amount) external onlyGovernorOrGuardian {\n _burn(address(canonicalToken), amount);\n }\n\n /// @notice Increases allowance of the `canonicalToken`\n function setupAllowance() public onlyGovernorOrGuardian {\n _approve(address(this), address(canonicalToken), type(uint256).max);\n }\n\n /// @notice Pauses bridging through the contract\n /// @param pause Future pause status\n function pauseSendTokens(bool pause) external onlyGovernorOrGuardian {\n pause ? _pause() : _unpause();\n }\n\n uint256[49] private __gap;\n}\n" + }, + "contracts/deprecated/layerZero/OldNonblockingLzApp.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.12;\n\nimport \"@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol\";\nimport \"../../interfaces/external/layerZero/ILayerZeroReceiver.sol\";\nimport \"../../interfaces/external/layerZero/ILayerZeroUserApplicationConfig.sol\";\nimport \"../../interfaces/external/layerZero/ILayerZeroEndpoint.sol\";\nimport \"../../interfaces/ITreasury.sol\";\n\n/// @title OldNonblockingLzApp\n/// @author Angle Labs, Inc., forked from https://github.com/LayerZero-Labs/solidity-examples/\n/// @notice Base contract for bridging using LayerZero\nabstract contract OldNonblockingLzApp is Initializable, ILayerZeroReceiver, ILayerZeroUserApplicationConfig {\n /// @notice Layer Zero endpoint\n ILayerZeroEndpoint public lzEndpoint;\n\n /// @notice Maps chainIds to failed messages to retry them\n mapping(uint16 => mapping(bytes => mapping(uint64 => bytes32))) public failedMessages;\n\n /// @notice Maps chainIds to their OFT address\n mapping(uint16 => bytes) public trustedRemoteLookup;\n\n /// @notice Reference to the treasury contract to fetch access control\n address public treasury;\n\n // ================================== Events ===================================\n\n event SetTrustedRemote(uint16 _srcChainId, bytes _srcAddress);\n event MessageFailed(uint16 _srcChainId, bytes _srcAddress, uint64 _nonce, bytes _payload);\n\n // =============================== Errors ================================\n\n error NotGovernor();\n error NotGovernorOrGuardian();\n error InsufficientGas();\n error InvalidEndpoint();\n error InvalidSource();\n error InvalidCaller();\n error InvalidParams();\n error InvalidPayload();\n error ZeroAddress();\n\n // ============================= Constructor ===================================\n\n //solhint-disable-next-line\n function __LzAppUpgradeable_init(address _endpoint, address _treasury) internal {\n if (_endpoint == address(0) || _treasury == address(0)) revert ZeroAddress();\n lzEndpoint = ILayerZeroEndpoint(_endpoint);\n treasury = _treasury;\n }\n\n // =============================== Modifiers ===================================\n\n /// @notice Checks whether the `msg.sender` has the governor role or the guardian role\n modifier onlyGovernorOrGuardian() {\n if (!ITreasury(treasury).isGovernorOrGuardian(msg.sender)) revert NotGovernorOrGuardian();\n _;\n }\n\n // ==================== External Permissionless Functions ======================\n\n /// @notice Receives a message from the LZ endpoint and process it\n /// @param _srcChainId ChainId of the source chain - LayerZero standard\n /// @param _srcAddress Sender of the source chain\n /// @param _nonce Nounce of the message\n /// @param _payload Data: recipient address and amount\n function lzReceive(\n uint16 _srcChainId,\n bytes memory _srcAddress,\n uint64 _nonce,\n bytes memory _payload\n ) public virtual override {\n // lzReceive must be called by the endpoint for security\n if (msg.sender != address(lzEndpoint)) revert InvalidEndpoint();\n\n bytes memory trustedRemote = trustedRemoteLookup[_srcChainId];\n // if will still block the message pathway from (srcChainId, srcAddress). should not receive message from untrusted remote.\n if (_srcAddress.length != trustedRemote.length || keccak256(_srcAddress) != keccak256(trustedRemote))\n revert InvalidSource();\n\n _blockingLzReceive(_srcChainId, _srcAddress, _nonce, _payload);\n }\n\n /// @notice Retries a message that previously failed and was stored\n /// @param _srcChainId ChainId of the source chain - LayerZero standard\n /// @param _srcAddress Sender of the source chain\n /// @param _nonce Nounce of the message\n /// @param _payload Data: recipient address and amount\n function retryMessage(\n uint16 _srcChainId,\n bytes memory _srcAddress,\n uint64 _nonce,\n bytes memory _payload\n ) public payable virtual {\n // assert there is message to retry\n bytes32 payloadHash = failedMessages[_srcChainId][_srcAddress][_nonce];\n if (payloadHash == bytes32(0) || keccak256(_payload) != payloadHash) revert InvalidPayload();\n // clear the stored message\n failedMessages[_srcChainId][_srcAddress][_nonce] = bytes32(0);\n // execute the message. revert if it fails again\n _nonblockingLzReceive(_srcChainId, _srcAddress, _nonce, _payload);\n }\n\n // ============================= Internal Functions ===================================\n\n /// @notice Handles message receptions in a non blocking way\n /// @param _srcChainId ChainId of the source chain - LayerZero standard\n /// @param _srcAddress Sender of the source chain\n /// @param _nonce Nounce of the message\n /// @param _payload Data: recipient address and amount\n /// @dev public for the needs of try / catch but effectively internal\n function nonblockingLzReceive(\n uint16 _srcChainId,\n bytes memory _srcAddress,\n uint64 _nonce,\n bytes memory _payload\n ) public virtual {\n // only internal transaction\n if (msg.sender != address(this)) revert InvalidCaller();\n _nonblockingLzReceive(_srcChainId, _srcAddress, _nonce, _payload);\n }\n\n /// @notice Handles message receptions in a non blocking way\n /// @param _srcChainId ChainId of the source chain - LayerZero standard\n /// @param _srcAddress Sender of the source chain\n /// @param _nonce Nounce of the message\n /// @param _payload Data: recipient address and amount\n function _nonblockingLzReceive(\n uint16 _srcChainId,\n bytes memory _srcAddress,\n uint64 _nonce,\n bytes memory _payload\n ) internal virtual;\n\n /// @notice Handles message receptions in a blocking way\n /// @param _srcChainId ChainId of the source chain - LayerZero standard\n /// @param _srcAddress Sender of the source chain\n /// @param _nonce Nounce of the message\n /// @param _payload Data: recipient address and amount\n function _blockingLzReceive(\n uint16 _srcChainId,\n bytes memory _srcAddress,\n uint64 _nonce,\n bytes memory _payload\n ) internal {\n // try-catch all errors/exceptions\n try this.nonblockingLzReceive(_srcChainId, _srcAddress, _nonce, _payload) {\n // do nothing\n } catch {\n // error / exception\n failedMessages[_srcChainId][_srcAddress][_nonce] = keccak256(_payload);\n emit MessageFailed(_srcChainId, _srcAddress, _nonce, _payload);\n }\n }\n\n /// @notice Sends a message to the LZ endpoint and process it\n /// @param _dstChainId L0 defined chain id to send tokens too\n /// @param _payload Data: recipient address and amount\n /// @param _refundAddress Address LayerZero refunds if too much message fee is sent\n /// @param _zroPaymentAddress Set to address(0x0) if not paying in ZRO (LayerZero Token)\n /// @param _adapterParams Flexible bytes array to indicate messaging adapter services in L0\n function _lzSend(\n uint16 _dstChainId,\n bytes memory _payload,\n address payable _refundAddress,\n address _zroPaymentAddress,\n bytes memory _adapterParams\n ) internal virtual {\n bytes memory trustedRemote = trustedRemoteLookup[_dstChainId];\n if (trustedRemote.length == 0) revert InvalidSource();\n //solhint-disable-next-line\n lzEndpoint.send{ value: msg.value }(\n _dstChainId,\n trustedRemote,\n _payload,\n _refundAddress,\n _zroPaymentAddress,\n _adapterParams\n );\n }\n\n // ======================= Governance Functions ================================\n\n /// @notice Sets the corresponding address on an other chain.\n /// @param _srcChainId ChainId of the source chain - LayerZero standard\n /// @param _srcAddress Address on the source chain\n /// @dev Used for both receiving and sending message\n /// @dev There can only be one trusted source per chain\n /// @dev Allows owner to set it multiple times.\n function setTrustedRemote(uint16 _srcChainId, bytes calldata _srcAddress) external onlyGovernorOrGuardian {\n trustedRemoteLookup[_srcChainId] = _srcAddress;\n emit SetTrustedRemote(_srcChainId, _srcAddress);\n }\n\n /// @notice Fetches the default LZ config\n function getConfig(\n uint16 _version,\n uint16 _chainId,\n address,\n uint256 _configType\n ) external view returns (bytes memory) {\n return lzEndpoint.getConfig(_version, _chainId, address(this), _configType);\n }\n\n /// @notice Overrides the default LZ config\n function setConfig(\n uint16 _version,\n uint16 _chainId,\n uint256 _configType,\n bytes calldata _config\n ) external override onlyGovernorOrGuardian {\n lzEndpoint.setConfig(_version, _chainId, _configType, _config);\n }\n\n /// @notice Overrides the default LZ config\n function setSendVersion(uint16 _version) external override onlyGovernorOrGuardian {\n lzEndpoint.setSendVersion(_version);\n }\n\n /// @notice Overrides the default LZ config\n function setReceiveVersion(uint16 _version) external override onlyGovernorOrGuardian {\n lzEndpoint.setReceiveVersion(_version);\n }\n\n /// @notice Unpauses the receive functionalities\n function forceResumeReceive(\n uint16 _srcChainId,\n bytes calldata _srcAddress\n ) external override onlyGovernorOrGuardian {\n lzEndpoint.forceResumeReceive(_srcChainId, _srcAddress);\n }\n\n // ======================= View Functions ================================\n\n /// @notice Checks if the `_srcAddress` corresponds to the trusted source\n function isTrustedRemote(uint16 _srcChainId, bytes calldata _srcAddress) external view returns (bool) {\n bytes memory trustedSource = trustedRemoteLookup[_srcChainId];\n return keccak256(trustedSource) == keccak256(_srcAddress);\n }\n\n uint256[46] private __gap;\n}\n" + }, + "contracts/deprecated/layerZero/OldOFTCore.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.12;\n\nimport \"./OldNonblockingLzApp.sol\";\nimport \"../../agToken/layerZero/utils/IOFTCore.sol\";\nimport \"@openzeppelin/contracts-upgradeable/utils/introspection/ERC165Upgradeable.sol\";\n\n/// @title OFTCore\n/// @author Forked from https://github.com/LayerZero-Labs/solidity-examples/blob/main/contracts/token/oft/OFTCore.sol\n/// but with slight modifications from the Angle Labs, Inc. which added return values to the `_creditTo` and `_debitFrom` functions\n/// @notice Base contract for bridging using LayerZero\nabstract contract OldOFTCore is OldNonblockingLzApp, ERC165Upgradeable, IOFTCore {\n // ==================== External Permissionless Functions ======================\n\n /// @inheritdoc IOFTCore\n function sendWithPermit(\n uint16 _dstChainId,\n bytes memory _toAddress,\n uint256 _amount,\n address payable _refundAddress,\n address _zroPaymentAddress,\n bytes memory _adapterParams,\n uint256 deadline,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) public payable virtual;\n\n /// @inheritdoc IOFTCore\n function send(\n uint16 _dstChainId,\n bytes memory _toAddress,\n uint256 _amount,\n address payable _refundAddress,\n address _zroPaymentAddress,\n bytes memory _adapterParams\n ) public payable virtual {\n _amount = _debitFrom(_dstChainId, _toAddress, _amount);\n\n bytes memory payload = abi.encode(_toAddress, _amount);\n _lzSend(_dstChainId, payload, _refundAddress, _zroPaymentAddress, _adapterParams);\n\n uint64 nonce = lzEndpoint.getOutboundNonce(_dstChainId, address(this));\n emit SendToChain(msg.sender, _dstChainId, _toAddress, _amount, nonce);\n }\n\n /// @inheritdoc IOFTCore\n function sendCredit(\n uint16 _dstChainId,\n bytes memory _toAddress,\n uint256 _amount,\n address payable _refundAddress,\n address _zroPaymentAddress,\n bytes memory _adapterParams\n ) public payable virtual {\n _amount = _debitCreditFrom(_dstChainId, _toAddress, _amount);\n\n _send(_dstChainId, _toAddress, _amount, _refundAddress, _zroPaymentAddress, _adapterParams);\n }\n\n /// @inheritdoc IOFTCore\n function withdraw(uint256 amount, address recipient) external virtual returns (uint256);\n\n // =========================== Internal Functions ==============================\n\n /// @notice Internal function to send `_amount` amount of token to (`_dstChainId`, `_toAddress`)\n /// @param _dstChainId the destination chain identifier\n /// @param _toAddress can be any size depending on the `dstChainId`.\n /// @param _amount the quantity of tokens in wei\n /// @param _refundAddress the address LayerZero refunds if too much message fee is sent\n /// @param _zroPaymentAddress set to address(0x0) if not paying in ZRO (LayerZero Token)\n /// @param _adapterParams is a flexible bytes array to indicate messaging adapter services\n /// @dev Accounting and checks should be performed beforehand\n function _send(\n uint16 _dstChainId,\n bytes memory _toAddress,\n uint256 _amount,\n address payable _refundAddress,\n address _zroPaymentAddress,\n bytes memory _adapterParams\n ) internal {\n bytes memory payload = abi.encode(_toAddress, _amount);\n _lzSend(_dstChainId, payload, _refundAddress, _zroPaymentAddress, _adapterParams);\n\n uint64 nonce = lzEndpoint.getOutboundNonce(_dstChainId, address(this));\n emit SendToChain(msg.sender, _dstChainId, _toAddress, _amount, nonce);\n }\n\n function _nonblockingLzReceive(\n uint16 _srcChainId,\n bytes memory _srcAddress,\n uint64 _nonce,\n bytes memory _payload\n ) internal virtual override {\n // decode and load the toAddress\n (bytes memory toAddressBytes, uint256 amount) = abi.decode(_payload, (bytes, uint256));\n address toAddress;\n //solhint-disable-next-line\n assembly {\n toAddress := mload(add(toAddressBytes, 20))\n }\n amount = _creditTo(_srcChainId, toAddress, amount);\n\n emit ReceiveFromChain(_srcChainId, _srcAddress, toAddress, amount, _nonce);\n }\n\n /// @notice Makes accountability when bridging from this contract using canonical token\n /// @param _dstChainId ChainId of the destination chain - LayerZero standard\n /// @param _toAddress Recipient on the destination chain\n /// @param _amount Amount to bridge\n function _debitFrom(\n uint16 _dstChainId,\n bytes memory _toAddress,\n uint256 _amount\n ) internal virtual returns (uint256);\n\n /// @notice Makes accountability when bridging from this contract's credit\n /// @param _dstChainId ChainId of the destination chain - LayerZero standard\n /// @param _toAddress Recipient on the destination chain\n /// @param _amount Amount to bridge\n function _debitCreditFrom(\n uint16 _dstChainId,\n bytes memory _toAddress,\n uint256 _amount\n ) internal virtual returns (uint256);\n\n /// @notice Makes accountability when bridging to this contract\n /// @param _srcChainId ChainId of the source chain - LayerZero standard\n /// @param _toAddress Recipient on this chain\n /// @param _amount Amount to bridge\n function _creditTo(uint16 _srcChainId, address _toAddress, uint256 _amount) internal virtual returns (uint256);\n\n // ========================== View Functions ===================================\n\n /// @inheritdoc ERC165Upgradeable\n function supportsInterface(\n bytes4 interfaceId\n ) public view virtual override(ERC165Upgradeable, IERC165) returns (bool) {\n return interfaceId == type(IOFTCore).interfaceId || super.supportsInterface(interfaceId);\n }\n\n /// @inheritdoc IOFTCore\n function estimateSendFee(\n uint16 _dstChainId,\n bytes memory _toAddress,\n uint256 _amount,\n bool _useZro,\n bytes memory _adapterParams\n ) public view virtual override returns (uint256 nativeFee, uint256 zroFee) {\n // mock the payload for send()\n bytes memory payload = abi.encode(_toAddress, _amount);\n return lzEndpoint.estimateFees(_dstChainId, address(this), payload, _useZro, _adapterParams);\n }\n\n uint256[50] private __gap;\n}\n" + }, + "contracts/deprecated/OldAgEUR.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\nimport \"../interfaces/IAgToken.sol\";\nimport \"../interfaces/coreModule/IStableMaster.sol\";\nimport \"../interfaces/ITreasury.sol\";\n// OpenZeppelin may update its version of the ERC20PermitUpgradeable token\nimport \"@openzeppelin/contracts-upgradeable/token/ERC20/extensions/draft-ERC20PermitUpgradeable.sol\";\n\n/// @title AgToken\n/// @author Angle Labs, Inc.\n/// @notice Base contract for agToken, that is to say Angle's stablecoins\n/// @dev This contract is used to create and handle the stablecoins of Angle protocol\n/// @dev It is still possible for any address to burn its agTokens without redeeming collateral in exchange\n/// @dev This contract is the upgraded version of the AgToken that was first deployed on Ethereum mainnet\ncontract OldAgEUR is IAgToken, ERC20PermitUpgradeable {\n // ========================= References to other contracts =====================\n\n /// @notice Reference to the `StableMaster` contract associated to this `AgToken`\n address public stableMaster;\n\n // ============================= Constructor ===================================\n\n /// @notice Initializes the `AgToken` contract\n /// @param name_ Name of the token\n /// @param symbol_ Symbol of the token\n /// @param stableMaster_ Reference to the `StableMaster` contract associated to this agToken\n /// @dev By default, agTokens are ERC-20 tokens with 18 decimals\n function initialize(string memory name_, string memory symbol_, address stableMaster_) external initializer {\n __ERC20Permit_init(name_);\n __ERC20_init(name_, symbol_);\n require(stableMaster_ != address(0), \"0\");\n stableMaster = stableMaster_;\n }\n\n /// @custom:oz-upgrades-unsafe-allow constructor\n constructor() initializer {}\n\n // ======= Added Parameters and Variables from the first implementation ========\n\n /// @inheritdoc IAgToken\n mapping(address => bool) public isMinter;\n /// @notice Reference to the treasury contract which can grant minting rights\n address public treasury;\n /// @notice Boolean to check whether the contract has been reinitialized after its upgrade\n bool public treasuryInitialized;\n\n // =============================== Added Events ================================\n\n event TreasuryUpdated(address indexed _treasury);\n event MinterToggled(address indexed minter);\n\n // =============================== Added Errors ================================\n\n error BurnAmountExceedsAllowance();\n error InvalidSender();\n error InvalidTreasury();\n error NotGovernor();\n error NotMinter();\n error NotTreasury();\n error TreasuryAlreadyInitialized();\n\n // =============================== Setup Function ==============================\n\n /// @notice Sets up the treasury contract in this AgToken contract\n /// @param _treasury Treasury contract to add\n /// @dev The address calling this function has to be hard-coded in the contract\n /// @dev Can be called only once\n function setUpTreasury(address _treasury) external {\n // Only governor\n if (msg.sender != 0xdC4e6DFe07EFCa50a197DF15D9200883eF4Eb1c8) revert NotGovernor();\n if (address(ITreasury(_treasury).stablecoin()) != address(this)) revert InvalidTreasury();\n if (treasuryInitialized) revert TreasuryAlreadyInitialized();\n treasury = _treasury;\n treasuryInitialized = true;\n isMinter[stableMaster] = true;\n emit TreasuryUpdated(_treasury);\n }\n\n // =============================== Modifiers ===================================\n\n /// @notice Checks to see if it is the `Treasury` calling this contract\n /// @dev There is no Access Control here, because it can be handled cheaply through this modifier\n modifier onlyTreasury() {\n if (msg.sender != treasury) revert NotTreasury();\n _;\n }\n\n /// @notice Checks whether the sender has the minting right\n modifier onlyMinter() {\n if (!isMinter[msg.sender]) revert NotMinter();\n _;\n }\n\n // ========================= External Functions ================================\n // The following functions allow anyone to burn stablecoins without redeeming collateral\n // in exchange for that\n\n /// @notice Destroys `amount` token from the caller without giving collateral back\n /// @param amount Amount to burn\n /// @param poolManager Reference to the `PoolManager` contract for which the `stocksUsers` will\n /// need to be updated\n /// @dev When calling this function, people should specify the `poolManager` for which they want to decrease\n /// the `stocksUsers`: this is a way for the protocol to maintain healthy accounting variables\n function burnNoRedeem(uint256 amount, address poolManager) external {\n _burn(msg.sender, amount);\n IStableMaster(stableMaster).updateStocksUsers(amount, poolManager);\n }\n\n /// @notice Burns `amount` of agToken on behalf of another account without redeeming collateral back\n /// @param account Account to burn on behalf of\n /// @param amount Amount to burn\n /// @param poolManager Reference to the `PoolManager` contract for which the `stocksUsers` will need to be updated\n function burnFromNoRedeem(address account, uint256 amount, address poolManager) external {\n _burnFromNoRedeem(amount, account, msg.sender);\n IStableMaster(stableMaster).updateStocksUsers(amount, poolManager);\n }\n\n /// @notice Allows anyone to burn agToken without redeeming collateral back\n /// @param amount Amount of stablecoins to burn\n /// @dev This function can typically be called if there is a settlement mechanism to burn stablecoins\n function burnStablecoin(uint256 amount) external {\n _burn(msg.sender, amount);\n }\n\n // ======================= Minter Role Only Functions ==========================\n\n /// @inheritdoc IAgToken\n function burnSelf(uint256 amount, address burner) external onlyMinter {\n _burn(burner, amount);\n }\n\n /// @inheritdoc IAgToken\n function burnFrom(uint256 amount, address burner, address sender) external onlyMinter {\n _burnFromNoRedeem(amount, burner, sender);\n }\n\n /// @inheritdoc IAgToken\n function mint(address account, uint256 amount) external onlyMinter {\n _mint(account, amount);\n }\n\n // ======================= Treasury Only Functions =============================\n\n /// @inheritdoc IAgToken\n function addMinter(address minter) external onlyTreasury {\n isMinter[minter] = true;\n emit MinterToggled(minter);\n }\n\n /// @inheritdoc IAgToken\n function removeMinter(address minter) external {\n // The `treasury` contract cannot remove the `stableMaster`\n if (msg.sender != minter && (msg.sender != address(treasury) || minter == stableMaster)) revert InvalidSender();\n isMinter[minter] = false;\n emit MinterToggled(minter);\n }\n\n /// @inheritdoc IAgToken\n function setTreasury(address _treasury) external onlyTreasury {\n treasury = _treasury;\n emit TreasuryUpdated(_treasury);\n }\n\n // ============================ Internal Function ==============================\n\n /// @notice Internal version of the function `burnFromNoRedeem`\n /// @param amount Amount to burn\n /// @dev It is at the level of this function that allowance checks are performed\n function _burnFromNoRedeem(uint256 amount, address burner, address sender) internal {\n if (burner != sender) {\n uint256 currentAllowance = allowance(burner, sender);\n if (currentAllowance < amount) revert BurnAmountExceedsAllowance();\n _approve(burner, sender, currentAllowance - amount);\n }\n _burn(burner, amount);\n }\n}\n" + }, + "contracts/deprecated/OldAngleHelpers.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\nimport \"../interfaces/IAngleRouter.sol\";\nimport \"../interfaces/coreModule/IAgTokenMainnet.sol\";\nimport \"../interfaces/coreModule/ICore.sol\";\nimport \"../interfaces/coreModule/IOracleCore.sol\";\nimport \"../interfaces/coreModule/IPerpetualManager.sol\";\nimport \"../interfaces/coreModule/IPoolManager.sol\";\nimport \"../interfaces/coreModule/IStableMaster.sol\";\nimport \"@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol\";\nimport \"../interfaces/IVaultManager.sol\";\n\npragma solidity ^0.8.12;\n\nstruct Parameters {\n SLPData slpData;\n MintBurnData feeData;\n PerpetualManagerFeeData perpFeeData;\n PerpetualManagerParamData perpParam;\n}\n\nstruct PerpetualManagerFeeData {\n uint64[] xHAFeesDeposit;\n uint64[] yHAFeesDeposit;\n uint64[] xHAFeesWithdraw;\n uint64[] yHAFeesWithdraw;\n uint64 haBonusMalusDeposit;\n uint64 haBonusMalusWithdraw;\n}\n\nstruct PerpetualManagerParamData {\n uint64 maintenanceMargin;\n uint64 maxLeverage;\n uint64 targetHAHedge;\n uint64 limitHAHedge;\n uint64 lockTime;\n}\n\nstruct CollateralAddresses {\n address stableMaster;\n address poolManager;\n address perpetualManager;\n address sanToken;\n address oracle;\n address gauge;\n address feeManager;\n address[] strategies;\n}\n\n/// @title AngleHelpers\n/// @author Angle Labs, Inc.\n/// @notice Contract with view functions designed to facilitate integrations on the Core module of the Angle Protocol\n/// @dev This contract only contains view functions to be queried off-chain. It was thus not optimized for gas consumption\ncontract OldAngleHelpers is Initializable {\n // ======================== Helper View Functions ==============================\n\n /// @notice Gives the amount of `agToken` you'd be getting if you were executing in the same block a mint transaction\n /// with `amount` of `collateral` in the Core module of the Angle protocol as well as the value of the fees\n /// (in `BASE_PARAMS`) that would be applied during the mint\n /// @return Amount of `agToken` that would be obtained with a mint transaction in the same block\n /// @return Percentage of fees that would be taken during a mint transaction in the same block\n /// @dev This function reverts if the mint transaction was to revert in the same conditions (without taking into account\n /// potential approval problems to the `StableMaster` contract)\n function previewMintAndFees(\n uint256 amount,\n address agToken,\n address collateral\n ) external view returns (uint256, uint256) {\n return _previewMintAndFees(amount, agToken, collateral);\n }\n\n /// @notice Gives the amount of `collateral` you'd be getting if you were executing in the same block a burn transaction\n /// with `amount` of `agToken` in the Core module of the Angle protocol as well as the value of the fees\n /// (in `BASE_PARAMS`) that would be applied during the burn\n /// @return Amount of `collateral` that would be obtained with a burn transaction in the same block\n /// @return Percentage of fees that would be taken during a burn transaction in the same block\n /// @dev This function reverts if the burn transaction was to revert in the same conditions (without taking into account\n /// potential approval problems to the `StableMaster` contract or agToken balance prior to the call)\n function previewBurnAndFees(\n uint256 amount,\n address agToken,\n address collateral\n ) external view returns (uint256, uint256) {\n return _previewBurnAndFees(amount, agToken, collateral);\n }\n\n /// @notice Returns all the addresses associated to the (`agToken`,`collateral`) pair given\n /// @return addresses A struct with all the addresses associated in the Core module\n function getCollateralAddresses(\n address agToken,\n address collateral\n ) external view returns (CollateralAddresses memory addresses) {\n address stableMaster = IAgTokenMainnet(agToken).stableMaster();\n (address poolManager, address perpetualManager, address sanToken, address gauge) = ROUTER.mapPoolManagers(\n stableMaster,\n collateral\n );\n (, , , IOracleCore oracle, , , , , ) = IStableMaster(stableMaster).collateralMap(poolManager);\n addresses.stableMaster = stableMaster;\n addresses.poolManager = poolManager;\n addresses.perpetualManager = perpetualManager;\n addresses.sanToken = sanToken;\n addresses.gauge = gauge;\n addresses.oracle = address(oracle);\n addresses.feeManager = IPoolManager(poolManager).feeManager();\n\n uint256 length = 0;\n while (true) {\n try IPoolManager(poolManager).strategyList(length) returns (address) {\n length += 1;\n } catch {\n break;\n }\n }\n address[] memory strategies = new address[](length);\n for (uint256 i; i < length; ++i) {\n strategies[i] = IPoolManager(poolManager).strategyList(i);\n }\n addresses.strategies = strategies;\n }\n\n /// @notice Gets the addresses of all the `StableMaster` contracts and their associated `AgToken` addresses\n /// @return List of the `StableMaster` addresses of the Angle protocol\n /// @return List of the `AgToken` addresses of the protocol\n /// @dev The place of an agToken address in the list is the same as the corresponding `StableMaster` address\n function getStablecoinAddresses() external view returns (address[] memory, address[] memory) {\n address[] memory stableMasterAddresses = CORE.stablecoinList();\n address[] memory agTokenAddresses = new address[](stableMasterAddresses.length);\n for (uint256 i; i < stableMasterAddresses.length; ++i) {\n agTokenAddresses[i] = IStableMaster(stableMasterAddresses[i]).agToken();\n }\n return (stableMasterAddresses, agTokenAddresses);\n }\n\n /// @notice Returns most of the governance parameters associated to the (`agToken`,`collateral`) pair given\n /// @return params Struct with most of the parameters in the `StableMaster` and `PerpetualManager` contracts\n /// @dev Check out the struct `Parameters` for the meaning of the return values\n function getCollateralParameters(\n address agToken,\n address collateral\n ) external view returns (Parameters memory params) {\n (address stableMaster, address poolManager) = _getStableMasterAndPoolManager(agToken, collateral);\n (\n ,\n ,\n IPerpetualManager perpetualManager,\n ,\n ,\n ,\n ,\n SLPData memory slpData,\n MintBurnData memory feeData\n ) = IStableMaster(stableMaster).collateralMap(poolManager);\n\n params.slpData = slpData;\n params.feeData = feeData;\n params.perpParam.maintenanceMargin = perpetualManager.maintenanceMargin();\n params.perpParam.maxLeverage = perpetualManager.maxLeverage();\n params.perpParam.targetHAHedge = perpetualManager.targetHAHedge();\n params.perpParam.limitHAHedge = perpetualManager.limitHAHedge();\n params.perpParam.lockTime = perpetualManager.lockTime();\n\n params.perpFeeData.haBonusMalusDeposit = perpetualManager.haBonusMalusDeposit();\n params.perpFeeData.haBonusMalusWithdraw = perpetualManager.haBonusMalusWithdraw();\n\n uint256 length = 0;\n while (true) {\n try perpetualManager.xHAFeesDeposit(length) returns (uint64) {\n length += 1;\n } catch {\n break;\n }\n }\n uint64[] memory data = new uint64[](length);\n uint64[] memory data2 = new uint64[](length);\n for (uint256 i; i < length; ++i) {\n data[i] = perpetualManager.xHAFeesDeposit(i);\n data2[i] = perpetualManager.yHAFeesDeposit(i);\n }\n params.perpFeeData.xHAFeesDeposit = data;\n params.perpFeeData.yHAFeesDeposit = data2;\n\n length = 0;\n while (true) {\n try perpetualManager.xHAFeesWithdraw(length) returns (uint64) {\n length += 1;\n } catch {\n break;\n }\n }\n data = new uint64[](length);\n data2 = new uint64[](length);\n for (uint256 i; i < length; ++i) {\n data[i] = perpetualManager.xHAFeesWithdraw(i);\n data2[i] = perpetualManager.yHAFeesWithdraw(i);\n }\n params.perpFeeData.xHAFeesWithdraw = data;\n params.perpFeeData.yHAFeesWithdraw = data2;\n }\n\n /// @notice Returns the address of the poolManager associated to an (`agToken`, `collateral`) pair\n /// in the Core module of the protocol\n function getPoolManager(address agToken, address collateral) public view returns (address poolManager) {\n (, poolManager) = _getStableMasterAndPoolManager(agToken, collateral);\n }\n\n // ======================== Replica Functions ==================================\n // These replicate what is done in the other contracts of the protocol\n\n function _previewBurnAndFees(\n uint256 amount,\n address agToken,\n address collateral\n ) internal view returns (uint256 amountForUserInCollat, uint256 feePercent) {\n (address stableMaster, address poolManager) = _getStableMasterAndPoolManager(agToken, collateral);\n (\n address token,\n ,\n IPerpetualManager perpetualManager,\n IOracleCore oracle,\n uint256 stocksUsers,\n ,\n uint256 collatBase,\n ,\n MintBurnData memory feeData\n ) = IStableMaster(stableMaster).collateralMap(poolManager);\n if (token == address(0) || IStableMaster(stableMaster).paused(keccak256(abi.encodePacked(STABLE, poolManager))))\n revert NotInitialized();\n if (amount > stocksUsers) revert InvalidAmount();\n\n if (feeData.xFeeBurn.length == 1) {\n feePercent = feeData.yFeeBurn[0];\n } else {\n bytes memory data = abi.encode(address(perpetualManager), feeData.targetHAHedge);\n uint64 hedgeRatio = _computeHedgeRatio(stocksUsers - amount, data);\n feePercent = _piecewiseLinear(hedgeRatio, feeData.xFeeBurn, feeData.yFeeBurn);\n }\n feePercent = (feePercent * feeData.bonusMalusBurn) / BASE_PARAMS;\n\n amountForUserInCollat = (amount * (BASE_PARAMS - feePercent) * collatBase) / (oracle.readUpper() * BASE_PARAMS);\n }\n\n function _previewMintAndFees(\n uint256 amount,\n address agToken,\n address collateral\n ) internal view returns (uint256 amountForUserInStable, uint256 feePercent) {\n (address stableMaster, address poolManager) = _getStableMasterAndPoolManager(agToken, collateral);\n (\n address token,\n ,\n IPerpetualManager perpetualManager,\n IOracleCore oracle,\n uint256 stocksUsers,\n ,\n ,\n ,\n MintBurnData memory feeData\n ) = IStableMaster(stableMaster).collateralMap(poolManager);\n if (token == address(0) || IStableMaster(stableMaster).paused(keccak256(abi.encodePacked(STABLE, poolManager))))\n revert NotInitialized();\n\n amountForUserInStable = oracle.readQuoteLower(amount);\n\n if (feeData.xFeeMint.length == 1) feePercent = feeData.yFeeMint[0];\n else {\n bytes memory data = abi.encode(address(perpetualManager), feeData.targetHAHedge);\n uint64 hedgeRatio = _computeHedgeRatio(amountForUserInStable + stocksUsers, data);\n feePercent = _piecewiseLinear(hedgeRatio, feeData.xFeeMint, feeData.yFeeMint);\n }\n feePercent = (feePercent * feeData.bonusMalusMint) / BASE_PARAMS;\n\n amountForUserInStable = (amountForUserInStable * (BASE_PARAMS - feePercent)) / BASE_PARAMS;\n if (stocksUsers + amountForUserInStable > feeData.capOnStableMinted) revert InvalidAmount();\n }\n\n // ======================== Utility Functions ==================================\n // These utility functions are taken from other contracts of the protocol\n\n function _computeHedgeRatio(uint256 newStocksUsers, bytes memory data) internal view returns (uint64 ratio) {\n (address perpetualManager, uint64 targetHAHedge) = abi.decode(data, (address, uint64));\n uint256 totalHedgeAmount = IPerpetualManager(perpetualManager).totalHedgeAmount();\n newStocksUsers = (targetHAHedge * newStocksUsers) / BASE_PARAMS;\n if (newStocksUsers > totalHedgeAmount) ratio = uint64((totalHedgeAmount * BASE_PARAMS) / newStocksUsers);\n else ratio = uint64(BASE_PARAMS);\n }\n\n function _piecewiseLinear(uint64 x, uint64[] memory xArray, uint64[] memory yArray) internal pure returns (uint64) {\n if (x >= xArray[xArray.length - 1]) {\n return yArray[xArray.length - 1];\n } else if (x <= xArray[0]) {\n return yArray[0];\n } else {\n uint256 lower;\n uint256 upper = xArray.length - 1;\n uint256 mid;\n while (upper - lower > 1) {\n mid = lower + (upper - lower) / 2;\n if (xArray[mid] <= x) {\n lower = mid;\n } else {\n upper = mid;\n }\n }\n if (yArray[upper] > yArray[lower]) {\n return\n yArray[lower] +\n ((yArray[upper] - yArray[lower]) * (x - xArray[lower])) /\n (xArray[upper] - xArray[lower]);\n } else {\n return\n yArray[lower] -\n ((yArray[lower] - yArray[upper]) * (x - xArray[lower])) /\n (xArray[upper] - xArray[lower]);\n }\n }\n }\n\n function _getStableMasterAndPoolManager(\n address agToken,\n address collateral\n ) internal view returns (address stableMaster, address poolManager) {\n stableMaster = IAgTokenMainnet(agToken).stableMaster();\n (poolManager, , , ) = ROUTER.mapPoolManagers(stableMaster, collateral);\n }\n\n // ====================== Constants and Initializers ===========================\n\n IAngleRouter public constant ROUTER = IAngleRouter(0xBB755240596530be0c1DE5DFD77ec6398471561d);\n ICore public constant CORE = ICore(0x61ed74de9Ca5796cF2F8fD60D54160D47E30B7c3);\n\n bytes32 public constant STABLE = keccak256(\"STABLE\");\n uint256 public constant BASE_PARAMS = 10 ** 9;\n\n error NotInitialized();\n error InvalidAmount();\n\n /// @custom:oz-upgrades-unsafe-allow constructor\n constructor() initializer {}\n}\n" + }, + "contracts/deprecated/vaultManager/OldVaultManagerERC721.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\nimport \"./OldVaultManagerStorage.sol\";\n\n/// @title VaultManagerERC721\n/// @author Angle Labs, Inc.\n/// @dev Base ERC721 Implementation of VaultManager\nabstract contract OldVaultManagerERC721 is IERC721MetadataUpgradeable, OldVaultManagerStorage {\n using SafeERC20 for IERC20;\n using Address for address;\n\n /// @inheritdoc IERC721MetadataUpgradeable\n string public name;\n /// @inheritdoc IERC721MetadataUpgradeable\n string public symbol;\n\n // ================================= MODIFIERS =================================\n\n /// @notice Checks if the person interacting with the vault with `vaultID` is approved\n /// @param caller Address of the person seeking to interact with the vault\n /// @param vaultID ID of the concerned vault\n modifier onlyApprovedOrOwner(address caller, uint256 vaultID) {\n if (!_isApprovedOrOwner(caller, vaultID)) revert NotApproved();\n _;\n }\n\n // ================================ ERC721 LOGIC ===============================\n\n /// @notice Checks whether a given address is approved for a vault or owns this vault\n /// @param spender Address for which vault ownership should be checked\n /// @param vaultID ID of the vault to check\n /// @return Whether the `spender` address owns or is approved for `vaultID`\n function isApprovedOrOwner(address spender, uint256 vaultID) external view returns (bool) {\n return _isApprovedOrOwner(spender, vaultID);\n }\n\n /// @inheritdoc IERC721MetadataUpgradeable\n function tokenURI(uint256 vaultID) external view returns (string memory) {\n if (!_exists(vaultID)) revert NonexistentVault();\n // There is no vault with `vaultID` equal to 0, so the following variable is\n // always greater than zero\n uint256 temp = vaultID;\n uint256 digits;\n while (temp != 0) {\n digits++;\n temp /= 10;\n }\n bytes memory buffer = new bytes(digits);\n while (vaultID != 0) {\n digits -= 1;\n buffer[digits] = bytes1(uint8(48 + uint256(vaultID % 10)));\n vaultID /= 10;\n }\n return bytes(_baseURI).length > 0 ? string(abi.encodePacked(_baseURI, string(buffer))) : \"\";\n }\n\n /// @inheritdoc IERC721Upgradeable\n function balanceOf(address owner) external view returns (uint256) {\n if (owner == address(0)) revert ZeroAddress();\n return _balances[owner];\n }\n\n /// @inheritdoc IERC721Upgradeable\n function ownerOf(uint256 vaultID) external view returns (address) {\n return _ownerOf(vaultID);\n }\n\n /// @inheritdoc IERC721Upgradeable\n function approve(address to, uint256 vaultID) external {\n address owner = _ownerOf(vaultID);\n if (to == owner) revert ApprovalToOwner();\n if (msg.sender != owner && !isApprovedForAll(owner, msg.sender)) revert NotApproved();\n\n _approve(to, vaultID);\n }\n\n /// @inheritdoc IERC721Upgradeable\n function getApproved(uint256 vaultID) external view returns (address) {\n if (!_exists(vaultID)) revert NonexistentVault();\n return _getApproved(vaultID);\n }\n\n /// @inheritdoc IERC721Upgradeable\n function setApprovalForAll(address operator, bool approved) external {\n _setApprovalForAll(msg.sender, operator, approved);\n }\n\n /// @inheritdoc IERC721Upgradeable\n function isApprovedForAll(address owner, address operator) public view returns (bool) {\n return _operatorApprovals[owner][operator] == 1;\n }\n\n /// @inheritdoc IERC721Upgradeable\n function transferFrom(address from, address to, uint256 vaultID) external onlyApprovedOrOwner(msg.sender, vaultID) {\n _transfer(from, to, vaultID);\n }\n\n /// @inheritdoc IERC721Upgradeable\n function safeTransferFrom(address from, address to, uint256 vaultID) external {\n safeTransferFrom(from, to, vaultID, \"\");\n }\n\n /// @inheritdoc IERC721Upgradeable\n function safeTransferFrom(\n address from,\n address to,\n uint256 vaultID,\n bytes memory _data\n ) public onlyApprovedOrOwner(msg.sender, vaultID) {\n _safeTransfer(from, to, vaultID, _data);\n }\n\n // ================================ ERC165 LOGIC ===============================\n\n /// @inheritdoc IERC165Upgradeable\n function supportsInterface(bytes4 interfaceId) external pure returns (bool) {\n return\n interfaceId == type(IERC721MetadataUpgradeable).interfaceId ||\n interfaceId == type(IERC721Upgradeable).interfaceId ||\n interfaceId == type(IVaultManager).interfaceId ||\n interfaceId == type(IERC165Upgradeable).interfaceId;\n }\n\n // ================== INTERNAL FUNCTIONS FOR THE ERC721 LOGIC ==================\n\n /// @notice Internal version of the `ownerOf` function\n function _ownerOf(uint256 vaultID) internal view returns (address owner) {\n owner = _owners[vaultID];\n if (owner == address(0)) revert NonexistentVault();\n }\n\n /// @notice Internal version of the `getApproved` function\n function _getApproved(uint256 vaultID) internal view returns (address) {\n return _vaultApprovals[vaultID];\n }\n\n /// @notice Internal version of the `safeTransferFrom` function (with the data parameter)\n function _safeTransfer(address from, address to, uint256 vaultID, bytes memory _data) internal {\n _transfer(from, to, vaultID);\n if (!_checkOnERC721Received(from, to, vaultID, _data)) revert NonERC721Receiver();\n }\n\n /// @notice Checks whether a vault exists\n /// @param vaultID ID of the vault to check\n /// @return Whether `vaultID` has been created\n function _exists(uint256 vaultID) internal view returns (bool) {\n return _owners[vaultID] != address(0);\n }\n\n /// @notice Internal version of the `isApprovedOrOwner` function\n function _isApprovedOrOwner(address spender, uint256 vaultID) internal view returns (bool) {\n // The following checks if the vault exists\n address owner = _ownerOf(vaultID);\n return (spender == owner || _getApproved(vaultID) == spender || _operatorApprovals[owner][spender] == 1);\n }\n\n /// @notice Internal version of the `createVault` function\n /// Mints `vaultID` and transfers it to `to`\n /// @dev This method is equivalent to the `_safeMint` method used in OpenZeppelin ERC721 contract\n /// @dev Emits a {Transfer} event\n function _mint(address to) internal returns (uint256 vaultID) {\n if (whitelistingActivated && (isWhitelisted[to] != 1 || isWhitelisted[msg.sender] != 1))\n revert NotWhitelisted();\n if (to == address(0)) revert ZeroAddress();\n\n unchecked {\n vaultIDCount += 1;\n }\n\n vaultID = vaultIDCount;\n _beforeTokenTransfer(address(0), to, vaultID);\n\n unchecked {\n _balances[to] += 1;\n }\n\n _owners[vaultID] = to;\n emit Transfer(address(0), to, vaultID);\n if (!_checkOnERC721Received(address(0), to, vaultID, \"\")) revert NonERC721Receiver();\n }\n\n /// @notice Destroys `vaultID`\n /// @dev `vaultID` must exist\n /// @dev Emits a {Transfer} event\n function _burn(uint256 vaultID) internal {\n address owner = _ownerOf(vaultID);\n\n _beforeTokenTransfer(owner, address(0), vaultID);\n // Clear approvals\n _approve(address(0), vaultID);\n // The following line cannot underflow as the owner's balance is necessarily\n // greater than 1\n unchecked {\n _balances[owner] -= 1;\n }\n delete _owners[vaultID];\n delete vaultData[vaultID];\n\n emit Transfer(owner, address(0), vaultID);\n }\n\n /// @notice Transfers `vaultID` from `from` to `to` as opposed to {transferFrom},\n /// this imposes no restrictions on msg.sender\n /// @dev `to` cannot be the zero address and `perpetualID` must be owned by `from`\n /// @dev Emits a {Transfer} event\n /// @dev A whitelist check is performed if necessary on the `to` address\n function _transfer(address from, address to, uint256 vaultID) internal {\n if (_ownerOf(vaultID) != from) revert NotApproved();\n if (to == address(0)) revert ZeroAddress();\n if (whitelistingActivated && isWhitelisted[to] != 1) revert NotWhitelisted();\n\n _beforeTokenTransfer(from, to, vaultID);\n\n // Clear approvals from the previous owner\n _approve(address(0), vaultID);\n unchecked {\n _balances[from] -= 1;\n _balances[to] += 1;\n }\n _owners[vaultID] = to;\n\n emit Transfer(from, to, vaultID);\n }\n\n /// @notice Approves `to` to operate on `vaultID`\n function _approve(address to, uint256 vaultID) internal {\n _vaultApprovals[vaultID] = to;\n emit Approval(_ownerOf(vaultID), to, vaultID);\n }\n\n /// @notice Internal version of the `setApprovalForAll` function\n /// @dev It contains an `approver` field to be used in case someone signs a permit for a particular\n /// address, and this signature is given to the contract by another address (like a router)\n function _setApprovalForAll(address approver, address operator, bool approved) internal {\n if (operator == approver) revert ApprovalToCaller();\n uint256 approval = approved ? 1 : 0;\n _operatorApprovals[approver][operator] = approval;\n emit ApprovalForAll(approver, operator, approved);\n }\n\n /// @notice Internal function to invoke {IERC721Receiver-onERC721Received} on a target address\n /// The call is not executed if the target address is not a contract\n /// @param from Address representing the previous owner of the given token ID\n /// @param to Target address that will receive the tokens\n /// @param vaultID ID of the token to be transferred\n /// @param _data Bytes optional data to send along with the call\n /// @return Bool whether the call correctly returned the expected value\n function _checkOnERC721Received(\n address from,\n address to,\n uint256 vaultID,\n bytes memory _data\n ) private returns (bool) {\n if (to.isContract()) {\n try IERC721ReceiverUpgradeable(to).onERC721Received(msg.sender, from, vaultID, _data) returns (\n bytes4 retval\n ) {\n return retval == IERC721ReceiverUpgradeable.onERC721Received.selector;\n } catch (bytes memory reason) {\n if (reason.length == 0) {\n revert NonERC721Receiver();\n } else {\n // solhint-disable-next-line no-inline-assembly\n assembly {\n revert(add(32, reason), mload(reason))\n }\n }\n }\n } else {\n return true;\n }\n }\n\n /// @notice Hook that is called before any token transfer. This includes minting and burning.\n /// Calling conditions:\n ///\n /// - When `from` and `to` are both non-zero, `from`'s `vaultID` will be\n /// transferred to `to`.\n /// - When `from` is zero, `vaultID` will be minted for `to`.\n /// - When `to` is zero, `from`'s `vaultID` will be burned.\n /// - `from` and `to` are never both zero.\n function _beforeTokenTransfer(address from, address to, uint256 vaultID) internal virtual {}\n}\n" + }, + "contracts/deprecated/vaultManager/OldVaultManagerPermit.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\nimport \"./OldVaultManagerERC721.sol\";\nimport \"../../interfaces/external/IERC1271.sol\";\n\n/// @title VaultManagerPermit\n/// @author Angle Labs, Inc.\n/// @dev Base Implementation of permit functions for the `VaultManager` contract\nabstract contract OldVaultManagerPermit is Initializable, OldVaultManagerERC721 {\n using Address for address;\n\n mapping(address => uint256) private _nonces;\n /* solhint-disable var-name-mixedcase */\n bytes32 private _HASHED_NAME;\n bytes32 private _HASHED_VERSION;\n bytes32 private _PERMIT_TYPEHASH;\n /* solhint-enable var-name-mixedcase */\n\n error ExpiredDeadline();\n error InvalidSignature();\n\n //solhint-disable-next-line\n function __ERC721Permit_init(string memory _name) internal onlyInitializing {\n _PERMIT_TYPEHASH = keccak256(\n \"Permit(address owner,address spender,bool approved,uint256 nonce,uint256 deadline)\"\n );\n _HASHED_NAME = keccak256(bytes(_name));\n _HASHED_VERSION = keccak256(bytes(\"1\"));\n }\n\n /// @notice Allows an address to give or revoke approval for all its vaults to another address\n /// @param owner Address signing the permit and giving (or revoking) its approval for all the controlled vaults\n /// @param spender Address to give approval to\n /// @param approved Whether to give or revoke the approval\n /// @param deadline Deadline parameter for the signature to be valid\n /// @dev The `v`, `r`, and `s` parameters are used as signature data\n function permit(\n address owner,\n address spender,\n bool approved,\n uint256 deadline,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) external {\n if (block.timestamp > deadline) revert ExpiredDeadline();\n // Additional signature checks performed in the `ECDSAUpgradeable.recover` function\n if (uint256(s) > 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D576E7357A4501DDFE92F46681B20A0 || (v != 27 && v != 28))\n revert InvalidSignature();\n\n bytes32 digest = keccak256(\n abi.encodePacked(\n \"\\x19\\x01\",\n _domainSeparatorV4(),\n keccak256(\n abi.encode(\n _PERMIT_TYPEHASH,\n // 0x3f43a9c6bafb5c7aab4e0cfe239dc5d4c15caf0381c6104188191f78a6640bd8,\n owner,\n spender,\n approved,\n _useNonce(owner),\n deadline\n )\n )\n )\n );\n if (owner.isContract()) {\n if (IERC1271(owner).isValidSignature(digest, abi.encodePacked(r, s, v)) != 0x1626ba7e)\n revert InvalidSignature();\n } else {\n address signer = ecrecover(digest, v, r, s);\n if (signer != owner || signer == address(0)) revert InvalidSignature();\n }\n\n _setApprovalForAll(owner, spender, approved);\n }\n\n /// @notice Returns the current nonce for an `owner` address\n function nonces(address owner) public view returns (uint256) {\n return _nonces[owner];\n }\n\n /// @notice Returns the domain separator for the current chain.\n // solhint-disable-next-line func-name-mixedcase\n function DOMAIN_SEPARATOR() external view returns (bytes32) {\n return _domainSeparatorV4();\n }\n\n /// @notice Internal version of the `DOMAIN_SEPARATOR` function\n function _domainSeparatorV4() internal view returns (bytes32) {\n return\n keccak256(\n abi.encode(\n // keccak256('EIP712Domain(string name,string version,uint256 chainId,address verifyingContract)')\n 0x8b73c3c69bb8fe3d512ecc4cf759cc79239f7b179b0ffacaa9a75d522b39400f,\n _HASHED_NAME,\n _HASHED_VERSION,\n block.chainid,\n address(this)\n )\n );\n }\n\n /// @notice Consumes a nonce for an address: returns the current value and increments it\n function _useNonce(address owner) internal returns (uint256 current) {\n current = _nonces[owner];\n _nonces[owner] = current + 1;\n }\n\n uint256[49] private __gap;\n}\n" + }, + "contracts/deprecated/vaultManager/OldVaultManagerStorage.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\nimport \"@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/token/ERC20/extensions/draft-IERC20PermitUpgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/token/ERC721/IERC721ReceiverUpgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/interfaces/IERC721MetadataUpgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/utils/introspection/IERC165Upgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/utils/AddressUpgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/security/ReentrancyGuardUpgradeable.sol\";\nimport \"@openzeppelin/contracts/token/ERC20/extensions/IERC20Metadata.sol\";\nimport \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\nimport \"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\";\n\nimport \"../../interfaces/IAgToken.sol\";\nimport \"../../interfaces/IOracle.sol\";\nimport \"../../interfaces/ISwapper.sol\";\nimport \"../../interfaces/ITreasury.sol\";\nimport \"../../interfaces/IVaultManager.sol\";\nimport \"../../interfaces/governance/IVeBoostProxy.sol\";\n\n/// @title VaultManagerStorage\n/// @author Angle Labs, Inc.\n/// @dev Variables, references, parameters and events needed in the `VaultManager` contract\n// solhint-disable-next-line max-states-count\ncontract OldVaultManagerStorage is IVaultManagerStorage, Initializable, ReentrancyGuardUpgradeable {\n /// @notice Base used for parameter computation: almost all the parameters of this contract are set in `BASE_PARAMS`\n uint256 public constant BASE_PARAMS = 10 ** 9;\n /// @notice Base used for interest rate computation\n uint256 public constant BASE_INTEREST = 10 ** 27;\n /// @notice Used for interest rate computation\n uint256 public constant HALF_BASE_INTEREST = 10 ** 27 / 2;\n\n // ================================= REFERENCES ================================\n\n /// @inheritdoc IVaultManagerStorage\n ITreasury public treasury;\n /// @inheritdoc IVaultManagerStorage\n IERC20 public collateral;\n /// @inheritdoc IVaultManagerStorage\n IAgToken public stablecoin;\n /// @inheritdoc IVaultManagerStorage\n IOracle public oracle;\n /// @notice Reference to the contract which computes adjusted veANGLE balances for liquidators boosts\n IVeBoostProxy public veBoostProxy;\n /// @notice Base of the collateral\n uint256 internal _collatBase;\n\n // ================================= PARAMETERS ================================\n // Unless specified otherwise, parameters of this contract are expressed in `BASE_PARAMS`\n\n /// @notice Maximum amount of stablecoins that can be issued with this contract (in `BASE_TOKENS`). This parameter should\n /// not be bigger than `type(uint256).max / BASE_INTEREST` otherwise there may be some overflows in the `increaseDebt` function\n uint256 public debtCeiling;\n /// @notice Threshold veANGLE balance values for the computation of the boost for liquidators: the length of this array\n /// should normally be 2. The base of the x-values in this array should be `BASE_TOKENS`\n uint256[] public xLiquidationBoost;\n /// @notice Values of the liquidation boost at the threshold values of x\n uint256[] public yLiquidationBoost;\n /// @inheritdoc IVaultManagerStorage\n uint64 public collateralFactor;\n /// @notice Maximum Health factor at which a vault can end up after a liquidation (unless it's fully liquidated)\n uint64 public targetHealthFactor;\n /// @notice Upfront fee taken when borrowing stablecoins: this fee is optional and should in practice not be used\n uint64 public borrowFee;\n /// @notice Upfront fee taken when repaying stablecoins: this fee is optional as well. It should be smaller\n /// than the liquidation surcharge (cf below) to avoid exploits where people voluntarily get liquidated at a 0\n /// discount to pay smaller repaying fees\n uint64 public repayFee;\n /// @notice Per second interest taken to borrowers taking agToken loans. Contrarily to other parameters, it is set in `BASE_INTEREST`\n /// that is to say in base 10**27\n uint64 public interestRate;\n /// @notice Fee taken by the protocol during a liquidation. Technically, this value is not the fee per se, it's 1 - fee.\n /// For instance for a 2% fee, `liquidationSurcharge` should be 98%\n uint64 public liquidationSurcharge;\n /// @notice Maximum discount given to liquidators\n uint64 public maxLiquidationDiscount;\n /// @notice Whether whitelisting is required to own a vault or not\n bool public whitelistingActivated;\n /// @notice Whether the contract is paused or not\n bool public paused;\n\n // ================================= VARIABLES =================================\n\n /// @notice Timestamp at which the `interestAccumulator` was updated\n uint256 public lastInterestAccumulatorUpdated;\n /// @inheritdoc IVaultManagerStorage\n uint256 public interestAccumulator;\n /// @inheritdoc IVaultManagerStorage\n uint256 public totalNormalizedDebt;\n /// @notice Surplus accumulated by the contract: surplus is always in stablecoins, and is then reset\n /// when the value is communicated to the treasury contract\n uint256 public surplus;\n /// @notice Bad debt made from liquidated vaults which ended up having no collateral and a positive amount\n /// of stablecoins\n uint256 public badDebt;\n\n // ================================== MAPPINGS =================================\n\n /// @inheritdoc IVaultManagerStorage\n mapping(uint256 => Vault) public vaultData;\n /// @notice Maps an address to 1 if it's whitelisted and can open or own a vault\n mapping(address => uint256) public isWhitelisted;\n\n // ================================ ERC721 DATA ================================\n\n /// @inheritdoc IVaultManagerStorage\n uint256 public vaultIDCount;\n\n /// @notice URI\n string internal _baseURI;\n\n // Mapping from `vaultID` to owner address\n mapping(uint256 => address) internal _owners;\n\n // Mapping from owner address to vault owned count\n mapping(address => uint256) internal _balances;\n\n // Mapping from `vaultID` to approved address\n mapping(uint256 => address) internal _vaultApprovals;\n\n // Mapping from owner to operator approvals\n mapping(address => mapping(address => uint256)) internal _operatorApprovals;\n\n uint256[50] private __gap;\n\n // =================================== EVENTS ==================================\n\n event AccruedToTreasury(uint256 surplusEndValue, uint256 badDebtEndValue);\n event CollateralAmountUpdated(uint256 vaultID, uint256 collateralAmount, uint8 isIncrease);\n event InterestAccumulatorUpdated(uint256 value, uint256 timestamp);\n event InternalDebtUpdated(uint256 vaultID, uint256 internalAmount, uint8 isIncrease);\n event FiledUint64(uint64 param, bytes32 what);\n event DebtCeilingUpdated(uint256 debtCeiling);\n event LiquidationBoostParametersUpdated(address indexed _veBoostProxy, uint256[] xBoost, uint256[] yBoost);\n event LiquidatedVaults(uint256[] vaultIDs);\n event DebtTransferred(uint256 srcVaultID, uint256 dstVaultID, address dstVaultManager, uint256 amount);\n\n // =================================== ERRORS ==================================\n\n error ApprovalToOwner();\n error ApprovalToCaller();\n error DustyLeftoverAmount();\n error DebtCeilingExceeded();\n error HealthyVault();\n error IncompatibleLengths();\n error InsolventVault();\n error InvalidParameterValue();\n error InvalidParameterType();\n error InvalidSetOfParameters();\n error InvalidTreasury();\n error NonERC721Receiver();\n error NonexistentVault();\n error NotApproved();\n error NotGovernor();\n error NotGovernorOrGuardian();\n error NotTreasury();\n error NotWhitelisted();\n error NotVaultManager();\n error Paused();\n error TooHighParameterValue();\n error TooSmallParameterValue();\n error ZeroAddress();\n\n /// @custom:oz-upgrades-unsafe-allow constructor\n constructor() initializer {}\n}\n" + }, + "contracts/external/ProxyAdmin.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\nimport \"./TransparentUpgradeableProxy.sol\";\nimport \"@openzeppelin/contracts/access/Ownable.sol\";\n\n/**\n * @dev This is an auxiliary contract meant to be assigned as the admin of a {TransparentUpgradeableProxy}. For an\n * explanation of why you would want to use this see the documentation for {TransparentUpgradeableProxy}.\n * This contract was fully forked from OpenZeppelin `ProxyAdmin`\n */\ncontract ProxyAdmin is Ownable {\n /**\n * @dev Returns the current implementation of `proxy`.\n *\n * Requirements:\n *\n * - This contract must be the admin of `proxy`.\n */\n function getProxyImplementation(TransparentUpgradeableProxy proxy) public view virtual returns (address) {\n // We need to manually run the static call since the getter cannot be flagged as view\n // bytes4(keccak256(\"implementation()\")) == 0x5c60da1b\n (bool success, bytes memory returndata) = address(proxy).staticcall(hex\"5c60da1b\");\n require(success);\n return abi.decode(returndata, (address));\n }\n\n /**\n * @dev Returns the current admin of `proxy`.\n *\n * Requirements:\n *\n * - This contract must be the admin of `proxy`.\n */\n function getProxyAdmin(TransparentUpgradeableProxy proxy) public view virtual returns (address) {\n // We need to manually run the static call since the getter cannot be flagged as view\n // bytes4(keccak256(\"admin()\")) == 0xf851a440\n (bool success, bytes memory returndata) = address(proxy).staticcall(hex\"f851a440\");\n require(success);\n return abi.decode(returndata, (address));\n }\n\n /**\n * @dev Changes the admin of `proxy` to `newAdmin`.\n *\n * Requirements:\n *\n * - This contract must be the current admin of `proxy`.\n */\n function changeProxyAdmin(TransparentUpgradeableProxy proxy, address newAdmin) public virtual onlyOwner {\n proxy.changeAdmin(newAdmin);\n }\n\n /**\n * @dev Upgrades `proxy` to `implementation`. See {TransparentUpgradeableProxy-upgradeTo}.\n *\n * Requirements:\n *\n * - This contract must be the admin of `proxy`.\n */\n function upgrade(TransparentUpgradeableProxy proxy, address implementation) public virtual onlyOwner {\n proxy.upgradeTo(implementation);\n }\n\n /**\n * @dev Upgrades `proxy` to `implementation` and calls a function on the new implementation. See\n * {TransparentUpgradeableProxy-upgradeToAndCall}.\n *\n * Requirements:\n *\n * - This contract must be the admin of `proxy`.\n */\n function upgradeAndCall(\n TransparentUpgradeableProxy proxy,\n address implementation,\n bytes memory data\n ) public payable virtual onlyOwner {\n proxy.upgradeToAndCall{ value: msg.value }(implementation, data);\n }\n}\n" + }, + "contracts/external/TransparentUpgradeableProxy.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\nimport \"@openzeppelin/contracts/proxy/ERC1967/ERC1967Proxy.sol\";\n\n/**\n * @dev This contract implements a proxy that is upgradeable by an admin. It is fully forked from OpenZeppelin\n * `TransparentUpgradeableProxy`\n *\n * To avoid https://medium.com/nomic-labs-blog/malicious-backdoors-in-ethereum-proxies-62629adf3357[proxy selector\n * clashing], which can potentially be used in an attack, this contract uses the\n * https://blog.openzeppelin.com/the-transparent-proxy-pattern/[transparent proxy pattern]. This pattern implies two\n * things that go hand in hand:\n *\n * 1. If any account other than the admin calls the proxy, the call will be forwarded to the implementation, even if\n * that call matches one of the admin functions exposed by the proxy itself.\n * 2. If the admin calls the proxy, it can access the admin functions, but its calls will never be forwarded to the\n * implementation. If the admin tries to call a function on the implementation it will fail with an error that says\n * \"admin cannot fallback to proxy target\".\n *\n * These properties mean that the admin account can only be used for admin actions like upgrading the proxy or changing\n * the admin, so it's best if it's a dedicated account that is not used for anything else. This will avoid headaches due\n * to sudden errors when trying to call a function from the proxy implementation.\n *\n * Our recommendation is for the dedicated account to be an instance of the {ProxyAdmin} contract. If set up this way,\n * you should think of the `ProxyAdmin` instance as the real administrative interface of your proxy.\n */\ncontract TransparentUpgradeableProxy is ERC1967Proxy {\n /**\n * @dev Initializes an upgradeable proxy managed by `_admin`, backed by the implementation at `_logic`, and\n * optionally initialized with `_data` as explained in {ERC1967Proxy-constructor}.\n */\n constructor(address _logic, address admin_, bytes memory _data) payable ERC1967Proxy(_logic, _data) {\n assert(_ADMIN_SLOT == bytes32(uint256(keccak256(\"eip1967.proxy.admin\")) - 1));\n _changeAdmin(admin_);\n }\n\n /**\n * @dev Modifier used internally that will delegate the call to the implementation unless the sender is the admin.\n */\n modifier ifAdmin() {\n if (msg.sender == _getAdmin()) {\n _;\n } else {\n _fallback();\n }\n }\n\n /**\n * @dev Returns the current admin.\n *\n * NOTE: Only the admin can call this function. See {ProxyAdmin-getProxyAdmin}.\n *\n * TIP: To get this value clients can read directly from the storage slot shown below (specified by EIP1967) using the\n * https://eth.wiki/json-rpc/API#eth_getstorageat[`eth_getStorageAt`] RPC call.\n * `0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103`\n */\n function admin() external ifAdmin returns (address admin_) {\n admin_ = _getAdmin();\n }\n\n /**\n * @dev Returns the current implementation.\n *\n * NOTE: Only the admin can call this function. See {ProxyAdmin-getProxyImplementation}.\n *\n * TIP: To get this value clients can read directly from the storage slot shown below (specified by EIP1967) using the\n * https://eth.wiki/json-rpc/API#eth_getstorageat[`eth_getStorageAt`] RPC call.\n * `0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc`\n */\n function implementation() external ifAdmin returns (address implementation_) {\n implementation_ = _implementation();\n }\n\n /**\n * @dev Changes the admin of the proxy.\n *\n * Emits an {AdminChanged} event.\n *\n * NOTE: Only the admin can call this function. See {ProxyAdmin-changeProxyAdmin}.\n */\n function changeAdmin(address newAdmin) external virtual ifAdmin {\n _changeAdmin(newAdmin);\n }\n\n /**\n * @dev Upgrade the implementation of the proxy.\n *\n * NOTE: Only the admin can call this function. See {ProxyAdmin-upgrade}.\n */\n function upgradeTo(address newImplementation) external ifAdmin {\n _upgradeToAndCall(newImplementation, bytes(\"\"), false);\n }\n\n /**\n * @dev Upgrade the implementation of the proxy, and then call a function from the new implementation as specified\n * by `data`, which should be an encoded function call. This is useful to initialize new storage variables in the\n * proxied contract.\n *\n * NOTE: Only the admin can call this function. See {ProxyAdmin-upgradeAndCall}.\n */\n function upgradeToAndCall(address newImplementation, bytes calldata data) external payable ifAdmin {\n _upgradeToAndCall(newImplementation, data, true);\n }\n\n /**\n * @dev Returns the current admin.\n */\n function _admin() internal view virtual returns (address) {\n return _getAdmin();\n }\n\n /**\n * @dev Makes sure the admin cannot access the fallback function. See {Proxy-_beforeFallback}.\n */\n function _beforeFallback() internal virtual override {\n require(msg.sender != _getAdmin(), \"TransparentUpgradeableProxy: admin cannot fallback to proxy target\");\n super._beforeFallback();\n }\n}\n" + }, + "contracts/flashloan/FlashAngle.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\nimport \"@openzeppelin/contracts-upgradeable/security/ReentrancyGuardUpgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol\";\nimport \"@openzeppelin/contracts/interfaces/IERC3156FlashBorrower.sol\";\nimport \"@openzeppelin/contracts/interfaces/IERC3156FlashLender.sol\";\nimport \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\nimport \"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\";\n\nimport \"../interfaces/IAgToken.sol\";\nimport \"../interfaces/ICoreBorrow.sol\";\nimport \"../interfaces/IFlashAngle.sol\";\nimport \"../interfaces/ITreasury.sol\";\n\n/// @title FlashAngle\n/// @author Angle Labs, Inc.\n/// @notice Contract to take flash loans on top of several AgToken contracts\ncontract FlashAngle is IERC3156FlashLender, IFlashAngle, Initializable, ReentrancyGuardUpgradeable {\n using SafeERC20 for IERC20;\n /// @notice Base used for parameter computation\n uint256 public constant BASE_PARAMS = 10 ** 9;\n /// @notice Success message received when calling a `FlashBorrower` contract\n bytes32 public constant CALLBACK_SUCCESS = keccak256(\"ERC3156FlashBorrower.onFlashLoan\");\n\n /// @notice Struct encoding for a given stablecoin the parameters\n struct StablecoinData {\n // Maximum amount borrowable for this stablecoin\n uint256 maxBorrowable;\n // Flash loan fee taken by the protocol for a flash loan on this stablecoin\n uint64 flashLoanFee;\n // Treasury address responsible of the stablecoin\n address treasury;\n }\n\n // ======================= Parameters and References ===========================\n\n /// @notice Maps a stablecoin to the data and parameters for flash loans\n mapping(IAgToken => StablecoinData) public stablecoinMap;\n /// @inheritdoc IFlashAngle\n ICoreBorrow public core;\n\n // =============================== Event =======================================\n\n event FlashLoan(address indexed stablecoin, uint256 amount, IERC3156FlashBorrower indexed receiver);\n event FlashLoanParametersUpdated(IAgToken indexed stablecoin, uint64 _flashLoanFee, uint256 _maxBorrowable);\n\n // =============================== Errors ======================================\n\n error InvalidReturnMessage();\n error NotCore();\n error NotGovernorOrGuardian();\n error NotTreasury();\n error TooBigAmount();\n error TooHighParameterValue();\n error UnsupportedStablecoin();\n error ZeroAddress();\n\n /// @notice Initializes the contract\n /// @param _core Core address handling this module\n function initialize(ICoreBorrow _core) public initializer {\n if (address(_core) == address(0)) revert ZeroAddress();\n core = _core;\n }\n\n /// @custom:oz-upgrades-unsafe-allow constructor\n constructor() initializer {}\n\n // =================================== Modifiers ===============================\n\n /// @notice Checks whether the sender is the core contract\n modifier onlyCore() {\n if (msg.sender != address(core)) revert NotCore();\n _;\n }\n\n /// @notice Checks whether a given stablecoin has been initialized in this contract\n /// @param stablecoin Stablecoin to check\n /// @dev To check whether a stablecoin has been initialized, we just need to check whether its associated\n /// `treasury` address is not null in the `stablecoinMap`. This is what's checked in the `CoreBorrow` contract\n /// when adding support for a stablecoin\n modifier onlyExistingStablecoin(IAgToken stablecoin) {\n if (stablecoinMap[stablecoin].treasury == address(0)) revert UnsupportedStablecoin();\n _;\n }\n\n // ================================ ERC3156 Spec ===============================\n\n /// @inheritdoc IERC3156FlashLender\n function flashFee(address token, uint256 amount) external view returns (uint256) {\n return _flashFee(token, amount);\n }\n\n /// @inheritdoc IERC3156FlashLender\n function maxFlashLoan(address token) external view returns (uint256) {\n // It will be 0 anyway if the token was not added\n return stablecoinMap[IAgToken(token)].maxBorrowable;\n }\n\n /// @inheritdoc IERC3156FlashLender\n function flashLoan(\n IERC3156FlashBorrower receiver,\n address token,\n uint256 amount,\n bytes calldata data\n ) external nonReentrant returns (bool) {\n uint256 fee = _flashFee(token, amount);\n if (amount > stablecoinMap[IAgToken(token)].maxBorrowable) revert TooBigAmount();\n IAgToken(token).mint(address(receiver), amount);\n if (receiver.onFlashLoan(msg.sender, token, amount, fee, data) != CALLBACK_SUCCESS)\n revert InvalidReturnMessage();\n // Token must be an agToken here so normally no need to use `safeTransferFrom`, but out of safety\n // and in case governance whitelists an agToken which does not have a correct implementation, we prefer\n // to use `safeTransferFrom` here\n IERC20(token).safeTransferFrom(address(receiver), address(this), amount + fee);\n IAgToken(token).burnSelf(amount, address(this));\n emit FlashLoan(token, amount, receiver);\n return true;\n }\n\n /// @notice Internal function to compute the fee induced for taking a flash loan of `amount` of `token`\n /// @param token The loan currency\n /// @param amount The amount of tokens lent\n /// @dev This function will revert if the `token` requested is not whitelisted here\n function _flashFee(\n address token,\n uint256 amount\n ) internal view onlyExistingStablecoin(IAgToken(token)) returns (uint256) {\n return (amount * stablecoinMap[IAgToken(token)].flashLoanFee) / BASE_PARAMS;\n }\n\n // ============================ Treasury Only Function =========================\n\n /// @inheritdoc IFlashAngle\n function accrueInterestToTreasury(IAgToken stablecoin) external returns (uint256 balance) {\n address treasury = stablecoinMap[stablecoin].treasury;\n if (msg.sender != treasury) revert NotTreasury();\n balance = stablecoin.balanceOf(address(this));\n IERC20(address(stablecoin)).safeTransfer(treasury, balance);\n }\n\n // =========================== Governance Only Function ========================\n\n /// @notice Sets the parameters for a given stablecoin\n /// @param stablecoin Stablecoin to change the parameters for\n /// @param _flashLoanFee New flash loan fee for this stablecoin\n /// @param _maxBorrowable Maximum amount that can be borrowed in a single flash loan\n /// @dev Setting a `maxBorrowable` parameter equal to 0 is a way to pause the functionality\n /// @dev Parameters can only be modified for whitelisted stablecoins\n function setFlashLoanParameters(\n IAgToken stablecoin,\n uint64 _flashLoanFee,\n uint256 _maxBorrowable\n ) external onlyExistingStablecoin(stablecoin) {\n if (!core.isGovernorOrGuardian(msg.sender)) revert NotGovernorOrGuardian();\n if (_flashLoanFee > BASE_PARAMS) revert TooHighParameterValue();\n stablecoinMap[stablecoin].flashLoanFee = _flashLoanFee;\n stablecoinMap[stablecoin].maxBorrowable = _maxBorrowable;\n emit FlashLoanParametersUpdated(stablecoin, _flashLoanFee, _maxBorrowable);\n }\n\n // =========================== CoreBorrow Only Functions =======================\n\n /// @inheritdoc IFlashAngle\n function addStablecoinSupport(address _treasury) external onlyCore {\n stablecoinMap[IAgToken(ITreasury(_treasury).stablecoin())].treasury = _treasury;\n }\n\n /// @inheritdoc IFlashAngle\n function removeStablecoinSupport(address _treasury) external onlyCore {\n delete stablecoinMap[IAgToken(ITreasury(_treasury).stablecoin())];\n }\n\n /// @inheritdoc IFlashAngle\n function setCore(address _core) external onlyCore {\n core = ICoreBorrow(_core);\n }\n}\n" + }, + "contracts/interfaces/coreModule/IAgTokenMainnet.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\n/// @title IAgTokenMainnet\n/// @author Angle Labs, Inc.\ninterface IAgTokenMainnet {\n function stableMaster() external view returns (address);\n}\n" + }, + "contracts/interfaces/coreModule/ICore.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\n/// @title ICore\n/// @author Angle Labs, Inc.\ninterface ICore {\n function stablecoinList() external view returns (address[] memory);\n}\n" + }, + "contracts/interfaces/coreModule/ILiquidityGauge.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\ninterface ILiquidityGauge {\n function deposit(\n uint256 _value,\n address _addr,\n // solhint-disable-next-line\n bool _claim_rewards\n ) external;\n\n function withdraw(\n uint256 _value,\n // solhint-disable-next-line\n bool _claim_rewards\n ) external;\n\n // solhint-disable-next-line\n function claim_rewards(address _addr, address _receiver) external;\n\n // solhint-disable-next-line\n function claimable_reward(address _addr, address _reward_token) external view returns (uint256 amount);\n}\n" + }, + "contracts/interfaces/coreModule/IOracleCore.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\n/// @title IOracleCore\n/// @author Angle Labs, Inc.\ninterface IOracleCore {\n function readUpper() external view returns (uint256);\n\n function readQuoteLower(uint256 baseAmount) external view returns (uint256);\n}\n" + }, + "contracts/interfaces/coreModule/IPerpetualManager.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\n/// @title IPerpetualManager\n/// @author Angle Labs, Inc.\ninterface IPerpetualManager {\n function totalHedgeAmount() external view returns (uint256);\n\n function maintenanceMargin() external view returns (uint64);\n\n function maxLeverage() external view returns (uint64);\n\n function targetHAHedge() external view returns (uint64);\n\n function limitHAHedge() external view returns (uint64);\n\n function lockTime() external view returns (uint64);\n\n function haBonusMalusDeposit() external view returns (uint64);\n\n function haBonusMalusWithdraw() external view returns (uint64);\n\n function xHAFeesDeposit(uint256) external view returns (uint64);\n\n function yHAFeesDeposit(uint256) external view returns (uint64);\n\n function xHAFeesWithdraw(uint256) external view returns (uint64);\n\n function yHAFeesWithdraw(uint256) external view returns (uint64);\n}\n" + }, + "contracts/interfaces/coreModule/IPoolManager.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\n/// @title IPoolManager\n/// @author Angle Labs, Inc.\ninterface IPoolManager {\n function feeManager() external view returns (address);\n\n function strategyList(uint256) external view returns (address);\n}\n" + }, + "contracts/interfaces/coreModule/IStableMaster.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\nimport \"./IPerpetualManager.sol\";\nimport \"./IOracleCore.sol\";\n\n// Struct to handle all the parameters to manage the fees\n// related to a given collateral pool (associated to the stablecoin)\nstruct MintBurnData {\n // Values of the thresholds to compute the minting fees\n // depending on HA hedge (scaled by `BASE_PARAMS`)\n uint64[] xFeeMint;\n // Values of the fees at thresholds (scaled by `BASE_PARAMS`)\n uint64[] yFeeMint;\n // Values of the thresholds to compute the burning fees\n // depending on HA hedge (scaled by `BASE_PARAMS`)\n uint64[] xFeeBurn;\n // Values of the fees at thresholds (scaled by `BASE_PARAMS`)\n uint64[] yFeeBurn;\n // Max proportion of collateral from users that can be covered by HAs\n // It is exactly the same as the parameter of the same name in `PerpetualManager`, whenever one is updated\n // the other changes accordingly\n uint64 targetHAHedge;\n // Minting fees correction set by the `FeeManager` contract: they are going to be multiplied\n // to the value of the fees computed using the hedge curve\n // Scaled by `BASE_PARAMS`\n uint64 bonusMalusMint;\n // Burning fees correction set by the `FeeManager` contract: they are going to be multiplied\n // to the value of the fees computed using the hedge curve\n // Scaled by `BASE_PARAMS`\n uint64 bonusMalusBurn;\n // Parameter used to limit the number of stablecoins that can be issued using the concerned collateral\n uint256 capOnStableMinted;\n}\n\n// Struct to handle all the variables and parameters to handle SLPs in the protocol\n// including the fraction of interests they receive or the fees to be distributed to\n// them\nstruct SLPData {\n // Last timestamp at which the `sanRate` has been updated for SLPs\n uint256 lastBlockUpdated;\n // Fees accumulated from previous blocks and to be distributed to SLPs\n uint256 lockedInterests;\n // Max interests used to update the `sanRate` in a single block\n // Should be in collateral token base\n uint256 maxInterestsDistributed;\n // Amount of fees left aside for SLPs and that will be distributed\n // when the protocol is collateralized back again\n uint256 feesAside;\n // Part of the fees normally going to SLPs that is left aside\n // before the protocol is collateralized back again (depends on collateral ratio)\n // Updated by keepers and scaled by `BASE_PARAMS`\n uint64 slippageFee;\n // Portion of the fees from users minting and burning\n // that goes to SLPs (the rest goes to surplus)\n uint64 feesForSLPs;\n // Slippage factor that's applied to SLPs exiting (depends on collateral ratio)\n // If `slippage = BASE_PARAMS`, SLPs can get nothing, if `slippage = 0` they get their full claim\n // Updated by keepers and scaled by `BASE_PARAMS`\n uint64 slippage;\n // Portion of the interests from lending\n // that goes to SLPs (the rest goes to surplus)\n uint64 interestsForSLPs;\n}\n\n/// @title IStableMaster\n/// @author Angle Labs, Inc.\ninterface IStableMaster {\n function agToken() external view returns (address);\n\n function updateStocksUsers(uint256 amount, address poolManager) external;\n\n function collateralMap(\n address poolManager\n )\n external\n view\n returns (\n address token,\n address sanToken,\n IPerpetualManager perpetualManager,\n IOracleCore oracle,\n uint256 stocksUsers,\n uint256 sanRate,\n uint256 collatBase,\n SLPData memory slpData,\n MintBurnData memory feeData\n );\n\n function paused(bytes32) external view returns (bool);\n\n function deposit(uint256 amount, address user, address poolManager) external;\n\n function withdraw(uint256 amount, address burner, address dest, address poolManager) external;\n}\n" + }, + "contracts/interfaces/external/create2/ImmutableCreate2Factory.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\ninterface ImmutableCreate2Factory {\n function safeCreate2(bytes32 salt, bytes memory initCode) external payable returns (address deploymentAddress);\n\n function findCreate2Address(\n bytes32 salt,\n bytes calldata initCode\n ) external view returns (address deploymentAddress);\n\n function findCreate2AddressViaHash(\n bytes32 salt,\n bytes32 initCodeHash\n ) external view returns (address deploymentAddress);\n}\n" + }, + "contracts/interfaces/external/IERC1271.sol": { + "content": "// SPDX-License-Identifier: GPL-2.0-or-later\npragma solidity ^0.8.12;\n\n/// @title Interface for verifying contract-based account signatures\n/// @notice Interface that verifies provided signature for the data\n/// @dev Interface defined by EIP-1271\ninterface IERC1271 {\n /// @notice Returns whether the provided signature is valid for the provided data\n /// @dev MUST return the bytes4 magic value 0x1626ba7e when function passes.\n /// MUST NOT modify state (using STATICCALL for solc < 0.5, view modifier for solc > 0.5).\n /// MUST allow external calls.\n /// @param hash Hash of the data to be signed\n /// @param signature Signature byte array associated with _data\n /// @return magicValue The bytes4 magic value 0x1626ba7e\n function isValidSignature(bytes32 hash, bytes memory signature) external view returns (bytes4 magicValue);\n}\n" + }, + "contracts/interfaces/external/IERC4626.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\npragma solidity >=0.8.0;\n\nimport \"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\";\nimport \"@openzeppelin/contracts/token/ERC20/ERC20.sol\";\n\n/// @notice Minimal IERC4646 tokenized Vault interface.\n/// @author Forked from Solmate (https://github.com/Rari-Capital/solmate/blob/main/src/mixins/ERC4626.sol)\n/// @dev Do not use in production! ERC-4626 is still in the review stage and is subject to change.\ninterface IERC4626 {\n event Deposit(address indexed from, address indexed to, uint256 amount, uint256 shares);\n event Withdraw(address indexed from, address indexed to, uint256 amount, uint256 shares);\n\n /// @notice Transfers a given amount of asset to the reactor and mint shares accordingly\n /// @param amount Given amount of asset\n /// @param to Address to mint shares to\n /// @return shares Amount of shares minted to `to`\n function deposit(uint256 amount, address to) external returns (uint256 shares);\n\n /// @notice Mints a given amount of shares to the reactor and transfer assets accordingly\n /// @param shares Given amount of shares\n /// @param to Address to mint shares to\n /// @return amount Amount of `asset` taken to the `msg.sender` to mint `shares`\n function mint(uint256 shares, address to) external returns (uint256 amount);\n\n /// @notice Transfers a given amount of asset from the reactor and burn shares accordingly\n /// @param amount Given amount of asset\n /// @param to Address to transfer assets to\n /// @param from Address to burn shares from\n /// @return shares Amount of shares burnt in the operation\n function withdraw(uint256 amount, address to, address from) external returns (uint256 shares);\n\n /// @notice Burns a given amount of shares to the reactor and transfer assets accordingly\n /// @param shares Given amount of shares\n /// @param to Address to transfer assets to\n /// @param from Address to burn shares from\n /// @return amount Amount of assets redeemed in the operation\n function redeem(uint256 shares, address to, address from) external returns (uint256 amount);\n\n /// @notice Returns the total assets managed by this reactor\n function totalAssets() external view returns (uint256);\n\n /// @notice Converts an amount of assets to the corresponding amount of reactor shares\n /// @param assets Amount of asset to convert\n /// @return Shares corresponding to the amount of assets obtained\n function convertToShares(uint256 assets) external view returns (uint256);\n\n /// @notice Converts an amount of shares to its current value in asset\n /// @param shares Amount of shares to convert\n /// @return Amount of assets corresponding to the amount of assets given\n function convertToAssets(uint256 shares) external view returns (uint256);\n\n /// @notice Computes how many shares one would get by depositing `assets`\n /// @param assets Amount of asset to convert\n function previewDeposit(uint256 assets) external view returns (uint256);\n\n /// @notice Computes how many assets one would need to mint `shares`\n /// @param shares Amount of shares required\n function previewMint(uint256 shares) external view returns (uint256);\n\n /// @notice Computes how many shares one would need to withdraw assets\n /// @param assets Amount of asset to withdraw\n function previewWithdraw(uint256 assets) external view returns (uint256);\n\n /// @notice Computes how many assets one would get by burning shares\n /// @param shares Amount of shares to burn\n function previewRedeem(uint256 shares) external view returns (uint256);\n\n /// @notice Max deposit allowed for a user\n /// @param user Address of the user to check\n function maxDeposit(address user) external returns (uint256);\n\n /// @notice Max mint allowed for a user\n /// @param user Address of the user to check\n function maxMint(address user) external returns (uint256);\n\n /// @notice Max withdraw allowed for a user\n /// @param user Address of the user to check\n function maxWithdraw(address user) external returns (uint256);\n\n /// @notice Max redeem allowed for a user\n /// @param user Address of the user to check\n function maxRedeem(address user) external returns (uint256);\n}\n" + }, + "contracts/interfaces/external/IWETH9.sol": { + "content": "// SPDX-License-Identifier: GPL-2.0-or-later\npragma solidity ^0.8.12;\n\nimport \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\n\n/// @title Interface for WETH9\ninterface IWETH9 is IERC20 {\n /// @notice Deposit ether to get wrapped ether\n function deposit() external payable;\n\n /// @notice Withdraw wrapped ether to get ether\n function withdraw(uint256) external;\n}\n" + }, + "contracts/interfaces/external/layerZero/ILayerZeroEndpoint.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity >=0.5.0;\n\nimport \"./ILayerZeroUserApplicationConfig.sol\";\n\ninterface ILayerZeroEndpoint is ILayerZeroUserApplicationConfig {\n // @notice send a LayerZero message to the specified address at a LayerZero endpoint.\n // @param _dstChainId - the destination chain identifier\n // @param _destination - the address on destination chain (in bytes). address length/format may vary by chains\n // @param _payload - a custom bytes payload to send to the destination contract\n // @param _refundAddress - if the source transaction is cheaper than the amount of value passed, refund the additional amount to this address\n // @param _zroPaymentAddress - the address of the ZRO token holder who would pay for the transaction\n // @param _adapterParams - parameters for custom functionality. e.g. receive airdropped native gas from the relayer on destination\n function send(\n uint16 _dstChainId,\n bytes calldata _destination,\n bytes calldata _payload,\n address payable _refundAddress,\n address _zroPaymentAddress,\n bytes calldata _adapterParams\n ) external payable;\n\n // @notice used by the messaging library to publish verified payload\n // @param _srcChainId - the source chain identifier\n // @param _srcAddress - the source contract (as bytes) at the source chain\n // @param _dstAddress - the address on destination chain\n // @param _nonce - the unbound message ordering nonce\n // @param _gasLimit - the gas limit for external contract execution\n // @param _payload - verified payload to send to the destination contract\n function receivePayload(\n uint16 _srcChainId,\n bytes calldata _srcAddress,\n address _dstAddress,\n uint64 _nonce,\n uint256 _gasLimit,\n bytes calldata _payload\n ) external;\n\n // @notice get the inboundNonce of a lzApp from a source chain which could be EVM or non-EVM chain\n // @param _srcChainId - the source chain identifier\n // @param _srcAddress - the source chain contract address\n function getInboundNonce(uint16 _srcChainId, bytes calldata _srcAddress) external view returns (uint64);\n\n // @notice get the outboundNonce from this source chain which, consequently, is always an EVM\n // @param _srcAddress - the source chain contract address\n function getOutboundNonce(uint16 _dstChainId, address _srcAddress) external view returns (uint64);\n\n // @notice gets a quote in source native gas, for the amount that send() requires to pay for message delivery\n // @param _dstChainId - the destination chain identifier\n // @param _userApplication - the user app address on this EVM chain\n // @param _payload - the custom message to send over LayerZero\n // @param _payInZRO - if false, user app pays the protocol fee in native token\n // @param _adapterParam - parameters for the adapter service, e.g. send some dust native token to dstChain\n function estimateFees(\n uint16 _dstChainId,\n address _userApplication,\n bytes calldata _payload,\n bool _payInZRO,\n bytes calldata _adapterParam\n ) external view returns (uint256 nativeFee, uint256 zroFee);\n\n // @notice get this Endpoint's immutable source identifier\n function getChainId() external view returns (uint16);\n\n // @notice the interface to retry failed message on this Endpoint destination\n // @param _srcChainId - the source chain identifier\n // @param _srcAddress - the source chain contract address\n // @param _payload - the payload to be retried\n function retryPayload(uint16 _srcChainId, bytes calldata _srcAddress, bytes calldata _payload) external;\n\n // @notice query if any STORED payload (message blocking) at the endpoint.\n // @param _srcChainId - the source chain identifier\n // @param _srcAddress - the source chain contract address\n function hasStoredPayload(uint16 _srcChainId, bytes calldata _srcAddress) external view returns (bool);\n\n // @notice query if the _libraryAddress is valid for sending msgs.\n // @param _userApplication - the user app address on this EVM chain\n function getSendLibraryAddress(address _userApplication) external view returns (address);\n\n // @notice query if the _libraryAddress is valid for receiving msgs.\n // @param _userApplication - the user app address on this EVM chain\n function getReceiveLibraryAddress(address _userApplication) external view returns (address);\n\n // @notice query if the non-reentrancy guard for send() is on\n // @return true if the guard is on. false otherwise\n function isSendingPayload() external view returns (bool);\n\n // @notice query if the non-reentrancy guard for receive() is on\n // @return true if the guard is on. false otherwise\n function isReceivingPayload() external view returns (bool);\n\n // @notice get the configuration of the LayerZero messaging library of the specified version\n // @param _version - messaging library version\n // @param _chainId - the chainId for the pending config change\n // @param _userApplication - the contract address of the user application\n // @param _configType - type of configuration. every messaging library has its own convention.\n function getConfig(\n uint16 _version,\n uint16 _chainId,\n address _userApplication,\n uint256 _configType\n ) external view returns (bytes memory);\n\n // @notice get the send() LayerZero messaging library version\n // @param _userApplication - the contract address of the user application\n function getSendVersion(address _userApplication) external view returns (uint16);\n\n // @notice get the lzReceive() LayerZero messaging library version\n // @param _userApplication - the contract address of the user application\n function getReceiveVersion(address _userApplication) external view returns (uint16);\n}\n" + }, + "contracts/interfaces/external/layerZero/ILayerZeroReceiver.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity >=0.5.0;\n\ninterface ILayerZeroReceiver {\n // @notice LayerZero endpoint will invoke this function to deliver the message on the destination\n // @param _srcChainId - the source endpoint identifier\n // @param _srcAddress - the source sending contract address from the source chain\n // @param _nonce - the ordered message nonce\n // @param _payload - the signed payload is the UA bytes has encoded to be sent\n function lzReceive(uint16 _srcChainId, bytes calldata _srcAddress, uint64 _nonce, bytes calldata _payload) external;\n}\n" + }, + "contracts/interfaces/external/layerZero/ILayerZeroUserApplicationConfig.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity >=0.5.0;\n\ninterface ILayerZeroUserApplicationConfig {\n // @notice set the configuration of the LayerZero messaging library of the specified version\n // @param _version - messaging library version\n // @param _chainId - the chainId for the pending config change\n // @param _configType - type of configuration. every messaging library has its own convention.\n // @param _config - configuration in the bytes. can encode arbitrary content.\n function setConfig(uint16 _version, uint16 _chainId, uint256 _configType, bytes calldata _config) external;\n\n // @notice set the send() LayerZero messaging library version to _version\n // @param _version - new messaging library version\n function setSendVersion(uint16 _version) external;\n\n // @notice set the lzReceive() LayerZero messaging library version to _version\n // @param _version - new messaging library version\n function setReceiveVersion(uint16 _version) external;\n\n // @notice Only when the UA needs to resume the message flow in blocking mode and clear the stored payload\n // @param _srcChainId - the chainId of the source chain\n // @param _srcAddress - the contract address of the source contract at the source chain\n function forceResumeReceive(uint16 _srcChainId, bytes calldata _srcAddress) external;\n}\n" + }, + "contracts/interfaces/external/lido/IStETH.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\n/// @title IStETH\n/// @author Angle Labs, Inc.\n/// @notice Interface for the `StETH` contract\n/// @dev This interface only contains functions of the `StETH` which are called by other contracts\n/// of this module\ninterface IStETH {\n function getPooledEthByShares(uint256 _sharesAmount) external view returns (uint256);\n\n event Submitted(address sender, uint256 amount, address referral);\n\n function submit(address) external payable returns (uint256);\n\n function getSharesByPooledEth(uint256 _ethAmount) external view returns (uint256);\n}\n" + }, + "contracts/interfaces/external/lido/IWStETH.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\n/// @title IWStETH\n/// @author Angle Labs, Inc.\n/// @notice Interface for the `WStETH` contract\n/// @dev This interface only contains functions of the `WStETH` which are called by other contracts\n/// of this module\ninterface IWStETH {\n function wrap(uint256 _stETHAmount) external returns (uint256);\n\n function stETH() external view returns (address);\n}\n" + }, + "contracts/interfaces/external/uniswap/IUniswapRouter.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\nstruct ExactInputParams {\n bytes path;\n address recipient;\n uint256 deadline;\n uint256 amountIn;\n uint256 amountOutMinimum;\n}\n\n/// @title Router token swapping functionality\n/// @notice Functions for swapping tokens via Uniswap V3\ninterface IUniswapV3Router {\n /// @notice Swaps `amountIn` of one token for as much as possible of another along the specified path\n /// @param params The parameters necessary for the multi-hop swap, encoded as `ExactInputParams` in calldata\n /// @return amountOut The amount of the received token\n function exactInput(ExactInputParams calldata params) external payable returns (uint256 amountOut);\n}\n\n/// @title Router for price estimation functionality\n/// @notice Functions for getting the price of one token with respect to another using Uniswap V2\n/// @dev This interface is only used for non critical elements of the protocol\ninterface IUniswapV2Router {\n /// @notice Given an input asset amount, returns the maximum output amount of the\n /// other asset (accounting for fees) given reserves.\n /// @param path Addresses of the pools used to get prices\n function getAmountsOut(uint256 amountIn, address[] calldata path) external view returns (uint256[] memory amounts);\n\n function swapExactTokensForTokens(\n uint256 swapAmount,\n uint256 minExpected,\n address[] calldata path,\n address receiver,\n uint256 swapDeadline\n ) external;\n}\n" + }, + "contracts/interfaces/external/uniswap/IUniswapV3Pool.sol": { + "content": "// SPDX-License-Identifier: GPL-2.0-or-later\npragma solidity >=0.5.0;\n\n/// @title Pool state that never changes\n/// @notice These parameters are fixed for a pool forever, i.e., the methods will always return the same values\ninterface IUniswapV3Pool {\n /// @notice The first of the two tokens of the pool, sorted by address\n /// @return The token contract address\n function token0() external view returns (address);\n\n /// @notice The second of the two tokens of the pool, sorted by address\n /// @return The token contract address\n function token1() external view returns (address);\n}\n" + }, + "contracts/interfaces/governance/IVeBoostProxy.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\n/// @title IVeBoostProxy\n/// @author Angle Labs, Inc.\n/// @notice Interface for the `VeBoostProxy` contract\n/// @dev This interface only contains functions of the contract which are called by other contracts\n/// of this module\n/// @dev The `veBoostProxy` contract used by Angle is a full fork of Curve Finance implementation\ninterface IVeBoostProxy {\n /// @notice Reads the adjusted veANGLE balance of an address (adjusted by delegation)\n //solhint-disable-next-line\n function adjusted_balance_of(address) external view returns (uint256);\n}\n" + }, + "contracts/interfaces/IAgToken.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\nimport \"@openzeppelin/contracts-upgradeable/token/ERC20/IERC20Upgradeable.sol\";\n\n/// @title IAgToken\n/// @author Angle Labs, Inc.\n/// @notice Interface for the stablecoins `AgToken` contracts\n/// @dev This interface only contains functions of the `AgToken` contract which are called by other contracts\n/// of this module or of the first module of the Angle Protocol\ninterface IAgToken is IERC20Upgradeable {\n // ======================= Minter Role Only Functions ===========================\n\n /// @notice Lets the `StableMaster` contract or another whitelisted contract mint agTokens\n /// @param account Address to mint to\n /// @param amount Amount to mint\n /// @dev The contracts allowed to issue agTokens are the `StableMaster` contract, `VaultManager` contracts\n /// associated to this stablecoin as well as the flash loan module (if activated) and potentially contracts\n /// whitelisted by governance\n function mint(address account, uint256 amount) external;\n\n /// @notice Burns `amount` tokens from a `burner` address after being asked to by `sender`\n /// @param amount Amount of tokens to burn\n /// @param burner Address to burn from\n /// @param sender Address which requested the burn from `burner`\n /// @dev This method is to be called by a contract with the minter right after being requested\n /// to do so by a `sender` address willing to burn tokens from another `burner` address\n /// @dev The method checks the allowance between the `sender` and the `burner`\n function burnFrom(uint256 amount, address burner, address sender) external;\n\n /// @notice Burns `amount` tokens from a `burner` address\n /// @param amount Amount of tokens to burn\n /// @param burner Address to burn from\n /// @dev This method is to be called by a contract with a minter right on the AgToken after being\n /// requested to do so by an address willing to burn tokens from its address\n function burnSelf(uint256 amount, address burner) external;\n\n // ========================= Treasury Only Functions ===========================\n\n /// @notice Adds a minter in the contract\n /// @param minter Minter address to add\n /// @dev Zero address checks are performed directly in the `Treasury` contract\n function addMinter(address minter) external;\n\n /// @notice Removes a minter from the contract\n /// @param minter Minter address to remove\n /// @dev This function can also be called by a minter wishing to revoke itself\n function removeMinter(address minter) external;\n\n /// @notice Sets a new treasury contract\n /// @param _treasury New treasury address\n function setTreasury(address _treasury) external;\n\n // ========================= External functions ================================\n\n /// @notice Checks whether an address has the right to mint agTokens\n /// @param minter Address for which the minting right should be checked\n /// @return Whether the address has the right to mint agTokens or not\n function isMinter(address minter) external view returns (bool);\n\n /// @notice Get the associated treasury\n function treasury() external view returns (address);\n}\n" + }, + "contracts/interfaces/IAgTokenSideChainMultiBridge.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\nimport \"@openzeppelin/contracts-upgradeable/token/ERC20/extensions/draft-IERC20PermitUpgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/token/ERC20/IERC20Upgradeable.sol\";\n\n/// @title IAgTokenSideChainMultiBridge\n/// @author Angle Labs, Inc.\n/// @notice Interface for the canonical `AgToken` contracts\n/// @dev This interface only contains functions useful for bridge tokens to interact with the canonical token\ninterface IAgTokenSideChainMultiBridge is IERC20PermitUpgradeable, IERC20Upgradeable {\n /// @notice Mints the canonical token from a supported bridge token\n /// @param bridgeToken Bridge token to use to mint\n /// @param amount Amount of bridge tokens to send\n /// @param to Address to which the stablecoin should be sent\n /// @return Amount of the canonical stablecoin actually minted\n /// @dev Some fees may be taken by the protocol depending on the token used and on the address calling\n function swapIn(address bridgeToken, uint256 amount, address to) external returns (uint256);\n\n /// @notice Burns the canonical token in exchange for a bridge token\n /// @param bridgeToken Bridge token required\n /// @param amount Amount of canonical tokens to burn\n /// @param to Address to which the bridge token should be sent\n /// @return Amount of bridge tokens actually sent back\n /// @dev Some fees may be taken by the protocol depending on the token used and on the address calling\n function swapOut(address bridgeToken, uint256 amount, address to) external returns (uint256);\n}\n" + }, + "contracts/interfaces/IAngleRouter.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\n/// @title IAngleRouter\n/// @author Angle Labs, Inc.\n/// @notice Interface for the `AngleRouter` contract\n/// @dev This interface only contains functions of the `AngleRouter01` contract which are called by other contracts\n/// of this module\ninterface IAngleRouter {\n function mint(\n address user,\n uint256 amount,\n uint256 minStableAmount,\n address stablecoin,\n address collateral\n ) external;\n\n function burn(address user, uint256 amount, uint256 minAmountOut, address stablecoin, address collateral) external;\n\n function mapPoolManagers(\n address stableMaster,\n address collateral\n ) external view returns (address poolManager, address perpetualManager, address sanToken, address gauge);\n}\n" + }, + "contracts/interfaces/IAngleRouterSidechain.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\n/// @notice Action types\nenum ActionType {\n transfer,\n wrap,\n wrapNative,\n sweep,\n sweepNative,\n unwrap,\n unwrapNative,\n swapIn,\n swapOut,\n uniswapV3,\n oneInch,\n claimRewards,\n gaugeDeposit,\n borrower\n}\n\n/// @notice Data needed to get permits\nstruct PermitType {\n address token;\n address owner;\n uint256 value;\n uint256 deadline;\n uint8 v;\n bytes32 r;\n bytes32 s;\n}\n\n/// @title IAngleRouterSidechain\n/// @author Angle Labs, Inc.\n/// @notice Interface for the `AngleRouter` contract on other chains\ninterface IAngleRouterSidechain {\n function mixer(PermitType[] memory paramsPermit, ActionType[] memory actions, bytes[] calldata data) external;\n}\n" + }, + "contracts/interfaces/ICoreBorrow.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\n/// @title ICoreBorrow\n/// @author Angle Labs, Inc.\n/// @notice Interface for the `CoreBorrow` contract\n/// @dev This interface only contains functions of the `CoreBorrow` contract which are called by other contracts\n/// of this module\ninterface ICoreBorrow {\n /// @notice Checks if an address corresponds to a treasury of a stablecoin with a flash loan\n /// module initialized on it\n /// @param treasury Address to check\n /// @return Whether the address has the `FLASHLOANER_TREASURY_ROLE` or not\n function isFlashLoanerTreasury(address treasury) external view returns (bool);\n\n /// @notice Checks whether an address is governor of the Angle Protocol or not\n /// @param admin Address to check\n /// @return Whether the address has the `GOVERNOR_ROLE` or not\n function isGovernor(address admin) external view returns (bool);\n\n /// @notice Checks whether an address is governor or a guardian of the Angle Protocol or not\n /// @param admin Address to check\n /// @return Whether the address has the `GUARDIAN_ROLE` or not\n /// @dev Governance should make sure when adding a governor to also give this governor the guardian\n /// role by calling the `addGovernor` function\n function isGovernorOrGuardian(address admin) external view returns (bool);\n}\n" + }, + "contracts/interfaces/IFlashAngle.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\nimport \"./IAgToken.sol\";\nimport \"./ICoreBorrow.sol\";\n\n/// @title IFlashAngle\n/// @author Angle Labs, Inc.\n/// @notice Interface for the `FlashAngle` contract\n/// @dev This interface only contains functions of the contract which are called by other contracts\n/// of this module\ninterface IFlashAngle {\n /// @notice Reference to the `CoreBorrow` contract managing the FlashLoan module\n function core() external view returns (ICoreBorrow);\n\n /// @notice Sends the fees taken from flash loans to the treasury contract associated to the stablecoin\n /// @param stablecoin Stablecoin from which profits should be sent\n /// @return balance Amount of profits sent\n /// @dev This function can only be called by the treasury contract\n function accrueInterestToTreasury(IAgToken stablecoin) external returns (uint256 balance);\n\n /// @notice Adds support for a stablecoin\n /// @param _treasury Treasury associated to the stablecoin to add support for\n /// @dev This function can only be called by the `CoreBorrow` contract\n function addStablecoinSupport(address _treasury) external;\n\n /// @notice Removes support for a stablecoin\n /// @param _treasury Treasury associated to the stablecoin to remove support for\n /// @dev This function can only be called by the `CoreBorrow` contract\n function removeStablecoinSupport(address _treasury) external;\n\n /// @notice Sets a new core contract\n /// @param _core Core contract address to set\n /// @dev This function can only be called by the `CoreBorrow` contract\n function setCore(address _core) external;\n}\n" + }, + "contracts/interfaces/IKeeperRegistry.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\nimport \"@openzeppelin/contracts-upgradeable/token/ERC20/IERC20Upgradeable.sol\";\n\n/// @title IKeeperRegistry\n/// @author Angle Labs, Inc.\ninterface IKeeperRegistry {\n /// @notice Checks whether an address is whitelisted during oracle updates\n /// @param caller Address for which the whitelist should be checked\n /// @return Whether the address is trusted or not\n function isTrusted(address caller) external view returns (bool);\n}\n" + }, + "contracts/interfaces/ILiquidityGauge.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.7;\n\ninterface ILiquidityGauge {\n function deposit(\n uint256 _value,\n address _addr,\n // solhint-disable-next-line\n bool _claim_rewards\n ) external;\n\n function withdraw(\n uint256 _value,\n // solhint-disable-next-line\n bool _claim_rewards\n ) external;\n\n // solhint-disable-next-line\n function claim_rewards(address _addr, address _receiver) external;\n\n // solhint-disable-next-line\n function claimable_reward(address _addr, address _reward_token) external view returns (uint256 amount);\n\n /// @dev Only for testing purposes\n // solhint-disable-next-line\n function deposit_reward_token(address _rewardToken, uint256 _amount) external;\n}\n" + }, + "contracts/interfaces/IOracle.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\nimport \"./ITreasury.sol\";\nimport \"@chainlink/contracts/src/v0.8/interfaces/AggregatorV3Interface.sol\";\n\n/// @title IOracle\n/// @author Angle Labs, Inc.\n/// @notice Interface for the `Oracle` contract\n/// @dev This interface only contains functions of the contract which are called by other contracts\n/// of this module\ninterface IOracle {\n /// @notice Reads the rate from the Chainlink circuit and other data provided\n /// @return quoteAmount The current rate between the in-currency and out-currency in the base\n /// of the out currency\n /// @dev For instance if the out currency is EUR (and hence agEUR), then the base of the returned\n /// value is 10**18\n function read() external view returns (uint256);\n\n /// @notice Changes the treasury contract\n /// @param _treasury Address of the new treasury contract\n /// @dev This function can be called by an approved `VaultManager` contract which can call\n /// this function after being requested to do so by a `treasury` contract\n /// @dev In some situations (like reactor contracts), the `VaultManager` may not directly be linked\n /// to the `oracle` contract and as such we may need governors to be able to call this function as well\n function setTreasury(address _treasury) external;\n\n /// @notice Reference to the `treasury` contract handling this `VaultManager`\n function treasury() external view returns (ITreasury treasury);\n\n /// @notice Array with the list of Chainlink feeds in the order in which they are read\n function circuitChainlink() external view returns (AggregatorV3Interface[] memory);\n}\n" + }, + "contracts/interfaces/ISwapper.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\nimport \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\n\n/// @title ISwapper\n/// @author Angle Labs, Inc.\n/// @notice Interface for Swapper contracts\n/// @dev This interface defines the key functions `Swapper` contracts should have when interacting with\n/// Angle\ninterface ISwapper {\n /// @notice Notifies a contract that an address should be given `outToken` from `inToken`\n /// @param inToken Address of the token received\n /// @param outToken Address of the token to obtain\n /// @param outTokenRecipient Address to which the outToken should be sent\n /// @param outTokenOwed Minimum amount of outToken the `outTokenRecipient` address should have at the end of the call\n /// @param inTokenObtained Amount of collateral obtained by a related address prior\n /// to the call to this function\n /// @param data Extra data needed (to encode Uniswap swaps for instance)\n function swap(\n IERC20 inToken,\n IERC20 outToken,\n address outTokenRecipient,\n uint256 outTokenOwed,\n uint256 inTokenObtained,\n bytes calldata data\n ) external;\n}\n" + }, + "contracts/interfaces/ITreasury.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\nimport \"./IAgToken.sol\";\nimport \"./ICoreBorrow.sol\";\nimport \"./IFlashAngle.sol\";\n\n/// @title ITreasury\n/// @author Angle Labs, Inc.\n/// @notice Interface for the `Treasury` contract\n/// @dev This interface only contains functions of the `Treasury` which are called by other contracts\n/// of this module\ninterface ITreasury {\n /// @notice Stablecoin handled by this `treasury` contract\n function stablecoin() external view returns (IAgToken);\n\n /// @notice Checks whether a given address has the governor role\n /// @param admin Address to check\n /// @return Whether the address has the governor role\n /// @dev Access control is only kept in the `CoreBorrow` contract\n function isGovernor(address admin) external view returns (bool);\n\n /// @notice Checks whether a given address has the guardian or the governor role\n /// @param admin Address to check\n /// @return Whether the address has the guardian or the governor role\n /// @dev Access control is only kept in the `CoreBorrow` contract which means that this function\n /// queries the `CoreBorrow` contract\n function isGovernorOrGuardian(address admin) external view returns (bool);\n\n /// @notice Checks whether a given address has well been initialized in this contract\n /// as a `VaultManager`\n /// @param _vaultManager Address to check\n /// @return Whether the address has been initialized or not\n function isVaultManager(address _vaultManager) external view returns (bool);\n\n /// @notice Sets a new flash loan module for this stablecoin\n /// @param _flashLoanModule Reference to the new flash loan module\n /// @dev This function removes the minting right to the old flash loan module and grants\n /// it to the new module\n function setFlashLoanModule(address _flashLoanModule) external;\n\n /// @notice Gets the vault manager list\n function vaultManagerList(uint256 i) external returns (address);\n}\n" + }, + "contracts/interfaces/IVaultManager.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\nimport \"@openzeppelin/contracts/interfaces/IERC721Metadata.sol\";\nimport \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\nimport \"./ITreasury.sol\";\nimport \"./IOracle.sol\";\n\n// ========================= Key Structs and Enums =============================\n\n/// @notice Parameters associated to a given `VaultManager` contract: these all correspond\n/// to parameters which signification is detailed in the `VaultManagerStorage` file\nstruct VaultParameters {\n uint256 debtCeiling;\n uint64 collateralFactor;\n uint64 targetHealthFactor;\n uint64 interestRate;\n uint64 liquidationSurcharge;\n uint64 maxLiquidationDiscount;\n bool whitelistingActivated;\n uint256 baseBoost;\n}\n\n/// @notice Data stored to track someone's loan (or equivalently called position)\nstruct Vault {\n // Amount of collateral deposited in the vault, in collateral decimals. For example, if the collateral\n // is USDC with 6 decimals, then `collateralAmount` will be in base 10**6\n uint256 collateralAmount;\n // Normalized value of the debt (that is to say of the stablecoins borrowed). It is expressed\n // in the base of Angle stablecoins (i.e. `BASE_TOKENS = 10**18`)\n uint256 normalizedDebt;\n}\n\n/// @notice For a given `vaultID`, this encodes a liquidation opportunity that is to say details about the maximum\n/// amount that could be repaid by liquidating the position\n/// @dev All the values are null in the case of a vault which cannot be liquidated under these conditions\nstruct LiquidationOpportunity {\n // Maximum stablecoin amount that can be repaid upon liquidating the vault\n uint256 maxStablecoinAmountToRepay;\n // Collateral amount given to the person in the case where the maximum amount to repay is given\n uint256 maxCollateralAmountGiven;\n // Threshold value of stablecoin amount to repay: it is ok for a liquidator to repay below threshold,\n // but if this threshold is non null and the liquidator wants to repay more than threshold, it should repay\n // the max stablecoin amount given in this vault\n uint256 thresholdRepayAmount;\n // Discount proposed to the liquidator on the collateral\n uint256 discount;\n // Amount of debt in the vault\n uint256 currentDebt;\n}\n\n/// @notice Data stored during a liquidation process to keep in memory what's due to a liquidator and some\n/// essential data for vaults being liquidated\nstruct LiquidatorData {\n // Current amount of stablecoins the liquidator should give to the contract\n uint256 stablecoinAmountToReceive;\n // Current amount of collateral the contract should give to the liquidator\n uint256 collateralAmountToGive;\n // Bad debt accrued across the liquidation process\n uint256 badDebtFromLiquidation;\n // Oracle value (in stablecoin base) at the time of the liquidation\n uint256 oracleValue;\n // Value of the `interestAccumulator` at the time of the call\n uint256 newInterestAccumulator;\n}\n\n/// @notice Data to track during a series of action the amount to give or receive in stablecoins and collateral\n/// to the caller or associated addresses\nstruct PaymentData {\n // Stablecoin amount the contract should give\n uint256 stablecoinAmountToGive;\n // Stablecoin amount owed to the contract\n uint256 stablecoinAmountToReceive;\n // Collateral amount the contract should give\n uint256 collateralAmountToGive;\n // Collateral amount owed to the contract\n uint256 collateralAmountToReceive;\n}\n\n/// @notice Actions possible when composing calls to the different entry functions proposed\nenum ActionType {\n createVault,\n closeVault,\n addCollateral,\n removeCollateral,\n repayDebt,\n borrow,\n getDebtIn,\n permit\n}\n\n// ========================= Interfaces =============================\n\n/// @title IVaultManagerFunctions\n/// @author Angle Labs, Inc.\n/// @notice Interface for the `VaultManager` contract\n/// @dev This interface only contains functions of the contract which are called by other contracts\n/// of this module (without getters)\ninterface IVaultManagerFunctions {\n /// @notice Accrues interest accumulated across all vaults to the surplus and sends the surplus to the treasury\n /// @return surplusValue Value of the surplus communicated to the `Treasury`\n /// @return badDebtValue Value of the bad debt communicated to the `Treasury`\n /// @dev `surplus` and `badDebt` should be reset to 0 once their current value have been given to the `treasury` contract\n function accrueInterestToTreasury() external returns (uint256 surplusValue, uint256 badDebtValue);\n\n /// @notice Removes debt from a vault after being requested to do so by another `VaultManager` contract\n /// @param vaultID ID of the vault to remove debt from\n /// @param amountStablecoins Amount of stablecoins to remove from the debt: this amount is to be converted to an\n /// internal debt amount\n /// @param senderBorrowFee Borrowing fees from the contract which requested this: this is to make sure that people are not\n /// arbitraging difference in minting fees\n /// @param senderRepayFee Repay fees from the contract which requested this: this is to make sure that people are not arbitraging\n /// differences in repay fees\n /// @dev This function can only be called from a vaultManager registered in the same Treasury\n function getDebtOut(\n uint256 vaultID,\n uint256 amountStablecoins,\n uint256 senderBorrowFee,\n uint256 senderRepayFee\n ) external;\n\n /// @notice Gets the current debt of a vault\n /// @param vaultID ID of the vault to check\n /// @return Debt of the vault\n function getVaultDebt(uint256 vaultID) external view returns (uint256);\n\n /// @notice Gets the total debt across all vaults\n /// @return Total debt across all vaults, taking into account the interest accumulated\n /// over time\n function getTotalDebt() external view returns (uint256);\n\n /// @notice Sets the treasury contract\n /// @param _treasury New treasury contract\n /// @dev All required checks when setting up a treasury contract are performed in the contract\n /// calling this function\n function setTreasury(address _treasury) external;\n\n /// @notice Creates a vault\n /// @param toVault Address for which the va\n /// @return vaultID ID of the vault created\n /// @dev This function just creates the vault without doing any collateral or\n function createVault(address toVault) external returns (uint256);\n\n /// @notice Allows composability between calls to the different entry points of this module. Any user calling\n /// this function can perform any of the allowed actions in the order of their choice\n /// @param actions Set of actions to perform\n /// @param datas Data to be decoded for each action: it can include like the `vaultID` or the `stablecoinAmount` to borrow\n /// @param from Address from which stablecoins will be taken if one action includes burning stablecoins. This address\n /// should either be the `msg.sender` or be approved by the latter\n /// @param to Address to which stablecoins and/or collateral will be sent in case of\n /// @param who Address of the contract to handle in case of repayment of stablecoins from received collateral\n /// @param repayData Data to pass to the repayment contract in case of\n /// @return paymentData Struct containing the accounting changes from the protocol's perspective (like how much of collateral\n /// or how much has been received). Note that the values in the struct are not aggregated and you could have in the output\n /// a positive amount of stablecoins to receive as well as a positive amount of stablecoins to give\n /// @dev This function is optimized to reduce gas cost due to payment from or to the user and that expensive calls\n /// or computations (like `oracleValue`) are done only once\n /// @dev When specifying `vaultID` in `data`, it is important to know that if you specify `vaultID = 0`, it will simply\n /// use the latest `vaultID`. This is the default behavior, and unless you're engaging into some complex protocol actions\n /// it is encouraged to use `vaultID = 0` only when the first action of the batch is `createVault`\n function angle(\n ActionType[] memory actions,\n bytes[] memory datas,\n address from,\n address to,\n address who,\n bytes memory repayData\n ) external returns (PaymentData memory paymentData);\n\n /// @notice This function is a wrapper built on top of the function above. It enables users to interact with the contract\n /// without having to provide `who` and `repayData` parameters\n function angle(\n ActionType[] memory actions,\n bytes[] memory datas,\n address from,\n address to\n ) external returns (PaymentData memory paymentData);\n\n /// @notice Initializes the `VaultManager` contract\n /// @param _treasury Treasury address handling the contract\n /// @param _collateral Collateral supported by this contract\n /// @param _oracle Oracle contract used\n /// @param _symbol Symbol used to define the `VaultManager` name and symbol\n /// @dev The parameters and the oracle are the only elements which could be modified once the\n /// contract has been initialized\n /// @dev For the contract to be fully initialized, governance needs to set the parameters for the liquidation\n /// boost\n function initialize(\n ITreasury _treasury,\n IERC20 _collateral,\n IOracle _oracle,\n VaultParameters calldata params,\n string memory _symbol\n ) external;\n\n /// @notice Minimum amount of debt a vault can have, expressed in `BASE_TOKENS` that is to say the base of the agTokens\n function dust() external view returns (uint256);\n\n /// @notice Pauses external permissionless functions of the contract\n function togglePause() external;\n}\n\n/// @title IVaultManagerStorage\n/// @author Angle Labs, Inc.\n/// @notice Interface for the `VaultManager` contract\n/// @dev This interface contains getters of the contract's public variables used by other contracts\n/// of this module\ninterface IVaultManagerStorage {\n /// @notice Encodes the maximum ratio stablecoin/collateral a vault can have before being liquidated. It's what\n /// determines the minimum collateral ratio of a position\n function collateralFactor() external view returns (uint64);\n\n /// @notice Stablecoin handled by this contract. Another `VaultManager` contract could have\n /// the same rights as this `VaultManager` on the stablecoin contract\n function stablecoin() external view returns (IAgToken);\n\n /// @notice Reference to the `treasury` contract handling this `VaultManager`\n function treasury() external view returns (ITreasury);\n\n /// @notice Oracle contract to get access to the price of the collateral with respect to the stablecoin\n function oracle() external view returns (IOracle);\n\n /// @notice The `interestAccumulator` variable keeps track of the interest that should accrue to the protocol.\n /// The stored value is not necessarily the true value: this one is recomputed every time an action takes place\n /// within the protocol. It is in base `BASE_INTEREST`\n function interestAccumulator() external view returns (uint256);\n\n /// @notice Reference to the collateral handled by this `VaultManager`\n function collateral() external view returns (IERC20);\n\n /// @notice Total normalized amount of stablecoins borrowed, not taking into account the potential bad debt accumulated\n /// This value is expressed in the base of Angle stablecoins (`BASE_TOKENS = 10**18`)\n function totalNormalizedDebt() external view returns (uint256);\n\n /// @notice Maximum amount of stablecoins that can be issued with this contract. It is expressed in `BASE_TOKENS`\n function debtCeiling() external view returns (uint256);\n\n /// @notice Maps a `vaultID` to its data (namely collateral amount and normalized debt)\n function vaultData(uint256 vaultID) external view returns (uint256 collateralAmount, uint256 normalizedDebt);\n\n /// @notice ID of the last vault created. The `vaultIDCount` variables serves as a counter to generate a unique\n /// `vaultID` for each vault: it is like `tokenID` in basic ERC721 contracts\n function vaultIDCount() external view returns (uint256);\n}\n\n/// @title IVaultManager\n/// @author Angle Labs, Inc.\n/// @notice Interface for the `VaultManager` contract\ninterface IVaultManager is IVaultManagerFunctions, IVaultManagerStorage, IERC721Metadata {\n function isApprovedOrOwner(address spender, uint256 vaultID) external view returns (bool);\n}\n\n/// @title IVaultManagerListing\n/// @author Angle Labs, Inc.\n/// @notice Interface for the `VaultManagerListing` contract\ninterface IVaultManagerListing is IVaultManager {\n /// @notice Get the collateral owned by `user` in the contract\n /// @dev This function effectively sums the collateral amounts of all the vaults owned by `user`\n function getUserCollateral(address user) external view returns (uint256);\n}\n" + }, + "contracts/keeperMulticall/KeeperMulticall.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\nimport \"@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/access/AccessControlUpgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol\";\nimport \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\nimport \"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\";\nimport \"./RevertReasonParser.sol\";\n\n/// @title KeeperMulticall\n/// @notice Allows an authorized caller (keeper) to execute multiple actions in a single tx.\n/// @author Angle Labs, Inc.\n/// @dev Special features:\n/// - ability to pay the miner (for private Flashbots transactions)\n/// - swap tokens through 1inch\n/// @dev Tx need to be encoded as an array of Action. The flag `isDelegateCall` is used for calling functions within this same contract\ncontract KeeperMulticall is Initializable, AccessControlUpgradeable {\n using SafeERC20 for IERC20;\n\n bytes32 public constant KEEPER_ROLE = keccak256(\"KEEPER_ROLE\");\n\n //solhint-disable-next-line\n address private constant _oneInch = 0x1111111254fb6c44bAC0beD2854e76F90643097d;\n\n struct Action {\n address target;\n bytes data;\n bool isDelegateCall;\n }\n\n event LogAction(address indexed target, bytes data);\n event SentToMiner(uint256 indexed value);\n event Recovered(address indexed tokenAddress, address indexed to, uint256 amount);\n\n error AmountOutTooLow(uint256 amount, uint256 min);\n error BalanceTooLow();\n error FlashbotsErrorPayingMiner(uint256 value);\n error IncompatibleLengths();\n error RevertBytes();\n error WrongAmount();\n error ZeroAddress();\n\n constructor() initializer {}\n\n function initialize(address keeper) external initializer {\n __AccessControl_init();\n\n _setupRole(KEEPER_ROLE, keeper);\n _setRoleAdmin(KEEPER_ROLE, KEEPER_ROLE);\n }\n\n /// @notice Allows an authorized keeper to execute multiple actions in a single step\n /// @param actions Actions to be executed\n /// @param percentageToMiner Percentage to pay to miner expressed in bps (10000)\n /// @dev This is the main entry point for actions to be executed. The `isDelegateCall` flag is used for calling function inside this `KeeperMulticall` contract,\n /// if we call other contracts, the flag should be false\n function executeActions(\n Action[] memory actions,\n uint256 percentageToMiner\n ) external payable onlyRole(KEEPER_ROLE) returns (bytes[] memory) {\n uint256 numberOfActions = actions.length;\n if (numberOfActions == 0) revert IncompatibleLengths();\n\n bytes[] memory returnValues = new bytes[](numberOfActions + 1);\n\n uint256 balanceBefore = address(this).balance;\n\n for (uint256 i; i < numberOfActions; ++i) {\n returnValues[i] = _executeAction(actions[i]);\n }\n\n if (percentageToMiner != 0) {\n if (percentageToMiner >= 10000) revert WrongAmount();\n uint256 balanceAfter = address(this).balance;\n if (balanceAfter > balanceBefore) {\n uint256 amountToMiner = ((balanceAfter - balanceBefore) * percentageToMiner) / 10000;\n returnValues[numberOfActions] = payFlashbots(amountToMiner);\n }\n }\n\n return returnValues;\n }\n\n /// @notice Gets the action address and data and executes it\n /// @param action Action to be executed\n function _executeAction(Action memory action) internal returns (bytes memory) {\n bool success;\n bytes memory response;\n\n if (action.isDelegateCall) {\n //solhint-disable-next-line\n (success, response) = action.target.delegatecall(action.data);\n } else {\n //solhint-disable-next-line\n (success, response) = action.target.call(action.data);\n }\n\n require(success, RevertReasonParser.parse(response, \"action reverted: \"));\n emit LogAction(action.target, action.data);\n return response;\n }\n\n /// @notice Ability to pay miner directly. Used for Flashbots to execute private transactions\n /// @param value Value to be sent\n function payFlashbots(uint256 value) public payable onlyRole(KEEPER_ROLE) returns (bytes memory) {\n //solhint-disable-next-line\n (bool success, bytes memory response) = block.coinbase.call{ value: value }(\"\");\n if (!success) revert FlashbotsErrorPayingMiner(value);\n emit SentToMiner(value);\n return response;\n }\n\n /// @notice Used to check the balances the token holds for each token. If we don't have enough of a token, we revert the tx\n /// @param tokens Array of tokens to check\n /// @param minBalances Array of balances for each token\n function finalBalanceCheck(IERC20[] memory tokens, uint256[] memory minBalances) external view returns (bool) {\n uint256 tokensLength = tokens.length;\n if (tokensLength == 0 || tokensLength != minBalances.length) revert IncompatibleLengths();\n\n for (uint256 i; i < tokensLength; ++i) {\n if (address(tokens[i]) == 0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE) {\n if (address(this).balance < minBalances[i]) revert BalanceTooLow();\n } else {\n if (tokens[i].balanceOf(address(this)) < minBalances[i]) revert BalanceTooLow();\n }\n }\n\n return true;\n }\n\n /// @notice Swap token to another through 1Inch\n /// @param minAmountOut Minimum amount of `out` token to receive for the swap to happen\n /// @param payload Bytes needed for 1Inch API\n function swapToken(uint256 minAmountOut, bytes memory payload) external onlyRole(KEEPER_ROLE) {\n //solhint-disable-next-line\n (bool success, bytes memory result) = _oneInch.call(payload);\n if (!success) _revertBytes(result);\n\n uint256 amountOut = abi.decode(result, (uint256));\n if (amountOut < minAmountOut) revert AmountOutTooLow(amountOut, minAmountOut);\n }\n\n /// @notice Copied from 1Inch contract, used to revert if there is an error\n function _revertBytes(bytes memory errMsg) internal pure {\n if (errMsg.length != 0) {\n //solhint-disable-next-line\n assembly {\n revert(add(32, errMsg), mload(errMsg))\n }\n }\n revert RevertBytes();\n }\n\n /// @notice Approve a `spender` for `token`\n /// @param token Address of the token to approve\n /// @param spender Address of the spender to approve\n /// @param amount Amount to approve\n function approve(IERC20 token, address spender, uint256 amount) external onlyRole(KEEPER_ROLE) {\n uint256 currentAllowance = token.allowance(address(this), spender);\n if (currentAllowance < amount) {\n token.safeIncreaseAllowance(spender, amount - currentAllowance);\n } else if (currentAllowance > amount) {\n token.safeDecreaseAllowance(spender, currentAllowance - amount);\n }\n }\n\n receive() external payable {}\n\n /// @notice Withdraw stuck funds\n /// @param token Address of the token to recover\n /// @param receiver Address where to send the tokens\n /// @param amount Amount to recover\n function withdrawStuckFunds(address token, address receiver, uint256 amount) external onlyRole(KEEPER_ROLE) {\n if (receiver == address(0)) revert ZeroAddress();\n if (token == 0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE) {\n payable(receiver).transfer(amount);\n } else {\n IERC20(token).safeTransfer(receiver, amount);\n }\n\n emit Recovered(token, receiver, amount);\n }\n}\n" + }, + "contracts/keeperMulticall/MulticallWithFailure.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.12;\n\n/// @title MultiCallWithFailure\n/// @author Angle Labs, Inc.\n/// @notice Multicall contract allowing subcalls to fail without reverting the entire call\ncontract MultiCallWithFailure {\n error SubcallFailed();\n\n struct Call {\n address target;\n bytes data;\n bool canFail;\n }\n\n function multiCall(Call[] memory calls) external view returns (bytes[] memory) {\n bytes[] memory results = new bytes[](calls.length);\n\n for (uint256 i; i < calls.length; ++i) {\n (bool success, bytes memory result) = calls[i].target.staticcall(calls[i].data);\n if (!calls[i].canFail) {\n if (!success) {\n revert SubcallFailed();\n }\n }\n results[i] = result;\n }\n\n return results;\n }\n}\n" + }, + "contracts/keeperMulticall/RevertReasonParser.sol": { + "content": "// SPDX-License-Identifier: GNU-3\n\npragma solidity ^0.8.12;\n\n/// @title RevertReasonParser\n/// @author 1Inch team, taken from:\n/// - https://docs.1inch.io/docs/limit-order-protocol/smart-contract/libraries/RevertReasonParser/\n/// - https://etherscan.io/address/0x1111111254fb6c44bAC0beD2854e76F90643097d#code\nlibrary RevertReasonParser {\n bytes4 private constant _PANIC_SELECTOR = bytes4(keccak256(\"Panic(uint256)\"));\n bytes4 private constant _ERROR_SELECTOR = bytes4(keccak256(\"Error(string)\"));\n\n function parse(bytes memory data, string memory prefix) internal pure returns (string memory) {\n if (data.length >= 4) {\n bytes4 selector;\n //solhint-disable-next-line\n assembly {\n selector := mload(add(data, 0x20))\n }\n\n // 68 = 4-byte selector + 32 bytes offset + 32 bytes length\n if (selector == _ERROR_SELECTOR && data.length >= 68) {\n uint256 offset;\n bytes memory reason;\n // solhint-disable no-inline-assembly\n assembly {\n // 36 = 32 bytes data length + 4-byte selector\n offset := mload(add(data, 36))\n reason := add(data, add(36, offset))\n }\n /*\n revert reason is padded up to 32 bytes with ABI encoder: Error(string)\n also sometimes there is extra 32 bytes of zeros padded in the end:\n https://github.com/ethereum/solidity/issues/10170\n because of that we can't check for equality and instead check\n that offset + string length + extra 36 bytes is less than overall data length\n */\n require(data.length >= 36 + offset + reason.length, \"Invalid revert reason\");\n return string(abi.encodePacked(prefix, \"Error(\", reason, \")\"));\n }\n // 36 = 4-byte selector + 32 bytes integer\n else if (selector == _PANIC_SELECTOR && data.length == 36) {\n uint256 code;\n // solhint-disable no-inline-assembly\n assembly {\n // 36 = 32 bytes data length + 4-byte selector\n code := mload(add(data, 36))\n }\n return string(abi.encodePacked(prefix, \"Panic(\", _toHex(code), \")\"));\n }\n }\n\n return string(abi.encodePacked(prefix, \"Unknown(\", _toHex(data), \")\"));\n }\n\n function _toHex(uint256 value) private pure returns (string memory) {\n return _toHex(abi.encodePacked(value));\n }\n\n function _toHex(bytes memory data) private pure returns (string memory) {\n bytes16 alphabet = 0x30313233343536373839616263646566;\n bytes memory str = new bytes(2 + data.length * 2);\n str[0] = \"0\";\n str[1] = \"x\";\n for (uint256 i; i < data.length; ++i) {\n str[2 * i + 2] = alphabet[uint8(data[i] >> 4)];\n str[2 * i + 3] = alphabet[uint8(data[i] & 0x0f)];\n }\n return string(str);\n }\n}\n" + }, + "contracts/mock/Mock1Inch.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.12;\n\nimport \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\nimport \"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\";\n\ncontract Mock1Inch {\n using SafeERC20 for IERC20;\n\n function swap(address tokenIn, uint256 amountIn, address to, address tokenOut, uint256 amountOut) external {\n IERC20(tokenIn).safeTransferFrom(msg.sender, to, amountIn);\n if (tokenOut == 0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE) {\n //solhint-disable-next-line\n (bool sent, bytes memory data) = msg.sender.call{ value: amountOut }(\"\");\n data;\n require(sent, \"Failed to send Ether\");\n } else {\n IERC20(tokenOut).safeTransferFrom(to, msg.sender, amountOut);\n }\n }\n\n receive() external payable {}\n}\n" + }, + "contracts/mock/MockAnything.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.12;\n\ncontract MockAnything {\n uint256 public stateVar = 1;\n\n error CustomError();\n error CustomErrorWithValue(uint256);\n\n function fail(uint256 value) external view returns (uint256) {\n stateVar;\n if (value < 10) {\n revert CustomError();\n }\n if (value < 20) {\n revert CustomErrorWithValue(value);\n }\n return value + 1;\n }\n\n function modifyState(uint256 value) external {\n stateVar = value;\n }\n}\n" + }, + "contracts/mock/MockChainlinkOracle.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.7;\n\ninterface MockAggregatorV3Interface {\n function decimals() external view returns (uint8);\n\n function description() external view returns (string memory);\n\n function version() external view returns (uint256);\n\n function getRoundData(\n uint80 _roundId\n )\n external\n view\n returns (uint80 roundId, int256 answer, uint256 startedAt, uint256 updatedAt, uint80 answeredInRound);\n\n function latestRoundData()\n external\n view\n returns (uint80 roundId, int256 answer, uint256 startedAt, uint256 updatedAt, uint80 answeredInRound);\n}\n\ncontract MockChainlinkOracle is MockAggregatorV3Interface {\n uint80 public roundId = 0;\n uint8 public keyDecimals = 0;\n\n struct Entry {\n uint80 roundId;\n int256 answer;\n uint256 startedAt;\n uint256 updatedAt;\n uint80 answeredInRound;\n }\n\n mapping(uint256 => Entry) public entries;\n\n bool public latestRoundDataShouldRevert;\n\n string public desc;\n\n constructor() {}\n\n // Mock setup function\n function setLatestAnswer(int256 answer, uint256 timestamp) external {\n roundId++;\n entries[roundId] = Entry({\n roundId: roundId,\n answer: answer,\n startedAt: timestamp,\n updatedAt: timestamp,\n answeredInRound: roundId\n });\n }\n\n function setLatestAnswerWithRound(int256 answer, uint256 timestamp, uint80 _roundId) external {\n roundId = _roundId;\n entries[roundId] = Entry({\n roundId: roundId,\n answer: answer,\n startedAt: timestamp,\n updatedAt: timestamp,\n answeredInRound: roundId\n });\n }\n\n function setLatestAnswerRevert(int256 answer, uint256 timestamp) external {\n roundId++;\n entries[roundId] = Entry({\n roundId: roundId,\n answer: answer,\n startedAt: timestamp,\n updatedAt: timestamp,\n answeredInRound: roundId - 1\n });\n }\n\n function setLatestRoundDataShouldRevert(bool _shouldRevert) external {\n latestRoundDataShouldRevert = _shouldRevert;\n }\n\n function setDecimals(uint8 _decimals) external {\n keyDecimals = _decimals;\n }\n\n function setDescritpion(string memory _desc) external {\n desc = _desc;\n }\n\n function description() external view override returns (string memory) {\n return desc;\n }\n\n function version() external view override returns (uint256) {\n roundId;\n return 0;\n }\n\n function latestRoundData() external view override returns (uint80, int256, uint256, uint256, uint80) {\n if (latestRoundDataShouldRevert) {\n revert(\"latestRoundData reverted\");\n }\n return getRoundData(uint80(roundId));\n }\n\n function decimals() external view override returns (uint8) {\n return keyDecimals;\n }\n\n function getRoundData(uint80 _roundId) public view override returns (uint80, int256, uint256, uint256, uint80) {\n Entry memory entry = entries[_roundId];\n // Emulate a Chainlink aggregator\n require(entry.updatedAt > 0, \"No data present\");\n return (entry.roundId, entry.answer, entry.startedAt, entry.updatedAt, entry.answeredInRound);\n }\n}\n" + }, + "contracts/mock/MockCoreBorrow.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\nimport \"../interfaces/ICoreBorrow.sol\";\nimport \"../interfaces/IFlashAngle.sol\";\nimport \"../interfaces/ITreasury.sol\";\n\ncontract MockCoreBorrow is ICoreBorrow {\n mapping(address => bool) public flashLoaners;\n mapping(address => bool) public governors;\n mapping(address => bool) public guardians;\n\n function isFlashLoanerTreasury(address treasury) external view override returns (bool) {\n return flashLoaners[treasury];\n }\n\n function isGovernor(address admin) external view override returns (bool) {\n return governors[admin];\n }\n\n function isGovernorOrGuardian(address admin) external view override returns (bool) {\n return governors[admin] || guardians[admin];\n }\n\n function toggleGovernor(address admin) external {\n governors[admin] = !governors[admin];\n }\n\n function toggleGuardian(address admin) external {\n guardians[admin] = !guardians[admin];\n }\n\n function toggleFlashLoaners(address admin) external {\n flashLoaners[admin] = !flashLoaners[admin];\n }\n\n function addStablecoinSupport(IFlashAngle flashAngle, address _treasury) external {\n flashAngle.addStablecoinSupport(_treasury);\n }\n\n function removeStablecoinSupport(IFlashAngle flashAngle, address _treasury) external {\n flashAngle.removeStablecoinSupport(_treasury);\n }\n\n function setCore(IFlashAngle flashAngle, address _core) external {\n flashAngle.setCore(_core);\n }\n\n function setFlashLoanModule(ITreasury _treasury, address _flashLoanModule) external {\n _treasury.setFlashLoanModule(_flashLoanModule);\n }\n}\n" + }, + "contracts/mock/MockERC1271.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.12;\n\nimport \"../interfaces/external/IERC1271.sol\";\n\ncontract MockERC1271 is IERC1271 {\n uint256 public mode = 0;\n\n function setMode(uint256 _mode) public {\n mode = _mode;\n }\n\n /// @notice Returns whether the provided signature is valid for the provided data\n /// @dev MUST return the bytes4 magic value 0x1626ba7e when function passes.\n /// MUST NOT modify state (using STATICCALL for solc < 0.5, view modifier for solc > 0.5).\n /// MUST allow external calls.\n /// @return magicValue The bytes4 magic value 0x1626ba7e\n function isValidSignature(bytes32, bytes memory) external view returns (bytes4 magicValue) {\n if (mode == 1) magicValue = 0x1626ba7e;\n }\n}\n" + }, + "contracts/mock/MockERC721Receiver.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (token/ERC721/utils/ERC721Holder.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Implementation of the {IERC721Receiver} interface.\n *\n * Accepts all token transfers.\n * Make sure the contract is able to use its token with {IERC721-safeTransferFrom}, {IERC721-approve} or {IERC721-setApprovalForAll}.\n */\ncontract MockERC721Receiver {\n uint256 public mode = 0;\n\n function setMode(uint256 _mode) public {\n mode = _mode;\n }\n\n function onERC721Received(address, address, uint256, bytes memory) public view returns (bytes4) {\n require(mode != 1, \"0x1111111\");\n if (mode == 2) return this.setMode.selector;\n return this.onERC721Received.selector;\n }\n}\n" + }, + "contracts/mock/MockEulerPool.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\nimport \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\n\ncontract MockEulerPool {\n IERC20 public collateral;\n uint256 public poolSize;\n //solhint-disable-next-line\n uint256 public MAX_SANE_AMOUNT;\n\n mapping(address => uint256) public users;\n uint256 public interestRateAccumulator;\n\n constructor(IERC20 collateral_, uint256 poolSize_) {\n collateral = collateral_;\n poolSize = poolSize_;\n interestRateAccumulator = 10 ** 18;\n MAX_SANE_AMOUNT = type(uint112).max;\n }\n\n function setPoolSize(uint256 poolSize_) external {\n uint256 balance = collateral.balanceOf(address(this));\n poolSize = poolSize_;\n if (balance > poolSize_) collateral.transfer(msg.sender, balance - poolSize_);\n if (balance < poolSize_) collateral.transferFrom(msg.sender, address(this), poolSize_ - balance);\n }\n\n function setInterestRateAccumulator(uint256 interestRateAccumulator_) external {\n interestRateAccumulator = interestRateAccumulator_;\n }\n\n //solhint-disable-next-line\n function setMAXSANEAMOUNT(uint256 MAX_SANE_AMOUNT_) external {\n MAX_SANE_AMOUNT = MAX_SANE_AMOUNT_;\n }\n\n function balanceOfUnderlying(address account) external view returns (uint256) {\n return (users[account] * interestRateAccumulator) / 10 ** 18;\n }\n\n function deposit(uint256, uint256 amount) external {\n users[msg.sender] += (amount * 10 ** 18) / interestRateAccumulator;\n poolSize += amount;\n collateral.transferFrom(msg.sender, address(this), amount);\n }\n\n function withdraw(uint256, uint256 amount) external {\n if (amount == type(uint256).max) amount = (users[msg.sender] * interestRateAccumulator) / 10 ** 18;\n\n require(amount <= poolSize, \"4\");\n users[msg.sender] -= (amount * 10 ** 18) / interestRateAccumulator;\n collateral.transfer(msg.sender, amount);\n }\n}\n" + }, + "contracts/mock/MockFlashLoanModule.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\nimport \"../interfaces/IFlashAngle.sol\";\nimport \"../interfaces/ICoreBorrow.sol\";\n\ncontract MockFlashLoanModule is IFlashAngle {\n ICoreBorrow public override core;\n mapping(address => bool) public stablecoinsSupported;\n mapping(IAgToken => uint256) public interestAccrued;\n uint256 public surplusValue;\n\n constructor(ICoreBorrow _core) {\n core = _core;\n }\n\n function accrueInterestToTreasury(IAgToken stablecoin) external override returns (uint256 balance) {\n balance = surplusValue;\n interestAccrued[stablecoin] += balance;\n }\n\n function addStablecoinSupport(address _treasury) external override {\n stablecoinsSupported[_treasury] = true;\n }\n\n function removeStablecoinSupport(address _treasury) external override {\n stablecoinsSupported[_treasury] = false;\n }\n\n function setCore(address _core) external override {\n core = ICoreBorrow(_core);\n }\n\n function setSurplusValue(uint256 _surplusValue) external {\n surplusValue = _surplusValue;\n }\n}\n" + }, + "contracts/mock/MockFlashLoanReceiver.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.7;\n\nimport \"@openzeppelin/contracts/token/ERC20/ERC20.sol\";\n\nimport \"@openzeppelin/contracts/interfaces/IERC3156FlashBorrower.sol\";\n\nimport \"@openzeppelin/contracts/interfaces/IERC3156FlashLender.sol\";\n\ncontract MockFlashLoanReceiver is IERC3156FlashBorrower {\n bytes32 public constant CALLBACK_SUCCESS = keccak256(\"ERC3156FlashBorrower.onFlashLoan\");\n\n constructor() {}\n\n function onFlashLoan(\n address,\n address token,\n uint256 amount,\n uint256 fee,\n bytes calldata data\n ) external override returns (bytes32) {\n IERC20(token).approve(msg.sender, amount + fee);\n if (amount >= 10 ** 21) return keccak256(\"error\");\n if (amount == 2 * 10 ** 18) {\n IERC3156FlashLender(msg.sender).flashLoan(IERC3156FlashBorrower(address(this)), token, amount, data);\n return keccak256(\"reentrant\");\n } else return CALLBACK_SUCCESS;\n }\n}\n" + }, + "contracts/mock/MockInterestRateComputer.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\ncontract MockInterestRateComputer {\n uint256 public interestRate;\n uint256 public interestAccumulator;\n uint256 public immutable baseInterest;\n uint256 public immutable halfBase;\n\n uint256 public constant WEEK = 7 * 86400;\n\n constructor(uint256 _baseInterest, uint256 _interestRate) {\n interestAccumulator = _baseInterest;\n baseInterest = _baseInterest;\n halfBase = _baseInterest / 2;\n interestRate = _interestRate;\n }\n\n function _calculateAngle(uint256 exp, uint256 _interestAccumulator) internal view returns (uint256) {\n uint256 ratePerSecond = interestRate;\n if (exp == 0 || ratePerSecond == 0) return _interestAccumulator;\n uint256 expMinusOne = exp - 1;\n uint256 expMinusTwo = exp > 2 ? exp - 2 : 0;\n uint256 basePowerTwo = (ratePerSecond * ratePerSecond) / baseInterest;\n uint256 basePowerThree = (basePowerTwo * ratePerSecond) / baseInterest;\n uint256 secondTerm = (exp * expMinusOne * basePowerTwo) / 2;\n uint256 thirdTerm = (exp * expMinusOne * expMinusTwo * basePowerThree) / 6;\n return (_interestAccumulator * (baseInterest + ratePerSecond * exp + secondTerm + thirdTerm)) / baseInterest;\n }\n\n function _calculateAave(uint256 exp, uint256 _interestAccumulator) internal view returns (uint256) {\n uint256 ratePerSecond = interestRate;\n if (exp == 0 || ratePerSecond == 0) return _interestAccumulator;\n uint256 expMinusOne = exp - 1;\n uint256 expMinusTwo = exp > 2 ? exp - 2 : 0;\n uint256 basePowerTwo = (ratePerSecond * ratePerSecond + halfBase) / baseInterest;\n uint256 basePowerThree = (basePowerTwo * ratePerSecond + halfBase) / baseInterest;\n uint256 secondTerm = (exp * expMinusOne * basePowerTwo) / 2;\n uint256 thirdTerm = (exp * expMinusOne * expMinusTwo * basePowerThree) / 6;\n return (_interestAccumulator * (baseInterest + ratePerSecond * exp + secondTerm + thirdTerm)) / baseInterest;\n }\n\n function _calculateCompound(uint256 exp, uint256 _interestAccumulator) internal view returns (uint256) {\n return _interestAccumulator * (baseInterest + interestRate * exp);\n }\n\n function _rpow(uint256 x, uint256 n, uint256 base) internal pure returns (uint256 z) {\n //solhint-disable-next-line\n assembly {\n switch x\n case 0 {\n switch n\n case 0 {\n z := base\n }\n default {\n z := 0\n }\n }\n default {\n switch mod(n, 2)\n case 0 {\n z := base\n }\n default {\n z := x\n }\n let half := div(base, 2) // for rounding.\n for {\n n := div(n, 2)\n } n {\n n := div(n, 2)\n } {\n let xx := mul(x, x)\n if iszero(eq(div(xx, x), x)) {\n revert(0, 0)\n }\n let xxRound := add(xx, half)\n if lt(xxRound, xx) {\n revert(0, 0)\n }\n x := div(xxRound, base)\n if mod(n, 2) {\n let zx := mul(z, x)\n if and(iszero(iszero(x)), iszero(eq(div(zx, x), z))) {\n revert(0, 0)\n }\n let zxRound := add(zx, half)\n if lt(zxRound, zx) {\n revert(0, 0)\n }\n z := div(zxRound, base)\n }\n }\n }\n }\n }\n\n function _calculateMaker(uint256 delta, uint256 _interestAccumulator) internal view returns (uint256) {\n return (_rpow(baseInterest + interestRate, delta, baseInterest) * _interestAccumulator) / baseInterest;\n }\n\n function calculateAngle(uint256 delta) external view returns (uint256) {\n return _calculateAngle(delta, interestAccumulator);\n }\n\n function calculateAave(uint256 delta) external view returns (uint256) {\n return _calculateAave(delta, interestAccumulator);\n }\n\n function calculateMaker(uint256 delta) external view returns (uint256) {\n return _calculateMaker(delta, interestAccumulator);\n }\n\n function calculateAngle1Year() external view returns (uint256) {\n uint256 _interestAccumulator = interestAccumulator;\n for (uint256 i; i < 52; ++i) {\n _interestAccumulator = _calculateAngle(WEEK, _interestAccumulator);\n }\n return _interestAccumulator;\n }\n\n function calculateAave1Year() external view returns (uint256) {\n uint256 _interestAccumulator = interestAccumulator;\n for (uint256 i; i < 52; ++i) {\n _interestAccumulator = _calculateAave(WEEK, _interestAccumulator);\n }\n return _interestAccumulator;\n }\n\n function calculateMaker1Year() external view returns (uint256) {\n uint256 _interestAccumulator = interestAccumulator;\n for (uint256 i; i < 52; ++i) {\n _interestAccumulator = _calculateMaker(WEEK, _interestAccumulator);\n }\n return _interestAccumulator;\n }\n\n function calculateAngle1YearDirect() external view returns (uint256) {\n uint256 _interestAccumulator = interestAccumulator;\n _interestAccumulator = _calculateAngle(52 * WEEK, _interestAccumulator);\n\n return _interestAccumulator;\n }\n\n function calculateAave1YearDirect() external view returns (uint256) {\n uint256 _interestAccumulator = interestAccumulator;\n _interestAccumulator = _calculateAave(52 * WEEK, _interestAccumulator);\n\n return _interestAccumulator;\n }\n\n function calculateMaker1YearDirect() external view returns (uint256) {\n uint256 _interestAccumulator = interestAccumulator;\n _interestAccumulator = _calculateMaker(52 * WEEK, _interestAccumulator);\n\n return _interestAccumulator;\n }\n\n function calculateCompound1YearDirect() external view returns (uint256) {\n uint256 _interestAccumulator = interestAccumulator;\n _interestAccumulator = _calculateCompound(52 * WEEK, _interestAccumulator);\n\n return _interestAccumulator;\n }\n}\n" + }, + "contracts/mock/MockKeeperMulticall.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.12;\n\nimport \"@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/access/AccessControlUpgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol\";\nimport \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\nimport \"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\";\n\ncontract MockKeeperMulticall is Initializable, AccessControlUpgradeable {\n using SafeERC20 for IERC20;\n\n bytes32 public constant KEEPER_ROLE = keccak256(\"KEEPER_ROLE\");\n\n //solhint-disable-next-line\n address private constant _oneInch = 0x1111111254fb6c44bAC0beD2854e76F90643097d;\n\n struct Action {\n address target;\n bytes data;\n bool isDelegateCall;\n }\n\n event LogAction(address indexed target, bytes data);\n event SentToMiner(uint256 indexed value);\n event Recovered(address indexed tokenAddress, address indexed to, uint256 amount);\n\n error AmountOutTooLow(uint256 amount, uint256 min);\n error BalanceTooLow();\n error FlashbotsErrorPayingMiner(uint256 value);\n error IncompatibleLengths();\n error RevertBytes();\n error ZeroAddress();\n\n constructor() initializer {}\n\n function initialize(address keeper) public initializer {\n __AccessControl_init();\n\n _setupRole(KEEPER_ROLE, keeper);\n _setRoleAdmin(KEEPER_ROLE, KEEPER_ROLE);\n }\n}\n\ncontract MockKeeperMulticall2 {\n uint256 public varTest = 1;\n\n bytes32 public constant KEEPER_ROLE = keccak256(\"KEEPER_ROLE\");\n\n //solhint-disable-next-line\n address private constant _oneInch = 0x1111111254fb6c44bAC0beD2854e76F90643097d;\n\n struct Action {\n address target;\n bytes data;\n bool isDelegateCall;\n }\n\n event LogAction(address indexed target, bytes data);\n event SentToMiner(uint256 indexed value);\n event Recovered(address indexed tokenAddress, address indexed to, uint256 amount);\n\n error AmountOutTooLow(uint256 amount, uint256 min);\n error BalanceTooLow();\n error FlashbotsErrorPayingMiner(uint256 value);\n error IncompatibleLengths();\n error RevertBytes();\n error ZeroAddress();\n\n function functionTest() external pure returns (bool) {\n return true;\n }\n}\n" + }, + "contracts/mock/MockLayerZero.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\ninterface ILzApp {\n function lzReceive(uint16 _srcChainId, bytes memory _srcAddress, uint64 _nonce, bytes memory _payload) external;\n}\n\ncontract MockLayerZero {\n mapping(uint16 => uint256) public counters;\n uint256 public config;\n mapping(uint16 => uint64) public outboundNonce;\n uint256 public resumeReceived;\n uint256 public sendVersion;\n uint256 public receiveVersion;\n\n /// @notice Initiate with a fixe change rate\n constructor() {}\n\n function send(\n uint16 _dstChainId,\n bytes calldata,\n bytes calldata,\n address,\n address,\n bytes calldata\n ) external payable {\n counters[_dstChainId] += 1;\n }\n\n function getOutboundNonce(uint16 _dstChainId, address) external view returns (uint64) {\n return outboundNonce[_dstChainId];\n }\n\n function setOutBoundNonce(uint16 _from, uint64 value) external {\n outboundNonce[_from] = value;\n }\n\n function lzReceive(\n address lzApp,\n uint16 _srcChainId,\n bytes memory _srcAddress,\n uint64 _nonce,\n bytes memory _payload\n ) public {\n ILzApp(lzApp).lzReceive(_srcChainId, _srcAddress, _nonce, _payload);\n }\n\n function estimateFees(\n uint16,\n address,\n bytes calldata,\n bool,\n bytes calldata\n ) external pure returns (uint256 nativeFee, uint256 zroFee) {\n return (123, 456);\n }\n\n function setConfig(uint16, uint16, uint256 _configType, bytes calldata) external {\n config = _configType;\n }\n\n function getConfig(uint16, uint16, address, uint256) external view returns (bytes memory) {\n return abi.encodePacked(config);\n }\n\n function setSendVersion(uint16 _version) external {\n sendVersion = _version;\n }\n\n function setReceiveVersion(uint16 _version) external {\n receiveVersion = _version;\n }\n\n function forceResumeReceive(uint16, bytes calldata) external {\n resumeReceived = 1 - resumeReceived;\n }\n}\n" + }, + "contracts/mock/MockLiquidityGauge.sol": { + "content": "// SPDX-License-Identifier: UNLICENSED\npragma solidity ^0.8.12;\n\nimport { ILiquidityGauge } from \"../interfaces/coreModule/ILiquidityGauge.sol\";\nimport \"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\";\nimport \"@openzeppelin/contracts/token/ERC20/ERC20.sol\";\n\ncontract MockLiquidityGauge is ILiquidityGauge, ERC20 {\n using SafeERC20 for IERC20;\n\n IERC20 internal _ANGLE = IERC20(0x31429d1856aD1377A8A0079410B297e1a9e214c2);\n IERC20 internal _token;\n mapping(address => uint256) public rewards;\n\n constructor(string memory name_, string memory symbol_, address token_) ERC20(name_, symbol_) {\n _token = IERC20(token_);\n }\n\n function deposit(\n uint256 _value,\n address _addr,\n // solhint-disable-next-line\n bool\n ) external {\n _token.safeTransferFrom(msg.sender, address(this), _value);\n _mint(_addr, _value);\n }\n\n function withdraw(\n uint256 _value,\n // solhint-disable-next-line\n bool\n ) external {\n _burn(msg.sender, _value);\n _token.safeTransfer(msg.sender, _value);\n }\n\n // solhint-disable-next-line\n function claim_rewards(address _addr, address _receiver) external {\n if (_receiver == address(0)) _receiver = _addr;\n _ANGLE.safeTransfer(_receiver, rewards[_addr]);\n rewards[_addr] = 0;\n }\n\n // solhint-disable-next-line\n function claimable_reward(address _addr, address) external view returns (uint256 amount) {\n return rewards[_addr];\n }\n\n function setReward(address receiver_, uint256 amount) external {\n rewards[receiver_] = amount;\n }\n}\n" + }, + "contracts/mock/MockOracle.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.7;\n\nimport \"../interfaces/IOracle.sol\";\n\ncontract MockOracle is IOracle {\n event Update(uint256 _peg);\n\n ITreasury public treasury;\n\n uint256 public base = 1 ether;\n uint256 public precision = 1 ether;\n uint256 public rate;\n bool public outdated;\n\n /// @notice Initiate with a fixe change rate\n constructor(uint256 rate_, ITreasury _treasury) {\n rate = rate_;\n treasury = _treasury;\n }\n\n /// @notice Mock read\n function read() external view override returns (uint256) {\n return rate;\n }\n\n /// @notice change oracle rate\n function update(uint256 newRate) external {\n rate = newRate;\n }\n\n function setTreasury(address _treasury) external override {\n treasury = ITreasury(_treasury);\n }\n\n function circuitChainlink() external pure override returns (AggregatorV3Interface[] memory) {}\n}\n" + }, + "contracts/mock/MockPolygonAgEUR.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.12;\n\nimport \"../agToken/polygon/utils/ERC20UpgradeableCustom.sol\";\nimport \"@openzeppelin/contracts-upgradeable/access/AccessControlUpgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/utils/cryptography/draft-EIP712Upgradeable.sol\";\nimport \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\nimport \"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\";\n\nimport \"../interfaces/IAgToken.sol\";\nimport \"../interfaces/ITreasury.sol\";\n\ninterface IChildToken {\n function deposit(address user, bytes calldata depositData) external;\n\n function withdraw(uint256 amount) external;\n}\n\ncontract MockPolygonAgEUR is\n Initializable,\n ERC20UpgradeableCustom,\n AccessControlUpgradeable,\n EIP712Upgradeable,\n IChildToken\n{\n bytes32 public constant DEPOSITOR_ROLE = keccak256(\"DEPOSITOR_ROLE\");\n\n /// @dev Emitted when the child chain manager changes\n event ChildChainManagerAdded(address newAddress);\n event ChildChainManagerRevoked(address oldAddress);\n\n constructor() initializer {}\n\n function initialize(\n string memory _name,\n string memory _symbol,\n address childChainManager,\n address guardian\n ) public initializer {\n __ERC20_init(_name, _symbol);\n __AccessControl_init();\n _setupRole(DEFAULT_ADMIN_ROLE, guardian);\n _setupRole(DEPOSITOR_ROLE, childChainManager);\n __EIP712_init(_name, \"1\");\n }\n\n /**\n * @notice Called when the bridge has tokens to mint\n * @param user Address to mint the token to\n * @param depositData Encoded amount to mint\n */\n function deposit(address user, bytes calldata depositData) external override {\n require(hasRole(DEPOSITOR_ROLE, msg.sender));\n uint256 amount = abi.decode(depositData, (uint256));\n _mint(user, amount);\n }\n\n /**\n * @notice Called when user wants to withdraw tokens back to root chain\n * @dev Should burn user's tokens. This transaction will be verified when exiting on root chain\n * @param amount Amount of tokens to withdraw\n */\n function withdraw(uint256 amount) external override {\n _burn(_msgSender(), amount);\n }\n\n // =============================================================================\n // ======================= New data added for the upgrade ======================\n // =============================================================================\n\n mapping(address => bool) public isMinter;\n /// @notice Reference to the treasury contract which can grant minting rights\n address public treasury;\n /// @notice Boolean to check whether the contract has been reinitialized after its upgrade\n bool public treasuryInitialized;\n\n using SafeERC20 for IERC20;\n\n /// @notice Base used for fee computation\n uint256 public constant BASE_PARAMS = 10 ** 9;\n\n // =============================== Bridging Data ===============================\n\n /// @notice Struct with some data about a specific bridge token\n struct BridgeDetails {\n // Limit on the balance of bridge token held by the contract: it is designed\n // to reduce the exposure of the system to hacks\n uint256 limit;\n // Limit on the hourly volume of token minted through this bridge\n // Technically the limit over a rolling hour is hourlyLimit x2 as hourly limit\n // is enforced only between x:00 and x+1:00\n uint256 hourlyLimit;\n // Fee taken for swapping in and out the token\n uint64 fee;\n // Whether the associated token is allowed or not\n bool allowed;\n // Whether swapping in and out from the associated token is paused or not\n bool paused;\n }\n\n /// @notice Maps a bridge token to data\n mapping(address => BridgeDetails) public bridges;\n /// @notice List of all bridge tokens\n address[] public bridgeTokensList;\n /// @notice Maps a bridge token to the associated hourly volume\n mapping(address => mapping(uint256 => uint256)) public usage;\n /// @notice Maps an address to whether it is exempt of fees for when it comes to swapping in and out\n mapping(address => uint256) public isFeeExempt;\n\n uint256[44] private __gap;\n\n // ================================== Events ===================================\n\n event BridgeTokenAdded(address indexed bridgeToken, uint256 limit, uint256 hourlyLimit, uint64 fee, bool paused);\n event BridgeTokenToggled(address indexed bridgeToken, bool toggleStatus);\n event BridgeTokenRemoved(address indexed bridgeToken);\n event BridgeTokenFeeUpdated(address indexed bridgeToken, uint64 fee);\n event BridgeTokenLimitUpdated(address indexed bridgeToken, uint256 limit);\n event BridgeTokenHourlyLimitUpdated(address indexed bridgeToken, uint256 hourlyLimit);\n event HourlyLimitUpdated(uint256 hourlyLimit);\n event FeeToggled(address indexed theAddress, uint256 toggleStatus);\n event KeeperToggled(address indexed keeper, bool toggleStatus);\n event MinterToggled(address indexed minter);\n event Recovered(address indexed token, address indexed to, uint256 amount);\n event TreasuryUpdated(address indexed _treasury);\n\n // ================================== Errors ===================================\n\n error AssetStillControlledInReserves();\n error BurnAmountExceedsAllowance();\n error HourlyLimitExceeded();\n error InvalidSender();\n error InvalidToken();\n error InvalidTreasury();\n error NotGovernor();\n error NotGovernorOrGuardian();\n error NotMinter();\n error NotTreasury();\n error TooBigAmount();\n error TooHighParameterValue();\n error TreasuryAlreadyInitialized();\n error ZeroAddress();\n\n /// @notice Checks to see if it is the `Treasury` calling this contract\n /// @dev There is no Access Control here, because it can be handled cheaply through this modifier\n modifier onlyTreasury() {\n if (msg.sender != treasury) revert NotTreasury();\n _;\n }\n\n /// @notice Checks whether the sender has the minting right\n modifier onlyMinter() {\n if (!isMinter[msg.sender]) revert NotMinter();\n _;\n }\n\n /// @notice Checks whether the `msg.sender` has the governor role or not\n modifier onlyGovernor() {\n if (!ITreasury(treasury).isGovernor(msg.sender)) revert NotGovernor();\n _;\n }\n\n /// @notice Checks whether the `msg.sender` has the governor role or the guardian role\n modifier onlyGovernorOrGuardian() {\n if (!ITreasury(treasury).isGovernorOrGuardian(msg.sender)) revert NotGovernorOrGuardian();\n _;\n }\n\n /// @notice Sets up the treasury contract on Polygon after the upgrade\n /// @param _treasury Address of the treasury contract\n function setUpTreasury(address _treasury) external {\n // Only governor on Polygon\n if (msg.sender != 0xdA2D2f638D6fcbE306236583845e5822554c02EA) revert NotGovernor();\n if (address(ITreasury(_treasury).stablecoin()) != address(this)) revert InvalidTreasury();\n if (treasuryInitialized) revert TreasuryAlreadyInitialized();\n treasury = _treasury;\n treasuryInitialized = true;\n emit TreasuryUpdated(_treasury);\n }\n\n // =========================== External Function ===============================\n\n /// @notice Allows anyone to burn agToken without redeeming collateral back\n /// @param amount Amount of stablecoins to burn\n /// @dev This function can typically be called if there is a settlement mechanism to burn stablecoins\n function burnStablecoin(uint256 amount) external {\n _burnCustom(msg.sender, amount);\n }\n\n // ======================= Minter Role Only Functions ==========================\n\n function burnSelf(uint256 amount, address burner) external onlyMinter {\n _burnCustom(burner, amount);\n }\n\n function burnFrom(uint256 amount, address burner, address sender) external onlyMinter {\n _burnFromNoRedeem(amount, burner, sender);\n }\n\n function mint(address account, uint256 amount) external onlyMinter {\n _mint(account, amount);\n }\n\n // ======================= Treasury Only Functions =============================\n\n function addMinter(address minter) external onlyTreasury {\n isMinter[minter] = true;\n emit MinterToggled(minter);\n }\n\n function removeMinter(address minter) external {\n if (msg.sender != address(treasury) && msg.sender != minter) revert InvalidSender();\n isMinter[minter] = false;\n emit MinterToggled(minter);\n }\n\n function setTreasury(address _treasury) external onlyTreasury {\n treasury = _treasury;\n emit TreasuryUpdated(_treasury);\n }\n\n // ============================ Internal Function ==============================\n\n /// @notice Internal version of the function `burnFromNoRedeem`\n /// @param amount Amount to burn\n /// @dev It is at the level of this function that allowance checks are performed\n function _burnFromNoRedeem(uint256 amount, address burner, address sender) internal {\n if (burner != sender) {\n uint256 currentAllowance = allowance(burner, sender);\n if (currentAllowance < amount) revert BurnAmountExceedsAllowance();\n _approve(burner, sender, currentAllowance - amount);\n }\n _burnCustom(burner, amount);\n }\n\n // ==================== External Permissionless Functions ======================\n\n /// @notice Returns the list of all supported bridge tokens\n /// @dev Helpful for UIs\n function allBridgeTokens() external view returns (address[] memory) {\n return bridgeTokensList;\n }\n\n /// @notice Returns the current volume for a bridge, for the current hour\n /// @dev Helpful for UIs\n function currentUsage(address bridge) external view returns (uint256) {\n return usage[bridge][block.timestamp / 3600];\n }\n\n /// @notice Mints the canonical token from a supported bridge token\n /// @param bridgeToken Bridge token to use to mint\n /// @param amount Amount of bridge tokens to send\n /// @param to Address to which the stablecoin should be sent\n /// @dev Some fees may be taken by the protocol depending on the token used and on the address calling\n function swapIn(address bridgeToken, uint256 amount, address to) external returns (uint256) {\n BridgeDetails memory bridgeDetails = bridges[bridgeToken];\n if (!bridgeDetails.allowed || bridgeDetails.paused) revert InvalidToken();\n uint256 balance = IERC20(bridgeToken).balanceOf(address(this));\n if (balance + amount > bridgeDetails.limit) {\n // In case someone maliciously sends tokens to this contract\n // Or the limit changes\n if (bridgeDetails.limit > balance) amount = bridgeDetails.limit - balance;\n else {\n amount = 0;\n }\n }\n\n // Checking requirement on the hourly volume\n uint256 hour = block.timestamp / 3600;\n uint256 hourlyUsage = usage[bridgeToken][hour] + amount;\n if (hourlyUsage > bridgeDetails.hourlyLimit) {\n // Edge case when the hourly limit changes\n if (bridgeDetails.hourlyLimit > usage[bridgeToken][hour])\n amount = bridgeDetails.hourlyLimit - usage[bridgeToken][hour];\n else {\n amount = 0;\n }\n }\n usage[bridgeToken][hour] = usage[bridgeToken][hour] + amount;\n\n IERC20(bridgeToken).safeTransferFrom(msg.sender, address(this), amount);\n uint256 canonicalOut = amount;\n // Computing fees\n if (isFeeExempt[msg.sender] == 0) {\n canonicalOut -= (canonicalOut * bridgeDetails.fee) / BASE_PARAMS;\n }\n _mint(to, canonicalOut);\n return canonicalOut;\n }\n\n /// @notice Burns the canonical token in exchange for a bridge token\n /// @param bridgeToken Bridge token required\n /// @param amount Amount of canonical tokens to burn\n /// @param to Address to which the bridge token should be sent\n /// @dev Some fees may be taken by the protocol depending on the token used and on the address calling\n function swapOut(address bridgeToken, uint256 amount, address to) external returns (uint256) {\n BridgeDetails memory bridgeDetails = bridges[bridgeToken];\n if (!bridgeDetails.allowed || bridgeDetails.paused) revert InvalidToken();\n\n _burnCustom(msg.sender, amount);\n uint256 bridgeOut = amount;\n if (isFeeExempt[msg.sender] == 0) {\n bridgeOut -= (bridgeOut * bridgeDetails.fee) / BASE_PARAMS;\n }\n IERC20(bridgeToken).safeTransfer(to, bridgeOut);\n return bridgeOut;\n }\n\n // ======================= Governance Functions ================================\n\n /// @notice Adds support for a bridge token\n /// @param bridgeToken Bridge token to add: it should be a version of the stablecoin from another bridge\n /// @param limit Limit on the balance of bridge token this contract could hold\n /// @param hourlyLimit Limit on the hourly volume for this bridge\n /// @param paused Whether swapping for this token should be paused or not\n /// @param fee Fee taken upon swapping for or against this token\n function addBridgeToken(\n address bridgeToken,\n uint256 limit,\n uint256 hourlyLimit,\n uint64 fee,\n bool paused\n ) external onlyGovernor {\n if (bridges[bridgeToken].allowed || bridgeToken == address(0)) revert InvalidToken();\n if (fee > BASE_PARAMS) revert TooHighParameterValue();\n BridgeDetails memory _bridge;\n _bridge.limit = limit;\n _bridge.hourlyLimit = hourlyLimit;\n _bridge.paused = paused;\n _bridge.fee = fee;\n _bridge.allowed = true;\n bridges[bridgeToken] = _bridge;\n bridgeTokensList.push(bridgeToken);\n emit BridgeTokenAdded(bridgeToken, limit, hourlyLimit, fee, paused);\n }\n\n /// @notice Removes support for a token\n /// @param bridgeToken Address of the bridge token to remove support for\n function removeBridgeToken(address bridgeToken) external onlyGovernor {\n if (IERC20(bridgeToken).balanceOf(address(this)) != 0) revert AssetStillControlledInReserves();\n delete bridges[bridgeToken];\n // Deletion from `bridgeTokensList` loop\n uint256 bridgeTokensListLength = bridgeTokensList.length;\n for (uint256 i; i < bridgeTokensListLength - 1; ++i) {\n if (bridgeTokensList[i] == bridgeToken) {\n // Replace the `bridgeToken` to remove with the last of the list\n bridgeTokensList[i] = bridgeTokensList[bridgeTokensListLength - 1];\n break;\n }\n }\n // Remove last element in array\n bridgeTokensList.pop();\n emit BridgeTokenRemoved(bridgeToken);\n }\n\n /// @notice Recovers any ERC20 token\n /// @dev Can be used to withdraw bridge tokens for them to be de-bridged on mainnet\n function recoverERC20(address tokenAddress, address to, uint256 amountToRecover) external onlyGovernor {\n IERC20(tokenAddress).safeTransfer(to, amountToRecover);\n emit Recovered(tokenAddress, to, amountToRecover);\n }\n\n /// @notice Updates the `limit` amount for `bridgeToken`\n function setLimit(address bridgeToken, uint256 limit) external onlyGovernorOrGuardian {\n if (!bridges[bridgeToken].allowed) revert InvalidToken();\n bridges[bridgeToken].limit = limit;\n emit BridgeTokenLimitUpdated(bridgeToken, limit);\n }\n\n /// @notice Updates the `hourlyLimit` amount for `bridgeToken`\n function setHourlyLimit(address bridgeToken, uint256 hourlyLimit) external onlyGovernorOrGuardian {\n if (!bridges[bridgeToken].allowed) revert InvalidToken();\n bridges[bridgeToken].hourlyLimit = hourlyLimit;\n emit BridgeTokenHourlyLimitUpdated(bridgeToken, hourlyLimit);\n }\n\n /// @notice Updates the `fee` value for `bridgeToken`\n function setSwapFee(address bridgeToken, uint64 fee) external onlyGovernorOrGuardian {\n if (!bridges[bridgeToken].allowed) revert InvalidToken();\n if (fee > BASE_PARAMS) revert TooHighParameterValue();\n bridges[bridgeToken].fee = fee;\n emit BridgeTokenFeeUpdated(bridgeToken, fee);\n }\n\n /// @notice Pauses or unpauses swapping in and out for a token\n function toggleBridge(address bridgeToken) external onlyGovernorOrGuardian {\n if (!bridges[bridgeToken].allowed) revert InvalidToken();\n bool pausedStatus = bridges[bridgeToken].paused;\n bridges[bridgeToken].paused = !pausedStatus;\n emit BridgeTokenToggled(bridgeToken, !pausedStatus);\n }\n\n /// @notice Toggles fees for the address `theAddress`\n function toggleFeesForAddress(address theAddress) external onlyGovernorOrGuardian {\n uint256 feeExemptStatus = 1 - isFeeExempt[theAddress];\n isFeeExempt[theAddress] = feeExemptStatus;\n emit FeeToggled(theAddress, feeExemptStatus);\n }\n}\n" + }, + "contracts/mock/MockRouter.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\nimport \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\nimport \"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\";\n\nimport \"../interfaces/IAngleRouter.sol\";\nimport \"../interfaces/external/uniswap/IUniswapRouter.sol\";\nimport \"../interfaces/external/lido/IWStETH.sol\";\n\ncontract MockRouter is IUniswapV3Router, IWStETH {\n using SafeERC20 for IERC20;\n\n uint256 public counterAngleMint;\n uint256 public counterAngleBurn;\n uint256 public counter1Inch;\n uint256 public counterUni;\n uint256 public counterWrap;\n uint256 public counterMixer;\n uint256 public amountOutUni;\n uint256 public multiplierMintBurn;\n uint256 public stETHMultiplier;\n address public inToken;\n address public outToken;\n\n address public stETH;\n\n /// @notice Action types\n enum ActionType {\n transfer,\n wrap,\n wrapNative,\n sweep,\n sweepNative,\n unwrap,\n unwrapNative,\n swapIn,\n swapOut,\n uniswapV3,\n oneInch,\n claimRewards,\n gaugeDeposit,\n borrower\n }\n\n /// @notice Data needed to get permits\n struct PermitType {\n address token;\n address owner;\n uint256 value;\n uint256 deadline;\n uint8 v;\n bytes32 r;\n bytes32 s;\n }\n\n constructor() {}\n\n function mint(address user, uint256 amount, uint256, address stablecoin, address collateral) external {\n counterAngleMint += 1;\n IERC20(collateral).safeTransferFrom(msg.sender, address(this), amount);\n IERC20(stablecoin).safeTransfer(user, (amount * 10 ** 9) / multiplierMintBurn);\n }\n\n function setStETH(address _stETH) external {\n stETH = _stETH;\n }\n\n function burn(address user, uint256 amount, uint256, address stablecoin, address collateral) external {\n counterAngleBurn += 1;\n IERC20(stablecoin).safeTransferFrom(msg.sender, address(this), amount);\n IERC20(collateral).safeTransfer(user, (amount * multiplierMintBurn) / 10 ** 9);\n }\n\n function mixer(\n PermitType[] memory paramsPermit,\n ActionType[] memory actions,\n bytes[] calldata data\n ) public payable virtual {\n paramsPermit;\n counterMixer += 1;\n for (uint256 i; i < actions.length; ++i) {\n if (actions[i] == ActionType.transfer) {\n (address transferToken, uint256 amount) = abi.decode(data[i], (address, uint256));\n IERC20(transferToken).safeTransferFrom(msg.sender, address(this), amount);\n }\n }\n }\n\n function wrap(uint256 amount) external returns (uint256 amountOut) {\n amountOut = (amount * stETHMultiplier) / 10 ** 9;\n counterWrap += 1;\n IERC20(stETH).safeTransferFrom(msg.sender, address(this), amount);\n IERC20(outToken).safeTransfer(msg.sender, amountOut);\n }\n\n function oneInch(uint256 amountIn) external returns (uint256 amountOut) {\n counter1Inch += 1;\n amountOut = (amountOutUni * amountIn) / 10 ** 9;\n IERC20(inToken).safeTransferFrom(msg.sender, address(this), amountIn);\n IERC20(outToken).safeTransfer(msg.sender, amountOut);\n }\n\n function oneInchReverts() external {\n counter1Inch += 1;\n revert(\"wrong swap\");\n }\n\n function oneInchRevertsWithoutMessage() external {\n counter1Inch += 1;\n require(false);\n }\n\n function exactInput(ExactInputParams calldata params) external payable returns (uint256 amountOut) {\n counterUni += 1;\n amountOut = (params.amountIn * amountOutUni) / 10 ** 9;\n IERC20(inToken).safeTransferFrom(msg.sender, address(this), params.amountIn);\n IERC20(outToken).safeTransfer(params.recipient, amountOut);\n require(amountOut >= params.amountOutMinimum);\n }\n\n function setMultipliers(uint256 a, uint256 b) external {\n amountOutUni = a;\n multiplierMintBurn = b;\n }\n\n function setStETHMultiplier(uint256 value) external {\n stETHMultiplier = value;\n }\n\n function setInOut(address _collateral, address _stablecoin) external {\n inToken = _collateral;\n outToken = _stablecoin;\n }\n}\n" + }, + "contracts/mock/MockSidechainAgEUR.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\nimport \"../agToken/AgToken.sol\";\nimport \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\nimport \"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\";\n\n/// @title AgTokenSideChainMultiBridge\n/// @author Angle Labs, Inc.\n/// @notice Contract for Angle agTokens on other chains than Ethereum mainnet\n/// @dev This contract supports bridge tokens having a minting right on the stablecoin (also referred to as the canonical\n/// or the native token)\n/// @dev References:\n/// - FRAX implementation: https://polygonscan.com/address/0x45c32fA6DF82ead1e2EF74d17b76547EDdFaFF89#code\n/// - QiDAO implementation: https://snowtrace.io/address/0x5c49b268c9841AFF1Cc3B0a418ff5c3442eE3F3b#code\ncontract MockSidechainAgEUR is AgToken {\n using SafeERC20 for IERC20;\n\n /// @notice Base used for fee computation\n uint256 public constant BASE_PARAMS = 10 ** 9;\n\n // =============================== Bridging Data ===============================\n\n /// @notice Struct with some data about a specific bridge token\n struct BridgeDetails {\n // Limit on the balance of bridge token held by the contract: it is designed\n // to reduce the exposure of the system to hacks\n uint256 limit;\n // Limit on the hourly volume of token minted through this bridge\n // Technically the limit over a rolling hour is hourlyLimit x2 as hourly limit\n // is enforced only between x:00 and x+1:00\n uint256 hourlyLimit;\n // Fee taken for swapping in and out the token\n uint64 fee;\n // Whether the associated token is allowed or not\n bool allowed;\n // Whether swapping in and out from the associated token is paused or not\n bool paused;\n }\n\n /// @notice Maps a bridge token to data\n mapping(address => BridgeDetails) public bridges;\n /// @notice List of all bridge tokens\n address[] public bridgeTokensList;\n /// @notice Maps a bridge token to the associated hourly volume\n mapping(address => mapping(uint256 => uint256)) public usage;\n /// @notice Maps an address to whether it is exempt of fees for when it comes to swapping in and out\n mapping(address => uint256) public isFeeExempt;\n\n // ================================== Events ===================================\n\n event BridgeTokenAdded(address indexed bridgeToken, uint256 limit, uint256 hourlyLimit, uint64 fee, bool paused);\n event BridgeTokenToggled(address indexed bridgeToken, bool toggleStatus);\n event BridgeTokenRemoved(address indexed bridgeToken);\n event BridgeTokenFeeUpdated(address indexed bridgeToken, uint64 fee);\n event BridgeTokenLimitUpdated(address indexed bridgeToken, uint256 limit);\n event BridgeTokenHourlyLimitUpdated(address indexed bridgeToken, uint256 hourlyLimit);\n event HourlyLimitUpdated(uint256 hourlyLimit);\n event Recovered(address indexed token, address indexed to, uint256 amount);\n event FeeToggled(address indexed theAddress, uint256 toggleStatus);\n\n // =============================== Errors ================================\n\n error AssetStillControlledInReserves();\n error HourlyLimitExceeded();\n error InvalidToken();\n error NotGovernor();\n error NotGovernorOrGuardian();\n error TooBigAmount();\n error TooHighParameterValue();\n error ZeroAddress();\n\n // ============================= Constructor ===================================\n\n /// @notice Checks whether the `msg.sender` has the governor role or not\n modifier onlyGovernor() {\n if (!ITreasury(treasury).isGovernor(msg.sender)) revert NotGovernor();\n _;\n }\n\n /// @notice Checks whether the `msg.sender` has the governor role or the guardian role\n modifier onlyGovernorOrGuardian() {\n if (!ITreasury(treasury).isGovernorOrGuardian(msg.sender)) revert NotGovernorOrGuardian();\n _;\n }\n\n // ==================== External Permissionless Functions ======================\n\n /// @notice Returns the list of all supported bridge tokens\n /// @dev Helpful for UIs\n function allBridgeTokens() external view returns (address[] memory) {\n return bridgeTokensList;\n }\n\n /// @notice Returns the current volume for a bridge, for the current hour\n /// @param bridgeToken Bridge used to mint\n /// @dev Helpful for UIs\n function currentUsage(address bridgeToken) external view returns (uint256) {\n return usage[bridgeToken][block.timestamp / 3600];\n }\n\n /// @notice Mints the canonical token from a supported bridge token\n /// @param bridgeToken Bridge token to use to mint\n /// @param amount Amount of bridge tokens to send\n /// @param to Address to which the stablecoin should be sent\n /// @return Amount of the canonical stablecoin actually minted\n /// @dev Some fees may be taken by the protocol depending on the token used and on the address calling\n function swapIn(address bridgeToken, uint256 amount, address to) external returns (uint256) {\n BridgeDetails memory bridgeDetails = bridges[bridgeToken];\n if (!bridgeDetails.allowed || bridgeDetails.paused) revert InvalidToken();\n uint256 balance = IERC20(bridgeToken).balanceOf(address(this));\n if (balance + amount > bridgeDetails.limit) {\n // In case someone maliciously sends tokens to this contract\n // Or the limit changes\n if (bridgeDetails.limit > balance) amount = bridgeDetails.limit - balance;\n else {\n amount = 0;\n }\n }\n\n // Checking requirement on the hourly volume\n uint256 hour = block.timestamp / 3600;\n uint256 hourlyUsage = usage[bridgeToken][hour] + amount;\n if (hourlyUsage > bridgeDetails.hourlyLimit) {\n // Edge case when the hourly limit changes\n if (bridgeDetails.hourlyLimit > usage[bridgeToken][hour])\n amount = bridgeDetails.hourlyLimit - usage[bridgeToken][hour];\n else {\n amount = 0;\n }\n }\n usage[bridgeToken][hour] = usage[bridgeToken][hour] + amount;\n\n IERC20(bridgeToken).safeTransferFrom(msg.sender, address(this), amount);\n uint256 canonicalOut = amount;\n // Computing fees\n if (isFeeExempt[msg.sender] == 0) {\n canonicalOut -= (canonicalOut * bridgeDetails.fee) / BASE_PARAMS;\n }\n _mint(to, canonicalOut);\n return canonicalOut;\n }\n\n /// @notice Burns the canonical token in exchange for a bridge token\n /// @param bridgeToken Bridge token required\n /// @param amount Amount of canonical tokens to burn\n /// @param to Address to which the bridge token should be sent\n /// @return Amount of bridge tokens actually sent back\n /// @dev Some fees may be taken by the protocol depending on the token used and on the address calling\n function swapOut(address bridgeToken, uint256 amount, address to) external returns (uint256) {\n BridgeDetails memory bridgeDetails = bridges[bridgeToken];\n if (!bridgeDetails.allowed || bridgeDetails.paused) revert InvalidToken();\n\n _burn(msg.sender, amount);\n uint256 bridgeOut = amount;\n if (isFeeExempt[msg.sender] == 0) {\n bridgeOut -= (bridgeOut * bridgeDetails.fee) / BASE_PARAMS;\n }\n IERC20(bridgeToken).safeTransfer(to, bridgeOut);\n return bridgeOut;\n }\n\n // ======================= Governance Functions ================================\n\n /// @notice Adds support for a bridge token\n /// @param bridgeToken Bridge token to add: it should be a version of the stablecoin from another bridge\n /// @param limit Limit on the balance of bridge token this contract could hold\n /// @param hourlyLimit Limit on the hourly volume for this bridge\n /// @param paused Whether swapping for this token should be paused or not\n /// @param fee Fee taken upon swapping for or against this token\n function addBridgeToken(\n address bridgeToken,\n uint256 limit,\n uint256 hourlyLimit,\n uint64 fee,\n bool paused\n ) external onlyGovernor {\n if (bridges[bridgeToken].allowed || bridgeToken == address(0)) revert InvalidToken();\n if (fee > BASE_PARAMS) revert TooHighParameterValue();\n BridgeDetails memory _bridge;\n _bridge.limit = limit;\n _bridge.hourlyLimit = hourlyLimit;\n _bridge.paused = paused;\n _bridge.fee = fee;\n _bridge.allowed = true;\n bridges[bridgeToken] = _bridge;\n bridgeTokensList.push(bridgeToken);\n emit BridgeTokenAdded(bridgeToken, limit, hourlyLimit, fee, paused);\n }\n\n /// @notice Removes support for a token\n /// @param bridgeToken Address of the bridge token to remove support for\n function removeBridgeToken(address bridgeToken) external onlyGovernor {\n if (IERC20(bridgeToken).balanceOf(address(this)) != 0) revert AssetStillControlledInReserves();\n delete bridges[bridgeToken];\n // Deletion from `bridgeTokensList` loop\n uint256 bridgeTokensListLength = bridgeTokensList.length;\n for (uint256 i; i < bridgeTokensListLength - 1; ++i) {\n if (bridgeTokensList[i] == bridgeToken) {\n // Replace the `bridgeToken` to remove with the last of the list\n bridgeTokensList[i] = bridgeTokensList[bridgeTokensListLength - 1];\n break;\n }\n }\n // Remove last element in array\n bridgeTokensList.pop();\n emit BridgeTokenRemoved(bridgeToken);\n }\n\n /// @notice Recovers any ERC20 token\n /// @dev Can be used to withdraw bridge tokens for them to be de-bridged on mainnet\n function recoverERC20(address tokenAddress, address to, uint256 amountToRecover) external onlyGovernor {\n IERC20(tokenAddress).safeTransfer(to, amountToRecover);\n emit Recovered(tokenAddress, to, amountToRecover);\n }\n\n /// @notice Updates the `limit` amount for `bridgeToken`\n function setLimit(address bridgeToken, uint256 limit) external onlyGovernorOrGuardian {\n if (!bridges[bridgeToken].allowed) revert InvalidToken();\n bridges[bridgeToken].limit = limit;\n emit BridgeTokenLimitUpdated(bridgeToken, limit);\n }\n\n /// @notice Updates the `hourlyLimit` amount for `bridgeToken`\n function setHourlyLimit(address bridgeToken, uint256 hourlyLimit) external onlyGovernorOrGuardian {\n if (!bridges[bridgeToken].allowed) revert InvalidToken();\n bridges[bridgeToken].hourlyLimit = hourlyLimit;\n emit BridgeTokenHourlyLimitUpdated(bridgeToken, hourlyLimit);\n }\n\n /// @notice Updates the `fee` value for `bridgeToken`\n function setSwapFee(address bridgeToken, uint64 fee) external onlyGovernorOrGuardian {\n if (!bridges[bridgeToken].allowed) revert InvalidToken();\n if (fee > BASE_PARAMS) revert TooHighParameterValue();\n bridges[bridgeToken].fee = fee;\n emit BridgeTokenFeeUpdated(bridgeToken, fee);\n }\n\n /// @notice Pauses or unpauses swapping in and out for a token\n function toggleBridge(address bridgeToken) external onlyGovernorOrGuardian {\n if (!bridges[bridgeToken].allowed) revert InvalidToken();\n bool pausedStatus = bridges[bridgeToken].paused;\n bridges[bridgeToken].paused = !pausedStatus;\n emit BridgeTokenToggled(bridgeToken, !pausedStatus);\n }\n\n /// @notice Toggles fees for the address `theAddress`\n function toggleFeesForAddress(address theAddress) external onlyGovernorOrGuardian {\n uint256 feeExemptStatus = 1 - isFeeExempt[theAddress];\n isFeeExempt[theAddress] = feeExemptStatus;\n emit FeeToggled(theAddress, feeExemptStatus);\n }\n}\n" + }, + "contracts/mock/MockStableMaster.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\nimport \"../interfaces/IAgToken.sol\";\nimport \"./MockToken.sol\";\nimport \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\nimport \"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\";\nimport { SLPData, MintBurnData } from \"../interfaces/coreModule/IStableMaster.sol\";\n\n// All the details about a collateral that are going to be stored in `StableMaster`\nstruct Collateral {\n // Interface for the token accepted by the underlying `PoolManager` contract\n IERC20 token;\n // Reference to the `SanToken` for the pool\n MockToken sanToken;\n // Reference to the `PerpetualManager` for the pool\n address perpetualManager;\n // Adress of the oracle for the change rate between\n // collateral and the corresponding stablecoin\n address oracle;\n // Amount of collateral in the reserves that comes from users\n // converted in stablecoin value. Updated at minting and burning.\n // A `stocksUsers` of 10 for a collateral type means that overall the balance of the collateral from users\n // that minted/burnt stablecoins using this collateral is worth 10 of stablecoins\n uint256 stocksUsers;\n // Exchange rate between sanToken and collateral\n uint256 sanRate;\n // Base used in the collateral implementation (ERC20 decimal)\n uint256 collatBase;\n // Parameters for SLPs and update of the `sanRate`\n SLPData slpData;\n // All the fees parameters\n MintBurnData feeData;\n}\n\ncontract MockStableMaster {\n mapping(address => uint256) public poolManagerMap;\n\n constructor() {}\n\n function updateStocksUsers(uint256 amount, address poolManager) external {\n poolManagerMap[poolManager] += amount;\n }\n\n function burnSelf(IAgToken agToken, uint256 amount, address burner) external {\n agToken.burnSelf(amount, burner);\n }\n\n function burnFrom(IAgToken agToken, uint256 amount, address burner, address sender) external {\n agToken.burnFrom(amount, burner, sender);\n }\n\n function mint(IAgToken agToken, address account, uint256 amount) external {\n agToken.mint(account, amount);\n }\n}\n\ncontract MockStableMasterSanWrapper is MockStableMaster {\n using SafeERC20 for IERC20;\n\n /// @notice Maps a `PoolManager` contract handling a collateral for this stablecoin to the properties of the struct above\n mapping(address => Collateral) public collateralMap;\n\n constructor() MockStableMaster() {}\n\n uint256 internal constant _BASE_TOKENS = 10 ** 18;\n uint256 internal constant _BASE_PARAMS = 10 ** 9;\n IERC20 public token;\n\n function deposit(uint256 assets, address receiver, address poolManager) external {\n token.safeTransferFrom(msg.sender, address(this), assets);\n Collateral storage col = collateralMap[poolManager];\n _updateSanRate(col);\n uint256 amount = (assets * _BASE_TOKENS) / col.sanRate;\n col.sanToken.mint(receiver, amount);\n }\n\n function withdraw(uint256 assets, address sender, address receiver, address poolManager) external {\n Collateral storage col = collateralMap[poolManager];\n _updateSanRate(col);\n col.sanToken.burn(sender, assets);\n // Computing the amount of collateral to give back to the SLP depending on slippage and on the `sanRate`\n uint256 redeemInC = (assets * (_BASE_PARAMS - col.slpData.slippage) * col.sanRate) /\n (_BASE_TOKENS * _BASE_PARAMS);\n token.safeTransfer(receiver, redeemInC);\n }\n\n function setPoolManagerToken(address, address token_) external {\n token = MockToken(token_);\n }\n\n function setPoolManagerSanToken(address poolManager, address sanToken_) external {\n Collateral storage col = collateralMap[poolManager];\n col.sanToken = MockToken(sanToken_);\n }\n\n function setSanRate(address poolManager, uint256 sanRate_) external {\n Collateral storage col = collateralMap[poolManager];\n col.sanRate = sanRate_;\n }\n\n function _updateSanRate(Collateral storage col) internal {\n uint256 _lockedInterests = col.slpData.lockedInterests;\n // Checking if the `sanRate` has been updated in the current block using past block fees\n // This is a way to prevent flash loans attacks when an important amount of fees are going to be distributed\n // in a block: fees are stored but will just be distributed to SLPs who will be here during next blocks\n if (block.timestamp != col.slpData.lastBlockUpdated && _lockedInterests > 0) {\n uint256 sanMint = col.sanToken.totalSupply();\n if (sanMint != 0) {\n // Checking if the update is too important and should be made in multiple blocks\n if (_lockedInterests > col.slpData.maxInterestsDistributed) {\n // `sanRate` is expressed in `BASE_TOKENS`\n col.sanRate += (col.slpData.maxInterestsDistributed * 10 ** 18) / sanMint;\n _lockedInterests -= col.slpData.maxInterestsDistributed;\n } else {\n col.sanRate += (_lockedInterests * 10 ** 18) / sanMint;\n _lockedInterests = 0;\n }\n } else {\n _lockedInterests = 0;\n }\n }\n col.slpData.lockedInterests = _lockedInterests;\n col.slpData.lastBlockUpdated = block.timestamp;\n }\n\n // copy paste from the deployed contract\n function estimateSanRate(address poolManager) external view returns (uint256 sanRate, uint64 slippage) {\n Collateral memory col = collateralMap[poolManager];\n uint256 _lockedInterests = col.slpData.lockedInterests;\n // Checking if the `sanRate` has been updated in the current block using past block fees\n // This is a way to prevent flash loans attacks when an important amount of fees are going to be distributed\n // in a block: fees are stored but will just be distributed to SLPs who will be here during next blocks\n if (block.timestamp != col.slpData.lastBlockUpdated && _lockedInterests > 0) {\n uint256 sanMint = col.sanToken.totalSupply();\n if (sanMint != 0) {\n // Checking if the update is too important and should be made in multiple blocks\n if (_lockedInterests > col.slpData.maxInterestsDistributed) {\n // `sanRate` is expressed in `BASE_TOKENS`\n col.sanRate += (col.slpData.maxInterestsDistributed * 10 ** 18) / sanMint;\n _lockedInterests -= col.slpData.maxInterestsDistributed;\n } else {\n col.sanRate += (_lockedInterests * 10 ** 18) / sanMint;\n _lockedInterests = 0;\n }\n } else {\n _lockedInterests = 0;\n }\n }\n return (col.sanRate, col.slpData.slippage);\n }\n\n function setSLPData(\n address poolManager,\n uint256 lockedInterests,\n uint256 maxInterestsDistributed,\n uint64 slippage\n ) external {\n Collateral storage col = collateralMap[poolManager];\n col.slpData.lockedInterests = lockedInterests;\n col.slpData.maxInterestsDistributed = maxInterestsDistributed;\n col.slpData.slippage = slippage;\n }\n}\n" + }, + "contracts/mock/MockSwapper.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\nimport \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\nimport \"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\";\n\nimport \"../interfaces/ISwapper.sol\";\n\ncontract MockSwapper is ISwapper {\n bytes32 public constant CALLBACK_SUCCESS = keccak256(\"ERC3156FlashBorrower.onFlashLoan\");\n\n uint256 public counter;\n\n constructor() {}\n\n function swap(IERC20, IERC20, address, uint256, uint256, bytes calldata data) external {\n counter += 1;\n data;\n }\n}\n\ncontract MockSwapperWithSwap is ISwapper {\n using SafeERC20 for IERC20;\n bytes32 public constant CALLBACK_SUCCESS = keccak256(\"ERC3156FlashBorrower.onFlashLoan\");\n\n uint256 public counter;\n\n constructor() {}\n\n function swap(\n IERC20,\n IERC20 outToken,\n address outTokenRecipient,\n uint256 outTokenOwed,\n uint256,\n bytes calldata data\n ) external {\n counter += 1;\n outToken.safeTransfer(outTokenRecipient, outTokenOwed);\n\n data;\n }\n}\n" + }, + "contracts/mock/MockSwapperSidechain.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\nimport \"../swapper/Swapper.sol\";\n\n/// @title MockSwapperSidechain\n/// @author Angle Labs, Inc.\ncontract MockSwapperSidechain is Swapper {\n error NotImplemented();\n\n /// @notice Constructor of the contract\n /// @param _core Core address\n /// @param _uniV3Router UniswapV3 Router address\n /// @param _oneInch 1Inch Router address\n /// @param _angleRouter AngleRouter contract address\n constructor(\n ICoreBorrow _core,\n IUniswapV3Router _uniV3Router,\n address _oneInch,\n IAngleRouterSidechain _angleRouter\n ) Swapper(_core, _uniV3Router, _oneInch, _angleRouter) {}\n\n function _swapLeverage(bytes memory) internal pure override returns (uint256) {\n revert NotImplemented();\n }\n}\n" + }, + "contracts/mock/MockToken.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.7;\n\nimport \"@openzeppelin/contracts/token/ERC20/ERC20.sol\";\n\ncontract MockToken is ERC20 {\n event Minting(address indexed _to, address indexed _minter, uint256 _amount);\n\n event Burning(address indexed _from, address indexed _burner, uint256 _amount);\n\n uint8 internal _decimal;\n mapping(address => bool) public minters;\n address public treasury;\n\n constructor(string memory name_, string memory symbol_, uint8 decimal_) ERC20(name_, symbol_) {\n _decimal = decimal_;\n }\n\n function decimals() public view override returns (uint8) {\n return _decimal;\n }\n\n function mint(address account, uint256 amount) external {\n _mint(account, amount);\n emit Minting(account, msg.sender, amount);\n }\n\n function burn(address account, uint256 amount) public {\n _burn(account, amount);\n emit Burning(account, msg.sender, amount);\n }\n\n function setAllowance(address from, address to) public {\n _approve(from, to, type(uint256).max);\n }\n\n function burnSelf(uint256 amount, address account) public {\n _burn(account, amount);\n emit Burning(account, msg.sender, amount);\n }\n\n function addMinter(address minter) public {\n minters[minter] = true;\n }\n\n function removeMinter(address minter) public {\n minters[minter] = false;\n }\n\n function setTreasury(address _treasury) public {\n treasury = _treasury;\n }\n}\n" + }, + "contracts/mock/MockTokenPermit.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.7;\n\nimport \"@openzeppelin/contracts/token/ERC20/extensions/draft-ERC20Permit.sol\";\nimport \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\nimport \"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\";\n\ncontract MockTokenPermit is ERC20Permit {\n using SafeERC20 for IERC20;\n event Minting(address indexed _to, address indexed _minter, uint256 _amount);\n\n event Burning(address indexed _from, address indexed _burner, uint256 _amount);\n\n uint8 internal _decimal;\n mapping(address => bool) public minters;\n address public treasury;\n uint256 public fees;\n\n bool public reverts;\n\n constructor(string memory name_, string memory symbol_, uint8 decimal_) ERC20Permit(name_) ERC20(name_, symbol_) {\n _decimal = decimal_;\n }\n\n function decimals() public view override returns (uint8) {\n return _decimal;\n }\n\n function mint(address account, uint256 amount) external {\n _mint(account, amount);\n emit Minting(account, msg.sender, amount);\n }\n\n function burn(address account, uint256 amount) public {\n _burn(account, amount);\n emit Burning(account, msg.sender, amount);\n }\n\n function setAllowance(address from, address to) public {\n _approve(from, to, type(uint256).max);\n }\n\n function burnSelf(uint256 amount, address account) public {\n _burn(account, amount);\n emit Burning(account, msg.sender, amount);\n }\n\n function addMinter(address minter) public {\n minters[minter] = true;\n }\n\n function removeMinter(address minter) public {\n minters[minter] = false;\n }\n\n function setTreasury(address _treasury) public {\n treasury = _treasury;\n }\n\n function setFees(uint256 _fees) public {\n fees = _fees;\n }\n\n function recoverERC20(IERC20 token, address to, uint256 amount) external {\n token.safeTransfer(to, amount);\n }\n\n function swapIn(address bridgeToken, uint256 amount, address to) external returns (uint256) {\n require(!reverts);\n\n IERC20(bridgeToken).safeTransferFrom(msg.sender, address(this), amount);\n uint256 canonicalOut = amount;\n canonicalOut -= (canonicalOut * fees) / 10 ** 9;\n _mint(to, canonicalOut);\n return canonicalOut;\n }\n\n function swapOut(address bridgeToken, uint256 amount, address to) external returns (uint256) {\n require(!reverts);\n _burn(msg.sender, amount);\n uint256 bridgeOut = amount;\n bridgeOut -= (bridgeOut * fees) / 10 ** 9;\n IERC20(bridgeToken).safeTransfer(to, bridgeOut);\n return bridgeOut;\n }\n}\n" + }, + "contracts/mock/MockTreasury.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\nimport \"../interfaces/ITreasury.sol\";\nimport \"../interfaces/IFlashAngle.sol\";\nimport \"../interfaces/IVaultManager.sol\";\n\ncontract MockTreasury is ITreasury {\n IAgToken public override stablecoin;\n address public governor;\n address public guardian;\n address public vaultManager1;\n address public vaultManager2;\n address public flashLoanModule;\n address[] public vaultManagerList;\n\n constructor(\n IAgToken _stablecoin,\n address _governor,\n address _guardian,\n address _vaultManager1,\n address _vaultManager2,\n address _flashLoanModule\n ) {\n stablecoin = _stablecoin;\n governor = _governor;\n guardian = _guardian;\n vaultManager1 = _vaultManager1;\n vaultManager2 = _vaultManager2;\n flashLoanModule = _flashLoanModule;\n }\n\n function isGovernor(address admin) external view override returns (bool) {\n return (admin == governor);\n }\n\n function isGovernorOrGuardian(address admin) external view override returns (bool) {\n return (admin == governor || admin == guardian);\n }\n\n function isVaultManager(address _vaultManager) external view override returns (bool) {\n return (_vaultManager == vaultManager1 || _vaultManager == vaultManager2);\n }\n\n function setStablecoin(IAgToken _stablecoin) external {\n stablecoin = _stablecoin;\n }\n\n function setFlashLoanModule(address _flashLoanModule) external override {\n flashLoanModule = _flashLoanModule;\n }\n\n function setGovernor(address _governor) external {\n governor = _governor;\n }\n\n function setVaultManager(address _vaultManager) external {\n vaultManager1 = _vaultManager;\n }\n\n function setVaultManager2(address _vaultManager) external {\n vaultManager2 = _vaultManager;\n }\n\n function setTreasury(address _agTokenOrVaultManager, address _treasury) external {\n IAgToken(_agTokenOrVaultManager).setTreasury(_treasury);\n }\n\n function addMinter(IAgToken _agToken, address _minter) external {\n _agToken.addMinter(_minter);\n }\n\n function removeMinter(IAgToken _agToken, address _minter) external {\n _agToken.removeMinter(_minter);\n }\n\n function accrueInterestToTreasury(IFlashAngle flashAngle) external returns (uint256 balance) {\n balance = flashAngle.accrueInterestToTreasury(stablecoin);\n }\n\n function accrueInterestToTreasuryVaultManager(IVaultManager _vaultManager) external returns (uint256, uint256) {\n return _vaultManager.accrueInterestToTreasury();\n }\n}\n" + }, + "contracts/mock/MockUniswapV3Pool.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.7;\n\ncontract MockUniswapV3Pool {\n address public token0;\n address public token1;\n uint32 public constant EPOCH_DURATION = 24 * 3600 * 7;\n\n function setToken(address token, uint256 who) external {\n if (who == 0) token0 = token;\n else token1 = token;\n }\n\n function round(uint256 amount) external pure returns (uint256) {\n return (amount / EPOCH_DURATION) * EPOCH_DURATION;\n }\n}\n" + }, + "contracts/mock/MockVaultManager.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\nimport \"../interfaces/IVaultManager.sol\";\nimport \"../interfaces/ITreasury.sol\";\nimport \"@openzeppelin/contracts/token/ERC20/ERC20.sol\";\n\ncontract MockVaultManager {\n ITreasury public treasury;\n mapping(uint256 => Vault) public vaultData;\n mapping(uint256 => address) public ownerOf;\n uint256 public surplus;\n uint256 public badDebt;\n IAgToken public token;\n address public oracle = address(this);\n\n address public governor;\n address public collateral;\n address public stablecoin;\n uint256 public oracleValue;\n uint256 public interestAccumulator;\n uint256 public collateralFactor;\n uint256 public totalNormalizedDebt;\n\n constructor(address _treasury) {\n treasury = ITreasury(_treasury);\n }\n\n function accrueInterestToTreasury() external returns (uint256, uint256) {\n // Avoid the function to be view\n if (surplus >= badDebt) {\n token.mint(msg.sender, surplus - badDebt);\n }\n return (surplus, badDebt);\n }\n\n function read() external view returns (uint256) {\n return oracleValue;\n }\n\n function setParams(\n address _governor,\n address _collateral,\n address _stablecoin,\n uint256 _oracleValue,\n uint256 _interestAccumulator,\n uint256 _collateralFactor,\n uint256 _totalNormalizedDebt\n ) external {\n governor = _governor;\n collateral = _collateral;\n stablecoin = _stablecoin;\n interestAccumulator = _interestAccumulator;\n collateralFactor = _collateralFactor;\n totalNormalizedDebt = _totalNormalizedDebt;\n oracleValue = _oracleValue;\n }\n\n function setOwner(uint256 vaultID, address owner) external virtual {\n ownerOf[vaultID] = owner;\n }\n\n function setVaultData(uint256 normalizedDebt, uint256 collateralAmount, uint256 vaultID) external {\n vaultData[vaultID].normalizedDebt = normalizedDebt;\n vaultData[vaultID].collateralAmount = collateralAmount;\n }\n\n function isGovernor(address admin) external view returns (bool) {\n return admin == governor;\n }\n\n function setSurplusBadDebt(uint256 _surplus, uint256 _badDebt, IAgToken _token) external {\n surplus = _surplus;\n badDebt = _badDebt;\n token = _token;\n }\n\n function getDebtOut(uint256 vaultID, uint256 amountStablecoins, uint256 senderBorrowFee) external {}\n\n function setTreasury(address _treasury) external {\n treasury = ITreasury(_treasury);\n }\n\n function getVaultDebt(uint256 vaultID) external view returns (uint256) {\n vaultID;\n token;\n return 0;\n }\n\n function createVault(address toVault) external view returns (uint256) {\n toVault;\n token;\n return 0;\n }\n}\n\ncontract MockVaultManagerListing is MockVaultManager {\n // @notice Mapping from owner address to all his vaults\n mapping(address => uint256[]) internal _ownerListVaults;\n\n constructor(address _treasury) MockVaultManager(_treasury) {}\n\n function getUserVaults(address owner) public view returns (uint256[] memory) {\n return _ownerListVaults[owner];\n }\n\n function getUserCollateral(address owner) public view returns (uint256 totalCollateral) {\n uint256[] memory vaultList = _ownerListVaults[owner];\n uint256 vaultListLength = vaultList.length;\n for (uint256 k; k < vaultListLength; ++k) {\n totalCollateral += vaultData[vaultList[k]].collateralAmount;\n }\n return totalCollateral;\n }\n\n function setOwner(uint256 vaultID, address owner) external override {\n if (ownerOf[vaultID] != address(0)) _removeVaultFromList(ownerOf[vaultID], vaultID);\n _ownerListVaults[owner].push(vaultID);\n ownerOf[vaultID] = owner;\n }\n\n /// @notice Remove `vaultID` from `user` stroed vault list\n /// @param user Address to look out for the vault list\n /// @param vaultID VaultId to remove from the list\n /// @dev The vault is necessarily in the list\n function _removeVaultFromList(address user, uint256 vaultID) internal {\n uint256[] storage vaultList = _ownerListVaults[user];\n uint256 vaultListLength = vaultList.length;\n for (uint256 i; i < vaultListLength - 1; ++i) {\n if (vaultList[i] == vaultID) {\n vaultList[i] = vaultList[vaultListLength - 1];\n break;\n }\n }\n vaultList.pop();\n }\n}\n" + }, + "contracts/mock/MockVeBoostProxy.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\nimport \"../interfaces/governance/IVeBoostProxy.sol\";\n\ncontract MockVeBoostProxy is IVeBoostProxy {\n //solhint-disable-next-line\n mapping(address => uint256) public adjusted_balance_of;\n\n constructor() {}\n\n function setBalance(address concerned, uint256 balance) external {\n adjusted_balance_of[concerned] = balance;\n }\n}\n" + }, + "contracts/oracle/BaseOracleChainlinkMulti.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\n/*\n * █ \n ***** ▓▓▓ \n * ▓▓▓▓▓▓▓ \n * ///. ▓▓▓▓▓▓▓▓▓▓▓▓▓ \n ***** //////// ▓▓▓▓▓▓▓ \n * ///////////// ▓▓▓ \n ▓▓ ////////////////// █ ▓▓ \n ▓▓ ▓▓ /////////////////////// ▓▓ ▓▓ \n ▓▓ ▓▓ //////////////////////////// ▓▓ ▓▓ \n ▓▓ ▓▓ /////////▓▓▓///////▓▓▓///////// ▓▓ ▓▓ \n ▓▓ ,////////////////////////////////////// ▓▓ ▓▓ \n ▓▓ ////////////////////////////////////////// ▓▓ \n ▓▓ //////////////////////▓▓▓▓///////////////////// \n ,//////////////////////////////////////////////////// \n .////////////////////////////////////////////////////////// \n .//////////////////////////██.,//////////////////////////█ \n .//////////////////////████..,./////////////////////██ \n ...////////////////███████.....,.////////////////███ \n ,.,////////////████████ ........,///////////████ \n .,.,//////█████████ ,.......///////████ \n ,..//████████ ........./████ \n ..,██████ .....,███ \n .██ ,.,█ \n \n \n \n ▓▓ ▓▓▓▓▓▓▓▓▓▓ ▓▓▓▓▓▓▓▓▓▓ ▓▓ ▓▓▓▓▓▓▓▓▓▓ \n ▓▓▓▓▓▓ ▓▓▓ ▓▓▓ ▓▓▓ ▓▓ ▓▓ ▓▓▓▓ \n ▓▓▓ ▓▓▓ ▓▓▓ ▓▓▓ ▓▓▓ ▓▓▓ ▓▓ ▓▓▓▓▓ \n ▓▓▓ ▓▓ ▓▓▓ ▓▓▓ ▓▓▓▓▓▓▓▓▓▓ ▓▓▓▓▓▓▓▓▓▓ ▓▓▓▓▓▓▓▓▓▓ \n*/\n\npragma solidity ^0.8.12;\n\nimport \"@chainlink/contracts/src/v0.8/interfaces/AggregatorV3Interface.sol\";\n\nimport \"../interfaces/IOracle.sol\";\nimport \"../interfaces/ITreasury.sol\";\n\n/// @title BaseOracleChainlinkMulti\n/// @author Angle Labs, Inc.\n/// @notice Base Contract to be overriden by all contracts of the protocol\n/// @dev This base contract concerns an oracle that uses Chainlink with multiple pools to read from\n/// @dev All gas-efficient implementation of the `OracleChainlinkMulti` contract should inherit from this\nabstract contract BaseOracleChainlinkMulti is IOracle {\n // ========================= Parameters and References =========================\n\n /// @inheritdoc IOracle\n ITreasury public override treasury;\n /// @notice Represent the maximum amount of time (in seconds) between each Chainlink update\n /// before the price feed is considered stale\n uint32 public stalePeriod;\n\n // =================================== Event ===================================\n\n event StalePeriodUpdated(uint32 _stalePeriod);\n\n // =================================== Errors ===================================\n\n error InvalidChainlinkRate();\n error NotGovernorOrGuardian();\n error NotVaultManagerOrGovernor();\n\n /// @notice Constructor for an oracle using Chainlink with multiple pools to read from\n /// @param _stalePeriod Minimum feed update frequency for the oracle to not revert\n /// @param _treasury Treasury associated to the VaultManager which reads from this feed\n constructor(uint32 _stalePeriod, address _treasury) {\n stalePeriod = _stalePeriod;\n treasury = ITreasury(_treasury);\n }\n\n // ============================= Reading Oracles ===============================\n\n /// @inheritdoc IOracle\n function read() external view virtual override returns (uint256 quoteAmount);\n\n /// @inheritdoc IOracle\n function circuitChainlink() public view virtual returns (AggregatorV3Interface[] memory);\n\n /// @notice Reads a Chainlink feed using a quote amount and converts the quote amount to\n /// the out-currency\n /// @param quoteAmount The amount for which to compute the price expressed with base decimal\n /// @param feed Chainlink feed to query\n /// @param multiplied Whether the ratio outputted by Chainlink should be multiplied or divided\n /// to the `quoteAmount`\n /// @param decimals Number of decimals of the corresponding Chainlink pair\n /// @return The `quoteAmount` converted in out-currency\n function _readChainlinkFeed(\n uint256 quoteAmount,\n AggregatorV3Interface feed,\n uint8 multiplied,\n uint256 decimals\n ) internal view returns (uint256) {\n (uint80 roundId, int256 ratio, , uint256 updatedAt, uint80 answeredInRound) = feed.latestRoundData();\n if (ratio <= 0 || roundId > answeredInRound || block.timestamp - updatedAt > stalePeriod)\n revert InvalidChainlinkRate();\n uint256 castedRatio = uint256(ratio);\n // Checking whether we should multiply or divide by the ratio computed\n if (multiplied == 1) return (quoteAmount * castedRatio) / (10 ** decimals);\n else return (quoteAmount * (10 ** decimals)) / castedRatio;\n }\n\n // ======================= Governance Related Functions ========================\n\n /// @notice Changes the stale period\n /// @param _stalePeriod New stale period (in seconds)\n function changeStalePeriod(uint32 _stalePeriod) external {\n if (!treasury.isGovernorOrGuardian(msg.sender)) revert NotGovernorOrGuardian();\n stalePeriod = _stalePeriod;\n emit StalePeriodUpdated(_stalePeriod);\n }\n\n /// @inheritdoc IOracle\n function setTreasury(address _treasury) external override {\n if (!treasury.isVaultManager(msg.sender) && !treasury.isGovernor(msg.sender))\n revert NotVaultManagerOrGovernor();\n treasury = ITreasury(_treasury);\n }\n}\n" + }, + "contracts/oracle/BaseOracleChainlinkMultiTwoFeeds.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\nimport \"@chainlink/contracts/src/v0.8/interfaces/AggregatorV3Interface.sol\";\n\nimport \"./BaseOracleChainlinkMulti.sol\";\n\n/// @title BaseOracleChainlinkMultiTwoFeeds\n/// @author Angle Labs, Inc.\n/// @notice Base contract for an oracle that reads into two Chainlink feeds (including an EUR/USD feed) which both have\n/// 8 decimals\nabstract contract BaseOracleChainlinkMultiTwoFeeds is BaseOracleChainlinkMulti {\n constructor(uint32 _stalePeriod, address _treasury) BaseOracleChainlinkMulti(_stalePeriod, _treasury) {}\n\n /// @notice Returns the quote amount of the oracle contract\n function _getQuoteAmount() internal view virtual returns (uint256) {\n return 10 ** 18;\n }\n\n /// @inheritdoc IOracle\n function read() external view virtual override returns (uint256 quoteAmount) {\n quoteAmount = _getQuoteAmount();\n AggregatorV3Interface[] memory _circuitChainlink = circuitChainlink();\n uint8[2] memory circuitChainIsMultiplied = [1, 0];\n uint8[2] memory chainlinkDecimals = [8, 8];\n uint256 circuitLength = _circuitChainlink.length;\n for (uint256 i; i < circuitLength; ++i) {\n quoteAmount = _readChainlinkFeed(\n quoteAmount,\n _circuitChainlink[i],\n circuitChainIsMultiplied[i],\n chainlinkDecimals[i]\n );\n }\n }\n}\n" + }, + "contracts/oracle/BaseOracleChainlinkOneFeed.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\nimport \"@chainlink/contracts/src/v0.8/interfaces/AggregatorV3Interface.sol\";\n\nimport \"./BaseOracleChainlinkMulti.sol\";\n\n/// @title BaseOracleChainlinkOneFeed\n/// @author Angle Labs, Inc.\n/// @notice Base contract for an oracle that reads into one Chainlink feeds with 8 decimals\nabstract contract BaseOracleChainlinkOneFeed is BaseOracleChainlinkMulti {\n constructor(uint32 _stalePeriod, address _treasury) BaseOracleChainlinkMulti(_stalePeriod, _treasury) {}\n\n /// @notice Returns the quote amount of the oracle contract\n function _getQuoteAmount() internal view virtual returns (uint256) {\n return 10 ** 18;\n }\n\n /// @inheritdoc IOracle\n function read() external view virtual override returns (uint256 quoteAmount) {\n AggregatorV3Interface[] memory _circuitChainlink = circuitChainlink();\n quoteAmount = _readChainlinkFeed(_getQuoteAmount(), _circuitChainlink[0], 1, 8);\n }\n}\n" + }, + "contracts/oracle/implementations/arbitrum/EUR/OracleBTCEURChainlinkArbitrum.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\nimport \"@chainlink/contracts/src/v0.8/interfaces/AggregatorV3Interface.sol\";\n\nimport \"../../../BaseOracleChainlinkMultiTwoFeeds.sol\";\n\n/// @title OracleBTCEURChainlinkArbitrum\n/// @author Angle Labs, Inc.\n/// @notice Gives the price of BTC in Euro in base 18\n/// @dev This contract is built to be deployed on Arbitrum\ncontract OracleBTCEURChainlinkArbitrum is BaseOracleChainlinkMultiTwoFeeds {\n string public constant DESCRIPTION = \"BTC/EUR Oracle\";\n\n constructor(uint32 _stalePeriod, address _treasury) BaseOracleChainlinkMultiTwoFeeds(_stalePeriod, _treasury) {}\n\n /// @inheritdoc IOracle\n function circuitChainlink() public pure override returns (AggregatorV3Interface[] memory) {\n AggregatorV3Interface[] memory _circuitChainlink = new AggregatorV3Interface[](2);\n // Oracle BTC/USD\n _circuitChainlink[0] = AggregatorV3Interface(0x6ce185860a4963106506C203335A2910413708e9);\n // Oracle EUR/USD\n _circuitChainlink[1] = AggregatorV3Interface(0xA14d53bC1F1c0F31B4aA3BD109344E5009051a84);\n return _circuitChainlink;\n }\n}\n" + }, + "contracts/oracle/implementations/arbitrum/EUR/OracleETHEURChainlinkArbitrum.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\nimport \"@chainlink/contracts/src/v0.8/interfaces/AggregatorV3Interface.sol\";\n\nimport \"../../../BaseOracleChainlinkMultiTwoFeeds.sol\";\n\n/// @title OracleETHEURChainlinkArbitrum\n/// @author Angle Labs, Inc.\n/// @notice Gives the price of ETH in Euro in base 18\n/// @dev This contract is built to be deployed on Arbitrum\ncontract OracleETHEURChainlinkArbitrum is BaseOracleChainlinkMultiTwoFeeds {\n string public constant DESCRIPTION = \"ETH/EUR Oracle\";\n\n constructor(uint32 _stalePeriod, address _treasury) BaseOracleChainlinkMultiTwoFeeds(_stalePeriod, _treasury) {}\n\n /// @inheritdoc IOracle\n function circuitChainlink() public pure override returns (AggregatorV3Interface[] memory) {\n AggregatorV3Interface[] memory _circuitChainlink = new AggregatorV3Interface[](2);\n // Oracle ETH/USD\n _circuitChainlink[0] = AggregatorV3Interface(0x639Fe6ab55C921f74e7fac1ee960C0B6293ba612);\n // Oracle EUR/USD\n _circuitChainlink[1] = AggregatorV3Interface(0xA14d53bC1F1c0F31B4aA3BD109344E5009051a84);\n return _circuitChainlink;\n }\n}\n" + }, + "contracts/oracle/implementations/arbitrum/EUR/OracleUSDCEURChainlinkArbitrum.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\nimport \"@chainlink/contracts/src/v0.8/interfaces/AggregatorV3Interface.sol\";\n\nimport \"../../../BaseOracleChainlinkMultiTwoFeeds.sol\";\n\n/// @title OracleUSDCEURChainlinkArbitrum\n/// @author Angle Labs, Inc.\n/// @notice Gives the price of USDC in Euro in base 18\n/// @dev This contract is built to be deployed on Arbitrum\ncontract OracleUSDCEURChainlinkArbitrum is BaseOracleChainlinkMultiTwoFeeds {\n string public constant DESCRIPTION = \"USDC/EUR Oracle\";\n\n constructor(uint32 _stalePeriod, address _treasury) BaseOracleChainlinkMultiTwoFeeds(_stalePeriod, _treasury) {}\n\n /// @inheritdoc IOracle\n function circuitChainlink() public pure override returns (AggregatorV3Interface[] memory) {\n AggregatorV3Interface[] memory _circuitChainlink = new AggregatorV3Interface[](2);\n // Oracle ETH/USD\n _circuitChainlink[0] = AggregatorV3Interface(0x50834F3163758fcC1Df9973b6e91f0F0F0434aD3);\n // Oracle EUR/USD\n _circuitChainlink[1] = AggregatorV3Interface(0xA14d53bC1F1c0F31B4aA3BD109344E5009051a84);\n return _circuitChainlink;\n }\n}\n" + }, + "contracts/oracle/implementations/avalanche/EUR/OracleAVAXEURChainlinkAvalanche.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\nimport \"@chainlink/contracts/src/v0.8/interfaces/AggregatorV3Interface.sol\";\n\nimport \"../../../BaseOracleChainlinkMultiTwoFeeds.sol\";\n\n/// @title OracleAVAXEURChainlinkAvalanche\n/// @author Angle Labs, Inc.\n/// @notice Gives the price of AVAX in Euro in base 18\n/// @dev This contract is built to be deployed on Avalanche\ncontract OracleAVAXEURChainlinkAvalanche is BaseOracleChainlinkMultiTwoFeeds {\n string public constant DESCRIPTION = \"AVAX/EUR Oracle\";\n\n constructor(uint32 _stalePeriod, address _treasury) BaseOracleChainlinkMultiTwoFeeds(_stalePeriod, _treasury) {}\n\n /// @inheritdoc IOracle\n function circuitChainlink() public pure override returns (AggregatorV3Interface[] memory) {\n AggregatorV3Interface[] memory _circuitChainlink = new AggregatorV3Interface[](2);\n // Oracle AVAX/USD\n _circuitChainlink[0] = AggregatorV3Interface(0x0A77230d17318075983913bC2145DB16C7366156);\n // Oracle EUR/USD\n _circuitChainlink[1] = AggregatorV3Interface(0x192f2DBA961Bb0277520C082d6bfa87D5961333E);\n return _circuitChainlink;\n }\n}\n" + }, + "contracts/oracle/implementations/avalanche/EUR/OracleUSDCEURChainlinkAvalanche.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\nimport \"@chainlink/contracts/src/v0.8/interfaces/AggregatorV3Interface.sol\";\n\nimport \"../../../BaseOracleChainlinkMultiTwoFeeds.sol\";\n\n/// @title OracleUSDCEURChainlinkAvalanche\n/// @author Angle Labs, Inc.\n/// @notice Gives the price of USDC in Euro in base 18\n/// @dev This contract is built to be deployed on Avalanche\ncontract OracleUSDCEURChainlinkAvalanche is BaseOracleChainlinkMultiTwoFeeds {\n string public constant DESCRIPTION = \"USDC/EUR Oracle\";\n\n constructor(uint32 _stalePeriod, address _treasury) BaseOracleChainlinkMultiTwoFeeds(_stalePeriod, _treasury) {}\n\n /// @inheritdoc IOracle\n function circuitChainlink() public pure override returns (AggregatorV3Interface[] memory) {\n AggregatorV3Interface[] memory _circuitChainlink = new AggregatorV3Interface[](2);\n // Oracle USDC/USD\n _circuitChainlink[0] = AggregatorV3Interface(0xF096872672F44d6EBA71458D74fe67F9a77a23B9);\n // Oracle EUR/USD\n _circuitChainlink[1] = AggregatorV3Interface(0x192f2DBA961Bb0277520C082d6bfa87D5961333E);\n return _circuitChainlink;\n }\n}\n" + }, + "contracts/oracle/implementations/mainnet/EUR/OracleBTCEURChainlink.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\nimport \"@chainlink/contracts/src/v0.8/interfaces/AggregatorV3Interface.sol\";\n\nimport \"../../../BaseOracleChainlinkMultiTwoFeeds.sol\";\n\n/// @title OracleBTCEURChainlink\n/// @author Angle Labs, Inc.\n/// @notice Gives the price of BTC in Euro in base 18\ncontract OracleBTCEURChainlink is BaseOracleChainlinkMultiTwoFeeds {\n string public constant DESCRIPTION = \"BTC/EUR Oracle\";\n\n constructor(uint32 _stalePeriod, address _treasury) BaseOracleChainlinkMultiTwoFeeds(_stalePeriod, _treasury) {}\n\n /// @inheritdoc IOracle\n function circuitChainlink() public pure override returns (AggregatorV3Interface[] memory) {\n AggregatorV3Interface[] memory _circuitChainlink = new AggregatorV3Interface[](2);\n // Oracle BTC/USD\n _circuitChainlink[0] = AggregatorV3Interface(0xF4030086522a5bEEa4988F8cA5B36dbC97BeE88c);\n // Oracle EUR/USD\n _circuitChainlink[1] = AggregatorV3Interface(0xb49f677943BC038e9857d61E7d053CaA2C1734C1);\n return _circuitChainlink;\n }\n}\n" + }, + "contracts/oracle/implementations/mainnet/EUR/OracleCBETHEURChainlink.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\nimport \"@chainlink/contracts/src/v0.8/interfaces/AggregatorV3Interface.sol\";\n\nimport \"../../../BaseOracleChainlinkMultiTwoFeeds.sol\";\n\n/// @title OracleCBETHEURChainlink\n/// @author Angle Labs, Inc.\n/// @notice Gives the price of cbETH in Euro in base 18\ncontract OracleCBETHEURChainlink is BaseOracleChainlinkMultiTwoFeeds {\n string public constant DESCRIPTION = \"cbETH/EUR Oracle\";\n\n constructor(uint32 _stalePeriod, address _treasury) BaseOracleChainlinkMultiTwoFeeds(_stalePeriod, _treasury) {}\n\n /// @inheritdoc IOracle\n function circuitChainlink() public pure override returns (AggregatorV3Interface[] memory) {\n AggregatorV3Interface[] memory _circuitChainlink = new AggregatorV3Interface[](3);\n // Oracle cbETH/ETH\n _circuitChainlink[0] = AggregatorV3Interface(0xF017fcB346A1885194689bA23Eff2fE6fA5C483b);\n // Oracle ETH/USD\n _circuitChainlink[1] = AggregatorV3Interface(0x5f4eC3Df9cbd43714FE2740f5E3616155c5b8419);\n // Oracle EUR/USD\n _circuitChainlink[2] = AggregatorV3Interface(0xb49f677943BC038e9857d61E7d053CaA2C1734C1);\n return _circuitChainlink;\n }\n\n /// @inheritdoc BaseOracleChainlinkMultiTwoFeeds\n function read() external view virtual override returns (uint256 quoteAmount) {\n quoteAmount = _getQuoteAmount();\n AggregatorV3Interface[] memory _circuitChainlink = circuitChainlink();\n uint8[3] memory circuitChainIsMultiplied = [1, 1, 0];\n uint8[3] memory chainlinkDecimals = [18, 8, 8];\n uint256 circuitLength = _circuitChainlink.length;\n for (uint256 i; i < circuitLength; ++i) {\n quoteAmount = _readChainlinkFeed(\n quoteAmount,\n _circuitChainlink[i],\n circuitChainIsMultiplied[i],\n chainlinkDecimals[i]\n );\n }\n }\n}\n" + }, + "contracts/oracle/implementations/mainnet/EUR/OracleETHEURChainlink.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\nimport \"@chainlink/contracts/src/v0.8/interfaces/AggregatorV3Interface.sol\";\n\nimport \"../../../BaseOracleChainlinkMultiTwoFeeds.sol\";\n\n/// @title OracleETHEURChainlink\n/// @author Angle Labs, Inc.\n/// @notice Gives the price of ETH in Euro in base 18\ncontract OracleETHEURChainlink is BaseOracleChainlinkMultiTwoFeeds {\n string public constant DESCRIPTION = \"ETH/EUR Oracle\";\n\n constructor(uint32 _stalePeriod, address _treasury) BaseOracleChainlinkMultiTwoFeeds(_stalePeriod, _treasury) {}\n\n /// @inheritdoc IOracle\n function circuitChainlink() public pure override returns (AggregatorV3Interface[] memory) {\n AggregatorV3Interface[] memory _circuitChainlink = new AggregatorV3Interface[](2);\n // Oracle ETH/USD\n _circuitChainlink[0] = AggregatorV3Interface(0x5f4eC3Df9cbd43714FE2740f5E3616155c5b8419);\n // Oracle EUR/USD\n _circuitChainlink[1] = AggregatorV3Interface(0xb49f677943BC038e9857d61E7d053CaA2C1734C1);\n return _circuitChainlink;\n }\n}\n" + }, + "contracts/oracle/implementations/mainnet/EUR/OracleHIGHEURChainlink.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\nimport \"@chainlink/contracts/src/v0.8/interfaces/AggregatorV3Interface.sol\";\n\nimport \"../../../BaseOracleChainlinkMultiTwoFeeds.sol\";\n\n/// @title OracleHIGHEURChainlink\n/// @author Angle Labs, Inc.\n/// @notice Gives the price of HIGH in Euro in base 18\ncontract OracleHIGHEURChainlink is BaseOracleChainlinkMultiTwoFeeds {\n string public constant DESCRIPTION = \"HIGH/EUR Oracle\";\n\n constructor(uint32 _stalePeriod, address _treasury) BaseOracleChainlinkMultiTwoFeeds(_stalePeriod, _treasury) {}\n\n /// @inheritdoc IOracle\n function circuitChainlink() public pure override returns (AggregatorV3Interface[] memory) {\n AggregatorV3Interface[] memory _circuitChainlink = new AggregatorV3Interface[](1);\n // Oracle HIGH/EUR\n _circuitChainlink[0] = AggregatorV3Interface(0x9E8E794ad6Ecdb6d5c7eaBE059D30E907F58859b);\n return _circuitChainlink;\n }\n\n /// @inheritdoc BaseOracleChainlinkMultiTwoFeeds\n function read() external view override returns (uint256 quoteAmount) {\n quoteAmount = _readChainlinkFeed(_getQuoteAmount(), circuitChainlink()[0], 1, 8);\n }\n}\n" + }, + "contracts/oracle/implementations/mainnet/EUR/OracleIB01EURChainlink.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\nimport \"@chainlink/contracts/src/v0.8/interfaces/AggregatorV3Interface.sol\";\n\nimport \"../../../BaseOracleChainlinkMultiTwoFeeds.sol\";\n\n/// @title OracleIB01EURChainlink\n/// @author Angle Labs, Inc.\n/// @notice Gives the price of IB01 in Euro in base 18\ncontract OracleIB01EURChainlink is BaseOracleChainlinkMultiTwoFeeds {\n string public constant DESCRIPTION = \"IB01/EUR Oracle\";\n\n constructor(uint32 _stalePeriod, address _treasury) BaseOracleChainlinkMultiTwoFeeds(_stalePeriod, _treasury) {}\n\n /// @inheritdoc IOracle\n function circuitChainlink() public pure override returns (AggregatorV3Interface[] memory) {\n AggregatorV3Interface[] memory _circuitChainlink = new AggregatorV3Interface[](2);\n // Oracle IB01/USD\n _circuitChainlink[0] = AggregatorV3Interface(0x32d1463EB53b73C095625719Afa544D5426354cB);\n // Oracle EUR/USD\n _circuitChainlink[1] = AggregatorV3Interface(0xb49f677943BC038e9857d61E7d053CaA2C1734C1);\n return _circuitChainlink;\n }\n}\n" + }, + "contracts/oracle/implementations/mainnet/EUR/OracleLUSDEURChainlink.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\nimport \"@chainlink/contracts/src/v0.8/interfaces/AggregatorV3Interface.sol\";\n\nimport \"../../../BaseOracleChainlinkMultiTwoFeeds.sol\";\n\n/// @title OracleLUSDEURChainlink\n/// @author Angle Labs, Inc.\n/// @notice Gives the price of LUSD in Euro in base 18\ncontract OracleLUSDEURChainlink is BaseOracleChainlinkMultiTwoFeeds {\n string public constant DESCRIPTION = \"LUSD/EUR Oracle\";\n\n constructor(uint32 _stalePeriod, address _treasury) BaseOracleChainlinkMultiTwoFeeds(_stalePeriod, _treasury) {}\n\n /// @inheritdoc IOracle\n function circuitChainlink() public pure override returns (AggregatorV3Interface[] memory) {\n AggregatorV3Interface[] memory _circuitChainlink = new AggregatorV3Interface[](2);\n // Oracle LUSD/USD\n _circuitChainlink[0] = AggregatorV3Interface(0x3D7aE7E594f2f2091Ad8798313450130d0Aba3a0);\n // Oracle EUR/USD\n _circuitChainlink[1] = AggregatorV3Interface(0xb49f677943BC038e9857d61E7d053CaA2C1734C1);\n return _circuitChainlink;\n }\n}\n" + }, + "contracts/oracle/implementations/mainnet/EUR/OracleUSDCEURChainlink.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\nimport \"@chainlink/contracts/src/v0.8/interfaces/AggregatorV3Interface.sol\";\n\nimport \"../../../BaseOracleChainlinkMultiTwoFeeds.sol\";\n\n/// @title OracleUSDCEURChainlink\n/// @author Angle Labs, Inc.\n/// @notice Gives the price of USDC in Euro in base 18\ncontract OracleUSDCEURChainlink is BaseOracleChainlinkMultiTwoFeeds {\n string public constant DESCRIPTION = \"USDC/EUR Oracle\";\n\n constructor(uint32 _stalePeriod, address _treasury) BaseOracleChainlinkMultiTwoFeeds(_stalePeriod, _treasury) {}\n\n /// @inheritdoc IOracle\n function circuitChainlink() public pure override returns (AggregatorV3Interface[] memory) {\n AggregatorV3Interface[] memory _circuitChainlink = new AggregatorV3Interface[](2);\n // Oracle USDC/USD\n _circuitChainlink[0] = AggregatorV3Interface(0x8fFfFfd4AfB6115b954Bd326cbe7B4BA576818f6);\n // Oracle EUR/USD\n _circuitChainlink[1] = AggregatorV3Interface(0xb49f677943BC038e9857d61E7d053CaA2C1734C1);\n return _circuitChainlink;\n }\n}\n" + }, + "contracts/oracle/implementations/mainnet/EUR/OracleWSTETHEURChainlink.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\nimport \"@chainlink/contracts/src/v0.8/interfaces/AggregatorV3Interface.sol\";\n\nimport \"../../../BaseOracleChainlinkMultiTwoFeeds.sol\";\nimport \"../../../../interfaces/external/lido/IStETH.sol\";\n\n/// @title OracleWSTETHEURChainlink\n/// @author Angle Labs, Inc.\n/// @notice Gives the price of wSTETH in Euro in base 18\ncontract OracleWSTETHEURChainlink is BaseOracleChainlinkMultiTwoFeeds {\n string public constant DESCRIPTION = \"wSTETH/EUR Oracle\";\n IStETH public constant STETH = IStETH(0xae7ab96520DE3A18E5e111B5EaAb095312D7fE84);\n\n constructor(uint32 _stalePeriod, address _treasury) BaseOracleChainlinkMultiTwoFeeds(_stalePeriod, _treasury) {}\n\n /// @inheritdoc IOracle\n function circuitChainlink() public pure override returns (AggregatorV3Interface[] memory) {\n AggregatorV3Interface[] memory _circuitChainlink = new AggregatorV3Interface[](2);\n // Oracle stETH/USD\n _circuitChainlink[0] = AggregatorV3Interface(0xCfE54B5cD566aB89272946F602D76Ea879CAb4a8);\n // Oracle EUR/USD\n _circuitChainlink[1] = AggregatorV3Interface(0xb49f677943BC038e9857d61E7d053CaA2C1734C1);\n return _circuitChainlink;\n }\n\n /// @inheritdoc BaseOracleChainlinkMultiTwoFeeds\n function _getQuoteAmount() internal view override returns (uint256) {\n return STETH.getPooledEthByShares(1 ether);\n }\n}\n" + }, + "contracts/oracle/implementations/mainnet/USD/OracleWSTETHUSDChainlink.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\nimport \"@chainlink/contracts/src/v0.8/interfaces/AggregatorV3Interface.sol\";\n\nimport \"../../../BaseOracleChainlinkOneFeed.sol\";\nimport \"../../../../interfaces/external/lido/IStETH.sol\";\n\n/// @title OracleWSTETHUSDChainlink\n/// @author Angle Labs, Inc.\n/// @notice Gives the price of wSTETH in USD in base 18\ncontract OracleWSTETHUSDChainlink is BaseOracleChainlinkOneFeed {\n string public constant DESCRIPTION = \"wSTETH/USD Oracle\";\n IStETH public constant STETH = IStETH(0xae7ab96520DE3A18E5e111B5EaAb095312D7fE84);\n\n constructor(uint32 _stalePeriod, address _treasury) BaseOracleChainlinkOneFeed(_stalePeriod, _treasury) {}\n\n /// @inheritdoc IOracle\n function circuitChainlink() public pure override returns (AggregatorV3Interface[] memory) {\n AggregatorV3Interface[] memory _circuitChainlink = new AggregatorV3Interface[](1);\n // Oracle stETH/USD\n _circuitChainlink[0] = AggregatorV3Interface(0xCfE54B5cD566aB89272946F602D76Ea879CAb4a8);\n return _circuitChainlink;\n }\n\n /// @inheritdoc BaseOracleChainlinkOneFeed\n function _getQuoteAmount() internal view override returns (uint256) {\n return STETH.getPooledEthByShares(1 ether);\n }\n}\n" + }, + "contracts/oracle/implementations/mainnet/XAU/OracleETHXAUChainlink.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\nimport \"@chainlink/contracts/src/v0.8/interfaces/AggregatorV3Interface.sol\";\n\nimport \"../../../BaseOracleChainlinkMultiTwoFeeds.sol\";\n\n/// @title OracleETHXAUChainlink\n/// @author Angle Labs, Inc.\n/// @notice Gives the price of ETH in XAU in base 18\ncontract OracleETHXAUChainlink is BaseOracleChainlinkMultiTwoFeeds {\n string public constant DESCRIPTION = \"ETH/GOLD Oracle\";\n\n constructor(uint32 _stalePeriod, address _treasury) BaseOracleChainlinkMultiTwoFeeds(_stalePeriod, _treasury) {}\n\n /// @inheritdoc IOracle\n function circuitChainlink() public pure override returns (AggregatorV3Interface[] memory) {\n AggregatorV3Interface[] memory _circuitChainlink = new AggregatorV3Interface[](2);\n // Oracle ETH/USD\n _circuitChainlink[0] = AggregatorV3Interface(0x5f4eC3Df9cbd43714FE2740f5E3616155c5b8419);\n // Oracle XAU/USD\n _circuitChainlink[1] = AggregatorV3Interface(0x214eD9Da11D2fbe465a6fc601a91E62EbEc1a0D6);\n return _circuitChainlink;\n }\n}\n" + }, + "contracts/oracle/implementations/mainnet/XAU/OracleLUSDXAUChainlink.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\nimport \"@chainlink/contracts/src/v0.8/interfaces/AggregatorV3Interface.sol\";\n\nimport \"../../../BaseOracleChainlinkMultiTwoFeeds.sol\";\n\n/// @title OracleLUSDXAUChainlink\n/// @author Angle Labs, Inc.\n/// @notice Gives the price of LUSD in XAU in base 18\ncontract OracleLUSDXAUChainlink is BaseOracleChainlinkMultiTwoFeeds {\n string public constant DESCRIPTION = \"LUSD/GOLD Oracle\";\n\n constructor(uint32 _stalePeriod, address _treasury) BaseOracleChainlinkMultiTwoFeeds(_stalePeriod, _treasury) {}\n\n /// @inheritdoc IOracle\n function circuitChainlink() public pure override returns (AggregatorV3Interface[] memory) {\n AggregatorV3Interface[] memory _circuitChainlink = new AggregatorV3Interface[](2);\n // Oracle LUSD/USD\n _circuitChainlink[0] = AggregatorV3Interface(0x3D7aE7E594f2f2091Ad8798313450130d0Aba3a0);\n // Oracle XAU/USD\n _circuitChainlink[1] = AggregatorV3Interface(0x214eD9Da11D2fbe465a6fc601a91E62EbEc1a0D6);\n return _circuitChainlink;\n }\n}\n" + }, + "contracts/oracle/implementations/mainnet/XAU/OracleUSDCXAUChainlink.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\nimport \"@chainlink/contracts/src/v0.8/interfaces/AggregatorV3Interface.sol\";\n\nimport \"../../../BaseOracleChainlinkMultiTwoFeeds.sol\";\n\n/// @title OracleUSDCXAUChainlink\n/// @author Angle Labs, Inc.\n/// @notice Gives the price of USDC in XAU in base 18\ncontract OracleUSDCXAUChainlink is BaseOracleChainlinkMultiTwoFeeds {\n string public constant DESCRIPTION = \"USDC/GOLD Oracle\";\n\n constructor(uint32 _stalePeriod, address _treasury) BaseOracleChainlinkMultiTwoFeeds(_stalePeriod, _treasury) {}\n\n /// @inheritdoc IOracle\n function circuitChainlink() public pure override returns (AggregatorV3Interface[] memory) {\n AggregatorV3Interface[] memory _circuitChainlink = new AggregatorV3Interface[](2);\n // Oracle USDC/USD\n _circuitChainlink[0] = AggregatorV3Interface(0x8fFfFfd4AfB6115b954Bd326cbe7B4BA576818f6);\n // Oracle XAU/USD\n _circuitChainlink[1] = AggregatorV3Interface(0x214eD9Da11D2fbe465a6fc601a91E62EbEc1a0D6);\n return _circuitChainlink;\n }\n}\n" + }, + "contracts/oracle/implementations/mainnet/XAU/OracleWSTETHXAUChainlink.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\nimport \"@chainlink/contracts/src/v0.8/interfaces/AggregatorV3Interface.sol\";\n\nimport \"../../../BaseOracleChainlinkMultiTwoFeeds.sol\";\nimport \"../../../../interfaces/external/lido/IStETH.sol\";\n\n/// @title OracleWSTETHXAUChainlink\n/// @author Angle Labs, Inc.\n/// @notice Gives the price of wSTETH in XAU in base 18\ncontract OracleWSTETHXAUChainlink is BaseOracleChainlinkMultiTwoFeeds {\n string public constant DESCRIPTION = \"wSTETH/XAU Oracle\";\n IStETH public constant STETH = IStETH(0xae7ab96520DE3A18E5e111B5EaAb095312D7fE84);\n\n constructor(uint32 _stalePeriod, address _treasury) BaseOracleChainlinkMultiTwoFeeds(_stalePeriod, _treasury) {}\n\n /// @inheritdoc IOracle\n function circuitChainlink() public pure override returns (AggregatorV3Interface[] memory) {\n AggregatorV3Interface[] memory _circuitChainlink = new AggregatorV3Interface[](2);\n // Oracle stETH/USD\n _circuitChainlink[0] = AggregatorV3Interface(0xCfE54B5cD566aB89272946F602D76Ea879CAb4a8);\n // Oracle XAU/USD\n _circuitChainlink[1] = AggregatorV3Interface(0x214eD9Da11D2fbe465a6fc601a91E62EbEc1a0D6);\n return _circuitChainlink;\n }\n\n /// @inheritdoc BaseOracleChainlinkMultiTwoFeeds\n function _getQuoteAmount() internal view override returns (uint256) {\n return STETH.getPooledEthByShares(1 ether);\n }\n}\n" + }, + "contracts/oracle/implementations/optimism/EUR/OracleETHEURChainlinkOptimism.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\nimport \"@chainlink/contracts/src/v0.8/interfaces/AggregatorV3Interface.sol\";\n\nimport \"../../../BaseOracleChainlinkMultiTwoFeeds.sol\";\n\n/// @title OracleETHEURChainlinkOptimism\n/// @author Angle Labs, Inc.\n/// @notice Gives the price of ETH in Euro in base 18\n/// @dev This contract is built to be deployed on Optimism\ncontract OracleETHEURChainlinkOptimism is BaseOracleChainlinkMultiTwoFeeds {\n string public constant DESCRIPTION = \"ETH/EUR Oracle\";\n\n constructor(uint32 _stalePeriod, address _treasury) BaseOracleChainlinkMultiTwoFeeds(_stalePeriod, _treasury) {}\n\n /// @inheritdoc IOracle\n function circuitChainlink() public pure override returns (AggregatorV3Interface[] memory) {\n AggregatorV3Interface[] memory _circuitChainlink = new AggregatorV3Interface[](2);\n // Oracle ETH/USD\n _circuitChainlink[0] = AggregatorV3Interface(0x13e3Ee699D1909E989722E753853AE30b17e08c5);\n // Oracle EUR/USD\n _circuitChainlink[1] = AggregatorV3Interface(0x3626369857A10CcC6cc3A6e4f5C2f5984a519F20);\n return _circuitChainlink;\n }\n}\n" + }, + "contracts/oracle/implementations/optimism/EUR/OracleOPEURChainlinkOptimism.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\nimport \"@chainlink/contracts/src/v0.8/interfaces/AggregatorV3Interface.sol\";\n\nimport \"../../../BaseOracleChainlinkMultiTwoFeeds.sol\";\n\n/// @title OracleOPEURChainlinkOptimism\n/// @author Angle Labs, Inc.\n/// @notice Gives the price of OP in Euro in base 18\n/// @dev This contract is built to be deployed on Optimism\ncontract OracleOPEURChainlinkOptimism is BaseOracleChainlinkMultiTwoFeeds {\n string public constant DESCRIPTION = \"OP/EUR Oracle\";\n\n constructor(uint32 _stalePeriod, address _treasury) BaseOracleChainlinkMultiTwoFeeds(_stalePeriod, _treasury) {}\n\n /// @inheritdoc IOracle\n function circuitChainlink() public pure override returns (AggregatorV3Interface[] memory) {\n AggregatorV3Interface[] memory _circuitChainlink = new AggregatorV3Interface[](2);\n // Oracle OP/USD\n _circuitChainlink[0] = AggregatorV3Interface(0x0D276FC14719f9292D5C1eA2198673d1f4269246);\n // Oracle EUR/USD\n _circuitChainlink[1] = AggregatorV3Interface(0x3626369857A10CcC6cc3A6e4f5C2f5984a519F20);\n return _circuitChainlink;\n }\n}\n" + }, + "contracts/oracle/implementations/optimism/EUR/OracleUSDCEURChainlinkOptimism.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\nimport \"@chainlink/contracts/src/v0.8/interfaces/AggregatorV3Interface.sol\";\n\nimport \"../../../BaseOracleChainlinkMultiTwoFeeds.sol\";\n\n/// @title OracleUSDCEURChainlinkOptimism\n/// @author Angle Labs, Inc.\n/// @notice Gives the price of USDC in Euro in base 18\n/// @dev This contract is built to be deployed on Optimism\ncontract OracleUSDCEURChainlinkOptimism is BaseOracleChainlinkMultiTwoFeeds {\n string public constant DESCRIPTION = \"USDC/EUR Oracle\";\n\n constructor(uint32 _stalePeriod, address _treasury) BaseOracleChainlinkMultiTwoFeeds(_stalePeriod, _treasury) {}\n\n /// @inheritdoc IOracle\n function circuitChainlink() public pure override returns (AggregatorV3Interface[] memory) {\n AggregatorV3Interface[] memory _circuitChainlink = new AggregatorV3Interface[](2);\n // Oracle USDC/USD\n _circuitChainlink[0] = AggregatorV3Interface(0x16a9FA2FDa030272Ce99B29CF780dFA30361E0f3);\n // Oracle EUR/USD\n _circuitChainlink[1] = AggregatorV3Interface(0x3626369857A10CcC6cc3A6e4f5C2f5984a519F20);\n return _circuitChainlink;\n }\n}\n" + }, + "contracts/oracle/implementations/polygon/EUR/OracleBTCEURChainlinkPolygon.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\nimport \"@chainlink/contracts/src/v0.8/interfaces/AggregatorV3Interface.sol\";\n\nimport \"../../../BaseOracleChainlinkMultiTwoFeeds.sol\";\n\n/// @title OracleBTCEURChainlinkPolygon\n/// @author Angle Labs, Inc.\n/// @notice Gives the price of BTC in Euro in base 18\n/// @dev This contract is built to be deployed on Polygon\ncontract OracleBTCEURChainlinkPolygon is BaseOracleChainlinkMultiTwoFeeds {\n string public constant DESCRIPTION = \"BTC/EUR Oracle\";\n\n constructor(uint32 _stalePeriod, address _treasury) BaseOracleChainlinkMultiTwoFeeds(_stalePeriod, _treasury) {}\n\n /// @inheritdoc IOracle\n function circuitChainlink() public pure override returns (AggregatorV3Interface[] memory) {\n AggregatorV3Interface[] memory _circuitChainlink = new AggregatorV3Interface[](2);\n // Oracle BTC/USD\n _circuitChainlink[0] = AggregatorV3Interface(0xc907E116054Ad103354f2D350FD2514433D57F6f);\n // Oracle EUR/USD\n _circuitChainlink[1] = AggregatorV3Interface(0x73366Fe0AA0Ded304479862808e02506FE556a98);\n return _circuitChainlink;\n }\n}\n" + }, + "contracts/oracle/implementations/polygon/EUR/OracleETHEURChainlinkPolygon.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\nimport \"@chainlink/contracts/src/v0.8/interfaces/AggregatorV3Interface.sol\";\n\nimport \"../../../BaseOracleChainlinkMultiTwoFeeds.sol\";\n\n/// @title OracleETHEURChainlinkPolygon\n/// @author Angle Labs, Inc.\n/// @notice Gives the price of ETH in Euro in base 18\n/// @dev This contract is built to be deployed on Polygon\ncontract OracleETHEURChainlinkPolygon is BaseOracleChainlinkMultiTwoFeeds {\n string public constant DESCRIPTION = \"ETH/EUR Oracle\";\n\n constructor(uint32 _stalePeriod, address _treasury) BaseOracleChainlinkMultiTwoFeeds(_stalePeriod, _treasury) {}\n\n /// @inheritdoc IOracle\n function circuitChainlink() public pure override returns (AggregatorV3Interface[] memory) {\n AggregatorV3Interface[] memory _circuitChainlink = new AggregatorV3Interface[](2);\n // Oracle ETH/USD\n _circuitChainlink[0] = AggregatorV3Interface(0xF9680D99D6C9589e2a93a78A04A279e509205945);\n // Oracle EUR/USD\n _circuitChainlink[1] = AggregatorV3Interface(0x73366Fe0AA0Ded304479862808e02506FE556a98);\n return _circuitChainlink;\n }\n}\n" + }, + "contracts/oracle/implementations/polygon/EUR/OracleMAIEURChainlinkPolygon.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\nimport \"@chainlink/contracts/src/v0.8/interfaces/AggregatorV3Interface.sol\";\n\nimport \"../../../BaseOracleChainlinkMultiTwoFeeds.sol\";\n\n/// @title OracleMAIEURChainlinkPolygon\n/// @author Angle Labs, Inc.\n/// @notice Gives the price of MAI in Euro in base 18\n/// @dev This contract is built to be deployed on Polygon\ncontract OracleMAIEURChainlinkPolygon is BaseOracleChainlinkMultiTwoFeeds {\n string public constant DESCRIPTION = \"MAI/EUR Oracle\";\n\n constructor(uint32 _stalePeriod, address _treasury) BaseOracleChainlinkMultiTwoFeeds(_stalePeriod, _treasury) {}\n\n /// @inheritdoc IOracle\n function circuitChainlink() public pure override returns (AggregatorV3Interface[] memory) {\n AggregatorV3Interface[] memory _circuitChainlink = new AggregatorV3Interface[](2);\n // Oracle MAI/USD\n _circuitChainlink[0] = AggregatorV3Interface(0xd8d483d813547CfB624b8Dc33a00F2fcbCd2D428);\n // Oracle EUR/USD\n _circuitChainlink[1] = AggregatorV3Interface(0x73366Fe0AA0Ded304479862808e02506FE556a98);\n return _circuitChainlink;\n }\n}\n" + }, + "contracts/oracle/implementations/polygon/EUR/OracleMATICEURChainlinkPolygon.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\nimport \"@chainlink/contracts/src/v0.8/interfaces/AggregatorV3Interface.sol\";\n\nimport \"../../../BaseOracleChainlinkMultiTwoFeeds.sol\";\n\n/// @title OracleMATICEURChainlinkPolygon\n/// @author Angle Labs, Inc.\n/// @notice Gives the price of MATIC in Euro in base 18\n/// @dev This contract is built to be deployed on Polygon\ncontract OracleMATICEURChainlinkPolygon is BaseOracleChainlinkMultiTwoFeeds {\n string public constant DESCRIPTION = \"MATIC/EUR Oracle\";\n\n constructor(uint32 _stalePeriod, address _treasury) BaseOracleChainlinkMultiTwoFeeds(_stalePeriod, _treasury) {}\n\n /// @inheritdoc IOracle\n function circuitChainlink() public pure override returns (AggregatorV3Interface[] memory) {\n AggregatorV3Interface[] memory _circuitChainlink = new AggregatorV3Interface[](2);\n // Oracle MATIC/USD\n _circuitChainlink[0] = AggregatorV3Interface(0xAB594600376Ec9fD91F8e885dADF0CE036862dE0);\n // Oracle EUR/USD\n _circuitChainlink[1] = AggregatorV3Interface(0x73366Fe0AA0Ded304479862808e02506FE556a98);\n return _circuitChainlink;\n }\n}\n" + }, + "contracts/oracle/implementations/polygon/EUR/OracleUSDCEURChainlinkPolygon.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\nimport \"../../../BaseOracleChainlinkMultiTwoFeeds.sol\";\n\n/// @title OracleUSDCEURChainlinkPolygon\n/// @author Angle Labs, Inc.\n/// @notice Gives the price of USDC in Euro in base 18\n/// @dev This contract is built to be deployed on Polygon\ncontract OracleUSDCEURChainlinkPolygon is BaseOracleChainlinkMultiTwoFeeds {\n string public constant DESCRIPTION = \"USDC/EUR Oracle\";\n\n constructor(uint32 _stalePeriod, address _treasury) BaseOracleChainlinkMultiTwoFeeds(_stalePeriod, _treasury) {}\n\n /// @inheritdoc IOracle\n function circuitChainlink() public pure override returns (AggregatorV3Interface[] memory) {\n AggregatorV3Interface[] memory _circuitChainlink = new AggregatorV3Interface[](2);\n // Oracle USDC/USD\n _circuitChainlink[0] = AggregatorV3Interface(0xfE4A8cc5b5B2366C1B58Bea3858e81843581b2F7);\n // Oracle EUR/USD\n _circuitChainlink[1] = AggregatorV3Interface(0x73366Fe0AA0Ded304479862808e02506FE556a98);\n return _circuitChainlink;\n }\n}\n" + }, + "contracts/oracle/implementations/polygon/XAU/OracleETHXAUChainlinkPolygon.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\nimport \"@chainlink/contracts/src/v0.8/interfaces/AggregatorV3Interface.sol\";\n\nimport \"../../../BaseOracleChainlinkMultiTwoFeeds.sol\";\n\n/// @title OracleETHXAUChainlinkPolygon\n/// @author Angle Labs, Inc.\n/// @notice Gives the price of ETH in XAU in base 18\n/// @dev This contract is built to be deployed on Polygon\ncontract OracleETHXAUChainlinkPolygon is BaseOracleChainlinkMultiTwoFeeds {\n string public constant DESCRIPTION = \"ETH/GOLD Oracle\";\n\n constructor(uint32 _stalePeriod, address _treasury) BaseOracleChainlinkMultiTwoFeeds(_stalePeriod, _treasury) {}\n\n /// @inheritdoc IOracle\n function circuitChainlink() public pure override returns (AggregatorV3Interface[] memory) {\n AggregatorV3Interface[] memory _circuitChainlink = new AggregatorV3Interface[](2);\n // Oracle ETH/USD\n _circuitChainlink[0] = AggregatorV3Interface(0xF9680D99D6C9589e2a93a78A04A279e509205945);\n // Oracle XAU/USD\n _circuitChainlink[1] = AggregatorV3Interface(0x0C466540B2ee1a31b441671eac0ca886e051E410);\n return _circuitChainlink;\n }\n}\n" + }, + "contracts/oracle/KeeperRegistry.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\nimport \"@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol\";\nimport \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\nimport \"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\";\n\nimport \"../interfaces/ICoreBorrow.sol\";\nimport \"../interfaces/IKeeperRegistry.sol\";\n\n/// @title KeeperRegistry\n/// @notice Maintains a mapping of keepers authorized to use the core module just after oracle updates\n/// @author Angle Labs, Inc.\ncontract KeeperRegistry is Initializable, IKeeperRegistry {\n using SafeERC20 for IERC20;\n\n /// @notice Contract handling access control\n ICoreBorrow public coreBorrow;\n\n /// @notice Trusted EOAs - needs to be tx.origin\n mapping(address => uint256) public trusted;\n\n uint256[48] private __gap;\n\n // =================================== EVENTS ==================================\n\n event TrustedToggled(address indexed wallet, bool trust);\n\n // =================================== ERRORS ==================================\n\n error NotGovernorOrGuardian();\n error NotTrusted();\n error ZeroAddress();\n\n // ================================= MODIFIERS =================================\n\n /// @notice Checks whether the `msg.sender` has the governor role or the guardian role\n modifier onlyGovernorOrGuardian() {\n if (!coreBorrow.isGovernorOrGuardian(msg.sender)) revert NotGovernorOrGuardian();\n _;\n }\n\n // ================================ CONSTRUCTOR ================================\n\n constructor() initializer {}\n\n function initialize(ICoreBorrow _coreBorrow) public initializer {\n if (address(_coreBorrow) == address(0)) revert ZeroAddress();\n coreBorrow = _coreBorrow;\n }\n\n // =============================== MAIN FUNCTIONS ==============================\n\n /// @notice Adds or removes a trusted keeper bot\n function toggleTrusted(address eoa) external onlyGovernorOrGuardian {\n uint256 trustedStatus = 1 - trusted[eoa];\n trusted[eoa] = trustedStatus;\n emit TrustedToggled(eoa, trustedStatus == 1);\n }\n\n /// @inheritdoc IKeeperRegistry\n function isTrusted(address caller) external view returns (bool) {\n return trusted[caller] == 1;\n }\n}\n" + }, + "contracts/oracle/OracleChainlinkMulti.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\nimport \"@chainlink/contracts/src/v0.8/interfaces/AggregatorV3Interface.sol\";\n\nimport \"./BaseOracleChainlinkMulti.sol\";\n\n/// @title OracleChainlinkMulti\n/// @author Angle Labs, Inc.\n/// @notice Oracle contract, one contract is deployed per collateral/stablecoin pair\n/// @dev This contract concerns an oracle that uses Chainlink with multiple pools to read from\n/// @dev Typically we expect to use this contract to read like the ETH/USD and then USD/EUR feed\ncontract OracleChainlinkMulti is BaseOracleChainlinkMulti {\n // ========================= Parameters and References =========================\n\n /// @notice Chainlink pools, the order of the pools has to be the order in which they are read for the computation\n /// of the price\n AggregatorV3Interface[] internal _circuitChainlink;\n /// @notice Whether each rate for the pairs in `circuitChainlink` should be multiplied or divided\n uint8[] public circuitChainIsMultiplied;\n /// @notice Decimals for each Chainlink pairs\n uint8[] public chainlinkDecimals;\n /// @notice Unit of the stablecoin\n uint256 public immutable outBase;\n /// @notice Description of the assets concerned by the oracle and the price outputted\n string public description;\n\n // ===================================== Error =================================\n\n error IncompatibleLengths();\n\n /// @notice Constructor for an oracle using Chainlink with multiple pools to read from\n /// @param circuitChainlink_ Chainlink pool addresses (in order)\n /// @param _circuitChainIsMultiplied Whether we should multiply or divide by this rate\n /// @param _outBase Unit of the stablecoin (or the out asset) associated to the oracle\n /// @param _stalePeriod Minimum feed update frequency for the oracle to not revert\n /// @param _treasury Treasury associated to the VaultManager which reads from this feed\n /// @param _description Description of the assets concerned by the oracle\n /// @dev For instance, if this oracle is supposed to give the price of ETH in EUR, and if the agEUR\n /// stablecoin associated to EUR has 18 decimals, then `outBase` should be 10**18\n constructor(\n address[] memory circuitChainlink_,\n uint8[] memory _circuitChainIsMultiplied,\n uint256 _outBase,\n uint32 _stalePeriod,\n address _treasury,\n string memory _description\n ) BaseOracleChainlinkMulti(_stalePeriod, _treasury) {\n outBase = _outBase;\n description = _description;\n uint256 circuitLength = circuitChainlink_.length;\n if (circuitLength == 0 || circuitLength != _circuitChainIsMultiplied.length) revert IncompatibleLengths();\n for (uint256 i; i < circuitLength; ++i) {\n AggregatorV3Interface _pool = AggregatorV3Interface(circuitChainlink_[i]);\n _circuitChainlink.push(_pool);\n chainlinkDecimals.push(_pool.decimals());\n }\n circuitChainIsMultiplied = _circuitChainIsMultiplied;\n }\n\n // ============================= Reading Oracles ===============================\n\n /// @inheritdoc IOracle\n function circuitChainlink() public view override returns (AggregatorV3Interface[] memory) {\n return _circuitChainlink;\n }\n\n /// @inheritdoc IOracle\n function read() external view override returns (uint256 quoteAmount) {\n quoteAmount = outBase;\n uint256 circuitLength = _circuitChainlink.length;\n for (uint256 i; i < circuitLength; ++i) {\n quoteAmount = _readChainlinkFeed(\n quoteAmount,\n _circuitChainlink[i],\n circuitChainIsMultiplied[i],\n chainlinkDecimals[i]\n );\n }\n }\n}\n" + }, + "contracts/settlement/Settlement.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\nimport \"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\";\nimport \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\nimport \"@openzeppelin/contracts/token/ERC20/extensions/IERC20Metadata.sol\";\n\nimport \"../interfaces/IAgToken.sol\";\nimport \"../interfaces/ISwapper.sol\";\nimport \"../interfaces/IVaultManager.sol\";\n\n/// @title Settlement\n/// @author Angle Labs, Inc.\n/// @notice Settlement Contract for a VaultManager\n/// @dev This settlement contract should be activated by a careful governance which needs to have performed\n/// some key operations before activating this contract\n/// @dev In case of global settlement, there should be one settlement contract per `VaultManager`\ncontract Settlement {\n using SafeERC20 for IERC20;\n\n /// @notice Base used for parameter computation\n uint256 public constant BASE_PARAMS = 10 ** 9;\n /// @notice Base used for interest computation\n uint256 public constant BASE_INTEREST = 10 ** 27;\n /// @notice Base used for exchange rate computation. It is assumed\n /// that stablecoins have this base\n uint256 public constant BASE_STABLECOIN = 10 ** 18;\n /// @notice Duration of the claim period for over-collateralized vaults\n uint256 public constant OVER_COLLATERALIZED_CLAIM_DURATION = 3 * 24 * 3600;\n\n // =============== Immutable references set in the constructor =================\n\n /// @notice `VaultManager` of this settlement contract\n IVaultManager public immutable vaultManager;\n /// @notice Reference to the stablecoin supported by the `VaultManager` contract\n IAgToken public immutable stablecoin;\n /// @notice Reference to the collateral supported by the `VaultManager`\n IERC20 public immutable collateral;\n /// @notice Base of the collateral\n uint256 internal immutable _collatBase;\n\n // ================ Variables frozen at settlement activation ==================\n\n /// @notice Value of the oracle for the collateral/stablecoin pair\n uint256 public oracleValue;\n /// @notice Value of the interest accumulator at settlement activation\n uint256 public interestAccumulator;\n /// @notice Timestamp at which settlement was activated\n uint256 public activationTimestamp;\n /// @notice Collateral factor of the `VaultManager`\n uint64 public collateralFactor;\n\n // =================== Variables updated during the process ====================\n\n /// @notice How much collateral you can get from stablecoins\n uint256 public collateralStablecoinExchangeRate;\n /// @notice Amount of collateral that will be left over at the end of the process\n uint256 public leftOverCollateral;\n /// @notice Whether the `collateralStablecoinExchangeRate` has been computed\n bool public exchangeRateComputed;\n /// @notice Maps a vault to 1 if it was claimed by its owner\n mapping(uint256 => uint256) public vaultCheck;\n\n // ================================ Events =====================================\n\n event GlobalClaimPeriodActivated(uint256 _collateralStablecoinExchangeRate);\n event Recovered(address indexed tokenAddress, address indexed to, uint256 amount);\n event SettlementActivated(uint256 startTimestamp);\n event VaultClaimed(uint256 vaultID, uint256 stablecoinAmount, uint256 collateralAmount);\n\n // ================================ Errors =====================================\n\n error GlobalClaimPeriodNotStarted();\n error InsolventVault();\n error NotGovernor();\n error NotOwner();\n error RestrictedClaimPeriodNotEnded();\n error SettlementNotInitialized();\n error VaultAlreadyClaimed();\n\n /// @notice Constructor of the contract\n /// @param _vaultManager Address of the `VaultManager` associated to this `Settlement` contract\n /// @dev Out of safety, this constructor reads values from the `VaultManager` contract directly\n constructor(IVaultManager _vaultManager) {\n vaultManager = _vaultManager;\n stablecoin = _vaultManager.stablecoin();\n collateral = _vaultManager.collateral();\n _collatBase = 10 ** (IERC20Metadata(address(collateral)).decimals());\n }\n\n /// @notice Checks whether the `msg.sender` has the governor role or not\n modifier onlyGovernor() {\n if (!(vaultManager.treasury().isGovernor(msg.sender))) revert NotGovernor();\n _;\n }\n\n /// @notice Activates the settlement contract\n /// @dev When calling this function governance should make sure to have:\n /// 1. Accrued the interest rate on the contract\n /// 2. Paused the contract\n /// 3. Recovered all the collateral available in the `VaultManager` contract either\n /// by doing a contract upgrade or by calling a `recoverERC20` method if supported\n function activateSettlement() external onlyGovernor {\n oracleValue = (vaultManager.oracle()).read();\n interestAccumulator = vaultManager.interestAccumulator();\n activationTimestamp = block.timestamp;\n collateralFactor = vaultManager.collateralFactor();\n emit SettlementActivated(block.timestamp);\n }\n\n /// @notice Allows the owner of an over-collateralized vault to claim its collateral upon bringing back all owed stablecoins\n /// @param vaultID ID of the vault to claim\n /// @param to Address to which collateral should be sent\n /// @param who Address which should be notified if needed of the transfer of stablecoins and collateral\n /// @param data Data to pass to the `who` contract for it to successfully give the correct amount of stablecoins\n /// to the `msg.sender` address\n /// @return Amount of collateral sent to the `to` address\n /// @return Amount of stablecoins sent to the contract\n /// @dev Claiming can only happen short after settlement activation\n /// @dev A vault cannot be claimed twice and only the owner of the vault can claim it (regardless of the approval logic)\n /// @dev Only over-collateralized vaults can be claimed from this medium\n function claimOverCollateralizedVault(\n uint256 vaultID,\n address to,\n address who,\n bytes memory data\n ) external returns (uint256, uint256) {\n if (activationTimestamp == 0 || block.timestamp > activationTimestamp + OVER_COLLATERALIZED_CLAIM_DURATION)\n revert SettlementNotInitialized();\n if (vaultCheck[vaultID] == 1) revert VaultAlreadyClaimed();\n if (vaultManager.ownerOf(vaultID) != msg.sender) revert NotOwner();\n (uint256 collateralAmount, uint256 normalizedDebt) = vaultManager.vaultData(vaultID);\n uint256 vaultDebt = (normalizedDebt * interestAccumulator) / BASE_INTEREST;\n if (collateralAmount * oracleValue * collateralFactor < vaultDebt * BASE_PARAMS * _collatBase)\n revert InsolventVault();\n vaultCheck[vaultID] = 1;\n emit VaultClaimed(vaultID, vaultDebt, collateralAmount);\n return _handleRepay(collateralAmount, vaultDebt, to, who, data);\n }\n\n /// @notice Activates the global claim period by setting the `collateralStablecoinExchangeRate` which is going to\n /// dictate how much of collateral will be recoverable for each stablecoin\n /// @dev This function can only be called by the governor in order to allow it in case multiple settlements happen across\n /// different `VaultManager` to rebalance the amount of stablecoins on each to make sure that across all settlement contracts\n /// a similar value of collateral can be obtained against a similar value of stablecoins\n function activateGlobalClaimPeriod() external onlyGovernor {\n if (activationTimestamp == 0 || block.timestamp <= activationTimestamp + OVER_COLLATERALIZED_CLAIM_DURATION)\n revert RestrictedClaimPeriodNotEnded();\n uint256 collateralBalance = collateral.balanceOf(address(this));\n uint256 leftOverDebt = (vaultManager.totalNormalizedDebt() * interestAccumulator) / BASE_INTEREST;\n uint256 stablecoinBalance = stablecoin.balanceOf(address(this));\n // How much 1 of stablecoin will give you in collateral\n uint256 _collateralStablecoinExchangeRate;\n\n if (stablecoinBalance < leftOverDebt) {\n // The left over debt is the total debt minus the stablecoins which have already been accumulated\n // in the first phase\n leftOverDebt -= stablecoinBalance;\n // If you control all the debt, then you are entitled to get all the collateral left in the protocol\n _collateralStablecoinExchangeRate = (collateralBalance * BASE_STABLECOIN) / leftOverDebt;\n // But at the same time, you cannot get more collateral than the value of the stablecoins you brought\n uint256 maxExchangeRate = (BASE_STABLECOIN * _collatBase) / oracleValue;\n if (_collateralStablecoinExchangeRate >= maxExchangeRate) {\n // In this situation, we're sure that `leftOverCollateral` will be positive: governance should be wary\n // to call `recoverERC20` short after though as there's nothing that is going to prevent people to redeem\n // more stablecoins than the `leftOverDebt`\n leftOverCollateral = collateralBalance - (leftOverDebt * _collatBase) / oracleValue;\n _collateralStablecoinExchangeRate = maxExchangeRate;\n }\n }\n exchangeRateComputed = true;\n // In the else case where there is no debt left, you cannot get anything from your stablecoins\n // and so the `collateralStablecoinExchangeRate` is null\n collateralStablecoinExchangeRate = _collateralStablecoinExchangeRate;\n emit GlobalClaimPeriodActivated(_collateralStablecoinExchangeRate);\n }\n\n /// @notice Allows to claim collateral from stablecoins\n /// @param to Address to which collateral should be sent\n /// @param who Address which should be notified if needed of the transfer of stablecoins and collateral\n /// @param data Data to pass to the `who` contract for it to successfully give the correct amount of stablecoins\n /// to the `msg.sender` address\n /// @return Amount of collateral sent to the `to` address\n /// @return Amount of stablecoins sent to the contract\n /// @dev This function reverts if the `collateralStablecoinExchangeRate` is null and hence if the global claim period has\n /// not been activated\n function claimCollateralFromStablecoins(\n uint256 stablecoinAmount,\n address to,\n address who,\n bytes memory data\n ) external returns (uint256, uint256) {\n if (!exchangeRateComputed) revert GlobalClaimPeriodNotStarted();\n return\n _handleRepay(\n (stablecoinAmount * collateralStablecoinExchangeRate) / BASE_STABLECOIN,\n stablecoinAmount,\n to,\n who,\n data\n );\n }\n\n /// @notice Handles the simultaneous repayment of stablecoins with a transfer of collateral\n /// @param collateralAmountToGive Amount of collateral the contract should give\n /// @param stableAmountToRepay Amount of stablecoins the contract should burn from the call\n /// @param to Address to which stablecoins should be sent\n /// @param who Address which should be notified if needed of the transfer\n /// @param data Data to pass to the `who` contract for it to successfully give the correct amount of stablecoins\n /// to the `msg.sender` address\n /// @dev This function allows for capital-efficient claims of collateral from stablecoins\n function _handleRepay(\n uint256 collateralAmountToGive,\n uint256 stableAmountToRepay,\n address to,\n address who,\n bytes memory data\n ) internal returns (uint256, uint256) {\n collateral.safeTransfer(to, collateralAmountToGive);\n if (data.length != 0) {\n ISwapper(who).swap(\n collateral,\n IERC20(address(stablecoin)),\n msg.sender,\n stableAmountToRepay,\n collateralAmountToGive,\n data\n );\n }\n stablecoin.transferFrom(msg.sender, address(this), stableAmountToRepay);\n return (collateralAmountToGive, stableAmountToRepay);\n }\n\n /// @notice Recovers leftover tokens from the contract or tokens that were mistakenly sent to the contract\n /// @param tokenAddress Address of the token to recover\n /// @param to Address to send the remaining tokens to\n /// @param amountToRecover Amount to recover from the contract\n /// @dev Governors cannot recover more collateral than what would be leftover from the contract\n /// @dev This function can be used to rebalance stablecoin balances across different settlement contracts\n /// to make sure every stablecoin can be redeemed for the same value of collateral\n /// @dev It can also be used to recover tokens that are mistakenly sent to this contract\n function recoverERC20(address tokenAddress, address to, uint256 amountToRecover) external onlyGovernor {\n if (tokenAddress == address(collateral)) {\n if (!exchangeRateComputed) revert GlobalClaimPeriodNotStarted();\n leftOverCollateral -= amountToRecover;\n collateral.safeTransfer(to, amountToRecover);\n } else {\n IERC20(tokenAddress).safeTransfer(to, amountToRecover);\n }\n emit Recovered(tokenAddress, to, amountToRecover);\n }\n}\n" + }, + "contracts/swapper/Swapper.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\n/*\n * █ \n ***** ▓▓▓ \n * ▓▓▓▓▓▓▓ \n * ///. ▓▓▓▓▓▓▓▓▓▓▓▓▓ \n ***** //////// ▓▓▓▓▓▓▓ \n * ///////////// ▓▓▓ \n ▓▓ ////////////////// █ ▓▓ \n ▓▓ ▓▓ /////////////////////// ▓▓ ▓▓ \n ▓▓ ▓▓ //////////////////////////// ▓▓ ▓▓ \n ▓▓ ▓▓ /////////▓▓▓///////▓▓▓///////// ▓▓ ▓▓ \n ▓▓ ,////////////////////////////////////// ▓▓ ▓▓ \n ▓▓ ////////////////////////////////////////// ▓▓ \n ▓▓ //////////////////////▓▓▓▓///////////////////// \n ,//////////////////////////////////////////////////// \n .////////////////////////////////////////////////////////// \n .//////////////////////////██.,//////////////////////////█ \n .//////////////////////████..,./////////////////////██ \n ...////////////////███████.....,.////////////////███ \n ,.,////////////████████ ........,///////////████ \n .,.,//////█████████ ,.......///////████ \n ,..//████████ ........./████ \n ..,██████ .....,███ \n .██ ,.,█ \n \n \n \n ▓▓ ▓▓▓▓▓▓▓▓▓▓ ▓▓▓▓▓▓▓▓▓▓ ▓▓ ▓▓▓▓▓▓▓▓▓▓ \n ▓▓▓▓▓▓ ▓▓▓ ▓▓▓ ▓▓▓ ▓▓ ▓▓ ▓▓▓▓ \n ▓▓▓ ▓▓▓ ▓▓▓ ▓▓▓ ▓▓▓ ▓▓▓ ▓▓ ▓▓▓▓▓ \n ▓▓▓ ▓▓ ▓▓▓ ▓▓▓ ▓▓▓▓▓▓▓▓▓▓ ▓▓▓▓▓▓▓▓▓▓ ▓▓▓▓▓▓▓▓▓▓ \n*/\n\npragma solidity ^0.8.12;\n\nimport \"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\";\nimport \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\n\nimport \"../interfaces/IAngleRouterSidechain.sol\";\nimport \"../interfaces/ICoreBorrow.sol\";\nimport \"../interfaces/ISwapper.sol\";\nimport \"../interfaces/external/lido/IWStETH.sol\";\nimport \"../interfaces/external/uniswap/IUniswapRouter.sol\";\n\n// ==================================== ENUM ===================================\n\n/// @notice All possible swaps\nenum SwapType {\n UniswapV3,\n oneInch,\n AngleRouter,\n Leverage,\n None\n}\n\n/// @title Swapper\n/// @author Angle Labs, Inc.\n/// @notice Swapper contract facilitating interactions with Angle VaultManager contracts, notably\n/// liquidation and leverage transactions\ncontract Swapper is ISwapper {\n using SafeERC20 for IERC20;\n\n // ===================== CONSTANTS AND IMMUTABLE VARIABLES =====================\n\n /// @notice Reference to the `CoreBorrow` contract of the module which handles all AccessControl logic\n ICoreBorrow public immutable core;\n /// @notice Uniswap Router contract\n IUniswapV3Router public immutable uniV3Router;\n /// @notice 1inch Router\n address public immutable oneInch;\n /// @notice AngleRouter\n IAngleRouterSidechain public immutable angleRouter;\n\n // =================================== ERRORS ==================================\n\n error EmptyReturnMessage();\n error IncompatibleLengths();\n error NotGovernorOrGuardian();\n error TooSmallAmountOut();\n error ZeroAddress();\n\n /// @notice Constructor of the contract\n /// @param _core Core address\n /// @param _uniV3Router UniswapV3 Router address\n /// @param _oneInch 1inch Router address\n /// @param _angleRouter AngleRouter contract address\n constructor(\n ICoreBorrow _core,\n IUniswapV3Router _uniV3Router,\n address _oneInch,\n IAngleRouterSidechain _angleRouter\n ) {\n if (address(_core) == address(0) || _oneInch == address(0) || address(_angleRouter) == address(0))\n revert ZeroAddress();\n core = _core;\n uniV3Router = _uniV3Router;\n oneInch = _oneInch;\n angleRouter = _angleRouter;\n }\n\n // ========================= EXTERNAL ACCESS FUNCTIONS =========================\n\n /// @inheritdoc ISwapper\n /// @dev This function swaps the `inToken` to the `outToken` by doing a UniV3 swap, a 1inch swap or by interacting\n /// with the `AngleRouter` contract\n /// @dev One slippage check is performed at the end of the call\n /// @dev In this implementation, the function tries to make sure that the `outTokenRecipient` address has at the end\n /// of the call `outTokenOwed`, leftover tokens are sent to a `to` address which by default is the `outTokenRecipient`\n function swap(\n IERC20 inToken,\n IERC20 outToken,\n address outTokenRecipient,\n uint256 outTokenOwed,\n uint256 inTokenObtained,\n bytes memory data\n ) external {\n // Address to receive the surplus amount of token at the end of the call\n address to;\n // For slippage protection, it is checked at the end of the call\n uint256 minAmountOut;\n // Type of the swap to execute: if `swapType == 4`, then it is optional to swap\n uint256 swapType;\n // We're reusing the `data` variable (it can be `path` on UniswapV3, a payload for 1inch or like encoded actions\n // for a router call)\n (to, minAmountOut, swapType, data) = abi.decode(data, (address, uint256, uint256, bytes));\n\n to = (to == address(0)) ? outTokenRecipient : to;\n\n _swap(inToken, inTokenObtained, SwapType(swapType), data);\n\n // A final slippage check is performed after the swaps\n uint256 outTokenBalance = outToken.balanceOf(address(this));\n if (outTokenBalance < minAmountOut) revert TooSmallAmountOut();\n\n // The `outTokenRecipient` may already have enough in balance, in which case there's no need to transfer\n // to this address the token and everything can be given to the `to` address\n uint256 outTokenBalanceRecipient = outToken.balanceOf(outTokenRecipient);\n if (outTokenBalanceRecipient >= outTokenOwed || to == outTokenRecipient)\n outToken.safeTransfer(to, outTokenBalance);\n else {\n // The `outTokenRecipient` should receive the delta to make sure its end balance is equal to `outTokenOwed`\n // Any leftover in this case is sent to the `to` address\n // The function reverts if it did not obtain more than `outTokenOwed - outTokenBalanceRecipient` from the swap\n outToken.safeTransfer(outTokenRecipient, outTokenOwed - outTokenBalanceRecipient);\n outToken.safeTransfer(to, outTokenBalanceRecipient + outTokenBalance - outTokenOwed);\n }\n // Reusing the `inTokenObtained` variable for the `inToken` balance\n // Sending back the remaining amount of inTokens to the `to` address: it is possible that not the full `inTokenObtained`\n // is swapped to `outToken` if we're using the `1inch` payload\n inTokenObtained = inToken.balanceOf(address(this));\n if (inTokenObtained != 0) inToken.safeTransfer(to, inTokenObtained);\n }\n\n // ============================ GOVERNANCE FUNCTION ============================\n\n /// @notice Changes allowances of this contract for different tokens\n /// @param tokens Addresses of the tokens to allow\n /// @param spenders Addresses to allow transfer\n /// @param amounts Amounts to allow\n function changeAllowance(\n IERC20[] calldata tokens,\n address[] calldata spenders,\n uint256[] calldata amounts\n ) external {\n if (!core.isGovernorOrGuardian(msg.sender)) revert NotGovernorOrGuardian();\n uint256 tokensLength = tokens.length;\n if (tokensLength != spenders.length || tokensLength != amounts.length) revert IncompatibleLengths();\n for (uint256 i; i < tokensLength; ++i) {\n _changeAllowance(tokens[i], spenders[i], amounts[i]);\n }\n }\n\n // ========================= INTERNAL UTILITY FUNCTIONS ========================\n\n /// @notice Internal version of the `_changeAllowance` function\n function _changeAllowance(IERC20 token, address spender, uint256 amount) internal {\n uint256 currentAllowance = token.allowance(address(this), spender);\n // In case `currentAllowance < type(uint256).max / 2` and we want to increase it:\n // Do nothing (to handle tokens that need reapprovals to 0 and save gas)\n if (currentAllowance < amount && currentAllowance < type(uint256).max / 2) {\n token.safeIncreaseAllowance(spender, amount - currentAllowance);\n } else if (currentAllowance > amount) {\n token.safeDecreaseAllowance(spender, currentAllowance - amount);\n }\n }\n\n /// @notice Checks the allowance for a contract and updates it to the max if it is not big enough\n /// @param token Token for which allowance should be checked\n /// @param spender Address to grant allowance to\n /// @param amount Minimum amount of tokens needed for the allowance\n function _checkAllowance(IERC20 token, address spender, uint256 amount) internal {\n uint256 currentAllowance = token.allowance(address(this), spender);\n if (currentAllowance < amount) token.safeIncreaseAllowance(spender, type(uint256).max - currentAllowance);\n }\n\n /// @notice Performs a swap using either Uniswap, 1inch. This function can also stake stETH to wstETH\n /// @param inToken Token to swap\n /// @param amount Amount of tokens to swap\n /// @param swapType Type of the swap to perform\n /// @param args Extra args for the swap: in the case of Uniswap it should be a path, for 1inch it should be\n /// a payload\n /// @dev This function does nothing if `swapType` is None and it simply passes on the `amount` it received\n /// @dev No slippage is specified in the actions given here as a final slippage check is performed\n /// after the call to this function\n function _swap(IERC20 inToken, uint256 amount, SwapType swapType, bytes memory args) internal {\n if (swapType == SwapType.UniswapV3) _swapOnUniswapV3(inToken, amount, args);\n else if (swapType == SwapType.oneInch) _swapOn1inch(inToken, args);\n else if (swapType == SwapType.AngleRouter) _angleRouterActions(inToken, args);\n else if (swapType == SwapType.Leverage) _swapLeverage(args);\n }\n\n /// @notice Performs a UniswapV3 swap\n /// @param inToken Token to swap\n /// @param amount Amount of tokens to swap\n /// @param path Path for the UniswapV3 swap: this encodes the out token that is going to be obtained\n /// @dev This function does not check the out token obtained here: if it is wrongly specified, either\n /// the `swap` function could fail or these tokens could stay on the contract\n function _swapOnUniswapV3(IERC20 inToken, uint256 amount, bytes memory path) internal returns (uint256 amountOut) {\n // We need more than `amount` of allowance to the contract\n _checkAllowance(inToken, address(uniV3Router), amount);\n amountOut = uniV3Router.exactInput(ExactInputParams(path, address(this), block.timestamp, amount, 0));\n }\n\n /// @notice Allows to swap any token to an accepted collateral via 1inch API\n /// @param inToken Token received for the 1inch swap\n /// @param payload Bytes needed for 1inch API\n function _swapOn1inch(IERC20 inToken, bytes memory payload) internal returns (uint256 amountOut) {\n _changeAllowance(inToken, oneInch, type(uint256).max);\n //solhint-disable-next-line\n (bool success, bytes memory result) = oneInch.call(payload);\n if (!success) _revertBytes(result);\n amountOut = abi.decode(result, (uint256));\n }\n\n /// @notice Performs actions with the router contract of the protocol on the corresponding chain\n /// @param inToken Token concerned by the action and for which\n function _angleRouterActions(IERC20 inToken, bytes memory args) internal {\n (ActionType[] memory actions, bytes[] memory actionData) = abi.decode(args, (ActionType[], bytes[]));\n _changeAllowance(inToken, address(angleRouter), type(uint256).max);\n PermitType[] memory permits;\n angleRouter.mixer(permits, actions, actionData);\n }\n\n /// @notice Allows to take leverage or deleverage via a specific contract\n /// @param payload Bytes needed for 1inch API\n /// @dev This function is to be implemented if the swapper concerns a token that requires some actions\n /// not supported by 1inch or UniV3\n function _swapLeverage(bytes memory payload) internal virtual returns (uint256 amountOut) {}\n\n /// @notice Internal function used for error handling\n /// @param errMsg Error message received\n function _revertBytes(bytes memory errMsg) internal pure {\n if (errMsg.length != 0) {\n //solhint-disable-next-line\n assembly {\n revert(add(32, errMsg), mload(errMsg))\n }\n }\n revert EmptyReturnMessage();\n }\n}\n" + }, + "contracts/treasury/Treasury.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\n/*\n * █ \n ***** ▓▓▓ \n * ▓▓▓▓▓▓▓ \n * ///. ▓▓▓▓▓▓▓▓▓▓▓▓▓ \n ***** //////// ▓▓▓▓▓▓▓ \n * ///////////// ▓▓▓ \n ▓▓ ////////////////// █ ▓▓ \n ▓▓ ▓▓ /////////////////////// ▓▓ ▓▓ \n ▓▓ ▓▓ //////////////////////////// ▓▓ ▓▓ \n ▓▓ ▓▓ /////////▓▓▓///////▓▓▓///////// ▓▓ ▓▓ \n ▓▓ ,////////////////////////////////////// ▓▓ ▓▓ \n ▓▓ ////////////////////////////////////////// ▓▓ \n ▓▓ //////////////////////▓▓▓▓///////////////////// \n ,//////////////////////////////////////////////////// \n .////////////////////////////////////////////////////////// \n .//////////////////////////██.,//////////////////////////█ \n .//////////////////////████..,./////////////////////██ \n ...////////////////███████.....,.////////////////███ \n ,.,////////////████████ ........,///////////████ \n .,.,//////█████████ ,.......///////████ \n ,..//████████ ........./████ \n ..,██████ .....,███ \n .██ ,.,█ \n \n \n \n ▓▓ ▓▓▓▓▓▓▓▓▓▓ ▓▓▓▓▓▓▓▓▓▓ ▓▓ ▓▓▓▓▓▓▓▓▓▓ \n ▓▓▓▓▓▓ ▓▓▓ ▓▓▓ ▓▓▓ ▓▓ ▓▓ ▓▓▓▓ \n ▓▓▓ ▓▓▓ ▓▓▓ ▓▓▓ ▓▓▓ ▓▓▓ ▓▓ ▓▓▓▓▓ \n ▓▓▓ ▓▓ ▓▓▓ ▓▓▓ ▓▓▓▓▓▓▓▓▓▓ ▓▓▓▓▓▓▓▓▓▓ ▓▓▓▓▓▓▓▓▓▓ \n*/\n\npragma solidity ^0.8.12;\n\nimport \"@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol\";\nimport \"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\";\nimport \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\n\nimport \"../interfaces/IAgToken.sol\";\nimport \"../interfaces/ICoreBorrow.sol\";\nimport \"../interfaces/IFlashAngle.sol\";\nimport \"../interfaces/ITreasury.sol\";\nimport \"../interfaces/IVaultManager.sol\";\n\n/// @title Treasury\n/// @author Angle Labs, Inc.\n/// @notice Treasury of Angle Borrowing Module doing the accounting across all VaultManagers for\n/// a given stablecoin\ncontract Treasury is ITreasury, Initializable {\n using SafeERC20 for IERC20;\n\n /// @notice Base used for parameter computation\n uint256 public constant BASE_9 = 1e9;\n\n // ================================= REFERENCES ================================\n\n /// @notice Reference to the `CoreBorrow` contract of the module which handles all AccessControl logic\n ICoreBorrow public core;\n /// @notice Flash Loan Module with a minter right on the stablecoin\n IFlashAngle public flashLoanModule;\n /// @inheritdoc ITreasury\n IAgToken public stablecoin;\n /// @notice Address responsible for handling the surplus made by the treasury\n address public surplusManager;\n /// @notice List of the accepted `VaultManager` of the protocol\n address[] public vaultManagerList;\n /// @notice Maps an address to 1 if it was initialized as a `VaultManager` contract\n mapping(address => uint256) public vaultManagerMap;\n\n // ================================= VARIABLES =================================\n\n /// @notice Amount of bad debt (unbacked stablecoin) accumulated across all `VaultManager` contracts\n /// linked to this stablecoin\n uint256 public badDebt;\n /// @notice Surplus amount accumulated by the contract waiting to be distributed to governance. Technically\n /// only a share of this `surplusBuffer` will go to governance. Once a share of the surplus buffer has been\n /// given to governance, then this surplus is reset\n uint256 public surplusBuffer;\n\n // ================================= PARAMETER =================================\n\n /// @notice Share of the `surplusBuffer` distributed to governance (in `BASE_9`)\n uint64 public surplusForGovernance;\n\n // =================================== EVENTS ==================================\n\n event BadDebtUpdated(uint256 badDebtValue);\n event CoreUpdated(address indexed _core);\n event NewTreasurySet(address indexed _treasury);\n event Recovered(address indexed token, address indexed to, uint256 amount);\n event SurplusBufferUpdated(uint256 surplusBufferValue);\n event SurplusForGovernanceUpdated(uint64 _surplusForGovernance);\n event SurplusManagerUpdated(address indexed _surplusManager);\n event VaultManagerToggled(address indexed vaultManager);\n\n // =================================== ERRORS ==================================\n\n error AlreadyVaultManager();\n error InvalidAddress();\n error InvalidTreasury();\n error NotCore();\n error NotGovernor();\n error NotVaultManager();\n error RightsNotRemoved();\n error TooBigAmount();\n error TooHighParameterValue();\n error ZeroAddress();\n\n // ================================== MODIFIER =================================\n\n /// @notice Checks whether the `msg.sender` has the governor role or not\n modifier onlyGovernor() {\n if (!core.isGovernor(msg.sender)) revert NotGovernor();\n _;\n }\n\n /// @notice Initializes the treasury contract\n /// @param _core Address of the `CoreBorrow` contract of the module\n /// @param _stablecoin Address of the stablecoin\n function initialize(ICoreBorrow _core, IAgToken _stablecoin) public virtual initializer {\n if (address(_stablecoin) == address(0) || address(_core) == address(0)) revert ZeroAddress();\n core = _core;\n stablecoin = _stablecoin;\n }\n\n /// @custom:oz-upgrades-unsafe-allow constructor\n constructor() initializer {}\n\n // =============================== VIEW FUNCTIONS ==============================\n\n /// @inheritdoc ITreasury\n function isGovernor(address admin) external view returns (bool) {\n return core.isGovernor(admin);\n }\n\n /// @inheritdoc ITreasury\n function isGovernorOrGuardian(address admin) external view returns (bool) {\n return core.isGovernorOrGuardian(admin);\n }\n\n /// @inheritdoc ITreasury\n function isVaultManager(address _vaultManager) external view returns (bool) {\n return vaultManagerMap[_vaultManager] == 1;\n }\n\n // ===================== EXTERNAL PERMISSIONLESS FUNCTIONS =====================\n\n /// @notice Fetches the surplus accrued across all the `VaultManager` contracts controlled by this\n /// `Treasury` contract as well as from the fees of the `FlashLoan` module\n /// @return Surplus buffer value at the end of the call\n /// @return Bad debt value at the end of the call\n /// @dev This function pools surplus and bad debt across all contracts and then updates the `surplusBuffer`\n /// (or the `badDebt` if more losses were made than profits)\n function fetchSurplusFromAll() external returns (uint256, uint256) {\n return _fetchSurplusFromAll();\n }\n\n /// @notice Fetches the surplus accrued in the flash loan module and updates the `surplusBuffer`\n /// @return Surplus buffer value at the end of the call\n /// @return Bad debt value at the end of the call\n /// @dev This function fails if the `flashLoanModule` has not been initialized yet\n function fetchSurplusFromFlashLoan() external returns (uint256, uint256) {\n uint256 surplusBufferValue = surplusBuffer + flashLoanModule.accrueInterestToTreasury(stablecoin);\n return _updateSurplusAndBadDebt(surplusBufferValue, badDebt);\n }\n\n /// @notice Pushes the surplus buffer to the `surplusManager` contract\n /// @return governanceAllocation Amount transferred to governance\n /// @dev It makes sure to fetch the surplus from all the contracts handled by this treasury to avoid\n /// the situation where rewards are still distributed to governance even though a `VaultManager` has made\n /// a big loss\n /// @dev Typically this function is to be called once every week by a keeper to distribute rewards to veANGLE\n /// holders\n /// @dev `stablecoin` must be an AgToken and hence `transfer` reverts if the call is not successful\n function pushSurplus() external returns (uint256 governanceAllocation) {\n address _surplusManager = surplusManager;\n if (_surplusManager == address(0)) {\n revert ZeroAddress();\n }\n (uint256 surplusBufferValue, ) = _fetchSurplusFromAll();\n surplusBuffer = 0;\n emit SurplusBufferUpdated(0);\n governanceAllocation = (surplusForGovernance * surplusBufferValue) / BASE_9;\n stablecoin.transfer(_surplusManager, governanceAllocation);\n }\n\n /// @notice Updates the bad debt of the protocol in case where the protocol has accumulated some revenue\n /// from an external source\n /// @param amount Amount to reduce the bad debt of\n /// @return badDebtValue Value of the bad debt at the end of the call\n /// @dev If the protocol has made a loss and managed to make some profits to recover for this loss (through\n /// a program like Olympus Pro), then this function needs to be called\n /// @dev `badDebt` is simply reduced here by burning stablecoins\n /// @dev It is impossible to burn more than the `badDebt` otherwise this function could be used to manipulate\n /// the `surplusBuffer` and hence the amount going to governance\n function updateBadDebt(uint256 amount) external returns (uint256 badDebtValue) {\n stablecoin.burnSelf(amount, address(this));\n badDebtValue = badDebt - amount;\n badDebt = badDebtValue;\n emit BadDebtUpdated(badDebtValue);\n }\n\n // ========================= INTERNAL UTILITY FUNCTIONS ========================\n\n /// @notice Internal version of the `fetchSurplusFromAll` function\n function _fetchSurplusFromAll() internal returns (uint256 surplusBufferValue, uint256 badDebtValue) {\n (surplusBufferValue, badDebtValue) = _fetchSurplusFromList(vaultManagerList);\n // It will fail anyway if the `flashLoanModule` is the zero address\n if (address(flashLoanModule) != address(0))\n surplusBufferValue += flashLoanModule.accrueInterestToTreasury(stablecoin);\n (surplusBufferValue, badDebtValue) = _updateSurplusAndBadDebt(surplusBufferValue, badDebtValue);\n }\n\n /// @notice Fetches the surplus from a list of `VaultManager` addresses without modifying the\n /// `surplusBuffer` and `badDebtValue`\n /// @return surplusBufferValue Value the `surplusBuffer` should have after the call if it was updated\n /// @return badDebtValue Value the `badDebt` should have after the call if it was updated\n /// @dev This internal function is never to be called alone, and should always be called in conjunction\n /// with the `_updateSurplusAndBadDebt` function\n function _fetchSurplusFromList(\n address[] memory vaultManagers\n ) internal returns (uint256 surplusBufferValue, uint256 badDebtValue) {\n badDebtValue = badDebt;\n surplusBufferValue = surplusBuffer;\n uint256 newSurplus;\n uint256 newBadDebt;\n uint256 vaultManagersLength = vaultManagers.length;\n for (uint256 i; i < vaultManagersLength; ++i) {\n (newSurplus, newBadDebt) = IVaultManager(vaultManagers[i]).accrueInterestToTreasury();\n surplusBufferValue += newSurplus;\n badDebtValue += newBadDebt;\n }\n }\n\n /// @notice Updates the `surplusBuffer` and the `badDebt` from updated values after calling the flash loan module\n /// and/or a list of `VaultManager` contracts\n /// @param surplusBufferValue Value of the surplus buffer after the calls to the different modules\n /// @param badDebtValue Value of the bad debt after the calls to the different modules\n /// @return Value of the `surplusBuffer` corrected from the `badDebt`\n /// @return Value of the `badDebt` corrected from the `surplusBuffer` and from the surplus the treasury had accumulated\n /// previously\n /// @dev When calling this function, it is possible that there is a positive `surplusBufferValue` and `badDebtValue`,\n /// this function tries to reconcile both values and makes sure that we either have surplus or bad debt but not both\n /// at the same time\n function _updateSurplusAndBadDebt(\n uint256 surplusBufferValue,\n uint256 badDebtValue\n ) internal returns (uint256, uint256) {\n if (badDebtValue != 0) {\n // If we have bad debt we need to burn stablecoins that accrued to the protocol\n // We still need to make sure that we're not burning too much or as much as we can if the debt is big\n uint256 balance = stablecoin.balanceOf(address(this));\n // We are going to burn `min(balance, badDebtValue)`\n uint256 toBurn = balance <= badDebtValue ? balance : badDebtValue;\n stablecoin.burnSelf(toBurn, address(this));\n // If we burned more than `surplusBuffer`, we set surplus to 0. It means we had to tap into Treasury reserve\n surplusBufferValue = toBurn >= surplusBufferValue ? 0 : surplusBufferValue - toBurn;\n badDebtValue -= toBurn;\n // Note here that the stablecoin balance is necessarily greater than the surplus buffer, and so if\n // `surplusBuffer >= toBurn`, then `badDebtValue = toBurn`\n }\n surplusBuffer = surplusBufferValue;\n badDebt = badDebtValue;\n emit SurplusBufferUpdated(surplusBufferValue);\n emit BadDebtUpdated(badDebtValue);\n return (surplusBufferValue, badDebtValue);\n }\n\n /// @notice Adds a new `VaultManager`\n /// @param vaultManager `VaultManager` contract to add\n /// @dev This contract should have already been initialized with a correct treasury address\n /// @dev It's this function that gives the minter right to the `VaultManager`\n function _addVaultManager(address vaultManager) internal virtual {\n if (vaultManagerMap[vaultManager] == 1) revert AlreadyVaultManager();\n if (address(IVaultManager(vaultManager).treasury()) != address(this)) revert InvalidTreasury();\n vaultManagerMap[vaultManager] = 1;\n vaultManagerList.push(vaultManager);\n emit VaultManagerToggled(vaultManager);\n stablecoin.addMinter(vaultManager);\n }\n\n // ============================= GOVERNOR FUNCTIONS ============================\n\n /// @notice Adds a new minter for the stablecoin\n /// @param minter Minter address to add\n function addMinter(address minter) external virtual onlyGovernor {\n if (minter == address(0)) revert ZeroAddress();\n stablecoin.addMinter(minter);\n }\n\n /// @notice External wrapper for `_addVaultManager`\n function addVaultManager(address vaultManager) external virtual onlyGovernor {\n _addVaultManager(vaultManager);\n }\n\n /// @notice Removes a minter from the stablecoin contract\n /// @param minter Minter address to remove\n function removeMinter(address minter) external virtual onlyGovernor {\n // To remove the minter role to a `VaultManager` you have to go through the `removeVaultManager` function\n if (vaultManagerMap[minter] == 1) revert InvalidAddress();\n stablecoin.removeMinter(minter);\n }\n\n /// @notice Removes a `VaultManager`\n /// @param vaultManager `VaultManager` contract to remove\n /// @dev A removed `VaultManager` loses its minter right on the stablecoin\n function removeVaultManager(address vaultManager) external onlyGovernor {\n if (vaultManagerMap[vaultManager] != 1) revert NotVaultManager();\n delete vaultManagerMap[vaultManager];\n // deletion from `vaultManagerList` loop\n uint256 vaultManagerListLength = vaultManagerList.length;\n for (uint256 i; i < vaultManagerListLength - 1; ++i) {\n if (vaultManagerList[i] == vaultManager) {\n // replace the `VaultManager` to remove with the last of the list\n vaultManagerList[i] = vaultManagerList[vaultManagerListLength - 1];\n break;\n }\n }\n // remove last element in array\n vaultManagerList.pop();\n emit VaultManagerToggled(vaultManager);\n stablecoin.removeMinter(vaultManager);\n }\n\n /// @notice Allows to recover any ERC20 token, including the stablecoin handled by this contract, and to send it\n /// to a contract\n /// @param tokenAddress Address of the token to recover\n /// @param to Address of the contract to send collateral to\n /// @param amountToRecover Amount of collateral to transfer\n /// @dev It is impossible to recover the stablecoin of the protocol if there is some bad debt for it\n /// @dev In this case, the function makes sure to fetch the surplus/bad debt from all the `VaultManager` contracts\n /// and from the flash loan module\n /// @dev If the token to recover is the stablecoin, tokens recovered are fetched\n /// from the surplus and not from the `surplusBuffer`\n function recoverERC20(address tokenAddress, address to, uint256 amountToRecover) external onlyGovernor {\n // Cannot recover stablecoin if badDebt or tap into the surplus buffer\n if (tokenAddress == address(stablecoin)) {\n _fetchSurplusFromAll();\n // If balance is non zero then this means, after the call to `fetchSurplusFromAll` that\n // bad debt is necessarily null\n uint256 balance = stablecoin.balanceOf(address(this));\n if (amountToRecover + surplusBuffer > balance) revert TooBigAmount();\n stablecoin.transfer(to, amountToRecover);\n } else {\n IERC20(tokenAddress).safeTransfer(to, amountToRecover);\n }\n emit Recovered(tokenAddress, to, amountToRecover);\n }\n\n /// @notice Changes the treasury contract and communicates this change to all `VaultManager` contract\n /// @param _treasury New treasury address for this stablecoin\n /// @dev This function is basically a way to remove rights to this contract and grant them to a new one\n /// @dev It could be used to set a new core contract\n function setTreasury(address _treasury) external virtual onlyGovernor {\n if (ITreasury(_treasury).stablecoin() != stablecoin) revert InvalidTreasury();\n // Flash loan role should be removed before calling this function\n if (core.isFlashLoanerTreasury(address(this))) revert RightsNotRemoved();\n emit NewTreasurySet(_treasury);\n uint256 vaultManagerListLength = vaultManagerList.length;\n for (uint256 i; i < vaultManagerListLength; ++i) {\n IVaultManager(vaultManagerList[i]).setTreasury(_treasury);\n }\n // A `TreasuryUpdated` event is triggered in the stablecoin\n stablecoin.setTreasury(_treasury);\n }\n\n /// @notice Sets the `surplusForGovernance` parameter\n /// @param _surplusForGovernance New value of the parameter\n /// @dev To pause surplus distribution, governance needs to set a zero value for `surplusForGovernance`\n /// which means\n function setSurplusForGovernance(uint64 _surplusForGovernance) external onlyGovernor {\n if (_surplusForGovernance > BASE_9) revert TooHighParameterValue();\n surplusForGovernance = _surplusForGovernance;\n emit SurplusForGovernanceUpdated(_surplusForGovernance);\n }\n\n /// @notice Sets the `surplusManager` contract responsible for handling the surplus of the\n /// protocol\n /// @param _surplusManager New address responsible for handling the surplus\n function setSurplusManager(address _surplusManager) external onlyGovernor {\n if (_surplusManager == address(0)) revert ZeroAddress();\n surplusManager = _surplusManager;\n emit SurplusManagerUpdated(_surplusManager);\n }\n\n /// @notice Sets a new `core` contract\n /// @dev This function should typically be called on all treasury contracts after the `setCore`\n /// function has been called on the `CoreBorrow` contract\n /// @dev One sanity check that can be performed here is to verify whether at least the governor\n /// calling the contract is still a governor in the new core\n function setCore(ICoreBorrow _core) external onlyGovernor {\n if (!_core.isGovernor(msg.sender)) revert NotGovernor();\n core = ICoreBorrow(_core);\n emit CoreUpdated(address(_core));\n }\n\n /// @inheritdoc ITreasury\n function setFlashLoanModule(address _flashLoanModule) external {\n if (msg.sender != address(core)) revert NotCore();\n address oldFlashLoanModule = address(flashLoanModule);\n flashLoanModule = IFlashAngle(_flashLoanModule);\n if (oldFlashLoanModule != address(0)) {\n stablecoin.removeMinter(oldFlashLoanModule);\n }\n // We may want to cancel the module\n if (_flashLoanModule != address(0)) {\n stablecoin.addMinter(_flashLoanModule);\n }\n }\n}\n" + }, + "contracts/ui-helpers/AngleBorrowHelpers.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\n/*\n * █ \n ***** ▓▓▓ \n * ▓▓▓▓▓▓▓ \n * ///. ▓▓▓▓▓▓▓▓▓▓▓▓▓ \n ***** //////// ▓▓▓▓▓▓▓ \n * ///////////// ▓▓▓ \n ▓▓ ////////////////// █ ▓▓ \n ▓▓ ▓▓ /////////////////////// ▓▓ ▓▓ \n ▓▓ ▓▓ //////////////////////////// ▓▓ ▓▓ \n ▓▓ ▓▓ /////////▓▓▓///////▓▓▓///////// ▓▓ ▓▓ \n ▓▓ ,////////////////////////////////////// ▓▓ ▓▓ \n ▓▓ ////////////////////////////////////////// ▓▓ \n ▓▓ //////////////////////▓▓▓▓///////////////////// \n ,//////////////////////////////////////////////////// \n .////////////////////////////////////////////////////////// \n .//////////////////////////██.,//////////////////////////█ \n .//////////////////////████..,./////////////////////██ \n ...////////////////███████.....,.////////////////███ \n ,.,////////////████████ ........,///////////████ \n .,.,//////█████████ ,.......///////████ \n ,..//████████ ........./████ \n ..,██████ .....,███ \n .██ ,.,█ \n \n \n \n ▓▓ ▓▓▓▓▓▓▓▓▓▓ ▓▓▓▓▓▓▓▓▓▓ ▓▓ ▓▓▓▓▓▓▓▓▓▓ \n ▓▓▓▓▓▓ ▓▓▓ ▓▓▓ ▓▓▓ ▓▓ ▓▓ ▓▓▓▓ \n ▓▓▓ ▓▓▓ ▓▓▓ ▓▓▓ ▓▓▓ ▓▓▓ ▓▓ ▓▓▓▓▓ \n ▓▓▓ ▓▓ ▓▓▓ ▓▓▓ ▓▓▓▓▓▓▓▓▓▓ ▓▓▓▓▓▓▓▓▓▓ ▓▓▓▓▓▓▓▓▓▓ \n*/\n\nimport \"@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol\";\nimport \"../interfaces/IVaultManager.sol\";\n\npragma solidity ^0.8.12;\n\n/// @title AngleBorrowHelpers\n/// @author Angle Labs, Inc.\n/// @notice Contract with view functions designed to facilitate integrations on the Borrow module of the Angle Protocol\n/// @dev This contract only contains view functions to be queried off-chain. It was thus not optimized for gas consumption\ncontract AngleBorrowHelpers is Initializable {\n /// @notice Returns all the vaults owned or controlled (under the form of approval) by an address\n /// @param vaultManager VaultManager address to query vaultIDs on\n /// @param spender Address for which vault ownerships should be checked\n /// @return List of `vaultID` controlled by this address\n /// @return Count of vaults owned by the address\n /// @dev This function is never to be called on-chain since it iterates over all vaultIDs. It is here\n /// to reduce dependency on an external graph to link an ID to its owner\n function getControlledVaults(\n IVaultManager vaultManager,\n address spender\n ) external view returns (uint256[] memory, uint256) {\n uint256 arraySize = vaultManager.vaultIDCount();\n uint256[] memory vaultsControlled = new uint256[](arraySize);\n uint256 count;\n for (uint256 i = 1; i <= arraySize; ++i) {\n try vaultManager.isApprovedOrOwner(spender, i) returns (bool _isApprovedOrOwner) {\n if (_isApprovedOrOwner) {\n vaultsControlled[count] = i;\n count += 1;\n }\n } catch {\n continue;\n } // This happens if nobody owns the vaultID=i (if there has been a burn)\n }\n return (vaultsControlled, count);\n }\n\n /// @custom:oz-upgrades-unsafe-allow constructor\n constructor() initializer {}\n}\n" + }, + "contracts/ui-helpers/AngleHelpers.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\nimport \"../interfaces/IAngleRouter.sol\";\nimport \"../interfaces/coreModule/IAgTokenMainnet.sol\";\nimport \"../interfaces/coreModule/ICore.sol\";\nimport \"../interfaces/coreModule/IOracleCore.sol\";\nimport \"../interfaces/coreModule/IPerpetualManager.sol\";\nimport \"../interfaces/coreModule/IPoolManager.sol\";\nimport \"../interfaces/coreModule/IStableMaster.sol\";\nimport \"./AngleBorrowHelpers.sol\";\n\npragma solidity ^0.8.12;\n\nstruct Parameters {\n SLPData slpData;\n MintBurnData feeData;\n PerpetualManagerFeeData perpFeeData;\n PerpetualManagerParamData perpParam;\n}\n\nstruct PerpetualManagerFeeData {\n uint64[] xHAFeesDeposit;\n uint64[] yHAFeesDeposit;\n uint64[] xHAFeesWithdraw;\n uint64[] yHAFeesWithdraw;\n uint64 haBonusMalusDeposit;\n uint64 haBonusMalusWithdraw;\n}\n\nstruct PerpetualManagerParamData {\n uint64 maintenanceMargin;\n uint64 maxLeverage;\n uint64 targetHAHedge;\n uint64 limitHAHedge;\n uint64 lockTime;\n}\n\nstruct CollateralAddresses {\n address stableMaster;\n address poolManager;\n address perpetualManager;\n address sanToken;\n address oracle;\n address gauge;\n address feeManager;\n address[] strategies;\n}\n\n/// @title AngleHelpers\n/// @author Angle Labs, Inc.\n/// @notice Contract with view functions designed to facilitate integrations on the Core and Borrow module of the Angle Protocol\n/// @dev This contract only contains view functions to be queried off-chain. It was thus not optimized for gas consumption\ncontract AngleHelpers is AngleBorrowHelpers {\n // =========================== HELPER VIEW FUNCTIONS ===========================\n\n /// @notice Gives the amount of `agToken` you'd be getting if you were executing in the same block a mint transaction\n /// with `amount` of `collateral` in the Core module of the Angle protocol as well as the value of the fees\n /// (in `BASE_PARAMS`) that would be applied during the mint\n /// @return Amount of `agToken` that would be obtained with a mint transaction in the same block\n /// @return Percentage of fees that would be taken during a mint transaction in the same block\n /// @dev This function reverts if the mint transaction was to revert in the same conditions (without taking into account\n /// potential approval problems to the `StableMaster` contract)\n function previewMintAndFees(\n uint256 amount,\n address agToken,\n address collateral\n ) external view returns (uint256, uint256) {\n return _previewMintAndFees(amount, agToken, collateral);\n }\n\n /// @notice Gives the amount of `collateral` you'd be getting if you were executing in the same block a burn transaction\n /// with `amount` of `agToken` in the Core module of the Angle protocol as well as the value of the fees\n /// (in `BASE_PARAMS`) that would be applied during the burn\n /// @return Amount of `collateral` that would be obtained with a burn transaction in the same block\n /// @return Percentage of fees that would be taken during a burn transaction in the same block\n /// @dev This function reverts if the burn transaction was to revert in the same conditions (without taking into account\n /// potential approval problems to the `StableMaster` contract or agToken balance prior to the call)\n function previewBurnAndFees(\n uint256 amount,\n address agToken,\n address collateral\n ) external view returns (uint256, uint256) {\n return _previewBurnAndFees(amount, agToken, collateral);\n }\n\n /// @notice Returns all the addresses associated to the (`agToken`,`collateral`) pair given\n /// @return addresses A struct with all the addresses associated in the Core module\n function getCollateralAddresses(\n address agToken,\n address collateral\n ) external view returns (CollateralAddresses memory addresses) {\n address stableMaster = IAgTokenMainnet(agToken).stableMaster();\n (address poolManager, address perpetualManager, address sanToken, address gauge) = ROUTER.mapPoolManagers(\n stableMaster,\n collateral\n );\n (, , , IOracleCore oracle, , , , , ) = IStableMaster(stableMaster).collateralMap(poolManager);\n addresses.stableMaster = stableMaster;\n addresses.poolManager = poolManager;\n addresses.perpetualManager = perpetualManager;\n addresses.sanToken = sanToken;\n addresses.gauge = gauge;\n addresses.oracle = address(oracle);\n addresses.feeManager = IPoolManager(poolManager).feeManager();\n\n uint256 length;\n while (true) {\n try IPoolManager(poolManager).strategyList(length) returns (address) {\n length += 1;\n } catch {\n break;\n }\n }\n address[] memory strategies = new address[](length);\n for (uint256 i; i < length; ++i) {\n strategies[i] = IPoolManager(poolManager).strategyList(i);\n }\n addresses.strategies = strategies;\n }\n\n /// @notice Gets the addresses of all the `StableMaster` contracts and their associated `AgToken` addresses\n /// @return List of the `StableMaster` addresses of the Angle protocol\n /// @return List of the `AgToken` addresses of the protocol\n /// @dev The place of an agToken address in the list is the same as the corresponding `StableMaster` address\n function getStablecoinAddresses() external view returns (address[] memory, address[] memory) {\n address[] memory stableMasterAddresses = CORE.stablecoinList();\n address[] memory agTokenAddresses = new address[](stableMasterAddresses.length);\n for (uint256 i; i < stableMasterAddresses.length; ++i) {\n agTokenAddresses[i] = IStableMaster(stableMasterAddresses[i]).agToken();\n }\n return (stableMasterAddresses, agTokenAddresses);\n }\n\n /// @notice Returns most of the governance parameters associated to the (`agToken`,`collateral`) pair given\n /// @return params Struct with most of the parameters in the `StableMaster` and `PerpetualManager` contracts\n /// @dev Check out the struct `Parameters` for the meaning of the return values\n function getCollateralParameters(\n address agToken,\n address collateral\n ) external view returns (Parameters memory params) {\n (address stableMaster, address poolManager) = _getStableMasterAndPoolManager(agToken, collateral);\n (\n ,\n ,\n IPerpetualManager perpetualManager,\n ,\n ,\n ,\n ,\n SLPData memory slpData,\n MintBurnData memory feeData\n ) = IStableMaster(stableMaster).collateralMap(poolManager);\n\n params.slpData = slpData;\n params.feeData = feeData;\n params.perpParam.maintenanceMargin = perpetualManager.maintenanceMargin();\n params.perpParam.maxLeverage = perpetualManager.maxLeverage();\n params.perpParam.targetHAHedge = perpetualManager.targetHAHedge();\n params.perpParam.limitHAHedge = perpetualManager.limitHAHedge();\n params.perpParam.lockTime = perpetualManager.lockTime();\n\n params.perpFeeData.haBonusMalusDeposit = perpetualManager.haBonusMalusDeposit();\n params.perpFeeData.haBonusMalusWithdraw = perpetualManager.haBonusMalusWithdraw();\n\n uint256 length;\n while (true) {\n try perpetualManager.xHAFeesDeposit(length) returns (uint64) {\n length += 1;\n } catch {\n break;\n }\n }\n uint64[] memory data = new uint64[](length);\n uint64[] memory data2 = new uint64[](length);\n for (uint256 i; i < length; ++i) {\n data[i] = perpetualManager.xHAFeesDeposit(i);\n data2[i] = perpetualManager.yHAFeesDeposit(i);\n }\n params.perpFeeData.xHAFeesDeposit = data;\n params.perpFeeData.yHAFeesDeposit = data2;\n\n length = 0;\n while (true) {\n try perpetualManager.xHAFeesWithdraw(length) returns (uint64) {\n length += 1;\n } catch {\n break;\n }\n }\n data = new uint64[](length);\n data2 = new uint64[](length);\n for (uint256 i; i < length; ++i) {\n data[i] = perpetualManager.xHAFeesWithdraw(i);\n data2[i] = perpetualManager.yHAFeesWithdraw(i);\n }\n params.perpFeeData.xHAFeesWithdraw = data;\n params.perpFeeData.yHAFeesWithdraw = data2;\n }\n\n /// @notice Returns the address of the poolManager associated to an (`agToken`, `collateral`) pair\n /// in the Core module of the protocol\n function getPoolManager(address agToken, address collateral) public view returns (address poolManager) {\n (, poolManager) = _getStableMasterAndPoolManager(agToken, collateral);\n }\n\n // ============================= REPLICA FUNCTIONS =============================\n // These replicate what is done in the other contracts of the protocol\n\n function _previewBurnAndFees(\n uint256 amount,\n address agToken,\n address collateral\n ) internal view returns (uint256 amountForUserInCollat, uint256 feePercent) {\n (address stableMaster, address poolManager) = _getStableMasterAndPoolManager(agToken, collateral);\n (\n address token,\n ,\n IPerpetualManager perpetualManager,\n IOracleCore oracle,\n uint256 stocksUsers,\n ,\n uint256 collatBase,\n ,\n MintBurnData memory feeData\n ) = IStableMaster(stableMaster).collateralMap(poolManager);\n if (token == address(0) || IStableMaster(stableMaster).paused(keccak256(abi.encodePacked(STABLE, poolManager))))\n revert NotInitialized();\n if (amount > stocksUsers) revert InvalidAmount();\n\n if (feeData.xFeeBurn.length == 1) {\n feePercent = feeData.yFeeBurn[0];\n } else {\n bytes memory data = abi.encode(address(perpetualManager), feeData.targetHAHedge);\n uint64 hedgeRatio = _computeHedgeRatio(stocksUsers - amount, data);\n feePercent = _piecewiseLinear(hedgeRatio, feeData.xFeeBurn, feeData.yFeeBurn);\n }\n feePercent = (feePercent * feeData.bonusMalusBurn) / BASE_PARAMS;\n\n amountForUserInCollat = (amount * (BASE_PARAMS - feePercent) * collatBase) / (oracle.readUpper() * BASE_PARAMS);\n }\n\n function _previewMintAndFees(\n uint256 amount,\n address agToken,\n address collateral\n ) internal view returns (uint256 amountForUserInStable, uint256 feePercent) {\n (address stableMaster, address poolManager) = _getStableMasterAndPoolManager(agToken, collateral);\n (\n address token,\n ,\n IPerpetualManager perpetualManager,\n IOracleCore oracle,\n uint256 stocksUsers,\n ,\n ,\n ,\n MintBurnData memory feeData\n ) = IStableMaster(stableMaster).collateralMap(poolManager);\n if (token == address(0) || IStableMaster(stableMaster).paused(keccak256(abi.encodePacked(STABLE, poolManager))))\n revert NotInitialized();\n\n amountForUserInStable = oracle.readQuoteLower(amount);\n\n if (feeData.xFeeMint.length == 1) feePercent = feeData.yFeeMint[0];\n else {\n bytes memory data = abi.encode(address(perpetualManager), feeData.targetHAHedge);\n uint64 hedgeRatio = _computeHedgeRatio(amountForUserInStable + stocksUsers, data);\n feePercent = _piecewiseLinear(hedgeRatio, feeData.xFeeMint, feeData.yFeeMint);\n }\n feePercent = (feePercent * feeData.bonusMalusMint) / BASE_PARAMS;\n\n amountForUserInStable = (amountForUserInStable * (BASE_PARAMS - feePercent)) / BASE_PARAMS;\n if (stocksUsers + amountForUserInStable > feeData.capOnStableMinted) revert InvalidAmount();\n }\n\n // ============================= UTILITY FUNCTIONS =============================\n // These utility functions are taken from other contracts of the protocol\n\n function _computeHedgeRatio(uint256 newStocksUsers, bytes memory data) internal view returns (uint64 ratio) {\n (address perpetualManager, uint64 targetHAHedge) = abi.decode(data, (address, uint64));\n uint256 totalHedgeAmount = IPerpetualManager(perpetualManager).totalHedgeAmount();\n newStocksUsers = (targetHAHedge * newStocksUsers) / BASE_PARAMS;\n if (newStocksUsers > totalHedgeAmount) ratio = uint64((totalHedgeAmount * BASE_PARAMS) / newStocksUsers);\n else ratio = uint64(BASE_PARAMS);\n }\n\n function _piecewiseLinear(uint64 x, uint64[] memory xArray, uint64[] memory yArray) internal pure returns (uint64) {\n if (x >= xArray[xArray.length - 1]) {\n return yArray[xArray.length - 1];\n } else if (x <= xArray[0]) {\n return yArray[0];\n } else {\n uint256 lower;\n uint256 upper = xArray.length - 1;\n uint256 mid;\n while (upper - lower > 1) {\n mid = lower + (upper - lower) / 2;\n if (xArray[mid] <= x) {\n lower = mid;\n } else {\n upper = mid;\n }\n }\n if (yArray[upper] > yArray[lower]) {\n return\n yArray[lower] +\n ((yArray[upper] - yArray[lower]) * (x - xArray[lower])) /\n (xArray[upper] - xArray[lower]);\n } else {\n return\n yArray[lower] -\n ((yArray[lower] - yArray[upper]) * (x - xArray[lower])) /\n (xArray[upper] - xArray[lower]);\n }\n }\n }\n\n function _getStableMasterAndPoolManager(\n address agToken,\n address collateral\n ) internal view returns (address stableMaster, address poolManager) {\n stableMaster = IAgTokenMainnet(agToken).stableMaster();\n (poolManager, , , ) = ROUTER.mapPoolManagers(stableMaster, collateral);\n }\n\n // ========================= CONSTANTS AND INITIALIZERS ========================\n\n IAngleRouter public constant ROUTER = IAngleRouter(0xBB755240596530be0c1DE5DFD77ec6398471561d);\n ICore public constant CORE = ICore(0x61ed74de9Ca5796cF2F8fD60D54160D47E30B7c3);\n\n bytes32 public constant STABLE = keccak256(\"STABLE\");\n uint256 public constant BASE_PARAMS = 10 ** 9;\n\n error NotInitialized();\n error InvalidAmount();\n}\n" + }, + "contracts/utils/Constants.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\nerror InsufficientAssets();\n\n/// @title Constants\n/// @author Angle Labs, Inc.\n/// @notice Constants and errors for Angle Protocol contracts\ncontract Constants {\n uint256 internal constant _BASE_9 = 1e9;\n uint256 internal constant _BASE_18 = 1e18;\n uint256 internal constant _BASE_27 = 1e27;\n uint256 internal constant _BASE_36 = 1e36;\n}\n" + }, + "contracts/vaultManager/VaultManagerERC721.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\nimport \"./VaultManagerStorage.sol\";\n\n/// @title VaultManagerERC721\n/// @author Angle Labs, Inc.\n/// @dev Base ERC721 Implementation of VaultManager\nabstract contract VaultManagerERC721 is IERC721MetadataUpgradeable, VaultManagerStorage {\n using SafeERC20 for IERC20;\n using Address for address;\n\n /// @inheritdoc IERC721MetadataUpgradeable\n string public name;\n /// @inheritdoc IERC721MetadataUpgradeable\n string public symbol;\n\n // ================================= MODIFIERS =================================\n\n /// @notice Checks if the person interacting with the vault with `vaultID` is approved\n /// @param caller Address of the person seeking to interact with the vault\n /// @param vaultID ID of the concerned vault\n modifier onlyApprovedOrOwner(address caller, uint256 vaultID) {\n if (!_isApprovedOrOwner(caller, vaultID)) revert NotApproved();\n _;\n }\n\n // ================================ ERC721 LOGIC ===============================\n\n /// @notice Checks whether a given address is approved for a vault or owns this vault\n /// @param spender Address for which vault ownership should be checked\n /// @param vaultID ID of the vault to check\n /// @return Whether the `spender` address owns or is approved for `vaultID`\n function isApprovedOrOwner(address spender, uint256 vaultID) external view returns (bool) {\n return _isApprovedOrOwner(spender, vaultID);\n }\n\n /// @inheritdoc IERC721MetadataUpgradeable\n function tokenURI(uint256 vaultID) external view returns (string memory) {\n if (!_exists(vaultID)) revert NonexistentVault();\n // There is no vault with `vaultID` equal to 0, so the following variable is\n // always greater than zero\n uint256 temp = vaultID;\n uint256 digits;\n while (temp != 0) {\n ++digits;\n temp /= 10;\n }\n bytes memory buffer = new bytes(digits);\n while (vaultID != 0) {\n digits -= 1;\n buffer[digits] = bytes1(uint8(48 + uint256(vaultID % 10)));\n vaultID /= 10;\n }\n return bytes(_baseURI).length != 0 ? string(abi.encodePacked(_baseURI, string(buffer))) : \"\";\n }\n\n /// @inheritdoc IERC721Upgradeable\n function balanceOf(address owner) external view returns (uint256) {\n if (owner == address(0)) revert ZeroAddress();\n return _balances[owner];\n }\n\n /// @inheritdoc IERC721Upgradeable\n function ownerOf(uint256 vaultID) external view returns (address) {\n return _ownerOf(vaultID);\n }\n\n /// @inheritdoc IERC721Upgradeable\n function approve(address to, uint256 vaultID) external {\n address owner = _ownerOf(vaultID);\n if (to == owner) revert ApprovalToOwner();\n if (msg.sender != owner && !isApprovedForAll(owner, msg.sender)) revert NotApproved();\n\n _approve(to, vaultID);\n }\n\n /// @inheritdoc IERC721Upgradeable\n function getApproved(uint256 vaultID) external view returns (address) {\n if (!_exists(vaultID)) revert NonexistentVault();\n return _getApproved(vaultID);\n }\n\n /// @inheritdoc IERC721Upgradeable\n function setApprovalForAll(address operator, bool approved) external {\n _setApprovalForAll(msg.sender, operator, approved);\n }\n\n /// @inheritdoc IERC721Upgradeable\n function isApprovedForAll(address owner, address operator) public view returns (bool) {\n return _operatorApprovals[owner][operator] == 1;\n }\n\n /// @inheritdoc IERC721Upgradeable\n function transferFrom(address from, address to, uint256 vaultID) external onlyApprovedOrOwner(msg.sender, vaultID) {\n _transfer(from, to, vaultID);\n }\n\n /// @inheritdoc IERC721Upgradeable\n function safeTransferFrom(address from, address to, uint256 vaultID) external {\n safeTransferFrom(from, to, vaultID, \"\");\n }\n\n /// @inheritdoc IERC721Upgradeable\n function safeTransferFrom(\n address from,\n address to,\n uint256 vaultID,\n bytes memory _data\n ) public onlyApprovedOrOwner(msg.sender, vaultID) {\n _safeTransfer(from, to, vaultID, _data);\n }\n\n // ================================ ERC165 LOGIC ===============================\n\n /// @inheritdoc IERC165Upgradeable\n function supportsInterface(bytes4 interfaceId) external pure returns (bool) {\n return\n interfaceId == type(IERC721MetadataUpgradeable).interfaceId ||\n interfaceId == type(IERC721Upgradeable).interfaceId ||\n interfaceId == type(IVaultManager).interfaceId ||\n interfaceId == type(IERC165Upgradeable).interfaceId;\n }\n\n // ================== INTERNAL FUNCTIONS FOR THE ERC721 LOGIC ==================\n\n /// @notice Internal version of the `ownerOf` function\n function _ownerOf(uint256 vaultID) internal view returns (address owner) {\n owner = _owners[vaultID];\n if (owner == address(0)) revert NonexistentVault();\n }\n\n /// @notice Internal version of the `getApproved` function\n function _getApproved(uint256 vaultID) internal view returns (address) {\n return _vaultApprovals[vaultID];\n }\n\n /// @notice Internal version of the `safeTransferFrom` function (with the data parameter)\n function _safeTransfer(address from, address to, uint256 vaultID, bytes memory _data) internal {\n _transfer(from, to, vaultID);\n if (!_checkOnERC721Received(from, to, vaultID, _data)) revert NonERC721Receiver();\n }\n\n /// @notice Checks whether a vault exists\n /// @param vaultID ID of the vault to check\n /// @return Whether `vaultID` has been created\n function _exists(uint256 vaultID) internal view returns (bool) {\n return _owners[vaultID] != address(0);\n }\n\n /// @notice Internal version of the `isApprovedOrOwner` function\n function _isApprovedOrOwner(address spender, uint256 vaultID) internal view returns (bool) {\n // The following checks if the vault exists\n address owner = _ownerOf(vaultID);\n return (spender == owner || _getApproved(vaultID) == spender || _operatorApprovals[owner][spender] == 1);\n }\n\n /// @notice Internal version of the `createVault` function\n /// Mints `vaultID` and transfers it to `to`\n /// @dev This method is equivalent to the `_safeMint` method used in OpenZeppelin ERC721 contract\n /// @dev Emits a {Transfer} event\n function _mint(address to) internal returns (uint256 vaultID) {\n if (to == address(0)) revert ZeroAddress();\n\n unchecked {\n vaultIDCount += 1;\n }\n\n vaultID = vaultIDCount;\n _beforeTokenTransfer(address(0), to, vaultID);\n\n unchecked {\n _balances[to] += 1;\n }\n\n _owners[vaultID] = to;\n emit Transfer(address(0), to, vaultID);\n if (!_checkOnERC721Received(address(0), to, vaultID, \"\")) revert NonERC721Receiver();\n }\n\n /// @notice Destroys `vaultID`\n /// @dev `vaultID` must exist\n /// @dev Emits a {Transfer} event\n function _burn(uint256 vaultID) internal {\n address owner = _ownerOf(vaultID);\n\n _beforeTokenTransfer(owner, address(0), vaultID);\n // Clear approvals\n _approve(address(0), vaultID);\n // The following line cannot underflow as the owner's balance is necessarily\n // greater than 1\n unchecked {\n _balances[owner] -= 1;\n }\n delete _owners[vaultID];\n delete vaultData[vaultID];\n\n emit Transfer(owner, address(0), vaultID);\n }\n\n /// @notice Transfers `vaultID` from `from` to `to` as opposed to {transferFrom},\n /// this imposes no restrictions on msg.sender\n /// @dev `to` cannot be the zero address and `perpetualID` must be owned by `from`\n /// @dev Emits a {Transfer} event\n function _transfer(address from, address to, uint256 vaultID) internal {\n if (_ownerOf(vaultID) != from) revert NotApproved();\n if (to == address(0)) revert ZeroAddress();\n\n _beforeTokenTransfer(from, to, vaultID);\n\n // Clear approvals from the previous owner\n _approve(address(0), vaultID);\n unchecked {\n _balances[from] -= 1;\n _balances[to] += 1;\n }\n _owners[vaultID] = to;\n\n emit Transfer(from, to, vaultID);\n }\n\n /// @notice Approves `to` to operate on `vaultID`\n function _approve(address to, uint256 vaultID) internal {\n _vaultApprovals[vaultID] = to;\n emit Approval(_ownerOf(vaultID), to, vaultID);\n }\n\n /// @notice Internal version of the `setApprovalForAll` function\n /// @dev It contains an `approver` field to be used in case someone signs a permit for a particular\n /// address, and this signature is given to the contract by another address (like a router)\n function _setApprovalForAll(address approver, address operator, bool approved) internal {\n if (operator == approver) revert ApprovalToCaller();\n uint256 approval = approved ? 1 : 0;\n _operatorApprovals[approver][operator] = approval;\n emit ApprovalForAll(approver, operator, approved);\n }\n\n /// @notice Internal function to invoke {IERC721Receiver-onERC721Received} on a target address\n /// The call is not executed if the target address is not a contract\n /// @param from Address representing the previous owner of the given token ID\n /// @param to Target address that will receive the tokens\n /// @param vaultID ID of the token to be transferred\n /// @param _data Bytes optional data to send along with the call\n /// @return Bool whether the call correctly returned the expected value\n function _checkOnERC721Received(\n address from,\n address to,\n uint256 vaultID,\n bytes memory _data\n ) private returns (bool) {\n if (to.isContract()) {\n try IERC721ReceiverUpgradeable(to).onERC721Received(msg.sender, from, vaultID, _data) returns (\n bytes4 retval\n ) {\n return retval == IERC721ReceiverUpgradeable.onERC721Received.selector;\n } catch (bytes memory reason) {\n if (reason.length == 0) {\n revert NonERC721Receiver();\n } else {\n // solhint-disable-next-line no-inline-assembly\n assembly {\n revert(add(32, reason), mload(reason))\n }\n }\n }\n } else {\n return true;\n }\n }\n\n /// @notice Hook that is called before any token transfer. This includes minting and burning.\n /// Calling conditions:\n ///\n /// - When `from` and `to` are both non-zero, `from`'s `vaultID` will be\n /// transferred to `to`.\n /// - When `from` is zero, `vaultID` will be minted for `to`.\n /// - When `to` is zero, `from`'s `vaultID` will be burned.\n /// - `from` and `to` are never both zero.\n function _beforeTokenTransfer(address from, address to, uint256 vaultID) internal virtual {}\n\n /// @notice Get `whitelistingActivated` in storage only if needed\n function _whitelistingActivated() internal view virtual returns (bool) {\n return whitelistingActivated;\n }\n}\n" + }, + "contracts/vaultManager/VaultManagerPermit.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\nimport \"./VaultManagerERC721.sol\";\nimport \"../interfaces/external/IERC1271.sol\";\n\n/// @title VaultManagerPermit\n/// @author Angle Labs, Inc.\n/// @dev Base Implementation of permit functions for the `VaultManager` contract\nabstract contract VaultManagerPermit is Initializable, VaultManagerERC721 {\n using Address for address;\n\n mapping(address => uint256) private _nonces;\n /* solhint-disable var-name-mixedcase */\n bytes32 private _HASHED_NAME;\n bytes32 private _HASHED_VERSION;\n bytes32 private _PERMIT_TYPEHASH;\n /* solhint-enable var-name-mixedcase */\n\n error ExpiredDeadline();\n error InvalidSignature();\n\n //solhint-disable-next-line\n function __ERC721Permit_init(string memory _name) internal onlyInitializing {\n _PERMIT_TYPEHASH = keccak256(\n \"Permit(address owner,address spender,bool approved,uint256 nonce,uint256 deadline)\"\n );\n _HASHED_NAME = keccak256(bytes(_name));\n _HASHED_VERSION = keccak256(bytes(\"1\"));\n }\n\n /// @notice Allows an address to give or revoke approval for all its vaults to another address\n /// @param owner Address signing the permit and giving (or revoking) its approval for all the controlled vaults\n /// @param spender Address to give approval to\n /// @param approved Whether to give or revoke the approval\n /// @param deadline Deadline parameter for the signature to be valid\n /// @dev The `v`, `r`, and `s` parameters are used as signature data\n function permit(\n address owner,\n address spender,\n bool approved,\n uint256 deadline,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) external {\n if (block.timestamp > deadline) revert ExpiredDeadline();\n // Additional signature checks performed in the `ECDSAUpgradeable.recover` function\n if (uint256(s) > 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D576E7357A4501DDFE92F46681B20A0 || (v != 27 && v != 28))\n revert InvalidSignature();\n\n bytes32 digest = keccak256(\n abi.encodePacked(\n \"\\x19\\x01\",\n _domainSeparatorV4(),\n keccak256(\n abi.encode(\n _PERMIT_TYPEHASH,\n // 0x3f43a9c6bafb5c7aab4e0cfe239dc5d4c15caf0381c6104188191f78a6640bd8,\n owner,\n spender,\n approved,\n _useNonce(owner),\n deadline\n )\n )\n )\n );\n if (owner.isContract()) {\n if (IERC1271(owner).isValidSignature(digest, abi.encodePacked(r, s, v)) != 0x1626ba7e)\n revert InvalidSignature();\n } else {\n address signer = ecrecover(digest, v, r, s);\n if (signer != owner || signer == address(0)) revert InvalidSignature();\n }\n\n _setApprovalForAll(owner, spender, approved);\n }\n\n /// @notice Returns the current nonce for an `owner` address\n function nonces(address owner) public view returns (uint256) {\n return _nonces[owner];\n }\n\n /// @notice Returns the domain separator for the current chain.\n // solhint-disable-next-line func-name-mixedcase\n function DOMAIN_SEPARATOR() external view returns (bytes32) {\n return _domainSeparatorV4();\n }\n\n /// @notice Internal version of the `DOMAIN_SEPARATOR` function\n function _domainSeparatorV4() internal view returns (bytes32) {\n return\n keccak256(\n abi.encode(\n // keccak256('EIP712Domain(string name,string version,uint256 chainId,address verifyingContract)')\n 0x8b73c3c69bb8fe3d512ecc4cf759cc79239f7b179b0ffacaa9a75d522b39400f,\n _HASHED_NAME,\n _HASHED_VERSION,\n block.chainid,\n address(this)\n )\n );\n }\n\n /// @notice Consumes a nonce for an address: returns the current value and increments it\n function _useNonce(address owner) internal returns (uint256 current) {\n current = _nonces[owner];\n _nonces[owner] = current + 1;\n }\n\n uint256[49] private __gap;\n}\n" + }, + "contracts/vaultManager/VaultManagerStorage.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\nimport \"@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/token/ERC20/extensions/draft-IERC20PermitUpgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/token/ERC721/IERC721ReceiverUpgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/interfaces/IERC721MetadataUpgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/utils/introspection/IERC165Upgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/utils/AddressUpgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/security/ReentrancyGuardUpgradeable.sol\";\nimport \"@openzeppelin/contracts/token/ERC20/extensions/IERC20Metadata.sol\";\nimport \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\nimport \"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\";\n\nimport \"../interfaces/IAgToken.sol\";\nimport \"../interfaces/IOracle.sol\";\nimport \"../interfaces/ISwapper.sol\";\nimport \"../interfaces/ITreasury.sol\";\nimport \"../interfaces/IVaultManager.sol\";\nimport \"../interfaces/governance/IVeBoostProxy.sol\";\n\n/// @title VaultManagerStorage\n/// @author Angle Labs, Inc.\n/// @dev Variables, references, parameters and events needed in the `VaultManager` contract\n// solhint-disable-next-line max-states-count\ncontract VaultManagerStorage is IVaultManagerStorage, Initializable, ReentrancyGuardUpgradeable {\n /// @notice Base used for parameter computation: almost all the parameters of this contract are set in `BASE_PARAMS`\n uint256 public constant BASE_PARAMS = 10 ** 9;\n /// @notice Base used for interest rate computation\n uint256 public constant BASE_INTEREST = 10 ** 27;\n /// @notice Used for interest rate computation\n uint256 public constant HALF_BASE_INTEREST = 10 ** 27 / 2;\n\n // ================================= REFERENCES ================================\n\n /// @inheritdoc IVaultManagerStorage\n ITreasury public treasury;\n /// @inheritdoc IVaultManagerStorage\n IERC20 public collateral;\n /// @inheritdoc IVaultManagerStorage\n IAgToken public stablecoin;\n /// @inheritdoc IVaultManagerStorage\n IOracle public oracle;\n /// @notice Reference to the contract which computes adjusted veANGLE balances for liquidators boosts\n IVeBoostProxy public veBoostProxy;\n /// @notice Base of the collateral\n uint256 internal _collatBase;\n\n // ================================= PARAMETERS ================================\n // Unless specified otherwise, parameters of this contract are expressed in `BASE_PARAMS`\n\n /// @notice Maximum amount of stablecoins that can be issued with this contract (in `BASE_TOKENS`). This parameter should\n /// not be bigger than `type(uint256).max / BASE_INTEREST` otherwise there may be some overflows in the `increaseDebt` function\n uint256 public debtCeiling;\n /// @notice Threshold veANGLE balance values for the computation of the boost for liquidators: the length of this array\n /// should normally be 2. The base of the x-values in this array should be `BASE_TOKENS`\n uint256[] public xLiquidationBoost;\n /// @notice Values of the liquidation boost at the threshold values of x\n uint256[] public yLiquidationBoost;\n /// @inheritdoc IVaultManagerStorage\n uint64 public collateralFactor;\n /// @notice Maximum Health factor at which a vault can end up after a liquidation (unless it's fully liquidated)\n uint64 public targetHealthFactor;\n /// @notice Upfront fee taken when borrowing stablecoins: this fee is optional and should in practice not be used\n uint64 public borrowFee;\n /// @notice Upfront fee taken when repaying stablecoins: this fee is optional as well. It should be smaller\n /// than the liquidation surcharge (cf below) to avoid exploits where people voluntarily get liquidated at a 0\n /// discount to pay smaller repaying fees\n uint64 public repayFee;\n /// @notice Per second interest taken to borrowers taking agToken loans. Contrarily to other parameters, it is set in `BASE_INTEREST`\n /// that is to say in base 10**27\n uint64 public interestRate;\n /// @notice Fee taken by the protocol during a liquidation. Technically, this value is not the fee per se, it's 1 - fee.\n /// For instance for a 2% fee, `liquidationSurcharge` should be 98%\n uint64 public liquidationSurcharge;\n /// @notice Maximum discount given to liquidators\n uint64 public maxLiquidationDiscount;\n /// @notice Whether whitelisting is required to own a vault or not\n bool public whitelistingActivated;\n /// @notice Whether the contract is paused or not\n bool public paused;\n\n // ================================= VARIABLES =================================\n\n /// @notice Timestamp at which the `interestAccumulator` was updated\n uint256 public lastInterestAccumulatorUpdated;\n /// @inheritdoc IVaultManagerStorage\n uint256 public interestAccumulator;\n /// @inheritdoc IVaultManagerStorage\n uint256 public totalNormalizedDebt;\n /// @notice Surplus accumulated by the contract: surplus is always in stablecoins, and is then reset\n /// when the value is communicated to the treasury contract\n uint256 public surplus;\n /// @notice Bad debt made from liquidated vaults which ended up having no collateral and a positive amount\n /// of stablecoins\n uint256 public badDebt;\n\n // ================================== MAPPINGS =================================\n\n /// @inheritdoc IVaultManagerStorage\n mapping(uint256 => Vault) public vaultData;\n /// @notice Maps an address to 1 if it's whitelisted and can open or own a vault\n mapping(address => uint256) public isWhitelisted;\n\n // ================================ ERC721 DATA ================================\n\n /// @inheritdoc IVaultManagerStorage\n uint256 public vaultIDCount;\n\n /// @notice URI\n string internal _baseURI;\n\n // Mapping from `vaultID` to owner address\n mapping(uint256 => address) internal _owners;\n\n // Mapping from owner address to vault owned count\n mapping(address => uint256) internal _balances;\n\n // Mapping from `vaultID` to approved address\n mapping(uint256 => address) internal _vaultApprovals;\n\n // Mapping from owner to operator approvals\n mapping(address => mapping(address => uint256)) internal _operatorApprovals;\n\n uint256[50] private __gap;\n\n // =================================== EVENTS ==================================\n\n event AccruedToTreasury(uint256 surplusEndValue, uint256 badDebtEndValue);\n event CollateralAmountUpdated(uint256 vaultID, uint256 collateralAmount, uint8 isIncrease);\n event InterestAccumulatorUpdated(uint256 value, uint256 timestamp);\n event InternalDebtUpdated(uint256 vaultID, uint256 internalAmount, uint8 isIncrease);\n event FiledUint64(uint64 param, bytes32 what);\n event DebtCeilingUpdated(uint256 debtCeiling);\n event LiquidationBoostParametersUpdated(address indexed _veBoostProxy, uint256[] xBoost, uint256[] yBoost);\n event LiquidatedVaults(uint256[] vaultIDs);\n event DebtTransferred(uint256 srcVaultID, uint256 dstVaultID, address dstVaultManager, uint256 amount);\n\n // =================================== ERRORS ==================================\n\n error ApprovalToOwner();\n error ApprovalToCaller();\n error DustyLeftoverAmount();\n error DebtCeilingExceeded();\n error HealthyVault();\n error IncompatibleLengths();\n error InsolventVault();\n error InvalidParameterValue();\n error InvalidParameterType();\n error InvalidSetOfParameters();\n error InvalidTreasury();\n error NonERC721Receiver();\n error NonexistentVault();\n error NotApproved();\n error NotGovernor();\n error NotGovernorOrGuardian();\n error NotTreasury();\n error NotWhitelisted();\n error NotVaultManager();\n error Paused();\n error TooHighParameterValue();\n error TooSmallParameterValue();\n error ZeroAddress();\n\n /// @custom:oz-upgrades-unsafe-allow constructor\n constructor() initializer {}\n}\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 1000000 + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers", + "metadata", + "devdoc", + "userdoc", + "storageLayout", + "evm.gasEstimates", + "devdoc", + "userdoc" + ], + "": [ + "ast" + ] + } + }, + "metadata": { + "useLiteralContent": true + } + } +} \ No newline at end of file diff --git a/deployments/bsc/AgTokenSideChainMultiBridge_Implementation.json b/deployments/bsc/AgTokenSideChainMultiBridge_Implementation.json index 1b6e24e3..fb3409ed 100644 --- a/deployments/bsc/AgTokenSideChainMultiBridge_Implementation.json +++ b/deployments/bsc/AgTokenSideChainMultiBridge_Implementation.json @@ -1,5 +1,5 @@ { - "address": "0x3E399AE5B4D8bc0021e53b51c8BCdD66DD62c03b", + "address": "0x92d84b0687361cd0753E95f5A8746fbaf42E9135", "abi": [ { "inputs": [], @@ -249,6 +249,19 @@ "name": "HourlyLimitUpdated", "type": "event" }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint8", + "name": "version", + "type": "uint8" + } + ], + "name": "Initialized", + "type": "event" + }, { "anonymous": false, "inputs": [ @@ -1111,7 +1124,7 @@ "inputs": [ { "internalType": "address", - "name": "recipient", + "name": "to", "type": "address" }, { @@ -1135,12 +1148,12 @@ "inputs": [ { "internalType": "address", - "name": "sender", + "name": "from", "type": "address" }, { "internalType": "address", - "name": "recipient", + "name": "to", "type": "address" }, { @@ -1198,31 +1211,44 @@ "type": "function" } ], - "transactionHash": "0x0910a76b65ae0e5c9e3af80d206832dc3ba8597b4bf8e082fba2bd3575904121", + "transactionHash": "0x6104afdbf04a67b65e380351dbaf4641d5a944dc342018cc9c9bb986a4ee60b5", "receipt": { "to": null, "from": "0xfdA462548Ce04282f4B6D6619823a7C64Fdc0185", - "contractAddress": "0x3E399AE5B4D8bc0021e53b51c8BCdD66DD62c03b", - "transactionIndex": 89, - "gasUsed": "4007120", - "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", - "blockHash": "0xa651365c456a42b3b0f128fb19b35d498cc77c1912945607fdefeb62401cece6", - "transactionHash": "0x0910a76b65ae0e5c9e3af80d206832dc3ba8597b4bf8e082fba2bd3575904121", - "logs": [], - "blockNumber": 22050481, - "cumulativeGasUsed": "10148491", + "contractAddress": "0x92d84b0687361cd0753E95f5A8746fbaf42E9135", + "transactionIndex": 124, + "gasUsed": "3964995", + "logsBloom": "0x00000000000000000000000000000080000000000000080000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000080000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "blockHash": "0x0e0f2c9937d4ea9b86072d91280540eaf253cb7a6735bc3ce7c0215a2640ad4d", + "transactionHash": "0x6104afdbf04a67b65e380351dbaf4641d5a944dc342018cc9c9bb986a4ee60b5", + "logs": [ + { + "transactionIndex": 124, + "blockNumber": 35121545, + "transactionHash": "0x6104afdbf04a67b65e380351dbaf4641d5a944dc342018cc9c9bb986a4ee60b5", + "address": "0x92d84b0687361cd0753E95f5A8746fbaf42E9135", + "topics": [ + "0x7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb3847402498" + ], + "data": "0x0000000000000000000000000000000000000000000000000000000000000001", + "logIndex": 199, + "blockHash": "0x0e0f2c9937d4ea9b86072d91280540eaf253cb7a6735bc3ce7c0215a2640ad4d" + } + ], + "blockNumber": 35121545, + "cumulativeGasUsed": "13591166", "status": 1, "byzantium": true }, "args": [], - "numDeployments": 1, - "solcInputHash": "c738595b9b57358bae83408c8b980d54", - "metadata": "{\"compiler\":{\"version\":\"0.8.12+commit.f00d7308\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[],\"name\":\"AssetStillControlledInReserves\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"BurnAmountExceedsAllowance\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"HourlyLimitExceeded\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidSender\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidToken\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidTreasury\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"NotGovernor\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"NotGovernorOrGuardian\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"NotMinter\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"NotTreasury\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"TooBigAmount\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"TooHighParameterValue\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ZeroAddress\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"spender\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"}],\"name\":\"Approval\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"bridgeToken\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"limit\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"hourlyLimit\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"fee\",\"type\":\"uint64\"},{\"indexed\":false,\"internalType\":\"bool\",\"name\":\"paused\",\"type\":\"bool\"}],\"name\":\"BridgeTokenAdded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"bridgeToken\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"fee\",\"type\":\"uint64\"}],\"name\":\"BridgeTokenFeeUpdated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"bridgeToken\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"hourlyLimit\",\"type\":\"uint256\"}],\"name\":\"BridgeTokenHourlyLimitUpdated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"bridgeToken\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"limit\",\"type\":\"uint256\"}],\"name\":\"BridgeTokenLimitUpdated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"bridgeToken\",\"type\":\"address\"}],\"name\":\"BridgeTokenRemoved\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"bridgeToken\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"bool\",\"name\":\"toggleStatus\",\"type\":\"bool\"}],\"name\":\"BridgeTokenToggled\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"theAddress\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"toggleStatus\",\"type\":\"uint256\"}],\"name\":\"FeeToggled\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"hourlyLimit\",\"type\":\"uint256\"}],\"name\":\"HourlyLimitUpdated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"minter\",\"type\":\"address\"}],\"name\":\"MinterToggled\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"Recovered\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"}],\"name\":\"Transfer\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"_treasury\",\"type\":\"address\"}],\"name\":\"TreasuryUpdated\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"BASE_PARAMS\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"DOMAIN_SEPARATOR\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"bridgeToken\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"limit\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"hourlyLimit\",\"type\":\"uint256\"},{\"internalType\":\"uint64\",\"name\":\"fee\",\"type\":\"uint64\"},{\"internalType\":\"bool\",\"name\":\"paused\",\"type\":\"bool\"}],\"name\":\"addBridgeToken\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"minter\",\"type\":\"address\"}],\"name\":\"addMinter\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"allBridgeTokens\",\"outputs\":[{\"internalType\":\"address[]\",\"name\":\"\",\"type\":\"address[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"spender\",\"type\":\"address\"}],\"name\":\"allowance\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"spender\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"approve\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"}],\"name\":\"balanceOf\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"name\":\"bridgeTokensList\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"bridges\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"limit\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"hourlyLimit\",\"type\":\"uint256\"},{\"internalType\":\"uint64\",\"name\":\"fee\",\"type\":\"uint64\"},{\"internalType\":\"bool\",\"name\":\"allowed\",\"type\":\"bool\"},{\"internalType\":\"bool\",\"name\":\"paused\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"burner\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"}],\"name\":\"burnFrom\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"burner\",\"type\":\"address\"}],\"name\":\"burnSelf\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"burnStablecoin\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"chainTotalHourlyLimit\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"name\":\"chainTotalUsage\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"currentTotalUsage\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"bridgeToken\",\"type\":\"address\"}],\"name\":\"currentUsage\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"decimals\",\"outputs\":[{\"internalType\":\"uint8\",\"name\":\"\",\"type\":\"uint8\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"spender\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"subtractedValue\",\"type\":\"uint256\"}],\"name\":\"decreaseAllowance\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"spender\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"addedValue\",\"type\":\"uint256\"}],\"name\":\"increaseAllowance\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"string\",\"name\":\"name_\",\"type\":\"string\"},{\"internalType\":\"string\",\"name\":\"symbol_\",\"type\":\"string\"},{\"internalType\":\"address\",\"name\":\"_treasury\",\"type\":\"address\"}],\"name\":\"initialize\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"isFeeExempt\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"isMinter\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"mint\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"name\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"}],\"name\":\"nonces\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"spender\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"deadline\",\"type\":\"uint256\"},{\"internalType\":\"uint8\",\"name\":\"v\",\"type\":\"uint8\"},{\"internalType\":\"bytes32\",\"name\":\"r\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32\",\"name\":\"s\",\"type\":\"bytes32\"}],\"name\":\"permit\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"tokenAddress\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amountToRecover\",\"type\":\"uint256\"}],\"name\":\"recoverERC20\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"bridgeToken\",\"type\":\"address\"}],\"name\":\"removeBridgeToken\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"minter\",\"type\":\"address\"}],\"name\":\"removeMinter\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"hourlyLimit\",\"type\":\"uint256\"}],\"name\":\"setChainTotalHourlyLimit\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"bridgeToken\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"hourlyLimit\",\"type\":\"uint256\"}],\"name\":\"setHourlyLimit\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"bridgeToken\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"limit\",\"type\":\"uint256\"}],\"name\":\"setLimit\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"bridgeToken\",\"type\":\"address\"},{\"internalType\":\"uint64\",\"name\":\"fee\",\"type\":\"uint64\"}],\"name\":\"setSwapFee\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_treasury\",\"type\":\"address\"}],\"name\":\"setTreasury\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"bridgeToken\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"swapIn\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"bridgeToken\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"swapOut\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"symbol\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"bridgeToken\",\"type\":\"address\"}],\"name\":\"toggleBridge\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"theAddress\",\"type\":\"address\"}],\"name\":\"toggleFeesForAddress\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"totalSupply\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"recipient\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"transfer\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"recipient\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"transferFrom\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"treasury\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"name\":\"usage\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"}],\"devdoc\":{\"author\":\"Angle Core Team\",\"details\":\"This contract supports bridge tokens having a minting right on the stablecoin (also referred to as the canonical or the native token)References: - FRAX implementation: https://polygonscan.com/address/0x45c32fA6DF82ead1e2EF74d17b76547EDdFaFF89#code - QiDAO implementation: https://snowtrace.io/address/0x5c49b268c9841AFF1Cc3B0a418ff5c3442eE3F3b#code\",\"kind\":\"dev\",\"methods\":{\"DOMAIN_SEPARATOR()\":{\"details\":\"See {IERC20Permit-DOMAIN_SEPARATOR}.\"},\"addBridgeToken(address,uint256,uint256,uint64,bool)\":{\"params\":{\"bridgeToken\":\"Bridge token to add: it should be a version of the stablecoin from another bridge\",\"fee\":\"Fee taken upon swapping for or against this token\",\"hourlyLimit\":\"Limit on the hourly volume for this bridge\",\"limit\":\"Limit on the balance of bridge token this contract could hold\",\"paused\":\"Whether swapping for this token should be paused or not\"}},\"addMinter(address)\":{\"details\":\"Zero address checks are performed directly in the `Treasury` contract\",\"params\":{\"minter\":\"Minter address to add\"}},\"allBridgeTokens()\":{\"details\":\"Helpful for UIs\"},\"allowance(address,address)\":{\"details\":\"See {IERC20-allowance}.\"},\"approve(address,uint256)\":{\"details\":\"See {IERC20-approve}. Requirements: - `spender` cannot be the zero address.\"},\"balanceOf(address)\":{\"details\":\"See {IERC20-balanceOf}.\"},\"burnFrom(uint256,address,address)\":{\"details\":\"This method is to be called by a contract with the minter right after being requested to do so by a `sender` address willing to burn tokens from another `burner` addressThe method checks the allowance between the `sender` and the `burner`\",\"params\":{\"amount\":\"Amount of tokens to burn\",\"burner\":\"Address to burn from\",\"sender\":\"Address which requested the burn from `burner`\"}},\"burnSelf(uint256,address)\":{\"details\":\"This method is to be called by a contract with a minter right on the AgToken after being requested to do so by an address willing to burn tokens from its address\",\"params\":{\"amount\":\"Amount of tokens to burn\",\"burner\":\"Address to burn from\"}},\"burnStablecoin(uint256)\":{\"details\":\"This function can typically be called if there is a settlement mechanism to burn stablecoins\",\"params\":{\"amount\":\"Amount of stablecoins to burn\"}},\"currentTotalUsage()\":{\"details\":\"Helpful for UIs\"},\"currentUsage(address)\":{\"details\":\"Helpful for UIs\",\"params\":{\"bridgeToken\":\"Bridge used to mint\"}},\"decimals()\":{\"details\":\"Returns the number of decimals used to get its user representation. For example, if `decimals` equals `2`, a balance of `505` tokens should be displayed to a user as `5.05` (`505 / 10 ** 2`). Tokens usually opt for a value of 18, imitating the relationship between Ether and Wei. This is the value {ERC20} uses, unless this function is overridden; NOTE: This information is only used for _display_ purposes: it in no way affects any of the arithmetic of the contract, including {IERC20-balanceOf} and {IERC20-transfer}.\"},\"decreaseAllowance(address,uint256)\":{\"details\":\"Atomically decreases the allowance granted to `spender` by the caller. This is an alternative to {approve} that can be used as a mitigation for problems described in {IERC20-approve}. Emits an {Approval} event indicating the updated allowance. Requirements: - `spender` cannot be the zero address. - `spender` must have allowance for the caller of at least `subtractedValue`.\"},\"increaseAllowance(address,uint256)\":{\"details\":\"Atomically increases the allowance granted to `spender` by the caller. This is an alternative to {approve} that can be used as a mitigation for problems described in {IERC20-approve}. Emits an {Approval} event indicating the updated allowance. Requirements: - `spender` cannot be the zero address.\"},\"initialize(string,string,address)\":{\"details\":\"By default, agTokens are ERC-20 tokens with 18 decimals\",\"params\":{\"_treasury\":\"Reference to the `Treasury` contract associated to this agToken\",\"name_\":\"Name of the token\",\"symbol_\":\"Symbol of the token\"}},\"mint(address,uint256)\":{\"details\":\"The contracts allowed to issue agTokens are the `StableMaster` contract, `VaultManager` contracts associated to this stablecoin as well as the flash loan module (if activated) and potentially contracts whitelisted by governance\",\"params\":{\"account\":\"Address to mint to\",\"amount\":\"Amount to mint\"}},\"name()\":{\"details\":\"Returns the name of the token.\"},\"nonces(address)\":{\"details\":\"See {IERC20Permit-nonces}.\"},\"permit(address,address,uint256,uint256,uint8,bytes32,bytes32)\":{\"details\":\"See {IERC20Permit-permit}.\"},\"recoverERC20(address,address,uint256)\":{\"details\":\"Can be used to withdraw bridge tokens for them to be de-bridged on mainnet\"},\"removeBridgeToken(address)\":{\"params\":{\"bridgeToken\":\"Address of the bridge token to remove support for\"}},\"removeMinter(address)\":{\"details\":\"This function can also be called by a minter wishing to revoke itself\",\"params\":{\"minter\":\"Minter address to remove\"}},\"setTreasury(address)\":{\"params\":{\"_treasury\":\"New treasury address\"}},\"swapIn(address,uint256,address)\":{\"details\":\"Some fees may be taken by the protocol depending on the token used and on the address calling\",\"params\":{\"amount\":\"Amount of bridge tokens to send\",\"bridgeToken\":\"Bridge token to use to mint\",\"to\":\"Address to which the stablecoin should be sent\"},\"returns\":{\"_0\":\"Amount of the canonical stablecoin actually minted\"}},\"swapOut(address,uint256,address)\":{\"details\":\"Some fees may be taken by the protocol depending on the token used and on the address calling\",\"params\":{\"amount\":\"Amount of canonical tokens to burn\",\"bridgeToken\":\"Bridge token required\",\"to\":\"Address to which the bridge token should be sent\"},\"returns\":{\"_0\":\"Amount of bridge tokens actually sent back\"}},\"symbol()\":{\"details\":\"Returns the symbol of the token, usually a shorter version of the name.\"},\"totalSupply()\":{\"details\":\"See {IERC20-totalSupply}.\"},\"transfer(address,uint256)\":{\"details\":\"See {IERC20-transfer}. Requirements: - `recipient` cannot be the zero address. - the caller must have a balance of at least `amount`.\"},\"transferFrom(address,address,uint256)\":{\"details\":\"See {IERC20-transferFrom}. Emits an {Approval} event indicating the updated allowance. This is not required by the EIP. See the note at the beginning of {ERC20}. Requirements: - `sender` and `recipient` cannot be the zero address. - `sender` must have a balance of at least `amount`. - the caller must have allowance for ``sender``'s tokens of at least `amount`.\"}},\"title\":\"AgTokenSideChainMultiBridge\",\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{\"BASE_PARAMS()\":{\"notice\":\"Base used for fee computation\"},\"addBridgeToken(address,uint256,uint256,uint64,bool)\":{\"notice\":\"Adds support for a bridge token\"},\"addMinter(address)\":{\"notice\":\"Adds a minter in the contract\"},\"allBridgeTokens()\":{\"notice\":\"Returns the list of all supported bridge tokens\"},\"bridgeTokensList(uint256)\":{\"notice\":\"List of all bridge tokens\"},\"bridges(address)\":{\"notice\":\"Maps a bridge token to data\"},\"burnFrom(uint256,address,address)\":{\"notice\":\"Burns `amount` tokens from a `burner` address after being asked to by `sender`\"},\"burnSelf(uint256,address)\":{\"notice\":\"Burns `amount` tokens from a `burner` address\"},\"burnStablecoin(uint256)\":{\"notice\":\"Allows anyone to burn agToken without redeeming collateral back\"},\"chainTotalHourlyLimit()\":{\"notice\":\"Limit to the amount of tokens that can be sent from that chain to another chain\"},\"chainTotalUsage(uint256)\":{\"notice\":\"Usage per hour on that chain. Maps an hourly timestamp to the total volume swapped out on the chain\"},\"currentTotalUsage()\":{\"notice\":\"Returns the current total volume on the chain for the current hour\"},\"currentUsage(address)\":{\"notice\":\"Returns the current volume for a bridge, for the current hour\"},\"initialize(string,string,address)\":{\"notice\":\"Initializes the `AgToken` contract\"},\"isFeeExempt(address)\":{\"notice\":\"Maps an address to whether it is exempt of fees for when it comes to swapping in and out\"},\"isMinter(address)\":{\"notice\":\"Checks whether an address has the right to mint agTokens\"},\"mint(address,uint256)\":{\"notice\":\"Lets the `StableMaster` contract or another whitelisted contract mint agTokens\"},\"recoverERC20(address,address,uint256)\":{\"notice\":\"Recovers any ERC20 token\"},\"removeBridgeToken(address)\":{\"notice\":\"Removes support for a token\"},\"removeMinter(address)\":{\"notice\":\"Removes a minter from the contract\"},\"setChainTotalHourlyLimit(uint256)\":{\"notice\":\"Updates the `chainTotalHourlyLimit` amount\"},\"setHourlyLimit(address,uint256)\":{\"notice\":\"Updates the `hourlyLimit` amount for `bridgeToken`\"},\"setLimit(address,uint256)\":{\"notice\":\"Updates the `limit` amount for `bridgeToken`\"},\"setSwapFee(address,uint64)\":{\"notice\":\"Updates the `fee` value for `bridgeToken`\"},\"setTreasury(address)\":{\"notice\":\"Sets a new treasury contract\"},\"swapIn(address,uint256,address)\":{\"notice\":\"Mints the canonical token from a supported bridge token\"},\"swapOut(address,uint256,address)\":{\"notice\":\"Burns the canonical token in exchange for a bridge token\"},\"toggleBridge(address)\":{\"notice\":\"Pauses or unpauses swapping in and out for a token\"},\"toggleFeesForAddress(address)\":{\"notice\":\"Toggles fees for the address `theAddress`\"},\"treasury()\":{\"notice\":\"Reference to the treasury contract which can grant minting rights\"},\"usage(address,uint256)\":{\"notice\":\"Maps a bridge token to the associated hourly volume\"}},\"notice\":\"Contract for Angle agTokens on other chains than Ethereum mainnet\",\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/agToken/AgTokenSideChainMultiBridge.sol\":\"AgTokenSideChainMultiBridge\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":1000000},\"remappings\":[]},\"sources\":{\"@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (proxy/utils/Initializable.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../../utils/AddressUpgradeable.sol\\\";\\n\\n/**\\n * @dev This is a base contract to aid in writing upgradeable contracts, or any kind of contract that will be deployed\\n * behind a proxy. Since a proxied contract can't have a constructor, it's common to move constructor logic to an\\n * external initializer function, usually called `initialize`. It then becomes necessary to protect this initializer\\n * function so it can only be called once. The {initializer} modifier provided by this contract will have this effect.\\n *\\n * TIP: To avoid leaving the proxy in an uninitialized state, the initializer function should be called as early as\\n * possible by providing the encoded function call as the `_data` argument to {ERC1967Proxy-constructor}.\\n *\\n * CAUTION: When used with inheritance, manual care must be taken to not invoke a parent initializer twice, or to ensure\\n * that all initializers are idempotent. This is not verified automatically as constructors are by Solidity.\\n *\\n * [CAUTION]\\n * ====\\n * Avoid leaving a contract uninitialized.\\n *\\n * An uninitialized contract can be taken over by an attacker. This applies to both a proxy and its implementation\\n * contract, which may impact the proxy. To initialize the implementation contract, you can either invoke the\\n * initializer manually, or you can include a constructor to automatically mark it as initialized when it is deployed:\\n *\\n * [.hljs-theme-light.nopadding]\\n * ```\\n * /// @custom:oz-upgrades-unsafe-allow constructor\\n * constructor() initializer {}\\n * ```\\n * ====\\n */\\nabstract contract Initializable {\\n /**\\n * @dev Indicates that the contract has been initialized.\\n */\\n bool private _initialized;\\n\\n /**\\n * @dev Indicates that the contract is in the process of being initialized.\\n */\\n bool private _initializing;\\n\\n /**\\n * @dev Modifier to protect an initializer function from being invoked twice.\\n */\\n modifier initializer() {\\n // If the contract is initializing we ignore whether _initialized is set in order to support multiple\\n // inheritance patterns, but we only do this in the context of a constructor, because in other contexts the\\n // contract may have been reentered.\\n require(_initializing ? _isConstructor() : !_initialized, \\\"Initializable: contract is already initialized\\\");\\n\\n bool isTopLevelCall = !_initializing;\\n if (isTopLevelCall) {\\n _initializing = true;\\n _initialized = true;\\n }\\n\\n _;\\n\\n if (isTopLevelCall) {\\n _initializing = false;\\n }\\n }\\n\\n /**\\n * @dev Modifier to protect an initialization function so that it can only be invoked by functions with the\\n * {initializer} modifier, directly or indirectly.\\n */\\n modifier onlyInitializing() {\\n require(_initializing, \\\"Initializable: contract is not initializing\\\");\\n _;\\n }\\n\\n function _isConstructor() private view returns (bool) {\\n return !AddressUpgradeable.isContract(address(this));\\n }\\n}\\n\",\"keccak256\":\"0x68861bcc80cacbd498efde75aab6c74a486cc48262660d326c8d7530d9752097\",\"license\":\"MIT\"},\"@openzeppelin/contracts-upgradeable/token/ERC20/ERC20Upgradeable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (token/ERC20/ERC20.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"./IERC20Upgradeable.sol\\\";\\nimport \\\"./extensions/IERC20MetadataUpgradeable.sol\\\";\\nimport \\\"../../utils/ContextUpgradeable.sol\\\";\\nimport \\\"../../proxy/utils/Initializable.sol\\\";\\n\\n/**\\n * @dev Implementation of the {IERC20} interface.\\n *\\n * This implementation is agnostic to the way tokens are created. This means\\n * that a supply mechanism has to be added in a derived contract using {_mint}.\\n * For a generic mechanism see {ERC20PresetMinterPauser}.\\n *\\n * TIP: For a detailed writeup see our guide\\n * https://forum.zeppelin.solutions/t/how-to-implement-erc20-supply-mechanisms/226[How\\n * to implement supply mechanisms].\\n *\\n * We have followed general OpenZeppelin Contracts guidelines: functions revert\\n * instead returning `false` on failure. This behavior is nonetheless\\n * conventional and does not conflict with the expectations of ERC20\\n * applications.\\n *\\n * Additionally, an {Approval} event is emitted on calls to {transferFrom}.\\n * This allows applications to reconstruct the allowance for all accounts just\\n * by listening to said events. Other implementations of the EIP may not emit\\n * these events, as it isn't required by the specification.\\n *\\n * Finally, the non-standard {decreaseAllowance} and {increaseAllowance}\\n * functions have been added to mitigate the well-known issues around setting\\n * allowances. See {IERC20-approve}.\\n */\\ncontract ERC20Upgradeable is Initializable, ContextUpgradeable, IERC20Upgradeable, IERC20MetadataUpgradeable {\\n mapping(address => uint256) private _balances;\\n\\n mapping(address => mapping(address => uint256)) private _allowances;\\n\\n uint256 private _totalSupply;\\n\\n string private _name;\\n string private _symbol;\\n\\n /**\\n * @dev Sets the values for {name} and {symbol}.\\n *\\n * The default value of {decimals} is 18. To select a different value for\\n * {decimals} you should overload it.\\n *\\n * All two of these values are immutable: they can only be set once during\\n * construction.\\n */\\n function __ERC20_init(string memory name_, string memory symbol_) internal onlyInitializing {\\n __Context_init_unchained();\\n __ERC20_init_unchained(name_, symbol_);\\n }\\n\\n function __ERC20_init_unchained(string memory name_, string memory symbol_) internal onlyInitializing {\\n _name = name_;\\n _symbol = symbol_;\\n }\\n\\n /**\\n * @dev Returns the name of the token.\\n */\\n function name() public view virtual override returns (string memory) {\\n return _name;\\n }\\n\\n /**\\n * @dev Returns the symbol of the token, usually a shorter version of the\\n * name.\\n */\\n function symbol() public view virtual override returns (string memory) {\\n return _symbol;\\n }\\n\\n /**\\n * @dev Returns the number of decimals used to get its user representation.\\n * For example, if `decimals` equals `2`, a balance of `505` tokens should\\n * be displayed to a user as `5.05` (`505 / 10 ** 2`).\\n *\\n * Tokens usually opt for a value of 18, imitating the relationship between\\n * Ether and Wei. This is the value {ERC20} uses, unless this function is\\n * overridden;\\n *\\n * NOTE: This information is only used for _display_ purposes: it in\\n * no way affects any of the arithmetic of the contract, including\\n * {IERC20-balanceOf} and {IERC20-transfer}.\\n */\\n function decimals() public view virtual override returns (uint8) {\\n return 18;\\n }\\n\\n /**\\n * @dev See {IERC20-totalSupply}.\\n */\\n function totalSupply() public view virtual override returns (uint256) {\\n return _totalSupply;\\n }\\n\\n /**\\n * @dev See {IERC20-balanceOf}.\\n */\\n function balanceOf(address account) public view virtual override returns (uint256) {\\n return _balances[account];\\n }\\n\\n /**\\n * @dev See {IERC20-transfer}.\\n *\\n * Requirements:\\n *\\n * - `recipient` cannot be the zero address.\\n * - the caller must have a balance of at least `amount`.\\n */\\n function transfer(address recipient, uint256 amount) public virtual override returns (bool) {\\n _transfer(_msgSender(), recipient, amount);\\n return true;\\n }\\n\\n /**\\n * @dev See {IERC20-allowance}.\\n */\\n function allowance(address owner, address spender) public view virtual override returns (uint256) {\\n return _allowances[owner][spender];\\n }\\n\\n /**\\n * @dev See {IERC20-approve}.\\n *\\n * Requirements:\\n *\\n * - `spender` cannot be the zero address.\\n */\\n function approve(address spender, uint256 amount) public virtual override returns (bool) {\\n _approve(_msgSender(), spender, amount);\\n return true;\\n }\\n\\n /**\\n * @dev See {IERC20-transferFrom}.\\n *\\n * Emits an {Approval} event indicating the updated allowance. This is not\\n * required by the EIP. See the note at the beginning of {ERC20}.\\n *\\n * Requirements:\\n *\\n * - `sender` and `recipient` cannot be the zero address.\\n * - `sender` must have a balance of at least `amount`.\\n * - the caller must have allowance for ``sender``'s tokens of at least\\n * `amount`.\\n */\\n function transferFrom(\\n address sender,\\n address recipient,\\n uint256 amount\\n ) public virtual override returns (bool) {\\n _transfer(sender, recipient, amount);\\n\\n uint256 currentAllowance = _allowances[sender][_msgSender()];\\n require(currentAllowance >= amount, \\\"ERC20: transfer amount exceeds allowance\\\");\\n unchecked {\\n _approve(sender, _msgSender(), currentAllowance - amount);\\n }\\n\\n return true;\\n }\\n\\n /**\\n * @dev Atomically increases the allowance granted to `spender` by the caller.\\n *\\n * This is an alternative to {approve} that can be used as a mitigation for\\n * problems described in {IERC20-approve}.\\n *\\n * Emits an {Approval} event indicating the updated allowance.\\n *\\n * Requirements:\\n *\\n * - `spender` cannot be the zero address.\\n */\\n function increaseAllowance(address spender, uint256 addedValue) public virtual returns (bool) {\\n _approve(_msgSender(), spender, _allowances[_msgSender()][spender] + addedValue);\\n return true;\\n }\\n\\n /**\\n * @dev Atomically decreases the allowance granted to `spender` by the caller.\\n *\\n * This is an alternative to {approve} that can be used as a mitigation for\\n * problems described in {IERC20-approve}.\\n *\\n * Emits an {Approval} event indicating the updated allowance.\\n *\\n * Requirements:\\n *\\n * - `spender` cannot be the zero address.\\n * - `spender` must have allowance for the caller of at least\\n * `subtractedValue`.\\n */\\n function decreaseAllowance(address spender, uint256 subtractedValue) public virtual returns (bool) {\\n uint256 currentAllowance = _allowances[_msgSender()][spender];\\n require(currentAllowance >= subtractedValue, \\\"ERC20: decreased allowance below zero\\\");\\n unchecked {\\n _approve(_msgSender(), spender, currentAllowance - subtractedValue);\\n }\\n\\n return true;\\n }\\n\\n /**\\n * @dev Moves `amount` of tokens from `sender` to `recipient`.\\n *\\n * This internal function is equivalent to {transfer}, and can be used to\\n * e.g. implement automatic token fees, slashing mechanisms, etc.\\n *\\n * Emits a {Transfer} event.\\n *\\n * Requirements:\\n *\\n * - `sender` cannot be the zero address.\\n * - `recipient` cannot be the zero address.\\n * - `sender` must have a balance of at least `amount`.\\n */\\n function _transfer(\\n address sender,\\n address recipient,\\n uint256 amount\\n ) internal virtual {\\n require(sender != address(0), \\\"ERC20: transfer from the zero address\\\");\\n require(recipient != address(0), \\\"ERC20: transfer to the zero address\\\");\\n\\n _beforeTokenTransfer(sender, recipient, amount);\\n\\n uint256 senderBalance = _balances[sender];\\n require(senderBalance >= amount, \\\"ERC20: transfer amount exceeds balance\\\");\\n unchecked {\\n _balances[sender] = senderBalance - amount;\\n }\\n _balances[recipient] += amount;\\n\\n emit Transfer(sender, recipient, amount);\\n\\n _afterTokenTransfer(sender, recipient, amount);\\n }\\n\\n /** @dev Creates `amount` tokens and assigns them to `account`, increasing\\n * the total supply.\\n *\\n * Emits a {Transfer} event with `from` set to the zero address.\\n *\\n * Requirements:\\n *\\n * - `account` cannot be the zero address.\\n */\\n function _mint(address account, uint256 amount) internal virtual {\\n require(account != address(0), \\\"ERC20: mint to the zero address\\\");\\n\\n _beforeTokenTransfer(address(0), account, amount);\\n\\n _totalSupply += amount;\\n _balances[account] += amount;\\n emit Transfer(address(0), account, amount);\\n\\n _afterTokenTransfer(address(0), account, amount);\\n }\\n\\n /**\\n * @dev Destroys `amount` tokens from `account`, reducing the\\n * total supply.\\n *\\n * Emits a {Transfer} event with `to` set to the zero address.\\n *\\n * Requirements:\\n *\\n * - `account` cannot be the zero address.\\n * - `account` must have at least `amount` tokens.\\n */\\n function _burn(address account, uint256 amount) internal virtual {\\n require(account != address(0), \\\"ERC20: burn from the zero address\\\");\\n\\n _beforeTokenTransfer(account, address(0), amount);\\n\\n uint256 accountBalance = _balances[account];\\n require(accountBalance >= amount, \\\"ERC20: burn amount exceeds balance\\\");\\n unchecked {\\n _balances[account] = accountBalance - amount;\\n }\\n _totalSupply -= amount;\\n\\n emit Transfer(account, address(0), amount);\\n\\n _afterTokenTransfer(account, address(0), amount);\\n }\\n\\n /**\\n * @dev Sets `amount` as the allowance of `spender` over the `owner` s tokens.\\n *\\n * This internal function is equivalent to `approve`, and can be used to\\n * e.g. set automatic allowances for certain subsystems, etc.\\n *\\n * Emits an {Approval} event.\\n *\\n * Requirements:\\n *\\n * - `owner` cannot be the zero address.\\n * - `spender` cannot be the zero address.\\n */\\n function _approve(\\n address owner,\\n address spender,\\n uint256 amount\\n ) internal virtual {\\n require(owner != address(0), \\\"ERC20: approve from the zero address\\\");\\n require(spender != address(0), \\\"ERC20: approve to the zero address\\\");\\n\\n _allowances[owner][spender] = amount;\\n emit Approval(owner, spender, amount);\\n }\\n\\n /**\\n * @dev Hook that is called before any transfer of tokens. This includes\\n * minting and burning.\\n *\\n * Calling conditions:\\n *\\n * - when `from` and `to` are both non-zero, `amount` of ``from``'s tokens\\n * will be transferred to `to`.\\n * - when `from` is zero, `amount` tokens will be minted for `to`.\\n * - when `to` is zero, `amount` of ``from``'s tokens will be burned.\\n * - `from` and `to` are never both zero.\\n *\\n * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].\\n */\\n function _beforeTokenTransfer(\\n address from,\\n address to,\\n uint256 amount\\n ) internal virtual {}\\n\\n /**\\n * @dev Hook that is called after any transfer of tokens. This includes\\n * minting and burning.\\n *\\n * Calling conditions:\\n *\\n * - when `from` and `to` are both non-zero, `amount` of ``from``'s tokens\\n * has been transferred to `to`.\\n * - when `from` is zero, `amount` tokens have been minted for `to`.\\n * - when `to` is zero, `amount` of ``from``'s tokens have been burned.\\n * - `from` and `to` are never both zero.\\n *\\n * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].\\n */\\n function _afterTokenTransfer(\\n address from,\\n address to,\\n uint256 amount\\n ) internal virtual {}\\n uint256[45] private __gap;\\n}\\n\",\"keccak256\":\"0x23a373902059fb51db98e32e13f89a0ef0c570039081a1345022e66bc7e315d4\",\"license\":\"MIT\"},\"@openzeppelin/contracts-upgradeable/token/ERC20/IERC20Upgradeable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (token/ERC20/IERC20.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Interface of the ERC20 standard as defined in the EIP.\\n */\\ninterface IERC20Upgradeable {\\n /**\\n * @dev Returns the amount of tokens in existence.\\n */\\n function totalSupply() external view returns (uint256);\\n\\n /**\\n * @dev Returns the amount of tokens owned by `account`.\\n */\\n function balanceOf(address account) external view returns (uint256);\\n\\n /**\\n * @dev Moves `amount` tokens from the caller's account to `recipient`.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * Emits a {Transfer} event.\\n */\\n function transfer(address recipient, uint256 amount) external returns (bool);\\n\\n /**\\n * @dev Returns the remaining number of tokens that `spender` will be\\n * allowed to spend on behalf of `owner` through {transferFrom}. This is\\n * zero by default.\\n *\\n * This value changes when {approve} or {transferFrom} are called.\\n */\\n function allowance(address owner, address spender) external view returns (uint256);\\n\\n /**\\n * @dev Sets `amount` as the allowance of `spender` over the caller's tokens.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * IMPORTANT: Beware that changing an allowance with this method brings the risk\\n * that someone may use both the old and the new allowance by unfortunate\\n * transaction ordering. One possible solution to mitigate this race\\n * condition is to first reduce the spender's allowance to 0 and set the\\n * desired value afterwards:\\n * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729\\n *\\n * Emits an {Approval} event.\\n */\\n function approve(address spender, uint256 amount) external returns (bool);\\n\\n /**\\n * @dev Moves `amount` tokens from `sender` to `recipient` using the\\n * allowance mechanism. `amount` is then deducted from the caller's\\n * allowance.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * Emits a {Transfer} event.\\n */\\n function transferFrom(\\n address sender,\\n address recipient,\\n uint256 amount\\n ) external returns (bool);\\n\\n /**\\n * @dev Emitted when `value` tokens are moved from one account (`from`) to\\n * another (`to`).\\n *\\n * Note that `value` may be zero.\\n */\\n event Transfer(address indexed from, address indexed to, uint256 value);\\n\\n /**\\n * @dev Emitted when the allowance of a `spender` for an `owner` is set by\\n * a call to {approve}. `value` is the new allowance.\\n */\\n event Approval(address indexed owner, address indexed spender, uint256 value);\\n}\\n\",\"keccak256\":\"0x5ca0eb1120133a6d0799752532d4638048391823a2b623c4fe9ff46e262266fb\",\"license\":\"MIT\"},\"@openzeppelin/contracts-upgradeable/token/ERC20/extensions/IERC20MetadataUpgradeable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (token/ERC20/extensions/IERC20Metadata.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../IERC20Upgradeable.sol\\\";\\n\\n/**\\n * @dev Interface for the optional metadata functions from the ERC20 standard.\\n *\\n * _Available since v4.1._\\n */\\ninterface IERC20MetadataUpgradeable is IERC20Upgradeable {\\n /**\\n * @dev Returns the name of the token.\\n */\\n function name() external view returns (string memory);\\n\\n /**\\n * @dev Returns the symbol of the token.\\n */\\n function symbol() external view returns (string memory);\\n\\n /**\\n * @dev Returns the decimals places of the token.\\n */\\n function decimals() external view returns (uint8);\\n}\\n\",\"keccak256\":\"0x605434219ebbe4653f703640f06969faa5a1d78f0bfef878e5ddbb1ca369ceeb\",\"license\":\"MIT\"},\"@openzeppelin/contracts-upgradeable/token/ERC20/extensions/draft-ERC20PermitUpgradeable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (token/ERC20/extensions/draft-ERC20Permit.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"./draft-IERC20PermitUpgradeable.sol\\\";\\nimport \\\"../ERC20Upgradeable.sol\\\";\\nimport \\\"../../../utils/cryptography/draft-EIP712Upgradeable.sol\\\";\\nimport \\\"../../../utils/cryptography/ECDSAUpgradeable.sol\\\";\\nimport \\\"../../../utils/CountersUpgradeable.sol\\\";\\nimport \\\"../../../proxy/utils/Initializable.sol\\\";\\n\\n/**\\n * @dev Implementation of the ERC20 Permit extension allowing approvals to be made via signatures, as defined in\\n * https://eips.ethereum.org/EIPS/eip-2612[EIP-2612].\\n *\\n * Adds the {permit} method, which can be used to change an account's ERC20 allowance (see {IERC20-allowance}) by\\n * presenting a message signed by the account. By not relying on `{IERC20-approve}`, the token holder account doesn't\\n * need to send a transaction, and thus is not required to hold Ether at all.\\n *\\n * _Available since v3.4._\\n */\\nabstract contract ERC20PermitUpgradeable is Initializable, ERC20Upgradeable, IERC20PermitUpgradeable, EIP712Upgradeable {\\n using CountersUpgradeable for CountersUpgradeable.Counter;\\n\\n mapping(address => CountersUpgradeable.Counter) private _nonces;\\n\\n // solhint-disable-next-line var-name-mixedcase\\n bytes32 private _PERMIT_TYPEHASH;\\n\\n /**\\n * @dev Initializes the {EIP712} domain separator using the `name` parameter, and setting `version` to `\\\"1\\\"`.\\n *\\n * It's a good idea to use the same `name` that is defined as the ERC20 token name.\\n */\\n function __ERC20Permit_init(string memory name) internal onlyInitializing {\\n __Context_init_unchained();\\n __EIP712_init_unchained(name, \\\"1\\\");\\n __ERC20Permit_init_unchained(name);\\n }\\n\\n function __ERC20Permit_init_unchained(string memory name) internal onlyInitializing {\\n _PERMIT_TYPEHASH = keccak256(\\\"Permit(address owner,address spender,uint256 value,uint256 nonce,uint256 deadline)\\\");}\\n\\n /**\\n * @dev See {IERC20Permit-permit}.\\n */\\n function permit(\\n address owner,\\n address spender,\\n uint256 value,\\n uint256 deadline,\\n uint8 v,\\n bytes32 r,\\n bytes32 s\\n ) public virtual override {\\n require(block.timestamp <= deadline, \\\"ERC20Permit: expired deadline\\\");\\n\\n bytes32 structHash = keccak256(abi.encode(_PERMIT_TYPEHASH, owner, spender, value, _useNonce(owner), deadline));\\n\\n bytes32 hash = _hashTypedDataV4(structHash);\\n\\n address signer = ECDSAUpgradeable.recover(hash, v, r, s);\\n require(signer == owner, \\\"ERC20Permit: invalid signature\\\");\\n\\n _approve(owner, spender, value);\\n }\\n\\n /**\\n * @dev See {IERC20Permit-nonces}.\\n */\\n function nonces(address owner) public view virtual override returns (uint256) {\\n return _nonces[owner].current();\\n }\\n\\n /**\\n * @dev See {IERC20Permit-DOMAIN_SEPARATOR}.\\n */\\n // solhint-disable-next-line func-name-mixedcase\\n function DOMAIN_SEPARATOR() external view override returns (bytes32) {\\n return _domainSeparatorV4();\\n }\\n\\n /**\\n * @dev \\\"Consume a nonce\\\": return the current value and increment.\\n *\\n * _Available since v4.1._\\n */\\n function _useNonce(address owner) internal virtual returns (uint256 current) {\\n CountersUpgradeable.Counter storage nonce = _nonces[owner];\\n current = nonce.current();\\n nonce.increment();\\n }\\n uint256[49] private __gap;\\n}\\n\",\"keccak256\":\"0x7fb71e823080ba5e320f036c7dbda29f3676f3d516db4dcdb8b0adbfbae5d830\",\"license\":\"MIT\"},\"@openzeppelin/contracts-upgradeable/token/ERC20/extensions/draft-IERC20PermitUpgradeable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (token/ERC20/extensions/draft-IERC20Permit.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Interface of the ERC20 Permit extension allowing approvals to be made via signatures, as defined in\\n * https://eips.ethereum.org/EIPS/eip-2612[EIP-2612].\\n *\\n * Adds the {permit} method, which can be used to change an account's ERC20 allowance (see {IERC20-allowance}) by\\n * presenting a message signed by the account. By not relying on {IERC20-approve}, the token holder account doesn't\\n * need to send a transaction, and thus is not required to hold Ether at all.\\n */\\ninterface IERC20PermitUpgradeable {\\n /**\\n * @dev Sets `value` as the allowance of `spender` over ``owner``'s tokens,\\n * given ``owner``'s signed approval.\\n *\\n * IMPORTANT: The same issues {IERC20-approve} has related to transaction\\n * ordering also apply here.\\n *\\n * Emits an {Approval} event.\\n *\\n * Requirements:\\n *\\n * - `spender` cannot be the zero address.\\n * - `deadline` must be a timestamp in the future.\\n * - `v`, `r` and `s` must be a valid `secp256k1` signature from `owner`\\n * over the EIP712-formatted function arguments.\\n * - the signature must use ``owner``'s current nonce (see {nonces}).\\n *\\n * For more information on the signature format, see the\\n * https://eips.ethereum.org/EIPS/eip-2612#specification[relevant EIP\\n * section].\\n */\\n function permit(\\n address owner,\\n address spender,\\n uint256 value,\\n uint256 deadline,\\n uint8 v,\\n bytes32 r,\\n bytes32 s\\n ) external;\\n\\n /**\\n * @dev Returns the current nonce for `owner`. This value must be\\n * included whenever a signature is generated for {permit}.\\n *\\n * Every successful call to {permit} increases ``owner``'s nonce by one. This\\n * prevents a signature from being used multiple times.\\n */\\n function nonces(address owner) external view returns (uint256);\\n\\n /**\\n * @dev Returns the domain separator used in the encoding of the signature for {permit}, as defined by {EIP712}.\\n */\\n // solhint-disable-next-line func-name-mixedcase\\n function DOMAIN_SEPARATOR() external view returns (bytes32);\\n}\\n\",\"keccak256\":\"0xcc70d8e2281fb3ff69e8ab242500f10142cd0a7fa8dd9e45882be270d4d09024\",\"license\":\"MIT\"},\"@openzeppelin/contracts-upgradeable/utils/AddressUpgradeable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (utils/Address.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Collection of functions related to the address type\\n */\\nlibrary AddressUpgradeable {\\n /**\\n * @dev Returns true if `account` is a contract.\\n *\\n * [IMPORTANT]\\n * ====\\n * It is unsafe to assume that an address for which this function returns\\n * false is an externally-owned account (EOA) and not a contract.\\n *\\n * Among others, `isContract` will return false for the following\\n * types of addresses:\\n *\\n * - an externally-owned account\\n * - a contract in construction\\n * - an address where a contract will be created\\n * - an address where a contract lived, but was destroyed\\n * ====\\n */\\n function isContract(address account) internal view returns (bool) {\\n // This method relies on extcodesize, which returns 0 for contracts in\\n // construction, since the code is only stored at the end of the\\n // constructor execution.\\n\\n uint256 size;\\n assembly {\\n size := extcodesize(account)\\n }\\n return size > 0;\\n }\\n\\n /**\\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\\n * `recipient`, forwarding all available gas and reverting on errors.\\n *\\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\\n * imposed by `transfer`, making them unable to receive funds via\\n * `transfer`. {sendValue} removes this limitation.\\n *\\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\\n *\\n * IMPORTANT: because control is transferred to `recipient`, care must be\\n * taken to not create reentrancy vulnerabilities. Consider using\\n * {ReentrancyGuard} or the\\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\\n */\\n function sendValue(address payable recipient, uint256 amount) internal {\\n require(address(this).balance >= amount, \\\"Address: insufficient balance\\\");\\n\\n (bool success, ) = recipient.call{value: amount}(\\\"\\\");\\n require(success, \\\"Address: unable to send value, recipient may have reverted\\\");\\n }\\n\\n /**\\n * @dev Performs a Solidity function call using a low level `call`. A\\n * plain `call` is an unsafe replacement for a function call: use this\\n * function instead.\\n *\\n * If `target` reverts with a revert reason, it is bubbled up by this\\n * function (like regular Solidity function calls).\\n *\\n * Returns the raw returned data. To convert to the expected return value,\\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\\n *\\n * Requirements:\\n *\\n * - `target` must be a contract.\\n * - calling `target` with `data` must not revert.\\n *\\n * _Available since v3.1._\\n */\\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\\n return functionCall(target, data, \\\"Address: low-level call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\\n * `errorMessage` as a fallback revert reason when `target` reverts.\\n *\\n * _Available since v3.1._\\n */\\n function functionCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n return functionCallWithValue(target, data, 0, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but also transferring `value` wei to `target`.\\n *\\n * Requirements:\\n *\\n * - the calling contract must have an ETH balance of at least `value`.\\n * - the called Solidity function must be `payable`.\\n *\\n * _Available since v3.1._\\n */\\n function functionCallWithValue(\\n address target,\\n bytes memory data,\\n uint256 value\\n ) internal returns (bytes memory) {\\n return functionCallWithValue(target, data, value, \\\"Address: low-level call with value failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\\n * with `errorMessage` as a fallback revert reason when `target` reverts.\\n *\\n * _Available since v3.1._\\n */\\n function functionCallWithValue(\\n address target,\\n bytes memory data,\\n uint256 value,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n require(address(this).balance >= value, \\\"Address: insufficient balance for call\\\");\\n require(isContract(target), \\\"Address: call to non-contract\\\");\\n\\n (bool success, bytes memory returndata) = target.call{value: value}(data);\\n return verifyCallResult(success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but performing a static call.\\n *\\n * _Available since v3.3._\\n */\\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\\n return functionStaticCall(target, data, \\\"Address: low-level static call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\\n * but performing a static call.\\n *\\n * _Available since v3.3._\\n */\\n function functionStaticCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal view returns (bytes memory) {\\n require(isContract(target), \\\"Address: static call to non-contract\\\");\\n\\n (bool success, bytes memory returndata) = target.staticcall(data);\\n return verifyCallResult(success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the\\n * revert reason using the provided one.\\n *\\n * _Available since v4.3._\\n */\\n function verifyCallResult(\\n bool success,\\n bytes memory returndata,\\n string memory errorMessage\\n ) internal pure returns (bytes memory) {\\n if (success) {\\n return returndata;\\n } else {\\n // Look for revert reason and bubble it up if present\\n if (returndata.length > 0) {\\n // The easiest way to bubble the revert reason is using memory via assembly\\n\\n assembly {\\n let returndata_size := mload(returndata)\\n revert(add(32, returndata), returndata_size)\\n }\\n } else {\\n revert(errorMessage);\\n }\\n }\\n }\\n}\\n\",\"keccak256\":\"0x3f0f878c796dfc7feba6d3c4e3e526c14c7deae8b7bfc71088e3f38fab0d77b3\",\"license\":\"MIT\"},\"@openzeppelin/contracts-upgradeable/utils/ContextUpgradeable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)\\n\\npragma solidity ^0.8.0;\\nimport \\\"../proxy/utils/Initializable.sol\\\";\\n\\n/**\\n * @dev Provides information about the current execution context, including the\\n * sender of the transaction and its data. While these are generally available\\n * via msg.sender and msg.data, they should not be accessed in such a direct\\n * manner, since when dealing with meta-transactions the account sending and\\n * paying for execution may not be the actual sender (as far as an application\\n * is concerned).\\n *\\n * This contract is only required for intermediate, library-like contracts.\\n */\\nabstract contract ContextUpgradeable is Initializable {\\n function __Context_init() internal onlyInitializing {\\n __Context_init_unchained();\\n }\\n\\n function __Context_init_unchained() internal onlyInitializing {\\n }\\n function _msgSender() internal view virtual returns (address) {\\n return msg.sender;\\n }\\n\\n function _msgData() internal view virtual returns (bytes calldata) {\\n return msg.data;\\n }\\n uint256[50] private __gap;\\n}\\n\",\"keccak256\":\"0x0b0d548f6381370d394f7a434f994dc678b3ef3e755de106109d61343a685ea7\",\"license\":\"MIT\"},\"@openzeppelin/contracts-upgradeable/utils/CountersUpgradeable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (utils/Counters.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @title Counters\\n * @author Matt Condon (@shrugs)\\n * @dev Provides counters that can only be incremented, decremented or reset. This can be used e.g. to track the number\\n * of elements in a mapping, issuing ERC721 ids, or counting request ids.\\n *\\n * Include with `using Counters for Counters.Counter;`\\n */\\nlibrary CountersUpgradeable {\\n struct Counter {\\n // This variable should never be directly accessed by users of the library: interactions must be restricted to\\n // the library's function. As of Solidity v0.5.2, this cannot be enforced, though there is a proposal to add\\n // this feature: see https://github.com/ethereum/solidity/issues/4637\\n uint256 _value; // default: 0\\n }\\n\\n function current(Counter storage counter) internal view returns (uint256) {\\n return counter._value;\\n }\\n\\n function increment(Counter storage counter) internal {\\n unchecked {\\n counter._value += 1;\\n }\\n }\\n\\n function decrement(Counter storage counter) internal {\\n uint256 value = counter._value;\\n require(value > 0, \\\"Counter: decrement overflow\\\");\\n unchecked {\\n counter._value = value - 1;\\n }\\n }\\n\\n function reset(Counter storage counter) internal {\\n counter._value = 0;\\n }\\n}\\n\",\"keccak256\":\"0x798741e231b22b81e2dd2eddaaf8832dee4baf5cd8e2dbaa5c1dd12a1c053c4d\",\"license\":\"MIT\"},\"@openzeppelin/contracts-upgradeable/utils/StringsUpgradeable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (utils/Strings.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev String operations.\\n */\\nlibrary StringsUpgradeable {\\n bytes16 private constant _HEX_SYMBOLS = \\\"0123456789abcdef\\\";\\n\\n /**\\n * @dev Converts a `uint256` to its ASCII `string` decimal representation.\\n */\\n function toString(uint256 value) internal pure returns (string memory) {\\n // Inspired by OraclizeAPI's implementation - MIT licence\\n // https://github.com/oraclize/ethereum-api/blob/b42146b063c7d6ee1358846c198246239e9360e8/oraclizeAPI_0.4.25.sol\\n\\n if (value == 0) {\\n return \\\"0\\\";\\n }\\n uint256 temp = value;\\n uint256 digits;\\n while (temp != 0) {\\n digits++;\\n temp /= 10;\\n }\\n bytes memory buffer = new bytes(digits);\\n while (value != 0) {\\n digits -= 1;\\n buffer[digits] = bytes1(uint8(48 + uint256(value % 10)));\\n value /= 10;\\n }\\n return string(buffer);\\n }\\n\\n /**\\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation.\\n */\\n function toHexString(uint256 value) internal pure returns (string memory) {\\n if (value == 0) {\\n return \\\"0x00\\\";\\n }\\n uint256 temp = value;\\n uint256 length = 0;\\n while (temp != 0) {\\n length++;\\n temp >>= 8;\\n }\\n return toHexString(value, length);\\n }\\n\\n /**\\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length.\\n */\\n function toHexString(uint256 value, uint256 length) internal pure returns (string memory) {\\n bytes memory buffer = new bytes(2 * length + 2);\\n buffer[0] = \\\"0\\\";\\n buffer[1] = \\\"x\\\";\\n for (uint256 i = 2 * length + 1; i > 1; --i) {\\n buffer[i] = _HEX_SYMBOLS[value & 0xf];\\n value >>= 4;\\n }\\n require(value == 0, \\\"Strings: hex length insufficient\\\");\\n return string(buffer);\\n }\\n}\\n\",\"keccak256\":\"0x398d3323c1932a5986bf36be7c57593e121e69d5db5b6574b4ee0d031443de37\",\"license\":\"MIT\"},\"@openzeppelin/contracts-upgradeable/utils/cryptography/ECDSAUpgradeable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (utils/cryptography/ECDSA.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../StringsUpgradeable.sol\\\";\\n\\n/**\\n * @dev Elliptic Curve Digital Signature Algorithm (ECDSA) operations.\\n *\\n * These functions can be used to verify that a message was signed by the holder\\n * of the private keys of a given address.\\n */\\nlibrary ECDSAUpgradeable {\\n enum RecoverError {\\n NoError,\\n InvalidSignature,\\n InvalidSignatureLength,\\n InvalidSignatureS,\\n InvalidSignatureV\\n }\\n\\n function _throwError(RecoverError error) private pure {\\n if (error == RecoverError.NoError) {\\n return; // no error: do nothing\\n } else if (error == RecoverError.InvalidSignature) {\\n revert(\\\"ECDSA: invalid signature\\\");\\n } else if (error == RecoverError.InvalidSignatureLength) {\\n revert(\\\"ECDSA: invalid signature length\\\");\\n } else if (error == RecoverError.InvalidSignatureS) {\\n revert(\\\"ECDSA: invalid signature 's' value\\\");\\n } else if (error == RecoverError.InvalidSignatureV) {\\n revert(\\\"ECDSA: invalid signature 'v' value\\\");\\n }\\n }\\n\\n /**\\n * @dev Returns the address that signed a hashed message (`hash`) with\\n * `signature` or error string. This address can then be used for verification purposes.\\n *\\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\\n * this function rejects them by requiring the `s` value to be in the lower\\n * half order, and the `v` value to be either 27 or 28.\\n *\\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\\n * verification to be secure: it is possible to craft signatures that\\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\\n * this is by receiving a hash of the original message (which may otherwise\\n * be too long), and then calling {toEthSignedMessageHash} on it.\\n *\\n * Documentation for signature generation:\\n * - with https://web3js.readthedocs.io/en/v1.3.4/web3-eth-accounts.html#sign[Web3.js]\\n * - with https://docs.ethers.io/v5/api/signer/#Signer-signMessage[ethers]\\n *\\n * _Available since v4.3._\\n */\\n function tryRecover(bytes32 hash, bytes memory signature) internal pure returns (address, RecoverError) {\\n // Check the signature length\\n // - case 65: r,s,v signature (standard)\\n // - case 64: r,vs signature (cf https://eips.ethereum.org/EIPS/eip-2098) _Available since v4.1._\\n if (signature.length == 65) {\\n bytes32 r;\\n bytes32 s;\\n uint8 v;\\n // ecrecover takes the signature parameters, and the only way to get them\\n // currently is to use assembly.\\n assembly {\\n r := mload(add(signature, 0x20))\\n s := mload(add(signature, 0x40))\\n v := byte(0, mload(add(signature, 0x60)))\\n }\\n return tryRecover(hash, v, r, s);\\n } else if (signature.length == 64) {\\n bytes32 r;\\n bytes32 vs;\\n // ecrecover takes the signature parameters, and the only way to get them\\n // currently is to use assembly.\\n assembly {\\n r := mload(add(signature, 0x20))\\n vs := mload(add(signature, 0x40))\\n }\\n return tryRecover(hash, r, vs);\\n } else {\\n return (address(0), RecoverError.InvalidSignatureLength);\\n }\\n }\\n\\n /**\\n * @dev Returns the address that signed a hashed message (`hash`) with\\n * `signature`. This address can then be used for verification purposes.\\n *\\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\\n * this function rejects them by requiring the `s` value to be in the lower\\n * half order, and the `v` value to be either 27 or 28.\\n *\\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\\n * verification to be secure: it is possible to craft signatures that\\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\\n * this is by receiving a hash of the original message (which may otherwise\\n * be too long), and then calling {toEthSignedMessageHash} on it.\\n */\\n function recover(bytes32 hash, bytes memory signature) internal pure returns (address) {\\n (address recovered, RecoverError error) = tryRecover(hash, signature);\\n _throwError(error);\\n return recovered;\\n }\\n\\n /**\\n * @dev Overload of {ECDSA-tryRecover} that receives the `r` and `vs` short-signature fields separately.\\n *\\n * See https://eips.ethereum.org/EIPS/eip-2098[EIP-2098 short signatures]\\n *\\n * _Available since v4.3._\\n */\\n function tryRecover(\\n bytes32 hash,\\n bytes32 r,\\n bytes32 vs\\n ) internal pure returns (address, RecoverError) {\\n bytes32 s;\\n uint8 v;\\n assembly {\\n s := and(vs, 0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff)\\n v := add(shr(255, vs), 27)\\n }\\n return tryRecover(hash, v, r, s);\\n }\\n\\n /**\\n * @dev Overload of {ECDSA-recover} that receives the `r and `vs` short-signature fields separately.\\n *\\n * _Available since v4.2._\\n */\\n function recover(\\n bytes32 hash,\\n bytes32 r,\\n bytes32 vs\\n ) internal pure returns (address) {\\n (address recovered, RecoverError error) = tryRecover(hash, r, vs);\\n _throwError(error);\\n return recovered;\\n }\\n\\n /**\\n * @dev Overload of {ECDSA-tryRecover} that receives the `v`,\\n * `r` and `s` signature fields separately.\\n *\\n * _Available since v4.3._\\n */\\n function tryRecover(\\n bytes32 hash,\\n uint8 v,\\n bytes32 r,\\n bytes32 s\\n ) internal pure returns (address, RecoverError) {\\n // EIP-2 still allows signature malleability for ecrecover(). Remove this possibility and make the signature\\n // unique. Appendix F in the Ethereum Yellow paper (https://ethereum.github.io/yellowpaper/paper.pdf), defines\\n // the valid range for s in (301): 0 < s < secp256k1n \\u00f7 2 + 1, and for v in (302): v \\u2208 {27, 28}. Most\\n // signatures from current libraries generate a unique signature with an s-value in the lower half order.\\n //\\n // If your library generates malleable signatures, such as s-values in the upper range, calculate a new s-value\\n // with 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141 - s1 and flip v from 27 to 28 or\\n // vice versa. If your library also generates signatures with 0/1 for v instead 27/28, add 27 to v to accept\\n // these malleable signatures as well.\\n if (uint256(s) > 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D576E7357A4501DDFE92F46681B20A0) {\\n return (address(0), RecoverError.InvalidSignatureS);\\n }\\n if (v != 27 && v != 28) {\\n return (address(0), RecoverError.InvalidSignatureV);\\n }\\n\\n // If the signature is valid (and not malleable), return the signer address\\n address signer = ecrecover(hash, v, r, s);\\n if (signer == address(0)) {\\n return (address(0), RecoverError.InvalidSignature);\\n }\\n\\n return (signer, RecoverError.NoError);\\n }\\n\\n /**\\n * @dev Overload of {ECDSA-recover} that receives the `v`,\\n * `r` and `s` signature fields separately.\\n */\\n function recover(\\n bytes32 hash,\\n uint8 v,\\n bytes32 r,\\n bytes32 s\\n ) internal pure returns (address) {\\n (address recovered, RecoverError error) = tryRecover(hash, v, r, s);\\n _throwError(error);\\n return recovered;\\n }\\n\\n /**\\n * @dev Returns an Ethereum Signed Message, created from a `hash`. This\\n * produces hash corresponding to the one signed with the\\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\\n * JSON-RPC method as part of EIP-191.\\n *\\n * See {recover}.\\n */\\n function toEthSignedMessageHash(bytes32 hash) internal pure returns (bytes32) {\\n // 32 is the length in bytes of hash,\\n // enforced by the type signature above\\n return keccak256(abi.encodePacked(\\\"\\\\x19Ethereum Signed Message:\\\\n32\\\", hash));\\n }\\n\\n /**\\n * @dev Returns an Ethereum Signed Message, created from `s`. This\\n * produces hash corresponding to the one signed with the\\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\\n * JSON-RPC method as part of EIP-191.\\n *\\n * See {recover}.\\n */\\n function toEthSignedMessageHash(bytes memory s) internal pure returns (bytes32) {\\n return keccak256(abi.encodePacked(\\\"\\\\x19Ethereum Signed Message:\\\\n\\\", StringsUpgradeable.toString(s.length), s));\\n }\\n\\n /**\\n * @dev Returns an Ethereum Signed Typed Data, created from a\\n * `domainSeparator` and a `structHash`. This produces hash corresponding\\n * to the one signed with the\\n * https://eips.ethereum.org/EIPS/eip-712[`eth_signTypedData`]\\n * JSON-RPC method as part of EIP-712.\\n *\\n * See {recover}.\\n */\\n function toTypedDataHash(bytes32 domainSeparator, bytes32 structHash) internal pure returns (bytes32) {\\n return keccak256(abi.encodePacked(\\\"\\\\x19\\\\x01\\\", domainSeparator, structHash));\\n }\\n}\\n\",\"keccak256\":\"0x1762ac67d230279d7fb183567ce22bbe202054ce08f94224d8794f9d19546d51\",\"license\":\"MIT\"},\"@openzeppelin/contracts-upgradeable/utils/cryptography/draft-EIP712Upgradeable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (utils/cryptography/draft-EIP712.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"./ECDSAUpgradeable.sol\\\";\\nimport \\\"../../proxy/utils/Initializable.sol\\\";\\n\\n/**\\n * @dev https://eips.ethereum.org/EIPS/eip-712[EIP 712] is a standard for hashing and signing of typed structured data.\\n *\\n * The encoding specified in the EIP is very generic, and such a generic implementation in Solidity is not feasible,\\n * thus this contract does not implement the encoding itself. Protocols need to implement the type-specific encoding\\n * they need in their contracts using a combination of `abi.encode` and `keccak256`.\\n *\\n * This contract implements the EIP 712 domain separator ({_domainSeparatorV4}) that is used as part of the encoding\\n * scheme, and the final step of the encoding to obtain the message digest that is then signed via ECDSA\\n * ({_hashTypedDataV4}).\\n *\\n * The implementation of the domain separator was designed to be as efficient as possible while still properly updating\\n * the chain id to protect against replay attacks on an eventual fork of the chain.\\n *\\n * NOTE: This contract implements the version of the encoding known as \\\"v4\\\", as implemented by the JSON RPC method\\n * https://docs.metamask.io/guide/signing-data.html[`eth_signTypedDataV4` in MetaMask].\\n *\\n * _Available since v3.4._\\n */\\nabstract contract EIP712Upgradeable is Initializable {\\n /* solhint-disable var-name-mixedcase */\\n bytes32 private _HASHED_NAME;\\n bytes32 private _HASHED_VERSION;\\n bytes32 private constant _TYPE_HASH = keccak256(\\\"EIP712Domain(string name,string version,uint256 chainId,address verifyingContract)\\\");\\n\\n /* solhint-enable var-name-mixedcase */\\n\\n /**\\n * @dev Initializes the domain separator and parameter caches.\\n *\\n * The meaning of `name` and `version` is specified in\\n * https://eips.ethereum.org/EIPS/eip-712#definition-of-domainseparator[EIP 712]:\\n *\\n * - `name`: the user readable name of the signing domain, i.e. the name of the DApp or the protocol.\\n * - `version`: the current major version of the signing domain.\\n *\\n * NOTE: These parameters cannot be changed except through a xref:learn::upgrading-smart-contracts.adoc[smart\\n * contract upgrade].\\n */\\n function __EIP712_init(string memory name, string memory version) internal onlyInitializing {\\n __EIP712_init_unchained(name, version);\\n }\\n\\n function __EIP712_init_unchained(string memory name, string memory version) internal onlyInitializing {\\n bytes32 hashedName = keccak256(bytes(name));\\n bytes32 hashedVersion = keccak256(bytes(version));\\n _HASHED_NAME = hashedName;\\n _HASHED_VERSION = hashedVersion;\\n }\\n\\n /**\\n * @dev Returns the domain separator for the current chain.\\n */\\n function _domainSeparatorV4() internal view returns (bytes32) {\\n return _buildDomainSeparator(_TYPE_HASH, _EIP712NameHash(), _EIP712VersionHash());\\n }\\n\\n function _buildDomainSeparator(\\n bytes32 typeHash,\\n bytes32 nameHash,\\n bytes32 versionHash\\n ) private view returns (bytes32) {\\n return keccak256(abi.encode(typeHash, nameHash, versionHash, block.chainid, address(this)));\\n }\\n\\n /**\\n * @dev Given an already https://eips.ethereum.org/EIPS/eip-712#definition-of-hashstruct[hashed struct], this\\n * function returns the hash of the fully encoded EIP712 message for this domain.\\n *\\n * This hash can be used together with {ECDSA-recover} to obtain the signer of a message. For example:\\n *\\n * ```solidity\\n * bytes32 digest = _hashTypedDataV4(keccak256(abi.encode(\\n * keccak256(\\\"Mail(address to,string contents)\\\"),\\n * mailTo,\\n * keccak256(bytes(mailContents))\\n * )));\\n * address signer = ECDSA.recover(digest, signature);\\n * ```\\n */\\n function _hashTypedDataV4(bytes32 structHash) internal view virtual returns (bytes32) {\\n return ECDSAUpgradeable.toTypedDataHash(_domainSeparatorV4(), structHash);\\n }\\n\\n /**\\n * @dev The hash of the name parameter for the EIP712 domain.\\n *\\n * NOTE: This function reads from storage by default, but can be redefined to return a constant value if gas costs\\n * are a concern.\\n */\\n function _EIP712NameHash() internal virtual view returns (bytes32) {\\n return _HASHED_NAME;\\n }\\n\\n /**\\n * @dev The hash of the version parameter for the EIP712 domain.\\n *\\n * NOTE: This function reads from storage by default, but can be redefined to return a constant value if gas costs\\n * are a concern.\\n */\\n function _EIP712VersionHash() internal virtual view returns (bytes32) {\\n return _HASHED_VERSION;\\n }\\n uint256[50] private __gap;\\n}\\n\",\"keccak256\":\"0x92e61d8dd5ba90b513769c06da820e0a8f5d93810a9c6d5207308af345815011\",\"license\":\"MIT\"},\"@openzeppelin/contracts/token/ERC20/IERC20.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (token/ERC20/IERC20.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Interface of the ERC20 standard as defined in the EIP.\\n */\\ninterface IERC20 {\\n /**\\n * @dev Returns the amount of tokens in existence.\\n */\\n function totalSupply() external view returns (uint256);\\n\\n /**\\n * @dev Returns the amount of tokens owned by `account`.\\n */\\n function balanceOf(address account) external view returns (uint256);\\n\\n /**\\n * @dev Moves `amount` tokens from the caller's account to `recipient`.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * Emits a {Transfer} event.\\n */\\n function transfer(address recipient, uint256 amount) external returns (bool);\\n\\n /**\\n * @dev Returns the remaining number of tokens that `spender` will be\\n * allowed to spend on behalf of `owner` through {transferFrom}. This is\\n * zero by default.\\n *\\n * This value changes when {approve} or {transferFrom} are called.\\n */\\n function allowance(address owner, address spender) external view returns (uint256);\\n\\n /**\\n * @dev Sets `amount` as the allowance of `spender` over the caller's tokens.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * IMPORTANT: Beware that changing an allowance with this method brings the risk\\n * that someone may use both the old and the new allowance by unfortunate\\n * transaction ordering. One possible solution to mitigate this race\\n * condition is to first reduce the spender's allowance to 0 and set the\\n * desired value afterwards:\\n * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729\\n *\\n * Emits an {Approval} event.\\n */\\n function approve(address spender, uint256 amount) external returns (bool);\\n\\n /**\\n * @dev Moves `amount` tokens from `sender` to `recipient` using the\\n * allowance mechanism. `amount` is then deducted from the caller's\\n * allowance.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * Emits a {Transfer} event.\\n */\\n function transferFrom(\\n address sender,\\n address recipient,\\n uint256 amount\\n ) external returns (bool);\\n\\n /**\\n * @dev Emitted when `value` tokens are moved from one account (`from`) to\\n * another (`to`).\\n *\\n * Note that `value` may be zero.\\n */\\n event Transfer(address indexed from, address indexed to, uint256 value);\\n\\n /**\\n * @dev Emitted when the allowance of a `spender` for an `owner` is set by\\n * a call to {approve}. `value` is the new allowance.\\n */\\n event Approval(address indexed owner, address indexed spender, uint256 value);\\n}\\n\",\"keccak256\":\"0x61437cb513a887a1bbad006e7b1c8b414478427d33de47c5600af3c748f108da\",\"license\":\"MIT\"},\"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (token/ERC20/utils/SafeERC20.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../IERC20.sol\\\";\\nimport \\\"../../../utils/Address.sol\\\";\\n\\n/**\\n * @title SafeERC20\\n * @dev Wrappers around ERC20 operations that throw on failure (when the token\\n * contract returns false). Tokens that return no value (and instead revert or\\n * throw on failure) are also supported, non-reverting calls are assumed to be\\n * successful.\\n * To use this library you can add a `using SafeERC20 for IERC20;` statement to your contract,\\n * which allows you to call the safe operations as `token.safeTransfer(...)`, etc.\\n */\\nlibrary SafeERC20 {\\n using Address for address;\\n\\n function safeTransfer(\\n IERC20 token,\\n address to,\\n uint256 value\\n ) internal {\\n _callOptionalReturn(token, abi.encodeWithSelector(token.transfer.selector, to, value));\\n }\\n\\n function safeTransferFrom(\\n IERC20 token,\\n address from,\\n address to,\\n uint256 value\\n ) internal {\\n _callOptionalReturn(token, abi.encodeWithSelector(token.transferFrom.selector, from, to, value));\\n }\\n\\n /**\\n * @dev Deprecated. This function has issues similar to the ones found in\\n * {IERC20-approve}, and its usage is discouraged.\\n *\\n * Whenever possible, use {safeIncreaseAllowance} and\\n * {safeDecreaseAllowance} instead.\\n */\\n function safeApprove(\\n IERC20 token,\\n address spender,\\n uint256 value\\n ) internal {\\n // safeApprove should only be called when setting an initial allowance,\\n // or when resetting it to zero. To increase and decrease it, use\\n // 'safeIncreaseAllowance' and 'safeDecreaseAllowance'\\n require(\\n (value == 0) || (token.allowance(address(this), spender) == 0),\\n \\\"SafeERC20: approve from non-zero to non-zero allowance\\\"\\n );\\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, value));\\n }\\n\\n function safeIncreaseAllowance(\\n IERC20 token,\\n address spender,\\n uint256 value\\n ) internal {\\n uint256 newAllowance = token.allowance(address(this), spender) + value;\\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));\\n }\\n\\n function safeDecreaseAllowance(\\n IERC20 token,\\n address spender,\\n uint256 value\\n ) internal {\\n unchecked {\\n uint256 oldAllowance = token.allowance(address(this), spender);\\n require(oldAllowance >= value, \\\"SafeERC20: decreased allowance below zero\\\");\\n uint256 newAllowance = oldAllowance - value;\\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));\\n }\\n }\\n\\n /**\\n * @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement\\n * on the return value: the return value is optional (but if data is returned, it must not be false).\\n * @param token The token targeted by the call.\\n * @param data The call data (encoded using abi.encode or one of its variants).\\n */\\n function _callOptionalReturn(IERC20 token, bytes memory data) private {\\n // We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since\\n // we're implementing it ourselves. We use {Address.functionCall} to perform this call, which verifies that\\n // the target address contains contract code and also asserts for success in the low-level call.\\n\\n bytes memory returndata = address(token).functionCall(data, \\\"SafeERC20: low-level call failed\\\");\\n if (returndata.length > 0) {\\n // Return data is optional\\n require(abi.decode(returndata, (bool)), \\\"SafeERC20: ERC20 operation did not succeed\\\");\\n }\\n }\\n}\\n\",\"keccak256\":\"0xc3d946432c0ddbb1f846a0d3985be71299df331b91d06732152117f62f0be2b5\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/Address.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (utils/Address.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Collection of functions related to the address type\\n */\\nlibrary Address {\\n /**\\n * @dev Returns true if `account` is a contract.\\n *\\n * [IMPORTANT]\\n * ====\\n * It is unsafe to assume that an address for which this function returns\\n * false is an externally-owned account (EOA) and not a contract.\\n *\\n * Among others, `isContract` will return false for the following\\n * types of addresses:\\n *\\n * - an externally-owned account\\n * - a contract in construction\\n * - an address where a contract will be created\\n * - an address where a contract lived, but was destroyed\\n * ====\\n */\\n function isContract(address account) internal view returns (bool) {\\n // This method relies on extcodesize, which returns 0 for contracts in\\n // construction, since the code is only stored at the end of the\\n // constructor execution.\\n\\n uint256 size;\\n assembly {\\n size := extcodesize(account)\\n }\\n return size > 0;\\n }\\n\\n /**\\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\\n * `recipient`, forwarding all available gas and reverting on errors.\\n *\\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\\n * imposed by `transfer`, making them unable to receive funds via\\n * `transfer`. {sendValue} removes this limitation.\\n *\\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\\n *\\n * IMPORTANT: because control is transferred to `recipient`, care must be\\n * taken to not create reentrancy vulnerabilities. Consider using\\n * {ReentrancyGuard} or the\\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\\n */\\n function sendValue(address payable recipient, uint256 amount) internal {\\n require(address(this).balance >= amount, \\\"Address: insufficient balance\\\");\\n\\n (bool success, ) = recipient.call{value: amount}(\\\"\\\");\\n require(success, \\\"Address: unable to send value, recipient may have reverted\\\");\\n }\\n\\n /**\\n * @dev Performs a Solidity function call using a low level `call`. A\\n * plain `call` is an unsafe replacement for a function call: use this\\n * function instead.\\n *\\n * If `target` reverts with a revert reason, it is bubbled up by this\\n * function (like regular Solidity function calls).\\n *\\n * Returns the raw returned data. To convert to the expected return value,\\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\\n *\\n * Requirements:\\n *\\n * - `target` must be a contract.\\n * - calling `target` with `data` must not revert.\\n *\\n * _Available since v3.1._\\n */\\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\\n return functionCall(target, data, \\\"Address: low-level call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\\n * `errorMessage` as a fallback revert reason when `target` reverts.\\n *\\n * _Available since v3.1._\\n */\\n function functionCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n return functionCallWithValue(target, data, 0, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but also transferring `value` wei to `target`.\\n *\\n * Requirements:\\n *\\n * - the calling contract must have an ETH balance of at least `value`.\\n * - the called Solidity function must be `payable`.\\n *\\n * _Available since v3.1._\\n */\\n function functionCallWithValue(\\n address target,\\n bytes memory data,\\n uint256 value\\n ) internal returns (bytes memory) {\\n return functionCallWithValue(target, data, value, \\\"Address: low-level call with value failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\\n * with `errorMessage` as a fallback revert reason when `target` reverts.\\n *\\n * _Available since v3.1._\\n */\\n function functionCallWithValue(\\n address target,\\n bytes memory data,\\n uint256 value,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n require(address(this).balance >= value, \\\"Address: insufficient balance for call\\\");\\n require(isContract(target), \\\"Address: call to non-contract\\\");\\n\\n (bool success, bytes memory returndata) = target.call{value: value}(data);\\n return verifyCallResult(success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but performing a static call.\\n *\\n * _Available since v3.3._\\n */\\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\\n return functionStaticCall(target, data, \\\"Address: low-level static call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\\n * but performing a static call.\\n *\\n * _Available since v3.3._\\n */\\n function functionStaticCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal view returns (bytes memory) {\\n require(isContract(target), \\\"Address: static call to non-contract\\\");\\n\\n (bool success, bytes memory returndata) = target.staticcall(data);\\n return verifyCallResult(success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but performing a delegate call.\\n *\\n * _Available since v3.4._\\n */\\n function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {\\n return functionDelegateCall(target, data, \\\"Address: low-level delegate call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\\n * but performing a delegate call.\\n *\\n * _Available since v3.4._\\n */\\n function functionDelegateCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n require(isContract(target), \\\"Address: delegate call to non-contract\\\");\\n\\n (bool success, bytes memory returndata) = target.delegatecall(data);\\n return verifyCallResult(success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the\\n * revert reason using the provided one.\\n *\\n * _Available since v4.3._\\n */\\n function verifyCallResult(\\n bool success,\\n bytes memory returndata,\\n string memory errorMessage\\n ) internal pure returns (bytes memory) {\\n if (success) {\\n return returndata;\\n } else {\\n // Look for revert reason and bubble it up if present\\n if (returndata.length > 0) {\\n // The easiest way to bubble the revert reason is using memory via assembly\\n\\n assembly {\\n let returndata_size := mload(returndata)\\n revert(add(32, returndata), returndata_size)\\n }\\n } else {\\n revert(errorMessage);\\n }\\n }\\n }\\n}\\n\",\"keccak256\":\"0x51b758a8815ecc9596c66c37d56b1d33883a444631a3f916b9fe65cb863ef7c4\",\"license\":\"MIT\"},\"contracts/agToken/AgTokenSideChainMultiBridge.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-3.0\\n\\npragma solidity 0.8.12;\\n\\nimport \\\"./BaseAgTokenSideChain.sol\\\";\\nimport \\\"@openzeppelin/contracts/token/ERC20/IERC20.sol\\\";\\nimport \\\"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\\\";\\n\\n/// @title AgTokenSideChainMultiBridge\\n/// @author Angle Core Team\\n/// @notice Contract for Angle agTokens on other chains than Ethereum mainnet\\n/// @dev This contract supports bridge tokens having a minting right on the stablecoin (also referred to as the canonical\\n/// or the native token)\\n/// @dev References:\\n/// - FRAX implementation: https://polygonscan.com/address/0x45c32fA6DF82ead1e2EF74d17b76547EDdFaFF89#code\\n/// - QiDAO implementation: https://snowtrace.io/address/0x5c49b268c9841AFF1Cc3B0a418ff5c3442eE3F3b#code\\ncontract AgTokenSideChainMultiBridge is BaseAgTokenSideChain {\\n using SafeERC20 for IERC20;\\n\\n /// @notice Base used for fee computation\\n uint256 public constant BASE_PARAMS = 10**9;\\n\\n // =============================== Bridging Data ===============================\\n\\n /// @notice Struct with some data about a specific bridge token\\n struct BridgeDetails {\\n // Limit on the balance of bridge token held by the contract: it is designed\\n // to reduce the exposure of the system to hacks\\n uint256 limit;\\n // Limit on the hourly volume of token minted through this bridge\\n // Technically the limit over a rolling hour is hourlyLimit x2 as hourly limit\\n // is enforced only between x:00 and x+1:00\\n uint256 hourlyLimit;\\n // Fee taken for swapping in and out the token\\n uint64 fee;\\n // Whether the associated token is allowed or not\\n bool allowed;\\n // Whether swapping in and out from the associated token is paused or not\\n bool paused;\\n }\\n\\n /// @notice Maps a bridge token to data\\n mapping(address => BridgeDetails) public bridges;\\n /// @notice List of all bridge tokens\\n address[] public bridgeTokensList;\\n /// @notice Maps a bridge token to the associated hourly volume\\n mapping(address => mapping(uint256 => uint256)) public usage;\\n /// @notice Maps an address to whether it is exempt of fees for when it comes to swapping in and out\\n mapping(address => uint256) public isFeeExempt;\\n /// @notice Limit to the amount of tokens that can be sent from that chain to another chain\\n uint256 public chainTotalHourlyLimit;\\n /// @notice Usage per hour on that chain. Maps an hourly timestamp to the total volume swapped out on the chain\\n mapping(uint256 => uint256) public chainTotalUsage;\\n\\n // ================================== Events ===================================\\n\\n event BridgeTokenAdded(address indexed bridgeToken, uint256 limit, uint256 hourlyLimit, uint64 fee, bool paused);\\n event BridgeTokenToggled(address indexed bridgeToken, bool toggleStatus);\\n event BridgeTokenRemoved(address indexed bridgeToken);\\n event BridgeTokenFeeUpdated(address indexed bridgeToken, uint64 fee);\\n event BridgeTokenLimitUpdated(address indexed bridgeToken, uint256 limit);\\n event BridgeTokenHourlyLimitUpdated(address indexed bridgeToken, uint256 hourlyLimit);\\n event HourlyLimitUpdated(uint256 hourlyLimit);\\n event Recovered(address indexed token, address indexed to, uint256 amount);\\n event FeeToggled(address indexed theAddress, uint256 toggleStatus);\\n\\n // =============================== Errors ================================\\n\\n error AssetStillControlledInReserves();\\n error HourlyLimitExceeded();\\n error InvalidToken();\\n error NotGovernor();\\n error NotGovernorOrGuardian();\\n error TooBigAmount();\\n error TooHighParameterValue();\\n error ZeroAddress();\\n\\n // ============================= Constructor ===================================\\n\\n /// @notice Initializes the `AgToken` contract\\n /// @param name_ Name of the token\\n /// @param symbol_ Symbol of the token\\n /// @param _treasury Reference to the `Treasury` contract associated to this agToken\\n /// @dev By default, agTokens are ERC-20 tokens with 18 decimals\\n function initialize(\\n string memory name_,\\n string memory symbol_,\\n address _treasury\\n ) external {\\n _initialize(name_, symbol_, _treasury);\\n }\\n\\n // =============================== Modifiers ===================================\\n\\n /// @notice Checks whether the `msg.sender` has the governor role or not\\n modifier onlyGovernor() {\\n if (!ITreasury(treasury).isGovernor(msg.sender)) revert NotGovernor();\\n _;\\n }\\n\\n /// @notice Checks whether the `msg.sender` has the governor role or the guardian role\\n modifier onlyGovernorOrGuardian() {\\n if (!ITreasury(treasury).isGovernorOrGuardian(msg.sender)) revert NotGovernorOrGuardian();\\n _;\\n }\\n\\n // ==================== External Permissionless Functions ======================\\n\\n /// @notice Returns the list of all supported bridge tokens\\n /// @dev Helpful for UIs\\n function allBridgeTokens() external view returns (address[] memory) {\\n return bridgeTokensList;\\n }\\n\\n /// @notice Returns the current volume for a bridge, for the current hour\\n /// @param bridgeToken Bridge used to mint\\n /// @dev Helpful for UIs\\n function currentUsage(address bridgeToken) external view returns (uint256) {\\n return usage[bridgeToken][block.timestamp / 3600];\\n }\\n\\n /// @notice Returns the current total volume on the chain for the current hour\\n /// @dev Helpful for UIs\\n function currentTotalUsage() external view returns (uint256) {\\n return chainTotalUsage[block.timestamp / 3600];\\n }\\n\\n /// @notice Mints the canonical token from a supported bridge token\\n /// @param bridgeToken Bridge token to use to mint\\n /// @param amount Amount of bridge tokens to send\\n /// @param to Address to which the stablecoin should be sent\\n /// @return Amount of the canonical stablecoin actually minted\\n /// @dev Some fees may be taken by the protocol depending on the token used and on the address calling\\n function swapIn(\\n address bridgeToken,\\n uint256 amount,\\n address to\\n ) external returns (uint256) {\\n BridgeDetails memory bridgeDetails = bridges[bridgeToken];\\n if (!bridgeDetails.allowed || bridgeDetails.paused) revert InvalidToken();\\n uint256 balance = IERC20(bridgeToken).balanceOf(address(this));\\n if (balance + amount > bridgeDetails.limit) {\\n // In case someone maliciously sends tokens to this contract\\n // Or the limit changes\\n if (bridgeDetails.limit > balance) amount = bridgeDetails.limit - balance;\\n else {\\n amount = 0;\\n }\\n }\\n\\n // Checking requirement on the hourly volume\\n uint256 hour = block.timestamp / 3600;\\n uint256 hourlyUsage = usage[bridgeToken][hour] + amount;\\n if (hourlyUsage > bridgeDetails.hourlyLimit) {\\n // Edge case when the hourly limit changes\\n if (bridgeDetails.hourlyLimit > usage[bridgeToken][hour])\\n amount = bridgeDetails.hourlyLimit - usage[bridgeToken][hour];\\n else {\\n amount = 0;\\n }\\n }\\n usage[bridgeToken][hour] = usage[bridgeToken][hour] + amount;\\n\\n IERC20(bridgeToken).safeTransferFrom(msg.sender, address(this), amount);\\n uint256 canonicalOut = amount;\\n // Computing fees\\n if (isFeeExempt[msg.sender] == 0) {\\n canonicalOut -= (canonicalOut * bridgeDetails.fee) / BASE_PARAMS;\\n }\\n _mint(to, canonicalOut);\\n return canonicalOut;\\n }\\n\\n /// @notice Burns the canonical token in exchange for a bridge token\\n /// @param bridgeToken Bridge token required\\n /// @param amount Amount of canonical tokens to burn\\n /// @param to Address to which the bridge token should be sent\\n /// @return Amount of bridge tokens actually sent back\\n /// @dev Some fees may be taken by the protocol depending on the token used and on the address calling\\n function swapOut(\\n address bridgeToken,\\n uint256 amount,\\n address to\\n ) external returns (uint256) {\\n BridgeDetails memory bridgeDetails = bridges[bridgeToken];\\n if (!bridgeDetails.allowed || bridgeDetails.paused) revert InvalidToken();\\n\\n uint256 hour = block.timestamp / 3600;\\n uint256 hourlyUsage = chainTotalUsage[hour] + amount;\\n // If the amount being swapped out exceeds the limit, we revert\\n // We don't want to change the amount being swapped out.\\n // The user can decide to send another tx with the correct amount to reach the limit\\n if (hourlyUsage > chainTotalHourlyLimit) revert HourlyLimitExceeded();\\n chainTotalUsage[hour] = hourlyUsage;\\n\\n _burn(msg.sender, amount);\\n uint256 bridgeOut = amount;\\n if (isFeeExempt[msg.sender] == 0) {\\n bridgeOut -= (bridgeOut * bridgeDetails.fee) / BASE_PARAMS;\\n }\\n IERC20(bridgeToken).safeTransfer(to, bridgeOut);\\n return bridgeOut;\\n }\\n\\n // ======================= Governance Functions ================================\\n\\n /// @notice Adds support for a bridge token\\n /// @param bridgeToken Bridge token to add: it should be a version of the stablecoin from another bridge\\n /// @param limit Limit on the balance of bridge token this contract could hold\\n /// @param hourlyLimit Limit on the hourly volume for this bridge\\n /// @param paused Whether swapping for this token should be paused or not\\n /// @param fee Fee taken upon swapping for or against this token\\n function addBridgeToken(\\n address bridgeToken,\\n uint256 limit,\\n uint256 hourlyLimit,\\n uint64 fee,\\n bool paused\\n ) external onlyGovernor {\\n if (bridges[bridgeToken].allowed || bridgeToken == address(0)) revert InvalidToken();\\n if (fee > BASE_PARAMS) revert TooHighParameterValue();\\n BridgeDetails memory _bridge;\\n _bridge.limit = limit;\\n _bridge.hourlyLimit = hourlyLimit;\\n _bridge.paused = paused;\\n _bridge.fee = fee;\\n _bridge.allowed = true;\\n bridges[bridgeToken] = _bridge;\\n bridgeTokensList.push(bridgeToken);\\n emit BridgeTokenAdded(bridgeToken, limit, hourlyLimit, fee, paused);\\n }\\n\\n /// @notice Removes support for a token\\n /// @param bridgeToken Address of the bridge token to remove support for\\n function removeBridgeToken(address bridgeToken) external onlyGovernor {\\n if (IERC20(bridgeToken).balanceOf(address(this)) != 0) revert AssetStillControlledInReserves();\\n delete bridges[bridgeToken];\\n // Deletion from `bridgeTokensList` loop\\n uint256 bridgeTokensListLength = bridgeTokensList.length;\\n for (uint256 i = 0; i < bridgeTokensListLength - 1; i++) {\\n if (bridgeTokensList[i] == bridgeToken) {\\n // Replace the `bridgeToken` to remove with the last of the list\\n bridgeTokensList[i] = bridgeTokensList[bridgeTokensListLength - 1];\\n break;\\n }\\n }\\n // Remove last element in array\\n bridgeTokensList.pop();\\n emit BridgeTokenRemoved(bridgeToken);\\n }\\n\\n /// @notice Recovers any ERC20 token\\n /// @dev Can be used to withdraw bridge tokens for them to be de-bridged on mainnet\\n function recoverERC20(\\n address tokenAddress,\\n address to,\\n uint256 amountToRecover\\n ) external onlyGovernor {\\n IERC20(tokenAddress).safeTransfer(to, amountToRecover);\\n emit Recovered(tokenAddress, to, amountToRecover);\\n }\\n\\n /// @notice Updates the `limit` amount for `bridgeToken`\\n function setLimit(address bridgeToken, uint256 limit) external onlyGovernorOrGuardian {\\n if (!bridges[bridgeToken].allowed) revert InvalidToken();\\n bridges[bridgeToken].limit = limit;\\n emit BridgeTokenLimitUpdated(bridgeToken, limit);\\n }\\n\\n /// @notice Updates the `hourlyLimit` amount for `bridgeToken`\\n function setHourlyLimit(address bridgeToken, uint256 hourlyLimit) external onlyGovernorOrGuardian {\\n if (!bridges[bridgeToken].allowed) revert InvalidToken();\\n bridges[bridgeToken].hourlyLimit = hourlyLimit;\\n emit BridgeTokenHourlyLimitUpdated(bridgeToken, hourlyLimit);\\n }\\n\\n /// @notice Updates the `chainTotalHourlyLimit` amount\\n function setChainTotalHourlyLimit(uint256 hourlyLimit) external onlyGovernorOrGuardian {\\n chainTotalHourlyLimit = hourlyLimit;\\n emit HourlyLimitUpdated(hourlyLimit);\\n }\\n\\n /// @notice Updates the `fee` value for `bridgeToken`\\n function setSwapFee(address bridgeToken, uint64 fee) external onlyGovernorOrGuardian {\\n if (!bridges[bridgeToken].allowed) revert InvalidToken();\\n if (fee > BASE_PARAMS) revert TooHighParameterValue();\\n bridges[bridgeToken].fee = fee;\\n emit BridgeTokenFeeUpdated(bridgeToken, fee);\\n }\\n\\n /// @notice Pauses or unpauses swapping in and out for a token\\n function toggleBridge(address bridgeToken) external onlyGovernorOrGuardian {\\n if (!bridges[bridgeToken].allowed) revert InvalidToken();\\n bool pausedStatus = bridges[bridgeToken].paused;\\n bridges[bridgeToken].paused = !pausedStatus;\\n emit BridgeTokenToggled(bridgeToken, !pausedStatus);\\n }\\n\\n /// @notice Toggles fees for the address `theAddress`\\n function toggleFeesForAddress(address theAddress) external onlyGovernorOrGuardian {\\n uint256 feeExemptStatus = 1 - isFeeExempt[theAddress];\\n isFeeExempt[theAddress] = feeExemptStatus;\\n emit FeeToggled(theAddress, feeExemptStatus);\\n }\\n}\\n\",\"keccak256\":\"0xf2f2d77a9504fa20ef62faae227c548cc32d8f796ef427864ec79580617d0cb3\",\"license\":\"GPL-3.0\"},\"contracts/agToken/BaseAgTokenSideChain.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-3.0\\n\\npragma solidity 0.8.12;\\n\\nimport \\\"../interfaces/IAgToken.sol\\\";\\nimport \\\"../interfaces/ITreasury.sol\\\";\\nimport \\\"@openzeppelin/contracts-upgradeable/token/ERC20/extensions/draft-ERC20PermitUpgradeable.sol\\\";\\n\\n/// @title BaseAgTokenSideChain\\n/// @author Angle Core Team\\n/// @notice Base Contract for Angle agTokens on other chains than Ethereum mainnet\\n/// @dev This type of contract can be used to create and handle the stablecoins of Angle protocol in different chains than Ethereum\\ncontract BaseAgTokenSideChain is IAgToken, ERC20PermitUpgradeable {\\n // ======================= Parameters and Variables ============================\\n\\n /// @inheritdoc IAgToken\\n mapping(address => bool) public isMinter;\\n /// @notice Reference to the treasury contract which can grant minting rights\\n address public treasury;\\n\\n // ================================== Events ===================================\\n\\n event TreasuryUpdated(address indexed _treasury);\\n event MinterToggled(address indexed minter);\\n\\n // =============================== Errors ================================\\n\\n error BurnAmountExceedsAllowance();\\n error InvalidSender();\\n error InvalidTreasury();\\n error NotMinter();\\n error NotTreasury();\\n\\n // ============================= Constructor ===================================\\n\\n /// @notice Initializes the contract\\n /// @param name_ Name of the token\\n /// @param symbol_ Symbol of the token\\n /// @param _treasury Reference to the `Treasury` contract associated to this agToken implementation\\n /// @dev By default, agTokens are ERC-20 tokens with 18 decimals\\n function _initialize(\\n string memory name_,\\n string memory symbol_,\\n address _treasury\\n ) internal initializer {\\n __ERC20Permit_init(name_);\\n __ERC20_init(name_, symbol_);\\n if (address(ITreasury(_treasury).stablecoin()) != address(this)) revert InvalidTreasury();\\n treasury = _treasury;\\n emit TreasuryUpdated(address(_treasury));\\n }\\n\\n /// @custom:oz-upgrades-unsafe-allow constructor\\n constructor() initializer {}\\n\\n // =============================== Modifiers ===================================\\n\\n /// @notice Checks to see if it is the `Treasury` calling this contract\\n /// @dev There is no Access Control here, because it can be handled cheaply through this modifier\\n modifier onlyTreasury() {\\n if (msg.sender != address(treasury)) revert NotTreasury();\\n _;\\n }\\n\\n /// @notice Checks whether the sender has the minting right\\n modifier onlyMinter() {\\n if (!isMinter[msg.sender]) revert NotMinter();\\n _;\\n }\\n\\n // =========================== External Function ===============================\\n\\n /// @notice Allows anyone to burn agToken without redeeming collateral back\\n /// @param amount Amount of stablecoins to burn\\n /// @dev This function can typically be called if there is a settlement mechanism to burn stablecoins\\n function burnStablecoin(uint256 amount) external {\\n _burn(msg.sender, amount);\\n }\\n\\n // ======================= Minter Role Only Functions ==========================\\n\\n /// @inheritdoc IAgToken\\n function burnSelf(uint256 amount, address burner) external onlyMinter {\\n _burn(burner, amount);\\n }\\n\\n /// @inheritdoc IAgToken\\n function burnFrom(\\n uint256 amount,\\n address burner,\\n address sender\\n ) external onlyMinter {\\n _burnFromNoRedeem(amount, burner, sender);\\n }\\n\\n /// @inheritdoc IAgToken\\n function mint(address account, uint256 amount) external onlyMinter {\\n _mint(account, amount);\\n }\\n\\n // ======================= Treasury Only Functions =============================\\n\\n /// @inheritdoc IAgToken\\n function addMinter(address minter) external onlyTreasury {\\n isMinter[minter] = true;\\n emit MinterToggled(minter);\\n }\\n\\n /// @inheritdoc IAgToken\\n function removeMinter(address minter) external {\\n if (msg.sender != address(treasury) && msg.sender != minter) revert InvalidSender();\\n isMinter[minter] = false;\\n emit MinterToggled(minter);\\n }\\n\\n /// @inheritdoc IAgToken\\n function setTreasury(address _treasury) external onlyTreasury {\\n treasury = _treasury;\\n emit TreasuryUpdated(_treasury);\\n }\\n\\n // ============================ Internal Function ==============================\\n\\n /// @notice Internal version of the function `burnFromNoRedeem`\\n /// @param amount Amount to burn\\n /// @dev It is at the level of this function that allowance checks are performed\\n function _burnFromNoRedeem(\\n uint256 amount,\\n address burner,\\n address sender\\n ) internal {\\n if (burner != sender) {\\n uint256 currentAllowance = allowance(burner, sender);\\n if (currentAllowance < amount) revert BurnAmountExceedsAllowance();\\n _approve(burner, sender, currentAllowance - amount);\\n }\\n _burn(burner, amount);\\n }\\n}\\n\",\"keccak256\":\"0xf54ef7218eba0e71f2b57da57956646f0227356fc18a55c8984f6c6a8f592077\",\"license\":\"GPL-3.0\"},\"contracts/interfaces/IAgToken.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-3.0\\n\\npragma solidity 0.8.12;\\n\\nimport \\\"@openzeppelin/contracts-upgradeable/token/ERC20/IERC20Upgradeable.sol\\\";\\n\\n/// @title IAgToken\\n/// @author Angle Core Team\\n/// @notice Interface for the stablecoins `AgToken` contracts\\n/// @dev This interface only contains functions of the `AgToken` contract which are called by other contracts\\n/// of this module or of the first module of the Angle Protocol\\ninterface IAgToken is IERC20Upgradeable {\\n // ======================= Minter Role Only Functions ===========================\\n\\n /// @notice Lets the `StableMaster` contract or another whitelisted contract mint agTokens\\n /// @param account Address to mint to\\n /// @param amount Amount to mint\\n /// @dev The contracts allowed to issue agTokens are the `StableMaster` contract, `VaultManager` contracts\\n /// associated to this stablecoin as well as the flash loan module (if activated) and potentially contracts\\n /// whitelisted by governance\\n function mint(address account, uint256 amount) external;\\n\\n /// @notice Burns `amount` tokens from a `burner` address after being asked to by `sender`\\n /// @param amount Amount of tokens to burn\\n /// @param burner Address to burn from\\n /// @param sender Address which requested the burn from `burner`\\n /// @dev This method is to be called by a contract with the minter right after being requested\\n /// to do so by a `sender` address willing to burn tokens from another `burner` address\\n /// @dev The method checks the allowance between the `sender` and the `burner`\\n function burnFrom(\\n uint256 amount,\\n address burner,\\n address sender\\n ) external;\\n\\n /// @notice Burns `amount` tokens from a `burner` address\\n /// @param amount Amount of tokens to burn\\n /// @param burner Address to burn from\\n /// @dev This method is to be called by a contract with a minter right on the AgToken after being\\n /// requested to do so by an address willing to burn tokens from its address\\n function burnSelf(uint256 amount, address burner) external;\\n\\n // ========================= Treasury Only Functions ===========================\\n\\n /// @notice Adds a minter in the contract\\n /// @param minter Minter address to add\\n /// @dev Zero address checks are performed directly in the `Treasury` contract\\n function addMinter(address minter) external;\\n\\n /// @notice Removes a minter from the contract\\n /// @param minter Minter address to remove\\n /// @dev This function can also be called by a minter wishing to revoke itself\\n function removeMinter(address minter) external;\\n\\n /// @notice Sets a new treasury contract\\n /// @param _treasury New treasury address\\n function setTreasury(address _treasury) external;\\n\\n // ========================= External functions ================================\\n\\n /// @notice Checks whether an address has the right to mint agTokens\\n /// @param minter Address for which the minting right should be checked\\n /// @return Whether the address has the right to mint agTokens or not\\n function isMinter(address minter) external view returns (bool);\\n}\\n\",\"keccak256\":\"0xcd50d86128e457543483981ea6127cb8dac03584b919614352aa89d7e991405c\",\"license\":\"GPL-3.0\"},\"contracts/interfaces/ICoreBorrow.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-3.0\\n\\npragma solidity 0.8.12;\\n\\n/// @title ICoreBorrow\\n/// @author Angle Core Team\\n/// @notice Interface for the `CoreBorrow` contract\\n/// @dev This interface only contains functions of the `CoreBorrow` contract which are called by other contracts\\n/// of this module\\ninterface ICoreBorrow {\\n /// @notice Checks if an address corresponds to a treasury of a stablecoin with a flash loan\\n /// module initialized on it\\n /// @param treasury Address to check\\n /// @return Whether the address has the `FLASHLOANER_TREASURY_ROLE` or not\\n function isFlashLoanerTreasury(address treasury) external view returns (bool);\\n\\n /// @notice Checks whether an address is governor of the Angle Protocol or not\\n /// @param admin Address to check\\n /// @return Whether the address has the `GOVERNOR_ROLE` or not\\n function isGovernor(address admin) external view returns (bool);\\n\\n /// @notice Checks whether an address is governor or a guardian of the Angle Protocol or not\\n /// @param admin Address to check\\n /// @return Whether the address has the `GUARDIAN_ROLE` or not\\n /// @dev Governance should make sure when adding a governor to also give this governor the guardian\\n /// role by calling the `addGovernor` function\\n function isGovernorOrGuardian(address admin) external view returns (bool);\\n}\\n\",\"keccak256\":\"0x25b65b3f506ca91745a444502a36f0556585d82d9d60f4bd32fbcaabc12840d4\",\"license\":\"GPL-3.0\"},\"contracts/interfaces/IFlashAngle.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-3.0\\n\\npragma solidity 0.8.12;\\n\\nimport \\\"./IAgToken.sol\\\";\\nimport \\\"./ICoreBorrow.sol\\\";\\n\\n/// @title IFlashAngle\\n/// @author Angle Core Team\\n/// @notice Interface for the `FlashAngle` contract\\n/// @dev This interface only contains functions of the contract which are called by other contracts\\n/// of this module\\ninterface IFlashAngle {\\n /// @notice Reference to the `CoreBorrow` contract managing the FlashLoan module\\n function core() external view returns (ICoreBorrow);\\n\\n /// @notice Sends the fees taken from flash loans to the treasury contract associated to the stablecoin\\n /// @param stablecoin Stablecoin from which profits should be sent\\n /// @return balance Amount of profits sent\\n /// @dev This function can only be called by the treasury contract\\n function accrueInterestToTreasury(IAgToken stablecoin) external returns (uint256 balance);\\n\\n /// @notice Adds support for a stablecoin\\n /// @param _treasury Treasury associated to the stablecoin to add support for\\n /// @dev This function can only be called by the `CoreBorrow` contract\\n function addStablecoinSupport(address _treasury) external;\\n\\n /// @notice Removes support for a stablecoin\\n /// @param _treasury Treasury associated to the stablecoin to remove support for\\n /// @dev This function can only be called by the `CoreBorrow` contract\\n function removeStablecoinSupport(address _treasury) external;\\n\\n /// @notice Sets a new core contract\\n /// @param _core Core contract address to set\\n /// @dev This function can only be called by the `CoreBorrow` contract\\n function setCore(address _core) external;\\n}\\n\",\"keccak256\":\"0xc17654e512897efe41e3f1173c07dd4676e8c699a72b859d14b473d1e8300e45\",\"license\":\"GPL-3.0\"},\"contracts/interfaces/ITreasury.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-3.0\\n\\npragma solidity 0.8.12;\\n\\nimport \\\"./IAgToken.sol\\\";\\nimport \\\"./ICoreBorrow.sol\\\";\\nimport \\\"./IFlashAngle.sol\\\";\\n\\n/// @title ITreasury\\n/// @author Angle Core Team\\n/// @notice Interface for the `Treasury` contract\\n/// @dev This interface only contains functions of the `Treasury` which are called by other contracts\\n/// of this module\\ninterface ITreasury {\\n /// @notice Stablecoin handled by this `treasury` contract\\n function stablecoin() external view returns (IAgToken);\\n\\n /// @notice Checks whether a given address has the governor role\\n /// @param admin Address to check\\n /// @return Whether the address has the governor role\\n /// @dev Access control is only kept in the `CoreBorrow` contract\\n function isGovernor(address admin) external view returns (bool);\\n\\n /// @notice Checks whether a given address has the guardian or the governor role\\n /// @param admin Address to check\\n /// @return Whether the address has the guardian or the governor role\\n /// @dev Access control is only kept in the `CoreBorrow` contract which means that this function\\n /// queries the `CoreBorrow` contract\\n function isGovernorOrGuardian(address admin) external view returns (bool);\\n\\n /// @notice Checks whether a given address has well been initialized in this contract\\n /// as a `VaultManager``\\n /// @param _vaultManager Address to check\\n /// @return Whether the address has been initialized or not\\n function isVaultManager(address _vaultManager) external view returns (bool);\\n\\n /// @notice Sets a new flash loan module for this stablecoin\\n /// @param _flashLoanModule Reference to the new flash loan module\\n /// @dev This function removes the minting right to the old flash loan module and grants\\n /// it to the new module\\n function setFlashLoanModule(address _flashLoanModule) external;\\n}\\n\",\"keccak256\":\"0xced9b7256fcbedc75682037e11ce51fe9116e5604794b8545e00dea0607629cc\",\"license\":\"GPL-3.0\"}},\"version\":1}", - "bytecode": "0x60806040523480156200001157600080fd5b50600054610100900460ff166200002f5760005460ff161562000039565b62000039620000de565b620000a15760405162461bcd60e51b815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201526d191e481a5b9a5d1a585b1a5e995960921b606482015260840160405180910390fd5b600054610100900460ff16158015620000c4576000805461ffff19166101011790555b8015620000d7576000805461ff00191690555b5062000102565b6000620000f630620000fc60201b620027c81760201c565b15905090565b3b151590565b61479b80620001126000396000f3fe608060405234801561001057600080fd5b50600436106102ff5760003560e01c806361d027b31161019c5780639f48118f116100ee578063ced67f0c11610097578063dd62ed3e11610071578063dd62ed3e14610724578063e3e286551461076a578063f0f442601461077d57600080fd5b8063ced67f0c1461066b578063d44ad63f146106fe578063d505accf1461071157600080fd5b8063aa271e1a116100c8578063aa271e1a14610620578063ba330bd714610643578063cd4839ca1461065657600080fd5b80639f48118f146105ef578063a457c2d7146105fa578063a9059cbb1461060d57600080fd5b80637ecebe001161015057806395d89b411161012a57806395d89b41146105c1578063983b2d56146105c95780639e4e0dae146105dc57600080fd5b80637ecebe00146105705780638933fb791461058357806390218cff146105ae57600080fd5b80637334d020116101815780637334d020146105425780637d4c9c2d146105555780637d74e25f1461056857600080fd5b806361d027b3146104c757806370a082311461050c57600080fd5b80633092afd511610255578063395093511161020957806340c10f19116101e357806340c10f19146104815780634dc32fcc146104945780635bfbec96146104a757600080fd5b8063395093511461043b5780633a55f89d1461044e5780633f4218e01461046157600080fd5b8063350ebe041161023a578063350ebe041461040d5780633644e5151461042057806336db43b51461042857600080fd5b80633092afd5146103eb578063313ce567146103fe57600080fd5b8063151dd755116102b757806323b872dd1161029157806323b872dd146103b25780632b471d8e146103c55780632e403e14146103d857600080fd5b8063151dd7551461038057806318160ddd146103a15780632342fb0e146103a957600080fd5b80630919a951116102e85780630919a95114610337578063095ea7b31461034a5780631171bda91461036d57600080fd5b806306fdde0314610304578063077f224a14610322575b600080fd5b61030c610790565b604051610319919061404a565b60405180910390f35b610335610330366004614197565b610822565b005b61033561034536600461420f565b610832565b61035d61035836600461422c565b610995565b6040519015158152602001610319565b61033561037b366004614258565b6109ab565b61039361038e366004614299565b610b00565b604051908152602001610319565b603554610393565b61039360d25481565b61035d6103c0366004614258565b610e51565b6103356103d33660046142d0565b610f3c565b6103356103e636600461420f565b610f93565b6103356103f936600461420f565b611345565b60405160128152602001610319565b61033561041b366004614300565b61142e565b610393611482565b61033561043636600461422c565b611491565b61035d61044936600461422c565b611621565b61033561045c366004614337565b61166a565b61039361046f36600461420f565b60d16020526000908152604090205481565b61033561048f36600461422c565b61176d565b6103936104a236600461420f565b6117c0565b6103936104b5366004614337565b60d36020526000908152604090205481565b60cd546104e79073ffffffffffffffffffffffffffffffffffffffff1681565b60405173ffffffffffffffffffffffffffffffffffffffff9091168152602001610319565b61039361051a36600461420f565b73ffffffffffffffffffffffffffffffffffffffff1660009081526033602052604090205490565b61033561055036600461422c565b611808565b61033561056336600461437b565b61199b565b610393611d03565b61039361057e36600461420f565b611d28565b61039361059136600461422c565b60d060209081526000928352604080842090915290825290205481565b6103356105bc366004614337565b611d55565b61030c611d62565b6103356105d736600461420f565b611d71565b6103356105ea3660046143d8565b611e39565b610393633b9aca0081565b61035d61060836600461422c565b612045565b61035d61061b36600461422c565b61211d565b61035d61062e36600461420f565b60cc6020526000908152604090205460ff1681565b6104e7610651366004614337565b61212a565b61065e612161565b604051610319919061440d565b6106c561067936600461420f565b60ce6020526000908152604090208054600182015460029092015490919067ffffffffffffffff81169060ff680100000000000000008204811691690100000000000000000090041685565b60408051958652602086019490945267ffffffffffffffff9092169284019290925290151560608301521515608082015260a001610319565b61039361070c366004614299565b6121cf565b61033561071f366004614467565b612393565b6103936107323660046144de565b73ffffffffffffffffffffffffffffffffffffffff918216600090815260346020908152604080832093909416825291909152205490565b61033561077836600461420f565b612534565b61033561078b36600461420f565b612708565b60606036805461079f9061450c565b80601f01602080910402602001604051908101604052809291908181526020018280546107cb9061450c565b80156108185780601f106107ed57610100808354040283529160200191610818565b820191906000526020600020905b8154815290600101906020018083116107fb57829003601f168201915b5050505050905090565b61082d8383836127ce565b505050565b60cd546040517f521d4de900000000000000000000000000000000000000000000000000000000815233600482015273ffffffffffffffffffffffffffffffffffffffff9091169063521d4de990602401602060405180830381865afa1580156108a0573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906108c4919061455a565b6108fa576040517f99e120bc00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff8116600090815260d1602052604081205461092b9060016145a6565b73ffffffffffffffffffffffffffffffffffffffff8316600081815260d160205260409081902083905551919250907f979ef83e7e7a87cb48064e296dd7e997870d50f43acf8d7ad221313526c8ca0f906109899084815260200190565b60405180910390a25050565b60006109a2338484612a3f565b50600192915050565b60cd546040517fe43581b800000000000000000000000000000000000000000000000000000000815233600482015273ffffffffffffffffffffffffffffffffffffffff9091169063e43581b890602401602060405180830381865afa158015610a19573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610a3d919061455a565b610a73576040517fee3675d400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b610a9473ffffffffffffffffffffffffffffffffffffffff84168383612bea565b8173ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff167ffff3b3844276f57024e0b42afec1a37f75db36511e43819a4f2a63ab7862b64883604051610af391815260200190565b60405180910390a3505050565b73ffffffffffffffffffffffffffffffffffffffff8316600090815260ce60209081526040808320815160a081018352815481526001820154938101939093526002015467ffffffffffffffff81169183019190915260ff680100000000000000008204811615801560608501526901000000000000000000909204161515608083015280610b90575080608001515b15610bc7576040517fc1ab6dc100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015260009073ffffffffffffffffffffffffffffffffffffffff8716906370a0823190602401602060405180830381865afa158015610c34573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610c5891906145bd565b8251909150610c6786836145d6565b1115610c8f578151811015610c8a578151610c839082906145a6565b9450610c8f565b600094505b6000610c9d610e10426145ee565b73ffffffffffffffffffffffffffffffffffffffff8816600090815260d06020908152604080832084845290915281205491925090610cdd9088906145d6565b90508360200151811115610d715773ffffffffffffffffffffffffffffffffffffffff8816600090815260d060209081526040808320858452825290912054908501511115610d6c5773ffffffffffffffffffffffffffffffffffffffff8816600090815260d06020908152604080832085845282529091205490850151610d6591906145a6565b9650610d71565b600096505b73ffffffffffffffffffffffffffffffffffffffff8816600090815260d060209081526040808320858452909152902054610dad9088906145d6565b73ffffffffffffffffffffffffffffffffffffffff8916600081815260d060209081526040808320878452909152902091909155610ded9033308a612cbe565b33600090815260d160205260409020548790610e3957633b9aca00856040015167ffffffffffffffff1682610e229190614629565b610e2c91906145ee565b610e3690826145a6565b90505b610e438782612d1c565b9450505050505b9392505050565b6000610e5e848484612e3c565b73ffffffffffffffffffffffffffffffffffffffff8416600090815260346020908152604080832033845290915290205482811015610f24576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602860248201527f45524332303a207472616e7366657220616d6f756e742065786365656473206160448201527f6c6c6f77616e636500000000000000000000000000000000000000000000000060648201526084015b60405180910390fd5b610f318533858403612a3f565b506001949350505050565b33600090815260cc602052604090205460ff16610f85576040517ff8d2906c00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b610f8f81836130ef565b5050565b60cd546040517fe43581b800000000000000000000000000000000000000000000000000000000815233600482015273ffffffffffffffffffffffffffffffffffffffff9091169063e43581b890602401602060405180830381865afa158015611001573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611025919061455a565b61105b576040517fee3675d400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015273ffffffffffffffffffffffffffffffffffffffff8216906370a0823190602401602060405180830381865afa1580156110c5573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906110e991906145bd565b15611120576040517f2ef630ec00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff8116600090815260ce602052604081208181556001810182905560020180547fffffffffffffffffffffffffffffffffffffffffffff0000000000000000000016905560cf54905b6111886001836145a6565b811015611296578273ffffffffffffffffffffffffffffffffffffffff1660cf82815481106111b9576111b9614666565b60009182526020909120015473ffffffffffffffffffffffffffffffffffffffff1614156112845760cf6111ee6001846145a6565b815481106111fe576111fe614666565b60009182526020909120015460cf805473ffffffffffffffffffffffffffffffffffffffff909216918390811061123757611237614666565b9060005260206000200160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550611296565b8061128e81614695565b91505061117d565b5060cf8054806112a8576112a86146ce565b60008281526020812082017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff90810180547fffffffffffffffffffffffff000000000000000000000000000000000000000016905590910190915560405173ffffffffffffffffffffffffffffffffffffffff8416917f5c95b49c4d59d97a2f044167723f29c74b30f99702e3fd406c3830160aa9ccb891a25050565b60cd5473ffffffffffffffffffffffffffffffffffffffff16331480159061138357503373ffffffffffffffffffffffffffffffffffffffff821614155b156113ba576040517fddb5de5e00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff8116600081815260cc602052604080822080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00169055517f98c15241d6c02bc5ee0b780e11b3ea737a2defd9d04877edbe9f9497065bd02f9190a250565b33600090815260cc602052604090205460ff16611477576040517ff8d2906c00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b61082d8383836132dc565b600061148c613397565b905090565b60cd546040517f521d4de900000000000000000000000000000000000000000000000000000000815233600482015273ffffffffffffffffffffffffffffffffffffffff9091169063521d4de990602401602060405180830381865afa1580156114ff573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611523919061455a565b611559576040517f99e120bc00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff8216600090815260ce602052604090206002015468010000000000000000900460ff166115c7576040517fc1ab6dc100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff8216600081815260ce602052604090819020839055517fe7b113fba37131b6396680a0c55790a697ec975e198ff8cfd89dac90a6379e61906109899084815260200190565b33600081815260346020908152604080832073ffffffffffffffffffffffffffffffffffffffff8716845290915281205490916109a29185906116659086906145d6565b612a3f565b60cd546040517f521d4de900000000000000000000000000000000000000000000000000000000815233600482015273ffffffffffffffffffffffffffffffffffffffff9091169063521d4de990602401602060405180830381865afa1580156116d8573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906116fc919061455a565b611732576040517f99e120bc00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60d28190556040518181527fc3b69829afe2345596a02c8b587d41f796ba0094481d899e1b2e07b7532a1e219060200160405180910390a150565b33600090815260cc602052604090205460ff166117b6576040517ff8d2906c00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b610f8f8282612d1c565b73ffffffffffffffffffffffffffffffffffffffff8116600090815260d060205260408120816117f2610e10426145ee565b8152602001908152602001600020549050919050565b60cd546040517f521d4de900000000000000000000000000000000000000000000000000000000815233600482015273ffffffffffffffffffffffffffffffffffffffff9091169063521d4de990602401602060405180830381865afa158015611876573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061189a919061455a565b6118d0576040517f99e120bc00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff8216600090815260ce602052604090206002015468010000000000000000900460ff1661193e576040517fc1ab6dc100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff8216600081815260ce602052604090819020600101839055517fe13ac9338b2ee623233f83c1b3ceab16490fa3e3737fac7f0970d0830a9f4871906109899084815260200190565b60cd546040517fe43581b800000000000000000000000000000000000000000000000000000000815233600482015273ffffffffffffffffffffffffffffffffffffffff9091169063e43581b890602401602060405180830381865afa158015611a09573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611a2d919061455a565b611a63576040517fee3675d400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff8516600090815260ce602052604090206002015468010000000000000000900460ff1680611aba575073ffffffffffffffffffffffffffffffffffffffff8516155b15611af1576040517fc1ab6dc100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b633b9aca008267ffffffffffffffff161115611b39576040517feca1d2c600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040805160a08101825260008082526020820181905291810182905260608101829052608081019190915284815260208082018581528315156080840190815267ffffffffffffffff808716604080870191825260016060880181815273ffffffffffffffffffffffffffffffffffffffff8e16600081815260ce9099528389208a5181559751888401559351600290970180549151965115156901000000000000000000027fffffffffffffffffffffffffffffffffffffffffffff00ffffffffffffffffff97151568010000000000000000027fffffffffffffffffffffffffffffffffffffffffffffff000000000000000000909316989096169790971717949094169290921790935560cf805492830181559093527facb8d954e2cfef495862221e91bd7523613cf8808827cb33edfe4904cc51bf290180547fffffffffffffffffffffffff0000000000000000000000000000000000000000168217905590517f53087ff85d80a7671594bd2e86b92af22e0b3c2c441c8033bba7399b7b5cbe2390611cf3908890889088908890938452602084019290925267ffffffffffffffff1660408301521515606082015260800190565b60405180910390a2505050505050565b600060d381611d14610e10426145ee565b815260200190815260200160002054905090565b73ffffffffffffffffffffffffffffffffffffffff81166000908152609960205260408120545b92915050565b611d5f33826130ef565b50565b60606037805461079f9061450c565b60cd5473ffffffffffffffffffffffffffffffffffffffff163314611dc2576040517fb90cdbb100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff8116600081815260cc602052604080822080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00166001179055517f98c15241d6c02bc5ee0b780e11b3ea737a2defd9d04877edbe9f9497065bd02f9190a250565b60cd546040517f521d4de900000000000000000000000000000000000000000000000000000000815233600482015273ffffffffffffffffffffffffffffffffffffffff9091169063521d4de990602401602060405180830381865afa158015611ea7573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611ecb919061455a565b611f01576040517f99e120bc00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff8216600090815260ce602052604090206002015468010000000000000000900460ff16611f6f576040517fc1ab6dc100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b633b9aca008167ffffffffffffffff161115611fb7576040517feca1d2c600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff8216600081815260ce602090815260409182902060020180547fffffffffffffffffffffffffffffffffffffffffffffffff00000000000000001667ffffffffffffffff861690811790915591519182527f901f9de19b475adc8da4110434b8df940dce085afd05e2281c86807f3a899d299101610989565b33600090815260346020908152604080832073ffffffffffffffffffffffffffffffffffffffff8616845290915281205482811015612106576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602560248201527f45524332303a2064656372656173656420616c6c6f77616e63652062656c6f7760448201527f207a65726f0000000000000000000000000000000000000000000000000000006064820152608401610f1b565b6121133385858403612a3f565b5060019392505050565b60006109a2338484612e3c565b60cf818154811061213a57600080fd5b60009182526020909120015473ffffffffffffffffffffffffffffffffffffffff16905081565b606060cf80548060200260200160405190810160405280929190818152602001828054801561081857602002820191906000526020600020905b815473ffffffffffffffffffffffffffffffffffffffff16815260019091019060200180831161219b575050505050905090565b73ffffffffffffffffffffffffffffffffffffffff8316600090815260ce60209081526040808320815160a081018352815481526001820154938101939093526002015467ffffffffffffffff81169183019190915260ff68010000000000000000820481161580156060850152690100000000000000000090920416151560808301528061225f575080608001515b15612296576040517fc1ab6dc100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60006122a4610e10426145ee565b600081815260d36020526040812054919250906122c29087906145d6565b905060d254811115612300576040517f6d43d1ac00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600082815260d36020526040902081905561231b33876130ef565b33600090815260d16020526040902054869061236757633b9aca00846040015167ffffffffffffffff16826123509190614629565b61235a91906145ee565b61236490826145a6565b90505b61238873ffffffffffffffffffffffffffffffffffffffff89168783612bea565b979650505050505050565b834211156123fd576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f45524332305065726d69743a206578706972656420646561646c696e650000006044820152606401610f1b565b6000609a5488888861240e8c613412565b60408051602081019690965273ffffffffffffffffffffffffffffffffffffffff94851690860152929091166060840152608083015260a082015260c0810186905260e001604051602081830303815290604052805190602001209050600061247682613447565b90506000612486828787876134b0565b90508973ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff161461251d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601e60248201527f45524332305065726d69743a20696e76616c6964207369676e617475726500006044820152606401610f1b565b6125288a8a8a612a3f565b50505050505050505050565b60cd546040517f521d4de900000000000000000000000000000000000000000000000000000000815233600482015273ffffffffffffffffffffffffffffffffffffffff9091169063521d4de990602401602060405180830381865afa1580156125a2573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906125c6919061455a565b6125fc576040517f99e120bc00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff8116600090815260ce602052604090206002015468010000000000000000900460ff1661266a576040517fc1ab6dc100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff8116600081815260ce602090815260409182902060020180547fffffffffffffffffffffffffffffffffffffffffffff00ffffffffffffffffff811669010000000000000000009182900460ff16801592830291909117909255925192835292917ff7c93079dcbf699749d66345a351afab7d24219bb1d915c9f4fc4cf03f00d3979101610989565b60cd5473ffffffffffffffffffffffffffffffffffffffff163314612759576040517fb90cdbb100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60cd80547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83169081179091556040517f7dae230f18360d76a040c81f050aa14eb9d6dc7901b20fc5d855e2a20fe814d190600090a250565b3b151590565b600054610100900460ff166127e95760005460ff16156127ed565b303b155b612879576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201527f647920696e697469616c697a65640000000000000000000000000000000000006064820152608401610f1b565b600054610100900460ff161580156128b857600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0000166101011790555b6128c1846134d8565b6128cb84846135bf565b3073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1663e9cbd8226040518163ffffffff1660e01b8152600401602060405180830381865afa15801561292d573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061295191906146fd565b73ffffffffffffffffffffffffffffffffffffffff161461299e576040517f14bcf5c800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60cd80547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff84169081179091556040517f7dae230f18360d76a040c81f050aa14eb9d6dc7901b20fc5d855e2a20fe814d190600090a28015612a3957600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff1690555b50505050565b73ffffffffffffffffffffffffffffffffffffffff8316612ae1576040517f08c379a0000000000000000000000000000000000000000000000000000000008152602060048201526024808201527f45524332303a20617070726f76652066726f6d20746865207a65726f2061646460448201527f72657373000000000000000000000000000000000000000000000000000000006064820152608401610f1b565b73ffffffffffffffffffffffffffffffffffffffff8216612b84576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602260248201527f45524332303a20617070726f766520746f20746865207a65726f20616464726560448201527f73730000000000000000000000000000000000000000000000000000000000006064820152608401610f1b565b73ffffffffffffffffffffffffffffffffffffffff83811660008181526034602090815260408083209487168084529482529182902085905590518481527f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b9259101610af3565b60405173ffffffffffffffffffffffffffffffffffffffff831660248201526044810182905261082d9084907fa9059cbb00000000000000000000000000000000000000000000000000000000906064015b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff0000000000000000000000000000000000000000000000000000000090931692909217909152613668565b60405173ffffffffffffffffffffffffffffffffffffffff80851660248301528316604482015260648101829052612a399085907f23b872dd0000000000000000000000000000000000000000000000000000000090608401612c3c565b73ffffffffffffffffffffffffffffffffffffffff8216612d99576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601f60248201527f45524332303a206d696e7420746f20746865207a65726f2061646472657373006044820152606401610f1b565b8060356000828254612dab91906145d6565b909155505073ffffffffffffffffffffffffffffffffffffffff821660009081526033602052604081208054839290612de59084906145d6565b909155505060405181815273ffffffffffffffffffffffffffffffffffffffff8316906000907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef9060200160405180910390a35050565b73ffffffffffffffffffffffffffffffffffffffff8316612edf576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602560248201527f45524332303a207472616e736665722066726f6d20746865207a65726f20616460448201527f64726573730000000000000000000000000000000000000000000000000000006064820152608401610f1b565b73ffffffffffffffffffffffffffffffffffffffff8216612f82576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602360248201527f45524332303a207472616e7366657220746f20746865207a65726f206164647260448201527f65737300000000000000000000000000000000000000000000000000000000006064820152608401610f1b565b73ffffffffffffffffffffffffffffffffffffffff831660009081526033602052604090205481811015613038576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f45524332303a207472616e7366657220616d6f756e742065786365656473206260448201527f616c616e636500000000000000000000000000000000000000000000000000006064820152608401610f1b565b73ffffffffffffffffffffffffffffffffffffffff80851660009081526033602052604080822085850390559185168152908120805484929061307c9084906145d6565b925050819055508273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef846040516130e291815260200190565b60405180910390a3612a39565b73ffffffffffffffffffffffffffffffffffffffff8216613192576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602160248201527f45524332303a206275726e2066726f6d20746865207a65726f2061646472657360448201527f73000000000000000000000000000000000000000000000000000000000000006064820152608401610f1b565b73ffffffffffffffffffffffffffffffffffffffff821660009081526033602052604090205481811015613248576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602260248201527f45524332303a206275726e20616d6f756e7420657863656564732062616c616e60448201527f63650000000000000000000000000000000000000000000000000000000000006064820152608401610f1b565b73ffffffffffffffffffffffffffffffffffffffff831660009081526033602052604081208383039055603580548492906132849084906145a6565b909155505060405182815260009073ffffffffffffffffffffffffffffffffffffffff8516907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef9060200160405180910390a3505050565b8073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff161461338d5773ffffffffffffffffffffffffffffffffffffffff8281166000908152603460209081526040808320938516835292905220548381101561337c576040517f715ec26c00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b61338b838361166587856145a6565b505b61082d82846130ef565b600061148c7f8b73c3c69bb8fe3d512ecc4cf759cc79239f7b179b0ffacaa9a75d522b39400f6133c660655490565b6066546040805160208101859052908101839052606081018290524660808201523060a082015260009060c0016040516020818303038152906040528051906020012090509392505050565b73ffffffffffffffffffffffffffffffffffffffff811660009081526099602052604090208054600181018255905b50919050565b6000611d4f613454613397565b836040517f19010000000000000000000000000000000000000000000000000000000000006020820152602281018390526042810182905260009060620160405160208183030381529060405280519060200120905092915050565b60008060006134c187878787613774565b915091506134ce8161388c565b5095945050505050565b600054610100900460ff1661356f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201527f6e697469616c697a696e670000000000000000000000000000000000000000006064820152608401610f1b565b613577613ae5565b6135b6816040518060400160405280600181526020017f3100000000000000000000000000000000000000000000000000000000000000815250613b7e565b611d5f81613c2f565b600054610100900460ff16613656576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201527f6e697469616c697a696e670000000000000000000000000000000000000000006064820152608401610f1b565b61365e613ae5565b610f8f8282613ced565b60006136ca826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c65648152508573ffffffffffffffffffffffffffffffffffffffff16613dab9092919063ffffffff16565b80519091501561082d57808060200190518101906136e8919061455a565b61082d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e60448201527f6f742073756363656564000000000000000000000000000000000000000000006064820152608401610f1b565b6000807f7fffffffffffffffffffffffffffffff5d576e7357a4501ddfe92f46681b20a08311156137ab5750600090506003613883565b8460ff16601b141580156137c357508460ff16601c14155b156137d45750600090506004613883565b6040805160008082526020820180845289905260ff881692820192909252606081018690526080810185905260019060a0016020604051602081039080840390855afa158015613828573d6000803e3d6000fd5b50506040517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0015191505073ffffffffffffffffffffffffffffffffffffffff811661387c57600060019250925050613883565b9150600090505b94509492505050565b60008160048111156138a0576138a061471a565b14156138a95750565b60018160048111156138bd576138bd61471a565b1415613925576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601860248201527f45434453413a20696e76616c6964207369676e617475726500000000000000006044820152606401610f1b565b60028160048111156139395761393961471a565b14156139a1576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601f60248201527f45434453413a20696e76616c6964207369676e6174757265206c656e677468006044820152606401610f1b565b60038160048111156139b5576139b561471a565b1415613a43576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602260248201527f45434453413a20696e76616c6964207369676e6174757265202773272076616c60448201527f75650000000000000000000000000000000000000000000000000000000000006064820152608401610f1b565b6004816004811115613a5757613a5761471a565b1415611d5f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602260248201527f45434453413a20696e76616c6964207369676e6174757265202776272076616c60448201527f75650000000000000000000000000000000000000000000000000000000000006064820152608401610f1b565b600054610100900460ff16613b7c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201527f6e697469616c697a696e670000000000000000000000000000000000000000006064820152608401610f1b565b565b600054610100900460ff16613c15576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201527f6e697469616c697a696e670000000000000000000000000000000000000000006064820152608401610f1b565b815160209283012081519190920120606591909155606655565b600054610100900460ff16613cc6576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201527f6e697469616c697a696e670000000000000000000000000000000000000000006064820152608401610f1b565b507f6e71edae12b1b97f4d1f60370fef10105fa2faae0126114a169c64845d6126c9609a55565b600054610100900460ff16613d84576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201527f6e697469616c697a696e670000000000000000000000000000000000000000006064820152608401610f1b565b8151613d97906036906020850190613f85565b50805161082d906037906020840190613f85565b6060613dba8484600085613dc2565b949350505050565b606082471015613e54576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f60448201527f722063616c6c00000000000000000000000000000000000000000000000000006064820152608401610f1b565b843b613ebc576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006044820152606401610f1b565b6000808673ffffffffffffffffffffffffffffffffffffffff168587604051613ee59190614749565b60006040518083038185875af1925050503d8060008114613f22576040519150601f19603f3d011682016040523d82523d6000602084013e613f27565b606091505b509150915061238882828660608315613f41575081610e4a565b825115613f515782518084602001fd5b816040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610f1b919061404a565b828054613f919061450c565b90600052602060002090601f016020900481019282613fb35760008555613ff9565b82601f10613fcc57805160ff1916838001178555613ff9565b82800160010185558215613ff9579182015b82811115613ff9578251825591602001919060010190613fde565b50614005929150614009565b5090565b5b80821115614005576000815560010161400a565b60005b83811015614039578181015183820152602001614021565b83811115612a395750506000910152565b602081526000825180602084015261406981604085016020870161401e565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169190910160400192915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b600082601f8301126140db57600080fd5b813567ffffffffffffffff808211156140f6576140f661409b565b604051601f83017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0908116603f0116810190828211818310171561413c5761413c61409b565b8160405283815286602085880101111561415557600080fd5b836020870160208301376000602085830101528094505050505092915050565b73ffffffffffffffffffffffffffffffffffffffff81168114611d5f57600080fd5b6000806000606084860312156141ac57600080fd5b833567ffffffffffffffff808211156141c457600080fd5b6141d0878388016140ca565b945060208601359150808211156141e657600080fd5b506141f3868287016140ca565b925050604084013561420481614175565b809150509250925092565b60006020828403121561422157600080fd5b8135610e4a81614175565b6000806040838503121561423f57600080fd5b823561424a81614175565b946020939093013593505050565b60008060006060848603121561426d57600080fd5b833561427881614175565b9250602084013561428881614175565b929592945050506040919091013590565b6000806000606084860312156142ae57600080fd5b83356142b981614175565b925060208401359150604084013561420481614175565b600080604083850312156142e357600080fd5b8235915060208301356142f581614175565b809150509250929050565b60008060006060848603121561431557600080fd5b83359250602084013561432781614175565b9150604084013561420481614175565b60006020828403121561434957600080fd5b5035919050565b803567ffffffffffffffff8116811461436857600080fd5b919050565b8015158114611d5f57600080fd5b600080600080600060a0868803121561439357600080fd5b853561439e81614175565b945060208601359350604086013592506143ba60608701614350565b915060808601356143ca8161436d565b809150509295509295909350565b600080604083850312156143eb57600080fd5b82356143f681614175565b915061440460208401614350565b90509250929050565b6020808252825182820181905260009190848201906040850190845b8181101561445b57835173ffffffffffffffffffffffffffffffffffffffff1683529284019291840191600101614429565b50909695505050505050565b600080600080600080600060e0888a03121561448257600080fd5b873561448d81614175565b9650602088013561449d81614175565b95506040880135945060608801359350608088013560ff811681146144c157600080fd5b9699959850939692959460a0840135945060c09093013592915050565b600080604083850312156144f157600080fd5b82356144fc81614175565b915060208301356142f581614175565b600181811c9082168061452057607f821691505b60208210811415613441577f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b60006020828403121561456c57600080fd5b8151610e4a8161436d565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b6000828210156145b8576145b8614577565b500390565b6000602082840312156145cf57600080fd5b5051919050565b600082198211156145e9576145e9614577565b500190565b600082614624577f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b500490565b6000817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff048311821515161561466157614661614577565b500290565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8214156146c7576146c7614577565b5060010190565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603160045260246000fd5b60006020828403121561470f57600080fd5b8151610e4a81614175565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b6000825161475b81846020870161401e565b919091019291505056fea2646970667358221220103b8d652dd7975983cef70f41cb81056a0bf607243b7332223b4013506c7eb664736f6c634300080c0033", - "deployedBytecode": "0x608060405234801561001057600080fd5b50600436106102ff5760003560e01c806361d027b31161019c5780639f48118f116100ee578063ced67f0c11610097578063dd62ed3e11610071578063dd62ed3e14610724578063e3e286551461076a578063f0f442601461077d57600080fd5b8063ced67f0c1461066b578063d44ad63f146106fe578063d505accf1461071157600080fd5b8063aa271e1a116100c8578063aa271e1a14610620578063ba330bd714610643578063cd4839ca1461065657600080fd5b80639f48118f146105ef578063a457c2d7146105fa578063a9059cbb1461060d57600080fd5b80637ecebe001161015057806395d89b411161012a57806395d89b41146105c1578063983b2d56146105c95780639e4e0dae146105dc57600080fd5b80637ecebe00146105705780638933fb791461058357806390218cff146105ae57600080fd5b80637334d020116101815780637334d020146105425780637d4c9c2d146105555780637d74e25f1461056857600080fd5b806361d027b3146104c757806370a082311461050c57600080fd5b80633092afd511610255578063395093511161020957806340c10f19116101e357806340c10f19146104815780634dc32fcc146104945780635bfbec96146104a757600080fd5b8063395093511461043b5780633a55f89d1461044e5780633f4218e01461046157600080fd5b8063350ebe041161023a578063350ebe041461040d5780633644e5151461042057806336db43b51461042857600080fd5b80633092afd5146103eb578063313ce567146103fe57600080fd5b8063151dd755116102b757806323b872dd1161029157806323b872dd146103b25780632b471d8e146103c55780632e403e14146103d857600080fd5b8063151dd7551461038057806318160ddd146103a15780632342fb0e146103a957600080fd5b80630919a951116102e85780630919a95114610337578063095ea7b31461034a5780631171bda91461036d57600080fd5b806306fdde0314610304578063077f224a14610322575b600080fd5b61030c610790565b604051610319919061404a565b60405180910390f35b610335610330366004614197565b610822565b005b61033561034536600461420f565b610832565b61035d61035836600461422c565b610995565b6040519015158152602001610319565b61033561037b366004614258565b6109ab565b61039361038e366004614299565b610b00565b604051908152602001610319565b603554610393565b61039360d25481565b61035d6103c0366004614258565b610e51565b6103356103d33660046142d0565b610f3c565b6103356103e636600461420f565b610f93565b6103356103f936600461420f565b611345565b60405160128152602001610319565b61033561041b366004614300565b61142e565b610393611482565b61033561043636600461422c565b611491565b61035d61044936600461422c565b611621565b61033561045c366004614337565b61166a565b61039361046f36600461420f565b60d16020526000908152604090205481565b61033561048f36600461422c565b61176d565b6103936104a236600461420f565b6117c0565b6103936104b5366004614337565b60d36020526000908152604090205481565b60cd546104e79073ffffffffffffffffffffffffffffffffffffffff1681565b60405173ffffffffffffffffffffffffffffffffffffffff9091168152602001610319565b61039361051a36600461420f565b73ffffffffffffffffffffffffffffffffffffffff1660009081526033602052604090205490565b61033561055036600461422c565b611808565b61033561056336600461437b565b61199b565b610393611d03565b61039361057e36600461420f565b611d28565b61039361059136600461422c565b60d060209081526000928352604080842090915290825290205481565b6103356105bc366004614337565b611d55565b61030c611d62565b6103356105d736600461420f565b611d71565b6103356105ea3660046143d8565b611e39565b610393633b9aca0081565b61035d61060836600461422c565b612045565b61035d61061b36600461422c565b61211d565b61035d61062e36600461420f565b60cc6020526000908152604090205460ff1681565b6104e7610651366004614337565b61212a565b61065e612161565b604051610319919061440d565b6106c561067936600461420f565b60ce6020526000908152604090208054600182015460029092015490919067ffffffffffffffff81169060ff680100000000000000008204811691690100000000000000000090041685565b60408051958652602086019490945267ffffffffffffffff9092169284019290925290151560608301521515608082015260a001610319565b61039361070c366004614299565b6121cf565b61033561071f366004614467565b612393565b6103936107323660046144de565b73ffffffffffffffffffffffffffffffffffffffff918216600090815260346020908152604080832093909416825291909152205490565b61033561077836600461420f565b612534565b61033561078b36600461420f565b612708565b60606036805461079f9061450c565b80601f01602080910402602001604051908101604052809291908181526020018280546107cb9061450c565b80156108185780601f106107ed57610100808354040283529160200191610818565b820191906000526020600020905b8154815290600101906020018083116107fb57829003601f168201915b5050505050905090565b61082d8383836127ce565b505050565b60cd546040517f521d4de900000000000000000000000000000000000000000000000000000000815233600482015273ffffffffffffffffffffffffffffffffffffffff9091169063521d4de990602401602060405180830381865afa1580156108a0573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906108c4919061455a565b6108fa576040517f99e120bc00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff8116600090815260d1602052604081205461092b9060016145a6565b73ffffffffffffffffffffffffffffffffffffffff8316600081815260d160205260409081902083905551919250907f979ef83e7e7a87cb48064e296dd7e997870d50f43acf8d7ad221313526c8ca0f906109899084815260200190565b60405180910390a25050565b60006109a2338484612a3f565b50600192915050565b60cd546040517fe43581b800000000000000000000000000000000000000000000000000000000815233600482015273ffffffffffffffffffffffffffffffffffffffff9091169063e43581b890602401602060405180830381865afa158015610a19573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610a3d919061455a565b610a73576040517fee3675d400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b610a9473ffffffffffffffffffffffffffffffffffffffff84168383612bea565b8173ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff167ffff3b3844276f57024e0b42afec1a37f75db36511e43819a4f2a63ab7862b64883604051610af391815260200190565b60405180910390a3505050565b73ffffffffffffffffffffffffffffffffffffffff8316600090815260ce60209081526040808320815160a081018352815481526001820154938101939093526002015467ffffffffffffffff81169183019190915260ff680100000000000000008204811615801560608501526901000000000000000000909204161515608083015280610b90575080608001515b15610bc7576040517fc1ab6dc100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015260009073ffffffffffffffffffffffffffffffffffffffff8716906370a0823190602401602060405180830381865afa158015610c34573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610c5891906145bd565b8251909150610c6786836145d6565b1115610c8f578151811015610c8a578151610c839082906145a6565b9450610c8f565b600094505b6000610c9d610e10426145ee565b73ffffffffffffffffffffffffffffffffffffffff8816600090815260d06020908152604080832084845290915281205491925090610cdd9088906145d6565b90508360200151811115610d715773ffffffffffffffffffffffffffffffffffffffff8816600090815260d060209081526040808320858452825290912054908501511115610d6c5773ffffffffffffffffffffffffffffffffffffffff8816600090815260d06020908152604080832085845282529091205490850151610d6591906145a6565b9650610d71565b600096505b73ffffffffffffffffffffffffffffffffffffffff8816600090815260d060209081526040808320858452909152902054610dad9088906145d6565b73ffffffffffffffffffffffffffffffffffffffff8916600081815260d060209081526040808320878452909152902091909155610ded9033308a612cbe565b33600090815260d160205260409020548790610e3957633b9aca00856040015167ffffffffffffffff1682610e229190614629565b610e2c91906145ee565b610e3690826145a6565b90505b610e438782612d1c565b9450505050505b9392505050565b6000610e5e848484612e3c565b73ffffffffffffffffffffffffffffffffffffffff8416600090815260346020908152604080832033845290915290205482811015610f24576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602860248201527f45524332303a207472616e7366657220616d6f756e742065786365656473206160448201527f6c6c6f77616e636500000000000000000000000000000000000000000000000060648201526084015b60405180910390fd5b610f318533858403612a3f565b506001949350505050565b33600090815260cc602052604090205460ff16610f85576040517ff8d2906c00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b610f8f81836130ef565b5050565b60cd546040517fe43581b800000000000000000000000000000000000000000000000000000000815233600482015273ffffffffffffffffffffffffffffffffffffffff9091169063e43581b890602401602060405180830381865afa158015611001573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611025919061455a565b61105b576040517fee3675d400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015273ffffffffffffffffffffffffffffffffffffffff8216906370a0823190602401602060405180830381865afa1580156110c5573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906110e991906145bd565b15611120576040517f2ef630ec00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff8116600090815260ce602052604081208181556001810182905560020180547fffffffffffffffffffffffffffffffffffffffffffff0000000000000000000016905560cf54905b6111886001836145a6565b811015611296578273ffffffffffffffffffffffffffffffffffffffff1660cf82815481106111b9576111b9614666565b60009182526020909120015473ffffffffffffffffffffffffffffffffffffffff1614156112845760cf6111ee6001846145a6565b815481106111fe576111fe614666565b60009182526020909120015460cf805473ffffffffffffffffffffffffffffffffffffffff909216918390811061123757611237614666565b9060005260206000200160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550611296565b8061128e81614695565b91505061117d565b5060cf8054806112a8576112a86146ce565b60008281526020812082017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff90810180547fffffffffffffffffffffffff000000000000000000000000000000000000000016905590910190915560405173ffffffffffffffffffffffffffffffffffffffff8416917f5c95b49c4d59d97a2f044167723f29c74b30f99702e3fd406c3830160aa9ccb891a25050565b60cd5473ffffffffffffffffffffffffffffffffffffffff16331480159061138357503373ffffffffffffffffffffffffffffffffffffffff821614155b156113ba576040517fddb5de5e00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff8116600081815260cc602052604080822080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00169055517f98c15241d6c02bc5ee0b780e11b3ea737a2defd9d04877edbe9f9497065bd02f9190a250565b33600090815260cc602052604090205460ff16611477576040517ff8d2906c00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b61082d8383836132dc565b600061148c613397565b905090565b60cd546040517f521d4de900000000000000000000000000000000000000000000000000000000815233600482015273ffffffffffffffffffffffffffffffffffffffff9091169063521d4de990602401602060405180830381865afa1580156114ff573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611523919061455a565b611559576040517f99e120bc00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff8216600090815260ce602052604090206002015468010000000000000000900460ff166115c7576040517fc1ab6dc100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff8216600081815260ce602052604090819020839055517fe7b113fba37131b6396680a0c55790a697ec975e198ff8cfd89dac90a6379e61906109899084815260200190565b33600081815260346020908152604080832073ffffffffffffffffffffffffffffffffffffffff8716845290915281205490916109a29185906116659086906145d6565b612a3f565b60cd546040517f521d4de900000000000000000000000000000000000000000000000000000000815233600482015273ffffffffffffffffffffffffffffffffffffffff9091169063521d4de990602401602060405180830381865afa1580156116d8573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906116fc919061455a565b611732576040517f99e120bc00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60d28190556040518181527fc3b69829afe2345596a02c8b587d41f796ba0094481d899e1b2e07b7532a1e219060200160405180910390a150565b33600090815260cc602052604090205460ff166117b6576040517ff8d2906c00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b610f8f8282612d1c565b73ffffffffffffffffffffffffffffffffffffffff8116600090815260d060205260408120816117f2610e10426145ee565b8152602001908152602001600020549050919050565b60cd546040517f521d4de900000000000000000000000000000000000000000000000000000000815233600482015273ffffffffffffffffffffffffffffffffffffffff9091169063521d4de990602401602060405180830381865afa158015611876573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061189a919061455a565b6118d0576040517f99e120bc00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff8216600090815260ce602052604090206002015468010000000000000000900460ff1661193e576040517fc1ab6dc100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff8216600081815260ce602052604090819020600101839055517fe13ac9338b2ee623233f83c1b3ceab16490fa3e3737fac7f0970d0830a9f4871906109899084815260200190565b60cd546040517fe43581b800000000000000000000000000000000000000000000000000000000815233600482015273ffffffffffffffffffffffffffffffffffffffff9091169063e43581b890602401602060405180830381865afa158015611a09573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611a2d919061455a565b611a63576040517fee3675d400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff8516600090815260ce602052604090206002015468010000000000000000900460ff1680611aba575073ffffffffffffffffffffffffffffffffffffffff8516155b15611af1576040517fc1ab6dc100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b633b9aca008267ffffffffffffffff161115611b39576040517feca1d2c600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040805160a08101825260008082526020820181905291810182905260608101829052608081019190915284815260208082018581528315156080840190815267ffffffffffffffff808716604080870191825260016060880181815273ffffffffffffffffffffffffffffffffffffffff8e16600081815260ce9099528389208a5181559751888401559351600290970180549151965115156901000000000000000000027fffffffffffffffffffffffffffffffffffffffffffff00ffffffffffffffffff97151568010000000000000000027fffffffffffffffffffffffffffffffffffffffffffffff000000000000000000909316989096169790971717949094169290921790935560cf805492830181559093527facb8d954e2cfef495862221e91bd7523613cf8808827cb33edfe4904cc51bf290180547fffffffffffffffffffffffff0000000000000000000000000000000000000000168217905590517f53087ff85d80a7671594bd2e86b92af22e0b3c2c441c8033bba7399b7b5cbe2390611cf3908890889088908890938452602084019290925267ffffffffffffffff1660408301521515606082015260800190565b60405180910390a2505050505050565b600060d381611d14610e10426145ee565b815260200190815260200160002054905090565b73ffffffffffffffffffffffffffffffffffffffff81166000908152609960205260408120545b92915050565b611d5f33826130ef565b50565b60606037805461079f9061450c565b60cd5473ffffffffffffffffffffffffffffffffffffffff163314611dc2576040517fb90cdbb100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff8116600081815260cc602052604080822080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00166001179055517f98c15241d6c02bc5ee0b780e11b3ea737a2defd9d04877edbe9f9497065bd02f9190a250565b60cd546040517f521d4de900000000000000000000000000000000000000000000000000000000815233600482015273ffffffffffffffffffffffffffffffffffffffff9091169063521d4de990602401602060405180830381865afa158015611ea7573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611ecb919061455a565b611f01576040517f99e120bc00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff8216600090815260ce602052604090206002015468010000000000000000900460ff16611f6f576040517fc1ab6dc100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b633b9aca008167ffffffffffffffff161115611fb7576040517feca1d2c600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff8216600081815260ce602090815260409182902060020180547fffffffffffffffffffffffffffffffffffffffffffffffff00000000000000001667ffffffffffffffff861690811790915591519182527f901f9de19b475adc8da4110434b8df940dce085afd05e2281c86807f3a899d299101610989565b33600090815260346020908152604080832073ffffffffffffffffffffffffffffffffffffffff8616845290915281205482811015612106576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602560248201527f45524332303a2064656372656173656420616c6c6f77616e63652062656c6f7760448201527f207a65726f0000000000000000000000000000000000000000000000000000006064820152608401610f1b565b6121133385858403612a3f565b5060019392505050565b60006109a2338484612e3c565b60cf818154811061213a57600080fd5b60009182526020909120015473ffffffffffffffffffffffffffffffffffffffff16905081565b606060cf80548060200260200160405190810160405280929190818152602001828054801561081857602002820191906000526020600020905b815473ffffffffffffffffffffffffffffffffffffffff16815260019091019060200180831161219b575050505050905090565b73ffffffffffffffffffffffffffffffffffffffff8316600090815260ce60209081526040808320815160a081018352815481526001820154938101939093526002015467ffffffffffffffff81169183019190915260ff68010000000000000000820481161580156060850152690100000000000000000090920416151560808301528061225f575080608001515b15612296576040517fc1ab6dc100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60006122a4610e10426145ee565b600081815260d36020526040812054919250906122c29087906145d6565b905060d254811115612300576040517f6d43d1ac00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600082815260d36020526040902081905561231b33876130ef565b33600090815260d16020526040902054869061236757633b9aca00846040015167ffffffffffffffff16826123509190614629565b61235a91906145ee565b61236490826145a6565b90505b61238873ffffffffffffffffffffffffffffffffffffffff89168783612bea565b979650505050505050565b834211156123fd576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f45524332305065726d69743a206578706972656420646561646c696e650000006044820152606401610f1b565b6000609a5488888861240e8c613412565b60408051602081019690965273ffffffffffffffffffffffffffffffffffffffff94851690860152929091166060840152608083015260a082015260c0810186905260e001604051602081830303815290604052805190602001209050600061247682613447565b90506000612486828787876134b0565b90508973ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff161461251d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601e60248201527f45524332305065726d69743a20696e76616c6964207369676e617475726500006044820152606401610f1b565b6125288a8a8a612a3f565b50505050505050505050565b60cd546040517f521d4de900000000000000000000000000000000000000000000000000000000815233600482015273ffffffffffffffffffffffffffffffffffffffff9091169063521d4de990602401602060405180830381865afa1580156125a2573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906125c6919061455a565b6125fc576040517f99e120bc00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff8116600090815260ce602052604090206002015468010000000000000000900460ff1661266a576040517fc1ab6dc100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff8116600081815260ce602090815260409182902060020180547fffffffffffffffffffffffffffffffffffffffffffff00ffffffffffffffffff811669010000000000000000009182900460ff16801592830291909117909255925192835292917ff7c93079dcbf699749d66345a351afab7d24219bb1d915c9f4fc4cf03f00d3979101610989565b60cd5473ffffffffffffffffffffffffffffffffffffffff163314612759576040517fb90cdbb100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60cd80547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83169081179091556040517f7dae230f18360d76a040c81f050aa14eb9d6dc7901b20fc5d855e2a20fe814d190600090a250565b3b151590565b600054610100900460ff166127e95760005460ff16156127ed565b303b155b612879576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201527f647920696e697469616c697a65640000000000000000000000000000000000006064820152608401610f1b565b600054610100900460ff161580156128b857600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0000166101011790555b6128c1846134d8565b6128cb84846135bf565b3073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1663e9cbd8226040518163ffffffff1660e01b8152600401602060405180830381865afa15801561292d573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061295191906146fd565b73ffffffffffffffffffffffffffffffffffffffff161461299e576040517f14bcf5c800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60cd80547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff84169081179091556040517f7dae230f18360d76a040c81f050aa14eb9d6dc7901b20fc5d855e2a20fe814d190600090a28015612a3957600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff1690555b50505050565b73ffffffffffffffffffffffffffffffffffffffff8316612ae1576040517f08c379a0000000000000000000000000000000000000000000000000000000008152602060048201526024808201527f45524332303a20617070726f76652066726f6d20746865207a65726f2061646460448201527f72657373000000000000000000000000000000000000000000000000000000006064820152608401610f1b565b73ffffffffffffffffffffffffffffffffffffffff8216612b84576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602260248201527f45524332303a20617070726f766520746f20746865207a65726f20616464726560448201527f73730000000000000000000000000000000000000000000000000000000000006064820152608401610f1b565b73ffffffffffffffffffffffffffffffffffffffff83811660008181526034602090815260408083209487168084529482529182902085905590518481527f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b9259101610af3565b60405173ffffffffffffffffffffffffffffffffffffffff831660248201526044810182905261082d9084907fa9059cbb00000000000000000000000000000000000000000000000000000000906064015b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff0000000000000000000000000000000000000000000000000000000090931692909217909152613668565b60405173ffffffffffffffffffffffffffffffffffffffff80851660248301528316604482015260648101829052612a399085907f23b872dd0000000000000000000000000000000000000000000000000000000090608401612c3c565b73ffffffffffffffffffffffffffffffffffffffff8216612d99576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601f60248201527f45524332303a206d696e7420746f20746865207a65726f2061646472657373006044820152606401610f1b565b8060356000828254612dab91906145d6565b909155505073ffffffffffffffffffffffffffffffffffffffff821660009081526033602052604081208054839290612de59084906145d6565b909155505060405181815273ffffffffffffffffffffffffffffffffffffffff8316906000907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef9060200160405180910390a35050565b73ffffffffffffffffffffffffffffffffffffffff8316612edf576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602560248201527f45524332303a207472616e736665722066726f6d20746865207a65726f20616460448201527f64726573730000000000000000000000000000000000000000000000000000006064820152608401610f1b565b73ffffffffffffffffffffffffffffffffffffffff8216612f82576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602360248201527f45524332303a207472616e7366657220746f20746865207a65726f206164647260448201527f65737300000000000000000000000000000000000000000000000000000000006064820152608401610f1b565b73ffffffffffffffffffffffffffffffffffffffff831660009081526033602052604090205481811015613038576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f45524332303a207472616e7366657220616d6f756e742065786365656473206260448201527f616c616e636500000000000000000000000000000000000000000000000000006064820152608401610f1b565b73ffffffffffffffffffffffffffffffffffffffff80851660009081526033602052604080822085850390559185168152908120805484929061307c9084906145d6565b925050819055508273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef846040516130e291815260200190565b60405180910390a3612a39565b73ffffffffffffffffffffffffffffffffffffffff8216613192576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602160248201527f45524332303a206275726e2066726f6d20746865207a65726f2061646472657360448201527f73000000000000000000000000000000000000000000000000000000000000006064820152608401610f1b565b73ffffffffffffffffffffffffffffffffffffffff821660009081526033602052604090205481811015613248576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602260248201527f45524332303a206275726e20616d6f756e7420657863656564732062616c616e60448201527f63650000000000000000000000000000000000000000000000000000000000006064820152608401610f1b565b73ffffffffffffffffffffffffffffffffffffffff831660009081526033602052604081208383039055603580548492906132849084906145a6565b909155505060405182815260009073ffffffffffffffffffffffffffffffffffffffff8516907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef9060200160405180910390a3505050565b8073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff161461338d5773ffffffffffffffffffffffffffffffffffffffff8281166000908152603460209081526040808320938516835292905220548381101561337c576040517f715ec26c00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b61338b838361166587856145a6565b505b61082d82846130ef565b600061148c7f8b73c3c69bb8fe3d512ecc4cf759cc79239f7b179b0ffacaa9a75d522b39400f6133c660655490565b6066546040805160208101859052908101839052606081018290524660808201523060a082015260009060c0016040516020818303038152906040528051906020012090509392505050565b73ffffffffffffffffffffffffffffffffffffffff811660009081526099602052604090208054600181018255905b50919050565b6000611d4f613454613397565b836040517f19010000000000000000000000000000000000000000000000000000000000006020820152602281018390526042810182905260009060620160405160208183030381529060405280519060200120905092915050565b60008060006134c187878787613774565b915091506134ce8161388c565b5095945050505050565b600054610100900460ff1661356f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201527f6e697469616c697a696e670000000000000000000000000000000000000000006064820152608401610f1b565b613577613ae5565b6135b6816040518060400160405280600181526020017f3100000000000000000000000000000000000000000000000000000000000000815250613b7e565b611d5f81613c2f565b600054610100900460ff16613656576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201527f6e697469616c697a696e670000000000000000000000000000000000000000006064820152608401610f1b565b61365e613ae5565b610f8f8282613ced565b60006136ca826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c65648152508573ffffffffffffffffffffffffffffffffffffffff16613dab9092919063ffffffff16565b80519091501561082d57808060200190518101906136e8919061455a565b61082d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e60448201527f6f742073756363656564000000000000000000000000000000000000000000006064820152608401610f1b565b6000807f7fffffffffffffffffffffffffffffff5d576e7357a4501ddfe92f46681b20a08311156137ab5750600090506003613883565b8460ff16601b141580156137c357508460ff16601c14155b156137d45750600090506004613883565b6040805160008082526020820180845289905260ff881692820192909252606081018690526080810185905260019060a0016020604051602081039080840390855afa158015613828573d6000803e3d6000fd5b50506040517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0015191505073ffffffffffffffffffffffffffffffffffffffff811661387c57600060019250925050613883565b9150600090505b94509492505050565b60008160048111156138a0576138a061471a565b14156138a95750565b60018160048111156138bd576138bd61471a565b1415613925576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601860248201527f45434453413a20696e76616c6964207369676e617475726500000000000000006044820152606401610f1b565b60028160048111156139395761393961471a565b14156139a1576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601f60248201527f45434453413a20696e76616c6964207369676e6174757265206c656e677468006044820152606401610f1b565b60038160048111156139b5576139b561471a565b1415613a43576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602260248201527f45434453413a20696e76616c6964207369676e6174757265202773272076616c60448201527f75650000000000000000000000000000000000000000000000000000000000006064820152608401610f1b565b6004816004811115613a5757613a5761471a565b1415611d5f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602260248201527f45434453413a20696e76616c6964207369676e6174757265202776272076616c60448201527f75650000000000000000000000000000000000000000000000000000000000006064820152608401610f1b565b600054610100900460ff16613b7c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201527f6e697469616c697a696e670000000000000000000000000000000000000000006064820152608401610f1b565b565b600054610100900460ff16613c15576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201527f6e697469616c697a696e670000000000000000000000000000000000000000006064820152608401610f1b565b815160209283012081519190920120606591909155606655565b600054610100900460ff16613cc6576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201527f6e697469616c697a696e670000000000000000000000000000000000000000006064820152608401610f1b565b507f6e71edae12b1b97f4d1f60370fef10105fa2faae0126114a169c64845d6126c9609a55565b600054610100900460ff16613d84576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201527f6e697469616c697a696e670000000000000000000000000000000000000000006064820152608401610f1b565b8151613d97906036906020850190613f85565b50805161082d906037906020840190613f85565b6060613dba8484600085613dc2565b949350505050565b606082471015613e54576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f60448201527f722063616c6c00000000000000000000000000000000000000000000000000006064820152608401610f1b565b843b613ebc576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006044820152606401610f1b565b6000808673ffffffffffffffffffffffffffffffffffffffff168587604051613ee59190614749565b60006040518083038185875af1925050503d8060008114613f22576040519150601f19603f3d011682016040523d82523d6000602084013e613f27565b606091505b509150915061238882828660608315613f41575081610e4a565b825115613f515782518084602001fd5b816040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610f1b919061404a565b828054613f919061450c565b90600052602060002090601f016020900481019282613fb35760008555613ff9565b82601f10613fcc57805160ff1916838001178555613ff9565b82800160010185558215613ff9579182015b82811115613ff9578251825591602001919060010190613fde565b50614005929150614009565b5090565b5b80821115614005576000815560010161400a565b60005b83811015614039578181015183820152602001614021565b83811115612a395750506000910152565b602081526000825180602084015261406981604085016020870161401e565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169190910160400192915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b600082601f8301126140db57600080fd5b813567ffffffffffffffff808211156140f6576140f661409b565b604051601f83017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0908116603f0116810190828211818310171561413c5761413c61409b565b8160405283815286602085880101111561415557600080fd5b836020870160208301376000602085830101528094505050505092915050565b73ffffffffffffffffffffffffffffffffffffffff81168114611d5f57600080fd5b6000806000606084860312156141ac57600080fd5b833567ffffffffffffffff808211156141c457600080fd5b6141d0878388016140ca565b945060208601359150808211156141e657600080fd5b506141f3868287016140ca565b925050604084013561420481614175565b809150509250925092565b60006020828403121561422157600080fd5b8135610e4a81614175565b6000806040838503121561423f57600080fd5b823561424a81614175565b946020939093013593505050565b60008060006060848603121561426d57600080fd5b833561427881614175565b9250602084013561428881614175565b929592945050506040919091013590565b6000806000606084860312156142ae57600080fd5b83356142b981614175565b925060208401359150604084013561420481614175565b600080604083850312156142e357600080fd5b8235915060208301356142f581614175565b809150509250929050565b60008060006060848603121561431557600080fd5b83359250602084013561432781614175565b9150604084013561420481614175565b60006020828403121561434957600080fd5b5035919050565b803567ffffffffffffffff8116811461436857600080fd5b919050565b8015158114611d5f57600080fd5b600080600080600060a0868803121561439357600080fd5b853561439e81614175565b945060208601359350604086013592506143ba60608701614350565b915060808601356143ca8161436d565b809150509295509295909350565b600080604083850312156143eb57600080fd5b82356143f681614175565b915061440460208401614350565b90509250929050565b6020808252825182820181905260009190848201906040850190845b8181101561445b57835173ffffffffffffffffffffffffffffffffffffffff1683529284019291840191600101614429565b50909695505050505050565b600080600080600080600060e0888a03121561448257600080fd5b873561448d81614175565b9650602088013561449d81614175565b95506040880135945060608801359350608088013560ff811681146144c157600080fd5b9699959850939692959460a0840135945060c09093013592915050565b600080604083850312156144f157600080fd5b82356144fc81614175565b915060208301356142f581614175565b600181811c9082168061452057607f821691505b60208210811415613441577f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b60006020828403121561456c57600080fd5b8151610e4a8161436d565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b6000828210156145b8576145b8614577565b500390565b6000602082840312156145cf57600080fd5b5051919050565b600082198211156145e9576145e9614577565b500190565b600082614624577f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b500490565b6000817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff048311821515161561466157614661614577565b500290565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8214156146c7576146c7614577565b5060010190565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603160045260246000fd5b60006020828403121561470f57600080fd5b8151610e4a81614175565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b6000825161475b81846020870161401e565b919091019291505056fea2646970667358221220103b8d652dd7975983cef70f41cb81056a0bf607243b7332223b4013506c7eb664736f6c634300080c0033", + "numDeployments": 2, + "solcInputHash": "871924e0c138825a2736b76def8fef8d", + "metadata": "{\"compiler\":{\"version\":\"0.8.17+commit.8df45f5f\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[],\"name\":\"AssetStillControlledInReserves\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"BurnAmountExceedsAllowance\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"HourlyLimitExceeded\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidSender\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidToken\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidTreasury\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"NotGovernor\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"NotGovernorOrGuardian\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"NotMinter\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"NotTreasury\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"TooBigAmount\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"TooHighParameterValue\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ZeroAddress\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"spender\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"}],\"name\":\"Approval\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"bridgeToken\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"limit\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"hourlyLimit\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"fee\",\"type\":\"uint64\"},{\"indexed\":false,\"internalType\":\"bool\",\"name\":\"paused\",\"type\":\"bool\"}],\"name\":\"BridgeTokenAdded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"bridgeToken\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"fee\",\"type\":\"uint64\"}],\"name\":\"BridgeTokenFeeUpdated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"bridgeToken\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"hourlyLimit\",\"type\":\"uint256\"}],\"name\":\"BridgeTokenHourlyLimitUpdated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"bridgeToken\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"limit\",\"type\":\"uint256\"}],\"name\":\"BridgeTokenLimitUpdated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"bridgeToken\",\"type\":\"address\"}],\"name\":\"BridgeTokenRemoved\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"bridgeToken\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"bool\",\"name\":\"toggleStatus\",\"type\":\"bool\"}],\"name\":\"BridgeTokenToggled\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"theAddress\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"toggleStatus\",\"type\":\"uint256\"}],\"name\":\"FeeToggled\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"hourlyLimit\",\"type\":\"uint256\"}],\"name\":\"HourlyLimitUpdated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint8\",\"name\":\"version\",\"type\":\"uint8\"}],\"name\":\"Initialized\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"minter\",\"type\":\"address\"}],\"name\":\"MinterToggled\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"Recovered\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"}],\"name\":\"Transfer\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"_treasury\",\"type\":\"address\"}],\"name\":\"TreasuryUpdated\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"BASE_PARAMS\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"DOMAIN_SEPARATOR\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"bridgeToken\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"limit\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"hourlyLimit\",\"type\":\"uint256\"},{\"internalType\":\"uint64\",\"name\":\"fee\",\"type\":\"uint64\"},{\"internalType\":\"bool\",\"name\":\"paused\",\"type\":\"bool\"}],\"name\":\"addBridgeToken\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"minter\",\"type\":\"address\"}],\"name\":\"addMinter\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"allBridgeTokens\",\"outputs\":[{\"internalType\":\"address[]\",\"name\":\"\",\"type\":\"address[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"spender\",\"type\":\"address\"}],\"name\":\"allowance\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"spender\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"approve\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"}],\"name\":\"balanceOf\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"name\":\"bridgeTokensList\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"bridges\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"limit\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"hourlyLimit\",\"type\":\"uint256\"},{\"internalType\":\"uint64\",\"name\":\"fee\",\"type\":\"uint64\"},{\"internalType\":\"bool\",\"name\":\"allowed\",\"type\":\"bool\"},{\"internalType\":\"bool\",\"name\":\"paused\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"burner\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"}],\"name\":\"burnFrom\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"burner\",\"type\":\"address\"}],\"name\":\"burnSelf\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"burnStablecoin\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"chainTotalHourlyLimit\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"name\":\"chainTotalUsage\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"currentTotalUsage\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"bridgeToken\",\"type\":\"address\"}],\"name\":\"currentUsage\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"decimals\",\"outputs\":[{\"internalType\":\"uint8\",\"name\":\"\",\"type\":\"uint8\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"spender\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"subtractedValue\",\"type\":\"uint256\"}],\"name\":\"decreaseAllowance\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"spender\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"addedValue\",\"type\":\"uint256\"}],\"name\":\"increaseAllowance\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"string\",\"name\":\"name_\",\"type\":\"string\"},{\"internalType\":\"string\",\"name\":\"symbol_\",\"type\":\"string\"},{\"internalType\":\"address\",\"name\":\"_treasury\",\"type\":\"address\"}],\"name\":\"initialize\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"isFeeExempt\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"isMinter\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"mint\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"name\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"}],\"name\":\"nonces\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"spender\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"deadline\",\"type\":\"uint256\"},{\"internalType\":\"uint8\",\"name\":\"v\",\"type\":\"uint8\"},{\"internalType\":\"bytes32\",\"name\":\"r\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32\",\"name\":\"s\",\"type\":\"bytes32\"}],\"name\":\"permit\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"tokenAddress\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amountToRecover\",\"type\":\"uint256\"}],\"name\":\"recoverERC20\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"bridgeToken\",\"type\":\"address\"}],\"name\":\"removeBridgeToken\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"minter\",\"type\":\"address\"}],\"name\":\"removeMinter\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"hourlyLimit\",\"type\":\"uint256\"}],\"name\":\"setChainTotalHourlyLimit\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"bridgeToken\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"hourlyLimit\",\"type\":\"uint256\"}],\"name\":\"setHourlyLimit\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"bridgeToken\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"limit\",\"type\":\"uint256\"}],\"name\":\"setLimit\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"bridgeToken\",\"type\":\"address\"},{\"internalType\":\"uint64\",\"name\":\"fee\",\"type\":\"uint64\"}],\"name\":\"setSwapFee\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_treasury\",\"type\":\"address\"}],\"name\":\"setTreasury\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"bridgeToken\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"swapIn\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"bridgeToken\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"swapOut\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"symbol\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"bridgeToken\",\"type\":\"address\"}],\"name\":\"toggleBridge\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"theAddress\",\"type\":\"address\"}],\"name\":\"toggleFeesForAddress\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"totalSupply\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"transfer\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"transferFrom\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"treasury\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"name\":\"usage\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"}],\"devdoc\":{\"author\":\"Angle Labs, Inc.\",\"details\":\"This contract supports bridge tokens having a minting right on the stablecoin (also referred to as the canonical or the native token)\",\"kind\":\"dev\",\"methods\":{\"DOMAIN_SEPARATOR()\":{\"details\":\"See {IERC20Permit-DOMAIN_SEPARATOR}.\"},\"addBridgeToken(address,uint256,uint256,uint64,bool)\":{\"params\":{\"bridgeToken\":\"Bridge token to add: it should be a version of the stablecoin from another bridge\",\"fee\":\"Fee taken upon swapping for or against this token\",\"hourlyLimit\":\"Limit on the hourly volume for this bridge\",\"limit\":\"Limit on the balance of bridge token this contract could hold\",\"paused\":\"Whether swapping for this token should be paused or not\"}},\"addMinter(address)\":{\"details\":\"Zero address checks are performed directly in the `Treasury` contract\",\"params\":{\"minter\":\"Minter address to add\"}},\"allBridgeTokens()\":{\"details\":\"Helpful for UIs\"},\"allowance(address,address)\":{\"details\":\"See {IERC20-allowance}.\"},\"approve(address,uint256)\":{\"details\":\"See {IERC20-approve}. NOTE: If `amount` is the maximum `uint256`, the allowance is not updated on `transferFrom`. This is semantically equivalent to an infinite approval. Requirements: - `spender` cannot be the zero address.\"},\"balanceOf(address)\":{\"details\":\"See {IERC20-balanceOf}.\"},\"burnFrom(uint256,address,address)\":{\"details\":\"This method is to be called by a contract with the minter right after being requested to do so by a `sender` address willing to burn tokens from another `burner` addressThe method checks the allowance between the `sender` and the `burner`\",\"params\":{\"amount\":\"Amount of tokens to burn\",\"burner\":\"Address to burn from\",\"sender\":\"Address which requested the burn from `burner`\"}},\"burnSelf(uint256,address)\":{\"details\":\"This method is to be called by a contract with a minter right on the AgToken after being requested to do so by an address willing to burn tokens from its address\",\"params\":{\"amount\":\"Amount of tokens to burn\",\"burner\":\"Address to burn from\"}},\"burnStablecoin(uint256)\":{\"details\":\"This function can typically be called if there is a settlement mechanism to burn stablecoins\",\"params\":{\"amount\":\"Amount of stablecoins to burn\"}},\"currentTotalUsage()\":{\"details\":\"Helpful for UIs\"},\"currentUsage(address)\":{\"details\":\"Helpful for UIs\",\"params\":{\"bridgeToken\":\"Bridge used to mint\"}},\"decimals()\":{\"details\":\"Returns the number of decimals used to get its user representation. For example, if `decimals` equals `2`, a balance of `505` tokens should be displayed to a user as `5.05` (`505 / 10 ** 2`). Tokens usually opt for a value of 18, imitating the relationship between Ether and Wei. This is the value {ERC20} uses, unless this function is overridden; NOTE: This information is only used for _display_ purposes: it in no way affects any of the arithmetic of the contract, including {IERC20-balanceOf} and {IERC20-transfer}.\"},\"decreaseAllowance(address,uint256)\":{\"details\":\"Atomically decreases the allowance granted to `spender` by the caller. This is an alternative to {approve} that can be used as a mitigation for problems described in {IERC20-approve}. Emits an {Approval} event indicating the updated allowance. Requirements: - `spender` cannot be the zero address. - `spender` must have allowance for the caller of at least `subtractedValue`.\"},\"increaseAllowance(address,uint256)\":{\"details\":\"Atomically increases the allowance granted to `spender` by the caller. This is an alternative to {approve} that can be used as a mitigation for problems described in {IERC20-approve}. Emits an {Approval} event indicating the updated allowance. Requirements: - `spender` cannot be the zero address.\"},\"mint(address,uint256)\":{\"details\":\"The contracts allowed to issue agTokens are the `StableMaster` contract, `VaultManager` contracts associated to this stablecoin as well as the flash loan module (if activated) and potentially contracts whitelisted by governance\",\"params\":{\"account\":\"Address to mint to\",\"amount\":\"Amount to mint\"}},\"name()\":{\"details\":\"Returns the name of the token.\"},\"nonces(address)\":{\"details\":\"See {IERC20Permit-nonces}.\"},\"permit(address,address,uint256,uint256,uint8,bytes32,bytes32)\":{\"details\":\"See {IERC20Permit-permit}.\"},\"recoverERC20(address,address,uint256)\":{\"details\":\"Can be used to withdraw bridge tokens for them to be de-bridged on mainnet\"},\"removeBridgeToken(address)\":{\"params\":{\"bridgeToken\":\"Address of the bridge token to remove support for\"}},\"removeMinter(address)\":{\"details\":\"This function can also be called by a minter wishing to revoke itself\",\"params\":{\"minter\":\"Minter address to remove\"}},\"setTreasury(address)\":{\"params\":{\"_treasury\":\"New treasury address\"}},\"swapIn(address,uint256,address)\":{\"details\":\"Some fees may be taken by the protocol depending on the token used and on the address calling\",\"params\":{\"amount\":\"Amount of bridge tokens to send\",\"bridgeToken\":\"Bridge token to use to mint\",\"to\":\"Address to which the stablecoin should be sent\"},\"returns\":{\"_0\":\"Amount of the canonical stablecoin actually minted\"}},\"swapOut(address,uint256,address)\":{\"details\":\"Some fees may be taken by the protocol depending on the token used and on the address calling\",\"params\":{\"amount\":\"Amount of canonical tokens to burn\",\"bridgeToken\":\"Bridge token required\",\"to\":\"Address to which the bridge token should be sent\"},\"returns\":{\"_0\":\"Amount of bridge tokens actually sent back\"}},\"symbol()\":{\"details\":\"Returns the symbol of the token, usually a shorter version of the name.\"},\"totalSupply()\":{\"details\":\"See {IERC20-totalSupply}.\"},\"transfer(address,uint256)\":{\"details\":\"See {IERC20-transfer}. Requirements: - `to` cannot be the zero address. - the caller must have a balance of at least `amount`.\"},\"transferFrom(address,address,uint256)\":{\"details\":\"See {IERC20-transferFrom}. Emits an {Approval} event indicating the updated allowance. This is not required by the EIP. See the note at the beginning of {ERC20}. NOTE: Does not update the allowance if the current allowance is the maximum `uint256`. Requirements: - `from` and `to` cannot be the zero address. - `from` must have a balance of at least `amount`. - the caller must have allowance for ``from``'s tokens of at least `amount`.\"}},\"title\":\"AgTokenSideChainMultiBridge\",\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{\"BASE_PARAMS()\":{\"notice\":\"Base used for fee computation\"},\"addBridgeToken(address,uint256,uint256,uint64,bool)\":{\"notice\":\"Adds support for a bridge token\"},\"addMinter(address)\":{\"notice\":\"Adds a minter in the contract\"},\"allBridgeTokens()\":{\"notice\":\"Returns the list of all supported bridge tokens\"},\"bridgeTokensList(uint256)\":{\"notice\":\"List of all bridge tokens\"},\"bridges(address)\":{\"notice\":\"Maps a bridge token to data\"},\"burnFrom(uint256,address,address)\":{\"notice\":\"Burns `amount` tokens from a `burner` address after being asked to by `sender`\"},\"burnSelf(uint256,address)\":{\"notice\":\"Burns `amount` tokens from a `burner` address\"},\"burnStablecoin(uint256)\":{\"notice\":\"Allows anyone to burn stablecoins\"},\"chainTotalHourlyLimit()\":{\"notice\":\"Limit to the amount of tokens that can be sent from that chain to another chain\"},\"chainTotalUsage(uint256)\":{\"notice\":\"Usage per hour on that chain. Maps an hourly timestamp to the total volume swapped out on the chain\"},\"currentTotalUsage()\":{\"notice\":\"Returns the current total volume on the chain for the current hour\"},\"currentUsage(address)\":{\"notice\":\"Returns the current volume for a bridge, for the current hour\"},\"initialize(string,string,address)\":{\"notice\":\"Initializes the `AgToken` contract\"},\"isFeeExempt(address)\":{\"notice\":\"Maps an address to whether it is exempt of fees for when it comes to swapping in and out\"},\"isMinter(address)\":{\"notice\":\"Checks whether an address has the right to mint agTokens\"},\"mint(address,uint256)\":{\"notice\":\"Lets the `StableMaster` contract or another whitelisted contract mint agTokens\"},\"recoverERC20(address,address,uint256)\":{\"notice\":\"Recovers any ERC20 token\"},\"removeBridgeToken(address)\":{\"notice\":\"Removes support for a token\"},\"removeMinter(address)\":{\"notice\":\"Removes a minter from the contract\"},\"setChainTotalHourlyLimit(uint256)\":{\"notice\":\"Updates the `chainTotalHourlyLimit` amount\"},\"setHourlyLimit(address,uint256)\":{\"notice\":\"Updates the `hourlyLimit` amount for `bridgeToken`\"},\"setLimit(address,uint256)\":{\"notice\":\"Updates the `limit` amount for `bridgeToken`\"},\"setSwapFee(address,uint64)\":{\"notice\":\"Updates the `fee` value for `bridgeToken`\"},\"setTreasury(address)\":{\"notice\":\"Sets a new treasury contract\"},\"swapIn(address,uint256,address)\":{\"notice\":\"Mints the canonical token from a supported bridge token\"},\"swapOut(address,uint256,address)\":{\"notice\":\"Burns the canonical token in exchange for a bridge token\"},\"toggleBridge(address)\":{\"notice\":\"Pauses or unpauses swapping in and out for a token\"},\"toggleFeesForAddress(address)\":{\"notice\":\"Toggles fees for the address `theAddress`\"},\"treasury()\":{\"notice\":\"Reference to the treasury contract which can grant minting rights\"},\"usage(address,uint256)\":{\"notice\":\"Maps a bridge token to the associated hourly volume\"}},\"notice\":\"Contract for Angle agTokens on other chains than Ethereum mainnet\",\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/agToken/AgTokenSideChainMultiBridge.sol\":\"AgTokenSideChainMultiBridge\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":1000000},\"remappings\":[]},\"sources\":{\"@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.7.0) (proxy/utils/Initializable.sol)\\n\\npragma solidity ^0.8.2;\\n\\nimport \\\"../../utils/AddressUpgradeable.sol\\\";\\n\\n/**\\n * @dev This is a base contract to aid in writing upgradeable contracts, or any kind of contract that will be deployed\\n * behind a proxy. Since proxied contracts do not make use of a constructor, it's common to move constructor logic to an\\n * external initializer function, usually called `initialize`. It then becomes necessary to protect this initializer\\n * function so it can only be called once. The {initializer} modifier provided by this contract will have this effect.\\n *\\n * The initialization functions use a version number. Once a version number is used, it is consumed and cannot be\\n * reused. This mechanism prevents re-execution of each \\\"step\\\" but allows the creation of new initialization steps in\\n * case an upgrade adds a module that needs to be initialized.\\n *\\n * For example:\\n *\\n * [.hljs-theme-light.nopadding]\\n * ```\\n * contract MyToken is ERC20Upgradeable {\\n * function initialize() initializer public {\\n * __ERC20_init(\\\"MyToken\\\", \\\"MTK\\\");\\n * }\\n * }\\n * contract MyTokenV2 is MyToken, ERC20PermitUpgradeable {\\n * function initializeV2() reinitializer(2) public {\\n * __ERC20Permit_init(\\\"MyToken\\\");\\n * }\\n * }\\n * ```\\n *\\n * TIP: To avoid leaving the proxy in an uninitialized state, the initializer function should be called as early as\\n * possible by providing the encoded function call as the `_data` argument to {ERC1967Proxy-constructor}.\\n *\\n * CAUTION: When used with inheritance, manual care must be taken to not invoke a parent initializer twice, or to ensure\\n * that all initializers are idempotent. This is not verified automatically as constructors are by Solidity.\\n *\\n * [CAUTION]\\n * ====\\n * Avoid leaving a contract uninitialized.\\n *\\n * An uninitialized contract can be taken over by an attacker. This applies to both a proxy and its implementation\\n * contract, which may impact the proxy. To prevent the implementation contract from being used, you should invoke\\n * the {_disableInitializers} function in the constructor to automatically lock it when it is deployed:\\n *\\n * [.hljs-theme-light.nopadding]\\n * ```\\n * /// @custom:oz-upgrades-unsafe-allow constructor\\n * constructor() {\\n * _disableInitializers();\\n * }\\n * ```\\n * ====\\n */\\nabstract contract Initializable {\\n /**\\n * @dev Indicates that the contract has been initialized.\\n * @custom:oz-retyped-from bool\\n */\\n uint8 private _initialized;\\n\\n /**\\n * @dev Indicates that the contract is in the process of being initialized.\\n */\\n bool private _initializing;\\n\\n /**\\n * @dev Triggered when the contract has been initialized or reinitialized.\\n */\\n event Initialized(uint8 version);\\n\\n /**\\n * @dev A modifier that defines a protected initializer function that can be invoked at most once. In its scope,\\n * `onlyInitializing` functions can be used to initialize parent contracts. Equivalent to `reinitializer(1)`.\\n */\\n modifier initializer() {\\n bool isTopLevelCall = !_initializing;\\n require(\\n (isTopLevelCall && _initialized < 1) || (!AddressUpgradeable.isContract(address(this)) && _initialized == 1),\\n \\\"Initializable: contract is already initialized\\\"\\n );\\n _initialized = 1;\\n if (isTopLevelCall) {\\n _initializing = true;\\n }\\n _;\\n if (isTopLevelCall) {\\n _initializing = false;\\n emit Initialized(1);\\n }\\n }\\n\\n /**\\n * @dev A modifier that defines a protected reinitializer function that can be invoked at most once, and only if the\\n * contract hasn't been initialized to a greater version before. In its scope, `onlyInitializing` functions can be\\n * used to initialize parent contracts.\\n *\\n * `initializer` is equivalent to `reinitializer(1)`, so a reinitializer may be used after the original\\n * initialization step. This is essential to configure modules that are added through upgrades and that require\\n * initialization.\\n *\\n * Note that versions can jump in increments greater than 1; this implies that if multiple reinitializers coexist in\\n * a contract, executing them in the right order is up to the developer or operator.\\n */\\n modifier reinitializer(uint8 version) {\\n require(!_initializing && _initialized < version, \\\"Initializable: contract is already initialized\\\");\\n _initialized = version;\\n _initializing = true;\\n _;\\n _initializing = false;\\n emit Initialized(version);\\n }\\n\\n /**\\n * @dev Modifier to protect an initialization function so that it can only be invoked by functions with the\\n * {initializer} and {reinitializer} modifiers, directly or indirectly.\\n */\\n modifier onlyInitializing() {\\n require(_initializing, \\\"Initializable: contract is not initializing\\\");\\n _;\\n }\\n\\n /**\\n * @dev Locks the contract, preventing any future reinitialization. This cannot be part of an initializer call.\\n * Calling this in the constructor of a contract will prevent that contract from being initialized or reinitialized\\n * to any version. It is recommended to use this to lock implementation contracts that are designed to be called\\n * through proxies.\\n */\\n function _disableInitializers() internal virtual {\\n require(!_initializing, \\\"Initializable: contract is initializing\\\");\\n if (_initialized < type(uint8).max) {\\n _initialized = type(uint8).max;\\n emit Initialized(type(uint8).max);\\n }\\n }\\n}\\n\",\"keccak256\":\"0x0203dcadc5737d9ef2c211d6fa15d18ebc3b30dfa51903b64870b01a062b0b4e\",\"license\":\"MIT\"},\"@openzeppelin/contracts-upgradeable/token/ERC20/ERC20Upgradeable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.7.0) (token/ERC20/ERC20.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"./IERC20Upgradeable.sol\\\";\\nimport \\\"./extensions/IERC20MetadataUpgradeable.sol\\\";\\nimport \\\"../../utils/ContextUpgradeable.sol\\\";\\nimport \\\"../../proxy/utils/Initializable.sol\\\";\\n\\n/**\\n * @dev Implementation of the {IERC20} interface.\\n *\\n * This implementation is agnostic to the way tokens are created. This means\\n * that a supply mechanism has to be added in a derived contract using {_mint}.\\n * For a generic mechanism see {ERC20PresetMinterPauser}.\\n *\\n * TIP: For a detailed writeup see our guide\\n * https://forum.zeppelin.solutions/t/how-to-implement-erc20-supply-mechanisms/226[How\\n * to implement supply mechanisms].\\n *\\n * We have followed general OpenZeppelin Contracts guidelines: functions revert\\n * instead returning `false` on failure. This behavior is nonetheless\\n * conventional and does not conflict with the expectations of ERC20\\n * applications.\\n *\\n * Additionally, an {Approval} event is emitted on calls to {transferFrom}.\\n * This allows applications to reconstruct the allowance for all accounts just\\n * by listening to said events. Other implementations of the EIP may not emit\\n * these events, as it isn't required by the specification.\\n *\\n * Finally, the non-standard {decreaseAllowance} and {increaseAllowance}\\n * functions have been added to mitigate the well-known issues around setting\\n * allowances. See {IERC20-approve}.\\n */\\ncontract ERC20Upgradeable is Initializable, ContextUpgradeable, IERC20Upgradeable, IERC20MetadataUpgradeable {\\n mapping(address => uint256) private _balances;\\n\\n mapping(address => mapping(address => uint256)) private _allowances;\\n\\n uint256 private _totalSupply;\\n\\n string private _name;\\n string private _symbol;\\n\\n /**\\n * @dev Sets the values for {name} and {symbol}.\\n *\\n * The default value of {decimals} is 18. To select a different value for\\n * {decimals} you should overload it.\\n *\\n * All two of these values are immutable: they can only be set once during\\n * construction.\\n */\\n function __ERC20_init(string memory name_, string memory symbol_) internal onlyInitializing {\\n __ERC20_init_unchained(name_, symbol_);\\n }\\n\\n function __ERC20_init_unchained(string memory name_, string memory symbol_) internal onlyInitializing {\\n _name = name_;\\n _symbol = symbol_;\\n }\\n\\n /**\\n * @dev Returns the name of the token.\\n */\\n function name() public view virtual override returns (string memory) {\\n return _name;\\n }\\n\\n /**\\n * @dev Returns the symbol of the token, usually a shorter version of the\\n * name.\\n */\\n function symbol() public view virtual override returns (string memory) {\\n return _symbol;\\n }\\n\\n /**\\n * @dev Returns the number of decimals used to get its user representation.\\n * For example, if `decimals` equals `2`, a balance of `505` tokens should\\n * be displayed to a user as `5.05` (`505 / 10 ** 2`).\\n *\\n * Tokens usually opt for a value of 18, imitating the relationship between\\n * Ether and Wei. This is the value {ERC20} uses, unless this function is\\n * overridden;\\n *\\n * NOTE: This information is only used for _display_ purposes: it in\\n * no way affects any of the arithmetic of the contract, including\\n * {IERC20-balanceOf} and {IERC20-transfer}.\\n */\\n function decimals() public view virtual override returns (uint8) {\\n return 18;\\n }\\n\\n /**\\n * @dev See {IERC20-totalSupply}.\\n */\\n function totalSupply() public view virtual override returns (uint256) {\\n return _totalSupply;\\n }\\n\\n /**\\n * @dev See {IERC20-balanceOf}.\\n */\\n function balanceOf(address account) public view virtual override returns (uint256) {\\n return _balances[account];\\n }\\n\\n /**\\n * @dev See {IERC20-transfer}.\\n *\\n * Requirements:\\n *\\n * - `to` cannot be the zero address.\\n * - the caller must have a balance of at least `amount`.\\n */\\n function transfer(address to, uint256 amount) public virtual override returns (bool) {\\n address owner = _msgSender();\\n _transfer(owner, to, amount);\\n return true;\\n }\\n\\n /**\\n * @dev See {IERC20-allowance}.\\n */\\n function allowance(address owner, address spender) public view virtual override returns (uint256) {\\n return _allowances[owner][spender];\\n }\\n\\n /**\\n * @dev See {IERC20-approve}.\\n *\\n * NOTE: If `amount` is the maximum `uint256`, the allowance is not updated on\\n * `transferFrom`. This is semantically equivalent to an infinite approval.\\n *\\n * Requirements:\\n *\\n * - `spender` cannot be the zero address.\\n */\\n function approve(address spender, uint256 amount) public virtual override returns (bool) {\\n address owner = _msgSender();\\n _approve(owner, spender, amount);\\n return true;\\n }\\n\\n /**\\n * @dev See {IERC20-transferFrom}.\\n *\\n * Emits an {Approval} event indicating the updated allowance. This is not\\n * required by the EIP. See the note at the beginning of {ERC20}.\\n *\\n * NOTE: Does not update the allowance if the current allowance\\n * is the maximum `uint256`.\\n *\\n * Requirements:\\n *\\n * - `from` and `to` cannot be the zero address.\\n * - `from` must have a balance of at least `amount`.\\n * - the caller must have allowance for ``from``'s tokens of at least\\n * `amount`.\\n */\\n function transferFrom(\\n address from,\\n address to,\\n uint256 amount\\n ) public virtual override returns (bool) {\\n address spender = _msgSender();\\n _spendAllowance(from, spender, amount);\\n _transfer(from, to, amount);\\n return true;\\n }\\n\\n /**\\n * @dev Atomically increases the allowance granted to `spender` by the caller.\\n *\\n * This is an alternative to {approve} that can be used as a mitigation for\\n * problems described in {IERC20-approve}.\\n *\\n * Emits an {Approval} event indicating the updated allowance.\\n *\\n * Requirements:\\n *\\n * - `spender` cannot be the zero address.\\n */\\n function increaseAllowance(address spender, uint256 addedValue) public virtual returns (bool) {\\n address owner = _msgSender();\\n _approve(owner, spender, allowance(owner, spender) + addedValue);\\n return true;\\n }\\n\\n /**\\n * @dev Atomically decreases the allowance granted to `spender` by the caller.\\n *\\n * This is an alternative to {approve} that can be used as a mitigation for\\n * problems described in {IERC20-approve}.\\n *\\n * Emits an {Approval} event indicating the updated allowance.\\n *\\n * Requirements:\\n *\\n * - `spender` cannot be the zero address.\\n * - `spender` must have allowance for the caller of at least\\n * `subtractedValue`.\\n */\\n function decreaseAllowance(address spender, uint256 subtractedValue) public virtual returns (bool) {\\n address owner = _msgSender();\\n uint256 currentAllowance = allowance(owner, spender);\\n require(currentAllowance >= subtractedValue, \\\"ERC20: decreased allowance below zero\\\");\\n unchecked {\\n _approve(owner, spender, currentAllowance - subtractedValue);\\n }\\n\\n return true;\\n }\\n\\n /**\\n * @dev Moves `amount` of tokens from `from` to `to`.\\n *\\n * This internal function is equivalent to {transfer}, and can be used to\\n * e.g. implement automatic token fees, slashing mechanisms, etc.\\n *\\n * Emits a {Transfer} event.\\n *\\n * Requirements:\\n *\\n * - `from` cannot be the zero address.\\n * - `to` cannot be the zero address.\\n * - `from` must have a balance of at least `amount`.\\n */\\n function _transfer(\\n address from,\\n address to,\\n uint256 amount\\n ) internal virtual {\\n require(from != address(0), \\\"ERC20: transfer from the zero address\\\");\\n require(to != address(0), \\\"ERC20: transfer to the zero address\\\");\\n\\n _beforeTokenTransfer(from, to, amount);\\n\\n uint256 fromBalance = _balances[from];\\n require(fromBalance >= amount, \\\"ERC20: transfer amount exceeds balance\\\");\\n unchecked {\\n _balances[from] = fromBalance - amount;\\n }\\n _balances[to] += amount;\\n\\n emit Transfer(from, to, amount);\\n\\n _afterTokenTransfer(from, to, amount);\\n }\\n\\n /** @dev Creates `amount` tokens and assigns them to `account`, increasing\\n * the total supply.\\n *\\n * Emits a {Transfer} event with `from` set to the zero address.\\n *\\n * Requirements:\\n *\\n * - `account` cannot be the zero address.\\n */\\n function _mint(address account, uint256 amount) internal virtual {\\n require(account != address(0), \\\"ERC20: mint to the zero address\\\");\\n\\n _beforeTokenTransfer(address(0), account, amount);\\n\\n _totalSupply += amount;\\n _balances[account] += amount;\\n emit Transfer(address(0), account, amount);\\n\\n _afterTokenTransfer(address(0), account, amount);\\n }\\n\\n /**\\n * @dev Destroys `amount` tokens from `account`, reducing the\\n * total supply.\\n *\\n * Emits a {Transfer} event with `to` set to the zero address.\\n *\\n * Requirements:\\n *\\n * - `account` cannot be the zero address.\\n * - `account` must have at least `amount` tokens.\\n */\\n function _burn(address account, uint256 amount) internal virtual {\\n require(account != address(0), \\\"ERC20: burn from the zero address\\\");\\n\\n _beforeTokenTransfer(account, address(0), amount);\\n\\n uint256 accountBalance = _balances[account];\\n require(accountBalance >= amount, \\\"ERC20: burn amount exceeds balance\\\");\\n unchecked {\\n _balances[account] = accountBalance - amount;\\n }\\n _totalSupply -= amount;\\n\\n emit Transfer(account, address(0), amount);\\n\\n _afterTokenTransfer(account, address(0), amount);\\n }\\n\\n /**\\n * @dev Sets `amount` as the allowance of `spender` over the `owner` s tokens.\\n *\\n * This internal function is equivalent to `approve`, and can be used to\\n * e.g. set automatic allowances for certain subsystems, etc.\\n *\\n * Emits an {Approval} event.\\n *\\n * Requirements:\\n *\\n * - `owner` cannot be the zero address.\\n * - `spender` cannot be the zero address.\\n */\\n function _approve(\\n address owner,\\n address spender,\\n uint256 amount\\n ) internal virtual {\\n require(owner != address(0), \\\"ERC20: approve from the zero address\\\");\\n require(spender != address(0), \\\"ERC20: approve to the zero address\\\");\\n\\n _allowances[owner][spender] = amount;\\n emit Approval(owner, spender, amount);\\n }\\n\\n /**\\n * @dev Updates `owner` s allowance for `spender` based on spent `amount`.\\n *\\n * Does not update the allowance amount in case of infinite allowance.\\n * Revert if not enough allowance is available.\\n *\\n * Might emit an {Approval} event.\\n */\\n function _spendAllowance(\\n address owner,\\n address spender,\\n uint256 amount\\n ) internal virtual {\\n uint256 currentAllowance = allowance(owner, spender);\\n if (currentAllowance != type(uint256).max) {\\n require(currentAllowance >= amount, \\\"ERC20: insufficient allowance\\\");\\n unchecked {\\n _approve(owner, spender, currentAllowance - amount);\\n }\\n }\\n }\\n\\n /**\\n * @dev Hook that is called before any transfer of tokens. This includes\\n * minting and burning.\\n *\\n * Calling conditions:\\n *\\n * - when `from` and `to` are both non-zero, `amount` of ``from``'s tokens\\n * will be transferred to `to`.\\n * - when `from` is zero, `amount` tokens will be minted for `to`.\\n * - when `to` is zero, `amount` of ``from``'s tokens will be burned.\\n * - `from` and `to` are never both zero.\\n *\\n * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].\\n */\\n function _beforeTokenTransfer(\\n address from,\\n address to,\\n uint256 amount\\n ) internal virtual {}\\n\\n /**\\n * @dev Hook that is called after any transfer of tokens. This includes\\n * minting and burning.\\n *\\n * Calling conditions:\\n *\\n * - when `from` and `to` are both non-zero, `amount` of ``from``'s tokens\\n * has been transferred to `to`.\\n * - when `from` is zero, `amount` tokens have been minted for `to`.\\n * - when `to` is zero, `amount` of ``from``'s tokens have been burned.\\n * - `from` and `to` are never both zero.\\n *\\n * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].\\n */\\n function _afterTokenTransfer(\\n address from,\\n address to,\\n uint256 amount\\n ) internal virtual {}\\n\\n /**\\n * @dev This empty reserved space is put in place to allow future versions to add new\\n * variables without shifting down storage in the inheritance chain.\\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\\n */\\n uint256[45] private __gap;\\n}\\n\",\"keccak256\":\"0x7c7ac0bc6c340a7f320524b9a4b4b079ee9da3c51258080d4bab237f329a427c\",\"license\":\"MIT\"},\"@openzeppelin/contracts-upgradeable/token/ERC20/IERC20Upgradeable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.6.0) (token/ERC20/IERC20.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Interface of the ERC20 standard as defined in the EIP.\\n */\\ninterface IERC20Upgradeable {\\n /**\\n * @dev Emitted when `value` tokens are moved from one account (`from`) to\\n * another (`to`).\\n *\\n * Note that `value` may be zero.\\n */\\n event Transfer(address indexed from, address indexed to, uint256 value);\\n\\n /**\\n * @dev Emitted when the allowance of a `spender` for an `owner` is set by\\n * a call to {approve}. `value` is the new allowance.\\n */\\n event Approval(address indexed owner, address indexed spender, uint256 value);\\n\\n /**\\n * @dev Returns the amount of tokens in existence.\\n */\\n function totalSupply() external view returns (uint256);\\n\\n /**\\n * @dev Returns the amount of tokens owned by `account`.\\n */\\n function balanceOf(address account) external view returns (uint256);\\n\\n /**\\n * @dev Moves `amount` tokens from the caller's account to `to`.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * Emits a {Transfer} event.\\n */\\n function transfer(address to, uint256 amount) external returns (bool);\\n\\n /**\\n * @dev Returns the remaining number of tokens that `spender` will be\\n * allowed to spend on behalf of `owner` through {transferFrom}. This is\\n * zero by default.\\n *\\n * This value changes when {approve} or {transferFrom} are called.\\n */\\n function allowance(address owner, address spender) external view returns (uint256);\\n\\n /**\\n * @dev Sets `amount` as the allowance of `spender` over the caller's tokens.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * IMPORTANT: Beware that changing an allowance with this method brings the risk\\n * that someone may use both the old and the new allowance by unfortunate\\n * transaction ordering. One possible solution to mitigate this race\\n * condition is to first reduce the spender's allowance to 0 and set the\\n * desired value afterwards:\\n * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729\\n *\\n * Emits an {Approval} event.\\n */\\n function approve(address spender, uint256 amount) external returns (bool);\\n\\n /**\\n * @dev Moves `amount` tokens from `from` to `to` using the\\n * allowance mechanism. `amount` is then deducted from the caller's\\n * allowance.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * Emits a {Transfer} event.\\n */\\n function transferFrom(\\n address from,\\n address to,\\n uint256 amount\\n ) external returns (bool);\\n}\\n\",\"keccak256\":\"0x4e733d3164f73f461eaf9d8087a7ad1ea180bdc8ba0d3d61b0e1ae16d8e63dff\",\"license\":\"MIT\"},\"@openzeppelin/contracts-upgradeable/token/ERC20/extensions/IERC20MetadataUpgradeable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (token/ERC20/extensions/IERC20Metadata.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../IERC20Upgradeable.sol\\\";\\n\\n/**\\n * @dev Interface for the optional metadata functions from the ERC20 standard.\\n *\\n * _Available since v4.1._\\n */\\ninterface IERC20MetadataUpgradeable is IERC20Upgradeable {\\n /**\\n * @dev Returns the name of the token.\\n */\\n function name() external view returns (string memory);\\n\\n /**\\n * @dev Returns the symbol of the token.\\n */\\n function symbol() external view returns (string memory);\\n\\n /**\\n * @dev Returns the decimals places of the token.\\n */\\n function decimals() external view returns (uint8);\\n}\\n\",\"keccak256\":\"0x605434219ebbe4653f703640f06969faa5a1d78f0bfef878e5ddbb1ca369ceeb\",\"license\":\"MIT\"},\"@openzeppelin/contracts-upgradeable/token/ERC20/extensions/draft-ERC20PermitUpgradeable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.6.0) (token/ERC20/extensions/draft-ERC20Permit.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"./draft-IERC20PermitUpgradeable.sol\\\";\\nimport \\\"../ERC20Upgradeable.sol\\\";\\nimport \\\"../../../utils/cryptography/draft-EIP712Upgradeable.sol\\\";\\nimport \\\"../../../utils/cryptography/ECDSAUpgradeable.sol\\\";\\nimport \\\"../../../utils/CountersUpgradeable.sol\\\";\\nimport \\\"../../../proxy/utils/Initializable.sol\\\";\\n\\n/**\\n * @dev Implementation of the ERC20 Permit extension allowing approvals to be made via signatures, as defined in\\n * https://eips.ethereum.org/EIPS/eip-2612[EIP-2612].\\n *\\n * Adds the {permit} method, which can be used to change an account's ERC20 allowance (see {IERC20-allowance}) by\\n * presenting a message signed by the account. By not relying on `{IERC20-approve}`, the token holder account doesn't\\n * need to send a transaction, and thus is not required to hold Ether at all.\\n *\\n * _Available since v3.4._\\n *\\n * @custom:storage-size 51\\n */\\nabstract contract ERC20PermitUpgradeable is Initializable, ERC20Upgradeable, IERC20PermitUpgradeable, EIP712Upgradeable {\\n using CountersUpgradeable for CountersUpgradeable.Counter;\\n\\n mapping(address => CountersUpgradeable.Counter) private _nonces;\\n\\n // solhint-disable-next-line var-name-mixedcase\\n bytes32 private constant _PERMIT_TYPEHASH =\\n keccak256(\\\"Permit(address owner,address spender,uint256 value,uint256 nonce,uint256 deadline)\\\");\\n /**\\n * @dev In previous versions `_PERMIT_TYPEHASH` was declared as `immutable`.\\n * However, to ensure consistency with the upgradeable transpiler, we will continue\\n * to reserve a slot.\\n * @custom:oz-renamed-from _PERMIT_TYPEHASH\\n */\\n // solhint-disable-next-line var-name-mixedcase\\n bytes32 private _PERMIT_TYPEHASH_DEPRECATED_SLOT;\\n\\n /**\\n * @dev Initializes the {EIP712} domain separator using the `name` parameter, and setting `version` to `\\\"1\\\"`.\\n *\\n * It's a good idea to use the same `name` that is defined as the ERC20 token name.\\n */\\n function __ERC20Permit_init(string memory name) internal onlyInitializing {\\n __EIP712_init_unchained(name, \\\"1\\\");\\n }\\n\\n function __ERC20Permit_init_unchained(string memory) internal onlyInitializing {}\\n\\n /**\\n * @dev See {IERC20Permit-permit}.\\n */\\n function permit(\\n address owner,\\n address spender,\\n uint256 value,\\n uint256 deadline,\\n uint8 v,\\n bytes32 r,\\n bytes32 s\\n ) public virtual override {\\n require(block.timestamp <= deadline, \\\"ERC20Permit: expired deadline\\\");\\n\\n bytes32 structHash = keccak256(abi.encode(_PERMIT_TYPEHASH, owner, spender, value, _useNonce(owner), deadline));\\n\\n bytes32 hash = _hashTypedDataV4(structHash);\\n\\n address signer = ECDSAUpgradeable.recover(hash, v, r, s);\\n require(signer == owner, \\\"ERC20Permit: invalid signature\\\");\\n\\n _approve(owner, spender, value);\\n }\\n\\n /**\\n * @dev See {IERC20Permit-nonces}.\\n */\\n function nonces(address owner) public view virtual override returns (uint256) {\\n return _nonces[owner].current();\\n }\\n\\n /**\\n * @dev See {IERC20Permit-DOMAIN_SEPARATOR}.\\n */\\n // solhint-disable-next-line func-name-mixedcase\\n function DOMAIN_SEPARATOR() external view override returns (bytes32) {\\n return _domainSeparatorV4();\\n }\\n\\n /**\\n * @dev \\\"Consume a nonce\\\": return the current value and increment.\\n *\\n * _Available since v4.1._\\n */\\n function _useNonce(address owner) internal virtual returns (uint256 current) {\\n CountersUpgradeable.Counter storage nonce = _nonces[owner];\\n current = nonce.current();\\n nonce.increment();\\n }\\n\\n /**\\n * @dev This empty reserved space is put in place to allow future versions to add new\\n * variables without shifting down storage in the inheritance chain.\\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\\n */\\n uint256[49] private __gap;\\n}\\n\",\"keccak256\":\"0x564385ebed633694decce3e13d687f3ac7e8eaef64f7a504bfb3f03ad210601f\",\"license\":\"MIT\"},\"@openzeppelin/contracts-upgradeable/token/ERC20/extensions/draft-IERC20PermitUpgradeable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (token/ERC20/extensions/draft-IERC20Permit.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Interface of the ERC20 Permit extension allowing approvals to be made via signatures, as defined in\\n * https://eips.ethereum.org/EIPS/eip-2612[EIP-2612].\\n *\\n * Adds the {permit} method, which can be used to change an account's ERC20 allowance (see {IERC20-allowance}) by\\n * presenting a message signed by the account. By not relying on {IERC20-approve}, the token holder account doesn't\\n * need to send a transaction, and thus is not required to hold Ether at all.\\n */\\ninterface IERC20PermitUpgradeable {\\n /**\\n * @dev Sets `value` as the allowance of `spender` over ``owner``'s tokens,\\n * given ``owner``'s signed approval.\\n *\\n * IMPORTANT: The same issues {IERC20-approve} has related to transaction\\n * ordering also apply here.\\n *\\n * Emits an {Approval} event.\\n *\\n * Requirements:\\n *\\n * - `spender` cannot be the zero address.\\n * - `deadline` must be a timestamp in the future.\\n * - `v`, `r` and `s` must be a valid `secp256k1` signature from `owner`\\n * over the EIP712-formatted function arguments.\\n * - the signature must use ``owner``'s current nonce (see {nonces}).\\n *\\n * For more information on the signature format, see the\\n * https://eips.ethereum.org/EIPS/eip-2612#specification[relevant EIP\\n * section].\\n */\\n function permit(\\n address owner,\\n address spender,\\n uint256 value,\\n uint256 deadline,\\n uint8 v,\\n bytes32 r,\\n bytes32 s\\n ) external;\\n\\n /**\\n * @dev Returns the current nonce for `owner`. This value must be\\n * included whenever a signature is generated for {permit}.\\n *\\n * Every successful call to {permit} increases ``owner``'s nonce by one. This\\n * prevents a signature from being used multiple times.\\n */\\n function nonces(address owner) external view returns (uint256);\\n\\n /**\\n * @dev Returns the domain separator used in the encoding of the signature for {permit}, as defined by {EIP712}.\\n */\\n // solhint-disable-next-line func-name-mixedcase\\n function DOMAIN_SEPARATOR() external view returns (bytes32);\\n}\\n\",\"keccak256\":\"0xcc70d8e2281fb3ff69e8ab242500f10142cd0a7fa8dd9e45882be270d4d09024\",\"license\":\"MIT\"},\"@openzeppelin/contracts-upgradeable/utils/AddressUpgradeable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.7.0) (utils/Address.sol)\\n\\npragma solidity ^0.8.1;\\n\\n/**\\n * @dev Collection of functions related to the address type\\n */\\nlibrary AddressUpgradeable {\\n /**\\n * @dev Returns true if `account` is a contract.\\n *\\n * [IMPORTANT]\\n * ====\\n * It is unsafe to assume that an address for which this function returns\\n * false is an externally-owned account (EOA) and not a contract.\\n *\\n * Among others, `isContract` will return false for the following\\n * types of addresses:\\n *\\n * - an externally-owned account\\n * - a contract in construction\\n * - an address where a contract will be created\\n * - an address where a contract lived, but was destroyed\\n * ====\\n *\\n * [IMPORTANT]\\n * ====\\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\\n *\\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\\n * constructor.\\n * ====\\n */\\n function isContract(address account) internal view returns (bool) {\\n // This method relies on extcodesize/address.code.length, which returns 0\\n // for contracts in construction, since the code is only stored at the end\\n // of the constructor execution.\\n\\n return account.code.length > 0;\\n }\\n\\n /**\\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\\n * `recipient`, forwarding all available gas and reverting on errors.\\n *\\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\\n * imposed by `transfer`, making them unable to receive funds via\\n * `transfer`. {sendValue} removes this limitation.\\n *\\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\\n *\\n * IMPORTANT: because control is transferred to `recipient`, care must be\\n * taken to not create reentrancy vulnerabilities. Consider using\\n * {ReentrancyGuard} or the\\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\\n */\\n function sendValue(address payable recipient, uint256 amount) internal {\\n require(address(this).balance >= amount, \\\"Address: insufficient balance\\\");\\n\\n (bool success, ) = recipient.call{value: amount}(\\\"\\\");\\n require(success, \\\"Address: unable to send value, recipient may have reverted\\\");\\n }\\n\\n /**\\n * @dev Performs a Solidity function call using a low level `call`. A\\n * plain `call` is an unsafe replacement for a function call: use this\\n * function instead.\\n *\\n * If `target` reverts with a revert reason, it is bubbled up by this\\n * function (like regular Solidity function calls).\\n *\\n * Returns the raw returned data. To convert to the expected return value,\\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\\n *\\n * Requirements:\\n *\\n * - `target` must be a contract.\\n * - calling `target` with `data` must not revert.\\n *\\n * _Available since v3.1._\\n */\\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\\n return functionCall(target, data, \\\"Address: low-level call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\\n * `errorMessage` as a fallback revert reason when `target` reverts.\\n *\\n * _Available since v3.1._\\n */\\n function functionCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n return functionCallWithValue(target, data, 0, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but also transferring `value` wei to `target`.\\n *\\n * Requirements:\\n *\\n * - the calling contract must have an ETH balance of at least `value`.\\n * - the called Solidity function must be `payable`.\\n *\\n * _Available since v3.1._\\n */\\n function functionCallWithValue(\\n address target,\\n bytes memory data,\\n uint256 value\\n ) internal returns (bytes memory) {\\n return functionCallWithValue(target, data, value, \\\"Address: low-level call with value failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\\n * with `errorMessage` as a fallback revert reason when `target` reverts.\\n *\\n * _Available since v3.1._\\n */\\n function functionCallWithValue(\\n address target,\\n bytes memory data,\\n uint256 value,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n require(address(this).balance >= value, \\\"Address: insufficient balance for call\\\");\\n require(isContract(target), \\\"Address: call to non-contract\\\");\\n\\n (bool success, bytes memory returndata) = target.call{value: value}(data);\\n return verifyCallResult(success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but performing a static call.\\n *\\n * _Available since v3.3._\\n */\\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\\n return functionStaticCall(target, data, \\\"Address: low-level static call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\\n * but performing a static call.\\n *\\n * _Available since v3.3._\\n */\\n function functionStaticCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal view returns (bytes memory) {\\n require(isContract(target), \\\"Address: static call to non-contract\\\");\\n\\n (bool success, bytes memory returndata) = target.staticcall(data);\\n return verifyCallResult(success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the\\n * revert reason using the provided one.\\n *\\n * _Available since v4.3._\\n */\\n function verifyCallResult(\\n bool success,\\n bytes memory returndata,\\n string memory errorMessage\\n ) internal pure returns (bytes memory) {\\n if (success) {\\n return returndata;\\n } else {\\n // Look for revert reason and bubble it up if present\\n if (returndata.length > 0) {\\n // The easiest way to bubble the revert reason is using memory via assembly\\n /// @solidity memory-safe-assembly\\n assembly {\\n let returndata_size := mload(returndata)\\n revert(add(32, returndata), returndata_size)\\n }\\n } else {\\n revert(errorMessage);\\n }\\n }\\n }\\n}\\n\",\"keccak256\":\"0x611aa3f23e59cfdd1863c536776407b3e33d695152a266fa7cfb34440a29a8a3\",\"license\":\"MIT\"},\"@openzeppelin/contracts-upgradeable/utils/ContextUpgradeable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)\\n\\npragma solidity ^0.8.0;\\nimport \\\"../proxy/utils/Initializable.sol\\\";\\n\\n/**\\n * @dev Provides information about the current execution context, including the\\n * sender of the transaction and its data. While these are generally available\\n * via msg.sender and msg.data, they should not be accessed in such a direct\\n * manner, since when dealing with meta-transactions the account sending and\\n * paying for execution may not be the actual sender (as far as an application\\n * is concerned).\\n *\\n * This contract is only required for intermediate, library-like contracts.\\n */\\nabstract contract ContextUpgradeable is Initializable {\\n function __Context_init() internal onlyInitializing {\\n }\\n\\n function __Context_init_unchained() internal onlyInitializing {\\n }\\n function _msgSender() internal view virtual returns (address) {\\n return msg.sender;\\n }\\n\\n function _msgData() internal view virtual returns (bytes calldata) {\\n return msg.data;\\n }\\n\\n /**\\n * @dev This empty reserved space is put in place to allow future versions to add new\\n * variables without shifting down storage in the inheritance chain.\\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\\n */\\n uint256[50] private __gap;\\n}\\n\",\"keccak256\":\"0x963ea7f0b48b032eef72fe3a7582edf78408d6f834115b9feadd673a4d5bd149\",\"license\":\"MIT\"},\"@openzeppelin/contracts-upgradeable/utils/CountersUpgradeable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (utils/Counters.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @title Counters\\n * @author Matt Condon (@shrugs)\\n * @dev Provides counters that can only be incremented, decremented or reset. This can be used e.g. to track the number\\n * of elements in a mapping, issuing ERC721 ids, or counting request ids.\\n *\\n * Include with `using Counters for Counters.Counter;`\\n */\\nlibrary CountersUpgradeable {\\n struct Counter {\\n // This variable should never be directly accessed by users of the library: interactions must be restricted to\\n // the library's function. As of Solidity v0.5.2, this cannot be enforced, though there is a proposal to add\\n // this feature: see https://github.com/ethereum/solidity/issues/4637\\n uint256 _value; // default: 0\\n }\\n\\n function current(Counter storage counter) internal view returns (uint256) {\\n return counter._value;\\n }\\n\\n function increment(Counter storage counter) internal {\\n unchecked {\\n counter._value += 1;\\n }\\n }\\n\\n function decrement(Counter storage counter) internal {\\n uint256 value = counter._value;\\n require(value > 0, \\\"Counter: decrement overflow\\\");\\n unchecked {\\n counter._value = value - 1;\\n }\\n }\\n\\n function reset(Counter storage counter) internal {\\n counter._value = 0;\\n }\\n}\\n\",\"keccak256\":\"0x798741e231b22b81e2dd2eddaaf8832dee4baf5cd8e2dbaa5c1dd12a1c053c4d\",\"license\":\"MIT\"},\"@openzeppelin/contracts-upgradeable/utils/StringsUpgradeable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.7.0) (utils/Strings.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev String operations.\\n */\\nlibrary StringsUpgradeable {\\n bytes16 private constant _HEX_SYMBOLS = \\\"0123456789abcdef\\\";\\n uint8 private constant _ADDRESS_LENGTH = 20;\\n\\n /**\\n * @dev Converts a `uint256` to its ASCII `string` decimal representation.\\n */\\n function toString(uint256 value) internal pure returns (string memory) {\\n // Inspired by OraclizeAPI's implementation - MIT licence\\n // https://github.com/oraclize/ethereum-api/blob/b42146b063c7d6ee1358846c198246239e9360e8/oraclizeAPI_0.4.25.sol\\n\\n if (value == 0) {\\n return \\\"0\\\";\\n }\\n uint256 temp = value;\\n uint256 digits;\\n while (temp != 0) {\\n digits++;\\n temp /= 10;\\n }\\n bytes memory buffer = new bytes(digits);\\n while (value != 0) {\\n digits -= 1;\\n buffer[digits] = bytes1(uint8(48 + uint256(value % 10)));\\n value /= 10;\\n }\\n return string(buffer);\\n }\\n\\n /**\\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation.\\n */\\n function toHexString(uint256 value) internal pure returns (string memory) {\\n if (value == 0) {\\n return \\\"0x00\\\";\\n }\\n uint256 temp = value;\\n uint256 length = 0;\\n while (temp != 0) {\\n length++;\\n temp >>= 8;\\n }\\n return toHexString(value, length);\\n }\\n\\n /**\\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length.\\n */\\n function toHexString(uint256 value, uint256 length) internal pure returns (string memory) {\\n bytes memory buffer = new bytes(2 * length + 2);\\n buffer[0] = \\\"0\\\";\\n buffer[1] = \\\"x\\\";\\n for (uint256 i = 2 * length + 1; i > 1; --i) {\\n buffer[i] = _HEX_SYMBOLS[value & 0xf];\\n value >>= 4;\\n }\\n require(value == 0, \\\"Strings: hex length insufficient\\\");\\n return string(buffer);\\n }\\n\\n /**\\n * @dev Converts an `address` with fixed length of 20 bytes to its not checksummed ASCII `string` hexadecimal representation.\\n */\\n function toHexString(address addr) internal pure returns (string memory) {\\n return toHexString(uint256(uint160(addr)), _ADDRESS_LENGTH);\\n }\\n}\\n\",\"keccak256\":\"0xea5339a7fff0ed42b45be56a88efdd0b2ddde9fa480dc99fef9a6a4c5b776863\",\"license\":\"MIT\"},\"@openzeppelin/contracts-upgradeable/utils/cryptography/ECDSAUpgradeable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.7.0) (utils/cryptography/ECDSA.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../StringsUpgradeable.sol\\\";\\n\\n/**\\n * @dev Elliptic Curve Digital Signature Algorithm (ECDSA) operations.\\n *\\n * These functions can be used to verify that a message was signed by the holder\\n * of the private keys of a given address.\\n */\\nlibrary ECDSAUpgradeable {\\n enum RecoverError {\\n NoError,\\n InvalidSignature,\\n InvalidSignatureLength,\\n InvalidSignatureS,\\n InvalidSignatureV\\n }\\n\\n function _throwError(RecoverError error) private pure {\\n if (error == RecoverError.NoError) {\\n return; // no error: do nothing\\n } else if (error == RecoverError.InvalidSignature) {\\n revert(\\\"ECDSA: invalid signature\\\");\\n } else if (error == RecoverError.InvalidSignatureLength) {\\n revert(\\\"ECDSA: invalid signature length\\\");\\n } else if (error == RecoverError.InvalidSignatureS) {\\n revert(\\\"ECDSA: invalid signature 's' value\\\");\\n } else if (error == RecoverError.InvalidSignatureV) {\\n revert(\\\"ECDSA: invalid signature 'v' value\\\");\\n }\\n }\\n\\n /**\\n * @dev Returns the address that signed a hashed message (`hash`) with\\n * `signature` or error string. This address can then be used for verification purposes.\\n *\\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\\n * this function rejects them by requiring the `s` value to be in the lower\\n * half order, and the `v` value to be either 27 or 28.\\n *\\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\\n * verification to be secure: it is possible to craft signatures that\\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\\n * this is by receiving a hash of the original message (which may otherwise\\n * be too long), and then calling {toEthSignedMessageHash} on it.\\n *\\n * Documentation for signature generation:\\n * - with https://web3js.readthedocs.io/en/v1.3.4/web3-eth-accounts.html#sign[Web3.js]\\n * - with https://docs.ethers.io/v5/api/signer/#Signer-signMessage[ethers]\\n *\\n * _Available since v4.3._\\n */\\n function tryRecover(bytes32 hash, bytes memory signature) internal pure returns (address, RecoverError) {\\n // Check the signature length\\n // - case 65: r,s,v signature (standard)\\n // - case 64: r,vs signature (cf https://eips.ethereum.org/EIPS/eip-2098) _Available since v4.1._\\n if (signature.length == 65) {\\n bytes32 r;\\n bytes32 s;\\n uint8 v;\\n // ecrecover takes the signature parameters, and the only way to get them\\n // currently is to use assembly.\\n /// @solidity memory-safe-assembly\\n assembly {\\n r := mload(add(signature, 0x20))\\n s := mload(add(signature, 0x40))\\n v := byte(0, mload(add(signature, 0x60)))\\n }\\n return tryRecover(hash, v, r, s);\\n } else if (signature.length == 64) {\\n bytes32 r;\\n bytes32 vs;\\n // ecrecover takes the signature parameters, and the only way to get them\\n // currently is to use assembly.\\n /// @solidity memory-safe-assembly\\n assembly {\\n r := mload(add(signature, 0x20))\\n vs := mload(add(signature, 0x40))\\n }\\n return tryRecover(hash, r, vs);\\n } else {\\n return (address(0), RecoverError.InvalidSignatureLength);\\n }\\n }\\n\\n /**\\n * @dev Returns the address that signed a hashed message (`hash`) with\\n * `signature`. This address can then be used for verification purposes.\\n *\\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\\n * this function rejects them by requiring the `s` value to be in the lower\\n * half order, and the `v` value to be either 27 or 28.\\n *\\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\\n * verification to be secure: it is possible to craft signatures that\\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\\n * this is by receiving a hash of the original message (which may otherwise\\n * be too long), and then calling {toEthSignedMessageHash} on it.\\n */\\n function recover(bytes32 hash, bytes memory signature) internal pure returns (address) {\\n (address recovered, RecoverError error) = tryRecover(hash, signature);\\n _throwError(error);\\n return recovered;\\n }\\n\\n /**\\n * @dev Overload of {ECDSA-tryRecover} that receives the `r` and `vs` short-signature fields separately.\\n *\\n * See https://eips.ethereum.org/EIPS/eip-2098[EIP-2098 short signatures]\\n *\\n * _Available since v4.3._\\n */\\n function tryRecover(\\n bytes32 hash,\\n bytes32 r,\\n bytes32 vs\\n ) internal pure returns (address, RecoverError) {\\n bytes32 s = vs & bytes32(0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff);\\n uint8 v = uint8((uint256(vs) >> 255) + 27);\\n return tryRecover(hash, v, r, s);\\n }\\n\\n /**\\n * @dev Overload of {ECDSA-recover} that receives the `r and `vs` short-signature fields separately.\\n *\\n * _Available since v4.2._\\n */\\n function recover(\\n bytes32 hash,\\n bytes32 r,\\n bytes32 vs\\n ) internal pure returns (address) {\\n (address recovered, RecoverError error) = tryRecover(hash, r, vs);\\n _throwError(error);\\n return recovered;\\n }\\n\\n /**\\n * @dev Overload of {ECDSA-tryRecover} that receives the `v`,\\n * `r` and `s` signature fields separately.\\n *\\n * _Available since v4.3._\\n */\\n function tryRecover(\\n bytes32 hash,\\n uint8 v,\\n bytes32 r,\\n bytes32 s\\n ) internal pure returns (address, RecoverError) {\\n // EIP-2 still allows signature malleability for ecrecover(). Remove this possibility and make the signature\\n // unique. Appendix F in the Ethereum Yellow paper (https://ethereum.github.io/yellowpaper/paper.pdf), defines\\n // the valid range for s in (301): 0 < s < secp256k1n \\u00f7 2 + 1, and for v in (302): v \\u2208 {27, 28}. Most\\n // signatures from current libraries generate a unique signature with an s-value in the lower half order.\\n //\\n // If your library generates malleable signatures, such as s-values in the upper range, calculate a new s-value\\n // with 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141 - s1 and flip v from 27 to 28 or\\n // vice versa. If your library also generates signatures with 0/1 for v instead 27/28, add 27 to v to accept\\n // these malleable signatures as well.\\n if (uint256(s) > 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D576E7357A4501DDFE92F46681B20A0) {\\n return (address(0), RecoverError.InvalidSignatureS);\\n }\\n if (v != 27 && v != 28) {\\n return (address(0), RecoverError.InvalidSignatureV);\\n }\\n\\n // If the signature is valid (and not malleable), return the signer address\\n address signer = ecrecover(hash, v, r, s);\\n if (signer == address(0)) {\\n return (address(0), RecoverError.InvalidSignature);\\n }\\n\\n return (signer, RecoverError.NoError);\\n }\\n\\n /**\\n * @dev Overload of {ECDSA-recover} that receives the `v`,\\n * `r` and `s` signature fields separately.\\n */\\n function recover(\\n bytes32 hash,\\n uint8 v,\\n bytes32 r,\\n bytes32 s\\n ) internal pure returns (address) {\\n (address recovered, RecoverError error) = tryRecover(hash, v, r, s);\\n _throwError(error);\\n return recovered;\\n }\\n\\n /**\\n * @dev Returns an Ethereum Signed Message, created from a `hash`. This\\n * produces hash corresponding to the one signed with the\\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\\n * JSON-RPC method as part of EIP-191.\\n *\\n * See {recover}.\\n */\\n function toEthSignedMessageHash(bytes32 hash) internal pure returns (bytes32) {\\n // 32 is the length in bytes of hash,\\n // enforced by the type signature above\\n return keccak256(abi.encodePacked(\\\"\\\\x19Ethereum Signed Message:\\\\n32\\\", hash));\\n }\\n\\n /**\\n * @dev Returns an Ethereum Signed Message, created from `s`. This\\n * produces hash corresponding to the one signed with the\\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\\n * JSON-RPC method as part of EIP-191.\\n *\\n * See {recover}.\\n */\\n function toEthSignedMessageHash(bytes memory s) internal pure returns (bytes32) {\\n return keccak256(abi.encodePacked(\\\"\\\\x19Ethereum Signed Message:\\\\n\\\", StringsUpgradeable.toString(s.length), s));\\n }\\n\\n /**\\n * @dev Returns an Ethereum Signed Typed Data, created from a\\n * `domainSeparator` and a `structHash`. This produces hash corresponding\\n * to the one signed with the\\n * https://eips.ethereum.org/EIPS/eip-712[`eth_signTypedData`]\\n * JSON-RPC method as part of EIP-712.\\n *\\n * See {recover}.\\n */\\n function toTypedDataHash(bytes32 domainSeparator, bytes32 structHash) internal pure returns (bytes32) {\\n return keccak256(abi.encodePacked(\\\"\\\\x19\\\\x01\\\", domainSeparator, structHash));\\n }\\n}\\n\",\"keccak256\":\"0xe8c62ca00ed2d0a4d9b7e3c4bf7d62c821618b2cdb3c844da91a1193986851bf\",\"license\":\"MIT\"},\"@openzeppelin/contracts-upgradeable/utils/cryptography/draft-EIP712Upgradeable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (utils/cryptography/draft-EIP712.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"./ECDSAUpgradeable.sol\\\";\\nimport \\\"../../proxy/utils/Initializable.sol\\\";\\n\\n/**\\n * @dev https://eips.ethereum.org/EIPS/eip-712[EIP 712] is a standard for hashing and signing of typed structured data.\\n *\\n * The encoding specified in the EIP is very generic, and such a generic implementation in Solidity is not feasible,\\n * thus this contract does not implement the encoding itself. Protocols need to implement the type-specific encoding\\n * they need in their contracts using a combination of `abi.encode` and `keccak256`.\\n *\\n * This contract implements the EIP 712 domain separator ({_domainSeparatorV4}) that is used as part of the encoding\\n * scheme, and the final step of the encoding to obtain the message digest that is then signed via ECDSA\\n * ({_hashTypedDataV4}).\\n *\\n * The implementation of the domain separator was designed to be as efficient as possible while still properly updating\\n * the chain id to protect against replay attacks on an eventual fork of the chain.\\n *\\n * NOTE: This contract implements the version of the encoding known as \\\"v4\\\", as implemented by the JSON RPC method\\n * https://docs.metamask.io/guide/signing-data.html[`eth_signTypedDataV4` in MetaMask].\\n *\\n * _Available since v3.4._\\n *\\n * @custom:storage-size 52\\n */\\nabstract contract EIP712Upgradeable is Initializable {\\n /* solhint-disable var-name-mixedcase */\\n bytes32 private _HASHED_NAME;\\n bytes32 private _HASHED_VERSION;\\n bytes32 private constant _TYPE_HASH = keccak256(\\\"EIP712Domain(string name,string version,uint256 chainId,address verifyingContract)\\\");\\n\\n /* solhint-enable var-name-mixedcase */\\n\\n /**\\n * @dev Initializes the domain separator and parameter caches.\\n *\\n * The meaning of `name` and `version` is specified in\\n * https://eips.ethereum.org/EIPS/eip-712#definition-of-domainseparator[EIP 712]:\\n *\\n * - `name`: the user readable name of the signing domain, i.e. the name of the DApp or the protocol.\\n * - `version`: the current major version of the signing domain.\\n *\\n * NOTE: These parameters cannot be changed except through a xref:learn::upgrading-smart-contracts.adoc[smart\\n * contract upgrade].\\n */\\n function __EIP712_init(string memory name, string memory version) internal onlyInitializing {\\n __EIP712_init_unchained(name, version);\\n }\\n\\n function __EIP712_init_unchained(string memory name, string memory version) internal onlyInitializing {\\n bytes32 hashedName = keccak256(bytes(name));\\n bytes32 hashedVersion = keccak256(bytes(version));\\n _HASHED_NAME = hashedName;\\n _HASHED_VERSION = hashedVersion;\\n }\\n\\n /**\\n * @dev Returns the domain separator for the current chain.\\n */\\n function _domainSeparatorV4() internal view returns (bytes32) {\\n return _buildDomainSeparator(_TYPE_HASH, _EIP712NameHash(), _EIP712VersionHash());\\n }\\n\\n function _buildDomainSeparator(\\n bytes32 typeHash,\\n bytes32 nameHash,\\n bytes32 versionHash\\n ) private view returns (bytes32) {\\n return keccak256(abi.encode(typeHash, nameHash, versionHash, block.chainid, address(this)));\\n }\\n\\n /**\\n * @dev Given an already https://eips.ethereum.org/EIPS/eip-712#definition-of-hashstruct[hashed struct], this\\n * function returns the hash of the fully encoded EIP712 message for this domain.\\n *\\n * This hash can be used together with {ECDSA-recover} to obtain the signer of a message. For example:\\n *\\n * ```solidity\\n * bytes32 digest = _hashTypedDataV4(keccak256(abi.encode(\\n * keccak256(\\\"Mail(address to,string contents)\\\"),\\n * mailTo,\\n * keccak256(bytes(mailContents))\\n * )));\\n * address signer = ECDSA.recover(digest, signature);\\n * ```\\n */\\n function _hashTypedDataV4(bytes32 structHash) internal view virtual returns (bytes32) {\\n return ECDSAUpgradeable.toTypedDataHash(_domainSeparatorV4(), structHash);\\n }\\n\\n /**\\n * @dev The hash of the name parameter for the EIP712 domain.\\n *\\n * NOTE: This function reads from storage by default, but can be redefined to return a constant value if gas costs\\n * are a concern.\\n */\\n function _EIP712NameHash() internal virtual view returns (bytes32) {\\n return _HASHED_NAME;\\n }\\n\\n /**\\n * @dev The hash of the version parameter for the EIP712 domain.\\n *\\n * NOTE: This function reads from storage by default, but can be redefined to return a constant value if gas costs\\n * are a concern.\\n */\\n function _EIP712VersionHash() internal virtual view returns (bytes32) {\\n return _HASHED_VERSION;\\n }\\n\\n /**\\n * @dev This empty reserved space is put in place to allow future versions to add new\\n * variables without shifting down storage in the inheritance chain.\\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\\n */\\n uint256[50] private __gap;\\n}\\n\",\"keccak256\":\"0xaf5a96100f421d61693605349511e43221d3c2e47d4b3efa87af2b936e2567fc\",\"license\":\"MIT\"},\"@openzeppelin/contracts/token/ERC20/IERC20.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.6.0) (token/ERC20/IERC20.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Interface of the ERC20 standard as defined in the EIP.\\n */\\ninterface IERC20 {\\n /**\\n * @dev Emitted when `value` tokens are moved from one account (`from`) to\\n * another (`to`).\\n *\\n * Note that `value` may be zero.\\n */\\n event Transfer(address indexed from, address indexed to, uint256 value);\\n\\n /**\\n * @dev Emitted when the allowance of a `spender` for an `owner` is set by\\n * a call to {approve}. `value` is the new allowance.\\n */\\n event Approval(address indexed owner, address indexed spender, uint256 value);\\n\\n /**\\n * @dev Returns the amount of tokens in existence.\\n */\\n function totalSupply() external view returns (uint256);\\n\\n /**\\n * @dev Returns the amount of tokens owned by `account`.\\n */\\n function balanceOf(address account) external view returns (uint256);\\n\\n /**\\n * @dev Moves `amount` tokens from the caller's account to `to`.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * Emits a {Transfer} event.\\n */\\n function transfer(address to, uint256 amount) external returns (bool);\\n\\n /**\\n * @dev Returns the remaining number of tokens that `spender` will be\\n * allowed to spend on behalf of `owner` through {transferFrom}. This is\\n * zero by default.\\n *\\n * This value changes when {approve} or {transferFrom} are called.\\n */\\n function allowance(address owner, address spender) external view returns (uint256);\\n\\n /**\\n * @dev Sets `amount` as the allowance of `spender` over the caller's tokens.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * IMPORTANT: Beware that changing an allowance with this method brings the risk\\n * that someone may use both the old and the new allowance by unfortunate\\n * transaction ordering. One possible solution to mitigate this race\\n * condition is to first reduce the spender's allowance to 0 and set the\\n * desired value afterwards:\\n * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729\\n *\\n * Emits an {Approval} event.\\n */\\n function approve(address spender, uint256 amount) external returns (bool);\\n\\n /**\\n * @dev Moves `amount` tokens from `from` to `to` using the\\n * allowance mechanism. `amount` is then deducted from the caller's\\n * allowance.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * Emits a {Transfer} event.\\n */\\n function transferFrom(\\n address from,\\n address to,\\n uint256 amount\\n ) external returns (bool);\\n}\\n\",\"keccak256\":\"0x9750c6b834f7b43000631af5cc30001c5f547b3ceb3635488f140f60e897ea6b\",\"license\":\"MIT\"},\"@openzeppelin/contracts/token/ERC20/extensions/draft-IERC20Permit.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (token/ERC20/extensions/draft-IERC20Permit.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Interface of the ERC20 Permit extension allowing approvals to be made via signatures, as defined in\\n * https://eips.ethereum.org/EIPS/eip-2612[EIP-2612].\\n *\\n * Adds the {permit} method, which can be used to change an account's ERC20 allowance (see {IERC20-allowance}) by\\n * presenting a message signed by the account. By not relying on {IERC20-approve}, the token holder account doesn't\\n * need to send a transaction, and thus is not required to hold Ether at all.\\n */\\ninterface IERC20Permit {\\n /**\\n * @dev Sets `value` as the allowance of `spender` over ``owner``'s tokens,\\n * given ``owner``'s signed approval.\\n *\\n * IMPORTANT: The same issues {IERC20-approve} has related to transaction\\n * ordering also apply here.\\n *\\n * Emits an {Approval} event.\\n *\\n * Requirements:\\n *\\n * - `spender` cannot be the zero address.\\n * - `deadline` must be a timestamp in the future.\\n * - `v`, `r` and `s` must be a valid `secp256k1` signature from `owner`\\n * over the EIP712-formatted function arguments.\\n * - the signature must use ``owner``'s current nonce (see {nonces}).\\n *\\n * For more information on the signature format, see the\\n * https://eips.ethereum.org/EIPS/eip-2612#specification[relevant EIP\\n * section].\\n */\\n function permit(\\n address owner,\\n address spender,\\n uint256 value,\\n uint256 deadline,\\n uint8 v,\\n bytes32 r,\\n bytes32 s\\n ) external;\\n\\n /**\\n * @dev Returns the current nonce for `owner`. This value must be\\n * included whenever a signature is generated for {permit}.\\n *\\n * Every successful call to {permit} increases ``owner``'s nonce by one. This\\n * prevents a signature from being used multiple times.\\n */\\n function nonces(address owner) external view returns (uint256);\\n\\n /**\\n * @dev Returns the domain separator used in the encoding of the signature for {permit}, as defined by {EIP712}.\\n */\\n // solhint-disable-next-line func-name-mixedcase\\n function DOMAIN_SEPARATOR() external view returns (bytes32);\\n}\\n\",\"keccak256\":\"0xf41ca991f30855bf80ffd11e9347856a517b977f0a6c2d52e6421a99b7840329\",\"license\":\"MIT\"},\"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.7.0) (token/ERC20/utils/SafeERC20.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../IERC20.sol\\\";\\nimport \\\"../extensions/draft-IERC20Permit.sol\\\";\\nimport \\\"../../../utils/Address.sol\\\";\\n\\n/**\\n * @title SafeERC20\\n * @dev Wrappers around ERC20 operations that throw on failure (when the token\\n * contract returns false). Tokens that return no value (and instead revert or\\n * throw on failure) are also supported, non-reverting calls are assumed to be\\n * successful.\\n * To use this library you can add a `using SafeERC20 for IERC20;` statement to your contract,\\n * which allows you to call the safe operations as `token.safeTransfer(...)`, etc.\\n */\\nlibrary SafeERC20 {\\n using Address for address;\\n\\n function safeTransfer(\\n IERC20 token,\\n address to,\\n uint256 value\\n ) internal {\\n _callOptionalReturn(token, abi.encodeWithSelector(token.transfer.selector, to, value));\\n }\\n\\n function safeTransferFrom(\\n IERC20 token,\\n address from,\\n address to,\\n uint256 value\\n ) internal {\\n _callOptionalReturn(token, abi.encodeWithSelector(token.transferFrom.selector, from, to, value));\\n }\\n\\n /**\\n * @dev Deprecated. This function has issues similar to the ones found in\\n * {IERC20-approve}, and its usage is discouraged.\\n *\\n * Whenever possible, use {safeIncreaseAllowance} and\\n * {safeDecreaseAllowance} instead.\\n */\\n function safeApprove(\\n IERC20 token,\\n address spender,\\n uint256 value\\n ) internal {\\n // safeApprove should only be called when setting an initial allowance,\\n // or when resetting it to zero. To increase and decrease it, use\\n // 'safeIncreaseAllowance' and 'safeDecreaseAllowance'\\n require(\\n (value == 0) || (token.allowance(address(this), spender) == 0),\\n \\\"SafeERC20: approve from non-zero to non-zero allowance\\\"\\n );\\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, value));\\n }\\n\\n function safeIncreaseAllowance(\\n IERC20 token,\\n address spender,\\n uint256 value\\n ) internal {\\n uint256 newAllowance = token.allowance(address(this), spender) + value;\\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));\\n }\\n\\n function safeDecreaseAllowance(\\n IERC20 token,\\n address spender,\\n uint256 value\\n ) internal {\\n unchecked {\\n uint256 oldAllowance = token.allowance(address(this), spender);\\n require(oldAllowance >= value, \\\"SafeERC20: decreased allowance below zero\\\");\\n uint256 newAllowance = oldAllowance - value;\\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));\\n }\\n }\\n\\n function safePermit(\\n IERC20Permit token,\\n address owner,\\n address spender,\\n uint256 value,\\n uint256 deadline,\\n uint8 v,\\n bytes32 r,\\n bytes32 s\\n ) internal {\\n uint256 nonceBefore = token.nonces(owner);\\n token.permit(owner, spender, value, deadline, v, r, s);\\n uint256 nonceAfter = token.nonces(owner);\\n require(nonceAfter == nonceBefore + 1, \\\"SafeERC20: permit did not succeed\\\");\\n }\\n\\n /**\\n * @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement\\n * on the return value: the return value is optional (but if data is returned, it must not be false).\\n * @param token The token targeted by the call.\\n * @param data The call data (encoded using abi.encode or one of its variants).\\n */\\n function _callOptionalReturn(IERC20 token, bytes memory data) private {\\n // We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since\\n // we're implementing it ourselves. We use {Address.functionCall} to perform this call, which verifies that\\n // the target address contains contract code and also asserts for success in the low-level call.\\n\\n bytes memory returndata = address(token).functionCall(data, \\\"SafeERC20: low-level call failed\\\");\\n if (returndata.length > 0) {\\n // Return data is optional\\n require(abi.decode(returndata, (bool)), \\\"SafeERC20: ERC20 operation did not succeed\\\");\\n }\\n }\\n}\\n\",\"keccak256\":\"0x032807210d1d7d218963d7355d62e021a84bf1b3339f4f50be2f63b53cccaf29\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/Address.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.7.0) (utils/Address.sol)\\n\\npragma solidity ^0.8.1;\\n\\n/**\\n * @dev Collection of functions related to the address type\\n */\\nlibrary Address {\\n /**\\n * @dev Returns true if `account` is a contract.\\n *\\n * [IMPORTANT]\\n * ====\\n * It is unsafe to assume that an address for which this function returns\\n * false is an externally-owned account (EOA) and not a contract.\\n *\\n * Among others, `isContract` will return false for the following\\n * types of addresses:\\n *\\n * - an externally-owned account\\n * - a contract in construction\\n * - an address where a contract will be created\\n * - an address where a contract lived, but was destroyed\\n * ====\\n *\\n * [IMPORTANT]\\n * ====\\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\\n *\\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\\n * constructor.\\n * ====\\n */\\n function isContract(address account) internal view returns (bool) {\\n // This method relies on extcodesize/address.code.length, which returns 0\\n // for contracts in construction, since the code is only stored at the end\\n // of the constructor execution.\\n\\n return account.code.length > 0;\\n }\\n\\n /**\\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\\n * `recipient`, forwarding all available gas and reverting on errors.\\n *\\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\\n * imposed by `transfer`, making them unable to receive funds via\\n * `transfer`. {sendValue} removes this limitation.\\n *\\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\\n *\\n * IMPORTANT: because control is transferred to `recipient`, care must be\\n * taken to not create reentrancy vulnerabilities. Consider using\\n * {ReentrancyGuard} or the\\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\\n */\\n function sendValue(address payable recipient, uint256 amount) internal {\\n require(address(this).balance >= amount, \\\"Address: insufficient balance\\\");\\n\\n (bool success, ) = recipient.call{value: amount}(\\\"\\\");\\n require(success, \\\"Address: unable to send value, recipient may have reverted\\\");\\n }\\n\\n /**\\n * @dev Performs a Solidity function call using a low level `call`. A\\n * plain `call` is an unsafe replacement for a function call: use this\\n * function instead.\\n *\\n * If `target` reverts with a revert reason, it is bubbled up by this\\n * function (like regular Solidity function calls).\\n *\\n * Returns the raw returned data. To convert to the expected return value,\\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\\n *\\n * Requirements:\\n *\\n * - `target` must be a contract.\\n * - calling `target` with `data` must not revert.\\n *\\n * _Available since v3.1._\\n */\\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\\n return functionCall(target, data, \\\"Address: low-level call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\\n * `errorMessage` as a fallback revert reason when `target` reverts.\\n *\\n * _Available since v3.1._\\n */\\n function functionCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n return functionCallWithValue(target, data, 0, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but also transferring `value` wei to `target`.\\n *\\n * Requirements:\\n *\\n * - the calling contract must have an ETH balance of at least `value`.\\n * - the called Solidity function must be `payable`.\\n *\\n * _Available since v3.1._\\n */\\n function functionCallWithValue(\\n address target,\\n bytes memory data,\\n uint256 value\\n ) internal returns (bytes memory) {\\n return functionCallWithValue(target, data, value, \\\"Address: low-level call with value failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\\n * with `errorMessage` as a fallback revert reason when `target` reverts.\\n *\\n * _Available since v3.1._\\n */\\n function functionCallWithValue(\\n address target,\\n bytes memory data,\\n uint256 value,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n require(address(this).balance >= value, \\\"Address: insufficient balance for call\\\");\\n require(isContract(target), \\\"Address: call to non-contract\\\");\\n\\n (bool success, bytes memory returndata) = target.call{value: value}(data);\\n return verifyCallResult(success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but performing a static call.\\n *\\n * _Available since v3.3._\\n */\\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\\n return functionStaticCall(target, data, \\\"Address: low-level static call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\\n * but performing a static call.\\n *\\n * _Available since v3.3._\\n */\\n function functionStaticCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal view returns (bytes memory) {\\n require(isContract(target), \\\"Address: static call to non-contract\\\");\\n\\n (bool success, bytes memory returndata) = target.staticcall(data);\\n return verifyCallResult(success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but performing a delegate call.\\n *\\n * _Available since v3.4._\\n */\\n function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {\\n return functionDelegateCall(target, data, \\\"Address: low-level delegate call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\\n * but performing a delegate call.\\n *\\n * _Available since v3.4._\\n */\\n function functionDelegateCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n require(isContract(target), \\\"Address: delegate call to non-contract\\\");\\n\\n (bool success, bytes memory returndata) = target.delegatecall(data);\\n return verifyCallResult(success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the\\n * revert reason using the provided one.\\n *\\n * _Available since v4.3._\\n */\\n function verifyCallResult(\\n bool success,\\n bytes memory returndata,\\n string memory errorMessage\\n ) internal pure returns (bytes memory) {\\n if (success) {\\n return returndata;\\n } else {\\n // Look for revert reason and bubble it up if present\\n if (returndata.length > 0) {\\n // The easiest way to bubble the revert reason is using memory via assembly\\n /// @solidity memory-safe-assembly\\n assembly {\\n let returndata_size := mload(returndata)\\n revert(add(32, returndata), returndata_size)\\n }\\n } else {\\n revert(errorMessage);\\n }\\n }\\n }\\n}\\n\",\"keccak256\":\"0xd6153ce99bcdcce22b124f755e72553295be6abcd63804cfdffceb188b8bef10\",\"license\":\"MIT\"},\"contracts/agToken/AgToken.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-3.0\\n\\npragma solidity ^0.8.12;\\n\\n/*\\n * \\u2588 \\n ***** \\u2593\\u2593\\u2593 \\n * \\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593 \\n * ///. \\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593 \\n ***** //////// \\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593 \\n * ///////////// \\u2593\\u2593\\u2593 \\n \\u2593\\u2593 ////////////////// \\u2588 \\u2593\\u2593 \\n \\u2593\\u2593 \\u2593\\u2593 /////////////////////// \\u2593\\u2593 \\u2593\\u2593 \\n \\u2593\\u2593 \\u2593\\u2593 //////////////////////////// \\u2593\\u2593 \\u2593\\u2593 \\n \\u2593\\u2593 \\u2593\\u2593 /////////\\u2593\\u2593\\u2593///////\\u2593\\u2593\\u2593///////// \\u2593\\u2593 \\u2593\\u2593 \\n \\u2593\\u2593 ,////////////////////////////////////// \\u2593\\u2593 \\u2593\\u2593 \\n \\u2593\\u2593 ////////////////////////////////////////// \\u2593\\u2593 \\n \\u2593\\u2593 //////////////////////\\u2593\\u2593\\u2593\\u2593///////////////////// \\n ,//////////////////////////////////////////////////// \\n .////////////////////////////////////////////////////////// \\n .//////////////////////////\\u2588\\u2588.,//////////////////////////\\u2588 \\n .//////////////////////\\u2588\\u2588\\u2588\\u2588..,./////////////////////\\u2588\\u2588 \\n ...////////////////\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588.....,.////////////////\\u2588\\u2588\\u2588 \\n ,.,////////////\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588 ........,///////////\\u2588\\u2588\\u2588\\u2588 \\n .,.,//////\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588 ,.......///////\\u2588\\u2588\\u2588\\u2588 \\n ,..//\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588 ........./\\u2588\\u2588\\u2588\\u2588 \\n ..,\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588 .....,\\u2588\\u2588\\u2588 \\n .\\u2588\\u2588 ,.,\\u2588 \\n \\n \\n \\n \\u2593\\u2593 \\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593 \\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593 \\u2593\\u2593 \\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593 \\n \\u2593\\u2593\\u2593\\u2593\\u2593\\u2593 \\u2593\\u2593\\u2593 \\u2593\\u2593\\u2593 \\u2593\\u2593\\u2593 \\u2593\\u2593 \\u2593\\u2593 \\u2593\\u2593\\u2593\\u2593 \\n \\u2593\\u2593\\u2593 \\u2593\\u2593\\u2593 \\u2593\\u2593\\u2593 \\u2593\\u2593\\u2593 \\u2593\\u2593\\u2593 \\u2593\\u2593\\u2593 \\u2593\\u2593 \\u2593\\u2593\\u2593\\u2593\\u2593 \\n \\u2593\\u2593\\u2593 \\u2593\\u2593 \\u2593\\u2593\\u2593 \\u2593\\u2593\\u2593 \\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593 \\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593 \\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593 \\n*/\\n\\nimport \\\"../interfaces/IAgToken.sol\\\";\\nimport \\\"../interfaces/ITreasury.sol\\\";\\nimport \\\"@openzeppelin/contracts-upgradeable/token/ERC20/extensions/draft-ERC20PermitUpgradeable.sol\\\";\\n\\n/// @title AgToken\\n/// @author Angle Labs, Inc.\\n/// @notice Base contract for Angle agTokens on Ethereum and on other chains\\n/// @dev By default, agTokens are ERC-20 tokens with 18 decimals\\ncontract AgToken is IAgToken, ERC20PermitUpgradeable {\\n // =========================== PARAMETERS / VARIABLES ==========================\\n\\n /// @inheritdoc IAgToken\\n mapping(address => bool) public isMinter;\\n /// @notice Reference to the treasury contract which can grant minting rights\\n address public treasury;\\n\\n // =================================== EVENTS ==================================\\n\\n event TreasuryUpdated(address indexed _treasury);\\n event MinterToggled(address indexed minter);\\n\\n // =================================== ERRORS ==================================\\n\\n error BurnAmountExceedsAllowance();\\n error InvalidSender();\\n error InvalidTreasury();\\n error NotMinter();\\n error NotTreasury();\\n\\n // ================================ CONSTRUCTOR ================================\\n\\n /// @custom:oz-upgrades-unsafe-allow constructor\\n constructor() initializer {}\\n\\n /// @notice Initializes the `AgToken` contract\\n function initialize(string memory name_, string memory symbol_, address _treasury) external {\\n _initialize(name_, symbol_, _treasury);\\n }\\n\\n /// @notice Initializes the contract\\n function _initialize(string memory name_, string memory symbol_, address _treasury) internal virtual initializer {\\n if (address(ITreasury(_treasury).stablecoin()) != address(this)) revert InvalidTreasury();\\n __ERC20Permit_init(name_);\\n __ERC20_init(name_, symbol_);\\n treasury = _treasury;\\n emit TreasuryUpdated(_treasury);\\n }\\n\\n // ================================= MODIFIERS =================================\\n\\n /// @notice Checks to see if it is the `Treasury` calling this contract\\n modifier onlyTreasury() {\\n if (msg.sender != treasury) revert NotTreasury();\\n _;\\n }\\n\\n /// @notice Checks whether the sender has the minting right\\n modifier onlyMinter() {\\n if (!isMinter[msg.sender]) revert NotMinter();\\n _;\\n }\\n\\n // ============================= EXTERNAL FUNCTION =============================\\n\\n /// @notice Allows anyone to burn stablecoins\\n /// @param amount Amount of stablecoins to burn\\n /// @dev This function can typically be called if there is a settlement mechanism to burn stablecoins\\n function burnStablecoin(uint256 amount) external {\\n _burn(msg.sender, amount);\\n }\\n\\n // ========================= MINTER ROLE ONLY FUNCTIONS ========================\\n\\n /// @inheritdoc IAgToken\\n function burnSelf(uint256 amount, address burner) external onlyMinter {\\n _burn(burner, amount);\\n }\\n\\n /// @inheritdoc IAgToken\\n function burnFrom(uint256 amount, address burner, address sender) external onlyMinter {\\n if (burner != sender) {\\n uint256 currentAllowance = allowance(burner, sender);\\n if (currentAllowance < amount) revert BurnAmountExceedsAllowance();\\n _approve(burner, sender, currentAllowance - amount);\\n }\\n _burn(burner, amount);\\n }\\n\\n /// @inheritdoc IAgToken\\n function mint(address account, uint256 amount) external onlyMinter {\\n _mint(account, amount);\\n }\\n\\n // ========================== GOVERNANCE ONLY FUNCTIONS ==========================\\n\\n /// @inheritdoc IAgToken\\n function addMinter(address minter) external onlyTreasury {\\n isMinter[minter] = true;\\n emit MinterToggled(minter);\\n }\\n\\n /// @inheritdoc IAgToken\\n function removeMinter(address minter) external {\\n if (msg.sender != address(treasury) && msg.sender != minter) revert InvalidSender();\\n isMinter[minter] = false;\\n emit MinterToggled(minter);\\n }\\n\\n /// @inheritdoc IAgToken\\n function setTreasury(address _treasury) external virtual onlyTreasury {\\n treasury = _treasury;\\n emit TreasuryUpdated(_treasury);\\n }\\n}\\n\",\"keccak256\":\"0x671d54d7840179050e859cf09662fe0e2c34cfaf5ec3782148d6c29e77c54d17\",\"license\":\"GPL-3.0\"},\"contracts/agToken/AgTokenSideChainMultiBridge.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-3.0\\n\\npragma solidity ^0.8.12;\\n\\nimport \\\"./AgToken.sol\\\";\\nimport \\\"@openzeppelin/contracts/token/ERC20/IERC20.sol\\\";\\nimport \\\"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\\\";\\n\\n/// @title AgTokenSideChainMultiBridge\\n/// @author Angle Labs, Inc.\\n/// @notice Contract for Angle agTokens on other chains than Ethereum mainnet\\n/// @dev This contract supports bridge tokens having a minting right on the stablecoin (also referred to as the canonical\\n/// or the native token)\\ncontract AgTokenSideChainMultiBridge is AgToken {\\n using SafeERC20 for IERC20;\\n\\n /// @notice Base used for fee computation\\n uint256 public constant BASE_PARAMS = 1e9;\\n\\n // =============================== BRIDGING DATA ===============================\\n\\n /// @notice Struct with some data about a specific bridge token\\n struct BridgeDetails {\\n // Limit on the balance of bridge token held by the contract: it is designed\\n // to reduce the exposure of the system to hacks\\n uint256 limit;\\n // Limit on the hourly volume of token minted through this bridge\\n // Technically the limit over a rolling hour is hourlyLimit x2 as hourly limit\\n // is enforced only between x:00 and x+1:00\\n uint256 hourlyLimit;\\n // Fee taken for swapping in and out the token\\n uint64 fee;\\n // Whether the associated token is allowed or not\\n bool allowed;\\n // Whether swapping in and out from the associated token is paused or not\\n bool paused;\\n }\\n\\n /// @notice Maps a bridge token to data\\n mapping(address => BridgeDetails) public bridges;\\n /// @notice List of all bridge tokens\\n address[] public bridgeTokensList;\\n /// @notice Maps a bridge token to the associated hourly volume\\n mapping(address => mapping(uint256 => uint256)) public usage;\\n /// @notice Maps an address to whether it is exempt of fees for when it comes to swapping in and out\\n mapping(address => uint256) public isFeeExempt;\\n /// @notice Limit to the amount of tokens that can be sent from that chain to another chain\\n uint256 public chainTotalHourlyLimit;\\n /// @notice Usage per hour on that chain. Maps an hourly timestamp to the total volume swapped out on the chain\\n mapping(uint256 => uint256) public chainTotalUsage;\\n\\n // =================================== EVENTS ==================================\\n\\n event BridgeTokenAdded(address indexed bridgeToken, uint256 limit, uint256 hourlyLimit, uint64 fee, bool paused);\\n event BridgeTokenToggled(address indexed bridgeToken, bool toggleStatus);\\n event BridgeTokenRemoved(address indexed bridgeToken);\\n event BridgeTokenFeeUpdated(address indexed bridgeToken, uint64 fee);\\n event BridgeTokenLimitUpdated(address indexed bridgeToken, uint256 limit);\\n event BridgeTokenHourlyLimitUpdated(address indexed bridgeToken, uint256 hourlyLimit);\\n event HourlyLimitUpdated(uint256 hourlyLimit);\\n event Recovered(address indexed token, address indexed to, uint256 amount);\\n event FeeToggled(address indexed theAddress, uint256 toggleStatus);\\n\\n // =================================== ERRORS ==================================\\n\\n error AssetStillControlledInReserves();\\n error HourlyLimitExceeded();\\n error InvalidToken();\\n error NotGovernor();\\n error NotGovernorOrGuardian();\\n error TooBigAmount();\\n error TooHighParameterValue();\\n error ZeroAddress();\\n\\n // ================================= MODIFIERS =================================\\n\\n /// @notice Checks whether the `msg.sender` has the governor role or not\\n modifier onlyGovernor() {\\n if (!ITreasury(treasury).isGovernor(msg.sender)) revert NotGovernor();\\n _;\\n }\\n\\n /// @notice Checks whether the `msg.sender` has the governor role or the guardian role\\n modifier onlyGovernorOrGuardian() {\\n if (!ITreasury(treasury).isGovernorOrGuardian(msg.sender)) revert NotGovernorOrGuardian();\\n _;\\n }\\n\\n // ===================== EXTERNAL PERMISSIONLESS FUNCTIONS =====================\\n\\n /// @notice Returns the list of all supported bridge tokens\\n /// @dev Helpful for UIs\\n function allBridgeTokens() external view returns (address[] memory) {\\n return bridgeTokensList;\\n }\\n\\n /// @notice Returns the current volume for a bridge, for the current hour\\n /// @param bridgeToken Bridge used to mint\\n /// @dev Helpful for UIs\\n function currentUsage(address bridgeToken) external view returns (uint256) {\\n return usage[bridgeToken][block.timestamp / 3600];\\n }\\n\\n /// @notice Returns the current total volume on the chain for the current hour\\n /// @dev Helpful for UIs\\n function currentTotalUsage() external view returns (uint256) {\\n return chainTotalUsage[block.timestamp / 3600];\\n }\\n\\n /// @notice Mints the canonical token from a supported bridge token\\n /// @param bridgeToken Bridge token to use to mint\\n /// @param amount Amount of bridge tokens to send\\n /// @param to Address to which the stablecoin should be sent\\n /// @return Amount of the canonical stablecoin actually minted\\n /// @dev Some fees may be taken by the protocol depending on the token used and on the address calling\\n function swapIn(address bridgeToken, uint256 amount, address to) external returns (uint256) {\\n BridgeDetails memory bridgeDetails = bridges[bridgeToken];\\n if (!bridgeDetails.allowed || bridgeDetails.paused) revert InvalidToken();\\n uint256 balance = IERC20(bridgeToken).balanceOf(address(this));\\n if (balance + amount > bridgeDetails.limit) {\\n // In case someone maliciously sends tokens to this contract\\n // Or the limit changes\\n if (bridgeDetails.limit > balance) amount = bridgeDetails.limit - balance;\\n else {\\n amount = 0;\\n }\\n }\\n\\n // Checking requirement on the hourly volume\\n uint256 hour = block.timestamp / 3600;\\n uint256 hourlyUsage = usage[bridgeToken][hour];\\n if (hourlyUsage + amount > bridgeDetails.hourlyLimit) {\\n // Edge case when the hourly limit changes\\n amount = bridgeDetails.hourlyLimit > hourlyUsage ? bridgeDetails.hourlyLimit - hourlyUsage : 0;\\n }\\n usage[bridgeToken][hour] = hourlyUsage + amount;\\n\\n IERC20(bridgeToken).safeTransferFrom(msg.sender, address(this), amount);\\n uint256 canonicalOut = amount;\\n // Computing fees\\n if (isFeeExempt[msg.sender] == 0) {\\n canonicalOut -= (canonicalOut * bridgeDetails.fee) / BASE_PARAMS;\\n }\\n _mint(to, canonicalOut);\\n return canonicalOut;\\n }\\n\\n /// @notice Burns the canonical token in exchange for a bridge token\\n /// @param bridgeToken Bridge token required\\n /// @param amount Amount of canonical tokens to burn\\n /// @param to Address to which the bridge token should be sent\\n /// @return Amount of bridge tokens actually sent back\\n /// @dev Some fees may be taken by the protocol depending on the token used and on the address calling\\n function swapOut(address bridgeToken, uint256 amount, address to) external returns (uint256) {\\n BridgeDetails memory bridgeDetails = bridges[bridgeToken];\\n if (!bridgeDetails.allowed || bridgeDetails.paused) revert InvalidToken();\\n\\n uint256 hour = block.timestamp / 3600;\\n uint256 hourlyUsage = chainTotalUsage[hour] + amount;\\n // If the amount being swapped out exceeds the limit, we revert\\n // We don't want to change the amount being swapped out.\\n // The user can decide to send another tx with the correct amount to reach the limit\\n if (hourlyUsage > chainTotalHourlyLimit) revert HourlyLimitExceeded();\\n chainTotalUsage[hour] = hourlyUsage;\\n\\n _burn(msg.sender, amount);\\n uint256 bridgeOut = amount;\\n if (isFeeExempt[msg.sender] == 0) {\\n bridgeOut -= (bridgeOut * bridgeDetails.fee) / BASE_PARAMS;\\n }\\n IERC20(bridgeToken).safeTransfer(to, bridgeOut);\\n return bridgeOut;\\n }\\n\\n // ============================ GOVERNANCE FUNCTIONS ===========================\\n\\n /// @notice Adds support for a bridge token\\n /// @param bridgeToken Bridge token to add: it should be a version of the stablecoin from another bridge\\n /// @param limit Limit on the balance of bridge token this contract could hold\\n /// @param hourlyLimit Limit on the hourly volume for this bridge\\n /// @param paused Whether swapping for this token should be paused or not\\n /// @param fee Fee taken upon swapping for or against this token\\n function addBridgeToken(\\n address bridgeToken,\\n uint256 limit,\\n uint256 hourlyLimit,\\n uint64 fee,\\n bool paused\\n ) external onlyGovernor {\\n if (bridges[bridgeToken].allowed || bridgeToken == address(0)) revert InvalidToken();\\n if (fee > BASE_PARAMS) revert TooHighParameterValue();\\n BridgeDetails memory _bridge;\\n _bridge.limit = limit;\\n _bridge.hourlyLimit = hourlyLimit;\\n _bridge.paused = paused;\\n _bridge.fee = fee;\\n _bridge.allowed = true;\\n bridges[bridgeToken] = _bridge;\\n bridgeTokensList.push(bridgeToken);\\n emit BridgeTokenAdded(bridgeToken, limit, hourlyLimit, fee, paused);\\n }\\n\\n /// @notice Removes support for a token\\n /// @param bridgeToken Address of the bridge token to remove support for\\n function removeBridgeToken(address bridgeToken) external onlyGovernor {\\n if (IERC20(bridgeToken).balanceOf(address(this)) != 0) revert AssetStillControlledInReserves();\\n delete bridges[bridgeToken];\\n // Deletion from `bridgeTokensList` loop\\n uint256 bridgeTokensListLength = bridgeTokensList.length;\\n for (uint256 i; i < bridgeTokensListLength - 1; ++i) {\\n if (bridgeTokensList[i] == bridgeToken) {\\n // Replace the `bridgeToken` to remove with the last of the list\\n bridgeTokensList[i] = bridgeTokensList[bridgeTokensListLength - 1];\\n break;\\n }\\n }\\n // Remove last element in array\\n bridgeTokensList.pop();\\n emit BridgeTokenRemoved(bridgeToken);\\n }\\n\\n /// @notice Recovers any ERC20 token\\n /// @dev Can be used to withdraw bridge tokens for them to be de-bridged on mainnet\\n function recoverERC20(address tokenAddress, address to, uint256 amountToRecover) external onlyGovernor {\\n IERC20(tokenAddress).safeTransfer(to, amountToRecover);\\n emit Recovered(tokenAddress, to, amountToRecover);\\n }\\n\\n /// @notice Updates the `limit` amount for `bridgeToken`\\n function setLimit(address bridgeToken, uint256 limit) external onlyGovernorOrGuardian {\\n if (!bridges[bridgeToken].allowed) revert InvalidToken();\\n bridges[bridgeToken].limit = limit;\\n emit BridgeTokenLimitUpdated(bridgeToken, limit);\\n }\\n\\n /// @notice Updates the `hourlyLimit` amount for `bridgeToken`\\n function setHourlyLimit(address bridgeToken, uint256 hourlyLimit) external onlyGovernorOrGuardian {\\n if (!bridges[bridgeToken].allowed) revert InvalidToken();\\n bridges[bridgeToken].hourlyLimit = hourlyLimit;\\n emit BridgeTokenHourlyLimitUpdated(bridgeToken, hourlyLimit);\\n }\\n\\n /// @notice Updates the `chainTotalHourlyLimit` amount\\n function setChainTotalHourlyLimit(uint256 hourlyLimit) external onlyGovernorOrGuardian {\\n chainTotalHourlyLimit = hourlyLimit;\\n emit HourlyLimitUpdated(hourlyLimit);\\n }\\n\\n /// @notice Updates the `fee` value for `bridgeToken`\\n function setSwapFee(address bridgeToken, uint64 fee) external onlyGovernorOrGuardian {\\n if (!bridges[bridgeToken].allowed) revert InvalidToken();\\n if (fee > BASE_PARAMS) revert TooHighParameterValue();\\n bridges[bridgeToken].fee = fee;\\n emit BridgeTokenFeeUpdated(bridgeToken, fee);\\n }\\n\\n /// @notice Pauses or unpauses swapping in and out for a token\\n function toggleBridge(address bridgeToken) external onlyGovernorOrGuardian {\\n if (!bridges[bridgeToken].allowed) revert InvalidToken();\\n bool pausedStatus = bridges[bridgeToken].paused;\\n bridges[bridgeToken].paused = !pausedStatus;\\n emit BridgeTokenToggled(bridgeToken, !pausedStatus);\\n }\\n\\n /// @notice Toggles fees for the address `theAddress`\\n function toggleFeesForAddress(address theAddress) external onlyGovernorOrGuardian {\\n uint256 feeExemptStatus = 1 - isFeeExempt[theAddress];\\n isFeeExempt[theAddress] = feeExemptStatus;\\n emit FeeToggled(theAddress, feeExemptStatus);\\n }\\n}\\n\",\"keccak256\":\"0x9782497e84a1dc4bc468778ede4aceb35cebf74e4159e2af8f469f49312c3841\",\"license\":\"GPL-3.0\"},\"contracts/interfaces/IAgToken.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-3.0\\n\\npragma solidity ^0.8.12;\\n\\nimport \\\"@openzeppelin/contracts-upgradeable/token/ERC20/IERC20Upgradeable.sol\\\";\\n\\n/// @title IAgToken\\n/// @author Angle Labs, Inc.\\n/// @notice Interface for the stablecoins `AgToken` contracts\\n/// @dev This interface only contains functions of the `AgToken` contract which are called by other contracts\\n/// of this module or of the first module of the Angle Protocol\\ninterface IAgToken is IERC20Upgradeable {\\n // ======================= Minter Role Only Functions ===========================\\n\\n /// @notice Lets the `StableMaster` contract or another whitelisted contract mint agTokens\\n /// @param account Address to mint to\\n /// @param amount Amount to mint\\n /// @dev The contracts allowed to issue agTokens are the `StableMaster` contract, `VaultManager` contracts\\n /// associated to this stablecoin as well as the flash loan module (if activated) and potentially contracts\\n /// whitelisted by governance\\n function mint(address account, uint256 amount) external;\\n\\n /// @notice Burns `amount` tokens from a `burner` address after being asked to by `sender`\\n /// @param amount Amount of tokens to burn\\n /// @param burner Address to burn from\\n /// @param sender Address which requested the burn from `burner`\\n /// @dev This method is to be called by a contract with the minter right after being requested\\n /// to do so by a `sender` address willing to burn tokens from another `burner` address\\n /// @dev The method checks the allowance between the `sender` and the `burner`\\n function burnFrom(uint256 amount, address burner, address sender) external;\\n\\n /// @notice Burns `amount` tokens from a `burner` address\\n /// @param amount Amount of tokens to burn\\n /// @param burner Address to burn from\\n /// @dev This method is to be called by a contract with a minter right on the AgToken after being\\n /// requested to do so by an address willing to burn tokens from its address\\n function burnSelf(uint256 amount, address burner) external;\\n\\n // ========================= Treasury Only Functions ===========================\\n\\n /// @notice Adds a minter in the contract\\n /// @param minter Minter address to add\\n /// @dev Zero address checks are performed directly in the `Treasury` contract\\n function addMinter(address minter) external;\\n\\n /// @notice Removes a minter from the contract\\n /// @param minter Minter address to remove\\n /// @dev This function can also be called by a minter wishing to revoke itself\\n function removeMinter(address minter) external;\\n\\n /// @notice Sets a new treasury contract\\n /// @param _treasury New treasury address\\n function setTreasury(address _treasury) external;\\n\\n // ========================= External functions ================================\\n\\n /// @notice Checks whether an address has the right to mint agTokens\\n /// @param minter Address for which the minting right should be checked\\n /// @return Whether the address has the right to mint agTokens or not\\n function isMinter(address minter) external view returns (bool);\\n\\n /// @notice Get the associated treasury\\n function treasury() external view returns (address);\\n}\\n\",\"keccak256\":\"0x0c83efcfc1fb9ae9ba830f7b89e3dab9abf6ad7a6205a31aa35fbccaa837dcdc\",\"license\":\"GPL-3.0\"},\"contracts/interfaces/ICoreBorrow.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-3.0\\n\\npragma solidity ^0.8.12;\\n\\n/// @title ICoreBorrow\\n/// @author Angle Labs, Inc.\\n/// @notice Interface for the `CoreBorrow` contract\\n/// @dev This interface only contains functions of the `CoreBorrow` contract which are called by other contracts\\n/// of this module\\ninterface ICoreBorrow {\\n /// @notice Checks if an address corresponds to a treasury of a stablecoin with a flash loan\\n /// module initialized on it\\n /// @param treasury Address to check\\n /// @return Whether the address has the `FLASHLOANER_TREASURY_ROLE` or not\\n function isFlashLoanerTreasury(address treasury) external view returns (bool);\\n\\n /// @notice Checks whether an address is governor of the Angle Protocol or not\\n /// @param admin Address to check\\n /// @return Whether the address has the `GOVERNOR_ROLE` or not\\n function isGovernor(address admin) external view returns (bool);\\n\\n /// @notice Checks whether an address is governor or a guardian of the Angle Protocol or not\\n /// @param admin Address to check\\n /// @return Whether the address has the `GUARDIAN_ROLE` or not\\n /// @dev Governance should make sure when adding a governor to also give this governor the guardian\\n /// role by calling the `addGovernor` function\\n function isGovernorOrGuardian(address admin) external view returns (bool);\\n}\\n\",\"keccak256\":\"0x10249210cbf522775f040baf981d7d037472168ce2746d87473ac7c29a34e62e\",\"license\":\"GPL-3.0\"},\"contracts/interfaces/IFlashAngle.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-3.0\\n\\npragma solidity ^0.8.12;\\n\\nimport \\\"./IAgToken.sol\\\";\\nimport \\\"./ICoreBorrow.sol\\\";\\n\\n/// @title IFlashAngle\\n/// @author Angle Labs, Inc.\\n/// @notice Interface for the `FlashAngle` contract\\n/// @dev This interface only contains functions of the contract which are called by other contracts\\n/// of this module\\ninterface IFlashAngle {\\n /// @notice Reference to the `CoreBorrow` contract managing the FlashLoan module\\n function core() external view returns (ICoreBorrow);\\n\\n /// @notice Sends the fees taken from flash loans to the treasury contract associated to the stablecoin\\n /// @param stablecoin Stablecoin from which profits should be sent\\n /// @return balance Amount of profits sent\\n /// @dev This function can only be called by the treasury contract\\n function accrueInterestToTreasury(IAgToken stablecoin) external returns (uint256 balance);\\n\\n /// @notice Adds support for a stablecoin\\n /// @param _treasury Treasury associated to the stablecoin to add support for\\n /// @dev This function can only be called by the `CoreBorrow` contract\\n function addStablecoinSupport(address _treasury) external;\\n\\n /// @notice Removes support for a stablecoin\\n /// @param _treasury Treasury associated to the stablecoin to remove support for\\n /// @dev This function can only be called by the `CoreBorrow` contract\\n function removeStablecoinSupport(address _treasury) external;\\n\\n /// @notice Sets a new core contract\\n /// @param _core Core contract address to set\\n /// @dev This function can only be called by the `CoreBorrow` contract\\n function setCore(address _core) external;\\n}\\n\",\"keccak256\":\"0x39b0097f695b9e934bccdc72676c91513f1077cc5d0fd151908fd25a7c5cfbe4\",\"license\":\"GPL-3.0\"},\"contracts/interfaces/ITreasury.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-3.0\\n\\npragma solidity ^0.8.12;\\n\\nimport \\\"./IAgToken.sol\\\";\\nimport \\\"./ICoreBorrow.sol\\\";\\nimport \\\"./IFlashAngle.sol\\\";\\n\\n/// @title ITreasury\\n/// @author Angle Labs, Inc.\\n/// @notice Interface for the `Treasury` contract\\n/// @dev This interface only contains functions of the `Treasury` which are called by other contracts\\n/// of this module\\ninterface ITreasury {\\n /// @notice Stablecoin handled by this `treasury` contract\\n function stablecoin() external view returns (IAgToken);\\n\\n /// @notice Checks whether a given address has the governor role\\n /// @param admin Address to check\\n /// @return Whether the address has the governor role\\n /// @dev Access control is only kept in the `CoreBorrow` contract\\n function isGovernor(address admin) external view returns (bool);\\n\\n /// @notice Checks whether a given address has the guardian or the governor role\\n /// @param admin Address to check\\n /// @return Whether the address has the guardian or the governor role\\n /// @dev Access control is only kept in the `CoreBorrow` contract which means that this function\\n /// queries the `CoreBorrow` contract\\n function isGovernorOrGuardian(address admin) external view returns (bool);\\n\\n /// @notice Checks whether a given address has well been initialized in this contract\\n /// as a `VaultManager`\\n /// @param _vaultManager Address to check\\n /// @return Whether the address has been initialized or not\\n function isVaultManager(address _vaultManager) external view returns (bool);\\n\\n /// @notice Sets a new flash loan module for this stablecoin\\n /// @param _flashLoanModule Reference to the new flash loan module\\n /// @dev This function removes the minting right to the old flash loan module and grants\\n /// it to the new module\\n function setFlashLoanModule(address _flashLoanModule) external;\\n\\n /// @notice Gets the vault manager list\\n function vaultManagerList(uint256 i) external returns (address);\\n}\\n\",\"keccak256\":\"0x06c2f781c08732ce1b5845c083af5742716245baa6c519bd737f32b230a884c1\",\"license\":\"GPL-3.0\"}},\"version\":1}", + "bytecode": "0x60806040523480156200001157600080fd5b50600054610100900460ff1615808015620000335750600054600160ff909116105b8062000063575062000050306200013d60201b6200273a1760201c565b15801562000063575060005460ff166001145b620000cb5760405162461bcd60e51b815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201526d191e481a5b9a5d1a585b1a5e995960921b606482015260840160405180910390fd5b6000805460ff191660011790558015620000ef576000805461ff0019166101001790555b801562000136576000805461ff0019169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15b506200014c565b6001600160a01b03163b151590565b6146d0806200015c6000396000f3fe608060405234801561001057600080fd5b50600436106102ff5760003560e01c806361d027b31161019c5780639f48118f116100ee578063ced67f0c11610097578063dd62ed3e11610071578063dd62ed3e14610724578063e3e286551461076a578063f0f442601461077d57600080fd5b8063ced67f0c1461066b578063d44ad63f146106fe578063d505accf1461071157600080fd5b8063aa271e1a116100c8578063aa271e1a14610620578063ba330bd714610643578063cd4839ca1461065657600080fd5b80639f48118f146105ef578063a457c2d7146105fa578063a9059cbb1461060d57600080fd5b80637ecebe001161015057806395d89b411161012a57806395d89b41146105c1578063983b2d56146105c95780639e4e0dae146105dc57600080fd5b80637ecebe00146105705780638933fb791461058357806390218cff146105ae57600080fd5b80637334d020116101815780637334d020146105425780637d4c9c2d146105555780637d74e25f1461056857600080fd5b806361d027b3146104c757806370a082311461050c57600080fd5b80633092afd511610255578063395093511161020957806340c10f19116101e357806340c10f19146104815780634dc32fcc146104945780635bfbec96146104a757600080fd5b8063395093511461043b5780633a55f89d1461044e5780633f4218e01461046157600080fd5b8063350ebe041161023a578063350ebe041461040d5780633644e5151461042057806336db43b51461042857600080fd5b80633092afd5146103eb578063313ce567146103fe57600080fd5b8063151dd755116102b757806323b872dd1161029157806323b872dd146103b25780632b471d8e146103c55780632e403e14146103d857600080fd5b8063151dd7551461038057806318160ddd146103a15780632342fb0e146103a957600080fd5b80630919a951116102e85780630919a95114610337578063095ea7b31461034a5780631171bda91461036d57600080fd5b806306fdde0314610304578063077f224a14610322575b600080fd5b61030c610790565b6040516103199190613e48565b60405180910390f35b610335610330366004613f95565b610822565b005b61033561034536600461400d565b610832565b61035d61035836600461402a565b610995565b6040519015158152602001610319565b61033561037b366004614056565b6109af565b61039361038e366004614097565b610b04565b604051908152602001610319565b603554610393565b61039360d25481565b61035d6103c0366004614056565b610dbe565b6103356103d33660046140ce565b610de2565b6103356103e636600461400d565b610e39565b6103356103f936600461400d565b6111e8565b60405160128152602001610319565b61033561041b3660046140fe565b6112d1565b6103936113da565b61033561043636600461402a565b6113e9565b61035d61044936600461402a565b611579565b61033561045c366004614135565b6115c0565b61039361046f36600461400d565b60d16020526000908152604090205481565b61033561048f36600461402a565b6116c3565b6103936104a236600461400d565b611716565b6103936104b5366004614135565b60d36020526000908152604090205481565b60cd546104e79073ffffffffffffffffffffffffffffffffffffffff1681565b60405173ffffffffffffffffffffffffffffffffffffffff9091168152602001610319565b61039361051a36600461400d565b73ffffffffffffffffffffffffffffffffffffffff1660009081526033602052604090205490565b61033561055036600461402a565b61175e565b610335610563366004614179565b6118f1565b610393611c59565b61039361057e36600461400d565b611c7e565b61039361059136600461402a565b60d060209081526000928352604080842090915290825290205481565b6103356105bc366004614135565b611ca9565b61030c611cb6565b6103356105d736600461400d565b611cc5565b6103356105ea3660046141d6565b611d8d565b610393633b9aca0081565b61035d61060836600461402a565b611f99565b61035d61061b36600461402a565b61206f565b61035d61062e36600461400d565b60cc6020526000908152604090205460ff1681565b6104e7610651366004614135565b61207d565b61065e6120b4565b604051610319919061420b565b6106c561067936600461400d565b60ce6020526000908152604090208054600182015460029092015490919067ffffffffffffffff81169060ff680100000000000000008204811691690100000000000000000090041685565b60408051958652602086019490945267ffffffffffffffff9092169284019290925290151560608301521515608082015260a001610319565b61039361070c366004614097565b612122565b61033561071f366004614265565b6122e7565b6103936107323660046142dc565b73ffffffffffffffffffffffffffffffffffffffff918216600090815260346020908152604080832093909416825291909152205490565b61033561077836600461400d565b6124a6565b61033561078b36600461400d565b61267a565b60606036805461079f9061430a565b80601f01602080910402602001604051908101604052809291908181526020018280546107cb9061430a565b80156108185780601f106107ed57610100808354040283529160200191610818565b820191906000526020600020905b8154815290600101906020018083116107fb57829003601f168201915b5050505050905090565b61082d838383612756565b505050565b60cd546040517f521d4de900000000000000000000000000000000000000000000000000000000815233600482015273ffffffffffffffffffffffffffffffffffffffff9091169063521d4de990602401602060405180830381865afa1580156108a0573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906108c49190614357565b6108fa576040517f99e120bc00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff8116600090815260d1602052604081205461092b9060016143a3565b73ffffffffffffffffffffffffffffffffffffffff8316600081815260d160205260409081902083905551919250907f979ef83e7e7a87cb48064e296dd7e997870d50f43acf8d7ad221313526c8ca0f906109899084815260200190565b60405180910390a25050565b6000336109a3818585612a35565b60019150505b92915050565b60cd546040517fe43581b800000000000000000000000000000000000000000000000000000000815233600482015273ffffffffffffffffffffffffffffffffffffffff9091169063e43581b890602401602060405180830381865afa158015610a1d573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610a419190614357565b610a77576040517fee3675d400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b610a9873ffffffffffffffffffffffffffffffffffffffff84168383612be0565b8173ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff167ffff3b3844276f57024e0b42afec1a37f75db36511e43819a4f2a63ab7862b64883604051610af791815260200190565b60405180910390a3505050565b73ffffffffffffffffffffffffffffffffffffffff8316600090815260ce60209081526040808320815160a081018352815481526001820154938101939093526002015467ffffffffffffffff81169183019190915260ff680100000000000000008204811615801560608501526901000000000000000000909204161515608083015280610b94575080608001515b15610bcb576040517fc1ab6dc100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015260009073ffffffffffffffffffffffffffffffffffffffff8716906370a0823190602401602060405180830381865afa158015610c38573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610c5c91906143b6565b8251909150610c6b86836143cf565b1115610c93578151811015610c8e578151610c879082906143a3565b9450610c93565b600094505b6000610ca1610e10426143e2565b73ffffffffffffffffffffffffffffffffffffffff8816600090815260d0602090815260408083208484528252909120549085015191925090610ce488836143cf565b1115610d0f5780846020015111610cfc576000610d0c565b808460200151610d0c91906143a3565b96505b610d1987826143cf565b73ffffffffffffffffffffffffffffffffffffffff8916600081815260d060209081526040808320878452909152902091909155610d599033308a612cb4565b33600090815260d16020526040812054889103610da657633b9aca00856040015167ffffffffffffffff1682610d8f919061441d565b610d9991906143e2565b610da390826143a3565b90505b610db08782612d12565b9450505050505b9392505050565b600033610dcc858285612e32565b610dd7858585612f03565b506001949350505050565b33600090815260cc602052604090205460ff16610e2b576040517ff8d2906c00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b610e3581836131b6565b5050565b60cd546040517fe43581b800000000000000000000000000000000000000000000000000000000815233600482015273ffffffffffffffffffffffffffffffffffffffff9091169063e43581b890602401602060405180830381865afa158015610ea7573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610ecb9190614357565b610f01576040517fee3675d400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015273ffffffffffffffffffffffffffffffffffffffff8216906370a0823190602401602060405180830381865afa158015610f6b573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610f8f91906143b6565b15610fc6576040517f2ef630ec00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff8116600090815260ce602052604081208181556001810182905560020180547fffffffffffffffffffffffffffffffffffffffffffff0000000000000000000016905560cf54905b61102e6001836143a3565b811015611139578273ffffffffffffffffffffffffffffffffffffffff1660cf828154811061105f5761105f614434565b60009182526020909120015473ffffffffffffffffffffffffffffffffffffffff16036111295760cf6110936001846143a3565b815481106110a3576110a3614434565b60009182526020909120015460cf805473ffffffffffffffffffffffffffffffffffffffff90921691839081106110dc576110dc614434565b9060005260206000200160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550611139565b61113281614463565b9050611023565b5060cf80548061114b5761114b61449b565b60008281526020812082017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff90810180547fffffffffffffffffffffffff000000000000000000000000000000000000000016905590910190915560405173ffffffffffffffffffffffffffffffffffffffff8416917f5c95b49c4d59d97a2f044167723f29c74b30f99702e3fd406c3830160aa9ccb891a25050565b60cd5473ffffffffffffffffffffffffffffffffffffffff16331480159061122657503373ffffffffffffffffffffffffffffffffffffffff821614155b1561125d576040517fddb5de5e00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff8116600081815260cc602052604080822080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00169055517f98c15241d6c02bc5ee0b780e11b3ea737a2defd9d04877edbe9f9497065bd02f9190a250565b33600090815260cc602052604090205460ff1661131a576040517ff8d2906c00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff16146113d05773ffffffffffffffffffffffffffffffffffffffff828116600090815260346020908152604080832093851683529290522054838110156113ba576040517f715ec26c00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6113ce83836113c987856143a3565b612a35565b505b61082d82846131b6565b60006113e46133a3565b905090565b60cd546040517f521d4de900000000000000000000000000000000000000000000000000000000815233600482015273ffffffffffffffffffffffffffffffffffffffff9091169063521d4de990602401602060405180830381865afa158015611457573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061147b9190614357565b6114b1576040517f99e120bc00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff8216600090815260ce602052604090206002015468010000000000000000900460ff1661151f576040517fc1ab6dc100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff8216600081815260ce602052604090819020839055517fe7b113fba37131b6396680a0c55790a697ec975e198ff8cfd89dac90a6379e61906109899084815260200190565b33600081815260346020908152604080832073ffffffffffffffffffffffffffffffffffffffff871684529091528120549091906109a390829086906113c99087906143cf565b60cd546040517f521d4de900000000000000000000000000000000000000000000000000000000815233600482015273ffffffffffffffffffffffffffffffffffffffff9091169063521d4de990602401602060405180830381865afa15801561162e573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906116529190614357565b611688576040517f99e120bc00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60d28190556040518181527fc3b69829afe2345596a02c8b587d41f796ba0094481d899e1b2e07b7532a1e219060200160405180910390a150565b33600090815260cc602052604090205460ff1661170c576040517ff8d2906c00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b610e358282612d12565b73ffffffffffffffffffffffffffffffffffffffff8116600090815260d06020526040812081611748610e10426143e2565b8152602001908152602001600020549050919050565b60cd546040517f521d4de900000000000000000000000000000000000000000000000000000000815233600482015273ffffffffffffffffffffffffffffffffffffffff9091169063521d4de990602401602060405180830381865afa1580156117cc573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906117f09190614357565b611826576040517f99e120bc00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff8216600090815260ce602052604090206002015468010000000000000000900460ff16611894576040517fc1ab6dc100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff8216600081815260ce602052604090819020600101839055517fe13ac9338b2ee623233f83c1b3ceab16490fa3e3737fac7f0970d0830a9f4871906109899084815260200190565b60cd546040517fe43581b800000000000000000000000000000000000000000000000000000000815233600482015273ffffffffffffffffffffffffffffffffffffffff9091169063e43581b890602401602060405180830381865afa15801561195f573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906119839190614357565b6119b9576040517fee3675d400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff8516600090815260ce602052604090206002015468010000000000000000900460ff1680611a10575073ffffffffffffffffffffffffffffffffffffffff8516155b15611a47576040517fc1ab6dc100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b633b9aca008267ffffffffffffffff161115611a8f576040517feca1d2c600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040805160a08101825260008082526020820181905291810182905260608101829052608081019190915284815260208082018581528315156080840190815267ffffffffffffffff808716604080870191825260016060880181815273ffffffffffffffffffffffffffffffffffffffff8e16600081815260ce9099528389208a5181559751888401559351600290970180549151965115156901000000000000000000027fffffffffffffffffffffffffffffffffffffffffffff00ffffffffffffffffff97151568010000000000000000027fffffffffffffffffffffffffffffffffffffffffffffff000000000000000000909316989096169790971717949094169290921790935560cf805492830181559093527facb8d954e2cfef495862221e91bd7523613cf8808827cb33edfe4904cc51bf290180547fffffffffffffffffffffffff0000000000000000000000000000000000000000168217905590517f53087ff85d80a7671594bd2e86b92af22e0b3c2c441c8033bba7399b7b5cbe2390611c49908890889088908890938452602084019290925267ffffffffffffffff1660408301521515606082015260800190565b60405180910390a2505050505050565b600060d381611c6a610e10426143e2565b815260200190815260200160002054905090565b73ffffffffffffffffffffffffffffffffffffffff81166000908152609960205260408120546109a9565b611cb333826131b6565b50565b60606037805461079f9061430a565b60cd5473ffffffffffffffffffffffffffffffffffffffff163314611d16576040517fb90cdbb100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff8116600081815260cc602052604080822080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00166001179055517f98c15241d6c02bc5ee0b780e11b3ea737a2defd9d04877edbe9f9497065bd02f9190a250565b60cd546040517f521d4de900000000000000000000000000000000000000000000000000000000815233600482015273ffffffffffffffffffffffffffffffffffffffff9091169063521d4de990602401602060405180830381865afa158015611dfb573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611e1f9190614357565b611e55576040517f99e120bc00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff8216600090815260ce602052604090206002015468010000000000000000900460ff16611ec3576040517fc1ab6dc100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b633b9aca008167ffffffffffffffff161115611f0b576040517feca1d2c600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff8216600081815260ce602090815260409182902060020180547fffffffffffffffffffffffffffffffffffffffffffffffff00000000000000001667ffffffffffffffff861690811790915591519182527f901f9de19b475adc8da4110434b8df940dce085afd05e2281c86807f3a899d299101610989565b33600081815260346020908152604080832073ffffffffffffffffffffffffffffffffffffffff8716845290915281205490919083811015612062576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602560248201527f45524332303a2064656372656173656420616c6c6f77616e63652062656c6f7760448201527f207a65726f00000000000000000000000000000000000000000000000000000060648201526084015b60405180910390fd5b610dd78286868403612a35565b6000336109a3818585612f03565b60cf818154811061208d57600080fd5b60009182526020909120015473ffffffffffffffffffffffffffffffffffffffff16905081565b606060cf80548060200260200160405190810160405280929190818152602001828054801561081857602002820191906000526020600020905b815473ffffffffffffffffffffffffffffffffffffffff1681526001909101906020018083116120ee575050505050905090565b73ffffffffffffffffffffffffffffffffffffffff8316600090815260ce60209081526040808320815160a081018352815481526001820154938101939093526002015467ffffffffffffffff81169183019190915260ff6801000000000000000082048116158015606085015269010000000000000000009092041615156080830152806121b2575080608001515b156121e9576040517fc1ab6dc100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60006121f7610e10426143e2565b600081815260d36020526040812054919250906122159087906143cf565b905060d254811115612253576040517f6d43d1ac00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600082815260d36020526040902081905561226e33876131b6565b33600090815260d160205260408120548791036122bb57633b9aca00846040015167ffffffffffffffff16826122a4919061441d565b6122ae91906143e2565b6122b890826143a3565b90505b6122dc73ffffffffffffffffffffffffffffffffffffffff89168783612be0565b979650505050505050565b83421115612351576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f45524332305065726d69743a206578706972656420646561646c696e650000006044820152606401612059565b60007f6e71edae12b1b97f4d1f60370fef10105fa2faae0126114a169c64845d6126c98888886123808c61341e565b60408051602081019690965273ffffffffffffffffffffffffffffffffffffffff94851690860152929091166060840152608083015260a082015260c0810186905260e00160405160208183030381529060405280519060200120905060006123e882613453565b905060006123f8828787876134bc565b90508973ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff161461248f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601e60248201527f45524332305065726d69743a20696e76616c6964207369676e617475726500006044820152606401612059565b61249a8a8a8a612a35565b50505050505050505050565b60cd546040517f521d4de900000000000000000000000000000000000000000000000000000000815233600482015273ffffffffffffffffffffffffffffffffffffffff9091169063521d4de990602401602060405180830381865afa158015612514573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906125389190614357565b61256e576040517f99e120bc00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff8116600090815260ce602052604090206002015468010000000000000000900460ff166125dc576040517fc1ab6dc100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff8116600081815260ce602090815260409182902060020180547fffffffffffffffffffffffffffffffffffffffffffff00ffffffffffffffffff811669010000000000000000009182900460ff16801592830291909117909255925192835292917ff7c93079dcbf699749d66345a351afab7d24219bb1d915c9f4fc4cf03f00d3979101610989565b60cd5473ffffffffffffffffffffffffffffffffffffffff1633146126cb576040517fb90cdbb100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60cd80547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83169081179091556040517f7dae230f18360d76a040c81f050aa14eb9d6dc7901b20fc5d855e2a20fe814d190600090a250565b73ffffffffffffffffffffffffffffffffffffffff163b151590565b600054610100900460ff16158080156127765750600054600160ff909116105b806127905750303b158015612790575060005460ff166001145b61281c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201527f647920696e697469616c697a65640000000000000000000000000000000000006064820152608401612059565b600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00166001179055801561287a57600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff166101001790555b3073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1663e9cbd8226040518163ffffffff1660e01b8152600401602060405180830381865afa1580156128dc573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061290091906144ca565b73ffffffffffffffffffffffffffffffffffffffff161461294d576040517f14bcf5c800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b612956846134e4565b61296084846135ba565b60cd80547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff84169081179091556040517f7dae230f18360d76a040c81f050aa14eb9d6dc7901b20fc5d855e2a20fe814d190600090a28015612a2f57600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15b50505050565b73ffffffffffffffffffffffffffffffffffffffff8316612ad7576040517f08c379a0000000000000000000000000000000000000000000000000000000008152602060048201526024808201527f45524332303a20617070726f76652066726f6d20746865207a65726f2061646460448201527f72657373000000000000000000000000000000000000000000000000000000006064820152608401612059565b73ffffffffffffffffffffffffffffffffffffffff8216612b7a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602260248201527f45524332303a20617070726f766520746f20746865207a65726f20616464726560448201527f73730000000000000000000000000000000000000000000000000000000000006064820152608401612059565b73ffffffffffffffffffffffffffffffffffffffff83811660008181526034602090815260408083209487168084529482529182902085905590518481527f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b9259101610af7565b60405173ffffffffffffffffffffffffffffffffffffffff831660248201526044810182905261082d9084907fa9059cbb00000000000000000000000000000000000000000000000000000000906064015b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff000000000000000000000000000000000000000000000000000000009093169290921790915261365b565b60405173ffffffffffffffffffffffffffffffffffffffff80851660248301528316604482015260648101829052612a2f9085907f23b872dd0000000000000000000000000000000000000000000000000000000090608401612c32565b73ffffffffffffffffffffffffffffffffffffffff8216612d8f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601f60248201527f45524332303a206d696e7420746f20746865207a65726f2061646472657373006044820152606401612059565b8060356000828254612da191906143cf565b909155505073ffffffffffffffffffffffffffffffffffffffff821660009081526033602052604081208054839290612ddb9084906143cf565b909155505060405181815273ffffffffffffffffffffffffffffffffffffffff8316906000907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef9060200160405180910390a35050565b73ffffffffffffffffffffffffffffffffffffffff8381166000908152603460209081526040808320938616835292905220547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8114612a2f5781811015612ef6576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f45524332303a20696e73756666696369656e7420616c6c6f77616e63650000006044820152606401612059565b612a2f8484848403612a35565b73ffffffffffffffffffffffffffffffffffffffff8316612fa6576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602560248201527f45524332303a207472616e736665722066726f6d20746865207a65726f20616460448201527f64726573730000000000000000000000000000000000000000000000000000006064820152608401612059565b73ffffffffffffffffffffffffffffffffffffffff8216613049576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602360248201527f45524332303a207472616e7366657220746f20746865207a65726f206164647260448201527f65737300000000000000000000000000000000000000000000000000000000006064820152608401612059565b73ffffffffffffffffffffffffffffffffffffffff8316600090815260336020526040902054818110156130ff576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f45524332303a207472616e7366657220616d6f756e742065786365656473206260448201527f616c616e636500000000000000000000000000000000000000000000000000006064820152608401612059565b73ffffffffffffffffffffffffffffffffffffffff8085166000908152603360205260408082208585039055918516815290812080548492906131439084906143cf565b925050819055508273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef846040516131a991815260200190565b60405180910390a3612a2f565b73ffffffffffffffffffffffffffffffffffffffff8216613259576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602160248201527f45524332303a206275726e2066726f6d20746865207a65726f2061646472657360448201527f73000000000000000000000000000000000000000000000000000000000000006064820152608401612059565b73ffffffffffffffffffffffffffffffffffffffff82166000908152603360205260409020548181101561330f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602260248201527f45524332303a206275726e20616d6f756e7420657863656564732062616c616e60448201527f63650000000000000000000000000000000000000000000000000000000000006064820152608401612059565b73ffffffffffffffffffffffffffffffffffffffff8316600090815260336020526040812083830390556035805484929061334b9084906143a3565b909155505060405182815260009073ffffffffffffffffffffffffffffffffffffffff8516907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef9060200160405180910390a3505050565b60006113e47f8b73c3c69bb8fe3d512ecc4cf759cc79239f7b179b0ffacaa9a75d522b39400f6133d260655490565b6066546040805160208101859052908101839052606081018290524660808201523060a082015260009060c0016040516020818303038152906040528051906020012090509392505050565b73ffffffffffffffffffffffffffffffffffffffff811660009081526099602052604090208054600181018255905b50919050565b60006109a96134606133a3565b836040517f19010000000000000000000000000000000000000000000000000000000000006020820152602281018390526042810182905260009060620160405160208183030381529060405280519060200120905092915050565b60008060006134cd87878787613767565b915091506134da8161387f565b5095945050505050565b600054610100900460ff1661357b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201527f6e697469616c697a696e670000000000000000000000000000000000000000006064820152608401612059565b611cb3816040518060400160405280600181526020017f3100000000000000000000000000000000000000000000000000000000000000815250613ad3565b600054610100900460ff16613651576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201527f6e697469616c697a696e670000000000000000000000000000000000000000006064820152608401612059565b610e358282613b84565b60006136bd826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c65648152508573ffffffffffffffffffffffffffffffffffffffff16613c349092919063ffffffff16565b80519091501561082d57808060200190518101906136db9190614357565b61082d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e60448201527f6f742073756363656564000000000000000000000000000000000000000000006064820152608401612059565b6000807f7fffffffffffffffffffffffffffffff5d576e7357a4501ddfe92f46681b20a083111561379e5750600090506003613876565b8460ff16601b141580156137b657508460ff16601c14155b156137c75750600090506004613876565b6040805160008082526020820180845289905260ff881692820192909252606081018690526080810185905260019060a0016020604051602081039080840390855afa15801561381b573d6000803e3d6000fd5b50506040517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0015191505073ffffffffffffffffffffffffffffffffffffffff811661386f57600060019250925050613876565b9150600090505b94509492505050565b6000816004811115613893576138936144e7565b0361389b5750565b60018160048111156138af576138af6144e7565b03613916576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601860248201527f45434453413a20696e76616c6964207369676e617475726500000000000000006044820152606401612059565b600281600481111561392a5761392a6144e7565b03613991576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601f60248201527f45434453413a20696e76616c6964207369676e6174757265206c656e677468006044820152606401612059565b60038160048111156139a5576139a56144e7565b03613a32576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602260248201527f45434453413a20696e76616c6964207369676e6174757265202773272076616c60448201527f75650000000000000000000000000000000000000000000000000000000000006064820152608401612059565b6004816004811115613a4657613a466144e7565b03611cb3576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602260248201527f45434453413a20696e76616c6964207369676e6174757265202776272076616c60448201527f75650000000000000000000000000000000000000000000000000000000000006064820152608401612059565b600054610100900460ff16613b6a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201527f6e697469616c697a696e670000000000000000000000000000000000000000006064820152608401612059565b815160209283012081519190920120606591909155606655565b600054610100900460ff16613c1b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201527f6e697469616c697a696e670000000000000000000000000000000000000000006064820152608401612059565b6036613c278382614564565b50603761082d8282614564565b6060613c438484600085613c4b565b949350505050565b606082471015613cdd576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f60448201527f722063616c6c00000000000000000000000000000000000000000000000000006064820152608401612059565b73ffffffffffffffffffffffffffffffffffffffff85163b613d5b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006044820152606401612059565b6000808673ffffffffffffffffffffffffffffffffffffffff168587604051613d84919061467e565b60006040518083038185875af1925050503d8060008114613dc1576040519150601f19603f3d011682016040523d82523d6000602084013e613dc6565b606091505b50915091506122dc82828660608315613de0575081610db7565b825115613df05782518084602001fd5b816040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016120599190613e48565b60005b83811015613e3f578181015183820152602001613e27565b50506000910152565b6020815260008251806020840152613e67816040850160208701613e24565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169190910160400192915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b600082601f830112613ed957600080fd5b813567ffffffffffffffff80821115613ef457613ef4613e99565b604051601f83017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0908116603f01168101908282118183101715613f3a57613f3a613e99565b81604052838152866020858801011115613f5357600080fd5b836020870160208301376000602085830101528094505050505092915050565b73ffffffffffffffffffffffffffffffffffffffff81168114611cb357600080fd5b600080600060608486031215613faa57600080fd5b833567ffffffffffffffff80821115613fc257600080fd5b613fce87838801613ec8565b94506020860135915080821115613fe457600080fd5b50613ff186828701613ec8565b925050604084013561400281613f73565b809150509250925092565b60006020828403121561401f57600080fd5b8135610db781613f73565b6000806040838503121561403d57600080fd5b823561404881613f73565b946020939093013593505050565b60008060006060848603121561406b57600080fd5b833561407681613f73565b9250602084013561408681613f73565b929592945050506040919091013590565b6000806000606084860312156140ac57600080fd5b83356140b781613f73565b925060208401359150604084013561400281613f73565b600080604083850312156140e157600080fd5b8235915060208301356140f381613f73565b809150509250929050565b60008060006060848603121561411357600080fd5b83359250602084013561412581613f73565b9150604084013561400281613f73565b60006020828403121561414757600080fd5b5035919050565b803567ffffffffffffffff8116811461416657600080fd5b919050565b8015158114611cb357600080fd5b600080600080600060a0868803121561419157600080fd5b853561419c81613f73565b945060208601359350604086013592506141b86060870161414e565b915060808601356141c88161416b565b809150509295509295909350565b600080604083850312156141e957600080fd5b82356141f481613f73565b91506142026020840161414e565b90509250929050565b6020808252825182820181905260009190848201906040850190845b8181101561425957835173ffffffffffffffffffffffffffffffffffffffff1683529284019291840191600101614227565b50909695505050505050565b600080600080600080600060e0888a03121561428057600080fd5b873561428b81613f73565b9650602088013561429b81613f73565b95506040880135945060608801359350608088013560ff811681146142bf57600080fd5b9699959850939692959460a0840135945060c09093013592915050565b600080604083850312156142ef57600080fd5b82356142fa81613f73565b915060208301356140f381613f73565b600181811c9082168061431e57607f821691505b60208210810361344d577f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b60006020828403121561436957600080fd5b8151610db78161416b565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b818103818111156109a9576109a9614374565b6000602082840312156143c857600080fd5b5051919050565b808201808211156109a9576109a9614374565b600082614418577f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b500490565b80820281158282048414176109a9576109a9614374565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff820361449457614494614374565b5060010190565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603160045260246000fd5b6000602082840312156144dc57600080fd5b8151610db781613f73565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b601f82111561082d57600081815260208120601f850160051c8101602086101561453d5750805b601f850160051c820191505b8181101561455c57828155600101614549565b505050505050565b815167ffffffffffffffff81111561457e5761457e613e99565b6145928161458c845461430a565b84614516565b602080601f8311600181146145e557600084156145af5750858301515b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600386901b1c1916600185901b17855561455c565b6000858152602081207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08616915b8281101561463257888601518255948401946001909101908401614613565b508582101561466e57878501517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600388901b60f8161c191681555b5050505050600190811b01905550565b60008251614690818460208701613e24565b919091019291505056fea2646970667358221220f2eb02bac1667a72be85ab617a5b5aa3d8f7a9b09b4d1fde9756b7a5636daf2164736f6c63430008110033", + "deployedBytecode": "0x608060405234801561001057600080fd5b50600436106102ff5760003560e01c806361d027b31161019c5780639f48118f116100ee578063ced67f0c11610097578063dd62ed3e11610071578063dd62ed3e14610724578063e3e286551461076a578063f0f442601461077d57600080fd5b8063ced67f0c1461066b578063d44ad63f146106fe578063d505accf1461071157600080fd5b8063aa271e1a116100c8578063aa271e1a14610620578063ba330bd714610643578063cd4839ca1461065657600080fd5b80639f48118f146105ef578063a457c2d7146105fa578063a9059cbb1461060d57600080fd5b80637ecebe001161015057806395d89b411161012a57806395d89b41146105c1578063983b2d56146105c95780639e4e0dae146105dc57600080fd5b80637ecebe00146105705780638933fb791461058357806390218cff146105ae57600080fd5b80637334d020116101815780637334d020146105425780637d4c9c2d146105555780637d74e25f1461056857600080fd5b806361d027b3146104c757806370a082311461050c57600080fd5b80633092afd511610255578063395093511161020957806340c10f19116101e357806340c10f19146104815780634dc32fcc146104945780635bfbec96146104a757600080fd5b8063395093511461043b5780633a55f89d1461044e5780633f4218e01461046157600080fd5b8063350ebe041161023a578063350ebe041461040d5780633644e5151461042057806336db43b51461042857600080fd5b80633092afd5146103eb578063313ce567146103fe57600080fd5b8063151dd755116102b757806323b872dd1161029157806323b872dd146103b25780632b471d8e146103c55780632e403e14146103d857600080fd5b8063151dd7551461038057806318160ddd146103a15780632342fb0e146103a957600080fd5b80630919a951116102e85780630919a95114610337578063095ea7b31461034a5780631171bda91461036d57600080fd5b806306fdde0314610304578063077f224a14610322575b600080fd5b61030c610790565b6040516103199190613e48565b60405180910390f35b610335610330366004613f95565b610822565b005b61033561034536600461400d565b610832565b61035d61035836600461402a565b610995565b6040519015158152602001610319565b61033561037b366004614056565b6109af565b61039361038e366004614097565b610b04565b604051908152602001610319565b603554610393565b61039360d25481565b61035d6103c0366004614056565b610dbe565b6103356103d33660046140ce565b610de2565b6103356103e636600461400d565b610e39565b6103356103f936600461400d565b6111e8565b60405160128152602001610319565b61033561041b3660046140fe565b6112d1565b6103936113da565b61033561043636600461402a565b6113e9565b61035d61044936600461402a565b611579565b61033561045c366004614135565b6115c0565b61039361046f36600461400d565b60d16020526000908152604090205481565b61033561048f36600461402a565b6116c3565b6103936104a236600461400d565b611716565b6103936104b5366004614135565b60d36020526000908152604090205481565b60cd546104e79073ffffffffffffffffffffffffffffffffffffffff1681565b60405173ffffffffffffffffffffffffffffffffffffffff9091168152602001610319565b61039361051a36600461400d565b73ffffffffffffffffffffffffffffffffffffffff1660009081526033602052604090205490565b61033561055036600461402a565b61175e565b610335610563366004614179565b6118f1565b610393611c59565b61039361057e36600461400d565b611c7e565b61039361059136600461402a565b60d060209081526000928352604080842090915290825290205481565b6103356105bc366004614135565b611ca9565b61030c611cb6565b6103356105d736600461400d565b611cc5565b6103356105ea3660046141d6565b611d8d565b610393633b9aca0081565b61035d61060836600461402a565b611f99565b61035d61061b36600461402a565b61206f565b61035d61062e36600461400d565b60cc6020526000908152604090205460ff1681565b6104e7610651366004614135565b61207d565b61065e6120b4565b604051610319919061420b565b6106c561067936600461400d565b60ce6020526000908152604090208054600182015460029092015490919067ffffffffffffffff81169060ff680100000000000000008204811691690100000000000000000090041685565b60408051958652602086019490945267ffffffffffffffff9092169284019290925290151560608301521515608082015260a001610319565b61039361070c366004614097565b612122565b61033561071f366004614265565b6122e7565b6103936107323660046142dc565b73ffffffffffffffffffffffffffffffffffffffff918216600090815260346020908152604080832093909416825291909152205490565b61033561077836600461400d565b6124a6565b61033561078b36600461400d565b61267a565b60606036805461079f9061430a565b80601f01602080910402602001604051908101604052809291908181526020018280546107cb9061430a565b80156108185780601f106107ed57610100808354040283529160200191610818565b820191906000526020600020905b8154815290600101906020018083116107fb57829003601f168201915b5050505050905090565b61082d838383612756565b505050565b60cd546040517f521d4de900000000000000000000000000000000000000000000000000000000815233600482015273ffffffffffffffffffffffffffffffffffffffff9091169063521d4de990602401602060405180830381865afa1580156108a0573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906108c49190614357565b6108fa576040517f99e120bc00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff8116600090815260d1602052604081205461092b9060016143a3565b73ffffffffffffffffffffffffffffffffffffffff8316600081815260d160205260409081902083905551919250907f979ef83e7e7a87cb48064e296dd7e997870d50f43acf8d7ad221313526c8ca0f906109899084815260200190565b60405180910390a25050565b6000336109a3818585612a35565b60019150505b92915050565b60cd546040517fe43581b800000000000000000000000000000000000000000000000000000000815233600482015273ffffffffffffffffffffffffffffffffffffffff9091169063e43581b890602401602060405180830381865afa158015610a1d573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610a419190614357565b610a77576040517fee3675d400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b610a9873ffffffffffffffffffffffffffffffffffffffff84168383612be0565b8173ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff167ffff3b3844276f57024e0b42afec1a37f75db36511e43819a4f2a63ab7862b64883604051610af791815260200190565b60405180910390a3505050565b73ffffffffffffffffffffffffffffffffffffffff8316600090815260ce60209081526040808320815160a081018352815481526001820154938101939093526002015467ffffffffffffffff81169183019190915260ff680100000000000000008204811615801560608501526901000000000000000000909204161515608083015280610b94575080608001515b15610bcb576040517fc1ab6dc100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015260009073ffffffffffffffffffffffffffffffffffffffff8716906370a0823190602401602060405180830381865afa158015610c38573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610c5c91906143b6565b8251909150610c6b86836143cf565b1115610c93578151811015610c8e578151610c879082906143a3565b9450610c93565b600094505b6000610ca1610e10426143e2565b73ffffffffffffffffffffffffffffffffffffffff8816600090815260d0602090815260408083208484528252909120549085015191925090610ce488836143cf565b1115610d0f5780846020015111610cfc576000610d0c565b808460200151610d0c91906143a3565b96505b610d1987826143cf565b73ffffffffffffffffffffffffffffffffffffffff8916600081815260d060209081526040808320878452909152902091909155610d599033308a612cb4565b33600090815260d16020526040812054889103610da657633b9aca00856040015167ffffffffffffffff1682610d8f919061441d565b610d9991906143e2565b610da390826143a3565b90505b610db08782612d12565b9450505050505b9392505050565b600033610dcc858285612e32565b610dd7858585612f03565b506001949350505050565b33600090815260cc602052604090205460ff16610e2b576040517ff8d2906c00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b610e3581836131b6565b5050565b60cd546040517fe43581b800000000000000000000000000000000000000000000000000000000815233600482015273ffffffffffffffffffffffffffffffffffffffff9091169063e43581b890602401602060405180830381865afa158015610ea7573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610ecb9190614357565b610f01576040517fee3675d400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015273ffffffffffffffffffffffffffffffffffffffff8216906370a0823190602401602060405180830381865afa158015610f6b573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610f8f91906143b6565b15610fc6576040517f2ef630ec00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff8116600090815260ce602052604081208181556001810182905560020180547fffffffffffffffffffffffffffffffffffffffffffff0000000000000000000016905560cf54905b61102e6001836143a3565b811015611139578273ffffffffffffffffffffffffffffffffffffffff1660cf828154811061105f5761105f614434565b60009182526020909120015473ffffffffffffffffffffffffffffffffffffffff16036111295760cf6110936001846143a3565b815481106110a3576110a3614434565b60009182526020909120015460cf805473ffffffffffffffffffffffffffffffffffffffff90921691839081106110dc576110dc614434565b9060005260206000200160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550611139565b61113281614463565b9050611023565b5060cf80548061114b5761114b61449b565b60008281526020812082017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff90810180547fffffffffffffffffffffffff000000000000000000000000000000000000000016905590910190915560405173ffffffffffffffffffffffffffffffffffffffff8416917f5c95b49c4d59d97a2f044167723f29c74b30f99702e3fd406c3830160aa9ccb891a25050565b60cd5473ffffffffffffffffffffffffffffffffffffffff16331480159061122657503373ffffffffffffffffffffffffffffffffffffffff821614155b1561125d576040517fddb5de5e00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff8116600081815260cc602052604080822080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00169055517f98c15241d6c02bc5ee0b780e11b3ea737a2defd9d04877edbe9f9497065bd02f9190a250565b33600090815260cc602052604090205460ff1661131a576040517ff8d2906c00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff16146113d05773ffffffffffffffffffffffffffffffffffffffff828116600090815260346020908152604080832093851683529290522054838110156113ba576040517f715ec26c00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6113ce83836113c987856143a3565b612a35565b505b61082d82846131b6565b60006113e46133a3565b905090565b60cd546040517f521d4de900000000000000000000000000000000000000000000000000000000815233600482015273ffffffffffffffffffffffffffffffffffffffff9091169063521d4de990602401602060405180830381865afa158015611457573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061147b9190614357565b6114b1576040517f99e120bc00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff8216600090815260ce602052604090206002015468010000000000000000900460ff1661151f576040517fc1ab6dc100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff8216600081815260ce602052604090819020839055517fe7b113fba37131b6396680a0c55790a697ec975e198ff8cfd89dac90a6379e61906109899084815260200190565b33600081815260346020908152604080832073ffffffffffffffffffffffffffffffffffffffff871684529091528120549091906109a390829086906113c99087906143cf565b60cd546040517f521d4de900000000000000000000000000000000000000000000000000000000815233600482015273ffffffffffffffffffffffffffffffffffffffff9091169063521d4de990602401602060405180830381865afa15801561162e573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906116529190614357565b611688576040517f99e120bc00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60d28190556040518181527fc3b69829afe2345596a02c8b587d41f796ba0094481d899e1b2e07b7532a1e219060200160405180910390a150565b33600090815260cc602052604090205460ff1661170c576040517ff8d2906c00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b610e358282612d12565b73ffffffffffffffffffffffffffffffffffffffff8116600090815260d06020526040812081611748610e10426143e2565b8152602001908152602001600020549050919050565b60cd546040517f521d4de900000000000000000000000000000000000000000000000000000000815233600482015273ffffffffffffffffffffffffffffffffffffffff9091169063521d4de990602401602060405180830381865afa1580156117cc573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906117f09190614357565b611826576040517f99e120bc00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff8216600090815260ce602052604090206002015468010000000000000000900460ff16611894576040517fc1ab6dc100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff8216600081815260ce602052604090819020600101839055517fe13ac9338b2ee623233f83c1b3ceab16490fa3e3737fac7f0970d0830a9f4871906109899084815260200190565b60cd546040517fe43581b800000000000000000000000000000000000000000000000000000000815233600482015273ffffffffffffffffffffffffffffffffffffffff9091169063e43581b890602401602060405180830381865afa15801561195f573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906119839190614357565b6119b9576040517fee3675d400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff8516600090815260ce602052604090206002015468010000000000000000900460ff1680611a10575073ffffffffffffffffffffffffffffffffffffffff8516155b15611a47576040517fc1ab6dc100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b633b9aca008267ffffffffffffffff161115611a8f576040517feca1d2c600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040805160a08101825260008082526020820181905291810182905260608101829052608081019190915284815260208082018581528315156080840190815267ffffffffffffffff808716604080870191825260016060880181815273ffffffffffffffffffffffffffffffffffffffff8e16600081815260ce9099528389208a5181559751888401559351600290970180549151965115156901000000000000000000027fffffffffffffffffffffffffffffffffffffffffffff00ffffffffffffffffff97151568010000000000000000027fffffffffffffffffffffffffffffffffffffffffffffff000000000000000000909316989096169790971717949094169290921790935560cf805492830181559093527facb8d954e2cfef495862221e91bd7523613cf8808827cb33edfe4904cc51bf290180547fffffffffffffffffffffffff0000000000000000000000000000000000000000168217905590517f53087ff85d80a7671594bd2e86b92af22e0b3c2c441c8033bba7399b7b5cbe2390611c49908890889088908890938452602084019290925267ffffffffffffffff1660408301521515606082015260800190565b60405180910390a2505050505050565b600060d381611c6a610e10426143e2565b815260200190815260200160002054905090565b73ffffffffffffffffffffffffffffffffffffffff81166000908152609960205260408120546109a9565b611cb333826131b6565b50565b60606037805461079f9061430a565b60cd5473ffffffffffffffffffffffffffffffffffffffff163314611d16576040517fb90cdbb100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff8116600081815260cc602052604080822080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00166001179055517f98c15241d6c02bc5ee0b780e11b3ea737a2defd9d04877edbe9f9497065bd02f9190a250565b60cd546040517f521d4de900000000000000000000000000000000000000000000000000000000815233600482015273ffffffffffffffffffffffffffffffffffffffff9091169063521d4de990602401602060405180830381865afa158015611dfb573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611e1f9190614357565b611e55576040517f99e120bc00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff8216600090815260ce602052604090206002015468010000000000000000900460ff16611ec3576040517fc1ab6dc100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b633b9aca008167ffffffffffffffff161115611f0b576040517feca1d2c600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff8216600081815260ce602090815260409182902060020180547fffffffffffffffffffffffffffffffffffffffffffffffff00000000000000001667ffffffffffffffff861690811790915591519182527f901f9de19b475adc8da4110434b8df940dce085afd05e2281c86807f3a899d299101610989565b33600081815260346020908152604080832073ffffffffffffffffffffffffffffffffffffffff8716845290915281205490919083811015612062576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602560248201527f45524332303a2064656372656173656420616c6c6f77616e63652062656c6f7760448201527f207a65726f00000000000000000000000000000000000000000000000000000060648201526084015b60405180910390fd5b610dd78286868403612a35565b6000336109a3818585612f03565b60cf818154811061208d57600080fd5b60009182526020909120015473ffffffffffffffffffffffffffffffffffffffff16905081565b606060cf80548060200260200160405190810160405280929190818152602001828054801561081857602002820191906000526020600020905b815473ffffffffffffffffffffffffffffffffffffffff1681526001909101906020018083116120ee575050505050905090565b73ffffffffffffffffffffffffffffffffffffffff8316600090815260ce60209081526040808320815160a081018352815481526001820154938101939093526002015467ffffffffffffffff81169183019190915260ff6801000000000000000082048116158015606085015269010000000000000000009092041615156080830152806121b2575080608001515b156121e9576040517fc1ab6dc100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60006121f7610e10426143e2565b600081815260d36020526040812054919250906122159087906143cf565b905060d254811115612253576040517f6d43d1ac00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600082815260d36020526040902081905561226e33876131b6565b33600090815260d160205260408120548791036122bb57633b9aca00846040015167ffffffffffffffff16826122a4919061441d565b6122ae91906143e2565b6122b890826143a3565b90505b6122dc73ffffffffffffffffffffffffffffffffffffffff89168783612be0565b979650505050505050565b83421115612351576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f45524332305065726d69743a206578706972656420646561646c696e650000006044820152606401612059565b60007f6e71edae12b1b97f4d1f60370fef10105fa2faae0126114a169c64845d6126c98888886123808c61341e565b60408051602081019690965273ffffffffffffffffffffffffffffffffffffffff94851690860152929091166060840152608083015260a082015260c0810186905260e00160405160208183030381529060405280519060200120905060006123e882613453565b905060006123f8828787876134bc565b90508973ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff161461248f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601e60248201527f45524332305065726d69743a20696e76616c6964207369676e617475726500006044820152606401612059565b61249a8a8a8a612a35565b50505050505050505050565b60cd546040517f521d4de900000000000000000000000000000000000000000000000000000000815233600482015273ffffffffffffffffffffffffffffffffffffffff9091169063521d4de990602401602060405180830381865afa158015612514573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906125389190614357565b61256e576040517f99e120bc00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff8116600090815260ce602052604090206002015468010000000000000000900460ff166125dc576040517fc1ab6dc100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff8116600081815260ce602090815260409182902060020180547fffffffffffffffffffffffffffffffffffffffffffff00ffffffffffffffffff811669010000000000000000009182900460ff16801592830291909117909255925192835292917ff7c93079dcbf699749d66345a351afab7d24219bb1d915c9f4fc4cf03f00d3979101610989565b60cd5473ffffffffffffffffffffffffffffffffffffffff1633146126cb576040517fb90cdbb100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60cd80547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83169081179091556040517f7dae230f18360d76a040c81f050aa14eb9d6dc7901b20fc5d855e2a20fe814d190600090a250565b73ffffffffffffffffffffffffffffffffffffffff163b151590565b600054610100900460ff16158080156127765750600054600160ff909116105b806127905750303b158015612790575060005460ff166001145b61281c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201527f647920696e697469616c697a65640000000000000000000000000000000000006064820152608401612059565b600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00166001179055801561287a57600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff166101001790555b3073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1663e9cbd8226040518163ffffffff1660e01b8152600401602060405180830381865afa1580156128dc573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061290091906144ca565b73ffffffffffffffffffffffffffffffffffffffff161461294d576040517f14bcf5c800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b612956846134e4565b61296084846135ba565b60cd80547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff84169081179091556040517f7dae230f18360d76a040c81f050aa14eb9d6dc7901b20fc5d855e2a20fe814d190600090a28015612a2f57600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15b50505050565b73ffffffffffffffffffffffffffffffffffffffff8316612ad7576040517f08c379a0000000000000000000000000000000000000000000000000000000008152602060048201526024808201527f45524332303a20617070726f76652066726f6d20746865207a65726f2061646460448201527f72657373000000000000000000000000000000000000000000000000000000006064820152608401612059565b73ffffffffffffffffffffffffffffffffffffffff8216612b7a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602260248201527f45524332303a20617070726f766520746f20746865207a65726f20616464726560448201527f73730000000000000000000000000000000000000000000000000000000000006064820152608401612059565b73ffffffffffffffffffffffffffffffffffffffff83811660008181526034602090815260408083209487168084529482529182902085905590518481527f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b9259101610af7565b60405173ffffffffffffffffffffffffffffffffffffffff831660248201526044810182905261082d9084907fa9059cbb00000000000000000000000000000000000000000000000000000000906064015b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff000000000000000000000000000000000000000000000000000000009093169290921790915261365b565b60405173ffffffffffffffffffffffffffffffffffffffff80851660248301528316604482015260648101829052612a2f9085907f23b872dd0000000000000000000000000000000000000000000000000000000090608401612c32565b73ffffffffffffffffffffffffffffffffffffffff8216612d8f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601f60248201527f45524332303a206d696e7420746f20746865207a65726f2061646472657373006044820152606401612059565b8060356000828254612da191906143cf565b909155505073ffffffffffffffffffffffffffffffffffffffff821660009081526033602052604081208054839290612ddb9084906143cf565b909155505060405181815273ffffffffffffffffffffffffffffffffffffffff8316906000907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef9060200160405180910390a35050565b73ffffffffffffffffffffffffffffffffffffffff8381166000908152603460209081526040808320938616835292905220547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8114612a2f5781811015612ef6576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f45524332303a20696e73756666696369656e7420616c6c6f77616e63650000006044820152606401612059565b612a2f8484848403612a35565b73ffffffffffffffffffffffffffffffffffffffff8316612fa6576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602560248201527f45524332303a207472616e736665722066726f6d20746865207a65726f20616460448201527f64726573730000000000000000000000000000000000000000000000000000006064820152608401612059565b73ffffffffffffffffffffffffffffffffffffffff8216613049576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602360248201527f45524332303a207472616e7366657220746f20746865207a65726f206164647260448201527f65737300000000000000000000000000000000000000000000000000000000006064820152608401612059565b73ffffffffffffffffffffffffffffffffffffffff8316600090815260336020526040902054818110156130ff576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f45524332303a207472616e7366657220616d6f756e742065786365656473206260448201527f616c616e636500000000000000000000000000000000000000000000000000006064820152608401612059565b73ffffffffffffffffffffffffffffffffffffffff8085166000908152603360205260408082208585039055918516815290812080548492906131439084906143cf565b925050819055508273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef846040516131a991815260200190565b60405180910390a3612a2f565b73ffffffffffffffffffffffffffffffffffffffff8216613259576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602160248201527f45524332303a206275726e2066726f6d20746865207a65726f2061646472657360448201527f73000000000000000000000000000000000000000000000000000000000000006064820152608401612059565b73ffffffffffffffffffffffffffffffffffffffff82166000908152603360205260409020548181101561330f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602260248201527f45524332303a206275726e20616d6f756e7420657863656564732062616c616e60448201527f63650000000000000000000000000000000000000000000000000000000000006064820152608401612059565b73ffffffffffffffffffffffffffffffffffffffff8316600090815260336020526040812083830390556035805484929061334b9084906143a3565b909155505060405182815260009073ffffffffffffffffffffffffffffffffffffffff8516907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef9060200160405180910390a3505050565b60006113e47f8b73c3c69bb8fe3d512ecc4cf759cc79239f7b179b0ffacaa9a75d522b39400f6133d260655490565b6066546040805160208101859052908101839052606081018290524660808201523060a082015260009060c0016040516020818303038152906040528051906020012090509392505050565b73ffffffffffffffffffffffffffffffffffffffff811660009081526099602052604090208054600181018255905b50919050565b60006109a96134606133a3565b836040517f19010000000000000000000000000000000000000000000000000000000000006020820152602281018390526042810182905260009060620160405160208183030381529060405280519060200120905092915050565b60008060006134cd87878787613767565b915091506134da8161387f565b5095945050505050565b600054610100900460ff1661357b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201527f6e697469616c697a696e670000000000000000000000000000000000000000006064820152608401612059565b611cb3816040518060400160405280600181526020017f3100000000000000000000000000000000000000000000000000000000000000815250613ad3565b600054610100900460ff16613651576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201527f6e697469616c697a696e670000000000000000000000000000000000000000006064820152608401612059565b610e358282613b84565b60006136bd826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c65648152508573ffffffffffffffffffffffffffffffffffffffff16613c349092919063ffffffff16565b80519091501561082d57808060200190518101906136db9190614357565b61082d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e60448201527f6f742073756363656564000000000000000000000000000000000000000000006064820152608401612059565b6000807f7fffffffffffffffffffffffffffffff5d576e7357a4501ddfe92f46681b20a083111561379e5750600090506003613876565b8460ff16601b141580156137b657508460ff16601c14155b156137c75750600090506004613876565b6040805160008082526020820180845289905260ff881692820192909252606081018690526080810185905260019060a0016020604051602081039080840390855afa15801561381b573d6000803e3d6000fd5b50506040517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0015191505073ffffffffffffffffffffffffffffffffffffffff811661386f57600060019250925050613876565b9150600090505b94509492505050565b6000816004811115613893576138936144e7565b0361389b5750565b60018160048111156138af576138af6144e7565b03613916576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601860248201527f45434453413a20696e76616c6964207369676e617475726500000000000000006044820152606401612059565b600281600481111561392a5761392a6144e7565b03613991576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601f60248201527f45434453413a20696e76616c6964207369676e6174757265206c656e677468006044820152606401612059565b60038160048111156139a5576139a56144e7565b03613a32576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602260248201527f45434453413a20696e76616c6964207369676e6174757265202773272076616c60448201527f75650000000000000000000000000000000000000000000000000000000000006064820152608401612059565b6004816004811115613a4657613a466144e7565b03611cb3576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602260248201527f45434453413a20696e76616c6964207369676e6174757265202776272076616c60448201527f75650000000000000000000000000000000000000000000000000000000000006064820152608401612059565b600054610100900460ff16613b6a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201527f6e697469616c697a696e670000000000000000000000000000000000000000006064820152608401612059565b815160209283012081519190920120606591909155606655565b600054610100900460ff16613c1b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201527f6e697469616c697a696e670000000000000000000000000000000000000000006064820152608401612059565b6036613c278382614564565b50603761082d8282614564565b6060613c438484600085613c4b565b949350505050565b606082471015613cdd576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f60448201527f722063616c6c00000000000000000000000000000000000000000000000000006064820152608401612059565b73ffffffffffffffffffffffffffffffffffffffff85163b613d5b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006044820152606401612059565b6000808673ffffffffffffffffffffffffffffffffffffffff168587604051613d84919061467e565b60006040518083038185875af1925050503d8060008114613dc1576040519150601f19603f3d011682016040523d82523d6000602084013e613dc6565b606091505b50915091506122dc82828660608315613de0575081610db7565b825115613df05782518084602001fd5b816040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016120599190613e48565b60005b83811015613e3f578181015183820152602001613e27565b50506000910152565b6020815260008251806020840152613e67816040850160208701613e24565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169190910160400192915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b600082601f830112613ed957600080fd5b813567ffffffffffffffff80821115613ef457613ef4613e99565b604051601f83017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0908116603f01168101908282118183101715613f3a57613f3a613e99565b81604052838152866020858801011115613f5357600080fd5b836020870160208301376000602085830101528094505050505092915050565b73ffffffffffffffffffffffffffffffffffffffff81168114611cb357600080fd5b600080600060608486031215613faa57600080fd5b833567ffffffffffffffff80821115613fc257600080fd5b613fce87838801613ec8565b94506020860135915080821115613fe457600080fd5b50613ff186828701613ec8565b925050604084013561400281613f73565b809150509250925092565b60006020828403121561401f57600080fd5b8135610db781613f73565b6000806040838503121561403d57600080fd5b823561404881613f73565b946020939093013593505050565b60008060006060848603121561406b57600080fd5b833561407681613f73565b9250602084013561408681613f73565b929592945050506040919091013590565b6000806000606084860312156140ac57600080fd5b83356140b781613f73565b925060208401359150604084013561400281613f73565b600080604083850312156140e157600080fd5b8235915060208301356140f381613f73565b809150509250929050565b60008060006060848603121561411357600080fd5b83359250602084013561412581613f73565b9150604084013561400281613f73565b60006020828403121561414757600080fd5b5035919050565b803567ffffffffffffffff8116811461416657600080fd5b919050565b8015158114611cb357600080fd5b600080600080600060a0868803121561419157600080fd5b853561419c81613f73565b945060208601359350604086013592506141b86060870161414e565b915060808601356141c88161416b565b809150509295509295909350565b600080604083850312156141e957600080fd5b82356141f481613f73565b91506142026020840161414e565b90509250929050565b6020808252825182820181905260009190848201906040850190845b8181101561425957835173ffffffffffffffffffffffffffffffffffffffff1683529284019291840191600101614227565b50909695505050505050565b600080600080600080600060e0888a03121561428057600080fd5b873561428b81613f73565b9650602088013561429b81613f73565b95506040880135945060608801359350608088013560ff811681146142bf57600080fd5b9699959850939692959460a0840135945060c09093013592915050565b600080604083850312156142ef57600080fd5b82356142fa81613f73565b915060208301356140f381613f73565b600181811c9082168061431e57607f821691505b60208210810361344d577f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b60006020828403121561436957600080fd5b8151610db78161416b565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b818103818111156109a9576109a9614374565b6000602082840312156143c857600080fd5b5051919050565b808201808211156109a9576109a9614374565b600082614418577f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b500490565b80820281158282048414176109a9576109a9614374565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff820361449457614494614374565b5060010190565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603160045260246000fd5b6000602082840312156144dc57600080fd5b8151610db781613f73565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b601f82111561082d57600081815260208120601f850160051c8101602086101561453d5750805b601f850160051c820191505b8181101561455c57828155600101614549565b505050505050565b815167ffffffffffffffff81111561457e5761457e613e99565b6145928161458c845461430a565b84614516565b602080601f8311600181146145e557600084156145af5750858301515b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600386901b1c1916600185901b17855561455c565b6000858152602081207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08616915b8281101561463257888601518255948401946001909101908401614613565b508582101561466e57878501517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600388901b60f8161c191681555b5050505050600190811b01905550565b60008251614690818460208701613e24565b919091019291505056fea2646970667358221220f2eb02bac1667a72be85ab617a5b5aa3d8f7a9b09b4d1fde9756b7a5636daf2164736f6c63430008110033", "devdoc": { - "author": "Angle Core Team", - "details": "This contract supports bridge tokens having a minting right on the stablecoin (also referred to as the canonical or the native token)References: - FRAX implementation: https://polygonscan.com/address/0x45c32fA6DF82ead1e2EF74d17b76547EDdFaFF89#code - QiDAO implementation: https://snowtrace.io/address/0x5c49b268c9841AFF1Cc3B0a418ff5c3442eE3F3b#code", + "author": "Angle Labs, Inc.", + "details": "This contract supports bridge tokens having a minting right on the stablecoin (also referred to as the canonical or the native token)", "kind": "dev", "methods": { "DOMAIN_SEPARATOR()": { @@ -1250,7 +1276,7 @@ "details": "See {IERC20-allowance}." }, "approve(address,uint256)": { - "details": "See {IERC20-approve}. Requirements: - `spender` cannot be the zero address." + "details": "See {IERC20-approve}. NOTE: If `amount` is the maximum `uint256`, the allowance is not updated on `transferFrom`. This is semantically equivalent to an infinite approval. Requirements: - `spender` cannot be the zero address." }, "balanceOf(address)": { "details": "See {IERC20-balanceOf}." @@ -1294,14 +1320,6 @@ "increaseAllowance(address,uint256)": { "details": "Atomically increases the allowance granted to `spender` by the caller. This is an alternative to {approve} that can be used as a mitigation for problems described in {IERC20-approve}. Emits an {Approval} event indicating the updated allowance. Requirements: - `spender` cannot be the zero address." }, - "initialize(string,string,address)": { - "details": "By default, agTokens are ERC-20 tokens with 18 decimals", - "params": { - "_treasury": "Reference to the `Treasury` contract associated to this agToken", - "name_": "Name of the token", - "symbol_": "Symbol of the token" - } - }, "mint(address,uint256)": { "details": "The contracts allowed to issue agTokens are the `StableMaster` contract, `VaultManager` contracts associated to this stablecoin as well as the flash loan module (if activated) and potentially contracts whitelisted by governance", "params": { @@ -1366,10 +1384,10 @@ "details": "See {IERC20-totalSupply}." }, "transfer(address,uint256)": { - "details": "See {IERC20-transfer}. Requirements: - `recipient` cannot be the zero address. - the caller must have a balance of at least `amount`." + "details": "See {IERC20-transfer}. Requirements: - `to` cannot be the zero address. - the caller must have a balance of at least `amount`." }, "transferFrom(address,address,uint256)": { - "details": "See {IERC20-transferFrom}. Emits an {Approval} event indicating the updated allowance. This is not required by the EIP. See the note at the beginning of {ERC20}. Requirements: - `sender` and `recipient` cannot be the zero address. - `sender` must have a balance of at least `amount`. - the caller must have allowance for ``sender``'s tokens of at least `amount`." + "details": "See {IERC20-transferFrom}. Emits an {Approval} event indicating the updated allowance. This is not required by the EIP. See the note at the beginning of {ERC20}. NOTE: Does not update the allowance if the current allowance is the maximum `uint256`. Requirements: - `from` and `to` cannot be the zero address. - `from` must have a balance of at least `amount`. - the caller must have allowance for ``from``'s tokens of at least `amount`." } }, "title": "AgTokenSideChainMultiBridge", @@ -1403,7 +1421,7 @@ "notice": "Burns `amount` tokens from a `burner` address" }, "burnStablecoin(uint256)": { - "notice": "Allows anyone to burn agToken without redeeming collateral back" + "notice": "Allows anyone to burn stablecoins" }, "chainTotalHourlyLimit()": { "notice": "Limit to the amount of tokens that can be sent from that chain to another chain" @@ -1478,15 +1496,15 @@ "storageLayout": { "storage": [ { - "astId": 772, + "astId": 770, "contract": "contracts/agToken/AgTokenSideChainMultiBridge.sol:AgTokenSideChainMultiBridge", "label": "_initialized", "offset": 0, "slot": "0", - "type": "t_bool" + "type": "t_uint8" }, { - "astId": 775, + "astId": 773, "contract": "contracts/agToken/AgTokenSideChainMultiBridge.sol:AgTokenSideChainMultiBridge", "label": "_initializing", "offset": 1, @@ -1494,7 +1512,7 @@ "type": "t_bool" }, { - "astId": 2592, + "astId": 2486, "contract": "contracts/agToken/AgTokenSideChainMultiBridge.sol:AgTokenSideChainMultiBridge", "label": "__gap", "offset": 0, @@ -1502,7 +1520,7 @@ "type": "t_array(t_uint256)50_storage" }, { - "astId": 1029, + "astId": 1119, "contract": "contracts/agToken/AgTokenSideChainMultiBridge.sol:AgTokenSideChainMultiBridge", "label": "_balances", "offset": 0, @@ -1510,7 +1528,7 @@ "type": "t_mapping(t_address,t_uint256)" }, { - "astId": 1035, + "astId": 1125, "contract": "contracts/agToken/AgTokenSideChainMultiBridge.sol:AgTokenSideChainMultiBridge", "label": "_allowances", "offset": 0, @@ -1518,7 +1536,7 @@ "type": "t_mapping(t_address,t_mapping(t_address,t_uint256))" }, { - "astId": 1037, + "astId": 1127, "contract": "contracts/agToken/AgTokenSideChainMultiBridge.sol:AgTokenSideChainMultiBridge", "label": "_totalSupply", "offset": 0, @@ -1526,7 +1544,7 @@ "type": "t_uint256" }, { - "astId": 1039, + "astId": 1129, "contract": "contracts/agToken/AgTokenSideChainMultiBridge.sol:AgTokenSideChainMultiBridge", "label": "_name", "offset": 0, @@ -1534,7 +1552,7 @@ "type": "t_string_storage" }, { - "astId": 1041, + "astId": 1131, "contract": "contracts/agToken/AgTokenSideChainMultiBridge.sol:AgTokenSideChainMultiBridge", "label": "_symbol", "offset": 0, @@ -1542,7 +1560,7 @@ "type": "t_string_storage" }, { - "astId": 1582, + "astId": 1710, "contract": "contracts/agToken/AgTokenSideChainMultiBridge.sol:AgTokenSideChainMultiBridge", "label": "__gap", "offset": 0, @@ -1550,7 +1568,7 @@ "type": "t_array(t_uint256)45_storage" }, { - "astId": 3269, + "astId": 3203, "contract": "contracts/agToken/AgTokenSideChainMultiBridge.sol:AgTokenSideChainMultiBridge", "label": "_HASHED_NAME", "offset": 0, @@ -1558,7 +1576,7 @@ "type": "t_bytes32" }, { - "astId": 3271, + "astId": 3205, "contract": "contracts/agToken/AgTokenSideChainMultiBridge.sol:AgTokenSideChainMultiBridge", "label": "_HASHED_VERSION", "offset": 0, @@ -1566,7 +1584,7 @@ "type": "t_bytes32" }, { - "astId": 3408, + "astId": 3343, "contract": "contracts/agToken/AgTokenSideChainMultiBridge.sol:AgTokenSideChainMultiBridge", "label": "__gap", "offset": 0, @@ -1574,23 +1592,23 @@ "type": "t_array(t_uint256)50_storage" }, { - "astId": 1712, + "astId": 1840, "contract": "contracts/agToken/AgTokenSideChainMultiBridge.sol:AgTokenSideChainMultiBridge", "label": "_nonces", "offset": 0, "slot": "153", - "type": "t_mapping(t_address,t_struct(Counter)2599_storage)" + "type": "t_mapping(t_address,t_struct(Counter)2493_storage)" }, { - "astId": 1714, + "astId": 1848, "contract": "contracts/agToken/AgTokenSideChainMultiBridge.sol:AgTokenSideChainMultiBridge", - "label": "_PERMIT_TYPEHASH", + "label": "_PERMIT_TYPEHASH_DEPRECATED_SLOT", "offset": 0, "slot": "154", "type": "t_bytes32" }, { - "astId": 1882, + "astId": 2004, "contract": "contracts/agToken/AgTokenSideChainMultiBridge.sol:AgTokenSideChainMultiBridge", "label": "__gap", "offset": 0, @@ -1598,7 +1616,7 @@ "type": "t_array(t_uint256)49_storage" }, { - "astId": 8835, + "astId": 7427, "contract": "contracts/agToken/AgTokenSideChainMultiBridge.sol:AgTokenSideChainMultiBridge", "label": "isMinter", "offset": 0, @@ -1606,7 +1624,7 @@ "type": "t_mapping(t_address,t_bool)" }, { - "astId": 8838, + "astId": 7430, "contract": "contracts/agToken/AgTokenSideChainMultiBridge.sol:AgTokenSideChainMultiBridge", "label": "treasury", "offset": 0, @@ -1614,15 +1632,15 @@ "type": "t_address" }, { - "astId": 7979, + "astId": 7739, "contract": "contracts/agToken/AgTokenSideChainMultiBridge.sol:AgTokenSideChainMultiBridge", "label": "bridges", "offset": 0, "slot": "206", - "type": "t_mapping(t_address,t_struct(BridgeDetails)7973_storage)" + "type": "t_mapping(t_address,t_struct(BridgeDetails)7733_storage)" }, { - "astId": 7983, + "astId": 7743, "contract": "contracts/agToken/AgTokenSideChainMultiBridge.sol:AgTokenSideChainMultiBridge", "label": "bridgeTokensList", "offset": 0, @@ -1630,7 +1648,7 @@ "type": "t_array(t_address)dyn_storage" }, { - "astId": 7990, + "astId": 7750, "contract": "contracts/agToken/AgTokenSideChainMultiBridge.sol:AgTokenSideChainMultiBridge", "label": "usage", "offset": 0, @@ -1638,7 +1656,7 @@ "type": "t_mapping(t_address,t_mapping(t_uint256,t_uint256))" }, { - "astId": 7995, + "astId": 7755, "contract": "contracts/agToken/AgTokenSideChainMultiBridge.sol:AgTokenSideChainMultiBridge", "label": "isFeeExempt", "offset": 0, @@ -1646,7 +1664,7 @@ "type": "t_mapping(t_address,t_uint256)" }, { - "astId": 7998, + "astId": 7758, "contract": "contracts/agToken/AgTokenSideChainMultiBridge.sol:AgTokenSideChainMultiBridge", "label": "chainTotalHourlyLimit", "offset": 0, @@ -1654,7 +1672,7 @@ "type": "t_uint256" }, { - "astId": 8003, + "astId": 7763, "contract": "contracts/agToken/AgTokenSideChainMultiBridge.sol:AgTokenSideChainMultiBridge", "label": "chainTotalUsage", "offset": 0, @@ -1723,19 +1741,19 @@ "numberOfBytes": "32", "value": "t_mapping(t_uint256,t_uint256)" }, - "t_mapping(t_address,t_struct(BridgeDetails)7973_storage)": { + "t_mapping(t_address,t_struct(BridgeDetails)7733_storage)": { "encoding": "mapping", "key": "t_address", "label": "mapping(address => struct AgTokenSideChainMultiBridge.BridgeDetails)", "numberOfBytes": "32", - "value": "t_struct(BridgeDetails)7973_storage" + "value": "t_struct(BridgeDetails)7733_storage" }, - "t_mapping(t_address,t_struct(Counter)2599_storage)": { + "t_mapping(t_address,t_struct(Counter)2493_storage)": { "encoding": "mapping", "key": "t_address", "label": "mapping(address => struct CountersUpgradeable.Counter)", "numberOfBytes": "32", - "value": "t_struct(Counter)2599_storage" + "value": "t_struct(Counter)2493_storage" }, "t_mapping(t_address,t_uint256)": { "encoding": "mapping", @@ -1756,12 +1774,12 @@ "label": "string", "numberOfBytes": "32" }, - "t_struct(BridgeDetails)7973_storage": { + "t_struct(BridgeDetails)7733_storage": { "encoding": "inplace", "label": "struct AgTokenSideChainMultiBridge.BridgeDetails", "members": [ { - "astId": 7964, + "astId": 7724, "contract": "contracts/agToken/AgTokenSideChainMultiBridge.sol:AgTokenSideChainMultiBridge", "label": "limit", "offset": 0, @@ -1769,7 +1787,7 @@ "type": "t_uint256" }, { - "astId": 7966, + "astId": 7726, "contract": "contracts/agToken/AgTokenSideChainMultiBridge.sol:AgTokenSideChainMultiBridge", "label": "hourlyLimit", "offset": 0, @@ -1777,7 +1795,7 @@ "type": "t_uint256" }, { - "astId": 7968, + "astId": 7728, "contract": "contracts/agToken/AgTokenSideChainMultiBridge.sol:AgTokenSideChainMultiBridge", "label": "fee", "offset": 0, @@ -1785,7 +1803,7 @@ "type": "t_uint64" }, { - "astId": 7970, + "astId": 7730, "contract": "contracts/agToken/AgTokenSideChainMultiBridge.sol:AgTokenSideChainMultiBridge", "label": "allowed", "offset": 8, @@ -1793,7 +1811,7 @@ "type": "t_bool" }, { - "astId": 7972, + "astId": 7732, "contract": "contracts/agToken/AgTokenSideChainMultiBridge.sol:AgTokenSideChainMultiBridge", "label": "paused", "offset": 9, @@ -1803,12 +1821,12 @@ ], "numberOfBytes": "96" }, - "t_struct(Counter)2599_storage": { + "t_struct(Counter)2493_storage": { "encoding": "inplace", "label": "struct CountersUpgradeable.Counter", "members": [ { - "astId": 2598, + "astId": 2492, "contract": "contracts/agToken/AgTokenSideChainMultiBridge.sol:AgTokenSideChainMultiBridge", "label": "_value", "offset": 0, @@ -1827,6 +1845,11 @@ "encoding": "inplace", "label": "uint64", "numberOfBytes": "8" + }, + "t_uint8": { + "encoding": "inplace", + "label": "uint8", + "numberOfBytes": "1" } } } diff --git a/deployments/bsc/CoreBorrowTest.json b/deployments/bsc/CoreBorrowTest.json new file mode 100644 index 00000000..179445a6 --- /dev/null +++ b/deployments/bsc/CoreBorrowTest.json @@ -0,0 +1,325 @@ +{ + "address": "0xC1F9266c6d3389e981639Ee873121199a7ACdb8F", + "abi": [ + { + "inputs": [ + { + "internalType": "address", + "name": "_logic", + "type": "address" + }, + { + "internalType": "address", + "name": "admin_", + "type": "address" + }, + { + "internalType": "bytes", + "name": "_data", + "type": "bytes" + } + ], + "stateMutability": "payable", + "type": "constructor" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "previousAdmin", + "type": "address" + }, + { + "indexed": false, + "internalType": "address", + "name": "newAdmin", + "type": "address" + } + ], + "name": "AdminChanged", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "beacon", + "type": "address" + } + ], + "name": "BeaconUpgraded", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "implementation", + "type": "address" + } + ], + "name": "Upgraded", + "type": "event" + }, + { + "stateMutability": "payable", + "type": "fallback" + }, + { + "inputs": [], + "name": "admin", + "outputs": [ + { + "internalType": "address", + "name": "admin_", + "type": "address" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "newAdmin", + "type": "address" + } + ], + "name": "changeAdmin", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "implementation", + "outputs": [ + { + "internalType": "address", + "name": "implementation_", + "type": "address" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "newImplementation", + "type": "address" + } + ], + "name": "upgradeTo", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "newImplementation", + "type": "address" + }, + { + "internalType": "bytes", + "name": "data", + "type": "bytes" + } + ], + "name": "upgradeToAndCall", + "outputs": [], + "stateMutability": "payable", + "type": "function" + }, + { + "stateMutability": "payable", + "type": "receive" + } + ], + "transactionHash": "0xe8d815354b6d727fe2231457e137b7d38e3659f9f41c047704ae73479bb77890", + "receipt": { + "to": null, + "from": "0xfdA462548Ce04282f4B6D6619823a7C64Fdc0185", + "contractAddress": "0xC1F9266c6d3389e981639Ee873121199a7ACdb8F", + "transactionIndex": 72, + "gasUsed": "1037362", + "logsBloom": "0x00200004000000000800000400000000480000000000000000000000200000000000002000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000020000400000000000000800000000800000000000000020000000000000000000000000000000000000000000200003000000000000000000804000000000000000000000010000000000000000000000000000001000100000001000000020020000000000008000000000000800000408000100000000000020000000800000000000008010000000000400000000000000000000000000040000", + "blockHash": "0x285ac609884d693300a882fe7139b053b5dba85b0a787cdd08f0db979cc51049", + "transactionHash": "0xe8d815354b6d727fe2231457e137b7d38e3659f9f41c047704ae73479bb77890", + "logs": [ + { + "transactionIndex": 72, + "blockNumber": 35121543, + "transactionHash": "0xe8d815354b6d727fe2231457e137b7d38e3659f9f41c047704ae73479bb77890", + "address": "0xC1F9266c6d3389e981639Ee873121199a7ACdb8F", + "topics": [ + "0xbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b", + "0x0000000000000000000000005183f032bf42109cd370b9559fd22207e432301e" + ], + "data": "0x", + "logIndex": 137, + "blockHash": "0x285ac609884d693300a882fe7139b053b5dba85b0a787cdd08f0db979cc51049" + }, + { + "transactionIndex": 72, + "blockNumber": 35121543, + "transactionHash": "0xe8d815354b6d727fe2231457e137b7d38e3659f9f41c047704ae73479bb77890", + "address": "0xC1F9266c6d3389e981639Ee873121199a7ACdb8F", + "topics": [ + "0x2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d", + "0x7935bd0ae54bc31f548c14dba4d37c5c64b3f8ca900cb468fb8abd54d5894f55", + "0x000000000000000000000000fda462548ce04282f4b6d6619823a7c64fdc0185", + "0x000000000000000000000000fda462548ce04282f4b6d6619823a7c64fdc0185" + ], + "data": "0x", + "logIndex": 138, + "blockHash": "0x285ac609884d693300a882fe7139b053b5dba85b0a787cdd08f0db979cc51049" + }, + { + "transactionIndex": 72, + "blockNumber": 35121543, + "transactionHash": "0xe8d815354b6d727fe2231457e137b7d38e3659f9f41c047704ae73479bb77890", + "address": "0xC1F9266c6d3389e981639Ee873121199a7ACdb8F", + "topics": [ + "0x2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d", + "0x55435dd261a4b9b3364963f7738a7a662ad9c84396d64be3365284bb7f0a5041", + "0x000000000000000000000000371ac6db8063e6076890ef032a4a3cfcf226f548", + "0x000000000000000000000000fda462548ce04282f4b6d6619823a7c64fdc0185" + ], + "data": "0x", + "logIndex": 139, + "blockHash": "0x285ac609884d693300a882fe7139b053b5dba85b0a787cdd08f0db979cc51049" + }, + { + "transactionIndex": 72, + "blockNumber": 35121543, + "transactionHash": "0xe8d815354b6d727fe2231457e137b7d38e3659f9f41c047704ae73479bb77890", + "address": "0xC1F9266c6d3389e981639Ee873121199a7ACdb8F", + "topics": [ + "0x2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d", + "0x55435dd261a4b9b3364963f7738a7a662ad9c84396d64be3365284bb7f0a5041", + "0x000000000000000000000000fda462548ce04282f4b6d6619823a7c64fdc0185", + "0x000000000000000000000000fda462548ce04282f4b6d6619823a7c64fdc0185" + ], + "data": "0x", + "logIndex": 140, + "blockHash": "0x285ac609884d693300a882fe7139b053b5dba85b0a787cdd08f0db979cc51049" + }, + { + "transactionIndex": 72, + "blockNumber": 35121543, + "transactionHash": "0xe8d815354b6d727fe2231457e137b7d38e3659f9f41c047704ae73479bb77890", + "address": "0xC1F9266c6d3389e981639Ee873121199a7ACdb8F", + "topics": [ + "0xbd79b86ffe0ab8e8776151514217cd7cacd52c909f66475c3af44e129f0b00ff", + "0x55435dd261a4b9b3364963f7738a7a662ad9c84396d64be3365284bb7f0a5041", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x7935bd0ae54bc31f548c14dba4d37c5c64b3f8ca900cb468fb8abd54d5894f55" + ], + "data": "0x", + "logIndex": 141, + "blockHash": "0x285ac609884d693300a882fe7139b053b5dba85b0a787cdd08f0db979cc51049" + }, + { + "transactionIndex": 72, + "blockNumber": 35121543, + "transactionHash": "0xe8d815354b6d727fe2231457e137b7d38e3659f9f41c047704ae73479bb77890", + "address": "0xC1F9266c6d3389e981639Ee873121199a7ACdb8F", + "topics": [ + "0xbd79b86ffe0ab8e8776151514217cd7cacd52c909f66475c3af44e129f0b00ff", + "0x7935bd0ae54bc31f548c14dba4d37c5c64b3f8ca900cb468fb8abd54d5894f55", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x7935bd0ae54bc31f548c14dba4d37c5c64b3f8ca900cb468fb8abd54d5894f55" + ], + "data": "0x", + "logIndex": 142, + "blockHash": "0x285ac609884d693300a882fe7139b053b5dba85b0a787cdd08f0db979cc51049" + }, + { + "transactionIndex": 72, + "blockNumber": 35121543, + "transactionHash": "0xe8d815354b6d727fe2231457e137b7d38e3659f9f41c047704ae73479bb77890", + "address": "0xC1F9266c6d3389e981639Ee873121199a7ACdb8F", + "topics": [ + "0xbd79b86ffe0ab8e8776151514217cd7cacd52c909f66475c3af44e129f0b00ff", + "0x0ae0130c6b34f32239dfe5e419a3fbd7546b44e99783257f2d93526d5a936d46", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x7935bd0ae54bc31f548c14dba4d37c5c64b3f8ca900cb468fb8abd54d5894f55" + ], + "data": "0x", + "logIndex": 143, + "blockHash": "0x285ac609884d693300a882fe7139b053b5dba85b0a787cdd08f0db979cc51049" + }, + { + "transactionIndex": 72, + "blockNumber": 35121543, + "transactionHash": "0xe8d815354b6d727fe2231457e137b7d38e3659f9f41c047704ae73479bb77890", + "address": "0xC1F9266c6d3389e981639Ee873121199a7ACdb8F", + "topics": [ + "0x7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f" + ], + "data": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000009a5b060bd7b8f86c4c0d720a17367729670afb19", + "logIndex": 144, + "blockHash": "0x285ac609884d693300a882fe7139b053b5dba85b0a787cdd08f0db979cc51049" + } + ], + "blockNumber": 35121543, + "cumulativeGasUsed": "6895983", + "status": 1, + "byzantium": true + }, + "args": [ + "0x5183f032bf42109cD370B9559FD22207e432301E", + "0x9a5b060Bd7b8f86c4C0D720a17367729670AfB19", + "0x485cc955000000000000000000000000fda462548ce04282f4b6d6619823a7c64fdc0185000000000000000000000000371ac6db8063e6076890ef032a4a3cfcf226f548" + ], + "numDeployments": 1, + "solcInputHash": "871924e0c138825a2736b76def8fef8d", + "metadata": "{\"compiler\":{\"version\":\"0.8.17+commit.8df45f5f\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_logic\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"admin_\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"_data\",\"type\":\"bytes\"}],\"stateMutability\":\"payable\",\"type\":\"constructor\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"previousAdmin\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"newAdmin\",\"type\":\"address\"}],\"name\":\"AdminChanged\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"beacon\",\"type\":\"address\"}],\"name\":\"BeaconUpgraded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"implementation\",\"type\":\"address\"}],\"name\":\"Upgraded\",\"type\":\"event\"},{\"stateMutability\":\"payable\",\"type\":\"fallback\"},{\"inputs\":[],\"name\":\"admin\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"admin_\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newAdmin\",\"type\":\"address\"}],\"name\":\"changeAdmin\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"implementation\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"implementation_\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newImplementation\",\"type\":\"address\"}],\"name\":\"upgradeTo\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newImplementation\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"}],\"name\":\"upgradeToAndCall\",\"outputs\":[],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"stateMutability\":\"payable\",\"type\":\"receive\"}],\"devdoc\":{\"details\":\"This contract implements a proxy that is upgradeable by an admin. It is fully forked from OpenZeppelin `TransparentUpgradeableProxy` To avoid https://medium.com/nomic-labs-blog/malicious-backdoors-in-ethereum-proxies-62629adf3357[proxy selector clashing], which can potentially be used in an attack, this contract uses the https://blog.openzeppelin.com/the-transparent-proxy-pattern/[transparent proxy pattern]. This pattern implies two things that go hand in hand: 1. If any account other than the admin calls the proxy, the call will be forwarded to the implementation, even if that call matches one of the admin functions exposed by the proxy itself. 2. If the admin calls the proxy, it can access the admin functions, but its calls will never be forwarded to the implementation. If the admin tries to call a function on the implementation it will fail with an error that says \\\"admin cannot fallback to proxy target\\\". These properties mean that the admin account can only be used for admin actions like upgrading the proxy or changing the admin, so it's best if it's a dedicated account that is not used for anything else. This will avoid headaches due to sudden errors when trying to call a function from the proxy implementation. Our recommendation is for the dedicated account to be an instance of the {ProxyAdmin} contract. If set up this way, you should think of the `ProxyAdmin` instance as the real administrative interface of your proxy.\",\"kind\":\"dev\",\"methods\":{\"admin()\":{\"details\":\"Returns the current admin. NOTE: Only the admin can call this function. See {ProxyAdmin-getProxyAdmin}. TIP: To get this value clients can read directly from the storage slot shown below (specified by EIP1967) using the https://eth.wiki/json-rpc/API#eth_getstorageat[`eth_getStorageAt`] RPC call. `0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103`\"},\"changeAdmin(address)\":{\"details\":\"Changes the admin of the proxy. Emits an {AdminChanged} event. NOTE: Only the admin can call this function. See {ProxyAdmin-changeProxyAdmin}.\"},\"constructor\":{\"details\":\"Initializes an upgradeable proxy managed by `_admin`, backed by the implementation at `_logic`, and optionally initialized with `_data` as explained in {ERC1967Proxy-constructor}.\"},\"implementation()\":{\"details\":\"Returns the current implementation. NOTE: Only the admin can call this function. See {ProxyAdmin-getProxyImplementation}. TIP: To get this value clients can read directly from the storage slot shown below (specified by EIP1967) using the https://eth.wiki/json-rpc/API#eth_getstorageat[`eth_getStorageAt`] RPC call. `0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc`\"},\"upgradeTo(address)\":{\"details\":\"Upgrade the implementation of the proxy. NOTE: Only the admin can call this function. See {ProxyAdmin-upgrade}.\"},\"upgradeToAndCall(address,bytes)\":{\"details\":\"Upgrade the implementation of the proxy, and then call a function from the new implementation as specified by `data`, which should be an encoded function call. This is useful to initialize new storage variables in the proxied contract. NOTE: Only the admin can call this function. See {ProxyAdmin-upgradeAndCall}.\"}},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/external/TransparentUpgradeableProxy.sol\":\"TransparentUpgradeableProxy\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":1000000},\"remappings\":[]},\"sources\":{\"@openzeppelin/contracts/interfaces/draft-IERC1822.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.5.0) (interfaces/draft-IERC1822.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev ERC1822: Universal Upgradeable Proxy Standard (UUPS) documents a method for upgradeability through a simplified\\n * proxy whose upgrades are fully controlled by the current implementation.\\n */\\ninterface IERC1822Proxiable {\\n /**\\n * @dev Returns the storage slot that the proxiable contract assumes is being used to store the implementation\\n * address.\\n *\\n * IMPORTANT: A proxy pointing at a proxiable contract should not be considered proxiable itself, because this risks\\n * bricking a proxy that upgrades to it, by delegating to itself until out of gas. Thus it is critical that this\\n * function revert if invoked through a proxy.\\n */\\n function proxiableUUID() external view returns (bytes32);\\n}\\n\",\"keccak256\":\"0x1d4afe6cb24200cc4545eed814ecf5847277dfe5d613a1707aad5fceecebcfff\",\"license\":\"MIT\"},\"@openzeppelin/contracts/proxy/ERC1967/ERC1967Proxy.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.7.0) (proxy/ERC1967/ERC1967Proxy.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../Proxy.sol\\\";\\nimport \\\"./ERC1967Upgrade.sol\\\";\\n\\n/**\\n * @dev This contract implements an upgradeable proxy. It is upgradeable because calls are delegated to an\\n * implementation address that can be changed. This address is stored in storage in the location specified by\\n * https://eips.ethereum.org/EIPS/eip-1967[EIP1967], so that it doesn't conflict with the storage layout of the\\n * implementation behind the proxy.\\n */\\ncontract ERC1967Proxy is Proxy, ERC1967Upgrade {\\n /**\\n * @dev Initializes the upgradeable proxy with an initial implementation specified by `_logic`.\\n *\\n * If `_data` is nonempty, it's used as data in a delegate call to `_logic`. This will typically be an encoded\\n * function call, and allows initializing the storage of the proxy like a Solidity constructor.\\n */\\n constructor(address _logic, bytes memory _data) payable {\\n _upgradeToAndCall(_logic, _data, false);\\n }\\n\\n /**\\n * @dev Returns the current implementation address.\\n */\\n function _implementation() internal view virtual override returns (address impl) {\\n return ERC1967Upgrade._getImplementation();\\n }\\n}\\n\",\"keccak256\":\"0xa2b22da3032e50b55f95ec1d13336102d675f341167aa76db571ef7f8bb7975d\",\"license\":\"MIT\"},\"@openzeppelin/contracts/proxy/ERC1967/ERC1967Upgrade.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.5.0) (proxy/ERC1967/ERC1967Upgrade.sol)\\n\\npragma solidity ^0.8.2;\\n\\nimport \\\"../beacon/IBeacon.sol\\\";\\nimport \\\"../../interfaces/draft-IERC1822.sol\\\";\\nimport \\\"../../utils/Address.sol\\\";\\nimport \\\"../../utils/StorageSlot.sol\\\";\\n\\n/**\\n * @dev This abstract contract provides getters and event emitting update functions for\\n * https://eips.ethereum.org/EIPS/eip-1967[EIP1967] slots.\\n *\\n * _Available since v4.1._\\n *\\n * @custom:oz-upgrades-unsafe-allow delegatecall\\n */\\nabstract contract ERC1967Upgrade {\\n // This is the keccak-256 hash of \\\"eip1967.proxy.rollback\\\" subtracted by 1\\n bytes32 private constant _ROLLBACK_SLOT = 0x4910fdfa16fed3260ed0e7147f7cc6da11a60208b5b9406d12a635614ffd9143;\\n\\n /**\\n * @dev Storage slot with the address of the current implementation.\\n * This is the keccak-256 hash of \\\"eip1967.proxy.implementation\\\" subtracted by 1, and is\\n * validated in the constructor.\\n */\\n bytes32 internal constant _IMPLEMENTATION_SLOT = 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc;\\n\\n /**\\n * @dev Emitted when the implementation is upgraded.\\n */\\n event Upgraded(address indexed implementation);\\n\\n /**\\n * @dev Returns the current implementation address.\\n */\\n function _getImplementation() internal view returns (address) {\\n return StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value;\\n }\\n\\n /**\\n * @dev Stores a new address in the EIP1967 implementation slot.\\n */\\n function _setImplementation(address newImplementation) private {\\n require(Address.isContract(newImplementation), \\\"ERC1967: new implementation is not a contract\\\");\\n StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value = newImplementation;\\n }\\n\\n /**\\n * @dev Perform implementation upgrade\\n *\\n * Emits an {Upgraded} event.\\n */\\n function _upgradeTo(address newImplementation) internal {\\n _setImplementation(newImplementation);\\n emit Upgraded(newImplementation);\\n }\\n\\n /**\\n * @dev Perform implementation upgrade with additional setup call.\\n *\\n * Emits an {Upgraded} event.\\n */\\n function _upgradeToAndCall(\\n address newImplementation,\\n bytes memory data,\\n bool forceCall\\n ) internal {\\n _upgradeTo(newImplementation);\\n if (data.length > 0 || forceCall) {\\n Address.functionDelegateCall(newImplementation, data);\\n }\\n }\\n\\n /**\\n * @dev Perform implementation upgrade with security checks for UUPS proxies, and additional setup call.\\n *\\n * Emits an {Upgraded} event.\\n */\\n function _upgradeToAndCallUUPS(\\n address newImplementation,\\n bytes memory data,\\n bool forceCall\\n ) internal {\\n // Upgrades from old implementations will perform a rollback test. This test requires the new\\n // implementation to upgrade back to the old, non-ERC1822 compliant, implementation. Removing\\n // this special case will break upgrade paths from old UUPS implementation to new ones.\\n if (StorageSlot.getBooleanSlot(_ROLLBACK_SLOT).value) {\\n _setImplementation(newImplementation);\\n } else {\\n try IERC1822Proxiable(newImplementation).proxiableUUID() returns (bytes32 slot) {\\n require(slot == _IMPLEMENTATION_SLOT, \\\"ERC1967Upgrade: unsupported proxiableUUID\\\");\\n } catch {\\n revert(\\\"ERC1967Upgrade: new implementation is not UUPS\\\");\\n }\\n _upgradeToAndCall(newImplementation, data, forceCall);\\n }\\n }\\n\\n /**\\n * @dev Storage slot with the admin of the contract.\\n * This is the keccak-256 hash of \\\"eip1967.proxy.admin\\\" subtracted by 1, and is\\n * validated in the constructor.\\n */\\n bytes32 internal constant _ADMIN_SLOT = 0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103;\\n\\n /**\\n * @dev Emitted when the admin account has changed.\\n */\\n event AdminChanged(address previousAdmin, address newAdmin);\\n\\n /**\\n * @dev Returns the current admin.\\n */\\n function _getAdmin() internal view returns (address) {\\n return StorageSlot.getAddressSlot(_ADMIN_SLOT).value;\\n }\\n\\n /**\\n * @dev Stores a new address in the EIP1967 admin slot.\\n */\\n function _setAdmin(address newAdmin) private {\\n require(newAdmin != address(0), \\\"ERC1967: new admin is the zero address\\\");\\n StorageSlot.getAddressSlot(_ADMIN_SLOT).value = newAdmin;\\n }\\n\\n /**\\n * @dev Changes the admin of the proxy.\\n *\\n * Emits an {AdminChanged} event.\\n */\\n function _changeAdmin(address newAdmin) internal {\\n emit AdminChanged(_getAdmin(), newAdmin);\\n _setAdmin(newAdmin);\\n }\\n\\n /**\\n * @dev The storage slot of the UpgradeableBeacon contract which defines the implementation for this proxy.\\n * This is bytes32(uint256(keccak256('eip1967.proxy.beacon')) - 1)) and is validated in the constructor.\\n */\\n bytes32 internal constant _BEACON_SLOT = 0xa3f0ad74e5423aebfd80d3ef4346578335a9a72aeaee59ff6cb3582b35133d50;\\n\\n /**\\n * @dev Emitted when the beacon is upgraded.\\n */\\n event BeaconUpgraded(address indexed beacon);\\n\\n /**\\n * @dev Returns the current beacon.\\n */\\n function _getBeacon() internal view returns (address) {\\n return StorageSlot.getAddressSlot(_BEACON_SLOT).value;\\n }\\n\\n /**\\n * @dev Stores a new beacon in the EIP1967 beacon slot.\\n */\\n function _setBeacon(address newBeacon) private {\\n require(Address.isContract(newBeacon), \\\"ERC1967: new beacon is not a contract\\\");\\n require(\\n Address.isContract(IBeacon(newBeacon).implementation()),\\n \\\"ERC1967: beacon implementation is not a contract\\\"\\n );\\n StorageSlot.getAddressSlot(_BEACON_SLOT).value = newBeacon;\\n }\\n\\n /**\\n * @dev Perform beacon upgrade with additional setup call. Note: This upgrades the address of the beacon, it does\\n * not upgrade the implementation contained in the beacon (see {UpgradeableBeacon-_setImplementation} for that).\\n *\\n * Emits a {BeaconUpgraded} event.\\n */\\n function _upgradeBeaconToAndCall(\\n address newBeacon,\\n bytes memory data,\\n bool forceCall\\n ) internal {\\n _setBeacon(newBeacon);\\n emit BeaconUpgraded(newBeacon);\\n if (data.length > 0 || forceCall) {\\n Address.functionDelegateCall(IBeacon(newBeacon).implementation(), data);\\n }\\n }\\n}\\n\",\"keccak256\":\"0xabf3f59bc0e5423eae45e459dbe92e7052c6983628d39008590edc852a62f94a\",\"license\":\"MIT\"},\"@openzeppelin/contracts/proxy/Proxy.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.6.0) (proxy/Proxy.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev This abstract contract provides a fallback function that delegates all calls to another contract using the EVM\\n * instruction `delegatecall`. We refer to the second contract as the _implementation_ behind the proxy, and it has to\\n * be specified by overriding the virtual {_implementation} function.\\n *\\n * Additionally, delegation to the implementation can be triggered manually through the {_fallback} function, or to a\\n * different contract through the {_delegate} function.\\n *\\n * The success and return data of the delegated call will be returned back to the caller of the proxy.\\n */\\nabstract contract Proxy {\\n /**\\n * @dev Delegates the current call to `implementation`.\\n *\\n * This function does not return to its internal call site, it will return directly to the external caller.\\n */\\n function _delegate(address implementation) internal virtual {\\n assembly {\\n // Copy msg.data. We take full control of memory in this inline assembly\\n // block because it will not return to Solidity code. We overwrite the\\n // Solidity scratch pad at memory position 0.\\n calldatacopy(0, 0, calldatasize())\\n\\n // Call the implementation.\\n // out and outsize are 0 because we don't know the size yet.\\n let result := delegatecall(gas(), implementation, 0, calldatasize(), 0, 0)\\n\\n // Copy the returned data.\\n returndatacopy(0, 0, returndatasize())\\n\\n switch result\\n // delegatecall returns 0 on error.\\n case 0 {\\n revert(0, returndatasize())\\n }\\n default {\\n return(0, returndatasize())\\n }\\n }\\n }\\n\\n /**\\n * @dev This is a virtual function that should be overridden so it returns the address to which the fallback function\\n * and {_fallback} should delegate.\\n */\\n function _implementation() internal view virtual returns (address);\\n\\n /**\\n * @dev Delegates the current call to the address returned by `_implementation()`.\\n *\\n * This function does not return to its internal call site, it will return directly to the external caller.\\n */\\n function _fallback() internal virtual {\\n _beforeFallback();\\n _delegate(_implementation());\\n }\\n\\n /**\\n * @dev Fallback function that delegates calls to the address returned by `_implementation()`. Will run if no other\\n * function in the contract matches the call data.\\n */\\n fallback() external payable virtual {\\n _fallback();\\n }\\n\\n /**\\n * @dev Fallback function that delegates calls to the address returned by `_implementation()`. Will run if call data\\n * is empty.\\n */\\n receive() external payable virtual {\\n _fallback();\\n }\\n\\n /**\\n * @dev Hook that is called before falling back to the implementation. Can happen as part of a manual `_fallback`\\n * call, or as part of the Solidity `fallback` or `receive` functions.\\n *\\n * If overridden should call `super._beforeFallback()`.\\n */\\n function _beforeFallback() internal virtual {}\\n}\\n\",\"keccak256\":\"0xc130fe33f1b2132158531a87734153293f6d07bc263ff4ac90e85da9c82c0e27\",\"license\":\"MIT\"},\"@openzeppelin/contracts/proxy/beacon/IBeacon.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (proxy/beacon/IBeacon.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev This is the interface that {BeaconProxy} expects of its beacon.\\n */\\ninterface IBeacon {\\n /**\\n * @dev Must return an address that can be used as a delegate call target.\\n *\\n * {BeaconProxy} will check that this address is a contract.\\n */\\n function implementation() external view returns (address);\\n}\\n\",\"keccak256\":\"0xd50a3421ac379ccb1be435fa646d66a65c986b4924f0849839f08692f39dde61\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/Address.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.7.0) (utils/Address.sol)\\n\\npragma solidity ^0.8.1;\\n\\n/**\\n * @dev Collection of functions related to the address type\\n */\\nlibrary Address {\\n /**\\n * @dev Returns true if `account` is a contract.\\n *\\n * [IMPORTANT]\\n * ====\\n * It is unsafe to assume that an address for which this function returns\\n * false is an externally-owned account (EOA) and not a contract.\\n *\\n * Among others, `isContract` will return false for the following\\n * types of addresses:\\n *\\n * - an externally-owned account\\n * - a contract in construction\\n * - an address where a contract will be created\\n * - an address where a contract lived, but was destroyed\\n * ====\\n *\\n * [IMPORTANT]\\n * ====\\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\\n *\\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\\n * constructor.\\n * ====\\n */\\n function isContract(address account) internal view returns (bool) {\\n // This method relies on extcodesize/address.code.length, which returns 0\\n // for contracts in construction, since the code is only stored at the end\\n // of the constructor execution.\\n\\n return account.code.length > 0;\\n }\\n\\n /**\\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\\n * `recipient`, forwarding all available gas and reverting on errors.\\n *\\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\\n * imposed by `transfer`, making them unable to receive funds via\\n * `transfer`. {sendValue} removes this limitation.\\n *\\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\\n *\\n * IMPORTANT: because control is transferred to `recipient`, care must be\\n * taken to not create reentrancy vulnerabilities. Consider using\\n * {ReentrancyGuard} or the\\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\\n */\\n function sendValue(address payable recipient, uint256 amount) internal {\\n require(address(this).balance >= amount, \\\"Address: insufficient balance\\\");\\n\\n (bool success, ) = recipient.call{value: amount}(\\\"\\\");\\n require(success, \\\"Address: unable to send value, recipient may have reverted\\\");\\n }\\n\\n /**\\n * @dev Performs a Solidity function call using a low level `call`. A\\n * plain `call` is an unsafe replacement for a function call: use this\\n * function instead.\\n *\\n * If `target` reverts with a revert reason, it is bubbled up by this\\n * function (like regular Solidity function calls).\\n *\\n * Returns the raw returned data. To convert to the expected return value,\\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\\n *\\n * Requirements:\\n *\\n * - `target` must be a contract.\\n * - calling `target` with `data` must not revert.\\n *\\n * _Available since v3.1._\\n */\\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\\n return functionCall(target, data, \\\"Address: low-level call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\\n * `errorMessage` as a fallback revert reason when `target` reverts.\\n *\\n * _Available since v3.1._\\n */\\n function functionCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n return functionCallWithValue(target, data, 0, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but also transferring `value` wei to `target`.\\n *\\n * Requirements:\\n *\\n * - the calling contract must have an ETH balance of at least `value`.\\n * - the called Solidity function must be `payable`.\\n *\\n * _Available since v3.1._\\n */\\n function functionCallWithValue(\\n address target,\\n bytes memory data,\\n uint256 value\\n ) internal returns (bytes memory) {\\n return functionCallWithValue(target, data, value, \\\"Address: low-level call with value failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\\n * with `errorMessage` as a fallback revert reason when `target` reverts.\\n *\\n * _Available since v3.1._\\n */\\n function functionCallWithValue(\\n address target,\\n bytes memory data,\\n uint256 value,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n require(address(this).balance >= value, \\\"Address: insufficient balance for call\\\");\\n require(isContract(target), \\\"Address: call to non-contract\\\");\\n\\n (bool success, bytes memory returndata) = target.call{value: value}(data);\\n return verifyCallResult(success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but performing a static call.\\n *\\n * _Available since v3.3._\\n */\\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\\n return functionStaticCall(target, data, \\\"Address: low-level static call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\\n * but performing a static call.\\n *\\n * _Available since v3.3._\\n */\\n function functionStaticCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal view returns (bytes memory) {\\n require(isContract(target), \\\"Address: static call to non-contract\\\");\\n\\n (bool success, bytes memory returndata) = target.staticcall(data);\\n return verifyCallResult(success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but performing a delegate call.\\n *\\n * _Available since v3.4._\\n */\\n function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {\\n return functionDelegateCall(target, data, \\\"Address: low-level delegate call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\\n * but performing a delegate call.\\n *\\n * _Available since v3.4._\\n */\\n function functionDelegateCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n require(isContract(target), \\\"Address: delegate call to non-contract\\\");\\n\\n (bool success, bytes memory returndata) = target.delegatecall(data);\\n return verifyCallResult(success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the\\n * revert reason using the provided one.\\n *\\n * _Available since v4.3._\\n */\\n function verifyCallResult(\\n bool success,\\n bytes memory returndata,\\n string memory errorMessage\\n ) internal pure returns (bytes memory) {\\n if (success) {\\n return returndata;\\n } else {\\n // Look for revert reason and bubble it up if present\\n if (returndata.length > 0) {\\n // The easiest way to bubble the revert reason is using memory via assembly\\n /// @solidity memory-safe-assembly\\n assembly {\\n let returndata_size := mload(returndata)\\n revert(add(32, returndata), returndata_size)\\n }\\n } else {\\n revert(errorMessage);\\n }\\n }\\n }\\n}\\n\",\"keccak256\":\"0xd6153ce99bcdcce22b124f755e72553295be6abcd63804cfdffceb188b8bef10\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/StorageSlot.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.7.0) (utils/StorageSlot.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Library for reading and writing primitive types to specific storage slots.\\n *\\n * Storage slots are often used to avoid storage conflict when dealing with upgradeable contracts.\\n * This library helps with reading and writing to such slots without the need for inline assembly.\\n *\\n * The functions in this library return Slot structs that contain a `value` member that can be used to read or write.\\n *\\n * Example usage to set ERC1967 implementation slot:\\n * ```\\n * contract ERC1967 {\\n * bytes32 internal constant _IMPLEMENTATION_SLOT = 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc;\\n *\\n * function _getImplementation() internal view returns (address) {\\n * return StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value;\\n * }\\n *\\n * function _setImplementation(address newImplementation) internal {\\n * require(Address.isContract(newImplementation), \\\"ERC1967: new implementation is not a contract\\\");\\n * StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value = newImplementation;\\n * }\\n * }\\n * ```\\n *\\n * _Available since v4.1 for `address`, `bool`, `bytes32`, and `uint256`._\\n */\\nlibrary StorageSlot {\\n struct AddressSlot {\\n address value;\\n }\\n\\n struct BooleanSlot {\\n bool value;\\n }\\n\\n struct Bytes32Slot {\\n bytes32 value;\\n }\\n\\n struct Uint256Slot {\\n uint256 value;\\n }\\n\\n /**\\n * @dev Returns an `AddressSlot` with member `value` located at `slot`.\\n */\\n function getAddressSlot(bytes32 slot) internal pure returns (AddressSlot storage r) {\\n /// @solidity memory-safe-assembly\\n assembly {\\n r.slot := slot\\n }\\n }\\n\\n /**\\n * @dev Returns an `BooleanSlot` with member `value` located at `slot`.\\n */\\n function getBooleanSlot(bytes32 slot) internal pure returns (BooleanSlot storage r) {\\n /// @solidity memory-safe-assembly\\n assembly {\\n r.slot := slot\\n }\\n }\\n\\n /**\\n * @dev Returns an `Bytes32Slot` with member `value` located at `slot`.\\n */\\n function getBytes32Slot(bytes32 slot) internal pure returns (Bytes32Slot storage r) {\\n /// @solidity memory-safe-assembly\\n assembly {\\n r.slot := slot\\n }\\n }\\n\\n /**\\n * @dev Returns an `Uint256Slot` with member `value` located at `slot`.\\n */\\n function getUint256Slot(bytes32 slot) internal pure returns (Uint256Slot storage r) {\\n /// @solidity memory-safe-assembly\\n assembly {\\n r.slot := slot\\n }\\n }\\n}\\n\",\"keccak256\":\"0xd5c50c54bf02740ebd122ff06832546cb5fa84486d52695a9ccfd11666e0c81d\",\"license\":\"MIT\"},\"contracts/external/TransparentUpgradeableProxy.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-3.0\\n\\npragma solidity ^0.8.12;\\n\\nimport \\\"@openzeppelin/contracts/proxy/ERC1967/ERC1967Proxy.sol\\\";\\n\\n/**\\n * @dev This contract implements a proxy that is upgradeable by an admin. It is fully forked from OpenZeppelin\\n * `TransparentUpgradeableProxy`\\n *\\n * To avoid https://medium.com/nomic-labs-blog/malicious-backdoors-in-ethereum-proxies-62629adf3357[proxy selector\\n * clashing], which can potentially be used in an attack, this contract uses the\\n * https://blog.openzeppelin.com/the-transparent-proxy-pattern/[transparent proxy pattern]. This pattern implies two\\n * things that go hand in hand:\\n *\\n * 1. If any account other than the admin calls the proxy, the call will be forwarded to the implementation, even if\\n * that call matches one of the admin functions exposed by the proxy itself.\\n * 2. If the admin calls the proxy, it can access the admin functions, but its calls will never be forwarded to the\\n * implementation. If the admin tries to call a function on the implementation it will fail with an error that says\\n * \\\"admin cannot fallback to proxy target\\\".\\n *\\n * These properties mean that the admin account can only be used for admin actions like upgrading the proxy or changing\\n * the admin, so it's best if it's a dedicated account that is not used for anything else. This will avoid headaches due\\n * to sudden errors when trying to call a function from the proxy implementation.\\n *\\n * Our recommendation is for the dedicated account to be an instance of the {ProxyAdmin} contract. If set up this way,\\n * you should think of the `ProxyAdmin` instance as the real administrative interface of your proxy.\\n */\\ncontract TransparentUpgradeableProxy is ERC1967Proxy {\\n /**\\n * @dev Initializes an upgradeable proxy managed by `_admin`, backed by the implementation at `_logic`, and\\n * optionally initialized with `_data` as explained in {ERC1967Proxy-constructor}.\\n */\\n constructor(address _logic, address admin_, bytes memory _data) payable ERC1967Proxy(_logic, _data) {\\n assert(_ADMIN_SLOT == bytes32(uint256(keccak256(\\\"eip1967.proxy.admin\\\")) - 1));\\n _changeAdmin(admin_);\\n }\\n\\n /**\\n * @dev Modifier used internally that will delegate the call to the implementation unless the sender is the admin.\\n */\\n modifier ifAdmin() {\\n if (msg.sender == _getAdmin()) {\\n _;\\n } else {\\n _fallback();\\n }\\n }\\n\\n /**\\n * @dev Returns the current admin.\\n *\\n * NOTE: Only the admin can call this function. See {ProxyAdmin-getProxyAdmin}.\\n *\\n * TIP: To get this value clients can read directly from the storage slot shown below (specified by EIP1967) using the\\n * https://eth.wiki/json-rpc/API#eth_getstorageat[`eth_getStorageAt`] RPC call.\\n * `0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103`\\n */\\n function admin() external ifAdmin returns (address admin_) {\\n admin_ = _getAdmin();\\n }\\n\\n /**\\n * @dev Returns the current implementation.\\n *\\n * NOTE: Only the admin can call this function. See {ProxyAdmin-getProxyImplementation}.\\n *\\n * TIP: To get this value clients can read directly from the storage slot shown below (specified by EIP1967) using the\\n * https://eth.wiki/json-rpc/API#eth_getstorageat[`eth_getStorageAt`] RPC call.\\n * `0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc`\\n */\\n function implementation() external ifAdmin returns (address implementation_) {\\n implementation_ = _implementation();\\n }\\n\\n /**\\n * @dev Changes the admin of the proxy.\\n *\\n * Emits an {AdminChanged} event.\\n *\\n * NOTE: Only the admin can call this function. See {ProxyAdmin-changeProxyAdmin}.\\n */\\n function changeAdmin(address newAdmin) external virtual ifAdmin {\\n _changeAdmin(newAdmin);\\n }\\n\\n /**\\n * @dev Upgrade the implementation of the proxy.\\n *\\n * NOTE: Only the admin can call this function. See {ProxyAdmin-upgrade}.\\n */\\n function upgradeTo(address newImplementation) external ifAdmin {\\n _upgradeToAndCall(newImplementation, bytes(\\\"\\\"), false);\\n }\\n\\n /**\\n * @dev Upgrade the implementation of the proxy, and then call a function from the new implementation as specified\\n * by `data`, which should be an encoded function call. This is useful to initialize new storage variables in the\\n * proxied contract.\\n *\\n * NOTE: Only the admin can call this function. See {ProxyAdmin-upgradeAndCall}.\\n */\\n function upgradeToAndCall(address newImplementation, bytes calldata data) external payable ifAdmin {\\n _upgradeToAndCall(newImplementation, data, true);\\n }\\n\\n /**\\n * @dev Returns the current admin.\\n */\\n function _admin() internal view virtual returns (address) {\\n return _getAdmin();\\n }\\n\\n /**\\n * @dev Makes sure the admin cannot access the fallback function. See {Proxy-_beforeFallback}.\\n */\\n function _beforeFallback() internal virtual override {\\n require(msg.sender != _getAdmin(), \\\"TransparentUpgradeableProxy: admin cannot fallback to proxy target\\\");\\n super._beforeFallback();\\n }\\n}\\n\",\"keccak256\":\"0x93a67a0f612ea3ff2a76315e138a6a88267270a1379d3cc7be52845fbbe611e2\",\"license\":\"GPL-3.0\"}},\"version\":1}", + "bytecode": "0x6080604052604051620010bb380380620010bb8339810160408190526200002691620004d8565b828162000036828260006200009a565b5062000066905060017fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6104620005b8565b6000805160206200107483398151915214620000865762000086620005da565b6200009182620000d7565b50505062000643565b620000a58362000132565b600082511180620000b35750805b15620000d257620000d083836200017460201b6200028c1760201c565b505b505050565b7f7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f62000102620001a5565b604080516001600160a01b03928316815291841660208301520160405180910390a16200012f81620001de565b50565b6200013d8162000293565b6040516001600160a01b038216907fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b90600090a250565b60606200019c8383604051806060016040528060278152602001620010946027913962000347565b90505b92915050565b6000620001cf6000805160206200107483398151915260001b6200042f60201b6200022e1760201c565b546001600160a01b0316919050565b6001600160a01b038116620002495760405162461bcd60e51b815260206004820152602660248201527f455243313936373a206e65772061646d696e20697320746865207a65726f206160448201526564647265737360d01b60648201526084015b60405180910390fd5b80620002726000805160206200107483398151915260001b6200042f60201b6200022e1760201c565b80546001600160a01b0319166001600160a01b039290921691909117905550565b620002a9816200043260201b620002b81760201c565b6200030d5760405162461bcd60e51b815260206004820152602d60248201527f455243313936373a206e657720696d706c656d656e746174696f6e206973206e60448201526c1bdd08184818dbdb9d1c9858dd609a1b606482015260840162000240565b80620002727f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc60001b6200042f60201b6200022e1760201c565b60606001600160a01b0384163b620003b15760405162461bcd60e51b815260206004820152602660248201527f416464726573733a2064656c65676174652063616c6c20746f206e6f6e2d636f6044820152651b9d1c9858dd60d21b606482015260840162000240565b600080856001600160a01b031685604051620003ce9190620005f0565b600060405180830381855af49150503d80600081146200040b576040519150601f19603f3d011682016040523d82523d6000602084013e62000410565b606091505b5090925090506200042382828662000441565b925050505b9392505050565b90565b6001600160a01b03163b151590565b606083156200045257508162000428565b825115620004635782518084602001fd5b8160405162461bcd60e51b81526004016200024091906200060e565b80516001600160a01b03811681146200049757600080fd5b919050565b634e487b7160e01b600052604160045260246000fd5b60005b83811015620004cf578181015183820152602001620004b5565b50506000910152565b600080600060608486031215620004ee57600080fd5b620004f9846200047f565b925062000509602085016200047f565b60408501519092506001600160401b03808211156200052757600080fd5b818601915086601f8301126200053c57600080fd5b8151818111156200055157620005516200049c565b604051601f8201601f19908116603f011681019083821181831017156200057c576200057c6200049c565b816040528281528960208487010111156200059657600080fd5b620005a9836020830160208801620004b2565b80955050505050509250925092565b818103818111156200019f57634e487b7160e01b600052601160045260246000fd5b634e487b7160e01b600052600160045260246000fd5b6000825162000604818460208701620004b2565b9190910192915050565b60208152600082518060208401526200062f816040850160208701620004b2565b601f01601f19169190910160400192915050565b610a2180620006536000396000f3fe60806040526004361061005e5760003560e01c80635c60da1b116100435780635c60da1b146100a85780638f283970146100e6578063f851a440146101065761006d565b80633659cfe6146100755780634f1ef286146100955761006d565b3661006d5761006b61011b565b005b61006b61011b565b34801561008157600080fd5b5061006b610090366004610895565b610135565b61006b6100a33660046108b0565b61017f565b3480156100b457600080fd5b506100bd6101f3565b60405173ffffffffffffffffffffffffffffffffffffffff909116815260200160405180910390f35b3480156100f257600080fd5b5061006b610101366004610895565b610231565b34801561011257600080fd5b506100bd61025e565b6101236102d4565b61013361012e6103ab565b6103b5565b565b61013d6103d9565b73ffffffffffffffffffffffffffffffffffffffff1633036101775761017481604051806020016040528060008152506000610419565b50565b61017461011b565b6101876103d9565b73ffffffffffffffffffffffffffffffffffffffff1633036101eb576101e68383838080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525060019250610419915050565b505050565b6101e661011b565b60006101fd6103d9565b73ffffffffffffffffffffffffffffffffffffffff163303610226576102216103ab565b905090565b61022e61011b565b90565b6102396103d9565b73ffffffffffffffffffffffffffffffffffffffff1633036101775761017481610444565b60006102686103d9565b73ffffffffffffffffffffffffffffffffffffffff163303610226576102216103d9565b60606102b183836040518060600160405280602781526020016109c5602791396104a5565b9392505050565b73ffffffffffffffffffffffffffffffffffffffff163b151590565b6102dc6103d9565b73ffffffffffffffffffffffffffffffffffffffff163303610133576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604260248201527f5472616e73706172656e745570677261646561626c6550726f78793a2061646d60448201527f696e2063616e6e6f742066616c6c6261636b20746f2070726f7879207461726760648201527f6574000000000000000000000000000000000000000000000000000000000000608482015260a4015b60405180910390fd5b60006102216105cd565b3660008037600080366000845af43d6000803e8080156103d4573d6000f35b3d6000fd5b60007fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035b5473ffffffffffffffffffffffffffffffffffffffff16919050565b610422836105f5565b60008251118061042f5750805b156101e65761043e838361028c565b50505050565b7f7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f61046d6103d9565b6040805173ffffffffffffffffffffffffffffffffffffffff928316815291841660208301520160405180910390a161017481610642565b606073ffffffffffffffffffffffffffffffffffffffff84163b61054b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f416464726573733a2064656c65676174652063616c6c20746f206e6f6e2d636f60448201527f6e7472616374000000000000000000000000000000000000000000000000000060648201526084016103a2565b6000808573ffffffffffffffffffffffffffffffffffffffff16856040516105739190610957565b600060405180830381855af49150503d80600081146105ae576040519150601f19603f3d011682016040523d82523d6000602084013e6105b3565b606091505b50915091506105c382828661074e565b9695505050505050565b60007f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc6103fd565b6105fe816107a1565b60405173ffffffffffffffffffffffffffffffffffffffff8216907fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b90600090a250565b73ffffffffffffffffffffffffffffffffffffffff81166106e5576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f455243313936373a206e65772061646d696e20697320746865207a65726f206160448201527f646472657373000000000000000000000000000000000000000000000000000060648201526084016103a2565b807fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035b80547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff9290921691909117905550565b6060831561075d5750816102b1565b82511561076d5782518084602001fd5b816040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016103a29190610973565b73ffffffffffffffffffffffffffffffffffffffff81163b610845576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602d60248201527f455243313936373a206e657720696d706c656d656e746174696f6e206973206e60448201527f6f74206120636f6e74726163740000000000000000000000000000000000000060648201526084016103a2565b807f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc610708565b803573ffffffffffffffffffffffffffffffffffffffff8116811461089057600080fd5b919050565b6000602082840312156108a757600080fd5b6102b18261086c565b6000806000604084860312156108c557600080fd5b6108ce8461086c565b9250602084013567ffffffffffffffff808211156108eb57600080fd5b818601915086601f8301126108ff57600080fd5b81358181111561090e57600080fd5b87602082850101111561092057600080fd5b6020830194508093505050509250925092565b60005b8381101561094e578181015183820152602001610936565b50506000910152565b60008251610969818460208701610933565b9190910192915050565b6020815260008251806020840152610992816040850160208701610933565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016919091016040019291505056fe416464726573733a206c6f772d6c6576656c2064656c65676174652063616c6c206661696c6564a2646970667358221220e96638b07fb1675d93a95c49e417bc8111448b23a59918698cdcd8fd488dd7cf64736f6c63430008110033b53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103416464726573733a206c6f772d6c6576656c2064656c65676174652063616c6c206661696c6564", + "deployedBytecode": "0x60806040526004361061005e5760003560e01c80635c60da1b116100435780635c60da1b146100a85780638f283970146100e6578063f851a440146101065761006d565b80633659cfe6146100755780634f1ef286146100955761006d565b3661006d5761006b61011b565b005b61006b61011b565b34801561008157600080fd5b5061006b610090366004610895565b610135565b61006b6100a33660046108b0565b61017f565b3480156100b457600080fd5b506100bd6101f3565b60405173ffffffffffffffffffffffffffffffffffffffff909116815260200160405180910390f35b3480156100f257600080fd5b5061006b610101366004610895565b610231565b34801561011257600080fd5b506100bd61025e565b6101236102d4565b61013361012e6103ab565b6103b5565b565b61013d6103d9565b73ffffffffffffffffffffffffffffffffffffffff1633036101775761017481604051806020016040528060008152506000610419565b50565b61017461011b565b6101876103d9565b73ffffffffffffffffffffffffffffffffffffffff1633036101eb576101e68383838080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525060019250610419915050565b505050565b6101e661011b565b60006101fd6103d9565b73ffffffffffffffffffffffffffffffffffffffff163303610226576102216103ab565b905090565b61022e61011b565b90565b6102396103d9565b73ffffffffffffffffffffffffffffffffffffffff1633036101775761017481610444565b60006102686103d9565b73ffffffffffffffffffffffffffffffffffffffff163303610226576102216103d9565b60606102b183836040518060600160405280602781526020016109c5602791396104a5565b9392505050565b73ffffffffffffffffffffffffffffffffffffffff163b151590565b6102dc6103d9565b73ffffffffffffffffffffffffffffffffffffffff163303610133576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604260248201527f5472616e73706172656e745570677261646561626c6550726f78793a2061646d60448201527f696e2063616e6e6f742066616c6c6261636b20746f2070726f7879207461726760648201527f6574000000000000000000000000000000000000000000000000000000000000608482015260a4015b60405180910390fd5b60006102216105cd565b3660008037600080366000845af43d6000803e8080156103d4573d6000f35b3d6000fd5b60007fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035b5473ffffffffffffffffffffffffffffffffffffffff16919050565b610422836105f5565b60008251118061042f5750805b156101e65761043e838361028c565b50505050565b7f7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f61046d6103d9565b6040805173ffffffffffffffffffffffffffffffffffffffff928316815291841660208301520160405180910390a161017481610642565b606073ffffffffffffffffffffffffffffffffffffffff84163b61054b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f416464726573733a2064656c65676174652063616c6c20746f206e6f6e2d636f60448201527f6e7472616374000000000000000000000000000000000000000000000000000060648201526084016103a2565b6000808573ffffffffffffffffffffffffffffffffffffffff16856040516105739190610957565b600060405180830381855af49150503d80600081146105ae576040519150601f19603f3d011682016040523d82523d6000602084013e6105b3565b606091505b50915091506105c382828661074e565b9695505050505050565b60007f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc6103fd565b6105fe816107a1565b60405173ffffffffffffffffffffffffffffffffffffffff8216907fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b90600090a250565b73ffffffffffffffffffffffffffffffffffffffff81166106e5576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f455243313936373a206e65772061646d696e20697320746865207a65726f206160448201527f646472657373000000000000000000000000000000000000000000000000000060648201526084016103a2565b807fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035b80547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff9290921691909117905550565b6060831561075d5750816102b1565b82511561076d5782518084602001fd5b816040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016103a29190610973565b73ffffffffffffffffffffffffffffffffffffffff81163b610845576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602d60248201527f455243313936373a206e657720696d706c656d656e746174696f6e206973206e60448201527f6f74206120636f6e74726163740000000000000000000000000000000000000060648201526084016103a2565b807f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc610708565b803573ffffffffffffffffffffffffffffffffffffffff8116811461089057600080fd5b919050565b6000602082840312156108a757600080fd5b6102b18261086c565b6000806000604084860312156108c557600080fd5b6108ce8461086c565b9250602084013567ffffffffffffffff808211156108eb57600080fd5b818601915086601f8301126108ff57600080fd5b81358181111561090e57600080fd5b87602082850101111561092057600080fd5b6020830194508093505050509250925092565b60005b8381101561094e578181015183820152602001610936565b50506000910152565b60008251610969818460208701610933565b9190910192915050565b6020815260008251806020840152610992816040850160208701610933565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016919091016040019291505056fe416464726573733a206c6f772d6c6576656c2064656c65676174652063616c6c206661696c6564a2646970667358221220e96638b07fb1675d93a95c49e417bc8111448b23a59918698cdcd8fd488dd7cf64736f6c63430008110033", + "devdoc": { + "details": "This contract implements a proxy that is upgradeable by an admin. It is fully forked from OpenZeppelin `TransparentUpgradeableProxy` To avoid https://medium.com/nomic-labs-blog/malicious-backdoors-in-ethereum-proxies-62629adf3357[proxy selector clashing], which can potentially be used in an attack, this contract uses the https://blog.openzeppelin.com/the-transparent-proxy-pattern/[transparent proxy pattern]. This pattern implies two things that go hand in hand: 1. If any account other than the admin calls the proxy, the call will be forwarded to the implementation, even if that call matches one of the admin functions exposed by the proxy itself. 2. If the admin calls the proxy, it can access the admin functions, but its calls will never be forwarded to the implementation. If the admin tries to call a function on the implementation it will fail with an error that says \"admin cannot fallback to proxy target\". These properties mean that the admin account can only be used for admin actions like upgrading the proxy or changing the admin, so it's best if it's a dedicated account that is not used for anything else. This will avoid headaches due to sudden errors when trying to call a function from the proxy implementation. Our recommendation is for the dedicated account to be an instance of the {ProxyAdmin} contract. If set up this way, you should think of the `ProxyAdmin` instance as the real administrative interface of your proxy.", + "kind": "dev", + "methods": { + "admin()": { + "details": "Returns the current admin. NOTE: Only the admin can call this function. See {ProxyAdmin-getProxyAdmin}. TIP: To get this value clients can read directly from the storage slot shown below (specified by EIP1967) using the https://eth.wiki/json-rpc/API#eth_getstorageat[`eth_getStorageAt`] RPC call. `0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103`" + }, + "changeAdmin(address)": { + "details": "Changes the admin of the proxy. Emits an {AdminChanged} event. NOTE: Only the admin can call this function. See {ProxyAdmin-changeProxyAdmin}." + }, + "constructor": { + "details": "Initializes an upgradeable proxy managed by `_admin`, backed by the implementation at `_logic`, and optionally initialized with `_data` as explained in {ERC1967Proxy-constructor}." + }, + "implementation()": { + "details": "Returns the current implementation. NOTE: Only the admin can call this function. See {ProxyAdmin-getProxyImplementation}. TIP: To get this value clients can read directly from the storage slot shown below (specified by EIP1967) using the https://eth.wiki/json-rpc/API#eth_getstorageat[`eth_getStorageAt`] RPC call. `0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc`" + }, + "upgradeTo(address)": { + "details": "Upgrade the implementation of the proxy. NOTE: Only the admin can call this function. See {ProxyAdmin-upgrade}." + }, + "upgradeToAndCall(address,bytes)": { + "details": "Upgrade the implementation of the proxy, and then call a function from the new implementation as specified by `data`, which should be an encoded function call. This is useful to initialize new storage variables in the proxied contract. NOTE: Only the admin can call this function. See {ProxyAdmin-upgradeAndCall}." + } + }, + "version": 1 + }, + "userdoc": { + "kind": "user", + "methods": {}, + "version": 1 + }, + "storageLayout": { + "storage": [], + "types": null + } +} \ No newline at end of file diff --git a/deployments/bsc/LayerZeroBridge_USD.json b/deployments/bsc/LayerZeroBridge_USD.json new file mode 100644 index 00000000..5ca21703 --- /dev/null +++ b/deployments/bsc/LayerZeroBridge_USD.json @@ -0,0 +1,275 @@ +{ + "address": "0x52F0C256E58c579Bf9E41e4332669b4f7C7209c5", + "abi": [ + { + "inputs": [ + { + "internalType": "address", + "name": "_logic", + "type": "address" + }, + { + "internalType": "address", + "name": "admin_", + "type": "address" + }, + { + "internalType": "bytes", + "name": "_data", + "type": "bytes" + } + ], + "stateMutability": "payable", + "type": "constructor" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "previousAdmin", + "type": "address" + }, + { + "indexed": false, + "internalType": "address", + "name": "newAdmin", + "type": "address" + } + ], + "name": "AdminChanged", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "beacon", + "type": "address" + } + ], + "name": "BeaconUpgraded", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "implementation", + "type": "address" + } + ], + "name": "Upgraded", + "type": "event" + }, + { + "stateMutability": "payable", + "type": "fallback" + }, + { + "inputs": [], + "name": "admin", + "outputs": [ + { + "internalType": "address", + "name": "admin_", + "type": "address" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "newAdmin", + "type": "address" + } + ], + "name": "changeAdmin", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "implementation", + "outputs": [ + { + "internalType": "address", + "name": "implementation_", + "type": "address" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "newImplementation", + "type": "address" + } + ], + "name": "upgradeTo", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "newImplementation", + "type": "address" + }, + { + "internalType": "bytes", + "name": "data", + "type": "bytes" + } + ], + "name": "upgradeToAndCall", + "outputs": [], + "stateMutability": "payable", + "type": "function" + }, + { + "stateMutability": "payable", + "type": "receive" + } + ], + "transactionHash": "0x60283e1ec032471dc7ccd1c90b9881eb434fbb03c31fe8c78b86d624a0f2c7ad", + "receipt": { + "to": null, + "from": "0xfdA462548Ce04282f4B6D6619823a7C64Fdc0185", + "contractAddress": "0x52F0C256E58c579Bf9E41e4332669b4f7C7209c5", + "transactionIndex": 3, + "gasUsed": "849932", + "logsBloom": "0x00000000000000000000000000000000400000000008000000000000000000000000001000000000000000000000000000000000000000000000000001200000000004000000000000000008000002080000000000000000000000000500000000000000020000000000000000000800000000800000000000000010000000000000000000000000000000000000000000000000000080000000000000800000020000000000000000000000000400000000000400000000000000000000000000000022000000000000000104040000000000000420000000000000010020000010000000000000000000000000000000000000000000000000000000000000", + "blockHash": "0x06629cb0c170ef5d11602785caaf3a96a1805c03cc37df0a2da7800baf6961b2", + "transactionHash": "0x60283e1ec032471dc7ccd1c90b9881eb434fbb03c31fe8c78b86d624a0f2c7ad", + "logs": [ + { + "transactionIndex": 3, + "blockNumber": 35121554, + "transactionHash": "0x60283e1ec032471dc7ccd1c90b9881eb434fbb03c31fe8c78b86d624a0f2c7ad", + "address": "0x52F0C256E58c579Bf9E41e4332669b4f7C7209c5", + "topics": [ + "0xbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b", + "0x000000000000000000000000b1f2a25ffb2b095e99f430caf507cc31f9a3eaab" + ], + "data": "0x", + "logIndex": 3, + "blockHash": "0x06629cb0c170ef5d11602785caaf3a96a1805c03cc37df0a2da7800baf6961b2" + }, + { + "transactionIndex": 3, + "blockNumber": 35121554, + "transactionHash": "0x60283e1ec032471dc7ccd1c90b9881eb434fbb03c31fe8c78b86d624a0f2c7ad", + "address": "0x52F0C256E58c579Bf9E41e4332669b4f7C7209c5", + "topics": [ + "0x8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925", + "0x00000000000000000000000052f0c256e58c579bf9e41e4332669b4f7c7209c5", + "0x0000000000000000000000000000206329b97db379d5e1bf586bbdb969c63274" + ], + "data": "0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", + "logIndex": 4, + "blockHash": "0x06629cb0c170ef5d11602785caaf3a96a1805c03cc37df0a2da7800baf6961b2" + }, + { + "transactionIndex": 3, + "blockNumber": 35121554, + "transactionHash": "0x60283e1ec032471dc7ccd1c90b9881eb434fbb03c31fe8c78b86d624a0f2c7ad", + "address": "0x52F0C256E58c579Bf9E41e4332669b4f7C7209c5", + "topics": [ + "0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000206329b97db379d5e1bf586bbdb969c63274" + ], + "data": "0x0000000000000000000000000000000000000000000000000000000000000000", + "logIndex": 5, + "blockHash": "0x06629cb0c170ef5d11602785caaf3a96a1805c03cc37df0a2da7800baf6961b2" + }, + { + "transactionIndex": 3, + "blockNumber": 35121554, + "transactionHash": "0x60283e1ec032471dc7ccd1c90b9881eb434fbb03c31fe8c78b86d624a0f2c7ad", + "address": "0x52F0C256E58c579Bf9E41e4332669b4f7C7209c5", + "topics": [ + "0x7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb3847402498" + ], + "data": "0x0000000000000000000000000000000000000000000000000000000000000001", + "logIndex": 6, + "blockHash": "0x06629cb0c170ef5d11602785caaf3a96a1805c03cc37df0a2da7800baf6961b2" + }, + { + "transactionIndex": 3, + "blockNumber": 35121554, + "transactionHash": "0x60283e1ec032471dc7ccd1c90b9881eb434fbb03c31fe8c78b86d624a0f2c7ad", + "address": "0x52F0C256E58c579Bf9E41e4332669b4f7C7209c5", + "topics": [ + "0x7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f" + ], + "data": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000009a5b060bd7b8f86c4c0d720a17367729670afb19", + "logIndex": 7, + "blockHash": "0x06629cb0c170ef5d11602785caaf3a96a1805c03cc37df0a2da7800baf6961b2" + } + ], + "blockNumber": 35121554, + "cumulativeGasUsed": "966285", + "status": 1, + "byzantium": true + }, + "args": [ + "0xb1F2A25fFB2b095E99f430cAF507cC31F9A3EaAB", + "0x9a5b060Bd7b8f86c4C0D720a17367729670AfB19", + "0xc9aba0aa00000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000000e00000000000000000000000003c2269811836af69497e5f486a85d7316753cf62000000000000000000000000075a2660901430dc5714ca50282e5a2a1eec4e59000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000164c617965725a65726f204272696467652061675553440000000000000000000000000000000000000000000000000000000000000000000000000000000000084c5a2d6167555344000000000000000000000000000000000000000000000000" + ], + "numDeployments": 1, + "solcInputHash": "871924e0c138825a2736b76def8fef8d", + "metadata": "{\"compiler\":{\"version\":\"0.8.17+commit.8df45f5f\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_logic\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"admin_\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"_data\",\"type\":\"bytes\"}],\"stateMutability\":\"payable\",\"type\":\"constructor\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"previousAdmin\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"newAdmin\",\"type\":\"address\"}],\"name\":\"AdminChanged\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"beacon\",\"type\":\"address\"}],\"name\":\"BeaconUpgraded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"implementation\",\"type\":\"address\"}],\"name\":\"Upgraded\",\"type\":\"event\"},{\"stateMutability\":\"payable\",\"type\":\"fallback\"},{\"inputs\":[],\"name\":\"admin\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"admin_\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newAdmin\",\"type\":\"address\"}],\"name\":\"changeAdmin\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"implementation\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"implementation_\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newImplementation\",\"type\":\"address\"}],\"name\":\"upgradeTo\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newImplementation\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"}],\"name\":\"upgradeToAndCall\",\"outputs\":[],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"stateMutability\":\"payable\",\"type\":\"receive\"}],\"devdoc\":{\"details\":\"This contract implements a proxy that is upgradeable by an admin. It is fully forked from OpenZeppelin `TransparentUpgradeableProxy` To avoid https://medium.com/nomic-labs-blog/malicious-backdoors-in-ethereum-proxies-62629adf3357[proxy selector clashing], which can potentially be used in an attack, this contract uses the https://blog.openzeppelin.com/the-transparent-proxy-pattern/[transparent proxy pattern]. This pattern implies two things that go hand in hand: 1. If any account other than the admin calls the proxy, the call will be forwarded to the implementation, even if that call matches one of the admin functions exposed by the proxy itself. 2. If the admin calls the proxy, it can access the admin functions, but its calls will never be forwarded to the implementation. If the admin tries to call a function on the implementation it will fail with an error that says \\\"admin cannot fallback to proxy target\\\". These properties mean that the admin account can only be used for admin actions like upgrading the proxy or changing the admin, so it's best if it's a dedicated account that is not used for anything else. This will avoid headaches due to sudden errors when trying to call a function from the proxy implementation. Our recommendation is for the dedicated account to be an instance of the {ProxyAdmin} contract. If set up this way, you should think of the `ProxyAdmin` instance as the real administrative interface of your proxy.\",\"kind\":\"dev\",\"methods\":{\"admin()\":{\"details\":\"Returns the current admin. NOTE: Only the admin can call this function. See {ProxyAdmin-getProxyAdmin}. TIP: To get this value clients can read directly from the storage slot shown below (specified by EIP1967) using the https://eth.wiki/json-rpc/API#eth_getstorageat[`eth_getStorageAt`] RPC call. `0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103`\"},\"changeAdmin(address)\":{\"details\":\"Changes the admin of the proxy. Emits an {AdminChanged} event. NOTE: Only the admin can call this function. See {ProxyAdmin-changeProxyAdmin}.\"},\"constructor\":{\"details\":\"Initializes an upgradeable proxy managed by `_admin`, backed by the implementation at `_logic`, and optionally initialized with `_data` as explained in {ERC1967Proxy-constructor}.\"},\"implementation()\":{\"details\":\"Returns the current implementation. NOTE: Only the admin can call this function. See {ProxyAdmin-getProxyImplementation}. TIP: To get this value clients can read directly from the storage slot shown below (specified by EIP1967) using the https://eth.wiki/json-rpc/API#eth_getstorageat[`eth_getStorageAt`] RPC call. `0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc`\"},\"upgradeTo(address)\":{\"details\":\"Upgrade the implementation of the proxy. NOTE: Only the admin can call this function. See {ProxyAdmin-upgrade}.\"},\"upgradeToAndCall(address,bytes)\":{\"details\":\"Upgrade the implementation of the proxy, and then call a function from the new implementation as specified by `data`, which should be an encoded function call. This is useful to initialize new storage variables in the proxied contract. NOTE: Only the admin can call this function. See {ProxyAdmin-upgradeAndCall}.\"}},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/external/TransparentUpgradeableProxy.sol\":\"TransparentUpgradeableProxy\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":1000000},\"remappings\":[]},\"sources\":{\"@openzeppelin/contracts/interfaces/draft-IERC1822.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.5.0) (interfaces/draft-IERC1822.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev ERC1822: Universal Upgradeable Proxy Standard (UUPS) documents a method for upgradeability through a simplified\\n * proxy whose upgrades are fully controlled by the current implementation.\\n */\\ninterface IERC1822Proxiable {\\n /**\\n * @dev Returns the storage slot that the proxiable contract assumes is being used to store the implementation\\n * address.\\n *\\n * IMPORTANT: A proxy pointing at a proxiable contract should not be considered proxiable itself, because this risks\\n * bricking a proxy that upgrades to it, by delegating to itself until out of gas. Thus it is critical that this\\n * function revert if invoked through a proxy.\\n */\\n function proxiableUUID() external view returns (bytes32);\\n}\\n\",\"keccak256\":\"0x1d4afe6cb24200cc4545eed814ecf5847277dfe5d613a1707aad5fceecebcfff\",\"license\":\"MIT\"},\"@openzeppelin/contracts/proxy/ERC1967/ERC1967Proxy.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.7.0) (proxy/ERC1967/ERC1967Proxy.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../Proxy.sol\\\";\\nimport \\\"./ERC1967Upgrade.sol\\\";\\n\\n/**\\n * @dev This contract implements an upgradeable proxy. It is upgradeable because calls are delegated to an\\n * implementation address that can be changed. This address is stored in storage in the location specified by\\n * https://eips.ethereum.org/EIPS/eip-1967[EIP1967], so that it doesn't conflict with the storage layout of the\\n * implementation behind the proxy.\\n */\\ncontract ERC1967Proxy is Proxy, ERC1967Upgrade {\\n /**\\n * @dev Initializes the upgradeable proxy with an initial implementation specified by `_logic`.\\n *\\n * If `_data` is nonempty, it's used as data in a delegate call to `_logic`. This will typically be an encoded\\n * function call, and allows initializing the storage of the proxy like a Solidity constructor.\\n */\\n constructor(address _logic, bytes memory _data) payable {\\n _upgradeToAndCall(_logic, _data, false);\\n }\\n\\n /**\\n * @dev Returns the current implementation address.\\n */\\n function _implementation() internal view virtual override returns (address impl) {\\n return ERC1967Upgrade._getImplementation();\\n }\\n}\\n\",\"keccak256\":\"0xa2b22da3032e50b55f95ec1d13336102d675f341167aa76db571ef7f8bb7975d\",\"license\":\"MIT\"},\"@openzeppelin/contracts/proxy/ERC1967/ERC1967Upgrade.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.5.0) (proxy/ERC1967/ERC1967Upgrade.sol)\\n\\npragma solidity ^0.8.2;\\n\\nimport \\\"../beacon/IBeacon.sol\\\";\\nimport \\\"../../interfaces/draft-IERC1822.sol\\\";\\nimport \\\"../../utils/Address.sol\\\";\\nimport \\\"../../utils/StorageSlot.sol\\\";\\n\\n/**\\n * @dev This abstract contract provides getters and event emitting update functions for\\n * https://eips.ethereum.org/EIPS/eip-1967[EIP1967] slots.\\n *\\n * _Available since v4.1._\\n *\\n * @custom:oz-upgrades-unsafe-allow delegatecall\\n */\\nabstract contract ERC1967Upgrade {\\n // This is the keccak-256 hash of \\\"eip1967.proxy.rollback\\\" subtracted by 1\\n bytes32 private constant _ROLLBACK_SLOT = 0x4910fdfa16fed3260ed0e7147f7cc6da11a60208b5b9406d12a635614ffd9143;\\n\\n /**\\n * @dev Storage slot with the address of the current implementation.\\n * This is the keccak-256 hash of \\\"eip1967.proxy.implementation\\\" subtracted by 1, and is\\n * validated in the constructor.\\n */\\n bytes32 internal constant _IMPLEMENTATION_SLOT = 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc;\\n\\n /**\\n * @dev Emitted when the implementation is upgraded.\\n */\\n event Upgraded(address indexed implementation);\\n\\n /**\\n * @dev Returns the current implementation address.\\n */\\n function _getImplementation() internal view returns (address) {\\n return StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value;\\n }\\n\\n /**\\n * @dev Stores a new address in the EIP1967 implementation slot.\\n */\\n function _setImplementation(address newImplementation) private {\\n require(Address.isContract(newImplementation), \\\"ERC1967: new implementation is not a contract\\\");\\n StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value = newImplementation;\\n }\\n\\n /**\\n * @dev Perform implementation upgrade\\n *\\n * Emits an {Upgraded} event.\\n */\\n function _upgradeTo(address newImplementation) internal {\\n _setImplementation(newImplementation);\\n emit Upgraded(newImplementation);\\n }\\n\\n /**\\n * @dev Perform implementation upgrade with additional setup call.\\n *\\n * Emits an {Upgraded} event.\\n */\\n function _upgradeToAndCall(\\n address newImplementation,\\n bytes memory data,\\n bool forceCall\\n ) internal {\\n _upgradeTo(newImplementation);\\n if (data.length > 0 || forceCall) {\\n Address.functionDelegateCall(newImplementation, data);\\n }\\n }\\n\\n /**\\n * @dev Perform implementation upgrade with security checks for UUPS proxies, and additional setup call.\\n *\\n * Emits an {Upgraded} event.\\n */\\n function _upgradeToAndCallUUPS(\\n address newImplementation,\\n bytes memory data,\\n bool forceCall\\n ) internal {\\n // Upgrades from old implementations will perform a rollback test. This test requires the new\\n // implementation to upgrade back to the old, non-ERC1822 compliant, implementation. Removing\\n // this special case will break upgrade paths from old UUPS implementation to new ones.\\n if (StorageSlot.getBooleanSlot(_ROLLBACK_SLOT).value) {\\n _setImplementation(newImplementation);\\n } else {\\n try IERC1822Proxiable(newImplementation).proxiableUUID() returns (bytes32 slot) {\\n require(slot == _IMPLEMENTATION_SLOT, \\\"ERC1967Upgrade: unsupported proxiableUUID\\\");\\n } catch {\\n revert(\\\"ERC1967Upgrade: new implementation is not UUPS\\\");\\n }\\n _upgradeToAndCall(newImplementation, data, forceCall);\\n }\\n }\\n\\n /**\\n * @dev Storage slot with the admin of the contract.\\n * This is the keccak-256 hash of \\\"eip1967.proxy.admin\\\" subtracted by 1, and is\\n * validated in the constructor.\\n */\\n bytes32 internal constant _ADMIN_SLOT = 0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103;\\n\\n /**\\n * @dev Emitted when the admin account has changed.\\n */\\n event AdminChanged(address previousAdmin, address newAdmin);\\n\\n /**\\n * @dev Returns the current admin.\\n */\\n function _getAdmin() internal view returns (address) {\\n return StorageSlot.getAddressSlot(_ADMIN_SLOT).value;\\n }\\n\\n /**\\n * @dev Stores a new address in the EIP1967 admin slot.\\n */\\n function _setAdmin(address newAdmin) private {\\n require(newAdmin != address(0), \\\"ERC1967: new admin is the zero address\\\");\\n StorageSlot.getAddressSlot(_ADMIN_SLOT).value = newAdmin;\\n }\\n\\n /**\\n * @dev Changes the admin of the proxy.\\n *\\n * Emits an {AdminChanged} event.\\n */\\n function _changeAdmin(address newAdmin) internal {\\n emit AdminChanged(_getAdmin(), newAdmin);\\n _setAdmin(newAdmin);\\n }\\n\\n /**\\n * @dev The storage slot of the UpgradeableBeacon contract which defines the implementation for this proxy.\\n * This is bytes32(uint256(keccak256('eip1967.proxy.beacon')) - 1)) and is validated in the constructor.\\n */\\n bytes32 internal constant _BEACON_SLOT = 0xa3f0ad74e5423aebfd80d3ef4346578335a9a72aeaee59ff6cb3582b35133d50;\\n\\n /**\\n * @dev Emitted when the beacon is upgraded.\\n */\\n event BeaconUpgraded(address indexed beacon);\\n\\n /**\\n * @dev Returns the current beacon.\\n */\\n function _getBeacon() internal view returns (address) {\\n return StorageSlot.getAddressSlot(_BEACON_SLOT).value;\\n }\\n\\n /**\\n * @dev Stores a new beacon in the EIP1967 beacon slot.\\n */\\n function _setBeacon(address newBeacon) private {\\n require(Address.isContract(newBeacon), \\\"ERC1967: new beacon is not a contract\\\");\\n require(\\n Address.isContract(IBeacon(newBeacon).implementation()),\\n \\\"ERC1967: beacon implementation is not a contract\\\"\\n );\\n StorageSlot.getAddressSlot(_BEACON_SLOT).value = newBeacon;\\n }\\n\\n /**\\n * @dev Perform beacon upgrade with additional setup call. Note: This upgrades the address of the beacon, it does\\n * not upgrade the implementation contained in the beacon (see {UpgradeableBeacon-_setImplementation} for that).\\n *\\n * Emits a {BeaconUpgraded} event.\\n */\\n function _upgradeBeaconToAndCall(\\n address newBeacon,\\n bytes memory data,\\n bool forceCall\\n ) internal {\\n _setBeacon(newBeacon);\\n emit BeaconUpgraded(newBeacon);\\n if (data.length > 0 || forceCall) {\\n Address.functionDelegateCall(IBeacon(newBeacon).implementation(), data);\\n }\\n }\\n}\\n\",\"keccak256\":\"0xabf3f59bc0e5423eae45e459dbe92e7052c6983628d39008590edc852a62f94a\",\"license\":\"MIT\"},\"@openzeppelin/contracts/proxy/Proxy.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.6.0) (proxy/Proxy.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev This abstract contract provides a fallback function that delegates all calls to another contract using the EVM\\n * instruction `delegatecall`. We refer to the second contract as the _implementation_ behind the proxy, and it has to\\n * be specified by overriding the virtual {_implementation} function.\\n *\\n * Additionally, delegation to the implementation can be triggered manually through the {_fallback} function, or to a\\n * different contract through the {_delegate} function.\\n *\\n * The success and return data of the delegated call will be returned back to the caller of the proxy.\\n */\\nabstract contract Proxy {\\n /**\\n * @dev Delegates the current call to `implementation`.\\n *\\n * This function does not return to its internal call site, it will return directly to the external caller.\\n */\\n function _delegate(address implementation) internal virtual {\\n assembly {\\n // Copy msg.data. We take full control of memory in this inline assembly\\n // block because it will not return to Solidity code. We overwrite the\\n // Solidity scratch pad at memory position 0.\\n calldatacopy(0, 0, calldatasize())\\n\\n // Call the implementation.\\n // out and outsize are 0 because we don't know the size yet.\\n let result := delegatecall(gas(), implementation, 0, calldatasize(), 0, 0)\\n\\n // Copy the returned data.\\n returndatacopy(0, 0, returndatasize())\\n\\n switch result\\n // delegatecall returns 0 on error.\\n case 0 {\\n revert(0, returndatasize())\\n }\\n default {\\n return(0, returndatasize())\\n }\\n }\\n }\\n\\n /**\\n * @dev This is a virtual function that should be overridden so it returns the address to which the fallback function\\n * and {_fallback} should delegate.\\n */\\n function _implementation() internal view virtual returns (address);\\n\\n /**\\n * @dev Delegates the current call to the address returned by `_implementation()`.\\n *\\n * This function does not return to its internal call site, it will return directly to the external caller.\\n */\\n function _fallback() internal virtual {\\n _beforeFallback();\\n _delegate(_implementation());\\n }\\n\\n /**\\n * @dev Fallback function that delegates calls to the address returned by `_implementation()`. Will run if no other\\n * function in the contract matches the call data.\\n */\\n fallback() external payable virtual {\\n _fallback();\\n }\\n\\n /**\\n * @dev Fallback function that delegates calls to the address returned by `_implementation()`. Will run if call data\\n * is empty.\\n */\\n receive() external payable virtual {\\n _fallback();\\n }\\n\\n /**\\n * @dev Hook that is called before falling back to the implementation. Can happen as part of a manual `_fallback`\\n * call, or as part of the Solidity `fallback` or `receive` functions.\\n *\\n * If overridden should call `super._beforeFallback()`.\\n */\\n function _beforeFallback() internal virtual {}\\n}\\n\",\"keccak256\":\"0xc130fe33f1b2132158531a87734153293f6d07bc263ff4ac90e85da9c82c0e27\",\"license\":\"MIT\"},\"@openzeppelin/contracts/proxy/beacon/IBeacon.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (proxy/beacon/IBeacon.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev This is the interface that {BeaconProxy} expects of its beacon.\\n */\\ninterface IBeacon {\\n /**\\n * @dev Must return an address that can be used as a delegate call target.\\n *\\n * {BeaconProxy} will check that this address is a contract.\\n */\\n function implementation() external view returns (address);\\n}\\n\",\"keccak256\":\"0xd50a3421ac379ccb1be435fa646d66a65c986b4924f0849839f08692f39dde61\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/Address.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.7.0) (utils/Address.sol)\\n\\npragma solidity ^0.8.1;\\n\\n/**\\n * @dev Collection of functions related to the address type\\n */\\nlibrary Address {\\n /**\\n * @dev Returns true if `account` is a contract.\\n *\\n * [IMPORTANT]\\n * ====\\n * It is unsafe to assume that an address for which this function returns\\n * false is an externally-owned account (EOA) and not a contract.\\n *\\n * Among others, `isContract` will return false for the following\\n * types of addresses:\\n *\\n * - an externally-owned account\\n * - a contract in construction\\n * - an address where a contract will be created\\n * - an address where a contract lived, but was destroyed\\n * ====\\n *\\n * [IMPORTANT]\\n * ====\\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\\n *\\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\\n * constructor.\\n * ====\\n */\\n function isContract(address account) internal view returns (bool) {\\n // This method relies on extcodesize/address.code.length, which returns 0\\n // for contracts in construction, since the code is only stored at the end\\n // of the constructor execution.\\n\\n return account.code.length > 0;\\n }\\n\\n /**\\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\\n * `recipient`, forwarding all available gas and reverting on errors.\\n *\\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\\n * imposed by `transfer`, making them unable to receive funds via\\n * `transfer`. {sendValue} removes this limitation.\\n *\\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\\n *\\n * IMPORTANT: because control is transferred to `recipient`, care must be\\n * taken to not create reentrancy vulnerabilities. Consider using\\n * {ReentrancyGuard} or the\\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\\n */\\n function sendValue(address payable recipient, uint256 amount) internal {\\n require(address(this).balance >= amount, \\\"Address: insufficient balance\\\");\\n\\n (bool success, ) = recipient.call{value: amount}(\\\"\\\");\\n require(success, \\\"Address: unable to send value, recipient may have reverted\\\");\\n }\\n\\n /**\\n * @dev Performs a Solidity function call using a low level `call`. A\\n * plain `call` is an unsafe replacement for a function call: use this\\n * function instead.\\n *\\n * If `target` reverts with a revert reason, it is bubbled up by this\\n * function (like regular Solidity function calls).\\n *\\n * Returns the raw returned data. To convert to the expected return value,\\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\\n *\\n * Requirements:\\n *\\n * - `target` must be a contract.\\n * - calling `target` with `data` must not revert.\\n *\\n * _Available since v3.1._\\n */\\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\\n return functionCall(target, data, \\\"Address: low-level call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\\n * `errorMessage` as a fallback revert reason when `target` reverts.\\n *\\n * _Available since v3.1._\\n */\\n function functionCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n return functionCallWithValue(target, data, 0, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but also transferring `value` wei to `target`.\\n *\\n * Requirements:\\n *\\n * - the calling contract must have an ETH balance of at least `value`.\\n * - the called Solidity function must be `payable`.\\n *\\n * _Available since v3.1._\\n */\\n function functionCallWithValue(\\n address target,\\n bytes memory data,\\n uint256 value\\n ) internal returns (bytes memory) {\\n return functionCallWithValue(target, data, value, \\\"Address: low-level call with value failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\\n * with `errorMessage` as a fallback revert reason when `target` reverts.\\n *\\n * _Available since v3.1._\\n */\\n function functionCallWithValue(\\n address target,\\n bytes memory data,\\n uint256 value,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n require(address(this).balance >= value, \\\"Address: insufficient balance for call\\\");\\n require(isContract(target), \\\"Address: call to non-contract\\\");\\n\\n (bool success, bytes memory returndata) = target.call{value: value}(data);\\n return verifyCallResult(success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but performing a static call.\\n *\\n * _Available since v3.3._\\n */\\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\\n return functionStaticCall(target, data, \\\"Address: low-level static call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\\n * but performing a static call.\\n *\\n * _Available since v3.3._\\n */\\n function functionStaticCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal view returns (bytes memory) {\\n require(isContract(target), \\\"Address: static call to non-contract\\\");\\n\\n (bool success, bytes memory returndata) = target.staticcall(data);\\n return verifyCallResult(success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but performing a delegate call.\\n *\\n * _Available since v3.4._\\n */\\n function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {\\n return functionDelegateCall(target, data, \\\"Address: low-level delegate call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\\n * but performing a delegate call.\\n *\\n * _Available since v3.4._\\n */\\n function functionDelegateCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n require(isContract(target), \\\"Address: delegate call to non-contract\\\");\\n\\n (bool success, bytes memory returndata) = target.delegatecall(data);\\n return verifyCallResult(success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the\\n * revert reason using the provided one.\\n *\\n * _Available since v4.3._\\n */\\n function verifyCallResult(\\n bool success,\\n bytes memory returndata,\\n string memory errorMessage\\n ) internal pure returns (bytes memory) {\\n if (success) {\\n return returndata;\\n } else {\\n // Look for revert reason and bubble it up if present\\n if (returndata.length > 0) {\\n // The easiest way to bubble the revert reason is using memory via assembly\\n /// @solidity memory-safe-assembly\\n assembly {\\n let returndata_size := mload(returndata)\\n revert(add(32, returndata), returndata_size)\\n }\\n } else {\\n revert(errorMessage);\\n }\\n }\\n }\\n}\\n\",\"keccak256\":\"0xd6153ce99bcdcce22b124f755e72553295be6abcd63804cfdffceb188b8bef10\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/StorageSlot.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.7.0) (utils/StorageSlot.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Library for reading and writing primitive types to specific storage slots.\\n *\\n * Storage slots are often used to avoid storage conflict when dealing with upgradeable contracts.\\n * This library helps with reading and writing to such slots without the need for inline assembly.\\n *\\n * The functions in this library return Slot structs that contain a `value` member that can be used to read or write.\\n *\\n * Example usage to set ERC1967 implementation slot:\\n * ```\\n * contract ERC1967 {\\n * bytes32 internal constant _IMPLEMENTATION_SLOT = 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc;\\n *\\n * function _getImplementation() internal view returns (address) {\\n * return StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value;\\n * }\\n *\\n * function _setImplementation(address newImplementation) internal {\\n * require(Address.isContract(newImplementation), \\\"ERC1967: new implementation is not a contract\\\");\\n * StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value = newImplementation;\\n * }\\n * }\\n * ```\\n *\\n * _Available since v4.1 for `address`, `bool`, `bytes32`, and `uint256`._\\n */\\nlibrary StorageSlot {\\n struct AddressSlot {\\n address value;\\n }\\n\\n struct BooleanSlot {\\n bool value;\\n }\\n\\n struct Bytes32Slot {\\n bytes32 value;\\n }\\n\\n struct Uint256Slot {\\n uint256 value;\\n }\\n\\n /**\\n * @dev Returns an `AddressSlot` with member `value` located at `slot`.\\n */\\n function getAddressSlot(bytes32 slot) internal pure returns (AddressSlot storage r) {\\n /// @solidity memory-safe-assembly\\n assembly {\\n r.slot := slot\\n }\\n }\\n\\n /**\\n * @dev Returns an `BooleanSlot` with member `value` located at `slot`.\\n */\\n function getBooleanSlot(bytes32 slot) internal pure returns (BooleanSlot storage r) {\\n /// @solidity memory-safe-assembly\\n assembly {\\n r.slot := slot\\n }\\n }\\n\\n /**\\n * @dev Returns an `Bytes32Slot` with member `value` located at `slot`.\\n */\\n function getBytes32Slot(bytes32 slot) internal pure returns (Bytes32Slot storage r) {\\n /// @solidity memory-safe-assembly\\n assembly {\\n r.slot := slot\\n }\\n }\\n\\n /**\\n * @dev Returns an `Uint256Slot` with member `value` located at `slot`.\\n */\\n function getUint256Slot(bytes32 slot) internal pure returns (Uint256Slot storage r) {\\n /// @solidity memory-safe-assembly\\n assembly {\\n r.slot := slot\\n }\\n }\\n}\\n\",\"keccak256\":\"0xd5c50c54bf02740ebd122ff06832546cb5fa84486d52695a9ccfd11666e0c81d\",\"license\":\"MIT\"},\"contracts/external/TransparentUpgradeableProxy.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-3.0\\n\\npragma solidity ^0.8.12;\\n\\nimport \\\"@openzeppelin/contracts/proxy/ERC1967/ERC1967Proxy.sol\\\";\\n\\n/**\\n * @dev This contract implements a proxy that is upgradeable by an admin. It is fully forked from OpenZeppelin\\n * `TransparentUpgradeableProxy`\\n *\\n * To avoid https://medium.com/nomic-labs-blog/malicious-backdoors-in-ethereum-proxies-62629adf3357[proxy selector\\n * clashing], which can potentially be used in an attack, this contract uses the\\n * https://blog.openzeppelin.com/the-transparent-proxy-pattern/[transparent proxy pattern]. This pattern implies two\\n * things that go hand in hand:\\n *\\n * 1. If any account other than the admin calls the proxy, the call will be forwarded to the implementation, even if\\n * that call matches one of the admin functions exposed by the proxy itself.\\n * 2. If the admin calls the proxy, it can access the admin functions, but its calls will never be forwarded to the\\n * implementation. If the admin tries to call a function on the implementation it will fail with an error that says\\n * \\\"admin cannot fallback to proxy target\\\".\\n *\\n * These properties mean that the admin account can only be used for admin actions like upgrading the proxy or changing\\n * the admin, so it's best if it's a dedicated account that is not used for anything else. This will avoid headaches due\\n * to sudden errors when trying to call a function from the proxy implementation.\\n *\\n * Our recommendation is for the dedicated account to be an instance of the {ProxyAdmin} contract. If set up this way,\\n * you should think of the `ProxyAdmin` instance as the real administrative interface of your proxy.\\n */\\ncontract TransparentUpgradeableProxy is ERC1967Proxy {\\n /**\\n * @dev Initializes an upgradeable proxy managed by `_admin`, backed by the implementation at `_logic`, and\\n * optionally initialized with `_data` as explained in {ERC1967Proxy-constructor}.\\n */\\n constructor(address _logic, address admin_, bytes memory _data) payable ERC1967Proxy(_logic, _data) {\\n assert(_ADMIN_SLOT == bytes32(uint256(keccak256(\\\"eip1967.proxy.admin\\\")) - 1));\\n _changeAdmin(admin_);\\n }\\n\\n /**\\n * @dev Modifier used internally that will delegate the call to the implementation unless the sender is the admin.\\n */\\n modifier ifAdmin() {\\n if (msg.sender == _getAdmin()) {\\n _;\\n } else {\\n _fallback();\\n }\\n }\\n\\n /**\\n * @dev Returns the current admin.\\n *\\n * NOTE: Only the admin can call this function. See {ProxyAdmin-getProxyAdmin}.\\n *\\n * TIP: To get this value clients can read directly from the storage slot shown below (specified by EIP1967) using the\\n * https://eth.wiki/json-rpc/API#eth_getstorageat[`eth_getStorageAt`] RPC call.\\n * `0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103`\\n */\\n function admin() external ifAdmin returns (address admin_) {\\n admin_ = _getAdmin();\\n }\\n\\n /**\\n * @dev Returns the current implementation.\\n *\\n * NOTE: Only the admin can call this function. See {ProxyAdmin-getProxyImplementation}.\\n *\\n * TIP: To get this value clients can read directly from the storage slot shown below (specified by EIP1967) using the\\n * https://eth.wiki/json-rpc/API#eth_getstorageat[`eth_getStorageAt`] RPC call.\\n * `0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc`\\n */\\n function implementation() external ifAdmin returns (address implementation_) {\\n implementation_ = _implementation();\\n }\\n\\n /**\\n * @dev Changes the admin of the proxy.\\n *\\n * Emits an {AdminChanged} event.\\n *\\n * NOTE: Only the admin can call this function. See {ProxyAdmin-changeProxyAdmin}.\\n */\\n function changeAdmin(address newAdmin) external virtual ifAdmin {\\n _changeAdmin(newAdmin);\\n }\\n\\n /**\\n * @dev Upgrade the implementation of the proxy.\\n *\\n * NOTE: Only the admin can call this function. See {ProxyAdmin-upgrade}.\\n */\\n function upgradeTo(address newImplementation) external ifAdmin {\\n _upgradeToAndCall(newImplementation, bytes(\\\"\\\"), false);\\n }\\n\\n /**\\n * @dev Upgrade the implementation of the proxy, and then call a function from the new implementation as specified\\n * by `data`, which should be an encoded function call. This is useful to initialize new storage variables in the\\n * proxied contract.\\n *\\n * NOTE: Only the admin can call this function. See {ProxyAdmin-upgradeAndCall}.\\n */\\n function upgradeToAndCall(address newImplementation, bytes calldata data) external payable ifAdmin {\\n _upgradeToAndCall(newImplementation, data, true);\\n }\\n\\n /**\\n * @dev Returns the current admin.\\n */\\n function _admin() internal view virtual returns (address) {\\n return _getAdmin();\\n }\\n\\n /**\\n * @dev Makes sure the admin cannot access the fallback function. See {Proxy-_beforeFallback}.\\n */\\n function _beforeFallback() internal virtual override {\\n require(msg.sender != _getAdmin(), \\\"TransparentUpgradeableProxy: admin cannot fallback to proxy target\\\");\\n super._beforeFallback();\\n }\\n}\\n\",\"keccak256\":\"0x93a67a0f612ea3ff2a76315e138a6a88267270a1379d3cc7be52845fbbe611e2\",\"license\":\"GPL-3.0\"}},\"version\":1}", + "bytecode": "0x6080604052604051620010bb380380620010bb8339810160408190526200002691620004d8565b828162000036828260006200009a565b5062000066905060017fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6104620005b8565b6000805160206200107483398151915214620000865762000086620005da565b6200009182620000d7565b50505062000643565b620000a58362000132565b600082511180620000b35750805b15620000d257620000d083836200017460201b6200028c1760201c565b505b505050565b7f7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f62000102620001a5565b604080516001600160a01b03928316815291841660208301520160405180910390a16200012f81620001de565b50565b6200013d8162000293565b6040516001600160a01b038216907fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b90600090a250565b60606200019c8383604051806060016040528060278152602001620010946027913962000347565b90505b92915050565b6000620001cf6000805160206200107483398151915260001b6200042f60201b6200022e1760201c565b546001600160a01b0316919050565b6001600160a01b038116620002495760405162461bcd60e51b815260206004820152602660248201527f455243313936373a206e65772061646d696e20697320746865207a65726f206160448201526564647265737360d01b60648201526084015b60405180910390fd5b80620002726000805160206200107483398151915260001b6200042f60201b6200022e1760201c565b80546001600160a01b0319166001600160a01b039290921691909117905550565b620002a9816200043260201b620002b81760201c565b6200030d5760405162461bcd60e51b815260206004820152602d60248201527f455243313936373a206e657720696d706c656d656e746174696f6e206973206e60448201526c1bdd08184818dbdb9d1c9858dd609a1b606482015260840162000240565b80620002727f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc60001b6200042f60201b6200022e1760201c565b60606001600160a01b0384163b620003b15760405162461bcd60e51b815260206004820152602660248201527f416464726573733a2064656c65676174652063616c6c20746f206e6f6e2d636f6044820152651b9d1c9858dd60d21b606482015260840162000240565b600080856001600160a01b031685604051620003ce9190620005f0565b600060405180830381855af49150503d80600081146200040b576040519150601f19603f3d011682016040523d82523d6000602084013e62000410565b606091505b5090925090506200042382828662000441565b925050505b9392505050565b90565b6001600160a01b03163b151590565b606083156200045257508162000428565b825115620004635782518084602001fd5b8160405162461bcd60e51b81526004016200024091906200060e565b80516001600160a01b03811681146200049757600080fd5b919050565b634e487b7160e01b600052604160045260246000fd5b60005b83811015620004cf578181015183820152602001620004b5565b50506000910152565b600080600060608486031215620004ee57600080fd5b620004f9846200047f565b925062000509602085016200047f565b60408501519092506001600160401b03808211156200052757600080fd5b818601915086601f8301126200053c57600080fd5b8151818111156200055157620005516200049c565b604051601f8201601f19908116603f011681019083821181831017156200057c576200057c6200049c565b816040528281528960208487010111156200059657600080fd5b620005a9836020830160208801620004b2565b80955050505050509250925092565b818103818111156200019f57634e487b7160e01b600052601160045260246000fd5b634e487b7160e01b600052600160045260246000fd5b6000825162000604818460208701620004b2565b9190910192915050565b60208152600082518060208401526200062f816040850160208701620004b2565b601f01601f19169190910160400192915050565b610a2180620006536000396000f3fe60806040526004361061005e5760003560e01c80635c60da1b116100435780635c60da1b146100a85780638f283970146100e6578063f851a440146101065761006d565b80633659cfe6146100755780634f1ef286146100955761006d565b3661006d5761006b61011b565b005b61006b61011b565b34801561008157600080fd5b5061006b610090366004610895565b610135565b61006b6100a33660046108b0565b61017f565b3480156100b457600080fd5b506100bd6101f3565b60405173ffffffffffffffffffffffffffffffffffffffff909116815260200160405180910390f35b3480156100f257600080fd5b5061006b610101366004610895565b610231565b34801561011257600080fd5b506100bd61025e565b6101236102d4565b61013361012e6103ab565b6103b5565b565b61013d6103d9565b73ffffffffffffffffffffffffffffffffffffffff1633036101775761017481604051806020016040528060008152506000610419565b50565b61017461011b565b6101876103d9565b73ffffffffffffffffffffffffffffffffffffffff1633036101eb576101e68383838080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525060019250610419915050565b505050565b6101e661011b565b60006101fd6103d9565b73ffffffffffffffffffffffffffffffffffffffff163303610226576102216103ab565b905090565b61022e61011b565b90565b6102396103d9565b73ffffffffffffffffffffffffffffffffffffffff1633036101775761017481610444565b60006102686103d9565b73ffffffffffffffffffffffffffffffffffffffff163303610226576102216103d9565b60606102b183836040518060600160405280602781526020016109c5602791396104a5565b9392505050565b73ffffffffffffffffffffffffffffffffffffffff163b151590565b6102dc6103d9565b73ffffffffffffffffffffffffffffffffffffffff163303610133576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604260248201527f5472616e73706172656e745570677261646561626c6550726f78793a2061646d60448201527f696e2063616e6e6f742066616c6c6261636b20746f2070726f7879207461726760648201527f6574000000000000000000000000000000000000000000000000000000000000608482015260a4015b60405180910390fd5b60006102216105cd565b3660008037600080366000845af43d6000803e8080156103d4573d6000f35b3d6000fd5b60007fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035b5473ffffffffffffffffffffffffffffffffffffffff16919050565b610422836105f5565b60008251118061042f5750805b156101e65761043e838361028c565b50505050565b7f7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f61046d6103d9565b6040805173ffffffffffffffffffffffffffffffffffffffff928316815291841660208301520160405180910390a161017481610642565b606073ffffffffffffffffffffffffffffffffffffffff84163b61054b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f416464726573733a2064656c65676174652063616c6c20746f206e6f6e2d636f60448201527f6e7472616374000000000000000000000000000000000000000000000000000060648201526084016103a2565b6000808573ffffffffffffffffffffffffffffffffffffffff16856040516105739190610957565b600060405180830381855af49150503d80600081146105ae576040519150601f19603f3d011682016040523d82523d6000602084013e6105b3565b606091505b50915091506105c382828661074e565b9695505050505050565b60007f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc6103fd565b6105fe816107a1565b60405173ffffffffffffffffffffffffffffffffffffffff8216907fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b90600090a250565b73ffffffffffffffffffffffffffffffffffffffff81166106e5576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f455243313936373a206e65772061646d696e20697320746865207a65726f206160448201527f646472657373000000000000000000000000000000000000000000000000000060648201526084016103a2565b807fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035b80547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff9290921691909117905550565b6060831561075d5750816102b1565b82511561076d5782518084602001fd5b816040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016103a29190610973565b73ffffffffffffffffffffffffffffffffffffffff81163b610845576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602d60248201527f455243313936373a206e657720696d706c656d656e746174696f6e206973206e60448201527f6f74206120636f6e74726163740000000000000000000000000000000000000060648201526084016103a2565b807f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc610708565b803573ffffffffffffffffffffffffffffffffffffffff8116811461089057600080fd5b919050565b6000602082840312156108a757600080fd5b6102b18261086c565b6000806000604084860312156108c557600080fd5b6108ce8461086c565b9250602084013567ffffffffffffffff808211156108eb57600080fd5b818601915086601f8301126108ff57600080fd5b81358181111561090e57600080fd5b87602082850101111561092057600080fd5b6020830194508093505050509250925092565b60005b8381101561094e578181015183820152602001610936565b50506000910152565b60008251610969818460208701610933565b9190910192915050565b6020815260008251806020840152610992816040850160208701610933565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016919091016040019291505056fe416464726573733a206c6f772d6c6576656c2064656c65676174652063616c6c206661696c6564a2646970667358221220e96638b07fb1675d93a95c49e417bc8111448b23a59918698cdcd8fd488dd7cf64736f6c63430008110033b53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103416464726573733a206c6f772d6c6576656c2064656c65676174652063616c6c206661696c6564", + "deployedBytecode": "0x60806040526004361061005e5760003560e01c80635c60da1b116100435780635c60da1b146100a85780638f283970146100e6578063f851a440146101065761006d565b80633659cfe6146100755780634f1ef286146100955761006d565b3661006d5761006b61011b565b005b61006b61011b565b34801561008157600080fd5b5061006b610090366004610895565b610135565b61006b6100a33660046108b0565b61017f565b3480156100b457600080fd5b506100bd6101f3565b60405173ffffffffffffffffffffffffffffffffffffffff909116815260200160405180910390f35b3480156100f257600080fd5b5061006b610101366004610895565b610231565b34801561011257600080fd5b506100bd61025e565b6101236102d4565b61013361012e6103ab565b6103b5565b565b61013d6103d9565b73ffffffffffffffffffffffffffffffffffffffff1633036101775761017481604051806020016040528060008152506000610419565b50565b61017461011b565b6101876103d9565b73ffffffffffffffffffffffffffffffffffffffff1633036101eb576101e68383838080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525060019250610419915050565b505050565b6101e661011b565b60006101fd6103d9565b73ffffffffffffffffffffffffffffffffffffffff163303610226576102216103ab565b905090565b61022e61011b565b90565b6102396103d9565b73ffffffffffffffffffffffffffffffffffffffff1633036101775761017481610444565b60006102686103d9565b73ffffffffffffffffffffffffffffffffffffffff163303610226576102216103d9565b60606102b183836040518060600160405280602781526020016109c5602791396104a5565b9392505050565b73ffffffffffffffffffffffffffffffffffffffff163b151590565b6102dc6103d9565b73ffffffffffffffffffffffffffffffffffffffff163303610133576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604260248201527f5472616e73706172656e745570677261646561626c6550726f78793a2061646d60448201527f696e2063616e6e6f742066616c6c6261636b20746f2070726f7879207461726760648201527f6574000000000000000000000000000000000000000000000000000000000000608482015260a4015b60405180910390fd5b60006102216105cd565b3660008037600080366000845af43d6000803e8080156103d4573d6000f35b3d6000fd5b60007fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035b5473ffffffffffffffffffffffffffffffffffffffff16919050565b610422836105f5565b60008251118061042f5750805b156101e65761043e838361028c565b50505050565b7f7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f61046d6103d9565b6040805173ffffffffffffffffffffffffffffffffffffffff928316815291841660208301520160405180910390a161017481610642565b606073ffffffffffffffffffffffffffffffffffffffff84163b61054b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f416464726573733a2064656c65676174652063616c6c20746f206e6f6e2d636f60448201527f6e7472616374000000000000000000000000000000000000000000000000000060648201526084016103a2565b6000808573ffffffffffffffffffffffffffffffffffffffff16856040516105739190610957565b600060405180830381855af49150503d80600081146105ae576040519150601f19603f3d011682016040523d82523d6000602084013e6105b3565b606091505b50915091506105c382828661074e565b9695505050505050565b60007f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc6103fd565b6105fe816107a1565b60405173ffffffffffffffffffffffffffffffffffffffff8216907fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b90600090a250565b73ffffffffffffffffffffffffffffffffffffffff81166106e5576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f455243313936373a206e65772061646d696e20697320746865207a65726f206160448201527f646472657373000000000000000000000000000000000000000000000000000060648201526084016103a2565b807fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035b80547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff9290921691909117905550565b6060831561075d5750816102b1565b82511561076d5782518084602001fd5b816040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016103a29190610973565b73ffffffffffffffffffffffffffffffffffffffff81163b610845576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602d60248201527f455243313936373a206e657720696d706c656d656e746174696f6e206973206e60448201527f6f74206120636f6e74726163740000000000000000000000000000000000000060648201526084016103a2565b807f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc610708565b803573ffffffffffffffffffffffffffffffffffffffff8116811461089057600080fd5b919050565b6000602082840312156108a757600080fd5b6102b18261086c565b6000806000604084860312156108c557600080fd5b6108ce8461086c565b9250602084013567ffffffffffffffff808211156108eb57600080fd5b818601915086601f8301126108ff57600080fd5b81358181111561090e57600080fd5b87602082850101111561092057600080fd5b6020830194508093505050509250925092565b60005b8381101561094e578181015183820152602001610936565b50506000910152565b60008251610969818460208701610933565b9190910192915050565b6020815260008251806020840152610992816040850160208701610933565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016919091016040019291505056fe416464726573733a206c6f772d6c6576656c2064656c65676174652063616c6c206661696c6564a2646970667358221220e96638b07fb1675d93a95c49e417bc8111448b23a59918698cdcd8fd488dd7cf64736f6c63430008110033", + "devdoc": { + "details": "This contract implements a proxy that is upgradeable by an admin. It is fully forked from OpenZeppelin `TransparentUpgradeableProxy` To avoid https://medium.com/nomic-labs-blog/malicious-backdoors-in-ethereum-proxies-62629adf3357[proxy selector clashing], which can potentially be used in an attack, this contract uses the https://blog.openzeppelin.com/the-transparent-proxy-pattern/[transparent proxy pattern]. This pattern implies two things that go hand in hand: 1. If any account other than the admin calls the proxy, the call will be forwarded to the implementation, even if that call matches one of the admin functions exposed by the proxy itself. 2. If the admin calls the proxy, it can access the admin functions, but its calls will never be forwarded to the implementation. If the admin tries to call a function on the implementation it will fail with an error that says \"admin cannot fallback to proxy target\". These properties mean that the admin account can only be used for admin actions like upgrading the proxy or changing the admin, so it's best if it's a dedicated account that is not used for anything else. This will avoid headaches due to sudden errors when trying to call a function from the proxy implementation. Our recommendation is for the dedicated account to be an instance of the {ProxyAdmin} contract. If set up this way, you should think of the `ProxyAdmin` instance as the real administrative interface of your proxy.", + "kind": "dev", + "methods": { + "admin()": { + "details": "Returns the current admin. NOTE: Only the admin can call this function. See {ProxyAdmin-getProxyAdmin}. TIP: To get this value clients can read directly from the storage slot shown below (specified by EIP1967) using the https://eth.wiki/json-rpc/API#eth_getstorageat[`eth_getStorageAt`] RPC call. `0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103`" + }, + "changeAdmin(address)": { + "details": "Changes the admin of the proxy. Emits an {AdminChanged} event. NOTE: Only the admin can call this function. See {ProxyAdmin-changeProxyAdmin}." + }, + "constructor": { + "details": "Initializes an upgradeable proxy managed by `_admin`, backed by the implementation at `_logic`, and optionally initialized with `_data` as explained in {ERC1967Proxy-constructor}." + }, + "implementation()": { + "details": "Returns the current implementation. NOTE: Only the admin can call this function. See {ProxyAdmin-getProxyImplementation}. TIP: To get this value clients can read directly from the storage slot shown below (specified by EIP1967) using the https://eth.wiki/json-rpc/API#eth_getstorageat[`eth_getStorageAt`] RPC call. `0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc`" + }, + "upgradeTo(address)": { + "details": "Upgrade the implementation of the proxy. NOTE: Only the admin can call this function. See {ProxyAdmin-upgrade}." + }, + "upgradeToAndCall(address,bytes)": { + "details": "Upgrade the implementation of the proxy, and then call a function from the new implementation as specified by `data`, which should be an encoded function call. This is useful to initialize new storage variables in the proxied contract. NOTE: Only the admin can call this function. See {ProxyAdmin-upgradeAndCall}." + } + }, + "version": 1 + }, + "userdoc": { + "kind": "user", + "methods": {}, + "version": 1 + }, + "storageLayout": { + "storage": [], + "types": null + } +} \ No newline at end of file diff --git a/deployments/bsc/Treasury_USD.json b/deployments/bsc/Treasury_USD.json new file mode 100644 index 00000000..8d5055dd --- /dev/null +++ b/deployments/bsc/Treasury_USD.json @@ -0,0 +1,235 @@ +{ + "address": "0x075A2660901430DC5714Ca50282e5a2A1Eec4e59", + "abi": [ + { + "inputs": [ + { + "internalType": "address", + "name": "_logic", + "type": "address" + }, + { + "internalType": "address", + "name": "admin_", + "type": "address" + }, + { + "internalType": "bytes", + "name": "_data", + "type": "bytes" + } + ], + "stateMutability": "payable", + "type": "constructor" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "previousAdmin", + "type": "address" + }, + { + "indexed": false, + "internalType": "address", + "name": "newAdmin", + "type": "address" + } + ], + "name": "AdminChanged", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "beacon", + "type": "address" + } + ], + "name": "BeaconUpgraded", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "implementation", + "type": "address" + } + ], + "name": "Upgraded", + "type": "event" + }, + { + "stateMutability": "payable", + "type": "fallback" + }, + { + "inputs": [], + "name": "admin", + "outputs": [ + { + "internalType": "address", + "name": "admin_", + "type": "address" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "newAdmin", + "type": "address" + } + ], + "name": "changeAdmin", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "implementation", + "outputs": [ + { + "internalType": "address", + "name": "implementation_", + "type": "address" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "newImplementation", + "type": "address" + } + ], + "name": "upgradeTo", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "newImplementation", + "type": "address" + }, + { + "internalType": "bytes", + "name": "data", + "type": "bytes" + } + ], + "name": "upgradeToAndCall", + "outputs": [], + "stateMutability": "payable", + "type": "function" + }, + { + "stateMutability": "payable", + "type": "receive" + } + ], + "transactionHash": "0x31c8081f0d72a5e87b11f78f9560b621bc00850781d33ccc539e2a5657ee4e6d", + "receipt": { + "to": null, + "from": "0xfdA462548Ce04282f4B6D6619823a7C64Fdc0185", + "contractAddress": "0x075A2660901430DC5714Ca50282e5a2A1Eec4e59", + "transactionIndex": 72, + "gasUsed": "734966", + "logsBloom": "0x00000000000080000000000001000000400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000002000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000000000400000000000800000000000000000000000000000000000000000000000000000000000000000000000010021000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "blockHash": "0x6032fb61fd82dea102186bcdf69fef169a4d0ee39829aa2bb6a36c56919e12d3", + "transactionHash": "0x31c8081f0d72a5e87b11f78f9560b621bc00850781d33ccc539e2a5657ee4e6d", + "logs": [ + { + "transactionIndex": 72, + "blockNumber": 35121551, + "transactionHash": "0x31c8081f0d72a5e87b11f78f9560b621bc00850781d33ccc539e2a5657ee4e6d", + "address": "0x075A2660901430DC5714Ca50282e5a2A1Eec4e59", + "topics": [ + "0xbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b", + "0x0000000000000000000000004b1e2c2762667331bc91648052f646d1b0d35984" + ], + "data": "0x", + "logIndex": 239, + "blockHash": "0x6032fb61fd82dea102186bcdf69fef169a4d0ee39829aa2bb6a36c56919e12d3" + }, + { + "transactionIndex": 72, + "blockNumber": 35121551, + "transactionHash": "0x31c8081f0d72a5e87b11f78f9560b621bc00850781d33ccc539e2a5657ee4e6d", + "address": "0x075A2660901430DC5714Ca50282e5a2A1Eec4e59", + "topics": [ + "0x7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f" + ], + "data": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000009a5b060bd7b8f86c4c0d720a17367729670afb19", + "logIndex": 240, + "blockHash": "0x6032fb61fd82dea102186bcdf69fef169a4d0ee39829aa2bb6a36c56919e12d3" + } + ], + "blockNumber": 35121551, + "cumulativeGasUsed": "7642254", + "status": 1, + "byzantium": true + }, + "args": [ + "0x4b1E2c2762667331Bc91648052F646d1b0d35984", + "0x9a5b060Bd7b8f86c4C0D720a17367729670AfB19", + "0x485cc955000000000000000000000000c1f9266c6d3389e981639ee873121199a7acdb8f0000000000000000000000000000206329b97db379d5e1bf586bbdb969c63274" + ], + "numDeployments": 1, + "solcInputHash": "871924e0c138825a2736b76def8fef8d", + "metadata": "{\"compiler\":{\"version\":\"0.8.17+commit.8df45f5f\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_logic\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"admin_\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"_data\",\"type\":\"bytes\"}],\"stateMutability\":\"payable\",\"type\":\"constructor\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"previousAdmin\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"newAdmin\",\"type\":\"address\"}],\"name\":\"AdminChanged\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"beacon\",\"type\":\"address\"}],\"name\":\"BeaconUpgraded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"implementation\",\"type\":\"address\"}],\"name\":\"Upgraded\",\"type\":\"event\"},{\"stateMutability\":\"payable\",\"type\":\"fallback\"},{\"inputs\":[],\"name\":\"admin\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"admin_\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newAdmin\",\"type\":\"address\"}],\"name\":\"changeAdmin\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"implementation\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"implementation_\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newImplementation\",\"type\":\"address\"}],\"name\":\"upgradeTo\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newImplementation\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"}],\"name\":\"upgradeToAndCall\",\"outputs\":[],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"stateMutability\":\"payable\",\"type\":\"receive\"}],\"devdoc\":{\"details\":\"This contract implements a proxy that is upgradeable by an admin. It is fully forked from OpenZeppelin `TransparentUpgradeableProxy` To avoid https://medium.com/nomic-labs-blog/malicious-backdoors-in-ethereum-proxies-62629adf3357[proxy selector clashing], which can potentially be used in an attack, this contract uses the https://blog.openzeppelin.com/the-transparent-proxy-pattern/[transparent proxy pattern]. This pattern implies two things that go hand in hand: 1. If any account other than the admin calls the proxy, the call will be forwarded to the implementation, even if that call matches one of the admin functions exposed by the proxy itself. 2. If the admin calls the proxy, it can access the admin functions, but its calls will never be forwarded to the implementation. If the admin tries to call a function on the implementation it will fail with an error that says \\\"admin cannot fallback to proxy target\\\". These properties mean that the admin account can only be used for admin actions like upgrading the proxy or changing the admin, so it's best if it's a dedicated account that is not used for anything else. This will avoid headaches due to sudden errors when trying to call a function from the proxy implementation. Our recommendation is for the dedicated account to be an instance of the {ProxyAdmin} contract. If set up this way, you should think of the `ProxyAdmin` instance as the real administrative interface of your proxy.\",\"kind\":\"dev\",\"methods\":{\"admin()\":{\"details\":\"Returns the current admin. NOTE: Only the admin can call this function. See {ProxyAdmin-getProxyAdmin}. TIP: To get this value clients can read directly from the storage slot shown below (specified by EIP1967) using the https://eth.wiki/json-rpc/API#eth_getstorageat[`eth_getStorageAt`] RPC call. `0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103`\"},\"changeAdmin(address)\":{\"details\":\"Changes the admin of the proxy. Emits an {AdminChanged} event. NOTE: Only the admin can call this function. See {ProxyAdmin-changeProxyAdmin}.\"},\"constructor\":{\"details\":\"Initializes an upgradeable proxy managed by `_admin`, backed by the implementation at `_logic`, and optionally initialized with `_data` as explained in {ERC1967Proxy-constructor}.\"},\"implementation()\":{\"details\":\"Returns the current implementation. NOTE: Only the admin can call this function. See {ProxyAdmin-getProxyImplementation}. TIP: To get this value clients can read directly from the storage slot shown below (specified by EIP1967) using the https://eth.wiki/json-rpc/API#eth_getstorageat[`eth_getStorageAt`] RPC call. `0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc`\"},\"upgradeTo(address)\":{\"details\":\"Upgrade the implementation of the proxy. NOTE: Only the admin can call this function. See {ProxyAdmin-upgrade}.\"},\"upgradeToAndCall(address,bytes)\":{\"details\":\"Upgrade the implementation of the proxy, and then call a function from the new implementation as specified by `data`, which should be an encoded function call. This is useful to initialize new storage variables in the proxied contract. NOTE: Only the admin can call this function. See {ProxyAdmin-upgradeAndCall}.\"}},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/external/TransparentUpgradeableProxy.sol\":\"TransparentUpgradeableProxy\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":1000000},\"remappings\":[]},\"sources\":{\"@openzeppelin/contracts/interfaces/draft-IERC1822.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.5.0) (interfaces/draft-IERC1822.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev ERC1822: Universal Upgradeable Proxy Standard (UUPS) documents a method for upgradeability through a simplified\\n * proxy whose upgrades are fully controlled by the current implementation.\\n */\\ninterface IERC1822Proxiable {\\n /**\\n * @dev Returns the storage slot that the proxiable contract assumes is being used to store the implementation\\n * address.\\n *\\n * IMPORTANT: A proxy pointing at a proxiable contract should not be considered proxiable itself, because this risks\\n * bricking a proxy that upgrades to it, by delegating to itself until out of gas. Thus it is critical that this\\n * function revert if invoked through a proxy.\\n */\\n function proxiableUUID() external view returns (bytes32);\\n}\\n\",\"keccak256\":\"0x1d4afe6cb24200cc4545eed814ecf5847277dfe5d613a1707aad5fceecebcfff\",\"license\":\"MIT\"},\"@openzeppelin/contracts/proxy/ERC1967/ERC1967Proxy.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.7.0) (proxy/ERC1967/ERC1967Proxy.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../Proxy.sol\\\";\\nimport \\\"./ERC1967Upgrade.sol\\\";\\n\\n/**\\n * @dev This contract implements an upgradeable proxy. It is upgradeable because calls are delegated to an\\n * implementation address that can be changed. This address is stored in storage in the location specified by\\n * https://eips.ethereum.org/EIPS/eip-1967[EIP1967], so that it doesn't conflict with the storage layout of the\\n * implementation behind the proxy.\\n */\\ncontract ERC1967Proxy is Proxy, ERC1967Upgrade {\\n /**\\n * @dev Initializes the upgradeable proxy with an initial implementation specified by `_logic`.\\n *\\n * If `_data` is nonempty, it's used as data in a delegate call to `_logic`. This will typically be an encoded\\n * function call, and allows initializing the storage of the proxy like a Solidity constructor.\\n */\\n constructor(address _logic, bytes memory _data) payable {\\n _upgradeToAndCall(_logic, _data, false);\\n }\\n\\n /**\\n * @dev Returns the current implementation address.\\n */\\n function _implementation() internal view virtual override returns (address impl) {\\n return ERC1967Upgrade._getImplementation();\\n }\\n}\\n\",\"keccak256\":\"0xa2b22da3032e50b55f95ec1d13336102d675f341167aa76db571ef7f8bb7975d\",\"license\":\"MIT\"},\"@openzeppelin/contracts/proxy/ERC1967/ERC1967Upgrade.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.5.0) (proxy/ERC1967/ERC1967Upgrade.sol)\\n\\npragma solidity ^0.8.2;\\n\\nimport \\\"../beacon/IBeacon.sol\\\";\\nimport \\\"../../interfaces/draft-IERC1822.sol\\\";\\nimport \\\"../../utils/Address.sol\\\";\\nimport \\\"../../utils/StorageSlot.sol\\\";\\n\\n/**\\n * @dev This abstract contract provides getters and event emitting update functions for\\n * https://eips.ethereum.org/EIPS/eip-1967[EIP1967] slots.\\n *\\n * _Available since v4.1._\\n *\\n * @custom:oz-upgrades-unsafe-allow delegatecall\\n */\\nabstract contract ERC1967Upgrade {\\n // This is the keccak-256 hash of \\\"eip1967.proxy.rollback\\\" subtracted by 1\\n bytes32 private constant _ROLLBACK_SLOT = 0x4910fdfa16fed3260ed0e7147f7cc6da11a60208b5b9406d12a635614ffd9143;\\n\\n /**\\n * @dev Storage slot with the address of the current implementation.\\n * This is the keccak-256 hash of \\\"eip1967.proxy.implementation\\\" subtracted by 1, and is\\n * validated in the constructor.\\n */\\n bytes32 internal constant _IMPLEMENTATION_SLOT = 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc;\\n\\n /**\\n * @dev Emitted when the implementation is upgraded.\\n */\\n event Upgraded(address indexed implementation);\\n\\n /**\\n * @dev Returns the current implementation address.\\n */\\n function _getImplementation() internal view returns (address) {\\n return StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value;\\n }\\n\\n /**\\n * @dev Stores a new address in the EIP1967 implementation slot.\\n */\\n function _setImplementation(address newImplementation) private {\\n require(Address.isContract(newImplementation), \\\"ERC1967: new implementation is not a contract\\\");\\n StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value = newImplementation;\\n }\\n\\n /**\\n * @dev Perform implementation upgrade\\n *\\n * Emits an {Upgraded} event.\\n */\\n function _upgradeTo(address newImplementation) internal {\\n _setImplementation(newImplementation);\\n emit Upgraded(newImplementation);\\n }\\n\\n /**\\n * @dev Perform implementation upgrade with additional setup call.\\n *\\n * Emits an {Upgraded} event.\\n */\\n function _upgradeToAndCall(\\n address newImplementation,\\n bytes memory data,\\n bool forceCall\\n ) internal {\\n _upgradeTo(newImplementation);\\n if (data.length > 0 || forceCall) {\\n Address.functionDelegateCall(newImplementation, data);\\n }\\n }\\n\\n /**\\n * @dev Perform implementation upgrade with security checks for UUPS proxies, and additional setup call.\\n *\\n * Emits an {Upgraded} event.\\n */\\n function _upgradeToAndCallUUPS(\\n address newImplementation,\\n bytes memory data,\\n bool forceCall\\n ) internal {\\n // Upgrades from old implementations will perform a rollback test. This test requires the new\\n // implementation to upgrade back to the old, non-ERC1822 compliant, implementation. Removing\\n // this special case will break upgrade paths from old UUPS implementation to new ones.\\n if (StorageSlot.getBooleanSlot(_ROLLBACK_SLOT).value) {\\n _setImplementation(newImplementation);\\n } else {\\n try IERC1822Proxiable(newImplementation).proxiableUUID() returns (bytes32 slot) {\\n require(slot == _IMPLEMENTATION_SLOT, \\\"ERC1967Upgrade: unsupported proxiableUUID\\\");\\n } catch {\\n revert(\\\"ERC1967Upgrade: new implementation is not UUPS\\\");\\n }\\n _upgradeToAndCall(newImplementation, data, forceCall);\\n }\\n }\\n\\n /**\\n * @dev Storage slot with the admin of the contract.\\n * This is the keccak-256 hash of \\\"eip1967.proxy.admin\\\" subtracted by 1, and is\\n * validated in the constructor.\\n */\\n bytes32 internal constant _ADMIN_SLOT = 0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103;\\n\\n /**\\n * @dev Emitted when the admin account has changed.\\n */\\n event AdminChanged(address previousAdmin, address newAdmin);\\n\\n /**\\n * @dev Returns the current admin.\\n */\\n function _getAdmin() internal view returns (address) {\\n return StorageSlot.getAddressSlot(_ADMIN_SLOT).value;\\n }\\n\\n /**\\n * @dev Stores a new address in the EIP1967 admin slot.\\n */\\n function _setAdmin(address newAdmin) private {\\n require(newAdmin != address(0), \\\"ERC1967: new admin is the zero address\\\");\\n StorageSlot.getAddressSlot(_ADMIN_SLOT).value = newAdmin;\\n }\\n\\n /**\\n * @dev Changes the admin of the proxy.\\n *\\n * Emits an {AdminChanged} event.\\n */\\n function _changeAdmin(address newAdmin) internal {\\n emit AdminChanged(_getAdmin(), newAdmin);\\n _setAdmin(newAdmin);\\n }\\n\\n /**\\n * @dev The storage slot of the UpgradeableBeacon contract which defines the implementation for this proxy.\\n * This is bytes32(uint256(keccak256('eip1967.proxy.beacon')) - 1)) and is validated in the constructor.\\n */\\n bytes32 internal constant _BEACON_SLOT = 0xa3f0ad74e5423aebfd80d3ef4346578335a9a72aeaee59ff6cb3582b35133d50;\\n\\n /**\\n * @dev Emitted when the beacon is upgraded.\\n */\\n event BeaconUpgraded(address indexed beacon);\\n\\n /**\\n * @dev Returns the current beacon.\\n */\\n function _getBeacon() internal view returns (address) {\\n return StorageSlot.getAddressSlot(_BEACON_SLOT).value;\\n }\\n\\n /**\\n * @dev Stores a new beacon in the EIP1967 beacon slot.\\n */\\n function _setBeacon(address newBeacon) private {\\n require(Address.isContract(newBeacon), \\\"ERC1967: new beacon is not a contract\\\");\\n require(\\n Address.isContract(IBeacon(newBeacon).implementation()),\\n \\\"ERC1967: beacon implementation is not a contract\\\"\\n );\\n StorageSlot.getAddressSlot(_BEACON_SLOT).value = newBeacon;\\n }\\n\\n /**\\n * @dev Perform beacon upgrade with additional setup call. Note: This upgrades the address of the beacon, it does\\n * not upgrade the implementation contained in the beacon (see {UpgradeableBeacon-_setImplementation} for that).\\n *\\n * Emits a {BeaconUpgraded} event.\\n */\\n function _upgradeBeaconToAndCall(\\n address newBeacon,\\n bytes memory data,\\n bool forceCall\\n ) internal {\\n _setBeacon(newBeacon);\\n emit BeaconUpgraded(newBeacon);\\n if (data.length > 0 || forceCall) {\\n Address.functionDelegateCall(IBeacon(newBeacon).implementation(), data);\\n }\\n }\\n}\\n\",\"keccak256\":\"0xabf3f59bc0e5423eae45e459dbe92e7052c6983628d39008590edc852a62f94a\",\"license\":\"MIT\"},\"@openzeppelin/contracts/proxy/Proxy.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.6.0) (proxy/Proxy.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev This abstract contract provides a fallback function that delegates all calls to another contract using the EVM\\n * instruction `delegatecall`. We refer to the second contract as the _implementation_ behind the proxy, and it has to\\n * be specified by overriding the virtual {_implementation} function.\\n *\\n * Additionally, delegation to the implementation can be triggered manually through the {_fallback} function, or to a\\n * different contract through the {_delegate} function.\\n *\\n * The success and return data of the delegated call will be returned back to the caller of the proxy.\\n */\\nabstract contract Proxy {\\n /**\\n * @dev Delegates the current call to `implementation`.\\n *\\n * This function does not return to its internal call site, it will return directly to the external caller.\\n */\\n function _delegate(address implementation) internal virtual {\\n assembly {\\n // Copy msg.data. We take full control of memory in this inline assembly\\n // block because it will not return to Solidity code. We overwrite the\\n // Solidity scratch pad at memory position 0.\\n calldatacopy(0, 0, calldatasize())\\n\\n // Call the implementation.\\n // out and outsize are 0 because we don't know the size yet.\\n let result := delegatecall(gas(), implementation, 0, calldatasize(), 0, 0)\\n\\n // Copy the returned data.\\n returndatacopy(0, 0, returndatasize())\\n\\n switch result\\n // delegatecall returns 0 on error.\\n case 0 {\\n revert(0, returndatasize())\\n }\\n default {\\n return(0, returndatasize())\\n }\\n }\\n }\\n\\n /**\\n * @dev This is a virtual function that should be overridden so it returns the address to which the fallback function\\n * and {_fallback} should delegate.\\n */\\n function _implementation() internal view virtual returns (address);\\n\\n /**\\n * @dev Delegates the current call to the address returned by `_implementation()`.\\n *\\n * This function does not return to its internal call site, it will return directly to the external caller.\\n */\\n function _fallback() internal virtual {\\n _beforeFallback();\\n _delegate(_implementation());\\n }\\n\\n /**\\n * @dev Fallback function that delegates calls to the address returned by `_implementation()`. Will run if no other\\n * function in the contract matches the call data.\\n */\\n fallback() external payable virtual {\\n _fallback();\\n }\\n\\n /**\\n * @dev Fallback function that delegates calls to the address returned by `_implementation()`. Will run if call data\\n * is empty.\\n */\\n receive() external payable virtual {\\n _fallback();\\n }\\n\\n /**\\n * @dev Hook that is called before falling back to the implementation. Can happen as part of a manual `_fallback`\\n * call, or as part of the Solidity `fallback` or `receive` functions.\\n *\\n * If overridden should call `super._beforeFallback()`.\\n */\\n function _beforeFallback() internal virtual {}\\n}\\n\",\"keccak256\":\"0xc130fe33f1b2132158531a87734153293f6d07bc263ff4ac90e85da9c82c0e27\",\"license\":\"MIT\"},\"@openzeppelin/contracts/proxy/beacon/IBeacon.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (proxy/beacon/IBeacon.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev This is the interface that {BeaconProxy} expects of its beacon.\\n */\\ninterface IBeacon {\\n /**\\n * @dev Must return an address that can be used as a delegate call target.\\n *\\n * {BeaconProxy} will check that this address is a contract.\\n */\\n function implementation() external view returns (address);\\n}\\n\",\"keccak256\":\"0xd50a3421ac379ccb1be435fa646d66a65c986b4924f0849839f08692f39dde61\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/Address.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.7.0) (utils/Address.sol)\\n\\npragma solidity ^0.8.1;\\n\\n/**\\n * @dev Collection of functions related to the address type\\n */\\nlibrary Address {\\n /**\\n * @dev Returns true if `account` is a contract.\\n *\\n * [IMPORTANT]\\n * ====\\n * It is unsafe to assume that an address for which this function returns\\n * false is an externally-owned account (EOA) and not a contract.\\n *\\n * Among others, `isContract` will return false for the following\\n * types of addresses:\\n *\\n * - an externally-owned account\\n * - a contract in construction\\n * - an address where a contract will be created\\n * - an address where a contract lived, but was destroyed\\n * ====\\n *\\n * [IMPORTANT]\\n * ====\\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\\n *\\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\\n * constructor.\\n * ====\\n */\\n function isContract(address account) internal view returns (bool) {\\n // This method relies on extcodesize/address.code.length, which returns 0\\n // for contracts in construction, since the code is only stored at the end\\n // of the constructor execution.\\n\\n return account.code.length > 0;\\n }\\n\\n /**\\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\\n * `recipient`, forwarding all available gas and reverting on errors.\\n *\\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\\n * imposed by `transfer`, making them unable to receive funds via\\n * `transfer`. {sendValue} removes this limitation.\\n *\\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\\n *\\n * IMPORTANT: because control is transferred to `recipient`, care must be\\n * taken to not create reentrancy vulnerabilities. Consider using\\n * {ReentrancyGuard} or the\\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\\n */\\n function sendValue(address payable recipient, uint256 amount) internal {\\n require(address(this).balance >= amount, \\\"Address: insufficient balance\\\");\\n\\n (bool success, ) = recipient.call{value: amount}(\\\"\\\");\\n require(success, \\\"Address: unable to send value, recipient may have reverted\\\");\\n }\\n\\n /**\\n * @dev Performs a Solidity function call using a low level `call`. A\\n * plain `call` is an unsafe replacement for a function call: use this\\n * function instead.\\n *\\n * If `target` reverts with a revert reason, it is bubbled up by this\\n * function (like regular Solidity function calls).\\n *\\n * Returns the raw returned data. To convert to the expected return value,\\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\\n *\\n * Requirements:\\n *\\n * - `target` must be a contract.\\n * - calling `target` with `data` must not revert.\\n *\\n * _Available since v3.1._\\n */\\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\\n return functionCall(target, data, \\\"Address: low-level call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\\n * `errorMessage` as a fallback revert reason when `target` reverts.\\n *\\n * _Available since v3.1._\\n */\\n function functionCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n return functionCallWithValue(target, data, 0, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but also transferring `value` wei to `target`.\\n *\\n * Requirements:\\n *\\n * - the calling contract must have an ETH balance of at least `value`.\\n * - the called Solidity function must be `payable`.\\n *\\n * _Available since v3.1._\\n */\\n function functionCallWithValue(\\n address target,\\n bytes memory data,\\n uint256 value\\n ) internal returns (bytes memory) {\\n return functionCallWithValue(target, data, value, \\\"Address: low-level call with value failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\\n * with `errorMessage` as a fallback revert reason when `target` reverts.\\n *\\n * _Available since v3.1._\\n */\\n function functionCallWithValue(\\n address target,\\n bytes memory data,\\n uint256 value,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n require(address(this).balance >= value, \\\"Address: insufficient balance for call\\\");\\n require(isContract(target), \\\"Address: call to non-contract\\\");\\n\\n (bool success, bytes memory returndata) = target.call{value: value}(data);\\n return verifyCallResult(success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but performing a static call.\\n *\\n * _Available since v3.3._\\n */\\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\\n return functionStaticCall(target, data, \\\"Address: low-level static call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\\n * but performing a static call.\\n *\\n * _Available since v3.3._\\n */\\n function functionStaticCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal view returns (bytes memory) {\\n require(isContract(target), \\\"Address: static call to non-contract\\\");\\n\\n (bool success, bytes memory returndata) = target.staticcall(data);\\n return verifyCallResult(success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but performing a delegate call.\\n *\\n * _Available since v3.4._\\n */\\n function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {\\n return functionDelegateCall(target, data, \\\"Address: low-level delegate call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\\n * but performing a delegate call.\\n *\\n * _Available since v3.4._\\n */\\n function functionDelegateCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n require(isContract(target), \\\"Address: delegate call to non-contract\\\");\\n\\n (bool success, bytes memory returndata) = target.delegatecall(data);\\n return verifyCallResult(success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the\\n * revert reason using the provided one.\\n *\\n * _Available since v4.3._\\n */\\n function verifyCallResult(\\n bool success,\\n bytes memory returndata,\\n string memory errorMessage\\n ) internal pure returns (bytes memory) {\\n if (success) {\\n return returndata;\\n } else {\\n // Look for revert reason and bubble it up if present\\n if (returndata.length > 0) {\\n // The easiest way to bubble the revert reason is using memory via assembly\\n /// @solidity memory-safe-assembly\\n assembly {\\n let returndata_size := mload(returndata)\\n revert(add(32, returndata), returndata_size)\\n }\\n } else {\\n revert(errorMessage);\\n }\\n }\\n }\\n}\\n\",\"keccak256\":\"0xd6153ce99bcdcce22b124f755e72553295be6abcd63804cfdffceb188b8bef10\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/StorageSlot.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.7.0) (utils/StorageSlot.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Library for reading and writing primitive types to specific storage slots.\\n *\\n * Storage slots are often used to avoid storage conflict when dealing with upgradeable contracts.\\n * This library helps with reading and writing to such slots without the need for inline assembly.\\n *\\n * The functions in this library return Slot structs that contain a `value` member that can be used to read or write.\\n *\\n * Example usage to set ERC1967 implementation slot:\\n * ```\\n * contract ERC1967 {\\n * bytes32 internal constant _IMPLEMENTATION_SLOT = 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc;\\n *\\n * function _getImplementation() internal view returns (address) {\\n * return StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value;\\n * }\\n *\\n * function _setImplementation(address newImplementation) internal {\\n * require(Address.isContract(newImplementation), \\\"ERC1967: new implementation is not a contract\\\");\\n * StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value = newImplementation;\\n * }\\n * }\\n * ```\\n *\\n * _Available since v4.1 for `address`, `bool`, `bytes32`, and `uint256`._\\n */\\nlibrary StorageSlot {\\n struct AddressSlot {\\n address value;\\n }\\n\\n struct BooleanSlot {\\n bool value;\\n }\\n\\n struct Bytes32Slot {\\n bytes32 value;\\n }\\n\\n struct Uint256Slot {\\n uint256 value;\\n }\\n\\n /**\\n * @dev Returns an `AddressSlot` with member `value` located at `slot`.\\n */\\n function getAddressSlot(bytes32 slot) internal pure returns (AddressSlot storage r) {\\n /// @solidity memory-safe-assembly\\n assembly {\\n r.slot := slot\\n }\\n }\\n\\n /**\\n * @dev Returns an `BooleanSlot` with member `value` located at `slot`.\\n */\\n function getBooleanSlot(bytes32 slot) internal pure returns (BooleanSlot storage r) {\\n /// @solidity memory-safe-assembly\\n assembly {\\n r.slot := slot\\n }\\n }\\n\\n /**\\n * @dev Returns an `Bytes32Slot` with member `value` located at `slot`.\\n */\\n function getBytes32Slot(bytes32 slot) internal pure returns (Bytes32Slot storage r) {\\n /// @solidity memory-safe-assembly\\n assembly {\\n r.slot := slot\\n }\\n }\\n\\n /**\\n * @dev Returns an `Uint256Slot` with member `value` located at `slot`.\\n */\\n function getUint256Slot(bytes32 slot) internal pure returns (Uint256Slot storage r) {\\n /// @solidity memory-safe-assembly\\n assembly {\\n r.slot := slot\\n }\\n }\\n}\\n\",\"keccak256\":\"0xd5c50c54bf02740ebd122ff06832546cb5fa84486d52695a9ccfd11666e0c81d\",\"license\":\"MIT\"},\"contracts/external/TransparentUpgradeableProxy.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-3.0\\n\\npragma solidity ^0.8.12;\\n\\nimport \\\"@openzeppelin/contracts/proxy/ERC1967/ERC1967Proxy.sol\\\";\\n\\n/**\\n * @dev This contract implements a proxy that is upgradeable by an admin. It is fully forked from OpenZeppelin\\n * `TransparentUpgradeableProxy`\\n *\\n * To avoid https://medium.com/nomic-labs-blog/malicious-backdoors-in-ethereum-proxies-62629adf3357[proxy selector\\n * clashing], which can potentially be used in an attack, this contract uses the\\n * https://blog.openzeppelin.com/the-transparent-proxy-pattern/[transparent proxy pattern]. This pattern implies two\\n * things that go hand in hand:\\n *\\n * 1. If any account other than the admin calls the proxy, the call will be forwarded to the implementation, even if\\n * that call matches one of the admin functions exposed by the proxy itself.\\n * 2. If the admin calls the proxy, it can access the admin functions, but its calls will never be forwarded to the\\n * implementation. If the admin tries to call a function on the implementation it will fail with an error that says\\n * \\\"admin cannot fallback to proxy target\\\".\\n *\\n * These properties mean that the admin account can only be used for admin actions like upgrading the proxy or changing\\n * the admin, so it's best if it's a dedicated account that is not used for anything else. This will avoid headaches due\\n * to sudden errors when trying to call a function from the proxy implementation.\\n *\\n * Our recommendation is for the dedicated account to be an instance of the {ProxyAdmin} contract. If set up this way,\\n * you should think of the `ProxyAdmin` instance as the real administrative interface of your proxy.\\n */\\ncontract TransparentUpgradeableProxy is ERC1967Proxy {\\n /**\\n * @dev Initializes an upgradeable proxy managed by `_admin`, backed by the implementation at `_logic`, and\\n * optionally initialized with `_data` as explained in {ERC1967Proxy-constructor}.\\n */\\n constructor(address _logic, address admin_, bytes memory _data) payable ERC1967Proxy(_logic, _data) {\\n assert(_ADMIN_SLOT == bytes32(uint256(keccak256(\\\"eip1967.proxy.admin\\\")) - 1));\\n _changeAdmin(admin_);\\n }\\n\\n /**\\n * @dev Modifier used internally that will delegate the call to the implementation unless the sender is the admin.\\n */\\n modifier ifAdmin() {\\n if (msg.sender == _getAdmin()) {\\n _;\\n } else {\\n _fallback();\\n }\\n }\\n\\n /**\\n * @dev Returns the current admin.\\n *\\n * NOTE: Only the admin can call this function. See {ProxyAdmin-getProxyAdmin}.\\n *\\n * TIP: To get this value clients can read directly from the storage slot shown below (specified by EIP1967) using the\\n * https://eth.wiki/json-rpc/API#eth_getstorageat[`eth_getStorageAt`] RPC call.\\n * `0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103`\\n */\\n function admin() external ifAdmin returns (address admin_) {\\n admin_ = _getAdmin();\\n }\\n\\n /**\\n * @dev Returns the current implementation.\\n *\\n * NOTE: Only the admin can call this function. See {ProxyAdmin-getProxyImplementation}.\\n *\\n * TIP: To get this value clients can read directly from the storage slot shown below (specified by EIP1967) using the\\n * https://eth.wiki/json-rpc/API#eth_getstorageat[`eth_getStorageAt`] RPC call.\\n * `0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc`\\n */\\n function implementation() external ifAdmin returns (address implementation_) {\\n implementation_ = _implementation();\\n }\\n\\n /**\\n * @dev Changes the admin of the proxy.\\n *\\n * Emits an {AdminChanged} event.\\n *\\n * NOTE: Only the admin can call this function. See {ProxyAdmin-changeProxyAdmin}.\\n */\\n function changeAdmin(address newAdmin) external virtual ifAdmin {\\n _changeAdmin(newAdmin);\\n }\\n\\n /**\\n * @dev Upgrade the implementation of the proxy.\\n *\\n * NOTE: Only the admin can call this function. See {ProxyAdmin-upgrade}.\\n */\\n function upgradeTo(address newImplementation) external ifAdmin {\\n _upgradeToAndCall(newImplementation, bytes(\\\"\\\"), false);\\n }\\n\\n /**\\n * @dev Upgrade the implementation of the proxy, and then call a function from the new implementation as specified\\n * by `data`, which should be an encoded function call. This is useful to initialize new storage variables in the\\n * proxied contract.\\n *\\n * NOTE: Only the admin can call this function. See {ProxyAdmin-upgradeAndCall}.\\n */\\n function upgradeToAndCall(address newImplementation, bytes calldata data) external payable ifAdmin {\\n _upgradeToAndCall(newImplementation, data, true);\\n }\\n\\n /**\\n * @dev Returns the current admin.\\n */\\n function _admin() internal view virtual returns (address) {\\n return _getAdmin();\\n }\\n\\n /**\\n * @dev Makes sure the admin cannot access the fallback function. See {Proxy-_beforeFallback}.\\n */\\n function _beforeFallback() internal virtual override {\\n require(msg.sender != _getAdmin(), \\\"TransparentUpgradeableProxy: admin cannot fallback to proxy target\\\");\\n super._beforeFallback();\\n }\\n}\\n\",\"keccak256\":\"0x93a67a0f612ea3ff2a76315e138a6a88267270a1379d3cc7be52845fbbe611e2\",\"license\":\"GPL-3.0\"}},\"version\":1}", + "bytecode": "0x6080604052604051620010bb380380620010bb8339810160408190526200002691620004d8565b828162000036828260006200009a565b5062000066905060017fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6104620005b8565b6000805160206200107483398151915214620000865762000086620005da565b6200009182620000d7565b50505062000643565b620000a58362000132565b600082511180620000b35750805b15620000d257620000d083836200017460201b6200028c1760201c565b505b505050565b7f7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f62000102620001a5565b604080516001600160a01b03928316815291841660208301520160405180910390a16200012f81620001de565b50565b6200013d8162000293565b6040516001600160a01b038216907fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b90600090a250565b60606200019c8383604051806060016040528060278152602001620010946027913962000347565b90505b92915050565b6000620001cf6000805160206200107483398151915260001b6200042f60201b6200022e1760201c565b546001600160a01b0316919050565b6001600160a01b038116620002495760405162461bcd60e51b815260206004820152602660248201527f455243313936373a206e65772061646d696e20697320746865207a65726f206160448201526564647265737360d01b60648201526084015b60405180910390fd5b80620002726000805160206200107483398151915260001b6200042f60201b6200022e1760201c565b80546001600160a01b0319166001600160a01b039290921691909117905550565b620002a9816200043260201b620002b81760201c565b6200030d5760405162461bcd60e51b815260206004820152602d60248201527f455243313936373a206e657720696d706c656d656e746174696f6e206973206e60448201526c1bdd08184818dbdb9d1c9858dd609a1b606482015260840162000240565b80620002727f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc60001b6200042f60201b6200022e1760201c565b60606001600160a01b0384163b620003b15760405162461bcd60e51b815260206004820152602660248201527f416464726573733a2064656c65676174652063616c6c20746f206e6f6e2d636f6044820152651b9d1c9858dd60d21b606482015260840162000240565b600080856001600160a01b031685604051620003ce9190620005f0565b600060405180830381855af49150503d80600081146200040b576040519150601f19603f3d011682016040523d82523d6000602084013e62000410565b606091505b5090925090506200042382828662000441565b925050505b9392505050565b90565b6001600160a01b03163b151590565b606083156200045257508162000428565b825115620004635782518084602001fd5b8160405162461bcd60e51b81526004016200024091906200060e565b80516001600160a01b03811681146200049757600080fd5b919050565b634e487b7160e01b600052604160045260246000fd5b60005b83811015620004cf578181015183820152602001620004b5565b50506000910152565b600080600060608486031215620004ee57600080fd5b620004f9846200047f565b925062000509602085016200047f565b60408501519092506001600160401b03808211156200052757600080fd5b818601915086601f8301126200053c57600080fd5b8151818111156200055157620005516200049c565b604051601f8201601f19908116603f011681019083821181831017156200057c576200057c6200049c565b816040528281528960208487010111156200059657600080fd5b620005a9836020830160208801620004b2565b80955050505050509250925092565b818103818111156200019f57634e487b7160e01b600052601160045260246000fd5b634e487b7160e01b600052600160045260246000fd5b6000825162000604818460208701620004b2565b9190910192915050565b60208152600082518060208401526200062f816040850160208701620004b2565b601f01601f19169190910160400192915050565b610a2180620006536000396000f3fe60806040526004361061005e5760003560e01c80635c60da1b116100435780635c60da1b146100a85780638f283970146100e6578063f851a440146101065761006d565b80633659cfe6146100755780634f1ef286146100955761006d565b3661006d5761006b61011b565b005b61006b61011b565b34801561008157600080fd5b5061006b610090366004610895565b610135565b61006b6100a33660046108b0565b61017f565b3480156100b457600080fd5b506100bd6101f3565b60405173ffffffffffffffffffffffffffffffffffffffff909116815260200160405180910390f35b3480156100f257600080fd5b5061006b610101366004610895565b610231565b34801561011257600080fd5b506100bd61025e565b6101236102d4565b61013361012e6103ab565b6103b5565b565b61013d6103d9565b73ffffffffffffffffffffffffffffffffffffffff1633036101775761017481604051806020016040528060008152506000610419565b50565b61017461011b565b6101876103d9565b73ffffffffffffffffffffffffffffffffffffffff1633036101eb576101e68383838080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525060019250610419915050565b505050565b6101e661011b565b60006101fd6103d9565b73ffffffffffffffffffffffffffffffffffffffff163303610226576102216103ab565b905090565b61022e61011b565b90565b6102396103d9565b73ffffffffffffffffffffffffffffffffffffffff1633036101775761017481610444565b60006102686103d9565b73ffffffffffffffffffffffffffffffffffffffff163303610226576102216103d9565b60606102b183836040518060600160405280602781526020016109c5602791396104a5565b9392505050565b73ffffffffffffffffffffffffffffffffffffffff163b151590565b6102dc6103d9565b73ffffffffffffffffffffffffffffffffffffffff163303610133576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604260248201527f5472616e73706172656e745570677261646561626c6550726f78793a2061646d60448201527f696e2063616e6e6f742066616c6c6261636b20746f2070726f7879207461726760648201527f6574000000000000000000000000000000000000000000000000000000000000608482015260a4015b60405180910390fd5b60006102216105cd565b3660008037600080366000845af43d6000803e8080156103d4573d6000f35b3d6000fd5b60007fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035b5473ffffffffffffffffffffffffffffffffffffffff16919050565b610422836105f5565b60008251118061042f5750805b156101e65761043e838361028c565b50505050565b7f7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f61046d6103d9565b6040805173ffffffffffffffffffffffffffffffffffffffff928316815291841660208301520160405180910390a161017481610642565b606073ffffffffffffffffffffffffffffffffffffffff84163b61054b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f416464726573733a2064656c65676174652063616c6c20746f206e6f6e2d636f60448201527f6e7472616374000000000000000000000000000000000000000000000000000060648201526084016103a2565b6000808573ffffffffffffffffffffffffffffffffffffffff16856040516105739190610957565b600060405180830381855af49150503d80600081146105ae576040519150601f19603f3d011682016040523d82523d6000602084013e6105b3565b606091505b50915091506105c382828661074e565b9695505050505050565b60007f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc6103fd565b6105fe816107a1565b60405173ffffffffffffffffffffffffffffffffffffffff8216907fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b90600090a250565b73ffffffffffffffffffffffffffffffffffffffff81166106e5576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f455243313936373a206e65772061646d696e20697320746865207a65726f206160448201527f646472657373000000000000000000000000000000000000000000000000000060648201526084016103a2565b807fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035b80547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff9290921691909117905550565b6060831561075d5750816102b1565b82511561076d5782518084602001fd5b816040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016103a29190610973565b73ffffffffffffffffffffffffffffffffffffffff81163b610845576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602d60248201527f455243313936373a206e657720696d706c656d656e746174696f6e206973206e60448201527f6f74206120636f6e74726163740000000000000000000000000000000000000060648201526084016103a2565b807f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc610708565b803573ffffffffffffffffffffffffffffffffffffffff8116811461089057600080fd5b919050565b6000602082840312156108a757600080fd5b6102b18261086c565b6000806000604084860312156108c557600080fd5b6108ce8461086c565b9250602084013567ffffffffffffffff808211156108eb57600080fd5b818601915086601f8301126108ff57600080fd5b81358181111561090e57600080fd5b87602082850101111561092057600080fd5b6020830194508093505050509250925092565b60005b8381101561094e578181015183820152602001610936565b50506000910152565b60008251610969818460208701610933565b9190910192915050565b6020815260008251806020840152610992816040850160208701610933565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016919091016040019291505056fe416464726573733a206c6f772d6c6576656c2064656c65676174652063616c6c206661696c6564a2646970667358221220e96638b07fb1675d93a95c49e417bc8111448b23a59918698cdcd8fd488dd7cf64736f6c63430008110033b53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103416464726573733a206c6f772d6c6576656c2064656c65676174652063616c6c206661696c6564", + "deployedBytecode": "0x60806040526004361061005e5760003560e01c80635c60da1b116100435780635c60da1b146100a85780638f283970146100e6578063f851a440146101065761006d565b80633659cfe6146100755780634f1ef286146100955761006d565b3661006d5761006b61011b565b005b61006b61011b565b34801561008157600080fd5b5061006b610090366004610895565b610135565b61006b6100a33660046108b0565b61017f565b3480156100b457600080fd5b506100bd6101f3565b60405173ffffffffffffffffffffffffffffffffffffffff909116815260200160405180910390f35b3480156100f257600080fd5b5061006b610101366004610895565b610231565b34801561011257600080fd5b506100bd61025e565b6101236102d4565b61013361012e6103ab565b6103b5565b565b61013d6103d9565b73ffffffffffffffffffffffffffffffffffffffff1633036101775761017481604051806020016040528060008152506000610419565b50565b61017461011b565b6101876103d9565b73ffffffffffffffffffffffffffffffffffffffff1633036101eb576101e68383838080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525060019250610419915050565b505050565b6101e661011b565b60006101fd6103d9565b73ffffffffffffffffffffffffffffffffffffffff163303610226576102216103ab565b905090565b61022e61011b565b90565b6102396103d9565b73ffffffffffffffffffffffffffffffffffffffff1633036101775761017481610444565b60006102686103d9565b73ffffffffffffffffffffffffffffffffffffffff163303610226576102216103d9565b60606102b183836040518060600160405280602781526020016109c5602791396104a5565b9392505050565b73ffffffffffffffffffffffffffffffffffffffff163b151590565b6102dc6103d9565b73ffffffffffffffffffffffffffffffffffffffff163303610133576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604260248201527f5472616e73706172656e745570677261646561626c6550726f78793a2061646d60448201527f696e2063616e6e6f742066616c6c6261636b20746f2070726f7879207461726760648201527f6574000000000000000000000000000000000000000000000000000000000000608482015260a4015b60405180910390fd5b60006102216105cd565b3660008037600080366000845af43d6000803e8080156103d4573d6000f35b3d6000fd5b60007fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035b5473ffffffffffffffffffffffffffffffffffffffff16919050565b610422836105f5565b60008251118061042f5750805b156101e65761043e838361028c565b50505050565b7f7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f61046d6103d9565b6040805173ffffffffffffffffffffffffffffffffffffffff928316815291841660208301520160405180910390a161017481610642565b606073ffffffffffffffffffffffffffffffffffffffff84163b61054b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f416464726573733a2064656c65676174652063616c6c20746f206e6f6e2d636f60448201527f6e7472616374000000000000000000000000000000000000000000000000000060648201526084016103a2565b6000808573ffffffffffffffffffffffffffffffffffffffff16856040516105739190610957565b600060405180830381855af49150503d80600081146105ae576040519150601f19603f3d011682016040523d82523d6000602084013e6105b3565b606091505b50915091506105c382828661074e565b9695505050505050565b60007f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc6103fd565b6105fe816107a1565b60405173ffffffffffffffffffffffffffffffffffffffff8216907fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b90600090a250565b73ffffffffffffffffffffffffffffffffffffffff81166106e5576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f455243313936373a206e65772061646d696e20697320746865207a65726f206160448201527f646472657373000000000000000000000000000000000000000000000000000060648201526084016103a2565b807fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035b80547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff9290921691909117905550565b6060831561075d5750816102b1565b82511561076d5782518084602001fd5b816040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016103a29190610973565b73ffffffffffffffffffffffffffffffffffffffff81163b610845576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602d60248201527f455243313936373a206e657720696d706c656d656e746174696f6e206973206e60448201527f6f74206120636f6e74726163740000000000000000000000000000000000000060648201526084016103a2565b807f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc610708565b803573ffffffffffffffffffffffffffffffffffffffff8116811461089057600080fd5b919050565b6000602082840312156108a757600080fd5b6102b18261086c565b6000806000604084860312156108c557600080fd5b6108ce8461086c565b9250602084013567ffffffffffffffff808211156108eb57600080fd5b818601915086601f8301126108ff57600080fd5b81358181111561090e57600080fd5b87602082850101111561092057600080fd5b6020830194508093505050509250925092565b60005b8381101561094e578181015183820152602001610936565b50506000910152565b60008251610969818460208701610933565b9190910192915050565b6020815260008251806020840152610992816040850160208701610933565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016919091016040019291505056fe416464726573733a206c6f772d6c6576656c2064656c65676174652063616c6c206661696c6564a2646970667358221220e96638b07fb1675d93a95c49e417bc8111448b23a59918698cdcd8fd488dd7cf64736f6c63430008110033", + "devdoc": { + "details": "This contract implements a proxy that is upgradeable by an admin. It is fully forked from OpenZeppelin `TransparentUpgradeableProxy` To avoid https://medium.com/nomic-labs-blog/malicious-backdoors-in-ethereum-proxies-62629adf3357[proxy selector clashing], which can potentially be used in an attack, this contract uses the https://blog.openzeppelin.com/the-transparent-proxy-pattern/[transparent proxy pattern]. This pattern implies two things that go hand in hand: 1. If any account other than the admin calls the proxy, the call will be forwarded to the implementation, even if that call matches one of the admin functions exposed by the proxy itself. 2. If the admin calls the proxy, it can access the admin functions, but its calls will never be forwarded to the implementation. If the admin tries to call a function on the implementation it will fail with an error that says \"admin cannot fallback to proxy target\". These properties mean that the admin account can only be used for admin actions like upgrading the proxy or changing the admin, so it's best if it's a dedicated account that is not used for anything else. This will avoid headaches due to sudden errors when trying to call a function from the proxy implementation. Our recommendation is for the dedicated account to be an instance of the {ProxyAdmin} contract. If set up this way, you should think of the `ProxyAdmin` instance as the real administrative interface of your proxy.", + "kind": "dev", + "methods": { + "admin()": { + "details": "Returns the current admin. NOTE: Only the admin can call this function. See {ProxyAdmin-getProxyAdmin}. TIP: To get this value clients can read directly from the storage slot shown below (specified by EIP1967) using the https://eth.wiki/json-rpc/API#eth_getstorageat[`eth_getStorageAt`] RPC call. `0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103`" + }, + "changeAdmin(address)": { + "details": "Changes the admin of the proxy. Emits an {AdminChanged} event. NOTE: Only the admin can call this function. See {ProxyAdmin-changeProxyAdmin}." + }, + "constructor": { + "details": "Initializes an upgradeable proxy managed by `_admin`, backed by the implementation at `_logic`, and optionally initialized with `_data` as explained in {ERC1967Proxy-constructor}." + }, + "implementation()": { + "details": "Returns the current implementation. NOTE: Only the admin can call this function. See {ProxyAdmin-getProxyImplementation}. TIP: To get this value clients can read directly from the storage slot shown below (specified by EIP1967) using the https://eth.wiki/json-rpc/API#eth_getstorageat[`eth_getStorageAt`] RPC call. `0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc`" + }, + "upgradeTo(address)": { + "details": "Upgrade the implementation of the proxy. NOTE: Only the admin can call this function. See {ProxyAdmin-upgrade}." + }, + "upgradeToAndCall(address,bytes)": { + "details": "Upgrade the implementation of the proxy, and then call a function from the new implementation as specified by `data`, which should be an encoded function call. This is useful to initialize new storage variables in the proxied contract. NOTE: Only the admin can call this function. See {ProxyAdmin-upgradeAndCall}." + } + }, + "version": 1 + }, + "userdoc": { + "kind": "user", + "methods": {}, + "version": 1 + }, + "storageLayout": { + "storage": [], + "types": null + } +} \ No newline at end of file diff --git a/deployments/bsc/solcInputs/871924e0c138825a2736b76def8fef8d.json b/deployments/bsc/solcInputs/871924e0c138825a2736b76def8fef8d.json new file mode 100644 index 00000000..57454028 --- /dev/null +++ b/deployments/bsc/solcInputs/871924e0c138825a2736b76def8fef8d.json @@ -0,0 +1,562 @@ +{ + "language": "Solidity", + "sources": { + "@chainlink/contracts/src/v0.8/interfaces/AggregatorV3Interface.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.0;\n\ninterface AggregatorV3Interface {\n\n function decimals()\n external\n view\n returns (\n uint8\n );\n\n function description()\n external\n view\n returns (\n string memory\n );\n\n function version()\n external\n view\n returns (\n uint256\n );\n\n // getRoundData and latestRoundData should both raise \"No data present\"\n // if they do not have data to report, instead of returning unset values\n // which could be misinterpreted as actual reported values.\n function getRoundData(\n uint80 _roundId\n )\n external\n view\n returns (\n uint80 roundId,\n int256 answer,\n uint256 startedAt,\n uint256 updatedAt,\n uint80 answeredInRound\n );\n\n function latestRoundData()\n external\n view\n returns (\n uint80 roundId,\n int256 answer,\n uint256 startedAt,\n uint256 updatedAt,\n uint80 answeredInRound\n );\n\n}\n" + }, + "@openzeppelin/contracts-upgradeable/access/AccessControlEnumerableUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.5.0) (access/AccessControlEnumerable.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./IAccessControlEnumerableUpgradeable.sol\";\nimport \"./AccessControlUpgradeable.sol\";\nimport \"../utils/structs/EnumerableSetUpgradeable.sol\";\nimport \"../proxy/utils/Initializable.sol\";\n\n/**\n * @dev Extension of {AccessControl} that allows enumerating the members of each role.\n */\nabstract contract AccessControlEnumerableUpgradeable is Initializable, IAccessControlEnumerableUpgradeable, AccessControlUpgradeable {\n function __AccessControlEnumerable_init() internal onlyInitializing {\n }\n\n function __AccessControlEnumerable_init_unchained() internal onlyInitializing {\n }\n using EnumerableSetUpgradeable for EnumerableSetUpgradeable.AddressSet;\n\n mapping(bytes32 => EnumerableSetUpgradeable.AddressSet) private _roleMembers;\n\n /**\n * @dev See {IERC165-supportsInterface}.\n */\n function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {\n return interfaceId == type(IAccessControlEnumerableUpgradeable).interfaceId || super.supportsInterface(interfaceId);\n }\n\n /**\n * @dev Returns one of the accounts that have `role`. `index` must be a\n * value between 0 and {getRoleMemberCount}, non-inclusive.\n *\n * Role bearers are not sorted in any particular way, and their ordering may\n * change at any point.\n *\n * WARNING: When using {getRoleMember} and {getRoleMemberCount}, make sure\n * you perform all queries on the same block. See the following\n * https://forum.openzeppelin.com/t/iterating-over-elements-on-enumerableset-in-openzeppelin-contracts/2296[forum post]\n * for more information.\n */\n function getRoleMember(bytes32 role, uint256 index) public view virtual override returns (address) {\n return _roleMembers[role].at(index);\n }\n\n /**\n * @dev Returns the number of accounts that have `role`. Can be used\n * together with {getRoleMember} to enumerate all bearers of a role.\n */\n function getRoleMemberCount(bytes32 role) public view virtual override returns (uint256) {\n return _roleMembers[role].length();\n }\n\n /**\n * @dev Overload {_grantRole} to track enumerable memberships\n */\n function _grantRole(bytes32 role, address account) internal virtual override {\n super._grantRole(role, account);\n _roleMembers[role].add(account);\n }\n\n /**\n * @dev Overload {_revokeRole} to track enumerable memberships\n */\n function _revokeRole(bytes32 role, address account) internal virtual override {\n super._revokeRole(role, account);\n _roleMembers[role].remove(account);\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[49] private __gap;\n}\n" + }, + "@openzeppelin/contracts-upgradeable/access/AccessControlUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (access/AccessControl.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./IAccessControlUpgradeable.sol\";\nimport \"../utils/ContextUpgradeable.sol\";\nimport \"../utils/StringsUpgradeable.sol\";\nimport \"../utils/introspection/ERC165Upgradeable.sol\";\nimport \"../proxy/utils/Initializable.sol\";\n\n/**\n * @dev Contract module that allows children to implement role-based access\n * control mechanisms. This is a lightweight version that doesn't allow enumerating role\n * members except through off-chain means by accessing the contract event logs. Some\n * applications may benefit from on-chain enumerability, for those cases see\n * {AccessControlEnumerable}.\n *\n * Roles are referred to by their `bytes32` identifier. These should be exposed\n * in the external API and be unique. The best way to achieve this is by\n * using `public constant` hash digests:\n *\n * ```\n * bytes32 public constant MY_ROLE = keccak256(\"MY_ROLE\");\n * ```\n *\n * Roles can be used to represent a set of permissions. To restrict access to a\n * function call, use {hasRole}:\n *\n * ```\n * function foo() public {\n * require(hasRole(MY_ROLE, msg.sender));\n * ...\n * }\n * ```\n *\n * Roles can be granted and revoked dynamically via the {grantRole} and\n * {revokeRole} functions. Each role has an associated admin role, and only\n * accounts that have a role's admin role can call {grantRole} and {revokeRole}.\n *\n * By default, the admin role for all roles is `DEFAULT_ADMIN_ROLE`, which means\n * that only accounts with this role will be able to grant or revoke other\n * roles. More complex role relationships can be created by using\n * {_setRoleAdmin}.\n *\n * WARNING: The `DEFAULT_ADMIN_ROLE` is also its own admin: it has permission to\n * grant and revoke this role. Extra precautions should be taken to secure\n * accounts that have been granted it.\n */\nabstract contract AccessControlUpgradeable is Initializable, ContextUpgradeable, IAccessControlUpgradeable, ERC165Upgradeable {\n function __AccessControl_init() internal onlyInitializing {\n }\n\n function __AccessControl_init_unchained() internal onlyInitializing {\n }\n struct RoleData {\n mapping(address => bool) members;\n bytes32 adminRole;\n }\n\n mapping(bytes32 => RoleData) private _roles;\n\n bytes32 public constant DEFAULT_ADMIN_ROLE = 0x00;\n\n /**\n * @dev Modifier that checks that an account has a specific role. Reverts\n * with a standardized message including the required role.\n *\n * The format of the revert reason is given by the following regular expression:\n *\n * /^AccessControl: account (0x[0-9a-f]{40}) is missing role (0x[0-9a-f]{64})$/\n *\n * _Available since v4.1._\n */\n modifier onlyRole(bytes32 role) {\n _checkRole(role);\n _;\n }\n\n /**\n * @dev See {IERC165-supportsInterface}.\n */\n function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {\n return interfaceId == type(IAccessControlUpgradeable).interfaceId || super.supportsInterface(interfaceId);\n }\n\n /**\n * @dev Returns `true` if `account` has been granted `role`.\n */\n function hasRole(bytes32 role, address account) public view virtual override returns (bool) {\n return _roles[role].members[account];\n }\n\n /**\n * @dev Revert with a standard message if `_msgSender()` is missing `role`.\n * Overriding this function changes the behavior of the {onlyRole} modifier.\n *\n * Format of the revert message is described in {_checkRole}.\n *\n * _Available since v4.6._\n */\n function _checkRole(bytes32 role) internal view virtual {\n _checkRole(role, _msgSender());\n }\n\n /**\n * @dev Revert with a standard message if `account` is missing `role`.\n *\n * The format of the revert reason is given by the following regular expression:\n *\n * /^AccessControl: account (0x[0-9a-f]{40}) is missing role (0x[0-9a-f]{64})$/\n */\n function _checkRole(bytes32 role, address account) internal view virtual {\n if (!hasRole(role, account)) {\n revert(\n string(\n abi.encodePacked(\n \"AccessControl: account \",\n StringsUpgradeable.toHexString(uint160(account), 20),\n \" is missing role \",\n StringsUpgradeable.toHexString(uint256(role), 32)\n )\n )\n );\n }\n }\n\n /**\n * @dev Returns the admin role that controls `role`. See {grantRole} and\n * {revokeRole}.\n *\n * To change a role's admin, use {_setRoleAdmin}.\n */\n function getRoleAdmin(bytes32 role) public view virtual override returns (bytes32) {\n return _roles[role].adminRole;\n }\n\n /**\n * @dev Grants `role` to `account`.\n *\n * If `account` had not been already granted `role`, emits a {RoleGranted}\n * event.\n *\n * Requirements:\n *\n * - the caller must have ``role``'s admin role.\n *\n * May emit a {RoleGranted} event.\n */\n function grantRole(bytes32 role, address account) public virtual override onlyRole(getRoleAdmin(role)) {\n _grantRole(role, account);\n }\n\n /**\n * @dev Revokes `role` from `account`.\n *\n * If `account` had been granted `role`, emits a {RoleRevoked} event.\n *\n * Requirements:\n *\n * - the caller must have ``role``'s admin role.\n *\n * May emit a {RoleRevoked} event.\n */\n function revokeRole(bytes32 role, address account) public virtual override onlyRole(getRoleAdmin(role)) {\n _revokeRole(role, account);\n }\n\n /**\n * @dev Revokes `role` from the calling account.\n *\n * Roles are often managed via {grantRole} and {revokeRole}: this function's\n * purpose is to provide a mechanism for accounts to lose their privileges\n * if they are compromised (such as when a trusted device is misplaced).\n *\n * If the calling account had been revoked `role`, emits a {RoleRevoked}\n * event.\n *\n * Requirements:\n *\n * - the caller must be `account`.\n *\n * May emit a {RoleRevoked} event.\n */\n function renounceRole(bytes32 role, address account) public virtual override {\n require(account == _msgSender(), \"AccessControl: can only renounce roles for self\");\n\n _revokeRole(role, account);\n }\n\n /**\n * @dev Grants `role` to `account`.\n *\n * If `account` had not been already granted `role`, emits a {RoleGranted}\n * event. Note that unlike {grantRole}, this function doesn't perform any\n * checks on the calling account.\n *\n * May emit a {RoleGranted} event.\n *\n * [WARNING]\n * ====\n * This function should only be called from the constructor when setting\n * up the initial roles for the system.\n *\n * Using this function in any other way is effectively circumventing the admin\n * system imposed by {AccessControl}.\n * ====\n *\n * NOTE: This function is deprecated in favor of {_grantRole}.\n */\n function _setupRole(bytes32 role, address account) internal virtual {\n _grantRole(role, account);\n }\n\n /**\n * @dev Sets `adminRole` as ``role``'s admin role.\n *\n * Emits a {RoleAdminChanged} event.\n */\n function _setRoleAdmin(bytes32 role, bytes32 adminRole) internal virtual {\n bytes32 previousAdminRole = getRoleAdmin(role);\n _roles[role].adminRole = adminRole;\n emit RoleAdminChanged(role, previousAdminRole, adminRole);\n }\n\n /**\n * @dev Grants `role` to `account`.\n *\n * Internal function without access restriction.\n *\n * May emit a {RoleGranted} event.\n */\n function _grantRole(bytes32 role, address account) internal virtual {\n if (!hasRole(role, account)) {\n _roles[role].members[account] = true;\n emit RoleGranted(role, account, _msgSender());\n }\n }\n\n /**\n * @dev Revokes `role` from `account`.\n *\n * Internal function without access restriction.\n *\n * May emit a {RoleRevoked} event.\n */\n function _revokeRole(bytes32 role, address account) internal virtual {\n if (hasRole(role, account)) {\n _roles[role].members[account] = false;\n emit RoleRevoked(role, account, _msgSender());\n }\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[49] private __gap;\n}\n" + }, + "@openzeppelin/contracts-upgradeable/access/IAccessControlEnumerableUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (access/IAccessControlEnumerable.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./IAccessControlUpgradeable.sol\";\n\n/**\n * @dev External interface of AccessControlEnumerable declared to support ERC165 detection.\n */\ninterface IAccessControlEnumerableUpgradeable is IAccessControlUpgradeable {\n /**\n * @dev Returns one of the accounts that have `role`. `index` must be a\n * value between 0 and {getRoleMemberCount}, non-inclusive.\n *\n * Role bearers are not sorted in any particular way, and their ordering may\n * change at any point.\n *\n * WARNING: When using {getRoleMember} and {getRoleMemberCount}, make sure\n * you perform all queries on the same block. See the following\n * https://forum.openzeppelin.com/t/iterating-over-elements-on-enumerableset-in-openzeppelin-contracts/2296[forum post]\n * for more information.\n */\n function getRoleMember(bytes32 role, uint256 index) external view returns (address);\n\n /**\n * @dev Returns the number of accounts that have `role`. Can be used\n * together with {getRoleMember} to enumerate all bearers of a role.\n */\n function getRoleMemberCount(bytes32 role) external view returns (uint256);\n}\n" + }, + "@openzeppelin/contracts-upgradeable/access/IAccessControlUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (access/IAccessControl.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev External interface of AccessControl declared to support ERC165 detection.\n */\ninterface IAccessControlUpgradeable {\n /**\n * @dev Emitted when `newAdminRole` is set as ``role``'s admin role, replacing `previousAdminRole`\n *\n * `DEFAULT_ADMIN_ROLE` is the starting admin for all roles, despite\n * {RoleAdminChanged} not being emitted signaling this.\n *\n * _Available since v3.1._\n */\n event RoleAdminChanged(bytes32 indexed role, bytes32 indexed previousAdminRole, bytes32 indexed newAdminRole);\n\n /**\n * @dev Emitted when `account` is granted `role`.\n *\n * `sender` is the account that originated the contract call, an admin role\n * bearer except when using {AccessControl-_setupRole}.\n */\n event RoleGranted(bytes32 indexed role, address indexed account, address indexed sender);\n\n /**\n * @dev Emitted when `account` is revoked `role`.\n *\n * `sender` is the account that originated the contract call:\n * - if using `revokeRole`, it is the admin role bearer\n * - if using `renounceRole`, it is the role bearer (i.e. `account`)\n */\n event RoleRevoked(bytes32 indexed role, address indexed account, address indexed sender);\n\n /**\n * @dev Returns `true` if `account` has been granted `role`.\n */\n function hasRole(bytes32 role, address account) external view returns (bool);\n\n /**\n * @dev Returns the admin role that controls `role`. See {grantRole} and\n * {revokeRole}.\n *\n * To change a role's admin, use {AccessControl-_setRoleAdmin}.\n */\n function getRoleAdmin(bytes32 role) external view returns (bytes32);\n\n /**\n * @dev Grants `role` to `account`.\n *\n * If `account` had not been already granted `role`, emits a {RoleGranted}\n * event.\n *\n * Requirements:\n *\n * - the caller must have ``role``'s admin role.\n */\n function grantRole(bytes32 role, address account) external;\n\n /**\n * @dev Revokes `role` from `account`.\n *\n * If `account` had been granted `role`, emits a {RoleRevoked} event.\n *\n * Requirements:\n *\n * - the caller must have ``role``'s admin role.\n */\n function revokeRole(bytes32 role, address account) external;\n\n /**\n * @dev Revokes `role` from the calling account.\n *\n * Roles are often managed via {grantRole} and {revokeRole}: this function's\n * purpose is to provide a mechanism for accounts to lose their privileges\n * if they are compromised (such as when a trusted device is misplaced).\n *\n * If the calling account had been granted `role`, emits a {RoleRevoked}\n * event.\n *\n * Requirements:\n *\n * - the caller must be `account`.\n */\n function renounceRole(bytes32 role, address account) external;\n}\n" + }, + "@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (access/Ownable.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../utils/ContextUpgradeable.sol\";\nimport \"../proxy/utils/Initializable.sol\";\n\n/**\n * @dev Contract module which provides a basic access control mechanism, where\n * there is an account (an owner) that can be granted exclusive access to\n * specific functions.\n *\n * By default, the owner account will be the one that deploys the contract. This\n * can later be changed with {transferOwnership}.\n *\n * This module is used through inheritance. It will make available the modifier\n * `onlyOwner`, which can be applied to your functions to restrict their use to\n * the owner.\n */\nabstract contract OwnableUpgradeable is Initializable, ContextUpgradeable {\n address private _owner;\n\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\n\n /**\n * @dev Initializes the contract setting the deployer as the initial owner.\n */\n function __Ownable_init() internal onlyInitializing {\n __Ownable_init_unchained();\n }\n\n function __Ownable_init_unchained() internal onlyInitializing {\n _transferOwnership(_msgSender());\n }\n\n /**\n * @dev Throws if called by any account other than the owner.\n */\n modifier onlyOwner() {\n _checkOwner();\n _;\n }\n\n /**\n * @dev Returns the address of the current owner.\n */\n function owner() public view virtual returns (address) {\n return _owner;\n }\n\n /**\n * @dev Throws if the sender is not the owner.\n */\n function _checkOwner() internal view virtual {\n require(owner() == _msgSender(), \"Ownable: caller is not the owner\");\n }\n\n /**\n * @dev Leaves the contract without owner. It will not be possible to call\n * `onlyOwner` functions anymore. Can only be called by the current owner.\n *\n * NOTE: Renouncing ownership will leave the contract without an owner,\n * thereby removing any functionality that is only available to the owner.\n */\n function renounceOwnership() public virtual onlyOwner {\n _transferOwnership(address(0));\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Can only be called by the current owner.\n */\n function transferOwnership(address newOwner) public virtual onlyOwner {\n require(newOwner != address(0), \"Ownable: new owner is the zero address\");\n _transferOwnership(newOwner);\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Internal function without access restriction.\n */\n function _transferOwnership(address newOwner) internal virtual {\n address oldOwner = _owner;\n _owner = newOwner;\n emit OwnershipTransferred(oldOwner, newOwner);\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[49] private __gap;\n}\n" + }, + "@openzeppelin/contracts-upgradeable/interfaces/IERC721MetadataUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (interfaces/IERC721Metadata.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../token/ERC721/extensions/IERC721MetadataUpgradeable.sol\";\n" + }, + "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (proxy/utils/Initializable.sol)\n\npragma solidity ^0.8.2;\n\nimport \"../../utils/AddressUpgradeable.sol\";\n\n/**\n * @dev This is a base contract to aid in writing upgradeable contracts, or any kind of contract that will be deployed\n * behind a proxy. Since proxied contracts do not make use of a constructor, it's common to move constructor logic to an\n * external initializer function, usually called `initialize`. It then becomes necessary to protect this initializer\n * function so it can only be called once. The {initializer} modifier provided by this contract will have this effect.\n *\n * The initialization functions use a version number. Once a version number is used, it is consumed and cannot be\n * reused. This mechanism prevents re-execution of each \"step\" but allows the creation of new initialization steps in\n * case an upgrade adds a module that needs to be initialized.\n *\n * For example:\n *\n * [.hljs-theme-light.nopadding]\n * ```\n * contract MyToken is ERC20Upgradeable {\n * function initialize() initializer public {\n * __ERC20_init(\"MyToken\", \"MTK\");\n * }\n * }\n * contract MyTokenV2 is MyToken, ERC20PermitUpgradeable {\n * function initializeV2() reinitializer(2) public {\n * __ERC20Permit_init(\"MyToken\");\n * }\n * }\n * ```\n *\n * TIP: To avoid leaving the proxy in an uninitialized state, the initializer function should be called as early as\n * possible by providing the encoded function call as the `_data` argument to {ERC1967Proxy-constructor}.\n *\n * CAUTION: When used with inheritance, manual care must be taken to not invoke a parent initializer twice, or to ensure\n * that all initializers are idempotent. This is not verified automatically as constructors are by Solidity.\n *\n * [CAUTION]\n * ====\n * Avoid leaving a contract uninitialized.\n *\n * An uninitialized contract can be taken over by an attacker. This applies to both a proxy and its implementation\n * contract, which may impact the proxy. To prevent the implementation contract from being used, you should invoke\n * the {_disableInitializers} function in the constructor to automatically lock it when it is deployed:\n *\n * [.hljs-theme-light.nopadding]\n * ```\n * /// @custom:oz-upgrades-unsafe-allow constructor\n * constructor() {\n * _disableInitializers();\n * }\n * ```\n * ====\n */\nabstract contract Initializable {\n /**\n * @dev Indicates that the contract has been initialized.\n * @custom:oz-retyped-from bool\n */\n uint8 private _initialized;\n\n /**\n * @dev Indicates that the contract is in the process of being initialized.\n */\n bool private _initializing;\n\n /**\n * @dev Triggered when the contract has been initialized or reinitialized.\n */\n event Initialized(uint8 version);\n\n /**\n * @dev A modifier that defines a protected initializer function that can be invoked at most once. In its scope,\n * `onlyInitializing` functions can be used to initialize parent contracts. Equivalent to `reinitializer(1)`.\n */\n modifier initializer() {\n bool isTopLevelCall = !_initializing;\n require(\n (isTopLevelCall && _initialized < 1) || (!AddressUpgradeable.isContract(address(this)) && _initialized == 1),\n \"Initializable: contract is already initialized\"\n );\n _initialized = 1;\n if (isTopLevelCall) {\n _initializing = true;\n }\n _;\n if (isTopLevelCall) {\n _initializing = false;\n emit Initialized(1);\n }\n }\n\n /**\n * @dev A modifier that defines a protected reinitializer function that can be invoked at most once, and only if the\n * contract hasn't been initialized to a greater version before. In its scope, `onlyInitializing` functions can be\n * used to initialize parent contracts.\n *\n * `initializer` is equivalent to `reinitializer(1)`, so a reinitializer may be used after the original\n * initialization step. This is essential to configure modules that are added through upgrades and that require\n * initialization.\n *\n * Note that versions can jump in increments greater than 1; this implies that if multiple reinitializers coexist in\n * a contract, executing them in the right order is up to the developer or operator.\n */\n modifier reinitializer(uint8 version) {\n require(!_initializing && _initialized < version, \"Initializable: contract is already initialized\");\n _initialized = version;\n _initializing = true;\n _;\n _initializing = false;\n emit Initialized(version);\n }\n\n /**\n * @dev Modifier to protect an initialization function so that it can only be invoked by functions with the\n * {initializer} and {reinitializer} modifiers, directly or indirectly.\n */\n modifier onlyInitializing() {\n require(_initializing, \"Initializable: contract is not initializing\");\n _;\n }\n\n /**\n * @dev Locks the contract, preventing any future reinitialization. This cannot be part of an initializer call.\n * Calling this in the constructor of a contract will prevent that contract from being initialized or reinitialized\n * to any version. It is recommended to use this to lock implementation contracts that are designed to be called\n * through proxies.\n */\n function _disableInitializers() internal virtual {\n require(!_initializing, \"Initializable: contract is initializing\");\n if (_initialized < type(uint8).max) {\n _initialized = type(uint8).max;\n emit Initialized(type(uint8).max);\n }\n }\n}\n" + }, + "@openzeppelin/contracts-upgradeable/security/PausableUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (security/Pausable.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../utils/ContextUpgradeable.sol\";\nimport \"../proxy/utils/Initializable.sol\";\n\n/**\n * @dev Contract module which allows children to implement an emergency stop\n * mechanism that can be triggered by an authorized account.\n *\n * This module is used through inheritance. It will make available the\n * modifiers `whenNotPaused` and `whenPaused`, which can be applied to\n * the functions of your contract. Note that they will not be pausable by\n * simply including this module, only once the modifiers are put in place.\n */\nabstract contract PausableUpgradeable is Initializable, ContextUpgradeable {\n /**\n * @dev Emitted when the pause is triggered by `account`.\n */\n event Paused(address account);\n\n /**\n * @dev Emitted when the pause is lifted by `account`.\n */\n event Unpaused(address account);\n\n bool private _paused;\n\n /**\n * @dev Initializes the contract in unpaused state.\n */\n function __Pausable_init() internal onlyInitializing {\n __Pausable_init_unchained();\n }\n\n function __Pausable_init_unchained() internal onlyInitializing {\n _paused = false;\n }\n\n /**\n * @dev Modifier to make a function callable only when the contract is not paused.\n *\n * Requirements:\n *\n * - The contract must not be paused.\n */\n modifier whenNotPaused() {\n _requireNotPaused();\n _;\n }\n\n /**\n * @dev Modifier to make a function callable only when the contract is paused.\n *\n * Requirements:\n *\n * - The contract must be paused.\n */\n modifier whenPaused() {\n _requirePaused();\n _;\n }\n\n /**\n * @dev Returns true if the contract is paused, and false otherwise.\n */\n function paused() public view virtual returns (bool) {\n return _paused;\n }\n\n /**\n * @dev Throws if the contract is paused.\n */\n function _requireNotPaused() internal view virtual {\n require(!paused(), \"Pausable: paused\");\n }\n\n /**\n * @dev Throws if the contract is not paused.\n */\n function _requirePaused() internal view virtual {\n require(paused(), \"Pausable: not paused\");\n }\n\n /**\n * @dev Triggers stopped state.\n *\n * Requirements:\n *\n * - The contract must not be paused.\n */\n function _pause() internal virtual whenNotPaused {\n _paused = true;\n emit Paused(_msgSender());\n }\n\n /**\n * @dev Returns to normal state.\n *\n * Requirements:\n *\n * - The contract must be paused.\n */\n function _unpause() internal virtual whenPaused {\n _paused = false;\n emit Unpaused(_msgSender());\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[49] private __gap;\n}\n" + }, + "@openzeppelin/contracts-upgradeable/security/ReentrancyGuardUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (security/ReentrancyGuard.sol)\n\npragma solidity ^0.8.0;\nimport \"../proxy/utils/Initializable.sol\";\n\n/**\n * @dev Contract module that helps prevent reentrant calls to a function.\n *\n * Inheriting from `ReentrancyGuard` will make the {nonReentrant} modifier\n * available, which can be applied to functions to make sure there are no nested\n * (reentrant) calls to them.\n *\n * Note that because there is a single `nonReentrant` guard, functions marked as\n * `nonReentrant` may not call one another. This can be worked around by making\n * those functions `private`, and then adding `external` `nonReentrant` entry\n * points to them.\n *\n * TIP: If you would like to learn more about reentrancy and alternative ways\n * to protect against it, check out our blog post\n * https://blog.openzeppelin.com/reentrancy-after-istanbul/[Reentrancy After Istanbul].\n */\nabstract contract ReentrancyGuardUpgradeable is Initializable {\n // Booleans are more expensive than uint256 or any type that takes up a full\n // word because each write operation emits an extra SLOAD to first read the\n // slot's contents, replace the bits taken up by the boolean, and then write\n // back. This is the compiler's defense against contract upgrades and\n // pointer aliasing, and it cannot be disabled.\n\n // The values being non-zero value makes deployment a bit more expensive,\n // but in exchange the refund on every call to nonReentrant will be lower in\n // amount. Since refunds are capped to a percentage of the total\n // transaction's gas, it is best to keep them low in cases like this one, to\n // increase the likelihood of the full refund coming into effect.\n uint256 private constant _NOT_ENTERED = 1;\n uint256 private constant _ENTERED = 2;\n\n uint256 private _status;\n\n function __ReentrancyGuard_init() internal onlyInitializing {\n __ReentrancyGuard_init_unchained();\n }\n\n function __ReentrancyGuard_init_unchained() internal onlyInitializing {\n _status = _NOT_ENTERED;\n }\n\n /**\n * @dev Prevents a contract from calling itself, directly or indirectly.\n * Calling a `nonReentrant` function from another `nonReentrant`\n * function is not supported. It is possible to prevent this from happening\n * by making the `nonReentrant` function external, and making it call a\n * `private` function that does the actual work.\n */\n modifier nonReentrant() {\n // On the first call to nonReentrant, _notEntered will be true\n require(_status != _ENTERED, \"ReentrancyGuard: reentrant call\");\n\n // Any calls to nonReentrant after this point will fail\n _status = _ENTERED;\n\n _;\n\n // By storing the original value once again, a refund is triggered (see\n // https://eips.ethereum.org/EIPS/eip-2200)\n _status = _NOT_ENTERED;\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[49] private __gap;\n}\n" + }, + "@openzeppelin/contracts-upgradeable/token/ERC20/ERC20Upgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (token/ERC20/ERC20.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./IERC20Upgradeable.sol\";\nimport \"./extensions/IERC20MetadataUpgradeable.sol\";\nimport \"../../utils/ContextUpgradeable.sol\";\nimport \"../../proxy/utils/Initializable.sol\";\n\n/**\n * @dev Implementation of the {IERC20} interface.\n *\n * This implementation is agnostic to the way tokens are created. This means\n * that a supply mechanism has to be added in a derived contract using {_mint}.\n * For a generic mechanism see {ERC20PresetMinterPauser}.\n *\n * TIP: For a detailed writeup see our guide\n * https://forum.zeppelin.solutions/t/how-to-implement-erc20-supply-mechanisms/226[How\n * to implement supply mechanisms].\n *\n * We have followed general OpenZeppelin Contracts guidelines: functions revert\n * instead returning `false` on failure. This behavior is nonetheless\n * conventional and does not conflict with the expectations of ERC20\n * applications.\n *\n * Additionally, an {Approval} event is emitted on calls to {transferFrom}.\n * This allows applications to reconstruct the allowance for all accounts just\n * by listening to said events. Other implementations of the EIP may not emit\n * these events, as it isn't required by the specification.\n *\n * Finally, the non-standard {decreaseAllowance} and {increaseAllowance}\n * functions have been added to mitigate the well-known issues around setting\n * allowances. See {IERC20-approve}.\n */\ncontract ERC20Upgradeable is Initializable, ContextUpgradeable, IERC20Upgradeable, IERC20MetadataUpgradeable {\n mapping(address => uint256) private _balances;\n\n mapping(address => mapping(address => uint256)) private _allowances;\n\n uint256 private _totalSupply;\n\n string private _name;\n string private _symbol;\n\n /**\n * @dev Sets the values for {name} and {symbol}.\n *\n * The default value of {decimals} is 18. To select a different value for\n * {decimals} you should overload it.\n *\n * All two of these values are immutable: they can only be set once during\n * construction.\n */\n function __ERC20_init(string memory name_, string memory symbol_) internal onlyInitializing {\n __ERC20_init_unchained(name_, symbol_);\n }\n\n function __ERC20_init_unchained(string memory name_, string memory symbol_) internal onlyInitializing {\n _name = name_;\n _symbol = symbol_;\n }\n\n /**\n * @dev Returns the name of the token.\n */\n function name() public view virtual override returns (string memory) {\n return _name;\n }\n\n /**\n * @dev Returns the symbol of the token, usually a shorter version of the\n * name.\n */\n function symbol() public view virtual override returns (string memory) {\n return _symbol;\n }\n\n /**\n * @dev Returns the number of decimals used to get its user representation.\n * For example, if `decimals` equals `2`, a balance of `505` tokens should\n * be displayed to a user as `5.05` (`505 / 10 ** 2`).\n *\n * Tokens usually opt for a value of 18, imitating the relationship between\n * Ether and Wei. This is the value {ERC20} uses, unless this function is\n * overridden;\n *\n * NOTE: This information is only used for _display_ purposes: it in\n * no way affects any of the arithmetic of the contract, including\n * {IERC20-balanceOf} and {IERC20-transfer}.\n */\n function decimals() public view virtual override returns (uint8) {\n return 18;\n }\n\n /**\n * @dev See {IERC20-totalSupply}.\n */\n function totalSupply() public view virtual override returns (uint256) {\n return _totalSupply;\n }\n\n /**\n * @dev See {IERC20-balanceOf}.\n */\n function balanceOf(address account) public view virtual override returns (uint256) {\n return _balances[account];\n }\n\n /**\n * @dev See {IERC20-transfer}.\n *\n * Requirements:\n *\n * - `to` cannot be the zero address.\n * - the caller must have a balance of at least `amount`.\n */\n function transfer(address to, uint256 amount) public virtual override returns (bool) {\n address owner = _msgSender();\n _transfer(owner, to, amount);\n return true;\n }\n\n /**\n * @dev See {IERC20-allowance}.\n */\n function allowance(address owner, address spender) public view virtual override returns (uint256) {\n return _allowances[owner][spender];\n }\n\n /**\n * @dev See {IERC20-approve}.\n *\n * NOTE: If `amount` is the maximum `uint256`, the allowance is not updated on\n * `transferFrom`. This is semantically equivalent to an infinite approval.\n *\n * Requirements:\n *\n * - `spender` cannot be the zero address.\n */\n function approve(address spender, uint256 amount) public virtual override returns (bool) {\n address owner = _msgSender();\n _approve(owner, spender, amount);\n return true;\n }\n\n /**\n * @dev See {IERC20-transferFrom}.\n *\n * Emits an {Approval} event indicating the updated allowance. This is not\n * required by the EIP. See the note at the beginning of {ERC20}.\n *\n * NOTE: Does not update the allowance if the current allowance\n * is the maximum `uint256`.\n *\n * Requirements:\n *\n * - `from` and `to` cannot be the zero address.\n * - `from` must have a balance of at least `amount`.\n * - the caller must have allowance for ``from``'s tokens of at least\n * `amount`.\n */\n function transferFrom(\n address from,\n address to,\n uint256 amount\n ) public virtual override returns (bool) {\n address spender = _msgSender();\n _spendAllowance(from, spender, amount);\n _transfer(from, to, amount);\n return true;\n }\n\n /**\n * @dev Atomically increases the allowance granted to `spender` by the caller.\n *\n * This is an alternative to {approve} that can be used as a mitigation for\n * problems described in {IERC20-approve}.\n *\n * Emits an {Approval} event indicating the updated allowance.\n *\n * Requirements:\n *\n * - `spender` cannot be the zero address.\n */\n function increaseAllowance(address spender, uint256 addedValue) public virtual returns (bool) {\n address owner = _msgSender();\n _approve(owner, spender, allowance(owner, spender) + addedValue);\n return true;\n }\n\n /**\n * @dev Atomically decreases the allowance granted to `spender` by the caller.\n *\n * This is an alternative to {approve} that can be used as a mitigation for\n * problems described in {IERC20-approve}.\n *\n * Emits an {Approval} event indicating the updated allowance.\n *\n * Requirements:\n *\n * - `spender` cannot be the zero address.\n * - `spender` must have allowance for the caller of at least\n * `subtractedValue`.\n */\n function decreaseAllowance(address spender, uint256 subtractedValue) public virtual returns (bool) {\n address owner = _msgSender();\n uint256 currentAllowance = allowance(owner, spender);\n require(currentAllowance >= subtractedValue, \"ERC20: decreased allowance below zero\");\n unchecked {\n _approve(owner, spender, currentAllowance - subtractedValue);\n }\n\n return true;\n }\n\n /**\n * @dev Moves `amount` of tokens from `from` to `to`.\n *\n * This internal function is equivalent to {transfer}, and can be used to\n * e.g. implement automatic token fees, slashing mechanisms, etc.\n *\n * Emits a {Transfer} event.\n *\n * Requirements:\n *\n * - `from` cannot be the zero address.\n * - `to` cannot be the zero address.\n * - `from` must have a balance of at least `amount`.\n */\n function _transfer(\n address from,\n address to,\n uint256 amount\n ) internal virtual {\n require(from != address(0), \"ERC20: transfer from the zero address\");\n require(to != address(0), \"ERC20: transfer to the zero address\");\n\n _beforeTokenTransfer(from, to, amount);\n\n uint256 fromBalance = _balances[from];\n require(fromBalance >= amount, \"ERC20: transfer amount exceeds balance\");\n unchecked {\n _balances[from] = fromBalance - amount;\n }\n _balances[to] += amount;\n\n emit Transfer(from, to, amount);\n\n _afterTokenTransfer(from, to, amount);\n }\n\n /** @dev Creates `amount` tokens and assigns them to `account`, increasing\n * the total supply.\n *\n * Emits a {Transfer} event with `from` set to the zero address.\n *\n * Requirements:\n *\n * - `account` cannot be the zero address.\n */\n function _mint(address account, uint256 amount) internal virtual {\n require(account != address(0), \"ERC20: mint to the zero address\");\n\n _beforeTokenTransfer(address(0), account, amount);\n\n _totalSupply += amount;\n _balances[account] += amount;\n emit Transfer(address(0), account, amount);\n\n _afterTokenTransfer(address(0), account, amount);\n }\n\n /**\n * @dev Destroys `amount` tokens from `account`, reducing the\n * total supply.\n *\n * Emits a {Transfer} event with `to` set to the zero address.\n *\n * Requirements:\n *\n * - `account` cannot be the zero address.\n * - `account` must have at least `amount` tokens.\n */\n function _burn(address account, uint256 amount) internal virtual {\n require(account != address(0), \"ERC20: burn from the zero address\");\n\n _beforeTokenTransfer(account, address(0), amount);\n\n uint256 accountBalance = _balances[account];\n require(accountBalance >= amount, \"ERC20: burn amount exceeds balance\");\n unchecked {\n _balances[account] = accountBalance - amount;\n }\n _totalSupply -= amount;\n\n emit Transfer(account, address(0), amount);\n\n _afterTokenTransfer(account, address(0), amount);\n }\n\n /**\n * @dev Sets `amount` as the allowance of `spender` over the `owner` s tokens.\n *\n * This internal function is equivalent to `approve`, and can be used to\n * e.g. set automatic allowances for certain subsystems, etc.\n *\n * Emits an {Approval} event.\n *\n * Requirements:\n *\n * - `owner` cannot be the zero address.\n * - `spender` cannot be the zero address.\n */\n function _approve(\n address owner,\n address spender,\n uint256 amount\n ) internal virtual {\n require(owner != address(0), \"ERC20: approve from the zero address\");\n require(spender != address(0), \"ERC20: approve to the zero address\");\n\n _allowances[owner][spender] = amount;\n emit Approval(owner, spender, amount);\n }\n\n /**\n * @dev Updates `owner` s allowance for `spender` based on spent `amount`.\n *\n * Does not update the allowance amount in case of infinite allowance.\n * Revert if not enough allowance is available.\n *\n * Might emit an {Approval} event.\n */\n function _spendAllowance(\n address owner,\n address spender,\n uint256 amount\n ) internal virtual {\n uint256 currentAllowance = allowance(owner, spender);\n if (currentAllowance != type(uint256).max) {\n require(currentAllowance >= amount, \"ERC20: insufficient allowance\");\n unchecked {\n _approve(owner, spender, currentAllowance - amount);\n }\n }\n }\n\n /**\n * @dev Hook that is called before any transfer of tokens. This includes\n * minting and burning.\n *\n * Calling conditions:\n *\n * - when `from` and `to` are both non-zero, `amount` of ``from``'s tokens\n * will be transferred to `to`.\n * - when `from` is zero, `amount` tokens will be minted for `to`.\n * - when `to` is zero, `amount` of ``from``'s tokens will be burned.\n * - `from` and `to` are never both zero.\n *\n * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].\n */\n function _beforeTokenTransfer(\n address from,\n address to,\n uint256 amount\n ) internal virtual {}\n\n /**\n * @dev Hook that is called after any transfer of tokens. This includes\n * minting and burning.\n *\n * Calling conditions:\n *\n * - when `from` and `to` are both non-zero, `amount` of ``from``'s tokens\n * has been transferred to `to`.\n * - when `from` is zero, `amount` tokens have been minted for `to`.\n * - when `to` is zero, `amount` of ``from``'s tokens have been burned.\n * - `from` and `to` are never both zero.\n *\n * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].\n */\n function _afterTokenTransfer(\n address from,\n address to,\n uint256 amount\n ) internal virtual {}\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[45] private __gap;\n}\n" + }, + "@openzeppelin/contracts-upgradeable/token/ERC20/extensions/draft-ERC20PermitUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.6.0) (token/ERC20/extensions/draft-ERC20Permit.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./draft-IERC20PermitUpgradeable.sol\";\nimport \"../ERC20Upgradeable.sol\";\nimport \"../../../utils/cryptography/draft-EIP712Upgradeable.sol\";\nimport \"../../../utils/cryptography/ECDSAUpgradeable.sol\";\nimport \"../../../utils/CountersUpgradeable.sol\";\nimport \"../../../proxy/utils/Initializable.sol\";\n\n/**\n * @dev Implementation of the ERC20 Permit extension allowing approvals to be made via signatures, as defined in\n * https://eips.ethereum.org/EIPS/eip-2612[EIP-2612].\n *\n * Adds the {permit} method, which can be used to change an account's ERC20 allowance (see {IERC20-allowance}) by\n * presenting a message signed by the account. By not relying on `{IERC20-approve}`, the token holder account doesn't\n * need to send a transaction, and thus is not required to hold Ether at all.\n *\n * _Available since v3.4._\n *\n * @custom:storage-size 51\n */\nabstract contract ERC20PermitUpgradeable is Initializable, ERC20Upgradeable, IERC20PermitUpgradeable, EIP712Upgradeable {\n using CountersUpgradeable for CountersUpgradeable.Counter;\n\n mapping(address => CountersUpgradeable.Counter) private _nonces;\n\n // solhint-disable-next-line var-name-mixedcase\n bytes32 private constant _PERMIT_TYPEHASH =\n keccak256(\"Permit(address owner,address spender,uint256 value,uint256 nonce,uint256 deadline)\");\n /**\n * @dev In previous versions `_PERMIT_TYPEHASH` was declared as `immutable`.\n * However, to ensure consistency with the upgradeable transpiler, we will continue\n * to reserve a slot.\n * @custom:oz-renamed-from _PERMIT_TYPEHASH\n */\n // solhint-disable-next-line var-name-mixedcase\n bytes32 private _PERMIT_TYPEHASH_DEPRECATED_SLOT;\n\n /**\n * @dev Initializes the {EIP712} domain separator using the `name` parameter, and setting `version` to `\"1\"`.\n *\n * It's a good idea to use the same `name` that is defined as the ERC20 token name.\n */\n function __ERC20Permit_init(string memory name) internal onlyInitializing {\n __EIP712_init_unchained(name, \"1\");\n }\n\n function __ERC20Permit_init_unchained(string memory) internal onlyInitializing {}\n\n /**\n * @dev See {IERC20Permit-permit}.\n */\n function permit(\n address owner,\n address spender,\n uint256 value,\n uint256 deadline,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) public virtual override {\n require(block.timestamp <= deadline, \"ERC20Permit: expired deadline\");\n\n bytes32 structHash = keccak256(abi.encode(_PERMIT_TYPEHASH, owner, spender, value, _useNonce(owner), deadline));\n\n bytes32 hash = _hashTypedDataV4(structHash);\n\n address signer = ECDSAUpgradeable.recover(hash, v, r, s);\n require(signer == owner, \"ERC20Permit: invalid signature\");\n\n _approve(owner, spender, value);\n }\n\n /**\n * @dev See {IERC20Permit-nonces}.\n */\n function nonces(address owner) public view virtual override returns (uint256) {\n return _nonces[owner].current();\n }\n\n /**\n * @dev See {IERC20Permit-DOMAIN_SEPARATOR}.\n */\n // solhint-disable-next-line func-name-mixedcase\n function DOMAIN_SEPARATOR() external view override returns (bytes32) {\n return _domainSeparatorV4();\n }\n\n /**\n * @dev \"Consume a nonce\": return the current value and increment.\n *\n * _Available since v4.1._\n */\n function _useNonce(address owner) internal virtual returns (uint256 current) {\n CountersUpgradeable.Counter storage nonce = _nonces[owner];\n current = nonce.current();\n nonce.increment();\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[49] private __gap;\n}\n" + }, + "@openzeppelin/contracts-upgradeable/token/ERC20/extensions/draft-IERC20PermitUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (token/ERC20/extensions/draft-IERC20Permit.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Interface of the ERC20 Permit extension allowing approvals to be made via signatures, as defined in\n * https://eips.ethereum.org/EIPS/eip-2612[EIP-2612].\n *\n * Adds the {permit} method, which can be used to change an account's ERC20 allowance (see {IERC20-allowance}) by\n * presenting a message signed by the account. By not relying on {IERC20-approve}, the token holder account doesn't\n * need to send a transaction, and thus is not required to hold Ether at all.\n */\ninterface IERC20PermitUpgradeable {\n /**\n * @dev Sets `value` as the allowance of `spender` over ``owner``'s tokens,\n * given ``owner``'s signed approval.\n *\n * IMPORTANT: The same issues {IERC20-approve} has related to transaction\n * ordering also apply here.\n *\n * Emits an {Approval} event.\n *\n * Requirements:\n *\n * - `spender` cannot be the zero address.\n * - `deadline` must be a timestamp in the future.\n * - `v`, `r` and `s` must be a valid `secp256k1` signature from `owner`\n * over the EIP712-formatted function arguments.\n * - the signature must use ``owner``'s current nonce (see {nonces}).\n *\n * For more information on the signature format, see the\n * https://eips.ethereum.org/EIPS/eip-2612#specification[relevant EIP\n * section].\n */\n function permit(\n address owner,\n address spender,\n uint256 value,\n uint256 deadline,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) external;\n\n /**\n * @dev Returns the current nonce for `owner`. This value must be\n * included whenever a signature is generated for {permit}.\n *\n * Every successful call to {permit} increases ``owner``'s nonce by one. This\n * prevents a signature from being used multiple times.\n */\n function nonces(address owner) external view returns (uint256);\n\n /**\n * @dev Returns the domain separator used in the encoding of the signature for {permit}, as defined by {EIP712}.\n */\n // solhint-disable-next-line func-name-mixedcase\n function DOMAIN_SEPARATOR() external view returns (bytes32);\n}\n" + }, + "@openzeppelin/contracts-upgradeable/token/ERC20/extensions/IERC20MetadataUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (token/ERC20/extensions/IERC20Metadata.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../IERC20Upgradeable.sol\";\n\n/**\n * @dev Interface for the optional metadata functions from the ERC20 standard.\n *\n * _Available since v4.1._\n */\ninterface IERC20MetadataUpgradeable is IERC20Upgradeable {\n /**\n * @dev Returns the name of the token.\n */\n function name() external view returns (string memory);\n\n /**\n * @dev Returns the symbol of the token.\n */\n function symbol() external view returns (string memory);\n\n /**\n * @dev Returns the decimals places of the token.\n */\n function decimals() external view returns (uint8);\n}\n" + }, + "@openzeppelin/contracts-upgradeable/token/ERC20/IERC20Upgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.6.0) (token/ERC20/IERC20.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Interface of the ERC20 standard as defined in the EIP.\n */\ninterface IERC20Upgradeable {\n /**\n * @dev Emitted when `value` tokens are moved from one account (`from`) to\n * another (`to`).\n *\n * Note that `value` may be zero.\n */\n event Transfer(address indexed from, address indexed to, uint256 value);\n\n /**\n * @dev Emitted when the allowance of a `spender` for an `owner` is set by\n * a call to {approve}. `value` is the new allowance.\n */\n event Approval(address indexed owner, address indexed spender, uint256 value);\n\n /**\n * @dev Returns the amount of tokens in existence.\n */\n function totalSupply() external view returns (uint256);\n\n /**\n * @dev Returns the amount of tokens owned by `account`.\n */\n function balanceOf(address account) external view returns (uint256);\n\n /**\n * @dev Moves `amount` tokens from the caller's account to `to`.\n *\n * Returns a boolean value indicating whether the operation succeeded.\n *\n * Emits a {Transfer} event.\n */\n function transfer(address to, uint256 amount) external returns (bool);\n\n /**\n * @dev Returns the remaining number of tokens that `spender` will be\n * allowed to spend on behalf of `owner` through {transferFrom}. This is\n * zero by default.\n *\n * This value changes when {approve} or {transferFrom} are called.\n */\n function allowance(address owner, address spender) external view returns (uint256);\n\n /**\n * @dev Sets `amount` as the allowance of `spender` over the caller's tokens.\n *\n * Returns a boolean value indicating whether the operation succeeded.\n *\n * IMPORTANT: Beware that changing an allowance with this method brings the risk\n * that someone may use both the old and the new allowance by unfortunate\n * transaction ordering. One possible solution to mitigate this race\n * condition is to first reduce the spender's allowance to 0 and set the\n * desired value afterwards:\n * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729\n *\n * Emits an {Approval} event.\n */\n function approve(address spender, uint256 amount) external returns (bool);\n\n /**\n * @dev Moves `amount` tokens from `from` to `to` using the\n * allowance mechanism. `amount` is then deducted from the caller's\n * allowance.\n *\n * Returns a boolean value indicating whether the operation succeeded.\n *\n * Emits a {Transfer} event.\n */\n function transferFrom(\n address from,\n address to,\n uint256 amount\n ) external returns (bool);\n}\n" + }, + "@openzeppelin/contracts-upgradeable/token/ERC721/extensions/IERC721MetadataUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (token/ERC721/extensions/IERC721Metadata.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../IERC721Upgradeable.sol\";\n\n/**\n * @title ERC-721 Non-Fungible Token Standard, optional metadata extension\n * @dev See https://eips.ethereum.org/EIPS/eip-721\n */\ninterface IERC721MetadataUpgradeable is IERC721Upgradeable {\n /**\n * @dev Returns the token collection name.\n */\n function name() external view returns (string memory);\n\n /**\n * @dev Returns the token collection symbol.\n */\n function symbol() external view returns (string memory);\n\n /**\n * @dev Returns the Uniform Resource Identifier (URI) for `tokenId` token.\n */\n function tokenURI(uint256 tokenId) external view returns (string memory);\n}\n" + }, + "@openzeppelin/contracts-upgradeable/token/ERC721/IERC721ReceiverUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.6.0) (token/ERC721/IERC721Receiver.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @title ERC721 token receiver interface\n * @dev Interface for any contract that wants to support safeTransfers\n * from ERC721 asset contracts.\n */\ninterface IERC721ReceiverUpgradeable {\n /**\n * @dev Whenever an {IERC721} `tokenId` token is transferred to this contract via {IERC721-safeTransferFrom}\n * by `operator` from `from`, this function is called.\n *\n * It must return its Solidity selector to confirm the token transfer.\n * If any other value is returned or the interface is not implemented by the recipient, the transfer will be reverted.\n *\n * The selector can be obtained in Solidity with `IERC721Receiver.onERC721Received.selector`.\n */\n function onERC721Received(\n address operator,\n address from,\n uint256 tokenId,\n bytes calldata data\n ) external returns (bytes4);\n}\n" + }, + "@openzeppelin/contracts-upgradeable/token/ERC721/IERC721Upgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (token/ERC721/IERC721.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../../utils/introspection/IERC165Upgradeable.sol\";\n\n/**\n * @dev Required interface of an ERC721 compliant contract.\n */\ninterface IERC721Upgradeable is IERC165Upgradeable {\n /**\n * @dev Emitted when `tokenId` token is transferred from `from` to `to`.\n */\n event Transfer(address indexed from, address indexed to, uint256 indexed tokenId);\n\n /**\n * @dev Emitted when `owner` enables `approved` to manage the `tokenId` token.\n */\n event Approval(address indexed owner, address indexed approved, uint256 indexed tokenId);\n\n /**\n * @dev Emitted when `owner` enables or disables (`approved`) `operator` to manage all of its assets.\n */\n event ApprovalForAll(address indexed owner, address indexed operator, bool approved);\n\n /**\n * @dev Returns the number of tokens in ``owner``'s account.\n */\n function balanceOf(address owner) external view returns (uint256 balance);\n\n /**\n * @dev Returns the owner of the `tokenId` token.\n *\n * Requirements:\n *\n * - `tokenId` must exist.\n */\n function ownerOf(uint256 tokenId) external view returns (address owner);\n\n /**\n * @dev Safely transfers `tokenId` token from `from` to `to`.\n *\n * Requirements:\n *\n * - `from` cannot be the zero address.\n * - `to` cannot be the zero address.\n * - `tokenId` token must exist and be owned by `from`.\n * - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}.\n * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.\n *\n * Emits a {Transfer} event.\n */\n function safeTransferFrom(\n address from,\n address to,\n uint256 tokenId,\n bytes calldata data\n ) external;\n\n /**\n * @dev Safely transfers `tokenId` token from `from` to `to`, checking first that contract recipients\n * are aware of the ERC721 protocol to prevent tokens from being forever locked.\n *\n * Requirements:\n *\n * - `from` cannot be the zero address.\n * - `to` cannot be the zero address.\n * - `tokenId` token must exist and be owned by `from`.\n * - If the caller is not `from`, it must have been allowed to move this token by either {approve} or {setApprovalForAll}.\n * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.\n *\n * Emits a {Transfer} event.\n */\n function safeTransferFrom(\n address from,\n address to,\n uint256 tokenId\n ) external;\n\n /**\n * @dev Transfers `tokenId` token from `from` to `to`.\n *\n * WARNING: Usage of this method is discouraged, use {safeTransferFrom} whenever possible.\n *\n * Requirements:\n *\n * - `from` cannot be the zero address.\n * - `to` cannot be the zero address.\n * - `tokenId` token must be owned by `from`.\n * - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}.\n *\n * Emits a {Transfer} event.\n */\n function transferFrom(\n address from,\n address to,\n uint256 tokenId\n ) external;\n\n /**\n * @dev Gives permission to `to` to transfer `tokenId` token to another account.\n * The approval is cleared when the token is transferred.\n *\n * Only a single account can be approved at a time, so approving the zero address clears previous approvals.\n *\n * Requirements:\n *\n * - The caller must own the token or be an approved operator.\n * - `tokenId` must exist.\n *\n * Emits an {Approval} event.\n */\n function approve(address to, uint256 tokenId) external;\n\n /**\n * @dev Approve or remove `operator` as an operator for the caller.\n * Operators can call {transferFrom} or {safeTransferFrom} for any token owned by the caller.\n *\n * Requirements:\n *\n * - The `operator` cannot be the caller.\n *\n * Emits an {ApprovalForAll} event.\n */\n function setApprovalForAll(address operator, bool _approved) external;\n\n /**\n * @dev Returns the account approved for `tokenId` token.\n *\n * Requirements:\n *\n * - `tokenId` must exist.\n */\n function getApproved(uint256 tokenId) external view returns (address operator);\n\n /**\n * @dev Returns if the `operator` is allowed to manage all of the assets of `owner`.\n *\n * See {setApprovalForAll}\n */\n function isApprovedForAll(address owner, address operator) external view returns (bool);\n}\n" + }, + "@openzeppelin/contracts-upgradeable/utils/AddressUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (utils/Address.sol)\n\npragma solidity ^0.8.1;\n\n/**\n * @dev Collection of functions related to the address type\n */\nlibrary AddressUpgradeable {\n /**\n * @dev Returns true if `account` is a contract.\n *\n * [IMPORTANT]\n * ====\n * It is unsafe to assume that an address for which this function returns\n * false is an externally-owned account (EOA) and not a contract.\n *\n * Among others, `isContract` will return false for the following\n * types of addresses:\n *\n * - an externally-owned account\n * - a contract in construction\n * - an address where a contract will be created\n * - an address where a contract lived, but was destroyed\n * ====\n *\n * [IMPORTANT]\n * ====\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\n *\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\n * constructor.\n * ====\n */\n function isContract(address account) internal view returns (bool) {\n // This method relies on extcodesize/address.code.length, which returns 0\n // for contracts in construction, since the code is only stored at the end\n // of the constructor execution.\n\n return account.code.length > 0;\n }\n\n /**\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\n * `recipient`, forwarding all available gas and reverting on errors.\n *\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\n * imposed by `transfer`, making them unable to receive funds via\n * `transfer`. {sendValue} removes this limitation.\n *\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\n *\n * IMPORTANT: because control is transferred to `recipient`, care must be\n * taken to not create reentrancy vulnerabilities. Consider using\n * {ReentrancyGuard} or the\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\n */\n function sendValue(address payable recipient, uint256 amount) internal {\n require(address(this).balance >= amount, \"Address: insufficient balance\");\n\n (bool success, ) = recipient.call{value: amount}(\"\");\n require(success, \"Address: unable to send value, recipient may have reverted\");\n }\n\n /**\n * @dev Performs a Solidity function call using a low level `call`. A\n * plain `call` is an unsafe replacement for a function call: use this\n * function instead.\n *\n * If `target` reverts with a revert reason, it is bubbled up by this\n * function (like regular Solidity function calls).\n *\n * Returns the raw returned data. To convert to the expected return value,\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\n *\n * Requirements:\n *\n * - `target` must be a contract.\n * - calling `target` with `data` must not revert.\n *\n * _Available since v3.1._\n */\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionCall(target, data, \"Address: low-level call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\n * `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, 0, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but also transferring `value` wei to `target`.\n *\n * Requirements:\n *\n * - the calling contract must have an ETH balance of at least `value`.\n * - the called Solidity function must be `payable`.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, value, \"Address: low-level call with value failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\n * with `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(address(this).balance >= value, \"Address: insufficient balance for call\");\n require(isContract(target), \"Address: call to non-contract\");\n\n (bool success, bytes memory returndata) = target.call{value: value}(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\n return functionStaticCall(target, data, \"Address: low-level static call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal view returns (bytes memory) {\n require(isContract(target), \"Address: static call to non-contract\");\n\n (bool success, bytes memory returndata) = target.staticcall(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the\n * revert reason using the provided one.\n *\n * _Available since v4.3._\n */\n function verifyCallResult(\n bool success,\n bytes memory returndata,\n string memory errorMessage\n ) internal pure returns (bytes memory) {\n if (success) {\n return returndata;\n } else {\n // Look for revert reason and bubble it up if present\n if (returndata.length > 0) {\n // The easiest way to bubble the revert reason is using memory via assembly\n /// @solidity memory-safe-assembly\n assembly {\n let returndata_size := mload(returndata)\n revert(add(32, returndata), returndata_size)\n }\n } else {\n revert(errorMessage);\n }\n }\n }\n}\n" + }, + "@openzeppelin/contracts-upgradeable/utils/ContextUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)\n\npragma solidity ^0.8.0;\nimport \"../proxy/utils/Initializable.sol\";\n\n/**\n * @dev Provides information about the current execution context, including the\n * sender of the transaction and its data. While these are generally available\n * via msg.sender and msg.data, they should not be accessed in such a direct\n * manner, since when dealing with meta-transactions the account sending and\n * paying for execution may not be the actual sender (as far as an application\n * is concerned).\n *\n * This contract is only required for intermediate, library-like contracts.\n */\nabstract contract ContextUpgradeable is Initializable {\n function __Context_init() internal onlyInitializing {\n }\n\n function __Context_init_unchained() internal onlyInitializing {\n }\n function _msgSender() internal view virtual returns (address) {\n return msg.sender;\n }\n\n function _msgData() internal view virtual returns (bytes calldata) {\n return msg.data;\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[50] private __gap;\n}\n" + }, + "@openzeppelin/contracts-upgradeable/utils/CountersUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (utils/Counters.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @title Counters\n * @author Matt Condon (@shrugs)\n * @dev Provides counters that can only be incremented, decremented or reset. This can be used e.g. to track the number\n * of elements in a mapping, issuing ERC721 ids, or counting request ids.\n *\n * Include with `using Counters for Counters.Counter;`\n */\nlibrary CountersUpgradeable {\n struct Counter {\n // This variable should never be directly accessed by users of the library: interactions must be restricted to\n // the library's function. As of Solidity v0.5.2, this cannot be enforced, though there is a proposal to add\n // this feature: see https://github.com/ethereum/solidity/issues/4637\n uint256 _value; // default: 0\n }\n\n function current(Counter storage counter) internal view returns (uint256) {\n return counter._value;\n }\n\n function increment(Counter storage counter) internal {\n unchecked {\n counter._value += 1;\n }\n }\n\n function decrement(Counter storage counter) internal {\n uint256 value = counter._value;\n require(value > 0, \"Counter: decrement overflow\");\n unchecked {\n counter._value = value - 1;\n }\n }\n\n function reset(Counter storage counter) internal {\n counter._value = 0;\n }\n}\n" + }, + "@openzeppelin/contracts-upgradeable/utils/cryptography/draft-EIP712Upgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (utils/cryptography/draft-EIP712.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./ECDSAUpgradeable.sol\";\nimport \"../../proxy/utils/Initializable.sol\";\n\n/**\n * @dev https://eips.ethereum.org/EIPS/eip-712[EIP 712] is a standard for hashing and signing of typed structured data.\n *\n * The encoding specified in the EIP is very generic, and such a generic implementation in Solidity is not feasible,\n * thus this contract does not implement the encoding itself. Protocols need to implement the type-specific encoding\n * they need in their contracts using a combination of `abi.encode` and `keccak256`.\n *\n * This contract implements the EIP 712 domain separator ({_domainSeparatorV4}) that is used as part of the encoding\n * scheme, and the final step of the encoding to obtain the message digest that is then signed via ECDSA\n * ({_hashTypedDataV4}).\n *\n * The implementation of the domain separator was designed to be as efficient as possible while still properly updating\n * the chain id to protect against replay attacks on an eventual fork of the chain.\n *\n * NOTE: This contract implements the version of the encoding known as \"v4\", as implemented by the JSON RPC method\n * https://docs.metamask.io/guide/signing-data.html[`eth_signTypedDataV4` in MetaMask].\n *\n * _Available since v3.4._\n *\n * @custom:storage-size 52\n */\nabstract contract EIP712Upgradeable is Initializable {\n /* solhint-disable var-name-mixedcase */\n bytes32 private _HASHED_NAME;\n bytes32 private _HASHED_VERSION;\n bytes32 private constant _TYPE_HASH = keccak256(\"EIP712Domain(string name,string version,uint256 chainId,address verifyingContract)\");\n\n /* solhint-enable var-name-mixedcase */\n\n /**\n * @dev Initializes the domain separator and parameter caches.\n *\n * The meaning of `name` and `version` is specified in\n * https://eips.ethereum.org/EIPS/eip-712#definition-of-domainseparator[EIP 712]:\n *\n * - `name`: the user readable name of the signing domain, i.e. the name of the DApp or the protocol.\n * - `version`: the current major version of the signing domain.\n *\n * NOTE: These parameters cannot be changed except through a xref:learn::upgrading-smart-contracts.adoc[smart\n * contract upgrade].\n */\n function __EIP712_init(string memory name, string memory version) internal onlyInitializing {\n __EIP712_init_unchained(name, version);\n }\n\n function __EIP712_init_unchained(string memory name, string memory version) internal onlyInitializing {\n bytes32 hashedName = keccak256(bytes(name));\n bytes32 hashedVersion = keccak256(bytes(version));\n _HASHED_NAME = hashedName;\n _HASHED_VERSION = hashedVersion;\n }\n\n /**\n * @dev Returns the domain separator for the current chain.\n */\n function _domainSeparatorV4() internal view returns (bytes32) {\n return _buildDomainSeparator(_TYPE_HASH, _EIP712NameHash(), _EIP712VersionHash());\n }\n\n function _buildDomainSeparator(\n bytes32 typeHash,\n bytes32 nameHash,\n bytes32 versionHash\n ) private view returns (bytes32) {\n return keccak256(abi.encode(typeHash, nameHash, versionHash, block.chainid, address(this)));\n }\n\n /**\n * @dev Given an already https://eips.ethereum.org/EIPS/eip-712#definition-of-hashstruct[hashed struct], this\n * function returns the hash of the fully encoded EIP712 message for this domain.\n *\n * This hash can be used together with {ECDSA-recover} to obtain the signer of a message. For example:\n *\n * ```solidity\n * bytes32 digest = _hashTypedDataV4(keccak256(abi.encode(\n * keccak256(\"Mail(address to,string contents)\"),\n * mailTo,\n * keccak256(bytes(mailContents))\n * )));\n * address signer = ECDSA.recover(digest, signature);\n * ```\n */\n function _hashTypedDataV4(bytes32 structHash) internal view virtual returns (bytes32) {\n return ECDSAUpgradeable.toTypedDataHash(_domainSeparatorV4(), structHash);\n }\n\n /**\n * @dev The hash of the name parameter for the EIP712 domain.\n *\n * NOTE: This function reads from storage by default, but can be redefined to return a constant value if gas costs\n * are a concern.\n */\n function _EIP712NameHash() internal virtual view returns (bytes32) {\n return _HASHED_NAME;\n }\n\n /**\n * @dev The hash of the version parameter for the EIP712 domain.\n *\n * NOTE: This function reads from storage by default, but can be redefined to return a constant value if gas costs\n * are a concern.\n */\n function _EIP712VersionHash() internal virtual view returns (bytes32) {\n return _HASHED_VERSION;\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[50] private __gap;\n}\n" + }, + "@openzeppelin/contracts-upgradeable/utils/cryptography/ECDSAUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (utils/cryptography/ECDSA.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../StringsUpgradeable.sol\";\n\n/**\n * @dev Elliptic Curve Digital Signature Algorithm (ECDSA) operations.\n *\n * These functions can be used to verify that a message was signed by the holder\n * of the private keys of a given address.\n */\nlibrary ECDSAUpgradeable {\n enum RecoverError {\n NoError,\n InvalidSignature,\n InvalidSignatureLength,\n InvalidSignatureS,\n InvalidSignatureV\n }\n\n function _throwError(RecoverError error) private pure {\n if (error == RecoverError.NoError) {\n return; // no error: do nothing\n } else if (error == RecoverError.InvalidSignature) {\n revert(\"ECDSA: invalid signature\");\n } else if (error == RecoverError.InvalidSignatureLength) {\n revert(\"ECDSA: invalid signature length\");\n } else if (error == RecoverError.InvalidSignatureS) {\n revert(\"ECDSA: invalid signature 's' value\");\n } else if (error == RecoverError.InvalidSignatureV) {\n revert(\"ECDSA: invalid signature 'v' value\");\n }\n }\n\n /**\n * @dev Returns the address that signed a hashed message (`hash`) with\n * `signature` or error string. This address can then be used for verification purposes.\n *\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\n * this function rejects them by requiring the `s` value to be in the lower\n * half order, and the `v` value to be either 27 or 28.\n *\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\n * verification to be secure: it is possible to craft signatures that\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\n * this is by receiving a hash of the original message (which may otherwise\n * be too long), and then calling {toEthSignedMessageHash} on it.\n *\n * Documentation for signature generation:\n * - with https://web3js.readthedocs.io/en/v1.3.4/web3-eth-accounts.html#sign[Web3.js]\n * - with https://docs.ethers.io/v5/api/signer/#Signer-signMessage[ethers]\n *\n * _Available since v4.3._\n */\n function tryRecover(bytes32 hash, bytes memory signature) internal pure returns (address, RecoverError) {\n // Check the signature length\n // - case 65: r,s,v signature (standard)\n // - case 64: r,vs signature (cf https://eips.ethereum.org/EIPS/eip-2098) _Available since v4.1._\n if (signature.length == 65) {\n bytes32 r;\n bytes32 s;\n uint8 v;\n // ecrecover takes the signature parameters, and the only way to get them\n // currently is to use assembly.\n /// @solidity memory-safe-assembly\n assembly {\n r := mload(add(signature, 0x20))\n s := mload(add(signature, 0x40))\n v := byte(0, mload(add(signature, 0x60)))\n }\n return tryRecover(hash, v, r, s);\n } else if (signature.length == 64) {\n bytes32 r;\n bytes32 vs;\n // ecrecover takes the signature parameters, and the only way to get them\n // currently is to use assembly.\n /// @solidity memory-safe-assembly\n assembly {\n r := mload(add(signature, 0x20))\n vs := mload(add(signature, 0x40))\n }\n return tryRecover(hash, r, vs);\n } else {\n return (address(0), RecoverError.InvalidSignatureLength);\n }\n }\n\n /**\n * @dev Returns the address that signed a hashed message (`hash`) with\n * `signature`. This address can then be used for verification purposes.\n *\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\n * this function rejects them by requiring the `s` value to be in the lower\n * half order, and the `v` value to be either 27 or 28.\n *\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\n * verification to be secure: it is possible to craft signatures that\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\n * this is by receiving a hash of the original message (which may otherwise\n * be too long), and then calling {toEthSignedMessageHash} on it.\n */\n function recover(bytes32 hash, bytes memory signature) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, signature);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Overload of {ECDSA-tryRecover} that receives the `r` and `vs` short-signature fields separately.\n *\n * See https://eips.ethereum.org/EIPS/eip-2098[EIP-2098 short signatures]\n *\n * _Available since v4.3._\n */\n function tryRecover(\n bytes32 hash,\n bytes32 r,\n bytes32 vs\n ) internal pure returns (address, RecoverError) {\n bytes32 s = vs & bytes32(0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff);\n uint8 v = uint8((uint256(vs) >> 255) + 27);\n return tryRecover(hash, v, r, s);\n }\n\n /**\n * @dev Overload of {ECDSA-recover} that receives the `r and `vs` short-signature fields separately.\n *\n * _Available since v4.2._\n */\n function recover(\n bytes32 hash,\n bytes32 r,\n bytes32 vs\n ) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, r, vs);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Overload of {ECDSA-tryRecover} that receives the `v`,\n * `r` and `s` signature fields separately.\n *\n * _Available since v4.3._\n */\n function tryRecover(\n bytes32 hash,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) internal pure returns (address, RecoverError) {\n // EIP-2 still allows signature malleability for ecrecover(). Remove this possibility and make the signature\n // unique. Appendix F in the Ethereum Yellow paper (https://ethereum.github.io/yellowpaper/paper.pdf), defines\n // the valid range for s in (301): 0 < s < secp256k1n ÷ 2 + 1, and for v in (302): v ∈ {27, 28}. Most\n // signatures from current libraries generate a unique signature with an s-value in the lower half order.\n //\n // If your library generates malleable signatures, such as s-values in the upper range, calculate a new s-value\n // with 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141 - s1 and flip v from 27 to 28 or\n // vice versa. If your library also generates signatures with 0/1 for v instead 27/28, add 27 to v to accept\n // these malleable signatures as well.\n if (uint256(s) > 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D576E7357A4501DDFE92F46681B20A0) {\n return (address(0), RecoverError.InvalidSignatureS);\n }\n if (v != 27 && v != 28) {\n return (address(0), RecoverError.InvalidSignatureV);\n }\n\n // If the signature is valid (and not malleable), return the signer address\n address signer = ecrecover(hash, v, r, s);\n if (signer == address(0)) {\n return (address(0), RecoverError.InvalidSignature);\n }\n\n return (signer, RecoverError.NoError);\n }\n\n /**\n * @dev Overload of {ECDSA-recover} that receives the `v`,\n * `r` and `s` signature fields separately.\n */\n function recover(\n bytes32 hash,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, v, r, s);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Returns an Ethereum Signed Message, created from a `hash`. This\n * produces hash corresponding to the one signed with the\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\n * JSON-RPC method as part of EIP-191.\n *\n * See {recover}.\n */\n function toEthSignedMessageHash(bytes32 hash) internal pure returns (bytes32) {\n // 32 is the length in bytes of hash,\n // enforced by the type signature above\n return keccak256(abi.encodePacked(\"\\x19Ethereum Signed Message:\\n32\", hash));\n }\n\n /**\n * @dev Returns an Ethereum Signed Message, created from `s`. This\n * produces hash corresponding to the one signed with the\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\n * JSON-RPC method as part of EIP-191.\n *\n * See {recover}.\n */\n function toEthSignedMessageHash(bytes memory s) internal pure returns (bytes32) {\n return keccak256(abi.encodePacked(\"\\x19Ethereum Signed Message:\\n\", StringsUpgradeable.toString(s.length), s));\n }\n\n /**\n * @dev Returns an Ethereum Signed Typed Data, created from a\n * `domainSeparator` and a `structHash`. This produces hash corresponding\n * to the one signed with the\n * https://eips.ethereum.org/EIPS/eip-712[`eth_signTypedData`]\n * JSON-RPC method as part of EIP-712.\n *\n * See {recover}.\n */\n function toTypedDataHash(bytes32 domainSeparator, bytes32 structHash) internal pure returns (bytes32) {\n return keccak256(abi.encodePacked(\"\\x19\\x01\", domainSeparator, structHash));\n }\n}\n" + }, + "@openzeppelin/contracts-upgradeable/utils/introspection/ERC165Upgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (utils/introspection/ERC165.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./IERC165Upgradeable.sol\";\nimport \"../../proxy/utils/Initializable.sol\";\n\n/**\n * @dev Implementation of the {IERC165} interface.\n *\n * Contracts that want to implement ERC165 should inherit from this contract and override {supportsInterface} to check\n * for the additional interface id that will be supported. For example:\n *\n * ```solidity\n * function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {\n * return interfaceId == type(MyInterface).interfaceId || super.supportsInterface(interfaceId);\n * }\n * ```\n *\n * Alternatively, {ERC165Storage} provides an easier to use but more expensive implementation.\n */\nabstract contract ERC165Upgradeable is Initializable, IERC165Upgradeable {\n function __ERC165_init() internal onlyInitializing {\n }\n\n function __ERC165_init_unchained() internal onlyInitializing {\n }\n /**\n * @dev See {IERC165-supportsInterface}.\n */\n function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {\n return interfaceId == type(IERC165Upgradeable).interfaceId;\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[50] private __gap;\n}\n" + }, + "@openzeppelin/contracts-upgradeable/utils/introspection/IERC165Upgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (utils/introspection/IERC165.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Interface of the ERC165 standard, as defined in the\n * https://eips.ethereum.org/EIPS/eip-165[EIP].\n *\n * Implementers can declare support of contract interfaces, which can then be\n * queried by others ({ERC165Checker}).\n *\n * For an implementation, see {ERC165}.\n */\ninterface IERC165Upgradeable {\n /**\n * @dev Returns true if this contract implements the interface defined by\n * `interfaceId`. See the corresponding\n * https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified[EIP section]\n * to learn more about how these ids are created.\n *\n * This function call must use less than 30 000 gas.\n */\n function supportsInterface(bytes4 interfaceId) external view returns (bool);\n}\n" + }, + "@openzeppelin/contracts-upgradeable/utils/StringsUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (utils/Strings.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev String operations.\n */\nlibrary StringsUpgradeable {\n bytes16 private constant _HEX_SYMBOLS = \"0123456789abcdef\";\n uint8 private constant _ADDRESS_LENGTH = 20;\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` decimal representation.\n */\n function toString(uint256 value) internal pure returns (string memory) {\n // Inspired by OraclizeAPI's implementation - MIT licence\n // https://github.com/oraclize/ethereum-api/blob/b42146b063c7d6ee1358846c198246239e9360e8/oraclizeAPI_0.4.25.sol\n\n if (value == 0) {\n return \"0\";\n }\n uint256 temp = value;\n uint256 digits;\n while (temp != 0) {\n digits++;\n temp /= 10;\n }\n bytes memory buffer = new bytes(digits);\n while (value != 0) {\n digits -= 1;\n buffer[digits] = bytes1(uint8(48 + uint256(value % 10)));\n value /= 10;\n }\n return string(buffer);\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation.\n */\n function toHexString(uint256 value) internal pure returns (string memory) {\n if (value == 0) {\n return \"0x00\";\n }\n uint256 temp = value;\n uint256 length = 0;\n while (temp != 0) {\n length++;\n temp >>= 8;\n }\n return toHexString(value, length);\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length.\n */\n function toHexString(uint256 value, uint256 length) internal pure returns (string memory) {\n bytes memory buffer = new bytes(2 * length + 2);\n buffer[0] = \"0\";\n buffer[1] = \"x\";\n for (uint256 i = 2 * length + 1; i > 1; --i) {\n buffer[i] = _HEX_SYMBOLS[value & 0xf];\n value >>= 4;\n }\n require(value == 0, \"Strings: hex length insufficient\");\n return string(buffer);\n }\n\n /**\n * @dev Converts an `address` with fixed length of 20 bytes to its not checksummed ASCII `string` hexadecimal representation.\n */\n function toHexString(address addr) internal pure returns (string memory) {\n return toHexString(uint256(uint160(addr)), _ADDRESS_LENGTH);\n }\n}\n" + }, + "@openzeppelin/contracts-upgradeable/utils/structs/EnumerableSetUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (utils/structs/EnumerableSet.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Library for managing\n * https://en.wikipedia.org/wiki/Set_(abstract_data_type)[sets] of primitive\n * types.\n *\n * Sets have the following properties:\n *\n * - Elements are added, removed, and checked for existence in constant time\n * (O(1)).\n * - Elements are enumerated in O(n). No guarantees are made on the ordering.\n *\n * ```\n * contract Example {\n * // Add the library methods\n * using EnumerableSet for EnumerableSet.AddressSet;\n *\n * // Declare a set state variable\n * EnumerableSet.AddressSet private mySet;\n * }\n * ```\n *\n * As of v3.3.0, sets of type `bytes32` (`Bytes32Set`), `address` (`AddressSet`)\n * and `uint256` (`UintSet`) are supported.\n *\n * [WARNING]\n * ====\n * Trying to delete such a structure from storage will likely result in data corruption, rendering the structure unusable.\n * See https://github.com/ethereum/solidity/pull/11843[ethereum/solidity#11843] for more info.\n *\n * In order to clean an EnumerableSet, you can either remove all elements one by one or create a fresh instance using an array of EnumerableSet.\n * ====\n */\nlibrary EnumerableSetUpgradeable {\n // To implement this library for multiple types with as little code\n // repetition as possible, we write it in terms of a generic Set type with\n // bytes32 values.\n // The Set implementation uses private functions, and user-facing\n // implementations (such as AddressSet) are just wrappers around the\n // underlying Set.\n // This means that we can only create new EnumerableSets for types that fit\n // in bytes32.\n\n struct Set {\n // Storage of set values\n bytes32[] _values;\n // Position of the value in the `values` array, plus 1 because index 0\n // means a value is not in the set.\n mapping(bytes32 => uint256) _indexes;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function _add(Set storage set, bytes32 value) private returns (bool) {\n if (!_contains(set, value)) {\n set._values.push(value);\n // The value is stored at length-1, but we add 1 to all indexes\n // and use 0 as a sentinel value\n set._indexes[value] = set._values.length;\n return true;\n } else {\n return false;\n }\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function _remove(Set storage set, bytes32 value) private returns (bool) {\n // We read and store the value's index to prevent multiple reads from the same storage slot\n uint256 valueIndex = set._indexes[value];\n\n if (valueIndex != 0) {\n // Equivalent to contains(set, value)\n // To delete an element from the _values array in O(1), we swap the element to delete with the last one in\n // the array, and then remove the last element (sometimes called as 'swap and pop').\n // This modifies the order of the array, as noted in {at}.\n\n uint256 toDeleteIndex = valueIndex - 1;\n uint256 lastIndex = set._values.length - 1;\n\n if (lastIndex != toDeleteIndex) {\n bytes32 lastValue = set._values[lastIndex];\n\n // Move the last value to the index where the value to delete is\n set._values[toDeleteIndex] = lastValue;\n // Update the index for the moved value\n set._indexes[lastValue] = valueIndex; // Replace lastValue's index to valueIndex\n }\n\n // Delete the slot where the moved value was stored\n set._values.pop();\n\n // Delete the index for the deleted slot\n delete set._indexes[value];\n\n return true;\n } else {\n return false;\n }\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function _contains(Set storage set, bytes32 value) private view returns (bool) {\n return set._indexes[value] != 0;\n }\n\n /**\n * @dev Returns the number of values on the set. O(1).\n */\n function _length(Set storage set) private view returns (uint256) {\n return set._values.length;\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function _at(Set storage set, uint256 index) private view returns (bytes32) {\n return set._values[index];\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function _values(Set storage set) private view returns (bytes32[] memory) {\n return set._values;\n }\n\n // Bytes32Set\n\n struct Bytes32Set {\n Set _inner;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function add(Bytes32Set storage set, bytes32 value) internal returns (bool) {\n return _add(set._inner, value);\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function remove(Bytes32Set storage set, bytes32 value) internal returns (bool) {\n return _remove(set._inner, value);\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function contains(Bytes32Set storage set, bytes32 value) internal view returns (bool) {\n return _contains(set._inner, value);\n }\n\n /**\n * @dev Returns the number of values in the set. O(1).\n */\n function length(Bytes32Set storage set) internal view returns (uint256) {\n return _length(set._inner);\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function at(Bytes32Set storage set, uint256 index) internal view returns (bytes32) {\n return _at(set._inner, index);\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function values(Bytes32Set storage set) internal view returns (bytes32[] memory) {\n return _values(set._inner);\n }\n\n // AddressSet\n\n struct AddressSet {\n Set _inner;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function add(AddressSet storage set, address value) internal returns (bool) {\n return _add(set._inner, bytes32(uint256(uint160(value))));\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function remove(AddressSet storage set, address value) internal returns (bool) {\n return _remove(set._inner, bytes32(uint256(uint160(value))));\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function contains(AddressSet storage set, address value) internal view returns (bool) {\n return _contains(set._inner, bytes32(uint256(uint160(value))));\n }\n\n /**\n * @dev Returns the number of values in the set. O(1).\n */\n function length(AddressSet storage set) internal view returns (uint256) {\n return _length(set._inner);\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function at(AddressSet storage set, uint256 index) internal view returns (address) {\n return address(uint160(uint256(_at(set._inner, index))));\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function values(AddressSet storage set) internal view returns (address[] memory) {\n bytes32[] memory store = _values(set._inner);\n address[] memory result;\n\n /// @solidity memory-safe-assembly\n assembly {\n result := store\n }\n\n return result;\n }\n\n // UintSet\n\n struct UintSet {\n Set _inner;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function add(UintSet storage set, uint256 value) internal returns (bool) {\n return _add(set._inner, bytes32(value));\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function remove(UintSet storage set, uint256 value) internal returns (bool) {\n return _remove(set._inner, bytes32(value));\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function contains(UintSet storage set, uint256 value) internal view returns (bool) {\n return _contains(set._inner, bytes32(value));\n }\n\n /**\n * @dev Returns the number of values on the set. O(1).\n */\n function length(UintSet storage set) internal view returns (uint256) {\n return _length(set._inner);\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function at(UintSet storage set, uint256 index) internal view returns (uint256) {\n return uint256(_at(set._inner, index));\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function values(UintSet storage set) internal view returns (uint256[] memory) {\n bytes32[] memory store = _values(set._inner);\n uint256[] memory result;\n\n /// @solidity memory-safe-assembly\n assembly {\n result := store\n }\n\n return result;\n }\n}\n" + }, + "@openzeppelin/contracts/access/Ownable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (access/Ownable.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../utils/Context.sol\";\n\n/**\n * @dev Contract module which provides a basic access control mechanism, where\n * there is an account (an owner) that can be granted exclusive access to\n * specific functions.\n *\n * By default, the owner account will be the one that deploys the contract. This\n * can later be changed with {transferOwnership}.\n *\n * This module is used through inheritance. It will make available the modifier\n * `onlyOwner`, which can be applied to your functions to restrict their use to\n * the owner.\n */\nabstract contract Ownable is Context {\n address private _owner;\n\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\n\n /**\n * @dev Initializes the contract setting the deployer as the initial owner.\n */\n constructor() {\n _transferOwnership(_msgSender());\n }\n\n /**\n * @dev Throws if called by any account other than the owner.\n */\n modifier onlyOwner() {\n _checkOwner();\n _;\n }\n\n /**\n * @dev Returns the address of the current owner.\n */\n function owner() public view virtual returns (address) {\n return _owner;\n }\n\n /**\n * @dev Throws if the sender is not the owner.\n */\n function _checkOwner() internal view virtual {\n require(owner() == _msgSender(), \"Ownable: caller is not the owner\");\n }\n\n /**\n * @dev Leaves the contract without owner. It will not be possible to call\n * `onlyOwner` functions anymore. Can only be called by the current owner.\n *\n * NOTE: Renouncing ownership will leave the contract without an owner,\n * thereby removing any functionality that is only available to the owner.\n */\n function renounceOwnership() public virtual onlyOwner {\n _transferOwnership(address(0));\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Can only be called by the current owner.\n */\n function transferOwnership(address newOwner) public virtual onlyOwner {\n require(newOwner != address(0), \"Ownable: new owner is the zero address\");\n _transferOwnership(newOwner);\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Internal function without access restriction.\n */\n function _transferOwnership(address newOwner) internal virtual {\n address oldOwner = _owner;\n _owner = newOwner;\n emit OwnershipTransferred(oldOwner, newOwner);\n }\n}\n" + }, + "@openzeppelin/contracts/interfaces/draft-IERC1822.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.5.0) (interfaces/draft-IERC1822.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev ERC1822: Universal Upgradeable Proxy Standard (UUPS) documents a method for upgradeability through a simplified\n * proxy whose upgrades are fully controlled by the current implementation.\n */\ninterface IERC1822Proxiable {\n /**\n * @dev Returns the storage slot that the proxiable contract assumes is being used to store the implementation\n * address.\n *\n * IMPORTANT: A proxy pointing at a proxiable contract should not be considered proxiable itself, because this risks\n * bricking a proxy that upgrades to it, by delegating to itself until out of gas. Thus it is critical that this\n * function revert if invoked through a proxy.\n */\n function proxiableUUID() external view returns (bytes32);\n}\n" + }, + "@openzeppelin/contracts/interfaces/IERC3156FlashBorrower.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (interfaces/IERC3156FlashBorrower.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Interface of the ERC3156 FlashBorrower, as defined in\n * https://eips.ethereum.org/EIPS/eip-3156[ERC-3156].\n *\n * _Available since v4.1._\n */\ninterface IERC3156FlashBorrower {\n /**\n * @dev Receive a flash loan.\n * @param initiator The initiator of the loan.\n * @param token The loan currency.\n * @param amount The amount of tokens lent.\n * @param fee The additional amount of tokens to repay.\n * @param data Arbitrary data structure, intended to contain user-defined parameters.\n * @return The keccak256 hash of \"IERC3156FlashBorrower.onFlashLoan\"\n */\n function onFlashLoan(\n address initiator,\n address token,\n uint256 amount,\n uint256 fee,\n bytes calldata data\n ) external returns (bytes32);\n}\n" + }, + "@openzeppelin/contracts/interfaces/IERC3156FlashLender.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (interfaces/IERC3156FlashLender.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./IERC3156FlashBorrower.sol\";\n\n/**\n * @dev Interface of the ERC3156 FlashLender, as defined in\n * https://eips.ethereum.org/EIPS/eip-3156[ERC-3156].\n *\n * _Available since v4.1._\n */\ninterface IERC3156FlashLender {\n /**\n * @dev The amount of currency available to be lended.\n * @param token The loan currency.\n * @return The amount of `token` that can be borrowed.\n */\n function maxFlashLoan(address token) external view returns (uint256);\n\n /**\n * @dev The fee to be charged for a given loan.\n * @param token The loan currency.\n * @param amount The amount of tokens lent.\n * @return The amount of `token` to be charged for the loan, on top of the returned principal.\n */\n function flashFee(address token, uint256 amount) external view returns (uint256);\n\n /**\n * @dev Initiate a flash loan.\n * @param receiver The receiver of the tokens in the loan, and the receiver of the callback.\n * @param token The loan currency.\n * @param amount The amount of tokens lent.\n * @param data Arbitrary data structure, intended to contain user-defined parameters.\n */\n function flashLoan(\n IERC3156FlashBorrower receiver,\n address token,\n uint256 amount,\n bytes calldata data\n ) external returns (bool);\n}\n" + }, + "@openzeppelin/contracts/interfaces/IERC721Metadata.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (interfaces/IERC721Metadata.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../token/ERC721/extensions/IERC721Metadata.sol\";\n" + }, + "@openzeppelin/contracts/proxy/beacon/IBeacon.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (proxy/beacon/IBeacon.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev This is the interface that {BeaconProxy} expects of its beacon.\n */\ninterface IBeacon {\n /**\n * @dev Must return an address that can be used as a delegate call target.\n *\n * {BeaconProxy} will check that this address is a contract.\n */\n function implementation() external view returns (address);\n}\n" + }, + "@openzeppelin/contracts/proxy/ERC1967/ERC1967Proxy.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (proxy/ERC1967/ERC1967Proxy.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../Proxy.sol\";\nimport \"./ERC1967Upgrade.sol\";\n\n/**\n * @dev This contract implements an upgradeable proxy. It is upgradeable because calls are delegated to an\n * implementation address that can be changed. This address is stored in storage in the location specified by\n * https://eips.ethereum.org/EIPS/eip-1967[EIP1967], so that it doesn't conflict with the storage layout of the\n * implementation behind the proxy.\n */\ncontract ERC1967Proxy is Proxy, ERC1967Upgrade {\n /**\n * @dev Initializes the upgradeable proxy with an initial implementation specified by `_logic`.\n *\n * If `_data` is nonempty, it's used as data in a delegate call to `_logic`. This will typically be an encoded\n * function call, and allows initializing the storage of the proxy like a Solidity constructor.\n */\n constructor(address _logic, bytes memory _data) payable {\n _upgradeToAndCall(_logic, _data, false);\n }\n\n /**\n * @dev Returns the current implementation address.\n */\n function _implementation() internal view virtual override returns (address impl) {\n return ERC1967Upgrade._getImplementation();\n }\n}\n" + }, + "@openzeppelin/contracts/proxy/ERC1967/ERC1967Upgrade.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.5.0) (proxy/ERC1967/ERC1967Upgrade.sol)\n\npragma solidity ^0.8.2;\n\nimport \"../beacon/IBeacon.sol\";\nimport \"../../interfaces/draft-IERC1822.sol\";\nimport \"../../utils/Address.sol\";\nimport \"../../utils/StorageSlot.sol\";\n\n/**\n * @dev This abstract contract provides getters and event emitting update functions for\n * https://eips.ethereum.org/EIPS/eip-1967[EIP1967] slots.\n *\n * _Available since v4.1._\n *\n * @custom:oz-upgrades-unsafe-allow delegatecall\n */\nabstract contract ERC1967Upgrade {\n // This is the keccak-256 hash of \"eip1967.proxy.rollback\" subtracted by 1\n bytes32 private constant _ROLLBACK_SLOT = 0x4910fdfa16fed3260ed0e7147f7cc6da11a60208b5b9406d12a635614ffd9143;\n\n /**\n * @dev Storage slot with the address of the current implementation.\n * This is the keccak-256 hash of \"eip1967.proxy.implementation\" subtracted by 1, and is\n * validated in the constructor.\n */\n bytes32 internal constant _IMPLEMENTATION_SLOT = 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc;\n\n /**\n * @dev Emitted when the implementation is upgraded.\n */\n event Upgraded(address indexed implementation);\n\n /**\n * @dev Returns the current implementation address.\n */\n function _getImplementation() internal view returns (address) {\n return StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value;\n }\n\n /**\n * @dev Stores a new address in the EIP1967 implementation slot.\n */\n function _setImplementation(address newImplementation) private {\n require(Address.isContract(newImplementation), \"ERC1967: new implementation is not a contract\");\n StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value = newImplementation;\n }\n\n /**\n * @dev Perform implementation upgrade\n *\n * Emits an {Upgraded} event.\n */\n function _upgradeTo(address newImplementation) internal {\n _setImplementation(newImplementation);\n emit Upgraded(newImplementation);\n }\n\n /**\n * @dev Perform implementation upgrade with additional setup call.\n *\n * Emits an {Upgraded} event.\n */\n function _upgradeToAndCall(\n address newImplementation,\n bytes memory data,\n bool forceCall\n ) internal {\n _upgradeTo(newImplementation);\n if (data.length > 0 || forceCall) {\n Address.functionDelegateCall(newImplementation, data);\n }\n }\n\n /**\n * @dev Perform implementation upgrade with security checks for UUPS proxies, and additional setup call.\n *\n * Emits an {Upgraded} event.\n */\n function _upgradeToAndCallUUPS(\n address newImplementation,\n bytes memory data,\n bool forceCall\n ) internal {\n // Upgrades from old implementations will perform a rollback test. This test requires the new\n // implementation to upgrade back to the old, non-ERC1822 compliant, implementation. Removing\n // this special case will break upgrade paths from old UUPS implementation to new ones.\n if (StorageSlot.getBooleanSlot(_ROLLBACK_SLOT).value) {\n _setImplementation(newImplementation);\n } else {\n try IERC1822Proxiable(newImplementation).proxiableUUID() returns (bytes32 slot) {\n require(slot == _IMPLEMENTATION_SLOT, \"ERC1967Upgrade: unsupported proxiableUUID\");\n } catch {\n revert(\"ERC1967Upgrade: new implementation is not UUPS\");\n }\n _upgradeToAndCall(newImplementation, data, forceCall);\n }\n }\n\n /**\n * @dev Storage slot with the admin of the contract.\n * This is the keccak-256 hash of \"eip1967.proxy.admin\" subtracted by 1, and is\n * validated in the constructor.\n */\n bytes32 internal constant _ADMIN_SLOT = 0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103;\n\n /**\n * @dev Emitted when the admin account has changed.\n */\n event AdminChanged(address previousAdmin, address newAdmin);\n\n /**\n * @dev Returns the current admin.\n */\n function _getAdmin() internal view returns (address) {\n return StorageSlot.getAddressSlot(_ADMIN_SLOT).value;\n }\n\n /**\n * @dev Stores a new address in the EIP1967 admin slot.\n */\n function _setAdmin(address newAdmin) private {\n require(newAdmin != address(0), \"ERC1967: new admin is the zero address\");\n StorageSlot.getAddressSlot(_ADMIN_SLOT).value = newAdmin;\n }\n\n /**\n * @dev Changes the admin of the proxy.\n *\n * Emits an {AdminChanged} event.\n */\n function _changeAdmin(address newAdmin) internal {\n emit AdminChanged(_getAdmin(), newAdmin);\n _setAdmin(newAdmin);\n }\n\n /**\n * @dev The storage slot of the UpgradeableBeacon contract which defines the implementation for this proxy.\n * This is bytes32(uint256(keccak256('eip1967.proxy.beacon')) - 1)) and is validated in the constructor.\n */\n bytes32 internal constant _BEACON_SLOT = 0xa3f0ad74e5423aebfd80d3ef4346578335a9a72aeaee59ff6cb3582b35133d50;\n\n /**\n * @dev Emitted when the beacon is upgraded.\n */\n event BeaconUpgraded(address indexed beacon);\n\n /**\n * @dev Returns the current beacon.\n */\n function _getBeacon() internal view returns (address) {\n return StorageSlot.getAddressSlot(_BEACON_SLOT).value;\n }\n\n /**\n * @dev Stores a new beacon in the EIP1967 beacon slot.\n */\n function _setBeacon(address newBeacon) private {\n require(Address.isContract(newBeacon), \"ERC1967: new beacon is not a contract\");\n require(\n Address.isContract(IBeacon(newBeacon).implementation()),\n \"ERC1967: beacon implementation is not a contract\"\n );\n StorageSlot.getAddressSlot(_BEACON_SLOT).value = newBeacon;\n }\n\n /**\n * @dev Perform beacon upgrade with additional setup call. Note: This upgrades the address of the beacon, it does\n * not upgrade the implementation contained in the beacon (see {UpgradeableBeacon-_setImplementation} for that).\n *\n * Emits a {BeaconUpgraded} event.\n */\n function _upgradeBeaconToAndCall(\n address newBeacon,\n bytes memory data,\n bool forceCall\n ) internal {\n _setBeacon(newBeacon);\n emit BeaconUpgraded(newBeacon);\n if (data.length > 0 || forceCall) {\n Address.functionDelegateCall(IBeacon(newBeacon).implementation(), data);\n }\n }\n}\n" + }, + "@openzeppelin/contracts/proxy/Proxy.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.6.0) (proxy/Proxy.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev This abstract contract provides a fallback function that delegates all calls to another contract using the EVM\n * instruction `delegatecall`. We refer to the second contract as the _implementation_ behind the proxy, and it has to\n * be specified by overriding the virtual {_implementation} function.\n *\n * Additionally, delegation to the implementation can be triggered manually through the {_fallback} function, or to a\n * different contract through the {_delegate} function.\n *\n * The success and return data of the delegated call will be returned back to the caller of the proxy.\n */\nabstract contract Proxy {\n /**\n * @dev Delegates the current call to `implementation`.\n *\n * This function does not return to its internal call site, it will return directly to the external caller.\n */\n function _delegate(address implementation) internal virtual {\n assembly {\n // Copy msg.data. We take full control of memory in this inline assembly\n // block because it will not return to Solidity code. We overwrite the\n // Solidity scratch pad at memory position 0.\n calldatacopy(0, 0, calldatasize())\n\n // Call the implementation.\n // out and outsize are 0 because we don't know the size yet.\n let result := delegatecall(gas(), implementation, 0, calldatasize(), 0, 0)\n\n // Copy the returned data.\n returndatacopy(0, 0, returndatasize())\n\n switch result\n // delegatecall returns 0 on error.\n case 0 {\n revert(0, returndatasize())\n }\n default {\n return(0, returndatasize())\n }\n }\n }\n\n /**\n * @dev This is a virtual function that should be overridden so it returns the address to which the fallback function\n * and {_fallback} should delegate.\n */\n function _implementation() internal view virtual returns (address);\n\n /**\n * @dev Delegates the current call to the address returned by `_implementation()`.\n *\n * This function does not return to its internal call site, it will return directly to the external caller.\n */\n function _fallback() internal virtual {\n _beforeFallback();\n _delegate(_implementation());\n }\n\n /**\n * @dev Fallback function that delegates calls to the address returned by `_implementation()`. Will run if no other\n * function in the contract matches the call data.\n */\n fallback() external payable virtual {\n _fallback();\n }\n\n /**\n * @dev Fallback function that delegates calls to the address returned by `_implementation()`. Will run if call data\n * is empty.\n */\n receive() external payable virtual {\n _fallback();\n }\n\n /**\n * @dev Hook that is called before falling back to the implementation. Can happen as part of a manual `_fallback`\n * call, or as part of the Solidity `fallback` or `receive` functions.\n *\n * If overridden should call `super._beforeFallback()`.\n */\n function _beforeFallback() internal virtual {}\n}\n" + }, + "@openzeppelin/contracts/token/ERC20/ERC20.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (token/ERC20/ERC20.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./IERC20.sol\";\nimport \"./extensions/IERC20Metadata.sol\";\nimport \"../../utils/Context.sol\";\n\n/**\n * @dev Implementation of the {IERC20} interface.\n *\n * This implementation is agnostic to the way tokens are created. This means\n * that a supply mechanism has to be added in a derived contract using {_mint}.\n * For a generic mechanism see {ERC20PresetMinterPauser}.\n *\n * TIP: For a detailed writeup see our guide\n * https://forum.zeppelin.solutions/t/how-to-implement-erc20-supply-mechanisms/226[How\n * to implement supply mechanisms].\n *\n * We have followed general OpenZeppelin Contracts guidelines: functions revert\n * instead returning `false` on failure. This behavior is nonetheless\n * conventional and does not conflict with the expectations of ERC20\n * applications.\n *\n * Additionally, an {Approval} event is emitted on calls to {transferFrom}.\n * This allows applications to reconstruct the allowance for all accounts just\n * by listening to said events. Other implementations of the EIP may not emit\n * these events, as it isn't required by the specification.\n *\n * Finally, the non-standard {decreaseAllowance} and {increaseAllowance}\n * functions have been added to mitigate the well-known issues around setting\n * allowances. See {IERC20-approve}.\n */\ncontract ERC20 is Context, IERC20, IERC20Metadata {\n mapping(address => uint256) private _balances;\n\n mapping(address => mapping(address => uint256)) private _allowances;\n\n uint256 private _totalSupply;\n\n string private _name;\n string private _symbol;\n\n /**\n * @dev Sets the values for {name} and {symbol}.\n *\n * The default value of {decimals} is 18. To select a different value for\n * {decimals} you should overload it.\n *\n * All two of these values are immutable: they can only be set once during\n * construction.\n */\n constructor(string memory name_, string memory symbol_) {\n _name = name_;\n _symbol = symbol_;\n }\n\n /**\n * @dev Returns the name of the token.\n */\n function name() public view virtual override returns (string memory) {\n return _name;\n }\n\n /**\n * @dev Returns the symbol of the token, usually a shorter version of the\n * name.\n */\n function symbol() public view virtual override returns (string memory) {\n return _symbol;\n }\n\n /**\n * @dev Returns the number of decimals used to get its user representation.\n * For example, if `decimals` equals `2`, a balance of `505` tokens should\n * be displayed to a user as `5.05` (`505 / 10 ** 2`).\n *\n * Tokens usually opt for a value of 18, imitating the relationship between\n * Ether and Wei. This is the value {ERC20} uses, unless this function is\n * overridden;\n *\n * NOTE: This information is only used for _display_ purposes: it in\n * no way affects any of the arithmetic of the contract, including\n * {IERC20-balanceOf} and {IERC20-transfer}.\n */\n function decimals() public view virtual override returns (uint8) {\n return 18;\n }\n\n /**\n * @dev See {IERC20-totalSupply}.\n */\n function totalSupply() public view virtual override returns (uint256) {\n return _totalSupply;\n }\n\n /**\n * @dev See {IERC20-balanceOf}.\n */\n function balanceOf(address account) public view virtual override returns (uint256) {\n return _balances[account];\n }\n\n /**\n * @dev See {IERC20-transfer}.\n *\n * Requirements:\n *\n * - `to` cannot be the zero address.\n * - the caller must have a balance of at least `amount`.\n */\n function transfer(address to, uint256 amount) public virtual override returns (bool) {\n address owner = _msgSender();\n _transfer(owner, to, amount);\n return true;\n }\n\n /**\n * @dev See {IERC20-allowance}.\n */\n function allowance(address owner, address spender) public view virtual override returns (uint256) {\n return _allowances[owner][spender];\n }\n\n /**\n * @dev See {IERC20-approve}.\n *\n * NOTE: If `amount` is the maximum `uint256`, the allowance is not updated on\n * `transferFrom`. This is semantically equivalent to an infinite approval.\n *\n * Requirements:\n *\n * - `spender` cannot be the zero address.\n */\n function approve(address spender, uint256 amount) public virtual override returns (bool) {\n address owner = _msgSender();\n _approve(owner, spender, amount);\n return true;\n }\n\n /**\n * @dev See {IERC20-transferFrom}.\n *\n * Emits an {Approval} event indicating the updated allowance. This is not\n * required by the EIP. See the note at the beginning of {ERC20}.\n *\n * NOTE: Does not update the allowance if the current allowance\n * is the maximum `uint256`.\n *\n * Requirements:\n *\n * - `from` and `to` cannot be the zero address.\n * - `from` must have a balance of at least `amount`.\n * - the caller must have allowance for ``from``'s tokens of at least\n * `amount`.\n */\n function transferFrom(\n address from,\n address to,\n uint256 amount\n ) public virtual override returns (bool) {\n address spender = _msgSender();\n _spendAllowance(from, spender, amount);\n _transfer(from, to, amount);\n return true;\n }\n\n /**\n * @dev Atomically increases the allowance granted to `spender` by the caller.\n *\n * This is an alternative to {approve} that can be used as a mitigation for\n * problems described in {IERC20-approve}.\n *\n * Emits an {Approval} event indicating the updated allowance.\n *\n * Requirements:\n *\n * - `spender` cannot be the zero address.\n */\n function increaseAllowance(address spender, uint256 addedValue) public virtual returns (bool) {\n address owner = _msgSender();\n _approve(owner, spender, allowance(owner, spender) + addedValue);\n return true;\n }\n\n /**\n * @dev Atomically decreases the allowance granted to `spender` by the caller.\n *\n * This is an alternative to {approve} that can be used as a mitigation for\n * problems described in {IERC20-approve}.\n *\n * Emits an {Approval} event indicating the updated allowance.\n *\n * Requirements:\n *\n * - `spender` cannot be the zero address.\n * - `spender` must have allowance for the caller of at least\n * `subtractedValue`.\n */\n function decreaseAllowance(address spender, uint256 subtractedValue) public virtual returns (bool) {\n address owner = _msgSender();\n uint256 currentAllowance = allowance(owner, spender);\n require(currentAllowance >= subtractedValue, \"ERC20: decreased allowance below zero\");\n unchecked {\n _approve(owner, spender, currentAllowance - subtractedValue);\n }\n\n return true;\n }\n\n /**\n * @dev Moves `amount` of tokens from `from` to `to`.\n *\n * This internal function is equivalent to {transfer}, and can be used to\n * e.g. implement automatic token fees, slashing mechanisms, etc.\n *\n * Emits a {Transfer} event.\n *\n * Requirements:\n *\n * - `from` cannot be the zero address.\n * - `to` cannot be the zero address.\n * - `from` must have a balance of at least `amount`.\n */\n function _transfer(\n address from,\n address to,\n uint256 amount\n ) internal virtual {\n require(from != address(0), \"ERC20: transfer from the zero address\");\n require(to != address(0), \"ERC20: transfer to the zero address\");\n\n _beforeTokenTransfer(from, to, amount);\n\n uint256 fromBalance = _balances[from];\n require(fromBalance >= amount, \"ERC20: transfer amount exceeds balance\");\n unchecked {\n _balances[from] = fromBalance - amount;\n }\n _balances[to] += amount;\n\n emit Transfer(from, to, amount);\n\n _afterTokenTransfer(from, to, amount);\n }\n\n /** @dev Creates `amount` tokens and assigns them to `account`, increasing\n * the total supply.\n *\n * Emits a {Transfer} event with `from` set to the zero address.\n *\n * Requirements:\n *\n * - `account` cannot be the zero address.\n */\n function _mint(address account, uint256 amount) internal virtual {\n require(account != address(0), \"ERC20: mint to the zero address\");\n\n _beforeTokenTransfer(address(0), account, amount);\n\n _totalSupply += amount;\n _balances[account] += amount;\n emit Transfer(address(0), account, amount);\n\n _afterTokenTransfer(address(0), account, amount);\n }\n\n /**\n * @dev Destroys `amount` tokens from `account`, reducing the\n * total supply.\n *\n * Emits a {Transfer} event with `to` set to the zero address.\n *\n * Requirements:\n *\n * - `account` cannot be the zero address.\n * - `account` must have at least `amount` tokens.\n */\n function _burn(address account, uint256 amount) internal virtual {\n require(account != address(0), \"ERC20: burn from the zero address\");\n\n _beforeTokenTransfer(account, address(0), amount);\n\n uint256 accountBalance = _balances[account];\n require(accountBalance >= amount, \"ERC20: burn amount exceeds balance\");\n unchecked {\n _balances[account] = accountBalance - amount;\n }\n _totalSupply -= amount;\n\n emit Transfer(account, address(0), amount);\n\n _afterTokenTransfer(account, address(0), amount);\n }\n\n /**\n * @dev Sets `amount` as the allowance of `spender` over the `owner` s tokens.\n *\n * This internal function is equivalent to `approve`, and can be used to\n * e.g. set automatic allowances for certain subsystems, etc.\n *\n * Emits an {Approval} event.\n *\n * Requirements:\n *\n * - `owner` cannot be the zero address.\n * - `spender` cannot be the zero address.\n */\n function _approve(\n address owner,\n address spender,\n uint256 amount\n ) internal virtual {\n require(owner != address(0), \"ERC20: approve from the zero address\");\n require(spender != address(0), \"ERC20: approve to the zero address\");\n\n _allowances[owner][spender] = amount;\n emit Approval(owner, spender, amount);\n }\n\n /**\n * @dev Updates `owner` s allowance for `spender` based on spent `amount`.\n *\n * Does not update the allowance amount in case of infinite allowance.\n * Revert if not enough allowance is available.\n *\n * Might emit an {Approval} event.\n */\n function _spendAllowance(\n address owner,\n address spender,\n uint256 amount\n ) internal virtual {\n uint256 currentAllowance = allowance(owner, spender);\n if (currentAllowance != type(uint256).max) {\n require(currentAllowance >= amount, \"ERC20: insufficient allowance\");\n unchecked {\n _approve(owner, spender, currentAllowance - amount);\n }\n }\n }\n\n /**\n * @dev Hook that is called before any transfer of tokens. This includes\n * minting and burning.\n *\n * Calling conditions:\n *\n * - when `from` and `to` are both non-zero, `amount` of ``from``'s tokens\n * will be transferred to `to`.\n * - when `from` is zero, `amount` tokens will be minted for `to`.\n * - when `to` is zero, `amount` of ``from``'s tokens will be burned.\n * - `from` and `to` are never both zero.\n *\n * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].\n */\n function _beforeTokenTransfer(\n address from,\n address to,\n uint256 amount\n ) internal virtual {}\n\n /**\n * @dev Hook that is called after any transfer of tokens. This includes\n * minting and burning.\n *\n * Calling conditions:\n *\n * - when `from` and `to` are both non-zero, `amount` of ``from``'s tokens\n * has been transferred to `to`.\n * - when `from` is zero, `amount` tokens have been minted for `to`.\n * - when `to` is zero, `amount` of ``from``'s tokens have been burned.\n * - `from` and `to` are never both zero.\n *\n * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].\n */\n function _afterTokenTransfer(\n address from,\n address to,\n uint256 amount\n ) internal virtual {}\n}\n" + }, + "@openzeppelin/contracts/token/ERC20/extensions/draft-ERC20Permit.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.6.0) (token/ERC20/extensions/draft-ERC20Permit.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./draft-IERC20Permit.sol\";\nimport \"../ERC20.sol\";\nimport \"../../../utils/cryptography/draft-EIP712.sol\";\nimport \"../../../utils/cryptography/ECDSA.sol\";\nimport \"../../../utils/Counters.sol\";\n\n/**\n * @dev Implementation of the ERC20 Permit extension allowing approvals to be made via signatures, as defined in\n * https://eips.ethereum.org/EIPS/eip-2612[EIP-2612].\n *\n * Adds the {permit} method, which can be used to change an account's ERC20 allowance (see {IERC20-allowance}) by\n * presenting a message signed by the account. By not relying on `{IERC20-approve}`, the token holder account doesn't\n * need to send a transaction, and thus is not required to hold Ether at all.\n *\n * _Available since v3.4._\n */\nabstract contract ERC20Permit is ERC20, IERC20Permit, EIP712 {\n using Counters for Counters.Counter;\n\n mapping(address => Counters.Counter) private _nonces;\n\n // solhint-disable-next-line var-name-mixedcase\n bytes32 private constant _PERMIT_TYPEHASH =\n keccak256(\"Permit(address owner,address spender,uint256 value,uint256 nonce,uint256 deadline)\");\n /**\n * @dev In previous versions `_PERMIT_TYPEHASH` was declared as `immutable`.\n * However, to ensure consistency with the upgradeable transpiler, we will continue\n * to reserve a slot.\n * @custom:oz-renamed-from _PERMIT_TYPEHASH\n */\n // solhint-disable-next-line var-name-mixedcase\n bytes32 private _PERMIT_TYPEHASH_DEPRECATED_SLOT;\n\n /**\n * @dev Initializes the {EIP712} domain separator using the `name` parameter, and setting `version` to `\"1\"`.\n *\n * It's a good idea to use the same `name` that is defined as the ERC20 token name.\n */\n constructor(string memory name) EIP712(name, \"1\") {}\n\n /**\n * @dev See {IERC20Permit-permit}.\n */\n function permit(\n address owner,\n address spender,\n uint256 value,\n uint256 deadline,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) public virtual override {\n require(block.timestamp <= deadline, \"ERC20Permit: expired deadline\");\n\n bytes32 structHash = keccak256(abi.encode(_PERMIT_TYPEHASH, owner, spender, value, _useNonce(owner), deadline));\n\n bytes32 hash = _hashTypedDataV4(structHash);\n\n address signer = ECDSA.recover(hash, v, r, s);\n require(signer == owner, \"ERC20Permit: invalid signature\");\n\n _approve(owner, spender, value);\n }\n\n /**\n * @dev See {IERC20Permit-nonces}.\n */\n function nonces(address owner) public view virtual override returns (uint256) {\n return _nonces[owner].current();\n }\n\n /**\n * @dev See {IERC20Permit-DOMAIN_SEPARATOR}.\n */\n // solhint-disable-next-line func-name-mixedcase\n function DOMAIN_SEPARATOR() external view override returns (bytes32) {\n return _domainSeparatorV4();\n }\n\n /**\n * @dev \"Consume a nonce\": return the current value and increment.\n *\n * _Available since v4.1._\n */\n function _useNonce(address owner) internal virtual returns (uint256 current) {\n Counters.Counter storage nonce = _nonces[owner];\n current = nonce.current();\n nonce.increment();\n }\n}\n" + }, + "@openzeppelin/contracts/token/ERC20/extensions/draft-IERC20Permit.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (token/ERC20/extensions/draft-IERC20Permit.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Interface of the ERC20 Permit extension allowing approvals to be made via signatures, as defined in\n * https://eips.ethereum.org/EIPS/eip-2612[EIP-2612].\n *\n * Adds the {permit} method, which can be used to change an account's ERC20 allowance (see {IERC20-allowance}) by\n * presenting a message signed by the account. By not relying on {IERC20-approve}, the token holder account doesn't\n * need to send a transaction, and thus is not required to hold Ether at all.\n */\ninterface IERC20Permit {\n /**\n * @dev Sets `value` as the allowance of `spender` over ``owner``'s tokens,\n * given ``owner``'s signed approval.\n *\n * IMPORTANT: The same issues {IERC20-approve} has related to transaction\n * ordering also apply here.\n *\n * Emits an {Approval} event.\n *\n * Requirements:\n *\n * - `spender` cannot be the zero address.\n * - `deadline` must be a timestamp in the future.\n * - `v`, `r` and `s` must be a valid `secp256k1` signature from `owner`\n * over the EIP712-formatted function arguments.\n * - the signature must use ``owner``'s current nonce (see {nonces}).\n *\n * For more information on the signature format, see the\n * https://eips.ethereum.org/EIPS/eip-2612#specification[relevant EIP\n * section].\n */\n function permit(\n address owner,\n address spender,\n uint256 value,\n uint256 deadline,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) external;\n\n /**\n * @dev Returns the current nonce for `owner`. This value must be\n * included whenever a signature is generated for {permit}.\n *\n * Every successful call to {permit} increases ``owner``'s nonce by one. This\n * prevents a signature from being used multiple times.\n */\n function nonces(address owner) external view returns (uint256);\n\n /**\n * @dev Returns the domain separator used in the encoding of the signature for {permit}, as defined by {EIP712}.\n */\n // solhint-disable-next-line func-name-mixedcase\n function DOMAIN_SEPARATOR() external view returns (bytes32);\n}\n" + }, + "@openzeppelin/contracts/token/ERC20/extensions/IERC20Metadata.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (token/ERC20/extensions/IERC20Metadata.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../IERC20.sol\";\n\n/**\n * @dev Interface for the optional metadata functions from the ERC20 standard.\n *\n * _Available since v4.1._\n */\ninterface IERC20Metadata is IERC20 {\n /**\n * @dev Returns the name of the token.\n */\n function name() external view returns (string memory);\n\n /**\n * @dev Returns the symbol of the token.\n */\n function symbol() external view returns (string memory);\n\n /**\n * @dev Returns the decimals places of the token.\n */\n function decimals() external view returns (uint8);\n}\n" + }, + "@openzeppelin/contracts/token/ERC20/IERC20.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.6.0) (token/ERC20/IERC20.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Interface of the ERC20 standard as defined in the EIP.\n */\ninterface IERC20 {\n /**\n * @dev Emitted when `value` tokens are moved from one account (`from`) to\n * another (`to`).\n *\n * Note that `value` may be zero.\n */\n event Transfer(address indexed from, address indexed to, uint256 value);\n\n /**\n * @dev Emitted when the allowance of a `spender` for an `owner` is set by\n * a call to {approve}. `value` is the new allowance.\n */\n event Approval(address indexed owner, address indexed spender, uint256 value);\n\n /**\n * @dev Returns the amount of tokens in existence.\n */\n function totalSupply() external view returns (uint256);\n\n /**\n * @dev Returns the amount of tokens owned by `account`.\n */\n function balanceOf(address account) external view returns (uint256);\n\n /**\n * @dev Moves `amount` tokens from the caller's account to `to`.\n *\n * Returns a boolean value indicating whether the operation succeeded.\n *\n * Emits a {Transfer} event.\n */\n function transfer(address to, uint256 amount) external returns (bool);\n\n /**\n * @dev Returns the remaining number of tokens that `spender` will be\n * allowed to spend on behalf of `owner` through {transferFrom}. This is\n * zero by default.\n *\n * This value changes when {approve} or {transferFrom} are called.\n */\n function allowance(address owner, address spender) external view returns (uint256);\n\n /**\n * @dev Sets `amount` as the allowance of `spender` over the caller's tokens.\n *\n * Returns a boolean value indicating whether the operation succeeded.\n *\n * IMPORTANT: Beware that changing an allowance with this method brings the risk\n * that someone may use both the old and the new allowance by unfortunate\n * transaction ordering. One possible solution to mitigate this race\n * condition is to first reduce the spender's allowance to 0 and set the\n * desired value afterwards:\n * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729\n *\n * Emits an {Approval} event.\n */\n function approve(address spender, uint256 amount) external returns (bool);\n\n /**\n * @dev Moves `amount` tokens from `from` to `to` using the\n * allowance mechanism. `amount` is then deducted from the caller's\n * allowance.\n *\n * Returns a boolean value indicating whether the operation succeeded.\n *\n * Emits a {Transfer} event.\n */\n function transferFrom(\n address from,\n address to,\n uint256 amount\n ) external returns (bool);\n}\n" + }, + "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (token/ERC20/utils/SafeERC20.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../IERC20.sol\";\nimport \"../extensions/draft-IERC20Permit.sol\";\nimport \"../../../utils/Address.sol\";\n\n/**\n * @title SafeERC20\n * @dev Wrappers around ERC20 operations that throw on failure (when the token\n * contract returns false). Tokens that return no value (and instead revert or\n * throw on failure) are also supported, non-reverting calls are assumed to be\n * successful.\n * To use this library you can add a `using SafeERC20 for IERC20;` statement to your contract,\n * which allows you to call the safe operations as `token.safeTransfer(...)`, etc.\n */\nlibrary SafeERC20 {\n using Address for address;\n\n function safeTransfer(\n IERC20 token,\n address to,\n uint256 value\n ) internal {\n _callOptionalReturn(token, abi.encodeWithSelector(token.transfer.selector, to, value));\n }\n\n function safeTransferFrom(\n IERC20 token,\n address from,\n address to,\n uint256 value\n ) internal {\n _callOptionalReturn(token, abi.encodeWithSelector(token.transferFrom.selector, from, to, value));\n }\n\n /**\n * @dev Deprecated. This function has issues similar to the ones found in\n * {IERC20-approve}, and its usage is discouraged.\n *\n * Whenever possible, use {safeIncreaseAllowance} and\n * {safeDecreaseAllowance} instead.\n */\n function safeApprove(\n IERC20 token,\n address spender,\n uint256 value\n ) internal {\n // safeApprove should only be called when setting an initial allowance,\n // or when resetting it to zero. To increase and decrease it, use\n // 'safeIncreaseAllowance' and 'safeDecreaseAllowance'\n require(\n (value == 0) || (token.allowance(address(this), spender) == 0),\n \"SafeERC20: approve from non-zero to non-zero allowance\"\n );\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, value));\n }\n\n function safeIncreaseAllowance(\n IERC20 token,\n address spender,\n uint256 value\n ) internal {\n uint256 newAllowance = token.allowance(address(this), spender) + value;\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));\n }\n\n function safeDecreaseAllowance(\n IERC20 token,\n address spender,\n uint256 value\n ) internal {\n unchecked {\n uint256 oldAllowance = token.allowance(address(this), spender);\n require(oldAllowance >= value, \"SafeERC20: decreased allowance below zero\");\n uint256 newAllowance = oldAllowance - value;\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));\n }\n }\n\n function safePermit(\n IERC20Permit token,\n address owner,\n address spender,\n uint256 value,\n uint256 deadline,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) internal {\n uint256 nonceBefore = token.nonces(owner);\n token.permit(owner, spender, value, deadline, v, r, s);\n uint256 nonceAfter = token.nonces(owner);\n require(nonceAfter == nonceBefore + 1, \"SafeERC20: permit did not succeed\");\n }\n\n /**\n * @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement\n * on the return value: the return value is optional (but if data is returned, it must not be false).\n * @param token The token targeted by the call.\n * @param data The call data (encoded using abi.encode or one of its variants).\n */\n function _callOptionalReturn(IERC20 token, bytes memory data) private {\n // We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since\n // we're implementing it ourselves. We use {Address.functionCall} to perform this call, which verifies that\n // the target address contains contract code and also asserts for success in the low-level call.\n\n bytes memory returndata = address(token).functionCall(data, \"SafeERC20: low-level call failed\");\n if (returndata.length > 0) {\n // Return data is optional\n require(abi.decode(returndata, (bool)), \"SafeERC20: ERC20 operation did not succeed\");\n }\n }\n}\n" + }, + "@openzeppelin/contracts/token/ERC721/extensions/IERC721Metadata.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (token/ERC721/extensions/IERC721Metadata.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../IERC721.sol\";\n\n/**\n * @title ERC-721 Non-Fungible Token Standard, optional metadata extension\n * @dev See https://eips.ethereum.org/EIPS/eip-721\n */\ninterface IERC721Metadata is IERC721 {\n /**\n * @dev Returns the token collection name.\n */\n function name() external view returns (string memory);\n\n /**\n * @dev Returns the token collection symbol.\n */\n function symbol() external view returns (string memory);\n\n /**\n * @dev Returns the Uniform Resource Identifier (URI) for `tokenId` token.\n */\n function tokenURI(uint256 tokenId) external view returns (string memory);\n}\n" + }, + "@openzeppelin/contracts/token/ERC721/IERC721.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (token/ERC721/IERC721.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../../utils/introspection/IERC165.sol\";\n\n/**\n * @dev Required interface of an ERC721 compliant contract.\n */\ninterface IERC721 is IERC165 {\n /**\n * @dev Emitted when `tokenId` token is transferred from `from` to `to`.\n */\n event Transfer(address indexed from, address indexed to, uint256 indexed tokenId);\n\n /**\n * @dev Emitted when `owner` enables `approved` to manage the `tokenId` token.\n */\n event Approval(address indexed owner, address indexed approved, uint256 indexed tokenId);\n\n /**\n * @dev Emitted when `owner` enables or disables (`approved`) `operator` to manage all of its assets.\n */\n event ApprovalForAll(address indexed owner, address indexed operator, bool approved);\n\n /**\n * @dev Returns the number of tokens in ``owner``'s account.\n */\n function balanceOf(address owner) external view returns (uint256 balance);\n\n /**\n * @dev Returns the owner of the `tokenId` token.\n *\n * Requirements:\n *\n * - `tokenId` must exist.\n */\n function ownerOf(uint256 tokenId) external view returns (address owner);\n\n /**\n * @dev Safely transfers `tokenId` token from `from` to `to`.\n *\n * Requirements:\n *\n * - `from` cannot be the zero address.\n * - `to` cannot be the zero address.\n * - `tokenId` token must exist and be owned by `from`.\n * - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}.\n * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.\n *\n * Emits a {Transfer} event.\n */\n function safeTransferFrom(\n address from,\n address to,\n uint256 tokenId,\n bytes calldata data\n ) external;\n\n /**\n * @dev Safely transfers `tokenId` token from `from` to `to`, checking first that contract recipients\n * are aware of the ERC721 protocol to prevent tokens from being forever locked.\n *\n * Requirements:\n *\n * - `from` cannot be the zero address.\n * - `to` cannot be the zero address.\n * - `tokenId` token must exist and be owned by `from`.\n * - If the caller is not `from`, it must have been allowed to move this token by either {approve} or {setApprovalForAll}.\n * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.\n *\n * Emits a {Transfer} event.\n */\n function safeTransferFrom(\n address from,\n address to,\n uint256 tokenId\n ) external;\n\n /**\n * @dev Transfers `tokenId` token from `from` to `to`.\n *\n * WARNING: Usage of this method is discouraged, use {safeTransferFrom} whenever possible.\n *\n * Requirements:\n *\n * - `from` cannot be the zero address.\n * - `to` cannot be the zero address.\n * - `tokenId` token must be owned by `from`.\n * - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}.\n *\n * Emits a {Transfer} event.\n */\n function transferFrom(\n address from,\n address to,\n uint256 tokenId\n ) external;\n\n /**\n * @dev Gives permission to `to` to transfer `tokenId` token to another account.\n * The approval is cleared when the token is transferred.\n *\n * Only a single account can be approved at a time, so approving the zero address clears previous approvals.\n *\n * Requirements:\n *\n * - The caller must own the token or be an approved operator.\n * - `tokenId` must exist.\n *\n * Emits an {Approval} event.\n */\n function approve(address to, uint256 tokenId) external;\n\n /**\n * @dev Approve or remove `operator` as an operator for the caller.\n * Operators can call {transferFrom} or {safeTransferFrom} for any token owned by the caller.\n *\n * Requirements:\n *\n * - The `operator` cannot be the caller.\n *\n * Emits an {ApprovalForAll} event.\n */\n function setApprovalForAll(address operator, bool _approved) external;\n\n /**\n * @dev Returns the account approved for `tokenId` token.\n *\n * Requirements:\n *\n * - `tokenId` must exist.\n */\n function getApproved(uint256 tokenId) external view returns (address operator);\n\n /**\n * @dev Returns if the `operator` is allowed to manage all of the assets of `owner`.\n *\n * See {setApprovalForAll}\n */\n function isApprovedForAll(address owner, address operator) external view returns (bool);\n}\n" + }, + "@openzeppelin/contracts/utils/Address.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (utils/Address.sol)\n\npragma solidity ^0.8.1;\n\n/**\n * @dev Collection of functions related to the address type\n */\nlibrary Address {\n /**\n * @dev Returns true if `account` is a contract.\n *\n * [IMPORTANT]\n * ====\n * It is unsafe to assume that an address for which this function returns\n * false is an externally-owned account (EOA) and not a contract.\n *\n * Among others, `isContract` will return false for the following\n * types of addresses:\n *\n * - an externally-owned account\n * - a contract in construction\n * - an address where a contract will be created\n * - an address where a contract lived, but was destroyed\n * ====\n *\n * [IMPORTANT]\n * ====\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\n *\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\n * constructor.\n * ====\n */\n function isContract(address account) internal view returns (bool) {\n // This method relies on extcodesize/address.code.length, which returns 0\n // for contracts in construction, since the code is only stored at the end\n // of the constructor execution.\n\n return account.code.length > 0;\n }\n\n /**\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\n * `recipient`, forwarding all available gas and reverting on errors.\n *\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\n * imposed by `transfer`, making them unable to receive funds via\n * `transfer`. {sendValue} removes this limitation.\n *\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\n *\n * IMPORTANT: because control is transferred to `recipient`, care must be\n * taken to not create reentrancy vulnerabilities. Consider using\n * {ReentrancyGuard} or the\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\n */\n function sendValue(address payable recipient, uint256 amount) internal {\n require(address(this).balance >= amount, \"Address: insufficient balance\");\n\n (bool success, ) = recipient.call{value: amount}(\"\");\n require(success, \"Address: unable to send value, recipient may have reverted\");\n }\n\n /**\n * @dev Performs a Solidity function call using a low level `call`. A\n * plain `call` is an unsafe replacement for a function call: use this\n * function instead.\n *\n * If `target` reverts with a revert reason, it is bubbled up by this\n * function (like regular Solidity function calls).\n *\n * Returns the raw returned data. To convert to the expected return value,\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\n *\n * Requirements:\n *\n * - `target` must be a contract.\n * - calling `target` with `data` must not revert.\n *\n * _Available since v3.1._\n */\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionCall(target, data, \"Address: low-level call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\n * `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, 0, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but also transferring `value` wei to `target`.\n *\n * Requirements:\n *\n * - the calling contract must have an ETH balance of at least `value`.\n * - the called Solidity function must be `payable`.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, value, \"Address: low-level call with value failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\n * with `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(address(this).balance >= value, \"Address: insufficient balance for call\");\n require(isContract(target), \"Address: call to non-contract\");\n\n (bool success, bytes memory returndata) = target.call{value: value}(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\n return functionStaticCall(target, data, \"Address: low-level static call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal view returns (bytes memory) {\n require(isContract(target), \"Address: static call to non-contract\");\n\n (bool success, bytes memory returndata) = target.staticcall(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a delegate call.\n *\n * _Available since v3.4._\n */\n function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionDelegateCall(target, data, \"Address: low-level delegate call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a delegate call.\n *\n * _Available since v3.4._\n */\n function functionDelegateCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(isContract(target), \"Address: delegate call to non-contract\");\n\n (bool success, bytes memory returndata) = target.delegatecall(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the\n * revert reason using the provided one.\n *\n * _Available since v4.3._\n */\n function verifyCallResult(\n bool success,\n bytes memory returndata,\n string memory errorMessage\n ) internal pure returns (bytes memory) {\n if (success) {\n return returndata;\n } else {\n // Look for revert reason and bubble it up if present\n if (returndata.length > 0) {\n // The easiest way to bubble the revert reason is using memory via assembly\n /// @solidity memory-safe-assembly\n assembly {\n let returndata_size := mload(returndata)\n revert(add(32, returndata), returndata_size)\n }\n } else {\n revert(errorMessage);\n }\n }\n }\n}\n" + }, + "@openzeppelin/contracts/utils/Context.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Provides information about the current execution context, including the\n * sender of the transaction and its data. While these are generally available\n * via msg.sender and msg.data, they should not be accessed in such a direct\n * manner, since when dealing with meta-transactions the account sending and\n * paying for execution may not be the actual sender (as far as an application\n * is concerned).\n *\n * This contract is only required for intermediate, library-like contracts.\n */\nabstract contract Context {\n function _msgSender() internal view virtual returns (address) {\n return msg.sender;\n }\n\n function _msgData() internal view virtual returns (bytes calldata) {\n return msg.data;\n }\n}\n" + }, + "@openzeppelin/contracts/utils/Counters.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (utils/Counters.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @title Counters\n * @author Matt Condon (@shrugs)\n * @dev Provides counters that can only be incremented, decremented or reset. This can be used e.g. to track the number\n * of elements in a mapping, issuing ERC721 ids, or counting request ids.\n *\n * Include with `using Counters for Counters.Counter;`\n */\nlibrary Counters {\n struct Counter {\n // This variable should never be directly accessed by users of the library: interactions must be restricted to\n // the library's function. As of Solidity v0.5.2, this cannot be enforced, though there is a proposal to add\n // this feature: see https://github.com/ethereum/solidity/issues/4637\n uint256 _value; // default: 0\n }\n\n function current(Counter storage counter) internal view returns (uint256) {\n return counter._value;\n }\n\n function increment(Counter storage counter) internal {\n unchecked {\n counter._value += 1;\n }\n }\n\n function decrement(Counter storage counter) internal {\n uint256 value = counter._value;\n require(value > 0, \"Counter: decrement overflow\");\n unchecked {\n counter._value = value - 1;\n }\n }\n\n function reset(Counter storage counter) internal {\n counter._value = 0;\n }\n}\n" + }, + "@openzeppelin/contracts/utils/cryptography/draft-EIP712.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (utils/cryptography/draft-EIP712.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./ECDSA.sol\";\n\n/**\n * @dev https://eips.ethereum.org/EIPS/eip-712[EIP 712] is a standard for hashing and signing of typed structured data.\n *\n * The encoding specified in the EIP is very generic, and such a generic implementation in Solidity is not feasible,\n * thus this contract does not implement the encoding itself. Protocols need to implement the type-specific encoding\n * they need in their contracts using a combination of `abi.encode` and `keccak256`.\n *\n * This contract implements the EIP 712 domain separator ({_domainSeparatorV4}) that is used as part of the encoding\n * scheme, and the final step of the encoding to obtain the message digest that is then signed via ECDSA\n * ({_hashTypedDataV4}).\n *\n * The implementation of the domain separator was designed to be as efficient as possible while still properly updating\n * the chain id to protect against replay attacks on an eventual fork of the chain.\n *\n * NOTE: This contract implements the version of the encoding known as \"v4\", as implemented by the JSON RPC method\n * https://docs.metamask.io/guide/signing-data.html[`eth_signTypedDataV4` in MetaMask].\n *\n * _Available since v3.4._\n */\nabstract contract EIP712 {\n /* solhint-disable var-name-mixedcase */\n // Cache the domain separator as an immutable value, but also store the chain id that it corresponds to, in order to\n // invalidate the cached domain separator if the chain id changes.\n bytes32 private immutable _CACHED_DOMAIN_SEPARATOR;\n uint256 private immutable _CACHED_CHAIN_ID;\n address private immutable _CACHED_THIS;\n\n bytes32 private immutable _HASHED_NAME;\n bytes32 private immutable _HASHED_VERSION;\n bytes32 private immutable _TYPE_HASH;\n\n /* solhint-enable var-name-mixedcase */\n\n /**\n * @dev Initializes the domain separator and parameter caches.\n *\n * The meaning of `name` and `version` is specified in\n * https://eips.ethereum.org/EIPS/eip-712#definition-of-domainseparator[EIP 712]:\n *\n * - `name`: the user readable name of the signing domain, i.e. the name of the DApp or the protocol.\n * - `version`: the current major version of the signing domain.\n *\n * NOTE: These parameters cannot be changed except through a xref:learn::upgrading-smart-contracts.adoc[smart\n * contract upgrade].\n */\n constructor(string memory name, string memory version) {\n bytes32 hashedName = keccak256(bytes(name));\n bytes32 hashedVersion = keccak256(bytes(version));\n bytes32 typeHash = keccak256(\n \"EIP712Domain(string name,string version,uint256 chainId,address verifyingContract)\"\n );\n _HASHED_NAME = hashedName;\n _HASHED_VERSION = hashedVersion;\n _CACHED_CHAIN_ID = block.chainid;\n _CACHED_DOMAIN_SEPARATOR = _buildDomainSeparator(typeHash, hashedName, hashedVersion);\n _CACHED_THIS = address(this);\n _TYPE_HASH = typeHash;\n }\n\n /**\n * @dev Returns the domain separator for the current chain.\n */\n function _domainSeparatorV4() internal view returns (bytes32) {\n if (address(this) == _CACHED_THIS && block.chainid == _CACHED_CHAIN_ID) {\n return _CACHED_DOMAIN_SEPARATOR;\n } else {\n return _buildDomainSeparator(_TYPE_HASH, _HASHED_NAME, _HASHED_VERSION);\n }\n }\n\n function _buildDomainSeparator(\n bytes32 typeHash,\n bytes32 nameHash,\n bytes32 versionHash\n ) private view returns (bytes32) {\n return keccak256(abi.encode(typeHash, nameHash, versionHash, block.chainid, address(this)));\n }\n\n /**\n * @dev Given an already https://eips.ethereum.org/EIPS/eip-712#definition-of-hashstruct[hashed struct], this\n * function returns the hash of the fully encoded EIP712 message for this domain.\n *\n * This hash can be used together with {ECDSA-recover} to obtain the signer of a message. For example:\n *\n * ```solidity\n * bytes32 digest = _hashTypedDataV4(keccak256(abi.encode(\n * keccak256(\"Mail(address to,string contents)\"),\n * mailTo,\n * keccak256(bytes(mailContents))\n * )));\n * address signer = ECDSA.recover(digest, signature);\n * ```\n */\n function _hashTypedDataV4(bytes32 structHash) internal view virtual returns (bytes32) {\n return ECDSA.toTypedDataHash(_domainSeparatorV4(), structHash);\n }\n}\n" + }, + "@openzeppelin/contracts/utils/cryptography/ECDSA.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (utils/cryptography/ECDSA.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../Strings.sol\";\n\n/**\n * @dev Elliptic Curve Digital Signature Algorithm (ECDSA) operations.\n *\n * These functions can be used to verify that a message was signed by the holder\n * of the private keys of a given address.\n */\nlibrary ECDSA {\n enum RecoverError {\n NoError,\n InvalidSignature,\n InvalidSignatureLength,\n InvalidSignatureS,\n InvalidSignatureV\n }\n\n function _throwError(RecoverError error) private pure {\n if (error == RecoverError.NoError) {\n return; // no error: do nothing\n } else if (error == RecoverError.InvalidSignature) {\n revert(\"ECDSA: invalid signature\");\n } else if (error == RecoverError.InvalidSignatureLength) {\n revert(\"ECDSA: invalid signature length\");\n } else if (error == RecoverError.InvalidSignatureS) {\n revert(\"ECDSA: invalid signature 's' value\");\n } else if (error == RecoverError.InvalidSignatureV) {\n revert(\"ECDSA: invalid signature 'v' value\");\n }\n }\n\n /**\n * @dev Returns the address that signed a hashed message (`hash`) with\n * `signature` or error string. This address can then be used for verification purposes.\n *\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\n * this function rejects them by requiring the `s` value to be in the lower\n * half order, and the `v` value to be either 27 or 28.\n *\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\n * verification to be secure: it is possible to craft signatures that\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\n * this is by receiving a hash of the original message (which may otherwise\n * be too long), and then calling {toEthSignedMessageHash} on it.\n *\n * Documentation for signature generation:\n * - with https://web3js.readthedocs.io/en/v1.3.4/web3-eth-accounts.html#sign[Web3.js]\n * - with https://docs.ethers.io/v5/api/signer/#Signer-signMessage[ethers]\n *\n * _Available since v4.3._\n */\n function tryRecover(bytes32 hash, bytes memory signature) internal pure returns (address, RecoverError) {\n // Check the signature length\n // - case 65: r,s,v signature (standard)\n // - case 64: r,vs signature (cf https://eips.ethereum.org/EIPS/eip-2098) _Available since v4.1._\n if (signature.length == 65) {\n bytes32 r;\n bytes32 s;\n uint8 v;\n // ecrecover takes the signature parameters, and the only way to get them\n // currently is to use assembly.\n /// @solidity memory-safe-assembly\n assembly {\n r := mload(add(signature, 0x20))\n s := mload(add(signature, 0x40))\n v := byte(0, mload(add(signature, 0x60)))\n }\n return tryRecover(hash, v, r, s);\n } else if (signature.length == 64) {\n bytes32 r;\n bytes32 vs;\n // ecrecover takes the signature parameters, and the only way to get them\n // currently is to use assembly.\n /// @solidity memory-safe-assembly\n assembly {\n r := mload(add(signature, 0x20))\n vs := mload(add(signature, 0x40))\n }\n return tryRecover(hash, r, vs);\n } else {\n return (address(0), RecoverError.InvalidSignatureLength);\n }\n }\n\n /**\n * @dev Returns the address that signed a hashed message (`hash`) with\n * `signature`. This address can then be used for verification purposes.\n *\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\n * this function rejects them by requiring the `s` value to be in the lower\n * half order, and the `v` value to be either 27 or 28.\n *\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\n * verification to be secure: it is possible to craft signatures that\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\n * this is by receiving a hash of the original message (which may otherwise\n * be too long), and then calling {toEthSignedMessageHash} on it.\n */\n function recover(bytes32 hash, bytes memory signature) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, signature);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Overload of {ECDSA-tryRecover} that receives the `r` and `vs` short-signature fields separately.\n *\n * See https://eips.ethereum.org/EIPS/eip-2098[EIP-2098 short signatures]\n *\n * _Available since v4.3._\n */\n function tryRecover(\n bytes32 hash,\n bytes32 r,\n bytes32 vs\n ) internal pure returns (address, RecoverError) {\n bytes32 s = vs & bytes32(0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff);\n uint8 v = uint8((uint256(vs) >> 255) + 27);\n return tryRecover(hash, v, r, s);\n }\n\n /**\n * @dev Overload of {ECDSA-recover} that receives the `r and `vs` short-signature fields separately.\n *\n * _Available since v4.2._\n */\n function recover(\n bytes32 hash,\n bytes32 r,\n bytes32 vs\n ) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, r, vs);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Overload of {ECDSA-tryRecover} that receives the `v`,\n * `r` and `s` signature fields separately.\n *\n * _Available since v4.3._\n */\n function tryRecover(\n bytes32 hash,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) internal pure returns (address, RecoverError) {\n // EIP-2 still allows signature malleability for ecrecover(). Remove this possibility and make the signature\n // unique. Appendix F in the Ethereum Yellow paper (https://ethereum.github.io/yellowpaper/paper.pdf), defines\n // the valid range for s in (301): 0 < s < secp256k1n ÷ 2 + 1, and for v in (302): v ∈ {27, 28}. Most\n // signatures from current libraries generate a unique signature with an s-value in the lower half order.\n //\n // If your library generates malleable signatures, such as s-values in the upper range, calculate a new s-value\n // with 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141 - s1 and flip v from 27 to 28 or\n // vice versa. If your library also generates signatures with 0/1 for v instead 27/28, add 27 to v to accept\n // these malleable signatures as well.\n if (uint256(s) > 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D576E7357A4501DDFE92F46681B20A0) {\n return (address(0), RecoverError.InvalidSignatureS);\n }\n if (v != 27 && v != 28) {\n return (address(0), RecoverError.InvalidSignatureV);\n }\n\n // If the signature is valid (and not malleable), return the signer address\n address signer = ecrecover(hash, v, r, s);\n if (signer == address(0)) {\n return (address(0), RecoverError.InvalidSignature);\n }\n\n return (signer, RecoverError.NoError);\n }\n\n /**\n * @dev Overload of {ECDSA-recover} that receives the `v`,\n * `r` and `s` signature fields separately.\n */\n function recover(\n bytes32 hash,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, v, r, s);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Returns an Ethereum Signed Message, created from a `hash`. This\n * produces hash corresponding to the one signed with the\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\n * JSON-RPC method as part of EIP-191.\n *\n * See {recover}.\n */\n function toEthSignedMessageHash(bytes32 hash) internal pure returns (bytes32) {\n // 32 is the length in bytes of hash,\n // enforced by the type signature above\n return keccak256(abi.encodePacked(\"\\x19Ethereum Signed Message:\\n32\", hash));\n }\n\n /**\n * @dev Returns an Ethereum Signed Message, created from `s`. This\n * produces hash corresponding to the one signed with the\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\n * JSON-RPC method as part of EIP-191.\n *\n * See {recover}.\n */\n function toEthSignedMessageHash(bytes memory s) internal pure returns (bytes32) {\n return keccak256(abi.encodePacked(\"\\x19Ethereum Signed Message:\\n\", Strings.toString(s.length), s));\n }\n\n /**\n * @dev Returns an Ethereum Signed Typed Data, created from a\n * `domainSeparator` and a `structHash`. This produces hash corresponding\n * to the one signed with the\n * https://eips.ethereum.org/EIPS/eip-712[`eth_signTypedData`]\n * JSON-RPC method as part of EIP-712.\n *\n * See {recover}.\n */\n function toTypedDataHash(bytes32 domainSeparator, bytes32 structHash) internal pure returns (bytes32) {\n return keccak256(abi.encodePacked(\"\\x19\\x01\", domainSeparator, structHash));\n }\n}\n" + }, + "@openzeppelin/contracts/utils/introspection/IERC165.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (utils/introspection/IERC165.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Interface of the ERC165 standard, as defined in the\n * https://eips.ethereum.org/EIPS/eip-165[EIP].\n *\n * Implementers can declare support of contract interfaces, which can then be\n * queried by others ({ERC165Checker}).\n *\n * For an implementation, see {ERC165}.\n */\ninterface IERC165 {\n /**\n * @dev Returns true if this contract implements the interface defined by\n * `interfaceId`. See the corresponding\n * https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified[EIP section]\n * to learn more about how these ids are created.\n *\n * This function call must use less than 30 000 gas.\n */\n function supportsInterface(bytes4 interfaceId) external view returns (bool);\n}\n" + }, + "@openzeppelin/contracts/utils/StorageSlot.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (utils/StorageSlot.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Library for reading and writing primitive types to specific storage slots.\n *\n * Storage slots are often used to avoid storage conflict when dealing with upgradeable contracts.\n * This library helps with reading and writing to such slots without the need for inline assembly.\n *\n * The functions in this library return Slot structs that contain a `value` member that can be used to read or write.\n *\n * Example usage to set ERC1967 implementation slot:\n * ```\n * contract ERC1967 {\n * bytes32 internal constant _IMPLEMENTATION_SLOT = 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc;\n *\n * function _getImplementation() internal view returns (address) {\n * return StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value;\n * }\n *\n * function _setImplementation(address newImplementation) internal {\n * require(Address.isContract(newImplementation), \"ERC1967: new implementation is not a contract\");\n * StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value = newImplementation;\n * }\n * }\n * ```\n *\n * _Available since v4.1 for `address`, `bool`, `bytes32`, and `uint256`._\n */\nlibrary StorageSlot {\n struct AddressSlot {\n address value;\n }\n\n struct BooleanSlot {\n bool value;\n }\n\n struct Bytes32Slot {\n bytes32 value;\n }\n\n struct Uint256Slot {\n uint256 value;\n }\n\n /**\n * @dev Returns an `AddressSlot` with member `value` located at `slot`.\n */\n function getAddressSlot(bytes32 slot) internal pure returns (AddressSlot storage r) {\n /// @solidity memory-safe-assembly\n assembly {\n r.slot := slot\n }\n }\n\n /**\n * @dev Returns an `BooleanSlot` with member `value` located at `slot`.\n */\n function getBooleanSlot(bytes32 slot) internal pure returns (BooleanSlot storage r) {\n /// @solidity memory-safe-assembly\n assembly {\n r.slot := slot\n }\n }\n\n /**\n * @dev Returns an `Bytes32Slot` with member `value` located at `slot`.\n */\n function getBytes32Slot(bytes32 slot) internal pure returns (Bytes32Slot storage r) {\n /// @solidity memory-safe-assembly\n assembly {\n r.slot := slot\n }\n }\n\n /**\n * @dev Returns an `Uint256Slot` with member `value` located at `slot`.\n */\n function getUint256Slot(bytes32 slot) internal pure returns (Uint256Slot storage r) {\n /// @solidity memory-safe-assembly\n assembly {\n r.slot := slot\n }\n }\n}\n" + }, + "@openzeppelin/contracts/utils/Strings.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (utils/Strings.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev String operations.\n */\nlibrary Strings {\n bytes16 private constant _HEX_SYMBOLS = \"0123456789abcdef\";\n uint8 private constant _ADDRESS_LENGTH = 20;\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` decimal representation.\n */\n function toString(uint256 value) internal pure returns (string memory) {\n // Inspired by OraclizeAPI's implementation - MIT licence\n // https://github.com/oraclize/ethereum-api/blob/b42146b063c7d6ee1358846c198246239e9360e8/oraclizeAPI_0.4.25.sol\n\n if (value == 0) {\n return \"0\";\n }\n uint256 temp = value;\n uint256 digits;\n while (temp != 0) {\n digits++;\n temp /= 10;\n }\n bytes memory buffer = new bytes(digits);\n while (value != 0) {\n digits -= 1;\n buffer[digits] = bytes1(uint8(48 + uint256(value % 10)));\n value /= 10;\n }\n return string(buffer);\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation.\n */\n function toHexString(uint256 value) internal pure returns (string memory) {\n if (value == 0) {\n return \"0x00\";\n }\n uint256 temp = value;\n uint256 length = 0;\n while (temp != 0) {\n length++;\n temp >>= 8;\n }\n return toHexString(value, length);\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length.\n */\n function toHexString(uint256 value, uint256 length) internal pure returns (string memory) {\n bytes memory buffer = new bytes(2 * length + 2);\n buffer[0] = \"0\";\n buffer[1] = \"x\";\n for (uint256 i = 2 * length + 1; i > 1; --i) {\n buffer[i] = _HEX_SYMBOLS[value & 0xf];\n value >>= 4;\n }\n require(value == 0, \"Strings: hex length insufficient\");\n return string(buffer);\n }\n\n /**\n * @dev Converts an `address` with fixed length of 20 bytes to its not checksummed ASCII `string` hexadecimal representation.\n */\n function toHexString(address addr) internal pure returns (string memory) {\n return toHexString(uint256(uint160(addr)), _ADDRESS_LENGTH);\n }\n}\n" + }, + "contracts/agToken/AgEUR.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\nimport \"../interfaces/IAgToken.sol\";\nimport \"../interfaces/coreModule/IStableMaster.sol\";\nimport \"../interfaces/ITreasury.sol\";\nimport \"@openzeppelin/contracts-upgradeable/token/ERC20/extensions/draft-ERC20PermitUpgradeable.sol\";\n\n/// @title AgEUR\n/// @author Angle Labs, Inc.\n/// @notice Base contract for agEUR, Angle's Euro stablecoin\n/// @dev This contract is an upgraded version of the agEUR contract that was first deployed on Ethereum mainnet\ncontract AgEUR is IAgToken, ERC20PermitUpgradeable {\n // ================================= REFERENCES ================================\n\n /// @notice Reference to the `StableMaster` contract associated to agEUR\n address public stableMaster;\n\n /// @custom:oz-upgrades-unsafe-allow constructor\n constructor() initializer {}\n\n // ============================== ADDED PARAMETERS =============================\n\n /// @inheritdoc IAgToken\n mapping(address => bool) public isMinter;\n /// @notice Reference to the treasury contract which can grant minting rights\n address public treasury;\n /// @notice Boolean used to check whether the contract had been reinitialized after an upgrade\n bool public treasuryInitialized;\n\n // =================================== EVENTS ==================================\n\n event TreasuryUpdated(address indexed _treasury);\n event MinterToggled(address indexed minter);\n\n // =================================== ERRORS ==================================\n\n error BurnAmountExceedsAllowance();\n error InvalidSender();\n error InvalidTreasury();\n error NotGovernor();\n error NotMinter();\n error NotTreasury();\n error TreasuryAlreadyInitialized();\n\n // ================================= MODIFIERS =================================\n\n /// @notice Checks to see if it is the `Treasury` calling this contract\n modifier onlyTreasury() {\n if (msg.sender != treasury) revert NotTreasury();\n _;\n }\n\n /// @notice Checks whether the sender has the minting right\n modifier onlyMinter() {\n if (!isMinter[msg.sender]) revert NotMinter();\n _;\n }\n\n // ============================= EXTERNAL FUNCTION =============================\n\n /// @notice Allows anyone to burn stablecoins\n /// @param amount Amount of stablecoins to burn\n /// @dev This function can typically be called if there is a settlement mechanism to burn stablecoins\n function burnStablecoin(uint256 amount) external {\n _burn(msg.sender, amount);\n }\n\n // ========================= MINTER ROLE ONLY FUNCTIONS ========================\n\n /// @inheritdoc IAgToken\n function burnSelf(uint256 amount, address burner) external onlyMinter {\n _burn(burner, amount);\n }\n\n /// @inheritdoc IAgToken\n function burnFrom(uint256 amount, address burner, address sender) external onlyMinter {\n if (burner != sender) {\n uint256 currentAllowance = allowance(burner, sender);\n if (currentAllowance < amount) revert BurnAmountExceedsAllowance();\n _approve(burner, sender, currentAllowance - amount);\n }\n _burn(burner, amount);\n }\n\n /// @inheritdoc IAgToken\n function mint(address account, uint256 amount) external onlyMinter {\n _mint(account, amount);\n }\n\n // ========================== TREASURY ONLY FUNCTIONS ==========================\n\n /// @inheritdoc IAgToken\n function addMinter(address minter) external onlyTreasury {\n isMinter[minter] = true;\n emit MinterToggled(minter);\n }\n\n /// @inheritdoc IAgToken\n function removeMinter(address minter) external {\n if (msg.sender != minter && msg.sender != address(treasury)) revert InvalidSender();\n isMinter[minter] = false;\n emit MinterToggled(minter);\n }\n\n /// @inheritdoc IAgToken\n function setTreasury(address _treasury) external onlyTreasury {\n treasury = _treasury;\n emit TreasuryUpdated(_treasury);\n }\n}\n" + }, + "contracts/agToken/AgToken.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\n/*\n * █ \n ***** ▓▓▓ \n * ▓▓▓▓▓▓▓ \n * ///. ▓▓▓▓▓▓▓▓▓▓▓▓▓ \n ***** //////// ▓▓▓▓▓▓▓ \n * ///////////// ▓▓▓ \n ▓▓ ////////////////// █ ▓▓ \n ▓▓ ▓▓ /////////////////////// ▓▓ ▓▓ \n ▓▓ ▓▓ //////////////////////////// ▓▓ ▓▓ \n ▓▓ ▓▓ /////////▓▓▓///////▓▓▓///////// ▓▓ ▓▓ \n ▓▓ ,////////////////////////////////////// ▓▓ ▓▓ \n ▓▓ ////////////////////////////////////////// ▓▓ \n ▓▓ //////////////////////▓▓▓▓///////////////////// \n ,//////////////////////////////////////////////////// \n .////////////////////////////////////////////////////////// \n .//////////////////////////██.,//////////////////////////█ \n .//////////////////////████..,./////////////////////██ \n ...////////////////███████.....,.////////////////███ \n ,.,////////////████████ ........,///////////████ \n .,.,//////█████████ ,.......///////████ \n ,..//████████ ........./████ \n ..,██████ .....,███ \n .██ ,.,█ \n \n \n \n ▓▓ ▓▓▓▓▓▓▓▓▓▓ ▓▓▓▓▓▓▓▓▓▓ ▓▓ ▓▓▓▓▓▓▓▓▓▓ \n ▓▓▓▓▓▓ ▓▓▓ ▓▓▓ ▓▓▓ ▓▓ ▓▓ ▓▓▓▓ \n ▓▓▓ ▓▓▓ ▓▓▓ ▓▓▓ ▓▓▓ ▓▓▓ ▓▓ ▓▓▓▓▓ \n ▓▓▓ ▓▓ ▓▓▓ ▓▓▓ ▓▓▓▓▓▓▓▓▓▓ ▓▓▓▓▓▓▓▓▓▓ ▓▓▓▓▓▓▓▓▓▓ \n*/\n\nimport \"../interfaces/IAgToken.sol\";\nimport \"../interfaces/ITreasury.sol\";\nimport \"@openzeppelin/contracts-upgradeable/token/ERC20/extensions/draft-ERC20PermitUpgradeable.sol\";\n\n/// @title AgToken\n/// @author Angle Labs, Inc.\n/// @notice Base contract for Angle agTokens on Ethereum and on other chains\n/// @dev By default, agTokens are ERC-20 tokens with 18 decimals\ncontract AgToken is IAgToken, ERC20PermitUpgradeable {\n // =========================== PARAMETERS / VARIABLES ==========================\n\n /// @inheritdoc IAgToken\n mapping(address => bool) public isMinter;\n /// @notice Reference to the treasury contract which can grant minting rights\n address public treasury;\n\n // =================================== EVENTS ==================================\n\n event TreasuryUpdated(address indexed _treasury);\n event MinterToggled(address indexed minter);\n\n // =================================== ERRORS ==================================\n\n error BurnAmountExceedsAllowance();\n error InvalidSender();\n error InvalidTreasury();\n error NotMinter();\n error NotTreasury();\n\n // ================================ CONSTRUCTOR ================================\n\n /// @custom:oz-upgrades-unsafe-allow constructor\n constructor() initializer {}\n\n /// @notice Initializes the `AgToken` contract\n function initialize(string memory name_, string memory symbol_, address _treasury) external {\n _initialize(name_, symbol_, _treasury);\n }\n\n /// @notice Initializes the contract\n function _initialize(string memory name_, string memory symbol_, address _treasury) internal virtual initializer {\n if (address(ITreasury(_treasury).stablecoin()) != address(this)) revert InvalidTreasury();\n __ERC20Permit_init(name_);\n __ERC20_init(name_, symbol_);\n treasury = _treasury;\n emit TreasuryUpdated(_treasury);\n }\n\n // ================================= MODIFIERS =================================\n\n /// @notice Checks to see if it is the `Treasury` calling this contract\n modifier onlyTreasury() {\n if (msg.sender != treasury) revert NotTreasury();\n _;\n }\n\n /// @notice Checks whether the sender has the minting right\n modifier onlyMinter() {\n if (!isMinter[msg.sender]) revert NotMinter();\n _;\n }\n\n // ============================= EXTERNAL FUNCTION =============================\n\n /// @notice Allows anyone to burn stablecoins\n /// @param amount Amount of stablecoins to burn\n /// @dev This function can typically be called if there is a settlement mechanism to burn stablecoins\n function burnStablecoin(uint256 amount) external {\n _burn(msg.sender, amount);\n }\n\n // ========================= MINTER ROLE ONLY FUNCTIONS ========================\n\n /// @inheritdoc IAgToken\n function burnSelf(uint256 amount, address burner) external onlyMinter {\n _burn(burner, amount);\n }\n\n /// @inheritdoc IAgToken\n function burnFrom(uint256 amount, address burner, address sender) external onlyMinter {\n if (burner != sender) {\n uint256 currentAllowance = allowance(burner, sender);\n if (currentAllowance < amount) revert BurnAmountExceedsAllowance();\n _approve(burner, sender, currentAllowance - amount);\n }\n _burn(burner, amount);\n }\n\n /// @inheritdoc IAgToken\n function mint(address account, uint256 amount) external onlyMinter {\n _mint(account, amount);\n }\n\n // ========================== GOVERNANCE ONLY FUNCTIONS ==========================\n\n /// @inheritdoc IAgToken\n function addMinter(address minter) external onlyTreasury {\n isMinter[minter] = true;\n emit MinterToggled(minter);\n }\n\n /// @inheritdoc IAgToken\n function removeMinter(address minter) external {\n if (msg.sender != address(treasury) && msg.sender != minter) revert InvalidSender();\n isMinter[minter] = false;\n emit MinterToggled(minter);\n }\n\n /// @inheritdoc IAgToken\n function setTreasury(address _treasury) external virtual onlyTreasury {\n treasury = _treasury;\n emit TreasuryUpdated(_treasury);\n }\n}\n" + }, + "contracts/agToken/AgTokenSideChainMultiBridge.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\nimport \"./AgToken.sol\";\nimport \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\nimport \"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\";\n\n/// @title AgTokenSideChainMultiBridge\n/// @author Angle Labs, Inc.\n/// @notice Contract for Angle agTokens on other chains than Ethereum mainnet\n/// @dev This contract supports bridge tokens having a minting right on the stablecoin (also referred to as the canonical\n/// or the native token)\ncontract AgTokenSideChainMultiBridge is AgToken {\n using SafeERC20 for IERC20;\n\n /// @notice Base used for fee computation\n uint256 public constant BASE_PARAMS = 1e9;\n\n // =============================== BRIDGING DATA ===============================\n\n /// @notice Struct with some data about a specific bridge token\n struct BridgeDetails {\n // Limit on the balance of bridge token held by the contract: it is designed\n // to reduce the exposure of the system to hacks\n uint256 limit;\n // Limit on the hourly volume of token minted through this bridge\n // Technically the limit over a rolling hour is hourlyLimit x2 as hourly limit\n // is enforced only between x:00 and x+1:00\n uint256 hourlyLimit;\n // Fee taken for swapping in and out the token\n uint64 fee;\n // Whether the associated token is allowed or not\n bool allowed;\n // Whether swapping in and out from the associated token is paused or not\n bool paused;\n }\n\n /// @notice Maps a bridge token to data\n mapping(address => BridgeDetails) public bridges;\n /// @notice List of all bridge tokens\n address[] public bridgeTokensList;\n /// @notice Maps a bridge token to the associated hourly volume\n mapping(address => mapping(uint256 => uint256)) public usage;\n /// @notice Maps an address to whether it is exempt of fees for when it comes to swapping in and out\n mapping(address => uint256) public isFeeExempt;\n /// @notice Limit to the amount of tokens that can be sent from that chain to another chain\n uint256 public chainTotalHourlyLimit;\n /// @notice Usage per hour on that chain. Maps an hourly timestamp to the total volume swapped out on the chain\n mapping(uint256 => uint256) public chainTotalUsage;\n\n // =================================== EVENTS ==================================\n\n event BridgeTokenAdded(address indexed bridgeToken, uint256 limit, uint256 hourlyLimit, uint64 fee, bool paused);\n event BridgeTokenToggled(address indexed bridgeToken, bool toggleStatus);\n event BridgeTokenRemoved(address indexed bridgeToken);\n event BridgeTokenFeeUpdated(address indexed bridgeToken, uint64 fee);\n event BridgeTokenLimitUpdated(address indexed bridgeToken, uint256 limit);\n event BridgeTokenHourlyLimitUpdated(address indexed bridgeToken, uint256 hourlyLimit);\n event HourlyLimitUpdated(uint256 hourlyLimit);\n event Recovered(address indexed token, address indexed to, uint256 amount);\n event FeeToggled(address indexed theAddress, uint256 toggleStatus);\n\n // =================================== ERRORS ==================================\n\n error AssetStillControlledInReserves();\n error HourlyLimitExceeded();\n error InvalidToken();\n error NotGovernor();\n error NotGovernorOrGuardian();\n error TooBigAmount();\n error TooHighParameterValue();\n error ZeroAddress();\n\n // ================================= MODIFIERS =================================\n\n /// @notice Checks whether the `msg.sender` has the governor role or not\n modifier onlyGovernor() {\n if (!ITreasury(treasury).isGovernor(msg.sender)) revert NotGovernor();\n _;\n }\n\n /// @notice Checks whether the `msg.sender` has the governor role or the guardian role\n modifier onlyGovernorOrGuardian() {\n if (!ITreasury(treasury).isGovernorOrGuardian(msg.sender)) revert NotGovernorOrGuardian();\n _;\n }\n\n // ===================== EXTERNAL PERMISSIONLESS FUNCTIONS =====================\n\n /// @notice Returns the list of all supported bridge tokens\n /// @dev Helpful for UIs\n function allBridgeTokens() external view returns (address[] memory) {\n return bridgeTokensList;\n }\n\n /// @notice Returns the current volume for a bridge, for the current hour\n /// @param bridgeToken Bridge used to mint\n /// @dev Helpful for UIs\n function currentUsage(address bridgeToken) external view returns (uint256) {\n return usage[bridgeToken][block.timestamp / 3600];\n }\n\n /// @notice Returns the current total volume on the chain for the current hour\n /// @dev Helpful for UIs\n function currentTotalUsage() external view returns (uint256) {\n return chainTotalUsage[block.timestamp / 3600];\n }\n\n /// @notice Mints the canonical token from a supported bridge token\n /// @param bridgeToken Bridge token to use to mint\n /// @param amount Amount of bridge tokens to send\n /// @param to Address to which the stablecoin should be sent\n /// @return Amount of the canonical stablecoin actually minted\n /// @dev Some fees may be taken by the protocol depending on the token used and on the address calling\n function swapIn(address bridgeToken, uint256 amount, address to) external returns (uint256) {\n BridgeDetails memory bridgeDetails = bridges[bridgeToken];\n if (!bridgeDetails.allowed || bridgeDetails.paused) revert InvalidToken();\n uint256 balance = IERC20(bridgeToken).balanceOf(address(this));\n if (balance + amount > bridgeDetails.limit) {\n // In case someone maliciously sends tokens to this contract\n // Or the limit changes\n if (bridgeDetails.limit > balance) amount = bridgeDetails.limit - balance;\n else {\n amount = 0;\n }\n }\n\n // Checking requirement on the hourly volume\n uint256 hour = block.timestamp / 3600;\n uint256 hourlyUsage = usage[bridgeToken][hour];\n if (hourlyUsage + amount > bridgeDetails.hourlyLimit) {\n // Edge case when the hourly limit changes\n amount = bridgeDetails.hourlyLimit > hourlyUsage ? bridgeDetails.hourlyLimit - hourlyUsage : 0;\n }\n usage[bridgeToken][hour] = hourlyUsage + amount;\n\n IERC20(bridgeToken).safeTransferFrom(msg.sender, address(this), amount);\n uint256 canonicalOut = amount;\n // Computing fees\n if (isFeeExempt[msg.sender] == 0) {\n canonicalOut -= (canonicalOut * bridgeDetails.fee) / BASE_PARAMS;\n }\n _mint(to, canonicalOut);\n return canonicalOut;\n }\n\n /// @notice Burns the canonical token in exchange for a bridge token\n /// @param bridgeToken Bridge token required\n /// @param amount Amount of canonical tokens to burn\n /// @param to Address to which the bridge token should be sent\n /// @return Amount of bridge tokens actually sent back\n /// @dev Some fees may be taken by the protocol depending on the token used and on the address calling\n function swapOut(address bridgeToken, uint256 amount, address to) external returns (uint256) {\n BridgeDetails memory bridgeDetails = bridges[bridgeToken];\n if (!bridgeDetails.allowed || bridgeDetails.paused) revert InvalidToken();\n\n uint256 hour = block.timestamp / 3600;\n uint256 hourlyUsage = chainTotalUsage[hour] + amount;\n // If the amount being swapped out exceeds the limit, we revert\n // We don't want to change the amount being swapped out.\n // The user can decide to send another tx with the correct amount to reach the limit\n if (hourlyUsage > chainTotalHourlyLimit) revert HourlyLimitExceeded();\n chainTotalUsage[hour] = hourlyUsage;\n\n _burn(msg.sender, amount);\n uint256 bridgeOut = amount;\n if (isFeeExempt[msg.sender] == 0) {\n bridgeOut -= (bridgeOut * bridgeDetails.fee) / BASE_PARAMS;\n }\n IERC20(bridgeToken).safeTransfer(to, bridgeOut);\n return bridgeOut;\n }\n\n // ============================ GOVERNANCE FUNCTIONS ===========================\n\n /// @notice Adds support for a bridge token\n /// @param bridgeToken Bridge token to add: it should be a version of the stablecoin from another bridge\n /// @param limit Limit on the balance of bridge token this contract could hold\n /// @param hourlyLimit Limit on the hourly volume for this bridge\n /// @param paused Whether swapping for this token should be paused or not\n /// @param fee Fee taken upon swapping for or against this token\n function addBridgeToken(\n address bridgeToken,\n uint256 limit,\n uint256 hourlyLimit,\n uint64 fee,\n bool paused\n ) external onlyGovernor {\n if (bridges[bridgeToken].allowed || bridgeToken == address(0)) revert InvalidToken();\n if (fee > BASE_PARAMS) revert TooHighParameterValue();\n BridgeDetails memory _bridge;\n _bridge.limit = limit;\n _bridge.hourlyLimit = hourlyLimit;\n _bridge.paused = paused;\n _bridge.fee = fee;\n _bridge.allowed = true;\n bridges[bridgeToken] = _bridge;\n bridgeTokensList.push(bridgeToken);\n emit BridgeTokenAdded(bridgeToken, limit, hourlyLimit, fee, paused);\n }\n\n /// @notice Removes support for a token\n /// @param bridgeToken Address of the bridge token to remove support for\n function removeBridgeToken(address bridgeToken) external onlyGovernor {\n if (IERC20(bridgeToken).balanceOf(address(this)) != 0) revert AssetStillControlledInReserves();\n delete bridges[bridgeToken];\n // Deletion from `bridgeTokensList` loop\n uint256 bridgeTokensListLength = bridgeTokensList.length;\n for (uint256 i; i < bridgeTokensListLength - 1; ++i) {\n if (bridgeTokensList[i] == bridgeToken) {\n // Replace the `bridgeToken` to remove with the last of the list\n bridgeTokensList[i] = bridgeTokensList[bridgeTokensListLength - 1];\n break;\n }\n }\n // Remove last element in array\n bridgeTokensList.pop();\n emit BridgeTokenRemoved(bridgeToken);\n }\n\n /// @notice Recovers any ERC20 token\n /// @dev Can be used to withdraw bridge tokens for them to be de-bridged on mainnet\n function recoverERC20(address tokenAddress, address to, uint256 amountToRecover) external onlyGovernor {\n IERC20(tokenAddress).safeTransfer(to, amountToRecover);\n emit Recovered(tokenAddress, to, amountToRecover);\n }\n\n /// @notice Updates the `limit` amount for `bridgeToken`\n function setLimit(address bridgeToken, uint256 limit) external onlyGovernorOrGuardian {\n if (!bridges[bridgeToken].allowed) revert InvalidToken();\n bridges[bridgeToken].limit = limit;\n emit BridgeTokenLimitUpdated(bridgeToken, limit);\n }\n\n /// @notice Updates the `hourlyLimit` amount for `bridgeToken`\n function setHourlyLimit(address bridgeToken, uint256 hourlyLimit) external onlyGovernorOrGuardian {\n if (!bridges[bridgeToken].allowed) revert InvalidToken();\n bridges[bridgeToken].hourlyLimit = hourlyLimit;\n emit BridgeTokenHourlyLimitUpdated(bridgeToken, hourlyLimit);\n }\n\n /// @notice Updates the `chainTotalHourlyLimit` amount\n function setChainTotalHourlyLimit(uint256 hourlyLimit) external onlyGovernorOrGuardian {\n chainTotalHourlyLimit = hourlyLimit;\n emit HourlyLimitUpdated(hourlyLimit);\n }\n\n /// @notice Updates the `fee` value for `bridgeToken`\n function setSwapFee(address bridgeToken, uint64 fee) external onlyGovernorOrGuardian {\n if (!bridges[bridgeToken].allowed) revert InvalidToken();\n if (fee > BASE_PARAMS) revert TooHighParameterValue();\n bridges[bridgeToken].fee = fee;\n emit BridgeTokenFeeUpdated(bridgeToken, fee);\n }\n\n /// @notice Pauses or unpauses swapping in and out for a token\n function toggleBridge(address bridgeToken) external onlyGovernorOrGuardian {\n if (!bridges[bridgeToken].allowed) revert InvalidToken();\n bool pausedStatus = bridges[bridgeToken].paused;\n bridges[bridgeToken].paused = !pausedStatus;\n emit BridgeTokenToggled(bridgeToken, !pausedStatus);\n }\n\n /// @notice Toggles fees for the address `theAddress`\n function toggleFeesForAddress(address theAddress) external onlyGovernorOrGuardian {\n uint256 feeExemptStatus = 1 - isFeeExempt[theAddress];\n isFeeExempt[theAddress] = feeExemptStatus;\n emit FeeToggled(theAddress, feeExemptStatus);\n }\n}\n" + }, + "contracts/agToken/layerZero/LayerZeroBridge.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.12;\n\nimport \"./utils/OFTCore.sol\";\nimport \"@openzeppelin/contracts-upgradeable/security/PausableUpgradeable.sol\";\nimport \"@openzeppelin/contracts/token/ERC20/extensions/draft-IERC20Permit.sol\";\n\n/// @title LayerZeroBridge\n/// @author Angle Labs, Inc., forked from https://github.com/LayerZero-Labs/solidity-examples/blob/main/contracts/token/oft/OFT.sol\n/// @notice Contract to be deployed on Ethereum for bridging an AgToken using a bridge intermediate token and LayerZero\ncontract LayerZeroBridge is OFTCore, PausableUpgradeable {\n /// @notice Name of the contract for indexing purposes\n string public name;\n\n /// @notice Address of the bridgeable token\n /// @dev Immutable\n IERC20 public canonicalToken;\n\n /// @notice Maps an address to the amount of token bridged but not received\n mapping(address => uint256) public balanceOf;\n\n // ================================ CONSTRUCTOR ================================\n /// @notice Initializes the contract\n /// @param _name Name of the token corresponding to this contract\n /// @param _lzEndpoint Layer zero endpoint to pass messages\n /// @param _treasury Address of the treasury contract used for access control\n function initialize(string memory _name, address _lzEndpoint, address _treasury) external initializer {\n __LzAppUpgradeable_init(_lzEndpoint, _treasury);\n name = _name;\n canonicalToken = IERC20(address(ITreasury(_treasury).stablecoin()));\n }\n\n /// @custom:oz-upgrades-unsafe-allow constructor\n constructor() initializer {}\n\n // ===================== EXTERNAL PERMISSIONLESS FUNCTIONS =====================\n\n /// @inheritdoc OFTCore\n function sendWithPermit(\n uint16 _dstChainId,\n bytes memory _toAddress,\n uint256 _amount,\n address payable _refundAddress,\n address _zroPaymentAddress,\n bytes memory _adapterParams,\n uint256 deadline,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) public payable override {\n IERC20Permit(address(canonicalToken)).permit(msg.sender, address(this), _amount, deadline, v, r, s);\n send(_dstChainId, _toAddress, _amount, _refundAddress, _zroPaymentAddress, _adapterParams);\n }\n\n /// @inheritdoc OFTCore\n function withdraw(uint256 amount, address recipient) external override returns (uint256) {\n return _withdraw(amount, msg.sender, recipient);\n }\n\n /// @notice Withdraws amount of `token` from the contract and sends it to the recipient\n /// @param amount Amount to withdraw\n /// @param recipient Address to withdraw for\n /// @return The amount of canonical token sent\n function withdrawFor(uint256 amount, address recipient) external returns (uint256) {\n return _withdraw(amount, recipient, recipient);\n }\n\n // ============================= INTERNAL FUNCTIONS ============================\n\n /// @notice Withdraws `amount` from the balance of the `from` address and sends these tokens to the `to` address\n /// @dev It's important to make sure that `from` is either the `msg.sender` or that `from` and `to` are the same\n /// addresses\n function _withdraw(uint256 amount, address from, address to) internal whenNotPaused returns (uint256) {\n balanceOf[from] -= amount; // Will overflow if the amount is too big\n canonicalToken.transfer(to, amount);\n return amount;\n }\n\n /// @inheritdoc OFTCore\n function _debitFrom(uint16, bytes memory, uint256 _amount) internal override whenNotPaused returns (uint256) {\n // No need to use safeTransferFrom as we know this implementation reverts on failure\n canonicalToken.transferFrom(msg.sender, address(this), _amount);\n return _amount;\n }\n\n /// @inheritdoc OFTCore\n function _debitCreditFrom(uint16, bytes memory, uint256 _amount) internal override whenNotPaused returns (uint256) {\n balanceOf[msg.sender] -= _amount;\n return _amount;\n }\n\n /// @inheritdoc OFTCore\n function _creditTo(uint16, address _toAddress, uint256 _amount) internal override whenNotPaused returns (uint256) {\n // Should never revert as all the LayerZero bridge tokens come from\n // this contract\n uint256 balance = canonicalToken.balanceOf(address(this));\n if (balance < _amount) {\n balanceOf[_toAddress] = _amount - balance;\n if (balance != 0) canonicalToken.transfer(_toAddress, balance);\n } else {\n canonicalToken.transfer(_toAddress, _amount);\n }\n return _amount;\n }\n\n // =============================== VIEW FUNCTIONS ==============================\n\n /// @inheritdoc ERC165Upgradeable\n function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {\n return interfaceId == type(IOFTCore).interfaceId || super.supportsInterface(interfaceId);\n }\n\n // ============================ GOVERNANCE FUNCTIONS ===========================\n\n /// @notice Pauses bridging through the contract\n /// @param pause Future pause status\n function pauseSendTokens(bool pause) external onlyGovernorOrGuardian {\n pause ? _pause() : _unpause();\n }\n\n /// @notice Decreases the balance of an address\n /// @param amount Amount to withdraw from balance\n /// @param recipient Address to withdraw from\n function sweep(uint256 amount, address recipient) external onlyGovernorOrGuardian {\n balanceOf[recipient] -= amount; // Will overflow if the amount is too big\n }\n\n uint256[47] private __gap;\n}\n" + }, + "contracts/agToken/layerZero/LayerZeroBridgeToken.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.12;\n\nimport \"./utils/OFTCore.sol\";\nimport \"../../interfaces/IAgTokenSideChainMultiBridge.sol\";\nimport \"@openzeppelin/contracts-upgradeable/security/PausableUpgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/token/ERC20/ERC20Upgradeable.sol\";\n\n/// @title LayerZeroBridgeToken\n/// @author Angle Labs, Inc., forked from https://github.com/LayerZero-Labs/solidity-examples/blob/main/contracts/token/oft/OFT.sol\n/// @notice Contract to be deployed on a L2/sidechain for bridging an AgToken using a bridge intermediate token and LayerZero\ncontract LayerZeroBridgeToken is OFTCore, ERC20Upgradeable, PausableUpgradeable {\n /// @notice Address of the bridgeable token\n /// @dev Immutable\n IAgTokenSideChainMultiBridge public canonicalToken;\n\n // =================================== ERROR ===================================\n\n error InvalidAllowance();\n\n // ================================ CONSTRUCTOR ================================\n\n /// @notice Initializes the contract\n /// @param _name Name of the token corresponding to this contract\n /// @param _symbol Symbol of the token corresponding to this contract\n /// @param _lzEndpoint Layer zero endpoint to pass messages\n /// @param _treasury Address of the treasury contract used for access control\n /// @param initialSupply Initial supply to mint to the canonical token address\n /// @dev The initial supply corresponds to the initial amount that could be bridged using this OFT\n function initialize(\n string memory _name,\n string memory _symbol,\n address _lzEndpoint,\n address _treasury,\n uint256 initialSupply\n ) external initializer {\n __ERC20_init_unchained(_name, _symbol);\n __LzAppUpgradeable_init(_lzEndpoint, _treasury);\n\n canonicalToken = IAgTokenSideChainMultiBridge(address(ITreasury(_treasury).stablecoin()));\n _approve(address(this), address(canonicalToken), type(uint256).max);\n _mint(address(canonicalToken), initialSupply);\n }\n\n /// @custom:oz-upgrades-unsafe-allow constructor\n constructor() initializer {}\n\n // ===================== EXTERNAL PERMISSIONLESS FUNCTIONS =====================\n\n /// @inheritdoc OFTCore\n function sendWithPermit(\n uint16 _dstChainId,\n bytes memory _toAddress,\n uint256 _amount,\n address payable _refundAddress,\n address _zroPaymentAddress,\n bytes memory _adapterParams,\n uint256 deadline,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) public payable override {\n canonicalToken.permit(msg.sender, address(this), _amount, deadline, v, r, s);\n send(_dstChainId, _toAddress, _amount, _refundAddress, _zroPaymentAddress, _adapterParams);\n }\n\n /// @inheritdoc OFTCore\n function withdraw(uint256 amount, address recipient) external override returns (uint256 amountMinted) {\n // Does not check allowances as transfers from `msg.sender`\n _transfer(msg.sender, address(this), amount);\n amountMinted = canonicalToken.swapIn(address(this), amount, recipient);\n uint256 leftover = balanceOf(address(this));\n if (leftover != 0) {\n _transfer(address(this), msg.sender, leftover);\n }\n }\n\n // ============================= INTERNAL FUNCTIONS ============================\n\n /// @inheritdoc OFTCore\n function _debitFrom(\n uint16,\n bytes memory,\n uint256 _amount\n ) internal override whenNotPaused returns (uint256 amountSwapped) {\n // No need to use safeTransferFrom as we know this implementation reverts on failure\n canonicalToken.transferFrom(msg.sender, address(this), _amount);\n\n // Swap canonical for this bridge token. There may be some fees\n amountSwapped = canonicalToken.swapOut(address(this), _amount, address(this));\n _burn(address(this), amountSwapped);\n }\n\n /// @inheritdoc OFTCore\n function _debitCreditFrom(uint16, bytes memory, uint256 _amount) internal override whenNotPaused returns (uint256) {\n _burn(msg.sender, _amount);\n return _amount;\n }\n\n /// @inheritdoc OFTCore\n function _creditTo(\n uint16,\n address _toAddress,\n uint256 _amount\n ) internal override whenNotPaused returns (uint256 amountMinted) {\n _mint(address(this), _amount);\n amountMinted = canonicalToken.swapIn(address(this), _amount, _toAddress);\n uint256 leftover = balanceOf(address(this));\n if (leftover != 0) {\n _transfer(address(this), _toAddress, leftover);\n }\n }\n\n // =============================== VIEW FUNCTIONS ==============================\n\n /// @inheritdoc ERC165Upgradeable\n function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {\n return\n interfaceId == type(IOFT).interfaceId ||\n interfaceId == type(IERC20).interfaceId ||\n super.supportsInterface(interfaceId);\n }\n\n // ============================ GOVERNANCE FUNCTIONS ===========================\n\n /// @notice Mints the intermediate contract to the `canonicalToken`\n /// @dev Used to increase the bridging capacity\n function mint(uint256 amount) external onlyGovernorOrGuardian {\n _mint(address(canonicalToken), amount);\n }\n\n /// @notice Burns the intermediate contract from the `canonicalToken`\n /// @dev Used to decrease the bridging capacity\n function burn(uint256 amount) external onlyGovernorOrGuardian {\n _burn(address(canonicalToken), amount);\n }\n\n /// @notice Increases allowance of the `canonicalToken`\n function setupAllowance() public onlyGovernorOrGuardian {\n _approve(address(this), address(canonicalToken), type(uint256).max);\n }\n\n /// @notice Pauses bridging through the contract\n /// @param pause Future pause status\n function pauseSendTokens(bool pause) external onlyGovernorOrGuardian {\n pause ? _pause() : _unpause();\n }\n\n uint256[49] private __gap;\n}\n" + }, + "contracts/agToken/layerZero/utils/IOFTCore.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.12;\n\nimport \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\nimport \"@openzeppelin/contracts/utils/introspection/IERC165.sol\";\n\n/**\n * @dev Interface of the IOFT core standard\n * @dev Forked from https://github.com/LayerZero-Labs/solidity-examples/blob/main/contracts/token/oft/IOFTCore.sol\n */\ninterface IOFTCore is IERC165 {\n /// @notice Estimates send token `_tokenId` to (`_dstChainId`, `_toAddress`)\n /// @param _dstChainId L0 defined chain id to send tokens too\n /// @param _toAddress dynamic bytes array which contains the address to whom you are sending tokens to on the dstChain\n /// @param _amount amount of the tokens to transfer\n /// @param _useZro indicates to use zro to pay L0 fees\n /// @param _adapterParams flexible bytes array to indicate messaging adapter services in L0\n function estimateSendFee(\n uint16 _dstChainId,\n bytes calldata _toAddress,\n uint256 _amount,\n bool _useZro,\n bytes calldata _adapterParams\n ) external view returns (uint256 nativeFee, uint256 zroFee);\n\n /// @notice Sends `_amount` amount of token to (`_dstChainId`, `_toAddress`)\n /// @param _dstChainId the destination chain identifier\n /// @param _toAddress can be any size depending on the `dstChainId`.\n /// @param _amount the quantity of tokens in wei\n /// @param _refundAddress the address LayerZero refunds if too much message fee is sent\n /// @param _zroPaymentAddress set to address(0x0) if not paying in ZRO (LayerZero Token)\n /// @param _adapterParams is a flexible bytes array to indicate messaging adapter services\n function send(\n uint16 _dstChainId,\n bytes calldata _toAddress,\n uint256 _amount,\n address payable _refundAddress,\n address _zroPaymentAddress,\n bytes calldata _adapterParams\n ) external payable;\n\n /// @notice Sends `_amount` amount of credit to (`_dstChainId`, `_toAddress`)\n /// @param _dstChainId the destination chain identifier\n /// @param _toAddress can be any size depending on the `dstChainId`.\n /// @param _amount the quantity of credit to send in wei\n /// @param _refundAddress the address LayerZero refunds if too much message fee is sent\n /// @param _zroPaymentAddress set to address(0x0) if not paying in ZRO (LayerZero Token)\n /// @param _adapterParams is a flexible bytes array to indicate messaging adapter services\n function sendCredit(\n uint16 _dstChainId,\n bytes calldata _toAddress,\n uint256 _amount,\n address payable _refundAddress,\n address _zroPaymentAddress,\n bytes calldata _adapterParams\n ) external payable;\n\n /// @notice Sends `_amount` amount of token to (`_dstChainId`, `_toAddress`)\n /// @param _dstChainId The destination chain identifier\n /// @param _toAddress Can be any size depending on the `dstChainId`.\n /// @param _amount Quantity of tokens in wei\n /// @param _refundAddress Address LayerZero refunds if too much message fee is sent\n /// @param _zroPaymentAddress Set to address(0x0) if not paying in ZRO (LayerZero Token)\n /// @param _adapterParams Flexible bytes array to indicate messaging adapter services\n /// @param deadline Deadline parameter for the signature to be valid\n /// @dev The `v`, `r`, and `s` parameters are used as signature data\n function sendWithPermit(\n uint16 _dstChainId,\n bytes memory _toAddress,\n uint256 _amount,\n address payable _refundAddress,\n address _zroPaymentAddress,\n bytes memory _adapterParams,\n uint256 deadline,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) external payable;\n\n /// @notice Withdraws amount of canonical token from the `msg.sender` balance and sends it to the recipient\n /// @param amount Amount to withdraw\n /// @param recipient Address to send the canonical token to\n /// @return The amount of canonical token sent\n function withdraw(uint256 amount, address recipient) external returns (uint256);\n\n /// @dev Emitted when `_amount` tokens are moved from the `_sender` to (`_dstChainId`, `_toAddress`)\n /// `_nonce` is the outbound nonce\n event SendToChain(\n address indexed _sender,\n uint16 indexed _dstChainId,\n bytes indexed _toAddress,\n uint256 _amount,\n uint64 _nonce\n );\n\n /// @dev Emitted when `_amount` tokens are received from `_srcChainId` into the `_toAddress` on the local chain.\n /// `_nonce` is the inbound nonce.\n event ReceiveFromChain(\n uint16 indexed _srcChainId,\n bytes indexed _srcAddress,\n address indexed _toAddress,\n uint256 _amount,\n uint64 _nonce\n );\n}\n\n/// @dev Interface of the OFT standard\ninterface IOFT is IOFTCore, IERC20 {\n\n}\n" + }, + "contracts/agToken/layerZero/utils/NonblockingLzApp.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.12;\n\nimport \"@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol\";\nimport \"../../../interfaces/external/layerZero/ILayerZeroReceiver.sol\";\nimport \"../../../interfaces/external/layerZero/ILayerZeroUserApplicationConfig.sol\";\nimport \"../../../interfaces/external/layerZero/ILayerZeroEndpoint.sol\";\nimport \"../../../interfaces/ITreasury.sol\";\n\n/// @title NonblockingLzApp\n/// @author Angle Labs, Inc., forked from https://github.com/LayerZero-Labs/solidity-examples/\n/// @notice Base contract for bridging using LayerZero\nabstract contract NonblockingLzApp is Initializable, ILayerZeroReceiver, ILayerZeroUserApplicationConfig {\n /// @notice Layer Zero endpoint\n ILayerZeroEndpoint public lzEndpoint;\n\n /// @notice Maps chainIds to failed messages to retry them\n mapping(uint16 => mapping(bytes => mapping(uint64 => bytes32))) public failedMessages;\n\n /// @notice Maps chainIds to their OFT address\n mapping(uint16 => bytes) public trustedRemoteLookup;\n\n /// @notice Reference to the treasury contract to fetch access control\n address public treasury;\n\n /// @notice Maps pairs of (`to` chain, `packetType`) to the minimum amount of gas needed on the destination chain\n mapping(uint16 => mapping(uint16 => uint256)) public minDstGasLookup;\n\n /// @notice For future LayerZero compatibility\n address public precrime;\n\n // ================================== Events ===================================\n\n event SetTrustedRemote(uint16 _srcChainId, bytes _srcAddress);\n event MessageFailed(uint16 _srcChainId, bytes _srcAddress, uint64 _nonce, bytes _payload);\n\n // =============================== Errors ================================\n\n error NotGovernor();\n error NotGovernorOrGuardian();\n error InsufficientGas();\n error InvalidEndpoint();\n error InvalidSource();\n error InvalidCaller();\n error InvalidParams();\n error InvalidPayload();\n error ZeroAddress();\n\n // ============================= Constructor ===================================\n\n //solhint-disable-next-line\n function __LzAppUpgradeable_init(address _endpoint, address _treasury) internal {\n if (_endpoint == address(0) || _treasury == address(0)) revert ZeroAddress();\n lzEndpoint = ILayerZeroEndpoint(_endpoint);\n treasury = _treasury;\n }\n\n // =============================== Modifiers ===================================\n\n /// @notice Checks whether the `msg.sender` has the governor role or the guardian role\n modifier onlyGovernorOrGuardian() {\n if (!ITreasury(treasury).isGovernorOrGuardian(msg.sender)) revert NotGovernorOrGuardian();\n _;\n }\n\n // ==================== External Permissionless Functions ======================\n\n /// @notice Receives a message from the LZ endpoint and process it\n /// @param _srcChainId ChainId of the source chain - LayerZero standard\n /// @param _srcAddress Sender of the source chain\n /// @param _nonce Nounce of the message\n /// @param _payload Data: recipient address and amount\n function lzReceive(\n uint16 _srcChainId,\n bytes memory _srcAddress,\n uint64 _nonce,\n bytes memory _payload\n ) public virtual override {\n // lzReceive must be called by the endpoint for security\n if (msg.sender != address(lzEndpoint)) revert InvalidEndpoint();\n\n bytes memory trustedRemote = trustedRemoteLookup[_srcChainId];\n // if will still block the message pathway from (srcChainId, srcAddress). should not receive message from untrusted remote.\n if (_srcAddress.length != trustedRemote.length || keccak256(_srcAddress) != keccak256(trustedRemote))\n revert InvalidSource();\n\n _blockingLzReceive(_srcChainId, _srcAddress, _nonce, _payload);\n }\n\n /// @notice Retries a message that previously failed and was stored\n /// @param _srcChainId ChainId of the source chain - LayerZero standard\n /// @param _srcAddress Sender of the source chain\n /// @param _nonce Nounce of the message\n /// @param _payload Data: recipient address and amount\n function retryMessage(\n uint16 _srcChainId,\n bytes memory _srcAddress,\n uint64 _nonce,\n bytes memory _payload\n ) public payable virtual {\n // assert there is message to retry\n bytes32 payloadHash = failedMessages[_srcChainId][_srcAddress][_nonce];\n if (payloadHash == bytes32(0) || keccak256(_payload) != payloadHash) revert InvalidPayload();\n // clear the stored message\n failedMessages[_srcChainId][_srcAddress][_nonce] = bytes32(0);\n // execute the message. revert if it fails again\n _nonblockingLzReceive(_srcChainId, _srcAddress, _nonce, _payload);\n }\n\n // ============================= Internal Functions ===================================\n\n /// @notice Handles message receptions in a non blocking way\n /// @param _srcChainId ChainId of the source chain - LayerZero standard\n /// @param _srcAddress Sender of the source chain\n /// @param _nonce Nounce of the message\n /// @param _payload Data: recipient address and amount\n /// @dev public for the needs of try / catch but effectively internal\n function nonblockingLzReceive(\n uint16 _srcChainId,\n bytes memory _srcAddress,\n uint64 _nonce,\n bytes memory _payload\n ) public virtual {\n // only internal transaction\n if (msg.sender != address(this)) revert InvalidCaller();\n _nonblockingLzReceive(_srcChainId, _srcAddress, _nonce, _payload);\n }\n\n /// @notice Handles message receptions in a non blocking way\n /// @param _srcChainId ChainId of the source chain - LayerZero standard\n /// @param _srcAddress Sender of the source chain\n /// @param _nonce Nounce of the message\n /// @param _payload Data: recipient address and amount\n function _nonblockingLzReceive(\n uint16 _srcChainId,\n bytes memory _srcAddress,\n uint64 _nonce,\n bytes memory _payload\n ) internal virtual;\n\n /// @notice Handles message receptions in a blocking way\n /// @param _srcChainId ChainId of the source chain - LayerZero standard\n /// @param _srcAddress Sender of the source chain\n /// @param _nonce Nounce of the message\n /// @param _payload Data: recipient address and amount\n function _blockingLzReceive(\n uint16 _srcChainId,\n bytes memory _srcAddress,\n uint64 _nonce,\n bytes memory _payload\n ) internal {\n // try-catch all errors/exceptions\n try this.nonblockingLzReceive(_srcChainId, _srcAddress, _nonce, _payload) {\n // do nothing\n } catch {\n // error / exception\n failedMessages[_srcChainId][_srcAddress][_nonce] = keccak256(_payload);\n emit MessageFailed(_srcChainId, _srcAddress, _nonce, _payload);\n }\n }\n\n /// @notice Sends a message to the LZ endpoint and process it\n /// @param _dstChainId L0 defined chain id to send tokens too\n /// @param _payload Data: recipient address and amount\n /// @param _refundAddress Address LayerZero refunds if too much message fee is sent\n /// @param _zroPaymentAddress Set to address(0x0) if not paying in ZRO (LayerZero Token)\n /// @param _adapterParams Flexible bytes array to indicate messaging adapter services in L0\n function _lzSend(\n uint16 _dstChainId,\n bytes memory _payload,\n address payable _refundAddress,\n address _zroPaymentAddress,\n bytes memory _adapterParams\n ) internal virtual {\n bytes memory trustedRemote = trustedRemoteLookup[_dstChainId];\n if (trustedRemote.length == 0) revert InvalidSource();\n //solhint-disable-next-line\n lzEndpoint.send{ value: msg.value }(\n _dstChainId,\n trustedRemote,\n _payload,\n _refundAddress,\n _zroPaymentAddress,\n _adapterParams\n );\n }\n\n /// @notice Checks the gas limit of a given transaction\n function _checkGasLimit(\n uint16 _dstChainId,\n uint16 _type,\n bytes memory _adapterParams,\n uint256 _extraGas\n ) internal view virtual {\n uint256 minGasLimit = minDstGasLookup[_dstChainId][_type] + _extraGas;\n if (minGasLimit == 0 || minGasLimit > _getGasLimit(_adapterParams)) revert InsufficientGas();\n }\n\n /// @notice Gets the gas limit from the `_adapterParams` parameter\n function _getGasLimit(bytes memory _adapterParams) internal pure virtual returns (uint256 gasLimit) {\n if (_adapterParams.length < 34) revert InvalidParams();\n // solhint-disable-next-line\n assembly {\n gasLimit := mload(add(_adapterParams, 34))\n }\n }\n\n // ======================= Governance Functions ================================\n\n /// @notice Sets the corresponding address on an other chain.\n /// @param _srcChainId ChainId of the source chain - LayerZero standard\n /// @param _srcAddress Address on the source chain\n /// @dev Used for both receiving and sending message\n /// @dev There can only be one trusted source per chain\n /// @dev Allows owner to set it multiple times.\n function setTrustedRemote(uint16 _srcChainId, bytes calldata _srcAddress) external onlyGovernorOrGuardian {\n trustedRemoteLookup[_srcChainId] = _srcAddress;\n emit SetTrustedRemote(_srcChainId, _srcAddress);\n }\n\n /// @notice Fetches the default LZ config\n function getConfig(\n uint16 _version,\n uint16 _chainId,\n address,\n uint256 _configType\n ) external view returns (bytes memory) {\n return lzEndpoint.getConfig(_version, _chainId, address(this), _configType);\n }\n\n /// @notice Overrides the default LZ config\n function setConfig(\n uint16 _version,\n uint16 _chainId,\n uint256 _configType,\n bytes calldata _config\n ) external override onlyGovernorOrGuardian {\n lzEndpoint.setConfig(_version, _chainId, _configType, _config);\n }\n\n /// @notice Overrides the default LZ config\n function setSendVersion(uint16 _version) external override onlyGovernorOrGuardian {\n lzEndpoint.setSendVersion(_version);\n }\n\n /// @notice Overrides the default LZ config\n function setReceiveVersion(uint16 _version) external override onlyGovernorOrGuardian {\n lzEndpoint.setReceiveVersion(_version);\n }\n\n /// @notice Unpauses the receive functionalities\n function forceResumeReceive(\n uint16 _srcChainId,\n bytes calldata _srcAddress\n ) external override onlyGovernorOrGuardian {\n lzEndpoint.forceResumeReceive(_srcChainId, _srcAddress);\n }\n\n /// @notice Sets the minimum gas parameter for a packet type on a given chain\n function setMinDstGas(uint16 _dstChainId, uint16 _packetType, uint256 _minGas) external onlyGovernorOrGuardian {\n if (_minGas == 0) revert InvalidParams();\n minDstGasLookup[_dstChainId][_packetType] = _minGas;\n }\n\n /// @notice Sets the precrime variable\n function setPrecrime(address _precrime) external onlyGovernorOrGuardian {\n precrime = _precrime;\n }\n\n // ======================= View Functions ================================\n\n /// @notice Checks if the `_srcAddress` corresponds to the trusted source\n function isTrustedRemote(uint16 _srcChainId, bytes calldata _srcAddress) external view returns (bool) {\n bytes memory trustedSource = trustedRemoteLookup[_srcChainId];\n return keccak256(trustedSource) == keccak256(_srcAddress);\n }\n\n uint256[44] private __gap;\n}\n" + }, + "contracts/agToken/layerZero/utils/OFTCore.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.12;\n\nimport \"./NonblockingLzApp.sol\";\nimport \"./IOFTCore.sol\";\nimport \"@openzeppelin/contracts-upgradeable/utils/introspection/ERC165Upgradeable.sol\";\n\n/// @title OFTCore\n/// @author Forked from https://github.com/LayerZero-Labs/solidity-examples/blob/main/contracts/token/oft/OFTCore.sol\n/// but with slight modifications from the Angle Labs, Inc. which added return values to the `_creditTo` and `_debitFrom` functions\n/// @notice Base contract for bridging using LayerZero\nabstract contract OFTCore is NonblockingLzApp, ERC165Upgradeable, IOFTCore {\n /// @notice Amount of additional gas specified\n uint256 public constant EXTRA_GAS = 200000;\n /// @notice Packet type for token transfer\n uint16 public constant PT_SEND = 0;\n\n /// @notice Whether to use custom parameters in transactions\n uint8 public useCustomAdapterParams;\n\n // ==================== External Permissionless Functions ======================\n\n /// @inheritdoc IOFTCore\n function sendWithPermit(\n uint16 _dstChainId,\n bytes memory _toAddress,\n uint256 _amount,\n address payable _refundAddress,\n address _zroPaymentAddress,\n bytes memory _adapterParams,\n uint256 deadline,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) public payable virtual;\n\n /// @inheritdoc IOFTCore\n function send(\n uint16 _dstChainId,\n bytes memory _toAddress,\n uint256 _amount,\n address payable _refundAddress,\n address _zroPaymentAddress,\n bytes memory _adapterParams\n ) public payable virtual {\n _checkAdapterParams(_dstChainId, PT_SEND, _adapterParams, EXTRA_GAS);\n _amount = _debitFrom(_dstChainId, _toAddress, _amount);\n\n bytes memory payload = abi.encode(_toAddress, _amount);\n _lzSend(_dstChainId, payload, _refundAddress, _zroPaymentAddress, _adapterParams);\n\n uint64 nonce = lzEndpoint.getOutboundNonce(_dstChainId, address(this));\n emit SendToChain(msg.sender, _dstChainId, _toAddress, _amount, nonce);\n }\n\n /// @inheritdoc IOFTCore\n function sendCredit(\n uint16 _dstChainId,\n bytes memory _toAddress,\n uint256 _amount,\n address payable _refundAddress,\n address _zroPaymentAddress,\n bytes memory _adapterParams\n ) public payable virtual {\n _checkAdapterParams(_dstChainId, PT_SEND, _adapterParams, EXTRA_GAS);\n _amount = _debitCreditFrom(_dstChainId, _toAddress, _amount);\n\n _send(_dstChainId, _toAddress, _amount, _refundAddress, _zroPaymentAddress, _adapterParams);\n }\n\n /// @inheritdoc IOFTCore\n function withdraw(uint256 amount, address recipient) external virtual returns (uint256);\n\n /// @notice Sets whether custom adapter parameters can be used or not\n function setUseCustomAdapterParams(uint8 _useCustomAdapterParams) public virtual onlyGovernorOrGuardian {\n useCustomAdapterParams = _useCustomAdapterParams;\n }\n\n // =========================== Internal Functions ==============================\n\n /// @notice Internal function to send `_amount` amount of token to (`_dstChainId`, `_toAddress`)\n /// @param _dstChainId the destination chain identifier\n /// @param _toAddress can be any size depending on the `dstChainId`.\n /// @param _amount the quantity of tokens in wei\n /// @param _refundAddress the address LayerZero refunds if too much message fee is sent\n /// @param _zroPaymentAddress set to address(0x0) if not paying in ZRO (LayerZero Token)\n /// @param _adapterParams is a flexible bytes array to indicate messaging adapter services\n /// @dev Accounting and checks should be performed beforehand\n function _send(\n uint16 _dstChainId,\n bytes memory _toAddress,\n uint256 _amount,\n address payable _refundAddress,\n address _zroPaymentAddress,\n bytes memory _adapterParams\n ) internal {\n bytes memory payload = abi.encode(_toAddress, _amount);\n _lzSend(_dstChainId, payload, _refundAddress, _zroPaymentAddress, _adapterParams);\n\n uint64 nonce = lzEndpoint.getOutboundNonce(_dstChainId, address(this));\n emit SendToChain(msg.sender, _dstChainId, _toAddress, _amount, nonce);\n }\n\n /// @inheritdoc NonblockingLzApp\n function _nonblockingLzReceive(\n uint16 _srcChainId,\n bytes memory _srcAddress,\n uint64 _nonce,\n bytes memory _payload\n ) internal virtual override {\n // decode and load the toAddress\n (bytes memory toAddressBytes, uint256 amount) = abi.decode(_payload, (bytes, uint256));\n address toAddress;\n //solhint-disable-next-line\n assembly {\n toAddress := mload(add(toAddressBytes, 20))\n }\n amount = _creditTo(_srcChainId, toAddress, amount);\n\n emit ReceiveFromChain(_srcChainId, _srcAddress, toAddress, amount, _nonce);\n }\n\n /// @notice Checks the adapter parameters given during the smart contract call\n function _checkAdapterParams(\n uint16 _dstChainId,\n uint16 _pkType,\n bytes memory _adapterParams,\n uint256 _extraGas\n ) internal virtual {\n if (useCustomAdapterParams > 0) _checkGasLimit(_dstChainId, _pkType, _adapterParams, _extraGas);\n else if (_adapterParams.length != 0) revert InvalidParams();\n }\n\n /// @notice Makes accountability when bridging from this contract using canonical token\n /// @param _dstChainId ChainId of the destination chain - LayerZero standard\n /// @param _toAddress Recipient on the destination chain\n /// @param _amount Amount to bridge\n function _debitFrom(\n uint16 _dstChainId,\n bytes memory _toAddress,\n uint256 _amount\n ) internal virtual returns (uint256);\n\n /// @notice Makes accountability when bridging from this contract's credit\n /// @param _dstChainId ChainId of the destination chain - LayerZero standard\n /// @param _toAddress Recipient on the destination chain\n /// @param _amount Amount to bridge\n function _debitCreditFrom(\n uint16 _dstChainId,\n bytes memory _toAddress,\n uint256 _amount\n ) internal virtual returns (uint256);\n\n /// @notice Makes accountability when bridging to this contract\n /// @param _srcChainId ChainId of the source chain - LayerZero standard\n /// @param _toAddress Recipient on this chain\n /// @param _amount Amount to bridge\n function _creditTo(uint16 _srcChainId, address _toAddress, uint256 _amount) internal virtual returns (uint256);\n\n // ========================== View Functions ===================================\n\n /// @inheritdoc ERC165Upgradeable\n function supportsInterface(\n bytes4 interfaceId\n ) public view virtual override(ERC165Upgradeable, IERC165) returns (bool) {\n return interfaceId == type(IOFTCore).interfaceId || super.supportsInterface(interfaceId);\n }\n\n /// @inheritdoc IOFTCore\n function estimateSendFee(\n uint16 _dstChainId,\n bytes memory _toAddress,\n uint256 _amount,\n bool _useZro,\n bytes memory _adapterParams\n ) public view virtual override returns (uint256 nativeFee, uint256 zroFee) {\n // mock the payload for send()\n bytes memory payload = abi.encode(_toAddress, _amount);\n return lzEndpoint.estimateFees(_dstChainId, address(this), payload, _useZro, _adapterParams);\n }\n\n uint256[49] private __gap;\n}\n" + }, + "contracts/agToken/polygon/TokenPolygonUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.12;\n\nimport \"./utils/ERC20UpgradeableCustom.sol\";\nimport \"@openzeppelin/contracts-upgradeable/access/AccessControlUpgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/utils/cryptography/draft-EIP712Upgradeable.sol\";\nimport \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\nimport \"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\";\n\nimport \"../../interfaces/IAgToken.sol\";\nimport \"../../interfaces/ITreasury.sol\";\n\ninterface IChildToken {\n function deposit(address user, bytes calldata depositData) external;\n\n function withdraw(uint256 amount) external;\n}\n\ncontract TokenPolygonUpgradeable is\n Initializable,\n ERC20UpgradeableCustom,\n AccessControlUpgradeable,\n EIP712Upgradeable,\n IChildToken\n{\n bytes32 public constant DEPOSITOR_ROLE = keccak256(\"DEPOSITOR_ROLE\");\n\n /// @dev Emitted when the child chain manager changes\n event ChildChainManagerAdded(address newAddress);\n event ChildChainManagerRevoked(address oldAddress);\n\n constructor() initializer {}\n\n function initialize(\n string memory _name,\n string memory _symbol,\n address childChainManager,\n address guardian\n ) public initializer {\n __ERC20_init(_name, _symbol);\n __AccessControl_init();\n _setupRole(DEFAULT_ADMIN_ROLE, guardian);\n _setupRole(DEPOSITOR_ROLE, childChainManager);\n __EIP712_init(_name, \"1\");\n }\n\n /**\n * @notice Called when the bridge has tokens to mint\n * @param user Address to mint the token to\n * @param depositData Encoded amount to mint\n */\n function deposit(address user, bytes calldata depositData) external override {\n require(hasRole(DEPOSITOR_ROLE, msg.sender));\n uint256 amount = abi.decode(depositData, (uint256));\n _mint(user, amount);\n }\n\n /**\n * @notice Called when user wants to withdraw tokens back to root chain\n * @dev Should burn user's tokens. This transaction will be verified when exiting on root chain\n * @param amount Amount of tokens to withdraw\n */\n function withdraw(uint256 amount) external override {\n _burn(_msgSender(), amount);\n }\n\n // =============================================================================\n // ======================= New data added for the upgrade ======================\n // =============================================================================\n\n mapping(address => bool) public isMinter;\n /// @notice Reference to the treasury contract which can grant minting rights\n address public treasury;\n /// @notice Boolean to check whether the contract has been reinitialized after its upgrade\n bool public treasuryInitialized;\n\n using SafeERC20 for IERC20;\n\n /// @notice Base used for fee computation\n uint256 public constant BASE_PARAMS = 10 ** 9;\n\n // =============================== Bridging Data ===============================\n\n /// @notice Struct with some data about a specific bridge token\n struct BridgeDetails {\n // Limit on the balance of bridge token held by the contract: it is designed\n // to reduce the exposure of the system to hacks\n uint256 limit;\n // Limit on the hourly volume of token minted through this bridge\n // Technically the limit over a rolling hour is hourlyLimit x2 as hourly limit\n // is enforced only between x:00 and x+1:00\n uint256 hourlyLimit;\n // Fee taken for swapping in and out the token\n uint64 fee;\n // Whether the associated token is allowed or not\n bool allowed;\n // Whether swapping in and out from the associated token is paused or not\n bool paused;\n }\n\n /// @notice Maps a bridge token to data\n mapping(address => BridgeDetails) public bridges;\n /// @notice List of all bridge tokens\n address[] public bridgeTokensList;\n /// @notice Maps a bridge token to the associated hourly volume\n mapping(address => mapping(uint256 => uint256)) public usage;\n /// @notice Maps an address to whether it is exempt of fees for when it comes to swapping in and out\n mapping(address => uint256) public isFeeExempt;\n /// @notice Limit to the amount of tokens that can be sent from that chain to another chain\n uint256 public chainTotalHourlyLimit;\n /// @notice Usage per hour on that chain. Maps an hourly timestamp to the total volume swapped out on the chain\n mapping(uint256 => uint256) public chainTotalUsage;\n\n uint256[42] private __gap;\n\n // ================================== Events ===================================\n\n event BridgeTokenAdded(address indexed bridgeToken, uint256 limit, uint256 hourlyLimit, uint64 fee, bool paused);\n event BridgeTokenToggled(address indexed bridgeToken, bool toggleStatus);\n event BridgeTokenRemoved(address indexed bridgeToken);\n event BridgeTokenFeeUpdated(address indexed bridgeToken, uint64 fee);\n event BridgeTokenLimitUpdated(address indexed bridgeToken, uint256 limit);\n event BridgeTokenHourlyLimitUpdated(address indexed bridgeToken, uint256 hourlyLimit);\n event HourlyLimitUpdated(uint256 hourlyLimit);\n event FeeToggled(address indexed theAddress, uint256 toggleStatus);\n event KeeperToggled(address indexed keeper, bool toggleStatus);\n event MinterToggled(address indexed minter);\n event Recovered(address indexed token, address indexed to, uint256 amount);\n event TreasuryUpdated(address indexed _treasury);\n\n // ================================== Errors ===================================\n\n error AssetStillControlledInReserves();\n error BurnAmountExceedsAllowance();\n error HourlyLimitExceeded();\n error InvalidSender();\n error InvalidToken();\n error InvalidTreasury();\n error NotGovernor();\n error NotGovernorOrGuardian();\n error NotMinter();\n error NotTreasury();\n error TooBigAmount();\n error TooHighParameterValue();\n error TreasuryAlreadyInitialized();\n error ZeroAddress();\n\n /// @notice Checks to see if it is the `Treasury` calling this contract\n /// @dev There is no Access Control here, because it can be handled cheaply through this modifier\n modifier onlyTreasury() {\n if (msg.sender != treasury) revert NotTreasury();\n _;\n }\n\n /// @notice Checks whether the sender has the minting right\n modifier onlyMinter() {\n if (!isMinter[msg.sender]) revert NotMinter();\n _;\n }\n\n /// @notice Checks whether the `msg.sender` has the governor role or not\n modifier onlyGovernor() {\n if (!ITreasury(treasury).isGovernor(msg.sender)) revert NotGovernor();\n _;\n }\n\n /// @notice Checks whether the `msg.sender` has the governor role or the guardian role\n modifier onlyGovernorOrGuardian() {\n if (!ITreasury(treasury).isGovernorOrGuardian(msg.sender)) revert NotGovernorOrGuardian();\n _;\n }\n\n /// @notice Sets up the treasury contract on Polygon after the upgrade\n /// @param _treasury Address of the treasury contract\n function setUpTreasury(address _treasury) external {\n // Only governor on Polygon\n if (msg.sender != 0xdA2D2f638D6fcbE306236583845e5822554c02EA) revert NotGovernor();\n if (address(ITreasury(_treasury).stablecoin()) != address(this)) revert InvalidTreasury();\n if (treasuryInitialized) revert TreasuryAlreadyInitialized();\n treasury = _treasury;\n treasuryInitialized = true;\n emit TreasuryUpdated(_treasury);\n }\n\n // =========================== External Function ===============================\n\n /// @notice Allows anyone to burn agToken without redeeming collateral back\n /// @param amount Amount of stablecoins to burn\n /// @dev This function can typically be called if there is a settlement mechanism to burn stablecoins\n function burnStablecoin(uint256 amount) external {\n _burnCustom(msg.sender, amount);\n }\n\n // ======================= Minter Role Only Functions ==========================\n\n function burnSelf(uint256 amount, address burner) external onlyMinter {\n _burnCustom(burner, amount);\n }\n\n function burnFrom(uint256 amount, address burner, address sender) external onlyMinter {\n _burnFromNoRedeem(amount, burner, sender);\n }\n\n function mint(address account, uint256 amount) external onlyMinter {\n _mint(account, amount);\n }\n\n // ======================= Treasury Only Functions =============================\n\n function addMinter(address minter) external onlyTreasury {\n isMinter[minter] = true;\n emit MinterToggled(minter);\n }\n\n function removeMinter(address minter) external {\n if (msg.sender != address(treasury) && msg.sender != minter) revert InvalidSender();\n isMinter[minter] = false;\n emit MinterToggled(minter);\n }\n\n function setTreasury(address _treasury) external onlyTreasury {\n treasury = _treasury;\n emit TreasuryUpdated(_treasury);\n }\n\n // ============================ Internal Function ==============================\n\n /// @notice Internal version of the function `burnFromNoRedeem`\n /// @param amount Amount to burn\n /// @dev It is at the level of this function that allowance checks are performed\n function _burnFromNoRedeem(uint256 amount, address burner, address sender) internal {\n if (burner != sender) {\n uint256 currentAllowance = allowance(burner, sender);\n if (currentAllowance < amount) revert BurnAmountExceedsAllowance();\n _approve(burner, sender, currentAllowance - amount);\n }\n _burnCustom(burner, amount);\n }\n\n // ==================== External Permissionless Functions ======================\n\n /// @notice Returns the list of all supported bridge tokens\n /// @dev Helpful for UIs\n function allBridgeTokens() external view returns (address[] memory) {\n return bridgeTokensList;\n }\n\n /// @notice Returns the current volume for a bridge, for the current hour\n /// @dev Helpful for UIs\n function currentUsage(address bridge) external view returns (uint256) {\n return usage[bridge][block.timestamp / 3600];\n }\n\n /// @notice Returns the current total volume on the chain for the current hour\n /// @dev Helpful for UIs\n function currentTotalUsage() external view returns (uint256) {\n return chainTotalUsage[block.timestamp / 3600];\n }\n\n /// @notice Mints the canonical token from a supported bridge token\n /// @param bridgeToken Bridge token to use to mint\n /// @param amount Amount of bridge tokens to send\n /// @param to Address to which the stablecoin should be sent\n /// @dev Some fees may be taken by the protocol depending on the token used and on the address calling\n function swapIn(address bridgeToken, uint256 amount, address to) external returns (uint256) {\n BridgeDetails memory bridgeDetails = bridges[bridgeToken];\n if (!bridgeDetails.allowed || bridgeDetails.paused) revert InvalidToken();\n uint256 balance = IERC20(bridgeToken).balanceOf(address(this));\n if (balance + amount > bridgeDetails.limit) {\n // In case someone maliciously sends tokens to this contract\n // Or the limit changes\n if (bridgeDetails.limit > balance) amount = bridgeDetails.limit - balance;\n else {\n amount = 0;\n }\n }\n\n // Checking requirement on the hourly volume\n uint256 hour = block.timestamp / 3600;\n uint256 hourlyUsage = usage[bridgeToken][hour] + amount;\n if (hourlyUsage > bridgeDetails.hourlyLimit) {\n // Edge case when the hourly limit changes\n if (bridgeDetails.hourlyLimit > usage[bridgeToken][hour])\n amount = bridgeDetails.hourlyLimit - usage[bridgeToken][hour];\n else {\n amount = 0;\n }\n }\n usage[bridgeToken][hour] += amount;\n\n IERC20(bridgeToken).safeTransferFrom(msg.sender, address(this), amount);\n uint256 canonicalOut = amount;\n // Computing fees\n if (isFeeExempt[msg.sender] == 0) {\n canonicalOut -= (canonicalOut * bridgeDetails.fee) / BASE_PARAMS;\n }\n _mint(to, canonicalOut);\n return canonicalOut;\n }\n\n /// @notice Burns the canonical token in exchange for a bridge token\n /// @param bridgeToken Bridge token required\n /// @param amount Amount of canonical tokens to burn\n /// @param to Address to which the bridge token should be sent\n /// @dev Some fees may be taken by the protocol depending on the token used and on the address calling\n function swapOut(address bridgeToken, uint256 amount, address to) external returns (uint256) {\n BridgeDetails memory bridgeDetails = bridges[bridgeToken];\n if (!bridgeDetails.allowed || bridgeDetails.paused) revert InvalidToken();\n\n uint256 hour = block.timestamp / 3600;\n uint256 hourlyUsage = chainTotalUsage[hour] + amount;\n // If the amount being swapped out exceeds the limit, we revert\n // We don't want to change the amount being swapped out.\n // The user can decide to send another tx with the correct amount to reach the limit\n if (hourlyUsage > chainTotalHourlyLimit) revert HourlyLimitExceeded();\n chainTotalUsage[hour] = hourlyUsage;\n\n _burnCustom(msg.sender, amount);\n uint256 bridgeOut = amount;\n if (isFeeExempt[msg.sender] == 0) {\n bridgeOut -= (bridgeOut * bridgeDetails.fee) / BASE_PARAMS;\n }\n IERC20(bridgeToken).safeTransfer(to, bridgeOut);\n return bridgeOut;\n }\n\n // ======================= Governance Functions ================================\n\n /// @notice Adds support for a bridge token\n /// @param bridgeToken Bridge token to add: it should be a version of the stablecoin from another bridge\n /// @param limit Limit on the balance of bridge token this contract could hold\n /// @param hourlyLimit Limit on the hourly volume for this bridge\n /// @param paused Whether swapping for this token should be paused or not\n /// @param fee Fee taken upon swapping for or against this token\n function addBridgeToken(\n address bridgeToken,\n uint256 limit,\n uint256 hourlyLimit,\n uint64 fee,\n bool paused\n ) external onlyGovernor {\n if (bridges[bridgeToken].allowed || bridgeToken == address(0)) revert InvalidToken();\n if (fee > BASE_PARAMS) revert TooHighParameterValue();\n BridgeDetails memory _bridge;\n _bridge.limit = limit;\n _bridge.hourlyLimit = hourlyLimit;\n _bridge.paused = paused;\n _bridge.fee = fee;\n _bridge.allowed = true;\n bridges[bridgeToken] = _bridge;\n bridgeTokensList.push(bridgeToken);\n emit BridgeTokenAdded(bridgeToken, limit, hourlyLimit, fee, paused);\n }\n\n /// @notice Removes support for a token\n /// @param bridgeToken Address of the bridge token to remove support for\n function removeBridgeToken(address bridgeToken) external onlyGovernor {\n if (IERC20(bridgeToken).balanceOf(address(this)) != 0) revert AssetStillControlledInReserves();\n delete bridges[bridgeToken];\n // Deletion from `bridgeTokensList` loop\n uint256 bridgeTokensListLength = bridgeTokensList.length;\n for (uint256 i; i < bridgeTokensListLength - 1; ++i) {\n if (bridgeTokensList[i] == bridgeToken) {\n // Replace the `bridgeToken` to remove with the last of the list\n bridgeTokensList[i] = bridgeTokensList[bridgeTokensListLength - 1];\n break;\n }\n }\n // Remove last element in array\n bridgeTokensList.pop();\n emit BridgeTokenRemoved(bridgeToken);\n }\n\n /// @notice Recovers any ERC20 token\n /// @dev Can be used to withdraw bridge tokens for them to be de-bridged on mainnet\n function recoverERC20(address tokenAddress, address to, uint256 amountToRecover) external onlyGovernor {\n IERC20(tokenAddress).safeTransfer(to, amountToRecover);\n emit Recovered(tokenAddress, to, amountToRecover);\n }\n\n /// @notice Updates the `limit` amount for `bridgeToken`\n function setLimit(address bridgeToken, uint256 limit) external onlyGovernorOrGuardian {\n if (!bridges[bridgeToken].allowed) revert InvalidToken();\n bridges[bridgeToken].limit = limit;\n emit BridgeTokenLimitUpdated(bridgeToken, limit);\n }\n\n /// @notice Updates the `hourlyLimit` amount for `bridgeToken`\n function setHourlyLimit(address bridgeToken, uint256 hourlyLimit) external onlyGovernorOrGuardian {\n if (!bridges[bridgeToken].allowed) revert InvalidToken();\n bridges[bridgeToken].hourlyLimit = hourlyLimit;\n emit BridgeTokenHourlyLimitUpdated(bridgeToken, hourlyLimit);\n }\n\n /// @notice Updates the `chainTotalHourlyLimit` amount\n function setChainTotalHourlyLimit(uint256 hourlyLimit) external onlyGovernorOrGuardian {\n chainTotalHourlyLimit = hourlyLimit;\n emit HourlyLimitUpdated(hourlyLimit);\n }\n\n /// @notice Updates the `fee` value for `bridgeToken`\n function setSwapFee(address bridgeToken, uint64 fee) external onlyGovernorOrGuardian {\n if (!bridges[bridgeToken].allowed) revert InvalidToken();\n if (fee > BASE_PARAMS) revert TooHighParameterValue();\n bridges[bridgeToken].fee = fee;\n emit BridgeTokenFeeUpdated(bridgeToken, fee);\n }\n\n /// @notice Pauses or unpauses swapping in and out for a token\n function toggleBridge(address bridgeToken) external onlyGovernorOrGuardian {\n if (!bridges[bridgeToken].allowed) revert InvalidToken();\n bool pausedStatus = bridges[bridgeToken].paused;\n bridges[bridgeToken].paused = !pausedStatus;\n emit BridgeTokenToggled(bridgeToken, !pausedStatus);\n }\n\n /// @notice Toggles fees for the address `theAddress`\n function toggleFeesForAddress(address theAddress) external onlyGovernorOrGuardian {\n uint256 feeExemptStatus = 1 - isFeeExempt[theAddress];\n isFeeExempt[theAddress] = feeExemptStatus;\n emit FeeToggled(theAddress, feeExemptStatus);\n }\n}\n" + }, + "contracts/agToken/polygon/utils/ERC20UpgradeableCustom.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (token/ERC20/ERC20.sol)\n\npragma solidity ^0.8.0;\n\nimport \"@openzeppelin/contracts-upgradeable/token/ERC20/IERC20Upgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/token/ERC20/extensions/IERC20MetadataUpgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/utils/ContextUpgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol\";\n\n/**\n * @dev Implementation of the {IERC20} interface modified by Angle Labs, Inc.\n *\n * This implementation has a custom burn function to avoid having a {Transfer} event to the zero address\n * in some specific burn cases to avoid having Polygon PoS bridge catching this event\n *\n * TIP: For a detailed writeup see our guide\n * https://forum.zeppelin.solutions/t/how-to-implement-erc20-supply-mechanisms/226[How\n * to implement supply mechanisms].\n *\n * We have followed general OpenZeppelin Contracts guidelines: functions revert\n * instead returning `false` on failure. This behavior is nonetheless\n * conventional and does not conflict with the expectations of ERC20\n * applications.\n *\n * Additionally, an {Approval} event is emitted on calls to {transferFrom}.\n * This allows applications to reconstruct the allowance for all accounts just\n * by listening to said events. Other implementations of the EIP may not emit\n * these events, as it isn't required by the specification.\n *\n * Finally, the non-standard {decreaseAllowance} and {increaseAllowance}\n * functions have been added to mitigate the well-known issues around setting\n * allowances. See {IERC20-approve}.\n */\ncontract ERC20UpgradeableCustom is Initializable, ContextUpgradeable, IERC20Upgradeable, IERC20MetadataUpgradeable {\n mapping(address => uint256) private _balances;\n\n mapping(address => mapping(address => uint256)) private _allowances;\n\n uint256 private _totalSupply;\n\n string private _name;\n string private _symbol;\n\n /**\n * @dev Sets the values for {name} and {symbol}.\n *\n * The default value of {decimals} is 18. To select a different value for\n * {decimals} you should overload it.\n *\n * All two of these values are immutable: they can only be set once during\n * construction.\n */\n //solhint-disable-next-line\n function __ERC20_init(string memory name_, string memory symbol_) internal onlyInitializing {\n __Context_init_unchained();\n __ERC20_init_unchained(name_, symbol_);\n }\n\n //solhint-disable-next-line\n function __ERC20_init_unchained(string memory name_, string memory symbol_) internal onlyInitializing {\n _name = name_;\n _symbol = symbol_;\n }\n\n /**\n * @dev Returns the name of the token.\n */\n function name() public view virtual override returns (string memory) {\n return _name;\n }\n\n /**\n * @dev Returns the symbol of the token, usually a shorter version of the\n * name.\n */\n function symbol() public view virtual override returns (string memory) {\n return _symbol;\n }\n\n /**\n * @dev Returns the number of decimals used to get its user representation.\n * For example, if `decimals` equals `2`, a balance of `505` tokens should\n * be displayed to a user as `5.05` (`505 / 10 ** 2`).\n *\n * Tokens usually opt for a value of 18, imitating the relationship between\n * Ether and Wei. This is the value {ERC20} uses, unless this function is\n * overridden;\n *\n * NOTE: This information is only used for _display_ purposes: it in\n * no way affects any of the arithmetic of the contract, including\n * {IERC20-balanceOf} and {IERC20-transfer}.\n */\n function decimals() public view virtual override returns (uint8) {\n return 18;\n }\n\n /**\n * @dev See {IERC20-totalSupply}.\n */\n function totalSupply() public view virtual override returns (uint256) {\n return _totalSupply;\n }\n\n /**\n * @dev See {IERC20-balanceOf}.\n */\n function balanceOf(address account) public view virtual override returns (uint256) {\n return _balances[account];\n }\n\n /**\n * @dev See {IERC20-transfer}.\n *\n * Requirements:\n *\n * - `recipient` cannot be the zero address.\n * - the caller must have a balance of at least `amount`.\n */\n function transfer(address recipient, uint256 amount) public virtual override returns (bool) {\n _transfer(_msgSender(), recipient, amount);\n return true;\n }\n\n /**\n * @dev See {IERC20-allowance}.\n */\n function allowance(address owner, address spender) public view virtual override returns (uint256) {\n return _allowances[owner][spender];\n }\n\n /**\n * @dev See {IERC20-approve}.\n *\n * Requirements:\n *\n * - `spender` cannot be the zero address.\n */\n function approve(address spender, uint256 amount) public virtual override returns (bool) {\n _approve(_msgSender(), spender, amount);\n return true;\n }\n\n /**\n * @dev See {IERC20-transferFrom}.\n *\n * Emits an {Approval} event indicating the updated allowance. This is not\n * required by the EIP. See the note at the beginning of {ERC20}.\n *\n * Requirements:\n *\n * - `sender` and `recipient` cannot be the zero address.\n * - `sender` must have a balance of at least `amount`.\n * - the caller must have allowance for `sender`'s tokens of at least\n * `amount`.\n */\n function transferFrom(address sender, address recipient, uint256 amount) public virtual override returns (bool) {\n _transfer(sender, recipient, amount);\n\n uint256 currentAllowance = _allowances[sender][_msgSender()];\n require(currentAllowance >= amount, \"ERC20: transfer amount exceeds allowance\");\n unchecked {\n _approve(sender, _msgSender(), currentAllowance - amount);\n }\n\n return true;\n }\n\n /**\n * @dev Atomically increases the allowance granted to `spender` by the caller.\n *\n * This is an alternative to {approve} that can be used as a mitigation for\n * problems described in {IERC20-approve}.\n *\n * Emits an {Approval} event indicating the updated allowance.\n *\n * Requirements:\n *\n * - `spender` cannot be the zero address.\n */\n function increaseAllowance(address spender, uint256 addedValue) public virtual returns (bool) {\n _approve(_msgSender(), spender, _allowances[_msgSender()][spender] + addedValue);\n return true;\n }\n\n /**\n * @dev Atomically decreases the allowance granted to `spender` by the caller.\n *\n * This is an alternative to {approve} that can be used as a mitigation for\n * problems described in {IERC20-approve}.\n *\n * Emits an {Approval} event indicating the updated allowance.\n *\n * Requirements:\n *\n * - `spender` cannot be the zero address.\n * - `spender` must have allowance for the caller of at least\n * `subtractedValue`.\n */\n function decreaseAllowance(address spender, uint256 subtractedValue) public virtual returns (bool) {\n uint256 currentAllowance = _allowances[_msgSender()][spender];\n require(currentAllowance >= subtractedValue, \"ERC20: decreased allowance below zero\");\n unchecked {\n _approve(_msgSender(), spender, currentAllowance - subtractedValue);\n }\n\n return true;\n }\n\n /**\n * @dev Moves `amount` of tokens from `sender` to `recipient`.\n *\n * This internal function is equivalent to {transfer}, and can be used to\n * e.g. implement automatic token fees, slashing mechanisms, etc.\n *\n * Emits a {Transfer} event.\n *\n * Requirements:\n *\n * - `sender` cannot be the zero address.\n * - `recipient` cannot be the zero address.\n * - `sender` must have a balance of at least `amount`.\n */\n function _transfer(address sender, address recipient, uint256 amount) internal virtual {\n require(sender != address(0), \"ERC20: transfer from the zero address\");\n require(recipient != address(0), \"ERC20: transfer to the zero address\");\n\n _beforeTokenTransfer(sender, recipient, amount);\n\n uint256 senderBalance = _balances[sender];\n require(senderBalance >= amount, \"ERC20: transfer amount exceeds balance\");\n unchecked {\n _balances[sender] = senderBalance - amount;\n }\n _balances[recipient] += amount;\n\n emit Transfer(sender, recipient, amount);\n\n _afterTokenTransfer(sender, recipient, amount);\n }\n\n /** @dev Creates `amount` tokens and assigns them to `account`, increasing\n * the total supply.\n *\n * Emits a {Transfer} event with `from` set to the zero address.\n *\n * Requirements:\n *\n * - `account` cannot be the zero address.\n */\n function _mint(address account, uint256 amount) internal virtual {\n require(account != address(0), \"ERC20: mint to the zero address\");\n\n _beforeTokenTransfer(address(0), account, amount);\n\n _totalSupply += amount;\n _balances[account] += amount;\n emit Transfer(address(0), account, amount);\n\n _afterTokenTransfer(address(0), account, amount);\n }\n\n /**\n * @dev Destroys `amount` tokens from `account`, reducing the\n * total supply.\n *\n * Emits a {Transfer} event with `to` set to the zero address.\n *\n * Requirements:\n *\n * - `account` cannot be the zero address.\n * - `account` must have at least `amount` tokens.\n */\n function _burn(address account, uint256 amount) internal virtual {\n require(account != address(0), \"ERC20: burn from the zero address\");\n\n _beforeTokenTransfer(account, address(0), amount);\n\n uint256 accountBalance = _balances[account];\n require(accountBalance >= amount, \"ERC20: burn amount exceeds balance\");\n unchecked {\n _balances[account] = accountBalance - amount;\n }\n _totalSupply -= amount;\n\n emit Transfer(account, address(0), amount);\n\n _afterTokenTransfer(account, address(0), amount);\n }\n\n /**\n * @dev Destroys `amount` tokens from `account`, reducing the\n * total supply.\n *\n * Contrary to the other `burn` function, the {Transfer} event is not to the zero address\n * but rather to this address: the reason is that not all burn events should be caught up\n * by the PoS bridge\n *\n * Requirements:\n *\n * - `account` cannot be the zero address.\n * - `account` must have at least `amount` tokens.\n */\n function _burnCustom(address account, uint256 amount) internal virtual {\n require(account != address(0), \"ERC20: burn from the zero address\");\n\n _beforeTokenTransfer(account, address(0), amount);\n\n uint256 accountBalance = _balances[account];\n require(accountBalance >= amount, \"ERC20: burn amount exceeds balance\");\n unchecked {\n _balances[account] = accountBalance - amount;\n }\n _totalSupply -= amount;\n\n emit Transfer(account, address(this), amount);\n\n _afterTokenTransfer(account, address(0), amount);\n }\n\n /**\n * @dev Sets `amount` as the allowance of `spender` over the `owner` s tokens.\n *\n * This internal function is equivalent to `approve`, and can be used to\n * e.g. set automatic allowances for certain subsystems, etc.\n *\n * Emits an {Approval} event.\n *\n * Requirements:\n *\n * - `owner` cannot be the zero address.\n * - `spender` cannot be the zero address.\n */\n function _approve(address owner, address spender, uint256 amount) internal virtual {\n require(owner != address(0), \"ERC20: approve from the zero address\");\n require(spender != address(0), \"ERC20: approve to the zero address\");\n\n _allowances[owner][spender] = amount;\n emit Approval(owner, spender, amount);\n }\n\n /**\n * @dev Hook that is called before any transfer of tokens. This includes\n * minting and burning.\n *\n * Calling conditions:\n *\n * - when `from` and `to` are both non-zero, `amount` of `from`'s tokens\n * will be transferred to `to`.\n * - when `from` is zero, `amount` tokens will be minted for `to`.\n * - when `to` is zero, `amount` of `from`'s tokens will be burned.\n * - `from` and `to` are never both zero.\n *\n * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].\n */\n function _beforeTokenTransfer(address from, address to, uint256 amount) internal virtual {}\n\n /**\n * @dev Hook that is called after any transfer of tokens. This includes\n * minting and burning.\n *\n * Calling conditions:\n *\n * - when `from` and `to` are both non-zero, `amount` of `from`'s tokens\n * has been transferred to `to`.\n * - when `from` is zero, `amount` tokens have been minted for `to`.\n * - when `to` is zero, `amount` of `from`'s tokens have been burned.\n * - `from` and `to` are never both zero.\n *\n * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].\n */\n function _afterTokenTransfer(address from, address to, uint256 amount) internal virtual {}\n\n uint256[45] private __gap;\n}\n" + }, + "contracts/coreBorrow/CoreBorrow.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\n/*\n * █ \n ***** ▓▓▓ \n * ▓▓▓▓▓▓▓ \n * ///. ▓▓▓▓▓▓▓▓▓▓▓▓▓ \n ***** //////// ▓▓▓▓▓▓▓ \n * ///////////// ▓▓▓ \n ▓▓ ////////////////// █ ▓▓ \n ▓▓ ▓▓ /////////////////////// ▓▓ ▓▓ \n ▓▓ ▓▓ //////////////////////////// ▓▓ ▓▓ \n ▓▓ ▓▓ /////////▓▓▓///////▓▓▓///////// ▓▓ ▓▓ \n ▓▓ ,////////////////////////////////////// ▓▓ ▓▓ \n ▓▓ ////////////////////////////////////////// ▓▓ \n ▓▓ //////////////////////▓▓▓▓///////////////////// \n ,//////////////////////////////////////////////////// \n .////////////////////////////////////////////////////////// \n .//////////////////////////██.,//////////////////////////█ \n .//////////////////////████..,./////////////////////██ \n ...////////////////███████.....,.////////////////███ \n ,.,////////////████████ ........,///////////████ \n .,.,//////█████████ ,.......///////████ \n ,..//████████ ........./████ \n ..,██████ .....,███ \n .██ ,.,█ \n \n \n \n ▓▓ ▓▓▓▓▓▓▓▓▓▓ ▓▓▓▓▓▓▓▓▓▓ ▓▓ ▓▓▓▓▓▓▓▓▓▓ \n ▓▓▓▓▓▓ ▓▓▓ ▓▓▓ ▓▓▓ ▓▓ ▓▓ ▓▓▓▓ \n ▓▓▓ ▓▓▓ ▓▓▓ ▓▓▓ ▓▓▓ ▓▓▓ ▓▓ ▓▓▓▓▓ \n ▓▓▓ ▓▓ ▓▓▓ ▓▓▓ ▓▓▓▓▓▓▓▓▓▓ ▓▓▓▓▓▓▓▓▓▓ ▓▓▓▓▓▓▓▓▓▓ \n*/\n\npragma solidity ^0.8.12;\n\nimport \"@openzeppelin/contracts-upgradeable/access/AccessControlEnumerableUpgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol\";\n\nimport \"../interfaces/ICoreBorrow.sol\";\nimport \"../interfaces/IFlashAngle.sol\";\nimport \"../interfaces/ITreasury.sol\";\n\n/// @title CoreBorrow\n/// @author Angle Labs, Inc.\n/// @notice Core contract of the borrowing module. This contract handles the access control across all contracts\n/// (it is read by all treasury contracts), and manages the `flashLoanModule`. It has no minting rights over the\n/// stablecoin contracts\ncontract CoreBorrow is ICoreBorrow, Initializable, AccessControlEnumerableUpgradeable {\n /// @notice Role for guardians\n bytes32 public constant GUARDIAN_ROLE = keccak256(\"GUARDIAN_ROLE\");\n /// @notice Role for governors\n bytes32 public constant GOVERNOR_ROLE = keccak256(\"GOVERNOR_ROLE\");\n /// @notice Role for treasury contract\n bytes32 public constant FLASHLOANER_TREASURY_ROLE = keccak256(\"FLASHLOANER_TREASURY_ROLE\");\n\n // ============================= Reference =====================================\n\n /// @notice Reference to the `flashLoanModule` with minting rights over the different stablecoins of the protocol\n address public flashLoanModule;\n\n // =============================== Events ======================================\n\n event FlashLoanModuleUpdated(address indexed _flashloanModule);\n event CoreUpdated(address indexed _core);\n\n // =============================== Errors ======================================\n\n error InvalidCore();\n error IncompatibleGovernorAndGuardian();\n error NotEnoughGovernorsLeft();\n error ZeroAddress();\n\n /// @notice Initializes the `CoreBorrow` contract and the access control of the borrowing module\n /// @param governor Address of the governor of the Angle Protocol\n /// @param guardian Guardian address of the protocol\n function initialize(address governor, address guardian) public initializer {\n if (governor == address(0) || guardian == address(0)) revert ZeroAddress();\n if (governor == guardian) revert IncompatibleGovernorAndGuardian();\n _setupRole(GOVERNOR_ROLE, governor);\n _setupRole(GUARDIAN_ROLE, guardian);\n _setupRole(GUARDIAN_ROLE, governor);\n _setRoleAdmin(GUARDIAN_ROLE, GOVERNOR_ROLE);\n _setRoleAdmin(GOVERNOR_ROLE, GOVERNOR_ROLE);\n _setRoleAdmin(FLASHLOANER_TREASURY_ROLE, GOVERNOR_ROLE);\n }\n\n /// @custom:oz-upgrades-unsafe-allow constructor\n constructor() initializer {}\n\n // =========================== View Functions ==================================\n\n /// @inheritdoc ICoreBorrow\n function isFlashLoanerTreasury(address treasury) external view returns (bool) {\n return hasRole(FLASHLOANER_TREASURY_ROLE, treasury);\n }\n\n /// @inheritdoc ICoreBorrow\n function isGovernor(address admin) external view returns (bool) {\n return hasRole(GOVERNOR_ROLE, admin);\n }\n\n /// @inheritdoc ICoreBorrow\n function isGovernorOrGuardian(address admin) external view returns (bool) {\n return hasRole(GUARDIAN_ROLE, admin);\n }\n\n // =========================== Governor Functions ==============================\n\n /// @notice Grants the `FLASHLOANER_TREASURY_ROLE` to a `treasury` contract\n /// @param treasury Contract to grant the role to\n /// @dev This function can be used to allow flash loans on a stablecoin of the protocol\n function addFlashLoanerTreasuryRole(address treasury) external {\n grantRole(FLASHLOANER_TREASURY_ROLE, treasury);\n address _flashLoanModule = flashLoanModule;\n if (_flashLoanModule != address(0)) {\n // This call will revert if `treasury` is the zero address or if it is not linked\n // to this `CoreBorrow` contract\n ITreasury(treasury).setFlashLoanModule(_flashLoanModule);\n IFlashAngle(_flashLoanModule).addStablecoinSupport(treasury);\n }\n }\n\n /// @notice Adds a governor in the protocol\n /// @param governor Address to grant the role to\n /// @dev It is necessary to call this function to grant a governor role to make sure\n /// all governors also have the guardian role\n function addGovernor(address governor) external {\n grantRole(GOVERNOR_ROLE, governor);\n grantRole(GUARDIAN_ROLE, governor);\n }\n\n /// @notice Revokes the flash loan ability for a stablecoin\n /// @param treasury Treasury address associated with the stablecoin for which flash loans\n /// should no longer be available\n function removeFlashLoanerTreasuryRole(address treasury) external {\n revokeRole(FLASHLOANER_TREASURY_ROLE, treasury);\n ITreasury(treasury).setFlashLoanModule(address(0));\n address _flashLoanModule = flashLoanModule;\n if (_flashLoanModule != address(0)) {\n IFlashAngle(flashLoanModule).removeStablecoinSupport(treasury);\n }\n }\n\n /// @notice Revokes a governor from the protocol\n /// @param governor Address to remove the role to\n /// @dev It is necessary to call this function to remove a governor role to make sure\n /// the address also loses its guardian role\n function removeGovernor(address governor) external {\n if (getRoleMemberCount(GOVERNOR_ROLE) <= 1) revert NotEnoughGovernorsLeft();\n revokeRole(GUARDIAN_ROLE, governor);\n revokeRole(GOVERNOR_ROLE, governor);\n }\n\n /// @notice Changes the `flashLoanModule` of the protocol\n /// @param _flashLoanModule Address of the new flash loan module\n function setFlashLoanModule(address _flashLoanModule) external onlyRole(GOVERNOR_ROLE) {\n if (_flashLoanModule != address(0)) {\n if (address(IFlashAngle(_flashLoanModule).core()) != address(this)) revert InvalidCore();\n }\n uint256 count = getRoleMemberCount(FLASHLOANER_TREASURY_ROLE);\n for (uint256 i; i < count; ++i) {\n ITreasury(getRoleMember(FLASHLOANER_TREASURY_ROLE, i)).setFlashLoanModule(_flashLoanModule);\n }\n flashLoanModule = _flashLoanModule;\n emit FlashLoanModuleUpdated(_flashLoanModule);\n }\n\n /// @notice Changes the core contract of the protocol\n /// @param _core New core contract\n /// @dev This function verifies that all governors of the current core contract are also governors\n /// of the new core contract. It also notifies the `flashLoanModule` of the change.\n /// @dev Governance wishing to change the core contract should also make sure to call `setCore`\n /// in the different treasury contracts\n function setCore(ICoreBorrow _core) external onlyRole(GOVERNOR_ROLE) {\n uint256 count = getRoleMemberCount(GOVERNOR_ROLE);\n bool success;\n for (uint256 i; i < count; ++i) {\n success = _core.isGovernor(getRoleMember(GOVERNOR_ROLE, i));\n if (!success) break;\n }\n if (!success) revert InvalidCore();\n address _flashLoanModule = flashLoanModule;\n if (_flashLoanModule != address(0)) IFlashAngle(_flashLoanModule).setCore(address(_core));\n emit CoreUpdated(address(_core));\n }\n}\n" + }, + "contracts/deprecated/AgTokenIntermediateUpgrade.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\nimport \"../interfaces/IAgToken.sol\";\nimport \"../interfaces/coreModule/IStableMaster.sol\";\n// OpenZeppelin may update its version of the ERC20PermitUpgradeable token\nimport \"@openzeppelin/contracts-upgradeable/token/ERC20/extensions/draft-ERC20PermitUpgradeable.sol\";\n\n/// @title AgTokenIntermediateUpgrade\n/// @author Angle Labs, Inc.\n/// @notice Base contract for agToken, that is to say Angle's stablecoins\n/// @dev This contract is used to create and handle the stablecoins of Angle protocol\n/// @dev It is still possible for any address to burn its agTokens without redeeming collateral in exchange\n/// @dev This contract is the upgraded version of the AgToken that was first deployed on Ethereum mainnet and is used to\n/// add other minters as needed by AMOs\ncontract AgTokenIntermediateUpgrade is ERC20PermitUpgradeable {\n // ========================= References to other contracts =====================\n\n /// @notice Reference to the `StableMaster` contract associated to this `AgToken`\n address public stableMaster;\n\n // ============================= Constructor ===================================\n\n /// @notice Initializes the `AgToken` contract\n /// @param name_ Name of the token\n /// @param symbol_ Symbol of the token\n /// @param stableMaster_ Reference to the `StableMaster` contract associated to this agToken\n /// @dev By default, agTokens are ERC-20 tokens with 18 decimals\n function initialize(string memory name_, string memory symbol_, address stableMaster_) external initializer {\n __ERC20Permit_init(name_);\n __ERC20_init(name_, symbol_);\n require(stableMaster_ != address(0), \"0\");\n stableMaster = stableMaster_;\n }\n\n /// @custom:oz-upgrades-unsafe-allow constructor\n constructor() initializer {}\n\n // ======= Added Parameters and Variables from the first implementation ========\n\n /// @notice Checks whether an address has the right to mint agTokens\n mapping(address => bool) public isMinter;\n\n // =============================== Added Events ================================\n\n event MinterToggled(address indexed minter);\n\n // =============================== Setup Function ==============================\n\n /// @notice Sets up the minter role and gives it to the governor\n /// @dev This function just has to be called once\n function setUpMinter() external {\n address governor = 0xdC4e6DFe07EFCa50a197DF15D9200883eF4Eb1c8;\n require(msg.sender == governor);\n isMinter[governor] = true;\n emit MinterToggled(governor);\n }\n\n // =============================== Modifiers ===================================\n\n /// @notice Checks whether the sender has the minting right\n modifier onlyMinter() {\n require(isMinter[msg.sender] || msg.sender == stableMaster, \"35\");\n _;\n }\n\n // ========================= External Functions ================================\n // The following functions allow anyone to burn stablecoins without redeeming collateral\n // in exchange for that\n\n /// @notice Destroys `amount` token from the caller without giving collateral back\n /// @param amount Amount to burn\n /// @param poolManager Reference to the `PoolManager` contract for which the `stocksUsers` will\n /// need to be updated\n /// @dev When calling this function, people should specify the `poolManager` for which they want to decrease\n /// the `stocksUsers`: this is a way for the protocol to maintain healthy accounting variables\n function burnNoRedeem(uint256 amount, address poolManager) external {\n _burn(msg.sender, amount);\n IStableMaster(stableMaster).updateStocksUsers(amount, poolManager);\n }\n\n /// @notice Burns `amount` of agToken on behalf of another account without redeeming collateral back\n /// @param account Account to burn on behalf of\n /// @param amount Amount to burn\n /// @param poolManager Reference to the `PoolManager` contract for which the `stocksUsers` will need to be updated\n function burnFromNoRedeem(address account, uint256 amount, address poolManager) external {\n _burnFromNoRedeem(amount, account, msg.sender);\n IStableMaster(stableMaster).updateStocksUsers(amount, poolManager);\n }\n\n // ======================= Minter Role Only Functions ==========================\n\n /// @notice Burns `amount` tokens from a `burner` address\n /// @param amount Amount of tokens to burn\n /// @param burner Address to burn from\n /// @dev This method is to be called by a contract with a minter right on the AgToken after being\n /// requested to do so by an address willing to burn tokens from its address\n function burnSelf(uint256 amount, address burner) external onlyMinter {\n _burn(burner, amount);\n }\n\n /// @notice Burns `amount` tokens from a `burner` address after being asked to by `sender`\n /// @param amount Amount of tokens to burn\n /// @param burner Address to burn from\n /// @param sender Address which requested the burn from `burner`\n /// @dev This method is to be called by a contract with the minter right after being requested\n /// to do so by a `sender` address willing to burn tokens from another `burner` address\n /// @dev The method checks the allowance between the `sender` and the `burner`\n function burnFrom(uint256 amount, address burner, address sender) external onlyMinter {\n _burnFromNoRedeem(amount, burner, sender);\n }\n\n /// @notice Lets the `StableMaster` contract or another whitelisted contract mint agTokens\n /// @param account Address to mint to\n /// @param amount Amount to mint\n /// @dev The contracts allowed to issue agTokens are the `StableMaster` contract, `VaultManager` contracts\n /// associated to this stablecoin as well as the flash loan module (if activated) and potentially contracts\n /// whitelisted by governance\n function mint(address account, uint256 amount) external onlyMinter {\n _mint(account, amount);\n }\n\n // ======================= Minter Only Functions ===============================\n\n /// @notice Adds a minter in the contract\n /// @param minter Minter address to add\n function addMinter(address minter) external onlyMinter {\n isMinter[minter] = true;\n emit MinterToggled(minter);\n }\n\n /// @notice Removes a minter from the contract\n /// @param minter Minter address to remove\n /// @dev This function can at the moment only be called by a minter wishing to revoke itself\n function removeMinter(address minter) external {\n require(msg.sender == minter && isMinter[msg.sender], \"36\");\n isMinter[minter] = false;\n emit MinterToggled(minter);\n }\n\n // ============================ Internal Function ==============================\n\n /// @notice Internal version of the function `burnFromNoRedeem`\n /// @param amount Amount to burn\n /// @dev It is at the level of this function that allowance checks are performed\n function _burnFromNoRedeem(uint256 amount, address burner, address sender) internal {\n if (burner != sender) {\n uint256 currentAllowance = allowance(burner, sender);\n require(currentAllowance >= amount, \"23\");\n _approve(burner, sender, currentAllowance - amount);\n }\n _burn(burner, amount);\n }\n}\n" + }, + "contracts/deprecated/layerZero/OldLayerZeroBridgeToken.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.12;\n\nimport \"./OldOFTCore.sol\";\nimport \"../../interfaces/IAgTokenSideChainMultiBridge.sol\";\nimport \"@openzeppelin/contracts-upgradeable/security/PausableUpgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/token/ERC20/ERC20Upgradeable.sol\";\n\n/// @title LayerZeroBridgeToken\n/// @author Angle Labs, Inc., forked from https://github.com/LayerZero-Labs/solidity-examples/blob/main/contracts/token/oft/OFT.sol\n/// @notice Contract to be deployed on a L2/sidechain for bridging an AgToken using a bridge intermediate token and LayerZero\ncontract OldLayerZeroBridgeToken is OldOFTCore, ERC20Upgradeable, PausableUpgradeable {\n /// @notice Address of the bridgeable token\n /// @dev Immutable\n IAgTokenSideChainMultiBridge public canonicalToken;\n\n // =============================== Errors ================================\n\n error InvalidAllowance();\n\n // ============================= Constructor ===================================\n\n /// @notice Initializes the contract\n /// @param _name Name of the token corresponding to this contract\n /// @param _symbol Symbol of the token corresponding to this contract\n /// @param _lzEndpoint Layer zero endpoint to pass messages\n /// @param _treasury Address of the treasury contract used for access control\n /// @param initialSupply Initial supply to mint to the canonical token address\n /// @dev The initial supply corresponds to the initial amount that could be bridged using this OFT\n function initialize(\n string memory _name,\n string memory _symbol,\n address _lzEndpoint,\n address _treasury,\n uint256 initialSupply\n ) external initializer {\n __ERC20_init_unchained(_name, _symbol);\n __LzAppUpgradeable_init(_lzEndpoint, _treasury);\n\n canonicalToken = IAgTokenSideChainMultiBridge(address(ITreasury(_treasury).stablecoin()));\n _approve(address(this), address(canonicalToken), type(uint256).max);\n _mint(address(canonicalToken), initialSupply);\n }\n\n /// @custom:oz-upgrades-unsafe-allow constructor\n constructor() initializer {}\n\n // ==================== External Permissionless Functions ======================\n\n function sendWithPermit(\n uint16 _dstChainId,\n bytes memory _toAddress,\n uint256 _amount,\n address payable _refundAddress,\n address _zroPaymentAddress,\n bytes memory _adapterParams,\n uint256 deadline,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) public payable override {\n canonicalToken.permit(msg.sender, address(this), _amount, deadline, v, r, s);\n send(_dstChainId, _toAddress, _amount, _refundAddress, _zroPaymentAddress, _adapterParams);\n }\n\n function withdraw(uint256 amount, address recipient) external override returns (uint256 amountMinted) {\n // Does not check allowances as transfers from `msg.sender`\n _transfer(msg.sender, address(this), amount);\n amountMinted = canonicalToken.swapIn(address(this), amount, recipient);\n uint256 leftover = balanceOf(address(this));\n if (leftover != 0) {\n _transfer(address(this), msg.sender, leftover);\n }\n }\n\n // ============================= Internal Functions ===================================\n\n function _debitFrom(\n uint16,\n bytes memory,\n uint256 _amount\n ) internal override whenNotPaused returns (uint256 amountSwapped) {\n // No need to use safeTransferFrom as we know this implementation reverts on failure\n canonicalToken.transferFrom(msg.sender, address(this), _amount);\n\n // Swap canonical for this bridge token. There may be some fees\n amountSwapped = canonicalToken.swapOut(address(this), _amount, address(this));\n _burn(address(this), amountSwapped);\n }\n\n function _debitCreditFrom(uint16, bytes memory, uint256 _amount) internal override whenNotPaused returns (uint256) {\n _burn(msg.sender, _amount);\n return _amount;\n }\n\n function _creditTo(\n uint16,\n address _toAddress,\n uint256 _amount\n ) internal override whenNotPaused returns (uint256 amountMinted) {\n _mint(address(this), _amount);\n amountMinted = canonicalToken.swapIn(address(this), _amount, _toAddress);\n uint256 leftover = balanceOf(address(this));\n if (leftover != 0) {\n _transfer(address(this), _toAddress, leftover);\n }\n }\n\n // ======================= View Functions ================================\n\n /// @inheritdoc ERC165Upgradeable\n function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {\n return\n interfaceId == type(IOFT).interfaceId ||\n interfaceId == type(IERC20).interfaceId ||\n super.supportsInterface(interfaceId);\n }\n\n // ======================= Governance Functions ================================\n\n /// @notice Mints the intermediate contract to the `canonicalToken`\n /// @dev Used to increase the bridging capacity\n function mint(uint256 amount) external onlyGovernorOrGuardian {\n _mint(address(canonicalToken), amount);\n }\n\n /// @notice Burns the intermediate contract from the `canonicalToken`\n /// @dev Used to decrease the bridging capacity\n function burn(uint256 amount) external onlyGovernorOrGuardian {\n _burn(address(canonicalToken), amount);\n }\n\n /// @notice Increases allowance of the `canonicalToken`\n function setupAllowance() public onlyGovernorOrGuardian {\n _approve(address(this), address(canonicalToken), type(uint256).max);\n }\n\n /// @notice Pauses bridging through the contract\n /// @param pause Future pause status\n function pauseSendTokens(bool pause) external onlyGovernorOrGuardian {\n pause ? _pause() : _unpause();\n }\n\n uint256[49] private __gap;\n}\n" + }, + "contracts/deprecated/layerZero/OldNonblockingLzApp.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.12;\n\nimport \"@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol\";\nimport \"../../interfaces/external/layerZero/ILayerZeroReceiver.sol\";\nimport \"../../interfaces/external/layerZero/ILayerZeroUserApplicationConfig.sol\";\nimport \"../../interfaces/external/layerZero/ILayerZeroEndpoint.sol\";\nimport \"../../interfaces/ITreasury.sol\";\n\n/// @title OldNonblockingLzApp\n/// @author Angle Labs, Inc., forked from https://github.com/LayerZero-Labs/solidity-examples/\n/// @notice Base contract for bridging using LayerZero\nabstract contract OldNonblockingLzApp is Initializable, ILayerZeroReceiver, ILayerZeroUserApplicationConfig {\n /// @notice Layer Zero endpoint\n ILayerZeroEndpoint public lzEndpoint;\n\n /// @notice Maps chainIds to failed messages to retry them\n mapping(uint16 => mapping(bytes => mapping(uint64 => bytes32))) public failedMessages;\n\n /// @notice Maps chainIds to their OFT address\n mapping(uint16 => bytes) public trustedRemoteLookup;\n\n /// @notice Reference to the treasury contract to fetch access control\n address public treasury;\n\n // ================================== Events ===================================\n\n event SetTrustedRemote(uint16 _srcChainId, bytes _srcAddress);\n event MessageFailed(uint16 _srcChainId, bytes _srcAddress, uint64 _nonce, bytes _payload);\n\n // =============================== Errors ================================\n\n error NotGovernor();\n error NotGovernorOrGuardian();\n error InsufficientGas();\n error InvalidEndpoint();\n error InvalidSource();\n error InvalidCaller();\n error InvalidParams();\n error InvalidPayload();\n error ZeroAddress();\n\n // ============================= Constructor ===================================\n\n //solhint-disable-next-line\n function __LzAppUpgradeable_init(address _endpoint, address _treasury) internal {\n if (_endpoint == address(0) || _treasury == address(0)) revert ZeroAddress();\n lzEndpoint = ILayerZeroEndpoint(_endpoint);\n treasury = _treasury;\n }\n\n // =============================== Modifiers ===================================\n\n /// @notice Checks whether the `msg.sender` has the governor role or the guardian role\n modifier onlyGovernorOrGuardian() {\n if (!ITreasury(treasury).isGovernorOrGuardian(msg.sender)) revert NotGovernorOrGuardian();\n _;\n }\n\n // ==================== External Permissionless Functions ======================\n\n /// @notice Receives a message from the LZ endpoint and process it\n /// @param _srcChainId ChainId of the source chain - LayerZero standard\n /// @param _srcAddress Sender of the source chain\n /// @param _nonce Nounce of the message\n /// @param _payload Data: recipient address and amount\n function lzReceive(\n uint16 _srcChainId,\n bytes memory _srcAddress,\n uint64 _nonce,\n bytes memory _payload\n ) public virtual override {\n // lzReceive must be called by the endpoint for security\n if (msg.sender != address(lzEndpoint)) revert InvalidEndpoint();\n\n bytes memory trustedRemote = trustedRemoteLookup[_srcChainId];\n // if will still block the message pathway from (srcChainId, srcAddress). should not receive message from untrusted remote.\n if (_srcAddress.length != trustedRemote.length || keccak256(_srcAddress) != keccak256(trustedRemote))\n revert InvalidSource();\n\n _blockingLzReceive(_srcChainId, _srcAddress, _nonce, _payload);\n }\n\n /// @notice Retries a message that previously failed and was stored\n /// @param _srcChainId ChainId of the source chain - LayerZero standard\n /// @param _srcAddress Sender of the source chain\n /// @param _nonce Nounce of the message\n /// @param _payload Data: recipient address and amount\n function retryMessage(\n uint16 _srcChainId,\n bytes memory _srcAddress,\n uint64 _nonce,\n bytes memory _payload\n ) public payable virtual {\n // assert there is message to retry\n bytes32 payloadHash = failedMessages[_srcChainId][_srcAddress][_nonce];\n if (payloadHash == bytes32(0) || keccak256(_payload) != payloadHash) revert InvalidPayload();\n // clear the stored message\n failedMessages[_srcChainId][_srcAddress][_nonce] = bytes32(0);\n // execute the message. revert if it fails again\n _nonblockingLzReceive(_srcChainId, _srcAddress, _nonce, _payload);\n }\n\n // ============================= Internal Functions ===================================\n\n /// @notice Handles message receptions in a non blocking way\n /// @param _srcChainId ChainId of the source chain - LayerZero standard\n /// @param _srcAddress Sender of the source chain\n /// @param _nonce Nounce of the message\n /// @param _payload Data: recipient address and amount\n /// @dev public for the needs of try / catch but effectively internal\n function nonblockingLzReceive(\n uint16 _srcChainId,\n bytes memory _srcAddress,\n uint64 _nonce,\n bytes memory _payload\n ) public virtual {\n // only internal transaction\n if (msg.sender != address(this)) revert InvalidCaller();\n _nonblockingLzReceive(_srcChainId, _srcAddress, _nonce, _payload);\n }\n\n /// @notice Handles message receptions in a non blocking way\n /// @param _srcChainId ChainId of the source chain - LayerZero standard\n /// @param _srcAddress Sender of the source chain\n /// @param _nonce Nounce of the message\n /// @param _payload Data: recipient address and amount\n function _nonblockingLzReceive(\n uint16 _srcChainId,\n bytes memory _srcAddress,\n uint64 _nonce,\n bytes memory _payload\n ) internal virtual;\n\n /// @notice Handles message receptions in a blocking way\n /// @param _srcChainId ChainId of the source chain - LayerZero standard\n /// @param _srcAddress Sender of the source chain\n /// @param _nonce Nounce of the message\n /// @param _payload Data: recipient address and amount\n function _blockingLzReceive(\n uint16 _srcChainId,\n bytes memory _srcAddress,\n uint64 _nonce,\n bytes memory _payload\n ) internal {\n // try-catch all errors/exceptions\n try this.nonblockingLzReceive(_srcChainId, _srcAddress, _nonce, _payload) {\n // do nothing\n } catch {\n // error / exception\n failedMessages[_srcChainId][_srcAddress][_nonce] = keccak256(_payload);\n emit MessageFailed(_srcChainId, _srcAddress, _nonce, _payload);\n }\n }\n\n /// @notice Sends a message to the LZ endpoint and process it\n /// @param _dstChainId L0 defined chain id to send tokens too\n /// @param _payload Data: recipient address and amount\n /// @param _refundAddress Address LayerZero refunds if too much message fee is sent\n /// @param _zroPaymentAddress Set to address(0x0) if not paying in ZRO (LayerZero Token)\n /// @param _adapterParams Flexible bytes array to indicate messaging adapter services in L0\n function _lzSend(\n uint16 _dstChainId,\n bytes memory _payload,\n address payable _refundAddress,\n address _zroPaymentAddress,\n bytes memory _adapterParams\n ) internal virtual {\n bytes memory trustedRemote = trustedRemoteLookup[_dstChainId];\n if (trustedRemote.length == 0) revert InvalidSource();\n //solhint-disable-next-line\n lzEndpoint.send{ value: msg.value }(\n _dstChainId,\n trustedRemote,\n _payload,\n _refundAddress,\n _zroPaymentAddress,\n _adapterParams\n );\n }\n\n // ======================= Governance Functions ================================\n\n /// @notice Sets the corresponding address on an other chain.\n /// @param _srcChainId ChainId of the source chain - LayerZero standard\n /// @param _srcAddress Address on the source chain\n /// @dev Used for both receiving and sending message\n /// @dev There can only be one trusted source per chain\n /// @dev Allows owner to set it multiple times.\n function setTrustedRemote(uint16 _srcChainId, bytes calldata _srcAddress) external onlyGovernorOrGuardian {\n trustedRemoteLookup[_srcChainId] = _srcAddress;\n emit SetTrustedRemote(_srcChainId, _srcAddress);\n }\n\n /// @notice Fetches the default LZ config\n function getConfig(\n uint16 _version,\n uint16 _chainId,\n address,\n uint256 _configType\n ) external view returns (bytes memory) {\n return lzEndpoint.getConfig(_version, _chainId, address(this), _configType);\n }\n\n /// @notice Overrides the default LZ config\n function setConfig(\n uint16 _version,\n uint16 _chainId,\n uint256 _configType,\n bytes calldata _config\n ) external override onlyGovernorOrGuardian {\n lzEndpoint.setConfig(_version, _chainId, _configType, _config);\n }\n\n /// @notice Overrides the default LZ config\n function setSendVersion(uint16 _version) external override onlyGovernorOrGuardian {\n lzEndpoint.setSendVersion(_version);\n }\n\n /// @notice Overrides the default LZ config\n function setReceiveVersion(uint16 _version) external override onlyGovernorOrGuardian {\n lzEndpoint.setReceiveVersion(_version);\n }\n\n /// @notice Unpauses the receive functionalities\n function forceResumeReceive(\n uint16 _srcChainId,\n bytes calldata _srcAddress\n ) external override onlyGovernorOrGuardian {\n lzEndpoint.forceResumeReceive(_srcChainId, _srcAddress);\n }\n\n // ======================= View Functions ================================\n\n /// @notice Checks if the `_srcAddress` corresponds to the trusted source\n function isTrustedRemote(uint16 _srcChainId, bytes calldata _srcAddress) external view returns (bool) {\n bytes memory trustedSource = trustedRemoteLookup[_srcChainId];\n return keccak256(trustedSource) == keccak256(_srcAddress);\n }\n\n uint256[46] private __gap;\n}\n" + }, + "contracts/deprecated/layerZero/OldOFTCore.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.12;\n\nimport \"./OldNonblockingLzApp.sol\";\nimport \"../../agToken/layerZero/utils/IOFTCore.sol\";\nimport \"@openzeppelin/contracts-upgradeable/utils/introspection/ERC165Upgradeable.sol\";\n\n/// @title OFTCore\n/// @author Forked from https://github.com/LayerZero-Labs/solidity-examples/blob/main/contracts/token/oft/OFTCore.sol\n/// but with slight modifications from the Angle Labs, Inc. which added return values to the `_creditTo` and `_debitFrom` functions\n/// @notice Base contract for bridging using LayerZero\nabstract contract OldOFTCore is OldNonblockingLzApp, ERC165Upgradeable, IOFTCore {\n // ==================== External Permissionless Functions ======================\n\n /// @inheritdoc IOFTCore\n function sendWithPermit(\n uint16 _dstChainId,\n bytes memory _toAddress,\n uint256 _amount,\n address payable _refundAddress,\n address _zroPaymentAddress,\n bytes memory _adapterParams,\n uint256 deadline,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) public payable virtual;\n\n /// @inheritdoc IOFTCore\n function send(\n uint16 _dstChainId,\n bytes memory _toAddress,\n uint256 _amount,\n address payable _refundAddress,\n address _zroPaymentAddress,\n bytes memory _adapterParams\n ) public payable virtual {\n _amount = _debitFrom(_dstChainId, _toAddress, _amount);\n\n bytes memory payload = abi.encode(_toAddress, _amount);\n _lzSend(_dstChainId, payload, _refundAddress, _zroPaymentAddress, _adapterParams);\n\n uint64 nonce = lzEndpoint.getOutboundNonce(_dstChainId, address(this));\n emit SendToChain(msg.sender, _dstChainId, _toAddress, _amount, nonce);\n }\n\n /// @inheritdoc IOFTCore\n function sendCredit(\n uint16 _dstChainId,\n bytes memory _toAddress,\n uint256 _amount,\n address payable _refundAddress,\n address _zroPaymentAddress,\n bytes memory _adapterParams\n ) public payable virtual {\n _amount = _debitCreditFrom(_dstChainId, _toAddress, _amount);\n\n _send(_dstChainId, _toAddress, _amount, _refundAddress, _zroPaymentAddress, _adapterParams);\n }\n\n /// @inheritdoc IOFTCore\n function withdraw(uint256 amount, address recipient) external virtual returns (uint256);\n\n // =========================== Internal Functions ==============================\n\n /// @notice Internal function to send `_amount` amount of token to (`_dstChainId`, `_toAddress`)\n /// @param _dstChainId the destination chain identifier\n /// @param _toAddress can be any size depending on the `dstChainId`.\n /// @param _amount the quantity of tokens in wei\n /// @param _refundAddress the address LayerZero refunds if too much message fee is sent\n /// @param _zroPaymentAddress set to address(0x0) if not paying in ZRO (LayerZero Token)\n /// @param _adapterParams is a flexible bytes array to indicate messaging adapter services\n /// @dev Accounting and checks should be performed beforehand\n function _send(\n uint16 _dstChainId,\n bytes memory _toAddress,\n uint256 _amount,\n address payable _refundAddress,\n address _zroPaymentAddress,\n bytes memory _adapterParams\n ) internal {\n bytes memory payload = abi.encode(_toAddress, _amount);\n _lzSend(_dstChainId, payload, _refundAddress, _zroPaymentAddress, _adapterParams);\n\n uint64 nonce = lzEndpoint.getOutboundNonce(_dstChainId, address(this));\n emit SendToChain(msg.sender, _dstChainId, _toAddress, _amount, nonce);\n }\n\n function _nonblockingLzReceive(\n uint16 _srcChainId,\n bytes memory _srcAddress,\n uint64 _nonce,\n bytes memory _payload\n ) internal virtual override {\n // decode and load the toAddress\n (bytes memory toAddressBytes, uint256 amount) = abi.decode(_payload, (bytes, uint256));\n address toAddress;\n //solhint-disable-next-line\n assembly {\n toAddress := mload(add(toAddressBytes, 20))\n }\n amount = _creditTo(_srcChainId, toAddress, amount);\n\n emit ReceiveFromChain(_srcChainId, _srcAddress, toAddress, amount, _nonce);\n }\n\n /// @notice Makes accountability when bridging from this contract using canonical token\n /// @param _dstChainId ChainId of the destination chain - LayerZero standard\n /// @param _toAddress Recipient on the destination chain\n /// @param _amount Amount to bridge\n function _debitFrom(\n uint16 _dstChainId,\n bytes memory _toAddress,\n uint256 _amount\n ) internal virtual returns (uint256);\n\n /// @notice Makes accountability when bridging from this contract's credit\n /// @param _dstChainId ChainId of the destination chain - LayerZero standard\n /// @param _toAddress Recipient on the destination chain\n /// @param _amount Amount to bridge\n function _debitCreditFrom(\n uint16 _dstChainId,\n bytes memory _toAddress,\n uint256 _amount\n ) internal virtual returns (uint256);\n\n /// @notice Makes accountability when bridging to this contract\n /// @param _srcChainId ChainId of the source chain - LayerZero standard\n /// @param _toAddress Recipient on this chain\n /// @param _amount Amount to bridge\n function _creditTo(uint16 _srcChainId, address _toAddress, uint256 _amount) internal virtual returns (uint256);\n\n // ========================== View Functions ===================================\n\n /// @inheritdoc ERC165Upgradeable\n function supportsInterface(\n bytes4 interfaceId\n ) public view virtual override(ERC165Upgradeable, IERC165) returns (bool) {\n return interfaceId == type(IOFTCore).interfaceId || super.supportsInterface(interfaceId);\n }\n\n /// @inheritdoc IOFTCore\n function estimateSendFee(\n uint16 _dstChainId,\n bytes memory _toAddress,\n uint256 _amount,\n bool _useZro,\n bytes memory _adapterParams\n ) public view virtual override returns (uint256 nativeFee, uint256 zroFee) {\n // mock the payload for send()\n bytes memory payload = abi.encode(_toAddress, _amount);\n return lzEndpoint.estimateFees(_dstChainId, address(this), payload, _useZro, _adapterParams);\n }\n\n uint256[50] private __gap;\n}\n" + }, + "contracts/deprecated/OldAgEUR.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\nimport \"../interfaces/IAgToken.sol\";\nimport \"../interfaces/coreModule/IStableMaster.sol\";\nimport \"../interfaces/ITreasury.sol\";\n// OpenZeppelin may update its version of the ERC20PermitUpgradeable token\nimport \"@openzeppelin/contracts-upgradeable/token/ERC20/extensions/draft-ERC20PermitUpgradeable.sol\";\n\n/// @title AgToken\n/// @author Angle Labs, Inc.\n/// @notice Base contract for agToken, that is to say Angle's stablecoins\n/// @dev This contract is used to create and handle the stablecoins of Angle protocol\n/// @dev It is still possible for any address to burn its agTokens without redeeming collateral in exchange\n/// @dev This contract is the upgraded version of the AgToken that was first deployed on Ethereum mainnet\ncontract OldAgEUR is IAgToken, ERC20PermitUpgradeable {\n // ========================= References to other contracts =====================\n\n /// @notice Reference to the `StableMaster` contract associated to this `AgToken`\n address public stableMaster;\n\n // ============================= Constructor ===================================\n\n /// @notice Initializes the `AgToken` contract\n /// @param name_ Name of the token\n /// @param symbol_ Symbol of the token\n /// @param stableMaster_ Reference to the `StableMaster` contract associated to this agToken\n /// @dev By default, agTokens are ERC-20 tokens with 18 decimals\n function initialize(string memory name_, string memory symbol_, address stableMaster_) external initializer {\n __ERC20Permit_init(name_);\n __ERC20_init(name_, symbol_);\n require(stableMaster_ != address(0), \"0\");\n stableMaster = stableMaster_;\n }\n\n /// @custom:oz-upgrades-unsafe-allow constructor\n constructor() initializer {}\n\n // ======= Added Parameters and Variables from the first implementation ========\n\n /// @inheritdoc IAgToken\n mapping(address => bool) public isMinter;\n /// @notice Reference to the treasury contract which can grant minting rights\n address public treasury;\n /// @notice Boolean to check whether the contract has been reinitialized after its upgrade\n bool public treasuryInitialized;\n\n // =============================== Added Events ================================\n\n event TreasuryUpdated(address indexed _treasury);\n event MinterToggled(address indexed minter);\n\n // =============================== Added Errors ================================\n\n error BurnAmountExceedsAllowance();\n error InvalidSender();\n error InvalidTreasury();\n error NotGovernor();\n error NotMinter();\n error NotTreasury();\n error TreasuryAlreadyInitialized();\n\n // =============================== Setup Function ==============================\n\n /// @notice Sets up the treasury contract in this AgToken contract\n /// @param _treasury Treasury contract to add\n /// @dev The address calling this function has to be hard-coded in the contract\n /// @dev Can be called only once\n function setUpTreasury(address _treasury) external {\n // Only governor\n if (msg.sender != 0xdC4e6DFe07EFCa50a197DF15D9200883eF4Eb1c8) revert NotGovernor();\n if (address(ITreasury(_treasury).stablecoin()) != address(this)) revert InvalidTreasury();\n if (treasuryInitialized) revert TreasuryAlreadyInitialized();\n treasury = _treasury;\n treasuryInitialized = true;\n isMinter[stableMaster] = true;\n emit TreasuryUpdated(_treasury);\n }\n\n // =============================== Modifiers ===================================\n\n /// @notice Checks to see if it is the `Treasury` calling this contract\n /// @dev There is no Access Control here, because it can be handled cheaply through this modifier\n modifier onlyTreasury() {\n if (msg.sender != treasury) revert NotTreasury();\n _;\n }\n\n /// @notice Checks whether the sender has the minting right\n modifier onlyMinter() {\n if (!isMinter[msg.sender]) revert NotMinter();\n _;\n }\n\n // ========================= External Functions ================================\n // The following functions allow anyone to burn stablecoins without redeeming collateral\n // in exchange for that\n\n /// @notice Destroys `amount` token from the caller without giving collateral back\n /// @param amount Amount to burn\n /// @param poolManager Reference to the `PoolManager` contract for which the `stocksUsers` will\n /// need to be updated\n /// @dev When calling this function, people should specify the `poolManager` for which they want to decrease\n /// the `stocksUsers`: this is a way for the protocol to maintain healthy accounting variables\n function burnNoRedeem(uint256 amount, address poolManager) external {\n _burn(msg.sender, amount);\n IStableMaster(stableMaster).updateStocksUsers(amount, poolManager);\n }\n\n /// @notice Burns `amount` of agToken on behalf of another account without redeeming collateral back\n /// @param account Account to burn on behalf of\n /// @param amount Amount to burn\n /// @param poolManager Reference to the `PoolManager` contract for which the `stocksUsers` will need to be updated\n function burnFromNoRedeem(address account, uint256 amount, address poolManager) external {\n _burnFromNoRedeem(amount, account, msg.sender);\n IStableMaster(stableMaster).updateStocksUsers(amount, poolManager);\n }\n\n /// @notice Allows anyone to burn agToken without redeeming collateral back\n /// @param amount Amount of stablecoins to burn\n /// @dev This function can typically be called if there is a settlement mechanism to burn stablecoins\n function burnStablecoin(uint256 amount) external {\n _burn(msg.sender, amount);\n }\n\n // ======================= Minter Role Only Functions ==========================\n\n /// @inheritdoc IAgToken\n function burnSelf(uint256 amount, address burner) external onlyMinter {\n _burn(burner, amount);\n }\n\n /// @inheritdoc IAgToken\n function burnFrom(uint256 amount, address burner, address sender) external onlyMinter {\n _burnFromNoRedeem(amount, burner, sender);\n }\n\n /// @inheritdoc IAgToken\n function mint(address account, uint256 amount) external onlyMinter {\n _mint(account, amount);\n }\n\n // ======================= Treasury Only Functions =============================\n\n /// @inheritdoc IAgToken\n function addMinter(address minter) external onlyTreasury {\n isMinter[minter] = true;\n emit MinterToggled(minter);\n }\n\n /// @inheritdoc IAgToken\n function removeMinter(address minter) external {\n // The `treasury` contract cannot remove the `stableMaster`\n if (msg.sender != minter && (msg.sender != address(treasury) || minter == stableMaster)) revert InvalidSender();\n isMinter[minter] = false;\n emit MinterToggled(minter);\n }\n\n /// @inheritdoc IAgToken\n function setTreasury(address _treasury) external onlyTreasury {\n treasury = _treasury;\n emit TreasuryUpdated(_treasury);\n }\n\n // ============================ Internal Function ==============================\n\n /// @notice Internal version of the function `burnFromNoRedeem`\n /// @param amount Amount to burn\n /// @dev It is at the level of this function that allowance checks are performed\n function _burnFromNoRedeem(uint256 amount, address burner, address sender) internal {\n if (burner != sender) {\n uint256 currentAllowance = allowance(burner, sender);\n if (currentAllowance < amount) revert BurnAmountExceedsAllowance();\n _approve(burner, sender, currentAllowance - amount);\n }\n _burn(burner, amount);\n }\n}\n" + }, + "contracts/deprecated/OldAngleHelpers.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\nimport \"../interfaces/IAngleRouter.sol\";\nimport \"../interfaces/coreModule/IAgTokenMainnet.sol\";\nimport \"../interfaces/coreModule/ICore.sol\";\nimport \"../interfaces/coreModule/IOracleCore.sol\";\nimport \"../interfaces/coreModule/IPerpetualManager.sol\";\nimport \"../interfaces/coreModule/IPoolManager.sol\";\nimport \"../interfaces/coreModule/IStableMaster.sol\";\nimport \"@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol\";\nimport \"../interfaces/IVaultManager.sol\";\n\npragma solidity ^0.8.12;\n\nstruct Parameters {\n SLPData slpData;\n MintBurnData feeData;\n PerpetualManagerFeeData perpFeeData;\n PerpetualManagerParamData perpParam;\n}\n\nstruct PerpetualManagerFeeData {\n uint64[] xHAFeesDeposit;\n uint64[] yHAFeesDeposit;\n uint64[] xHAFeesWithdraw;\n uint64[] yHAFeesWithdraw;\n uint64 haBonusMalusDeposit;\n uint64 haBonusMalusWithdraw;\n}\n\nstruct PerpetualManagerParamData {\n uint64 maintenanceMargin;\n uint64 maxLeverage;\n uint64 targetHAHedge;\n uint64 limitHAHedge;\n uint64 lockTime;\n}\n\nstruct CollateralAddresses {\n address stableMaster;\n address poolManager;\n address perpetualManager;\n address sanToken;\n address oracle;\n address gauge;\n address feeManager;\n address[] strategies;\n}\n\n/// @title AngleHelpers\n/// @author Angle Labs, Inc.\n/// @notice Contract with view functions designed to facilitate integrations on the Core module of the Angle Protocol\n/// @dev This contract only contains view functions to be queried off-chain. It was thus not optimized for gas consumption\ncontract OldAngleHelpers is Initializable {\n // ======================== Helper View Functions ==============================\n\n /// @notice Gives the amount of `agToken` you'd be getting if you were executing in the same block a mint transaction\n /// with `amount` of `collateral` in the Core module of the Angle protocol as well as the value of the fees\n /// (in `BASE_PARAMS`) that would be applied during the mint\n /// @return Amount of `agToken` that would be obtained with a mint transaction in the same block\n /// @return Percentage of fees that would be taken during a mint transaction in the same block\n /// @dev This function reverts if the mint transaction was to revert in the same conditions (without taking into account\n /// potential approval problems to the `StableMaster` contract)\n function previewMintAndFees(\n uint256 amount,\n address agToken,\n address collateral\n ) external view returns (uint256, uint256) {\n return _previewMintAndFees(amount, agToken, collateral);\n }\n\n /// @notice Gives the amount of `collateral` you'd be getting if you were executing in the same block a burn transaction\n /// with `amount` of `agToken` in the Core module of the Angle protocol as well as the value of the fees\n /// (in `BASE_PARAMS`) that would be applied during the burn\n /// @return Amount of `collateral` that would be obtained with a burn transaction in the same block\n /// @return Percentage of fees that would be taken during a burn transaction in the same block\n /// @dev This function reverts if the burn transaction was to revert in the same conditions (without taking into account\n /// potential approval problems to the `StableMaster` contract or agToken balance prior to the call)\n function previewBurnAndFees(\n uint256 amount,\n address agToken,\n address collateral\n ) external view returns (uint256, uint256) {\n return _previewBurnAndFees(amount, agToken, collateral);\n }\n\n /// @notice Returns all the addresses associated to the (`agToken`,`collateral`) pair given\n /// @return addresses A struct with all the addresses associated in the Core module\n function getCollateralAddresses(\n address agToken,\n address collateral\n ) external view returns (CollateralAddresses memory addresses) {\n address stableMaster = IAgTokenMainnet(agToken).stableMaster();\n (address poolManager, address perpetualManager, address sanToken, address gauge) = ROUTER.mapPoolManagers(\n stableMaster,\n collateral\n );\n (, , , IOracleCore oracle, , , , , ) = IStableMaster(stableMaster).collateralMap(poolManager);\n addresses.stableMaster = stableMaster;\n addresses.poolManager = poolManager;\n addresses.perpetualManager = perpetualManager;\n addresses.sanToken = sanToken;\n addresses.gauge = gauge;\n addresses.oracle = address(oracle);\n addresses.feeManager = IPoolManager(poolManager).feeManager();\n\n uint256 length = 0;\n while (true) {\n try IPoolManager(poolManager).strategyList(length) returns (address) {\n length += 1;\n } catch {\n break;\n }\n }\n address[] memory strategies = new address[](length);\n for (uint256 i; i < length; ++i) {\n strategies[i] = IPoolManager(poolManager).strategyList(i);\n }\n addresses.strategies = strategies;\n }\n\n /// @notice Gets the addresses of all the `StableMaster` contracts and their associated `AgToken` addresses\n /// @return List of the `StableMaster` addresses of the Angle protocol\n /// @return List of the `AgToken` addresses of the protocol\n /// @dev The place of an agToken address in the list is the same as the corresponding `StableMaster` address\n function getStablecoinAddresses() external view returns (address[] memory, address[] memory) {\n address[] memory stableMasterAddresses = CORE.stablecoinList();\n address[] memory agTokenAddresses = new address[](stableMasterAddresses.length);\n for (uint256 i; i < stableMasterAddresses.length; ++i) {\n agTokenAddresses[i] = IStableMaster(stableMasterAddresses[i]).agToken();\n }\n return (stableMasterAddresses, agTokenAddresses);\n }\n\n /// @notice Returns most of the governance parameters associated to the (`agToken`,`collateral`) pair given\n /// @return params Struct with most of the parameters in the `StableMaster` and `PerpetualManager` contracts\n /// @dev Check out the struct `Parameters` for the meaning of the return values\n function getCollateralParameters(\n address agToken,\n address collateral\n ) external view returns (Parameters memory params) {\n (address stableMaster, address poolManager) = _getStableMasterAndPoolManager(agToken, collateral);\n (\n ,\n ,\n IPerpetualManager perpetualManager,\n ,\n ,\n ,\n ,\n SLPData memory slpData,\n MintBurnData memory feeData\n ) = IStableMaster(stableMaster).collateralMap(poolManager);\n\n params.slpData = slpData;\n params.feeData = feeData;\n params.perpParam.maintenanceMargin = perpetualManager.maintenanceMargin();\n params.perpParam.maxLeverage = perpetualManager.maxLeverage();\n params.perpParam.targetHAHedge = perpetualManager.targetHAHedge();\n params.perpParam.limitHAHedge = perpetualManager.limitHAHedge();\n params.perpParam.lockTime = perpetualManager.lockTime();\n\n params.perpFeeData.haBonusMalusDeposit = perpetualManager.haBonusMalusDeposit();\n params.perpFeeData.haBonusMalusWithdraw = perpetualManager.haBonusMalusWithdraw();\n\n uint256 length = 0;\n while (true) {\n try perpetualManager.xHAFeesDeposit(length) returns (uint64) {\n length += 1;\n } catch {\n break;\n }\n }\n uint64[] memory data = new uint64[](length);\n uint64[] memory data2 = new uint64[](length);\n for (uint256 i; i < length; ++i) {\n data[i] = perpetualManager.xHAFeesDeposit(i);\n data2[i] = perpetualManager.yHAFeesDeposit(i);\n }\n params.perpFeeData.xHAFeesDeposit = data;\n params.perpFeeData.yHAFeesDeposit = data2;\n\n length = 0;\n while (true) {\n try perpetualManager.xHAFeesWithdraw(length) returns (uint64) {\n length += 1;\n } catch {\n break;\n }\n }\n data = new uint64[](length);\n data2 = new uint64[](length);\n for (uint256 i; i < length; ++i) {\n data[i] = perpetualManager.xHAFeesWithdraw(i);\n data2[i] = perpetualManager.yHAFeesWithdraw(i);\n }\n params.perpFeeData.xHAFeesWithdraw = data;\n params.perpFeeData.yHAFeesWithdraw = data2;\n }\n\n /// @notice Returns the address of the poolManager associated to an (`agToken`, `collateral`) pair\n /// in the Core module of the protocol\n function getPoolManager(address agToken, address collateral) public view returns (address poolManager) {\n (, poolManager) = _getStableMasterAndPoolManager(agToken, collateral);\n }\n\n // ======================== Replica Functions ==================================\n // These replicate what is done in the other contracts of the protocol\n\n function _previewBurnAndFees(\n uint256 amount,\n address agToken,\n address collateral\n ) internal view returns (uint256 amountForUserInCollat, uint256 feePercent) {\n (address stableMaster, address poolManager) = _getStableMasterAndPoolManager(agToken, collateral);\n (\n address token,\n ,\n IPerpetualManager perpetualManager,\n IOracleCore oracle,\n uint256 stocksUsers,\n ,\n uint256 collatBase,\n ,\n MintBurnData memory feeData\n ) = IStableMaster(stableMaster).collateralMap(poolManager);\n if (token == address(0) || IStableMaster(stableMaster).paused(keccak256(abi.encodePacked(STABLE, poolManager))))\n revert NotInitialized();\n if (amount > stocksUsers) revert InvalidAmount();\n\n if (feeData.xFeeBurn.length == 1) {\n feePercent = feeData.yFeeBurn[0];\n } else {\n bytes memory data = abi.encode(address(perpetualManager), feeData.targetHAHedge);\n uint64 hedgeRatio = _computeHedgeRatio(stocksUsers - amount, data);\n feePercent = _piecewiseLinear(hedgeRatio, feeData.xFeeBurn, feeData.yFeeBurn);\n }\n feePercent = (feePercent * feeData.bonusMalusBurn) / BASE_PARAMS;\n\n amountForUserInCollat = (amount * (BASE_PARAMS - feePercent) * collatBase) / (oracle.readUpper() * BASE_PARAMS);\n }\n\n function _previewMintAndFees(\n uint256 amount,\n address agToken,\n address collateral\n ) internal view returns (uint256 amountForUserInStable, uint256 feePercent) {\n (address stableMaster, address poolManager) = _getStableMasterAndPoolManager(agToken, collateral);\n (\n address token,\n ,\n IPerpetualManager perpetualManager,\n IOracleCore oracle,\n uint256 stocksUsers,\n ,\n ,\n ,\n MintBurnData memory feeData\n ) = IStableMaster(stableMaster).collateralMap(poolManager);\n if (token == address(0) || IStableMaster(stableMaster).paused(keccak256(abi.encodePacked(STABLE, poolManager))))\n revert NotInitialized();\n\n amountForUserInStable = oracle.readQuoteLower(amount);\n\n if (feeData.xFeeMint.length == 1) feePercent = feeData.yFeeMint[0];\n else {\n bytes memory data = abi.encode(address(perpetualManager), feeData.targetHAHedge);\n uint64 hedgeRatio = _computeHedgeRatio(amountForUserInStable + stocksUsers, data);\n feePercent = _piecewiseLinear(hedgeRatio, feeData.xFeeMint, feeData.yFeeMint);\n }\n feePercent = (feePercent * feeData.bonusMalusMint) / BASE_PARAMS;\n\n amountForUserInStable = (amountForUserInStable * (BASE_PARAMS - feePercent)) / BASE_PARAMS;\n if (stocksUsers + amountForUserInStable > feeData.capOnStableMinted) revert InvalidAmount();\n }\n\n // ======================== Utility Functions ==================================\n // These utility functions are taken from other contracts of the protocol\n\n function _computeHedgeRatio(uint256 newStocksUsers, bytes memory data) internal view returns (uint64 ratio) {\n (address perpetualManager, uint64 targetHAHedge) = abi.decode(data, (address, uint64));\n uint256 totalHedgeAmount = IPerpetualManager(perpetualManager).totalHedgeAmount();\n newStocksUsers = (targetHAHedge * newStocksUsers) / BASE_PARAMS;\n if (newStocksUsers > totalHedgeAmount) ratio = uint64((totalHedgeAmount * BASE_PARAMS) / newStocksUsers);\n else ratio = uint64(BASE_PARAMS);\n }\n\n function _piecewiseLinear(uint64 x, uint64[] memory xArray, uint64[] memory yArray) internal pure returns (uint64) {\n if (x >= xArray[xArray.length - 1]) {\n return yArray[xArray.length - 1];\n } else if (x <= xArray[0]) {\n return yArray[0];\n } else {\n uint256 lower;\n uint256 upper = xArray.length - 1;\n uint256 mid;\n while (upper - lower > 1) {\n mid = lower + (upper - lower) / 2;\n if (xArray[mid] <= x) {\n lower = mid;\n } else {\n upper = mid;\n }\n }\n if (yArray[upper] > yArray[lower]) {\n return\n yArray[lower] +\n ((yArray[upper] - yArray[lower]) * (x - xArray[lower])) /\n (xArray[upper] - xArray[lower]);\n } else {\n return\n yArray[lower] -\n ((yArray[lower] - yArray[upper]) * (x - xArray[lower])) /\n (xArray[upper] - xArray[lower]);\n }\n }\n }\n\n function _getStableMasterAndPoolManager(\n address agToken,\n address collateral\n ) internal view returns (address stableMaster, address poolManager) {\n stableMaster = IAgTokenMainnet(agToken).stableMaster();\n (poolManager, , , ) = ROUTER.mapPoolManagers(stableMaster, collateral);\n }\n\n // ====================== Constants and Initializers ===========================\n\n IAngleRouter public constant ROUTER = IAngleRouter(0xBB755240596530be0c1DE5DFD77ec6398471561d);\n ICore public constant CORE = ICore(0x61ed74de9Ca5796cF2F8fD60D54160D47E30B7c3);\n\n bytes32 public constant STABLE = keccak256(\"STABLE\");\n uint256 public constant BASE_PARAMS = 10 ** 9;\n\n error NotInitialized();\n error InvalidAmount();\n\n /// @custom:oz-upgrades-unsafe-allow constructor\n constructor() initializer {}\n}\n" + }, + "contracts/deprecated/vaultManager/OldVaultManagerERC721.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\nimport \"./OldVaultManagerStorage.sol\";\n\n/// @title VaultManagerERC721\n/// @author Angle Labs, Inc.\n/// @dev Base ERC721 Implementation of VaultManager\nabstract contract OldVaultManagerERC721 is IERC721MetadataUpgradeable, OldVaultManagerStorage {\n using SafeERC20 for IERC20;\n using Address for address;\n\n /// @inheritdoc IERC721MetadataUpgradeable\n string public name;\n /// @inheritdoc IERC721MetadataUpgradeable\n string public symbol;\n\n // ================================= MODIFIERS =================================\n\n /// @notice Checks if the person interacting with the vault with `vaultID` is approved\n /// @param caller Address of the person seeking to interact with the vault\n /// @param vaultID ID of the concerned vault\n modifier onlyApprovedOrOwner(address caller, uint256 vaultID) {\n if (!_isApprovedOrOwner(caller, vaultID)) revert NotApproved();\n _;\n }\n\n // ================================ ERC721 LOGIC ===============================\n\n /// @notice Checks whether a given address is approved for a vault or owns this vault\n /// @param spender Address for which vault ownership should be checked\n /// @param vaultID ID of the vault to check\n /// @return Whether the `spender` address owns or is approved for `vaultID`\n function isApprovedOrOwner(address spender, uint256 vaultID) external view returns (bool) {\n return _isApprovedOrOwner(spender, vaultID);\n }\n\n /// @inheritdoc IERC721MetadataUpgradeable\n function tokenURI(uint256 vaultID) external view returns (string memory) {\n if (!_exists(vaultID)) revert NonexistentVault();\n // There is no vault with `vaultID` equal to 0, so the following variable is\n // always greater than zero\n uint256 temp = vaultID;\n uint256 digits;\n while (temp != 0) {\n digits++;\n temp /= 10;\n }\n bytes memory buffer = new bytes(digits);\n while (vaultID != 0) {\n digits -= 1;\n buffer[digits] = bytes1(uint8(48 + uint256(vaultID % 10)));\n vaultID /= 10;\n }\n return bytes(_baseURI).length > 0 ? string(abi.encodePacked(_baseURI, string(buffer))) : \"\";\n }\n\n /// @inheritdoc IERC721Upgradeable\n function balanceOf(address owner) external view returns (uint256) {\n if (owner == address(0)) revert ZeroAddress();\n return _balances[owner];\n }\n\n /// @inheritdoc IERC721Upgradeable\n function ownerOf(uint256 vaultID) external view returns (address) {\n return _ownerOf(vaultID);\n }\n\n /// @inheritdoc IERC721Upgradeable\n function approve(address to, uint256 vaultID) external {\n address owner = _ownerOf(vaultID);\n if (to == owner) revert ApprovalToOwner();\n if (msg.sender != owner && !isApprovedForAll(owner, msg.sender)) revert NotApproved();\n\n _approve(to, vaultID);\n }\n\n /// @inheritdoc IERC721Upgradeable\n function getApproved(uint256 vaultID) external view returns (address) {\n if (!_exists(vaultID)) revert NonexistentVault();\n return _getApproved(vaultID);\n }\n\n /// @inheritdoc IERC721Upgradeable\n function setApprovalForAll(address operator, bool approved) external {\n _setApprovalForAll(msg.sender, operator, approved);\n }\n\n /// @inheritdoc IERC721Upgradeable\n function isApprovedForAll(address owner, address operator) public view returns (bool) {\n return _operatorApprovals[owner][operator] == 1;\n }\n\n /// @inheritdoc IERC721Upgradeable\n function transferFrom(address from, address to, uint256 vaultID) external onlyApprovedOrOwner(msg.sender, vaultID) {\n _transfer(from, to, vaultID);\n }\n\n /// @inheritdoc IERC721Upgradeable\n function safeTransferFrom(address from, address to, uint256 vaultID) external {\n safeTransferFrom(from, to, vaultID, \"\");\n }\n\n /// @inheritdoc IERC721Upgradeable\n function safeTransferFrom(\n address from,\n address to,\n uint256 vaultID,\n bytes memory _data\n ) public onlyApprovedOrOwner(msg.sender, vaultID) {\n _safeTransfer(from, to, vaultID, _data);\n }\n\n // ================================ ERC165 LOGIC ===============================\n\n /// @inheritdoc IERC165Upgradeable\n function supportsInterface(bytes4 interfaceId) external pure returns (bool) {\n return\n interfaceId == type(IERC721MetadataUpgradeable).interfaceId ||\n interfaceId == type(IERC721Upgradeable).interfaceId ||\n interfaceId == type(IVaultManager).interfaceId ||\n interfaceId == type(IERC165Upgradeable).interfaceId;\n }\n\n // ================== INTERNAL FUNCTIONS FOR THE ERC721 LOGIC ==================\n\n /// @notice Internal version of the `ownerOf` function\n function _ownerOf(uint256 vaultID) internal view returns (address owner) {\n owner = _owners[vaultID];\n if (owner == address(0)) revert NonexistentVault();\n }\n\n /// @notice Internal version of the `getApproved` function\n function _getApproved(uint256 vaultID) internal view returns (address) {\n return _vaultApprovals[vaultID];\n }\n\n /// @notice Internal version of the `safeTransferFrom` function (with the data parameter)\n function _safeTransfer(address from, address to, uint256 vaultID, bytes memory _data) internal {\n _transfer(from, to, vaultID);\n if (!_checkOnERC721Received(from, to, vaultID, _data)) revert NonERC721Receiver();\n }\n\n /// @notice Checks whether a vault exists\n /// @param vaultID ID of the vault to check\n /// @return Whether `vaultID` has been created\n function _exists(uint256 vaultID) internal view returns (bool) {\n return _owners[vaultID] != address(0);\n }\n\n /// @notice Internal version of the `isApprovedOrOwner` function\n function _isApprovedOrOwner(address spender, uint256 vaultID) internal view returns (bool) {\n // The following checks if the vault exists\n address owner = _ownerOf(vaultID);\n return (spender == owner || _getApproved(vaultID) == spender || _operatorApprovals[owner][spender] == 1);\n }\n\n /// @notice Internal version of the `createVault` function\n /// Mints `vaultID` and transfers it to `to`\n /// @dev This method is equivalent to the `_safeMint` method used in OpenZeppelin ERC721 contract\n /// @dev Emits a {Transfer} event\n function _mint(address to) internal returns (uint256 vaultID) {\n if (whitelistingActivated && (isWhitelisted[to] != 1 || isWhitelisted[msg.sender] != 1))\n revert NotWhitelisted();\n if (to == address(0)) revert ZeroAddress();\n\n unchecked {\n vaultIDCount += 1;\n }\n\n vaultID = vaultIDCount;\n _beforeTokenTransfer(address(0), to, vaultID);\n\n unchecked {\n _balances[to] += 1;\n }\n\n _owners[vaultID] = to;\n emit Transfer(address(0), to, vaultID);\n if (!_checkOnERC721Received(address(0), to, vaultID, \"\")) revert NonERC721Receiver();\n }\n\n /// @notice Destroys `vaultID`\n /// @dev `vaultID` must exist\n /// @dev Emits a {Transfer} event\n function _burn(uint256 vaultID) internal {\n address owner = _ownerOf(vaultID);\n\n _beforeTokenTransfer(owner, address(0), vaultID);\n // Clear approvals\n _approve(address(0), vaultID);\n // The following line cannot underflow as the owner's balance is necessarily\n // greater than 1\n unchecked {\n _balances[owner] -= 1;\n }\n delete _owners[vaultID];\n delete vaultData[vaultID];\n\n emit Transfer(owner, address(0), vaultID);\n }\n\n /// @notice Transfers `vaultID` from `from` to `to` as opposed to {transferFrom},\n /// this imposes no restrictions on msg.sender\n /// @dev `to` cannot be the zero address and `perpetualID` must be owned by `from`\n /// @dev Emits a {Transfer} event\n /// @dev A whitelist check is performed if necessary on the `to` address\n function _transfer(address from, address to, uint256 vaultID) internal {\n if (_ownerOf(vaultID) != from) revert NotApproved();\n if (to == address(0)) revert ZeroAddress();\n if (whitelistingActivated && isWhitelisted[to] != 1) revert NotWhitelisted();\n\n _beforeTokenTransfer(from, to, vaultID);\n\n // Clear approvals from the previous owner\n _approve(address(0), vaultID);\n unchecked {\n _balances[from] -= 1;\n _balances[to] += 1;\n }\n _owners[vaultID] = to;\n\n emit Transfer(from, to, vaultID);\n }\n\n /// @notice Approves `to` to operate on `vaultID`\n function _approve(address to, uint256 vaultID) internal {\n _vaultApprovals[vaultID] = to;\n emit Approval(_ownerOf(vaultID), to, vaultID);\n }\n\n /// @notice Internal version of the `setApprovalForAll` function\n /// @dev It contains an `approver` field to be used in case someone signs a permit for a particular\n /// address, and this signature is given to the contract by another address (like a router)\n function _setApprovalForAll(address approver, address operator, bool approved) internal {\n if (operator == approver) revert ApprovalToCaller();\n uint256 approval = approved ? 1 : 0;\n _operatorApprovals[approver][operator] = approval;\n emit ApprovalForAll(approver, operator, approved);\n }\n\n /// @notice Internal function to invoke {IERC721Receiver-onERC721Received} on a target address\n /// The call is not executed if the target address is not a contract\n /// @param from Address representing the previous owner of the given token ID\n /// @param to Target address that will receive the tokens\n /// @param vaultID ID of the token to be transferred\n /// @param _data Bytes optional data to send along with the call\n /// @return Bool whether the call correctly returned the expected value\n function _checkOnERC721Received(\n address from,\n address to,\n uint256 vaultID,\n bytes memory _data\n ) private returns (bool) {\n if (to.isContract()) {\n try IERC721ReceiverUpgradeable(to).onERC721Received(msg.sender, from, vaultID, _data) returns (\n bytes4 retval\n ) {\n return retval == IERC721ReceiverUpgradeable.onERC721Received.selector;\n } catch (bytes memory reason) {\n if (reason.length == 0) {\n revert NonERC721Receiver();\n } else {\n // solhint-disable-next-line no-inline-assembly\n assembly {\n revert(add(32, reason), mload(reason))\n }\n }\n }\n } else {\n return true;\n }\n }\n\n /// @notice Hook that is called before any token transfer. This includes minting and burning.\n /// Calling conditions:\n ///\n /// - When `from` and `to` are both non-zero, `from`'s `vaultID` will be\n /// transferred to `to`.\n /// - When `from` is zero, `vaultID` will be minted for `to`.\n /// - When `to` is zero, `from`'s `vaultID` will be burned.\n /// - `from` and `to` are never both zero.\n function _beforeTokenTransfer(address from, address to, uint256 vaultID) internal virtual {}\n}\n" + }, + "contracts/deprecated/vaultManager/OldVaultManagerPermit.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\nimport \"./OldVaultManagerERC721.sol\";\nimport \"../../interfaces/external/IERC1271.sol\";\n\n/// @title VaultManagerPermit\n/// @author Angle Labs, Inc.\n/// @dev Base Implementation of permit functions for the `VaultManager` contract\nabstract contract OldVaultManagerPermit is Initializable, OldVaultManagerERC721 {\n using Address for address;\n\n mapping(address => uint256) private _nonces;\n /* solhint-disable var-name-mixedcase */\n bytes32 private _HASHED_NAME;\n bytes32 private _HASHED_VERSION;\n bytes32 private _PERMIT_TYPEHASH;\n /* solhint-enable var-name-mixedcase */\n\n error ExpiredDeadline();\n error InvalidSignature();\n\n //solhint-disable-next-line\n function __ERC721Permit_init(string memory _name) internal onlyInitializing {\n _PERMIT_TYPEHASH = keccak256(\n \"Permit(address owner,address spender,bool approved,uint256 nonce,uint256 deadline)\"\n );\n _HASHED_NAME = keccak256(bytes(_name));\n _HASHED_VERSION = keccak256(bytes(\"1\"));\n }\n\n /// @notice Allows an address to give or revoke approval for all its vaults to another address\n /// @param owner Address signing the permit and giving (or revoking) its approval for all the controlled vaults\n /// @param spender Address to give approval to\n /// @param approved Whether to give or revoke the approval\n /// @param deadline Deadline parameter for the signature to be valid\n /// @dev The `v`, `r`, and `s` parameters are used as signature data\n function permit(\n address owner,\n address spender,\n bool approved,\n uint256 deadline,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) external {\n if (block.timestamp > deadline) revert ExpiredDeadline();\n // Additional signature checks performed in the `ECDSAUpgradeable.recover` function\n if (uint256(s) > 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D576E7357A4501DDFE92F46681B20A0 || (v != 27 && v != 28))\n revert InvalidSignature();\n\n bytes32 digest = keccak256(\n abi.encodePacked(\n \"\\x19\\x01\",\n _domainSeparatorV4(),\n keccak256(\n abi.encode(\n _PERMIT_TYPEHASH,\n // 0x3f43a9c6bafb5c7aab4e0cfe239dc5d4c15caf0381c6104188191f78a6640bd8,\n owner,\n spender,\n approved,\n _useNonce(owner),\n deadline\n )\n )\n )\n );\n if (owner.isContract()) {\n if (IERC1271(owner).isValidSignature(digest, abi.encodePacked(r, s, v)) != 0x1626ba7e)\n revert InvalidSignature();\n } else {\n address signer = ecrecover(digest, v, r, s);\n if (signer != owner || signer == address(0)) revert InvalidSignature();\n }\n\n _setApprovalForAll(owner, spender, approved);\n }\n\n /// @notice Returns the current nonce for an `owner` address\n function nonces(address owner) public view returns (uint256) {\n return _nonces[owner];\n }\n\n /// @notice Returns the domain separator for the current chain.\n // solhint-disable-next-line func-name-mixedcase\n function DOMAIN_SEPARATOR() external view returns (bytes32) {\n return _domainSeparatorV4();\n }\n\n /// @notice Internal version of the `DOMAIN_SEPARATOR` function\n function _domainSeparatorV4() internal view returns (bytes32) {\n return\n keccak256(\n abi.encode(\n // keccak256('EIP712Domain(string name,string version,uint256 chainId,address verifyingContract)')\n 0x8b73c3c69bb8fe3d512ecc4cf759cc79239f7b179b0ffacaa9a75d522b39400f,\n _HASHED_NAME,\n _HASHED_VERSION,\n block.chainid,\n address(this)\n )\n );\n }\n\n /// @notice Consumes a nonce for an address: returns the current value and increments it\n function _useNonce(address owner) internal returns (uint256 current) {\n current = _nonces[owner];\n _nonces[owner] = current + 1;\n }\n\n uint256[49] private __gap;\n}\n" + }, + "contracts/deprecated/vaultManager/OldVaultManagerStorage.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\nimport \"@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/token/ERC20/extensions/draft-IERC20PermitUpgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/token/ERC721/IERC721ReceiverUpgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/interfaces/IERC721MetadataUpgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/utils/introspection/IERC165Upgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/utils/AddressUpgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/security/ReentrancyGuardUpgradeable.sol\";\nimport \"@openzeppelin/contracts/token/ERC20/extensions/IERC20Metadata.sol\";\nimport \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\nimport \"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\";\n\nimport \"../../interfaces/IAgToken.sol\";\nimport \"../../interfaces/IOracle.sol\";\nimport \"../../interfaces/ISwapper.sol\";\nimport \"../../interfaces/ITreasury.sol\";\nimport \"../../interfaces/IVaultManager.sol\";\nimport \"../../interfaces/governance/IVeBoostProxy.sol\";\n\n/// @title VaultManagerStorage\n/// @author Angle Labs, Inc.\n/// @dev Variables, references, parameters and events needed in the `VaultManager` contract\n// solhint-disable-next-line max-states-count\ncontract OldVaultManagerStorage is IVaultManagerStorage, Initializable, ReentrancyGuardUpgradeable {\n /// @notice Base used for parameter computation: almost all the parameters of this contract are set in `BASE_PARAMS`\n uint256 public constant BASE_PARAMS = 10 ** 9;\n /// @notice Base used for interest rate computation\n uint256 public constant BASE_INTEREST = 10 ** 27;\n /// @notice Used for interest rate computation\n uint256 public constant HALF_BASE_INTEREST = 10 ** 27 / 2;\n\n // ================================= REFERENCES ================================\n\n /// @inheritdoc IVaultManagerStorage\n ITreasury public treasury;\n /// @inheritdoc IVaultManagerStorage\n IERC20 public collateral;\n /// @inheritdoc IVaultManagerStorage\n IAgToken public stablecoin;\n /// @inheritdoc IVaultManagerStorage\n IOracle public oracle;\n /// @notice Reference to the contract which computes adjusted veANGLE balances for liquidators boosts\n IVeBoostProxy public veBoostProxy;\n /// @notice Base of the collateral\n uint256 internal _collatBase;\n\n // ================================= PARAMETERS ================================\n // Unless specified otherwise, parameters of this contract are expressed in `BASE_PARAMS`\n\n /// @notice Maximum amount of stablecoins that can be issued with this contract (in `BASE_TOKENS`). This parameter should\n /// not be bigger than `type(uint256).max / BASE_INTEREST` otherwise there may be some overflows in the `increaseDebt` function\n uint256 public debtCeiling;\n /// @notice Threshold veANGLE balance values for the computation of the boost for liquidators: the length of this array\n /// should normally be 2. The base of the x-values in this array should be `BASE_TOKENS`\n uint256[] public xLiquidationBoost;\n /// @notice Values of the liquidation boost at the threshold values of x\n uint256[] public yLiquidationBoost;\n /// @inheritdoc IVaultManagerStorage\n uint64 public collateralFactor;\n /// @notice Maximum Health factor at which a vault can end up after a liquidation (unless it's fully liquidated)\n uint64 public targetHealthFactor;\n /// @notice Upfront fee taken when borrowing stablecoins: this fee is optional and should in practice not be used\n uint64 public borrowFee;\n /// @notice Upfront fee taken when repaying stablecoins: this fee is optional as well. It should be smaller\n /// than the liquidation surcharge (cf below) to avoid exploits where people voluntarily get liquidated at a 0\n /// discount to pay smaller repaying fees\n uint64 public repayFee;\n /// @notice Per second interest taken to borrowers taking agToken loans. Contrarily to other parameters, it is set in `BASE_INTEREST`\n /// that is to say in base 10**27\n uint64 public interestRate;\n /// @notice Fee taken by the protocol during a liquidation. Technically, this value is not the fee per se, it's 1 - fee.\n /// For instance for a 2% fee, `liquidationSurcharge` should be 98%\n uint64 public liquidationSurcharge;\n /// @notice Maximum discount given to liquidators\n uint64 public maxLiquidationDiscount;\n /// @notice Whether whitelisting is required to own a vault or not\n bool public whitelistingActivated;\n /// @notice Whether the contract is paused or not\n bool public paused;\n\n // ================================= VARIABLES =================================\n\n /// @notice Timestamp at which the `interestAccumulator` was updated\n uint256 public lastInterestAccumulatorUpdated;\n /// @inheritdoc IVaultManagerStorage\n uint256 public interestAccumulator;\n /// @inheritdoc IVaultManagerStorage\n uint256 public totalNormalizedDebt;\n /// @notice Surplus accumulated by the contract: surplus is always in stablecoins, and is then reset\n /// when the value is communicated to the treasury contract\n uint256 public surplus;\n /// @notice Bad debt made from liquidated vaults which ended up having no collateral and a positive amount\n /// of stablecoins\n uint256 public badDebt;\n\n // ================================== MAPPINGS =================================\n\n /// @inheritdoc IVaultManagerStorage\n mapping(uint256 => Vault) public vaultData;\n /// @notice Maps an address to 1 if it's whitelisted and can open or own a vault\n mapping(address => uint256) public isWhitelisted;\n\n // ================================ ERC721 DATA ================================\n\n /// @inheritdoc IVaultManagerStorage\n uint256 public vaultIDCount;\n\n /// @notice URI\n string internal _baseURI;\n\n // Mapping from `vaultID` to owner address\n mapping(uint256 => address) internal _owners;\n\n // Mapping from owner address to vault owned count\n mapping(address => uint256) internal _balances;\n\n // Mapping from `vaultID` to approved address\n mapping(uint256 => address) internal _vaultApprovals;\n\n // Mapping from owner to operator approvals\n mapping(address => mapping(address => uint256)) internal _operatorApprovals;\n\n uint256[50] private __gap;\n\n // =================================== EVENTS ==================================\n\n event AccruedToTreasury(uint256 surplusEndValue, uint256 badDebtEndValue);\n event CollateralAmountUpdated(uint256 vaultID, uint256 collateralAmount, uint8 isIncrease);\n event InterestAccumulatorUpdated(uint256 value, uint256 timestamp);\n event InternalDebtUpdated(uint256 vaultID, uint256 internalAmount, uint8 isIncrease);\n event FiledUint64(uint64 param, bytes32 what);\n event DebtCeilingUpdated(uint256 debtCeiling);\n event LiquidationBoostParametersUpdated(address indexed _veBoostProxy, uint256[] xBoost, uint256[] yBoost);\n event LiquidatedVaults(uint256[] vaultIDs);\n event DebtTransferred(uint256 srcVaultID, uint256 dstVaultID, address dstVaultManager, uint256 amount);\n\n // =================================== ERRORS ==================================\n\n error ApprovalToOwner();\n error ApprovalToCaller();\n error DustyLeftoverAmount();\n error DebtCeilingExceeded();\n error HealthyVault();\n error IncompatibleLengths();\n error InsolventVault();\n error InvalidParameterValue();\n error InvalidParameterType();\n error InvalidSetOfParameters();\n error InvalidTreasury();\n error NonERC721Receiver();\n error NonexistentVault();\n error NotApproved();\n error NotGovernor();\n error NotGovernorOrGuardian();\n error NotTreasury();\n error NotWhitelisted();\n error NotVaultManager();\n error Paused();\n error TooHighParameterValue();\n error TooSmallParameterValue();\n error ZeroAddress();\n\n /// @custom:oz-upgrades-unsafe-allow constructor\n constructor() initializer {}\n}\n" + }, + "contracts/external/ProxyAdmin.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\nimport \"./TransparentUpgradeableProxy.sol\";\nimport \"@openzeppelin/contracts/access/Ownable.sol\";\n\n/**\n * @dev This is an auxiliary contract meant to be assigned as the admin of a {TransparentUpgradeableProxy}. For an\n * explanation of why you would want to use this see the documentation for {TransparentUpgradeableProxy}.\n * This contract was fully forked from OpenZeppelin `ProxyAdmin`\n */\ncontract ProxyAdmin is Ownable {\n /**\n * @dev Returns the current implementation of `proxy`.\n *\n * Requirements:\n *\n * - This contract must be the admin of `proxy`.\n */\n function getProxyImplementation(TransparentUpgradeableProxy proxy) public view virtual returns (address) {\n // We need to manually run the static call since the getter cannot be flagged as view\n // bytes4(keccak256(\"implementation()\")) == 0x5c60da1b\n (bool success, bytes memory returndata) = address(proxy).staticcall(hex\"5c60da1b\");\n require(success);\n return abi.decode(returndata, (address));\n }\n\n /**\n * @dev Returns the current admin of `proxy`.\n *\n * Requirements:\n *\n * - This contract must be the admin of `proxy`.\n */\n function getProxyAdmin(TransparentUpgradeableProxy proxy) public view virtual returns (address) {\n // We need to manually run the static call since the getter cannot be flagged as view\n // bytes4(keccak256(\"admin()\")) == 0xf851a440\n (bool success, bytes memory returndata) = address(proxy).staticcall(hex\"f851a440\");\n require(success);\n return abi.decode(returndata, (address));\n }\n\n /**\n * @dev Changes the admin of `proxy` to `newAdmin`.\n *\n * Requirements:\n *\n * - This contract must be the current admin of `proxy`.\n */\n function changeProxyAdmin(TransparentUpgradeableProxy proxy, address newAdmin) public virtual onlyOwner {\n proxy.changeAdmin(newAdmin);\n }\n\n /**\n * @dev Upgrades `proxy` to `implementation`. See {TransparentUpgradeableProxy-upgradeTo}.\n *\n * Requirements:\n *\n * - This contract must be the admin of `proxy`.\n */\n function upgrade(TransparentUpgradeableProxy proxy, address implementation) public virtual onlyOwner {\n proxy.upgradeTo(implementation);\n }\n\n /**\n * @dev Upgrades `proxy` to `implementation` and calls a function on the new implementation. See\n * {TransparentUpgradeableProxy-upgradeToAndCall}.\n *\n * Requirements:\n *\n * - This contract must be the admin of `proxy`.\n */\n function upgradeAndCall(\n TransparentUpgradeableProxy proxy,\n address implementation,\n bytes memory data\n ) public payable virtual onlyOwner {\n proxy.upgradeToAndCall{ value: msg.value }(implementation, data);\n }\n}\n" + }, + "contracts/external/TransparentUpgradeableProxy.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\nimport \"@openzeppelin/contracts/proxy/ERC1967/ERC1967Proxy.sol\";\n\n/**\n * @dev This contract implements a proxy that is upgradeable by an admin. It is fully forked from OpenZeppelin\n * `TransparentUpgradeableProxy`\n *\n * To avoid https://medium.com/nomic-labs-blog/malicious-backdoors-in-ethereum-proxies-62629adf3357[proxy selector\n * clashing], which can potentially be used in an attack, this contract uses the\n * https://blog.openzeppelin.com/the-transparent-proxy-pattern/[transparent proxy pattern]. This pattern implies two\n * things that go hand in hand:\n *\n * 1. If any account other than the admin calls the proxy, the call will be forwarded to the implementation, even if\n * that call matches one of the admin functions exposed by the proxy itself.\n * 2. If the admin calls the proxy, it can access the admin functions, but its calls will never be forwarded to the\n * implementation. If the admin tries to call a function on the implementation it will fail with an error that says\n * \"admin cannot fallback to proxy target\".\n *\n * These properties mean that the admin account can only be used for admin actions like upgrading the proxy or changing\n * the admin, so it's best if it's a dedicated account that is not used for anything else. This will avoid headaches due\n * to sudden errors when trying to call a function from the proxy implementation.\n *\n * Our recommendation is for the dedicated account to be an instance of the {ProxyAdmin} contract. If set up this way,\n * you should think of the `ProxyAdmin` instance as the real administrative interface of your proxy.\n */\ncontract TransparentUpgradeableProxy is ERC1967Proxy {\n /**\n * @dev Initializes an upgradeable proxy managed by `_admin`, backed by the implementation at `_logic`, and\n * optionally initialized with `_data` as explained in {ERC1967Proxy-constructor}.\n */\n constructor(address _logic, address admin_, bytes memory _data) payable ERC1967Proxy(_logic, _data) {\n assert(_ADMIN_SLOT == bytes32(uint256(keccak256(\"eip1967.proxy.admin\")) - 1));\n _changeAdmin(admin_);\n }\n\n /**\n * @dev Modifier used internally that will delegate the call to the implementation unless the sender is the admin.\n */\n modifier ifAdmin() {\n if (msg.sender == _getAdmin()) {\n _;\n } else {\n _fallback();\n }\n }\n\n /**\n * @dev Returns the current admin.\n *\n * NOTE: Only the admin can call this function. See {ProxyAdmin-getProxyAdmin}.\n *\n * TIP: To get this value clients can read directly from the storage slot shown below (specified by EIP1967) using the\n * https://eth.wiki/json-rpc/API#eth_getstorageat[`eth_getStorageAt`] RPC call.\n * `0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103`\n */\n function admin() external ifAdmin returns (address admin_) {\n admin_ = _getAdmin();\n }\n\n /**\n * @dev Returns the current implementation.\n *\n * NOTE: Only the admin can call this function. See {ProxyAdmin-getProxyImplementation}.\n *\n * TIP: To get this value clients can read directly from the storage slot shown below (specified by EIP1967) using the\n * https://eth.wiki/json-rpc/API#eth_getstorageat[`eth_getStorageAt`] RPC call.\n * `0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc`\n */\n function implementation() external ifAdmin returns (address implementation_) {\n implementation_ = _implementation();\n }\n\n /**\n * @dev Changes the admin of the proxy.\n *\n * Emits an {AdminChanged} event.\n *\n * NOTE: Only the admin can call this function. See {ProxyAdmin-changeProxyAdmin}.\n */\n function changeAdmin(address newAdmin) external virtual ifAdmin {\n _changeAdmin(newAdmin);\n }\n\n /**\n * @dev Upgrade the implementation of the proxy.\n *\n * NOTE: Only the admin can call this function. See {ProxyAdmin-upgrade}.\n */\n function upgradeTo(address newImplementation) external ifAdmin {\n _upgradeToAndCall(newImplementation, bytes(\"\"), false);\n }\n\n /**\n * @dev Upgrade the implementation of the proxy, and then call a function from the new implementation as specified\n * by `data`, which should be an encoded function call. This is useful to initialize new storage variables in the\n * proxied contract.\n *\n * NOTE: Only the admin can call this function. See {ProxyAdmin-upgradeAndCall}.\n */\n function upgradeToAndCall(address newImplementation, bytes calldata data) external payable ifAdmin {\n _upgradeToAndCall(newImplementation, data, true);\n }\n\n /**\n * @dev Returns the current admin.\n */\n function _admin() internal view virtual returns (address) {\n return _getAdmin();\n }\n\n /**\n * @dev Makes sure the admin cannot access the fallback function. See {Proxy-_beforeFallback}.\n */\n function _beforeFallback() internal virtual override {\n require(msg.sender != _getAdmin(), \"TransparentUpgradeableProxy: admin cannot fallback to proxy target\");\n super._beforeFallback();\n }\n}\n" + }, + "contracts/flashloan/FlashAngle.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\nimport \"@openzeppelin/contracts-upgradeable/security/ReentrancyGuardUpgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol\";\nimport \"@openzeppelin/contracts/interfaces/IERC3156FlashBorrower.sol\";\nimport \"@openzeppelin/contracts/interfaces/IERC3156FlashLender.sol\";\nimport \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\nimport \"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\";\n\nimport \"../interfaces/IAgToken.sol\";\nimport \"../interfaces/ICoreBorrow.sol\";\nimport \"../interfaces/IFlashAngle.sol\";\nimport \"../interfaces/ITreasury.sol\";\n\n/// @title FlashAngle\n/// @author Angle Labs, Inc.\n/// @notice Contract to take flash loans on top of several AgToken contracts\ncontract FlashAngle is IERC3156FlashLender, IFlashAngle, Initializable, ReentrancyGuardUpgradeable {\n using SafeERC20 for IERC20;\n /// @notice Base used for parameter computation\n uint256 public constant BASE_PARAMS = 10 ** 9;\n /// @notice Success message received when calling a `FlashBorrower` contract\n bytes32 public constant CALLBACK_SUCCESS = keccak256(\"ERC3156FlashBorrower.onFlashLoan\");\n\n /// @notice Struct encoding for a given stablecoin the parameters\n struct StablecoinData {\n // Maximum amount borrowable for this stablecoin\n uint256 maxBorrowable;\n // Flash loan fee taken by the protocol for a flash loan on this stablecoin\n uint64 flashLoanFee;\n // Treasury address responsible of the stablecoin\n address treasury;\n }\n\n // ======================= Parameters and References ===========================\n\n /// @notice Maps a stablecoin to the data and parameters for flash loans\n mapping(IAgToken => StablecoinData) public stablecoinMap;\n /// @inheritdoc IFlashAngle\n ICoreBorrow public core;\n\n // =============================== Event =======================================\n\n event FlashLoan(address indexed stablecoin, uint256 amount, IERC3156FlashBorrower indexed receiver);\n event FlashLoanParametersUpdated(IAgToken indexed stablecoin, uint64 _flashLoanFee, uint256 _maxBorrowable);\n\n // =============================== Errors ======================================\n\n error InvalidReturnMessage();\n error NotCore();\n error NotGovernorOrGuardian();\n error NotTreasury();\n error TooBigAmount();\n error TooHighParameterValue();\n error UnsupportedStablecoin();\n error ZeroAddress();\n\n /// @notice Initializes the contract\n /// @param _core Core address handling this module\n function initialize(ICoreBorrow _core) public initializer {\n if (address(_core) == address(0)) revert ZeroAddress();\n core = _core;\n }\n\n /// @custom:oz-upgrades-unsafe-allow constructor\n constructor() initializer {}\n\n // =================================== Modifiers ===============================\n\n /// @notice Checks whether the sender is the core contract\n modifier onlyCore() {\n if (msg.sender != address(core)) revert NotCore();\n _;\n }\n\n /// @notice Checks whether a given stablecoin has been initialized in this contract\n /// @param stablecoin Stablecoin to check\n /// @dev To check whether a stablecoin has been initialized, we just need to check whether its associated\n /// `treasury` address is not null in the `stablecoinMap`. This is what's checked in the `CoreBorrow` contract\n /// when adding support for a stablecoin\n modifier onlyExistingStablecoin(IAgToken stablecoin) {\n if (stablecoinMap[stablecoin].treasury == address(0)) revert UnsupportedStablecoin();\n _;\n }\n\n // ================================ ERC3156 Spec ===============================\n\n /// @inheritdoc IERC3156FlashLender\n function flashFee(address token, uint256 amount) external view returns (uint256) {\n return _flashFee(token, amount);\n }\n\n /// @inheritdoc IERC3156FlashLender\n function maxFlashLoan(address token) external view returns (uint256) {\n // It will be 0 anyway if the token was not added\n return stablecoinMap[IAgToken(token)].maxBorrowable;\n }\n\n /// @inheritdoc IERC3156FlashLender\n function flashLoan(\n IERC3156FlashBorrower receiver,\n address token,\n uint256 amount,\n bytes calldata data\n ) external nonReentrant returns (bool) {\n uint256 fee = _flashFee(token, amount);\n if (amount > stablecoinMap[IAgToken(token)].maxBorrowable) revert TooBigAmount();\n IAgToken(token).mint(address(receiver), amount);\n if (receiver.onFlashLoan(msg.sender, token, amount, fee, data) != CALLBACK_SUCCESS)\n revert InvalidReturnMessage();\n // Token must be an agToken here so normally no need to use `safeTransferFrom`, but out of safety\n // and in case governance whitelists an agToken which does not have a correct implementation, we prefer\n // to use `safeTransferFrom` here\n IERC20(token).safeTransferFrom(address(receiver), address(this), amount + fee);\n IAgToken(token).burnSelf(amount, address(this));\n emit FlashLoan(token, amount, receiver);\n return true;\n }\n\n /// @notice Internal function to compute the fee induced for taking a flash loan of `amount` of `token`\n /// @param token The loan currency\n /// @param amount The amount of tokens lent\n /// @dev This function will revert if the `token` requested is not whitelisted here\n function _flashFee(\n address token,\n uint256 amount\n ) internal view onlyExistingStablecoin(IAgToken(token)) returns (uint256) {\n return (amount * stablecoinMap[IAgToken(token)].flashLoanFee) / BASE_PARAMS;\n }\n\n // ============================ Treasury Only Function =========================\n\n /// @inheritdoc IFlashAngle\n function accrueInterestToTreasury(IAgToken stablecoin) external returns (uint256 balance) {\n address treasury = stablecoinMap[stablecoin].treasury;\n if (msg.sender != treasury) revert NotTreasury();\n balance = stablecoin.balanceOf(address(this));\n IERC20(address(stablecoin)).safeTransfer(treasury, balance);\n }\n\n // =========================== Governance Only Function ========================\n\n /// @notice Sets the parameters for a given stablecoin\n /// @param stablecoin Stablecoin to change the parameters for\n /// @param _flashLoanFee New flash loan fee for this stablecoin\n /// @param _maxBorrowable Maximum amount that can be borrowed in a single flash loan\n /// @dev Setting a `maxBorrowable` parameter equal to 0 is a way to pause the functionality\n /// @dev Parameters can only be modified for whitelisted stablecoins\n function setFlashLoanParameters(\n IAgToken stablecoin,\n uint64 _flashLoanFee,\n uint256 _maxBorrowable\n ) external onlyExistingStablecoin(stablecoin) {\n if (!core.isGovernorOrGuardian(msg.sender)) revert NotGovernorOrGuardian();\n if (_flashLoanFee > BASE_PARAMS) revert TooHighParameterValue();\n stablecoinMap[stablecoin].flashLoanFee = _flashLoanFee;\n stablecoinMap[stablecoin].maxBorrowable = _maxBorrowable;\n emit FlashLoanParametersUpdated(stablecoin, _flashLoanFee, _maxBorrowable);\n }\n\n // =========================== CoreBorrow Only Functions =======================\n\n /// @inheritdoc IFlashAngle\n function addStablecoinSupport(address _treasury) external onlyCore {\n stablecoinMap[IAgToken(ITreasury(_treasury).stablecoin())].treasury = _treasury;\n }\n\n /// @inheritdoc IFlashAngle\n function removeStablecoinSupport(address _treasury) external onlyCore {\n delete stablecoinMap[IAgToken(ITreasury(_treasury).stablecoin())];\n }\n\n /// @inheritdoc IFlashAngle\n function setCore(address _core) external onlyCore {\n core = ICoreBorrow(_core);\n }\n}\n" + }, + "contracts/interfaces/coreModule/IAgTokenMainnet.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\n/// @title IAgTokenMainnet\n/// @author Angle Labs, Inc.\ninterface IAgTokenMainnet {\n function stableMaster() external view returns (address);\n}\n" + }, + "contracts/interfaces/coreModule/ICore.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\n/// @title ICore\n/// @author Angle Labs, Inc.\ninterface ICore {\n function stablecoinList() external view returns (address[] memory);\n}\n" + }, + "contracts/interfaces/coreModule/ILiquidityGauge.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\ninterface ILiquidityGauge {\n function deposit(\n uint256 _value,\n address _addr,\n // solhint-disable-next-line\n bool _claim_rewards\n ) external;\n\n function withdraw(\n uint256 _value,\n // solhint-disable-next-line\n bool _claim_rewards\n ) external;\n\n // solhint-disable-next-line\n function claim_rewards(address _addr, address _receiver) external;\n\n // solhint-disable-next-line\n function claimable_reward(address _addr, address _reward_token) external view returns (uint256 amount);\n}\n" + }, + "contracts/interfaces/coreModule/IOracleCore.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\n/// @title IOracleCore\n/// @author Angle Labs, Inc.\ninterface IOracleCore {\n function readUpper() external view returns (uint256);\n\n function readQuoteLower(uint256 baseAmount) external view returns (uint256);\n}\n" + }, + "contracts/interfaces/coreModule/IPerpetualManager.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\n/// @title IPerpetualManager\n/// @author Angle Labs, Inc.\ninterface IPerpetualManager {\n function totalHedgeAmount() external view returns (uint256);\n\n function maintenanceMargin() external view returns (uint64);\n\n function maxLeverage() external view returns (uint64);\n\n function targetHAHedge() external view returns (uint64);\n\n function limitHAHedge() external view returns (uint64);\n\n function lockTime() external view returns (uint64);\n\n function haBonusMalusDeposit() external view returns (uint64);\n\n function haBonusMalusWithdraw() external view returns (uint64);\n\n function xHAFeesDeposit(uint256) external view returns (uint64);\n\n function yHAFeesDeposit(uint256) external view returns (uint64);\n\n function xHAFeesWithdraw(uint256) external view returns (uint64);\n\n function yHAFeesWithdraw(uint256) external view returns (uint64);\n}\n" + }, + "contracts/interfaces/coreModule/IPoolManager.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\n/// @title IPoolManager\n/// @author Angle Labs, Inc.\ninterface IPoolManager {\n function feeManager() external view returns (address);\n\n function strategyList(uint256) external view returns (address);\n}\n" + }, + "contracts/interfaces/coreModule/IStableMaster.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\nimport \"./IPerpetualManager.sol\";\nimport \"./IOracleCore.sol\";\n\n// Struct to handle all the parameters to manage the fees\n// related to a given collateral pool (associated to the stablecoin)\nstruct MintBurnData {\n // Values of the thresholds to compute the minting fees\n // depending on HA hedge (scaled by `BASE_PARAMS`)\n uint64[] xFeeMint;\n // Values of the fees at thresholds (scaled by `BASE_PARAMS`)\n uint64[] yFeeMint;\n // Values of the thresholds to compute the burning fees\n // depending on HA hedge (scaled by `BASE_PARAMS`)\n uint64[] xFeeBurn;\n // Values of the fees at thresholds (scaled by `BASE_PARAMS`)\n uint64[] yFeeBurn;\n // Max proportion of collateral from users that can be covered by HAs\n // It is exactly the same as the parameter of the same name in `PerpetualManager`, whenever one is updated\n // the other changes accordingly\n uint64 targetHAHedge;\n // Minting fees correction set by the `FeeManager` contract: they are going to be multiplied\n // to the value of the fees computed using the hedge curve\n // Scaled by `BASE_PARAMS`\n uint64 bonusMalusMint;\n // Burning fees correction set by the `FeeManager` contract: they are going to be multiplied\n // to the value of the fees computed using the hedge curve\n // Scaled by `BASE_PARAMS`\n uint64 bonusMalusBurn;\n // Parameter used to limit the number of stablecoins that can be issued using the concerned collateral\n uint256 capOnStableMinted;\n}\n\n// Struct to handle all the variables and parameters to handle SLPs in the protocol\n// including the fraction of interests they receive or the fees to be distributed to\n// them\nstruct SLPData {\n // Last timestamp at which the `sanRate` has been updated for SLPs\n uint256 lastBlockUpdated;\n // Fees accumulated from previous blocks and to be distributed to SLPs\n uint256 lockedInterests;\n // Max interests used to update the `sanRate` in a single block\n // Should be in collateral token base\n uint256 maxInterestsDistributed;\n // Amount of fees left aside for SLPs and that will be distributed\n // when the protocol is collateralized back again\n uint256 feesAside;\n // Part of the fees normally going to SLPs that is left aside\n // before the protocol is collateralized back again (depends on collateral ratio)\n // Updated by keepers and scaled by `BASE_PARAMS`\n uint64 slippageFee;\n // Portion of the fees from users minting and burning\n // that goes to SLPs (the rest goes to surplus)\n uint64 feesForSLPs;\n // Slippage factor that's applied to SLPs exiting (depends on collateral ratio)\n // If `slippage = BASE_PARAMS`, SLPs can get nothing, if `slippage = 0` they get their full claim\n // Updated by keepers and scaled by `BASE_PARAMS`\n uint64 slippage;\n // Portion of the interests from lending\n // that goes to SLPs (the rest goes to surplus)\n uint64 interestsForSLPs;\n}\n\n/// @title IStableMaster\n/// @author Angle Labs, Inc.\ninterface IStableMaster {\n function agToken() external view returns (address);\n\n function updateStocksUsers(uint256 amount, address poolManager) external;\n\n function collateralMap(\n address poolManager\n )\n external\n view\n returns (\n address token,\n address sanToken,\n IPerpetualManager perpetualManager,\n IOracleCore oracle,\n uint256 stocksUsers,\n uint256 sanRate,\n uint256 collatBase,\n SLPData memory slpData,\n MintBurnData memory feeData\n );\n\n function paused(bytes32) external view returns (bool);\n\n function deposit(uint256 amount, address user, address poolManager) external;\n\n function withdraw(uint256 amount, address burner, address dest, address poolManager) external;\n}\n" + }, + "contracts/interfaces/external/create2/ImmutableCreate2Factory.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\ninterface ImmutableCreate2Factory {\n function safeCreate2(bytes32 salt, bytes memory initCode) external payable returns (address deploymentAddress);\n\n function findCreate2Address(\n bytes32 salt,\n bytes calldata initCode\n ) external view returns (address deploymentAddress);\n\n function findCreate2AddressViaHash(\n bytes32 salt,\n bytes32 initCodeHash\n ) external view returns (address deploymentAddress);\n}\n" + }, + "contracts/interfaces/external/IERC1271.sol": { + "content": "// SPDX-License-Identifier: GPL-2.0-or-later\npragma solidity ^0.8.12;\n\n/// @title Interface for verifying contract-based account signatures\n/// @notice Interface that verifies provided signature for the data\n/// @dev Interface defined by EIP-1271\ninterface IERC1271 {\n /// @notice Returns whether the provided signature is valid for the provided data\n /// @dev MUST return the bytes4 magic value 0x1626ba7e when function passes.\n /// MUST NOT modify state (using STATICCALL for solc < 0.5, view modifier for solc > 0.5).\n /// MUST allow external calls.\n /// @param hash Hash of the data to be signed\n /// @param signature Signature byte array associated with _data\n /// @return magicValue The bytes4 magic value 0x1626ba7e\n function isValidSignature(bytes32 hash, bytes memory signature) external view returns (bytes4 magicValue);\n}\n" + }, + "contracts/interfaces/external/IERC4626.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\npragma solidity >=0.8.0;\n\nimport \"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\";\nimport \"@openzeppelin/contracts/token/ERC20/ERC20.sol\";\n\n/// @notice Minimal IERC4646 tokenized Vault interface.\n/// @author Forked from Solmate (https://github.com/Rari-Capital/solmate/blob/main/src/mixins/ERC4626.sol)\n/// @dev Do not use in production! ERC-4626 is still in the review stage and is subject to change.\ninterface IERC4626 {\n event Deposit(address indexed from, address indexed to, uint256 amount, uint256 shares);\n event Withdraw(address indexed from, address indexed to, uint256 amount, uint256 shares);\n\n /// @notice Transfers a given amount of asset to the reactor and mint shares accordingly\n /// @param amount Given amount of asset\n /// @param to Address to mint shares to\n /// @return shares Amount of shares minted to `to`\n function deposit(uint256 amount, address to) external returns (uint256 shares);\n\n /// @notice Mints a given amount of shares to the reactor and transfer assets accordingly\n /// @param shares Given amount of shares\n /// @param to Address to mint shares to\n /// @return amount Amount of `asset` taken to the `msg.sender` to mint `shares`\n function mint(uint256 shares, address to) external returns (uint256 amount);\n\n /// @notice Transfers a given amount of asset from the reactor and burn shares accordingly\n /// @param amount Given amount of asset\n /// @param to Address to transfer assets to\n /// @param from Address to burn shares from\n /// @return shares Amount of shares burnt in the operation\n function withdraw(uint256 amount, address to, address from) external returns (uint256 shares);\n\n /// @notice Burns a given amount of shares to the reactor and transfer assets accordingly\n /// @param shares Given amount of shares\n /// @param to Address to transfer assets to\n /// @param from Address to burn shares from\n /// @return amount Amount of assets redeemed in the operation\n function redeem(uint256 shares, address to, address from) external returns (uint256 amount);\n\n /// @notice Returns the total assets managed by this reactor\n function totalAssets() external view returns (uint256);\n\n /// @notice Converts an amount of assets to the corresponding amount of reactor shares\n /// @param assets Amount of asset to convert\n /// @return Shares corresponding to the amount of assets obtained\n function convertToShares(uint256 assets) external view returns (uint256);\n\n /// @notice Converts an amount of shares to its current value in asset\n /// @param shares Amount of shares to convert\n /// @return Amount of assets corresponding to the amount of assets given\n function convertToAssets(uint256 shares) external view returns (uint256);\n\n /// @notice Computes how many shares one would get by depositing `assets`\n /// @param assets Amount of asset to convert\n function previewDeposit(uint256 assets) external view returns (uint256);\n\n /// @notice Computes how many assets one would need to mint `shares`\n /// @param shares Amount of shares required\n function previewMint(uint256 shares) external view returns (uint256);\n\n /// @notice Computes how many shares one would need to withdraw assets\n /// @param assets Amount of asset to withdraw\n function previewWithdraw(uint256 assets) external view returns (uint256);\n\n /// @notice Computes how many assets one would get by burning shares\n /// @param shares Amount of shares to burn\n function previewRedeem(uint256 shares) external view returns (uint256);\n\n /// @notice Max deposit allowed for a user\n /// @param user Address of the user to check\n function maxDeposit(address user) external returns (uint256);\n\n /// @notice Max mint allowed for a user\n /// @param user Address of the user to check\n function maxMint(address user) external returns (uint256);\n\n /// @notice Max withdraw allowed for a user\n /// @param user Address of the user to check\n function maxWithdraw(address user) external returns (uint256);\n\n /// @notice Max redeem allowed for a user\n /// @param user Address of the user to check\n function maxRedeem(address user) external returns (uint256);\n}\n" + }, + "contracts/interfaces/external/IWETH9.sol": { + "content": "// SPDX-License-Identifier: GPL-2.0-or-later\npragma solidity ^0.8.12;\n\nimport \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\n\n/// @title Interface for WETH9\ninterface IWETH9 is IERC20 {\n /// @notice Deposit ether to get wrapped ether\n function deposit() external payable;\n\n /// @notice Withdraw wrapped ether to get ether\n function withdraw(uint256) external;\n}\n" + }, + "contracts/interfaces/external/layerZero/ILayerZeroEndpoint.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity >=0.5.0;\n\nimport \"./ILayerZeroUserApplicationConfig.sol\";\n\ninterface ILayerZeroEndpoint is ILayerZeroUserApplicationConfig {\n // @notice send a LayerZero message to the specified address at a LayerZero endpoint.\n // @param _dstChainId - the destination chain identifier\n // @param _destination - the address on destination chain (in bytes). address length/format may vary by chains\n // @param _payload - a custom bytes payload to send to the destination contract\n // @param _refundAddress - if the source transaction is cheaper than the amount of value passed, refund the additional amount to this address\n // @param _zroPaymentAddress - the address of the ZRO token holder who would pay for the transaction\n // @param _adapterParams - parameters for custom functionality. e.g. receive airdropped native gas from the relayer on destination\n function send(\n uint16 _dstChainId,\n bytes calldata _destination,\n bytes calldata _payload,\n address payable _refundAddress,\n address _zroPaymentAddress,\n bytes calldata _adapterParams\n ) external payable;\n\n // @notice used by the messaging library to publish verified payload\n // @param _srcChainId - the source chain identifier\n // @param _srcAddress - the source contract (as bytes) at the source chain\n // @param _dstAddress - the address on destination chain\n // @param _nonce - the unbound message ordering nonce\n // @param _gasLimit - the gas limit for external contract execution\n // @param _payload - verified payload to send to the destination contract\n function receivePayload(\n uint16 _srcChainId,\n bytes calldata _srcAddress,\n address _dstAddress,\n uint64 _nonce,\n uint256 _gasLimit,\n bytes calldata _payload\n ) external;\n\n // @notice get the inboundNonce of a lzApp from a source chain which could be EVM or non-EVM chain\n // @param _srcChainId - the source chain identifier\n // @param _srcAddress - the source chain contract address\n function getInboundNonce(uint16 _srcChainId, bytes calldata _srcAddress) external view returns (uint64);\n\n // @notice get the outboundNonce from this source chain which, consequently, is always an EVM\n // @param _srcAddress - the source chain contract address\n function getOutboundNonce(uint16 _dstChainId, address _srcAddress) external view returns (uint64);\n\n // @notice gets a quote in source native gas, for the amount that send() requires to pay for message delivery\n // @param _dstChainId - the destination chain identifier\n // @param _userApplication - the user app address on this EVM chain\n // @param _payload - the custom message to send over LayerZero\n // @param _payInZRO - if false, user app pays the protocol fee in native token\n // @param _adapterParam - parameters for the adapter service, e.g. send some dust native token to dstChain\n function estimateFees(\n uint16 _dstChainId,\n address _userApplication,\n bytes calldata _payload,\n bool _payInZRO,\n bytes calldata _adapterParam\n ) external view returns (uint256 nativeFee, uint256 zroFee);\n\n // @notice get this Endpoint's immutable source identifier\n function getChainId() external view returns (uint16);\n\n // @notice the interface to retry failed message on this Endpoint destination\n // @param _srcChainId - the source chain identifier\n // @param _srcAddress - the source chain contract address\n // @param _payload - the payload to be retried\n function retryPayload(uint16 _srcChainId, bytes calldata _srcAddress, bytes calldata _payload) external;\n\n // @notice query if any STORED payload (message blocking) at the endpoint.\n // @param _srcChainId - the source chain identifier\n // @param _srcAddress - the source chain contract address\n function hasStoredPayload(uint16 _srcChainId, bytes calldata _srcAddress) external view returns (bool);\n\n // @notice query if the _libraryAddress is valid for sending msgs.\n // @param _userApplication - the user app address on this EVM chain\n function getSendLibraryAddress(address _userApplication) external view returns (address);\n\n // @notice query if the _libraryAddress is valid for receiving msgs.\n // @param _userApplication - the user app address on this EVM chain\n function getReceiveLibraryAddress(address _userApplication) external view returns (address);\n\n // @notice query if the non-reentrancy guard for send() is on\n // @return true if the guard is on. false otherwise\n function isSendingPayload() external view returns (bool);\n\n // @notice query if the non-reentrancy guard for receive() is on\n // @return true if the guard is on. false otherwise\n function isReceivingPayload() external view returns (bool);\n\n // @notice get the configuration of the LayerZero messaging library of the specified version\n // @param _version - messaging library version\n // @param _chainId - the chainId for the pending config change\n // @param _userApplication - the contract address of the user application\n // @param _configType - type of configuration. every messaging library has its own convention.\n function getConfig(\n uint16 _version,\n uint16 _chainId,\n address _userApplication,\n uint256 _configType\n ) external view returns (bytes memory);\n\n // @notice get the send() LayerZero messaging library version\n // @param _userApplication - the contract address of the user application\n function getSendVersion(address _userApplication) external view returns (uint16);\n\n // @notice get the lzReceive() LayerZero messaging library version\n // @param _userApplication - the contract address of the user application\n function getReceiveVersion(address _userApplication) external view returns (uint16);\n}\n" + }, + "contracts/interfaces/external/layerZero/ILayerZeroReceiver.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity >=0.5.0;\n\ninterface ILayerZeroReceiver {\n // @notice LayerZero endpoint will invoke this function to deliver the message on the destination\n // @param _srcChainId - the source endpoint identifier\n // @param _srcAddress - the source sending contract address from the source chain\n // @param _nonce - the ordered message nonce\n // @param _payload - the signed payload is the UA bytes has encoded to be sent\n function lzReceive(uint16 _srcChainId, bytes calldata _srcAddress, uint64 _nonce, bytes calldata _payload) external;\n}\n" + }, + "contracts/interfaces/external/layerZero/ILayerZeroUserApplicationConfig.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity >=0.5.0;\n\ninterface ILayerZeroUserApplicationConfig {\n // @notice set the configuration of the LayerZero messaging library of the specified version\n // @param _version - messaging library version\n // @param _chainId - the chainId for the pending config change\n // @param _configType - type of configuration. every messaging library has its own convention.\n // @param _config - configuration in the bytes. can encode arbitrary content.\n function setConfig(uint16 _version, uint16 _chainId, uint256 _configType, bytes calldata _config) external;\n\n // @notice set the send() LayerZero messaging library version to _version\n // @param _version - new messaging library version\n function setSendVersion(uint16 _version) external;\n\n // @notice set the lzReceive() LayerZero messaging library version to _version\n // @param _version - new messaging library version\n function setReceiveVersion(uint16 _version) external;\n\n // @notice Only when the UA needs to resume the message flow in blocking mode and clear the stored payload\n // @param _srcChainId - the chainId of the source chain\n // @param _srcAddress - the contract address of the source contract at the source chain\n function forceResumeReceive(uint16 _srcChainId, bytes calldata _srcAddress) external;\n}\n" + }, + "contracts/interfaces/external/lido/IStETH.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\n/// @title IStETH\n/// @author Angle Labs, Inc.\n/// @notice Interface for the `StETH` contract\n/// @dev This interface only contains functions of the `StETH` which are called by other contracts\n/// of this module\ninterface IStETH {\n function getPooledEthByShares(uint256 _sharesAmount) external view returns (uint256);\n\n event Submitted(address sender, uint256 amount, address referral);\n\n function submit(address) external payable returns (uint256);\n\n function getSharesByPooledEth(uint256 _ethAmount) external view returns (uint256);\n}\n" + }, + "contracts/interfaces/external/lido/IWStETH.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\n/// @title IWStETH\n/// @author Angle Labs, Inc.\n/// @notice Interface for the `WStETH` contract\n/// @dev This interface only contains functions of the `WStETH` which are called by other contracts\n/// of this module\ninterface IWStETH {\n function wrap(uint256 _stETHAmount) external returns (uint256);\n\n function stETH() external view returns (address);\n}\n" + }, + "contracts/interfaces/external/uniswap/IUniswapRouter.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\nstruct ExactInputParams {\n bytes path;\n address recipient;\n uint256 deadline;\n uint256 amountIn;\n uint256 amountOutMinimum;\n}\n\n/// @title Router token swapping functionality\n/// @notice Functions for swapping tokens via Uniswap V3\ninterface IUniswapV3Router {\n /// @notice Swaps `amountIn` of one token for as much as possible of another along the specified path\n /// @param params The parameters necessary for the multi-hop swap, encoded as `ExactInputParams` in calldata\n /// @return amountOut The amount of the received token\n function exactInput(ExactInputParams calldata params) external payable returns (uint256 amountOut);\n}\n\n/// @title Router for price estimation functionality\n/// @notice Functions for getting the price of one token with respect to another using Uniswap V2\n/// @dev This interface is only used for non critical elements of the protocol\ninterface IUniswapV2Router {\n /// @notice Given an input asset amount, returns the maximum output amount of the\n /// other asset (accounting for fees) given reserves.\n /// @param path Addresses of the pools used to get prices\n function getAmountsOut(uint256 amountIn, address[] calldata path) external view returns (uint256[] memory amounts);\n\n function swapExactTokensForTokens(\n uint256 swapAmount,\n uint256 minExpected,\n address[] calldata path,\n address receiver,\n uint256 swapDeadline\n ) external;\n}\n" + }, + "contracts/interfaces/external/uniswap/IUniswapV3Pool.sol": { + "content": "// SPDX-License-Identifier: GPL-2.0-or-later\npragma solidity >=0.5.0;\n\n/// @title Pool state that never changes\n/// @notice These parameters are fixed for a pool forever, i.e., the methods will always return the same values\ninterface IUniswapV3Pool {\n /// @notice The first of the two tokens of the pool, sorted by address\n /// @return The token contract address\n function token0() external view returns (address);\n\n /// @notice The second of the two tokens of the pool, sorted by address\n /// @return The token contract address\n function token1() external view returns (address);\n}\n" + }, + "contracts/interfaces/governance/IVeBoostProxy.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\n/// @title IVeBoostProxy\n/// @author Angle Labs, Inc.\n/// @notice Interface for the `VeBoostProxy` contract\n/// @dev This interface only contains functions of the contract which are called by other contracts\n/// of this module\n/// @dev The `veBoostProxy` contract used by Angle is a full fork of Curve Finance implementation\ninterface IVeBoostProxy {\n /// @notice Reads the adjusted veANGLE balance of an address (adjusted by delegation)\n //solhint-disable-next-line\n function adjusted_balance_of(address) external view returns (uint256);\n}\n" + }, + "contracts/interfaces/IAgToken.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\nimport \"@openzeppelin/contracts-upgradeable/token/ERC20/IERC20Upgradeable.sol\";\n\n/// @title IAgToken\n/// @author Angle Labs, Inc.\n/// @notice Interface for the stablecoins `AgToken` contracts\n/// @dev This interface only contains functions of the `AgToken` contract which are called by other contracts\n/// of this module or of the first module of the Angle Protocol\ninterface IAgToken is IERC20Upgradeable {\n // ======================= Minter Role Only Functions ===========================\n\n /// @notice Lets the `StableMaster` contract or another whitelisted contract mint agTokens\n /// @param account Address to mint to\n /// @param amount Amount to mint\n /// @dev The contracts allowed to issue agTokens are the `StableMaster` contract, `VaultManager` contracts\n /// associated to this stablecoin as well as the flash loan module (if activated) and potentially contracts\n /// whitelisted by governance\n function mint(address account, uint256 amount) external;\n\n /// @notice Burns `amount` tokens from a `burner` address after being asked to by `sender`\n /// @param amount Amount of tokens to burn\n /// @param burner Address to burn from\n /// @param sender Address which requested the burn from `burner`\n /// @dev This method is to be called by a contract with the minter right after being requested\n /// to do so by a `sender` address willing to burn tokens from another `burner` address\n /// @dev The method checks the allowance between the `sender` and the `burner`\n function burnFrom(uint256 amount, address burner, address sender) external;\n\n /// @notice Burns `amount` tokens from a `burner` address\n /// @param amount Amount of tokens to burn\n /// @param burner Address to burn from\n /// @dev This method is to be called by a contract with a minter right on the AgToken after being\n /// requested to do so by an address willing to burn tokens from its address\n function burnSelf(uint256 amount, address burner) external;\n\n // ========================= Treasury Only Functions ===========================\n\n /// @notice Adds a minter in the contract\n /// @param minter Minter address to add\n /// @dev Zero address checks are performed directly in the `Treasury` contract\n function addMinter(address minter) external;\n\n /// @notice Removes a minter from the contract\n /// @param minter Minter address to remove\n /// @dev This function can also be called by a minter wishing to revoke itself\n function removeMinter(address minter) external;\n\n /// @notice Sets a new treasury contract\n /// @param _treasury New treasury address\n function setTreasury(address _treasury) external;\n\n // ========================= External functions ================================\n\n /// @notice Checks whether an address has the right to mint agTokens\n /// @param minter Address for which the minting right should be checked\n /// @return Whether the address has the right to mint agTokens or not\n function isMinter(address minter) external view returns (bool);\n\n /// @notice Get the associated treasury\n function treasury() external view returns (address);\n}\n" + }, + "contracts/interfaces/IAgTokenSideChainMultiBridge.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\nimport \"@openzeppelin/contracts-upgradeable/token/ERC20/extensions/draft-IERC20PermitUpgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/token/ERC20/IERC20Upgradeable.sol\";\n\n/// @title IAgTokenSideChainMultiBridge\n/// @author Angle Labs, Inc.\n/// @notice Interface for the canonical `AgToken` contracts\n/// @dev This interface only contains functions useful for bridge tokens to interact with the canonical token\ninterface IAgTokenSideChainMultiBridge is IERC20PermitUpgradeable, IERC20Upgradeable {\n /// @notice Mints the canonical token from a supported bridge token\n /// @param bridgeToken Bridge token to use to mint\n /// @param amount Amount of bridge tokens to send\n /// @param to Address to which the stablecoin should be sent\n /// @return Amount of the canonical stablecoin actually minted\n /// @dev Some fees may be taken by the protocol depending on the token used and on the address calling\n function swapIn(address bridgeToken, uint256 amount, address to) external returns (uint256);\n\n /// @notice Burns the canonical token in exchange for a bridge token\n /// @param bridgeToken Bridge token required\n /// @param amount Amount of canonical tokens to burn\n /// @param to Address to which the bridge token should be sent\n /// @return Amount of bridge tokens actually sent back\n /// @dev Some fees may be taken by the protocol depending on the token used and on the address calling\n function swapOut(address bridgeToken, uint256 amount, address to) external returns (uint256);\n}\n" + }, + "contracts/interfaces/IAngleRouter.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\n/// @title IAngleRouter\n/// @author Angle Labs, Inc.\n/// @notice Interface for the `AngleRouter` contract\n/// @dev This interface only contains functions of the `AngleRouter01` contract which are called by other contracts\n/// of this module\ninterface IAngleRouter {\n function mint(\n address user,\n uint256 amount,\n uint256 minStableAmount,\n address stablecoin,\n address collateral\n ) external;\n\n function burn(address user, uint256 amount, uint256 minAmountOut, address stablecoin, address collateral) external;\n\n function mapPoolManagers(\n address stableMaster,\n address collateral\n ) external view returns (address poolManager, address perpetualManager, address sanToken, address gauge);\n}\n" + }, + "contracts/interfaces/IAngleRouterSidechain.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\n/// @notice Action types\nenum ActionType {\n transfer,\n wrap,\n wrapNative,\n sweep,\n sweepNative,\n unwrap,\n unwrapNative,\n swapIn,\n swapOut,\n uniswapV3,\n oneInch,\n claimRewards,\n gaugeDeposit,\n borrower\n}\n\n/// @notice Data needed to get permits\nstruct PermitType {\n address token;\n address owner;\n uint256 value;\n uint256 deadline;\n uint8 v;\n bytes32 r;\n bytes32 s;\n}\n\n/// @title IAngleRouterSidechain\n/// @author Angle Labs, Inc.\n/// @notice Interface for the `AngleRouter` contract on other chains\ninterface IAngleRouterSidechain {\n function mixer(PermitType[] memory paramsPermit, ActionType[] memory actions, bytes[] calldata data) external;\n}\n" + }, + "contracts/interfaces/ICoreBorrow.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\n/// @title ICoreBorrow\n/// @author Angle Labs, Inc.\n/// @notice Interface for the `CoreBorrow` contract\n/// @dev This interface only contains functions of the `CoreBorrow` contract which are called by other contracts\n/// of this module\ninterface ICoreBorrow {\n /// @notice Checks if an address corresponds to a treasury of a stablecoin with a flash loan\n /// module initialized on it\n /// @param treasury Address to check\n /// @return Whether the address has the `FLASHLOANER_TREASURY_ROLE` or not\n function isFlashLoanerTreasury(address treasury) external view returns (bool);\n\n /// @notice Checks whether an address is governor of the Angle Protocol or not\n /// @param admin Address to check\n /// @return Whether the address has the `GOVERNOR_ROLE` or not\n function isGovernor(address admin) external view returns (bool);\n\n /// @notice Checks whether an address is governor or a guardian of the Angle Protocol or not\n /// @param admin Address to check\n /// @return Whether the address has the `GUARDIAN_ROLE` or not\n /// @dev Governance should make sure when adding a governor to also give this governor the guardian\n /// role by calling the `addGovernor` function\n function isGovernorOrGuardian(address admin) external view returns (bool);\n}\n" + }, + "contracts/interfaces/IFlashAngle.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\nimport \"./IAgToken.sol\";\nimport \"./ICoreBorrow.sol\";\n\n/// @title IFlashAngle\n/// @author Angle Labs, Inc.\n/// @notice Interface for the `FlashAngle` contract\n/// @dev This interface only contains functions of the contract which are called by other contracts\n/// of this module\ninterface IFlashAngle {\n /// @notice Reference to the `CoreBorrow` contract managing the FlashLoan module\n function core() external view returns (ICoreBorrow);\n\n /// @notice Sends the fees taken from flash loans to the treasury contract associated to the stablecoin\n /// @param stablecoin Stablecoin from which profits should be sent\n /// @return balance Amount of profits sent\n /// @dev This function can only be called by the treasury contract\n function accrueInterestToTreasury(IAgToken stablecoin) external returns (uint256 balance);\n\n /// @notice Adds support for a stablecoin\n /// @param _treasury Treasury associated to the stablecoin to add support for\n /// @dev This function can only be called by the `CoreBorrow` contract\n function addStablecoinSupport(address _treasury) external;\n\n /// @notice Removes support for a stablecoin\n /// @param _treasury Treasury associated to the stablecoin to remove support for\n /// @dev This function can only be called by the `CoreBorrow` contract\n function removeStablecoinSupport(address _treasury) external;\n\n /// @notice Sets a new core contract\n /// @param _core Core contract address to set\n /// @dev This function can only be called by the `CoreBorrow` contract\n function setCore(address _core) external;\n}\n" + }, + "contracts/interfaces/IKeeperRegistry.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\nimport \"@openzeppelin/contracts-upgradeable/token/ERC20/IERC20Upgradeable.sol\";\n\n/// @title IKeeperRegistry\n/// @author Angle Labs, Inc.\ninterface IKeeperRegistry {\n /// @notice Checks whether an address is whitelisted during oracle updates\n /// @param caller Address for which the whitelist should be checked\n /// @return Whether the address is trusted or not\n function isTrusted(address caller) external view returns (bool);\n}\n" + }, + "contracts/interfaces/ILiquidityGauge.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.7;\n\ninterface ILiquidityGauge {\n function deposit(\n uint256 _value,\n address _addr,\n // solhint-disable-next-line\n bool _claim_rewards\n ) external;\n\n function withdraw(\n uint256 _value,\n // solhint-disable-next-line\n bool _claim_rewards\n ) external;\n\n // solhint-disable-next-line\n function claim_rewards(address _addr, address _receiver) external;\n\n // solhint-disable-next-line\n function claimable_reward(address _addr, address _reward_token) external view returns (uint256 amount);\n\n /// @dev Only for testing purposes\n // solhint-disable-next-line\n function deposit_reward_token(address _rewardToken, uint256 _amount) external;\n}\n" + }, + "contracts/interfaces/IOracle.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\nimport \"./ITreasury.sol\";\nimport \"@chainlink/contracts/src/v0.8/interfaces/AggregatorV3Interface.sol\";\n\n/// @title IOracle\n/// @author Angle Labs, Inc.\n/// @notice Interface for the `Oracle` contract\n/// @dev This interface only contains functions of the contract which are called by other contracts\n/// of this module\ninterface IOracle {\n /// @notice Reads the rate from the Chainlink circuit and other data provided\n /// @return quoteAmount The current rate between the in-currency and out-currency in the base\n /// of the out currency\n /// @dev For instance if the out currency is EUR (and hence agEUR), then the base of the returned\n /// value is 10**18\n function read() external view returns (uint256);\n\n /// @notice Changes the treasury contract\n /// @param _treasury Address of the new treasury contract\n /// @dev This function can be called by an approved `VaultManager` contract which can call\n /// this function after being requested to do so by a `treasury` contract\n /// @dev In some situations (like reactor contracts), the `VaultManager` may not directly be linked\n /// to the `oracle` contract and as such we may need governors to be able to call this function as well\n function setTreasury(address _treasury) external;\n\n /// @notice Reference to the `treasury` contract handling this `VaultManager`\n function treasury() external view returns (ITreasury treasury);\n\n /// @notice Array with the list of Chainlink feeds in the order in which they are read\n function circuitChainlink() external view returns (AggregatorV3Interface[] memory);\n}\n" + }, + "contracts/interfaces/ISwapper.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\nimport \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\n\n/// @title ISwapper\n/// @author Angle Labs, Inc.\n/// @notice Interface for Swapper contracts\n/// @dev This interface defines the key functions `Swapper` contracts should have when interacting with\n/// Angle\ninterface ISwapper {\n /// @notice Notifies a contract that an address should be given `outToken` from `inToken`\n /// @param inToken Address of the token received\n /// @param outToken Address of the token to obtain\n /// @param outTokenRecipient Address to which the outToken should be sent\n /// @param outTokenOwed Minimum amount of outToken the `outTokenRecipient` address should have at the end of the call\n /// @param inTokenObtained Amount of collateral obtained by a related address prior\n /// to the call to this function\n /// @param data Extra data needed (to encode Uniswap swaps for instance)\n function swap(\n IERC20 inToken,\n IERC20 outToken,\n address outTokenRecipient,\n uint256 outTokenOwed,\n uint256 inTokenObtained,\n bytes calldata data\n ) external;\n}\n" + }, + "contracts/interfaces/ITreasury.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\nimport \"./IAgToken.sol\";\nimport \"./ICoreBorrow.sol\";\nimport \"./IFlashAngle.sol\";\n\n/// @title ITreasury\n/// @author Angle Labs, Inc.\n/// @notice Interface for the `Treasury` contract\n/// @dev This interface only contains functions of the `Treasury` which are called by other contracts\n/// of this module\ninterface ITreasury {\n /// @notice Stablecoin handled by this `treasury` contract\n function stablecoin() external view returns (IAgToken);\n\n /// @notice Checks whether a given address has the governor role\n /// @param admin Address to check\n /// @return Whether the address has the governor role\n /// @dev Access control is only kept in the `CoreBorrow` contract\n function isGovernor(address admin) external view returns (bool);\n\n /// @notice Checks whether a given address has the guardian or the governor role\n /// @param admin Address to check\n /// @return Whether the address has the guardian or the governor role\n /// @dev Access control is only kept in the `CoreBorrow` contract which means that this function\n /// queries the `CoreBorrow` contract\n function isGovernorOrGuardian(address admin) external view returns (bool);\n\n /// @notice Checks whether a given address has well been initialized in this contract\n /// as a `VaultManager`\n /// @param _vaultManager Address to check\n /// @return Whether the address has been initialized or not\n function isVaultManager(address _vaultManager) external view returns (bool);\n\n /// @notice Sets a new flash loan module for this stablecoin\n /// @param _flashLoanModule Reference to the new flash loan module\n /// @dev This function removes the minting right to the old flash loan module and grants\n /// it to the new module\n function setFlashLoanModule(address _flashLoanModule) external;\n\n /// @notice Gets the vault manager list\n function vaultManagerList(uint256 i) external returns (address);\n}\n" + }, + "contracts/interfaces/IVaultManager.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\nimport \"@openzeppelin/contracts/interfaces/IERC721Metadata.sol\";\nimport \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\nimport \"./ITreasury.sol\";\nimport \"./IOracle.sol\";\n\n// ========================= Key Structs and Enums =============================\n\n/// @notice Parameters associated to a given `VaultManager` contract: these all correspond\n/// to parameters which signification is detailed in the `VaultManagerStorage` file\nstruct VaultParameters {\n uint256 debtCeiling;\n uint64 collateralFactor;\n uint64 targetHealthFactor;\n uint64 interestRate;\n uint64 liquidationSurcharge;\n uint64 maxLiquidationDiscount;\n bool whitelistingActivated;\n uint256 baseBoost;\n}\n\n/// @notice Data stored to track someone's loan (or equivalently called position)\nstruct Vault {\n // Amount of collateral deposited in the vault, in collateral decimals. For example, if the collateral\n // is USDC with 6 decimals, then `collateralAmount` will be in base 10**6\n uint256 collateralAmount;\n // Normalized value of the debt (that is to say of the stablecoins borrowed). It is expressed\n // in the base of Angle stablecoins (i.e. `BASE_TOKENS = 10**18`)\n uint256 normalizedDebt;\n}\n\n/// @notice For a given `vaultID`, this encodes a liquidation opportunity that is to say details about the maximum\n/// amount that could be repaid by liquidating the position\n/// @dev All the values are null in the case of a vault which cannot be liquidated under these conditions\nstruct LiquidationOpportunity {\n // Maximum stablecoin amount that can be repaid upon liquidating the vault\n uint256 maxStablecoinAmountToRepay;\n // Collateral amount given to the person in the case where the maximum amount to repay is given\n uint256 maxCollateralAmountGiven;\n // Threshold value of stablecoin amount to repay: it is ok for a liquidator to repay below threshold,\n // but if this threshold is non null and the liquidator wants to repay more than threshold, it should repay\n // the max stablecoin amount given in this vault\n uint256 thresholdRepayAmount;\n // Discount proposed to the liquidator on the collateral\n uint256 discount;\n // Amount of debt in the vault\n uint256 currentDebt;\n}\n\n/// @notice Data stored during a liquidation process to keep in memory what's due to a liquidator and some\n/// essential data for vaults being liquidated\nstruct LiquidatorData {\n // Current amount of stablecoins the liquidator should give to the contract\n uint256 stablecoinAmountToReceive;\n // Current amount of collateral the contract should give to the liquidator\n uint256 collateralAmountToGive;\n // Bad debt accrued across the liquidation process\n uint256 badDebtFromLiquidation;\n // Oracle value (in stablecoin base) at the time of the liquidation\n uint256 oracleValue;\n // Value of the `interestAccumulator` at the time of the call\n uint256 newInterestAccumulator;\n}\n\n/// @notice Data to track during a series of action the amount to give or receive in stablecoins and collateral\n/// to the caller or associated addresses\nstruct PaymentData {\n // Stablecoin amount the contract should give\n uint256 stablecoinAmountToGive;\n // Stablecoin amount owed to the contract\n uint256 stablecoinAmountToReceive;\n // Collateral amount the contract should give\n uint256 collateralAmountToGive;\n // Collateral amount owed to the contract\n uint256 collateralAmountToReceive;\n}\n\n/// @notice Actions possible when composing calls to the different entry functions proposed\nenum ActionType {\n createVault,\n closeVault,\n addCollateral,\n removeCollateral,\n repayDebt,\n borrow,\n getDebtIn,\n permit\n}\n\n// ========================= Interfaces =============================\n\n/// @title IVaultManagerFunctions\n/// @author Angle Labs, Inc.\n/// @notice Interface for the `VaultManager` contract\n/// @dev This interface only contains functions of the contract which are called by other contracts\n/// of this module (without getters)\ninterface IVaultManagerFunctions {\n /// @notice Accrues interest accumulated across all vaults to the surplus and sends the surplus to the treasury\n /// @return surplusValue Value of the surplus communicated to the `Treasury`\n /// @return badDebtValue Value of the bad debt communicated to the `Treasury`\n /// @dev `surplus` and `badDebt` should be reset to 0 once their current value have been given to the `treasury` contract\n function accrueInterestToTreasury() external returns (uint256 surplusValue, uint256 badDebtValue);\n\n /// @notice Removes debt from a vault after being requested to do so by another `VaultManager` contract\n /// @param vaultID ID of the vault to remove debt from\n /// @param amountStablecoins Amount of stablecoins to remove from the debt: this amount is to be converted to an\n /// internal debt amount\n /// @param senderBorrowFee Borrowing fees from the contract which requested this: this is to make sure that people are not\n /// arbitraging difference in minting fees\n /// @param senderRepayFee Repay fees from the contract which requested this: this is to make sure that people are not arbitraging\n /// differences in repay fees\n /// @dev This function can only be called from a vaultManager registered in the same Treasury\n function getDebtOut(\n uint256 vaultID,\n uint256 amountStablecoins,\n uint256 senderBorrowFee,\n uint256 senderRepayFee\n ) external;\n\n /// @notice Gets the current debt of a vault\n /// @param vaultID ID of the vault to check\n /// @return Debt of the vault\n function getVaultDebt(uint256 vaultID) external view returns (uint256);\n\n /// @notice Gets the total debt across all vaults\n /// @return Total debt across all vaults, taking into account the interest accumulated\n /// over time\n function getTotalDebt() external view returns (uint256);\n\n /// @notice Sets the treasury contract\n /// @param _treasury New treasury contract\n /// @dev All required checks when setting up a treasury contract are performed in the contract\n /// calling this function\n function setTreasury(address _treasury) external;\n\n /// @notice Creates a vault\n /// @param toVault Address for which the va\n /// @return vaultID ID of the vault created\n /// @dev This function just creates the vault without doing any collateral or\n function createVault(address toVault) external returns (uint256);\n\n /// @notice Allows composability between calls to the different entry points of this module. Any user calling\n /// this function can perform any of the allowed actions in the order of their choice\n /// @param actions Set of actions to perform\n /// @param datas Data to be decoded for each action: it can include like the `vaultID` or the `stablecoinAmount` to borrow\n /// @param from Address from which stablecoins will be taken if one action includes burning stablecoins. This address\n /// should either be the `msg.sender` or be approved by the latter\n /// @param to Address to which stablecoins and/or collateral will be sent in case of\n /// @param who Address of the contract to handle in case of repayment of stablecoins from received collateral\n /// @param repayData Data to pass to the repayment contract in case of\n /// @return paymentData Struct containing the accounting changes from the protocol's perspective (like how much of collateral\n /// or how much has been received). Note that the values in the struct are not aggregated and you could have in the output\n /// a positive amount of stablecoins to receive as well as a positive amount of stablecoins to give\n /// @dev This function is optimized to reduce gas cost due to payment from or to the user and that expensive calls\n /// or computations (like `oracleValue`) are done only once\n /// @dev When specifying `vaultID` in `data`, it is important to know that if you specify `vaultID = 0`, it will simply\n /// use the latest `vaultID`. This is the default behavior, and unless you're engaging into some complex protocol actions\n /// it is encouraged to use `vaultID = 0` only when the first action of the batch is `createVault`\n function angle(\n ActionType[] memory actions,\n bytes[] memory datas,\n address from,\n address to,\n address who,\n bytes memory repayData\n ) external returns (PaymentData memory paymentData);\n\n /// @notice This function is a wrapper built on top of the function above. It enables users to interact with the contract\n /// without having to provide `who` and `repayData` parameters\n function angle(\n ActionType[] memory actions,\n bytes[] memory datas,\n address from,\n address to\n ) external returns (PaymentData memory paymentData);\n\n /// @notice Initializes the `VaultManager` contract\n /// @param _treasury Treasury address handling the contract\n /// @param _collateral Collateral supported by this contract\n /// @param _oracle Oracle contract used\n /// @param _symbol Symbol used to define the `VaultManager` name and symbol\n /// @dev The parameters and the oracle are the only elements which could be modified once the\n /// contract has been initialized\n /// @dev For the contract to be fully initialized, governance needs to set the parameters for the liquidation\n /// boost\n function initialize(\n ITreasury _treasury,\n IERC20 _collateral,\n IOracle _oracle,\n VaultParameters calldata params,\n string memory _symbol\n ) external;\n\n /// @notice Minimum amount of debt a vault can have, expressed in `BASE_TOKENS` that is to say the base of the agTokens\n function dust() external view returns (uint256);\n\n /// @notice Pauses external permissionless functions of the contract\n function togglePause() external;\n}\n\n/// @title IVaultManagerStorage\n/// @author Angle Labs, Inc.\n/// @notice Interface for the `VaultManager` contract\n/// @dev This interface contains getters of the contract's public variables used by other contracts\n/// of this module\ninterface IVaultManagerStorage {\n /// @notice Encodes the maximum ratio stablecoin/collateral a vault can have before being liquidated. It's what\n /// determines the minimum collateral ratio of a position\n function collateralFactor() external view returns (uint64);\n\n /// @notice Stablecoin handled by this contract. Another `VaultManager` contract could have\n /// the same rights as this `VaultManager` on the stablecoin contract\n function stablecoin() external view returns (IAgToken);\n\n /// @notice Reference to the `treasury` contract handling this `VaultManager`\n function treasury() external view returns (ITreasury);\n\n /// @notice Oracle contract to get access to the price of the collateral with respect to the stablecoin\n function oracle() external view returns (IOracle);\n\n /// @notice The `interestAccumulator` variable keeps track of the interest that should accrue to the protocol.\n /// The stored value is not necessarily the true value: this one is recomputed every time an action takes place\n /// within the protocol. It is in base `BASE_INTEREST`\n function interestAccumulator() external view returns (uint256);\n\n /// @notice Reference to the collateral handled by this `VaultManager`\n function collateral() external view returns (IERC20);\n\n /// @notice Total normalized amount of stablecoins borrowed, not taking into account the potential bad debt accumulated\n /// This value is expressed in the base of Angle stablecoins (`BASE_TOKENS = 10**18`)\n function totalNormalizedDebt() external view returns (uint256);\n\n /// @notice Maximum amount of stablecoins that can be issued with this contract. It is expressed in `BASE_TOKENS`\n function debtCeiling() external view returns (uint256);\n\n /// @notice Maps a `vaultID` to its data (namely collateral amount and normalized debt)\n function vaultData(uint256 vaultID) external view returns (uint256 collateralAmount, uint256 normalizedDebt);\n\n /// @notice ID of the last vault created. The `vaultIDCount` variables serves as a counter to generate a unique\n /// `vaultID` for each vault: it is like `tokenID` in basic ERC721 contracts\n function vaultIDCount() external view returns (uint256);\n}\n\n/// @title IVaultManager\n/// @author Angle Labs, Inc.\n/// @notice Interface for the `VaultManager` contract\ninterface IVaultManager is IVaultManagerFunctions, IVaultManagerStorage, IERC721Metadata {\n function isApprovedOrOwner(address spender, uint256 vaultID) external view returns (bool);\n}\n\n/// @title IVaultManagerListing\n/// @author Angle Labs, Inc.\n/// @notice Interface for the `VaultManagerListing` contract\ninterface IVaultManagerListing is IVaultManager {\n /// @notice Get the collateral owned by `user` in the contract\n /// @dev This function effectively sums the collateral amounts of all the vaults owned by `user`\n function getUserCollateral(address user) external view returns (uint256);\n}\n" + }, + "contracts/keeperMulticall/KeeperMulticall.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\nimport \"@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/access/AccessControlUpgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol\";\nimport \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\nimport \"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\";\nimport \"./RevertReasonParser.sol\";\n\n/// @title KeeperMulticall\n/// @notice Allows an authorized caller (keeper) to execute multiple actions in a single tx.\n/// @author Angle Labs, Inc.\n/// @dev Special features:\n/// - ability to pay the miner (for private Flashbots transactions)\n/// - swap tokens through 1inch\n/// @dev Tx need to be encoded as an array of Action. The flag `isDelegateCall` is used for calling functions within this same contract\ncontract KeeperMulticall is Initializable, AccessControlUpgradeable {\n using SafeERC20 for IERC20;\n\n bytes32 public constant KEEPER_ROLE = keccak256(\"KEEPER_ROLE\");\n\n //solhint-disable-next-line\n address private constant _oneInch = 0x1111111254fb6c44bAC0beD2854e76F90643097d;\n\n struct Action {\n address target;\n bytes data;\n bool isDelegateCall;\n }\n\n event LogAction(address indexed target, bytes data);\n event SentToMiner(uint256 indexed value);\n event Recovered(address indexed tokenAddress, address indexed to, uint256 amount);\n\n error AmountOutTooLow(uint256 amount, uint256 min);\n error BalanceTooLow();\n error FlashbotsErrorPayingMiner(uint256 value);\n error IncompatibleLengths();\n error RevertBytes();\n error WrongAmount();\n error ZeroAddress();\n\n constructor() initializer {}\n\n function initialize(address keeper) external initializer {\n __AccessControl_init();\n\n _setupRole(KEEPER_ROLE, keeper);\n _setRoleAdmin(KEEPER_ROLE, KEEPER_ROLE);\n }\n\n /// @notice Allows an authorized keeper to execute multiple actions in a single step\n /// @param actions Actions to be executed\n /// @param percentageToMiner Percentage to pay to miner expressed in bps (10000)\n /// @dev This is the main entry point for actions to be executed. The `isDelegateCall` flag is used for calling function inside this `KeeperMulticall` contract,\n /// if we call other contracts, the flag should be false\n function executeActions(\n Action[] memory actions,\n uint256 percentageToMiner\n ) external payable onlyRole(KEEPER_ROLE) returns (bytes[] memory) {\n uint256 numberOfActions = actions.length;\n if (numberOfActions == 0) revert IncompatibleLengths();\n\n bytes[] memory returnValues = new bytes[](numberOfActions + 1);\n\n uint256 balanceBefore = address(this).balance;\n\n for (uint256 i; i < numberOfActions; ++i) {\n returnValues[i] = _executeAction(actions[i]);\n }\n\n if (percentageToMiner != 0) {\n if (percentageToMiner >= 10000) revert WrongAmount();\n uint256 balanceAfter = address(this).balance;\n if (balanceAfter > balanceBefore) {\n uint256 amountToMiner = ((balanceAfter - balanceBefore) * percentageToMiner) / 10000;\n returnValues[numberOfActions] = payFlashbots(amountToMiner);\n }\n }\n\n return returnValues;\n }\n\n /// @notice Gets the action address and data and executes it\n /// @param action Action to be executed\n function _executeAction(Action memory action) internal returns (bytes memory) {\n bool success;\n bytes memory response;\n\n if (action.isDelegateCall) {\n //solhint-disable-next-line\n (success, response) = action.target.delegatecall(action.data);\n } else {\n //solhint-disable-next-line\n (success, response) = action.target.call(action.data);\n }\n\n require(success, RevertReasonParser.parse(response, \"action reverted: \"));\n emit LogAction(action.target, action.data);\n return response;\n }\n\n /// @notice Ability to pay miner directly. Used for Flashbots to execute private transactions\n /// @param value Value to be sent\n function payFlashbots(uint256 value) public payable onlyRole(KEEPER_ROLE) returns (bytes memory) {\n //solhint-disable-next-line\n (bool success, bytes memory response) = block.coinbase.call{ value: value }(\"\");\n if (!success) revert FlashbotsErrorPayingMiner(value);\n emit SentToMiner(value);\n return response;\n }\n\n /// @notice Used to check the balances the token holds for each token. If we don't have enough of a token, we revert the tx\n /// @param tokens Array of tokens to check\n /// @param minBalances Array of balances for each token\n function finalBalanceCheck(IERC20[] memory tokens, uint256[] memory minBalances) external view returns (bool) {\n uint256 tokensLength = tokens.length;\n if (tokensLength == 0 || tokensLength != minBalances.length) revert IncompatibleLengths();\n\n for (uint256 i; i < tokensLength; ++i) {\n if (address(tokens[i]) == 0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE) {\n if (address(this).balance < minBalances[i]) revert BalanceTooLow();\n } else {\n if (tokens[i].balanceOf(address(this)) < minBalances[i]) revert BalanceTooLow();\n }\n }\n\n return true;\n }\n\n /// @notice Swap token to another through 1Inch\n /// @param minAmountOut Minimum amount of `out` token to receive for the swap to happen\n /// @param payload Bytes needed for 1Inch API\n function swapToken(uint256 minAmountOut, bytes memory payload) external onlyRole(KEEPER_ROLE) {\n //solhint-disable-next-line\n (bool success, bytes memory result) = _oneInch.call(payload);\n if (!success) _revertBytes(result);\n\n uint256 amountOut = abi.decode(result, (uint256));\n if (amountOut < minAmountOut) revert AmountOutTooLow(amountOut, minAmountOut);\n }\n\n /// @notice Copied from 1Inch contract, used to revert if there is an error\n function _revertBytes(bytes memory errMsg) internal pure {\n if (errMsg.length != 0) {\n //solhint-disable-next-line\n assembly {\n revert(add(32, errMsg), mload(errMsg))\n }\n }\n revert RevertBytes();\n }\n\n /// @notice Approve a `spender` for `token`\n /// @param token Address of the token to approve\n /// @param spender Address of the spender to approve\n /// @param amount Amount to approve\n function approve(IERC20 token, address spender, uint256 amount) external onlyRole(KEEPER_ROLE) {\n uint256 currentAllowance = token.allowance(address(this), spender);\n if (currentAllowance < amount) {\n token.safeIncreaseAllowance(spender, amount - currentAllowance);\n } else if (currentAllowance > amount) {\n token.safeDecreaseAllowance(spender, currentAllowance - amount);\n }\n }\n\n receive() external payable {}\n\n /// @notice Withdraw stuck funds\n /// @param token Address of the token to recover\n /// @param receiver Address where to send the tokens\n /// @param amount Amount to recover\n function withdrawStuckFunds(address token, address receiver, uint256 amount) external onlyRole(KEEPER_ROLE) {\n if (receiver == address(0)) revert ZeroAddress();\n if (token == 0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE) {\n payable(receiver).transfer(amount);\n } else {\n IERC20(token).safeTransfer(receiver, amount);\n }\n\n emit Recovered(token, receiver, amount);\n }\n}\n" + }, + "contracts/keeperMulticall/MulticallWithFailure.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.12;\n\n/// @title MultiCallWithFailure\n/// @author Angle Labs, Inc.\n/// @notice Multicall contract allowing subcalls to fail without reverting the entire call\ncontract MultiCallWithFailure {\n error SubcallFailed();\n\n struct Call {\n address target;\n bytes data;\n bool canFail;\n }\n\n function multiCall(Call[] memory calls) external view returns (bytes[] memory) {\n bytes[] memory results = new bytes[](calls.length);\n\n for (uint256 i; i < calls.length; ++i) {\n (bool success, bytes memory result) = calls[i].target.staticcall(calls[i].data);\n if (!calls[i].canFail) {\n if (!success) {\n revert SubcallFailed();\n }\n }\n results[i] = result;\n }\n\n return results;\n }\n}\n" + }, + "contracts/keeperMulticall/RevertReasonParser.sol": { + "content": "// SPDX-License-Identifier: GNU-3\n\npragma solidity ^0.8.12;\n\n/// @title RevertReasonParser\n/// @author 1Inch team, taken from:\n/// - https://docs.1inch.io/docs/limit-order-protocol/smart-contract/libraries/RevertReasonParser/\n/// - https://etherscan.io/address/0x1111111254fb6c44bAC0beD2854e76F90643097d#code\nlibrary RevertReasonParser {\n bytes4 private constant _PANIC_SELECTOR = bytes4(keccak256(\"Panic(uint256)\"));\n bytes4 private constant _ERROR_SELECTOR = bytes4(keccak256(\"Error(string)\"));\n\n function parse(bytes memory data, string memory prefix) internal pure returns (string memory) {\n if (data.length >= 4) {\n bytes4 selector;\n //solhint-disable-next-line\n assembly {\n selector := mload(add(data, 0x20))\n }\n\n // 68 = 4-byte selector + 32 bytes offset + 32 bytes length\n if (selector == _ERROR_SELECTOR && data.length >= 68) {\n uint256 offset;\n bytes memory reason;\n // solhint-disable no-inline-assembly\n assembly {\n // 36 = 32 bytes data length + 4-byte selector\n offset := mload(add(data, 36))\n reason := add(data, add(36, offset))\n }\n /*\n revert reason is padded up to 32 bytes with ABI encoder: Error(string)\n also sometimes there is extra 32 bytes of zeros padded in the end:\n https://github.com/ethereum/solidity/issues/10170\n because of that we can't check for equality and instead check\n that offset + string length + extra 36 bytes is less than overall data length\n */\n require(data.length >= 36 + offset + reason.length, \"Invalid revert reason\");\n return string(abi.encodePacked(prefix, \"Error(\", reason, \")\"));\n }\n // 36 = 4-byte selector + 32 bytes integer\n else if (selector == _PANIC_SELECTOR && data.length == 36) {\n uint256 code;\n // solhint-disable no-inline-assembly\n assembly {\n // 36 = 32 bytes data length + 4-byte selector\n code := mload(add(data, 36))\n }\n return string(abi.encodePacked(prefix, \"Panic(\", _toHex(code), \")\"));\n }\n }\n\n return string(abi.encodePacked(prefix, \"Unknown(\", _toHex(data), \")\"));\n }\n\n function _toHex(uint256 value) private pure returns (string memory) {\n return _toHex(abi.encodePacked(value));\n }\n\n function _toHex(bytes memory data) private pure returns (string memory) {\n bytes16 alphabet = 0x30313233343536373839616263646566;\n bytes memory str = new bytes(2 + data.length * 2);\n str[0] = \"0\";\n str[1] = \"x\";\n for (uint256 i; i < data.length; ++i) {\n str[2 * i + 2] = alphabet[uint8(data[i] >> 4)];\n str[2 * i + 3] = alphabet[uint8(data[i] & 0x0f)];\n }\n return string(str);\n }\n}\n" + }, + "contracts/mock/Mock1Inch.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.12;\n\nimport \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\nimport \"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\";\n\ncontract Mock1Inch {\n using SafeERC20 for IERC20;\n\n function swap(address tokenIn, uint256 amountIn, address to, address tokenOut, uint256 amountOut) external {\n IERC20(tokenIn).safeTransferFrom(msg.sender, to, amountIn);\n if (tokenOut == 0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE) {\n //solhint-disable-next-line\n (bool sent, bytes memory data) = msg.sender.call{ value: amountOut }(\"\");\n data;\n require(sent, \"Failed to send Ether\");\n } else {\n IERC20(tokenOut).safeTransferFrom(to, msg.sender, amountOut);\n }\n }\n\n receive() external payable {}\n}\n" + }, + "contracts/mock/MockAnything.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.12;\n\ncontract MockAnything {\n uint256 public stateVar = 1;\n\n error CustomError();\n error CustomErrorWithValue(uint256);\n\n function fail(uint256 value) external view returns (uint256) {\n stateVar;\n if (value < 10) {\n revert CustomError();\n }\n if (value < 20) {\n revert CustomErrorWithValue(value);\n }\n return value + 1;\n }\n\n function modifyState(uint256 value) external {\n stateVar = value;\n }\n}\n" + }, + "contracts/mock/MockChainlinkOracle.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.7;\n\ninterface MockAggregatorV3Interface {\n function decimals() external view returns (uint8);\n\n function description() external view returns (string memory);\n\n function version() external view returns (uint256);\n\n function getRoundData(\n uint80 _roundId\n )\n external\n view\n returns (uint80 roundId, int256 answer, uint256 startedAt, uint256 updatedAt, uint80 answeredInRound);\n\n function latestRoundData()\n external\n view\n returns (uint80 roundId, int256 answer, uint256 startedAt, uint256 updatedAt, uint80 answeredInRound);\n}\n\ncontract MockChainlinkOracle is MockAggregatorV3Interface {\n uint80 public roundId = 0;\n uint8 public keyDecimals = 0;\n\n struct Entry {\n uint80 roundId;\n int256 answer;\n uint256 startedAt;\n uint256 updatedAt;\n uint80 answeredInRound;\n }\n\n mapping(uint256 => Entry) public entries;\n\n bool public latestRoundDataShouldRevert;\n\n string public desc;\n\n constructor() {}\n\n // Mock setup function\n function setLatestAnswer(int256 answer, uint256 timestamp) external {\n roundId++;\n entries[roundId] = Entry({\n roundId: roundId,\n answer: answer,\n startedAt: timestamp,\n updatedAt: timestamp,\n answeredInRound: roundId\n });\n }\n\n function setLatestAnswerWithRound(int256 answer, uint256 timestamp, uint80 _roundId) external {\n roundId = _roundId;\n entries[roundId] = Entry({\n roundId: roundId,\n answer: answer,\n startedAt: timestamp,\n updatedAt: timestamp,\n answeredInRound: roundId\n });\n }\n\n function setLatestAnswerRevert(int256 answer, uint256 timestamp) external {\n roundId++;\n entries[roundId] = Entry({\n roundId: roundId,\n answer: answer,\n startedAt: timestamp,\n updatedAt: timestamp,\n answeredInRound: roundId - 1\n });\n }\n\n function setLatestRoundDataShouldRevert(bool _shouldRevert) external {\n latestRoundDataShouldRevert = _shouldRevert;\n }\n\n function setDecimals(uint8 _decimals) external {\n keyDecimals = _decimals;\n }\n\n function setDescritpion(string memory _desc) external {\n desc = _desc;\n }\n\n function description() external view override returns (string memory) {\n return desc;\n }\n\n function version() external view override returns (uint256) {\n roundId;\n return 0;\n }\n\n function latestRoundData() external view override returns (uint80, int256, uint256, uint256, uint80) {\n if (latestRoundDataShouldRevert) {\n revert(\"latestRoundData reverted\");\n }\n return getRoundData(uint80(roundId));\n }\n\n function decimals() external view override returns (uint8) {\n return keyDecimals;\n }\n\n function getRoundData(uint80 _roundId) public view override returns (uint80, int256, uint256, uint256, uint80) {\n Entry memory entry = entries[_roundId];\n // Emulate a Chainlink aggregator\n require(entry.updatedAt > 0, \"No data present\");\n return (entry.roundId, entry.answer, entry.startedAt, entry.updatedAt, entry.answeredInRound);\n }\n}\n" + }, + "contracts/mock/MockCoreBorrow.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\nimport \"../interfaces/ICoreBorrow.sol\";\nimport \"../interfaces/IFlashAngle.sol\";\nimport \"../interfaces/ITreasury.sol\";\n\ncontract MockCoreBorrow is ICoreBorrow {\n mapping(address => bool) public flashLoaners;\n mapping(address => bool) public governors;\n mapping(address => bool) public guardians;\n\n function isFlashLoanerTreasury(address treasury) external view override returns (bool) {\n return flashLoaners[treasury];\n }\n\n function isGovernor(address admin) external view override returns (bool) {\n return governors[admin];\n }\n\n function isGovernorOrGuardian(address admin) external view override returns (bool) {\n return governors[admin] || guardians[admin];\n }\n\n function toggleGovernor(address admin) external {\n governors[admin] = !governors[admin];\n }\n\n function toggleGuardian(address admin) external {\n guardians[admin] = !guardians[admin];\n }\n\n function toggleFlashLoaners(address admin) external {\n flashLoaners[admin] = !flashLoaners[admin];\n }\n\n function addStablecoinSupport(IFlashAngle flashAngle, address _treasury) external {\n flashAngle.addStablecoinSupport(_treasury);\n }\n\n function removeStablecoinSupport(IFlashAngle flashAngle, address _treasury) external {\n flashAngle.removeStablecoinSupport(_treasury);\n }\n\n function setCore(IFlashAngle flashAngle, address _core) external {\n flashAngle.setCore(_core);\n }\n\n function setFlashLoanModule(ITreasury _treasury, address _flashLoanModule) external {\n _treasury.setFlashLoanModule(_flashLoanModule);\n }\n}\n" + }, + "contracts/mock/MockERC1271.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.12;\n\nimport \"../interfaces/external/IERC1271.sol\";\n\ncontract MockERC1271 is IERC1271 {\n uint256 public mode = 0;\n\n function setMode(uint256 _mode) public {\n mode = _mode;\n }\n\n /// @notice Returns whether the provided signature is valid for the provided data\n /// @dev MUST return the bytes4 magic value 0x1626ba7e when function passes.\n /// MUST NOT modify state (using STATICCALL for solc < 0.5, view modifier for solc > 0.5).\n /// MUST allow external calls.\n /// @return magicValue The bytes4 magic value 0x1626ba7e\n function isValidSignature(bytes32, bytes memory) external view returns (bytes4 magicValue) {\n if (mode == 1) magicValue = 0x1626ba7e;\n }\n}\n" + }, + "contracts/mock/MockERC721Receiver.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (token/ERC721/utils/ERC721Holder.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Implementation of the {IERC721Receiver} interface.\n *\n * Accepts all token transfers.\n * Make sure the contract is able to use its token with {IERC721-safeTransferFrom}, {IERC721-approve} or {IERC721-setApprovalForAll}.\n */\ncontract MockERC721Receiver {\n uint256 public mode = 0;\n\n function setMode(uint256 _mode) public {\n mode = _mode;\n }\n\n function onERC721Received(address, address, uint256, bytes memory) public view returns (bytes4) {\n require(mode != 1, \"0x1111111\");\n if (mode == 2) return this.setMode.selector;\n return this.onERC721Received.selector;\n }\n}\n" + }, + "contracts/mock/MockEulerPool.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\nimport \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\n\ncontract MockEulerPool {\n IERC20 public collateral;\n uint256 public poolSize;\n //solhint-disable-next-line\n uint256 public MAX_SANE_AMOUNT;\n\n mapping(address => uint256) public users;\n uint256 public interestRateAccumulator;\n\n constructor(IERC20 collateral_, uint256 poolSize_) {\n collateral = collateral_;\n poolSize = poolSize_;\n interestRateAccumulator = 10 ** 18;\n MAX_SANE_AMOUNT = type(uint112).max;\n }\n\n function setPoolSize(uint256 poolSize_) external {\n uint256 balance = collateral.balanceOf(address(this));\n poolSize = poolSize_;\n if (balance > poolSize_) collateral.transfer(msg.sender, balance - poolSize_);\n if (balance < poolSize_) collateral.transferFrom(msg.sender, address(this), poolSize_ - balance);\n }\n\n function setInterestRateAccumulator(uint256 interestRateAccumulator_) external {\n interestRateAccumulator = interestRateAccumulator_;\n }\n\n //solhint-disable-next-line\n function setMAXSANEAMOUNT(uint256 MAX_SANE_AMOUNT_) external {\n MAX_SANE_AMOUNT = MAX_SANE_AMOUNT_;\n }\n\n function balanceOfUnderlying(address account) external view returns (uint256) {\n return (users[account] * interestRateAccumulator) / 10 ** 18;\n }\n\n function deposit(uint256, uint256 amount) external {\n users[msg.sender] += (amount * 10 ** 18) / interestRateAccumulator;\n poolSize += amount;\n collateral.transferFrom(msg.sender, address(this), amount);\n }\n\n function withdraw(uint256, uint256 amount) external {\n if (amount == type(uint256).max) amount = (users[msg.sender] * interestRateAccumulator) / 10 ** 18;\n\n require(amount <= poolSize, \"4\");\n users[msg.sender] -= (amount * 10 ** 18) / interestRateAccumulator;\n collateral.transfer(msg.sender, amount);\n }\n}\n" + }, + "contracts/mock/MockFlashLoanModule.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\nimport \"../interfaces/IFlashAngle.sol\";\nimport \"../interfaces/ICoreBorrow.sol\";\n\ncontract MockFlashLoanModule is IFlashAngle {\n ICoreBorrow public override core;\n mapping(address => bool) public stablecoinsSupported;\n mapping(IAgToken => uint256) public interestAccrued;\n uint256 public surplusValue;\n\n constructor(ICoreBorrow _core) {\n core = _core;\n }\n\n function accrueInterestToTreasury(IAgToken stablecoin) external override returns (uint256 balance) {\n balance = surplusValue;\n interestAccrued[stablecoin] += balance;\n }\n\n function addStablecoinSupport(address _treasury) external override {\n stablecoinsSupported[_treasury] = true;\n }\n\n function removeStablecoinSupport(address _treasury) external override {\n stablecoinsSupported[_treasury] = false;\n }\n\n function setCore(address _core) external override {\n core = ICoreBorrow(_core);\n }\n\n function setSurplusValue(uint256 _surplusValue) external {\n surplusValue = _surplusValue;\n }\n}\n" + }, + "contracts/mock/MockFlashLoanReceiver.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.7;\n\nimport \"@openzeppelin/contracts/token/ERC20/ERC20.sol\";\n\nimport \"@openzeppelin/contracts/interfaces/IERC3156FlashBorrower.sol\";\n\nimport \"@openzeppelin/contracts/interfaces/IERC3156FlashLender.sol\";\n\ncontract MockFlashLoanReceiver is IERC3156FlashBorrower {\n bytes32 public constant CALLBACK_SUCCESS = keccak256(\"ERC3156FlashBorrower.onFlashLoan\");\n\n constructor() {}\n\n function onFlashLoan(\n address,\n address token,\n uint256 amount,\n uint256 fee,\n bytes calldata data\n ) external override returns (bytes32) {\n IERC20(token).approve(msg.sender, amount + fee);\n if (amount >= 10 ** 21) return keccak256(\"error\");\n if (amount == 2 * 10 ** 18) {\n IERC3156FlashLender(msg.sender).flashLoan(IERC3156FlashBorrower(address(this)), token, amount, data);\n return keccak256(\"reentrant\");\n } else return CALLBACK_SUCCESS;\n }\n}\n" + }, + "contracts/mock/MockInterestRateComputer.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\ncontract MockInterestRateComputer {\n uint256 public interestRate;\n uint256 public interestAccumulator;\n uint256 public immutable baseInterest;\n uint256 public immutable halfBase;\n\n uint256 public constant WEEK = 7 * 86400;\n\n constructor(uint256 _baseInterest, uint256 _interestRate) {\n interestAccumulator = _baseInterest;\n baseInterest = _baseInterest;\n halfBase = _baseInterest / 2;\n interestRate = _interestRate;\n }\n\n function _calculateAngle(uint256 exp, uint256 _interestAccumulator) internal view returns (uint256) {\n uint256 ratePerSecond = interestRate;\n if (exp == 0 || ratePerSecond == 0) return _interestAccumulator;\n uint256 expMinusOne = exp - 1;\n uint256 expMinusTwo = exp > 2 ? exp - 2 : 0;\n uint256 basePowerTwo = (ratePerSecond * ratePerSecond) / baseInterest;\n uint256 basePowerThree = (basePowerTwo * ratePerSecond) / baseInterest;\n uint256 secondTerm = (exp * expMinusOne * basePowerTwo) / 2;\n uint256 thirdTerm = (exp * expMinusOne * expMinusTwo * basePowerThree) / 6;\n return (_interestAccumulator * (baseInterest + ratePerSecond * exp + secondTerm + thirdTerm)) / baseInterest;\n }\n\n function _calculateAave(uint256 exp, uint256 _interestAccumulator) internal view returns (uint256) {\n uint256 ratePerSecond = interestRate;\n if (exp == 0 || ratePerSecond == 0) return _interestAccumulator;\n uint256 expMinusOne = exp - 1;\n uint256 expMinusTwo = exp > 2 ? exp - 2 : 0;\n uint256 basePowerTwo = (ratePerSecond * ratePerSecond + halfBase) / baseInterest;\n uint256 basePowerThree = (basePowerTwo * ratePerSecond + halfBase) / baseInterest;\n uint256 secondTerm = (exp * expMinusOne * basePowerTwo) / 2;\n uint256 thirdTerm = (exp * expMinusOne * expMinusTwo * basePowerThree) / 6;\n return (_interestAccumulator * (baseInterest + ratePerSecond * exp + secondTerm + thirdTerm)) / baseInterest;\n }\n\n function _calculateCompound(uint256 exp, uint256 _interestAccumulator) internal view returns (uint256) {\n return _interestAccumulator * (baseInterest + interestRate * exp);\n }\n\n function _rpow(uint256 x, uint256 n, uint256 base) internal pure returns (uint256 z) {\n //solhint-disable-next-line\n assembly {\n switch x\n case 0 {\n switch n\n case 0 {\n z := base\n }\n default {\n z := 0\n }\n }\n default {\n switch mod(n, 2)\n case 0 {\n z := base\n }\n default {\n z := x\n }\n let half := div(base, 2) // for rounding.\n for {\n n := div(n, 2)\n } n {\n n := div(n, 2)\n } {\n let xx := mul(x, x)\n if iszero(eq(div(xx, x), x)) {\n revert(0, 0)\n }\n let xxRound := add(xx, half)\n if lt(xxRound, xx) {\n revert(0, 0)\n }\n x := div(xxRound, base)\n if mod(n, 2) {\n let zx := mul(z, x)\n if and(iszero(iszero(x)), iszero(eq(div(zx, x), z))) {\n revert(0, 0)\n }\n let zxRound := add(zx, half)\n if lt(zxRound, zx) {\n revert(0, 0)\n }\n z := div(zxRound, base)\n }\n }\n }\n }\n }\n\n function _calculateMaker(uint256 delta, uint256 _interestAccumulator) internal view returns (uint256) {\n return (_rpow(baseInterest + interestRate, delta, baseInterest) * _interestAccumulator) / baseInterest;\n }\n\n function calculateAngle(uint256 delta) external view returns (uint256) {\n return _calculateAngle(delta, interestAccumulator);\n }\n\n function calculateAave(uint256 delta) external view returns (uint256) {\n return _calculateAave(delta, interestAccumulator);\n }\n\n function calculateMaker(uint256 delta) external view returns (uint256) {\n return _calculateMaker(delta, interestAccumulator);\n }\n\n function calculateAngle1Year() external view returns (uint256) {\n uint256 _interestAccumulator = interestAccumulator;\n for (uint256 i; i < 52; ++i) {\n _interestAccumulator = _calculateAngle(WEEK, _interestAccumulator);\n }\n return _interestAccumulator;\n }\n\n function calculateAave1Year() external view returns (uint256) {\n uint256 _interestAccumulator = interestAccumulator;\n for (uint256 i; i < 52; ++i) {\n _interestAccumulator = _calculateAave(WEEK, _interestAccumulator);\n }\n return _interestAccumulator;\n }\n\n function calculateMaker1Year() external view returns (uint256) {\n uint256 _interestAccumulator = interestAccumulator;\n for (uint256 i; i < 52; ++i) {\n _interestAccumulator = _calculateMaker(WEEK, _interestAccumulator);\n }\n return _interestAccumulator;\n }\n\n function calculateAngle1YearDirect() external view returns (uint256) {\n uint256 _interestAccumulator = interestAccumulator;\n _interestAccumulator = _calculateAngle(52 * WEEK, _interestAccumulator);\n\n return _interestAccumulator;\n }\n\n function calculateAave1YearDirect() external view returns (uint256) {\n uint256 _interestAccumulator = interestAccumulator;\n _interestAccumulator = _calculateAave(52 * WEEK, _interestAccumulator);\n\n return _interestAccumulator;\n }\n\n function calculateMaker1YearDirect() external view returns (uint256) {\n uint256 _interestAccumulator = interestAccumulator;\n _interestAccumulator = _calculateMaker(52 * WEEK, _interestAccumulator);\n\n return _interestAccumulator;\n }\n\n function calculateCompound1YearDirect() external view returns (uint256) {\n uint256 _interestAccumulator = interestAccumulator;\n _interestAccumulator = _calculateCompound(52 * WEEK, _interestAccumulator);\n\n return _interestAccumulator;\n }\n}\n" + }, + "contracts/mock/MockKeeperMulticall.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.12;\n\nimport \"@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/access/AccessControlUpgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol\";\nimport \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\nimport \"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\";\n\ncontract MockKeeperMulticall is Initializable, AccessControlUpgradeable {\n using SafeERC20 for IERC20;\n\n bytes32 public constant KEEPER_ROLE = keccak256(\"KEEPER_ROLE\");\n\n //solhint-disable-next-line\n address private constant _oneInch = 0x1111111254fb6c44bAC0beD2854e76F90643097d;\n\n struct Action {\n address target;\n bytes data;\n bool isDelegateCall;\n }\n\n event LogAction(address indexed target, bytes data);\n event SentToMiner(uint256 indexed value);\n event Recovered(address indexed tokenAddress, address indexed to, uint256 amount);\n\n error AmountOutTooLow(uint256 amount, uint256 min);\n error BalanceTooLow();\n error FlashbotsErrorPayingMiner(uint256 value);\n error IncompatibleLengths();\n error RevertBytes();\n error ZeroAddress();\n\n constructor() initializer {}\n\n function initialize(address keeper) public initializer {\n __AccessControl_init();\n\n _setupRole(KEEPER_ROLE, keeper);\n _setRoleAdmin(KEEPER_ROLE, KEEPER_ROLE);\n }\n}\n\ncontract MockKeeperMulticall2 {\n uint256 public varTest = 1;\n\n bytes32 public constant KEEPER_ROLE = keccak256(\"KEEPER_ROLE\");\n\n //solhint-disable-next-line\n address private constant _oneInch = 0x1111111254fb6c44bAC0beD2854e76F90643097d;\n\n struct Action {\n address target;\n bytes data;\n bool isDelegateCall;\n }\n\n event LogAction(address indexed target, bytes data);\n event SentToMiner(uint256 indexed value);\n event Recovered(address indexed tokenAddress, address indexed to, uint256 amount);\n\n error AmountOutTooLow(uint256 amount, uint256 min);\n error BalanceTooLow();\n error FlashbotsErrorPayingMiner(uint256 value);\n error IncompatibleLengths();\n error RevertBytes();\n error ZeroAddress();\n\n function functionTest() external pure returns (bool) {\n return true;\n }\n}\n" + }, + "contracts/mock/MockLayerZero.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\ninterface ILzApp {\n function lzReceive(uint16 _srcChainId, bytes memory _srcAddress, uint64 _nonce, bytes memory _payload) external;\n}\n\ncontract MockLayerZero {\n mapping(uint16 => uint256) public counters;\n uint256 public config;\n mapping(uint16 => uint64) public outboundNonce;\n uint256 public resumeReceived;\n uint256 public sendVersion;\n uint256 public receiveVersion;\n\n /// @notice Initiate with a fixe change rate\n constructor() {}\n\n function send(\n uint16 _dstChainId,\n bytes calldata,\n bytes calldata,\n address,\n address,\n bytes calldata\n ) external payable {\n counters[_dstChainId] += 1;\n }\n\n function getOutboundNonce(uint16 _dstChainId, address) external view returns (uint64) {\n return outboundNonce[_dstChainId];\n }\n\n function setOutBoundNonce(uint16 _from, uint64 value) external {\n outboundNonce[_from] = value;\n }\n\n function lzReceive(\n address lzApp,\n uint16 _srcChainId,\n bytes memory _srcAddress,\n uint64 _nonce,\n bytes memory _payload\n ) public {\n ILzApp(lzApp).lzReceive(_srcChainId, _srcAddress, _nonce, _payload);\n }\n\n function estimateFees(\n uint16,\n address,\n bytes calldata,\n bool,\n bytes calldata\n ) external pure returns (uint256 nativeFee, uint256 zroFee) {\n return (123, 456);\n }\n\n function setConfig(uint16, uint16, uint256 _configType, bytes calldata) external {\n config = _configType;\n }\n\n function getConfig(uint16, uint16, address, uint256) external view returns (bytes memory) {\n return abi.encodePacked(config);\n }\n\n function setSendVersion(uint16 _version) external {\n sendVersion = _version;\n }\n\n function setReceiveVersion(uint16 _version) external {\n receiveVersion = _version;\n }\n\n function forceResumeReceive(uint16, bytes calldata) external {\n resumeReceived = 1 - resumeReceived;\n }\n}\n" + }, + "contracts/mock/MockLiquidityGauge.sol": { + "content": "// SPDX-License-Identifier: UNLICENSED\npragma solidity ^0.8.12;\n\nimport { ILiquidityGauge } from \"../interfaces/coreModule/ILiquidityGauge.sol\";\nimport \"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\";\nimport \"@openzeppelin/contracts/token/ERC20/ERC20.sol\";\n\ncontract MockLiquidityGauge is ILiquidityGauge, ERC20 {\n using SafeERC20 for IERC20;\n\n IERC20 internal _ANGLE = IERC20(0x31429d1856aD1377A8A0079410B297e1a9e214c2);\n IERC20 internal _token;\n mapping(address => uint256) public rewards;\n\n constructor(string memory name_, string memory symbol_, address token_) ERC20(name_, symbol_) {\n _token = IERC20(token_);\n }\n\n function deposit(\n uint256 _value,\n address _addr,\n // solhint-disable-next-line\n bool\n ) external {\n _token.safeTransferFrom(msg.sender, address(this), _value);\n _mint(_addr, _value);\n }\n\n function withdraw(\n uint256 _value,\n // solhint-disable-next-line\n bool\n ) external {\n _burn(msg.sender, _value);\n _token.safeTransfer(msg.sender, _value);\n }\n\n // solhint-disable-next-line\n function claim_rewards(address _addr, address _receiver) external {\n if (_receiver == address(0)) _receiver = _addr;\n _ANGLE.safeTransfer(_receiver, rewards[_addr]);\n rewards[_addr] = 0;\n }\n\n // solhint-disable-next-line\n function claimable_reward(address _addr, address) external view returns (uint256 amount) {\n return rewards[_addr];\n }\n\n function setReward(address receiver_, uint256 amount) external {\n rewards[receiver_] = amount;\n }\n}\n" + }, + "contracts/mock/MockOracle.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.7;\n\nimport \"../interfaces/IOracle.sol\";\n\ncontract MockOracle is IOracle {\n event Update(uint256 _peg);\n\n ITreasury public treasury;\n\n uint256 public base = 1 ether;\n uint256 public precision = 1 ether;\n uint256 public rate;\n bool public outdated;\n\n /// @notice Initiate with a fixe change rate\n constructor(uint256 rate_, ITreasury _treasury) {\n rate = rate_;\n treasury = _treasury;\n }\n\n /// @notice Mock read\n function read() external view override returns (uint256) {\n return rate;\n }\n\n /// @notice change oracle rate\n function update(uint256 newRate) external {\n rate = newRate;\n }\n\n function setTreasury(address _treasury) external override {\n treasury = ITreasury(_treasury);\n }\n\n function circuitChainlink() external pure override returns (AggregatorV3Interface[] memory) {}\n}\n" + }, + "contracts/mock/MockPolygonAgEUR.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.12;\n\nimport \"../agToken/polygon/utils/ERC20UpgradeableCustom.sol\";\nimport \"@openzeppelin/contracts-upgradeable/access/AccessControlUpgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/utils/cryptography/draft-EIP712Upgradeable.sol\";\nimport \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\nimport \"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\";\n\nimport \"../interfaces/IAgToken.sol\";\nimport \"../interfaces/ITreasury.sol\";\n\ninterface IChildToken {\n function deposit(address user, bytes calldata depositData) external;\n\n function withdraw(uint256 amount) external;\n}\n\ncontract MockPolygonAgEUR is\n Initializable,\n ERC20UpgradeableCustom,\n AccessControlUpgradeable,\n EIP712Upgradeable,\n IChildToken\n{\n bytes32 public constant DEPOSITOR_ROLE = keccak256(\"DEPOSITOR_ROLE\");\n\n /// @dev Emitted when the child chain manager changes\n event ChildChainManagerAdded(address newAddress);\n event ChildChainManagerRevoked(address oldAddress);\n\n constructor() initializer {}\n\n function initialize(\n string memory _name,\n string memory _symbol,\n address childChainManager,\n address guardian\n ) public initializer {\n __ERC20_init(_name, _symbol);\n __AccessControl_init();\n _setupRole(DEFAULT_ADMIN_ROLE, guardian);\n _setupRole(DEPOSITOR_ROLE, childChainManager);\n __EIP712_init(_name, \"1\");\n }\n\n /**\n * @notice Called when the bridge has tokens to mint\n * @param user Address to mint the token to\n * @param depositData Encoded amount to mint\n */\n function deposit(address user, bytes calldata depositData) external override {\n require(hasRole(DEPOSITOR_ROLE, msg.sender));\n uint256 amount = abi.decode(depositData, (uint256));\n _mint(user, amount);\n }\n\n /**\n * @notice Called when user wants to withdraw tokens back to root chain\n * @dev Should burn user's tokens. This transaction will be verified when exiting on root chain\n * @param amount Amount of tokens to withdraw\n */\n function withdraw(uint256 amount) external override {\n _burn(_msgSender(), amount);\n }\n\n // =============================================================================\n // ======================= New data added for the upgrade ======================\n // =============================================================================\n\n mapping(address => bool) public isMinter;\n /// @notice Reference to the treasury contract which can grant minting rights\n address public treasury;\n /// @notice Boolean to check whether the contract has been reinitialized after its upgrade\n bool public treasuryInitialized;\n\n using SafeERC20 for IERC20;\n\n /// @notice Base used for fee computation\n uint256 public constant BASE_PARAMS = 10 ** 9;\n\n // =============================== Bridging Data ===============================\n\n /// @notice Struct with some data about a specific bridge token\n struct BridgeDetails {\n // Limit on the balance of bridge token held by the contract: it is designed\n // to reduce the exposure of the system to hacks\n uint256 limit;\n // Limit on the hourly volume of token minted through this bridge\n // Technically the limit over a rolling hour is hourlyLimit x2 as hourly limit\n // is enforced only between x:00 and x+1:00\n uint256 hourlyLimit;\n // Fee taken for swapping in and out the token\n uint64 fee;\n // Whether the associated token is allowed or not\n bool allowed;\n // Whether swapping in and out from the associated token is paused or not\n bool paused;\n }\n\n /// @notice Maps a bridge token to data\n mapping(address => BridgeDetails) public bridges;\n /// @notice List of all bridge tokens\n address[] public bridgeTokensList;\n /// @notice Maps a bridge token to the associated hourly volume\n mapping(address => mapping(uint256 => uint256)) public usage;\n /// @notice Maps an address to whether it is exempt of fees for when it comes to swapping in and out\n mapping(address => uint256) public isFeeExempt;\n\n uint256[44] private __gap;\n\n // ================================== Events ===================================\n\n event BridgeTokenAdded(address indexed bridgeToken, uint256 limit, uint256 hourlyLimit, uint64 fee, bool paused);\n event BridgeTokenToggled(address indexed bridgeToken, bool toggleStatus);\n event BridgeTokenRemoved(address indexed bridgeToken);\n event BridgeTokenFeeUpdated(address indexed bridgeToken, uint64 fee);\n event BridgeTokenLimitUpdated(address indexed bridgeToken, uint256 limit);\n event BridgeTokenHourlyLimitUpdated(address indexed bridgeToken, uint256 hourlyLimit);\n event HourlyLimitUpdated(uint256 hourlyLimit);\n event FeeToggled(address indexed theAddress, uint256 toggleStatus);\n event KeeperToggled(address indexed keeper, bool toggleStatus);\n event MinterToggled(address indexed minter);\n event Recovered(address indexed token, address indexed to, uint256 amount);\n event TreasuryUpdated(address indexed _treasury);\n\n // ================================== Errors ===================================\n\n error AssetStillControlledInReserves();\n error BurnAmountExceedsAllowance();\n error HourlyLimitExceeded();\n error InvalidSender();\n error InvalidToken();\n error InvalidTreasury();\n error NotGovernor();\n error NotGovernorOrGuardian();\n error NotMinter();\n error NotTreasury();\n error TooBigAmount();\n error TooHighParameterValue();\n error TreasuryAlreadyInitialized();\n error ZeroAddress();\n\n /// @notice Checks to see if it is the `Treasury` calling this contract\n /// @dev There is no Access Control here, because it can be handled cheaply through this modifier\n modifier onlyTreasury() {\n if (msg.sender != treasury) revert NotTreasury();\n _;\n }\n\n /// @notice Checks whether the sender has the minting right\n modifier onlyMinter() {\n if (!isMinter[msg.sender]) revert NotMinter();\n _;\n }\n\n /// @notice Checks whether the `msg.sender` has the governor role or not\n modifier onlyGovernor() {\n if (!ITreasury(treasury).isGovernor(msg.sender)) revert NotGovernor();\n _;\n }\n\n /// @notice Checks whether the `msg.sender` has the governor role or the guardian role\n modifier onlyGovernorOrGuardian() {\n if (!ITreasury(treasury).isGovernorOrGuardian(msg.sender)) revert NotGovernorOrGuardian();\n _;\n }\n\n /// @notice Sets up the treasury contract on Polygon after the upgrade\n /// @param _treasury Address of the treasury contract\n function setUpTreasury(address _treasury) external {\n // Only governor on Polygon\n if (msg.sender != 0xdA2D2f638D6fcbE306236583845e5822554c02EA) revert NotGovernor();\n if (address(ITreasury(_treasury).stablecoin()) != address(this)) revert InvalidTreasury();\n if (treasuryInitialized) revert TreasuryAlreadyInitialized();\n treasury = _treasury;\n treasuryInitialized = true;\n emit TreasuryUpdated(_treasury);\n }\n\n // =========================== External Function ===============================\n\n /// @notice Allows anyone to burn agToken without redeeming collateral back\n /// @param amount Amount of stablecoins to burn\n /// @dev This function can typically be called if there is a settlement mechanism to burn stablecoins\n function burnStablecoin(uint256 amount) external {\n _burnCustom(msg.sender, amount);\n }\n\n // ======================= Minter Role Only Functions ==========================\n\n function burnSelf(uint256 amount, address burner) external onlyMinter {\n _burnCustom(burner, amount);\n }\n\n function burnFrom(uint256 amount, address burner, address sender) external onlyMinter {\n _burnFromNoRedeem(amount, burner, sender);\n }\n\n function mint(address account, uint256 amount) external onlyMinter {\n _mint(account, amount);\n }\n\n // ======================= Treasury Only Functions =============================\n\n function addMinter(address minter) external onlyTreasury {\n isMinter[minter] = true;\n emit MinterToggled(minter);\n }\n\n function removeMinter(address minter) external {\n if (msg.sender != address(treasury) && msg.sender != minter) revert InvalidSender();\n isMinter[minter] = false;\n emit MinterToggled(minter);\n }\n\n function setTreasury(address _treasury) external onlyTreasury {\n treasury = _treasury;\n emit TreasuryUpdated(_treasury);\n }\n\n // ============================ Internal Function ==============================\n\n /// @notice Internal version of the function `burnFromNoRedeem`\n /// @param amount Amount to burn\n /// @dev It is at the level of this function that allowance checks are performed\n function _burnFromNoRedeem(uint256 amount, address burner, address sender) internal {\n if (burner != sender) {\n uint256 currentAllowance = allowance(burner, sender);\n if (currentAllowance < amount) revert BurnAmountExceedsAllowance();\n _approve(burner, sender, currentAllowance - amount);\n }\n _burnCustom(burner, amount);\n }\n\n // ==================== External Permissionless Functions ======================\n\n /// @notice Returns the list of all supported bridge tokens\n /// @dev Helpful for UIs\n function allBridgeTokens() external view returns (address[] memory) {\n return bridgeTokensList;\n }\n\n /// @notice Returns the current volume for a bridge, for the current hour\n /// @dev Helpful for UIs\n function currentUsage(address bridge) external view returns (uint256) {\n return usage[bridge][block.timestamp / 3600];\n }\n\n /// @notice Mints the canonical token from a supported bridge token\n /// @param bridgeToken Bridge token to use to mint\n /// @param amount Amount of bridge tokens to send\n /// @param to Address to which the stablecoin should be sent\n /// @dev Some fees may be taken by the protocol depending on the token used and on the address calling\n function swapIn(address bridgeToken, uint256 amount, address to) external returns (uint256) {\n BridgeDetails memory bridgeDetails = bridges[bridgeToken];\n if (!bridgeDetails.allowed || bridgeDetails.paused) revert InvalidToken();\n uint256 balance = IERC20(bridgeToken).balanceOf(address(this));\n if (balance + amount > bridgeDetails.limit) {\n // In case someone maliciously sends tokens to this contract\n // Or the limit changes\n if (bridgeDetails.limit > balance) amount = bridgeDetails.limit - balance;\n else {\n amount = 0;\n }\n }\n\n // Checking requirement on the hourly volume\n uint256 hour = block.timestamp / 3600;\n uint256 hourlyUsage = usage[bridgeToken][hour] + amount;\n if (hourlyUsage > bridgeDetails.hourlyLimit) {\n // Edge case when the hourly limit changes\n if (bridgeDetails.hourlyLimit > usage[bridgeToken][hour])\n amount = bridgeDetails.hourlyLimit - usage[bridgeToken][hour];\n else {\n amount = 0;\n }\n }\n usage[bridgeToken][hour] = usage[bridgeToken][hour] + amount;\n\n IERC20(bridgeToken).safeTransferFrom(msg.sender, address(this), amount);\n uint256 canonicalOut = amount;\n // Computing fees\n if (isFeeExempt[msg.sender] == 0) {\n canonicalOut -= (canonicalOut * bridgeDetails.fee) / BASE_PARAMS;\n }\n _mint(to, canonicalOut);\n return canonicalOut;\n }\n\n /// @notice Burns the canonical token in exchange for a bridge token\n /// @param bridgeToken Bridge token required\n /// @param amount Amount of canonical tokens to burn\n /// @param to Address to which the bridge token should be sent\n /// @dev Some fees may be taken by the protocol depending on the token used and on the address calling\n function swapOut(address bridgeToken, uint256 amount, address to) external returns (uint256) {\n BridgeDetails memory bridgeDetails = bridges[bridgeToken];\n if (!bridgeDetails.allowed || bridgeDetails.paused) revert InvalidToken();\n\n _burnCustom(msg.sender, amount);\n uint256 bridgeOut = amount;\n if (isFeeExempt[msg.sender] == 0) {\n bridgeOut -= (bridgeOut * bridgeDetails.fee) / BASE_PARAMS;\n }\n IERC20(bridgeToken).safeTransfer(to, bridgeOut);\n return bridgeOut;\n }\n\n // ======================= Governance Functions ================================\n\n /// @notice Adds support for a bridge token\n /// @param bridgeToken Bridge token to add: it should be a version of the stablecoin from another bridge\n /// @param limit Limit on the balance of bridge token this contract could hold\n /// @param hourlyLimit Limit on the hourly volume for this bridge\n /// @param paused Whether swapping for this token should be paused or not\n /// @param fee Fee taken upon swapping for or against this token\n function addBridgeToken(\n address bridgeToken,\n uint256 limit,\n uint256 hourlyLimit,\n uint64 fee,\n bool paused\n ) external onlyGovernor {\n if (bridges[bridgeToken].allowed || bridgeToken == address(0)) revert InvalidToken();\n if (fee > BASE_PARAMS) revert TooHighParameterValue();\n BridgeDetails memory _bridge;\n _bridge.limit = limit;\n _bridge.hourlyLimit = hourlyLimit;\n _bridge.paused = paused;\n _bridge.fee = fee;\n _bridge.allowed = true;\n bridges[bridgeToken] = _bridge;\n bridgeTokensList.push(bridgeToken);\n emit BridgeTokenAdded(bridgeToken, limit, hourlyLimit, fee, paused);\n }\n\n /// @notice Removes support for a token\n /// @param bridgeToken Address of the bridge token to remove support for\n function removeBridgeToken(address bridgeToken) external onlyGovernor {\n if (IERC20(bridgeToken).balanceOf(address(this)) != 0) revert AssetStillControlledInReserves();\n delete bridges[bridgeToken];\n // Deletion from `bridgeTokensList` loop\n uint256 bridgeTokensListLength = bridgeTokensList.length;\n for (uint256 i; i < bridgeTokensListLength - 1; ++i) {\n if (bridgeTokensList[i] == bridgeToken) {\n // Replace the `bridgeToken` to remove with the last of the list\n bridgeTokensList[i] = bridgeTokensList[bridgeTokensListLength - 1];\n break;\n }\n }\n // Remove last element in array\n bridgeTokensList.pop();\n emit BridgeTokenRemoved(bridgeToken);\n }\n\n /// @notice Recovers any ERC20 token\n /// @dev Can be used to withdraw bridge tokens for them to be de-bridged on mainnet\n function recoverERC20(address tokenAddress, address to, uint256 amountToRecover) external onlyGovernor {\n IERC20(tokenAddress).safeTransfer(to, amountToRecover);\n emit Recovered(tokenAddress, to, amountToRecover);\n }\n\n /// @notice Updates the `limit` amount for `bridgeToken`\n function setLimit(address bridgeToken, uint256 limit) external onlyGovernorOrGuardian {\n if (!bridges[bridgeToken].allowed) revert InvalidToken();\n bridges[bridgeToken].limit = limit;\n emit BridgeTokenLimitUpdated(bridgeToken, limit);\n }\n\n /// @notice Updates the `hourlyLimit` amount for `bridgeToken`\n function setHourlyLimit(address bridgeToken, uint256 hourlyLimit) external onlyGovernorOrGuardian {\n if (!bridges[bridgeToken].allowed) revert InvalidToken();\n bridges[bridgeToken].hourlyLimit = hourlyLimit;\n emit BridgeTokenHourlyLimitUpdated(bridgeToken, hourlyLimit);\n }\n\n /// @notice Updates the `fee` value for `bridgeToken`\n function setSwapFee(address bridgeToken, uint64 fee) external onlyGovernorOrGuardian {\n if (!bridges[bridgeToken].allowed) revert InvalidToken();\n if (fee > BASE_PARAMS) revert TooHighParameterValue();\n bridges[bridgeToken].fee = fee;\n emit BridgeTokenFeeUpdated(bridgeToken, fee);\n }\n\n /// @notice Pauses or unpauses swapping in and out for a token\n function toggleBridge(address bridgeToken) external onlyGovernorOrGuardian {\n if (!bridges[bridgeToken].allowed) revert InvalidToken();\n bool pausedStatus = bridges[bridgeToken].paused;\n bridges[bridgeToken].paused = !pausedStatus;\n emit BridgeTokenToggled(bridgeToken, !pausedStatus);\n }\n\n /// @notice Toggles fees for the address `theAddress`\n function toggleFeesForAddress(address theAddress) external onlyGovernorOrGuardian {\n uint256 feeExemptStatus = 1 - isFeeExempt[theAddress];\n isFeeExempt[theAddress] = feeExemptStatus;\n emit FeeToggled(theAddress, feeExemptStatus);\n }\n}\n" + }, + "contracts/mock/MockRouter.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\nimport \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\nimport \"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\";\n\nimport \"../interfaces/IAngleRouter.sol\";\nimport \"../interfaces/external/uniswap/IUniswapRouter.sol\";\nimport \"../interfaces/external/lido/IWStETH.sol\";\n\ncontract MockRouter is IUniswapV3Router, IWStETH {\n using SafeERC20 for IERC20;\n\n uint256 public counterAngleMint;\n uint256 public counterAngleBurn;\n uint256 public counter1Inch;\n uint256 public counterUni;\n uint256 public counterWrap;\n uint256 public counterMixer;\n uint256 public amountOutUni;\n uint256 public multiplierMintBurn;\n uint256 public stETHMultiplier;\n address public inToken;\n address public outToken;\n\n address public stETH;\n\n /// @notice Action types\n enum ActionType {\n transfer,\n wrap,\n wrapNative,\n sweep,\n sweepNative,\n unwrap,\n unwrapNative,\n swapIn,\n swapOut,\n uniswapV3,\n oneInch,\n claimRewards,\n gaugeDeposit,\n borrower\n }\n\n /// @notice Data needed to get permits\n struct PermitType {\n address token;\n address owner;\n uint256 value;\n uint256 deadline;\n uint8 v;\n bytes32 r;\n bytes32 s;\n }\n\n constructor() {}\n\n function mint(address user, uint256 amount, uint256, address stablecoin, address collateral) external {\n counterAngleMint += 1;\n IERC20(collateral).safeTransferFrom(msg.sender, address(this), amount);\n IERC20(stablecoin).safeTransfer(user, (amount * 10 ** 9) / multiplierMintBurn);\n }\n\n function setStETH(address _stETH) external {\n stETH = _stETH;\n }\n\n function burn(address user, uint256 amount, uint256, address stablecoin, address collateral) external {\n counterAngleBurn += 1;\n IERC20(stablecoin).safeTransferFrom(msg.sender, address(this), amount);\n IERC20(collateral).safeTransfer(user, (amount * multiplierMintBurn) / 10 ** 9);\n }\n\n function mixer(\n PermitType[] memory paramsPermit,\n ActionType[] memory actions,\n bytes[] calldata data\n ) public payable virtual {\n paramsPermit;\n counterMixer += 1;\n for (uint256 i; i < actions.length; ++i) {\n if (actions[i] == ActionType.transfer) {\n (address transferToken, uint256 amount) = abi.decode(data[i], (address, uint256));\n IERC20(transferToken).safeTransferFrom(msg.sender, address(this), amount);\n }\n }\n }\n\n function wrap(uint256 amount) external returns (uint256 amountOut) {\n amountOut = (amount * stETHMultiplier) / 10 ** 9;\n counterWrap += 1;\n IERC20(stETH).safeTransferFrom(msg.sender, address(this), amount);\n IERC20(outToken).safeTransfer(msg.sender, amountOut);\n }\n\n function oneInch(uint256 amountIn) external returns (uint256 amountOut) {\n counter1Inch += 1;\n amountOut = (amountOutUni * amountIn) / 10 ** 9;\n IERC20(inToken).safeTransferFrom(msg.sender, address(this), amountIn);\n IERC20(outToken).safeTransfer(msg.sender, amountOut);\n }\n\n function oneInchReverts() external {\n counter1Inch += 1;\n revert(\"wrong swap\");\n }\n\n function oneInchRevertsWithoutMessage() external {\n counter1Inch += 1;\n require(false);\n }\n\n function exactInput(ExactInputParams calldata params) external payable returns (uint256 amountOut) {\n counterUni += 1;\n amountOut = (params.amountIn * amountOutUni) / 10 ** 9;\n IERC20(inToken).safeTransferFrom(msg.sender, address(this), params.amountIn);\n IERC20(outToken).safeTransfer(params.recipient, amountOut);\n require(amountOut >= params.amountOutMinimum);\n }\n\n function setMultipliers(uint256 a, uint256 b) external {\n amountOutUni = a;\n multiplierMintBurn = b;\n }\n\n function setStETHMultiplier(uint256 value) external {\n stETHMultiplier = value;\n }\n\n function setInOut(address _collateral, address _stablecoin) external {\n inToken = _collateral;\n outToken = _stablecoin;\n }\n}\n" + }, + "contracts/mock/MockSidechainAgEUR.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\nimport \"../agToken/AgToken.sol\";\nimport \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\nimport \"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\";\n\n/// @title AgTokenSideChainMultiBridge\n/// @author Angle Labs, Inc.\n/// @notice Contract for Angle agTokens on other chains than Ethereum mainnet\n/// @dev This contract supports bridge tokens having a minting right on the stablecoin (also referred to as the canonical\n/// or the native token)\n/// @dev References:\n/// - FRAX implementation: https://polygonscan.com/address/0x45c32fA6DF82ead1e2EF74d17b76547EDdFaFF89#code\n/// - QiDAO implementation: https://snowtrace.io/address/0x5c49b268c9841AFF1Cc3B0a418ff5c3442eE3F3b#code\ncontract MockSidechainAgEUR is AgToken {\n using SafeERC20 for IERC20;\n\n /// @notice Base used for fee computation\n uint256 public constant BASE_PARAMS = 10 ** 9;\n\n // =============================== Bridging Data ===============================\n\n /// @notice Struct with some data about a specific bridge token\n struct BridgeDetails {\n // Limit on the balance of bridge token held by the contract: it is designed\n // to reduce the exposure of the system to hacks\n uint256 limit;\n // Limit on the hourly volume of token minted through this bridge\n // Technically the limit over a rolling hour is hourlyLimit x2 as hourly limit\n // is enforced only between x:00 and x+1:00\n uint256 hourlyLimit;\n // Fee taken for swapping in and out the token\n uint64 fee;\n // Whether the associated token is allowed or not\n bool allowed;\n // Whether swapping in and out from the associated token is paused or not\n bool paused;\n }\n\n /// @notice Maps a bridge token to data\n mapping(address => BridgeDetails) public bridges;\n /// @notice List of all bridge tokens\n address[] public bridgeTokensList;\n /// @notice Maps a bridge token to the associated hourly volume\n mapping(address => mapping(uint256 => uint256)) public usage;\n /// @notice Maps an address to whether it is exempt of fees for when it comes to swapping in and out\n mapping(address => uint256) public isFeeExempt;\n\n // ================================== Events ===================================\n\n event BridgeTokenAdded(address indexed bridgeToken, uint256 limit, uint256 hourlyLimit, uint64 fee, bool paused);\n event BridgeTokenToggled(address indexed bridgeToken, bool toggleStatus);\n event BridgeTokenRemoved(address indexed bridgeToken);\n event BridgeTokenFeeUpdated(address indexed bridgeToken, uint64 fee);\n event BridgeTokenLimitUpdated(address indexed bridgeToken, uint256 limit);\n event BridgeTokenHourlyLimitUpdated(address indexed bridgeToken, uint256 hourlyLimit);\n event HourlyLimitUpdated(uint256 hourlyLimit);\n event Recovered(address indexed token, address indexed to, uint256 amount);\n event FeeToggled(address indexed theAddress, uint256 toggleStatus);\n\n // =============================== Errors ================================\n\n error AssetStillControlledInReserves();\n error HourlyLimitExceeded();\n error InvalidToken();\n error NotGovernor();\n error NotGovernorOrGuardian();\n error TooBigAmount();\n error TooHighParameterValue();\n error ZeroAddress();\n\n // ============================= Constructor ===================================\n\n /// @notice Checks whether the `msg.sender` has the governor role or not\n modifier onlyGovernor() {\n if (!ITreasury(treasury).isGovernor(msg.sender)) revert NotGovernor();\n _;\n }\n\n /// @notice Checks whether the `msg.sender` has the governor role or the guardian role\n modifier onlyGovernorOrGuardian() {\n if (!ITreasury(treasury).isGovernorOrGuardian(msg.sender)) revert NotGovernorOrGuardian();\n _;\n }\n\n // ==================== External Permissionless Functions ======================\n\n /// @notice Returns the list of all supported bridge tokens\n /// @dev Helpful for UIs\n function allBridgeTokens() external view returns (address[] memory) {\n return bridgeTokensList;\n }\n\n /// @notice Returns the current volume for a bridge, for the current hour\n /// @param bridgeToken Bridge used to mint\n /// @dev Helpful for UIs\n function currentUsage(address bridgeToken) external view returns (uint256) {\n return usage[bridgeToken][block.timestamp / 3600];\n }\n\n /// @notice Mints the canonical token from a supported bridge token\n /// @param bridgeToken Bridge token to use to mint\n /// @param amount Amount of bridge tokens to send\n /// @param to Address to which the stablecoin should be sent\n /// @return Amount of the canonical stablecoin actually minted\n /// @dev Some fees may be taken by the protocol depending on the token used and on the address calling\n function swapIn(address bridgeToken, uint256 amount, address to) external returns (uint256) {\n BridgeDetails memory bridgeDetails = bridges[bridgeToken];\n if (!bridgeDetails.allowed || bridgeDetails.paused) revert InvalidToken();\n uint256 balance = IERC20(bridgeToken).balanceOf(address(this));\n if (balance + amount > bridgeDetails.limit) {\n // In case someone maliciously sends tokens to this contract\n // Or the limit changes\n if (bridgeDetails.limit > balance) amount = bridgeDetails.limit - balance;\n else {\n amount = 0;\n }\n }\n\n // Checking requirement on the hourly volume\n uint256 hour = block.timestamp / 3600;\n uint256 hourlyUsage = usage[bridgeToken][hour] + amount;\n if (hourlyUsage > bridgeDetails.hourlyLimit) {\n // Edge case when the hourly limit changes\n if (bridgeDetails.hourlyLimit > usage[bridgeToken][hour])\n amount = bridgeDetails.hourlyLimit - usage[bridgeToken][hour];\n else {\n amount = 0;\n }\n }\n usage[bridgeToken][hour] = usage[bridgeToken][hour] + amount;\n\n IERC20(bridgeToken).safeTransferFrom(msg.sender, address(this), amount);\n uint256 canonicalOut = amount;\n // Computing fees\n if (isFeeExempt[msg.sender] == 0) {\n canonicalOut -= (canonicalOut * bridgeDetails.fee) / BASE_PARAMS;\n }\n _mint(to, canonicalOut);\n return canonicalOut;\n }\n\n /// @notice Burns the canonical token in exchange for a bridge token\n /// @param bridgeToken Bridge token required\n /// @param amount Amount of canonical tokens to burn\n /// @param to Address to which the bridge token should be sent\n /// @return Amount of bridge tokens actually sent back\n /// @dev Some fees may be taken by the protocol depending on the token used and on the address calling\n function swapOut(address bridgeToken, uint256 amount, address to) external returns (uint256) {\n BridgeDetails memory bridgeDetails = bridges[bridgeToken];\n if (!bridgeDetails.allowed || bridgeDetails.paused) revert InvalidToken();\n\n _burn(msg.sender, amount);\n uint256 bridgeOut = amount;\n if (isFeeExempt[msg.sender] == 0) {\n bridgeOut -= (bridgeOut * bridgeDetails.fee) / BASE_PARAMS;\n }\n IERC20(bridgeToken).safeTransfer(to, bridgeOut);\n return bridgeOut;\n }\n\n // ======================= Governance Functions ================================\n\n /// @notice Adds support for a bridge token\n /// @param bridgeToken Bridge token to add: it should be a version of the stablecoin from another bridge\n /// @param limit Limit on the balance of bridge token this contract could hold\n /// @param hourlyLimit Limit on the hourly volume for this bridge\n /// @param paused Whether swapping for this token should be paused or not\n /// @param fee Fee taken upon swapping for or against this token\n function addBridgeToken(\n address bridgeToken,\n uint256 limit,\n uint256 hourlyLimit,\n uint64 fee,\n bool paused\n ) external onlyGovernor {\n if (bridges[bridgeToken].allowed || bridgeToken == address(0)) revert InvalidToken();\n if (fee > BASE_PARAMS) revert TooHighParameterValue();\n BridgeDetails memory _bridge;\n _bridge.limit = limit;\n _bridge.hourlyLimit = hourlyLimit;\n _bridge.paused = paused;\n _bridge.fee = fee;\n _bridge.allowed = true;\n bridges[bridgeToken] = _bridge;\n bridgeTokensList.push(bridgeToken);\n emit BridgeTokenAdded(bridgeToken, limit, hourlyLimit, fee, paused);\n }\n\n /// @notice Removes support for a token\n /// @param bridgeToken Address of the bridge token to remove support for\n function removeBridgeToken(address bridgeToken) external onlyGovernor {\n if (IERC20(bridgeToken).balanceOf(address(this)) != 0) revert AssetStillControlledInReserves();\n delete bridges[bridgeToken];\n // Deletion from `bridgeTokensList` loop\n uint256 bridgeTokensListLength = bridgeTokensList.length;\n for (uint256 i; i < bridgeTokensListLength - 1; ++i) {\n if (bridgeTokensList[i] == bridgeToken) {\n // Replace the `bridgeToken` to remove with the last of the list\n bridgeTokensList[i] = bridgeTokensList[bridgeTokensListLength - 1];\n break;\n }\n }\n // Remove last element in array\n bridgeTokensList.pop();\n emit BridgeTokenRemoved(bridgeToken);\n }\n\n /// @notice Recovers any ERC20 token\n /// @dev Can be used to withdraw bridge tokens for them to be de-bridged on mainnet\n function recoverERC20(address tokenAddress, address to, uint256 amountToRecover) external onlyGovernor {\n IERC20(tokenAddress).safeTransfer(to, amountToRecover);\n emit Recovered(tokenAddress, to, amountToRecover);\n }\n\n /// @notice Updates the `limit` amount for `bridgeToken`\n function setLimit(address bridgeToken, uint256 limit) external onlyGovernorOrGuardian {\n if (!bridges[bridgeToken].allowed) revert InvalidToken();\n bridges[bridgeToken].limit = limit;\n emit BridgeTokenLimitUpdated(bridgeToken, limit);\n }\n\n /// @notice Updates the `hourlyLimit` amount for `bridgeToken`\n function setHourlyLimit(address bridgeToken, uint256 hourlyLimit) external onlyGovernorOrGuardian {\n if (!bridges[bridgeToken].allowed) revert InvalidToken();\n bridges[bridgeToken].hourlyLimit = hourlyLimit;\n emit BridgeTokenHourlyLimitUpdated(bridgeToken, hourlyLimit);\n }\n\n /// @notice Updates the `fee` value for `bridgeToken`\n function setSwapFee(address bridgeToken, uint64 fee) external onlyGovernorOrGuardian {\n if (!bridges[bridgeToken].allowed) revert InvalidToken();\n if (fee > BASE_PARAMS) revert TooHighParameterValue();\n bridges[bridgeToken].fee = fee;\n emit BridgeTokenFeeUpdated(bridgeToken, fee);\n }\n\n /// @notice Pauses or unpauses swapping in and out for a token\n function toggleBridge(address bridgeToken) external onlyGovernorOrGuardian {\n if (!bridges[bridgeToken].allowed) revert InvalidToken();\n bool pausedStatus = bridges[bridgeToken].paused;\n bridges[bridgeToken].paused = !pausedStatus;\n emit BridgeTokenToggled(bridgeToken, !pausedStatus);\n }\n\n /// @notice Toggles fees for the address `theAddress`\n function toggleFeesForAddress(address theAddress) external onlyGovernorOrGuardian {\n uint256 feeExemptStatus = 1 - isFeeExempt[theAddress];\n isFeeExempt[theAddress] = feeExemptStatus;\n emit FeeToggled(theAddress, feeExemptStatus);\n }\n}\n" + }, + "contracts/mock/MockStableMaster.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\nimport \"../interfaces/IAgToken.sol\";\nimport \"./MockToken.sol\";\nimport \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\nimport \"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\";\nimport { SLPData, MintBurnData } from \"../interfaces/coreModule/IStableMaster.sol\";\n\n// All the details about a collateral that are going to be stored in `StableMaster`\nstruct Collateral {\n // Interface for the token accepted by the underlying `PoolManager` contract\n IERC20 token;\n // Reference to the `SanToken` for the pool\n MockToken sanToken;\n // Reference to the `PerpetualManager` for the pool\n address perpetualManager;\n // Adress of the oracle for the change rate between\n // collateral and the corresponding stablecoin\n address oracle;\n // Amount of collateral in the reserves that comes from users\n // converted in stablecoin value. Updated at minting and burning.\n // A `stocksUsers` of 10 for a collateral type means that overall the balance of the collateral from users\n // that minted/burnt stablecoins using this collateral is worth 10 of stablecoins\n uint256 stocksUsers;\n // Exchange rate between sanToken and collateral\n uint256 sanRate;\n // Base used in the collateral implementation (ERC20 decimal)\n uint256 collatBase;\n // Parameters for SLPs and update of the `sanRate`\n SLPData slpData;\n // All the fees parameters\n MintBurnData feeData;\n}\n\ncontract MockStableMaster {\n mapping(address => uint256) public poolManagerMap;\n\n constructor() {}\n\n function updateStocksUsers(uint256 amount, address poolManager) external {\n poolManagerMap[poolManager] += amount;\n }\n\n function burnSelf(IAgToken agToken, uint256 amount, address burner) external {\n agToken.burnSelf(amount, burner);\n }\n\n function burnFrom(IAgToken agToken, uint256 amount, address burner, address sender) external {\n agToken.burnFrom(amount, burner, sender);\n }\n\n function mint(IAgToken agToken, address account, uint256 amount) external {\n agToken.mint(account, amount);\n }\n}\n\ncontract MockStableMasterSanWrapper is MockStableMaster {\n using SafeERC20 for IERC20;\n\n /// @notice Maps a `PoolManager` contract handling a collateral for this stablecoin to the properties of the struct above\n mapping(address => Collateral) public collateralMap;\n\n constructor() MockStableMaster() {}\n\n uint256 internal constant _BASE_TOKENS = 10 ** 18;\n uint256 internal constant _BASE_PARAMS = 10 ** 9;\n IERC20 public token;\n\n function deposit(uint256 assets, address receiver, address poolManager) external {\n token.safeTransferFrom(msg.sender, address(this), assets);\n Collateral storage col = collateralMap[poolManager];\n _updateSanRate(col);\n uint256 amount = (assets * _BASE_TOKENS) / col.sanRate;\n col.sanToken.mint(receiver, amount);\n }\n\n function withdraw(uint256 assets, address sender, address receiver, address poolManager) external {\n Collateral storage col = collateralMap[poolManager];\n _updateSanRate(col);\n col.sanToken.burn(sender, assets);\n // Computing the amount of collateral to give back to the SLP depending on slippage and on the `sanRate`\n uint256 redeemInC = (assets * (_BASE_PARAMS - col.slpData.slippage) * col.sanRate) /\n (_BASE_TOKENS * _BASE_PARAMS);\n token.safeTransfer(receiver, redeemInC);\n }\n\n function setPoolManagerToken(address, address token_) external {\n token = MockToken(token_);\n }\n\n function setPoolManagerSanToken(address poolManager, address sanToken_) external {\n Collateral storage col = collateralMap[poolManager];\n col.sanToken = MockToken(sanToken_);\n }\n\n function setSanRate(address poolManager, uint256 sanRate_) external {\n Collateral storage col = collateralMap[poolManager];\n col.sanRate = sanRate_;\n }\n\n function _updateSanRate(Collateral storage col) internal {\n uint256 _lockedInterests = col.slpData.lockedInterests;\n // Checking if the `sanRate` has been updated in the current block using past block fees\n // This is a way to prevent flash loans attacks when an important amount of fees are going to be distributed\n // in a block: fees are stored but will just be distributed to SLPs who will be here during next blocks\n if (block.timestamp != col.slpData.lastBlockUpdated && _lockedInterests > 0) {\n uint256 sanMint = col.sanToken.totalSupply();\n if (sanMint != 0) {\n // Checking if the update is too important and should be made in multiple blocks\n if (_lockedInterests > col.slpData.maxInterestsDistributed) {\n // `sanRate` is expressed in `BASE_TOKENS`\n col.sanRate += (col.slpData.maxInterestsDistributed * 10 ** 18) / sanMint;\n _lockedInterests -= col.slpData.maxInterestsDistributed;\n } else {\n col.sanRate += (_lockedInterests * 10 ** 18) / sanMint;\n _lockedInterests = 0;\n }\n } else {\n _lockedInterests = 0;\n }\n }\n col.slpData.lockedInterests = _lockedInterests;\n col.slpData.lastBlockUpdated = block.timestamp;\n }\n\n // copy paste from the deployed contract\n function estimateSanRate(address poolManager) external view returns (uint256 sanRate, uint64 slippage) {\n Collateral memory col = collateralMap[poolManager];\n uint256 _lockedInterests = col.slpData.lockedInterests;\n // Checking if the `sanRate` has been updated in the current block using past block fees\n // This is a way to prevent flash loans attacks when an important amount of fees are going to be distributed\n // in a block: fees are stored but will just be distributed to SLPs who will be here during next blocks\n if (block.timestamp != col.slpData.lastBlockUpdated && _lockedInterests > 0) {\n uint256 sanMint = col.sanToken.totalSupply();\n if (sanMint != 0) {\n // Checking if the update is too important and should be made in multiple blocks\n if (_lockedInterests > col.slpData.maxInterestsDistributed) {\n // `sanRate` is expressed in `BASE_TOKENS`\n col.sanRate += (col.slpData.maxInterestsDistributed * 10 ** 18) / sanMint;\n _lockedInterests -= col.slpData.maxInterestsDistributed;\n } else {\n col.sanRate += (_lockedInterests * 10 ** 18) / sanMint;\n _lockedInterests = 0;\n }\n } else {\n _lockedInterests = 0;\n }\n }\n return (col.sanRate, col.slpData.slippage);\n }\n\n function setSLPData(\n address poolManager,\n uint256 lockedInterests,\n uint256 maxInterestsDistributed,\n uint64 slippage\n ) external {\n Collateral storage col = collateralMap[poolManager];\n col.slpData.lockedInterests = lockedInterests;\n col.slpData.maxInterestsDistributed = maxInterestsDistributed;\n col.slpData.slippage = slippage;\n }\n}\n" + }, + "contracts/mock/MockSwapper.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\nimport \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\nimport \"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\";\n\nimport \"../interfaces/ISwapper.sol\";\n\ncontract MockSwapper is ISwapper {\n bytes32 public constant CALLBACK_SUCCESS = keccak256(\"ERC3156FlashBorrower.onFlashLoan\");\n\n uint256 public counter;\n\n constructor() {}\n\n function swap(IERC20, IERC20, address, uint256, uint256, bytes calldata data) external {\n counter += 1;\n data;\n }\n}\n\ncontract MockSwapperWithSwap is ISwapper {\n using SafeERC20 for IERC20;\n bytes32 public constant CALLBACK_SUCCESS = keccak256(\"ERC3156FlashBorrower.onFlashLoan\");\n\n uint256 public counter;\n\n constructor() {}\n\n function swap(\n IERC20,\n IERC20 outToken,\n address outTokenRecipient,\n uint256 outTokenOwed,\n uint256,\n bytes calldata data\n ) external {\n counter += 1;\n outToken.safeTransfer(outTokenRecipient, outTokenOwed);\n\n data;\n }\n}\n" + }, + "contracts/mock/MockSwapperSidechain.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\nimport \"../swapper/Swapper.sol\";\n\n/// @title MockSwapperSidechain\n/// @author Angle Labs, Inc.\ncontract MockSwapperSidechain is Swapper {\n error NotImplemented();\n\n /// @notice Constructor of the contract\n /// @param _core Core address\n /// @param _uniV3Router UniswapV3 Router address\n /// @param _oneInch 1Inch Router address\n /// @param _angleRouter AngleRouter contract address\n constructor(\n ICoreBorrow _core,\n IUniswapV3Router _uniV3Router,\n address _oneInch,\n IAngleRouterSidechain _angleRouter\n ) Swapper(_core, _uniV3Router, _oneInch, _angleRouter) {}\n\n function _swapLeverage(bytes memory) internal pure override returns (uint256) {\n revert NotImplemented();\n }\n}\n" + }, + "contracts/mock/MockToken.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.7;\n\nimport \"@openzeppelin/contracts/token/ERC20/ERC20.sol\";\n\ncontract MockToken is ERC20 {\n event Minting(address indexed _to, address indexed _minter, uint256 _amount);\n\n event Burning(address indexed _from, address indexed _burner, uint256 _amount);\n\n uint8 internal _decimal;\n mapping(address => bool) public minters;\n address public treasury;\n\n constructor(string memory name_, string memory symbol_, uint8 decimal_) ERC20(name_, symbol_) {\n _decimal = decimal_;\n }\n\n function decimals() public view override returns (uint8) {\n return _decimal;\n }\n\n function mint(address account, uint256 amount) external {\n _mint(account, amount);\n emit Minting(account, msg.sender, amount);\n }\n\n function burn(address account, uint256 amount) public {\n _burn(account, amount);\n emit Burning(account, msg.sender, amount);\n }\n\n function setAllowance(address from, address to) public {\n _approve(from, to, type(uint256).max);\n }\n\n function burnSelf(uint256 amount, address account) public {\n _burn(account, amount);\n emit Burning(account, msg.sender, amount);\n }\n\n function addMinter(address minter) public {\n minters[minter] = true;\n }\n\n function removeMinter(address minter) public {\n minters[minter] = false;\n }\n\n function setTreasury(address _treasury) public {\n treasury = _treasury;\n }\n}\n" + }, + "contracts/mock/MockTokenPermit.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.7;\n\nimport \"@openzeppelin/contracts/token/ERC20/extensions/draft-ERC20Permit.sol\";\nimport \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\nimport \"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\";\n\ncontract MockTokenPermit is ERC20Permit {\n using SafeERC20 for IERC20;\n event Minting(address indexed _to, address indexed _minter, uint256 _amount);\n\n event Burning(address indexed _from, address indexed _burner, uint256 _amount);\n\n uint8 internal _decimal;\n mapping(address => bool) public minters;\n address public treasury;\n uint256 public fees;\n\n bool public reverts;\n\n constructor(string memory name_, string memory symbol_, uint8 decimal_) ERC20Permit(name_) ERC20(name_, symbol_) {\n _decimal = decimal_;\n }\n\n function decimals() public view override returns (uint8) {\n return _decimal;\n }\n\n function mint(address account, uint256 amount) external {\n _mint(account, amount);\n emit Minting(account, msg.sender, amount);\n }\n\n function burn(address account, uint256 amount) public {\n _burn(account, amount);\n emit Burning(account, msg.sender, amount);\n }\n\n function setAllowance(address from, address to) public {\n _approve(from, to, type(uint256).max);\n }\n\n function burnSelf(uint256 amount, address account) public {\n _burn(account, amount);\n emit Burning(account, msg.sender, amount);\n }\n\n function addMinter(address minter) public {\n minters[minter] = true;\n }\n\n function removeMinter(address minter) public {\n minters[minter] = false;\n }\n\n function setTreasury(address _treasury) public {\n treasury = _treasury;\n }\n\n function setFees(uint256 _fees) public {\n fees = _fees;\n }\n\n function recoverERC20(IERC20 token, address to, uint256 amount) external {\n token.safeTransfer(to, amount);\n }\n\n function swapIn(address bridgeToken, uint256 amount, address to) external returns (uint256) {\n require(!reverts);\n\n IERC20(bridgeToken).safeTransferFrom(msg.sender, address(this), amount);\n uint256 canonicalOut = amount;\n canonicalOut -= (canonicalOut * fees) / 10 ** 9;\n _mint(to, canonicalOut);\n return canonicalOut;\n }\n\n function swapOut(address bridgeToken, uint256 amount, address to) external returns (uint256) {\n require(!reverts);\n _burn(msg.sender, amount);\n uint256 bridgeOut = amount;\n bridgeOut -= (bridgeOut * fees) / 10 ** 9;\n IERC20(bridgeToken).safeTransfer(to, bridgeOut);\n return bridgeOut;\n }\n}\n" + }, + "contracts/mock/MockTreasury.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\nimport \"../interfaces/ITreasury.sol\";\nimport \"../interfaces/IFlashAngle.sol\";\nimport \"../interfaces/IVaultManager.sol\";\n\ncontract MockTreasury is ITreasury {\n IAgToken public override stablecoin;\n address public governor;\n address public guardian;\n address public vaultManager1;\n address public vaultManager2;\n address public flashLoanModule;\n address[] public vaultManagerList;\n\n constructor(\n IAgToken _stablecoin,\n address _governor,\n address _guardian,\n address _vaultManager1,\n address _vaultManager2,\n address _flashLoanModule\n ) {\n stablecoin = _stablecoin;\n governor = _governor;\n guardian = _guardian;\n vaultManager1 = _vaultManager1;\n vaultManager2 = _vaultManager2;\n flashLoanModule = _flashLoanModule;\n }\n\n function isGovernor(address admin) external view override returns (bool) {\n return (admin == governor);\n }\n\n function isGovernorOrGuardian(address admin) external view override returns (bool) {\n return (admin == governor || admin == guardian);\n }\n\n function isVaultManager(address _vaultManager) external view override returns (bool) {\n return (_vaultManager == vaultManager1 || _vaultManager == vaultManager2);\n }\n\n function setStablecoin(IAgToken _stablecoin) external {\n stablecoin = _stablecoin;\n }\n\n function setFlashLoanModule(address _flashLoanModule) external override {\n flashLoanModule = _flashLoanModule;\n }\n\n function setGovernor(address _governor) external {\n governor = _governor;\n }\n\n function setVaultManager(address _vaultManager) external {\n vaultManager1 = _vaultManager;\n }\n\n function setVaultManager2(address _vaultManager) external {\n vaultManager2 = _vaultManager;\n }\n\n function setTreasury(address _agTokenOrVaultManager, address _treasury) external {\n IAgToken(_agTokenOrVaultManager).setTreasury(_treasury);\n }\n\n function addMinter(IAgToken _agToken, address _minter) external {\n _agToken.addMinter(_minter);\n }\n\n function removeMinter(IAgToken _agToken, address _minter) external {\n _agToken.removeMinter(_minter);\n }\n\n function accrueInterestToTreasury(IFlashAngle flashAngle) external returns (uint256 balance) {\n balance = flashAngle.accrueInterestToTreasury(stablecoin);\n }\n\n function accrueInterestToTreasuryVaultManager(IVaultManager _vaultManager) external returns (uint256, uint256) {\n return _vaultManager.accrueInterestToTreasury();\n }\n}\n" + }, + "contracts/mock/MockUniswapV3Pool.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.7;\n\ncontract MockUniswapV3Pool {\n address public token0;\n address public token1;\n uint32 public constant EPOCH_DURATION = 24 * 3600 * 7;\n\n function setToken(address token, uint256 who) external {\n if (who == 0) token0 = token;\n else token1 = token;\n }\n\n function round(uint256 amount) external pure returns (uint256) {\n return (amount / EPOCH_DURATION) * EPOCH_DURATION;\n }\n}\n" + }, + "contracts/mock/MockVaultManager.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\nimport \"../interfaces/IVaultManager.sol\";\nimport \"../interfaces/ITreasury.sol\";\nimport \"@openzeppelin/contracts/token/ERC20/ERC20.sol\";\n\ncontract MockVaultManager {\n ITreasury public treasury;\n mapping(uint256 => Vault) public vaultData;\n mapping(uint256 => address) public ownerOf;\n uint256 public surplus;\n uint256 public badDebt;\n IAgToken public token;\n address public oracle = address(this);\n\n address public governor;\n address public collateral;\n address public stablecoin;\n uint256 public oracleValue;\n uint256 public interestAccumulator;\n uint256 public collateralFactor;\n uint256 public totalNormalizedDebt;\n\n constructor(address _treasury) {\n treasury = ITreasury(_treasury);\n }\n\n function accrueInterestToTreasury() external returns (uint256, uint256) {\n // Avoid the function to be view\n if (surplus >= badDebt) {\n token.mint(msg.sender, surplus - badDebt);\n }\n return (surplus, badDebt);\n }\n\n function read() external view returns (uint256) {\n return oracleValue;\n }\n\n function setParams(\n address _governor,\n address _collateral,\n address _stablecoin,\n uint256 _oracleValue,\n uint256 _interestAccumulator,\n uint256 _collateralFactor,\n uint256 _totalNormalizedDebt\n ) external {\n governor = _governor;\n collateral = _collateral;\n stablecoin = _stablecoin;\n interestAccumulator = _interestAccumulator;\n collateralFactor = _collateralFactor;\n totalNormalizedDebt = _totalNormalizedDebt;\n oracleValue = _oracleValue;\n }\n\n function setOwner(uint256 vaultID, address owner) external virtual {\n ownerOf[vaultID] = owner;\n }\n\n function setVaultData(uint256 normalizedDebt, uint256 collateralAmount, uint256 vaultID) external {\n vaultData[vaultID].normalizedDebt = normalizedDebt;\n vaultData[vaultID].collateralAmount = collateralAmount;\n }\n\n function isGovernor(address admin) external view returns (bool) {\n return admin == governor;\n }\n\n function setSurplusBadDebt(uint256 _surplus, uint256 _badDebt, IAgToken _token) external {\n surplus = _surplus;\n badDebt = _badDebt;\n token = _token;\n }\n\n function getDebtOut(uint256 vaultID, uint256 amountStablecoins, uint256 senderBorrowFee) external {}\n\n function setTreasury(address _treasury) external {\n treasury = ITreasury(_treasury);\n }\n\n function getVaultDebt(uint256 vaultID) external view returns (uint256) {\n vaultID;\n token;\n return 0;\n }\n\n function createVault(address toVault) external view returns (uint256) {\n toVault;\n token;\n return 0;\n }\n}\n\ncontract MockVaultManagerListing is MockVaultManager {\n // @notice Mapping from owner address to all his vaults\n mapping(address => uint256[]) internal _ownerListVaults;\n\n constructor(address _treasury) MockVaultManager(_treasury) {}\n\n function getUserVaults(address owner) public view returns (uint256[] memory) {\n return _ownerListVaults[owner];\n }\n\n function getUserCollateral(address owner) public view returns (uint256 totalCollateral) {\n uint256[] memory vaultList = _ownerListVaults[owner];\n uint256 vaultListLength = vaultList.length;\n for (uint256 k; k < vaultListLength; ++k) {\n totalCollateral += vaultData[vaultList[k]].collateralAmount;\n }\n return totalCollateral;\n }\n\n function setOwner(uint256 vaultID, address owner) external override {\n if (ownerOf[vaultID] != address(0)) _removeVaultFromList(ownerOf[vaultID], vaultID);\n _ownerListVaults[owner].push(vaultID);\n ownerOf[vaultID] = owner;\n }\n\n /// @notice Remove `vaultID` from `user` stroed vault list\n /// @param user Address to look out for the vault list\n /// @param vaultID VaultId to remove from the list\n /// @dev The vault is necessarily in the list\n function _removeVaultFromList(address user, uint256 vaultID) internal {\n uint256[] storage vaultList = _ownerListVaults[user];\n uint256 vaultListLength = vaultList.length;\n for (uint256 i; i < vaultListLength - 1; ++i) {\n if (vaultList[i] == vaultID) {\n vaultList[i] = vaultList[vaultListLength - 1];\n break;\n }\n }\n vaultList.pop();\n }\n}\n" + }, + "contracts/mock/MockVeBoostProxy.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\nimport \"../interfaces/governance/IVeBoostProxy.sol\";\n\ncontract MockVeBoostProxy is IVeBoostProxy {\n //solhint-disable-next-line\n mapping(address => uint256) public adjusted_balance_of;\n\n constructor() {}\n\n function setBalance(address concerned, uint256 balance) external {\n adjusted_balance_of[concerned] = balance;\n }\n}\n" + }, + "contracts/oracle/BaseOracleChainlinkMulti.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\n/*\n * █ \n ***** ▓▓▓ \n * ▓▓▓▓▓▓▓ \n * ///. ▓▓▓▓▓▓▓▓▓▓▓▓▓ \n ***** //////// ▓▓▓▓▓▓▓ \n * ///////////// ▓▓▓ \n ▓▓ ////////////////// █ ▓▓ \n ▓▓ ▓▓ /////////////////////// ▓▓ ▓▓ \n ▓▓ ▓▓ //////////////////////////// ▓▓ ▓▓ \n ▓▓ ▓▓ /////////▓▓▓///////▓▓▓///////// ▓▓ ▓▓ \n ▓▓ ,////////////////////////////////////// ▓▓ ▓▓ \n ▓▓ ////////////////////////////////////////// ▓▓ \n ▓▓ //////////////////////▓▓▓▓///////////////////// \n ,//////////////////////////////////////////////////// \n .////////////////////////////////////////////////////////// \n .//////////////////////////██.,//////////////////////////█ \n .//////////////////////████..,./////////////////////██ \n ...////////////////███████.....,.////////////////███ \n ,.,////////////████████ ........,///////////████ \n .,.,//////█████████ ,.......///////████ \n ,..//████████ ........./████ \n ..,██████ .....,███ \n .██ ,.,█ \n \n \n \n ▓▓ ▓▓▓▓▓▓▓▓▓▓ ▓▓▓▓▓▓▓▓▓▓ ▓▓ ▓▓▓▓▓▓▓▓▓▓ \n ▓▓▓▓▓▓ ▓▓▓ ▓▓▓ ▓▓▓ ▓▓ ▓▓ ▓▓▓▓ \n ▓▓▓ ▓▓▓ ▓▓▓ ▓▓▓ ▓▓▓ ▓▓▓ ▓▓ ▓▓▓▓▓ \n ▓▓▓ ▓▓ ▓▓▓ ▓▓▓ ▓▓▓▓▓▓▓▓▓▓ ▓▓▓▓▓▓▓▓▓▓ ▓▓▓▓▓▓▓▓▓▓ \n*/\n\npragma solidity ^0.8.12;\n\nimport \"@chainlink/contracts/src/v0.8/interfaces/AggregatorV3Interface.sol\";\n\nimport \"../interfaces/IOracle.sol\";\nimport \"../interfaces/ITreasury.sol\";\n\n/// @title BaseOracleChainlinkMulti\n/// @author Angle Labs, Inc.\n/// @notice Base Contract to be overriden by all contracts of the protocol\n/// @dev This base contract concerns an oracle that uses Chainlink with multiple pools to read from\n/// @dev All gas-efficient implementation of the `OracleChainlinkMulti` contract should inherit from this\nabstract contract BaseOracleChainlinkMulti is IOracle {\n // ========================= Parameters and References =========================\n\n /// @inheritdoc IOracle\n ITreasury public override treasury;\n /// @notice Represent the maximum amount of time (in seconds) between each Chainlink update\n /// before the price feed is considered stale\n uint32 public stalePeriod;\n\n // =================================== Event ===================================\n\n event StalePeriodUpdated(uint32 _stalePeriod);\n\n // =================================== Errors ===================================\n\n error InvalidChainlinkRate();\n error NotGovernorOrGuardian();\n error NotVaultManagerOrGovernor();\n\n /// @notice Constructor for an oracle using Chainlink with multiple pools to read from\n /// @param _stalePeriod Minimum feed update frequency for the oracle to not revert\n /// @param _treasury Treasury associated to the VaultManager which reads from this feed\n constructor(uint32 _stalePeriod, address _treasury) {\n stalePeriod = _stalePeriod;\n treasury = ITreasury(_treasury);\n }\n\n // ============================= Reading Oracles ===============================\n\n /// @inheritdoc IOracle\n function read() external view virtual override returns (uint256 quoteAmount);\n\n /// @inheritdoc IOracle\n function circuitChainlink() public view virtual returns (AggregatorV3Interface[] memory);\n\n /// @notice Reads a Chainlink feed using a quote amount and converts the quote amount to\n /// the out-currency\n /// @param quoteAmount The amount for which to compute the price expressed with base decimal\n /// @param feed Chainlink feed to query\n /// @param multiplied Whether the ratio outputted by Chainlink should be multiplied or divided\n /// to the `quoteAmount`\n /// @param decimals Number of decimals of the corresponding Chainlink pair\n /// @return The `quoteAmount` converted in out-currency\n function _readChainlinkFeed(\n uint256 quoteAmount,\n AggregatorV3Interface feed,\n uint8 multiplied,\n uint256 decimals\n ) internal view returns (uint256) {\n (uint80 roundId, int256 ratio, , uint256 updatedAt, uint80 answeredInRound) = feed.latestRoundData();\n if (ratio <= 0 || roundId > answeredInRound || block.timestamp - updatedAt > stalePeriod)\n revert InvalidChainlinkRate();\n uint256 castedRatio = uint256(ratio);\n // Checking whether we should multiply or divide by the ratio computed\n if (multiplied == 1) return (quoteAmount * castedRatio) / (10 ** decimals);\n else return (quoteAmount * (10 ** decimals)) / castedRatio;\n }\n\n // ======================= Governance Related Functions ========================\n\n /// @notice Changes the stale period\n /// @param _stalePeriod New stale period (in seconds)\n function changeStalePeriod(uint32 _stalePeriod) external {\n if (!treasury.isGovernorOrGuardian(msg.sender)) revert NotGovernorOrGuardian();\n stalePeriod = _stalePeriod;\n emit StalePeriodUpdated(_stalePeriod);\n }\n\n /// @inheritdoc IOracle\n function setTreasury(address _treasury) external override {\n if (!treasury.isVaultManager(msg.sender) && !treasury.isGovernor(msg.sender))\n revert NotVaultManagerOrGovernor();\n treasury = ITreasury(_treasury);\n }\n}\n" + }, + "contracts/oracle/BaseOracleChainlinkMultiTwoFeeds.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\nimport \"@chainlink/contracts/src/v0.8/interfaces/AggregatorV3Interface.sol\";\n\nimport \"./BaseOracleChainlinkMulti.sol\";\n\n/// @title BaseOracleChainlinkMultiTwoFeeds\n/// @author Angle Labs, Inc.\n/// @notice Base contract for an oracle that reads into two Chainlink feeds (including an EUR/USD feed) which both have\n/// 8 decimals\nabstract contract BaseOracleChainlinkMultiTwoFeeds is BaseOracleChainlinkMulti {\n constructor(uint32 _stalePeriod, address _treasury) BaseOracleChainlinkMulti(_stalePeriod, _treasury) {}\n\n /// @notice Returns the quote amount of the oracle contract\n function _getQuoteAmount() internal view virtual returns (uint256) {\n return 10 ** 18;\n }\n\n /// @inheritdoc IOracle\n function read() external view virtual override returns (uint256 quoteAmount) {\n quoteAmount = _getQuoteAmount();\n AggregatorV3Interface[] memory _circuitChainlink = circuitChainlink();\n uint8[2] memory circuitChainIsMultiplied = [1, 0];\n uint8[2] memory chainlinkDecimals = [8, 8];\n uint256 circuitLength = _circuitChainlink.length;\n for (uint256 i; i < circuitLength; ++i) {\n quoteAmount = _readChainlinkFeed(\n quoteAmount,\n _circuitChainlink[i],\n circuitChainIsMultiplied[i],\n chainlinkDecimals[i]\n );\n }\n }\n}\n" + }, + "contracts/oracle/BaseOracleChainlinkOneFeed.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\nimport \"@chainlink/contracts/src/v0.8/interfaces/AggregatorV3Interface.sol\";\n\nimport \"./BaseOracleChainlinkMulti.sol\";\n\n/// @title BaseOracleChainlinkOneFeed\n/// @author Angle Labs, Inc.\n/// @notice Base contract for an oracle that reads into one Chainlink feeds with 8 decimals\nabstract contract BaseOracleChainlinkOneFeed is BaseOracleChainlinkMulti {\n constructor(uint32 _stalePeriod, address _treasury) BaseOracleChainlinkMulti(_stalePeriod, _treasury) {}\n\n /// @notice Returns the quote amount of the oracle contract\n function _getQuoteAmount() internal view virtual returns (uint256) {\n return 10 ** 18;\n }\n\n /// @inheritdoc IOracle\n function read() external view virtual override returns (uint256 quoteAmount) {\n AggregatorV3Interface[] memory _circuitChainlink = circuitChainlink();\n quoteAmount = _readChainlinkFeed(_getQuoteAmount(), _circuitChainlink[0], 1, 8);\n }\n}\n" + }, + "contracts/oracle/implementations/arbitrum/EUR/OracleBTCEURChainlinkArbitrum.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\nimport \"@chainlink/contracts/src/v0.8/interfaces/AggregatorV3Interface.sol\";\n\nimport \"../../../BaseOracleChainlinkMultiTwoFeeds.sol\";\n\n/// @title OracleBTCEURChainlinkArbitrum\n/// @author Angle Labs, Inc.\n/// @notice Gives the price of BTC in Euro in base 18\n/// @dev This contract is built to be deployed on Arbitrum\ncontract OracleBTCEURChainlinkArbitrum is BaseOracleChainlinkMultiTwoFeeds {\n string public constant DESCRIPTION = \"BTC/EUR Oracle\";\n\n constructor(uint32 _stalePeriod, address _treasury) BaseOracleChainlinkMultiTwoFeeds(_stalePeriod, _treasury) {}\n\n /// @inheritdoc IOracle\n function circuitChainlink() public pure override returns (AggregatorV3Interface[] memory) {\n AggregatorV3Interface[] memory _circuitChainlink = new AggregatorV3Interface[](2);\n // Oracle BTC/USD\n _circuitChainlink[0] = AggregatorV3Interface(0x6ce185860a4963106506C203335A2910413708e9);\n // Oracle EUR/USD\n _circuitChainlink[1] = AggregatorV3Interface(0xA14d53bC1F1c0F31B4aA3BD109344E5009051a84);\n return _circuitChainlink;\n }\n}\n" + }, + "contracts/oracle/implementations/arbitrum/EUR/OracleETHEURChainlinkArbitrum.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\nimport \"@chainlink/contracts/src/v0.8/interfaces/AggregatorV3Interface.sol\";\n\nimport \"../../../BaseOracleChainlinkMultiTwoFeeds.sol\";\n\n/// @title OracleETHEURChainlinkArbitrum\n/// @author Angle Labs, Inc.\n/// @notice Gives the price of ETH in Euro in base 18\n/// @dev This contract is built to be deployed on Arbitrum\ncontract OracleETHEURChainlinkArbitrum is BaseOracleChainlinkMultiTwoFeeds {\n string public constant DESCRIPTION = \"ETH/EUR Oracle\";\n\n constructor(uint32 _stalePeriod, address _treasury) BaseOracleChainlinkMultiTwoFeeds(_stalePeriod, _treasury) {}\n\n /// @inheritdoc IOracle\n function circuitChainlink() public pure override returns (AggregatorV3Interface[] memory) {\n AggregatorV3Interface[] memory _circuitChainlink = new AggregatorV3Interface[](2);\n // Oracle ETH/USD\n _circuitChainlink[0] = AggregatorV3Interface(0x639Fe6ab55C921f74e7fac1ee960C0B6293ba612);\n // Oracle EUR/USD\n _circuitChainlink[1] = AggregatorV3Interface(0xA14d53bC1F1c0F31B4aA3BD109344E5009051a84);\n return _circuitChainlink;\n }\n}\n" + }, + "contracts/oracle/implementations/arbitrum/EUR/OracleUSDCEURChainlinkArbitrum.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\nimport \"@chainlink/contracts/src/v0.8/interfaces/AggregatorV3Interface.sol\";\n\nimport \"../../../BaseOracleChainlinkMultiTwoFeeds.sol\";\n\n/// @title OracleUSDCEURChainlinkArbitrum\n/// @author Angle Labs, Inc.\n/// @notice Gives the price of USDC in Euro in base 18\n/// @dev This contract is built to be deployed on Arbitrum\ncontract OracleUSDCEURChainlinkArbitrum is BaseOracleChainlinkMultiTwoFeeds {\n string public constant DESCRIPTION = \"USDC/EUR Oracle\";\n\n constructor(uint32 _stalePeriod, address _treasury) BaseOracleChainlinkMultiTwoFeeds(_stalePeriod, _treasury) {}\n\n /// @inheritdoc IOracle\n function circuitChainlink() public pure override returns (AggregatorV3Interface[] memory) {\n AggregatorV3Interface[] memory _circuitChainlink = new AggregatorV3Interface[](2);\n // Oracle ETH/USD\n _circuitChainlink[0] = AggregatorV3Interface(0x50834F3163758fcC1Df9973b6e91f0F0F0434aD3);\n // Oracle EUR/USD\n _circuitChainlink[1] = AggregatorV3Interface(0xA14d53bC1F1c0F31B4aA3BD109344E5009051a84);\n return _circuitChainlink;\n }\n}\n" + }, + "contracts/oracle/implementations/avalanche/EUR/OracleAVAXEURChainlinkAvalanche.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\nimport \"@chainlink/contracts/src/v0.8/interfaces/AggregatorV3Interface.sol\";\n\nimport \"../../../BaseOracleChainlinkMultiTwoFeeds.sol\";\n\n/// @title OracleAVAXEURChainlinkAvalanche\n/// @author Angle Labs, Inc.\n/// @notice Gives the price of AVAX in Euro in base 18\n/// @dev This contract is built to be deployed on Avalanche\ncontract OracleAVAXEURChainlinkAvalanche is BaseOracleChainlinkMultiTwoFeeds {\n string public constant DESCRIPTION = \"AVAX/EUR Oracle\";\n\n constructor(uint32 _stalePeriod, address _treasury) BaseOracleChainlinkMultiTwoFeeds(_stalePeriod, _treasury) {}\n\n /// @inheritdoc IOracle\n function circuitChainlink() public pure override returns (AggregatorV3Interface[] memory) {\n AggregatorV3Interface[] memory _circuitChainlink = new AggregatorV3Interface[](2);\n // Oracle AVAX/USD\n _circuitChainlink[0] = AggregatorV3Interface(0x0A77230d17318075983913bC2145DB16C7366156);\n // Oracle EUR/USD\n _circuitChainlink[1] = AggregatorV3Interface(0x192f2DBA961Bb0277520C082d6bfa87D5961333E);\n return _circuitChainlink;\n }\n}\n" + }, + "contracts/oracle/implementations/avalanche/EUR/OracleUSDCEURChainlinkAvalanche.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\nimport \"@chainlink/contracts/src/v0.8/interfaces/AggregatorV3Interface.sol\";\n\nimport \"../../../BaseOracleChainlinkMultiTwoFeeds.sol\";\n\n/// @title OracleUSDCEURChainlinkAvalanche\n/// @author Angle Labs, Inc.\n/// @notice Gives the price of USDC in Euro in base 18\n/// @dev This contract is built to be deployed on Avalanche\ncontract OracleUSDCEURChainlinkAvalanche is BaseOracleChainlinkMultiTwoFeeds {\n string public constant DESCRIPTION = \"USDC/EUR Oracle\";\n\n constructor(uint32 _stalePeriod, address _treasury) BaseOracleChainlinkMultiTwoFeeds(_stalePeriod, _treasury) {}\n\n /// @inheritdoc IOracle\n function circuitChainlink() public pure override returns (AggregatorV3Interface[] memory) {\n AggregatorV3Interface[] memory _circuitChainlink = new AggregatorV3Interface[](2);\n // Oracle USDC/USD\n _circuitChainlink[0] = AggregatorV3Interface(0xF096872672F44d6EBA71458D74fe67F9a77a23B9);\n // Oracle EUR/USD\n _circuitChainlink[1] = AggregatorV3Interface(0x192f2DBA961Bb0277520C082d6bfa87D5961333E);\n return _circuitChainlink;\n }\n}\n" + }, + "contracts/oracle/implementations/mainnet/EUR/OracleBTCEURChainlink.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\nimport \"@chainlink/contracts/src/v0.8/interfaces/AggregatorV3Interface.sol\";\n\nimport \"../../../BaseOracleChainlinkMultiTwoFeeds.sol\";\n\n/// @title OracleBTCEURChainlink\n/// @author Angle Labs, Inc.\n/// @notice Gives the price of BTC in Euro in base 18\ncontract OracleBTCEURChainlink is BaseOracleChainlinkMultiTwoFeeds {\n string public constant DESCRIPTION = \"BTC/EUR Oracle\";\n\n constructor(uint32 _stalePeriod, address _treasury) BaseOracleChainlinkMultiTwoFeeds(_stalePeriod, _treasury) {}\n\n /// @inheritdoc IOracle\n function circuitChainlink() public pure override returns (AggregatorV3Interface[] memory) {\n AggregatorV3Interface[] memory _circuitChainlink = new AggregatorV3Interface[](2);\n // Oracle BTC/USD\n _circuitChainlink[0] = AggregatorV3Interface(0xF4030086522a5bEEa4988F8cA5B36dbC97BeE88c);\n // Oracle EUR/USD\n _circuitChainlink[1] = AggregatorV3Interface(0xb49f677943BC038e9857d61E7d053CaA2C1734C1);\n return _circuitChainlink;\n }\n}\n" + }, + "contracts/oracle/implementations/mainnet/EUR/OracleCBETHEURChainlink.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\nimport \"@chainlink/contracts/src/v0.8/interfaces/AggregatorV3Interface.sol\";\n\nimport \"../../../BaseOracleChainlinkMultiTwoFeeds.sol\";\n\n/// @title OracleCBETHEURChainlink\n/// @author Angle Labs, Inc.\n/// @notice Gives the price of cbETH in Euro in base 18\ncontract OracleCBETHEURChainlink is BaseOracleChainlinkMultiTwoFeeds {\n string public constant DESCRIPTION = \"cbETH/EUR Oracle\";\n\n constructor(uint32 _stalePeriod, address _treasury) BaseOracleChainlinkMultiTwoFeeds(_stalePeriod, _treasury) {}\n\n /// @inheritdoc IOracle\n function circuitChainlink() public pure override returns (AggregatorV3Interface[] memory) {\n AggregatorV3Interface[] memory _circuitChainlink = new AggregatorV3Interface[](3);\n // Oracle cbETH/ETH\n _circuitChainlink[0] = AggregatorV3Interface(0xF017fcB346A1885194689bA23Eff2fE6fA5C483b);\n // Oracle ETH/USD\n _circuitChainlink[1] = AggregatorV3Interface(0x5f4eC3Df9cbd43714FE2740f5E3616155c5b8419);\n // Oracle EUR/USD\n _circuitChainlink[2] = AggregatorV3Interface(0xb49f677943BC038e9857d61E7d053CaA2C1734C1);\n return _circuitChainlink;\n }\n\n /// @inheritdoc BaseOracleChainlinkMultiTwoFeeds\n function read() external view virtual override returns (uint256 quoteAmount) {\n quoteAmount = _getQuoteAmount();\n AggregatorV3Interface[] memory _circuitChainlink = circuitChainlink();\n uint8[3] memory circuitChainIsMultiplied = [1, 1, 0];\n uint8[3] memory chainlinkDecimals = [18, 8, 8];\n uint256 circuitLength = _circuitChainlink.length;\n for (uint256 i; i < circuitLength; ++i) {\n quoteAmount = _readChainlinkFeed(\n quoteAmount,\n _circuitChainlink[i],\n circuitChainIsMultiplied[i],\n chainlinkDecimals[i]\n );\n }\n }\n}\n" + }, + "contracts/oracle/implementations/mainnet/EUR/OracleETHEURChainlink.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\nimport \"@chainlink/contracts/src/v0.8/interfaces/AggregatorV3Interface.sol\";\n\nimport \"../../../BaseOracleChainlinkMultiTwoFeeds.sol\";\n\n/// @title OracleETHEURChainlink\n/// @author Angle Labs, Inc.\n/// @notice Gives the price of ETH in Euro in base 18\ncontract OracleETHEURChainlink is BaseOracleChainlinkMultiTwoFeeds {\n string public constant DESCRIPTION = \"ETH/EUR Oracle\";\n\n constructor(uint32 _stalePeriod, address _treasury) BaseOracleChainlinkMultiTwoFeeds(_stalePeriod, _treasury) {}\n\n /// @inheritdoc IOracle\n function circuitChainlink() public pure override returns (AggregatorV3Interface[] memory) {\n AggregatorV3Interface[] memory _circuitChainlink = new AggregatorV3Interface[](2);\n // Oracle ETH/USD\n _circuitChainlink[0] = AggregatorV3Interface(0x5f4eC3Df9cbd43714FE2740f5E3616155c5b8419);\n // Oracle EUR/USD\n _circuitChainlink[1] = AggregatorV3Interface(0xb49f677943BC038e9857d61E7d053CaA2C1734C1);\n return _circuitChainlink;\n }\n}\n" + }, + "contracts/oracle/implementations/mainnet/EUR/OracleHIGHEURChainlink.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\nimport \"@chainlink/contracts/src/v0.8/interfaces/AggregatorV3Interface.sol\";\n\nimport \"../../../BaseOracleChainlinkMultiTwoFeeds.sol\";\n\n/// @title OracleHIGHEURChainlink\n/// @author Angle Labs, Inc.\n/// @notice Gives the price of HIGH in Euro in base 18\ncontract OracleHIGHEURChainlink is BaseOracleChainlinkMultiTwoFeeds {\n string public constant DESCRIPTION = \"HIGH/EUR Oracle\";\n\n constructor(uint32 _stalePeriod, address _treasury) BaseOracleChainlinkMultiTwoFeeds(_stalePeriod, _treasury) {}\n\n /// @inheritdoc IOracle\n function circuitChainlink() public pure override returns (AggregatorV3Interface[] memory) {\n AggregatorV3Interface[] memory _circuitChainlink = new AggregatorV3Interface[](1);\n // Oracle HIGH/EUR\n _circuitChainlink[0] = AggregatorV3Interface(0x9E8E794ad6Ecdb6d5c7eaBE059D30E907F58859b);\n return _circuitChainlink;\n }\n\n /// @inheritdoc BaseOracleChainlinkMultiTwoFeeds\n function read() external view override returns (uint256 quoteAmount) {\n quoteAmount = _readChainlinkFeed(_getQuoteAmount(), circuitChainlink()[0], 1, 8);\n }\n}\n" + }, + "contracts/oracle/implementations/mainnet/EUR/OracleIB01EURChainlink.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\nimport \"@chainlink/contracts/src/v0.8/interfaces/AggregatorV3Interface.sol\";\n\nimport \"../../../BaseOracleChainlinkMultiTwoFeeds.sol\";\n\n/// @title OracleIB01EURChainlink\n/// @author Angle Labs, Inc.\n/// @notice Gives the price of IB01 in Euro in base 18\ncontract OracleIB01EURChainlink is BaseOracleChainlinkMultiTwoFeeds {\n string public constant DESCRIPTION = \"IB01/EUR Oracle\";\n\n constructor(uint32 _stalePeriod, address _treasury) BaseOracleChainlinkMultiTwoFeeds(_stalePeriod, _treasury) {}\n\n /// @inheritdoc IOracle\n function circuitChainlink() public pure override returns (AggregatorV3Interface[] memory) {\n AggregatorV3Interface[] memory _circuitChainlink = new AggregatorV3Interface[](2);\n // Oracle IB01/USD\n _circuitChainlink[0] = AggregatorV3Interface(0x32d1463EB53b73C095625719Afa544D5426354cB);\n // Oracle EUR/USD\n _circuitChainlink[1] = AggregatorV3Interface(0xb49f677943BC038e9857d61E7d053CaA2C1734C1);\n return _circuitChainlink;\n }\n}\n" + }, + "contracts/oracle/implementations/mainnet/EUR/OracleLUSDEURChainlink.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\nimport \"@chainlink/contracts/src/v0.8/interfaces/AggregatorV3Interface.sol\";\n\nimport \"../../../BaseOracleChainlinkMultiTwoFeeds.sol\";\n\n/// @title OracleLUSDEURChainlink\n/// @author Angle Labs, Inc.\n/// @notice Gives the price of LUSD in Euro in base 18\ncontract OracleLUSDEURChainlink is BaseOracleChainlinkMultiTwoFeeds {\n string public constant DESCRIPTION = \"LUSD/EUR Oracle\";\n\n constructor(uint32 _stalePeriod, address _treasury) BaseOracleChainlinkMultiTwoFeeds(_stalePeriod, _treasury) {}\n\n /// @inheritdoc IOracle\n function circuitChainlink() public pure override returns (AggregatorV3Interface[] memory) {\n AggregatorV3Interface[] memory _circuitChainlink = new AggregatorV3Interface[](2);\n // Oracle LUSD/USD\n _circuitChainlink[0] = AggregatorV3Interface(0x3D7aE7E594f2f2091Ad8798313450130d0Aba3a0);\n // Oracle EUR/USD\n _circuitChainlink[1] = AggregatorV3Interface(0xb49f677943BC038e9857d61E7d053CaA2C1734C1);\n return _circuitChainlink;\n }\n}\n" + }, + "contracts/oracle/implementations/mainnet/EUR/OracleUSDCEURChainlink.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\nimport \"@chainlink/contracts/src/v0.8/interfaces/AggregatorV3Interface.sol\";\n\nimport \"../../../BaseOracleChainlinkMultiTwoFeeds.sol\";\n\n/// @title OracleUSDCEURChainlink\n/// @author Angle Labs, Inc.\n/// @notice Gives the price of USDC in Euro in base 18\ncontract OracleUSDCEURChainlink is BaseOracleChainlinkMultiTwoFeeds {\n string public constant DESCRIPTION = \"USDC/EUR Oracle\";\n\n constructor(uint32 _stalePeriod, address _treasury) BaseOracleChainlinkMultiTwoFeeds(_stalePeriod, _treasury) {}\n\n /// @inheritdoc IOracle\n function circuitChainlink() public pure override returns (AggregatorV3Interface[] memory) {\n AggregatorV3Interface[] memory _circuitChainlink = new AggregatorV3Interface[](2);\n // Oracle USDC/USD\n _circuitChainlink[0] = AggregatorV3Interface(0x8fFfFfd4AfB6115b954Bd326cbe7B4BA576818f6);\n // Oracle EUR/USD\n _circuitChainlink[1] = AggregatorV3Interface(0xb49f677943BC038e9857d61E7d053CaA2C1734C1);\n return _circuitChainlink;\n }\n}\n" + }, + "contracts/oracle/implementations/mainnet/EUR/OracleWSTETHEURChainlink.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\nimport \"@chainlink/contracts/src/v0.8/interfaces/AggregatorV3Interface.sol\";\n\nimport \"../../../BaseOracleChainlinkMultiTwoFeeds.sol\";\nimport \"../../../../interfaces/external/lido/IStETH.sol\";\n\n/// @title OracleWSTETHEURChainlink\n/// @author Angle Labs, Inc.\n/// @notice Gives the price of wSTETH in Euro in base 18\ncontract OracleWSTETHEURChainlink is BaseOracleChainlinkMultiTwoFeeds {\n string public constant DESCRIPTION = \"wSTETH/EUR Oracle\";\n IStETH public constant STETH = IStETH(0xae7ab96520DE3A18E5e111B5EaAb095312D7fE84);\n\n constructor(uint32 _stalePeriod, address _treasury) BaseOracleChainlinkMultiTwoFeeds(_stalePeriod, _treasury) {}\n\n /// @inheritdoc IOracle\n function circuitChainlink() public pure override returns (AggregatorV3Interface[] memory) {\n AggregatorV3Interface[] memory _circuitChainlink = new AggregatorV3Interface[](2);\n // Oracle stETH/USD\n _circuitChainlink[0] = AggregatorV3Interface(0xCfE54B5cD566aB89272946F602D76Ea879CAb4a8);\n // Oracle EUR/USD\n _circuitChainlink[1] = AggregatorV3Interface(0xb49f677943BC038e9857d61E7d053CaA2C1734C1);\n return _circuitChainlink;\n }\n\n /// @inheritdoc BaseOracleChainlinkMultiTwoFeeds\n function _getQuoteAmount() internal view override returns (uint256) {\n return STETH.getPooledEthByShares(1 ether);\n }\n}\n" + }, + "contracts/oracle/implementations/mainnet/USD/OracleWSTETHUSDChainlink.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\nimport \"@chainlink/contracts/src/v0.8/interfaces/AggregatorV3Interface.sol\";\n\nimport \"../../../BaseOracleChainlinkOneFeed.sol\";\nimport \"../../../../interfaces/external/lido/IStETH.sol\";\n\n/// @title OracleWSTETHUSDChainlink\n/// @author Angle Labs, Inc.\n/// @notice Gives the price of wSTETH in USD in base 18\ncontract OracleWSTETHUSDChainlink is BaseOracleChainlinkOneFeed {\n string public constant DESCRIPTION = \"wSTETH/USD Oracle\";\n IStETH public constant STETH = IStETH(0xae7ab96520DE3A18E5e111B5EaAb095312D7fE84);\n\n constructor(uint32 _stalePeriod, address _treasury) BaseOracleChainlinkOneFeed(_stalePeriod, _treasury) {}\n\n /// @inheritdoc IOracle\n function circuitChainlink() public pure override returns (AggregatorV3Interface[] memory) {\n AggregatorV3Interface[] memory _circuitChainlink = new AggregatorV3Interface[](1);\n // Oracle stETH/USD\n _circuitChainlink[0] = AggregatorV3Interface(0xCfE54B5cD566aB89272946F602D76Ea879CAb4a8);\n return _circuitChainlink;\n }\n\n /// @inheritdoc BaseOracleChainlinkOneFeed\n function _getQuoteAmount() internal view override returns (uint256) {\n return STETH.getPooledEthByShares(1 ether);\n }\n}\n" + }, + "contracts/oracle/implementations/mainnet/XAU/OracleETHXAUChainlink.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\nimport \"@chainlink/contracts/src/v0.8/interfaces/AggregatorV3Interface.sol\";\n\nimport \"../../../BaseOracleChainlinkMultiTwoFeeds.sol\";\n\n/// @title OracleETHXAUChainlink\n/// @author Angle Labs, Inc.\n/// @notice Gives the price of ETH in XAU in base 18\ncontract OracleETHXAUChainlink is BaseOracleChainlinkMultiTwoFeeds {\n string public constant DESCRIPTION = \"ETH/GOLD Oracle\";\n\n constructor(uint32 _stalePeriod, address _treasury) BaseOracleChainlinkMultiTwoFeeds(_stalePeriod, _treasury) {}\n\n /// @inheritdoc IOracle\n function circuitChainlink() public pure override returns (AggregatorV3Interface[] memory) {\n AggregatorV3Interface[] memory _circuitChainlink = new AggregatorV3Interface[](2);\n // Oracle ETH/USD\n _circuitChainlink[0] = AggregatorV3Interface(0x5f4eC3Df9cbd43714FE2740f5E3616155c5b8419);\n // Oracle XAU/USD\n _circuitChainlink[1] = AggregatorV3Interface(0x214eD9Da11D2fbe465a6fc601a91E62EbEc1a0D6);\n return _circuitChainlink;\n }\n}\n" + }, + "contracts/oracle/implementations/mainnet/XAU/OracleLUSDXAUChainlink.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\nimport \"@chainlink/contracts/src/v0.8/interfaces/AggregatorV3Interface.sol\";\n\nimport \"../../../BaseOracleChainlinkMultiTwoFeeds.sol\";\n\n/// @title OracleLUSDXAUChainlink\n/// @author Angle Labs, Inc.\n/// @notice Gives the price of LUSD in XAU in base 18\ncontract OracleLUSDXAUChainlink is BaseOracleChainlinkMultiTwoFeeds {\n string public constant DESCRIPTION = \"LUSD/GOLD Oracle\";\n\n constructor(uint32 _stalePeriod, address _treasury) BaseOracleChainlinkMultiTwoFeeds(_stalePeriod, _treasury) {}\n\n /// @inheritdoc IOracle\n function circuitChainlink() public pure override returns (AggregatorV3Interface[] memory) {\n AggregatorV3Interface[] memory _circuitChainlink = new AggregatorV3Interface[](2);\n // Oracle LUSD/USD\n _circuitChainlink[0] = AggregatorV3Interface(0x3D7aE7E594f2f2091Ad8798313450130d0Aba3a0);\n // Oracle XAU/USD\n _circuitChainlink[1] = AggregatorV3Interface(0x214eD9Da11D2fbe465a6fc601a91E62EbEc1a0D6);\n return _circuitChainlink;\n }\n}\n" + }, + "contracts/oracle/implementations/mainnet/XAU/OracleUSDCXAUChainlink.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\nimport \"@chainlink/contracts/src/v0.8/interfaces/AggregatorV3Interface.sol\";\n\nimport \"../../../BaseOracleChainlinkMultiTwoFeeds.sol\";\n\n/// @title OracleUSDCXAUChainlink\n/// @author Angle Labs, Inc.\n/// @notice Gives the price of USDC in XAU in base 18\ncontract OracleUSDCXAUChainlink is BaseOracleChainlinkMultiTwoFeeds {\n string public constant DESCRIPTION = \"USDC/GOLD Oracle\";\n\n constructor(uint32 _stalePeriod, address _treasury) BaseOracleChainlinkMultiTwoFeeds(_stalePeriod, _treasury) {}\n\n /// @inheritdoc IOracle\n function circuitChainlink() public pure override returns (AggregatorV3Interface[] memory) {\n AggregatorV3Interface[] memory _circuitChainlink = new AggregatorV3Interface[](2);\n // Oracle USDC/USD\n _circuitChainlink[0] = AggregatorV3Interface(0x8fFfFfd4AfB6115b954Bd326cbe7B4BA576818f6);\n // Oracle XAU/USD\n _circuitChainlink[1] = AggregatorV3Interface(0x214eD9Da11D2fbe465a6fc601a91E62EbEc1a0D6);\n return _circuitChainlink;\n }\n}\n" + }, + "contracts/oracle/implementations/mainnet/XAU/OracleWSTETHXAUChainlink.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\nimport \"@chainlink/contracts/src/v0.8/interfaces/AggregatorV3Interface.sol\";\n\nimport \"../../../BaseOracleChainlinkMultiTwoFeeds.sol\";\nimport \"../../../../interfaces/external/lido/IStETH.sol\";\n\n/// @title OracleWSTETHXAUChainlink\n/// @author Angle Labs, Inc.\n/// @notice Gives the price of wSTETH in XAU in base 18\ncontract OracleWSTETHXAUChainlink is BaseOracleChainlinkMultiTwoFeeds {\n string public constant DESCRIPTION = \"wSTETH/XAU Oracle\";\n IStETH public constant STETH = IStETH(0xae7ab96520DE3A18E5e111B5EaAb095312D7fE84);\n\n constructor(uint32 _stalePeriod, address _treasury) BaseOracleChainlinkMultiTwoFeeds(_stalePeriod, _treasury) {}\n\n /// @inheritdoc IOracle\n function circuitChainlink() public pure override returns (AggregatorV3Interface[] memory) {\n AggregatorV3Interface[] memory _circuitChainlink = new AggregatorV3Interface[](2);\n // Oracle stETH/USD\n _circuitChainlink[0] = AggregatorV3Interface(0xCfE54B5cD566aB89272946F602D76Ea879CAb4a8);\n // Oracle XAU/USD\n _circuitChainlink[1] = AggregatorV3Interface(0x214eD9Da11D2fbe465a6fc601a91E62EbEc1a0D6);\n return _circuitChainlink;\n }\n\n /// @inheritdoc BaseOracleChainlinkMultiTwoFeeds\n function _getQuoteAmount() internal view override returns (uint256) {\n return STETH.getPooledEthByShares(1 ether);\n }\n}\n" + }, + "contracts/oracle/implementations/optimism/EUR/OracleETHEURChainlinkOptimism.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\nimport \"@chainlink/contracts/src/v0.8/interfaces/AggregatorV3Interface.sol\";\n\nimport \"../../../BaseOracleChainlinkMultiTwoFeeds.sol\";\n\n/// @title OracleETHEURChainlinkOptimism\n/// @author Angle Labs, Inc.\n/// @notice Gives the price of ETH in Euro in base 18\n/// @dev This contract is built to be deployed on Optimism\ncontract OracleETHEURChainlinkOptimism is BaseOracleChainlinkMultiTwoFeeds {\n string public constant DESCRIPTION = \"ETH/EUR Oracle\";\n\n constructor(uint32 _stalePeriod, address _treasury) BaseOracleChainlinkMultiTwoFeeds(_stalePeriod, _treasury) {}\n\n /// @inheritdoc IOracle\n function circuitChainlink() public pure override returns (AggregatorV3Interface[] memory) {\n AggregatorV3Interface[] memory _circuitChainlink = new AggregatorV3Interface[](2);\n // Oracle ETH/USD\n _circuitChainlink[0] = AggregatorV3Interface(0x13e3Ee699D1909E989722E753853AE30b17e08c5);\n // Oracle EUR/USD\n _circuitChainlink[1] = AggregatorV3Interface(0x3626369857A10CcC6cc3A6e4f5C2f5984a519F20);\n return _circuitChainlink;\n }\n}\n" + }, + "contracts/oracle/implementations/optimism/EUR/OracleOPEURChainlinkOptimism.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\nimport \"@chainlink/contracts/src/v0.8/interfaces/AggregatorV3Interface.sol\";\n\nimport \"../../../BaseOracleChainlinkMultiTwoFeeds.sol\";\n\n/// @title OracleOPEURChainlinkOptimism\n/// @author Angle Labs, Inc.\n/// @notice Gives the price of OP in Euro in base 18\n/// @dev This contract is built to be deployed on Optimism\ncontract OracleOPEURChainlinkOptimism is BaseOracleChainlinkMultiTwoFeeds {\n string public constant DESCRIPTION = \"OP/EUR Oracle\";\n\n constructor(uint32 _stalePeriod, address _treasury) BaseOracleChainlinkMultiTwoFeeds(_stalePeriod, _treasury) {}\n\n /// @inheritdoc IOracle\n function circuitChainlink() public pure override returns (AggregatorV3Interface[] memory) {\n AggregatorV3Interface[] memory _circuitChainlink = new AggregatorV3Interface[](2);\n // Oracle OP/USD\n _circuitChainlink[0] = AggregatorV3Interface(0x0D276FC14719f9292D5C1eA2198673d1f4269246);\n // Oracle EUR/USD\n _circuitChainlink[1] = AggregatorV3Interface(0x3626369857A10CcC6cc3A6e4f5C2f5984a519F20);\n return _circuitChainlink;\n }\n}\n" + }, + "contracts/oracle/implementations/optimism/EUR/OracleUSDCEURChainlinkOptimism.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\nimport \"@chainlink/contracts/src/v0.8/interfaces/AggregatorV3Interface.sol\";\n\nimport \"../../../BaseOracleChainlinkMultiTwoFeeds.sol\";\n\n/// @title OracleUSDCEURChainlinkOptimism\n/// @author Angle Labs, Inc.\n/// @notice Gives the price of USDC in Euro in base 18\n/// @dev This contract is built to be deployed on Optimism\ncontract OracleUSDCEURChainlinkOptimism is BaseOracleChainlinkMultiTwoFeeds {\n string public constant DESCRIPTION = \"USDC/EUR Oracle\";\n\n constructor(uint32 _stalePeriod, address _treasury) BaseOracleChainlinkMultiTwoFeeds(_stalePeriod, _treasury) {}\n\n /// @inheritdoc IOracle\n function circuitChainlink() public pure override returns (AggregatorV3Interface[] memory) {\n AggregatorV3Interface[] memory _circuitChainlink = new AggregatorV3Interface[](2);\n // Oracle USDC/USD\n _circuitChainlink[0] = AggregatorV3Interface(0x16a9FA2FDa030272Ce99B29CF780dFA30361E0f3);\n // Oracle EUR/USD\n _circuitChainlink[1] = AggregatorV3Interface(0x3626369857A10CcC6cc3A6e4f5C2f5984a519F20);\n return _circuitChainlink;\n }\n}\n" + }, + "contracts/oracle/implementations/polygon/EUR/OracleBTCEURChainlinkPolygon.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\nimport \"@chainlink/contracts/src/v0.8/interfaces/AggregatorV3Interface.sol\";\n\nimport \"../../../BaseOracleChainlinkMultiTwoFeeds.sol\";\n\n/// @title OracleBTCEURChainlinkPolygon\n/// @author Angle Labs, Inc.\n/// @notice Gives the price of BTC in Euro in base 18\n/// @dev This contract is built to be deployed on Polygon\ncontract OracleBTCEURChainlinkPolygon is BaseOracleChainlinkMultiTwoFeeds {\n string public constant DESCRIPTION = \"BTC/EUR Oracle\";\n\n constructor(uint32 _stalePeriod, address _treasury) BaseOracleChainlinkMultiTwoFeeds(_stalePeriod, _treasury) {}\n\n /// @inheritdoc IOracle\n function circuitChainlink() public pure override returns (AggregatorV3Interface[] memory) {\n AggregatorV3Interface[] memory _circuitChainlink = new AggregatorV3Interface[](2);\n // Oracle BTC/USD\n _circuitChainlink[0] = AggregatorV3Interface(0xc907E116054Ad103354f2D350FD2514433D57F6f);\n // Oracle EUR/USD\n _circuitChainlink[1] = AggregatorV3Interface(0x73366Fe0AA0Ded304479862808e02506FE556a98);\n return _circuitChainlink;\n }\n}\n" + }, + "contracts/oracle/implementations/polygon/EUR/OracleETHEURChainlinkPolygon.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\nimport \"@chainlink/contracts/src/v0.8/interfaces/AggregatorV3Interface.sol\";\n\nimport \"../../../BaseOracleChainlinkMultiTwoFeeds.sol\";\n\n/// @title OracleETHEURChainlinkPolygon\n/// @author Angle Labs, Inc.\n/// @notice Gives the price of ETH in Euro in base 18\n/// @dev This contract is built to be deployed on Polygon\ncontract OracleETHEURChainlinkPolygon is BaseOracleChainlinkMultiTwoFeeds {\n string public constant DESCRIPTION = \"ETH/EUR Oracle\";\n\n constructor(uint32 _stalePeriod, address _treasury) BaseOracleChainlinkMultiTwoFeeds(_stalePeriod, _treasury) {}\n\n /// @inheritdoc IOracle\n function circuitChainlink() public pure override returns (AggregatorV3Interface[] memory) {\n AggregatorV3Interface[] memory _circuitChainlink = new AggregatorV3Interface[](2);\n // Oracle ETH/USD\n _circuitChainlink[0] = AggregatorV3Interface(0xF9680D99D6C9589e2a93a78A04A279e509205945);\n // Oracle EUR/USD\n _circuitChainlink[1] = AggregatorV3Interface(0x73366Fe0AA0Ded304479862808e02506FE556a98);\n return _circuitChainlink;\n }\n}\n" + }, + "contracts/oracle/implementations/polygon/EUR/OracleMAIEURChainlinkPolygon.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\nimport \"@chainlink/contracts/src/v0.8/interfaces/AggregatorV3Interface.sol\";\n\nimport \"../../../BaseOracleChainlinkMultiTwoFeeds.sol\";\n\n/// @title OracleMAIEURChainlinkPolygon\n/// @author Angle Labs, Inc.\n/// @notice Gives the price of MAI in Euro in base 18\n/// @dev This contract is built to be deployed on Polygon\ncontract OracleMAIEURChainlinkPolygon is BaseOracleChainlinkMultiTwoFeeds {\n string public constant DESCRIPTION = \"MAI/EUR Oracle\";\n\n constructor(uint32 _stalePeriod, address _treasury) BaseOracleChainlinkMultiTwoFeeds(_stalePeriod, _treasury) {}\n\n /// @inheritdoc IOracle\n function circuitChainlink() public pure override returns (AggregatorV3Interface[] memory) {\n AggregatorV3Interface[] memory _circuitChainlink = new AggregatorV3Interface[](2);\n // Oracle MAI/USD\n _circuitChainlink[0] = AggregatorV3Interface(0xd8d483d813547CfB624b8Dc33a00F2fcbCd2D428);\n // Oracle EUR/USD\n _circuitChainlink[1] = AggregatorV3Interface(0x73366Fe0AA0Ded304479862808e02506FE556a98);\n return _circuitChainlink;\n }\n}\n" + }, + "contracts/oracle/implementations/polygon/EUR/OracleMATICEURChainlinkPolygon.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\nimport \"@chainlink/contracts/src/v0.8/interfaces/AggregatorV3Interface.sol\";\n\nimport \"../../../BaseOracleChainlinkMultiTwoFeeds.sol\";\n\n/// @title OracleMATICEURChainlinkPolygon\n/// @author Angle Labs, Inc.\n/// @notice Gives the price of MATIC in Euro in base 18\n/// @dev This contract is built to be deployed on Polygon\ncontract OracleMATICEURChainlinkPolygon is BaseOracleChainlinkMultiTwoFeeds {\n string public constant DESCRIPTION = \"MATIC/EUR Oracle\";\n\n constructor(uint32 _stalePeriod, address _treasury) BaseOracleChainlinkMultiTwoFeeds(_stalePeriod, _treasury) {}\n\n /// @inheritdoc IOracle\n function circuitChainlink() public pure override returns (AggregatorV3Interface[] memory) {\n AggregatorV3Interface[] memory _circuitChainlink = new AggregatorV3Interface[](2);\n // Oracle MATIC/USD\n _circuitChainlink[0] = AggregatorV3Interface(0xAB594600376Ec9fD91F8e885dADF0CE036862dE0);\n // Oracle EUR/USD\n _circuitChainlink[1] = AggregatorV3Interface(0x73366Fe0AA0Ded304479862808e02506FE556a98);\n return _circuitChainlink;\n }\n}\n" + }, + "contracts/oracle/implementations/polygon/EUR/OracleUSDCEURChainlinkPolygon.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\nimport \"../../../BaseOracleChainlinkMultiTwoFeeds.sol\";\n\n/// @title OracleUSDCEURChainlinkPolygon\n/// @author Angle Labs, Inc.\n/// @notice Gives the price of USDC in Euro in base 18\n/// @dev This contract is built to be deployed on Polygon\ncontract OracleUSDCEURChainlinkPolygon is BaseOracleChainlinkMultiTwoFeeds {\n string public constant DESCRIPTION = \"USDC/EUR Oracle\";\n\n constructor(uint32 _stalePeriod, address _treasury) BaseOracleChainlinkMultiTwoFeeds(_stalePeriod, _treasury) {}\n\n /// @inheritdoc IOracle\n function circuitChainlink() public pure override returns (AggregatorV3Interface[] memory) {\n AggregatorV3Interface[] memory _circuitChainlink = new AggregatorV3Interface[](2);\n // Oracle USDC/USD\n _circuitChainlink[0] = AggregatorV3Interface(0xfE4A8cc5b5B2366C1B58Bea3858e81843581b2F7);\n // Oracle EUR/USD\n _circuitChainlink[1] = AggregatorV3Interface(0x73366Fe0AA0Ded304479862808e02506FE556a98);\n return _circuitChainlink;\n }\n}\n" + }, + "contracts/oracle/implementations/polygon/XAU/OracleETHXAUChainlinkPolygon.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\nimport \"@chainlink/contracts/src/v0.8/interfaces/AggregatorV3Interface.sol\";\n\nimport \"../../../BaseOracleChainlinkMultiTwoFeeds.sol\";\n\n/// @title OracleETHXAUChainlinkPolygon\n/// @author Angle Labs, Inc.\n/// @notice Gives the price of ETH in XAU in base 18\n/// @dev This contract is built to be deployed on Polygon\ncontract OracleETHXAUChainlinkPolygon is BaseOracleChainlinkMultiTwoFeeds {\n string public constant DESCRIPTION = \"ETH/GOLD Oracle\";\n\n constructor(uint32 _stalePeriod, address _treasury) BaseOracleChainlinkMultiTwoFeeds(_stalePeriod, _treasury) {}\n\n /// @inheritdoc IOracle\n function circuitChainlink() public pure override returns (AggregatorV3Interface[] memory) {\n AggregatorV3Interface[] memory _circuitChainlink = new AggregatorV3Interface[](2);\n // Oracle ETH/USD\n _circuitChainlink[0] = AggregatorV3Interface(0xF9680D99D6C9589e2a93a78A04A279e509205945);\n // Oracle XAU/USD\n _circuitChainlink[1] = AggregatorV3Interface(0x0C466540B2ee1a31b441671eac0ca886e051E410);\n return _circuitChainlink;\n }\n}\n" + }, + "contracts/oracle/KeeperRegistry.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\nimport \"@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol\";\nimport \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\nimport \"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\";\n\nimport \"../interfaces/ICoreBorrow.sol\";\nimport \"../interfaces/IKeeperRegistry.sol\";\n\n/// @title KeeperRegistry\n/// @notice Maintains a mapping of keepers authorized to use the core module just after oracle updates\n/// @author Angle Labs, Inc.\ncontract KeeperRegistry is Initializable, IKeeperRegistry {\n using SafeERC20 for IERC20;\n\n /// @notice Contract handling access control\n ICoreBorrow public coreBorrow;\n\n /// @notice Trusted EOAs - needs to be tx.origin\n mapping(address => uint256) public trusted;\n\n uint256[48] private __gap;\n\n // =================================== EVENTS ==================================\n\n event TrustedToggled(address indexed wallet, bool trust);\n\n // =================================== ERRORS ==================================\n\n error NotGovernorOrGuardian();\n error NotTrusted();\n error ZeroAddress();\n\n // ================================= MODIFIERS =================================\n\n /// @notice Checks whether the `msg.sender` has the governor role or the guardian role\n modifier onlyGovernorOrGuardian() {\n if (!coreBorrow.isGovernorOrGuardian(msg.sender)) revert NotGovernorOrGuardian();\n _;\n }\n\n // ================================ CONSTRUCTOR ================================\n\n constructor() initializer {}\n\n function initialize(ICoreBorrow _coreBorrow) public initializer {\n if (address(_coreBorrow) == address(0)) revert ZeroAddress();\n coreBorrow = _coreBorrow;\n }\n\n // =============================== MAIN FUNCTIONS ==============================\n\n /// @notice Adds or removes a trusted keeper bot\n function toggleTrusted(address eoa) external onlyGovernorOrGuardian {\n uint256 trustedStatus = 1 - trusted[eoa];\n trusted[eoa] = trustedStatus;\n emit TrustedToggled(eoa, trustedStatus == 1);\n }\n\n /// @inheritdoc IKeeperRegistry\n function isTrusted(address caller) external view returns (bool) {\n return trusted[caller] == 1;\n }\n}\n" + }, + "contracts/oracle/OracleChainlinkMulti.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\nimport \"@chainlink/contracts/src/v0.8/interfaces/AggregatorV3Interface.sol\";\n\nimport \"./BaseOracleChainlinkMulti.sol\";\n\n/// @title OracleChainlinkMulti\n/// @author Angle Labs, Inc.\n/// @notice Oracle contract, one contract is deployed per collateral/stablecoin pair\n/// @dev This contract concerns an oracle that uses Chainlink with multiple pools to read from\n/// @dev Typically we expect to use this contract to read like the ETH/USD and then USD/EUR feed\ncontract OracleChainlinkMulti is BaseOracleChainlinkMulti {\n // ========================= Parameters and References =========================\n\n /// @notice Chainlink pools, the order of the pools has to be the order in which they are read for the computation\n /// of the price\n AggregatorV3Interface[] internal _circuitChainlink;\n /// @notice Whether each rate for the pairs in `circuitChainlink` should be multiplied or divided\n uint8[] public circuitChainIsMultiplied;\n /// @notice Decimals for each Chainlink pairs\n uint8[] public chainlinkDecimals;\n /// @notice Unit of the stablecoin\n uint256 public immutable outBase;\n /// @notice Description of the assets concerned by the oracle and the price outputted\n string public description;\n\n // ===================================== Error =================================\n\n error IncompatibleLengths();\n\n /// @notice Constructor for an oracle using Chainlink with multiple pools to read from\n /// @param circuitChainlink_ Chainlink pool addresses (in order)\n /// @param _circuitChainIsMultiplied Whether we should multiply or divide by this rate\n /// @param _outBase Unit of the stablecoin (or the out asset) associated to the oracle\n /// @param _stalePeriod Minimum feed update frequency for the oracle to not revert\n /// @param _treasury Treasury associated to the VaultManager which reads from this feed\n /// @param _description Description of the assets concerned by the oracle\n /// @dev For instance, if this oracle is supposed to give the price of ETH in EUR, and if the agEUR\n /// stablecoin associated to EUR has 18 decimals, then `outBase` should be 10**18\n constructor(\n address[] memory circuitChainlink_,\n uint8[] memory _circuitChainIsMultiplied,\n uint256 _outBase,\n uint32 _stalePeriod,\n address _treasury,\n string memory _description\n ) BaseOracleChainlinkMulti(_stalePeriod, _treasury) {\n outBase = _outBase;\n description = _description;\n uint256 circuitLength = circuitChainlink_.length;\n if (circuitLength == 0 || circuitLength != _circuitChainIsMultiplied.length) revert IncompatibleLengths();\n for (uint256 i; i < circuitLength; ++i) {\n AggregatorV3Interface _pool = AggregatorV3Interface(circuitChainlink_[i]);\n _circuitChainlink.push(_pool);\n chainlinkDecimals.push(_pool.decimals());\n }\n circuitChainIsMultiplied = _circuitChainIsMultiplied;\n }\n\n // ============================= Reading Oracles ===============================\n\n /// @inheritdoc IOracle\n function circuitChainlink() public view override returns (AggregatorV3Interface[] memory) {\n return _circuitChainlink;\n }\n\n /// @inheritdoc IOracle\n function read() external view override returns (uint256 quoteAmount) {\n quoteAmount = outBase;\n uint256 circuitLength = _circuitChainlink.length;\n for (uint256 i; i < circuitLength; ++i) {\n quoteAmount = _readChainlinkFeed(\n quoteAmount,\n _circuitChainlink[i],\n circuitChainIsMultiplied[i],\n chainlinkDecimals[i]\n );\n }\n }\n}\n" + }, + "contracts/settlement/Settlement.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\nimport \"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\";\nimport \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\nimport \"@openzeppelin/contracts/token/ERC20/extensions/IERC20Metadata.sol\";\n\nimport \"../interfaces/IAgToken.sol\";\nimport \"../interfaces/ISwapper.sol\";\nimport \"../interfaces/IVaultManager.sol\";\n\n/// @title Settlement\n/// @author Angle Labs, Inc.\n/// @notice Settlement Contract for a VaultManager\n/// @dev This settlement contract should be activated by a careful governance which needs to have performed\n/// some key operations before activating this contract\n/// @dev In case of global settlement, there should be one settlement contract per `VaultManager`\ncontract Settlement {\n using SafeERC20 for IERC20;\n\n /// @notice Base used for parameter computation\n uint256 public constant BASE_PARAMS = 10 ** 9;\n /// @notice Base used for interest computation\n uint256 public constant BASE_INTEREST = 10 ** 27;\n /// @notice Base used for exchange rate computation. It is assumed\n /// that stablecoins have this base\n uint256 public constant BASE_STABLECOIN = 10 ** 18;\n /// @notice Duration of the claim period for over-collateralized vaults\n uint256 public constant OVER_COLLATERALIZED_CLAIM_DURATION = 3 * 24 * 3600;\n\n // =============== Immutable references set in the constructor =================\n\n /// @notice `VaultManager` of this settlement contract\n IVaultManager public immutable vaultManager;\n /// @notice Reference to the stablecoin supported by the `VaultManager` contract\n IAgToken public immutable stablecoin;\n /// @notice Reference to the collateral supported by the `VaultManager`\n IERC20 public immutable collateral;\n /// @notice Base of the collateral\n uint256 internal immutable _collatBase;\n\n // ================ Variables frozen at settlement activation ==================\n\n /// @notice Value of the oracle for the collateral/stablecoin pair\n uint256 public oracleValue;\n /// @notice Value of the interest accumulator at settlement activation\n uint256 public interestAccumulator;\n /// @notice Timestamp at which settlement was activated\n uint256 public activationTimestamp;\n /// @notice Collateral factor of the `VaultManager`\n uint64 public collateralFactor;\n\n // =================== Variables updated during the process ====================\n\n /// @notice How much collateral you can get from stablecoins\n uint256 public collateralStablecoinExchangeRate;\n /// @notice Amount of collateral that will be left over at the end of the process\n uint256 public leftOverCollateral;\n /// @notice Whether the `collateralStablecoinExchangeRate` has been computed\n bool public exchangeRateComputed;\n /// @notice Maps a vault to 1 if it was claimed by its owner\n mapping(uint256 => uint256) public vaultCheck;\n\n // ================================ Events =====================================\n\n event GlobalClaimPeriodActivated(uint256 _collateralStablecoinExchangeRate);\n event Recovered(address indexed tokenAddress, address indexed to, uint256 amount);\n event SettlementActivated(uint256 startTimestamp);\n event VaultClaimed(uint256 vaultID, uint256 stablecoinAmount, uint256 collateralAmount);\n\n // ================================ Errors =====================================\n\n error GlobalClaimPeriodNotStarted();\n error InsolventVault();\n error NotGovernor();\n error NotOwner();\n error RestrictedClaimPeriodNotEnded();\n error SettlementNotInitialized();\n error VaultAlreadyClaimed();\n\n /// @notice Constructor of the contract\n /// @param _vaultManager Address of the `VaultManager` associated to this `Settlement` contract\n /// @dev Out of safety, this constructor reads values from the `VaultManager` contract directly\n constructor(IVaultManager _vaultManager) {\n vaultManager = _vaultManager;\n stablecoin = _vaultManager.stablecoin();\n collateral = _vaultManager.collateral();\n _collatBase = 10 ** (IERC20Metadata(address(collateral)).decimals());\n }\n\n /// @notice Checks whether the `msg.sender` has the governor role or not\n modifier onlyGovernor() {\n if (!(vaultManager.treasury().isGovernor(msg.sender))) revert NotGovernor();\n _;\n }\n\n /// @notice Activates the settlement contract\n /// @dev When calling this function governance should make sure to have:\n /// 1. Accrued the interest rate on the contract\n /// 2. Paused the contract\n /// 3. Recovered all the collateral available in the `VaultManager` contract either\n /// by doing a contract upgrade or by calling a `recoverERC20` method if supported\n function activateSettlement() external onlyGovernor {\n oracleValue = (vaultManager.oracle()).read();\n interestAccumulator = vaultManager.interestAccumulator();\n activationTimestamp = block.timestamp;\n collateralFactor = vaultManager.collateralFactor();\n emit SettlementActivated(block.timestamp);\n }\n\n /// @notice Allows the owner of an over-collateralized vault to claim its collateral upon bringing back all owed stablecoins\n /// @param vaultID ID of the vault to claim\n /// @param to Address to which collateral should be sent\n /// @param who Address which should be notified if needed of the transfer of stablecoins and collateral\n /// @param data Data to pass to the `who` contract for it to successfully give the correct amount of stablecoins\n /// to the `msg.sender` address\n /// @return Amount of collateral sent to the `to` address\n /// @return Amount of stablecoins sent to the contract\n /// @dev Claiming can only happen short after settlement activation\n /// @dev A vault cannot be claimed twice and only the owner of the vault can claim it (regardless of the approval logic)\n /// @dev Only over-collateralized vaults can be claimed from this medium\n function claimOverCollateralizedVault(\n uint256 vaultID,\n address to,\n address who,\n bytes memory data\n ) external returns (uint256, uint256) {\n if (activationTimestamp == 0 || block.timestamp > activationTimestamp + OVER_COLLATERALIZED_CLAIM_DURATION)\n revert SettlementNotInitialized();\n if (vaultCheck[vaultID] == 1) revert VaultAlreadyClaimed();\n if (vaultManager.ownerOf(vaultID) != msg.sender) revert NotOwner();\n (uint256 collateralAmount, uint256 normalizedDebt) = vaultManager.vaultData(vaultID);\n uint256 vaultDebt = (normalizedDebt * interestAccumulator) / BASE_INTEREST;\n if (collateralAmount * oracleValue * collateralFactor < vaultDebt * BASE_PARAMS * _collatBase)\n revert InsolventVault();\n vaultCheck[vaultID] = 1;\n emit VaultClaimed(vaultID, vaultDebt, collateralAmount);\n return _handleRepay(collateralAmount, vaultDebt, to, who, data);\n }\n\n /// @notice Activates the global claim period by setting the `collateralStablecoinExchangeRate` which is going to\n /// dictate how much of collateral will be recoverable for each stablecoin\n /// @dev This function can only be called by the governor in order to allow it in case multiple settlements happen across\n /// different `VaultManager` to rebalance the amount of stablecoins on each to make sure that across all settlement contracts\n /// a similar value of collateral can be obtained against a similar value of stablecoins\n function activateGlobalClaimPeriod() external onlyGovernor {\n if (activationTimestamp == 0 || block.timestamp <= activationTimestamp + OVER_COLLATERALIZED_CLAIM_DURATION)\n revert RestrictedClaimPeriodNotEnded();\n uint256 collateralBalance = collateral.balanceOf(address(this));\n uint256 leftOverDebt = (vaultManager.totalNormalizedDebt() * interestAccumulator) / BASE_INTEREST;\n uint256 stablecoinBalance = stablecoin.balanceOf(address(this));\n // How much 1 of stablecoin will give you in collateral\n uint256 _collateralStablecoinExchangeRate;\n\n if (stablecoinBalance < leftOverDebt) {\n // The left over debt is the total debt minus the stablecoins which have already been accumulated\n // in the first phase\n leftOverDebt -= stablecoinBalance;\n // If you control all the debt, then you are entitled to get all the collateral left in the protocol\n _collateralStablecoinExchangeRate = (collateralBalance * BASE_STABLECOIN) / leftOverDebt;\n // But at the same time, you cannot get more collateral than the value of the stablecoins you brought\n uint256 maxExchangeRate = (BASE_STABLECOIN * _collatBase) / oracleValue;\n if (_collateralStablecoinExchangeRate >= maxExchangeRate) {\n // In this situation, we're sure that `leftOverCollateral` will be positive: governance should be wary\n // to call `recoverERC20` short after though as there's nothing that is going to prevent people to redeem\n // more stablecoins than the `leftOverDebt`\n leftOverCollateral = collateralBalance - (leftOverDebt * _collatBase) / oracleValue;\n _collateralStablecoinExchangeRate = maxExchangeRate;\n }\n }\n exchangeRateComputed = true;\n // In the else case where there is no debt left, you cannot get anything from your stablecoins\n // and so the `collateralStablecoinExchangeRate` is null\n collateralStablecoinExchangeRate = _collateralStablecoinExchangeRate;\n emit GlobalClaimPeriodActivated(_collateralStablecoinExchangeRate);\n }\n\n /// @notice Allows to claim collateral from stablecoins\n /// @param to Address to which collateral should be sent\n /// @param who Address which should be notified if needed of the transfer of stablecoins and collateral\n /// @param data Data to pass to the `who` contract for it to successfully give the correct amount of stablecoins\n /// to the `msg.sender` address\n /// @return Amount of collateral sent to the `to` address\n /// @return Amount of stablecoins sent to the contract\n /// @dev This function reverts if the `collateralStablecoinExchangeRate` is null and hence if the global claim period has\n /// not been activated\n function claimCollateralFromStablecoins(\n uint256 stablecoinAmount,\n address to,\n address who,\n bytes memory data\n ) external returns (uint256, uint256) {\n if (!exchangeRateComputed) revert GlobalClaimPeriodNotStarted();\n return\n _handleRepay(\n (stablecoinAmount * collateralStablecoinExchangeRate) / BASE_STABLECOIN,\n stablecoinAmount,\n to,\n who,\n data\n );\n }\n\n /// @notice Handles the simultaneous repayment of stablecoins with a transfer of collateral\n /// @param collateralAmountToGive Amount of collateral the contract should give\n /// @param stableAmountToRepay Amount of stablecoins the contract should burn from the call\n /// @param to Address to which stablecoins should be sent\n /// @param who Address which should be notified if needed of the transfer\n /// @param data Data to pass to the `who` contract for it to successfully give the correct amount of stablecoins\n /// to the `msg.sender` address\n /// @dev This function allows for capital-efficient claims of collateral from stablecoins\n function _handleRepay(\n uint256 collateralAmountToGive,\n uint256 stableAmountToRepay,\n address to,\n address who,\n bytes memory data\n ) internal returns (uint256, uint256) {\n collateral.safeTransfer(to, collateralAmountToGive);\n if (data.length != 0) {\n ISwapper(who).swap(\n collateral,\n IERC20(address(stablecoin)),\n msg.sender,\n stableAmountToRepay,\n collateralAmountToGive,\n data\n );\n }\n stablecoin.transferFrom(msg.sender, address(this), stableAmountToRepay);\n return (collateralAmountToGive, stableAmountToRepay);\n }\n\n /// @notice Recovers leftover tokens from the contract or tokens that were mistakenly sent to the contract\n /// @param tokenAddress Address of the token to recover\n /// @param to Address to send the remaining tokens to\n /// @param amountToRecover Amount to recover from the contract\n /// @dev Governors cannot recover more collateral than what would be leftover from the contract\n /// @dev This function can be used to rebalance stablecoin balances across different settlement contracts\n /// to make sure every stablecoin can be redeemed for the same value of collateral\n /// @dev It can also be used to recover tokens that are mistakenly sent to this contract\n function recoverERC20(address tokenAddress, address to, uint256 amountToRecover) external onlyGovernor {\n if (tokenAddress == address(collateral)) {\n if (!exchangeRateComputed) revert GlobalClaimPeriodNotStarted();\n leftOverCollateral -= amountToRecover;\n collateral.safeTransfer(to, amountToRecover);\n } else {\n IERC20(tokenAddress).safeTransfer(to, amountToRecover);\n }\n emit Recovered(tokenAddress, to, amountToRecover);\n }\n}\n" + }, + "contracts/swapper/Swapper.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\n/*\n * █ \n ***** ▓▓▓ \n * ▓▓▓▓▓▓▓ \n * ///. ▓▓▓▓▓▓▓▓▓▓▓▓▓ \n ***** //////// ▓▓▓▓▓▓▓ \n * ///////////// ▓▓▓ \n ▓▓ ////////////////// █ ▓▓ \n ▓▓ ▓▓ /////////////////////// ▓▓ ▓▓ \n ▓▓ ▓▓ //////////////////////////// ▓▓ ▓▓ \n ▓▓ ▓▓ /////////▓▓▓///////▓▓▓///////// ▓▓ ▓▓ \n ▓▓ ,////////////////////////////////////// ▓▓ ▓▓ \n ▓▓ ////////////////////////////////////////// ▓▓ \n ▓▓ //////////////////////▓▓▓▓///////////////////// \n ,//////////////////////////////////////////////////// \n .////////////////////////////////////////////////////////// \n .//////////////////////////██.,//////////////////////////█ \n .//////////////////////████..,./////////////////////██ \n ...////////////////███████.....,.////////////////███ \n ,.,////////////████████ ........,///////////████ \n .,.,//////█████████ ,.......///////████ \n ,..//████████ ........./████ \n ..,██████ .....,███ \n .██ ,.,█ \n \n \n \n ▓▓ ▓▓▓▓▓▓▓▓▓▓ ▓▓▓▓▓▓▓▓▓▓ ▓▓ ▓▓▓▓▓▓▓▓▓▓ \n ▓▓▓▓▓▓ ▓▓▓ ▓▓▓ ▓▓▓ ▓▓ ▓▓ ▓▓▓▓ \n ▓▓▓ ▓▓▓ ▓▓▓ ▓▓▓ ▓▓▓ ▓▓▓ ▓▓ ▓▓▓▓▓ \n ▓▓▓ ▓▓ ▓▓▓ ▓▓▓ ▓▓▓▓▓▓▓▓▓▓ ▓▓▓▓▓▓▓▓▓▓ ▓▓▓▓▓▓▓▓▓▓ \n*/\n\npragma solidity ^0.8.12;\n\nimport \"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\";\nimport \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\n\nimport \"../interfaces/IAngleRouterSidechain.sol\";\nimport \"../interfaces/ICoreBorrow.sol\";\nimport \"../interfaces/ISwapper.sol\";\nimport \"../interfaces/external/lido/IWStETH.sol\";\nimport \"../interfaces/external/uniswap/IUniswapRouter.sol\";\n\n// ==================================== ENUM ===================================\n\n/// @notice All possible swaps\nenum SwapType {\n UniswapV3,\n oneInch,\n AngleRouter,\n Leverage,\n None\n}\n\n/// @title Swapper\n/// @author Angle Labs, Inc.\n/// @notice Swapper contract facilitating interactions with Angle VaultManager contracts, notably\n/// liquidation and leverage transactions\ncontract Swapper is ISwapper {\n using SafeERC20 for IERC20;\n\n // ===================== CONSTANTS AND IMMUTABLE VARIABLES =====================\n\n /// @notice Reference to the `CoreBorrow` contract of the module which handles all AccessControl logic\n ICoreBorrow public immutable core;\n /// @notice Uniswap Router contract\n IUniswapV3Router public immutable uniV3Router;\n /// @notice 1inch Router\n address public immutable oneInch;\n /// @notice AngleRouter\n IAngleRouterSidechain public immutable angleRouter;\n\n // =================================== ERRORS ==================================\n\n error EmptyReturnMessage();\n error IncompatibleLengths();\n error NotGovernorOrGuardian();\n error TooSmallAmountOut();\n error ZeroAddress();\n\n /// @notice Constructor of the contract\n /// @param _core Core address\n /// @param _uniV3Router UniswapV3 Router address\n /// @param _oneInch 1inch Router address\n /// @param _angleRouter AngleRouter contract address\n constructor(\n ICoreBorrow _core,\n IUniswapV3Router _uniV3Router,\n address _oneInch,\n IAngleRouterSidechain _angleRouter\n ) {\n if (address(_core) == address(0) || _oneInch == address(0) || address(_angleRouter) == address(0))\n revert ZeroAddress();\n core = _core;\n uniV3Router = _uniV3Router;\n oneInch = _oneInch;\n angleRouter = _angleRouter;\n }\n\n // ========================= EXTERNAL ACCESS FUNCTIONS =========================\n\n /// @inheritdoc ISwapper\n /// @dev This function swaps the `inToken` to the `outToken` by doing a UniV3 swap, a 1inch swap or by interacting\n /// with the `AngleRouter` contract\n /// @dev One slippage check is performed at the end of the call\n /// @dev In this implementation, the function tries to make sure that the `outTokenRecipient` address has at the end\n /// of the call `outTokenOwed`, leftover tokens are sent to a `to` address which by default is the `outTokenRecipient`\n function swap(\n IERC20 inToken,\n IERC20 outToken,\n address outTokenRecipient,\n uint256 outTokenOwed,\n uint256 inTokenObtained,\n bytes memory data\n ) external {\n // Address to receive the surplus amount of token at the end of the call\n address to;\n // For slippage protection, it is checked at the end of the call\n uint256 minAmountOut;\n // Type of the swap to execute: if `swapType == 4`, then it is optional to swap\n uint256 swapType;\n // We're reusing the `data` variable (it can be `path` on UniswapV3, a payload for 1inch or like encoded actions\n // for a router call)\n (to, minAmountOut, swapType, data) = abi.decode(data, (address, uint256, uint256, bytes));\n\n to = (to == address(0)) ? outTokenRecipient : to;\n\n _swap(inToken, inTokenObtained, SwapType(swapType), data);\n\n // A final slippage check is performed after the swaps\n uint256 outTokenBalance = outToken.balanceOf(address(this));\n if (outTokenBalance < minAmountOut) revert TooSmallAmountOut();\n\n // The `outTokenRecipient` may already have enough in balance, in which case there's no need to transfer\n // to this address the token and everything can be given to the `to` address\n uint256 outTokenBalanceRecipient = outToken.balanceOf(outTokenRecipient);\n if (outTokenBalanceRecipient >= outTokenOwed || to == outTokenRecipient)\n outToken.safeTransfer(to, outTokenBalance);\n else {\n // The `outTokenRecipient` should receive the delta to make sure its end balance is equal to `outTokenOwed`\n // Any leftover in this case is sent to the `to` address\n // The function reverts if it did not obtain more than `outTokenOwed - outTokenBalanceRecipient` from the swap\n outToken.safeTransfer(outTokenRecipient, outTokenOwed - outTokenBalanceRecipient);\n outToken.safeTransfer(to, outTokenBalanceRecipient + outTokenBalance - outTokenOwed);\n }\n // Reusing the `inTokenObtained` variable for the `inToken` balance\n // Sending back the remaining amount of inTokens to the `to` address: it is possible that not the full `inTokenObtained`\n // is swapped to `outToken` if we're using the `1inch` payload\n inTokenObtained = inToken.balanceOf(address(this));\n if (inTokenObtained != 0) inToken.safeTransfer(to, inTokenObtained);\n }\n\n // ============================ GOVERNANCE FUNCTION ============================\n\n /// @notice Changes allowances of this contract for different tokens\n /// @param tokens Addresses of the tokens to allow\n /// @param spenders Addresses to allow transfer\n /// @param amounts Amounts to allow\n function changeAllowance(\n IERC20[] calldata tokens,\n address[] calldata spenders,\n uint256[] calldata amounts\n ) external {\n if (!core.isGovernorOrGuardian(msg.sender)) revert NotGovernorOrGuardian();\n uint256 tokensLength = tokens.length;\n if (tokensLength != spenders.length || tokensLength != amounts.length) revert IncompatibleLengths();\n for (uint256 i; i < tokensLength; ++i) {\n _changeAllowance(tokens[i], spenders[i], amounts[i]);\n }\n }\n\n // ========================= INTERNAL UTILITY FUNCTIONS ========================\n\n /// @notice Internal version of the `_changeAllowance` function\n function _changeAllowance(IERC20 token, address spender, uint256 amount) internal {\n uint256 currentAllowance = token.allowance(address(this), spender);\n // In case `currentAllowance < type(uint256).max / 2` and we want to increase it:\n // Do nothing (to handle tokens that need reapprovals to 0 and save gas)\n if (currentAllowance < amount && currentAllowance < type(uint256).max / 2) {\n token.safeIncreaseAllowance(spender, amount - currentAllowance);\n } else if (currentAllowance > amount) {\n token.safeDecreaseAllowance(spender, currentAllowance - amount);\n }\n }\n\n /// @notice Checks the allowance for a contract and updates it to the max if it is not big enough\n /// @param token Token for which allowance should be checked\n /// @param spender Address to grant allowance to\n /// @param amount Minimum amount of tokens needed for the allowance\n function _checkAllowance(IERC20 token, address spender, uint256 amount) internal {\n uint256 currentAllowance = token.allowance(address(this), spender);\n if (currentAllowance < amount) token.safeIncreaseAllowance(spender, type(uint256).max - currentAllowance);\n }\n\n /// @notice Performs a swap using either Uniswap, 1inch. This function can also stake stETH to wstETH\n /// @param inToken Token to swap\n /// @param amount Amount of tokens to swap\n /// @param swapType Type of the swap to perform\n /// @param args Extra args for the swap: in the case of Uniswap it should be a path, for 1inch it should be\n /// a payload\n /// @dev This function does nothing if `swapType` is None and it simply passes on the `amount` it received\n /// @dev No slippage is specified in the actions given here as a final slippage check is performed\n /// after the call to this function\n function _swap(IERC20 inToken, uint256 amount, SwapType swapType, bytes memory args) internal {\n if (swapType == SwapType.UniswapV3) _swapOnUniswapV3(inToken, amount, args);\n else if (swapType == SwapType.oneInch) _swapOn1inch(inToken, args);\n else if (swapType == SwapType.AngleRouter) _angleRouterActions(inToken, args);\n else if (swapType == SwapType.Leverage) _swapLeverage(args);\n }\n\n /// @notice Performs a UniswapV3 swap\n /// @param inToken Token to swap\n /// @param amount Amount of tokens to swap\n /// @param path Path for the UniswapV3 swap: this encodes the out token that is going to be obtained\n /// @dev This function does not check the out token obtained here: if it is wrongly specified, either\n /// the `swap` function could fail or these tokens could stay on the contract\n function _swapOnUniswapV3(IERC20 inToken, uint256 amount, bytes memory path) internal returns (uint256 amountOut) {\n // We need more than `amount` of allowance to the contract\n _checkAllowance(inToken, address(uniV3Router), amount);\n amountOut = uniV3Router.exactInput(ExactInputParams(path, address(this), block.timestamp, amount, 0));\n }\n\n /// @notice Allows to swap any token to an accepted collateral via 1inch API\n /// @param inToken Token received for the 1inch swap\n /// @param payload Bytes needed for 1inch API\n function _swapOn1inch(IERC20 inToken, bytes memory payload) internal returns (uint256 amountOut) {\n _changeAllowance(inToken, oneInch, type(uint256).max);\n //solhint-disable-next-line\n (bool success, bytes memory result) = oneInch.call(payload);\n if (!success) _revertBytes(result);\n amountOut = abi.decode(result, (uint256));\n }\n\n /// @notice Performs actions with the router contract of the protocol on the corresponding chain\n /// @param inToken Token concerned by the action and for which\n function _angleRouterActions(IERC20 inToken, bytes memory args) internal {\n (ActionType[] memory actions, bytes[] memory actionData) = abi.decode(args, (ActionType[], bytes[]));\n _changeAllowance(inToken, address(angleRouter), type(uint256).max);\n PermitType[] memory permits;\n angleRouter.mixer(permits, actions, actionData);\n }\n\n /// @notice Allows to take leverage or deleverage via a specific contract\n /// @param payload Bytes needed for 1inch API\n /// @dev This function is to be implemented if the swapper concerns a token that requires some actions\n /// not supported by 1inch or UniV3\n function _swapLeverage(bytes memory payload) internal virtual returns (uint256 amountOut) {}\n\n /// @notice Internal function used for error handling\n /// @param errMsg Error message received\n function _revertBytes(bytes memory errMsg) internal pure {\n if (errMsg.length != 0) {\n //solhint-disable-next-line\n assembly {\n revert(add(32, errMsg), mload(errMsg))\n }\n }\n revert EmptyReturnMessage();\n }\n}\n" + }, + "contracts/treasury/Treasury.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\n/*\n * █ \n ***** ▓▓▓ \n * ▓▓▓▓▓▓▓ \n * ///. ▓▓▓▓▓▓▓▓▓▓▓▓▓ \n ***** //////// ▓▓▓▓▓▓▓ \n * ///////////// ▓▓▓ \n ▓▓ ////////////////// █ ▓▓ \n ▓▓ ▓▓ /////////////////////// ▓▓ ▓▓ \n ▓▓ ▓▓ //////////////////////////// ▓▓ ▓▓ \n ▓▓ ▓▓ /////////▓▓▓///////▓▓▓///////// ▓▓ ▓▓ \n ▓▓ ,////////////////////////////////////// ▓▓ ▓▓ \n ▓▓ ////////////////////////////////////////// ▓▓ \n ▓▓ //////////////////////▓▓▓▓///////////////////// \n ,//////////////////////////////////////////////////// \n .////////////////////////////////////////////////////////// \n .//////////////////////////██.,//////////////////////////█ \n .//////////////////////████..,./////////////////////██ \n ...////////////////███████.....,.////////////////███ \n ,.,////////////████████ ........,///////////████ \n .,.,//////█████████ ,.......///////████ \n ,..//████████ ........./████ \n ..,██████ .....,███ \n .██ ,.,█ \n \n \n \n ▓▓ ▓▓▓▓▓▓▓▓▓▓ ▓▓▓▓▓▓▓▓▓▓ ▓▓ ▓▓▓▓▓▓▓▓▓▓ \n ▓▓▓▓▓▓ ▓▓▓ ▓▓▓ ▓▓▓ ▓▓ ▓▓ ▓▓▓▓ \n ▓▓▓ ▓▓▓ ▓▓▓ ▓▓▓ ▓▓▓ ▓▓▓ ▓▓ ▓▓▓▓▓ \n ▓▓▓ ▓▓ ▓▓▓ ▓▓▓ ▓▓▓▓▓▓▓▓▓▓ ▓▓▓▓▓▓▓▓▓▓ ▓▓▓▓▓▓▓▓▓▓ \n*/\n\npragma solidity ^0.8.12;\n\nimport \"@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol\";\nimport \"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\";\nimport \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\n\nimport \"../interfaces/IAgToken.sol\";\nimport \"../interfaces/ICoreBorrow.sol\";\nimport \"../interfaces/IFlashAngle.sol\";\nimport \"../interfaces/ITreasury.sol\";\nimport \"../interfaces/IVaultManager.sol\";\n\n/// @title Treasury\n/// @author Angle Labs, Inc.\n/// @notice Treasury of Angle Borrowing Module doing the accounting across all VaultManagers for\n/// a given stablecoin\ncontract Treasury is ITreasury, Initializable {\n using SafeERC20 for IERC20;\n\n /// @notice Base used for parameter computation\n uint256 public constant BASE_9 = 1e9;\n\n // ================================= REFERENCES ================================\n\n /// @notice Reference to the `CoreBorrow` contract of the module which handles all AccessControl logic\n ICoreBorrow public core;\n /// @notice Flash Loan Module with a minter right on the stablecoin\n IFlashAngle public flashLoanModule;\n /// @inheritdoc ITreasury\n IAgToken public stablecoin;\n /// @notice Address responsible for handling the surplus made by the treasury\n address public surplusManager;\n /// @notice List of the accepted `VaultManager` of the protocol\n address[] public vaultManagerList;\n /// @notice Maps an address to 1 if it was initialized as a `VaultManager` contract\n mapping(address => uint256) public vaultManagerMap;\n\n // ================================= VARIABLES =================================\n\n /// @notice Amount of bad debt (unbacked stablecoin) accumulated across all `VaultManager` contracts\n /// linked to this stablecoin\n uint256 public badDebt;\n /// @notice Surplus amount accumulated by the contract waiting to be distributed to governance. Technically\n /// only a share of this `surplusBuffer` will go to governance. Once a share of the surplus buffer has been\n /// given to governance, then this surplus is reset\n uint256 public surplusBuffer;\n\n // ================================= PARAMETER =================================\n\n /// @notice Share of the `surplusBuffer` distributed to governance (in `BASE_9`)\n uint64 public surplusForGovernance;\n\n // =================================== EVENTS ==================================\n\n event BadDebtUpdated(uint256 badDebtValue);\n event CoreUpdated(address indexed _core);\n event NewTreasurySet(address indexed _treasury);\n event Recovered(address indexed token, address indexed to, uint256 amount);\n event SurplusBufferUpdated(uint256 surplusBufferValue);\n event SurplusForGovernanceUpdated(uint64 _surplusForGovernance);\n event SurplusManagerUpdated(address indexed _surplusManager);\n event VaultManagerToggled(address indexed vaultManager);\n\n // =================================== ERRORS ==================================\n\n error AlreadyVaultManager();\n error InvalidAddress();\n error InvalidTreasury();\n error NotCore();\n error NotGovernor();\n error NotVaultManager();\n error RightsNotRemoved();\n error TooBigAmount();\n error TooHighParameterValue();\n error ZeroAddress();\n\n // ================================== MODIFIER =================================\n\n /// @notice Checks whether the `msg.sender` has the governor role or not\n modifier onlyGovernor() {\n if (!core.isGovernor(msg.sender)) revert NotGovernor();\n _;\n }\n\n /// @notice Initializes the treasury contract\n /// @param _core Address of the `CoreBorrow` contract of the module\n /// @param _stablecoin Address of the stablecoin\n function initialize(ICoreBorrow _core, IAgToken _stablecoin) public virtual initializer {\n if (address(_stablecoin) == address(0) || address(_core) == address(0)) revert ZeroAddress();\n core = _core;\n stablecoin = _stablecoin;\n }\n\n /// @custom:oz-upgrades-unsafe-allow constructor\n constructor() initializer {}\n\n // =============================== VIEW FUNCTIONS ==============================\n\n /// @inheritdoc ITreasury\n function isGovernor(address admin) external view returns (bool) {\n return core.isGovernor(admin);\n }\n\n /// @inheritdoc ITreasury\n function isGovernorOrGuardian(address admin) external view returns (bool) {\n return core.isGovernorOrGuardian(admin);\n }\n\n /// @inheritdoc ITreasury\n function isVaultManager(address _vaultManager) external view returns (bool) {\n return vaultManagerMap[_vaultManager] == 1;\n }\n\n // ===================== EXTERNAL PERMISSIONLESS FUNCTIONS =====================\n\n /// @notice Fetches the surplus accrued across all the `VaultManager` contracts controlled by this\n /// `Treasury` contract as well as from the fees of the `FlashLoan` module\n /// @return Surplus buffer value at the end of the call\n /// @return Bad debt value at the end of the call\n /// @dev This function pools surplus and bad debt across all contracts and then updates the `surplusBuffer`\n /// (or the `badDebt` if more losses were made than profits)\n function fetchSurplusFromAll() external returns (uint256, uint256) {\n return _fetchSurplusFromAll();\n }\n\n /// @notice Fetches the surplus accrued in the flash loan module and updates the `surplusBuffer`\n /// @return Surplus buffer value at the end of the call\n /// @return Bad debt value at the end of the call\n /// @dev This function fails if the `flashLoanModule` has not been initialized yet\n function fetchSurplusFromFlashLoan() external returns (uint256, uint256) {\n uint256 surplusBufferValue = surplusBuffer + flashLoanModule.accrueInterestToTreasury(stablecoin);\n return _updateSurplusAndBadDebt(surplusBufferValue, badDebt);\n }\n\n /// @notice Pushes the surplus buffer to the `surplusManager` contract\n /// @return governanceAllocation Amount transferred to governance\n /// @dev It makes sure to fetch the surplus from all the contracts handled by this treasury to avoid\n /// the situation where rewards are still distributed to governance even though a `VaultManager` has made\n /// a big loss\n /// @dev Typically this function is to be called once every week by a keeper to distribute rewards to veANGLE\n /// holders\n /// @dev `stablecoin` must be an AgToken and hence `transfer` reverts if the call is not successful\n function pushSurplus() external returns (uint256 governanceAllocation) {\n address _surplusManager = surplusManager;\n if (_surplusManager == address(0)) {\n revert ZeroAddress();\n }\n (uint256 surplusBufferValue, ) = _fetchSurplusFromAll();\n surplusBuffer = 0;\n emit SurplusBufferUpdated(0);\n governanceAllocation = (surplusForGovernance * surplusBufferValue) / BASE_9;\n stablecoin.transfer(_surplusManager, governanceAllocation);\n }\n\n /// @notice Updates the bad debt of the protocol in case where the protocol has accumulated some revenue\n /// from an external source\n /// @param amount Amount to reduce the bad debt of\n /// @return badDebtValue Value of the bad debt at the end of the call\n /// @dev If the protocol has made a loss and managed to make some profits to recover for this loss (through\n /// a program like Olympus Pro), then this function needs to be called\n /// @dev `badDebt` is simply reduced here by burning stablecoins\n /// @dev It is impossible to burn more than the `badDebt` otherwise this function could be used to manipulate\n /// the `surplusBuffer` and hence the amount going to governance\n function updateBadDebt(uint256 amount) external returns (uint256 badDebtValue) {\n stablecoin.burnSelf(amount, address(this));\n badDebtValue = badDebt - amount;\n badDebt = badDebtValue;\n emit BadDebtUpdated(badDebtValue);\n }\n\n // ========================= INTERNAL UTILITY FUNCTIONS ========================\n\n /// @notice Internal version of the `fetchSurplusFromAll` function\n function _fetchSurplusFromAll() internal returns (uint256 surplusBufferValue, uint256 badDebtValue) {\n (surplusBufferValue, badDebtValue) = _fetchSurplusFromList(vaultManagerList);\n // It will fail anyway if the `flashLoanModule` is the zero address\n if (address(flashLoanModule) != address(0))\n surplusBufferValue += flashLoanModule.accrueInterestToTreasury(stablecoin);\n (surplusBufferValue, badDebtValue) = _updateSurplusAndBadDebt(surplusBufferValue, badDebtValue);\n }\n\n /// @notice Fetches the surplus from a list of `VaultManager` addresses without modifying the\n /// `surplusBuffer` and `badDebtValue`\n /// @return surplusBufferValue Value the `surplusBuffer` should have after the call if it was updated\n /// @return badDebtValue Value the `badDebt` should have after the call if it was updated\n /// @dev This internal function is never to be called alone, and should always be called in conjunction\n /// with the `_updateSurplusAndBadDebt` function\n function _fetchSurplusFromList(\n address[] memory vaultManagers\n ) internal returns (uint256 surplusBufferValue, uint256 badDebtValue) {\n badDebtValue = badDebt;\n surplusBufferValue = surplusBuffer;\n uint256 newSurplus;\n uint256 newBadDebt;\n uint256 vaultManagersLength = vaultManagers.length;\n for (uint256 i; i < vaultManagersLength; ++i) {\n (newSurplus, newBadDebt) = IVaultManager(vaultManagers[i]).accrueInterestToTreasury();\n surplusBufferValue += newSurplus;\n badDebtValue += newBadDebt;\n }\n }\n\n /// @notice Updates the `surplusBuffer` and the `badDebt` from updated values after calling the flash loan module\n /// and/or a list of `VaultManager` contracts\n /// @param surplusBufferValue Value of the surplus buffer after the calls to the different modules\n /// @param badDebtValue Value of the bad debt after the calls to the different modules\n /// @return Value of the `surplusBuffer` corrected from the `badDebt`\n /// @return Value of the `badDebt` corrected from the `surplusBuffer` and from the surplus the treasury had accumulated\n /// previously\n /// @dev When calling this function, it is possible that there is a positive `surplusBufferValue` and `badDebtValue`,\n /// this function tries to reconcile both values and makes sure that we either have surplus or bad debt but not both\n /// at the same time\n function _updateSurplusAndBadDebt(\n uint256 surplusBufferValue,\n uint256 badDebtValue\n ) internal returns (uint256, uint256) {\n if (badDebtValue != 0) {\n // If we have bad debt we need to burn stablecoins that accrued to the protocol\n // We still need to make sure that we're not burning too much or as much as we can if the debt is big\n uint256 balance = stablecoin.balanceOf(address(this));\n // We are going to burn `min(balance, badDebtValue)`\n uint256 toBurn = balance <= badDebtValue ? balance : badDebtValue;\n stablecoin.burnSelf(toBurn, address(this));\n // If we burned more than `surplusBuffer`, we set surplus to 0. It means we had to tap into Treasury reserve\n surplusBufferValue = toBurn >= surplusBufferValue ? 0 : surplusBufferValue - toBurn;\n badDebtValue -= toBurn;\n // Note here that the stablecoin balance is necessarily greater than the surplus buffer, and so if\n // `surplusBuffer >= toBurn`, then `badDebtValue = toBurn`\n }\n surplusBuffer = surplusBufferValue;\n badDebt = badDebtValue;\n emit SurplusBufferUpdated(surplusBufferValue);\n emit BadDebtUpdated(badDebtValue);\n return (surplusBufferValue, badDebtValue);\n }\n\n /// @notice Adds a new `VaultManager`\n /// @param vaultManager `VaultManager` contract to add\n /// @dev This contract should have already been initialized with a correct treasury address\n /// @dev It's this function that gives the minter right to the `VaultManager`\n function _addVaultManager(address vaultManager) internal virtual {\n if (vaultManagerMap[vaultManager] == 1) revert AlreadyVaultManager();\n if (address(IVaultManager(vaultManager).treasury()) != address(this)) revert InvalidTreasury();\n vaultManagerMap[vaultManager] = 1;\n vaultManagerList.push(vaultManager);\n emit VaultManagerToggled(vaultManager);\n stablecoin.addMinter(vaultManager);\n }\n\n // ============================= GOVERNOR FUNCTIONS ============================\n\n /// @notice Adds a new minter for the stablecoin\n /// @param minter Minter address to add\n function addMinter(address minter) external virtual onlyGovernor {\n if (minter == address(0)) revert ZeroAddress();\n stablecoin.addMinter(minter);\n }\n\n /// @notice External wrapper for `_addVaultManager`\n function addVaultManager(address vaultManager) external virtual onlyGovernor {\n _addVaultManager(vaultManager);\n }\n\n /// @notice Removes a minter from the stablecoin contract\n /// @param minter Minter address to remove\n function removeMinter(address minter) external virtual onlyGovernor {\n // To remove the minter role to a `VaultManager` you have to go through the `removeVaultManager` function\n if (vaultManagerMap[minter] == 1) revert InvalidAddress();\n stablecoin.removeMinter(minter);\n }\n\n /// @notice Removes a `VaultManager`\n /// @param vaultManager `VaultManager` contract to remove\n /// @dev A removed `VaultManager` loses its minter right on the stablecoin\n function removeVaultManager(address vaultManager) external onlyGovernor {\n if (vaultManagerMap[vaultManager] != 1) revert NotVaultManager();\n delete vaultManagerMap[vaultManager];\n // deletion from `vaultManagerList` loop\n uint256 vaultManagerListLength = vaultManagerList.length;\n for (uint256 i; i < vaultManagerListLength - 1; ++i) {\n if (vaultManagerList[i] == vaultManager) {\n // replace the `VaultManager` to remove with the last of the list\n vaultManagerList[i] = vaultManagerList[vaultManagerListLength - 1];\n break;\n }\n }\n // remove last element in array\n vaultManagerList.pop();\n emit VaultManagerToggled(vaultManager);\n stablecoin.removeMinter(vaultManager);\n }\n\n /// @notice Allows to recover any ERC20 token, including the stablecoin handled by this contract, and to send it\n /// to a contract\n /// @param tokenAddress Address of the token to recover\n /// @param to Address of the contract to send collateral to\n /// @param amountToRecover Amount of collateral to transfer\n /// @dev It is impossible to recover the stablecoin of the protocol if there is some bad debt for it\n /// @dev In this case, the function makes sure to fetch the surplus/bad debt from all the `VaultManager` contracts\n /// and from the flash loan module\n /// @dev If the token to recover is the stablecoin, tokens recovered are fetched\n /// from the surplus and not from the `surplusBuffer`\n function recoverERC20(address tokenAddress, address to, uint256 amountToRecover) external onlyGovernor {\n // Cannot recover stablecoin if badDebt or tap into the surplus buffer\n if (tokenAddress == address(stablecoin)) {\n _fetchSurplusFromAll();\n // If balance is non zero then this means, after the call to `fetchSurplusFromAll` that\n // bad debt is necessarily null\n uint256 balance = stablecoin.balanceOf(address(this));\n if (amountToRecover + surplusBuffer > balance) revert TooBigAmount();\n stablecoin.transfer(to, amountToRecover);\n } else {\n IERC20(tokenAddress).safeTransfer(to, amountToRecover);\n }\n emit Recovered(tokenAddress, to, amountToRecover);\n }\n\n /// @notice Changes the treasury contract and communicates this change to all `VaultManager` contract\n /// @param _treasury New treasury address for this stablecoin\n /// @dev This function is basically a way to remove rights to this contract and grant them to a new one\n /// @dev It could be used to set a new core contract\n function setTreasury(address _treasury) external virtual onlyGovernor {\n if (ITreasury(_treasury).stablecoin() != stablecoin) revert InvalidTreasury();\n // Flash loan role should be removed before calling this function\n if (core.isFlashLoanerTreasury(address(this))) revert RightsNotRemoved();\n emit NewTreasurySet(_treasury);\n uint256 vaultManagerListLength = vaultManagerList.length;\n for (uint256 i; i < vaultManagerListLength; ++i) {\n IVaultManager(vaultManagerList[i]).setTreasury(_treasury);\n }\n // A `TreasuryUpdated` event is triggered in the stablecoin\n stablecoin.setTreasury(_treasury);\n }\n\n /// @notice Sets the `surplusForGovernance` parameter\n /// @param _surplusForGovernance New value of the parameter\n /// @dev To pause surplus distribution, governance needs to set a zero value for `surplusForGovernance`\n /// which means\n function setSurplusForGovernance(uint64 _surplusForGovernance) external onlyGovernor {\n if (_surplusForGovernance > BASE_9) revert TooHighParameterValue();\n surplusForGovernance = _surplusForGovernance;\n emit SurplusForGovernanceUpdated(_surplusForGovernance);\n }\n\n /// @notice Sets the `surplusManager` contract responsible for handling the surplus of the\n /// protocol\n /// @param _surplusManager New address responsible for handling the surplus\n function setSurplusManager(address _surplusManager) external onlyGovernor {\n if (_surplusManager == address(0)) revert ZeroAddress();\n surplusManager = _surplusManager;\n emit SurplusManagerUpdated(_surplusManager);\n }\n\n /// @notice Sets a new `core` contract\n /// @dev This function should typically be called on all treasury contracts after the `setCore`\n /// function has been called on the `CoreBorrow` contract\n /// @dev One sanity check that can be performed here is to verify whether at least the governor\n /// calling the contract is still a governor in the new core\n function setCore(ICoreBorrow _core) external onlyGovernor {\n if (!_core.isGovernor(msg.sender)) revert NotGovernor();\n core = ICoreBorrow(_core);\n emit CoreUpdated(address(_core));\n }\n\n /// @inheritdoc ITreasury\n function setFlashLoanModule(address _flashLoanModule) external {\n if (msg.sender != address(core)) revert NotCore();\n address oldFlashLoanModule = address(flashLoanModule);\n flashLoanModule = IFlashAngle(_flashLoanModule);\n if (oldFlashLoanModule != address(0)) {\n stablecoin.removeMinter(oldFlashLoanModule);\n }\n // We may want to cancel the module\n if (_flashLoanModule != address(0)) {\n stablecoin.addMinter(_flashLoanModule);\n }\n }\n}\n" + }, + "contracts/ui-helpers/AngleBorrowHelpers.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\n/*\n * █ \n ***** ▓▓▓ \n * ▓▓▓▓▓▓▓ \n * ///. ▓▓▓▓▓▓▓▓▓▓▓▓▓ \n ***** //////// ▓▓▓▓▓▓▓ \n * ///////////// ▓▓▓ \n ▓▓ ////////////////// █ ▓▓ \n ▓▓ ▓▓ /////////////////////// ▓▓ ▓▓ \n ▓▓ ▓▓ //////////////////////////// ▓▓ ▓▓ \n ▓▓ ▓▓ /////////▓▓▓///////▓▓▓///////// ▓▓ ▓▓ \n ▓▓ ,////////////////////////////////////// ▓▓ ▓▓ \n ▓▓ ////////////////////////////////////////// ▓▓ \n ▓▓ //////////////////////▓▓▓▓///////////////////// \n ,//////////////////////////////////////////////////// \n .////////////////////////////////////////////////////////// \n .//////////////////////////██.,//////////////////////////█ \n .//////////////////////████..,./////////////////////██ \n ...////////////////███████.....,.////////////////███ \n ,.,////////////████████ ........,///////////████ \n .,.,//////█████████ ,.......///////████ \n ,..//████████ ........./████ \n ..,██████ .....,███ \n .██ ,.,█ \n \n \n \n ▓▓ ▓▓▓▓▓▓▓▓▓▓ ▓▓▓▓▓▓▓▓▓▓ ▓▓ ▓▓▓▓▓▓▓▓▓▓ \n ▓▓▓▓▓▓ ▓▓▓ ▓▓▓ ▓▓▓ ▓▓ ▓▓ ▓▓▓▓ \n ▓▓▓ ▓▓▓ ▓▓▓ ▓▓▓ ▓▓▓ ▓▓▓ ▓▓ ▓▓▓▓▓ \n ▓▓▓ ▓▓ ▓▓▓ ▓▓▓ ▓▓▓▓▓▓▓▓▓▓ ▓▓▓▓▓▓▓▓▓▓ ▓▓▓▓▓▓▓▓▓▓ \n*/\n\nimport \"@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol\";\nimport \"../interfaces/IVaultManager.sol\";\n\npragma solidity ^0.8.12;\n\n/// @title AngleBorrowHelpers\n/// @author Angle Labs, Inc.\n/// @notice Contract with view functions designed to facilitate integrations on the Borrow module of the Angle Protocol\n/// @dev This contract only contains view functions to be queried off-chain. It was thus not optimized for gas consumption\ncontract AngleBorrowHelpers is Initializable {\n /// @notice Returns all the vaults owned or controlled (under the form of approval) by an address\n /// @param vaultManager VaultManager address to query vaultIDs on\n /// @param spender Address for which vault ownerships should be checked\n /// @return List of `vaultID` controlled by this address\n /// @return Count of vaults owned by the address\n /// @dev This function is never to be called on-chain since it iterates over all vaultIDs. It is here\n /// to reduce dependency on an external graph to link an ID to its owner\n function getControlledVaults(\n IVaultManager vaultManager,\n address spender\n ) external view returns (uint256[] memory, uint256) {\n uint256 arraySize = vaultManager.vaultIDCount();\n uint256[] memory vaultsControlled = new uint256[](arraySize);\n uint256 count;\n for (uint256 i = 1; i <= arraySize; ++i) {\n try vaultManager.isApprovedOrOwner(spender, i) returns (bool _isApprovedOrOwner) {\n if (_isApprovedOrOwner) {\n vaultsControlled[count] = i;\n count += 1;\n }\n } catch {\n continue;\n } // This happens if nobody owns the vaultID=i (if there has been a burn)\n }\n return (vaultsControlled, count);\n }\n\n /// @custom:oz-upgrades-unsafe-allow constructor\n constructor() initializer {}\n}\n" + }, + "contracts/ui-helpers/AngleHelpers.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\nimport \"../interfaces/IAngleRouter.sol\";\nimport \"../interfaces/coreModule/IAgTokenMainnet.sol\";\nimport \"../interfaces/coreModule/ICore.sol\";\nimport \"../interfaces/coreModule/IOracleCore.sol\";\nimport \"../interfaces/coreModule/IPerpetualManager.sol\";\nimport \"../interfaces/coreModule/IPoolManager.sol\";\nimport \"../interfaces/coreModule/IStableMaster.sol\";\nimport \"./AngleBorrowHelpers.sol\";\n\npragma solidity ^0.8.12;\n\nstruct Parameters {\n SLPData slpData;\n MintBurnData feeData;\n PerpetualManagerFeeData perpFeeData;\n PerpetualManagerParamData perpParam;\n}\n\nstruct PerpetualManagerFeeData {\n uint64[] xHAFeesDeposit;\n uint64[] yHAFeesDeposit;\n uint64[] xHAFeesWithdraw;\n uint64[] yHAFeesWithdraw;\n uint64 haBonusMalusDeposit;\n uint64 haBonusMalusWithdraw;\n}\n\nstruct PerpetualManagerParamData {\n uint64 maintenanceMargin;\n uint64 maxLeverage;\n uint64 targetHAHedge;\n uint64 limitHAHedge;\n uint64 lockTime;\n}\n\nstruct CollateralAddresses {\n address stableMaster;\n address poolManager;\n address perpetualManager;\n address sanToken;\n address oracle;\n address gauge;\n address feeManager;\n address[] strategies;\n}\n\n/// @title AngleHelpers\n/// @author Angle Labs, Inc.\n/// @notice Contract with view functions designed to facilitate integrations on the Core and Borrow module of the Angle Protocol\n/// @dev This contract only contains view functions to be queried off-chain. It was thus not optimized for gas consumption\ncontract AngleHelpers is AngleBorrowHelpers {\n // =========================== HELPER VIEW FUNCTIONS ===========================\n\n /// @notice Gives the amount of `agToken` you'd be getting if you were executing in the same block a mint transaction\n /// with `amount` of `collateral` in the Core module of the Angle protocol as well as the value of the fees\n /// (in `BASE_PARAMS`) that would be applied during the mint\n /// @return Amount of `agToken` that would be obtained with a mint transaction in the same block\n /// @return Percentage of fees that would be taken during a mint transaction in the same block\n /// @dev This function reverts if the mint transaction was to revert in the same conditions (without taking into account\n /// potential approval problems to the `StableMaster` contract)\n function previewMintAndFees(\n uint256 amount,\n address agToken,\n address collateral\n ) external view returns (uint256, uint256) {\n return _previewMintAndFees(amount, agToken, collateral);\n }\n\n /// @notice Gives the amount of `collateral` you'd be getting if you were executing in the same block a burn transaction\n /// with `amount` of `agToken` in the Core module of the Angle protocol as well as the value of the fees\n /// (in `BASE_PARAMS`) that would be applied during the burn\n /// @return Amount of `collateral` that would be obtained with a burn transaction in the same block\n /// @return Percentage of fees that would be taken during a burn transaction in the same block\n /// @dev This function reverts if the burn transaction was to revert in the same conditions (without taking into account\n /// potential approval problems to the `StableMaster` contract or agToken balance prior to the call)\n function previewBurnAndFees(\n uint256 amount,\n address agToken,\n address collateral\n ) external view returns (uint256, uint256) {\n return _previewBurnAndFees(amount, agToken, collateral);\n }\n\n /// @notice Returns all the addresses associated to the (`agToken`,`collateral`) pair given\n /// @return addresses A struct with all the addresses associated in the Core module\n function getCollateralAddresses(\n address agToken,\n address collateral\n ) external view returns (CollateralAddresses memory addresses) {\n address stableMaster = IAgTokenMainnet(agToken).stableMaster();\n (address poolManager, address perpetualManager, address sanToken, address gauge) = ROUTER.mapPoolManagers(\n stableMaster,\n collateral\n );\n (, , , IOracleCore oracle, , , , , ) = IStableMaster(stableMaster).collateralMap(poolManager);\n addresses.stableMaster = stableMaster;\n addresses.poolManager = poolManager;\n addresses.perpetualManager = perpetualManager;\n addresses.sanToken = sanToken;\n addresses.gauge = gauge;\n addresses.oracle = address(oracle);\n addresses.feeManager = IPoolManager(poolManager).feeManager();\n\n uint256 length;\n while (true) {\n try IPoolManager(poolManager).strategyList(length) returns (address) {\n length += 1;\n } catch {\n break;\n }\n }\n address[] memory strategies = new address[](length);\n for (uint256 i; i < length; ++i) {\n strategies[i] = IPoolManager(poolManager).strategyList(i);\n }\n addresses.strategies = strategies;\n }\n\n /// @notice Gets the addresses of all the `StableMaster` contracts and their associated `AgToken` addresses\n /// @return List of the `StableMaster` addresses of the Angle protocol\n /// @return List of the `AgToken` addresses of the protocol\n /// @dev The place of an agToken address in the list is the same as the corresponding `StableMaster` address\n function getStablecoinAddresses() external view returns (address[] memory, address[] memory) {\n address[] memory stableMasterAddresses = CORE.stablecoinList();\n address[] memory agTokenAddresses = new address[](stableMasterAddresses.length);\n for (uint256 i; i < stableMasterAddresses.length; ++i) {\n agTokenAddresses[i] = IStableMaster(stableMasterAddresses[i]).agToken();\n }\n return (stableMasterAddresses, agTokenAddresses);\n }\n\n /// @notice Returns most of the governance parameters associated to the (`agToken`,`collateral`) pair given\n /// @return params Struct with most of the parameters in the `StableMaster` and `PerpetualManager` contracts\n /// @dev Check out the struct `Parameters` for the meaning of the return values\n function getCollateralParameters(\n address agToken,\n address collateral\n ) external view returns (Parameters memory params) {\n (address stableMaster, address poolManager) = _getStableMasterAndPoolManager(agToken, collateral);\n (\n ,\n ,\n IPerpetualManager perpetualManager,\n ,\n ,\n ,\n ,\n SLPData memory slpData,\n MintBurnData memory feeData\n ) = IStableMaster(stableMaster).collateralMap(poolManager);\n\n params.slpData = slpData;\n params.feeData = feeData;\n params.perpParam.maintenanceMargin = perpetualManager.maintenanceMargin();\n params.perpParam.maxLeverage = perpetualManager.maxLeverage();\n params.perpParam.targetHAHedge = perpetualManager.targetHAHedge();\n params.perpParam.limitHAHedge = perpetualManager.limitHAHedge();\n params.perpParam.lockTime = perpetualManager.lockTime();\n\n params.perpFeeData.haBonusMalusDeposit = perpetualManager.haBonusMalusDeposit();\n params.perpFeeData.haBonusMalusWithdraw = perpetualManager.haBonusMalusWithdraw();\n\n uint256 length;\n while (true) {\n try perpetualManager.xHAFeesDeposit(length) returns (uint64) {\n length += 1;\n } catch {\n break;\n }\n }\n uint64[] memory data = new uint64[](length);\n uint64[] memory data2 = new uint64[](length);\n for (uint256 i; i < length; ++i) {\n data[i] = perpetualManager.xHAFeesDeposit(i);\n data2[i] = perpetualManager.yHAFeesDeposit(i);\n }\n params.perpFeeData.xHAFeesDeposit = data;\n params.perpFeeData.yHAFeesDeposit = data2;\n\n length = 0;\n while (true) {\n try perpetualManager.xHAFeesWithdraw(length) returns (uint64) {\n length += 1;\n } catch {\n break;\n }\n }\n data = new uint64[](length);\n data2 = new uint64[](length);\n for (uint256 i; i < length; ++i) {\n data[i] = perpetualManager.xHAFeesWithdraw(i);\n data2[i] = perpetualManager.yHAFeesWithdraw(i);\n }\n params.perpFeeData.xHAFeesWithdraw = data;\n params.perpFeeData.yHAFeesWithdraw = data2;\n }\n\n /// @notice Returns the address of the poolManager associated to an (`agToken`, `collateral`) pair\n /// in the Core module of the protocol\n function getPoolManager(address agToken, address collateral) public view returns (address poolManager) {\n (, poolManager) = _getStableMasterAndPoolManager(agToken, collateral);\n }\n\n // ============================= REPLICA FUNCTIONS =============================\n // These replicate what is done in the other contracts of the protocol\n\n function _previewBurnAndFees(\n uint256 amount,\n address agToken,\n address collateral\n ) internal view returns (uint256 amountForUserInCollat, uint256 feePercent) {\n (address stableMaster, address poolManager) = _getStableMasterAndPoolManager(agToken, collateral);\n (\n address token,\n ,\n IPerpetualManager perpetualManager,\n IOracleCore oracle,\n uint256 stocksUsers,\n ,\n uint256 collatBase,\n ,\n MintBurnData memory feeData\n ) = IStableMaster(stableMaster).collateralMap(poolManager);\n if (token == address(0) || IStableMaster(stableMaster).paused(keccak256(abi.encodePacked(STABLE, poolManager))))\n revert NotInitialized();\n if (amount > stocksUsers) revert InvalidAmount();\n\n if (feeData.xFeeBurn.length == 1) {\n feePercent = feeData.yFeeBurn[0];\n } else {\n bytes memory data = abi.encode(address(perpetualManager), feeData.targetHAHedge);\n uint64 hedgeRatio = _computeHedgeRatio(stocksUsers - amount, data);\n feePercent = _piecewiseLinear(hedgeRatio, feeData.xFeeBurn, feeData.yFeeBurn);\n }\n feePercent = (feePercent * feeData.bonusMalusBurn) / BASE_PARAMS;\n\n amountForUserInCollat = (amount * (BASE_PARAMS - feePercent) * collatBase) / (oracle.readUpper() * BASE_PARAMS);\n }\n\n function _previewMintAndFees(\n uint256 amount,\n address agToken,\n address collateral\n ) internal view returns (uint256 amountForUserInStable, uint256 feePercent) {\n (address stableMaster, address poolManager) = _getStableMasterAndPoolManager(agToken, collateral);\n (\n address token,\n ,\n IPerpetualManager perpetualManager,\n IOracleCore oracle,\n uint256 stocksUsers,\n ,\n ,\n ,\n MintBurnData memory feeData\n ) = IStableMaster(stableMaster).collateralMap(poolManager);\n if (token == address(0) || IStableMaster(stableMaster).paused(keccak256(abi.encodePacked(STABLE, poolManager))))\n revert NotInitialized();\n\n amountForUserInStable = oracle.readQuoteLower(amount);\n\n if (feeData.xFeeMint.length == 1) feePercent = feeData.yFeeMint[0];\n else {\n bytes memory data = abi.encode(address(perpetualManager), feeData.targetHAHedge);\n uint64 hedgeRatio = _computeHedgeRatio(amountForUserInStable + stocksUsers, data);\n feePercent = _piecewiseLinear(hedgeRatio, feeData.xFeeMint, feeData.yFeeMint);\n }\n feePercent = (feePercent * feeData.bonusMalusMint) / BASE_PARAMS;\n\n amountForUserInStable = (amountForUserInStable * (BASE_PARAMS - feePercent)) / BASE_PARAMS;\n if (stocksUsers + amountForUserInStable > feeData.capOnStableMinted) revert InvalidAmount();\n }\n\n // ============================= UTILITY FUNCTIONS =============================\n // These utility functions are taken from other contracts of the protocol\n\n function _computeHedgeRatio(uint256 newStocksUsers, bytes memory data) internal view returns (uint64 ratio) {\n (address perpetualManager, uint64 targetHAHedge) = abi.decode(data, (address, uint64));\n uint256 totalHedgeAmount = IPerpetualManager(perpetualManager).totalHedgeAmount();\n newStocksUsers = (targetHAHedge * newStocksUsers) / BASE_PARAMS;\n if (newStocksUsers > totalHedgeAmount) ratio = uint64((totalHedgeAmount * BASE_PARAMS) / newStocksUsers);\n else ratio = uint64(BASE_PARAMS);\n }\n\n function _piecewiseLinear(uint64 x, uint64[] memory xArray, uint64[] memory yArray) internal pure returns (uint64) {\n if (x >= xArray[xArray.length - 1]) {\n return yArray[xArray.length - 1];\n } else if (x <= xArray[0]) {\n return yArray[0];\n } else {\n uint256 lower;\n uint256 upper = xArray.length - 1;\n uint256 mid;\n while (upper - lower > 1) {\n mid = lower + (upper - lower) / 2;\n if (xArray[mid] <= x) {\n lower = mid;\n } else {\n upper = mid;\n }\n }\n if (yArray[upper] > yArray[lower]) {\n return\n yArray[lower] +\n ((yArray[upper] - yArray[lower]) * (x - xArray[lower])) /\n (xArray[upper] - xArray[lower]);\n } else {\n return\n yArray[lower] -\n ((yArray[lower] - yArray[upper]) * (x - xArray[lower])) /\n (xArray[upper] - xArray[lower]);\n }\n }\n }\n\n function _getStableMasterAndPoolManager(\n address agToken,\n address collateral\n ) internal view returns (address stableMaster, address poolManager) {\n stableMaster = IAgTokenMainnet(agToken).stableMaster();\n (poolManager, , , ) = ROUTER.mapPoolManagers(stableMaster, collateral);\n }\n\n // ========================= CONSTANTS AND INITIALIZERS ========================\n\n IAngleRouter public constant ROUTER = IAngleRouter(0xBB755240596530be0c1DE5DFD77ec6398471561d);\n ICore public constant CORE = ICore(0x61ed74de9Ca5796cF2F8fD60D54160D47E30B7c3);\n\n bytes32 public constant STABLE = keccak256(\"STABLE\");\n uint256 public constant BASE_PARAMS = 10 ** 9;\n\n error NotInitialized();\n error InvalidAmount();\n}\n" + }, + "contracts/utils/Constants.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\nerror InsufficientAssets();\n\n/// @title Constants\n/// @author Angle Labs, Inc.\n/// @notice Constants and errors for Angle Protocol contracts\ncontract Constants {\n uint256 internal constant _BASE_9 = 1e9;\n uint256 internal constant _BASE_18 = 1e18;\n uint256 internal constant _BASE_27 = 1e27;\n uint256 internal constant _BASE_36 = 1e36;\n}\n" + }, + "contracts/vaultManager/VaultManagerERC721.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\nimport \"./VaultManagerStorage.sol\";\n\n/// @title VaultManagerERC721\n/// @author Angle Labs, Inc.\n/// @dev Base ERC721 Implementation of VaultManager\nabstract contract VaultManagerERC721 is IERC721MetadataUpgradeable, VaultManagerStorage {\n using SafeERC20 for IERC20;\n using Address for address;\n\n /// @inheritdoc IERC721MetadataUpgradeable\n string public name;\n /// @inheritdoc IERC721MetadataUpgradeable\n string public symbol;\n\n // ================================= MODIFIERS =================================\n\n /// @notice Checks if the person interacting with the vault with `vaultID` is approved\n /// @param caller Address of the person seeking to interact with the vault\n /// @param vaultID ID of the concerned vault\n modifier onlyApprovedOrOwner(address caller, uint256 vaultID) {\n if (!_isApprovedOrOwner(caller, vaultID)) revert NotApproved();\n _;\n }\n\n // ================================ ERC721 LOGIC ===============================\n\n /// @notice Checks whether a given address is approved for a vault or owns this vault\n /// @param spender Address for which vault ownership should be checked\n /// @param vaultID ID of the vault to check\n /// @return Whether the `spender` address owns or is approved for `vaultID`\n function isApprovedOrOwner(address spender, uint256 vaultID) external view returns (bool) {\n return _isApprovedOrOwner(spender, vaultID);\n }\n\n /// @inheritdoc IERC721MetadataUpgradeable\n function tokenURI(uint256 vaultID) external view returns (string memory) {\n if (!_exists(vaultID)) revert NonexistentVault();\n // There is no vault with `vaultID` equal to 0, so the following variable is\n // always greater than zero\n uint256 temp = vaultID;\n uint256 digits;\n while (temp != 0) {\n ++digits;\n temp /= 10;\n }\n bytes memory buffer = new bytes(digits);\n while (vaultID != 0) {\n digits -= 1;\n buffer[digits] = bytes1(uint8(48 + uint256(vaultID % 10)));\n vaultID /= 10;\n }\n return bytes(_baseURI).length != 0 ? string(abi.encodePacked(_baseURI, string(buffer))) : \"\";\n }\n\n /// @inheritdoc IERC721Upgradeable\n function balanceOf(address owner) external view returns (uint256) {\n if (owner == address(0)) revert ZeroAddress();\n return _balances[owner];\n }\n\n /// @inheritdoc IERC721Upgradeable\n function ownerOf(uint256 vaultID) external view returns (address) {\n return _ownerOf(vaultID);\n }\n\n /// @inheritdoc IERC721Upgradeable\n function approve(address to, uint256 vaultID) external {\n address owner = _ownerOf(vaultID);\n if (to == owner) revert ApprovalToOwner();\n if (msg.sender != owner && !isApprovedForAll(owner, msg.sender)) revert NotApproved();\n\n _approve(to, vaultID);\n }\n\n /// @inheritdoc IERC721Upgradeable\n function getApproved(uint256 vaultID) external view returns (address) {\n if (!_exists(vaultID)) revert NonexistentVault();\n return _getApproved(vaultID);\n }\n\n /// @inheritdoc IERC721Upgradeable\n function setApprovalForAll(address operator, bool approved) external {\n _setApprovalForAll(msg.sender, operator, approved);\n }\n\n /// @inheritdoc IERC721Upgradeable\n function isApprovedForAll(address owner, address operator) public view returns (bool) {\n return _operatorApprovals[owner][operator] == 1;\n }\n\n /// @inheritdoc IERC721Upgradeable\n function transferFrom(address from, address to, uint256 vaultID) external onlyApprovedOrOwner(msg.sender, vaultID) {\n _transfer(from, to, vaultID);\n }\n\n /// @inheritdoc IERC721Upgradeable\n function safeTransferFrom(address from, address to, uint256 vaultID) external {\n safeTransferFrom(from, to, vaultID, \"\");\n }\n\n /// @inheritdoc IERC721Upgradeable\n function safeTransferFrom(\n address from,\n address to,\n uint256 vaultID,\n bytes memory _data\n ) public onlyApprovedOrOwner(msg.sender, vaultID) {\n _safeTransfer(from, to, vaultID, _data);\n }\n\n // ================================ ERC165 LOGIC ===============================\n\n /// @inheritdoc IERC165Upgradeable\n function supportsInterface(bytes4 interfaceId) external pure returns (bool) {\n return\n interfaceId == type(IERC721MetadataUpgradeable).interfaceId ||\n interfaceId == type(IERC721Upgradeable).interfaceId ||\n interfaceId == type(IVaultManager).interfaceId ||\n interfaceId == type(IERC165Upgradeable).interfaceId;\n }\n\n // ================== INTERNAL FUNCTIONS FOR THE ERC721 LOGIC ==================\n\n /// @notice Internal version of the `ownerOf` function\n function _ownerOf(uint256 vaultID) internal view returns (address owner) {\n owner = _owners[vaultID];\n if (owner == address(0)) revert NonexistentVault();\n }\n\n /// @notice Internal version of the `getApproved` function\n function _getApproved(uint256 vaultID) internal view returns (address) {\n return _vaultApprovals[vaultID];\n }\n\n /// @notice Internal version of the `safeTransferFrom` function (with the data parameter)\n function _safeTransfer(address from, address to, uint256 vaultID, bytes memory _data) internal {\n _transfer(from, to, vaultID);\n if (!_checkOnERC721Received(from, to, vaultID, _data)) revert NonERC721Receiver();\n }\n\n /// @notice Checks whether a vault exists\n /// @param vaultID ID of the vault to check\n /// @return Whether `vaultID` has been created\n function _exists(uint256 vaultID) internal view returns (bool) {\n return _owners[vaultID] != address(0);\n }\n\n /// @notice Internal version of the `isApprovedOrOwner` function\n function _isApprovedOrOwner(address spender, uint256 vaultID) internal view returns (bool) {\n // The following checks if the vault exists\n address owner = _ownerOf(vaultID);\n return (spender == owner || _getApproved(vaultID) == spender || _operatorApprovals[owner][spender] == 1);\n }\n\n /// @notice Internal version of the `createVault` function\n /// Mints `vaultID` and transfers it to `to`\n /// @dev This method is equivalent to the `_safeMint` method used in OpenZeppelin ERC721 contract\n /// @dev Emits a {Transfer} event\n function _mint(address to) internal returns (uint256 vaultID) {\n if (to == address(0)) revert ZeroAddress();\n\n unchecked {\n vaultIDCount += 1;\n }\n\n vaultID = vaultIDCount;\n _beforeTokenTransfer(address(0), to, vaultID);\n\n unchecked {\n _balances[to] += 1;\n }\n\n _owners[vaultID] = to;\n emit Transfer(address(0), to, vaultID);\n if (!_checkOnERC721Received(address(0), to, vaultID, \"\")) revert NonERC721Receiver();\n }\n\n /// @notice Destroys `vaultID`\n /// @dev `vaultID` must exist\n /// @dev Emits a {Transfer} event\n function _burn(uint256 vaultID) internal {\n address owner = _ownerOf(vaultID);\n\n _beforeTokenTransfer(owner, address(0), vaultID);\n // Clear approvals\n _approve(address(0), vaultID);\n // The following line cannot underflow as the owner's balance is necessarily\n // greater than 1\n unchecked {\n _balances[owner] -= 1;\n }\n delete _owners[vaultID];\n delete vaultData[vaultID];\n\n emit Transfer(owner, address(0), vaultID);\n }\n\n /// @notice Transfers `vaultID` from `from` to `to` as opposed to {transferFrom},\n /// this imposes no restrictions on msg.sender\n /// @dev `to` cannot be the zero address and `perpetualID` must be owned by `from`\n /// @dev Emits a {Transfer} event\n function _transfer(address from, address to, uint256 vaultID) internal {\n if (_ownerOf(vaultID) != from) revert NotApproved();\n if (to == address(0)) revert ZeroAddress();\n\n _beforeTokenTransfer(from, to, vaultID);\n\n // Clear approvals from the previous owner\n _approve(address(0), vaultID);\n unchecked {\n _balances[from] -= 1;\n _balances[to] += 1;\n }\n _owners[vaultID] = to;\n\n emit Transfer(from, to, vaultID);\n }\n\n /// @notice Approves `to` to operate on `vaultID`\n function _approve(address to, uint256 vaultID) internal {\n _vaultApprovals[vaultID] = to;\n emit Approval(_ownerOf(vaultID), to, vaultID);\n }\n\n /// @notice Internal version of the `setApprovalForAll` function\n /// @dev It contains an `approver` field to be used in case someone signs a permit for a particular\n /// address, and this signature is given to the contract by another address (like a router)\n function _setApprovalForAll(address approver, address operator, bool approved) internal {\n if (operator == approver) revert ApprovalToCaller();\n uint256 approval = approved ? 1 : 0;\n _operatorApprovals[approver][operator] = approval;\n emit ApprovalForAll(approver, operator, approved);\n }\n\n /// @notice Internal function to invoke {IERC721Receiver-onERC721Received} on a target address\n /// The call is not executed if the target address is not a contract\n /// @param from Address representing the previous owner of the given token ID\n /// @param to Target address that will receive the tokens\n /// @param vaultID ID of the token to be transferred\n /// @param _data Bytes optional data to send along with the call\n /// @return Bool whether the call correctly returned the expected value\n function _checkOnERC721Received(\n address from,\n address to,\n uint256 vaultID,\n bytes memory _data\n ) private returns (bool) {\n if (to.isContract()) {\n try IERC721ReceiverUpgradeable(to).onERC721Received(msg.sender, from, vaultID, _data) returns (\n bytes4 retval\n ) {\n return retval == IERC721ReceiverUpgradeable.onERC721Received.selector;\n } catch (bytes memory reason) {\n if (reason.length == 0) {\n revert NonERC721Receiver();\n } else {\n // solhint-disable-next-line no-inline-assembly\n assembly {\n revert(add(32, reason), mload(reason))\n }\n }\n }\n } else {\n return true;\n }\n }\n\n /// @notice Hook that is called before any token transfer. This includes minting and burning.\n /// Calling conditions:\n ///\n /// - When `from` and `to` are both non-zero, `from`'s `vaultID` will be\n /// transferred to `to`.\n /// - When `from` is zero, `vaultID` will be minted for `to`.\n /// - When `to` is zero, `from`'s `vaultID` will be burned.\n /// - `from` and `to` are never both zero.\n function _beforeTokenTransfer(address from, address to, uint256 vaultID) internal virtual {}\n\n /// @notice Get `whitelistingActivated` in storage only if needed\n function _whitelistingActivated() internal view virtual returns (bool) {\n return whitelistingActivated;\n }\n}\n" + }, + "contracts/vaultManager/VaultManagerPermit.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\nimport \"./VaultManagerERC721.sol\";\nimport \"../interfaces/external/IERC1271.sol\";\n\n/// @title VaultManagerPermit\n/// @author Angle Labs, Inc.\n/// @dev Base Implementation of permit functions for the `VaultManager` contract\nabstract contract VaultManagerPermit is Initializable, VaultManagerERC721 {\n using Address for address;\n\n mapping(address => uint256) private _nonces;\n /* solhint-disable var-name-mixedcase */\n bytes32 private _HASHED_NAME;\n bytes32 private _HASHED_VERSION;\n bytes32 private _PERMIT_TYPEHASH;\n /* solhint-enable var-name-mixedcase */\n\n error ExpiredDeadline();\n error InvalidSignature();\n\n //solhint-disable-next-line\n function __ERC721Permit_init(string memory _name) internal onlyInitializing {\n _PERMIT_TYPEHASH = keccak256(\n \"Permit(address owner,address spender,bool approved,uint256 nonce,uint256 deadline)\"\n );\n _HASHED_NAME = keccak256(bytes(_name));\n _HASHED_VERSION = keccak256(bytes(\"1\"));\n }\n\n /// @notice Allows an address to give or revoke approval for all its vaults to another address\n /// @param owner Address signing the permit and giving (or revoking) its approval for all the controlled vaults\n /// @param spender Address to give approval to\n /// @param approved Whether to give or revoke the approval\n /// @param deadline Deadline parameter for the signature to be valid\n /// @dev The `v`, `r`, and `s` parameters are used as signature data\n function permit(\n address owner,\n address spender,\n bool approved,\n uint256 deadline,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) external {\n if (block.timestamp > deadline) revert ExpiredDeadline();\n // Additional signature checks performed in the `ECDSAUpgradeable.recover` function\n if (uint256(s) > 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D576E7357A4501DDFE92F46681B20A0 || (v != 27 && v != 28))\n revert InvalidSignature();\n\n bytes32 digest = keccak256(\n abi.encodePacked(\n \"\\x19\\x01\",\n _domainSeparatorV4(),\n keccak256(\n abi.encode(\n _PERMIT_TYPEHASH,\n // 0x3f43a9c6bafb5c7aab4e0cfe239dc5d4c15caf0381c6104188191f78a6640bd8,\n owner,\n spender,\n approved,\n _useNonce(owner),\n deadline\n )\n )\n )\n );\n if (owner.isContract()) {\n if (IERC1271(owner).isValidSignature(digest, abi.encodePacked(r, s, v)) != 0x1626ba7e)\n revert InvalidSignature();\n } else {\n address signer = ecrecover(digest, v, r, s);\n if (signer != owner || signer == address(0)) revert InvalidSignature();\n }\n\n _setApprovalForAll(owner, spender, approved);\n }\n\n /// @notice Returns the current nonce for an `owner` address\n function nonces(address owner) public view returns (uint256) {\n return _nonces[owner];\n }\n\n /// @notice Returns the domain separator for the current chain.\n // solhint-disable-next-line func-name-mixedcase\n function DOMAIN_SEPARATOR() external view returns (bytes32) {\n return _domainSeparatorV4();\n }\n\n /// @notice Internal version of the `DOMAIN_SEPARATOR` function\n function _domainSeparatorV4() internal view returns (bytes32) {\n return\n keccak256(\n abi.encode(\n // keccak256('EIP712Domain(string name,string version,uint256 chainId,address verifyingContract)')\n 0x8b73c3c69bb8fe3d512ecc4cf759cc79239f7b179b0ffacaa9a75d522b39400f,\n _HASHED_NAME,\n _HASHED_VERSION,\n block.chainid,\n address(this)\n )\n );\n }\n\n /// @notice Consumes a nonce for an address: returns the current value and increments it\n function _useNonce(address owner) internal returns (uint256 current) {\n current = _nonces[owner];\n _nonces[owner] = current + 1;\n }\n\n uint256[49] private __gap;\n}\n" + }, + "contracts/vaultManager/VaultManagerStorage.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\nimport \"@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/token/ERC20/extensions/draft-IERC20PermitUpgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/token/ERC721/IERC721ReceiverUpgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/interfaces/IERC721MetadataUpgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/utils/introspection/IERC165Upgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/utils/AddressUpgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/security/ReentrancyGuardUpgradeable.sol\";\nimport \"@openzeppelin/contracts/token/ERC20/extensions/IERC20Metadata.sol\";\nimport \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\nimport \"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\";\n\nimport \"../interfaces/IAgToken.sol\";\nimport \"../interfaces/IOracle.sol\";\nimport \"../interfaces/ISwapper.sol\";\nimport \"../interfaces/ITreasury.sol\";\nimport \"../interfaces/IVaultManager.sol\";\nimport \"../interfaces/governance/IVeBoostProxy.sol\";\n\n/// @title VaultManagerStorage\n/// @author Angle Labs, Inc.\n/// @dev Variables, references, parameters and events needed in the `VaultManager` contract\n// solhint-disable-next-line max-states-count\ncontract VaultManagerStorage is IVaultManagerStorage, Initializable, ReentrancyGuardUpgradeable {\n /// @notice Base used for parameter computation: almost all the parameters of this contract are set in `BASE_PARAMS`\n uint256 public constant BASE_PARAMS = 10 ** 9;\n /// @notice Base used for interest rate computation\n uint256 public constant BASE_INTEREST = 10 ** 27;\n /// @notice Used for interest rate computation\n uint256 public constant HALF_BASE_INTEREST = 10 ** 27 / 2;\n\n // ================================= REFERENCES ================================\n\n /// @inheritdoc IVaultManagerStorage\n ITreasury public treasury;\n /// @inheritdoc IVaultManagerStorage\n IERC20 public collateral;\n /// @inheritdoc IVaultManagerStorage\n IAgToken public stablecoin;\n /// @inheritdoc IVaultManagerStorage\n IOracle public oracle;\n /// @notice Reference to the contract which computes adjusted veANGLE balances for liquidators boosts\n IVeBoostProxy public veBoostProxy;\n /// @notice Base of the collateral\n uint256 internal _collatBase;\n\n // ================================= PARAMETERS ================================\n // Unless specified otherwise, parameters of this contract are expressed in `BASE_PARAMS`\n\n /// @notice Maximum amount of stablecoins that can be issued with this contract (in `BASE_TOKENS`). This parameter should\n /// not be bigger than `type(uint256).max / BASE_INTEREST` otherwise there may be some overflows in the `increaseDebt` function\n uint256 public debtCeiling;\n /// @notice Threshold veANGLE balance values for the computation of the boost for liquidators: the length of this array\n /// should normally be 2. The base of the x-values in this array should be `BASE_TOKENS`\n uint256[] public xLiquidationBoost;\n /// @notice Values of the liquidation boost at the threshold values of x\n uint256[] public yLiquidationBoost;\n /// @inheritdoc IVaultManagerStorage\n uint64 public collateralFactor;\n /// @notice Maximum Health factor at which a vault can end up after a liquidation (unless it's fully liquidated)\n uint64 public targetHealthFactor;\n /// @notice Upfront fee taken when borrowing stablecoins: this fee is optional and should in practice not be used\n uint64 public borrowFee;\n /// @notice Upfront fee taken when repaying stablecoins: this fee is optional as well. It should be smaller\n /// than the liquidation surcharge (cf below) to avoid exploits where people voluntarily get liquidated at a 0\n /// discount to pay smaller repaying fees\n uint64 public repayFee;\n /// @notice Per second interest taken to borrowers taking agToken loans. Contrarily to other parameters, it is set in `BASE_INTEREST`\n /// that is to say in base 10**27\n uint64 public interestRate;\n /// @notice Fee taken by the protocol during a liquidation. Technically, this value is not the fee per se, it's 1 - fee.\n /// For instance for a 2% fee, `liquidationSurcharge` should be 98%\n uint64 public liquidationSurcharge;\n /// @notice Maximum discount given to liquidators\n uint64 public maxLiquidationDiscount;\n /// @notice Whether whitelisting is required to own a vault or not\n bool public whitelistingActivated;\n /// @notice Whether the contract is paused or not\n bool public paused;\n\n // ================================= VARIABLES =================================\n\n /// @notice Timestamp at which the `interestAccumulator` was updated\n uint256 public lastInterestAccumulatorUpdated;\n /// @inheritdoc IVaultManagerStorage\n uint256 public interestAccumulator;\n /// @inheritdoc IVaultManagerStorage\n uint256 public totalNormalizedDebt;\n /// @notice Surplus accumulated by the contract: surplus is always in stablecoins, and is then reset\n /// when the value is communicated to the treasury contract\n uint256 public surplus;\n /// @notice Bad debt made from liquidated vaults which ended up having no collateral and a positive amount\n /// of stablecoins\n uint256 public badDebt;\n\n // ================================== MAPPINGS =================================\n\n /// @inheritdoc IVaultManagerStorage\n mapping(uint256 => Vault) public vaultData;\n /// @notice Maps an address to 1 if it's whitelisted and can open or own a vault\n mapping(address => uint256) public isWhitelisted;\n\n // ================================ ERC721 DATA ================================\n\n /// @inheritdoc IVaultManagerStorage\n uint256 public vaultIDCount;\n\n /// @notice URI\n string internal _baseURI;\n\n // Mapping from `vaultID` to owner address\n mapping(uint256 => address) internal _owners;\n\n // Mapping from owner address to vault owned count\n mapping(address => uint256) internal _balances;\n\n // Mapping from `vaultID` to approved address\n mapping(uint256 => address) internal _vaultApprovals;\n\n // Mapping from owner to operator approvals\n mapping(address => mapping(address => uint256)) internal _operatorApprovals;\n\n uint256[50] private __gap;\n\n // =================================== EVENTS ==================================\n\n event AccruedToTreasury(uint256 surplusEndValue, uint256 badDebtEndValue);\n event CollateralAmountUpdated(uint256 vaultID, uint256 collateralAmount, uint8 isIncrease);\n event InterestAccumulatorUpdated(uint256 value, uint256 timestamp);\n event InternalDebtUpdated(uint256 vaultID, uint256 internalAmount, uint8 isIncrease);\n event FiledUint64(uint64 param, bytes32 what);\n event DebtCeilingUpdated(uint256 debtCeiling);\n event LiquidationBoostParametersUpdated(address indexed _veBoostProxy, uint256[] xBoost, uint256[] yBoost);\n event LiquidatedVaults(uint256[] vaultIDs);\n event DebtTransferred(uint256 srcVaultID, uint256 dstVaultID, address dstVaultManager, uint256 amount);\n\n // =================================== ERRORS ==================================\n\n error ApprovalToOwner();\n error ApprovalToCaller();\n error DustyLeftoverAmount();\n error DebtCeilingExceeded();\n error HealthyVault();\n error IncompatibleLengths();\n error InsolventVault();\n error InvalidParameterValue();\n error InvalidParameterType();\n error InvalidSetOfParameters();\n error InvalidTreasury();\n error NonERC721Receiver();\n error NonexistentVault();\n error NotApproved();\n error NotGovernor();\n error NotGovernorOrGuardian();\n error NotTreasury();\n error NotWhitelisted();\n error NotVaultManager();\n error Paused();\n error TooHighParameterValue();\n error TooSmallParameterValue();\n error ZeroAddress();\n\n /// @custom:oz-upgrades-unsafe-allow constructor\n constructor() initializer {}\n}\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 1000000 + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers", + "metadata", + "devdoc", + "userdoc", + "storageLayout", + "evm.gasEstimates", + "devdoc", + "userdoc" + ], + "": [ + "ast" + ] + } + }, + "metadata": { + "useLiteralContent": true + } + } +} \ No newline at end of file diff --git a/deployments/celo/AgTokenSideChainMultiBridge_Implementation.json b/deployments/celo/AgTokenSideChainMultiBridge_Implementation.json new file mode 100644 index 00000000..c6e49429 --- /dev/null +++ b/deployments/celo/AgTokenSideChainMultiBridge_Implementation.json @@ -0,0 +1,1856 @@ +{ + "address": "0x656B80B667a46869144047E6e6C0000C81610253", + "abi": [ + { + "inputs": [], + "name": "AssetStillControlledInReserves", + "type": "error" + }, + { + "inputs": [], + "name": "BurnAmountExceedsAllowance", + "type": "error" + }, + { + "inputs": [], + "name": "HourlyLimitExceeded", + "type": "error" + }, + { + "inputs": [], + "name": "InvalidSender", + "type": "error" + }, + { + "inputs": [], + "name": "InvalidToken", + "type": "error" + }, + { + "inputs": [], + "name": "InvalidTreasury", + "type": "error" + }, + { + "inputs": [], + "name": "NotGovernor", + "type": "error" + }, + { + "inputs": [], + "name": "NotGovernorOrGuardian", + "type": "error" + }, + { + "inputs": [], + "name": "NotMinter", + "type": "error" + }, + { + "inputs": [], + "name": "NotTreasury", + "type": "error" + }, + { + "inputs": [], + "name": "TooBigAmount", + "type": "error" + }, + { + "inputs": [], + "name": "TooHighParameterValue", + "type": "error" + }, + { + "inputs": [], + "name": "ZeroAddress", + "type": "error" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "owner", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "spender", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "value", + "type": "uint256" + } + ], + "name": "Approval", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "bridgeToken", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "limit", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "hourlyLimit", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint64", + "name": "fee", + "type": "uint64" + }, + { + "indexed": false, + "internalType": "bool", + "name": "paused", + "type": "bool" + } + ], + "name": "BridgeTokenAdded", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "bridgeToken", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint64", + "name": "fee", + "type": "uint64" + } + ], + "name": "BridgeTokenFeeUpdated", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "bridgeToken", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "hourlyLimit", + "type": "uint256" + } + ], + "name": "BridgeTokenHourlyLimitUpdated", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "bridgeToken", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "limit", + "type": "uint256" + } + ], + "name": "BridgeTokenLimitUpdated", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "bridgeToken", + "type": "address" + } + ], + "name": "BridgeTokenRemoved", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "bridgeToken", + "type": "address" + }, + { + "indexed": false, + "internalType": "bool", + "name": "toggleStatus", + "type": "bool" + } + ], + "name": "BridgeTokenToggled", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "theAddress", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "toggleStatus", + "type": "uint256" + } + ], + "name": "FeeToggled", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint256", + "name": "hourlyLimit", + "type": "uint256" + } + ], + "name": "HourlyLimitUpdated", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint8", + "name": "version", + "type": "uint8" + } + ], + "name": "Initialized", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "minter", + "type": "address" + } + ], + "name": "MinterToggled", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "token", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "Recovered", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "from", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "value", + "type": "uint256" + } + ], + "name": "Transfer", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "_treasury", + "type": "address" + } + ], + "name": "TreasuryUpdated", + "type": "event" + }, + { + "inputs": [], + "name": "BASE_PARAMS", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "DOMAIN_SEPARATOR", + "outputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "bridgeToken", + "type": "address" + }, + { + "internalType": "uint256", + "name": "limit", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "hourlyLimit", + "type": "uint256" + }, + { + "internalType": "uint64", + "name": "fee", + "type": "uint64" + }, + { + "internalType": "bool", + "name": "paused", + "type": "bool" + } + ], + "name": "addBridgeToken", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "minter", + "type": "address" + } + ], + "name": "addMinter", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "allBridgeTokens", + "outputs": [ + { + "internalType": "address[]", + "name": "", + "type": "address[]" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "owner", + "type": "address" + }, + { + "internalType": "address", + "name": "spender", + "type": "address" + } + ], + "name": "allowance", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "spender", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "approve", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "balanceOf", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "name": "bridgeTokensList", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "bridges", + "outputs": [ + { + "internalType": "uint256", + "name": "limit", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "hourlyLimit", + "type": "uint256" + }, + { + "internalType": "uint64", + "name": "fee", + "type": "uint64" + }, + { + "internalType": "bool", + "name": "allowed", + "type": "bool" + }, + { + "internalType": "bool", + "name": "paused", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + }, + { + "internalType": "address", + "name": "burner", + "type": "address" + }, + { + "internalType": "address", + "name": "sender", + "type": "address" + } + ], + "name": "burnFrom", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + }, + { + "internalType": "address", + "name": "burner", + "type": "address" + } + ], + "name": "burnSelf", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "burnStablecoin", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "chainTotalHourlyLimit", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "name": "chainTotalUsage", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "currentTotalUsage", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "bridgeToken", + "type": "address" + } + ], + "name": "currentUsage", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "decimals", + "outputs": [ + { + "internalType": "uint8", + "name": "", + "type": "uint8" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "spender", + "type": "address" + }, + { + "internalType": "uint256", + "name": "subtractedValue", + "type": "uint256" + } + ], + "name": "decreaseAllowance", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "spender", + "type": "address" + }, + { + "internalType": "uint256", + "name": "addedValue", + "type": "uint256" + } + ], + "name": "increaseAllowance", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "string", + "name": "name_", + "type": "string" + }, + { + "internalType": "string", + "name": "symbol_", + "type": "string" + }, + { + "internalType": "address", + "name": "_treasury", + "type": "address" + } + ], + "name": "initialize", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "isFeeExempt", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "isMinter", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "account", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "mint", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "name", + "outputs": [ + { + "internalType": "string", + "name": "", + "type": "string" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "owner", + "type": "address" + } + ], + "name": "nonces", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "owner", + "type": "address" + }, + { + "internalType": "address", + "name": "spender", + "type": "address" + }, + { + "internalType": "uint256", + "name": "value", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "deadline", + "type": "uint256" + }, + { + "internalType": "uint8", + "name": "v", + "type": "uint8" + }, + { + "internalType": "bytes32", + "name": "r", + "type": "bytes32" + }, + { + "internalType": "bytes32", + "name": "s", + "type": "bytes32" + } + ], + "name": "permit", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "tokenAddress", + "type": "address" + }, + { + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amountToRecover", + "type": "uint256" + } + ], + "name": "recoverERC20", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "bridgeToken", + "type": "address" + } + ], + "name": "removeBridgeToken", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "minter", + "type": "address" + } + ], + "name": "removeMinter", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "hourlyLimit", + "type": "uint256" + } + ], + "name": "setChainTotalHourlyLimit", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "bridgeToken", + "type": "address" + }, + { + "internalType": "uint256", + "name": "hourlyLimit", + "type": "uint256" + } + ], + "name": "setHourlyLimit", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "bridgeToken", + "type": "address" + }, + { + "internalType": "uint256", + "name": "limit", + "type": "uint256" + } + ], + "name": "setLimit", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "bridgeToken", + "type": "address" + }, + { + "internalType": "uint64", + "name": "fee", + "type": "uint64" + } + ], + "name": "setSwapFee", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_treasury", + "type": "address" + } + ], + "name": "setTreasury", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "bridgeToken", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + }, + { + "internalType": "address", + "name": "to", + "type": "address" + } + ], + "name": "swapIn", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "bridgeToken", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + }, + { + "internalType": "address", + "name": "to", + "type": "address" + } + ], + "name": "swapOut", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "symbol", + "outputs": [ + { + "internalType": "string", + "name": "", + "type": "string" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "bridgeToken", + "type": "address" + } + ], + "name": "toggleBridge", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "theAddress", + "type": "address" + } + ], + "name": "toggleFeesForAddress", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "totalSupply", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "transfer", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "from", + "type": "address" + }, + { + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "transferFrom", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "treasury", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + }, + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "name": "usage", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + } + ], + "transactionHash": "0xf3d1b512169afbdb6e5441a7d19bca843f757e52d003c43bff9baf9b7629c3eb", + "receipt": { + "to": null, + "from": "0xfdA462548Ce04282f4B6D6619823a7C64Fdc0185", + "contractAddress": "0x656B80B667a46869144047E6e6C0000C81610253", + "transactionIndex": 25, + "gasUsed": "3964995", + "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000080000000000000000000000000000000002000000000000400000000000000000000000000000000000000000000000000200000000000040000000000000000000040000000000000000000000000000000000000000000000000000000000000000000000000000000", + "blockHash": "0x580f93cd110273e4aaf5b8ee30f5af65c0aae95472f9a3238e2d930ff5dcdf26", + "transactionHash": "0xf3d1b512169afbdb6e5441a7d19bca843f757e52d003c43bff9baf9b7629c3eb", + "logs": [ + { + "transactionIndex": 25, + "blockNumber": 23443573, + "transactionHash": "0xf3d1b512169afbdb6e5441a7d19bca843f757e52d003c43bff9baf9b7629c3eb", + "address": "0x656B80B667a46869144047E6e6C0000C81610253", + "topics": [ + "0x7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb3847402498" + ], + "data": "0x0000000000000000000000000000000000000000000000000000000000000001", + "logIndex": 45, + "blockHash": "0x580f93cd110273e4aaf5b8ee30f5af65c0aae95472f9a3238e2d930ff5dcdf26" + } + ], + "blockNumber": 23443573, + "cumulativeGasUsed": "6142149", + "status": 1, + "byzantium": true + }, + "args": [], + "numDeployments": 1, + "solcInputHash": "871924e0c138825a2736b76def8fef8d", + "metadata": "{\"compiler\":{\"version\":\"0.8.17+commit.8df45f5f\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[],\"name\":\"AssetStillControlledInReserves\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"BurnAmountExceedsAllowance\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"HourlyLimitExceeded\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidSender\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidToken\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidTreasury\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"NotGovernor\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"NotGovernorOrGuardian\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"NotMinter\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"NotTreasury\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"TooBigAmount\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"TooHighParameterValue\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ZeroAddress\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"spender\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"}],\"name\":\"Approval\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"bridgeToken\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"limit\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"hourlyLimit\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"fee\",\"type\":\"uint64\"},{\"indexed\":false,\"internalType\":\"bool\",\"name\":\"paused\",\"type\":\"bool\"}],\"name\":\"BridgeTokenAdded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"bridgeToken\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"fee\",\"type\":\"uint64\"}],\"name\":\"BridgeTokenFeeUpdated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"bridgeToken\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"hourlyLimit\",\"type\":\"uint256\"}],\"name\":\"BridgeTokenHourlyLimitUpdated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"bridgeToken\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"limit\",\"type\":\"uint256\"}],\"name\":\"BridgeTokenLimitUpdated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"bridgeToken\",\"type\":\"address\"}],\"name\":\"BridgeTokenRemoved\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"bridgeToken\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"bool\",\"name\":\"toggleStatus\",\"type\":\"bool\"}],\"name\":\"BridgeTokenToggled\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"theAddress\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"toggleStatus\",\"type\":\"uint256\"}],\"name\":\"FeeToggled\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"hourlyLimit\",\"type\":\"uint256\"}],\"name\":\"HourlyLimitUpdated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint8\",\"name\":\"version\",\"type\":\"uint8\"}],\"name\":\"Initialized\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"minter\",\"type\":\"address\"}],\"name\":\"MinterToggled\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"Recovered\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"}],\"name\":\"Transfer\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"_treasury\",\"type\":\"address\"}],\"name\":\"TreasuryUpdated\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"BASE_PARAMS\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"DOMAIN_SEPARATOR\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"bridgeToken\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"limit\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"hourlyLimit\",\"type\":\"uint256\"},{\"internalType\":\"uint64\",\"name\":\"fee\",\"type\":\"uint64\"},{\"internalType\":\"bool\",\"name\":\"paused\",\"type\":\"bool\"}],\"name\":\"addBridgeToken\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"minter\",\"type\":\"address\"}],\"name\":\"addMinter\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"allBridgeTokens\",\"outputs\":[{\"internalType\":\"address[]\",\"name\":\"\",\"type\":\"address[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"spender\",\"type\":\"address\"}],\"name\":\"allowance\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"spender\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"approve\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"}],\"name\":\"balanceOf\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"name\":\"bridgeTokensList\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"bridges\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"limit\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"hourlyLimit\",\"type\":\"uint256\"},{\"internalType\":\"uint64\",\"name\":\"fee\",\"type\":\"uint64\"},{\"internalType\":\"bool\",\"name\":\"allowed\",\"type\":\"bool\"},{\"internalType\":\"bool\",\"name\":\"paused\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"burner\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"}],\"name\":\"burnFrom\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"burner\",\"type\":\"address\"}],\"name\":\"burnSelf\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"burnStablecoin\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"chainTotalHourlyLimit\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"name\":\"chainTotalUsage\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"currentTotalUsage\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"bridgeToken\",\"type\":\"address\"}],\"name\":\"currentUsage\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"decimals\",\"outputs\":[{\"internalType\":\"uint8\",\"name\":\"\",\"type\":\"uint8\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"spender\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"subtractedValue\",\"type\":\"uint256\"}],\"name\":\"decreaseAllowance\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"spender\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"addedValue\",\"type\":\"uint256\"}],\"name\":\"increaseAllowance\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"string\",\"name\":\"name_\",\"type\":\"string\"},{\"internalType\":\"string\",\"name\":\"symbol_\",\"type\":\"string\"},{\"internalType\":\"address\",\"name\":\"_treasury\",\"type\":\"address\"}],\"name\":\"initialize\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"isFeeExempt\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"isMinter\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"mint\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"name\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"}],\"name\":\"nonces\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"spender\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"deadline\",\"type\":\"uint256\"},{\"internalType\":\"uint8\",\"name\":\"v\",\"type\":\"uint8\"},{\"internalType\":\"bytes32\",\"name\":\"r\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32\",\"name\":\"s\",\"type\":\"bytes32\"}],\"name\":\"permit\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"tokenAddress\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amountToRecover\",\"type\":\"uint256\"}],\"name\":\"recoverERC20\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"bridgeToken\",\"type\":\"address\"}],\"name\":\"removeBridgeToken\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"minter\",\"type\":\"address\"}],\"name\":\"removeMinter\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"hourlyLimit\",\"type\":\"uint256\"}],\"name\":\"setChainTotalHourlyLimit\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"bridgeToken\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"hourlyLimit\",\"type\":\"uint256\"}],\"name\":\"setHourlyLimit\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"bridgeToken\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"limit\",\"type\":\"uint256\"}],\"name\":\"setLimit\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"bridgeToken\",\"type\":\"address\"},{\"internalType\":\"uint64\",\"name\":\"fee\",\"type\":\"uint64\"}],\"name\":\"setSwapFee\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_treasury\",\"type\":\"address\"}],\"name\":\"setTreasury\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"bridgeToken\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"swapIn\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"bridgeToken\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"swapOut\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"symbol\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"bridgeToken\",\"type\":\"address\"}],\"name\":\"toggleBridge\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"theAddress\",\"type\":\"address\"}],\"name\":\"toggleFeesForAddress\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"totalSupply\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"transfer\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"transferFrom\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"treasury\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"name\":\"usage\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"}],\"devdoc\":{\"author\":\"Angle Labs, Inc.\",\"details\":\"This contract supports bridge tokens having a minting right on the stablecoin (also referred to as the canonical or the native token)\",\"kind\":\"dev\",\"methods\":{\"DOMAIN_SEPARATOR()\":{\"details\":\"See {IERC20Permit-DOMAIN_SEPARATOR}.\"},\"addBridgeToken(address,uint256,uint256,uint64,bool)\":{\"params\":{\"bridgeToken\":\"Bridge token to add: it should be a version of the stablecoin from another bridge\",\"fee\":\"Fee taken upon swapping for or against this token\",\"hourlyLimit\":\"Limit on the hourly volume for this bridge\",\"limit\":\"Limit on the balance of bridge token this contract could hold\",\"paused\":\"Whether swapping for this token should be paused or not\"}},\"addMinter(address)\":{\"details\":\"Zero address checks are performed directly in the `Treasury` contract\",\"params\":{\"minter\":\"Minter address to add\"}},\"allBridgeTokens()\":{\"details\":\"Helpful for UIs\"},\"allowance(address,address)\":{\"details\":\"See {IERC20-allowance}.\"},\"approve(address,uint256)\":{\"details\":\"See {IERC20-approve}. NOTE: If `amount` is the maximum `uint256`, the allowance is not updated on `transferFrom`. This is semantically equivalent to an infinite approval. Requirements: - `spender` cannot be the zero address.\"},\"balanceOf(address)\":{\"details\":\"See {IERC20-balanceOf}.\"},\"burnFrom(uint256,address,address)\":{\"details\":\"This method is to be called by a contract with the minter right after being requested to do so by a `sender` address willing to burn tokens from another `burner` addressThe method checks the allowance between the `sender` and the `burner`\",\"params\":{\"amount\":\"Amount of tokens to burn\",\"burner\":\"Address to burn from\",\"sender\":\"Address which requested the burn from `burner`\"}},\"burnSelf(uint256,address)\":{\"details\":\"This method is to be called by a contract with a minter right on the AgToken after being requested to do so by an address willing to burn tokens from its address\",\"params\":{\"amount\":\"Amount of tokens to burn\",\"burner\":\"Address to burn from\"}},\"burnStablecoin(uint256)\":{\"details\":\"This function can typically be called if there is a settlement mechanism to burn stablecoins\",\"params\":{\"amount\":\"Amount of stablecoins to burn\"}},\"currentTotalUsage()\":{\"details\":\"Helpful for UIs\"},\"currentUsage(address)\":{\"details\":\"Helpful for UIs\",\"params\":{\"bridgeToken\":\"Bridge used to mint\"}},\"decimals()\":{\"details\":\"Returns the number of decimals used to get its user representation. For example, if `decimals` equals `2`, a balance of `505` tokens should be displayed to a user as `5.05` (`505 / 10 ** 2`). Tokens usually opt for a value of 18, imitating the relationship between Ether and Wei. This is the value {ERC20} uses, unless this function is overridden; NOTE: This information is only used for _display_ purposes: it in no way affects any of the arithmetic of the contract, including {IERC20-balanceOf} and {IERC20-transfer}.\"},\"decreaseAllowance(address,uint256)\":{\"details\":\"Atomically decreases the allowance granted to `spender` by the caller. This is an alternative to {approve} that can be used as a mitigation for problems described in {IERC20-approve}. Emits an {Approval} event indicating the updated allowance. Requirements: - `spender` cannot be the zero address. - `spender` must have allowance for the caller of at least `subtractedValue`.\"},\"increaseAllowance(address,uint256)\":{\"details\":\"Atomically increases the allowance granted to `spender` by the caller. This is an alternative to {approve} that can be used as a mitigation for problems described in {IERC20-approve}. Emits an {Approval} event indicating the updated allowance. Requirements: - `spender` cannot be the zero address.\"},\"mint(address,uint256)\":{\"details\":\"The contracts allowed to issue agTokens are the `StableMaster` contract, `VaultManager` contracts associated to this stablecoin as well as the flash loan module (if activated) and potentially contracts whitelisted by governance\",\"params\":{\"account\":\"Address to mint to\",\"amount\":\"Amount to mint\"}},\"name()\":{\"details\":\"Returns the name of the token.\"},\"nonces(address)\":{\"details\":\"See {IERC20Permit-nonces}.\"},\"permit(address,address,uint256,uint256,uint8,bytes32,bytes32)\":{\"details\":\"See {IERC20Permit-permit}.\"},\"recoverERC20(address,address,uint256)\":{\"details\":\"Can be used to withdraw bridge tokens for them to be de-bridged on mainnet\"},\"removeBridgeToken(address)\":{\"params\":{\"bridgeToken\":\"Address of the bridge token to remove support for\"}},\"removeMinter(address)\":{\"details\":\"This function can also be called by a minter wishing to revoke itself\",\"params\":{\"minter\":\"Minter address to remove\"}},\"setTreasury(address)\":{\"params\":{\"_treasury\":\"New treasury address\"}},\"swapIn(address,uint256,address)\":{\"details\":\"Some fees may be taken by the protocol depending on the token used and on the address calling\",\"params\":{\"amount\":\"Amount of bridge tokens to send\",\"bridgeToken\":\"Bridge token to use to mint\",\"to\":\"Address to which the stablecoin should be sent\"},\"returns\":{\"_0\":\"Amount of the canonical stablecoin actually minted\"}},\"swapOut(address,uint256,address)\":{\"details\":\"Some fees may be taken by the protocol depending on the token used and on the address calling\",\"params\":{\"amount\":\"Amount of canonical tokens to burn\",\"bridgeToken\":\"Bridge token required\",\"to\":\"Address to which the bridge token should be sent\"},\"returns\":{\"_0\":\"Amount of bridge tokens actually sent back\"}},\"symbol()\":{\"details\":\"Returns the symbol of the token, usually a shorter version of the name.\"},\"totalSupply()\":{\"details\":\"See {IERC20-totalSupply}.\"},\"transfer(address,uint256)\":{\"details\":\"See {IERC20-transfer}. Requirements: - `to` cannot be the zero address. - the caller must have a balance of at least `amount`.\"},\"transferFrom(address,address,uint256)\":{\"details\":\"See {IERC20-transferFrom}. Emits an {Approval} event indicating the updated allowance. This is not required by the EIP. See the note at the beginning of {ERC20}. NOTE: Does not update the allowance if the current allowance is the maximum `uint256`. Requirements: - `from` and `to` cannot be the zero address. - `from` must have a balance of at least `amount`. - the caller must have allowance for ``from``'s tokens of at least `amount`.\"}},\"title\":\"AgTokenSideChainMultiBridge\",\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{\"BASE_PARAMS()\":{\"notice\":\"Base used for fee computation\"},\"addBridgeToken(address,uint256,uint256,uint64,bool)\":{\"notice\":\"Adds support for a bridge token\"},\"addMinter(address)\":{\"notice\":\"Adds a minter in the contract\"},\"allBridgeTokens()\":{\"notice\":\"Returns the list of all supported bridge tokens\"},\"bridgeTokensList(uint256)\":{\"notice\":\"List of all bridge tokens\"},\"bridges(address)\":{\"notice\":\"Maps a bridge token to data\"},\"burnFrom(uint256,address,address)\":{\"notice\":\"Burns `amount` tokens from a `burner` address after being asked to by `sender`\"},\"burnSelf(uint256,address)\":{\"notice\":\"Burns `amount` tokens from a `burner` address\"},\"burnStablecoin(uint256)\":{\"notice\":\"Allows anyone to burn stablecoins\"},\"chainTotalHourlyLimit()\":{\"notice\":\"Limit to the amount of tokens that can be sent from that chain to another chain\"},\"chainTotalUsage(uint256)\":{\"notice\":\"Usage per hour on that chain. Maps an hourly timestamp to the total volume swapped out on the chain\"},\"currentTotalUsage()\":{\"notice\":\"Returns the current total volume on the chain for the current hour\"},\"currentUsage(address)\":{\"notice\":\"Returns the current volume for a bridge, for the current hour\"},\"initialize(string,string,address)\":{\"notice\":\"Initializes the `AgToken` contract\"},\"isFeeExempt(address)\":{\"notice\":\"Maps an address to whether it is exempt of fees for when it comes to swapping in and out\"},\"isMinter(address)\":{\"notice\":\"Checks whether an address has the right to mint agTokens\"},\"mint(address,uint256)\":{\"notice\":\"Lets the `StableMaster` contract or another whitelisted contract mint agTokens\"},\"recoverERC20(address,address,uint256)\":{\"notice\":\"Recovers any ERC20 token\"},\"removeBridgeToken(address)\":{\"notice\":\"Removes support for a token\"},\"removeMinter(address)\":{\"notice\":\"Removes a minter from the contract\"},\"setChainTotalHourlyLimit(uint256)\":{\"notice\":\"Updates the `chainTotalHourlyLimit` amount\"},\"setHourlyLimit(address,uint256)\":{\"notice\":\"Updates the `hourlyLimit` amount for `bridgeToken`\"},\"setLimit(address,uint256)\":{\"notice\":\"Updates the `limit` amount for `bridgeToken`\"},\"setSwapFee(address,uint64)\":{\"notice\":\"Updates the `fee` value for `bridgeToken`\"},\"setTreasury(address)\":{\"notice\":\"Sets a new treasury contract\"},\"swapIn(address,uint256,address)\":{\"notice\":\"Mints the canonical token from a supported bridge token\"},\"swapOut(address,uint256,address)\":{\"notice\":\"Burns the canonical token in exchange for a bridge token\"},\"toggleBridge(address)\":{\"notice\":\"Pauses or unpauses swapping in and out for a token\"},\"toggleFeesForAddress(address)\":{\"notice\":\"Toggles fees for the address `theAddress`\"},\"treasury()\":{\"notice\":\"Reference to the treasury contract which can grant minting rights\"},\"usage(address,uint256)\":{\"notice\":\"Maps a bridge token to the associated hourly volume\"}},\"notice\":\"Contract for Angle agTokens on other chains than Ethereum mainnet\",\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/agToken/AgTokenSideChainMultiBridge.sol\":\"AgTokenSideChainMultiBridge\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":1000000},\"remappings\":[]},\"sources\":{\"@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.7.0) (proxy/utils/Initializable.sol)\\n\\npragma solidity ^0.8.2;\\n\\nimport \\\"../../utils/AddressUpgradeable.sol\\\";\\n\\n/**\\n * @dev This is a base contract to aid in writing upgradeable contracts, or any kind of contract that will be deployed\\n * behind a proxy. Since proxied contracts do not make use of a constructor, it's common to move constructor logic to an\\n * external initializer function, usually called `initialize`. It then becomes necessary to protect this initializer\\n * function so it can only be called once. The {initializer} modifier provided by this contract will have this effect.\\n *\\n * The initialization functions use a version number. Once a version number is used, it is consumed and cannot be\\n * reused. This mechanism prevents re-execution of each \\\"step\\\" but allows the creation of new initialization steps in\\n * case an upgrade adds a module that needs to be initialized.\\n *\\n * For example:\\n *\\n * [.hljs-theme-light.nopadding]\\n * ```\\n * contract MyToken is ERC20Upgradeable {\\n * function initialize() initializer public {\\n * __ERC20_init(\\\"MyToken\\\", \\\"MTK\\\");\\n * }\\n * }\\n * contract MyTokenV2 is MyToken, ERC20PermitUpgradeable {\\n * function initializeV2() reinitializer(2) public {\\n * __ERC20Permit_init(\\\"MyToken\\\");\\n * }\\n * }\\n * ```\\n *\\n * TIP: To avoid leaving the proxy in an uninitialized state, the initializer function should be called as early as\\n * possible by providing the encoded function call as the `_data` argument to {ERC1967Proxy-constructor}.\\n *\\n * CAUTION: When used with inheritance, manual care must be taken to not invoke a parent initializer twice, or to ensure\\n * that all initializers are idempotent. This is not verified automatically as constructors are by Solidity.\\n *\\n * [CAUTION]\\n * ====\\n * Avoid leaving a contract uninitialized.\\n *\\n * An uninitialized contract can be taken over by an attacker. This applies to both a proxy and its implementation\\n * contract, which may impact the proxy. To prevent the implementation contract from being used, you should invoke\\n * the {_disableInitializers} function in the constructor to automatically lock it when it is deployed:\\n *\\n * [.hljs-theme-light.nopadding]\\n * ```\\n * /// @custom:oz-upgrades-unsafe-allow constructor\\n * constructor() {\\n * _disableInitializers();\\n * }\\n * ```\\n * ====\\n */\\nabstract contract Initializable {\\n /**\\n * @dev Indicates that the contract has been initialized.\\n * @custom:oz-retyped-from bool\\n */\\n uint8 private _initialized;\\n\\n /**\\n * @dev Indicates that the contract is in the process of being initialized.\\n */\\n bool private _initializing;\\n\\n /**\\n * @dev Triggered when the contract has been initialized or reinitialized.\\n */\\n event Initialized(uint8 version);\\n\\n /**\\n * @dev A modifier that defines a protected initializer function that can be invoked at most once. In its scope,\\n * `onlyInitializing` functions can be used to initialize parent contracts. Equivalent to `reinitializer(1)`.\\n */\\n modifier initializer() {\\n bool isTopLevelCall = !_initializing;\\n require(\\n (isTopLevelCall && _initialized < 1) || (!AddressUpgradeable.isContract(address(this)) && _initialized == 1),\\n \\\"Initializable: contract is already initialized\\\"\\n );\\n _initialized = 1;\\n if (isTopLevelCall) {\\n _initializing = true;\\n }\\n _;\\n if (isTopLevelCall) {\\n _initializing = false;\\n emit Initialized(1);\\n }\\n }\\n\\n /**\\n * @dev A modifier that defines a protected reinitializer function that can be invoked at most once, and only if the\\n * contract hasn't been initialized to a greater version before. In its scope, `onlyInitializing` functions can be\\n * used to initialize parent contracts.\\n *\\n * `initializer` is equivalent to `reinitializer(1)`, so a reinitializer may be used after the original\\n * initialization step. This is essential to configure modules that are added through upgrades and that require\\n * initialization.\\n *\\n * Note that versions can jump in increments greater than 1; this implies that if multiple reinitializers coexist in\\n * a contract, executing them in the right order is up to the developer or operator.\\n */\\n modifier reinitializer(uint8 version) {\\n require(!_initializing && _initialized < version, \\\"Initializable: contract is already initialized\\\");\\n _initialized = version;\\n _initializing = true;\\n _;\\n _initializing = false;\\n emit Initialized(version);\\n }\\n\\n /**\\n * @dev Modifier to protect an initialization function so that it can only be invoked by functions with the\\n * {initializer} and {reinitializer} modifiers, directly or indirectly.\\n */\\n modifier onlyInitializing() {\\n require(_initializing, \\\"Initializable: contract is not initializing\\\");\\n _;\\n }\\n\\n /**\\n * @dev Locks the contract, preventing any future reinitialization. This cannot be part of an initializer call.\\n * Calling this in the constructor of a contract will prevent that contract from being initialized or reinitialized\\n * to any version. It is recommended to use this to lock implementation contracts that are designed to be called\\n * through proxies.\\n */\\n function _disableInitializers() internal virtual {\\n require(!_initializing, \\\"Initializable: contract is initializing\\\");\\n if (_initialized < type(uint8).max) {\\n _initialized = type(uint8).max;\\n emit Initialized(type(uint8).max);\\n }\\n }\\n}\\n\",\"keccak256\":\"0x0203dcadc5737d9ef2c211d6fa15d18ebc3b30dfa51903b64870b01a062b0b4e\",\"license\":\"MIT\"},\"@openzeppelin/contracts-upgradeable/token/ERC20/ERC20Upgradeable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.7.0) (token/ERC20/ERC20.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"./IERC20Upgradeable.sol\\\";\\nimport \\\"./extensions/IERC20MetadataUpgradeable.sol\\\";\\nimport \\\"../../utils/ContextUpgradeable.sol\\\";\\nimport \\\"../../proxy/utils/Initializable.sol\\\";\\n\\n/**\\n * @dev Implementation of the {IERC20} interface.\\n *\\n * This implementation is agnostic to the way tokens are created. This means\\n * that a supply mechanism has to be added in a derived contract using {_mint}.\\n * For a generic mechanism see {ERC20PresetMinterPauser}.\\n *\\n * TIP: For a detailed writeup see our guide\\n * https://forum.zeppelin.solutions/t/how-to-implement-erc20-supply-mechanisms/226[How\\n * to implement supply mechanisms].\\n *\\n * We have followed general OpenZeppelin Contracts guidelines: functions revert\\n * instead returning `false` on failure. This behavior is nonetheless\\n * conventional and does not conflict with the expectations of ERC20\\n * applications.\\n *\\n * Additionally, an {Approval} event is emitted on calls to {transferFrom}.\\n * This allows applications to reconstruct the allowance for all accounts just\\n * by listening to said events. Other implementations of the EIP may not emit\\n * these events, as it isn't required by the specification.\\n *\\n * Finally, the non-standard {decreaseAllowance} and {increaseAllowance}\\n * functions have been added to mitigate the well-known issues around setting\\n * allowances. See {IERC20-approve}.\\n */\\ncontract ERC20Upgradeable is Initializable, ContextUpgradeable, IERC20Upgradeable, IERC20MetadataUpgradeable {\\n mapping(address => uint256) private _balances;\\n\\n mapping(address => mapping(address => uint256)) private _allowances;\\n\\n uint256 private _totalSupply;\\n\\n string private _name;\\n string private _symbol;\\n\\n /**\\n * @dev Sets the values for {name} and {symbol}.\\n *\\n * The default value of {decimals} is 18. To select a different value for\\n * {decimals} you should overload it.\\n *\\n * All two of these values are immutable: they can only be set once during\\n * construction.\\n */\\n function __ERC20_init(string memory name_, string memory symbol_) internal onlyInitializing {\\n __ERC20_init_unchained(name_, symbol_);\\n }\\n\\n function __ERC20_init_unchained(string memory name_, string memory symbol_) internal onlyInitializing {\\n _name = name_;\\n _symbol = symbol_;\\n }\\n\\n /**\\n * @dev Returns the name of the token.\\n */\\n function name() public view virtual override returns (string memory) {\\n return _name;\\n }\\n\\n /**\\n * @dev Returns the symbol of the token, usually a shorter version of the\\n * name.\\n */\\n function symbol() public view virtual override returns (string memory) {\\n return _symbol;\\n }\\n\\n /**\\n * @dev Returns the number of decimals used to get its user representation.\\n * For example, if `decimals` equals `2`, a balance of `505` tokens should\\n * be displayed to a user as `5.05` (`505 / 10 ** 2`).\\n *\\n * Tokens usually opt for a value of 18, imitating the relationship between\\n * Ether and Wei. This is the value {ERC20} uses, unless this function is\\n * overridden;\\n *\\n * NOTE: This information is only used for _display_ purposes: it in\\n * no way affects any of the arithmetic of the contract, including\\n * {IERC20-balanceOf} and {IERC20-transfer}.\\n */\\n function decimals() public view virtual override returns (uint8) {\\n return 18;\\n }\\n\\n /**\\n * @dev See {IERC20-totalSupply}.\\n */\\n function totalSupply() public view virtual override returns (uint256) {\\n return _totalSupply;\\n }\\n\\n /**\\n * @dev See {IERC20-balanceOf}.\\n */\\n function balanceOf(address account) public view virtual override returns (uint256) {\\n return _balances[account];\\n }\\n\\n /**\\n * @dev See {IERC20-transfer}.\\n *\\n * Requirements:\\n *\\n * - `to` cannot be the zero address.\\n * - the caller must have a balance of at least `amount`.\\n */\\n function transfer(address to, uint256 amount) public virtual override returns (bool) {\\n address owner = _msgSender();\\n _transfer(owner, to, amount);\\n return true;\\n }\\n\\n /**\\n * @dev See {IERC20-allowance}.\\n */\\n function allowance(address owner, address spender) public view virtual override returns (uint256) {\\n return _allowances[owner][spender];\\n }\\n\\n /**\\n * @dev See {IERC20-approve}.\\n *\\n * NOTE: If `amount` is the maximum `uint256`, the allowance is not updated on\\n * `transferFrom`. This is semantically equivalent to an infinite approval.\\n *\\n * Requirements:\\n *\\n * - `spender` cannot be the zero address.\\n */\\n function approve(address spender, uint256 amount) public virtual override returns (bool) {\\n address owner = _msgSender();\\n _approve(owner, spender, amount);\\n return true;\\n }\\n\\n /**\\n * @dev See {IERC20-transferFrom}.\\n *\\n * Emits an {Approval} event indicating the updated allowance. This is not\\n * required by the EIP. See the note at the beginning of {ERC20}.\\n *\\n * NOTE: Does not update the allowance if the current allowance\\n * is the maximum `uint256`.\\n *\\n * Requirements:\\n *\\n * - `from` and `to` cannot be the zero address.\\n * - `from` must have a balance of at least `amount`.\\n * - the caller must have allowance for ``from``'s tokens of at least\\n * `amount`.\\n */\\n function transferFrom(\\n address from,\\n address to,\\n uint256 amount\\n ) public virtual override returns (bool) {\\n address spender = _msgSender();\\n _spendAllowance(from, spender, amount);\\n _transfer(from, to, amount);\\n return true;\\n }\\n\\n /**\\n * @dev Atomically increases the allowance granted to `spender` by the caller.\\n *\\n * This is an alternative to {approve} that can be used as a mitigation for\\n * problems described in {IERC20-approve}.\\n *\\n * Emits an {Approval} event indicating the updated allowance.\\n *\\n * Requirements:\\n *\\n * - `spender` cannot be the zero address.\\n */\\n function increaseAllowance(address spender, uint256 addedValue) public virtual returns (bool) {\\n address owner = _msgSender();\\n _approve(owner, spender, allowance(owner, spender) + addedValue);\\n return true;\\n }\\n\\n /**\\n * @dev Atomically decreases the allowance granted to `spender` by the caller.\\n *\\n * This is an alternative to {approve} that can be used as a mitigation for\\n * problems described in {IERC20-approve}.\\n *\\n * Emits an {Approval} event indicating the updated allowance.\\n *\\n * Requirements:\\n *\\n * - `spender` cannot be the zero address.\\n * - `spender` must have allowance for the caller of at least\\n * `subtractedValue`.\\n */\\n function decreaseAllowance(address spender, uint256 subtractedValue) public virtual returns (bool) {\\n address owner = _msgSender();\\n uint256 currentAllowance = allowance(owner, spender);\\n require(currentAllowance >= subtractedValue, \\\"ERC20: decreased allowance below zero\\\");\\n unchecked {\\n _approve(owner, spender, currentAllowance - subtractedValue);\\n }\\n\\n return true;\\n }\\n\\n /**\\n * @dev Moves `amount` of tokens from `from` to `to`.\\n *\\n * This internal function is equivalent to {transfer}, and can be used to\\n * e.g. implement automatic token fees, slashing mechanisms, etc.\\n *\\n * Emits a {Transfer} event.\\n *\\n * Requirements:\\n *\\n * - `from` cannot be the zero address.\\n * - `to` cannot be the zero address.\\n * - `from` must have a balance of at least `amount`.\\n */\\n function _transfer(\\n address from,\\n address to,\\n uint256 amount\\n ) internal virtual {\\n require(from != address(0), \\\"ERC20: transfer from the zero address\\\");\\n require(to != address(0), \\\"ERC20: transfer to the zero address\\\");\\n\\n _beforeTokenTransfer(from, to, amount);\\n\\n uint256 fromBalance = _balances[from];\\n require(fromBalance >= amount, \\\"ERC20: transfer amount exceeds balance\\\");\\n unchecked {\\n _balances[from] = fromBalance - amount;\\n }\\n _balances[to] += amount;\\n\\n emit Transfer(from, to, amount);\\n\\n _afterTokenTransfer(from, to, amount);\\n }\\n\\n /** @dev Creates `amount` tokens and assigns them to `account`, increasing\\n * the total supply.\\n *\\n * Emits a {Transfer} event with `from` set to the zero address.\\n *\\n * Requirements:\\n *\\n * - `account` cannot be the zero address.\\n */\\n function _mint(address account, uint256 amount) internal virtual {\\n require(account != address(0), \\\"ERC20: mint to the zero address\\\");\\n\\n _beforeTokenTransfer(address(0), account, amount);\\n\\n _totalSupply += amount;\\n _balances[account] += amount;\\n emit Transfer(address(0), account, amount);\\n\\n _afterTokenTransfer(address(0), account, amount);\\n }\\n\\n /**\\n * @dev Destroys `amount` tokens from `account`, reducing the\\n * total supply.\\n *\\n * Emits a {Transfer} event with `to` set to the zero address.\\n *\\n * Requirements:\\n *\\n * - `account` cannot be the zero address.\\n * - `account` must have at least `amount` tokens.\\n */\\n function _burn(address account, uint256 amount) internal virtual {\\n require(account != address(0), \\\"ERC20: burn from the zero address\\\");\\n\\n _beforeTokenTransfer(account, address(0), amount);\\n\\n uint256 accountBalance = _balances[account];\\n require(accountBalance >= amount, \\\"ERC20: burn amount exceeds balance\\\");\\n unchecked {\\n _balances[account] = accountBalance - amount;\\n }\\n _totalSupply -= amount;\\n\\n emit Transfer(account, address(0), amount);\\n\\n _afterTokenTransfer(account, address(0), amount);\\n }\\n\\n /**\\n * @dev Sets `amount` as the allowance of `spender` over the `owner` s tokens.\\n *\\n * This internal function is equivalent to `approve`, and can be used to\\n * e.g. set automatic allowances for certain subsystems, etc.\\n *\\n * Emits an {Approval} event.\\n *\\n * Requirements:\\n *\\n * - `owner` cannot be the zero address.\\n * - `spender` cannot be the zero address.\\n */\\n function _approve(\\n address owner,\\n address spender,\\n uint256 amount\\n ) internal virtual {\\n require(owner != address(0), \\\"ERC20: approve from the zero address\\\");\\n require(spender != address(0), \\\"ERC20: approve to the zero address\\\");\\n\\n _allowances[owner][spender] = amount;\\n emit Approval(owner, spender, amount);\\n }\\n\\n /**\\n * @dev Updates `owner` s allowance for `spender` based on spent `amount`.\\n *\\n * Does not update the allowance amount in case of infinite allowance.\\n * Revert if not enough allowance is available.\\n *\\n * Might emit an {Approval} event.\\n */\\n function _spendAllowance(\\n address owner,\\n address spender,\\n uint256 amount\\n ) internal virtual {\\n uint256 currentAllowance = allowance(owner, spender);\\n if (currentAllowance != type(uint256).max) {\\n require(currentAllowance >= amount, \\\"ERC20: insufficient allowance\\\");\\n unchecked {\\n _approve(owner, spender, currentAllowance - amount);\\n }\\n }\\n }\\n\\n /**\\n * @dev Hook that is called before any transfer of tokens. This includes\\n * minting and burning.\\n *\\n * Calling conditions:\\n *\\n * - when `from` and `to` are both non-zero, `amount` of ``from``'s tokens\\n * will be transferred to `to`.\\n * - when `from` is zero, `amount` tokens will be minted for `to`.\\n * - when `to` is zero, `amount` of ``from``'s tokens will be burned.\\n * - `from` and `to` are never both zero.\\n *\\n * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].\\n */\\n function _beforeTokenTransfer(\\n address from,\\n address to,\\n uint256 amount\\n ) internal virtual {}\\n\\n /**\\n * @dev Hook that is called after any transfer of tokens. This includes\\n * minting and burning.\\n *\\n * Calling conditions:\\n *\\n * - when `from` and `to` are both non-zero, `amount` of ``from``'s tokens\\n * has been transferred to `to`.\\n * - when `from` is zero, `amount` tokens have been minted for `to`.\\n * - when `to` is zero, `amount` of ``from``'s tokens have been burned.\\n * - `from` and `to` are never both zero.\\n *\\n * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].\\n */\\n function _afterTokenTransfer(\\n address from,\\n address to,\\n uint256 amount\\n ) internal virtual {}\\n\\n /**\\n * @dev This empty reserved space is put in place to allow future versions to add new\\n * variables without shifting down storage in the inheritance chain.\\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\\n */\\n uint256[45] private __gap;\\n}\\n\",\"keccak256\":\"0x7c7ac0bc6c340a7f320524b9a4b4b079ee9da3c51258080d4bab237f329a427c\",\"license\":\"MIT\"},\"@openzeppelin/contracts-upgradeable/token/ERC20/IERC20Upgradeable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.6.0) (token/ERC20/IERC20.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Interface of the ERC20 standard as defined in the EIP.\\n */\\ninterface IERC20Upgradeable {\\n /**\\n * @dev Emitted when `value` tokens are moved from one account (`from`) to\\n * another (`to`).\\n *\\n * Note that `value` may be zero.\\n */\\n event Transfer(address indexed from, address indexed to, uint256 value);\\n\\n /**\\n * @dev Emitted when the allowance of a `spender` for an `owner` is set by\\n * a call to {approve}. `value` is the new allowance.\\n */\\n event Approval(address indexed owner, address indexed spender, uint256 value);\\n\\n /**\\n * @dev Returns the amount of tokens in existence.\\n */\\n function totalSupply() external view returns (uint256);\\n\\n /**\\n * @dev Returns the amount of tokens owned by `account`.\\n */\\n function balanceOf(address account) external view returns (uint256);\\n\\n /**\\n * @dev Moves `amount` tokens from the caller's account to `to`.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * Emits a {Transfer} event.\\n */\\n function transfer(address to, uint256 amount) external returns (bool);\\n\\n /**\\n * @dev Returns the remaining number of tokens that `spender` will be\\n * allowed to spend on behalf of `owner` through {transferFrom}. This is\\n * zero by default.\\n *\\n * This value changes when {approve} or {transferFrom} are called.\\n */\\n function allowance(address owner, address spender) external view returns (uint256);\\n\\n /**\\n * @dev Sets `amount` as the allowance of `spender` over the caller's tokens.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * IMPORTANT: Beware that changing an allowance with this method brings the risk\\n * that someone may use both the old and the new allowance by unfortunate\\n * transaction ordering. One possible solution to mitigate this race\\n * condition is to first reduce the spender's allowance to 0 and set the\\n * desired value afterwards:\\n * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729\\n *\\n * Emits an {Approval} event.\\n */\\n function approve(address spender, uint256 amount) external returns (bool);\\n\\n /**\\n * @dev Moves `amount` tokens from `from` to `to` using the\\n * allowance mechanism. `amount` is then deducted from the caller's\\n * allowance.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * Emits a {Transfer} event.\\n */\\n function transferFrom(\\n address from,\\n address to,\\n uint256 amount\\n ) external returns (bool);\\n}\\n\",\"keccak256\":\"0x4e733d3164f73f461eaf9d8087a7ad1ea180bdc8ba0d3d61b0e1ae16d8e63dff\",\"license\":\"MIT\"},\"@openzeppelin/contracts-upgradeable/token/ERC20/extensions/IERC20MetadataUpgradeable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (token/ERC20/extensions/IERC20Metadata.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../IERC20Upgradeable.sol\\\";\\n\\n/**\\n * @dev Interface for the optional metadata functions from the ERC20 standard.\\n *\\n * _Available since v4.1._\\n */\\ninterface IERC20MetadataUpgradeable is IERC20Upgradeable {\\n /**\\n * @dev Returns the name of the token.\\n */\\n function name() external view returns (string memory);\\n\\n /**\\n * @dev Returns the symbol of the token.\\n */\\n function symbol() external view returns (string memory);\\n\\n /**\\n * @dev Returns the decimals places of the token.\\n */\\n function decimals() external view returns (uint8);\\n}\\n\",\"keccak256\":\"0x605434219ebbe4653f703640f06969faa5a1d78f0bfef878e5ddbb1ca369ceeb\",\"license\":\"MIT\"},\"@openzeppelin/contracts-upgradeable/token/ERC20/extensions/draft-ERC20PermitUpgradeable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.6.0) (token/ERC20/extensions/draft-ERC20Permit.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"./draft-IERC20PermitUpgradeable.sol\\\";\\nimport \\\"../ERC20Upgradeable.sol\\\";\\nimport \\\"../../../utils/cryptography/draft-EIP712Upgradeable.sol\\\";\\nimport \\\"../../../utils/cryptography/ECDSAUpgradeable.sol\\\";\\nimport \\\"../../../utils/CountersUpgradeable.sol\\\";\\nimport \\\"../../../proxy/utils/Initializable.sol\\\";\\n\\n/**\\n * @dev Implementation of the ERC20 Permit extension allowing approvals to be made via signatures, as defined in\\n * https://eips.ethereum.org/EIPS/eip-2612[EIP-2612].\\n *\\n * Adds the {permit} method, which can be used to change an account's ERC20 allowance (see {IERC20-allowance}) by\\n * presenting a message signed by the account. By not relying on `{IERC20-approve}`, the token holder account doesn't\\n * need to send a transaction, and thus is not required to hold Ether at all.\\n *\\n * _Available since v3.4._\\n *\\n * @custom:storage-size 51\\n */\\nabstract contract ERC20PermitUpgradeable is Initializable, ERC20Upgradeable, IERC20PermitUpgradeable, EIP712Upgradeable {\\n using CountersUpgradeable for CountersUpgradeable.Counter;\\n\\n mapping(address => CountersUpgradeable.Counter) private _nonces;\\n\\n // solhint-disable-next-line var-name-mixedcase\\n bytes32 private constant _PERMIT_TYPEHASH =\\n keccak256(\\\"Permit(address owner,address spender,uint256 value,uint256 nonce,uint256 deadline)\\\");\\n /**\\n * @dev In previous versions `_PERMIT_TYPEHASH` was declared as `immutable`.\\n * However, to ensure consistency with the upgradeable transpiler, we will continue\\n * to reserve a slot.\\n * @custom:oz-renamed-from _PERMIT_TYPEHASH\\n */\\n // solhint-disable-next-line var-name-mixedcase\\n bytes32 private _PERMIT_TYPEHASH_DEPRECATED_SLOT;\\n\\n /**\\n * @dev Initializes the {EIP712} domain separator using the `name` parameter, and setting `version` to `\\\"1\\\"`.\\n *\\n * It's a good idea to use the same `name` that is defined as the ERC20 token name.\\n */\\n function __ERC20Permit_init(string memory name) internal onlyInitializing {\\n __EIP712_init_unchained(name, \\\"1\\\");\\n }\\n\\n function __ERC20Permit_init_unchained(string memory) internal onlyInitializing {}\\n\\n /**\\n * @dev See {IERC20Permit-permit}.\\n */\\n function permit(\\n address owner,\\n address spender,\\n uint256 value,\\n uint256 deadline,\\n uint8 v,\\n bytes32 r,\\n bytes32 s\\n ) public virtual override {\\n require(block.timestamp <= deadline, \\\"ERC20Permit: expired deadline\\\");\\n\\n bytes32 structHash = keccak256(abi.encode(_PERMIT_TYPEHASH, owner, spender, value, _useNonce(owner), deadline));\\n\\n bytes32 hash = _hashTypedDataV4(structHash);\\n\\n address signer = ECDSAUpgradeable.recover(hash, v, r, s);\\n require(signer == owner, \\\"ERC20Permit: invalid signature\\\");\\n\\n _approve(owner, spender, value);\\n }\\n\\n /**\\n * @dev See {IERC20Permit-nonces}.\\n */\\n function nonces(address owner) public view virtual override returns (uint256) {\\n return _nonces[owner].current();\\n }\\n\\n /**\\n * @dev See {IERC20Permit-DOMAIN_SEPARATOR}.\\n */\\n // solhint-disable-next-line func-name-mixedcase\\n function DOMAIN_SEPARATOR() external view override returns (bytes32) {\\n return _domainSeparatorV4();\\n }\\n\\n /**\\n * @dev \\\"Consume a nonce\\\": return the current value and increment.\\n *\\n * _Available since v4.1._\\n */\\n function _useNonce(address owner) internal virtual returns (uint256 current) {\\n CountersUpgradeable.Counter storage nonce = _nonces[owner];\\n current = nonce.current();\\n nonce.increment();\\n }\\n\\n /**\\n * @dev This empty reserved space is put in place to allow future versions to add new\\n * variables without shifting down storage in the inheritance chain.\\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\\n */\\n uint256[49] private __gap;\\n}\\n\",\"keccak256\":\"0x564385ebed633694decce3e13d687f3ac7e8eaef64f7a504bfb3f03ad210601f\",\"license\":\"MIT\"},\"@openzeppelin/contracts-upgradeable/token/ERC20/extensions/draft-IERC20PermitUpgradeable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (token/ERC20/extensions/draft-IERC20Permit.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Interface of the ERC20 Permit extension allowing approvals to be made via signatures, as defined in\\n * https://eips.ethereum.org/EIPS/eip-2612[EIP-2612].\\n *\\n * Adds the {permit} method, which can be used to change an account's ERC20 allowance (see {IERC20-allowance}) by\\n * presenting a message signed by the account. By not relying on {IERC20-approve}, the token holder account doesn't\\n * need to send a transaction, and thus is not required to hold Ether at all.\\n */\\ninterface IERC20PermitUpgradeable {\\n /**\\n * @dev Sets `value` as the allowance of `spender` over ``owner``'s tokens,\\n * given ``owner``'s signed approval.\\n *\\n * IMPORTANT: The same issues {IERC20-approve} has related to transaction\\n * ordering also apply here.\\n *\\n * Emits an {Approval} event.\\n *\\n * Requirements:\\n *\\n * - `spender` cannot be the zero address.\\n * - `deadline` must be a timestamp in the future.\\n * - `v`, `r` and `s` must be a valid `secp256k1` signature from `owner`\\n * over the EIP712-formatted function arguments.\\n * - the signature must use ``owner``'s current nonce (see {nonces}).\\n *\\n * For more information on the signature format, see the\\n * https://eips.ethereum.org/EIPS/eip-2612#specification[relevant EIP\\n * section].\\n */\\n function permit(\\n address owner,\\n address spender,\\n uint256 value,\\n uint256 deadline,\\n uint8 v,\\n bytes32 r,\\n bytes32 s\\n ) external;\\n\\n /**\\n * @dev Returns the current nonce for `owner`. This value must be\\n * included whenever a signature is generated for {permit}.\\n *\\n * Every successful call to {permit} increases ``owner``'s nonce by one. This\\n * prevents a signature from being used multiple times.\\n */\\n function nonces(address owner) external view returns (uint256);\\n\\n /**\\n * @dev Returns the domain separator used in the encoding of the signature for {permit}, as defined by {EIP712}.\\n */\\n // solhint-disable-next-line func-name-mixedcase\\n function DOMAIN_SEPARATOR() external view returns (bytes32);\\n}\\n\",\"keccak256\":\"0xcc70d8e2281fb3ff69e8ab242500f10142cd0a7fa8dd9e45882be270d4d09024\",\"license\":\"MIT\"},\"@openzeppelin/contracts-upgradeable/utils/AddressUpgradeable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.7.0) (utils/Address.sol)\\n\\npragma solidity ^0.8.1;\\n\\n/**\\n * @dev Collection of functions related to the address type\\n */\\nlibrary AddressUpgradeable {\\n /**\\n * @dev Returns true if `account` is a contract.\\n *\\n * [IMPORTANT]\\n * ====\\n * It is unsafe to assume that an address for which this function returns\\n * false is an externally-owned account (EOA) and not a contract.\\n *\\n * Among others, `isContract` will return false for the following\\n * types of addresses:\\n *\\n * - an externally-owned account\\n * - a contract in construction\\n * - an address where a contract will be created\\n * - an address where a contract lived, but was destroyed\\n * ====\\n *\\n * [IMPORTANT]\\n * ====\\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\\n *\\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\\n * constructor.\\n * ====\\n */\\n function isContract(address account) internal view returns (bool) {\\n // This method relies on extcodesize/address.code.length, which returns 0\\n // for contracts in construction, since the code is only stored at the end\\n // of the constructor execution.\\n\\n return account.code.length > 0;\\n }\\n\\n /**\\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\\n * `recipient`, forwarding all available gas and reverting on errors.\\n *\\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\\n * imposed by `transfer`, making them unable to receive funds via\\n * `transfer`. {sendValue} removes this limitation.\\n *\\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\\n *\\n * IMPORTANT: because control is transferred to `recipient`, care must be\\n * taken to not create reentrancy vulnerabilities. Consider using\\n * {ReentrancyGuard} or the\\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\\n */\\n function sendValue(address payable recipient, uint256 amount) internal {\\n require(address(this).balance >= amount, \\\"Address: insufficient balance\\\");\\n\\n (bool success, ) = recipient.call{value: amount}(\\\"\\\");\\n require(success, \\\"Address: unable to send value, recipient may have reverted\\\");\\n }\\n\\n /**\\n * @dev Performs a Solidity function call using a low level `call`. A\\n * plain `call` is an unsafe replacement for a function call: use this\\n * function instead.\\n *\\n * If `target` reverts with a revert reason, it is bubbled up by this\\n * function (like regular Solidity function calls).\\n *\\n * Returns the raw returned data. To convert to the expected return value,\\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\\n *\\n * Requirements:\\n *\\n * - `target` must be a contract.\\n * - calling `target` with `data` must not revert.\\n *\\n * _Available since v3.1._\\n */\\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\\n return functionCall(target, data, \\\"Address: low-level call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\\n * `errorMessage` as a fallback revert reason when `target` reverts.\\n *\\n * _Available since v3.1._\\n */\\n function functionCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n return functionCallWithValue(target, data, 0, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but also transferring `value` wei to `target`.\\n *\\n * Requirements:\\n *\\n * - the calling contract must have an ETH balance of at least `value`.\\n * - the called Solidity function must be `payable`.\\n *\\n * _Available since v3.1._\\n */\\n function functionCallWithValue(\\n address target,\\n bytes memory data,\\n uint256 value\\n ) internal returns (bytes memory) {\\n return functionCallWithValue(target, data, value, \\\"Address: low-level call with value failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\\n * with `errorMessage` as a fallback revert reason when `target` reverts.\\n *\\n * _Available since v3.1._\\n */\\n function functionCallWithValue(\\n address target,\\n bytes memory data,\\n uint256 value,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n require(address(this).balance >= value, \\\"Address: insufficient balance for call\\\");\\n require(isContract(target), \\\"Address: call to non-contract\\\");\\n\\n (bool success, bytes memory returndata) = target.call{value: value}(data);\\n return verifyCallResult(success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but performing a static call.\\n *\\n * _Available since v3.3._\\n */\\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\\n return functionStaticCall(target, data, \\\"Address: low-level static call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\\n * but performing a static call.\\n *\\n * _Available since v3.3._\\n */\\n function functionStaticCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal view returns (bytes memory) {\\n require(isContract(target), \\\"Address: static call to non-contract\\\");\\n\\n (bool success, bytes memory returndata) = target.staticcall(data);\\n return verifyCallResult(success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the\\n * revert reason using the provided one.\\n *\\n * _Available since v4.3._\\n */\\n function verifyCallResult(\\n bool success,\\n bytes memory returndata,\\n string memory errorMessage\\n ) internal pure returns (bytes memory) {\\n if (success) {\\n return returndata;\\n } else {\\n // Look for revert reason and bubble it up if present\\n if (returndata.length > 0) {\\n // The easiest way to bubble the revert reason is using memory via assembly\\n /// @solidity memory-safe-assembly\\n assembly {\\n let returndata_size := mload(returndata)\\n revert(add(32, returndata), returndata_size)\\n }\\n } else {\\n revert(errorMessage);\\n }\\n }\\n }\\n}\\n\",\"keccak256\":\"0x611aa3f23e59cfdd1863c536776407b3e33d695152a266fa7cfb34440a29a8a3\",\"license\":\"MIT\"},\"@openzeppelin/contracts-upgradeable/utils/ContextUpgradeable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)\\n\\npragma solidity ^0.8.0;\\nimport \\\"../proxy/utils/Initializable.sol\\\";\\n\\n/**\\n * @dev Provides information about the current execution context, including the\\n * sender of the transaction and its data. While these are generally available\\n * via msg.sender and msg.data, they should not be accessed in such a direct\\n * manner, since when dealing with meta-transactions the account sending and\\n * paying for execution may not be the actual sender (as far as an application\\n * is concerned).\\n *\\n * This contract is only required for intermediate, library-like contracts.\\n */\\nabstract contract ContextUpgradeable is Initializable {\\n function __Context_init() internal onlyInitializing {\\n }\\n\\n function __Context_init_unchained() internal onlyInitializing {\\n }\\n function _msgSender() internal view virtual returns (address) {\\n return msg.sender;\\n }\\n\\n function _msgData() internal view virtual returns (bytes calldata) {\\n return msg.data;\\n }\\n\\n /**\\n * @dev This empty reserved space is put in place to allow future versions to add new\\n * variables without shifting down storage in the inheritance chain.\\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\\n */\\n uint256[50] private __gap;\\n}\\n\",\"keccak256\":\"0x963ea7f0b48b032eef72fe3a7582edf78408d6f834115b9feadd673a4d5bd149\",\"license\":\"MIT\"},\"@openzeppelin/contracts-upgradeable/utils/CountersUpgradeable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (utils/Counters.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @title Counters\\n * @author Matt Condon (@shrugs)\\n * @dev Provides counters that can only be incremented, decremented or reset. This can be used e.g. to track the number\\n * of elements in a mapping, issuing ERC721 ids, or counting request ids.\\n *\\n * Include with `using Counters for Counters.Counter;`\\n */\\nlibrary CountersUpgradeable {\\n struct Counter {\\n // This variable should never be directly accessed by users of the library: interactions must be restricted to\\n // the library's function. As of Solidity v0.5.2, this cannot be enforced, though there is a proposal to add\\n // this feature: see https://github.com/ethereum/solidity/issues/4637\\n uint256 _value; // default: 0\\n }\\n\\n function current(Counter storage counter) internal view returns (uint256) {\\n return counter._value;\\n }\\n\\n function increment(Counter storage counter) internal {\\n unchecked {\\n counter._value += 1;\\n }\\n }\\n\\n function decrement(Counter storage counter) internal {\\n uint256 value = counter._value;\\n require(value > 0, \\\"Counter: decrement overflow\\\");\\n unchecked {\\n counter._value = value - 1;\\n }\\n }\\n\\n function reset(Counter storage counter) internal {\\n counter._value = 0;\\n }\\n}\\n\",\"keccak256\":\"0x798741e231b22b81e2dd2eddaaf8832dee4baf5cd8e2dbaa5c1dd12a1c053c4d\",\"license\":\"MIT\"},\"@openzeppelin/contracts-upgradeable/utils/StringsUpgradeable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.7.0) (utils/Strings.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev String operations.\\n */\\nlibrary StringsUpgradeable {\\n bytes16 private constant _HEX_SYMBOLS = \\\"0123456789abcdef\\\";\\n uint8 private constant _ADDRESS_LENGTH = 20;\\n\\n /**\\n * @dev Converts a `uint256` to its ASCII `string` decimal representation.\\n */\\n function toString(uint256 value) internal pure returns (string memory) {\\n // Inspired by OraclizeAPI's implementation - MIT licence\\n // https://github.com/oraclize/ethereum-api/blob/b42146b063c7d6ee1358846c198246239e9360e8/oraclizeAPI_0.4.25.sol\\n\\n if (value == 0) {\\n return \\\"0\\\";\\n }\\n uint256 temp = value;\\n uint256 digits;\\n while (temp != 0) {\\n digits++;\\n temp /= 10;\\n }\\n bytes memory buffer = new bytes(digits);\\n while (value != 0) {\\n digits -= 1;\\n buffer[digits] = bytes1(uint8(48 + uint256(value % 10)));\\n value /= 10;\\n }\\n return string(buffer);\\n }\\n\\n /**\\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation.\\n */\\n function toHexString(uint256 value) internal pure returns (string memory) {\\n if (value == 0) {\\n return \\\"0x00\\\";\\n }\\n uint256 temp = value;\\n uint256 length = 0;\\n while (temp != 0) {\\n length++;\\n temp >>= 8;\\n }\\n return toHexString(value, length);\\n }\\n\\n /**\\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length.\\n */\\n function toHexString(uint256 value, uint256 length) internal pure returns (string memory) {\\n bytes memory buffer = new bytes(2 * length + 2);\\n buffer[0] = \\\"0\\\";\\n buffer[1] = \\\"x\\\";\\n for (uint256 i = 2 * length + 1; i > 1; --i) {\\n buffer[i] = _HEX_SYMBOLS[value & 0xf];\\n value >>= 4;\\n }\\n require(value == 0, \\\"Strings: hex length insufficient\\\");\\n return string(buffer);\\n }\\n\\n /**\\n * @dev Converts an `address` with fixed length of 20 bytes to its not checksummed ASCII `string` hexadecimal representation.\\n */\\n function toHexString(address addr) internal pure returns (string memory) {\\n return toHexString(uint256(uint160(addr)), _ADDRESS_LENGTH);\\n }\\n}\\n\",\"keccak256\":\"0xea5339a7fff0ed42b45be56a88efdd0b2ddde9fa480dc99fef9a6a4c5b776863\",\"license\":\"MIT\"},\"@openzeppelin/contracts-upgradeable/utils/cryptography/ECDSAUpgradeable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.7.0) (utils/cryptography/ECDSA.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../StringsUpgradeable.sol\\\";\\n\\n/**\\n * @dev Elliptic Curve Digital Signature Algorithm (ECDSA) operations.\\n *\\n * These functions can be used to verify that a message was signed by the holder\\n * of the private keys of a given address.\\n */\\nlibrary ECDSAUpgradeable {\\n enum RecoverError {\\n NoError,\\n InvalidSignature,\\n InvalidSignatureLength,\\n InvalidSignatureS,\\n InvalidSignatureV\\n }\\n\\n function _throwError(RecoverError error) private pure {\\n if (error == RecoverError.NoError) {\\n return; // no error: do nothing\\n } else if (error == RecoverError.InvalidSignature) {\\n revert(\\\"ECDSA: invalid signature\\\");\\n } else if (error == RecoverError.InvalidSignatureLength) {\\n revert(\\\"ECDSA: invalid signature length\\\");\\n } else if (error == RecoverError.InvalidSignatureS) {\\n revert(\\\"ECDSA: invalid signature 's' value\\\");\\n } else if (error == RecoverError.InvalidSignatureV) {\\n revert(\\\"ECDSA: invalid signature 'v' value\\\");\\n }\\n }\\n\\n /**\\n * @dev Returns the address that signed a hashed message (`hash`) with\\n * `signature` or error string. This address can then be used for verification purposes.\\n *\\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\\n * this function rejects them by requiring the `s` value to be in the lower\\n * half order, and the `v` value to be either 27 or 28.\\n *\\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\\n * verification to be secure: it is possible to craft signatures that\\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\\n * this is by receiving a hash of the original message (which may otherwise\\n * be too long), and then calling {toEthSignedMessageHash} on it.\\n *\\n * Documentation for signature generation:\\n * - with https://web3js.readthedocs.io/en/v1.3.4/web3-eth-accounts.html#sign[Web3.js]\\n * - with https://docs.ethers.io/v5/api/signer/#Signer-signMessage[ethers]\\n *\\n * _Available since v4.3._\\n */\\n function tryRecover(bytes32 hash, bytes memory signature) internal pure returns (address, RecoverError) {\\n // Check the signature length\\n // - case 65: r,s,v signature (standard)\\n // - case 64: r,vs signature (cf https://eips.ethereum.org/EIPS/eip-2098) _Available since v4.1._\\n if (signature.length == 65) {\\n bytes32 r;\\n bytes32 s;\\n uint8 v;\\n // ecrecover takes the signature parameters, and the only way to get them\\n // currently is to use assembly.\\n /// @solidity memory-safe-assembly\\n assembly {\\n r := mload(add(signature, 0x20))\\n s := mload(add(signature, 0x40))\\n v := byte(0, mload(add(signature, 0x60)))\\n }\\n return tryRecover(hash, v, r, s);\\n } else if (signature.length == 64) {\\n bytes32 r;\\n bytes32 vs;\\n // ecrecover takes the signature parameters, and the only way to get them\\n // currently is to use assembly.\\n /// @solidity memory-safe-assembly\\n assembly {\\n r := mload(add(signature, 0x20))\\n vs := mload(add(signature, 0x40))\\n }\\n return tryRecover(hash, r, vs);\\n } else {\\n return (address(0), RecoverError.InvalidSignatureLength);\\n }\\n }\\n\\n /**\\n * @dev Returns the address that signed a hashed message (`hash`) with\\n * `signature`. This address can then be used for verification purposes.\\n *\\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\\n * this function rejects them by requiring the `s` value to be in the lower\\n * half order, and the `v` value to be either 27 or 28.\\n *\\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\\n * verification to be secure: it is possible to craft signatures that\\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\\n * this is by receiving a hash of the original message (which may otherwise\\n * be too long), and then calling {toEthSignedMessageHash} on it.\\n */\\n function recover(bytes32 hash, bytes memory signature) internal pure returns (address) {\\n (address recovered, RecoverError error) = tryRecover(hash, signature);\\n _throwError(error);\\n return recovered;\\n }\\n\\n /**\\n * @dev Overload of {ECDSA-tryRecover} that receives the `r` and `vs` short-signature fields separately.\\n *\\n * See https://eips.ethereum.org/EIPS/eip-2098[EIP-2098 short signatures]\\n *\\n * _Available since v4.3._\\n */\\n function tryRecover(\\n bytes32 hash,\\n bytes32 r,\\n bytes32 vs\\n ) internal pure returns (address, RecoverError) {\\n bytes32 s = vs & bytes32(0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff);\\n uint8 v = uint8((uint256(vs) >> 255) + 27);\\n return tryRecover(hash, v, r, s);\\n }\\n\\n /**\\n * @dev Overload of {ECDSA-recover} that receives the `r and `vs` short-signature fields separately.\\n *\\n * _Available since v4.2._\\n */\\n function recover(\\n bytes32 hash,\\n bytes32 r,\\n bytes32 vs\\n ) internal pure returns (address) {\\n (address recovered, RecoverError error) = tryRecover(hash, r, vs);\\n _throwError(error);\\n return recovered;\\n }\\n\\n /**\\n * @dev Overload of {ECDSA-tryRecover} that receives the `v`,\\n * `r` and `s` signature fields separately.\\n *\\n * _Available since v4.3._\\n */\\n function tryRecover(\\n bytes32 hash,\\n uint8 v,\\n bytes32 r,\\n bytes32 s\\n ) internal pure returns (address, RecoverError) {\\n // EIP-2 still allows signature malleability for ecrecover(). Remove this possibility and make the signature\\n // unique. Appendix F in the Ethereum Yellow paper (https://ethereum.github.io/yellowpaper/paper.pdf), defines\\n // the valid range for s in (301): 0 < s < secp256k1n \\u00f7 2 + 1, and for v in (302): v \\u2208 {27, 28}. Most\\n // signatures from current libraries generate a unique signature with an s-value in the lower half order.\\n //\\n // If your library generates malleable signatures, such as s-values in the upper range, calculate a new s-value\\n // with 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141 - s1 and flip v from 27 to 28 or\\n // vice versa. If your library also generates signatures with 0/1 for v instead 27/28, add 27 to v to accept\\n // these malleable signatures as well.\\n if (uint256(s) > 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D576E7357A4501DDFE92F46681B20A0) {\\n return (address(0), RecoverError.InvalidSignatureS);\\n }\\n if (v != 27 && v != 28) {\\n return (address(0), RecoverError.InvalidSignatureV);\\n }\\n\\n // If the signature is valid (and not malleable), return the signer address\\n address signer = ecrecover(hash, v, r, s);\\n if (signer == address(0)) {\\n return (address(0), RecoverError.InvalidSignature);\\n }\\n\\n return (signer, RecoverError.NoError);\\n }\\n\\n /**\\n * @dev Overload of {ECDSA-recover} that receives the `v`,\\n * `r` and `s` signature fields separately.\\n */\\n function recover(\\n bytes32 hash,\\n uint8 v,\\n bytes32 r,\\n bytes32 s\\n ) internal pure returns (address) {\\n (address recovered, RecoverError error) = tryRecover(hash, v, r, s);\\n _throwError(error);\\n return recovered;\\n }\\n\\n /**\\n * @dev Returns an Ethereum Signed Message, created from a `hash`. This\\n * produces hash corresponding to the one signed with the\\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\\n * JSON-RPC method as part of EIP-191.\\n *\\n * See {recover}.\\n */\\n function toEthSignedMessageHash(bytes32 hash) internal pure returns (bytes32) {\\n // 32 is the length in bytes of hash,\\n // enforced by the type signature above\\n return keccak256(abi.encodePacked(\\\"\\\\x19Ethereum Signed Message:\\\\n32\\\", hash));\\n }\\n\\n /**\\n * @dev Returns an Ethereum Signed Message, created from `s`. This\\n * produces hash corresponding to the one signed with the\\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\\n * JSON-RPC method as part of EIP-191.\\n *\\n * See {recover}.\\n */\\n function toEthSignedMessageHash(bytes memory s) internal pure returns (bytes32) {\\n return keccak256(abi.encodePacked(\\\"\\\\x19Ethereum Signed Message:\\\\n\\\", StringsUpgradeable.toString(s.length), s));\\n }\\n\\n /**\\n * @dev Returns an Ethereum Signed Typed Data, created from a\\n * `domainSeparator` and a `structHash`. This produces hash corresponding\\n * to the one signed with the\\n * https://eips.ethereum.org/EIPS/eip-712[`eth_signTypedData`]\\n * JSON-RPC method as part of EIP-712.\\n *\\n * See {recover}.\\n */\\n function toTypedDataHash(bytes32 domainSeparator, bytes32 structHash) internal pure returns (bytes32) {\\n return keccak256(abi.encodePacked(\\\"\\\\x19\\\\x01\\\", domainSeparator, structHash));\\n }\\n}\\n\",\"keccak256\":\"0xe8c62ca00ed2d0a4d9b7e3c4bf7d62c821618b2cdb3c844da91a1193986851bf\",\"license\":\"MIT\"},\"@openzeppelin/contracts-upgradeable/utils/cryptography/draft-EIP712Upgradeable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (utils/cryptography/draft-EIP712.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"./ECDSAUpgradeable.sol\\\";\\nimport \\\"../../proxy/utils/Initializable.sol\\\";\\n\\n/**\\n * @dev https://eips.ethereum.org/EIPS/eip-712[EIP 712] is a standard for hashing and signing of typed structured data.\\n *\\n * The encoding specified in the EIP is very generic, and such a generic implementation in Solidity is not feasible,\\n * thus this contract does not implement the encoding itself. Protocols need to implement the type-specific encoding\\n * they need in their contracts using a combination of `abi.encode` and `keccak256`.\\n *\\n * This contract implements the EIP 712 domain separator ({_domainSeparatorV4}) that is used as part of the encoding\\n * scheme, and the final step of the encoding to obtain the message digest that is then signed via ECDSA\\n * ({_hashTypedDataV4}).\\n *\\n * The implementation of the domain separator was designed to be as efficient as possible while still properly updating\\n * the chain id to protect against replay attacks on an eventual fork of the chain.\\n *\\n * NOTE: This contract implements the version of the encoding known as \\\"v4\\\", as implemented by the JSON RPC method\\n * https://docs.metamask.io/guide/signing-data.html[`eth_signTypedDataV4` in MetaMask].\\n *\\n * _Available since v3.4._\\n *\\n * @custom:storage-size 52\\n */\\nabstract contract EIP712Upgradeable is Initializable {\\n /* solhint-disable var-name-mixedcase */\\n bytes32 private _HASHED_NAME;\\n bytes32 private _HASHED_VERSION;\\n bytes32 private constant _TYPE_HASH = keccak256(\\\"EIP712Domain(string name,string version,uint256 chainId,address verifyingContract)\\\");\\n\\n /* solhint-enable var-name-mixedcase */\\n\\n /**\\n * @dev Initializes the domain separator and parameter caches.\\n *\\n * The meaning of `name` and `version` is specified in\\n * https://eips.ethereum.org/EIPS/eip-712#definition-of-domainseparator[EIP 712]:\\n *\\n * - `name`: the user readable name of the signing domain, i.e. the name of the DApp or the protocol.\\n * - `version`: the current major version of the signing domain.\\n *\\n * NOTE: These parameters cannot be changed except through a xref:learn::upgrading-smart-contracts.adoc[smart\\n * contract upgrade].\\n */\\n function __EIP712_init(string memory name, string memory version) internal onlyInitializing {\\n __EIP712_init_unchained(name, version);\\n }\\n\\n function __EIP712_init_unchained(string memory name, string memory version) internal onlyInitializing {\\n bytes32 hashedName = keccak256(bytes(name));\\n bytes32 hashedVersion = keccak256(bytes(version));\\n _HASHED_NAME = hashedName;\\n _HASHED_VERSION = hashedVersion;\\n }\\n\\n /**\\n * @dev Returns the domain separator for the current chain.\\n */\\n function _domainSeparatorV4() internal view returns (bytes32) {\\n return _buildDomainSeparator(_TYPE_HASH, _EIP712NameHash(), _EIP712VersionHash());\\n }\\n\\n function _buildDomainSeparator(\\n bytes32 typeHash,\\n bytes32 nameHash,\\n bytes32 versionHash\\n ) private view returns (bytes32) {\\n return keccak256(abi.encode(typeHash, nameHash, versionHash, block.chainid, address(this)));\\n }\\n\\n /**\\n * @dev Given an already https://eips.ethereum.org/EIPS/eip-712#definition-of-hashstruct[hashed struct], this\\n * function returns the hash of the fully encoded EIP712 message for this domain.\\n *\\n * This hash can be used together with {ECDSA-recover} to obtain the signer of a message. For example:\\n *\\n * ```solidity\\n * bytes32 digest = _hashTypedDataV4(keccak256(abi.encode(\\n * keccak256(\\\"Mail(address to,string contents)\\\"),\\n * mailTo,\\n * keccak256(bytes(mailContents))\\n * )));\\n * address signer = ECDSA.recover(digest, signature);\\n * ```\\n */\\n function _hashTypedDataV4(bytes32 structHash) internal view virtual returns (bytes32) {\\n return ECDSAUpgradeable.toTypedDataHash(_domainSeparatorV4(), structHash);\\n }\\n\\n /**\\n * @dev The hash of the name parameter for the EIP712 domain.\\n *\\n * NOTE: This function reads from storage by default, but can be redefined to return a constant value if gas costs\\n * are a concern.\\n */\\n function _EIP712NameHash() internal virtual view returns (bytes32) {\\n return _HASHED_NAME;\\n }\\n\\n /**\\n * @dev The hash of the version parameter for the EIP712 domain.\\n *\\n * NOTE: This function reads from storage by default, but can be redefined to return a constant value if gas costs\\n * are a concern.\\n */\\n function _EIP712VersionHash() internal virtual view returns (bytes32) {\\n return _HASHED_VERSION;\\n }\\n\\n /**\\n * @dev This empty reserved space is put in place to allow future versions to add new\\n * variables without shifting down storage in the inheritance chain.\\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\\n */\\n uint256[50] private __gap;\\n}\\n\",\"keccak256\":\"0xaf5a96100f421d61693605349511e43221d3c2e47d4b3efa87af2b936e2567fc\",\"license\":\"MIT\"},\"@openzeppelin/contracts/token/ERC20/IERC20.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.6.0) (token/ERC20/IERC20.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Interface of the ERC20 standard as defined in the EIP.\\n */\\ninterface IERC20 {\\n /**\\n * @dev Emitted when `value` tokens are moved from one account (`from`) to\\n * another (`to`).\\n *\\n * Note that `value` may be zero.\\n */\\n event Transfer(address indexed from, address indexed to, uint256 value);\\n\\n /**\\n * @dev Emitted when the allowance of a `spender` for an `owner` is set by\\n * a call to {approve}. `value` is the new allowance.\\n */\\n event Approval(address indexed owner, address indexed spender, uint256 value);\\n\\n /**\\n * @dev Returns the amount of tokens in existence.\\n */\\n function totalSupply() external view returns (uint256);\\n\\n /**\\n * @dev Returns the amount of tokens owned by `account`.\\n */\\n function balanceOf(address account) external view returns (uint256);\\n\\n /**\\n * @dev Moves `amount` tokens from the caller's account to `to`.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * Emits a {Transfer} event.\\n */\\n function transfer(address to, uint256 amount) external returns (bool);\\n\\n /**\\n * @dev Returns the remaining number of tokens that `spender` will be\\n * allowed to spend on behalf of `owner` through {transferFrom}. This is\\n * zero by default.\\n *\\n * This value changes when {approve} or {transferFrom} are called.\\n */\\n function allowance(address owner, address spender) external view returns (uint256);\\n\\n /**\\n * @dev Sets `amount` as the allowance of `spender` over the caller's tokens.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * IMPORTANT: Beware that changing an allowance with this method brings the risk\\n * that someone may use both the old and the new allowance by unfortunate\\n * transaction ordering. One possible solution to mitigate this race\\n * condition is to first reduce the spender's allowance to 0 and set the\\n * desired value afterwards:\\n * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729\\n *\\n * Emits an {Approval} event.\\n */\\n function approve(address spender, uint256 amount) external returns (bool);\\n\\n /**\\n * @dev Moves `amount` tokens from `from` to `to` using the\\n * allowance mechanism. `amount` is then deducted from the caller's\\n * allowance.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * Emits a {Transfer} event.\\n */\\n function transferFrom(\\n address from,\\n address to,\\n uint256 amount\\n ) external returns (bool);\\n}\\n\",\"keccak256\":\"0x9750c6b834f7b43000631af5cc30001c5f547b3ceb3635488f140f60e897ea6b\",\"license\":\"MIT\"},\"@openzeppelin/contracts/token/ERC20/extensions/draft-IERC20Permit.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (token/ERC20/extensions/draft-IERC20Permit.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Interface of the ERC20 Permit extension allowing approvals to be made via signatures, as defined in\\n * https://eips.ethereum.org/EIPS/eip-2612[EIP-2612].\\n *\\n * Adds the {permit} method, which can be used to change an account's ERC20 allowance (see {IERC20-allowance}) by\\n * presenting a message signed by the account. By not relying on {IERC20-approve}, the token holder account doesn't\\n * need to send a transaction, and thus is not required to hold Ether at all.\\n */\\ninterface IERC20Permit {\\n /**\\n * @dev Sets `value` as the allowance of `spender` over ``owner``'s tokens,\\n * given ``owner``'s signed approval.\\n *\\n * IMPORTANT: The same issues {IERC20-approve} has related to transaction\\n * ordering also apply here.\\n *\\n * Emits an {Approval} event.\\n *\\n * Requirements:\\n *\\n * - `spender` cannot be the zero address.\\n * - `deadline` must be a timestamp in the future.\\n * - `v`, `r` and `s` must be a valid `secp256k1` signature from `owner`\\n * over the EIP712-formatted function arguments.\\n * - the signature must use ``owner``'s current nonce (see {nonces}).\\n *\\n * For more information on the signature format, see the\\n * https://eips.ethereum.org/EIPS/eip-2612#specification[relevant EIP\\n * section].\\n */\\n function permit(\\n address owner,\\n address spender,\\n uint256 value,\\n uint256 deadline,\\n uint8 v,\\n bytes32 r,\\n bytes32 s\\n ) external;\\n\\n /**\\n * @dev Returns the current nonce for `owner`. This value must be\\n * included whenever a signature is generated for {permit}.\\n *\\n * Every successful call to {permit} increases ``owner``'s nonce by one. This\\n * prevents a signature from being used multiple times.\\n */\\n function nonces(address owner) external view returns (uint256);\\n\\n /**\\n * @dev Returns the domain separator used in the encoding of the signature for {permit}, as defined by {EIP712}.\\n */\\n // solhint-disable-next-line func-name-mixedcase\\n function DOMAIN_SEPARATOR() external view returns (bytes32);\\n}\\n\",\"keccak256\":\"0xf41ca991f30855bf80ffd11e9347856a517b977f0a6c2d52e6421a99b7840329\",\"license\":\"MIT\"},\"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.7.0) (token/ERC20/utils/SafeERC20.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../IERC20.sol\\\";\\nimport \\\"../extensions/draft-IERC20Permit.sol\\\";\\nimport \\\"../../../utils/Address.sol\\\";\\n\\n/**\\n * @title SafeERC20\\n * @dev Wrappers around ERC20 operations that throw on failure (when the token\\n * contract returns false). Tokens that return no value (and instead revert or\\n * throw on failure) are also supported, non-reverting calls are assumed to be\\n * successful.\\n * To use this library you can add a `using SafeERC20 for IERC20;` statement to your contract,\\n * which allows you to call the safe operations as `token.safeTransfer(...)`, etc.\\n */\\nlibrary SafeERC20 {\\n using Address for address;\\n\\n function safeTransfer(\\n IERC20 token,\\n address to,\\n uint256 value\\n ) internal {\\n _callOptionalReturn(token, abi.encodeWithSelector(token.transfer.selector, to, value));\\n }\\n\\n function safeTransferFrom(\\n IERC20 token,\\n address from,\\n address to,\\n uint256 value\\n ) internal {\\n _callOptionalReturn(token, abi.encodeWithSelector(token.transferFrom.selector, from, to, value));\\n }\\n\\n /**\\n * @dev Deprecated. This function has issues similar to the ones found in\\n * {IERC20-approve}, and its usage is discouraged.\\n *\\n * Whenever possible, use {safeIncreaseAllowance} and\\n * {safeDecreaseAllowance} instead.\\n */\\n function safeApprove(\\n IERC20 token,\\n address spender,\\n uint256 value\\n ) internal {\\n // safeApprove should only be called when setting an initial allowance,\\n // or when resetting it to zero. To increase and decrease it, use\\n // 'safeIncreaseAllowance' and 'safeDecreaseAllowance'\\n require(\\n (value == 0) || (token.allowance(address(this), spender) == 0),\\n \\\"SafeERC20: approve from non-zero to non-zero allowance\\\"\\n );\\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, value));\\n }\\n\\n function safeIncreaseAllowance(\\n IERC20 token,\\n address spender,\\n uint256 value\\n ) internal {\\n uint256 newAllowance = token.allowance(address(this), spender) + value;\\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));\\n }\\n\\n function safeDecreaseAllowance(\\n IERC20 token,\\n address spender,\\n uint256 value\\n ) internal {\\n unchecked {\\n uint256 oldAllowance = token.allowance(address(this), spender);\\n require(oldAllowance >= value, \\\"SafeERC20: decreased allowance below zero\\\");\\n uint256 newAllowance = oldAllowance - value;\\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));\\n }\\n }\\n\\n function safePermit(\\n IERC20Permit token,\\n address owner,\\n address spender,\\n uint256 value,\\n uint256 deadline,\\n uint8 v,\\n bytes32 r,\\n bytes32 s\\n ) internal {\\n uint256 nonceBefore = token.nonces(owner);\\n token.permit(owner, spender, value, deadline, v, r, s);\\n uint256 nonceAfter = token.nonces(owner);\\n require(nonceAfter == nonceBefore + 1, \\\"SafeERC20: permit did not succeed\\\");\\n }\\n\\n /**\\n * @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement\\n * on the return value: the return value is optional (but if data is returned, it must not be false).\\n * @param token The token targeted by the call.\\n * @param data The call data (encoded using abi.encode or one of its variants).\\n */\\n function _callOptionalReturn(IERC20 token, bytes memory data) private {\\n // We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since\\n // we're implementing it ourselves. We use {Address.functionCall} to perform this call, which verifies that\\n // the target address contains contract code and also asserts for success in the low-level call.\\n\\n bytes memory returndata = address(token).functionCall(data, \\\"SafeERC20: low-level call failed\\\");\\n if (returndata.length > 0) {\\n // Return data is optional\\n require(abi.decode(returndata, (bool)), \\\"SafeERC20: ERC20 operation did not succeed\\\");\\n }\\n }\\n}\\n\",\"keccak256\":\"0x032807210d1d7d218963d7355d62e021a84bf1b3339f4f50be2f63b53cccaf29\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/Address.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.7.0) (utils/Address.sol)\\n\\npragma solidity ^0.8.1;\\n\\n/**\\n * @dev Collection of functions related to the address type\\n */\\nlibrary Address {\\n /**\\n * @dev Returns true if `account` is a contract.\\n *\\n * [IMPORTANT]\\n * ====\\n * It is unsafe to assume that an address for which this function returns\\n * false is an externally-owned account (EOA) and not a contract.\\n *\\n * Among others, `isContract` will return false for the following\\n * types of addresses:\\n *\\n * - an externally-owned account\\n * - a contract in construction\\n * - an address where a contract will be created\\n * - an address where a contract lived, but was destroyed\\n * ====\\n *\\n * [IMPORTANT]\\n * ====\\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\\n *\\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\\n * constructor.\\n * ====\\n */\\n function isContract(address account) internal view returns (bool) {\\n // This method relies on extcodesize/address.code.length, which returns 0\\n // for contracts in construction, since the code is only stored at the end\\n // of the constructor execution.\\n\\n return account.code.length > 0;\\n }\\n\\n /**\\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\\n * `recipient`, forwarding all available gas and reverting on errors.\\n *\\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\\n * imposed by `transfer`, making them unable to receive funds via\\n * `transfer`. {sendValue} removes this limitation.\\n *\\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\\n *\\n * IMPORTANT: because control is transferred to `recipient`, care must be\\n * taken to not create reentrancy vulnerabilities. Consider using\\n * {ReentrancyGuard} or the\\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\\n */\\n function sendValue(address payable recipient, uint256 amount) internal {\\n require(address(this).balance >= amount, \\\"Address: insufficient balance\\\");\\n\\n (bool success, ) = recipient.call{value: amount}(\\\"\\\");\\n require(success, \\\"Address: unable to send value, recipient may have reverted\\\");\\n }\\n\\n /**\\n * @dev Performs a Solidity function call using a low level `call`. A\\n * plain `call` is an unsafe replacement for a function call: use this\\n * function instead.\\n *\\n * If `target` reverts with a revert reason, it is bubbled up by this\\n * function (like regular Solidity function calls).\\n *\\n * Returns the raw returned data. To convert to the expected return value,\\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\\n *\\n * Requirements:\\n *\\n * - `target` must be a contract.\\n * - calling `target` with `data` must not revert.\\n *\\n * _Available since v3.1._\\n */\\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\\n return functionCall(target, data, \\\"Address: low-level call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\\n * `errorMessage` as a fallback revert reason when `target` reverts.\\n *\\n * _Available since v3.1._\\n */\\n function functionCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n return functionCallWithValue(target, data, 0, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but also transferring `value` wei to `target`.\\n *\\n * Requirements:\\n *\\n * - the calling contract must have an ETH balance of at least `value`.\\n * - the called Solidity function must be `payable`.\\n *\\n * _Available since v3.1._\\n */\\n function functionCallWithValue(\\n address target,\\n bytes memory data,\\n uint256 value\\n ) internal returns (bytes memory) {\\n return functionCallWithValue(target, data, value, \\\"Address: low-level call with value failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\\n * with `errorMessage` as a fallback revert reason when `target` reverts.\\n *\\n * _Available since v3.1._\\n */\\n function functionCallWithValue(\\n address target,\\n bytes memory data,\\n uint256 value,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n require(address(this).balance >= value, \\\"Address: insufficient balance for call\\\");\\n require(isContract(target), \\\"Address: call to non-contract\\\");\\n\\n (bool success, bytes memory returndata) = target.call{value: value}(data);\\n return verifyCallResult(success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but performing a static call.\\n *\\n * _Available since v3.3._\\n */\\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\\n return functionStaticCall(target, data, \\\"Address: low-level static call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\\n * but performing a static call.\\n *\\n * _Available since v3.3._\\n */\\n function functionStaticCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal view returns (bytes memory) {\\n require(isContract(target), \\\"Address: static call to non-contract\\\");\\n\\n (bool success, bytes memory returndata) = target.staticcall(data);\\n return verifyCallResult(success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but performing a delegate call.\\n *\\n * _Available since v3.4._\\n */\\n function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {\\n return functionDelegateCall(target, data, \\\"Address: low-level delegate call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\\n * but performing a delegate call.\\n *\\n * _Available since v3.4._\\n */\\n function functionDelegateCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n require(isContract(target), \\\"Address: delegate call to non-contract\\\");\\n\\n (bool success, bytes memory returndata) = target.delegatecall(data);\\n return verifyCallResult(success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the\\n * revert reason using the provided one.\\n *\\n * _Available since v4.3._\\n */\\n function verifyCallResult(\\n bool success,\\n bytes memory returndata,\\n string memory errorMessage\\n ) internal pure returns (bytes memory) {\\n if (success) {\\n return returndata;\\n } else {\\n // Look for revert reason and bubble it up if present\\n if (returndata.length > 0) {\\n // The easiest way to bubble the revert reason is using memory via assembly\\n /// @solidity memory-safe-assembly\\n assembly {\\n let returndata_size := mload(returndata)\\n revert(add(32, returndata), returndata_size)\\n }\\n } else {\\n revert(errorMessage);\\n }\\n }\\n }\\n}\\n\",\"keccak256\":\"0xd6153ce99bcdcce22b124f755e72553295be6abcd63804cfdffceb188b8bef10\",\"license\":\"MIT\"},\"contracts/agToken/AgToken.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-3.0\\n\\npragma solidity ^0.8.12;\\n\\n/*\\n * \\u2588 \\n ***** \\u2593\\u2593\\u2593 \\n * \\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593 \\n * ///. \\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593 \\n ***** //////// \\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593 \\n * ///////////// \\u2593\\u2593\\u2593 \\n \\u2593\\u2593 ////////////////// \\u2588 \\u2593\\u2593 \\n \\u2593\\u2593 \\u2593\\u2593 /////////////////////// \\u2593\\u2593 \\u2593\\u2593 \\n \\u2593\\u2593 \\u2593\\u2593 //////////////////////////// \\u2593\\u2593 \\u2593\\u2593 \\n \\u2593\\u2593 \\u2593\\u2593 /////////\\u2593\\u2593\\u2593///////\\u2593\\u2593\\u2593///////// \\u2593\\u2593 \\u2593\\u2593 \\n \\u2593\\u2593 ,////////////////////////////////////// \\u2593\\u2593 \\u2593\\u2593 \\n \\u2593\\u2593 ////////////////////////////////////////// \\u2593\\u2593 \\n \\u2593\\u2593 //////////////////////\\u2593\\u2593\\u2593\\u2593///////////////////// \\n ,//////////////////////////////////////////////////// \\n .////////////////////////////////////////////////////////// \\n .//////////////////////////\\u2588\\u2588.,//////////////////////////\\u2588 \\n .//////////////////////\\u2588\\u2588\\u2588\\u2588..,./////////////////////\\u2588\\u2588 \\n ...////////////////\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588.....,.////////////////\\u2588\\u2588\\u2588 \\n ,.,////////////\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588 ........,///////////\\u2588\\u2588\\u2588\\u2588 \\n .,.,//////\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588 ,.......///////\\u2588\\u2588\\u2588\\u2588 \\n ,..//\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588 ........./\\u2588\\u2588\\u2588\\u2588 \\n ..,\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588 .....,\\u2588\\u2588\\u2588 \\n .\\u2588\\u2588 ,.,\\u2588 \\n \\n \\n \\n \\u2593\\u2593 \\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593 \\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593 \\u2593\\u2593 \\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593 \\n \\u2593\\u2593\\u2593\\u2593\\u2593\\u2593 \\u2593\\u2593\\u2593 \\u2593\\u2593\\u2593 \\u2593\\u2593\\u2593 \\u2593\\u2593 \\u2593\\u2593 \\u2593\\u2593\\u2593\\u2593 \\n \\u2593\\u2593\\u2593 \\u2593\\u2593\\u2593 \\u2593\\u2593\\u2593 \\u2593\\u2593\\u2593 \\u2593\\u2593\\u2593 \\u2593\\u2593\\u2593 \\u2593\\u2593 \\u2593\\u2593\\u2593\\u2593\\u2593 \\n \\u2593\\u2593\\u2593 \\u2593\\u2593 \\u2593\\u2593\\u2593 \\u2593\\u2593\\u2593 \\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593 \\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593 \\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593 \\n*/\\n\\nimport \\\"../interfaces/IAgToken.sol\\\";\\nimport \\\"../interfaces/ITreasury.sol\\\";\\nimport \\\"@openzeppelin/contracts-upgradeable/token/ERC20/extensions/draft-ERC20PermitUpgradeable.sol\\\";\\n\\n/// @title AgToken\\n/// @author Angle Labs, Inc.\\n/// @notice Base contract for Angle agTokens on Ethereum and on other chains\\n/// @dev By default, agTokens are ERC-20 tokens with 18 decimals\\ncontract AgToken is IAgToken, ERC20PermitUpgradeable {\\n // =========================== PARAMETERS / VARIABLES ==========================\\n\\n /// @inheritdoc IAgToken\\n mapping(address => bool) public isMinter;\\n /// @notice Reference to the treasury contract which can grant minting rights\\n address public treasury;\\n\\n // =================================== EVENTS ==================================\\n\\n event TreasuryUpdated(address indexed _treasury);\\n event MinterToggled(address indexed minter);\\n\\n // =================================== ERRORS ==================================\\n\\n error BurnAmountExceedsAllowance();\\n error InvalidSender();\\n error InvalidTreasury();\\n error NotMinter();\\n error NotTreasury();\\n\\n // ================================ CONSTRUCTOR ================================\\n\\n /// @custom:oz-upgrades-unsafe-allow constructor\\n constructor() initializer {}\\n\\n /// @notice Initializes the `AgToken` contract\\n function initialize(string memory name_, string memory symbol_, address _treasury) external {\\n _initialize(name_, symbol_, _treasury);\\n }\\n\\n /// @notice Initializes the contract\\n function _initialize(string memory name_, string memory symbol_, address _treasury) internal virtual initializer {\\n if (address(ITreasury(_treasury).stablecoin()) != address(this)) revert InvalidTreasury();\\n __ERC20Permit_init(name_);\\n __ERC20_init(name_, symbol_);\\n treasury = _treasury;\\n emit TreasuryUpdated(_treasury);\\n }\\n\\n // ================================= MODIFIERS =================================\\n\\n /// @notice Checks to see if it is the `Treasury` calling this contract\\n modifier onlyTreasury() {\\n if (msg.sender != treasury) revert NotTreasury();\\n _;\\n }\\n\\n /// @notice Checks whether the sender has the minting right\\n modifier onlyMinter() {\\n if (!isMinter[msg.sender]) revert NotMinter();\\n _;\\n }\\n\\n // ============================= EXTERNAL FUNCTION =============================\\n\\n /// @notice Allows anyone to burn stablecoins\\n /// @param amount Amount of stablecoins to burn\\n /// @dev This function can typically be called if there is a settlement mechanism to burn stablecoins\\n function burnStablecoin(uint256 amount) external {\\n _burn(msg.sender, amount);\\n }\\n\\n // ========================= MINTER ROLE ONLY FUNCTIONS ========================\\n\\n /// @inheritdoc IAgToken\\n function burnSelf(uint256 amount, address burner) external onlyMinter {\\n _burn(burner, amount);\\n }\\n\\n /// @inheritdoc IAgToken\\n function burnFrom(uint256 amount, address burner, address sender) external onlyMinter {\\n if (burner != sender) {\\n uint256 currentAllowance = allowance(burner, sender);\\n if (currentAllowance < amount) revert BurnAmountExceedsAllowance();\\n _approve(burner, sender, currentAllowance - amount);\\n }\\n _burn(burner, amount);\\n }\\n\\n /// @inheritdoc IAgToken\\n function mint(address account, uint256 amount) external onlyMinter {\\n _mint(account, amount);\\n }\\n\\n // ========================== GOVERNANCE ONLY FUNCTIONS ==========================\\n\\n /// @inheritdoc IAgToken\\n function addMinter(address minter) external onlyTreasury {\\n isMinter[minter] = true;\\n emit MinterToggled(minter);\\n }\\n\\n /// @inheritdoc IAgToken\\n function removeMinter(address minter) external {\\n if (msg.sender != address(treasury) && msg.sender != minter) revert InvalidSender();\\n isMinter[minter] = false;\\n emit MinterToggled(minter);\\n }\\n\\n /// @inheritdoc IAgToken\\n function setTreasury(address _treasury) external virtual onlyTreasury {\\n treasury = _treasury;\\n emit TreasuryUpdated(_treasury);\\n }\\n}\\n\",\"keccak256\":\"0x671d54d7840179050e859cf09662fe0e2c34cfaf5ec3782148d6c29e77c54d17\",\"license\":\"GPL-3.0\"},\"contracts/agToken/AgTokenSideChainMultiBridge.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-3.0\\n\\npragma solidity ^0.8.12;\\n\\nimport \\\"./AgToken.sol\\\";\\nimport \\\"@openzeppelin/contracts/token/ERC20/IERC20.sol\\\";\\nimport \\\"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\\\";\\n\\n/// @title AgTokenSideChainMultiBridge\\n/// @author Angle Labs, Inc.\\n/// @notice Contract for Angle agTokens on other chains than Ethereum mainnet\\n/// @dev This contract supports bridge tokens having a minting right on the stablecoin (also referred to as the canonical\\n/// or the native token)\\ncontract AgTokenSideChainMultiBridge is AgToken {\\n using SafeERC20 for IERC20;\\n\\n /// @notice Base used for fee computation\\n uint256 public constant BASE_PARAMS = 1e9;\\n\\n // =============================== BRIDGING DATA ===============================\\n\\n /// @notice Struct with some data about a specific bridge token\\n struct BridgeDetails {\\n // Limit on the balance of bridge token held by the contract: it is designed\\n // to reduce the exposure of the system to hacks\\n uint256 limit;\\n // Limit on the hourly volume of token minted through this bridge\\n // Technically the limit over a rolling hour is hourlyLimit x2 as hourly limit\\n // is enforced only between x:00 and x+1:00\\n uint256 hourlyLimit;\\n // Fee taken for swapping in and out the token\\n uint64 fee;\\n // Whether the associated token is allowed or not\\n bool allowed;\\n // Whether swapping in and out from the associated token is paused or not\\n bool paused;\\n }\\n\\n /// @notice Maps a bridge token to data\\n mapping(address => BridgeDetails) public bridges;\\n /// @notice List of all bridge tokens\\n address[] public bridgeTokensList;\\n /// @notice Maps a bridge token to the associated hourly volume\\n mapping(address => mapping(uint256 => uint256)) public usage;\\n /// @notice Maps an address to whether it is exempt of fees for when it comes to swapping in and out\\n mapping(address => uint256) public isFeeExempt;\\n /// @notice Limit to the amount of tokens that can be sent from that chain to another chain\\n uint256 public chainTotalHourlyLimit;\\n /// @notice Usage per hour on that chain. Maps an hourly timestamp to the total volume swapped out on the chain\\n mapping(uint256 => uint256) public chainTotalUsage;\\n\\n // =================================== EVENTS ==================================\\n\\n event BridgeTokenAdded(address indexed bridgeToken, uint256 limit, uint256 hourlyLimit, uint64 fee, bool paused);\\n event BridgeTokenToggled(address indexed bridgeToken, bool toggleStatus);\\n event BridgeTokenRemoved(address indexed bridgeToken);\\n event BridgeTokenFeeUpdated(address indexed bridgeToken, uint64 fee);\\n event BridgeTokenLimitUpdated(address indexed bridgeToken, uint256 limit);\\n event BridgeTokenHourlyLimitUpdated(address indexed bridgeToken, uint256 hourlyLimit);\\n event HourlyLimitUpdated(uint256 hourlyLimit);\\n event Recovered(address indexed token, address indexed to, uint256 amount);\\n event FeeToggled(address indexed theAddress, uint256 toggleStatus);\\n\\n // =================================== ERRORS ==================================\\n\\n error AssetStillControlledInReserves();\\n error HourlyLimitExceeded();\\n error InvalidToken();\\n error NotGovernor();\\n error NotGovernorOrGuardian();\\n error TooBigAmount();\\n error TooHighParameterValue();\\n error ZeroAddress();\\n\\n // ================================= MODIFIERS =================================\\n\\n /// @notice Checks whether the `msg.sender` has the governor role or not\\n modifier onlyGovernor() {\\n if (!ITreasury(treasury).isGovernor(msg.sender)) revert NotGovernor();\\n _;\\n }\\n\\n /// @notice Checks whether the `msg.sender` has the governor role or the guardian role\\n modifier onlyGovernorOrGuardian() {\\n if (!ITreasury(treasury).isGovernorOrGuardian(msg.sender)) revert NotGovernorOrGuardian();\\n _;\\n }\\n\\n // ===================== EXTERNAL PERMISSIONLESS FUNCTIONS =====================\\n\\n /// @notice Returns the list of all supported bridge tokens\\n /// @dev Helpful for UIs\\n function allBridgeTokens() external view returns (address[] memory) {\\n return bridgeTokensList;\\n }\\n\\n /// @notice Returns the current volume for a bridge, for the current hour\\n /// @param bridgeToken Bridge used to mint\\n /// @dev Helpful for UIs\\n function currentUsage(address bridgeToken) external view returns (uint256) {\\n return usage[bridgeToken][block.timestamp / 3600];\\n }\\n\\n /// @notice Returns the current total volume on the chain for the current hour\\n /// @dev Helpful for UIs\\n function currentTotalUsage() external view returns (uint256) {\\n return chainTotalUsage[block.timestamp / 3600];\\n }\\n\\n /// @notice Mints the canonical token from a supported bridge token\\n /// @param bridgeToken Bridge token to use to mint\\n /// @param amount Amount of bridge tokens to send\\n /// @param to Address to which the stablecoin should be sent\\n /// @return Amount of the canonical stablecoin actually minted\\n /// @dev Some fees may be taken by the protocol depending on the token used and on the address calling\\n function swapIn(address bridgeToken, uint256 amount, address to) external returns (uint256) {\\n BridgeDetails memory bridgeDetails = bridges[bridgeToken];\\n if (!bridgeDetails.allowed || bridgeDetails.paused) revert InvalidToken();\\n uint256 balance = IERC20(bridgeToken).balanceOf(address(this));\\n if (balance + amount > bridgeDetails.limit) {\\n // In case someone maliciously sends tokens to this contract\\n // Or the limit changes\\n if (bridgeDetails.limit > balance) amount = bridgeDetails.limit - balance;\\n else {\\n amount = 0;\\n }\\n }\\n\\n // Checking requirement on the hourly volume\\n uint256 hour = block.timestamp / 3600;\\n uint256 hourlyUsage = usage[bridgeToken][hour];\\n if (hourlyUsage + amount > bridgeDetails.hourlyLimit) {\\n // Edge case when the hourly limit changes\\n amount = bridgeDetails.hourlyLimit > hourlyUsage ? bridgeDetails.hourlyLimit - hourlyUsage : 0;\\n }\\n usage[bridgeToken][hour] = hourlyUsage + amount;\\n\\n IERC20(bridgeToken).safeTransferFrom(msg.sender, address(this), amount);\\n uint256 canonicalOut = amount;\\n // Computing fees\\n if (isFeeExempt[msg.sender] == 0) {\\n canonicalOut -= (canonicalOut * bridgeDetails.fee) / BASE_PARAMS;\\n }\\n _mint(to, canonicalOut);\\n return canonicalOut;\\n }\\n\\n /// @notice Burns the canonical token in exchange for a bridge token\\n /// @param bridgeToken Bridge token required\\n /// @param amount Amount of canonical tokens to burn\\n /// @param to Address to which the bridge token should be sent\\n /// @return Amount of bridge tokens actually sent back\\n /// @dev Some fees may be taken by the protocol depending on the token used and on the address calling\\n function swapOut(address bridgeToken, uint256 amount, address to) external returns (uint256) {\\n BridgeDetails memory bridgeDetails = bridges[bridgeToken];\\n if (!bridgeDetails.allowed || bridgeDetails.paused) revert InvalidToken();\\n\\n uint256 hour = block.timestamp / 3600;\\n uint256 hourlyUsage = chainTotalUsage[hour] + amount;\\n // If the amount being swapped out exceeds the limit, we revert\\n // We don't want to change the amount being swapped out.\\n // The user can decide to send another tx with the correct amount to reach the limit\\n if (hourlyUsage > chainTotalHourlyLimit) revert HourlyLimitExceeded();\\n chainTotalUsage[hour] = hourlyUsage;\\n\\n _burn(msg.sender, amount);\\n uint256 bridgeOut = amount;\\n if (isFeeExempt[msg.sender] == 0) {\\n bridgeOut -= (bridgeOut * bridgeDetails.fee) / BASE_PARAMS;\\n }\\n IERC20(bridgeToken).safeTransfer(to, bridgeOut);\\n return bridgeOut;\\n }\\n\\n // ============================ GOVERNANCE FUNCTIONS ===========================\\n\\n /// @notice Adds support for a bridge token\\n /// @param bridgeToken Bridge token to add: it should be a version of the stablecoin from another bridge\\n /// @param limit Limit on the balance of bridge token this contract could hold\\n /// @param hourlyLimit Limit on the hourly volume for this bridge\\n /// @param paused Whether swapping for this token should be paused or not\\n /// @param fee Fee taken upon swapping for or against this token\\n function addBridgeToken(\\n address bridgeToken,\\n uint256 limit,\\n uint256 hourlyLimit,\\n uint64 fee,\\n bool paused\\n ) external onlyGovernor {\\n if (bridges[bridgeToken].allowed || bridgeToken == address(0)) revert InvalidToken();\\n if (fee > BASE_PARAMS) revert TooHighParameterValue();\\n BridgeDetails memory _bridge;\\n _bridge.limit = limit;\\n _bridge.hourlyLimit = hourlyLimit;\\n _bridge.paused = paused;\\n _bridge.fee = fee;\\n _bridge.allowed = true;\\n bridges[bridgeToken] = _bridge;\\n bridgeTokensList.push(bridgeToken);\\n emit BridgeTokenAdded(bridgeToken, limit, hourlyLimit, fee, paused);\\n }\\n\\n /// @notice Removes support for a token\\n /// @param bridgeToken Address of the bridge token to remove support for\\n function removeBridgeToken(address bridgeToken) external onlyGovernor {\\n if (IERC20(bridgeToken).balanceOf(address(this)) != 0) revert AssetStillControlledInReserves();\\n delete bridges[bridgeToken];\\n // Deletion from `bridgeTokensList` loop\\n uint256 bridgeTokensListLength = bridgeTokensList.length;\\n for (uint256 i; i < bridgeTokensListLength - 1; ++i) {\\n if (bridgeTokensList[i] == bridgeToken) {\\n // Replace the `bridgeToken` to remove with the last of the list\\n bridgeTokensList[i] = bridgeTokensList[bridgeTokensListLength - 1];\\n break;\\n }\\n }\\n // Remove last element in array\\n bridgeTokensList.pop();\\n emit BridgeTokenRemoved(bridgeToken);\\n }\\n\\n /// @notice Recovers any ERC20 token\\n /// @dev Can be used to withdraw bridge tokens for them to be de-bridged on mainnet\\n function recoverERC20(address tokenAddress, address to, uint256 amountToRecover) external onlyGovernor {\\n IERC20(tokenAddress).safeTransfer(to, amountToRecover);\\n emit Recovered(tokenAddress, to, amountToRecover);\\n }\\n\\n /// @notice Updates the `limit` amount for `bridgeToken`\\n function setLimit(address bridgeToken, uint256 limit) external onlyGovernorOrGuardian {\\n if (!bridges[bridgeToken].allowed) revert InvalidToken();\\n bridges[bridgeToken].limit = limit;\\n emit BridgeTokenLimitUpdated(bridgeToken, limit);\\n }\\n\\n /// @notice Updates the `hourlyLimit` amount for `bridgeToken`\\n function setHourlyLimit(address bridgeToken, uint256 hourlyLimit) external onlyGovernorOrGuardian {\\n if (!bridges[bridgeToken].allowed) revert InvalidToken();\\n bridges[bridgeToken].hourlyLimit = hourlyLimit;\\n emit BridgeTokenHourlyLimitUpdated(bridgeToken, hourlyLimit);\\n }\\n\\n /// @notice Updates the `chainTotalHourlyLimit` amount\\n function setChainTotalHourlyLimit(uint256 hourlyLimit) external onlyGovernorOrGuardian {\\n chainTotalHourlyLimit = hourlyLimit;\\n emit HourlyLimitUpdated(hourlyLimit);\\n }\\n\\n /// @notice Updates the `fee` value for `bridgeToken`\\n function setSwapFee(address bridgeToken, uint64 fee) external onlyGovernorOrGuardian {\\n if (!bridges[bridgeToken].allowed) revert InvalidToken();\\n if (fee > BASE_PARAMS) revert TooHighParameterValue();\\n bridges[bridgeToken].fee = fee;\\n emit BridgeTokenFeeUpdated(bridgeToken, fee);\\n }\\n\\n /// @notice Pauses or unpauses swapping in and out for a token\\n function toggleBridge(address bridgeToken) external onlyGovernorOrGuardian {\\n if (!bridges[bridgeToken].allowed) revert InvalidToken();\\n bool pausedStatus = bridges[bridgeToken].paused;\\n bridges[bridgeToken].paused = !pausedStatus;\\n emit BridgeTokenToggled(bridgeToken, !pausedStatus);\\n }\\n\\n /// @notice Toggles fees for the address `theAddress`\\n function toggleFeesForAddress(address theAddress) external onlyGovernorOrGuardian {\\n uint256 feeExemptStatus = 1 - isFeeExempt[theAddress];\\n isFeeExempt[theAddress] = feeExemptStatus;\\n emit FeeToggled(theAddress, feeExemptStatus);\\n }\\n}\\n\",\"keccak256\":\"0x9782497e84a1dc4bc468778ede4aceb35cebf74e4159e2af8f469f49312c3841\",\"license\":\"GPL-3.0\"},\"contracts/interfaces/IAgToken.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-3.0\\n\\npragma solidity ^0.8.12;\\n\\nimport \\\"@openzeppelin/contracts-upgradeable/token/ERC20/IERC20Upgradeable.sol\\\";\\n\\n/// @title IAgToken\\n/// @author Angle Labs, Inc.\\n/// @notice Interface for the stablecoins `AgToken` contracts\\n/// @dev This interface only contains functions of the `AgToken` contract which are called by other contracts\\n/// of this module or of the first module of the Angle Protocol\\ninterface IAgToken is IERC20Upgradeable {\\n // ======================= Minter Role Only Functions ===========================\\n\\n /// @notice Lets the `StableMaster` contract or another whitelisted contract mint agTokens\\n /// @param account Address to mint to\\n /// @param amount Amount to mint\\n /// @dev The contracts allowed to issue agTokens are the `StableMaster` contract, `VaultManager` contracts\\n /// associated to this stablecoin as well as the flash loan module (if activated) and potentially contracts\\n /// whitelisted by governance\\n function mint(address account, uint256 amount) external;\\n\\n /// @notice Burns `amount` tokens from a `burner` address after being asked to by `sender`\\n /// @param amount Amount of tokens to burn\\n /// @param burner Address to burn from\\n /// @param sender Address which requested the burn from `burner`\\n /// @dev This method is to be called by a contract with the minter right after being requested\\n /// to do so by a `sender` address willing to burn tokens from another `burner` address\\n /// @dev The method checks the allowance between the `sender` and the `burner`\\n function burnFrom(uint256 amount, address burner, address sender) external;\\n\\n /// @notice Burns `amount` tokens from a `burner` address\\n /// @param amount Amount of tokens to burn\\n /// @param burner Address to burn from\\n /// @dev This method is to be called by a contract with a minter right on the AgToken after being\\n /// requested to do so by an address willing to burn tokens from its address\\n function burnSelf(uint256 amount, address burner) external;\\n\\n // ========================= Treasury Only Functions ===========================\\n\\n /// @notice Adds a minter in the contract\\n /// @param minter Minter address to add\\n /// @dev Zero address checks are performed directly in the `Treasury` contract\\n function addMinter(address minter) external;\\n\\n /// @notice Removes a minter from the contract\\n /// @param minter Minter address to remove\\n /// @dev This function can also be called by a minter wishing to revoke itself\\n function removeMinter(address minter) external;\\n\\n /// @notice Sets a new treasury contract\\n /// @param _treasury New treasury address\\n function setTreasury(address _treasury) external;\\n\\n // ========================= External functions ================================\\n\\n /// @notice Checks whether an address has the right to mint agTokens\\n /// @param minter Address for which the minting right should be checked\\n /// @return Whether the address has the right to mint agTokens or not\\n function isMinter(address minter) external view returns (bool);\\n\\n /// @notice Get the associated treasury\\n function treasury() external view returns (address);\\n}\\n\",\"keccak256\":\"0x0c83efcfc1fb9ae9ba830f7b89e3dab9abf6ad7a6205a31aa35fbccaa837dcdc\",\"license\":\"GPL-3.0\"},\"contracts/interfaces/ICoreBorrow.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-3.0\\n\\npragma solidity ^0.8.12;\\n\\n/// @title ICoreBorrow\\n/// @author Angle Labs, Inc.\\n/// @notice Interface for the `CoreBorrow` contract\\n/// @dev This interface only contains functions of the `CoreBorrow` contract which are called by other contracts\\n/// of this module\\ninterface ICoreBorrow {\\n /// @notice Checks if an address corresponds to a treasury of a stablecoin with a flash loan\\n /// module initialized on it\\n /// @param treasury Address to check\\n /// @return Whether the address has the `FLASHLOANER_TREASURY_ROLE` or not\\n function isFlashLoanerTreasury(address treasury) external view returns (bool);\\n\\n /// @notice Checks whether an address is governor of the Angle Protocol or not\\n /// @param admin Address to check\\n /// @return Whether the address has the `GOVERNOR_ROLE` or not\\n function isGovernor(address admin) external view returns (bool);\\n\\n /// @notice Checks whether an address is governor or a guardian of the Angle Protocol or not\\n /// @param admin Address to check\\n /// @return Whether the address has the `GUARDIAN_ROLE` or not\\n /// @dev Governance should make sure when adding a governor to also give this governor the guardian\\n /// role by calling the `addGovernor` function\\n function isGovernorOrGuardian(address admin) external view returns (bool);\\n}\\n\",\"keccak256\":\"0x10249210cbf522775f040baf981d7d037472168ce2746d87473ac7c29a34e62e\",\"license\":\"GPL-3.0\"},\"contracts/interfaces/IFlashAngle.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-3.0\\n\\npragma solidity ^0.8.12;\\n\\nimport \\\"./IAgToken.sol\\\";\\nimport \\\"./ICoreBorrow.sol\\\";\\n\\n/// @title IFlashAngle\\n/// @author Angle Labs, Inc.\\n/// @notice Interface for the `FlashAngle` contract\\n/// @dev This interface only contains functions of the contract which are called by other contracts\\n/// of this module\\ninterface IFlashAngle {\\n /// @notice Reference to the `CoreBorrow` contract managing the FlashLoan module\\n function core() external view returns (ICoreBorrow);\\n\\n /// @notice Sends the fees taken from flash loans to the treasury contract associated to the stablecoin\\n /// @param stablecoin Stablecoin from which profits should be sent\\n /// @return balance Amount of profits sent\\n /// @dev This function can only be called by the treasury contract\\n function accrueInterestToTreasury(IAgToken stablecoin) external returns (uint256 balance);\\n\\n /// @notice Adds support for a stablecoin\\n /// @param _treasury Treasury associated to the stablecoin to add support for\\n /// @dev This function can only be called by the `CoreBorrow` contract\\n function addStablecoinSupport(address _treasury) external;\\n\\n /// @notice Removes support for a stablecoin\\n /// @param _treasury Treasury associated to the stablecoin to remove support for\\n /// @dev This function can only be called by the `CoreBorrow` contract\\n function removeStablecoinSupport(address _treasury) external;\\n\\n /// @notice Sets a new core contract\\n /// @param _core Core contract address to set\\n /// @dev This function can only be called by the `CoreBorrow` contract\\n function setCore(address _core) external;\\n}\\n\",\"keccak256\":\"0x39b0097f695b9e934bccdc72676c91513f1077cc5d0fd151908fd25a7c5cfbe4\",\"license\":\"GPL-3.0\"},\"contracts/interfaces/ITreasury.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-3.0\\n\\npragma solidity ^0.8.12;\\n\\nimport \\\"./IAgToken.sol\\\";\\nimport \\\"./ICoreBorrow.sol\\\";\\nimport \\\"./IFlashAngle.sol\\\";\\n\\n/// @title ITreasury\\n/// @author Angle Labs, Inc.\\n/// @notice Interface for the `Treasury` contract\\n/// @dev This interface only contains functions of the `Treasury` which are called by other contracts\\n/// of this module\\ninterface ITreasury {\\n /// @notice Stablecoin handled by this `treasury` contract\\n function stablecoin() external view returns (IAgToken);\\n\\n /// @notice Checks whether a given address has the governor role\\n /// @param admin Address to check\\n /// @return Whether the address has the governor role\\n /// @dev Access control is only kept in the `CoreBorrow` contract\\n function isGovernor(address admin) external view returns (bool);\\n\\n /// @notice Checks whether a given address has the guardian or the governor role\\n /// @param admin Address to check\\n /// @return Whether the address has the guardian or the governor role\\n /// @dev Access control is only kept in the `CoreBorrow` contract which means that this function\\n /// queries the `CoreBorrow` contract\\n function isGovernorOrGuardian(address admin) external view returns (bool);\\n\\n /// @notice Checks whether a given address has well been initialized in this contract\\n /// as a `VaultManager`\\n /// @param _vaultManager Address to check\\n /// @return Whether the address has been initialized or not\\n function isVaultManager(address _vaultManager) external view returns (bool);\\n\\n /// @notice Sets a new flash loan module for this stablecoin\\n /// @param _flashLoanModule Reference to the new flash loan module\\n /// @dev This function removes the minting right to the old flash loan module and grants\\n /// it to the new module\\n function setFlashLoanModule(address _flashLoanModule) external;\\n\\n /// @notice Gets the vault manager list\\n function vaultManagerList(uint256 i) external returns (address);\\n}\\n\",\"keccak256\":\"0x06c2f781c08732ce1b5845c083af5742716245baa6c519bd737f32b230a884c1\",\"license\":\"GPL-3.0\"}},\"version\":1}", + "bytecode": "0x60806040523480156200001157600080fd5b50600054610100900460ff1615808015620000335750600054600160ff909116105b8062000063575062000050306200013d60201b6200273a1760201c565b15801562000063575060005460ff166001145b620000cb5760405162461bcd60e51b815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201526d191e481a5b9a5d1a585b1a5e995960921b606482015260840160405180910390fd5b6000805460ff191660011790558015620000ef576000805461ff0019166101001790555b801562000136576000805461ff0019169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15b506200014c565b6001600160a01b03163b151590565b6146d0806200015c6000396000f3fe608060405234801561001057600080fd5b50600436106102ff5760003560e01c806361d027b31161019c5780639f48118f116100ee578063ced67f0c11610097578063dd62ed3e11610071578063dd62ed3e14610724578063e3e286551461076a578063f0f442601461077d57600080fd5b8063ced67f0c1461066b578063d44ad63f146106fe578063d505accf1461071157600080fd5b8063aa271e1a116100c8578063aa271e1a14610620578063ba330bd714610643578063cd4839ca1461065657600080fd5b80639f48118f146105ef578063a457c2d7146105fa578063a9059cbb1461060d57600080fd5b80637ecebe001161015057806395d89b411161012a57806395d89b41146105c1578063983b2d56146105c95780639e4e0dae146105dc57600080fd5b80637ecebe00146105705780638933fb791461058357806390218cff146105ae57600080fd5b80637334d020116101815780637334d020146105425780637d4c9c2d146105555780637d74e25f1461056857600080fd5b806361d027b3146104c757806370a082311461050c57600080fd5b80633092afd511610255578063395093511161020957806340c10f19116101e357806340c10f19146104815780634dc32fcc146104945780635bfbec96146104a757600080fd5b8063395093511461043b5780633a55f89d1461044e5780633f4218e01461046157600080fd5b8063350ebe041161023a578063350ebe041461040d5780633644e5151461042057806336db43b51461042857600080fd5b80633092afd5146103eb578063313ce567146103fe57600080fd5b8063151dd755116102b757806323b872dd1161029157806323b872dd146103b25780632b471d8e146103c55780632e403e14146103d857600080fd5b8063151dd7551461038057806318160ddd146103a15780632342fb0e146103a957600080fd5b80630919a951116102e85780630919a95114610337578063095ea7b31461034a5780631171bda91461036d57600080fd5b806306fdde0314610304578063077f224a14610322575b600080fd5b61030c610790565b6040516103199190613e48565b60405180910390f35b610335610330366004613f95565b610822565b005b61033561034536600461400d565b610832565b61035d61035836600461402a565b610995565b6040519015158152602001610319565b61033561037b366004614056565b6109af565b61039361038e366004614097565b610b04565b604051908152602001610319565b603554610393565b61039360d25481565b61035d6103c0366004614056565b610dbe565b6103356103d33660046140ce565b610de2565b6103356103e636600461400d565b610e39565b6103356103f936600461400d565b6111e8565b60405160128152602001610319565b61033561041b3660046140fe565b6112d1565b6103936113da565b61033561043636600461402a565b6113e9565b61035d61044936600461402a565b611579565b61033561045c366004614135565b6115c0565b61039361046f36600461400d565b60d16020526000908152604090205481565b61033561048f36600461402a565b6116c3565b6103936104a236600461400d565b611716565b6103936104b5366004614135565b60d36020526000908152604090205481565b60cd546104e79073ffffffffffffffffffffffffffffffffffffffff1681565b60405173ffffffffffffffffffffffffffffffffffffffff9091168152602001610319565b61039361051a36600461400d565b73ffffffffffffffffffffffffffffffffffffffff1660009081526033602052604090205490565b61033561055036600461402a565b61175e565b610335610563366004614179565b6118f1565b610393611c59565b61039361057e36600461400d565b611c7e565b61039361059136600461402a565b60d060209081526000928352604080842090915290825290205481565b6103356105bc366004614135565b611ca9565b61030c611cb6565b6103356105d736600461400d565b611cc5565b6103356105ea3660046141d6565b611d8d565b610393633b9aca0081565b61035d61060836600461402a565b611f99565b61035d61061b36600461402a565b61206f565b61035d61062e36600461400d565b60cc6020526000908152604090205460ff1681565b6104e7610651366004614135565b61207d565b61065e6120b4565b604051610319919061420b565b6106c561067936600461400d565b60ce6020526000908152604090208054600182015460029092015490919067ffffffffffffffff81169060ff680100000000000000008204811691690100000000000000000090041685565b60408051958652602086019490945267ffffffffffffffff9092169284019290925290151560608301521515608082015260a001610319565b61039361070c366004614097565b612122565b61033561071f366004614265565b6122e7565b6103936107323660046142dc565b73ffffffffffffffffffffffffffffffffffffffff918216600090815260346020908152604080832093909416825291909152205490565b61033561077836600461400d565b6124a6565b61033561078b36600461400d565b61267a565b60606036805461079f9061430a565b80601f01602080910402602001604051908101604052809291908181526020018280546107cb9061430a565b80156108185780601f106107ed57610100808354040283529160200191610818565b820191906000526020600020905b8154815290600101906020018083116107fb57829003601f168201915b5050505050905090565b61082d838383612756565b505050565b60cd546040517f521d4de900000000000000000000000000000000000000000000000000000000815233600482015273ffffffffffffffffffffffffffffffffffffffff9091169063521d4de990602401602060405180830381865afa1580156108a0573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906108c49190614357565b6108fa576040517f99e120bc00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff8116600090815260d1602052604081205461092b9060016143a3565b73ffffffffffffffffffffffffffffffffffffffff8316600081815260d160205260409081902083905551919250907f979ef83e7e7a87cb48064e296dd7e997870d50f43acf8d7ad221313526c8ca0f906109899084815260200190565b60405180910390a25050565b6000336109a3818585612a35565b60019150505b92915050565b60cd546040517fe43581b800000000000000000000000000000000000000000000000000000000815233600482015273ffffffffffffffffffffffffffffffffffffffff9091169063e43581b890602401602060405180830381865afa158015610a1d573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610a419190614357565b610a77576040517fee3675d400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b610a9873ffffffffffffffffffffffffffffffffffffffff84168383612be0565b8173ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff167ffff3b3844276f57024e0b42afec1a37f75db36511e43819a4f2a63ab7862b64883604051610af791815260200190565b60405180910390a3505050565b73ffffffffffffffffffffffffffffffffffffffff8316600090815260ce60209081526040808320815160a081018352815481526001820154938101939093526002015467ffffffffffffffff81169183019190915260ff680100000000000000008204811615801560608501526901000000000000000000909204161515608083015280610b94575080608001515b15610bcb576040517fc1ab6dc100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015260009073ffffffffffffffffffffffffffffffffffffffff8716906370a0823190602401602060405180830381865afa158015610c38573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610c5c91906143b6565b8251909150610c6b86836143cf565b1115610c93578151811015610c8e578151610c879082906143a3565b9450610c93565b600094505b6000610ca1610e10426143e2565b73ffffffffffffffffffffffffffffffffffffffff8816600090815260d0602090815260408083208484528252909120549085015191925090610ce488836143cf565b1115610d0f5780846020015111610cfc576000610d0c565b808460200151610d0c91906143a3565b96505b610d1987826143cf565b73ffffffffffffffffffffffffffffffffffffffff8916600081815260d060209081526040808320878452909152902091909155610d599033308a612cb4565b33600090815260d16020526040812054889103610da657633b9aca00856040015167ffffffffffffffff1682610d8f919061441d565b610d9991906143e2565b610da390826143a3565b90505b610db08782612d12565b9450505050505b9392505050565b600033610dcc858285612e32565b610dd7858585612f03565b506001949350505050565b33600090815260cc602052604090205460ff16610e2b576040517ff8d2906c00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b610e3581836131b6565b5050565b60cd546040517fe43581b800000000000000000000000000000000000000000000000000000000815233600482015273ffffffffffffffffffffffffffffffffffffffff9091169063e43581b890602401602060405180830381865afa158015610ea7573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610ecb9190614357565b610f01576040517fee3675d400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015273ffffffffffffffffffffffffffffffffffffffff8216906370a0823190602401602060405180830381865afa158015610f6b573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610f8f91906143b6565b15610fc6576040517f2ef630ec00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff8116600090815260ce602052604081208181556001810182905560020180547fffffffffffffffffffffffffffffffffffffffffffff0000000000000000000016905560cf54905b61102e6001836143a3565b811015611139578273ffffffffffffffffffffffffffffffffffffffff1660cf828154811061105f5761105f614434565b60009182526020909120015473ffffffffffffffffffffffffffffffffffffffff16036111295760cf6110936001846143a3565b815481106110a3576110a3614434565b60009182526020909120015460cf805473ffffffffffffffffffffffffffffffffffffffff90921691839081106110dc576110dc614434565b9060005260206000200160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550611139565b61113281614463565b9050611023565b5060cf80548061114b5761114b61449b565b60008281526020812082017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff90810180547fffffffffffffffffffffffff000000000000000000000000000000000000000016905590910190915560405173ffffffffffffffffffffffffffffffffffffffff8416917f5c95b49c4d59d97a2f044167723f29c74b30f99702e3fd406c3830160aa9ccb891a25050565b60cd5473ffffffffffffffffffffffffffffffffffffffff16331480159061122657503373ffffffffffffffffffffffffffffffffffffffff821614155b1561125d576040517fddb5de5e00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff8116600081815260cc602052604080822080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00169055517f98c15241d6c02bc5ee0b780e11b3ea737a2defd9d04877edbe9f9497065bd02f9190a250565b33600090815260cc602052604090205460ff1661131a576040517ff8d2906c00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff16146113d05773ffffffffffffffffffffffffffffffffffffffff828116600090815260346020908152604080832093851683529290522054838110156113ba576040517f715ec26c00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6113ce83836113c987856143a3565b612a35565b505b61082d82846131b6565b60006113e46133a3565b905090565b60cd546040517f521d4de900000000000000000000000000000000000000000000000000000000815233600482015273ffffffffffffffffffffffffffffffffffffffff9091169063521d4de990602401602060405180830381865afa158015611457573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061147b9190614357565b6114b1576040517f99e120bc00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff8216600090815260ce602052604090206002015468010000000000000000900460ff1661151f576040517fc1ab6dc100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff8216600081815260ce602052604090819020839055517fe7b113fba37131b6396680a0c55790a697ec975e198ff8cfd89dac90a6379e61906109899084815260200190565b33600081815260346020908152604080832073ffffffffffffffffffffffffffffffffffffffff871684529091528120549091906109a390829086906113c99087906143cf565b60cd546040517f521d4de900000000000000000000000000000000000000000000000000000000815233600482015273ffffffffffffffffffffffffffffffffffffffff9091169063521d4de990602401602060405180830381865afa15801561162e573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906116529190614357565b611688576040517f99e120bc00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60d28190556040518181527fc3b69829afe2345596a02c8b587d41f796ba0094481d899e1b2e07b7532a1e219060200160405180910390a150565b33600090815260cc602052604090205460ff1661170c576040517ff8d2906c00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b610e358282612d12565b73ffffffffffffffffffffffffffffffffffffffff8116600090815260d06020526040812081611748610e10426143e2565b8152602001908152602001600020549050919050565b60cd546040517f521d4de900000000000000000000000000000000000000000000000000000000815233600482015273ffffffffffffffffffffffffffffffffffffffff9091169063521d4de990602401602060405180830381865afa1580156117cc573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906117f09190614357565b611826576040517f99e120bc00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff8216600090815260ce602052604090206002015468010000000000000000900460ff16611894576040517fc1ab6dc100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff8216600081815260ce602052604090819020600101839055517fe13ac9338b2ee623233f83c1b3ceab16490fa3e3737fac7f0970d0830a9f4871906109899084815260200190565b60cd546040517fe43581b800000000000000000000000000000000000000000000000000000000815233600482015273ffffffffffffffffffffffffffffffffffffffff9091169063e43581b890602401602060405180830381865afa15801561195f573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906119839190614357565b6119b9576040517fee3675d400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff8516600090815260ce602052604090206002015468010000000000000000900460ff1680611a10575073ffffffffffffffffffffffffffffffffffffffff8516155b15611a47576040517fc1ab6dc100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b633b9aca008267ffffffffffffffff161115611a8f576040517feca1d2c600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040805160a08101825260008082526020820181905291810182905260608101829052608081019190915284815260208082018581528315156080840190815267ffffffffffffffff808716604080870191825260016060880181815273ffffffffffffffffffffffffffffffffffffffff8e16600081815260ce9099528389208a5181559751888401559351600290970180549151965115156901000000000000000000027fffffffffffffffffffffffffffffffffffffffffffff00ffffffffffffffffff97151568010000000000000000027fffffffffffffffffffffffffffffffffffffffffffffff000000000000000000909316989096169790971717949094169290921790935560cf805492830181559093527facb8d954e2cfef495862221e91bd7523613cf8808827cb33edfe4904cc51bf290180547fffffffffffffffffffffffff0000000000000000000000000000000000000000168217905590517f53087ff85d80a7671594bd2e86b92af22e0b3c2c441c8033bba7399b7b5cbe2390611c49908890889088908890938452602084019290925267ffffffffffffffff1660408301521515606082015260800190565b60405180910390a2505050505050565b600060d381611c6a610e10426143e2565b815260200190815260200160002054905090565b73ffffffffffffffffffffffffffffffffffffffff81166000908152609960205260408120546109a9565b611cb333826131b6565b50565b60606037805461079f9061430a565b60cd5473ffffffffffffffffffffffffffffffffffffffff163314611d16576040517fb90cdbb100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff8116600081815260cc602052604080822080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00166001179055517f98c15241d6c02bc5ee0b780e11b3ea737a2defd9d04877edbe9f9497065bd02f9190a250565b60cd546040517f521d4de900000000000000000000000000000000000000000000000000000000815233600482015273ffffffffffffffffffffffffffffffffffffffff9091169063521d4de990602401602060405180830381865afa158015611dfb573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611e1f9190614357565b611e55576040517f99e120bc00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff8216600090815260ce602052604090206002015468010000000000000000900460ff16611ec3576040517fc1ab6dc100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b633b9aca008167ffffffffffffffff161115611f0b576040517feca1d2c600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff8216600081815260ce602090815260409182902060020180547fffffffffffffffffffffffffffffffffffffffffffffffff00000000000000001667ffffffffffffffff861690811790915591519182527f901f9de19b475adc8da4110434b8df940dce085afd05e2281c86807f3a899d299101610989565b33600081815260346020908152604080832073ffffffffffffffffffffffffffffffffffffffff8716845290915281205490919083811015612062576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602560248201527f45524332303a2064656372656173656420616c6c6f77616e63652062656c6f7760448201527f207a65726f00000000000000000000000000000000000000000000000000000060648201526084015b60405180910390fd5b610dd78286868403612a35565b6000336109a3818585612f03565b60cf818154811061208d57600080fd5b60009182526020909120015473ffffffffffffffffffffffffffffffffffffffff16905081565b606060cf80548060200260200160405190810160405280929190818152602001828054801561081857602002820191906000526020600020905b815473ffffffffffffffffffffffffffffffffffffffff1681526001909101906020018083116120ee575050505050905090565b73ffffffffffffffffffffffffffffffffffffffff8316600090815260ce60209081526040808320815160a081018352815481526001820154938101939093526002015467ffffffffffffffff81169183019190915260ff6801000000000000000082048116158015606085015269010000000000000000009092041615156080830152806121b2575080608001515b156121e9576040517fc1ab6dc100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60006121f7610e10426143e2565b600081815260d36020526040812054919250906122159087906143cf565b905060d254811115612253576040517f6d43d1ac00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600082815260d36020526040902081905561226e33876131b6565b33600090815260d160205260408120548791036122bb57633b9aca00846040015167ffffffffffffffff16826122a4919061441d565b6122ae91906143e2565b6122b890826143a3565b90505b6122dc73ffffffffffffffffffffffffffffffffffffffff89168783612be0565b979650505050505050565b83421115612351576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f45524332305065726d69743a206578706972656420646561646c696e650000006044820152606401612059565b60007f6e71edae12b1b97f4d1f60370fef10105fa2faae0126114a169c64845d6126c98888886123808c61341e565b60408051602081019690965273ffffffffffffffffffffffffffffffffffffffff94851690860152929091166060840152608083015260a082015260c0810186905260e00160405160208183030381529060405280519060200120905060006123e882613453565b905060006123f8828787876134bc565b90508973ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff161461248f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601e60248201527f45524332305065726d69743a20696e76616c6964207369676e617475726500006044820152606401612059565b61249a8a8a8a612a35565b50505050505050505050565b60cd546040517f521d4de900000000000000000000000000000000000000000000000000000000815233600482015273ffffffffffffffffffffffffffffffffffffffff9091169063521d4de990602401602060405180830381865afa158015612514573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906125389190614357565b61256e576040517f99e120bc00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff8116600090815260ce602052604090206002015468010000000000000000900460ff166125dc576040517fc1ab6dc100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff8116600081815260ce602090815260409182902060020180547fffffffffffffffffffffffffffffffffffffffffffff00ffffffffffffffffff811669010000000000000000009182900460ff16801592830291909117909255925192835292917ff7c93079dcbf699749d66345a351afab7d24219bb1d915c9f4fc4cf03f00d3979101610989565b60cd5473ffffffffffffffffffffffffffffffffffffffff1633146126cb576040517fb90cdbb100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60cd80547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83169081179091556040517f7dae230f18360d76a040c81f050aa14eb9d6dc7901b20fc5d855e2a20fe814d190600090a250565b73ffffffffffffffffffffffffffffffffffffffff163b151590565b600054610100900460ff16158080156127765750600054600160ff909116105b806127905750303b158015612790575060005460ff166001145b61281c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201527f647920696e697469616c697a65640000000000000000000000000000000000006064820152608401612059565b600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00166001179055801561287a57600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff166101001790555b3073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1663e9cbd8226040518163ffffffff1660e01b8152600401602060405180830381865afa1580156128dc573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061290091906144ca565b73ffffffffffffffffffffffffffffffffffffffff161461294d576040517f14bcf5c800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b612956846134e4565b61296084846135ba565b60cd80547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff84169081179091556040517f7dae230f18360d76a040c81f050aa14eb9d6dc7901b20fc5d855e2a20fe814d190600090a28015612a2f57600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15b50505050565b73ffffffffffffffffffffffffffffffffffffffff8316612ad7576040517f08c379a0000000000000000000000000000000000000000000000000000000008152602060048201526024808201527f45524332303a20617070726f76652066726f6d20746865207a65726f2061646460448201527f72657373000000000000000000000000000000000000000000000000000000006064820152608401612059565b73ffffffffffffffffffffffffffffffffffffffff8216612b7a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602260248201527f45524332303a20617070726f766520746f20746865207a65726f20616464726560448201527f73730000000000000000000000000000000000000000000000000000000000006064820152608401612059565b73ffffffffffffffffffffffffffffffffffffffff83811660008181526034602090815260408083209487168084529482529182902085905590518481527f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b9259101610af7565b60405173ffffffffffffffffffffffffffffffffffffffff831660248201526044810182905261082d9084907fa9059cbb00000000000000000000000000000000000000000000000000000000906064015b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff000000000000000000000000000000000000000000000000000000009093169290921790915261365b565b60405173ffffffffffffffffffffffffffffffffffffffff80851660248301528316604482015260648101829052612a2f9085907f23b872dd0000000000000000000000000000000000000000000000000000000090608401612c32565b73ffffffffffffffffffffffffffffffffffffffff8216612d8f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601f60248201527f45524332303a206d696e7420746f20746865207a65726f2061646472657373006044820152606401612059565b8060356000828254612da191906143cf565b909155505073ffffffffffffffffffffffffffffffffffffffff821660009081526033602052604081208054839290612ddb9084906143cf565b909155505060405181815273ffffffffffffffffffffffffffffffffffffffff8316906000907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef9060200160405180910390a35050565b73ffffffffffffffffffffffffffffffffffffffff8381166000908152603460209081526040808320938616835292905220547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8114612a2f5781811015612ef6576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f45524332303a20696e73756666696369656e7420616c6c6f77616e63650000006044820152606401612059565b612a2f8484848403612a35565b73ffffffffffffffffffffffffffffffffffffffff8316612fa6576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602560248201527f45524332303a207472616e736665722066726f6d20746865207a65726f20616460448201527f64726573730000000000000000000000000000000000000000000000000000006064820152608401612059565b73ffffffffffffffffffffffffffffffffffffffff8216613049576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602360248201527f45524332303a207472616e7366657220746f20746865207a65726f206164647260448201527f65737300000000000000000000000000000000000000000000000000000000006064820152608401612059565b73ffffffffffffffffffffffffffffffffffffffff8316600090815260336020526040902054818110156130ff576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f45524332303a207472616e7366657220616d6f756e742065786365656473206260448201527f616c616e636500000000000000000000000000000000000000000000000000006064820152608401612059565b73ffffffffffffffffffffffffffffffffffffffff8085166000908152603360205260408082208585039055918516815290812080548492906131439084906143cf565b925050819055508273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef846040516131a991815260200190565b60405180910390a3612a2f565b73ffffffffffffffffffffffffffffffffffffffff8216613259576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602160248201527f45524332303a206275726e2066726f6d20746865207a65726f2061646472657360448201527f73000000000000000000000000000000000000000000000000000000000000006064820152608401612059565b73ffffffffffffffffffffffffffffffffffffffff82166000908152603360205260409020548181101561330f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602260248201527f45524332303a206275726e20616d6f756e7420657863656564732062616c616e60448201527f63650000000000000000000000000000000000000000000000000000000000006064820152608401612059565b73ffffffffffffffffffffffffffffffffffffffff8316600090815260336020526040812083830390556035805484929061334b9084906143a3565b909155505060405182815260009073ffffffffffffffffffffffffffffffffffffffff8516907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef9060200160405180910390a3505050565b60006113e47f8b73c3c69bb8fe3d512ecc4cf759cc79239f7b179b0ffacaa9a75d522b39400f6133d260655490565b6066546040805160208101859052908101839052606081018290524660808201523060a082015260009060c0016040516020818303038152906040528051906020012090509392505050565b73ffffffffffffffffffffffffffffffffffffffff811660009081526099602052604090208054600181018255905b50919050565b60006109a96134606133a3565b836040517f19010000000000000000000000000000000000000000000000000000000000006020820152602281018390526042810182905260009060620160405160208183030381529060405280519060200120905092915050565b60008060006134cd87878787613767565b915091506134da8161387f565b5095945050505050565b600054610100900460ff1661357b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201527f6e697469616c697a696e670000000000000000000000000000000000000000006064820152608401612059565b611cb3816040518060400160405280600181526020017f3100000000000000000000000000000000000000000000000000000000000000815250613ad3565b600054610100900460ff16613651576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201527f6e697469616c697a696e670000000000000000000000000000000000000000006064820152608401612059565b610e358282613b84565b60006136bd826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c65648152508573ffffffffffffffffffffffffffffffffffffffff16613c349092919063ffffffff16565b80519091501561082d57808060200190518101906136db9190614357565b61082d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e60448201527f6f742073756363656564000000000000000000000000000000000000000000006064820152608401612059565b6000807f7fffffffffffffffffffffffffffffff5d576e7357a4501ddfe92f46681b20a083111561379e5750600090506003613876565b8460ff16601b141580156137b657508460ff16601c14155b156137c75750600090506004613876565b6040805160008082526020820180845289905260ff881692820192909252606081018690526080810185905260019060a0016020604051602081039080840390855afa15801561381b573d6000803e3d6000fd5b50506040517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0015191505073ffffffffffffffffffffffffffffffffffffffff811661386f57600060019250925050613876565b9150600090505b94509492505050565b6000816004811115613893576138936144e7565b0361389b5750565b60018160048111156138af576138af6144e7565b03613916576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601860248201527f45434453413a20696e76616c6964207369676e617475726500000000000000006044820152606401612059565b600281600481111561392a5761392a6144e7565b03613991576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601f60248201527f45434453413a20696e76616c6964207369676e6174757265206c656e677468006044820152606401612059565b60038160048111156139a5576139a56144e7565b03613a32576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602260248201527f45434453413a20696e76616c6964207369676e6174757265202773272076616c60448201527f75650000000000000000000000000000000000000000000000000000000000006064820152608401612059565b6004816004811115613a4657613a466144e7565b03611cb3576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602260248201527f45434453413a20696e76616c6964207369676e6174757265202776272076616c60448201527f75650000000000000000000000000000000000000000000000000000000000006064820152608401612059565b600054610100900460ff16613b6a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201527f6e697469616c697a696e670000000000000000000000000000000000000000006064820152608401612059565b815160209283012081519190920120606591909155606655565b600054610100900460ff16613c1b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201527f6e697469616c697a696e670000000000000000000000000000000000000000006064820152608401612059565b6036613c278382614564565b50603761082d8282614564565b6060613c438484600085613c4b565b949350505050565b606082471015613cdd576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f60448201527f722063616c6c00000000000000000000000000000000000000000000000000006064820152608401612059565b73ffffffffffffffffffffffffffffffffffffffff85163b613d5b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006044820152606401612059565b6000808673ffffffffffffffffffffffffffffffffffffffff168587604051613d84919061467e565b60006040518083038185875af1925050503d8060008114613dc1576040519150601f19603f3d011682016040523d82523d6000602084013e613dc6565b606091505b50915091506122dc82828660608315613de0575081610db7565b825115613df05782518084602001fd5b816040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016120599190613e48565b60005b83811015613e3f578181015183820152602001613e27565b50506000910152565b6020815260008251806020840152613e67816040850160208701613e24565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169190910160400192915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b600082601f830112613ed957600080fd5b813567ffffffffffffffff80821115613ef457613ef4613e99565b604051601f83017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0908116603f01168101908282118183101715613f3a57613f3a613e99565b81604052838152866020858801011115613f5357600080fd5b836020870160208301376000602085830101528094505050505092915050565b73ffffffffffffffffffffffffffffffffffffffff81168114611cb357600080fd5b600080600060608486031215613faa57600080fd5b833567ffffffffffffffff80821115613fc257600080fd5b613fce87838801613ec8565b94506020860135915080821115613fe457600080fd5b50613ff186828701613ec8565b925050604084013561400281613f73565b809150509250925092565b60006020828403121561401f57600080fd5b8135610db781613f73565b6000806040838503121561403d57600080fd5b823561404881613f73565b946020939093013593505050565b60008060006060848603121561406b57600080fd5b833561407681613f73565b9250602084013561408681613f73565b929592945050506040919091013590565b6000806000606084860312156140ac57600080fd5b83356140b781613f73565b925060208401359150604084013561400281613f73565b600080604083850312156140e157600080fd5b8235915060208301356140f381613f73565b809150509250929050565b60008060006060848603121561411357600080fd5b83359250602084013561412581613f73565b9150604084013561400281613f73565b60006020828403121561414757600080fd5b5035919050565b803567ffffffffffffffff8116811461416657600080fd5b919050565b8015158114611cb357600080fd5b600080600080600060a0868803121561419157600080fd5b853561419c81613f73565b945060208601359350604086013592506141b86060870161414e565b915060808601356141c88161416b565b809150509295509295909350565b600080604083850312156141e957600080fd5b82356141f481613f73565b91506142026020840161414e565b90509250929050565b6020808252825182820181905260009190848201906040850190845b8181101561425957835173ffffffffffffffffffffffffffffffffffffffff1683529284019291840191600101614227565b50909695505050505050565b600080600080600080600060e0888a03121561428057600080fd5b873561428b81613f73565b9650602088013561429b81613f73565b95506040880135945060608801359350608088013560ff811681146142bf57600080fd5b9699959850939692959460a0840135945060c09093013592915050565b600080604083850312156142ef57600080fd5b82356142fa81613f73565b915060208301356140f381613f73565b600181811c9082168061431e57607f821691505b60208210810361344d577f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b60006020828403121561436957600080fd5b8151610db78161416b565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b818103818111156109a9576109a9614374565b6000602082840312156143c857600080fd5b5051919050565b808201808211156109a9576109a9614374565b600082614418577f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b500490565b80820281158282048414176109a9576109a9614374565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff820361449457614494614374565b5060010190565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603160045260246000fd5b6000602082840312156144dc57600080fd5b8151610db781613f73565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b601f82111561082d57600081815260208120601f850160051c8101602086101561453d5750805b601f850160051c820191505b8181101561455c57828155600101614549565b505050505050565b815167ffffffffffffffff81111561457e5761457e613e99565b6145928161458c845461430a565b84614516565b602080601f8311600181146145e557600084156145af5750858301515b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600386901b1c1916600185901b17855561455c565b6000858152602081207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08616915b8281101561463257888601518255948401946001909101908401614613565b508582101561466e57878501517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600388901b60f8161c191681555b5050505050600190811b01905550565b60008251614690818460208701613e24565b919091019291505056fea2646970667358221220f2eb02bac1667a72be85ab617a5b5aa3d8f7a9b09b4d1fde9756b7a5636daf2164736f6c63430008110033", + "deployedBytecode": "0x608060405234801561001057600080fd5b50600436106102ff5760003560e01c806361d027b31161019c5780639f48118f116100ee578063ced67f0c11610097578063dd62ed3e11610071578063dd62ed3e14610724578063e3e286551461076a578063f0f442601461077d57600080fd5b8063ced67f0c1461066b578063d44ad63f146106fe578063d505accf1461071157600080fd5b8063aa271e1a116100c8578063aa271e1a14610620578063ba330bd714610643578063cd4839ca1461065657600080fd5b80639f48118f146105ef578063a457c2d7146105fa578063a9059cbb1461060d57600080fd5b80637ecebe001161015057806395d89b411161012a57806395d89b41146105c1578063983b2d56146105c95780639e4e0dae146105dc57600080fd5b80637ecebe00146105705780638933fb791461058357806390218cff146105ae57600080fd5b80637334d020116101815780637334d020146105425780637d4c9c2d146105555780637d74e25f1461056857600080fd5b806361d027b3146104c757806370a082311461050c57600080fd5b80633092afd511610255578063395093511161020957806340c10f19116101e357806340c10f19146104815780634dc32fcc146104945780635bfbec96146104a757600080fd5b8063395093511461043b5780633a55f89d1461044e5780633f4218e01461046157600080fd5b8063350ebe041161023a578063350ebe041461040d5780633644e5151461042057806336db43b51461042857600080fd5b80633092afd5146103eb578063313ce567146103fe57600080fd5b8063151dd755116102b757806323b872dd1161029157806323b872dd146103b25780632b471d8e146103c55780632e403e14146103d857600080fd5b8063151dd7551461038057806318160ddd146103a15780632342fb0e146103a957600080fd5b80630919a951116102e85780630919a95114610337578063095ea7b31461034a5780631171bda91461036d57600080fd5b806306fdde0314610304578063077f224a14610322575b600080fd5b61030c610790565b6040516103199190613e48565b60405180910390f35b610335610330366004613f95565b610822565b005b61033561034536600461400d565b610832565b61035d61035836600461402a565b610995565b6040519015158152602001610319565b61033561037b366004614056565b6109af565b61039361038e366004614097565b610b04565b604051908152602001610319565b603554610393565b61039360d25481565b61035d6103c0366004614056565b610dbe565b6103356103d33660046140ce565b610de2565b6103356103e636600461400d565b610e39565b6103356103f936600461400d565b6111e8565b60405160128152602001610319565b61033561041b3660046140fe565b6112d1565b6103936113da565b61033561043636600461402a565b6113e9565b61035d61044936600461402a565b611579565b61033561045c366004614135565b6115c0565b61039361046f36600461400d565b60d16020526000908152604090205481565b61033561048f36600461402a565b6116c3565b6103936104a236600461400d565b611716565b6103936104b5366004614135565b60d36020526000908152604090205481565b60cd546104e79073ffffffffffffffffffffffffffffffffffffffff1681565b60405173ffffffffffffffffffffffffffffffffffffffff9091168152602001610319565b61039361051a36600461400d565b73ffffffffffffffffffffffffffffffffffffffff1660009081526033602052604090205490565b61033561055036600461402a565b61175e565b610335610563366004614179565b6118f1565b610393611c59565b61039361057e36600461400d565b611c7e565b61039361059136600461402a565b60d060209081526000928352604080842090915290825290205481565b6103356105bc366004614135565b611ca9565b61030c611cb6565b6103356105d736600461400d565b611cc5565b6103356105ea3660046141d6565b611d8d565b610393633b9aca0081565b61035d61060836600461402a565b611f99565b61035d61061b36600461402a565b61206f565b61035d61062e36600461400d565b60cc6020526000908152604090205460ff1681565b6104e7610651366004614135565b61207d565b61065e6120b4565b604051610319919061420b565b6106c561067936600461400d565b60ce6020526000908152604090208054600182015460029092015490919067ffffffffffffffff81169060ff680100000000000000008204811691690100000000000000000090041685565b60408051958652602086019490945267ffffffffffffffff9092169284019290925290151560608301521515608082015260a001610319565b61039361070c366004614097565b612122565b61033561071f366004614265565b6122e7565b6103936107323660046142dc565b73ffffffffffffffffffffffffffffffffffffffff918216600090815260346020908152604080832093909416825291909152205490565b61033561077836600461400d565b6124a6565b61033561078b36600461400d565b61267a565b60606036805461079f9061430a565b80601f01602080910402602001604051908101604052809291908181526020018280546107cb9061430a565b80156108185780601f106107ed57610100808354040283529160200191610818565b820191906000526020600020905b8154815290600101906020018083116107fb57829003601f168201915b5050505050905090565b61082d838383612756565b505050565b60cd546040517f521d4de900000000000000000000000000000000000000000000000000000000815233600482015273ffffffffffffffffffffffffffffffffffffffff9091169063521d4de990602401602060405180830381865afa1580156108a0573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906108c49190614357565b6108fa576040517f99e120bc00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff8116600090815260d1602052604081205461092b9060016143a3565b73ffffffffffffffffffffffffffffffffffffffff8316600081815260d160205260409081902083905551919250907f979ef83e7e7a87cb48064e296dd7e997870d50f43acf8d7ad221313526c8ca0f906109899084815260200190565b60405180910390a25050565b6000336109a3818585612a35565b60019150505b92915050565b60cd546040517fe43581b800000000000000000000000000000000000000000000000000000000815233600482015273ffffffffffffffffffffffffffffffffffffffff9091169063e43581b890602401602060405180830381865afa158015610a1d573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610a419190614357565b610a77576040517fee3675d400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b610a9873ffffffffffffffffffffffffffffffffffffffff84168383612be0565b8173ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff167ffff3b3844276f57024e0b42afec1a37f75db36511e43819a4f2a63ab7862b64883604051610af791815260200190565b60405180910390a3505050565b73ffffffffffffffffffffffffffffffffffffffff8316600090815260ce60209081526040808320815160a081018352815481526001820154938101939093526002015467ffffffffffffffff81169183019190915260ff680100000000000000008204811615801560608501526901000000000000000000909204161515608083015280610b94575080608001515b15610bcb576040517fc1ab6dc100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015260009073ffffffffffffffffffffffffffffffffffffffff8716906370a0823190602401602060405180830381865afa158015610c38573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610c5c91906143b6565b8251909150610c6b86836143cf565b1115610c93578151811015610c8e578151610c879082906143a3565b9450610c93565b600094505b6000610ca1610e10426143e2565b73ffffffffffffffffffffffffffffffffffffffff8816600090815260d0602090815260408083208484528252909120549085015191925090610ce488836143cf565b1115610d0f5780846020015111610cfc576000610d0c565b808460200151610d0c91906143a3565b96505b610d1987826143cf565b73ffffffffffffffffffffffffffffffffffffffff8916600081815260d060209081526040808320878452909152902091909155610d599033308a612cb4565b33600090815260d16020526040812054889103610da657633b9aca00856040015167ffffffffffffffff1682610d8f919061441d565b610d9991906143e2565b610da390826143a3565b90505b610db08782612d12565b9450505050505b9392505050565b600033610dcc858285612e32565b610dd7858585612f03565b506001949350505050565b33600090815260cc602052604090205460ff16610e2b576040517ff8d2906c00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b610e3581836131b6565b5050565b60cd546040517fe43581b800000000000000000000000000000000000000000000000000000000815233600482015273ffffffffffffffffffffffffffffffffffffffff9091169063e43581b890602401602060405180830381865afa158015610ea7573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610ecb9190614357565b610f01576040517fee3675d400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015273ffffffffffffffffffffffffffffffffffffffff8216906370a0823190602401602060405180830381865afa158015610f6b573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610f8f91906143b6565b15610fc6576040517f2ef630ec00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff8116600090815260ce602052604081208181556001810182905560020180547fffffffffffffffffffffffffffffffffffffffffffff0000000000000000000016905560cf54905b61102e6001836143a3565b811015611139578273ffffffffffffffffffffffffffffffffffffffff1660cf828154811061105f5761105f614434565b60009182526020909120015473ffffffffffffffffffffffffffffffffffffffff16036111295760cf6110936001846143a3565b815481106110a3576110a3614434565b60009182526020909120015460cf805473ffffffffffffffffffffffffffffffffffffffff90921691839081106110dc576110dc614434565b9060005260206000200160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550611139565b61113281614463565b9050611023565b5060cf80548061114b5761114b61449b565b60008281526020812082017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff90810180547fffffffffffffffffffffffff000000000000000000000000000000000000000016905590910190915560405173ffffffffffffffffffffffffffffffffffffffff8416917f5c95b49c4d59d97a2f044167723f29c74b30f99702e3fd406c3830160aa9ccb891a25050565b60cd5473ffffffffffffffffffffffffffffffffffffffff16331480159061122657503373ffffffffffffffffffffffffffffffffffffffff821614155b1561125d576040517fddb5de5e00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff8116600081815260cc602052604080822080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00169055517f98c15241d6c02bc5ee0b780e11b3ea737a2defd9d04877edbe9f9497065bd02f9190a250565b33600090815260cc602052604090205460ff1661131a576040517ff8d2906c00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff16146113d05773ffffffffffffffffffffffffffffffffffffffff828116600090815260346020908152604080832093851683529290522054838110156113ba576040517f715ec26c00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6113ce83836113c987856143a3565b612a35565b505b61082d82846131b6565b60006113e46133a3565b905090565b60cd546040517f521d4de900000000000000000000000000000000000000000000000000000000815233600482015273ffffffffffffffffffffffffffffffffffffffff9091169063521d4de990602401602060405180830381865afa158015611457573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061147b9190614357565b6114b1576040517f99e120bc00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff8216600090815260ce602052604090206002015468010000000000000000900460ff1661151f576040517fc1ab6dc100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff8216600081815260ce602052604090819020839055517fe7b113fba37131b6396680a0c55790a697ec975e198ff8cfd89dac90a6379e61906109899084815260200190565b33600081815260346020908152604080832073ffffffffffffffffffffffffffffffffffffffff871684529091528120549091906109a390829086906113c99087906143cf565b60cd546040517f521d4de900000000000000000000000000000000000000000000000000000000815233600482015273ffffffffffffffffffffffffffffffffffffffff9091169063521d4de990602401602060405180830381865afa15801561162e573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906116529190614357565b611688576040517f99e120bc00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60d28190556040518181527fc3b69829afe2345596a02c8b587d41f796ba0094481d899e1b2e07b7532a1e219060200160405180910390a150565b33600090815260cc602052604090205460ff1661170c576040517ff8d2906c00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b610e358282612d12565b73ffffffffffffffffffffffffffffffffffffffff8116600090815260d06020526040812081611748610e10426143e2565b8152602001908152602001600020549050919050565b60cd546040517f521d4de900000000000000000000000000000000000000000000000000000000815233600482015273ffffffffffffffffffffffffffffffffffffffff9091169063521d4de990602401602060405180830381865afa1580156117cc573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906117f09190614357565b611826576040517f99e120bc00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff8216600090815260ce602052604090206002015468010000000000000000900460ff16611894576040517fc1ab6dc100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff8216600081815260ce602052604090819020600101839055517fe13ac9338b2ee623233f83c1b3ceab16490fa3e3737fac7f0970d0830a9f4871906109899084815260200190565b60cd546040517fe43581b800000000000000000000000000000000000000000000000000000000815233600482015273ffffffffffffffffffffffffffffffffffffffff9091169063e43581b890602401602060405180830381865afa15801561195f573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906119839190614357565b6119b9576040517fee3675d400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff8516600090815260ce602052604090206002015468010000000000000000900460ff1680611a10575073ffffffffffffffffffffffffffffffffffffffff8516155b15611a47576040517fc1ab6dc100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b633b9aca008267ffffffffffffffff161115611a8f576040517feca1d2c600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040805160a08101825260008082526020820181905291810182905260608101829052608081019190915284815260208082018581528315156080840190815267ffffffffffffffff808716604080870191825260016060880181815273ffffffffffffffffffffffffffffffffffffffff8e16600081815260ce9099528389208a5181559751888401559351600290970180549151965115156901000000000000000000027fffffffffffffffffffffffffffffffffffffffffffff00ffffffffffffffffff97151568010000000000000000027fffffffffffffffffffffffffffffffffffffffffffffff000000000000000000909316989096169790971717949094169290921790935560cf805492830181559093527facb8d954e2cfef495862221e91bd7523613cf8808827cb33edfe4904cc51bf290180547fffffffffffffffffffffffff0000000000000000000000000000000000000000168217905590517f53087ff85d80a7671594bd2e86b92af22e0b3c2c441c8033bba7399b7b5cbe2390611c49908890889088908890938452602084019290925267ffffffffffffffff1660408301521515606082015260800190565b60405180910390a2505050505050565b600060d381611c6a610e10426143e2565b815260200190815260200160002054905090565b73ffffffffffffffffffffffffffffffffffffffff81166000908152609960205260408120546109a9565b611cb333826131b6565b50565b60606037805461079f9061430a565b60cd5473ffffffffffffffffffffffffffffffffffffffff163314611d16576040517fb90cdbb100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff8116600081815260cc602052604080822080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00166001179055517f98c15241d6c02bc5ee0b780e11b3ea737a2defd9d04877edbe9f9497065bd02f9190a250565b60cd546040517f521d4de900000000000000000000000000000000000000000000000000000000815233600482015273ffffffffffffffffffffffffffffffffffffffff9091169063521d4de990602401602060405180830381865afa158015611dfb573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611e1f9190614357565b611e55576040517f99e120bc00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff8216600090815260ce602052604090206002015468010000000000000000900460ff16611ec3576040517fc1ab6dc100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b633b9aca008167ffffffffffffffff161115611f0b576040517feca1d2c600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff8216600081815260ce602090815260409182902060020180547fffffffffffffffffffffffffffffffffffffffffffffffff00000000000000001667ffffffffffffffff861690811790915591519182527f901f9de19b475adc8da4110434b8df940dce085afd05e2281c86807f3a899d299101610989565b33600081815260346020908152604080832073ffffffffffffffffffffffffffffffffffffffff8716845290915281205490919083811015612062576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602560248201527f45524332303a2064656372656173656420616c6c6f77616e63652062656c6f7760448201527f207a65726f00000000000000000000000000000000000000000000000000000060648201526084015b60405180910390fd5b610dd78286868403612a35565b6000336109a3818585612f03565b60cf818154811061208d57600080fd5b60009182526020909120015473ffffffffffffffffffffffffffffffffffffffff16905081565b606060cf80548060200260200160405190810160405280929190818152602001828054801561081857602002820191906000526020600020905b815473ffffffffffffffffffffffffffffffffffffffff1681526001909101906020018083116120ee575050505050905090565b73ffffffffffffffffffffffffffffffffffffffff8316600090815260ce60209081526040808320815160a081018352815481526001820154938101939093526002015467ffffffffffffffff81169183019190915260ff6801000000000000000082048116158015606085015269010000000000000000009092041615156080830152806121b2575080608001515b156121e9576040517fc1ab6dc100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60006121f7610e10426143e2565b600081815260d36020526040812054919250906122159087906143cf565b905060d254811115612253576040517f6d43d1ac00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600082815260d36020526040902081905561226e33876131b6565b33600090815260d160205260408120548791036122bb57633b9aca00846040015167ffffffffffffffff16826122a4919061441d565b6122ae91906143e2565b6122b890826143a3565b90505b6122dc73ffffffffffffffffffffffffffffffffffffffff89168783612be0565b979650505050505050565b83421115612351576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f45524332305065726d69743a206578706972656420646561646c696e650000006044820152606401612059565b60007f6e71edae12b1b97f4d1f60370fef10105fa2faae0126114a169c64845d6126c98888886123808c61341e565b60408051602081019690965273ffffffffffffffffffffffffffffffffffffffff94851690860152929091166060840152608083015260a082015260c0810186905260e00160405160208183030381529060405280519060200120905060006123e882613453565b905060006123f8828787876134bc565b90508973ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff161461248f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601e60248201527f45524332305065726d69743a20696e76616c6964207369676e617475726500006044820152606401612059565b61249a8a8a8a612a35565b50505050505050505050565b60cd546040517f521d4de900000000000000000000000000000000000000000000000000000000815233600482015273ffffffffffffffffffffffffffffffffffffffff9091169063521d4de990602401602060405180830381865afa158015612514573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906125389190614357565b61256e576040517f99e120bc00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff8116600090815260ce602052604090206002015468010000000000000000900460ff166125dc576040517fc1ab6dc100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff8116600081815260ce602090815260409182902060020180547fffffffffffffffffffffffffffffffffffffffffffff00ffffffffffffffffff811669010000000000000000009182900460ff16801592830291909117909255925192835292917ff7c93079dcbf699749d66345a351afab7d24219bb1d915c9f4fc4cf03f00d3979101610989565b60cd5473ffffffffffffffffffffffffffffffffffffffff1633146126cb576040517fb90cdbb100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60cd80547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83169081179091556040517f7dae230f18360d76a040c81f050aa14eb9d6dc7901b20fc5d855e2a20fe814d190600090a250565b73ffffffffffffffffffffffffffffffffffffffff163b151590565b600054610100900460ff16158080156127765750600054600160ff909116105b806127905750303b158015612790575060005460ff166001145b61281c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201527f647920696e697469616c697a65640000000000000000000000000000000000006064820152608401612059565b600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00166001179055801561287a57600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff166101001790555b3073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1663e9cbd8226040518163ffffffff1660e01b8152600401602060405180830381865afa1580156128dc573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061290091906144ca565b73ffffffffffffffffffffffffffffffffffffffff161461294d576040517f14bcf5c800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b612956846134e4565b61296084846135ba565b60cd80547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff84169081179091556040517f7dae230f18360d76a040c81f050aa14eb9d6dc7901b20fc5d855e2a20fe814d190600090a28015612a2f57600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15b50505050565b73ffffffffffffffffffffffffffffffffffffffff8316612ad7576040517f08c379a0000000000000000000000000000000000000000000000000000000008152602060048201526024808201527f45524332303a20617070726f76652066726f6d20746865207a65726f2061646460448201527f72657373000000000000000000000000000000000000000000000000000000006064820152608401612059565b73ffffffffffffffffffffffffffffffffffffffff8216612b7a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602260248201527f45524332303a20617070726f766520746f20746865207a65726f20616464726560448201527f73730000000000000000000000000000000000000000000000000000000000006064820152608401612059565b73ffffffffffffffffffffffffffffffffffffffff83811660008181526034602090815260408083209487168084529482529182902085905590518481527f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b9259101610af7565b60405173ffffffffffffffffffffffffffffffffffffffff831660248201526044810182905261082d9084907fa9059cbb00000000000000000000000000000000000000000000000000000000906064015b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff000000000000000000000000000000000000000000000000000000009093169290921790915261365b565b60405173ffffffffffffffffffffffffffffffffffffffff80851660248301528316604482015260648101829052612a2f9085907f23b872dd0000000000000000000000000000000000000000000000000000000090608401612c32565b73ffffffffffffffffffffffffffffffffffffffff8216612d8f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601f60248201527f45524332303a206d696e7420746f20746865207a65726f2061646472657373006044820152606401612059565b8060356000828254612da191906143cf565b909155505073ffffffffffffffffffffffffffffffffffffffff821660009081526033602052604081208054839290612ddb9084906143cf565b909155505060405181815273ffffffffffffffffffffffffffffffffffffffff8316906000907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef9060200160405180910390a35050565b73ffffffffffffffffffffffffffffffffffffffff8381166000908152603460209081526040808320938616835292905220547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8114612a2f5781811015612ef6576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f45524332303a20696e73756666696369656e7420616c6c6f77616e63650000006044820152606401612059565b612a2f8484848403612a35565b73ffffffffffffffffffffffffffffffffffffffff8316612fa6576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602560248201527f45524332303a207472616e736665722066726f6d20746865207a65726f20616460448201527f64726573730000000000000000000000000000000000000000000000000000006064820152608401612059565b73ffffffffffffffffffffffffffffffffffffffff8216613049576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602360248201527f45524332303a207472616e7366657220746f20746865207a65726f206164647260448201527f65737300000000000000000000000000000000000000000000000000000000006064820152608401612059565b73ffffffffffffffffffffffffffffffffffffffff8316600090815260336020526040902054818110156130ff576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f45524332303a207472616e7366657220616d6f756e742065786365656473206260448201527f616c616e636500000000000000000000000000000000000000000000000000006064820152608401612059565b73ffffffffffffffffffffffffffffffffffffffff8085166000908152603360205260408082208585039055918516815290812080548492906131439084906143cf565b925050819055508273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef846040516131a991815260200190565b60405180910390a3612a2f565b73ffffffffffffffffffffffffffffffffffffffff8216613259576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602160248201527f45524332303a206275726e2066726f6d20746865207a65726f2061646472657360448201527f73000000000000000000000000000000000000000000000000000000000000006064820152608401612059565b73ffffffffffffffffffffffffffffffffffffffff82166000908152603360205260409020548181101561330f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602260248201527f45524332303a206275726e20616d6f756e7420657863656564732062616c616e60448201527f63650000000000000000000000000000000000000000000000000000000000006064820152608401612059565b73ffffffffffffffffffffffffffffffffffffffff8316600090815260336020526040812083830390556035805484929061334b9084906143a3565b909155505060405182815260009073ffffffffffffffffffffffffffffffffffffffff8516907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef9060200160405180910390a3505050565b60006113e47f8b73c3c69bb8fe3d512ecc4cf759cc79239f7b179b0ffacaa9a75d522b39400f6133d260655490565b6066546040805160208101859052908101839052606081018290524660808201523060a082015260009060c0016040516020818303038152906040528051906020012090509392505050565b73ffffffffffffffffffffffffffffffffffffffff811660009081526099602052604090208054600181018255905b50919050565b60006109a96134606133a3565b836040517f19010000000000000000000000000000000000000000000000000000000000006020820152602281018390526042810182905260009060620160405160208183030381529060405280519060200120905092915050565b60008060006134cd87878787613767565b915091506134da8161387f565b5095945050505050565b600054610100900460ff1661357b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201527f6e697469616c697a696e670000000000000000000000000000000000000000006064820152608401612059565b611cb3816040518060400160405280600181526020017f3100000000000000000000000000000000000000000000000000000000000000815250613ad3565b600054610100900460ff16613651576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201527f6e697469616c697a696e670000000000000000000000000000000000000000006064820152608401612059565b610e358282613b84565b60006136bd826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c65648152508573ffffffffffffffffffffffffffffffffffffffff16613c349092919063ffffffff16565b80519091501561082d57808060200190518101906136db9190614357565b61082d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e60448201527f6f742073756363656564000000000000000000000000000000000000000000006064820152608401612059565b6000807f7fffffffffffffffffffffffffffffff5d576e7357a4501ddfe92f46681b20a083111561379e5750600090506003613876565b8460ff16601b141580156137b657508460ff16601c14155b156137c75750600090506004613876565b6040805160008082526020820180845289905260ff881692820192909252606081018690526080810185905260019060a0016020604051602081039080840390855afa15801561381b573d6000803e3d6000fd5b50506040517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0015191505073ffffffffffffffffffffffffffffffffffffffff811661386f57600060019250925050613876565b9150600090505b94509492505050565b6000816004811115613893576138936144e7565b0361389b5750565b60018160048111156138af576138af6144e7565b03613916576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601860248201527f45434453413a20696e76616c6964207369676e617475726500000000000000006044820152606401612059565b600281600481111561392a5761392a6144e7565b03613991576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601f60248201527f45434453413a20696e76616c6964207369676e6174757265206c656e677468006044820152606401612059565b60038160048111156139a5576139a56144e7565b03613a32576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602260248201527f45434453413a20696e76616c6964207369676e6174757265202773272076616c60448201527f75650000000000000000000000000000000000000000000000000000000000006064820152608401612059565b6004816004811115613a4657613a466144e7565b03611cb3576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602260248201527f45434453413a20696e76616c6964207369676e6174757265202776272076616c60448201527f75650000000000000000000000000000000000000000000000000000000000006064820152608401612059565b600054610100900460ff16613b6a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201527f6e697469616c697a696e670000000000000000000000000000000000000000006064820152608401612059565b815160209283012081519190920120606591909155606655565b600054610100900460ff16613c1b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201527f6e697469616c697a696e670000000000000000000000000000000000000000006064820152608401612059565b6036613c278382614564565b50603761082d8282614564565b6060613c438484600085613c4b565b949350505050565b606082471015613cdd576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f60448201527f722063616c6c00000000000000000000000000000000000000000000000000006064820152608401612059565b73ffffffffffffffffffffffffffffffffffffffff85163b613d5b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006044820152606401612059565b6000808673ffffffffffffffffffffffffffffffffffffffff168587604051613d84919061467e565b60006040518083038185875af1925050503d8060008114613dc1576040519150601f19603f3d011682016040523d82523d6000602084013e613dc6565b606091505b50915091506122dc82828660608315613de0575081610db7565b825115613df05782518084602001fd5b816040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016120599190613e48565b60005b83811015613e3f578181015183820152602001613e27565b50506000910152565b6020815260008251806020840152613e67816040850160208701613e24565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169190910160400192915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b600082601f830112613ed957600080fd5b813567ffffffffffffffff80821115613ef457613ef4613e99565b604051601f83017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0908116603f01168101908282118183101715613f3a57613f3a613e99565b81604052838152866020858801011115613f5357600080fd5b836020870160208301376000602085830101528094505050505092915050565b73ffffffffffffffffffffffffffffffffffffffff81168114611cb357600080fd5b600080600060608486031215613faa57600080fd5b833567ffffffffffffffff80821115613fc257600080fd5b613fce87838801613ec8565b94506020860135915080821115613fe457600080fd5b50613ff186828701613ec8565b925050604084013561400281613f73565b809150509250925092565b60006020828403121561401f57600080fd5b8135610db781613f73565b6000806040838503121561403d57600080fd5b823561404881613f73565b946020939093013593505050565b60008060006060848603121561406b57600080fd5b833561407681613f73565b9250602084013561408681613f73565b929592945050506040919091013590565b6000806000606084860312156140ac57600080fd5b83356140b781613f73565b925060208401359150604084013561400281613f73565b600080604083850312156140e157600080fd5b8235915060208301356140f381613f73565b809150509250929050565b60008060006060848603121561411357600080fd5b83359250602084013561412581613f73565b9150604084013561400281613f73565b60006020828403121561414757600080fd5b5035919050565b803567ffffffffffffffff8116811461416657600080fd5b919050565b8015158114611cb357600080fd5b600080600080600060a0868803121561419157600080fd5b853561419c81613f73565b945060208601359350604086013592506141b86060870161414e565b915060808601356141c88161416b565b809150509295509295909350565b600080604083850312156141e957600080fd5b82356141f481613f73565b91506142026020840161414e565b90509250929050565b6020808252825182820181905260009190848201906040850190845b8181101561425957835173ffffffffffffffffffffffffffffffffffffffff1683529284019291840191600101614227565b50909695505050505050565b600080600080600080600060e0888a03121561428057600080fd5b873561428b81613f73565b9650602088013561429b81613f73565b95506040880135945060608801359350608088013560ff811681146142bf57600080fd5b9699959850939692959460a0840135945060c09093013592915050565b600080604083850312156142ef57600080fd5b82356142fa81613f73565b915060208301356140f381613f73565b600181811c9082168061431e57607f821691505b60208210810361344d577f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b60006020828403121561436957600080fd5b8151610db78161416b565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b818103818111156109a9576109a9614374565b6000602082840312156143c857600080fd5b5051919050565b808201808211156109a9576109a9614374565b600082614418577f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b500490565b80820281158282048414176109a9576109a9614374565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff820361449457614494614374565b5060010190565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603160045260246000fd5b6000602082840312156144dc57600080fd5b8151610db781613f73565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b601f82111561082d57600081815260208120601f850160051c8101602086101561453d5750805b601f850160051c820191505b8181101561455c57828155600101614549565b505050505050565b815167ffffffffffffffff81111561457e5761457e613e99565b6145928161458c845461430a565b84614516565b602080601f8311600181146145e557600084156145af5750858301515b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600386901b1c1916600185901b17855561455c565b6000858152602081207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08616915b8281101561463257888601518255948401946001909101908401614613565b508582101561466e57878501517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600388901b60f8161c191681555b5050505050600190811b01905550565b60008251614690818460208701613e24565b919091019291505056fea2646970667358221220f2eb02bac1667a72be85ab617a5b5aa3d8f7a9b09b4d1fde9756b7a5636daf2164736f6c63430008110033", + "devdoc": { + "author": "Angle Labs, Inc.", + "details": "This contract supports bridge tokens having a minting right on the stablecoin (also referred to as the canonical or the native token)", + "kind": "dev", + "methods": { + "DOMAIN_SEPARATOR()": { + "details": "See {IERC20Permit-DOMAIN_SEPARATOR}." + }, + "addBridgeToken(address,uint256,uint256,uint64,bool)": { + "params": { + "bridgeToken": "Bridge token to add: it should be a version of the stablecoin from another bridge", + "fee": "Fee taken upon swapping for or against this token", + "hourlyLimit": "Limit on the hourly volume for this bridge", + "limit": "Limit on the balance of bridge token this contract could hold", + "paused": "Whether swapping for this token should be paused or not" + } + }, + "addMinter(address)": { + "details": "Zero address checks are performed directly in the `Treasury` contract", + "params": { + "minter": "Minter address to add" + } + }, + "allBridgeTokens()": { + "details": "Helpful for UIs" + }, + "allowance(address,address)": { + "details": "See {IERC20-allowance}." + }, + "approve(address,uint256)": { + "details": "See {IERC20-approve}. NOTE: If `amount` is the maximum `uint256`, the allowance is not updated on `transferFrom`. This is semantically equivalent to an infinite approval. Requirements: - `spender` cannot be the zero address." + }, + "balanceOf(address)": { + "details": "See {IERC20-balanceOf}." + }, + "burnFrom(uint256,address,address)": { + "details": "This method is to be called by a contract with the minter right after being requested to do so by a `sender` address willing to burn tokens from another `burner` addressThe method checks the allowance between the `sender` and the `burner`", + "params": { + "amount": "Amount of tokens to burn", + "burner": "Address to burn from", + "sender": "Address which requested the burn from `burner`" + } + }, + "burnSelf(uint256,address)": { + "details": "This method is to be called by a contract with a minter right on the AgToken after being requested to do so by an address willing to burn tokens from its address", + "params": { + "amount": "Amount of tokens to burn", + "burner": "Address to burn from" + } + }, + "burnStablecoin(uint256)": { + "details": "This function can typically be called if there is a settlement mechanism to burn stablecoins", + "params": { + "amount": "Amount of stablecoins to burn" + } + }, + "currentTotalUsage()": { + "details": "Helpful for UIs" + }, + "currentUsage(address)": { + "details": "Helpful for UIs", + "params": { + "bridgeToken": "Bridge used to mint" + } + }, + "decimals()": { + "details": "Returns the number of decimals used to get its user representation. For example, if `decimals` equals `2`, a balance of `505` tokens should be displayed to a user as `5.05` (`505 / 10 ** 2`). Tokens usually opt for a value of 18, imitating the relationship between Ether and Wei. This is the value {ERC20} uses, unless this function is overridden; NOTE: This information is only used for _display_ purposes: it in no way affects any of the arithmetic of the contract, including {IERC20-balanceOf} and {IERC20-transfer}." + }, + "decreaseAllowance(address,uint256)": { + "details": "Atomically decreases the allowance granted to `spender` by the caller. This is an alternative to {approve} that can be used as a mitigation for problems described in {IERC20-approve}. Emits an {Approval} event indicating the updated allowance. Requirements: - `spender` cannot be the zero address. - `spender` must have allowance for the caller of at least `subtractedValue`." + }, + "increaseAllowance(address,uint256)": { + "details": "Atomically increases the allowance granted to `spender` by the caller. This is an alternative to {approve} that can be used as a mitigation for problems described in {IERC20-approve}. Emits an {Approval} event indicating the updated allowance. Requirements: - `spender` cannot be the zero address." + }, + "mint(address,uint256)": { + "details": "The contracts allowed to issue agTokens are the `StableMaster` contract, `VaultManager` contracts associated to this stablecoin as well as the flash loan module (if activated) and potentially contracts whitelisted by governance", + "params": { + "account": "Address to mint to", + "amount": "Amount to mint" + } + }, + "name()": { + "details": "Returns the name of the token." + }, + "nonces(address)": { + "details": "See {IERC20Permit-nonces}." + }, + "permit(address,address,uint256,uint256,uint8,bytes32,bytes32)": { + "details": "See {IERC20Permit-permit}." + }, + "recoverERC20(address,address,uint256)": { + "details": "Can be used to withdraw bridge tokens for them to be de-bridged on mainnet" + }, + "removeBridgeToken(address)": { + "params": { + "bridgeToken": "Address of the bridge token to remove support for" + } + }, + "removeMinter(address)": { + "details": "This function can also be called by a minter wishing to revoke itself", + "params": { + "minter": "Minter address to remove" + } + }, + "setTreasury(address)": { + "params": { + "_treasury": "New treasury address" + } + }, + "swapIn(address,uint256,address)": { + "details": "Some fees may be taken by the protocol depending on the token used and on the address calling", + "params": { + "amount": "Amount of bridge tokens to send", + "bridgeToken": "Bridge token to use to mint", + "to": "Address to which the stablecoin should be sent" + }, + "returns": { + "_0": "Amount of the canonical stablecoin actually minted" + } + }, + "swapOut(address,uint256,address)": { + "details": "Some fees may be taken by the protocol depending on the token used and on the address calling", + "params": { + "amount": "Amount of canonical tokens to burn", + "bridgeToken": "Bridge token required", + "to": "Address to which the bridge token should be sent" + }, + "returns": { + "_0": "Amount of bridge tokens actually sent back" + } + }, + "symbol()": { + "details": "Returns the symbol of the token, usually a shorter version of the name." + }, + "totalSupply()": { + "details": "See {IERC20-totalSupply}." + }, + "transfer(address,uint256)": { + "details": "See {IERC20-transfer}. Requirements: - `to` cannot be the zero address. - the caller must have a balance of at least `amount`." + }, + "transferFrom(address,address,uint256)": { + "details": "See {IERC20-transferFrom}. Emits an {Approval} event indicating the updated allowance. This is not required by the EIP. See the note at the beginning of {ERC20}. NOTE: Does not update the allowance if the current allowance is the maximum `uint256`. Requirements: - `from` and `to` cannot be the zero address. - `from` must have a balance of at least `amount`. - the caller must have allowance for ``from``'s tokens of at least `amount`." + } + }, + "title": "AgTokenSideChainMultiBridge", + "version": 1 + }, + "userdoc": { + "kind": "user", + "methods": { + "BASE_PARAMS()": { + "notice": "Base used for fee computation" + }, + "addBridgeToken(address,uint256,uint256,uint64,bool)": { + "notice": "Adds support for a bridge token" + }, + "addMinter(address)": { + "notice": "Adds a minter in the contract" + }, + "allBridgeTokens()": { + "notice": "Returns the list of all supported bridge tokens" + }, + "bridgeTokensList(uint256)": { + "notice": "List of all bridge tokens" + }, + "bridges(address)": { + "notice": "Maps a bridge token to data" + }, + "burnFrom(uint256,address,address)": { + "notice": "Burns `amount` tokens from a `burner` address after being asked to by `sender`" + }, + "burnSelf(uint256,address)": { + "notice": "Burns `amount` tokens from a `burner` address" + }, + "burnStablecoin(uint256)": { + "notice": "Allows anyone to burn stablecoins" + }, + "chainTotalHourlyLimit()": { + "notice": "Limit to the amount of tokens that can be sent from that chain to another chain" + }, + "chainTotalUsage(uint256)": { + "notice": "Usage per hour on that chain. Maps an hourly timestamp to the total volume swapped out on the chain" + }, + "currentTotalUsage()": { + "notice": "Returns the current total volume on the chain for the current hour" + }, + "currentUsage(address)": { + "notice": "Returns the current volume for a bridge, for the current hour" + }, + "initialize(string,string,address)": { + "notice": "Initializes the `AgToken` contract" + }, + "isFeeExempt(address)": { + "notice": "Maps an address to whether it is exempt of fees for when it comes to swapping in and out" + }, + "isMinter(address)": { + "notice": "Checks whether an address has the right to mint agTokens" + }, + "mint(address,uint256)": { + "notice": "Lets the `StableMaster` contract or another whitelisted contract mint agTokens" + }, + "recoverERC20(address,address,uint256)": { + "notice": "Recovers any ERC20 token" + }, + "removeBridgeToken(address)": { + "notice": "Removes support for a token" + }, + "removeMinter(address)": { + "notice": "Removes a minter from the contract" + }, + "setChainTotalHourlyLimit(uint256)": { + "notice": "Updates the `chainTotalHourlyLimit` amount" + }, + "setHourlyLimit(address,uint256)": { + "notice": "Updates the `hourlyLimit` amount for `bridgeToken`" + }, + "setLimit(address,uint256)": { + "notice": "Updates the `limit` amount for `bridgeToken`" + }, + "setSwapFee(address,uint64)": { + "notice": "Updates the `fee` value for `bridgeToken`" + }, + "setTreasury(address)": { + "notice": "Sets a new treasury contract" + }, + "swapIn(address,uint256,address)": { + "notice": "Mints the canonical token from a supported bridge token" + }, + "swapOut(address,uint256,address)": { + "notice": "Burns the canonical token in exchange for a bridge token" + }, + "toggleBridge(address)": { + "notice": "Pauses or unpauses swapping in and out for a token" + }, + "toggleFeesForAddress(address)": { + "notice": "Toggles fees for the address `theAddress`" + }, + "treasury()": { + "notice": "Reference to the treasury contract which can grant minting rights" + }, + "usage(address,uint256)": { + "notice": "Maps a bridge token to the associated hourly volume" + } + }, + "notice": "Contract for Angle agTokens on other chains than Ethereum mainnet", + "version": 1 + }, + "storageLayout": { + "storage": [ + { + "astId": 770, + "contract": "contracts/agToken/AgTokenSideChainMultiBridge.sol:AgTokenSideChainMultiBridge", + "label": "_initialized", + "offset": 0, + "slot": "0", + "type": "t_uint8" + }, + { + "astId": 773, + "contract": "contracts/agToken/AgTokenSideChainMultiBridge.sol:AgTokenSideChainMultiBridge", + "label": "_initializing", + "offset": 1, + "slot": "0", + "type": "t_bool" + }, + { + "astId": 2486, + "contract": "contracts/agToken/AgTokenSideChainMultiBridge.sol:AgTokenSideChainMultiBridge", + "label": "__gap", + "offset": 0, + "slot": "1", + "type": "t_array(t_uint256)50_storage" + }, + { + "astId": 1119, + "contract": "contracts/agToken/AgTokenSideChainMultiBridge.sol:AgTokenSideChainMultiBridge", + "label": "_balances", + "offset": 0, + "slot": "51", + "type": "t_mapping(t_address,t_uint256)" + }, + { + "astId": 1125, + "contract": "contracts/agToken/AgTokenSideChainMultiBridge.sol:AgTokenSideChainMultiBridge", + "label": "_allowances", + "offset": 0, + "slot": "52", + "type": "t_mapping(t_address,t_mapping(t_address,t_uint256))" + }, + { + "astId": 1127, + "contract": "contracts/agToken/AgTokenSideChainMultiBridge.sol:AgTokenSideChainMultiBridge", + "label": "_totalSupply", + "offset": 0, + "slot": "53", + "type": "t_uint256" + }, + { + "astId": 1129, + "contract": "contracts/agToken/AgTokenSideChainMultiBridge.sol:AgTokenSideChainMultiBridge", + "label": "_name", + "offset": 0, + "slot": "54", + "type": "t_string_storage" + }, + { + "astId": 1131, + "contract": "contracts/agToken/AgTokenSideChainMultiBridge.sol:AgTokenSideChainMultiBridge", + "label": "_symbol", + "offset": 0, + "slot": "55", + "type": "t_string_storage" + }, + { + "astId": 1710, + "contract": "contracts/agToken/AgTokenSideChainMultiBridge.sol:AgTokenSideChainMultiBridge", + "label": "__gap", + "offset": 0, + "slot": "56", + "type": "t_array(t_uint256)45_storage" + }, + { + "astId": 3203, + "contract": "contracts/agToken/AgTokenSideChainMultiBridge.sol:AgTokenSideChainMultiBridge", + "label": "_HASHED_NAME", + "offset": 0, + "slot": "101", + "type": "t_bytes32" + }, + { + "astId": 3205, + "contract": "contracts/agToken/AgTokenSideChainMultiBridge.sol:AgTokenSideChainMultiBridge", + "label": "_HASHED_VERSION", + "offset": 0, + "slot": "102", + "type": "t_bytes32" + }, + { + "astId": 3343, + "contract": "contracts/agToken/AgTokenSideChainMultiBridge.sol:AgTokenSideChainMultiBridge", + "label": "__gap", + "offset": 0, + "slot": "103", + "type": "t_array(t_uint256)50_storage" + }, + { + "astId": 1840, + "contract": "contracts/agToken/AgTokenSideChainMultiBridge.sol:AgTokenSideChainMultiBridge", + "label": "_nonces", + "offset": 0, + "slot": "153", + "type": "t_mapping(t_address,t_struct(Counter)2493_storage)" + }, + { + "astId": 1848, + "contract": "contracts/agToken/AgTokenSideChainMultiBridge.sol:AgTokenSideChainMultiBridge", + "label": "_PERMIT_TYPEHASH_DEPRECATED_SLOT", + "offset": 0, + "slot": "154", + "type": "t_bytes32" + }, + { + "astId": 2004, + "contract": "contracts/agToken/AgTokenSideChainMultiBridge.sol:AgTokenSideChainMultiBridge", + "label": "__gap", + "offset": 0, + "slot": "155", + "type": "t_array(t_uint256)49_storage" + }, + { + "astId": 7427, + "contract": "contracts/agToken/AgTokenSideChainMultiBridge.sol:AgTokenSideChainMultiBridge", + "label": "isMinter", + "offset": 0, + "slot": "204", + "type": "t_mapping(t_address,t_bool)" + }, + { + "astId": 7430, + "contract": "contracts/agToken/AgTokenSideChainMultiBridge.sol:AgTokenSideChainMultiBridge", + "label": "treasury", + "offset": 0, + "slot": "205", + "type": "t_address" + }, + { + "astId": 7739, + "contract": "contracts/agToken/AgTokenSideChainMultiBridge.sol:AgTokenSideChainMultiBridge", + "label": "bridges", + "offset": 0, + "slot": "206", + "type": "t_mapping(t_address,t_struct(BridgeDetails)7733_storage)" + }, + { + "astId": 7743, + "contract": "contracts/agToken/AgTokenSideChainMultiBridge.sol:AgTokenSideChainMultiBridge", + "label": "bridgeTokensList", + "offset": 0, + "slot": "207", + "type": "t_array(t_address)dyn_storage" + }, + { + "astId": 7750, + "contract": "contracts/agToken/AgTokenSideChainMultiBridge.sol:AgTokenSideChainMultiBridge", + "label": "usage", + "offset": 0, + "slot": "208", + "type": "t_mapping(t_address,t_mapping(t_uint256,t_uint256))" + }, + { + "astId": 7755, + "contract": "contracts/agToken/AgTokenSideChainMultiBridge.sol:AgTokenSideChainMultiBridge", + "label": "isFeeExempt", + "offset": 0, + "slot": "209", + "type": "t_mapping(t_address,t_uint256)" + }, + { + "astId": 7758, + "contract": "contracts/agToken/AgTokenSideChainMultiBridge.sol:AgTokenSideChainMultiBridge", + "label": "chainTotalHourlyLimit", + "offset": 0, + "slot": "210", + "type": "t_uint256" + }, + { + "astId": 7763, + "contract": "contracts/agToken/AgTokenSideChainMultiBridge.sol:AgTokenSideChainMultiBridge", + "label": "chainTotalUsage", + "offset": 0, + "slot": "211", + "type": "t_mapping(t_uint256,t_uint256)" + } + ], + "types": { + "t_address": { + "encoding": "inplace", + "label": "address", + "numberOfBytes": "20" + }, + "t_array(t_address)dyn_storage": { + "base": "t_address", + "encoding": "dynamic_array", + "label": "address[]", + "numberOfBytes": "32" + }, + "t_array(t_uint256)45_storage": { + "base": "t_uint256", + "encoding": "inplace", + "label": "uint256[45]", + "numberOfBytes": "1440" + }, + "t_array(t_uint256)49_storage": { + "base": "t_uint256", + "encoding": "inplace", + "label": "uint256[49]", + "numberOfBytes": "1568" + }, + "t_array(t_uint256)50_storage": { + "base": "t_uint256", + "encoding": "inplace", + "label": "uint256[50]", + "numberOfBytes": "1600" + }, + "t_bool": { + "encoding": "inplace", + "label": "bool", + "numberOfBytes": "1" + }, + "t_bytes32": { + "encoding": "inplace", + "label": "bytes32", + "numberOfBytes": "32" + }, + "t_mapping(t_address,t_bool)": { + "encoding": "mapping", + "key": "t_address", + "label": "mapping(address => bool)", + "numberOfBytes": "32", + "value": "t_bool" + }, + "t_mapping(t_address,t_mapping(t_address,t_uint256))": { + "encoding": "mapping", + "key": "t_address", + "label": "mapping(address => mapping(address => uint256))", + "numberOfBytes": "32", + "value": "t_mapping(t_address,t_uint256)" + }, + "t_mapping(t_address,t_mapping(t_uint256,t_uint256))": { + "encoding": "mapping", + "key": "t_address", + "label": "mapping(address => mapping(uint256 => uint256))", + "numberOfBytes": "32", + "value": "t_mapping(t_uint256,t_uint256)" + }, + "t_mapping(t_address,t_struct(BridgeDetails)7733_storage)": { + "encoding": "mapping", + "key": "t_address", + "label": "mapping(address => struct AgTokenSideChainMultiBridge.BridgeDetails)", + "numberOfBytes": "32", + "value": "t_struct(BridgeDetails)7733_storage" + }, + "t_mapping(t_address,t_struct(Counter)2493_storage)": { + "encoding": "mapping", + "key": "t_address", + "label": "mapping(address => struct CountersUpgradeable.Counter)", + "numberOfBytes": "32", + "value": "t_struct(Counter)2493_storage" + }, + "t_mapping(t_address,t_uint256)": { + "encoding": "mapping", + "key": "t_address", + "label": "mapping(address => uint256)", + "numberOfBytes": "32", + "value": "t_uint256" + }, + "t_mapping(t_uint256,t_uint256)": { + "encoding": "mapping", + "key": "t_uint256", + "label": "mapping(uint256 => uint256)", + "numberOfBytes": "32", + "value": "t_uint256" + }, + "t_string_storage": { + "encoding": "bytes", + "label": "string", + "numberOfBytes": "32" + }, + "t_struct(BridgeDetails)7733_storage": { + "encoding": "inplace", + "label": "struct AgTokenSideChainMultiBridge.BridgeDetails", + "members": [ + { + "astId": 7724, + "contract": "contracts/agToken/AgTokenSideChainMultiBridge.sol:AgTokenSideChainMultiBridge", + "label": "limit", + "offset": 0, + "slot": "0", + "type": "t_uint256" + }, + { + "astId": 7726, + "contract": "contracts/agToken/AgTokenSideChainMultiBridge.sol:AgTokenSideChainMultiBridge", + "label": "hourlyLimit", + "offset": 0, + "slot": "1", + "type": "t_uint256" + }, + { + "astId": 7728, + "contract": "contracts/agToken/AgTokenSideChainMultiBridge.sol:AgTokenSideChainMultiBridge", + "label": "fee", + "offset": 0, + "slot": "2", + "type": "t_uint64" + }, + { + "astId": 7730, + "contract": "contracts/agToken/AgTokenSideChainMultiBridge.sol:AgTokenSideChainMultiBridge", + "label": "allowed", + "offset": 8, + "slot": "2", + "type": "t_bool" + }, + { + "astId": 7732, + "contract": "contracts/agToken/AgTokenSideChainMultiBridge.sol:AgTokenSideChainMultiBridge", + "label": "paused", + "offset": 9, + "slot": "2", + "type": "t_bool" + } + ], + "numberOfBytes": "96" + }, + "t_struct(Counter)2493_storage": { + "encoding": "inplace", + "label": "struct CountersUpgradeable.Counter", + "members": [ + { + "astId": 2492, + "contract": "contracts/agToken/AgTokenSideChainMultiBridge.sol:AgTokenSideChainMultiBridge", + "label": "_value", + "offset": 0, + "slot": "0", + "type": "t_uint256" + } + ], + "numberOfBytes": "32" + }, + "t_uint256": { + "encoding": "inplace", + "label": "uint256", + "numberOfBytes": "32" + }, + "t_uint64": { + "encoding": "inplace", + "label": "uint64", + "numberOfBytes": "8" + }, + "t_uint8": { + "encoding": "inplace", + "label": "uint8", + "numberOfBytes": "1" + } + } + } +} \ No newline at end of file diff --git a/deployments/celo/CoreBorrowTest.json b/deployments/celo/CoreBorrowTest.json new file mode 100644 index 00000000..9489e22b --- /dev/null +++ b/deployments/celo/CoreBorrowTest.json @@ -0,0 +1,337 @@ +{ + "address": "0x03C2d2014795EE8cA78B62738433B457AB19F4b3", + "abi": [ + { + "inputs": [ + { + "internalType": "address", + "name": "_logic", + "type": "address" + }, + { + "internalType": "address", + "name": "admin_", + "type": "address" + }, + { + "internalType": "bytes", + "name": "_data", + "type": "bytes" + } + ], + "stateMutability": "payable", + "type": "constructor" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "previousAdmin", + "type": "address" + }, + { + "indexed": false, + "internalType": "address", + "name": "newAdmin", + "type": "address" + } + ], + "name": "AdminChanged", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "beacon", + "type": "address" + } + ], + "name": "BeaconUpgraded", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "implementation", + "type": "address" + } + ], + "name": "Upgraded", + "type": "event" + }, + { + "stateMutability": "payable", + "type": "fallback" + }, + { + "inputs": [], + "name": "admin", + "outputs": [ + { + "internalType": "address", + "name": "admin_", + "type": "address" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "newAdmin", + "type": "address" + } + ], + "name": "changeAdmin", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "implementation", + "outputs": [ + { + "internalType": "address", + "name": "implementation_", + "type": "address" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "newImplementation", + "type": "address" + } + ], + "name": "upgradeTo", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "newImplementation", + "type": "address" + }, + { + "internalType": "bytes", + "name": "data", + "type": "bytes" + } + ], + "name": "upgradeToAndCall", + "outputs": [], + "stateMutability": "payable", + "type": "function" + }, + { + "stateMutability": "payable", + "type": "receive" + } + ], + "transactionHash": "0x16c9afff600a9ad09f93040c3c620576b7f04e36d94979e6577666807fddb83d", + "receipt": { + "to": null, + "from": "0xfdA462548Ce04282f4B6D6619823a7C64Fdc0185", + "contractAddress": "0x03C2d2014795EE8cA78B62738433B457AB19F4b3", + "transactionIndex": 6, + "gasUsed": "1038534", + "logsBloom": "0x00000004000000000800000400000000480000000000000000800000200000000000020000000000000000000000000000000000000000000000000000000020000000000000000000000000000002000000000000002000000200000000000000000000020000400000000000000800000000800000000000000000000008000000000000000000000000000000000000000003000080000000000000804000000000000040000000000000000400000000000000000004001000000000001000000020020000000000008000040000000800000400000100000000000020000080800000000000000000000000000400000000000000000000000000040000", + "blockHash": "0xe7325e6830fae52129b93f46b7130840ae2793e78ca91f4ba41071624b709ce1", + "transactionHash": "0x16c9afff600a9ad09f93040c3c620576b7f04e36d94979e6577666807fddb83d", + "logs": [ + { + "transactionIndex": 6, + "blockNumber": 23443571, + "transactionHash": "0x16c9afff600a9ad09f93040c3c620576b7f04e36d94979e6577666807fddb83d", + "address": "0x03C2d2014795EE8cA78B62738433B457AB19F4b3", + "topics": [ + "0xbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b", + "0x0000000000000000000000003e399ae5b4d8bc0021e53b51c8bcdd66dd62c03b" + ], + "data": "0x", + "logIndex": 55, + "blockHash": "0xe7325e6830fae52129b93f46b7130840ae2793e78ca91f4ba41071624b709ce1" + }, + { + "transactionIndex": 6, + "blockNumber": 23443571, + "transactionHash": "0x16c9afff600a9ad09f93040c3c620576b7f04e36d94979e6577666807fddb83d", + "address": "0x03C2d2014795EE8cA78B62738433B457AB19F4b3", + "topics": [ + "0x2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d", + "0x7935bd0ae54bc31f548c14dba4d37c5c64b3f8ca900cb468fb8abd54d5894f55", + "0x000000000000000000000000fda462548ce04282f4b6d6619823a7c64fdc0185", + "0x000000000000000000000000fda462548ce04282f4b6d6619823a7c64fdc0185" + ], + "data": "0x", + "logIndex": 56, + "blockHash": "0xe7325e6830fae52129b93f46b7130840ae2793e78ca91f4ba41071624b709ce1" + }, + { + "transactionIndex": 6, + "blockNumber": 23443571, + "transactionHash": "0x16c9afff600a9ad09f93040c3c620576b7f04e36d94979e6577666807fddb83d", + "address": "0x03C2d2014795EE8cA78B62738433B457AB19F4b3", + "topics": [ + "0x2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d", + "0x55435dd261a4b9b3364963f7738a7a662ad9c84396d64be3365284bb7f0a5041", + "0x000000000000000000000000434153aa505959bcd5aaa7c17445eb8d835086f5", + "0x000000000000000000000000fda462548ce04282f4b6d6619823a7c64fdc0185" + ], + "data": "0x", + "logIndex": 57, + "blockHash": "0xe7325e6830fae52129b93f46b7130840ae2793e78ca91f4ba41071624b709ce1" + }, + { + "transactionIndex": 6, + "blockNumber": 23443571, + "transactionHash": "0x16c9afff600a9ad09f93040c3c620576b7f04e36d94979e6577666807fddb83d", + "address": "0x03C2d2014795EE8cA78B62738433B457AB19F4b3", + "topics": [ + "0x2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d", + "0x55435dd261a4b9b3364963f7738a7a662ad9c84396d64be3365284bb7f0a5041", + "0x000000000000000000000000fda462548ce04282f4b6d6619823a7c64fdc0185", + "0x000000000000000000000000fda462548ce04282f4b6d6619823a7c64fdc0185" + ], + "data": "0x", + "logIndex": 58, + "blockHash": "0xe7325e6830fae52129b93f46b7130840ae2793e78ca91f4ba41071624b709ce1" + }, + { + "transactionIndex": 6, + "blockNumber": 23443571, + "transactionHash": "0x16c9afff600a9ad09f93040c3c620576b7f04e36d94979e6577666807fddb83d", + "address": "0x03C2d2014795EE8cA78B62738433B457AB19F4b3", + "topics": [ + "0xbd79b86ffe0ab8e8776151514217cd7cacd52c909f66475c3af44e129f0b00ff", + "0x55435dd261a4b9b3364963f7738a7a662ad9c84396d64be3365284bb7f0a5041", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x7935bd0ae54bc31f548c14dba4d37c5c64b3f8ca900cb468fb8abd54d5894f55" + ], + "data": "0x", + "logIndex": 59, + "blockHash": "0xe7325e6830fae52129b93f46b7130840ae2793e78ca91f4ba41071624b709ce1" + }, + { + "transactionIndex": 6, + "blockNumber": 23443571, + "transactionHash": "0x16c9afff600a9ad09f93040c3c620576b7f04e36d94979e6577666807fddb83d", + "address": "0x03C2d2014795EE8cA78B62738433B457AB19F4b3", + "topics": [ + "0xbd79b86ffe0ab8e8776151514217cd7cacd52c909f66475c3af44e129f0b00ff", + "0x7935bd0ae54bc31f548c14dba4d37c5c64b3f8ca900cb468fb8abd54d5894f55", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x7935bd0ae54bc31f548c14dba4d37c5c64b3f8ca900cb468fb8abd54d5894f55" + ], + "data": "0x", + "logIndex": 60, + "blockHash": "0xe7325e6830fae52129b93f46b7130840ae2793e78ca91f4ba41071624b709ce1" + }, + { + "transactionIndex": 6, + "blockNumber": 23443571, + "transactionHash": "0x16c9afff600a9ad09f93040c3c620576b7f04e36d94979e6577666807fddb83d", + "address": "0x03C2d2014795EE8cA78B62738433B457AB19F4b3", + "topics": [ + "0xbd79b86ffe0ab8e8776151514217cd7cacd52c909f66475c3af44e129f0b00ff", + "0x0ae0130c6b34f32239dfe5e419a3fbd7546b44e99783257f2d93526d5a936d46", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x7935bd0ae54bc31f548c14dba4d37c5c64b3f8ca900cb468fb8abd54d5894f55" + ], + "data": "0x", + "logIndex": 61, + "blockHash": "0xe7325e6830fae52129b93f46b7130840ae2793e78ca91f4ba41071624b709ce1" + }, + { + "transactionIndex": 6, + "blockNumber": 23443571, + "transactionHash": "0x16c9afff600a9ad09f93040c3c620576b7f04e36d94979e6577666807fddb83d", + "address": "0x03C2d2014795EE8cA78B62738433B457AB19F4b3", + "topics": [ + "0x7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb3847402498" + ], + "data": "0x0000000000000000000000000000000000000000000000000000000000000001", + "logIndex": 62, + "blockHash": "0xe7325e6830fae52129b93f46b7130840ae2793e78ca91f4ba41071624b709ce1" + }, + { + "transactionIndex": 6, + "blockNumber": 23443571, + "transactionHash": "0x16c9afff600a9ad09f93040c3c620576b7f04e36d94979e6577666807fddb83d", + "address": "0x03C2d2014795EE8cA78B62738433B457AB19F4b3", + "topics": [ + "0x7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f" + ], + "data": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000005183f032bf42109cd370b9559fd22207e432301e", + "logIndex": 63, + "blockHash": "0xe7325e6830fae52129b93f46b7130840ae2793e78ca91f4ba41071624b709ce1" + } + ], + "blockNumber": 23443571, + "cumulativeGasUsed": "2176842", + "status": 1, + "byzantium": true + }, + "args": [ + "0x3E399AE5B4D8bc0021e53b51c8BCdD66DD62c03b", + "0x5183f032bf42109cD370B9559FD22207e432301E", + "0x485cc955000000000000000000000000fda462548ce04282f4b6d6619823a7c64fdc0185000000000000000000000000434153aa505959bcd5aaa7c17445eb8d835086f5" + ], + "numDeployments": 1, + "solcInputHash": "871924e0c138825a2736b76def8fef8d", + "metadata": "{\"compiler\":{\"version\":\"0.8.17+commit.8df45f5f\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_logic\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"admin_\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"_data\",\"type\":\"bytes\"}],\"stateMutability\":\"payable\",\"type\":\"constructor\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"previousAdmin\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"newAdmin\",\"type\":\"address\"}],\"name\":\"AdminChanged\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"beacon\",\"type\":\"address\"}],\"name\":\"BeaconUpgraded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"implementation\",\"type\":\"address\"}],\"name\":\"Upgraded\",\"type\":\"event\"},{\"stateMutability\":\"payable\",\"type\":\"fallback\"},{\"inputs\":[],\"name\":\"admin\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"admin_\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newAdmin\",\"type\":\"address\"}],\"name\":\"changeAdmin\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"implementation\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"implementation_\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newImplementation\",\"type\":\"address\"}],\"name\":\"upgradeTo\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newImplementation\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"}],\"name\":\"upgradeToAndCall\",\"outputs\":[],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"stateMutability\":\"payable\",\"type\":\"receive\"}],\"devdoc\":{\"details\":\"This contract implements a proxy that is upgradeable by an admin. It is fully forked from OpenZeppelin `TransparentUpgradeableProxy` To avoid https://medium.com/nomic-labs-blog/malicious-backdoors-in-ethereum-proxies-62629adf3357[proxy selector clashing], which can potentially be used in an attack, this contract uses the https://blog.openzeppelin.com/the-transparent-proxy-pattern/[transparent proxy pattern]. This pattern implies two things that go hand in hand: 1. If any account other than the admin calls the proxy, the call will be forwarded to the implementation, even if that call matches one of the admin functions exposed by the proxy itself. 2. If the admin calls the proxy, it can access the admin functions, but its calls will never be forwarded to the implementation. If the admin tries to call a function on the implementation it will fail with an error that says \\\"admin cannot fallback to proxy target\\\". These properties mean that the admin account can only be used for admin actions like upgrading the proxy or changing the admin, so it's best if it's a dedicated account that is not used for anything else. This will avoid headaches due to sudden errors when trying to call a function from the proxy implementation. Our recommendation is for the dedicated account to be an instance of the {ProxyAdmin} contract. If set up this way, you should think of the `ProxyAdmin` instance as the real administrative interface of your proxy.\",\"kind\":\"dev\",\"methods\":{\"admin()\":{\"details\":\"Returns the current admin. NOTE: Only the admin can call this function. See {ProxyAdmin-getProxyAdmin}. TIP: To get this value clients can read directly from the storage slot shown below (specified by EIP1967) using the https://eth.wiki/json-rpc/API#eth_getstorageat[`eth_getStorageAt`] RPC call. `0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103`\"},\"changeAdmin(address)\":{\"details\":\"Changes the admin of the proxy. Emits an {AdminChanged} event. NOTE: Only the admin can call this function. See {ProxyAdmin-changeProxyAdmin}.\"},\"constructor\":{\"details\":\"Initializes an upgradeable proxy managed by `_admin`, backed by the implementation at `_logic`, and optionally initialized with `_data` as explained in {ERC1967Proxy-constructor}.\"},\"implementation()\":{\"details\":\"Returns the current implementation. NOTE: Only the admin can call this function. See {ProxyAdmin-getProxyImplementation}. TIP: To get this value clients can read directly from the storage slot shown below (specified by EIP1967) using the https://eth.wiki/json-rpc/API#eth_getstorageat[`eth_getStorageAt`] RPC call. `0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc`\"},\"upgradeTo(address)\":{\"details\":\"Upgrade the implementation of the proxy. NOTE: Only the admin can call this function. See {ProxyAdmin-upgrade}.\"},\"upgradeToAndCall(address,bytes)\":{\"details\":\"Upgrade the implementation of the proxy, and then call a function from the new implementation as specified by `data`, which should be an encoded function call. This is useful to initialize new storage variables in the proxied contract. NOTE: Only the admin can call this function. See {ProxyAdmin-upgradeAndCall}.\"}},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/external/TransparentUpgradeableProxy.sol\":\"TransparentUpgradeableProxy\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":1000000},\"remappings\":[]},\"sources\":{\"@openzeppelin/contracts/interfaces/draft-IERC1822.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.5.0) (interfaces/draft-IERC1822.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev ERC1822: Universal Upgradeable Proxy Standard (UUPS) documents a method for upgradeability through a simplified\\n * proxy whose upgrades are fully controlled by the current implementation.\\n */\\ninterface IERC1822Proxiable {\\n /**\\n * @dev Returns the storage slot that the proxiable contract assumes is being used to store the implementation\\n * address.\\n *\\n * IMPORTANT: A proxy pointing at a proxiable contract should not be considered proxiable itself, because this risks\\n * bricking a proxy that upgrades to it, by delegating to itself until out of gas. Thus it is critical that this\\n * function revert if invoked through a proxy.\\n */\\n function proxiableUUID() external view returns (bytes32);\\n}\\n\",\"keccak256\":\"0x1d4afe6cb24200cc4545eed814ecf5847277dfe5d613a1707aad5fceecebcfff\",\"license\":\"MIT\"},\"@openzeppelin/contracts/proxy/ERC1967/ERC1967Proxy.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.7.0) (proxy/ERC1967/ERC1967Proxy.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../Proxy.sol\\\";\\nimport \\\"./ERC1967Upgrade.sol\\\";\\n\\n/**\\n * @dev This contract implements an upgradeable proxy. It is upgradeable because calls are delegated to an\\n * implementation address that can be changed. This address is stored in storage in the location specified by\\n * https://eips.ethereum.org/EIPS/eip-1967[EIP1967], so that it doesn't conflict with the storage layout of the\\n * implementation behind the proxy.\\n */\\ncontract ERC1967Proxy is Proxy, ERC1967Upgrade {\\n /**\\n * @dev Initializes the upgradeable proxy with an initial implementation specified by `_logic`.\\n *\\n * If `_data` is nonempty, it's used as data in a delegate call to `_logic`. This will typically be an encoded\\n * function call, and allows initializing the storage of the proxy like a Solidity constructor.\\n */\\n constructor(address _logic, bytes memory _data) payable {\\n _upgradeToAndCall(_logic, _data, false);\\n }\\n\\n /**\\n * @dev Returns the current implementation address.\\n */\\n function _implementation() internal view virtual override returns (address impl) {\\n return ERC1967Upgrade._getImplementation();\\n }\\n}\\n\",\"keccak256\":\"0xa2b22da3032e50b55f95ec1d13336102d675f341167aa76db571ef7f8bb7975d\",\"license\":\"MIT\"},\"@openzeppelin/contracts/proxy/ERC1967/ERC1967Upgrade.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.5.0) (proxy/ERC1967/ERC1967Upgrade.sol)\\n\\npragma solidity ^0.8.2;\\n\\nimport \\\"../beacon/IBeacon.sol\\\";\\nimport \\\"../../interfaces/draft-IERC1822.sol\\\";\\nimport \\\"../../utils/Address.sol\\\";\\nimport \\\"../../utils/StorageSlot.sol\\\";\\n\\n/**\\n * @dev This abstract contract provides getters and event emitting update functions for\\n * https://eips.ethereum.org/EIPS/eip-1967[EIP1967] slots.\\n *\\n * _Available since v4.1._\\n *\\n * @custom:oz-upgrades-unsafe-allow delegatecall\\n */\\nabstract contract ERC1967Upgrade {\\n // This is the keccak-256 hash of \\\"eip1967.proxy.rollback\\\" subtracted by 1\\n bytes32 private constant _ROLLBACK_SLOT = 0x4910fdfa16fed3260ed0e7147f7cc6da11a60208b5b9406d12a635614ffd9143;\\n\\n /**\\n * @dev Storage slot with the address of the current implementation.\\n * This is the keccak-256 hash of \\\"eip1967.proxy.implementation\\\" subtracted by 1, and is\\n * validated in the constructor.\\n */\\n bytes32 internal constant _IMPLEMENTATION_SLOT = 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc;\\n\\n /**\\n * @dev Emitted when the implementation is upgraded.\\n */\\n event Upgraded(address indexed implementation);\\n\\n /**\\n * @dev Returns the current implementation address.\\n */\\n function _getImplementation() internal view returns (address) {\\n return StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value;\\n }\\n\\n /**\\n * @dev Stores a new address in the EIP1967 implementation slot.\\n */\\n function _setImplementation(address newImplementation) private {\\n require(Address.isContract(newImplementation), \\\"ERC1967: new implementation is not a contract\\\");\\n StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value = newImplementation;\\n }\\n\\n /**\\n * @dev Perform implementation upgrade\\n *\\n * Emits an {Upgraded} event.\\n */\\n function _upgradeTo(address newImplementation) internal {\\n _setImplementation(newImplementation);\\n emit Upgraded(newImplementation);\\n }\\n\\n /**\\n * @dev Perform implementation upgrade with additional setup call.\\n *\\n * Emits an {Upgraded} event.\\n */\\n function _upgradeToAndCall(\\n address newImplementation,\\n bytes memory data,\\n bool forceCall\\n ) internal {\\n _upgradeTo(newImplementation);\\n if (data.length > 0 || forceCall) {\\n Address.functionDelegateCall(newImplementation, data);\\n }\\n }\\n\\n /**\\n * @dev Perform implementation upgrade with security checks for UUPS proxies, and additional setup call.\\n *\\n * Emits an {Upgraded} event.\\n */\\n function _upgradeToAndCallUUPS(\\n address newImplementation,\\n bytes memory data,\\n bool forceCall\\n ) internal {\\n // Upgrades from old implementations will perform a rollback test. This test requires the new\\n // implementation to upgrade back to the old, non-ERC1822 compliant, implementation. Removing\\n // this special case will break upgrade paths from old UUPS implementation to new ones.\\n if (StorageSlot.getBooleanSlot(_ROLLBACK_SLOT).value) {\\n _setImplementation(newImplementation);\\n } else {\\n try IERC1822Proxiable(newImplementation).proxiableUUID() returns (bytes32 slot) {\\n require(slot == _IMPLEMENTATION_SLOT, \\\"ERC1967Upgrade: unsupported proxiableUUID\\\");\\n } catch {\\n revert(\\\"ERC1967Upgrade: new implementation is not UUPS\\\");\\n }\\n _upgradeToAndCall(newImplementation, data, forceCall);\\n }\\n }\\n\\n /**\\n * @dev Storage slot with the admin of the contract.\\n * This is the keccak-256 hash of \\\"eip1967.proxy.admin\\\" subtracted by 1, and is\\n * validated in the constructor.\\n */\\n bytes32 internal constant _ADMIN_SLOT = 0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103;\\n\\n /**\\n * @dev Emitted when the admin account has changed.\\n */\\n event AdminChanged(address previousAdmin, address newAdmin);\\n\\n /**\\n * @dev Returns the current admin.\\n */\\n function _getAdmin() internal view returns (address) {\\n return StorageSlot.getAddressSlot(_ADMIN_SLOT).value;\\n }\\n\\n /**\\n * @dev Stores a new address in the EIP1967 admin slot.\\n */\\n function _setAdmin(address newAdmin) private {\\n require(newAdmin != address(0), \\\"ERC1967: new admin is the zero address\\\");\\n StorageSlot.getAddressSlot(_ADMIN_SLOT).value = newAdmin;\\n }\\n\\n /**\\n * @dev Changes the admin of the proxy.\\n *\\n * Emits an {AdminChanged} event.\\n */\\n function _changeAdmin(address newAdmin) internal {\\n emit AdminChanged(_getAdmin(), newAdmin);\\n _setAdmin(newAdmin);\\n }\\n\\n /**\\n * @dev The storage slot of the UpgradeableBeacon contract which defines the implementation for this proxy.\\n * This is bytes32(uint256(keccak256('eip1967.proxy.beacon')) - 1)) and is validated in the constructor.\\n */\\n bytes32 internal constant _BEACON_SLOT = 0xa3f0ad74e5423aebfd80d3ef4346578335a9a72aeaee59ff6cb3582b35133d50;\\n\\n /**\\n * @dev Emitted when the beacon is upgraded.\\n */\\n event BeaconUpgraded(address indexed beacon);\\n\\n /**\\n * @dev Returns the current beacon.\\n */\\n function _getBeacon() internal view returns (address) {\\n return StorageSlot.getAddressSlot(_BEACON_SLOT).value;\\n }\\n\\n /**\\n * @dev Stores a new beacon in the EIP1967 beacon slot.\\n */\\n function _setBeacon(address newBeacon) private {\\n require(Address.isContract(newBeacon), \\\"ERC1967: new beacon is not a contract\\\");\\n require(\\n Address.isContract(IBeacon(newBeacon).implementation()),\\n \\\"ERC1967: beacon implementation is not a contract\\\"\\n );\\n StorageSlot.getAddressSlot(_BEACON_SLOT).value = newBeacon;\\n }\\n\\n /**\\n * @dev Perform beacon upgrade with additional setup call. Note: This upgrades the address of the beacon, it does\\n * not upgrade the implementation contained in the beacon (see {UpgradeableBeacon-_setImplementation} for that).\\n *\\n * Emits a {BeaconUpgraded} event.\\n */\\n function _upgradeBeaconToAndCall(\\n address newBeacon,\\n bytes memory data,\\n bool forceCall\\n ) internal {\\n _setBeacon(newBeacon);\\n emit BeaconUpgraded(newBeacon);\\n if (data.length > 0 || forceCall) {\\n Address.functionDelegateCall(IBeacon(newBeacon).implementation(), data);\\n }\\n }\\n}\\n\",\"keccak256\":\"0xabf3f59bc0e5423eae45e459dbe92e7052c6983628d39008590edc852a62f94a\",\"license\":\"MIT\"},\"@openzeppelin/contracts/proxy/Proxy.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.6.0) (proxy/Proxy.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev This abstract contract provides a fallback function that delegates all calls to another contract using the EVM\\n * instruction `delegatecall`. We refer to the second contract as the _implementation_ behind the proxy, and it has to\\n * be specified by overriding the virtual {_implementation} function.\\n *\\n * Additionally, delegation to the implementation can be triggered manually through the {_fallback} function, or to a\\n * different contract through the {_delegate} function.\\n *\\n * The success and return data of the delegated call will be returned back to the caller of the proxy.\\n */\\nabstract contract Proxy {\\n /**\\n * @dev Delegates the current call to `implementation`.\\n *\\n * This function does not return to its internal call site, it will return directly to the external caller.\\n */\\n function _delegate(address implementation) internal virtual {\\n assembly {\\n // Copy msg.data. We take full control of memory in this inline assembly\\n // block because it will not return to Solidity code. We overwrite the\\n // Solidity scratch pad at memory position 0.\\n calldatacopy(0, 0, calldatasize())\\n\\n // Call the implementation.\\n // out and outsize are 0 because we don't know the size yet.\\n let result := delegatecall(gas(), implementation, 0, calldatasize(), 0, 0)\\n\\n // Copy the returned data.\\n returndatacopy(0, 0, returndatasize())\\n\\n switch result\\n // delegatecall returns 0 on error.\\n case 0 {\\n revert(0, returndatasize())\\n }\\n default {\\n return(0, returndatasize())\\n }\\n }\\n }\\n\\n /**\\n * @dev This is a virtual function that should be overridden so it returns the address to which the fallback function\\n * and {_fallback} should delegate.\\n */\\n function _implementation() internal view virtual returns (address);\\n\\n /**\\n * @dev Delegates the current call to the address returned by `_implementation()`.\\n *\\n * This function does not return to its internal call site, it will return directly to the external caller.\\n */\\n function _fallback() internal virtual {\\n _beforeFallback();\\n _delegate(_implementation());\\n }\\n\\n /**\\n * @dev Fallback function that delegates calls to the address returned by `_implementation()`. Will run if no other\\n * function in the contract matches the call data.\\n */\\n fallback() external payable virtual {\\n _fallback();\\n }\\n\\n /**\\n * @dev Fallback function that delegates calls to the address returned by `_implementation()`. Will run if call data\\n * is empty.\\n */\\n receive() external payable virtual {\\n _fallback();\\n }\\n\\n /**\\n * @dev Hook that is called before falling back to the implementation. Can happen as part of a manual `_fallback`\\n * call, or as part of the Solidity `fallback` or `receive` functions.\\n *\\n * If overridden should call `super._beforeFallback()`.\\n */\\n function _beforeFallback() internal virtual {}\\n}\\n\",\"keccak256\":\"0xc130fe33f1b2132158531a87734153293f6d07bc263ff4ac90e85da9c82c0e27\",\"license\":\"MIT\"},\"@openzeppelin/contracts/proxy/beacon/IBeacon.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (proxy/beacon/IBeacon.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev This is the interface that {BeaconProxy} expects of its beacon.\\n */\\ninterface IBeacon {\\n /**\\n * @dev Must return an address that can be used as a delegate call target.\\n *\\n * {BeaconProxy} will check that this address is a contract.\\n */\\n function implementation() external view returns (address);\\n}\\n\",\"keccak256\":\"0xd50a3421ac379ccb1be435fa646d66a65c986b4924f0849839f08692f39dde61\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/Address.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.7.0) (utils/Address.sol)\\n\\npragma solidity ^0.8.1;\\n\\n/**\\n * @dev Collection of functions related to the address type\\n */\\nlibrary Address {\\n /**\\n * @dev Returns true if `account` is a contract.\\n *\\n * [IMPORTANT]\\n * ====\\n * It is unsafe to assume that an address for which this function returns\\n * false is an externally-owned account (EOA) and not a contract.\\n *\\n * Among others, `isContract` will return false for the following\\n * types of addresses:\\n *\\n * - an externally-owned account\\n * - a contract in construction\\n * - an address where a contract will be created\\n * - an address where a contract lived, but was destroyed\\n * ====\\n *\\n * [IMPORTANT]\\n * ====\\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\\n *\\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\\n * constructor.\\n * ====\\n */\\n function isContract(address account) internal view returns (bool) {\\n // This method relies on extcodesize/address.code.length, which returns 0\\n // for contracts in construction, since the code is only stored at the end\\n // of the constructor execution.\\n\\n return account.code.length > 0;\\n }\\n\\n /**\\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\\n * `recipient`, forwarding all available gas and reverting on errors.\\n *\\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\\n * imposed by `transfer`, making them unable to receive funds via\\n * `transfer`. {sendValue} removes this limitation.\\n *\\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\\n *\\n * IMPORTANT: because control is transferred to `recipient`, care must be\\n * taken to not create reentrancy vulnerabilities. Consider using\\n * {ReentrancyGuard} or the\\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\\n */\\n function sendValue(address payable recipient, uint256 amount) internal {\\n require(address(this).balance >= amount, \\\"Address: insufficient balance\\\");\\n\\n (bool success, ) = recipient.call{value: amount}(\\\"\\\");\\n require(success, \\\"Address: unable to send value, recipient may have reverted\\\");\\n }\\n\\n /**\\n * @dev Performs a Solidity function call using a low level `call`. A\\n * plain `call` is an unsafe replacement for a function call: use this\\n * function instead.\\n *\\n * If `target` reverts with a revert reason, it is bubbled up by this\\n * function (like regular Solidity function calls).\\n *\\n * Returns the raw returned data. To convert to the expected return value,\\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\\n *\\n * Requirements:\\n *\\n * - `target` must be a contract.\\n * - calling `target` with `data` must not revert.\\n *\\n * _Available since v3.1._\\n */\\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\\n return functionCall(target, data, \\\"Address: low-level call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\\n * `errorMessage` as a fallback revert reason when `target` reverts.\\n *\\n * _Available since v3.1._\\n */\\n function functionCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n return functionCallWithValue(target, data, 0, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but also transferring `value` wei to `target`.\\n *\\n * Requirements:\\n *\\n * - the calling contract must have an ETH balance of at least `value`.\\n * - the called Solidity function must be `payable`.\\n *\\n * _Available since v3.1._\\n */\\n function functionCallWithValue(\\n address target,\\n bytes memory data,\\n uint256 value\\n ) internal returns (bytes memory) {\\n return functionCallWithValue(target, data, value, \\\"Address: low-level call with value failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\\n * with `errorMessage` as a fallback revert reason when `target` reverts.\\n *\\n * _Available since v3.1._\\n */\\n function functionCallWithValue(\\n address target,\\n bytes memory data,\\n uint256 value,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n require(address(this).balance >= value, \\\"Address: insufficient balance for call\\\");\\n require(isContract(target), \\\"Address: call to non-contract\\\");\\n\\n (bool success, bytes memory returndata) = target.call{value: value}(data);\\n return verifyCallResult(success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but performing a static call.\\n *\\n * _Available since v3.3._\\n */\\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\\n return functionStaticCall(target, data, \\\"Address: low-level static call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\\n * but performing a static call.\\n *\\n * _Available since v3.3._\\n */\\n function functionStaticCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal view returns (bytes memory) {\\n require(isContract(target), \\\"Address: static call to non-contract\\\");\\n\\n (bool success, bytes memory returndata) = target.staticcall(data);\\n return verifyCallResult(success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but performing a delegate call.\\n *\\n * _Available since v3.4._\\n */\\n function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {\\n return functionDelegateCall(target, data, \\\"Address: low-level delegate call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\\n * but performing a delegate call.\\n *\\n * _Available since v3.4._\\n */\\n function functionDelegateCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n require(isContract(target), \\\"Address: delegate call to non-contract\\\");\\n\\n (bool success, bytes memory returndata) = target.delegatecall(data);\\n return verifyCallResult(success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the\\n * revert reason using the provided one.\\n *\\n * _Available since v4.3._\\n */\\n function verifyCallResult(\\n bool success,\\n bytes memory returndata,\\n string memory errorMessage\\n ) internal pure returns (bytes memory) {\\n if (success) {\\n return returndata;\\n } else {\\n // Look for revert reason and bubble it up if present\\n if (returndata.length > 0) {\\n // The easiest way to bubble the revert reason is using memory via assembly\\n /// @solidity memory-safe-assembly\\n assembly {\\n let returndata_size := mload(returndata)\\n revert(add(32, returndata), returndata_size)\\n }\\n } else {\\n revert(errorMessage);\\n }\\n }\\n }\\n}\\n\",\"keccak256\":\"0xd6153ce99bcdcce22b124f755e72553295be6abcd63804cfdffceb188b8bef10\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/StorageSlot.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.7.0) (utils/StorageSlot.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Library for reading and writing primitive types to specific storage slots.\\n *\\n * Storage slots are often used to avoid storage conflict when dealing with upgradeable contracts.\\n * This library helps with reading and writing to such slots without the need for inline assembly.\\n *\\n * The functions in this library return Slot structs that contain a `value` member that can be used to read or write.\\n *\\n * Example usage to set ERC1967 implementation slot:\\n * ```\\n * contract ERC1967 {\\n * bytes32 internal constant _IMPLEMENTATION_SLOT = 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc;\\n *\\n * function _getImplementation() internal view returns (address) {\\n * return StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value;\\n * }\\n *\\n * function _setImplementation(address newImplementation) internal {\\n * require(Address.isContract(newImplementation), \\\"ERC1967: new implementation is not a contract\\\");\\n * StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value = newImplementation;\\n * }\\n * }\\n * ```\\n *\\n * _Available since v4.1 for `address`, `bool`, `bytes32`, and `uint256`._\\n */\\nlibrary StorageSlot {\\n struct AddressSlot {\\n address value;\\n }\\n\\n struct BooleanSlot {\\n bool value;\\n }\\n\\n struct Bytes32Slot {\\n bytes32 value;\\n }\\n\\n struct Uint256Slot {\\n uint256 value;\\n }\\n\\n /**\\n * @dev Returns an `AddressSlot` with member `value` located at `slot`.\\n */\\n function getAddressSlot(bytes32 slot) internal pure returns (AddressSlot storage r) {\\n /// @solidity memory-safe-assembly\\n assembly {\\n r.slot := slot\\n }\\n }\\n\\n /**\\n * @dev Returns an `BooleanSlot` with member `value` located at `slot`.\\n */\\n function getBooleanSlot(bytes32 slot) internal pure returns (BooleanSlot storage r) {\\n /// @solidity memory-safe-assembly\\n assembly {\\n r.slot := slot\\n }\\n }\\n\\n /**\\n * @dev Returns an `Bytes32Slot` with member `value` located at `slot`.\\n */\\n function getBytes32Slot(bytes32 slot) internal pure returns (Bytes32Slot storage r) {\\n /// @solidity memory-safe-assembly\\n assembly {\\n r.slot := slot\\n }\\n }\\n\\n /**\\n * @dev Returns an `Uint256Slot` with member `value` located at `slot`.\\n */\\n function getUint256Slot(bytes32 slot) internal pure returns (Uint256Slot storage r) {\\n /// @solidity memory-safe-assembly\\n assembly {\\n r.slot := slot\\n }\\n }\\n}\\n\",\"keccak256\":\"0xd5c50c54bf02740ebd122ff06832546cb5fa84486d52695a9ccfd11666e0c81d\",\"license\":\"MIT\"},\"contracts/external/TransparentUpgradeableProxy.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-3.0\\n\\npragma solidity ^0.8.12;\\n\\nimport \\\"@openzeppelin/contracts/proxy/ERC1967/ERC1967Proxy.sol\\\";\\n\\n/**\\n * @dev This contract implements a proxy that is upgradeable by an admin. It is fully forked from OpenZeppelin\\n * `TransparentUpgradeableProxy`\\n *\\n * To avoid https://medium.com/nomic-labs-blog/malicious-backdoors-in-ethereum-proxies-62629adf3357[proxy selector\\n * clashing], which can potentially be used in an attack, this contract uses the\\n * https://blog.openzeppelin.com/the-transparent-proxy-pattern/[transparent proxy pattern]. This pattern implies two\\n * things that go hand in hand:\\n *\\n * 1. If any account other than the admin calls the proxy, the call will be forwarded to the implementation, even if\\n * that call matches one of the admin functions exposed by the proxy itself.\\n * 2. If the admin calls the proxy, it can access the admin functions, but its calls will never be forwarded to the\\n * implementation. If the admin tries to call a function on the implementation it will fail with an error that says\\n * \\\"admin cannot fallback to proxy target\\\".\\n *\\n * These properties mean that the admin account can only be used for admin actions like upgrading the proxy or changing\\n * the admin, so it's best if it's a dedicated account that is not used for anything else. This will avoid headaches due\\n * to sudden errors when trying to call a function from the proxy implementation.\\n *\\n * Our recommendation is for the dedicated account to be an instance of the {ProxyAdmin} contract. If set up this way,\\n * you should think of the `ProxyAdmin` instance as the real administrative interface of your proxy.\\n */\\ncontract TransparentUpgradeableProxy is ERC1967Proxy {\\n /**\\n * @dev Initializes an upgradeable proxy managed by `_admin`, backed by the implementation at `_logic`, and\\n * optionally initialized with `_data` as explained in {ERC1967Proxy-constructor}.\\n */\\n constructor(address _logic, address admin_, bytes memory _data) payable ERC1967Proxy(_logic, _data) {\\n assert(_ADMIN_SLOT == bytes32(uint256(keccak256(\\\"eip1967.proxy.admin\\\")) - 1));\\n _changeAdmin(admin_);\\n }\\n\\n /**\\n * @dev Modifier used internally that will delegate the call to the implementation unless the sender is the admin.\\n */\\n modifier ifAdmin() {\\n if (msg.sender == _getAdmin()) {\\n _;\\n } else {\\n _fallback();\\n }\\n }\\n\\n /**\\n * @dev Returns the current admin.\\n *\\n * NOTE: Only the admin can call this function. See {ProxyAdmin-getProxyAdmin}.\\n *\\n * TIP: To get this value clients can read directly from the storage slot shown below (specified by EIP1967) using the\\n * https://eth.wiki/json-rpc/API#eth_getstorageat[`eth_getStorageAt`] RPC call.\\n * `0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103`\\n */\\n function admin() external ifAdmin returns (address admin_) {\\n admin_ = _getAdmin();\\n }\\n\\n /**\\n * @dev Returns the current implementation.\\n *\\n * NOTE: Only the admin can call this function. See {ProxyAdmin-getProxyImplementation}.\\n *\\n * TIP: To get this value clients can read directly from the storage slot shown below (specified by EIP1967) using the\\n * https://eth.wiki/json-rpc/API#eth_getstorageat[`eth_getStorageAt`] RPC call.\\n * `0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc`\\n */\\n function implementation() external ifAdmin returns (address implementation_) {\\n implementation_ = _implementation();\\n }\\n\\n /**\\n * @dev Changes the admin of the proxy.\\n *\\n * Emits an {AdminChanged} event.\\n *\\n * NOTE: Only the admin can call this function. See {ProxyAdmin-changeProxyAdmin}.\\n */\\n function changeAdmin(address newAdmin) external virtual ifAdmin {\\n _changeAdmin(newAdmin);\\n }\\n\\n /**\\n * @dev Upgrade the implementation of the proxy.\\n *\\n * NOTE: Only the admin can call this function. See {ProxyAdmin-upgrade}.\\n */\\n function upgradeTo(address newImplementation) external ifAdmin {\\n _upgradeToAndCall(newImplementation, bytes(\\\"\\\"), false);\\n }\\n\\n /**\\n * @dev Upgrade the implementation of the proxy, and then call a function from the new implementation as specified\\n * by `data`, which should be an encoded function call. This is useful to initialize new storage variables in the\\n * proxied contract.\\n *\\n * NOTE: Only the admin can call this function. See {ProxyAdmin-upgradeAndCall}.\\n */\\n function upgradeToAndCall(address newImplementation, bytes calldata data) external payable ifAdmin {\\n _upgradeToAndCall(newImplementation, data, true);\\n }\\n\\n /**\\n * @dev Returns the current admin.\\n */\\n function _admin() internal view virtual returns (address) {\\n return _getAdmin();\\n }\\n\\n /**\\n * @dev Makes sure the admin cannot access the fallback function. See {Proxy-_beforeFallback}.\\n */\\n function _beforeFallback() internal virtual override {\\n require(msg.sender != _getAdmin(), \\\"TransparentUpgradeableProxy: admin cannot fallback to proxy target\\\");\\n super._beforeFallback();\\n }\\n}\\n\",\"keccak256\":\"0x93a67a0f612ea3ff2a76315e138a6a88267270a1379d3cc7be52845fbbe611e2\",\"license\":\"GPL-3.0\"}},\"version\":1}", + "bytecode": "0x6080604052604051620010bb380380620010bb8339810160408190526200002691620004d8565b828162000036828260006200009a565b5062000066905060017fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6104620005b8565b6000805160206200107483398151915214620000865762000086620005da565b6200009182620000d7565b50505062000643565b620000a58362000132565b600082511180620000b35750805b15620000d257620000d083836200017460201b6200028c1760201c565b505b505050565b7f7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f62000102620001a5565b604080516001600160a01b03928316815291841660208301520160405180910390a16200012f81620001de565b50565b6200013d8162000293565b6040516001600160a01b038216907fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b90600090a250565b60606200019c8383604051806060016040528060278152602001620010946027913962000347565b90505b92915050565b6000620001cf6000805160206200107483398151915260001b6200042f60201b6200022e1760201c565b546001600160a01b0316919050565b6001600160a01b038116620002495760405162461bcd60e51b815260206004820152602660248201527f455243313936373a206e65772061646d696e20697320746865207a65726f206160448201526564647265737360d01b60648201526084015b60405180910390fd5b80620002726000805160206200107483398151915260001b6200042f60201b6200022e1760201c565b80546001600160a01b0319166001600160a01b039290921691909117905550565b620002a9816200043260201b620002b81760201c565b6200030d5760405162461bcd60e51b815260206004820152602d60248201527f455243313936373a206e657720696d706c656d656e746174696f6e206973206e60448201526c1bdd08184818dbdb9d1c9858dd609a1b606482015260840162000240565b80620002727f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc60001b6200042f60201b6200022e1760201c565b60606001600160a01b0384163b620003b15760405162461bcd60e51b815260206004820152602660248201527f416464726573733a2064656c65676174652063616c6c20746f206e6f6e2d636f6044820152651b9d1c9858dd60d21b606482015260840162000240565b600080856001600160a01b031685604051620003ce9190620005f0565b600060405180830381855af49150503d80600081146200040b576040519150601f19603f3d011682016040523d82523d6000602084013e62000410565b606091505b5090925090506200042382828662000441565b925050505b9392505050565b90565b6001600160a01b03163b151590565b606083156200045257508162000428565b825115620004635782518084602001fd5b8160405162461bcd60e51b81526004016200024091906200060e565b80516001600160a01b03811681146200049757600080fd5b919050565b634e487b7160e01b600052604160045260246000fd5b60005b83811015620004cf578181015183820152602001620004b5565b50506000910152565b600080600060608486031215620004ee57600080fd5b620004f9846200047f565b925062000509602085016200047f565b60408501519092506001600160401b03808211156200052757600080fd5b818601915086601f8301126200053c57600080fd5b8151818111156200055157620005516200049c565b604051601f8201601f19908116603f011681019083821181831017156200057c576200057c6200049c565b816040528281528960208487010111156200059657600080fd5b620005a9836020830160208801620004b2565b80955050505050509250925092565b818103818111156200019f57634e487b7160e01b600052601160045260246000fd5b634e487b7160e01b600052600160045260246000fd5b6000825162000604818460208701620004b2565b9190910192915050565b60208152600082518060208401526200062f816040850160208701620004b2565b601f01601f19169190910160400192915050565b610a2180620006536000396000f3fe60806040526004361061005e5760003560e01c80635c60da1b116100435780635c60da1b146100a85780638f283970146100e6578063f851a440146101065761006d565b80633659cfe6146100755780634f1ef286146100955761006d565b3661006d5761006b61011b565b005b61006b61011b565b34801561008157600080fd5b5061006b610090366004610895565b610135565b61006b6100a33660046108b0565b61017f565b3480156100b457600080fd5b506100bd6101f3565b60405173ffffffffffffffffffffffffffffffffffffffff909116815260200160405180910390f35b3480156100f257600080fd5b5061006b610101366004610895565b610231565b34801561011257600080fd5b506100bd61025e565b6101236102d4565b61013361012e6103ab565b6103b5565b565b61013d6103d9565b73ffffffffffffffffffffffffffffffffffffffff1633036101775761017481604051806020016040528060008152506000610419565b50565b61017461011b565b6101876103d9565b73ffffffffffffffffffffffffffffffffffffffff1633036101eb576101e68383838080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525060019250610419915050565b505050565b6101e661011b565b60006101fd6103d9565b73ffffffffffffffffffffffffffffffffffffffff163303610226576102216103ab565b905090565b61022e61011b565b90565b6102396103d9565b73ffffffffffffffffffffffffffffffffffffffff1633036101775761017481610444565b60006102686103d9565b73ffffffffffffffffffffffffffffffffffffffff163303610226576102216103d9565b60606102b183836040518060600160405280602781526020016109c5602791396104a5565b9392505050565b73ffffffffffffffffffffffffffffffffffffffff163b151590565b6102dc6103d9565b73ffffffffffffffffffffffffffffffffffffffff163303610133576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604260248201527f5472616e73706172656e745570677261646561626c6550726f78793a2061646d60448201527f696e2063616e6e6f742066616c6c6261636b20746f2070726f7879207461726760648201527f6574000000000000000000000000000000000000000000000000000000000000608482015260a4015b60405180910390fd5b60006102216105cd565b3660008037600080366000845af43d6000803e8080156103d4573d6000f35b3d6000fd5b60007fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035b5473ffffffffffffffffffffffffffffffffffffffff16919050565b610422836105f5565b60008251118061042f5750805b156101e65761043e838361028c565b50505050565b7f7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f61046d6103d9565b6040805173ffffffffffffffffffffffffffffffffffffffff928316815291841660208301520160405180910390a161017481610642565b606073ffffffffffffffffffffffffffffffffffffffff84163b61054b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f416464726573733a2064656c65676174652063616c6c20746f206e6f6e2d636f60448201527f6e7472616374000000000000000000000000000000000000000000000000000060648201526084016103a2565b6000808573ffffffffffffffffffffffffffffffffffffffff16856040516105739190610957565b600060405180830381855af49150503d80600081146105ae576040519150601f19603f3d011682016040523d82523d6000602084013e6105b3565b606091505b50915091506105c382828661074e565b9695505050505050565b60007f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc6103fd565b6105fe816107a1565b60405173ffffffffffffffffffffffffffffffffffffffff8216907fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b90600090a250565b73ffffffffffffffffffffffffffffffffffffffff81166106e5576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f455243313936373a206e65772061646d696e20697320746865207a65726f206160448201527f646472657373000000000000000000000000000000000000000000000000000060648201526084016103a2565b807fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035b80547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff9290921691909117905550565b6060831561075d5750816102b1565b82511561076d5782518084602001fd5b816040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016103a29190610973565b73ffffffffffffffffffffffffffffffffffffffff81163b610845576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602d60248201527f455243313936373a206e657720696d706c656d656e746174696f6e206973206e60448201527f6f74206120636f6e74726163740000000000000000000000000000000000000060648201526084016103a2565b807f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc610708565b803573ffffffffffffffffffffffffffffffffffffffff8116811461089057600080fd5b919050565b6000602082840312156108a757600080fd5b6102b18261086c565b6000806000604084860312156108c557600080fd5b6108ce8461086c565b9250602084013567ffffffffffffffff808211156108eb57600080fd5b818601915086601f8301126108ff57600080fd5b81358181111561090e57600080fd5b87602082850101111561092057600080fd5b6020830194508093505050509250925092565b60005b8381101561094e578181015183820152602001610936565b50506000910152565b60008251610969818460208701610933565b9190910192915050565b6020815260008251806020840152610992816040850160208701610933565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016919091016040019291505056fe416464726573733a206c6f772d6c6576656c2064656c65676174652063616c6c206661696c6564a2646970667358221220e96638b07fb1675d93a95c49e417bc8111448b23a59918698cdcd8fd488dd7cf64736f6c63430008110033b53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103416464726573733a206c6f772d6c6576656c2064656c65676174652063616c6c206661696c6564", + "deployedBytecode": "0x60806040526004361061005e5760003560e01c80635c60da1b116100435780635c60da1b146100a85780638f283970146100e6578063f851a440146101065761006d565b80633659cfe6146100755780634f1ef286146100955761006d565b3661006d5761006b61011b565b005b61006b61011b565b34801561008157600080fd5b5061006b610090366004610895565b610135565b61006b6100a33660046108b0565b61017f565b3480156100b457600080fd5b506100bd6101f3565b60405173ffffffffffffffffffffffffffffffffffffffff909116815260200160405180910390f35b3480156100f257600080fd5b5061006b610101366004610895565b610231565b34801561011257600080fd5b506100bd61025e565b6101236102d4565b61013361012e6103ab565b6103b5565b565b61013d6103d9565b73ffffffffffffffffffffffffffffffffffffffff1633036101775761017481604051806020016040528060008152506000610419565b50565b61017461011b565b6101876103d9565b73ffffffffffffffffffffffffffffffffffffffff1633036101eb576101e68383838080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525060019250610419915050565b505050565b6101e661011b565b60006101fd6103d9565b73ffffffffffffffffffffffffffffffffffffffff163303610226576102216103ab565b905090565b61022e61011b565b90565b6102396103d9565b73ffffffffffffffffffffffffffffffffffffffff1633036101775761017481610444565b60006102686103d9565b73ffffffffffffffffffffffffffffffffffffffff163303610226576102216103d9565b60606102b183836040518060600160405280602781526020016109c5602791396104a5565b9392505050565b73ffffffffffffffffffffffffffffffffffffffff163b151590565b6102dc6103d9565b73ffffffffffffffffffffffffffffffffffffffff163303610133576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604260248201527f5472616e73706172656e745570677261646561626c6550726f78793a2061646d60448201527f696e2063616e6e6f742066616c6c6261636b20746f2070726f7879207461726760648201527f6574000000000000000000000000000000000000000000000000000000000000608482015260a4015b60405180910390fd5b60006102216105cd565b3660008037600080366000845af43d6000803e8080156103d4573d6000f35b3d6000fd5b60007fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035b5473ffffffffffffffffffffffffffffffffffffffff16919050565b610422836105f5565b60008251118061042f5750805b156101e65761043e838361028c565b50505050565b7f7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f61046d6103d9565b6040805173ffffffffffffffffffffffffffffffffffffffff928316815291841660208301520160405180910390a161017481610642565b606073ffffffffffffffffffffffffffffffffffffffff84163b61054b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f416464726573733a2064656c65676174652063616c6c20746f206e6f6e2d636f60448201527f6e7472616374000000000000000000000000000000000000000000000000000060648201526084016103a2565b6000808573ffffffffffffffffffffffffffffffffffffffff16856040516105739190610957565b600060405180830381855af49150503d80600081146105ae576040519150601f19603f3d011682016040523d82523d6000602084013e6105b3565b606091505b50915091506105c382828661074e565b9695505050505050565b60007f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc6103fd565b6105fe816107a1565b60405173ffffffffffffffffffffffffffffffffffffffff8216907fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b90600090a250565b73ffffffffffffffffffffffffffffffffffffffff81166106e5576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f455243313936373a206e65772061646d696e20697320746865207a65726f206160448201527f646472657373000000000000000000000000000000000000000000000000000060648201526084016103a2565b807fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035b80547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff9290921691909117905550565b6060831561075d5750816102b1565b82511561076d5782518084602001fd5b816040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016103a29190610973565b73ffffffffffffffffffffffffffffffffffffffff81163b610845576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602d60248201527f455243313936373a206e657720696d706c656d656e746174696f6e206973206e60448201527f6f74206120636f6e74726163740000000000000000000000000000000000000060648201526084016103a2565b807f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc610708565b803573ffffffffffffffffffffffffffffffffffffffff8116811461089057600080fd5b919050565b6000602082840312156108a757600080fd5b6102b18261086c565b6000806000604084860312156108c557600080fd5b6108ce8461086c565b9250602084013567ffffffffffffffff808211156108eb57600080fd5b818601915086601f8301126108ff57600080fd5b81358181111561090e57600080fd5b87602082850101111561092057600080fd5b6020830194508093505050509250925092565b60005b8381101561094e578181015183820152602001610936565b50506000910152565b60008251610969818460208701610933565b9190910192915050565b6020815260008251806020840152610992816040850160208701610933565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016919091016040019291505056fe416464726573733a206c6f772d6c6576656c2064656c65676174652063616c6c206661696c6564a2646970667358221220e96638b07fb1675d93a95c49e417bc8111448b23a59918698cdcd8fd488dd7cf64736f6c63430008110033", + "devdoc": { + "details": "This contract implements a proxy that is upgradeable by an admin. It is fully forked from OpenZeppelin `TransparentUpgradeableProxy` To avoid https://medium.com/nomic-labs-blog/malicious-backdoors-in-ethereum-proxies-62629adf3357[proxy selector clashing], which can potentially be used in an attack, this contract uses the https://blog.openzeppelin.com/the-transparent-proxy-pattern/[transparent proxy pattern]. This pattern implies two things that go hand in hand: 1. If any account other than the admin calls the proxy, the call will be forwarded to the implementation, even if that call matches one of the admin functions exposed by the proxy itself. 2. If the admin calls the proxy, it can access the admin functions, but its calls will never be forwarded to the implementation. If the admin tries to call a function on the implementation it will fail with an error that says \"admin cannot fallback to proxy target\". These properties mean that the admin account can only be used for admin actions like upgrading the proxy or changing the admin, so it's best if it's a dedicated account that is not used for anything else. This will avoid headaches due to sudden errors when trying to call a function from the proxy implementation. Our recommendation is for the dedicated account to be an instance of the {ProxyAdmin} contract. If set up this way, you should think of the `ProxyAdmin` instance as the real administrative interface of your proxy.", + "kind": "dev", + "methods": { + "admin()": { + "details": "Returns the current admin. NOTE: Only the admin can call this function. See {ProxyAdmin-getProxyAdmin}. TIP: To get this value clients can read directly from the storage slot shown below (specified by EIP1967) using the https://eth.wiki/json-rpc/API#eth_getstorageat[`eth_getStorageAt`] RPC call. `0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103`" + }, + "changeAdmin(address)": { + "details": "Changes the admin of the proxy. Emits an {AdminChanged} event. NOTE: Only the admin can call this function. See {ProxyAdmin-changeProxyAdmin}." + }, + "constructor": { + "details": "Initializes an upgradeable proxy managed by `_admin`, backed by the implementation at `_logic`, and optionally initialized with `_data` as explained in {ERC1967Proxy-constructor}." + }, + "implementation()": { + "details": "Returns the current implementation. NOTE: Only the admin can call this function. See {ProxyAdmin-getProxyImplementation}. TIP: To get this value clients can read directly from the storage slot shown below (specified by EIP1967) using the https://eth.wiki/json-rpc/API#eth_getstorageat[`eth_getStorageAt`] RPC call. `0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc`" + }, + "upgradeTo(address)": { + "details": "Upgrade the implementation of the proxy. NOTE: Only the admin can call this function. See {ProxyAdmin-upgrade}." + }, + "upgradeToAndCall(address,bytes)": { + "details": "Upgrade the implementation of the proxy, and then call a function from the new implementation as specified by `data`, which should be an encoded function call. This is useful to initialize new storage variables in the proxied contract. NOTE: Only the admin can call this function. See {ProxyAdmin-upgradeAndCall}." + } + }, + "version": 1 + }, + "userdoc": { + "kind": "user", + "methods": {}, + "version": 1 + }, + "storageLayout": { + "storage": [], + "types": null + } +} \ No newline at end of file diff --git a/deployments/celo/LayerZeroBridge_USD.json b/deployments/celo/LayerZeroBridge_USD.json new file mode 100644 index 00000000..bafb051c --- /dev/null +++ b/deployments/celo/LayerZeroBridge_USD.json @@ -0,0 +1,275 @@ +{ + "address": "0xdD6A0A00fE3353e813F3B3864694D55D2a7cE11C", + "abi": [ + { + "inputs": [ + { + "internalType": "address", + "name": "_logic", + "type": "address" + }, + { + "internalType": "address", + "name": "admin_", + "type": "address" + }, + { + "internalType": "bytes", + "name": "_data", + "type": "bytes" + } + ], + "stateMutability": "payable", + "type": "constructor" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "previousAdmin", + "type": "address" + }, + { + "indexed": false, + "internalType": "address", + "name": "newAdmin", + "type": "address" + } + ], + "name": "AdminChanged", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "beacon", + "type": "address" + } + ], + "name": "BeaconUpgraded", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "implementation", + "type": "address" + } + ], + "name": "Upgraded", + "type": "event" + }, + { + "stateMutability": "payable", + "type": "fallback" + }, + { + "inputs": [], + "name": "admin", + "outputs": [ + { + "internalType": "address", + "name": "admin_", + "type": "address" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "newAdmin", + "type": "address" + } + ], + "name": "changeAdmin", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "implementation", + "outputs": [ + { + "internalType": "address", + "name": "implementation_", + "type": "address" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "newImplementation", + "type": "address" + } + ], + "name": "upgradeTo", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "newImplementation", + "type": "address" + }, + { + "internalType": "bytes", + "name": "data", + "type": "bytes" + } + ], + "name": "upgradeToAndCall", + "outputs": [], + "stateMutability": "payable", + "type": "function" + }, + { + "stateMutability": "payable", + "type": "receive" + } + ], + "transactionHash": "0x6cc01b731498c4d093b79a0d104f237ab0326886d117c73db4549bb71372c7ca", + "receipt": { + "to": null, + "from": "0xfdA462548Ce04282f4B6D6619823a7C64Fdc0185", + "contractAddress": "0xdD6A0A00fE3353e813F3B3864694D55D2a7cE11C", + "transactionIndex": 8, + "gasUsed": "849932", + "logsBloom": "0x00000000000000000000000000000000400000000000000000000000000000000000000008000000000000000008000000000000000000000000000000200000000004000000000000000008000002000000000000000000000000000500000000000000020000000000000000000800000000800000000000000010000000000000000010000000000000000000000000000000000080000000000000800000020080000000000000001000000400000000000000000000000000000000000000000022000200000000000000040000000000020400000000000000000020000010008000000000000000000000000000000000000008000000000000000000", + "blockHash": "0x0925f71f5c3571c22af5c47a30c91343dfeadba2e22b39909d33d8d1ad682875", + "transactionHash": "0x6cc01b731498c4d093b79a0d104f237ab0326886d117c73db4549bb71372c7ca", + "logs": [ + { + "transactionIndex": 8, + "blockNumber": 23443582, + "transactionHash": "0x6cc01b731498c4d093b79a0d104f237ab0326886d117c73db4549bb71372c7ca", + "address": "0xdD6A0A00fE3353e813F3B3864694D55D2a7cE11C", + "topics": [ + "0xbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b", + "0x0000000000000000000000006cd24ac05103c2c911347a6d3628d64a9f07eaf5" + ], + "data": "0x", + "logIndex": 13, + "blockHash": "0x0925f71f5c3571c22af5c47a30c91343dfeadba2e22b39909d33d8d1ad682875" + }, + { + "transactionIndex": 8, + "blockNumber": 23443582, + "transactionHash": "0x6cc01b731498c4d093b79a0d104f237ab0326886d117c73db4549bb71372c7ca", + "address": "0xdD6A0A00fE3353e813F3B3864694D55D2a7cE11C", + "topics": [ + "0x8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925", + "0x000000000000000000000000dd6a0a00fe3353e813f3b3864694d55d2a7ce11c", + "0x0000000000000000000000000000206329b97db379d5e1bf586bbdb969c63274" + ], + "data": "0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", + "logIndex": 14, + "blockHash": "0x0925f71f5c3571c22af5c47a30c91343dfeadba2e22b39909d33d8d1ad682875" + }, + { + "transactionIndex": 8, + "blockNumber": 23443582, + "transactionHash": "0x6cc01b731498c4d093b79a0d104f237ab0326886d117c73db4549bb71372c7ca", + "address": "0xdD6A0A00fE3353e813F3B3864694D55D2a7cE11C", + "topics": [ + "0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000206329b97db379d5e1bf586bbdb969c63274" + ], + "data": "0x0000000000000000000000000000000000000000000000000000000000000000", + "logIndex": 15, + "blockHash": "0x0925f71f5c3571c22af5c47a30c91343dfeadba2e22b39909d33d8d1ad682875" + }, + { + "transactionIndex": 8, + "blockNumber": 23443582, + "transactionHash": "0x6cc01b731498c4d093b79a0d104f237ab0326886d117c73db4549bb71372c7ca", + "address": "0xdD6A0A00fE3353e813F3B3864694D55D2a7cE11C", + "topics": [ + "0x7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb3847402498" + ], + "data": "0x0000000000000000000000000000000000000000000000000000000000000001", + "logIndex": 16, + "blockHash": "0x0925f71f5c3571c22af5c47a30c91343dfeadba2e22b39909d33d8d1ad682875" + }, + { + "transactionIndex": 8, + "blockNumber": 23443582, + "transactionHash": "0x6cc01b731498c4d093b79a0d104f237ab0326886d117c73db4549bb71372c7ca", + "address": "0xdD6A0A00fE3353e813F3B3864694D55D2a7cE11C", + "topics": [ + "0x7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f" + ], + "data": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000005183f032bf42109cd370b9559fd22207e432301e", + "logIndex": 17, + "blockHash": "0x0925f71f5c3571c22af5c47a30c91343dfeadba2e22b39909d33d8d1ad682875" + } + ], + "blockNumber": 23443582, + "cumulativeGasUsed": "1635349", + "status": 1, + "byzantium": true + }, + "args": [ + "0x6cd24ac05103C2C911347a6D3628d64a9F07eAf5", + "0x5183f032bf42109cD370B9559FD22207e432301E", + "0xc9aba0aa00000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000000e00000000000000000000000003a73033c0b1407574c76bdbac67f126f6b4a9aa9000000000000000000000000029f049c59a6b56610a34ba01d0d28e26ed407a8000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000164c617965725a65726f204272696467652061675553440000000000000000000000000000000000000000000000000000000000000000000000000000000000084c5a2d6167555344000000000000000000000000000000000000000000000000" + ], + "numDeployments": 1, + "solcInputHash": "871924e0c138825a2736b76def8fef8d", + "metadata": "{\"compiler\":{\"version\":\"0.8.17+commit.8df45f5f\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_logic\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"admin_\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"_data\",\"type\":\"bytes\"}],\"stateMutability\":\"payable\",\"type\":\"constructor\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"previousAdmin\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"newAdmin\",\"type\":\"address\"}],\"name\":\"AdminChanged\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"beacon\",\"type\":\"address\"}],\"name\":\"BeaconUpgraded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"implementation\",\"type\":\"address\"}],\"name\":\"Upgraded\",\"type\":\"event\"},{\"stateMutability\":\"payable\",\"type\":\"fallback\"},{\"inputs\":[],\"name\":\"admin\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"admin_\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newAdmin\",\"type\":\"address\"}],\"name\":\"changeAdmin\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"implementation\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"implementation_\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newImplementation\",\"type\":\"address\"}],\"name\":\"upgradeTo\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newImplementation\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"}],\"name\":\"upgradeToAndCall\",\"outputs\":[],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"stateMutability\":\"payable\",\"type\":\"receive\"}],\"devdoc\":{\"details\":\"This contract implements a proxy that is upgradeable by an admin. It is fully forked from OpenZeppelin `TransparentUpgradeableProxy` To avoid https://medium.com/nomic-labs-blog/malicious-backdoors-in-ethereum-proxies-62629adf3357[proxy selector clashing], which can potentially be used in an attack, this contract uses the https://blog.openzeppelin.com/the-transparent-proxy-pattern/[transparent proxy pattern]. This pattern implies two things that go hand in hand: 1. If any account other than the admin calls the proxy, the call will be forwarded to the implementation, even if that call matches one of the admin functions exposed by the proxy itself. 2. If the admin calls the proxy, it can access the admin functions, but its calls will never be forwarded to the implementation. If the admin tries to call a function on the implementation it will fail with an error that says \\\"admin cannot fallback to proxy target\\\". These properties mean that the admin account can only be used for admin actions like upgrading the proxy or changing the admin, so it's best if it's a dedicated account that is not used for anything else. This will avoid headaches due to sudden errors when trying to call a function from the proxy implementation. Our recommendation is for the dedicated account to be an instance of the {ProxyAdmin} contract. If set up this way, you should think of the `ProxyAdmin` instance as the real administrative interface of your proxy.\",\"kind\":\"dev\",\"methods\":{\"admin()\":{\"details\":\"Returns the current admin. NOTE: Only the admin can call this function. See {ProxyAdmin-getProxyAdmin}. TIP: To get this value clients can read directly from the storage slot shown below (specified by EIP1967) using the https://eth.wiki/json-rpc/API#eth_getstorageat[`eth_getStorageAt`] RPC call. `0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103`\"},\"changeAdmin(address)\":{\"details\":\"Changes the admin of the proxy. Emits an {AdminChanged} event. NOTE: Only the admin can call this function. See {ProxyAdmin-changeProxyAdmin}.\"},\"constructor\":{\"details\":\"Initializes an upgradeable proxy managed by `_admin`, backed by the implementation at `_logic`, and optionally initialized with `_data` as explained in {ERC1967Proxy-constructor}.\"},\"implementation()\":{\"details\":\"Returns the current implementation. NOTE: Only the admin can call this function. See {ProxyAdmin-getProxyImplementation}. TIP: To get this value clients can read directly from the storage slot shown below (specified by EIP1967) using the https://eth.wiki/json-rpc/API#eth_getstorageat[`eth_getStorageAt`] RPC call. `0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc`\"},\"upgradeTo(address)\":{\"details\":\"Upgrade the implementation of the proxy. NOTE: Only the admin can call this function. See {ProxyAdmin-upgrade}.\"},\"upgradeToAndCall(address,bytes)\":{\"details\":\"Upgrade the implementation of the proxy, and then call a function from the new implementation as specified by `data`, which should be an encoded function call. This is useful to initialize new storage variables in the proxied contract. NOTE: Only the admin can call this function. See {ProxyAdmin-upgradeAndCall}.\"}},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/external/TransparentUpgradeableProxy.sol\":\"TransparentUpgradeableProxy\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":1000000},\"remappings\":[]},\"sources\":{\"@openzeppelin/contracts/interfaces/draft-IERC1822.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.5.0) (interfaces/draft-IERC1822.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev ERC1822: Universal Upgradeable Proxy Standard (UUPS) documents a method for upgradeability through a simplified\\n * proxy whose upgrades are fully controlled by the current implementation.\\n */\\ninterface IERC1822Proxiable {\\n /**\\n * @dev Returns the storage slot that the proxiable contract assumes is being used to store the implementation\\n * address.\\n *\\n * IMPORTANT: A proxy pointing at a proxiable contract should not be considered proxiable itself, because this risks\\n * bricking a proxy that upgrades to it, by delegating to itself until out of gas. Thus it is critical that this\\n * function revert if invoked through a proxy.\\n */\\n function proxiableUUID() external view returns (bytes32);\\n}\\n\",\"keccak256\":\"0x1d4afe6cb24200cc4545eed814ecf5847277dfe5d613a1707aad5fceecebcfff\",\"license\":\"MIT\"},\"@openzeppelin/contracts/proxy/ERC1967/ERC1967Proxy.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.7.0) (proxy/ERC1967/ERC1967Proxy.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../Proxy.sol\\\";\\nimport \\\"./ERC1967Upgrade.sol\\\";\\n\\n/**\\n * @dev This contract implements an upgradeable proxy. It is upgradeable because calls are delegated to an\\n * implementation address that can be changed. This address is stored in storage in the location specified by\\n * https://eips.ethereum.org/EIPS/eip-1967[EIP1967], so that it doesn't conflict with the storage layout of the\\n * implementation behind the proxy.\\n */\\ncontract ERC1967Proxy is Proxy, ERC1967Upgrade {\\n /**\\n * @dev Initializes the upgradeable proxy with an initial implementation specified by `_logic`.\\n *\\n * If `_data` is nonempty, it's used as data in a delegate call to `_logic`. This will typically be an encoded\\n * function call, and allows initializing the storage of the proxy like a Solidity constructor.\\n */\\n constructor(address _logic, bytes memory _data) payable {\\n _upgradeToAndCall(_logic, _data, false);\\n }\\n\\n /**\\n * @dev Returns the current implementation address.\\n */\\n function _implementation() internal view virtual override returns (address impl) {\\n return ERC1967Upgrade._getImplementation();\\n }\\n}\\n\",\"keccak256\":\"0xa2b22da3032e50b55f95ec1d13336102d675f341167aa76db571ef7f8bb7975d\",\"license\":\"MIT\"},\"@openzeppelin/contracts/proxy/ERC1967/ERC1967Upgrade.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.5.0) (proxy/ERC1967/ERC1967Upgrade.sol)\\n\\npragma solidity ^0.8.2;\\n\\nimport \\\"../beacon/IBeacon.sol\\\";\\nimport \\\"../../interfaces/draft-IERC1822.sol\\\";\\nimport \\\"../../utils/Address.sol\\\";\\nimport \\\"../../utils/StorageSlot.sol\\\";\\n\\n/**\\n * @dev This abstract contract provides getters and event emitting update functions for\\n * https://eips.ethereum.org/EIPS/eip-1967[EIP1967] slots.\\n *\\n * _Available since v4.1._\\n *\\n * @custom:oz-upgrades-unsafe-allow delegatecall\\n */\\nabstract contract ERC1967Upgrade {\\n // This is the keccak-256 hash of \\\"eip1967.proxy.rollback\\\" subtracted by 1\\n bytes32 private constant _ROLLBACK_SLOT = 0x4910fdfa16fed3260ed0e7147f7cc6da11a60208b5b9406d12a635614ffd9143;\\n\\n /**\\n * @dev Storage slot with the address of the current implementation.\\n * This is the keccak-256 hash of \\\"eip1967.proxy.implementation\\\" subtracted by 1, and is\\n * validated in the constructor.\\n */\\n bytes32 internal constant _IMPLEMENTATION_SLOT = 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc;\\n\\n /**\\n * @dev Emitted when the implementation is upgraded.\\n */\\n event Upgraded(address indexed implementation);\\n\\n /**\\n * @dev Returns the current implementation address.\\n */\\n function _getImplementation() internal view returns (address) {\\n return StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value;\\n }\\n\\n /**\\n * @dev Stores a new address in the EIP1967 implementation slot.\\n */\\n function _setImplementation(address newImplementation) private {\\n require(Address.isContract(newImplementation), \\\"ERC1967: new implementation is not a contract\\\");\\n StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value = newImplementation;\\n }\\n\\n /**\\n * @dev Perform implementation upgrade\\n *\\n * Emits an {Upgraded} event.\\n */\\n function _upgradeTo(address newImplementation) internal {\\n _setImplementation(newImplementation);\\n emit Upgraded(newImplementation);\\n }\\n\\n /**\\n * @dev Perform implementation upgrade with additional setup call.\\n *\\n * Emits an {Upgraded} event.\\n */\\n function _upgradeToAndCall(\\n address newImplementation,\\n bytes memory data,\\n bool forceCall\\n ) internal {\\n _upgradeTo(newImplementation);\\n if (data.length > 0 || forceCall) {\\n Address.functionDelegateCall(newImplementation, data);\\n }\\n }\\n\\n /**\\n * @dev Perform implementation upgrade with security checks for UUPS proxies, and additional setup call.\\n *\\n * Emits an {Upgraded} event.\\n */\\n function _upgradeToAndCallUUPS(\\n address newImplementation,\\n bytes memory data,\\n bool forceCall\\n ) internal {\\n // Upgrades from old implementations will perform a rollback test. This test requires the new\\n // implementation to upgrade back to the old, non-ERC1822 compliant, implementation. Removing\\n // this special case will break upgrade paths from old UUPS implementation to new ones.\\n if (StorageSlot.getBooleanSlot(_ROLLBACK_SLOT).value) {\\n _setImplementation(newImplementation);\\n } else {\\n try IERC1822Proxiable(newImplementation).proxiableUUID() returns (bytes32 slot) {\\n require(slot == _IMPLEMENTATION_SLOT, \\\"ERC1967Upgrade: unsupported proxiableUUID\\\");\\n } catch {\\n revert(\\\"ERC1967Upgrade: new implementation is not UUPS\\\");\\n }\\n _upgradeToAndCall(newImplementation, data, forceCall);\\n }\\n }\\n\\n /**\\n * @dev Storage slot with the admin of the contract.\\n * This is the keccak-256 hash of \\\"eip1967.proxy.admin\\\" subtracted by 1, and is\\n * validated in the constructor.\\n */\\n bytes32 internal constant _ADMIN_SLOT = 0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103;\\n\\n /**\\n * @dev Emitted when the admin account has changed.\\n */\\n event AdminChanged(address previousAdmin, address newAdmin);\\n\\n /**\\n * @dev Returns the current admin.\\n */\\n function _getAdmin() internal view returns (address) {\\n return StorageSlot.getAddressSlot(_ADMIN_SLOT).value;\\n }\\n\\n /**\\n * @dev Stores a new address in the EIP1967 admin slot.\\n */\\n function _setAdmin(address newAdmin) private {\\n require(newAdmin != address(0), \\\"ERC1967: new admin is the zero address\\\");\\n StorageSlot.getAddressSlot(_ADMIN_SLOT).value = newAdmin;\\n }\\n\\n /**\\n * @dev Changes the admin of the proxy.\\n *\\n * Emits an {AdminChanged} event.\\n */\\n function _changeAdmin(address newAdmin) internal {\\n emit AdminChanged(_getAdmin(), newAdmin);\\n _setAdmin(newAdmin);\\n }\\n\\n /**\\n * @dev The storage slot of the UpgradeableBeacon contract which defines the implementation for this proxy.\\n * This is bytes32(uint256(keccak256('eip1967.proxy.beacon')) - 1)) and is validated in the constructor.\\n */\\n bytes32 internal constant _BEACON_SLOT = 0xa3f0ad74e5423aebfd80d3ef4346578335a9a72aeaee59ff6cb3582b35133d50;\\n\\n /**\\n * @dev Emitted when the beacon is upgraded.\\n */\\n event BeaconUpgraded(address indexed beacon);\\n\\n /**\\n * @dev Returns the current beacon.\\n */\\n function _getBeacon() internal view returns (address) {\\n return StorageSlot.getAddressSlot(_BEACON_SLOT).value;\\n }\\n\\n /**\\n * @dev Stores a new beacon in the EIP1967 beacon slot.\\n */\\n function _setBeacon(address newBeacon) private {\\n require(Address.isContract(newBeacon), \\\"ERC1967: new beacon is not a contract\\\");\\n require(\\n Address.isContract(IBeacon(newBeacon).implementation()),\\n \\\"ERC1967: beacon implementation is not a contract\\\"\\n );\\n StorageSlot.getAddressSlot(_BEACON_SLOT).value = newBeacon;\\n }\\n\\n /**\\n * @dev Perform beacon upgrade with additional setup call. Note: This upgrades the address of the beacon, it does\\n * not upgrade the implementation contained in the beacon (see {UpgradeableBeacon-_setImplementation} for that).\\n *\\n * Emits a {BeaconUpgraded} event.\\n */\\n function _upgradeBeaconToAndCall(\\n address newBeacon,\\n bytes memory data,\\n bool forceCall\\n ) internal {\\n _setBeacon(newBeacon);\\n emit BeaconUpgraded(newBeacon);\\n if (data.length > 0 || forceCall) {\\n Address.functionDelegateCall(IBeacon(newBeacon).implementation(), data);\\n }\\n }\\n}\\n\",\"keccak256\":\"0xabf3f59bc0e5423eae45e459dbe92e7052c6983628d39008590edc852a62f94a\",\"license\":\"MIT\"},\"@openzeppelin/contracts/proxy/Proxy.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.6.0) (proxy/Proxy.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev This abstract contract provides a fallback function that delegates all calls to another contract using the EVM\\n * instruction `delegatecall`. We refer to the second contract as the _implementation_ behind the proxy, and it has to\\n * be specified by overriding the virtual {_implementation} function.\\n *\\n * Additionally, delegation to the implementation can be triggered manually through the {_fallback} function, or to a\\n * different contract through the {_delegate} function.\\n *\\n * The success and return data of the delegated call will be returned back to the caller of the proxy.\\n */\\nabstract contract Proxy {\\n /**\\n * @dev Delegates the current call to `implementation`.\\n *\\n * This function does not return to its internal call site, it will return directly to the external caller.\\n */\\n function _delegate(address implementation) internal virtual {\\n assembly {\\n // Copy msg.data. We take full control of memory in this inline assembly\\n // block because it will not return to Solidity code. We overwrite the\\n // Solidity scratch pad at memory position 0.\\n calldatacopy(0, 0, calldatasize())\\n\\n // Call the implementation.\\n // out and outsize are 0 because we don't know the size yet.\\n let result := delegatecall(gas(), implementation, 0, calldatasize(), 0, 0)\\n\\n // Copy the returned data.\\n returndatacopy(0, 0, returndatasize())\\n\\n switch result\\n // delegatecall returns 0 on error.\\n case 0 {\\n revert(0, returndatasize())\\n }\\n default {\\n return(0, returndatasize())\\n }\\n }\\n }\\n\\n /**\\n * @dev This is a virtual function that should be overridden so it returns the address to which the fallback function\\n * and {_fallback} should delegate.\\n */\\n function _implementation() internal view virtual returns (address);\\n\\n /**\\n * @dev Delegates the current call to the address returned by `_implementation()`.\\n *\\n * This function does not return to its internal call site, it will return directly to the external caller.\\n */\\n function _fallback() internal virtual {\\n _beforeFallback();\\n _delegate(_implementation());\\n }\\n\\n /**\\n * @dev Fallback function that delegates calls to the address returned by `_implementation()`. Will run if no other\\n * function in the contract matches the call data.\\n */\\n fallback() external payable virtual {\\n _fallback();\\n }\\n\\n /**\\n * @dev Fallback function that delegates calls to the address returned by `_implementation()`. Will run if call data\\n * is empty.\\n */\\n receive() external payable virtual {\\n _fallback();\\n }\\n\\n /**\\n * @dev Hook that is called before falling back to the implementation. Can happen as part of a manual `_fallback`\\n * call, or as part of the Solidity `fallback` or `receive` functions.\\n *\\n * If overridden should call `super._beforeFallback()`.\\n */\\n function _beforeFallback() internal virtual {}\\n}\\n\",\"keccak256\":\"0xc130fe33f1b2132158531a87734153293f6d07bc263ff4ac90e85da9c82c0e27\",\"license\":\"MIT\"},\"@openzeppelin/contracts/proxy/beacon/IBeacon.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (proxy/beacon/IBeacon.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev This is the interface that {BeaconProxy} expects of its beacon.\\n */\\ninterface IBeacon {\\n /**\\n * @dev Must return an address that can be used as a delegate call target.\\n *\\n * {BeaconProxy} will check that this address is a contract.\\n */\\n function implementation() external view returns (address);\\n}\\n\",\"keccak256\":\"0xd50a3421ac379ccb1be435fa646d66a65c986b4924f0849839f08692f39dde61\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/Address.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.7.0) (utils/Address.sol)\\n\\npragma solidity ^0.8.1;\\n\\n/**\\n * @dev Collection of functions related to the address type\\n */\\nlibrary Address {\\n /**\\n * @dev Returns true if `account` is a contract.\\n *\\n * [IMPORTANT]\\n * ====\\n * It is unsafe to assume that an address for which this function returns\\n * false is an externally-owned account (EOA) and not a contract.\\n *\\n * Among others, `isContract` will return false for the following\\n * types of addresses:\\n *\\n * - an externally-owned account\\n * - a contract in construction\\n * - an address where a contract will be created\\n * - an address where a contract lived, but was destroyed\\n * ====\\n *\\n * [IMPORTANT]\\n * ====\\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\\n *\\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\\n * constructor.\\n * ====\\n */\\n function isContract(address account) internal view returns (bool) {\\n // This method relies on extcodesize/address.code.length, which returns 0\\n // for contracts in construction, since the code is only stored at the end\\n // of the constructor execution.\\n\\n return account.code.length > 0;\\n }\\n\\n /**\\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\\n * `recipient`, forwarding all available gas and reverting on errors.\\n *\\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\\n * imposed by `transfer`, making them unable to receive funds via\\n * `transfer`. {sendValue} removes this limitation.\\n *\\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\\n *\\n * IMPORTANT: because control is transferred to `recipient`, care must be\\n * taken to not create reentrancy vulnerabilities. Consider using\\n * {ReentrancyGuard} or the\\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\\n */\\n function sendValue(address payable recipient, uint256 amount) internal {\\n require(address(this).balance >= amount, \\\"Address: insufficient balance\\\");\\n\\n (bool success, ) = recipient.call{value: amount}(\\\"\\\");\\n require(success, \\\"Address: unable to send value, recipient may have reverted\\\");\\n }\\n\\n /**\\n * @dev Performs a Solidity function call using a low level `call`. A\\n * plain `call` is an unsafe replacement for a function call: use this\\n * function instead.\\n *\\n * If `target` reverts with a revert reason, it is bubbled up by this\\n * function (like regular Solidity function calls).\\n *\\n * Returns the raw returned data. To convert to the expected return value,\\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\\n *\\n * Requirements:\\n *\\n * - `target` must be a contract.\\n * - calling `target` with `data` must not revert.\\n *\\n * _Available since v3.1._\\n */\\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\\n return functionCall(target, data, \\\"Address: low-level call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\\n * `errorMessage` as a fallback revert reason when `target` reverts.\\n *\\n * _Available since v3.1._\\n */\\n function functionCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n return functionCallWithValue(target, data, 0, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but also transferring `value` wei to `target`.\\n *\\n * Requirements:\\n *\\n * - the calling contract must have an ETH balance of at least `value`.\\n * - the called Solidity function must be `payable`.\\n *\\n * _Available since v3.1._\\n */\\n function functionCallWithValue(\\n address target,\\n bytes memory data,\\n uint256 value\\n ) internal returns (bytes memory) {\\n return functionCallWithValue(target, data, value, \\\"Address: low-level call with value failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\\n * with `errorMessage` as a fallback revert reason when `target` reverts.\\n *\\n * _Available since v3.1._\\n */\\n function functionCallWithValue(\\n address target,\\n bytes memory data,\\n uint256 value,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n require(address(this).balance >= value, \\\"Address: insufficient balance for call\\\");\\n require(isContract(target), \\\"Address: call to non-contract\\\");\\n\\n (bool success, bytes memory returndata) = target.call{value: value}(data);\\n return verifyCallResult(success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but performing a static call.\\n *\\n * _Available since v3.3._\\n */\\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\\n return functionStaticCall(target, data, \\\"Address: low-level static call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\\n * but performing a static call.\\n *\\n * _Available since v3.3._\\n */\\n function functionStaticCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal view returns (bytes memory) {\\n require(isContract(target), \\\"Address: static call to non-contract\\\");\\n\\n (bool success, bytes memory returndata) = target.staticcall(data);\\n return verifyCallResult(success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but performing a delegate call.\\n *\\n * _Available since v3.4._\\n */\\n function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {\\n return functionDelegateCall(target, data, \\\"Address: low-level delegate call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\\n * but performing a delegate call.\\n *\\n * _Available since v3.4._\\n */\\n function functionDelegateCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n require(isContract(target), \\\"Address: delegate call to non-contract\\\");\\n\\n (bool success, bytes memory returndata) = target.delegatecall(data);\\n return verifyCallResult(success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the\\n * revert reason using the provided one.\\n *\\n * _Available since v4.3._\\n */\\n function verifyCallResult(\\n bool success,\\n bytes memory returndata,\\n string memory errorMessage\\n ) internal pure returns (bytes memory) {\\n if (success) {\\n return returndata;\\n } else {\\n // Look for revert reason and bubble it up if present\\n if (returndata.length > 0) {\\n // The easiest way to bubble the revert reason is using memory via assembly\\n /// @solidity memory-safe-assembly\\n assembly {\\n let returndata_size := mload(returndata)\\n revert(add(32, returndata), returndata_size)\\n }\\n } else {\\n revert(errorMessage);\\n }\\n }\\n }\\n}\\n\",\"keccak256\":\"0xd6153ce99bcdcce22b124f755e72553295be6abcd63804cfdffceb188b8bef10\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/StorageSlot.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.7.0) (utils/StorageSlot.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Library for reading and writing primitive types to specific storage slots.\\n *\\n * Storage slots are often used to avoid storage conflict when dealing with upgradeable contracts.\\n * This library helps with reading and writing to such slots without the need for inline assembly.\\n *\\n * The functions in this library return Slot structs that contain a `value` member that can be used to read or write.\\n *\\n * Example usage to set ERC1967 implementation slot:\\n * ```\\n * contract ERC1967 {\\n * bytes32 internal constant _IMPLEMENTATION_SLOT = 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc;\\n *\\n * function _getImplementation() internal view returns (address) {\\n * return StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value;\\n * }\\n *\\n * function _setImplementation(address newImplementation) internal {\\n * require(Address.isContract(newImplementation), \\\"ERC1967: new implementation is not a contract\\\");\\n * StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value = newImplementation;\\n * }\\n * }\\n * ```\\n *\\n * _Available since v4.1 for `address`, `bool`, `bytes32`, and `uint256`._\\n */\\nlibrary StorageSlot {\\n struct AddressSlot {\\n address value;\\n }\\n\\n struct BooleanSlot {\\n bool value;\\n }\\n\\n struct Bytes32Slot {\\n bytes32 value;\\n }\\n\\n struct Uint256Slot {\\n uint256 value;\\n }\\n\\n /**\\n * @dev Returns an `AddressSlot` with member `value` located at `slot`.\\n */\\n function getAddressSlot(bytes32 slot) internal pure returns (AddressSlot storage r) {\\n /// @solidity memory-safe-assembly\\n assembly {\\n r.slot := slot\\n }\\n }\\n\\n /**\\n * @dev Returns an `BooleanSlot` with member `value` located at `slot`.\\n */\\n function getBooleanSlot(bytes32 slot) internal pure returns (BooleanSlot storage r) {\\n /// @solidity memory-safe-assembly\\n assembly {\\n r.slot := slot\\n }\\n }\\n\\n /**\\n * @dev Returns an `Bytes32Slot` with member `value` located at `slot`.\\n */\\n function getBytes32Slot(bytes32 slot) internal pure returns (Bytes32Slot storage r) {\\n /// @solidity memory-safe-assembly\\n assembly {\\n r.slot := slot\\n }\\n }\\n\\n /**\\n * @dev Returns an `Uint256Slot` with member `value` located at `slot`.\\n */\\n function getUint256Slot(bytes32 slot) internal pure returns (Uint256Slot storage r) {\\n /// @solidity memory-safe-assembly\\n assembly {\\n r.slot := slot\\n }\\n }\\n}\\n\",\"keccak256\":\"0xd5c50c54bf02740ebd122ff06832546cb5fa84486d52695a9ccfd11666e0c81d\",\"license\":\"MIT\"},\"contracts/external/TransparentUpgradeableProxy.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-3.0\\n\\npragma solidity ^0.8.12;\\n\\nimport \\\"@openzeppelin/contracts/proxy/ERC1967/ERC1967Proxy.sol\\\";\\n\\n/**\\n * @dev This contract implements a proxy that is upgradeable by an admin. It is fully forked from OpenZeppelin\\n * `TransparentUpgradeableProxy`\\n *\\n * To avoid https://medium.com/nomic-labs-blog/malicious-backdoors-in-ethereum-proxies-62629adf3357[proxy selector\\n * clashing], which can potentially be used in an attack, this contract uses the\\n * https://blog.openzeppelin.com/the-transparent-proxy-pattern/[transparent proxy pattern]. This pattern implies two\\n * things that go hand in hand:\\n *\\n * 1. If any account other than the admin calls the proxy, the call will be forwarded to the implementation, even if\\n * that call matches one of the admin functions exposed by the proxy itself.\\n * 2. If the admin calls the proxy, it can access the admin functions, but its calls will never be forwarded to the\\n * implementation. If the admin tries to call a function on the implementation it will fail with an error that says\\n * \\\"admin cannot fallback to proxy target\\\".\\n *\\n * These properties mean that the admin account can only be used for admin actions like upgrading the proxy or changing\\n * the admin, so it's best if it's a dedicated account that is not used for anything else. This will avoid headaches due\\n * to sudden errors when trying to call a function from the proxy implementation.\\n *\\n * Our recommendation is for the dedicated account to be an instance of the {ProxyAdmin} contract. If set up this way,\\n * you should think of the `ProxyAdmin` instance as the real administrative interface of your proxy.\\n */\\ncontract TransparentUpgradeableProxy is ERC1967Proxy {\\n /**\\n * @dev Initializes an upgradeable proxy managed by `_admin`, backed by the implementation at `_logic`, and\\n * optionally initialized with `_data` as explained in {ERC1967Proxy-constructor}.\\n */\\n constructor(address _logic, address admin_, bytes memory _data) payable ERC1967Proxy(_logic, _data) {\\n assert(_ADMIN_SLOT == bytes32(uint256(keccak256(\\\"eip1967.proxy.admin\\\")) - 1));\\n _changeAdmin(admin_);\\n }\\n\\n /**\\n * @dev Modifier used internally that will delegate the call to the implementation unless the sender is the admin.\\n */\\n modifier ifAdmin() {\\n if (msg.sender == _getAdmin()) {\\n _;\\n } else {\\n _fallback();\\n }\\n }\\n\\n /**\\n * @dev Returns the current admin.\\n *\\n * NOTE: Only the admin can call this function. See {ProxyAdmin-getProxyAdmin}.\\n *\\n * TIP: To get this value clients can read directly from the storage slot shown below (specified by EIP1967) using the\\n * https://eth.wiki/json-rpc/API#eth_getstorageat[`eth_getStorageAt`] RPC call.\\n * `0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103`\\n */\\n function admin() external ifAdmin returns (address admin_) {\\n admin_ = _getAdmin();\\n }\\n\\n /**\\n * @dev Returns the current implementation.\\n *\\n * NOTE: Only the admin can call this function. See {ProxyAdmin-getProxyImplementation}.\\n *\\n * TIP: To get this value clients can read directly from the storage slot shown below (specified by EIP1967) using the\\n * https://eth.wiki/json-rpc/API#eth_getstorageat[`eth_getStorageAt`] RPC call.\\n * `0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc`\\n */\\n function implementation() external ifAdmin returns (address implementation_) {\\n implementation_ = _implementation();\\n }\\n\\n /**\\n * @dev Changes the admin of the proxy.\\n *\\n * Emits an {AdminChanged} event.\\n *\\n * NOTE: Only the admin can call this function. See {ProxyAdmin-changeProxyAdmin}.\\n */\\n function changeAdmin(address newAdmin) external virtual ifAdmin {\\n _changeAdmin(newAdmin);\\n }\\n\\n /**\\n * @dev Upgrade the implementation of the proxy.\\n *\\n * NOTE: Only the admin can call this function. See {ProxyAdmin-upgrade}.\\n */\\n function upgradeTo(address newImplementation) external ifAdmin {\\n _upgradeToAndCall(newImplementation, bytes(\\\"\\\"), false);\\n }\\n\\n /**\\n * @dev Upgrade the implementation of the proxy, and then call a function from the new implementation as specified\\n * by `data`, which should be an encoded function call. This is useful to initialize new storage variables in the\\n * proxied contract.\\n *\\n * NOTE: Only the admin can call this function. See {ProxyAdmin-upgradeAndCall}.\\n */\\n function upgradeToAndCall(address newImplementation, bytes calldata data) external payable ifAdmin {\\n _upgradeToAndCall(newImplementation, data, true);\\n }\\n\\n /**\\n * @dev Returns the current admin.\\n */\\n function _admin() internal view virtual returns (address) {\\n return _getAdmin();\\n }\\n\\n /**\\n * @dev Makes sure the admin cannot access the fallback function. See {Proxy-_beforeFallback}.\\n */\\n function _beforeFallback() internal virtual override {\\n require(msg.sender != _getAdmin(), \\\"TransparentUpgradeableProxy: admin cannot fallback to proxy target\\\");\\n super._beforeFallback();\\n }\\n}\\n\",\"keccak256\":\"0x93a67a0f612ea3ff2a76315e138a6a88267270a1379d3cc7be52845fbbe611e2\",\"license\":\"GPL-3.0\"}},\"version\":1}", + "bytecode": "0x6080604052604051620010bb380380620010bb8339810160408190526200002691620004d8565b828162000036828260006200009a565b5062000066905060017fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6104620005b8565b6000805160206200107483398151915214620000865762000086620005da565b6200009182620000d7565b50505062000643565b620000a58362000132565b600082511180620000b35750805b15620000d257620000d083836200017460201b6200028c1760201c565b505b505050565b7f7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f62000102620001a5565b604080516001600160a01b03928316815291841660208301520160405180910390a16200012f81620001de565b50565b6200013d8162000293565b6040516001600160a01b038216907fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b90600090a250565b60606200019c8383604051806060016040528060278152602001620010946027913962000347565b90505b92915050565b6000620001cf6000805160206200107483398151915260001b6200042f60201b6200022e1760201c565b546001600160a01b0316919050565b6001600160a01b038116620002495760405162461bcd60e51b815260206004820152602660248201527f455243313936373a206e65772061646d696e20697320746865207a65726f206160448201526564647265737360d01b60648201526084015b60405180910390fd5b80620002726000805160206200107483398151915260001b6200042f60201b6200022e1760201c565b80546001600160a01b0319166001600160a01b039290921691909117905550565b620002a9816200043260201b620002b81760201c565b6200030d5760405162461bcd60e51b815260206004820152602d60248201527f455243313936373a206e657720696d706c656d656e746174696f6e206973206e60448201526c1bdd08184818dbdb9d1c9858dd609a1b606482015260840162000240565b80620002727f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc60001b6200042f60201b6200022e1760201c565b60606001600160a01b0384163b620003b15760405162461bcd60e51b815260206004820152602660248201527f416464726573733a2064656c65676174652063616c6c20746f206e6f6e2d636f6044820152651b9d1c9858dd60d21b606482015260840162000240565b600080856001600160a01b031685604051620003ce9190620005f0565b600060405180830381855af49150503d80600081146200040b576040519150601f19603f3d011682016040523d82523d6000602084013e62000410565b606091505b5090925090506200042382828662000441565b925050505b9392505050565b90565b6001600160a01b03163b151590565b606083156200045257508162000428565b825115620004635782518084602001fd5b8160405162461bcd60e51b81526004016200024091906200060e565b80516001600160a01b03811681146200049757600080fd5b919050565b634e487b7160e01b600052604160045260246000fd5b60005b83811015620004cf578181015183820152602001620004b5565b50506000910152565b600080600060608486031215620004ee57600080fd5b620004f9846200047f565b925062000509602085016200047f565b60408501519092506001600160401b03808211156200052757600080fd5b818601915086601f8301126200053c57600080fd5b8151818111156200055157620005516200049c565b604051601f8201601f19908116603f011681019083821181831017156200057c576200057c6200049c565b816040528281528960208487010111156200059657600080fd5b620005a9836020830160208801620004b2565b80955050505050509250925092565b818103818111156200019f57634e487b7160e01b600052601160045260246000fd5b634e487b7160e01b600052600160045260246000fd5b6000825162000604818460208701620004b2565b9190910192915050565b60208152600082518060208401526200062f816040850160208701620004b2565b601f01601f19169190910160400192915050565b610a2180620006536000396000f3fe60806040526004361061005e5760003560e01c80635c60da1b116100435780635c60da1b146100a85780638f283970146100e6578063f851a440146101065761006d565b80633659cfe6146100755780634f1ef286146100955761006d565b3661006d5761006b61011b565b005b61006b61011b565b34801561008157600080fd5b5061006b610090366004610895565b610135565b61006b6100a33660046108b0565b61017f565b3480156100b457600080fd5b506100bd6101f3565b60405173ffffffffffffffffffffffffffffffffffffffff909116815260200160405180910390f35b3480156100f257600080fd5b5061006b610101366004610895565b610231565b34801561011257600080fd5b506100bd61025e565b6101236102d4565b61013361012e6103ab565b6103b5565b565b61013d6103d9565b73ffffffffffffffffffffffffffffffffffffffff1633036101775761017481604051806020016040528060008152506000610419565b50565b61017461011b565b6101876103d9565b73ffffffffffffffffffffffffffffffffffffffff1633036101eb576101e68383838080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525060019250610419915050565b505050565b6101e661011b565b60006101fd6103d9565b73ffffffffffffffffffffffffffffffffffffffff163303610226576102216103ab565b905090565b61022e61011b565b90565b6102396103d9565b73ffffffffffffffffffffffffffffffffffffffff1633036101775761017481610444565b60006102686103d9565b73ffffffffffffffffffffffffffffffffffffffff163303610226576102216103d9565b60606102b183836040518060600160405280602781526020016109c5602791396104a5565b9392505050565b73ffffffffffffffffffffffffffffffffffffffff163b151590565b6102dc6103d9565b73ffffffffffffffffffffffffffffffffffffffff163303610133576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604260248201527f5472616e73706172656e745570677261646561626c6550726f78793a2061646d60448201527f696e2063616e6e6f742066616c6c6261636b20746f2070726f7879207461726760648201527f6574000000000000000000000000000000000000000000000000000000000000608482015260a4015b60405180910390fd5b60006102216105cd565b3660008037600080366000845af43d6000803e8080156103d4573d6000f35b3d6000fd5b60007fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035b5473ffffffffffffffffffffffffffffffffffffffff16919050565b610422836105f5565b60008251118061042f5750805b156101e65761043e838361028c565b50505050565b7f7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f61046d6103d9565b6040805173ffffffffffffffffffffffffffffffffffffffff928316815291841660208301520160405180910390a161017481610642565b606073ffffffffffffffffffffffffffffffffffffffff84163b61054b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f416464726573733a2064656c65676174652063616c6c20746f206e6f6e2d636f60448201527f6e7472616374000000000000000000000000000000000000000000000000000060648201526084016103a2565b6000808573ffffffffffffffffffffffffffffffffffffffff16856040516105739190610957565b600060405180830381855af49150503d80600081146105ae576040519150601f19603f3d011682016040523d82523d6000602084013e6105b3565b606091505b50915091506105c382828661074e565b9695505050505050565b60007f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc6103fd565b6105fe816107a1565b60405173ffffffffffffffffffffffffffffffffffffffff8216907fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b90600090a250565b73ffffffffffffffffffffffffffffffffffffffff81166106e5576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f455243313936373a206e65772061646d696e20697320746865207a65726f206160448201527f646472657373000000000000000000000000000000000000000000000000000060648201526084016103a2565b807fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035b80547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff9290921691909117905550565b6060831561075d5750816102b1565b82511561076d5782518084602001fd5b816040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016103a29190610973565b73ffffffffffffffffffffffffffffffffffffffff81163b610845576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602d60248201527f455243313936373a206e657720696d706c656d656e746174696f6e206973206e60448201527f6f74206120636f6e74726163740000000000000000000000000000000000000060648201526084016103a2565b807f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc610708565b803573ffffffffffffffffffffffffffffffffffffffff8116811461089057600080fd5b919050565b6000602082840312156108a757600080fd5b6102b18261086c565b6000806000604084860312156108c557600080fd5b6108ce8461086c565b9250602084013567ffffffffffffffff808211156108eb57600080fd5b818601915086601f8301126108ff57600080fd5b81358181111561090e57600080fd5b87602082850101111561092057600080fd5b6020830194508093505050509250925092565b60005b8381101561094e578181015183820152602001610936565b50506000910152565b60008251610969818460208701610933565b9190910192915050565b6020815260008251806020840152610992816040850160208701610933565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016919091016040019291505056fe416464726573733a206c6f772d6c6576656c2064656c65676174652063616c6c206661696c6564a2646970667358221220e96638b07fb1675d93a95c49e417bc8111448b23a59918698cdcd8fd488dd7cf64736f6c63430008110033b53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103416464726573733a206c6f772d6c6576656c2064656c65676174652063616c6c206661696c6564", + "deployedBytecode": "0x60806040526004361061005e5760003560e01c80635c60da1b116100435780635c60da1b146100a85780638f283970146100e6578063f851a440146101065761006d565b80633659cfe6146100755780634f1ef286146100955761006d565b3661006d5761006b61011b565b005b61006b61011b565b34801561008157600080fd5b5061006b610090366004610895565b610135565b61006b6100a33660046108b0565b61017f565b3480156100b457600080fd5b506100bd6101f3565b60405173ffffffffffffffffffffffffffffffffffffffff909116815260200160405180910390f35b3480156100f257600080fd5b5061006b610101366004610895565b610231565b34801561011257600080fd5b506100bd61025e565b6101236102d4565b61013361012e6103ab565b6103b5565b565b61013d6103d9565b73ffffffffffffffffffffffffffffffffffffffff1633036101775761017481604051806020016040528060008152506000610419565b50565b61017461011b565b6101876103d9565b73ffffffffffffffffffffffffffffffffffffffff1633036101eb576101e68383838080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525060019250610419915050565b505050565b6101e661011b565b60006101fd6103d9565b73ffffffffffffffffffffffffffffffffffffffff163303610226576102216103ab565b905090565b61022e61011b565b90565b6102396103d9565b73ffffffffffffffffffffffffffffffffffffffff1633036101775761017481610444565b60006102686103d9565b73ffffffffffffffffffffffffffffffffffffffff163303610226576102216103d9565b60606102b183836040518060600160405280602781526020016109c5602791396104a5565b9392505050565b73ffffffffffffffffffffffffffffffffffffffff163b151590565b6102dc6103d9565b73ffffffffffffffffffffffffffffffffffffffff163303610133576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604260248201527f5472616e73706172656e745570677261646561626c6550726f78793a2061646d60448201527f696e2063616e6e6f742066616c6c6261636b20746f2070726f7879207461726760648201527f6574000000000000000000000000000000000000000000000000000000000000608482015260a4015b60405180910390fd5b60006102216105cd565b3660008037600080366000845af43d6000803e8080156103d4573d6000f35b3d6000fd5b60007fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035b5473ffffffffffffffffffffffffffffffffffffffff16919050565b610422836105f5565b60008251118061042f5750805b156101e65761043e838361028c565b50505050565b7f7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f61046d6103d9565b6040805173ffffffffffffffffffffffffffffffffffffffff928316815291841660208301520160405180910390a161017481610642565b606073ffffffffffffffffffffffffffffffffffffffff84163b61054b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f416464726573733a2064656c65676174652063616c6c20746f206e6f6e2d636f60448201527f6e7472616374000000000000000000000000000000000000000000000000000060648201526084016103a2565b6000808573ffffffffffffffffffffffffffffffffffffffff16856040516105739190610957565b600060405180830381855af49150503d80600081146105ae576040519150601f19603f3d011682016040523d82523d6000602084013e6105b3565b606091505b50915091506105c382828661074e565b9695505050505050565b60007f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc6103fd565b6105fe816107a1565b60405173ffffffffffffffffffffffffffffffffffffffff8216907fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b90600090a250565b73ffffffffffffffffffffffffffffffffffffffff81166106e5576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f455243313936373a206e65772061646d696e20697320746865207a65726f206160448201527f646472657373000000000000000000000000000000000000000000000000000060648201526084016103a2565b807fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035b80547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff9290921691909117905550565b6060831561075d5750816102b1565b82511561076d5782518084602001fd5b816040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016103a29190610973565b73ffffffffffffffffffffffffffffffffffffffff81163b610845576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602d60248201527f455243313936373a206e657720696d706c656d656e746174696f6e206973206e60448201527f6f74206120636f6e74726163740000000000000000000000000000000000000060648201526084016103a2565b807f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc610708565b803573ffffffffffffffffffffffffffffffffffffffff8116811461089057600080fd5b919050565b6000602082840312156108a757600080fd5b6102b18261086c565b6000806000604084860312156108c557600080fd5b6108ce8461086c565b9250602084013567ffffffffffffffff808211156108eb57600080fd5b818601915086601f8301126108ff57600080fd5b81358181111561090e57600080fd5b87602082850101111561092057600080fd5b6020830194508093505050509250925092565b60005b8381101561094e578181015183820152602001610936565b50506000910152565b60008251610969818460208701610933565b9190910192915050565b6020815260008251806020840152610992816040850160208701610933565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016919091016040019291505056fe416464726573733a206c6f772d6c6576656c2064656c65676174652063616c6c206661696c6564a2646970667358221220e96638b07fb1675d93a95c49e417bc8111448b23a59918698cdcd8fd488dd7cf64736f6c63430008110033", + "devdoc": { + "details": "This contract implements a proxy that is upgradeable by an admin. It is fully forked from OpenZeppelin `TransparentUpgradeableProxy` To avoid https://medium.com/nomic-labs-blog/malicious-backdoors-in-ethereum-proxies-62629adf3357[proxy selector clashing], which can potentially be used in an attack, this contract uses the https://blog.openzeppelin.com/the-transparent-proxy-pattern/[transparent proxy pattern]. This pattern implies two things that go hand in hand: 1. If any account other than the admin calls the proxy, the call will be forwarded to the implementation, even if that call matches one of the admin functions exposed by the proxy itself. 2. If the admin calls the proxy, it can access the admin functions, but its calls will never be forwarded to the implementation. If the admin tries to call a function on the implementation it will fail with an error that says \"admin cannot fallback to proxy target\". These properties mean that the admin account can only be used for admin actions like upgrading the proxy or changing the admin, so it's best if it's a dedicated account that is not used for anything else. This will avoid headaches due to sudden errors when trying to call a function from the proxy implementation. Our recommendation is for the dedicated account to be an instance of the {ProxyAdmin} contract. If set up this way, you should think of the `ProxyAdmin` instance as the real administrative interface of your proxy.", + "kind": "dev", + "methods": { + "admin()": { + "details": "Returns the current admin. NOTE: Only the admin can call this function. See {ProxyAdmin-getProxyAdmin}. TIP: To get this value clients can read directly from the storage slot shown below (specified by EIP1967) using the https://eth.wiki/json-rpc/API#eth_getstorageat[`eth_getStorageAt`] RPC call. `0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103`" + }, + "changeAdmin(address)": { + "details": "Changes the admin of the proxy. Emits an {AdminChanged} event. NOTE: Only the admin can call this function. See {ProxyAdmin-changeProxyAdmin}." + }, + "constructor": { + "details": "Initializes an upgradeable proxy managed by `_admin`, backed by the implementation at `_logic`, and optionally initialized with `_data` as explained in {ERC1967Proxy-constructor}." + }, + "implementation()": { + "details": "Returns the current implementation. NOTE: Only the admin can call this function. See {ProxyAdmin-getProxyImplementation}. TIP: To get this value clients can read directly from the storage slot shown below (specified by EIP1967) using the https://eth.wiki/json-rpc/API#eth_getstorageat[`eth_getStorageAt`] RPC call. `0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc`" + }, + "upgradeTo(address)": { + "details": "Upgrade the implementation of the proxy. NOTE: Only the admin can call this function. See {ProxyAdmin-upgrade}." + }, + "upgradeToAndCall(address,bytes)": { + "details": "Upgrade the implementation of the proxy, and then call a function from the new implementation as specified by `data`, which should be an encoded function call. This is useful to initialize new storage variables in the proxied contract. NOTE: Only the admin can call this function. See {ProxyAdmin-upgradeAndCall}." + } + }, + "version": 1 + }, + "userdoc": { + "kind": "user", + "methods": {}, + "version": 1 + }, + "storageLayout": { + "storage": [], + "types": null + } +} \ No newline at end of file diff --git a/deployments/celo/Treasury_USD.json b/deployments/celo/Treasury_USD.json new file mode 100644 index 00000000..daa3bb8a --- /dev/null +++ b/deployments/celo/Treasury_USD.json @@ -0,0 +1,247 @@ +{ + "address": "0x029F049C59A6b56610a34ba01d0d28E26ed407A8", + "abi": [ + { + "inputs": [ + { + "internalType": "address", + "name": "_logic", + "type": "address" + }, + { + "internalType": "address", + "name": "admin_", + "type": "address" + }, + { + "internalType": "bytes", + "name": "_data", + "type": "bytes" + } + ], + "stateMutability": "payable", + "type": "constructor" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "previousAdmin", + "type": "address" + }, + { + "indexed": false, + "internalType": "address", + "name": "newAdmin", + "type": "address" + } + ], + "name": "AdminChanged", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "beacon", + "type": "address" + } + ], + "name": "BeaconUpgraded", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "implementation", + "type": "address" + } + ], + "name": "Upgraded", + "type": "event" + }, + { + "stateMutability": "payable", + "type": "fallback" + }, + { + "inputs": [], + "name": "admin", + "outputs": [ + { + "internalType": "address", + "name": "admin_", + "type": "address" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "newAdmin", + "type": "address" + } + ], + "name": "changeAdmin", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "implementation", + "outputs": [ + { + "internalType": "address", + "name": "implementation_", + "type": "address" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "newImplementation", + "type": "address" + } + ], + "name": "upgradeTo", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "newImplementation", + "type": "address" + }, + { + "internalType": "bytes", + "name": "data", + "type": "bytes" + } + ], + "name": "upgradeToAndCall", + "outputs": [], + "stateMutability": "payable", + "type": "function" + }, + { + "stateMutability": "payable", + "type": "receive" + } + ], + "transactionHash": "0x779a072efc858989b1546be35bc9a0615dd473f2137b0b532add504db66c6e85", + "receipt": { + "to": null, + "from": "0xfdA462548Ce04282f4B6D6619823a7C64Fdc0185", + "contractAddress": "0x029F049C59A6b56610a34ba01d0d28E26ed407A8", + "transactionIndex": 6, + "gasUsed": "736150", + "logsBloom": "0x00040000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000080000000000000800000000000000000000000000000000000000000000000400000000000000000000080000000000000800000000000000000000000000000000401000000400000000000000000000000000000000020000000000000000000050000000000000400000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "blockHash": "0xd216b32dd055423b17bd77bc1a89f3067d1b8d78d96581f17ddf5071ab4256a7", + "transactionHash": "0x779a072efc858989b1546be35bc9a0615dd473f2137b0b532add504db66c6e85", + "logs": [ + { + "transactionIndex": 6, + "blockNumber": 23443580, + "transactionHash": "0x779a072efc858989b1546be35bc9a0615dd473f2137b0b532add504db66c6e85", + "address": "0x029F049C59A6b56610a34ba01d0d28E26ed407A8", + "topics": [ + "0xbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b", + "0x0000000000000000000000005addc89785d75c86ab939e9e15bfbbb7fc086a87" + ], + "data": "0x", + "logIndex": 17, + "blockHash": "0xd216b32dd055423b17bd77bc1a89f3067d1b8d78d96581f17ddf5071ab4256a7" + }, + { + "transactionIndex": 6, + "blockNumber": 23443580, + "transactionHash": "0x779a072efc858989b1546be35bc9a0615dd473f2137b0b532add504db66c6e85", + "address": "0x029F049C59A6b56610a34ba01d0d28E26ed407A8", + "topics": [ + "0x7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb3847402498" + ], + "data": "0x0000000000000000000000000000000000000000000000000000000000000001", + "logIndex": 18, + "blockHash": "0xd216b32dd055423b17bd77bc1a89f3067d1b8d78d96581f17ddf5071ab4256a7" + }, + { + "transactionIndex": 6, + "blockNumber": 23443580, + "transactionHash": "0x779a072efc858989b1546be35bc9a0615dd473f2137b0b532add504db66c6e85", + "address": "0x029F049C59A6b56610a34ba01d0d28E26ed407A8", + "topics": [ + "0x7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f" + ], + "data": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000005183f032bf42109cd370b9559fd22207e432301e", + "logIndex": 19, + "blockHash": "0xd216b32dd055423b17bd77bc1a89f3067d1b8d78d96581f17ddf5071ab4256a7" + } + ], + "blockNumber": 23443580, + "cumulativeGasUsed": "1653718", + "status": 1, + "byzantium": true + }, + "args": [ + "0x5adDc89785D75C86aB939E9e15bfBBb7Fc086A87", + "0x5183f032bf42109cD370B9559FD22207e432301E", + "0x485cc95500000000000000000000000003c2d2014795ee8ca78b62738433b457ab19f4b30000000000000000000000000000206329b97db379d5e1bf586bbdb969c63274" + ], + "numDeployments": 1, + "solcInputHash": "871924e0c138825a2736b76def8fef8d", + "metadata": "{\"compiler\":{\"version\":\"0.8.17+commit.8df45f5f\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_logic\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"admin_\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"_data\",\"type\":\"bytes\"}],\"stateMutability\":\"payable\",\"type\":\"constructor\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"previousAdmin\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"newAdmin\",\"type\":\"address\"}],\"name\":\"AdminChanged\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"beacon\",\"type\":\"address\"}],\"name\":\"BeaconUpgraded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"implementation\",\"type\":\"address\"}],\"name\":\"Upgraded\",\"type\":\"event\"},{\"stateMutability\":\"payable\",\"type\":\"fallback\"},{\"inputs\":[],\"name\":\"admin\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"admin_\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newAdmin\",\"type\":\"address\"}],\"name\":\"changeAdmin\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"implementation\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"implementation_\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newImplementation\",\"type\":\"address\"}],\"name\":\"upgradeTo\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newImplementation\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"}],\"name\":\"upgradeToAndCall\",\"outputs\":[],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"stateMutability\":\"payable\",\"type\":\"receive\"}],\"devdoc\":{\"details\":\"This contract implements a proxy that is upgradeable by an admin. It is fully forked from OpenZeppelin `TransparentUpgradeableProxy` To avoid https://medium.com/nomic-labs-blog/malicious-backdoors-in-ethereum-proxies-62629adf3357[proxy selector clashing], which can potentially be used in an attack, this contract uses the https://blog.openzeppelin.com/the-transparent-proxy-pattern/[transparent proxy pattern]. This pattern implies two things that go hand in hand: 1. If any account other than the admin calls the proxy, the call will be forwarded to the implementation, even if that call matches one of the admin functions exposed by the proxy itself. 2. If the admin calls the proxy, it can access the admin functions, but its calls will never be forwarded to the implementation. If the admin tries to call a function on the implementation it will fail with an error that says \\\"admin cannot fallback to proxy target\\\". These properties mean that the admin account can only be used for admin actions like upgrading the proxy or changing the admin, so it's best if it's a dedicated account that is not used for anything else. This will avoid headaches due to sudden errors when trying to call a function from the proxy implementation. Our recommendation is for the dedicated account to be an instance of the {ProxyAdmin} contract. If set up this way, you should think of the `ProxyAdmin` instance as the real administrative interface of your proxy.\",\"kind\":\"dev\",\"methods\":{\"admin()\":{\"details\":\"Returns the current admin. NOTE: Only the admin can call this function. See {ProxyAdmin-getProxyAdmin}. TIP: To get this value clients can read directly from the storage slot shown below (specified by EIP1967) using the https://eth.wiki/json-rpc/API#eth_getstorageat[`eth_getStorageAt`] RPC call. `0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103`\"},\"changeAdmin(address)\":{\"details\":\"Changes the admin of the proxy. Emits an {AdminChanged} event. NOTE: Only the admin can call this function. See {ProxyAdmin-changeProxyAdmin}.\"},\"constructor\":{\"details\":\"Initializes an upgradeable proxy managed by `_admin`, backed by the implementation at `_logic`, and optionally initialized with `_data` as explained in {ERC1967Proxy-constructor}.\"},\"implementation()\":{\"details\":\"Returns the current implementation. NOTE: Only the admin can call this function. See {ProxyAdmin-getProxyImplementation}. TIP: To get this value clients can read directly from the storage slot shown below (specified by EIP1967) using the https://eth.wiki/json-rpc/API#eth_getstorageat[`eth_getStorageAt`] RPC call. `0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc`\"},\"upgradeTo(address)\":{\"details\":\"Upgrade the implementation of the proxy. NOTE: Only the admin can call this function. See {ProxyAdmin-upgrade}.\"},\"upgradeToAndCall(address,bytes)\":{\"details\":\"Upgrade the implementation of the proxy, and then call a function from the new implementation as specified by `data`, which should be an encoded function call. This is useful to initialize new storage variables in the proxied contract. NOTE: Only the admin can call this function. See {ProxyAdmin-upgradeAndCall}.\"}},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/external/TransparentUpgradeableProxy.sol\":\"TransparentUpgradeableProxy\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":1000000},\"remappings\":[]},\"sources\":{\"@openzeppelin/contracts/interfaces/draft-IERC1822.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.5.0) (interfaces/draft-IERC1822.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev ERC1822: Universal Upgradeable Proxy Standard (UUPS) documents a method for upgradeability through a simplified\\n * proxy whose upgrades are fully controlled by the current implementation.\\n */\\ninterface IERC1822Proxiable {\\n /**\\n * @dev Returns the storage slot that the proxiable contract assumes is being used to store the implementation\\n * address.\\n *\\n * IMPORTANT: A proxy pointing at a proxiable contract should not be considered proxiable itself, because this risks\\n * bricking a proxy that upgrades to it, by delegating to itself until out of gas. Thus it is critical that this\\n * function revert if invoked through a proxy.\\n */\\n function proxiableUUID() external view returns (bytes32);\\n}\\n\",\"keccak256\":\"0x1d4afe6cb24200cc4545eed814ecf5847277dfe5d613a1707aad5fceecebcfff\",\"license\":\"MIT\"},\"@openzeppelin/contracts/proxy/ERC1967/ERC1967Proxy.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.7.0) (proxy/ERC1967/ERC1967Proxy.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../Proxy.sol\\\";\\nimport \\\"./ERC1967Upgrade.sol\\\";\\n\\n/**\\n * @dev This contract implements an upgradeable proxy. It is upgradeable because calls are delegated to an\\n * implementation address that can be changed. This address is stored in storage in the location specified by\\n * https://eips.ethereum.org/EIPS/eip-1967[EIP1967], so that it doesn't conflict with the storage layout of the\\n * implementation behind the proxy.\\n */\\ncontract ERC1967Proxy is Proxy, ERC1967Upgrade {\\n /**\\n * @dev Initializes the upgradeable proxy with an initial implementation specified by `_logic`.\\n *\\n * If `_data` is nonempty, it's used as data in a delegate call to `_logic`. This will typically be an encoded\\n * function call, and allows initializing the storage of the proxy like a Solidity constructor.\\n */\\n constructor(address _logic, bytes memory _data) payable {\\n _upgradeToAndCall(_logic, _data, false);\\n }\\n\\n /**\\n * @dev Returns the current implementation address.\\n */\\n function _implementation() internal view virtual override returns (address impl) {\\n return ERC1967Upgrade._getImplementation();\\n }\\n}\\n\",\"keccak256\":\"0xa2b22da3032e50b55f95ec1d13336102d675f341167aa76db571ef7f8bb7975d\",\"license\":\"MIT\"},\"@openzeppelin/contracts/proxy/ERC1967/ERC1967Upgrade.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.5.0) (proxy/ERC1967/ERC1967Upgrade.sol)\\n\\npragma solidity ^0.8.2;\\n\\nimport \\\"../beacon/IBeacon.sol\\\";\\nimport \\\"../../interfaces/draft-IERC1822.sol\\\";\\nimport \\\"../../utils/Address.sol\\\";\\nimport \\\"../../utils/StorageSlot.sol\\\";\\n\\n/**\\n * @dev This abstract contract provides getters and event emitting update functions for\\n * https://eips.ethereum.org/EIPS/eip-1967[EIP1967] slots.\\n *\\n * _Available since v4.1._\\n *\\n * @custom:oz-upgrades-unsafe-allow delegatecall\\n */\\nabstract contract ERC1967Upgrade {\\n // This is the keccak-256 hash of \\\"eip1967.proxy.rollback\\\" subtracted by 1\\n bytes32 private constant _ROLLBACK_SLOT = 0x4910fdfa16fed3260ed0e7147f7cc6da11a60208b5b9406d12a635614ffd9143;\\n\\n /**\\n * @dev Storage slot with the address of the current implementation.\\n * This is the keccak-256 hash of \\\"eip1967.proxy.implementation\\\" subtracted by 1, and is\\n * validated in the constructor.\\n */\\n bytes32 internal constant _IMPLEMENTATION_SLOT = 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc;\\n\\n /**\\n * @dev Emitted when the implementation is upgraded.\\n */\\n event Upgraded(address indexed implementation);\\n\\n /**\\n * @dev Returns the current implementation address.\\n */\\n function _getImplementation() internal view returns (address) {\\n return StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value;\\n }\\n\\n /**\\n * @dev Stores a new address in the EIP1967 implementation slot.\\n */\\n function _setImplementation(address newImplementation) private {\\n require(Address.isContract(newImplementation), \\\"ERC1967: new implementation is not a contract\\\");\\n StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value = newImplementation;\\n }\\n\\n /**\\n * @dev Perform implementation upgrade\\n *\\n * Emits an {Upgraded} event.\\n */\\n function _upgradeTo(address newImplementation) internal {\\n _setImplementation(newImplementation);\\n emit Upgraded(newImplementation);\\n }\\n\\n /**\\n * @dev Perform implementation upgrade with additional setup call.\\n *\\n * Emits an {Upgraded} event.\\n */\\n function _upgradeToAndCall(\\n address newImplementation,\\n bytes memory data,\\n bool forceCall\\n ) internal {\\n _upgradeTo(newImplementation);\\n if (data.length > 0 || forceCall) {\\n Address.functionDelegateCall(newImplementation, data);\\n }\\n }\\n\\n /**\\n * @dev Perform implementation upgrade with security checks for UUPS proxies, and additional setup call.\\n *\\n * Emits an {Upgraded} event.\\n */\\n function _upgradeToAndCallUUPS(\\n address newImplementation,\\n bytes memory data,\\n bool forceCall\\n ) internal {\\n // Upgrades from old implementations will perform a rollback test. This test requires the new\\n // implementation to upgrade back to the old, non-ERC1822 compliant, implementation. Removing\\n // this special case will break upgrade paths from old UUPS implementation to new ones.\\n if (StorageSlot.getBooleanSlot(_ROLLBACK_SLOT).value) {\\n _setImplementation(newImplementation);\\n } else {\\n try IERC1822Proxiable(newImplementation).proxiableUUID() returns (bytes32 slot) {\\n require(slot == _IMPLEMENTATION_SLOT, \\\"ERC1967Upgrade: unsupported proxiableUUID\\\");\\n } catch {\\n revert(\\\"ERC1967Upgrade: new implementation is not UUPS\\\");\\n }\\n _upgradeToAndCall(newImplementation, data, forceCall);\\n }\\n }\\n\\n /**\\n * @dev Storage slot with the admin of the contract.\\n * This is the keccak-256 hash of \\\"eip1967.proxy.admin\\\" subtracted by 1, and is\\n * validated in the constructor.\\n */\\n bytes32 internal constant _ADMIN_SLOT = 0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103;\\n\\n /**\\n * @dev Emitted when the admin account has changed.\\n */\\n event AdminChanged(address previousAdmin, address newAdmin);\\n\\n /**\\n * @dev Returns the current admin.\\n */\\n function _getAdmin() internal view returns (address) {\\n return StorageSlot.getAddressSlot(_ADMIN_SLOT).value;\\n }\\n\\n /**\\n * @dev Stores a new address in the EIP1967 admin slot.\\n */\\n function _setAdmin(address newAdmin) private {\\n require(newAdmin != address(0), \\\"ERC1967: new admin is the zero address\\\");\\n StorageSlot.getAddressSlot(_ADMIN_SLOT).value = newAdmin;\\n }\\n\\n /**\\n * @dev Changes the admin of the proxy.\\n *\\n * Emits an {AdminChanged} event.\\n */\\n function _changeAdmin(address newAdmin) internal {\\n emit AdminChanged(_getAdmin(), newAdmin);\\n _setAdmin(newAdmin);\\n }\\n\\n /**\\n * @dev The storage slot of the UpgradeableBeacon contract which defines the implementation for this proxy.\\n * This is bytes32(uint256(keccak256('eip1967.proxy.beacon')) - 1)) and is validated in the constructor.\\n */\\n bytes32 internal constant _BEACON_SLOT = 0xa3f0ad74e5423aebfd80d3ef4346578335a9a72aeaee59ff6cb3582b35133d50;\\n\\n /**\\n * @dev Emitted when the beacon is upgraded.\\n */\\n event BeaconUpgraded(address indexed beacon);\\n\\n /**\\n * @dev Returns the current beacon.\\n */\\n function _getBeacon() internal view returns (address) {\\n return StorageSlot.getAddressSlot(_BEACON_SLOT).value;\\n }\\n\\n /**\\n * @dev Stores a new beacon in the EIP1967 beacon slot.\\n */\\n function _setBeacon(address newBeacon) private {\\n require(Address.isContract(newBeacon), \\\"ERC1967: new beacon is not a contract\\\");\\n require(\\n Address.isContract(IBeacon(newBeacon).implementation()),\\n \\\"ERC1967: beacon implementation is not a contract\\\"\\n );\\n StorageSlot.getAddressSlot(_BEACON_SLOT).value = newBeacon;\\n }\\n\\n /**\\n * @dev Perform beacon upgrade with additional setup call. Note: This upgrades the address of the beacon, it does\\n * not upgrade the implementation contained in the beacon (see {UpgradeableBeacon-_setImplementation} for that).\\n *\\n * Emits a {BeaconUpgraded} event.\\n */\\n function _upgradeBeaconToAndCall(\\n address newBeacon,\\n bytes memory data,\\n bool forceCall\\n ) internal {\\n _setBeacon(newBeacon);\\n emit BeaconUpgraded(newBeacon);\\n if (data.length > 0 || forceCall) {\\n Address.functionDelegateCall(IBeacon(newBeacon).implementation(), data);\\n }\\n }\\n}\\n\",\"keccak256\":\"0xabf3f59bc0e5423eae45e459dbe92e7052c6983628d39008590edc852a62f94a\",\"license\":\"MIT\"},\"@openzeppelin/contracts/proxy/Proxy.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.6.0) (proxy/Proxy.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev This abstract contract provides a fallback function that delegates all calls to another contract using the EVM\\n * instruction `delegatecall`. We refer to the second contract as the _implementation_ behind the proxy, and it has to\\n * be specified by overriding the virtual {_implementation} function.\\n *\\n * Additionally, delegation to the implementation can be triggered manually through the {_fallback} function, or to a\\n * different contract through the {_delegate} function.\\n *\\n * The success and return data of the delegated call will be returned back to the caller of the proxy.\\n */\\nabstract contract Proxy {\\n /**\\n * @dev Delegates the current call to `implementation`.\\n *\\n * This function does not return to its internal call site, it will return directly to the external caller.\\n */\\n function _delegate(address implementation) internal virtual {\\n assembly {\\n // Copy msg.data. We take full control of memory in this inline assembly\\n // block because it will not return to Solidity code. We overwrite the\\n // Solidity scratch pad at memory position 0.\\n calldatacopy(0, 0, calldatasize())\\n\\n // Call the implementation.\\n // out and outsize are 0 because we don't know the size yet.\\n let result := delegatecall(gas(), implementation, 0, calldatasize(), 0, 0)\\n\\n // Copy the returned data.\\n returndatacopy(0, 0, returndatasize())\\n\\n switch result\\n // delegatecall returns 0 on error.\\n case 0 {\\n revert(0, returndatasize())\\n }\\n default {\\n return(0, returndatasize())\\n }\\n }\\n }\\n\\n /**\\n * @dev This is a virtual function that should be overridden so it returns the address to which the fallback function\\n * and {_fallback} should delegate.\\n */\\n function _implementation() internal view virtual returns (address);\\n\\n /**\\n * @dev Delegates the current call to the address returned by `_implementation()`.\\n *\\n * This function does not return to its internal call site, it will return directly to the external caller.\\n */\\n function _fallback() internal virtual {\\n _beforeFallback();\\n _delegate(_implementation());\\n }\\n\\n /**\\n * @dev Fallback function that delegates calls to the address returned by `_implementation()`. Will run if no other\\n * function in the contract matches the call data.\\n */\\n fallback() external payable virtual {\\n _fallback();\\n }\\n\\n /**\\n * @dev Fallback function that delegates calls to the address returned by `_implementation()`. Will run if call data\\n * is empty.\\n */\\n receive() external payable virtual {\\n _fallback();\\n }\\n\\n /**\\n * @dev Hook that is called before falling back to the implementation. Can happen as part of a manual `_fallback`\\n * call, or as part of the Solidity `fallback` or `receive` functions.\\n *\\n * If overridden should call `super._beforeFallback()`.\\n */\\n function _beforeFallback() internal virtual {}\\n}\\n\",\"keccak256\":\"0xc130fe33f1b2132158531a87734153293f6d07bc263ff4ac90e85da9c82c0e27\",\"license\":\"MIT\"},\"@openzeppelin/contracts/proxy/beacon/IBeacon.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (proxy/beacon/IBeacon.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev This is the interface that {BeaconProxy} expects of its beacon.\\n */\\ninterface IBeacon {\\n /**\\n * @dev Must return an address that can be used as a delegate call target.\\n *\\n * {BeaconProxy} will check that this address is a contract.\\n */\\n function implementation() external view returns (address);\\n}\\n\",\"keccak256\":\"0xd50a3421ac379ccb1be435fa646d66a65c986b4924f0849839f08692f39dde61\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/Address.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.7.0) (utils/Address.sol)\\n\\npragma solidity ^0.8.1;\\n\\n/**\\n * @dev Collection of functions related to the address type\\n */\\nlibrary Address {\\n /**\\n * @dev Returns true if `account` is a contract.\\n *\\n * [IMPORTANT]\\n * ====\\n * It is unsafe to assume that an address for which this function returns\\n * false is an externally-owned account (EOA) and not a contract.\\n *\\n * Among others, `isContract` will return false for the following\\n * types of addresses:\\n *\\n * - an externally-owned account\\n * - a contract in construction\\n * - an address where a contract will be created\\n * - an address where a contract lived, but was destroyed\\n * ====\\n *\\n * [IMPORTANT]\\n * ====\\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\\n *\\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\\n * constructor.\\n * ====\\n */\\n function isContract(address account) internal view returns (bool) {\\n // This method relies on extcodesize/address.code.length, which returns 0\\n // for contracts in construction, since the code is only stored at the end\\n // of the constructor execution.\\n\\n return account.code.length > 0;\\n }\\n\\n /**\\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\\n * `recipient`, forwarding all available gas and reverting on errors.\\n *\\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\\n * imposed by `transfer`, making them unable to receive funds via\\n * `transfer`. {sendValue} removes this limitation.\\n *\\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\\n *\\n * IMPORTANT: because control is transferred to `recipient`, care must be\\n * taken to not create reentrancy vulnerabilities. Consider using\\n * {ReentrancyGuard} or the\\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\\n */\\n function sendValue(address payable recipient, uint256 amount) internal {\\n require(address(this).balance >= amount, \\\"Address: insufficient balance\\\");\\n\\n (bool success, ) = recipient.call{value: amount}(\\\"\\\");\\n require(success, \\\"Address: unable to send value, recipient may have reverted\\\");\\n }\\n\\n /**\\n * @dev Performs a Solidity function call using a low level `call`. A\\n * plain `call` is an unsafe replacement for a function call: use this\\n * function instead.\\n *\\n * If `target` reverts with a revert reason, it is bubbled up by this\\n * function (like regular Solidity function calls).\\n *\\n * Returns the raw returned data. To convert to the expected return value,\\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\\n *\\n * Requirements:\\n *\\n * - `target` must be a contract.\\n * - calling `target` with `data` must not revert.\\n *\\n * _Available since v3.1._\\n */\\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\\n return functionCall(target, data, \\\"Address: low-level call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\\n * `errorMessage` as a fallback revert reason when `target` reverts.\\n *\\n * _Available since v3.1._\\n */\\n function functionCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n return functionCallWithValue(target, data, 0, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but also transferring `value` wei to `target`.\\n *\\n * Requirements:\\n *\\n * - the calling contract must have an ETH balance of at least `value`.\\n * - the called Solidity function must be `payable`.\\n *\\n * _Available since v3.1._\\n */\\n function functionCallWithValue(\\n address target,\\n bytes memory data,\\n uint256 value\\n ) internal returns (bytes memory) {\\n return functionCallWithValue(target, data, value, \\\"Address: low-level call with value failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\\n * with `errorMessage` as a fallback revert reason when `target` reverts.\\n *\\n * _Available since v3.1._\\n */\\n function functionCallWithValue(\\n address target,\\n bytes memory data,\\n uint256 value,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n require(address(this).balance >= value, \\\"Address: insufficient balance for call\\\");\\n require(isContract(target), \\\"Address: call to non-contract\\\");\\n\\n (bool success, bytes memory returndata) = target.call{value: value}(data);\\n return verifyCallResult(success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but performing a static call.\\n *\\n * _Available since v3.3._\\n */\\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\\n return functionStaticCall(target, data, \\\"Address: low-level static call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\\n * but performing a static call.\\n *\\n * _Available since v3.3._\\n */\\n function functionStaticCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal view returns (bytes memory) {\\n require(isContract(target), \\\"Address: static call to non-contract\\\");\\n\\n (bool success, bytes memory returndata) = target.staticcall(data);\\n return verifyCallResult(success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but performing a delegate call.\\n *\\n * _Available since v3.4._\\n */\\n function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {\\n return functionDelegateCall(target, data, \\\"Address: low-level delegate call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\\n * but performing a delegate call.\\n *\\n * _Available since v3.4._\\n */\\n function functionDelegateCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n require(isContract(target), \\\"Address: delegate call to non-contract\\\");\\n\\n (bool success, bytes memory returndata) = target.delegatecall(data);\\n return verifyCallResult(success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the\\n * revert reason using the provided one.\\n *\\n * _Available since v4.3._\\n */\\n function verifyCallResult(\\n bool success,\\n bytes memory returndata,\\n string memory errorMessage\\n ) internal pure returns (bytes memory) {\\n if (success) {\\n return returndata;\\n } else {\\n // Look for revert reason and bubble it up if present\\n if (returndata.length > 0) {\\n // The easiest way to bubble the revert reason is using memory via assembly\\n /// @solidity memory-safe-assembly\\n assembly {\\n let returndata_size := mload(returndata)\\n revert(add(32, returndata), returndata_size)\\n }\\n } else {\\n revert(errorMessage);\\n }\\n }\\n }\\n}\\n\",\"keccak256\":\"0xd6153ce99bcdcce22b124f755e72553295be6abcd63804cfdffceb188b8bef10\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/StorageSlot.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.7.0) (utils/StorageSlot.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Library for reading and writing primitive types to specific storage slots.\\n *\\n * Storage slots are often used to avoid storage conflict when dealing with upgradeable contracts.\\n * This library helps with reading and writing to such slots without the need for inline assembly.\\n *\\n * The functions in this library return Slot structs that contain a `value` member that can be used to read or write.\\n *\\n * Example usage to set ERC1967 implementation slot:\\n * ```\\n * contract ERC1967 {\\n * bytes32 internal constant _IMPLEMENTATION_SLOT = 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc;\\n *\\n * function _getImplementation() internal view returns (address) {\\n * return StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value;\\n * }\\n *\\n * function _setImplementation(address newImplementation) internal {\\n * require(Address.isContract(newImplementation), \\\"ERC1967: new implementation is not a contract\\\");\\n * StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value = newImplementation;\\n * }\\n * }\\n * ```\\n *\\n * _Available since v4.1 for `address`, `bool`, `bytes32`, and `uint256`._\\n */\\nlibrary StorageSlot {\\n struct AddressSlot {\\n address value;\\n }\\n\\n struct BooleanSlot {\\n bool value;\\n }\\n\\n struct Bytes32Slot {\\n bytes32 value;\\n }\\n\\n struct Uint256Slot {\\n uint256 value;\\n }\\n\\n /**\\n * @dev Returns an `AddressSlot` with member `value` located at `slot`.\\n */\\n function getAddressSlot(bytes32 slot) internal pure returns (AddressSlot storage r) {\\n /// @solidity memory-safe-assembly\\n assembly {\\n r.slot := slot\\n }\\n }\\n\\n /**\\n * @dev Returns an `BooleanSlot` with member `value` located at `slot`.\\n */\\n function getBooleanSlot(bytes32 slot) internal pure returns (BooleanSlot storage r) {\\n /// @solidity memory-safe-assembly\\n assembly {\\n r.slot := slot\\n }\\n }\\n\\n /**\\n * @dev Returns an `Bytes32Slot` with member `value` located at `slot`.\\n */\\n function getBytes32Slot(bytes32 slot) internal pure returns (Bytes32Slot storage r) {\\n /// @solidity memory-safe-assembly\\n assembly {\\n r.slot := slot\\n }\\n }\\n\\n /**\\n * @dev Returns an `Uint256Slot` with member `value` located at `slot`.\\n */\\n function getUint256Slot(bytes32 slot) internal pure returns (Uint256Slot storage r) {\\n /// @solidity memory-safe-assembly\\n assembly {\\n r.slot := slot\\n }\\n }\\n}\\n\",\"keccak256\":\"0xd5c50c54bf02740ebd122ff06832546cb5fa84486d52695a9ccfd11666e0c81d\",\"license\":\"MIT\"},\"contracts/external/TransparentUpgradeableProxy.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-3.0\\n\\npragma solidity ^0.8.12;\\n\\nimport \\\"@openzeppelin/contracts/proxy/ERC1967/ERC1967Proxy.sol\\\";\\n\\n/**\\n * @dev This contract implements a proxy that is upgradeable by an admin. It is fully forked from OpenZeppelin\\n * `TransparentUpgradeableProxy`\\n *\\n * To avoid https://medium.com/nomic-labs-blog/malicious-backdoors-in-ethereum-proxies-62629adf3357[proxy selector\\n * clashing], which can potentially be used in an attack, this contract uses the\\n * https://blog.openzeppelin.com/the-transparent-proxy-pattern/[transparent proxy pattern]. This pattern implies two\\n * things that go hand in hand:\\n *\\n * 1. If any account other than the admin calls the proxy, the call will be forwarded to the implementation, even if\\n * that call matches one of the admin functions exposed by the proxy itself.\\n * 2. If the admin calls the proxy, it can access the admin functions, but its calls will never be forwarded to the\\n * implementation. If the admin tries to call a function on the implementation it will fail with an error that says\\n * \\\"admin cannot fallback to proxy target\\\".\\n *\\n * These properties mean that the admin account can only be used for admin actions like upgrading the proxy or changing\\n * the admin, so it's best if it's a dedicated account that is not used for anything else. This will avoid headaches due\\n * to sudden errors when trying to call a function from the proxy implementation.\\n *\\n * Our recommendation is for the dedicated account to be an instance of the {ProxyAdmin} contract. If set up this way,\\n * you should think of the `ProxyAdmin` instance as the real administrative interface of your proxy.\\n */\\ncontract TransparentUpgradeableProxy is ERC1967Proxy {\\n /**\\n * @dev Initializes an upgradeable proxy managed by `_admin`, backed by the implementation at `_logic`, and\\n * optionally initialized with `_data` as explained in {ERC1967Proxy-constructor}.\\n */\\n constructor(address _logic, address admin_, bytes memory _data) payable ERC1967Proxy(_logic, _data) {\\n assert(_ADMIN_SLOT == bytes32(uint256(keccak256(\\\"eip1967.proxy.admin\\\")) - 1));\\n _changeAdmin(admin_);\\n }\\n\\n /**\\n * @dev Modifier used internally that will delegate the call to the implementation unless the sender is the admin.\\n */\\n modifier ifAdmin() {\\n if (msg.sender == _getAdmin()) {\\n _;\\n } else {\\n _fallback();\\n }\\n }\\n\\n /**\\n * @dev Returns the current admin.\\n *\\n * NOTE: Only the admin can call this function. See {ProxyAdmin-getProxyAdmin}.\\n *\\n * TIP: To get this value clients can read directly from the storage slot shown below (specified by EIP1967) using the\\n * https://eth.wiki/json-rpc/API#eth_getstorageat[`eth_getStorageAt`] RPC call.\\n * `0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103`\\n */\\n function admin() external ifAdmin returns (address admin_) {\\n admin_ = _getAdmin();\\n }\\n\\n /**\\n * @dev Returns the current implementation.\\n *\\n * NOTE: Only the admin can call this function. See {ProxyAdmin-getProxyImplementation}.\\n *\\n * TIP: To get this value clients can read directly from the storage slot shown below (specified by EIP1967) using the\\n * https://eth.wiki/json-rpc/API#eth_getstorageat[`eth_getStorageAt`] RPC call.\\n * `0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc`\\n */\\n function implementation() external ifAdmin returns (address implementation_) {\\n implementation_ = _implementation();\\n }\\n\\n /**\\n * @dev Changes the admin of the proxy.\\n *\\n * Emits an {AdminChanged} event.\\n *\\n * NOTE: Only the admin can call this function. See {ProxyAdmin-changeProxyAdmin}.\\n */\\n function changeAdmin(address newAdmin) external virtual ifAdmin {\\n _changeAdmin(newAdmin);\\n }\\n\\n /**\\n * @dev Upgrade the implementation of the proxy.\\n *\\n * NOTE: Only the admin can call this function. See {ProxyAdmin-upgrade}.\\n */\\n function upgradeTo(address newImplementation) external ifAdmin {\\n _upgradeToAndCall(newImplementation, bytes(\\\"\\\"), false);\\n }\\n\\n /**\\n * @dev Upgrade the implementation of the proxy, and then call a function from the new implementation as specified\\n * by `data`, which should be an encoded function call. This is useful to initialize new storage variables in the\\n * proxied contract.\\n *\\n * NOTE: Only the admin can call this function. See {ProxyAdmin-upgradeAndCall}.\\n */\\n function upgradeToAndCall(address newImplementation, bytes calldata data) external payable ifAdmin {\\n _upgradeToAndCall(newImplementation, data, true);\\n }\\n\\n /**\\n * @dev Returns the current admin.\\n */\\n function _admin() internal view virtual returns (address) {\\n return _getAdmin();\\n }\\n\\n /**\\n * @dev Makes sure the admin cannot access the fallback function. See {Proxy-_beforeFallback}.\\n */\\n function _beforeFallback() internal virtual override {\\n require(msg.sender != _getAdmin(), \\\"TransparentUpgradeableProxy: admin cannot fallback to proxy target\\\");\\n super._beforeFallback();\\n }\\n}\\n\",\"keccak256\":\"0x93a67a0f612ea3ff2a76315e138a6a88267270a1379d3cc7be52845fbbe611e2\",\"license\":\"GPL-3.0\"}},\"version\":1}", + "bytecode": "0x6080604052604051620010bb380380620010bb8339810160408190526200002691620004d8565b828162000036828260006200009a565b5062000066905060017fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6104620005b8565b6000805160206200107483398151915214620000865762000086620005da565b6200009182620000d7565b50505062000643565b620000a58362000132565b600082511180620000b35750805b15620000d257620000d083836200017460201b6200028c1760201c565b505b505050565b7f7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f62000102620001a5565b604080516001600160a01b03928316815291841660208301520160405180910390a16200012f81620001de565b50565b6200013d8162000293565b6040516001600160a01b038216907fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b90600090a250565b60606200019c8383604051806060016040528060278152602001620010946027913962000347565b90505b92915050565b6000620001cf6000805160206200107483398151915260001b6200042f60201b6200022e1760201c565b546001600160a01b0316919050565b6001600160a01b038116620002495760405162461bcd60e51b815260206004820152602660248201527f455243313936373a206e65772061646d696e20697320746865207a65726f206160448201526564647265737360d01b60648201526084015b60405180910390fd5b80620002726000805160206200107483398151915260001b6200042f60201b6200022e1760201c565b80546001600160a01b0319166001600160a01b039290921691909117905550565b620002a9816200043260201b620002b81760201c565b6200030d5760405162461bcd60e51b815260206004820152602d60248201527f455243313936373a206e657720696d706c656d656e746174696f6e206973206e60448201526c1bdd08184818dbdb9d1c9858dd609a1b606482015260840162000240565b80620002727f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc60001b6200042f60201b6200022e1760201c565b60606001600160a01b0384163b620003b15760405162461bcd60e51b815260206004820152602660248201527f416464726573733a2064656c65676174652063616c6c20746f206e6f6e2d636f6044820152651b9d1c9858dd60d21b606482015260840162000240565b600080856001600160a01b031685604051620003ce9190620005f0565b600060405180830381855af49150503d80600081146200040b576040519150601f19603f3d011682016040523d82523d6000602084013e62000410565b606091505b5090925090506200042382828662000441565b925050505b9392505050565b90565b6001600160a01b03163b151590565b606083156200045257508162000428565b825115620004635782518084602001fd5b8160405162461bcd60e51b81526004016200024091906200060e565b80516001600160a01b03811681146200049757600080fd5b919050565b634e487b7160e01b600052604160045260246000fd5b60005b83811015620004cf578181015183820152602001620004b5565b50506000910152565b600080600060608486031215620004ee57600080fd5b620004f9846200047f565b925062000509602085016200047f565b60408501519092506001600160401b03808211156200052757600080fd5b818601915086601f8301126200053c57600080fd5b8151818111156200055157620005516200049c565b604051601f8201601f19908116603f011681019083821181831017156200057c576200057c6200049c565b816040528281528960208487010111156200059657600080fd5b620005a9836020830160208801620004b2565b80955050505050509250925092565b818103818111156200019f57634e487b7160e01b600052601160045260246000fd5b634e487b7160e01b600052600160045260246000fd5b6000825162000604818460208701620004b2565b9190910192915050565b60208152600082518060208401526200062f816040850160208701620004b2565b601f01601f19169190910160400192915050565b610a2180620006536000396000f3fe60806040526004361061005e5760003560e01c80635c60da1b116100435780635c60da1b146100a85780638f283970146100e6578063f851a440146101065761006d565b80633659cfe6146100755780634f1ef286146100955761006d565b3661006d5761006b61011b565b005b61006b61011b565b34801561008157600080fd5b5061006b610090366004610895565b610135565b61006b6100a33660046108b0565b61017f565b3480156100b457600080fd5b506100bd6101f3565b60405173ffffffffffffffffffffffffffffffffffffffff909116815260200160405180910390f35b3480156100f257600080fd5b5061006b610101366004610895565b610231565b34801561011257600080fd5b506100bd61025e565b6101236102d4565b61013361012e6103ab565b6103b5565b565b61013d6103d9565b73ffffffffffffffffffffffffffffffffffffffff1633036101775761017481604051806020016040528060008152506000610419565b50565b61017461011b565b6101876103d9565b73ffffffffffffffffffffffffffffffffffffffff1633036101eb576101e68383838080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525060019250610419915050565b505050565b6101e661011b565b60006101fd6103d9565b73ffffffffffffffffffffffffffffffffffffffff163303610226576102216103ab565b905090565b61022e61011b565b90565b6102396103d9565b73ffffffffffffffffffffffffffffffffffffffff1633036101775761017481610444565b60006102686103d9565b73ffffffffffffffffffffffffffffffffffffffff163303610226576102216103d9565b60606102b183836040518060600160405280602781526020016109c5602791396104a5565b9392505050565b73ffffffffffffffffffffffffffffffffffffffff163b151590565b6102dc6103d9565b73ffffffffffffffffffffffffffffffffffffffff163303610133576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604260248201527f5472616e73706172656e745570677261646561626c6550726f78793a2061646d60448201527f696e2063616e6e6f742066616c6c6261636b20746f2070726f7879207461726760648201527f6574000000000000000000000000000000000000000000000000000000000000608482015260a4015b60405180910390fd5b60006102216105cd565b3660008037600080366000845af43d6000803e8080156103d4573d6000f35b3d6000fd5b60007fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035b5473ffffffffffffffffffffffffffffffffffffffff16919050565b610422836105f5565b60008251118061042f5750805b156101e65761043e838361028c565b50505050565b7f7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f61046d6103d9565b6040805173ffffffffffffffffffffffffffffffffffffffff928316815291841660208301520160405180910390a161017481610642565b606073ffffffffffffffffffffffffffffffffffffffff84163b61054b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f416464726573733a2064656c65676174652063616c6c20746f206e6f6e2d636f60448201527f6e7472616374000000000000000000000000000000000000000000000000000060648201526084016103a2565b6000808573ffffffffffffffffffffffffffffffffffffffff16856040516105739190610957565b600060405180830381855af49150503d80600081146105ae576040519150601f19603f3d011682016040523d82523d6000602084013e6105b3565b606091505b50915091506105c382828661074e565b9695505050505050565b60007f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc6103fd565b6105fe816107a1565b60405173ffffffffffffffffffffffffffffffffffffffff8216907fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b90600090a250565b73ffffffffffffffffffffffffffffffffffffffff81166106e5576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f455243313936373a206e65772061646d696e20697320746865207a65726f206160448201527f646472657373000000000000000000000000000000000000000000000000000060648201526084016103a2565b807fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035b80547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff9290921691909117905550565b6060831561075d5750816102b1565b82511561076d5782518084602001fd5b816040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016103a29190610973565b73ffffffffffffffffffffffffffffffffffffffff81163b610845576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602d60248201527f455243313936373a206e657720696d706c656d656e746174696f6e206973206e60448201527f6f74206120636f6e74726163740000000000000000000000000000000000000060648201526084016103a2565b807f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc610708565b803573ffffffffffffffffffffffffffffffffffffffff8116811461089057600080fd5b919050565b6000602082840312156108a757600080fd5b6102b18261086c565b6000806000604084860312156108c557600080fd5b6108ce8461086c565b9250602084013567ffffffffffffffff808211156108eb57600080fd5b818601915086601f8301126108ff57600080fd5b81358181111561090e57600080fd5b87602082850101111561092057600080fd5b6020830194508093505050509250925092565b60005b8381101561094e578181015183820152602001610936565b50506000910152565b60008251610969818460208701610933565b9190910192915050565b6020815260008251806020840152610992816040850160208701610933565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016919091016040019291505056fe416464726573733a206c6f772d6c6576656c2064656c65676174652063616c6c206661696c6564a2646970667358221220e96638b07fb1675d93a95c49e417bc8111448b23a59918698cdcd8fd488dd7cf64736f6c63430008110033b53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103416464726573733a206c6f772d6c6576656c2064656c65676174652063616c6c206661696c6564", + "deployedBytecode": "0x60806040526004361061005e5760003560e01c80635c60da1b116100435780635c60da1b146100a85780638f283970146100e6578063f851a440146101065761006d565b80633659cfe6146100755780634f1ef286146100955761006d565b3661006d5761006b61011b565b005b61006b61011b565b34801561008157600080fd5b5061006b610090366004610895565b610135565b61006b6100a33660046108b0565b61017f565b3480156100b457600080fd5b506100bd6101f3565b60405173ffffffffffffffffffffffffffffffffffffffff909116815260200160405180910390f35b3480156100f257600080fd5b5061006b610101366004610895565b610231565b34801561011257600080fd5b506100bd61025e565b6101236102d4565b61013361012e6103ab565b6103b5565b565b61013d6103d9565b73ffffffffffffffffffffffffffffffffffffffff1633036101775761017481604051806020016040528060008152506000610419565b50565b61017461011b565b6101876103d9565b73ffffffffffffffffffffffffffffffffffffffff1633036101eb576101e68383838080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525060019250610419915050565b505050565b6101e661011b565b60006101fd6103d9565b73ffffffffffffffffffffffffffffffffffffffff163303610226576102216103ab565b905090565b61022e61011b565b90565b6102396103d9565b73ffffffffffffffffffffffffffffffffffffffff1633036101775761017481610444565b60006102686103d9565b73ffffffffffffffffffffffffffffffffffffffff163303610226576102216103d9565b60606102b183836040518060600160405280602781526020016109c5602791396104a5565b9392505050565b73ffffffffffffffffffffffffffffffffffffffff163b151590565b6102dc6103d9565b73ffffffffffffffffffffffffffffffffffffffff163303610133576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604260248201527f5472616e73706172656e745570677261646561626c6550726f78793a2061646d60448201527f696e2063616e6e6f742066616c6c6261636b20746f2070726f7879207461726760648201527f6574000000000000000000000000000000000000000000000000000000000000608482015260a4015b60405180910390fd5b60006102216105cd565b3660008037600080366000845af43d6000803e8080156103d4573d6000f35b3d6000fd5b60007fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035b5473ffffffffffffffffffffffffffffffffffffffff16919050565b610422836105f5565b60008251118061042f5750805b156101e65761043e838361028c565b50505050565b7f7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f61046d6103d9565b6040805173ffffffffffffffffffffffffffffffffffffffff928316815291841660208301520160405180910390a161017481610642565b606073ffffffffffffffffffffffffffffffffffffffff84163b61054b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f416464726573733a2064656c65676174652063616c6c20746f206e6f6e2d636f60448201527f6e7472616374000000000000000000000000000000000000000000000000000060648201526084016103a2565b6000808573ffffffffffffffffffffffffffffffffffffffff16856040516105739190610957565b600060405180830381855af49150503d80600081146105ae576040519150601f19603f3d011682016040523d82523d6000602084013e6105b3565b606091505b50915091506105c382828661074e565b9695505050505050565b60007f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc6103fd565b6105fe816107a1565b60405173ffffffffffffffffffffffffffffffffffffffff8216907fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b90600090a250565b73ffffffffffffffffffffffffffffffffffffffff81166106e5576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f455243313936373a206e65772061646d696e20697320746865207a65726f206160448201527f646472657373000000000000000000000000000000000000000000000000000060648201526084016103a2565b807fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035b80547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff9290921691909117905550565b6060831561075d5750816102b1565b82511561076d5782518084602001fd5b816040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016103a29190610973565b73ffffffffffffffffffffffffffffffffffffffff81163b610845576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602d60248201527f455243313936373a206e657720696d706c656d656e746174696f6e206973206e60448201527f6f74206120636f6e74726163740000000000000000000000000000000000000060648201526084016103a2565b807f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc610708565b803573ffffffffffffffffffffffffffffffffffffffff8116811461089057600080fd5b919050565b6000602082840312156108a757600080fd5b6102b18261086c565b6000806000604084860312156108c557600080fd5b6108ce8461086c565b9250602084013567ffffffffffffffff808211156108eb57600080fd5b818601915086601f8301126108ff57600080fd5b81358181111561090e57600080fd5b87602082850101111561092057600080fd5b6020830194508093505050509250925092565b60005b8381101561094e578181015183820152602001610936565b50506000910152565b60008251610969818460208701610933565b9190910192915050565b6020815260008251806020840152610992816040850160208701610933565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016919091016040019291505056fe416464726573733a206c6f772d6c6576656c2064656c65676174652063616c6c206661696c6564a2646970667358221220e96638b07fb1675d93a95c49e417bc8111448b23a59918698cdcd8fd488dd7cf64736f6c63430008110033", + "devdoc": { + "details": "This contract implements a proxy that is upgradeable by an admin. It is fully forked from OpenZeppelin `TransparentUpgradeableProxy` To avoid https://medium.com/nomic-labs-blog/malicious-backdoors-in-ethereum-proxies-62629adf3357[proxy selector clashing], which can potentially be used in an attack, this contract uses the https://blog.openzeppelin.com/the-transparent-proxy-pattern/[transparent proxy pattern]. This pattern implies two things that go hand in hand: 1. If any account other than the admin calls the proxy, the call will be forwarded to the implementation, even if that call matches one of the admin functions exposed by the proxy itself. 2. If the admin calls the proxy, it can access the admin functions, but its calls will never be forwarded to the implementation. If the admin tries to call a function on the implementation it will fail with an error that says \"admin cannot fallback to proxy target\". These properties mean that the admin account can only be used for admin actions like upgrading the proxy or changing the admin, so it's best if it's a dedicated account that is not used for anything else. This will avoid headaches due to sudden errors when trying to call a function from the proxy implementation. Our recommendation is for the dedicated account to be an instance of the {ProxyAdmin} contract. If set up this way, you should think of the `ProxyAdmin` instance as the real administrative interface of your proxy.", + "kind": "dev", + "methods": { + "admin()": { + "details": "Returns the current admin. NOTE: Only the admin can call this function. See {ProxyAdmin-getProxyAdmin}. TIP: To get this value clients can read directly from the storage slot shown below (specified by EIP1967) using the https://eth.wiki/json-rpc/API#eth_getstorageat[`eth_getStorageAt`] RPC call. `0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103`" + }, + "changeAdmin(address)": { + "details": "Changes the admin of the proxy. Emits an {AdminChanged} event. NOTE: Only the admin can call this function. See {ProxyAdmin-changeProxyAdmin}." + }, + "constructor": { + "details": "Initializes an upgradeable proxy managed by `_admin`, backed by the implementation at `_logic`, and optionally initialized with `_data` as explained in {ERC1967Proxy-constructor}." + }, + "implementation()": { + "details": "Returns the current implementation. NOTE: Only the admin can call this function. See {ProxyAdmin-getProxyImplementation}. TIP: To get this value clients can read directly from the storage slot shown below (specified by EIP1967) using the https://eth.wiki/json-rpc/API#eth_getstorageat[`eth_getStorageAt`] RPC call. `0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc`" + }, + "upgradeTo(address)": { + "details": "Upgrade the implementation of the proxy. NOTE: Only the admin can call this function. See {ProxyAdmin-upgrade}." + }, + "upgradeToAndCall(address,bytes)": { + "details": "Upgrade the implementation of the proxy, and then call a function from the new implementation as specified by `data`, which should be an encoded function call. This is useful to initialize new storage variables in the proxied contract. NOTE: Only the admin can call this function. See {ProxyAdmin-upgradeAndCall}." + } + }, + "version": 1 + }, + "userdoc": { + "kind": "user", + "methods": {}, + "version": 1 + }, + "storageLayout": { + "storage": [], + "types": null + } +} \ No newline at end of file diff --git a/deployments/celo/solcInputs/871924e0c138825a2736b76def8fef8d.json b/deployments/celo/solcInputs/871924e0c138825a2736b76def8fef8d.json new file mode 100644 index 00000000..57454028 --- /dev/null +++ b/deployments/celo/solcInputs/871924e0c138825a2736b76def8fef8d.json @@ -0,0 +1,562 @@ +{ + "language": "Solidity", + "sources": { + "@chainlink/contracts/src/v0.8/interfaces/AggregatorV3Interface.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.0;\n\ninterface AggregatorV3Interface {\n\n function decimals()\n external\n view\n returns (\n uint8\n );\n\n function description()\n external\n view\n returns (\n string memory\n );\n\n function version()\n external\n view\n returns (\n uint256\n );\n\n // getRoundData and latestRoundData should both raise \"No data present\"\n // if they do not have data to report, instead of returning unset values\n // which could be misinterpreted as actual reported values.\n function getRoundData(\n uint80 _roundId\n )\n external\n view\n returns (\n uint80 roundId,\n int256 answer,\n uint256 startedAt,\n uint256 updatedAt,\n uint80 answeredInRound\n );\n\n function latestRoundData()\n external\n view\n returns (\n uint80 roundId,\n int256 answer,\n uint256 startedAt,\n uint256 updatedAt,\n uint80 answeredInRound\n );\n\n}\n" + }, + "@openzeppelin/contracts-upgradeable/access/AccessControlEnumerableUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.5.0) (access/AccessControlEnumerable.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./IAccessControlEnumerableUpgradeable.sol\";\nimport \"./AccessControlUpgradeable.sol\";\nimport \"../utils/structs/EnumerableSetUpgradeable.sol\";\nimport \"../proxy/utils/Initializable.sol\";\n\n/**\n * @dev Extension of {AccessControl} that allows enumerating the members of each role.\n */\nabstract contract AccessControlEnumerableUpgradeable is Initializable, IAccessControlEnumerableUpgradeable, AccessControlUpgradeable {\n function __AccessControlEnumerable_init() internal onlyInitializing {\n }\n\n function __AccessControlEnumerable_init_unchained() internal onlyInitializing {\n }\n using EnumerableSetUpgradeable for EnumerableSetUpgradeable.AddressSet;\n\n mapping(bytes32 => EnumerableSetUpgradeable.AddressSet) private _roleMembers;\n\n /**\n * @dev See {IERC165-supportsInterface}.\n */\n function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {\n return interfaceId == type(IAccessControlEnumerableUpgradeable).interfaceId || super.supportsInterface(interfaceId);\n }\n\n /**\n * @dev Returns one of the accounts that have `role`. `index` must be a\n * value between 0 and {getRoleMemberCount}, non-inclusive.\n *\n * Role bearers are not sorted in any particular way, and their ordering may\n * change at any point.\n *\n * WARNING: When using {getRoleMember} and {getRoleMemberCount}, make sure\n * you perform all queries on the same block. See the following\n * https://forum.openzeppelin.com/t/iterating-over-elements-on-enumerableset-in-openzeppelin-contracts/2296[forum post]\n * for more information.\n */\n function getRoleMember(bytes32 role, uint256 index) public view virtual override returns (address) {\n return _roleMembers[role].at(index);\n }\n\n /**\n * @dev Returns the number of accounts that have `role`. Can be used\n * together with {getRoleMember} to enumerate all bearers of a role.\n */\n function getRoleMemberCount(bytes32 role) public view virtual override returns (uint256) {\n return _roleMembers[role].length();\n }\n\n /**\n * @dev Overload {_grantRole} to track enumerable memberships\n */\n function _grantRole(bytes32 role, address account) internal virtual override {\n super._grantRole(role, account);\n _roleMembers[role].add(account);\n }\n\n /**\n * @dev Overload {_revokeRole} to track enumerable memberships\n */\n function _revokeRole(bytes32 role, address account) internal virtual override {\n super._revokeRole(role, account);\n _roleMembers[role].remove(account);\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[49] private __gap;\n}\n" + }, + "@openzeppelin/contracts-upgradeable/access/AccessControlUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (access/AccessControl.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./IAccessControlUpgradeable.sol\";\nimport \"../utils/ContextUpgradeable.sol\";\nimport \"../utils/StringsUpgradeable.sol\";\nimport \"../utils/introspection/ERC165Upgradeable.sol\";\nimport \"../proxy/utils/Initializable.sol\";\n\n/**\n * @dev Contract module that allows children to implement role-based access\n * control mechanisms. This is a lightweight version that doesn't allow enumerating role\n * members except through off-chain means by accessing the contract event logs. Some\n * applications may benefit from on-chain enumerability, for those cases see\n * {AccessControlEnumerable}.\n *\n * Roles are referred to by their `bytes32` identifier. These should be exposed\n * in the external API and be unique. The best way to achieve this is by\n * using `public constant` hash digests:\n *\n * ```\n * bytes32 public constant MY_ROLE = keccak256(\"MY_ROLE\");\n * ```\n *\n * Roles can be used to represent a set of permissions. To restrict access to a\n * function call, use {hasRole}:\n *\n * ```\n * function foo() public {\n * require(hasRole(MY_ROLE, msg.sender));\n * ...\n * }\n * ```\n *\n * Roles can be granted and revoked dynamically via the {grantRole} and\n * {revokeRole} functions. Each role has an associated admin role, and only\n * accounts that have a role's admin role can call {grantRole} and {revokeRole}.\n *\n * By default, the admin role for all roles is `DEFAULT_ADMIN_ROLE`, which means\n * that only accounts with this role will be able to grant or revoke other\n * roles. More complex role relationships can be created by using\n * {_setRoleAdmin}.\n *\n * WARNING: The `DEFAULT_ADMIN_ROLE` is also its own admin: it has permission to\n * grant and revoke this role. Extra precautions should be taken to secure\n * accounts that have been granted it.\n */\nabstract contract AccessControlUpgradeable is Initializable, ContextUpgradeable, IAccessControlUpgradeable, ERC165Upgradeable {\n function __AccessControl_init() internal onlyInitializing {\n }\n\n function __AccessControl_init_unchained() internal onlyInitializing {\n }\n struct RoleData {\n mapping(address => bool) members;\n bytes32 adminRole;\n }\n\n mapping(bytes32 => RoleData) private _roles;\n\n bytes32 public constant DEFAULT_ADMIN_ROLE = 0x00;\n\n /**\n * @dev Modifier that checks that an account has a specific role. Reverts\n * with a standardized message including the required role.\n *\n * The format of the revert reason is given by the following regular expression:\n *\n * /^AccessControl: account (0x[0-9a-f]{40}) is missing role (0x[0-9a-f]{64})$/\n *\n * _Available since v4.1._\n */\n modifier onlyRole(bytes32 role) {\n _checkRole(role);\n _;\n }\n\n /**\n * @dev See {IERC165-supportsInterface}.\n */\n function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {\n return interfaceId == type(IAccessControlUpgradeable).interfaceId || super.supportsInterface(interfaceId);\n }\n\n /**\n * @dev Returns `true` if `account` has been granted `role`.\n */\n function hasRole(bytes32 role, address account) public view virtual override returns (bool) {\n return _roles[role].members[account];\n }\n\n /**\n * @dev Revert with a standard message if `_msgSender()` is missing `role`.\n * Overriding this function changes the behavior of the {onlyRole} modifier.\n *\n * Format of the revert message is described in {_checkRole}.\n *\n * _Available since v4.6._\n */\n function _checkRole(bytes32 role) internal view virtual {\n _checkRole(role, _msgSender());\n }\n\n /**\n * @dev Revert with a standard message if `account` is missing `role`.\n *\n * The format of the revert reason is given by the following regular expression:\n *\n * /^AccessControl: account (0x[0-9a-f]{40}) is missing role (0x[0-9a-f]{64})$/\n */\n function _checkRole(bytes32 role, address account) internal view virtual {\n if (!hasRole(role, account)) {\n revert(\n string(\n abi.encodePacked(\n \"AccessControl: account \",\n StringsUpgradeable.toHexString(uint160(account), 20),\n \" is missing role \",\n StringsUpgradeable.toHexString(uint256(role), 32)\n )\n )\n );\n }\n }\n\n /**\n * @dev Returns the admin role that controls `role`. See {grantRole} and\n * {revokeRole}.\n *\n * To change a role's admin, use {_setRoleAdmin}.\n */\n function getRoleAdmin(bytes32 role) public view virtual override returns (bytes32) {\n return _roles[role].adminRole;\n }\n\n /**\n * @dev Grants `role` to `account`.\n *\n * If `account` had not been already granted `role`, emits a {RoleGranted}\n * event.\n *\n * Requirements:\n *\n * - the caller must have ``role``'s admin role.\n *\n * May emit a {RoleGranted} event.\n */\n function grantRole(bytes32 role, address account) public virtual override onlyRole(getRoleAdmin(role)) {\n _grantRole(role, account);\n }\n\n /**\n * @dev Revokes `role` from `account`.\n *\n * If `account` had been granted `role`, emits a {RoleRevoked} event.\n *\n * Requirements:\n *\n * - the caller must have ``role``'s admin role.\n *\n * May emit a {RoleRevoked} event.\n */\n function revokeRole(bytes32 role, address account) public virtual override onlyRole(getRoleAdmin(role)) {\n _revokeRole(role, account);\n }\n\n /**\n * @dev Revokes `role` from the calling account.\n *\n * Roles are often managed via {grantRole} and {revokeRole}: this function's\n * purpose is to provide a mechanism for accounts to lose their privileges\n * if they are compromised (such as when a trusted device is misplaced).\n *\n * If the calling account had been revoked `role`, emits a {RoleRevoked}\n * event.\n *\n * Requirements:\n *\n * - the caller must be `account`.\n *\n * May emit a {RoleRevoked} event.\n */\n function renounceRole(bytes32 role, address account) public virtual override {\n require(account == _msgSender(), \"AccessControl: can only renounce roles for self\");\n\n _revokeRole(role, account);\n }\n\n /**\n * @dev Grants `role` to `account`.\n *\n * If `account` had not been already granted `role`, emits a {RoleGranted}\n * event. Note that unlike {grantRole}, this function doesn't perform any\n * checks on the calling account.\n *\n * May emit a {RoleGranted} event.\n *\n * [WARNING]\n * ====\n * This function should only be called from the constructor when setting\n * up the initial roles for the system.\n *\n * Using this function in any other way is effectively circumventing the admin\n * system imposed by {AccessControl}.\n * ====\n *\n * NOTE: This function is deprecated in favor of {_grantRole}.\n */\n function _setupRole(bytes32 role, address account) internal virtual {\n _grantRole(role, account);\n }\n\n /**\n * @dev Sets `adminRole` as ``role``'s admin role.\n *\n * Emits a {RoleAdminChanged} event.\n */\n function _setRoleAdmin(bytes32 role, bytes32 adminRole) internal virtual {\n bytes32 previousAdminRole = getRoleAdmin(role);\n _roles[role].adminRole = adminRole;\n emit RoleAdminChanged(role, previousAdminRole, adminRole);\n }\n\n /**\n * @dev Grants `role` to `account`.\n *\n * Internal function without access restriction.\n *\n * May emit a {RoleGranted} event.\n */\n function _grantRole(bytes32 role, address account) internal virtual {\n if (!hasRole(role, account)) {\n _roles[role].members[account] = true;\n emit RoleGranted(role, account, _msgSender());\n }\n }\n\n /**\n * @dev Revokes `role` from `account`.\n *\n * Internal function without access restriction.\n *\n * May emit a {RoleRevoked} event.\n */\n function _revokeRole(bytes32 role, address account) internal virtual {\n if (hasRole(role, account)) {\n _roles[role].members[account] = false;\n emit RoleRevoked(role, account, _msgSender());\n }\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[49] private __gap;\n}\n" + }, + "@openzeppelin/contracts-upgradeable/access/IAccessControlEnumerableUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (access/IAccessControlEnumerable.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./IAccessControlUpgradeable.sol\";\n\n/**\n * @dev External interface of AccessControlEnumerable declared to support ERC165 detection.\n */\ninterface IAccessControlEnumerableUpgradeable is IAccessControlUpgradeable {\n /**\n * @dev Returns one of the accounts that have `role`. `index` must be a\n * value between 0 and {getRoleMemberCount}, non-inclusive.\n *\n * Role bearers are not sorted in any particular way, and their ordering may\n * change at any point.\n *\n * WARNING: When using {getRoleMember} and {getRoleMemberCount}, make sure\n * you perform all queries on the same block. See the following\n * https://forum.openzeppelin.com/t/iterating-over-elements-on-enumerableset-in-openzeppelin-contracts/2296[forum post]\n * for more information.\n */\n function getRoleMember(bytes32 role, uint256 index) external view returns (address);\n\n /**\n * @dev Returns the number of accounts that have `role`. Can be used\n * together with {getRoleMember} to enumerate all bearers of a role.\n */\n function getRoleMemberCount(bytes32 role) external view returns (uint256);\n}\n" + }, + "@openzeppelin/contracts-upgradeable/access/IAccessControlUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (access/IAccessControl.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev External interface of AccessControl declared to support ERC165 detection.\n */\ninterface IAccessControlUpgradeable {\n /**\n * @dev Emitted when `newAdminRole` is set as ``role``'s admin role, replacing `previousAdminRole`\n *\n * `DEFAULT_ADMIN_ROLE` is the starting admin for all roles, despite\n * {RoleAdminChanged} not being emitted signaling this.\n *\n * _Available since v3.1._\n */\n event RoleAdminChanged(bytes32 indexed role, bytes32 indexed previousAdminRole, bytes32 indexed newAdminRole);\n\n /**\n * @dev Emitted when `account` is granted `role`.\n *\n * `sender` is the account that originated the contract call, an admin role\n * bearer except when using {AccessControl-_setupRole}.\n */\n event RoleGranted(bytes32 indexed role, address indexed account, address indexed sender);\n\n /**\n * @dev Emitted when `account` is revoked `role`.\n *\n * `sender` is the account that originated the contract call:\n * - if using `revokeRole`, it is the admin role bearer\n * - if using `renounceRole`, it is the role bearer (i.e. `account`)\n */\n event RoleRevoked(bytes32 indexed role, address indexed account, address indexed sender);\n\n /**\n * @dev Returns `true` if `account` has been granted `role`.\n */\n function hasRole(bytes32 role, address account) external view returns (bool);\n\n /**\n * @dev Returns the admin role that controls `role`. See {grantRole} and\n * {revokeRole}.\n *\n * To change a role's admin, use {AccessControl-_setRoleAdmin}.\n */\n function getRoleAdmin(bytes32 role) external view returns (bytes32);\n\n /**\n * @dev Grants `role` to `account`.\n *\n * If `account` had not been already granted `role`, emits a {RoleGranted}\n * event.\n *\n * Requirements:\n *\n * - the caller must have ``role``'s admin role.\n */\n function grantRole(bytes32 role, address account) external;\n\n /**\n * @dev Revokes `role` from `account`.\n *\n * If `account` had been granted `role`, emits a {RoleRevoked} event.\n *\n * Requirements:\n *\n * - the caller must have ``role``'s admin role.\n */\n function revokeRole(bytes32 role, address account) external;\n\n /**\n * @dev Revokes `role` from the calling account.\n *\n * Roles are often managed via {grantRole} and {revokeRole}: this function's\n * purpose is to provide a mechanism for accounts to lose their privileges\n * if they are compromised (such as when a trusted device is misplaced).\n *\n * If the calling account had been granted `role`, emits a {RoleRevoked}\n * event.\n *\n * Requirements:\n *\n * - the caller must be `account`.\n */\n function renounceRole(bytes32 role, address account) external;\n}\n" + }, + "@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (access/Ownable.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../utils/ContextUpgradeable.sol\";\nimport \"../proxy/utils/Initializable.sol\";\n\n/**\n * @dev Contract module which provides a basic access control mechanism, where\n * there is an account (an owner) that can be granted exclusive access to\n * specific functions.\n *\n * By default, the owner account will be the one that deploys the contract. This\n * can later be changed with {transferOwnership}.\n *\n * This module is used through inheritance. It will make available the modifier\n * `onlyOwner`, which can be applied to your functions to restrict their use to\n * the owner.\n */\nabstract contract OwnableUpgradeable is Initializable, ContextUpgradeable {\n address private _owner;\n\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\n\n /**\n * @dev Initializes the contract setting the deployer as the initial owner.\n */\n function __Ownable_init() internal onlyInitializing {\n __Ownable_init_unchained();\n }\n\n function __Ownable_init_unchained() internal onlyInitializing {\n _transferOwnership(_msgSender());\n }\n\n /**\n * @dev Throws if called by any account other than the owner.\n */\n modifier onlyOwner() {\n _checkOwner();\n _;\n }\n\n /**\n * @dev Returns the address of the current owner.\n */\n function owner() public view virtual returns (address) {\n return _owner;\n }\n\n /**\n * @dev Throws if the sender is not the owner.\n */\n function _checkOwner() internal view virtual {\n require(owner() == _msgSender(), \"Ownable: caller is not the owner\");\n }\n\n /**\n * @dev Leaves the contract without owner. It will not be possible to call\n * `onlyOwner` functions anymore. Can only be called by the current owner.\n *\n * NOTE: Renouncing ownership will leave the contract without an owner,\n * thereby removing any functionality that is only available to the owner.\n */\n function renounceOwnership() public virtual onlyOwner {\n _transferOwnership(address(0));\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Can only be called by the current owner.\n */\n function transferOwnership(address newOwner) public virtual onlyOwner {\n require(newOwner != address(0), \"Ownable: new owner is the zero address\");\n _transferOwnership(newOwner);\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Internal function without access restriction.\n */\n function _transferOwnership(address newOwner) internal virtual {\n address oldOwner = _owner;\n _owner = newOwner;\n emit OwnershipTransferred(oldOwner, newOwner);\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[49] private __gap;\n}\n" + }, + "@openzeppelin/contracts-upgradeable/interfaces/IERC721MetadataUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (interfaces/IERC721Metadata.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../token/ERC721/extensions/IERC721MetadataUpgradeable.sol\";\n" + }, + "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (proxy/utils/Initializable.sol)\n\npragma solidity ^0.8.2;\n\nimport \"../../utils/AddressUpgradeable.sol\";\n\n/**\n * @dev This is a base contract to aid in writing upgradeable contracts, or any kind of contract that will be deployed\n * behind a proxy. Since proxied contracts do not make use of a constructor, it's common to move constructor logic to an\n * external initializer function, usually called `initialize`. It then becomes necessary to protect this initializer\n * function so it can only be called once. The {initializer} modifier provided by this contract will have this effect.\n *\n * The initialization functions use a version number. Once a version number is used, it is consumed and cannot be\n * reused. This mechanism prevents re-execution of each \"step\" but allows the creation of new initialization steps in\n * case an upgrade adds a module that needs to be initialized.\n *\n * For example:\n *\n * [.hljs-theme-light.nopadding]\n * ```\n * contract MyToken is ERC20Upgradeable {\n * function initialize() initializer public {\n * __ERC20_init(\"MyToken\", \"MTK\");\n * }\n * }\n * contract MyTokenV2 is MyToken, ERC20PermitUpgradeable {\n * function initializeV2() reinitializer(2) public {\n * __ERC20Permit_init(\"MyToken\");\n * }\n * }\n * ```\n *\n * TIP: To avoid leaving the proxy in an uninitialized state, the initializer function should be called as early as\n * possible by providing the encoded function call as the `_data` argument to {ERC1967Proxy-constructor}.\n *\n * CAUTION: When used with inheritance, manual care must be taken to not invoke a parent initializer twice, or to ensure\n * that all initializers are idempotent. This is not verified automatically as constructors are by Solidity.\n *\n * [CAUTION]\n * ====\n * Avoid leaving a contract uninitialized.\n *\n * An uninitialized contract can be taken over by an attacker. This applies to both a proxy and its implementation\n * contract, which may impact the proxy. To prevent the implementation contract from being used, you should invoke\n * the {_disableInitializers} function in the constructor to automatically lock it when it is deployed:\n *\n * [.hljs-theme-light.nopadding]\n * ```\n * /// @custom:oz-upgrades-unsafe-allow constructor\n * constructor() {\n * _disableInitializers();\n * }\n * ```\n * ====\n */\nabstract contract Initializable {\n /**\n * @dev Indicates that the contract has been initialized.\n * @custom:oz-retyped-from bool\n */\n uint8 private _initialized;\n\n /**\n * @dev Indicates that the contract is in the process of being initialized.\n */\n bool private _initializing;\n\n /**\n * @dev Triggered when the contract has been initialized or reinitialized.\n */\n event Initialized(uint8 version);\n\n /**\n * @dev A modifier that defines a protected initializer function that can be invoked at most once. In its scope,\n * `onlyInitializing` functions can be used to initialize parent contracts. Equivalent to `reinitializer(1)`.\n */\n modifier initializer() {\n bool isTopLevelCall = !_initializing;\n require(\n (isTopLevelCall && _initialized < 1) || (!AddressUpgradeable.isContract(address(this)) && _initialized == 1),\n \"Initializable: contract is already initialized\"\n );\n _initialized = 1;\n if (isTopLevelCall) {\n _initializing = true;\n }\n _;\n if (isTopLevelCall) {\n _initializing = false;\n emit Initialized(1);\n }\n }\n\n /**\n * @dev A modifier that defines a protected reinitializer function that can be invoked at most once, and only if the\n * contract hasn't been initialized to a greater version before. In its scope, `onlyInitializing` functions can be\n * used to initialize parent contracts.\n *\n * `initializer` is equivalent to `reinitializer(1)`, so a reinitializer may be used after the original\n * initialization step. This is essential to configure modules that are added through upgrades and that require\n * initialization.\n *\n * Note that versions can jump in increments greater than 1; this implies that if multiple reinitializers coexist in\n * a contract, executing them in the right order is up to the developer or operator.\n */\n modifier reinitializer(uint8 version) {\n require(!_initializing && _initialized < version, \"Initializable: contract is already initialized\");\n _initialized = version;\n _initializing = true;\n _;\n _initializing = false;\n emit Initialized(version);\n }\n\n /**\n * @dev Modifier to protect an initialization function so that it can only be invoked by functions with the\n * {initializer} and {reinitializer} modifiers, directly or indirectly.\n */\n modifier onlyInitializing() {\n require(_initializing, \"Initializable: contract is not initializing\");\n _;\n }\n\n /**\n * @dev Locks the contract, preventing any future reinitialization. This cannot be part of an initializer call.\n * Calling this in the constructor of a contract will prevent that contract from being initialized or reinitialized\n * to any version. It is recommended to use this to lock implementation contracts that are designed to be called\n * through proxies.\n */\n function _disableInitializers() internal virtual {\n require(!_initializing, \"Initializable: contract is initializing\");\n if (_initialized < type(uint8).max) {\n _initialized = type(uint8).max;\n emit Initialized(type(uint8).max);\n }\n }\n}\n" + }, + "@openzeppelin/contracts-upgradeable/security/PausableUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (security/Pausable.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../utils/ContextUpgradeable.sol\";\nimport \"../proxy/utils/Initializable.sol\";\n\n/**\n * @dev Contract module which allows children to implement an emergency stop\n * mechanism that can be triggered by an authorized account.\n *\n * This module is used through inheritance. It will make available the\n * modifiers `whenNotPaused` and `whenPaused`, which can be applied to\n * the functions of your contract. Note that they will not be pausable by\n * simply including this module, only once the modifiers are put in place.\n */\nabstract contract PausableUpgradeable is Initializable, ContextUpgradeable {\n /**\n * @dev Emitted when the pause is triggered by `account`.\n */\n event Paused(address account);\n\n /**\n * @dev Emitted when the pause is lifted by `account`.\n */\n event Unpaused(address account);\n\n bool private _paused;\n\n /**\n * @dev Initializes the contract in unpaused state.\n */\n function __Pausable_init() internal onlyInitializing {\n __Pausable_init_unchained();\n }\n\n function __Pausable_init_unchained() internal onlyInitializing {\n _paused = false;\n }\n\n /**\n * @dev Modifier to make a function callable only when the contract is not paused.\n *\n * Requirements:\n *\n * - The contract must not be paused.\n */\n modifier whenNotPaused() {\n _requireNotPaused();\n _;\n }\n\n /**\n * @dev Modifier to make a function callable only when the contract is paused.\n *\n * Requirements:\n *\n * - The contract must be paused.\n */\n modifier whenPaused() {\n _requirePaused();\n _;\n }\n\n /**\n * @dev Returns true if the contract is paused, and false otherwise.\n */\n function paused() public view virtual returns (bool) {\n return _paused;\n }\n\n /**\n * @dev Throws if the contract is paused.\n */\n function _requireNotPaused() internal view virtual {\n require(!paused(), \"Pausable: paused\");\n }\n\n /**\n * @dev Throws if the contract is not paused.\n */\n function _requirePaused() internal view virtual {\n require(paused(), \"Pausable: not paused\");\n }\n\n /**\n * @dev Triggers stopped state.\n *\n * Requirements:\n *\n * - The contract must not be paused.\n */\n function _pause() internal virtual whenNotPaused {\n _paused = true;\n emit Paused(_msgSender());\n }\n\n /**\n * @dev Returns to normal state.\n *\n * Requirements:\n *\n * - The contract must be paused.\n */\n function _unpause() internal virtual whenPaused {\n _paused = false;\n emit Unpaused(_msgSender());\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[49] private __gap;\n}\n" + }, + "@openzeppelin/contracts-upgradeable/security/ReentrancyGuardUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (security/ReentrancyGuard.sol)\n\npragma solidity ^0.8.0;\nimport \"../proxy/utils/Initializable.sol\";\n\n/**\n * @dev Contract module that helps prevent reentrant calls to a function.\n *\n * Inheriting from `ReentrancyGuard` will make the {nonReentrant} modifier\n * available, which can be applied to functions to make sure there are no nested\n * (reentrant) calls to them.\n *\n * Note that because there is a single `nonReentrant` guard, functions marked as\n * `nonReentrant` may not call one another. This can be worked around by making\n * those functions `private`, and then adding `external` `nonReentrant` entry\n * points to them.\n *\n * TIP: If you would like to learn more about reentrancy and alternative ways\n * to protect against it, check out our blog post\n * https://blog.openzeppelin.com/reentrancy-after-istanbul/[Reentrancy After Istanbul].\n */\nabstract contract ReentrancyGuardUpgradeable is Initializable {\n // Booleans are more expensive than uint256 or any type that takes up a full\n // word because each write operation emits an extra SLOAD to first read the\n // slot's contents, replace the bits taken up by the boolean, and then write\n // back. This is the compiler's defense against contract upgrades and\n // pointer aliasing, and it cannot be disabled.\n\n // The values being non-zero value makes deployment a bit more expensive,\n // but in exchange the refund on every call to nonReentrant will be lower in\n // amount. Since refunds are capped to a percentage of the total\n // transaction's gas, it is best to keep them low in cases like this one, to\n // increase the likelihood of the full refund coming into effect.\n uint256 private constant _NOT_ENTERED = 1;\n uint256 private constant _ENTERED = 2;\n\n uint256 private _status;\n\n function __ReentrancyGuard_init() internal onlyInitializing {\n __ReentrancyGuard_init_unchained();\n }\n\n function __ReentrancyGuard_init_unchained() internal onlyInitializing {\n _status = _NOT_ENTERED;\n }\n\n /**\n * @dev Prevents a contract from calling itself, directly or indirectly.\n * Calling a `nonReentrant` function from another `nonReentrant`\n * function is not supported. It is possible to prevent this from happening\n * by making the `nonReentrant` function external, and making it call a\n * `private` function that does the actual work.\n */\n modifier nonReentrant() {\n // On the first call to nonReentrant, _notEntered will be true\n require(_status != _ENTERED, \"ReentrancyGuard: reentrant call\");\n\n // Any calls to nonReentrant after this point will fail\n _status = _ENTERED;\n\n _;\n\n // By storing the original value once again, a refund is triggered (see\n // https://eips.ethereum.org/EIPS/eip-2200)\n _status = _NOT_ENTERED;\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[49] private __gap;\n}\n" + }, + "@openzeppelin/contracts-upgradeable/token/ERC20/ERC20Upgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (token/ERC20/ERC20.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./IERC20Upgradeable.sol\";\nimport \"./extensions/IERC20MetadataUpgradeable.sol\";\nimport \"../../utils/ContextUpgradeable.sol\";\nimport \"../../proxy/utils/Initializable.sol\";\n\n/**\n * @dev Implementation of the {IERC20} interface.\n *\n * This implementation is agnostic to the way tokens are created. This means\n * that a supply mechanism has to be added in a derived contract using {_mint}.\n * For a generic mechanism see {ERC20PresetMinterPauser}.\n *\n * TIP: For a detailed writeup see our guide\n * https://forum.zeppelin.solutions/t/how-to-implement-erc20-supply-mechanisms/226[How\n * to implement supply mechanisms].\n *\n * We have followed general OpenZeppelin Contracts guidelines: functions revert\n * instead returning `false` on failure. This behavior is nonetheless\n * conventional and does not conflict with the expectations of ERC20\n * applications.\n *\n * Additionally, an {Approval} event is emitted on calls to {transferFrom}.\n * This allows applications to reconstruct the allowance for all accounts just\n * by listening to said events. Other implementations of the EIP may not emit\n * these events, as it isn't required by the specification.\n *\n * Finally, the non-standard {decreaseAllowance} and {increaseAllowance}\n * functions have been added to mitigate the well-known issues around setting\n * allowances. See {IERC20-approve}.\n */\ncontract ERC20Upgradeable is Initializable, ContextUpgradeable, IERC20Upgradeable, IERC20MetadataUpgradeable {\n mapping(address => uint256) private _balances;\n\n mapping(address => mapping(address => uint256)) private _allowances;\n\n uint256 private _totalSupply;\n\n string private _name;\n string private _symbol;\n\n /**\n * @dev Sets the values for {name} and {symbol}.\n *\n * The default value of {decimals} is 18. To select a different value for\n * {decimals} you should overload it.\n *\n * All two of these values are immutable: they can only be set once during\n * construction.\n */\n function __ERC20_init(string memory name_, string memory symbol_) internal onlyInitializing {\n __ERC20_init_unchained(name_, symbol_);\n }\n\n function __ERC20_init_unchained(string memory name_, string memory symbol_) internal onlyInitializing {\n _name = name_;\n _symbol = symbol_;\n }\n\n /**\n * @dev Returns the name of the token.\n */\n function name() public view virtual override returns (string memory) {\n return _name;\n }\n\n /**\n * @dev Returns the symbol of the token, usually a shorter version of the\n * name.\n */\n function symbol() public view virtual override returns (string memory) {\n return _symbol;\n }\n\n /**\n * @dev Returns the number of decimals used to get its user representation.\n * For example, if `decimals` equals `2`, a balance of `505` tokens should\n * be displayed to a user as `5.05` (`505 / 10 ** 2`).\n *\n * Tokens usually opt for a value of 18, imitating the relationship between\n * Ether and Wei. This is the value {ERC20} uses, unless this function is\n * overridden;\n *\n * NOTE: This information is only used for _display_ purposes: it in\n * no way affects any of the arithmetic of the contract, including\n * {IERC20-balanceOf} and {IERC20-transfer}.\n */\n function decimals() public view virtual override returns (uint8) {\n return 18;\n }\n\n /**\n * @dev See {IERC20-totalSupply}.\n */\n function totalSupply() public view virtual override returns (uint256) {\n return _totalSupply;\n }\n\n /**\n * @dev See {IERC20-balanceOf}.\n */\n function balanceOf(address account) public view virtual override returns (uint256) {\n return _balances[account];\n }\n\n /**\n * @dev See {IERC20-transfer}.\n *\n * Requirements:\n *\n * - `to` cannot be the zero address.\n * - the caller must have a balance of at least `amount`.\n */\n function transfer(address to, uint256 amount) public virtual override returns (bool) {\n address owner = _msgSender();\n _transfer(owner, to, amount);\n return true;\n }\n\n /**\n * @dev See {IERC20-allowance}.\n */\n function allowance(address owner, address spender) public view virtual override returns (uint256) {\n return _allowances[owner][spender];\n }\n\n /**\n * @dev See {IERC20-approve}.\n *\n * NOTE: If `amount` is the maximum `uint256`, the allowance is not updated on\n * `transferFrom`. This is semantically equivalent to an infinite approval.\n *\n * Requirements:\n *\n * - `spender` cannot be the zero address.\n */\n function approve(address spender, uint256 amount) public virtual override returns (bool) {\n address owner = _msgSender();\n _approve(owner, spender, amount);\n return true;\n }\n\n /**\n * @dev See {IERC20-transferFrom}.\n *\n * Emits an {Approval} event indicating the updated allowance. This is not\n * required by the EIP. See the note at the beginning of {ERC20}.\n *\n * NOTE: Does not update the allowance if the current allowance\n * is the maximum `uint256`.\n *\n * Requirements:\n *\n * - `from` and `to` cannot be the zero address.\n * - `from` must have a balance of at least `amount`.\n * - the caller must have allowance for ``from``'s tokens of at least\n * `amount`.\n */\n function transferFrom(\n address from,\n address to,\n uint256 amount\n ) public virtual override returns (bool) {\n address spender = _msgSender();\n _spendAllowance(from, spender, amount);\n _transfer(from, to, amount);\n return true;\n }\n\n /**\n * @dev Atomically increases the allowance granted to `spender` by the caller.\n *\n * This is an alternative to {approve} that can be used as a mitigation for\n * problems described in {IERC20-approve}.\n *\n * Emits an {Approval} event indicating the updated allowance.\n *\n * Requirements:\n *\n * - `spender` cannot be the zero address.\n */\n function increaseAllowance(address spender, uint256 addedValue) public virtual returns (bool) {\n address owner = _msgSender();\n _approve(owner, spender, allowance(owner, spender) + addedValue);\n return true;\n }\n\n /**\n * @dev Atomically decreases the allowance granted to `spender` by the caller.\n *\n * This is an alternative to {approve} that can be used as a mitigation for\n * problems described in {IERC20-approve}.\n *\n * Emits an {Approval} event indicating the updated allowance.\n *\n * Requirements:\n *\n * - `spender` cannot be the zero address.\n * - `spender` must have allowance for the caller of at least\n * `subtractedValue`.\n */\n function decreaseAllowance(address spender, uint256 subtractedValue) public virtual returns (bool) {\n address owner = _msgSender();\n uint256 currentAllowance = allowance(owner, spender);\n require(currentAllowance >= subtractedValue, \"ERC20: decreased allowance below zero\");\n unchecked {\n _approve(owner, spender, currentAllowance - subtractedValue);\n }\n\n return true;\n }\n\n /**\n * @dev Moves `amount` of tokens from `from` to `to`.\n *\n * This internal function is equivalent to {transfer}, and can be used to\n * e.g. implement automatic token fees, slashing mechanisms, etc.\n *\n * Emits a {Transfer} event.\n *\n * Requirements:\n *\n * - `from` cannot be the zero address.\n * - `to` cannot be the zero address.\n * - `from` must have a balance of at least `amount`.\n */\n function _transfer(\n address from,\n address to,\n uint256 amount\n ) internal virtual {\n require(from != address(0), \"ERC20: transfer from the zero address\");\n require(to != address(0), \"ERC20: transfer to the zero address\");\n\n _beforeTokenTransfer(from, to, amount);\n\n uint256 fromBalance = _balances[from];\n require(fromBalance >= amount, \"ERC20: transfer amount exceeds balance\");\n unchecked {\n _balances[from] = fromBalance - amount;\n }\n _balances[to] += amount;\n\n emit Transfer(from, to, amount);\n\n _afterTokenTransfer(from, to, amount);\n }\n\n /** @dev Creates `amount` tokens and assigns them to `account`, increasing\n * the total supply.\n *\n * Emits a {Transfer} event with `from` set to the zero address.\n *\n * Requirements:\n *\n * - `account` cannot be the zero address.\n */\n function _mint(address account, uint256 amount) internal virtual {\n require(account != address(0), \"ERC20: mint to the zero address\");\n\n _beforeTokenTransfer(address(0), account, amount);\n\n _totalSupply += amount;\n _balances[account] += amount;\n emit Transfer(address(0), account, amount);\n\n _afterTokenTransfer(address(0), account, amount);\n }\n\n /**\n * @dev Destroys `amount` tokens from `account`, reducing the\n * total supply.\n *\n * Emits a {Transfer} event with `to` set to the zero address.\n *\n * Requirements:\n *\n * - `account` cannot be the zero address.\n * - `account` must have at least `amount` tokens.\n */\n function _burn(address account, uint256 amount) internal virtual {\n require(account != address(0), \"ERC20: burn from the zero address\");\n\n _beforeTokenTransfer(account, address(0), amount);\n\n uint256 accountBalance = _balances[account];\n require(accountBalance >= amount, \"ERC20: burn amount exceeds balance\");\n unchecked {\n _balances[account] = accountBalance - amount;\n }\n _totalSupply -= amount;\n\n emit Transfer(account, address(0), amount);\n\n _afterTokenTransfer(account, address(0), amount);\n }\n\n /**\n * @dev Sets `amount` as the allowance of `spender` over the `owner` s tokens.\n *\n * This internal function is equivalent to `approve`, and can be used to\n * e.g. set automatic allowances for certain subsystems, etc.\n *\n * Emits an {Approval} event.\n *\n * Requirements:\n *\n * - `owner` cannot be the zero address.\n * - `spender` cannot be the zero address.\n */\n function _approve(\n address owner,\n address spender,\n uint256 amount\n ) internal virtual {\n require(owner != address(0), \"ERC20: approve from the zero address\");\n require(spender != address(0), \"ERC20: approve to the zero address\");\n\n _allowances[owner][spender] = amount;\n emit Approval(owner, spender, amount);\n }\n\n /**\n * @dev Updates `owner` s allowance for `spender` based on spent `amount`.\n *\n * Does not update the allowance amount in case of infinite allowance.\n * Revert if not enough allowance is available.\n *\n * Might emit an {Approval} event.\n */\n function _spendAllowance(\n address owner,\n address spender,\n uint256 amount\n ) internal virtual {\n uint256 currentAllowance = allowance(owner, spender);\n if (currentAllowance != type(uint256).max) {\n require(currentAllowance >= amount, \"ERC20: insufficient allowance\");\n unchecked {\n _approve(owner, spender, currentAllowance - amount);\n }\n }\n }\n\n /**\n * @dev Hook that is called before any transfer of tokens. This includes\n * minting and burning.\n *\n * Calling conditions:\n *\n * - when `from` and `to` are both non-zero, `amount` of ``from``'s tokens\n * will be transferred to `to`.\n * - when `from` is zero, `amount` tokens will be minted for `to`.\n * - when `to` is zero, `amount` of ``from``'s tokens will be burned.\n * - `from` and `to` are never both zero.\n *\n * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].\n */\n function _beforeTokenTransfer(\n address from,\n address to,\n uint256 amount\n ) internal virtual {}\n\n /**\n * @dev Hook that is called after any transfer of tokens. This includes\n * minting and burning.\n *\n * Calling conditions:\n *\n * - when `from` and `to` are both non-zero, `amount` of ``from``'s tokens\n * has been transferred to `to`.\n * - when `from` is zero, `amount` tokens have been minted for `to`.\n * - when `to` is zero, `amount` of ``from``'s tokens have been burned.\n * - `from` and `to` are never both zero.\n *\n * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].\n */\n function _afterTokenTransfer(\n address from,\n address to,\n uint256 amount\n ) internal virtual {}\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[45] private __gap;\n}\n" + }, + "@openzeppelin/contracts-upgradeable/token/ERC20/extensions/draft-ERC20PermitUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.6.0) (token/ERC20/extensions/draft-ERC20Permit.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./draft-IERC20PermitUpgradeable.sol\";\nimport \"../ERC20Upgradeable.sol\";\nimport \"../../../utils/cryptography/draft-EIP712Upgradeable.sol\";\nimport \"../../../utils/cryptography/ECDSAUpgradeable.sol\";\nimport \"../../../utils/CountersUpgradeable.sol\";\nimport \"../../../proxy/utils/Initializable.sol\";\n\n/**\n * @dev Implementation of the ERC20 Permit extension allowing approvals to be made via signatures, as defined in\n * https://eips.ethereum.org/EIPS/eip-2612[EIP-2612].\n *\n * Adds the {permit} method, which can be used to change an account's ERC20 allowance (see {IERC20-allowance}) by\n * presenting a message signed by the account. By not relying on `{IERC20-approve}`, the token holder account doesn't\n * need to send a transaction, and thus is not required to hold Ether at all.\n *\n * _Available since v3.4._\n *\n * @custom:storage-size 51\n */\nabstract contract ERC20PermitUpgradeable is Initializable, ERC20Upgradeable, IERC20PermitUpgradeable, EIP712Upgradeable {\n using CountersUpgradeable for CountersUpgradeable.Counter;\n\n mapping(address => CountersUpgradeable.Counter) private _nonces;\n\n // solhint-disable-next-line var-name-mixedcase\n bytes32 private constant _PERMIT_TYPEHASH =\n keccak256(\"Permit(address owner,address spender,uint256 value,uint256 nonce,uint256 deadline)\");\n /**\n * @dev In previous versions `_PERMIT_TYPEHASH` was declared as `immutable`.\n * However, to ensure consistency with the upgradeable transpiler, we will continue\n * to reserve a slot.\n * @custom:oz-renamed-from _PERMIT_TYPEHASH\n */\n // solhint-disable-next-line var-name-mixedcase\n bytes32 private _PERMIT_TYPEHASH_DEPRECATED_SLOT;\n\n /**\n * @dev Initializes the {EIP712} domain separator using the `name` parameter, and setting `version` to `\"1\"`.\n *\n * It's a good idea to use the same `name` that is defined as the ERC20 token name.\n */\n function __ERC20Permit_init(string memory name) internal onlyInitializing {\n __EIP712_init_unchained(name, \"1\");\n }\n\n function __ERC20Permit_init_unchained(string memory) internal onlyInitializing {}\n\n /**\n * @dev See {IERC20Permit-permit}.\n */\n function permit(\n address owner,\n address spender,\n uint256 value,\n uint256 deadline,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) public virtual override {\n require(block.timestamp <= deadline, \"ERC20Permit: expired deadline\");\n\n bytes32 structHash = keccak256(abi.encode(_PERMIT_TYPEHASH, owner, spender, value, _useNonce(owner), deadline));\n\n bytes32 hash = _hashTypedDataV4(structHash);\n\n address signer = ECDSAUpgradeable.recover(hash, v, r, s);\n require(signer == owner, \"ERC20Permit: invalid signature\");\n\n _approve(owner, spender, value);\n }\n\n /**\n * @dev See {IERC20Permit-nonces}.\n */\n function nonces(address owner) public view virtual override returns (uint256) {\n return _nonces[owner].current();\n }\n\n /**\n * @dev See {IERC20Permit-DOMAIN_SEPARATOR}.\n */\n // solhint-disable-next-line func-name-mixedcase\n function DOMAIN_SEPARATOR() external view override returns (bytes32) {\n return _domainSeparatorV4();\n }\n\n /**\n * @dev \"Consume a nonce\": return the current value and increment.\n *\n * _Available since v4.1._\n */\n function _useNonce(address owner) internal virtual returns (uint256 current) {\n CountersUpgradeable.Counter storage nonce = _nonces[owner];\n current = nonce.current();\n nonce.increment();\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[49] private __gap;\n}\n" + }, + "@openzeppelin/contracts-upgradeable/token/ERC20/extensions/draft-IERC20PermitUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (token/ERC20/extensions/draft-IERC20Permit.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Interface of the ERC20 Permit extension allowing approvals to be made via signatures, as defined in\n * https://eips.ethereum.org/EIPS/eip-2612[EIP-2612].\n *\n * Adds the {permit} method, which can be used to change an account's ERC20 allowance (see {IERC20-allowance}) by\n * presenting a message signed by the account. By not relying on {IERC20-approve}, the token holder account doesn't\n * need to send a transaction, and thus is not required to hold Ether at all.\n */\ninterface IERC20PermitUpgradeable {\n /**\n * @dev Sets `value` as the allowance of `spender` over ``owner``'s tokens,\n * given ``owner``'s signed approval.\n *\n * IMPORTANT: The same issues {IERC20-approve} has related to transaction\n * ordering also apply here.\n *\n * Emits an {Approval} event.\n *\n * Requirements:\n *\n * - `spender` cannot be the zero address.\n * - `deadline` must be a timestamp in the future.\n * - `v`, `r` and `s` must be a valid `secp256k1` signature from `owner`\n * over the EIP712-formatted function arguments.\n * - the signature must use ``owner``'s current nonce (see {nonces}).\n *\n * For more information on the signature format, see the\n * https://eips.ethereum.org/EIPS/eip-2612#specification[relevant EIP\n * section].\n */\n function permit(\n address owner,\n address spender,\n uint256 value,\n uint256 deadline,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) external;\n\n /**\n * @dev Returns the current nonce for `owner`. This value must be\n * included whenever a signature is generated for {permit}.\n *\n * Every successful call to {permit} increases ``owner``'s nonce by one. This\n * prevents a signature from being used multiple times.\n */\n function nonces(address owner) external view returns (uint256);\n\n /**\n * @dev Returns the domain separator used in the encoding of the signature for {permit}, as defined by {EIP712}.\n */\n // solhint-disable-next-line func-name-mixedcase\n function DOMAIN_SEPARATOR() external view returns (bytes32);\n}\n" + }, + "@openzeppelin/contracts-upgradeable/token/ERC20/extensions/IERC20MetadataUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (token/ERC20/extensions/IERC20Metadata.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../IERC20Upgradeable.sol\";\n\n/**\n * @dev Interface for the optional metadata functions from the ERC20 standard.\n *\n * _Available since v4.1._\n */\ninterface IERC20MetadataUpgradeable is IERC20Upgradeable {\n /**\n * @dev Returns the name of the token.\n */\n function name() external view returns (string memory);\n\n /**\n * @dev Returns the symbol of the token.\n */\n function symbol() external view returns (string memory);\n\n /**\n * @dev Returns the decimals places of the token.\n */\n function decimals() external view returns (uint8);\n}\n" + }, + "@openzeppelin/contracts-upgradeable/token/ERC20/IERC20Upgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.6.0) (token/ERC20/IERC20.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Interface of the ERC20 standard as defined in the EIP.\n */\ninterface IERC20Upgradeable {\n /**\n * @dev Emitted when `value` tokens are moved from one account (`from`) to\n * another (`to`).\n *\n * Note that `value` may be zero.\n */\n event Transfer(address indexed from, address indexed to, uint256 value);\n\n /**\n * @dev Emitted when the allowance of a `spender` for an `owner` is set by\n * a call to {approve}. `value` is the new allowance.\n */\n event Approval(address indexed owner, address indexed spender, uint256 value);\n\n /**\n * @dev Returns the amount of tokens in existence.\n */\n function totalSupply() external view returns (uint256);\n\n /**\n * @dev Returns the amount of tokens owned by `account`.\n */\n function balanceOf(address account) external view returns (uint256);\n\n /**\n * @dev Moves `amount` tokens from the caller's account to `to`.\n *\n * Returns a boolean value indicating whether the operation succeeded.\n *\n * Emits a {Transfer} event.\n */\n function transfer(address to, uint256 amount) external returns (bool);\n\n /**\n * @dev Returns the remaining number of tokens that `spender` will be\n * allowed to spend on behalf of `owner` through {transferFrom}. This is\n * zero by default.\n *\n * This value changes when {approve} or {transferFrom} are called.\n */\n function allowance(address owner, address spender) external view returns (uint256);\n\n /**\n * @dev Sets `amount` as the allowance of `spender` over the caller's tokens.\n *\n * Returns a boolean value indicating whether the operation succeeded.\n *\n * IMPORTANT: Beware that changing an allowance with this method brings the risk\n * that someone may use both the old and the new allowance by unfortunate\n * transaction ordering. One possible solution to mitigate this race\n * condition is to first reduce the spender's allowance to 0 and set the\n * desired value afterwards:\n * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729\n *\n * Emits an {Approval} event.\n */\n function approve(address spender, uint256 amount) external returns (bool);\n\n /**\n * @dev Moves `amount` tokens from `from` to `to` using the\n * allowance mechanism. `amount` is then deducted from the caller's\n * allowance.\n *\n * Returns a boolean value indicating whether the operation succeeded.\n *\n * Emits a {Transfer} event.\n */\n function transferFrom(\n address from,\n address to,\n uint256 amount\n ) external returns (bool);\n}\n" + }, + "@openzeppelin/contracts-upgradeable/token/ERC721/extensions/IERC721MetadataUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (token/ERC721/extensions/IERC721Metadata.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../IERC721Upgradeable.sol\";\n\n/**\n * @title ERC-721 Non-Fungible Token Standard, optional metadata extension\n * @dev See https://eips.ethereum.org/EIPS/eip-721\n */\ninterface IERC721MetadataUpgradeable is IERC721Upgradeable {\n /**\n * @dev Returns the token collection name.\n */\n function name() external view returns (string memory);\n\n /**\n * @dev Returns the token collection symbol.\n */\n function symbol() external view returns (string memory);\n\n /**\n * @dev Returns the Uniform Resource Identifier (URI) for `tokenId` token.\n */\n function tokenURI(uint256 tokenId) external view returns (string memory);\n}\n" + }, + "@openzeppelin/contracts-upgradeable/token/ERC721/IERC721ReceiverUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.6.0) (token/ERC721/IERC721Receiver.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @title ERC721 token receiver interface\n * @dev Interface for any contract that wants to support safeTransfers\n * from ERC721 asset contracts.\n */\ninterface IERC721ReceiverUpgradeable {\n /**\n * @dev Whenever an {IERC721} `tokenId` token is transferred to this contract via {IERC721-safeTransferFrom}\n * by `operator` from `from`, this function is called.\n *\n * It must return its Solidity selector to confirm the token transfer.\n * If any other value is returned or the interface is not implemented by the recipient, the transfer will be reverted.\n *\n * The selector can be obtained in Solidity with `IERC721Receiver.onERC721Received.selector`.\n */\n function onERC721Received(\n address operator,\n address from,\n uint256 tokenId,\n bytes calldata data\n ) external returns (bytes4);\n}\n" + }, + "@openzeppelin/contracts-upgradeable/token/ERC721/IERC721Upgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (token/ERC721/IERC721.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../../utils/introspection/IERC165Upgradeable.sol\";\n\n/**\n * @dev Required interface of an ERC721 compliant contract.\n */\ninterface IERC721Upgradeable is IERC165Upgradeable {\n /**\n * @dev Emitted when `tokenId` token is transferred from `from` to `to`.\n */\n event Transfer(address indexed from, address indexed to, uint256 indexed tokenId);\n\n /**\n * @dev Emitted when `owner` enables `approved` to manage the `tokenId` token.\n */\n event Approval(address indexed owner, address indexed approved, uint256 indexed tokenId);\n\n /**\n * @dev Emitted when `owner` enables or disables (`approved`) `operator` to manage all of its assets.\n */\n event ApprovalForAll(address indexed owner, address indexed operator, bool approved);\n\n /**\n * @dev Returns the number of tokens in ``owner``'s account.\n */\n function balanceOf(address owner) external view returns (uint256 balance);\n\n /**\n * @dev Returns the owner of the `tokenId` token.\n *\n * Requirements:\n *\n * - `tokenId` must exist.\n */\n function ownerOf(uint256 tokenId) external view returns (address owner);\n\n /**\n * @dev Safely transfers `tokenId` token from `from` to `to`.\n *\n * Requirements:\n *\n * - `from` cannot be the zero address.\n * - `to` cannot be the zero address.\n * - `tokenId` token must exist and be owned by `from`.\n * - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}.\n * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.\n *\n * Emits a {Transfer} event.\n */\n function safeTransferFrom(\n address from,\n address to,\n uint256 tokenId,\n bytes calldata data\n ) external;\n\n /**\n * @dev Safely transfers `tokenId` token from `from` to `to`, checking first that contract recipients\n * are aware of the ERC721 protocol to prevent tokens from being forever locked.\n *\n * Requirements:\n *\n * - `from` cannot be the zero address.\n * - `to` cannot be the zero address.\n * - `tokenId` token must exist and be owned by `from`.\n * - If the caller is not `from`, it must have been allowed to move this token by either {approve} or {setApprovalForAll}.\n * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.\n *\n * Emits a {Transfer} event.\n */\n function safeTransferFrom(\n address from,\n address to,\n uint256 tokenId\n ) external;\n\n /**\n * @dev Transfers `tokenId` token from `from` to `to`.\n *\n * WARNING: Usage of this method is discouraged, use {safeTransferFrom} whenever possible.\n *\n * Requirements:\n *\n * - `from` cannot be the zero address.\n * - `to` cannot be the zero address.\n * - `tokenId` token must be owned by `from`.\n * - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}.\n *\n * Emits a {Transfer} event.\n */\n function transferFrom(\n address from,\n address to,\n uint256 tokenId\n ) external;\n\n /**\n * @dev Gives permission to `to` to transfer `tokenId` token to another account.\n * The approval is cleared when the token is transferred.\n *\n * Only a single account can be approved at a time, so approving the zero address clears previous approvals.\n *\n * Requirements:\n *\n * - The caller must own the token or be an approved operator.\n * - `tokenId` must exist.\n *\n * Emits an {Approval} event.\n */\n function approve(address to, uint256 tokenId) external;\n\n /**\n * @dev Approve or remove `operator` as an operator for the caller.\n * Operators can call {transferFrom} or {safeTransferFrom} for any token owned by the caller.\n *\n * Requirements:\n *\n * - The `operator` cannot be the caller.\n *\n * Emits an {ApprovalForAll} event.\n */\n function setApprovalForAll(address operator, bool _approved) external;\n\n /**\n * @dev Returns the account approved for `tokenId` token.\n *\n * Requirements:\n *\n * - `tokenId` must exist.\n */\n function getApproved(uint256 tokenId) external view returns (address operator);\n\n /**\n * @dev Returns if the `operator` is allowed to manage all of the assets of `owner`.\n *\n * See {setApprovalForAll}\n */\n function isApprovedForAll(address owner, address operator) external view returns (bool);\n}\n" + }, + "@openzeppelin/contracts-upgradeable/utils/AddressUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (utils/Address.sol)\n\npragma solidity ^0.8.1;\n\n/**\n * @dev Collection of functions related to the address type\n */\nlibrary AddressUpgradeable {\n /**\n * @dev Returns true if `account` is a contract.\n *\n * [IMPORTANT]\n * ====\n * It is unsafe to assume that an address for which this function returns\n * false is an externally-owned account (EOA) and not a contract.\n *\n * Among others, `isContract` will return false for the following\n * types of addresses:\n *\n * - an externally-owned account\n * - a contract in construction\n * - an address where a contract will be created\n * - an address where a contract lived, but was destroyed\n * ====\n *\n * [IMPORTANT]\n * ====\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\n *\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\n * constructor.\n * ====\n */\n function isContract(address account) internal view returns (bool) {\n // This method relies on extcodesize/address.code.length, which returns 0\n // for contracts in construction, since the code is only stored at the end\n // of the constructor execution.\n\n return account.code.length > 0;\n }\n\n /**\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\n * `recipient`, forwarding all available gas and reverting on errors.\n *\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\n * imposed by `transfer`, making them unable to receive funds via\n * `transfer`. {sendValue} removes this limitation.\n *\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\n *\n * IMPORTANT: because control is transferred to `recipient`, care must be\n * taken to not create reentrancy vulnerabilities. Consider using\n * {ReentrancyGuard} or the\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\n */\n function sendValue(address payable recipient, uint256 amount) internal {\n require(address(this).balance >= amount, \"Address: insufficient balance\");\n\n (bool success, ) = recipient.call{value: amount}(\"\");\n require(success, \"Address: unable to send value, recipient may have reverted\");\n }\n\n /**\n * @dev Performs a Solidity function call using a low level `call`. A\n * plain `call` is an unsafe replacement for a function call: use this\n * function instead.\n *\n * If `target` reverts with a revert reason, it is bubbled up by this\n * function (like regular Solidity function calls).\n *\n * Returns the raw returned data. To convert to the expected return value,\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\n *\n * Requirements:\n *\n * - `target` must be a contract.\n * - calling `target` with `data` must not revert.\n *\n * _Available since v3.1._\n */\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionCall(target, data, \"Address: low-level call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\n * `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, 0, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but also transferring `value` wei to `target`.\n *\n * Requirements:\n *\n * - the calling contract must have an ETH balance of at least `value`.\n * - the called Solidity function must be `payable`.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, value, \"Address: low-level call with value failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\n * with `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(address(this).balance >= value, \"Address: insufficient balance for call\");\n require(isContract(target), \"Address: call to non-contract\");\n\n (bool success, bytes memory returndata) = target.call{value: value}(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\n return functionStaticCall(target, data, \"Address: low-level static call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal view returns (bytes memory) {\n require(isContract(target), \"Address: static call to non-contract\");\n\n (bool success, bytes memory returndata) = target.staticcall(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the\n * revert reason using the provided one.\n *\n * _Available since v4.3._\n */\n function verifyCallResult(\n bool success,\n bytes memory returndata,\n string memory errorMessage\n ) internal pure returns (bytes memory) {\n if (success) {\n return returndata;\n } else {\n // Look for revert reason and bubble it up if present\n if (returndata.length > 0) {\n // The easiest way to bubble the revert reason is using memory via assembly\n /// @solidity memory-safe-assembly\n assembly {\n let returndata_size := mload(returndata)\n revert(add(32, returndata), returndata_size)\n }\n } else {\n revert(errorMessage);\n }\n }\n }\n}\n" + }, + "@openzeppelin/contracts-upgradeable/utils/ContextUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)\n\npragma solidity ^0.8.0;\nimport \"../proxy/utils/Initializable.sol\";\n\n/**\n * @dev Provides information about the current execution context, including the\n * sender of the transaction and its data. While these are generally available\n * via msg.sender and msg.data, they should not be accessed in such a direct\n * manner, since when dealing with meta-transactions the account sending and\n * paying for execution may not be the actual sender (as far as an application\n * is concerned).\n *\n * This contract is only required for intermediate, library-like contracts.\n */\nabstract contract ContextUpgradeable is Initializable {\n function __Context_init() internal onlyInitializing {\n }\n\n function __Context_init_unchained() internal onlyInitializing {\n }\n function _msgSender() internal view virtual returns (address) {\n return msg.sender;\n }\n\n function _msgData() internal view virtual returns (bytes calldata) {\n return msg.data;\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[50] private __gap;\n}\n" + }, + "@openzeppelin/contracts-upgradeable/utils/CountersUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (utils/Counters.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @title Counters\n * @author Matt Condon (@shrugs)\n * @dev Provides counters that can only be incremented, decremented or reset. This can be used e.g. to track the number\n * of elements in a mapping, issuing ERC721 ids, or counting request ids.\n *\n * Include with `using Counters for Counters.Counter;`\n */\nlibrary CountersUpgradeable {\n struct Counter {\n // This variable should never be directly accessed by users of the library: interactions must be restricted to\n // the library's function. As of Solidity v0.5.2, this cannot be enforced, though there is a proposal to add\n // this feature: see https://github.com/ethereum/solidity/issues/4637\n uint256 _value; // default: 0\n }\n\n function current(Counter storage counter) internal view returns (uint256) {\n return counter._value;\n }\n\n function increment(Counter storage counter) internal {\n unchecked {\n counter._value += 1;\n }\n }\n\n function decrement(Counter storage counter) internal {\n uint256 value = counter._value;\n require(value > 0, \"Counter: decrement overflow\");\n unchecked {\n counter._value = value - 1;\n }\n }\n\n function reset(Counter storage counter) internal {\n counter._value = 0;\n }\n}\n" + }, + "@openzeppelin/contracts-upgradeable/utils/cryptography/draft-EIP712Upgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (utils/cryptography/draft-EIP712.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./ECDSAUpgradeable.sol\";\nimport \"../../proxy/utils/Initializable.sol\";\n\n/**\n * @dev https://eips.ethereum.org/EIPS/eip-712[EIP 712] is a standard for hashing and signing of typed structured data.\n *\n * The encoding specified in the EIP is very generic, and such a generic implementation in Solidity is not feasible,\n * thus this contract does not implement the encoding itself. Protocols need to implement the type-specific encoding\n * they need in their contracts using a combination of `abi.encode` and `keccak256`.\n *\n * This contract implements the EIP 712 domain separator ({_domainSeparatorV4}) that is used as part of the encoding\n * scheme, and the final step of the encoding to obtain the message digest that is then signed via ECDSA\n * ({_hashTypedDataV4}).\n *\n * The implementation of the domain separator was designed to be as efficient as possible while still properly updating\n * the chain id to protect against replay attacks on an eventual fork of the chain.\n *\n * NOTE: This contract implements the version of the encoding known as \"v4\", as implemented by the JSON RPC method\n * https://docs.metamask.io/guide/signing-data.html[`eth_signTypedDataV4` in MetaMask].\n *\n * _Available since v3.4._\n *\n * @custom:storage-size 52\n */\nabstract contract EIP712Upgradeable is Initializable {\n /* solhint-disable var-name-mixedcase */\n bytes32 private _HASHED_NAME;\n bytes32 private _HASHED_VERSION;\n bytes32 private constant _TYPE_HASH = keccak256(\"EIP712Domain(string name,string version,uint256 chainId,address verifyingContract)\");\n\n /* solhint-enable var-name-mixedcase */\n\n /**\n * @dev Initializes the domain separator and parameter caches.\n *\n * The meaning of `name` and `version` is specified in\n * https://eips.ethereum.org/EIPS/eip-712#definition-of-domainseparator[EIP 712]:\n *\n * - `name`: the user readable name of the signing domain, i.e. the name of the DApp or the protocol.\n * - `version`: the current major version of the signing domain.\n *\n * NOTE: These parameters cannot be changed except through a xref:learn::upgrading-smart-contracts.adoc[smart\n * contract upgrade].\n */\n function __EIP712_init(string memory name, string memory version) internal onlyInitializing {\n __EIP712_init_unchained(name, version);\n }\n\n function __EIP712_init_unchained(string memory name, string memory version) internal onlyInitializing {\n bytes32 hashedName = keccak256(bytes(name));\n bytes32 hashedVersion = keccak256(bytes(version));\n _HASHED_NAME = hashedName;\n _HASHED_VERSION = hashedVersion;\n }\n\n /**\n * @dev Returns the domain separator for the current chain.\n */\n function _domainSeparatorV4() internal view returns (bytes32) {\n return _buildDomainSeparator(_TYPE_HASH, _EIP712NameHash(), _EIP712VersionHash());\n }\n\n function _buildDomainSeparator(\n bytes32 typeHash,\n bytes32 nameHash,\n bytes32 versionHash\n ) private view returns (bytes32) {\n return keccak256(abi.encode(typeHash, nameHash, versionHash, block.chainid, address(this)));\n }\n\n /**\n * @dev Given an already https://eips.ethereum.org/EIPS/eip-712#definition-of-hashstruct[hashed struct], this\n * function returns the hash of the fully encoded EIP712 message for this domain.\n *\n * This hash can be used together with {ECDSA-recover} to obtain the signer of a message. For example:\n *\n * ```solidity\n * bytes32 digest = _hashTypedDataV4(keccak256(abi.encode(\n * keccak256(\"Mail(address to,string contents)\"),\n * mailTo,\n * keccak256(bytes(mailContents))\n * )));\n * address signer = ECDSA.recover(digest, signature);\n * ```\n */\n function _hashTypedDataV4(bytes32 structHash) internal view virtual returns (bytes32) {\n return ECDSAUpgradeable.toTypedDataHash(_domainSeparatorV4(), structHash);\n }\n\n /**\n * @dev The hash of the name parameter for the EIP712 domain.\n *\n * NOTE: This function reads from storage by default, but can be redefined to return a constant value if gas costs\n * are a concern.\n */\n function _EIP712NameHash() internal virtual view returns (bytes32) {\n return _HASHED_NAME;\n }\n\n /**\n * @dev The hash of the version parameter for the EIP712 domain.\n *\n * NOTE: This function reads from storage by default, but can be redefined to return a constant value if gas costs\n * are a concern.\n */\n function _EIP712VersionHash() internal virtual view returns (bytes32) {\n return _HASHED_VERSION;\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[50] private __gap;\n}\n" + }, + "@openzeppelin/contracts-upgradeable/utils/cryptography/ECDSAUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (utils/cryptography/ECDSA.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../StringsUpgradeable.sol\";\n\n/**\n * @dev Elliptic Curve Digital Signature Algorithm (ECDSA) operations.\n *\n * These functions can be used to verify that a message was signed by the holder\n * of the private keys of a given address.\n */\nlibrary ECDSAUpgradeable {\n enum RecoverError {\n NoError,\n InvalidSignature,\n InvalidSignatureLength,\n InvalidSignatureS,\n InvalidSignatureV\n }\n\n function _throwError(RecoverError error) private pure {\n if (error == RecoverError.NoError) {\n return; // no error: do nothing\n } else if (error == RecoverError.InvalidSignature) {\n revert(\"ECDSA: invalid signature\");\n } else if (error == RecoverError.InvalidSignatureLength) {\n revert(\"ECDSA: invalid signature length\");\n } else if (error == RecoverError.InvalidSignatureS) {\n revert(\"ECDSA: invalid signature 's' value\");\n } else if (error == RecoverError.InvalidSignatureV) {\n revert(\"ECDSA: invalid signature 'v' value\");\n }\n }\n\n /**\n * @dev Returns the address that signed a hashed message (`hash`) with\n * `signature` or error string. This address can then be used for verification purposes.\n *\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\n * this function rejects them by requiring the `s` value to be in the lower\n * half order, and the `v` value to be either 27 or 28.\n *\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\n * verification to be secure: it is possible to craft signatures that\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\n * this is by receiving a hash of the original message (which may otherwise\n * be too long), and then calling {toEthSignedMessageHash} on it.\n *\n * Documentation for signature generation:\n * - with https://web3js.readthedocs.io/en/v1.3.4/web3-eth-accounts.html#sign[Web3.js]\n * - with https://docs.ethers.io/v5/api/signer/#Signer-signMessage[ethers]\n *\n * _Available since v4.3._\n */\n function tryRecover(bytes32 hash, bytes memory signature) internal pure returns (address, RecoverError) {\n // Check the signature length\n // - case 65: r,s,v signature (standard)\n // - case 64: r,vs signature (cf https://eips.ethereum.org/EIPS/eip-2098) _Available since v4.1._\n if (signature.length == 65) {\n bytes32 r;\n bytes32 s;\n uint8 v;\n // ecrecover takes the signature parameters, and the only way to get them\n // currently is to use assembly.\n /// @solidity memory-safe-assembly\n assembly {\n r := mload(add(signature, 0x20))\n s := mload(add(signature, 0x40))\n v := byte(0, mload(add(signature, 0x60)))\n }\n return tryRecover(hash, v, r, s);\n } else if (signature.length == 64) {\n bytes32 r;\n bytes32 vs;\n // ecrecover takes the signature parameters, and the only way to get them\n // currently is to use assembly.\n /// @solidity memory-safe-assembly\n assembly {\n r := mload(add(signature, 0x20))\n vs := mload(add(signature, 0x40))\n }\n return tryRecover(hash, r, vs);\n } else {\n return (address(0), RecoverError.InvalidSignatureLength);\n }\n }\n\n /**\n * @dev Returns the address that signed a hashed message (`hash`) with\n * `signature`. This address can then be used for verification purposes.\n *\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\n * this function rejects them by requiring the `s` value to be in the lower\n * half order, and the `v` value to be either 27 or 28.\n *\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\n * verification to be secure: it is possible to craft signatures that\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\n * this is by receiving a hash of the original message (which may otherwise\n * be too long), and then calling {toEthSignedMessageHash} on it.\n */\n function recover(bytes32 hash, bytes memory signature) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, signature);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Overload of {ECDSA-tryRecover} that receives the `r` and `vs` short-signature fields separately.\n *\n * See https://eips.ethereum.org/EIPS/eip-2098[EIP-2098 short signatures]\n *\n * _Available since v4.3._\n */\n function tryRecover(\n bytes32 hash,\n bytes32 r,\n bytes32 vs\n ) internal pure returns (address, RecoverError) {\n bytes32 s = vs & bytes32(0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff);\n uint8 v = uint8((uint256(vs) >> 255) + 27);\n return tryRecover(hash, v, r, s);\n }\n\n /**\n * @dev Overload of {ECDSA-recover} that receives the `r and `vs` short-signature fields separately.\n *\n * _Available since v4.2._\n */\n function recover(\n bytes32 hash,\n bytes32 r,\n bytes32 vs\n ) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, r, vs);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Overload of {ECDSA-tryRecover} that receives the `v`,\n * `r` and `s` signature fields separately.\n *\n * _Available since v4.3._\n */\n function tryRecover(\n bytes32 hash,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) internal pure returns (address, RecoverError) {\n // EIP-2 still allows signature malleability for ecrecover(). Remove this possibility and make the signature\n // unique. Appendix F in the Ethereum Yellow paper (https://ethereum.github.io/yellowpaper/paper.pdf), defines\n // the valid range for s in (301): 0 < s < secp256k1n ÷ 2 + 1, and for v in (302): v ∈ {27, 28}. Most\n // signatures from current libraries generate a unique signature with an s-value in the lower half order.\n //\n // If your library generates malleable signatures, such as s-values in the upper range, calculate a new s-value\n // with 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141 - s1 and flip v from 27 to 28 or\n // vice versa. If your library also generates signatures with 0/1 for v instead 27/28, add 27 to v to accept\n // these malleable signatures as well.\n if (uint256(s) > 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D576E7357A4501DDFE92F46681B20A0) {\n return (address(0), RecoverError.InvalidSignatureS);\n }\n if (v != 27 && v != 28) {\n return (address(0), RecoverError.InvalidSignatureV);\n }\n\n // If the signature is valid (and not malleable), return the signer address\n address signer = ecrecover(hash, v, r, s);\n if (signer == address(0)) {\n return (address(0), RecoverError.InvalidSignature);\n }\n\n return (signer, RecoverError.NoError);\n }\n\n /**\n * @dev Overload of {ECDSA-recover} that receives the `v`,\n * `r` and `s` signature fields separately.\n */\n function recover(\n bytes32 hash,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, v, r, s);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Returns an Ethereum Signed Message, created from a `hash`. This\n * produces hash corresponding to the one signed with the\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\n * JSON-RPC method as part of EIP-191.\n *\n * See {recover}.\n */\n function toEthSignedMessageHash(bytes32 hash) internal pure returns (bytes32) {\n // 32 is the length in bytes of hash,\n // enforced by the type signature above\n return keccak256(abi.encodePacked(\"\\x19Ethereum Signed Message:\\n32\", hash));\n }\n\n /**\n * @dev Returns an Ethereum Signed Message, created from `s`. This\n * produces hash corresponding to the one signed with the\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\n * JSON-RPC method as part of EIP-191.\n *\n * See {recover}.\n */\n function toEthSignedMessageHash(bytes memory s) internal pure returns (bytes32) {\n return keccak256(abi.encodePacked(\"\\x19Ethereum Signed Message:\\n\", StringsUpgradeable.toString(s.length), s));\n }\n\n /**\n * @dev Returns an Ethereum Signed Typed Data, created from a\n * `domainSeparator` and a `structHash`. This produces hash corresponding\n * to the one signed with the\n * https://eips.ethereum.org/EIPS/eip-712[`eth_signTypedData`]\n * JSON-RPC method as part of EIP-712.\n *\n * See {recover}.\n */\n function toTypedDataHash(bytes32 domainSeparator, bytes32 structHash) internal pure returns (bytes32) {\n return keccak256(abi.encodePacked(\"\\x19\\x01\", domainSeparator, structHash));\n }\n}\n" + }, + "@openzeppelin/contracts-upgradeable/utils/introspection/ERC165Upgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (utils/introspection/ERC165.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./IERC165Upgradeable.sol\";\nimport \"../../proxy/utils/Initializable.sol\";\n\n/**\n * @dev Implementation of the {IERC165} interface.\n *\n * Contracts that want to implement ERC165 should inherit from this contract and override {supportsInterface} to check\n * for the additional interface id that will be supported. For example:\n *\n * ```solidity\n * function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {\n * return interfaceId == type(MyInterface).interfaceId || super.supportsInterface(interfaceId);\n * }\n * ```\n *\n * Alternatively, {ERC165Storage} provides an easier to use but more expensive implementation.\n */\nabstract contract ERC165Upgradeable is Initializable, IERC165Upgradeable {\n function __ERC165_init() internal onlyInitializing {\n }\n\n function __ERC165_init_unchained() internal onlyInitializing {\n }\n /**\n * @dev See {IERC165-supportsInterface}.\n */\n function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {\n return interfaceId == type(IERC165Upgradeable).interfaceId;\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[50] private __gap;\n}\n" + }, + "@openzeppelin/contracts-upgradeable/utils/introspection/IERC165Upgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (utils/introspection/IERC165.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Interface of the ERC165 standard, as defined in the\n * https://eips.ethereum.org/EIPS/eip-165[EIP].\n *\n * Implementers can declare support of contract interfaces, which can then be\n * queried by others ({ERC165Checker}).\n *\n * For an implementation, see {ERC165}.\n */\ninterface IERC165Upgradeable {\n /**\n * @dev Returns true if this contract implements the interface defined by\n * `interfaceId`. See the corresponding\n * https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified[EIP section]\n * to learn more about how these ids are created.\n *\n * This function call must use less than 30 000 gas.\n */\n function supportsInterface(bytes4 interfaceId) external view returns (bool);\n}\n" + }, + "@openzeppelin/contracts-upgradeable/utils/StringsUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (utils/Strings.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev String operations.\n */\nlibrary StringsUpgradeable {\n bytes16 private constant _HEX_SYMBOLS = \"0123456789abcdef\";\n uint8 private constant _ADDRESS_LENGTH = 20;\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` decimal representation.\n */\n function toString(uint256 value) internal pure returns (string memory) {\n // Inspired by OraclizeAPI's implementation - MIT licence\n // https://github.com/oraclize/ethereum-api/blob/b42146b063c7d6ee1358846c198246239e9360e8/oraclizeAPI_0.4.25.sol\n\n if (value == 0) {\n return \"0\";\n }\n uint256 temp = value;\n uint256 digits;\n while (temp != 0) {\n digits++;\n temp /= 10;\n }\n bytes memory buffer = new bytes(digits);\n while (value != 0) {\n digits -= 1;\n buffer[digits] = bytes1(uint8(48 + uint256(value % 10)));\n value /= 10;\n }\n return string(buffer);\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation.\n */\n function toHexString(uint256 value) internal pure returns (string memory) {\n if (value == 0) {\n return \"0x00\";\n }\n uint256 temp = value;\n uint256 length = 0;\n while (temp != 0) {\n length++;\n temp >>= 8;\n }\n return toHexString(value, length);\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length.\n */\n function toHexString(uint256 value, uint256 length) internal pure returns (string memory) {\n bytes memory buffer = new bytes(2 * length + 2);\n buffer[0] = \"0\";\n buffer[1] = \"x\";\n for (uint256 i = 2 * length + 1; i > 1; --i) {\n buffer[i] = _HEX_SYMBOLS[value & 0xf];\n value >>= 4;\n }\n require(value == 0, \"Strings: hex length insufficient\");\n return string(buffer);\n }\n\n /**\n * @dev Converts an `address` with fixed length of 20 bytes to its not checksummed ASCII `string` hexadecimal representation.\n */\n function toHexString(address addr) internal pure returns (string memory) {\n return toHexString(uint256(uint160(addr)), _ADDRESS_LENGTH);\n }\n}\n" + }, + "@openzeppelin/contracts-upgradeable/utils/structs/EnumerableSetUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (utils/structs/EnumerableSet.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Library for managing\n * https://en.wikipedia.org/wiki/Set_(abstract_data_type)[sets] of primitive\n * types.\n *\n * Sets have the following properties:\n *\n * - Elements are added, removed, and checked for existence in constant time\n * (O(1)).\n * - Elements are enumerated in O(n). No guarantees are made on the ordering.\n *\n * ```\n * contract Example {\n * // Add the library methods\n * using EnumerableSet for EnumerableSet.AddressSet;\n *\n * // Declare a set state variable\n * EnumerableSet.AddressSet private mySet;\n * }\n * ```\n *\n * As of v3.3.0, sets of type `bytes32` (`Bytes32Set`), `address` (`AddressSet`)\n * and `uint256` (`UintSet`) are supported.\n *\n * [WARNING]\n * ====\n * Trying to delete such a structure from storage will likely result in data corruption, rendering the structure unusable.\n * See https://github.com/ethereum/solidity/pull/11843[ethereum/solidity#11843] for more info.\n *\n * In order to clean an EnumerableSet, you can either remove all elements one by one or create a fresh instance using an array of EnumerableSet.\n * ====\n */\nlibrary EnumerableSetUpgradeable {\n // To implement this library for multiple types with as little code\n // repetition as possible, we write it in terms of a generic Set type with\n // bytes32 values.\n // The Set implementation uses private functions, and user-facing\n // implementations (such as AddressSet) are just wrappers around the\n // underlying Set.\n // This means that we can only create new EnumerableSets for types that fit\n // in bytes32.\n\n struct Set {\n // Storage of set values\n bytes32[] _values;\n // Position of the value in the `values` array, plus 1 because index 0\n // means a value is not in the set.\n mapping(bytes32 => uint256) _indexes;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function _add(Set storage set, bytes32 value) private returns (bool) {\n if (!_contains(set, value)) {\n set._values.push(value);\n // The value is stored at length-1, but we add 1 to all indexes\n // and use 0 as a sentinel value\n set._indexes[value] = set._values.length;\n return true;\n } else {\n return false;\n }\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function _remove(Set storage set, bytes32 value) private returns (bool) {\n // We read and store the value's index to prevent multiple reads from the same storage slot\n uint256 valueIndex = set._indexes[value];\n\n if (valueIndex != 0) {\n // Equivalent to contains(set, value)\n // To delete an element from the _values array in O(1), we swap the element to delete with the last one in\n // the array, and then remove the last element (sometimes called as 'swap and pop').\n // This modifies the order of the array, as noted in {at}.\n\n uint256 toDeleteIndex = valueIndex - 1;\n uint256 lastIndex = set._values.length - 1;\n\n if (lastIndex != toDeleteIndex) {\n bytes32 lastValue = set._values[lastIndex];\n\n // Move the last value to the index where the value to delete is\n set._values[toDeleteIndex] = lastValue;\n // Update the index for the moved value\n set._indexes[lastValue] = valueIndex; // Replace lastValue's index to valueIndex\n }\n\n // Delete the slot where the moved value was stored\n set._values.pop();\n\n // Delete the index for the deleted slot\n delete set._indexes[value];\n\n return true;\n } else {\n return false;\n }\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function _contains(Set storage set, bytes32 value) private view returns (bool) {\n return set._indexes[value] != 0;\n }\n\n /**\n * @dev Returns the number of values on the set. O(1).\n */\n function _length(Set storage set) private view returns (uint256) {\n return set._values.length;\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function _at(Set storage set, uint256 index) private view returns (bytes32) {\n return set._values[index];\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function _values(Set storage set) private view returns (bytes32[] memory) {\n return set._values;\n }\n\n // Bytes32Set\n\n struct Bytes32Set {\n Set _inner;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function add(Bytes32Set storage set, bytes32 value) internal returns (bool) {\n return _add(set._inner, value);\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function remove(Bytes32Set storage set, bytes32 value) internal returns (bool) {\n return _remove(set._inner, value);\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function contains(Bytes32Set storage set, bytes32 value) internal view returns (bool) {\n return _contains(set._inner, value);\n }\n\n /**\n * @dev Returns the number of values in the set. O(1).\n */\n function length(Bytes32Set storage set) internal view returns (uint256) {\n return _length(set._inner);\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function at(Bytes32Set storage set, uint256 index) internal view returns (bytes32) {\n return _at(set._inner, index);\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function values(Bytes32Set storage set) internal view returns (bytes32[] memory) {\n return _values(set._inner);\n }\n\n // AddressSet\n\n struct AddressSet {\n Set _inner;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function add(AddressSet storage set, address value) internal returns (bool) {\n return _add(set._inner, bytes32(uint256(uint160(value))));\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function remove(AddressSet storage set, address value) internal returns (bool) {\n return _remove(set._inner, bytes32(uint256(uint160(value))));\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function contains(AddressSet storage set, address value) internal view returns (bool) {\n return _contains(set._inner, bytes32(uint256(uint160(value))));\n }\n\n /**\n * @dev Returns the number of values in the set. O(1).\n */\n function length(AddressSet storage set) internal view returns (uint256) {\n return _length(set._inner);\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function at(AddressSet storage set, uint256 index) internal view returns (address) {\n return address(uint160(uint256(_at(set._inner, index))));\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function values(AddressSet storage set) internal view returns (address[] memory) {\n bytes32[] memory store = _values(set._inner);\n address[] memory result;\n\n /// @solidity memory-safe-assembly\n assembly {\n result := store\n }\n\n return result;\n }\n\n // UintSet\n\n struct UintSet {\n Set _inner;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function add(UintSet storage set, uint256 value) internal returns (bool) {\n return _add(set._inner, bytes32(value));\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function remove(UintSet storage set, uint256 value) internal returns (bool) {\n return _remove(set._inner, bytes32(value));\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function contains(UintSet storage set, uint256 value) internal view returns (bool) {\n return _contains(set._inner, bytes32(value));\n }\n\n /**\n * @dev Returns the number of values on the set. O(1).\n */\n function length(UintSet storage set) internal view returns (uint256) {\n return _length(set._inner);\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function at(UintSet storage set, uint256 index) internal view returns (uint256) {\n return uint256(_at(set._inner, index));\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function values(UintSet storage set) internal view returns (uint256[] memory) {\n bytes32[] memory store = _values(set._inner);\n uint256[] memory result;\n\n /// @solidity memory-safe-assembly\n assembly {\n result := store\n }\n\n return result;\n }\n}\n" + }, + "@openzeppelin/contracts/access/Ownable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (access/Ownable.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../utils/Context.sol\";\n\n/**\n * @dev Contract module which provides a basic access control mechanism, where\n * there is an account (an owner) that can be granted exclusive access to\n * specific functions.\n *\n * By default, the owner account will be the one that deploys the contract. This\n * can later be changed with {transferOwnership}.\n *\n * This module is used through inheritance. It will make available the modifier\n * `onlyOwner`, which can be applied to your functions to restrict their use to\n * the owner.\n */\nabstract contract Ownable is Context {\n address private _owner;\n\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\n\n /**\n * @dev Initializes the contract setting the deployer as the initial owner.\n */\n constructor() {\n _transferOwnership(_msgSender());\n }\n\n /**\n * @dev Throws if called by any account other than the owner.\n */\n modifier onlyOwner() {\n _checkOwner();\n _;\n }\n\n /**\n * @dev Returns the address of the current owner.\n */\n function owner() public view virtual returns (address) {\n return _owner;\n }\n\n /**\n * @dev Throws if the sender is not the owner.\n */\n function _checkOwner() internal view virtual {\n require(owner() == _msgSender(), \"Ownable: caller is not the owner\");\n }\n\n /**\n * @dev Leaves the contract without owner. It will not be possible to call\n * `onlyOwner` functions anymore. Can only be called by the current owner.\n *\n * NOTE: Renouncing ownership will leave the contract without an owner,\n * thereby removing any functionality that is only available to the owner.\n */\n function renounceOwnership() public virtual onlyOwner {\n _transferOwnership(address(0));\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Can only be called by the current owner.\n */\n function transferOwnership(address newOwner) public virtual onlyOwner {\n require(newOwner != address(0), \"Ownable: new owner is the zero address\");\n _transferOwnership(newOwner);\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Internal function without access restriction.\n */\n function _transferOwnership(address newOwner) internal virtual {\n address oldOwner = _owner;\n _owner = newOwner;\n emit OwnershipTransferred(oldOwner, newOwner);\n }\n}\n" + }, + "@openzeppelin/contracts/interfaces/draft-IERC1822.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.5.0) (interfaces/draft-IERC1822.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev ERC1822: Universal Upgradeable Proxy Standard (UUPS) documents a method for upgradeability through a simplified\n * proxy whose upgrades are fully controlled by the current implementation.\n */\ninterface IERC1822Proxiable {\n /**\n * @dev Returns the storage slot that the proxiable contract assumes is being used to store the implementation\n * address.\n *\n * IMPORTANT: A proxy pointing at a proxiable contract should not be considered proxiable itself, because this risks\n * bricking a proxy that upgrades to it, by delegating to itself until out of gas. Thus it is critical that this\n * function revert if invoked through a proxy.\n */\n function proxiableUUID() external view returns (bytes32);\n}\n" + }, + "@openzeppelin/contracts/interfaces/IERC3156FlashBorrower.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (interfaces/IERC3156FlashBorrower.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Interface of the ERC3156 FlashBorrower, as defined in\n * https://eips.ethereum.org/EIPS/eip-3156[ERC-3156].\n *\n * _Available since v4.1._\n */\ninterface IERC3156FlashBorrower {\n /**\n * @dev Receive a flash loan.\n * @param initiator The initiator of the loan.\n * @param token The loan currency.\n * @param amount The amount of tokens lent.\n * @param fee The additional amount of tokens to repay.\n * @param data Arbitrary data structure, intended to contain user-defined parameters.\n * @return The keccak256 hash of \"IERC3156FlashBorrower.onFlashLoan\"\n */\n function onFlashLoan(\n address initiator,\n address token,\n uint256 amount,\n uint256 fee,\n bytes calldata data\n ) external returns (bytes32);\n}\n" + }, + "@openzeppelin/contracts/interfaces/IERC3156FlashLender.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (interfaces/IERC3156FlashLender.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./IERC3156FlashBorrower.sol\";\n\n/**\n * @dev Interface of the ERC3156 FlashLender, as defined in\n * https://eips.ethereum.org/EIPS/eip-3156[ERC-3156].\n *\n * _Available since v4.1._\n */\ninterface IERC3156FlashLender {\n /**\n * @dev The amount of currency available to be lended.\n * @param token The loan currency.\n * @return The amount of `token` that can be borrowed.\n */\n function maxFlashLoan(address token) external view returns (uint256);\n\n /**\n * @dev The fee to be charged for a given loan.\n * @param token The loan currency.\n * @param amount The amount of tokens lent.\n * @return The amount of `token` to be charged for the loan, on top of the returned principal.\n */\n function flashFee(address token, uint256 amount) external view returns (uint256);\n\n /**\n * @dev Initiate a flash loan.\n * @param receiver The receiver of the tokens in the loan, and the receiver of the callback.\n * @param token The loan currency.\n * @param amount The amount of tokens lent.\n * @param data Arbitrary data structure, intended to contain user-defined parameters.\n */\n function flashLoan(\n IERC3156FlashBorrower receiver,\n address token,\n uint256 amount,\n bytes calldata data\n ) external returns (bool);\n}\n" + }, + "@openzeppelin/contracts/interfaces/IERC721Metadata.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (interfaces/IERC721Metadata.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../token/ERC721/extensions/IERC721Metadata.sol\";\n" + }, + "@openzeppelin/contracts/proxy/beacon/IBeacon.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (proxy/beacon/IBeacon.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev This is the interface that {BeaconProxy} expects of its beacon.\n */\ninterface IBeacon {\n /**\n * @dev Must return an address that can be used as a delegate call target.\n *\n * {BeaconProxy} will check that this address is a contract.\n */\n function implementation() external view returns (address);\n}\n" + }, + "@openzeppelin/contracts/proxy/ERC1967/ERC1967Proxy.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (proxy/ERC1967/ERC1967Proxy.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../Proxy.sol\";\nimport \"./ERC1967Upgrade.sol\";\n\n/**\n * @dev This contract implements an upgradeable proxy. It is upgradeable because calls are delegated to an\n * implementation address that can be changed. This address is stored in storage in the location specified by\n * https://eips.ethereum.org/EIPS/eip-1967[EIP1967], so that it doesn't conflict with the storage layout of the\n * implementation behind the proxy.\n */\ncontract ERC1967Proxy is Proxy, ERC1967Upgrade {\n /**\n * @dev Initializes the upgradeable proxy with an initial implementation specified by `_logic`.\n *\n * If `_data` is nonempty, it's used as data in a delegate call to `_logic`. This will typically be an encoded\n * function call, and allows initializing the storage of the proxy like a Solidity constructor.\n */\n constructor(address _logic, bytes memory _data) payable {\n _upgradeToAndCall(_logic, _data, false);\n }\n\n /**\n * @dev Returns the current implementation address.\n */\n function _implementation() internal view virtual override returns (address impl) {\n return ERC1967Upgrade._getImplementation();\n }\n}\n" + }, + "@openzeppelin/contracts/proxy/ERC1967/ERC1967Upgrade.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.5.0) (proxy/ERC1967/ERC1967Upgrade.sol)\n\npragma solidity ^0.8.2;\n\nimport \"../beacon/IBeacon.sol\";\nimport \"../../interfaces/draft-IERC1822.sol\";\nimport \"../../utils/Address.sol\";\nimport \"../../utils/StorageSlot.sol\";\n\n/**\n * @dev This abstract contract provides getters and event emitting update functions for\n * https://eips.ethereum.org/EIPS/eip-1967[EIP1967] slots.\n *\n * _Available since v4.1._\n *\n * @custom:oz-upgrades-unsafe-allow delegatecall\n */\nabstract contract ERC1967Upgrade {\n // This is the keccak-256 hash of \"eip1967.proxy.rollback\" subtracted by 1\n bytes32 private constant _ROLLBACK_SLOT = 0x4910fdfa16fed3260ed0e7147f7cc6da11a60208b5b9406d12a635614ffd9143;\n\n /**\n * @dev Storage slot with the address of the current implementation.\n * This is the keccak-256 hash of \"eip1967.proxy.implementation\" subtracted by 1, and is\n * validated in the constructor.\n */\n bytes32 internal constant _IMPLEMENTATION_SLOT = 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc;\n\n /**\n * @dev Emitted when the implementation is upgraded.\n */\n event Upgraded(address indexed implementation);\n\n /**\n * @dev Returns the current implementation address.\n */\n function _getImplementation() internal view returns (address) {\n return StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value;\n }\n\n /**\n * @dev Stores a new address in the EIP1967 implementation slot.\n */\n function _setImplementation(address newImplementation) private {\n require(Address.isContract(newImplementation), \"ERC1967: new implementation is not a contract\");\n StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value = newImplementation;\n }\n\n /**\n * @dev Perform implementation upgrade\n *\n * Emits an {Upgraded} event.\n */\n function _upgradeTo(address newImplementation) internal {\n _setImplementation(newImplementation);\n emit Upgraded(newImplementation);\n }\n\n /**\n * @dev Perform implementation upgrade with additional setup call.\n *\n * Emits an {Upgraded} event.\n */\n function _upgradeToAndCall(\n address newImplementation,\n bytes memory data,\n bool forceCall\n ) internal {\n _upgradeTo(newImplementation);\n if (data.length > 0 || forceCall) {\n Address.functionDelegateCall(newImplementation, data);\n }\n }\n\n /**\n * @dev Perform implementation upgrade with security checks for UUPS proxies, and additional setup call.\n *\n * Emits an {Upgraded} event.\n */\n function _upgradeToAndCallUUPS(\n address newImplementation,\n bytes memory data,\n bool forceCall\n ) internal {\n // Upgrades from old implementations will perform a rollback test. This test requires the new\n // implementation to upgrade back to the old, non-ERC1822 compliant, implementation. Removing\n // this special case will break upgrade paths from old UUPS implementation to new ones.\n if (StorageSlot.getBooleanSlot(_ROLLBACK_SLOT).value) {\n _setImplementation(newImplementation);\n } else {\n try IERC1822Proxiable(newImplementation).proxiableUUID() returns (bytes32 slot) {\n require(slot == _IMPLEMENTATION_SLOT, \"ERC1967Upgrade: unsupported proxiableUUID\");\n } catch {\n revert(\"ERC1967Upgrade: new implementation is not UUPS\");\n }\n _upgradeToAndCall(newImplementation, data, forceCall);\n }\n }\n\n /**\n * @dev Storage slot with the admin of the contract.\n * This is the keccak-256 hash of \"eip1967.proxy.admin\" subtracted by 1, and is\n * validated in the constructor.\n */\n bytes32 internal constant _ADMIN_SLOT = 0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103;\n\n /**\n * @dev Emitted when the admin account has changed.\n */\n event AdminChanged(address previousAdmin, address newAdmin);\n\n /**\n * @dev Returns the current admin.\n */\n function _getAdmin() internal view returns (address) {\n return StorageSlot.getAddressSlot(_ADMIN_SLOT).value;\n }\n\n /**\n * @dev Stores a new address in the EIP1967 admin slot.\n */\n function _setAdmin(address newAdmin) private {\n require(newAdmin != address(0), \"ERC1967: new admin is the zero address\");\n StorageSlot.getAddressSlot(_ADMIN_SLOT).value = newAdmin;\n }\n\n /**\n * @dev Changes the admin of the proxy.\n *\n * Emits an {AdminChanged} event.\n */\n function _changeAdmin(address newAdmin) internal {\n emit AdminChanged(_getAdmin(), newAdmin);\n _setAdmin(newAdmin);\n }\n\n /**\n * @dev The storage slot of the UpgradeableBeacon contract which defines the implementation for this proxy.\n * This is bytes32(uint256(keccak256('eip1967.proxy.beacon')) - 1)) and is validated in the constructor.\n */\n bytes32 internal constant _BEACON_SLOT = 0xa3f0ad74e5423aebfd80d3ef4346578335a9a72aeaee59ff6cb3582b35133d50;\n\n /**\n * @dev Emitted when the beacon is upgraded.\n */\n event BeaconUpgraded(address indexed beacon);\n\n /**\n * @dev Returns the current beacon.\n */\n function _getBeacon() internal view returns (address) {\n return StorageSlot.getAddressSlot(_BEACON_SLOT).value;\n }\n\n /**\n * @dev Stores a new beacon in the EIP1967 beacon slot.\n */\n function _setBeacon(address newBeacon) private {\n require(Address.isContract(newBeacon), \"ERC1967: new beacon is not a contract\");\n require(\n Address.isContract(IBeacon(newBeacon).implementation()),\n \"ERC1967: beacon implementation is not a contract\"\n );\n StorageSlot.getAddressSlot(_BEACON_SLOT).value = newBeacon;\n }\n\n /**\n * @dev Perform beacon upgrade with additional setup call. Note: This upgrades the address of the beacon, it does\n * not upgrade the implementation contained in the beacon (see {UpgradeableBeacon-_setImplementation} for that).\n *\n * Emits a {BeaconUpgraded} event.\n */\n function _upgradeBeaconToAndCall(\n address newBeacon,\n bytes memory data,\n bool forceCall\n ) internal {\n _setBeacon(newBeacon);\n emit BeaconUpgraded(newBeacon);\n if (data.length > 0 || forceCall) {\n Address.functionDelegateCall(IBeacon(newBeacon).implementation(), data);\n }\n }\n}\n" + }, + "@openzeppelin/contracts/proxy/Proxy.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.6.0) (proxy/Proxy.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev This abstract contract provides a fallback function that delegates all calls to another contract using the EVM\n * instruction `delegatecall`. We refer to the second contract as the _implementation_ behind the proxy, and it has to\n * be specified by overriding the virtual {_implementation} function.\n *\n * Additionally, delegation to the implementation can be triggered manually through the {_fallback} function, or to a\n * different contract through the {_delegate} function.\n *\n * The success and return data of the delegated call will be returned back to the caller of the proxy.\n */\nabstract contract Proxy {\n /**\n * @dev Delegates the current call to `implementation`.\n *\n * This function does not return to its internal call site, it will return directly to the external caller.\n */\n function _delegate(address implementation) internal virtual {\n assembly {\n // Copy msg.data. We take full control of memory in this inline assembly\n // block because it will not return to Solidity code. We overwrite the\n // Solidity scratch pad at memory position 0.\n calldatacopy(0, 0, calldatasize())\n\n // Call the implementation.\n // out and outsize are 0 because we don't know the size yet.\n let result := delegatecall(gas(), implementation, 0, calldatasize(), 0, 0)\n\n // Copy the returned data.\n returndatacopy(0, 0, returndatasize())\n\n switch result\n // delegatecall returns 0 on error.\n case 0 {\n revert(0, returndatasize())\n }\n default {\n return(0, returndatasize())\n }\n }\n }\n\n /**\n * @dev This is a virtual function that should be overridden so it returns the address to which the fallback function\n * and {_fallback} should delegate.\n */\n function _implementation() internal view virtual returns (address);\n\n /**\n * @dev Delegates the current call to the address returned by `_implementation()`.\n *\n * This function does not return to its internal call site, it will return directly to the external caller.\n */\n function _fallback() internal virtual {\n _beforeFallback();\n _delegate(_implementation());\n }\n\n /**\n * @dev Fallback function that delegates calls to the address returned by `_implementation()`. Will run if no other\n * function in the contract matches the call data.\n */\n fallback() external payable virtual {\n _fallback();\n }\n\n /**\n * @dev Fallback function that delegates calls to the address returned by `_implementation()`. Will run if call data\n * is empty.\n */\n receive() external payable virtual {\n _fallback();\n }\n\n /**\n * @dev Hook that is called before falling back to the implementation. Can happen as part of a manual `_fallback`\n * call, or as part of the Solidity `fallback` or `receive` functions.\n *\n * If overridden should call `super._beforeFallback()`.\n */\n function _beforeFallback() internal virtual {}\n}\n" + }, + "@openzeppelin/contracts/token/ERC20/ERC20.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (token/ERC20/ERC20.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./IERC20.sol\";\nimport \"./extensions/IERC20Metadata.sol\";\nimport \"../../utils/Context.sol\";\n\n/**\n * @dev Implementation of the {IERC20} interface.\n *\n * This implementation is agnostic to the way tokens are created. This means\n * that a supply mechanism has to be added in a derived contract using {_mint}.\n * For a generic mechanism see {ERC20PresetMinterPauser}.\n *\n * TIP: For a detailed writeup see our guide\n * https://forum.zeppelin.solutions/t/how-to-implement-erc20-supply-mechanisms/226[How\n * to implement supply mechanisms].\n *\n * We have followed general OpenZeppelin Contracts guidelines: functions revert\n * instead returning `false` on failure. This behavior is nonetheless\n * conventional and does not conflict with the expectations of ERC20\n * applications.\n *\n * Additionally, an {Approval} event is emitted on calls to {transferFrom}.\n * This allows applications to reconstruct the allowance for all accounts just\n * by listening to said events. Other implementations of the EIP may not emit\n * these events, as it isn't required by the specification.\n *\n * Finally, the non-standard {decreaseAllowance} and {increaseAllowance}\n * functions have been added to mitigate the well-known issues around setting\n * allowances. See {IERC20-approve}.\n */\ncontract ERC20 is Context, IERC20, IERC20Metadata {\n mapping(address => uint256) private _balances;\n\n mapping(address => mapping(address => uint256)) private _allowances;\n\n uint256 private _totalSupply;\n\n string private _name;\n string private _symbol;\n\n /**\n * @dev Sets the values for {name} and {symbol}.\n *\n * The default value of {decimals} is 18. To select a different value for\n * {decimals} you should overload it.\n *\n * All two of these values are immutable: they can only be set once during\n * construction.\n */\n constructor(string memory name_, string memory symbol_) {\n _name = name_;\n _symbol = symbol_;\n }\n\n /**\n * @dev Returns the name of the token.\n */\n function name() public view virtual override returns (string memory) {\n return _name;\n }\n\n /**\n * @dev Returns the symbol of the token, usually a shorter version of the\n * name.\n */\n function symbol() public view virtual override returns (string memory) {\n return _symbol;\n }\n\n /**\n * @dev Returns the number of decimals used to get its user representation.\n * For example, if `decimals` equals `2`, a balance of `505` tokens should\n * be displayed to a user as `5.05` (`505 / 10 ** 2`).\n *\n * Tokens usually opt for a value of 18, imitating the relationship between\n * Ether and Wei. This is the value {ERC20} uses, unless this function is\n * overridden;\n *\n * NOTE: This information is only used for _display_ purposes: it in\n * no way affects any of the arithmetic of the contract, including\n * {IERC20-balanceOf} and {IERC20-transfer}.\n */\n function decimals() public view virtual override returns (uint8) {\n return 18;\n }\n\n /**\n * @dev See {IERC20-totalSupply}.\n */\n function totalSupply() public view virtual override returns (uint256) {\n return _totalSupply;\n }\n\n /**\n * @dev See {IERC20-balanceOf}.\n */\n function balanceOf(address account) public view virtual override returns (uint256) {\n return _balances[account];\n }\n\n /**\n * @dev See {IERC20-transfer}.\n *\n * Requirements:\n *\n * - `to` cannot be the zero address.\n * - the caller must have a balance of at least `amount`.\n */\n function transfer(address to, uint256 amount) public virtual override returns (bool) {\n address owner = _msgSender();\n _transfer(owner, to, amount);\n return true;\n }\n\n /**\n * @dev See {IERC20-allowance}.\n */\n function allowance(address owner, address spender) public view virtual override returns (uint256) {\n return _allowances[owner][spender];\n }\n\n /**\n * @dev See {IERC20-approve}.\n *\n * NOTE: If `amount` is the maximum `uint256`, the allowance is not updated on\n * `transferFrom`. This is semantically equivalent to an infinite approval.\n *\n * Requirements:\n *\n * - `spender` cannot be the zero address.\n */\n function approve(address spender, uint256 amount) public virtual override returns (bool) {\n address owner = _msgSender();\n _approve(owner, spender, amount);\n return true;\n }\n\n /**\n * @dev See {IERC20-transferFrom}.\n *\n * Emits an {Approval} event indicating the updated allowance. This is not\n * required by the EIP. See the note at the beginning of {ERC20}.\n *\n * NOTE: Does not update the allowance if the current allowance\n * is the maximum `uint256`.\n *\n * Requirements:\n *\n * - `from` and `to` cannot be the zero address.\n * - `from` must have a balance of at least `amount`.\n * - the caller must have allowance for ``from``'s tokens of at least\n * `amount`.\n */\n function transferFrom(\n address from,\n address to,\n uint256 amount\n ) public virtual override returns (bool) {\n address spender = _msgSender();\n _spendAllowance(from, spender, amount);\n _transfer(from, to, amount);\n return true;\n }\n\n /**\n * @dev Atomically increases the allowance granted to `spender` by the caller.\n *\n * This is an alternative to {approve} that can be used as a mitigation for\n * problems described in {IERC20-approve}.\n *\n * Emits an {Approval} event indicating the updated allowance.\n *\n * Requirements:\n *\n * - `spender` cannot be the zero address.\n */\n function increaseAllowance(address spender, uint256 addedValue) public virtual returns (bool) {\n address owner = _msgSender();\n _approve(owner, spender, allowance(owner, spender) + addedValue);\n return true;\n }\n\n /**\n * @dev Atomically decreases the allowance granted to `spender` by the caller.\n *\n * This is an alternative to {approve} that can be used as a mitigation for\n * problems described in {IERC20-approve}.\n *\n * Emits an {Approval} event indicating the updated allowance.\n *\n * Requirements:\n *\n * - `spender` cannot be the zero address.\n * - `spender` must have allowance for the caller of at least\n * `subtractedValue`.\n */\n function decreaseAllowance(address spender, uint256 subtractedValue) public virtual returns (bool) {\n address owner = _msgSender();\n uint256 currentAllowance = allowance(owner, spender);\n require(currentAllowance >= subtractedValue, \"ERC20: decreased allowance below zero\");\n unchecked {\n _approve(owner, spender, currentAllowance - subtractedValue);\n }\n\n return true;\n }\n\n /**\n * @dev Moves `amount` of tokens from `from` to `to`.\n *\n * This internal function is equivalent to {transfer}, and can be used to\n * e.g. implement automatic token fees, slashing mechanisms, etc.\n *\n * Emits a {Transfer} event.\n *\n * Requirements:\n *\n * - `from` cannot be the zero address.\n * - `to` cannot be the zero address.\n * - `from` must have a balance of at least `amount`.\n */\n function _transfer(\n address from,\n address to,\n uint256 amount\n ) internal virtual {\n require(from != address(0), \"ERC20: transfer from the zero address\");\n require(to != address(0), \"ERC20: transfer to the zero address\");\n\n _beforeTokenTransfer(from, to, amount);\n\n uint256 fromBalance = _balances[from];\n require(fromBalance >= amount, \"ERC20: transfer amount exceeds balance\");\n unchecked {\n _balances[from] = fromBalance - amount;\n }\n _balances[to] += amount;\n\n emit Transfer(from, to, amount);\n\n _afterTokenTransfer(from, to, amount);\n }\n\n /** @dev Creates `amount` tokens and assigns them to `account`, increasing\n * the total supply.\n *\n * Emits a {Transfer} event with `from` set to the zero address.\n *\n * Requirements:\n *\n * - `account` cannot be the zero address.\n */\n function _mint(address account, uint256 amount) internal virtual {\n require(account != address(0), \"ERC20: mint to the zero address\");\n\n _beforeTokenTransfer(address(0), account, amount);\n\n _totalSupply += amount;\n _balances[account] += amount;\n emit Transfer(address(0), account, amount);\n\n _afterTokenTransfer(address(0), account, amount);\n }\n\n /**\n * @dev Destroys `amount` tokens from `account`, reducing the\n * total supply.\n *\n * Emits a {Transfer} event with `to` set to the zero address.\n *\n * Requirements:\n *\n * - `account` cannot be the zero address.\n * - `account` must have at least `amount` tokens.\n */\n function _burn(address account, uint256 amount) internal virtual {\n require(account != address(0), \"ERC20: burn from the zero address\");\n\n _beforeTokenTransfer(account, address(0), amount);\n\n uint256 accountBalance = _balances[account];\n require(accountBalance >= amount, \"ERC20: burn amount exceeds balance\");\n unchecked {\n _balances[account] = accountBalance - amount;\n }\n _totalSupply -= amount;\n\n emit Transfer(account, address(0), amount);\n\n _afterTokenTransfer(account, address(0), amount);\n }\n\n /**\n * @dev Sets `amount` as the allowance of `spender` over the `owner` s tokens.\n *\n * This internal function is equivalent to `approve`, and can be used to\n * e.g. set automatic allowances for certain subsystems, etc.\n *\n * Emits an {Approval} event.\n *\n * Requirements:\n *\n * - `owner` cannot be the zero address.\n * - `spender` cannot be the zero address.\n */\n function _approve(\n address owner,\n address spender,\n uint256 amount\n ) internal virtual {\n require(owner != address(0), \"ERC20: approve from the zero address\");\n require(spender != address(0), \"ERC20: approve to the zero address\");\n\n _allowances[owner][spender] = amount;\n emit Approval(owner, spender, amount);\n }\n\n /**\n * @dev Updates `owner` s allowance for `spender` based on spent `amount`.\n *\n * Does not update the allowance amount in case of infinite allowance.\n * Revert if not enough allowance is available.\n *\n * Might emit an {Approval} event.\n */\n function _spendAllowance(\n address owner,\n address spender,\n uint256 amount\n ) internal virtual {\n uint256 currentAllowance = allowance(owner, spender);\n if (currentAllowance != type(uint256).max) {\n require(currentAllowance >= amount, \"ERC20: insufficient allowance\");\n unchecked {\n _approve(owner, spender, currentAllowance - amount);\n }\n }\n }\n\n /**\n * @dev Hook that is called before any transfer of tokens. This includes\n * minting and burning.\n *\n * Calling conditions:\n *\n * - when `from` and `to` are both non-zero, `amount` of ``from``'s tokens\n * will be transferred to `to`.\n * - when `from` is zero, `amount` tokens will be minted for `to`.\n * - when `to` is zero, `amount` of ``from``'s tokens will be burned.\n * - `from` and `to` are never both zero.\n *\n * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].\n */\n function _beforeTokenTransfer(\n address from,\n address to,\n uint256 amount\n ) internal virtual {}\n\n /**\n * @dev Hook that is called after any transfer of tokens. This includes\n * minting and burning.\n *\n * Calling conditions:\n *\n * - when `from` and `to` are both non-zero, `amount` of ``from``'s tokens\n * has been transferred to `to`.\n * - when `from` is zero, `amount` tokens have been minted for `to`.\n * - when `to` is zero, `amount` of ``from``'s tokens have been burned.\n * - `from` and `to` are never both zero.\n *\n * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].\n */\n function _afterTokenTransfer(\n address from,\n address to,\n uint256 amount\n ) internal virtual {}\n}\n" + }, + "@openzeppelin/contracts/token/ERC20/extensions/draft-ERC20Permit.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.6.0) (token/ERC20/extensions/draft-ERC20Permit.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./draft-IERC20Permit.sol\";\nimport \"../ERC20.sol\";\nimport \"../../../utils/cryptography/draft-EIP712.sol\";\nimport \"../../../utils/cryptography/ECDSA.sol\";\nimport \"../../../utils/Counters.sol\";\n\n/**\n * @dev Implementation of the ERC20 Permit extension allowing approvals to be made via signatures, as defined in\n * https://eips.ethereum.org/EIPS/eip-2612[EIP-2612].\n *\n * Adds the {permit} method, which can be used to change an account's ERC20 allowance (see {IERC20-allowance}) by\n * presenting a message signed by the account. By not relying on `{IERC20-approve}`, the token holder account doesn't\n * need to send a transaction, and thus is not required to hold Ether at all.\n *\n * _Available since v3.4._\n */\nabstract contract ERC20Permit is ERC20, IERC20Permit, EIP712 {\n using Counters for Counters.Counter;\n\n mapping(address => Counters.Counter) private _nonces;\n\n // solhint-disable-next-line var-name-mixedcase\n bytes32 private constant _PERMIT_TYPEHASH =\n keccak256(\"Permit(address owner,address spender,uint256 value,uint256 nonce,uint256 deadline)\");\n /**\n * @dev In previous versions `_PERMIT_TYPEHASH` was declared as `immutable`.\n * However, to ensure consistency with the upgradeable transpiler, we will continue\n * to reserve a slot.\n * @custom:oz-renamed-from _PERMIT_TYPEHASH\n */\n // solhint-disable-next-line var-name-mixedcase\n bytes32 private _PERMIT_TYPEHASH_DEPRECATED_SLOT;\n\n /**\n * @dev Initializes the {EIP712} domain separator using the `name` parameter, and setting `version` to `\"1\"`.\n *\n * It's a good idea to use the same `name` that is defined as the ERC20 token name.\n */\n constructor(string memory name) EIP712(name, \"1\") {}\n\n /**\n * @dev See {IERC20Permit-permit}.\n */\n function permit(\n address owner,\n address spender,\n uint256 value,\n uint256 deadline,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) public virtual override {\n require(block.timestamp <= deadline, \"ERC20Permit: expired deadline\");\n\n bytes32 structHash = keccak256(abi.encode(_PERMIT_TYPEHASH, owner, spender, value, _useNonce(owner), deadline));\n\n bytes32 hash = _hashTypedDataV4(structHash);\n\n address signer = ECDSA.recover(hash, v, r, s);\n require(signer == owner, \"ERC20Permit: invalid signature\");\n\n _approve(owner, spender, value);\n }\n\n /**\n * @dev See {IERC20Permit-nonces}.\n */\n function nonces(address owner) public view virtual override returns (uint256) {\n return _nonces[owner].current();\n }\n\n /**\n * @dev See {IERC20Permit-DOMAIN_SEPARATOR}.\n */\n // solhint-disable-next-line func-name-mixedcase\n function DOMAIN_SEPARATOR() external view override returns (bytes32) {\n return _domainSeparatorV4();\n }\n\n /**\n * @dev \"Consume a nonce\": return the current value and increment.\n *\n * _Available since v4.1._\n */\n function _useNonce(address owner) internal virtual returns (uint256 current) {\n Counters.Counter storage nonce = _nonces[owner];\n current = nonce.current();\n nonce.increment();\n }\n}\n" + }, + "@openzeppelin/contracts/token/ERC20/extensions/draft-IERC20Permit.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (token/ERC20/extensions/draft-IERC20Permit.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Interface of the ERC20 Permit extension allowing approvals to be made via signatures, as defined in\n * https://eips.ethereum.org/EIPS/eip-2612[EIP-2612].\n *\n * Adds the {permit} method, which can be used to change an account's ERC20 allowance (see {IERC20-allowance}) by\n * presenting a message signed by the account. By not relying on {IERC20-approve}, the token holder account doesn't\n * need to send a transaction, and thus is not required to hold Ether at all.\n */\ninterface IERC20Permit {\n /**\n * @dev Sets `value` as the allowance of `spender` over ``owner``'s tokens,\n * given ``owner``'s signed approval.\n *\n * IMPORTANT: The same issues {IERC20-approve} has related to transaction\n * ordering also apply here.\n *\n * Emits an {Approval} event.\n *\n * Requirements:\n *\n * - `spender` cannot be the zero address.\n * - `deadline` must be a timestamp in the future.\n * - `v`, `r` and `s` must be a valid `secp256k1` signature from `owner`\n * over the EIP712-formatted function arguments.\n * - the signature must use ``owner``'s current nonce (see {nonces}).\n *\n * For more information on the signature format, see the\n * https://eips.ethereum.org/EIPS/eip-2612#specification[relevant EIP\n * section].\n */\n function permit(\n address owner,\n address spender,\n uint256 value,\n uint256 deadline,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) external;\n\n /**\n * @dev Returns the current nonce for `owner`. This value must be\n * included whenever a signature is generated for {permit}.\n *\n * Every successful call to {permit} increases ``owner``'s nonce by one. This\n * prevents a signature from being used multiple times.\n */\n function nonces(address owner) external view returns (uint256);\n\n /**\n * @dev Returns the domain separator used in the encoding of the signature for {permit}, as defined by {EIP712}.\n */\n // solhint-disable-next-line func-name-mixedcase\n function DOMAIN_SEPARATOR() external view returns (bytes32);\n}\n" + }, + "@openzeppelin/contracts/token/ERC20/extensions/IERC20Metadata.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (token/ERC20/extensions/IERC20Metadata.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../IERC20.sol\";\n\n/**\n * @dev Interface for the optional metadata functions from the ERC20 standard.\n *\n * _Available since v4.1._\n */\ninterface IERC20Metadata is IERC20 {\n /**\n * @dev Returns the name of the token.\n */\n function name() external view returns (string memory);\n\n /**\n * @dev Returns the symbol of the token.\n */\n function symbol() external view returns (string memory);\n\n /**\n * @dev Returns the decimals places of the token.\n */\n function decimals() external view returns (uint8);\n}\n" + }, + "@openzeppelin/contracts/token/ERC20/IERC20.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.6.0) (token/ERC20/IERC20.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Interface of the ERC20 standard as defined in the EIP.\n */\ninterface IERC20 {\n /**\n * @dev Emitted when `value` tokens are moved from one account (`from`) to\n * another (`to`).\n *\n * Note that `value` may be zero.\n */\n event Transfer(address indexed from, address indexed to, uint256 value);\n\n /**\n * @dev Emitted when the allowance of a `spender` for an `owner` is set by\n * a call to {approve}. `value` is the new allowance.\n */\n event Approval(address indexed owner, address indexed spender, uint256 value);\n\n /**\n * @dev Returns the amount of tokens in existence.\n */\n function totalSupply() external view returns (uint256);\n\n /**\n * @dev Returns the amount of tokens owned by `account`.\n */\n function balanceOf(address account) external view returns (uint256);\n\n /**\n * @dev Moves `amount` tokens from the caller's account to `to`.\n *\n * Returns a boolean value indicating whether the operation succeeded.\n *\n * Emits a {Transfer} event.\n */\n function transfer(address to, uint256 amount) external returns (bool);\n\n /**\n * @dev Returns the remaining number of tokens that `spender` will be\n * allowed to spend on behalf of `owner` through {transferFrom}. This is\n * zero by default.\n *\n * This value changes when {approve} or {transferFrom} are called.\n */\n function allowance(address owner, address spender) external view returns (uint256);\n\n /**\n * @dev Sets `amount` as the allowance of `spender` over the caller's tokens.\n *\n * Returns a boolean value indicating whether the operation succeeded.\n *\n * IMPORTANT: Beware that changing an allowance with this method brings the risk\n * that someone may use both the old and the new allowance by unfortunate\n * transaction ordering. One possible solution to mitigate this race\n * condition is to first reduce the spender's allowance to 0 and set the\n * desired value afterwards:\n * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729\n *\n * Emits an {Approval} event.\n */\n function approve(address spender, uint256 amount) external returns (bool);\n\n /**\n * @dev Moves `amount` tokens from `from` to `to` using the\n * allowance mechanism. `amount` is then deducted from the caller's\n * allowance.\n *\n * Returns a boolean value indicating whether the operation succeeded.\n *\n * Emits a {Transfer} event.\n */\n function transferFrom(\n address from,\n address to,\n uint256 amount\n ) external returns (bool);\n}\n" + }, + "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (token/ERC20/utils/SafeERC20.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../IERC20.sol\";\nimport \"../extensions/draft-IERC20Permit.sol\";\nimport \"../../../utils/Address.sol\";\n\n/**\n * @title SafeERC20\n * @dev Wrappers around ERC20 operations that throw on failure (when the token\n * contract returns false). Tokens that return no value (and instead revert or\n * throw on failure) are also supported, non-reverting calls are assumed to be\n * successful.\n * To use this library you can add a `using SafeERC20 for IERC20;` statement to your contract,\n * which allows you to call the safe operations as `token.safeTransfer(...)`, etc.\n */\nlibrary SafeERC20 {\n using Address for address;\n\n function safeTransfer(\n IERC20 token,\n address to,\n uint256 value\n ) internal {\n _callOptionalReturn(token, abi.encodeWithSelector(token.transfer.selector, to, value));\n }\n\n function safeTransferFrom(\n IERC20 token,\n address from,\n address to,\n uint256 value\n ) internal {\n _callOptionalReturn(token, abi.encodeWithSelector(token.transferFrom.selector, from, to, value));\n }\n\n /**\n * @dev Deprecated. This function has issues similar to the ones found in\n * {IERC20-approve}, and its usage is discouraged.\n *\n * Whenever possible, use {safeIncreaseAllowance} and\n * {safeDecreaseAllowance} instead.\n */\n function safeApprove(\n IERC20 token,\n address spender,\n uint256 value\n ) internal {\n // safeApprove should only be called when setting an initial allowance,\n // or when resetting it to zero. To increase and decrease it, use\n // 'safeIncreaseAllowance' and 'safeDecreaseAllowance'\n require(\n (value == 0) || (token.allowance(address(this), spender) == 0),\n \"SafeERC20: approve from non-zero to non-zero allowance\"\n );\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, value));\n }\n\n function safeIncreaseAllowance(\n IERC20 token,\n address spender,\n uint256 value\n ) internal {\n uint256 newAllowance = token.allowance(address(this), spender) + value;\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));\n }\n\n function safeDecreaseAllowance(\n IERC20 token,\n address spender,\n uint256 value\n ) internal {\n unchecked {\n uint256 oldAllowance = token.allowance(address(this), spender);\n require(oldAllowance >= value, \"SafeERC20: decreased allowance below zero\");\n uint256 newAllowance = oldAllowance - value;\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));\n }\n }\n\n function safePermit(\n IERC20Permit token,\n address owner,\n address spender,\n uint256 value,\n uint256 deadline,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) internal {\n uint256 nonceBefore = token.nonces(owner);\n token.permit(owner, spender, value, deadline, v, r, s);\n uint256 nonceAfter = token.nonces(owner);\n require(nonceAfter == nonceBefore + 1, \"SafeERC20: permit did not succeed\");\n }\n\n /**\n * @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement\n * on the return value: the return value is optional (but if data is returned, it must not be false).\n * @param token The token targeted by the call.\n * @param data The call data (encoded using abi.encode or one of its variants).\n */\n function _callOptionalReturn(IERC20 token, bytes memory data) private {\n // We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since\n // we're implementing it ourselves. We use {Address.functionCall} to perform this call, which verifies that\n // the target address contains contract code and also asserts for success in the low-level call.\n\n bytes memory returndata = address(token).functionCall(data, \"SafeERC20: low-level call failed\");\n if (returndata.length > 0) {\n // Return data is optional\n require(abi.decode(returndata, (bool)), \"SafeERC20: ERC20 operation did not succeed\");\n }\n }\n}\n" + }, + "@openzeppelin/contracts/token/ERC721/extensions/IERC721Metadata.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (token/ERC721/extensions/IERC721Metadata.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../IERC721.sol\";\n\n/**\n * @title ERC-721 Non-Fungible Token Standard, optional metadata extension\n * @dev See https://eips.ethereum.org/EIPS/eip-721\n */\ninterface IERC721Metadata is IERC721 {\n /**\n * @dev Returns the token collection name.\n */\n function name() external view returns (string memory);\n\n /**\n * @dev Returns the token collection symbol.\n */\n function symbol() external view returns (string memory);\n\n /**\n * @dev Returns the Uniform Resource Identifier (URI) for `tokenId` token.\n */\n function tokenURI(uint256 tokenId) external view returns (string memory);\n}\n" + }, + "@openzeppelin/contracts/token/ERC721/IERC721.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (token/ERC721/IERC721.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../../utils/introspection/IERC165.sol\";\n\n/**\n * @dev Required interface of an ERC721 compliant contract.\n */\ninterface IERC721 is IERC165 {\n /**\n * @dev Emitted when `tokenId` token is transferred from `from` to `to`.\n */\n event Transfer(address indexed from, address indexed to, uint256 indexed tokenId);\n\n /**\n * @dev Emitted when `owner` enables `approved` to manage the `tokenId` token.\n */\n event Approval(address indexed owner, address indexed approved, uint256 indexed tokenId);\n\n /**\n * @dev Emitted when `owner` enables or disables (`approved`) `operator` to manage all of its assets.\n */\n event ApprovalForAll(address indexed owner, address indexed operator, bool approved);\n\n /**\n * @dev Returns the number of tokens in ``owner``'s account.\n */\n function balanceOf(address owner) external view returns (uint256 balance);\n\n /**\n * @dev Returns the owner of the `tokenId` token.\n *\n * Requirements:\n *\n * - `tokenId` must exist.\n */\n function ownerOf(uint256 tokenId) external view returns (address owner);\n\n /**\n * @dev Safely transfers `tokenId` token from `from` to `to`.\n *\n * Requirements:\n *\n * - `from` cannot be the zero address.\n * - `to` cannot be the zero address.\n * - `tokenId` token must exist and be owned by `from`.\n * - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}.\n * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.\n *\n * Emits a {Transfer} event.\n */\n function safeTransferFrom(\n address from,\n address to,\n uint256 tokenId,\n bytes calldata data\n ) external;\n\n /**\n * @dev Safely transfers `tokenId` token from `from` to `to`, checking first that contract recipients\n * are aware of the ERC721 protocol to prevent tokens from being forever locked.\n *\n * Requirements:\n *\n * - `from` cannot be the zero address.\n * - `to` cannot be the zero address.\n * - `tokenId` token must exist and be owned by `from`.\n * - If the caller is not `from`, it must have been allowed to move this token by either {approve} or {setApprovalForAll}.\n * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.\n *\n * Emits a {Transfer} event.\n */\n function safeTransferFrom(\n address from,\n address to,\n uint256 tokenId\n ) external;\n\n /**\n * @dev Transfers `tokenId` token from `from` to `to`.\n *\n * WARNING: Usage of this method is discouraged, use {safeTransferFrom} whenever possible.\n *\n * Requirements:\n *\n * - `from` cannot be the zero address.\n * - `to` cannot be the zero address.\n * - `tokenId` token must be owned by `from`.\n * - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}.\n *\n * Emits a {Transfer} event.\n */\n function transferFrom(\n address from,\n address to,\n uint256 tokenId\n ) external;\n\n /**\n * @dev Gives permission to `to` to transfer `tokenId` token to another account.\n * The approval is cleared when the token is transferred.\n *\n * Only a single account can be approved at a time, so approving the zero address clears previous approvals.\n *\n * Requirements:\n *\n * - The caller must own the token or be an approved operator.\n * - `tokenId` must exist.\n *\n * Emits an {Approval} event.\n */\n function approve(address to, uint256 tokenId) external;\n\n /**\n * @dev Approve or remove `operator` as an operator for the caller.\n * Operators can call {transferFrom} or {safeTransferFrom} for any token owned by the caller.\n *\n * Requirements:\n *\n * - The `operator` cannot be the caller.\n *\n * Emits an {ApprovalForAll} event.\n */\n function setApprovalForAll(address operator, bool _approved) external;\n\n /**\n * @dev Returns the account approved for `tokenId` token.\n *\n * Requirements:\n *\n * - `tokenId` must exist.\n */\n function getApproved(uint256 tokenId) external view returns (address operator);\n\n /**\n * @dev Returns if the `operator` is allowed to manage all of the assets of `owner`.\n *\n * See {setApprovalForAll}\n */\n function isApprovedForAll(address owner, address operator) external view returns (bool);\n}\n" + }, + "@openzeppelin/contracts/utils/Address.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (utils/Address.sol)\n\npragma solidity ^0.8.1;\n\n/**\n * @dev Collection of functions related to the address type\n */\nlibrary Address {\n /**\n * @dev Returns true if `account` is a contract.\n *\n * [IMPORTANT]\n * ====\n * It is unsafe to assume that an address for which this function returns\n * false is an externally-owned account (EOA) and not a contract.\n *\n * Among others, `isContract` will return false for the following\n * types of addresses:\n *\n * - an externally-owned account\n * - a contract in construction\n * - an address where a contract will be created\n * - an address where a contract lived, but was destroyed\n * ====\n *\n * [IMPORTANT]\n * ====\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\n *\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\n * constructor.\n * ====\n */\n function isContract(address account) internal view returns (bool) {\n // This method relies on extcodesize/address.code.length, which returns 0\n // for contracts in construction, since the code is only stored at the end\n // of the constructor execution.\n\n return account.code.length > 0;\n }\n\n /**\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\n * `recipient`, forwarding all available gas and reverting on errors.\n *\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\n * imposed by `transfer`, making them unable to receive funds via\n * `transfer`. {sendValue} removes this limitation.\n *\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\n *\n * IMPORTANT: because control is transferred to `recipient`, care must be\n * taken to not create reentrancy vulnerabilities. Consider using\n * {ReentrancyGuard} or the\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\n */\n function sendValue(address payable recipient, uint256 amount) internal {\n require(address(this).balance >= amount, \"Address: insufficient balance\");\n\n (bool success, ) = recipient.call{value: amount}(\"\");\n require(success, \"Address: unable to send value, recipient may have reverted\");\n }\n\n /**\n * @dev Performs a Solidity function call using a low level `call`. A\n * plain `call` is an unsafe replacement for a function call: use this\n * function instead.\n *\n * If `target` reverts with a revert reason, it is bubbled up by this\n * function (like regular Solidity function calls).\n *\n * Returns the raw returned data. To convert to the expected return value,\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\n *\n * Requirements:\n *\n * - `target` must be a contract.\n * - calling `target` with `data` must not revert.\n *\n * _Available since v3.1._\n */\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionCall(target, data, \"Address: low-level call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\n * `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, 0, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but also transferring `value` wei to `target`.\n *\n * Requirements:\n *\n * - the calling contract must have an ETH balance of at least `value`.\n * - the called Solidity function must be `payable`.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, value, \"Address: low-level call with value failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\n * with `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(address(this).balance >= value, \"Address: insufficient balance for call\");\n require(isContract(target), \"Address: call to non-contract\");\n\n (bool success, bytes memory returndata) = target.call{value: value}(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\n return functionStaticCall(target, data, \"Address: low-level static call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal view returns (bytes memory) {\n require(isContract(target), \"Address: static call to non-contract\");\n\n (bool success, bytes memory returndata) = target.staticcall(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a delegate call.\n *\n * _Available since v3.4._\n */\n function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionDelegateCall(target, data, \"Address: low-level delegate call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a delegate call.\n *\n * _Available since v3.4._\n */\n function functionDelegateCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(isContract(target), \"Address: delegate call to non-contract\");\n\n (bool success, bytes memory returndata) = target.delegatecall(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the\n * revert reason using the provided one.\n *\n * _Available since v4.3._\n */\n function verifyCallResult(\n bool success,\n bytes memory returndata,\n string memory errorMessage\n ) internal pure returns (bytes memory) {\n if (success) {\n return returndata;\n } else {\n // Look for revert reason and bubble it up if present\n if (returndata.length > 0) {\n // The easiest way to bubble the revert reason is using memory via assembly\n /// @solidity memory-safe-assembly\n assembly {\n let returndata_size := mload(returndata)\n revert(add(32, returndata), returndata_size)\n }\n } else {\n revert(errorMessage);\n }\n }\n }\n}\n" + }, + "@openzeppelin/contracts/utils/Context.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Provides information about the current execution context, including the\n * sender of the transaction and its data. While these are generally available\n * via msg.sender and msg.data, they should not be accessed in such a direct\n * manner, since when dealing with meta-transactions the account sending and\n * paying for execution may not be the actual sender (as far as an application\n * is concerned).\n *\n * This contract is only required for intermediate, library-like contracts.\n */\nabstract contract Context {\n function _msgSender() internal view virtual returns (address) {\n return msg.sender;\n }\n\n function _msgData() internal view virtual returns (bytes calldata) {\n return msg.data;\n }\n}\n" + }, + "@openzeppelin/contracts/utils/Counters.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (utils/Counters.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @title Counters\n * @author Matt Condon (@shrugs)\n * @dev Provides counters that can only be incremented, decremented or reset. This can be used e.g. to track the number\n * of elements in a mapping, issuing ERC721 ids, or counting request ids.\n *\n * Include with `using Counters for Counters.Counter;`\n */\nlibrary Counters {\n struct Counter {\n // This variable should never be directly accessed by users of the library: interactions must be restricted to\n // the library's function. As of Solidity v0.5.2, this cannot be enforced, though there is a proposal to add\n // this feature: see https://github.com/ethereum/solidity/issues/4637\n uint256 _value; // default: 0\n }\n\n function current(Counter storage counter) internal view returns (uint256) {\n return counter._value;\n }\n\n function increment(Counter storage counter) internal {\n unchecked {\n counter._value += 1;\n }\n }\n\n function decrement(Counter storage counter) internal {\n uint256 value = counter._value;\n require(value > 0, \"Counter: decrement overflow\");\n unchecked {\n counter._value = value - 1;\n }\n }\n\n function reset(Counter storage counter) internal {\n counter._value = 0;\n }\n}\n" + }, + "@openzeppelin/contracts/utils/cryptography/draft-EIP712.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (utils/cryptography/draft-EIP712.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./ECDSA.sol\";\n\n/**\n * @dev https://eips.ethereum.org/EIPS/eip-712[EIP 712] is a standard for hashing and signing of typed structured data.\n *\n * The encoding specified in the EIP is very generic, and such a generic implementation in Solidity is not feasible,\n * thus this contract does not implement the encoding itself. Protocols need to implement the type-specific encoding\n * they need in their contracts using a combination of `abi.encode` and `keccak256`.\n *\n * This contract implements the EIP 712 domain separator ({_domainSeparatorV4}) that is used as part of the encoding\n * scheme, and the final step of the encoding to obtain the message digest that is then signed via ECDSA\n * ({_hashTypedDataV4}).\n *\n * The implementation of the domain separator was designed to be as efficient as possible while still properly updating\n * the chain id to protect against replay attacks on an eventual fork of the chain.\n *\n * NOTE: This contract implements the version of the encoding known as \"v4\", as implemented by the JSON RPC method\n * https://docs.metamask.io/guide/signing-data.html[`eth_signTypedDataV4` in MetaMask].\n *\n * _Available since v3.4._\n */\nabstract contract EIP712 {\n /* solhint-disable var-name-mixedcase */\n // Cache the domain separator as an immutable value, but also store the chain id that it corresponds to, in order to\n // invalidate the cached domain separator if the chain id changes.\n bytes32 private immutable _CACHED_DOMAIN_SEPARATOR;\n uint256 private immutable _CACHED_CHAIN_ID;\n address private immutable _CACHED_THIS;\n\n bytes32 private immutable _HASHED_NAME;\n bytes32 private immutable _HASHED_VERSION;\n bytes32 private immutable _TYPE_HASH;\n\n /* solhint-enable var-name-mixedcase */\n\n /**\n * @dev Initializes the domain separator and parameter caches.\n *\n * The meaning of `name` and `version` is specified in\n * https://eips.ethereum.org/EIPS/eip-712#definition-of-domainseparator[EIP 712]:\n *\n * - `name`: the user readable name of the signing domain, i.e. the name of the DApp or the protocol.\n * - `version`: the current major version of the signing domain.\n *\n * NOTE: These parameters cannot be changed except through a xref:learn::upgrading-smart-contracts.adoc[smart\n * contract upgrade].\n */\n constructor(string memory name, string memory version) {\n bytes32 hashedName = keccak256(bytes(name));\n bytes32 hashedVersion = keccak256(bytes(version));\n bytes32 typeHash = keccak256(\n \"EIP712Domain(string name,string version,uint256 chainId,address verifyingContract)\"\n );\n _HASHED_NAME = hashedName;\n _HASHED_VERSION = hashedVersion;\n _CACHED_CHAIN_ID = block.chainid;\n _CACHED_DOMAIN_SEPARATOR = _buildDomainSeparator(typeHash, hashedName, hashedVersion);\n _CACHED_THIS = address(this);\n _TYPE_HASH = typeHash;\n }\n\n /**\n * @dev Returns the domain separator for the current chain.\n */\n function _domainSeparatorV4() internal view returns (bytes32) {\n if (address(this) == _CACHED_THIS && block.chainid == _CACHED_CHAIN_ID) {\n return _CACHED_DOMAIN_SEPARATOR;\n } else {\n return _buildDomainSeparator(_TYPE_HASH, _HASHED_NAME, _HASHED_VERSION);\n }\n }\n\n function _buildDomainSeparator(\n bytes32 typeHash,\n bytes32 nameHash,\n bytes32 versionHash\n ) private view returns (bytes32) {\n return keccak256(abi.encode(typeHash, nameHash, versionHash, block.chainid, address(this)));\n }\n\n /**\n * @dev Given an already https://eips.ethereum.org/EIPS/eip-712#definition-of-hashstruct[hashed struct], this\n * function returns the hash of the fully encoded EIP712 message for this domain.\n *\n * This hash can be used together with {ECDSA-recover} to obtain the signer of a message. For example:\n *\n * ```solidity\n * bytes32 digest = _hashTypedDataV4(keccak256(abi.encode(\n * keccak256(\"Mail(address to,string contents)\"),\n * mailTo,\n * keccak256(bytes(mailContents))\n * )));\n * address signer = ECDSA.recover(digest, signature);\n * ```\n */\n function _hashTypedDataV4(bytes32 structHash) internal view virtual returns (bytes32) {\n return ECDSA.toTypedDataHash(_domainSeparatorV4(), structHash);\n }\n}\n" + }, + "@openzeppelin/contracts/utils/cryptography/ECDSA.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (utils/cryptography/ECDSA.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../Strings.sol\";\n\n/**\n * @dev Elliptic Curve Digital Signature Algorithm (ECDSA) operations.\n *\n * These functions can be used to verify that a message was signed by the holder\n * of the private keys of a given address.\n */\nlibrary ECDSA {\n enum RecoverError {\n NoError,\n InvalidSignature,\n InvalidSignatureLength,\n InvalidSignatureS,\n InvalidSignatureV\n }\n\n function _throwError(RecoverError error) private pure {\n if (error == RecoverError.NoError) {\n return; // no error: do nothing\n } else if (error == RecoverError.InvalidSignature) {\n revert(\"ECDSA: invalid signature\");\n } else if (error == RecoverError.InvalidSignatureLength) {\n revert(\"ECDSA: invalid signature length\");\n } else if (error == RecoverError.InvalidSignatureS) {\n revert(\"ECDSA: invalid signature 's' value\");\n } else if (error == RecoverError.InvalidSignatureV) {\n revert(\"ECDSA: invalid signature 'v' value\");\n }\n }\n\n /**\n * @dev Returns the address that signed a hashed message (`hash`) with\n * `signature` or error string. This address can then be used for verification purposes.\n *\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\n * this function rejects them by requiring the `s` value to be in the lower\n * half order, and the `v` value to be either 27 or 28.\n *\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\n * verification to be secure: it is possible to craft signatures that\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\n * this is by receiving a hash of the original message (which may otherwise\n * be too long), and then calling {toEthSignedMessageHash} on it.\n *\n * Documentation for signature generation:\n * - with https://web3js.readthedocs.io/en/v1.3.4/web3-eth-accounts.html#sign[Web3.js]\n * - with https://docs.ethers.io/v5/api/signer/#Signer-signMessage[ethers]\n *\n * _Available since v4.3._\n */\n function tryRecover(bytes32 hash, bytes memory signature) internal pure returns (address, RecoverError) {\n // Check the signature length\n // - case 65: r,s,v signature (standard)\n // - case 64: r,vs signature (cf https://eips.ethereum.org/EIPS/eip-2098) _Available since v4.1._\n if (signature.length == 65) {\n bytes32 r;\n bytes32 s;\n uint8 v;\n // ecrecover takes the signature parameters, and the only way to get them\n // currently is to use assembly.\n /// @solidity memory-safe-assembly\n assembly {\n r := mload(add(signature, 0x20))\n s := mload(add(signature, 0x40))\n v := byte(0, mload(add(signature, 0x60)))\n }\n return tryRecover(hash, v, r, s);\n } else if (signature.length == 64) {\n bytes32 r;\n bytes32 vs;\n // ecrecover takes the signature parameters, and the only way to get them\n // currently is to use assembly.\n /// @solidity memory-safe-assembly\n assembly {\n r := mload(add(signature, 0x20))\n vs := mload(add(signature, 0x40))\n }\n return tryRecover(hash, r, vs);\n } else {\n return (address(0), RecoverError.InvalidSignatureLength);\n }\n }\n\n /**\n * @dev Returns the address that signed a hashed message (`hash`) with\n * `signature`. This address can then be used for verification purposes.\n *\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\n * this function rejects them by requiring the `s` value to be in the lower\n * half order, and the `v` value to be either 27 or 28.\n *\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\n * verification to be secure: it is possible to craft signatures that\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\n * this is by receiving a hash of the original message (which may otherwise\n * be too long), and then calling {toEthSignedMessageHash} on it.\n */\n function recover(bytes32 hash, bytes memory signature) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, signature);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Overload of {ECDSA-tryRecover} that receives the `r` and `vs` short-signature fields separately.\n *\n * See https://eips.ethereum.org/EIPS/eip-2098[EIP-2098 short signatures]\n *\n * _Available since v4.3._\n */\n function tryRecover(\n bytes32 hash,\n bytes32 r,\n bytes32 vs\n ) internal pure returns (address, RecoverError) {\n bytes32 s = vs & bytes32(0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff);\n uint8 v = uint8((uint256(vs) >> 255) + 27);\n return tryRecover(hash, v, r, s);\n }\n\n /**\n * @dev Overload of {ECDSA-recover} that receives the `r and `vs` short-signature fields separately.\n *\n * _Available since v4.2._\n */\n function recover(\n bytes32 hash,\n bytes32 r,\n bytes32 vs\n ) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, r, vs);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Overload of {ECDSA-tryRecover} that receives the `v`,\n * `r` and `s` signature fields separately.\n *\n * _Available since v4.3._\n */\n function tryRecover(\n bytes32 hash,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) internal pure returns (address, RecoverError) {\n // EIP-2 still allows signature malleability for ecrecover(). Remove this possibility and make the signature\n // unique. Appendix F in the Ethereum Yellow paper (https://ethereum.github.io/yellowpaper/paper.pdf), defines\n // the valid range for s in (301): 0 < s < secp256k1n ÷ 2 + 1, and for v in (302): v ∈ {27, 28}. Most\n // signatures from current libraries generate a unique signature with an s-value in the lower half order.\n //\n // If your library generates malleable signatures, such as s-values in the upper range, calculate a new s-value\n // with 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141 - s1 and flip v from 27 to 28 or\n // vice versa. If your library also generates signatures with 0/1 for v instead 27/28, add 27 to v to accept\n // these malleable signatures as well.\n if (uint256(s) > 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D576E7357A4501DDFE92F46681B20A0) {\n return (address(0), RecoverError.InvalidSignatureS);\n }\n if (v != 27 && v != 28) {\n return (address(0), RecoverError.InvalidSignatureV);\n }\n\n // If the signature is valid (and not malleable), return the signer address\n address signer = ecrecover(hash, v, r, s);\n if (signer == address(0)) {\n return (address(0), RecoverError.InvalidSignature);\n }\n\n return (signer, RecoverError.NoError);\n }\n\n /**\n * @dev Overload of {ECDSA-recover} that receives the `v`,\n * `r` and `s` signature fields separately.\n */\n function recover(\n bytes32 hash,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, v, r, s);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Returns an Ethereum Signed Message, created from a `hash`. This\n * produces hash corresponding to the one signed with the\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\n * JSON-RPC method as part of EIP-191.\n *\n * See {recover}.\n */\n function toEthSignedMessageHash(bytes32 hash) internal pure returns (bytes32) {\n // 32 is the length in bytes of hash,\n // enforced by the type signature above\n return keccak256(abi.encodePacked(\"\\x19Ethereum Signed Message:\\n32\", hash));\n }\n\n /**\n * @dev Returns an Ethereum Signed Message, created from `s`. This\n * produces hash corresponding to the one signed with the\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\n * JSON-RPC method as part of EIP-191.\n *\n * See {recover}.\n */\n function toEthSignedMessageHash(bytes memory s) internal pure returns (bytes32) {\n return keccak256(abi.encodePacked(\"\\x19Ethereum Signed Message:\\n\", Strings.toString(s.length), s));\n }\n\n /**\n * @dev Returns an Ethereum Signed Typed Data, created from a\n * `domainSeparator` and a `structHash`. This produces hash corresponding\n * to the one signed with the\n * https://eips.ethereum.org/EIPS/eip-712[`eth_signTypedData`]\n * JSON-RPC method as part of EIP-712.\n *\n * See {recover}.\n */\n function toTypedDataHash(bytes32 domainSeparator, bytes32 structHash) internal pure returns (bytes32) {\n return keccak256(abi.encodePacked(\"\\x19\\x01\", domainSeparator, structHash));\n }\n}\n" + }, + "@openzeppelin/contracts/utils/introspection/IERC165.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (utils/introspection/IERC165.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Interface of the ERC165 standard, as defined in the\n * https://eips.ethereum.org/EIPS/eip-165[EIP].\n *\n * Implementers can declare support of contract interfaces, which can then be\n * queried by others ({ERC165Checker}).\n *\n * For an implementation, see {ERC165}.\n */\ninterface IERC165 {\n /**\n * @dev Returns true if this contract implements the interface defined by\n * `interfaceId`. See the corresponding\n * https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified[EIP section]\n * to learn more about how these ids are created.\n *\n * This function call must use less than 30 000 gas.\n */\n function supportsInterface(bytes4 interfaceId) external view returns (bool);\n}\n" + }, + "@openzeppelin/contracts/utils/StorageSlot.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (utils/StorageSlot.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Library for reading and writing primitive types to specific storage slots.\n *\n * Storage slots are often used to avoid storage conflict when dealing with upgradeable contracts.\n * This library helps with reading and writing to such slots without the need for inline assembly.\n *\n * The functions in this library return Slot structs that contain a `value` member that can be used to read or write.\n *\n * Example usage to set ERC1967 implementation slot:\n * ```\n * contract ERC1967 {\n * bytes32 internal constant _IMPLEMENTATION_SLOT = 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc;\n *\n * function _getImplementation() internal view returns (address) {\n * return StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value;\n * }\n *\n * function _setImplementation(address newImplementation) internal {\n * require(Address.isContract(newImplementation), \"ERC1967: new implementation is not a contract\");\n * StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value = newImplementation;\n * }\n * }\n * ```\n *\n * _Available since v4.1 for `address`, `bool`, `bytes32`, and `uint256`._\n */\nlibrary StorageSlot {\n struct AddressSlot {\n address value;\n }\n\n struct BooleanSlot {\n bool value;\n }\n\n struct Bytes32Slot {\n bytes32 value;\n }\n\n struct Uint256Slot {\n uint256 value;\n }\n\n /**\n * @dev Returns an `AddressSlot` with member `value` located at `slot`.\n */\n function getAddressSlot(bytes32 slot) internal pure returns (AddressSlot storage r) {\n /// @solidity memory-safe-assembly\n assembly {\n r.slot := slot\n }\n }\n\n /**\n * @dev Returns an `BooleanSlot` with member `value` located at `slot`.\n */\n function getBooleanSlot(bytes32 slot) internal pure returns (BooleanSlot storage r) {\n /// @solidity memory-safe-assembly\n assembly {\n r.slot := slot\n }\n }\n\n /**\n * @dev Returns an `Bytes32Slot` with member `value` located at `slot`.\n */\n function getBytes32Slot(bytes32 slot) internal pure returns (Bytes32Slot storage r) {\n /// @solidity memory-safe-assembly\n assembly {\n r.slot := slot\n }\n }\n\n /**\n * @dev Returns an `Uint256Slot` with member `value` located at `slot`.\n */\n function getUint256Slot(bytes32 slot) internal pure returns (Uint256Slot storage r) {\n /// @solidity memory-safe-assembly\n assembly {\n r.slot := slot\n }\n }\n}\n" + }, + "@openzeppelin/contracts/utils/Strings.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (utils/Strings.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev String operations.\n */\nlibrary Strings {\n bytes16 private constant _HEX_SYMBOLS = \"0123456789abcdef\";\n uint8 private constant _ADDRESS_LENGTH = 20;\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` decimal representation.\n */\n function toString(uint256 value) internal pure returns (string memory) {\n // Inspired by OraclizeAPI's implementation - MIT licence\n // https://github.com/oraclize/ethereum-api/blob/b42146b063c7d6ee1358846c198246239e9360e8/oraclizeAPI_0.4.25.sol\n\n if (value == 0) {\n return \"0\";\n }\n uint256 temp = value;\n uint256 digits;\n while (temp != 0) {\n digits++;\n temp /= 10;\n }\n bytes memory buffer = new bytes(digits);\n while (value != 0) {\n digits -= 1;\n buffer[digits] = bytes1(uint8(48 + uint256(value % 10)));\n value /= 10;\n }\n return string(buffer);\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation.\n */\n function toHexString(uint256 value) internal pure returns (string memory) {\n if (value == 0) {\n return \"0x00\";\n }\n uint256 temp = value;\n uint256 length = 0;\n while (temp != 0) {\n length++;\n temp >>= 8;\n }\n return toHexString(value, length);\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length.\n */\n function toHexString(uint256 value, uint256 length) internal pure returns (string memory) {\n bytes memory buffer = new bytes(2 * length + 2);\n buffer[0] = \"0\";\n buffer[1] = \"x\";\n for (uint256 i = 2 * length + 1; i > 1; --i) {\n buffer[i] = _HEX_SYMBOLS[value & 0xf];\n value >>= 4;\n }\n require(value == 0, \"Strings: hex length insufficient\");\n return string(buffer);\n }\n\n /**\n * @dev Converts an `address` with fixed length of 20 bytes to its not checksummed ASCII `string` hexadecimal representation.\n */\n function toHexString(address addr) internal pure returns (string memory) {\n return toHexString(uint256(uint160(addr)), _ADDRESS_LENGTH);\n }\n}\n" + }, + "contracts/agToken/AgEUR.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\nimport \"../interfaces/IAgToken.sol\";\nimport \"../interfaces/coreModule/IStableMaster.sol\";\nimport \"../interfaces/ITreasury.sol\";\nimport \"@openzeppelin/contracts-upgradeable/token/ERC20/extensions/draft-ERC20PermitUpgradeable.sol\";\n\n/// @title AgEUR\n/// @author Angle Labs, Inc.\n/// @notice Base contract for agEUR, Angle's Euro stablecoin\n/// @dev This contract is an upgraded version of the agEUR contract that was first deployed on Ethereum mainnet\ncontract AgEUR is IAgToken, ERC20PermitUpgradeable {\n // ================================= REFERENCES ================================\n\n /// @notice Reference to the `StableMaster` contract associated to agEUR\n address public stableMaster;\n\n /// @custom:oz-upgrades-unsafe-allow constructor\n constructor() initializer {}\n\n // ============================== ADDED PARAMETERS =============================\n\n /// @inheritdoc IAgToken\n mapping(address => bool) public isMinter;\n /// @notice Reference to the treasury contract which can grant minting rights\n address public treasury;\n /// @notice Boolean used to check whether the contract had been reinitialized after an upgrade\n bool public treasuryInitialized;\n\n // =================================== EVENTS ==================================\n\n event TreasuryUpdated(address indexed _treasury);\n event MinterToggled(address indexed minter);\n\n // =================================== ERRORS ==================================\n\n error BurnAmountExceedsAllowance();\n error InvalidSender();\n error InvalidTreasury();\n error NotGovernor();\n error NotMinter();\n error NotTreasury();\n error TreasuryAlreadyInitialized();\n\n // ================================= MODIFIERS =================================\n\n /// @notice Checks to see if it is the `Treasury` calling this contract\n modifier onlyTreasury() {\n if (msg.sender != treasury) revert NotTreasury();\n _;\n }\n\n /// @notice Checks whether the sender has the minting right\n modifier onlyMinter() {\n if (!isMinter[msg.sender]) revert NotMinter();\n _;\n }\n\n // ============================= EXTERNAL FUNCTION =============================\n\n /// @notice Allows anyone to burn stablecoins\n /// @param amount Amount of stablecoins to burn\n /// @dev This function can typically be called if there is a settlement mechanism to burn stablecoins\n function burnStablecoin(uint256 amount) external {\n _burn(msg.sender, amount);\n }\n\n // ========================= MINTER ROLE ONLY FUNCTIONS ========================\n\n /// @inheritdoc IAgToken\n function burnSelf(uint256 amount, address burner) external onlyMinter {\n _burn(burner, amount);\n }\n\n /// @inheritdoc IAgToken\n function burnFrom(uint256 amount, address burner, address sender) external onlyMinter {\n if (burner != sender) {\n uint256 currentAllowance = allowance(burner, sender);\n if (currentAllowance < amount) revert BurnAmountExceedsAllowance();\n _approve(burner, sender, currentAllowance - amount);\n }\n _burn(burner, amount);\n }\n\n /// @inheritdoc IAgToken\n function mint(address account, uint256 amount) external onlyMinter {\n _mint(account, amount);\n }\n\n // ========================== TREASURY ONLY FUNCTIONS ==========================\n\n /// @inheritdoc IAgToken\n function addMinter(address minter) external onlyTreasury {\n isMinter[minter] = true;\n emit MinterToggled(minter);\n }\n\n /// @inheritdoc IAgToken\n function removeMinter(address minter) external {\n if (msg.sender != minter && msg.sender != address(treasury)) revert InvalidSender();\n isMinter[minter] = false;\n emit MinterToggled(minter);\n }\n\n /// @inheritdoc IAgToken\n function setTreasury(address _treasury) external onlyTreasury {\n treasury = _treasury;\n emit TreasuryUpdated(_treasury);\n }\n}\n" + }, + "contracts/agToken/AgToken.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\n/*\n * █ \n ***** ▓▓▓ \n * ▓▓▓▓▓▓▓ \n * ///. ▓▓▓▓▓▓▓▓▓▓▓▓▓ \n ***** //////// ▓▓▓▓▓▓▓ \n * ///////////// ▓▓▓ \n ▓▓ ////////////////// █ ▓▓ \n ▓▓ ▓▓ /////////////////////// ▓▓ ▓▓ \n ▓▓ ▓▓ //////////////////////////// ▓▓ ▓▓ \n ▓▓ ▓▓ /////////▓▓▓///////▓▓▓///////// ▓▓ ▓▓ \n ▓▓ ,////////////////////////////////////// ▓▓ ▓▓ \n ▓▓ ////////////////////////////////////////// ▓▓ \n ▓▓ //////////////////////▓▓▓▓///////////////////// \n ,//////////////////////////////////////////////////// \n .////////////////////////////////////////////////////////// \n .//////////////////////////██.,//////////////////////////█ \n .//////////////////////████..,./////////////////////██ \n ...////////////////███████.....,.////////////////███ \n ,.,////////////████████ ........,///////////████ \n .,.,//////█████████ ,.......///////████ \n ,..//████████ ........./████ \n ..,██████ .....,███ \n .██ ,.,█ \n \n \n \n ▓▓ ▓▓▓▓▓▓▓▓▓▓ ▓▓▓▓▓▓▓▓▓▓ ▓▓ ▓▓▓▓▓▓▓▓▓▓ \n ▓▓▓▓▓▓ ▓▓▓ ▓▓▓ ▓▓▓ ▓▓ ▓▓ ▓▓▓▓ \n ▓▓▓ ▓▓▓ ▓▓▓ ▓▓▓ ▓▓▓ ▓▓▓ ▓▓ ▓▓▓▓▓ \n ▓▓▓ ▓▓ ▓▓▓ ▓▓▓ ▓▓▓▓▓▓▓▓▓▓ ▓▓▓▓▓▓▓▓▓▓ ▓▓▓▓▓▓▓▓▓▓ \n*/\n\nimport \"../interfaces/IAgToken.sol\";\nimport \"../interfaces/ITreasury.sol\";\nimport \"@openzeppelin/contracts-upgradeable/token/ERC20/extensions/draft-ERC20PermitUpgradeable.sol\";\n\n/// @title AgToken\n/// @author Angle Labs, Inc.\n/// @notice Base contract for Angle agTokens on Ethereum and on other chains\n/// @dev By default, agTokens are ERC-20 tokens with 18 decimals\ncontract AgToken is IAgToken, ERC20PermitUpgradeable {\n // =========================== PARAMETERS / VARIABLES ==========================\n\n /// @inheritdoc IAgToken\n mapping(address => bool) public isMinter;\n /// @notice Reference to the treasury contract which can grant minting rights\n address public treasury;\n\n // =================================== EVENTS ==================================\n\n event TreasuryUpdated(address indexed _treasury);\n event MinterToggled(address indexed minter);\n\n // =================================== ERRORS ==================================\n\n error BurnAmountExceedsAllowance();\n error InvalidSender();\n error InvalidTreasury();\n error NotMinter();\n error NotTreasury();\n\n // ================================ CONSTRUCTOR ================================\n\n /// @custom:oz-upgrades-unsafe-allow constructor\n constructor() initializer {}\n\n /// @notice Initializes the `AgToken` contract\n function initialize(string memory name_, string memory symbol_, address _treasury) external {\n _initialize(name_, symbol_, _treasury);\n }\n\n /// @notice Initializes the contract\n function _initialize(string memory name_, string memory symbol_, address _treasury) internal virtual initializer {\n if (address(ITreasury(_treasury).stablecoin()) != address(this)) revert InvalidTreasury();\n __ERC20Permit_init(name_);\n __ERC20_init(name_, symbol_);\n treasury = _treasury;\n emit TreasuryUpdated(_treasury);\n }\n\n // ================================= MODIFIERS =================================\n\n /// @notice Checks to see if it is the `Treasury` calling this contract\n modifier onlyTreasury() {\n if (msg.sender != treasury) revert NotTreasury();\n _;\n }\n\n /// @notice Checks whether the sender has the minting right\n modifier onlyMinter() {\n if (!isMinter[msg.sender]) revert NotMinter();\n _;\n }\n\n // ============================= EXTERNAL FUNCTION =============================\n\n /// @notice Allows anyone to burn stablecoins\n /// @param amount Amount of stablecoins to burn\n /// @dev This function can typically be called if there is a settlement mechanism to burn stablecoins\n function burnStablecoin(uint256 amount) external {\n _burn(msg.sender, amount);\n }\n\n // ========================= MINTER ROLE ONLY FUNCTIONS ========================\n\n /// @inheritdoc IAgToken\n function burnSelf(uint256 amount, address burner) external onlyMinter {\n _burn(burner, amount);\n }\n\n /// @inheritdoc IAgToken\n function burnFrom(uint256 amount, address burner, address sender) external onlyMinter {\n if (burner != sender) {\n uint256 currentAllowance = allowance(burner, sender);\n if (currentAllowance < amount) revert BurnAmountExceedsAllowance();\n _approve(burner, sender, currentAllowance - amount);\n }\n _burn(burner, amount);\n }\n\n /// @inheritdoc IAgToken\n function mint(address account, uint256 amount) external onlyMinter {\n _mint(account, amount);\n }\n\n // ========================== GOVERNANCE ONLY FUNCTIONS ==========================\n\n /// @inheritdoc IAgToken\n function addMinter(address minter) external onlyTreasury {\n isMinter[minter] = true;\n emit MinterToggled(minter);\n }\n\n /// @inheritdoc IAgToken\n function removeMinter(address minter) external {\n if (msg.sender != address(treasury) && msg.sender != minter) revert InvalidSender();\n isMinter[minter] = false;\n emit MinterToggled(minter);\n }\n\n /// @inheritdoc IAgToken\n function setTreasury(address _treasury) external virtual onlyTreasury {\n treasury = _treasury;\n emit TreasuryUpdated(_treasury);\n }\n}\n" + }, + "contracts/agToken/AgTokenSideChainMultiBridge.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\nimport \"./AgToken.sol\";\nimport \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\nimport \"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\";\n\n/// @title AgTokenSideChainMultiBridge\n/// @author Angle Labs, Inc.\n/// @notice Contract for Angle agTokens on other chains than Ethereum mainnet\n/// @dev This contract supports bridge tokens having a minting right on the stablecoin (also referred to as the canonical\n/// or the native token)\ncontract AgTokenSideChainMultiBridge is AgToken {\n using SafeERC20 for IERC20;\n\n /// @notice Base used for fee computation\n uint256 public constant BASE_PARAMS = 1e9;\n\n // =============================== BRIDGING DATA ===============================\n\n /// @notice Struct with some data about a specific bridge token\n struct BridgeDetails {\n // Limit on the balance of bridge token held by the contract: it is designed\n // to reduce the exposure of the system to hacks\n uint256 limit;\n // Limit on the hourly volume of token minted through this bridge\n // Technically the limit over a rolling hour is hourlyLimit x2 as hourly limit\n // is enforced only between x:00 and x+1:00\n uint256 hourlyLimit;\n // Fee taken for swapping in and out the token\n uint64 fee;\n // Whether the associated token is allowed or not\n bool allowed;\n // Whether swapping in and out from the associated token is paused or not\n bool paused;\n }\n\n /// @notice Maps a bridge token to data\n mapping(address => BridgeDetails) public bridges;\n /// @notice List of all bridge tokens\n address[] public bridgeTokensList;\n /// @notice Maps a bridge token to the associated hourly volume\n mapping(address => mapping(uint256 => uint256)) public usage;\n /// @notice Maps an address to whether it is exempt of fees for when it comes to swapping in and out\n mapping(address => uint256) public isFeeExempt;\n /// @notice Limit to the amount of tokens that can be sent from that chain to another chain\n uint256 public chainTotalHourlyLimit;\n /// @notice Usage per hour on that chain. Maps an hourly timestamp to the total volume swapped out on the chain\n mapping(uint256 => uint256) public chainTotalUsage;\n\n // =================================== EVENTS ==================================\n\n event BridgeTokenAdded(address indexed bridgeToken, uint256 limit, uint256 hourlyLimit, uint64 fee, bool paused);\n event BridgeTokenToggled(address indexed bridgeToken, bool toggleStatus);\n event BridgeTokenRemoved(address indexed bridgeToken);\n event BridgeTokenFeeUpdated(address indexed bridgeToken, uint64 fee);\n event BridgeTokenLimitUpdated(address indexed bridgeToken, uint256 limit);\n event BridgeTokenHourlyLimitUpdated(address indexed bridgeToken, uint256 hourlyLimit);\n event HourlyLimitUpdated(uint256 hourlyLimit);\n event Recovered(address indexed token, address indexed to, uint256 amount);\n event FeeToggled(address indexed theAddress, uint256 toggleStatus);\n\n // =================================== ERRORS ==================================\n\n error AssetStillControlledInReserves();\n error HourlyLimitExceeded();\n error InvalidToken();\n error NotGovernor();\n error NotGovernorOrGuardian();\n error TooBigAmount();\n error TooHighParameterValue();\n error ZeroAddress();\n\n // ================================= MODIFIERS =================================\n\n /// @notice Checks whether the `msg.sender` has the governor role or not\n modifier onlyGovernor() {\n if (!ITreasury(treasury).isGovernor(msg.sender)) revert NotGovernor();\n _;\n }\n\n /// @notice Checks whether the `msg.sender` has the governor role or the guardian role\n modifier onlyGovernorOrGuardian() {\n if (!ITreasury(treasury).isGovernorOrGuardian(msg.sender)) revert NotGovernorOrGuardian();\n _;\n }\n\n // ===================== EXTERNAL PERMISSIONLESS FUNCTIONS =====================\n\n /// @notice Returns the list of all supported bridge tokens\n /// @dev Helpful for UIs\n function allBridgeTokens() external view returns (address[] memory) {\n return bridgeTokensList;\n }\n\n /// @notice Returns the current volume for a bridge, for the current hour\n /// @param bridgeToken Bridge used to mint\n /// @dev Helpful for UIs\n function currentUsage(address bridgeToken) external view returns (uint256) {\n return usage[bridgeToken][block.timestamp / 3600];\n }\n\n /// @notice Returns the current total volume on the chain for the current hour\n /// @dev Helpful for UIs\n function currentTotalUsage() external view returns (uint256) {\n return chainTotalUsage[block.timestamp / 3600];\n }\n\n /// @notice Mints the canonical token from a supported bridge token\n /// @param bridgeToken Bridge token to use to mint\n /// @param amount Amount of bridge tokens to send\n /// @param to Address to which the stablecoin should be sent\n /// @return Amount of the canonical stablecoin actually minted\n /// @dev Some fees may be taken by the protocol depending on the token used and on the address calling\n function swapIn(address bridgeToken, uint256 amount, address to) external returns (uint256) {\n BridgeDetails memory bridgeDetails = bridges[bridgeToken];\n if (!bridgeDetails.allowed || bridgeDetails.paused) revert InvalidToken();\n uint256 balance = IERC20(bridgeToken).balanceOf(address(this));\n if (balance + amount > bridgeDetails.limit) {\n // In case someone maliciously sends tokens to this contract\n // Or the limit changes\n if (bridgeDetails.limit > balance) amount = bridgeDetails.limit - balance;\n else {\n amount = 0;\n }\n }\n\n // Checking requirement on the hourly volume\n uint256 hour = block.timestamp / 3600;\n uint256 hourlyUsage = usage[bridgeToken][hour];\n if (hourlyUsage + amount > bridgeDetails.hourlyLimit) {\n // Edge case when the hourly limit changes\n amount = bridgeDetails.hourlyLimit > hourlyUsage ? bridgeDetails.hourlyLimit - hourlyUsage : 0;\n }\n usage[bridgeToken][hour] = hourlyUsage + amount;\n\n IERC20(bridgeToken).safeTransferFrom(msg.sender, address(this), amount);\n uint256 canonicalOut = amount;\n // Computing fees\n if (isFeeExempt[msg.sender] == 0) {\n canonicalOut -= (canonicalOut * bridgeDetails.fee) / BASE_PARAMS;\n }\n _mint(to, canonicalOut);\n return canonicalOut;\n }\n\n /// @notice Burns the canonical token in exchange for a bridge token\n /// @param bridgeToken Bridge token required\n /// @param amount Amount of canonical tokens to burn\n /// @param to Address to which the bridge token should be sent\n /// @return Amount of bridge tokens actually sent back\n /// @dev Some fees may be taken by the protocol depending on the token used and on the address calling\n function swapOut(address bridgeToken, uint256 amount, address to) external returns (uint256) {\n BridgeDetails memory bridgeDetails = bridges[bridgeToken];\n if (!bridgeDetails.allowed || bridgeDetails.paused) revert InvalidToken();\n\n uint256 hour = block.timestamp / 3600;\n uint256 hourlyUsage = chainTotalUsage[hour] + amount;\n // If the amount being swapped out exceeds the limit, we revert\n // We don't want to change the amount being swapped out.\n // The user can decide to send another tx with the correct amount to reach the limit\n if (hourlyUsage > chainTotalHourlyLimit) revert HourlyLimitExceeded();\n chainTotalUsage[hour] = hourlyUsage;\n\n _burn(msg.sender, amount);\n uint256 bridgeOut = amount;\n if (isFeeExempt[msg.sender] == 0) {\n bridgeOut -= (bridgeOut * bridgeDetails.fee) / BASE_PARAMS;\n }\n IERC20(bridgeToken).safeTransfer(to, bridgeOut);\n return bridgeOut;\n }\n\n // ============================ GOVERNANCE FUNCTIONS ===========================\n\n /// @notice Adds support for a bridge token\n /// @param bridgeToken Bridge token to add: it should be a version of the stablecoin from another bridge\n /// @param limit Limit on the balance of bridge token this contract could hold\n /// @param hourlyLimit Limit on the hourly volume for this bridge\n /// @param paused Whether swapping for this token should be paused or not\n /// @param fee Fee taken upon swapping for or against this token\n function addBridgeToken(\n address bridgeToken,\n uint256 limit,\n uint256 hourlyLimit,\n uint64 fee,\n bool paused\n ) external onlyGovernor {\n if (bridges[bridgeToken].allowed || bridgeToken == address(0)) revert InvalidToken();\n if (fee > BASE_PARAMS) revert TooHighParameterValue();\n BridgeDetails memory _bridge;\n _bridge.limit = limit;\n _bridge.hourlyLimit = hourlyLimit;\n _bridge.paused = paused;\n _bridge.fee = fee;\n _bridge.allowed = true;\n bridges[bridgeToken] = _bridge;\n bridgeTokensList.push(bridgeToken);\n emit BridgeTokenAdded(bridgeToken, limit, hourlyLimit, fee, paused);\n }\n\n /// @notice Removes support for a token\n /// @param bridgeToken Address of the bridge token to remove support for\n function removeBridgeToken(address bridgeToken) external onlyGovernor {\n if (IERC20(bridgeToken).balanceOf(address(this)) != 0) revert AssetStillControlledInReserves();\n delete bridges[bridgeToken];\n // Deletion from `bridgeTokensList` loop\n uint256 bridgeTokensListLength = bridgeTokensList.length;\n for (uint256 i; i < bridgeTokensListLength - 1; ++i) {\n if (bridgeTokensList[i] == bridgeToken) {\n // Replace the `bridgeToken` to remove with the last of the list\n bridgeTokensList[i] = bridgeTokensList[bridgeTokensListLength - 1];\n break;\n }\n }\n // Remove last element in array\n bridgeTokensList.pop();\n emit BridgeTokenRemoved(bridgeToken);\n }\n\n /// @notice Recovers any ERC20 token\n /// @dev Can be used to withdraw bridge tokens for them to be de-bridged on mainnet\n function recoverERC20(address tokenAddress, address to, uint256 amountToRecover) external onlyGovernor {\n IERC20(tokenAddress).safeTransfer(to, amountToRecover);\n emit Recovered(tokenAddress, to, amountToRecover);\n }\n\n /// @notice Updates the `limit` amount for `bridgeToken`\n function setLimit(address bridgeToken, uint256 limit) external onlyGovernorOrGuardian {\n if (!bridges[bridgeToken].allowed) revert InvalidToken();\n bridges[bridgeToken].limit = limit;\n emit BridgeTokenLimitUpdated(bridgeToken, limit);\n }\n\n /// @notice Updates the `hourlyLimit` amount for `bridgeToken`\n function setHourlyLimit(address bridgeToken, uint256 hourlyLimit) external onlyGovernorOrGuardian {\n if (!bridges[bridgeToken].allowed) revert InvalidToken();\n bridges[bridgeToken].hourlyLimit = hourlyLimit;\n emit BridgeTokenHourlyLimitUpdated(bridgeToken, hourlyLimit);\n }\n\n /// @notice Updates the `chainTotalHourlyLimit` amount\n function setChainTotalHourlyLimit(uint256 hourlyLimit) external onlyGovernorOrGuardian {\n chainTotalHourlyLimit = hourlyLimit;\n emit HourlyLimitUpdated(hourlyLimit);\n }\n\n /// @notice Updates the `fee` value for `bridgeToken`\n function setSwapFee(address bridgeToken, uint64 fee) external onlyGovernorOrGuardian {\n if (!bridges[bridgeToken].allowed) revert InvalidToken();\n if (fee > BASE_PARAMS) revert TooHighParameterValue();\n bridges[bridgeToken].fee = fee;\n emit BridgeTokenFeeUpdated(bridgeToken, fee);\n }\n\n /// @notice Pauses or unpauses swapping in and out for a token\n function toggleBridge(address bridgeToken) external onlyGovernorOrGuardian {\n if (!bridges[bridgeToken].allowed) revert InvalidToken();\n bool pausedStatus = bridges[bridgeToken].paused;\n bridges[bridgeToken].paused = !pausedStatus;\n emit BridgeTokenToggled(bridgeToken, !pausedStatus);\n }\n\n /// @notice Toggles fees for the address `theAddress`\n function toggleFeesForAddress(address theAddress) external onlyGovernorOrGuardian {\n uint256 feeExemptStatus = 1 - isFeeExempt[theAddress];\n isFeeExempt[theAddress] = feeExemptStatus;\n emit FeeToggled(theAddress, feeExemptStatus);\n }\n}\n" + }, + "contracts/agToken/layerZero/LayerZeroBridge.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.12;\n\nimport \"./utils/OFTCore.sol\";\nimport \"@openzeppelin/contracts-upgradeable/security/PausableUpgradeable.sol\";\nimport \"@openzeppelin/contracts/token/ERC20/extensions/draft-IERC20Permit.sol\";\n\n/// @title LayerZeroBridge\n/// @author Angle Labs, Inc., forked from https://github.com/LayerZero-Labs/solidity-examples/blob/main/contracts/token/oft/OFT.sol\n/// @notice Contract to be deployed on Ethereum for bridging an AgToken using a bridge intermediate token and LayerZero\ncontract LayerZeroBridge is OFTCore, PausableUpgradeable {\n /// @notice Name of the contract for indexing purposes\n string public name;\n\n /// @notice Address of the bridgeable token\n /// @dev Immutable\n IERC20 public canonicalToken;\n\n /// @notice Maps an address to the amount of token bridged but not received\n mapping(address => uint256) public balanceOf;\n\n // ================================ CONSTRUCTOR ================================\n /// @notice Initializes the contract\n /// @param _name Name of the token corresponding to this contract\n /// @param _lzEndpoint Layer zero endpoint to pass messages\n /// @param _treasury Address of the treasury contract used for access control\n function initialize(string memory _name, address _lzEndpoint, address _treasury) external initializer {\n __LzAppUpgradeable_init(_lzEndpoint, _treasury);\n name = _name;\n canonicalToken = IERC20(address(ITreasury(_treasury).stablecoin()));\n }\n\n /// @custom:oz-upgrades-unsafe-allow constructor\n constructor() initializer {}\n\n // ===================== EXTERNAL PERMISSIONLESS FUNCTIONS =====================\n\n /// @inheritdoc OFTCore\n function sendWithPermit(\n uint16 _dstChainId,\n bytes memory _toAddress,\n uint256 _amount,\n address payable _refundAddress,\n address _zroPaymentAddress,\n bytes memory _adapterParams,\n uint256 deadline,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) public payable override {\n IERC20Permit(address(canonicalToken)).permit(msg.sender, address(this), _amount, deadline, v, r, s);\n send(_dstChainId, _toAddress, _amount, _refundAddress, _zroPaymentAddress, _adapterParams);\n }\n\n /// @inheritdoc OFTCore\n function withdraw(uint256 amount, address recipient) external override returns (uint256) {\n return _withdraw(amount, msg.sender, recipient);\n }\n\n /// @notice Withdraws amount of `token` from the contract and sends it to the recipient\n /// @param amount Amount to withdraw\n /// @param recipient Address to withdraw for\n /// @return The amount of canonical token sent\n function withdrawFor(uint256 amount, address recipient) external returns (uint256) {\n return _withdraw(amount, recipient, recipient);\n }\n\n // ============================= INTERNAL FUNCTIONS ============================\n\n /// @notice Withdraws `amount` from the balance of the `from` address and sends these tokens to the `to` address\n /// @dev It's important to make sure that `from` is either the `msg.sender` or that `from` and `to` are the same\n /// addresses\n function _withdraw(uint256 amount, address from, address to) internal whenNotPaused returns (uint256) {\n balanceOf[from] -= amount; // Will overflow if the amount is too big\n canonicalToken.transfer(to, amount);\n return amount;\n }\n\n /// @inheritdoc OFTCore\n function _debitFrom(uint16, bytes memory, uint256 _amount) internal override whenNotPaused returns (uint256) {\n // No need to use safeTransferFrom as we know this implementation reverts on failure\n canonicalToken.transferFrom(msg.sender, address(this), _amount);\n return _amount;\n }\n\n /// @inheritdoc OFTCore\n function _debitCreditFrom(uint16, bytes memory, uint256 _amount) internal override whenNotPaused returns (uint256) {\n balanceOf[msg.sender] -= _amount;\n return _amount;\n }\n\n /// @inheritdoc OFTCore\n function _creditTo(uint16, address _toAddress, uint256 _amount) internal override whenNotPaused returns (uint256) {\n // Should never revert as all the LayerZero bridge tokens come from\n // this contract\n uint256 balance = canonicalToken.balanceOf(address(this));\n if (balance < _amount) {\n balanceOf[_toAddress] = _amount - balance;\n if (balance != 0) canonicalToken.transfer(_toAddress, balance);\n } else {\n canonicalToken.transfer(_toAddress, _amount);\n }\n return _amount;\n }\n\n // =============================== VIEW FUNCTIONS ==============================\n\n /// @inheritdoc ERC165Upgradeable\n function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {\n return interfaceId == type(IOFTCore).interfaceId || super.supportsInterface(interfaceId);\n }\n\n // ============================ GOVERNANCE FUNCTIONS ===========================\n\n /// @notice Pauses bridging through the contract\n /// @param pause Future pause status\n function pauseSendTokens(bool pause) external onlyGovernorOrGuardian {\n pause ? _pause() : _unpause();\n }\n\n /// @notice Decreases the balance of an address\n /// @param amount Amount to withdraw from balance\n /// @param recipient Address to withdraw from\n function sweep(uint256 amount, address recipient) external onlyGovernorOrGuardian {\n balanceOf[recipient] -= amount; // Will overflow if the amount is too big\n }\n\n uint256[47] private __gap;\n}\n" + }, + "contracts/agToken/layerZero/LayerZeroBridgeToken.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.12;\n\nimport \"./utils/OFTCore.sol\";\nimport \"../../interfaces/IAgTokenSideChainMultiBridge.sol\";\nimport \"@openzeppelin/contracts-upgradeable/security/PausableUpgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/token/ERC20/ERC20Upgradeable.sol\";\n\n/// @title LayerZeroBridgeToken\n/// @author Angle Labs, Inc., forked from https://github.com/LayerZero-Labs/solidity-examples/blob/main/contracts/token/oft/OFT.sol\n/// @notice Contract to be deployed on a L2/sidechain for bridging an AgToken using a bridge intermediate token and LayerZero\ncontract LayerZeroBridgeToken is OFTCore, ERC20Upgradeable, PausableUpgradeable {\n /// @notice Address of the bridgeable token\n /// @dev Immutable\n IAgTokenSideChainMultiBridge public canonicalToken;\n\n // =================================== ERROR ===================================\n\n error InvalidAllowance();\n\n // ================================ CONSTRUCTOR ================================\n\n /// @notice Initializes the contract\n /// @param _name Name of the token corresponding to this contract\n /// @param _symbol Symbol of the token corresponding to this contract\n /// @param _lzEndpoint Layer zero endpoint to pass messages\n /// @param _treasury Address of the treasury contract used for access control\n /// @param initialSupply Initial supply to mint to the canonical token address\n /// @dev The initial supply corresponds to the initial amount that could be bridged using this OFT\n function initialize(\n string memory _name,\n string memory _symbol,\n address _lzEndpoint,\n address _treasury,\n uint256 initialSupply\n ) external initializer {\n __ERC20_init_unchained(_name, _symbol);\n __LzAppUpgradeable_init(_lzEndpoint, _treasury);\n\n canonicalToken = IAgTokenSideChainMultiBridge(address(ITreasury(_treasury).stablecoin()));\n _approve(address(this), address(canonicalToken), type(uint256).max);\n _mint(address(canonicalToken), initialSupply);\n }\n\n /// @custom:oz-upgrades-unsafe-allow constructor\n constructor() initializer {}\n\n // ===================== EXTERNAL PERMISSIONLESS FUNCTIONS =====================\n\n /// @inheritdoc OFTCore\n function sendWithPermit(\n uint16 _dstChainId,\n bytes memory _toAddress,\n uint256 _amount,\n address payable _refundAddress,\n address _zroPaymentAddress,\n bytes memory _adapterParams,\n uint256 deadline,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) public payable override {\n canonicalToken.permit(msg.sender, address(this), _amount, deadline, v, r, s);\n send(_dstChainId, _toAddress, _amount, _refundAddress, _zroPaymentAddress, _adapterParams);\n }\n\n /// @inheritdoc OFTCore\n function withdraw(uint256 amount, address recipient) external override returns (uint256 amountMinted) {\n // Does not check allowances as transfers from `msg.sender`\n _transfer(msg.sender, address(this), amount);\n amountMinted = canonicalToken.swapIn(address(this), amount, recipient);\n uint256 leftover = balanceOf(address(this));\n if (leftover != 0) {\n _transfer(address(this), msg.sender, leftover);\n }\n }\n\n // ============================= INTERNAL FUNCTIONS ============================\n\n /// @inheritdoc OFTCore\n function _debitFrom(\n uint16,\n bytes memory,\n uint256 _amount\n ) internal override whenNotPaused returns (uint256 amountSwapped) {\n // No need to use safeTransferFrom as we know this implementation reverts on failure\n canonicalToken.transferFrom(msg.sender, address(this), _amount);\n\n // Swap canonical for this bridge token. There may be some fees\n amountSwapped = canonicalToken.swapOut(address(this), _amount, address(this));\n _burn(address(this), amountSwapped);\n }\n\n /// @inheritdoc OFTCore\n function _debitCreditFrom(uint16, bytes memory, uint256 _amount) internal override whenNotPaused returns (uint256) {\n _burn(msg.sender, _amount);\n return _amount;\n }\n\n /// @inheritdoc OFTCore\n function _creditTo(\n uint16,\n address _toAddress,\n uint256 _amount\n ) internal override whenNotPaused returns (uint256 amountMinted) {\n _mint(address(this), _amount);\n amountMinted = canonicalToken.swapIn(address(this), _amount, _toAddress);\n uint256 leftover = balanceOf(address(this));\n if (leftover != 0) {\n _transfer(address(this), _toAddress, leftover);\n }\n }\n\n // =============================== VIEW FUNCTIONS ==============================\n\n /// @inheritdoc ERC165Upgradeable\n function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {\n return\n interfaceId == type(IOFT).interfaceId ||\n interfaceId == type(IERC20).interfaceId ||\n super.supportsInterface(interfaceId);\n }\n\n // ============================ GOVERNANCE FUNCTIONS ===========================\n\n /// @notice Mints the intermediate contract to the `canonicalToken`\n /// @dev Used to increase the bridging capacity\n function mint(uint256 amount) external onlyGovernorOrGuardian {\n _mint(address(canonicalToken), amount);\n }\n\n /// @notice Burns the intermediate contract from the `canonicalToken`\n /// @dev Used to decrease the bridging capacity\n function burn(uint256 amount) external onlyGovernorOrGuardian {\n _burn(address(canonicalToken), amount);\n }\n\n /// @notice Increases allowance of the `canonicalToken`\n function setupAllowance() public onlyGovernorOrGuardian {\n _approve(address(this), address(canonicalToken), type(uint256).max);\n }\n\n /// @notice Pauses bridging through the contract\n /// @param pause Future pause status\n function pauseSendTokens(bool pause) external onlyGovernorOrGuardian {\n pause ? _pause() : _unpause();\n }\n\n uint256[49] private __gap;\n}\n" + }, + "contracts/agToken/layerZero/utils/IOFTCore.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.12;\n\nimport \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\nimport \"@openzeppelin/contracts/utils/introspection/IERC165.sol\";\n\n/**\n * @dev Interface of the IOFT core standard\n * @dev Forked from https://github.com/LayerZero-Labs/solidity-examples/blob/main/contracts/token/oft/IOFTCore.sol\n */\ninterface IOFTCore is IERC165 {\n /// @notice Estimates send token `_tokenId` to (`_dstChainId`, `_toAddress`)\n /// @param _dstChainId L0 defined chain id to send tokens too\n /// @param _toAddress dynamic bytes array which contains the address to whom you are sending tokens to on the dstChain\n /// @param _amount amount of the tokens to transfer\n /// @param _useZro indicates to use zro to pay L0 fees\n /// @param _adapterParams flexible bytes array to indicate messaging adapter services in L0\n function estimateSendFee(\n uint16 _dstChainId,\n bytes calldata _toAddress,\n uint256 _amount,\n bool _useZro,\n bytes calldata _adapterParams\n ) external view returns (uint256 nativeFee, uint256 zroFee);\n\n /// @notice Sends `_amount` amount of token to (`_dstChainId`, `_toAddress`)\n /// @param _dstChainId the destination chain identifier\n /// @param _toAddress can be any size depending on the `dstChainId`.\n /// @param _amount the quantity of tokens in wei\n /// @param _refundAddress the address LayerZero refunds if too much message fee is sent\n /// @param _zroPaymentAddress set to address(0x0) if not paying in ZRO (LayerZero Token)\n /// @param _adapterParams is a flexible bytes array to indicate messaging adapter services\n function send(\n uint16 _dstChainId,\n bytes calldata _toAddress,\n uint256 _amount,\n address payable _refundAddress,\n address _zroPaymentAddress,\n bytes calldata _adapterParams\n ) external payable;\n\n /// @notice Sends `_amount` amount of credit to (`_dstChainId`, `_toAddress`)\n /// @param _dstChainId the destination chain identifier\n /// @param _toAddress can be any size depending on the `dstChainId`.\n /// @param _amount the quantity of credit to send in wei\n /// @param _refundAddress the address LayerZero refunds if too much message fee is sent\n /// @param _zroPaymentAddress set to address(0x0) if not paying in ZRO (LayerZero Token)\n /// @param _adapterParams is a flexible bytes array to indicate messaging adapter services\n function sendCredit(\n uint16 _dstChainId,\n bytes calldata _toAddress,\n uint256 _amount,\n address payable _refundAddress,\n address _zroPaymentAddress,\n bytes calldata _adapterParams\n ) external payable;\n\n /// @notice Sends `_amount` amount of token to (`_dstChainId`, `_toAddress`)\n /// @param _dstChainId The destination chain identifier\n /// @param _toAddress Can be any size depending on the `dstChainId`.\n /// @param _amount Quantity of tokens in wei\n /// @param _refundAddress Address LayerZero refunds if too much message fee is sent\n /// @param _zroPaymentAddress Set to address(0x0) if not paying in ZRO (LayerZero Token)\n /// @param _adapterParams Flexible bytes array to indicate messaging adapter services\n /// @param deadline Deadline parameter for the signature to be valid\n /// @dev The `v`, `r`, and `s` parameters are used as signature data\n function sendWithPermit(\n uint16 _dstChainId,\n bytes memory _toAddress,\n uint256 _amount,\n address payable _refundAddress,\n address _zroPaymentAddress,\n bytes memory _adapterParams,\n uint256 deadline,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) external payable;\n\n /// @notice Withdraws amount of canonical token from the `msg.sender` balance and sends it to the recipient\n /// @param amount Amount to withdraw\n /// @param recipient Address to send the canonical token to\n /// @return The amount of canonical token sent\n function withdraw(uint256 amount, address recipient) external returns (uint256);\n\n /// @dev Emitted when `_amount` tokens are moved from the `_sender` to (`_dstChainId`, `_toAddress`)\n /// `_nonce` is the outbound nonce\n event SendToChain(\n address indexed _sender,\n uint16 indexed _dstChainId,\n bytes indexed _toAddress,\n uint256 _amount,\n uint64 _nonce\n );\n\n /// @dev Emitted when `_amount` tokens are received from `_srcChainId` into the `_toAddress` on the local chain.\n /// `_nonce` is the inbound nonce.\n event ReceiveFromChain(\n uint16 indexed _srcChainId,\n bytes indexed _srcAddress,\n address indexed _toAddress,\n uint256 _amount,\n uint64 _nonce\n );\n}\n\n/// @dev Interface of the OFT standard\ninterface IOFT is IOFTCore, IERC20 {\n\n}\n" + }, + "contracts/agToken/layerZero/utils/NonblockingLzApp.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.12;\n\nimport \"@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol\";\nimport \"../../../interfaces/external/layerZero/ILayerZeroReceiver.sol\";\nimport \"../../../interfaces/external/layerZero/ILayerZeroUserApplicationConfig.sol\";\nimport \"../../../interfaces/external/layerZero/ILayerZeroEndpoint.sol\";\nimport \"../../../interfaces/ITreasury.sol\";\n\n/// @title NonblockingLzApp\n/// @author Angle Labs, Inc., forked from https://github.com/LayerZero-Labs/solidity-examples/\n/// @notice Base contract for bridging using LayerZero\nabstract contract NonblockingLzApp is Initializable, ILayerZeroReceiver, ILayerZeroUserApplicationConfig {\n /// @notice Layer Zero endpoint\n ILayerZeroEndpoint public lzEndpoint;\n\n /// @notice Maps chainIds to failed messages to retry them\n mapping(uint16 => mapping(bytes => mapping(uint64 => bytes32))) public failedMessages;\n\n /// @notice Maps chainIds to their OFT address\n mapping(uint16 => bytes) public trustedRemoteLookup;\n\n /// @notice Reference to the treasury contract to fetch access control\n address public treasury;\n\n /// @notice Maps pairs of (`to` chain, `packetType`) to the minimum amount of gas needed on the destination chain\n mapping(uint16 => mapping(uint16 => uint256)) public minDstGasLookup;\n\n /// @notice For future LayerZero compatibility\n address public precrime;\n\n // ================================== Events ===================================\n\n event SetTrustedRemote(uint16 _srcChainId, bytes _srcAddress);\n event MessageFailed(uint16 _srcChainId, bytes _srcAddress, uint64 _nonce, bytes _payload);\n\n // =============================== Errors ================================\n\n error NotGovernor();\n error NotGovernorOrGuardian();\n error InsufficientGas();\n error InvalidEndpoint();\n error InvalidSource();\n error InvalidCaller();\n error InvalidParams();\n error InvalidPayload();\n error ZeroAddress();\n\n // ============================= Constructor ===================================\n\n //solhint-disable-next-line\n function __LzAppUpgradeable_init(address _endpoint, address _treasury) internal {\n if (_endpoint == address(0) || _treasury == address(0)) revert ZeroAddress();\n lzEndpoint = ILayerZeroEndpoint(_endpoint);\n treasury = _treasury;\n }\n\n // =============================== Modifiers ===================================\n\n /// @notice Checks whether the `msg.sender` has the governor role or the guardian role\n modifier onlyGovernorOrGuardian() {\n if (!ITreasury(treasury).isGovernorOrGuardian(msg.sender)) revert NotGovernorOrGuardian();\n _;\n }\n\n // ==================== External Permissionless Functions ======================\n\n /// @notice Receives a message from the LZ endpoint and process it\n /// @param _srcChainId ChainId of the source chain - LayerZero standard\n /// @param _srcAddress Sender of the source chain\n /// @param _nonce Nounce of the message\n /// @param _payload Data: recipient address and amount\n function lzReceive(\n uint16 _srcChainId,\n bytes memory _srcAddress,\n uint64 _nonce,\n bytes memory _payload\n ) public virtual override {\n // lzReceive must be called by the endpoint for security\n if (msg.sender != address(lzEndpoint)) revert InvalidEndpoint();\n\n bytes memory trustedRemote = trustedRemoteLookup[_srcChainId];\n // if will still block the message pathway from (srcChainId, srcAddress). should not receive message from untrusted remote.\n if (_srcAddress.length != trustedRemote.length || keccak256(_srcAddress) != keccak256(trustedRemote))\n revert InvalidSource();\n\n _blockingLzReceive(_srcChainId, _srcAddress, _nonce, _payload);\n }\n\n /// @notice Retries a message that previously failed and was stored\n /// @param _srcChainId ChainId of the source chain - LayerZero standard\n /// @param _srcAddress Sender of the source chain\n /// @param _nonce Nounce of the message\n /// @param _payload Data: recipient address and amount\n function retryMessage(\n uint16 _srcChainId,\n bytes memory _srcAddress,\n uint64 _nonce,\n bytes memory _payload\n ) public payable virtual {\n // assert there is message to retry\n bytes32 payloadHash = failedMessages[_srcChainId][_srcAddress][_nonce];\n if (payloadHash == bytes32(0) || keccak256(_payload) != payloadHash) revert InvalidPayload();\n // clear the stored message\n failedMessages[_srcChainId][_srcAddress][_nonce] = bytes32(0);\n // execute the message. revert if it fails again\n _nonblockingLzReceive(_srcChainId, _srcAddress, _nonce, _payload);\n }\n\n // ============================= Internal Functions ===================================\n\n /// @notice Handles message receptions in a non blocking way\n /// @param _srcChainId ChainId of the source chain - LayerZero standard\n /// @param _srcAddress Sender of the source chain\n /// @param _nonce Nounce of the message\n /// @param _payload Data: recipient address and amount\n /// @dev public for the needs of try / catch but effectively internal\n function nonblockingLzReceive(\n uint16 _srcChainId,\n bytes memory _srcAddress,\n uint64 _nonce,\n bytes memory _payload\n ) public virtual {\n // only internal transaction\n if (msg.sender != address(this)) revert InvalidCaller();\n _nonblockingLzReceive(_srcChainId, _srcAddress, _nonce, _payload);\n }\n\n /// @notice Handles message receptions in a non blocking way\n /// @param _srcChainId ChainId of the source chain - LayerZero standard\n /// @param _srcAddress Sender of the source chain\n /// @param _nonce Nounce of the message\n /// @param _payload Data: recipient address and amount\n function _nonblockingLzReceive(\n uint16 _srcChainId,\n bytes memory _srcAddress,\n uint64 _nonce,\n bytes memory _payload\n ) internal virtual;\n\n /// @notice Handles message receptions in a blocking way\n /// @param _srcChainId ChainId of the source chain - LayerZero standard\n /// @param _srcAddress Sender of the source chain\n /// @param _nonce Nounce of the message\n /// @param _payload Data: recipient address and amount\n function _blockingLzReceive(\n uint16 _srcChainId,\n bytes memory _srcAddress,\n uint64 _nonce,\n bytes memory _payload\n ) internal {\n // try-catch all errors/exceptions\n try this.nonblockingLzReceive(_srcChainId, _srcAddress, _nonce, _payload) {\n // do nothing\n } catch {\n // error / exception\n failedMessages[_srcChainId][_srcAddress][_nonce] = keccak256(_payload);\n emit MessageFailed(_srcChainId, _srcAddress, _nonce, _payload);\n }\n }\n\n /// @notice Sends a message to the LZ endpoint and process it\n /// @param _dstChainId L0 defined chain id to send tokens too\n /// @param _payload Data: recipient address and amount\n /// @param _refundAddress Address LayerZero refunds if too much message fee is sent\n /// @param _zroPaymentAddress Set to address(0x0) if not paying in ZRO (LayerZero Token)\n /// @param _adapterParams Flexible bytes array to indicate messaging adapter services in L0\n function _lzSend(\n uint16 _dstChainId,\n bytes memory _payload,\n address payable _refundAddress,\n address _zroPaymentAddress,\n bytes memory _adapterParams\n ) internal virtual {\n bytes memory trustedRemote = trustedRemoteLookup[_dstChainId];\n if (trustedRemote.length == 0) revert InvalidSource();\n //solhint-disable-next-line\n lzEndpoint.send{ value: msg.value }(\n _dstChainId,\n trustedRemote,\n _payload,\n _refundAddress,\n _zroPaymentAddress,\n _adapterParams\n );\n }\n\n /// @notice Checks the gas limit of a given transaction\n function _checkGasLimit(\n uint16 _dstChainId,\n uint16 _type,\n bytes memory _adapterParams,\n uint256 _extraGas\n ) internal view virtual {\n uint256 minGasLimit = minDstGasLookup[_dstChainId][_type] + _extraGas;\n if (minGasLimit == 0 || minGasLimit > _getGasLimit(_adapterParams)) revert InsufficientGas();\n }\n\n /// @notice Gets the gas limit from the `_adapterParams` parameter\n function _getGasLimit(bytes memory _adapterParams) internal pure virtual returns (uint256 gasLimit) {\n if (_adapterParams.length < 34) revert InvalidParams();\n // solhint-disable-next-line\n assembly {\n gasLimit := mload(add(_adapterParams, 34))\n }\n }\n\n // ======================= Governance Functions ================================\n\n /// @notice Sets the corresponding address on an other chain.\n /// @param _srcChainId ChainId of the source chain - LayerZero standard\n /// @param _srcAddress Address on the source chain\n /// @dev Used for both receiving and sending message\n /// @dev There can only be one trusted source per chain\n /// @dev Allows owner to set it multiple times.\n function setTrustedRemote(uint16 _srcChainId, bytes calldata _srcAddress) external onlyGovernorOrGuardian {\n trustedRemoteLookup[_srcChainId] = _srcAddress;\n emit SetTrustedRemote(_srcChainId, _srcAddress);\n }\n\n /// @notice Fetches the default LZ config\n function getConfig(\n uint16 _version,\n uint16 _chainId,\n address,\n uint256 _configType\n ) external view returns (bytes memory) {\n return lzEndpoint.getConfig(_version, _chainId, address(this), _configType);\n }\n\n /// @notice Overrides the default LZ config\n function setConfig(\n uint16 _version,\n uint16 _chainId,\n uint256 _configType,\n bytes calldata _config\n ) external override onlyGovernorOrGuardian {\n lzEndpoint.setConfig(_version, _chainId, _configType, _config);\n }\n\n /// @notice Overrides the default LZ config\n function setSendVersion(uint16 _version) external override onlyGovernorOrGuardian {\n lzEndpoint.setSendVersion(_version);\n }\n\n /// @notice Overrides the default LZ config\n function setReceiveVersion(uint16 _version) external override onlyGovernorOrGuardian {\n lzEndpoint.setReceiveVersion(_version);\n }\n\n /// @notice Unpauses the receive functionalities\n function forceResumeReceive(\n uint16 _srcChainId,\n bytes calldata _srcAddress\n ) external override onlyGovernorOrGuardian {\n lzEndpoint.forceResumeReceive(_srcChainId, _srcAddress);\n }\n\n /// @notice Sets the minimum gas parameter for a packet type on a given chain\n function setMinDstGas(uint16 _dstChainId, uint16 _packetType, uint256 _minGas) external onlyGovernorOrGuardian {\n if (_minGas == 0) revert InvalidParams();\n minDstGasLookup[_dstChainId][_packetType] = _minGas;\n }\n\n /// @notice Sets the precrime variable\n function setPrecrime(address _precrime) external onlyGovernorOrGuardian {\n precrime = _precrime;\n }\n\n // ======================= View Functions ================================\n\n /// @notice Checks if the `_srcAddress` corresponds to the trusted source\n function isTrustedRemote(uint16 _srcChainId, bytes calldata _srcAddress) external view returns (bool) {\n bytes memory trustedSource = trustedRemoteLookup[_srcChainId];\n return keccak256(trustedSource) == keccak256(_srcAddress);\n }\n\n uint256[44] private __gap;\n}\n" + }, + "contracts/agToken/layerZero/utils/OFTCore.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.12;\n\nimport \"./NonblockingLzApp.sol\";\nimport \"./IOFTCore.sol\";\nimport \"@openzeppelin/contracts-upgradeable/utils/introspection/ERC165Upgradeable.sol\";\n\n/// @title OFTCore\n/// @author Forked from https://github.com/LayerZero-Labs/solidity-examples/blob/main/contracts/token/oft/OFTCore.sol\n/// but with slight modifications from the Angle Labs, Inc. which added return values to the `_creditTo` and `_debitFrom` functions\n/// @notice Base contract for bridging using LayerZero\nabstract contract OFTCore is NonblockingLzApp, ERC165Upgradeable, IOFTCore {\n /// @notice Amount of additional gas specified\n uint256 public constant EXTRA_GAS = 200000;\n /// @notice Packet type for token transfer\n uint16 public constant PT_SEND = 0;\n\n /// @notice Whether to use custom parameters in transactions\n uint8 public useCustomAdapterParams;\n\n // ==================== External Permissionless Functions ======================\n\n /// @inheritdoc IOFTCore\n function sendWithPermit(\n uint16 _dstChainId,\n bytes memory _toAddress,\n uint256 _amount,\n address payable _refundAddress,\n address _zroPaymentAddress,\n bytes memory _adapterParams,\n uint256 deadline,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) public payable virtual;\n\n /// @inheritdoc IOFTCore\n function send(\n uint16 _dstChainId,\n bytes memory _toAddress,\n uint256 _amount,\n address payable _refundAddress,\n address _zroPaymentAddress,\n bytes memory _adapterParams\n ) public payable virtual {\n _checkAdapterParams(_dstChainId, PT_SEND, _adapterParams, EXTRA_GAS);\n _amount = _debitFrom(_dstChainId, _toAddress, _amount);\n\n bytes memory payload = abi.encode(_toAddress, _amount);\n _lzSend(_dstChainId, payload, _refundAddress, _zroPaymentAddress, _adapterParams);\n\n uint64 nonce = lzEndpoint.getOutboundNonce(_dstChainId, address(this));\n emit SendToChain(msg.sender, _dstChainId, _toAddress, _amount, nonce);\n }\n\n /// @inheritdoc IOFTCore\n function sendCredit(\n uint16 _dstChainId,\n bytes memory _toAddress,\n uint256 _amount,\n address payable _refundAddress,\n address _zroPaymentAddress,\n bytes memory _adapterParams\n ) public payable virtual {\n _checkAdapterParams(_dstChainId, PT_SEND, _adapterParams, EXTRA_GAS);\n _amount = _debitCreditFrom(_dstChainId, _toAddress, _amount);\n\n _send(_dstChainId, _toAddress, _amount, _refundAddress, _zroPaymentAddress, _adapterParams);\n }\n\n /// @inheritdoc IOFTCore\n function withdraw(uint256 amount, address recipient) external virtual returns (uint256);\n\n /// @notice Sets whether custom adapter parameters can be used or not\n function setUseCustomAdapterParams(uint8 _useCustomAdapterParams) public virtual onlyGovernorOrGuardian {\n useCustomAdapterParams = _useCustomAdapterParams;\n }\n\n // =========================== Internal Functions ==============================\n\n /// @notice Internal function to send `_amount` amount of token to (`_dstChainId`, `_toAddress`)\n /// @param _dstChainId the destination chain identifier\n /// @param _toAddress can be any size depending on the `dstChainId`.\n /// @param _amount the quantity of tokens in wei\n /// @param _refundAddress the address LayerZero refunds if too much message fee is sent\n /// @param _zroPaymentAddress set to address(0x0) if not paying in ZRO (LayerZero Token)\n /// @param _adapterParams is a flexible bytes array to indicate messaging adapter services\n /// @dev Accounting and checks should be performed beforehand\n function _send(\n uint16 _dstChainId,\n bytes memory _toAddress,\n uint256 _amount,\n address payable _refundAddress,\n address _zroPaymentAddress,\n bytes memory _adapterParams\n ) internal {\n bytes memory payload = abi.encode(_toAddress, _amount);\n _lzSend(_dstChainId, payload, _refundAddress, _zroPaymentAddress, _adapterParams);\n\n uint64 nonce = lzEndpoint.getOutboundNonce(_dstChainId, address(this));\n emit SendToChain(msg.sender, _dstChainId, _toAddress, _amount, nonce);\n }\n\n /// @inheritdoc NonblockingLzApp\n function _nonblockingLzReceive(\n uint16 _srcChainId,\n bytes memory _srcAddress,\n uint64 _nonce,\n bytes memory _payload\n ) internal virtual override {\n // decode and load the toAddress\n (bytes memory toAddressBytes, uint256 amount) = abi.decode(_payload, (bytes, uint256));\n address toAddress;\n //solhint-disable-next-line\n assembly {\n toAddress := mload(add(toAddressBytes, 20))\n }\n amount = _creditTo(_srcChainId, toAddress, amount);\n\n emit ReceiveFromChain(_srcChainId, _srcAddress, toAddress, amount, _nonce);\n }\n\n /// @notice Checks the adapter parameters given during the smart contract call\n function _checkAdapterParams(\n uint16 _dstChainId,\n uint16 _pkType,\n bytes memory _adapterParams,\n uint256 _extraGas\n ) internal virtual {\n if (useCustomAdapterParams > 0) _checkGasLimit(_dstChainId, _pkType, _adapterParams, _extraGas);\n else if (_adapterParams.length != 0) revert InvalidParams();\n }\n\n /// @notice Makes accountability when bridging from this contract using canonical token\n /// @param _dstChainId ChainId of the destination chain - LayerZero standard\n /// @param _toAddress Recipient on the destination chain\n /// @param _amount Amount to bridge\n function _debitFrom(\n uint16 _dstChainId,\n bytes memory _toAddress,\n uint256 _amount\n ) internal virtual returns (uint256);\n\n /// @notice Makes accountability when bridging from this contract's credit\n /// @param _dstChainId ChainId of the destination chain - LayerZero standard\n /// @param _toAddress Recipient on the destination chain\n /// @param _amount Amount to bridge\n function _debitCreditFrom(\n uint16 _dstChainId,\n bytes memory _toAddress,\n uint256 _amount\n ) internal virtual returns (uint256);\n\n /// @notice Makes accountability when bridging to this contract\n /// @param _srcChainId ChainId of the source chain - LayerZero standard\n /// @param _toAddress Recipient on this chain\n /// @param _amount Amount to bridge\n function _creditTo(uint16 _srcChainId, address _toAddress, uint256 _amount) internal virtual returns (uint256);\n\n // ========================== View Functions ===================================\n\n /// @inheritdoc ERC165Upgradeable\n function supportsInterface(\n bytes4 interfaceId\n ) public view virtual override(ERC165Upgradeable, IERC165) returns (bool) {\n return interfaceId == type(IOFTCore).interfaceId || super.supportsInterface(interfaceId);\n }\n\n /// @inheritdoc IOFTCore\n function estimateSendFee(\n uint16 _dstChainId,\n bytes memory _toAddress,\n uint256 _amount,\n bool _useZro,\n bytes memory _adapterParams\n ) public view virtual override returns (uint256 nativeFee, uint256 zroFee) {\n // mock the payload for send()\n bytes memory payload = abi.encode(_toAddress, _amount);\n return lzEndpoint.estimateFees(_dstChainId, address(this), payload, _useZro, _adapterParams);\n }\n\n uint256[49] private __gap;\n}\n" + }, + "contracts/agToken/polygon/TokenPolygonUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.12;\n\nimport \"./utils/ERC20UpgradeableCustom.sol\";\nimport \"@openzeppelin/contracts-upgradeable/access/AccessControlUpgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/utils/cryptography/draft-EIP712Upgradeable.sol\";\nimport \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\nimport \"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\";\n\nimport \"../../interfaces/IAgToken.sol\";\nimport \"../../interfaces/ITreasury.sol\";\n\ninterface IChildToken {\n function deposit(address user, bytes calldata depositData) external;\n\n function withdraw(uint256 amount) external;\n}\n\ncontract TokenPolygonUpgradeable is\n Initializable,\n ERC20UpgradeableCustom,\n AccessControlUpgradeable,\n EIP712Upgradeable,\n IChildToken\n{\n bytes32 public constant DEPOSITOR_ROLE = keccak256(\"DEPOSITOR_ROLE\");\n\n /// @dev Emitted when the child chain manager changes\n event ChildChainManagerAdded(address newAddress);\n event ChildChainManagerRevoked(address oldAddress);\n\n constructor() initializer {}\n\n function initialize(\n string memory _name,\n string memory _symbol,\n address childChainManager,\n address guardian\n ) public initializer {\n __ERC20_init(_name, _symbol);\n __AccessControl_init();\n _setupRole(DEFAULT_ADMIN_ROLE, guardian);\n _setupRole(DEPOSITOR_ROLE, childChainManager);\n __EIP712_init(_name, \"1\");\n }\n\n /**\n * @notice Called when the bridge has tokens to mint\n * @param user Address to mint the token to\n * @param depositData Encoded amount to mint\n */\n function deposit(address user, bytes calldata depositData) external override {\n require(hasRole(DEPOSITOR_ROLE, msg.sender));\n uint256 amount = abi.decode(depositData, (uint256));\n _mint(user, amount);\n }\n\n /**\n * @notice Called when user wants to withdraw tokens back to root chain\n * @dev Should burn user's tokens. This transaction will be verified when exiting on root chain\n * @param amount Amount of tokens to withdraw\n */\n function withdraw(uint256 amount) external override {\n _burn(_msgSender(), amount);\n }\n\n // =============================================================================\n // ======================= New data added for the upgrade ======================\n // =============================================================================\n\n mapping(address => bool) public isMinter;\n /// @notice Reference to the treasury contract which can grant minting rights\n address public treasury;\n /// @notice Boolean to check whether the contract has been reinitialized after its upgrade\n bool public treasuryInitialized;\n\n using SafeERC20 for IERC20;\n\n /// @notice Base used for fee computation\n uint256 public constant BASE_PARAMS = 10 ** 9;\n\n // =============================== Bridging Data ===============================\n\n /// @notice Struct with some data about a specific bridge token\n struct BridgeDetails {\n // Limit on the balance of bridge token held by the contract: it is designed\n // to reduce the exposure of the system to hacks\n uint256 limit;\n // Limit on the hourly volume of token minted through this bridge\n // Technically the limit over a rolling hour is hourlyLimit x2 as hourly limit\n // is enforced only between x:00 and x+1:00\n uint256 hourlyLimit;\n // Fee taken for swapping in and out the token\n uint64 fee;\n // Whether the associated token is allowed or not\n bool allowed;\n // Whether swapping in and out from the associated token is paused or not\n bool paused;\n }\n\n /// @notice Maps a bridge token to data\n mapping(address => BridgeDetails) public bridges;\n /// @notice List of all bridge tokens\n address[] public bridgeTokensList;\n /// @notice Maps a bridge token to the associated hourly volume\n mapping(address => mapping(uint256 => uint256)) public usage;\n /// @notice Maps an address to whether it is exempt of fees for when it comes to swapping in and out\n mapping(address => uint256) public isFeeExempt;\n /// @notice Limit to the amount of tokens that can be sent from that chain to another chain\n uint256 public chainTotalHourlyLimit;\n /// @notice Usage per hour on that chain. Maps an hourly timestamp to the total volume swapped out on the chain\n mapping(uint256 => uint256) public chainTotalUsage;\n\n uint256[42] private __gap;\n\n // ================================== Events ===================================\n\n event BridgeTokenAdded(address indexed bridgeToken, uint256 limit, uint256 hourlyLimit, uint64 fee, bool paused);\n event BridgeTokenToggled(address indexed bridgeToken, bool toggleStatus);\n event BridgeTokenRemoved(address indexed bridgeToken);\n event BridgeTokenFeeUpdated(address indexed bridgeToken, uint64 fee);\n event BridgeTokenLimitUpdated(address indexed bridgeToken, uint256 limit);\n event BridgeTokenHourlyLimitUpdated(address indexed bridgeToken, uint256 hourlyLimit);\n event HourlyLimitUpdated(uint256 hourlyLimit);\n event FeeToggled(address indexed theAddress, uint256 toggleStatus);\n event KeeperToggled(address indexed keeper, bool toggleStatus);\n event MinterToggled(address indexed minter);\n event Recovered(address indexed token, address indexed to, uint256 amount);\n event TreasuryUpdated(address indexed _treasury);\n\n // ================================== Errors ===================================\n\n error AssetStillControlledInReserves();\n error BurnAmountExceedsAllowance();\n error HourlyLimitExceeded();\n error InvalidSender();\n error InvalidToken();\n error InvalidTreasury();\n error NotGovernor();\n error NotGovernorOrGuardian();\n error NotMinter();\n error NotTreasury();\n error TooBigAmount();\n error TooHighParameterValue();\n error TreasuryAlreadyInitialized();\n error ZeroAddress();\n\n /// @notice Checks to see if it is the `Treasury` calling this contract\n /// @dev There is no Access Control here, because it can be handled cheaply through this modifier\n modifier onlyTreasury() {\n if (msg.sender != treasury) revert NotTreasury();\n _;\n }\n\n /// @notice Checks whether the sender has the minting right\n modifier onlyMinter() {\n if (!isMinter[msg.sender]) revert NotMinter();\n _;\n }\n\n /// @notice Checks whether the `msg.sender` has the governor role or not\n modifier onlyGovernor() {\n if (!ITreasury(treasury).isGovernor(msg.sender)) revert NotGovernor();\n _;\n }\n\n /// @notice Checks whether the `msg.sender` has the governor role or the guardian role\n modifier onlyGovernorOrGuardian() {\n if (!ITreasury(treasury).isGovernorOrGuardian(msg.sender)) revert NotGovernorOrGuardian();\n _;\n }\n\n /// @notice Sets up the treasury contract on Polygon after the upgrade\n /// @param _treasury Address of the treasury contract\n function setUpTreasury(address _treasury) external {\n // Only governor on Polygon\n if (msg.sender != 0xdA2D2f638D6fcbE306236583845e5822554c02EA) revert NotGovernor();\n if (address(ITreasury(_treasury).stablecoin()) != address(this)) revert InvalidTreasury();\n if (treasuryInitialized) revert TreasuryAlreadyInitialized();\n treasury = _treasury;\n treasuryInitialized = true;\n emit TreasuryUpdated(_treasury);\n }\n\n // =========================== External Function ===============================\n\n /// @notice Allows anyone to burn agToken without redeeming collateral back\n /// @param amount Amount of stablecoins to burn\n /// @dev This function can typically be called if there is a settlement mechanism to burn stablecoins\n function burnStablecoin(uint256 amount) external {\n _burnCustom(msg.sender, amount);\n }\n\n // ======================= Minter Role Only Functions ==========================\n\n function burnSelf(uint256 amount, address burner) external onlyMinter {\n _burnCustom(burner, amount);\n }\n\n function burnFrom(uint256 amount, address burner, address sender) external onlyMinter {\n _burnFromNoRedeem(amount, burner, sender);\n }\n\n function mint(address account, uint256 amount) external onlyMinter {\n _mint(account, amount);\n }\n\n // ======================= Treasury Only Functions =============================\n\n function addMinter(address minter) external onlyTreasury {\n isMinter[minter] = true;\n emit MinterToggled(minter);\n }\n\n function removeMinter(address minter) external {\n if (msg.sender != address(treasury) && msg.sender != minter) revert InvalidSender();\n isMinter[minter] = false;\n emit MinterToggled(minter);\n }\n\n function setTreasury(address _treasury) external onlyTreasury {\n treasury = _treasury;\n emit TreasuryUpdated(_treasury);\n }\n\n // ============================ Internal Function ==============================\n\n /// @notice Internal version of the function `burnFromNoRedeem`\n /// @param amount Amount to burn\n /// @dev It is at the level of this function that allowance checks are performed\n function _burnFromNoRedeem(uint256 amount, address burner, address sender) internal {\n if (burner != sender) {\n uint256 currentAllowance = allowance(burner, sender);\n if (currentAllowance < amount) revert BurnAmountExceedsAllowance();\n _approve(burner, sender, currentAllowance - amount);\n }\n _burnCustom(burner, amount);\n }\n\n // ==================== External Permissionless Functions ======================\n\n /// @notice Returns the list of all supported bridge tokens\n /// @dev Helpful for UIs\n function allBridgeTokens() external view returns (address[] memory) {\n return bridgeTokensList;\n }\n\n /// @notice Returns the current volume for a bridge, for the current hour\n /// @dev Helpful for UIs\n function currentUsage(address bridge) external view returns (uint256) {\n return usage[bridge][block.timestamp / 3600];\n }\n\n /// @notice Returns the current total volume on the chain for the current hour\n /// @dev Helpful for UIs\n function currentTotalUsage() external view returns (uint256) {\n return chainTotalUsage[block.timestamp / 3600];\n }\n\n /// @notice Mints the canonical token from a supported bridge token\n /// @param bridgeToken Bridge token to use to mint\n /// @param amount Amount of bridge tokens to send\n /// @param to Address to which the stablecoin should be sent\n /// @dev Some fees may be taken by the protocol depending on the token used and on the address calling\n function swapIn(address bridgeToken, uint256 amount, address to) external returns (uint256) {\n BridgeDetails memory bridgeDetails = bridges[bridgeToken];\n if (!bridgeDetails.allowed || bridgeDetails.paused) revert InvalidToken();\n uint256 balance = IERC20(bridgeToken).balanceOf(address(this));\n if (balance + amount > bridgeDetails.limit) {\n // In case someone maliciously sends tokens to this contract\n // Or the limit changes\n if (bridgeDetails.limit > balance) amount = bridgeDetails.limit - balance;\n else {\n amount = 0;\n }\n }\n\n // Checking requirement on the hourly volume\n uint256 hour = block.timestamp / 3600;\n uint256 hourlyUsage = usage[bridgeToken][hour] + amount;\n if (hourlyUsage > bridgeDetails.hourlyLimit) {\n // Edge case when the hourly limit changes\n if (bridgeDetails.hourlyLimit > usage[bridgeToken][hour])\n amount = bridgeDetails.hourlyLimit - usage[bridgeToken][hour];\n else {\n amount = 0;\n }\n }\n usage[bridgeToken][hour] += amount;\n\n IERC20(bridgeToken).safeTransferFrom(msg.sender, address(this), amount);\n uint256 canonicalOut = amount;\n // Computing fees\n if (isFeeExempt[msg.sender] == 0) {\n canonicalOut -= (canonicalOut * bridgeDetails.fee) / BASE_PARAMS;\n }\n _mint(to, canonicalOut);\n return canonicalOut;\n }\n\n /// @notice Burns the canonical token in exchange for a bridge token\n /// @param bridgeToken Bridge token required\n /// @param amount Amount of canonical tokens to burn\n /// @param to Address to which the bridge token should be sent\n /// @dev Some fees may be taken by the protocol depending on the token used and on the address calling\n function swapOut(address bridgeToken, uint256 amount, address to) external returns (uint256) {\n BridgeDetails memory bridgeDetails = bridges[bridgeToken];\n if (!bridgeDetails.allowed || bridgeDetails.paused) revert InvalidToken();\n\n uint256 hour = block.timestamp / 3600;\n uint256 hourlyUsage = chainTotalUsage[hour] + amount;\n // If the amount being swapped out exceeds the limit, we revert\n // We don't want to change the amount being swapped out.\n // The user can decide to send another tx with the correct amount to reach the limit\n if (hourlyUsage > chainTotalHourlyLimit) revert HourlyLimitExceeded();\n chainTotalUsage[hour] = hourlyUsage;\n\n _burnCustom(msg.sender, amount);\n uint256 bridgeOut = amount;\n if (isFeeExempt[msg.sender] == 0) {\n bridgeOut -= (bridgeOut * bridgeDetails.fee) / BASE_PARAMS;\n }\n IERC20(bridgeToken).safeTransfer(to, bridgeOut);\n return bridgeOut;\n }\n\n // ======================= Governance Functions ================================\n\n /// @notice Adds support for a bridge token\n /// @param bridgeToken Bridge token to add: it should be a version of the stablecoin from another bridge\n /// @param limit Limit on the balance of bridge token this contract could hold\n /// @param hourlyLimit Limit on the hourly volume for this bridge\n /// @param paused Whether swapping for this token should be paused or not\n /// @param fee Fee taken upon swapping for or against this token\n function addBridgeToken(\n address bridgeToken,\n uint256 limit,\n uint256 hourlyLimit,\n uint64 fee,\n bool paused\n ) external onlyGovernor {\n if (bridges[bridgeToken].allowed || bridgeToken == address(0)) revert InvalidToken();\n if (fee > BASE_PARAMS) revert TooHighParameterValue();\n BridgeDetails memory _bridge;\n _bridge.limit = limit;\n _bridge.hourlyLimit = hourlyLimit;\n _bridge.paused = paused;\n _bridge.fee = fee;\n _bridge.allowed = true;\n bridges[bridgeToken] = _bridge;\n bridgeTokensList.push(bridgeToken);\n emit BridgeTokenAdded(bridgeToken, limit, hourlyLimit, fee, paused);\n }\n\n /// @notice Removes support for a token\n /// @param bridgeToken Address of the bridge token to remove support for\n function removeBridgeToken(address bridgeToken) external onlyGovernor {\n if (IERC20(bridgeToken).balanceOf(address(this)) != 0) revert AssetStillControlledInReserves();\n delete bridges[bridgeToken];\n // Deletion from `bridgeTokensList` loop\n uint256 bridgeTokensListLength = bridgeTokensList.length;\n for (uint256 i; i < bridgeTokensListLength - 1; ++i) {\n if (bridgeTokensList[i] == bridgeToken) {\n // Replace the `bridgeToken` to remove with the last of the list\n bridgeTokensList[i] = bridgeTokensList[bridgeTokensListLength - 1];\n break;\n }\n }\n // Remove last element in array\n bridgeTokensList.pop();\n emit BridgeTokenRemoved(bridgeToken);\n }\n\n /// @notice Recovers any ERC20 token\n /// @dev Can be used to withdraw bridge tokens for them to be de-bridged on mainnet\n function recoverERC20(address tokenAddress, address to, uint256 amountToRecover) external onlyGovernor {\n IERC20(tokenAddress).safeTransfer(to, amountToRecover);\n emit Recovered(tokenAddress, to, amountToRecover);\n }\n\n /// @notice Updates the `limit` amount for `bridgeToken`\n function setLimit(address bridgeToken, uint256 limit) external onlyGovernorOrGuardian {\n if (!bridges[bridgeToken].allowed) revert InvalidToken();\n bridges[bridgeToken].limit = limit;\n emit BridgeTokenLimitUpdated(bridgeToken, limit);\n }\n\n /// @notice Updates the `hourlyLimit` amount for `bridgeToken`\n function setHourlyLimit(address bridgeToken, uint256 hourlyLimit) external onlyGovernorOrGuardian {\n if (!bridges[bridgeToken].allowed) revert InvalidToken();\n bridges[bridgeToken].hourlyLimit = hourlyLimit;\n emit BridgeTokenHourlyLimitUpdated(bridgeToken, hourlyLimit);\n }\n\n /// @notice Updates the `chainTotalHourlyLimit` amount\n function setChainTotalHourlyLimit(uint256 hourlyLimit) external onlyGovernorOrGuardian {\n chainTotalHourlyLimit = hourlyLimit;\n emit HourlyLimitUpdated(hourlyLimit);\n }\n\n /// @notice Updates the `fee` value for `bridgeToken`\n function setSwapFee(address bridgeToken, uint64 fee) external onlyGovernorOrGuardian {\n if (!bridges[bridgeToken].allowed) revert InvalidToken();\n if (fee > BASE_PARAMS) revert TooHighParameterValue();\n bridges[bridgeToken].fee = fee;\n emit BridgeTokenFeeUpdated(bridgeToken, fee);\n }\n\n /// @notice Pauses or unpauses swapping in and out for a token\n function toggleBridge(address bridgeToken) external onlyGovernorOrGuardian {\n if (!bridges[bridgeToken].allowed) revert InvalidToken();\n bool pausedStatus = bridges[bridgeToken].paused;\n bridges[bridgeToken].paused = !pausedStatus;\n emit BridgeTokenToggled(bridgeToken, !pausedStatus);\n }\n\n /// @notice Toggles fees for the address `theAddress`\n function toggleFeesForAddress(address theAddress) external onlyGovernorOrGuardian {\n uint256 feeExemptStatus = 1 - isFeeExempt[theAddress];\n isFeeExempt[theAddress] = feeExemptStatus;\n emit FeeToggled(theAddress, feeExemptStatus);\n }\n}\n" + }, + "contracts/agToken/polygon/utils/ERC20UpgradeableCustom.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (token/ERC20/ERC20.sol)\n\npragma solidity ^0.8.0;\n\nimport \"@openzeppelin/contracts-upgradeable/token/ERC20/IERC20Upgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/token/ERC20/extensions/IERC20MetadataUpgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/utils/ContextUpgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol\";\n\n/**\n * @dev Implementation of the {IERC20} interface modified by Angle Labs, Inc.\n *\n * This implementation has a custom burn function to avoid having a {Transfer} event to the zero address\n * in some specific burn cases to avoid having Polygon PoS bridge catching this event\n *\n * TIP: For a detailed writeup see our guide\n * https://forum.zeppelin.solutions/t/how-to-implement-erc20-supply-mechanisms/226[How\n * to implement supply mechanisms].\n *\n * We have followed general OpenZeppelin Contracts guidelines: functions revert\n * instead returning `false` on failure. This behavior is nonetheless\n * conventional and does not conflict with the expectations of ERC20\n * applications.\n *\n * Additionally, an {Approval} event is emitted on calls to {transferFrom}.\n * This allows applications to reconstruct the allowance for all accounts just\n * by listening to said events. Other implementations of the EIP may not emit\n * these events, as it isn't required by the specification.\n *\n * Finally, the non-standard {decreaseAllowance} and {increaseAllowance}\n * functions have been added to mitigate the well-known issues around setting\n * allowances. See {IERC20-approve}.\n */\ncontract ERC20UpgradeableCustom is Initializable, ContextUpgradeable, IERC20Upgradeable, IERC20MetadataUpgradeable {\n mapping(address => uint256) private _balances;\n\n mapping(address => mapping(address => uint256)) private _allowances;\n\n uint256 private _totalSupply;\n\n string private _name;\n string private _symbol;\n\n /**\n * @dev Sets the values for {name} and {symbol}.\n *\n * The default value of {decimals} is 18. To select a different value for\n * {decimals} you should overload it.\n *\n * All two of these values are immutable: they can only be set once during\n * construction.\n */\n //solhint-disable-next-line\n function __ERC20_init(string memory name_, string memory symbol_) internal onlyInitializing {\n __Context_init_unchained();\n __ERC20_init_unchained(name_, symbol_);\n }\n\n //solhint-disable-next-line\n function __ERC20_init_unchained(string memory name_, string memory symbol_) internal onlyInitializing {\n _name = name_;\n _symbol = symbol_;\n }\n\n /**\n * @dev Returns the name of the token.\n */\n function name() public view virtual override returns (string memory) {\n return _name;\n }\n\n /**\n * @dev Returns the symbol of the token, usually a shorter version of the\n * name.\n */\n function symbol() public view virtual override returns (string memory) {\n return _symbol;\n }\n\n /**\n * @dev Returns the number of decimals used to get its user representation.\n * For example, if `decimals` equals `2`, a balance of `505` tokens should\n * be displayed to a user as `5.05` (`505 / 10 ** 2`).\n *\n * Tokens usually opt for a value of 18, imitating the relationship between\n * Ether and Wei. This is the value {ERC20} uses, unless this function is\n * overridden;\n *\n * NOTE: This information is only used for _display_ purposes: it in\n * no way affects any of the arithmetic of the contract, including\n * {IERC20-balanceOf} and {IERC20-transfer}.\n */\n function decimals() public view virtual override returns (uint8) {\n return 18;\n }\n\n /**\n * @dev See {IERC20-totalSupply}.\n */\n function totalSupply() public view virtual override returns (uint256) {\n return _totalSupply;\n }\n\n /**\n * @dev See {IERC20-balanceOf}.\n */\n function balanceOf(address account) public view virtual override returns (uint256) {\n return _balances[account];\n }\n\n /**\n * @dev See {IERC20-transfer}.\n *\n * Requirements:\n *\n * - `recipient` cannot be the zero address.\n * - the caller must have a balance of at least `amount`.\n */\n function transfer(address recipient, uint256 amount) public virtual override returns (bool) {\n _transfer(_msgSender(), recipient, amount);\n return true;\n }\n\n /**\n * @dev See {IERC20-allowance}.\n */\n function allowance(address owner, address spender) public view virtual override returns (uint256) {\n return _allowances[owner][spender];\n }\n\n /**\n * @dev See {IERC20-approve}.\n *\n * Requirements:\n *\n * - `spender` cannot be the zero address.\n */\n function approve(address spender, uint256 amount) public virtual override returns (bool) {\n _approve(_msgSender(), spender, amount);\n return true;\n }\n\n /**\n * @dev See {IERC20-transferFrom}.\n *\n * Emits an {Approval} event indicating the updated allowance. This is not\n * required by the EIP. See the note at the beginning of {ERC20}.\n *\n * Requirements:\n *\n * - `sender` and `recipient` cannot be the zero address.\n * - `sender` must have a balance of at least `amount`.\n * - the caller must have allowance for `sender`'s tokens of at least\n * `amount`.\n */\n function transferFrom(address sender, address recipient, uint256 amount) public virtual override returns (bool) {\n _transfer(sender, recipient, amount);\n\n uint256 currentAllowance = _allowances[sender][_msgSender()];\n require(currentAllowance >= amount, \"ERC20: transfer amount exceeds allowance\");\n unchecked {\n _approve(sender, _msgSender(), currentAllowance - amount);\n }\n\n return true;\n }\n\n /**\n * @dev Atomically increases the allowance granted to `spender` by the caller.\n *\n * This is an alternative to {approve} that can be used as a mitigation for\n * problems described in {IERC20-approve}.\n *\n * Emits an {Approval} event indicating the updated allowance.\n *\n * Requirements:\n *\n * - `spender` cannot be the zero address.\n */\n function increaseAllowance(address spender, uint256 addedValue) public virtual returns (bool) {\n _approve(_msgSender(), spender, _allowances[_msgSender()][spender] + addedValue);\n return true;\n }\n\n /**\n * @dev Atomically decreases the allowance granted to `spender` by the caller.\n *\n * This is an alternative to {approve} that can be used as a mitigation for\n * problems described in {IERC20-approve}.\n *\n * Emits an {Approval} event indicating the updated allowance.\n *\n * Requirements:\n *\n * - `spender` cannot be the zero address.\n * - `spender` must have allowance for the caller of at least\n * `subtractedValue`.\n */\n function decreaseAllowance(address spender, uint256 subtractedValue) public virtual returns (bool) {\n uint256 currentAllowance = _allowances[_msgSender()][spender];\n require(currentAllowance >= subtractedValue, \"ERC20: decreased allowance below zero\");\n unchecked {\n _approve(_msgSender(), spender, currentAllowance - subtractedValue);\n }\n\n return true;\n }\n\n /**\n * @dev Moves `amount` of tokens from `sender` to `recipient`.\n *\n * This internal function is equivalent to {transfer}, and can be used to\n * e.g. implement automatic token fees, slashing mechanisms, etc.\n *\n * Emits a {Transfer} event.\n *\n * Requirements:\n *\n * - `sender` cannot be the zero address.\n * - `recipient` cannot be the zero address.\n * - `sender` must have a balance of at least `amount`.\n */\n function _transfer(address sender, address recipient, uint256 amount) internal virtual {\n require(sender != address(0), \"ERC20: transfer from the zero address\");\n require(recipient != address(0), \"ERC20: transfer to the zero address\");\n\n _beforeTokenTransfer(sender, recipient, amount);\n\n uint256 senderBalance = _balances[sender];\n require(senderBalance >= amount, \"ERC20: transfer amount exceeds balance\");\n unchecked {\n _balances[sender] = senderBalance - amount;\n }\n _balances[recipient] += amount;\n\n emit Transfer(sender, recipient, amount);\n\n _afterTokenTransfer(sender, recipient, amount);\n }\n\n /** @dev Creates `amount` tokens and assigns them to `account`, increasing\n * the total supply.\n *\n * Emits a {Transfer} event with `from` set to the zero address.\n *\n * Requirements:\n *\n * - `account` cannot be the zero address.\n */\n function _mint(address account, uint256 amount) internal virtual {\n require(account != address(0), \"ERC20: mint to the zero address\");\n\n _beforeTokenTransfer(address(0), account, amount);\n\n _totalSupply += amount;\n _balances[account] += amount;\n emit Transfer(address(0), account, amount);\n\n _afterTokenTransfer(address(0), account, amount);\n }\n\n /**\n * @dev Destroys `amount` tokens from `account`, reducing the\n * total supply.\n *\n * Emits a {Transfer} event with `to` set to the zero address.\n *\n * Requirements:\n *\n * - `account` cannot be the zero address.\n * - `account` must have at least `amount` tokens.\n */\n function _burn(address account, uint256 amount) internal virtual {\n require(account != address(0), \"ERC20: burn from the zero address\");\n\n _beforeTokenTransfer(account, address(0), amount);\n\n uint256 accountBalance = _balances[account];\n require(accountBalance >= amount, \"ERC20: burn amount exceeds balance\");\n unchecked {\n _balances[account] = accountBalance - amount;\n }\n _totalSupply -= amount;\n\n emit Transfer(account, address(0), amount);\n\n _afterTokenTransfer(account, address(0), amount);\n }\n\n /**\n * @dev Destroys `amount` tokens from `account`, reducing the\n * total supply.\n *\n * Contrary to the other `burn` function, the {Transfer} event is not to the zero address\n * but rather to this address: the reason is that not all burn events should be caught up\n * by the PoS bridge\n *\n * Requirements:\n *\n * - `account` cannot be the zero address.\n * - `account` must have at least `amount` tokens.\n */\n function _burnCustom(address account, uint256 amount) internal virtual {\n require(account != address(0), \"ERC20: burn from the zero address\");\n\n _beforeTokenTransfer(account, address(0), amount);\n\n uint256 accountBalance = _balances[account];\n require(accountBalance >= amount, \"ERC20: burn amount exceeds balance\");\n unchecked {\n _balances[account] = accountBalance - amount;\n }\n _totalSupply -= amount;\n\n emit Transfer(account, address(this), amount);\n\n _afterTokenTransfer(account, address(0), amount);\n }\n\n /**\n * @dev Sets `amount` as the allowance of `spender` over the `owner` s tokens.\n *\n * This internal function is equivalent to `approve`, and can be used to\n * e.g. set automatic allowances for certain subsystems, etc.\n *\n * Emits an {Approval} event.\n *\n * Requirements:\n *\n * - `owner` cannot be the zero address.\n * - `spender` cannot be the zero address.\n */\n function _approve(address owner, address spender, uint256 amount) internal virtual {\n require(owner != address(0), \"ERC20: approve from the zero address\");\n require(spender != address(0), \"ERC20: approve to the zero address\");\n\n _allowances[owner][spender] = amount;\n emit Approval(owner, spender, amount);\n }\n\n /**\n * @dev Hook that is called before any transfer of tokens. This includes\n * minting and burning.\n *\n * Calling conditions:\n *\n * - when `from` and `to` are both non-zero, `amount` of `from`'s tokens\n * will be transferred to `to`.\n * - when `from` is zero, `amount` tokens will be minted for `to`.\n * - when `to` is zero, `amount` of `from`'s tokens will be burned.\n * - `from` and `to` are never both zero.\n *\n * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].\n */\n function _beforeTokenTransfer(address from, address to, uint256 amount) internal virtual {}\n\n /**\n * @dev Hook that is called after any transfer of tokens. This includes\n * minting and burning.\n *\n * Calling conditions:\n *\n * - when `from` and `to` are both non-zero, `amount` of `from`'s tokens\n * has been transferred to `to`.\n * - when `from` is zero, `amount` tokens have been minted for `to`.\n * - when `to` is zero, `amount` of `from`'s tokens have been burned.\n * - `from` and `to` are never both zero.\n *\n * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].\n */\n function _afterTokenTransfer(address from, address to, uint256 amount) internal virtual {}\n\n uint256[45] private __gap;\n}\n" + }, + "contracts/coreBorrow/CoreBorrow.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\n/*\n * █ \n ***** ▓▓▓ \n * ▓▓▓▓▓▓▓ \n * ///. ▓▓▓▓▓▓▓▓▓▓▓▓▓ \n ***** //////// ▓▓▓▓▓▓▓ \n * ///////////// ▓▓▓ \n ▓▓ ////////////////// █ ▓▓ \n ▓▓ ▓▓ /////////////////////// ▓▓ ▓▓ \n ▓▓ ▓▓ //////////////////////////// ▓▓ ▓▓ \n ▓▓ ▓▓ /////////▓▓▓///////▓▓▓///////// ▓▓ ▓▓ \n ▓▓ ,////////////////////////////////////// ▓▓ ▓▓ \n ▓▓ ////////////////////////////////////////// ▓▓ \n ▓▓ //////////////////////▓▓▓▓///////////////////// \n ,//////////////////////////////////////////////////// \n .////////////////////////////////////////////////////////// \n .//////////////////////////██.,//////////////////////////█ \n .//////////////////////████..,./////////////////////██ \n ...////////////////███████.....,.////////////////███ \n ,.,////////////████████ ........,///////////████ \n .,.,//////█████████ ,.......///////████ \n ,..//████████ ........./████ \n ..,██████ .....,███ \n .██ ,.,█ \n \n \n \n ▓▓ ▓▓▓▓▓▓▓▓▓▓ ▓▓▓▓▓▓▓▓▓▓ ▓▓ ▓▓▓▓▓▓▓▓▓▓ \n ▓▓▓▓▓▓ ▓▓▓ ▓▓▓ ▓▓▓ ▓▓ ▓▓ ▓▓▓▓ \n ▓▓▓ ▓▓▓ ▓▓▓ ▓▓▓ ▓▓▓ ▓▓▓ ▓▓ ▓▓▓▓▓ \n ▓▓▓ ▓▓ ▓▓▓ ▓▓▓ ▓▓▓▓▓▓▓▓▓▓ ▓▓▓▓▓▓▓▓▓▓ ▓▓▓▓▓▓▓▓▓▓ \n*/\n\npragma solidity ^0.8.12;\n\nimport \"@openzeppelin/contracts-upgradeable/access/AccessControlEnumerableUpgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol\";\n\nimport \"../interfaces/ICoreBorrow.sol\";\nimport \"../interfaces/IFlashAngle.sol\";\nimport \"../interfaces/ITreasury.sol\";\n\n/// @title CoreBorrow\n/// @author Angle Labs, Inc.\n/// @notice Core contract of the borrowing module. This contract handles the access control across all contracts\n/// (it is read by all treasury contracts), and manages the `flashLoanModule`. It has no minting rights over the\n/// stablecoin contracts\ncontract CoreBorrow is ICoreBorrow, Initializable, AccessControlEnumerableUpgradeable {\n /// @notice Role for guardians\n bytes32 public constant GUARDIAN_ROLE = keccak256(\"GUARDIAN_ROLE\");\n /// @notice Role for governors\n bytes32 public constant GOVERNOR_ROLE = keccak256(\"GOVERNOR_ROLE\");\n /// @notice Role for treasury contract\n bytes32 public constant FLASHLOANER_TREASURY_ROLE = keccak256(\"FLASHLOANER_TREASURY_ROLE\");\n\n // ============================= Reference =====================================\n\n /// @notice Reference to the `flashLoanModule` with minting rights over the different stablecoins of the protocol\n address public flashLoanModule;\n\n // =============================== Events ======================================\n\n event FlashLoanModuleUpdated(address indexed _flashloanModule);\n event CoreUpdated(address indexed _core);\n\n // =============================== Errors ======================================\n\n error InvalidCore();\n error IncompatibleGovernorAndGuardian();\n error NotEnoughGovernorsLeft();\n error ZeroAddress();\n\n /// @notice Initializes the `CoreBorrow` contract and the access control of the borrowing module\n /// @param governor Address of the governor of the Angle Protocol\n /// @param guardian Guardian address of the protocol\n function initialize(address governor, address guardian) public initializer {\n if (governor == address(0) || guardian == address(0)) revert ZeroAddress();\n if (governor == guardian) revert IncompatibleGovernorAndGuardian();\n _setupRole(GOVERNOR_ROLE, governor);\n _setupRole(GUARDIAN_ROLE, guardian);\n _setupRole(GUARDIAN_ROLE, governor);\n _setRoleAdmin(GUARDIAN_ROLE, GOVERNOR_ROLE);\n _setRoleAdmin(GOVERNOR_ROLE, GOVERNOR_ROLE);\n _setRoleAdmin(FLASHLOANER_TREASURY_ROLE, GOVERNOR_ROLE);\n }\n\n /// @custom:oz-upgrades-unsafe-allow constructor\n constructor() initializer {}\n\n // =========================== View Functions ==================================\n\n /// @inheritdoc ICoreBorrow\n function isFlashLoanerTreasury(address treasury) external view returns (bool) {\n return hasRole(FLASHLOANER_TREASURY_ROLE, treasury);\n }\n\n /// @inheritdoc ICoreBorrow\n function isGovernor(address admin) external view returns (bool) {\n return hasRole(GOVERNOR_ROLE, admin);\n }\n\n /// @inheritdoc ICoreBorrow\n function isGovernorOrGuardian(address admin) external view returns (bool) {\n return hasRole(GUARDIAN_ROLE, admin);\n }\n\n // =========================== Governor Functions ==============================\n\n /// @notice Grants the `FLASHLOANER_TREASURY_ROLE` to a `treasury` contract\n /// @param treasury Contract to grant the role to\n /// @dev This function can be used to allow flash loans on a stablecoin of the protocol\n function addFlashLoanerTreasuryRole(address treasury) external {\n grantRole(FLASHLOANER_TREASURY_ROLE, treasury);\n address _flashLoanModule = flashLoanModule;\n if (_flashLoanModule != address(0)) {\n // This call will revert if `treasury` is the zero address or if it is not linked\n // to this `CoreBorrow` contract\n ITreasury(treasury).setFlashLoanModule(_flashLoanModule);\n IFlashAngle(_flashLoanModule).addStablecoinSupport(treasury);\n }\n }\n\n /// @notice Adds a governor in the protocol\n /// @param governor Address to grant the role to\n /// @dev It is necessary to call this function to grant a governor role to make sure\n /// all governors also have the guardian role\n function addGovernor(address governor) external {\n grantRole(GOVERNOR_ROLE, governor);\n grantRole(GUARDIAN_ROLE, governor);\n }\n\n /// @notice Revokes the flash loan ability for a stablecoin\n /// @param treasury Treasury address associated with the stablecoin for which flash loans\n /// should no longer be available\n function removeFlashLoanerTreasuryRole(address treasury) external {\n revokeRole(FLASHLOANER_TREASURY_ROLE, treasury);\n ITreasury(treasury).setFlashLoanModule(address(0));\n address _flashLoanModule = flashLoanModule;\n if (_flashLoanModule != address(0)) {\n IFlashAngle(flashLoanModule).removeStablecoinSupport(treasury);\n }\n }\n\n /// @notice Revokes a governor from the protocol\n /// @param governor Address to remove the role to\n /// @dev It is necessary to call this function to remove a governor role to make sure\n /// the address also loses its guardian role\n function removeGovernor(address governor) external {\n if (getRoleMemberCount(GOVERNOR_ROLE) <= 1) revert NotEnoughGovernorsLeft();\n revokeRole(GUARDIAN_ROLE, governor);\n revokeRole(GOVERNOR_ROLE, governor);\n }\n\n /// @notice Changes the `flashLoanModule` of the protocol\n /// @param _flashLoanModule Address of the new flash loan module\n function setFlashLoanModule(address _flashLoanModule) external onlyRole(GOVERNOR_ROLE) {\n if (_flashLoanModule != address(0)) {\n if (address(IFlashAngle(_flashLoanModule).core()) != address(this)) revert InvalidCore();\n }\n uint256 count = getRoleMemberCount(FLASHLOANER_TREASURY_ROLE);\n for (uint256 i; i < count; ++i) {\n ITreasury(getRoleMember(FLASHLOANER_TREASURY_ROLE, i)).setFlashLoanModule(_flashLoanModule);\n }\n flashLoanModule = _flashLoanModule;\n emit FlashLoanModuleUpdated(_flashLoanModule);\n }\n\n /// @notice Changes the core contract of the protocol\n /// @param _core New core contract\n /// @dev This function verifies that all governors of the current core contract are also governors\n /// of the new core contract. It also notifies the `flashLoanModule` of the change.\n /// @dev Governance wishing to change the core contract should also make sure to call `setCore`\n /// in the different treasury contracts\n function setCore(ICoreBorrow _core) external onlyRole(GOVERNOR_ROLE) {\n uint256 count = getRoleMemberCount(GOVERNOR_ROLE);\n bool success;\n for (uint256 i; i < count; ++i) {\n success = _core.isGovernor(getRoleMember(GOVERNOR_ROLE, i));\n if (!success) break;\n }\n if (!success) revert InvalidCore();\n address _flashLoanModule = flashLoanModule;\n if (_flashLoanModule != address(0)) IFlashAngle(_flashLoanModule).setCore(address(_core));\n emit CoreUpdated(address(_core));\n }\n}\n" + }, + "contracts/deprecated/AgTokenIntermediateUpgrade.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\nimport \"../interfaces/IAgToken.sol\";\nimport \"../interfaces/coreModule/IStableMaster.sol\";\n// OpenZeppelin may update its version of the ERC20PermitUpgradeable token\nimport \"@openzeppelin/contracts-upgradeable/token/ERC20/extensions/draft-ERC20PermitUpgradeable.sol\";\n\n/// @title AgTokenIntermediateUpgrade\n/// @author Angle Labs, Inc.\n/// @notice Base contract for agToken, that is to say Angle's stablecoins\n/// @dev This contract is used to create and handle the stablecoins of Angle protocol\n/// @dev It is still possible for any address to burn its agTokens without redeeming collateral in exchange\n/// @dev This contract is the upgraded version of the AgToken that was first deployed on Ethereum mainnet and is used to\n/// add other minters as needed by AMOs\ncontract AgTokenIntermediateUpgrade is ERC20PermitUpgradeable {\n // ========================= References to other contracts =====================\n\n /// @notice Reference to the `StableMaster` contract associated to this `AgToken`\n address public stableMaster;\n\n // ============================= Constructor ===================================\n\n /// @notice Initializes the `AgToken` contract\n /// @param name_ Name of the token\n /// @param symbol_ Symbol of the token\n /// @param stableMaster_ Reference to the `StableMaster` contract associated to this agToken\n /// @dev By default, agTokens are ERC-20 tokens with 18 decimals\n function initialize(string memory name_, string memory symbol_, address stableMaster_) external initializer {\n __ERC20Permit_init(name_);\n __ERC20_init(name_, symbol_);\n require(stableMaster_ != address(0), \"0\");\n stableMaster = stableMaster_;\n }\n\n /// @custom:oz-upgrades-unsafe-allow constructor\n constructor() initializer {}\n\n // ======= Added Parameters and Variables from the first implementation ========\n\n /// @notice Checks whether an address has the right to mint agTokens\n mapping(address => bool) public isMinter;\n\n // =============================== Added Events ================================\n\n event MinterToggled(address indexed minter);\n\n // =============================== Setup Function ==============================\n\n /// @notice Sets up the minter role and gives it to the governor\n /// @dev This function just has to be called once\n function setUpMinter() external {\n address governor = 0xdC4e6DFe07EFCa50a197DF15D9200883eF4Eb1c8;\n require(msg.sender == governor);\n isMinter[governor] = true;\n emit MinterToggled(governor);\n }\n\n // =============================== Modifiers ===================================\n\n /// @notice Checks whether the sender has the minting right\n modifier onlyMinter() {\n require(isMinter[msg.sender] || msg.sender == stableMaster, \"35\");\n _;\n }\n\n // ========================= External Functions ================================\n // The following functions allow anyone to burn stablecoins without redeeming collateral\n // in exchange for that\n\n /// @notice Destroys `amount` token from the caller without giving collateral back\n /// @param amount Amount to burn\n /// @param poolManager Reference to the `PoolManager` contract for which the `stocksUsers` will\n /// need to be updated\n /// @dev When calling this function, people should specify the `poolManager` for which they want to decrease\n /// the `stocksUsers`: this is a way for the protocol to maintain healthy accounting variables\n function burnNoRedeem(uint256 amount, address poolManager) external {\n _burn(msg.sender, amount);\n IStableMaster(stableMaster).updateStocksUsers(amount, poolManager);\n }\n\n /// @notice Burns `amount` of agToken on behalf of another account without redeeming collateral back\n /// @param account Account to burn on behalf of\n /// @param amount Amount to burn\n /// @param poolManager Reference to the `PoolManager` contract for which the `stocksUsers` will need to be updated\n function burnFromNoRedeem(address account, uint256 amount, address poolManager) external {\n _burnFromNoRedeem(amount, account, msg.sender);\n IStableMaster(stableMaster).updateStocksUsers(amount, poolManager);\n }\n\n // ======================= Minter Role Only Functions ==========================\n\n /// @notice Burns `amount` tokens from a `burner` address\n /// @param amount Amount of tokens to burn\n /// @param burner Address to burn from\n /// @dev This method is to be called by a contract with a minter right on the AgToken after being\n /// requested to do so by an address willing to burn tokens from its address\n function burnSelf(uint256 amount, address burner) external onlyMinter {\n _burn(burner, amount);\n }\n\n /// @notice Burns `amount` tokens from a `burner` address after being asked to by `sender`\n /// @param amount Amount of tokens to burn\n /// @param burner Address to burn from\n /// @param sender Address which requested the burn from `burner`\n /// @dev This method is to be called by a contract with the minter right after being requested\n /// to do so by a `sender` address willing to burn tokens from another `burner` address\n /// @dev The method checks the allowance between the `sender` and the `burner`\n function burnFrom(uint256 amount, address burner, address sender) external onlyMinter {\n _burnFromNoRedeem(amount, burner, sender);\n }\n\n /// @notice Lets the `StableMaster` contract or another whitelisted contract mint agTokens\n /// @param account Address to mint to\n /// @param amount Amount to mint\n /// @dev The contracts allowed to issue agTokens are the `StableMaster` contract, `VaultManager` contracts\n /// associated to this stablecoin as well as the flash loan module (if activated) and potentially contracts\n /// whitelisted by governance\n function mint(address account, uint256 amount) external onlyMinter {\n _mint(account, amount);\n }\n\n // ======================= Minter Only Functions ===============================\n\n /// @notice Adds a minter in the contract\n /// @param minter Minter address to add\n function addMinter(address minter) external onlyMinter {\n isMinter[minter] = true;\n emit MinterToggled(minter);\n }\n\n /// @notice Removes a minter from the contract\n /// @param minter Minter address to remove\n /// @dev This function can at the moment only be called by a minter wishing to revoke itself\n function removeMinter(address minter) external {\n require(msg.sender == minter && isMinter[msg.sender], \"36\");\n isMinter[minter] = false;\n emit MinterToggled(minter);\n }\n\n // ============================ Internal Function ==============================\n\n /// @notice Internal version of the function `burnFromNoRedeem`\n /// @param amount Amount to burn\n /// @dev It is at the level of this function that allowance checks are performed\n function _burnFromNoRedeem(uint256 amount, address burner, address sender) internal {\n if (burner != sender) {\n uint256 currentAllowance = allowance(burner, sender);\n require(currentAllowance >= amount, \"23\");\n _approve(burner, sender, currentAllowance - amount);\n }\n _burn(burner, amount);\n }\n}\n" + }, + "contracts/deprecated/layerZero/OldLayerZeroBridgeToken.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.12;\n\nimport \"./OldOFTCore.sol\";\nimport \"../../interfaces/IAgTokenSideChainMultiBridge.sol\";\nimport \"@openzeppelin/contracts-upgradeable/security/PausableUpgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/token/ERC20/ERC20Upgradeable.sol\";\n\n/// @title LayerZeroBridgeToken\n/// @author Angle Labs, Inc., forked from https://github.com/LayerZero-Labs/solidity-examples/blob/main/contracts/token/oft/OFT.sol\n/// @notice Contract to be deployed on a L2/sidechain for bridging an AgToken using a bridge intermediate token and LayerZero\ncontract OldLayerZeroBridgeToken is OldOFTCore, ERC20Upgradeable, PausableUpgradeable {\n /// @notice Address of the bridgeable token\n /// @dev Immutable\n IAgTokenSideChainMultiBridge public canonicalToken;\n\n // =============================== Errors ================================\n\n error InvalidAllowance();\n\n // ============================= Constructor ===================================\n\n /// @notice Initializes the contract\n /// @param _name Name of the token corresponding to this contract\n /// @param _symbol Symbol of the token corresponding to this contract\n /// @param _lzEndpoint Layer zero endpoint to pass messages\n /// @param _treasury Address of the treasury contract used for access control\n /// @param initialSupply Initial supply to mint to the canonical token address\n /// @dev The initial supply corresponds to the initial amount that could be bridged using this OFT\n function initialize(\n string memory _name,\n string memory _symbol,\n address _lzEndpoint,\n address _treasury,\n uint256 initialSupply\n ) external initializer {\n __ERC20_init_unchained(_name, _symbol);\n __LzAppUpgradeable_init(_lzEndpoint, _treasury);\n\n canonicalToken = IAgTokenSideChainMultiBridge(address(ITreasury(_treasury).stablecoin()));\n _approve(address(this), address(canonicalToken), type(uint256).max);\n _mint(address(canonicalToken), initialSupply);\n }\n\n /// @custom:oz-upgrades-unsafe-allow constructor\n constructor() initializer {}\n\n // ==================== External Permissionless Functions ======================\n\n function sendWithPermit(\n uint16 _dstChainId,\n bytes memory _toAddress,\n uint256 _amount,\n address payable _refundAddress,\n address _zroPaymentAddress,\n bytes memory _adapterParams,\n uint256 deadline,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) public payable override {\n canonicalToken.permit(msg.sender, address(this), _amount, deadline, v, r, s);\n send(_dstChainId, _toAddress, _amount, _refundAddress, _zroPaymentAddress, _adapterParams);\n }\n\n function withdraw(uint256 amount, address recipient) external override returns (uint256 amountMinted) {\n // Does not check allowances as transfers from `msg.sender`\n _transfer(msg.sender, address(this), amount);\n amountMinted = canonicalToken.swapIn(address(this), amount, recipient);\n uint256 leftover = balanceOf(address(this));\n if (leftover != 0) {\n _transfer(address(this), msg.sender, leftover);\n }\n }\n\n // ============================= Internal Functions ===================================\n\n function _debitFrom(\n uint16,\n bytes memory,\n uint256 _amount\n ) internal override whenNotPaused returns (uint256 amountSwapped) {\n // No need to use safeTransferFrom as we know this implementation reverts on failure\n canonicalToken.transferFrom(msg.sender, address(this), _amount);\n\n // Swap canonical for this bridge token. There may be some fees\n amountSwapped = canonicalToken.swapOut(address(this), _amount, address(this));\n _burn(address(this), amountSwapped);\n }\n\n function _debitCreditFrom(uint16, bytes memory, uint256 _amount) internal override whenNotPaused returns (uint256) {\n _burn(msg.sender, _amount);\n return _amount;\n }\n\n function _creditTo(\n uint16,\n address _toAddress,\n uint256 _amount\n ) internal override whenNotPaused returns (uint256 amountMinted) {\n _mint(address(this), _amount);\n amountMinted = canonicalToken.swapIn(address(this), _amount, _toAddress);\n uint256 leftover = balanceOf(address(this));\n if (leftover != 0) {\n _transfer(address(this), _toAddress, leftover);\n }\n }\n\n // ======================= View Functions ================================\n\n /// @inheritdoc ERC165Upgradeable\n function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {\n return\n interfaceId == type(IOFT).interfaceId ||\n interfaceId == type(IERC20).interfaceId ||\n super.supportsInterface(interfaceId);\n }\n\n // ======================= Governance Functions ================================\n\n /// @notice Mints the intermediate contract to the `canonicalToken`\n /// @dev Used to increase the bridging capacity\n function mint(uint256 amount) external onlyGovernorOrGuardian {\n _mint(address(canonicalToken), amount);\n }\n\n /// @notice Burns the intermediate contract from the `canonicalToken`\n /// @dev Used to decrease the bridging capacity\n function burn(uint256 amount) external onlyGovernorOrGuardian {\n _burn(address(canonicalToken), amount);\n }\n\n /// @notice Increases allowance of the `canonicalToken`\n function setupAllowance() public onlyGovernorOrGuardian {\n _approve(address(this), address(canonicalToken), type(uint256).max);\n }\n\n /// @notice Pauses bridging through the contract\n /// @param pause Future pause status\n function pauseSendTokens(bool pause) external onlyGovernorOrGuardian {\n pause ? _pause() : _unpause();\n }\n\n uint256[49] private __gap;\n}\n" + }, + "contracts/deprecated/layerZero/OldNonblockingLzApp.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.12;\n\nimport \"@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol\";\nimport \"../../interfaces/external/layerZero/ILayerZeroReceiver.sol\";\nimport \"../../interfaces/external/layerZero/ILayerZeroUserApplicationConfig.sol\";\nimport \"../../interfaces/external/layerZero/ILayerZeroEndpoint.sol\";\nimport \"../../interfaces/ITreasury.sol\";\n\n/// @title OldNonblockingLzApp\n/// @author Angle Labs, Inc., forked from https://github.com/LayerZero-Labs/solidity-examples/\n/// @notice Base contract for bridging using LayerZero\nabstract contract OldNonblockingLzApp is Initializable, ILayerZeroReceiver, ILayerZeroUserApplicationConfig {\n /// @notice Layer Zero endpoint\n ILayerZeroEndpoint public lzEndpoint;\n\n /// @notice Maps chainIds to failed messages to retry them\n mapping(uint16 => mapping(bytes => mapping(uint64 => bytes32))) public failedMessages;\n\n /// @notice Maps chainIds to their OFT address\n mapping(uint16 => bytes) public trustedRemoteLookup;\n\n /// @notice Reference to the treasury contract to fetch access control\n address public treasury;\n\n // ================================== Events ===================================\n\n event SetTrustedRemote(uint16 _srcChainId, bytes _srcAddress);\n event MessageFailed(uint16 _srcChainId, bytes _srcAddress, uint64 _nonce, bytes _payload);\n\n // =============================== Errors ================================\n\n error NotGovernor();\n error NotGovernorOrGuardian();\n error InsufficientGas();\n error InvalidEndpoint();\n error InvalidSource();\n error InvalidCaller();\n error InvalidParams();\n error InvalidPayload();\n error ZeroAddress();\n\n // ============================= Constructor ===================================\n\n //solhint-disable-next-line\n function __LzAppUpgradeable_init(address _endpoint, address _treasury) internal {\n if (_endpoint == address(0) || _treasury == address(0)) revert ZeroAddress();\n lzEndpoint = ILayerZeroEndpoint(_endpoint);\n treasury = _treasury;\n }\n\n // =============================== Modifiers ===================================\n\n /// @notice Checks whether the `msg.sender` has the governor role or the guardian role\n modifier onlyGovernorOrGuardian() {\n if (!ITreasury(treasury).isGovernorOrGuardian(msg.sender)) revert NotGovernorOrGuardian();\n _;\n }\n\n // ==================== External Permissionless Functions ======================\n\n /// @notice Receives a message from the LZ endpoint and process it\n /// @param _srcChainId ChainId of the source chain - LayerZero standard\n /// @param _srcAddress Sender of the source chain\n /// @param _nonce Nounce of the message\n /// @param _payload Data: recipient address and amount\n function lzReceive(\n uint16 _srcChainId,\n bytes memory _srcAddress,\n uint64 _nonce,\n bytes memory _payload\n ) public virtual override {\n // lzReceive must be called by the endpoint for security\n if (msg.sender != address(lzEndpoint)) revert InvalidEndpoint();\n\n bytes memory trustedRemote = trustedRemoteLookup[_srcChainId];\n // if will still block the message pathway from (srcChainId, srcAddress). should not receive message from untrusted remote.\n if (_srcAddress.length != trustedRemote.length || keccak256(_srcAddress) != keccak256(trustedRemote))\n revert InvalidSource();\n\n _blockingLzReceive(_srcChainId, _srcAddress, _nonce, _payload);\n }\n\n /// @notice Retries a message that previously failed and was stored\n /// @param _srcChainId ChainId of the source chain - LayerZero standard\n /// @param _srcAddress Sender of the source chain\n /// @param _nonce Nounce of the message\n /// @param _payload Data: recipient address and amount\n function retryMessage(\n uint16 _srcChainId,\n bytes memory _srcAddress,\n uint64 _nonce,\n bytes memory _payload\n ) public payable virtual {\n // assert there is message to retry\n bytes32 payloadHash = failedMessages[_srcChainId][_srcAddress][_nonce];\n if (payloadHash == bytes32(0) || keccak256(_payload) != payloadHash) revert InvalidPayload();\n // clear the stored message\n failedMessages[_srcChainId][_srcAddress][_nonce] = bytes32(0);\n // execute the message. revert if it fails again\n _nonblockingLzReceive(_srcChainId, _srcAddress, _nonce, _payload);\n }\n\n // ============================= Internal Functions ===================================\n\n /// @notice Handles message receptions in a non blocking way\n /// @param _srcChainId ChainId of the source chain - LayerZero standard\n /// @param _srcAddress Sender of the source chain\n /// @param _nonce Nounce of the message\n /// @param _payload Data: recipient address and amount\n /// @dev public for the needs of try / catch but effectively internal\n function nonblockingLzReceive(\n uint16 _srcChainId,\n bytes memory _srcAddress,\n uint64 _nonce,\n bytes memory _payload\n ) public virtual {\n // only internal transaction\n if (msg.sender != address(this)) revert InvalidCaller();\n _nonblockingLzReceive(_srcChainId, _srcAddress, _nonce, _payload);\n }\n\n /// @notice Handles message receptions in a non blocking way\n /// @param _srcChainId ChainId of the source chain - LayerZero standard\n /// @param _srcAddress Sender of the source chain\n /// @param _nonce Nounce of the message\n /// @param _payload Data: recipient address and amount\n function _nonblockingLzReceive(\n uint16 _srcChainId,\n bytes memory _srcAddress,\n uint64 _nonce,\n bytes memory _payload\n ) internal virtual;\n\n /// @notice Handles message receptions in a blocking way\n /// @param _srcChainId ChainId of the source chain - LayerZero standard\n /// @param _srcAddress Sender of the source chain\n /// @param _nonce Nounce of the message\n /// @param _payload Data: recipient address and amount\n function _blockingLzReceive(\n uint16 _srcChainId,\n bytes memory _srcAddress,\n uint64 _nonce,\n bytes memory _payload\n ) internal {\n // try-catch all errors/exceptions\n try this.nonblockingLzReceive(_srcChainId, _srcAddress, _nonce, _payload) {\n // do nothing\n } catch {\n // error / exception\n failedMessages[_srcChainId][_srcAddress][_nonce] = keccak256(_payload);\n emit MessageFailed(_srcChainId, _srcAddress, _nonce, _payload);\n }\n }\n\n /// @notice Sends a message to the LZ endpoint and process it\n /// @param _dstChainId L0 defined chain id to send tokens too\n /// @param _payload Data: recipient address and amount\n /// @param _refundAddress Address LayerZero refunds if too much message fee is sent\n /// @param _zroPaymentAddress Set to address(0x0) if not paying in ZRO (LayerZero Token)\n /// @param _adapterParams Flexible bytes array to indicate messaging adapter services in L0\n function _lzSend(\n uint16 _dstChainId,\n bytes memory _payload,\n address payable _refundAddress,\n address _zroPaymentAddress,\n bytes memory _adapterParams\n ) internal virtual {\n bytes memory trustedRemote = trustedRemoteLookup[_dstChainId];\n if (trustedRemote.length == 0) revert InvalidSource();\n //solhint-disable-next-line\n lzEndpoint.send{ value: msg.value }(\n _dstChainId,\n trustedRemote,\n _payload,\n _refundAddress,\n _zroPaymentAddress,\n _adapterParams\n );\n }\n\n // ======================= Governance Functions ================================\n\n /// @notice Sets the corresponding address on an other chain.\n /// @param _srcChainId ChainId of the source chain - LayerZero standard\n /// @param _srcAddress Address on the source chain\n /// @dev Used for both receiving and sending message\n /// @dev There can only be one trusted source per chain\n /// @dev Allows owner to set it multiple times.\n function setTrustedRemote(uint16 _srcChainId, bytes calldata _srcAddress) external onlyGovernorOrGuardian {\n trustedRemoteLookup[_srcChainId] = _srcAddress;\n emit SetTrustedRemote(_srcChainId, _srcAddress);\n }\n\n /// @notice Fetches the default LZ config\n function getConfig(\n uint16 _version,\n uint16 _chainId,\n address,\n uint256 _configType\n ) external view returns (bytes memory) {\n return lzEndpoint.getConfig(_version, _chainId, address(this), _configType);\n }\n\n /// @notice Overrides the default LZ config\n function setConfig(\n uint16 _version,\n uint16 _chainId,\n uint256 _configType,\n bytes calldata _config\n ) external override onlyGovernorOrGuardian {\n lzEndpoint.setConfig(_version, _chainId, _configType, _config);\n }\n\n /// @notice Overrides the default LZ config\n function setSendVersion(uint16 _version) external override onlyGovernorOrGuardian {\n lzEndpoint.setSendVersion(_version);\n }\n\n /// @notice Overrides the default LZ config\n function setReceiveVersion(uint16 _version) external override onlyGovernorOrGuardian {\n lzEndpoint.setReceiveVersion(_version);\n }\n\n /// @notice Unpauses the receive functionalities\n function forceResumeReceive(\n uint16 _srcChainId,\n bytes calldata _srcAddress\n ) external override onlyGovernorOrGuardian {\n lzEndpoint.forceResumeReceive(_srcChainId, _srcAddress);\n }\n\n // ======================= View Functions ================================\n\n /// @notice Checks if the `_srcAddress` corresponds to the trusted source\n function isTrustedRemote(uint16 _srcChainId, bytes calldata _srcAddress) external view returns (bool) {\n bytes memory trustedSource = trustedRemoteLookup[_srcChainId];\n return keccak256(trustedSource) == keccak256(_srcAddress);\n }\n\n uint256[46] private __gap;\n}\n" + }, + "contracts/deprecated/layerZero/OldOFTCore.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.12;\n\nimport \"./OldNonblockingLzApp.sol\";\nimport \"../../agToken/layerZero/utils/IOFTCore.sol\";\nimport \"@openzeppelin/contracts-upgradeable/utils/introspection/ERC165Upgradeable.sol\";\n\n/// @title OFTCore\n/// @author Forked from https://github.com/LayerZero-Labs/solidity-examples/blob/main/contracts/token/oft/OFTCore.sol\n/// but with slight modifications from the Angle Labs, Inc. which added return values to the `_creditTo` and `_debitFrom` functions\n/// @notice Base contract for bridging using LayerZero\nabstract contract OldOFTCore is OldNonblockingLzApp, ERC165Upgradeable, IOFTCore {\n // ==================== External Permissionless Functions ======================\n\n /// @inheritdoc IOFTCore\n function sendWithPermit(\n uint16 _dstChainId,\n bytes memory _toAddress,\n uint256 _amount,\n address payable _refundAddress,\n address _zroPaymentAddress,\n bytes memory _adapterParams,\n uint256 deadline,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) public payable virtual;\n\n /// @inheritdoc IOFTCore\n function send(\n uint16 _dstChainId,\n bytes memory _toAddress,\n uint256 _amount,\n address payable _refundAddress,\n address _zroPaymentAddress,\n bytes memory _adapterParams\n ) public payable virtual {\n _amount = _debitFrom(_dstChainId, _toAddress, _amount);\n\n bytes memory payload = abi.encode(_toAddress, _amount);\n _lzSend(_dstChainId, payload, _refundAddress, _zroPaymentAddress, _adapterParams);\n\n uint64 nonce = lzEndpoint.getOutboundNonce(_dstChainId, address(this));\n emit SendToChain(msg.sender, _dstChainId, _toAddress, _amount, nonce);\n }\n\n /// @inheritdoc IOFTCore\n function sendCredit(\n uint16 _dstChainId,\n bytes memory _toAddress,\n uint256 _amount,\n address payable _refundAddress,\n address _zroPaymentAddress,\n bytes memory _adapterParams\n ) public payable virtual {\n _amount = _debitCreditFrom(_dstChainId, _toAddress, _amount);\n\n _send(_dstChainId, _toAddress, _amount, _refundAddress, _zroPaymentAddress, _adapterParams);\n }\n\n /// @inheritdoc IOFTCore\n function withdraw(uint256 amount, address recipient) external virtual returns (uint256);\n\n // =========================== Internal Functions ==============================\n\n /// @notice Internal function to send `_amount` amount of token to (`_dstChainId`, `_toAddress`)\n /// @param _dstChainId the destination chain identifier\n /// @param _toAddress can be any size depending on the `dstChainId`.\n /// @param _amount the quantity of tokens in wei\n /// @param _refundAddress the address LayerZero refunds if too much message fee is sent\n /// @param _zroPaymentAddress set to address(0x0) if not paying in ZRO (LayerZero Token)\n /// @param _adapterParams is a flexible bytes array to indicate messaging adapter services\n /// @dev Accounting and checks should be performed beforehand\n function _send(\n uint16 _dstChainId,\n bytes memory _toAddress,\n uint256 _amount,\n address payable _refundAddress,\n address _zroPaymentAddress,\n bytes memory _adapterParams\n ) internal {\n bytes memory payload = abi.encode(_toAddress, _amount);\n _lzSend(_dstChainId, payload, _refundAddress, _zroPaymentAddress, _adapterParams);\n\n uint64 nonce = lzEndpoint.getOutboundNonce(_dstChainId, address(this));\n emit SendToChain(msg.sender, _dstChainId, _toAddress, _amount, nonce);\n }\n\n function _nonblockingLzReceive(\n uint16 _srcChainId,\n bytes memory _srcAddress,\n uint64 _nonce,\n bytes memory _payload\n ) internal virtual override {\n // decode and load the toAddress\n (bytes memory toAddressBytes, uint256 amount) = abi.decode(_payload, (bytes, uint256));\n address toAddress;\n //solhint-disable-next-line\n assembly {\n toAddress := mload(add(toAddressBytes, 20))\n }\n amount = _creditTo(_srcChainId, toAddress, amount);\n\n emit ReceiveFromChain(_srcChainId, _srcAddress, toAddress, amount, _nonce);\n }\n\n /// @notice Makes accountability when bridging from this contract using canonical token\n /// @param _dstChainId ChainId of the destination chain - LayerZero standard\n /// @param _toAddress Recipient on the destination chain\n /// @param _amount Amount to bridge\n function _debitFrom(\n uint16 _dstChainId,\n bytes memory _toAddress,\n uint256 _amount\n ) internal virtual returns (uint256);\n\n /// @notice Makes accountability when bridging from this contract's credit\n /// @param _dstChainId ChainId of the destination chain - LayerZero standard\n /// @param _toAddress Recipient on the destination chain\n /// @param _amount Amount to bridge\n function _debitCreditFrom(\n uint16 _dstChainId,\n bytes memory _toAddress,\n uint256 _amount\n ) internal virtual returns (uint256);\n\n /// @notice Makes accountability when bridging to this contract\n /// @param _srcChainId ChainId of the source chain - LayerZero standard\n /// @param _toAddress Recipient on this chain\n /// @param _amount Amount to bridge\n function _creditTo(uint16 _srcChainId, address _toAddress, uint256 _amount) internal virtual returns (uint256);\n\n // ========================== View Functions ===================================\n\n /// @inheritdoc ERC165Upgradeable\n function supportsInterface(\n bytes4 interfaceId\n ) public view virtual override(ERC165Upgradeable, IERC165) returns (bool) {\n return interfaceId == type(IOFTCore).interfaceId || super.supportsInterface(interfaceId);\n }\n\n /// @inheritdoc IOFTCore\n function estimateSendFee(\n uint16 _dstChainId,\n bytes memory _toAddress,\n uint256 _amount,\n bool _useZro,\n bytes memory _adapterParams\n ) public view virtual override returns (uint256 nativeFee, uint256 zroFee) {\n // mock the payload for send()\n bytes memory payload = abi.encode(_toAddress, _amount);\n return lzEndpoint.estimateFees(_dstChainId, address(this), payload, _useZro, _adapterParams);\n }\n\n uint256[50] private __gap;\n}\n" + }, + "contracts/deprecated/OldAgEUR.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\nimport \"../interfaces/IAgToken.sol\";\nimport \"../interfaces/coreModule/IStableMaster.sol\";\nimport \"../interfaces/ITreasury.sol\";\n// OpenZeppelin may update its version of the ERC20PermitUpgradeable token\nimport \"@openzeppelin/contracts-upgradeable/token/ERC20/extensions/draft-ERC20PermitUpgradeable.sol\";\n\n/// @title AgToken\n/// @author Angle Labs, Inc.\n/// @notice Base contract for agToken, that is to say Angle's stablecoins\n/// @dev This contract is used to create and handle the stablecoins of Angle protocol\n/// @dev It is still possible for any address to burn its agTokens without redeeming collateral in exchange\n/// @dev This contract is the upgraded version of the AgToken that was first deployed on Ethereum mainnet\ncontract OldAgEUR is IAgToken, ERC20PermitUpgradeable {\n // ========================= References to other contracts =====================\n\n /// @notice Reference to the `StableMaster` contract associated to this `AgToken`\n address public stableMaster;\n\n // ============================= Constructor ===================================\n\n /// @notice Initializes the `AgToken` contract\n /// @param name_ Name of the token\n /// @param symbol_ Symbol of the token\n /// @param stableMaster_ Reference to the `StableMaster` contract associated to this agToken\n /// @dev By default, agTokens are ERC-20 tokens with 18 decimals\n function initialize(string memory name_, string memory symbol_, address stableMaster_) external initializer {\n __ERC20Permit_init(name_);\n __ERC20_init(name_, symbol_);\n require(stableMaster_ != address(0), \"0\");\n stableMaster = stableMaster_;\n }\n\n /// @custom:oz-upgrades-unsafe-allow constructor\n constructor() initializer {}\n\n // ======= Added Parameters and Variables from the first implementation ========\n\n /// @inheritdoc IAgToken\n mapping(address => bool) public isMinter;\n /// @notice Reference to the treasury contract which can grant minting rights\n address public treasury;\n /// @notice Boolean to check whether the contract has been reinitialized after its upgrade\n bool public treasuryInitialized;\n\n // =============================== Added Events ================================\n\n event TreasuryUpdated(address indexed _treasury);\n event MinterToggled(address indexed minter);\n\n // =============================== Added Errors ================================\n\n error BurnAmountExceedsAllowance();\n error InvalidSender();\n error InvalidTreasury();\n error NotGovernor();\n error NotMinter();\n error NotTreasury();\n error TreasuryAlreadyInitialized();\n\n // =============================== Setup Function ==============================\n\n /// @notice Sets up the treasury contract in this AgToken contract\n /// @param _treasury Treasury contract to add\n /// @dev The address calling this function has to be hard-coded in the contract\n /// @dev Can be called only once\n function setUpTreasury(address _treasury) external {\n // Only governor\n if (msg.sender != 0xdC4e6DFe07EFCa50a197DF15D9200883eF4Eb1c8) revert NotGovernor();\n if (address(ITreasury(_treasury).stablecoin()) != address(this)) revert InvalidTreasury();\n if (treasuryInitialized) revert TreasuryAlreadyInitialized();\n treasury = _treasury;\n treasuryInitialized = true;\n isMinter[stableMaster] = true;\n emit TreasuryUpdated(_treasury);\n }\n\n // =============================== Modifiers ===================================\n\n /// @notice Checks to see if it is the `Treasury` calling this contract\n /// @dev There is no Access Control here, because it can be handled cheaply through this modifier\n modifier onlyTreasury() {\n if (msg.sender != treasury) revert NotTreasury();\n _;\n }\n\n /// @notice Checks whether the sender has the minting right\n modifier onlyMinter() {\n if (!isMinter[msg.sender]) revert NotMinter();\n _;\n }\n\n // ========================= External Functions ================================\n // The following functions allow anyone to burn stablecoins without redeeming collateral\n // in exchange for that\n\n /// @notice Destroys `amount` token from the caller without giving collateral back\n /// @param amount Amount to burn\n /// @param poolManager Reference to the `PoolManager` contract for which the `stocksUsers` will\n /// need to be updated\n /// @dev When calling this function, people should specify the `poolManager` for which they want to decrease\n /// the `stocksUsers`: this is a way for the protocol to maintain healthy accounting variables\n function burnNoRedeem(uint256 amount, address poolManager) external {\n _burn(msg.sender, amount);\n IStableMaster(stableMaster).updateStocksUsers(amount, poolManager);\n }\n\n /// @notice Burns `amount` of agToken on behalf of another account without redeeming collateral back\n /// @param account Account to burn on behalf of\n /// @param amount Amount to burn\n /// @param poolManager Reference to the `PoolManager` contract for which the `stocksUsers` will need to be updated\n function burnFromNoRedeem(address account, uint256 amount, address poolManager) external {\n _burnFromNoRedeem(amount, account, msg.sender);\n IStableMaster(stableMaster).updateStocksUsers(amount, poolManager);\n }\n\n /// @notice Allows anyone to burn agToken without redeeming collateral back\n /// @param amount Amount of stablecoins to burn\n /// @dev This function can typically be called if there is a settlement mechanism to burn stablecoins\n function burnStablecoin(uint256 amount) external {\n _burn(msg.sender, amount);\n }\n\n // ======================= Minter Role Only Functions ==========================\n\n /// @inheritdoc IAgToken\n function burnSelf(uint256 amount, address burner) external onlyMinter {\n _burn(burner, amount);\n }\n\n /// @inheritdoc IAgToken\n function burnFrom(uint256 amount, address burner, address sender) external onlyMinter {\n _burnFromNoRedeem(amount, burner, sender);\n }\n\n /// @inheritdoc IAgToken\n function mint(address account, uint256 amount) external onlyMinter {\n _mint(account, amount);\n }\n\n // ======================= Treasury Only Functions =============================\n\n /// @inheritdoc IAgToken\n function addMinter(address minter) external onlyTreasury {\n isMinter[minter] = true;\n emit MinterToggled(minter);\n }\n\n /// @inheritdoc IAgToken\n function removeMinter(address minter) external {\n // The `treasury` contract cannot remove the `stableMaster`\n if (msg.sender != minter && (msg.sender != address(treasury) || minter == stableMaster)) revert InvalidSender();\n isMinter[minter] = false;\n emit MinterToggled(minter);\n }\n\n /// @inheritdoc IAgToken\n function setTreasury(address _treasury) external onlyTreasury {\n treasury = _treasury;\n emit TreasuryUpdated(_treasury);\n }\n\n // ============================ Internal Function ==============================\n\n /// @notice Internal version of the function `burnFromNoRedeem`\n /// @param amount Amount to burn\n /// @dev It is at the level of this function that allowance checks are performed\n function _burnFromNoRedeem(uint256 amount, address burner, address sender) internal {\n if (burner != sender) {\n uint256 currentAllowance = allowance(burner, sender);\n if (currentAllowance < amount) revert BurnAmountExceedsAllowance();\n _approve(burner, sender, currentAllowance - amount);\n }\n _burn(burner, amount);\n }\n}\n" + }, + "contracts/deprecated/OldAngleHelpers.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\nimport \"../interfaces/IAngleRouter.sol\";\nimport \"../interfaces/coreModule/IAgTokenMainnet.sol\";\nimport \"../interfaces/coreModule/ICore.sol\";\nimport \"../interfaces/coreModule/IOracleCore.sol\";\nimport \"../interfaces/coreModule/IPerpetualManager.sol\";\nimport \"../interfaces/coreModule/IPoolManager.sol\";\nimport \"../interfaces/coreModule/IStableMaster.sol\";\nimport \"@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol\";\nimport \"../interfaces/IVaultManager.sol\";\n\npragma solidity ^0.8.12;\n\nstruct Parameters {\n SLPData slpData;\n MintBurnData feeData;\n PerpetualManagerFeeData perpFeeData;\n PerpetualManagerParamData perpParam;\n}\n\nstruct PerpetualManagerFeeData {\n uint64[] xHAFeesDeposit;\n uint64[] yHAFeesDeposit;\n uint64[] xHAFeesWithdraw;\n uint64[] yHAFeesWithdraw;\n uint64 haBonusMalusDeposit;\n uint64 haBonusMalusWithdraw;\n}\n\nstruct PerpetualManagerParamData {\n uint64 maintenanceMargin;\n uint64 maxLeverage;\n uint64 targetHAHedge;\n uint64 limitHAHedge;\n uint64 lockTime;\n}\n\nstruct CollateralAddresses {\n address stableMaster;\n address poolManager;\n address perpetualManager;\n address sanToken;\n address oracle;\n address gauge;\n address feeManager;\n address[] strategies;\n}\n\n/// @title AngleHelpers\n/// @author Angle Labs, Inc.\n/// @notice Contract with view functions designed to facilitate integrations on the Core module of the Angle Protocol\n/// @dev This contract only contains view functions to be queried off-chain. It was thus not optimized for gas consumption\ncontract OldAngleHelpers is Initializable {\n // ======================== Helper View Functions ==============================\n\n /// @notice Gives the amount of `agToken` you'd be getting if you were executing in the same block a mint transaction\n /// with `amount` of `collateral` in the Core module of the Angle protocol as well as the value of the fees\n /// (in `BASE_PARAMS`) that would be applied during the mint\n /// @return Amount of `agToken` that would be obtained with a mint transaction in the same block\n /// @return Percentage of fees that would be taken during a mint transaction in the same block\n /// @dev This function reverts if the mint transaction was to revert in the same conditions (without taking into account\n /// potential approval problems to the `StableMaster` contract)\n function previewMintAndFees(\n uint256 amount,\n address agToken,\n address collateral\n ) external view returns (uint256, uint256) {\n return _previewMintAndFees(amount, agToken, collateral);\n }\n\n /// @notice Gives the amount of `collateral` you'd be getting if you were executing in the same block a burn transaction\n /// with `amount` of `agToken` in the Core module of the Angle protocol as well as the value of the fees\n /// (in `BASE_PARAMS`) that would be applied during the burn\n /// @return Amount of `collateral` that would be obtained with a burn transaction in the same block\n /// @return Percentage of fees that would be taken during a burn transaction in the same block\n /// @dev This function reverts if the burn transaction was to revert in the same conditions (without taking into account\n /// potential approval problems to the `StableMaster` contract or agToken balance prior to the call)\n function previewBurnAndFees(\n uint256 amount,\n address agToken,\n address collateral\n ) external view returns (uint256, uint256) {\n return _previewBurnAndFees(amount, agToken, collateral);\n }\n\n /// @notice Returns all the addresses associated to the (`agToken`,`collateral`) pair given\n /// @return addresses A struct with all the addresses associated in the Core module\n function getCollateralAddresses(\n address agToken,\n address collateral\n ) external view returns (CollateralAddresses memory addresses) {\n address stableMaster = IAgTokenMainnet(agToken).stableMaster();\n (address poolManager, address perpetualManager, address sanToken, address gauge) = ROUTER.mapPoolManagers(\n stableMaster,\n collateral\n );\n (, , , IOracleCore oracle, , , , , ) = IStableMaster(stableMaster).collateralMap(poolManager);\n addresses.stableMaster = stableMaster;\n addresses.poolManager = poolManager;\n addresses.perpetualManager = perpetualManager;\n addresses.sanToken = sanToken;\n addresses.gauge = gauge;\n addresses.oracle = address(oracle);\n addresses.feeManager = IPoolManager(poolManager).feeManager();\n\n uint256 length = 0;\n while (true) {\n try IPoolManager(poolManager).strategyList(length) returns (address) {\n length += 1;\n } catch {\n break;\n }\n }\n address[] memory strategies = new address[](length);\n for (uint256 i; i < length; ++i) {\n strategies[i] = IPoolManager(poolManager).strategyList(i);\n }\n addresses.strategies = strategies;\n }\n\n /// @notice Gets the addresses of all the `StableMaster` contracts and their associated `AgToken` addresses\n /// @return List of the `StableMaster` addresses of the Angle protocol\n /// @return List of the `AgToken` addresses of the protocol\n /// @dev The place of an agToken address in the list is the same as the corresponding `StableMaster` address\n function getStablecoinAddresses() external view returns (address[] memory, address[] memory) {\n address[] memory stableMasterAddresses = CORE.stablecoinList();\n address[] memory agTokenAddresses = new address[](stableMasterAddresses.length);\n for (uint256 i; i < stableMasterAddresses.length; ++i) {\n agTokenAddresses[i] = IStableMaster(stableMasterAddresses[i]).agToken();\n }\n return (stableMasterAddresses, agTokenAddresses);\n }\n\n /// @notice Returns most of the governance parameters associated to the (`agToken`,`collateral`) pair given\n /// @return params Struct with most of the parameters in the `StableMaster` and `PerpetualManager` contracts\n /// @dev Check out the struct `Parameters` for the meaning of the return values\n function getCollateralParameters(\n address agToken,\n address collateral\n ) external view returns (Parameters memory params) {\n (address stableMaster, address poolManager) = _getStableMasterAndPoolManager(agToken, collateral);\n (\n ,\n ,\n IPerpetualManager perpetualManager,\n ,\n ,\n ,\n ,\n SLPData memory slpData,\n MintBurnData memory feeData\n ) = IStableMaster(stableMaster).collateralMap(poolManager);\n\n params.slpData = slpData;\n params.feeData = feeData;\n params.perpParam.maintenanceMargin = perpetualManager.maintenanceMargin();\n params.perpParam.maxLeverage = perpetualManager.maxLeverage();\n params.perpParam.targetHAHedge = perpetualManager.targetHAHedge();\n params.perpParam.limitHAHedge = perpetualManager.limitHAHedge();\n params.perpParam.lockTime = perpetualManager.lockTime();\n\n params.perpFeeData.haBonusMalusDeposit = perpetualManager.haBonusMalusDeposit();\n params.perpFeeData.haBonusMalusWithdraw = perpetualManager.haBonusMalusWithdraw();\n\n uint256 length = 0;\n while (true) {\n try perpetualManager.xHAFeesDeposit(length) returns (uint64) {\n length += 1;\n } catch {\n break;\n }\n }\n uint64[] memory data = new uint64[](length);\n uint64[] memory data2 = new uint64[](length);\n for (uint256 i; i < length; ++i) {\n data[i] = perpetualManager.xHAFeesDeposit(i);\n data2[i] = perpetualManager.yHAFeesDeposit(i);\n }\n params.perpFeeData.xHAFeesDeposit = data;\n params.perpFeeData.yHAFeesDeposit = data2;\n\n length = 0;\n while (true) {\n try perpetualManager.xHAFeesWithdraw(length) returns (uint64) {\n length += 1;\n } catch {\n break;\n }\n }\n data = new uint64[](length);\n data2 = new uint64[](length);\n for (uint256 i; i < length; ++i) {\n data[i] = perpetualManager.xHAFeesWithdraw(i);\n data2[i] = perpetualManager.yHAFeesWithdraw(i);\n }\n params.perpFeeData.xHAFeesWithdraw = data;\n params.perpFeeData.yHAFeesWithdraw = data2;\n }\n\n /// @notice Returns the address of the poolManager associated to an (`agToken`, `collateral`) pair\n /// in the Core module of the protocol\n function getPoolManager(address agToken, address collateral) public view returns (address poolManager) {\n (, poolManager) = _getStableMasterAndPoolManager(agToken, collateral);\n }\n\n // ======================== Replica Functions ==================================\n // These replicate what is done in the other contracts of the protocol\n\n function _previewBurnAndFees(\n uint256 amount,\n address agToken,\n address collateral\n ) internal view returns (uint256 amountForUserInCollat, uint256 feePercent) {\n (address stableMaster, address poolManager) = _getStableMasterAndPoolManager(agToken, collateral);\n (\n address token,\n ,\n IPerpetualManager perpetualManager,\n IOracleCore oracle,\n uint256 stocksUsers,\n ,\n uint256 collatBase,\n ,\n MintBurnData memory feeData\n ) = IStableMaster(stableMaster).collateralMap(poolManager);\n if (token == address(0) || IStableMaster(stableMaster).paused(keccak256(abi.encodePacked(STABLE, poolManager))))\n revert NotInitialized();\n if (amount > stocksUsers) revert InvalidAmount();\n\n if (feeData.xFeeBurn.length == 1) {\n feePercent = feeData.yFeeBurn[0];\n } else {\n bytes memory data = abi.encode(address(perpetualManager), feeData.targetHAHedge);\n uint64 hedgeRatio = _computeHedgeRatio(stocksUsers - amount, data);\n feePercent = _piecewiseLinear(hedgeRatio, feeData.xFeeBurn, feeData.yFeeBurn);\n }\n feePercent = (feePercent * feeData.bonusMalusBurn) / BASE_PARAMS;\n\n amountForUserInCollat = (amount * (BASE_PARAMS - feePercent) * collatBase) / (oracle.readUpper() * BASE_PARAMS);\n }\n\n function _previewMintAndFees(\n uint256 amount,\n address agToken,\n address collateral\n ) internal view returns (uint256 amountForUserInStable, uint256 feePercent) {\n (address stableMaster, address poolManager) = _getStableMasterAndPoolManager(agToken, collateral);\n (\n address token,\n ,\n IPerpetualManager perpetualManager,\n IOracleCore oracle,\n uint256 stocksUsers,\n ,\n ,\n ,\n MintBurnData memory feeData\n ) = IStableMaster(stableMaster).collateralMap(poolManager);\n if (token == address(0) || IStableMaster(stableMaster).paused(keccak256(abi.encodePacked(STABLE, poolManager))))\n revert NotInitialized();\n\n amountForUserInStable = oracle.readQuoteLower(amount);\n\n if (feeData.xFeeMint.length == 1) feePercent = feeData.yFeeMint[0];\n else {\n bytes memory data = abi.encode(address(perpetualManager), feeData.targetHAHedge);\n uint64 hedgeRatio = _computeHedgeRatio(amountForUserInStable + stocksUsers, data);\n feePercent = _piecewiseLinear(hedgeRatio, feeData.xFeeMint, feeData.yFeeMint);\n }\n feePercent = (feePercent * feeData.bonusMalusMint) / BASE_PARAMS;\n\n amountForUserInStable = (amountForUserInStable * (BASE_PARAMS - feePercent)) / BASE_PARAMS;\n if (stocksUsers + amountForUserInStable > feeData.capOnStableMinted) revert InvalidAmount();\n }\n\n // ======================== Utility Functions ==================================\n // These utility functions are taken from other contracts of the protocol\n\n function _computeHedgeRatio(uint256 newStocksUsers, bytes memory data) internal view returns (uint64 ratio) {\n (address perpetualManager, uint64 targetHAHedge) = abi.decode(data, (address, uint64));\n uint256 totalHedgeAmount = IPerpetualManager(perpetualManager).totalHedgeAmount();\n newStocksUsers = (targetHAHedge * newStocksUsers) / BASE_PARAMS;\n if (newStocksUsers > totalHedgeAmount) ratio = uint64((totalHedgeAmount * BASE_PARAMS) / newStocksUsers);\n else ratio = uint64(BASE_PARAMS);\n }\n\n function _piecewiseLinear(uint64 x, uint64[] memory xArray, uint64[] memory yArray) internal pure returns (uint64) {\n if (x >= xArray[xArray.length - 1]) {\n return yArray[xArray.length - 1];\n } else if (x <= xArray[0]) {\n return yArray[0];\n } else {\n uint256 lower;\n uint256 upper = xArray.length - 1;\n uint256 mid;\n while (upper - lower > 1) {\n mid = lower + (upper - lower) / 2;\n if (xArray[mid] <= x) {\n lower = mid;\n } else {\n upper = mid;\n }\n }\n if (yArray[upper] > yArray[lower]) {\n return\n yArray[lower] +\n ((yArray[upper] - yArray[lower]) * (x - xArray[lower])) /\n (xArray[upper] - xArray[lower]);\n } else {\n return\n yArray[lower] -\n ((yArray[lower] - yArray[upper]) * (x - xArray[lower])) /\n (xArray[upper] - xArray[lower]);\n }\n }\n }\n\n function _getStableMasterAndPoolManager(\n address agToken,\n address collateral\n ) internal view returns (address stableMaster, address poolManager) {\n stableMaster = IAgTokenMainnet(agToken).stableMaster();\n (poolManager, , , ) = ROUTER.mapPoolManagers(stableMaster, collateral);\n }\n\n // ====================== Constants and Initializers ===========================\n\n IAngleRouter public constant ROUTER = IAngleRouter(0xBB755240596530be0c1DE5DFD77ec6398471561d);\n ICore public constant CORE = ICore(0x61ed74de9Ca5796cF2F8fD60D54160D47E30B7c3);\n\n bytes32 public constant STABLE = keccak256(\"STABLE\");\n uint256 public constant BASE_PARAMS = 10 ** 9;\n\n error NotInitialized();\n error InvalidAmount();\n\n /// @custom:oz-upgrades-unsafe-allow constructor\n constructor() initializer {}\n}\n" + }, + "contracts/deprecated/vaultManager/OldVaultManagerERC721.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\nimport \"./OldVaultManagerStorage.sol\";\n\n/// @title VaultManagerERC721\n/// @author Angle Labs, Inc.\n/// @dev Base ERC721 Implementation of VaultManager\nabstract contract OldVaultManagerERC721 is IERC721MetadataUpgradeable, OldVaultManagerStorage {\n using SafeERC20 for IERC20;\n using Address for address;\n\n /// @inheritdoc IERC721MetadataUpgradeable\n string public name;\n /// @inheritdoc IERC721MetadataUpgradeable\n string public symbol;\n\n // ================================= MODIFIERS =================================\n\n /// @notice Checks if the person interacting with the vault with `vaultID` is approved\n /// @param caller Address of the person seeking to interact with the vault\n /// @param vaultID ID of the concerned vault\n modifier onlyApprovedOrOwner(address caller, uint256 vaultID) {\n if (!_isApprovedOrOwner(caller, vaultID)) revert NotApproved();\n _;\n }\n\n // ================================ ERC721 LOGIC ===============================\n\n /// @notice Checks whether a given address is approved for a vault or owns this vault\n /// @param spender Address for which vault ownership should be checked\n /// @param vaultID ID of the vault to check\n /// @return Whether the `spender` address owns or is approved for `vaultID`\n function isApprovedOrOwner(address spender, uint256 vaultID) external view returns (bool) {\n return _isApprovedOrOwner(spender, vaultID);\n }\n\n /// @inheritdoc IERC721MetadataUpgradeable\n function tokenURI(uint256 vaultID) external view returns (string memory) {\n if (!_exists(vaultID)) revert NonexistentVault();\n // There is no vault with `vaultID` equal to 0, so the following variable is\n // always greater than zero\n uint256 temp = vaultID;\n uint256 digits;\n while (temp != 0) {\n digits++;\n temp /= 10;\n }\n bytes memory buffer = new bytes(digits);\n while (vaultID != 0) {\n digits -= 1;\n buffer[digits] = bytes1(uint8(48 + uint256(vaultID % 10)));\n vaultID /= 10;\n }\n return bytes(_baseURI).length > 0 ? string(abi.encodePacked(_baseURI, string(buffer))) : \"\";\n }\n\n /// @inheritdoc IERC721Upgradeable\n function balanceOf(address owner) external view returns (uint256) {\n if (owner == address(0)) revert ZeroAddress();\n return _balances[owner];\n }\n\n /// @inheritdoc IERC721Upgradeable\n function ownerOf(uint256 vaultID) external view returns (address) {\n return _ownerOf(vaultID);\n }\n\n /// @inheritdoc IERC721Upgradeable\n function approve(address to, uint256 vaultID) external {\n address owner = _ownerOf(vaultID);\n if (to == owner) revert ApprovalToOwner();\n if (msg.sender != owner && !isApprovedForAll(owner, msg.sender)) revert NotApproved();\n\n _approve(to, vaultID);\n }\n\n /// @inheritdoc IERC721Upgradeable\n function getApproved(uint256 vaultID) external view returns (address) {\n if (!_exists(vaultID)) revert NonexistentVault();\n return _getApproved(vaultID);\n }\n\n /// @inheritdoc IERC721Upgradeable\n function setApprovalForAll(address operator, bool approved) external {\n _setApprovalForAll(msg.sender, operator, approved);\n }\n\n /// @inheritdoc IERC721Upgradeable\n function isApprovedForAll(address owner, address operator) public view returns (bool) {\n return _operatorApprovals[owner][operator] == 1;\n }\n\n /// @inheritdoc IERC721Upgradeable\n function transferFrom(address from, address to, uint256 vaultID) external onlyApprovedOrOwner(msg.sender, vaultID) {\n _transfer(from, to, vaultID);\n }\n\n /// @inheritdoc IERC721Upgradeable\n function safeTransferFrom(address from, address to, uint256 vaultID) external {\n safeTransferFrom(from, to, vaultID, \"\");\n }\n\n /// @inheritdoc IERC721Upgradeable\n function safeTransferFrom(\n address from,\n address to,\n uint256 vaultID,\n bytes memory _data\n ) public onlyApprovedOrOwner(msg.sender, vaultID) {\n _safeTransfer(from, to, vaultID, _data);\n }\n\n // ================================ ERC165 LOGIC ===============================\n\n /// @inheritdoc IERC165Upgradeable\n function supportsInterface(bytes4 interfaceId) external pure returns (bool) {\n return\n interfaceId == type(IERC721MetadataUpgradeable).interfaceId ||\n interfaceId == type(IERC721Upgradeable).interfaceId ||\n interfaceId == type(IVaultManager).interfaceId ||\n interfaceId == type(IERC165Upgradeable).interfaceId;\n }\n\n // ================== INTERNAL FUNCTIONS FOR THE ERC721 LOGIC ==================\n\n /// @notice Internal version of the `ownerOf` function\n function _ownerOf(uint256 vaultID) internal view returns (address owner) {\n owner = _owners[vaultID];\n if (owner == address(0)) revert NonexistentVault();\n }\n\n /// @notice Internal version of the `getApproved` function\n function _getApproved(uint256 vaultID) internal view returns (address) {\n return _vaultApprovals[vaultID];\n }\n\n /// @notice Internal version of the `safeTransferFrom` function (with the data parameter)\n function _safeTransfer(address from, address to, uint256 vaultID, bytes memory _data) internal {\n _transfer(from, to, vaultID);\n if (!_checkOnERC721Received(from, to, vaultID, _data)) revert NonERC721Receiver();\n }\n\n /// @notice Checks whether a vault exists\n /// @param vaultID ID of the vault to check\n /// @return Whether `vaultID` has been created\n function _exists(uint256 vaultID) internal view returns (bool) {\n return _owners[vaultID] != address(0);\n }\n\n /// @notice Internal version of the `isApprovedOrOwner` function\n function _isApprovedOrOwner(address spender, uint256 vaultID) internal view returns (bool) {\n // The following checks if the vault exists\n address owner = _ownerOf(vaultID);\n return (spender == owner || _getApproved(vaultID) == spender || _operatorApprovals[owner][spender] == 1);\n }\n\n /// @notice Internal version of the `createVault` function\n /// Mints `vaultID` and transfers it to `to`\n /// @dev This method is equivalent to the `_safeMint` method used in OpenZeppelin ERC721 contract\n /// @dev Emits a {Transfer} event\n function _mint(address to) internal returns (uint256 vaultID) {\n if (whitelistingActivated && (isWhitelisted[to] != 1 || isWhitelisted[msg.sender] != 1))\n revert NotWhitelisted();\n if (to == address(0)) revert ZeroAddress();\n\n unchecked {\n vaultIDCount += 1;\n }\n\n vaultID = vaultIDCount;\n _beforeTokenTransfer(address(0), to, vaultID);\n\n unchecked {\n _balances[to] += 1;\n }\n\n _owners[vaultID] = to;\n emit Transfer(address(0), to, vaultID);\n if (!_checkOnERC721Received(address(0), to, vaultID, \"\")) revert NonERC721Receiver();\n }\n\n /// @notice Destroys `vaultID`\n /// @dev `vaultID` must exist\n /// @dev Emits a {Transfer} event\n function _burn(uint256 vaultID) internal {\n address owner = _ownerOf(vaultID);\n\n _beforeTokenTransfer(owner, address(0), vaultID);\n // Clear approvals\n _approve(address(0), vaultID);\n // The following line cannot underflow as the owner's balance is necessarily\n // greater than 1\n unchecked {\n _balances[owner] -= 1;\n }\n delete _owners[vaultID];\n delete vaultData[vaultID];\n\n emit Transfer(owner, address(0), vaultID);\n }\n\n /// @notice Transfers `vaultID` from `from` to `to` as opposed to {transferFrom},\n /// this imposes no restrictions on msg.sender\n /// @dev `to` cannot be the zero address and `perpetualID` must be owned by `from`\n /// @dev Emits a {Transfer} event\n /// @dev A whitelist check is performed if necessary on the `to` address\n function _transfer(address from, address to, uint256 vaultID) internal {\n if (_ownerOf(vaultID) != from) revert NotApproved();\n if (to == address(0)) revert ZeroAddress();\n if (whitelistingActivated && isWhitelisted[to] != 1) revert NotWhitelisted();\n\n _beforeTokenTransfer(from, to, vaultID);\n\n // Clear approvals from the previous owner\n _approve(address(0), vaultID);\n unchecked {\n _balances[from] -= 1;\n _balances[to] += 1;\n }\n _owners[vaultID] = to;\n\n emit Transfer(from, to, vaultID);\n }\n\n /// @notice Approves `to` to operate on `vaultID`\n function _approve(address to, uint256 vaultID) internal {\n _vaultApprovals[vaultID] = to;\n emit Approval(_ownerOf(vaultID), to, vaultID);\n }\n\n /// @notice Internal version of the `setApprovalForAll` function\n /// @dev It contains an `approver` field to be used in case someone signs a permit for a particular\n /// address, and this signature is given to the contract by another address (like a router)\n function _setApprovalForAll(address approver, address operator, bool approved) internal {\n if (operator == approver) revert ApprovalToCaller();\n uint256 approval = approved ? 1 : 0;\n _operatorApprovals[approver][operator] = approval;\n emit ApprovalForAll(approver, operator, approved);\n }\n\n /// @notice Internal function to invoke {IERC721Receiver-onERC721Received} on a target address\n /// The call is not executed if the target address is not a contract\n /// @param from Address representing the previous owner of the given token ID\n /// @param to Target address that will receive the tokens\n /// @param vaultID ID of the token to be transferred\n /// @param _data Bytes optional data to send along with the call\n /// @return Bool whether the call correctly returned the expected value\n function _checkOnERC721Received(\n address from,\n address to,\n uint256 vaultID,\n bytes memory _data\n ) private returns (bool) {\n if (to.isContract()) {\n try IERC721ReceiverUpgradeable(to).onERC721Received(msg.sender, from, vaultID, _data) returns (\n bytes4 retval\n ) {\n return retval == IERC721ReceiverUpgradeable.onERC721Received.selector;\n } catch (bytes memory reason) {\n if (reason.length == 0) {\n revert NonERC721Receiver();\n } else {\n // solhint-disable-next-line no-inline-assembly\n assembly {\n revert(add(32, reason), mload(reason))\n }\n }\n }\n } else {\n return true;\n }\n }\n\n /// @notice Hook that is called before any token transfer. This includes minting and burning.\n /// Calling conditions:\n ///\n /// - When `from` and `to` are both non-zero, `from`'s `vaultID` will be\n /// transferred to `to`.\n /// - When `from` is zero, `vaultID` will be minted for `to`.\n /// - When `to` is zero, `from`'s `vaultID` will be burned.\n /// - `from` and `to` are never both zero.\n function _beforeTokenTransfer(address from, address to, uint256 vaultID) internal virtual {}\n}\n" + }, + "contracts/deprecated/vaultManager/OldVaultManagerPermit.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\nimport \"./OldVaultManagerERC721.sol\";\nimport \"../../interfaces/external/IERC1271.sol\";\n\n/// @title VaultManagerPermit\n/// @author Angle Labs, Inc.\n/// @dev Base Implementation of permit functions for the `VaultManager` contract\nabstract contract OldVaultManagerPermit is Initializable, OldVaultManagerERC721 {\n using Address for address;\n\n mapping(address => uint256) private _nonces;\n /* solhint-disable var-name-mixedcase */\n bytes32 private _HASHED_NAME;\n bytes32 private _HASHED_VERSION;\n bytes32 private _PERMIT_TYPEHASH;\n /* solhint-enable var-name-mixedcase */\n\n error ExpiredDeadline();\n error InvalidSignature();\n\n //solhint-disable-next-line\n function __ERC721Permit_init(string memory _name) internal onlyInitializing {\n _PERMIT_TYPEHASH = keccak256(\n \"Permit(address owner,address spender,bool approved,uint256 nonce,uint256 deadline)\"\n );\n _HASHED_NAME = keccak256(bytes(_name));\n _HASHED_VERSION = keccak256(bytes(\"1\"));\n }\n\n /// @notice Allows an address to give or revoke approval for all its vaults to another address\n /// @param owner Address signing the permit and giving (or revoking) its approval for all the controlled vaults\n /// @param spender Address to give approval to\n /// @param approved Whether to give or revoke the approval\n /// @param deadline Deadline parameter for the signature to be valid\n /// @dev The `v`, `r`, and `s` parameters are used as signature data\n function permit(\n address owner,\n address spender,\n bool approved,\n uint256 deadline,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) external {\n if (block.timestamp > deadline) revert ExpiredDeadline();\n // Additional signature checks performed in the `ECDSAUpgradeable.recover` function\n if (uint256(s) > 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D576E7357A4501DDFE92F46681B20A0 || (v != 27 && v != 28))\n revert InvalidSignature();\n\n bytes32 digest = keccak256(\n abi.encodePacked(\n \"\\x19\\x01\",\n _domainSeparatorV4(),\n keccak256(\n abi.encode(\n _PERMIT_TYPEHASH,\n // 0x3f43a9c6bafb5c7aab4e0cfe239dc5d4c15caf0381c6104188191f78a6640bd8,\n owner,\n spender,\n approved,\n _useNonce(owner),\n deadline\n )\n )\n )\n );\n if (owner.isContract()) {\n if (IERC1271(owner).isValidSignature(digest, abi.encodePacked(r, s, v)) != 0x1626ba7e)\n revert InvalidSignature();\n } else {\n address signer = ecrecover(digest, v, r, s);\n if (signer != owner || signer == address(0)) revert InvalidSignature();\n }\n\n _setApprovalForAll(owner, spender, approved);\n }\n\n /// @notice Returns the current nonce for an `owner` address\n function nonces(address owner) public view returns (uint256) {\n return _nonces[owner];\n }\n\n /// @notice Returns the domain separator for the current chain.\n // solhint-disable-next-line func-name-mixedcase\n function DOMAIN_SEPARATOR() external view returns (bytes32) {\n return _domainSeparatorV4();\n }\n\n /// @notice Internal version of the `DOMAIN_SEPARATOR` function\n function _domainSeparatorV4() internal view returns (bytes32) {\n return\n keccak256(\n abi.encode(\n // keccak256('EIP712Domain(string name,string version,uint256 chainId,address verifyingContract)')\n 0x8b73c3c69bb8fe3d512ecc4cf759cc79239f7b179b0ffacaa9a75d522b39400f,\n _HASHED_NAME,\n _HASHED_VERSION,\n block.chainid,\n address(this)\n )\n );\n }\n\n /// @notice Consumes a nonce for an address: returns the current value and increments it\n function _useNonce(address owner) internal returns (uint256 current) {\n current = _nonces[owner];\n _nonces[owner] = current + 1;\n }\n\n uint256[49] private __gap;\n}\n" + }, + "contracts/deprecated/vaultManager/OldVaultManagerStorage.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\nimport \"@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/token/ERC20/extensions/draft-IERC20PermitUpgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/token/ERC721/IERC721ReceiverUpgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/interfaces/IERC721MetadataUpgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/utils/introspection/IERC165Upgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/utils/AddressUpgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/security/ReentrancyGuardUpgradeable.sol\";\nimport \"@openzeppelin/contracts/token/ERC20/extensions/IERC20Metadata.sol\";\nimport \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\nimport \"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\";\n\nimport \"../../interfaces/IAgToken.sol\";\nimport \"../../interfaces/IOracle.sol\";\nimport \"../../interfaces/ISwapper.sol\";\nimport \"../../interfaces/ITreasury.sol\";\nimport \"../../interfaces/IVaultManager.sol\";\nimport \"../../interfaces/governance/IVeBoostProxy.sol\";\n\n/// @title VaultManagerStorage\n/// @author Angle Labs, Inc.\n/// @dev Variables, references, parameters and events needed in the `VaultManager` contract\n// solhint-disable-next-line max-states-count\ncontract OldVaultManagerStorage is IVaultManagerStorage, Initializable, ReentrancyGuardUpgradeable {\n /// @notice Base used for parameter computation: almost all the parameters of this contract are set in `BASE_PARAMS`\n uint256 public constant BASE_PARAMS = 10 ** 9;\n /// @notice Base used for interest rate computation\n uint256 public constant BASE_INTEREST = 10 ** 27;\n /// @notice Used for interest rate computation\n uint256 public constant HALF_BASE_INTEREST = 10 ** 27 / 2;\n\n // ================================= REFERENCES ================================\n\n /// @inheritdoc IVaultManagerStorage\n ITreasury public treasury;\n /// @inheritdoc IVaultManagerStorage\n IERC20 public collateral;\n /// @inheritdoc IVaultManagerStorage\n IAgToken public stablecoin;\n /// @inheritdoc IVaultManagerStorage\n IOracle public oracle;\n /// @notice Reference to the contract which computes adjusted veANGLE balances for liquidators boosts\n IVeBoostProxy public veBoostProxy;\n /// @notice Base of the collateral\n uint256 internal _collatBase;\n\n // ================================= PARAMETERS ================================\n // Unless specified otherwise, parameters of this contract are expressed in `BASE_PARAMS`\n\n /// @notice Maximum amount of stablecoins that can be issued with this contract (in `BASE_TOKENS`). This parameter should\n /// not be bigger than `type(uint256).max / BASE_INTEREST` otherwise there may be some overflows in the `increaseDebt` function\n uint256 public debtCeiling;\n /// @notice Threshold veANGLE balance values for the computation of the boost for liquidators: the length of this array\n /// should normally be 2. The base of the x-values in this array should be `BASE_TOKENS`\n uint256[] public xLiquidationBoost;\n /// @notice Values of the liquidation boost at the threshold values of x\n uint256[] public yLiquidationBoost;\n /// @inheritdoc IVaultManagerStorage\n uint64 public collateralFactor;\n /// @notice Maximum Health factor at which a vault can end up after a liquidation (unless it's fully liquidated)\n uint64 public targetHealthFactor;\n /// @notice Upfront fee taken when borrowing stablecoins: this fee is optional and should in practice not be used\n uint64 public borrowFee;\n /// @notice Upfront fee taken when repaying stablecoins: this fee is optional as well. It should be smaller\n /// than the liquidation surcharge (cf below) to avoid exploits where people voluntarily get liquidated at a 0\n /// discount to pay smaller repaying fees\n uint64 public repayFee;\n /// @notice Per second interest taken to borrowers taking agToken loans. Contrarily to other parameters, it is set in `BASE_INTEREST`\n /// that is to say in base 10**27\n uint64 public interestRate;\n /// @notice Fee taken by the protocol during a liquidation. Technically, this value is not the fee per se, it's 1 - fee.\n /// For instance for a 2% fee, `liquidationSurcharge` should be 98%\n uint64 public liquidationSurcharge;\n /// @notice Maximum discount given to liquidators\n uint64 public maxLiquidationDiscount;\n /// @notice Whether whitelisting is required to own a vault or not\n bool public whitelistingActivated;\n /// @notice Whether the contract is paused or not\n bool public paused;\n\n // ================================= VARIABLES =================================\n\n /// @notice Timestamp at which the `interestAccumulator` was updated\n uint256 public lastInterestAccumulatorUpdated;\n /// @inheritdoc IVaultManagerStorage\n uint256 public interestAccumulator;\n /// @inheritdoc IVaultManagerStorage\n uint256 public totalNormalizedDebt;\n /// @notice Surplus accumulated by the contract: surplus is always in stablecoins, and is then reset\n /// when the value is communicated to the treasury contract\n uint256 public surplus;\n /// @notice Bad debt made from liquidated vaults which ended up having no collateral and a positive amount\n /// of stablecoins\n uint256 public badDebt;\n\n // ================================== MAPPINGS =================================\n\n /// @inheritdoc IVaultManagerStorage\n mapping(uint256 => Vault) public vaultData;\n /// @notice Maps an address to 1 if it's whitelisted and can open or own a vault\n mapping(address => uint256) public isWhitelisted;\n\n // ================================ ERC721 DATA ================================\n\n /// @inheritdoc IVaultManagerStorage\n uint256 public vaultIDCount;\n\n /// @notice URI\n string internal _baseURI;\n\n // Mapping from `vaultID` to owner address\n mapping(uint256 => address) internal _owners;\n\n // Mapping from owner address to vault owned count\n mapping(address => uint256) internal _balances;\n\n // Mapping from `vaultID` to approved address\n mapping(uint256 => address) internal _vaultApprovals;\n\n // Mapping from owner to operator approvals\n mapping(address => mapping(address => uint256)) internal _operatorApprovals;\n\n uint256[50] private __gap;\n\n // =================================== EVENTS ==================================\n\n event AccruedToTreasury(uint256 surplusEndValue, uint256 badDebtEndValue);\n event CollateralAmountUpdated(uint256 vaultID, uint256 collateralAmount, uint8 isIncrease);\n event InterestAccumulatorUpdated(uint256 value, uint256 timestamp);\n event InternalDebtUpdated(uint256 vaultID, uint256 internalAmount, uint8 isIncrease);\n event FiledUint64(uint64 param, bytes32 what);\n event DebtCeilingUpdated(uint256 debtCeiling);\n event LiquidationBoostParametersUpdated(address indexed _veBoostProxy, uint256[] xBoost, uint256[] yBoost);\n event LiquidatedVaults(uint256[] vaultIDs);\n event DebtTransferred(uint256 srcVaultID, uint256 dstVaultID, address dstVaultManager, uint256 amount);\n\n // =================================== ERRORS ==================================\n\n error ApprovalToOwner();\n error ApprovalToCaller();\n error DustyLeftoverAmount();\n error DebtCeilingExceeded();\n error HealthyVault();\n error IncompatibleLengths();\n error InsolventVault();\n error InvalidParameterValue();\n error InvalidParameterType();\n error InvalidSetOfParameters();\n error InvalidTreasury();\n error NonERC721Receiver();\n error NonexistentVault();\n error NotApproved();\n error NotGovernor();\n error NotGovernorOrGuardian();\n error NotTreasury();\n error NotWhitelisted();\n error NotVaultManager();\n error Paused();\n error TooHighParameterValue();\n error TooSmallParameterValue();\n error ZeroAddress();\n\n /// @custom:oz-upgrades-unsafe-allow constructor\n constructor() initializer {}\n}\n" + }, + "contracts/external/ProxyAdmin.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\nimport \"./TransparentUpgradeableProxy.sol\";\nimport \"@openzeppelin/contracts/access/Ownable.sol\";\n\n/**\n * @dev This is an auxiliary contract meant to be assigned as the admin of a {TransparentUpgradeableProxy}. For an\n * explanation of why you would want to use this see the documentation for {TransparentUpgradeableProxy}.\n * This contract was fully forked from OpenZeppelin `ProxyAdmin`\n */\ncontract ProxyAdmin is Ownable {\n /**\n * @dev Returns the current implementation of `proxy`.\n *\n * Requirements:\n *\n * - This contract must be the admin of `proxy`.\n */\n function getProxyImplementation(TransparentUpgradeableProxy proxy) public view virtual returns (address) {\n // We need to manually run the static call since the getter cannot be flagged as view\n // bytes4(keccak256(\"implementation()\")) == 0x5c60da1b\n (bool success, bytes memory returndata) = address(proxy).staticcall(hex\"5c60da1b\");\n require(success);\n return abi.decode(returndata, (address));\n }\n\n /**\n * @dev Returns the current admin of `proxy`.\n *\n * Requirements:\n *\n * - This contract must be the admin of `proxy`.\n */\n function getProxyAdmin(TransparentUpgradeableProxy proxy) public view virtual returns (address) {\n // We need to manually run the static call since the getter cannot be flagged as view\n // bytes4(keccak256(\"admin()\")) == 0xf851a440\n (bool success, bytes memory returndata) = address(proxy).staticcall(hex\"f851a440\");\n require(success);\n return abi.decode(returndata, (address));\n }\n\n /**\n * @dev Changes the admin of `proxy` to `newAdmin`.\n *\n * Requirements:\n *\n * - This contract must be the current admin of `proxy`.\n */\n function changeProxyAdmin(TransparentUpgradeableProxy proxy, address newAdmin) public virtual onlyOwner {\n proxy.changeAdmin(newAdmin);\n }\n\n /**\n * @dev Upgrades `proxy` to `implementation`. See {TransparentUpgradeableProxy-upgradeTo}.\n *\n * Requirements:\n *\n * - This contract must be the admin of `proxy`.\n */\n function upgrade(TransparentUpgradeableProxy proxy, address implementation) public virtual onlyOwner {\n proxy.upgradeTo(implementation);\n }\n\n /**\n * @dev Upgrades `proxy` to `implementation` and calls a function on the new implementation. See\n * {TransparentUpgradeableProxy-upgradeToAndCall}.\n *\n * Requirements:\n *\n * - This contract must be the admin of `proxy`.\n */\n function upgradeAndCall(\n TransparentUpgradeableProxy proxy,\n address implementation,\n bytes memory data\n ) public payable virtual onlyOwner {\n proxy.upgradeToAndCall{ value: msg.value }(implementation, data);\n }\n}\n" + }, + "contracts/external/TransparentUpgradeableProxy.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\nimport \"@openzeppelin/contracts/proxy/ERC1967/ERC1967Proxy.sol\";\n\n/**\n * @dev This contract implements a proxy that is upgradeable by an admin. It is fully forked from OpenZeppelin\n * `TransparentUpgradeableProxy`\n *\n * To avoid https://medium.com/nomic-labs-blog/malicious-backdoors-in-ethereum-proxies-62629adf3357[proxy selector\n * clashing], which can potentially be used in an attack, this contract uses the\n * https://blog.openzeppelin.com/the-transparent-proxy-pattern/[transparent proxy pattern]. This pattern implies two\n * things that go hand in hand:\n *\n * 1. If any account other than the admin calls the proxy, the call will be forwarded to the implementation, even if\n * that call matches one of the admin functions exposed by the proxy itself.\n * 2. If the admin calls the proxy, it can access the admin functions, but its calls will never be forwarded to the\n * implementation. If the admin tries to call a function on the implementation it will fail with an error that says\n * \"admin cannot fallback to proxy target\".\n *\n * These properties mean that the admin account can only be used for admin actions like upgrading the proxy or changing\n * the admin, so it's best if it's a dedicated account that is not used for anything else. This will avoid headaches due\n * to sudden errors when trying to call a function from the proxy implementation.\n *\n * Our recommendation is for the dedicated account to be an instance of the {ProxyAdmin} contract. If set up this way,\n * you should think of the `ProxyAdmin` instance as the real administrative interface of your proxy.\n */\ncontract TransparentUpgradeableProxy is ERC1967Proxy {\n /**\n * @dev Initializes an upgradeable proxy managed by `_admin`, backed by the implementation at `_logic`, and\n * optionally initialized with `_data` as explained in {ERC1967Proxy-constructor}.\n */\n constructor(address _logic, address admin_, bytes memory _data) payable ERC1967Proxy(_logic, _data) {\n assert(_ADMIN_SLOT == bytes32(uint256(keccak256(\"eip1967.proxy.admin\")) - 1));\n _changeAdmin(admin_);\n }\n\n /**\n * @dev Modifier used internally that will delegate the call to the implementation unless the sender is the admin.\n */\n modifier ifAdmin() {\n if (msg.sender == _getAdmin()) {\n _;\n } else {\n _fallback();\n }\n }\n\n /**\n * @dev Returns the current admin.\n *\n * NOTE: Only the admin can call this function. See {ProxyAdmin-getProxyAdmin}.\n *\n * TIP: To get this value clients can read directly from the storage slot shown below (specified by EIP1967) using the\n * https://eth.wiki/json-rpc/API#eth_getstorageat[`eth_getStorageAt`] RPC call.\n * `0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103`\n */\n function admin() external ifAdmin returns (address admin_) {\n admin_ = _getAdmin();\n }\n\n /**\n * @dev Returns the current implementation.\n *\n * NOTE: Only the admin can call this function. See {ProxyAdmin-getProxyImplementation}.\n *\n * TIP: To get this value clients can read directly from the storage slot shown below (specified by EIP1967) using the\n * https://eth.wiki/json-rpc/API#eth_getstorageat[`eth_getStorageAt`] RPC call.\n * `0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc`\n */\n function implementation() external ifAdmin returns (address implementation_) {\n implementation_ = _implementation();\n }\n\n /**\n * @dev Changes the admin of the proxy.\n *\n * Emits an {AdminChanged} event.\n *\n * NOTE: Only the admin can call this function. See {ProxyAdmin-changeProxyAdmin}.\n */\n function changeAdmin(address newAdmin) external virtual ifAdmin {\n _changeAdmin(newAdmin);\n }\n\n /**\n * @dev Upgrade the implementation of the proxy.\n *\n * NOTE: Only the admin can call this function. See {ProxyAdmin-upgrade}.\n */\n function upgradeTo(address newImplementation) external ifAdmin {\n _upgradeToAndCall(newImplementation, bytes(\"\"), false);\n }\n\n /**\n * @dev Upgrade the implementation of the proxy, and then call a function from the new implementation as specified\n * by `data`, which should be an encoded function call. This is useful to initialize new storage variables in the\n * proxied contract.\n *\n * NOTE: Only the admin can call this function. See {ProxyAdmin-upgradeAndCall}.\n */\n function upgradeToAndCall(address newImplementation, bytes calldata data) external payable ifAdmin {\n _upgradeToAndCall(newImplementation, data, true);\n }\n\n /**\n * @dev Returns the current admin.\n */\n function _admin() internal view virtual returns (address) {\n return _getAdmin();\n }\n\n /**\n * @dev Makes sure the admin cannot access the fallback function. See {Proxy-_beforeFallback}.\n */\n function _beforeFallback() internal virtual override {\n require(msg.sender != _getAdmin(), \"TransparentUpgradeableProxy: admin cannot fallback to proxy target\");\n super._beforeFallback();\n }\n}\n" + }, + "contracts/flashloan/FlashAngle.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\nimport \"@openzeppelin/contracts-upgradeable/security/ReentrancyGuardUpgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol\";\nimport \"@openzeppelin/contracts/interfaces/IERC3156FlashBorrower.sol\";\nimport \"@openzeppelin/contracts/interfaces/IERC3156FlashLender.sol\";\nimport \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\nimport \"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\";\n\nimport \"../interfaces/IAgToken.sol\";\nimport \"../interfaces/ICoreBorrow.sol\";\nimport \"../interfaces/IFlashAngle.sol\";\nimport \"../interfaces/ITreasury.sol\";\n\n/// @title FlashAngle\n/// @author Angle Labs, Inc.\n/// @notice Contract to take flash loans on top of several AgToken contracts\ncontract FlashAngle is IERC3156FlashLender, IFlashAngle, Initializable, ReentrancyGuardUpgradeable {\n using SafeERC20 for IERC20;\n /// @notice Base used for parameter computation\n uint256 public constant BASE_PARAMS = 10 ** 9;\n /// @notice Success message received when calling a `FlashBorrower` contract\n bytes32 public constant CALLBACK_SUCCESS = keccak256(\"ERC3156FlashBorrower.onFlashLoan\");\n\n /// @notice Struct encoding for a given stablecoin the parameters\n struct StablecoinData {\n // Maximum amount borrowable for this stablecoin\n uint256 maxBorrowable;\n // Flash loan fee taken by the protocol for a flash loan on this stablecoin\n uint64 flashLoanFee;\n // Treasury address responsible of the stablecoin\n address treasury;\n }\n\n // ======================= Parameters and References ===========================\n\n /// @notice Maps a stablecoin to the data and parameters for flash loans\n mapping(IAgToken => StablecoinData) public stablecoinMap;\n /// @inheritdoc IFlashAngle\n ICoreBorrow public core;\n\n // =============================== Event =======================================\n\n event FlashLoan(address indexed stablecoin, uint256 amount, IERC3156FlashBorrower indexed receiver);\n event FlashLoanParametersUpdated(IAgToken indexed stablecoin, uint64 _flashLoanFee, uint256 _maxBorrowable);\n\n // =============================== Errors ======================================\n\n error InvalidReturnMessage();\n error NotCore();\n error NotGovernorOrGuardian();\n error NotTreasury();\n error TooBigAmount();\n error TooHighParameterValue();\n error UnsupportedStablecoin();\n error ZeroAddress();\n\n /// @notice Initializes the contract\n /// @param _core Core address handling this module\n function initialize(ICoreBorrow _core) public initializer {\n if (address(_core) == address(0)) revert ZeroAddress();\n core = _core;\n }\n\n /// @custom:oz-upgrades-unsafe-allow constructor\n constructor() initializer {}\n\n // =================================== Modifiers ===============================\n\n /// @notice Checks whether the sender is the core contract\n modifier onlyCore() {\n if (msg.sender != address(core)) revert NotCore();\n _;\n }\n\n /// @notice Checks whether a given stablecoin has been initialized in this contract\n /// @param stablecoin Stablecoin to check\n /// @dev To check whether a stablecoin has been initialized, we just need to check whether its associated\n /// `treasury` address is not null in the `stablecoinMap`. This is what's checked in the `CoreBorrow` contract\n /// when adding support for a stablecoin\n modifier onlyExistingStablecoin(IAgToken stablecoin) {\n if (stablecoinMap[stablecoin].treasury == address(0)) revert UnsupportedStablecoin();\n _;\n }\n\n // ================================ ERC3156 Spec ===============================\n\n /// @inheritdoc IERC3156FlashLender\n function flashFee(address token, uint256 amount) external view returns (uint256) {\n return _flashFee(token, amount);\n }\n\n /// @inheritdoc IERC3156FlashLender\n function maxFlashLoan(address token) external view returns (uint256) {\n // It will be 0 anyway if the token was not added\n return stablecoinMap[IAgToken(token)].maxBorrowable;\n }\n\n /// @inheritdoc IERC3156FlashLender\n function flashLoan(\n IERC3156FlashBorrower receiver,\n address token,\n uint256 amount,\n bytes calldata data\n ) external nonReentrant returns (bool) {\n uint256 fee = _flashFee(token, amount);\n if (amount > stablecoinMap[IAgToken(token)].maxBorrowable) revert TooBigAmount();\n IAgToken(token).mint(address(receiver), amount);\n if (receiver.onFlashLoan(msg.sender, token, amount, fee, data) != CALLBACK_SUCCESS)\n revert InvalidReturnMessage();\n // Token must be an agToken here so normally no need to use `safeTransferFrom`, but out of safety\n // and in case governance whitelists an agToken which does not have a correct implementation, we prefer\n // to use `safeTransferFrom` here\n IERC20(token).safeTransferFrom(address(receiver), address(this), amount + fee);\n IAgToken(token).burnSelf(amount, address(this));\n emit FlashLoan(token, amount, receiver);\n return true;\n }\n\n /// @notice Internal function to compute the fee induced for taking a flash loan of `amount` of `token`\n /// @param token The loan currency\n /// @param amount The amount of tokens lent\n /// @dev This function will revert if the `token` requested is not whitelisted here\n function _flashFee(\n address token,\n uint256 amount\n ) internal view onlyExistingStablecoin(IAgToken(token)) returns (uint256) {\n return (amount * stablecoinMap[IAgToken(token)].flashLoanFee) / BASE_PARAMS;\n }\n\n // ============================ Treasury Only Function =========================\n\n /// @inheritdoc IFlashAngle\n function accrueInterestToTreasury(IAgToken stablecoin) external returns (uint256 balance) {\n address treasury = stablecoinMap[stablecoin].treasury;\n if (msg.sender != treasury) revert NotTreasury();\n balance = stablecoin.balanceOf(address(this));\n IERC20(address(stablecoin)).safeTransfer(treasury, balance);\n }\n\n // =========================== Governance Only Function ========================\n\n /// @notice Sets the parameters for a given stablecoin\n /// @param stablecoin Stablecoin to change the parameters for\n /// @param _flashLoanFee New flash loan fee for this stablecoin\n /// @param _maxBorrowable Maximum amount that can be borrowed in a single flash loan\n /// @dev Setting a `maxBorrowable` parameter equal to 0 is a way to pause the functionality\n /// @dev Parameters can only be modified for whitelisted stablecoins\n function setFlashLoanParameters(\n IAgToken stablecoin,\n uint64 _flashLoanFee,\n uint256 _maxBorrowable\n ) external onlyExistingStablecoin(stablecoin) {\n if (!core.isGovernorOrGuardian(msg.sender)) revert NotGovernorOrGuardian();\n if (_flashLoanFee > BASE_PARAMS) revert TooHighParameterValue();\n stablecoinMap[stablecoin].flashLoanFee = _flashLoanFee;\n stablecoinMap[stablecoin].maxBorrowable = _maxBorrowable;\n emit FlashLoanParametersUpdated(stablecoin, _flashLoanFee, _maxBorrowable);\n }\n\n // =========================== CoreBorrow Only Functions =======================\n\n /// @inheritdoc IFlashAngle\n function addStablecoinSupport(address _treasury) external onlyCore {\n stablecoinMap[IAgToken(ITreasury(_treasury).stablecoin())].treasury = _treasury;\n }\n\n /// @inheritdoc IFlashAngle\n function removeStablecoinSupport(address _treasury) external onlyCore {\n delete stablecoinMap[IAgToken(ITreasury(_treasury).stablecoin())];\n }\n\n /// @inheritdoc IFlashAngle\n function setCore(address _core) external onlyCore {\n core = ICoreBorrow(_core);\n }\n}\n" + }, + "contracts/interfaces/coreModule/IAgTokenMainnet.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\n/// @title IAgTokenMainnet\n/// @author Angle Labs, Inc.\ninterface IAgTokenMainnet {\n function stableMaster() external view returns (address);\n}\n" + }, + "contracts/interfaces/coreModule/ICore.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\n/// @title ICore\n/// @author Angle Labs, Inc.\ninterface ICore {\n function stablecoinList() external view returns (address[] memory);\n}\n" + }, + "contracts/interfaces/coreModule/ILiquidityGauge.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\ninterface ILiquidityGauge {\n function deposit(\n uint256 _value,\n address _addr,\n // solhint-disable-next-line\n bool _claim_rewards\n ) external;\n\n function withdraw(\n uint256 _value,\n // solhint-disable-next-line\n bool _claim_rewards\n ) external;\n\n // solhint-disable-next-line\n function claim_rewards(address _addr, address _receiver) external;\n\n // solhint-disable-next-line\n function claimable_reward(address _addr, address _reward_token) external view returns (uint256 amount);\n}\n" + }, + "contracts/interfaces/coreModule/IOracleCore.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\n/// @title IOracleCore\n/// @author Angle Labs, Inc.\ninterface IOracleCore {\n function readUpper() external view returns (uint256);\n\n function readQuoteLower(uint256 baseAmount) external view returns (uint256);\n}\n" + }, + "contracts/interfaces/coreModule/IPerpetualManager.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\n/// @title IPerpetualManager\n/// @author Angle Labs, Inc.\ninterface IPerpetualManager {\n function totalHedgeAmount() external view returns (uint256);\n\n function maintenanceMargin() external view returns (uint64);\n\n function maxLeverage() external view returns (uint64);\n\n function targetHAHedge() external view returns (uint64);\n\n function limitHAHedge() external view returns (uint64);\n\n function lockTime() external view returns (uint64);\n\n function haBonusMalusDeposit() external view returns (uint64);\n\n function haBonusMalusWithdraw() external view returns (uint64);\n\n function xHAFeesDeposit(uint256) external view returns (uint64);\n\n function yHAFeesDeposit(uint256) external view returns (uint64);\n\n function xHAFeesWithdraw(uint256) external view returns (uint64);\n\n function yHAFeesWithdraw(uint256) external view returns (uint64);\n}\n" + }, + "contracts/interfaces/coreModule/IPoolManager.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\n/// @title IPoolManager\n/// @author Angle Labs, Inc.\ninterface IPoolManager {\n function feeManager() external view returns (address);\n\n function strategyList(uint256) external view returns (address);\n}\n" + }, + "contracts/interfaces/coreModule/IStableMaster.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\nimport \"./IPerpetualManager.sol\";\nimport \"./IOracleCore.sol\";\n\n// Struct to handle all the parameters to manage the fees\n// related to a given collateral pool (associated to the stablecoin)\nstruct MintBurnData {\n // Values of the thresholds to compute the minting fees\n // depending on HA hedge (scaled by `BASE_PARAMS`)\n uint64[] xFeeMint;\n // Values of the fees at thresholds (scaled by `BASE_PARAMS`)\n uint64[] yFeeMint;\n // Values of the thresholds to compute the burning fees\n // depending on HA hedge (scaled by `BASE_PARAMS`)\n uint64[] xFeeBurn;\n // Values of the fees at thresholds (scaled by `BASE_PARAMS`)\n uint64[] yFeeBurn;\n // Max proportion of collateral from users that can be covered by HAs\n // It is exactly the same as the parameter of the same name in `PerpetualManager`, whenever one is updated\n // the other changes accordingly\n uint64 targetHAHedge;\n // Minting fees correction set by the `FeeManager` contract: they are going to be multiplied\n // to the value of the fees computed using the hedge curve\n // Scaled by `BASE_PARAMS`\n uint64 bonusMalusMint;\n // Burning fees correction set by the `FeeManager` contract: they are going to be multiplied\n // to the value of the fees computed using the hedge curve\n // Scaled by `BASE_PARAMS`\n uint64 bonusMalusBurn;\n // Parameter used to limit the number of stablecoins that can be issued using the concerned collateral\n uint256 capOnStableMinted;\n}\n\n// Struct to handle all the variables and parameters to handle SLPs in the protocol\n// including the fraction of interests they receive or the fees to be distributed to\n// them\nstruct SLPData {\n // Last timestamp at which the `sanRate` has been updated for SLPs\n uint256 lastBlockUpdated;\n // Fees accumulated from previous blocks and to be distributed to SLPs\n uint256 lockedInterests;\n // Max interests used to update the `sanRate` in a single block\n // Should be in collateral token base\n uint256 maxInterestsDistributed;\n // Amount of fees left aside for SLPs and that will be distributed\n // when the protocol is collateralized back again\n uint256 feesAside;\n // Part of the fees normally going to SLPs that is left aside\n // before the protocol is collateralized back again (depends on collateral ratio)\n // Updated by keepers and scaled by `BASE_PARAMS`\n uint64 slippageFee;\n // Portion of the fees from users minting and burning\n // that goes to SLPs (the rest goes to surplus)\n uint64 feesForSLPs;\n // Slippage factor that's applied to SLPs exiting (depends on collateral ratio)\n // If `slippage = BASE_PARAMS`, SLPs can get nothing, if `slippage = 0` they get their full claim\n // Updated by keepers and scaled by `BASE_PARAMS`\n uint64 slippage;\n // Portion of the interests from lending\n // that goes to SLPs (the rest goes to surplus)\n uint64 interestsForSLPs;\n}\n\n/// @title IStableMaster\n/// @author Angle Labs, Inc.\ninterface IStableMaster {\n function agToken() external view returns (address);\n\n function updateStocksUsers(uint256 amount, address poolManager) external;\n\n function collateralMap(\n address poolManager\n )\n external\n view\n returns (\n address token,\n address sanToken,\n IPerpetualManager perpetualManager,\n IOracleCore oracle,\n uint256 stocksUsers,\n uint256 sanRate,\n uint256 collatBase,\n SLPData memory slpData,\n MintBurnData memory feeData\n );\n\n function paused(bytes32) external view returns (bool);\n\n function deposit(uint256 amount, address user, address poolManager) external;\n\n function withdraw(uint256 amount, address burner, address dest, address poolManager) external;\n}\n" + }, + "contracts/interfaces/external/create2/ImmutableCreate2Factory.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\ninterface ImmutableCreate2Factory {\n function safeCreate2(bytes32 salt, bytes memory initCode) external payable returns (address deploymentAddress);\n\n function findCreate2Address(\n bytes32 salt,\n bytes calldata initCode\n ) external view returns (address deploymentAddress);\n\n function findCreate2AddressViaHash(\n bytes32 salt,\n bytes32 initCodeHash\n ) external view returns (address deploymentAddress);\n}\n" + }, + "contracts/interfaces/external/IERC1271.sol": { + "content": "// SPDX-License-Identifier: GPL-2.0-or-later\npragma solidity ^0.8.12;\n\n/// @title Interface for verifying contract-based account signatures\n/// @notice Interface that verifies provided signature for the data\n/// @dev Interface defined by EIP-1271\ninterface IERC1271 {\n /// @notice Returns whether the provided signature is valid for the provided data\n /// @dev MUST return the bytes4 magic value 0x1626ba7e when function passes.\n /// MUST NOT modify state (using STATICCALL for solc < 0.5, view modifier for solc > 0.5).\n /// MUST allow external calls.\n /// @param hash Hash of the data to be signed\n /// @param signature Signature byte array associated with _data\n /// @return magicValue The bytes4 magic value 0x1626ba7e\n function isValidSignature(bytes32 hash, bytes memory signature) external view returns (bytes4 magicValue);\n}\n" + }, + "contracts/interfaces/external/IERC4626.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\npragma solidity >=0.8.0;\n\nimport \"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\";\nimport \"@openzeppelin/contracts/token/ERC20/ERC20.sol\";\n\n/// @notice Minimal IERC4646 tokenized Vault interface.\n/// @author Forked from Solmate (https://github.com/Rari-Capital/solmate/blob/main/src/mixins/ERC4626.sol)\n/// @dev Do not use in production! ERC-4626 is still in the review stage and is subject to change.\ninterface IERC4626 {\n event Deposit(address indexed from, address indexed to, uint256 amount, uint256 shares);\n event Withdraw(address indexed from, address indexed to, uint256 amount, uint256 shares);\n\n /// @notice Transfers a given amount of asset to the reactor and mint shares accordingly\n /// @param amount Given amount of asset\n /// @param to Address to mint shares to\n /// @return shares Amount of shares minted to `to`\n function deposit(uint256 amount, address to) external returns (uint256 shares);\n\n /// @notice Mints a given amount of shares to the reactor and transfer assets accordingly\n /// @param shares Given amount of shares\n /// @param to Address to mint shares to\n /// @return amount Amount of `asset` taken to the `msg.sender` to mint `shares`\n function mint(uint256 shares, address to) external returns (uint256 amount);\n\n /// @notice Transfers a given amount of asset from the reactor and burn shares accordingly\n /// @param amount Given amount of asset\n /// @param to Address to transfer assets to\n /// @param from Address to burn shares from\n /// @return shares Amount of shares burnt in the operation\n function withdraw(uint256 amount, address to, address from) external returns (uint256 shares);\n\n /// @notice Burns a given amount of shares to the reactor and transfer assets accordingly\n /// @param shares Given amount of shares\n /// @param to Address to transfer assets to\n /// @param from Address to burn shares from\n /// @return amount Amount of assets redeemed in the operation\n function redeem(uint256 shares, address to, address from) external returns (uint256 amount);\n\n /// @notice Returns the total assets managed by this reactor\n function totalAssets() external view returns (uint256);\n\n /// @notice Converts an amount of assets to the corresponding amount of reactor shares\n /// @param assets Amount of asset to convert\n /// @return Shares corresponding to the amount of assets obtained\n function convertToShares(uint256 assets) external view returns (uint256);\n\n /// @notice Converts an amount of shares to its current value in asset\n /// @param shares Amount of shares to convert\n /// @return Amount of assets corresponding to the amount of assets given\n function convertToAssets(uint256 shares) external view returns (uint256);\n\n /// @notice Computes how many shares one would get by depositing `assets`\n /// @param assets Amount of asset to convert\n function previewDeposit(uint256 assets) external view returns (uint256);\n\n /// @notice Computes how many assets one would need to mint `shares`\n /// @param shares Amount of shares required\n function previewMint(uint256 shares) external view returns (uint256);\n\n /// @notice Computes how many shares one would need to withdraw assets\n /// @param assets Amount of asset to withdraw\n function previewWithdraw(uint256 assets) external view returns (uint256);\n\n /// @notice Computes how many assets one would get by burning shares\n /// @param shares Amount of shares to burn\n function previewRedeem(uint256 shares) external view returns (uint256);\n\n /// @notice Max deposit allowed for a user\n /// @param user Address of the user to check\n function maxDeposit(address user) external returns (uint256);\n\n /// @notice Max mint allowed for a user\n /// @param user Address of the user to check\n function maxMint(address user) external returns (uint256);\n\n /// @notice Max withdraw allowed for a user\n /// @param user Address of the user to check\n function maxWithdraw(address user) external returns (uint256);\n\n /// @notice Max redeem allowed for a user\n /// @param user Address of the user to check\n function maxRedeem(address user) external returns (uint256);\n}\n" + }, + "contracts/interfaces/external/IWETH9.sol": { + "content": "// SPDX-License-Identifier: GPL-2.0-or-later\npragma solidity ^0.8.12;\n\nimport \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\n\n/// @title Interface for WETH9\ninterface IWETH9 is IERC20 {\n /// @notice Deposit ether to get wrapped ether\n function deposit() external payable;\n\n /// @notice Withdraw wrapped ether to get ether\n function withdraw(uint256) external;\n}\n" + }, + "contracts/interfaces/external/layerZero/ILayerZeroEndpoint.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity >=0.5.0;\n\nimport \"./ILayerZeroUserApplicationConfig.sol\";\n\ninterface ILayerZeroEndpoint is ILayerZeroUserApplicationConfig {\n // @notice send a LayerZero message to the specified address at a LayerZero endpoint.\n // @param _dstChainId - the destination chain identifier\n // @param _destination - the address on destination chain (in bytes). address length/format may vary by chains\n // @param _payload - a custom bytes payload to send to the destination contract\n // @param _refundAddress - if the source transaction is cheaper than the amount of value passed, refund the additional amount to this address\n // @param _zroPaymentAddress - the address of the ZRO token holder who would pay for the transaction\n // @param _adapterParams - parameters for custom functionality. e.g. receive airdropped native gas from the relayer on destination\n function send(\n uint16 _dstChainId,\n bytes calldata _destination,\n bytes calldata _payload,\n address payable _refundAddress,\n address _zroPaymentAddress,\n bytes calldata _adapterParams\n ) external payable;\n\n // @notice used by the messaging library to publish verified payload\n // @param _srcChainId - the source chain identifier\n // @param _srcAddress - the source contract (as bytes) at the source chain\n // @param _dstAddress - the address on destination chain\n // @param _nonce - the unbound message ordering nonce\n // @param _gasLimit - the gas limit for external contract execution\n // @param _payload - verified payload to send to the destination contract\n function receivePayload(\n uint16 _srcChainId,\n bytes calldata _srcAddress,\n address _dstAddress,\n uint64 _nonce,\n uint256 _gasLimit,\n bytes calldata _payload\n ) external;\n\n // @notice get the inboundNonce of a lzApp from a source chain which could be EVM or non-EVM chain\n // @param _srcChainId - the source chain identifier\n // @param _srcAddress - the source chain contract address\n function getInboundNonce(uint16 _srcChainId, bytes calldata _srcAddress) external view returns (uint64);\n\n // @notice get the outboundNonce from this source chain which, consequently, is always an EVM\n // @param _srcAddress - the source chain contract address\n function getOutboundNonce(uint16 _dstChainId, address _srcAddress) external view returns (uint64);\n\n // @notice gets a quote in source native gas, for the amount that send() requires to pay for message delivery\n // @param _dstChainId - the destination chain identifier\n // @param _userApplication - the user app address on this EVM chain\n // @param _payload - the custom message to send over LayerZero\n // @param _payInZRO - if false, user app pays the protocol fee in native token\n // @param _adapterParam - parameters for the adapter service, e.g. send some dust native token to dstChain\n function estimateFees(\n uint16 _dstChainId,\n address _userApplication,\n bytes calldata _payload,\n bool _payInZRO,\n bytes calldata _adapterParam\n ) external view returns (uint256 nativeFee, uint256 zroFee);\n\n // @notice get this Endpoint's immutable source identifier\n function getChainId() external view returns (uint16);\n\n // @notice the interface to retry failed message on this Endpoint destination\n // @param _srcChainId - the source chain identifier\n // @param _srcAddress - the source chain contract address\n // @param _payload - the payload to be retried\n function retryPayload(uint16 _srcChainId, bytes calldata _srcAddress, bytes calldata _payload) external;\n\n // @notice query if any STORED payload (message blocking) at the endpoint.\n // @param _srcChainId - the source chain identifier\n // @param _srcAddress - the source chain contract address\n function hasStoredPayload(uint16 _srcChainId, bytes calldata _srcAddress) external view returns (bool);\n\n // @notice query if the _libraryAddress is valid for sending msgs.\n // @param _userApplication - the user app address on this EVM chain\n function getSendLibraryAddress(address _userApplication) external view returns (address);\n\n // @notice query if the _libraryAddress is valid for receiving msgs.\n // @param _userApplication - the user app address on this EVM chain\n function getReceiveLibraryAddress(address _userApplication) external view returns (address);\n\n // @notice query if the non-reentrancy guard for send() is on\n // @return true if the guard is on. false otherwise\n function isSendingPayload() external view returns (bool);\n\n // @notice query if the non-reentrancy guard for receive() is on\n // @return true if the guard is on. false otherwise\n function isReceivingPayload() external view returns (bool);\n\n // @notice get the configuration of the LayerZero messaging library of the specified version\n // @param _version - messaging library version\n // @param _chainId - the chainId for the pending config change\n // @param _userApplication - the contract address of the user application\n // @param _configType - type of configuration. every messaging library has its own convention.\n function getConfig(\n uint16 _version,\n uint16 _chainId,\n address _userApplication,\n uint256 _configType\n ) external view returns (bytes memory);\n\n // @notice get the send() LayerZero messaging library version\n // @param _userApplication - the contract address of the user application\n function getSendVersion(address _userApplication) external view returns (uint16);\n\n // @notice get the lzReceive() LayerZero messaging library version\n // @param _userApplication - the contract address of the user application\n function getReceiveVersion(address _userApplication) external view returns (uint16);\n}\n" + }, + "contracts/interfaces/external/layerZero/ILayerZeroReceiver.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity >=0.5.0;\n\ninterface ILayerZeroReceiver {\n // @notice LayerZero endpoint will invoke this function to deliver the message on the destination\n // @param _srcChainId - the source endpoint identifier\n // @param _srcAddress - the source sending contract address from the source chain\n // @param _nonce - the ordered message nonce\n // @param _payload - the signed payload is the UA bytes has encoded to be sent\n function lzReceive(uint16 _srcChainId, bytes calldata _srcAddress, uint64 _nonce, bytes calldata _payload) external;\n}\n" + }, + "contracts/interfaces/external/layerZero/ILayerZeroUserApplicationConfig.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity >=0.5.0;\n\ninterface ILayerZeroUserApplicationConfig {\n // @notice set the configuration of the LayerZero messaging library of the specified version\n // @param _version - messaging library version\n // @param _chainId - the chainId for the pending config change\n // @param _configType - type of configuration. every messaging library has its own convention.\n // @param _config - configuration in the bytes. can encode arbitrary content.\n function setConfig(uint16 _version, uint16 _chainId, uint256 _configType, bytes calldata _config) external;\n\n // @notice set the send() LayerZero messaging library version to _version\n // @param _version - new messaging library version\n function setSendVersion(uint16 _version) external;\n\n // @notice set the lzReceive() LayerZero messaging library version to _version\n // @param _version - new messaging library version\n function setReceiveVersion(uint16 _version) external;\n\n // @notice Only when the UA needs to resume the message flow in blocking mode and clear the stored payload\n // @param _srcChainId - the chainId of the source chain\n // @param _srcAddress - the contract address of the source contract at the source chain\n function forceResumeReceive(uint16 _srcChainId, bytes calldata _srcAddress) external;\n}\n" + }, + "contracts/interfaces/external/lido/IStETH.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\n/// @title IStETH\n/// @author Angle Labs, Inc.\n/// @notice Interface for the `StETH` contract\n/// @dev This interface only contains functions of the `StETH` which are called by other contracts\n/// of this module\ninterface IStETH {\n function getPooledEthByShares(uint256 _sharesAmount) external view returns (uint256);\n\n event Submitted(address sender, uint256 amount, address referral);\n\n function submit(address) external payable returns (uint256);\n\n function getSharesByPooledEth(uint256 _ethAmount) external view returns (uint256);\n}\n" + }, + "contracts/interfaces/external/lido/IWStETH.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\n/// @title IWStETH\n/// @author Angle Labs, Inc.\n/// @notice Interface for the `WStETH` contract\n/// @dev This interface only contains functions of the `WStETH` which are called by other contracts\n/// of this module\ninterface IWStETH {\n function wrap(uint256 _stETHAmount) external returns (uint256);\n\n function stETH() external view returns (address);\n}\n" + }, + "contracts/interfaces/external/uniswap/IUniswapRouter.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\nstruct ExactInputParams {\n bytes path;\n address recipient;\n uint256 deadline;\n uint256 amountIn;\n uint256 amountOutMinimum;\n}\n\n/// @title Router token swapping functionality\n/// @notice Functions for swapping tokens via Uniswap V3\ninterface IUniswapV3Router {\n /// @notice Swaps `amountIn` of one token for as much as possible of another along the specified path\n /// @param params The parameters necessary for the multi-hop swap, encoded as `ExactInputParams` in calldata\n /// @return amountOut The amount of the received token\n function exactInput(ExactInputParams calldata params) external payable returns (uint256 amountOut);\n}\n\n/// @title Router for price estimation functionality\n/// @notice Functions for getting the price of one token with respect to another using Uniswap V2\n/// @dev This interface is only used for non critical elements of the protocol\ninterface IUniswapV2Router {\n /// @notice Given an input asset amount, returns the maximum output amount of the\n /// other asset (accounting for fees) given reserves.\n /// @param path Addresses of the pools used to get prices\n function getAmountsOut(uint256 amountIn, address[] calldata path) external view returns (uint256[] memory amounts);\n\n function swapExactTokensForTokens(\n uint256 swapAmount,\n uint256 minExpected,\n address[] calldata path,\n address receiver,\n uint256 swapDeadline\n ) external;\n}\n" + }, + "contracts/interfaces/external/uniswap/IUniswapV3Pool.sol": { + "content": "// SPDX-License-Identifier: GPL-2.0-or-later\npragma solidity >=0.5.0;\n\n/// @title Pool state that never changes\n/// @notice These parameters are fixed for a pool forever, i.e., the methods will always return the same values\ninterface IUniswapV3Pool {\n /// @notice The first of the two tokens of the pool, sorted by address\n /// @return The token contract address\n function token0() external view returns (address);\n\n /// @notice The second of the two tokens of the pool, sorted by address\n /// @return The token contract address\n function token1() external view returns (address);\n}\n" + }, + "contracts/interfaces/governance/IVeBoostProxy.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\n/// @title IVeBoostProxy\n/// @author Angle Labs, Inc.\n/// @notice Interface for the `VeBoostProxy` contract\n/// @dev This interface only contains functions of the contract which are called by other contracts\n/// of this module\n/// @dev The `veBoostProxy` contract used by Angle is a full fork of Curve Finance implementation\ninterface IVeBoostProxy {\n /// @notice Reads the adjusted veANGLE balance of an address (adjusted by delegation)\n //solhint-disable-next-line\n function adjusted_balance_of(address) external view returns (uint256);\n}\n" + }, + "contracts/interfaces/IAgToken.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\nimport \"@openzeppelin/contracts-upgradeable/token/ERC20/IERC20Upgradeable.sol\";\n\n/// @title IAgToken\n/// @author Angle Labs, Inc.\n/// @notice Interface for the stablecoins `AgToken` contracts\n/// @dev This interface only contains functions of the `AgToken` contract which are called by other contracts\n/// of this module or of the first module of the Angle Protocol\ninterface IAgToken is IERC20Upgradeable {\n // ======================= Minter Role Only Functions ===========================\n\n /// @notice Lets the `StableMaster` contract or another whitelisted contract mint agTokens\n /// @param account Address to mint to\n /// @param amount Amount to mint\n /// @dev The contracts allowed to issue agTokens are the `StableMaster` contract, `VaultManager` contracts\n /// associated to this stablecoin as well as the flash loan module (if activated) and potentially contracts\n /// whitelisted by governance\n function mint(address account, uint256 amount) external;\n\n /// @notice Burns `amount` tokens from a `burner` address after being asked to by `sender`\n /// @param amount Amount of tokens to burn\n /// @param burner Address to burn from\n /// @param sender Address which requested the burn from `burner`\n /// @dev This method is to be called by a contract with the minter right after being requested\n /// to do so by a `sender` address willing to burn tokens from another `burner` address\n /// @dev The method checks the allowance between the `sender` and the `burner`\n function burnFrom(uint256 amount, address burner, address sender) external;\n\n /// @notice Burns `amount` tokens from a `burner` address\n /// @param amount Amount of tokens to burn\n /// @param burner Address to burn from\n /// @dev This method is to be called by a contract with a minter right on the AgToken after being\n /// requested to do so by an address willing to burn tokens from its address\n function burnSelf(uint256 amount, address burner) external;\n\n // ========================= Treasury Only Functions ===========================\n\n /// @notice Adds a minter in the contract\n /// @param minter Minter address to add\n /// @dev Zero address checks are performed directly in the `Treasury` contract\n function addMinter(address minter) external;\n\n /// @notice Removes a minter from the contract\n /// @param minter Minter address to remove\n /// @dev This function can also be called by a minter wishing to revoke itself\n function removeMinter(address minter) external;\n\n /// @notice Sets a new treasury contract\n /// @param _treasury New treasury address\n function setTreasury(address _treasury) external;\n\n // ========================= External functions ================================\n\n /// @notice Checks whether an address has the right to mint agTokens\n /// @param minter Address for which the minting right should be checked\n /// @return Whether the address has the right to mint agTokens or not\n function isMinter(address minter) external view returns (bool);\n\n /// @notice Get the associated treasury\n function treasury() external view returns (address);\n}\n" + }, + "contracts/interfaces/IAgTokenSideChainMultiBridge.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\nimport \"@openzeppelin/contracts-upgradeable/token/ERC20/extensions/draft-IERC20PermitUpgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/token/ERC20/IERC20Upgradeable.sol\";\n\n/// @title IAgTokenSideChainMultiBridge\n/// @author Angle Labs, Inc.\n/// @notice Interface for the canonical `AgToken` contracts\n/// @dev This interface only contains functions useful for bridge tokens to interact with the canonical token\ninterface IAgTokenSideChainMultiBridge is IERC20PermitUpgradeable, IERC20Upgradeable {\n /// @notice Mints the canonical token from a supported bridge token\n /// @param bridgeToken Bridge token to use to mint\n /// @param amount Amount of bridge tokens to send\n /// @param to Address to which the stablecoin should be sent\n /// @return Amount of the canonical stablecoin actually minted\n /// @dev Some fees may be taken by the protocol depending on the token used and on the address calling\n function swapIn(address bridgeToken, uint256 amount, address to) external returns (uint256);\n\n /// @notice Burns the canonical token in exchange for a bridge token\n /// @param bridgeToken Bridge token required\n /// @param amount Amount of canonical tokens to burn\n /// @param to Address to which the bridge token should be sent\n /// @return Amount of bridge tokens actually sent back\n /// @dev Some fees may be taken by the protocol depending on the token used and on the address calling\n function swapOut(address bridgeToken, uint256 amount, address to) external returns (uint256);\n}\n" + }, + "contracts/interfaces/IAngleRouter.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\n/// @title IAngleRouter\n/// @author Angle Labs, Inc.\n/// @notice Interface for the `AngleRouter` contract\n/// @dev This interface only contains functions of the `AngleRouter01` contract which are called by other contracts\n/// of this module\ninterface IAngleRouter {\n function mint(\n address user,\n uint256 amount,\n uint256 minStableAmount,\n address stablecoin,\n address collateral\n ) external;\n\n function burn(address user, uint256 amount, uint256 minAmountOut, address stablecoin, address collateral) external;\n\n function mapPoolManagers(\n address stableMaster,\n address collateral\n ) external view returns (address poolManager, address perpetualManager, address sanToken, address gauge);\n}\n" + }, + "contracts/interfaces/IAngleRouterSidechain.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\n/// @notice Action types\nenum ActionType {\n transfer,\n wrap,\n wrapNative,\n sweep,\n sweepNative,\n unwrap,\n unwrapNative,\n swapIn,\n swapOut,\n uniswapV3,\n oneInch,\n claimRewards,\n gaugeDeposit,\n borrower\n}\n\n/// @notice Data needed to get permits\nstruct PermitType {\n address token;\n address owner;\n uint256 value;\n uint256 deadline;\n uint8 v;\n bytes32 r;\n bytes32 s;\n}\n\n/// @title IAngleRouterSidechain\n/// @author Angle Labs, Inc.\n/// @notice Interface for the `AngleRouter` contract on other chains\ninterface IAngleRouterSidechain {\n function mixer(PermitType[] memory paramsPermit, ActionType[] memory actions, bytes[] calldata data) external;\n}\n" + }, + "contracts/interfaces/ICoreBorrow.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\n/// @title ICoreBorrow\n/// @author Angle Labs, Inc.\n/// @notice Interface for the `CoreBorrow` contract\n/// @dev This interface only contains functions of the `CoreBorrow` contract which are called by other contracts\n/// of this module\ninterface ICoreBorrow {\n /// @notice Checks if an address corresponds to a treasury of a stablecoin with a flash loan\n /// module initialized on it\n /// @param treasury Address to check\n /// @return Whether the address has the `FLASHLOANER_TREASURY_ROLE` or not\n function isFlashLoanerTreasury(address treasury) external view returns (bool);\n\n /// @notice Checks whether an address is governor of the Angle Protocol or not\n /// @param admin Address to check\n /// @return Whether the address has the `GOVERNOR_ROLE` or not\n function isGovernor(address admin) external view returns (bool);\n\n /// @notice Checks whether an address is governor or a guardian of the Angle Protocol or not\n /// @param admin Address to check\n /// @return Whether the address has the `GUARDIAN_ROLE` or not\n /// @dev Governance should make sure when adding a governor to also give this governor the guardian\n /// role by calling the `addGovernor` function\n function isGovernorOrGuardian(address admin) external view returns (bool);\n}\n" + }, + "contracts/interfaces/IFlashAngle.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\nimport \"./IAgToken.sol\";\nimport \"./ICoreBorrow.sol\";\n\n/// @title IFlashAngle\n/// @author Angle Labs, Inc.\n/// @notice Interface for the `FlashAngle` contract\n/// @dev This interface only contains functions of the contract which are called by other contracts\n/// of this module\ninterface IFlashAngle {\n /// @notice Reference to the `CoreBorrow` contract managing the FlashLoan module\n function core() external view returns (ICoreBorrow);\n\n /// @notice Sends the fees taken from flash loans to the treasury contract associated to the stablecoin\n /// @param stablecoin Stablecoin from which profits should be sent\n /// @return balance Amount of profits sent\n /// @dev This function can only be called by the treasury contract\n function accrueInterestToTreasury(IAgToken stablecoin) external returns (uint256 balance);\n\n /// @notice Adds support for a stablecoin\n /// @param _treasury Treasury associated to the stablecoin to add support for\n /// @dev This function can only be called by the `CoreBorrow` contract\n function addStablecoinSupport(address _treasury) external;\n\n /// @notice Removes support for a stablecoin\n /// @param _treasury Treasury associated to the stablecoin to remove support for\n /// @dev This function can only be called by the `CoreBorrow` contract\n function removeStablecoinSupport(address _treasury) external;\n\n /// @notice Sets a new core contract\n /// @param _core Core contract address to set\n /// @dev This function can only be called by the `CoreBorrow` contract\n function setCore(address _core) external;\n}\n" + }, + "contracts/interfaces/IKeeperRegistry.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\nimport \"@openzeppelin/contracts-upgradeable/token/ERC20/IERC20Upgradeable.sol\";\n\n/// @title IKeeperRegistry\n/// @author Angle Labs, Inc.\ninterface IKeeperRegistry {\n /// @notice Checks whether an address is whitelisted during oracle updates\n /// @param caller Address for which the whitelist should be checked\n /// @return Whether the address is trusted or not\n function isTrusted(address caller) external view returns (bool);\n}\n" + }, + "contracts/interfaces/ILiquidityGauge.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.7;\n\ninterface ILiquidityGauge {\n function deposit(\n uint256 _value,\n address _addr,\n // solhint-disable-next-line\n bool _claim_rewards\n ) external;\n\n function withdraw(\n uint256 _value,\n // solhint-disable-next-line\n bool _claim_rewards\n ) external;\n\n // solhint-disable-next-line\n function claim_rewards(address _addr, address _receiver) external;\n\n // solhint-disable-next-line\n function claimable_reward(address _addr, address _reward_token) external view returns (uint256 amount);\n\n /// @dev Only for testing purposes\n // solhint-disable-next-line\n function deposit_reward_token(address _rewardToken, uint256 _amount) external;\n}\n" + }, + "contracts/interfaces/IOracle.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\nimport \"./ITreasury.sol\";\nimport \"@chainlink/contracts/src/v0.8/interfaces/AggregatorV3Interface.sol\";\n\n/// @title IOracle\n/// @author Angle Labs, Inc.\n/// @notice Interface for the `Oracle` contract\n/// @dev This interface only contains functions of the contract which are called by other contracts\n/// of this module\ninterface IOracle {\n /// @notice Reads the rate from the Chainlink circuit and other data provided\n /// @return quoteAmount The current rate between the in-currency and out-currency in the base\n /// of the out currency\n /// @dev For instance if the out currency is EUR (and hence agEUR), then the base of the returned\n /// value is 10**18\n function read() external view returns (uint256);\n\n /// @notice Changes the treasury contract\n /// @param _treasury Address of the new treasury contract\n /// @dev This function can be called by an approved `VaultManager` contract which can call\n /// this function after being requested to do so by a `treasury` contract\n /// @dev In some situations (like reactor contracts), the `VaultManager` may not directly be linked\n /// to the `oracle` contract and as such we may need governors to be able to call this function as well\n function setTreasury(address _treasury) external;\n\n /// @notice Reference to the `treasury` contract handling this `VaultManager`\n function treasury() external view returns (ITreasury treasury);\n\n /// @notice Array with the list of Chainlink feeds in the order in which they are read\n function circuitChainlink() external view returns (AggregatorV3Interface[] memory);\n}\n" + }, + "contracts/interfaces/ISwapper.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\nimport \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\n\n/// @title ISwapper\n/// @author Angle Labs, Inc.\n/// @notice Interface for Swapper contracts\n/// @dev This interface defines the key functions `Swapper` contracts should have when interacting with\n/// Angle\ninterface ISwapper {\n /// @notice Notifies a contract that an address should be given `outToken` from `inToken`\n /// @param inToken Address of the token received\n /// @param outToken Address of the token to obtain\n /// @param outTokenRecipient Address to which the outToken should be sent\n /// @param outTokenOwed Minimum amount of outToken the `outTokenRecipient` address should have at the end of the call\n /// @param inTokenObtained Amount of collateral obtained by a related address prior\n /// to the call to this function\n /// @param data Extra data needed (to encode Uniswap swaps for instance)\n function swap(\n IERC20 inToken,\n IERC20 outToken,\n address outTokenRecipient,\n uint256 outTokenOwed,\n uint256 inTokenObtained,\n bytes calldata data\n ) external;\n}\n" + }, + "contracts/interfaces/ITreasury.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\nimport \"./IAgToken.sol\";\nimport \"./ICoreBorrow.sol\";\nimport \"./IFlashAngle.sol\";\n\n/// @title ITreasury\n/// @author Angle Labs, Inc.\n/// @notice Interface for the `Treasury` contract\n/// @dev This interface only contains functions of the `Treasury` which are called by other contracts\n/// of this module\ninterface ITreasury {\n /// @notice Stablecoin handled by this `treasury` contract\n function stablecoin() external view returns (IAgToken);\n\n /// @notice Checks whether a given address has the governor role\n /// @param admin Address to check\n /// @return Whether the address has the governor role\n /// @dev Access control is only kept in the `CoreBorrow` contract\n function isGovernor(address admin) external view returns (bool);\n\n /// @notice Checks whether a given address has the guardian or the governor role\n /// @param admin Address to check\n /// @return Whether the address has the guardian or the governor role\n /// @dev Access control is only kept in the `CoreBorrow` contract which means that this function\n /// queries the `CoreBorrow` contract\n function isGovernorOrGuardian(address admin) external view returns (bool);\n\n /// @notice Checks whether a given address has well been initialized in this contract\n /// as a `VaultManager`\n /// @param _vaultManager Address to check\n /// @return Whether the address has been initialized or not\n function isVaultManager(address _vaultManager) external view returns (bool);\n\n /// @notice Sets a new flash loan module for this stablecoin\n /// @param _flashLoanModule Reference to the new flash loan module\n /// @dev This function removes the minting right to the old flash loan module and grants\n /// it to the new module\n function setFlashLoanModule(address _flashLoanModule) external;\n\n /// @notice Gets the vault manager list\n function vaultManagerList(uint256 i) external returns (address);\n}\n" + }, + "contracts/interfaces/IVaultManager.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\nimport \"@openzeppelin/contracts/interfaces/IERC721Metadata.sol\";\nimport \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\nimport \"./ITreasury.sol\";\nimport \"./IOracle.sol\";\n\n// ========================= Key Structs and Enums =============================\n\n/// @notice Parameters associated to a given `VaultManager` contract: these all correspond\n/// to parameters which signification is detailed in the `VaultManagerStorage` file\nstruct VaultParameters {\n uint256 debtCeiling;\n uint64 collateralFactor;\n uint64 targetHealthFactor;\n uint64 interestRate;\n uint64 liquidationSurcharge;\n uint64 maxLiquidationDiscount;\n bool whitelistingActivated;\n uint256 baseBoost;\n}\n\n/// @notice Data stored to track someone's loan (or equivalently called position)\nstruct Vault {\n // Amount of collateral deposited in the vault, in collateral decimals. For example, if the collateral\n // is USDC with 6 decimals, then `collateralAmount` will be in base 10**6\n uint256 collateralAmount;\n // Normalized value of the debt (that is to say of the stablecoins borrowed). It is expressed\n // in the base of Angle stablecoins (i.e. `BASE_TOKENS = 10**18`)\n uint256 normalizedDebt;\n}\n\n/// @notice For a given `vaultID`, this encodes a liquidation opportunity that is to say details about the maximum\n/// amount that could be repaid by liquidating the position\n/// @dev All the values are null in the case of a vault which cannot be liquidated under these conditions\nstruct LiquidationOpportunity {\n // Maximum stablecoin amount that can be repaid upon liquidating the vault\n uint256 maxStablecoinAmountToRepay;\n // Collateral amount given to the person in the case where the maximum amount to repay is given\n uint256 maxCollateralAmountGiven;\n // Threshold value of stablecoin amount to repay: it is ok for a liquidator to repay below threshold,\n // but if this threshold is non null and the liquidator wants to repay more than threshold, it should repay\n // the max stablecoin amount given in this vault\n uint256 thresholdRepayAmount;\n // Discount proposed to the liquidator on the collateral\n uint256 discount;\n // Amount of debt in the vault\n uint256 currentDebt;\n}\n\n/// @notice Data stored during a liquidation process to keep in memory what's due to a liquidator and some\n/// essential data for vaults being liquidated\nstruct LiquidatorData {\n // Current amount of stablecoins the liquidator should give to the contract\n uint256 stablecoinAmountToReceive;\n // Current amount of collateral the contract should give to the liquidator\n uint256 collateralAmountToGive;\n // Bad debt accrued across the liquidation process\n uint256 badDebtFromLiquidation;\n // Oracle value (in stablecoin base) at the time of the liquidation\n uint256 oracleValue;\n // Value of the `interestAccumulator` at the time of the call\n uint256 newInterestAccumulator;\n}\n\n/// @notice Data to track during a series of action the amount to give or receive in stablecoins and collateral\n/// to the caller or associated addresses\nstruct PaymentData {\n // Stablecoin amount the contract should give\n uint256 stablecoinAmountToGive;\n // Stablecoin amount owed to the contract\n uint256 stablecoinAmountToReceive;\n // Collateral amount the contract should give\n uint256 collateralAmountToGive;\n // Collateral amount owed to the contract\n uint256 collateralAmountToReceive;\n}\n\n/// @notice Actions possible when composing calls to the different entry functions proposed\nenum ActionType {\n createVault,\n closeVault,\n addCollateral,\n removeCollateral,\n repayDebt,\n borrow,\n getDebtIn,\n permit\n}\n\n// ========================= Interfaces =============================\n\n/// @title IVaultManagerFunctions\n/// @author Angle Labs, Inc.\n/// @notice Interface for the `VaultManager` contract\n/// @dev This interface only contains functions of the contract which are called by other contracts\n/// of this module (without getters)\ninterface IVaultManagerFunctions {\n /// @notice Accrues interest accumulated across all vaults to the surplus and sends the surplus to the treasury\n /// @return surplusValue Value of the surplus communicated to the `Treasury`\n /// @return badDebtValue Value of the bad debt communicated to the `Treasury`\n /// @dev `surplus` and `badDebt` should be reset to 0 once their current value have been given to the `treasury` contract\n function accrueInterestToTreasury() external returns (uint256 surplusValue, uint256 badDebtValue);\n\n /// @notice Removes debt from a vault after being requested to do so by another `VaultManager` contract\n /// @param vaultID ID of the vault to remove debt from\n /// @param amountStablecoins Amount of stablecoins to remove from the debt: this amount is to be converted to an\n /// internal debt amount\n /// @param senderBorrowFee Borrowing fees from the contract which requested this: this is to make sure that people are not\n /// arbitraging difference in minting fees\n /// @param senderRepayFee Repay fees from the contract which requested this: this is to make sure that people are not arbitraging\n /// differences in repay fees\n /// @dev This function can only be called from a vaultManager registered in the same Treasury\n function getDebtOut(\n uint256 vaultID,\n uint256 amountStablecoins,\n uint256 senderBorrowFee,\n uint256 senderRepayFee\n ) external;\n\n /// @notice Gets the current debt of a vault\n /// @param vaultID ID of the vault to check\n /// @return Debt of the vault\n function getVaultDebt(uint256 vaultID) external view returns (uint256);\n\n /// @notice Gets the total debt across all vaults\n /// @return Total debt across all vaults, taking into account the interest accumulated\n /// over time\n function getTotalDebt() external view returns (uint256);\n\n /// @notice Sets the treasury contract\n /// @param _treasury New treasury contract\n /// @dev All required checks when setting up a treasury contract are performed in the contract\n /// calling this function\n function setTreasury(address _treasury) external;\n\n /// @notice Creates a vault\n /// @param toVault Address for which the va\n /// @return vaultID ID of the vault created\n /// @dev This function just creates the vault without doing any collateral or\n function createVault(address toVault) external returns (uint256);\n\n /// @notice Allows composability between calls to the different entry points of this module. Any user calling\n /// this function can perform any of the allowed actions in the order of their choice\n /// @param actions Set of actions to perform\n /// @param datas Data to be decoded for each action: it can include like the `vaultID` or the `stablecoinAmount` to borrow\n /// @param from Address from which stablecoins will be taken if one action includes burning stablecoins. This address\n /// should either be the `msg.sender` or be approved by the latter\n /// @param to Address to which stablecoins and/or collateral will be sent in case of\n /// @param who Address of the contract to handle in case of repayment of stablecoins from received collateral\n /// @param repayData Data to pass to the repayment contract in case of\n /// @return paymentData Struct containing the accounting changes from the protocol's perspective (like how much of collateral\n /// or how much has been received). Note that the values in the struct are not aggregated and you could have in the output\n /// a positive amount of stablecoins to receive as well as a positive amount of stablecoins to give\n /// @dev This function is optimized to reduce gas cost due to payment from or to the user and that expensive calls\n /// or computations (like `oracleValue`) are done only once\n /// @dev When specifying `vaultID` in `data`, it is important to know that if you specify `vaultID = 0`, it will simply\n /// use the latest `vaultID`. This is the default behavior, and unless you're engaging into some complex protocol actions\n /// it is encouraged to use `vaultID = 0` only when the first action of the batch is `createVault`\n function angle(\n ActionType[] memory actions,\n bytes[] memory datas,\n address from,\n address to,\n address who,\n bytes memory repayData\n ) external returns (PaymentData memory paymentData);\n\n /// @notice This function is a wrapper built on top of the function above. It enables users to interact with the contract\n /// without having to provide `who` and `repayData` parameters\n function angle(\n ActionType[] memory actions,\n bytes[] memory datas,\n address from,\n address to\n ) external returns (PaymentData memory paymentData);\n\n /// @notice Initializes the `VaultManager` contract\n /// @param _treasury Treasury address handling the contract\n /// @param _collateral Collateral supported by this contract\n /// @param _oracle Oracle contract used\n /// @param _symbol Symbol used to define the `VaultManager` name and symbol\n /// @dev The parameters and the oracle are the only elements which could be modified once the\n /// contract has been initialized\n /// @dev For the contract to be fully initialized, governance needs to set the parameters for the liquidation\n /// boost\n function initialize(\n ITreasury _treasury,\n IERC20 _collateral,\n IOracle _oracle,\n VaultParameters calldata params,\n string memory _symbol\n ) external;\n\n /// @notice Minimum amount of debt a vault can have, expressed in `BASE_TOKENS` that is to say the base of the agTokens\n function dust() external view returns (uint256);\n\n /// @notice Pauses external permissionless functions of the contract\n function togglePause() external;\n}\n\n/// @title IVaultManagerStorage\n/// @author Angle Labs, Inc.\n/// @notice Interface for the `VaultManager` contract\n/// @dev This interface contains getters of the contract's public variables used by other contracts\n/// of this module\ninterface IVaultManagerStorage {\n /// @notice Encodes the maximum ratio stablecoin/collateral a vault can have before being liquidated. It's what\n /// determines the minimum collateral ratio of a position\n function collateralFactor() external view returns (uint64);\n\n /// @notice Stablecoin handled by this contract. Another `VaultManager` contract could have\n /// the same rights as this `VaultManager` on the stablecoin contract\n function stablecoin() external view returns (IAgToken);\n\n /// @notice Reference to the `treasury` contract handling this `VaultManager`\n function treasury() external view returns (ITreasury);\n\n /// @notice Oracle contract to get access to the price of the collateral with respect to the stablecoin\n function oracle() external view returns (IOracle);\n\n /// @notice The `interestAccumulator` variable keeps track of the interest that should accrue to the protocol.\n /// The stored value is not necessarily the true value: this one is recomputed every time an action takes place\n /// within the protocol. It is in base `BASE_INTEREST`\n function interestAccumulator() external view returns (uint256);\n\n /// @notice Reference to the collateral handled by this `VaultManager`\n function collateral() external view returns (IERC20);\n\n /// @notice Total normalized amount of stablecoins borrowed, not taking into account the potential bad debt accumulated\n /// This value is expressed in the base of Angle stablecoins (`BASE_TOKENS = 10**18`)\n function totalNormalizedDebt() external view returns (uint256);\n\n /// @notice Maximum amount of stablecoins that can be issued with this contract. It is expressed in `BASE_TOKENS`\n function debtCeiling() external view returns (uint256);\n\n /// @notice Maps a `vaultID` to its data (namely collateral amount and normalized debt)\n function vaultData(uint256 vaultID) external view returns (uint256 collateralAmount, uint256 normalizedDebt);\n\n /// @notice ID of the last vault created. The `vaultIDCount` variables serves as a counter to generate a unique\n /// `vaultID` for each vault: it is like `tokenID` in basic ERC721 contracts\n function vaultIDCount() external view returns (uint256);\n}\n\n/// @title IVaultManager\n/// @author Angle Labs, Inc.\n/// @notice Interface for the `VaultManager` contract\ninterface IVaultManager is IVaultManagerFunctions, IVaultManagerStorage, IERC721Metadata {\n function isApprovedOrOwner(address spender, uint256 vaultID) external view returns (bool);\n}\n\n/// @title IVaultManagerListing\n/// @author Angle Labs, Inc.\n/// @notice Interface for the `VaultManagerListing` contract\ninterface IVaultManagerListing is IVaultManager {\n /// @notice Get the collateral owned by `user` in the contract\n /// @dev This function effectively sums the collateral amounts of all the vaults owned by `user`\n function getUserCollateral(address user) external view returns (uint256);\n}\n" + }, + "contracts/keeperMulticall/KeeperMulticall.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\nimport \"@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/access/AccessControlUpgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol\";\nimport \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\nimport \"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\";\nimport \"./RevertReasonParser.sol\";\n\n/// @title KeeperMulticall\n/// @notice Allows an authorized caller (keeper) to execute multiple actions in a single tx.\n/// @author Angle Labs, Inc.\n/// @dev Special features:\n/// - ability to pay the miner (for private Flashbots transactions)\n/// - swap tokens through 1inch\n/// @dev Tx need to be encoded as an array of Action. The flag `isDelegateCall` is used for calling functions within this same contract\ncontract KeeperMulticall is Initializable, AccessControlUpgradeable {\n using SafeERC20 for IERC20;\n\n bytes32 public constant KEEPER_ROLE = keccak256(\"KEEPER_ROLE\");\n\n //solhint-disable-next-line\n address private constant _oneInch = 0x1111111254fb6c44bAC0beD2854e76F90643097d;\n\n struct Action {\n address target;\n bytes data;\n bool isDelegateCall;\n }\n\n event LogAction(address indexed target, bytes data);\n event SentToMiner(uint256 indexed value);\n event Recovered(address indexed tokenAddress, address indexed to, uint256 amount);\n\n error AmountOutTooLow(uint256 amount, uint256 min);\n error BalanceTooLow();\n error FlashbotsErrorPayingMiner(uint256 value);\n error IncompatibleLengths();\n error RevertBytes();\n error WrongAmount();\n error ZeroAddress();\n\n constructor() initializer {}\n\n function initialize(address keeper) external initializer {\n __AccessControl_init();\n\n _setupRole(KEEPER_ROLE, keeper);\n _setRoleAdmin(KEEPER_ROLE, KEEPER_ROLE);\n }\n\n /// @notice Allows an authorized keeper to execute multiple actions in a single step\n /// @param actions Actions to be executed\n /// @param percentageToMiner Percentage to pay to miner expressed in bps (10000)\n /// @dev This is the main entry point for actions to be executed. The `isDelegateCall` flag is used for calling function inside this `KeeperMulticall` contract,\n /// if we call other contracts, the flag should be false\n function executeActions(\n Action[] memory actions,\n uint256 percentageToMiner\n ) external payable onlyRole(KEEPER_ROLE) returns (bytes[] memory) {\n uint256 numberOfActions = actions.length;\n if (numberOfActions == 0) revert IncompatibleLengths();\n\n bytes[] memory returnValues = new bytes[](numberOfActions + 1);\n\n uint256 balanceBefore = address(this).balance;\n\n for (uint256 i; i < numberOfActions; ++i) {\n returnValues[i] = _executeAction(actions[i]);\n }\n\n if (percentageToMiner != 0) {\n if (percentageToMiner >= 10000) revert WrongAmount();\n uint256 balanceAfter = address(this).balance;\n if (balanceAfter > balanceBefore) {\n uint256 amountToMiner = ((balanceAfter - balanceBefore) * percentageToMiner) / 10000;\n returnValues[numberOfActions] = payFlashbots(amountToMiner);\n }\n }\n\n return returnValues;\n }\n\n /// @notice Gets the action address and data and executes it\n /// @param action Action to be executed\n function _executeAction(Action memory action) internal returns (bytes memory) {\n bool success;\n bytes memory response;\n\n if (action.isDelegateCall) {\n //solhint-disable-next-line\n (success, response) = action.target.delegatecall(action.data);\n } else {\n //solhint-disable-next-line\n (success, response) = action.target.call(action.data);\n }\n\n require(success, RevertReasonParser.parse(response, \"action reverted: \"));\n emit LogAction(action.target, action.data);\n return response;\n }\n\n /// @notice Ability to pay miner directly. Used for Flashbots to execute private transactions\n /// @param value Value to be sent\n function payFlashbots(uint256 value) public payable onlyRole(KEEPER_ROLE) returns (bytes memory) {\n //solhint-disable-next-line\n (bool success, bytes memory response) = block.coinbase.call{ value: value }(\"\");\n if (!success) revert FlashbotsErrorPayingMiner(value);\n emit SentToMiner(value);\n return response;\n }\n\n /// @notice Used to check the balances the token holds for each token. If we don't have enough of a token, we revert the tx\n /// @param tokens Array of tokens to check\n /// @param minBalances Array of balances for each token\n function finalBalanceCheck(IERC20[] memory tokens, uint256[] memory minBalances) external view returns (bool) {\n uint256 tokensLength = tokens.length;\n if (tokensLength == 0 || tokensLength != minBalances.length) revert IncompatibleLengths();\n\n for (uint256 i; i < tokensLength; ++i) {\n if (address(tokens[i]) == 0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE) {\n if (address(this).balance < minBalances[i]) revert BalanceTooLow();\n } else {\n if (tokens[i].balanceOf(address(this)) < minBalances[i]) revert BalanceTooLow();\n }\n }\n\n return true;\n }\n\n /// @notice Swap token to another through 1Inch\n /// @param minAmountOut Minimum amount of `out` token to receive for the swap to happen\n /// @param payload Bytes needed for 1Inch API\n function swapToken(uint256 minAmountOut, bytes memory payload) external onlyRole(KEEPER_ROLE) {\n //solhint-disable-next-line\n (bool success, bytes memory result) = _oneInch.call(payload);\n if (!success) _revertBytes(result);\n\n uint256 amountOut = abi.decode(result, (uint256));\n if (amountOut < minAmountOut) revert AmountOutTooLow(amountOut, minAmountOut);\n }\n\n /// @notice Copied from 1Inch contract, used to revert if there is an error\n function _revertBytes(bytes memory errMsg) internal pure {\n if (errMsg.length != 0) {\n //solhint-disable-next-line\n assembly {\n revert(add(32, errMsg), mload(errMsg))\n }\n }\n revert RevertBytes();\n }\n\n /// @notice Approve a `spender` for `token`\n /// @param token Address of the token to approve\n /// @param spender Address of the spender to approve\n /// @param amount Amount to approve\n function approve(IERC20 token, address spender, uint256 amount) external onlyRole(KEEPER_ROLE) {\n uint256 currentAllowance = token.allowance(address(this), spender);\n if (currentAllowance < amount) {\n token.safeIncreaseAllowance(spender, amount - currentAllowance);\n } else if (currentAllowance > amount) {\n token.safeDecreaseAllowance(spender, currentAllowance - amount);\n }\n }\n\n receive() external payable {}\n\n /// @notice Withdraw stuck funds\n /// @param token Address of the token to recover\n /// @param receiver Address where to send the tokens\n /// @param amount Amount to recover\n function withdrawStuckFunds(address token, address receiver, uint256 amount) external onlyRole(KEEPER_ROLE) {\n if (receiver == address(0)) revert ZeroAddress();\n if (token == 0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE) {\n payable(receiver).transfer(amount);\n } else {\n IERC20(token).safeTransfer(receiver, amount);\n }\n\n emit Recovered(token, receiver, amount);\n }\n}\n" + }, + "contracts/keeperMulticall/MulticallWithFailure.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.12;\n\n/// @title MultiCallWithFailure\n/// @author Angle Labs, Inc.\n/// @notice Multicall contract allowing subcalls to fail without reverting the entire call\ncontract MultiCallWithFailure {\n error SubcallFailed();\n\n struct Call {\n address target;\n bytes data;\n bool canFail;\n }\n\n function multiCall(Call[] memory calls) external view returns (bytes[] memory) {\n bytes[] memory results = new bytes[](calls.length);\n\n for (uint256 i; i < calls.length; ++i) {\n (bool success, bytes memory result) = calls[i].target.staticcall(calls[i].data);\n if (!calls[i].canFail) {\n if (!success) {\n revert SubcallFailed();\n }\n }\n results[i] = result;\n }\n\n return results;\n }\n}\n" + }, + "contracts/keeperMulticall/RevertReasonParser.sol": { + "content": "// SPDX-License-Identifier: GNU-3\n\npragma solidity ^0.8.12;\n\n/// @title RevertReasonParser\n/// @author 1Inch team, taken from:\n/// - https://docs.1inch.io/docs/limit-order-protocol/smart-contract/libraries/RevertReasonParser/\n/// - https://etherscan.io/address/0x1111111254fb6c44bAC0beD2854e76F90643097d#code\nlibrary RevertReasonParser {\n bytes4 private constant _PANIC_SELECTOR = bytes4(keccak256(\"Panic(uint256)\"));\n bytes4 private constant _ERROR_SELECTOR = bytes4(keccak256(\"Error(string)\"));\n\n function parse(bytes memory data, string memory prefix) internal pure returns (string memory) {\n if (data.length >= 4) {\n bytes4 selector;\n //solhint-disable-next-line\n assembly {\n selector := mload(add(data, 0x20))\n }\n\n // 68 = 4-byte selector + 32 bytes offset + 32 bytes length\n if (selector == _ERROR_SELECTOR && data.length >= 68) {\n uint256 offset;\n bytes memory reason;\n // solhint-disable no-inline-assembly\n assembly {\n // 36 = 32 bytes data length + 4-byte selector\n offset := mload(add(data, 36))\n reason := add(data, add(36, offset))\n }\n /*\n revert reason is padded up to 32 bytes with ABI encoder: Error(string)\n also sometimes there is extra 32 bytes of zeros padded in the end:\n https://github.com/ethereum/solidity/issues/10170\n because of that we can't check for equality and instead check\n that offset + string length + extra 36 bytes is less than overall data length\n */\n require(data.length >= 36 + offset + reason.length, \"Invalid revert reason\");\n return string(abi.encodePacked(prefix, \"Error(\", reason, \")\"));\n }\n // 36 = 4-byte selector + 32 bytes integer\n else if (selector == _PANIC_SELECTOR && data.length == 36) {\n uint256 code;\n // solhint-disable no-inline-assembly\n assembly {\n // 36 = 32 bytes data length + 4-byte selector\n code := mload(add(data, 36))\n }\n return string(abi.encodePacked(prefix, \"Panic(\", _toHex(code), \")\"));\n }\n }\n\n return string(abi.encodePacked(prefix, \"Unknown(\", _toHex(data), \")\"));\n }\n\n function _toHex(uint256 value) private pure returns (string memory) {\n return _toHex(abi.encodePacked(value));\n }\n\n function _toHex(bytes memory data) private pure returns (string memory) {\n bytes16 alphabet = 0x30313233343536373839616263646566;\n bytes memory str = new bytes(2 + data.length * 2);\n str[0] = \"0\";\n str[1] = \"x\";\n for (uint256 i; i < data.length; ++i) {\n str[2 * i + 2] = alphabet[uint8(data[i] >> 4)];\n str[2 * i + 3] = alphabet[uint8(data[i] & 0x0f)];\n }\n return string(str);\n }\n}\n" + }, + "contracts/mock/Mock1Inch.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.12;\n\nimport \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\nimport \"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\";\n\ncontract Mock1Inch {\n using SafeERC20 for IERC20;\n\n function swap(address tokenIn, uint256 amountIn, address to, address tokenOut, uint256 amountOut) external {\n IERC20(tokenIn).safeTransferFrom(msg.sender, to, amountIn);\n if (tokenOut == 0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE) {\n //solhint-disable-next-line\n (bool sent, bytes memory data) = msg.sender.call{ value: amountOut }(\"\");\n data;\n require(sent, \"Failed to send Ether\");\n } else {\n IERC20(tokenOut).safeTransferFrom(to, msg.sender, amountOut);\n }\n }\n\n receive() external payable {}\n}\n" + }, + "contracts/mock/MockAnything.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.12;\n\ncontract MockAnything {\n uint256 public stateVar = 1;\n\n error CustomError();\n error CustomErrorWithValue(uint256);\n\n function fail(uint256 value) external view returns (uint256) {\n stateVar;\n if (value < 10) {\n revert CustomError();\n }\n if (value < 20) {\n revert CustomErrorWithValue(value);\n }\n return value + 1;\n }\n\n function modifyState(uint256 value) external {\n stateVar = value;\n }\n}\n" + }, + "contracts/mock/MockChainlinkOracle.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.7;\n\ninterface MockAggregatorV3Interface {\n function decimals() external view returns (uint8);\n\n function description() external view returns (string memory);\n\n function version() external view returns (uint256);\n\n function getRoundData(\n uint80 _roundId\n )\n external\n view\n returns (uint80 roundId, int256 answer, uint256 startedAt, uint256 updatedAt, uint80 answeredInRound);\n\n function latestRoundData()\n external\n view\n returns (uint80 roundId, int256 answer, uint256 startedAt, uint256 updatedAt, uint80 answeredInRound);\n}\n\ncontract MockChainlinkOracle is MockAggregatorV3Interface {\n uint80 public roundId = 0;\n uint8 public keyDecimals = 0;\n\n struct Entry {\n uint80 roundId;\n int256 answer;\n uint256 startedAt;\n uint256 updatedAt;\n uint80 answeredInRound;\n }\n\n mapping(uint256 => Entry) public entries;\n\n bool public latestRoundDataShouldRevert;\n\n string public desc;\n\n constructor() {}\n\n // Mock setup function\n function setLatestAnswer(int256 answer, uint256 timestamp) external {\n roundId++;\n entries[roundId] = Entry({\n roundId: roundId,\n answer: answer,\n startedAt: timestamp,\n updatedAt: timestamp,\n answeredInRound: roundId\n });\n }\n\n function setLatestAnswerWithRound(int256 answer, uint256 timestamp, uint80 _roundId) external {\n roundId = _roundId;\n entries[roundId] = Entry({\n roundId: roundId,\n answer: answer,\n startedAt: timestamp,\n updatedAt: timestamp,\n answeredInRound: roundId\n });\n }\n\n function setLatestAnswerRevert(int256 answer, uint256 timestamp) external {\n roundId++;\n entries[roundId] = Entry({\n roundId: roundId,\n answer: answer,\n startedAt: timestamp,\n updatedAt: timestamp,\n answeredInRound: roundId - 1\n });\n }\n\n function setLatestRoundDataShouldRevert(bool _shouldRevert) external {\n latestRoundDataShouldRevert = _shouldRevert;\n }\n\n function setDecimals(uint8 _decimals) external {\n keyDecimals = _decimals;\n }\n\n function setDescritpion(string memory _desc) external {\n desc = _desc;\n }\n\n function description() external view override returns (string memory) {\n return desc;\n }\n\n function version() external view override returns (uint256) {\n roundId;\n return 0;\n }\n\n function latestRoundData() external view override returns (uint80, int256, uint256, uint256, uint80) {\n if (latestRoundDataShouldRevert) {\n revert(\"latestRoundData reverted\");\n }\n return getRoundData(uint80(roundId));\n }\n\n function decimals() external view override returns (uint8) {\n return keyDecimals;\n }\n\n function getRoundData(uint80 _roundId) public view override returns (uint80, int256, uint256, uint256, uint80) {\n Entry memory entry = entries[_roundId];\n // Emulate a Chainlink aggregator\n require(entry.updatedAt > 0, \"No data present\");\n return (entry.roundId, entry.answer, entry.startedAt, entry.updatedAt, entry.answeredInRound);\n }\n}\n" + }, + "contracts/mock/MockCoreBorrow.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\nimport \"../interfaces/ICoreBorrow.sol\";\nimport \"../interfaces/IFlashAngle.sol\";\nimport \"../interfaces/ITreasury.sol\";\n\ncontract MockCoreBorrow is ICoreBorrow {\n mapping(address => bool) public flashLoaners;\n mapping(address => bool) public governors;\n mapping(address => bool) public guardians;\n\n function isFlashLoanerTreasury(address treasury) external view override returns (bool) {\n return flashLoaners[treasury];\n }\n\n function isGovernor(address admin) external view override returns (bool) {\n return governors[admin];\n }\n\n function isGovernorOrGuardian(address admin) external view override returns (bool) {\n return governors[admin] || guardians[admin];\n }\n\n function toggleGovernor(address admin) external {\n governors[admin] = !governors[admin];\n }\n\n function toggleGuardian(address admin) external {\n guardians[admin] = !guardians[admin];\n }\n\n function toggleFlashLoaners(address admin) external {\n flashLoaners[admin] = !flashLoaners[admin];\n }\n\n function addStablecoinSupport(IFlashAngle flashAngle, address _treasury) external {\n flashAngle.addStablecoinSupport(_treasury);\n }\n\n function removeStablecoinSupport(IFlashAngle flashAngle, address _treasury) external {\n flashAngle.removeStablecoinSupport(_treasury);\n }\n\n function setCore(IFlashAngle flashAngle, address _core) external {\n flashAngle.setCore(_core);\n }\n\n function setFlashLoanModule(ITreasury _treasury, address _flashLoanModule) external {\n _treasury.setFlashLoanModule(_flashLoanModule);\n }\n}\n" + }, + "contracts/mock/MockERC1271.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.12;\n\nimport \"../interfaces/external/IERC1271.sol\";\n\ncontract MockERC1271 is IERC1271 {\n uint256 public mode = 0;\n\n function setMode(uint256 _mode) public {\n mode = _mode;\n }\n\n /// @notice Returns whether the provided signature is valid for the provided data\n /// @dev MUST return the bytes4 magic value 0x1626ba7e when function passes.\n /// MUST NOT modify state (using STATICCALL for solc < 0.5, view modifier for solc > 0.5).\n /// MUST allow external calls.\n /// @return magicValue The bytes4 magic value 0x1626ba7e\n function isValidSignature(bytes32, bytes memory) external view returns (bytes4 magicValue) {\n if (mode == 1) magicValue = 0x1626ba7e;\n }\n}\n" + }, + "contracts/mock/MockERC721Receiver.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (token/ERC721/utils/ERC721Holder.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Implementation of the {IERC721Receiver} interface.\n *\n * Accepts all token transfers.\n * Make sure the contract is able to use its token with {IERC721-safeTransferFrom}, {IERC721-approve} or {IERC721-setApprovalForAll}.\n */\ncontract MockERC721Receiver {\n uint256 public mode = 0;\n\n function setMode(uint256 _mode) public {\n mode = _mode;\n }\n\n function onERC721Received(address, address, uint256, bytes memory) public view returns (bytes4) {\n require(mode != 1, \"0x1111111\");\n if (mode == 2) return this.setMode.selector;\n return this.onERC721Received.selector;\n }\n}\n" + }, + "contracts/mock/MockEulerPool.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\nimport \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\n\ncontract MockEulerPool {\n IERC20 public collateral;\n uint256 public poolSize;\n //solhint-disable-next-line\n uint256 public MAX_SANE_AMOUNT;\n\n mapping(address => uint256) public users;\n uint256 public interestRateAccumulator;\n\n constructor(IERC20 collateral_, uint256 poolSize_) {\n collateral = collateral_;\n poolSize = poolSize_;\n interestRateAccumulator = 10 ** 18;\n MAX_SANE_AMOUNT = type(uint112).max;\n }\n\n function setPoolSize(uint256 poolSize_) external {\n uint256 balance = collateral.balanceOf(address(this));\n poolSize = poolSize_;\n if (balance > poolSize_) collateral.transfer(msg.sender, balance - poolSize_);\n if (balance < poolSize_) collateral.transferFrom(msg.sender, address(this), poolSize_ - balance);\n }\n\n function setInterestRateAccumulator(uint256 interestRateAccumulator_) external {\n interestRateAccumulator = interestRateAccumulator_;\n }\n\n //solhint-disable-next-line\n function setMAXSANEAMOUNT(uint256 MAX_SANE_AMOUNT_) external {\n MAX_SANE_AMOUNT = MAX_SANE_AMOUNT_;\n }\n\n function balanceOfUnderlying(address account) external view returns (uint256) {\n return (users[account] * interestRateAccumulator) / 10 ** 18;\n }\n\n function deposit(uint256, uint256 amount) external {\n users[msg.sender] += (amount * 10 ** 18) / interestRateAccumulator;\n poolSize += amount;\n collateral.transferFrom(msg.sender, address(this), amount);\n }\n\n function withdraw(uint256, uint256 amount) external {\n if (amount == type(uint256).max) amount = (users[msg.sender] * interestRateAccumulator) / 10 ** 18;\n\n require(amount <= poolSize, \"4\");\n users[msg.sender] -= (amount * 10 ** 18) / interestRateAccumulator;\n collateral.transfer(msg.sender, amount);\n }\n}\n" + }, + "contracts/mock/MockFlashLoanModule.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\nimport \"../interfaces/IFlashAngle.sol\";\nimport \"../interfaces/ICoreBorrow.sol\";\n\ncontract MockFlashLoanModule is IFlashAngle {\n ICoreBorrow public override core;\n mapping(address => bool) public stablecoinsSupported;\n mapping(IAgToken => uint256) public interestAccrued;\n uint256 public surplusValue;\n\n constructor(ICoreBorrow _core) {\n core = _core;\n }\n\n function accrueInterestToTreasury(IAgToken stablecoin) external override returns (uint256 balance) {\n balance = surplusValue;\n interestAccrued[stablecoin] += balance;\n }\n\n function addStablecoinSupport(address _treasury) external override {\n stablecoinsSupported[_treasury] = true;\n }\n\n function removeStablecoinSupport(address _treasury) external override {\n stablecoinsSupported[_treasury] = false;\n }\n\n function setCore(address _core) external override {\n core = ICoreBorrow(_core);\n }\n\n function setSurplusValue(uint256 _surplusValue) external {\n surplusValue = _surplusValue;\n }\n}\n" + }, + "contracts/mock/MockFlashLoanReceiver.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.7;\n\nimport \"@openzeppelin/contracts/token/ERC20/ERC20.sol\";\n\nimport \"@openzeppelin/contracts/interfaces/IERC3156FlashBorrower.sol\";\n\nimport \"@openzeppelin/contracts/interfaces/IERC3156FlashLender.sol\";\n\ncontract MockFlashLoanReceiver is IERC3156FlashBorrower {\n bytes32 public constant CALLBACK_SUCCESS = keccak256(\"ERC3156FlashBorrower.onFlashLoan\");\n\n constructor() {}\n\n function onFlashLoan(\n address,\n address token,\n uint256 amount,\n uint256 fee,\n bytes calldata data\n ) external override returns (bytes32) {\n IERC20(token).approve(msg.sender, amount + fee);\n if (amount >= 10 ** 21) return keccak256(\"error\");\n if (amount == 2 * 10 ** 18) {\n IERC3156FlashLender(msg.sender).flashLoan(IERC3156FlashBorrower(address(this)), token, amount, data);\n return keccak256(\"reentrant\");\n } else return CALLBACK_SUCCESS;\n }\n}\n" + }, + "contracts/mock/MockInterestRateComputer.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\ncontract MockInterestRateComputer {\n uint256 public interestRate;\n uint256 public interestAccumulator;\n uint256 public immutable baseInterest;\n uint256 public immutable halfBase;\n\n uint256 public constant WEEK = 7 * 86400;\n\n constructor(uint256 _baseInterest, uint256 _interestRate) {\n interestAccumulator = _baseInterest;\n baseInterest = _baseInterest;\n halfBase = _baseInterest / 2;\n interestRate = _interestRate;\n }\n\n function _calculateAngle(uint256 exp, uint256 _interestAccumulator) internal view returns (uint256) {\n uint256 ratePerSecond = interestRate;\n if (exp == 0 || ratePerSecond == 0) return _interestAccumulator;\n uint256 expMinusOne = exp - 1;\n uint256 expMinusTwo = exp > 2 ? exp - 2 : 0;\n uint256 basePowerTwo = (ratePerSecond * ratePerSecond) / baseInterest;\n uint256 basePowerThree = (basePowerTwo * ratePerSecond) / baseInterest;\n uint256 secondTerm = (exp * expMinusOne * basePowerTwo) / 2;\n uint256 thirdTerm = (exp * expMinusOne * expMinusTwo * basePowerThree) / 6;\n return (_interestAccumulator * (baseInterest + ratePerSecond * exp + secondTerm + thirdTerm)) / baseInterest;\n }\n\n function _calculateAave(uint256 exp, uint256 _interestAccumulator) internal view returns (uint256) {\n uint256 ratePerSecond = interestRate;\n if (exp == 0 || ratePerSecond == 0) return _interestAccumulator;\n uint256 expMinusOne = exp - 1;\n uint256 expMinusTwo = exp > 2 ? exp - 2 : 0;\n uint256 basePowerTwo = (ratePerSecond * ratePerSecond + halfBase) / baseInterest;\n uint256 basePowerThree = (basePowerTwo * ratePerSecond + halfBase) / baseInterest;\n uint256 secondTerm = (exp * expMinusOne * basePowerTwo) / 2;\n uint256 thirdTerm = (exp * expMinusOne * expMinusTwo * basePowerThree) / 6;\n return (_interestAccumulator * (baseInterest + ratePerSecond * exp + secondTerm + thirdTerm)) / baseInterest;\n }\n\n function _calculateCompound(uint256 exp, uint256 _interestAccumulator) internal view returns (uint256) {\n return _interestAccumulator * (baseInterest + interestRate * exp);\n }\n\n function _rpow(uint256 x, uint256 n, uint256 base) internal pure returns (uint256 z) {\n //solhint-disable-next-line\n assembly {\n switch x\n case 0 {\n switch n\n case 0 {\n z := base\n }\n default {\n z := 0\n }\n }\n default {\n switch mod(n, 2)\n case 0 {\n z := base\n }\n default {\n z := x\n }\n let half := div(base, 2) // for rounding.\n for {\n n := div(n, 2)\n } n {\n n := div(n, 2)\n } {\n let xx := mul(x, x)\n if iszero(eq(div(xx, x), x)) {\n revert(0, 0)\n }\n let xxRound := add(xx, half)\n if lt(xxRound, xx) {\n revert(0, 0)\n }\n x := div(xxRound, base)\n if mod(n, 2) {\n let zx := mul(z, x)\n if and(iszero(iszero(x)), iszero(eq(div(zx, x), z))) {\n revert(0, 0)\n }\n let zxRound := add(zx, half)\n if lt(zxRound, zx) {\n revert(0, 0)\n }\n z := div(zxRound, base)\n }\n }\n }\n }\n }\n\n function _calculateMaker(uint256 delta, uint256 _interestAccumulator) internal view returns (uint256) {\n return (_rpow(baseInterest + interestRate, delta, baseInterest) * _interestAccumulator) / baseInterest;\n }\n\n function calculateAngle(uint256 delta) external view returns (uint256) {\n return _calculateAngle(delta, interestAccumulator);\n }\n\n function calculateAave(uint256 delta) external view returns (uint256) {\n return _calculateAave(delta, interestAccumulator);\n }\n\n function calculateMaker(uint256 delta) external view returns (uint256) {\n return _calculateMaker(delta, interestAccumulator);\n }\n\n function calculateAngle1Year() external view returns (uint256) {\n uint256 _interestAccumulator = interestAccumulator;\n for (uint256 i; i < 52; ++i) {\n _interestAccumulator = _calculateAngle(WEEK, _interestAccumulator);\n }\n return _interestAccumulator;\n }\n\n function calculateAave1Year() external view returns (uint256) {\n uint256 _interestAccumulator = interestAccumulator;\n for (uint256 i; i < 52; ++i) {\n _interestAccumulator = _calculateAave(WEEK, _interestAccumulator);\n }\n return _interestAccumulator;\n }\n\n function calculateMaker1Year() external view returns (uint256) {\n uint256 _interestAccumulator = interestAccumulator;\n for (uint256 i; i < 52; ++i) {\n _interestAccumulator = _calculateMaker(WEEK, _interestAccumulator);\n }\n return _interestAccumulator;\n }\n\n function calculateAngle1YearDirect() external view returns (uint256) {\n uint256 _interestAccumulator = interestAccumulator;\n _interestAccumulator = _calculateAngle(52 * WEEK, _interestAccumulator);\n\n return _interestAccumulator;\n }\n\n function calculateAave1YearDirect() external view returns (uint256) {\n uint256 _interestAccumulator = interestAccumulator;\n _interestAccumulator = _calculateAave(52 * WEEK, _interestAccumulator);\n\n return _interestAccumulator;\n }\n\n function calculateMaker1YearDirect() external view returns (uint256) {\n uint256 _interestAccumulator = interestAccumulator;\n _interestAccumulator = _calculateMaker(52 * WEEK, _interestAccumulator);\n\n return _interestAccumulator;\n }\n\n function calculateCompound1YearDirect() external view returns (uint256) {\n uint256 _interestAccumulator = interestAccumulator;\n _interestAccumulator = _calculateCompound(52 * WEEK, _interestAccumulator);\n\n return _interestAccumulator;\n }\n}\n" + }, + "contracts/mock/MockKeeperMulticall.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.12;\n\nimport \"@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/access/AccessControlUpgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol\";\nimport \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\nimport \"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\";\n\ncontract MockKeeperMulticall is Initializable, AccessControlUpgradeable {\n using SafeERC20 for IERC20;\n\n bytes32 public constant KEEPER_ROLE = keccak256(\"KEEPER_ROLE\");\n\n //solhint-disable-next-line\n address private constant _oneInch = 0x1111111254fb6c44bAC0beD2854e76F90643097d;\n\n struct Action {\n address target;\n bytes data;\n bool isDelegateCall;\n }\n\n event LogAction(address indexed target, bytes data);\n event SentToMiner(uint256 indexed value);\n event Recovered(address indexed tokenAddress, address indexed to, uint256 amount);\n\n error AmountOutTooLow(uint256 amount, uint256 min);\n error BalanceTooLow();\n error FlashbotsErrorPayingMiner(uint256 value);\n error IncompatibleLengths();\n error RevertBytes();\n error ZeroAddress();\n\n constructor() initializer {}\n\n function initialize(address keeper) public initializer {\n __AccessControl_init();\n\n _setupRole(KEEPER_ROLE, keeper);\n _setRoleAdmin(KEEPER_ROLE, KEEPER_ROLE);\n }\n}\n\ncontract MockKeeperMulticall2 {\n uint256 public varTest = 1;\n\n bytes32 public constant KEEPER_ROLE = keccak256(\"KEEPER_ROLE\");\n\n //solhint-disable-next-line\n address private constant _oneInch = 0x1111111254fb6c44bAC0beD2854e76F90643097d;\n\n struct Action {\n address target;\n bytes data;\n bool isDelegateCall;\n }\n\n event LogAction(address indexed target, bytes data);\n event SentToMiner(uint256 indexed value);\n event Recovered(address indexed tokenAddress, address indexed to, uint256 amount);\n\n error AmountOutTooLow(uint256 amount, uint256 min);\n error BalanceTooLow();\n error FlashbotsErrorPayingMiner(uint256 value);\n error IncompatibleLengths();\n error RevertBytes();\n error ZeroAddress();\n\n function functionTest() external pure returns (bool) {\n return true;\n }\n}\n" + }, + "contracts/mock/MockLayerZero.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\ninterface ILzApp {\n function lzReceive(uint16 _srcChainId, bytes memory _srcAddress, uint64 _nonce, bytes memory _payload) external;\n}\n\ncontract MockLayerZero {\n mapping(uint16 => uint256) public counters;\n uint256 public config;\n mapping(uint16 => uint64) public outboundNonce;\n uint256 public resumeReceived;\n uint256 public sendVersion;\n uint256 public receiveVersion;\n\n /// @notice Initiate with a fixe change rate\n constructor() {}\n\n function send(\n uint16 _dstChainId,\n bytes calldata,\n bytes calldata,\n address,\n address,\n bytes calldata\n ) external payable {\n counters[_dstChainId] += 1;\n }\n\n function getOutboundNonce(uint16 _dstChainId, address) external view returns (uint64) {\n return outboundNonce[_dstChainId];\n }\n\n function setOutBoundNonce(uint16 _from, uint64 value) external {\n outboundNonce[_from] = value;\n }\n\n function lzReceive(\n address lzApp,\n uint16 _srcChainId,\n bytes memory _srcAddress,\n uint64 _nonce,\n bytes memory _payload\n ) public {\n ILzApp(lzApp).lzReceive(_srcChainId, _srcAddress, _nonce, _payload);\n }\n\n function estimateFees(\n uint16,\n address,\n bytes calldata,\n bool,\n bytes calldata\n ) external pure returns (uint256 nativeFee, uint256 zroFee) {\n return (123, 456);\n }\n\n function setConfig(uint16, uint16, uint256 _configType, bytes calldata) external {\n config = _configType;\n }\n\n function getConfig(uint16, uint16, address, uint256) external view returns (bytes memory) {\n return abi.encodePacked(config);\n }\n\n function setSendVersion(uint16 _version) external {\n sendVersion = _version;\n }\n\n function setReceiveVersion(uint16 _version) external {\n receiveVersion = _version;\n }\n\n function forceResumeReceive(uint16, bytes calldata) external {\n resumeReceived = 1 - resumeReceived;\n }\n}\n" + }, + "contracts/mock/MockLiquidityGauge.sol": { + "content": "// SPDX-License-Identifier: UNLICENSED\npragma solidity ^0.8.12;\n\nimport { ILiquidityGauge } from \"../interfaces/coreModule/ILiquidityGauge.sol\";\nimport \"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\";\nimport \"@openzeppelin/contracts/token/ERC20/ERC20.sol\";\n\ncontract MockLiquidityGauge is ILiquidityGauge, ERC20 {\n using SafeERC20 for IERC20;\n\n IERC20 internal _ANGLE = IERC20(0x31429d1856aD1377A8A0079410B297e1a9e214c2);\n IERC20 internal _token;\n mapping(address => uint256) public rewards;\n\n constructor(string memory name_, string memory symbol_, address token_) ERC20(name_, symbol_) {\n _token = IERC20(token_);\n }\n\n function deposit(\n uint256 _value,\n address _addr,\n // solhint-disable-next-line\n bool\n ) external {\n _token.safeTransferFrom(msg.sender, address(this), _value);\n _mint(_addr, _value);\n }\n\n function withdraw(\n uint256 _value,\n // solhint-disable-next-line\n bool\n ) external {\n _burn(msg.sender, _value);\n _token.safeTransfer(msg.sender, _value);\n }\n\n // solhint-disable-next-line\n function claim_rewards(address _addr, address _receiver) external {\n if (_receiver == address(0)) _receiver = _addr;\n _ANGLE.safeTransfer(_receiver, rewards[_addr]);\n rewards[_addr] = 0;\n }\n\n // solhint-disable-next-line\n function claimable_reward(address _addr, address) external view returns (uint256 amount) {\n return rewards[_addr];\n }\n\n function setReward(address receiver_, uint256 amount) external {\n rewards[receiver_] = amount;\n }\n}\n" + }, + "contracts/mock/MockOracle.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.7;\n\nimport \"../interfaces/IOracle.sol\";\n\ncontract MockOracle is IOracle {\n event Update(uint256 _peg);\n\n ITreasury public treasury;\n\n uint256 public base = 1 ether;\n uint256 public precision = 1 ether;\n uint256 public rate;\n bool public outdated;\n\n /// @notice Initiate with a fixe change rate\n constructor(uint256 rate_, ITreasury _treasury) {\n rate = rate_;\n treasury = _treasury;\n }\n\n /// @notice Mock read\n function read() external view override returns (uint256) {\n return rate;\n }\n\n /// @notice change oracle rate\n function update(uint256 newRate) external {\n rate = newRate;\n }\n\n function setTreasury(address _treasury) external override {\n treasury = ITreasury(_treasury);\n }\n\n function circuitChainlink() external pure override returns (AggregatorV3Interface[] memory) {}\n}\n" + }, + "contracts/mock/MockPolygonAgEUR.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.12;\n\nimport \"../agToken/polygon/utils/ERC20UpgradeableCustom.sol\";\nimport \"@openzeppelin/contracts-upgradeable/access/AccessControlUpgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/utils/cryptography/draft-EIP712Upgradeable.sol\";\nimport \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\nimport \"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\";\n\nimport \"../interfaces/IAgToken.sol\";\nimport \"../interfaces/ITreasury.sol\";\n\ninterface IChildToken {\n function deposit(address user, bytes calldata depositData) external;\n\n function withdraw(uint256 amount) external;\n}\n\ncontract MockPolygonAgEUR is\n Initializable,\n ERC20UpgradeableCustom,\n AccessControlUpgradeable,\n EIP712Upgradeable,\n IChildToken\n{\n bytes32 public constant DEPOSITOR_ROLE = keccak256(\"DEPOSITOR_ROLE\");\n\n /// @dev Emitted when the child chain manager changes\n event ChildChainManagerAdded(address newAddress);\n event ChildChainManagerRevoked(address oldAddress);\n\n constructor() initializer {}\n\n function initialize(\n string memory _name,\n string memory _symbol,\n address childChainManager,\n address guardian\n ) public initializer {\n __ERC20_init(_name, _symbol);\n __AccessControl_init();\n _setupRole(DEFAULT_ADMIN_ROLE, guardian);\n _setupRole(DEPOSITOR_ROLE, childChainManager);\n __EIP712_init(_name, \"1\");\n }\n\n /**\n * @notice Called when the bridge has tokens to mint\n * @param user Address to mint the token to\n * @param depositData Encoded amount to mint\n */\n function deposit(address user, bytes calldata depositData) external override {\n require(hasRole(DEPOSITOR_ROLE, msg.sender));\n uint256 amount = abi.decode(depositData, (uint256));\n _mint(user, amount);\n }\n\n /**\n * @notice Called when user wants to withdraw tokens back to root chain\n * @dev Should burn user's tokens. This transaction will be verified when exiting on root chain\n * @param amount Amount of tokens to withdraw\n */\n function withdraw(uint256 amount) external override {\n _burn(_msgSender(), amount);\n }\n\n // =============================================================================\n // ======================= New data added for the upgrade ======================\n // =============================================================================\n\n mapping(address => bool) public isMinter;\n /// @notice Reference to the treasury contract which can grant minting rights\n address public treasury;\n /// @notice Boolean to check whether the contract has been reinitialized after its upgrade\n bool public treasuryInitialized;\n\n using SafeERC20 for IERC20;\n\n /// @notice Base used for fee computation\n uint256 public constant BASE_PARAMS = 10 ** 9;\n\n // =============================== Bridging Data ===============================\n\n /// @notice Struct with some data about a specific bridge token\n struct BridgeDetails {\n // Limit on the balance of bridge token held by the contract: it is designed\n // to reduce the exposure of the system to hacks\n uint256 limit;\n // Limit on the hourly volume of token minted through this bridge\n // Technically the limit over a rolling hour is hourlyLimit x2 as hourly limit\n // is enforced only between x:00 and x+1:00\n uint256 hourlyLimit;\n // Fee taken for swapping in and out the token\n uint64 fee;\n // Whether the associated token is allowed or not\n bool allowed;\n // Whether swapping in and out from the associated token is paused or not\n bool paused;\n }\n\n /// @notice Maps a bridge token to data\n mapping(address => BridgeDetails) public bridges;\n /// @notice List of all bridge tokens\n address[] public bridgeTokensList;\n /// @notice Maps a bridge token to the associated hourly volume\n mapping(address => mapping(uint256 => uint256)) public usage;\n /// @notice Maps an address to whether it is exempt of fees for when it comes to swapping in and out\n mapping(address => uint256) public isFeeExempt;\n\n uint256[44] private __gap;\n\n // ================================== Events ===================================\n\n event BridgeTokenAdded(address indexed bridgeToken, uint256 limit, uint256 hourlyLimit, uint64 fee, bool paused);\n event BridgeTokenToggled(address indexed bridgeToken, bool toggleStatus);\n event BridgeTokenRemoved(address indexed bridgeToken);\n event BridgeTokenFeeUpdated(address indexed bridgeToken, uint64 fee);\n event BridgeTokenLimitUpdated(address indexed bridgeToken, uint256 limit);\n event BridgeTokenHourlyLimitUpdated(address indexed bridgeToken, uint256 hourlyLimit);\n event HourlyLimitUpdated(uint256 hourlyLimit);\n event FeeToggled(address indexed theAddress, uint256 toggleStatus);\n event KeeperToggled(address indexed keeper, bool toggleStatus);\n event MinterToggled(address indexed minter);\n event Recovered(address indexed token, address indexed to, uint256 amount);\n event TreasuryUpdated(address indexed _treasury);\n\n // ================================== Errors ===================================\n\n error AssetStillControlledInReserves();\n error BurnAmountExceedsAllowance();\n error HourlyLimitExceeded();\n error InvalidSender();\n error InvalidToken();\n error InvalidTreasury();\n error NotGovernor();\n error NotGovernorOrGuardian();\n error NotMinter();\n error NotTreasury();\n error TooBigAmount();\n error TooHighParameterValue();\n error TreasuryAlreadyInitialized();\n error ZeroAddress();\n\n /// @notice Checks to see if it is the `Treasury` calling this contract\n /// @dev There is no Access Control here, because it can be handled cheaply through this modifier\n modifier onlyTreasury() {\n if (msg.sender != treasury) revert NotTreasury();\n _;\n }\n\n /// @notice Checks whether the sender has the minting right\n modifier onlyMinter() {\n if (!isMinter[msg.sender]) revert NotMinter();\n _;\n }\n\n /// @notice Checks whether the `msg.sender` has the governor role or not\n modifier onlyGovernor() {\n if (!ITreasury(treasury).isGovernor(msg.sender)) revert NotGovernor();\n _;\n }\n\n /// @notice Checks whether the `msg.sender` has the governor role or the guardian role\n modifier onlyGovernorOrGuardian() {\n if (!ITreasury(treasury).isGovernorOrGuardian(msg.sender)) revert NotGovernorOrGuardian();\n _;\n }\n\n /// @notice Sets up the treasury contract on Polygon after the upgrade\n /// @param _treasury Address of the treasury contract\n function setUpTreasury(address _treasury) external {\n // Only governor on Polygon\n if (msg.sender != 0xdA2D2f638D6fcbE306236583845e5822554c02EA) revert NotGovernor();\n if (address(ITreasury(_treasury).stablecoin()) != address(this)) revert InvalidTreasury();\n if (treasuryInitialized) revert TreasuryAlreadyInitialized();\n treasury = _treasury;\n treasuryInitialized = true;\n emit TreasuryUpdated(_treasury);\n }\n\n // =========================== External Function ===============================\n\n /// @notice Allows anyone to burn agToken without redeeming collateral back\n /// @param amount Amount of stablecoins to burn\n /// @dev This function can typically be called if there is a settlement mechanism to burn stablecoins\n function burnStablecoin(uint256 amount) external {\n _burnCustom(msg.sender, amount);\n }\n\n // ======================= Minter Role Only Functions ==========================\n\n function burnSelf(uint256 amount, address burner) external onlyMinter {\n _burnCustom(burner, amount);\n }\n\n function burnFrom(uint256 amount, address burner, address sender) external onlyMinter {\n _burnFromNoRedeem(amount, burner, sender);\n }\n\n function mint(address account, uint256 amount) external onlyMinter {\n _mint(account, amount);\n }\n\n // ======================= Treasury Only Functions =============================\n\n function addMinter(address minter) external onlyTreasury {\n isMinter[minter] = true;\n emit MinterToggled(minter);\n }\n\n function removeMinter(address minter) external {\n if (msg.sender != address(treasury) && msg.sender != minter) revert InvalidSender();\n isMinter[minter] = false;\n emit MinterToggled(minter);\n }\n\n function setTreasury(address _treasury) external onlyTreasury {\n treasury = _treasury;\n emit TreasuryUpdated(_treasury);\n }\n\n // ============================ Internal Function ==============================\n\n /// @notice Internal version of the function `burnFromNoRedeem`\n /// @param amount Amount to burn\n /// @dev It is at the level of this function that allowance checks are performed\n function _burnFromNoRedeem(uint256 amount, address burner, address sender) internal {\n if (burner != sender) {\n uint256 currentAllowance = allowance(burner, sender);\n if (currentAllowance < amount) revert BurnAmountExceedsAllowance();\n _approve(burner, sender, currentAllowance - amount);\n }\n _burnCustom(burner, amount);\n }\n\n // ==================== External Permissionless Functions ======================\n\n /// @notice Returns the list of all supported bridge tokens\n /// @dev Helpful for UIs\n function allBridgeTokens() external view returns (address[] memory) {\n return bridgeTokensList;\n }\n\n /// @notice Returns the current volume for a bridge, for the current hour\n /// @dev Helpful for UIs\n function currentUsage(address bridge) external view returns (uint256) {\n return usage[bridge][block.timestamp / 3600];\n }\n\n /// @notice Mints the canonical token from a supported bridge token\n /// @param bridgeToken Bridge token to use to mint\n /// @param amount Amount of bridge tokens to send\n /// @param to Address to which the stablecoin should be sent\n /// @dev Some fees may be taken by the protocol depending on the token used and on the address calling\n function swapIn(address bridgeToken, uint256 amount, address to) external returns (uint256) {\n BridgeDetails memory bridgeDetails = bridges[bridgeToken];\n if (!bridgeDetails.allowed || bridgeDetails.paused) revert InvalidToken();\n uint256 balance = IERC20(bridgeToken).balanceOf(address(this));\n if (balance + amount > bridgeDetails.limit) {\n // In case someone maliciously sends tokens to this contract\n // Or the limit changes\n if (bridgeDetails.limit > balance) amount = bridgeDetails.limit - balance;\n else {\n amount = 0;\n }\n }\n\n // Checking requirement on the hourly volume\n uint256 hour = block.timestamp / 3600;\n uint256 hourlyUsage = usage[bridgeToken][hour] + amount;\n if (hourlyUsage > bridgeDetails.hourlyLimit) {\n // Edge case when the hourly limit changes\n if (bridgeDetails.hourlyLimit > usage[bridgeToken][hour])\n amount = bridgeDetails.hourlyLimit - usage[bridgeToken][hour];\n else {\n amount = 0;\n }\n }\n usage[bridgeToken][hour] = usage[bridgeToken][hour] + amount;\n\n IERC20(bridgeToken).safeTransferFrom(msg.sender, address(this), amount);\n uint256 canonicalOut = amount;\n // Computing fees\n if (isFeeExempt[msg.sender] == 0) {\n canonicalOut -= (canonicalOut * bridgeDetails.fee) / BASE_PARAMS;\n }\n _mint(to, canonicalOut);\n return canonicalOut;\n }\n\n /// @notice Burns the canonical token in exchange for a bridge token\n /// @param bridgeToken Bridge token required\n /// @param amount Amount of canonical tokens to burn\n /// @param to Address to which the bridge token should be sent\n /// @dev Some fees may be taken by the protocol depending on the token used and on the address calling\n function swapOut(address bridgeToken, uint256 amount, address to) external returns (uint256) {\n BridgeDetails memory bridgeDetails = bridges[bridgeToken];\n if (!bridgeDetails.allowed || bridgeDetails.paused) revert InvalidToken();\n\n _burnCustom(msg.sender, amount);\n uint256 bridgeOut = amount;\n if (isFeeExempt[msg.sender] == 0) {\n bridgeOut -= (bridgeOut * bridgeDetails.fee) / BASE_PARAMS;\n }\n IERC20(bridgeToken).safeTransfer(to, bridgeOut);\n return bridgeOut;\n }\n\n // ======================= Governance Functions ================================\n\n /// @notice Adds support for a bridge token\n /// @param bridgeToken Bridge token to add: it should be a version of the stablecoin from another bridge\n /// @param limit Limit on the balance of bridge token this contract could hold\n /// @param hourlyLimit Limit on the hourly volume for this bridge\n /// @param paused Whether swapping for this token should be paused or not\n /// @param fee Fee taken upon swapping for or against this token\n function addBridgeToken(\n address bridgeToken,\n uint256 limit,\n uint256 hourlyLimit,\n uint64 fee,\n bool paused\n ) external onlyGovernor {\n if (bridges[bridgeToken].allowed || bridgeToken == address(0)) revert InvalidToken();\n if (fee > BASE_PARAMS) revert TooHighParameterValue();\n BridgeDetails memory _bridge;\n _bridge.limit = limit;\n _bridge.hourlyLimit = hourlyLimit;\n _bridge.paused = paused;\n _bridge.fee = fee;\n _bridge.allowed = true;\n bridges[bridgeToken] = _bridge;\n bridgeTokensList.push(bridgeToken);\n emit BridgeTokenAdded(bridgeToken, limit, hourlyLimit, fee, paused);\n }\n\n /// @notice Removes support for a token\n /// @param bridgeToken Address of the bridge token to remove support for\n function removeBridgeToken(address bridgeToken) external onlyGovernor {\n if (IERC20(bridgeToken).balanceOf(address(this)) != 0) revert AssetStillControlledInReserves();\n delete bridges[bridgeToken];\n // Deletion from `bridgeTokensList` loop\n uint256 bridgeTokensListLength = bridgeTokensList.length;\n for (uint256 i; i < bridgeTokensListLength - 1; ++i) {\n if (bridgeTokensList[i] == bridgeToken) {\n // Replace the `bridgeToken` to remove with the last of the list\n bridgeTokensList[i] = bridgeTokensList[bridgeTokensListLength - 1];\n break;\n }\n }\n // Remove last element in array\n bridgeTokensList.pop();\n emit BridgeTokenRemoved(bridgeToken);\n }\n\n /// @notice Recovers any ERC20 token\n /// @dev Can be used to withdraw bridge tokens for them to be de-bridged on mainnet\n function recoverERC20(address tokenAddress, address to, uint256 amountToRecover) external onlyGovernor {\n IERC20(tokenAddress).safeTransfer(to, amountToRecover);\n emit Recovered(tokenAddress, to, amountToRecover);\n }\n\n /// @notice Updates the `limit` amount for `bridgeToken`\n function setLimit(address bridgeToken, uint256 limit) external onlyGovernorOrGuardian {\n if (!bridges[bridgeToken].allowed) revert InvalidToken();\n bridges[bridgeToken].limit = limit;\n emit BridgeTokenLimitUpdated(bridgeToken, limit);\n }\n\n /// @notice Updates the `hourlyLimit` amount for `bridgeToken`\n function setHourlyLimit(address bridgeToken, uint256 hourlyLimit) external onlyGovernorOrGuardian {\n if (!bridges[bridgeToken].allowed) revert InvalidToken();\n bridges[bridgeToken].hourlyLimit = hourlyLimit;\n emit BridgeTokenHourlyLimitUpdated(bridgeToken, hourlyLimit);\n }\n\n /// @notice Updates the `fee` value for `bridgeToken`\n function setSwapFee(address bridgeToken, uint64 fee) external onlyGovernorOrGuardian {\n if (!bridges[bridgeToken].allowed) revert InvalidToken();\n if (fee > BASE_PARAMS) revert TooHighParameterValue();\n bridges[bridgeToken].fee = fee;\n emit BridgeTokenFeeUpdated(bridgeToken, fee);\n }\n\n /// @notice Pauses or unpauses swapping in and out for a token\n function toggleBridge(address bridgeToken) external onlyGovernorOrGuardian {\n if (!bridges[bridgeToken].allowed) revert InvalidToken();\n bool pausedStatus = bridges[bridgeToken].paused;\n bridges[bridgeToken].paused = !pausedStatus;\n emit BridgeTokenToggled(bridgeToken, !pausedStatus);\n }\n\n /// @notice Toggles fees for the address `theAddress`\n function toggleFeesForAddress(address theAddress) external onlyGovernorOrGuardian {\n uint256 feeExemptStatus = 1 - isFeeExempt[theAddress];\n isFeeExempt[theAddress] = feeExemptStatus;\n emit FeeToggled(theAddress, feeExemptStatus);\n }\n}\n" + }, + "contracts/mock/MockRouter.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\nimport \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\nimport \"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\";\n\nimport \"../interfaces/IAngleRouter.sol\";\nimport \"../interfaces/external/uniswap/IUniswapRouter.sol\";\nimport \"../interfaces/external/lido/IWStETH.sol\";\n\ncontract MockRouter is IUniswapV3Router, IWStETH {\n using SafeERC20 for IERC20;\n\n uint256 public counterAngleMint;\n uint256 public counterAngleBurn;\n uint256 public counter1Inch;\n uint256 public counterUni;\n uint256 public counterWrap;\n uint256 public counterMixer;\n uint256 public amountOutUni;\n uint256 public multiplierMintBurn;\n uint256 public stETHMultiplier;\n address public inToken;\n address public outToken;\n\n address public stETH;\n\n /// @notice Action types\n enum ActionType {\n transfer,\n wrap,\n wrapNative,\n sweep,\n sweepNative,\n unwrap,\n unwrapNative,\n swapIn,\n swapOut,\n uniswapV3,\n oneInch,\n claimRewards,\n gaugeDeposit,\n borrower\n }\n\n /// @notice Data needed to get permits\n struct PermitType {\n address token;\n address owner;\n uint256 value;\n uint256 deadline;\n uint8 v;\n bytes32 r;\n bytes32 s;\n }\n\n constructor() {}\n\n function mint(address user, uint256 amount, uint256, address stablecoin, address collateral) external {\n counterAngleMint += 1;\n IERC20(collateral).safeTransferFrom(msg.sender, address(this), amount);\n IERC20(stablecoin).safeTransfer(user, (amount * 10 ** 9) / multiplierMintBurn);\n }\n\n function setStETH(address _stETH) external {\n stETH = _stETH;\n }\n\n function burn(address user, uint256 amount, uint256, address stablecoin, address collateral) external {\n counterAngleBurn += 1;\n IERC20(stablecoin).safeTransferFrom(msg.sender, address(this), amount);\n IERC20(collateral).safeTransfer(user, (amount * multiplierMintBurn) / 10 ** 9);\n }\n\n function mixer(\n PermitType[] memory paramsPermit,\n ActionType[] memory actions,\n bytes[] calldata data\n ) public payable virtual {\n paramsPermit;\n counterMixer += 1;\n for (uint256 i; i < actions.length; ++i) {\n if (actions[i] == ActionType.transfer) {\n (address transferToken, uint256 amount) = abi.decode(data[i], (address, uint256));\n IERC20(transferToken).safeTransferFrom(msg.sender, address(this), amount);\n }\n }\n }\n\n function wrap(uint256 amount) external returns (uint256 amountOut) {\n amountOut = (amount * stETHMultiplier) / 10 ** 9;\n counterWrap += 1;\n IERC20(stETH).safeTransferFrom(msg.sender, address(this), amount);\n IERC20(outToken).safeTransfer(msg.sender, amountOut);\n }\n\n function oneInch(uint256 amountIn) external returns (uint256 amountOut) {\n counter1Inch += 1;\n amountOut = (amountOutUni * amountIn) / 10 ** 9;\n IERC20(inToken).safeTransferFrom(msg.sender, address(this), amountIn);\n IERC20(outToken).safeTransfer(msg.sender, amountOut);\n }\n\n function oneInchReverts() external {\n counter1Inch += 1;\n revert(\"wrong swap\");\n }\n\n function oneInchRevertsWithoutMessage() external {\n counter1Inch += 1;\n require(false);\n }\n\n function exactInput(ExactInputParams calldata params) external payable returns (uint256 amountOut) {\n counterUni += 1;\n amountOut = (params.amountIn * amountOutUni) / 10 ** 9;\n IERC20(inToken).safeTransferFrom(msg.sender, address(this), params.amountIn);\n IERC20(outToken).safeTransfer(params.recipient, amountOut);\n require(amountOut >= params.amountOutMinimum);\n }\n\n function setMultipliers(uint256 a, uint256 b) external {\n amountOutUni = a;\n multiplierMintBurn = b;\n }\n\n function setStETHMultiplier(uint256 value) external {\n stETHMultiplier = value;\n }\n\n function setInOut(address _collateral, address _stablecoin) external {\n inToken = _collateral;\n outToken = _stablecoin;\n }\n}\n" + }, + "contracts/mock/MockSidechainAgEUR.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\nimport \"../agToken/AgToken.sol\";\nimport \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\nimport \"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\";\n\n/// @title AgTokenSideChainMultiBridge\n/// @author Angle Labs, Inc.\n/// @notice Contract for Angle agTokens on other chains than Ethereum mainnet\n/// @dev This contract supports bridge tokens having a minting right on the stablecoin (also referred to as the canonical\n/// or the native token)\n/// @dev References:\n/// - FRAX implementation: https://polygonscan.com/address/0x45c32fA6DF82ead1e2EF74d17b76547EDdFaFF89#code\n/// - QiDAO implementation: https://snowtrace.io/address/0x5c49b268c9841AFF1Cc3B0a418ff5c3442eE3F3b#code\ncontract MockSidechainAgEUR is AgToken {\n using SafeERC20 for IERC20;\n\n /// @notice Base used for fee computation\n uint256 public constant BASE_PARAMS = 10 ** 9;\n\n // =============================== Bridging Data ===============================\n\n /// @notice Struct with some data about a specific bridge token\n struct BridgeDetails {\n // Limit on the balance of bridge token held by the contract: it is designed\n // to reduce the exposure of the system to hacks\n uint256 limit;\n // Limit on the hourly volume of token minted through this bridge\n // Technically the limit over a rolling hour is hourlyLimit x2 as hourly limit\n // is enforced only between x:00 and x+1:00\n uint256 hourlyLimit;\n // Fee taken for swapping in and out the token\n uint64 fee;\n // Whether the associated token is allowed or not\n bool allowed;\n // Whether swapping in and out from the associated token is paused or not\n bool paused;\n }\n\n /// @notice Maps a bridge token to data\n mapping(address => BridgeDetails) public bridges;\n /// @notice List of all bridge tokens\n address[] public bridgeTokensList;\n /// @notice Maps a bridge token to the associated hourly volume\n mapping(address => mapping(uint256 => uint256)) public usage;\n /// @notice Maps an address to whether it is exempt of fees for when it comes to swapping in and out\n mapping(address => uint256) public isFeeExempt;\n\n // ================================== Events ===================================\n\n event BridgeTokenAdded(address indexed bridgeToken, uint256 limit, uint256 hourlyLimit, uint64 fee, bool paused);\n event BridgeTokenToggled(address indexed bridgeToken, bool toggleStatus);\n event BridgeTokenRemoved(address indexed bridgeToken);\n event BridgeTokenFeeUpdated(address indexed bridgeToken, uint64 fee);\n event BridgeTokenLimitUpdated(address indexed bridgeToken, uint256 limit);\n event BridgeTokenHourlyLimitUpdated(address indexed bridgeToken, uint256 hourlyLimit);\n event HourlyLimitUpdated(uint256 hourlyLimit);\n event Recovered(address indexed token, address indexed to, uint256 amount);\n event FeeToggled(address indexed theAddress, uint256 toggleStatus);\n\n // =============================== Errors ================================\n\n error AssetStillControlledInReserves();\n error HourlyLimitExceeded();\n error InvalidToken();\n error NotGovernor();\n error NotGovernorOrGuardian();\n error TooBigAmount();\n error TooHighParameterValue();\n error ZeroAddress();\n\n // ============================= Constructor ===================================\n\n /// @notice Checks whether the `msg.sender` has the governor role or not\n modifier onlyGovernor() {\n if (!ITreasury(treasury).isGovernor(msg.sender)) revert NotGovernor();\n _;\n }\n\n /// @notice Checks whether the `msg.sender` has the governor role or the guardian role\n modifier onlyGovernorOrGuardian() {\n if (!ITreasury(treasury).isGovernorOrGuardian(msg.sender)) revert NotGovernorOrGuardian();\n _;\n }\n\n // ==================== External Permissionless Functions ======================\n\n /// @notice Returns the list of all supported bridge tokens\n /// @dev Helpful for UIs\n function allBridgeTokens() external view returns (address[] memory) {\n return bridgeTokensList;\n }\n\n /// @notice Returns the current volume for a bridge, for the current hour\n /// @param bridgeToken Bridge used to mint\n /// @dev Helpful for UIs\n function currentUsage(address bridgeToken) external view returns (uint256) {\n return usage[bridgeToken][block.timestamp / 3600];\n }\n\n /// @notice Mints the canonical token from a supported bridge token\n /// @param bridgeToken Bridge token to use to mint\n /// @param amount Amount of bridge tokens to send\n /// @param to Address to which the stablecoin should be sent\n /// @return Amount of the canonical stablecoin actually minted\n /// @dev Some fees may be taken by the protocol depending on the token used and on the address calling\n function swapIn(address bridgeToken, uint256 amount, address to) external returns (uint256) {\n BridgeDetails memory bridgeDetails = bridges[bridgeToken];\n if (!bridgeDetails.allowed || bridgeDetails.paused) revert InvalidToken();\n uint256 balance = IERC20(bridgeToken).balanceOf(address(this));\n if (balance + amount > bridgeDetails.limit) {\n // In case someone maliciously sends tokens to this contract\n // Or the limit changes\n if (bridgeDetails.limit > balance) amount = bridgeDetails.limit - balance;\n else {\n amount = 0;\n }\n }\n\n // Checking requirement on the hourly volume\n uint256 hour = block.timestamp / 3600;\n uint256 hourlyUsage = usage[bridgeToken][hour] + amount;\n if (hourlyUsage > bridgeDetails.hourlyLimit) {\n // Edge case when the hourly limit changes\n if (bridgeDetails.hourlyLimit > usage[bridgeToken][hour])\n amount = bridgeDetails.hourlyLimit - usage[bridgeToken][hour];\n else {\n amount = 0;\n }\n }\n usage[bridgeToken][hour] = usage[bridgeToken][hour] + amount;\n\n IERC20(bridgeToken).safeTransferFrom(msg.sender, address(this), amount);\n uint256 canonicalOut = amount;\n // Computing fees\n if (isFeeExempt[msg.sender] == 0) {\n canonicalOut -= (canonicalOut * bridgeDetails.fee) / BASE_PARAMS;\n }\n _mint(to, canonicalOut);\n return canonicalOut;\n }\n\n /// @notice Burns the canonical token in exchange for a bridge token\n /// @param bridgeToken Bridge token required\n /// @param amount Amount of canonical tokens to burn\n /// @param to Address to which the bridge token should be sent\n /// @return Amount of bridge tokens actually sent back\n /// @dev Some fees may be taken by the protocol depending on the token used and on the address calling\n function swapOut(address bridgeToken, uint256 amount, address to) external returns (uint256) {\n BridgeDetails memory bridgeDetails = bridges[bridgeToken];\n if (!bridgeDetails.allowed || bridgeDetails.paused) revert InvalidToken();\n\n _burn(msg.sender, amount);\n uint256 bridgeOut = amount;\n if (isFeeExempt[msg.sender] == 0) {\n bridgeOut -= (bridgeOut * bridgeDetails.fee) / BASE_PARAMS;\n }\n IERC20(bridgeToken).safeTransfer(to, bridgeOut);\n return bridgeOut;\n }\n\n // ======================= Governance Functions ================================\n\n /// @notice Adds support for a bridge token\n /// @param bridgeToken Bridge token to add: it should be a version of the stablecoin from another bridge\n /// @param limit Limit on the balance of bridge token this contract could hold\n /// @param hourlyLimit Limit on the hourly volume for this bridge\n /// @param paused Whether swapping for this token should be paused or not\n /// @param fee Fee taken upon swapping for or against this token\n function addBridgeToken(\n address bridgeToken,\n uint256 limit,\n uint256 hourlyLimit,\n uint64 fee,\n bool paused\n ) external onlyGovernor {\n if (bridges[bridgeToken].allowed || bridgeToken == address(0)) revert InvalidToken();\n if (fee > BASE_PARAMS) revert TooHighParameterValue();\n BridgeDetails memory _bridge;\n _bridge.limit = limit;\n _bridge.hourlyLimit = hourlyLimit;\n _bridge.paused = paused;\n _bridge.fee = fee;\n _bridge.allowed = true;\n bridges[bridgeToken] = _bridge;\n bridgeTokensList.push(bridgeToken);\n emit BridgeTokenAdded(bridgeToken, limit, hourlyLimit, fee, paused);\n }\n\n /// @notice Removes support for a token\n /// @param bridgeToken Address of the bridge token to remove support for\n function removeBridgeToken(address bridgeToken) external onlyGovernor {\n if (IERC20(bridgeToken).balanceOf(address(this)) != 0) revert AssetStillControlledInReserves();\n delete bridges[bridgeToken];\n // Deletion from `bridgeTokensList` loop\n uint256 bridgeTokensListLength = bridgeTokensList.length;\n for (uint256 i; i < bridgeTokensListLength - 1; ++i) {\n if (bridgeTokensList[i] == bridgeToken) {\n // Replace the `bridgeToken` to remove with the last of the list\n bridgeTokensList[i] = bridgeTokensList[bridgeTokensListLength - 1];\n break;\n }\n }\n // Remove last element in array\n bridgeTokensList.pop();\n emit BridgeTokenRemoved(bridgeToken);\n }\n\n /// @notice Recovers any ERC20 token\n /// @dev Can be used to withdraw bridge tokens for them to be de-bridged on mainnet\n function recoverERC20(address tokenAddress, address to, uint256 amountToRecover) external onlyGovernor {\n IERC20(tokenAddress).safeTransfer(to, amountToRecover);\n emit Recovered(tokenAddress, to, amountToRecover);\n }\n\n /// @notice Updates the `limit` amount for `bridgeToken`\n function setLimit(address bridgeToken, uint256 limit) external onlyGovernorOrGuardian {\n if (!bridges[bridgeToken].allowed) revert InvalidToken();\n bridges[bridgeToken].limit = limit;\n emit BridgeTokenLimitUpdated(bridgeToken, limit);\n }\n\n /// @notice Updates the `hourlyLimit` amount for `bridgeToken`\n function setHourlyLimit(address bridgeToken, uint256 hourlyLimit) external onlyGovernorOrGuardian {\n if (!bridges[bridgeToken].allowed) revert InvalidToken();\n bridges[bridgeToken].hourlyLimit = hourlyLimit;\n emit BridgeTokenHourlyLimitUpdated(bridgeToken, hourlyLimit);\n }\n\n /// @notice Updates the `fee` value for `bridgeToken`\n function setSwapFee(address bridgeToken, uint64 fee) external onlyGovernorOrGuardian {\n if (!bridges[bridgeToken].allowed) revert InvalidToken();\n if (fee > BASE_PARAMS) revert TooHighParameterValue();\n bridges[bridgeToken].fee = fee;\n emit BridgeTokenFeeUpdated(bridgeToken, fee);\n }\n\n /// @notice Pauses or unpauses swapping in and out for a token\n function toggleBridge(address bridgeToken) external onlyGovernorOrGuardian {\n if (!bridges[bridgeToken].allowed) revert InvalidToken();\n bool pausedStatus = bridges[bridgeToken].paused;\n bridges[bridgeToken].paused = !pausedStatus;\n emit BridgeTokenToggled(bridgeToken, !pausedStatus);\n }\n\n /// @notice Toggles fees for the address `theAddress`\n function toggleFeesForAddress(address theAddress) external onlyGovernorOrGuardian {\n uint256 feeExemptStatus = 1 - isFeeExempt[theAddress];\n isFeeExempt[theAddress] = feeExemptStatus;\n emit FeeToggled(theAddress, feeExemptStatus);\n }\n}\n" + }, + "contracts/mock/MockStableMaster.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\nimport \"../interfaces/IAgToken.sol\";\nimport \"./MockToken.sol\";\nimport \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\nimport \"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\";\nimport { SLPData, MintBurnData } from \"../interfaces/coreModule/IStableMaster.sol\";\n\n// All the details about a collateral that are going to be stored in `StableMaster`\nstruct Collateral {\n // Interface for the token accepted by the underlying `PoolManager` contract\n IERC20 token;\n // Reference to the `SanToken` for the pool\n MockToken sanToken;\n // Reference to the `PerpetualManager` for the pool\n address perpetualManager;\n // Adress of the oracle for the change rate between\n // collateral and the corresponding stablecoin\n address oracle;\n // Amount of collateral in the reserves that comes from users\n // converted in stablecoin value. Updated at minting and burning.\n // A `stocksUsers` of 10 for a collateral type means that overall the balance of the collateral from users\n // that minted/burnt stablecoins using this collateral is worth 10 of stablecoins\n uint256 stocksUsers;\n // Exchange rate between sanToken and collateral\n uint256 sanRate;\n // Base used in the collateral implementation (ERC20 decimal)\n uint256 collatBase;\n // Parameters for SLPs and update of the `sanRate`\n SLPData slpData;\n // All the fees parameters\n MintBurnData feeData;\n}\n\ncontract MockStableMaster {\n mapping(address => uint256) public poolManagerMap;\n\n constructor() {}\n\n function updateStocksUsers(uint256 amount, address poolManager) external {\n poolManagerMap[poolManager] += amount;\n }\n\n function burnSelf(IAgToken agToken, uint256 amount, address burner) external {\n agToken.burnSelf(amount, burner);\n }\n\n function burnFrom(IAgToken agToken, uint256 amount, address burner, address sender) external {\n agToken.burnFrom(amount, burner, sender);\n }\n\n function mint(IAgToken agToken, address account, uint256 amount) external {\n agToken.mint(account, amount);\n }\n}\n\ncontract MockStableMasterSanWrapper is MockStableMaster {\n using SafeERC20 for IERC20;\n\n /// @notice Maps a `PoolManager` contract handling a collateral for this stablecoin to the properties of the struct above\n mapping(address => Collateral) public collateralMap;\n\n constructor() MockStableMaster() {}\n\n uint256 internal constant _BASE_TOKENS = 10 ** 18;\n uint256 internal constant _BASE_PARAMS = 10 ** 9;\n IERC20 public token;\n\n function deposit(uint256 assets, address receiver, address poolManager) external {\n token.safeTransferFrom(msg.sender, address(this), assets);\n Collateral storage col = collateralMap[poolManager];\n _updateSanRate(col);\n uint256 amount = (assets * _BASE_TOKENS) / col.sanRate;\n col.sanToken.mint(receiver, amount);\n }\n\n function withdraw(uint256 assets, address sender, address receiver, address poolManager) external {\n Collateral storage col = collateralMap[poolManager];\n _updateSanRate(col);\n col.sanToken.burn(sender, assets);\n // Computing the amount of collateral to give back to the SLP depending on slippage and on the `sanRate`\n uint256 redeemInC = (assets * (_BASE_PARAMS - col.slpData.slippage) * col.sanRate) /\n (_BASE_TOKENS * _BASE_PARAMS);\n token.safeTransfer(receiver, redeemInC);\n }\n\n function setPoolManagerToken(address, address token_) external {\n token = MockToken(token_);\n }\n\n function setPoolManagerSanToken(address poolManager, address sanToken_) external {\n Collateral storage col = collateralMap[poolManager];\n col.sanToken = MockToken(sanToken_);\n }\n\n function setSanRate(address poolManager, uint256 sanRate_) external {\n Collateral storage col = collateralMap[poolManager];\n col.sanRate = sanRate_;\n }\n\n function _updateSanRate(Collateral storage col) internal {\n uint256 _lockedInterests = col.slpData.lockedInterests;\n // Checking if the `sanRate` has been updated in the current block using past block fees\n // This is a way to prevent flash loans attacks when an important amount of fees are going to be distributed\n // in a block: fees are stored but will just be distributed to SLPs who will be here during next blocks\n if (block.timestamp != col.slpData.lastBlockUpdated && _lockedInterests > 0) {\n uint256 sanMint = col.sanToken.totalSupply();\n if (sanMint != 0) {\n // Checking if the update is too important and should be made in multiple blocks\n if (_lockedInterests > col.slpData.maxInterestsDistributed) {\n // `sanRate` is expressed in `BASE_TOKENS`\n col.sanRate += (col.slpData.maxInterestsDistributed * 10 ** 18) / sanMint;\n _lockedInterests -= col.slpData.maxInterestsDistributed;\n } else {\n col.sanRate += (_lockedInterests * 10 ** 18) / sanMint;\n _lockedInterests = 0;\n }\n } else {\n _lockedInterests = 0;\n }\n }\n col.slpData.lockedInterests = _lockedInterests;\n col.slpData.lastBlockUpdated = block.timestamp;\n }\n\n // copy paste from the deployed contract\n function estimateSanRate(address poolManager) external view returns (uint256 sanRate, uint64 slippage) {\n Collateral memory col = collateralMap[poolManager];\n uint256 _lockedInterests = col.slpData.lockedInterests;\n // Checking if the `sanRate` has been updated in the current block using past block fees\n // This is a way to prevent flash loans attacks when an important amount of fees are going to be distributed\n // in a block: fees are stored but will just be distributed to SLPs who will be here during next blocks\n if (block.timestamp != col.slpData.lastBlockUpdated && _lockedInterests > 0) {\n uint256 sanMint = col.sanToken.totalSupply();\n if (sanMint != 0) {\n // Checking if the update is too important and should be made in multiple blocks\n if (_lockedInterests > col.slpData.maxInterestsDistributed) {\n // `sanRate` is expressed in `BASE_TOKENS`\n col.sanRate += (col.slpData.maxInterestsDistributed * 10 ** 18) / sanMint;\n _lockedInterests -= col.slpData.maxInterestsDistributed;\n } else {\n col.sanRate += (_lockedInterests * 10 ** 18) / sanMint;\n _lockedInterests = 0;\n }\n } else {\n _lockedInterests = 0;\n }\n }\n return (col.sanRate, col.slpData.slippage);\n }\n\n function setSLPData(\n address poolManager,\n uint256 lockedInterests,\n uint256 maxInterestsDistributed,\n uint64 slippage\n ) external {\n Collateral storage col = collateralMap[poolManager];\n col.slpData.lockedInterests = lockedInterests;\n col.slpData.maxInterestsDistributed = maxInterestsDistributed;\n col.slpData.slippage = slippage;\n }\n}\n" + }, + "contracts/mock/MockSwapper.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\nimport \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\nimport \"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\";\n\nimport \"../interfaces/ISwapper.sol\";\n\ncontract MockSwapper is ISwapper {\n bytes32 public constant CALLBACK_SUCCESS = keccak256(\"ERC3156FlashBorrower.onFlashLoan\");\n\n uint256 public counter;\n\n constructor() {}\n\n function swap(IERC20, IERC20, address, uint256, uint256, bytes calldata data) external {\n counter += 1;\n data;\n }\n}\n\ncontract MockSwapperWithSwap is ISwapper {\n using SafeERC20 for IERC20;\n bytes32 public constant CALLBACK_SUCCESS = keccak256(\"ERC3156FlashBorrower.onFlashLoan\");\n\n uint256 public counter;\n\n constructor() {}\n\n function swap(\n IERC20,\n IERC20 outToken,\n address outTokenRecipient,\n uint256 outTokenOwed,\n uint256,\n bytes calldata data\n ) external {\n counter += 1;\n outToken.safeTransfer(outTokenRecipient, outTokenOwed);\n\n data;\n }\n}\n" + }, + "contracts/mock/MockSwapperSidechain.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\nimport \"../swapper/Swapper.sol\";\n\n/// @title MockSwapperSidechain\n/// @author Angle Labs, Inc.\ncontract MockSwapperSidechain is Swapper {\n error NotImplemented();\n\n /// @notice Constructor of the contract\n /// @param _core Core address\n /// @param _uniV3Router UniswapV3 Router address\n /// @param _oneInch 1Inch Router address\n /// @param _angleRouter AngleRouter contract address\n constructor(\n ICoreBorrow _core,\n IUniswapV3Router _uniV3Router,\n address _oneInch,\n IAngleRouterSidechain _angleRouter\n ) Swapper(_core, _uniV3Router, _oneInch, _angleRouter) {}\n\n function _swapLeverage(bytes memory) internal pure override returns (uint256) {\n revert NotImplemented();\n }\n}\n" + }, + "contracts/mock/MockToken.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.7;\n\nimport \"@openzeppelin/contracts/token/ERC20/ERC20.sol\";\n\ncontract MockToken is ERC20 {\n event Minting(address indexed _to, address indexed _minter, uint256 _amount);\n\n event Burning(address indexed _from, address indexed _burner, uint256 _amount);\n\n uint8 internal _decimal;\n mapping(address => bool) public minters;\n address public treasury;\n\n constructor(string memory name_, string memory symbol_, uint8 decimal_) ERC20(name_, symbol_) {\n _decimal = decimal_;\n }\n\n function decimals() public view override returns (uint8) {\n return _decimal;\n }\n\n function mint(address account, uint256 amount) external {\n _mint(account, amount);\n emit Minting(account, msg.sender, amount);\n }\n\n function burn(address account, uint256 amount) public {\n _burn(account, amount);\n emit Burning(account, msg.sender, amount);\n }\n\n function setAllowance(address from, address to) public {\n _approve(from, to, type(uint256).max);\n }\n\n function burnSelf(uint256 amount, address account) public {\n _burn(account, amount);\n emit Burning(account, msg.sender, amount);\n }\n\n function addMinter(address minter) public {\n minters[minter] = true;\n }\n\n function removeMinter(address minter) public {\n minters[minter] = false;\n }\n\n function setTreasury(address _treasury) public {\n treasury = _treasury;\n }\n}\n" + }, + "contracts/mock/MockTokenPermit.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.7;\n\nimport \"@openzeppelin/contracts/token/ERC20/extensions/draft-ERC20Permit.sol\";\nimport \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\nimport \"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\";\n\ncontract MockTokenPermit is ERC20Permit {\n using SafeERC20 for IERC20;\n event Minting(address indexed _to, address indexed _minter, uint256 _amount);\n\n event Burning(address indexed _from, address indexed _burner, uint256 _amount);\n\n uint8 internal _decimal;\n mapping(address => bool) public minters;\n address public treasury;\n uint256 public fees;\n\n bool public reverts;\n\n constructor(string memory name_, string memory symbol_, uint8 decimal_) ERC20Permit(name_) ERC20(name_, symbol_) {\n _decimal = decimal_;\n }\n\n function decimals() public view override returns (uint8) {\n return _decimal;\n }\n\n function mint(address account, uint256 amount) external {\n _mint(account, amount);\n emit Minting(account, msg.sender, amount);\n }\n\n function burn(address account, uint256 amount) public {\n _burn(account, amount);\n emit Burning(account, msg.sender, amount);\n }\n\n function setAllowance(address from, address to) public {\n _approve(from, to, type(uint256).max);\n }\n\n function burnSelf(uint256 amount, address account) public {\n _burn(account, amount);\n emit Burning(account, msg.sender, amount);\n }\n\n function addMinter(address minter) public {\n minters[minter] = true;\n }\n\n function removeMinter(address minter) public {\n minters[minter] = false;\n }\n\n function setTreasury(address _treasury) public {\n treasury = _treasury;\n }\n\n function setFees(uint256 _fees) public {\n fees = _fees;\n }\n\n function recoverERC20(IERC20 token, address to, uint256 amount) external {\n token.safeTransfer(to, amount);\n }\n\n function swapIn(address bridgeToken, uint256 amount, address to) external returns (uint256) {\n require(!reverts);\n\n IERC20(bridgeToken).safeTransferFrom(msg.sender, address(this), amount);\n uint256 canonicalOut = amount;\n canonicalOut -= (canonicalOut * fees) / 10 ** 9;\n _mint(to, canonicalOut);\n return canonicalOut;\n }\n\n function swapOut(address bridgeToken, uint256 amount, address to) external returns (uint256) {\n require(!reverts);\n _burn(msg.sender, amount);\n uint256 bridgeOut = amount;\n bridgeOut -= (bridgeOut * fees) / 10 ** 9;\n IERC20(bridgeToken).safeTransfer(to, bridgeOut);\n return bridgeOut;\n }\n}\n" + }, + "contracts/mock/MockTreasury.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\nimport \"../interfaces/ITreasury.sol\";\nimport \"../interfaces/IFlashAngle.sol\";\nimport \"../interfaces/IVaultManager.sol\";\n\ncontract MockTreasury is ITreasury {\n IAgToken public override stablecoin;\n address public governor;\n address public guardian;\n address public vaultManager1;\n address public vaultManager2;\n address public flashLoanModule;\n address[] public vaultManagerList;\n\n constructor(\n IAgToken _stablecoin,\n address _governor,\n address _guardian,\n address _vaultManager1,\n address _vaultManager2,\n address _flashLoanModule\n ) {\n stablecoin = _stablecoin;\n governor = _governor;\n guardian = _guardian;\n vaultManager1 = _vaultManager1;\n vaultManager2 = _vaultManager2;\n flashLoanModule = _flashLoanModule;\n }\n\n function isGovernor(address admin) external view override returns (bool) {\n return (admin == governor);\n }\n\n function isGovernorOrGuardian(address admin) external view override returns (bool) {\n return (admin == governor || admin == guardian);\n }\n\n function isVaultManager(address _vaultManager) external view override returns (bool) {\n return (_vaultManager == vaultManager1 || _vaultManager == vaultManager2);\n }\n\n function setStablecoin(IAgToken _stablecoin) external {\n stablecoin = _stablecoin;\n }\n\n function setFlashLoanModule(address _flashLoanModule) external override {\n flashLoanModule = _flashLoanModule;\n }\n\n function setGovernor(address _governor) external {\n governor = _governor;\n }\n\n function setVaultManager(address _vaultManager) external {\n vaultManager1 = _vaultManager;\n }\n\n function setVaultManager2(address _vaultManager) external {\n vaultManager2 = _vaultManager;\n }\n\n function setTreasury(address _agTokenOrVaultManager, address _treasury) external {\n IAgToken(_agTokenOrVaultManager).setTreasury(_treasury);\n }\n\n function addMinter(IAgToken _agToken, address _minter) external {\n _agToken.addMinter(_minter);\n }\n\n function removeMinter(IAgToken _agToken, address _minter) external {\n _agToken.removeMinter(_minter);\n }\n\n function accrueInterestToTreasury(IFlashAngle flashAngle) external returns (uint256 balance) {\n balance = flashAngle.accrueInterestToTreasury(stablecoin);\n }\n\n function accrueInterestToTreasuryVaultManager(IVaultManager _vaultManager) external returns (uint256, uint256) {\n return _vaultManager.accrueInterestToTreasury();\n }\n}\n" + }, + "contracts/mock/MockUniswapV3Pool.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.7;\n\ncontract MockUniswapV3Pool {\n address public token0;\n address public token1;\n uint32 public constant EPOCH_DURATION = 24 * 3600 * 7;\n\n function setToken(address token, uint256 who) external {\n if (who == 0) token0 = token;\n else token1 = token;\n }\n\n function round(uint256 amount) external pure returns (uint256) {\n return (amount / EPOCH_DURATION) * EPOCH_DURATION;\n }\n}\n" + }, + "contracts/mock/MockVaultManager.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\nimport \"../interfaces/IVaultManager.sol\";\nimport \"../interfaces/ITreasury.sol\";\nimport \"@openzeppelin/contracts/token/ERC20/ERC20.sol\";\n\ncontract MockVaultManager {\n ITreasury public treasury;\n mapping(uint256 => Vault) public vaultData;\n mapping(uint256 => address) public ownerOf;\n uint256 public surplus;\n uint256 public badDebt;\n IAgToken public token;\n address public oracle = address(this);\n\n address public governor;\n address public collateral;\n address public stablecoin;\n uint256 public oracleValue;\n uint256 public interestAccumulator;\n uint256 public collateralFactor;\n uint256 public totalNormalizedDebt;\n\n constructor(address _treasury) {\n treasury = ITreasury(_treasury);\n }\n\n function accrueInterestToTreasury() external returns (uint256, uint256) {\n // Avoid the function to be view\n if (surplus >= badDebt) {\n token.mint(msg.sender, surplus - badDebt);\n }\n return (surplus, badDebt);\n }\n\n function read() external view returns (uint256) {\n return oracleValue;\n }\n\n function setParams(\n address _governor,\n address _collateral,\n address _stablecoin,\n uint256 _oracleValue,\n uint256 _interestAccumulator,\n uint256 _collateralFactor,\n uint256 _totalNormalizedDebt\n ) external {\n governor = _governor;\n collateral = _collateral;\n stablecoin = _stablecoin;\n interestAccumulator = _interestAccumulator;\n collateralFactor = _collateralFactor;\n totalNormalizedDebt = _totalNormalizedDebt;\n oracleValue = _oracleValue;\n }\n\n function setOwner(uint256 vaultID, address owner) external virtual {\n ownerOf[vaultID] = owner;\n }\n\n function setVaultData(uint256 normalizedDebt, uint256 collateralAmount, uint256 vaultID) external {\n vaultData[vaultID].normalizedDebt = normalizedDebt;\n vaultData[vaultID].collateralAmount = collateralAmount;\n }\n\n function isGovernor(address admin) external view returns (bool) {\n return admin == governor;\n }\n\n function setSurplusBadDebt(uint256 _surplus, uint256 _badDebt, IAgToken _token) external {\n surplus = _surplus;\n badDebt = _badDebt;\n token = _token;\n }\n\n function getDebtOut(uint256 vaultID, uint256 amountStablecoins, uint256 senderBorrowFee) external {}\n\n function setTreasury(address _treasury) external {\n treasury = ITreasury(_treasury);\n }\n\n function getVaultDebt(uint256 vaultID) external view returns (uint256) {\n vaultID;\n token;\n return 0;\n }\n\n function createVault(address toVault) external view returns (uint256) {\n toVault;\n token;\n return 0;\n }\n}\n\ncontract MockVaultManagerListing is MockVaultManager {\n // @notice Mapping from owner address to all his vaults\n mapping(address => uint256[]) internal _ownerListVaults;\n\n constructor(address _treasury) MockVaultManager(_treasury) {}\n\n function getUserVaults(address owner) public view returns (uint256[] memory) {\n return _ownerListVaults[owner];\n }\n\n function getUserCollateral(address owner) public view returns (uint256 totalCollateral) {\n uint256[] memory vaultList = _ownerListVaults[owner];\n uint256 vaultListLength = vaultList.length;\n for (uint256 k; k < vaultListLength; ++k) {\n totalCollateral += vaultData[vaultList[k]].collateralAmount;\n }\n return totalCollateral;\n }\n\n function setOwner(uint256 vaultID, address owner) external override {\n if (ownerOf[vaultID] != address(0)) _removeVaultFromList(ownerOf[vaultID], vaultID);\n _ownerListVaults[owner].push(vaultID);\n ownerOf[vaultID] = owner;\n }\n\n /// @notice Remove `vaultID` from `user` stroed vault list\n /// @param user Address to look out for the vault list\n /// @param vaultID VaultId to remove from the list\n /// @dev The vault is necessarily in the list\n function _removeVaultFromList(address user, uint256 vaultID) internal {\n uint256[] storage vaultList = _ownerListVaults[user];\n uint256 vaultListLength = vaultList.length;\n for (uint256 i; i < vaultListLength - 1; ++i) {\n if (vaultList[i] == vaultID) {\n vaultList[i] = vaultList[vaultListLength - 1];\n break;\n }\n }\n vaultList.pop();\n }\n}\n" + }, + "contracts/mock/MockVeBoostProxy.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\nimport \"../interfaces/governance/IVeBoostProxy.sol\";\n\ncontract MockVeBoostProxy is IVeBoostProxy {\n //solhint-disable-next-line\n mapping(address => uint256) public adjusted_balance_of;\n\n constructor() {}\n\n function setBalance(address concerned, uint256 balance) external {\n adjusted_balance_of[concerned] = balance;\n }\n}\n" + }, + "contracts/oracle/BaseOracleChainlinkMulti.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\n/*\n * █ \n ***** ▓▓▓ \n * ▓▓▓▓▓▓▓ \n * ///. ▓▓▓▓▓▓▓▓▓▓▓▓▓ \n ***** //////// ▓▓▓▓▓▓▓ \n * ///////////// ▓▓▓ \n ▓▓ ////////////////// █ ▓▓ \n ▓▓ ▓▓ /////////////////////// ▓▓ ▓▓ \n ▓▓ ▓▓ //////////////////////////// ▓▓ ▓▓ \n ▓▓ ▓▓ /////////▓▓▓///////▓▓▓///////// ▓▓ ▓▓ \n ▓▓ ,////////////////////////////////////// ▓▓ ▓▓ \n ▓▓ ////////////////////////////////////////// ▓▓ \n ▓▓ //////////////////////▓▓▓▓///////////////////// \n ,//////////////////////////////////////////////////// \n .////////////////////////////////////////////////////////// \n .//////////////////////////██.,//////////////////////////█ \n .//////////////////////████..,./////////////////////██ \n ...////////////////███████.....,.////////////////███ \n ,.,////////////████████ ........,///////////████ \n .,.,//////█████████ ,.......///////████ \n ,..//████████ ........./████ \n ..,██████ .....,███ \n .██ ,.,█ \n \n \n \n ▓▓ ▓▓▓▓▓▓▓▓▓▓ ▓▓▓▓▓▓▓▓▓▓ ▓▓ ▓▓▓▓▓▓▓▓▓▓ \n ▓▓▓▓▓▓ ▓▓▓ ▓▓▓ ▓▓▓ ▓▓ ▓▓ ▓▓▓▓ \n ▓▓▓ ▓▓▓ ▓▓▓ ▓▓▓ ▓▓▓ ▓▓▓ ▓▓ ▓▓▓▓▓ \n ▓▓▓ ▓▓ ▓▓▓ ▓▓▓ ▓▓▓▓▓▓▓▓▓▓ ▓▓▓▓▓▓▓▓▓▓ ▓▓▓▓▓▓▓▓▓▓ \n*/\n\npragma solidity ^0.8.12;\n\nimport \"@chainlink/contracts/src/v0.8/interfaces/AggregatorV3Interface.sol\";\n\nimport \"../interfaces/IOracle.sol\";\nimport \"../interfaces/ITreasury.sol\";\n\n/// @title BaseOracleChainlinkMulti\n/// @author Angle Labs, Inc.\n/// @notice Base Contract to be overriden by all contracts of the protocol\n/// @dev This base contract concerns an oracle that uses Chainlink with multiple pools to read from\n/// @dev All gas-efficient implementation of the `OracleChainlinkMulti` contract should inherit from this\nabstract contract BaseOracleChainlinkMulti is IOracle {\n // ========================= Parameters and References =========================\n\n /// @inheritdoc IOracle\n ITreasury public override treasury;\n /// @notice Represent the maximum amount of time (in seconds) between each Chainlink update\n /// before the price feed is considered stale\n uint32 public stalePeriod;\n\n // =================================== Event ===================================\n\n event StalePeriodUpdated(uint32 _stalePeriod);\n\n // =================================== Errors ===================================\n\n error InvalidChainlinkRate();\n error NotGovernorOrGuardian();\n error NotVaultManagerOrGovernor();\n\n /// @notice Constructor for an oracle using Chainlink with multiple pools to read from\n /// @param _stalePeriod Minimum feed update frequency for the oracle to not revert\n /// @param _treasury Treasury associated to the VaultManager which reads from this feed\n constructor(uint32 _stalePeriod, address _treasury) {\n stalePeriod = _stalePeriod;\n treasury = ITreasury(_treasury);\n }\n\n // ============================= Reading Oracles ===============================\n\n /// @inheritdoc IOracle\n function read() external view virtual override returns (uint256 quoteAmount);\n\n /// @inheritdoc IOracle\n function circuitChainlink() public view virtual returns (AggregatorV3Interface[] memory);\n\n /// @notice Reads a Chainlink feed using a quote amount and converts the quote amount to\n /// the out-currency\n /// @param quoteAmount The amount for which to compute the price expressed with base decimal\n /// @param feed Chainlink feed to query\n /// @param multiplied Whether the ratio outputted by Chainlink should be multiplied or divided\n /// to the `quoteAmount`\n /// @param decimals Number of decimals of the corresponding Chainlink pair\n /// @return The `quoteAmount` converted in out-currency\n function _readChainlinkFeed(\n uint256 quoteAmount,\n AggregatorV3Interface feed,\n uint8 multiplied,\n uint256 decimals\n ) internal view returns (uint256) {\n (uint80 roundId, int256 ratio, , uint256 updatedAt, uint80 answeredInRound) = feed.latestRoundData();\n if (ratio <= 0 || roundId > answeredInRound || block.timestamp - updatedAt > stalePeriod)\n revert InvalidChainlinkRate();\n uint256 castedRatio = uint256(ratio);\n // Checking whether we should multiply or divide by the ratio computed\n if (multiplied == 1) return (quoteAmount * castedRatio) / (10 ** decimals);\n else return (quoteAmount * (10 ** decimals)) / castedRatio;\n }\n\n // ======================= Governance Related Functions ========================\n\n /// @notice Changes the stale period\n /// @param _stalePeriod New stale period (in seconds)\n function changeStalePeriod(uint32 _stalePeriod) external {\n if (!treasury.isGovernorOrGuardian(msg.sender)) revert NotGovernorOrGuardian();\n stalePeriod = _stalePeriod;\n emit StalePeriodUpdated(_stalePeriod);\n }\n\n /// @inheritdoc IOracle\n function setTreasury(address _treasury) external override {\n if (!treasury.isVaultManager(msg.sender) && !treasury.isGovernor(msg.sender))\n revert NotVaultManagerOrGovernor();\n treasury = ITreasury(_treasury);\n }\n}\n" + }, + "contracts/oracle/BaseOracleChainlinkMultiTwoFeeds.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\nimport \"@chainlink/contracts/src/v0.8/interfaces/AggregatorV3Interface.sol\";\n\nimport \"./BaseOracleChainlinkMulti.sol\";\n\n/// @title BaseOracleChainlinkMultiTwoFeeds\n/// @author Angle Labs, Inc.\n/// @notice Base contract for an oracle that reads into two Chainlink feeds (including an EUR/USD feed) which both have\n/// 8 decimals\nabstract contract BaseOracleChainlinkMultiTwoFeeds is BaseOracleChainlinkMulti {\n constructor(uint32 _stalePeriod, address _treasury) BaseOracleChainlinkMulti(_stalePeriod, _treasury) {}\n\n /// @notice Returns the quote amount of the oracle contract\n function _getQuoteAmount() internal view virtual returns (uint256) {\n return 10 ** 18;\n }\n\n /// @inheritdoc IOracle\n function read() external view virtual override returns (uint256 quoteAmount) {\n quoteAmount = _getQuoteAmount();\n AggregatorV3Interface[] memory _circuitChainlink = circuitChainlink();\n uint8[2] memory circuitChainIsMultiplied = [1, 0];\n uint8[2] memory chainlinkDecimals = [8, 8];\n uint256 circuitLength = _circuitChainlink.length;\n for (uint256 i; i < circuitLength; ++i) {\n quoteAmount = _readChainlinkFeed(\n quoteAmount,\n _circuitChainlink[i],\n circuitChainIsMultiplied[i],\n chainlinkDecimals[i]\n );\n }\n }\n}\n" + }, + "contracts/oracle/BaseOracleChainlinkOneFeed.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\nimport \"@chainlink/contracts/src/v0.8/interfaces/AggregatorV3Interface.sol\";\n\nimport \"./BaseOracleChainlinkMulti.sol\";\n\n/// @title BaseOracleChainlinkOneFeed\n/// @author Angle Labs, Inc.\n/// @notice Base contract for an oracle that reads into one Chainlink feeds with 8 decimals\nabstract contract BaseOracleChainlinkOneFeed is BaseOracleChainlinkMulti {\n constructor(uint32 _stalePeriod, address _treasury) BaseOracleChainlinkMulti(_stalePeriod, _treasury) {}\n\n /// @notice Returns the quote amount of the oracle contract\n function _getQuoteAmount() internal view virtual returns (uint256) {\n return 10 ** 18;\n }\n\n /// @inheritdoc IOracle\n function read() external view virtual override returns (uint256 quoteAmount) {\n AggregatorV3Interface[] memory _circuitChainlink = circuitChainlink();\n quoteAmount = _readChainlinkFeed(_getQuoteAmount(), _circuitChainlink[0], 1, 8);\n }\n}\n" + }, + "contracts/oracle/implementations/arbitrum/EUR/OracleBTCEURChainlinkArbitrum.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\nimport \"@chainlink/contracts/src/v0.8/interfaces/AggregatorV3Interface.sol\";\n\nimport \"../../../BaseOracleChainlinkMultiTwoFeeds.sol\";\n\n/// @title OracleBTCEURChainlinkArbitrum\n/// @author Angle Labs, Inc.\n/// @notice Gives the price of BTC in Euro in base 18\n/// @dev This contract is built to be deployed on Arbitrum\ncontract OracleBTCEURChainlinkArbitrum is BaseOracleChainlinkMultiTwoFeeds {\n string public constant DESCRIPTION = \"BTC/EUR Oracle\";\n\n constructor(uint32 _stalePeriod, address _treasury) BaseOracleChainlinkMultiTwoFeeds(_stalePeriod, _treasury) {}\n\n /// @inheritdoc IOracle\n function circuitChainlink() public pure override returns (AggregatorV3Interface[] memory) {\n AggregatorV3Interface[] memory _circuitChainlink = new AggregatorV3Interface[](2);\n // Oracle BTC/USD\n _circuitChainlink[0] = AggregatorV3Interface(0x6ce185860a4963106506C203335A2910413708e9);\n // Oracle EUR/USD\n _circuitChainlink[1] = AggregatorV3Interface(0xA14d53bC1F1c0F31B4aA3BD109344E5009051a84);\n return _circuitChainlink;\n }\n}\n" + }, + "contracts/oracle/implementations/arbitrum/EUR/OracleETHEURChainlinkArbitrum.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\nimport \"@chainlink/contracts/src/v0.8/interfaces/AggregatorV3Interface.sol\";\n\nimport \"../../../BaseOracleChainlinkMultiTwoFeeds.sol\";\n\n/// @title OracleETHEURChainlinkArbitrum\n/// @author Angle Labs, Inc.\n/// @notice Gives the price of ETH in Euro in base 18\n/// @dev This contract is built to be deployed on Arbitrum\ncontract OracleETHEURChainlinkArbitrum is BaseOracleChainlinkMultiTwoFeeds {\n string public constant DESCRIPTION = \"ETH/EUR Oracle\";\n\n constructor(uint32 _stalePeriod, address _treasury) BaseOracleChainlinkMultiTwoFeeds(_stalePeriod, _treasury) {}\n\n /// @inheritdoc IOracle\n function circuitChainlink() public pure override returns (AggregatorV3Interface[] memory) {\n AggregatorV3Interface[] memory _circuitChainlink = new AggregatorV3Interface[](2);\n // Oracle ETH/USD\n _circuitChainlink[0] = AggregatorV3Interface(0x639Fe6ab55C921f74e7fac1ee960C0B6293ba612);\n // Oracle EUR/USD\n _circuitChainlink[1] = AggregatorV3Interface(0xA14d53bC1F1c0F31B4aA3BD109344E5009051a84);\n return _circuitChainlink;\n }\n}\n" + }, + "contracts/oracle/implementations/arbitrum/EUR/OracleUSDCEURChainlinkArbitrum.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\nimport \"@chainlink/contracts/src/v0.8/interfaces/AggregatorV3Interface.sol\";\n\nimport \"../../../BaseOracleChainlinkMultiTwoFeeds.sol\";\n\n/// @title OracleUSDCEURChainlinkArbitrum\n/// @author Angle Labs, Inc.\n/// @notice Gives the price of USDC in Euro in base 18\n/// @dev This contract is built to be deployed on Arbitrum\ncontract OracleUSDCEURChainlinkArbitrum is BaseOracleChainlinkMultiTwoFeeds {\n string public constant DESCRIPTION = \"USDC/EUR Oracle\";\n\n constructor(uint32 _stalePeriod, address _treasury) BaseOracleChainlinkMultiTwoFeeds(_stalePeriod, _treasury) {}\n\n /// @inheritdoc IOracle\n function circuitChainlink() public pure override returns (AggregatorV3Interface[] memory) {\n AggregatorV3Interface[] memory _circuitChainlink = new AggregatorV3Interface[](2);\n // Oracle ETH/USD\n _circuitChainlink[0] = AggregatorV3Interface(0x50834F3163758fcC1Df9973b6e91f0F0F0434aD3);\n // Oracle EUR/USD\n _circuitChainlink[1] = AggregatorV3Interface(0xA14d53bC1F1c0F31B4aA3BD109344E5009051a84);\n return _circuitChainlink;\n }\n}\n" + }, + "contracts/oracle/implementations/avalanche/EUR/OracleAVAXEURChainlinkAvalanche.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\nimport \"@chainlink/contracts/src/v0.8/interfaces/AggregatorV3Interface.sol\";\n\nimport \"../../../BaseOracleChainlinkMultiTwoFeeds.sol\";\n\n/// @title OracleAVAXEURChainlinkAvalanche\n/// @author Angle Labs, Inc.\n/// @notice Gives the price of AVAX in Euro in base 18\n/// @dev This contract is built to be deployed on Avalanche\ncontract OracleAVAXEURChainlinkAvalanche is BaseOracleChainlinkMultiTwoFeeds {\n string public constant DESCRIPTION = \"AVAX/EUR Oracle\";\n\n constructor(uint32 _stalePeriod, address _treasury) BaseOracleChainlinkMultiTwoFeeds(_stalePeriod, _treasury) {}\n\n /// @inheritdoc IOracle\n function circuitChainlink() public pure override returns (AggregatorV3Interface[] memory) {\n AggregatorV3Interface[] memory _circuitChainlink = new AggregatorV3Interface[](2);\n // Oracle AVAX/USD\n _circuitChainlink[0] = AggregatorV3Interface(0x0A77230d17318075983913bC2145DB16C7366156);\n // Oracle EUR/USD\n _circuitChainlink[1] = AggregatorV3Interface(0x192f2DBA961Bb0277520C082d6bfa87D5961333E);\n return _circuitChainlink;\n }\n}\n" + }, + "contracts/oracle/implementations/avalanche/EUR/OracleUSDCEURChainlinkAvalanche.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\nimport \"@chainlink/contracts/src/v0.8/interfaces/AggregatorV3Interface.sol\";\n\nimport \"../../../BaseOracleChainlinkMultiTwoFeeds.sol\";\n\n/// @title OracleUSDCEURChainlinkAvalanche\n/// @author Angle Labs, Inc.\n/// @notice Gives the price of USDC in Euro in base 18\n/// @dev This contract is built to be deployed on Avalanche\ncontract OracleUSDCEURChainlinkAvalanche is BaseOracleChainlinkMultiTwoFeeds {\n string public constant DESCRIPTION = \"USDC/EUR Oracle\";\n\n constructor(uint32 _stalePeriod, address _treasury) BaseOracleChainlinkMultiTwoFeeds(_stalePeriod, _treasury) {}\n\n /// @inheritdoc IOracle\n function circuitChainlink() public pure override returns (AggregatorV3Interface[] memory) {\n AggregatorV3Interface[] memory _circuitChainlink = new AggregatorV3Interface[](2);\n // Oracle USDC/USD\n _circuitChainlink[0] = AggregatorV3Interface(0xF096872672F44d6EBA71458D74fe67F9a77a23B9);\n // Oracle EUR/USD\n _circuitChainlink[1] = AggregatorV3Interface(0x192f2DBA961Bb0277520C082d6bfa87D5961333E);\n return _circuitChainlink;\n }\n}\n" + }, + "contracts/oracle/implementations/mainnet/EUR/OracleBTCEURChainlink.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\nimport \"@chainlink/contracts/src/v0.8/interfaces/AggregatorV3Interface.sol\";\n\nimport \"../../../BaseOracleChainlinkMultiTwoFeeds.sol\";\n\n/// @title OracleBTCEURChainlink\n/// @author Angle Labs, Inc.\n/// @notice Gives the price of BTC in Euro in base 18\ncontract OracleBTCEURChainlink is BaseOracleChainlinkMultiTwoFeeds {\n string public constant DESCRIPTION = \"BTC/EUR Oracle\";\n\n constructor(uint32 _stalePeriod, address _treasury) BaseOracleChainlinkMultiTwoFeeds(_stalePeriod, _treasury) {}\n\n /// @inheritdoc IOracle\n function circuitChainlink() public pure override returns (AggregatorV3Interface[] memory) {\n AggregatorV3Interface[] memory _circuitChainlink = new AggregatorV3Interface[](2);\n // Oracle BTC/USD\n _circuitChainlink[0] = AggregatorV3Interface(0xF4030086522a5bEEa4988F8cA5B36dbC97BeE88c);\n // Oracle EUR/USD\n _circuitChainlink[1] = AggregatorV3Interface(0xb49f677943BC038e9857d61E7d053CaA2C1734C1);\n return _circuitChainlink;\n }\n}\n" + }, + "contracts/oracle/implementations/mainnet/EUR/OracleCBETHEURChainlink.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\nimport \"@chainlink/contracts/src/v0.8/interfaces/AggregatorV3Interface.sol\";\n\nimport \"../../../BaseOracleChainlinkMultiTwoFeeds.sol\";\n\n/// @title OracleCBETHEURChainlink\n/// @author Angle Labs, Inc.\n/// @notice Gives the price of cbETH in Euro in base 18\ncontract OracleCBETHEURChainlink is BaseOracleChainlinkMultiTwoFeeds {\n string public constant DESCRIPTION = \"cbETH/EUR Oracle\";\n\n constructor(uint32 _stalePeriod, address _treasury) BaseOracleChainlinkMultiTwoFeeds(_stalePeriod, _treasury) {}\n\n /// @inheritdoc IOracle\n function circuitChainlink() public pure override returns (AggregatorV3Interface[] memory) {\n AggregatorV3Interface[] memory _circuitChainlink = new AggregatorV3Interface[](3);\n // Oracle cbETH/ETH\n _circuitChainlink[0] = AggregatorV3Interface(0xF017fcB346A1885194689bA23Eff2fE6fA5C483b);\n // Oracle ETH/USD\n _circuitChainlink[1] = AggregatorV3Interface(0x5f4eC3Df9cbd43714FE2740f5E3616155c5b8419);\n // Oracle EUR/USD\n _circuitChainlink[2] = AggregatorV3Interface(0xb49f677943BC038e9857d61E7d053CaA2C1734C1);\n return _circuitChainlink;\n }\n\n /// @inheritdoc BaseOracleChainlinkMultiTwoFeeds\n function read() external view virtual override returns (uint256 quoteAmount) {\n quoteAmount = _getQuoteAmount();\n AggregatorV3Interface[] memory _circuitChainlink = circuitChainlink();\n uint8[3] memory circuitChainIsMultiplied = [1, 1, 0];\n uint8[3] memory chainlinkDecimals = [18, 8, 8];\n uint256 circuitLength = _circuitChainlink.length;\n for (uint256 i; i < circuitLength; ++i) {\n quoteAmount = _readChainlinkFeed(\n quoteAmount,\n _circuitChainlink[i],\n circuitChainIsMultiplied[i],\n chainlinkDecimals[i]\n );\n }\n }\n}\n" + }, + "contracts/oracle/implementations/mainnet/EUR/OracleETHEURChainlink.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\nimport \"@chainlink/contracts/src/v0.8/interfaces/AggregatorV3Interface.sol\";\n\nimport \"../../../BaseOracleChainlinkMultiTwoFeeds.sol\";\n\n/// @title OracleETHEURChainlink\n/// @author Angle Labs, Inc.\n/// @notice Gives the price of ETH in Euro in base 18\ncontract OracleETHEURChainlink is BaseOracleChainlinkMultiTwoFeeds {\n string public constant DESCRIPTION = \"ETH/EUR Oracle\";\n\n constructor(uint32 _stalePeriod, address _treasury) BaseOracleChainlinkMultiTwoFeeds(_stalePeriod, _treasury) {}\n\n /// @inheritdoc IOracle\n function circuitChainlink() public pure override returns (AggregatorV3Interface[] memory) {\n AggregatorV3Interface[] memory _circuitChainlink = new AggregatorV3Interface[](2);\n // Oracle ETH/USD\n _circuitChainlink[0] = AggregatorV3Interface(0x5f4eC3Df9cbd43714FE2740f5E3616155c5b8419);\n // Oracle EUR/USD\n _circuitChainlink[1] = AggregatorV3Interface(0xb49f677943BC038e9857d61E7d053CaA2C1734C1);\n return _circuitChainlink;\n }\n}\n" + }, + "contracts/oracle/implementations/mainnet/EUR/OracleHIGHEURChainlink.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\nimport \"@chainlink/contracts/src/v0.8/interfaces/AggregatorV3Interface.sol\";\n\nimport \"../../../BaseOracleChainlinkMultiTwoFeeds.sol\";\n\n/// @title OracleHIGHEURChainlink\n/// @author Angle Labs, Inc.\n/// @notice Gives the price of HIGH in Euro in base 18\ncontract OracleHIGHEURChainlink is BaseOracleChainlinkMultiTwoFeeds {\n string public constant DESCRIPTION = \"HIGH/EUR Oracle\";\n\n constructor(uint32 _stalePeriod, address _treasury) BaseOracleChainlinkMultiTwoFeeds(_stalePeriod, _treasury) {}\n\n /// @inheritdoc IOracle\n function circuitChainlink() public pure override returns (AggregatorV3Interface[] memory) {\n AggregatorV3Interface[] memory _circuitChainlink = new AggregatorV3Interface[](1);\n // Oracle HIGH/EUR\n _circuitChainlink[0] = AggregatorV3Interface(0x9E8E794ad6Ecdb6d5c7eaBE059D30E907F58859b);\n return _circuitChainlink;\n }\n\n /// @inheritdoc BaseOracleChainlinkMultiTwoFeeds\n function read() external view override returns (uint256 quoteAmount) {\n quoteAmount = _readChainlinkFeed(_getQuoteAmount(), circuitChainlink()[0], 1, 8);\n }\n}\n" + }, + "contracts/oracle/implementations/mainnet/EUR/OracleIB01EURChainlink.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\nimport \"@chainlink/contracts/src/v0.8/interfaces/AggregatorV3Interface.sol\";\n\nimport \"../../../BaseOracleChainlinkMultiTwoFeeds.sol\";\n\n/// @title OracleIB01EURChainlink\n/// @author Angle Labs, Inc.\n/// @notice Gives the price of IB01 in Euro in base 18\ncontract OracleIB01EURChainlink is BaseOracleChainlinkMultiTwoFeeds {\n string public constant DESCRIPTION = \"IB01/EUR Oracle\";\n\n constructor(uint32 _stalePeriod, address _treasury) BaseOracleChainlinkMultiTwoFeeds(_stalePeriod, _treasury) {}\n\n /// @inheritdoc IOracle\n function circuitChainlink() public pure override returns (AggregatorV3Interface[] memory) {\n AggregatorV3Interface[] memory _circuitChainlink = new AggregatorV3Interface[](2);\n // Oracle IB01/USD\n _circuitChainlink[0] = AggregatorV3Interface(0x32d1463EB53b73C095625719Afa544D5426354cB);\n // Oracle EUR/USD\n _circuitChainlink[1] = AggregatorV3Interface(0xb49f677943BC038e9857d61E7d053CaA2C1734C1);\n return _circuitChainlink;\n }\n}\n" + }, + "contracts/oracle/implementations/mainnet/EUR/OracleLUSDEURChainlink.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\nimport \"@chainlink/contracts/src/v0.8/interfaces/AggregatorV3Interface.sol\";\n\nimport \"../../../BaseOracleChainlinkMultiTwoFeeds.sol\";\n\n/// @title OracleLUSDEURChainlink\n/// @author Angle Labs, Inc.\n/// @notice Gives the price of LUSD in Euro in base 18\ncontract OracleLUSDEURChainlink is BaseOracleChainlinkMultiTwoFeeds {\n string public constant DESCRIPTION = \"LUSD/EUR Oracle\";\n\n constructor(uint32 _stalePeriod, address _treasury) BaseOracleChainlinkMultiTwoFeeds(_stalePeriod, _treasury) {}\n\n /// @inheritdoc IOracle\n function circuitChainlink() public pure override returns (AggregatorV3Interface[] memory) {\n AggregatorV3Interface[] memory _circuitChainlink = new AggregatorV3Interface[](2);\n // Oracle LUSD/USD\n _circuitChainlink[0] = AggregatorV3Interface(0x3D7aE7E594f2f2091Ad8798313450130d0Aba3a0);\n // Oracle EUR/USD\n _circuitChainlink[1] = AggregatorV3Interface(0xb49f677943BC038e9857d61E7d053CaA2C1734C1);\n return _circuitChainlink;\n }\n}\n" + }, + "contracts/oracle/implementations/mainnet/EUR/OracleUSDCEURChainlink.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\nimport \"@chainlink/contracts/src/v0.8/interfaces/AggregatorV3Interface.sol\";\n\nimport \"../../../BaseOracleChainlinkMultiTwoFeeds.sol\";\n\n/// @title OracleUSDCEURChainlink\n/// @author Angle Labs, Inc.\n/// @notice Gives the price of USDC in Euro in base 18\ncontract OracleUSDCEURChainlink is BaseOracleChainlinkMultiTwoFeeds {\n string public constant DESCRIPTION = \"USDC/EUR Oracle\";\n\n constructor(uint32 _stalePeriod, address _treasury) BaseOracleChainlinkMultiTwoFeeds(_stalePeriod, _treasury) {}\n\n /// @inheritdoc IOracle\n function circuitChainlink() public pure override returns (AggregatorV3Interface[] memory) {\n AggregatorV3Interface[] memory _circuitChainlink = new AggregatorV3Interface[](2);\n // Oracle USDC/USD\n _circuitChainlink[0] = AggregatorV3Interface(0x8fFfFfd4AfB6115b954Bd326cbe7B4BA576818f6);\n // Oracle EUR/USD\n _circuitChainlink[1] = AggregatorV3Interface(0xb49f677943BC038e9857d61E7d053CaA2C1734C1);\n return _circuitChainlink;\n }\n}\n" + }, + "contracts/oracle/implementations/mainnet/EUR/OracleWSTETHEURChainlink.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\nimport \"@chainlink/contracts/src/v0.8/interfaces/AggregatorV3Interface.sol\";\n\nimport \"../../../BaseOracleChainlinkMultiTwoFeeds.sol\";\nimport \"../../../../interfaces/external/lido/IStETH.sol\";\n\n/// @title OracleWSTETHEURChainlink\n/// @author Angle Labs, Inc.\n/// @notice Gives the price of wSTETH in Euro in base 18\ncontract OracleWSTETHEURChainlink is BaseOracleChainlinkMultiTwoFeeds {\n string public constant DESCRIPTION = \"wSTETH/EUR Oracle\";\n IStETH public constant STETH = IStETH(0xae7ab96520DE3A18E5e111B5EaAb095312D7fE84);\n\n constructor(uint32 _stalePeriod, address _treasury) BaseOracleChainlinkMultiTwoFeeds(_stalePeriod, _treasury) {}\n\n /// @inheritdoc IOracle\n function circuitChainlink() public pure override returns (AggregatorV3Interface[] memory) {\n AggregatorV3Interface[] memory _circuitChainlink = new AggregatorV3Interface[](2);\n // Oracle stETH/USD\n _circuitChainlink[0] = AggregatorV3Interface(0xCfE54B5cD566aB89272946F602D76Ea879CAb4a8);\n // Oracle EUR/USD\n _circuitChainlink[1] = AggregatorV3Interface(0xb49f677943BC038e9857d61E7d053CaA2C1734C1);\n return _circuitChainlink;\n }\n\n /// @inheritdoc BaseOracleChainlinkMultiTwoFeeds\n function _getQuoteAmount() internal view override returns (uint256) {\n return STETH.getPooledEthByShares(1 ether);\n }\n}\n" + }, + "contracts/oracle/implementations/mainnet/USD/OracleWSTETHUSDChainlink.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\nimport \"@chainlink/contracts/src/v0.8/interfaces/AggregatorV3Interface.sol\";\n\nimport \"../../../BaseOracleChainlinkOneFeed.sol\";\nimport \"../../../../interfaces/external/lido/IStETH.sol\";\n\n/// @title OracleWSTETHUSDChainlink\n/// @author Angle Labs, Inc.\n/// @notice Gives the price of wSTETH in USD in base 18\ncontract OracleWSTETHUSDChainlink is BaseOracleChainlinkOneFeed {\n string public constant DESCRIPTION = \"wSTETH/USD Oracle\";\n IStETH public constant STETH = IStETH(0xae7ab96520DE3A18E5e111B5EaAb095312D7fE84);\n\n constructor(uint32 _stalePeriod, address _treasury) BaseOracleChainlinkOneFeed(_stalePeriod, _treasury) {}\n\n /// @inheritdoc IOracle\n function circuitChainlink() public pure override returns (AggregatorV3Interface[] memory) {\n AggregatorV3Interface[] memory _circuitChainlink = new AggregatorV3Interface[](1);\n // Oracle stETH/USD\n _circuitChainlink[0] = AggregatorV3Interface(0xCfE54B5cD566aB89272946F602D76Ea879CAb4a8);\n return _circuitChainlink;\n }\n\n /// @inheritdoc BaseOracleChainlinkOneFeed\n function _getQuoteAmount() internal view override returns (uint256) {\n return STETH.getPooledEthByShares(1 ether);\n }\n}\n" + }, + "contracts/oracle/implementations/mainnet/XAU/OracleETHXAUChainlink.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\nimport \"@chainlink/contracts/src/v0.8/interfaces/AggregatorV3Interface.sol\";\n\nimport \"../../../BaseOracleChainlinkMultiTwoFeeds.sol\";\n\n/// @title OracleETHXAUChainlink\n/// @author Angle Labs, Inc.\n/// @notice Gives the price of ETH in XAU in base 18\ncontract OracleETHXAUChainlink is BaseOracleChainlinkMultiTwoFeeds {\n string public constant DESCRIPTION = \"ETH/GOLD Oracle\";\n\n constructor(uint32 _stalePeriod, address _treasury) BaseOracleChainlinkMultiTwoFeeds(_stalePeriod, _treasury) {}\n\n /// @inheritdoc IOracle\n function circuitChainlink() public pure override returns (AggregatorV3Interface[] memory) {\n AggregatorV3Interface[] memory _circuitChainlink = new AggregatorV3Interface[](2);\n // Oracle ETH/USD\n _circuitChainlink[0] = AggregatorV3Interface(0x5f4eC3Df9cbd43714FE2740f5E3616155c5b8419);\n // Oracle XAU/USD\n _circuitChainlink[1] = AggregatorV3Interface(0x214eD9Da11D2fbe465a6fc601a91E62EbEc1a0D6);\n return _circuitChainlink;\n }\n}\n" + }, + "contracts/oracle/implementations/mainnet/XAU/OracleLUSDXAUChainlink.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\nimport \"@chainlink/contracts/src/v0.8/interfaces/AggregatorV3Interface.sol\";\n\nimport \"../../../BaseOracleChainlinkMultiTwoFeeds.sol\";\n\n/// @title OracleLUSDXAUChainlink\n/// @author Angle Labs, Inc.\n/// @notice Gives the price of LUSD in XAU in base 18\ncontract OracleLUSDXAUChainlink is BaseOracleChainlinkMultiTwoFeeds {\n string public constant DESCRIPTION = \"LUSD/GOLD Oracle\";\n\n constructor(uint32 _stalePeriod, address _treasury) BaseOracleChainlinkMultiTwoFeeds(_stalePeriod, _treasury) {}\n\n /// @inheritdoc IOracle\n function circuitChainlink() public pure override returns (AggregatorV3Interface[] memory) {\n AggregatorV3Interface[] memory _circuitChainlink = new AggregatorV3Interface[](2);\n // Oracle LUSD/USD\n _circuitChainlink[0] = AggregatorV3Interface(0x3D7aE7E594f2f2091Ad8798313450130d0Aba3a0);\n // Oracle XAU/USD\n _circuitChainlink[1] = AggregatorV3Interface(0x214eD9Da11D2fbe465a6fc601a91E62EbEc1a0D6);\n return _circuitChainlink;\n }\n}\n" + }, + "contracts/oracle/implementations/mainnet/XAU/OracleUSDCXAUChainlink.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\nimport \"@chainlink/contracts/src/v0.8/interfaces/AggregatorV3Interface.sol\";\n\nimport \"../../../BaseOracleChainlinkMultiTwoFeeds.sol\";\n\n/// @title OracleUSDCXAUChainlink\n/// @author Angle Labs, Inc.\n/// @notice Gives the price of USDC in XAU in base 18\ncontract OracleUSDCXAUChainlink is BaseOracleChainlinkMultiTwoFeeds {\n string public constant DESCRIPTION = \"USDC/GOLD Oracle\";\n\n constructor(uint32 _stalePeriod, address _treasury) BaseOracleChainlinkMultiTwoFeeds(_stalePeriod, _treasury) {}\n\n /// @inheritdoc IOracle\n function circuitChainlink() public pure override returns (AggregatorV3Interface[] memory) {\n AggregatorV3Interface[] memory _circuitChainlink = new AggregatorV3Interface[](2);\n // Oracle USDC/USD\n _circuitChainlink[0] = AggregatorV3Interface(0x8fFfFfd4AfB6115b954Bd326cbe7B4BA576818f6);\n // Oracle XAU/USD\n _circuitChainlink[1] = AggregatorV3Interface(0x214eD9Da11D2fbe465a6fc601a91E62EbEc1a0D6);\n return _circuitChainlink;\n }\n}\n" + }, + "contracts/oracle/implementations/mainnet/XAU/OracleWSTETHXAUChainlink.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\nimport \"@chainlink/contracts/src/v0.8/interfaces/AggregatorV3Interface.sol\";\n\nimport \"../../../BaseOracleChainlinkMultiTwoFeeds.sol\";\nimport \"../../../../interfaces/external/lido/IStETH.sol\";\n\n/// @title OracleWSTETHXAUChainlink\n/// @author Angle Labs, Inc.\n/// @notice Gives the price of wSTETH in XAU in base 18\ncontract OracleWSTETHXAUChainlink is BaseOracleChainlinkMultiTwoFeeds {\n string public constant DESCRIPTION = \"wSTETH/XAU Oracle\";\n IStETH public constant STETH = IStETH(0xae7ab96520DE3A18E5e111B5EaAb095312D7fE84);\n\n constructor(uint32 _stalePeriod, address _treasury) BaseOracleChainlinkMultiTwoFeeds(_stalePeriod, _treasury) {}\n\n /// @inheritdoc IOracle\n function circuitChainlink() public pure override returns (AggregatorV3Interface[] memory) {\n AggregatorV3Interface[] memory _circuitChainlink = new AggregatorV3Interface[](2);\n // Oracle stETH/USD\n _circuitChainlink[0] = AggregatorV3Interface(0xCfE54B5cD566aB89272946F602D76Ea879CAb4a8);\n // Oracle XAU/USD\n _circuitChainlink[1] = AggregatorV3Interface(0x214eD9Da11D2fbe465a6fc601a91E62EbEc1a0D6);\n return _circuitChainlink;\n }\n\n /// @inheritdoc BaseOracleChainlinkMultiTwoFeeds\n function _getQuoteAmount() internal view override returns (uint256) {\n return STETH.getPooledEthByShares(1 ether);\n }\n}\n" + }, + "contracts/oracle/implementations/optimism/EUR/OracleETHEURChainlinkOptimism.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\nimport \"@chainlink/contracts/src/v0.8/interfaces/AggregatorV3Interface.sol\";\n\nimport \"../../../BaseOracleChainlinkMultiTwoFeeds.sol\";\n\n/// @title OracleETHEURChainlinkOptimism\n/// @author Angle Labs, Inc.\n/// @notice Gives the price of ETH in Euro in base 18\n/// @dev This contract is built to be deployed on Optimism\ncontract OracleETHEURChainlinkOptimism is BaseOracleChainlinkMultiTwoFeeds {\n string public constant DESCRIPTION = \"ETH/EUR Oracle\";\n\n constructor(uint32 _stalePeriod, address _treasury) BaseOracleChainlinkMultiTwoFeeds(_stalePeriod, _treasury) {}\n\n /// @inheritdoc IOracle\n function circuitChainlink() public pure override returns (AggregatorV3Interface[] memory) {\n AggregatorV3Interface[] memory _circuitChainlink = new AggregatorV3Interface[](2);\n // Oracle ETH/USD\n _circuitChainlink[0] = AggregatorV3Interface(0x13e3Ee699D1909E989722E753853AE30b17e08c5);\n // Oracle EUR/USD\n _circuitChainlink[1] = AggregatorV3Interface(0x3626369857A10CcC6cc3A6e4f5C2f5984a519F20);\n return _circuitChainlink;\n }\n}\n" + }, + "contracts/oracle/implementations/optimism/EUR/OracleOPEURChainlinkOptimism.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\nimport \"@chainlink/contracts/src/v0.8/interfaces/AggregatorV3Interface.sol\";\n\nimport \"../../../BaseOracleChainlinkMultiTwoFeeds.sol\";\n\n/// @title OracleOPEURChainlinkOptimism\n/// @author Angle Labs, Inc.\n/// @notice Gives the price of OP in Euro in base 18\n/// @dev This contract is built to be deployed on Optimism\ncontract OracleOPEURChainlinkOptimism is BaseOracleChainlinkMultiTwoFeeds {\n string public constant DESCRIPTION = \"OP/EUR Oracle\";\n\n constructor(uint32 _stalePeriod, address _treasury) BaseOracleChainlinkMultiTwoFeeds(_stalePeriod, _treasury) {}\n\n /// @inheritdoc IOracle\n function circuitChainlink() public pure override returns (AggregatorV3Interface[] memory) {\n AggregatorV3Interface[] memory _circuitChainlink = new AggregatorV3Interface[](2);\n // Oracle OP/USD\n _circuitChainlink[0] = AggregatorV3Interface(0x0D276FC14719f9292D5C1eA2198673d1f4269246);\n // Oracle EUR/USD\n _circuitChainlink[1] = AggregatorV3Interface(0x3626369857A10CcC6cc3A6e4f5C2f5984a519F20);\n return _circuitChainlink;\n }\n}\n" + }, + "contracts/oracle/implementations/optimism/EUR/OracleUSDCEURChainlinkOptimism.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\nimport \"@chainlink/contracts/src/v0.8/interfaces/AggregatorV3Interface.sol\";\n\nimport \"../../../BaseOracleChainlinkMultiTwoFeeds.sol\";\n\n/// @title OracleUSDCEURChainlinkOptimism\n/// @author Angle Labs, Inc.\n/// @notice Gives the price of USDC in Euro in base 18\n/// @dev This contract is built to be deployed on Optimism\ncontract OracleUSDCEURChainlinkOptimism is BaseOracleChainlinkMultiTwoFeeds {\n string public constant DESCRIPTION = \"USDC/EUR Oracle\";\n\n constructor(uint32 _stalePeriod, address _treasury) BaseOracleChainlinkMultiTwoFeeds(_stalePeriod, _treasury) {}\n\n /// @inheritdoc IOracle\n function circuitChainlink() public pure override returns (AggregatorV3Interface[] memory) {\n AggregatorV3Interface[] memory _circuitChainlink = new AggregatorV3Interface[](2);\n // Oracle USDC/USD\n _circuitChainlink[0] = AggregatorV3Interface(0x16a9FA2FDa030272Ce99B29CF780dFA30361E0f3);\n // Oracle EUR/USD\n _circuitChainlink[1] = AggregatorV3Interface(0x3626369857A10CcC6cc3A6e4f5C2f5984a519F20);\n return _circuitChainlink;\n }\n}\n" + }, + "contracts/oracle/implementations/polygon/EUR/OracleBTCEURChainlinkPolygon.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\nimport \"@chainlink/contracts/src/v0.8/interfaces/AggregatorV3Interface.sol\";\n\nimport \"../../../BaseOracleChainlinkMultiTwoFeeds.sol\";\n\n/// @title OracleBTCEURChainlinkPolygon\n/// @author Angle Labs, Inc.\n/// @notice Gives the price of BTC in Euro in base 18\n/// @dev This contract is built to be deployed on Polygon\ncontract OracleBTCEURChainlinkPolygon is BaseOracleChainlinkMultiTwoFeeds {\n string public constant DESCRIPTION = \"BTC/EUR Oracle\";\n\n constructor(uint32 _stalePeriod, address _treasury) BaseOracleChainlinkMultiTwoFeeds(_stalePeriod, _treasury) {}\n\n /// @inheritdoc IOracle\n function circuitChainlink() public pure override returns (AggregatorV3Interface[] memory) {\n AggregatorV3Interface[] memory _circuitChainlink = new AggregatorV3Interface[](2);\n // Oracle BTC/USD\n _circuitChainlink[0] = AggregatorV3Interface(0xc907E116054Ad103354f2D350FD2514433D57F6f);\n // Oracle EUR/USD\n _circuitChainlink[1] = AggregatorV3Interface(0x73366Fe0AA0Ded304479862808e02506FE556a98);\n return _circuitChainlink;\n }\n}\n" + }, + "contracts/oracle/implementations/polygon/EUR/OracleETHEURChainlinkPolygon.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\nimport \"@chainlink/contracts/src/v0.8/interfaces/AggregatorV3Interface.sol\";\n\nimport \"../../../BaseOracleChainlinkMultiTwoFeeds.sol\";\n\n/// @title OracleETHEURChainlinkPolygon\n/// @author Angle Labs, Inc.\n/// @notice Gives the price of ETH in Euro in base 18\n/// @dev This contract is built to be deployed on Polygon\ncontract OracleETHEURChainlinkPolygon is BaseOracleChainlinkMultiTwoFeeds {\n string public constant DESCRIPTION = \"ETH/EUR Oracle\";\n\n constructor(uint32 _stalePeriod, address _treasury) BaseOracleChainlinkMultiTwoFeeds(_stalePeriod, _treasury) {}\n\n /// @inheritdoc IOracle\n function circuitChainlink() public pure override returns (AggregatorV3Interface[] memory) {\n AggregatorV3Interface[] memory _circuitChainlink = new AggregatorV3Interface[](2);\n // Oracle ETH/USD\n _circuitChainlink[0] = AggregatorV3Interface(0xF9680D99D6C9589e2a93a78A04A279e509205945);\n // Oracle EUR/USD\n _circuitChainlink[1] = AggregatorV3Interface(0x73366Fe0AA0Ded304479862808e02506FE556a98);\n return _circuitChainlink;\n }\n}\n" + }, + "contracts/oracle/implementations/polygon/EUR/OracleMAIEURChainlinkPolygon.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\nimport \"@chainlink/contracts/src/v0.8/interfaces/AggregatorV3Interface.sol\";\n\nimport \"../../../BaseOracleChainlinkMultiTwoFeeds.sol\";\n\n/// @title OracleMAIEURChainlinkPolygon\n/// @author Angle Labs, Inc.\n/// @notice Gives the price of MAI in Euro in base 18\n/// @dev This contract is built to be deployed on Polygon\ncontract OracleMAIEURChainlinkPolygon is BaseOracleChainlinkMultiTwoFeeds {\n string public constant DESCRIPTION = \"MAI/EUR Oracle\";\n\n constructor(uint32 _stalePeriod, address _treasury) BaseOracleChainlinkMultiTwoFeeds(_stalePeriod, _treasury) {}\n\n /// @inheritdoc IOracle\n function circuitChainlink() public pure override returns (AggregatorV3Interface[] memory) {\n AggregatorV3Interface[] memory _circuitChainlink = new AggregatorV3Interface[](2);\n // Oracle MAI/USD\n _circuitChainlink[0] = AggregatorV3Interface(0xd8d483d813547CfB624b8Dc33a00F2fcbCd2D428);\n // Oracle EUR/USD\n _circuitChainlink[1] = AggregatorV3Interface(0x73366Fe0AA0Ded304479862808e02506FE556a98);\n return _circuitChainlink;\n }\n}\n" + }, + "contracts/oracle/implementations/polygon/EUR/OracleMATICEURChainlinkPolygon.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\nimport \"@chainlink/contracts/src/v0.8/interfaces/AggregatorV3Interface.sol\";\n\nimport \"../../../BaseOracleChainlinkMultiTwoFeeds.sol\";\n\n/// @title OracleMATICEURChainlinkPolygon\n/// @author Angle Labs, Inc.\n/// @notice Gives the price of MATIC in Euro in base 18\n/// @dev This contract is built to be deployed on Polygon\ncontract OracleMATICEURChainlinkPolygon is BaseOracleChainlinkMultiTwoFeeds {\n string public constant DESCRIPTION = \"MATIC/EUR Oracle\";\n\n constructor(uint32 _stalePeriod, address _treasury) BaseOracleChainlinkMultiTwoFeeds(_stalePeriod, _treasury) {}\n\n /// @inheritdoc IOracle\n function circuitChainlink() public pure override returns (AggregatorV3Interface[] memory) {\n AggregatorV3Interface[] memory _circuitChainlink = new AggregatorV3Interface[](2);\n // Oracle MATIC/USD\n _circuitChainlink[0] = AggregatorV3Interface(0xAB594600376Ec9fD91F8e885dADF0CE036862dE0);\n // Oracle EUR/USD\n _circuitChainlink[1] = AggregatorV3Interface(0x73366Fe0AA0Ded304479862808e02506FE556a98);\n return _circuitChainlink;\n }\n}\n" + }, + "contracts/oracle/implementations/polygon/EUR/OracleUSDCEURChainlinkPolygon.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\nimport \"../../../BaseOracleChainlinkMultiTwoFeeds.sol\";\n\n/// @title OracleUSDCEURChainlinkPolygon\n/// @author Angle Labs, Inc.\n/// @notice Gives the price of USDC in Euro in base 18\n/// @dev This contract is built to be deployed on Polygon\ncontract OracleUSDCEURChainlinkPolygon is BaseOracleChainlinkMultiTwoFeeds {\n string public constant DESCRIPTION = \"USDC/EUR Oracle\";\n\n constructor(uint32 _stalePeriod, address _treasury) BaseOracleChainlinkMultiTwoFeeds(_stalePeriod, _treasury) {}\n\n /// @inheritdoc IOracle\n function circuitChainlink() public pure override returns (AggregatorV3Interface[] memory) {\n AggregatorV3Interface[] memory _circuitChainlink = new AggregatorV3Interface[](2);\n // Oracle USDC/USD\n _circuitChainlink[0] = AggregatorV3Interface(0xfE4A8cc5b5B2366C1B58Bea3858e81843581b2F7);\n // Oracle EUR/USD\n _circuitChainlink[1] = AggregatorV3Interface(0x73366Fe0AA0Ded304479862808e02506FE556a98);\n return _circuitChainlink;\n }\n}\n" + }, + "contracts/oracle/implementations/polygon/XAU/OracleETHXAUChainlinkPolygon.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\nimport \"@chainlink/contracts/src/v0.8/interfaces/AggregatorV3Interface.sol\";\n\nimport \"../../../BaseOracleChainlinkMultiTwoFeeds.sol\";\n\n/// @title OracleETHXAUChainlinkPolygon\n/// @author Angle Labs, Inc.\n/// @notice Gives the price of ETH in XAU in base 18\n/// @dev This contract is built to be deployed on Polygon\ncontract OracleETHXAUChainlinkPolygon is BaseOracleChainlinkMultiTwoFeeds {\n string public constant DESCRIPTION = \"ETH/GOLD Oracle\";\n\n constructor(uint32 _stalePeriod, address _treasury) BaseOracleChainlinkMultiTwoFeeds(_stalePeriod, _treasury) {}\n\n /// @inheritdoc IOracle\n function circuitChainlink() public pure override returns (AggregatorV3Interface[] memory) {\n AggregatorV3Interface[] memory _circuitChainlink = new AggregatorV3Interface[](2);\n // Oracle ETH/USD\n _circuitChainlink[0] = AggregatorV3Interface(0xF9680D99D6C9589e2a93a78A04A279e509205945);\n // Oracle XAU/USD\n _circuitChainlink[1] = AggregatorV3Interface(0x0C466540B2ee1a31b441671eac0ca886e051E410);\n return _circuitChainlink;\n }\n}\n" + }, + "contracts/oracle/KeeperRegistry.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\nimport \"@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol\";\nimport \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\nimport \"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\";\n\nimport \"../interfaces/ICoreBorrow.sol\";\nimport \"../interfaces/IKeeperRegistry.sol\";\n\n/// @title KeeperRegistry\n/// @notice Maintains a mapping of keepers authorized to use the core module just after oracle updates\n/// @author Angle Labs, Inc.\ncontract KeeperRegistry is Initializable, IKeeperRegistry {\n using SafeERC20 for IERC20;\n\n /// @notice Contract handling access control\n ICoreBorrow public coreBorrow;\n\n /// @notice Trusted EOAs - needs to be tx.origin\n mapping(address => uint256) public trusted;\n\n uint256[48] private __gap;\n\n // =================================== EVENTS ==================================\n\n event TrustedToggled(address indexed wallet, bool trust);\n\n // =================================== ERRORS ==================================\n\n error NotGovernorOrGuardian();\n error NotTrusted();\n error ZeroAddress();\n\n // ================================= MODIFIERS =================================\n\n /// @notice Checks whether the `msg.sender` has the governor role or the guardian role\n modifier onlyGovernorOrGuardian() {\n if (!coreBorrow.isGovernorOrGuardian(msg.sender)) revert NotGovernorOrGuardian();\n _;\n }\n\n // ================================ CONSTRUCTOR ================================\n\n constructor() initializer {}\n\n function initialize(ICoreBorrow _coreBorrow) public initializer {\n if (address(_coreBorrow) == address(0)) revert ZeroAddress();\n coreBorrow = _coreBorrow;\n }\n\n // =============================== MAIN FUNCTIONS ==============================\n\n /// @notice Adds or removes a trusted keeper bot\n function toggleTrusted(address eoa) external onlyGovernorOrGuardian {\n uint256 trustedStatus = 1 - trusted[eoa];\n trusted[eoa] = trustedStatus;\n emit TrustedToggled(eoa, trustedStatus == 1);\n }\n\n /// @inheritdoc IKeeperRegistry\n function isTrusted(address caller) external view returns (bool) {\n return trusted[caller] == 1;\n }\n}\n" + }, + "contracts/oracle/OracleChainlinkMulti.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\nimport \"@chainlink/contracts/src/v0.8/interfaces/AggregatorV3Interface.sol\";\n\nimport \"./BaseOracleChainlinkMulti.sol\";\n\n/// @title OracleChainlinkMulti\n/// @author Angle Labs, Inc.\n/// @notice Oracle contract, one contract is deployed per collateral/stablecoin pair\n/// @dev This contract concerns an oracle that uses Chainlink with multiple pools to read from\n/// @dev Typically we expect to use this contract to read like the ETH/USD and then USD/EUR feed\ncontract OracleChainlinkMulti is BaseOracleChainlinkMulti {\n // ========================= Parameters and References =========================\n\n /// @notice Chainlink pools, the order of the pools has to be the order in which they are read for the computation\n /// of the price\n AggregatorV3Interface[] internal _circuitChainlink;\n /// @notice Whether each rate for the pairs in `circuitChainlink` should be multiplied or divided\n uint8[] public circuitChainIsMultiplied;\n /// @notice Decimals for each Chainlink pairs\n uint8[] public chainlinkDecimals;\n /// @notice Unit of the stablecoin\n uint256 public immutable outBase;\n /// @notice Description of the assets concerned by the oracle and the price outputted\n string public description;\n\n // ===================================== Error =================================\n\n error IncompatibleLengths();\n\n /// @notice Constructor for an oracle using Chainlink with multiple pools to read from\n /// @param circuitChainlink_ Chainlink pool addresses (in order)\n /// @param _circuitChainIsMultiplied Whether we should multiply or divide by this rate\n /// @param _outBase Unit of the stablecoin (or the out asset) associated to the oracle\n /// @param _stalePeriod Minimum feed update frequency for the oracle to not revert\n /// @param _treasury Treasury associated to the VaultManager which reads from this feed\n /// @param _description Description of the assets concerned by the oracle\n /// @dev For instance, if this oracle is supposed to give the price of ETH in EUR, and if the agEUR\n /// stablecoin associated to EUR has 18 decimals, then `outBase` should be 10**18\n constructor(\n address[] memory circuitChainlink_,\n uint8[] memory _circuitChainIsMultiplied,\n uint256 _outBase,\n uint32 _stalePeriod,\n address _treasury,\n string memory _description\n ) BaseOracleChainlinkMulti(_stalePeriod, _treasury) {\n outBase = _outBase;\n description = _description;\n uint256 circuitLength = circuitChainlink_.length;\n if (circuitLength == 0 || circuitLength != _circuitChainIsMultiplied.length) revert IncompatibleLengths();\n for (uint256 i; i < circuitLength; ++i) {\n AggregatorV3Interface _pool = AggregatorV3Interface(circuitChainlink_[i]);\n _circuitChainlink.push(_pool);\n chainlinkDecimals.push(_pool.decimals());\n }\n circuitChainIsMultiplied = _circuitChainIsMultiplied;\n }\n\n // ============================= Reading Oracles ===============================\n\n /// @inheritdoc IOracle\n function circuitChainlink() public view override returns (AggregatorV3Interface[] memory) {\n return _circuitChainlink;\n }\n\n /// @inheritdoc IOracle\n function read() external view override returns (uint256 quoteAmount) {\n quoteAmount = outBase;\n uint256 circuitLength = _circuitChainlink.length;\n for (uint256 i; i < circuitLength; ++i) {\n quoteAmount = _readChainlinkFeed(\n quoteAmount,\n _circuitChainlink[i],\n circuitChainIsMultiplied[i],\n chainlinkDecimals[i]\n );\n }\n }\n}\n" + }, + "contracts/settlement/Settlement.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\nimport \"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\";\nimport \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\nimport \"@openzeppelin/contracts/token/ERC20/extensions/IERC20Metadata.sol\";\n\nimport \"../interfaces/IAgToken.sol\";\nimport \"../interfaces/ISwapper.sol\";\nimport \"../interfaces/IVaultManager.sol\";\n\n/// @title Settlement\n/// @author Angle Labs, Inc.\n/// @notice Settlement Contract for a VaultManager\n/// @dev This settlement contract should be activated by a careful governance which needs to have performed\n/// some key operations before activating this contract\n/// @dev In case of global settlement, there should be one settlement contract per `VaultManager`\ncontract Settlement {\n using SafeERC20 for IERC20;\n\n /// @notice Base used for parameter computation\n uint256 public constant BASE_PARAMS = 10 ** 9;\n /// @notice Base used for interest computation\n uint256 public constant BASE_INTEREST = 10 ** 27;\n /// @notice Base used for exchange rate computation. It is assumed\n /// that stablecoins have this base\n uint256 public constant BASE_STABLECOIN = 10 ** 18;\n /// @notice Duration of the claim period for over-collateralized vaults\n uint256 public constant OVER_COLLATERALIZED_CLAIM_DURATION = 3 * 24 * 3600;\n\n // =============== Immutable references set in the constructor =================\n\n /// @notice `VaultManager` of this settlement contract\n IVaultManager public immutable vaultManager;\n /// @notice Reference to the stablecoin supported by the `VaultManager` contract\n IAgToken public immutable stablecoin;\n /// @notice Reference to the collateral supported by the `VaultManager`\n IERC20 public immutable collateral;\n /// @notice Base of the collateral\n uint256 internal immutable _collatBase;\n\n // ================ Variables frozen at settlement activation ==================\n\n /// @notice Value of the oracle for the collateral/stablecoin pair\n uint256 public oracleValue;\n /// @notice Value of the interest accumulator at settlement activation\n uint256 public interestAccumulator;\n /// @notice Timestamp at which settlement was activated\n uint256 public activationTimestamp;\n /// @notice Collateral factor of the `VaultManager`\n uint64 public collateralFactor;\n\n // =================== Variables updated during the process ====================\n\n /// @notice How much collateral you can get from stablecoins\n uint256 public collateralStablecoinExchangeRate;\n /// @notice Amount of collateral that will be left over at the end of the process\n uint256 public leftOverCollateral;\n /// @notice Whether the `collateralStablecoinExchangeRate` has been computed\n bool public exchangeRateComputed;\n /// @notice Maps a vault to 1 if it was claimed by its owner\n mapping(uint256 => uint256) public vaultCheck;\n\n // ================================ Events =====================================\n\n event GlobalClaimPeriodActivated(uint256 _collateralStablecoinExchangeRate);\n event Recovered(address indexed tokenAddress, address indexed to, uint256 amount);\n event SettlementActivated(uint256 startTimestamp);\n event VaultClaimed(uint256 vaultID, uint256 stablecoinAmount, uint256 collateralAmount);\n\n // ================================ Errors =====================================\n\n error GlobalClaimPeriodNotStarted();\n error InsolventVault();\n error NotGovernor();\n error NotOwner();\n error RestrictedClaimPeriodNotEnded();\n error SettlementNotInitialized();\n error VaultAlreadyClaimed();\n\n /// @notice Constructor of the contract\n /// @param _vaultManager Address of the `VaultManager` associated to this `Settlement` contract\n /// @dev Out of safety, this constructor reads values from the `VaultManager` contract directly\n constructor(IVaultManager _vaultManager) {\n vaultManager = _vaultManager;\n stablecoin = _vaultManager.stablecoin();\n collateral = _vaultManager.collateral();\n _collatBase = 10 ** (IERC20Metadata(address(collateral)).decimals());\n }\n\n /// @notice Checks whether the `msg.sender` has the governor role or not\n modifier onlyGovernor() {\n if (!(vaultManager.treasury().isGovernor(msg.sender))) revert NotGovernor();\n _;\n }\n\n /// @notice Activates the settlement contract\n /// @dev When calling this function governance should make sure to have:\n /// 1. Accrued the interest rate on the contract\n /// 2. Paused the contract\n /// 3. Recovered all the collateral available in the `VaultManager` contract either\n /// by doing a contract upgrade or by calling a `recoverERC20` method if supported\n function activateSettlement() external onlyGovernor {\n oracleValue = (vaultManager.oracle()).read();\n interestAccumulator = vaultManager.interestAccumulator();\n activationTimestamp = block.timestamp;\n collateralFactor = vaultManager.collateralFactor();\n emit SettlementActivated(block.timestamp);\n }\n\n /// @notice Allows the owner of an over-collateralized vault to claim its collateral upon bringing back all owed stablecoins\n /// @param vaultID ID of the vault to claim\n /// @param to Address to which collateral should be sent\n /// @param who Address which should be notified if needed of the transfer of stablecoins and collateral\n /// @param data Data to pass to the `who` contract for it to successfully give the correct amount of stablecoins\n /// to the `msg.sender` address\n /// @return Amount of collateral sent to the `to` address\n /// @return Amount of stablecoins sent to the contract\n /// @dev Claiming can only happen short after settlement activation\n /// @dev A vault cannot be claimed twice and only the owner of the vault can claim it (regardless of the approval logic)\n /// @dev Only over-collateralized vaults can be claimed from this medium\n function claimOverCollateralizedVault(\n uint256 vaultID,\n address to,\n address who,\n bytes memory data\n ) external returns (uint256, uint256) {\n if (activationTimestamp == 0 || block.timestamp > activationTimestamp + OVER_COLLATERALIZED_CLAIM_DURATION)\n revert SettlementNotInitialized();\n if (vaultCheck[vaultID] == 1) revert VaultAlreadyClaimed();\n if (vaultManager.ownerOf(vaultID) != msg.sender) revert NotOwner();\n (uint256 collateralAmount, uint256 normalizedDebt) = vaultManager.vaultData(vaultID);\n uint256 vaultDebt = (normalizedDebt * interestAccumulator) / BASE_INTEREST;\n if (collateralAmount * oracleValue * collateralFactor < vaultDebt * BASE_PARAMS * _collatBase)\n revert InsolventVault();\n vaultCheck[vaultID] = 1;\n emit VaultClaimed(vaultID, vaultDebt, collateralAmount);\n return _handleRepay(collateralAmount, vaultDebt, to, who, data);\n }\n\n /// @notice Activates the global claim period by setting the `collateralStablecoinExchangeRate` which is going to\n /// dictate how much of collateral will be recoverable for each stablecoin\n /// @dev This function can only be called by the governor in order to allow it in case multiple settlements happen across\n /// different `VaultManager` to rebalance the amount of stablecoins on each to make sure that across all settlement contracts\n /// a similar value of collateral can be obtained against a similar value of stablecoins\n function activateGlobalClaimPeriod() external onlyGovernor {\n if (activationTimestamp == 0 || block.timestamp <= activationTimestamp + OVER_COLLATERALIZED_CLAIM_DURATION)\n revert RestrictedClaimPeriodNotEnded();\n uint256 collateralBalance = collateral.balanceOf(address(this));\n uint256 leftOverDebt = (vaultManager.totalNormalizedDebt() * interestAccumulator) / BASE_INTEREST;\n uint256 stablecoinBalance = stablecoin.balanceOf(address(this));\n // How much 1 of stablecoin will give you in collateral\n uint256 _collateralStablecoinExchangeRate;\n\n if (stablecoinBalance < leftOverDebt) {\n // The left over debt is the total debt minus the stablecoins which have already been accumulated\n // in the first phase\n leftOverDebt -= stablecoinBalance;\n // If you control all the debt, then you are entitled to get all the collateral left in the protocol\n _collateralStablecoinExchangeRate = (collateralBalance * BASE_STABLECOIN) / leftOverDebt;\n // But at the same time, you cannot get more collateral than the value of the stablecoins you brought\n uint256 maxExchangeRate = (BASE_STABLECOIN * _collatBase) / oracleValue;\n if (_collateralStablecoinExchangeRate >= maxExchangeRate) {\n // In this situation, we're sure that `leftOverCollateral` will be positive: governance should be wary\n // to call `recoverERC20` short after though as there's nothing that is going to prevent people to redeem\n // more stablecoins than the `leftOverDebt`\n leftOverCollateral = collateralBalance - (leftOverDebt * _collatBase) / oracleValue;\n _collateralStablecoinExchangeRate = maxExchangeRate;\n }\n }\n exchangeRateComputed = true;\n // In the else case where there is no debt left, you cannot get anything from your stablecoins\n // and so the `collateralStablecoinExchangeRate` is null\n collateralStablecoinExchangeRate = _collateralStablecoinExchangeRate;\n emit GlobalClaimPeriodActivated(_collateralStablecoinExchangeRate);\n }\n\n /// @notice Allows to claim collateral from stablecoins\n /// @param to Address to which collateral should be sent\n /// @param who Address which should be notified if needed of the transfer of stablecoins and collateral\n /// @param data Data to pass to the `who` contract for it to successfully give the correct amount of stablecoins\n /// to the `msg.sender` address\n /// @return Amount of collateral sent to the `to` address\n /// @return Amount of stablecoins sent to the contract\n /// @dev This function reverts if the `collateralStablecoinExchangeRate` is null and hence if the global claim period has\n /// not been activated\n function claimCollateralFromStablecoins(\n uint256 stablecoinAmount,\n address to,\n address who,\n bytes memory data\n ) external returns (uint256, uint256) {\n if (!exchangeRateComputed) revert GlobalClaimPeriodNotStarted();\n return\n _handleRepay(\n (stablecoinAmount * collateralStablecoinExchangeRate) / BASE_STABLECOIN,\n stablecoinAmount,\n to,\n who,\n data\n );\n }\n\n /// @notice Handles the simultaneous repayment of stablecoins with a transfer of collateral\n /// @param collateralAmountToGive Amount of collateral the contract should give\n /// @param stableAmountToRepay Amount of stablecoins the contract should burn from the call\n /// @param to Address to which stablecoins should be sent\n /// @param who Address which should be notified if needed of the transfer\n /// @param data Data to pass to the `who` contract for it to successfully give the correct amount of stablecoins\n /// to the `msg.sender` address\n /// @dev This function allows for capital-efficient claims of collateral from stablecoins\n function _handleRepay(\n uint256 collateralAmountToGive,\n uint256 stableAmountToRepay,\n address to,\n address who,\n bytes memory data\n ) internal returns (uint256, uint256) {\n collateral.safeTransfer(to, collateralAmountToGive);\n if (data.length != 0) {\n ISwapper(who).swap(\n collateral,\n IERC20(address(stablecoin)),\n msg.sender,\n stableAmountToRepay,\n collateralAmountToGive,\n data\n );\n }\n stablecoin.transferFrom(msg.sender, address(this), stableAmountToRepay);\n return (collateralAmountToGive, stableAmountToRepay);\n }\n\n /// @notice Recovers leftover tokens from the contract or tokens that were mistakenly sent to the contract\n /// @param tokenAddress Address of the token to recover\n /// @param to Address to send the remaining tokens to\n /// @param amountToRecover Amount to recover from the contract\n /// @dev Governors cannot recover more collateral than what would be leftover from the contract\n /// @dev This function can be used to rebalance stablecoin balances across different settlement contracts\n /// to make sure every stablecoin can be redeemed for the same value of collateral\n /// @dev It can also be used to recover tokens that are mistakenly sent to this contract\n function recoverERC20(address tokenAddress, address to, uint256 amountToRecover) external onlyGovernor {\n if (tokenAddress == address(collateral)) {\n if (!exchangeRateComputed) revert GlobalClaimPeriodNotStarted();\n leftOverCollateral -= amountToRecover;\n collateral.safeTransfer(to, amountToRecover);\n } else {\n IERC20(tokenAddress).safeTransfer(to, amountToRecover);\n }\n emit Recovered(tokenAddress, to, amountToRecover);\n }\n}\n" + }, + "contracts/swapper/Swapper.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\n/*\n * █ \n ***** ▓▓▓ \n * ▓▓▓▓▓▓▓ \n * ///. ▓▓▓▓▓▓▓▓▓▓▓▓▓ \n ***** //////// ▓▓▓▓▓▓▓ \n * ///////////// ▓▓▓ \n ▓▓ ////////////////// █ ▓▓ \n ▓▓ ▓▓ /////////////////////// ▓▓ ▓▓ \n ▓▓ ▓▓ //////////////////////////// ▓▓ ▓▓ \n ▓▓ ▓▓ /////////▓▓▓///////▓▓▓///////// ▓▓ ▓▓ \n ▓▓ ,////////////////////////////////////// ▓▓ ▓▓ \n ▓▓ ////////////////////////////////////////// ▓▓ \n ▓▓ //////////////////////▓▓▓▓///////////////////// \n ,//////////////////////////////////////////////////// \n .////////////////////////////////////////////////////////// \n .//////////////////////////██.,//////////////////////////█ \n .//////////////////////████..,./////////////////////██ \n ...////////////////███████.....,.////////////////███ \n ,.,////////////████████ ........,///////////████ \n .,.,//////█████████ ,.......///////████ \n ,..//████████ ........./████ \n ..,██████ .....,███ \n .██ ,.,█ \n \n \n \n ▓▓ ▓▓▓▓▓▓▓▓▓▓ ▓▓▓▓▓▓▓▓▓▓ ▓▓ ▓▓▓▓▓▓▓▓▓▓ \n ▓▓▓▓▓▓ ▓▓▓ ▓▓▓ ▓▓▓ ▓▓ ▓▓ ▓▓▓▓ \n ▓▓▓ ▓▓▓ ▓▓▓ ▓▓▓ ▓▓▓ ▓▓▓ ▓▓ ▓▓▓▓▓ \n ▓▓▓ ▓▓ ▓▓▓ ▓▓▓ ▓▓▓▓▓▓▓▓▓▓ ▓▓▓▓▓▓▓▓▓▓ ▓▓▓▓▓▓▓▓▓▓ \n*/\n\npragma solidity ^0.8.12;\n\nimport \"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\";\nimport \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\n\nimport \"../interfaces/IAngleRouterSidechain.sol\";\nimport \"../interfaces/ICoreBorrow.sol\";\nimport \"../interfaces/ISwapper.sol\";\nimport \"../interfaces/external/lido/IWStETH.sol\";\nimport \"../interfaces/external/uniswap/IUniswapRouter.sol\";\n\n// ==================================== ENUM ===================================\n\n/// @notice All possible swaps\nenum SwapType {\n UniswapV3,\n oneInch,\n AngleRouter,\n Leverage,\n None\n}\n\n/// @title Swapper\n/// @author Angle Labs, Inc.\n/// @notice Swapper contract facilitating interactions with Angle VaultManager contracts, notably\n/// liquidation and leverage transactions\ncontract Swapper is ISwapper {\n using SafeERC20 for IERC20;\n\n // ===================== CONSTANTS AND IMMUTABLE VARIABLES =====================\n\n /// @notice Reference to the `CoreBorrow` contract of the module which handles all AccessControl logic\n ICoreBorrow public immutable core;\n /// @notice Uniswap Router contract\n IUniswapV3Router public immutable uniV3Router;\n /// @notice 1inch Router\n address public immutable oneInch;\n /// @notice AngleRouter\n IAngleRouterSidechain public immutable angleRouter;\n\n // =================================== ERRORS ==================================\n\n error EmptyReturnMessage();\n error IncompatibleLengths();\n error NotGovernorOrGuardian();\n error TooSmallAmountOut();\n error ZeroAddress();\n\n /// @notice Constructor of the contract\n /// @param _core Core address\n /// @param _uniV3Router UniswapV3 Router address\n /// @param _oneInch 1inch Router address\n /// @param _angleRouter AngleRouter contract address\n constructor(\n ICoreBorrow _core,\n IUniswapV3Router _uniV3Router,\n address _oneInch,\n IAngleRouterSidechain _angleRouter\n ) {\n if (address(_core) == address(0) || _oneInch == address(0) || address(_angleRouter) == address(0))\n revert ZeroAddress();\n core = _core;\n uniV3Router = _uniV3Router;\n oneInch = _oneInch;\n angleRouter = _angleRouter;\n }\n\n // ========================= EXTERNAL ACCESS FUNCTIONS =========================\n\n /// @inheritdoc ISwapper\n /// @dev This function swaps the `inToken` to the `outToken` by doing a UniV3 swap, a 1inch swap or by interacting\n /// with the `AngleRouter` contract\n /// @dev One slippage check is performed at the end of the call\n /// @dev In this implementation, the function tries to make sure that the `outTokenRecipient` address has at the end\n /// of the call `outTokenOwed`, leftover tokens are sent to a `to` address which by default is the `outTokenRecipient`\n function swap(\n IERC20 inToken,\n IERC20 outToken,\n address outTokenRecipient,\n uint256 outTokenOwed,\n uint256 inTokenObtained,\n bytes memory data\n ) external {\n // Address to receive the surplus amount of token at the end of the call\n address to;\n // For slippage protection, it is checked at the end of the call\n uint256 minAmountOut;\n // Type of the swap to execute: if `swapType == 4`, then it is optional to swap\n uint256 swapType;\n // We're reusing the `data` variable (it can be `path` on UniswapV3, a payload for 1inch or like encoded actions\n // for a router call)\n (to, minAmountOut, swapType, data) = abi.decode(data, (address, uint256, uint256, bytes));\n\n to = (to == address(0)) ? outTokenRecipient : to;\n\n _swap(inToken, inTokenObtained, SwapType(swapType), data);\n\n // A final slippage check is performed after the swaps\n uint256 outTokenBalance = outToken.balanceOf(address(this));\n if (outTokenBalance < minAmountOut) revert TooSmallAmountOut();\n\n // The `outTokenRecipient` may already have enough in balance, in which case there's no need to transfer\n // to this address the token and everything can be given to the `to` address\n uint256 outTokenBalanceRecipient = outToken.balanceOf(outTokenRecipient);\n if (outTokenBalanceRecipient >= outTokenOwed || to == outTokenRecipient)\n outToken.safeTransfer(to, outTokenBalance);\n else {\n // The `outTokenRecipient` should receive the delta to make sure its end balance is equal to `outTokenOwed`\n // Any leftover in this case is sent to the `to` address\n // The function reverts if it did not obtain more than `outTokenOwed - outTokenBalanceRecipient` from the swap\n outToken.safeTransfer(outTokenRecipient, outTokenOwed - outTokenBalanceRecipient);\n outToken.safeTransfer(to, outTokenBalanceRecipient + outTokenBalance - outTokenOwed);\n }\n // Reusing the `inTokenObtained` variable for the `inToken` balance\n // Sending back the remaining amount of inTokens to the `to` address: it is possible that not the full `inTokenObtained`\n // is swapped to `outToken` if we're using the `1inch` payload\n inTokenObtained = inToken.balanceOf(address(this));\n if (inTokenObtained != 0) inToken.safeTransfer(to, inTokenObtained);\n }\n\n // ============================ GOVERNANCE FUNCTION ============================\n\n /// @notice Changes allowances of this contract for different tokens\n /// @param tokens Addresses of the tokens to allow\n /// @param spenders Addresses to allow transfer\n /// @param amounts Amounts to allow\n function changeAllowance(\n IERC20[] calldata tokens,\n address[] calldata spenders,\n uint256[] calldata amounts\n ) external {\n if (!core.isGovernorOrGuardian(msg.sender)) revert NotGovernorOrGuardian();\n uint256 tokensLength = tokens.length;\n if (tokensLength != spenders.length || tokensLength != amounts.length) revert IncompatibleLengths();\n for (uint256 i; i < tokensLength; ++i) {\n _changeAllowance(tokens[i], spenders[i], amounts[i]);\n }\n }\n\n // ========================= INTERNAL UTILITY FUNCTIONS ========================\n\n /// @notice Internal version of the `_changeAllowance` function\n function _changeAllowance(IERC20 token, address spender, uint256 amount) internal {\n uint256 currentAllowance = token.allowance(address(this), spender);\n // In case `currentAllowance < type(uint256).max / 2` and we want to increase it:\n // Do nothing (to handle tokens that need reapprovals to 0 and save gas)\n if (currentAllowance < amount && currentAllowance < type(uint256).max / 2) {\n token.safeIncreaseAllowance(spender, amount - currentAllowance);\n } else if (currentAllowance > amount) {\n token.safeDecreaseAllowance(spender, currentAllowance - amount);\n }\n }\n\n /// @notice Checks the allowance for a contract and updates it to the max if it is not big enough\n /// @param token Token for which allowance should be checked\n /// @param spender Address to grant allowance to\n /// @param amount Minimum amount of tokens needed for the allowance\n function _checkAllowance(IERC20 token, address spender, uint256 amount) internal {\n uint256 currentAllowance = token.allowance(address(this), spender);\n if (currentAllowance < amount) token.safeIncreaseAllowance(spender, type(uint256).max - currentAllowance);\n }\n\n /// @notice Performs a swap using either Uniswap, 1inch. This function can also stake stETH to wstETH\n /// @param inToken Token to swap\n /// @param amount Amount of tokens to swap\n /// @param swapType Type of the swap to perform\n /// @param args Extra args for the swap: in the case of Uniswap it should be a path, for 1inch it should be\n /// a payload\n /// @dev This function does nothing if `swapType` is None and it simply passes on the `amount` it received\n /// @dev No slippage is specified in the actions given here as a final slippage check is performed\n /// after the call to this function\n function _swap(IERC20 inToken, uint256 amount, SwapType swapType, bytes memory args) internal {\n if (swapType == SwapType.UniswapV3) _swapOnUniswapV3(inToken, amount, args);\n else if (swapType == SwapType.oneInch) _swapOn1inch(inToken, args);\n else if (swapType == SwapType.AngleRouter) _angleRouterActions(inToken, args);\n else if (swapType == SwapType.Leverage) _swapLeverage(args);\n }\n\n /// @notice Performs a UniswapV3 swap\n /// @param inToken Token to swap\n /// @param amount Amount of tokens to swap\n /// @param path Path for the UniswapV3 swap: this encodes the out token that is going to be obtained\n /// @dev This function does not check the out token obtained here: if it is wrongly specified, either\n /// the `swap` function could fail or these tokens could stay on the contract\n function _swapOnUniswapV3(IERC20 inToken, uint256 amount, bytes memory path) internal returns (uint256 amountOut) {\n // We need more than `amount` of allowance to the contract\n _checkAllowance(inToken, address(uniV3Router), amount);\n amountOut = uniV3Router.exactInput(ExactInputParams(path, address(this), block.timestamp, amount, 0));\n }\n\n /// @notice Allows to swap any token to an accepted collateral via 1inch API\n /// @param inToken Token received for the 1inch swap\n /// @param payload Bytes needed for 1inch API\n function _swapOn1inch(IERC20 inToken, bytes memory payload) internal returns (uint256 amountOut) {\n _changeAllowance(inToken, oneInch, type(uint256).max);\n //solhint-disable-next-line\n (bool success, bytes memory result) = oneInch.call(payload);\n if (!success) _revertBytes(result);\n amountOut = abi.decode(result, (uint256));\n }\n\n /// @notice Performs actions with the router contract of the protocol on the corresponding chain\n /// @param inToken Token concerned by the action and for which\n function _angleRouterActions(IERC20 inToken, bytes memory args) internal {\n (ActionType[] memory actions, bytes[] memory actionData) = abi.decode(args, (ActionType[], bytes[]));\n _changeAllowance(inToken, address(angleRouter), type(uint256).max);\n PermitType[] memory permits;\n angleRouter.mixer(permits, actions, actionData);\n }\n\n /// @notice Allows to take leverage or deleverage via a specific contract\n /// @param payload Bytes needed for 1inch API\n /// @dev This function is to be implemented if the swapper concerns a token that requires some actions\n /// not supported by 1inch or UniV3\n function _swapLeverage(bytes memory payload) internal virtual returns (uint256 amountOut) {}\n\n /// @notice Internal function used for error handling\n /// @param errMsg Error message received\n function _revertBytes(bytes memory errMsg) internal pure {\n if (errMsg.length != 0) {\n //solhint-disable-next-line\n assembly {\n revert(add(32, errMsg), mload(errMsg))\n }\n }\n revert EmptyReturnMessage();\n }\n}\n" + }, + "contracts/treasury/Treasury.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\n/*\n * █ \n ***** ▓▓▓ \n * ▓▓▓▓▓▓▓ \n * ///. ▓▓▓▓▓▓▓▓▓▓▓▓▓ \n ***** //////// ▓▓▓▓▓▓▓ \n * ///////////// ▓▓▓ \n ▓▓ ////////////////// █ ▓▓ \n ▓▓ ▓▓ /////////////////////// ▓▓ ▓▓ \n ▓▓ ▓▓ //////////////////////////// ▓▓ ▓▓ \n ▓▓ ▓▓ /////////▓▓▓///////▓▓▓///////// ▓▓ ▓▓ \n ▓▓ ,////////////////////////////////////// ▓▓ ▓▓ \n ▓▓ ////////////////////////////////////////// ▓▓ \n ▓▓ //////////////////////▓▓▓▓///////////////////// \n ,//////////////////////////////////////////////////// \n .////////////////////////////////////////////////////////// \n .//////////////////////////██.,//////////////////////////█ \n .//////////////////////████..,./////////////////////██ \n ...////////////////███████.....,.////////////////███ \n ,.,////////////████████ ........,///////////████ \n .,.,//////█████████ ,.......///////████ \n ,..//████████ ........./████ \n ..,██████ .....,███ \n .██ ,.,█ \n \n \n \n ▓▓ ▓▓▓▓▓▓▓▓▓▓ ▓▓▓▓▓▓▓▓▓▓ ▓▓ ▓▓▓▓▓▓▓▓▓▓ \n ▓▓▓▓▓▓ ▓▓▓ ▓▓▓ ▓▓▓ ▓▓ ▓▓ ▓▓▓▓ \n ▓▓▓ ▓▓▓ ▓▓▓ ▓▓▓ ▓▓▓ ▓▓▓ ▓▓ ▓▓▓▓▓ \n ▓▓▓ ▓▓ ▓▓▓ ▓▓▓ ▓▓▓▓▓▓▓▓▓▓ ▓▓▓▓▓▓▓▓▓▓ ▓▓▓▓▓▓▓▓▓▓ \n*/\n\npragma solidity ^0.8.12;\n\nimport \"@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol\";\nimport \"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\";\nimport \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\n\nimport \"../interfaces/IAgToken.sol\";\nimport \"../interfaces/ICoreBorrow.sol\";\nimport \"../interfaces/IFlashAngle.sol\";\nimport \"../interfaces/ITreasury.sol\";\nimport \"../interfaces/IVaultManager.sol\";\n\n/// @title Treasury\n/// @author Angle Labs, Inc.\n/// @notice Treasury of Angle Borrowing Module doing the accounting across all VaultManagers for\n/// a given stablecoin\ncontract Treasury is ITreasury, Initializable {\n using SafeERC20 for IERC20;\n\n /// @notice Base used for parameter computation\n uint256 public constant BASE_9 = 1e9;\n\n // ================================= REFERENCES ================================\n\n /// @notice Reference to the `CoreBorrow` contract of the module which handles all AccessControl logic\n ICoreBorrow public core;\n /// @notice Flash Loan Module with a minter right on the stablecoin\n IFlashAngle public flashLoanModule;\n /// @inheritdoc ITreasury\n IAgToken public stablecoin;\n /// @notice Address responsible for handling the surplus made by the treasury\n address public surplusManager;\n /// @notice List of the accepted `VaultManager` of the protocol\n address[] public vaultManagerList;\n /// @notice Maps an address to 1 if it was initialized as a `VaultManager` contract\n mapping(address => uint256) public vaultManagerMap;\n\n // ================================= VARIABLES =================================\n\n /// @notice Amount of bad debt (unbacked stablecoin) accumulated across all `VaultManager` contracts\n /// linked to this stablecoin\n uint256 public badDebt;\n /// @notice Surplus amount accumulated by the contract waiting to be distributed to governance. Technically\n /// only a share of this `surplusBuffer` will go to governance. Once a share of the surplus buffer has been\n /// given to governance, then this surplus is reset\n uint256 public surplusBuffer;\n\n // ================================= PARAMETER =================================\n\n /// @notice Share of the `surplusBuffer` distributed to governance (in `BASE_9`)\n uint64 public surplusForGovernance;\n\n // =================================== EVENTS ==================================\n\n event BadDebtUpdated(uint256 badDebtValue);\n event CoreUpdated(address indexed _core);\n event NewTreasurySet(address indexed _treasury);\n event Recovered(address indexed token, address indexed to, uint256 amount);\n event SurplusBufferUpdated(uint256 surplusBufferValue);\n event SurplusForGovernanceUpdated(uint64 _surplusForGovernance);\n event SurplusManagerUpdated(address indexed _surplusManager);\n event VaultManagerToggled(address indexed vaultManager);\n\n // =================================== ERRORS ==================================\n\n error AlreadyVaultManager();\n error InvalidAddress();\n error InvalidTreasury();\n error NotCore();\n error NotGovernor();\n error NotVaultManager();\n error RightsNotRemoved();\n error TooBigAmount();\n error TooHighParameterValue();\n error ZeroAddress();\n\n // ================================== MODIFIER =================================\n\n /// @notice Checks whether the `msg.sender` has the governor role or not\n modifier onlyGovernor() {\n if (!core.isGovernor(msg.sender)) revert NotGovernor();\n _;\n }\n\n /// @notice Initializes the treasury contract\n /// @param _core Address of the `CoreBorrow` contract of the module\n /// @param _stablecoin Address of the stablecoin\n function initialize(ICoreBorrow _core, IAgToken _stablecoin) public virtual initializer {\n if (address(_stablecoin) == address(0) || address(_core) == address(0)) revert ZeroAddress();\n core = _core;\n stablecoin = _stablecoin;\n }\n\n /// @custom:oz-upgrades-unsafe-allow constructor\n constructor() initializer {}\n\n // =============================== VIEW FUNCTIONS ==============================\n\n /// @inheritdoc ITreasury\n function isGovernor(address admin) external view returns (bool) {\n return core.isGovernor(admin);\n }\n\n /// @inheritdoc ITreasury\n function isGovernorOrGuardian(address admin) external view returns (bool) {\n return core.isGovernorOrGuardian(admin);\n }\n\n /// @inheritdoc ITreasury\n function isVaultManager(address _vaultManager) external view returns (bool) {\n return vaultManagerMap[_vaultManager] == 1;\n }\n\n // ===================== EXTERNAL PERMISSIONLESS FUNCTIONS =====================\n\n /// @notice Fetches the surplus accrued across all the `VaultManager` contracts controlled by this\n /// `Treasury` contract as well as from the fees of the `FlashLoan` module\n /// @return Surplus buffer value at the end of the call\n /// @return Bad debt value at the end of the call\n /// @dev This function pools surplus and bad debt across all contracts and then updates the `surplusBuffer`\n /// (or the `badDebt` if more losses were made than profits)\n function fetchSurplusFromAll() external returns (uint256, uint256) {\n return _fetchSurplusFromAll();\n }\n\n /// @notice Fetches the surplus accrued in the flash loan module and updates the `surplusBuffer`\n /// @return Surplus buffer value at the end of the call\n /// @return Bad debt value at the end of the call\n /// @dev This function fails if the `flashLoanModule` has not been initialized yet\n function fetchSurplusFromFlashLoan() external returns (uint256, uint256) {\n uint256 surplusBufferValue = surplusBuffer + flashLoanModule.accrueInterestToTreasury(stablecoin);\n return _updateSurplusAndBadDebt(surplusBufferValue, badDebt);\n }\n\n /// @notice Pushes the surplus buffer to the `surplusManager` contract\n /// @return governanceAllocation Amount transferred to governance\n /// @dev It makes sure to fetch the surplus from all the contracts handled by this treasury to avoid\n /// the situation where rewards are still distributed to governance even though a `VaultManager` has made\n /// a big loss\n /// @dev Typically this function is to be called once every week by a keeper to distribute rewards to veANGLE\n /// holders\n /// @dev `stablecoin` must be an AgToken and hence `transfer` reverts if the call is not successful\n function pushSurplus() external returns (uint256 governanceAllocation) {\n address _surplusManager = surplusManager;\n if (_surplusManager == address(0)) {\n revert ZeroAddress();\n }\n (uint256 surplusBufferValue, ) = _fetchSurplusFromAll();\n surplusBuffer = 0;\n emit SurplusBufferUpdated(0);\n governanceAllocation = (surplusForGovernance * surplusBufferValue) / BASE_9;\n stablecoin.transfer(_surplusManager, governanceAllocation);\n }\n\n /// @notice Updates the bad debt of the protocol in case where the protocol has accumulated some revenue\n /// from an external source\n /// @param amount Amount to reduce the bad debt of\n /// @return badDebtValue Value of the bad debt at the end of the call\n /// @dev If the protocol has made a loss and managed to make some profits to recover for this loss (through\n /// a program like Olympus Pro), then this function needs to be called\n /// @dev `badDebt` is simply reduced here by burning stablecoins\n /// @dev It is impossible to burn more than the `badDebt` otherwise this function could be used to manipulate\n /// the `surplusBuffer` and hence the amount going to governance\n function updateBadDebt(uint256 amount) external returns (uint256 badDebtValue) {\n stablecoin.burnSelf(amount, address(this));\n badDebtValue = badDebt - amount;\n badDebt = badDebtValue;\n emit BadDebtUpdated(badDebtValue);\n }\n\n // ========================= INTERNAL UTILITY FUNCTIONS ========================\n\n /// @notice Internal version of the `fetchSurplusFromAll` function\n function _fetchSurplusFromAll() internal returns (uint256 surplusBufferValue, uint256 badDebtValue) {\n (surplusBufferValue, badDebtValue) = _fetchSurplusFromList(vaultManagerList);\n // It will fail anyway if the `flashLoanModule` is the zero address\n if (address(flashLoanModule) != address(0))\n surplusBufferValue += flashLoanModule.accrueInterestToTreasury(stablecoin);\n (surplusBufferValue, badDebtValue) = _updateSurplusAndBadDebt(surplusBufferValue, badDebtValue);\n }\n\n /// @notice Fetches the surplus from a list of `VaultManager` addresses without modifying the\n /// `surplusBuffer` and `badDebtValue`\n /// @return surplusBufferValue Value the `surplusBuffer` should have after the call if it was updated\n /// @return badDebtValue Value the `badDebt` should have after the call if it was updated\n /// @dev This internal function is never to be called alone, and should always be called in conjunction\n /// with the `_updateSurplusAndBadDebt` function\n function _fetchSurplusFromList(\n address[] memory vaultManagers\n ) internal returns (uint256 surplusBufferValue, uint256 badDebtValue) {\n badDebtValue = badDebt;\n surplusBufferValue = surplusBuffer;\n uint256 newSurplus;\n uint256 newBadDebt;\n uint256 vaultManagersLength = vaultManagers.length;\n for (uint256 i; i < vaultManagersLength; ++i) {\n (newSurplus, newBadDebt) = IVaultManager(vaultManagers[i]).accrueInterestToTreasury();\n surplusBufferValue += newSurplus;\n badDebtValue += newBadDebt;\n }\n }\n\n /// @notice Updates the `surplusBuffer` and the `badDebt` from updated values after calling the flash loan module\n /// and/or a list of `VaultManager` contracts\n /// @param surplusBufferValue Value of the surplus buffer after the calls to the different modules\n /// @param badDebtValue Value of the bad debt after the calls to the different modules\n /// @return Value of the `surplusBuffer` corrected from the `badDebt`\n /// @return Value of the `badDebt` corrected from the `surplusBuffer` and from the surplus the treasury had accumulated\n /// previously\n /// @dev When calling this function, it is possible that there is a positive `surplusBufferValue` and `badDebtValue`,\n /// this function tries to reconcile both values and makes sure that we either have surplus or bad debt but not both\n /// at the same time\n function _updateSurplusAndBadDebt(\n uint256 surplusBufferValue,\n uint256 badDebtValue\n ) internal returns (uint256, uint256) {\n if (badDebtValue != 0) {\n // If we have bad debt we need to burn stablecoins that accrued to the protocol\n // We still need to make sure that we're not burning too much or as much as we can if the debt is big\n uint256 balance = stablecoin.balanceOf(address(this));\n // We are going to burn `min(balance, badDebtValue)`\n uint256 toBurn = balance <= badDebtValue ? balance : badDebtValue;\n stablecoin.burnSelf(toBurn, address(this));\n // If we burned more than `surplusBuffer`, we set surplus to 0. It means we had to tap into Treasury reserve\n surplusBufferValue = toBurn >= surplusBufferValue ? 0 : surplusBufferValue - toBurn;\n badDebtValue -= toBurn;\n // Note here that the stablecoin balance is necessarily greater than the surplus buffer, and so if\n // `surplusBuffer >= toBurn`, then `badDebtValue = toBurn`\n }\n surplusBuffer = surplusBufferValue;\n badDebt = badDebtValue;\n emit SurplusBufferUpdated(surplusBufferValue);\n emit BadDebtUpdated(badDebtValue);\n return (surplusBufferValue, badDebtValue);\n }\n\n /// @notice Adds a new `VaultManager`\n /// @param vaultManager `VaultManager` contract to add\n /// @dev This contract should have already been initialized with a correct treasury address\n /// @dev It's this function that gives the minter right to the `VaultManager`\n function _addVaultManager(address vaultManager) internal virtual {\n if (vaultManagerMap[vaultManager] == 1) revert AlreadyVaultManager();\n if (address(IVaultManager(vaultManager).treasury()) != address(this)) revert InvalidTreasury();\n vaultManagerMap[vaultManager] = 1;\n vaultManagerList.push(vaultManager);\n emit VaultManagerToggled(vaultManager);\n stablecoin.addMinter(vaultManager);\n }\n\n // ============================= GOVERNOR FUNCTIONS ============================\n\n /// @notice Adds a new minter for the stablecoin\n /// @param minter Minter address to add\n function addMinter(address minter) external virtual onlyGovernor {\n if (minter == address(0)) revert ZeroAddress();\n stablecoin.addMinter(minter);\n }\n\n /// @notice External wrapper for `_addVaultManager`\n function addVaultManager(address vaultManager) external virtual onlyGovernor {\n _addVaultManager(vaultManager);\n }\n\n /// @notice Removes a minter from the stablecoin contract\n /// @param minter Minter address to remove\n function removeMinter(address minter) external virtual onlyGovernor {\n // To remove the minter role to a `VaultManager` you have to go through the `removeVaultManager` function\n if (vaultManagerMap[minter] == 1) revert InvalidAddress();\n stablecoin.removeMinter(minter);\n }\n\n /// @notice Removes a `VaultManager`\n /// @param vaultManager `VaultManager` contract to remove\n /// @dev A removed `VaultManager` loses its minter right on the stablecoin\n function removeVaultManager(address vaultManager) external onlyGovernor {\n if (vaultManagerMap[vaultManager] != 1) revert NotVaultManager();\n delete vaultManagerMap[vaultManager];\n // deletion from `vaultManagerList` loop\n uint256 vaultManagerListLength = vaultManagerList.length;\n for (uint256 i; i < vaultManagerListLength - 1; ++i) {\n if (vaultManagerList[i] == vaultManager) {\n // replace the `VaultManager` to remove with the last of the list\n vaultManagerList[i] = vaultManagerList[vaultManagerListLength - 1];\n break;\n }\n }\n // remove last element in array\n vaultManagerList.pop();\n emit VaultManagerToggled(vaultManager);\n stablecoin.removeMinter(vaultManager);\n }\n\n /// @notice Allows to recover any ERC20 token, including the stablecoin handled by this contract, and to send it\n /// to a contract\n /// @param tokenAddress Address of the token to recover\n /// @param to Address of the contract to send collateral to\n /// @param amountToRecover Amount of collateral to transfer\n /// @dev It is impossible to recover the stablecoin of the protocol if there is some bad debt for it\n /// @dev In this case, the function makes sure to fetch the surplus/bad debt from all the `VaultManager` contracts\n /// and from the flash loan module\n /// @dev If the token to recover is the stablecoin, tokens recovered are fetched\n /// from the surplus and not from the `surplusBuffer`\n function recoverERC20(address tokenAddress, address to, uint256 amountToRecover) external onlyGovernor {\n // Cannot recover stablecoin if badDebt or tap into the surplus buffer\n if (tokenAddress == address(stablecoin)) {\n _fetchSurplusFromAll();\n // If balance is non zero then this means, after the call to `fetchSurplusFromAll` that\n // bad debt is necessarily null\n uint256 balance = stablecoin.balanceOf(address(this));\n if (amountToRecover + surplusBuffer > balance) revert TooBigAmount();\n stablecoin.transfer(to, amountToRecover);\n } else {\n IERC20(tokenAddress).safeTransfer(to, amountToRecover);\n }\n emit Recovered(tokenAddress, to, amountToRecover);\n }\n\n /// @notice Changes the treasury contract and communicates this change to all `VaultManager` contract\n /// @param _treasury New treasury address for this stablecoin\n /// @dev This function is basically a way to remove rights to this contract and grant them to a new one\n /// @dev It could be used to set a new core contract\n function setTreasury(address _treasury) external virtual onlyGovernor {\n if (ITreasury(_treasury).stablecoin() != stablecoin) revert InvalidTreasury();\n // Flash loan role should be removed before calling this function\n if (core.isFlashLoanerTreasury(address(this))) revert RightsNotRemoved();\n emit NewTreasurySet(_treasury);\n uint256 vaultManagerListLength = vaultManagerList.length;\n for (uint256 i; i < vaultManagerListLength; ++i) {\n IVaultManager(vaultManagerList[i]).setTreasury(_treasury);\n }\n // A `TreasuryUpdated` event is triggered in the stablecoin\n stablecoin.setTreasury(_treasury);\n }\n\n /// @notice Sets the `surplusForGovernance` parameter\n /// @param _surplusForGovernance New value of the parameter\n /// @dev To pause surplus distribution, governance needs to set a zero value for `surplusForGovernance`\n /// which means\n function setSurplusForGovernance(uint64 _surplusForGovernance) external onlyGovernor {\n if (_surplusForGovernance > BASE_9) revert TooHighParameterValue();\n surplusForGovernance = _surplusForGovernance;\n emit SurplusForGovernanceUpdated(_surplusForGovernance);\n }\n\n /// @notice Sets the `surplusManager` contract responsible for handling the surplus of the\n /// protocol\n /// @param _surplusManager New address responsible for handling the surplus\n function setSurplusManager(address _surplusManager) external onlyGovernor {\n if (_surplusManager == address(0)) revert ZeroAddress();\n surplusManager = _surplusManager;\n emit SurplusManagerUpdated(_surplusManager);\n }\n\n /// @notice Sets a new `core` contract\n /// @dev This function should typically be called on all treasury contracts after the `setCore`\n /// function has been called on the `CoreBorrow` contract\n /// @dev One sanity check that can be performed here is to verify whether at least the governor\n /// calling the contract is still a governor in the new core\n function setCore(ICoreBorrow _core) external onlyGovernor {\n if (!_core.isGovernor(msg.sender)) revert NotGovernor();\n core = ICoreBorrow(_core);\n emit CoreUpdated(address(_core));\n }\n\n /// @inheritdoc ITreasury\n function setFlashLoanModule(address _flashLoanModule) external {\n if (msg.sender != address(core)) revert NotCore();\n address oldFlashLoanModule = address(flashLoanModule);\n flashLoanModule = IFlashAngle(_flashLoanModule);\n if (oldFlashLoanModule != address(0)) {\n stablecoin.removeMinter(oldFlashLoanModule);\n }\n // We may want to cancel the module\n if (_flashLoanModule != address(0)) {\n stablecoin.addMinter(_flashLoanModule);\n }\n }\n}\n" + }, + "contracts/ui-helpers/AngleBorrowHelpers.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\n/*\n * █ \n ***** ▓▓▓ \n * ▓▓▓▓▓▓▓ \n * ///. ▓▓▓▓▓▓▓▓▓▓▓▓▓ \n ***** //////// ▓▓▓▓▓▓▓ \n * ///////////// ▓▓▓ \n ▓▓ ////////////////// █ ▓▓ \n ▓▓ ▓▓ /////////////////////// ▓▓ ▓▓ \n ▓▓ ▓▓ //////////////////////////// ▓▓ ▓▓ \n ▓▓ ▓▓ /////////▓▓▓///////▓▓▓///////// ▓▓ ▓▓ \n ▓▓ ,////////////////////////////////////// ▓▓ ▓▓ \n ▓▓ ////////////////////////////////////////// ▓▓ \n ▓▓ //////////////////////▓▓▓▓///////////////////// \n ,//////////////////////////////////////////////////// \n .////////////////////////////////////////////////////////// \n .//////////////////////////██.,//////////////////////////█ \n .//////////////////////████..,./////////////////////██ \n ...////////////////███████.....,.////////////////███ \n ,.,////////////████████ ........,///////////████ \n .,.,//////█████████ ,.......///////████ \n ,..//████████ ........./████ \n ..,██████ .....,███ \n .██ ,.,█ \n \n \n \n ▓▓ ▓▓▓▓▓▓▓▓▓▓ ▓▓▓▓▓▓▓▓▓▓ ▓▓ ▓▓▓▓▓▓▓▓▓▓ \n ▓▓▓▓▓▓ ▓▓▓ ▓▓▓ ▓▓▓ ▓▓ ▓▓ ▓▓▓▓ \n ▓▓▓ ▓▓▓ ▓▓▓ ▓▓▓ ▓▓▓ ▓▓▓ ▓▓ ▓▓▓▓▓ \n ▓▓▓ ▓▓ ▓▓▓ ▓▓▓ ▓▓▓▓▓▓▓▓▓▓ ▓▓▓▓▓▓▓▓▓▓ ▓▓▓▓▓▓▓▓▓▓ \n*/\n\nimport \"@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol\";\nimport \"../interfaces/IVaultManager.sol\";\n\npragma solidity ^0.8.12;\n\n/// @title AngleBorrowHelpers\n/// @author Angle Labs, Inc.\n/// @notice Contract with view functions designed to facilitate integrations on the Borrow module of the Angle Protocol\n/// @dev This contract only contains view functions to be queried off-chain. It was thus not optimized for gas consumption\ncontract AngleBorrowHelpers is Initializable {\n /// @notice Returns all the vaults owned or controlled (under the form of approval) by an address\n /// @param vaultManager VaultManager address to query vaultIDs on\n /// @param spender Address for which vault ownerships should be checked\n /// @return List of `vaultID` controlled by this address\n /// @return Count of vaults owned by the address\n /// @dev This function is never to be called on-chain since it iterates over all vaultIDs. It is here\n /// to reduce dependency on an external graph to link an ID to its owner\n function getControlledVaults(\n IVaultManager vaultManager,\n address spender\n ) external view returns (uint256[] memory, uint256) {\n uint256 arraySize = vaultManager.vaultIDCount();\n uint256[] memory vaultsControlled = new uint256[](arraySize);\n uint256 count;\n for (uint256 i = 1; i <= arraySize; ++i) {\n try vaultManager.isApprovedOrOwner(spender, i) returns (bool _isApprovedOrOwner) {\n if (_isApprovedOrOwner) {\n vaultsControlled[count] = i;\n count += 1;\n }\n } catch {\n continue;\n } // This happens if nobody owns the vaultID=i (if there has been a burn)\n }\n return (vaultsControlled, count);\n }\n\n /// @custom:oz-upgrades-unsafe-allow constructor\n constructor() initializer {}\n}\n" + }, + "contracts/ui-helpers/AngleHelpers.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\nimport \"../interfaces/IAngleRouter.sol\";\nimport \"../interfaces/coreModule/IAgTokenMainnet.sol\";\nimport \"../interfaces/coreModule/ICore.sol\";\nimport \"../interfaces/coreModule/IOracleCore.sol\";\nimport \"../interfaces/coreModule/IPerpetualManager.sol\";\nimport \"../interfaces/coreModule/IPoolManager.sol\";\nimport \"../interfaces/coreModule/IStableMaster.sol\";\nimport \"./AngleBorrowHelpers.sol\";\n\npragma solidity ^0.8.12;\n\nstruct Parameters {\n SLPData slpData;\n MintBurnData feeData;\n PerpetualManagerFeeData perpFeeData;\n PerpetualManagerParamData perpParam;\n}\n\nstruct PerpetualManagerFeeData {\n uint64[] xHAFeesDeposit;\n uint64[] yHAFeesDeposit;\n uint64[] xHAFeesWithdraw;\n uint64[] yHAFeesWithdraw;\n uint64 haBonusMalusDeposit;\n uint64 haBonusMalusWithdraw;\n}\n\nstruct PerpetualManagerParamData {\n uint64 maintenanceMargin;\n uint64 maxLeverage;\n uint64 targetHAHedge;\n uint64 limitHAHedge;\n uint64 lockTime;\n}\n\nstruct CollateralAddresses {\n address stableMaster;\n address poolManager;\n address perpetualManager;\n address sanToken;\n address oracle;\n address gauge;\n address feeManager;\n address[] strategies;\n}\n\n/// @title AngleHelpers\n/// @author Angle Labs, Inc.\n/// @notice Contract with view functions designed to facilitate integrations on the Core and Borrow module of the Angle Protocol\n/// @dev This contract only contains view functions to be queried off-chain. It was thus not optimized for gas consumption\ncontract AngleHelpers is AngleBorrowHelpers {\n // =========================== HELPER VIEW FUNCTIONS ===========================\n\n /// @notice Gives the amount of `agToken` you'd be getting if you were executing in the same block a mint transaction\n /// with `amount` of `collateral` in the Core module of the Angle protocol as well as the value of the fees\n /// (in `BASE_PARAMS`) that would be applied during the mint\n /// @return Amount of `agToken` that would be obtained with a mint transaction in the same block\n /// @return Percentage of fees that would be taken during a mint transaction in the same block\n /// @dev This function reverts if the mint transaction was to revert in the same conditions (without taking into account\n /// potential approval problems to the `StableMaster` contract)\n function previewMintAndFees(\n uint256 amount,\n address agToken,\n address collateral\n ) external view returns (uint256, uint256) {\n return _previewMintAndFees(amount, agToken, collateral);\n }\n\n /// @notice Gives the amount of `collateral` you'd be getting if you were executing in the same block a burn transaction\n /// with `amount` of `agToken` in the Core module of the Angle protocol as well as the value of the fees\n /// (in `BASE_PARAMS`) that would be applied during the burn\n /// @return Amount of `collateral` that would be obtained with a burn transaction in the same block\n /// @return Percentage of fees that would be taken during a burn transaction in the same block\n /// @dev This function reverts if the burn transaction was to revert in the same conditions (without taking into account\n /// potential approval problems to the `StableMaster` contract or agToken balance prior to the call)\n function previewBurnAndFees(\n uint256 amount,\n address agToken,\n address collateral\n ) external view returns (uint256, uint256) {\n return _previewBurnAndFees(amount, agToken, collateral);\n }\n\n /// @notice Returns all the addresses associated to the (`agToken`,`collateral`) pair given\n /// @return addresses A struct with all the addresses associated in the Core module\n function getCollateralAddresses(\n address agToken,\n address collateral\n ) external view returns (CollateralAddresses memory addresses) {\n address stableMaster = IAgTokenMainnet(agToken).stableMaster();\n (address poolManager, address perpetualManager, address sanToken, address gauge) = ROUTER.mapPoolManagers(\n stableMaster,\n collateral\n );\n (, , , IOracleCore oracle, , , , , ) = IStableMaster(stableMaster).collateralMap(poolManager);\n addresses.stableMaster = stableMaster;\n addresses.poolManager = poolManager;\n addresses.perpetualManager = perpetualManager;\n addresses.sanToken = sanToken;\n addresses.gauge = gauge;\n addresses.oracle = address(oracle);\n addresses.feeManager = IPoolManager(poolManager).feeManager();\n\n uint256 length;\n while (true) {\n try IPoolManager(poolManager).strategyList(length) returns (address) {\n length += 1;\n } catch {\n break;\n }\n }\n address[] memory strategies = new address[](length);\n for (uint256 i; i < length; ++i) {\n strategies[i] = IPoolManager(poolManager).strategyList(i);\n }\n addresses.strategies = strategies;\n }\n\n /// @notice Gets the addresses of all the `StableMaster` contracts and their associated `AgToken` addresses\n /// @return List of the `StableMaster` addresses of the Angle protocol\n /// @return List of the `AgToken` addresses of the protocol\n /// @dev The place of an agToken address in the list is the same as the corresponding `StableMaster` address\n function getStablecoinAddresses() external view returns (address[] memory, address[] memory) {\n address[] memory stableMasterAddresses = CORE.stablecoinList();\n address[] memory agTokenAddresses = new address[](stableMasterAddresses.length);\n for (uint256 i; i < stableMasterAddresses.length; ++i) {\n agTokenAddresses[i] = IStableMaster(stableMasterAddresses[i]).agToken();\n }\n return (stableMasterAddresses, agTokenAddresses);\n }\n\n /// @notice Returns most of the governance parameters associated to the (`agToken`,`collateral`) pair given\n /// @return params Struct with most of the parameters in the `StableMaster` and `PerpetualManager` contracts\n /// @dev Check out the struct `Parameters` for the meaning of the return values\n function getCollateralParameters(\n address agToken,\n address collateral\n ) external view returns (Parameters memory params) {\n (address stableMaster, address poolManager) = _getStableMasterAndPoolManager(agToken, collateral);\n (\n ,\n ,\n IPerpetualManager perpetualManager,\n ,\n ,\n ,\n ,\n SLPData memory slpData,\n MintBurnData memory feeData\n ) = IStableMaster(stableMaster).collateralMap(poolManager);\n\n params.slpData = slpData;\n params.feeData = feeData;\n params.perpParam.maintenanceMargin = perpetualManager.maintenanceMargin();\n params.perpParam.maxLeverage = perpetualManager.maxLeverage();\n params.perpParam.targetHAHedge = perpetualManager.targetHAHedge();\n params.perpParam.limitHAHedge = perpetualManager.limitHAHedge();\n params.perpParam.lockTime = perpetualManager.lockTime();\n\n params.perpFeeData.haBonusMalusDeposit = perpetualManager.haBonusMalusDeposit();\n params.perpFeeData.haBonusMalusWithdraw = perpetualManager.haBonusMalusWithdraw();\n\n uint256 length;\n while (true) {\n try perpetualManager.xHAFeesDeposit(length) returns (uint64) {\n length += 1;\n } catch {\n break;\n }\n }\n uint64[] memory data = new uint64[](length);\n uint64[] memory data2 = new uint64[](length);\n for (uint256 i; i < length; ++i) {\n data[i] = perpetualManager.xHAFeesDeposit(i);\n data2[i] = perpetualManager.yHAFeesDeposit(i);\n }\n params.perpFeeData.xHAFeesDeposit = data;\n params.perpFeeData.yHAFeesDeposit = data2;\n\n length = 0;\n while (true) {\n try perpetualManager.xHAFeesWithdraw(length) returns (uint64) {\n length += 1;\n } catch {\n break;\n }\n }\n data = new uint64[](length);\n data2 = new uint64[](length);\n for (uint256 i; i < length; ++i) {\n data[i] = perpetualManager.xHAFeesWithdraw(i);\n data2[i] = perpetualManager.yHAFeesWithdraw(i);\n }\n params.perpFeeData.xHAFeesWithdraw = data;\n params.perpFeeData.yHAFeesWithdraw = data2;\n }\n\n /// @notice Returns the address of the poolManager associated to an (`agToken`, `collateral`) pair\n /// in the Core module of the protocol\n function getPoolManager(address agToken, address collateral) public view returns (address poolManager) {\n (, poolManager) = _getStableMasterAndPoolManager(agToken, collateral);\n }\n\n // ============================= REPLICA FUNCTIONS =============================\n // These replicate what is done in the other contracts of the protocol\n\n function _previewBurnAndFees(\n uint256 amount,\n address agToken,\n address collateral\n ) internal view returns (uint256 amountForUserInCollat, uint256 feePercent) {\n (address stableMaster, address poolManager) = _getStableMasterAndPoolManager(agToken, collateral);\n (\n address token,\n ,\n IPerpetualManager perpetualManager,\n IOracleCore oracle,\n uint256 stocksUsers,\n ,\n uint256 collatBase,\n ,\n MintBurnData memory feeData\n ) = IStableMaster(stableMaster).collateralMap(poolManager);\n if (token == address(0) || IStableMaster(stableMaster).paused(keccak256(abi.encodePacked(STABLE, poolManager))))\n revert NotInitialized();\n if (amount > stocksUsers) revert InvalidAmount();\n\n if (feeData.xFeeBurn.length == 1) {\n feePercent = feeData.yFeeBurn[0];\n } else {\n bytes memory data = abi.encode(address(perpetualManager), feeData.targetHAHedge);\n uint64 hedgeRatio = _computeHedgeRatio(stocksUsers - amount, data);\n feePercent = _piecewiseLinear(hedgeRatio, feeData.xFeeBurn, feeData.yFeeBurn);\n }\n feePercent = (feePercent * feeData.bonusMalusBurn) / BASE_PARAMS;\n\n amountForUserInCollat = (amount * (BASE_PARAMS - feePercent) * collatBase) / (oracle.readUpper() * BASE_PARAMS);\n }\n\n function _previewMintAndFees(\n uint256 amount,\n address agToken,\n address collateral\n ) internal view returns (uint256 amountForUserInStable, uint256 feePercent) {\n (address stableMaster, address poolManager) = _getStableMasterAndPoolManager(agToken, collateral);\n (\n address token,\n ,\n IPerpetualManager perpetualManager,\n IOracleCore oracle,\n uint256 stocksUsers,\n ,\n ,\n ,\n MintBurnData memory feeData\n ) = IStableMaster(stableMaster).collateralMap(poolManager);\n if (token == address(0) || IStableMaster(stableMaster).paused(keccak256(abi.encodePacked(STABLE, poolManager))))\n revert NotInitialized();\n\n amountForUserInStable = oracle.readQuoteLower(amount);\n\n if (feeData.xFeeMint.length == 1) feePercent = feeData.yFeeMint[0];\n else {\n bytes memory data = abi.encode(address(perpetualManager), feeData.targetHAHedge);\n uint64 hedgeRatio = _computeHedgeRatio(amountForUserInStable + stocksUsers, data);\n feePercent = _piecewiseLinear(hedgeRatio, feeData.xFeeMint, feeData.yFeeMint);\n }\n feePercent = (feePercent * feeData.bonusMalusMint) / BASE_PARAMS;\n\n amountForUserInStable = (amountForUserInStable * (BASE_PARAMS - feePercent)) / BASE_PARAMS;\n if (stocksUsers + amountForUserInStable > feeData.capOnStableMinted) revert InvalidAmount();\n }\n\n // ============================= UTILITY FUNCTIONS =============================\n // These utility functions are taken from other contracts of the protocol\n\n function _computeHedgeRatio(uint256 newStocksUsers, bytes memory data) internal view returns (uint64 ratio) {\n (address perpetualManager, uint64 targetHAHedge) = abi.decode(data, (address, uint64));\n uint256 totalHedgeAmount = IPerpetualManager(perpetualManager).totalHedgeAmount();\n newStocksUsers = (targetHAHedge * newStocksUsers) / BASE_PARAMS;\n if (newStocksUsers > totalHedgeAmount) ratio = uint64((totalHedgeAmount * BASE_PARAMS) / newStocksUsers);\n else ratio = uint64(BASE_PARAMS);\n }\n\n function _piecewiseLinear(uint64 x, uint64[] memory xArray, uint64[] memory yArray) internal pure returns (uint64) {\n if (x >= xArray[xArray.length - 1]) {\n return yArray[xArray.length - 1];\n } else if (x <= xArray[0]) {\n return yArray[0];\n } else {\n uint256 lower;\n uint256 upper = xArray.length - 1;\n uint256 mid;\n while (upper - lower > 1) {\n mid = lower + (upper - lower) / 2;\n if (xArray[mid] <= x) {\n lower = mid;\n } else {\n upper = mid;\n }\n }\n if (yArray[upper] > yArray[lower]) {\n return\n yArray[lower] +\n ((yArray[upper] - yArray[lower]) * (x - xArray[lower])) /\n (xArray[upper] - xArray[lower]);\n } else {\n return\n yArray[lower] -\n ((yArray[lower] - yArray[upper]) * (x - xArray[lower])) /\n (xArray[upper] - xArray[lower]);\n }\n }\n }\n\n function _getStableMasterAndPoolManager(\n address agToken,\n address collateral\n ) internal view returns (address stableMaster, address poolManager) {\n stableMaster = IAgTokenMainnet(agToken).stableMaster();\n (poolManager, , , ) = ROUTER.mapPoolManagers(stableMaster, collateral);\n }\n\n // ========================= CONSTANTS AND INITIALIZERS ========================\n\n IAngleRouter public constant ROUTER = IAngleRouter(0xBB755240596530be0c1DE5DFD77ec6398471561d);\n ICore public constant CORE = ICore(0x61ed74de9Ca5796cF2F8fD60D54160D47E30B7c3);\n\n bytes32 public constant STABLE = keccak256(\"STABLE\");\n uint256 public constant BASE_PARAMS = 10 ** 9;\n\n error NotInitialized();\n error InvalidAmount();\n}\n" + }, + "contracts/utils/Constants.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\nerror InsufficientAssets();\n\n/// @title Constants\n/// @author Angle Labs, Inc.\n/// @notice Constants and errors for Angle Protocol contracts\ncontract Constants {\n uint256 internal constant _BASE_9 = 1e9;\n uint256 internal constant _BASE_18 = 1e18;\n uint256 internal constant _BASE_27 = 1e27;\n uint256 internal constant _BASE_36 = 1e36;\n}\n" + }, + "contracts/vaultManager/VaultManagerERC721.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\nimport \"./VaultManagerStorage.sol\";\n\n/// @title VaultManagerERC721\n/// @author Angle Labs, Inc.\n/// @dev Base ERC721 Implementation of VaultManager\nabstract contract VaultManagerERC721 is IERC721MetadataUpgradeable, VaultManagerStorage {\n using SafeERC20 for IERC20;\n using Address for address;\n\n /// @inheritdoc IERC721MetadataUpgradeable\n string public name;\n /// @inheritdoc IERC721MetadataUpgradeable\n string public symbol;\n\n // ================================= MODIFIERS =================================\n\n /// @notice Checks if the person interacting with the vault with `vaultID` is approved\n /// @param caller Address of the person seeking to interact with the vault\n /// @param vaultID ID of the concerned vault\n modifier onlyApprovedOrOwner(address caller, uint256 vaultID) {\n if (!_isApprovedOrOwner(caller, vaultID)) revert NotApproved();\n _;\n }\n\n // ================================ ERC721 LOGIC ===============================\n\n /// @notice Checks whether a given address is approved for a vault or owns this vault\n /// @param spender Address for which vault ownership should be checked\n /// @param vaultID ID of the vault to check\n /// @return Whether the `spender` address owns or is approved for `vaultID`\n function isApprovedOrOwner(address spender, uint256 vaultID) external view returns (bool) {\n return _isApprovedOrOwner(spender, vaultID);\n }\n\n /// @inheritdoc IERC721MetadataUpgradeable\n function tokenURI(uint256 vaultID) external view returns (string memory) {\n if (!_exists(vaultID)) revert NonexistentVault();\n // There is no vault with `vaultID` equal to 0, so the following variable is\n // always greater than zero\n uint256 temp = vaultID;\n uint256 digits;\n while (temp != 0) {\n ++digits;\n temp /= 10;\n }\n bytes memory buffer = new bytes(digits);\n while (vaultID != 0) {\n digits -= 1;\n buffer[digits] = bytes1(uint8(48 + uint256(vaultID % 10)));\n vaultID /= 10;\n }\n return bytes(_baseURI).length != 0 ? string(abi.encodePacked(_baseURI, string(buffer))) : \"\";\n }\n\n /// @inheritdoc IERC721Upgradeable\n function balanceOf(address owner) external view returns (uint256) {\n if (owner == address(0)) revert ZeroAddress();\n return _balances[owner];\n }\n\n /// @inheritdoc IERC721Upgradeable\n function ownerOf(uint256 vaultID) external view returns (address) {\n return _ownerOf(vaultID);\n }\n\n /// @inheritdoc IERC721Upgradeable\n function approve(address to, uint256 vaultID) external {\n address owner = _ownerOf(vaultID);\n if (to == owner) revert ApprovalToOwner();\n if (msg.sender != owner && !isApprovedForAll(owner, msg.sender)) revert NotApproved();\n\n _approve(to, vaultID);\n }\n\n /// @inheritdoc IERC721Upgradeable\n function getApproved(uint256 vaultID) external view returns (address) {\n if (!_exists(vaultID)) revert NonexistentVault();\n return _getApproved(vaultID);\n }\n\n /// @inheritdoc IERC721Upgradeable\n function setApprovalForAll(address operator, bool approved) external {\n _setApprovalForAll(msg.sender, operator, approved);\n }\n\n /// @inheritdoc IERC721Upgradeable\n function isApprovedForAll(address owner, address operator) public view returns (bool) {\n return _operatorApprovals[owner][operator] == 1;\n }\n\n /// @inheritdoc IERC721Upgradeable\n function transferFrom(address from, address to, uint256 vaultID) external onlyApprovedOrOwner(msg.sender, vaultID) {\n _transfer(from, to, vaultID);\n }\n\n /// @inheritdoc IERC721Upgradeable\n function safeTransferFrom(address from, address to, uint256 vaultID) external {\n safeTransferFrom(from, to, vaultID, \"\");\n }\n\n /// @inheritdoc IERC721Upgradeable\n function safeTransferFrom(\n address from,\n address to,\n uint256 vaultID,\n bytes memory _data\n ) public onlyApprovedOrOwner(msg.sender, vaultID) {\n _safeTransfer(from, to, vaultID, _data);\n }\n\n // ================================ ERC165 LOGIC ===============================\n\n /// @inheritdoc IERC165Upgradeable\n function supportsInterface(bytes4 interfaceId) external pure returns (bool) {\n return\n interfaceId == type(IERC721MetadataUpgradeable).interfaceId ||\n interfaceId == type(IERC721Upgradeable).interfaceId ||\n interfaceId == type(IVaultManager).interfaceId ||\n interfaceId == type(IERC165Upgradeable).interfaceId;\n }\n\n // ================== INTERNAL FUNCTIONS FOR THE ERC721 LOGIC ==================\n\n /// @notice Internal version of the `ownerOf` function\n function _ownerOf(uint256 vaultID) internal view returns (address owner) {\n owner = _owners[vaultID];\n if (owner == address(0)) revert NonexistentVault();\n }\n\n /// @notice Internal version of the `getApproved` function\n function _getApproved(uint256 vaultID) internal view returns (address) {\n return _vaultApprovals[vaultID];\n }\n\n /// @notice Internal version of the `safeTransferFrom` function (with the data parameter)\n function _safeTransfer(address from, address to, uint256 vaultID, bytes memory _data) internal {\n _transfer(from, to, vaultID);\n if (!_checkOnERC721Received(from, to, vaultID, _data)) revert NonERC721Receiver();\n }\n\n /// @notice Checks whether a vault exists\n /// @param vaultID ID of the vault to check\n /// @return Whether `vaultID` has been created\n function _exists(uint256 vaultID) internal view returns (bool) {\n return _owners[vaultID] != address(0);\n }\n\n /// @notice Internal version of the `isApprovedOrOwner` function\n function _isApprovedOrOwner(address spender, uint256 vaultID) internal view returns (bool) {\n // The following checks if the vault exists\n address owner = _ownerOf(vaultID);\n return (spender == owner || _getApproved(vaultID) == spender || _operatorApprovals[owner][spender] == 1);\n }\n\n /// @notice Internal version of the `createVault` function\n /// Mints `vaultID` and transfers it to `to`\n /// @dev This method is equivalent to the `_safeMint` method used in OpenZeppelin ERC721 contract\n /// @dev Emits a {Transfer} event\n function _mint(address to) internal returns (uint256 vaultID) {\n if (to == address(0)) revert ZeroAddress();\n\n unchecked {\n vaultIDCount += 1;\n }\n\n vaultID = vaultIDCount;\n _beforeTokenTransfer(address(0), to, vaultID);\n\n unchecked {\n _balances[to] += 1;\n }\n\n _owners[vaultID] = to;\n emit Transfer(address(0), to, vaultID);\n if (!_checkOnERC721Received(address(0), to, vaultID, \"\")) revert NonERC721Receiver();\n }\n\n /// @notice Destroys `vaultID`\n /// @dev `vaultID` must exist\n /// @dev Emits a {Transfer} event\n function _burn(uint256 vaultID) internal {\n address owner = _ownerOf(vaultID);\n\n _beforeTokenTransfer(owner, address(0), vaultID);\n // Clear approvals\n _approve(address(0), vaultID);\n // The following line cannot underflow as the owner's balance is necessarily\n // greater than 1\n unchecked {\n _balances[owner] -= 1;\n }\n delete _owners[vaultID];\n delete vaultData[vaultID];\n\n emit Transfer(owner, address(0), vaultID);\n }\n\n /// @notice Transfers `vaultID` from `from` to `to` as opposed to {transferFrom},\n /// this imposes no restrictions on msg.sender\n /// @dev `to` cannot be the zero address and `perpetualID` must be owned by `from`\n /// @dev Emits a {Transfer} event\n function _transfer(address from, address to, uint256 vaultID) internal {\n if (_ownerOf(vaultID) != from) revert NotApproved();\n if (to == address(0)) revert ZeroAddress();\n\n _beforeTokenTransfer(from, to, vaultID);\n\n // Clear approvals from the previous owner\n _approve(address(0), vaultID);\n unchecked {\n _balances[from] -= 1;\n _balances[to] += 1;\n }\n _owners[vaultID] = to;\n\n emit Transfer(from, to, vaultID);\n }\n\n /// @notice Approves `to` to operate on `vaultID`\n function _approve(address to, uint256 vaultID) internal {\n _vaultApprovals[vaultID] = to;\n emit Approval(_ownerOf(vaultID), to, vaultID);\n }\n\n /// @notice Internal version of the `setApprovalForAll` function\n /// @dev It contains an `approver` field to be used in case someone signs a permit for a particular\n /// address, and this signature is given to the contract by another address (like a router)\n function _setApprovalForAll(address approver, address operator, bool approved) internal {\n if (operator == approver) revert ApprovalToCaller();\n uint256 approval = approved ? 1 : 0;\n _operatorApprovals[approver][operator] = approval;\n emit ApprovalForAll(approver, operator, approved);\n }\n\n /// @notice Internal function to invoke {IERC721Receiver-onERC721Received} on a target address\n /// The call is not executed if the target address is not a contract\n /// @param from Address representing the previous owner of the given token ID\n /// @param to Target address that will receive the tokens\n /// @param vaultID ID of the token to be transferred\n /// @param _data Bytes optional data to send along with the call\n /// @return Bool whether the call correctly returned the expected value\n function _checkOnERC721Received(\n address from,\n address to,\n uint256 vaultID,\n bytes memory _data\n ) private returns (bool) {\n if (to.isContract()) {\n try IERC721ReceiverUpgradeable(to).onERC721Received(msg.sender, from, vaultID, _data) returns (\n bytes4 retval\n ) {\n return retval == IERC721ReceiverUpgradeable.onERC721Received.selector;\n } catch (bytes memory reason) {\n if (reason.length == 0) {\n revert NonERC721Receiver();\n } else {\n // solhint-disable-next-line no-inline-assembly\n assembly {\n revert(add(32, reason), mload(reason))\n }\n }\n }\n } else {\n return true;\n }\n }\n\n /// @notice Hook that is called before any token transfer. This includes minting and burning.\n /// Calling conditions:\n ///\n /// - When `from` and `to` are both non-zero, `from`'s `vaultID` will be\n /// transferred to `to`.\n /// - When `from` is zero, `vaultID` will be minted for `to`.\n /// - When `to` is zero, `from`'s `vaultID` will be burned.\n /// - `from` and `to` are never both zero.\n function _beforeTokenTransfer(address from, address to, uint256 vaultID) internal virtual {}\n\n /// @notice Get `whitelistingActivated` in storage only if needed\n function _whitelistingActivated() internal view virtual returns (bool) {\n return whitelistingActivated;\n }\n}\n" + }, + "contracts/vaultManager/VaultManagerPermit.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\nimport \"./VaultManagerERC721.sol\";\nimport \"../interfaces/external/IERC1271.sol\";\n\n/// @title VaultManagerPermit\n/// @author Angle Labs, Inc.\n/// @dev Base Implementation of permit functions for the `VaultManager` contract\nabstract contract VaultManagerPermit is Initializable, VaultManagerERC721 {\n using Address for address;\n\n mapping(address => uint256) private _nonces;\n /* solhint-disable var-name-mixedcase */\n bytes32 private _HASHED_NAME;\n bytes32 private _HASHED_VERSION;\n bytes32 private _PERMIT_TYPEHASH;\n /* solhint-enable var-name-mixedcase */\n\n error ExpiredDeadline();\n error InvalidSignature();\n\n //solhint-disable-next-line\n function __ERC721Permit_init(string memory _name) internal onlyInitializing {\n _PERMIT_TYPEHASH = keccak256(\n \"Permit(address owner,address spender,bool approved,uint256 nonce,uint256 deadline)\"\n );\n _HASHED_NAME = keccak256(bytes(_name));\n _HASHED_VERSION = keccak256(bytes(\"1\"));\n }\n\n /// @notice Allows an address to give or revoke approval for all its vaults to another address\n /// @param owner Address signing the permit and giving (or revoking) its approval for all the controlled vaults\n /// @param spender Address to give approval to\n /// @param approved Whether to give or revoke the approval\n /// @param deadline Deadline parameter for the signature to be valid\n /// @dev The `v`, `r`, and `s` parameters are used as signature data\n function permit(\n address owner,\n address spender,\n bool approved,\n uint256 deadline,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) external {\n if (block.timestamp > deadline) revert ExpiredDeadline();\n // Additional signature checks performed in the `ECDSAUpgradeable.recover` function\n if (uint256(s) > 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D576E7357A4501DDFE92F46681B20A0 || (v != 27 && v != 28))\n revert InvalidSignature();\n\n bytes32 digest = keccak256(\n abi.encodePacked(\n \"\\x19\\x01\",\n _domainSeparatorV4(),\n keccak256(\n abi.encode(\n _PERMIT_TYPEHASH,\n // 0x3f43a9c6bafb5c7aab4e0cfe239dc5d4c15caf0381c6104188191f78a6640bd8,\n owner,\n spender,\n approved,\n _useNonce(owner),\n deadline\n )\n )\n )\n );\n if (owner.isContract()) {\n if (IERC1271(owner).isValidSignature(digest, abi.encodePacked(r, s, v)) != 0x1626ba7e)\n revert InvalidSignature();\n } else {\n address signer = ecrecover(digest, v, r, s);\n if (signer != owner || signer == address(0)) revert InvalidSignature();\n }\n\n _setApprovalForAll(owner, spender, approved);\n }\n\n /// @notice Returns the current nonce for an `owner` address\n function nonces(address owner) public view returns (uint256) {\n return _nonces[owner];\n }\n\n /// @notice Returns the domain separator for the current chain.\n // solhint-disable-next-line func-name-mixedcase\n function DOMAIN_SEPARATOR() external view returns (bytes32) {\n return _domainSeparatorV4();\n }\n\n /// @notice Internal version of the `DOMAIN_SEPARATOR` function\n function _domainSeparatorV4() internal view returns (bytes32) {\n return\n keccak256(\n abi.encode(\n // keccak256('EIP712Domain(string name,string version,uint256 chainId,address verifyingContract)')\n 0x8b73c3c69bb8fe3d512ecc4cf759cc79239f7b179b0ffacaa9a75d522b39400f,\n _HASHED_NAME,\n _HASHED_VERSION,\n block.chainid,\n address(this)\n )\n );\n }\n\n /// @notice Consumes a nonce for an address: returns the current value and increments it\n function _useNonce(address owner) internal returns (uint256 current) {\n current = _nonces[owner];\n _nonces[owner] = current + 1;\n }\n\n uint256[49] private __gap;\n}\n" + }, + "contracts/vaultManager/VaultManagerStorage.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\nimport \"@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/token/ERC20/extensions/draft-IERC20PermitUpgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/token/ERC721/IERC721ReceiverUpgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/interfaces/IERC721MetadataUpgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/utils/introspection/IERC165Upgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/utils/AddressUpgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/security/ReentrancyGuardUpgradeable.sol\";\nimport \"@openzeppelin/contracts/token/ERC20/extensions/IERC20Metadata.sol\";\nimport \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\nimport \"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\";\n\nimport \"../interfaces/IAgToken.sol\";\nimport \"../interfaces/IOracle.sol\";\nimport \"../interfaces/ISwapper.sol\";\nimport \"../interfaces/ITreasury.sol\";\nimport \"../interfaces/IVaultManager.sol\";\nimport \"../interfaces/governance/IVeBoostProxy.sol\";\n\n/// @title VaultManagerStorage\n/// @author Angle Labs, Inc.\n/// @dev Variables, references, parameters and events needed in the `VaultManager` contract\n// solhint-disable-next-line max-states-count\ncontract VaultManagerStorage is IVaultManagerStorage, Initializable, ReentrancyGuardUpgradeable {\n /// @notice Base used for parameter computation: almost all the parameters of this contract are set in `BASE_PARAMS`\n uint256 public constant BASE_PARAMS = 10 ** 9;\n /// @notice Base used for interest rate computation\n uint256 public constant BASE_INTEREST = 10 ** 27;\n /// @notice Used for interest rate computation\n uint256 public constant HALF_BASE_INTEREST = 10 ** 27 / 2;\n\n // ================================= REFERENCES ================================\n\n /// @inheritdoc IVaultManagerStorage\n ITreasury public treasury;\n /// @inheritdoc IVaultManagerStorage\n IERC20 public collateral;\n /// @inheritdoc IVaultManagerStorage\n IAgToken public stablecoin;\n /// @inheritdoc IVaultManagerStorage\n IOracle public oracle;\n /// @notice Reference to the contract which computes adjusted veANGLE balances for liquidators boosts\n IVeBoostProxy public veBoostProxy;\n /// @notice Base of the collateral\n uint256 internal _collatBase;\n\n // ================================= PARAMETERS ================================\n // Unless specified otherwise, parameters of this contract are expressed in `BASE_PARAMS`\n\n /// @notice Maximum amount of stablecoins that can be issued with this contract (in `BASE_TOKENS`). This parameter should\n /// not be bigger than `type(uint256).max / BASE_INTEREST` otherwise there may be some overflows in the `increaseDebt` function\n uint256 public debtCeiling;\n /// @notice Threshold veANGLE balance values for the computation of the boost for liquidators: the length of this array\n /// should normally be 2. The base of the x-values in this array should be `BASE_TOKENS`\n uint256[] public xLiquidationBoost;\n /// @notice Values of the liquidation boost at the threshold values of x\n uint256[] public yLiquidationBoost;\n /// @inheritdoc IVaultManagerStorage\n uint64 public collateralFactor;\n /// @notice Maximum Health factor at which a vault can end up after a liquidation (unless it's fully liquidated)\n uint64 public targetHealthFactor;\n /// @notice Upfront fee taken when borrowing stablecoins: this fee is optional and should in practice not be used\n uint64 public borrowFee;\n /// @notice Upfront fee taken when repaying stablecoins: this fee is optional as well. It should be smaller\n /// than the liquidation surcharge (cf below) to avoid exploits where people voluntarily get liquidated at a 0\n /// discount to pay smaller repaying fees\n uint64 public repayFee;\n /// @notice Per second interest taken to borrowers taking agToken loans. Contrarily to other parameters, it is set in `BASE_INTEREST`\n /// that is to say in base 10**27\n uint64 public interestRate;\n /// @notice Fee taken by the protocol during a liquidation. Technically, this value is not the fee per se, it's 1 - fee.\n /// For instance for a 2% fee, `liquidationSurcharge` should be 98%\n uint64 public liquidationSurcharge;\n /// @notice Maximum discount given to liquidators\n uint64 public maxLiquidationDiscount;\n /// @notice Whether whitelisting is required to own a vault or not\n bool public whitelistingActivated;\n /// @notice Whether the contract is paused or not\n bool public paused;\n\n // ================================= VARIABLES =================================\n\n /// @notice Timestamp at which the `interestAccumulator` was updated\n uint256 public lastInterestAccumulatorUpdated;\n /// @inheritdoc IVaultManagerStorage\n uint256 public interestAccumulator;\n /// @inheritdoc IVaultManagerStorage\n uint256 public totalNormalizedDebt;\n /// @notice Surplus accumulated by the contract: surplus is always in stablecoins, and is then reset\n /// when the value is communicated to the treasury contract\n uint256 public surplus;\n /// @notice Bad debt made from liquidated vaults which ended up having no collateral and a positive amount\n /// of stablecoins\n uint256 public badDebt;\n\n // ================================== MAPPINGS =================================\n\n /// @inheritdoc IVaultManagerStorage\n mapping(uint256 => Vault) public vaultData;\n /// @notice Maps an address to 1 if it's whitelisted and can open or own a vault\n mapping(address => uint256) public isWhitelisted;\n\n // ================================ ERC721 DATA ================================\n\n /// @inheritdoc IVaultManagerStorage\n uint256 public vaultIDCount;\n\n /// @notice URI\n string internal _baseURI;\n\n // Mapping from `vaultID` to owner address\n mapping(uint256 => address) internal _owners;\n\n // Mapping from owner address to vault owned count\n mapping(address => uint256) internal _balances;\n\n // Mapping from `vaultID` to approved address\n mapping(uint256 => address) internal _vaultApprovals;\n\n // Mapping from owner to operator approvals\n mapping(address => mapping(address => uint256)) internal _operatorApprovals;\n\n uint256[50] private __gap;\n\n // =================================== EVENTS ==================================\n\n event AccruedToTreasury(uint256 surplusEndValue, uint256 badDebtEndValue);\n event CollateralAmountUpdated(uint256 vaultID, uint256 collateralAmount, uint8 isIncrease);\n event InterestAccumulatorUpdated(uint256 value, uint256 timestamp);\n event InternalDebtUpdated(uint256 vaultID, uint256 internalAmount, uint8 isIncrease);\n event FiledUint64(uint64 param, bytes32 what);\n event DebtCeilingUpdated(uint256 debtCeiling);\n event LiquidationBoostParametersUpdated(address indexed _veBoostProxy, uint256[] xBoost, uint256[] yBoost);\n event LiquidatedVaults(uint256[] vaultIDs);\n event DebtTransferred(uint256 srcVaultID, uint256 dstVaultID, address dstVaultManager, uint256 amount);\n\n // =================================== ERRORS ==================================\n\n error ApprovalToOwner();\n error ApprovalToCaller();\n error DustyLeftoverAmount();\n error DebtCeilingExceeded();\n error HealthyVault();\n error IncompatibleLengths();\n error InsolventVault();\n error InvalidParameterValue();\n error InvalidParameterType();\n error InvalidSetOfParameters();\n error InvalidTreasury();\n error NonERC721Receiver();\n error NonexistentVault();\n error NotApproved();\n error NotGovernor();\n error NotGovernorOrGuardian();\n error NotTreasury();\n error NotWhitelisted();\n error NotVaultManager();\n error Paused();\n error TooHighParameterValue();\n error TooSmallParameterValue();\n error ZeroAddress();\n\n /// @custom:oz-upgrades-unsafe-allow constructor\n constructor() initializer {}\n}\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 1000000 + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers", + "metadata", + "devdoc", + "userdoc", + "storageLayout", + "evm.gasEstimates", + "devdoc", + "userdoc" + ], + "": [ + "ast" + ] + } + }, + "metadata": { + "useLiteralContent": true + } + } +} \ No newline at end of file diff --git a/deployments/gnosis/AgTokenSideChainMultiBridge_Implementation.json b/deployments/gnosis/AgTokenSideChainMultiBridge_Implementation.json index 0c2ce7d8..463187a7 100644 --- a/deployments/gnosis/AgTokenSideChainMultiBridge_Implementation.json +++ b/deployments/gnosis/AgTokenSideChainMultiBridge_Implementation.json @@ -1,5 +1,5 @@ { - "address": "0x59153e939c5b4721543251ff3049Ea04c755373B", + "address": "0xc63AAf16F1fa309e97CAbe3937472d6cA16fB629", "abi": [ { "inputs": [], @@ -1211,44 +1211,44 @@ "type": "function" } ], - "transactionHash": "0xb0d6ee3bf818ba54b3c527f0b28bed98dd41057d41937e59f16c703ed96a25b5", + "transactionHash": "0x5283dadcbc53947ef911ad3758bed9d68309f88b8b4ce56cd6314fbdcc70cad0", "receipt": { "to": null, "from": "0xfdA462548Ce04282f4B6D6619823a7C64Fdc0185", - "contractAddress": "0x59153e939c5b4721543251ff3049Ea04c755373B", - "transactionIndex": 1, - "gasUsed": "3970824", - "logsBloom": "0x00000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000004000000000000000000000000000000000000000000000000000000000000000000000000000080000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", - "blockHash": "0xf3ce235ddf49b575a655b5e577ccaeba91663bdaaa7b40f633ae87ccbc606985", - "transactionHash": "0xb0d6ee3bf818ba54b3c527f0b28bed98dd41057d41937e59f16c703ed96a25b5", + "contractAddress": "0xc63AAf16F1fa309e97CAbe3937472d6cA16fB629", + "transactionIndex": 23, + "gasUsed": "3966151", + "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000080000000000000000000000000000000000000000000000400000000000000000010000000000040000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "blockHash": "0x75a01b1b9facec93bcdb5b1464e8f05f219c61d2d4cea2f54dca7046b1a98471", + "transactionHash": "0x5283dadcbc53947ef911ad3758bed9d68309f88b8b4ce56cd6314fbdcc70cad0", "logs": [ { - "transactionIndex": 1, - "blockNumber": 27626094, - "transactionHash": "0xb0d6ee3bf818ba54b3c527f0b28bed98dd41057d41937e59f16c703ed96a25b5", - "address": "0x59153e939c5b4721543251ff3049Ea04c755373B", + "transactionIndex": 23, + "blockNumber": 31876822, + "transactionHash": "0x5283dadcbc53947ef911ad3758bed9d68309f88b8b4ce56cd6314fbdcc70cad0", + "address": "0xc63AAf16F1fa309e97CAbe3937472d6cA16fB629", "topics": [ "0x7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb3847402498" ], "data": "0x0000000000000000000000000000000000000000000000000000000000000001", - "logIndex": 1, - "blockHash": "0xf3ce235ddf49b575a655b5e577ccaeba91663bdaaa7b40f633ae87ccbc606985" + "logIndex": 136, + "blockHash": "0x75a01b1b9facec93bcdb5b1464e8f05f219c61d2d4cea2f54dca7046b1a98471" } ], - "blockNumber": 27626094, - "cumulativeGasUsed": "4007985", + "blockNumber": 31876822, + "cumulativeGasUsed": "7451719", "status": 1, "byzantium": true }, "args": [], - "numDeployments": 1, - "solcInputHash": "0f9a6ebe7ec9fe0adfd464d351fcde70", - "metadata": "{\"compiler\":{\"version\":\"0.8.17+commit.8df45f5f\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[],\"name\":\"AssetStillControlledInReserves\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"BurnAmountExceedsAllowance\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"HourlyLimitExceeded\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidSender\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidToken\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidTreasury\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"NotGovernor\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"NotGovernorOrGuardian\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"NotMinter\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"NotTreasury\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"TooBigAmount\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"TooHighParameterValue\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ZeroAddress\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"spender\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"}],\"name\":\"Approval\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"bridgeToken\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"limit\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"hourlyLimit\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"fee\",\"type\":\"uint64\"},{\"indexed\":false,\"internalType\":\"bool\",\"name\":\"paused\",\"type\":\"bool\"}],\"name\":\"BridgeTokenAdded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"bridgeToken\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"fee\",\"type\":\"uint64\"}],\"name\":\"BridgeTokenFeeUpdated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"bridgeToken\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"hourlyLimit\",\"type\":\"uint256\"}],\"name\":\"BridgeTokenHourlyLimitUpdated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"bridgeToken\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"limit\",\"type\":\"uint256\"}],\"name\":\"BridgeTokenLimitUpdated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"bridgeToken\",\"type\":\"address\"}],\"name\":\"BridgeTokenRemoved\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"bridgeToken\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"bool\",\"name\":\"toggleStatus\",\"type\":\"bool\"}],\"name\":\"BridgeTokenToggled\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"theAddress\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"toggleStatus\",\"type\":\"uint256\"}],\"name\":\"FeeToggled\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"hourlyLimit\",\"type\":\"uint256\"}],\"name\":\"HourlyLimitUpdated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint8\",\"name\":\"version\",\"type\":\"uint8\"}],\"name\":\"Initialized\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"minter\",\"type\":\"address\"}],\"name\":\"MinterToggled\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"Recovered\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"}],\"name\":\"Transfer\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"_treasury\",\"type\":\"address\"}],\"name\":\"TreasuryUpdated\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"BASE_PARAMS\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"DOMAIN_SEPARATOR\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"bridgeToken\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"limit\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"hourlyLimit\",\"type\":\"uint256\"},{\"internalType\":\"uint64\",\"name\":\"fee\",\"type\":\"uint64\"},{\"internalType\":\"bool\",\"name\":\"paused\",\"type\":\"bool\"}],\"name\":\"addBridgeToken\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"minter\",\"type\":\"address\"}],\"name\":\"addMinter\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"allBridgeTokens\",\"outputs\":[{\"internalType\":\"address[]\",\"name\":\"\",\"type\":\"address[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"spender\",\"type\":\"address\"}],\"name\":\"allowance\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"spender\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"approve\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"}],\"name\":\"balanceOf\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"name\":\"bridgeTokensList\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"bridges\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"limit\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"hourlyLimit\",\"type\":\"uint256\"},{\"internalType\":\"uint64\",\"name\":\"fee\",\"type\":\"uint64\"},{\"internalType\":\"bool\",\"name\":\"allowed\",\"type\":\"bool\"},{\"internalType\":\"bool\",\"name\":\"paused\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"burner\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"}],\"name\":\"burnFrom\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"burner\",\"type\":\"address\"}],\"name\":\"burnSelf\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"burnStablecoin\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"chainTotalHourlyLimit\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"name\":\"chainTotalUsage\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"currentTotalUsage\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"bridgeToken\",\"type\":\"address\"}],\"name\":\"currentUsage\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"decimals\",\"outputs\":[{\"internalType\":\"uint8\",\"name\":\"\",\"type\":\"uint8\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"spender\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"subtractedValue\",\"type\":\"uint256\"}],\"name\":\"decreaseAllowance\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"spender\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"addedValue\",\"type\":\"uint256\"}],\"name\":\"increaseAllowance\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"string\",\"name\":\"name_\",\"type\":\"string\"},{\"internalType\":\"string\",\"name\":\"symbol_\",\"type\":\"string\"},{\"internalType\":\"address\",\"name\":\"_treasury\",\"type\":\"address\"}],\"name\":\"initialize\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"isFeeExempt\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"isMinter\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"mint\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"name\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"}],\"name\":\"nonces\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"spender\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"deadline\",\"type\":\"uint256\"},{\"internalType\":\"uint8\",\"name\":\"v\",\"type\":\"uint8\"},{\"internalType\":\"bytes32\",\"name\":\"r\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32\",\"name\":\"s\",\"type\":\"bytes32\"}],\"name\":\"permit\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"tokenAddress\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amountToRecover\",\"type\":\"uint256\"}],\"name\":\"recoverERC20\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"bridgeToken\",\"type\":\"address\"}],\"name\":\"removeBridgeToken\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"minter\",\"type\":\"address\"}],\"name\":\"removeMinter\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"hourlyLimit\",\"type\":\"uint256\"}],\"name\":\"setChainTotalHourlyLimit\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"bridgeToken\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"hourlyLimit\",\"type\":\"uint256\"}],\"name\":\"setHourlyLimit\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"bridgeToken\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"limit\",\"type\":\"uint256\"}],\"name\":\"setLimit\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"bridgeToken\",\"type\":\"address\"},{\"internalType\":\"uint64\",\"name\":\"fee\",\"type\":\"uint64\"}],\"name\":\"setSwapFee\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_treasury\",\"type\":\"address\"}],\"name\":\"setTreasury\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"bridgeToken\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"swapIn\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"bridgeToken\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"swapOut\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"symbol\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"bridgeToken\",\"type\":\"address\"}],\"name\":\"toggleBridge\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"theAddress\",\"type\":\"address\"}],\"name\":\"toggleFeesForAddress\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"totalSupply\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"transfer\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"transferFrom\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"treasury\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"name\":\"usage\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"}],\"devdoc\":{\"author\":\"Angle Labs, Inc.\",\"details\":\"This contract supports bridge tokens having a minting right on the stablecoin (also referred to as the canonical or the native token)References: - FRAX implementation: https://polygonscan.com/address/0x45c32fA6DF82ead1e2EF74d17b76547EDdFaFF89#code - QiDAO implementation: https://snowtrace.io/address/0x5c49b268c9841AFF1Cc3B0a418ff5c3442eE3F3b#code\",\"kind\":\"dev\",\"methods\":{\"DOMAIN_SEPARATOR()\":{\"details\":\"See {IERC20Permit-DOMAIN_SEPARATOR}.\"},\"addBridgeToken(address,uint256,uint256,uint64,bool)\":{\"params\":{\"bridgeToken\":\"Bridge token to add: it should be a version of the stablecoin from another bridge\",\"fee\":\"Fee taken upon swapping for or against this token\",\"hourlyLimit\":\"Limit on the hourly volume for this bridge\",\"limit\":\"Limit on the balance of bridge token this contract could hold\",\"paused\":\"Whether swapping for this token should be paused or not\"}},\"addMinter(address)\":{\"details\":\"Zero address checks are performed directly in the `Treasury` contract\",\"params\":{\"minter\":\"Minter address to add\"}},\"allBridgeTokens()\":{\"details\":\"Helpful for UIs\"},\"allowance(address,address)\":{\"details\":\"See {IERC20-allowance}.\"},\"approve(address,uint256)\":{\"details\":\"See {IERC20-approve}. NOTE: If `amount` is the maximum `uint256`, the allowance is not updated on `transferFrom`. This is semantically equivalent to an infinite approval. Requirements: - `spender` cannot be the zero address.\"},\"balanceOf(address)\":{\"details\":\"See {IERC20-balanceOf}.\"},\"burnFrom(uint256,address,address)\":{\"details\":\"This method is to be called by a contract with the minter right after being requested to do so by a `sender` address willing to burn tokens from another `burner` addressThe method checks the allowance between the `sender` and the `burner`\",\"params\":{\"amount\":\"Amount of tokens to burn\",\"burner\":\"Address to burn from\",\"sender\":\"Address which requested the burn from `burner`\"}},\"burnSelf(uint256,address)\":{\"details\":\"This method is to be called by a contract with a minter right on the AgToken after being requested to do so by an address willing to burn tokens from its address\",\"params\":{\"amount\":\"Amount of tokens to burn\",\"burner\":\"Address to burn from\"}},\"burnStablecoin(uint256)\":{\"details\":\"This function can typically be called if there is a settlement mechanism to burn stablecoins\",\"params\":{\"amount\":\"Amount of stablecoins to burn\"}},\"currentTotalUsage()\":{\"details\":\"Helpful for UIs\"},\"currentUsage(address)\":{\"details\":\"Helpful for UIs\",\"params\":{\"bridgeToken\":\"Bridge used to mint\"}},\"decimals()\":{\"details\":\"Returns the number of decimals used to get its user representation. For example, if `decimals` equals `2`, a balance of `505` tokens should be displayed to a user as `5.05` (`505 / 10 ** 2`). Tokens usually opt for a value of 18, imitating the relationship between Ether and Wei. This is the value {ERC20} uses, unless this function is overridden; NOTE: This information is only used for _display_ purposes: it in no way affects any of the arithmetic of the contract, including {IERC20-balanceOf} and {IERC20-transfer}.\"},\"decreaseAllowance(address,uint256)\":{\"details\":\"Atomically decreases the allowance granted to `spender` by the caller. This is an alternative to {approve} that can be used as a mitigation for problems described in {IERC20-approve}. Emits an {Approval} event indicating the updated allowance. Requirements: - `spender` cannot be the zero address. - `spender` must have allowance for the caller of at least `subtractedValue`.\"},\"increaseAllowance(address,uint256)\":{\"details\":\"Atomically increases the allowance granted to `spender` by the caller. This is an alternative to {approve} that can be used as a mitigation for problems described in {IERC20-approve}. Emits an {Approval} event indicating the updated allowance. Requirements: - `spender` cannot be the zero address.\"},\"initialize(string,string,address)\":{\"details\":\"By default, agTokens are ERC-20 tokens with 18 decimals\",\"params\":{\"_treasury\":\"Reference to the `Treasury` contract associated to this agToken\",\"name_\":\"Name of the token\",\"symbol_\":\"Symbol of the token\"}},\"mint(address,uint256)\":{\"details\":\"The contracts allowed to issue agTokens are the `StableMaster` contract, `VaultManager` contracts associated to this stablecoin as well as the flash loan module (if activated) and potentially contracts whitelisted by governance\",\"params\":{\"account\":\"Address to mint to\",\"amount\":\"Amount to mint\"}},\"name()\":{\"details\":\"Returns the name of the token.\"},\"nonces(address)\":{\"details\":\"See {IERC20Permit-nonces}.\"},\"permit(address,address,uint256,uint256,uint8,bytes32,bytes32)\":{\"details\":\"See {IERC20Permit-permit}.\"},\"recoverERC20(address,address,uint256)\":{\"details\":\"Can be used to withdraw bridge tokens for them to be de-bridged on mainnet\"},\"removeBridgeToken(address)\":{\"params\":{\"bridgeToken\":\"Address of the bridge token to remove support for\"}},\"removeMinter(address)\":{\"details\":\"This function can also be called by a minter wishing to revoke itself\",\"params\":{\"minter\":\"Minter address to remove\"}},\"setTreasury(address)\":{\"params\":{\"_treasury\":\"New treasury address\"}},\"swapIn(address,uint256,address)\":{\"details\":\"Some fees may be taken by the protocol depending on the token used and on the address calling\",\"params\":{\"amount\":\"Amount of bridge tokens to send\",\"bridgeToken\":\"Bridge token to use to mint\",\"to\":\"Address to which the stablecoin should be sent\"},\"returns\":{\"_0\":\"Amount of the canonical stablecoin actually minted\"}},\"swapOut(address,uint256,address)\":{\"details\":\"Some fees may be taken by the protocol depending on the token used and on the address calling\",\"params\":{\"amount\":\"Amount of canonical tokens to burn\",\"bridgeToken\":\"Bridge token required\",\"to\":\"Address to which the bridge token should be sent\"},\"returns\":{\"_0\":\"Amount of bridge tokens actually sent back\"}},\"symbol()\":{\"details\":\"Returns the symbol of the token, usually a shorter version of the name.\"},\"totalSupply()\":{\"details\":\"See {IERC20-totalSupply}.\"},\"transfer(address,uint256)\":{\"details\":\"See {IERC20-transfer}. Requirements: - `to` cannot be the zero address. - the caller must have a balance of at least `amount`.\"},\"transferFrom(address,address,uint256)\":{\"details\":\"See {IERC20-transferFrom}. Emits an {Approval} event indicating the updated allowance. This is not required by the EIP. See the note at the beginning of {ERC20}. NOTE: Does not update the allowance if the current allowance is the maximum `uint256`. Requirements: - `from` and `to` cannot be the zero address. - `from` must have a balance of at least `amount`. - the caller must have allowance for ``from``'s tokens of at least `amount`.\"}},\"title\":\"AgTokenSideChainMultiBridge\",\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{\"BASE_PARAMS()\":{\"notice\":\"Base used for fee computation\"},\"addBridgeToken(address,uint256,uint256,uint64,bool)\":{\"notice\":\"Adds support for a bridge token\"},\"addMinter(address)\":{\"notice\":\"Adds a minter in the contract\"},\"allBridgeTokens()\":{\"notice\":\"Returns the list of all supported bridge tokens\"},\"bridgeTokensList(uint256)\":{\"notice\":\"List of all bridge tokens\"},\"bridges(address)\":{\"notice\":\"Maps a bridge token to data\"},\"burnFrom(uint256,address,address)\":{\"notice\":\"Burns `amount` tokens from a `burner` address after being asked to by `sender`\"},\"burnSelf(uint256,address)\":{\"notice\":\"Burns `amount` tokens from a `burner` address\"},\"burnStablecoin(uint256)\":{\"notice\":\"Allows anyone to burn agToken without redeeming collateral back\"},\"chainTotalHourlyLimit()\":{\"notice\":\"Limit to the amount of tokens that can be sent from that chain to another chain\"},\"chainTotalUsage(uint256)\":{\"notice\":\"Usage per hour on that chain. Maps an hourly timestamp to the total volume swapped out on the chain\"},\"currentTotalUsage()\":{\"notice\":\"Returns the current total volume on the chain for the current hour\"},\"currentUsage(address)\":{\"notice\":\"Returns the current volume for a bridge, for the current hour\"},\"initialize(string,string,address)\":{\"notice\":\"Initializes the `AgToken` contract\"},\"isFeeExempt(address)\":{\"notice\":\"Maps an address to whether it is exempt of fees for when it comes to swapping in and out\"},\"isMinter(address)\":{\"notice\":\"Checks whether an address has the right to mint agTokens\"},\"mint(address,uint256)\":{\"notice\":\"Lets the `StableMaster` contract or another whitelisted contract mint agTokens\"},\"recoverERC20(address,address,uint256)\":{\"notice\":\"Recovers any ERC20 token\"},\"removeBridgeToken(address)\":{\"notice\":\"Removes support for a token\"},\"removeMinter(address)\":{\"notice\":\"Removes a minter from the contract\"},\"setChainTotalHourlyLimit(uint256)\":{\"notice\":\"Updates the `chainTotalHourlyLimit` amount\"},\"setHourlyLimit(address,uint256)\":{\"notice\":\"Updates the `hourlyLimit` amount for `bridgeToken`\"},\"setLimit(address,uint256)\":{\"notice\":\"Updates the `limit` amount for `bridgeToken`\"},\"setSwapFee(address,uint64)\":{\"notice\":\"Updates the `fee` value for `bridgeToken`\"},\"setTreasury(address)\":{\"notice\":\"Sets a new treasury contract\"},\"swapIn(address,uint256,address)\":{\"notice\":\"Mints the canonical token from a supported bridge token\"},\"swapOut(address,uint256,address)\":{\"notice\":\"Burns the canonical token in exchange for a bridge token\"},\"toggleBridge(address)\":{\"notice\":\"Pauses or unpauses swapping in and out for a token\"},\"toggleFeesForAddress(address)\":{\"notice\":\"Toggles fees for the address `theAddress`\"},\"treasury()\":{\"notice\":\"Reference to the treasury contract which can grant minting rights\"},\"usage(address,uint256)\":{\"notice\":\"Maps a bridge token to the associated hourly volume\"}},\"notice\":\"Contract for Angle agTokens on other chains than Ethereum mainnet\",\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/agToken/AgTokenSideChainMultiBridge.sol\":\"AgTokenSideChainMultiBridge\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":1000000},\"remappings\":[]},\"sources\":{\"@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.7.0) (proxy/utils/Initializable.sol)\\n\\npragma solidity ^0.8.2;\\n\\nimport \\\"../../utils/AddressUpgradeable.sol\\\";\\n\\n/**\\n * @dev This is a base contract to aid in writing upgradeable contracts, or any kind of contract that will be deployed\\n * behind a proxy. Since proxied contracts do not make use of a constructor, it's common to move constructor logic to an\\n * external initializer function, usually called `initialize`. It then becomes necessary to protect this initializer\\n * function so it can only be called once. The {initializer} modifier provided by this contract will have this effect.\\n *\\n * The initialization functions use a version number. Once a version number is used, it is consumed and cannot be\\n * reused. This mechanism prevents re-execution of each \\\"step\\\" but allows the creation of new initialization steps in\\n * case an upgrade adds a module that needs to be initialized.\\n *\\n * For example:\\n *\\n * [.hljs-theme-light.nopadding]\\n * ```\\n * contract MyToken is ERC20Upgradeable {\\n * function initialize() initializer public {\\n * __ERC20_init(\\\"MyToken\\\", \\\"MTK\\\");\\n * }\\n * }\\n * contract MyTokenV2 is MyToken, ERC20PermitUpgradeable {\\n * function initializeV2() reinitializer(2) public {\\n * __ERC20Permit_init(\\\"MyToken\\\");\\n * }\\n * }\\n * ```\\n *\\n * TIP: To avoid leaving the proxy in an uninitialized state, the initializer function should be called as early as\\n * possible by providing the encoded function call as the `_data` argument to {ERC1967Proxy-constructor}.\\n *\\n * CAUTION: When used with inheritance, manual care must be taken to not invoke a parent initializer twice, or to ensure\\n * that all initializers are idempotent. This is not verified automatically as constructors are by Solidity.\\n *\\n * [CAUTION]\\n * ====\\n * Avoid leaving a contract uninitialized.\\n *\\n * An uninitialized contract can be taken over by an attacker. This applies to both a proxy and its implementation\\n * contract, which may impact the proxy. To prevent the implementation contract from being used, you should invoke\\n * the {_disableInitializers} function in the constructor to automatically lock it when it is deployed:\\n *\\n * [.hljs-theme-light.nopadding]\\n * ```\\n * /// @custom:oz-upgrades-unsafe-allow constructor\\n * constructor() {\\n * _disableInitializers();\\n * }\\n * ```\\n * ====\\n */\\nabstract contract Initializable {\\n /**\\n * @dev Indicates that the contract has been initialized.\\n * @custom:oz-retyped-from bool\\n */\\n uint8 private _initialized;\\n\\n /**\\n * @dev Indicates that the contract is in the process of being initialized.\\n */\\n bool private _initializing;\\n\\n /**\\n * @dev Triggered when the contract has been initialized or reinitialized.\\n */\\n event Initialized(uint8 version);\\n\\n /**\\n * @dev A modifier that defines a protected initializer function that can be invoked at most once. In its scope,\\n * `onlyInitializing` functions can be used to initialize parent contracts. Equivalent to `reinitializer(1)`.\\n */\\n modifier initializer() {\\n bool isTopLevelCall = !_initializing;\\n require(\\n (isTopLevelCall && _initialized < 1) || (!AddressUpgradeable.isContract(address(this)) && _initialized == 1),\\n \\\"Initializable: contract is already initialized\\\"\\n );\\n _initialized = 1;\\n if (isTopLevelCall) {\\n _initializing = true;\\n }\\n _;\\n if (isTopLevelCall) {\\n _initializing = false;\\n emit Initialized(1);\\n }\\n }\\n\\n /**\\n * @dev A modifier that defines a protected reinitializer function that can be invoked at most once, and only if the\\n * contract hasn't been initialized to a greater version before. In its scope, `onlyInitializing` functions can be\\n * used to initialize parent contracts.\\n *\\n * `initializer` is equivalent to `reinitializer(1)`, so a reinitializer may be used after the original\\n * initialization step. This is essential to configure modules that are added through upgrades and that require\\n * initialization.\\n *\\n * Note that versions can jump in increments greater than 1; this implies that if multiple reinitializers coexist in\\n * a contract, executing them in the right order is up to the developer or operator.\\n */\\n modifier reinitializer(uint8 version) {\\n require(!_initializing && _initialized < version, \\\"Initializable: contract is already initialized\\\");\\n _initialized = version;\\n _initializing = true;\\n _;\\n _initializing = false;\\n emit Initialized(version);\\n }\\n\\n /**\\n * @dev Modifier to protect an initialization function so that it can only be invoked by functions with the\\n * {initializer} and {reinitializer} modifiers, directly or indirectly.\\n */\\n modifier onlyInitializing() {\\n require(_initializing, \\\"Initializable: contract is not initializing\\\");\\n _;\\n }\\n\\n /**\\n * @dev Locks the contract, preventing any future reinitialization. This cannot be part of an initializer call.\\n * Calling this in the constructor of a contract will prevent that contract from being initialized or reinitialized\\n * to any version. It is recommended to use this to lock implementation contracts that are designed to be called\\n * through proxies.\\n */\\n function _disableInitializers() internal virtual {\\n require(!_initializing, \\\"Initializable: contract is initializing\\\");\\n if (_initialized < type(uint8).max) {\\n _initialized = type(uint8).max;\\n emit Initialized(type(uint8).max);\\n }\\n }\\n}\\n\",\"keccak256\":\"0x0203dcadc5737d9ef2c211d6fa15d18ebc3b30dfa51903b64870b01a062b0b4e\",\"license\":\"MIT\"},\"@openzeppelin/contracts-upgradeable/token/ERC20/ERC20Upgradeable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.7.0) (token/ERC20/ERC20.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"./IERC20Upgradeable.sol\\\";\\nimport \\\"./extensions/IERC20MetadataUpgradeable.sol\\\";\\nimport \\\"../../utils/ContextUpgradeable.sol\\\";\\nimport \\\"../../proxy/utils/Initializable.sol\\\";\\n\\n/**\\n * @dev Implementation of the {IERC20} interface.\\n *\\n * This implementation is agnostic to the way tokens are created. This means\\n * that a supply mechanism has to be added in a derived contract using {_mint}.\\n * For a generic mechanism see {ERC20PresetMinterPauser}.\\n *\\n * TIP: For a detailed writeup see our guide\\n * https://forum.zeppelin.solutions/t/how-to-implement-erc20-supply-mechanisms/226[How\\n * to implement supply mechanisms].\\n *\\n * We have followed general OpenZeppelin Contracts guidelines: functions revert\\n * instead returning `false` on failure. This behavior is nonetheless\\n * conventional and does not conflict with the expectations of ERC20\\n * applications.\\n *\\n * Additionally, an {Approval} event is emitted on calls to {transferFrom}.\\n * This allows applications to reconstruct the allowance for all accounts just\\n * by listening to said events. Other implementations of the EIP may not emit\\n * these events, as it isn't required by the specification.\\n *\\n * Finally, the non-standard {decreaseAllowance} and {increaseAllowance}\\n * functions have been added to mitigate the well-known issues around setting\\n * allowances. See {IERC20-approve}.\\n */\\ncontract ERC20Upgradeable is Initializable, ContextUpgradeable, IERC20Upgradeable, IERC20MetadataUpgradeable {\\n mapping(address => uint256) private _balances;\\n\\n mapping(address => mapping(address => uint256)) private _allowances;\\n\\n uint256 private _totalSupply;\\n\\n string private _name;\\n string private _symbol;\\n\\n /**\\n * @dev Sets the values for {name} and {symbol}.\\n *\\n * The default value of {decimals} is 18. To select a different value for\\n * {decimals} you should overload it.\\n *\\n * All two of these values are immutable: they can only be set once during\\n * construction.\\n */\\n function __ERC20_init(string memory name_, string memory symbol_) internal onlyInitializing {\\n __ERC20_init_unchained(name_, symbol_);\\n }\\n\\n function __ERC20_init_unchained(string memory name_, string memory symbol_) internal onlyInitializing {\\n _name = name_;\\n _symbol = symbol_;\\n }\\n\\n /**\\n * @dev Returns the name of the token.\\n */\\n function name() public view virtual override returns (string memory) {\\n return _name;\\n }\\n\\n /**\\n * @dev Returns the symbol of the token, usually a shorter version of the\\n * name.\\n */\\n function symbol() public view virtual override returns (string memory) {\\n return _symbol;\\n }\\n\\n /**\\n * @dev Returns the number of decimals used to get its user representation.\\n * For example, if `decimals` equals `2`, a balance of `505` tokens should\\n * be displayed to a user as `5.05` (`505 / 10 ** 2`).\\n *\\n * Tokens usually opt for a value of 18, imitating the relationship between\\n * Ether and Wei. This is the value {ERC20} uses, unless this function is\\n * overridden;\\n *\\n * NOTE: This information is only used for _display_ purposes: it in\\n * no way affects any of the arithmetic of the contract, including\\n * {IERC20-balanceOf} and {IERC20-transfer}.\\n */\\n function decimals() public view virtual override returns (uint8) {\\n return 18;\\n }\\n\\n /**\\n * @dev See {IERC20-totalSupply}.\\n */\\n function totalSupply() public view virtual override returns (uint256) {\\n return _totalSupply;\\n }\\n\\n /**\\n * @dev See {IERC20-balanceOf}.\\n */\\n function balanceOf(address account) public view virtual override returns (uint256) {\\n return _balances[account];\\n }\\n\\n /**\\n * @dev See {IERC20-transfer}.\\n *\\n * Requirements:\\n *\\n * - `to` cannot be the zero address.\\n * - the caller must have a balance of at least `amount`.\\n */\\n function transfer(address to, uint256 amount) public virtual override returns (bool) {\\n address owner = _msgSender();\\n _transfer(owner, to, amount);\\n return true;\\n }\\n\\n /**\\n * @dev See {IERC20-allowance}.\\n */\\n function allowance(address owner, address spender) public view virtual override returns (uint256) {\\n return _allowances[owner][spender];\\n }\\n\\n /**\\n * @dev See {IERC20-approve}.\\n *\\n * NOTE: If `amount` is the maximum `uint256`, the allowance is not updated on\\n * `transferFrom`. This is semantically equivalent to an infinite approval.\\n *\\n * Requirements:\\n *\\n * - `spender` cannot be the zero address.\\n */\\n function approve(address spender, uint256 amount) public virtual override returns (bool) {\\n address owner = _msgSender();\\n _approve(owner, spender, amount);\\n return true;\\n }\\n\\n /**\\n * @dev See {IERC20-transferFrom}.\\n *\\n * Emits an {Approval} event indicating the updated allowance. This is not\\n * required by the EIP. See the note at the beginning of {ERC20}.\\n *\\n * NOTE: Does not update the allowance if the current allowance\\n * is the maximum `uint256`.\\n *\\n * Requirements:\\n *\\n * - `from` and `to` cannot be the zero address.\\n * - `from` must have a balance of at least `amount`.\\n * - the caller must have allowance for ``from``'s tokens of at least\\n * `amount`.\\n */\\n function transferFrom(\\n address from,\\n address to,\\n uint256 amount\\n ) public virtual override returns (bool) {\\n address spender = _msgSender();\\n _spendAllowance(from, spender, amount);\\n _transfer(from, to, amount);\\n return true;\\n }\\n\\n /**\\n * @dev Atomically increases the allowance granted to `spender` by the caller.\\n *\\n * This is an alternative to {approve} that can be used as a mitigation for\\n * problems described in {IERC20-approve}.\\n *\\n * Emits an {Approval} event indicating the updated allowance.\\n *\\n * Requirements:\\n *\\n * - `spender` cannot be the zero address.\\n */\\n function increaseAllowance(address spender, uint256 addedValue) public virtual returns (bool) {\\n address owner = _msgSender();\\n _approve(owner, spender, allowance(owner, spender) + addedValue);\\n return true;\\n }\\n\\n /**\\n * @dev Atomically decreases the allowance granted to `spender` by the caller.\\n *\\n * This is an alternative to {approve} that can be used as a mitigation for\\n * problems described in {IERC20-approve}.\\n *\\n * Emits an {Approval} event indicating the updated allowance.\\n *\\n * Requirements:\\n *\\n * - `spender` cannot be the zero address.\\n * - `spender` must have allowance for the caller of at least\\n * `subtractedValue`.\\n */\\n function decreaseAllowance(address spender, uint256 subtractedValue) public virtual returns (bool) {\\n address owner = _msgSender();\\n uint256 currentAllowance = allowance(owner, spender);\\n require(currentAllowance >= subtractedValue, \\\"ERC20: decreased allowance below zero\\\");\\n unchecked {\\n _approve(owner, spender, currentAllowance - subtractedValue);\\n }\\n\\n return true;\\n }\\n\\n /**\\n * @dev Moves `amount` of tokens from `from` to `to`.\\n *\\n * This internal function is equivalent to {transfer}, and can be used to\\n * e.g. implement automatic token fees, slashing mechanisms, etc.\\n *\\n * Emits a {Transfer} event.\\n *\\n * Requirements:\\n *\\n * - `from` cannot be the zero address.\\n * - `to` cannot be the zero address.\\n * - `from` must have a balance of at least `amount`.\\n */\\n function _transfer(\\n address from,\\n address to,\\n uint256 amount\\n ) internal virtual {\\n require(from != address(0), \\\"ERC20: transfer from the zero address\\\");\\n require(to != address(0), \\\"ERC20: transfer to the zero address\\\");\\n\\n _beforeTokenTransfer(from, to, amount);\\n\\n uint256 fromBalance = _balances[from];\\n require(fromBalance >= amount, \\\"ERC20: transfer amount exceeds balance\\\");\\n unchecked {\\n _balances[from] = fromBalance - amount;\\n }\\n _balances[to] += amount;\\n\\n emit Transfer(from, to, amount);\\n\\n _afterTokenTransfer(from, to, amount);\\n }\\n\\n /** @dev Creates `amount` tokens and assigns them to `account`, increasing\\n * the total supply.\\n *\\n * Emits a {Transfer} event with `from` set to the zero address.\\n *\\n * Requirements:\\n *\\n * - `account` cannot be the zero address.\\n */\\n function _mint(address account, uint256 amount) internal virtual {\\n require(account != address(0), \\\"ERC20: mint to the zero address\\\");\\n\\n _beforeTokenTransfer(address(0), account, amount);\\n\\n _totalSupply += amount;\\n _balances[account] += amount;\\n emit Transfer(address(0), account, amount);\\n\\n _afterTokenTransfer(address(0), account, amount);\\n }\\n\\n /**\\n * @dev Destroys `amount` tokens from `account`, reducing the\\n * total supply.\\n *\\n * Emits a {Transfer} event with `to` set to the zero address.\\n *\\n * Requirements:\\n *\\n * - `account` cannot be the zero address.\\n * - `account` must have at least `amount` tokens.\\n */\\n function _burn(address account, uint256 amount) internal virtual {\\n require(account != address(0), \\\"ERC20: burn from the zero address\\\");\\n\\n _beforeTokenTransfer(account, address(0), amount);\\n\\n uint256 accountBalance = _balances[account];\\n require(accountBalance >= amount, \\\"ERC20: burn amount exceeds balance\\\");\\n unchecked {\\n _balances[account] = accountBalance - amount;\\n }\\n _totalSupply -= amount;\\n\\n emit Transfer(account, address(0), amount);\\n\\n _afterTokenTransfer(account, address(0), amount);\\n }\\n\\n /**\\n * @dev Sets `amount` as the allowance of `spender` over the `owner` s tokens.\\n *\\n * This internal function is equivalent to `approve`, and can be used to\\n * e.g. set automatic allowances for certain subsystems, etc.\\n *\\n * Emits an {Approval} event.\\n *\\n * Requirements:\\n *\\n * - `owner` cannot be the zero address.\\n * - `spender` cannot be the zero address.\\n */\\n function _approve(\\n address owner,\\n address spender,\\n uint256 amount\\n ) internal virtual {\\n require(owner != address(0), \\\"ERC20: approve from the zero address\\\");\\n require(spender != address(0), \\\"ERC20: approve to the zero address\\\");\\n\\n _allowances[owner][spender] = amount;\\n emit Approval(owner, spender, amount);\\n }\\n\\n /**\\n * @dev Updates `owner` s allowance for `spender` based on spent `amount`.\\n *\\n * Does not update the allowance amount in case of infinite allowance.\\n * Revert if not enough allowance is available.\\n *\\n * Might emit an {Approval} event.\\n */\\n function _spendAllowance(\\n address owner,\\n address spender,\\n uint256 amount\\n ) internal virtual {\\n uint256 currentAllowance = allowance(owner, spender);\\n if (currentAllowance != type(uint256).max) {\\n require(currentAllowance >= amount, \\\"ERC20: insufficient allowance\\\");\\n unchecked {\\n _approve(owner, spender, currentAllowance - amount);\\n }\\n }\\n }\\n\\n /**\\n * @dev Hook that is called before any transfer of tokens. This includes\\n * minting and burning.\\n *\\n * Calling conditions:\\n *\\n * - when `from` and `to` are both non-zero, `amount` of ``from``'s tokens\\n * will be transferred to `to`.\\n * - when `from` is zero, `amount` tokens will be minted for `to`.\\n * - when `to` is zero, `amount` of ``from``'s tokens will be burned.\\n * - `from` and `to` are never both zero.\\n *\\n * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].\\n */\\n function _beforeTokenTransfer(\\n address from,\\n address to,\\n uint256 amount\\n ) internal virtual {}\\n\\n /**\\n * @dev Hook that is called after any transfer of tokens. This includes\\n * minting and burning.\\n *\\n * Calling conditions:\\n *\\n * - when `from` and `to` are both non-zero, `amount` of ``from``'s tokens\\n * has been transferred to `to`.\\n * - when `from` is zero, `amount` tokens have been minted for `to`.\\n * - when `to` is zero, `amount` of ``from``'s tokens have been burned.\\n * - `from` and `to` are never both zero.\\n *\\n * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].\\n */\\n function _afterTokenTransfer(\\n address from,\\n address to,\\n uint256 amount\\n ) internal virtual {}\\n\\n /**\\n * @dev This empty reserved space is put in place to allow future versions to add new\\n * variables without shifting down storage in the inheritance chain.\\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\\n */\\n uint256[45] private __gap;\\n}\\n\",\"keccak256\":\"0x7c7ac0bc6c340a7f320524b9a4b4b079ee9da3c51258080d4bab237f329a427c\",\"license\":\"MIT\"},\"@openzeppelin/contracts-upgradeable/token/ERC20/IERC20Upgradeable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.6.0) (token/ERC20/IERC20.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Interface of the ERC20 standard as defined in the EIP.\\n */\\ninterface IERC20Upgradeable {\\n /**\\n * @dev Emitted when `value` tokens are moved from one account (`from`) to\\n * another (`to`).\\n *\\n * Note that `value` may be zero.\\n */\\n event Transfer(address indexed from, address indexed to, uint256 value);\\n\\n /**\\n * @dev Emitted when the allowance of a `spender` for an `owner` is set by\\n * a call to {approve}. `value` is the new allowance.\\n */\\n event Approval(address indexed owner, address indexed spender, uint256 value);\\n\\n /**\\n * @dev Returns the amount of tokens in existence.\\n */\\n function totalSupply() external view returns (uint256);\\n\\n /**\\n * @dev Returns the amount of tokens owned by `account`.\\n */\\n function balanceOf(address account) external view returns (uint256);\\n\\n /**\\n * @dev Moves `amount` tokens from the caller's account to `to`.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * Emits a {Transfer} event.\\n */\\n function transfer(address to, uint256 amount) external returns (bool);\\n\\n /**\\n * @dev Returns the remaining number of tokens that `spender` will be\\n * allowed to spend on behalf of `owner` through {transferFrom}. This is\\n * zero by default.\\n *\\n * This value changes when {approve} or {transferFrom} are called.\\n */\\n function allowance(address owner, address spender) external view returns (uint256);\\n\\n /**\\n * @dev Sets `amount` as the allowance of `spender` over the caller's tokens.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * IMPORTANT: Beware that changing an allowance with this method brings the risk\\n * that someone may use both the old and the new allowance by unfortunate\\n * transaction ordering. One possible solution to mitigate this race\\n * condition is to first reduce the spender's allowance to 0 and set the\\n * desired value afterwards:\\n * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729\\n *\\n * Emits an {Approval} event.\\n */\\n function approve(address spender, uint256 amount) external returns (bool);\\n\\n /**\\n * @dev Moves `amount` tokens from `from` to `to` using the\\n * allowance mechanism. `amount` is then deducted from the caller's\\n * allowance.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * Emits a {Transfer} event.\\n */\\n function transferFrom(\\n address from,\\n address to,\\n uint256 amount\\n ) external returns (bool);\\n}\\n\",\"keccak256\":\"0x4e733d3164f73f461eaf9d8087a7ad1ea180bdc8ba0d3d61b0e1ae16d8e63dff\",\"license\":\"MIT\"},\"@openzeppelin/contracts-upgradeable/token/ERC20/extensions/IERC20MetadataUpgradeable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (token/ERC20/extensions/IERC20Metadata.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../IERC20Upgradeable.sol\\\";\\n\\n/**\\n * @dev Interface for the optional metadata functions from the ERC20 standard.\\n *\\n * _Available since v4.1._\\n */\\ninterface IERC20MetadataUpgradeable is IERC20Upgradeable {\\n /**\\n * @dev Returns the name of the token.\\n */\\n function name() external view returns (string memory);\\n\\n /**\\n * @dev Returns the symbol of the token.\\n */\\n function symbol() external view returns (string memory);\\n\\n /**\\n * @dev Returns the decimals places of the token.\\n */\\n function decimals() external view returns (uint8);\\n}\\n\",\"keccak256\":\"0x605434219ebbe4653f703640f06969faa5a1d78f0bfef878e5ddbb1ca369ceeb\",\"license\":\"MIT\"},\"@openzeppelin/contracts-upgradeable/token/ERC20/extensions/draft-ERC20PermitUpgradeable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.6.0) (token/ERC20/extensions/draft-ERC20Permit.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"./draft-IERC20PermitUpgradeable.sol\\\";\\nimport \\\"../ERC20Upgradeable.sol\\\";\\nimport \\\"../../../utils/cryptography/draft-EIP712Upgradeable.sol\\\";\\nimport \\\"../../../utils/cryptography/ECDSAUpgradeable.sol\\\";\\nimport \\\"../../../utils/CountersUpgradeable.sol\\\";\\nimport \\\"../../../proxy/utils/Initializable.sol\\\";\\n\\n/**\\n * @dev Implementation of the ERC20 Permit extension allowing approvals to be made via signatures, as defined in\\n * https://eips.ethereum.org/EIPS/eip-2612[EIP-2612].\\n *\\n * Adds the {permit} method, which can be used to change an account's ERC20 allowance (see {IERC20-allowance}) by\\n * presenting a message signed by the account. By not relying on `{IERC20-approve}`, the token holder account doesn't\\n * need to send a transaction, and thus is not required to hold Ether at all.\\n *\\n * _Available since v3.4._\\n *\\n * @custom:storage-size 51\\n */\\nabstract contract ERC20PermitUpgradeable is Initializable, ERC20Upgradeable, IERC20PermitUpgradeable, EIP712Upgradeable {\\n using CountersUpgradeable for CountersUpgradeable.Counter;\\n\\n mapping(address => CountersUpgradeable.Counter) private _nonces;\\n\\n // solhint-disable-next-line var-name-mixedcase\\n bytes32 private constant _PERMIT_TYPEHASH =\\n keccak256(\\\"Permit(address owner,address spender,uint256 value,uint256 nonce,uint256 deadline)\\\");\\n /**\\n * @dev In previous versions `_PERMIT_TYPEHASH` was declared as `immutable`.\\n * However, to ensure consistency with the upgradeable transpiler, we will continue\\n * to reserve a slot.\\n * @custom:oz-renamed-from _PERMIT_TYPEHASH\\n */\\n // solhint-disable-next-line var-name-mixedcase\\n bytes32 private _PERMIT_TYPEHASH_DEPRECATED_SLOT;\\n\\n /**\\n * @dev Initializes the {EIP712} domain separator using the `name` parameter, and setting `version` to `\\\"1\\\"`.\\n *\\n * It's a good idea to use the same `name` that is defined as the ERC20 token name.\\n */\\n function __ERC20Permit_init(string memory name) internal onlyInitializing {\\n __EIP712_init_unchained(name, \\\"1\\\");\\n }\\n\\n function __ERC20Permit_init_unchained(string memory) internal onlyInitializing {}\\n\\n /**\\n * @dev See {IERC20Permit-permit}.\\n */\\n function permit(\\n address owner,\\n address spender,\\n uint256 value,\\n uint256 deadline,\\n uint8 v,\\n bytes32 r,\\n bytes32 s\\n ) public virtual override {\\n require(block.timestamp <= deadline, \\\"ERC20Permit: expired deadline\\\");\\n\\n bytes32 structHash = keccak256(abi.encode(_PERMIT_TYPEHASH, owner, spender, value, _useNonce(owner), deadline));\\n\\n bytes32 hash = _hashTypedDataV4(structHash);\\n\\n address signer = ECDSAUpgradeable.recover(hash, v, r, s);\\n require(signer == owner, \\\"ERC20Permit: invalid signature\\\");\\n\\n _approve(owner, spender, value);\\n }\\n\\n /**\\n * @dev See {IERC20Permit-nonces}.\\n */\\n function nonces(address owner) public view virtual override returns (uint256) {\\n return _nonces[owner].current();\\n }\\n\\n /**\\n * @dev See {IERC20Permit-DOMAIN_SEPARATOR}.\\n */\\n // solhint-disable-next-line func-name-mixedcase\\n function DOMAIN_SEPARATOR() external view override returns (bytes32) {\\n return _domainSeparatorV4();\\n }\\n\\n /**\\n * @dev \\\"Consume a nonce\\\": return the current value and increment.\\n *\\n * _Available since v4.1._\\n */\\n function _useNonce(address owner) internal virtual returns (uint256 current) {\\n CountersUpgradeable.Counter storage nonce = _nonces[owner];\\n current = nonce.current();\\n nonce.increment();\\n }\\n\\n /**\\n * @dev This empty reserved space is put in place to allow future versions to add new\\n * variables without shifting down storage in the inheritance chain.\\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\\n */\\n uint256[49] private __gap;\\n}\\n\",\"keccak256\":\"0x564385ebed633694decce3e13d687f3ac7e8eaef64f7a504bfb3f03ad210601f\",\"license\":\"MIT\"},\"@openzeppelin/contracts-upgradeable/token/ERC20/extensions/draft-IERC20PermitUpgradeable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (token/ERC20/extensions/draft-IERC20Permit.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Interface of the ERC20 Permit extension allowing approvals to be made via signatures, as defined in\\n * https://eips.ethereum.org/EIPS/eip-2612[EIP-2612].\\n *\\n * Adds the {permit} method, which can be used to change an account's ERC20 allowance (see {IERC20-allowance}) by\\n * presenting a message signed by the account. By not relying on {IERC20-approve}, the token holder account doesn't\\n * need to send a transaction, and thus is not required to hold Ether at all.\\n */\\ninterface IERC20PermitUpgradeable {\\n /**\\n * @dev Sets `value` as the allowance of `spender` over ``owner``'s tokens,\\n * given ``owner``'s signed approval.\\n *\\n * IMPORTANT: The same issues {IERC20-approve} has related to transaction\\n * ordering also apply here.\\n *\\n * Emits an {Approval} event.\\n *\\n * Requirements:\\n *\\n * - `spender` cannot be the zero address.\\n * - `deadline` must be a timestamp in the future.\\n * - `v`, `r` and `s` must be a valid `secp256k1` signature from `owner`\\n * over the EIP712-formatted function arguments.\\n * - the signature must use ``owner``'s current nonce (see {nonces}).\\n *\\n * For more information on the signature format, see the\\n * https://eips.ethereum.org/EIPS/eip-2612#specification[relevant EIP\\n * section].\\n */\\n function permit(\\n address owner,\\n address spender,\\n uint256 value,\\n uint256 deadline,\\n uint8 v,\\n bytes32 r,\\n bytes32 s\\n ) external;\\n\\n /**\\n * @dev Returns the current nonce for `owner`. This value must be\\n * included whenever a signature is generated for {permit}.\\n *\\n * Every successful call to {permit} increases ``owner``'s nonce by one. This\\n * prevents a signature from being used multiple times.\\n */\\n function nonces(address owner) external view returns (uint256);\\n\\n /**\\n * @dev Returns the domain separator used in the encoding of the signature for {permit}, as defined by {EIP712}.\\n */\\n // solhint-disable-next-line func-name-mixedcase\\n function DOMAIN_SEPARATOR() external view returns (bytes32);\\n}\\n\",\"keccak256\":\"0xcc70d8e2281fb3ff69e8ab242500f10142cd0a7fa8dd9e45882be270d4d09024\",\"license\":\"MIT\"},\"@openzeppelin/contracts-upgradeable/utils/AddressUpgradeable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.7.0) (utils/Address.sol)\\n\\npragma solidity ^0.8.1;\\n\\n/**\\n * @dev Collection of functions related to the address type\\n */\\nlibrary AddressUpgradeable {\\n /**\\n * @dev Returns true if `account` is a contract.\\n *\\n * [IMPORTANT]\\n * ====\\n * It is unsafe to assume that an address for which this function returns\\n * false is an externally-owned account (EOA) and not a contract.\\n *\\n * Among others, `isContract` will return false for the following\\n * types of addresses:\\n *\\n * - an externally-owned account\\n * - a contract in construction\\n * - an address where a contract will be created\\n * - an address where a contract lived, but was destroyed\\n * ====\\n *\\n * [IMPORTANT]\\n * ====\\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\\n *\\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\\n * constructor.\\n * ====\\n */\\n function isContract(address account) internal view returns (bool) {\\n // This method relies on extcodesize/address.code.length, which returns 0\\n // for contracts in construction, since the code is only stored at the end\\n // of the constructor execution.\\n\\n return account.code.length > 0;\\n }\\n\\n /**\\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\\n * `recipient`, forwarding all available gas and reverting on errors.\\n *\\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\\n * imposed by `transfer`, making them unable to receive funds via\\n * `transfer`. {sendValue} removes this limitation.\\n *\\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\\n *\\n * IMPORTANT: because control is transferred to `recipient`, care must be\\n * taken to not create reentrancy vulnerabilities. Consider using\\n * {ReentrancyGuard} or the\\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\\n */\\n function sendValue(address payable recipient, uint256 amount) internal {\\n require(address(this).balance >= amount, \\\"Address: insufficient balance\\\");\\n\\n (bool success, ) = recipient.call{value: amount}(\\\"\\\");\\n require(success, \\\"Address: unable to send value, recipient may have reverted\\\");\\n }\\n\\n /**\\n * @dev Performs a Solidity function call using a low level `call`. A\\n * plain `call` is an unsafe replacement for a function call: use this\\n * function instead.\\n *\\n * If `target` reverts with a revert reason, it is bubbled up by this\\n * function (like regular Solidity function calls).\\n *\\n * Returns the raw returned data. To convert to the expected return value,\\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\\n *\\n * Requirements:\\n *\\n * - `target` must be a contract.\\n * - calling `target` with `data` must not revert.\\n *\\n * _Available since v3.1._\\n */\\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\\n return functionCall(target, data, \\\"Address: low-level call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\\n * `errorMessage` as a fallback revert reason when `target` reverts.\\n *\\n * _Available since v3.1._\\n */\\n function functionCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n return functionCallWithValue(target, data, 0, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but also transferring `value` wei to `target`.\\n *\\n * Requirements:\\n *\\n * - the calling contract must have an ETH balance of at least `value`.\\n * - the called Solidity function must be `payable`.\\n *\\n * _Available since v3.1._\\n */\\n function functionCallWithValue(\\n address target,\\n bytes memory data,\\n uint256 value\\n ) internal returns (bytes memory) {\\n return functionCallWithValue(target, data, value, \\\"Address: low-level call with value failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\\n * with `errorMessage` as a fallback revert reason when `target` reverts.\\n *\\n * _Available since v3.1._\\n */\\n function functionCallWithValue(\\n address target,\\n bytes memory data,\\n uint256 value,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n require(address(this).balance >= value, \\\"Address: insufficient balance for call\\\");\\n require(isContract(target), \\\"Address: call to non-contract\\\");\\n\\n (bool success, bytes memory returndata) = target.call{value: value}(data);\\n return verifyCallResult(success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but performing a static call.\\n *\\n * _Available since v3.3._\\n */\\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\\n return functionStaticCall(target, data, \\\"Address: low-level static call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\\n * but performing a static call.\\n *\\n * _Available since v3.3._\\n */\\n function functionStaticCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal view returns (bytes memory) {\\n require(isContract(target), \\\"Address: static call to non-contract\\\");\\n\\n (bool success, bytes memory returndata) = target.staticcall(data);\\n return verifyCallResult(success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the\\n * revert reason using the provided one.\\n *\\n * _Available since v4.3._\\n */\\n function verifyCallResult(\\n bool success,\\n bytes memory returndata,\\n string memory errorMessage\\n ) internal pure returns (bytes memory) {\\n if (success) {\\n return returndata;\\n } else {\\n // Look for revert reason and bubble it up if present\\n if (returndata.length > 0) {\\n // The easiest way to bubble the revert reason is using memory via assembly\\n /// @solidity memory-safe-assembly\\n assembly {\\n let returndata_size := mload(returndata)\\n revert(add(32, returndata), returndata_size)\\n }\\n } else {\\n revert(errorMessage);\\n }\\n }\\n }\\n}\\n\",\"keccak256\":\"0x611aa3f23e59cfdd1863c536776407b3e33d695152a266fa7cfb34440a29a8a3\",\"license\":\"MIT\"},\"@openzeppelin/contracts-upgradeable/utils/ContextUpgradeable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)\\n\\npragma solidity ^0.8.0;\\nimport \\\"../proxy/utils/Initializable.sol\\\";\\n\\n/**\\n * @dev Provides information about the current execution context, including the\\n * sender of the transaction and its data. While these are generally available\\n * via msg.sender and msg.data, they should not be accessed in such a direct\\n * manner, since when dealing with meta-transactions the account sending and\\n * paying for execution may not be the actual sender (as far as an application\\n * is concerned).\\n *\\n * This contract is only required for intermediate, library-like contracts.\\n */\\nabstract contract ContextUpgradeable is Initializable {\\n function __Context_init() internal onlyInitializing {\\n }\\n\\n function __Context_init_unchained() internal onlyInitializing {\\n }\\n function _msgSender() internal view virtual returns (address) {\\n return msg.sender;\\n }\\n\\n function _msgData() internal view virtual returns (bytes calldata) {\\n return msg.data;\\n }\\n\\n /**\\n * @dev This empty reserved space is put in place to allow future versions to add new\\n * variables without shifting down storage in the inheritance chain.\\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\\n */\\n uint256[50] private __gap;\\n}\\n\",\"keccak256\":\"0x963ea7f0b48b032eef72fe3a7582edf78408d6f834115b9feadd673a4d5bd149\",\"license\":\"MIT\"},\"@openzeppelin/contracts-upgradeable/utils/CountersUpgradeable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (utils/Counters.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @title Counters\\n * @author Matt Condon (@shrugs)\\n * @dev Provides counters that can only be incremented, decremented or reset. This can be used e.g. to track the number\\n * of elements in a mapping, issuing ERC721 ids, or counting request ids.\\n *\\n * Include with `using Counters for Counters.Counter;`\\n */\\nlibrary CountersUpgradeable {\\n struct Counter {\\n // This variable should never be directly accessed by users of the library: interactions must be restricted to\\n // the library's function. As of Solidity v0.5.2, this cannot be enforced, though there is a proposal to add\\n // this feature: see https://github.com/ethereum/solidity/issues/4637\\n uint256 _value; // default: 0\\n }\\n\\n function current(Counter storage counter) internal view returns (uint256) {\\n return counter._value;\\n }\\n\\n function increment(Counter storage counter) internal {\\n unchecked {\\n counter._value += 1;\\n }\\n }\\n\\n function decrement(Counter storage counter) internal {\\n uint256 value = counter._value;\\n require(value > 0, \\\"Counter: decrement overflow\\\");\\n unchecked {\\n counter._value = value - 1;\\n }\\n }\\n\\n function reset(Counter storage counter) internal {\\n counter._value = 0;\\n }\\n}\\n\",\"keccak256\":\"0x798741e231b22b81e2dd2eddaaf8832dee4baf5cd8e2dbaa5c1dd12a1c053c4d\",\"license\":\"MIT\"},\"@openzeppelin/contracts-upgradeable/utils/StringsUpgradeable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.7.0) (utils/Strings.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev String operations.\\n */\\nlibrary StringsUpgradeable {\\n bytes16 private constant _HEX_SYMBOLS = \\\"0123456789abcdef\\\";\\n uint8 private constant _ADDRESS_LENGTH = 20;\\n\\n /**\\n * @dev Converts a `uint256` to its ASCII `string` decimal representation.\\n */\\n function toString(uint256 value) internal pure returns (string memory) {\\n // Inspired by OraclizeAPI's implementation - MIT licence\\n // https://github.com/oraclize/ethereum-api/blob/b42146b063c7d6ee1358846c198246239e9360e8/oraclizeAPI_0.4.25.sol\\n\\n if (value == 0) {\\n return \\\"0\\\";\\n }\\n uint256 temp = value;\\n uint256 digits;\\n while (temp != 0) {\\n digits++;\\n temp /= 10;\\n }\\n bytes memory buffer = new bytes(digits);\\n while (value != 0) {\\n digits -= 1;\\n buffer[digits] = bytes1(uint8(48 + uint256(value % 10)));\\n value /= 10;\\n }\\n return string(buffer);\\n }\\n\\n /**\\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation.\\n */\\n function toHexString(uint256 value) internal pure returns (string memory) {\\n if (value == 0) {\\n return \\\"0x00\\\";\\n }\\n uint256 temp = value;\\n uint256 length = 0;\\n while (temp != 0) {\\n length++;\\n temp >>= 8;\\n }\\n return toHexString(value, length);\\n }\\n\\n /**\\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length.\\n */\\n function toHexString(uint256 value, uint256 length) internal pure returns (string memory) {\\n bytes memory buffer = new bytes(2 * length + 2);\\n buffer[0] = \\\"0\\\";\\n buffer[1] = \\\"x\\\";\\n for (uint256 i = 2 * length + 1; i > 1; --i) {\\n buffer[i] = _HEX_SYMBOLS[value & 0xf];\\n value >>= 4;\\n }\\n require(value == 0, \\\"Strings: hex length insufficient\\\");\\n return string(buffer);\\n }\\n\\n /**\\n * @dev Converts an `address` with fixed length of 20 bytes to its not checksummed ASCII `string` hexadecimal representation.\\n */\\n function toHexString(address addr) internal pure returns (string memory) {\\n return toHexString(uint256(uint160(addr)), _ADDRESS_LENGTH);\\n }\\n}\\n\",\"keccak256\":\"0xea5339a7fff0ed42b45be56a88efdd0b2ddde9fa480dc99fef9a6a4c5b776863\",\"license\":\"MIT\"},\"@openzeppelin/contracts-upgradeable/utils/cryptography/ECDSAUpgradeable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.7.0) (utils/cryptography/ECDSA.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../StringsUpgradeable.sol\\\";\\n\\n/**\\n * @dev Elliptic Curve Digital Signature Algorithm (ECDSA) operations.\\n *\\n * These functions can be used to verify that a message was signed by the holder\\n * of the private keys of a given address.\\n */\\nlibrary ECDSAUpgradeable {\\n enum RecoverError {\\n NoError,\\n InvalidSignature,\\n InvalidSignatureLength,\\n InvalidSignatureS,\\n InvalidSignatureV\\n }\\n\\n function _throwError(RecoverError error) private pure {\\n if (error == RecoverError.NoError) {\\n return; // no error: do nothing\\n } else if (error == RecoverError.InvalidSignature) {\\n revert(\\\"ECDSA: invalid signature\\\");\\n } else if (error == RecoverError.InvalidSignatureLength) {\\n revert(\\\"ECDSA: invalid signature length\\\");\\n } else if (error == RecoverError.InvalidSignatureS) {\\n revert(\\\"ECDSA: invalid signature 's' value\\\");\\n } else if (error == RecoverError.InvalidSignatureV) {\\n revert(\\\"ECDSA: invalid signature 'v' value\\\");\\n }\\n }\\n\\n /**\\n * @dev Returns the address that signed a hashed message (`hash`) with\\n * `signature` or error string. This address can then be used for verification purposes.\\n *\\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\\n * this function rejects them by requiring the `s` value to be in the lower\\n * half order, and the `v` value to be either 27 or 28.\\n *\\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\\n * verification to be secure: it is possible to craft signatures that\\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\\n * this is by receiving a hash of the original message (which may otherwise\\n * be too long), and then calling {toEthSignedMessageHash} on it.\\n *\\n * Documentation for signature generation:\\n * - with https://web3js.readthedocs.io/en/v1.3.4/web3-eth-accounts.html#sign[Web3.js]\\n * - with https://docs.ethers.io/v5/api/signer/#Signer-signMessage[ethers]\\n *\\n * _Available since v4.3._\\n */\\n function tryRecover(bytes32 hash, bytes memory signature) internal pure returns (address, RecoverError) {\\n // Check the signature length\\n // - case 65: r,s,v signature (standard)\\n // - case 64: r,vs signature (cf https://eips.ethereum.org/EIPS/eip-2098) _Available since v4.1._\\n if (signature.length == 65) {\\n bytes32 r;\\n bytes32 s;\\n uint8 v;\\n // ecrecover takes the signature parameters, and the only way to get them\\n // currently is to use assembly.\\n /// @solidity memory-safe-assembly\\n assembly {\\n r := mload(add(signature, 0x20))\\n s := mload(add(signature, 0x40))\\n v := byte(0, mload(add(signature, 0x60)))\\n }\\n return tryRecover(hash, v, r, s);\\n } else if (signature.length == 64) {\\n bytes32 r;\\n bytes32 vs;\\n // ecrecover takes the signature parameters, and the only way to get them\\n // currently is to use assembly.\\n /// @solidity memory-safe-assembly\\n assembly {\\n r := mload(add(signature, 0x20))\\n vs := mload(add(signature, 0x40))\\n }\\n return tryRecover(hash, r, vs);\\n } else {\\n return (address(0), RecoverError.InvalidSignatureLength);\\n }\\n }\\n\\n /**\\n * @dev Returns the address that signed a hashed message (`hash`) with\\n * `signature`. This address can then be used for verification purposes.\\n *\\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\\n * this function rejects them by requiring the `s` value to be in the lower\\n * half order, and the `v` value to be either 27 or 28.\\n *\\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\\n * verification to be secure: it is possible to craft signatures that\\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\\n * this is by receiving a hash of the original message (which may otherwise\\n * be too long), and then calling {toEthSignedMessageHash} on it.\\n */\\n function recover(bytes32 hash, bytes memory signature) internal pure returns (address) {\\n (address recovered, RecoverError error) = tryRecover(hash, signature);\\n _throwError(error);\\n return recovered;\\n }\\n\\n /**\\n * @dev Overload of {ECDSA-tryRecover} that receives the `r` and `vs` short-signature fields separately.\\n *\\n * See https://eips.ethereum.org/EIPS/eip-2098[EIP-2098 short signatures]\\n *\\n * _Available since v4.3._\\n */\\n function tryRecover(\\n bytes32 hash,\\n bytes32 r,\\n bytes32 vs\\n ) internal pure returns (address, RecoverError) {\\n bytes32 s = vs & bytes32(0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff);\\n uint8 v = uint8((uint256(vs) >> 255) + 27);\\n return tryRecover(hash, v, r, s);\\n }\\n\\n /**\\n * @dev Overload of {ECDSA-recover} that receives the `r and `vs` short-signature fields separately.\\n *\\n * _Available since v4.2._\\n */\\n function recover(\\n bytes32 hash,\\n bytes32 r,\\n bytes32 vs\\n ) internal pure returns (address) {\\n (address recovered, RecoverError error) = tryRecover(hash, r, vs);\\n _throwError(error);\\n return recovered;\\n }\\n\\n /**\\n * @dev Overload of {ECDSA-tryRecover} that receives the `v`,\\n * `r` and `s` signature fields separately.\\n *\\n * _Available since v4.3._\\n */\\n function tryRecover(\\n bytes32 hash,\\n uint8 v,\\n bytes32 r,\\n bytes32 s\\n ) internal pure returns (address, RecoverError) {\\n // EIP-2 still allows signature malleability for ecrecover(). Remove this possibility and make the signature\\n // unique. Appendix F in the Ethereum Yellow paper (https://ethereum.github.io/yellowpaper/paper.pdf), defines\\n // the valid range for s in (301): 0 < s < secp256k1n \\u00f7 2 + 1, and for v in (302): v \\u2208 {27, 28}. Most\\n // signatures from current libraries generate a unique signature with an s-value in the lower half order.\\n //\\n // If your library generates malleable signatures, such as s-values in the upper range, calculate a new s-value\\n // with 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141 - s1 and flip v from 27 to 28 or\\n // vice versa. If your library also generates signatures with 0/1 for v instead 27/28, add 27 to v to accept\\n // these malleable signatures as well.\\n if (uint256(s) > 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D576E7357A4501DDFE92F46681B20A0) {\\n return (address(0), RecoverError.InvalidSignatureS);\\n }\\n if (v != 27 && v != 28) {\\n return (address(0), RecoverError.InvalidSignatureV);\\n }\\n\\n // If the signature is valid (and not malleable), return the signer address\\n address signer = ecrecover(hash, v, r, s);\\n if (signer == address(0)) {\\n return (address(0), RecoverError.InvalidSignature);\\n }\\n\\n return (signer, RecoverError.NoError);\\n }\\n\\n /**\\n * @dev Overload of {ECDSA-recover} that receives the `v`,\\n * `r` and `s` signature fields separately.\\n */\\n function recover(\\n bytes32 hash,\\n uint8 v,\\n bytes32 r,\\n bytes32 s\\n ) internal pure returns (address) {\\n (address recovered, RecoverError error) = tryRecover(hash, v, r, s);\\n _throwError(error);\\n return recovered;\\n }\\n\\n /**\\n * @dev Returns an Ethereum Signed Message, created from a `hash`. This\\n * produces hash corresponding to the one signed with the\\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\\n * JSON-RPC method as part of EIP-191.\\n *\\n * See {recover}.\\n */\\n function toEthSignedMessageHash(bytes32 hash) internal pure returns (bytes32) {\\n // 32 is the length in bytes of hash,\\n // enforced by the type signature above\\n return keccak256(abi.encodePacked(\\\"\\\\x19Ethereum Signed Message:\\\\n32\\\", hash));\\n }\\n\\n /**\\n * @dev Returns an Ethereum Signed Message, created from `s`. This\\n * produces hash corresponding to the one signed with the\\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\\n * JSON-RPC method as part of EIP-191.\\n *\\n * See {recover}.\\n */\\n function toEthSignedMessageHash(bytes memory s) internal pure returns (bytes32) {\\n return keccak256(abi.encodePacked(\\\"\\\\x19Ethereum Signed Message:\\\\n\\\", StringsUpgradeable.toString(s.length), s));\\n }\\n\\n /**\\n * @dev Returns an Ethereum Signed Typed Data, created from a\\n * `domainSeparator` and a `structHash`. This produces hash corresponding\\n * to the one signed with the\\n * https://eips.ethereum.org/EIPS/eip-712[`eth_signTypedData`]\\n * JSON-RPC method as part of EIP-712.\\n *\\n * See {recover}.\\n */\\n function toTypedDataHash(bytes32 domainSeparator, bytes32 structHash) internal pure returns (bytes32) {\\n return keccak256(abi.encodePacked(\\\"\\\\x19\\\\x01\\\", domainSeparator, structHash));\\n }\\n}\\n\",\"keccak256\":\"0xe8c62ca00ed2d0a4d9b7e3c4bf7d62c821618b2cdb3c844da91a1193986851bf\",\"license\":\"MIT\"},\"@openzeppelin/contracts-upgradeable/utils/cryptography/draft-EIP712Upgradeable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (utils/cryptography/draft-EIP712.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"./ECDSAUpgradeable.sol\\\";\\nimport \\\"../../proxy/utils/Initializable.sol\\\";\\n\\n/**\\n * @dev https://eips.ethereum.org/EIPS/eip-712[EIP 712] is a standard for hashing and signing of typed structured data.\\n *\\n * The encoding specified in the EIP is very generic, and such a generic implementation in Solidity is not feasible,\\n * thus this contract does not implement the encoding itself. Protocols need to implement the type-specific encoding\\n * they need in their contracts using a combination of `abi.encode` and `keccak256`.\\n *\\n * This contract implements the EIP 712 domain separator ({_domainSeparatorV4}) that is used as part of the encoding\\n * scheme, and the final step of the encoding to obtain the message digest that is then signed via ECDSA\\n * ({_hashTypedDataV4}).\\n *\\n * The implementation of the domain separator was designed to be as efficient as possible while still properly updating\\n * the chain id to protect against replay attacks on an eventual fork of the chain.\\n *\\n * NOTE: This contract implements the version of the encoding known as \\\"v4\\\", as implemented by the JSON RPC method\\n * https://docs.metamask.io/guide/signing-data.html[`eth_signTypedDataV4` in MetaMask].\\n *\\n * _Available since v3.4._\\n *\\n * @custom:storage-size 52\\n */\\nabstract contract EIP712Upgradeable is Initializable {\\n /* solhint-disable var-name-mixedcase */\\n bytes32 private _HASHED_NAME;\\n bytes32 private _HASHED_VERSION;\\n bytes32 private constant _TYPE_HASH = keccak256(\\\"EIP712Domain(string name,string version,uint256 chainId,address verifyingContract)\\\");\\n\\n /* solhint-enable var-name-mixedcase */\\n\\n /**\\n * @dev Initializes the domain separator and parameter caches.\\n *\\n * The meaning of `name` and `version` is specified in\\n * https://eips.ethereum.org/EIPS/eip-712#definition-of-domainseparator[EIP 712]:\\n *\\n * - `name`: the user readable name of the signing domain, i.e. the name of the DApp or the protocol.\\n * - `version`: the current major version of the signing domain.\\n *\\n * NOTE: These parameters cannot be changed except through a xref:learn::upgrading-smart-contracts.adoc[smart\\n * contract upgrade].\\n */\\n function __EIP712_init(string memory name, string memory version) internal onlyInitializing {\\n __EIP712_init_unchained(name, version);\\n }\\n\\n function __EIP712_init_unchained(string memory name, string memory version) internal onlyInitializing {\\n bytes32 hashedName = keccak256(bytes(name));\\n bytes32 hashedVersion = keccak256(bytes(version));\\n _HASHED_NAME = hashedName;\\n _HASHED_VERSION = hashedVersion;\\n }\\n\\n /**\\n * @dev Returns the domain separator for the current chain.\\n */\\n function _domainSeparatorV4() internal view returns (bytes32) {\\n return _buildDomainSeparator(_TYPE_HASH, _EIP712NameHash(), _EIP712VersionHash());\\n }\\n\\n function _buildDomainSeparator(\\n bytes32 typeHash,\\n bytes32 nameHash,\\n bytes32 versionHash\\n ) private view returns (bytes32) {\\n return keccak256(abi.encode(typeHash, nameHash, versionHash, block.chainid, address(this)));\\n }\\n\\n /**\\n * @dev Given an already https://eips.ethereum.org/EIPS/eip-712#definition-of-hashstruct[hashed struct], this\\n * function returns the hash of the fully encoded EIP712 message for this domain.\\n *\\n * This hash can be used together with {ECDSA-recover} to obtain the signer of a message. For example:\\n *\\n * ```solidity\\n * bytes32 digest = _hashTypedDataV4(keccak256(abi.encode(\\n * keccak256(\\\"Mail(address to,string contents)\\\"),\\n * mailTo,\\n * keccak256(bytes(mailContents))\\n * )));\\n * address signer = ECDSA.recover(digest, signature);\\n * ```\\n */\\n function _hashTypedDataV4(bytes32 structHash) internal view virtual returns (bytes32) {\\n return ECDSAUpgradeable.toTypedDataHash(_domainSeparatorV4(), structHash);\\n }\\n\\n /**\\n * @dev The hash of the name parameter for the EIP712 domain.\\n *\\n * NOTE: This function reads from storage by default, but can be redefined to return a constant value if gas costs\\n * are a concern.\\n */\\n function _EIP712NameHash() internal virtual view returns (bytes32) {\\n return _HASHED_NAME;\\n }\\n\\n /**\\n * @dev The hash of the version parameter for the EIP712 domain.\\n *\\n * NOTE: This function reads from storage by default, but can be redefined to return a constant value if gas costs\\n * are a concern.\\n */\\n function _EIP712VersionHash() internal virtual view returns (bytes32) {\\n return _HASHED_VERSION;\\n }\\n\\n /**\\n * @dev This empty reserved space is put in place to allow future versions to add new\\n * variables without shifting down storage in the inheritance chain.\\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\\n */\\n uint256[50] private __gap;\\n}\\n\",\"keccak256\":\"0xaf5a96100f421d61693605349511e43221d3c2e47d4b3efa87af2b936e2567fc\",\"license\":\"MIT\"},\"@openzeppelin/contracts/token/ERC20/IERC20.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.6.0) (token/ERC20/IERC20.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Interface of the ERC20 standard as defined in the EIP.\\n */\\ninterface IERC20 {\\n /**\\n * @dev Emitted when `value` tokens are moved from one account (`from`) to\\n * another (`to`).\\n *\\n * Note that `value` may be zero.\\n */\\n event Transfer(address indexed from, address indexed to, uint256 value);\\n\\n /**\\n * @dev Emitted when the allowance of a `spender` for an `owner` is set by\\n * a call to {approve}. `value` is the new allowance.\\n */\\n event Approval(address indexed owner, address indexed spender, uint256 value);\\n\\n /**\\n * @dev Returns the amount of tokens in existence.\\n */\\n function totalSupply() external view returns (uint256);\\n\\n /**\\n * @dev Returns the amount of tokens owned by `account`.\\n */\\n function balanceOf(address account) external view returns (uint256);\\n\\n /**\\n * @dev Moves `amount` tokens from the caller's account to `to`.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * Emits a {Transfer} event.\\n */\\n function transfer(address to, uint256 amount) external returns (bool);\\n\\n /**\\n * @dev Returns the remaining number of tokens that `spender` will be\\n * allowed to spend on behalf of `owner` through {transferFrom}. This is\\n * zero by default.\\n *\\n * This value changes when {approve} or {transferFrom} are called.\\n */\\n function allowance(address owner, address spender) external view returns (uint256);\\n\\n /**\\n * @dev Sets `amount` as the allowance of `spender` over the caller's tokens.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * IMPORTANT: Beware that changing an allowance with this method brings the risk\\n * that someone may use both the old and the new allowance by unfortunate\\n * transaction ordering. One possible solution to mitigate this race\\n * condition is to first reduce the spender's allowance to 0 and set the\\n * desired value afterwards:\\n * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729\\n *\\n * Emits an {Approval} event.\\n */\\n function approve(address spender, uint256 amount) external returns (bool);\\n\\n /**\\n * @dev Moves `amount` tokens from `from` to `to` using the\\n * allowance mechanism. `amount` is then deducted from the caller's\\n * allowance.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * Emits a {Transfer} event.\\n */\\n function transferFrom(\\n address from,\\n address to,\\n uint256 amount\\n ) external returns (bool);\\n}\\n\",\"keccak256\":\"0x9750c6b834f7b43000631af5cc30001c5f547b3ceb3635488f140f60e897ea6b\",\"license\":\"MIT\"},\"@openzeppelin/contracts/token/ERC20/extensions/draft-IERC20Permit.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (token/ERC20/extensions/draft-IERC20Permit.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Interface of the ERC20 Permit extension allowing approvals to be made via signatures, as defined in\\n * https://eips.ethereum.org/EIPS/eip-2612[EIP-2612].\\n *\\n * Adds the {permit} method, which can be used to change an account's ERC20 allowance (see {IERC20-allowance}) by\\n * presenting a message signed by the account. By not relying on {IERC20-approve}, the token holder account doesn't\\n * need to send a transaction, and thus is not required to hold Ether at all.\\n */\\ninterface IERC20Permit {\\n /**\\n * @dev Sets `value` as the allowance of `spender` over ``owner``'s tokens,\\n * given ``owner``'s signed approval.\\n *\\n * IMPORTANT: The same issues {IERC20-approve} has related to transaction\\n * ordering also apply here.\\n *\\n * Emits an {Approval} event.\\n *\\n * Requirements:\\n *\\n * - `spender` cannot be the zero address.\\n * - `deadline` must be a timestamp in the future.\\n * - `v`, `r` and `s` must be a valid `secp256k1` signature from `owner`\\n * over the EIP712-formatted function arguments.\\n * - the signature must use ``owner``'s current nonce (see {nonces}).\\n *\\n * For more information on the signature format, see the\\n * https://eips.ethereum.org/EIPS/eip-2612#specification[relevant EIP\\n * section].\\n */\\n function permit(\\n address owner,\\n address spender,\\n uint256 value,\\n uint256 deadline,\\n uint8 v,\\n bytes32 r,\\n bytes32 s\\n ) external;\\n\\n /**\\n * @dev Returns the current nonce for `owner`. This value must be\\n * included whenever a signature is generated for {permit}.\\n *\\n * Every successful call to {permit} increases ``owner``'s nonce by one. This\\n * prevents a signature from being used multiple times.\\n */\\n function nonces(address owner) external view returns (uint256);\\n\\n /**\\n * @dev Returns the domain separator used in the encoding of the signature for {permit}, as defined by {EIP712}.\\n */\\n // solhint-disable-next-line func-name-mixedcase\\n function DOMAIN_SEPARATOR() external view returns (bytes32);\\n}\\n\",\"keccak256\":\"0xf41ca991f30855bf80ffd11e9347856a517b977f0a6c2d52e6421a99b7840329\",\"license\":\"MIT\"},\"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.7.0) (token/ERC20/utils/SafeERC20.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../IERC20.sol\\\";\\nimport \\\"../extensions/draft-IERC20Permit.sol\\\";\\nimport \\\"../../../utils/Address.sol\\\";\\n\\n/**\\n * @title SafeERC20\\n * @dev Wrappers around ERC20 operations that throw on failure (when the token\\n * contract returns false). Tokens that return no value (and instead revert or\\n * throw on failure) are also supported, non-reverting calls are assumed to be\\n * successful.\\n * To use this library you can add a `using SafeERC20 for IERC20;` statement to your contract,\\n * which allows you to call the safe operations as `token.safeTransfer(...)`, etc.\\n */\\nlibrary SafeERC20 {\\n using Address for address;\\n\\n function safeTransfer(\\n IERC20 token,\\n address to,\\n uint256 value\\n ) internal {\\n _callOptionalReturn(token, abi.encodeWithSelector(token.transfer.selector, to, value));\\n }\\n\\n function safeTransferFrom(\\n IERC20 token,\\n address from,\\n address to,\\n uint256 value\\n ) internal {\\n _callOptionalReturn(token, abi.encodeWithSelector(token.transferFrom.selector, from, to, value));\\n }\\n\\n /**\\n * @dev Deprecated. This function has issues similar to the ones found in\\n * {IERC20-approve}, and its usage is discouraged.\\n *\\n * Whenever possible, use {safeIncreaseAllowance} and\\n * {safeDecreaseAllowance} instead.\\n */\\n function safeApprove(\\n IERC20 token,\\n address spender,\\n uint256 value\\n ) internal {\\n // safeApprove should only be called when setting an initial allowance,\\n // or when resetting it to zero. To increase and decrease it, use\\n // 'safeIncreaseAllowance' and 'safeDecreaseAllowance'\\n require(\\n (value == 0) || (token.allowance(address(this), spender) == 0),\\n \\\"SafeERC20: approve from non-zero to non-zero allowance\\\"\\n );\\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, value));\\n }\\n\\n function safeIncreaseAllowance(\\n IERC20 token,\\n address spender,\\n uint256 value\\n ) internal {\\n uint256 newAllowance = token.allowance(address(this), spender) + value;\\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));\\n }\\n\\n function safeDecreaseAllowance(\\n IERC20 token,\\n address spender,\\n uint256 value\\n ) internal {\\n unchecked {\\n uint256 oldAllowance = token.allowance(address(this), spender);\\n require(oldAllowance >= value, \\\"SafeERC20: decreased allowance below zero\\\");\\n uint256 newAllowance = oldAllowance - value;\\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));\\n }\\n }\\n\\n function safePermit(\\n IERC20Permit token,\\n address owner,\\n address spender,\\n uint256 value,\\n uint256 deadline,\\n uint8 v,\\n bytes32 r,\\n bytes32 s\\n ) internal {\\n uint256 nonceBefore = token.nonces(owner);\\n token.permit(owner, spender, value, deadline, v, r, s);\\n uint256 nonceAfter = token.nonces(owner);\\n require(nonceAfter == nonceBefore + 1, \\\"SafeERC20: permit did not succeed\\\");\\n }\\n\\n /**\\n * @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement\\n * on the return value: the return value is optional (but if data is returned, it must not be false).\\n * @param token The token targeted by the call.\\n * @param data The call data (encoded using abi.encode or one of its variants).\\n */\\n function _callOptionalReturn(IERC20 token, bytes memory data) private {\\n // We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since\\n // we're implementing it ourselves. We use {Address.functionCall} to perform this call, which verifies that\\n // the target address contains contract code and also asserts for success in the low-level call.\\n\\n bytes memory returndata = address(token).functionCall(data, \\\"SafeERC20: low-level call failed\\\");\\n if (returndata.length > 0) {\\n // Return data is optional\\n require(abi.decode(returndata, (bool)), \\\"SafeERC20: ERC20 operation did not succeed\\\");\\n }\\n }\\n}\\n\",\"keccak256\":\"0x032807210d1d7d218963d7355d62e021a84bf1b3339f4f50be2f63b53cccaf29\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/Address.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.7.0) (utils/Address.sol)\\n\\npragma solidity ^0.8.1;\\n\\n/**\\n * @dev Collection of functions related to the address type\\n */\\nlibrary Address {\\n /**\\n * @dev Returns true if `account` is a contract.\\n *\\n * [IMPORTANT]\\n * ====\\n * It is unsafe to assume that an address for which this function returns\\n * false is an externally-owned account (EOA) and not a contract.\\n *\\n * Among others, `isContract` will return false for the following\\n * types of addresses:\\n *\\n * - an externally-owned account\\n * - a contract in construction\\n * - an address where a contract will be created\\n * - an address where a contract lived, but was destroyed\\n * ====\\n *\\n * [IMPORTANT]\\n * ====\\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\\n *\\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\\n * constructor.\\n * ====\\n */\\n function isContract(address account) internal view returns (bool) {\\n // This method relies on extcodesize/address.code.length, which returns 0\\n // for contracts in construction, since the code is only stored at the end\\n // of the constructor execution.\\n\\n return account.code.length > 0;\\n }\\n\\n /**\\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\\n * `recipient`, forwarding all available gas and reverting on errors.\\n *\\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\\n * imposed by `transfer`, making them unable to receive funds via\\n * `transfer`. {sendValue} removes this limitation.\\n *\\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\\n *\\n * IMPORTANT: because control is transferred to `recipient`, care must be\\n * taken to not create reentrancy vulnerabilities. Consider using\\n * {ReentrancyGuard} or the\\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\\n */\\n function sendValue(address payable recipient, uint256 amount) internal {\\n require(address(this).balance >= amount, \\\"Address: insufficient balance\\\");\\n\\n (bool success, ) = recipient.call{value: amount}(\\\"\\\");\\n require(success, \\\"Address: unable to send value, recipient may have reverted\\\");\\n }\\n\\n /**\\n * @dev Performs a Solidity function call using a low level `call`. A\\n * plain `call` is an unsafe replacement for a function call: use this\\n * function instead.\\n *\\n * If `target` reverts with a revert reason, it is bubbled up by this\\n * function (like regular Solidity function calls).\\n *\\n * Returns the raw returned data. To convert to the expected return value,\\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\\n *\\n * Requirements:\\n *\\n * - `target` must be a contract.\\n * - calling `target` with `data` must not revert.\\n *\\n * _Available since v3.1._\\n */\\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\\n return functionCall(target, data, \\\"Address: low-level call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\\n * `errorMessage` as a fallback revert reason when `target` reverts.\\n *\\n * _Available since v3.1._\\n */\\n function functionCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n return functionCallWithValue(target, data, 0, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but also transferring `value` wei to `target`.\\n *\\n * Requirements:\\n *\\n * - the calling contract must have an ETH balance of at least `value`.\\n * - the called Solidity function must be `payable`.\\n *\\n * _Available since v3.1._\\n */\\n function functionCallWithValue(\\n address target,\\n bytes memory data,\\n uint256 value\\n ) internal returns (bytes memory) {\\n return functionCallWithValue(target, data, value, \\\"Address: low-level call with value failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\\n * with `errorMessage` as a fallback revert reason when `target` reverts.\\n *\\n * _Available since v3.1._\\n */\\n function functionCallWithValue(\\n address target,\\n bytes memory data,\\n uint256 value,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n require(address(this).balance >= value, \\\"Address: insufficient balance for call\\\");\\n require(isContract(target), \\\"Address: call to non-contract\\\");\\n\\n (bool success, bytes memory returndata) = target.call{value: value}(data);\\n return verifyCallResult(success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but performing a static call.\\n *\\n * _Available since v3.3._\\n */\\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\\n return functionStaticCall(target, data, \\\"Address: low-level static call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\\n * but performing a static call.\\n *\\n * _Available since v3.3._\\n */\\n function functionStaticCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal view returns (bytes memory) {\\n require(isContract(target), \\\"Address: static call to non-contract\\\");\\n\\n (bool success, bytes memory returndata) = target.staticcall(data);\\n return verifyCallResult(success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but performing a delegate call.\\n *\\n * _Available since v3.4._\\n */\\n function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {\\n return functionDelegateCall(target, data, \\\"Address: low-level delegate call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\\n * but performing a delegate call.\\n *\\n * _Available since v3.4._\\n */\\n function functionDelegateCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n require(isContract(target), \\\"Address: delegate call to non-contract\\\");\\n\\n (bool success, bytes memory returndata) = target.delegatecall(data);\\n return verifyCallResult(success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the\\n * revert reason using the provided one.\\n *\\n * _Available since v4.3._\\n */\\n function verifyCallResult(\\n bool success,\\n bytes memory returndata,\\n string memory errorMessage\\n ) internal pure returns (bytes memory) {\\n if (success) {\\n return returndata;\\n } else {\\n // Look for revert reason and bubble it up if present\\n if (returndata.length > 0) {\\n // The easiest way to bubble the revert reason is using memory via assembly\\n /// @solidity memory-safe-assembly\\n assembly {\\n let returndata_size := mload(returndata)\\n revert(add(32, returndata), returndata_size)\\n }\\n } else {\\n revert(errorMessage);\\n }\\n }\\n }\\n}\\n\",\"keccak256\":\"0xd6153ce99bcdcce22b124f755e72553295be6abcd63804cfdffceb188b8bef10\",\"license\":\"MIT\"},\"contracts/agToken/AgTokenSideChainMultiBridge.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-3.0\\n\\npragma solidity ^0.8.12;\\n\\nimport \\\"./BaseAgTokenSideChain.sol\\\";\\nimport \\\"@openzeppelin/contracts/token/ERC20/IERC20.sol\\\";\\nimport \\\"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\\\";\\n\\n/// @title AgTokenSideChainMultiBridge\\n/// @author Angle Labs, Inc.\\n/// @notice Contract for Angle agTokens on other chains than Ethereum mainnet\\n/// @dev This contract supports bridge tokens having a minting right on the stablecoin (also referred to as the canonical\\n/// or the native token)\\n/// @dev References:\\n/// - FRAX implementation: https://polygonscan.com/address/0x45c32fA6DF82ead1e2EF74d17b76547EDdFaFF89#code\\n/// - QiDAO implementation: https://snowtrace.io/address/0x5c49b268c9841AFF1Cc3B0a418ff5c3442eE3F3b#code\\ncontract AgTokenSideChainMultiBridge is BaseAgTokenSideChain {\\n using SafeERC20 for IERC20;\\n\\n /// @notice Base used for fee computation\\n uint256 public constant BASE_PARAMS = 10**9;\\n\\n // =============================== Bridging Data ===============================\\n\\n /// @notice Struct with some data about a specific bridge token\\n struct BridgeDetails {\\n // Limit on the balance of bridge token held by the contract: it is designed\\n // to reduce the exposure of the system to hacks\\n uint256 limit;\\n // Limit on the hourly volume of token minted through this bridge\\n // Technically the limit over a rolling hour is hourlyLimit x2 as hourly limit\\n // is enforced only between x:00 and x+1:00\\n uint256 hourlyLimit;\\n // Fee taken for swapping in and out the token\\n uint64 fee;\\n // Whether the associated token is allowed or not\\n bool allowed;\\n // Whether swapping in and out from the associated token is paused or not\\n bool paused;\\n }\\n\\n /// @notice Maps a bridge token to data\\n mapping(address => BridgeDetails) public bridges;\\n /// @notice List of all bridge tokens\\n address[] public bridgeTokensList;\\n /// @notice Maps a bridge token to the associated hourly volume\\n mapping(address => mapping(uint256 => uint256)) public usage;\\n /// @notice Maps an address to whether it is exempt of fees for when it comes to swapping in and out\\n mapping(address => uint256) public isFeeExempt;\\n /// @notice Limit to the amount of tokens that can be sent from that chain to another chain\\n uint256 public chainTotalHourlyLimit;\\n /// @notice Usage per hour on that chain. Maps an hourly timestamp to the total volume swapped out on the chain\\n mapping(uint256 => uint256) public chainTotalUsage;\\n\\n // ================================== Events ===================================\\n\\n event BridgeTokenAdded(address indexed bridgeToken, uint256 limit, uint256 hourlyLimit, uint64 fee, bool paused);\\n event BridgeTokenToggled(address indexed bridgeToken, bool toggleStatus);\\n event BridgeTokenRemoved(address indexed bridgeToken);\\n event BridgeTokenFeeUpdated(address indexed bridgeToken, uint64 fee);\\n event BridgeTokenLimitUpdated(address indexed bridgeToken, uint256 limit);\\n event BridgeTokenHourlyLimitUpdated(address indexed bridgeToken, uint256 hourlyLimit);\\n event HourlyLimitUpdated(uint256 hourlyLimit);\\n event Recovered(address indexed token, address indexed to, uint256 amount);\\n event FeeToggled(address indexed theAddress, uint256 toggleStatus);\\n\\n // =============================== Errors ================================\\n\\n error AssetStillControlledInReserves();\\n error HourlyLimitExceeded();\\n error InvalidToken();\\n error NotGovernor();\\n error NotGovernorOrGuardian();\\n error TooBigAmount();\\n error TooHighParameterValue();\\n error ZeroAddress();\\n\\n // ============================= Constructor ===================================\\n\\n /// @notice Initializes the `AgToken` contract\\n /// @param name_ Name of the token\\n /// @param symbol_ Symbol of the token\\n /// @param _treasury Reference to the `Treasury` contract associated to this agToken\\n /// @dev By default, agTokens are ERC-20 tokens with 18 decimals\\n function initialize(\\n string memory name_,\\n string memory symbol_,\\n address _treasury\\n ) external {\\n _initialize(name_, symbol_, _treasury);\\n }\\n\\n // =============================== Modifiers ===================================\\n\\n /// @notice Checks whether the `msg.sender` has the governor role or not\\n modifier onlyGovernor() {\\n if (!ITreasury(treasury).isGovernor(msg.sender)) revert NotGovernor();\\n _;\\n }\\n\\n /// @notice Checks whether the `msg.sender` has the governor role or the guardian role\\n modifier onlyGovernorOrGuardian() {\\n if (!ITreasury(treasury).isGovernorOrGuardian(msg.sender)) revert NotGovernorOrGuardian();\\n _;\\n }\\n\\n // ==================== External Permissionless Functions ======================\\n\\n /// @notice Returns the list of all supported bridge tokens\\n /// @dev Helpful for UIs\\n function allBridgeTokens() external view returns (address[] memory) {\\n return bridgeTokensList;\\n }\\n\\n /// @notice Returns the current volume for a bridge, for the current hour\\n /// @param bridgeToken Bridge used to mint\\n /// @dev Helpful for UIs\\n function currentUsage(address bridgeToken) external view returns (uint256) {\\n return usage[bridgeToken][block.timestamp / 3600];\\n }\\n\\n /// @notice Returns the current total volume on the chain for the current hour\\n /// @dev Helpful for UIs\\n function currentTotalUsage() external view returns (uint256) {\\n return chainTotalUsage[block.timestamp / 3600];\\n }\\n\\n /// @notice Mints the canonical token from a supported bridge token\\n /// @param bridgeToken Bridge token to use to mint\\n /// @param amount Amount of bridge tokens to send\\n /// @param to Address to which the stablecoin should be sent\\n /// @return Amount of the canonical stablecoin actually minted\\n /// @dev Some fees may be taken by the protocol depending on the token used and on the address calling\\n function swapIn(\\n address bridgeToken,\\n uint256 amount,\\n address to\\n ) external returns (uint256) {\\n BridgeDetails memory bridgeDetails = bridges[bridgeToken];\\n if (!bridgeDetails.allowed || bridgeDetails.paused) revert InvalidToken();\\n uint256 balance = IERC20(bridgeToken).balanceOf(address(this));\\n if (balance + amount > bridgeDetails.limit) {\\n // In case someone maliciously sends tokens to this contract\\n // Or the limit changes\\n if (bridgeDetails.limit > balance) amount = bridgeDetails.limit - balance;\\n else {\\n amount = 0;\\n }\\n }\\n\\n // Checking requirement on the hourly volume\\n uint256 hour = block.timestamp / 3600;\\n uint256 hourlyUsage = usage[bridgeToken][hour];\\n if (hourlyUsage + amount > bridgeDetails.hourlyLimit) {\\n // Edge case when the hourly limit changes\\n amount = bridgeDetails.hourlyLimit > hourlyUsage ? bridgeDetails.hourlyLimit - hourlyUsage : 0;\\n }\\n usage[bridgeToken][hour] = hourlyUsage + amount;\\n\\n IERC20(bridgeToken).safeTransferFrom(msg.sender, address(this), amount);\\n uint256 canonicalOut = amount;\\n // Computing fees\\n if (isFeeExempt[msg.sender] == 0) {\\n canonicalOut -= (canonicalOut * bridgeDetails.fee) / BASE_PARAMS;\\n }\\n _mint(to, canonicalOut);\\n return canonicalOut;\\n }\\n\\n /// @notice Burns the canonical token in exchange for a bridge token\\n /// @param bridgeToken Bridge token required\\n /// @param amount Amount of canonical tokens to burn\\n /// @param to Address to which the bridge token should be sent\\n /// @return Amount of bridge tokens actually sent back\\n /// @dev Some fees may be taken by the protocol depending on the token used and on the address calling\\n function swapOut(\\n address bridgeToken,\\n uint256 amount,\\n address to\\n ) external returns (uint256) {\\n BridgeDetails memory bridgeDetails = bridges[bridgeToken];\\n if (!bridgeDetails.allowed || bridgeDetails.paused) revert InvalidToken();\\n\\n uint256 hour = block.timestamp / 3600;\\n uint256 hourlyUsage = chainTotalUsage[hour] + amount;\\n // If the amount being swapped out exceeds the limit, we revert\\n // We don't want to change the amount being swapped out.\\n // The user can decide to send another tx with the correct amount to reach the limit\\n if (hourlyUsage > chainTotalHourlyLimit) revert HourlyLimitExceeded();\\n chainTotalUsage[hour] = hourlyUsage;\\n\\n _burn(msg.sender, amount);\\n uint256 bridgeOut = amount;\\n if (isFeeExempt[msg.sender] == 0) {\\n bridgeOut -= (bridgeOut * bridgeDetails.fee) / BASE_PARAMS;\\n }\\n IERC20(bridgeToken).safeTransfer(to, bridgeOut);\\n return bridgeOut;\\n }\\n\\n // ======================= Governance Functions ================================\\n\\n /// @notice Adds support for a bridge token\\n /// @param bridgeToken Bridge token to add: it should be a version of the stablecoin from another bridge\\n /// @param limit Limit on the balance of bridge token this contract could hold\\n /// @param hourlyLimit Limit on the hourly volume for this bridge\\n /// @param paused Whether swapping for this token should be paused or not\\n /// @param fee Fee taken upon swapping for or against this token\\n function addBridgeToken(\\n address bridgeToken,\\n uint256 limit,\\n uint256 hourlyLimit,\\n uint64 fee,\\n bool paused\\n ) external onlyGovernor {\\n if (bridges[bridgeToken].allowed || bridgeToken == address(0)) revert InvalidToken();\\n if (fee > BASE_PARAMS) revert TooHighParameterValue();\\n BridgeDetails memory _bridge;\\n _bridge.limit = limit;\\n _bridge.hourlyLimit = hourlyLimit;\\n _bridge.paused = paused;\\n _bridge.fee = fee;\\n _bridge.allowed = true;\\n bridges[bridgeToken] = _bridge;\\n bridgeTokensList.push(bridgeToken);\\n emit BridgeTokenAdded(bridgeToken, limit, hourlyLimit, fee, paused);\\n }\\n\\n /// @notice Removes support for a token\\n /// @param bridgeToken Address of the bridge token to remove support for\\n function removeBridgeToken(address bridgeToken) external onlyGovernor {\\n if (IERC20(bridgeToken).balanceOf(address(this)) != 0) revert AssetStillControlledInReserves();\\n delete bridges[bridgeToken];\\n // Deletion from `bridgeTokensList` loop\\n uint256 bridgeTokensListLength = bridgeTokensList.length;\\n for (uint256 i; i < bridgeTokensListLength - 1; ++i) {\\n if (bridgeTokensList[i] == bridgeToken) {\\n // Replace the `bridgeToken` to remove with the last of the list\\n bridgeTokensList[i] = bridgeTokensList[bridgeTokensListLength - 1];\\n break;\\n }\\n }\\n // Remove last element in array\\n bridgeTokensList.pop();\\n emit BridgeTokenRemoved(bridgeToken);\\n }\\n\\n /// @notice Recovers any ERC20 token\\n /// @dev Can be used to withdraw bridge tokens for them to be de-bridged on mainnet\\n function recoverERC20(\\n address tokenAddress,\\n address to,\\n uint256 amountToRecover\\n ) external onlyGovernor {\\n IERC20(tokenAddress).safeTransfer(to, amountToRecover);\\n emit Recovered(tokenAddress, to, amountToRecover);\\n }\\n\\n /// @notice Updates the `limit` amount for `bridgeToken`\\n function setLimit(address bridgeToken, uint256 limit) external onlyGovernorOrGuardian {\\n if (!bridges[bridgeToken].allowed) revert InvalidToken();\\n bridges[bridgeToken].limit = limit;\\n emit BridgeTokenLimitUpdated(bridgeToken, limit);\\n }\\n\\n /// @notice Updates the `hourlyLimit` amount for `bridgeToken`\\n function setHourlyLimit(address bridgeToken, uint256 hourlyLimit) external onlyGovernorOrGuardian {\\n if (!bridges[bridgeToken].allowed) revert InvalidToken();\\n bridges[bridgeToken].hourlyLimit = hourlyLimit;\\n emit BridgeTokenHourlyLimitUpdated(bridgeToken, hourlyLimit);\\n }\\n\\n /// @notice Updates the `chainTotalHourlyLimit` amount\\n function setChainTotalHourlyLimit(uint256 hourlyLimit) external onlyGovernorOrGuardian {\\n chainTotalHourlyLimit = hourlyLimit;\\n emit HourlyLimitUpdated(hourlyLimit);\\n }\\n\\n /// @notice Updates the `fee` value for `bridgeToken`\\n function setSwapFee(address bridgeToken, uint64 fee) external onlyGovernorOrGuardian {\\n if (!bridges[bridgeToken].allowed) revert InvalidToken();\\n if (fee > BASE_PARAMS) revert TooHighParameterValue();\\n bridges[bridgeToken].fee = fee;\\n emit BridgeTokenFeeUpdated(bridgeToken, fee);\\n }\\n\\n /// @notice Pauses or unpauses swapping in and out for a token\\n function toggleBridge(address bridgeToken) external onlyGovernorOrGuardian {\\n if (!bridges[bridgeToken].allowed) revert InvalidToken();\\n bool pausedStatus = bridges[bridgeToken].paused;\\n bridges[bridgeToken].paused = !pausedStatus;\\n emit BridgeTokenToggled(bridgeToken, !pausedStatus);\\n }\\n\\n /// @notice Toggles fees for the address `theAddress`\\n function toggleFeesForAddress(address theAddress) external onlyGovernorOrGuardian {\\n uint256 feeExemptStatus = 1 - isFeeExempt[theAddress];\\n isFeeExempt[theAddress] = feeExemptStatus;\\n emit FeeToggled(theAddress, feeExemptStatus);\\n }\\n}\\n\",\"keccak256\":\"0x03d7733482f57983ff12e1ea50ad9f7ba089f747e566c11d27ee199c59ff229c\",\"license\":\"GPL-3.0\"},\"contracts/agToken/BaseAgTokenSideChain.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-3.0\\n\\npragma solidity ^0.8.12;\\n\\n/*\\n * \\u2588 \\n ***** \\u2593\\u2593\\u2593 \\n * \\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593 \\n * ///. \\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593 \\n ***** //////// \\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593 \\n * ///////////// \\u2593\\u2593\\u2593 \\n \\u2593\\u2593 ////////////////// \\u2588 \\u2593\\u2593 \\n \\u2593\\u2593 \\u2593\\u2593 /////////////////////// \\u2593\\u2593 \\u2593\\u2593 \\n \\u2593\\u2593 \\u2593\\u2593 //////////////////////////// \\u2593\\u2593 \\u2593\\u2593 \\n \\u2593\\u2593 \\u2593\\u2593 /////////\\u2593\\u2593\\u2593///////\\u2593\\u2593\\u2593///////// \\u2593\\u2593 \\u2593\\u2593 \\n \\u2593\\u2593 ,////////////////////////////////////// \\u2593\\u2593 \\u2593\\u2593 \\n \\u2593\\u2593 ////////////////////////////////////////// \\u2593\\u2593 \\n \\u2593\\u2593 //////////////////////\\u2593\\u2593\\u2593\\u2593///////////////////// \\n ,//////////////////////////////////////////////////// \\n .////////////////////////////////////////////////////////// \\n .//////////////////////////\\u2588\\u2588.,//////////////////////////\\u2588 \\n .//////////////////////\\u2588\\u2588\\u2588\\u2588..,./////////////////////\\u2588\\u2588 \\n ...////////////////\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588.....,.////////////////\\u2588\\u2588\\u2588 \\n ,.,////////////\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588 ........,///////////\\u2588\\u2588\\u2588\\u2588 \\n .,.,//////\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588 ,.......///////\\u2588\\u2588\\u2588\\u2588 \\n ,..//\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588 ........./\\u2588\\u2588\\u2588\\u2588 \\n ..,\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588 .....,\\u2588\\u2588\\u2588 \\n .\\u2588\\u2588 ,.,\\u2588 \\n \\n \\n \\n \\u2593\\u2593 \\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593 \\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593 \\u2593\\u2593 \\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593 \\n \\u2593\\u2593\\u2593\\u2593\\u2593\\u2593 \\u2593\\u2593\\u2593 \\u2593\\u2593\\u2593 \\u2593\\u2593\\u2593 \\u2593\\u2593 \\u2593\\u2593 \\u2593\\u2593\\u2593\\u2593 \\n \\u2593\\u2593\\u2593 \\u2593\\u2593\\u2593 \\u2593\\u2593\\u2593 \\u2593\\u2593\\u2593 \\u2593\\u2593\\u2593 \\u2593\\u2593\\u2593 \\u2593\\u2593 \\u2593\\u2593\\u2593\\u2593\\u2593 \\n \\u2593\\u2593\\u2593 \\u2593\\u2593 \\u2593\\u2593\\u2593 \\u2593\\u2593\\u2593 \\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593 \\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593 \\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593 \\n*/\\n\\nimport \\\"../interfaces/IAgToken.sol\\\";\\nimport \\\"../interfaces/ITreasury.sol\\\";\\nimport \\\"@openzeppelin/contracts-upgradeable/token/ERC20/extensions/draft-ERC20PermitUpgradeable.sol\\\";\\n\\n/// @title BaseAgTokenSideChain\\n/// @author Angle Labs, Inc.\\n/// @notice Base contract for Angle agTokens on Ethereum and on other chains\\n/// @dev By default, agTokens are ERC-20 tokens with 18 decimals\\ncontract BaseAgTokenSideChain is IAgToken, ERC20PermitUpgradeable {\\n // =========================== PARAMETERS / VARIABLES ==========================\\n\\n /// @inheritdoc IAgToken\\n mapping(address => bool) public isMinter;\\n /// @notice Reference to the treasury contract which can grant minting rights\\n address public treasury;\\n\\n // =================================== EVENTS ==================================\\n\\n event TreasuryUpdated(address indexed _treasury);\\n event MinterToggled(address indexed minter);\\n\\n // =================================== ERRORS ==================================\\n\\n error BurnAmountExceedsAllowance();\\n error InvalidSender();\\n error InvalidTreasury();\\n error NotMinter();\\n error NotTreasury();\\n\\n // ================================ CONSTRUCTOR ================================\\n\\n /// @notice Wraps `_initializeBase` for `BaseAgTokenSideChain` and makes a safety check\\n /// on `_treasury`\\n function _initialize(string memory name_, string memory symbol_, address _treasury) internal virtual initializer {\\n if (address(ITreasury(_treasury).stablecoin()) != address(this)) revert InvalidTreasury();\\n _initializeBase(name_, symbol_, _treasury);\\n }\\n\\n /// @custom:oz-upgrades-unsafe-allow constructor\\n constructor() initializer {}\\n\\n /// @notice Initializes the contract\\n /// @param name_ Name of the token\\n /// @param symbol_ Symbol of the token\\n /// @param _treasury Reference to the `Treasury` contract associated to this agToken implementation\\n function _initializeBase(string memory name_, string memory symbol_, address _treasury) internal virtual {\\n __ERC20Permit_init(name_);\\n __ERC20_init(name_, symbol_);\\n treasury = _treasury;\\n emit TreasuryUpdated(address(_treasury));\\n }\\n\\n // ================================= MODIFIERS =================================\\n\\n /// @notice Checks to see if it is the `Treasury` calling this contract\\n /// @dev There is no Access Control here, because it can be handled cheaply through this modifier\\n modifier onlyTreasury() {\\n if (msg.sender != address(treasury)) revert NotTreasury();\\n _;\\n }\\n\\n /// @notice Checks whether the sender has the minting right\\n modifier onlyMinter() {\\n if (!isMinter[msg.sender]) revert NotMinter();\\n _;\\n }\\n\\n // ============================= EXTERNAL FUNCTION =============================\\n\\n /// @notice Allows anyone to burn agToken without redeeming collateral back\\n /// @param amount Amount of stablecoins to burn\\n /// @dev This function can typically be called if there is a settlement mechanism to burn stablecoins\\n function burnStablecoin(uint256 amount) external {\\n _burn(msg.sender, amount);\\n }\\n\\n // ========================= MINTER ROLE ONLY FUNCTIONS ========================\\n\\n /// @inheritdoc IAgToken\\n function burnSelf(uint256 amount, address burner) external onlyMinter {\\n _burn(burner, amount);\\n }\\n\\n /// @inheritdoc IAgToken\\n function burnFrom(uint256 amount, address burner, address sender) external onlyMinter {\\n _burnFromNoRedeem(amount, burner, sender);\\n }\\n\\n /// @inheritdoc IAgToken\\n function mint(address account, uint256 amount) external onlyMinter {\\n _mint(account, amount);\\n }\\n\\n // ========================== TREASURY ONLY FUNCTIONS ==========================\\n\\n /// @inheritdoc IAgToken\\n function addMinter(address minter) external onlyTreasury {\\n isMinter[minter] = true;\\n emit MinterToggled(minter);\\n }\\n\\n /// @inheritdoc IAgToken\\n function removeMinter(address minter) external {\\n if (msg.sender != address(treasury) && msg.sender != minter) revert InvalidSender();\\n isMinter[minter] = false;\\n emit MinterToggled(minter);\\n }\\n\\n /// @inheritdoc IAgToken\\n function setTreasury(address _treasury) external virtual onlyTreasury {\\n treasury = _treasury;\\n emit TreasuryUpdated(_treasury);\\n }\\n\\n // ============================= INTERNAL FUNCTION =============================\\n\\n /// @notice Internal version of the function `burnFromNoRedeem`\\n /// @param amount Amount to burn\\n /// @dev It is at the level of this function that allowance checks are performed\\n function _burnFromNoRedeem(uint256 amount, address burner, address sender) internal {\\n if (burner != sender) {\\n uint256 currentAllowance = allowance(burner, sender);\\n if (currentAllowance < amount) revert BurnAmountExceedsAllowance();\\n _approve(burner, sender, currentAllowance - amount);\\n }\\n _burn(burner, amount);\\n }\\n}\\n\",\"keccak256\":\"0x3a120df43d66baf21914de14312a36c51fb22d7d10b7ef704ff0ec847c128943\",\"license\":\"GPL-3.0\"},\"contracts/interfaces/IAgToken.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-3.0\\n\\npragma solidity ^0.8.12;\\n\\nimport \\\"@openzeppelin/contracts-upgradeable/token/ERC20/IERC20Upgradeable.sol\\\";\\n\\n/// @title IAgToken\\n/// @author Angle Labs, Inc.\\n/// @notice Interface for the stablecoins `AgToken` contracts\\n/// @dev This interface only contains functions of the `AgToken` contract which are called by other contracts\\n/// of this module or of the first module of the Angle Protocol\\ninterface IAgToken is IERC20Upgradeable {\\n // ======================= Minter Role Only Functions ===========================\\n\\n /// @notice Lets the `StableMaster` contract or another whitelisted contract mint agTokens\\n /// @param account Address to mint to\\n /// @param amount Amount to mint\\n /// @dev The contracts allowed to issue agTokens are the `StableMaster` contract, `VaultManager` contracts\\n /// associated to this stablecoin as well as the flash loan module (if activated) and potentially contracts\\n /// whitelisted by governance\\n function mint(address account, uint256 amount) external;\\n\\n /// @notice Burns `amount` tokens from a `burner` address after being asked to by `sender`\\n /// @param amount Amount of tokens to burn\\n /// @param burner Address to burn from\\n /// @param sender Address which requested the burn from `burner`\\n /// @dev This method is to be called by a contract with the minter right after being requested\\n /// to do so by a `sender` address willing to burn tokens from another `burner` address\\n /// @dev The method checks the allowance between the `sender` and the `burner`\\n function burnFrom(\\n uint256 amount,\\n address burner,\\n address sender\\n ) external;\\n\\n /// @notice Burns `amount` tokens from a `burner` address\\n /// @param amount Amount of tokens to burn\\n /// @param burner Address to burn from\\n /// @dev This method is to be called by a contract with a minter right on the AgToken after being\\n /// requested to do so by an address willing to burn tokens from its address\\n function burnSelf(uint256 amount, address burner) external;\\n\\n // ========================= Treasury Only Functions ===========================\\n\\n /// @notice Adds a minter in the contract\\n /// @param minter Minter address to add\\n /// @dev Zero address checks are performed directly in the `Treasury` contract\\n function addMinter(address minter) external;\\n\\n /// @notice Removes a minter from the contract\\n /// @param minter Minter address to remove\\n /// @dev This function can also be called by a minter wishing to revoke itself\\n function removeMinter(address minter) external;\\n\\n /// @notice Sets a new treasury contract\\n /// @param _treasury New treasury address\\n function setTreasury(address _treasury) external;\\n\\n // ========================= External functions ================================\\n\\n /// @notice Checks whether an address has the right to mint agTokens\\n /// @param minter Address for which the minting right should be checked\\n /// @return Whether the address has the right to mint agTokens or not\\n function isMinter(address minter) external view returns (bool);\\n\\n /// @notice Get the associated treasury\\n function treasury() external view returns (address);\\n}\\n\",\"keccak256\":\"0xd671dbd00b28a86b839fd455ada4d1ef9203694d06142be76853e00a91f80b5f\",\"license\":\"GPL-3.0\"},\"contracts/interfaces/ICoreBorrow.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-3.0\\n\\npragma solidity ^0.8.12;\\n\\n/// @title ICoreBorrow\\n/// @author Angle Labs, Inc.\\n/// @notice Interface for the `CoreBorrow` contract\\n/// @dev This interface only contains functions of the `CoreBorrow` contract which are called by other contracts\\n/// of this module\\ninterface ICoreBorrow {\\n /// @notice Checks if an address corresponds to a treasury of a stablecoin with a flash loan\\n /// module initialized on it\\n /// @param treasury Address to check\\n /// @return Whether the address has the `FLASHLOANER_TREASURY_ROLE` or not\\n function isFlashLoanerTreasury(address treasury) external view returns (bool);\\n\\n /// @notice Checks whether an address is governor of the Angle Protocol or not\\n /// @param admin Address to check\\n /// @return Whether the address has the `GOVERNOR_ROLE` or not\\n function isGovernor(address admin) external view returns (bool);\\n\\n /// @notice Checks whether an address is governor or a guardian of the Angle Protocol or not\\n /// @param admin Address to check\\n /// @return Whether the address has the `GUARDIAN_ROLE` or not\\n /// @dev Governance should make sure when adding a governor to also give this governor the guardian\\n /// role by calling the `addGovernor` function\\n function isGovernorOrGuardian(address admin) external view returns (bool);\\n}\\n\",\"keccak256\":\"0x10249210cbf522775f040baf981d7d037472168ce2746d87473ac7c29a34e62e\",\"license\":\"GPL-3.0\"},\"contracts/interfaces/IFlashAngle.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-3.0\\n\\npragma solidity ^0.8.12;\\n\\nimport \\\"./IAgToken.sol\\\";\\nimport \\\"./ICoreBorrow.sol\\\";\\n\\n/// @title IFlashAngle\\n/// @author Angle Labs, Inc.\\n/// @notice Interface for the `FlashAngle` contract\\n/// @dev This interface only contains functions of the contract which are called by other contracts\\n/// of this module\\ninterface IFlashAngle {\\n /// @notice Reference to the `CoreBorrow` contract managing the FlashLoan module\\n function core() external view returns (ICoreBorrow);\\n\\n /// @notice Sends the fees taken from flash loans to the treasury contract associated to the stablecoin\\n /// @param stablecoin Stablecoin from which profits should be sent\\n /// @return balance Amount of profits sent\\n /// @dev This function can only be called by the treasury contract\\n function accrueInterestToTreasury(IAgToken stablecoin) external returns (uint256 balance);\\n\\n /// @notice Adds support for a stablecoin\\n /// @param _treasury Treasury associated to the stablecoin to add support for\\n /// @dev This function can only be called by the `CoreBorrow` contract\\n function addStablecoinSupport(address _treasury) external;\\n\\n /// @notice Removes support for a stablecoin\\n /// @param _treasury Treasury associated to the stablecoin to remove support for\\n /// @dev This function can only be called by the `CoreBorrow` contract\\n function removeStablecoinSupport(address _treasury) external;\\n\\n /// @notice Sets a new core contract\\n /// @param _core Core contract address to set\\n /// @dev This function can only be called by the `CoreBorrow` contract\\n function setCore(address _core) external;\\n}\\n\",\"keccak256\":\"0x39b0097f695b9e934bccdc72676c91513f1077cc5d0fd151908fd25a7c5cfbe4\",\"license\":\"GPL-3.0\"},\"contracts/interfaces/ITreasury.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-3.0\\n\\npragma solidity ^0.8.12;\\n\\nimport \\\"./IAgToken.sol\\\";\\nimport \\\"./ICoreBorrow.sol\\\";\\nimport \\\"./IFlashAngle.sol\\\";\\n\\n/// @title ITreasury\\n/// @author Angle Labs, Inc.\\n/// @notice Interface for the `Treasury` contract\\n/// @dev This interface only contains functions of the `Treasury` which are called by other contracts\\n/// of this module\\ninterface ITreasury {\\n /// @notice Stablecoin handled by this `treasury` contract\\n function stablecoin() external view returns (IAgToken);\\n\\n /// @notice Checks whether a given address has the governor role\\n /// @param admin Address to check\\n /// @return Whether the address has the governor role\\n /// @dev Access control is only kept in the `CoreBorrow` contract\\n function isGovernor(address admin) external view returns (bool);\\n\\n /// @notice Checks whether a given address has the guardian or the governor role\\n /// @param admin Address to check\\n /// @return Whether the address has the guardian or the governor role\\n /// @dev Access control is only kept in the `CoreBorrow` contract which means that this function\\n /// queries the `CoreBorrow` contract\\n function isGovernorOrGuardian(address admin) external view returns (bool);\\n\\n /// @notice Checks whether a given address has well been initialized in this contract\\n /// as a `VaultManager`\\n /// @param _vaultManager Address to check\\n /// @return Whether the address has been initialized or not\\n function isVaultManager(address _vaultManager) external view returns (bool);\\n\\n /// @notice Sets a new flash loan module for this stablecoin\\n /// @param _flashLoanModule Reference to the new flash loan module\\n /// @dev This function removes the minting right to the old flash loan module and grants\\n /// it to the new module\\n function setFlashLoanModule(address _flashLoanModule) external;\\n}\\n\",\"keccak256\":\"0x624733dae1bfb98721ba994573aed10997f7448c893b791ed985300531c361fd\",\"license\":\"GPL-3.0\"}},\"version\":1}", - "bytecode": "0x60806040523480156200001157600080fd5b50600054610100900460ff1615808015620000335750600054600160ff909116105b8062000063575062000050306200013d60201b6200268a1760201c565b15801562000063575060005460ff166001145b620000cb5760405162461bcd60e51b815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201526d191e481a5b9a5d1a585b1a5e995960921b606482015260840160405180910390fd5b6000805460ff191660011790558015620000ef576000805461ff0019166101001790555b801562000136576000805461ff0019169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15b506200014c565b6001600160a01b03163b151590565b6146eb806200015c6000396000f3fe608060405234801561001057600080fd5b50600436106102ff5760003560e01c806361d027b31161019c5780639f48118f116100ee578063ced67f0c11610097578063dd62ed3e11610071578063dd62ed3e14610724578063e3e286551461076a578063f0f442601461077d57600080fd5b8063ced67f0c1461066b578063d44ad63f146106fe578063d505accf1461071157600080fd5b8063aa271e1a116100c8578063aa271e1a14610620578063ba330bd714610643578063cd4839ca1461065657600080fd5b80639f48118f146105ef578063a457c2d7146105fa578063a9059cbb1461060d57600080fd5b80637ecebe001161015057806395d89b411161012a57806395d89b41146105c1578063983b2d56146105c95780639e4e0dae146105dc57600080fd5b80637ecebe00146105705780638933fb791461058357806390218cff146105ae57600080fd5b80637334d020116101815780637334d020146105425780637d4c9c2d146105555780637d74e25f1461056857600080fd5b806361d027b3146104c757806370a082311461050c57600080fd5b80633092afd511610255578063395093511161020957806340c10f19116101e357806340c10f19146104815780634dc32fcc146104945780635bfbec96146104a757600080fd5b8063395093511461043b5780633a55f89d1461044e5780633f4218e01461046157600080fd5b8063350ebe041161023a578063350ebe041461040d5780633644e5151461042057806336db43b51461042857600080fd5b80633092afd5146103eb578063313ce567146103fe57600080fd5b8063151dd755116102b757806323b872dd1161029157806323b872dd146103b25780632b471d8e146103c55780632e403e14146103d857600080fd5b8063151dd7551461038057806318160ddd146103a15780632342fb0e146103a957600080fd5b80630919a951116102e85780630919a95114610337578063095ea7b31461034a5780631171bda91461036d57600080fd5b806306fdde0314610304578063077f224a14610322575b600080fd5b61030c610790565b6040516103199190613e63565b60405180910390f35b610335610330366004613fb0565b610822565b005b610335610345366004614028565b610832565b61035d610358366004614045565b610995565b6040519015158152602001610319565b61033561037b366004614071565b6109af565b61039361038e3660046140b2565b610b04565b604051908152602001610319565b603554610393565b61039360d25481565b61035d6103c0366004614071565b610dbe565b6103356103d33660046140e9565b610de2565b6103356103e6366004614028565b610e39565b6103356103f9366004614028565b6111e8565b60405160128152602001610319565b61033561041b366004614119565b6112d1565b610393611325565b610335610436366004614045565b611334565b61035d610449366004614045565b6114c4565b61033561045c366004614150565b611510565b61039361046f366004614028565b60d16020526000908152604090205481565b61033561048f366004614045565b611613565b6103936104a2366004614028565b611666565b6103936104b5366004614150565b60d36020526000908152604090205481565b60cd546104e79073ffffffffffffffffffffffffffffffffffffffff1681565b60405173ffffffffffffffffffffffffffffffffffffffff9091168152602001610319565b61039361051a366004614028565b73ffffffffffffffffffffffffffffffffffffffff1660009081526033602052604090205490565b610335610550366004614045565b6116ae565b610335610563366004614194565b611841565b610393611ba9565b61039361057e366004614028565b611bce565b610393610591366004614045565b60d060209081526000928352604080842090915290825290205481565b6103356105bc366004614150565b611bf9565b61030c611c06565b6103356105d7366004614028565b611c15565b6103356105ea3660046141f1565b611cdd565b610393633b9aca0081565b61035d610608366004614045565b611ee9565b61035d61061b366004614045565b611fbf565b61035d61062e366004614028565b60cc6020526000908152604090205460ff1681565b6104e7610651366004614150565b611fcd565b61065e612004565b6040516103199190614226565b6106c5610679366004614028565b60ce6020526000908152604090208054600182015460029092015490919067ffffffffffffffff81169060ff680100000000000000008204811691690100000000000000000090041685565b60408051958652602086019490945267ffffffffffffffff9092169284019290925290151560608301521515608082015260a001610319565b61039361070c3660046140b2565b612072565b61033561071f366004614280565b612237565b6103936107323660046142f7565b73ffffffffffffffffffffffffffffffffffffffff918216600090815260346020908152604080832093909416825291909152205490565b610335610778366004614028565b6123f6565b61033561078b366004614028565b6125ca565b60606036805461079f90614325565b80601f01602080910402602001604051908101604052809291908181526020018280546107cb90614325565b80156108185780601f106107ed57610100808354040283529160200191610818565b820191906000526020600020905b8154815290600101906020018083116107fb57829003601f168201915b5050505050905090565b61082d8383836126a6565b505050565b60cd546040517f521d4de900000000000000000000000000000000000000000000000000000000815233600482015273ffffffffffffffffffffffffffffffffffffffff9091169063521d4de990602401602060405180830381865afa1580156108a0573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906108c49190614372565b6108fa576040517f99e120bc00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff8116600090815260d1602052604081205461092b9060016143be565b73ffffffffffffffffffffffffffffffffffffffff8316600081815260d160205260409081902083905551919250907f979ef83e7e7a87cb48064e296dd7e997870d50f43acf8d7ad221313526c8ca0f906109899084815260200190565b60405180910390a25050565b6000336109a3818585612911565b60019150505b92915050565b60cd546040517fe43581b800000000000000000000000000000000000000000000000000000000815233600482015273ffffffffffffffffffffffffffffffffffffffff9091169063e43581b890602401602060405180830381865afa158015610a1d573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610a419190614372565b610a77576040517fee3675d400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b610a9873ffffffffffffffffffffffffffffffffffffffff84168383612abc565b8173ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff167ffff3b3844276f57024e0b42afec1a37f75db36511e43819a4f2a63ab7862b64883604051610af791815260200190565b60405180910390a3505050565b73ffffffffffffffffffffffffffffffffffffffff8316600090815260ce60209081526040808320815160a081018352815481526001820154938101939093526002015467ffffffffffffffff81169183019190915260ff680100000000000000008204811615801560608501526901000000000000000000909204161515608083015280610b94575080608001515b15610bcb576040517fc1ab6dc100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015260009073ffffffffffffffffffffffffffffffffffffffff8716906370a0823190602401602060405180830381865afa158015610c38573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610c5c91906143d1565b8251909150610c6b86836143ea565b1115610c93578151811015610c8e578151610c879082906143be565b9450610c93565b600094505b6000610ca1610e10426143fd565b73ffffffffffffffffffffffffffffffffffffffff8816600090815260d0602090815260408083208484528252909120549085015191925090610ce488836143ea565b1115610d0f5780846020015111610cfc576000610d0c565b808460200151610d0c91906143be565b96505b610d1987826143ea565b73ffffffffffffffffffffffffffffffffffffffff8916600081815260d060209081526040808320878452909152902091909155610d599033308a612b90565b33600090815260d16020526040812054889103610da657633b9aca00856040015167ffffffffffffffff1682610d8f9190614438565b610d9991906143fd565b610da390826143be565b90505b610db08782612bee565b9450505050505b9392505050565b600033610dcc858285612d0e565b610dd7858585612ddf565b506001949350505050565b33600090815260cc602052604090205460ff16610e2b576040517ff8d2906c00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b610e358183613092565b5050565b60cd546040517fe43581b800000000000000000000000000000000000000000000000000000000815233600482015273ffffffffffffffffffffffffffffffffffffffff9091169063e43581b890602401602060405180830381865afa158015610ea7573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610ecb9190614372565b610f01576040517fee3675d400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015273ffffffffffffffffffffffffffffffffffffffff8216906370a0823190602401602060405180830381865afa158015610f6b573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610f8f91906143d1565b15610fc6576040517f2ef630ec00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff8116600090815260ce602052604081208181556001810182905560020180547fffffffffffffffffffffffffffffffffffffffffffff0000000000000000000016905560cf54905b61102e6001836143be565b811015611139578273ffffffffffffffffffffffffffffffffffffffff1660cf828154811061105f5761105f61444f565b60009182526020909120015473ffffffffffffffffffffffffffffffffffffffff16036111295760cf6110936001846143be565b815481106110a3576110a361444f565b60009182526020909120015460cf805473ffffffffffffffffffffffffffffffffffffffff90921691839081106110dc576110dc61444f565b9060005260206000200160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550611139565b6111328161447e565b9050611023565b5060cf80548061114b5761114b6144b6565b60008281526020812082017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff90810180547fffffffffffffffffffffffff000000000000000000000000000000000000000016905590910190915560405173ffffffffffffffffffffffffffffffffffffffff8416917f5c95b49c4d59d97a2f044167723f29c74b30f99702e3fd406c3830160aa9ccb891a25050565b60cd5473ffffffffffffffffffffffffffffffffffffffff16331480159061122657503373ffffffffffffffffffffffffffffffffffffffff821614155b1561125d576040517fddb5de5e00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff8116600081815260cc602052604080822080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00169055517f98c15241d6c02bc5ee0b780e11b3ea737a2defd9d04877edbe9f9497065bd02f9190a250565b33600090815260cc602052604090205460ff1661131a576040517ff8d2906c00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b61082d83838361327f565b600061132f61333a565b905090565b60cd546040517f521d4de900000000000000000000000000000000000000000000000000000000815233600482015273ffffffffffffffffffffffffffffffffffffffff9091169063521d4de990602401602060405180830381865afa1580156113a2573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906113c69190614372565b6113fc576040517f99e120bc00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff8216600090815260ce602052604090206002015468010000000000000000900460ff1661146a576040517fc1ab6dc100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff8216600081815260ce602052604090819020839055517fe7b113fba37131b6396680a0c55790a697ec975e198ff8cfd89dac90a6379e61906109899084815260200190565b33600081815260346020908152604080832073ffffffffffffffffffffffffffffffffffffffff871684529091528120549091906109a3908290869061150b9087906143ea565b612911565b60cd546040517f521d4de900000000000000000000000000000000000000000000000000000000815233600482015273ffffffffffffffffffffffffffffffffffffffff9091169063521d4de990602401602060405180830381865afa15801561157e573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906115a29190614372565b6115d8576040517f99e120bc00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60d28190556040518181527fc3b69829afe2345596a02c8b587d41f796ba0094481d899e1b2e07b7532a1e219060200160405180910390a150565b33600090815260cc602052604090205460ff1661165c576040517ff8d2906c00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b610e358282612bee565b73ffffffffffffffffffffffffffffffffffffffff8116600090815260d06020526040812081611698610e10426143fd565b8152602001908152602001600020549050919050565b60cd546040517f521d4de900000000000000000000000000000000000000000000000000000000815233600482015273ffffffffffffffffffffffffffffffffffffffff9091169063521d4de990602401602060405180830381865afa15801561171c573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906117409190614372565b611776576040517f99e120bc00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff8216600090815260ce602052604090206002015468010000000000000000900460ff166117e4576040517fc1ab6dc100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff8216600081815260ce602052604090819020600101839055517fe13ac9338b2ee623233f83c1b3ceab16490fa3e3737fac7f0970d0830a9f4871906109899084815260200190565b60cd546040517fe43581b800000000000000000000000000000000000000000000000000000000815233600482015273ffffffffffffffffffffffffffffffffffffffff9091169063e43581b890602401602060405180830381865afa1580156118af573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906118d39190614372565b611909576040517fee3675d400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff8516600090815260ce602052604090206002015468010000000000000000900460ff1680611960575073ffffffffffffffffffffffffffffffffffffffff8516155b15611997576040517fc1ab6dc100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b633b9aca008267ffffffffffffffff1611156119df576040517feca1d2c600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040805160a08101825260008082526020820181905291810182905260608101829052608081019190915284815260208082018581528315156080840190815267ffffffffffffffff808716604080870191825260016060880181815273ffffffffffffffffffffffffffffffffffffffff8e16600081815260ce9099528389208a5181559751888401559351600290970180549151965115156901000000000000000000027fffffffffffffffffffffffffffffffffffffffffffff00ffffffffffffffffff97151568010000000000000000027fffffffffffffffffffffffffffffffffffffffffffffff000000000000000000909316989096169790971717949094169290921790935560cf805492830181559093527facb8d954e2cfef495862221e91bd7523613cf8808827cb33edfe4904cc51bf290180547fffffffffffffffffffffffff0000000000000000000000000000000000000000168217905590517f53087ff85d80a7671594bd2e86b92af22e0b3c2c441c8033bba7399b7b5cbe2390611b99908890889088908890938452602084019290925267ffffffffffffffff1660408301521515606082015260800190565b60405180910390a2505050505050565b600060d381611bba610e10426143fd565b815260200190815260200160002054905090565b73ffffffffffffffffffffffffffffffffffffffff81166000908152609960205260408120546109a9565b611c033382613092565b50565b60606037805461079f90614325565b60cd5473ffffffffffffffffffffffffffffffffffffffff163314611c66576040517fb90cdbb100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff8116600081815260cc602052604080822080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00166001179055517f98c15241d6c02bc5ee0b780e11b3ea737a2defd9d04877edbe9f9497065bd02f9190a250565b60cd546040517f521d4de900000000000000000000000000000000000000000000000000000000815233600482015273ffffffffffffffffffffffffffffffffffffffff9091169063521d4de990602401602060405180830381865afa158015611d4b573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611d6f9190614372565b611da5576040517f99e120bc00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff8216600090815260ce602052604090206002015468010000000000000000900460ff16611e13576040517fc1ab6dc100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b633b9aca008167ffffffffffffffff161115611e5b576040517feca1d2c600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff8216600081815260ce602090815260409182902060020180547fffffffffffffffffffffffffffffffffffffffffffffffff00000000000000001667ffffffffffffffff861690811790915591519182527f901f9de19b475adc8da4110434b8df940dce085afd05e2281c86807f3a899d299101610989565b33600081815260346020908152604080832073ffffffffffffffffffffffffffffffffffffffff8716845290915281205490919083811015611fb2576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602560248201527f45524332303a2064656372656173656420616c6c6f77616e63652062656c6f7760448201527f207a65726f00000000000000000000000000000000000000000000000000000060648201526084015b60405180910390fd5b610dd78286868403612911565b6000336109a3818585612ddf565b60cf8181548110611fdd57600080fd5b60009182526020909120015473ffffffffffffffffffffffffffffffffffffffff16905081565b606060cf80548060200260200160405190810160405280929190818152602001828054801561081857602002820191906000526020600020905b815473ffffffffffffffffffffffffffffffffffffffff16815260019091019060200180831161203e575050505050905090565b73ffffffffffffffffffffffffffffffffffffffff8316600090815260ce60209081526040808320815160a081018352815481526001820154938101939093526002015467ffffffffffffffff81169183019190915260ff680100000000000000008204811615801560608501526901000000000000000000909204161515608083015280612102575080608001515b15612139576040517fc1ab6dc100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000612147610e10426143fd565b600081815260d36020526040812054919250906121659087906143ea565b905060d2548111156121a3576040517f6d43d1ac00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600082815260d3602052604090208190556121be3387613092565b33600090815260d1602052604081205487910361220b57633b9aca00846040015167ffffffffffffffff16826121f49190614438565b6121fe91906143fd565b61220890826143be565b90505b61222c73ffffffffffffffffffffffffffffffffffffffff89168783612abc565b979650505050505050565b834211156122a1576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f45524332305065726d69743a206578706972656420646561646c696e650000006044820152606401611fa9565b60007f6e71edae12b1b97f4d1f60370fef10105fa2faae0126114a169c64845d6126c98888886122d08c6133b5565b60408051602081019690965273ffffffffffffffffffffffffffffffffffffffff94851690860152929091166060840152608083015260a082015260c0810186905260e0016040516020818303038152906040528051906020012090506000612338826133ea565b9050600061234882878787613453565b90508973ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16146123df576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601e60248201527f45524332305065726d69743a20696e76616c6964207369676e617475726500006044820152606401611fa9565b6123ea8a8a8a612911565b50505050505050505050565b60cd546040517f521d4de900000000000000000000000000000000000000000000000000000000815233600482015273ffffffffffffffffffffffffffffffffffffffff9091169063521d4de990602401602060405180830381865afa158015612464573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906124889190614372565b6124be576040517f99e120bc00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff8116600090815260ce602052604090206002015468010000000000000000900460ff1661252c576040517fc1ab6dc100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff8116600081815260ce602090815260409182902060020180547fffffffffffffffffffffffffffffffffffffffffffff00ffffffffffffffffff811669010000000000000000009182900460ff16801592830291909117909255925192835292917ff7c93079dcbf699749d66345a351afab7d24219bb1d915c9f4fc4cf03f00d3979101610989565b60cd5473ffffffffffffffffffffffffffffffffffffffff16331461261b576040517fb90cdbb100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60cd80547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83169081179091556040517f7dae230f18360d76a040c81f050aa14eb9d6dc7901b20fc5d855e2a20fe814d190600090a250565b73ffffffffffffffffffffffffffffffffffffffff163b151590565b600054610100900460ff16158080156126c65750600054600160ff909116105b806126e05750303b1580156126e0575060005460ff166001145b61276c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201527f647920696e697469616c697a65640000000000000000000000000000000000006064820152608401611fa9565b600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0016600117905580156127ca57600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff166101001790555b3073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1663e9cbd8226040518163ffffffff1660e01b8152600401602060405180830381865afa15801561282c573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061285091906144e5565b73ffffffffffffffffffffffffffffffffffffffff161461289d576040517f14bcf5c800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6128a884848461347b565b801561290b57600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15b50505050565b73ffffffffffffffffffffffffffffffffffffffff83166129b3576040517f08c379a0000000000000000000000000000000000000000000000000000000008152602060048201526024808201527f45524332303a20617070726f76652066726f6d20746865207a65726f2061646460448201527f72657373000000000000000000000000000000000000000000000000000000006064820152608401611fa9565b73ffffffffffffffffffffffffffffffffffffffff8216612a56576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602260248201527f45524332303a20617070726f766520746f20746865207a65726f20616464726560448201527f73730000000000000000000000000000000000000000000000000000000000006064820152608401611fa9565b73ffffffffffffffffffffffffffffffffffffffff83811660008181526034602090815260408083209487168084529482529182902085905590518481527f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b9259101610af7565b60405173ffffffffffffffffffffffffffffffffffffffff831660248201526044810182905261082d9084907fa9059cbb00000000000000000000000000000000000000000000000000000000906064015b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff00000000000000000000000000000000000000000000000000000000909316929092179091526134ff565b60405173ffffffffffffffffffffffffffffffffffffffff8085166024830152831660448201526064810182905261290b9085907f23b872dd0000000000000000000000000000000000000000000000000000000090608401612b0e565b73ffffffffffffffffffffffffffffffffffffffff8216612c6b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601f60248201527f45524332303a206d696e7420746f20746865207a65726f2061646472657373006044820152606401611fa9565b8060356000828254612c7d91906143ea565b909155505073ffffffffffffffffffffffffffffffffffffffff821660009081526033602052604081208054839290612cb79084906143ea565b909155505060405181815273ffffffffffffffffffffffffffffffffffffffff8316906000907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef9060200160405180910390a35050565b73ffffffffffffffffffffffffffffffffffffffff8381166000908152603460209081526040808320938616835292905220547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff811461290b5781811015612dd2576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f45524332303a20696e73756666696369656e7420616c6c6f77616e63650000006044820152606401611fa9565b61290b8484848403612911565b73ffffffffffffffffffffffffffffffffffffffff8316612e82576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602560248201527f45524332303a207472616e736665722066726f6d20746865207a65726f20616460448201527f64726573730000000000000000000000000000000000000000000000000000006064820152608401611fa9565b73ffffffffffffffffffffffffffffffffffffffff8216612f25576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602360248201527f45524332303a207472616e7366657220746f20746865207a65726f206164647260448201527f65737300000000000000000000000000000000000000000000000000000000006064820152608401611fa9565b73ffffffffffffffffffffffffffffffffffffffff831660009081526033602052604090205481811015612fdb576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f45524332303a207472616e7366657220616d6f756e742065786365656473206260448201527f616c616e636500000000000000000000000000000000000000000000000000006064820152608401611fa9565b73ffffffffffffffffffffffffffffffffffffffff80851660009081526033602052604080822085850390559185168152908120805484929061301f9084906143ea565b925050819055508273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef8460405161308591815260200190565b60405180910390a361290b565b73ffffffffffffffffffffffffffffffffffffffff8216613135576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602160248201527f45524332303a206275726e2066726f6d20746865207a65726f2061646472657360448201527f73000000000000000000000000000000000000000000000000000000000000006064820152608401611fa9565b73ffffffffffffffffffffffffffffffffffffffff8216600090815260336020526040902054818110156131eb576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602260248201527f45524332303a206275726e20616d6f756e7420657863656564732062616c616e60448201527f63650000000000000000000000000000000000000000000000000000000000006064820152608401611fa9565b73ffffffffffffffffffffffffffffffffffffffff831660009081526033602052604081208383039055603580548492906132279084906143be565b909155505060405182815260009073ffffffffffffffffffffffffffffffffffffffff8516907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef9060200160405180910390a3505050565b8073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff16146133305773ffffffffffffffffffffffffffffffffffffffff8281166000908152603460209081526040808320938516835292905220548381101561331f576040517f715ec26c00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b61332e838361150b87856143be565b505b61082d8284613092565b600061132f7f8b73c3c69bb8fe3d512ecc4cf759cc79239f7b179b0ffacaa9a75d522b39400f61336960655490565b6066546040805160208101859052908101839052606081018290524660808201523060a082015260009060c0016040516020818303038152906040528051906020012090509392505050565b73ffffffffffffffffffffffffffffffffffffffff811660009081526099602052604090208054600181018255905b50919050565b60006109a96133f761333a565b836040517f19010000000000000000000000000000000000000000000000000000000000006020820152602281018390526042810182905260009060620160405160208183030381529060405280519060200120905092915050565b60008060006134648787878761360b565b9150915061347181613723565b5095945050505050565b61348483613977565b61348e8383613a4d565b60cd80547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83169081179091556040517f7dae230f18360d76a040c81f050aa14eb9d6dc7901b20fc5d855e2a20fe814d190600090a2505050565b6000613561826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c65648152508573ffffffffffffffffffffffffffffffffffffffff16613aee9092919063ffffffff16565b80519091501561082d578080602001905181019061357f9190614372565b61082d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e60448201527f6f742073756363656564000000000000000000000000000000000000000000006064820152608401611fa9565b6000807f7fffffffffffffffffffffffffffffff5d576e7357a4501ddfe92f46681b20a0831115613642575060009050600361371a565b8460ff16601b1415801561365a57508460ff16601c14155b1561366b575060009050600461371a565b6040805160008082526020820180845289905260ff881692820192909252606081018690526080810185905260019060a0016020604051602081039080840390855afa1580156136bf573d6000803e3d6000fd5b50506040517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0015191505073ffffffffffffffffffffffffffffffffffffffff81166137135760006001925092505061371a565b9150600090505b94509492505050565b600081600481111561373757613737614502565b0361373f5750565b600181600481111561375357613753614502565b036137ba576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601860248201527f45434453413a20696e76616c6964207369676e617475726500000000000000006044820152606401611fa9565b60028160048111156137ce576137ce614502565b03613835576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601f60248201527f45434453413a20696e76616c6964207369676e6174757265206c656e677468006044820152606401611fa9565b600381600481111561384957613849614502565b036138d6576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602260248201527f45434453413a20696e76616c6964207369676e6174757265202773272076616c60448201527f75650000000000000000000000000000000000000000000000000000000000006064820152608401611fa9565b60048160048111156138ea576138ea614502565b03611c03576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602260248201527f45434453413a20696e76616c6964207369676e6174757265202776272076616c60448201527f75650000000000000000000000000000000000000000000000000000000000006064820152608401611fa9565b600054610100900460ff16613a0e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201527f6e697469616c697a696e670000000000000000000000000000000000000000006064820152608401611fa9565b611c03816040518060400160405280600181526020017f3100000000000000000000000000000000000000000000000000000000000000815250613b05565b600054610100900460ff16613ae4576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201527f6e697469616c697a696e670000000000000000000000000000000000000000006064820152608401611fa9565b610e358282613bb6565b6060613afd8484600085613c66565b949350505050565b600054610100900460ff16613b9c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201527f6e697469616c697a696e670000000000000000000000000000000000000000006064820152608401611fa9565b815160209283012081519190920120606591909155606655565b600054610100900460ff16613c4d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201527f6e697469616c697a696e670000000000000000000000000000000000000000006064820152608401611fa9565b6036613c59838261457f565b50603761082d828261457f565b606082471015613cf8576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f60448201527f722063616c6c00000000000000000000000000000000000000000000000000006064820152608401611fa9565b73ffffffffffffffffffffffffffffffffffffffff85163b613d76576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006044820152606401611fa9565b6000808673ffffffffffffffffffffffffffffffffffffffff168587604051613d9f9190614699565b60006040518083038185875af1925050503d8060008114613ddc576040519150601f19603f3d011682016040523d82523d6000602084013e613de1565b606091505b509150915061222c82828660608315613dfb575081610db7565b825115613e0b5782518084602001fd5b816040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611fa99190613e63565b60005b83811015613e5a578181015183820152602001613e42565b50506000910152565b6020815260008251806020840152613e82816040850160208701613e3f565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169190910160400192915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b600082601f830112613ef457600080fd5b813567ffffffffffffffff80821115613f0f57613f0f613eb4565b604051601f83017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0908116603f01168101908282118183101715613f5557613f55613eb4565b81604052838152866020858801011115613f6e57600080fd5b836020870160208301376000602085830101528094505050505092915050565b73ffffffffffffffffffffffffffffffffffffffff81168114611c0357600080fd5b600080600060608486031215613fc557600080fd5b833567ffffffffffffffff80821115613fdd57600080fd5b613fe987838801613ee3565b94506020860135915080821115613fff57600080fd5b5061400c86828701613ee3565b925050604084013561401d81613f8e565b809150509250925092565b60006020828403121561403a57600080fd5b8135610db781613f8e565b6000806040838503121561405857600080fd5b823561406381613f8e565b946020939093013593505050565b60008060006060848603121561408657600080fd5b833561409181613f8e565b925060208401356140a181613f8e565b929592945050506040919091013590565b6000806000606084860312156140c757600080fd5b83356140d281613f8e565b925060208401359150604084013561401d81613f8e565b600080604083850312156140fc57600080fd5b82359150602083013561410e81613f8e565b809150509250929050565b60008060006060848603121561412e57600080fd5b83359250602084013561414081613f8e565b9150604084013561401d81613f8e565b60006020828403121561416257600080fd5b5035919050565b803567ffffffffffffffff8116811461418157600080fd5b919050565b8015158114611c0357600080fd5b600080600080600060a086880312156141ac57600080fd5b85356141b781613f8e565b945060208601359350604086013592506141d360608701614169565b915060808601356141e381614186565b809150509295509295909350565b6000806040838503121561420457600080fd5b823561420f81613f8e565b915061421d60208401614169565b90509250929050565b6020808252825182820181905260009190848201906040850190845b8181101561427457835173ffffffffffffffffffffffffffffffffffffffff1683529284019291840191600101614242565b50909695505050505050565b600080600080600080600060e0888a03121561429b57600080fd5b87356142a681613f8e565b965060208801356142b681613f8e565b95506040880135945060608801359350608088013560ff811681146142da57600080fd5b9699959850939692959460a0840135945060c09093013592915050565b6000806040838503121561430a57600080fd5b823561431581613f8e565b9150602083013561410e81613f8e565b600181811c9082168061433957607f821691505b6020821081036133e4577f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b60006020828403121561438457600080fd5b8151610db781614186565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b818103818111156109a9576109a961438f565b6000602082840312156143e357600080fd5b5051919050565b808201808211156109a9576109a961438f565b600082614433577f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b500490565b80820281158282048414176109a9576109a961438f565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82036144af576144af61438f565b5060010190565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603160045260246000fd5b6000602082840312156144f757600080fd5b8151610db781613f8e565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b601f82111561082d57600081815260208120601f850160051c810160208610156145585750805b601f850160051c820191505b8181101561457757828155600101614564565b505050505050565b815167ffffffffffffffff81111561459957614599613eb4565b6145ad816145a78454614325565b84614531565b602080601f83116001811461460057600084156145ca5750858301515b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600386901b1c1916600185901b178555614577565b6000858152602081207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08616915b8281101561464d5788860151825594840194600190910190840161462e565b508582101561468957878501517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600388901b60f8161c191681555b5050505050600190811b01905550565b600082516146ab818460208701613e3f565b919091019291505056fea26469706673582212204ab762f428941cadd300d875bf277cb0f7dff52a487fb7282a657f3da537ca0564736f6c63430008110033", - "deployedBytecode": "0x608060405234801561001057600080fd5b50600436106102ff5760003560e01c806361d027b31161019c5780639f48118f116100ee578063ced67f0c11610097578063dd62ed3e11610071578063dd62ed3e14610724578063e3e286551461076a578063f0f442601461077d57600080fd5b8063ced67f0c1461066b578063d44ad63f146106fe578063d505accf1461071157600080fd5b8063aa271e1a116100c8578063aa271e1a14610620578063ba330bd714610643578063cd4839ca1461065657600080fd5b80639f48118f146105ef578063a457c2d7146105fa578063a9059cbb1461060d57600080fd5b80637ecebe001161015057806395d89b411161012a57806395d89b41146105c1578063983b2d56146105c95780639e4e0dae146105dc57600080fd5b80637ecebe00146105705780638933fb791461058357806390218cff146105ae57600080fd5b80637334d020116101815780637334d020146105425780637d4c9c2d146105555780637d74e25f1461056857600080fd5b806361d027b3146104c757806370a082311461050c57600080fd5b80633092afd511610255578063395093511161020957806340c10f19116101e357806340c10f19146104815780634dc32fcc146104945780635bfbec96146104a757600080fd5b8063395093511461043b5780633a55f89d1461044e5780633f4218e01461046157600080fd5b8063350ebe041161023a578063350ebe041461040d5780633644e5151461042057806336db43b51461042857600080fd5b80633092afd5146103eb578063313ce567146103fe57600080fd5b8063151dd755116102b757806323b872dd1161029157806323b872dd146103b25780632b471d8e146103c55780632e403e14146103d857600080fd5b8063151dd7551461038057806318160ddd146103a15780632342fb0e146103a957600080fd5b80630919a951116102e85780630919a95114610337578063095ea7b31461034a5780631171bda91461036d57600080fd5b806306fdde0314610304578063077f224a14610322575b600080fd5b61030c610790565b6040516103199190613e63565b60405180910390f35b610335610330366004613fb0565b610822565b005b610335610345366004614028565b610832565b61035d610358366004614045565b610995565b6040519015158152602001610319565b61033561037b366004614071565b6109af565b61039361038e3660046140b2565b610b04565b604051908152602001610319565b603554610393565b61039360d25481565b61035d6103c0366004614071565b610dbe565b6103356103d33660046140e9565b610de2565b6103356103e6366004614028565b610e39565b6103356103f9366004614028565b6111e8565b60405160128152602001610319565b61033561041b366004614119565b6112d1565b610393611325565b610335610436366004614045565b611334565b61035d610449366004614045565b6114c4565b61033561045c366004614150565b611510565b61039361046f366004614028565b60d16020526000908152604090205481565b61033561048f366004614045565b611613565b6103936104a2366004614028565b611666565b6103936104b5366004614150565b60d36020526000908152604090205481565b60cd546104e79073ffffffffffffffffffffffffffffffffffffffff1681565b60405173ffffffffffffffffffffffffffffffffffffffff9091168152602001610319565b61039361051a366004614028565b73ffffffffffffffffffffffffffffffffffffffff1660009081526033602052604090205490565b610335610550366004614045565b6116ae565b610335610563366004614194565b611841565b610393611ba9565b61039361057e366004614028565b611bce565b610393610591366004614045565b60d060209081526000928352604080842090915290825290205481565b6103356105bc366004614150565b611bf9565b61030c611c06565b6103356105d7366004614028565b611c15565b6103356105ea3660046141f1565b611cdd565b610393633b9aca0081565b61035d610608366004614045565b611ee9565b61035d61061b366004614045565b611fbf565b61035d61062e366004614028565b60cc6020526000908152604090205460ff1681565b6104e7610651366004614150565b611fcd565b61065e612004565b6040516103199190614226565b6106c5610679366004614028565b60ce6020526000908152604090208054600182015460029092015490919067ffffffffffffffff81169060ff680100000000000000008204811691690100000000000000000090041685565b60408051958652602086019490945267ffffffffffffffff9092169284019290925290151560608301521515608082015260a001610319565b61039361070c3660046140b2565b612072565b61033561071f366004614280565b612237565b6103936107323660046142f7565b73ffffffffffffffffffffffffffffffffffffffff918216600090815260346020908152604080832093909416825291909152205490565b610335610778366004614028565b6123f6565b61033561078b366004614028565b6125ca565b60606036805461079f90614325565b80601f01602080910402602001604051908101604052809291908181526020018280546107cb90614325565b80156108185780601f106107ed57610100808354040283529160200191610818565b820191906000526020600020905b8154815290600101906020018083116107fb57829003601f168201915b5050505050905090565b61082d8383836126a6565b505050565b60cd546040517f521d4de900000000000000000000000000000000000000000000000000000000815233600482015273ffffffffffffffffffffffffffffffffffffffff9091169063521d4de990602401602060405180830381865afa1580156108a0573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906108c49190614372565b6108fa576040517f99e120bc00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff8116600090815260d1602052604081205461092b9060016143be565b73ffffffffffffffffffffffffffffffffffffffff8316600081815260d160205260409081902083905551919250907f979ef83e7e7a87cb48064e296dd7e997870d50f43acf8d7ad221313526c8ca0f906109899084815260200190565b60405180910390a25050565b6000336109a3818585612911565b60019150505b92915050565b60cd546040517fe43581b800000000000000000000000000000000000000000000000000000000815233600482015273ffffffffffffffffffffffffffffffffffffffff9091169063e43581b890602401602060405180830381865afa158015610a1d573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610a419190614372565b610a77576040517fee3675d400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b610a9873ffffffffffffffffffffffffffffffffffffffff84168383612abc565b8173ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff167ffff3b3844276f57024e0b42afec1a37f75db36511e43819a4f2a63ab7862b64883604051610af791815260200190565b60405180910390a3505050565b73ffffffffffffffffffffffffffffffffffffffff8316600090815260ce60209081526040808320815160a081018352815481526001820154938101939093526002015467ffffffffffffffff81169183019190915260ff680100000000000000008204811615801560608501526901000000000000000000909204161515608083015280610b94575080608001515b15610bcb576040517fc1ab6dc100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015260009073ffffffffffffffffffffffffffffffffffffffff8716906370a0823190602401602060405180830381865afa158015610c38573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610c5c91906143d1565b8251909150610c6b86836143ea565b1115610c93578151811015610c8e578151610c879082906143be565b9450610c93565b600094505b6000610ca1610e10426143fd565b73ffffffffffffffffffffffffffffffffffffffff8816600090815260d0602090815260408083208484528252909120549085015191925090610ce488836143ea565b1115610d0f5780846020015111610cfc576000610d0c565b808460200151610d0c91906143be565b96505b610d1987826143ea565b73ffffffffffffffffffffffffffffffffffffffff8916600081815260d060209081526040808320878452909152902091909155610d599033308a612b90565b33600090815260d16020526040812054889103610da657633b9aca00856040015167ffffffffffffffff1682610d8f9190614438565b610d9991906143fd565b610da390826143be565b90505b610db08782612bee565b9450505050505b9392505050565b600033610dcc858285612d0e565b610dd7858585612ddf565b506001949350505050565b33600090815260cc602052604090205460ff16610e2b576040517ff8d2906c00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b610e358183613092565b5050565b60cd546040517fe43581b800000000000000000000000000000000000000000000000000000000815233600482015273ffffffffffffffffffffffffffffffffffffffff9091169063e43581b890602401602060405180830381865afa158015610ea7573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610ecb9190614372565b610f01576040517fee3675d400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015273ffffffffffffffffffffffffffffffffffffffff8216906370a0823190602401602060405180830381865afa158015610f6b573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610f8f91906143d1565b15610fc6576040517f2ef630ec00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff8116600090815260ce602052604081208181556001810182905560020180547fffffffffffffffffffffffffffffffffffffffffffff0000000000000000000016905560cf54905b61102e6001836143be565b811015611139578273ffffffffffffffffffffffffffffffffffffffff1660cf828154811061105f5761105f61444f565b60009182526020909120015473ffffffffffffffffffffffffffffffffffffffff16036111295760cf6110936001846143be565b815481106110a3576110a361444f565b60009182526020909120015460cf805473ffffffffffffffffffffffffffffffffffffffff90921691839081106110dc576110dc61444f565b9060005260206000200160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550611139565b6111328161447e565b9050611023565b5060cf80548061114b5761114b6144b6565b60008281526020812082017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff90810180547fffffffffffffffffffffffff000000000000000000000000000000000000000016905590910190915560405173ffffffffffffffffffffffffffffffffffffffff8416917f5c95b49c4d59d97a2f044167723f29c74b30f99702e3fd406c3830160aa9ccb891a25050565b60cd5473ffffffffffffffffffffffffffffffffffffffff16331480159061122657503373ffffffffffffffffffffffffffffffffffffffff821614155b1561125d576040517fddb5de5e00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff8116600081815260cc602052604080822080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00169055517f98c15241d6c02bc5ee0b780e11b3ea737a2defd9d04877edbe9f9497065bd02f9190a250565b33600090815260cc602052604090205460ff1661131a576040517ff8d2906c00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b61082d83838361327f565b600061132f61333a565b905090565b60cd546040517f521d4de900000000000000000000000000000000000000000000000000000000815233600482015273ffffffffffffffffffffffffffffffffffffffff9091169063521d4de990602401602060405180830381865afa1580156113a2573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906113c69190614372565b6113fc576040517f99e120bc00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff8216600090815260ce602052604090206002015468010000000000000000900460ff1661146a576040517fc1ab6dc100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff8216600081815260ce602052604090819020839055517fe7b113fba37131b6396680a0c55790a697ec975e198ff8cfd89dac90a6379e61906109899084815260200190565b33600081815260346020908152604080832073ffffffffffffffffffffffffffffffffffffffff871684529091528120549091906109a3908290869061150b9087906143ea565b612911565b60cd546040517f521d4de900000000000000000000000000000000000000000000000000000000815233600482015273ffffffffffffffffffffffffffffffffffffffff9091169063521d4de990602401602060405180830381865afa15801561157e573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906115a29190614372565b6115d8576040517f99e120bc00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60d28190556040518181527fc3b69829afe2345596a02c8b587d41f796ba0094481d899e1b2e07b7532a1e219060200160405180910390a150565b33600090815260cc602052604090205460ff1661165c576040517ff8d2906c00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b610e358282612bee565b73ffffffffffffffffffffffffffffffffffffffff8116600090815260d06020526040812081611698610e10426143fd565b8152602001908152602001600020549050919050565b60cd546040517f521d4de900000000000000000000000000000000000000000000000000000000815233600482015273ffffffffffffffffffffffffffffffffffffffff9091169063521d4de990602401602060405180830381865afa15801561171c573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906117409190614372565b611776576040517f99e120bc00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff8216600090815260ce602052604090206002015468010000000000000000900460ff166117e4576040517fc1ab6dc100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff8216600081815260ce602052604090819020600101839055517fe13ac9338b2ee623233f83c1b3ceab16490fa3e3737fac7f0970d0830a9f4871906109899084815260200190565b60cd546040517fe43581b800000000000000000000000000000000000000000000000000000000815233600482015273ffffffffffffffffffffffffffffffffffffffff9091169063e43581b890602401602060405180830381865afa1580156118af573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906118d39190614372565b611909576040517fee3675d400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff8516600090815260ce602052604090206002015468010000000000000000900460ff1680611960575073ffffffffffffffffffffffffffffffffffffffff8516155b15611997576040517fc1ab6dc100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b633b9aca008267ffffffffffffffff1611156119df576040517feca1d2c600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040805160a08101825260008082526020820181905291810182905260608101829052608081019190915284815260208082018581528315156080840190815267ffffffffffffffff808716604080870191825260016060880181815273ffffffffffffffffffffffffffffffffffffffff8e16600081815260ce9099528389208a5181559751888401559351600290970180549151965115156901000000000000000000027fffffffffffffffffffffffffffffffffffffffffffff00ffffffffffffffffff97151568010000000000000000027fffffffffffffffffffffffffffffffffffffffffffffff000000000000000000909316989096169790971717949094169290921790935560cf805492830181559093527facb8d954e2cfef495862221e91bd7523613cf8808827cb33edfe4904cc51bf290180547fffffffffffffffffffffffff0000000000000000000000000000000000000000168217905590517f53087ff85d80a7671594bd2e86b92af22e0b3c2c441c8033bba7399b7b5cbe2390611b99908890889088908890938452602084019290925267ffffffffffffffff1660408301521515606082015260800190565b60405180910390a2505050505050565b600060d381611bba610e10426143fd565b815260200190815260200160002054905090565b73ffffffffffffffffffffffffffffffffffffffff81166000908152609960205260408120546109a9565b611c033382613092565b50565b60606037805461079f90614325565b60cd5473ffffffffffffffffffffffffffffffffffffffff163314611c66576040517fb90cdbb100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff8116600081815260cc602052604080822080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00166001179055517f98c15241d6c02bc5ee0b780e11b3ea737a2defd9d04877edbe9f9497065bd02f9190a250565b60cd546040517f521d4de900000000000000000000000000000000000000000000000000000000815233600482015273ffffffffffffffffffffffffffffffffffffffff9091169063521d4de990602401602060405180830381865afa158015611d4b573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611d6f9190614372565b611da5576040517f99e120bc00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff8216600090815260ce602052604090206002015468010000000000000000900460ff16611e13576040517fc1ab6dc100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b633b9aca008167ffffffffffffffff161115611e5b576040517feca1d2c600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff8216600081815260ce602090815260409182902060020180547fffffffffffffffffffffffffffffffffffffffffffffffff00000000000000001667ffffffffffffffff861690811790915591519182527f901f9de19b475adc8da4110434b8df940dce085afd05e2281c86807f3a899d299101610989565b33600081815260346020908152604080832073ffffffffffffffffffffffffffffffffffffffff8716845290915281205490919083811015611fb2576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602560248201527f45524332303a2064656372656173656420616c6c6f77616e63652062656c6f7760448201527f207a65726f00000000000000000000000000000000000000000000000000000060648201526084015b60405180910390fd5b610dd78286868403612911565b6000336109a3818585612ddf565b60cf8181548110611fdd57600080fd5b60009182526020909120015473ffffffffffffffffffffffffffffffffffffffff16905081565b606060cf80548060200260200160405190810160405280929190818152602001828054801561081857602002820191906000526020600020905b815473ffffffffffffffffffffffffffffffffffffffff16815260019091019060200180831161203e575050505050905090565b73ffffffffffffffffffffffffffffffffffffffff8316600090815260ce60209081526040808320815160a081018352815481526001820154938101939093526002015467ffffffffffffffff81169183019190915260ff680100000000000000008204811615801560608501526901000000000000000000909204161515608083015280612102575080608001515b15612139576040517fc1ab6dc100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000612147610e10426143fd565b600081815260d36020526040812054919250906121659087906143ea565b905060d2548111156121a3576040517f6d43d1ac00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600082815260d3602052604090208190556121be3387613092565b33600090815260d1602052604081205487910361220b57633b9aca00846040015167ffffffffffffffff16826121f49190614438565b6121fe91906143fd565b61220890826143be565b90505b61222c73ffffffffffffffffffffffffffffffffffffffff89168783612abc565b979650505050505050565b834211156122a1576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f45524332305065726d69743a206578706972656420646561646c696e650000006044820152606401611fa9565b60007f6e71edae12b1b97f4d1f60370fef10105fa2faae0126114a169c64845d6126c98888886122d08c6133b5565b60408051602081019690965273ffffffffffffffffffffffffffffffffffffffff94851690860152929091166060840152608083015260a082015260c0810186905260e0016040516020818303038152906040528051906020012090506000612338826133ea565b9050600061234882878787613453565b90508973ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16146123df576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601e60248201527f45524332305065726d69743a20696e76616c6964207369676e617475726500006044820152606401611fa9565b6123ea8a8a8a612911565b50505050505050505050565b60cd546040517f521d4de900000000000000000000000000000000000000000000000000000000815233600482015273ffffffffffffffffffffffffffffffffffffffff9091169063521d4de990602401602060405180830381865afa158015612464573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906124889190614372565b6124be576040517f99e120bc00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff8116600090815260ce602052604090206002015468010000000000000000900460ff1661252c576040517fc1ab6dc100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff8116600081815260ce602090815260409182902060020180547fffffffffffffffffffffffffffffffffffffffffffff00ffffffffffffffffff811669010000000000000000009182900460ff16801592830291909117909255925192835292917ff7c93079dcbf699749d66345a351afab7d24219bb1d915c9f4fc4cf03f00d3979101610989565b60cd5473ffffffffffffffffffffffffffffffffffffffff16331461261b576040517fb90cdbb100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60cd80547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83169081179091556040517f7dae230f18360d76a040c81f050aa14eb9d6dc7901b20fc5d855e2a20fe814d190600090a250565b73ffffffffffffffffffffffffffffffffffffffff163b151590565b600054610100900460ff16158080156126c65750600054600160ff909116105b806126e05750303b1580156126e0575060005460ff166001145b61276c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201527f647920696e697469616c697a65640000000000000000000000000000000000006064820152608401611fa9565b600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0016600117905580156127ca57600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff166101001790555b3073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1663e9cbd8226040518163ffffffff1660e01b8152600401602060405180830381865afa15801561282c573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061285091906144e5565b73ffffffffffffffffffffffffffffffffffffffff161461289d576040517f14bcf5c800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6128a884848461347b565b801561290b57600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15b50505050565b73ffffffffffffffffffffffffffffffffffffffff83166129b3576040517f08c379a0000000000000000000000000000000000000000000000000000000008152602060048201526024808201527f45524332303a20617070726f76652066726f6d20746865207a65726f2061646460448201527f72657373000000000000000000000000000000000000000000000000000000006064820152608401611fa9565b73ffffffffffffffffffffffffffffffffffffffff8216612a56576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602260248201527f45524332303a20617070726f766520746f20746865207a65726f20616464726560448201527f73730000000000000000000000000000000000000000000000000000000000006064820152608401611fa9565b73ffffffffffffffffffffffffffffffffffffffff83811660008181526034602090815260408083209487168084529482529182902085905590518481527f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b9259101610af7565b60405173ffffffffffffffffffffffffffffffffffffffff831660248201526044810182905261082d9084907fa9059cbb00000000000000000000000000000000000000000000000000000000906064015b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff00000000000000000000000000000000000000000000000000000000909316929092179091526134ff565b60405173ffffffffffffffffffffffffffffffffffffffff8085166024830152831660448201526064810182905261290b9085907f23b872dd0000000000000000000000000000000000000000000000000000000090608401612b0e565b73ffffffffffffffffffffffffffffffffffffffff8216612c6b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601f60248201527f45524332303a206d696e7420746f20746865207a65726f2061646472657373006044820152606401611fa9565b8060356000828254612c7d91906143ea565b909155505073ffffffffffffffffffffffffffffffffffffffff821660009081526033602052604081208054839290612cb79084906143ea565b909155505060405181815273ffffffffffffffffffffffffffffffffffffffff8316906000907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef9060200160405180910390a35050565b73ffffffffffffffffffffffffffffffffffffffff8381166000908152603460209081526040808320938616835292905220547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff811461290b5781811015612dd2576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f45524332303a20696e73756666696369656e7420616c6c6f77616e63650000006044820152606401611fa9565b61290b8484848403612911565b73ffffffffffffffffffffffffffffffffffffffff8316612e82576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602560248201527f45524332303a207472616e736665722066726f6d20746865207a65726f20616460448201527f64726573730000000000000000000000000000000000000000000000000000006064820152608401611fa9565b73ffffffffffffffffffffffffffffffffffffffff8216612f25576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602360248201527f45524332303a207472616e7366657220746f20746865207a65726f206164647260448201527f65737300000000000000000000000000000000000000000000000000000000006064820152608401611fa9565b73ffffffffffffffffffffffffffffffffffffffff831660009081526033602052604090205481811015612fdb576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f45524332303a207472616e7366657220616d6f756e742065786365656473206260448201527f616c616e636500000000000000000000000000000000000000000000000000006064820152608401611fa9565b73ffffffffffffffffffffffffffffffffffffffff80851660009081526033602052604080822085850390559185168152908120805484929061301f9084906143ea565b925050819055508273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef8460405161308591815260200190565b60405180910390a361290b565b73ffffffffffffffffffffffffffffffffffffffff8216613135576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602160248201527f45524332303a206275726e2066726f6d20746865207a65726f2061646472657360448201527f73000000000000000000000000000000000000000000000000000000000000006064820152608401611fa9565b73ffffffffffffffffffffffffffffffffffffffff8216600090815260336020526040902054818110156131eb576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602260248201527f45524332303a206275726e20616d6f756e7420657863656564732062616c616e60448201527f63650000000000000000000000000000000000000000000000000000000000006064820152608401611fa9565b73ffffffffffffffffffffffffffffffffffffffff831660009081526033602052604081208383039055603580548492906132279084906143be565b909155505060405182815260009073ffffffffffffffffffffffffffffffffffffffff8516907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef9060200160405180910390a3505050565b8073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff16146133305773ffffffffffffffffffffffffffffffffffffffff8281166000908152603460209081526040808320938516835292905220548381101561331f576040517f715ec26c00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b61332e838361150b87856143be565b505b61082d8284613092565b600061132f7f8b73c3c69bb8fe3d512ecc4cf759cc79239f7b179b0ffacaa9a75d522b39400f61336960655490565b6066546040805160208101859052908101839052606081018290524660808201523060a082015260009060c0016040516020818303038152906040528051906020012090509392505050565b73ffffffffffffffffffffffffffffffffffffffff811660009081526099602052604090208054600181018255905b50919050565b60006109a96133f761333a565b836040517f19010000000000000000000000000000000000000000000000000000000000006020820152602281018390526042810182905260009060620160405160208183030381529060405280519060200120905092915050565b60008060006134648787878761360b565b9150915061347181613723565b5095945050505050565b61348483613977565b61348e8383613a4d565b60cd80547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83169081179091556040517f7dae230f18360d76a040c81f050aa14eb9d6dc7901b20fc5d855e2a20fe814d190600090a2505050565b6000613561826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c65648152508573ffffffffffffffffffffffffffffffffffffffff16613aee9092919063ffffffff16565b80519091501561082d578080602001905181019061357f9190614372565b61082d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e60448201527f6f742073756363656564000000000000000000000000000000000000000000006064820152608401611fa9565b6000807f7fffffffffffffffffffffffffffffff5d576e7357a4501ddfe92f46681b20a0831115613642575060009050600361371a565b8460ff16601b1415801561365a57508460ff16601c14155b1561366b575060009050600461371a565b6040805160008082526020820180845289905260ff881692820192909252606081018690526080810185905260019060a0016020604051602081039080840390855afa1580156136bf573d6000803e3d6000fd5b50506040517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0015191505073ffffffffffffffffffffffffffffffffffffffff81166137135760006001925092505061371a565b9150600090505b94509492505050565b600081600481111561373757613737614502565b0361373f5750565b600181600481111561375357613753614502565b036137ba576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601860248201527f45434453413a20696e76616c6964207369676e617475726500000000000000006044820152606401611fa9565b60028160048111156137ce576137ce614502565b03613835576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601f60248201527f45434453413a20696e76616c6964207369676e6174757265206c656e677468006044820152606401611fa9565b600381600481111561384957613849614502565b036138d6576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602260248201527f45434453413a20696e76616c6964207369676e6174757265202773272076616c60448201527f75650000000000000000000000000000000000000000000000000000000000006064820152608401611fa9565b60048160048111156138ea576138ea614502565b03611c03576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602260248201527f45434453413a20696e76616c6964207369676e6174757265202776272076616c60448201527f75650000000000000000000000000000000000000000000000000000000000006064820152608401611fa9565b600054610100900460ff16613a0e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201527f6e697469616c697a696e670000000000000000000000000000000000000000006064820152608401611fa9565b611c03816040518060400160405280600181526020017f3100000000000000000000000000000000000000000000000000000000000000815250613b05565b600054610100900460ff16613ae4576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201527f6e697469616c697a696e670000000000000000000000000000000000000000006064820152608401611fa9565b610e358282613bb6565b6060613afd8484600085613c66565b949350505050565b600054610100900460ff16613b9c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201527f6e697469616c697a696e670000000000000000000000000000000000000000006064820152608401611fa9565b815160209283012081519190920120606591909155606655565b600054610100900460ff16613c4d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201527f6e697469616c697a696e670000000000000000000000000000000000000000006064820152608401611fa9565b6036613c59838261457f565b50603761082d828261457f565b606082471015613cf8576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f60448201527f722063616c6c00000000000000000000000000000000000000000000000000006064820152608401611fa9565b73ffffffffffffffffffffffffffffffffffffffff85163b613d76576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006044820152606401611fa9565b6000808673ffffffffffffffffffffffffffffffffffffffff168587604051613d9f9190614699565b60006040518083038185875af1925050503d8060008114613ddc576040519150601f19603f3d011682016040523d82523d6000602084013e613de1565b606091505b509150915061222c82828660608315613dfb575081610db7565b825115613e0b5782518084602001fd5b816040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611fa99190613e63565b60005b83811015613e5a578181015183820152602001613e42565b50506000910152565b6020815260008251806020840152613e82816040850160208701613e3f565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169190910160400192915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b600082601f830112613ef457600080fd5b813567ffffffffffffffff80821115613f0f57613f0f613eb4565b604051601f83017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0908116603f01168101908282118183101715613f5557613f55613eb4565b81604052838152866020858801011115613f6e57600080fd5b836020870160208301376000602085830101528094505050505092915050565b73ffffffffffffffffffffffffffffffffffffffff81168114611c0357600080fd5b600080600060608486031215613fc557600080fd5b833567ffffffffffffffff80821115613fdd57600080fd5b613fe987838801613ee3565b94506020860135915080821115613fff57600080fd5b5061400c86828701613ee3565b925050604084013561401d81613f8e565b809150509250925092565b60006020828403121561403a57600080fd5b8135610db781613f8e565b6000806040838503121561405857600080fd5b823561406381613f8e565b946020939093013593505050565b60008060006060848603121561408657600080fd5b833561409181613f8e565b925060208401356140a181613f8e565b929592945050506040919091013590565b6000806000606084860312156140c757600080fd5b83356140d281613f8e565b925060208401359150604084013561401d81613f8e565b600080604083850312156140fc57600080fd5b82359150602083013561410e81613f8e565b809150509250929050565b60008060006060848603121561412e57600080fd5b83359250602084013561414081613f8e565b9150604084013561401d81613f8e565b60006020828403121561416257600080fd5b5035919050565b803567ffffffffffffffff8116811461418157600080fd5b919050565b8015158114611c0357600080fd5b600080600080600060a086880312156141ac57600080fd5b85356141b781613f8e565b945060208601359350604086013592506141d360608701614169565b915060808601356141e381614186565b809150509295509295909350565b6000806040838503121561420457600080fd5b823561420f81613f8e565b915061421d60208401614169565b90509250929050565b6020808252825182820181905260009190848201906040850190845b8181101561427457835173ffffffffffffffffffffffffffffffffffffffff1683529284019291840191600101614242565b50909695505050505050565b600080600080600080600060e0888a03121561429b57600080fd5b87356142a681613f8e565b965060208801356142b681613f8e565b95506040880135945060608801359350608088013560ff811681146142da57600080fd5b9699959850939692959460a0840135945060c09093013592915050565b6000806040838503121561430a57600080fd5b823561431581613f8e565b9150602083013561410e81613f8e565b600181811c9082168061433957607f821691505b6020821081036133e4577f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b60006020828403121561438457600080fd5b8151610db781614186565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b818103818111156109a9576109a961438f565b6000602082840312156143e357600080fd5b5051919050565b808201808211156109a9576109a961438f565b600082614433577f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b500490565b80820281158282048414176109a9576109a961438f565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82036144af576144af61438f565b5060010190565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603160045260246000fd5b6000602082840312156144f757600080fd5b8151610db781613f8e565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b601f82111561082d57600081815260208120601f850160051c810160208610156145585750805b601f850160051c820191505b8181101561457757828155600101614564565b505050505050565b815167ffffffffffffffff81111561459957614599613eb4565b6145ad816145a78454614325565b84614531565b602080601f83116001811461460057600084156145ca5750858301515b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600386901b1c1916600185901b178555614577565b6000858152602081207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08616915b8281101561464d5788860151825594840194600190910190840161462e565b508582101561468957878501517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600388901b60f8161c191681555b5050505050600190811b01905550565b600082516146ab818460208701613e3f565b919091019291505056fea26469706673582212204ab762f428941cadd300d875bf277cb0f7dff52a487fb7282a657f3da537ca0564736f6c63430008110033", + "numDeployments": 2, + "solcInputHash": "871924e0c138825a2736b76def8fef8d", + "metadata": "{\"compiler\":{\"version\":\"0.8.17+commit.8df45f5f\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[],\"name\":\"AssetStillControlledInReserves\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"BurnAmountExceedsAllowance\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"HourlyLimitExceeded\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidSender\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidToken\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidTreasury\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"NotGovernor\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"NotGovernorOrGuardian\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"NotMinter\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"NotTreasury\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"TooBigAmount\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"TooHighParameterValue\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ZeroAddress\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"spender\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"}],\"name\":\"Approval\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"bridgeToken\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"limit\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"hourlyLimit\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"fee\",\"type\":\"uint64\"},{\"indexed\":false,\"internalType\":\"bool\",\"name\":\"paused\",\"type\":\"bool\"}],\"name\":\"BridgeTokenAdded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"bridgeToken\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"fee\",\"type\":\"uint64\"}],\"name\":\"BridgeTokenFeeUpdated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"bridgeToken\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"hourlyLimit\",\"type\":\"uint256\"}],\"name\":\"BridgeTokenHourlyLimitUpdated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"bridgeToken\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"limit\",\"type\":\"uint256\"}],\"name\":\"BridgeTokenLimitUpdated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"bridgeToken\",\"type\":\"address\"}],\"name\":\"BridgeTokenRemoved\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"bridgeToken\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"bool\",\"name\":\"toggleStatus\",\"type\":\"bool\"}],\"name\":\"BridgeTokenToggled\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"theAddress\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"toggleStatus\",\"type\":\"uint256\"}],\"name\":\"FeeToggled\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"hourlyLimit\",\"type\":\"uint256\"}],\"name\":\"HourlyLimitUpdated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint8\",\"name\":\"version\",\"type\":\"uint8\"}],\"name\":\"Initialized\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"minter\",\"type\":\"address\"}],\"name\":\"MinterToggled\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"Recovered\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"}],\"name\":\"Transfer\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"_treasury\",\"type\":\"address\"}],\"name\":\"TreasuryUpdated\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"BASE_PARAMS\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"DOMAIN_SEPARATOR\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"bridgeToken\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"limit\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"hourlyLimit\",\"type\":\"uint256\"},{\"internalType\":\"uint64\",\"name\":\"fee\",\"type\":\"uint64\"},{\"internalType\":\"bool\",\"name\":\"paused\",\"type\":\"bool\"}],\"name\":\"addBridgeToken\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"minter\",\"type\":\"address\"}],\"name\":\"addMinter\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"allBridgeTokens\",\"outputs\":[{\"internalType\":\"address[]\",\"name\":\"\",\"type\":\"address[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"spender\",\"type\":\"address\"}],\"name\":\"allowance\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"spender\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"approve\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"}],\"name\":\"balanceOf\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"name\":\"bridgeTokensList\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"bridges\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"limit\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"hourlyLimit\",\"type\":\"uint256\"},{\"internalType\":\"uint64\",\"name\":\"fee\",\"type\":\"uint64\"},{\"internalType\":\"bool\",\"name\":\"allowed\",\"type\":\"bool\"},{\"internalType\":\"bool\",\"name\":\"paused\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"burner\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"}],\"name\":\"burnFrom\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"burner\",\"type\":\"address\"}],\"name\":\"burnSelf\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"burnStablecoin\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"chainTotalHourlyLimit\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"name\":\"chainTotalUsage\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"currentTotalUsage\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"bridgeToken\",\"type\":\"address\"}],\"name\":\"currentUsage\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"decimals\",\"outputs\":[{\"internalType\":\"uint8\",\"name\":\"\",\"type\":\"uint8\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"spender\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"subtractedValue\",\"type\":\"uint256\"}],\"name\":\"decreaseAllowance\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"spender\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"addedValue\",\"type\":\"uint256\"}],\"name\":\"increaseAllowance\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"string\",\"name\":\"name_\",\"type\":\"string\"},{\"internalType\":\"string\",\"name\":\"symbol_\",\"type\":\"string\"},{\"internalType\":\"address\",\"name\":\"_treasury\",\"type\":\"address\"}],\"name\":\"initialize\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"isFeeExempt\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"isMinter\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"mint\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"name\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"}],\"name\":\"nonces\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"spender\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"deadline\",\"type\":\"uint256\"},{\"internalType\":\"uint8\",\"name\":\"v\",\"type\":\"uint8\"},{\"internalType\":\"bytes32\",\"name\":\"r\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32\",\"name\":\"s\",\"type\":\"bytes32\"}],\"name\":\"permit\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"tokenAddress\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amountToRecover\",\"type\":\"uint256\"}],\"name\":\"recoverERC20\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"bridgeToken\",\"type\":\"address\"}],\"name\":\"removeBridgeToken\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"minter\",\"type\":\"address\"}],\"name\":\"removeMinter\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"hourlyLimit\",\"type\":\"uint256\"}],\"name\":\"setChainTotalHourlyLimit\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"bridgeToken\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"hourlyLimit\",\"type\":\"uint256\"}],\"name\":\"setHourlyLimit\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"bridgeToken\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"limit\",\"type\":\"uint256\"}],\"name\":\"setLimit\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"bridgeToken\",\"type\":\"address\"},{\"internalType\":\"uint64\",\"name\":\"fee\",\"type\":\"uint64\"}],\"name\":\"setSwapFee\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_treasury\",\"type\":\"address\"}],\"name\":\"setTreasury\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"bridgeToken\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"swapIn\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"bridgeToken\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"swapOut\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"symbol\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"bridgeToken\",\"type\":\"address\"}],\"name\":\"toggleBridge\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"theAddress\",\"type\":\"address\"}],\"name\":\"toggleFeesForAddress\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"totalSupply\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"transfer\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"transferFrom\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"treasury\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"name\":\"usage\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"}],\"devdoc\":{\"author\":\"Angle Labs, Inc.\",\"details\":\"This contract supports bridge tokens having a minting right on the stablecoin (also referred to as the canonical or the native token)\",\"kind\":\"dev\",\"methods\":{\"DOMAIN_SEPARATOR()\":{\"details\":\"See {IERC20Permit-DOMAIN_SEPARATOR}.\"},\"addBridgeToken(address,uint256,uint256,uint64,bool)\":{\"params\":{\"bridgeToken\":\"Bridge token to add: it should be a version of the stablecoin from another bridge\",\"fee\":\"Fee taken upon swapping for or against this token\",\"hourlyLimit\":\"Limit on the hourly volume for this bridge\",\"limit\":\"Limit on the balance of bridge token this contract could hold\",\"paused\":\"Whether swapping for this token should be paused or not\"}},\"addMinter(address)\":{\"details\":\"Zero address checks are performed directly in the `Treasury` contract\",\"params\":{\"minter\":\"Minter address to add\"}},\"allBridgeTokens()\":{\"details\":\"Helpful for UIs\"},\"allowance(address,address)\":{\"details\":\"See {IERC20-allowance}.\"},\"approve(address,uint256)\":{\"details\":\"See {IERC20-approve}. NOTE: If `amount` is the maximum `uint256`, the allowance is not updated on `transferFrom`. This is semantically equivalent to an infinite approval. Requirements: - `spender` cannot be the zero address.\"},\"balanceOf(address)\":{\"details\":\"See {IERC20-balanceOf}.\"},\"burnFrom(uint256,address,address)\":{\"details\":\"This method is to be called by a contract with the minter right after being requested to do so by a `sender` address willing to burn tokens from another `burner` addressThe method checks the allowance between the `sender` and the `burner`\",\"params\":{\"amount\":\"Amount of tokens to burn\",\"burner\":\"Address to burn from\",\"sender\":\"Address which requested the burn from `burner`\"}},\"burnSelf(uint256,address)\":{\"details\":\"This method is to be called by a contract with a minter right on the AgToken after being requested to do so by an address willing to burn tokens from its address\",\"params\":{\"amount\":\"Amount of tokens to burn\",\"burner\":\"Address to burn from\"}},\"burnStablecoin(uint256)\":{\"details\":\"This function can typically be called if there is a settlement mechanism to burn stablecoins\",\"params\":{\"amount\":\"Amount of stablecoins to burn\"}},\"currentTotalUsage()\":{\"details\":\"Helpful for UIs\"},\"currentUsage(address)\":{\"details\":\"Helpful for UIs\",\"params\":{\"bridgeToken\":\"Bridge used to mint\"}},\"decimals()\":{\"details\":\"Returns the number of decimals used to get its user representation. For example, if `decimals` equals `2`, a balance of `505` tokens should be displayed to a user as `5.05` (`505 / 10 ** 2`). Tokens usually opt for a value of 18, imitating the relationship between Ether and Wei. This is the value {ERC20} uses, unless this function is overridden; NOTE: This information is only used for _display_ purposes: it in no way affects any of the arithmetic of the contract, including {IERC20-balanceOf} and {IERC20-transfer}.\"},\"decreaseAllowance(address,uint256)\":{\"details\":\"Atomically decreases the allowance granted to `spender` by the caller. This is an alternative to {approve} that can be used as a mitigation for problems described in {IERC20-approve}. Emits an {Approval} event indicating the updated allowance. Requirements: - `spender` cannot be the zero address. - `spender` must have allowance for the caller of at least `subtractedValue`.\"},\"increaseAllowance(address,uint256)\":{\"details\":\"Atomically increases the allowance granted to `spender` by the caller. This is an alternative to {approve} that can be used as a mitigation for problems described in {IERC20-approve}. Emits an {Approval} event indicating the updated allowance. Requirements: - `spender` cannot be the zero address.\"},\"mint(address,uint256)\":{\"details\":\"The contracts allowed to issue agTokens are the `StableMaster` contract, `VaultManager` contracts associated to this stablecoin as well as the flash loan module (if activated) and potentially contracts whitelisted by governance\",\"params\":{\"account\":\"Address to mint to\",\"amount\":\"Amount to mint\"}},\"name()\":{\"details\":\"Returns the name of the token.\"},\"nonces(address)\":{\"details\":\"See {IERC20Permit-nonces}.\"},\"permit(address,address,uint256,uint256,uint8,bytes32,bytes32)\":{\"details\":\"See {IERC20Permit-permit}.\"},\"recoverERC20(address,address,uint256)\":{\"details\":\"Can be used to withdraw bridge tokens for them to be de-bridged on mainnet\"},\"removeBridgeToken(address)\":{\"params\":{\"bridgeToken\":\"Address of the bridge token to remove support for\"}},\"removeMinter(address)\":{\"details\":\"This function can also be called by a minter wishing to revoke itself\",\"params\":{\"minter\":\"Minter address to remove\"}},\"setTreasury(address)\":{\"params\":{\"_treasury\":\"New treasury address\"}},\"swapIn(address,uint256,address)\":{\"details\":\"Some fees may be taken by the protocol depending on the token used and on the address calling\",\"params\":{\"amount\":\"Amount of bridge tokens to send\",\"bridgeToken\":\"Bridge token to use to mint\",\"to\":\"Address to which the stablecoin should be sent\"},\"returns\":{\"_0\":\"Amount of the canonical stablecoin actually minted\"}},\"swapOut(address,uint256,address)\":{\"details\":\"Some fees may be taken by the protocol depending on the token used and on the address calling\",\"params\":{\"amount\":\"Amount of canonical tokens to burn\",\"bridgeToken\":\"Bridge token required\",\"to\":\"Address to which the bridge token should be sent\"},\"returns\":{\"_0\":\"Amount of bridge tokens actually sent back\"}},\"symbol()\":{\"details\":\"Returns the symbol of the token, usually a shorter version of the name.\"},\"totalSupply()\":{\"details\":\"See {IERC20-totalSupply}.\"},\"transfer(address,uint256)\":{\"details\":\"See {IERC20-transfer}. Requirements: - `to` cannot be the zero address. - the caller must have a balance of at least `amount`.\"},\"transferFrom(address,address,uint256)\":{\"details\":\"See {IERC20-transferFrom}. Emits an {Approval} event indicating the updated allowance. This is not required by the EIP. See the note at the beginning of {ERC20}. NOTE: Does not update the allowance if the current allowance is the maximum `uint256`. Requirements: - `from` and `to` cannot be the zero address. - `from` must have a balance of at least `amount`. - the caller must have allowance for ``from``'s tokens of at least `amount`.\"}},\"title\":\"AgTokenSideChainMultiBridge\",\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{\"BASE_PARAMS()\":{\"notice\":\"Base used for fee computation\"},\"addBridgeToken(address,uint256,uint256,uint64,bool)\":{\"notice\":\"Adds support for a bridge token\"},\"addMinter(address)\":{\"notice\":\"Adds a minter in the contract\"},\"allBridgeTokens()\":{\"notice\":\"Returns the list of all supported bridge tokens\"},\"bridgeTokensList(uint256)\":{\"notice\":\"List of all bridge tokens\"},\"bridges(address)\":{\"notice\":\"Maps a bridge token to data\"},\"burnFrom(uint256,address,address)\":{\"notice\":\"Burns `amount` tokens from a `burner` address after being asked to by `sender`\"},\"burnSelf(uint256,address)\":{\"notice\":\"Burns `amount` tokens from a `burner` address\"},\"burnStablecoin(uint256)\":{\"notice\":\"Allows anyone to burn stablecoins\"},\"chainTotalHourlyLimit()\":{\"notice\":\"Limit to the amount of tokens that can be sent from that chain to another chain\"},\"chainTotalUsage(uint256)\":{\"notice\":\"Usage per hour on that chain. Maps an hourly timestamp to the total volume swapped out on the chain\"},\"currentTotalUsage()\":{\"notice\":\"Returns the current total volume on the chain for the current hour\"},\"currentUsage(address)\":{\"notice\":\"Returns the current volume for a bridge, for the current hour\"},\"initialize(string,string,address)\":{\"notice\":\"Initializes the `AgToken` contract\"},\"isFeeExempt(address)\":{\"notice\":\"Maps an address to whether it is exempt of fees for when it comes to swapping in and out\"},\"isMinter(address)\":{\"notice\":\"Checks whether an address has the right to mint agTokens\"},\"mint(address,uint256)\":{\"notice\":\"Lets the `StableMaster` contract or another whitelisted contract mint agTokens\"},\"recoverERC20(address,address,uint256)\":{\"notice\":\"Recovers any ERC20 token\"},\"removeBridgeToken(address)\":{\"notice\":\"Removes support for a token\"},\"removeMinter(address)\":{\"notice\":\"Removes a minter from the contract\"},\"setChainTotalHourlyLimit(uint256)\":{\"notice\":\"Updates the `chainTotalHourlyLimit` amount\"},\"setHourlyLimit(address,uint256)\":{\"notice\":\"Updates the `hourlyLimit` amount for `bridgeToken`\"},\"setLimit(address,uint256)\":{\"notice\":\"Updates the `limit` amount for `bridgeToken`\"},\"setSwapFee(address,uint64)\":{\"notice\":\"Updates the `fee` value for `bridgeToken`\"},\"setTreasury(address)\":{\"notice\":\"Sets a new treasury contract\"},\"swapIn(address,uint256,address)\":{\"notice\":\"Mints the canonical token from a supported bridge token\"},\"swapOut(address,uint256,address)\":{\"notice\":\"Burns the canonical token in exchange for a bridge token\"},\"toggleBridge(address)\":{\"notice\":\"Pauses or unpauses swapping in and out for a token\"},\"toggleFeesForAddress(address)\":{\"notice\":\"Toggles fees for the address `theAddress`\"},\"treasury()\":{\"notice\":\"Reference to the treasury contract which can grant minting rights\"},\"usage(address,uint256)\":{\"notice\":\"Maps a bridge token to the associated hourly volume\"}},\"notice\":\"Contract for Angle agTokens on other chains than Ethereum mainnet\",\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/agToken/AgTokenSideChainMultiBridge.sol\":\"AgTokenSideChainMultiBridge\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":1000000},\"remappings\":[]},\"sources\":{\"@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.7.0) (proxy/utils/Initializable.sol)\\n\\npragma solidity ^0.8.2;\\n\\nimport \\\"../../utils/AddressUpgradeable.sol\\\";\\n\\n/**\\n * @dev This is a base contract to aid in writing upgradeable contracts, or any kind of contract that will be deployed\\n * behind a proxy. Since proxied contracts do not make use of a constructor, it's common to move constructor logic to an\\n * external initializer function, usually called `initialize`. It then becomes necessary to protect this initializer\\n * function so it can only be called once. The {initializer} modifier provided by this contract will have this effect.\\n *\\n * The initialization functions use a version number. Once a version number is used, it is consumed and cannot be\\n * reused. This mechanism prevents re-execution of each \\\"step\\\" but allows the creation of new initialization steps in\\n * case an upgrade adds a module that needs to be initialized.\\n *\\n * For example:\\n *\\n * [.hljs-theme-light.nopadding]\\n * ```\\n * contract MyToken is ERC20Upgradeable {\\n * function initialize() initializer public {\\n * __ERC20_init(\\\"MyToken\\\", \\\"MTK\\\");\\n * }\\n * }\\n * contract MyTokenV2 is MyToken, ERC20PermitUpgradeable {\\n * function initializeV2() reinitializer(2) public {\\n * __ERC20Permit_init(\\\"MyToken\\\");\\n * }\\n * }\\n * ```\\n *\\n * TIP: To avoid leaving the proxy in an uninitialized state, the initializer function should be called as early as\\n * possible by providing the encoded function call as the `_data` argument to {ERC1967Proxy-constructor}.\\n *\\n * CAUTION: When used with inheritance, manual care must be taken to not invoke a parent initializer twice, or to ensure\\n * that all initializers are idempotent. This is not verified automatically as constructors are by Solidity.\\n *\\n * [CAUTION]\\n * ====\\n * Avoid leaving a contract uninitialized.\\n *\\n * An uninitialized contract can be taken over by an attacker. This applies to both a proxy and its implementation\\n * contract, which may impact the proxy. To prevent the implementation contract from being used, you should invoke\\n * the {_disableInitializers} function in the constructor to automatically lock it when it is deployed:\\n *\\n * [.hljs-theme-light.nopadding]\\n * ```\\n * /// @custom:oz-upgrades-unsafe-allow constructor\\n * constructor() {\\n * _disableInitializers();\\n * }\\n * ```\\n * ====\\n */\\nabstract contract Initializable {\\n /**\\n * @dev Indicates that the contract has been initialized.\\n * @custom:oz-retyped-from bool\\n */\\n uint8 private _initialized;\\n\\n /**\\n * @dev Indicates that the contract is in the process of being initialized.\\n */\\n bool private _initializing;\\n\\n /**\\n * @dev Triggered when the contract has been initialized or reinitialized.\\n */\\n event Initialized(uint8 version);\\n\\n /**\\n * @dev A modifier that defines a protected initializer function that can be invoked at most once. In its scope,\\n * `onlyInitializing` functions can be used to initialize parent contracts. Equivalent to `reinitializer(1)`.\\n */\\n modifier initializer() {\\n bool isTopLevelCall = !_initializing;\\n require(\\n (isTopLevelCall && _initialized < 1) || (!AddressUpgradeable.isContract(address(this)) && _initialized == 1),\\n \\\"Initializable: contract is already initialized\\\"\\n );\\n _initialized = 1;\\n if (isTopLevelCall) {\\n _initializing = true;\\n }\\n _;\\n if (isTopLevelCall) {\\n _initializing = false;\\n emit Initialized(1);\\n }\\n }\\n\\n /**\\n * @dev A modifier that defines a protected reinitializer function that can be invoked at most once, and only if the\\n * contract hasn't been initialized to a greater version before. In its scope, `onlyInitializing` functions can be\\n * used to initialize parent contracts.\\n *\\n * `initializer` is equivalent to `reinitializer(1)`, so a reinitializer may be used after the original\\n * initialization step. This is essential to configure modules that are added through upgrades and that require\\n * initialization.\\n *\\n * Note that versions can jump in increments greater than 1; this implies that if multiple reinitializers coexist in\\n * a contract, executing them in the right order is up to the developer or operator.\\n */\\n modifier reinitializer(uint8 version) {\\n require(!_initializing && _initialized < version, \\\"Initializable: contract is already initialized\\\");\\n _initialized = version;\\n _initializing = true;\\n _;\\n _initializing = false;\\n emit Initialized(version);\\n }\\n\\n /**\\n * @dev Modifier to protect an initialization function so that it can only be invoked by functions with the\\n * {initializer} and {reinitializer} modifiers, directly or indirectly.\\n */\\n modifier onlyInitializing() {\\n require(_initializing, \\\"Initializable: contract is not initializing\\\");\\n _;\\n }\\n\\n /**\\n * @dev Locks the contract, preventing any future reinitialization. This cannot be part of an initializer call.\\n * Calling this in the constructor of a contract will prevent that contract from being initialized or reinitialized\\n * to any version. It is recommended to use this to lock implementation contracts that are designed to be called\\n * through proxies.\\n */\\n function _disableInitializers() internal virtual {\\n require(!_initializing, \\\"Initializable: contract is initializing\\\");\\n if (_initialized < type(uint8).max) {\\n _initialized = type(uint8).max;\\n emit Initialized(type(uint8).max);\\n }\\n }\\n}\\n\",\"keccak256\":\"0x0203dcadc5737d9ef2c211d6fa15d18ebc3b30dfa51903b64870b01a062b0b4e\",\"license\":\"MIT\"},\"@openzeppelin/contracts-upgradeable/token/ERC20/ERC20Upgradeable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.7.0) (token/ERC20/ERC20.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"./IERC20Upgradeable.sol\\\";\\nimport \\\"./extensions/IERC20MetadataUpgradeable.sol\\\";\\nimport \\\"../../utils/ContextUpgradeable.sol\\\";\\nimport \\\"../../proxy/utils/Initializable.sol\\\";\\n\\n/**\\n * @dev Implementation of the {IERC20} interface.\\n *\\n * This implementation is agnostic to the way tokens are created. This means\\n * that a supply mechanism has to be added in a derived contract using {_mint}.\\n * For a generic mechanism see {ERC20PresetMinterPauser}.\\n *\\n * TIP: For a detailed writeup see our guide\\n * https://forum.zeppelin.solutions/t/how-to-implement-erc20-supply-mechanisms/226[How\\n * to implement supply mechanisms].\\n *\\n * We have followed general OpenZeppelin Contracts guidelines: functions revert\\n * instead returning `false` on failure. This behavior is nonetheless\\n * conventional and does not conflict with the expectations of ERC20\\n * applications.\\n *\\n * Additionally, an {Approval} event is emitted on calls to {transferFrom}.\\n * This allows applications to reconstruct the allowance for all accounts just\\n * by listening to said events. Other implementations of the EIP may not emit\\n * these events, as it isn't required by the specification.\\n *\\n * Finally, the non-standard {decreaseAllowance} and {increaseAllowance}\\n * functions have been added to mitigate the well-known issues around setting\\n * allowances. See {IERC20-approve}.\\n */\\ncontract ERC20Upgradeable is Initializable, ContextUpgradeable, IERC20Upgradeable, IERC20MetadataUpgradeable {\\n mapping(address => uint256) private _balances;\\n\\n mapping(address => mapping(address => uint256)) private _allowances;\\n\\n uint256 private _totalSupply;\\n\\n string private _name;\\n string private _symbol;\\n\\n /**\\n * @dev Sets the values for {name} and {symbol}.\\n *\\n * The default value of {decimals} is 18. To select a different value for\\n * {decimals} you should overload it.\\n *\\n * All two of these values are immutable: they can only be set once during\\n * construction.\\n */\\n function __ERC20_init(string memory name_, string memory symbol_) internal onlyInitializing {\\n __ERC20_init_unchained(name_, symbol_);\\n }\\n\\n function __ERC20_init_unchained(string memory name_, string memory symbol_) internal onlyInitializing {\\n _name = name_;\\n _symbol = symbol_;\\n }\\n\\n /**\\n * @dev Returns the name of the token.\\n */\\n function name() public view virtual override returns (string memory) {\\n return _name;\\n }\\n\\n /**\\n * @dev Returns the symbol of the token, usually a shorter version of the\\n * name.\\n */\\n function symbol() public view virtual override returns (string memory) {\\n return _symbol;\\n }\\n\\n /**\\n * @dev Returns the number of decimals used to get its user representation.\\n * For example, if `decimals` equals `2`, a balance of `505` tokens should\\n * be displayed to a user as `5.05` (`505 / 10 ** 2`).\\n *\\n * Tokens usually opt for a value of 18, imitating the relationship between\\n * Ether and Wei. This is the value {ERC20} uses, unless this function is\\n * overridden;\\n *\\n * NOTE: This information is only used for _display_ purposes: it in\\n * no way affects any of the arithmetic of the contract, including\\n * {IERC20-balanceOf} and {IERC20-transfer}.\\n */\\n function decimals() public view virtual override returns (uint8) {\\n return 18;\\n }\\n\\n /**\\n * @dev See {IERC20-totalSupply}.\\n */\\n function totalSupply() public view virtual override returns (uint256) {\\n return _totalSupply;\\n }\\n\\n /**\\n * @dev See {IERC20-balanceOf}.\\n */\\n function balanceOf(address account) public view virtual override returns (uint256) {\\n return _balances[account];\\n }\\n\\n /**\\n * @dev See {IERC20-transfer}.\\n *\\n * Requirements:\\n *\\n * - `to` cannot be the zero address.\\n * - the caller must have a balance of at least `amount`.\\n */\\n function transfer(address to, uint256 amount) public virtual override returns (bool) {\\n address owner = _msgSender();\\n _transfer(owner, to, amount);\\n return true;\\n }\\n\\n /**\\n * @dev See {IERC20-allowance}.\\n */\\n function allowance(address owner, address spender) public view virtual override returns (uint256) {\\n return _allowances[owner][spender];\\n }\\n\\n /**\\n * @dev See {IERC20-approve}.\\n *\\n * NOTE: If `amount` is the maximum `uint256`, the allowance is not updated on\\n * `transferFrom`. This is semantically equivalent to an infinite approval.\\n *\\n * Requirements:\\n *\\n * - `spender` cannot be the zero address.\\n */\\n function approve(address spender, uint256 amount) public virtual override returns (bool) {\\n address owner = _msgSender();\\n _approve(owner, spender, amount);\\n return true;\\n }\\n\\n /**\\n * @dev See {IERC20-transferFrom}.\\n *\\n * Emits an {Approval} event indicating the updated allowance. This is not\\n * required by the EIP. See the note at the beginning of {ERC20}.\\n *\\n * NOTE: Does not update the allowance if the current allowance\\n * is the maximum `uint256`.\\n *\\n * Requirements:\\n *\\n * - `from` and `to` cannot be the zero address.\\n * - `from` must have a balance of at least `amount`.\\n * - the caller must have allowance for ``from``'s tokens of at least\\n * `amount`.\\n */\\n function transferFrom(\\n address from,\\n address to,\\n uint256 amount\\n ) public virtual override returns (bool) {\\n address spender = _msgSender();\\n _spendAllowance(from, spender, amount);\\n _transfer(from, to, amount);\\n return true;\\n }\\n\\n /**\\n * @dev Atomically increases the allowance granted to `spender` by the caller.\\n *\\n * This is an alternative to {approve} that can be used as a mitigation for\\n * problems described in {IERC20-approve}.\\n *\\n * Emits an {Approval} event indicating the updated allowance.\\n *\\n * Requirements:\\n *\\n * - `spender` cannot be the zero address.\\n */\\n function increaseAllowance(address spender, uint256 addedValue) public virtual returns (bool) {\\n address owner = _msgSender();\\n _approve(owner, spender, allowance(owner, spender) + addedValue);\\n return true;\\n }\\n\\n /**\\n * @dev Atomically decreases the allowance granted to `spender` by the caller.\\n *\\n * This is an alternative to {approve} that can be used as a mitigation for\\n * problems described in {IERC20-approve}.\\n *\\n * Emits an {Approval} event indicating the updated allowance.\\n *\\n * Requirements:\\n *\\n * - `spender` cannot be the zero address.\\n * - `spender` must have allowance for the caller of at least\\n * `subtractedValue`.\\n */\\n function decreaseAllowance(address spender, uint256 subtractedValue) public virtual returns (bool) {\\n address owner = _msgSender();\\n uint256 currentAllowance = allowance(owner, spender);\\n require(currentAllowance >= subtractedValue, \\\"ERC20: decreased allowance below zero\\\");\\n unchecked {\\n _approve(owner, spender, currentAllowance - subtractedValue);\\n }\\n\\n return true;\\n }\\n\\n /**\\n * @dev Moves `amount` of tokens from `from` to `to`.\\n *\\n * This internal function is equivalent to {transfer}, and can be used to\\n * e.g. implement automatic token fees, slashing mechanisms, etc.\\n *\\n * Emits a {Transfer} event.\\n *\\n * Requirements:\\n *\\n * - `from` cannot be the zero address.\\n * - `to` cannot be the zero address.\\n * - `from` must have a balance of at least `amount`.\\n */\\n function _transfer(\\n address from,\\n address to,\\n uint256 amount\\n ) internal virtual {\\n require(from != address(0), \\\"ERC20: transfer from the zero address\\\");\\n require(to != address(0), \\\"ERC20: transfer to the zero address\\\");\\n\\n _beforeTokenTransfer(from, to, amount);\\n\\n uint256 fromBalance = _balances[from];\\n require(fromBalance >= amount, \\\"ERC20: transfer amount exceeds balance\\\");\\n unchecked {\\n _balances[from] = fromBalance - amount;\\n }\\n _balances[to] += amount;\\n\\n emit Transfer(from, to, amount);\\n\\n _afterTokenTransfer(from, to, amount);\\n }\\n\\n /** @dev Creates `amount` tokens and assigns them to `account`, increasing\\n * the total supply.\\n *\\n * Emits a {Transfer} event with `from` set to the zero address.\\n *\\n * Requirements:\\n *\\n * - `account` cannot be the zero address.\\n */\\n function _mint(address account, uint256 amount) internal virtual {\\n require(account != address(0), \\\"ERC20: mint to the zero address\\\");\\n\\n _beforeTokenTransfer(address(0), account, amount);\\n\\n _totalSupply += amount;\\n _balances[account] += amount;\\n emit Transfer(address(0), account, amount);\\n\\n _afterTokenTransfer(address(0), account, amount);\\n }\\n\\n /**\\n * @dev Destroys `amount` tokens from `account`, reducing the\\n * total supply.\\n *\\n * Emits a {Transfer} event with `to` set to the zero address.\\n *\\n * Requirements:\\n *\\n * - `account` cannot be the zero address.\\n * - `account` must have at least `amount` tokens.\\n */\\n function _burn(address account, uint256 amount) internal virtual {\\n require(account != address(0), \\\"ERC20: burn from the zero address\\\");\\n\\n _beforeTokenTransfer(account, address(0), amount);\\n\\n uint256 accountBalance = _balances[account];\\n require(accountBalance >= amount, \\\"ERC20: burn amount exceeds balance\\\");\\n unchecked {\\n _balances[account] = accountBalance - amount;\\n }\\n _totalSupply -= amount;\\n\\n emit Transfer(account, address(0), amount);\\n\\n _afterTokenTransfer(account, address(0), amount);\\n }\\n\\n /**\\n * @dev Sets `amount` as the allowance of `spender` over the `owner` s tokens.\\n *\\n * This internal function is equivalent to `approve`, and can be used to\\n * e.g. set automatic allowances for certain subsystems, etc.\\n *\\n * Emits an {Approval} event.\\n *\\n * Requirements:\\n *\\n * - `owner` cannot be the zero address.\\n * - `spender` cannot be the zero address.\\n */\\n function _approve(\\n address owner,\\n address spender,\\n uint256 amount\\n ) internal virtual {\\n require(owner != address(0), \\\"ERC20: approve from the zero address\\\");\\n require(spender != address(0), \\\"ERC20: approve to the zero address\\\");\\n\\n _allowances[owner][spender] = amount;\\n emit Approval(owner, spender, amount);\\n }\\n\\n /**\\n * @dev Updates `owner` s allowance for `spender` based on spent `amount`.\\n *\\n * Does not update the allowance amount in case of infinite allowance.\\n * Revert if not enough allowance is available.\\n *\\n * Might emit an {Approval} event.\\n */\\n function _spendAllowance(\\n address owner,\\n address spender,\\n uint256 amount\\n ) internal virtual {\\n uint256 currentAllowance = allowance(owner, spender);\\n if (currentAllowance != type(uint256).max) {\\n require(currentAllowance >= amount, \\\"ERC20: insufficient allowance\\\");\\n unchecked {\\n _approve(owner, spender, currentAllowance - amount);\\n }\\n }\\n }\\n\\n /**\\n * @dev Hook that is called before any transfer of tokens. This includes\\n * minting and burning.\\n *\\n * Calling conditions:\\n *\\n * - when `from` and `to` are both non-zero, `amount` of ``from``'s tokens\\n * will be transferred to `to`.\\n * - when `from` is zero, `amount` tokens will be minted for `to`.\\n * - when `to` is zero, `amount` of ``from``'s tokens will be burned.\\n * - `from` and `to` are never both zero.\\n *\\n * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].\\n */\\n function _beforeTokenTransfer(\\n address from,\\n address to,\\n uint256 amount\\n ) internal virtual {}\\n\\n /**\\n * @dev Hook that is called after any transfer of tokens. This includes\\n * minting and burning.\\n *\\n * Calling conditions:\\n *\\n * - when `from` and `to` are both non-zero, `amount` of ``from``'s tokens\\n * has been transferred to `to`.\\n * - when `from` is zero, `amount` tokens have been minted for `to`.\\n * - when `to` is zero, `amount` of ``from``'s tokens have been burned.\\n * - `from` and `to` are never both zero.\\n *\\n * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].\\n */\\n function _afterTokenTransfer(\\n address from,\\n address to,\\n uint256 amount\\n ) internal virtual {}\\n\\n /**\\n * @dev This empty reserved space is put in place to allow future versions to add new\\n * variables without shifting down storage in the inheritance chain.\\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\\n */\\n uint256[45] private __gap;\\n}\\n\",\"keccak256\":\"0x7c7ac0bc6c340a7f320524b9a4b4b079ee9da3c51258080d4bab237f329a427c\",\"license\":\"MIT\"},\"@openzeppelin/contracts-upgradeable/token/ERC20/IERC20Upgradeable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.6.0) (token/ERC20/IERC20.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Interface of the ERC20 standard as defined in the EIP.\\n */\\ninterface IERC20Upgradeable {\\n /**\\n * @dev Emitted when `value` tokens are moved from one account (`from`) to\\n * another (`to`).\\n *\\n * Note that `value` may be zero.\\n */\\n event Transfer(address indexed from, address indexed to, uint256 value);\\n\\n /**\\n * @dev Emitted when the allowance of a `spender` for an `owner` is set by\\n * a call to {approve}. `value` is the new allowance.\\n */\\n event Approval(address indexed owner, address indexed spender, uint256 value);\\n\\n /**\\n * @dev Returns the amount of tokens in existence.\\n */\\n function totalSupply() external view returns (uint256);\\n\\n /**\\n * @dev Returns the amount of tokens owned by `account`.\\n */\\n function balanceOf(address account) external view returns (uint256);\\n\\n /**\\n * @dev Moves `amount` tokens from the caller's account to `to`.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * Emits a {Transfer} event.\\n */\\n function transfer(address to, uint256 amount) external returns (bool);\\n\\n /**\\n * @dev Returns the remaining number of tokens that `spender` will be\\n * allowed to spend on behalf of `owner` through {transferFrom}. This is\\n * zero by default.\\n *\\n * This value changes when {approve} or {transferFrom} are called.\\n */\\n function allowance(address owner, address spender) external view returns (uint256);\\n\\n /**\\n * @dev Sets `amount` as the allowance of `spender` over the caller's tokens.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * IMPORTANT: Beware that changing an allowance with this method brings the risk\\n * that someone may use both the old and the new allowance by unfortunate\\n * transaction ordering. One possible solution to mitigate this race\\n * condition is to first reduce the spender's allowance to 0 and set the\\n * desired value afterwards:\\n * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729\\n *\\n * Emits an {Approval} event.\\n */\\n function approve(address spender, uint256 amount) external returns (bool);\\n\\n /**\\n * @dev Moves `amount` tokens from `from` to `to` using the\\n * allowance mechanism. `amount` is then deducted from the caller's\\n * allowance.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * Emits a {Transfer} event.\\n */\\n function transferFrom(\\n address from,\\n address to,\\n uint256 amount\\n ) external returns (bool);\\n}\\n\",\"keccak256\":\"0x4e733d3164f73f461eaf9d8087a7ad1ea180bdc8ba0d3d61b0e1ae16d8e63dff\",\"license\":\"MIT\"},\"@openzeppelin/contracts-upgradeable/token/ERC20/extensions/IERC20MetadataUpgradeable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (token/ERC20/extensions/IERC20Metadata.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../IERC20Upgradeable.sol\\\";\\n\\n/**\\n * @dev Interface for the optional metadata functions from the ERC20 standard.\\n *\\n * _Available since v4.1._\\n */\\ninterface IERC20MetadataUpgradeable is IERC20Upgradeable {\\n /**\\n * @dev Returns the name of the token.\\n */\\n function name() external view returns (string memory);\\n\\n /**\\n * @dev Returns the symbol of the token.\\n */\\n function symbol() external view returns (string memory);\\n\\n /**\\n * @dev Returns the decimals places of the token.\\n */\\n function decimals() external view returns (uint8);\\n}\\n\",\"keccak256\":\"0x605434219ebbe4653f703640f06969faa5a1d78f0bfef878e5ddbb1ca369ceeb\",\"license\":\"MIT\"},\"@openzeppelin/contracts-upgradeable/token/ERC20/extensions/draft-ERC20PermitUpgradeable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.6.0) (token/ERC20/extensions/draft-ERC20Permit.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"./draft-IERC20PermitUpgradeable.sol\\\";\\nimport \\\"../ERC20Upgradeable.sol\\\";\\nimport \\\"../../../utils/cryptography/draft-EIP712Upgradeable.sol\\\";\\nimport \\\"../../../utils/cryptography/ECDSAUpgradeable.sol\\\";\\nimport \\\"../../../utils/CountersUpgradeable.sol\\\";\\nimport \\\"../../../proxy/utils/Initializable.sol\\\";\\n\\n/**\\n * @dev Implementation of the ERC20 Permit extension allowing approvals to be made via signatures, as defined in\\n * https://eips.ethereum.org/EIPS/eip-2612[EIP-2612].\\n *\\n * Adds the {permit} method, which can be used to change an account's ERC20 allowance (see {IERC20-allowance}) by\\n * presenting a message signed by the account. By not relying on `{IERC20-approve}`, the token holder account doesn't\\n * need to send a transaction, and thus is not required to hold Ether at all.\\n *\\n * _Available since v3.4._\\n *\\n * @custom:storage-size 51\\n */\\nabstract contract ERC20PermitUpgradeable is Initializable, ERC20Upgradeable, IERC20PermitUpgradeable, EIP712Upgradeable {\\n using CountersUpgradeable for CountersUpgradeable.Counter;\\n\\n mapping(address => CountersUpgradeable.Counter) private _nonces;\\n\\n // solhint-disable-next-line var-name-mixedcase\\n bytes32 private constant _PERMIT_TYPEHASH =\\n keccak256(\\\"Permit(address owner,address spender,uint256 value,uint256 nonce,uint256 deadline)\\\");\\n /**\\n * @dev In previous versions `_PERMIT_TYPEHASH` was declared as `immutable`.\\n * However, to ensure consistency with the upgradeable transpiler, we will continue\\n * to reserve a slot.\\n * @custom:oz-renamed-from _PERMIT_TYPEHASH\\n */\\n // solhint-disable-next-line var-name-mixedcase\\n bytes32 private _PERMIT_TYPEHASH_DEPRECATED_SLOT;\\n\\n /**\\n * @dev Initializes the {EIP712} domain separator using the `name` parameter, and setting `version` to `\\\"1\\\"`.\\n *\\n * It's a good idea to use the same `name` that is defined as the ERC20 token name.\\n */\\n function __ERC20Permit_init(string memory name) internal onlyInitializing {\\n __EIP712_init_unchained(name, \\\"1\\\");\\n }\\n\\n function __ERC20Permit_init_unchained(string memory) internal onlyInitializing {}\\n\\n /**\\n * @dev See {IERC20Permit-permit}.\\n */\\n function permit(\\n address owner,\\n address spender,\\n uint256 value,\\n uint256 deadline,\\n uint8 v,\\n bytes32 r,\\n bytes32 s\\n ) public virtual override {\\n require(block.timestamp <= deadline, \\\"ERC20Permit: expired deadline\\\");\\n\\n bytes32 structHash = keccak256(abi.encode(_PERMIT_TYPEHASH, owner, spender, value, _useNonce(owner), deadline));\\n\\n bytes32 hash = _hashTypedDataV4(structHash);\\n\\n address signer = ECDSAUpgradeable.recover(hash, v, r, s);\\n require(signer == owner, \\\"ERC20Permit: invalid signature\\\");\\n\\n _approve(owner, spender, value);\\n }\\n\\n /**\\n * @dev See {IERC20Permit-nonces}.\\n */\\n function nonces(address owner) public view virtual override returns (uint256) {\\n return _nonces[owner].current();\\n }\\n\\n /**\\n * @dev See {IERC20Permit-DOMAIN_SEPARATOR}.\\n */\\n // solhint-disable-next-line func-name-mixedcase\\n function DOMAIN_SEPARATOR() external view override returns (bytes32) {\\n return _domainSeparatorV4();\\n }\\n\\n /**\\n * @dev \\\"Consume a nonce\\\": return the current value and increment.\\n *\\n * _Available since v4.1._\\n */\\n function _useNonce(address owner) internal virtual returns (uint256 current) {\\n CountersUpgradeable.Counter storage nonce = _nonces[owner];\\n current = nonce.current();\\n nonce.increment();\\n }\\n\\n /**\\n * @dev This empty reserved space is put in place to allow future versions to add new\\n * variables without shifting down storage in the inheritance chain.\\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\\n */\\n uint256[49] private __gap;\\n}\\n\",\"keccak256\":\"0x564385ebed633694decce3e13d687f3ac7e8eaef64f7a504bfb3f03ad210601f\",\"license\":\"MIT\"},\"@openzeppelin/contracts-upgradeable/token/ERC20/extensions/draft-IERC20PermitUpgradeable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (token/ERC20/extensions/draft-IERC20Permit.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Interface of the ERC20 Permit extension allowing approvals to be made via signatures, as defined in\\n * https://eips.ethereum.org/EIPS/eip-2612[EIP-2612].\\n *\\n * Adds the {permit} method, which can be used to change an account's ERC20 allowance (see {IERC20-allowance}) by\\n * presenting a message signed by the account. By not relying on {IERC20-approve}, the token holder account doesn't\\n * need to send a transaction, and thus is not required to hold Ether at all.\\n */\\ninterface IERC20PermitUpgradeable {\\n /**\\n * @dev Sets `value` as the allowance of `spender` over ``owner``'s tokens,\\n * given ``owner``'s signed approval.\\n *\\n * IMPORTANT: The same issues {IERC20-approve} has related to transaction\\n * ordering also apply here.\\n *\\n * Emits an {Approval} event.\\n *\\n * Requirements:\\n *\\n * - `spender` cannot be the zero address.\\n * - `deadline` must be a timestamp in the future.\\n * - `v`, `r` and `s` must be a valid `secp256k1` signature from `owner`\\n * over the EIP712-formatted function arguments.\\n * - the signature must use ``owner``'s current nonce (see {nonces}).\\n *\\n * For more information on the signature format, see the\\n * https://eips.ethereum.org/EIPS/eip-2612#specification[relevant EIP\\n * section].\\n */\\n function permit(\\n address owner,\\n address spender,\\n uint256 value,\\n uint256 deadline,\\n uint8 v,\\n bytes32 r,\\n bytes32 s\\n ) external;\\n\\n /**\\n * @dev Returns the current nonce for `owner`. This value must be\\n * included whenever a signature is generated for {permit}.\\n *\\n * Every successful call to {permit} increases ``owner``'s nonce by one. This\\n * prevents a signature from being used multiple times.\\n */\\n function nonces(address owner) external view returns (uint256);\\n\\n /**\\n * @dev Returns the domain separator used in the encoding of the signature for {permit}, as defined by {EIP712}.\\n */\\n // solhint-disable-next-line func-name-mixedcase\\n function DOMAIN_SEPARATOR() external view returns (bytes32);\\n}\\n\",\"keccak256\":\"0xcc70d8e2281fb3ff69e8ab242500f10142cd0a7fa8dd9e45882be270d4d09024\",\"license\":\"MIT\"},\"@openzeppelin/contracts-upgradeable/utils/AddressUpgradeable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.7.0) (utils/Address.sol)\\n\\npragma solidity ^0.8.1;\\n\\n/**\\n * @dev Collection of functions related to the address type\\n */\\nlibrary AddressUpgradeable {\\n /**\\n * @dev Returns true if `account` is a contract.\\n *\\n * [IMPORTANT]\\n * ====\\n * It is unsafe to assume that an address for which this function returns\\n * false is an externally-owned account (EOA) and not a contract.\\n *\\n * Among others, `isContract` will return false for the following\\n * types of addresses:\\n *\\n * - an externally-owned account\\n * - a contract in construction\\n * - an address where a contract will be created\\n * - an address where a contract lived, but was destroyed\\n * ====\\n *\\n * [IMPORTANT]\\n * ====\\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\\n *\\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\\n * constructor.\\n * ====\\n */\\n function isContract(address account) internal view returns (bool) {\\n // This method relies on extcodesize/address.code.length, which returns 0\\n // for contracts in construction, since the code is only stored at the end\\n // of the constructor execution.\\n\\n return account.code.length > 0;\\n }\\n\\n /**\\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\\n * `recipient`, forwarding all available gas and reverting on errors.\\n *\\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\\n * imposed by `transfer`, making them unable to receive funds via\\n * `transfer`. {sendValue} removes this limitation.\\n *\\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\\n *\\n * IMPORTANT: because control is transferred to `recipient`, care must be\\n * taken to not create reentrancy vulnerabilities. Consider using\\n * {ReentrancyGuard} or the\\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\\n */\\n function sendValue(address payable recipient, uint256 amount) internal {\\n require(address(this).balance >= amount, \\\"Address: insufficient balance\\\");\\n\\n (bool success, ) = recipient.call{value: amount}(\\\"\\\");\\n require(success, \\\"Address: unable to send value, recipient may have reverted\\\");\\n }\\n\\n /**\\n * @dev Performs a Solidity function call using a low level `call`. A\\n * plain `call` is an unsafe replacement for a function call: use this\\n * function instead.\\n *\\n * If `target` reverts with a revert reason, it is bubbled up by this\\n * function (like regular Solidity function calls).\\n *\\n * Returns the raw returned data. To convert to the expected return value,\\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\\n *\\n * Requirements:\\n *\\n * - `target` must be a contract.\\n * - calling `target` with `data` must not revert.\\n *\\n * _Available since v3.1._\\n */\\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\\n return functionCall(target, data, \\\"Address: low-level call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\\n * `errorMessage` as a fallback revert reason when `target` reverts.\\n *\\n * _Available since v3.1._\\n */\\n function functionCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n return functionCallWithValue(target, data, 0, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but also transferring `value` wei to `target`.\\n *\\n * Requirements:\\n *\\n * - the calling contract must have an ETH balance of at least `value`.\\n * - the called Solidity function must be `payable`.\\n *\\n * _Available since v3.1._\\n */\\n function functionCallWithValue(\\n address target,\\n bytes memory data,\\n uint256 value\\n ) internal returns (bytes memory) {\\n return functionCallWithValue(target, data, value, \\\"Address: low-level call with value failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\\n * with `errorMessage` as a fallback revert reason when `target` reverts.\\n *\\n * _Available since v3.1._\\n */\\n function functionCallWithValue(\\n address target,\\n bytes memory data,\\n uint256 value,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n require(address(this).balance >= value, \\\"Address: insufficient balance for call\\\");\\n require(isContract(target), \\\"Address: call to non-contract\\\");\\n\\n (bool success, bytes memory returndata) = target.call{value: value}(data);\\n return verifyCallResult(success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but performing a static call.\\n *\\n * _Available since v3.3._\\n */\\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\\n return functionStaticCall(target, data, \\\"Address: low-level static call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\\n * but performing a static call.\\n *\\n * _Available since v3.3._\\n */\\n function functionStaticCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal view returns (bytes memory) {\\n require(isContract(target), \\\"Address: static call to non-contract\\\");\\n\\n (bool success, bytes memory returndata) = target.staticcall(data);\\n return verifyCallResult(success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the\\n * revert reason using the provided one.\\n *\\n * _Available since v4.3._\\n */\\n function verifyCallResult(\\n bool success,\\n bytes memory returndata,\\n string memory errorMessage\\n ) internal pure returns (bytes memory) {\\n if (success) {\\n return returndata;\\n } else {\\n // Look for revert reason and bubble it up if present\\n if (returndata.length > 0) {\\n // The easiest way to bubble the revert reason is using memory via assembly\\n /// @solidity memory-safe-assembly\\n assembly {\\n let returndata_size := mload(returndata)\\n revert(add(32, returndata), returndata_size)\\n }\\n } else {\\n revert(errorMessage);\\n }\\n }\\n }\\n}\\n\",\"keccak256\":\"0x611aa3f23e59cfdd1863c536776407b3e33d695152a266fa7cfb34440a29a8a3\",\"license\":\"MIT\"},\"@openzeppelin/contracts-upgradeable/utils/ContextUpgradeable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)\\n\\npragma solidity ^0.8.0;\\nimport \\\"../proxy/utils/Initializable.sol\\\";\\n\\n/**\\n * @dev Provides information about the current execution context, including the\\n * sender of the transaction and its data. While these are generally available\\n * via msg.sender and msg.data, they should not be accessed in such a direct\\n * manner, since when dealing with meta-transactions the account sending and\\n * paying for execution may not be the actual sender (as far as an application\\n * is concerned).\\n *\\n * This contract is only required for intermediate, library-like contracts.\\n */\\nabstract contract ContextUpgradeable is Initializable {\\n function __Context_init() internal onlyInitializing {\\n }\\n\\n function __Context_init_unchained() internal onlyInitializing {\\n }\\n function _msgSender() internal view virtual returns (address) {\\n return msg.sender;\\n }\\n\\n function _msgData() internal view virtual returns (bytes calldata) {\\n return msg.data;\\n }\\n\\n /**\\n * @dev This empty reserved space is put in place to allow future versions to add new\\n * variables without shifting down storage in the inheritance chain.\\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\\n */\\n uint256[50] private __gap;\\n}\\n\",\"keccak256\":\"0x963ea7f0b48b032eef72fe3a7582edf78408d6f834115b9feadd673a4d5bd149\",\"license\":\"MIT\"},\"@openzeppelin/contracts-upgradeable/utils/CountersUpgradeable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (utils/Counters.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @title Counters\\n * @author Matt Condon (@shrugs)\\n * @dev Provides counters that can only be incremented, decremented or reset. This can be used e.g. to track the number\\n * of elements in a mapping, issuing ERC721 ids, or counting request ids.\\n *\\n * Include with `using Counters for Counters.Counter;`\\n */\\nlibrary CountersUpgradeable {\\n struct Counter {\\n // This variable should never be directly accessed by users of the library: interactions must be restricted to\\n // the library's function. As of Solidity v0.5.2, this cannot be enforced, though there is a proposal to add\\n // this feature: see https://github.com/ethereum/solidity/issues/4637\\n uint256 _value; // default: 0\\n }\\n\\n function current(Counter storage counter) internal view returns (uint256) {\\n return counter._value;\\n }\\n\\n function increment(Counter storage counter) internal {\\n unchecked {\\n counter._value += 1;\\n }\\n }\\n\\n function decrement(Counter storage counter) internal {\\n uint256 value = counter._value;\\n require(value > 0, \\\"Counter: decrement overflow\\\");\\n unchecked {\\n counter._value = value - 1;\\n }\\n }\\n\\n function reset(Counter storage counter) internal {\\n counter._value = 0;\\n }\\n}\\n\",\"keccak256\":\"0x798741e231b22b81e2dd2eddaaf8832dee4baf5cd8e2dbaa5c1dd12a1c053c4d\",\"license\":\"MIT\"},\"@openzeppelin/contracts-upgradeable/utils/StringsUpgradeable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.7.0) (utils/Strings.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev String operations.\\n */\\nlibrary StringsUpgradeable {\\n bytes16 private constant _HEX_SYMBOLS = \\\"0123456789abcdef\\\";\\n uint8 private constant _ADDRESS_LENGTH = 20;\\n\\n /**\\n * @dev Converts a `uint256` to its ASCII `string` decimal representation.\\n */\\n function toString(uint256 value) internal pure returns (string memory) {\\n // Inspired by OraclizeAPI's implementation - MIT licence\\n // https://github.com/oraclize/ethereum-api/blob/b42146b063c7d6ee1358846c198246239e9360e8/oraclizeAPI_0.4.25.sol\\n\\n if (value == 0) {\\n return \\\"0\\\";\\n }\\n uint256 temp = value;\\n uint256 digits;\\n while (temp != 0) {\\n digits++;\\n temp /= 10;\\n }\\n bytes memory buffer = new bytes(digits);\\n while (value != 0) {\\n digits -= 1;\\n buffer[digits] = bytes1(uint8(48 + uint256(value % 10)));\\n value /= 10;\\n }\\n return string(buffer);\\n }\\n\\n /**\\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation.\\n */\\n function toHexString(uint256 value) internal pure returns (string memory) {\\n if (value == 0) {\\n return \\\"0x00\\\";\\n }\\n uint256 temp = value;\\n uint256 length = 0;\\n while (temp != 0) {\\n length++;\\n temp >>= 8;\\n }\\n return toHexString(value, length);\\n }\\n\\n /**\\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length.\\n */\\n function toHexString(uint256 value, uint256 length) internal pure returns (string memory) {\\n bytes memory buffer = new bytes(2 * length + 2);\\n buffer[0] = \\\"0\\\";\\n buffer[1] = \\\"x\\\";\\n for (uint256 i = 2 * length + 1; i > 1; --i) {\\n buffer[i] = _HEX_SYMBOLS[value & 0xf];\\n value >>= 4;\\n }\\n require(value == 0, \\\"Strings: hex length insufficient\\\");\\n return string(buffer);\\n }\\n\\n /**\\n * @dev Converts an `address` with fixed length of 20 bytes to its not checksummed ASCII `string` hexadecimal representation.\\n */\\n function toHexString(address addr) internal pure returns (string memory) {\\n return toHexString(uint256(uint160(addr)), _ADDRESS_LENGTH);\\n }\\n}\\n\",\"keccak256\":\"0xea5339a7fff0ed42b45be56a88efdd0b2ddde9fa480dc99fef9a6a4c5b776863\",\"license\":\"MIT\"},\"@openzeppelin/contracts-upgradeable/utils/cryptography/ECDSAUpgradeable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.7.0) (utils/cryptography/ECDSA.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../StringsUpgradeable.sol\\\";\\n\\n/**\\n * @dev Elliptic Curve Digital Signature Algorithm (ECDSA) operations.\\n *\\n * These functions can be used to verify that a message was signed by the holder\\n * of the private keys of a given address.\\n */\\nlibrary ECDSAUpgradeable {\\n enum RecoverError {\\n NoError,\\n InvalidSignature,\\n InvalidSignatureLength,\\n InvalidSignatureS,\\n InvalidSignatureV\\n }\\n\\n function _throwError(RecoverError error) private pure {\\n if (error == RecoverError.NoError) {\\n return; // no error: do nothing\\n } else if (error == RecoverError.InvalidSignature) {\\n revert(\\\"ECDSA: invalid signature\\\");\\n } else if (error == RecoverError.InvalidSignatureLength) {\\n revert(\\\"ECDSA: invalid signature length\\\");\\n } else if (error == RecoverError.InvalidSignatureS) {\\n revert(\\\"ECDSA: invalid signature 's' value\\\");\\n } else if (error == RecoverError.InvalidSignatureV) {\\n revert(\\\"ECDSA: invalid signature 'v' value\\\");\\n }\\n }\\n\\n /**\\n * @dev Returns the address that signed a hashed message (`hash`) with\\n * `signature` or error string. This address can then be used for verification purposes.\\n *\\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\\n * this function rejects them by requiring the `s` value to be in the lower\\n * half order, and the `v` value to be either 27 or 28.\\n *\\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\\n * verification to be secure: it is possible to craft signatures that\\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\\n * this is by receiving a hash of the original message (which may otherwise\\n * be too long), and then calling {toEthSignedMessageHash} on it.\\n *\\n * Documentation for signature generation:\\n * - with https://web3js.readthedocs.io/en/v1.3.4/web3-eth-accounts.html#sign[Web3.js]\\n * - with https://docs.ethers.io/v5/api/signer/#Signer-signMessage[ethers]\\n *\\n * _Available since v4.3._\\n */\\n function tryRecover(bytes32 hash, bytes memory signature) internal pure returns (address, RecoverError) {\\n // Check the signature length\\n // - case 65: r,s,v signature (standard)\\n // - case 64: r,vs signature (cf https://eips.ethereum.org/EIPS/eip-2098) _Available since v4.1._\\n if (signature.length == 65) {\\n bytes32 r;\\n bytes32 s;\\n uint8 v;\\n // ecrecover takes the signature parameters, and the only way to get them\\n // currently is to use assembly.\\n /// @solidity memory-safe-assembly\\n assembly {\\n r := mload(add(signature, 0x20))\\n s := mload(add(signature, 0x40))\\n v := byte(0, mload(add(signature, 0x60)))\\n }\\n return tryRecover(hash, v, r, s);\\n } else if (signature.length == 64) {\\n bytes32 r;\\n bytes32 vs;\\n // ecrecover takes the signature parameters, and the only way to get them\\n // currently is to use assembly.\\n /// @solidity memory-safe-assembly\\n assembly {\\n r := mload(add(signature, 0x20))\\n vs := mload(add(signature, 0x40))\\n }\\n return tryRecover(hash, r, vs);\\n } else {\\n return (address(0), RecoverError.InvalidSignatureLength);\\n }\\n }\\n\\n /**\\n * @dev Returns the address that signed a hashed message (`hash`) with\\n * `signature`. This address can then be used for verification purposes.\\n *\\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\\n * this function rejects them by requiring the `s` value to be in the lower\\n * half order, and the `v` value to be either 27 or 28.\\n *\\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\\n * verification to be secure: it is possible to craft signatures that\\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\\n * this is by receiving a hash of the original message (which may otherwise\\n * be too long), and then calling {toEthSignedMessageHash} on it.\\n */\\n function recover(bytes32 hash, bytes memory signature) internal pure returns (address) {\\n (address recovered, RecoverError error) = tryRecover(hash, signature);\\n _throwError(error);\\n return recovered;\\n }\\n\\n /**\\n * @dev Overload of {ECDSA-tryRecover} that receives the `r` and `vs` short-signature fields separately.\\n *\\n * See https://eips.ethereum.org/EIPS/eip-2098[EIP-2098 short signatures]\\n *\\n * _Available since v4.3._\\n */\\n function tryRecover(\\n bytes32 hash,\\n bytes32 r,\\n bytes32 vs\\n ) internal pure returns (address, RecoverError) {\\n bytes32 s = vs & bytes32(0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff);\\n uint8 v = uint8((uint256(vs) >> 255) + 27);\\n return tryRecover(hash, v, r, s);\\n }\\n\\n /**\\n * @dev Overload of {ECDSA-recover} that receives the `r and `vs` short-signature fields separately.\\n *\\n * _Available since v4.2._\\n */\\n function recover(\\n bytes32 hash,\\n bytes32 r,\\n bytes32 vs\\n ) internal pure returns (address) {\\n (address recovered, RecoverError error) = tryRecover(hash, r, vs);\\n _throwError(error);\\n return recovered;\\n }\\n\\n /**\\n * @dev Overload of {ECDSA-tryRecover} that receives the `v`,\\n * `r` and `s` signature fields separately.\\n *\\n * _Available since v4.3._\\n */\\n function tryRecover(\\n bytes32 hash,\\n uint8 v,\\n bytes32 r,\\n bytes32 s\\n ) internal pure returns (address, RecoverError) {\\n // EIP-2 still allows signature malleability for ecrecover(). Remove this possibility and make the signature\\n // unique. Appendix F in the Ethereum Yellow paper (https://ethereum.github.io/yellowpaper/paper.pdf), defines\\n // the valid range for s in (301): 0 < s < secp256k1n \\u00f7 2 + 1, and for v in (302): v \\u2208 {27, 28}. Most\\n // signatures from current libraries generate a unique signature with an s-value in the lower half order.\\n //\\n // If your library generates malleable signatures, such as s-values in the upper range, calculate a new s-value\\n // with 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141 - s1 and flip v from 27 to 28 or\\n // vice versa. If your library also generates signatures with 0/1 for v instead 27/28, add 27 to v to accept\\n // these malleable signatures as well.\\n if (uint256(s) > 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D576E7357A4501DDFE92F46681B20A0) {\\n return (address(0), RecoverError.InvalidSignatureS);\\n }\\n if (v != 27 && v != 28) {\\n return (address(0), RecoverError.InvalidSignatureV);\\n }\\n\\n // If the signature is valid (and not malleable), return the signer address\\n address signer = ecrecover(hash, v, r, s);\\n if (signer == address(0)) {\\n return (address(0), RecoverError.InvalidSignature);\\n }\\n\\n return (signer, RecoverError.NoError);\\n }\\n\\n /**\\n * @dev Overload of {ECDSA-recover} that receives the `v`,\\n * `r` and `s` signature fields separately.\\n */\\n function recover(\\n bytes32 hash,\\n uint8 v,\\n bytes32 r,\\n bytes32 s\\n ) internal pure returns (address) {\\n (address recovered, RecoverError error) = tryRecover(hash, v, r, s);\\n _throwError(error);\\n return recovered;\\n }\\n\\n /**\\n * @dev Returns an Ethereum Signed Message, created from a `hash`. This\\n * produces hash corresponding to the one signed with the\\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\\n * JSON-RPC method as part of EIP-191.\\n *\\n * See {recover}.\\n */\\n function toEthSignedMessageHash(bytes32 hash) internal pure returns (bytes32) {\\n // 32 is the length in bytes of hash,\\n // enforced by the type signature above\\n return keccak256(abi.encodePacked(\\\"\\\\x19Ethereum Signed Message:\\\\n32\\\", hash));\\n }\\n\\n /**\\n * @dev Returns an Ethereum Signed Message, created from `s`. This\\n * produces hash corresponding to the one signed with the\\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\\n * JSON-RPC method as part of EIP-191.\\n *\\n * See {recover}.\\n */\\n function toEthSignedMessageHash(bytes memory s) internal pure returns (bytes32) {\\n return keccak256(abi.encodePacked(\\\"\\\\x19Ethereum Signed Message:\\\\n\\\", StringsUpgradeable.toString(s.length), s));\\n }\\n\\n /**\\n * @dev Returns an Ethereum Signed Typed Data, created from a\\n * `domainSeparator` and a `structHash`. This produces hash corresponding\\n * to the one signed with the\\n * https://eips.ethereum.org/EIPS/eip-712[`eth_signTypedData`]\\n * JSON-RPC method as part of EIP-712.\\n *\\n * See {recover}.\\n */\\n function toTypedDataHash(bytes32 domainSeparator, bytes32 structHash) internal pure returns (bytes32) {\\n return keccak256(abi.encodePacked(\\\"\\\\x19\\\\x01\\\", domainSeparator, structHash));\\n }\\n}\\n\",\"keccak256\":\"0xe8c62ca00ed2d0a4d9b7e3c4bf7d62c821618b2cdb3c844da91a1193986851bf\",\"license\":\"MIT\"},\"@openzeppelin/contracts-upgradeable/utils/cryptography/draft-EIP712Upgradeable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (utils/cryptography/draft-EIP712.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"./ECDSAUpgradeable.sol\\\";\\nimport \\\"../../proxy/utils/Initializable.sol\\\";\\n\\n/**\\n * @dev https://eips.ethereum.org/EIPS/eip-712[EIP 712] is a standard for hashing and signing of typed structured data.\\n *\\n * The encoding specified in the EIP is very generic, and such a generic implementation in Solidity is not feasible,\\n * thus this contract does not implement the encoding itself. Protocols need to implement the type-specific encoding\\n * they need in their contracts using a combination of `abi.encode` and `keccak256`.\\n *\\n * This contract implements the EIP 712 domain separator ({_domainSeparatorV4}) that is used as part of the encoding\\n * scheme, and the final step of the encoding to obtain the message digest that is then signed via ECDSA\\n * ({_hashTypedDataV4}).\\n *\\n * The implementation of the domain separator was designed to be as efficient as possible while still properly updating\\n * the chain id to protect against replay attacks on an eventual fork of the chain.\\n *\\n * NOTE: This contract implements the version of the encoding known as \\\"v4\\\", as implemented by the JSON RPC method\\n * https://docs.metamask.io/guide/signing-data.html[`eth_signTypedDataV4` in MetaMask].\\n *\\n * _Available since v3.4._\\n *\\n * @custom:storage-size 52\\n */\\nabstract contract EIP712Upgradeable is Initializable {\\n /* solhint-disable var-name-mixedcase */\\n bytes32 private _HASHED_NAME;\\n bytes32 private _HASHED_VERSION;\\n bytes32 private constant _TYPE_HASH = keccak256(\\\"EIP712Domain(string name,string version,uint256 chainId,address verifyingContract)\\\");\\n\\n /* solhint-enable var-name-mixedcase */\\n\\n /**\\n * @dev Initializes the domain separator and parameter caches.\\n *\\n * The meaning of `name` and `version` is specified in\\n * https://eips.ethereum.org/EIPS/eip-712#definition-of-domainseparator[EIP 712]:\\n *\\n * - `name`: the user readable name of the signing domain, i.e. the name of the DApp or the protocol.\\n * - `version`: the current major version of the signing domain.\\n *\\n * NOTE: These parameters cannot be changed except through a xref:learn::upgrading-smart-contracts.adoc[smart\\n * contract upgrade].\\n */\\n function __EIP712_init(string memory name, string memory version) internal onlyInitializing {\\n __EIP712_init_unchained(name, version);\\n }\\n\\n function __EIP712_init_unchained(string memory name, string memory version) internal onlyInitializing {\\n bytes32 hashedName = keccak256(bytes(name));\\n bytes32 hashedVersion = keccak256(bytes(version));\\n _HASHED_NAME = hashedName;\\n _HASHED_VERSION = hashedVersion;\\n }\\n\\n /**\\n * @dev Returns the domain separator for the current chain.\\n */\\n function _domainSeparatorV4() internal view returns (bytes32) {\\n return _buildDomainSeparator(_TYPE_HASH, _EIP712NameHash(), _EIP712VersionHash());\\n }\\n\\n function _buildDomainSeparator(\\n bytes32 typeHash,\\n bytes32 nameHash,\\n bytes32 versionHash\\n ) private view returns (bytes32) {\\n return keccak256(abi.encode(typeHash, nameHash, versionHash, block.chainid, address(this)));\\n }\\n\\n /**\\n * @dev Given an already https://eips.ethereum.org/EIPS/eip-712#definition-of-hashstruct[hashed struct], this\\n * function returns the hash of the fully encoded EIP712 message for this domain.\\n *\\n * This hash can be used together with {ECDSA-recover} to obtain the signer of a message. For example:\\n *\\n * ```solidity\\n * bytes32 digest = _hashTypedDataV4(keccak256(abi.encode(\\n * keccak256(\\\"Mail(address to,string contents)\\\"),\\n * mailTo,\\n * keccak256(bytes(mailContents))\\n * )));\\n * address signer = ECDSA.recover(digest, signature);\\n * ```\\n */\\n function _hashTypedDataV4(bytes32 structHash) internal view virtual returns (bytes32) {\\n return ECDSAUpgradeable.toTypedDataHash(_domainSeparatorV4(), structHash);\\n }\\n\\n /**\\n * @dev The hash of the name parameter for the EIP712 domain.\\n *\\n * NOTE: This function reads from storage by default, but can be redefined to return a constant value if gas costs\\n * are a concern.\\n */\\n function _EIP712NameHash() internal virtual view returns (bytes32) {\\n return _HASHED_NAME;\\n }\\n\\n /**\\n * @dev The hash of the version parameter for the EIP712 domain.\\n *\\n * NOTE: This function reads from storage by default, but can be redefined to return a constant value if gas costs\\n * are a concern.\\n */\\n function _EIP712VersionHash() internal virtual view returns (bytes32) {\\n return _HASHED_VERSION;\\n }\\n\\n /**\\n * @dev This empty reserved space is put in place to allow future versions to add new\\n * variables without shifting down storage in the inheritance chain.\\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\\n */\\n uint256[50] private __gap;\\n}\\n\",\"keccak256\":\"0xaf5a96100f421d61693605349511e43221d3c2e47d4b3efa87af2b936e2567fc\",\"license\":\"MIT\"},\"@openzeppelin/contracts/token/ERC20/IERC20.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.6.0) (token/ERC20/IERC20.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Interface of the ERC20 standard as defined in the EIP.\\n */\\ninterface IERC20 {\\n /**\\n * @dev Emitted when `value` tokens are moved from one account (`from`) to\\n * another (`to`).\\n *\\n * Note that `value` may be zero.\\n */\\n event Transfer(address indexed from, address indexed to, uint256 value);\\n\\n /**\\n * @dev Emitted when the allowance of a `spender` for an `owner` is set by\\n * a call to {approve}. `value` is the new allowance.\\n */\\n event Approval(address indexed owner, address indexed spender, uint256 value);\\n\\n /**\\n * @dev Returns the amount of tokens in existence.\\n */\\n function totalSupply() external view returns (uint256);\\n\\n /**\\n * @dev Returns the amount of tokens owned by `account`.\\n */\\n function balanceOf(address account) external view returns (uint256);\\n\\n /**\\n * @dev Moves `amount` tokens from the caller's account to `to`.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * Emits a {Transfer} event.\\n */\\n function transfer(address to, uint256 amount) external returns (bool);\\n\\n /**\\n * @dev Returns the remaining number of tokens that `spender` will be\\n * allowed to spend on behalf of `owner` through {transferFrom}. This is\\n * zero by default.\\n *\\n * This value changes when {approve} or {transferFrom} are called.\\n */\\n function allowance(address owner, address spender) external view returns (uint256);\\n\\n /**\\n * @dev Sets `amount` as the allowance of `spender` over the caller's tokens.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * IMPORTANT: Beware that changing an allowance with this method brings the risk\\n * that someone may use both the old and the new allowance by unfortunate\\n * transaction ordering. One possible solution to mitigate this race\\n * condition is to first reduce the spender's allowance to 0 and set the\\n * desired value afterwards:\\n * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729\\n *\\n * Emits an {Approval} event.\\n */\\n function approve(address spender, uint256 amount) external returns (bool);\\n\\n /**\\n * @dev Moves `amount` tokens from `from` to `to` using the\\n * allowance mechanism. `amount` is then deducted from the caller's\\n * allowance.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * Emits a {Transfer} event.\\n */\\n function transferFrom(\\n address from,\\n address to,\\n uint256 amount\\n ) external returns (bool);\\n}\\n\",\"keccak256\":\"0x9750c6b834f7b43000631af5cc30001c5f547b3ceb3635488f140f60e897ea6b\",\"license\":\"MIT\"},\"@openzeppelin/contracts/token/ERC20/extensions/draft-IERC20Permit.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (token/ERC20/extensions/draft-IERC20Permit.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Interface of the ERC20 Permit extension allowing approvals to be made via signatures, as defined in\\n * https://eips.ethereum.org/EIPS/eip-2612[EIP-2612].\\n *\\n * Adds the {permit} method, which can be used to change an account's ERC20 allowance (see {IERC20-allowance}) by\\n * presenting a message signed by the account. By not relying on {IERC20-approve}, the token holder account doesn't\\n * need to send a transaction, and thus is not required to hold Ether at all.\\n */\\ninterface IERC20Permit {\\n /**\\n * @dev Sets `value` as the allowance of `spender` over ``owner``'s tokens,\\n * given ``owner``'s signed approval.\\n *\\n * IMPORTANT: The same issues {IERC20-approve} has related to transaction\\n * ordering also apply here.\\n *\\n * Emits an {Approval} event.\\n *\\n * Requirements:\\n *\\n * - `spender` cannot be the zero address.\\n * - `deadline` must be a timestamp in the future.\\n * - `v`, `r` and `s` must be a valid `secp256k1` signature from `owner`\\n * over the EIP712-formatted function arguments.\\n * - the signature must use ``owner``'s current nonce (see {nonces}).\\n *\\n * For more information on the signature format, see the\\n * https://eips.ethereum.org/EIPS/eip-2612#specification[relevant EIP\\n * section].\\n */\\n function permit(\\n address owner,\\n address spender,\\n uint256 value,\\n uint256 deadline,\\n uint8 v,\\n bytes32 r,\\n bytes32 s\\n ) external;\\n\\n /**\\n * @dev Returns the current nonce for `owner`. This value must be\\n * included whenever a signature is generated for {permit}.\\n *\\n * Every successful call to {permit} increases ``owner``'s nonce by one. This\\n * prevents a signature from being used multiple times.\\n */\\n function nonces(address owner) external view returns (uint256);\\n\\n /**\\n * @dev Returns the domain separator used in the encoding of the signature for {permit}, as defined by {EIP712}.\\n */\\n // solhint-disable-next-line func-name-mixedcase\\n function DOMAIN_SEPARATOR() external view returns (bytes32);\\n}\\n\",\"keccak256\":\"0xf41ca991f30855bf80ffd11e9347856a517b977f0a6c2d52e6421a99b7840329\",\"license\":\"MIT\"},\"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.7.0) (token/ERC20/utils/SafeERC20.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../IERC20.sol\\\";\\nimport \\\"../extensions/draft-IERC20Permit.sol\\\";\\nimport \\\"../../../utils/Address.sol\\\";\\n\\n/**\\n * @title SafeERC20\\n * @dev Wrappers around ERC20 operations that throw on failure (when the token\\n * contract returns false). Tokens that return no value (and instead revert or\\n * throw on failure) are also supported, non-reverting calls are assumed to be\\n * successful.\\n * To use this library you can add a `using SafeERC20 for IERC20;` statement to your contract,\\n * which allows you to call the safe operations as `token.safeTransfer(...)`, etc.\\n */\\nlibrary SafeERC20 {\\n using Address for address;\\n\\n function safeTransfer(\\n IERC20 token,\\n address to,\\n uint256 value\\n ) internal {\\n _callOptionalReturn(token, abi.encodeWithSelector(token.transfer.selector, to, value));\\n }\\n\\n function safeTransferFrom(\\n IERC20 token,\\n address from,\\n address to,\\n uint256 value\\n ) internal {\\n _callOptionalReturn(token, abi.encodeWithSelector(token.transferFrom.selector, from, to, value));\\n }\\n\\n /**\\n * @dev Deprecated. This function has issues similar to the ones found in\\n * {IERC20-approve}, and its usage is discouraged.\\n *\\n * Whenever possible, use {safeIncreaseAllowance} and\\n * {safeDecreaseAllowance} instead.\\n */\\n function safeApprove(\\n IERC20 token,\\n address spender,\\n uint256 value\\n ) internal {\\n // safeApprove should only be called when setting an initial allowance,\\n // or when resetting it to zero. To increase and decrease it, use\\n // 'safeIncreaseAllowance' and 'safeDecreaseAllowance'\\n require(\\n (value == 0) || (token.allowance(address(this), spender) == 0),\\n \\\"SafeERC20: approve from non-zero to non-zero allowance\\\"\\n );\\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, value));\\n }\\n\\n function safeIncreaseAllowance(\\n IERC20 token,\\n address spender,\\n uint256 value\\n ) internal {\\n uint256 newAllowance = token.allowance(address(this), spender) + value;\\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));\\n }\\n\\n function safeDecreaseAllowance(\\n IERC20 token,\\n address spender,\\n uint256 value\\n ) internal {\\n unchecked {\\n uint256 oldAllowance = token.allowance(address(this), spender);\\n require(oldAllowance >= value, \\\"SafeERC20: decreased allowance below zero\\\");\\n uint256 newAllowance = oldAllowance - value;\\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));\\n }\\n }\\n\\n function safePermit(\\n IERC20Permit token,\\n address owner,\\n address spender,\\n uint256 value,\\n uint256 deadline,\\n uint8 v,\\n bytes32 r,\\n bytes32 s\\n ) internal {\\n uint256 nonceBefore = token.nonces(owner);\\n token.permit(owner, spender, value, deadline, v, r, s);\\n uint256 nonceAfter = token.nonces(owner);\\n require(nonceAfter == nonceBefore + 1, \\\"SafeERC20: permit did not succeed\\\");\\n }\\n\\n /**\\n * @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement\\n * on the return value: the return value is optional (but if data is returned, it must not be false).\\n * @param token The token targeted by the call.\\n * @param data The call data (encoded using abi.encode or one of its variants).\\n */\\n function _callOptionalReturn(IERC20 token, bytes memory data) private {\\n // We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since\\n // we're implementing it ourselves. We use {Address.functionCall} to perform this call, which verifies that\\n // the target address contains contract code and also asserts for success in the low-level call.\\n\\n bytes memory returndata = address(token).functionCall(data, \\\"SafeERC20: low-level call failed\\\");\\n if (returndata.length > 0) {\\n // Return data is optional\\n require(abi.decode(returndata, (bool)), \\\"SafeERC20: ERC20 operation did not succeed\\\");\\n }\\n }\\n}\\n\",\"keccak256\":\"0x032807210d1d7d218963d7355d62e021a84bf1b3339f4f50be2f63b53cccaf29\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/Address.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.7.0) (utils/Address.sol)\\n\\npragma solidity ^0.8.1;\\n\\n/**\\n * @dev Collection of functions related to the address type\\n */\\nlibrary Address {\\n /**\\n * @dev Returns true if `account` is a contract.\\n *\\n * [IMPORTANT]\\n * ====\\n * It is unsafe to assume that an address for which this function returns\\n * false is an externally-owned account (EOA) and not a contract.\\n *\\n * Among others, `isContract` will return false for the following\\n * types of addresses:\\n *\\n * - an externally-owned account\\n * - a contract in construction\\n * - an address where a contract will be created\\n * - an address where a contract lived, but was destroyed\\n * ====\\n *\\n * [IMPORTANT]\\n * ====\\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\\n *\\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\\n * constructor.\\n * ====\\n */\\n function isContract(address account) internal view returns (bool) {\\n // This method relies on extcodesize/address.code.length, which returns 0\\n // for contracts in construction, since the code is only stored at the end\\n // of the constructor execution.\\n\\n return account.code.length > 0;\\n }\\n\\n /**\\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\\n * `recipient`, forwarding all available gas and reverting on errors.\\n *\\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\\n * imposed by `transfer`, making them unable to receive funds via\\n * `transfer`. {sendValue} removes this limitation.\\n *\\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\\n *\\n * IMPORTANT: because control is transferred to `recipient`, care must be\\n * taken to not create reentrancy vulnerabilities. Consider using\\n * {ReentrancyGuard} or the\\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\\n */\\n function sendValue(address payable recipient, uint256 amount) internal {\\n require(address(this).balance >= amount, \\\"Address: insufficient balance\\\");\\n\\n (bool success, ) = recipient.call{value: amount}(\\\"\\\");\\n require(success, \\\"Address: unable to send value, recipient may have reverted\\\");\\n }\\n\\n /**\\n * @dev Performs a Solidity function call using a low level `call`. A\\n * plain `call` is an unsafe replacement for a function call: use this\\n * function instead.\\n *\\n * If `target` reverts with a revert reason, it is bubbled up by this\\n * function (like regular Solidity function calls).\\n *\\n * Returns the raw returned data. To convert to the expected return value,\\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\\n *\\n * Requirements:\\n *\\n * - `target` must be a contract.\\n * - calling `target` with `data` must not revert.\\n *\\n * _Available since v3.1._\\n */\\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\\n return functionCall(target, data, \\\"Address: low-level call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\\n * `errorMessage` as a fallback revert reason when `target` reverts.\\n *\\n * _Available since v3.1._\\n */\\n function functionCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n return functionCallWithValue(target, data, 0, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but also transferring `value` wei to `target`.\\n *\\n * Requirements:\\n *\\n * - the calling contract must have an ETH balance of at least `value`.\\n * - the called Solidity function must be `payable`.\\n *\\n * _Available since v3.1._\\n */\\n function functionCallWithValue(\\n address target,\\n bytes memory data,\\n uint256 value\\n ) internal returns (bytes memory) {\\n return functionCallWithValue(target, data, value, \\\"Address: low-level call with value failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\\n * with `errorMessage` as a fallback revert reason when `target` reverts.\\n *\\n * _Available since v3.1._\\n */\\n function functionCallWithValue(\\n address target,\\n bytes memory data,\\n uint256 value,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n require(address(this).balance >= value, \\\"Address: insufficient balance for call\\\");\\n require(isContract(target), \\\"Address: call to non-contract\\\");\\n\\n (bool success, bytes memory returndata) = target.call{value: value}(data);\\n return verifyCallResult(success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but performing a static call.\\n *\\n * _Available since v3.3._\\n */\\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\\n return functionStaticCall(target, data, \\\"Address: low-level static call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\\n * but performing a static call.\\n *\\n * _Available since v3.3._\\n */\\n function functionStaticCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal view returns (bytes memory) {\\n require(isContract(target), \\\"Address: static call to non-contract\\\");\\n\\n (bool success, bytes memory returndata) = target.staticcall(data);\\n return verifyCallResult(success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but performing a delegate call.\\n *\\n * _Available since v3.4._\\n */\\n function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {\\n return functionDelegateCall(target, data, \\\"Address: low-level delegate call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\\n * but performing a delegate call.\\n *\\n * _Available since v3.4._\\n */\\n function functionDelegateCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n require(isContract(target), \\\"Address: delegate call to non-contract\\\");\\n\\n (bool success, bytes memory returndata) = target.delegatecall(data);\\n return verifyCallResult(success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the\\n * revert reason using the provided one.\\n *\\n * _Available since v4.3._\\n */\\n function verifyCallResult(\\n bool success,\\n bytes memory returndata,\\n string memory errorMessage\\n ) internal pure returns (bytes memory) {\\n if (success) {\\n return returndata;\\n } else {\\n // Look for revert reason and bubble it up if present\\n if (returndata.length > 0) {\\n // The easiest way to bubble the revert reason is using memory via assembly\\n /// @solidity memory-safe-assembly\\n assembly {\\n let returndata_size := mload(returndata)\\n revert(add(32, returndata), returndata_size)\\n }\\n } else {\\n revert(errorMessage);\\n }\\n }\\n }\\n}\\n\",\"keccak256\":\"0xd6153ce99bcdcce22b124f755e72553295be6abcd63804cfdffceb188b8bef10\",\"license\":\"MIT\"},\"contracts/agToken/AgToken.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-3.0\\n\\npragma solidity ^0.8.12;\\n\\n/*\\n * \\u2588 \\n ***** \\u2593\\u2593\\u2593 \\n * \\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593 \\n * ///. \\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593 \\n ***** //////// \\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593 \\n * ///////////// \\u2593\\u2593\\u2593 \\n \\u2593\\u2593 ////////////////// \\u2588 \\u2593\\u2593 \\n \\u2593\\u2593 \\u2593\\u2593 /////////////////////// \\u2593\\u2593 \\u2593\\u2593 \\n \\u2593\\u2593 \\u2593\\u2593 //////////////////////////// \\u2593\\u2593 \\u2593\\u2593 \\n \\u2593\\u2593 \\u2593\\u2593 /////////\\u2593\\u2593\\u2593///////\\u2593\\u2593\\u2593///////// \\u2593\\u2593 \\u2593\\u2593 \\n \\u2593\\u2593 ,////////////////////////////////////// \\u2593\\u2593 \\u2593\\u2593 \\n \\u2593\\u2593 ////////////////////////////////////////// \\u2593\\u2593 \\n \\u2593\\u2593 //////////////////////\\u2593\\u2593\\u2593\\u2593///////////////////// \\n ,//////////////////////////////////////////////////// \\n .////////////////////////////////////////////////////////// \\n .//////////////////////////\\u2588\\u2588.,//////////////////////////\\u2588 \\n .//////////////////////\\u2588\\u2588\\u2588\\u2588..,./////////////////////\\u2588\\u2588 \\n ...////////////////\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588.....,.////////////////\\u2588\\u2588\\u2588 \\n ,.,////////////\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588 ........,///////////\\u2588\\u2588\\u2588\\u2588 \\n .,.,//////\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588 ,.......///////\\u2588\\u2588\\u2588\\u2588 \\n ,..//\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588 ........./\\u2588\\u2588\\u2588\\u2588 \\n ..,\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588 .....,\\u2588\\u2588\\u2588 \\n .\\u2588\\u2588 ,.,\\u2588 \\n \\n \\n \\n \\u2593\\u2593 \\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593 \\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593 \\u2593\\u2593 \\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593 \\n \\u2593\\u2593\\u2593\\u2593\\u2593\\u2593 \\u2593\\u2593\\u2593 \\u2593\\u2593\\u2593 \\u2593\\u2593\\u2593 \\u2593\\u2593 \\u2593\\u2593 \\u2593\\u2593\\u2593\\u2593 \\n \\u2593\\u2593\\u2593 \\u2593\\u2593\\u2593 \\u2593\\u2593\\u2593 \\u2593\\u2593\\u2593 \\u2593\\u2593\\u2593 \\u2593\\u2593\\u2593 \\u2593\\u2593 \\u2593\\u2593\\u2593\\u2593\\u2593 \\n \\u2593\\u2593\\u2593 \\u2593\\u2593 \\u2593\\u2593\\u2593 \\u2593\\u2593\\u2593 \\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593 \\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593 \\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593 \\n*/\\n\\nimport \\\"../interfaces/IAgToken.sol\\\";\\nimport \\\"../interfaces/ITreasury.sol\\\";\\nimport \\\"@openzeppelin/contracts-upgradeable/token/ERC20/extensions/draft-ERC20PermitUpgradeable.sol\\\";\\n\\n/// @title AgToken\\n/// @author Angle Labs, Inc.\\n/// @notice Base contract for Angle agTokens on Ethereum and on other chains\\n/// @dev By default, agTokens are ERC-20 tokens with 18 decimals\\ncontract AgToken is IAgToken, ERC20PermitUpgradeable {\\n // =========================== PARAMETERS / VARIABLES ==========================\\n\\n /// @inheritdoc IAgToken\\n mapping(address => bool) public isMinter;\\n /// @notice Reference to the treasury contract which can grant minting rights\\n address public treasury;\\n\\n // =================================== EVENTS ==================================\\n\\n event TreasuryUpdated(address indexed _treasury);\\n event MinterToggled(address indexed minter);\\n\\n // =================================== ERRORS ==================================\\n\\n error BurnAmountExceedsAllowance();\\n error InvalidSender();\\n error InvalidTreasury();\\n error NotMinter();\\n error NotTreasury();\\n\\n // ================================ CONSTRUCTOR ================================\\n\\n /// @custom:oz-upgrades-unsafe-allow constructor\\n constructor() initializer {}\\n\\n /// @notice Initializes the `AgToken` contract\\n function initialize(string memory name_, string memory symbol_, address _treasury) external {\\n _initialize(name_, symbol_, _treasury);\\n }\\n\\n /// @notice Initializes the contract\\n function _initialize(string memory name_, string memory symbol_, address _treasury) internal virtual initializer {\\n if (address(ITreasury(_treasury).stablecoin()) != address(this)) revert InvalidTreasury();\\n __ERC20Permit_init(name_);\\n __ERC20_init(name_, symbol_);\\n treasury = _treasury;\\n emit TreasuryUpdated(_treasury);\\n }\\n\\n // ================================= MODIFIERS =================================\\n\\n /// @notice Checks to see if it is the `Treasury` calling this contract\\n modifier onlyTreasury() {\\n if (msg.sender != treasury) revert NotTreasury();\\n _;\\n }\\n\\n /// @notice Checks whether the sender has the minting right\\n modifier onlyMinter() {\\n if (!isMinter[msg.sender]) revert NotMinter();\\n _;\\n }\\n\\n // ============================= EXTERNAL FUNCTION =============================\\n\\n /// @notice Allows anyone to burn stablecoins\\n /// @param amount Amount of stablecoins to burn\\n /// @dev This function can typically be called if there is a settlement mechanism to burn stablecoins\\n function burnStablecoin(uint256 amount) external {\\n _burn(msg.sender, amount);\\n }\\n\\n // ========================= MINTER ROLE ONLY FUNCTIONS ========================\\n\\n /// @inheritdoc IAgToken\\n function burnSelf(uint256 amount, address burner) external onlyMinter {\\n _burn(burner, amount);\\n }\\n\\n /// @inheritdoc IAgToken\\n function burnFrom(uint256 amount, address burner, address sender) external onlyMinter {\\n if (burner != sender) {\\n uint256 currentAllowance = allowance(burner, sender);\\n if (currentAllowance < amount) revert BurnAmountExceedsAllowance();\\n _approve(burner, sender, currentAllowance - amount);\\n }\\n _burn(burner, amount);\\n }\\n\\n /// @inheritdoc IAgToken\\n function mint(address account, uint256 amount) external onlyMinter {\\n _mint(account, amount);\\n }\\n\\n // ========================== GOVERNANCE ONLY FUNCTIONS ==========================\\n\\n /// @inheritdoc IAgToken\\n function addMinter(address minter) external onlyTreasury {\\n isMinter[minter] = true;\\n emit MinterToggled(minter);\\n }\\n\\n /// @inheritdoc IAgToken\\n function removeMinter(address minter) external {\\n if (msg.sender != address(treasury) && msg.sender != minter) revert InvalidSender();\\n isMinter[minter] = false;\\n emit MinterToggled(minter);\\n }\\n\\n /// @inheritdoc IAgToken\\n function setTreasury(address _treasury) external virtual onlyTreasury {\\n treasury = _treasury;\\n emit TreasuryUpdated(_treasury);\\n }\\n}\\n\",\"keccak256\":\"0x671d54d7840179050e859cf09662fe0e2c34cfaf5ec3782148d6c29e77c54d17\",\"license\":\"GPL-3.0\"},\"contracts/agToken/AgTokenSideChainMultiBridge.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-3.0\\n\\npragma solidity ^0.8.12;\\n\\nimport \\\"./AgToken.sol\\\";\\nimport \\\"@openzeppelin/contracts/token/ERC20/IERC20.sol\\\";\\nimport \\\"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\\\";\\n\\n/// @title AgTokenSideChainMultiBridge\\n/// @author Angle Labs, Inc.\\n/// @notice Contract for Angle agTokens on other chains than Ethereum mainnet\\n/// @dev This contract supports bridge tokens having a minting right on the stablecoin (also referred to as the canonical\\n/// or the native token)\\ncontract AgTokenSideChainMultiBridge is AgToken {\\n using SafeERC20 for IERC20;\\n\\n /// @notice Base used for fee computation\\n uint256 public constant BASE_PARAMS = 1e9;\\n\\n // =============================== BRIDGING DATA ===============================\\n\\n /// @notice Struct with some data about a specific bridge token\\n struct BridgeDetails {\\n // Limit on the balance of bridge token held by the contract: it is designed\\n // to reduce the exposure of the system to hacks\\n uint256 limit;\\n // Limit on the hourly volume of token minted through this bridge\\n // Technically the limit over a rolling hour is hourlyLimit x2 as hourly limit\\n // is enforced only between x:00 and x+1:00\\n uint256 hourlyLimit;\\n // Fee taken for swapping in and out the token\\n uint64 fee;\\n // Whether the associated token is allowed or not\\n bool allowed;\\n // Whether swapping in and out from the associated token is paused or not\\n bool paused;\\n }\\n\\n /// @notice Maps a bridge token to data\\n mapping(address => BridgeDetails) public bridges;\\n /// @notice List of all bridge tokens\\n address[] public bridgeTokensList;\\n /// @notice Maps a bridge token to the associated hourly volume\\n mapping(address => mapping(uint256 => uint256)) public usage;\\n /// @notice Maps an address to whether it is exempt of fees for when it comes to swapping in and out\\n mapping(address => uint256) public isFeeExempt;\\n /// @notice Limit to the amount of tokens that can be sent from that chain to another chain\\n uint256 public chainTotalHourlyLimit;\\n /// @notice Usage per hour on that chain. Maps an hourly timestamp to the total volume swapped out on the chain\\n mapping(uint256 => uint256) public chainTotalUsage;\\n\\n // =================================== EVENTS ==================================\\n\\n event BridgeTokenAdded(address indexed bridgeToken, uint256 limit, uint256 hourlyLimit, uint64 fee, bool paused);\\n event BridgeTokenToggled(address indexed bridgeToken, bool toggleStatus);\\n event BridgeTokenRemoved(address indexed bridgeToken);\\n event BridgeTokenFeeUpdated(address indexed bridgeToken, uint64 fee);\\n event BridgeTokenLimitUpdated(address indexed bridgeToken, uint256 limit);\\n event BridgeTokenHourlyLimitUpdated(address indexed bridgeToken, uint256 hourlyLimit);\\n event HourlyLimitUpdated(uint256 hourlyLimit);\\n event Recovered(address indexed token, address indexed to, uint256 amount);\\n event FeeToggled(address indexed theAddress, uint256 toggleStatus);\\n\\n // =================================== ERRORS ==================================\\n\\n error AssetStillControlledInReserves();\\n error HourlyLimitExceeded();\\n error InvalidToken();\\n error NotGovernor();\\n error NotGovernorOrGuardian();\\n error TooBigAmount();\\n error TooHighParameterValue();\\n error ZeroAddress();\\n\\n // ================================= MODIFIERS =================================\\n\\n /// @notice Checks whether the `msg.sender` has the governor role or not\\n modifier onlyGovernor() {\\n if (!ITreasury(treasury).isGovernor(msg.sender)) revert NotGovernor();\\n _;\\n }\\n\\n /// @notice Checks whether the `msg.sender` has the governor role or the guardian role\\n modifier onlyGovernorOrGuardian() {\\n if (!ITreasury(treasury).isGovernorOrGuardian(msg.sender)) revert NotGovernorOrGuardian();\\n _;\\n }\\n\\n // ===================== EXTERNAL PERMISSIONLESS FUNCTIONS =====================\\n\\n /// @notice Returns the list of all supported bridge tokens\\n /// @dev Helpful for UIs\\n function allBridgeTokens() external view returns (address[] memory) {\\n return bridgeTokensList;\\n }\\n\\n /// @notice Returns the current volume for a bridge, for the current hour\\n /// @param bridgeToken Bridge used to mint\\n /// @dev Helpful for UIs\\n function currentUsage(address bridgeToken) external view returns (uint256) {\\n return usage[bridgeToken][block.timestamp / 3600];\\n }\\n\\n /// @notice Returns the current total volume on the chain for the current hour\\n /// @dev Helpful for UIs\\n function currentTotalUsage() external view returns (uint256) {\\n return chainTotalUsage[block.timestamp / 3600];\\n }\\n\\n /// @notice Mints the canonical token from a supported bridge token\\n /// @param bridgeToken Bridge token to use to mint\\n /// @param amount Amount of bridge tokens to send\\n /// @param to Address to which the stablecoin should be sent\\n /// @return Amount of the canonical stablecoin actually minted\\n /// @dev Some fees may be taken by the protocol depending on the token used and on the address calling\\n function swapIn(address bridgeToken, uint256 amount, address to) external returns (uint256) {\\n BridgeDetails memory bridgeDetails = bridges[bridgeToken];\\n if (!bridgeDetails.allowed || bridgeDetails.paused) revert InvalidToken();\\n uint256 balance = IERC20(bridgeToken).balanceOf(address(this));\\n if (balance + amount > bridgeDetails.limit) {\\n // In case someone maliciously sends tokens to this contract\\n // Or the limit changes\\n if (bridgeDetails.limit > balance) amount = bridgeDetails.limit - balance;\\n else {\\n amount = 0;\\n }\\n }\\n\\n // Checking requirement on the hourly volume\\n uint256 hour = block.timestamp / 3600;\\n uint256 hourlyUsage = usage[bridgeToken][hour];\\n if (hourlyUsage + amount > bridgeDetails.hourlyLimit) {\\n // Edge case when the hourly limit changes\\n amount = bridgeDetails.hourlyLimit > hourlyUsage ? bridgeDetails.hourlyLimit - hourlyUsage : 0;\\n }\\n usage[bridgeToken][hour] = hourlyUsage + amount;\\n\\n IERC20(bridgeToken).safeTransferFrom(msg.sender, address(this), amount);\\n uint256 canonicalOut = amount;\\n // Computing fees\\n if (isFeeExempt[msg.sender] == 0) {\\n canonicalOut -= (canonicalOut * bridgeDetails.fee) / BASE_PARAMS;\\n }\\n _mint(to, canonicalOut);\\n return canonicalOut;\\n }\\n\\n /// @notice Burns the canonical token in exchange for a bridge token\\n /// @param bridgeToken Bridge token required\\n /// @param amount Amount of canonical tokens to burn\\n /// @param to Address to which the bridge token should be sent\\n /// @return Amount of bridge tokens actually sent back\\n /// @dev Some fees may be taken by the protocol depending on the token used and on the address calling\\n function swapOut(address bridgeToken, uint256 amount, address to) external returns (uint256) {\\n BridgeDetails memory bridgeDetails = bridges[bridgeToken];\\n if (!bridgeDetails.allowed || bridgeDetails.paused) revert InvalidToken();\\n\\n uint256 hour = block.timestamp / 3600;\\n uint256 hourlyUsage = chainTotalUsage[hour] + amount;\\n // If the amount being swapped out exceeds the limit, we revert\\n // We don't want to change the amount being swapped out.\\n // The user can decide to send another tx with the correct amount to reach the limit\\n if (hourlyUsage > chainTotalHourlyLimit) revert HourlyLimitExceeded();\\n chainTotalUsage[hour] = hourlyUsage;\\n\\n _burn(msg.sender, amount);\\n uint256 bridgeOut = amount;\\n if (isFeeExempt[msg.sender] == 0) {\\n bridgeOut -= (bridgeOut * bridgeDetails.fee) / BASE_PARAMS;\\n }\\n IERC20(bridgeToken).safeTransfer(to, bridgeOut);\\n return bridgeOut;\\n }\\n\\n // ============================ GOVERNANCE FUNCTIONS ===========================\\n\\n /// @notice Adds support for a bridge token\\n /// @param bridgeToken Bridge token to add: it should be a version of the stablecoin from another bridge\\n /// @param limit Limit on the balance of bridge token this contract could hold\\n /// @param hourlyLimit Limit on the hourly volume for this bridge\\n /// @param paused Whether swapping for this token should be paused or not\\n /// @param fee Fee taken upon swapping for or against this token\\n function addBridgeToken(\\n address bridgeToken,\\n uint256 limit,\\n uint256 hourlyLimit,\\n uint64 fee,\\n bool paused\\n ) external onlyGovernor {\\n if (bridges[bridgeToken].allowed || bridgeToken == address(0)) revert InvalidToken();\\n if (fee > BASE_PARAMS) revert TooHighParameterValue();\\n BridgeDetails memory _bridge;\\n _bridge.limit = limit;\\n _bridge.hourlyLimit = hourlyLimit;\\n _bridge.paused = paused;\\n _bridge.fee = fee;\\n _bridge.allowed = true;\\n bridges[bridgeToken] = _bridge;\\n bridgeTokensList.push(bridgeToken);\\n emit BridgeTokenAdded(bridgeToken, limit, hourlyLimit, fee, paused);\\n }\\n\\n /// @notice Removes support for a token\\n /// @param bridgeToken Address of the bridge token to remove support for\\n function removeBridgeToken(address bridgeToken) external onlyGovernor {\\n if (IERC20(bridgeToken).balanceOf(address(this)) != 0) revert AssetStillControlledInReserves();\\n delete bridges[bridgeToken];\\n // Deletion from `bridgeTokensList` loop\\n uint256 bridgeTokensListLength = bridgeTokensList.length;\\n for (uint256 i; i < bridgeTokensListLength - 1; ++i) {\\n if (bridgeTokensList[i] == bridgeToken) {\\n // Replace the `bridgeToken` to remove with the last of the list\\n bridgeTokensList[i] = bridgeTokensList[bridgeTokensListLength - 1];\\n break;\\n }\\n }\\n // Remove last element in array\\n bridgeTokensList.pop();\\n emit BridgeTokenRemoved(bridgeToken);\\n }\\n\\n /// @notice Recovers any ERC20 token\\n /// @dev Can be used to withdraw bridge tokens for them to be de-bridged on mainnet\\n function recoverERC20(address tokenAddress, address to, uint256 amountToRecover) external onlyGovernor {\\n IERC20(tokenAddress).safeTransfer(to, amountToRecover);\\n emit Recovered(tokenAddress, to, amountToRecover);\\n }\\n\\n /// @notice Updates the `limit` amount for `bridgeToken`\\n function setLimit(address bridgeToken, uint256 limit) external onlyGovernorOrGuardian {\\n if (!bridges[bridgeToken].allowed) revert InvalidToken();\\n bridges[bridgeToken].limit = limit;\\n emit BridgeTokenLimitUpdated(bridgeToken, limit);\\n }\\n\\n /// @notice Updates the `hourlyLimit` amount for `bridgeToken`\\n function setHourlyLimit(address bridgeToken, uint256 hourlyLimit) external onlyGovernorOrGuardian {\\n if (!bridges[bridgeToken].allowed) revert InvalidToken();\\n bridges[bridgeToken].hourlyLimit = hourlyLimit;\\n emit BridgeTokenHourlyLimitUpdated(bridgeToken, hourlyLimit);\\n }\\n\\n /// @notice Updates the `chainTotalHourlyLimit` amount\\n function setChainTotalHourlyLimit(uint256 hourlyLimit) external onlyGovernorOrGuardian {\\n chainTotalHourlyLimit = hourlyLimit;\\n emit HourlyLimitUpdated(hourlyLimit);\\n }\\n\\n /// @notice Updates the `fee` value for `bridgeToken`\\n function setSwapFee(address bridgeToken, uint64 fee) external onlyGovernorOrGuardian {\\n if (!bridges[bridgeToken].allowed) revert InvalidToken();\\n if (fee > BASE_PARAMS) revert TooHighParameterValue();\\n bridges[bridgeToken].fee = fee;\\n emit BridgeTokenFeeUpdated(bridgeToken, fee);\\n }\\n\\n /// @notice Pauses or unpauses swapping in and out for a token\\n function toggleBridge(address bridgeToken) external onlyGovernorOrGuardian {\\n if (!bridges[bridgeToken].allowed) revert InvalidToken();\\n bool pausedStatus = bridges[bridgeToken].paused;\\n bridges[bridgeToken].paused = !pausedStatus;\\n emit BridgeTokenToggled(bridgeToken, !pausedStatus);\\n }\\n\\n /// @notice Toggles fees for the address `theAddress`\\n function toggleFeesForAddress(address theAddress) external onlyGovernorOrGuardian {\\n uint256 feeExemptStatus = 1 - isFeeExempt[theAddress];\\n isFeeExempt[theAddress] = feeExemptStatus;\\n emit FeeToggled(theAddress, feeExemptStatus);\\n }\\n}\\n\",\"keccak256\":\"0x9782497e84a1dc4bc468778ede4aceb35cebf74e4159e2af8f469f49312c3841\",\"license\":\"GPL-3.0\"},\"contracts/interfaces/IAgToken.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-3.0\\n\\npragma solidity ^0.8.12;\\n\\nimport \\\"@openzeppelin/contracts-upgradeable/token/ERC20/IERC20Upgradeable.sol\\\";\\n\\n/// @title IAgToken\\n/// @author Angle Labs, Inc.\\n/// @notice Interface for the stablecoins `AgToken` contracts\\n/// @dev This interface only contains functions of the `AgToken` contract which are called by other contracts\\n/// of this module or of the first module of the Angle Protocol\\ninterface IAgToken is IERC20Upgradeable {\\n // ======================= Minter Role Only Functions ===========================\\n\\n /// @notice Lets the `StableMaster` contract or another whitelisted contract mint agTokens\\n /// @param account Address to mint to\\n /// @param amount Amount to mint\\n /// @dev The contracts allowed to issue agTokens are the `StableMaster` contract, `VaultManager` contracts\\n /// associated to this stablecoin as well as the flash loan module (if activated) and potentially contracts\\n /// whitelisted by governance\\n function mint(address account, uint256 amount) external;\\n\\n /// @notice Burns `amount` tokens from a `burner` address after being asked to by `sender`\\n /// @param amount Amount of tokens to burn\\n /// @param burner Address to burn from\\n /// @param sender Address which requested the burn from `burner`\\n /// @dev This method is to be called by a contract with the minter right after being requested\\n /// to do so by a `sender` address willing to burn tokens from another `burner` address\\n /// @dev The method checks the allowance between the `sender` and the `burner`\\n function burnFrom(uint256 amount, address burner, address sender) external;\\n\\n /// @notice Burns `amount` tokens from a `burner` address\\n /// @param amount Amount of tokens to burn\\n /// @param burner Address to burn from\\n /// @dev This method is to be called by a contract with a minter right on the AgToken after being\\n /// requested to do so by an address willing to burn tokens from its address\\n function burnSelf(uint256 amount, address burner) external;\\n\\n // ========================= Treasury Only Functions ===========================\\n\\n /// @notice Adds a minter in the contract\\n /// @param minter Minter address to add\\n /// @dev Zero address checks are performed directly in the `Treasury` contract\\n function addMinter(address minter) external;\\n\\n /// @notice Removes a minter from the contract\\n /// @param minter Minter address to remove\\n /// @dev This function can also be called by a minter wishing to revoke itself\\n function removeMinter(address minter) external;\\n\\n /// @notice Sets a new treasury contract\\n /// @param _treasury New treasury address\\n function setTreasury(address _treasury) external;\\n\\n // ========================= External functions ================================\\n\\n /// @notice Checks whether an address has the right to mint agTokens\\n /// @param minter Address for which the minting right should be checked\\n /// @return Whether the address has the right to mint agTokens or not\\n function isMinter(address minter) external view returns (bool);\\n\\n /// @notice Get the associated treasury\\n function treasury() external view returns (address);\\n}\\n\",\"keccak256\":\"0x0c83efcfc1fb9ae9ba830f7b89e3dab9abf6ad7a6205a31aa35fbccaa837dcdc\",\"license\":\"GPL-3.0\"},\"contracts/interfaces/ICoreBorrow.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-3.0\\n\\npragma solidity ^0.8.12;\\n\\n/// @title ICoreBorrow\\n/// @author Angle Labs, Inc.\\n/// @notice Interface for the `CoreBorrow` contract\\n/// @dev This interface only contains functions of the `CoreBorrow` contract which are called by other contracts\\n/// of this module\\ninterface ICoreBorrow {\\n /// @notice Checks if an address corresponds to a treasury of a stablecoin with a flash loan\\n /// module initialized on it\\n /// @param treasury Address to check\\n /// @return Whether the address has the `FLASHLOANER_TREASURY_ROLE` or not\\n function isFlashLoanerTreasury(address treasury) external view returns (bool);\\n\\n /// @notice Checks whether an address is governor of the Angle Protocol or not\\n /// @param admin Address to check\\n /// @return Whether the address has the `GOVERNOR_ROLE` or not\\n function isGovernor(address admin) external view returns (bool);\\n\\n /// @notice Checks whether an address is governor or a guardian of the Angle Protocol or not\\n /// @param admin Address to check\\n /// @return Whether the address has the `GUARDIAN_ROLE` or not\\n /// @dev Governance should make sure when adding a governor to also give this governor the guardian\\n /// role by calling the `addGovernor` function\\n function isGovernorOrGuardian(address admin) external view returns (bool);\\n}\\n\",\"keccak256\":\"0x10249210cbf522775f040baf981d7d037472168ce2746d87473ac7c29a34e62e\",\"license\":\"GPL-3.0\"},\"contracts/interfaces/IFlashAngle.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-3.0\\n\\npragma solidity ^0.8.12;\\n\\nimport \\\"./IAgToken.sol\\\";\\nimport \\\"./ICoreBorrow.sol\\\";\\n\\n/// @title IFlashAngle\\n/// @author Angle Labs, Inc.\\n/// @notice Interface for the `FlashAngle` contract\\n/// @dev This interface only contains functions of the contract which are called by other contracts\\n/// of this module\\ninterface IFlashAngle {\\n /// @notice Reference to the `CoreBorrow` contract managing the FlashLoan module\\n function core() external view returns (ICoreBorrow);\\n\\n /// @notice Sends the fees taken from flash loans to the treasury contract associated to the stablecoin\\n /// @param stablecoin Stablecoin from which profits should be sent\\n /// @return balance Amount of profits sent\\n /// @dev This function can only be called by the treasury contract\\n function accrueInterestToTreasury(IAgToken stablecoin) external returns (uint256 balance);\\n\\n /// @notice Adds support for a stablecoin\\n /// @param _treasury Treasury associated to the stablecoin to add support for\\n /// @dev This function can only be called by the `CoreBorrow` contract\\n function addStablecoinSupport(address _treasury) external;\\n\\n /// @notice Removes support for a stablecoin\\n /// @param _treasury Treasury associated to the stablecoin to remove support for\\n /// @dev This function can only be called by the `CoreBorrow` contract\\n function removeStablecoinSupport(address _treasury) external;\\n\\n /// @notice Sets a new core contract\\n /// @param _core Core contract address to set\\n /// @dev This function can only be called by the `CoreBorrow` contract\\n function setCore(address _core) external;\\n}\\n\",\"keccak256\":\"0x39b0097f695b9e934bccdc72676c91513f1077cc5d0fd151908fd25a7c5cfbe4\",\"license\":\"GPL-3.0\"},\"contracts/interfaces/ITreasury.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-3.0\\n\\npragma solidity ^0.8.12;\\n\\nimport \\\"./IAgToken.sol\\\";\\nimport \\\"./ICoreBorrow.sol\\\";\\nimport \\\"./IFlashAngle.sol\\\";\\n\\n/// @title ITreasury\\n/// @author Angle Labs, Inc.\\n/// @notice Interface for the `Treasury` contract\\n/// @dev This interface only contains functions of the `Treasury` which are called by other contracts\\n/// of this module\\ninterface ITreasury {\\n /// @notice Stablecoin handled by this `treasury` contract\\n function stablecoin() external view returns (IAgToken);\\n\\n /// @notice Checks whether a given address has the governor role\\n /// @param admin Address to check\\n /// @return Whether the address has the governor role\\n /// @dev Access control is only kept in the `CoreBorrow` contract\\n function isGovernor(address admin) external view returns (bool);\\n\\n /// @notice Checks whether a given address has the guardian or the governor role\\n /// @param admin Address to check\\n /// @return Whether the address has the guardian or the governor role\\n /// @dev Access control is only kept in the `CoreBorrow` contract which means that this function\\n /// queries the `CoreBorrow` contract\\n function isGovernorOrGuardian(address admin) external view returns (bool);\\n\\n /// @notice Checks whether a given address has well been initialized in this contract\\n /// as a `VaultManager`\\n /// @param _vaultManager Address to check\\n /// @return Whether the address has been initialized or not\\n function isVaultManager(address _vaultManager) external view returns (bool);\\n\\n /// @notice Sets a new flash loan module for this stablecoin\\n /// @param _flashLoanModule Reference to the new flash loan module\\n /// @dev This function removes the minting right to the old flash loan module and grants\\n /// it to the new module\\n function setFlashLoanModule(address _flashLoanModule) external;\\n\\n /// @notice Gets the vault manager list\\n function vaultManagerList(uint256 i) external returns (address);\\n}\\n\",\"keccak256\":\"0x06c2f781c08732ce1b5845c083af5742716245baa6c519bd737f32b230a884c1\",\"license\":\"GPL-3.0\"}},\"version\":1}", + "bytecode": "0x60806040523480156200001157600080fd5b50600054610100900460ff1615808015620000335750600054600160ff909116105b8062000063575062000050306200013d60201b6200273a1760201c565b15801562000063575060005460ff166001145b620000cb5760405162461bcd60e51b815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201526d191e481a5b9a5d1a585b1a5e995960921b606482015260840160405180910390fd5b6000805460ff191660011790558015620000ef576000805461ff0019166101001790555b801562000136576000805461ff0019169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15b506200014c565b6001600160a01b03163b151590565b6146d0806200015c6000396000f3fe608060405234801561001057600080fd5b50600436106102ff5760003560e01c806361d027b31161019c5780639f48118f116100ee578063ced67f0c11610097578063dd62ed3e11610071578063dd62ed3e14610724578063e3e286551461076a578063f0f442601461077d57600080fd5b8063ced67f0c1461066b578063d44ad63f146106fe578063d505accf1461071157600080fd5b8063aa271e1a116100c8578063aa271e1a14610620578063ba330bd714610643578063cd4839ca1461065657600080fd5b80639f48118f146105ef578063a457c2d7146105fa578063a9059cbb1461060d57600080fd5b80637ecebe001161015057806395d89b411161012a57806395d89b41146105c1578063983b2d56146105c95780639e4e0dae146105dc57600080fd5b80637ecebe00146105705780638933fb791461058357806390218cff146105ae57600080fd5b80637334d020116101815780637334d020146105425780637d4c9c2d146105555780637d74e25f1461056857600080fd5b806361d027b3146104c757806370a082311461050c57600080fd5b80633092afd511610255578063395093511161020957806340c10f19116101e357806340c10f19146104815780634dc32fcc146104945780635bfbec96146104a757600080fd5b8063395093511461043b5780633a55f89d1461044e5780633f4218e01461046157600080fd5b8063350ebe041161023a578063350ebe041461040d5780633644e5151461042057806336db43b51461042857600080fd5b80633092afd5146103eb578063313ce567146103fe57600080fd5b8063151dd755116102b757806323b872dd1161029157806323b872dd146103b25780632b471d8e146103c55780632e403e14146103d857600080fd5b8063151dd7551461038057806318160ddd146103a15780632342fb0e146103a957600080fd5b80630919a951116102e85780630919a95114610337578063095ea7b31461034a5780631171bda91461036d57600080fd5b806306fdde0314610304578063077f224a14610322575b600080fd5b61030c610790565b6040516103199190613e48565b60405180910390f35b610335610330366004613f95565b610822565b005b61033561034536600461400d565b610832565b61035d61035836600461402a565b610995565b6040519015158152602001610319565b61033561037b366004614056565b6109af565b61039361038e366004614097565b610b04565b604051908152602001610319565b603554610393565b61039360d25481565b61035d6103c0366004614056565b610dbe565b6103356103d33660046140ce565b610de2565b6103356103e636600461400d565b610e39565b6103356103f936600461400d565b6111e8565b60405160128152602001610319565b61033561041b3660046140fe565b6112d1565b6103936113da565b61033561043636600461402a565b6113e9565b61035d61044936600461402a565b611579565b61033561045c366004614135565b6115c0565b61039361046f36600461400d565b60d16020526000908152604090205481565b61033561048f36600461402a565b6116c3565b6103936104a236600461400d565b611716565b6103936104b5366004614135565b60d36020526000908152604090205481565b60cd546104e79073ffffffffffffffffffffffffffffffffffffffff1681565b60405173ffffffffffffffffffffffffffffffffffffffff9091168152602001610319565b61039361051a36600461400d565b73ffffffffffffffffffffffffffffffffffffffff1660009081526033602052604090205490565b61033561055036600461402a565b61175e565b610335610563366004614179565b6118f1565b610393611c59565b61039361057e36600461400d565b611c7e565b61039361059136600461402a565b60d060209081526000928352604080842090915290825290205481565b6103356105bc366004614135565b611ca9565b61030c611cb6565b6103356105d736600461400d565b611cc5565b6103356105ea3660046141d6565b611d8d565b610393633b9aca0081565b61035d61060836600461402a565b611f99565b61035d61061b36600461402a565b61206f565b61035d61062e36600461400d565b60cc6020526000908152604090205460ff1681565b6104e7610651366004614135565b61207d565b61065e6120b4565b604051610319919061420b565b6106c561067936600461400d565b60ce6020526000908152604090208054600182015460029092015490919067ffffffffffffffff81169060ff680100000000000000008204811691690100000000000000000090041685565b60408051958652602086019490945267ffffffffffffffff9092169284019290925290151560608301521515608082015260a001610319565b61039361070c366004614097565b612122565b61033561071f366004614265565b6122e7565b6103936107323660046142dc565b73ffffffffffffffffffffffffffffffffffffffff918216600090815260346020908152604080832093909416825291909152205490565b61033561077836600461400d565b6124a6565b61033561078b36600461400d565b61267a565b60606036805461079f9061430a565b80601f01602080910402602001604051908101604052809291908181526020018280546107cb9061430a565b80156108185780601f106107ed57610100808354040283529160200191610818565b820191906000526020600020905b8154815290600101906020018083116107fb57829003601f168201915b5050505050905090565b61082d838383612756565b505050565b60cd546040517f521d4de900000000000000000000000000000000000000000000000000000000815233600482015273ffffffffffffffffffffffffffffffffffffffff9091169063521d4de990602401602060405180830381865afa1580156108a0573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906108c49190614357565b6108fa576040517f99e120bc00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff8116600090815260d1602052604081205461092b9060016143a3565b73ffffffffffffffffffffffffffffffffffffffff8316600081815260d160205260409081902083905551919250907f979ef83e7e7a87cb48064e296dd7e997870d50f43acf8d7ad221313526c8ca0f906109899084815260200190565b60405180910390a25050565b6000336109a3818585612a35565b60019150505b92915050565b60cd546040517fe43581b800000000000000000000000000000000000000000000000000000000815233600482015273ffffffffffffffffffffffffffffffffffffffff9091169063e43581b890602401602060405180830381865afa158015610a1d573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610a419190614357565b610a77576040517fee3675d400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b610a9873ffffffffffffffffffffffffffffffffffffffff84168383612be0565b8173ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff167ffff3b3844276f57024e0b42afec1a37f75db36511e43819a4f2a63ab7862b64883604051610af791815260200190565b60405180910390a3505050565b73ffffffffffffffffffffffffffffffffffffffff8316600090815260ce60209081526040808320815160a081018352815481526001820154938101939093526002015467ffffffffffffffff81169183019190915260ff680100000000000000008204811615801560608501526901000000000000000000909204161515608083015280610b94575080608001515b15610bcb576040517fc1ab6dc100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015260009073ffffffffffffffffffffffffffffffffffffffff8716906370a0823190602401602060405180830381865afa158015610c38573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610c5c91906143b6565b8251909150610c6b86836143cf565b1115610c93578151811015610c8e578151610c879082906143a3565b9450610c93565b600094505b6000610ca1610e10426143e2565b73ffffffffffffffffffffffffffffffffffffffff8816600090815260d0602090815260408083208484528252909120549085015191925090610ce488836143cf565b1115610d0f5780846020015111610cfc576000610d0c565b808460200151610d0c91906143a3565b96505b610d1987826143cf565b73ffffffffffffffffffffffffffffffffffffffff8916600081815260d060209081526040808320878452909152902091909155610d599033308a612cb4565b33600090815260d16020526040812054889103610da657633b9aca00856040015167ffffffffffffffff1682610d8f919061441d565b610d9991906143e2565b610da390826143a3565b90505b610db08782612d12565b9450505050505b9392505050565b600033610dcc858285612e32565b610dd7858585612f03565b506001949350505050565b33600090815260cc602052604090205460ff16610e2b576040517ff8d2906c00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b610e3581836131b6565b5050565b60cd546040517fe43581b800000000000000000000000000000000000000000000000000000000815233600482015273ffffffffffffffffffffffffffffffffffffffff9091169063e43581b890602401602060405180830381865afa158015610ea7573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610ecb9190614357565b610f01576040517fee3675d400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015273ffffffffffffffffffffffffffffffffffffffff8216906370a0823190602401602060405180830381865afa158015610f6b573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610f8f91906143b6565b15610fc6576040517f2ef630ec00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff8116600090815260ce602052604081208181556001810182905560020180547fffffffffffffffffffffffffffffffffffffffffffff0000000000000000000016905560cf54905b61102e6001836143a3565b811015611139578273ffffffffffffffffffffffffffffffffffffffff1660cf828154811061105f5761105f614434565b60009182526020909120015473ffffffffffffffffffffffffffffffffffffffff16036111295760cf6110936001846143a3565b815481106110a3576110a3614434565b60009182526020909120015460cf805473ffffffffffffffffffffffffffffffffffffffff90921691839081106110dc576110dc614434565b9060005260206000200160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550611139565b61113281614463565b9050611023565b5060cf80548061114b5761114b61449b565b60008281526020812082017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff90810180547fffffffffffffffffffffffff000000000000000000000000000000000000000016905590910190915560405173ffffffffffffffffffffffffffffffffffffffff8416917f5c95b49c4d59d97a2f044167723f29c74b30f99702e3fd406c3830160aa9ccb891a25050565b60cd5473ffffffffffffffffffffffffffffffffffffffff16331480159061122657503373ffffffffffffffffffffffffffffffffffffffff821614155b1561125d576040517fddb5de5e00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff8116600081815260cc602052604080822080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00169055517f98c15241d6c02bc5ee0b780e11b3ea737a2defd9d04877edbe9f9497065bd02f9190a250565b33600090815260cc602052604090205460ff1661131a576040517ff8d2906c00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff16146113d05773ffffffffffffffffffffffffffffffffffffffff828116600090815260346020908152604080832093851683529290522054838110156113ba576040517f715ec26c00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6113ce83836113c987856143a3565b612a35565b505b61082d82846131b6565b60006113e46133a3565b905090565b60cd546040517f521d4de900000000000000000000000000000000000000000000000000000000815233600482015273ffffffffffffffffffffffffffffffffffffffff9091169063521d4de990602401602060405180830381865afa158015611457573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061147b9190614357565b6114b1576040517f99e120bc00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff8216600090815260ce602052604090206002015468010000000000000000900460ff1661151f576040517fc1ab6dc100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff8216600081815260ce602052604090819020839055517fe7b113fba37131b6396680a0c55790a697ec975e198ff8cfd89dac90a6379e61906109899084815260200190565b33600081815260346020908152604080832073ffffffffffffffffffffffffffffffffffffffff871684529091528120549091906109a390829086906113c99087906143cf565b60cd546040517f521d4de900000000000000000000000000000000000000000000000000000000815233600482015273ffffffffffffffffffffffffffffffffffffffff9091169063521d4de990602401602060405180830381865afa15801561162e573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906116529190614357565b611688576040517f99e120bc00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60d28190556040518181527fc3b69829afe2345596a02c8b587d41f796ba0094481d899e1b2e07b7532a1e219060200160405180910390a150565b33600090815260cc602052604090205460ff1661170c576040517ff8d2906c00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b610e358282612d12565b73ffffffffffffffffffffffffffffffffffffffff8116600090815260d06020526040812081611748610e10426143e2565b8152602001908152602001600020549050919050565b60cd546040517f521d4de900000000000000000000000000000000000000000000000000000000815233600482015273ffffffffffffffffffffffffffffffffffffffff9091169063521d4de990602401602060405180830381865afa1580156117cc573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906117f09190614357565b611826576040517f99e120bc00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff8216600090815260ce602052604090206002015468010000000000000000900460ff16611894576040517fc1ab6dc100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff8216600081815260ce602052604090819020600101839055517fe13ac9338b2ee623233f83c1b3ceab16490fa3e3737fac7f0970d0830a9f4871906109899084815260200190565b60cd546040517fe43581b800000000000000000000000000000000000000000000000000000000815233600482015273ffffffffffffffffffffffffffffffffffffffff9091169063e43581b890602401602060405180830381865afa15801561195f573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906119839190614357565b6119b9576040517fee3675d400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff8516600090815260ce602052604090206002015468010000000000000000900460ff1680611a10575073ffffffffffffffffffffffffffffffffffffffff8516155b15611a47576040517fc1ab6dc100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b633b9aca008267ffffffffffffffff161115611a8f576040517feca1d2c600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040805160a08101825260008082526020820181905291810182905260608101829052608081019190915284815260208082018581528315156080840190815267ffffffffffffffff808716604080870191825260016060880181815273ffffffffffffffffffffffffffffffffffffffff8e16600081815260ce9099528389208a5181559751888401559351600290970180549151965115156901000000000000000000027fffffffffffffffffffffffffffffffffffffffffffff00ffffffffffffffffff97151568010000000000000000027fffffffffffffffffffffffffffffffffffffffffffffff000000000000000000909316989096169790971717949094169290921790935560cf805492830181559093527facb8d954e2cfef495862221e91bd7523613cf8808827cb33edfe4904cc51bf290180547fffffffffffffffffffffffff0000000000000000000000000000000000000000168217905590517f53087ff85d80a7671594bd2e86b92af22e0b3c2c441c8033bba7399b7b5cbe2390611c49908890889088908890938452602084019290925267ffffffffffffffff1660408301521515606082015260800190565b60405180910390a2505050505050565b600060d381611c6a610e10426143e2565b815260200190815260200160002054905090565b73ffffffffffffffffffffffffffffffffffffffff81166000908152609960205260408120546109a9565b611cb333826131b6565b50565b60606037805461079f9061430a565b60cd5473ffffffffffffffffffffffffffffffffffffffff163314611d16576040517fb90cdbb100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff8116600081815260cc602052604080822080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00166001179055517f98c15241d6c02bc5ee0b780e11b3ea737a2defd9d04877edbe9f9497065bd02f9190a250565b60cd546040517f521d4de900000000000000000000000000000000000000000000000000000000815233600482015273ffffffffffffffffffffffffffffffffffffffff9091169063521d4de990602401602060405180830381865afa158015611dfb573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611e1f9190614357565b611e55576040517f99e120bc00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff8216600090815260ce602052604090206002015468010000000000000000900460ff16611ec3576040517fc1ab6dc100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b633b9aca008167ffffffffffffffff161115611f0b576040517feca1d2c600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff8216600081815260ce602090815260409182902060020180547fffffffffffffffffffffffffffffffffffffffffffffffff00000000000000001667ffffffffffffffff861690811790915591519182527f901f9de19b475adc8da4110434b8df940dce085afd05e2281c86807f3a899d299101610989565b33600081815260346020908152604080832073ffffffffffffffffffffffffffffffffffffffff8716845290915281205490919083811015612062576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602560248201527f45524332303a2064656372656173656420616c6c6f77616e63652062656c6f7760448201527f207a65726f00000000000000000000000000000000000000000000000000000060648201526084015b60405180910390fd5b610dd78286868403612a35565b6000336109a3818585612f03565b60cf818154811061208d57600080fd5b60009182526020909120015473ffffffffffffffffffffffffffffffffffffffff16905081565b606060cf80548060200260200160405190810160405280929190818152602001828054801561081857602002820191906000526020600020905b815473ffffffffffffffffffffffffffffffffffffffff1681526001909101906020018083116120ee575050505050905090565b73ffffffffffffffffffffffffffffffffffffffff8316600090815260ce60209081526040808320815160a081018352815481526001820154938101939093526002015467ffffffffffffffff81169183019190915260ff6801000000000000000082048116158015606085015269010000000000000000009092041615156080830152806121b2575080608001515b156121e9576040517fc1ab6dc100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60006121f7610e10426143e2565b600081815260d36020526040812054919250906122159087906143cf565b905060d254811115612253576040517f6d43d1ac00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600082815260d36020526040902081905561226e33876131b6565b33600090815260d160205260408120548791036122bb57633b9aca00846040015167ffffffffffffffff16826122a4919061441d565b6122ae91906143e2565b6122b890826143a3565b90505b6122dc73ffffffffffffffffffffffffffffffffffffffff89168783612be0565b979650505050505050565b83421115612351576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f45524332305065726d69743a206578706972656420646561646c696e650000006044820152606401612059565b60007f6e71edae12b1b97f4d1f60370fef10105fa2faae0126114a169c64845d6126c98888886123808c61341e565b60408051602081019690965273ffffffffffffffffffffffffffffffffffffffff94851690860152929091166060840152608083015260a082015260c0810186905260e00160405160208183030381529060405280519060200120905060006123e882613453565b905060006123f8828787876134bc565b90508973ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff161461248f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601e60248201527f45524332305065726d69743a20696e76616c6964207369676e617475726500006044820152606401612059565b61249a8a8a8a612a35565b50505050505050505050565b60cd546040517f521d4de900000000000000000000000000000000000000000000000000000000815233600482015273ffffffffffffffffffffffffffffffffffffffff9091169063521d4de990602401602060405180830381865afa158015612514573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906125389190614357565b61256e576040517f99e120bc00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff8116600090815260ce602052604090206002015468010000000000000000900460ff166125dc576040517fc1ab6dc100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff8116600081815260ce602090815260409182902060020180547fffffffffffffffffffffffffffffffffffffffffffff00ffffffffffffffffff811669010000000000000000009182900460ff16801592830291909117909255925192835292917ff7c93079dcbf699749d66345a351afab7d24219bb1d915c9f4fc4cf03f00d3979101610989565b60cd5473ffffffffffffffffffffffffffffffffffffffff1633146126cb576040517fb90cdbb100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60cd80547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83169081179091556040517f7dae230f18360d76a040c81f050aa14eb9d6dc7901b20fc5d855e2a20fe814d190600090a250565b73ffffffffffffffffffffffffffffffffffffffff163b151590565b600054610100900460ff16158080156127765750600054600160ff909116105b806127905750303b158015612790575060005460ff166001145b61281c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201527f647920696e697469616c697a65640000000000000000000000000000000000006064820152608401612059565b600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00166001179055801561287a57600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff166101001790555b3073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1663e9cbd8226040518163ffffffff1660e01b8152600401602060405180830381865afa1580156128dc573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061290091906144ca565b73ffffffffffffffffffffffffffffffffffffffff161461294d576040517f14bcf5c800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b612956846134e4565b61296084846135ba565b60cd80547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff84169081179091556040517f7dae230f18360d76a040c81f050aa14eb9d6dc7901b20fc5d855e2a20fe814d190600090a28015612a2f57600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15b50505050565b73ffffffffffffffffffffffffffffffffffffffff8316612ad7576040517f08c379a0000000000000000000000000000000000000000000000000000000008152602060048201526024808201527f45524332303a20617070726f76652066726f6d20746865207a65726f2061646460448201527f72657373000000000000000000000000000000000000000000000000000000006064820152608401612059565b73ffffffffffffffffffffffffffffffffffffffff8216612b7a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602260248201527f45524332303a20617070726f766520746f20746865207a65726f20616464726560448201527f73730000000000000000000000000000000000000000000000000000000000006064820152608401612059565b73ffffffffffffffffffffffffffffffffffffffff83811660008181526034602090815260408083209487168084529482529182902085905590518481527f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b9259101610af7565b60405173ffffffffffffffffffffffffffffffffffffffff831660248201526044810182905261082d9084907fa9059cbb00000000000000000000000000000000000000000000000000000000906064015b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff000000000000000000000000000000000000000000000000000000009093169290921790915261365b565b60405173ffffffffffffffffffffffffffffffffffffffff80851660248301528316604482015260648101829052612a2f9085907f23b872dd0000000000000000000000000000000000000000000000000000000090608401612c32565b73ffffffffffffffffffffffffffffffffffffffff8216612d8f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601f60248201527f45524332303a206d696e7420746f20746865207a65726f2061646472657373006044820152606401612059565b8060356000828254612da191906143cf565b909155505073ffffffffffffffffffffffffffffffffffffffff821660009081526033602052604081208054839290612ddb9084906143cf565b909155505060405181815273ffffffffffffffffffffffffffffffffffffffff8316906000907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef9060200160405180910390a35050565b73ffffffffffffffffffffffffffffffffffffffff8381166000908152603460209081526040808320938616835292905220547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8114612a2f5781811015612ef6576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f45524332303a20696e73756666696369656e7420616c6c6f77616e63650000006044820152606401612059565b612a2f8484848403612a35565b73ffffffffffffffffffffffffffffffffffffffff8316612fa6576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602560248201527f45524332303a207472616e736665722066726f6d20746865207a65726f20616460448201527f64726573730000000000000000000000000000000000000000000000000000006064820152608401612059565b73ffffffffffffffffffffffffffffffffffffffff8216613049576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602360248201527f45524332303a207472616e7366657220746f20746865207a65726f206164647260448201527f65737300000000000000000000000000000000000000000000000000000000006064820152608401612059565b73ffffffffffffffffffffffffffffffffffffffff8316600090815260336020526040902054818110156130ff576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f45524332303a207472616e7366657220616d6f756e742065786365656473206260448201527f616c616e636500000000000000000000000000000000000000000000000000006064820152608401612059565b73ffffffffffffffffffffffffffffffffffffffff8085166000908152603360205260408082208585039055918516815290812080548492906131439084906143cf565b925050819055508273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef846040516131a991815260200190565b60405180910390a3612a2f565b73ffffffffffffffffffffffffffffffffffffffff8216613259576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602160248201527f45524332303a206275726e2066726f6d20746865207a65726f2061646472657360448201527f73000000000000000000000000000000000000000000000000000000000000006064820152608401612059565b73ffffffffffffffffffffffffffffffffffffffff82166000908152603360205260409020548181101561330f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602260248201527f45524332303a206275726e20616d6f756e7420657863656564732062616c616e60448201527f63650000000000000000000000000000000000000000000000000000000000006064820152608401612059565b73ffffffffffffffffffffffffffffffffffffffff8316600090815260336020526040812083830390556035805484929061334b9084906143a3565b909155505060405182815260009073ffffffffffffffffffffffffffffffffffffffff8516907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef9060200160405180910390a3505050565b60006113e47f8b73c3c69bb8fe3d512ecc4cf759cc79239f7b179b0ffacaa9a75d522b39400f6133d260655490565b6066546040805160208101859052908101839052606081018290524660808201523060a082015260009060c0016040516020818303038152906040528051906020012090509392505050565b73ffffffffffffffffffffffffffffffffffffffff811660009081526099602052604090208054600181018255905b50919050565b60006109a96134606133a3565b836040517f19010000000000000000000000000000000000000000000000000000000000006020820152602281018390526042810182905260009060620160405160208183030381529060405280519060200120905092915050565b60008060006134cd87878787613767565b915091506134da8161387f565b5095945050505050565b600054610100900460ff1661357b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201527f6e697469616c697a696e670000000000000000000000000000000000000000006064820152608401612059565b611cb3816040518060400160405280600181526020017f3100000000000000000000000000000000000000000000000000000000000000815250613ad3565b600054610100900460ff16613651576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201527f6e697469616c697a696e670000000000000000000000000000000000000000006064820152608401612059565b610e358282613b84565b60006136bd826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c65648152508573ffffffffffffffffffffffffffffffffffffffff16613c349092919063ffffffff16565b80519091501561082d57808060200190518101906136db9190614357565b61082d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e60448201527f6f742073756363656564000000000000000000000000000000000000000000006064820152608401612059565b6000807f7fffffffffffffffffffffffffffffff5d576e7357a4501ddfe92f46681b20a083111561379e5750600090506003613876565b8460ff16601b141580156137b657508460ff16601c14155b156137c75750600090506004613876565b6040805160008082526020820180845289905260ff881692820192909252606081018690526080810185905260019060a0016020604051602081039080840390855afa15801561381b573d6000803e3d6000fd5b50506040517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0015191505073ffffffffffffffffffffffffffffffffffffffff811661386f57600060019250925050613876565b9150600090505b94509492505050565b6000816004811115613893576138936144e7565b0361389b5750565b60018160048111156138af576138af6144e7565b03613916576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601860248201527f45434453413a20696e76616c6964207369676e617475726500000000000000006044820152606401612059565b600281600481111561392a5761392a6144e7565b03613991576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601f60248201527f45434453413a20696e76616c6964207369676e6174757265206c656e677468006044820152606401612059565b60038160048111156139a5576139a56144e7565b03613a32576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602260248201527f45434453413a20696e76616c6964207369676e6174757265202773272076616c60448201527f75650000000000000000000000000000000000000000000000000000000000006064820152608401612059565b6004816004811115613a4657613a466144e7565b03611cb3576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602260248201527f45434453413a20696e76616c6964207369676e6174757265202776272076616c60448201527f75650000000000000000000000000000000000000000000000000000000000006064820152608401612059565b600054610100900460ff16613b6a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201527f6e697469616c697a696e670000000000000000000000000000000000000000006064820152608401612059565b815160209283012081519190920120606591909155606655565b600054610100900460ff16613c1b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201527f6e697469616c697a696e670000000000000000000000000000000000000000006064820152608401612059565b6036613c278382614564565b50603761082d8282614564565b6060613c438484600085613c4b565b949350505050565b606082471015613cdd576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f60448201527f722063616c6c00000000000000000000000000000000000000000000000000006064820152608401612059565b73ffffffffffffffffffffffffffffffffffffffff85163b613d5b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006044820152606401612059565b6000808673ffffffffffffffffffffffffffffffffffffffff168587604051613d84919061467e565b60006040518083038185875af1925050503d8060008114613dc1576040519150601f19603f3d011682016040523d82523d6000602084013e613dc6565b606091505b50915091506122dc82828660608315613de0575081610db7565b825115613df05782518084602001fd5b816040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016120599190613e48565b60005b83811015613e3f578181015183820152602001613e27565b50506000910152565b6020815260008251806020840152613e67816040850160208701613e24565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169190910160400192915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b600082601f830112613ed957600080fd5b813567ffffffffffffffff80821115613ef457613ef4613e99565b604051601f83017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0908116603f01168101908282118183101715613f3a57613f3a613e99565b81604052838152866020858801011115613f5357600080fd5b836020870160208301376000602085830101528094505050505092915050565b73ffffffffffffffffffffffffffffffffffffffff81168114611cb357600080fd5b600080600060608486031215613faa57600080fd5b833567ffffffffffffffff80821115613fc257600080fd5b613fce87838801613ec8565b94506020860135915080821115613fe457600080fd5b50613ff186828701613ec8565b925050604084013561400281613f73565b809150509250925092565b60006020828403121561401f57600080fd5b8135610db781613f73565b6000806040838503121561403d57600080fd5b823561404881613f73565b946020939093013593505050565b60008060006060848603121561406b57600080fd5b833561407681613f73565b9250602084013561408681613f73565b929592945050506040919091013590565b6000806000606084860312156140ac57600080fd5b83356140b781613f73565b925060208401359150604084013561400281613f73565b600080604083850312156140e157600080fd5b8235915060208301356140f381613f73565b809150509250929050565b60008060006060848603121561411357600080fd5b83359250602084013561412581613f73565b9150604084013561400281613f73565b60006020828403121561414757600080fd5b5035919050565b803567ffffffffffffffff8116811461416657600080fd5b919050565b8015158114611cb357600080fd5b600080600080600060a0868803121561419157600080fd5b853561419c81613f73565b945060208601359350604086013592506141b86060870161414e565b915060808601356141c88161416b565b809150509295509295909350565b600080604083850312156141e957600080fd5b82356141f481613f73565b91506142026020840161414e565b90509250929050565b6020808252825182820181905260009190848201906040850190845b8181101561425957835173ffffffffffffffffffffffffffffffffffffffff1683529284019291840191600101614227565b50909695505050505050565b600080600080600080600060e0888a03121561428057600080fd5b873561428b81613f73565b9650602088013561429b81613f73565b95506040880135945060608801359350608088013560ff811681146142bf57600080fd5b9699959850939692959460a0840135945060c09093013592915050565b600080604083850312156142ef57600080fd5b82356142fa81613f73565b915060208301356140f381613f73565b600181811c9082168061431e57607f821691505b60208210810361344d577f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b60006020828403121561436957600080fd5b8151610db78161416b565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b818103818111156109a9576109a9614374565b6000602082840312156143c857600080fd5b5051919050565b808201808211156109a9576109a9614374565b600082614418577f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b500490565b80820281158282048414176109a9576109a9614374565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff820361449457614494614374565b5060010190565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603160045260246000fd5b6000602082840312156144dc57600080fd5b8151610db781613f73565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b601f82111561082d57600081815260208120601f850160051c8101602086101561453d5750805b601f850160051c820191505b8181101561455c57828155600101614549565b505050505050565b815167ffffffffffffffff81111561457e5761457e613e99565b6145928161458c845461430a565b84614516565b602080601f8311600181146145e557600084156145af5750858301515b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600386901b1c1916600185901b17855561455c565b6000858152602081207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08616915b8281101561463257888601518255948401946001909101908401614613565b508582101561466e57878501517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600388901b60f8161c191681555b5050505050600190811b01905550565b60008251614690818460208701613e24565b919091019291505056fea2646970667358221220f2eb02bac1667a72be85ab617a5b5aa3d8f7a9b09b4d1fde9756b7a5636daf2164736f6c63430008110033", + "deployedBytecode": "0x608060405234801561001057600080fd5b50600436106102ff5760003560e01c806361d027b31161019c5780639f48118f116100ee578063ced67f0c11610097578063dd62ed3e11610071578063dd62ed3e14610724578063e3e286551461076a578063f0f442601461077d57600080fd5b8063ced67f0c1461066b578063d44ad63f146106fe578063d505accf1461071157600080fd5b8063aa271e1a116100c8578063aa271e1a14610620578063ba330bd714610643578063cd4839ca1461065657600080fd5b80639f48118f146105ef578063a457c2d7146105fa578063a9059cbb1461060d57600080fd5b80637ecebe001161015057806395d89b411161012a57806395d89b41146105c1578063983b2d56146105c95780639e4e0dae146105dc57600080fd5b80637ecebe00146105705780638933fb791461058357806390218cff146105ae57600080fd5b80637334d020116101815780637334d020146105425780637d4c9c2d146105555780637d74e25f1461056857600080fd5b806361d027b3146104c757806370a082311461050c57600080fd5b80633092afd511610255578063395093511161020957806340c10f19116101e357806340c10f19146104815780634dc32fcc146104945780635bfbec96146104a757600080fd5b8063395093511461043b5780633a55f89d1461044e5780633f4218e01461046157600080fd5b8063350ebe041161023a578063350ebe041461040d5780633644e5151461042057806336db43b51461042857600080fd5b80633092afd5146103eb578063313ce567146103fe57600080fd5b8063151dd755116102b757806323b872dd1161029157806323b872dd146103b25780632b471d8e146103c55780632e403e14146103d857600080fd5b8063151dd7551461038057806318160ddd146103a15780632342fb0e146103a957600080fd5b80630919a951116102e85780630919a95114610337578063095ea7b31461034a5780631171bda91461036d57600080fd5b806306fdde0314610304578063077f224a14610322575b600080fd5b61030c610790565b6040516103199190613e48565b60405180910390f35b610335610330366004613f95565b610822565b005b61033561034536600461400d565b610832565b61035d61035836600461402a565b610995565b6040519015158152602001610319565b61033561037b366004614056565b6109af565b61039361038e366004614097565b610b04565b604051908152602001610319565b603554610393565b61039360d25481565b61035d6103c0366004614056565b610dbe565b6103356103d33660046140ce565b610de2565b6103356103e636600461400d565b610e39565b6103356103f936600461400d565b6111e8565b60405160128152602001610319565b61033561041b3660046140fe565b6112d1565b6103936113da565b61033561043636600461402a565b6113e9565b61035d61044936600461402a565b611579565b61033561045c366004614135565b6115c0565b61039361046f36600461400d565b60d16020526000908152604090205481565b61033561048f36600461402a565b6116c3565b6103936104a236600461400d565b611716565b6103936104b5366004614135565b60d36020526000908152604090205481565b60cd546104e79073ffffffffffffffffffffffffffffffffffffffff1681565b60405173ffffffffffffffffffffffffffffffffffffffff9091168152602001610319565b61039361051a36600461400d565b73ffffffffffffffffffffffffffffffffffffffff1660009081526033602052604090205490565b61033561055036600461402a565b61175e565b610335610563366004614179565b6118f1565b610393611c59565b61039361057e36600461400d565b611c7e565b61039361059136600461402a565b60d060209081526000928352604080842090915290825290205481565b6103356105bc366004614135565b611ca9565b61030c611cb6565b6103356105d736600461400d565b611cc5565b6103356105ea3660046141d6565b611d8d565b610393633b9aca0081565b61035d61060836600461402a565b611f99565b61035d61061b36600461402a565b61206f565b61035d61062e36600461400d565b60cc6020526000908152604090205460ff1681565b6104e7610651366004614135565b61207d565b61065e6120b4565b604051610319919061420b565b6106c561067936600461400d565b60ce6020526000908152604090208054600182015460029092015490919067ffffffffffffffff81169060ff680100000000000000008204811691690100000000000000000090041685565b60408051958652602086019490945267ffffffffffffffff9092169284019290925290151560608301521515608082015260a001610319565b61039361070c366004614097565b612122565b61033561071f366004614265565b6122e7565b6103936107323660046142dc565b73ffffffffffffffffffffffffffffffffffffffff918216600090815260346020908152604080832093909416825291909152205490565b61033561077836600461400d565b6124a6565b61033561078b36600461400d565b61267a565b60606036805461079f9061430a565b80601f01602080910402602001604051908101604052809291908181526020018280546107cb9061430a565b80156108185780601f106107ed57610100808354040283529160200191610818565b820191906000526020600020905b8154815290600101906020018083116107fb57829003601f168201915b5050505050905090565b61082d838383612756565b505050565b60cd546040517f521d4de900000000000000000000000000000000000000000000000000000000815233600482015273ffffffffffffffffffffffffffffffffffffffff9091169063521d4de990602401602060405180830381865afa1580156108a0573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906108c49190614357565b6108fa576040517f99e120bc00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff8116600090815260d1602052604081205461092b9060016143a3565b73ffffffffffffffffffffffffffffffffffffffff8316600081815260d160205260409081902083905551919250907f979ef83e7e7a87cb48064e296dd7e997870d50f43acf8d7ad221313526c8ca0f906109899084815260200190565b60405180910390a25050565b6000336109a3818585612a35565b60019150505b92915050565b60cd546040517fe43581b800000000000000000000000000000000000000000000000000000000815233600482015273ffffffffffffffffffffffffffffffffffffffff9091169063e43581b890602401602060405180830381865afa158015610a1d573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610a419190614357565b610a77576040517fee3675d400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b610a9873ffffffffffffffffffffffffffffffffffffffff84168383612be0565b8173ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff167ffff3b3844276f57024e0b42afec1a37f75db36511e43819a4f2a63ab7862b64883604051610af791815260200190565b60405180910390a3505050565b73ffffffffffffffffffffffffffffffffffffffff8316600090815260ce60209081526040808320815160a081018352815481526001820154938101939093526002015467ffffffffffffffff81169183019190915260ff680100000000000000008204811615801560608501526901000000000000000000909204161515608083015280610b94575080608001515b15610bcb576040517fc1ab6dc100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015260009073ffffffffffffffffffffffffffffffffffffffff8716906370a0823190602401602060405180830381865afa158015610c38573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610c5c91906143b6565b8251909150610c6b86836143cf565b1115610c93578151811015610c8e578151610c879082906143a3565b9450610c93565b600094505b6000610ca1610e10426143e2565b73ffffffffffffffffffffffffffffffffffffffff8816600090815260d0602090815260408083208484528252909120549085015191925090610ce488836143cf565b1115610d0f5780846020015111610cfc576000610d0c565b808460200151610d0c91906143a3565b96505b610d1987826143cf565b73ffffffffffffffffffffffffffffffffffffffff8916600081815260d060209081526040808320878452909152902091909155610d599033308a612cb4565b33600090815260d16020526040812054889103610da657633b9aca00856040015167ffffffffffffffff1682610d8f919061441d565b610d9991906143e2565b610da390826143a3565b90505b610db08782612d12565b9450505050505b9392505050565b600033610dcc858285612e32565b610dd7858585612f03565b506001949350505050565b33600090815260cc602052604090205460ff16610e2b576040517ff8d2906c00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b610e3581836131b6565b5050565b60cd546040517fe43581b800000000000000000000000000000000000000000000000000000000815233600482015273ffffffffffffffffffffffffffffffffffffffff9091169063e43581b890602401602060405180830381865afa158015610ea7573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610ecb9190614357565b610f01576040517fee3675d400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015273ffffffffffffffffffffffffffffffffffffffff8216906370a0823190602401602060405180830381865afa158015610f6b573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610f8f91906143b6565b15610fc6576040517f2ef630ec00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff8116600090815260ce602052604081208181556001810182905560020180547fffffffffffffffffffffffffffffffffffffffffffff0000000000000000000016905560cf54905b61102e6001836143a3565b811015611139578273ffffffffffffffffffffffffffffffffffffffff1660cf828154811061105f5761105f614434565b60009182526020909120015473ffffffffffffffffffffffffffffffffffffffff16036111295760cf6110936001846143a3565b815481106110a3576110a3614434565b60009182526020909120015460cf805473ffffffffffffffffffffffffffffffffffffffff90921691839081106110dc576110dc614434565b9060005260206000200160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550611139565b61113281614463565b9050611023565b5060cf80548061114b5761114b61449b565b60008281526020812082017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff90810180547fffffffffffffffffffffffff000000000000000000000000000000000000000016905590910190915560405173ffffffffffffffffffffffffffffffffffffffff8416917f5c95b49c4d59d97a2f044167723f29c74b30f99702e3fd406c3830160aa9ccb891a25050565b60cd5473ffffffffffffffffffffffffffffffffffffffff16331480159061122657503373ffffffffffffffffffffffffffffffffffffffff821614155b1561125d576040517fddb5de5e00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff8116600081815260cc602052604080822080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00169055517f98c15241d6c02bc5ee0b780e11b3ea737a2defd9d04877edbe9f9497065bd02f9190a250565b33600090815260cc602052604090205460ff1661131a576040517ff8d2906c00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff16146113d05773ffffffffffffffffffffffffffffffffffffffff828116600090815260346020908152604080832093851683529290522054838110156113ba576040517f715ec26c00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6113ce83836113c987856143a3565b612a35565b505b61082d82846131b6565b60006113e46133a3565b905090565b60cd546040517f521d4de900000000000000000000000000000000000000000000000000000000815233600482015273ffffffffffffffffffffffffffffffffffffffff9091169063521d4de990602401602060405180830381865afa158015611457573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061147b9190614357565b6114b1576040517f99e120bc00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff8216600090815260ce602052604090206002015468010000000000000000900460ff1661151f576040517fc1ab6dc100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff8216600081815260ce602052604090819020839055517fe7b113fba37131b6396680a0c55790a697ec975e198ff8cfd89dac90a6379e61906109899084815260200190565b33600081815260346020908152604080832073ffffffffffffffffffffffffffffffffffffffff871684529091528120549091906109a390829086906113c99087906143cf565b60cd546040517f521d4de900000000000000000000000000000000000000000000000000000000815233600482015273ffffffffffffffffffffffffffffffffffffffff9091169063521d4de990602401602060405180830381865afa15801561162e573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906116529190614357565b611688576040517f99e120bc00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60d28190556040518181527fc3b69829afe2345596a02c8b587d41f796ba0094481d899e1b2e07b7532a1e219060200160405180910390a150565b33600090815260cc602052604090205460ff1661170c576040517ff8d2906c00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b610e358282612d12565b73ffffffffffffffffffffffffffffffffffffffff8116600090815260d06020526040812081611748610e10426143e2565b8152602001908152602001600020549050919050565b60cd546040517f521d4de900000000000000000000000000000000000000000000000000000000815233600482015273ffffffffffffffffffffffffffffffffffffffff9091169063521d4de990602401602060405180830381865afa1580156117cc573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906117f09190614357565b611826576040517f99e120bc00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff8216600090815260ce602052604090206002015468010000000000000000900460ff16611894576040517fc1ab6dc100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff8216600081815260ce602052604090819020600101839055517fe13ac9338b2ee623233f83c1b3ceab16490fa3e3737fac7f0970d0830a9f4871906109899084815260200190565b60cd546040517fe43581b800000000000000000000000000000000000000000000000000000000815233600482015273ffffffffffffffffffffffffffffffffffffffff9091169063e43581b890602401602060405180830381865afa15801561195f573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906119839190614357565b6119b9576040517fee3675d400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff8516600090815260ce602052604090206002015468010000000000000000900460ff1680611a10575073ffffffffffffffffffffffffffffffffffffffff8516155b15611a47576040517fc1ab6dc100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b633b9aca008267ffffffffffffffff161115611a8f576040517feca1d2c600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040805160a08101825260008082526020820181905291810182905260608101829052608081019190915284815260208082018581528315156080840190815267ffffffffffffffff808716604080870191825260016060880181815273ffffffffffffffffffffffffffffffffffffffff8e16600081815260ce9099528389208a5181559751888401559351600290970180549151965115156901000000000000000000027fffffffffffffffffffffffffffffffffffffffffffff00ffffffffffffffffff97151568010000000000000000027fffffffffffffffffffffffffffffffffffffffffffffff000000000000000000909316989096169790971717949094169290921790935560cf805492830181559093527facb8d954e2cfef495862221e91bd7523613cf8808827cb33edfe4904cc51bf290180547fffffffffffffffffffffffff0000000000000000000000000000000000000000168217905590517f53087ff85d80a7671594bd2e86b92af22e0b3c2c441c8033bba7399b7b5cbe2390611c49908890889088908890938452602084019290925267ffffffffffffffff1660408301521515606082015260800190565b60405180910390a2505050505050565b600060d381611c6a610e10426143e2565b815260200190815260200160002054905090565b73ffffffffffffffffffffffffffffffffffffffff81166000908152609960205260408120546109a9565b611cb333826131b6565b50565b60606037805461079f9061430a565b60cd5473ffffffffffffffffffffffffffffffffffffffff163314611d16576040517fb90cdbb100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff8116600081815260cc602052604080822080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00166001179055517f98c15241d6c02bc5ee0b780e11b3ea737a2defd9d04877edbe9f9497065bd02f9190a250565b60cd546040517f521d4de900000000000000000000000000000000000000000000000000000000815233600482015273ffffffffffffffffffffffffffffffffffffffff9091169063521d4de990602401602060405180830381865afa158015611dfb573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611e1f9190614357565b611e55576040517f99e120bc00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff8216600090815260ce602052604090206002015468010000000000000000900460ff16611ec3576040517fc1ab6dc100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b633b9aca008167ffffffffffffffff161115611f0b576040517feca1d2c600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff8216600081815260ce602090815260409182902060020180547fffffffffffffffffffffffffffffffffffffffffffffffff00000000000000001667ffffffffffffffff861690811790915591519182527f901f9de19b475adc8da4110434b8df940dce085afd05e2281c86807f3a899d299101610989565b33600081815260346020908152604080832073ffffffffffffffffffffffffffffffffffffffff8716845290915281205490919083811015612062576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602560248201527f45524332303a2064656372656173656420616c6c6f77616e63652062656c6f7760448201527f207a65726f00000000000000000000000000000000000000000000000000000060648201526084015b60405180910390fd5b610dd78286868403612a35565b6000336109a3818585612f03565b60cf818154811061208d57600080fd5b60009182526020909120015473ffffffffffffffffffffffffffffffffffffffff16905081565b606060cf80548060200260200160405190810160405280929190818152602001828054801561081857602002820191906000526020600020905b815473ffffffffffffffffffffffffffffffffffffffff1681526001909101906020018083116120ee575050505050905090565b73ffffffffffffffffffffffffffffffffffffffff8316600090815260ce60209081526040808320815160a081018352815481526001820154938101939093526002015467ffffffffffffffff81169183019190915260ff6801000000000000000082048116158015606085015269010000000000000000009092041615156080830152806121b2575080608001515b156121e9576040517fc1ab6dc100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60006121f7610e10426143e2565b600081815260d36020526040812054919250906122159087906143cf565b905060d254811115612253576040517f6d43d1ac00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600082815260d36020526040902081905561226e33876131b6565b33600090815260d160205260408120548791036122bb57633b9aca00846040015167ffffffffffffffff16826122a4919061441d565b6122ae91906143e2565b6122b890826143a3565b90505b6122dc73ffffffffffffffffffffffffffffffffffffffff89168783612be0565b979650505050505050565b83421115612351576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f45524332305065726d69743a206578706972656420646561646c696e650000006044820152606401612059565b60007f6e71edae12b1b97f4d1f60370fef10105fa2faae0126114a169c64845d6126c98888886123808c61341e565b60408051602081019690965273ffffffffffffffffffffffffffffffffffffffff94851690860152929091166060840152608083015260a082015260c0810186905260e00160405160208183030381529060405280519060200120905060006123e882613453565b905060006123f8828787876134bc565b90508973ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff161461248f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601e60248201527f45524332305065726d69743a20696e76616c6964207369676e617475726500006044820152606401612059565b61249a8a8a8a612a35565b50505050505050505050565b60cd546040517f521d4de900000000000000000000000000000000000000000000000000000000815233600482015273ffffffffffffffffffffffffffffffffffffffff9091169063521d4de990602401602060405180830381865afa158015612514573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906125389190614357565b61256e576040517f99e120bc00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff8116600090815260ce602052604090206002015468010000000000000000900460ff166125dc576040517fc1ab6dc100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff8116600081815260ce602090815260409182902060020180547fffffffffffffffffffffffffffffffffffffffffffff00ffffffffffffffffff811669010000000000000000009182900460ff16801592830291909117909255925192835292917ff7c93079dcbf699749d66345a351afab7d24219bb1d915c9f4fc4cf03f00d3979101610989565b60cd5473ffffffffffffffffffffffffffffffffffffffff1633146126cb576040517fb90cdbb100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60cd80547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83169081179091556040517f7dae230f18360d76a040c81f050aa14eb9d6dc7901b20fc5d855e2a20fe814d190600090a250565b73ffffffffffffffffffffffffffffffffffffffff163b151590565b600054610100900460ff16158080156127765750600054600160ff909116105b806127905750303b158015612790575060005460ff166001145b61281c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201527f647920696e697469616c697a65640000000000000000000000000000000000006064820152608401612059565b600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00166001179055801561287a57600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff166101001790555b3073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1663e9cbd8226040518163ffffffff1660e01b8152600401602060405180830381865afa1580156128dc573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061290091906144ca565b73ffffffffffffffffffffffffffffffffffffffff161461294d576040517f14bcf5c800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b612956846134e4565b61296084846135ba565b60cd80547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff84169081179091556040517f7dae230f18360d76a040c81f050aa14eb9d6dc7901b20fc5d855e2a20fe814d190600090a28015612a2f57600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15b50505050565b73ffffffffffffffffffffffffffffffffffffffff8316612ad7576040517f08c379a0000000000000000000000000000000000000000000000000000000008152602060048201526024808201527f45524332303a20617070726f76652066726f6d20746865207a65726f2061646460448201527f72657373000000000000000000000000000000000000000000000000000000006064820152608401612059565b73ffffffffffffffffffffffffffffffffffffffff8216612b7a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602260248201527f45524332303a20617070726f766520746f20746865207a65726f20616464726560448201527f73730000000000000000000000000000000000000000000000000000000000006064820152608401612059565b73ffffffffffffffffffffffffffffffffffffffff83811660008181526034602090815260408083209487168084529482529182902085905590518481527f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b9259101610af7565b60405173ffffffffffffffffffffffffffffffffffffffff831660248201526044810182905261082d9084907fa9059cbb00000000000000000000000000000000000000000000000000000000906064015b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff000000000000000000000000000000000000000000000000000000009093169290921790915261365b565b60405173ffffffffffffffffffffffffffffffffffffffff80851660248301528316604482015260648101829052612a2f9085907f23b872dd0000000000000000000000000000000000000000000000000000000090608401612c32565b73ffffffffffffffffffffffffffffffffffffffff8216612d8f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601f60248201527f45524332303a206d696e7420746f20746865207a65726f2061646472657373006044820152606401612059565b8060356000828254612da191906143cf565b909155505073ffffffffffffffffffffffffffffffffffffffff821660009081526033602052604081208054839290612ddb9084906143cf565b909155505060405181815273ffffffffffffffffffffffffffffffffffffffff8316906000907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef9060200160405180910390a35050565b73ffffffffffffffffffffffffffffffffffffffff8381166000908152603460209081526040808320938616835292905220547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8114612a2f5781811015612ef6576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f45524332303a20696e73756666696369656e7420616c6c6f77616e63650000006044820152606401612059565b612a2f8484848403612a35565b73ffffffffffffffffffffffffffffffffffffffff8316612fa6576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602560248201527f45524332303a207472616e736665722066726f6d20746865207a65726f20616460448201527f64726573730000000000000000000000000000000000000000000000000000006064820152608401612059565b73ffffffffffffffffffffffffffffffffffffffff8216613049576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602360248201527f45524332303a207472616e7366657220746f20746865207a65726f206164647260448201527f65737300000000000000000000000000000000000000000000000000000000006064820152608401612059565b73ffffffffffffffffffffffffffffffffffffffff8316600090815260336020526040902054818110156130ff576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f45524332303a207472616e7366657220616d6f756e742065786365656473206260448201527f616c616e636500000000000000000000000000000000000000000000000000006064820152608401612059565b73ffffffffffffffffffffffffffffffffffffffff8085166000908152603360205260408082208585039055918516815290812080548492906131439084906143cf565b925050819055508273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef846040516131a991815260200190565b60405180910390a3612a2f565b73ffffffffffffffffffffffffffffffffffffffff8216613259576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602160248201527f45524332303a206275726e2066726f6d20746865207a65726f2061646472657360448201527f73000000000000000000000000000000000000000000000000000000000000006064820152608401612059565b73ffffffffffffffffffffffffffffffffffffffff82166000908152603360205260409020548181101561330f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602260248201527f45524332303a206275726e20616d6f756e7420657863656564732062616c616e60448201527f63650000000000000000000000000000000000000000000000000000000000006064820152608401612059565b73ffffffffffffffffffffffffffffffffffffffff8316600090815260336020526040812083830390556035805484929061334b9084906143a3565b909155505060405182815260009073ffffffffffffffffffffffffffffffffffffffff8516907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef9060200160405180910390a3505050565b60006113e47f8b73c3c69bb8fe3d512ecc4cf759cc79239f7b179b0ffacaa9a75d522b39400f6133d260655490565b6066546040805160208101859052908101839052606081018290524660808201523060a082015260009060c0016040516020818303038152906040528051906020012090509392505050565b73ffffffffffffffffffffffffffffffffffffffff811660009081526099602052604090208054600181018255905b50919050565b60006109a96134606133a3565b836040517f19010000000000000000000000000000000000000000000000000000000000006020820152602281018390526042810182905260009060620160405160208183030381529060405280519060200120905092915050565b60008060006134cd87878787613767565b915091506134da8161387f565b5095945050505050565b600054610100900460ff1661357b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201527f6e697469616c697a696e670000000000000000000000000000000000000000006064820152608401612059565b611cb3816040518060400160405280600181526020017f3100000000000000000000000000000000000000000000000000000000000000815250613ad3565b600054610100900460ff16613651576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201527f6e697469616c697a696e670000000000000000000000000000000000000000006064820152608401612059565b610e358282613b84565b60006136bd826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c65648152508573ffffffffffffffffffffffffffffffffffffffff16613c349092919063ffffffff16565b80519091501561082d57808060200190518101906136db9190614357565b61082d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e60448201527f6f742073756363656564000000000000000000000000000000000000000000006064820152608401612059565b6000807f7fffffffffffffffffffffffffffffff5d576e7357a4501ddfe92f46681b20a083111561379e5750600090506003613876565b8460ff16601b141580156137b657508460ff16601c14155b156137c75750600090506004613876565b6040805160008082526020820180845289905260ff881692820192909252606081018690526080810185905260019060a0016020604051602081039080840390855afa15801561381b573d6000803e3d6000fd5b50506040517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0015191505073ffffffffffffffffffffffffffffffffffffffff811661386f57600060019250925050613876565b9150600090505b94509492505050565b6000816004811115613893576138936144e7565b0361389b5750565b60018160048111156138af576138af6144e7565b03613916576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601860248201527f45434453413a20696e76616c6964207369676e617475726500000000000000006044820152606401612059565b600281600481111561392a5761392a6144e7565b03613991576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601f60248201527f45434453413a20696e76616c6964207369676e6174757265206c656e677468006044820152606401612059565b60038160048111156139a5576139a56144e7565b03613a32576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602260248201527f45434453413a20696e76616c6964207369676e6174757265202773272076616c60448201527f75650000000000000000000000000000000000000000000000000000000000006064820152608401612059565b6004816004811115613a4657613a466144e7565b03611cb3576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602260248201527f45434453413a20696e76616c6964207369676e6174757265202776272076616c60448201527f75650000000000000000000000000000000000000000000000000000000000006064820152608401612059565b600054610100900460ff16613b6a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201527f6e697469616c697a696e670000000000000000000000000000000000000000006064820152608401612059565b815160209283012081519190920120606591909155606655565b600054610100900460ff16613c1b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201527f6e697469616c697a696e670000000000000000000000000000000000000000006064820152608401612059565b6036613c278382614564565b50603761082d8282614564565b6060613c438484600085613c4b565b949350505050565b606082471015613cdd576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f60448201527f722063616c6c00000000000000000000000000000000000000000000000000006064820152608401612059565b73ffffffffffffffffffffffffffffffffffffffff85163b613d5b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006044820152606401612059565b6000808673ffffffffffffffffffffffffffffffffffffffff168587604051613d84919061467e565b60006040518083038185875af1925050503d8060008114613dc1576040519150601f19603f3d011682016040523d82523d6000602084013e613dc6565b606091505b50915091506122dc82828660608315613de0575081610db7565b825115613df05782518084602001fd5b816040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016120599190613e48565b60005b83811015613e3f578181015183820152602001613e27565b50506000910152565b6020815260008251806020840152613e67816040850160208701613e24565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169190910160400192915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b600082601f830112613ed957600080fd5b813567ffffffffffffffff80821115613ef457613ef4613e99565b604051601f83017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0908116603f01168101908282118183101715613f3a57613f3a613e99565b81604052838152866020858801011115613f5357600080fd5b836020870160208301376000602085830101528094505050505092915050565b73ffffffffffffffffffffffffffffffffffffffff81168114611cb357600080fd5b600080600060608486031215613faa57600080fd5b833567ffffffffffffffff80821115613fc257600080fd5b613fce87838801613ec8565b94506020860135915080821115613fe457600080fd5b50613ff186828701613ec8565b925050604084013561400281613f73565b809150509250925092565b60006020828403121561401f57600080fd5b8135610db781613f73565b6000806040838503121561403d57600080fd5b823561404881613f73565b946020939093013593505050565b60008060006060848603121561406b57600080fd5b833561407681613f73565b9250602084013561408681613f73565b929592945050506040919091013590565b6000806000606084860312156140ac57600080fd5b83356140b781613f73565b925060208401359150604084013561400281613f73565b600080604083850312156140e157600080fd5b8235915060208301356140f381613f73565b809150509250929050565b60008060006060848603121561411357600080fd5b83359250602084013561412581613f73565b9150604084013561400281613f73565b60006020828403121561414757600080fd5b5035919050565b803567ffffffffffffffff8116811461416657600080fd5b919050565b8015158114611cb357600080fd5b600080600080600060a0868803121561419157600080fd5b853561419c81613f73565b945060208601359350604086013592506141b86060870161414e565b915060808601356141c88161416b565b809150509295509295909350565b600080604083850312156141e957600080fd5b82356141f481613f73565b91506142026020840161414e565b90509250929050565b6020808252825182820181905260009190848201906040850190845b8181101561425957835173ffffffffffffffffffffffffffffffffffffffff1683529284019291840191600101614227565b50909695505050505050565b600080600080600080600060e0888a03121561428057600080fd5b873561428b81613f73565b9650602088013561429b81613f73565b95506040880135945060608801359350608088013560ff811681146142bf57600080fd5b9699959850939692959460a0840135945060c09093013592915050565b600080604083850312156142ef57600080fd5b82356142fa81613f73565b915060208301356140f381613f73565b600181811c9082168061431e57607f821691505b60208210810361344d577f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b60006020828403121561436957600080fd5b8151610db78161416b565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b818103818111156109a9576109a9614374565b6000602082840312156143c857600080fd5b5051919050565b808201808211156109a9576109a9614374565b600082614418577f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b500490565b80820281158282048414176109a9576109a9614374565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff820361449457614494614374565b5060010190565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603160045260246000fd5b6000602082840312156144dc57600080fd5b8151610db781613f73565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b601f82111561082d57600081815260208120601f850160051c8101602086101561453d5750805b601f850160051c820191505b8181101561455c57828155600101614549565b505050505050565b815167ffffffffffffffff81111561457e5761457e613e99565b6145928161458c845461430a565b84614516565b602080601f8311600181146145e557600084156145af5750858301515b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600386901b1c1916600185901b17855561455c565b6000858152602081207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08616915b8281101561463257888601518255948401946001909101908401614613565b508582101561466e57878501517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600388901b60f8161c191681555b5050505050600190811b01905550565b60008251614690818460208701613e24565b919091019291505056fea2646970667358221220f2eb02bac1667a72be85ab617a5b5aa3d8f7a9b09b4d1fde9756b7a5636daf2164736f6c63430008110033", "devdoc": { "author": "Angle Labs, Inc.", - "details": "This contract supports bridge tokens having a minting right on the stablecoin (also referred to as the canonical or the native token)References: - FRAX implementation: https://polygonscan.com/address/0x45c32fA6DF82ead1e2EF74d17b76547EDdFaFF89#code - QiDAO implementation: https://snowtrace.io/address/0x5c49b268c9841AFF1Cc3B0a418ff5c3442eE3F3b#code", + "details": "This contract supports bridge tokens having a minting right on the stablecoin (also referred to as the canonical or the native token)", "kind": "dev", "methods": { "DOMAIN_SEPARATOR()": { @@ -1320,14 +1320,6 @@ "increaseAllowance(address,uint256)": { "details": "Atomically increases the allowance granted to `spender` by the caller. This is an alternative to {approve} that can be used as a mitigation for problems described in {IERC20-approve}. Emits an {Approval} event indicating the updated allowance. Requirements: - `spender` cannot be the zero address." }, - "initialize(string,string,address)": { - "details": "By default, agTokens are ERC-20 tokens with 18 decimals", - "params": { - "_treasury": "Reference to the `Treasury` contract associated to this agToken", - "name_": "Name of the token", - "symbol_": "Symbol of the token" - } - }, "mint(address,uint256)": { "details": "The contracts allowed to issue agTokens are the `StableMaster` contract, `VaultManager` contracts associated to this stablecoin as well as the flash loan module (if activated) and potentially contracts whitelisted by governance", "params": { @@ -1429,7 +1421,7 @@ "notice": "Burns `amount` tokens from a `burner` address" }, "burnStablecoin(uint256)": { - "notice": "Allows anyone to burn agToken without redeeming collateral back" + "notice": "Allows anyone to burn stablecoins" }, "chainTotalHourlyLimit()": { "notice": "Limit to the amount of tokens that can be sent from that chain to another chain" @@ -1504,7 +1496,7 @@ "storageLayout": { "storage": [ { - "astId": 941, + "astId": 770, "contract": "contracts/agToken/AgTokenSideChainMultiBridge.sol:AgTokenSideChainMultiBridge", "label": "_initialized", "offset": 0, @@ -1512,7 +1504,7 @@ "type": "t_uint8" }, { - "astId": 944, + "astId": 773, "contract": "contracts/agToken/AgTokenSideChainMultiBridge.sol:AgTokenSideChainMultiBridge", "label": "_initializing", "offset": 1, @@ -1520,7 +1512,7 @@ "type": "t_bool" }, { - "astId": 2938, + "astId": 2486, "contract": "contracts/agToken/AgTokenSideChainMultiBridge.sol:AgTokenSideChainMultiBridge", "label": "__gap", "offset": 0, @@ -1528,7 +1520,7 @@ "type": "t_array(t_uint256)50_storage" }, { - "astId": 1290, + "astId": 1119, "contract": "contracts/agToken/AgTokenSideChainMultiBridge.sol:AgTokenSideChainMultiBridge", "label": "_balances", "offset": 0, @@ -1536,7 +1528,7 @@ "type": "t_mapping(t_address,t_uint256)" }, { - "astId": 1296, + "astId": 1125, "contract": "contracts/agToken/AgTokenSideChainMultiBridge.sol:AgTokenSideChainMultiBridge", "label": "_allowances", "offset": 0, @@ -1544,7 +1536,7 @@ "type": "t_mapping(t_address,t_mapping(t_address,t_uint256))" }, { - "astId": 1298, + "astId": 1127, "contract": "contracts/agToken/AgTokenSideChainMultiBridge.sol:AgTokenSideChainMultiBridge", "label": "_totalSupply", "offset": 0, @@ -1552,7 +1544,7 @@ "type": "t_uint256" }, { - "astId": 1300, + "astId": 1129, "contract": "contracts/agToken/AgTokenSideChainMultiBridge.sol:AgTokenSideChainMultiBridge", "label": "_name", "offset": 0, @@ -1560,7 +1552,7 @@ "type": "t_string_storage" }, { - "astId": 1302, + "astId": 1131, "contract": "contracts/agToken/AgTokenSideChainMultiBridge.sol:AgTokenSideChainMultiBridge", "label": "_symbol", "offset": 0, @@ -1568,7 +1560,7 @@ "type": "t_string_storage" }, { - "astId": 1881, + "astId": 1710, "contract": "contracts/agToken/AgTokenSideChainMultiBridge.sol:AgTokenSideChainMultiBridge", "label": "__gap", "offset": 0, @@ -1576,7 +1568,7 @@ "type": "t_array(t_uint256)45_storage" }, { - "astId": 3655, + "astId": 3203, "contract": "contracts/agToken/AgTokenSideChainMultiBridge.sol:AgTokenSideChainMultiBridge", "label": "_HASHED_NAME", "offset": 0, @@ -1584,7 +1576,7 @@ "type": "t_bytes32" }, { - "astId": 3657, + "astId": 3205, "contract": "contracts/agToken/AgTokenSideChainMultiBridge.sol:AgTokenSideChainMultiBridge", "label": "_HASHED_VERSION", "offset": 0, @@ -1592,7 +1584,7 @@ "type": "t_bytes32" }, { - "astId": 3795, + "astId": 3343, "contract": "contracts/agToken/AgTokenSideChainMultiBridge.sol:AgTokenSideChainMultiBridge", "label": "__gap", "offset": 0, @@ -1600,15 +1592,15 @@ "type": "t_array(t_uint256)50_storage" }, { - "astId": 2011, + "astId": 1840, "contract": "contracts/agToken/AgTokenSideChainMultiBridge.sol:AgTokenSideChainMultiBridge", "label": "_nonces", "offset": 0, "slot": "153", - "type": "t_mapping(t_address,t_struct(Counter)2945_storage)" + "type": "t_mapping(t_address,t_struct(Counter)2493_storage)" }, { - "astId": 2019, + "astId": 1848, "contract": "contracts/agToken/AgTokenSideChainMultiBridge.sol:AgTokenSideChainMultiBridge", "label": "_PERMIT_TYPEHASH_DEPRECATED_SLOT", "offset": 0, @@ -1616,7 +1608,7 @@ "type": "t_bytes32" }, { - "astId": 2175, + "astId": 2004, "contract": "contracts/agToken/AgTokenSideChainMultiBridge.sol:AgTokenSideChainMultiBridge", "label": "__gap", "offset": 0, @@ -1624,7 +1616,7 @@ "type": "t_array(t_uint256)49_storage" }, { - "astId": 11202, + "astId": 7427, "contract": "contracts/agToken/AgTokenSideChainMultiBridge.sol:AgTokenSideChainMultiBridge", "label": "isMinter", "offset": 0, @@ -1632,7 +1624,7 @@ "type": "t_mapping(t_address,t_bool)" }, { - "astId": 11205, + "astId": 7430, "contract": "contracts/agToken/AgTokenSideChainMultiBridge.sol:AgTokenSideChainMultiBridge", "label": "treasury", "offset": 0, @@ -1640,15 +1632,15 @@ "type": "t_address" }, { - "astId": 10363, + "astId": 7739, "contract": "contracts/agToken/AgTokenSideChainMultiBridge.sol:AgTokenSideChainMultiBridge", "label": "bridges", "offset": 0, "slot": "206", - "type": "t_mapping(t_address,t_struct(BridgeDetails)10357_storage)" + "type": "t_mapping(t_address,t_struct(BridgeDetails)7733_storage)" }, { - "astId": 10367, + "astId": 7743, "contract": "contracts/agToken/AgTokenSideChainMultiBridge.sol:AgTokenSideChainMultiBridge", "label": "bridgeTokensList", "offset": 0, @@ -1656,7 +1648,7 @@ "type": "t_array(t_address)dyn_storage" }, { - "astId": 10374, + "astId": 7750, "contract": "contracts/agToken/AgTokenSideChainMultiBridge.sol:AgTokenSideChainMultiBridge", "label": "usage", "offset": 0, @@ -1664,7 +1656,7 @@ "type": "t_mapping(t_address,t_mapping(t_uint256,t_uint256))" }, { - "astId": 10379, + "astId": 7755, "contract": "contracts/agToken/AgTokenSideChainMultiBridge.sol:AgTokenSideChainMultiBridge", "label": "isFeeExempt", "offset": 0, @@ -1672,7 +1664,7 @@ "type": "t_mapping(t_address,t_uint256)" }, { - "astId": 10382, + "astId": 7758, "contract": "contracts/agToken/AgTokenSideChainMultiBridge.sol:AgTokenSideChainMultiBridge", "label": "chainTotalHourlyLimit", "offset": 0, @@ -1680,7 +1672,7 @@ "type": "t_uint256" }, { - "astId": 10387, + "astId": 7763, "contract": "contracts/agToken/AgTokenSideChainMultiBridge.sol:AgTokenSideChainMultiBridge", "label": "chainTotalUsage", "offset": 0, @@ -1749,19 +1741,19 @@ "numberOfBytes": "32", "value": "t_mapping(t_uint256,t_uint256)" }, - "t_mapping(t_address,t_struct(BridgeDetails)10357_storage)": { + "t_mapping(t_address,t_struct(BridgeDetails)7733_storage)": { "encoding": "mapping", "key": "t_address", "label": "mapping(address => struct AgTokenSideChainMultiBridge.BridgeDetails)", "numberOfBytes": "32", - "value": "t_struct(BridgeDetails)10357_storage" + "value": "t_struct(BridgeDetails)7733_storage" }, - "t_mapping(t_address,t_struct(Counter)2945_storage)": { + "t_mapping(t_address,t_struct(Counter)2493_storage)": { "encoding": "mapping", "key": "t_address", "label": "mapping(address => struct CountersUpgradeable.Counter)", "numberOfBytes": "32", - "value": "t_struct(Counter)2945_storage" + "value": "t_struct(Counter)2493_storage" }, "t_mapping(t_address,t_uint256)": { "encoding": "mapping", @@ -1782,12 +1774,12 @@ "label": "string", "numberOfBytes": "32" }, - "t_struct(BridgeDetails)10357_storage": { + "t_struct(BridgeDetails)7733_storage": { "encoding": "inplace", "label": "struct AgTokenSideChainMultiBridge.BridgeDetails", "members": [ { - "astId": 10348, + "astId": 7724, "contract": "contracts/agToken/AgTokenSideChainMultiBridge.sol:AgTokenSideChainMultiBridge", "label": "limit", "offset": 0, @@ -1795,7 +1787,7 @@ "type": "t_uint256" }, { - "astId": 10350, + "astId": 7726, "contract": "contracts/agToken/AgTokenSideChainMultiBridge.sol:AgTokenSideChainMultiBridge", "label": "hourlyLimit", "offset": 0, @@ -1803,7 +1795,7 @@ "type": "t_uint256" }, { - "astId": 10352, + "astId": 7728, "contract": "contracts/agToken/AgTokenSideChainMultiBridge.sol:AgTokenSideChainMultiBridge", "label": "fee", "offset": 0, @@ -1811,7 +1803,7 @@ "type": "t_uint64" }, { - "astId": 10354, + "astId": 7730, "contract": "contracts/agToken/AgTokenSideChainMultiBridge.sol:AgTokenSideChainMultiBridge", "label": "allowed", "offset": 8, @@ -1819,7 +1811,7 @@ "type": "t_bool" }, { - "astId": 10356, + "astId": 7732, "contract": "contracts/agToken/AgTokenSideChainMultiBridge.sol:AgTokenSideChainMultiBridge", "label": "paused", "offset": 9, @@ -1829,12 +1821,12 @@ ], "numberOfBytes": "96" }, - "t_struct(Counter)2945_storage": { + "t_struct(Counter)2493_storage": { "encoding": "inplace", "label": "struct CountersUpgradeable.Counter", "members": [ { - "astId": 2944, + "astId": 2492, "contract": "contracts/agToken/AgTokenSideChainMultiBridge.sol:AgTokenSideChainMultiBridge", "label": "_value", "offset": 0, diff --git a/deployments/gnosis/CoreBorrowTest.json b/deployments/gnosis/CoreBorrowTest.json new file mode 100644 index 00000000..af23aa5e --- /dev/null +++ b/deployments/gnosis/CoreBorrowTest.json @@ -0,0 +1,337 @@ +{ + "address": "0x67b9C7c45BBdd1A78aEd4B8FF3B1bb3C8170BDAB", + "abi": [ + { + "inputs": [ + { + "internalType": "address", + "name": "_logic", + "type": "address" + }, + { + "internalType": "address", + "name": "admin_", + "type": "address" + }, + { + "internalType": "bytes", + "name": "_data", + "type": "bytes" + } + ], + "stateMutability": "payable", + "type": "constructor" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "previousAdmin", + "type": "address" + }, + { + "indexed": false, + "internalType": "address", + "name": "newAdmin", + "type": "address" + } + ], + "name": "AdminChanged", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "beacon", + "type": "address" + } + ], + "name": "BeaconUpgraded", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "implementation", + "type": "address" + } + ], + "name": "Upgraded", + "type": "event" + }, + { + "stateMutability": "payable", + "type": "fallback" + }, + { + "inputs": [], + "name": "admin", + "outputs": [ + { + "internalType": "address", + "name": "admin_", + "type": "address" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "newAdmin", + "type": "address" + } + ], + "name": "changeAdmin", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "implementation", + "outputs": [ + { + "internalType": "address", + "name": "implementation_", + "type": "address" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "newImplementation", + "type": "address" + } + ], + "name": "upgradeTo", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "newImplementation", + "type": "address" + }, + { + "internalType": "bytes", + "name": "data", + "type": "bytes" + } + ], + "name": "upgradeToAndCall", + "outputs": [], + "stateMutability": "payable", + "type": "function" + }, + { + "stateMutability": "payable", + "type": "receive" + } + ], + "transactionHash": "0x11d42f8d54411eb3261d849da871617eb34d648a3230a876b404de3479ef14c6", + "receipt": { + "to": null, + "from": "0xfdA462548Ce04282f4B6D6619823a7C64Fdc0185", + "contractAddress": "0x67b9C7c45BBdd1A78aEd4B8FF3B1bb3C8170BDAB", + "transactionIndex": 11, + "gasUsed": "1038825", + "logsBloom": "0x00000204000000000800000500000000480000000000000040000000200000000000000000010000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000020000400000000000000800000000800000000000001000000000000000000000400000000000000000000000000003000080000000000000804000000000000000000000000000000400000000000000004000001000000000001000000020020400000000008000040000000800000400000100000000000020000000800000000000000000000000080400000000000000000000000000040000", + "blockHash": "0xb62e15ba18735e80e3ffe2241671922cd729b0a3584d076b9422bf0cd0c1e258", + "transactionHash": "0x11d42f8d54411eb3261d849da871617eb34d648a3230a876b404de3479ef14c6", + "logs": [ + { + "transactionIndex": 11, + "blockNumber": 31876779, + "transactionHash": "0x11d42f8d54411eb3261d849da871617eb34d648a3230a876b404de3479ef14c6", + "address": "0x67b9C7c45BBdd1A78aEd4B8FF3B1bb3C8170BDAB", + "topics": [ + "0xbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b", + "0x00000000000000000000000031429d1856ad1377a8a0079410b297e1a9e214c2" + ], + "data": "0x", + "logIndex": 141, + "blockHash": "0xb62e15ba18735e80e3ffe2241671922cd729b0a3584d076b9422bf0cd0c1e258" + }, + { + "transactionIndex": 11, + "blockNumber": 31876779, + "transactionHash": "0x11d42f8d54411eb3261d849da871617eb34d648a3230a876b404de3479ef14c6", + "address": "0x67b9C7c45BBdd1A78aEd4B8FF3B1bb3C8170BDAB", + "topics": [ + "0x2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d", + "0x7935bd0ae54bc31f548c14dba4d37c5c64b3f8ca900cb468fb8abd54d5894f55", + "0x000000000000000000000000fda462548ce04282f4b6d6619823a7c64fdc0185", + "0x000000000000000000000000fda462548ce04282f4b6d6619823a7c64fdc0185" + ], + "data": "0x", + "logIndex": 142, + "blockHash": "0xb62e15ba18735e80e3ffe2241671922cd729b0a3584d076b9422bf0cd0c1e258" + }, + { + "transactionIndex": 11, + "blockNumber": 31876779, + "transactionHash": "0x11d42f8d54411eb3261d849da871617eb34d648a3230a876b404de3479ef14c6", + "address": "0x67b9C7c45BBdd1A78aEd4B8FF3B1bb3C8170BDAB", + "topics": [ + "0x2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d", + "0x55435dd261a4b9b3364963f7738a7a662ad9c84396d64be3365284bb7f0a5041", + "0x000000000000000000000000f0a31faec2b4fc6396c65b1af1f6a71e653f11f0", + "0x000000000000000000000000fda462548ce04282f4b6d6619823a7c64fdc0185" + ], + "data": "0x", + "logIndex": 143, + "blockHash": "0xb62e15ba18735e80e3ffe2241671922cd729b0a3584d076b9422bf0cd0c1e258" + }, + { + "transactionIndex": 11, + "blockNumber": 31876779, + "transactionHash": "0x11d42f8d54411eb3261d849da871617eb34d648a3230a876b404de3479ef14c6", + "address": "0x67b9C7c45BBdd1A78aEd4B8FF3B1bb3C8170BDAB", + "topics": [ + "0x2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d", + "0x55435dd261a4b9b3364963f7738a7a662ad9c84396d64be3365284bb7f0a5041", + "0x000000000000000000000000fda462548ce04282f4b6d6619823a7c64fdc0185", + "0x000000000000000000000000fda462548ce04282f4b6d6619823a7c64fdc0185" + ], + "data": "0x", + "logIndex": 144, + "blockHash": "0xb62e15ba18735e80e3ffe2241671922cd729b0a3584d076b9422bf0cd0c1e258" + }, + { + "transactionIndex": 11, + "blockNumber": 31876779, + "transactionHash": "0x11d42f8d54411eb3261d849da871617eb34d648a3230a876b404de3479ef14c6", + "address": "0x67b9C7c45BBdd1A78aEd4B8FF3B1bb3C8170BDAB", + "topics": [ + "0xbd79b86ffe0ab8e8776151514217cd7cacd52c909f66475c3af44e129f0b00ff", + "0x55435dd261a4b9b3364963f7738a7a662ad9c84396d64be3365284bb7f0a5041", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x7935bd0ae54bc31f548c14dba4d37c5c64b3f8ca900cb468fb8abd54d5894f55" + ], + "data": "0x", + "logIndex": 145, + "blockHash": "0xb62e15ba18735e80e3ffe2241671922cd729b0a3584d076b9422bf0cd0c1e258" + }, + { + "transactionIndex": 11, + "blockNumber": 31876779, + "transactionHash": "0x11d42f8d54411eb3261d849da871617eb34d648a3230a876b404de3479ef14c6", + "address": "0x67b9C7c45BBdd1A78aEd4B8FF3B1bb3C8170BDAB", + "topics": [ + "0xbd79b86ffe0ab8e8776151514217cd7cacd52c909f66475c3af44e129f0b00ff", + "0x7935bd0ae54bc31f548c14dba4d37c5c64b3f8ca900cb468fb8abd54d5894f55", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x7935bd0ae54bc31f548c14dba4d37c5c64b3f8ca900cb468fb8abd54d5894f55" + ], + "data": "0x", + "logIndex": 146, + "blockHash": "0xb62e15ba18735e80e3ffe2241671922cd729b0a3584d076b9422bf0cd0c1e258" + }, + { + "transactionIndex": 11, + "blockNumber": 31876779, + "transactionHash": "0x11d42f8d54411eb3261d849da871617eb34d648a3230a876b404de3479ef14c6", + "address": "0x67b9C7c45BBdd1A78aEd4B8FF3B1bb3C8170BDAB", + "topics": [ + "0xbd79b86ffe0ab8e8776151514217cd7cacd52c909f66475c3af44e129f0b00ff", + "0x0ae0130c6b34f32239dfe5e419a3fbd7546b44e99783257f2d93526d5a936d46", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x7935bd0ae54bc31f548c14dba4d37c5c64b3f8ca900cb468fb8abd54d5894f55" + ], + "data": "0x", + "logIndex": 147, + "blockHash": "0xb62e15ba18735e80e3ffe2241671922cd729b0a3584d076b9422bf0cd0c1e258" + }, + { + "transactionIndex": 11, + "blockNumber": 31876779, + "transactionHash": "0x11d42f8d54411eb3261d849da871617eb34d648a3230a876b404de3479ef14c6", + "address": "0x67b9C7c45BBdd1A78aEd4B8FF3B1bb3C8170BDAB", + "topics": [ + "0x7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb3847402498" + ], + "data": "0x0000000000000000000000000000000000000000000000000000000000000001", + "logIndex": 148, + "blockHash": "0xb62e15ba18735e80e3ffe2241671922cd729b0a3584d076b9422bf0cd0c1e258" + }, + { + "transactionIndex": 11, + "blockNumber": 31876779, + "transactionHash": "0x11d42f8d54411eb3261d849da871617eb34d648a3230a876b404de3479ef14c6", + "address": "0x67b9C7c45BBdd1A78aEd4B8FF3B1bb3C8170BDAB", + "topics": [ + "0x7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f" + ], + "data": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000009a5b060bd7b8f86c4c0d720a17367729670afb19", + "logIndex": 149, + "blockHash": "0xb62e15ba18735e80e3ffe2241671922cd729b0a3584d076b9422bf0cd0c1e258" + } + ], + "blockNumber": 31876779, + "cumulativeGasUsed": "2667323", + "status": 1, + "byzantium": true + }, + "args": [ + "0x31429d1856aD1377A8A0079410B297e1a9e214c2", + "0x9a5b060Bd7b8f86c4C0D720a17367729670AfB19", + "0x485cc955000000000000000000000000fda462548ce04282f4b6d6619823a7c64fdc0185000000000000000000000000f0a31faec2b4fc6396c65b1af1f6a71e653f11f0" + ], + "numDeployments": 1, + "solcInputHash": "871924e0c138825a2736b76def8fef8d", + "metadata": "{\"compiler\":{\"version\":\"0.8.17+commit.8df45f5f\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_logic\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"admin_\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"_data\",\"type\":\"bytes\"}],\"stateMutability\":\"payable\",\"type\":\"constructor\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"previousAdmin\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"newAdmin\",\"type\":\"address\"}],\"name\":\"AdminChanged\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"beacon\",\"type\":\"address\"}],\"name\":\"BeaconUpgraded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"implementation\",\"type\":\"address\"}],\"name\":\"Upgraded\",\"type\":\"event\"},{\"stateMutability\":\"payable\",\"type\":\"fallback\"},{\"inputs\":[],\"name\":\"admin\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"admin_\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newAdmin\",\"type\":\"address\"}],\"name\":\"changeAdmin\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"implementation\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"implementation_\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newImplementation\",\"type\":\"address\"}],\"name\":\"upgradeTo\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newImplementation\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"}],\"name\":\"upgradeToAndCall\",\"outputs\":[],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"stateMutability\":\"payable\",\"type\":\"receive\"}],\"devdoc\":{\"details\":\"This contract implements a proxy that is upgradeable by an admin. It is fully forked from OpenZeppelin `TransparentUpgradeableProxy` To avoid https://medium.com/nomic-labs-blog/malicious-backdoors-in-ethereum-proxies-62629adf3357[proxy selector clashing], which can potentially be used in an attack, this contract uses the https://blog.openzeppelin.com/the-transparent-proxy-pattern/[transparent proxy pattern]. This pattern implies two things that go hand in hand: 1. If any account other than the admin calls the proxy, the call will be forwarded to the implementation, even if that call matches one of the admin functions exposed by the proxy itself. 2. If the admin calls the proxy, it can access the admin functions, but its calls will never be forwarded to the implementation. If the admin tries to call a function on the implementation it will fail with an error that says \\\"admin cannot fallback to proxy target\\\". These properties mean that the admin account can only be used for admin actions like upgrading the proxy or changing the admin, so it's best if it's a dedicated account that is not used for anything else. This will avoid headaches due to sudden errors when trying to call a function from the proxy implementation. Our recommendation is for the dedicated account to be an instance of the {ProxyAdmin} contract. If set up this way, you should think of the `ProxyAdmin` instance as the real administrative interface of your proxy.\",\"kind\":\"dev\",\"methods\":{\"admin()\":{\"details\":\"Returns the current admin. NOTE: Only the admin can call this function. See {ProxyAdmin-getProxyAdmin}. TIP: To get this value clients can read directly from the storage slot shown below (specified by EIP1967) using the https://eth.wiki/json-rpc/API#eth_getstorageat[`eth_getStorageAt`] RPC call. `0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103`\"},\"changeAdmin(address)\":{\"details\":\"Changes the admin of the proxy. Emits an {AdminChanged} event. NOTE: Only the admin can call this function. See {ProxyAdmin-changeProxyAdmin}.\"},\"constructor\":{\"details\":\"Initializes an upgradeable proxy managed by `_admin`, backed by the implementation at `_logic`, and optionally initialized with `_data` as explained in {ERC1967Proxy-constructor}.\"},\"implementation()\":{\"details\":\"Returns the current implementation. NOTE: Only the admin can call this function. See {ProxyAdmin-getProxyImplementation}. TIP: To get this value clients can read directly from the storage slot shown below (specified by EIP1967) using the https://eth.wiki/json-rpc/API#eth_getstorageat[`eth_getStorageAt`] RPC call. `0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc`\"},\"upgradeTo(address)\":{\"details\":\"Upgrade the implementation of the proxy. NOTE: Only the admin can call this function. See {ProxyAdmin-upgrade}.\"},\"upgradeToAndCall(address,bytes)\":{\"details\":\"Upgrade the implementation of the proxy, and then call a function from the new implementation as specified by `data`, which should be an encoded function call. This is useful to initialize new storage variables in the proxied contract. NOTE: Only the admin can call this function. See {ProxyAdmin-upgradeAndCall}.\"}},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/external/TransparentUpgradeableProxy.sol\":\"TransparentUpgradeableProxy\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":1000000},\"remappings\":[]},\"sources\":{\"@openzeppelin/contracts/interfaces/draft-IERC1822.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.5.0) (interfaces/draft-IERC1822.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev ERC1822: Universal Upgradeable Proxy Standard (UUPS) documents a method for upgradeability through a simplified\\n * proxy whose upgrades are fully controlled by the current implementation.\\n */\\ninterface IERC1822Proxiable {\\n /**\\n * @dev Returns the storage slot that the proxiable contract assumes is being used to store the implementation\\n * address.\\n *\\n * IMPORTANT: A proxy pointing at a proxiable contract should not be considered proxiable itself, because this risks\\n * bricking a proxy that upgrades to it, by delegating to itself until out of gas. Thus it is critical that this\\n * function revert if invoked through a proxy.\\n */\\n function proxiableUUID() external view returns (bytes32);\\n}\\n\",\"keccak256\":\"0x1d4afe6cb24200cc4545eed814ecf5847277dfe5d613a1707aad5fceecebcfff\",\"license\":\"MIT\"},\"@openzeppelin/contracts/proxy/ERC1967/ERC1967Proxy.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.7.0) (proxy/ERC1967/ERC1967Proxy.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../Proxy.sol\\\";\\nimport \\\"./ERC1967Upgrade.sol\\\";\\n\\n/**\\n * @dev This contract implements an upgradeable proxy. It is upgradeable because calls are delegated to an\\n * implementation address that can be changed. This address is stored in storage in the location specified by\\n * https://eips.ethereum.org/EIPS/eip-1967[EIP1967], so that it doesn't conflict with the storage layout of the\\n * implementation behind the proxy.\\n */\\ncontract ERC1967Proxy is Proxy, ERC1967Upgrade {\\n /**\\n * @dev Initializes the upgradeable proxy with an initial implementation specified by `_logic`.\\n *\\n * If `_data` is nonempty, it's used as data in a delegate call to `_logic`. This will typically be an encoded\\n * function call, and allows initializing the storage of the proxy like a Solidity constructor.\\n */\\n constructor(address _logic, bytes memory _data) payable {\\n _upgradeToAndCall(_logic, _data, false);\\n }\\n\\n /**\\n * @dev Returns the current implementation address.\\n */\\n function _implementation() internal view virtual override returns (address impl) {\\n return ERC1967Upgrade._getImplementation();\\n }\\n}\\n\",\"keccak256\":\"0xa2b22da3032e50b55f95ec1d13336102d675f341167aa76db571ef7f8bb7975d\",\"license\":\"MIT\"},\"@openzeppelin/contracts/proxy/ERC1967/ERC1967Upgrade.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.5.0) (proxy/ERC1967/ERC1967Upgrade.sol)\\n\\npragma solidity ^0.8.2;\\n\\nimport \\\"../beacon/IBeacon.sol\\\";\\nimport \\\"../../interfaces/draft-IERC1822.sol\\\";\\nimport \\\"../../utils/Address.sol\\\";\\nimport \\\"../../utils/StorageSlot.sol\\\";\\n\\n/**\\n * @dev This abstract contract provides getters and event emitting update functions for\\n * https://eips.ethereum.org/EIPS/eip-1967[EIP1967] slots.\\n *\\n * _Available since v4.1._\\n *\\n * @custom:oz-upgrades-unsafe-allow delegatecall\\n */\\nabstract contract ERC1967Upgrade {\\n // This is the keccak-256 hash of \\\"eip1967.proxy.rollback\\\" subtracted by 1\\n bytes32 private constant _ROLLBACK_SLOT = 0x4910fdfa16fed3260ed0e7147f7cc6da11a60208b5b9406d12a635614ffd9143;\\n\\n /**\\n * @dev Storage slot with the address of the current implementation.\\n * This is the keccak-256 hash of \\\"eip1967.proxy.implementation\\\" subtracted by 1, and is\\n * validated in the constructor.\\n */\\n bytes32 internal constant _IMPLEMENTATION_SLOT = 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc;\\n\\n /**\\n * @dev Emitted when the implementation is upgraded.\\n */\\n event Upgraded(address indexed implementation);\\n\\n /**\\n * @dev Returns the current implementation address.\\n */\\n function _getImplementation() internal view returns (address) {\\n return StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value;\\n }\\n\\n /**\\n * @dev Stores a new address in the EIP1967 implementation slot.\\n */\\n function _setImplementation(address newImplementation) private {\\n require(Address.isContract(newImplementation), \\\"ERC1967: new implementation is not a contract\\\");\\n StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value = newImplementation;\\n }\\n\\n /**\\n * @dev Perform implementation upgrade\\n *\\n * Emits an {Upgraded} event.\\n */\\n function _upgradeTo(address newImplementation) internal {\\n _setImplementation(newImplementation);\\n emit Upgraded(newImplementation);\\n }\\n\\n /**\\n * @dev Perform implementation upgrade with additional setup call.\\n *\\n * Emits an {Upgraded} event.\\n */\\n function _upgradeToAndCall(\\n address newImplementation,\\n bytes memory data,\\n bool forceCall\\n ) internal {\\n _upgradeTo(newImplementation);\\n if (data.length > 0 || forceCall) {\\n Address.functionDelegateCall(newImplementation, data);\\n }\\n }\\n\\n /**\\n * @dev Perform implementation upgrade with security checks for UUPS proxies, and additional setup call.\\n *\\n * Emits an {Upgraded} event.\\n */\\n function _upgradeToAndCallUUPS(\\n address newImplementation,\\n bytes memory data,\\n bool forceCall\\n ) internal {\\n // Upgrades from old implementations will perform a rollback test. This test requires the new\\n // implementation to upgrade back to the old, non-ERC1822 compliant, implementation. Removing\\n // this special case will break upgrade paths from old UUPS implementation to new ones.\\n if (StorageSlot.getBooleanSlot(_ROLLBACK_SLOT).value) {\\n _setImplementation(newImplementation);\\n } else {\\n try IERC1822Proxiable(newImplementation).proxiableUUID() returns (bytes32 slot) {\\n require(slot == _IMPLEMENTATION_SLOT, \\\"ERC1967Upgrade: unsupported proxiableUUID\\\");\\n } catch {\\n revert(\\\"ERC1967Upgrade: new implementation is not UUPS\\\");\\n }\\n _upgradeToAndCall(newImplementation, data, forceCall);\\n }\\n }\\n\\n /**\\n * @dev Storage slot with the admin of the contract.\\n * This is the keccak-256 hash of \\\"eip1967.proxy.admin\\\" subtracted by 1, and is\\n * validated in the constructor.\\n */\\n bytes32 internal constant _ADMIN_SLOT = 0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103;\\n\\n /**\\n * @dev Emitted when the admin account has changed.\\n */\\n event AdminChanged(address previousAdmin, address newAdmin);\\n\\n /**\\n * @dev Returns the current admin.\\n */\\n function _getAdmin() internal view returns (address) {\\n return StorageSlot.getAddressSlot(_ADMIN_SLOT).value;\\n }\\n\\n /**\\n * @dev Stores a new address in the EIP1967 admin slot.\\n */\\n function _setAdmin(address newAdmin) private {\\n require(newAdmin != address(0), \\\"ERC1967: new admin is the zero address\\\");\\n StorageSlot.getAddressSlot(_ADMIN_SLOT).value = newAdmin;\\n }\\n\\n /**\\n * @dev Changes the admin of the proxy.\\n *\\n * Emits an {AdminChanged} event.\\n */\\n function _changeAdmin(address newAdmin) internal {\\n emit AdminChanged(_getAdmin(), newAdmin);\\n _setAdmin(newAdmin);\\n }\\n\\n /**\\n * @dev The storage slot of the UpgradeableBeacon contract which defines the implementation for this proxy.\\n * This is bytes32(uint256(keccak256('eip1967.proxy.beacon')) - 1)) and is validated in the constructor.\\n */\\n bytes32 internal constant _BEACON_SLOT = 0xa3f0ad74e5423aebfd80d3ef4346578335a9a72aeaee59ff6cb3582b35133d50;\\n\\n /**\\n * @dev Emitted when the beacon is upgraded.\\n */\\n event BeaconUpgraded(address indexed beacon);\\n\\n /**\\n * @dev Returns the current beacon.\\n */\\n function _getBeacon() internal view returns (address) {\\n return StorageSlot.getAddressSlot(_BEACON_SLOT).value;\\n }\\n\\n /**\\n * @dev Stores a new beacon in the EIP1967 beacon slot.\\n */\\n function _setBeacon(address newBeacon) private {\\n require(Address.isContract(newBeacon), \\\"ERC1967: new beacon is not a contract\\\");\\n require(\\n Address.isContract(IBeacon(newBeacon).implementation()),\\n \\\"ERC1967: beacon implementation is not a contract\\\"\\n );\\n StorageSlot.getAddressSlot(_BEACON_SLOT).value = newBeacon;\\n }\\n\\n /**\\n * @dev Perform beacon upgrade with additional setup call. Note: This upgrades the address of the beacon, it does\\n * not upgrade the implementation contained in the beacon (see {UpgradeableBeacon-_setImplementation} for that).\\n *\\n * Emits a {BeaconUpgraded} event.\\n */\\n function _upgradeBeaconToAndCall(\\n address newBeacon,\\n bytes memory data,\\n bool forceCall\\n ) internal {\\n _setBeacon(newBeacon);\\n emit BeaconUpgraded(newBeacon);\\n if (data.length > 0 || forceCall) {\\n Address.functionDelegateCall(IBeacon(newBeacon).implementation(), data);\\n }\\n }\\n}\\n\",\"keccak256\":\"0xabf3f59bc0e5423eae45e459dbe92e7052c6983628d39008590edc852a62f94a\",\"license\":\"MIT\"},\"@openzeppelin/contracts/proxy/Proxy.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.6.0) (proxy/Proxy.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev This abstract contract provides a fallback function that delegates all calls to another contract using the EVM\\n * instruction `delegatecall`. We refer to the second contract as the _implementation_ behind the proxy, and it has to\\n * be specified by overriding the virtual {_implementation} function.\\n *\\n * Additionally, delegation to the implementation can be triggered manually through the {_fallback} function, or to a\\n * different contract through the {_delegate} function.\\n *\\n * The success and return data of the delegated call will be returned back to the caller of the proxy.\\n */\\nabstract contract Proxy {\\n /**\\n * @dev Delegates the current call to `implementation`.\\n *\\n * This function does not return to its internal call site, it will return directly to the external caller.\\n */\\n function _delegate(address implementation) internal virtual {\\n assembly {\\n // Copy msg.data. We take full control of memory in this inline assembly\\n // block because it will not return to Solidity code. We overwrite the\\n // Solidity scratch pad at memory position 0.\\n calldatacopy(0, 0, calldatasize())\\n\\n // Call the implementation.\\n // out and outsize are 0 because we don't know the size yet.\\n let result := delegatecall(gas(), implementation, 0, calldatasize(), 0, 0)\\n\\n // Copy the returned data.\\n returndatacopy(0, 0, returndatasize())\\n\\n switch result\\n // delegatecall returns 0 on error.\\n case 0 {\\n revert(0, returndatasize())\\n }\\n default {\\n return(0, returndatasize())\\n }\\n }\\n }\\n\\n /**\\n * @dev This is a virtual function that should be overridden so it returns the address to which the fallback function\\n * and {_fallback} should delegate.\\n */\\n function _implementation() internal view virtual returns (address);\\n\\n /**\\n * @dev Delegates the current call to the address returned by `_implementation()`.\\n *\\n * This function does not return to its internal call site, it will return directly to the external caller.\\n */\\n function _fallback() internal virtual {\\n _beforeFallback();\\n _delegate(_implementation());\\n }\\n\\n /**\\n * @dev Fallback function that delegates calls to the address returned by `_implementation()`. Will run if no other\\n * function in the contract matches the call data.\\n */\\n fallback() external payable virtual {\\n _fallback();\\n }\\n\\n /**\\n * @dev Fallback function that delegates calls to the address returned by `_implementation()`. Will run if call data\\n * is empty.\\n */\\n receive() external payable virtual {\\n _fallback();\\n }\\n\\n /**\\n * @dev Hook that is called before falling back to the implementation. Can happen as part of a manual `_fallback`\\n * call, or as part of the Solidity `fallback` or `receive` functions.\\n *\\n * If overridden should call `super._beforeFallback()`.\\n */\\n function _beforeFallback() internal virtual {}\\n}\\n\",\"keccak256\":\"0xc130fe33f1b2132158531a87734153293f6d07bc263ff4ac90e85da9c82c0e27\",\"license\":\"MIT\"},\"@openzeppelin/contracts/proxy/beacon/IBeacon.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (proxy/beacon/IBeacon.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev This is the interface that {BeaconProxy} expects of its beacon.\\n */\\ninterface IBeacon {\\n /**\\n * @dev Must return an address that can be used as a delegate call target.\\n *\\n * {BeaconProxy} will check that this address is a contract.\\n */\\n function implementation() external view returns (address);\\n}\\n\",\"keccak256\":\"0xd50a3421ac379ccb1be435fa646d66a65c986b4924f0849839f08692f39dde61\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/Address.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.7.0) (utils/Address.sol)\\n\\npragma solidity ^0.8.1;\\n\\n/**\\n * @dev Collection of functions related to the address type\\n */\\nlibrary Address {\\n /**\\n * @dev Returns true if `account` is a contract.\\n *\\n * [IMPORTANT]\\n * ====\\n * It is unsafe to assume that an address for which this function returns\\n * false is an externally-owned account (EOA) and not a contract.\\n *\\n * Among others, `isContract` will return false for the following\\n * types of addresses:\\n *\\n * - an externally-owned account\\n * - a contract in construction\\n * - an address where a contract will be created\\n * - an address where a contract lived, but was destroyed\\n * ====\\n *\\n * [IMPORTANT]\\n * ====\\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\\n *\\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\\n * constructor.\\n * ====\\n */\\n function isContract(address account) internal view returns (bool) {\\n // This method relies on extcodesize/address.code.length, which returns 0\\n // for contracts in construction, since the code is only stored at the end\\n // of the constructor execution.\\n\\n return account.code.length > 0;\\n }\\n\\n /**\\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\\n * `recipient`, forwarding all available gas and reverting on errors.\\n *\\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\\n * imposed by `transfer`, making them unable to receive funds via\\n * `transfer`. {sendValue} removes this limitation.\\n *\\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\\n *\\n * IMPORTANT: because control is transferred to `recipient`, care must be\\n * taken to not create reentrancy vulnerabilities. Consider using\\n * {ReentrancyGuard} or the\\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\\n */\\n function sendValue(address payable recipient, uint256 amount) internal {\\n require(address(this).balance >= amount, \\\"Address: insufficient balance\\\");\\n\\n (bool success, ) = recipient.call{value: amount}(\\\"\\\");\\n require(success, \\\"Address: unable to send value, recipient may have reverted\\\");\\n }\\n\\n /**\\n * @dev Performs a Solidity function call using a low level `call`. A\\n * plain `call` is an unsafe replacement for a function call: use this\\n * function instead.\\n *\\n * If `target` reverts with a revert reason, it is bubbled up by this\\n * function (like regular Solidity function calls).\\n *\\n * Returns the raw returned data. To convert to the expected return value,\\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\\n *\\n * Requirements:\\n *\\n * - `target` must be a contract.\\n * - calling `target` with `data` must not revert.\\n *\\n * _Available since v3.1._\\n */\\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\\n return functionCall(target, data, \\\"Address: low-level call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\\n * `errorMessage` as a fallback revert reason when `target` reverts.\\n *\\n * _Available since v3.1._\\n */\\n function functionCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n return functionCallWithValue(target, data, 0, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but also transferring `value` wei to `target`.\\n *\\n * Requirements:\\n *\\n * - the calling contract must have an ETH balance of at least `value`.\\n * - the called Solidity function must be `payable`.\\n *\\n * _Available since v3.1._\\n */\\n function functionCallWithValue(\\n address target,\\n bytes memory data,\\n uint256 value\\n ) internal returns (bytes memory) {\\n return functionCallWithValue(target, data, value, \\\"Address: low-level call with value failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\\n * with `errorMessage` as a fallback revert reason when `target` reverts.\\n *\\n * _Available since v3.1._\\n */\\n function functionCallWithValue(\\n address target,\\n bytes memory data,\\n uint256 value,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n require(address(this).balance >= value, \\\"Address: insufficient balance for call\\\");\\n require(isContract(target), \\\"Address: call to non-contract\\\");\\n\\n (bool success, bytes memory returndata) = target.call{value: value}(data);\\n return verifyCallResult(success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but performing a static call.\\n *\\n * _Available since v3.3._\\n */\\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\\n return functionStaticCall(target, data, \\\"Address: low-level static call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\\n * but performing a static call.\\n *\\n * _Available since v3.3._\\n */\\n function functionStaticCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal view returns (bytes memory) {\\n require(isContract(target), \\\"Address: static call to non-contract\\\");\\n\\n (bool success, bytes memory returndata) = target.staticcall(data);\\n return verifyCallResult(success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but performing a delegate call.\\n *\\n * _Available since v3.4._\\n */\\n function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {\\n return functionDelegateCall(target, data, \\\"Address: low-level delegate call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\\n * but performing a delegate call.\\n *\\n * _Available since v3.4._\\n */\\n function functionDelegateCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n require(isContract(target), \\\"Address: delegate call to non-contract\\\");\\n\\n (bool success, bytes memory returndata) = target.delegatecall(data);\\n return verifyCallResult(success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the\\n * revert reason using the provided one.\\n *\\n * _Available since v4.3._\\n */\\n function verifyCallResult(\\n bool success,\\n bytes memory returndata,\\n string memory errorMessage\\n ) internal pure returns (bytes memory) {\\n if (success) {\\n return returndata;\\n } else {\\n // Look for revert reason and bubble it up if present\\n if (returndata.length > 0) {\\n // The easiest way to bubble the revert reason is using memory via assembly\\n /// @solidity memory-safe-assembly\\n assembly {\\n let returndata_size := mload(returndata)\\n revert(add(32, returndata), returndata_size)\\n }\\n } else {\\n revert(errorMessage);\\n }\\n }\\n }\\n}\\n\",\"keccak256\":\"0xd6153ce99bcdcce22b124f755e72553295be6abcd63804cfdffceb188b8bef10\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/StorageSlot.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.7.0) (utils/StorageSlot.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Library for reading and writing primitive types to specific storage slots.\\n *\\n * Storage slots are often used to avoid storage conflict when dealing with upgradeable contracts.\\n * This library helps with reading and writing to such slots without the need for inline assembly.\\n *\\n * The functions in this library return Slot structs that contain a `value` member that can be used to read or write.\\n *\\n * Example usage to set ERC1967 implementation slot:\\n * ```\\n * contract ERC1967 {\\n * bytes32 internal constant _IMPLEMENTATION_SLOT = 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc;\\n *\\n * function _getImplementation() internal view returns (address) {\\n * return StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value;\\n * }\\n *\\n * function _setImplementation(address newImplementation) internal {\\n * require(Address.isContract(newImplementation), \\\"ERC1967: new implementation is not a contract\\\");\\n * StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value = newImplementation;\\n * }\\n * }\\n * ```\\n *\\n * _Available since v4.1 for `address`, `bool`, `bytes32`, and `uint256`._\\n */\\nlibrary StorageSlot {\\n struct AddressSlot {\\n address value;\\n }\\n\\n struct BooleanSlot {\\n bool value;\\n }\\n\\n struct Bytes32Slot {\\n bytes32 value;\\n }\\n\\n struct Uint256Slot {\\n uint256 value;\\n }\\n\\n /**\\n * @dev Returns an `AddressSlot` with member `value` located at `slot`.\\n */\\n function getAddressSlot(bytes32 slot) internal pure returns (AddressSlot storage r) {\\n /// @solidity memory-safe-assembly\\n assembly {\\n r.slot := slot\\n }\\n }\\n\\n /**\\n * @dev Returns an `BooleanSlot` with member `value` located at `slot`.\\n */\\n function getBooleanSlot(bytes32 slot) internal pure returns (BooleanSlot storage r) {\\n /// @solidity memory-safe-assembly\\n assembly {\\n r.slot := slot\\n }\\n }\\n\\n /**\\n * @dev Returns an `Bytes32Slot` with member `value` located at `slot`.\\n */\\n function getBytes32Slot(bytes32 slot) internal pure returns (Bytes32Slot storage r) {\\n /// @solidity memory-safe-assembly\\n assembly {\\n r.slot := slot\\n }\\n }\\n\\n /**\\n * @dev Returns an `Uint256Slot` with member `value` located at `slot`.\\n */\\n function getUint256Slot(bytes32 slot) internal pure returns (Uint256Slot storage r) {\\n /// @solidity memory-safe-assembly\\n assembly {\\n r.slot := slot\\n }\\n }\\n}\\n\",\"keccak256\":\"0xd5c50c54bf02740ebd122ff06832546cb5fa84486d52695a9ccfd11666e0c81d\",\"license\":\"MIT\"},\"contracts/external/TransparentUpgradeableProxy.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-3.0\\n\\npragma solidity ^0.8.12;\\n\\nimport \\\"@openzeppelin/contracts/proxy/ERC1967/ERC1967Proxy.sol\\\";\\n\\n/**\\n * @dev This contract implements a proxy that is upgradeable by an admin. It is fully forked from OpenZeppelin\\n * `TransparentUpgradeableProxy`\\n *\\n * To avoid https://medium.com/nomic-labs-blog/malicious-backdoors-in-ethereum-proxies-62629adf3357[proxy selector\\n * clashing], which can potentially be used in an attack, this contract uses the\\n * https://blog.openzeppelin.com/the-transparent-proxy-pattern/[transparent proxy pattern]. This pattern implies two\\n * things that go hand in hand:\\n *\\n * 1. If any account other than the admin calls the proxy, the call will be forwarded to the implementation, even if\\n * that call matches one of the admin functions exposed by the proxy itself.\\n * 2. If the admin calls the proxy, it can access the admin functions, but its calls will never be forwarded to the\\n * implementation. If the admin tries to call a function on the implementation it will fail with an error that says\\n * \\\"admin cannot fallback to proxy target\\\".\\n *\\n * These properties mean that the admin account can only be used for admin actions like upgrading the proxy or changing\\n * the admin, so it's best if it's a dedicated account that is not used for anything else. This will avoid headaches due\\n * to sudden errors when trying to call a function from the proxy implementation.\\n *\\n * Our recommendation is for the dedicated account to be an instance of the {ProxyAdmin} contract. If set up this way,\\n * you should think of the `ProxyAdmin` instance as the real administrative interface of your proxy.\\n */\\ncontract TransparentUpgradeableProxy is ERC1967Proxy {\\n /**\\n * @dev Initializes an upgradeable proxy managed by `_admin`, backed by the implementation at `_logic`, and\\n * optionally initialized with `_data` as explained in {ERC1967Proxy-constructor}.\\n */\\n constructor(address _logic, address admin_, bytes memory _data) payable ERC1967Proxy(_logic, _data) {\\n assert(_ADMIN_SLOT == bytes32(uint256(keccak256(\\\"eip1967.proxy.admin\\\")) - 1));\\n _changeAdmin(admin_);\\n }\\n\\n /**\\n * @dev Modifier used internally that will delegate the call to the implementation unless the sender is the admin.\\n */\\n modifier ifAdmin() {\\n if (msg.sender == _getAdmin()) {\\n _;\\n } else {\\n _fallback();\\n }\\n }\\n\\n /**\\n * @dev Returns the current admin.\\n *\\n * NOTE: Only the admin can call this function. See {ProxyAdmin-getProxyAdmin}.\\n *\\n * TIP: To get this value clients can read directly from the storage slot shown below (specified by EIP1967) using the\\n * https://eth.wiki/json-rpc/API#eth_getstorageat[`eth_getStorageAt`] RPC call.\\n * `0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103`\\n */\\n function admin() external ifAdmin returns (address admin_) {\\n admin_ = _getAdmin();\\n }\\n\\n /**\\n * @dev Returns the current implementation.\\n *\\n * NOTE: Only the admin can call this function. See {ProxyAdmin-getProxyImplementation}.\\n *\\n * TIP: To get this value clients can read directly from the storage slot shown below (specified by EIP1967) using the\\n * https://eth.wiki/json-rpc/API#eth_getstorageat[`eth_getStorageAt`] RPC call.\\n * `0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc`\\n */\\n function implementation() external ifAdmin returns (address implementation_) {\\n implementation_ = _implementation();\\n }\\n\\n /**\\n * @dev Changes the admin of the proxy.\\n *\\n * Emits an {AdminChanged} event.\\n *\\n * NOTE: Only the admin can call this function. See {ProxyAdmin-changeProxyAdmin}.\\n */\\n function changeAdmin(address newAdmin) external virtual ifAdmin {\\n _changeAdmin(newAdmin);\\n }\\n\\n /**\\n * @dev Upgrade the implementation of the proxy.\\n *\\n * NOTE: Only the admin can call this function. See {ProxyAdmin-upgrade}.\\n */\\n function upgradeTo(address newImplementation) external ifAdmin {\\n _upgradeToAndCall(newImplementation, bytes(\\\"\\\"), false);\\n }\\n\\n /**\\n * @dev Upgrade the implementation of the proxy, and then call a function from the new implementation as specified\\n * by `data`, which should be an encoded function call. This is useful to initialize new storage variables in the\\n * proxied contract.\\n *\\n * NOTE: Only the admin can call this function. See {ProxyAdmin-upgradeAndCall}.\\n */\\n function upgradeToAndCall(address newImplementation, bytes calldata data) external payable ifAdmin {\\n _upgradeToAndCall(newImplementation, data, true);\\n }\\n\\n /**\\n * @dev Returns the current admin.\\n */\\n function _admin() internal view virtual returns (address) {\\n return _getAdmin();\\n }\\n\\n /**\\n * @dev Makes sure the admin cannot access the fallback function. See {Proxy-_beforeFallback}.\\n */\\n function _beforeFallback() internal virtual override {\\n require(msg.sender != _getAdmin(), \\\"TransparentUpgradeableProxy: admin cannot fallback to proxy target\\\");\\n super._beforeFallback();\\n }\\n}\\n\",\"keccak256\":\"0x93a67a0f612ea3ff2a76315e138a6a88267270a1379d3cc7be52845fbbe611e2\",\"license\":\"GPL-3.0\"}},\"version\":1}", + "bytecode": "0x6080604052604051620010bb380380620010bb8339810160408190526200002691620004d8565b828162000036828260006200009a565b5062000066905060017fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6104620005b8565b6000805160206200107483398151915214620000865762000086620005da565b6200009182620000d7565b50505062000643565b620000a58362000132565b600082511180620000b35750805b15620000d257620000d083836200017460201b6200028c1760201c565b505b505050565b7f7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f62000102620001a5565b604080516001600160a01b03928316815291841660208301520160405180910390a16200012f81620001de565b50565b6200013d8162000293565b6040516001600160a01b038216907fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b90600090a250565b60606200019c8383604051806060016040528060278152602001620010946027913962000347565b90505b92915050565b6000620001cf6000805160206200107483398151915260001b6200042f60201b6200022e1760201c565b546001600160a01b0316919050565b6001600160a01b038116620002495760405162461bcd60e51b815260206004820152602660248201527f455243313936373a206e65772061646d696e20697320746865207a65726f206160448201526564647265737360d01b60648201526084015b60405180910390fd5b80620002726000805160206200107483398151915260001b6200042f60201b6200022e1760201c565b80546001600160a01b0319166001600160a01b039290921691909117905550565b620002a9816200043260201b620002b81760201c565b6200030d5760405162461bcd60e51b815260206004820152602d60248201527f455243313936373a206e657720696d706c656d656e746174696f6e206973206e60448201526c1bdd08184818dbdb9d1c9858dd609a1b606482015260840162000240565b80620002727f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc60001b6200042f60201b6200022e1760201c565b60606001600160a01b0384163b620003b15760405162461bcd60e51b815260206004820152602660248201527f416464726573733a2064656c65676174652063616c6c20746f206e6f6e2d636f6044820152651b9d1c9858dd60d21b606482015260840162000240565b600080856001600160a01b031685604051620003ce9190620005f0565b600060405180830381855af49150503d80600081146200040b576040519150601f19603f3d011682016040523d82523d6000602084013e62000410565b606091505b5090925090506200042382828662000441565b925050505b9392505050565b90565b6001600160a01b03163b151590565b606083156200045257508162000428565b825115620004635782518084602001fd5b8160405162461bcd60e51b81526004016200024091906200060e565b80516001600160a01b03811681146200049757600080fd5b919050565b634e487b7160e01b600052604160045260246000fd5b60005b83811015620004cf578181015183820152602001620004b5565b50506000910152565b600080600060608486031215620004ee57600080fd5b620004f9846200047f565b925062000509602085016200047f565b60408501519092506001600160401b03808211156200052757600080fd5b818601915086601f8301126200053c57600080fd5b8151818111156200055157620005516200049c565b604051601f8201601f19908116603f011681019083821181831017156200057c576200057c6200049c565b816040528281528960208487010111156200059657600080fd5b620005a9836020830160208801620004b2565b80955050505050509250925092565b818103818111156200019f57634e487b7160e01b600052601160045260246000fd5b634e487b7160e01b600052600160045260246000fd5b6000825162000604818460208701620004b2565b9190910192915050565b60208152600082518060208401526200062f816040850160208701620004b2565b601f01601f19169190910160400192915050565b610a2180620006536000396000f3fe60806040526004361061005e5760003560e01c80635c60da1b116100435780635c60da1b146100a85780638f283970146100e6578063f851a440146101065761006d565b80633659cfe6146100755780634f1ef286146100955761006d565b3661006d5761006b61011b565b005b61006b61011b565b34801561008157600080fd5b5061006b610090366004610895565b610135565b61006b6100a33660046108b0565b61017f565b3480156100b457600080fd5b506100bd6101f3565b60405173ffffffffffffffffffffffffffffffffffffffff909116815260200160405180910390f35b3480156100f257600080fd5b5061006b610101366004610895565b610231565b34801561011257600080fd5b506100bd61025e565b6101236102d4565b61013361012e6103ab565b6103b5565b565b61013d6103d9565b73ffffffffffffffffffffffffffffffffffffffff1633036101775761017481604051806020016040528060008152506000610419565b50565b61017461011b565b6101876103d9565b73ffffffffffffffffffffffffffffffffffffffff1633036101eb576101e68383838080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525060019250610419915050565b505050565b6101e661011b565b60006101fd6103d9565b73ffffffffffffffffffffffffffffffffffffffff163303610226576102216103ab565b905090565b61022e61011b565b90565b6102396103d9565b73ffffffffffffffffffffffffffffffffffffffff1633036101775761017481610444565b60006102686103d9565b73ffffffffffffffffffffffffffffffffffffffff163303610226576102216103d9565b60606102b183836040518060600160405280602781526020016109c5602791396104a5565b9392505050565b73ffffffffffffffffffffffffffffffffffffffff163b151590565b6102dc6103d9565b73ffffffffffffffffffffffffffffffffffffffff163303610133576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604260248201527f5472616e73706172656e745570677261646561626c6550726f78793a2061646d60448201527f696e2063616e6e6f742066616c6c6261636b20746f2070726f7879207461726760648201527f6574000000000000000000000000000000000000000000000000000000000000608482015260a4015b60405180910390fd5b60006102216105cd565b3660008037600080366000845af43d6000803e8080156103d4573d6000f35b3d6000fd5b60007fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035b5473ffffffffffffffffffffffffffffffffffffffff16919050565b610422836105f5565b60008251118061042f5750805b156101e65761043e838361028c565b50505050565b7f7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f61046d6103d9565b6040805173ffffffffffffffffffffffffffffffffffffffff928316815291841660208301520160405180910390a161017481610642565b606073ffffffffffffffffffffffffffffffffffffffff84163b61054b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f416464726573733a2064656c65676174652063616c6c20746f206e6f6e2d636f60448201527f6e7472616374000000000000000000000000000000000000000000000000000060648201526084016103a2565b6000808573ffffffffffffffffffffffffffffffffffffffff16856040516105739190610957565b600060405180830381855af49150503d80600081146105ae576040519150601f19603f3d011682016040523d82523d6000602084013e6105b3565b606091505b50915091506105c382828661074e565b9695505050505050565b60007f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc6103fd565b6105fe816107a1565b60405173ffffffffffffffffffffffffffffffffffffffff8216907fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b90600090a250565b73ffffffffffffffffffffffffffffffffffffffff81166106e5576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f455243313936373a206e65772061646d696e20697320746865207a65726f206160448201527f646472657373000000000000000000000000000000000000000000000000000060648201526084016103a2565b807fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035b80547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff9290921691909117905550565b6060831561075d5750816102b1565b82511561076d5782518084602001fd5b816040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016103a29190610973565b73ffffffffffffffffffffffffffffffffffffffff81163b610845576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602d60248201527f455243313936373a206e657720696d706c656d656e746174696f6e206973206e60448201527f6f74206120636f6e74726163740000000000000000000000000000000000000060648201526084016103a2565b807f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc610708565b803573ffffffffffffffffffffffffffffffffffffffff8116811461089057600080fd5b919050565b6000602082840312156108a757600080fd5b6102b18261086c565b6000806000604084860312156108c557600080fd5b6108ce8461086c565b9250602084013567ffffffffffffffff808211156108eb57600080fd5b818601915086601f8301126108ff57600080fd5b81358181111561090e57600080fd5b87602082850101111561092057600080fd5b6020830194508093505050509250925092565b60005b8381101561094e578181015183820152602001610936565b50506000910152565b60008251610969818460208701610933565b9190910192915050565b6020815260008251806020840152610992816040850160208701610933565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016919091016040019291505056fe416464726573733a206c6f772d6c6576656c2064656c65676174652063616c6c206661696c6564a2646970667358221220e96638b07fb1675d93a95c49e417bc8111448b23a59918698cdcd8fd488dd7cf64736f6c63430008110033b53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103416464726573733a206c6f772d6c6576656c2064656c65676174652063616c6c206661696c6564", + "deployedBytecode": "0x60806040526004361061005e5760003560e01c80635c60da1b116100435780635c60da1b146100a85780638f283970146100e6578063f851a440146101065761006d565b80633659cfe6146100755780634f1ef286146100955761006d565b3661006d5761006b61011b565b005b61006b61011b565b34801561008157600080fd5b5061006b610090366004610895565b610135565b61006b6100a33660046108b0565b61017f565b3480156100b457600080fd5b506100bd6101f3565b60405173ffffffffffffffffffffffffffffffffffffffff909116815260200160405180910390f35b3480156100f257600080fd5b5061006b610101366004610895565b610231565b34801561011257600080fd5b506100bd61025e565b6101236102d4565b61013361012e6103ab565b6103b5565b565b61013d6103d9565b73ffffffffffffffffffffffffffffffffffffffff1633036101775761017481604051806020016040528060008152506000610419565b50565b61017461011b565b6101876103d9565b73ffffffffffffffffffffffffffffffffffffffff1633036101eb576101e68383838080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525060019250610419915050565b505050565b6101e661011b565b60006101fd6103d9565b73ffffffffffffffffffffffffffffffffffffffff163303610226576102216103ab565b905090565b61022e61011b565b90565b6102396103d9565b73ffffffffffffffffffffffffffffffffffffffff1633036101775761017481610444565b60006102686103d9565b73ffffffffffffffffffffffffffffffffffffffff163303610226576102216103d9565b60606102b183836040518060600160405280602781526020016109c5602791396104a5565b9392505050565b73ffffffffffffffffffffffffffffffffffffffff163b151590565b6102dc6103d9565b73ffffffffffffffffffffffffffffffffffffffff163303610133576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604260248201527f5472616e73706172656e745570677261646561626c6550726f78793a2061646d60448201527f696e2063616e6e6f742066616c6c6261636b20746f2070726f7879207461726760648201527f6574000000000000000000000000000000000000000000000000000000000000608482015260a4015b60405180910390fd5b60006102216105cd565b3660008037600080366000845af43d6000803e8080156103d4573d6000f35b3d6000fd5b60007fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035b5473ffffffffffffffffffffffffffffffffffffffff16919050565b610422836105f5565b60008251118061042f5750805b156101e65761043e838361028c565b50505050565b7f7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f61046d6103d9565b6040805173ffffffffffffffffffffffffffffffffffffffff928316815291841660208301520160405180910390a161017481610642565b606073ffffffffffffffffffffffffffffffffffffffff84163b61054b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f416464726573733a2064656c65676174652063616c6c20746f206e6f6e2d636f60448201527f6e7472616374000000000000000000000000000000000000000000000000000060648201526084016103a2565b6000808573ffffffffffffffffffffffffffffffffffffffff16856040516105739190610957565b600060405180830381855af49150503d80600081146105ae576040519150601f19603f3d011682016040523d82523d6000602084013e6105b3565b606091505b50915091506105c382828661074e565b9695505050505050565b60007f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc6103fd565b6105fe816107a1565b60405173ffffffffffffffffffffffffffffffffffffffff8216907fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b90600090a250565b73ffffffffffffffffffffffffffffffffffffffff81166106e5576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f455243313936373a206e65772061646d696e20697320746865207a65726f206160448201527f646472657373000000000000000000000000000000000000000000000000000060648201526084016103a2565b807fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035b80547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff9290921691909117905550565b6060831561075d5750816102b1565b82511561076d5782518084602001fd5b816040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016103a29190610973565b73ffffffffffffffffffffffffffffffffffffffff81163b610845576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602d60248201527f455243313936373a206e657720696d706c656d656e746174696f6e206973206e60448201527f6f74206120636f6e74726163740000000000000000000000000000000000000060648201526084016103a2565b807f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc610708565b803573ffffffffffffffffffffffffffffffffffffffff8116811461089057600080fd5b919050565b6000602082840312156108a757600080fd5b6102b18261086c565b6000806000604084860312156108c557600080fd5b6108ce8461086c565b9250602084013567ffffffffffffffff808211156108eb57600080fd5b818601915086601f8301126108ff57600080fd5b81358181111561090e57600080fd5b87602082850101111561092057600080fd5b6020830194508093505050509250925092565b60005b8381101561094e578181015183820152602001610936565b50506000910152565b60008251610969818460208701610933565b9190910192915050565b6020815260008251806020840152610992816040850160208701610933565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016919091016040019291505056fe416464726573733a206c6f772d6c6576656c2064656c65676174652063616c6c206661696c6564a2646970667358221220e96638b07fb1675d93a95c49e417bc8111448b23a59918698cdcd8fd488dd7cf64736f6c63430008110033", + "devdoc": { + "details": "This contract implements a proxy that is upgradeable by an admin. It is fully forked from OpenZeppelin `TransparentUpgradeableProxy` To avoid https://medium.com/nomic-labs-blog/malicious-backdoors-in-ethereum-proxies-62629adf3357[proxy selector clashing], which can potentially be used in an attack, this contract uses the https://blog.openzeppelin.com/the-transparent-proxy-pattern/[transparent proxy pattern]. This pattern implies two things that go hand in hand: 1. If any account other than the admin calls the proxy, the call will be forwarded to the implementation, even if that call matches one of the admin functions exposed by the proxy itself. 2. If the admin calls the proxy, it can access the admin functions, but its calls will never be forwarded to the implementation. If the admin tries to call a function on the implementation it will fail with an error that says \"admin cannot fallback to proxy target\". These properties mean that the admin account can only be used for admin actions like upgrading the proxy or changing the admin, so it's best if it's a dedicated account that is not used for anything else. This will avoid headaches due to sudden errors when trying to call a function from the proxy implementation. Our recommendation is for the dedicated account to be an instance of the {ProxyAdmin} contract. If set up this way, you should think of the `ProxyAdmin` instance as the real administrative interface of your proxy.", + "kind": "dev", + "methods": { + "admin()": { + "details": "Returns the current admin. NOTE: Only the admin can call this function. See {ProxyAdmin-getProxyAdmin}. TIP: To get this value clients can read directly from the storage slot shown below (specified by EIP1967) using the https://eth.wiki/json-rpc/API#eth_getstorageat[`eth_getStorageAt`] RPC call. `0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103`" + }, + "changeAdmin(address)": { + "details": "Changes the admin of the proxy. Emits an {AdminChanged} event. NOTE: Only the admin can call this function. See {ProxyAdmin-changeProxyAdmin}." + }, + "constructor": { + "details": "Initializes an upgradeable proxy managed by `_admin`, backed by the implementation at `_logic`, and optionally initialized with `_data` as explained in {ERC1967Proxy-constructor}." + }, + "implementation()": { + "details": "Returns the current implementation. NOTE: Only the admin can call this function. See {ProxyAdmin-getProxyImplementation}. TIP: To get this value clients can read directly from the storage slot shown below (specified by EIP1967) using the https://eth.wiki/json-rpc/API#eth_getstorageat[`eth_getStorageAt`] RPC call. `0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc`" + }, + "upgradeTo(address)": { + "details": "Upgrade the implementation of the proxy. NOTE: Only the admin can call this function. See {ProxyAdmin-upgrade}." + }, + "upgradeToAndCall(address,bytes)": { + "details": "Upgrade the implementation of the proxy, and then call a function from the new implementation as specified by `data`, which should be an encoded function call. This is useful to initialize new storage variables in the proxied contract. NOTE: Only the admin can call this function. See {ProxyAdmin-upgradeAndCall}." + } + }, + "version": 1 + }, + "userdoc": { + "kind": "user", + "methods": {}, + "version": 1 + }, + "storageLayout": { + "storage": [], + "types": null + } +} \ No newline at end of file diff --git a/deployments/gnosis/LayerZeroBridge_USD.json b/deployments/gnosis/LayerZeroBridge_USD.json new file mode 100644 index 00000000..40260378 --- /dev/null +++ b/deployments/gnosis/LayerZeroBridge_USD.json @@ -0,0 +1,275 @@ +{ + "address": "0x4DD4758F594B60551dC64f30289204D34cCd077D", + "abi": [ + { + "inputs": [ + { + "internalType": "address", + "name": "_logic", + "type": "address" + }, + { + "internalType": "address", + "name": "admin_", + "type": "address" + }, + { + "internalType": "bytes", + "name": "_data", + "type": "bytes" + } + ], + "stateMutability": "payable", + "type": "constructor" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "previousAdmin", + "type": "address" + }, + { + "indexed": false, + "internalType": "address", + "name": "newAdmin", + "type": "address" + } + ], + "name": "AdminChanged", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "beacon", + "type": "address" + } + ], + "name": "BeaconUpgraded", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "implementation", + "type": "address" + } + ], + "name": "Upgraded", + "type": "event" + }, + { + "stateMutability": "payable", + "type": "fallback" + }, + { + "inputs": [], + "name": "admin", + "outputs": [ + { + "internalType": "address", + "name": "admin_", + "type": "address" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "newAdmin", + "type": "address" + } + ], + "name": "changeAdmin", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "implementation", + "outputs": [ + { + "internalType": "address", + "name": "implementation_", + "type": "address" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "newImplementation", + "type": "address" + } + ], + "name": "upgradeTo", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "newImplementation", + "type": "address" + }, + { + "internalType": "bytes", + "name": "data", + "type": "bytes" + } + ], + "name": "upgradeToAndCall", + "outputs": [], + "stateMutability": "payable", + "type": "function" + }, + { + "stateMutability": "payable", + "type": "receive" + } + ], + "transactionHash": "0x4090a8a5ab38f590a37af16cf6bc73da00f8c9032fd7ac14be77e0270f1087fc", + "receipt": { + "to": null, + "from": "0xfdA462548Ce04282f4B6D6619823a7C64Fdc0185", + "contractAddress": "0x4DD4758F594B60551dC64f30289204D34cCd077D", + "transactionIndex": 2, + "gasUsed": "850228", + "logsBloom": "0x02000000000000000000000001000000400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000200000000004000000000000000008000002000000000080000000000000000500000000000000020000000000000000000900000000800000000000000010000000000000000000020000000000000000200000000000000080000000000000800000020000000000000000000000000400000000000000000000000000000000000000000022000000000000001000040000000000000400000000000000000020000010000000004000000000000000040000000000000000000000000000000000", + "blockHash": "0x889e76c2c306fb431d542026291d6e18e05550dbec3c1205e92905f876e618d7", + "transactionHash": "0x4090a8a5ab38f590a37af16cf6bc73da00f8c9032fd7ac14be77e0270f1087fc", + "logs": [ + { + "transactionIndex": 2, + "blockNumber": 31876830, + "transactionHash": "0x4090a8a5ab38f590a37af16cf6bc73da00f8c9032fd7ac14be77e0270f1087fc", + "address": "0x4DD4758F594B60551dC64f30289204D34cCd077D", + "topics": [ + "0xbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b", + "0x0000000000000000000000001033dd8415a282db52f14902e91de6e91868ac6d" + ], + "data": "0x", + "logIndex": 797, + "blockHash": "0x889e76c2c306fb431d542026291d6e18e05550dbec3c1205e92905f876e618d7" + }, + { + "transactionIndex": 2, + "blockNumber": 31876830, + "transactionHash": "0x4090a8a5ab38f590a37af16cf6bc73da00f8c9032fd7ac14be77e0270f1087fc", + "address": "0x4DD4758F594B60551dC64f30289204D34cCd077D", + "topics": [ + "0x8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925", + "0x0000000000000000000000004dd4758f594b60551dc64f30289204d34ccd077d", + "0x0000000000000000000000000000206329b97db379d5e1bf586bbdb969c63274" + ], + "data": "0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", + "logIndex": 798, + "blockHash": "0x889e76c2c306fb431d542026291d6e18e05550dbec3c1205e92905f876e618d7" + }, + { + "transactionIndex": 2, + "blockNumber": 31876830, + "transactionHash": "0x4090a8a5ab38f590a37af16cf6bc73da00f8c9032fd7ac14be77e0270f1087fc", + "address": "0x4DD4758F594B60551dC64f30289204D34cCd077D", + "topics": [ + "0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000206329b97db379d5e1bf586bbdb969c63274" + ], + "data": "0x0000000000000000000000000000000000000000000000000000000000000000", + "logIndex": 799, + "blockHash": "0x889e76c2c306fb431d542026291d6e18e05550dbec3c1205e92905f876e618d7" + }, + { + "transactionIndex": 2, + "blockNumber": 31876830, + "transactionHash": "0x4090a8a5ab38f590a37af16cf6bc73da00f8c9032fd7ac14be77e0270f1087fc", + "address": "0x4DD4758F594B60551dC64f30289204D34cCd077D", + "topics": [ + "0x7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb3847402498" + ], + "data": "0x0000000000000000000000000000000000000000000000000000000000000001", + "logIndex": 800, + "blockHash": "0x889e76c2c306fb431d542026291d6e18e05550dbec3c1205e92905f876e618d7" + }, + { + "transactionIndex": 2, + "blockNumber": 31876830, + "transactionHash": "0x4090a8a5ab38f590a37af16cf6bc73da00f8c9032fd7ac14be77e0270f1087fc", + "address": "0x4DD4758F594B60551dC64f30289204D34cCd077D", + "topics": [ + "0x7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f" + ], + "data": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000009a5b060bd7b8f86c4c0d720a17367729670afb19", + "logIndex": 801, + "blockHash": "0x889e76c2c306fb431d542026291d6e18e05550dbec3c1205e92905f876e618d7" + } + ], + "blockNumber": 31876830, + "cumulativeGasUsed": "4019409", + "status": 1, + "byzantium": true + }, + "args": [ + "0x1033dD8415A282Db52f14902E91DE6e91868aC6D", + "0x9a5b060Bd7b8f86c4C0D720a17367729670AfB19", + "0xc9aba0aa00000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000000e00000000000000000000000009740ff91f1985d8d2b71494ae1a2f723bb3ed9e40000000000000000000000003e9ea799c447b3c65702c82f8193085f330a1db0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000164c617965725a65726f204272696467652061675553440000000000000000000000000000000000000000000000000000000000000000000000000000000000084c5a2d6167555344000000000000000000000000000000000000000000000000" + ], + "numDeployments": 1, + "solcInputHash": "871924e0c138825a2736b76def8fef8d", + "metadata": "{\"compiler\":{\"version\":\"0.8.17+commit.8df45f5f\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_logic\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"admin_\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"_data\",\"type\":\"bytes\"}],\"stateMutability\":\"payable\",\"type\":\"constructor\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"previousAdmin\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"newAdmin\",\"type\":\"address\"}],\"name\":\"AdminChanged\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"beacon\",\"type\":\"address\"}],\"name\":\"BeaconUpgraded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"implementation\",\"type\":\"address\"}],\"name\":\"Upgraded\",\"type\":\"event\"},{\"stateMutability\":\"payable\",\"type\":\"fallback\"},{\"inputs\":[],\"name\":\"admin\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"admin_\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newAdmin\",\"type\":\"address\"}],\"name\":\"changeAdmin\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"implementation\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"implementation_\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newImplementation\",\"type\":\"address\"}],\"name\":\"upgradeTo\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newImplementation\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"}],\"name\":\"upgradeToAndCall\",\"outputs\":[],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"stateMutability\":\"payable\",\"type\":\"receive\"}],\"devdoc\":{\"details\":\"This contract implements a proxy that is upgradeable by an admin. It is fully forked from OpenZeppelin `TransparentUpgradeableProxy` To avoid https://medium.com/nomic-labs-blog/malicious-backdoors-in-ethereum-proxies-62629adf3357[proxy selector clashing], which can potentially be used in an attack, this contract uses the https://blog.openzeppelin.com/the-transparent-proxy-pattern/[transparent proxy pattern]. This pattern implies two things that go hand in hand: 1. If any account other than the admin calls the proxy, the call will be forwarded to the implementation, even if that call matches one of the admin functions exposed by the proxy itself. 2. If the admin calls the proxy, it can access the admin functions, but its calls will never be forwarded to the implementation. If the admin tries to call a function on the implementation it will fail with an error that says \\\"admin cannot fallback to proxy target\\\". These properties mean that the admin account can only be used for admin actions like upgrading the proxy or changing the admin, so it's best if it's a dedicated account that is not used for anything else. This will avoid headaches due to sudden errors when trying to call a function from the proxy implementation. Our recommendation is for the dedicated account to be an instance of the {ProxyAdmin} contract. If set up this way, you should think of the `ProxyAdmin` instance as the real administrative interface of your proxy.\",\"kind\":\"dev\",\"methods\":{\"admin()\":{\"details\":\"Returns the current admin. NOTE: Only the admin can call this function. See {ProxyAdmin-getProxyAdmin}. TIP: To get this value clients can read directly from the storage slot shown below (specified by EIP1967) using the https://eth.wiki/json-rpc/API#eth_getstorageat[`eth_getStorageAt`] RPC call. `0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103`\"},\"changeAdmin(address)\":{\"details\":\"Changes the admin of the proxy. Emits an {AdminChanged} event. NOTE: Only the admin can call this function. See {ProxyAdmin-changeProxyAdmin}.\"},\"constructor\":{\"details\":\"Initializes an upgradeable proxy managed by `_admin`, backed by the implementation at `_logic`, and optionally initialized with `_data` as explained in {ERC1967Proxy-constructor}.\"},\"implementation()\":{\"details\":\"Returns the current implementation. NOTE: Only the admin can call this function. See {ProxyAdmin-getProxyImplementation}. TIP: To get this value clients can read directly from the storage slot shown below (specified by EIP1967) using the https://eth.wiki/json-rpc/API#eth_getstorageat[`eth_getStorageAt`] RPC call. `0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc`\"},\"upgradeTo(address)\":{\"details\":\"Upgrade the implementation of the proxy. NOTE: Only the admin can call this function. See {ProxyAdmin-upgrade}.\"},\"upgradeToAndCall(address,bytes)\":{\"details\":\"Upgrade the implementation of the proxy, and then call a function from the new implementation as specified by `data`, which should be an encoded function call. This is useful to initialize new storage variables in the proxied contract. NOTE: Only the admin can call this function. See {ProxyAdmin-upgradeAndCall}.\"}},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/external/TransparentUpgradeableProxy.sol\":\"TransparentUpgradeableProxy\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":1000000},\"remappings\":[]},\"sources\":{\"@openzeppelin/contracts/interfaces/draft-IERC1822.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.5.0) (interfaces/draft-IERC1822.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev ERC1822: Universal Upgradeable Proxy Standard (UUPS) documents a method for upgradeability through a simplified\\n * proxy whose upgrades are fully controlled by the current implementation.\\n */\\ninterface IERC1822Proxiable {\\n /**\\n * @dev Returns the storage slot that the proxiable contract assumes is being used to store the implementation\\n * address.\\n *\\n * IMPORTANT: A proxy pointing at a proxiable contract should not be considered proxiable itself, because this risks\\n * bricking a proxy that upgrades to it, by delegating to itself until out of gas. Thus it is critical that this\\n * function revert if invoked through a proxy.\\n */\\n function proxiableUUID() external view returns (bytes32);\\n}\\n\",\"keccak256\":\"0x1d4afe6cb24200cc4545eed814ecf5847277dfe5d613a1707aad5fceecebcfff\",\"license\":\"MIT\"},\"@openzeppelin/contracts/proxy/ERC1967/ERC1967Proxy.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.7.0) (proxy/ERC1967/ERC1967Proxy.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../Proxy.sol\\\";\\nimport \\\"./ERC1967Upgrade.sol\\\";\\n\\n/**\\n * @dev This contract implements an upgradeable proxy. It is upgradeable because calls are delegated to an\\n * implementation address that can be changed. This address is stored in storage in the location specified by\\n * https://eips.ethereum.org/EIPS/eip-1967[EIP1967], so that it doesn't conflict with the storage layout of the\\n * implementation behind the proxy.\\n */\\ncontract ERC1967Proxy is Proxy, ERC1967Upgrade {\\n /**\\n * @dev Initializes the upgradeable proxy with an initial implementation specified by `_logic`.\\n *\\n * If `_data` is nonempty, it's used as data in a delegate call to `_logic`. This will typically be an encoded\\n * function call, and allows initializing the storage of the proxy like a Solidity constructor.\\n */\\n constructor(address _logic, bytes memory _data) payable {\\n _upgradeToAndCall(_logic, _data, false);\\n }\\n\\n /**\\n * @dev Returns the current implementation address.\\n */\\n function _implementation() internal view virtual override returns (address impl) {\\n return ERC1967Upgrade._getImplementation();\\n }\\n}\\n\",\"keccak256\":\"0xa2b22da3032e50b55f95ec1d13336102d675f341167aa76db571ef7f8bb7975d\",\"license\":\"MIT\"},\"@openzeppelin/contracts/proxy/ERC1967/ERC1967Upgrade.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.5.0) (proxy/ERC1967/ERC1967Upgrade.sol)\\n\\npragma solidity ^0.8.2;\\n\\nimport \\\"../beacon/IBeacon.sol\\\";\\nimport \\\"../../interfaces/draft-IERC1822.sol\\\";\\nimport \\\"../../utils/Address.sol\\\";\\nimport \\\"../../utils/StorageSlot.sol\\\";\\n\\n/**\\n * @dev This abstract contract provides getters and event emitting update functions for\\n * https://eips.ethereum.org/EIPS/eip-1967[EIP1967] slots.\\n *\\n * _Available since v4.1._\\n *\\n * @custom:oz-upgrades-unsafe-allow delegatecall\\n */\\nabstract contract ERC1967Upgrade {\\n // This is the keccak-256 hash of \\\"eip1967.proxy.rollback\\\" subtracted by 1\\n bytes32 private constant _ROLLBACK_SLOT = 0x4910fdfa16fed3260ed0e7147f7cc6da11a60208b5b9406d12a635614ffd9143;\\n\\n /**\\n * @dev Storage slot with the address of the current implementation.\\n * This is the keccak-256 hash of \\\"eip1967.proxy.implementation\\\" subtracted by 1, and is\\n * validated in the constructor.\\n */\\n bytes32 internal constant _IMPLEMENTATION_SLOT = 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc;\\n\\n /**\\n * @dev Emitted when the implementation is upgraded.\\n */\\n event Upgraded(address indexed implementation);\\n\\n /**\\n * @dev Returns the current implementation address.\\n */\\n function _getImplementation() internal view returns (address) {\\n return StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value;\\n }\\n\\n /**\\n * @dev Stores a new address in the EIP1967 implementation slot.\\n */\\n function _setImplementation(address newImplementation) private {\\n require(Address.isContract(newImplementation), \\\"ERC1967: new implementation is not a contract\\\");\\n StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value = newImplementation;\\n }\\n\\n /**\\n * @dev Perform implementation upgrade\\n *\\n * Emits an {Upgraded} event.\\n */\\n function _upgradeTo(address newImplementation) internal {\\n _setImplementation(newImplementation);\\n emit Upgraded(newImplementation);\\n }\\n\\n /**\\n * @dev Perform implementation upgrade with additional setup call.\\n *\\n * Emits an {Upgraded} event.\\n */\\n function _upgradeToAndCall(\\n address newImplementation,\\n bytes memory data,\\n bool forceCall\\n ) internal {\\n _upgradeTo(newImplementation);\\n if (data.length > 0 || forceCall) {\\n Address.functionDelegateCall(newImplementation, data);\\n }\\n }\\n\\n /**\\n * @dev Perform implementation upgrade with security checks for UUPS proxies, and additional setup call.\\n *\\n * Emits an {Upgraded} event.\\n */\\n function _upgradeToAndCallUUPS(\\n address newImplementation,\\n bytes memory data,\\n bool forceCall\\n ) internal {\\n // Upgrades from old implementations will perform a rollback test. This test requires the new\\n // implementation to upgrade back to the old, non-ERC1822 compliant, implementation. Removing\\n // this special case will break upgrade paths from old UUPS implementation to new ones.\\n if (StorageSlot.getBooleanSlot(_ROLLBACK_SLOT).value) {\\n _setImplementation(newImplementation);\\n } else {\\n try IERC1822Proxiable(newImplementation).proxiableUUID() returns (bytes32 slot) {\\n require(slot == _IMPLEMENTATION_SLOT, \\\"ERC1967Upgrade: unsupported proxiableUUID\\\");\\n } catch {\\n revert(\\\"ERC1967Upgrade: new implementation is not UUPS\\\");\\n }\\n _upgradeToAndCall(newImplementation, data, forceCall);\\n }\\n }\\n\\n /**\\n * @dev Storage slot with the admin of the contract.\\n * This is the keccak-256 hash of \\\"eip1967.proxy.admin\\\" subtracted by 1, and is\\n * validated in the constructor.\\n */\\n bytes32 internal constant _ADMIN_SLOT = 0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103;\\n\\n /**\\n * @dev Emitted when the admin account has changed.\\n */\\n event AdminChanged(address previousAdmin, address newAdmin);\\n\\n /**\\n * @dev Returns the current admin.\\n */\\n function _getAdmin() internal view returns (address) {\\n return StorageSlot.getAddressSlot(_ADMIN_SLOT).value;\\n }\\n\\n /**\\n * @dev Stores a new address in the EIP1967 admin slot.\\n */\\n function _setAdmin(address newAdmin) private {\\n require(newAdmin != address(0), \\\"ERC1967: new admin is the zero address\\\");\\n StorageSlot.getAddressSlot(_ADMIN_SLOT).value = newAdmin;\\n }\\n\\n /**\\n * @dev Changes the admin of the proxy.\\n *\\n * Emits an {AdminChanged} event.\\n */\\n function _changeAdmin(address newAdmin) internal {\\n emit AdminChanged(_getAdmin(), newAdmin);\\n _setAdmin(newAdmin);\\n }\\n\\n /**\\n * @dev The storage slot of the UpgradeableBeacon contract which defines the implementation for this proxy.\\n * This is bytes32(uint256(keccak256('eip1967.proxy.beacon')) - 1)) and is validated in the constructor.\\n */\\n bytes32 internal constant _BEACON_SLOT = 0xa3f0ad74e5423aebfd80d3ef4346578335a9a72aeaee59ff6cb3582b35133d50;\\n\\n /**\\n * @dev Emitted when the beacon is upgraded.\\n */\\n event BeaconUpgraded(address indexed beacon);\\n\\n /**\\n * @dev Returns the current beacon.\\n */\\n function _getBeacon() internal view returns (address) {\\n return StorageSlot.getAddressSlot(_BEACON_SLOT).value;\\n }\\n\\n /**\\n * @dev Stores a new beacon in the EIP1967 beacon slot.\\n */\\n function _setBeacon(address newBeacon) private {\\n require(Address.isContract(newBeacon), \\\"ERC1967: new beacon is not a contract\\\");\\n require(\\n Address.isContract(IBeacon(newBeacon).implementation()),\\n \\\"ERC1967: beacon implementation is not a contract\\\"\\n );\\n StorageSlot.getAddressSlot(_BEACON_SLOT).value = newBeacon;\\n }\\n\\n /**\\n * @dev Perform beacon upgrade with additional setup call. Note: This upgrades the address of the beacon, it does\\n * not upgrade the implementation contained in the beacon (see {UpgradeableBeacon-_setImplementation} for that).\\n *\\n * Emits a {BeaconUpgraded} event.\\n */\\n function _upgradeBeaconToAndCall(\\n address newBeacon,\\n bytes memory data,\\n bool forceCall\\n ) internal {\\n _setBeacon(newBeacon);\\n emit BeaconUpgraded(newBeacon);\\n if (data.length > 0 || forceCall) {\\n Address.functionDelegateCall(IBeacon(newBeacon).implementation(), data);\\n }\\n }\\n}\\n\",\"keccak256\":\"0xabf3f59bc0e5423eae45e459dbe92e7052c6983628d39008590edc852a62f94a\",\"license\":\"MIT\"},\"@openzeppelin/contracts/proxy/Proxy.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.6.0) (proxy/Proxy.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev This abstract contract provides a fallback function that delegates all calls to another contract using the EVM\\n * instruction `delegatecall`. We refer to the second contract as the _implementation_ behind the proxy, and it has to\\n * be specified by overriding the virtual {_implementation} function.\\n *\\n * Additionally, delegation to the implementation can be triggered manually through the {_fallback} function, or to a\\n * different contract through the {_delegate} function.\\n *\\n * The success and return data of the delegated call will be returned back to the caller of the proxy.\\n */\\nabstract contract Proxy {\\n /**\\n * @dev Delegates the current call to `implementation`.\\n *\\n * This function does not return to its internal call site, it will return directly to the external caller.\\n */\\n function _delegate(address implementation) internal virtual {\\n assembly {\\n // Copy msg.data. We take full control of memory in this inline assembly\\n // block because it will not return to Solidity code. We overwrite the\\n // Solidity scratch pad at memory position 0.\\n calldatacopy(0, 0, calldatasize())\\n\\n // Call the implementation.\\n // out and outsize are 0 because we don't know the size yet.\\n let result := delegatecall(gas(), implementation, 0, calldatasize(), 0, 0)\\n\\n // Copy the returned data.\\n returndatacopy(0, 0, returndatasize())\\n\\n switch result\\n // delegatecall returns 0 on error.\\n case 0 {\\n revert(0, returndatasize())\\n }\\n default {\\n return(0, returndatasize())\\n }\\n }\\n }\\n\\n /**\\n * @dev This is a virtual function that should be overridden so it returns the address to which the fallback function\\n * and {_fallback} should delegate.\\n */\\n function _implementation() internal view virtual returns (address);\\n\\n /**\\n * @dev Delegates the current call to the address returned by `_implementation()`.\\n *\\n * This function does not return to its internal call site, it will return directly to the external caller.\\n */\\n function _fallback() internal virtual {\\n _beforeFallback();\\n _delegate(_implementation());\\n }\\n\\n /**\\n * @dev Fallback function that delegates calls to the address returned by `_implementation()`. Will run if no other\\n * function in the contract matches the call data.\\n */\\n fallback() external payable virtual {\\n _fallback();\\n }\\n\\n /**\\n * @dev Fallback function that delegates calls to the address returned by `_implementation()`. Will run if call data\\n * is empty.\\n */\\n receive() external payable virtual {\\n _fallback();\\n }\\n\\n /**\\n * @dev Hook that is called before falling back to the implementation. Can happen as part of a manual `_fallback`\\n * call, or as part of the Solidity `fallback` or `receive` functions.\\n *\\n * If overridden should call `super._beforeFallback()`.\\n */\\n function _beforeFallback() internal virtual {}\\n}\\n\",\"keccak256\":\"0xc130fe33f1b2132158531a87734153293f6d07bc263ff4ac90e85da9c82c0e27\",\"license\":\"MIT\"},\"@openzeppelin/contracts/proxy/beacon/IBeacon.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (proxy/beacon/IBeacon.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev This is the interface that {BeaconProxy} expects of its beacon.\\n */\\ninterface IBeacon {\\n /**\\n * @dev Must return an address that can be used as a delegate call target.\\n *\\n * {BeaconProxy} will check that this address is a contract.\\n */\\n function implementation() external view returns (address);\\n}\\n\",\"keccak256\":\"0xd50a3421ac379ccb1be435fa646d66a65c986b4924f0849839f08692f39dde61\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/Address.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.7.0) (utils/Address.sol)\\n\\npragma solidity ^0.8.1;\\n\\n/**\\n * @dev Collection of functions related to the address type\\n */\\nlibrary Address {\\n /**\\n * @dev Returns true if `account` is a contract.\\n *\\n * [IMPORTANT]\\n * ====\\n * It is unsafe to assume that an address for which this function returns\\n * false is an externally-owned account (EOA) and not a contract.\\n *\\n * Among others, `isContract` will return false for the following\\n * types of addresses:\\n *\\n * - an externally-owned account\\n * - a contract in construction\\n * - an address where a contract will be created\\n * - an address where a contract lived, but was destroyed\\n * ====\\n *\\n * [IMPORTANT]\\n * ====\\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\\n *\\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\\n * constructor.\\n * ====\\n */\\n function isContract(address account) internal view returns (bool) {\\n // This method relies on extcodesize/address.code.length, which returns 0\\n // for contracts in construction, since the code is only stored at the end\\n // of the constructor execution.\\n\\n return account.code.length > 0;\\n }\\n\\n /**\\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\\n * `recipient`, forwarding all available gas and reverting on errors.\\n *\\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\\n * imposed by `transfer`, making them unable to receive funds via\\n * `transfer`. {sendValue} removes this limitation.\\n *\\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\\n *\\n * IMPORTANT: because control is transferred to `recipient`, care must be\\n * taken to not create reentrancy vulnerabilities. Consider using\\n * {ReentrancyGuard} or the\\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\\n */\\n function sendValue(address payable recipient, uint256 amount) internal {\\n require(address(this).balance >= amount, \\\"Address: insufficient balance\\\");\\n\\n (bool success, ) = recipient.call{value: amount}(\\\"\\\");\\n require(success, \\\"Address: unable to send value, recipient may have reverted\\\");\\n }\\n\\n /**\\n * @dev Performs a Solidity function call using a low level `call`. A\\n * plain `call` is an unsafe replacement for a function call: use this\\n * function instead.\\n *\\n * If `target` reverts with a revert reason, it is bubbled up by this\\n * function (like regular Solidity function calls).\\n *\\n * Returns the raw returned data. To convert to the expected return value,\\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\\n *\\n * Requirements:\\n *\\n * - `target` must be a contract.\\n * - calling `target` with `data` must not revert.\\n *\\n * _Available since v3.1._\\n */\\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\\n return functionCall(target, data, \\\"Address: low-level call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\\n * `errorMessage` as a fallback revert reason when `target` reverts.\\n *\\n * _Available since v3.1._\\n */\\n function functionCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n return functionCallWithValue(target, data, 0, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but also transferring `value` wei to `target`.\\n *\\n * Requirements:\\n *\\n * - the calling contract must have an ETH balance of at least `value`.\\n * - the called Solidity function must be `payable`.\\n *\\n * _Available since v3.1._\\n */\\n function functionCallWithValue(\\n address target,\\n bytes memory data,\\n uint256 value\\n ) internal returns (bytes memory) {\\n return functionCallWithValue(target, data, value, \\\"Address: low-level call with value failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\\n * with `errorMessage` as a fallback revert reason when `target` reverts.\\n *\\n * _Available since v3.1._\\n */\\n function functionCallWithValue(\\n address target,\\n bytes memory data,\\n uint256 value,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n require(address(this).balance >= value, \\\"Address: insufficient balance for call\\\");\\n require(isContract(target), \\\"Address: call to non-contract\\\");\\n\\n (bool success, bytes memory returndata) = target.call{value: value}(data);\\n return verifyCallResult(success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but performing a static call.\\n *\\n * _Available since v3.3._\\n */\\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\\n return functionStaticCall(target, data, \\\"Address: low-level static call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\\n * but performing a static call.\\n *\\n * _Available since v3.3._\\n */\\n function functionStaticCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal view returns (bytes memory) {\\n require(isContract(target), \\\"Address: static call to non-contract\\\");\\n\\n (bool success, bytes memory returndata) = target.staticcall(data);\\n return verifyCallResult(success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but performing a delegate call.\\n *\\n * _Available since v3.4._\\n */\\n function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {\\n return functionDelegateCall(target, data, \\\"Address: low-level delegate call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\\n * but performing a delegate call.\\n *\\n * _Available since v3.4._\\n */\\n function functionDelegateCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n require(isContract(target), \\\"Address: delegate call to non-contract\\\");\\n\\n (bool success, bytes memory returndata) = target.delegatecall(data);\\n return verifyCallResult(success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the\\n * revert reason using the provided one.\\n *\\n * _Available since v4.3._\\n */\\n function verifyCallResult(\\n bool success,\\n bytes memory returndata,\\n string memory errorMessage\\n ) internal pure returns (bytes memory) {\\n if (success) {\\n return returndata;\\n } else {\\n // Look for revert reason and bubble it up if present\\n if (returndata.length > 0) {\\n // The easiest way to bubble the revert reason is using memory via assembly\\n /// @solidity memory-safe-assembly\\n assembly {\\n let returndata_size := mload(returndata)\\n revert(add(32, returndata), returndata_size)\\n }\\n } else {\\n revert(errorMessage);\\n }\\n }\\n }\\n}\\n\",\"keccak256\":\"0xd6153ce99bcdcce22b124f755e72553295be6abcd63804cfdffceb188b8bef10\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/StorageSlot.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.7.0) (utils/StorageSlot.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Library for reading and writing primitive types to specific storage slots.\\n *\\n * Storage slots are often used to avoid storage conflict when dealing with upgradeable contracts.\\n * This library helps with reading and writing to such slots without the need for inline assembly.\\n *\\n * The functions in this library return Slot structs that contain a `value` member that can be used to read or write.\\n *\\n * Example usage to set ERC1967 implementation slot:\\n * ```\\n * contract ERC1967 {\\n * bytes32 internal constant _IMPLEMENTATION_SLOT = 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc;\\n *\\n * function _getImplementation() internal view returns (address) {\\n * return StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value;\\n * }\\n *\\n * function _setImplementation(address newImplementation) internal {\\n * require(Address.isContract(newImplementation), \\\"ERC1967: new implementation is not a contract\\\");\\n * StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value = newImplementation;\\n * }\\n * }\\n * ```\\n *\\n * _Available since v4.1 for `address`, `bool`, `bytes32`, and `uint256`._\\n */\\nlibrary StorageSlot {\\n struct AddressSlot {\\n address value;\\n }\\n\\n struct BooleanSlot {\\n bool value;\\n }\\n\\n struct Bytes32Slot {\\n bytes32 value;\\n }\\n\\n struct Uint256Slot {\\n uint256 value;\\n }\\n\\n /**\\n * @dev Returns an `AddressSlot` with member `value` located at `slot`.\\n */\\n function getAddressSlot(bytes32 slot) internal pure returns (AddressSlot storage r) {\\n /// @solidity memory-safe-assembly\\n assembly {\\n r.slot := slot\\n }\\n }\\n\\n /**\\n * @dev Returns an `BooleanSlot` with member `value` located at `slot`.\\n */\\n function getBooleanSlot(bytes32 slot) internal pure returns (BooleanSlot storage r) {\\n /// @solidity memory-safe-assembly\\n assembly {\\n r.slot := slot\\n }\\n }\\n\\n /**\\n * @dev Returns an `Bytes32Slot` with member `value` located at `slot`.\\n */\\n function getBytes32Slot(bytes32 slot) internal pure returns (Bytes32Slot storage r) {\\n /// @solidity memory-safe-assembly\\n assembly {\\n r.slot := slot\\n }\\n }\\n\\n /**\\n * @dev Returns an `Uint256Slot` with member `value` located at `slot`.\\n */\\n function getUint256Slot(bytes32 slot) internal pure returns (Uint256Slot storage r) {\\n /// @solidity memory-safe-assembly\\n assembly {\\n r.slot := slot\\n }\\n }\\n}\\n\",\"keccak256\":\"0xd5c50c54bf02740ebd122ff06832546cb5fa84486d52695a9ccfd11666e0c81d\",\"license\":\"MIT\"},\"contracts/external/TransparentUpgradeableProxy.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-3.0\\n\\npragma solidity ^0.8.12;\\n\\nimport \\\"@openzeppelin/contracts/proxy/ERC1967/ERC1967Proxy.sol\\\";\\n\\n/**\\n * @dev This contract implements a proxy that is upgradeable by an admin. It is fully forked from OpenZeppelin\\n * `TransparentUpgradeableProxy`\\n *\\n * To avoid https://medium.com/nomic-labs-blog/malicious-backdoors-in-ethereum-proxies-62629adf3357[proxy selector\\n * clashing], which can potentially be used in an attack, this contract uses the\\n * https://blog.openzeppelin.com/the-transparent-proxy-pattern/[transparent proxy pattern]. This pattern implies two\\n * things that go hand in hand:\\n *\\n * 1. If any account other than the admin calls the proxy, the call will be forwarded to the implementation, even if\\n * that call matches one of the admin functions exposed by the proxy itself.\\n * 2. If the admin calls the proxy, it can access the admin functions, but its calls will never be forwarded to the\\n * implementation. If the admin tries to call a function on the implementation it will fail with an error that says\\n * \\\"admin cannot fallback to proxy target\\\".\\n *\\n * These properties mean that the admin account can only be used for admin actions like upgrading the proxy or changing\\n * the admin, so it's best if it's a dedicated account that is not used for anything else. This will avoid headaches due\\n * to sudden errors when trying to call a function from the proxy implementation.\\n *\\n * Our recommendation is for the dedicated account to be an instance of the {ProxyAdmin} contract. If set up this way,\\n * you should think of the `ProxyAdmin` instance as the real administrative interface of your proxy.\\n */\\ncontract TransparentUpgradeableProxy is ERC1967Proxy {\\n /**\\n * @dev Initializes an upgradeable proxy managed by `_admin`, backed by the implementation at `_logic`, and\\n * optionally initialized with `_data` as explained in {ERC1967Proxy-constructor}.\\n */\\n constructor(address _logic, address admin_, bytes memory _data) payable ERC1967Proxy(_logic, _data) {\\n assert(_ADMIN_SLOT == bytes32(uint256(keccak256(\\\"eip1967.proxy.admin\\\")) - 1));\\n _changeAdmin(admin_);\\n }\\n\\n /**\\n * @dev Modifier used internally that will delegate the call to the implementation unless the sender is the admin.\\n */\\n modifier ifAdmin() {\\n if (msg.sender == _getAdmin()) {\\n _;\\n } else {\\n _fallback();\\n }\\n }\\n\\n /**\\n * @dev Returns the current admin.\\n *\\n * NOTE: Only the admin can call this function. See {ProxyAdmin-getProxyAdmin}.\\n *\\n * TIP: To get this value clients can read directly from the storage slot shown below (specified by EIP1967) using the\\n * https://eth.wiki/json-rpc/API#eth_getstorageat[`eth_getStorageAt`] RPC call.\\n * `0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103`\\n */\\n function admin() external ifAdmin returns (address admin_) {\\n admin_ = _getAdmin();\\n }\\n\\n /**\\n * @dev Returns the current implementation.\\n *\\n * NOTE: Only the admin can call this function. See {ProxyAdmin-getProxyImplementation}.\\n *\\n * TIP: To get this value clients can read directly from the storage slot shown below (specified by EIP1967) using the\\n * https://eth.wiki/json-rpc/API#eth_getstorageat[`eth_getStorageAt`] RPC call.\\n * `0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc`\\n */\\n function implementation() external ifAdmin returns (address implementation_) {\\n implementation_ = _implementation();\\n }\\n\\n /**\\n * @dev Changes the admin of the proxy.\\n *\\n * Emits an {AdminChanged} event.\\n *\\n * NOTE: Only the admin can call this function. See {ProxyAdmin-changeProxyAdmin}.\\n */\\n function changeAdmin(address newAdmin) external virtual ifAdmin {\\n _changeAdmin(newAdmin);\\n }\\n\\n /**\\n * @dev Upgrade the implementation of the proxy.\\n *\\n * NOTE: Only the admin can call this function. See {ProxyAdmin-upgrade}.\\n */\\n function upgradeTo(address newImplementation) external ifAdmin {\\n _upgradeToAndCall(newImplementation, bytes(\\\"\\\"), false);\\n }\\n\\n /**\\n * @dev Upgrade the implementation of the proxy, and then call a function from the new implementation as specified\\n * by `data`, which should be an encoded function call. This is useful to initialize new storage variables in the\\n * proxied contract.\\n *\\n * NOTE: Only the admin can call this function. See {ProxyAdmin-upgradeAndCall}.\\n */\\n function upgradeToAndCall(address newImplementation, bytes calldata data) external payable ifAdmin {\\n _upgradeToAndCall(newImplementation, data, true);\\n }\\n\\n /**\\n * @dev Returns the current admin.\\n */\\n function _admin() internal view virtual returns (address) {\\n return _getAdmin();\\n }\\n\\n /**\\n * @dev Makes sure the admin cannot access the fallback function. See {Proxy-_beforeFallback}.\\n */\\n function _beforeFallback() internal virtual override {\\n require(msg.sender != _getAdmin(), \\\"TransparentUpgradeableProxy: admin cannot fallback to proxy target\\\");\\n super._beforeFallback();\\n }\\n}\\n\",\"keccak256\":\"0x93a67a0f612ea3ff2a76315e138a6a88267270a1379d3cc7be52845fbbe611e2\",\"license\":\"GPL-3.0\"}},\"version\":1}", + "bytecode": "0x6080604052604051620010bb380380620010bb8339810160408190526200002691620004d8565b828162000036828260006200009a565b5062000066905060017fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6104620005b8565b6000805160206200107483398151915214620000865762000086620005da565b6200009182620000d7565b50505062000643565b620000a58362000132565b600082511180620000b35750805b15620000d257620000d083836200017460201b6200028c1760201c565b505b505050565b7f7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f62000102620001a5565b604080516001600160a01b03928316815291841660208301520160405180910390a16200012f81620001de565b50565b6200013d8162000293565b6040516001600160a01b038216907fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b90600090a250565b60606200019c8383604051806060016040528060278152602001620010946027913962000347565b90505b92915050565b6000620001cf6000805160206200107483398151915260001b6200042f60201b6200022e1760201c565b546001600160a01b0316919050565b6001600160a01b038116620002495760405162461bcd60e51b815260206004820152602660248201527f455243313936373a206e65772061646d696e20697320746865207a65726f206160448201526564647265737360d01b60648201526084015b60405180910390fd5b80620002726000805160206200107483398151915260001b6200042f60201b6200022e1760201c565b80546001600160a01b0319166001600160a01b039290921691909117905550565b620002a9816200043260201b620002b81760201c565b6200030d5760405162461bcd60e51b815260206004820152602d60248201527f455243313936373a206e657720696d706c656d656e746174696f6e206973206e60448201526c1bdd08184818dbdb9d1c9858dd609a1b606482015260840162000240565b80620002727f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc60001b6200042f60201b6200022e1760201c565b60606001600160a01b0384163b620003b15760405162461bcd60e51b815260206004820152602660248201527f416464726573733a2064656c65676174652063616c6c20746f206e6f6e2d636f6044820152651b9d1c9858dd60d21b606482015260840162000240565b600080856001600160a01b031685604051620003ce9190620005f0565b600060405180830381855af49150503d80600081146200040b576040519150601f19603f3d011682016040523d82523d6000602084013e62000410565b606091505b5090925090506200042382828662000441565b925050505b9392505050565b90565b6001600160a01b03163b151590565b606083156200045257508162000428565b825115620004635782518084602001fd5b8160405162461bcd60e51b81526004016200024091906200060e565b80516001600160a01b03811681146200049757600080fd5b919050565b634e487b7160e01b600052604160045260246000fd5b60005b83811015620004cf578181015183820152602001620004b5565b50506000910152565b600080600060608486031215620004ee57600080fd5b620004f9846200047f565b925062000509602085016200047f565b60408501519092506001600160401b03808211156200052757600080fd5b818601915086601f8301126200053c57600080fd5b8151818111156200055157620005516200049c565b604051601f8201601f19908116603f011681019083821181831017156200057c576200057c6200049c565b816040528281528960208487010111156200059657600080fd5b620005a9836020830160208801620004b2565b80955050505050509250925092565b818103818111156200019f57634e487b7160e01b600052601160045260246000fd5b634e487b7160e01b600052600160045260246000fd5b6000825162000604818460208701620004b2565b9190910192915050565b60208152600082518060208401526200062f816040850160208701620004b2565b601f01601f19169190910160400192915050565b610a2180620006536000396000f3fe60806040526004361061005e5760003560e01c80635c60da1b116100435780635c60da1b146100a85780638f283970146100e6578063f851a440146101065761006d565b80633659cfe6146100755780634f1ef286146100955761006d565b3661006d5761006b61011b565b005b61006b61011b565b34801561008157600080fd5b5061006b610090366004610895565b610135565b61006b6100a33660046108b0565b61017f565b3480156100b457600080fd5b506100bd6101f3565b60405173ffffffffffffffffffffffffffffffffffffffff909116815260200160405180910390f35b3480156100f257600080fd5b5061006b610101366004610895565b610231565b34801561011257600080fd5b506100bd61025e565b6101236102d4565b61013361012e6103ab565b6103b5565b565b61013d6103d9565b73ffffffffffffffffffffffffffffffffffffffff1633036101775761017481604051806020016040528060008152506000610419565b50565b61017461011b565b6101876103d9565b73ffffffffffffffffffffffffffffffffffffffff1633036101eb576101e68383838080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525060019250610419915050565b505050565b6101e661011b565b60006101fd6103d9565b73ffffffffffffffffffffffffffffffffffffffff163303610226576102216103ab565b905090565b61022e61011b565b90565b6102396103d9565b73ffffffffffffffffffffffffffffffffffffffff1633036101775761017481610444565b60006102686103d9565b73ffffffffffffffffffffffffffffffffffffffff163303610226576102216103d9565b60606102b183836040518060600160405280602781526020016109c5602791396104a5565b9392505050565b73ffffffffffffffffffffffffffffffffffffffff163b151590565b6102dc6103d9565b73ffffffffffffffffffffffffffffffffffffffff163303610133576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604260248201527f5472616e73706172656e745570677261646561626c6550726f78793a2061646d60448201527f696e2063616e6e6f742066616c6c6261636b20746f2070726f7879207461726760648201527f6574000000000000000000000000000000000000000000000000000000000000608482015260a4015b60405180910390fd5b60006102216105cd565b3660008037600080366000845af43d6000803e8080156103d4573d6000f35b3d6000fd5b60007fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035b5473ffffffffffffffffffffffffffffffffffffffff16919050565b610422836105f5565b60008251118061042f5750805b156101e65761043e838361028c565b50505050565b7f7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f61046d6103d9565b6040805173ffffffffffffffffffffffffffffffffffffffff928316815291841660208301520160405180910390a161017481610642565b606073ffffffffffffffffffffffffffffffffffffffff84163b61054b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f416464726573733a2064656c65676174652063616c6c20746f206e6f6e2d636f60448201527f6e7472616374000000000000000000000000000000000000000000000000000060648201526084016103a2565b6000808573ffffffffffffffffffffffffffffffffffffffff16856040516105739190610957565b600060405180830381855af49150503d80600081146105ae576040519150601f19603f3d011682016040523d82523d6000602084013e6105b3565b606091505b50915091506105c382828661074e565b9695505050505050565b60007f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc6103fd565b6105fe816107a1565b60405173ffffffffffffffffffffffffffffffffffffffff8216907fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b90600090a250565b73ffffffffffffffffffffffffffffffffffffffff81166106e5576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f455243313936373a206e65772061646d696e20697320746865207a65726f206160448201527f646472657373000000000000000000000000000000000000000000000000000060648201526084016103a2565b807fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035b80547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff9290921691909117905550565b6060831561075d5750816102b1565b82511561076d5782518084602001fd5b816040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016103a29190610973565b73ffffffffffffffffffffffffffffffffffffffff81163b610845576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602d60248201527f455243313936373a206e657720696d706c656d656e746174696f6e206973206e60448201527f6f74206120636f6e74726163740000000000000000000000000000000000000060648201526084016103a2565b807f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc610708565b803573ffffffffffffffffffffffffffffffffffffffff8116811461089057600080fd5b919050565b6000602082840312156108a757600080fd5b6102b18261086c565b6000806000604084860312156108c557600080fd5b6108ce8461086c565b9250602084013567ffffffffffffffff808211156108eb57600080fd5b818601915086601f8301126108ff57600080fd5b81358181111561090e57600080fd5b87602082850101111561092057600080fd5b6020830194508093505050509250925092565b60005b8381101561094e578181015183820152602001610936565b50506000910152565b60008251610969818460208701610933565b9190910192915050565b6020815260008251806020840152610992816040850160208701610933565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016919091016040019291505056fe416464726573733a206c6f772d6c6576656c2064656c65676174652063616c6c206661696c6564a2646970667358221220e96638b07fb1675d93a95c49e417bc8111448b23a59918698cdcd8fd488dd7cf64736f6c63430008110033b53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103416464726573733a206c6f772d6c6576656c2064656c65676174652063616c6c206661696c6564", + "deployedBytecode": "0x60806040526004361061005e5760003560e01c80635c60da1b116100435780635c60da1b146100a85780638f283970146100e6578063f851a440146101065761006d565b80633659cfe6146100755780634f1ef286146100955761006d565b3661006d5761006b61011b565b005b61006b61011b565b34801561008157600080fd5b5061006b610090366004610895565b610135565b61006b6100a33660046108b0565b61017f565b3480156100b457600080fd5b506100bd6101f3565b60405173ffffffffffffffffffffffffffffffffffffffff909116815260200160405180910390f35b3480156100f257600080fd5b5061006b610101366004610895565b610231565b34801561011257600080fd5b506100bd61025e565b6101236102d4565b61013361012e6103ab565b6103b5565b565b61013d6103d9565b73ffffffffffffffffffffffffffffffffffffffff1633036101775761017481604051806020016040528060008152506000610419565b50565b61017461011b565b6101876103d9565b73ffffffffffffffffffffffffffffffffffffffff1633036101eb576101e68383838080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525060019250610419915050565b505050565b6101e661011b565b60006101fd6103d9565b73ffffffffffffffffffffffffffffffffffffffff163303610226576102216103ab565b905090565b61022e61011b565b90565b6102396103d9565b73ffffffffffffffffffffffffffffffffffffffff1633036101775761017481610444565b60006102686103d9565b73ffffffffffffffffffffffffffffffffffffffff163303610226576102216103d9565b60606102b183836040518060600160405280602781526020016109c5602791396104a5565b9392505050565b73ffffffffffffffffffffffffffffffffffffffff163b151590565b6102dc6103d9565b73ffffffffffffffffffffffffffffffffffffffff163303610133576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604260248201527f5472616e73706172656e745570677261646561626c6550726f78793a2061646d60448201527f696e2063616e6e6f742066616c6c6261636b20746f2070726f7879207461726760648201527f6574000000000000000000000000000000000000000000000000000000000000608482015260a4015b60405180910390fd5b60006102216105cd565b3660008037600080366000845af43d6000803e8080156103d4573d6000f35b3d6000fd5b60007fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035b5473ffffffffffffffffffffffffffffffffffffffff16919050565b610422836105f5565b60008251118061042f5750805b156101e65761043e838361028c565b50505050565b7f7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f61046d6103d9565b6040805173ffffffffffffffffffffffffffffffffffffffff928316815291841660208301520160405180910390a161017481610642565b606073ffffffffffffffffffffffffffffffffffffffff84163b61054b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f416464726573733a2064656c65676174652063616c6c20746f206e6f6e2d636f60448201527f6e7472616374000000000000000000000000000000000000000000000000000060648201526084016103a2565b6000808573ffffffffffffffffffffffffffffffffffffffff16856040516105739190610957565b600060405180830381855af49150503d80600081146105ae576040519150601f19603f3d011682016040523d82523d6000602084013e6105b3565b606091505b50915091506105c382828661074e565b9695505050505050565b60007f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc6103fd565b6105fe816107a1565b60405173ffffffffffffffffffffffffffffffffffffffff8216907fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b90600090a250565b73ffffffffffffffffffffffffffffffffffffffff81166106e5576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f455243313936373a206e65772061646d696e20697320746865207a65726f206160448201527f646472657373000000000000000000000000000000000000000000000000000060648201526084016103a2565b807fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035b80547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff9290921691909117905550565b6060831561075d5750816102b1565b82511561076d5782518084602001fd5b816040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016103a29190610973565b73ffffffffffffffffffffffffffffffffffffffff81163b610845576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602d60248201527f455243313936373a206e657720696d706c656d656e746174696f6e206973206e60448201527f6f74206120636f6e74726163740000000000000000000000000000000000000060648201526084016103a2565b807f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc610708565b803573ffffffffffffffffffffffffffffffffffffffff8116811461089057600080fd5b919050565b6000602082840312156108a757600080fd5b6102b18261086c565b6000806000604084860312156108c557600080fd5b6108ce8461086c565b9250602084013567ffffffffffffffff808211156108eb57600080fd5b818601915086601f8301126108ff57600080fd5b81358181111561090e57600080fd5b87602082850101111561092057600080fd5b6020830194508093505050509250925092565b60005b8381101561094e578181015183820152602001610936565b50506000910152565b60008251610969818460208701610933565b9190910192915050565b6020815260008251806020840152610992816040850160208701610933565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016919091016040019291505056fe416464726573733a206c6f772d6c6576656c2064656c65676174652063616c6c206661696c6564a2646970667358221220e96638b07fb1675d93a95c49e417bc8111448b23a59918698cdcd8fd488dd7cf64736f6c63430008110033", + "devdoc": { + "details": "This contract implements a proxy that is upgradeable by an admin. It is fully forked from OpenZeppelin `TransparentUpgradeableProxy` To avoid https://medium.com/nomic-labs-blog/malicious-backdoors-in-ethereum-proxies-62629adf3357[proxy selector clashing], which can potentially be used in an attack, this contract uses the https://blog.openzeppelin.com/the-transparent-proxy-pattern/[transparent proxy pattern]. This pattern implies two things that go hand in hand: 1. If any account other than the admin calls the proxy, the call will be forwarded to the implementation, even if that call matches one of the admin functions exposed by the proxy itself. 2. If the admin calls the proxy, it can access the admin functions, but its calls will never be forwarded to the implementation. If the admin tries to call a function on the implementation it will fail with an error that says \"admin cannot fallback to proxy target\". These properties mean that the admin account can only be used for admin actions like upgrading the proxy or changing the admin, so it's best if it's a dedicated account that is not used for anything else. This will avoid headaches due to sudden errors when trying to call a function from the proxy implementation. Our recommendation is for the dedicated account to be an instance of the {ProxyAdmin} contract. If set up this way, you should think of the `ProxyAdmin` instance as the real administrative interface of your proxy.", + "kind": "dev", + "methods": { + "admin()": { + "details": "Returns the current admin. NOTE: Only the admin can call this function. See {ProxyAdmin-getProxyAdmin}. TIP: To get this value clients can read directly from the storage slot shown below (specified by EIP1967) using the https://eth.wiki/json-rpc/API#eth_getstorageat[`eth_getStorageAt`] RPC call. `0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103`" + }, + "changeAdmin(address)": { + "details": "Changes the admin of the proxy. Emits an {AdminChanged} event. NOTE: Only the admin can call this function. See {ProxyAdmin-changeProxyAdmin}." + }, + "constructor": { + "details": "Initializes an upgradeable proxy managed by `_admin`, backed by the implementation at `_logic`, and optionally initialized with `_data` as explained in {ERC1967Proxy-constructor}." + }, + "implementation()": { + "details": "Returns the current implementation. NOTE: Only the admin can call this function. See {ProxyAdmin-getProxyImplementation}. TIP: To get this value clients can read directly from the storage slot shown below (specified by EIP1967) using the https://eth.wiki/json-rpc/API#eth_getstorageat[`eth_getStorageAt`] RPC call. `0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc`" + }, + "upgradeTo(address)": { + "details": "Upgrade the implementation of the proxy. NOTE: Only the admin can call this function. See {ProxyAdmin-upgrade}." + }, + "upgradeToAndCall(address,bytes)": { + "details": "Upgrade the implementation of the proxy, and then call a function from the new implementation as specified by `data`, which should be an encoded function call. This is useful to initialize new storage variables in the proxied contract. NOTE: Only the admin can call this function. See {ProxyAdmin-upgradeAndCall}." + } + }, + "version": 1 + }, + "userdoc": { + "kind": "user", + "methods": {}, + "version": 1 + }, + "storageLayout": { + "storage": [], + "types": null + } +} \ No newline at end of file diff --git a/deployments/gnosis/Treasury_USD.json b/deployments/gnosis/Treasury_USD.json new file mode 100644 index 00000000..ab06b2d9 --- /dev/null +++ b/deployments/gnosis/Treasury_USD.json @@ -0,0 +1,247 @@ +{ + "address": "0x3E9Ea799C447B3C65702c82F8193085F330a1DB0", + "abi": [ + { + "inputs": [ + { + "internalType": "address", + "name": "_logic", + "type": "address" + }, + { + "internalType": "address", + "name": "admin_", + "type": "address" + }, + { + "internalType": "bytes", + "name": "_data", + "type": "bytes" + } + ], + "stateMutability": "payable", + "type": "constructor" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "previousAdmin", + "type": "address" + }, + { + "indexed": false, + "internalType": "address", + "name": "newAdmin", + "type": "address" + } + ], + "name": "AdminChanged", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "beacon", + "type": "address" + } + ], + "name": "BeaconUpgraded", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "implementation", + "type": "address" + } + ], + "name": "Upgraded", + "type": "event" + }, + { + "stateMutability": "payable", + "type": "fallback" + }, + { + "inputs": [], + "name": "admin", + "outputs": [ + { + "internalType": "address", + "name": "admin_", + "type": "address" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "newAdmin", + "type": "address" + } + ], + "name": "changeAdmin", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "implementation", + "outputs": [ + { + "internalType": "address", + "name": "implementation_", + "type": "address" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "newImplementation", + "type": "address" + } + ], + "name": "upgradeTo", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "newImplementation", + "type": "address" + }, + { + "internalType": "bytes", + "name": "data", + "type": "bytes" + } + ], + "name": "upgradeToAndCall", + "outputs": [], + "stateMutability": "payable", + "type": "function" + }, + { + "stateMutability": "payable", + "type": "receive" + } + ], + "transactionHash": "0x276dc0a947970d728a12dac803869965bd9f4f156b0e01f8d06f7b1420a54012", + "receipt": { + "to": null, + "from": "0xfdA462548Ce04282f4B6D6619823a7C64Fdc0185", + "contractAddress": "0x3E9Ea799C447B3C65702c82F8193085F330a1DB0", + "transactionIndex": 3, + "gasUsed": "736432", + "logsBloom": "0x00000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000000000004800000000000000000000000000000000040000000000000000000000000000000000080000000000000800000000000000000000000000000000400000000000000000000000000000000000000000020000000000000000000040000000000000404000100000000000000000000000000000000000000080000000000000000000000000000000008000000", + "blockHash": "0xdf33bf8960736b6f39b9270f3ec0f81bb27e7f67d43b95131c7031627f5b7981", + "transactionHash": "0x276dc0a947970d728a12dac803869965bd9f4f156b0e01f8d06f7b1420a54012", + "logs": [ + { + "transactionIndex": 3, + "blockNumber": 31876828, + "transactionHash": "0x276dc0a947970d728a12dac803869965bd9f4f156b0e01f8d06f7b1420a54012", + "address": "0x3E9Ea799C447B3C65702c82F8193085F330a1DB0", + "topics": [ + "0xbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b", + "0x000000000000000000000000c16b81af351ba9e64c1a069e3ab18c244a1e3049" + ], + "data": "0x", + "logIndex": 525, + "blockHash": "0xdf33bf8960736b6f39b9270f3ec0f81bb27e7f67d43b95131c7031627f5b7981" + }, + { + "transactionIndex": 3, + "blockNumber": 31876828, + "transactionHash": "0x276dc0a947970d728a12dac803869965bd9f4f156b0e01f8d06f7b1420a54012", + "address": "0x3E9Ea799C447B3C65702c82F8193085F330a1DB0", + "topics": [ + "0x7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb3847402498" + ], + "data": "0x0000000000000000000000000000000000000000000000000000000000000001", + "logIndex": 526, + "blockHash": "0xdf33bf8960736b6f39b9270f3ec0f81bb27e7f67d43b95131c7031627f5b7981" + }, + { + "transactionIndex": 3, + "blockNumber": 31876828, + "transactionHash": "0x276dc0a947970d728a12dac803869965bd9f4f156b0e01f8d06f7b1420a54012", + "address": "0x3E9Ea799C447B3C65702c82F8193085F330a1DB0", + "topics": [ + "0x7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f" + ], + "data": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000009a5b060bd7b8f86c4c0d720a17367729670afb19", + "logIndex": 527, + "blockHash": "0xdf33bf8960736b6f39b9270f3ec0f81bb27e7f67d43b95131c7031627f5b7981" + } + ], + "blockNumber": 31876828, + "cumulativeGasUsed": "3052952", + "status": 1, + "byzantium": true + }, + "args": [ + "0xC16B81Af351BA9e64C1a069E3Ab18c244A1E3049", + "0x9a5b060Bd7b8f86c4C0D720a17367729670AfB19", + "0x485cc95500000000000000000000000067b9c7c45bbdd1a78aed4b8ff3b1bb3c8170bdab0000000000000000000000000000206329b97db379d5e1bf586bbdb969c63274" + ], + "numDeployments": 1, + "solcInputHash": "871924e0c138825a2736b76def8fef8d", + "metadata": "{\"compiler\":{\"version\":\"0.8.17+commit.8df45f5f\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_logic\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"admin_\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"_data\",\"type\":\"bytes\"}],\"stateMutability\":\"payable\",\"type\":\"constructor\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"previousAdmin\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"newAdmin\",\"type\":\"address\"}],\"name\":\"AdminChanged\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"beacon\",\"type\":\"address\"}],\"name\":\"BeaconUpgraded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"implementation\",\"type\":\"address\"}],\"name\":\"Upgraded\",\"type\":\"event\"},{\"stateMutability\":\"payable\",\"type\":\"fallback\"},{\"inputs\":[],\"name\":\"admin\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"admin_\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newAdmin\",\"type\":\"address\"}],\"name\":\"changeAdmin\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"implementation\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"implementation_\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newImplementation\",\"type\":\"address\"}],\"name\":\"upgradeTo\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newImplementation\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"}],\"name\":\"upgradeToAndCall\",\"outputs\":[],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"stateMutability\":\"payable\",\"type\":\"receive\"}],\"devdoc\":{\"details\":\"This contract implements a proxy that is upgradeable by an admin. It is fully forked from OpenZeppelin `TransparentUpgradeableProxy` To avoid https://medium.com/nomic-labs-blog/malicious-backdoors-in-ethereum-proxies-62629adf3357[proxy selector clashing], which can potentially be used in an attack, this contract uses the https://blog.openzeppelin.com/the-transparent-proxy-pattern/[transparent proxy pattern]. This pattern implies two things that go hand in hand: 1. If any account other than the admin calls the proxy, the call will be forwarded to the implementation, even if that call matches one of the admin functions exposed by the proxy itself. 2. If the admin calls the proxy, it can access the admin functions, but its calls will never be forwarded to the implementation. If the admin tries to call a function on the implementation it will fail with an error that says \\\"admin cannot fallback to proxy target\\\". These properties mean that the admin account can only be used for admin actions like upgrading the proxy or changing the admin, so it's best if it's a dedicated account that is not used for anything else. This will avoid headaches due to sudden errors when trying to call a function from the proxy implementation. Our recommendation is for the dedicated account to be an instance of the {ProxyAdmin} contract. If set up this way, you should think of the `ProxyAdmin` instance as the real administrative interface of your proxy.\",\"kind\":\"dev\",\"methods\":{\"admin()\":{\"details\":\"Returns the current admin. NOTE: Only the admin can call this function. See {ProxyAdmin-getProxyAdmin}. TIP: To get this value clients can read directly from the storage slot shown below (specified by EIP1967) using the https://eth.wiki/json-rpc/API#eth_getstorageat[`eth_getStorageAt`] RPC call. `0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103`\"},\"changeAdmin(address)\":{\"details\":\"Changes the admin of the proxy. Emits an {AdminChanged} event. NOTE: Only the admin can call this function. See {ProxyAdmin-changeProxyAdmin}.\"},\"constructor\":{\"details\":\"Initializes an upgradeable proxy managed by `_admin`, backed by the implementation at `_logic`, and optionally initialized with `_data` as explained in {ERC1967Proxy-constructor}.\"},\"implementation()\":{\"details\":\"Returns the current implementation. NOTE: Only the admin can call this function. See {ProxyAdmin-getProxyImplementation}. TIP: To get this value clients can read directly from the storage slot shown below (specified by EIP1967) using the https://eth.wiki/json-rpc/API#eth_getstorageat[`eth_getStorageAt`] RPC call. `0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc`\"},\"upgradeTo(address)\":{\"details\":\"Upgrade the implementation of the proxy. NOTE: Only the admin can call this function. See {ProxyAdmin-upgrade}.\"},\"upgradeToAndCall(address,bytes)\":{\"details\":\"Upgrade the implementation of the proxy, and then call a function from the new implementation as specified by `data`, which should be an encoded function call. This is useful to initialize new storage variables in the proxied contract. NOTE: Only the admin can call this function. See {ProxyAdmin-upgradeAndCall}.\"}},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/external/TransparentUpgradeableProxy.sol\":\"TransparentUpgradeableProxy\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":1000000},\"remappings\":[]},\"sources\":{\"@openzeppelin/contracts/interfaces/draft-IERC1822.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.5.0) (interfaces/draft-IERC1822.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev ERC1822: Universal Upgradeable Proxy Standard (UUPS) documents a method for upgradeability through a simplified\\n * proxy whose upgrades are fully controlled by the current implementation.\\n */\\ninterface IERC1822Proxiable {\\n /**\\n * @dev Returns the storage slot that the proxiable contract assumes is being used to store the implementation\\n * address.\\n *\\n * IMPORTANT: A proxy pointing at a proxiable contract should not be considered proxiable itself, because this risks\\n * bricking a proxy that upgrades to it, by delegating to itself until out of gas. Thus it is critical that this\\n * function revert if invoked through a proxy.\\n */\\n function proxiableUUID() external view returns (bytes32);\\n}\\n\",\"keccak256\":\"0x1d4afe6cb24200cc4545eed814ecf5847277dfe5d613a1707aad5fceecebcfff\",\"license\":\"MIT\"},\"@openzeppelin/contracts/proxy/ERC1967/ERC1967Proxy.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.7.0) (proxy/ERC1967/ERC1967Proxy.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../Proxy.sol\\\";\\nimport \\\"./ERC1967Upgrade.sol\\\";\\n\\n/**\\n * @dev This contract implements an upgradeable proxy. It is upgradeable because calls are delegated to an\\n * implementation address that can be changed. This address is stored in storage in the location specified by\\n * https://eips.ethereum.org/EIPS/eip-1967[EIP1967], so that it doesn't conflict with the storage layout of the\\n * implementation behind the proxy.\\n */\\ncontract ERC1967Proxy is Proxy, ERC1967Upgrade {\\n /**\\n * @dev Initializes the upgradeable proxy with an initial implementation specified by `_logic`.\\n *\\n * If `_data` is nonempty, it's used as data in a delegate call to `_logic`. This will typically be an encoded\\n * function call, and allows initializing the storage of the proxy like a Solidity constructor.\\n */\\n constructor(address _logic, bytes memory _data) payable {\\n _upgradeToAndCall(_logic, _data, false);\\n }\\n\\n /**\\n * @dev Returns the current implementation address.\\n */\\n function _implementation() internal view virtual override returns (address impl) {\\n return ERC1967Upgrade._getImplementation();\\n }\\n}\\n\",\"keccak256\":\"0xa2b22da3032e50b55f95ec1d13336102d675f341167aa76db571ef7f8bb7975d\",\"license\":\"MIT\"},\"@openzeppelin/contracts/proxy/ERC1967/ERC1967Upgrade.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.5.0) (proxy/ERC1967/ERC1967Upgrade.sol)\\n\\npragma solidity ^0.8.2;\\n\\nimport \\\"../beacon/IBeacon.sol\\\";\\nimport \\\"../../interfaces/draft-IERC1822.sol\\\";\\nimport \\\"../../utils/Address.sol\\\";\\nimport \\\"../../utils/StorageSlot.sol\\\";\\n\\n/**\\n * @dev This abstract contract provides getters and event emitting update functions for\\n * https://eips.ethereum.org/EIPS/eip-1967[EIP1967] slots.\\n *\\n * _Available since v4.1._\\n *\\n * @custom:oz-upgrades-unsafe-allow delegatecall\\n */\\nabstract contract ERC1967Upgrade {\\n // This is the keccak-256 hash of \\\"eip1967.proxy.rollback\\\" subtracted by 1\\n bytes32 private constant _ROLLBACK_SLOT = 0x4910fdfa16fed3260ed0e7147f7cc6da11a60208b5b9406d12a635614ffd9143;\\n\\n /**\\n * @dev Storage slot with the address of the current implementation.\\n * This is the keccak-256 hash of \\\"eip1967.proxy.implementation\\\" subtracted by 1, and is\\n * validated in the constructor.\\n */\\n bytes32 internal constant _IMPLEMENTATION_SLOT = 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc;\\n\\n /**\\n * @dev Emitted when the implementation is upgraded.\\n */\\n event Upgraded(address indexed implementation);\\n\\n /**\\n * @dev Returns the current implementation address.\\n */\\n function _getImplementation() internal view returns (address) {\\n return StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value;\\n }\\n\\n /**\\n * @dev Stores a new address in the EIP1967 implementation slot.\\n */\\n function _setImplementation(address newImplementation) private {\\n require(Address.isContract(newImplementation), \\\"ERC1967: new implementation is not a contract\\\");\\n StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value = newImplementation;\\n }\\n\\n /**\\n * @dev Perform implementation upgrade\\n *\\n * Emits an {Upgraded} event.\\n */\\n function _upgradeTo(address newImplementation) internal {\\n _setImplementation(newImplementation);\\n emit Upgraded(newImplementation);\\n }\\n\\n /**\\n * @dev Perform implementation upgrade with additional setup call.\\n *\\n * Emits an {Upgraded} event.\\n */\\n function _upgradeToAndCall(\\n address newImplementation,\\n bytes memory data,\\n bool forceCall\\n ) internal {\\n _upgradeTo(newImplementation);\\n if (data.length > 0 || forceCall) {\\n Address.functionDelegateCall(newImplementation, data);\\n }\\n }\\n\\n /**\\n * @dev Perform implementation upgrade with security checks for UUPS proxies, and additional setup call.\\n *\\n * Emits an {Upgraded} event.\\n */\\n function _upgradeToAndCallUUPS(\\n address newImplementation,\\n bytes memory data,\\n bool forceCall\\n ) internal {\\n // Upgrades from old implementations will perform a rollback test. This test requires the new\\n // implementation to upgrade back to the old, non-ERC1822 compliant, implementation. Removing\\n // this special case will break upgrade paths from old UUPS implementation to new ones.\\n if (StorageSlot.getBooleanSlot(_ROLLBACK_SLOT).value) {\\n _setImplementation(newImplementation);\\n } else {\\n try IERC1822Proxiable(newImplementation).proxiableUUID() returns (bytes32 slot) {\\n require(slot == _IMPLEMENTATION_SLOT, \\\"ERC1967Upgrade: unsupported proxiableUUID\\\");\\n } catch {\\n revert(\\\"ERC1967Upgrade: new implementation is not UUPS\\\");\\n }\\n _upgradeToAndCall(newImplementation, data, forceCall);\\n }\\n }\\n\\n /**\\n * @dev Storage slot with the admin of the contract.\\n * This is the keccak-256 hash of \\\"eip1967.proxy.admin\\\" subtracted by 1, and is\\n * validated in the constructor.\\n */\\n bytes32 internal constant _ADMIN_SLOT = 0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103;\\n\\n /**\\n * @dev Emitted when the admin account has changed.\\n */\\n event AdminChanged(address previousAdmin, address newAdmin);\\n\\n /**\\n * @dev Returns the current admin.\\n */\\n function _getAdmin() internal view returns (address) {\\n return StorageSlot.getAddressSlot(_ADMIN_SLOT).value;\\n }\\n\\n /**\\n * @dev Stores a new address in the EIP1967 admin slot.\\n */\\n function _setAdmin(address newAdmin) private {\\n require(newAdmin != address(0), \\\"ERC1967: new admin is the zero address\\\");\\n StorageSlot.getAddressSlot(_ADMIN_SLOT).value = newAdmin;\\n }\\n\\n /**\\n * @dev Changes the admin of the proxy.\\n *\\n * Emits an {AdminChanged} event.\\n */\\n function _changeAdmin(address newAdmin) internal {\\n emit AdminChanged(_getAdmin(), newAdmin);\\n _setAdmin(newAdmin);\\n }\\n\\n /**\\n * @dev The storage slot of the UpgradeableBeacon contract which defines the implementation for this proxy.\\n * This is bytes32(uint256(keccak256('eip1967.proxy.beacon')) - 1)) and is validated in the constructor.\\n */\\n bytes32 internal constant _BEACON_SLOT = 0xa3f0ad74e5423aebfd80d3ef4346578335a9a72aeaee59ff6cb3582b35133d50;\\n\\n /**\\n * @dev Emitted when the beacon is upgraded.\\n */\\n event BeaconUpgraded(address indexed beacon);\\n\\n /**\\n * @dev Returns the current beacon.\\n */\\n function _getBeacon() internal view returns (address) {\\n return StorageSlot.getAddressSlot(_BEACON_SLOT).value;\\n }\\n\\n /**\\n * @dev Stores a new beacon in the EIP1967 beacon slot.\\n */\\n function _setBeacon(address newBeacon) private {\\n require(Address.isContract(newBeacon), \\\"ERC1967: new beacon is not a contract\\\");\\n require(\\n Address.isContract(IBeacon(newBeacon).implementation()),\\n \\\"ERC1967: beacon implementation is not a contract\\\"\\n );\\n StorageSlot.getAddressSlot(_BEACON_SLOT).value = newBeacon;\\n }\\n\\n /**\\n * @dev Perform beacon upgrade with additional setup call. Note: This upgrades the address of the beacon, it does\\n * not upgrade the implementation contained in the beacon (see {UpgradeableBeacon-_setImplementation} for that).\\n *\\n * Emits a {BeaconUpgraded} event.\\n */\\n function _upgradeBeaconToAndCall(\\n address newBeacon,\\n bytes memory data,\\n bool forceCall\\n ) internal {\\n _setBeacon(newBeacon);\\n emit BeaconUpgraded(newBeacon);\\n if (data.length > 0 || forceCall) {\\n Address.functionDelegateCall(IBeacon(newBeacon).implementation(), data);\\n }\\n }\\n}\\n\",\"keccak256\":\"0xabf3f59bc0e5423eae45e459dbe92e7052c6983628d39008590edc852a62f94a\",\"license\":\"MIT\"},\"@openzeppelin/contracts/proxy/Proxy.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.6.0) (proxy/Proxy.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev This abstract contract provides a fallback function that delegates all calls to another contract using the EVM\\n * instruction `delegatecall`. We refer to the second contract as the _implementation_ behind the proxy, and it has to\\n * be specified by overriding the virtual {_implementation} function.\\n *\\n * Additionally, delegation to the implementation can be triggered manually through the {_fallback} function, or to a\\n * different contract through the {_delegate} function.\\n *\\n * The success and return data of the delegated call will be returned back to the caller of the proxy.\\n */\\nabstract contract Proxy {\\n /**\\n * @dev Delegates the current call to `implementation`.\\n *\\n * This function does not return to its internal call site, it will return directly to the external caller.\\n */\\n function _delegate(address implementation) internal virtual {\\n assembly {\\n // Copy msg.data. We take full control of memory in this inline assembly\\n // block because it will not return to Solidity code. We overwrite the\\n // Solidity scratch pad at memory position 0.\\n calldatacopy(0, 0, calldatasize())\\n\\n // Call the implementation.\\n // out and outsize are 0 because we don't know the size yet.\\n let result := delegatecall(gas(), implementation, 0, calldatasize(), 0, 0)\\n\\n // Copy the returned data.\\n returndatacopy(0, 0, returndatasize())\\n\\n switch result\\n // delegatecall returns 0 on error.\\n case 0 {\\n revert(0, returndatasize())\\n }\\n default {\\n return(0, returndatasize())\\n }\\n }\\n }\\n\\n /**\\n * @dev This is a virtual function that should be overridden so it returns the address to which the fallback function\\n * and {_fallback} should delegate.\\n */\\n function _implementation() internal view virtual returns (address);\\n\\n /**\\n * @dev Delegates the current call to the address returned by `_implementation()`.\\n *\\n * This function does not return to its internal call site, it will return directly to the external caller.\\n */\\n function _fallback() internal virtual {\\n _beforeFallback();\\n _delegate(_implementation());\\n }\\n\\n /**\\n * @dev Fallback function that delegates calls to the address returned by `_implementation()`. Will run if no other\\n * function in the contract matches the call data.\\n */\\n fallback() external payable virtual {\\n _fallback();\\n }\\n\\n /**\\n * @dev Fallback function that delegates calls to the address returned by `_implementation()`. Will run if call data\\n * is empty.\\n */\\n receive() external payable virtual {\\n _fallback();\\n }\\n\\n /**\\n * @dev Hook that is called before falling back to the implementation. Can happen as part of a manual `_fallback`\\n * call, or as part of the Solidity `fallback` or `receive` functions.\\n *\\n * If overridden should call `super._beforeFallback()`.\\n */\\n function _beforeFallback() internal virtual {}\\n}\\n\",\"keccak256\":\"0xc130fe33f1b2132158531a87734153293f6d07bc263ff4ac90e85da9c82c0e27\",\"license\":\"MIT\"},\"@openzeppelin/contracts/proxy/beacon/IBeacon.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (proxy/beacon/IBeacon.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev This is the interface that {BeaconProxy} expects of its beacon.\\n */\\ninterface IBeacon {\\n /**\\n * @dev Must return an address that can be used as a delegate call target.\\n *\\n * {BeaconProxy} will check that this address is a contract.\\n */\\n function implementation() external view returns (address);\\n}\\n\",\"keccak256\":\"0xd50a3421ac379ccb1be435fa646d66a65c986b4924f0849839f08692f39dde61\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/Address.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.7.0) (utils/Address.sol)\\n\\npragma solidity ^0.8.1;\\n\\n/**\\n * @dev Collection of functions related to the address type\\n */\\nlibrary Address {\\n /**\\n * @dev Returns true if `account` is a contract.\\n *\\n * [IMPORTANT]\\n * ====\\n * It is unsafe to assume that an address for which this function returns\\n * false is an externally-owned account (EOA) and not a contract.\\n *\\n * Among others, `isContract` will return false for the following\\n * types of addresses:\\n *\\n * - an externally-owned account\\n * - a contract in construction\\n * - an address where a contract will be created\\n * - an address where a contract lived, but was destroyed\\n * ====\\n *\\n * [IMPORTANT]\\n * ====\\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\\n *\\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\\n * constructor.\\n * ====\\n */\\n function isContract(address account) internal view returns (bool) {\\n // This method relies on extcodesize/address.code.length, which returns 0\\n // for contracts in construction, since the code is only stored at the end\\n // of the constructor execution.\\n\\n return account.code.length > 0;\\n }\\n\\n /**\\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\\n * `recipient`, forwarding all available gas and reverting on errors.\\n *\\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\\n * imposed by `transfer`, making them unable to receive funds via\\n * `transfer`. {sendValue} removes this limitation.\\n *\\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\\n *\\n * IMPORTANT: because control is transferred to `recipient`, care must be\\n * taken to not create reentrancy vulnerabilities. Consider using\\n * {ReentrancyGuard} or the\\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\\n */\\n function sendValue(address payable recipient, uint256 amount) internal {\\n require(address(this).balance >= amount, \\\"Address: insufficient balance\\\");\\n\\n (bool success, ) = recipient.call{value: amount}(\\\"\\\");\\n require(success, \\\"Address: unable to send value, recipient may have reverted\\\");\\n }\\n\\n /**\\n * @dev Performs a Solidity function call using a low level `call`. A\\n * plain `call` is an unsafe replacement for a function call: use this\\n * function instead.\\n *\\n * If `target` reverts with a revert reason, it is bubbled up by this\\n * function (like regular Solidity function calls).\\n *\\n * Returns the raw returned data. To convert to the expected return value,\\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\\n *\\n * Requirements:\\n *\\n * - `target` must be a contract.\\n * - calling `target` with `data` must not revert.\\n *\\n * _Available since v3.1._\\n */\\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\\n return functionCall(target, data, \\\"Address: low-level call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\\n * `errorMessage` as a fallback revert reason when `target` reverts.\\n *\\n * _Available since v3.1._\\n */\\n function functionCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n return functionCallWithValue(target, data, 0, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but also transferring `value` wei to `target`.\\n *\\n * Requirements:\\n *\\n * - the calling contract must have an ETH balance of at least `value`.\\n * - the called Solidity function must be `payable`.\\n *\\n * _Available since v3.1._\\n */\\n function functionCallWithValue(\\n address target,\\n bytes memory data,\\n uint256 value\\n ) internal returns (bytes memory) {\\n return functionCallWithValue(target, data, value, \\\"Address: low-level call with value failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\\n * with `errorMessage` as a fallback revert reason when `target` reverts.\\n *\\n * _Available since v3.1._\\n */\\n function functionCallWithValue(\\n address target,\\n bytes memory data,\\n uint256 value,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n require(address(this).balance >= value, \\\"Address: insufficient balance for call\\\");\\n require(isContract(target), \\\"Address: call to non-contract\\\");\\n\\n (bool success, bytes memory returndata) = target.call{value: value}(data);\\n return verifyCallResult(success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but performing a static call.\\n *\\n * _Available since v3.3._\\n */\\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\\n return functionStaticCall(target, data, \\\"Address: low-level static call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\\n * but performing a static call.\\n *\\n * _Available since v3.3._\\n */\\n function functionStaticCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal view returns (bytes memory) {\\n require(isContract(target), \\\"Address: static call to non-contract\\\");\\n\\n (bool success, bytes memory returndata) = target.staticcall(data);\\n return verifyCallResult(success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but performing a delegate call.\\n *\\n * _Available since v3.4._\\n */\\n function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {\\n return functionDelegateCall(target, data, \\\"Address: low-level delegate call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\\n * but performing a delegate call.\\n *\\n * _Available since v3.4._\\n */\\n function functionDelegateCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n require(isContract(target), \\\"Address: delegate call to non-contract\\\");\\n\\n (bool success, bytes memory returndata) = target.delegatecall(data);\\n return verifyCallResult(success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the\\n * revert reason using the provided one.\\n *\\n * _Available since v4.3._\\n */\\n function verifyCallResult(\\n bool success,\\n bytes memory returndata,\\n string memory errorMessage\\n ) internal pure returns (bytes memory) {\\n if (success) {\\n return returndata;\\n } else {\\n // Look for revert reason and bubble it up if present\\n if (returndata.length > 0) {\\n // The easiest way to bubble the revert reason is using memory via assembly\\n /// @solidity memory-safe-assembly\\n assembly {\\n let returndata_size := mload(returndata)\\n revert(add(32, returndata), returndata_size)\\n }\\n } else {\\n revert(errorMessage);\\n }\\n }\\n }\\n}\\n\",\"keccak256\":\"0xd6153ce99bcdcce22b124f755e72553295be6abcd63804cfdffceb188b8bef10\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/StorageSlot.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.7.0) (utils/StorageSlot.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Library for reading and writing primitive types to specific storage slots.\\n *\\n * Storage slots are often used to avoid storage conflict when dealing with upgradeable contracts.\\n * This library helps with reading and writing to such slots without the need for inline assembly.\\n *\\n * The functions in this library return Slot structs that contain a `value` member that can be used to read or write.\\n *\\n * Example usage to set ERC1967 implementation slot:\\n * ```\\n * contract ERC1967 {\\n * bytes32 internal constant _IMPLEMENTATION_SLOT = 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc;\\n *\\n * function _getImplementation() internal view returns (address) {\\n * return StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value;\\n * }\\n *\\n * function _setImplementation(address newImplementation) internal {\\n * require(Address.isContract(newImplementation), \\\"ERC1967: new implementation is not a contract\\\");\\n * StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value = newImplementation;\\n * }\\n * }\\n * ```\\n *\\n * _Available since v4.1 for `address`, `bool`, `bytes32`, and `uint256`._\\n */\\nlibrary StorageSlot {\\n struct AddressSlot {\\n address value;\\n }\\n\\n struct BooleanSlot {\\n bool value;\\n }\\n\\n struct Bytes32Slot {\\n bytes32 value;\\n }\\n\\n struct Uint256Slot {\\n uint256 value;\\n }\\n\\n /**\\n * @dev Returns an `AddressSlot` with member `value` located at `slot`.\\n */\\n function getAddressSlot(bytes32 slot) internal pure returns (AddressSlot storage r) {\\n /// @solidity memory-safe-assembly\\n assembly {\\n r.slot := slot\\n }\\n }\\n\\n /**\\n * @dev Returns an `BooleanSlot` with member `value` located at `slot`.\\n */\\n function getBooleanSlot(bytes32 slot) internal pure returns (BooleanSlot storage r) {\\n /// @solidity memory-safe-assembly\\n assembly {\\n r.slot := slot\\n }\\n }\\n\\n /**\\n * @dev Returns an `Bytes32Slot` with member `value` located at `slot`.\\n */\\n function getBytes32Slot(bytes32 slot) internal pure returns (Bytes32Slot storage r) {\\n /// @solidity memory-safe-assembly\\n assembly {\\n r.slot := slot\\n }\\n }\\n\\n /**\\n * @dev Returns an `Uint256Slot` with member `value` located at `slot`.\\n */\\n function getUint256Slot(bytes32 slot) internal pure returns (Uint256Slot storage r) {\\n /// @solidity memory-safe-assembly\\n assembly {\\n r.slot := slot\\n }\\n }\\n}\\n\",\"keccak256\":\"0xd5c50c54bf02740ebd122ff06832546cb5fa84486d52695a9ccfd11666e0c81d\",\"license\":\"MIT\"},\"contracts/external/TransparentUpgradeableProxy.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-3.0\\n\\npragma solidity ^0.8.12;\\n\\nimport \\\"@openzeppelin/contracts/proxy/ERC1967/ERC1967Proxy.sol\\\";\\n\\n/**\\n * @dev This contract implements a proxy that is upgradeable by an admin. It is fully forked from OpenZeppelin\\n * `TransparentUpgradeableProxy`\\n *\\n * To avoid https://medium.com/nomic-labs-blog/malicious-backdoors-in-ethereum-proxies-62629adf3357[proxy selector\\n * clashing], which can potentially be used in an attack, this contract uses the\\n * https://blog.openzeppelin.com/the-transparent-proxy-pattern/[transparent proxy pattern]. This pattern implies two\\n * things that go hand in hand:\\n *\\n * 1. If any account other than the admin calls the proxy, the call will be forwarded to the implementation, even if\\n * that call matches one of the admin functions exposed by the proxy itself.\\n * 2. If the admin calls the proxy, it can access the admin functions, but its calls will never be forwarded to the\\n * implementation. If the admin tries to call a function on the implementation it will fail with an error that says\\n * \\\"admin cannot fallback to proxy target\\\".\\n *\\n * These properties mean that the admin account can only be used for admin actions like upgrading the proxy or changing\\n * the admin, so it's best if it's a dedicated account that is not used for anything else. This will avoid headaches due\\n * to sudden errors when trying to call a function from the proxy implementation.\\n *\\n * Our recommendation is for the dedicated account to be an instance of the {ProxyAdmin} contract. If set up this way,\\n * you should think of the `ProxyAdmin` instance as the real administrative interface of your proxy.\\n */\\ncontract TransparentUpgradeableProxy is ERC1967Proxy {\\n /**\\n * @dev Initializes an upgradeable proxy managed by `_admin`, backed by the implementation at `_logic`, and\\n * optionally initialized with `_data` as explained in {ERC1967Proxy-constructor}.\\n */\\n constructor(address _logic, address admin_, bytes memory _data) payable ERC1967Proxy(_logic, _data) {\\n assert(_ADMIN_SLOT == bytes32(uint256(keccak256(\\\"eip1967.proxy.admin\\\")) - 1));\\n _changeAdmin(admin_);\\n }\\n\\n /**\\n * @dev Modifier used internally that will delegate the call to the implementation unless the sender is the admin.\\n */\\n modifier ifAdmin() {\\n if (msg.sender == _getAdmin()) {\\n _;\\n } else {\\n _fallback();\\n }\\n }\\n\\n /**\\n * @dev Returns the current admin.\\n *\\n * NOTE: Only the admin can call this function. See {ProxyAdmin-getProxyAdmin}.\\n *\\n * TIP: To get this value clients can read directly from the storage slot shown below (specified by EIP1967) using the\\n * https://eth.wiki/json-rpc/API#eth_getstorageat[`eth_getStorageAt`] RPC call.\\n * `0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103`\\n */\\n function admin() external ifAdmin returns (address admin_) {\\n admin_ = _getAdmin();\\n }\\n\\n /**\\n * @dev Returns the current implementation.\\n *\\n * NOTE: Only the admin can call this function. See {ProxyAdmin-getProxyImplementation}.\\n *\\n * TIP: To get this value clients can read directly from the storage slot shown below (specified by EIP1967) using the\\n * https://eth.wiki/json-rpc/API#eth_getstorageat[`eth_getStorageAt`] RPC call.\\n * `0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc`\\n */\\n function implementation() external ifAdmin returns (address implementation_) {\\n implementation_ = _implementation();\\n }\\n\\n /**\\n * @dev Changes the admin of the proxy.\\n *\\n * Emits an {AdminChanged} event.\\n *\\n * NOTE: Only the admin can call this function. See {ProxyAdmin-changeProxyAdmin}.\\n */\\n function changeAdmin(address newAdmin) external virtual ifAdmin {\\n _changeAdmin(newAdmin);\\n }\\n\\n /**\\n * @dev Upgrade the implementation of the proxy.\\n *\\n * NOTE: Only the admin can call this function. See {ProxyAdmin-upgrade}.\\n */\\n function upgradeTo(address newImplementation) external ifAdmin {\\n _upgradeToAndCall(newImplementation, bytes(\\\"\\\"), false);\\n }\\n\\n /**\\n * @dev Upgrade the implementation of the proxy, and then call a function from the new implementation as specified\\n * by `data`, which should be an encoded function call. This is useful to initialize new storage variables in the\\n * proxied contract.\\n *\\n * NOTE: Only the admin can call this function. See {ProxyAdmin-upgradeAndCall}.\\n */\\n function upgradeToAndCall(address newImplementation, bytes calldata data) external payable ifAdmin {\\n _upgradeToAndCall(newImplementation, data, true);\\n }\\n\\n /**\\n * @dev Returns the current admin.\\n */\\n function _admin() internal view virtual returns (address) {\\n return _getAdmin();\\n }\\n\\n /**\\n * @dev Makes sure the admin cannot access the fallback function. See {Proxy-_beforeFallback}.\\n */\\n function _beforeFallback() internal virtual override {\\n require(msg.sender != _getAdmin(), \\\"TransparentUpgradeableProxy: admin cannot fallback to proxy target\\\");\\n super._beforeFallback();\\n }\\n}\\n\",\"keccak256\":\"0x93a67a0f612ea3ff2a76315e138a6a88267270a1379d3cc7be52845fbbe611e2\",\"license\":\"GPL-3.0\"}},\"version\":1}", + "bytecode": "0x6080604052604051620010bb380380620010bb8339810160408190526200002691620004d8565b828162000036828260006200009a565b5062000066905060017fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6104620005b8565b6000805160206200107483398151915214620000865762000086620005da565b6200009182620000d7565b50505062000643565b620000a58362000132565b600082511180620000b35750805b15620000d257620000d083836200017460201b6200028c1760201c565b505b505050565b7f7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f62000102620001a5565b604080516001600160a01b03928316815291841660208301520160405180910390a16200012f81620001de565b50565b6200013d8162000293565b6040516001600160a01b038216907fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b90600090a250565b60606200019c8383604051806060016040528060278152602001620010946027913962000347565b90505b92915050565b6000620001cf6000805160206200107483398151915260001b6200042f60201b6200022e1760201c565b546001600160a01b0316919050565b6001600160a01b038116620002495760405162461bcd60e51b815260206004820152602660248201527f455243313936373a206e65772061646d696e20697320746865207a65726f206160448201526564647265737360d01b60648201526084015b60405180910390fd5b80620002726000805160206200107483398151915260001b6200042f60201b6200022e1760201c565b80546001600160a01b0319166001600160a01b039290921691909117905550565b620002a9816200043260201b620002b81760201c565b6200030d5760405162461bcd60e51b815260206004820152602d60248201527f455243313936373a206e657720696d706c656d656e746174696f6e206973206e60448201526c1bdd08184818dbdb9d1c9858dd609a1b606482015260840162000240565b80620002727f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc60001b6200042f60201b6200022e1760201c565b60606001600160a01b0384163b620003b15760405162461bcd60e51b815260206004820152602660248201527f416464726573733a2064656c65676174652063616c6c20746f206e6f6e2d636f6044820152651b9d1c9858dd60d21b606482015260840162000240565b600080856001600160a01b031685604051620003ce9190620005f0565b600060405180830381855af49150503d80600081146200040b576040519150601f19603f3d011682016040523d82523d6000602084013e62000410565b606091505b5090925090506200042382828662000441565b925050505b9392505050565b90565b6001600160a01b03163b151590565b606083156200045257508162000428565b825115620004635782518084602001fd5b8160405162461bcd60e51b81526004016200024091906200060e565b80516001600160a01b03811681146200049757600080fd5b919050565b634e487b7160e01b600052604160045260246000fd5b60005b83811015620004cf578181015183820152602001620004b5565b50506000910152565b600080600060608486031215620004ee57600080fd5b620004f9846200047f565b925062000509602085016200047f565b60408501519092506001600160401b03808211156200052757600080fd5b818601915086601f8301126200053c57600080fd5b8151818111156200055157620005516200049c565b604051601f8201601f19908116603f011681019083821181831017156200057c576200057c6200049c565b816040528281528960208487010111156200059657600080fd5b620005a9836020830160208801620004b2565b80955050505050509250925092565b818103818111156200019f57634e487b7160e01b600052601160045260246000fd5b634e487b7160e01b600052600160045260246000fd5b6000825162000604818460208701620004b2565b9190910192915050565b60208152600082518060208401526200062f816040850160208701620004b2565b601f01601f19169190910160400192915050565b610a2180620006536000396000f3fe60806040526004361061005e5760003560e01c80635c60da1b116100435780635c60da1b146100a85780638f283970146100e6578063f851a440146101065761006d565b80633659cfe6146100755780634f1ef286146100955761006d565b3661006d5761006b61011b565b005b61006b61011b565b34801561008157600080fd5b5061006b610090366004610895565b610135565b61006b6100a33660046108b0565b61017f565b3480156100b457600080fd5b506100bd6101f3565b60405173ffffffffffffffffffffffffffffffffffffffff909116815260200160405180910390f35b3480156100f257600080fd5b5061006b610101366004610895565b610231565b34801561011257600080fd5b506100bd61025e565b6101236102d4565b61013361012e6103ab565b6103b5565b565b61013d6103d9565b73ffffffffffffffffffffffffffffffffffffffff1633036101775761017481604051806020016040528060008152506000610419565b50565b61017461011b565b6101876103d9565b73ffffffffffffffffffffffffffffffffffffffff1633036101eb576101e68383838080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525060019250610419915050565b505050565b6101e661011b565b60006101fd6103d9565b73ffffffffffffffffffffffffffffffffffffffff163303610226576102216103ab565b905090565b61022e61011b565b90565b6102396103d9565b73ffffffffffffffffffffffffffffffffffffffff1633036101775761017481610444565b60006102686103d9565b73ffffffffffffffffffffffffffffffffffffffff163303610226576102216103d9565b60606102b183836040518060600160405280602781526020016109c5602791396104a5565b9392505050565b73ffffffffffffffffffffffffffffffffffffffff163b151590565b6102dc6103d9565b73ffffffffffffffffffffffffffffffffffffffff163303610133576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604260248201527f5472616e73706172656e745570677261646561626c6550726f78793a2061646d60448201527f696e2063616e6e6f742066616c6c6261636b20746f2070726f7879207461726760648201527f6574000000000000000000000000000000000000000000000000000000000000608482015260a4015b60405180910390fd5b60006102216105cd565b3660008037600080366000845af43d6000803e8080156103d4573d6000f35b3d6000fd5b60007fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035b5473ffffffffffffffffffffffffffffffffffffffff16919050565b610422836105f5565b60008251118061042f5750805b156101e65761043e838361028c565b50505050565b7f7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f61046d6103d9565b6040805173ffffffffffffffffffffffffffffffffffffffff928316815291841660208301520160405180910390a161017481610642565b606073ffffffffffffffffffffffffffffffffffffffff84163b61054b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f416464726573733a2064656c65676174652063616c6c20746f206e6f6e2d636f60448201527f6e7472616374000000000000000000000000000000000000000000000000000060648201526084016103a2565b6000808573ffffffffffffffffffffffffffffffffffffffff16856040516105739190610957565b600060405180830381855af49150503d80600081146105ae576040519150601f19603f3d011682016040523d82523d6000602084013e6105b3565b606091505b50915091506105c382828661074e565b9695505050505050565b60007f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc6103fd565b6105fe816107a1565b60405173ffffffffffffffffffffffffffffffffffffffff8216907fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b90600090a250565b73ffffffffffffffffffffffffffffffffffffffff81166106e5576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f455243313936373a206e65772061646d696e20697320746865207a65726f206160448201527f646472657373000000000000000000000000000000000000000000000000000060648201526084016103a2565b807fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035b80547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff9290921691909117905550565b6060831561075d5750816102b1565b82511561076d5782518084602001fd5b816040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016103a29190610973565b73ffffffffffffffffffffffffffffffffffffffff81163b610845576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602d60248201527f455243313936373a206e657720696d706c656d656e746174696f6e206973206e60448201527f6f74206120636f6e74726163740000000000000000000000000000000000000060648201526084016103a2565b807f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc610708565b803573ffffffffffffffffffffffffffffffffffffffff8116811461089057600080fd5b919050565b6000602082840312156108a757600080fd5b6102b18261086c565b6000806000604084860312156108c557600080fd5b6108ce8461086c565b9250602084013567ffffffffffffffff808211156108eb57600080fd5b818601915086601f8301126108ff57600080fd5b81358181111561090e57600080fd5b87602082850101111561092057600080fd5b6020830194508093505050509250925092565b60005b8381101561094e578181015183820152602001610936565b50506000910152565b60008251610969818460208701610933565b9190910192915050565b6020815260008251806020840152610992816040850160208701610933565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016919091016040019291505056fe416464726573733a206c6f772d6c6576656c2064656c65676174652063616c6c206661696c6564a2646970667358221220e96638b07fb1675d93a95c49e417bc8111448b23a59918698cdcd8fd488dd7cf64736f6c63430008110033b53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103416464726573733a206c6f772d6c6576656c2064656c65676174652063616c6c206661696c6564", + "deployedBytecode": "0x60806040526004361061005e5760003560e01c80635c60da1b116100435780635c60da1b146100a85780638f283970146100e6578063f851a440146101065761006d565b80633659cfe6146100755780634f1ef286146100955761006d565b3661006d5761006b61011b565b005b61006b61011b565b34801561008157600080fd5b5061006b610090366004610895565b610135565b61006b6100a33660046108b0565b61017f565b3480156100b457600080fd5b506100bd6101f3565b60405173ffffffffffffffffffffffffffffffffffffffff909116815260200160405180910390f35b3480156100f257600080fd5b5061006b610101366004610895565b610231565b34801561011257600080fd5b506100bd61025e565b6101236102d4565b61013361012e6103ab565b6103b5565b565b61013d6103d9565b73ffffffffffffffffffffffffffffffffffffffff1633036101775761017481604051806020016040528060008152506000610419565b50565b61017461011b565b6101876103d9565b73ffffffffffffffffffffffffffffffffffffffff1633036101eb576101e68383838080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525060019250610419915050565b505050565b6101e661011b565b60006101fd6103d9565b73ffffffffffffffffffffffffffffffffffffffff163303610226576102216103ab565b905090565b61022e61011b565b90565b6102396103d9565b73ffffffffffffffffffffffffffffffffffffffff1633036101775761017481610444565b60006102686103d9565b73ffffffffffffffffffffffffffffffffffffffff163303610226576102216103d9565b60606102b183836040518060600160405280602781526020016109c5602791396104a5565b9392505050565b73ffffffffffffffffffffffffffffffffffffffff163b151590565b6102dc6103d9565b73ffffffffffffffffffffffffffffffffffffffff163303610133576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604260248201527f5472616e73706172656e745570677261646561626c6550726f78793a2061646d60448201527f696e2063616e6e6f742066616c6c6261636b20746f2070726f7879207461726760648201527f6574000000000000000000000000000000000000000000000000000000000000608482015260a4015b60405180910390fd5b60006102216105cd565b3660008037600080366000845af43d6000803e8080156103d4573d6000f35b3d6000fd5b60007fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035b5473ffffffffffffffffffffffffffffffffffffffff16919050565b610422836105f5565b60008251118061042f5750805b156101e65761043e838361028c565b50505050565b7f7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f61046d6103d9565b6040805173ffffffffffffffffffffffffffffffffffffffff928316815291841660208301520160405180910390a161017481610642565b606073ffffffffffffffffffffffffffffffffffffffff84163b61054b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f416464726573733a2064656c65676174652063616c6c20746f206e6f6e2d636f60448201527f6e7472616374000000000000000000000000000000000000000000000000000060648201526084016103a2565b6000808573ffffffffffffffffffffffffffffffffffffffff16856040516105739190610957565b600060405180830381855af49150503d80600081146105ae576040519150601f19603f3d011682016040523d82523d6000602084013e6105b3565b606091505b50915091506105c382828661074e565b9695505050505050565b60007f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc6103fd565b6105fe816107a1565b60405173ffffffffffffffffffffffffffffffffffffffff8216907fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b90600090a250565b73ffffffffffffffffffffffffffffffffffffffff81166106e5576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f455243313936373a206e65772061646d696e20697320746865207a65726f206160448201527f646472657373000000000000000000000000000000000000000000000000000060648201526084016103a2565b807fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035b80547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff9290921691909117905550565b6060831561075d5750816102b1565b82511561076d5782518084602001fd5b816040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016103a29190610973565b73ffffffffffffffffffffffffffffffffffffffff81163b610845576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602d60248201527f455243313936373a206e657720696d706c656d656e746174696f6e206973206e60448201527f6f74206120636f6e74726163740000000000000000000000000000000000000060648201526084016103a2565b807f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc610708565b803573ffffffffffffffffffffffffffffffffffffffff8116811461089057600080fd5b919050565b6000602082840312156108a757600080fd5b6102b18261086c565b6000806000604084860312156108c557600080fd5b6108ce8461086c565b9250602084013567ffffffffffffffff808211156108eb57600080fd5b818601915086601f8301126108ff57600080fd5b81358181111561090e57600080fd5b87602082850101111561092057600080fd5b6020830194508093505050509250925092565b60005b8381101561094e578181015183820152602001610936565b50506000910152565b60008251610969818460208701610933565b9190910192915050565b6020815260008251806020840152610992816040850160208701610933565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016919091016040019291505056fe416464726573733a206c6f772d6c6576656c2064656c65676174652063616c6c206661696c6564a2646970667358221220e96638b07fb1675d93a95c49e417bc8111448b23a59918698cdcd8fd488dd7cf64736f6c63430008110033", + "devdoc": { + "details": "This contract implements a proxy that is upgradeable by an admin. It is fully forked from OpenZeppelin `TransparentUpgradeableProxy` To avoid https://medium.com/nomic-labs-blog/malicious-backdoors-in-ethereum-proxies-62629adf3357[proxy selector clashing], which can potentially be used in an attack, this contract uses the https://blog.openzeppelin.com/the-transparent-proxy-pattern/[transparent proxy pattern]. This pattern implies two things that go hand in hand: 1. If any account other than the admin calls the proxy, the call will be forwarded to the implementation, even if that call matches one of the admin functions exposed by the proxy itself. 2. If the admin calls the proxy, it can access the admin functions, but its calls will never be forwarded to the implementation. If the admin tries to call a function on the implementation it will fail with an error that says \"admin cannot fallback to proxy target\". These properties mean that the admin account can only be used for admin actions like upgrading the proxy or changing the admin, so it's best if it's a dedicated account that is not used for anything else. This will avoid headaches due to sudden errors when trying to call a function from the proxy implementation. Our recommendation is for the dedicated account to be an instance of the {ProxyAdmin} contract. If set up this way, you should think of the `ProxyAdmin` instance as the real administrative interface of your proxy.", + "kind": "dev", + "methods": { + "admin()": { + "details": "Returns the current admin. NOTE: Only the admin can call this function. See {ProxyAdmin-getProxyAdmin}. TIP: To get this value clients can read directly from the storage slot shown below (specified by EIP1967) using the https://eth.wiki/json-rpc/API#eth_getstorageat[`eth_getStorageAt`] RPC call. `0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103`" + }, + "changeAdmin(address)": { + "details": "Changes the admin of the proxy. Emits an {AdminChanged} event. NOTE: Only the admin can call this function. See {ProxyAdmin-changeProxyAdmin}." + }, + "constructor": { + "details": "Initializes an upgradeable proxy managed by `_admin`, backed by the implementation at `_logic`, and optionally initialized with `_data` as explained in {ERC1967Proxy-constructor}." + }, + "implementation()": { + "details": "Returns the current implementation. NOTE: Only the admin can call this function. See {ProxyAdmin-getProxyImplementation}. TIP: To get this value clients can read directly from the storage slot shown below (specified by EIP1967) using the https://eth.wiki/json-rpc/API#eth_getstorageat[`eth_getStorageAt`] RPC call. `0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc`" + }, + "upgradeTo(address)": { + "details": "Upgrade the implementation of the proxy. NOTE: Only the admin can call this function. See {ProxyAdmin-upgrade}." + }, + "upgradeToAndCall(address,bytes)": { + "details": "Upgrade the implementation of the proxy, and then call a function from the new implementation as specified by `data`, which should be an encoded function call. This is useful to initialize new storage variables in the proxied contract. NOTE: Only the admin can call this function. See {ProxyAdmin-upgradeAndCall}." + } + }, + "version": 1 + }, + "userdoc": { + "kind": "user", + "methods": {}, + "version": 1 + }, + "storageLayout": { + "storage": [], + "types": null + } +} \ No newline at end of file diff --git a/deployments/gnosis/aglaMerkl.json b/deployments/gnosis/aglaMerkl.json new file mode 100644 index 00000000..30837edb --- /dev/null +++ b/deployments/gnosis/aglaMerkl.json @@ -0,0 +1,675 @@ +{ + "address": "0x65A1DfB54CDec9011688b1818A27A8C687e6B1ed", + "abi": [ + { + "inputs": [ + { + "internalType": "string", + "name": "name_", + "type": "string" + }, + { + "internalType": "string", + "name": "symbol_", + "type": "string" + }, + { + "internalType": "uint8", + "name": "decimal_", + "type": "uint8" + } + ], + "stateMutability": "nonpayable", + "type": "constructor" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "owner", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "spender", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "value", + "type": "uint256" + } + ], + "name": "Approval", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "_from", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "_burner", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "_amount", + "type": "uint256" + } + ], + "name": "Burning", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "_to", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "_minter", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "_amount", + "type": "uint256" + } + ], + "name": "Minting", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "from", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "value", + "type": "uint256" + } + ], + "name": "Transfer", + "type": "event" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "minter", + "type": "address" + } + ], + "name": "addMinter", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "owner", + "type": "address" + }, + { + "internalType": "address", + "name": "spender", + "type": "address" + } + ], + "name": "allowance", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "spender", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "approve", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "balanceOf", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "account", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "burn", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + }, + { + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "burnSelf", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "decimals", + "outputs": [ + { + "internalType": "uint8", + "name": "", + "type": "uint8" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "spender", + "type": "address" + }, + { + "internalType": "uint256", + "name": "subtractedValue", + "type": "uint256" + } + ], + "name": "decreaseAllowance", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "spender", + "type": "address" + }, + { + "internalType": "uint256", + "name": "addedValue", + "type": "uint256" + } + ], + "name": "increaseAllowance", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "account", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "mint", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "minters", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "name", + "outputs": [ + { + "internalType": "string", + "name": "", + "type": "string" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "minter", + "type": "address" + } + ], + "name": "removeMinter", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "from", + "type": "address" + }, + { + "internalType": "address", + "name": "to", + "type": "address" + } + ], + "name": "setAllowance", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_treasury", + "type": "address" + } + ], + "name": "setTreasury", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "symbol", + "outputs": [ + { + "internalType": "string", + "name": "", + "type": "string" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "totalSupply", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "transfer", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "from", + "type": "address" + }, + { + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "transferFrom", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "treasury", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + } + ], + "transactionHash": "0x93032522b378e15200688f1f57b6e5d1fe689e73fd976f349295a881da2ddc05", + "receipt": { + "to": null, + "from": "0xfdA462548Ce04282f4B6D6619823a7C64Fdc0185", + "contractAddress": "0x65A1DfB54CDec9011688b1818A27A8C687e6B1ed", + "transactionIndex": 15, + "gasUsed": "1137333", + "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "blockHash": "0x16ebc47748ecefd5b65d531efe2a652e06a0ab47fe2e913df3a00b02f981b8d8", + "transactionHash": "0x93032522b378e15200688f1f57b6e5d1fe689e73fd976f349295a881da2ddc05", + "logs": [], + "blockNumber": 31747167, + "cumulativeGasUsed": "12391865", + "status": 1, + "byzantium": true + }, + "args": [ + "aglaMerkl", + "aglaMerkl", + 8 + ], + "numDeployments": 1, + "solcInputHash": "c1b0a0ed63155d980ec50a220c46f41c", + "metadata": "{\"compiler\":{\"version\":\"0.8.17+commit.8df45f5f\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[{\"internalType\":\"string\",\"name\":\"name_\",\"type\":\"string\"},{\"internalType\":\"string\",\"name\":\"symbol_\",\"type\":\"string\"},{\"internalType\":\"uint8\",\"name\":\"decimal_\",\"type\":\"uint8\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"spender\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"}],\"name\":\"Approval\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"_from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"_burner\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"_amount\",\"type\":\"uint256\"}],\"name\":\"Burning\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"_to\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"_minter\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"_amount\",\"type\":\"uint256\"}],\"name\":\"Minting\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"}],\"name\":\"Transfer\",\"type\":\"event\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"minter\",\"type\":\"address\"}],\"name\":\"addMinter\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"spender\",\"type\":\"address\"}],\"name\":\"allowance\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"spender\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"approve\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"}],\"name\":\"balanceOf\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"burn\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"}],\"name\":\"burnSelf\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"decimals\",\"outputs\":[{\"internalType\":\"uint8\",\"name\":\"\",\"type\":\"uint8\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"spender\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"subtractedValue\",\"type\":\"uint256\"}],\"name\":\"decreaseAllowance\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"spender\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"addedValue\",\"type\":\"uint256\"}],\"name\":\"increaseAllowance\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"mint\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"minters\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"name\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"minter\",\"type\":\"address\"}],\"name\":\"removeMinter\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"setAllowance\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_treasury\",\"type\":\"address\"}],\"name\":\"setTreasury\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"symbol\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"totalSupply\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"transfer\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"transferFrom\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"treasury\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"}],\"devdoc\":{\"kind\":\"dev\",\"methods\":{\"allowance(address,address)\":{\"details\":\"See {IERC20-allowance}.\"},\"approve(address,uint256)\":{\"details\":\"See {IERC20-approve}. NOTE: If `amount` is the maximum `uint256`, the allowance is not updated on `transferFrom`. This is semantically equivalent to an infinite approval. Requirements: - `spender` cannot be the zero address.\"},\"balanceOf(address)\":{\"details\":\"See {IERC20-balanceOf}.\"},\"decimals()\":{\"details\":\"Returns the number of decimals used to get its user representation. For example, if `decimals` equals `2`, a balance of `505` tokens should be displayed to a user as `5.05` (`505 / 10 ** 2`). Tokens usually opt for a value of 18, imitating the relationship between Ether and Wei. This is the value {ERC20} uses, unless this function is overridden; NOTE: This information is only used for _display_ purposes: it in no way affects any of the arithmetic of the contract, including {IERC20-balanceOf} and {IERC20-transfer}.\"},\"decreaseAllowance(address,uint256)\":{\"details\":\"Atomically decreases the allowance granted to `spender` by the caller. This is an alternative to {approve} that can be used as a mitigation for problems described in {IERC20-approve}. Emits an {Approval} event indicating the updated allowance. Requirements: - `spender` cannot be the zero address. - `spender` must have allowance for the caller of at least `subtractedValue`.\"},\"increaseAllowance(address,uint256)\":{\"details\":\"Atomically increases the allowance granted to `spender` by the caller. This is an alternative to {approve} that can be used as a mitigation for problems described in {IERC20-approve}. Emits an {Approval} event indicating the updated allowance. Requirements: - `spender` cannot be the zero address.\"},\"name()\":{\"details\":\"Returns the name of the token.\"},\"symbol()\":{\"details\":\"Returns the symbol of the token, usually a shorter version of the name.\"},\"totalSupply()\":{\"details\":\"See {IERC20-totalSupply}.\"},\"transfer(address,uint256)\":{\"details\":\"See {IERC20-transfer}. Requirements: - `to` cannot be the zero address. - the caller must have a balance of at least `amount`.\"},\"transferFrom(address,address,uint256)\":{\"details\":\"See {IERC20-transferFrom}. Emits an {Approval} event indicating the updated allowance. This is not required by the EIP. See the note at the beginning of {ERC20}. NOTE: Does not update the allowance if the current allowance is the maximum `uint256`. Requirements: - `from` and `to` cannot be the zero address. - `from` must have a balance of at least `amount`. - the caller must have allowance for ``from``'s tokens of at least `amount`.\"}},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/mock/MockToken.sol\":\"MockToken\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":1000000},\"remappings\":[]},\"sources\":{\"@openzeppelin/contracts/token/ERC20/ERC20.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.7.0) (token/ERC20/ERC20.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"./IERC20.sol\\\";\\nimport \\\"./extensions/IERC20Metadata.sol\\\";\\nimport \\\"../../utils/Context.sol\\\";\\n\\n/**\\n * @dev Implementation of the {IERC20} interface.\\n *\\n * This implementation is agnostic to the way tokens are created. This means\\n * that a supply mechanism has to be added in a derived contract using {_mint}.\\n * For a generic mechanism see {ERC20PresetMinterPauser}.\\n *\\n * TIP: For a detailed writeup see our guide\\n * https://forum.zeppelin.solutions/t/how-to-implement-erc20-supply-mechanisms/226[How\\n * to implement supply mechanisms].\\n *\\n * We have followed general OpenZeppelin Contracts guidelines: functions revert\\n * instead returning `false` on failure. This behavior is nonetheless\\n * conventional and does not conflict with the expectations of ERC20\\n * applications.\\n *\\n * Additionally, an {Approval} event is emitted on calls to {transferFrom}.\\n * This allows applications to reconstruct the allowance for all accounts just\\n * by listening to said events. Other implementations of the EIP may not emit\\n * these events, as it isn't required by the specification.\\n *\\n * Finally, the non-standard {decreaseAllowance} and {increaseAllowance}\\n * functions have been added to mitigate the well-known issues around setting\\n * allowances. See {IERC20-approve}.\\n */\\ncontract ERC20 is Context, IERC20, IERC20Metadata {\\n mapping(address => uint256) private _balances;\\n\\n mapping(address => mapping(address => uint256)) private _allowances;\\n\\n uint256 private _totalSupply;\\n\\n string private _name;\\n string private _symbol;\\n\\n /**\\n * @dev Sets the values for {name} and {symbol}.\\n *\\n * The default value of {decimals} is 18. To select a different value for\\n * {decimals} you should overload it.\\n *\\n * All two of these values are immutable: they can only be set once during\\n * construction.\\n */\\n constructor(string memory name_, string memory symbol_) {\\n _name = name_;\\n _symbol = symbol_;\\n }\\n\\n /**\\n * @dev Returns the name of the token.\\n */\\n function name() public view virtual override returns (string memory) {\\n return _name;\\n }\\n\\n /**\\n * @dev Returns the symbol of the token, usually a shorter version of the\\n * name.\\n */\\n function symbol() public view virtual override returns (string memory) {\\n return _symbol;\\n }\\n\\n /**\\n * @dev Returns the number of decimals used to get its user representation.\\n * For example, if `decimals` equals `2`, a balance of `505` tokens should\\n * be displayed to a user as `5.05` (`505 / 10 ** 2`).\\n *\\n * Tokens usually opt for a value of 18, imitating the relationship between\\n * Ether and Wei. This is the value {ERC20} uses, unless this function is\\n * overridden;\\n *\\n * NOTE: This information is only used for _display_ purposes: it in\\n * no way affects any of the arithmetic of the contract, including\\n * {IERC20-balanceOf} and {IERC20-transfer}.\\n */\\n function decimals() public view virtual override returns (uint8) {\\n return 18;\\n }\\n\\n /**\\n * @dev See {IERC20-totalSupply}.\\n */\\n function totalSupply() public view virtual override returns (uint256) {\\n return _totalSupply;\\n }\\n\\n /**\\n * @dev See {IERC20-balanceOf}.\\n */\\n function balanceOf(address account) public view virtual override returns (uint256) {\\n return _balances[account];\\n }\\n\\n /**\\n * @dev See {IERC20-transfer}.\\n *\\n * Requirements:\\n *\\n * - `to` cannot be the zero address.\\n * - the caller must have a balance of at least `amount`.\\n */\\n function transfer(address to, uint256 amount) public virtual override returns (bool) {\\n address owner = _msgSender();\\n _transfer(owner, to, amount);\\n return true;\\n }\\n\\n /**\\n * @dev See {IERC20-allowance}.\\n */\\n function allowance(address owner, address spender) public view virtual override returns (uint256) {\\n return _allowances[owner][spender];\\n }\\n\\n /**\\n * @dev See {IERC20-approve}.\\n *\\n * NOTE: If `amount` is the maximum `uint256`, the allowance is not updated on\\n * `transferFrom`. This is semantically equivalent to an infinite approval.\\n *\\n * Requirements:\\n *\\n * - `spender` cannot be the zero address.\\n */\\n function approve(address spender, uint256 amount) public virtual override returns (bool) {\\n address owner = _msgSender();\\n _approve(owner, spender, amount);\\n return true;\\n }\\n\\n /**\\n * @dev See {IERC20-transferFrom}.\\n *\\n * Emits an {Approval} event indicating the updated allowance. This is not\\n * required by the EIP. See the note at the beginning of {ERC20}.\\n *\\n * NOTE: Does not update the allowance if the current allowance\\n * is the maximum `uint256`.\\n *\\n * Requirements:\\n *\\n * - `from` and `to` cannot be the zero address.\\n * - `from` must have a balance of at least `amount`.\\n * - the caller must have allowance for ``from``'s tokens of at least\\n * `amount`.\\n */\\n function transferFrom(\\n address from,\\n address to,\\n uint256 amount\\n ) public virtual override returns (bool) {\\n address spender = _msgSender();\\n _spendAllowance(from, spender, amount);\\n _transfer(from, to, amount);\\n return true;\\n }\\n\\n /**\\n * @dev Atomically increases the allowance granted to `spender` by the caller.\\n *\\n * This is an alternative to {approve} that can be used as a mitigation for\\n * problems described in {IERC20-approve}.\\n *\\n * Emits an {Approval} event indicating the updated allowance.\\n *\\n * Requirements:\\n *\\n * - `spender` cannot be the zero address.\\n */\\n function increaseAllowance(address spender, uint256 addedValue) public virtual returns (bool) {\\n address owner = _msgSender();\\n _approve(owner, spender, allowance(owner, spender) + addedValue);\\n return true;\\n }\\n\\n /**\\n * @dev Atomically decreases the allowance granted to `spender` by the caller.\\n *\\n * This is an alternative to {approve} that can be used as a mitigation for\\n * problems described in {IERC20-approve}.\\n *\\n * Emits an {Approval} event indicating the updated allowance.\\n *\\n * Requirements:\\n *\\n * - `spender` cannot be the zero address.\\n * - `spender` must have allowance for the caller of at least\\n * `subtractedValue`.\\n */\\n function decreaseAllowance(address spender, uint256 subtractedValue) public virtual returns (bool) {\\n address owner = _msgSender();\\n uint256 currentAllowance = allowance(owner, spender);\\n require(currentAllowance >= subtractedValue, \\\"ERC20: decreased allowance below zero\\\");\\n unchecked {\\n _approve(owner, spender, currentAllowance - subtractedValue);\\n }\\n\\n return true;\\n }\\n\\n /**\\n * @dev Moves `amount` of tokens from `from` to `to`.\\n *\\n * This internal function is equivalent to {transfer}, and can be used to\\n * e.g. implement automatic token fees, slashing mechanisms, etc.\\n *\\n * Emits a {Transfer} event.\\n *\\n * Requirements:\\n *\\n * - `from` cannot be the zero address.\\n * - `to` cannot be the zero address.\\n * - `from` must have a balance of at least `amount`.\\n */\\n function _transfer(\\n address from,\\n address to,\\n uint256 amount\\n ) internal virtual {\\n require(from != address(0), \\\"ERC20: transfer from the zero address\\\");\\n require(to != address(0), \\\"ERC20: transfer to the zero address\\\");\\n\\n _beforeTokenTransfer(from, to, amount);\\n\\n uint256 fromBalance = _balances[from];\\n require(fromBalance >= amount, \\\"ERC20: transfer amount exceeds balance\\\");\\n unchecked {\\n _balances[from] = fromBalance - amount;\\n }\\n _balances[to] += amount;\\n\\n emit Transfer(from, to, amount);\\n\\n _afterTokenTransfer(from, to, amount);\\n }\\n\\n /** @dev Creates `amount` tokens and assigns them to `account`, increasing\\n * the total supply.\\n *\\n * Emits a {Transfer} event with `from` set to the zero address.\\n *\\n * Requirements:\\n *\\n * - `account` cannot be the zero address.\\n */\\n function _mint(address account, uint256 amount) internal virtual {\\n require(account != address(0), \\\"ERC20: mint to the zero address\\\");\\n\\n _beforeTokenTransfer(address(0), account, amount);\\n\\n _totalSupply += amount;\\n _balances[account] += amount;\\n emit Transfer(address(0), account, amount);\\n\\n _afterTokenTransfer(address(0), account, amount);\\n }\\n\\n /**\\n * @dev Destroys `amount` tokens from `account`, reducing the\\n * total supply.\\n *\\n * Emits a {Transfer} event with `to` set to the zero address.\\n *\\n * Requirements:\\n *\\n * - `account` cannot be the zero address.\\n * - `account` must have at least `amount` tokens.\\n */\\n function _burn(address account, uint256 amount) internal virtual {\\n require(account != address(0), \\\"ERC20: burn from the zero address\\\");\\n\\n _beforeTokenTransfer(account, address(0), amount);\\n\\n uint256 accountBalance = _balances[account];\\n require(accountBalance >= amount, \\\"ERC20: burn amount exceeds balance\\\");\\n unchecked {\\n _balances[account] = accountBalance - amount;\\n }\\n _totalSupply -= amount;\\n\\n emit Transfer(account, address(0), amount);\\n\\n _afterTokenTransfer(account, address(0), amount);\\n }\\n\\n /**\\n * @dev Sets `amount` as the allowance of `spender` over the `owner` s tokens.\\n *\\n * This internal function is equivalent to `approve`, and can be used to\\n * e.g. set automatic allowances for certain subsystems, etc.\\n *\\n * Emits an {Approval} event.\\n *\\n * Requirements:\\n *\\n * - `owner` cannot be the zero address.\\n * - `spender` cannot be the zero address.\\n */\\n function _approve(\\n address owner,\\n address spender,\\n uint256 amount\\n ) internal virtual {\\n require(owner != address(0), \\\"ERC20: approve from the zero address\\\");\\n require(spender != address(0), \\\"ERC20: approve to the zero address\\\");\\n\\n _allowances[owner][spender] = amount;\\n emit Approval(owner, spender, amount);\\n }\\n\\n /**\\n * @dev Updates `owner` s allowance for `spender` based on spent `amount`.\\n *\\n * Does not update the allowance amount in case of infinite allowance.\\n * Revert if not enough allowance is available.\\n *\\n * Might emit an {Approval} event.\\n */\\n function _spendAllowance(\\n address owner,\\n address spender,\\n uint256 amount\\n ) internal virtual {\\n uint256 currentAllowance = allowance(owner, spender);\\n if (currentAllowance != type(uint256).max) {\\n require(currentAllowance >= amount, \\\"ERC20: insufficient allowance\\\");\\n unchecked {\\n _approve(owner, spender, currentAllowance - amount);\\n }\\n }\\n }\\n\\n /**\\n * @dev Hook that is called before any transfer of tokens. This includes\\n * minting and burning.\\n *\\n * Calling conditions:\\n *\\n * - when `from` and `to` are both non-zero, `amount` of ``from``'s tokens\\n * will be transferred to `to`.\\n * - when `from` is zero, `amount` tokens will be minted for `to`.\\n * - when `to` is zero, `amount` of ``from``'s tokens will be burned.\\n * - `from` and `to` are never both zero.\\n *\\n * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].\\n */\\n function _beforeTokenTransfer(\\n address from,\\n address to,\\n uint256 amount\\n ) internal virtual {}\\n\\n /**\\n * @dev Hook that is called after any transfer of tokens. This includes\\n * minting and burning.\\n *\\n * Calling conditions:\\n *\\n * - when `from` and `to` are both non-zero, `amount` of ``from``'s tokens\\n * has been transferred to `to`.\\n * - when `from` is zero, `amount` tokens have been minted for `to`.\\n * - when `to` is zero, `amount` of ``from``'s tokens have been burned.\\n * - `from` and `to` are never both zero.\\n *\\n * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].\\n */\\n function _afterTokenTransfer(\\n address from,\\n address to,\\n uint256 amount\\n ) internal virtual {}\\n}\\n\",\"keccak256\":\"0x24b04b8aacaaf1a4a0719117b29c9c3647b1f479c5ac2a60f5ff1bb6d839c238\",\"license\":\"MIT\"},\"@openzeppelin/contracts/token/ERC20/IERC20.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.6.0) (token/ERC20/IERC20.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Interface of the ERC20 standard as defined in the EIP.\\n */\\ninterface IERC20 {\\n /**\\n * @dev Emitted when `value` tokens are moved from one account (`from`) to\\n * another (`to`).\\n *\\n * Note that `value` may be zero.\\n */\\n event Transfer(address indexed from, address indexed to, uint256 value);\\n\\n /**\\n * @dev Emitted when the allowance of a `spender` for an `owner` is set by\\n * a call to {approve}. `value` is the new allowance.\\n */\\n event Approval(address indexed owner, address indexed spender, uint256 value);\\n\\n /**\\n * @dev Returns the amount of tokens in existence.\\n */\\n function totalSupply() external view returns (uint256);\\n\\n /**\\n * @dev Returns the amount of tokens owned by `account`.\\n */\\n function balanceOf(address account) external view returns (uint256);\\n\\n /**\\n * @dev Moves `amount` tokens from the caller's account to `to`.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * Emits a {Transfer} event.\\n */\\n function transfer(address to, uint256 amount) external returns (bool);\\n\\n /**\\n * @dev Returns the remaining number of tokens that `spender` will be\\n * allowed to spend on behalf of `owner` through {transferFrom}. This is\\n * zero by default.\\n *\\n * This value changes when {approve} or {transferFrom} are called.\\n */\\n function allowance(address owner, address spender) external view returns (uint256);\\n\\n /**\\n * @dev Sets `amount` as the allowance of `spender` over the caller's tokens.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * IMPORTANT: Beware that changing an allowance with this method brings the risk\\n * that someone may use both the old and the new allowance by unfortunate\\n * transaction ordering. One possible solution to mitigate this race\\n * condition is to first reduce the spender's allowance to 0 and set the\\n * desired value afterwards:\\n * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729\\n *\\n * Emits an {Approval} event.\\n */\\n function approve(address spender, uint256 amount) external returns (bool);\\n\\n /**\\n * @dev Moves `amount` tokens from `from` to `to` using the\\n * allowance mechanism. `amount` is then deducted from the caller's\\n * allowance.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * Emits a {Transfer} event.\\n */\\n function transferFrom(\\n address from,\\n address to,\\n uint256 amount\\n ) external returns (bool);\\n}\\n\",\"keccak256\":\"0x9750c6b834f7b43000631af5cc30001c5f547b3ceb3635488f140f60e897ea6b\",\"license\":\"MIT\"},\"@openzeppelin/contracts/token/ERC20/extensions/IERC20Metadata.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (token/ERC20/extensions/IERC20Metadata.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../IERC20.sol\\\";\\n\\n/**\\n * @dev Interface for the optional metadata functions from the ERC20 standard.\\n *\\n * _Available since v4.1._\\n */\\ninterface IERC20Metadata is IERC20 {\\n /**\\n * @dev Returns the name of the token.\\n */\\n function name() external view returns (string memory);\\n\\n /**\\n * @dev Returns the symbol of the token.\\n */\\n function symbol() external view returns (string memory);\\n\\n /**\\n * @dev Returns the decimals places of the token.\\n */\\n function decimals() external view returns (uint8);\\n}\\n\",\"keccak256\":\"0x8de418a5503946cabe331f35fe242d3201a73f67f77aaeb7110acb1f30423aca\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/Context.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Provides information about the current execution context, including the\\n * sender of the transaction and its data. While these are generally available\\n * via msg.sender and msg.data, they should not be accessed in such a direct\\n * manner, since when dealing with meta-transactions the account sending and\\n * paying for execution may not be the actual sender (as far as an application\\n * is concerned).\\n *\\n * This contract is only required for intermediate, library-like contracts.\\n */\\nabstract contract Context {\\n function _msgSender() internal view virtual returns (address) {\\n return msg.sender;\\n }\\n\\n function _msgData() internal view virtual returns (bytes calldata) {\\n return msg.data;\\n }\\n}\\n\",\"keccak256\":\"0xe2e337e6dde9ef6b680e07338c493ebea1b5fd09b43424112868e9cc1706bca7\",\"license\":\"MIT\"},\"contracts/mock/MockToken.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-3.0\\n\\npragma solidity ^0.8.7;\\n\\nimport \\\"@openzeppelin/contracts/token/ERC20/ERC20.sol\\\";\\n\\ncontract MockToken is ERC20 {\\n event Minting(address indexed _to, address indexed _minter, uint256 _amount);\\n\\n event Burning(address indexed _from, address indexed _burner, uint256 _amount);\\n\\n uint8 internal _decimal;\\n mapping(address => bool) public minters;\\n address public treasury;\\n\\n constructor(string memory name_, string memory symbol_, uint8 decimal_) ERC20(name_, symbol_) {\\n _decimal = decimal_;\\n }\\n\\n function decimals() public view override returns (uint8) {\\n return _decimal;\\n }\\n\\n function mint(address account, uint256 amount) external {\\n _mint(account, amount);\\n emit Minting(account, msg.sender, amount);\\n }\\n\\n function burn(address account, uint256 amount) public {\\n _burn(account, amount);\\n emit Burning(account, msg.sender, amount);\\n }\\n\\n function setAllowance(address from, address to) public {\\n _approve(from, to, type(uint256).max);\\n }\\n\\n function burnSelf(uint256 amount, address account) public {\\n _burn(account, amount);\\n emit Burning(account, msg.sender, amount);\\n }\\n\\n function addMinter(address minter) public {\\n minters[minter] = true;\\n }\\n\\n function removeMinter(address minter) public {\\n minters[minter] = false;\\n }\\n\\n function setTreasury(address _treasury) public {\\n treasury = _treasury;\\n }\\n}\\n\",\"keccak256\":\"0x39f0abfb5674ee9d98d5212d8b1bcd31b26f6aa4737ce1f921aa24d747bc0c62\",\"license\":\"GPL-3.0\"}},\"version\":1}", + "bytecode": "0x60806040523480156200001157600080fd5b506040516200156a3803806200156a833981016040819052620000349162000139565b828260036200004483826200024d565b5060046200005382826200024d565b50506005805460ff191660ff93909316929092179091555062000319915050565b634e487b7160e01b600052604160045260246000fd5b600082601f8301126200009c57600080fd5b81516001600160401b0380821115620000b957620000b962000074565b604051601f8301601f19908116603f01168101908282118183101715620000e457620000e462000074565b816040528381526020925086838588010111156200010157600080fd5b600091505b8382101562000125578582018301518183018401529082019062000106565b600093810190920192909252949350505050565b6000806000606084860312156200014f57600080fd5b83516001600160401b03808211156200016757600080fd5b62000175878388016200008a565b945060208601519150808211156200018c57600080fd5b506200019b868287016200008a565b925050604084015160ff81168114620001b357600080fd5b809150509250925092565b600181811c90821680620001d357607f821691505b602082108103620001f457634e487b7160e01b600052602260045260246000fd5b50919050565b601f8211156200024857600081815260208120601f850160051c81016020861015620002235750805b601f850160051c820191505b8181101562000244578281556001016200022f565b5050505b505050565b81516001600160401b0381111562000269576200026962000074565b62000281816200027a8454620001be565b84620001fa565b602080601f831160018114620002b95760008415620002a05750858301515b600019600386901b1c1916600185901b17855562000244565b600085815260208120601f198616915b82811015620002ea57888601518255948401946001909101908401620002c9565b5085821015620003095787850151600019600388901b60f8161c191681555b5050505050600190811b01905550565b61124180620003296000396000f3fe608060405234801561001057600080fd5b506004361061016c5760003560e01c806361d027b3116100cd578063a457c2d711610081578063dd62ed3e11610066578063dd62ed3e146103ad578063f0f44260146103f3578063f46eccc41461044857600080fd5b8063a457c2d714610387578063a9059cbb1461039a57600080fd5b806395d89b41116100b257806395d89b411461030f578063983b2d56146103175780639dc29fac1461037457600080fd5b806361d027b31461029457806370a08231146102d957600080fd5b80632b471d8e11610124578063313ce56711610109578063313ce56714610259578063395093511461026e57806340c10f191461028157600080fd5b80632b471d8e146101ec5780633092afd5146101ff57600080fd5b806318160ddd1161015557806318160ddd146101b25780631cedc203146101c457806323b872dd146101d957600080fd5b806306fdde0314610171578063095ea7b31461018f575b600080fd5b61017961046b565b6040516101869190610ff0565b60405180910390f35b6101a261019d366004611085565b6104fd565b6040519015158152602001610186565b6002545b604051908152602001610186565b6101d76101d23660046110af565b610517565b005b6101a26101e73660046110e2565b610546565b6101d76101fa36600461111e565b61056a565b6101d761020d366004611141565b73ffffffffffffffffffffffffffffffffffffffff16600090815260066020526040902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00169055565b60055460405160ff9091168152602001610186565b6101a261027c366004611085565b6105c6565b6101d761028f366004611085565b610612565b6007546102b49073ffffffffffffffffffffffffffffffffffffffff1681565b60405173ffffffffffffffffffffffffffffffffffffffff9091168152602001610186565b6101b66102e7366004611141565b73ffffffffffffffffffffffffffffffffffffffff1660009081526020819052604090205490565b610179610666565b6101d7610325366004611141565b73ffffffffffffffffffffffffffffffffffffffff16600090815260066020526040902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00166001179055565b6101d7610382366004611085565b610675565b6101a2610395366004611085565b6106c9565b6101a26103a8366004611085565b61079f565b6101b66103bb3660046110af565b73ffffffffffffffffffffffffffffffffffffffff918216600090815260016020908152604080832093909416825291909152205490565b6101d7610401366004611141565b600780547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff92909216919091179055565b6101a2610456366004611141565b60066020526000908152604090205460ff1681565b60606003805461047a90611163565b80601f01602080910402602001604051908101604052809291908181526020018280546104a690611163565b80156104f35780601f106104c8576101008083540402835291602001916104f3565b820191906000526020600020905b8154815290600101906020018083116104d657829003601f168201915b5050505050905090565b60003361050b8185856107ad565b60019150505b92915050565b61054282827fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff6107ad565b5050565b600033610554858285610961565b61055f858585610a38565b506001949350505050565b6105748183610ceb565b604051828152339073ffffffffffffffffffffffffffffffffffffffff8316907f227fb4b3aae8331f21af5167739c291fefe3afd3c2e08cea44f499e564f486ef906020015b60405180910390a35050565b33600081815260016020908152604080832073ffffffffffffffffffffffffffffffffffffffff8716845290915281205490919061050b908290869061060d9087906111e5565b6107ad565b61061c8282610ed0565b604051818152339073ffffffffffffffffffffffffffffffffffffffff8416907fb1233017d63154bc561d57c16f7b6a55e2e1acd7fcac94045a9f35fb31a850ca906020016105ba565b60606004805461047a90611163565b61067f8282610ceb565b604051818152339073ffffffffffffffffffffffffffffffffffffffff8416907f227fb4b3aae8331f21af5167739c291fefe3afd3c2e08cea44f499e564f486ef906020016105ba565b33600081815260016020908152604080832073ffffffffffffffffffffffffffffffffffffffff8716845290915281205490919083811015610792576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602560248201527f45524332303a2064656372656173656420616c6c6f77616e63652062656c6f7760448201527f207a65726f00000000000000000000000000000000000000000000000000000060648201526084015b60405180910390fd5b61055f82868684036107ad565b60003361050b818585610a38565b73ffffffffffffffffffffffffffffffffffffffff831661084f576040517f08c379a0000000000000000000000000000000000000000000000000000000008152602060048201526024808201527f45524332303a20617070726f76652066726f6d20746865207a65726f2061646460448201527f72657373000000000000000000000000000000000000000000000000000000006064820152608401610789565b73ffffffffffffffffffffffffffffffffffffffff82166108f2576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602260248201527f45524332303a20617070726f766520746f20746865207a65726f20616464726560448201527f73730000000000000000000000000000000000000000000000000000000000006064820152608401610789565b73ffffffffffffffffffffffffffffffffffffffff83811660008181526001602090815260408083209487168084529482529182902085905590518481527f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92591015b60405180910390a3505050565b73ffffffffffffffffffffffffffffffffffffffff8381166000908152600160209081526040808320938616835292905220547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8114610a325781811015610a25576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f45524332303a20696e73756666696369656e7420616c6c6f77616e63650000006044820152606401610789565b610a3284848484036107ad565b50505050565b73ffffffffffffffffffffffffffffffffffffffff8316610adb576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602560248201527f45524332303a207472616e736665722066726f6d20746865207a65726f20616460448201527f64726573730000000000000000000000000000000000000000000000000000006064820152608401610789565b73ffffffffffffffffffffffffffffffffffffffff8216610b7e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602360248201527f45524332303a207472616e7366657220746f20746865207a65726f206164647260448201527f65737300000000000000000000000000000000000000000000000000000000006064820152608401610789565b73ffffffffffffffffffffffffffffffffffffffff831660009081526020819052604090205481811015610c34576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f45524332303a207472616e7366657220616d6f756e742065786365656473206260448201527f616c616e636500000000000000000000000000000000000000000000000000006064820152608401610789565b73ffffffffffffffffffffffffffffffffffffffff808516600090815260208190526040808220858503905591851681529081208054849290610c789084906111e5565b925050819055508273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef84604051610cde91815260200190565b60405180910390a3610a32565b73ffffffffffffffffffffffffffffffffffffffff8216610d8e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602160248201527f45524332303a206275726e2066726f6d20746865207a65726f2061646472657360448201527f73000000000000000000000000000000000000000000000000000000000000006064820152608401610789565b73ffffffffffffffffffffffffffffffffffffffff821660009081526020819052604090205481811015610e44576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602260248201527f45524332303a206275726e20616d6f756e7420657863656564732062616c616e60448201527f63650000000000000000000000000000000000000000000000000000000000006064820152608401610789565b73ffffffffffffffffffffffffffffffffffffffff83166000908152602081905260408120838303905560028054849290610e809084906111f8565b909155505060405182815260009073ffffffffffffffffffffffffffffffffffffffff8516907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef90602001610954565b73ffffffffffffffffffffffffffffffffffffffff8216610f4d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601f60248201527f45524332303a206d696e7420746f20746865207a65726f2061646472657373006044820152606401610789565b8060026000828254610f5f91906111e5565b909155505073ffffffffffffffffffffffffffffffffffffffff821660009081526020819052604081208054839290610f999084906111e5565b909155505060405181815273ffffffffffffffffffffffffffffffffffffffff8316906000907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef9060200160405180910390a35050565b600060208083528351808285015260005b8181101561101d57858101830151858201604001528201611001565b5060006040828601015260407fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f8301168501019250505092915050565b803573ffffffffffffffffffffffffffffffffffffffff8116811461108057600080fd5b919050565b6000806040838503121561109857600080fd5b6110a18361105c565b946020939093013593505050565b600080604083850312156110c257600080fd5b6110cb8361105c565b91506110d96020840161105c565b90509250929050565b6000806000606084860312156110f757600080fd5b6111008461105c565b925061110e6020850161105c565b9150604084013590509250925092565b6000806040838503121561113157600080fd5b823591506110d96020840161105c565b60006020828403121561115357600080fd5b61115c8261105c565b9392505050565b600181811c9082168061117757607f821691505b6020821081036111b0577f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b50919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b80820180821115610511576105116111b6565b81810381811115610511576105116111b656fea264697066735822122006a46129fff2e6800d72658b043565f7aae96733cd836d2f2d573a961a2f376764736f6c63430008110033", + "deployedBytecode": "0x608060405234801561001057600080fd5b506004361061016c5760003560e01c806361d027b3116100cd578063a457c2d711610081578063dd62ed3e11610066578063dd62ed3e146103ad578063f0f44260146103f3578063f46eccc41461044857600080fd5b8063a457c2d714610387578063a9059cbb1461039a57600080fd5b806395d89b41116100b257806395d89b411461030f578063983b2d56146103175780639dc29fac1461037457600080fd5b806361d027b31461029457806370a08231146102d957600080fd5b80632b471d8e11610124578063313ce56711610109578063313ce56714610259578063395093511461026e57806340c10f191461028157600080fd5b80632b471d8e146101ec5780633092afd5146101ff57600080fd5b806318160ddd1161015557806318160ddd146101b25780631cedc203146101c457806323b872dd146101d957600080fd5b806306fdde0314610171578063095ea7b31461018f575b600080fd5b61017961046b565b6040516101869190610ff0565b60405180910390f35b6101a261019d366004611085565b6104fd565b6040519015158152602001610186565b6002545b604051908152602001610186565b6101d76101d23660046110af565b610517565b005b6101a26101e73660046110e2565b610546565b6101d76101fa36600461111e565b61056a565b6101d761020d366004611141565b73ffffffffffffffffffffffffffffffffffffffff16600090815260066020526040902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00169055565b60055460405160ff9091168152602001610186565b6101a261027c366004611085565b6105c6565b6101d761028f366004611085565b610612565b6007546102b49073ffffffffffffffffffffffffffffffffffffffff1681565b60405173ffffffffffffffffffffffffffffffffffffffff9091168152602001610186565b6101b66102e7366004611141565b73ffffffffffffffffffffffffffffffffffffffff1660009081526020819052604090205490565b610179610666565b6101d7610325366004611141565b73ffffffffffffffffffffffffffffffffffffffff16600090815260066020526040902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00166001179055565b6101d7610382366004611085565b610675565b6101a2610395366004611085565b6106c9565b6101a26103a8366004611085565b61079f565b6101b66103bb3660046110af565b73ffffffffffffffffffffffffffffffffffffffff918216600090815260016020908152604080832093909416825291909152205490565b6101d7610401366004611141565b600780547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff92909216919091179055565b6101a2610456366004611141565b60066020526000908152604090205460ff1681565b60606003805461047a90611163565b80601f01602080910402602001604051908101604052809291908181526020018280546104a690611163565b80156104f35780601f106104c8576101008083540402835291602001916104f3565b820191906000526020600020905b8154815290600101906020018083116104d657829003601f168201915b5050505050905090565b60003361050b8185856107ad565b60019150505b92915050565b61054282827fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff6107ad565b5050565b600033610554858285610961565b61055f858585610a38565b506001949350505050565b6105748183610ceb565b604051828152339073ffffffffffffffffffffffffffffffffffffffff8316907f227fb4b3aae8331f21af5167739c291fefe3afd3c2e08cea44f499e564f486ef906020015b60405180910390a35050565b33600081815260016020908152604080832073ffffffffffffffffffffffffffffffffffffffff8716845290915281205490919061050b908290869061060d9087906111e5565b6107ad565b61061c8282610ed0565b604051818152339073ffffffffffffffffffffffffffffffffffffffff8416907fb1233017d63154bc561d57c16f7b6a55e2e1acd7fcac94045a9f35fb31a850ca906020016105ba565b60606004805461047a90611163565b61067f8282610ceb565b604051818152339073ffffffffffffffffffffffffffffffffffffffff8416907f227fb4b3aae8331f21af5167739c291fefe3afd3c2e08cea44f499e564f486ef906020016105ba565b33600081815260016020908152604080832073ffffffffffffffffffffffffffffffffffffffff8716845290915281205490919083811015610792576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602560248201527f45524332303a2064656372656173656420616c6c6f77616e63652062656c6f7760448201527f207a65726f00000000000000000000000000000000000000000000000000000060648201526084015b60405180910390fd5b61055f82868684036107ad565b60003361050b818585610a38565b73ffffffffffffffffffffffffffffffffffffffff831661084f576040517f08c379a0000000000000000000000000000000000000000000000000000000008152602060048201526024808201527f45524332303a20617070726f76652066726f6d20746865207a65726f2061646460448201527f72657373000000000000000000000000000000000000000000000000000000006064820152608401610789565b73ffffffffffffffffffffffffffffffffffffffff82166108f2576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602260248201527f45524332303a20617070726f766520746f20746865207a65726f20616464726560448201527f73730000000000000000000000000000000000000000000000000000000000006064820152608401610789565b73ffffffffffffffffffffffffffffffffffffffff83811660008181526001602090815260408083209487168084529482529182902085905590518481527f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92591015b60405180910390a3505050565b73ffffffffffffffffffffffffffffffffffffffff8381166000908152600160209081526040808320938616835292905220547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8114610a325781811015610a25576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f45524332303a20696e73756666696369656e7420616c6c6f77616e63650000006044820152606401610789565b610a3284848484036107ad565b50505050565b73ffffffffffffffffffffffffffffffffffffffff8316610adb576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602560248201527f45524332303a207472616e736665722066726f6d20746865207a65726f20616460448201527f64726573730000000000000000000000000000000000000000000000000000006064820152608401610789565b73ffffffffffffffffffffffffffffffffffffffff8216610b7e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602360248201527f45524332303a207472616e7366657220746f20746865207a65726f206164647260448201527f65737300000000000000000000000000000000000000000000000000000000006064820152608401610789565b73ffffffffffffffffffffffffffffffffffffffff831660009081526020819052604090205481811015610c34576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f45524332303a207472616e7366657220616d6f756e742065786365656473206260448201527f616c616e636500000000000000000000000000000000000000000000000000006064820152608401610789565b73ffffffffffffffffffffffffffffffffffffffff808516600090815260208190526040808220858503905591851681529081208054849290610c789084906111e5565b925050819055508273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef84604051610cde91815260200190565b60405180910390a3610a32565b73ffffffffffffffffffffffffffffffffffffffff8216610d8e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602160248201527f45524332303a206275726e2066726f6d20746865207a65726f2061646472657360448201527f73000000000000000000000000000000000000000000000000000000000000006064820152608401610789565b73ffffffffffffffffffffffffffffffffffffffff821660009081526020819052604090205481811015610e44576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602260248201527f45524332303a206275726e20616d6f756e7420657863656564732062616c616e60448201527f63650000000000000000000000000000000000000000000000000000000000006064820152608401610789565b73ffffffffffffffffffffffffffffffffffffffff83166000908152602081905260408120838303905560028054849290610e809084906111f8565b909155505060405182815260009073ffffffffffffffffffffffffffffffffffffffff8516907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef90602001610954565b73ffffffffffffffffffffffffffffffffffffffff8216610f4d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601f60248201527f45524332303a206d696e7420746f20746865207a65726f2061646472657373006044820152606401610789565b8060026000828254610f5f91906111e5565b909155505073ffffffffffffffffffffffffffffffffffffffff821660009081526020819052604081208054839290610f999084906111e5565b909155505060405181815273ffffffffffffffffffffffffffffffffffffffff8316906000907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef9060200160405180910390a35050565b600060208083528351808285015260005b8181101561101d57858101830151858201604001528201611001565b5060006040828601015260407fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f8301168501019250505092915050565b803573ffffffffffffffffffffffffffffffffffffffff8116811461108057600080fd5b919050565b6000806040838503121561109857600080fd5b6110a18361105c565b946020939093013593505050565b600080604083850312156110c257600080fd5b6110cb8361105c565b91506110d96020840161105c565b90509250929050565b6000806000606084860312156110f757600080fd5b6111008461105c565b925061110e6020850161105c565b9150604084013590509250925092565b6000806040838503121561113157600080fd5b823591506110d96020840161105c565b60006020828403121561115357600080fd5b61115c8261105c565b9392505050565b600181811c9082168061117757607f821691505b6020821081036111b0577f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b50919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b80820180821115610511576105116111b6565b81810381811115610511576105116111b656fea264697066735822122006a46129fff2e6800d72658b043565f7aae96733cd836d2f2d573a961a2f376764736f6c63430008110033", + "devdoc": { + "kind": "dev", + "methods": { + "allowance(address,address)": { + "details": "See {IERC20-allowance}." + }, + "approve(address,uint256)": { + "details": "See {IERC20-approve}. NOTE: If `amount` is the maximum `uint256`, the allowance is not updated on `transferFrom`. This is semantically equivalent to an infinite approval. Requirements: - `spender` cannot be the zero address." + }, + "balanceOf(address)": { + "details": "See {IERC20-balanceOf}." + }, + "decimals()": { + "details": "Returns the number of decimals used to get its user representation. For example, if `decimals` equals `2`, a balance of `505` tokens should be displayed to a user as `5.05` (`505 / 10 ** 2`). Tokens usually opt for a value of 18, imitating the relationship between Ether and Wei. This is the value {ERC20} uses, unless this function is overridden; NOTE: This information is only used for _display_ purposes: it in no way affects any of the arithmetic of the contract, including {IERC20-balanceOf} and {IERC20-transfer}." + }, + "decreaseAllowance(address,uint256)": { + "details": "Atomically decreases the allowance granted to `spender` by the caller. This is an alternative to {approve} that can be used as a mitigation for problems described in {IERC20-approve}. Emits an {Approval} event indicating the updated allowance. Requirements: - `spender` cannot be the zero address. - `spender` must have allowance for the caller of at least `subtractedValue`." + }, + "increaseAllowance(address,uint256)": { + "details": "Atomically increases the allowance granted to `spender` by the caller. This is an alternative to {approve} that can be used as a mitigation for problems described in {IERC20-approve}. Emits an {Approval} event indicating the updated allowance. Requirements: - `spender` cannot be the zero address." + }, + "name()": { + "details": "Returns the name of the token." + }, + "symbol()": { + "details": "Returns the symbol of the token, usually a shorter version of the name." + }, + "totalSupply()": { + "details": "See {IERC20-totalSupply}." + }, + "transfer(address,uint256)": { + "details": "See {IERC20-transfer}. Requirements: - `to` cannot be the zero address. - the caller must have a balance of at least `amount`." + }, + "transferFrom(address,address,uint256)": { + "details": "See {IERC20-transferFrom}. Emits an {Approval} event indicating the updated allowance. This is not required by the EIP. See the note at the beginning of {ERC20}. NOTE: Does not update the allowance if the current allowance is the maximum `uint256`. Requirements: - `from` and `to` cannot be the zero address. - `from` must have a balance of at least `amount`. - the caller must have allowance for ``from``'s tokens of at least `amount`." + } + }, + "version": 1 + }, + "userdoc": { + "kind": "user", + "methods": {}, + "version": 1 + }, + "storageLayout": { + "storage": [ + { + "astId": 4616, + "contract": "contracts/mock/MockToken.sol:MockToken", + "label": "_balances", + "offset": 0, + "slot": "0", + "type": "t_mapping(t_address,t_uint256)" + }, + { + "astId": 4622, + "contract": "contracts/mock/MockToken.sol:MockToken", + "label": "_allowances", + "offset": 0, + "slot": "1", + "type": "t_mapping(t_address,t_mapping(t_address,t_uint256))" + }, + { + "astId": 4624, + "contract": "contracts/mock/MockToken.sol:MockToken", + "label": "_totalSupply", + "offset": 0, + "slot": "2", + "type": "t_uint256" + }, + { + "astId": 4626, + "contract": "contracts/mock/MockToken.sol:MockToken", + "label": "_name", + "offset": 0, + "slot": "3", + "type": "t_string_storage" + }, + { + "astId": 4628, + "contract": "contracts/mock/MockToken.sol:MockToken", + "label": "_symbol", + "offset": 0, + "slot": "4", + "type": "t_string_storage" + }, + { + "astId": 24659, + "contract": "contracts/mock/MockToken.sol:MockToken", + "label": "_decimal", + "offset": 0, + "slot": "5", + "type": "t_uint8" + }, + { + "astId": 24663, + "contract": "contracts/mock/MockToken.sol:MockToken", + "label": "minters", + "offset": 0, + "slot": "6", + "type": "t_mapping(t_address,t_bool)" + }, + { + "astId": 24665, + "contract": "contracts/mock/MockToken.sol:MockToken", + "label": "treasury", + "offset": 0, + "slot": "7", + "type": "t_address" + } + ], + "types": { + "t_address": { + "encoding": "inplace", + "label": "address", + "numberOfBytes": "20" + }, + "t_bool": { + "encoding": "inplace", + "label": "bool", + "numberOfBytes": "1" + }, + "t_mapping(t_address,t_bool)": { + "encoding": "mapping", + "key": "t_address", + "label": "mapping(address => bool)", + "numberOfBytes": "32", + "value": "t_bool" + }, + "t_mapping(t_address,t_mapping(t_address,t_uint256))": { + "encoding": "mapping", + "key": "t_address", + "label": "mapping(address => mapping(address => uint256))", + "numberOfBytes": "32", + "value": "t_mapping(t_address,t_uint256)" + }, + "t_mapping(t_address,t_uint256)": { + "encoding": "mapping", + "key": "t_address", + "label": "mapping(address => uint256)", + "numberOfBytes": "32", + "value": "t_uint256" + }, + "t_string_storage": { + "encoding": "bytes", + "label": "string", + "numberOfBytes": "32" + }, + "t_uint256": { + "encoding": "inplace", + "label": "uint256", + "numberOfBytes": "32" + }, + "t_uint8": { + "encoding": "inplace", + "label": "uint8", + "numberOfBytes": "1" + } + } + } +} \ No newline at end of file diff --git a/deployments/gnosis/solcInputs/871924e0c138825a2736b76def8fef8d.json b/deployments/gnosis/solcInputs/871924e0c138825a2736b76def8fef8d.json new file mode 100644 index 00000000..57454028 --- /dev/null +++ b/deployments/gnosis/solcInputs/871924e0c138825a2736b76def8fef8d.json @@ -0,0 +1,562 @@ +{ + "language": "Solidity", + "sources": { + "@chainlink/contracts/src/v0.8/interfaces/AggregatorV3Interface.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.0;\n\ninterface AggregatorV3Interface {\n\n function decimals()\n external\n view\n returns (\n uint8\n );\n\n function description()\n external\n view\n returns (\n string memory\n );\n\n function version()\n external\n view\n returns (\n uint256\n );\n\n // getRoundData and latestRoundData should both raise \"No data present\"\n // if they do not have data to report, instead of returning unset values\n // which could be misinterpreted as actual reported values.\n function getRoundData(\n uint80 _roundId\n )\n external\n view\n returns (\n uint80 roundId,\n int256 answer,\n uint256 startedAt,\n uint256 updatedAt,\n uint80 answeredInRound\n );\n\n function latestRoundData()\n external\n view\n returns (\n uint80 roundId,\n int256 answer,\n uint256 startedAt,\n uint256 updatedAt,\n uint80 answeredInRound\n );\n\n}\n" + }, + "@openzeppelin/contracts-upgradeable/access/AccessControlEnumerableUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.5.0) (access/AccessControlEnumerable.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./IAccessControlEnumerableUpgradeable.sol\";\nimport \"./AccessControlUpgradeable.sol\";\nimport \"../utils/structs/EnumerableSetUpgradeable.sol\";\nimport \"../proxy/utils/Initializable.sol\";\n\n/**\n * @dev Extension of {AccessControl} that allows enumerating the members of each role.\n */\nabstract contract AccessControlEnumerableUpgradeable is Initializable, IAccessControlEnumerableUpgradeable, AccessControlUpgradeable {\n function __AccessControlEnumerable_init() internal onlyInitializing {\n }\n\n function __AccessControlEnumerable_init_unchained() internal onlyInitializing {\n }\n using EnumerableSetUpgradeable for EnumerableSetUpgradeable.AddressSet;\n\n mapping(bytes32 => EnumerableSetUpgradeable.AddressSet) private _roleMembers;\n\n /**\n * @dev See {IERC165-supportsInterface}.\n */\n function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {\n return interfaceId == type(IAccessControlEnumerableUpgradeable).interfaceId || super.supportsInterface(interfaceId);\n }\n\n /**\n * @dev Returns one of the accounts that have `role`. `index` must be a\n * value between 0 and {getRoleMemberCount}, non-inclusive.\n *\n * Role bearers are not sorted in any particular way, and their ordering may\n * change at any point.\n *\n * WARNING: When using {getRoleMember} and {getRoleMemberCount}, make sure\n * you perform all queries on the same block. See the following\n * https://forum.openzeppelin.com/t/iterating-over-elements-on-enumerableset-in-openzeppelin-contracts/2296[forum post]\n * for more information.\n */\n function getRoleMember(bytes32 role, uint256 index) public view virtual override returns (address) {\n return _roleMembers[role].at(index);\n }\n\n /**\n * @dev Returns the number of accounts that have `role`. Can be used\n * together with {getRoleMember} to enumerate all bearers of a role.\n */\n function getRoleMemberCount(bytes32 role) public view virtual override returns (uint256) {\n return _roleMembers[role].length();\n }\n\n /**\n * @dev Overload {_grantRole} to track enumerable memberships\n */\n function _grantRole(bytes32 role, address account) internal virtual override {\n super._grantRole(role, account);\n _roleMembers[role].add(account);\n }\n\n /**\n * @dev Overload {_revokeRole} to track enumerable memberships\n */\n function _revokeRole(bytes32 role, address account) internal virtual override {\n super._revokeRole(role, account);\n _roleMembers[role].remove(account);\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[49] private __gap;\n}\n" + }, + "@openzeppelin/contracts-upgradeable/access/AccessControlUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (access/AccessControl.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./IAccessControlUpgradeable.sol\";\nimport \"../utils/ContextUpgradeable.sol\";\nimport \"../utils/StringsUpgradeable.sol\";\nimport \"../utils/introspection/ERC165Upgradeable.sol\";\nimport \"../proxy/utils/Initializable.sol\";\n\n/**\n * @dev Contract module that allows children to implement role-based access\n * control mechanisms. This is a lightweight version that doesn't allow enumerating role\n * members except through off-chain means by accessing the contract event logs. Some\n * applications may benefit from on-chain enumerability, for those cases see\n * {AccessControlEnumerable}.\n *\n * Roles are referred to by their `bytes32` identifier. These should be exposed\n * in the external API and be unique. The best way to achieve this is by\n * using `public constant` hash digests:\n *\n * ```\n * bytes32 public constant MY_ROLE = keccak256(\"MY_ROLE\");\n * ```\n *\n * Roles can be used to represent a set of permissions. To restrict access to a\n * function call, use {hasRole}:\n *\n * ```\n * function foo() public {\n * require(hasRole(MY_ROLE, msg.sender));\n * ...\n * }\n * ```\n *\n * Roles can be granted and revoked dynamically via the {grantRole} and\n * {revokeRole} functions. Each role has an associated admin role, and only\n * accounts that have a role's admin role can call {grantRole} and {revokeRole}.\n *\n * By default, the admin role for all roles is `DEFAULT_ADMIN_ROLE`, which means\n * that only accounts with this role will be able to grant or revoke other\n * roles. More complex role relationships can be created by using\n * {_setRoleAdmin}.\n *\n * WARNING: The `DEFAULT_ADMIN_ROLE` is also its own admin: it has permission to\n * grant and revoke this role. Extra precautions should be taken to secure\n * accounts that have been granted it.\n */\nabstract contract AccessControlUpgradeable is Initializable, ContextUpgradeable, IAccessControlUpgradeable, ERC165Upgradeable {\n function __AccessControl_init() internal onlyInitializing {\n }\n\n function __AccessControl_init_unchained() internal onlyInitializing {\n }\n struct RoleData {\n mapping(address => bool) members;\n bytes32 adminRole;\n }\n\n mapping(bytes32 => RoleData) private _roles;\n\n bytes32 public constant DEFAULT_ADMIN_ROLE = 0x00;\n\n /**\n * @dev Modifier that checks that an account has a specific role. Reverts\n * with a standardized message including the required role.\n *\n * The format of the revert reason is given by the following regular expression:\n *\n * /^AccessControl: account (0x[0-9a-f]{40}) is missing role (0x[0-9a-f]{64})$/\n *\n * _Available since v4.1._\n */\n modifier onlyRole(bytes32 role) {\n _checkRole(role);\n _;\n }\n\n /**\n * @dev See {IERC165-supportsInterface}.\n */\n function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {\n return interfaceId == type(IAccessControlUpgradeable).interfaceId || super.supportsInterface(interfaceId);\n }\n\n /**\n * @dev Returns `true` if `account` has been granted `role`.\n */\n function hasRole(bytes32 role, address account) public view virtual override returns (bool) {\n return _roles[role].members[account];\n }\n\n /**\n * @dev Revert with a standard message if `_msgSender()` is missing `role`.\n * Overriding this function changes the behavior of the {onlyRole} modifier.\n *\n * Format of the revert message is described in {_checkRole}.\n *\n * _Available since v4.6._\n */\n function _checkRole(bytes32 role) internal view virtual {\n _checkRole(role, _msgSender());\n }\n\n /**\n * @dev Revert with a standard message if `account` is missing `role`.\n *\n * The format of the revert reason is given by the following regular expression:\n *\n * /^AccessControl: account (0x[0-9a-f]{40}) is missing role (0x[0-9a-f]{64})$/\n */\n function _checkRole(bytes32 role, address account) internal view virtual {\n if (!hasRole(role, account)) {\n revert(\n string(\n abi.encodePacked(\n \"AccessControl: account \",\n StringsUpgradeable.toHexString(uint160(account), 20),\n \" is missing role \",\n StringsUpgradeable.toHexString(uint256(role), 32)\n )\n )\n );\n }\n }\n\n /**\n * @dev Returns the admin role that controls `role`. See {grantRole} and\n * {revokeRole}.\n *\n * To change a role's admin, use {_setRoleAdmin}.\n */\n function getRoleAdmin(bytes32 role) public view virtual override returns (bytes32) {\n return _roles[role].adminRole;\n }\n\n /**\n * @dev Grants `role` to `account`.\n *\n * If `account` had not been already granted `role`, emits a {RoleGranted}\n * event.\n *\n * Requirements:\n *\n * - the caller must have ``role``'s admin role.\n *\n * May emit a {RoleGranted} event.\n */\n function grantRole(bytes32 role, address account) public virtual override onlyRole(getRoleAdmin(role)) {\n _grantRole(role, account);\n }\n\n /**\n * @dev Revokes `role` from `account`.\n *\n * If `account` had been granted `role`, emits a {RoleRevoked} event.\n *\n * Requirements:\n *\n * - the caller must have ``role``'s admin role.\n *\n * May emit a {RoleRevoked} event.\n */\n function revokeRole(bytes32 role, address account) public virtual override onlyRole(getRoleAdmin(role)) {\n _revokeRole(role, account);\n }\n\n /**\n * @dev Revokes `role` from the calling account.\n *\n * Roles are often managed via {grantRole} and {revokeRole}: this function's\n * purpose is to provide a mechanism for accounts to lose their privileges\n * if they are compromised (such as when a trusted device is misplaced).\n *\n * If the calling account had been revoked `role`, emits a {RoleRevoked}\n * event.\n *\n * Requirements:\n *\n * - the caller must be `account`.\n *\n * May emit a {RoleRevoked} event.\n */\n function renounceRole(bytes32 role, address account) public virtual override {\n require(account == _msgSender(), \"AccessControl: can only renounce roles for self\");\n\n _revokeRole(role, account);\n }\n\n /**\n * @dev Grants `role` to `account`.\n *\n * If `account` had not been already granted `role`, emits a {RoleGranted}\n * event. Note that unlike {grantRole}, this function doesn't perform any\n * checks on the calling account.\n *\n * May emit a {RoleGranted} event.\n *\n * [WARNING]\n * ====\n * This function should only be called from the constructor when setting\n * up the initial roles for the system.\n *\n * Using this function in any other way is effectively circumventing the admin\n * system imposed by {AccessControl}.\n * ====\n *\n * NOTE: This function is deprecated in favor of {_grantRole}.\n */\n function _setupRole(bytes32 role, address account) internal virtual {\n _grantRole(role, account);\n }\n\n /**\n * @dev Sets `adminRole` as ``role``'s admin role.\n *\n * Emits a {RoleAdminChanged} event.\n */\n function _setRoleAdmin(bytes32 role, bytes32 adminRole) internal virtual {\n bytes32 previousAdminRole = getRoleAdmin(role);\n _roles[role].adminRole = adminRole;\n emit RoleAdminChanged(role, previousAdminRole, adminRole);\n }\n\n /**\n * @dev Grants `role` to `account`.\n *\n * Internal function without access restriction.\n *\n * May emit a {RoleGranted} event.\n */\n function _grantRole(bytes32 role, address account) internal virtual {\n if (!hasRole(role, account)) {\n _roles[role].members[account] = true;\n emit RoleGranted(role, account, _msgSender());\n }\n }\n\n /**\n * @dev Revokes `role` from `account`.\n *\n * Internal function without access restriction.\n *\n * May emit a {RoleRevoked} event.\n */\n function _revokeRole(bytes32 role, address account) internal virtual {\n if (hasRole(role, account)) {\n _roles[role].members[account] = false;\n emit RoleRevoked(role, account, _msgSender());\n }\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[49] private __gap;\n}\n" + }, + "@openzeppelin/contracts-upgradeable/access/IAccessControlEnumerableUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (access/IAccessControlEnumerable.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./IAccessControlUpgradeable.sol\";\n\n/**\n * @dev External interface of AccessControlEnumerable declared to support ERC165 detection.\n */\ninterface IAccessControlEnumerableUpgradeable is IAccessControlUpgradeable {\n /**\n * @dev Returns one of the accounts that have `role`. `index` must be a\n * value between 0 and {getRoleMemberCount}, non-inclusive.\n *\n * Role bearers are not sorted in any particular way, and their ordering may\n * change at any point.\n *\n * WARNING: When using {getRoleMember} and {getRoleMemberCount}, make sure\n * you perform all queries on the same block. See the following\n * https://forum.openzeppelin.com/t/iterating-over-elements-on-enumerableset-in-openzeppelin-contracts/2296[forum post]\n * for more information.\n */\n function getRoleMember(bytes32 role, uint256 index) external view returns (address);\n\n /**\n * @dev Returns the number of accounts that have `role`. Can be used\n * together with {getRoleMember} to enumerate all bearers of a role.\n */\n function getRoleMemberCount(bytes32 role) external view returns (uint256);\n}\n" + }, + "@openzeppelin/contracts-upgradeable/access/IAccessControlUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (access/IAccessControl.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev External interface of AccessControl declared to support ERC165 detection.\n */\ninterface IAccessControlUpgradeable {\n /**\n * @dev Emitted when `newAdminRole` is set as ``role``'s admin role, replacing `previousAdminRole`\n *\n * `DEFAULT_ADMIN_ROLE` is the starting admin for all roles, despite\n * {RoleAdminChanged} not being emitted signaling this.\n *\n * _Available since v3.1._\n */\n event RoleAdminChanged(bytes32 indexed role, bytes32 indexed previousAdminRole, bytes32 indexed newAdminRole);\n\n /**\n * @dev Emitted when `account` is granted `role`.\n *\n * `sender` is the account that originated the contract call, an admin role\n * bearer except when using {AccessControl-_setupRole}.\n */\n event RoleGranted(bytes32 indexed role, address indexed account, address indexed sender);\n\n /**\n * @dev Emitted when `account` is revoked `role`.\n *\n * `sender` is the account that originated the contract call:\n * - if using `revokeRole`, it is the admin role bearer\n * - if using `renounceRole`, it is the role bearer (i.e. `account`)\n */\n event RoleRevoked(bytes32 indexed role, address indexed account, address indexed sender);\n\n /**\n * @dev Returns `true` if `account` has been granted `role`.\n */\n function hasRole(bytes32 role, address account) external view returns (bool);\n\n /**\n * @dev Returns the admin role that controls `role`. See {grantRole} and\n * {revokeRole}.\n *\n * To change a role's admin, use {AccessControl-_setRoleAdmin}.\n */\n function getRoleAdmin(bytes32 role) external view returns (bytes32);\n\n /**\n * @dev Grants `role` to `account`.\n *\n * If `account` had not been already granted `role`, emits a {RoleGranted}\n * event.\n *\n * Requirements:\n *\n * - the caller must have ``role``'s admin role.\n */\n function grantRole(bytes32 role, address account) external;\n\n /**\n * @dev Revokes `role` from `account`.\n *\n * If `account` had been granted `role`, emits a {RoleRevoked} event.\n *\n * Requirements:\n *\n * - the caller must have ``role``'s admin role.\n */\n function revokeRole(bytes32 role, address account) external;\n\n /**\n * @dev Revokes `role` from the calling account.\n *\n * Roles are often managed via {grantRole} and {revokeRole}: this function's\n * purpose is to provide a mechanism for accounts to lose their privileges\n * if they are compromised (such as when a trusted device is misplaced).\n *\n * If the calling account had been granted `role`, emits a {RoleRevoked}\n * event.\n *\n * Requirements:\n *\n * - the caller must be `account`.\n */\n function renounceRole(bytes32 role, address account) external;\n}\n" + }, + "@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (access/Ownable.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../utils/ContextUpgradeable.sol\";\nimport \"../proxy/utils/Initializable.sol\";\n\n/**\n * @dev Contract module which provides a basic access control mechanism, where\n * there is an account (an owner) that can be granted exclusive access to\n * specific functions.\n *\n * By default, the owner account will be the one that deploys the contract. This\n * can later be changed with {transferOwnership}.\n *\n * This module is used through inheritance. It will make available the modifier\n * `onlyOwner`, which can be applied to your functions to restrict their use to\n * the owner.\n */\nabstract contract OwnableUpgradeable is Initializable, ContextUpgradeable {\n address private _owner;\n\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\n\n /**\n * @dev Initializes the contract setting the deployer as the initial owner.\n */\n function __Ownable_init() internal onlyInitializing {\n __Ownable_init_unchained();\n }\n\n function __Ownable_init_unchained() internal onlyInitializing {\n _transferOwnership(_msgSender());\n }\n\n /**\n * @dev Throws if called by any account other than the owner.\n */\n modifier onlyOwner() {\n _checkOwner();\n _;\n }\n\n /**\n * @dev Returns the address of the current owner.\n */\n function owner() public view virtual returns (address) {\n return _owner;\n }\n\n /**\n * @dev Throws if the sender is not the owner.\n */\n function _checkOwner() internal view virtual {\n require(owner() == _msgSender(), \"Ownable: caller is not the owner\");\n }\n\n /**\n * @dev Leaves the contract without owner. It will not be possible to call\n * `onlyOwner` functions anymore. Can only be called by the current owner.\n *\n * NOTE: Renouncing ownership will leave the contract without an owner,\n * thereby removing any functionality that is only available to the owner.\n */\n function renounceOwnership() public virtual onlyOwner {\n _transferOwnership(address(0));\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Can only be called by the current owner.\n */\n function transferOwnership(address newOwner) public virtual onlyOwner {\n require(newOwner != address(0), \"Ownable: new owner is the zero address\");\n _transferOwnership(newOwner);\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Internal function without access restriction.\n */\n function _transferOwnership(address newOwner) internal virtual {\n address oldOwner = _owner;\n _owner = newOwner;\n emit OwnershipTransferred(oldOwner, newOwner);\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[49] private __gap;\n}\n" + }, + "@openzeppelin/contracts-upgradeable/interfaces/IERC721MetadataUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (interfaces/IERC721Metadata.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../token/ERC721/extensions/IERC721MetadataUpgradeable.sol\";\n" + }, + "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (proxy/utils/Initializable.sol)\n\npragma solidity ^0.8.2;\n\nimport \"../../utils/AddressUpgradeable.sol\";\n\n/**\n * @dev This is a base contract to aid in writing upgradeable contracts, or any kind of contract that will be deployed\n * behind a proxy. Since proxied contracts do not make use of a constructor, it's common to move constructor logic to an\n * external initializer function, usually called `initialize`. It then becomes necessary to protect this initializer\n * function so it can only be called once. The {initializer} modifier provided by this contract will have this effect.\n *\n * The initialization functions use a version number. Once a version number is used, it is consumed and cannot be\n * reused. This mechanism prevents re-execution of each \"step\" but allows the creation of new initialization steps in\n * case an upgrade adds a module that needs to be initialized.\n *\n * For example:\n *\n * [.hljs-theme-light.nopadding]\n * ```\n * contract MyToken is ERC20Upgradeable {\n * function initialize() initializer public {\n * __ERC20_init(\"MyToken\", \"MTK\");\n * }\n * }\n * contract MyTokenV2 is MyToken, ERC20PermitUpgradeable {\n * function initializeV2() reinitializer(2) public {\n * __ERC20Permit_init(\"MyToken\");\n * }\n * }\n * ```\n *\n * TIP: To avoid leaving the proxy in an uninitialized state, the initializer function should be called as early as\n * possible by providing the encoded function call as the `_data` argument to {ERC1967Proxy-constructor}.\n *\n * CAUTION: When used with inheritance, manual care must be taken to not invoke a parent initializer twice, or to ensure\n * that all initializers are idempotent. This is not verified automatically as constructors are by Solidity.\n *\n * [CAUTION]\n * ====\n * Avoid leaving a contract uninitialized.\n *\n * An uninitialized contract can be taken over by an attacker. This applies to both a proxy and its implementation\n * contract, which may impact the proxy. To prevent the implementation contract from being used, you should invoke\n * the {_disableInitializers} function in the constructor to automatically lock it when it is deployed:\n *\n * [.hljs-theme-light.nopadding]\n * ```\n * /// @custom:oz-upgrades-unsafe-allow constructor\n * constructor() {\n * _disableInitializers();\n * }\n * ```\n * ====\n */\nabstract contract Initializable {\n /**\n * @dev Indicates that the contract has been initialized.\n * @custom:oz-retyped-from bool\n */\n uint8 private _initialized;\n\n /**\n * @dev Indicates that the contract is in the process of being initialized.\n */\n bool private _initializing;\n\n /**\n * @dev Triggered when the contract has been initialized or reinitialized.\n */\n event Initialized(uint8 version);\n\n /**\n * @dev A modifier that defines a protected initializer function that can be invoked at most once. In its scope,\n * `onlyInitializing` functions can be used to initialize parent contracts. Equivalent to `reinitializer(1)`.\n */\n modifier initializer() {\n bool isTopLevelCall = !_initializing;\n require(\n (isTopLevelCall && _initialized < 1) || (!AddressUpgradeable.isContract(address(this)) && _initialized == 1),\n \"Initializable: contract is already initialized\"\n );\n _initialized = 1;\n if (isTopLevelCall) {\n _initializing = true;\n }\n _;\n if (isTopLevelCall) {\n _initializing = false;\n emit Initialized(1);\n }\n }\n\n /**\n * @dev A modifier that defines a protected reinitializer function that can be invoked at most once, and only if the\n * contract hasn't been initialized to a greater version before. In its scope, `onlyInitializing` functions can be\n * used to initialize parent contracts.\n *\n * `initializer` is equivalent to `reinitializer(1)`, so a reinitializer may be used after the original\n * initialization step. This is essential to configure modules that are added through upgrades and that require\n * initialization.\n *\n * Note that versions can jump in increments greater than 1; this implies that if multiple reinitializers coexist in\n * a contract, executing them in the right order is up to the developer or operator.\n */\n modifier reinitializer(uint8 version) {\n require(!_initializing && _initialized < version, \"Initializable: contract is already initialized\");\n _initialized = version;\n _initializing = true;\n _;\n _initializing = false;\n emit Initialized(version);\n }\n\n /**\n * @dev Modifier to protect an initialization function so that it can only be invoked by functions with the\n * {initializer} and {reinitializer} modifiers, directly or indirectly.\n */\n modifier onlyInitializing() {\n require(_initializing, \"Initializable: contract is not initializing\");\n _;\n }\n\n /**\n * @dev Locks the contract, preventing any future reinitialization. This cannot be part of an initializer call.\n * Calling this in the constructor of a contract will prevent that contract from being initialized or reinitialized\n * to any version. It is recommended to use this to lock implementation contracts that are designed to be called\n * through proxies.\n */\n function _disableInitializers() internal virtual {\n require(!_initializing, \"Initializable: contract is initializing\");\n if (_initialized < type(uint8).max) {\n _initialized = type(uint8).max;\n emit Initialized(type(uint8).max);\n }\n }\n}\n" + }, + "@openzeppelin/contracts-upgradeable/security/PausableUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (security/Pausable.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../utils/ContextUpgradeable.sol\";\nimport \"../proxy/utils/Initializable.sol\";\n\n/**\n * @dev Contract module which allows children to implement an emergency stop\n * mechanism that can be triggered by an authorized account.\n *\n * This module is used through inheritance. It will make available the\n * modifiers `whenNotPaused` and `whenPaused`, which can be applied to\n * the functions of your contract. Note that they will not be pausable by\n * simply including this module, only once the modifiers are put in place.\n */\nabstract contract PausableUpgradeable is Initializable, ContextUpgradeable {\n /**\n * @dev Emitted when the pause is triggered by `account`.\n */\n event Paused(address account);\n\n /**\n * @dev Emitted when the pause is lifted by `account`.\n */\n event Unpaused(address account);\n\n bool private _paused;\n\n /**\n * @dev Initializes the contract in unpaused state.\n */\n function __Pausable_init() internal onlyInitializing {\n __Pausable_init_unchained();\n }\n\n function __Pausable_init_unchained() internal onlyInitializing {\n _paused = false;\n }\n\n /**\n * @dev Modifier to make a function callable only when the contract is not paused.\n *\n * Requirements:\n *\n * - The contract must not be paused.\n */\n modifier whenNotPaused() {\n _requireNotPaused();\n _;\n }\n\n /**\n * @dev Modifier to make a function callable only when the contract is paused.\n *\n * Requirements:\n *\n * - The contract must be paused.\n */\n modifier whenPaused() {\n _requirePaused();\n _;\n }\n\n /**\n * @dev Returns true if the contract is paused, and false otherwise.\n */\n function paused() public view virtual returns (bool) {\n return _paused;\n }\n\n /**\n * @dev Throws if the contract is paused.\n */\n function _requireNotPaused() internal view virtual {\n require(!paused(), \"Pausable: paused\");\n }\n\n /**\n * @dev Throws if the contract is not paused.\n */\n function _requirePaused() internal view virtual {\n require(paused(), \"Pausable: not paused\");\n }\n\n /**\n * @dev Triggers stopped state.\n *\n * Requirements:\n *\n * - The contract must not be paused.\n */\n function _pause() internal virtual whenNotPaused {\n _paused = true;\n emit Paused(_msgSender());\n }\n\n /**\n * @dev Returns to normal state.\n *\n * Requirements:\n *\n * - The contract must be paused.\n */\n function _unpause() internal virtual whenPaused {\n _paused = false;\n emit Unpaused(_msgSender());\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[49] private __gap;\n}\n" + }, + "@openzeppelin/contracts-upgradeable/security/ReentrancyGuardUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (security/ReentrancyGuard.sol)\n\npragma solidity ^0.8.0;\nimport \"../proxy/utils/Initializable.sol\";\n\n/**\n * @dev Contract module that helps prevent reentrant calls to a function.\n *\n * Inheriting from `ReentrancyGuard` will make the {nonReentrant} modifier\n * available, which can be applied to functions to make sure there are no nested\n * (reentrant) calls to them.\n *\n * Note that because there is a single `nonReentrant` guard, functions marked as\n * `nonReentrant` may not call one another. This can be worked around by making\n * those functions `private`, and then adding `external` `nonReentrant` entry\n * points to them.\n *\n * TIP: If you would like to learn more about reentrancy and alternative ways\n * to protect against it, check out our blog post\n * https://blog.openzeppelin.com/reentrancy-after-istanbul/[Reentrancy After Istanbul].\n */\nabstract contract ReentrancyGuardUpgradeable is Initializable {\n // Booleans are more expensive than uint256 or any type that takes up a full\n // word because each write operation emits an extra SLOAD to first read the\n // slot's contents, replace the bits taken up by the boolean, and then write\n // back. This is the compiler's defense against contract upgrades and\n // pointer aliasing, and it cannot be disabled.\n\n // The values being non-zero value makes deployment a bit more expensive,\n // but in exchange the refund on every call to nonReentrant will be lower in\n // amount. Since refunds are capped to a percentage of the total\n // transaction's gas, it is best to keep them low in cases like this one, to\n // increase the likelihood of the full refund coming into effect.\n uint256 private constant _NOT_ENTERED = 1;\n uint256 private constant _ENTERED = 2;\n\n uint256 private _status;\n\n function __ReentrancyGuard_init() internal onlyInitializing {\n __ReentrancyGuard_init_unchained();\n }\n\n function __ReentrancyGuard_init_unchained() internal onlyInitializing {\n _status = _NOT_ENTERED;\n }\n\n /**\n * @dev Prevents a contract from calling itself, directly or indirectly.\n * Calling a `nonReentrant` function from another `nonReentrant`\n * function is not supported. It is possible to prevent this from happening\n * by making the `nonReentrant` function external, and making it call a\n * `private` function that does the actual work.\n */\n modifier nonReentrant() {\n // On the first call to nonReentrant, _notEntered will be true\n require(_status != _ENTERED, \"ReentrancyGuard: reentrant call\");\n\n // Any calls to nonReentrant after this point will fail\n _status = _ENTERED;\n\n _;\n\n // By storing the original value once again, a refund is triggered (see\n // https://eips.ethereum.org/EIPS/eip-2200)\n _status = _NOT_ENTERED;\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[49] private __gap;\n}\n" + }, + "@openzeppelin/contracts-upgradeable/token/ERC20/ERC20Upgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (token/ERC20/ERC20.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./IERC20Upgradeable.sol\";\nimport \"./extensions/IERC20MetadataUpgradeable.sol\";\nimport \"../../utils/ContextUpgradeable.sol\";\nimport \"../../proxy/utils/Initializable.sol\";\n\n/**\n * @dev Implementation of the {IERC20} interface.\n *\n * This implementation is agnostic to the way tokens are created. This means\n * that a supply mechanism has to be added in a derived contract using {_mint}.\n * For a generic mechanism see {ERC20PresetMinterPauser}.\n *\n * TIP: For a detailed writeup see our guide\n * https://forum.zeppelin.solutions/t/how-to-implement-erc20-supply-mechanisms/226[How\n * to implement supply mechanisms].\n *\n * We have followed general OpenZeppelin Contracts guidelines: functions revert\n * instead returning `false` on failure. This behavior is nonetheless\n * conventional and does not conflict with the expectations of ERC20\n * applications.\n *\n * Additionally, an {Approval} event is emitted on calls to {transferFrom}.\n * This allows applications to reconstruct the allowance for all accounts just\n * by listening to said events. Other implementations of the EIP may not emit\n * these events, as it isn't required by the specification.\n *\n * Finally, the non-standard {decreaseAllowance} and {increaseAllowance}\n * functions have been added to mitigate the well-known issues around setting\n * allowances. See {IERC20-approve}.\n */\ncontract ERC20Upgradeable is Initializable, ContextUpgradeable, IERC20Upgradeable, IERC20MetadataUpgradeable {\n mapping(address => uint256) private _balances;\n\n mapping(address => mapping(address => uint256)) private _allowances;\n\n uint256 private _totalSupply;\n\n string private _name;\n string private _symbol;\n\n /**\n * @dev Sets the values for {name} and {symbol}.\n *\n * The default value of {decimals} is 18. To select a different value for\n * {decimals} you should overload it.\n *\n * All two of these values are immutable: they can only be set once during\n * construction.\n */\n function __ERC20_init(string memory name_, string memory symbol_) internal onlyInitializing {\n __ERC20_init_unchained(name_, symbol_);\n }\n\n function __ERC20_init_unchained(string memory name_, string memory symbol_) internal onlyInitializing {\n _name = name_;\n _symbol = symbol_;\n }\n\n /**\n * @dev Returns the name of the token.\n */\n function name() public view virtual override returns (string memory) {\n return _name;\n }\n\n /**\n * @dev Returns the symbol of the token, usually a shorter version of the\n * name.\n */\n function symbol() public view virtual override returns (string memory) {\n return _symbol;\n }\n\n /**\n * @dev Returns the number of decimals used to get its user representation.\n * For example, if `decimals` equals `2`, a balance of `505` tokens should\n * be displayed to a user as `5.05` (`505 / 10 ** 2`).\n *\n * Tokens usually opt for a value of 18, imitating the relationship between\n * Ether and Wei. This is the value {ERC20} uses, unless this function is\n * overridden;\n *\n * NOTE: This information is only used for _display_ purposes: it in\n * no way affects any of the arithmetic of the contract, including\n * {IERC20-balanceOf} and {IERC20-transfer}.\n */\n function decimals() public view virtual override returns (uint8) {\n return 18;\n }\n\n /**\n * @dev See {IERC20-totalSupply}.\n */\n function totalSupply() public view virtual override returns (uint256) {\n return _totalSupply;\n }\n\n /**\n * @dev See {IERC20-balanceOf}.\n */\n function balanceOf(address account) public view virtual override returns (uint256) {\n return _balances[account];\n }\n\n /**\n * @dev See {IERC20-transfer}.\n *\n * Requirements:\n *\n * - `to` cannot be the zero address.\n * - the caller must have a balance of at least `amount`.\n */\n function transfer(address to, uint256 amount) public virtual override returns (bool) {\n address owner = _msgSender();\n _transfer(owner, to, amount);\n return true;\n }\n\n /**\n * @dev See {IERC20-allowance}.\n */\n function allowance(address owner, address spender) public view virtual override returns (uint256) {\n return _allowances[owner][spender];\n }\n\n /**\n * @dev See {IERC20-approve}.\n *\n * NOTE: If `amount` is the maximum `uint256`, the allowance is not updated on\n * `transferFrom`. This is semantically equivalent to an infinite approval.\n *\n * Requirements:\n *\n * - `spender` cannot be the zero address.\n */\n function approve(address spender, uint256 amount) public virtual override returns (bool) {\n address owner = _msgSender();\n _approve(owner, spender, amount);\n return true;\n }\n\n /**\n * @dev See {IERC20-transferFrom}.\n *\n * Emits an {Approval} event indicating the updated allowance. This is not\n * required by the EIP. See the note at the beginning of {ERC20}.\n *\n * NOTE: Does not update the allowance if the current allowance\n * is the maximum `uint256`.\n *\n * Requirements:\n *\n * - `from` and `to` cannot be the zero address.\n * - `from` must have a balance of at least `amount`.\n * - the caller must have allowance for ``from``'s tokens of at least\n * `amount`.\n */\n function transferFrom(\n address from,\n address to,\n uint256 amount\n ) public virtual override returns (bool) {\n address spender = _msgSender();\n _spendAllowance(from, spender, amount);\n _transfer(from, to, amount);\n return true;\n }\n\n /**\n * @dev Atomically increases the allowance granted to `spender` by the caller.\n *\n * This is an alternative to {approve} that can be used as a mitigation for\n * problems described in {IERC20-approve}.\n *\n * Emits an {Approval} event indicating the updated allowance.\n *\n * Requirements:\n *\n * - `spender` cannot be the zero address.\n */\n function increaseAllowance(address spender, uint256 addedValue) public virtual returns (bool) {\n address owner = _msgSender();\n _approve(owner, spender, allowance(owner, spender) + addedValue);\n return true;\n }\n\n /**\n * @dev Atomically decreases the allowance granted to `spender` by the caller.\n *\n * This is an alternative to {approve} that can be used as a mitigation for\n * problems described in {IERC20-approve}.\n *\n * Emits an {Approval} event indicating the updated allowance.\n *\n * Requirements:\n *\n * - `spender` cannot be the zero address.\n * - `spender` must have allowance for the caller of at least\n * `subtractedValue`.\n */\n function decreaseAllowance(address spender, uint256 subtractedValue) public virtual returns (bool) {\n address owner = _msgSender();\n uint256 currentAllowance = allowance(owner, spender);\n require(currentAllowance >= subtractedValue, \"ERC20: decreased allowance below zero\");\n unchecked {\n _approve(owner, spender, currentAllowance - subtractedValue);\n }\n\n return true;\n }\n\n /**\n * @dev Moves `amount` of tokens from `from` to `to`.\n *\n * This internal function is equivalent to {transfer}, and can be used to\n * e.g. implement automatic token fees, slashing mechanisms, etc.\n *\n * Emits a {Transfer} event.\n *\n * Requirements:\n *\n * - `from` cannot be the zero address.\n * - `to` cannot be the zero address.\n * - `from` must have a balance of at least `amount`.\n */\n function _transfer(\n address from,\n address to,\n uint256 amount\n ) internal virtual {\n require(from != address(0), \"ERC20: transfer from the zero address\");\n require(to != address(0), \"ERC20: transfer to the zero address\");\n\n _beforeTokenTransfer(from, to, amount);\n\n uint256 fromBalance = _balances[from];\n require(fromBalance >= amount, \"ERC20: transfer amount exceeds balance\");\n unchecked {\n _balances[from] = fromBalance - amount;\n }\n _balances[to] += amount;\n\n emit Transfer(from, to, amount);\n\n _afterTokenTransfer(from, to, amount);\n }\n\n /** @dev Creates `amount` tokens and assigns them to `account`, increasing\n * the total supply.\n *\n * Emits a {Transfer} event with `from` set to the zero address.\n *\n * Requirements:\n *\n * - `account` cannot be the zero address.\n */\n function _mint(address account, uint256 amount) internal virtual {\n require(account != address(0), \"ERC20: mint to the zero address\");\n\n _beforeTokenTransfer(address(0), account, amount);\n\n _totalSupply += amount;\n _balances[account] += amount;\n emit Transfer(address(0), account, amount);\n\n _afterTokenTransfer(address(0), account, amount);\n }\n\n /**\n * @dev Destroys `amount` tokens from `account`, reducing the\n * total supply.\n *\n * Emits a {Transfer} event with `to` set to the zero address.\n *\n * Requirements:\n *\n * - `account` cannot be the zero address.\n * - `account` must have at least `amount` tokens.\n */\n function _burn(address account, uint256 amount) internal virtual {\n require(account != address(0), \"ERC20: burn from the zero address\");\n\n _beforeTokenTransfer(account, address(0), amount);\n\n uint256 accountBalance = _balances[account];\n require(accountBalance >= amount, \"ERC20: burn amount exceeds balance\");\n unchecked {\n _balances[account] = accountBalance - amount;\n }\n _totalSupply -= amount;\n\n emit Transfer(account, address(0), amount);\n\n _afterTokenTransfer(account, address(0), amount);\n }\n\n /**\n * @dev Sets `amount` as the allowance of `spender` over the `owner` s tokens.\n *\n * This internal function is equivalent to `approve`, and can be used to\n * e.g. set automatic allowances for certain subsystems, etc.\n *\n * Emits an {Approval} event.\n *\n * Requirements:\n *\n * - `owner` cannot be the zero address.\n * - `spender` cannot be the zero address.\n */\n function _approve(\n address owner,\n address spender,\n uint256 amount\n ) internal virtual {\n require(owner != address(0), \"ERC20: approve from the zero address\");\n require(spender != address(0), \"ERC20: approve to the zero address\");\n\n _allowances[owner][spender] = amount;\n emit Approval(owner, spender, amount);\n }\n\n /**\n * @dev Updates `owner` s allowance for `spender` based on spent `amount`.\n *\n * Does not update the allowance amount in case of infinite allowance.\n * Revert if not enough allowance is available.\n *\n * Might emit an {Approval} event.\n */\n function _spendAllowance(\n address owner,\n address spender,\n uint256 amount\n ) internal virtual {\n uint256 currentAllowance = allowance(owner, spender);\n if (currentAllowance != type(uint256).max) {\n require(currentAllowance >= amount, \"ERC20: insufficient allowance\");\n unchecked {\n _approve(owner, spender, currentAllowance - amount);\n }\n }\n }\n\n /**\n * @dev Hook that is called before any transfer of tokens. This includes\n * minting and burning.\n *\n * Calling conditions:\n *\n * - when `from` and `to` are both non-zero, `amount` of ``from``'s tokens\n * will be transferred to `to`.\n * - when `from` is zero, `amount` tokens will be minted for `to`.\n * - when `to` is zero, `amount` of ``from``'s tokens will be burned.\n * - `from` and `to` are never both zero.\n *\n * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].\n */\n function _beforeTokenTransfer(\n address from,\n address to,\n uint256 amount\n ) internal virtual {}\n\n /**\n * @dev Hook that is called after any transfer of tokens. This includes\n * minting and burning.\n *\n * Calling conditions:\n *\n * - when `from` and `to` are both non-zero, `amount` of ``from``'s tokens\n * has been transferred to `to`.\n * - when `from` is zero, `amount` tokens have been minted for `to`.\n * - when `to` is zero, `amount` of ``from``'s tokens have been burned.\n * - `from` and `to` are never both zero.\n *\n * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].\n */\n function _afterTokenTransfer(\n address from,\n address to,\n uint256 amount\n ) internal virtual {}\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[45] private __gap;\n}\n" + }, + "@openzeppelin/contracts-upgradeable/token/ERC20/extensions/draft-ERC20PermitUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.6.0) (token/ERC20/extensions/draft-ERC20Permit.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./draft-IERC20PermitUpgradeable.sol\";\nimport \"../ERC20Upgradeable.sol\";\nimport \"../../../utils/cryptography/draft-EIP712Upgradeable.sol\";\nimport \"../../../utils/cryptography/ECDSAUpgradeable.sol\";\nimport \"../../../utils/CountersUpgradeable.sol\";\nimport \"../../../proxy/utils/Initializable.sol\";\n\n/**\n * @dev Implementation of the ERC20 Permit extension allowing approvals to be made via signatures, as defined in\n * https://eips.ethereum.org/EIPS/eip-2612[EIP-2612].\n *\n * Adds the {permit} method, which can be used to change an account's ERC20 allowance (see {IERC20-allowance}) by\n * presenting a message signed by the account. By not relying on `{IERC20-approve}`, the token holder account doesn't\n * need to send a transaction, and thus is not required to hold Ether at all.\n *\n * _Available since v3.4._\n *\n * @custom:storage-size 51\n */\nabstract contract ERC20PermitUpgradeable is Initializable, ERC20Upgradeable, IERC20PermitUpgradeable, EIP712Upgradeable {\n using CountersUpgradeable for CountersUpgradeable.Counter;\n\n mapping(address => CountersUpgradeable.Counter) private _nonces;\n\n // solhint-disable-next-line var-name-mixedcase\n bytes32 private constant _PERMIT_TYPEHASH =\n keccak256(\"Permit(address owner,address spender,uint256 value,uint256 nonce,uint256 deadline)\");\n /**\n * @dev In previous versions `_PERMIT_TYPEHASH` was declared as `immutable`.\n * However, to ensure consistency with the upgradeable transpiler, we will continue\n * to reserve a slot.\n * @custom:oz-renamed-from _PERMIT_TYPEHASH\n */\n // solhint-disable-next-line var-name-mixedcase\n bytes32 private _PERMIT_TYPEHASH_DEPRECATED_SLOT;\n\n /**\n * @dev Initializes the {EIP712} domain separator using the `name` parameter, and setting `version` to `\"1\"`.\n *\n * It's a good idea to use the same `name` that is defined as the ERC20 token name.\n */\n function __ERC20Permit_init(string memory name) internal onlyInitializing {\n __EIP712_init_unchained(name, \"1\");\n }\n\n function __ERC20Permit_init_unchained(string memory) internal onlyInitializing {}\n\n /**\n * @dev See {IERC20Permit-permit}.\n */\n function permit(\n address owner,\n address spender,\n uint256 value,\n uint256 deadline,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) public virtual override {\n require(block.timestamp <= deadline, \"ERC20Permit: expired deadline\");\n\n bytes32 structHash = keccak256(abi.encode(_PERMIT_TYPEHASH, owner, spender, value, _useNonce(owner), deadline));\n\n bytes32 hash = _hashTypedDataV4(structHash);\n\n address signer = ECDSAUpgradeable.recover(hash, v, r, s);\n require(signer == owner, \"ERC20Permit: invalid signature\");\n\n _approve(owner, spender, value);\n }\n\n /**\n * @dev See {IERC20Permit-nonces}.\n */\n function nonces(address owner) public view virtual override returns (uint256) {\n return _nonces[owner].current();\n }\n\n /**\n * @dev See {IERC20Permit-DOMAIN_SEPARATOR}.\n */\n // solhint-disable-next-line func-name-mixedcase\n function DOMAIN_SEPARATOR() external view override returns (bytes32) {\n return _domainSeparatorV4();\n }\n\n /**\n * @dev \"Consume a nonce\": return the current value and increment.\n *\n * _Available since v4.1._\n */\n function _useNonce(address owner) internal virtual returns (uint256 current) {\n CountersUpgradeable.Counter storage nonce = _nonces[owner];\n current = nonce.current();\n nonce.increment();\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[49] private __gap;\n}\n" + }, + "@openzeppelin/contracts-upgradeable/token/ERC20/extensions/draft-IERC20PermitUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (token/ERC20/extensions/draft-IERC20Permit.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Interface of the ERC20 Permit extension allowing approvals to be made via signatures, as defined in\n * https://eips.ethereum.org/EIPS/eip-2612[EIP-2612].\n *\n * Adds the {permit} method, which can be used to change an account's ERC20 allowance (see {IERC20-allowance}) by\n * presenting a message signed by the account. By not relying on {IERC20-approve}, the token holder account doesn't\n * need to send a transaction, and thus is not required to hold Ether at all.\n */\ninterface IERC20PermitUpgradeable {\n /**\n * @dev Sets `value` as the allowance of `spender` over ``owner``'s tokens,\n * given ``owner``'s signed approval.\n *\n * IMPORTANT: The same issues {IERC20-approve} has related to transaction\n * ordering also apply here.\n *\n * Emits an {Approval} event.\n *\n * Requirements:\n *\n * - `spender` cannot be the zero address.\n * - `deadline` must be a timestamp in the future.\n * - `v`, `r` and `s` must be a valid `secp256k1` signature from `owner`\n * over the EIP712-formatted function arguments.\n * - the signature must use ``owner``'s current nonce (see {nonces}).\n *\n * For more information on the signature format, see the\n * https://eips.ethereum.org/EIPS/eip-2612#specification[relevant EIP\n * section].\n */\n function permit(\n address owner,\n address spender,\n uint256 value,\n uint256 deadline,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) external;\n\n /**\n * @dev Returns the current nonce for `owner`. This value must be\n * included whenever a signature is generated for {permit}.\n *\n * Every successful call to {permit} increases ``owner``'s nonce by one. This\n * prevents a signature from being used multiple times.\n */\n function nonces(address owner) external view returns (uint256);\n\n /**\n * @dev Returns the domain separator used in the encoding of the signature for {permit}, as defined by {EIP712}.\n */\n // solhint-disable-next-line func-name-mixedcase\n function DOMAIN_SEPARATOR() external view returns (bytes32);\n}\n" + }, + "@openzeppelin/contracts-upgradeable/token/ERC20/extensions/IERC20MetadataUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (token/ERC20/extensions/IERC20Metadata.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../IERC20Upgradeable.sol\";\n\n/**\n * @dev Interface for the optional metadata functions from the ERC20 standard.\n *\n * _Available since v4.1._\n */\ninterface IERC20MetadataUpgradeable is IERC20Upgradeable {\n /**\n * @dev Returns the name of the token.\n */\n function name() external view returns (string memory);\n\n /**\n * @dev Returns the symbol of the token.\n */\n function symbol() external view returns (string memory);\n\n /**\n * @dev Returns the decimals places of the token.\n */\n function decimals() external view returns (uint8);\n}\n" + }, + "@openzeppelin/contracts-upgradeable/token/ERC20/IERC20Upgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.6.0) (token/ERC20/IERC20.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Interface of the ERC20 standard as defined in the EIP.\n */\ninterface IERC20Upgradeable {\n /**\n * @dev Emitted when `value` tokens are moved from one account (`from`) to\n * another (`to`).\n *\n * Note that `value` may be zero.\n */\n event Transfer(address indexed from, address indexed to, uint256 value);\n\n /**\n * @dev Emitted when the allowance of a `spender` for an `owner` is set by\n * a call to {approve}. `value` is the new allowance.\n */\n event Approval(address indexed owner, address indexed spender, uint256 value);\n\n /**\n * @dev Returns the amount of tokens in existence.\n */\n function totalSupply() external view returns (uint256);\n\n /**\n * @dev Returns the amount of tokens owned by `account`.\n */\n function balanceOf(address account) external view returns (uint256);\n\n /**\n * @dev Moves `amount` tokens from the caller's account to `to`.\n *\n * Returns a boolean value indicating whether the operation succeeded.\n *\n * Emits a {Transfer} event.\n */\n function transfer(address to, uint256 amount) external returns (bool);\n\n /**\n * @dev Returns the remaining number of tokens that `spender` will be\n * allowed to spend on behalf of `owner` through {transferFrom}. This is\n * zero by default.\n *\n * This value changes when {approve} or {transferFrom} are called.\n */\n function allowance(address owner, address spender) external view returns (uint256);\n\n /**\n * @dev Sets `amount` as the allowance of `spender` over the caller's tokens.\n *\n * Returns a boolean value indicating whether the operation succeeded.\n *\n * IMPORTANT: Beware that changing an allowance with this method brings the risk\n * that someone may use both the old and the new allowance by unfortunate\n * transaction ordering. One possible solution to mitigate this race\n * condition is to first reduce the spender's allowance to 0 and set the\n * desired value afterwards:\n * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729\n *\n * Emits an {Approval} event.\n */\n function approve(address spender, uint256 amount) external returns (bool);\n\n /**\n * @dev Moves `amount` tokens from `from` to `to` using the\n * allowance mechanism. `amount` is then deducted from the caller's\n * allowance.\n *\n * Returns a boolean value indicating whether the operation succeeded.\n *\n * Emits a {Transfer} event.\n */\n function transferFrom(\n address from,\n address to,\n uint256 amount\n ) external returns (bool);\n}\n" + }, + "@openzeppelin/contracts-upgradeable/token/ERC721/extensions/IERC721MetadataUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (token/ERC721/extensions/IERC721Metadata.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../IERC721Upgradeable.sol\";\n\n/**\n * @title ERC-721 Non-Fungible Token Standard, optional metadata extension\n * @dev See https://eips.ethereum.org/EIPS/eip-721\n */\ninterface IERC721MetadataUpgradeable is IERC721Upgradeable {\n /**\n * @dev Returns the token collection name.\n */\n function name() external view returns (string memory);\n\n /**\n * @dev Returns the token collection symbol.\n */\n function symbol() external view returns (string memory);\n\n /**\n * @dev Returns the Uniform Resource Identifier (URI) for `tokenId` token.\n */\n function tokenURI(uint256 tokenId) external view returns (string memory);\n}\n" + }, + "@openzeppelin/contracts-upgradeable/token/ERC721/IERC721ReceiverUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.6.0) (token/ERC721/IERC721Receiver.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @title ERC721 token receiver interface\n * @dev Interface for any contract that wants to support safeTransfers\n * from ERC721 asset contracts.\n */\ninterface IERC721ReceiverUpgradeable {\n /**\n * @dev Whenever an {IERC721} `tokenId` token is transferred to this contract via {IERC721-safeTransferFrom}\n * by `operator` from `from`, this function is called.\n *\n * It must return its Solidity selector to confirm the token transfer.\n * If any other value is returned or the interface is not implemented by the recipient, the transfer will be reverted.\n *\n * The selector can be obtained in Solidity with `IERC721Receiver.onERC721Received.selector`.\n */\n function onERC721Received(\n address operator,\n address from,\n uint256 tokenId,\n bytes calldata data\n ) external returns (bytes4);\n}\n" + }, + "@openzeppelin/contracts-upgradeable/token/ERC721/IERC721Upgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (token/ERC721/IERC721.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../../utils/introspection/IERC165Upgradeable.sol\";\n\n/**\n * @dev Required interface of an ERC721 compliant contract.\n */\ninterface IERC721Upgradeable is IERC165Upgradeable {\n /**\n * @dev Emitted when `tokenId` token is transferred from `from` to `to`.\n */\n event Transfer(address indexed from, address indexed to, uint256 indexed tokenId);\n\n /**\n * @dev Emitted when `owner` enables `approved` to manage the `tokenId` token.\n */\n event Approval(address indexed owner, address indexed approved, uint256 indexed tokenId);\n\n /**\n * @dev Emitted when `owner` enables or disables (`approved`) `operator` to manage all of its assets.\n */\n event ApprovalForAll(address indexed owner, address indexed operator, bool approved);\n\n /**\n * @dev Returns the number of tokens in ``owner``'s account.\n */\n function balanceOf(address owner) external view returns (uint256 balance);\n\n /**\n * @dev Returns the owner of the `tokenId` token.\n *\n * Requirements:\n *\n * - `tokenId` must exist.\n */\n function ownerOf(uint256 tokenId) external view returns (address owner);\n\n /**\n * @dev Safely transfers `tokenId` token from `from` to `to`.\n *\n * Requirements:\n *\n * - `from` cannot be the zero address.\n * - `to` cannot be the zero address.\n * - `tokenId` token must exist and be owned by `from`.\n * - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}.\n * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.\n *\n * Emits a {Transfer} event.\n */\n function safeTransferFrom(\n address from,\n address to,\n uint256 tokenId,\n bytes calldata data\n ) external;\n\n /**\n * @dev Safely transfers `tokenId` token from `from` to `to`, checking first that contract recipients\n * are aware of the ERC721 protocol to prevent tokens from being forever locked.\n *\n * Requirements:\n *\n * - `from` cannot be the zero address.\n * - `to` cannot be the zero address.\n * - `tokenId` token must exist and be owned by `from`.\n * - If the caller is not `from`, it must have been allowed to move this token by either {approve} or {setApprovalForAll}.\n * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.\n *\n * Emits a {Transfer} event.\n */\n function safeTransferFrom(\n address from,\n address to,\n uint256 tokenId\n ) external;\n\n /**\n * @dev Transfers `tokenId` token from `from` to `to`.\n *\n * WARNING: Usage of this method is discouraged, use {safeTransferFrom} whenever possible.\n *\n * Requirements:\n *\n * - `from` cannot be the zero address.\n * - `to` cannot be the zero address.\n * - `tokenId` token must be owned by `from`.\n * - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}.\n *\n * Emits a {Transfer} event.\n */\n function transferFrom(\n address from,\n address to,\n uint256 tokenId\n ) external;\n\n /**\n * @dev Gives permission to `to` to transfer `tokenId` token to another account.\n * The approval is cleared when the token is transferred.\n *\n * Only a single account can be approved at a time, so approving the zero address clears previous approvals.\n *\n * Requirements:\n *\n * - The caller must own the token or be an approved operator.\n * - `tokenId` must exist.\n *\n * Emits an {Approval} event.\n */\n function approve(address to, uint256 tokenId) external;\n\n /**\n * @dev Approve or remove `operator` as an operator for the caller.\n * Operators can call {transferFrom} or {safeTransferFrom} for any token owned by the caller.\n *\n * Requirements:\n *\n * - The `operator` cannot be the caller.\n *\n * Emits an {ApprovalForAll} event.\n */\n function setApprovalForAll(address operator, bool _approved) external;\n\n /**\n * @dev Returns the account approved for `tokenId` token.\n *\n * Requirements:\n *\n * - `tokenId` must exist.\n */\n function getApproved(uint256 tokenId) external view returns (address operator);\n\n /**\n * @dev Returns if the `operator` is allowed to manage all of the assets of `owner`.\n *\n * See {setApprovalForAll}\n */\n function isApprovedForAll(address owner, address operator) external view returns (bool);\n}\n" + }, + "@openzeppelin/contracts-upgradeable/utils/AddressUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (utils/Address.sol)\n\npragma solidity ^0.8.1;\n\n/**\n * @dev Collection of functions related to the address type\n */\nlibrary AddressUpgradeable {\n /**\n * @dev Returns true if `account` is a contract.\n *\n * [IMPORTANT]\n * ====\n * It is unsafe to assume that an address for which this function returns\n * false is an externally-owned account (EOA) and not a contract.\n *\n * Among others, `isContract` will return false for the following\n * types of addresses:\n *\n * - an externally-owned account\n * - a contract in construction\n * - an address where a contract will be created\n * - an address where a contract lived, but was destroyed\n * ====\n *\n * [IMPORTANT]\n * ====\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\n *\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\n * constructor.\n * ====\n */\n function isContract(address account) internal view returns (bool) {\n // This method relies on extcodesize/address.code.length, which returns 0\n // for contracts in construction, since the code is only stored at the end\n // of the constructor execution.\n\n return account.code.length > 0;\n }\n\n /**\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\n * `recipient`, forwarding all available gas and reverting on errors.\n *\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\n * imposed by `transfer`, making them unable to receive funds via\n * `transfer`. {sendValue} removes this limitation.\n *\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\n *\n * IMPORTANT: because control is transferred to `recipient`, care must be\n * taken to not create reentrancy vulnerabilities. Consider using\n * {ReentrancyGuard} or the\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\n */\n function sendValue(address payable recipient, uint256 amount) internal {\n require(address(this).balance >= amount, \"Address: insufficient balance\");\n\n (bool success, ) = recipient.call{value: amount}(\"\");\n require(success, \"Address: unable to send value, recipient may have reverted\");\n }\n\n /**\n * @dev Performs a Solidity function call using a low level `call`. A\n * plain `call` is an unsafe replacement for a function call: use this\n * function instead.\n *\n * If `target` reverts with a revert reason, it is bubbled up by this\n * function (like regular Solidity function calls).\n *\n * Returns the raw returned data. To convert to the expected return value,\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\n *\n * Requirements:\n *\n * - `target` must be a contract.\n * - calling `target` with `data` must not revert.\n *\n * _Available since v3.1._\n */\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionCall(target, data, \"Address: low-level call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\n * `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, 0, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but also transferring `value` wei to `target`.\n *\n * Requirements:\n *\n * - the calling contract must have an ETH balance of at least `value`.\n * - the called Solidity function must be `payable`.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, value, \"Address: low-level call with value failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\n * with `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(address(this).balance >= value, \"Address: insufficient balance for call\");\n require(isContract(target), \"Address: call to non-contract\");\n\n (bool success, bytes memory returndata) = target.call{value: value}(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\n return functionStaticCall(target, data, \"Address: low-level static call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal view returns (bytes memory) {\n require(isContract(target), \"Address: static call to non-contract\");\n\n (bool success, bytes memory returndata) = target.staticcall(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the\n * revert reason using the provided one.\n *\n * _Available since v4.3._\n */\n function verifyCallResult(\n bool success,\n bytes memory returndata,\n string memory errorMessage\n ) internal pure returns (bytes memory) {\n if (success) {\n return returndata;\n } else {\n // Look for revert reason and bubble it up if present\n if (returndata.length > 0) {\n // The easiest way to bubble the revert reason is using memory via assembly\n /// @solidity memory-safe-assembly\n assembly {\n let returndata_size := mload(returndata)\n revert(add(32, returndata), returndata_size)\n }\n } else {\n revert(errorMessage);\n }\n }\n }\n}\n" + }, + "@openzeppelin/contracts-upgradeable/utils/ContextUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)\n\npragma solidity ^0.8.0;\nimport \"../proxy/utils/Initializable.sol\";\n\n/**\n * @dev Provides information about the current execution context, including the\n * sender of the transaction and its data. While these are generally available\n * via msg.sender and msg.data, they should not be accessed in such a direct\n * manner, since when dealing with meta-transactions the account sending and\n * paying for execution may not be the actual sender (as far as an application\n * is concerned).\n *\n * This contract is only required for intermediate, library-like contracts.\n */\nabstract contract ContextUpgradeable is Initializable {\n function __Context_init() internal onlyInitializing {\n }\n\n function __Context_init_unchained() internal onlyInitializing {\n }\n function _msgSender() internal view virtual returns (address) {\n return msg.sender;\n }\n\n function _msgData() internal view virtual returns (bytes calldata) {\n return msg.data;\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[50] private __gap;\n}\n" + }, + "@openzeppelin/contracts-upgradeable/utils/CountersUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (utils/Counters.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @title Counters\n * @author Matt Condon (@shrugs)\n * @dev Provides counters that can only be incremented, decremented or reset. This can be used e.g. to track the number\n * of elements in a mapping, issuing ERC721 ids, or counting request ids.\n *\n * Include with `using Counters for Counters.Counter;`\n */\nlibrary CountersUpgradeable {\n struct Counter {\n // This variable should never be directly accessed by users of the library: interactions must be restricted to\n // the library's function. As of Solidity v0.5.2, this cannot be enforced, though there is a proposal to add\n // this feature: see https://github.com/ethereum/solidity/issues/4637\n uint256 _value; // default: 0\n }\n\n function current(Counter storage counter) internal view returns (uint256) {\n return counter._value;\n }\n\n function increment(Counter storage counter) internal {\n unchecked {\n counter._value += 1;\n }\n }\n\n function decrement(Counter storage counter) internal {\n uint256 value = counter._value;\n require(value > 0, \"Counter: decrement overflow\");\n unchecked {\n counter._value = value - 1;\n }\n }\n\n function reset(Counter storage counter) internal {\n counter._value = 0;\n }\n}\n" + }, + "@openzeppelin/contracts-upgradeable/utils/cryptography/draft-EIP712Upgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (utils/cryptography/draft-EIP712.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./ECDSAUpgradeable.sol\";\nimport \"../../proxy/utils/Initializable.sol\";\n\n/**\n * @dev https://eips.ethereum.org/EIPS/eip-712[EIP 712] is a standard for hashing and signing of typed structured data.\n *\n * The encoding specified in the EIP is very generic, and such a generic implementation in Solidity is not feasible,\n * thus this contract does not implement the encoding itself. Protocols need to implement the type-specific encoding\n * they need in their contracts using a combination of `abi.encode` and `keccak256`.\n *\n * This contract implements the EIP 712 domain separator ({_domainSeparatorV4}) that is used as part of the encoding\n * scheme, and the final step of the encoding to obtain the message digest that is then signed via ECDSA\n * ({_hashTypedDataV4}).\n *\n * The implementation of the domain separator was designed to be as efficient as possible while still properly updating\n * the chain id to protect against replay attacks on an eventual fork of the chain.\n *\n * NOTE: This contract implements the version of the encoding known as \"v4\", as implemented by the JSON RPC method\n * https://docs.metamask.io/guide/signing-data.html[`eth_signTypedDataV4` in MetaMask].\n *\n * _Available since v3.4._\n *\n * @custom:storage-size 52\n */\nabstract contract EIP712Upgradeable is Initializable {\n /* solhint-disable var-name-mixedcase */\n bytes32 private _HASHED_NAME;\n bytes32 private _HASHED_VERSION;\n bytes32 private constant _TYPE_HASH = keccak256(\"EIP712Domain(string name,string version,uint256 chainId,address verifyingContract)\");\n\n /* solhint-enable var-name-mixedcase */\n\n /**\n * @dev Initializes the domain separator and parameter caches.\n *\n * The meaning of `name` and `version` is specified in\n * https://eips.ethereum.org/EIPS/eip-712#definition-of-domainseparator[EIP 712]:\n *\n * - `name`: the user readable name of the signing domain, i.e. the name of the DApp or the protocol.\n * - `version`: the current major version of the signing domain.\n *\n * NOTE: These parameters cannot be changed except through a xref:learn::upgrading-smart-contracts.adoc[smart\n * contract upgrade].\n */\n function __EIP712_init(string memory name, string memory version) internal onlyInitializing {\n __EIP712_init_unchained(name, version);\n }\n\n function __EIP712_init_unchained(string memory name, string memory version) internal onlyInitializing {\n bytes32 hashedName = keccak256(bytes(name));\n bytes32 hashedVersion = keccak256(bytes(version));\n _HASHED_NAME = hashedName;\n _HASHED_VERSION = hashedVersion;\n }\n\n /**\n * @dev Returns the domain separator for the current chain.\n */\n function _domainSeparatorV4() internal view returns (bytes32) {\n return _buildDomainSeparator(_TYPE_HASH, _EIP712NameHash(), _EIP712VersionHash());\n }\n\n function _buildDomainSeparator(\n bytes32 typeHash,\n bytes32 nameHash,\n bytes32 versionHash\n ) private view returns (bytes32) {\n return keccak256(abi.encode(typeHash, nameHash, versionHash, block.chainid, address(this)));\n }\n\n /**\n * @dev Given an already https://eips.ethereum.org/EIPS/eip-712#definition-of-hashstruct[hashed struct], this\n * function returns the hash of the fully encoded EIP712 message for this domain.\n *\n * This hash can be used together with {ECDSA-recover} to obtain the signer of a message. For example:\n *\n * ```solidity\n * bytes32 digest = _hashTypedDataV4(keccak256(abi.encode(\n * keccak256(\"Mail(address to,string contents)\"),\n * mailTo,\n * keccak256(bytes(mailContents))\n * )));\n * address signer = ECDSA.recover(digest, signature);\n * ```\n */\n function _hashTypedDataV4(bytes32 structHash) internal view virtual returns (bytes32) {\n return ECDSAUpgradeable.toTypedDataHash(_domainSeparatorV4(), structHash);\n }\n\n /**\n * @dev The hash of the name parameter for the EIP712 domain.\n *\n * NOTE: This function reads from storage by default, but can be redefined to return a constant value if gas costs\n * are a concern.\n */\n function _EIP712NameHash() internal virtual view returns (bytes32) {\n return _HASHED_NAME;\n }\n\n /**\n * @dev The hash of the version parameter for the EIP712 domain.\n *\n * NOTE: This function reads from storage by default, but can be redefined to return a constant value if gas costs\n * are a concern.\n */\n function _EIP712VersionHash() internal virtual view returns (bytes32) {\n return _HASHED_VERSION;\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[50] private __gap;\n}\n" + }, + "@openzeppelin/contracts-upgradeable/utils/cryptography/ECDSAUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (utils/cryptography/ECDSA.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../StringsUpgradeable.sol\";\n\n/**\n * @dev Elliptic Curve Digital Signature Algorithm (ECDSA) operations.\n *\n * These functions can be used to verify that a message was signed by the holder\n * of the private keys of a given address.\n */\nlibrary ECDSAUpgradeable {\n enum RecoverError {\n NoError,\n InvalidSignature,\n InvalidSignatureLength,\n InvalidSignatureS,\n InvalidSignatureV\n }\n\n function _throwError(RecoverError error) private pure {\n if (error == RecoverError.NoError) {\n return; // no error: do nothing\n } else if (error == RecoverError.InvalidSignature) {\n revert(\"ECDSA: invalid signature\");\n } else if (error == RecoverError.InvalidSignatureLength) {\n revert(\"ECDSA: invalid signature length\");\n } else if (error == RecoverError.InvalidSignatureS) {\n revert(\"ECDSA: invalid signature 's' value\");\n } else if (error == RecoverError.InvalidSignatureV) {\n revert(\"ECDSA: invalid signature 'v' value\");\n }\n }\n\n /**\n * @dev Returns the address that signed a hashed message (`hash`) with\n * `signature` or error string. This address can then be used for verification purposes.\n *\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\n * this function rejects them by requiring the `s` value to be in the lower\n * half order, and the `v` value to be either 27 or 28.\n *\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\n * verification to be secure: it is possible to craft signatures that\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\n * this is by receiving a hash of the original message (which may otherwise\n * be too long), and then calling {toEthSignedMessageHash} on it.\n *\n * Documentation for signature generation:\n * - with https://web3js.readthedocs.io/en/v1.3.4/web3-eth-accounts.html#sign[Web3.js]\n * - with https://docs.ethers.io/v5/api/signer/#Signer-signMessage[ethers]\n *\n * _Available since v4.3._\n */\n function tryRecover(bytes32 hash, bytes memory signature) internal pure returns (address, RecoverError) {\n // Check the signature length\n // - case 65: r,s,v signature (standard)\n // - case 64: r,vs signature (cf https://eips.ethereum.org/EIPS/eip-2098) _Available since v4.1._\n if (signature.length == 65) {\n bytes32 r;\n bytes32 s;\n uint8 v;\n // ecrecover takes the signature parameters, and the only way to get them\n // currently is to use assembly.\n /// @solidity memory-safe-assembly\n assembly {\n r := mload(add(signature, 0x20))\n s := mload(add(signature, 0x40))\n v := byte(0, mload(add(signature, 0x60)))\n }\n return tryRecover(hash, v, r, s);\n } else if (signature.length == 64) {\n bytes32 r;\n bytes32 vs;\n // ecrecover takes the signature parameters, and the only way to get them\n // currently is to use assembly.\n /// @solidity memory-safe-assembly\n assembly {\n r := mload(add(signature, 0x20))\n vs := mload(add(signature, 0x40))\n }\n return tryRecover(hash, r, vs);\n } else {\n return (address(0), RecoverError.InvalidSignatureLength);\n }\n }\n\n /**\n * @dev Returns the address that signed a hashed message (`hash`) with\n * `signature`. This address can then be used for verification purposes.\n *\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\n * this function rejects them by requiring the `s` value to be in the lower\n * half order, and the `v` value to be either 27 or 28.\n *\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\n * verification to be secure: it is possible to craft signatures that\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\n * this is by receiving a hash of the original message (which may otherwise\n * be too long), and then calling {toEthSignedMessageHash} on it.\n */\n function recover(bytes32 hash, bytes memory signature) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, signature);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Overload of {ECDSA-tryRecover} that receives the `r` and `vs` short-signature fields separately.\n *\n * See https://eips.ethereum.org/EIPS/eip-2098[EIP-2098 short signatures]\n *\n * _Available since v4.3._\n */\n function tryRecover(\n bytes32 hash,\n bytes32 r,\n bytes32 vs\n ) internal pure returns (address, RecoverError) {\n bytes32 s = vs & bytes32(0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff);\n uint8 v = uint8((uint256(vs) >> 255) + 27);\n return tryRecover(hash, v, r, s);\n }\n\n /**\n * @dev Overload of {ECDSA-recover} that receives the `r and `vs` short-signature fields separately.\n *\n * _Available since v4.2._\n */\n function recover(\n bytes32 hash,\n bytes32 r,\n bytes32 vs\n ) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, r, vs);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Overload of {ECDSA-tryRecover} that receives the `v`,\n * `r` and `s` signature fields separately.\n *\n * _Available since v4.3._\n */\n function tryRecover(\n bytes32 hash,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) internal pure returns (address, RecoverError) {\n // EIP-2 still allows signature malleability for ecrecover(). Remove this possibility and make the signature\n // unique. Appendix F in the Ethereum Yellow paper (https://ethereum.github.io/yellowpaper/paper.pdf), defines\n // the valid range for s in (301): 0 < s < secp256k1n ÷ 2 + 1, and for v in (302): v ∈ {27, 28}. Most\n // signatures from current libraries generate a unique signature with an s-value in the lower half order.\n //\n // If your library generates malleable signatures, such as s-values in the upper range, calculate a new s-value\n // with 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141 - s1 and flip v from 27 to 28 or\n // vice versa. If your library also generates signatures with 0/1 for v instead 27/28, add 27 to v to accept\n // these malleable signatures as well.\n if (uint256(s) > 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D576E7357A4501DDFE92F46681B20A0) {\n return (address(0), RecoverError.InvalidSignatureS);\n }\n if (v != 27 && v != 28) {\n return (address(0), RecoverError.InvalidSignatureV);\n }\n\n // If the signature is valid (and not malleable), return the signer address\n address signer = ecrecover(hash, v, r, s);\n if (signer == address(0)) {\n return (address(0), RecoverError.InvalidSignature);\n }\n\n return (signer, RecoverError.NoError);\n }\n\n /**\n * @dev Overload of {ECDSA-recover} that receives the `v`,\n * `r` and `s` signature fields separately.\n */\n function recover(\n bytes32 hash,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, v, r, s);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Returns an Ethereum Signed Message, created from a `hash`. This\n * produces hash corresponding to the one signed with the\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\n * JSON-RPC method as part of EIP-191.\n *\n * See {recover}.\n */\n function toEthSignedMessageHash(bytes32 hash) internal pure returns (bytes32) {\n // 32 is the length in bytes of hash,\n // enforced by the type signature above\n return keccak256(abi.encodePacked(\"\\x19Ethereum Signed Message:\\n32\", hash));\n }\n\n /**\n * @dev Returns an Ethereum Signed Message, created from `s`. This\n * produces hash corresponding to the one signed with the\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\n * JSON-RPC method as part of EIP-191.\n *\n * See {recover}.\n */\n function toEthSignedMessageHash(bytes memory s) internal pure returns (bytes32) {\n return keccak256(abi.encodePacked(\"\\x19Ethereum Signed Message:\\n\", StringsUpgradeable.toString(s.length), s));\n }\n\n /**\n * @dev Returns an Ethereum Signed Typed Data, created from a\n * `domainSeparator` and a `structHash`. This produces hash corresponding\n * to the one signed with the\n * https://eips.ethereum.org/EIPS/eip-712[`eth_signTypedData`]\n * JSON-RPC method as part of EIP-712.\n *\n * See {recover}.\n */\n function toTypedDataHash(bytes32 domainSeparator, bytes32 structHash) internal pure returns (bytes32) {\n return keccak256(abi.encodePacked(\"\\x19\\x01\", domainSeparator, structHash));\n }\n}\n" + }, + "@openzeppelin/contracts-upgradeable/utils/introspection/ERC165Upgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (utils/introspection/ERC165.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./IERC165Upgradeable.sol\";\nimport \"../../proxy/utils/Initializable.sol\";\n\n/**\n * @dev Implementation of the {IERC165} interface.\n *\n * Contracts that want to implement ERC165 should inherit from this contract and override {supportsInterface} to check\n * for the additional interface id that will be supported. For example:\n *\n * ```solidity\n * function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {\n * return interfaceId == type(MyInterface).interfaceId || super.supportsInterface(interfaceId);\n * }\n * ```\n *\n * Alternatively, {ERC165Storage} provides an easier to use but more expensive implementation.\n */\nabstract contract ERC165Upgradeable is Initializable, IERC165Upgradeable {\n function __ERC165_init() internal onlyInitializing {\n }\n\n function __ERC165_init_unchained() internal onlyInitializing {\n }\n /**\n * @dev See {IERC165-supportsInterface}.\n */\n function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {\n return interfaceId == type(IERC165Upgradeable).interfaceId;\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[50] private __gap;\n}\n" + }, + "@openzeppelin/contracts-upgradeable/utils/introspection/IERC165Upgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (utils/introspection/IERC165.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Interface of the ERC165 standard, as defined in the\n * https://eips.ethereum.org/EIPS/eip-165[EIP].\n *\n * Implementers can declare support of contract interfaces, which can then be\n * queried by others ({ERC165Checker}).\n *\n * For an implementation, see {ERC165}.\n */\ninterface IERC165Upgradeable {\n /**\n * @dev Returns true if this contract implements the interface defined by\n * `interfaceId`. See the corresponding\n * https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified[EIP section]\n * to learn more about how these ids are created.\n *\n * This function call must use less than 30 000 gas.\n */\n function supportsInterface(bytes4 interfaceId) external view returns (bool);\n}\n" + }, + "@openzeppelin/contracts-upgradeable/utils/StringsUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (utils/Strings.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev String operations.\n */\nlibrary StringsUpgradeable {\n bytes16 private constant _HEX_SYMBOLS = \"0123456789abcdef\";\n uint8 private constant _ADDRESS_LENGTH = 20;\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` decimal representation.\n */\n function toString(uint256 value) internal pure returns (string memory) {\n // Inspired by OraclizeAPI's implementation - MIT licence\n // https://github.com/oraclize/ethereum-api/blob/b42146b063c7d6ee1358846c198246239e9360e8/oraclizeAPI_0.4.25.sol\n\n if (value == 0) {\n return \"0\";\n }\n uint256 temp = value;\n uint256 digits;\n while (temp != 0) {\n digits++;\n temp /= 10;\n }\n bytes memory buffer = new bytes(digits);\n while (value != 0) {\n digits -= 1;\n buffer[digits] = bytes1(uint8(48 + uint256(value % 10)));\n value /= 10;\n }\n return string(buffer);\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation.\n */\n function toHexString(uint256 value) internal pure returns (string memory) {\n if (value == 0) {\n return \"0x00\";\n }\n uint256 temp = value;\n uint256 length = 0;\n while (temp != 0) {\n length++;\n temp >>= 8;\n }\n return toHexString(value, length);\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length.\n */\n function toHexString(uint256 value, uint256 length) internal pure returns (string memory) {\n bytes memory buffer = new bytes(2 * length + 2);\n buffer[0] = \"0\";\n buffer[1] = \"x\";\n for (uint256 i = 2 * length + 1; i > 1; --i) {\n buffer[i] = _HEX_SYMBOLS[value & 0xf];\n value >>= 4;\n }\n require(value == 0, \"Strings: hex length insufficient\");\n return string(buffer);\n }\n\n /**\n * @dev Converts an `address` with fixed length of 20 bytes to its not checksummed ASCII `string` hexadecimal representation.\n */\n function toHexString(address addr) internal pure returns (string memory) {\n return toHexString(uint256(uint160(addr)), _ADDRESS_LENGTH);\n }\n}\n" + }, + "@openzeppelin/contracts-upgradeable/utils/structs/EnumerableSetUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (utils/structs/EnumerableSet.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Library for managing\n * https://en.wikipedia.org/wiki/Set_(abstract_data_type)[sets] of primitive\n * types.\n *\n * Sets have the following properties:\n *\n * - Elements are added, removed, and checked for existence in constant time\n * (O(1)).\n * - Elements are enumerated in O(n). No guarantees are made on the ordering.\n *\n * ```\n * contract Example {\n * // Add the library methods\n * using EnumerableSet for EnumerableSet.AddressSet;\n *\n * // Declare a set state variable\n * EnumerableSet.AddressSet private mySet;\n * }\n * ```\n *\n * As of v3.3.0, sets of type `bytes32` (`Bytes32Set`), `address` (`AddressSet`)\n * and `uint256` (`UintSet`) are supported.\n *\n * [WARNING]\n * ====\n * Trying to delete such a structure from storage will likely result in data corruption, rendering the structure unusable.\n * See https://github.com/ethereum/solidity/pull/11843[ethereum/solidity#11843] for more info.\n *\n * In order to clean an EnumerableSet, you can either remove all elements one by one or create a fresh instance using an array of EnumerableSet.\n * ====\n */\nlibrary EnumerableSetUpgradeable {\n // To implement this library for multiple types with as little code\n // repetition as possible, we write it in terms of a generic Set type with\n // bytes32 values.\n // The Set implementation uses private functions, and user-facing\n // implementations (such as AddressSet) are just wrappers around the\n // underlying Set.\n // This means that we can only create new EnumerableSets for types that fit\n // in bytes32.\n\n struct Set {\n // Storage of set values\n bytes32[] _values;\n // Position of the value in the `values` array, plus 1 because index 0\n // means a value is not in the set.\n mapping(bytes32 => uint256) _indexes;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function _add(Set storage set, bytes32 value) private returns (bool) {\n if (!_contains(set, value)) {\n set._values.push(value);\n // The value is stored at length-1, but we add 1 to all indexes\n // and use 0 as a sentinel value\n set._indexes[value] = set._values.length;\n return true;\n } else {\n return false;\n }\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function _remove(Set storage set, bytes32 value) private returns (bool) {\n // We read and store the value's index to prevent multiple reads from the same storage slot\n uint256 valueIndex = set._indexes[value];\n\n if (valueIndex != 0) {\n // Equivalent to contains(set, value)\n // To delete an element from the _values array in O(1), we swap the element to delete with the last one in\n // the array, and then remove the last element (sometimes called as 'swap and pop').\n // This modifies the order of the array, as noted in {at}.\n\n uint256 toDeleteIndex = valueIndex - 1;\n uint256 lastIndex = set._values.length - 1;\n\n if (lastIndex != toDeleteIndex) {\n bytes32 lastValue = set._values[lastIndex];\n\n // Move the last value to the index where the value to delete is\n set._values[toDeleteIndex] = lastValue;\n // Update the index for the moved value\n set._indexes[lastValue] = valueIndex; // Replace lastValue's index to valueIndex\n }\n\n // Delete the slot where the moved value was stored\n set._values.pop();\n\n // Delete the index for the deleted slot\n delete set._indexes[value];\n\n return true;\n } else {\n return false;\n }\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function _contains(Set storage set, bytes32 value) private view returns (bool) {\n return set._indexes[value] != 0;\n }\n\n /**\n * @dev Returns the number of values on the set. O(1).\n */\n function _length(Set storage set) private view returns (uint256) {\n return set._values.length;\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function _at(Set storage set, uint256 index) private view returns (bytes32) {\n return set._values[index];\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function _values(Set storage set) private view returns (bytes32[] memory) {\n return set._values;\n }\n\n // Bytes32Set\n\n struct Bytes32Set {\n Set _inner;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function add(Bytes32Set storage set, bytes32 value) internal returns (bool) {\n return _add(set._inner, value);\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function remove(Bytes32Set storage set, bytes32 value) internal returns (bool) {\n return _remove(set._inner, value);\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function contains(Bytes32Set storage set, bytes32 value) internal view returns (bool) {\n return _contains(set._inner, value);\n }\n\n /**\n * @dev Returns the number of values in the set. O(1).\n */\n function length(Bytes32Set storage set) internal view returns (uint256) {\n return _length(set._inner);\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function at(Bytes32Set storage set, uint256 index) internal view returns (bytes32) {\n return _at(set._inner, index);\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function values(Bytes32Set storage set) internal view returns (bytes32[] memory) {\n return _values(set._inner);\n }\n\n // AddressSet\n\n struct AddressSet {\n Set _inner;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function add(AddressSet storage set, address value) internal returns (bool) {\n return _add(set._inner, bytes32(uint256(uint160(value))));\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function remove(AddressSet storage set, address value) internal returns (bool) {\n return _remove(set._inner, bytes32(uint256(uint160(value))));\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function contains(AddressSet storage set, address value) internal view returns (bool) {\n return _contains(set._inner, bytes32(uint256(uint160(value))));\n }\n\n /**\n * @dev Returns the number of values in the set. O(1).\n */\n function length(AddressSet storage set) internal view returns (uint256) {\n return _length(set._inner);\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function at(AddressSet storage set, uint256 index) internal view returns (address) {\n return address(uint160(uint256(_at(set._inner, index))));\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function values(AddressSet storage set) internal view returns (address[] memory) {\n bytes32[] memory store = _values(set._inner);\n address[] memory result;\n\n /// @solidity memory-safe-assembly\n assembly {\n result := store\n }\n\n return result;\n }\n\n // UintSet\n\n struct UintSet {\n Set _inner;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function add(UintSet storage set, uint256 value) internal returns (bool) {\n return _add(set._inner, bytes32(value));\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function remove(UintSet storage set, uint256 value) internal returns (bool) {\n return _remove(set._inner, bytes32(value));\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function contains(UintSet storage set, uint256 value) internal view returns (bool) {\n return _contains(set._inner, bytes32(value));\n }\n\n /**\n * @dev Returns the number of values on the set. O(1).\n */\n function length(UintSet storage set) internal view returns (uint256) {\n return _length(set._inner);\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function at(UintSet storage set, uint256 index) internal view returns (uint256) {\n return uint256(_at(set._inner, index));\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function values(UintSet storage set) internal view returns (uint256[] memory) {\n bytes32[] memory store = _values(set._inner);\n uint256[] memory result;\n\n /// @solidity memory-safe-assembly\n assembly {\n result := store\n }\n\n return result;\n }\n}\n" + }, + "@openzeppelin/contracts/access/Ownable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (access/Ownable.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../utils/Context.sol\";\n\n/**\n * @dev Contract module which provides a basic access control mechanism, where\n * there is an account (an owner) that can be granted exclusive access to\n * specific functions.\n *\n * By default, the owner account will be the one that deploys the contract. This\n * can later be changed with {transferOwnership}.\n *\n * This module is used through inheritance. It will make available the modifier\n * `onlyOwner`, which can be applied to your functions to restrict their use to\n * the owner.\n */\nabstract contract Ownable is Context {\n address private _owner;\n\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\n\n /**\n * @dev Initializes the contract setting the deployer as the initial owner.\n */\n constructor() {\n _transferOwnership(_msgSender());\n }\n\n /**\n * @dev Throws if called by any account other than the owner.\n */\n modifier onlyOwner() {\n _checkOwner();\n _;\n }\n\n /**\n * @dev Returns the address of the current owner.\n */\n function owner() public view virtual returns (address) {\n return _owner;\n }\n\n /**\n * @dev Throws if the sender is not the owner.\n */\n function _checkOwner() internal view virtual {\n require(owner() == _msgSender(), \"Ownable: caller is not the owner\");\n }\n\n /**\n * @dev Leaves the contract without owner. It will not be possible to call\n * `onlyOwner` functions anymore. Can only be called by the current owner.\n *\n * NOTE: Renouncing ownership will leave the contract without an owner,\n * thereby removing any functionality that is only available to the owner.\n */\n function renounceOwnership() public virtual onlyOwner {\n _transferOwnership(address(0));\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Can only be called by the current owner.\n */\n function transferOwnership(address newOwner) public virtual onlyOwner {\n require(newOwner != address(0), \"Ownable: new owner is the zero address\");\n _transferOwnership(newOwner);\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Internal function without access restriction.\n */\n function _transferOwnership(address newOwner) internal virtual {\n address oldOwner = _owner;\n _owner = newOwner;\n emit OwnershipTransferred(oldOwner, newOwner);\n }\n}\n" + }, + "@openzeppelin/contracts/interfaces/draft-IERC1822.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.5.0) (interfaces/draft-IERC1822.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev ERC1822: Universal Upgradeable Proxy Standard (UUPS) documents a method for upgradeability through a simplified\n * proxy whose upgrades are fully controlled by the current implementation.\n */\ninterface IERC1822Proxiable {\n /**\n * @dev Returns the storage slot that the proxiable contract assumes is being used to store the implementation\n * address.\n *\n * IMPORTANT: A proxy pointing at a proxiable contract should not be considered proxiable itself, because this risks\n * bricking a proxy that upgrades to it, by delegating to itself until out of gas. Thus it is critical that this\n * function revert if invoked through a proxy.\n */\n function proxiableUUID() external view returns (bytes32);\n}\n" + }, + "@openzeppelin/contracts/interfaces/IERC3156FlashBorrower.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (interfaces/IERC3156FlashBorrower.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Interface of the ERC3156 FlashBorrower, as defined in\n * https://eips.ethereum.org/EIPS/eip-3156[ERC-3156].\n *\n * _Available since v4.1._\n */\ninterface IERC3156FlashBorrower {\n /**\n * @dev Receive a flash loan.\n * @param initiator The initiator of the loan.\n * @param token The loan currency.\n * @param amount The amount of tokens lent.\n * @param fee The additional amount of tokens to repay.\n * @param data Arbitrary data structure, intended to contain user-defined parameters.\n * @return The keccak256 hash of \"IERC3156FlashBorrower.onFlashLoan\"\n */\n function onFlashLoan(\n address initiator,\n address token,\n uint256 amount,\n uint256 fee,\n bytes calldata data\n ) external returns (bytes32);\n}\n" + }, + "@openzeppelin/contracts/interfaces/IERC3156FlashLender.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (interfaces/IERC3156FlashLender.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./IERC3156FlashBorrower.sol\";\n\n/**\n * @dev Interface of the ERC3156 FlashLender, as defined in\n * https://eips.ethereum.org/EIPS/eip-3156[ERC-3156].\n *\n * _Available since v4.1._\n */\ninterface IERC3156FlashLender {\n /**\n * @dev The amount of currency available to be lended.\n * @param token The loan currency.\n * @return The amount of `token` that can be borrowed.\n */\n function maxFlashLoan(address token) external view returns (uint256);\n\n /**\n * @dev The fee to be charged for a given loan.\n * @param token The loan currency.\n * @param amount The amount of tokens lent.\n * @return The amount of `token` to be charged for the loan, on top of the returned principal.\n */\n function flashFee(address token, uint256 amount) external view returns (uint256);\n\n /**\n * @dev Initiate a flash loan.\n * @param receiver The receiver of the tokens in the loan, and the receiver of the callback.\n * @param token The loan currency.\n * @param amount The amount of tokens lent.\n * @param data Arbitrary data structure, intended to contain user-defined parameters.\n */\n function flashLoan(\n IERC3156FlashBorrower receiver,\n address token,\n uint256 amount,\n bytes calldata data\n ) external returns (bool);\n}\n" + }, + "@openzeppelin/contracts/interfaces/IERC721Metadata.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (interfaces/IERC721Metadata.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../token/ERC721/extensions/IERC721Metadata.sol\";\n" + }, + "@openzeppelin/contracts/proxy/beacon/IBeacon.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (proxy/beacon/IBeacon.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev This is the interface that {BeaconProxy} expects of its beacon.\n */\ninterface IBeacon {\n /**\n * @dev Must return an address that can be used as a delegate call target.\n *\n * {BeaconProxy} will check that this address is a contract.\n */\n function implementation() external view returns (address);\n}\n" + }, + "@openzeppelin/contracts/proxy/ERC1967/ERC1967Proxy.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (proxy/ERC1967/ERC1967Proxy.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../Proxy.sol\";\nimport \"./ERC1967Upgrade.sol\";\n\n/**\n * @dev This contract implements an upgradeable proxy. It is upgradeable because calls are delegated to an\n * implementation address that can be changed. This address is stored in storage in the location specified by\n * https://eips.ethereum.org/EIPS/eip-1967[EIP1967], so that it doesn't conflict with the storage layout of the\n * implementation behind the proxy.\n */\ncontract ERC1967Proxy is Proxy, ERC1967Upgrade {\n /**\n * @dev Initializes the upgradeable proxy with an initial implementation specified by `_logic`.\n *\n * If `_data` is nonempty, it's used as data in a delegate call to `_logic`. This will typically be an encoded\n * function call, and allows initializing the storage of the proxy like a Solidity constructor.\n */\n constructor(address _logic, bytes memory _data) payable {\n _upgradeToAndCall(_logic, _data, false);\n }\n\n /**\n * @dev Returns the current implementation address.\n */\n function _implementation() internal view virtual override returns (address impl) {\n return ERC1967Upgrade._getImplementation();\n }\n}\n" + }, + "@openzeppelin/contracts/proxy/ERC1967/ERC1967Upgrade.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.5.0) (proxy/ERC1967/ERC1967Upgrade.sol)\n\npragma solidity ^0.8.2;\n\nimport \"../beacon/IBeacon.sol\";\nimport \"../../interfaces/draft-IERC1822.sol\";\nimport \"../../utils/Address.sol\";\nimport \"../../utils/StorageSlot.sol\";\n\n/**\n * @dev This abstract contract provides getters and event emitting update functions for\n * https://eips.ethereum.org/EIPS/eip-1967[EIP1967] slots.\n *\n * _Available since v4.1._\n *\n * @custom:oz-upgrades-unsafe-allow delegatecall\n */\nabstract contract ERC1967Upgrade {\n // This is the keccak-256 hash of \"eip1967.proxy.rollback\" subtracted by 1\n bytes32 private constant _ROLLBACK_SLOT = 0x4910fdfa16fed3260ed0e7147f7cc6da11a60208b5b9406d12a635614ffd9143;\n\n /**\n * @dev Storage slot with the address of the current implementation.\n * This is the keccak-256 hash of \"eip1967.proxy.implementation\" subtracted by 1, and is\n * validated in the constructor.\n */\n bytes32 internal constant _IMPLEMENTATION_SLOT = 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc;\n\n /**\n * @dev Emitted when the implementation is upgraded.\n */\n event Upgraded(address indexed implementation);\n\n /**\n * @dev Returns the current implementation address.\n */\n function _getImplementation() internal view returns (address) {\n return StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value;\n }\n\n /**\n * @dev Stores a new address in the EIP1967 implementation slot.\n */\n function _setImplementation(address newImplementation) private {\n require(Address.isContract(newImplementation), \"ERC1967: new implementation is not a contract\");\n StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value = newImplementation;\n }\n\n /**\n * @dev Perform implementation upgrade\n *\n * Emits an {Upgraded} event.\n */\n function _upgradeTo(address newImplementation) internal {\n _setImplementation(newImplementation);\n emit Upgraded(newImplementation);\n }\n\n /**\n * @dev Perform implementation upgrade with additional setup call.\n *\n * Emits an {Upgraded} event.\n */\n function _upgradeToAndCall(\n address newImplementation,\n bytes memory data,\n bool forceCall\n ) internal {\n _upgradeTo(newImplementation);\n if (data.length > 0 || forceCall) {\n Address.functionDelegateCall(newImplementation, data);\n }\n }\n\n /**\n * @dev Perform implementation upgrade with security checks for UUPS proxies, and additional setup call.\n *\n * Emits an {Upgraded} event.\n */\n function _upgradeToAndCallUUPS(\n address newImplementation,\n bytes memory data,\n bool forceCall\n ) internal {\n // Upgrades from old implementations will perform a rollback test. This test requires the new\n // implementation to upgrade back to the old, non-ERC1822 compliant, implementation. Removing\n // this special case will break upgrade paths from old UUPS implementation to new ones.\n if (StorageSlot.getBooleanSlot(_ROLLBACK_SLOT).value) {\n _setImplementation(newImplementation);\n } else {\n try IERC1822Proxiable(newImplementation).proxiableUUID() returns (bytes32 slot) {\n require(slot == _IMPLEMENTATION_SLOT, \"ERC1967Upgrade: unsupported proxiableUUID\");\n } catch {\n revert(\"ERC1967Upgrade: new implementation is not UUPS\");\n }\n _upgradeToAndCall(newImplementation, data, forceCall);\n }\n }\n\n /**\n * @dev Storage slot with the admin of the contract.\n * This is the keccak-256 hash of \"eip1967.proxy.admin\" subtracted by 1, and is\n * validated in the constructor.\n */\n bytes32 internal constant _ADMIN_SLOT = 0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103;\n\n /**\n * @dev Emitted when the admin account has changed.\n */\n event AdminChanged(address previousAdmin, address newAdmin);\n\n /**\n * @dev Returns the current admin.\n */\n function _getAdmin() internal view returns (address) {\n return StorageSlot.getAddressSlot(_ADMIN_SLOT).value;\n }\n\n /**\n * @dev Stores a new address in the EIP1967 admin slot.\n */\n function _setAdmin(address newAdmin) private {\n require(newAdmin != address(0), \"ERC1967: new admin is the zero address\");\n StorageSlot.getAddressSlot(_ADMIN_SLOT).value = newAdmin;\n }\n\n /**\n * @dev Changes the admin of the proxy.\n *\n * Emits an {AdminChanged} event.\n */\n function _changeAdmin(address newAdmin) internal {\n emit AdminChanged(_getAdmin(), newAdmin);\n _setAdmin(newAdmin);\n }\n\n /**\n * @dev The storage slot of the UpgradeableBeacon contract which defines the implementation for this proxy.\n * This is bytes32(uint256(keccak256('eip1967.proxy.beacon')) - 1)) and is validated in the constructor.\n */\n bytes32 internal constant _BEACON_SLOT = 0xa3f0ad74e5423aebfd80d3ef4346578335a9a72aeaee59ff6cb3582b35133d50;\n\n /**\n * @dev Emitted when the beacon is upgraded.\n */\n event BeaconUpgraded(address indexed beacon);\n\n /**\n * @dev Returns the current beacon.\n */\n function _getBeacon() internal view returns (address) {\n return StorageSlot.getAddressSlot(_BEACON_SLOT).value;\n }\n\n /**\n * @dev Stores a new beacon in the EIP1967 beacon slot.\n */\n function _setBeacon(address newBeacon) private {\n require(Address.isContract(newBeacon), \"ERC1967: new beacon is not a contract\");\n require(\n Address.isContract(IBeacon(newBeacon).implementation()),\n \"ERC1967: beacon implementation is not a contract\"\n );\n StorageSlot.getAddressSlot(_BEACON_SLOT).value = newBeacon;\n }\n\n /**\n * @dev Perform beacon upgrade with additional setup call. Note: This upgrades the address of the beacon, it does\n * not upgrade the implementation contained in the beacon (see {UpgradeableBeacon-_setImplementation} for that).\n *\n * Emits a {BeaconUpgraded} event.\n */\n function _upgradeBeaconToAndCall(\n address newBeacon,\n bytes memory data,\n bool forceCall\n ) internal {\n _setBeacon(newBeacon);\n emit BeaconUpgraded(newBeacon);\n if (data.length > 0 || forceCall) {\n Address.functionDelegateCall(IBeacon(newBeacon).implementation(), data);\n }\n }\n}\n" + }, + "@openzeppelin/contracts/proxy/Proxy.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.6.0) (proxy/Proxy.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev This abstract contract provides a fallback function that delegates all calls to another contract using the EVM\n * instruction `delegatecall`. We refer to the second contract as the _implementation_ behind the proxy, and it has to\n * be specified by overriding the virtual {_implementation} function.\n *\n * Additionally, delegation to the implementation can be triggered manually through the {_fallback} function, or to a\n * different contract through the {_delegate} function.\n *\n * The success and return data of the delegated call will be returned back to the caller of the proxy.\n */\nabstract contract Proxy {\n /**\n * @dev Delegates the current call to `implementation`.\n *\n * This function does not return to its internal call site, it will return directly to the external caller.\n */\n function _delegate(address implementation) internal virtual {\n assembly {\n // Copy msg.data. We take full control of memory in this inline assembly\n // block because it will not return to Solidity code. We overwrite the\n // Solidity scratch pad at memory position 0.\n calldatacopy(0, 0, calldatasize())\n\n // Call the implementation.\n // out and outsize are 0 because we don't know the size yet.\n let result := delegatecall(gas(), implementation, 0, calldatasize(), 0, 0)\n\n // Copy the returned data.\n returndatacopy(0, 0, returndatasize())\n\n switch result\n // delegatecall returns 0 on error.\n case 0 {\n revert(0, returndatasize())\n }\n default {\n return(0, returndatasize())\n }\n }\n }\n\n /**\n * @dev This is a virtual function that should be overridden so it returns the address to which the fallback function\n * and {_fallback} should delegate.\n */\n function _implementation() internal view virtual returns (address);\n\n /**\n * @dev Delegates the current call to the address returned by `_implementation()`.\n *\n * This function does not return to its internal call site, it will return directly to the external caller.\n */\n function _fallback() internal virtual {\n _beforeFallback();\n _delegate(_implementation());\n }\n\n /**\n * @dev Fallback function that delegates calls to the address returned by `_implementation()`. Will run if no other\n * function in the contract matches the call data.\n */\n fallback() external payable virtual {\n _fallback();\n }\n\n /**\n * @dev Fallback function that delegates calls to the address returned by `_implementation()`. Will run if call data\n * is empty.\n */\n receive() external payable virtual {\n _fallback();\n }\n\n /**\n * @dev Hook that is called before falling back to the implementation. Can happen as part of a manual `_fallback`\n * call, or as part of the Solidity `fallback` or `receive` functions.\n *\n * If overridden should call `super._beforeFallback()`.\n */\n function _beforeFallback() internal virtual {}\n}\n" + }, + "@openzeppelin/contracts/token/ERC20/ERC20.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (token/ERC20/ERC20.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./IERC20.sol\";\nimport \"./extensions/IERC20Metadata.sol\";\nimport \"../../utils/Context.sol\";\n\n/**\n * @dev Implementation of the {IERC20} interface.\n *\n * This implementation is agnostic to the way tokens are created. This means\n * that a supply mechanism has to be added in a derived contract using {_mint}.\n * For a generic mechanism see {ERC20PresetMinterPauser}.\n *\n * TIP: For a detailed writeup see our guide\n * https://forum.zeppelin.solutions/t/how-to-implement-erc20-supply-mechanisms/226[How\n * to implement supply mechanisms].\n *\n * We have followed general OpenZeppelin Contracts guidelines: functions revert\n * instead returning `false` on failure. This behavior is nonetheless\n * conventional and does not conflict with the expectations of ERC20\n * applications.\n *\n * Additionally, an {Approval} event is emitted on calls to {transferFrom}.\n * This allows applications to reconstruct the allowance for all accounts just\n * by listening to said events. Other implementations of the EIP may not emit\n * these events, as it isn't required by the specification.\n *\n * Finally, the non-standard {decreaseAllowance} and {increaseAllowance}\n * functions have been added to mitigate the well-known issues around setting\n * allowances. See {IERC20-approve}.\n */\ncontract ERC20 is Context, IERC20, IERC20Metadata {\n mapping(address => uint256) private _balances;\n\n mapping(address => mapping(address => uint256)) private _allowances;\n\n uint256 private _totalSupply;\n\n string private _name;\n string private _symbol;\n\n /**\n * @dev Sets the values for {name} and {symbol}.\n *\n * The default value of {decimals} is 18. To select a different value for\n * {decimals} you should overload it.\n *\n * All two of these values are immutable: they can only be set once during\n * construction.\n */\n constructor(string memory name_, string memory symbol_) {\n _name = name_;\n _symbol = symbol_;\n }\n\n /**\n * @dev Returns the name of the token.\n */\n function name() public view virtual override returns (string memory) {\n return _name;\n }\n\n /**\n * @dev Returns the symbol of the token, usually a shorter version of the\n * name.\n */\n function symbol() public view virtual override returns (string memory) {\n return _symbol;\n }\n\n /**\n * @dev Returns the number of decimals used to get its user representation.\n * For example, if `decimals` equals `2`, a balance of `505` tokens should\n * be displayed to a user as `5.05` (`505 / 10 ** 2`).\n *\n * Tokens usually opt for a value of 18, imitating the relationship between\n * Ether and Wei. This is the value {ERC20} uses, unless this function is\n * overridden;\n *\n * NOTE: This information is only used for _display_ purposes: it in\n * no way affects any of the arithmetic of the contract, including\n * {IERC20-balanceOf} and {IERC20-transfer}.\n */\n function decimals() public view virtual override returns (uint8) {\n return 18;\n }\n\n /**\n * @dev See {IERC20-totalSupply}.\n */\n function totalSupply() public view virtual override returns (uint256) {\n return _totalSupply;\n }\n\n /**\n * @dev See {IERC20-balanceOf}.\n */\n function balanceOf(address account) public view virtual override returns (uint256) {\n return _balances[account];\n }\n\n /**\n * @dev See {IERC20-transfer}.\n *\n * Requirements:\n *\n * - `to` cannot be the zero address.\n * - the caller must have a balance of at least `amount`.\n */\n function transfer(address to, uint256 amount) public virtual override returns (bool) {\n address owner = _msgSender();\n _transfer(owner, to, amount);\n return true;\n }\n\n /**\n * @dev See {IERC20-allowance}.\n */\n function allowance(address owner, address spender) public view virtual override returns (uint256) {\n return _allowances[owner][spender];\n }\n\n /**\n * @dev See {IERC20-approve}.\n *\n * NOTE: If `amount` is the maximum `uint256`, the allowance is not updated on\n * `transferFrom`. This is semantically equivalent to an infinite approval.\n *\n * Requirements:\n *\n * - `spender` cannot be the zero address.\n */\n function approve(address spender, uint256 amount) public virtual override returns (bool) {\n address owner = _msgSender();\n _approve(owner, spender, amount);\n return true;\n }\n\n /**\n * @dev See {IERC20-transferFrom}.\n *\n * Emits an {Approval} event indicating the updated allowance. This is not\n * required by the EIP. See the note at the beginning of {ERC20}.\n *\n * NOTE: Does not update the allowance if the current allowance\n * is the maximum `uint256`.\n *\n * Requirements:\n *\n * - `from` and `to` cannot be the zero address.\n * - `from` must have a balance of at least `amount`.\n * - the caller must have allowance for ``from``'s tokens of at least\n * `amount`.\n */\n function transferFrom(\n address from,\n address to,\n uint256 amount\n ) public virtual override returns (bool) {\n address spender = _msgSender();\n _spendAllowance(from, spender, amount);\n _transfer(from, to, amount);\n return true;\n }\n\n /**\n * @dev Atomically increases the allowance granted to `spender` by the caller.\n *\n * This is an alternative to {approve} that can be used as a mitigation for\n * problems described in {IERC20-approve}.\n *\n * Emits an {Approval} event indicating the updated allowance.\n *\n * Requirements:\n *\n * - `spender` cannot be the zero address.\n */\n function increaseAllowance(address spender, uint256 addedValue) public virtual returns (bool) {\n address owner = _msgSender();\n _approve(owner, spender, allowance(owner, spender) + addedValue);\n return true;\n }\n\n /**\n * @dev Atomically decreases the allowance granted to `spender` by the caller.\n *\n * This is an alternative to {approve} that can be used as a mitigation for\n * problems described in {IERC20-approve}.\n *\n * Emits an {Approval} event indicating the updated allowance.\n *\n * Requirements:\n *\n * - `spender` cannot be the zero address.\n * - `spender` must have allowance for the caller of at least\n * `subtractedValue`.\n */\n function decreaseAllowance(address spender, uint256 subtractedValue) public virtual returns (bool) {\n address owner = _msgSender();\n uint256 currentAllowance = allowance(owner, spender);\n require(currentAllowance >= subtractedValue, \"ERC20: decreased allowance below zero\");\n unchecked {\n _approve(owner, spender, currentAllowance - subtractedValue);\n }\n\n return true;\n }\n\n /**\n * @dev Moves `amount` of tokens from `from` to `to`.\n *\n * This internal function is equivalent to {transfer}, and can be used to\n * e.g. implement automatic token fees, slashing mechanisms, etc.\n *\n * Emits a {Transfer} event.\n *\n * Requirements:\n *\n * - `from` cannot be the zero address.\n * - `to` cannot be the zero address.\n * - `from` must have a balance of at least `amount`.\n */\n function _transfer(\n address from,\n address to,\n uint256 amount\n ) internal virtual {\n require(from != address(0), \"ERC20: transfer from the zero address\");\n require(to != address(0), \"ERC20: transfer to the zero address\");\n\n _beforeTokenTransfer(from, to, amount);\n\n uint256 fromBalance = _balances[from];\n require(fromBalance >= amount, \"ERC20: transfer amount exceeds balance\");\n unchecked {\n _balances[from] = fromBalance - amount;\n }\n _balances[to] += amount;\n\n emit Transfer(from, to, amount);\n\n _afterTokenTransfer(from, to, amount);\n }\n\n /** @dev Creates `amount` tokens and assigns them to `account`, increasing\n * the total supply.\n *\n * Emits a {Transfer} event with `from` set to the zero address.\n *\n * Requirements:\n *\n * - `account` cannot be the zero address.\n */\n function _mint(address account, uint256 amount) internal virtual {\n require(account != address(0), \"ERC20: mint to the zero address\");\n\n _beforeTokenTransfer(address(0), account, amount);\n\n _totalSupply += amount;\n _balances[account] += amount;\n emit Transfer(address(0), account, amount);\n\n _afterTokenTransfer(address(0), account, amount);\n }\n\n /**\n * @dev Destroys `amount` tokens from `account`, reducing the\n * total supply.\n *\n * Emits a {Transfer} event with `to` set to the zero address.\n *\n * Requirements:\n *\n * - `account` cannot be the zero address.\n * - `account` must have at least `amount` tokens.\n */\n function _burn(address account, uint256 amount) internal virtual {\n require(account != address(0), \"ERC20: burn from the zero address\");\n\n _beforeTokenTransfer(account, address(0), amount);\n\n uint256 accountBalance = _balances[account];\n require(accountBalance >= amount, \"ERC20: burn amount exceeds balance\");\n unchecked {\n _balances[account] = accountBalance - amount;\n }\n _totalSupply -= amount;\n\n emit Transfer(account, address(0), amount);\n\n _afterTokenTransfer(account, address(0), amount);\n }\n\n /**\n * @dev Sets `amount` as the allowance of `spender` over the `owner` s tokens.\n *\n * This internal function is equivalent to `approve`, and can be used to\n * e.g. set automatic allowances for certain subsystems, etc.\n *\n * Emits an {Approval} event.\n *\n * Requirements:\n *\n * - `owner` cannot be the zero address.\n * - `spender` cannot be the zero address.\n */\n function _approve(\n address owner,\n address spender,\n uint256 amount\n ) internal virtual {\n require(owner != address(0), \"ERC20: approve from the zero address\");\n require(spender != address(0), \"ERC20: approve to the zero address\");\n\n _allowances[owner][spender] = amount;\n emit Approval(owner, spender, amount);\n }\n\n /**\n * @dev Updates `owner` s allowance for `spender` based on spent `amount`.\n *\n * Does not update the allowance amount in case of infinite allowance.\n * Revert if not enough allowance is available.\n *\n * Might emit an {Approval} event.\n */\n function _spendAllowance(\n address owner,\n address spender,\n uint256 amount\n ) internal virtual {\n uint256 currentAllowance = allowance(owner, spender);\n if (currentAllowance != type(uint256).max) {\n require(currentAllowance >= amount, \"ERC20: insufficient allowance\");\n unchecked {\n _approve(owner, spender, currentAllowance - amount);\n }\n }\n }\n\n /**\n * @dev Hook that is called before any transfer of tokens. This includes\n * minting and burning.\n *\n * Calling conditions:\n *\n * - when `from` and `to` are both non-zero, `amount` of ``from``'s tokens\n * will be transferred to `to`.\n * - when `from` is zero, `amount` tokens will be minted for `to`.\n * - when `to` is zero, `amount` of ``from``'s tokens will be burned.\n * - `from` and `to` are never both zero.\n *\n * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].\n */\n function _beforeTokenTransfer(\n address from,\n address to,\n uint256 amount\n ) internal virtual {}\n\n /**\n * @dev Hook that is called after any transfer of tokens. This includes\n * minting and burning.\n *\n * Calling conditions:\n *\n * - when `from` and `to` are both non-zero, `amount` of ``from``'s tokens\n * has been transferred to `to`.\n * - when `from` is zero, `amount` tokens have been minted for `to`.\n * - when `to` is zero, `amount` of ``from``'s tokens have been burned.\n * - `from` and `to` are never both zero.\n *\n * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].\n */\n function _afterTokenTransfer(\n address from,\n address to,\n uint256 amount\n ) internal virtual {}\n}\n" + }, + "@openzeppelin/contracts/token/ERC20/extensions/draft-ERC20Permit.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.6.0) (token/ERC20/extensions/draft-ERC20Permit.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./draft-IERC20Permit.sol\";\nimport \"../ERC20.sol\";\nimport \"../../../utils/cryptography/draft-EIP712.sol\";\nimport \"../../../utils/cryptography/ECDSA.sol\";\nimport \"../../../utils/Counters.sol\";\n\n/**\n * @dev Implementation of the ERC20 Permit extension allowing approvals to be made via signatures, as defined in\n * https://eips.ethereum.org/EIPS/eip-2612[EIP-2612].\n *\n * Adds the {permit} method, which can be used to change an account's ERC20 allowance (see {IERC20-allowance}) by\n * presenting a message signed by the account. By not relying on `{IERC20-approve}`, the token holder account doesn't\n * need to send a transaction, and thus is not required to hold Ether at all.\n *\n * _Available since v3.4._\n */\nabstract contract ERC20Permit is ERC20, IERC20Permit, EIP712 {\n using Counters for Counters.Counter;\n\n mapping(address => Counters.Counter) private _nonces;\n\n // solhint-disable-next-line var-name-mixedcase\n bytes32 private constant _PERMIT_TYPEHASH =\n keccak256(\"Permit(address owner,address spender,uint256 value,uint256 nonce,uint256 deadline)\");\n /**\n * @dev In previous versions `_PERMIT_TYPEHASH` was declared as `immutable`.\n * However, to ensure consistency with the upgradeable transpiler, we will continue\n * to reserve a slot.\n * @custom:oz-renamed-from _PERMIT_TYPEHASH\n */\n // solhint-disable-next-line var-name-mixedcase\n bytes32 private _PERMIT_TYPEHASH_DEPRECATED_SLOT;\n\n /**\n * @dev Initializes the {EIP712} domain separator using the `name` parameter, and setting `version` to `\"1\"`.\n *\n * It's a good idea to use the same `name` that is defined as the ERC20 token name.\n */\n constructor(string memory name) EIP712(name, \"1\") {}\n\n /**\n * @dev See {IERC20Permit-permit}.\n */\n function permit(\n address owner,\n address spender,\n uint256 value,\n uint256 deadline,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) public virtual override {\n require(block.timestamp <= deadline, \"ERC20Permit: expired deadline\");\n\n bytes32 structHash = keccak256(abi.encode(_PERMIT_TYPEHASH, owner, spender, value, _useNonce(owner), deadline));\n\n bytes32 hash = _hashTypedDataV4(structHash);\n\n address signer = ECDSA.recover(hash, v, r, s);\n require(signer == owner, \"ERC20Permit: invalid signature\");\n\n _approve(owner, spender, value);\n }\n\n /**\n * @dev See {IERC20Permit-nonces}.\n */\n function nonces(address owner) public view virtual override returns (uint256) {\n return _nonces[owner].current();\n }\n\n /**\n * @dev See {IERC20Permit-DOMAIN_SEPARATOR}.\n */\n // solhint-disable-next-line func-name-mixedcase\n function DOMAIN_SEPARATOR() external view override returns (bytes32) {\n return _domainSeparatorV4();\n }\n\n /**\n * @dev \"Consume a nonce\": return the current value and increment.\n *\n * _Available since v4.1._\n */\n function _useNonce(address owner) internal virtual returns (uint256 current) {\n Counters.Counter storage nonce = _nonces[owner];\n current = nonce.current();\n nonce.increment();\n }\n}\n" + }, + "@openzeppelin/contracts/token/ERC20/extensions/draft-IERC20Permit.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (token/ERC20/extensions/draft-IERC20Permit.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Interface of the ERC20 Permit extension allowing approvals to be made via signatures, as defined in\n * https://eips.ethereum.org/EIPS/eip-2612[EIP-2612].\n *\n * Adds the {permit} method, which can be used to change an account's ERC20 allowance (see {IERC20-allowance}) by\n * presenting a message signed by the account. By not relying on {IERC20-approve}, the token holder account doesn't\n * need to send a transaction, and thus is not required to hold Ether at all.\n */\ninterface IERC20Permit {\n /**\n * @dev Sets `value` as the allowance of `spender` over ``owner``'s tokens,\n * given ``owner``'s signed approval.\n *\n * IMPORTANT: The same issues {IERC20-approve} has related to transaction\n * ordering also apply here.\n *\n * Emits an {Approval} event.\n *\n * Requirements:\n *\n * - `spender` cannot be the zero address.\n * - `deadline` must be a timestamp in the future.\n * - `v`, `r` and `s` must be a valid `secp256k1` signature from `owner`\n * over the EIP712-formatted function arguments.\n * - the signature must use ``owner``'s current nonce (see {nonces}).\n *\n * For more information on the signature format, see the\n * https://eips.ethereum.org/EIPS/eip-2612#specification[relevant EIP\n * section].\n */\n function permit(\n address owner,\n address spender,\n uint256 value,\n uint256 deadline,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) external;\n\n /**\n * @dev Returns the current nonce for `owner`. This value must be\n * included whenever a signature is generated for {permit}.\n *\n * Every successful call to {permit} increases ``owner``'s nonce by one. This\n * prevents a signature from being used multiple times.\n */\n function nonces(address owner) external view returns (uint256);\n\n /**\n * @dev Returns the domain separator used in the encoding of the signature for {permit}, as defined by {EIP712}.\n */\n // solhint-disable-next-line func-name-mixedcase\n function DOMAIN_SEPARATOR() external view returns (bytes32);\n}\n" + }, + "@openzeppelin/contracts/token/ERC20/extensions/IERC20Metadata.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (token/ERC20/extensions/IERC20Metadata.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../IERC20.sol\";\n\n/**\n * @dev Interface for the optional metadata functions from the ERC20 standard.\n *\n * _Available since v4.1._\n */\ninterface IERC20Metadata is IERC20 {\n /**\n * @dev Returns the name of the token.\n */\n function name() external view returns (string memory);\n\n /**\n * @dev Returns the symbol of the token.\n */\n function symbol() external view returns (string memory);\n\n /**\n * @dev Returns the decimals places of the token.\n */\n function decimals() external view returns (uint8);\n}\n" + }, + "@openzeppelin/contracts/token/ERC20/IERC20.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.6.0) (token/ERC20/IERC20.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Interface of the ERC20 standard as defined in the EIP.\n */\ninterface IERC20 {\n /**\n * @dev Emitted when `value` tokens are moved from one account (`from`) to\n * another (`to`).\n *\n * Note that `value` may be zero.\n */\n event Transfer(address indexed from, address indexed to, uint256 value);\n\n /**\n * @dev Emitted when the allowance of a `spender` for an `owner` is set by\n * a call to {approve}. `value` is the new allowance.\n */\n event Approval(address indexed owner, address indexed spender, uint256 value);\n\n /**\n * @dev Returns the amount of tokens in existence.\n */\n function totalSupply() external view returns (uint256);\n\n /**\n * @dev Returns the amount of tokens owned by `account`.\n */\n function balanceOf(address account) external view returns (uint256);\n\n /**\n * @dev Moves `amount` tokens from the caller's account to `to`.\n *\n * Returns a boolean value indicating whether the operation succeeded.\n *\n * Emits a {Transfer} event.\n */\n function transfer(address to, uint256 amount) external returns (bool);\n\n /**\n * @dev Returns the remaining number of tokens that `spender` will be\n * allowed to spend on behalf of `owner` through {transferFrom}. This is\n * zero by default.\n *\n * This value changes when {approve} or {transferFrom} are called.\n */\n function allowance(address owner, address spender) external view returns (uint256);\n\n /**\n * @dev Sets `amount` as the allowance of `spender` over the caller's tokens.\n *\n * Returns a boolean value indicating whether the operation succeeded.\n *\n * IMPORTANT: Beware that changing an allowance with this method brings the risk\n * that someone may use both the old and the new allowance by unfortunate\n * transaction ordering. One possible solution to mitigate this race\n * condition is to first reduce the spender's allowance to 0 and set the\n * desired value afterwards:\n * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729\n *\n * Emits an {Approval} event.\n */\n function approve(address spender, uint256 amount) external returns (bool);\n\n /**\n * @dev Moves `amount` tokens from `from` to `to` using the\n * allowance mechanism. `amount` is then deducted from the caller's\n * allowance.\n *\n * Returns a boolean value indicating whether the operation succeeded.\n *\n * Emits a {Transfer} event.\n */\n function transferFrom(\n address from,\n address to,\n uint256 amount\n ) external returns (bool);\n}\n" + }, + "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (token/ERC20/utils/SafeERC20.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../IERC20.sol\";\nimport \"../extensions/draft-IERC20Permit.sol\";\nimport \"../../../utils/Address.sol\";\n\n/**\n * @title SafeERC20\n * @dev Wrappers around ERC20 operations that throw on failure (when the token\n * contract returns false). Tokens that return no value (and instead revert or\n * throw on failure) are also supported, non-reverting calls are assumed to be\n * successful.\n * To use this library you can add a `using SafeERC20 for IERC20;` statement to your contract,\n * which allows you to call the safe operations as `token.safeTransfer(...)`, etc.\n */\nlibrary SafeERC20 {\n using Address for address;\n\n function safeTransfer(\n IERC20 token,\n address to,\n uint256 value\n ) internal {\n _callOptionalReturn(token, abi.encodeWithSelector(token.transfer.selector, to, value));\n }\n\n function safeTransferFrom(\n IERC20 token,\n address from,\n address to,\n uint256 value\n ) internal {\n _callOptionalReturn(token, abi.encodeWithSelector(token.transferFrom.selector, from, to, value));\n }\n\n /**\n * @dev Deprecated. This function has issues similar to the ones found in\n * {IERC20-approve}, and its usage is discouraged.\n *\n * Whenever possible, use {safeIncreaseAllowance} and\n * {safeDecreaseAllowance} instead.\n */\n function safeApprove(\n IERC20 token,\n address spender,\n uint256 value\n ) internal {\n // safeApprove should only be called when setting an initial allowance,\n // or when resetting it to zero. To increase and decrease it, use\n // 'safeIncreaseAllowance' and 'safeDecreaseAllowance'\n require(\n (value == 0) || (token.allowance(address(this), spender) == 0),\n \"SafeERC20: approve from non-zero to non-zero allowance\"\n );\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, value));\n }\n\n function safeIncreaseAllowance(\n IERC20 token,\n address spender,\n uint256 value\n ) internal {\n uint256 newAllowance = token.allowance(address(this), spender) + value;\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));\n }\n\n function safeDecreaseAllowance(\n IERC20 token,\n address spender,\n uint256 value\n ) internal {\n unchecked {\n uint256 oldAllowance = token.allowance(address(this), spender);\n require(oldAllowance >= value, \"SafeERC20: decreased allowance below zero\");\n uint256 newAllowance = oldAllowance - value;\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));\n }\n }\n\n function safePermit(\n IERC20Permit token,\n address owner,\n address spender,\n uint256 value,\n uint256 deadline,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) internal {\n uint256 nonceBefore = token.nonces(owner);\n token.permit(owner, spender, value, deadline, v, r, s);\n uint256 nonceAfter = token.nonces(owner);\n require(nonceAfter == nonceBefore + 1, \"SafeERC20: permit did not succeed\");\n }\n\n /**\n * @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement\n * on the return value: the return value is optional (but if data is returned, it must not be false).\n * @param token The token targeted by the call.\n * @param data The call data (encoded using abi.encode or one of its variants).\n */\n function _callOptionalReturn(IERC20 token, bytes memory data) private {\n // We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since\n // we're implementing it ourselves. We use {Address.functionCall} to perform this call, which verifies that\n // the target address contains contract code and also asserts for success in the low-level call.\n\n bytes memory returndata = address(token).functionCall(data, \"SafeERC20: low-level call failed\");\n if (returndata.length > 0) {\n // Return data is optional\n require(abi.decode(returndata, (bool)), \"SafeERC20: ERC20 operation did not succeed\");\n }\n }\n}\n" + }, + "@openzeppelin/contracts/token/ERC721/extensions/IERC721Metadata.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (token/ERC721/extensions/IERC721Metadata.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../IERC721.sol\";\n\n/**\n * @title ERC-721 Non-Fungible Token Standard, optional metadata extension\n * @dev See https://eips.ethereum.org/EIPS/eip-721\n */\ninterface IERC721Metadata is IERC721 {\n /**\n * @dev Returns the token collection name.\n */\n function name() external view returns (string memory);\n\n /**\n * @dev Returns the token collection symbol.\n */\n function symbol() external view returns (string memory);\n\n /**\n * @dev Returns the Uniform Resource Identifier (URI) for `tokenId` token.\n */\n function tokenURI(uint256 tokenId) external view returns (string memory);\n}\n" + }, + "@openzeppelin/contracts/token/ERC721/IERC721.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (token/ERC721/IERC721.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../../utils/introspection/IERC165.sol\";\n\n/**\n * @dev Required interface of an ERC721 compliant contract.\n */\ninterface IERC721 is IERC165 {\n /**\n * @dev Emitted when `tokenId` token is transferred from `from` to `to`.\n */\n event Transfer(address indexed from, address indexed to, uint256 indexed tokenId);\n\n /**\n * @dev Emitted when `owner` enables `approved` to manage the `tokenId` token.\n */\n event Approval(address indexed owner, address indexed approved, uint256 indexed tokenId);\n\n /**\n * @dev Emitted when `owner` enables or disables (`approved`) `operator` to manage all of its assets.\n */\n event ApprovalForAll(address indexed owner, address indexed operator, bool approved);\n\n /**\n * @dev Returns the number of tokens in ``owner``'s account.\n */\n function balanceOf(address owner) external view returns (uint256 balance);\n\n /**\n * @dev Returns the owner of the `tokenId` token.\n *\n * Requirements:\n *\n * - `tokenId` must exist.\n */\n function ownerOf(uint256 tokenId) external view returns (address owner);\n\n /**\n * @dev Safely transfers `tokenId` token from `from` to `to`.\n *\n * Requirements:\n *\n * - `from` cannot be the zero address.\n * - `to` cannot be the zero address.\n * - `tokenId` token must exist and be owned by `from`.\n * - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}.\n * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.\n *\n * Emits a {Transfer} event.\n */\n function safeTransferFrom(\n address from,\n address to,\n uint256 tokenId,\n bytes calldata data\n ) external;\n\n /**\n * @dev Safely transfers `tokenId` token from `from` to `to`, checking first that contract recipients\n * are aware of the ERC721 protocol to prevent tokens from being forever locked.\n *\n * Requirements:\n *\n * - `from` cannot be the zero address.\n * - `to` cannot be the zero address.\n * - `tokenId` token must exist and be owned by `from`.\n * - If the caller is not `from`, it must have been allowed to move this token by either {approve} or {setApprovalForAll}.\n * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.\n *\n * Emits a {Transfer} event.\n */\n function safeTransferFrom(\n address from,\n address to,\n uint256 tokenId\n ) external;\n\n /**\n * @dev Transfers `tokenId` token from `from` to `to`.\n *\n * WARNING: Usage of this method is discouraged, use {safeTransferFrom} whenever possible.\n *\n * Requirements:\n *\n * - `from` cannot be the zero address.\n * - `to` cannot be the zero address.\n * - `tokenId` token must be owned by `from`.\n * - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}.\n *\n * Emits a {Transfer} event.\n */\n function transferFrom(\n address from,\n address to,\n uint256 tokenId\n ) external;\n\n /**\n * @dev Gives permission to `to` to transfer `tokenId` token to another account.\n * The approval is cleared when the token is transferred.\n *\n * Only a single account can be approved at a time, so approving the zero address clears previous approvals.\n *\n * Requirements:\n *\n * - The caller must own the token or be an approved operator.\n * - `tokenId` must exist.\n *\n * Emits an {Approval} event.\n */\n function approve(address to, uint256 tokenId) external;\n\n /**\n * @dev Approve or remove `operator` as an operator for the caller.\n * Operators can call {transferFrom} or {safeTransferFrom} for any token owned by the caller.\n *\n * Requirements:\n *\n * - The `operator` cannot be the caller.\n *\n * Emits an {ApprovalForAll} event.\n */\n function setApprovalForAll(address operator, bool _approved) external;\n\n /**\n * @dev Returns the account approved for `tokenId` token.\n *\n * Requirements:\n *\n * - `tokenId` must exist.\n */\n function getApproved(uint256 tokenId) external view returns (address operator);\n\n /**\n * @dev Returns if the `operator` is allowed to manage all of the assets of `owner`.\n *\n * See {setApprovalForAll}\n */\n function isApprovedForAll(address owner, address operator) external view returns (bool);\n}\n" + }, + "@openzeppelin/contracts/utils/Address.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (utils/Address.sol)\n\npragma solidity ^0.8.1;\n\n/**\n * @dev Collection of functions related to the address type\n */\nlibrary Address {\n /**\n * @dev Returns true if `account` is a contract.\n *\n * [IMPORTANT]\n * ====\n * It is unsafe to assume that an address for which this function returns\n * false is an externally-owned account (EOA) and not a contract.\n *\n * Among others, `isContract` will return false for the following\n * types of addresses:\n *\n * - an externally-owned account\n * - a contract in construction\n * - an address where a contract will be created\n * - an address where a contract lived, but was destroyed\n * ====\n *\n * [IMPORTANT]\n * ====\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\n *\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\n * constructor.\n * ====\n */\n function isContract(address account) internal view returns (bool) {\n // This method relies on extcodesize/address.code.length, which returns 0\n // for contracts in construction, since the code is only stored at the end\n // of the constructor execution.\n\n return account.code.length > 0;\n }\n\n /**\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\n * `recipient`, forwarding all available gas and reverting on errors.\n *\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\n * imposed by `transfer`, making them unable to receive funds via\n * `transfer`. {sendValue} removes this limitation.\n *\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\n *\n * IMPORTANT: because control is transferred to `recipient`, care must be\n * taken to not create reentrancy vulnerabilities. Consider using\n * {ReentrancyGuard} or the\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\n */\n function sendValue(address payable recipient, uint256 amount) internal {\n require(address(this).balance >= amount, \"Address: insufficient balance\");\n\n (bool success, ) = recipient.call{value: amount}(\"\");\n require(success, \"Address: unable to send value, recipient may have reverted\");\n }\n\n /**\n * @dev Performs a Solidity function call using a low level `call`. A\n * plain `call` is an unsafe replacement for a function call: use this\n * function instead.\n *\n * If `target` reverts with a revert reason, it is bubbled up by this\n * function (like regular Solidity function calls).\n *\n * Returns the raw returned data. To convert to the expected return value,\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\n *\n * Requirements:\n *\n * - `target` must be a contract.\n * - calling `target` with `data` must not revert.\n *\n * _Available since v3.1._\n */\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionCall(target, data, \"Address: low-level call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\n * `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, 0, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but also transferring `value` wei to `target`.\n *\n * Requirements:\n *\n * - the calling contract must have an ETH balance of at least `value`.\n * - the called Solidity function must be `payable`.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, value, \"Address: low-level call with value failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\n * with `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(address(this).balance >= value, \"Address: insufficient balance for call\");\n require(isContract(target), \"Address: call to non-contract\");\n\n (bool success, bytes memory returndata) = target.call{value: value}(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\n return functionStaticCall(target, data, \"Address: low-level static call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal view returns (bytes memory) {\n require(isContract(target), \"Address: static call to non-contract\");\n\n (bool success, bytes memory returndata) = target.staticcall(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a delegate call.\n *\n * _Available since v3.4._\n */\n function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionDelegateCall(target, data, \"Address: low-level delegate call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a delegate call.\n *\n * _Available since v3.4._\n */\n function functionDelegateCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(isContract(target), \"Address: delegate call to non-contract\");\n\n (bool success, bytes memory returndata) = target.delegatecall(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the\n * revert reason using the provided one.\n *\n * _Available since v4.3._\n */\n function verifyCallResult(\n bool success,\n bytes memory returndata,\n string memory errorMessage\n ) internal pure returns (bytes memory) {\n if (success) {\n return returndata;\n } else {\n // Look for revert reason and bubble it up if present\n if (returndata.length > 0) {\n // The easiest way to bubble the revert reason is using memory via assembly\n /// @solidity memory-safe-assembly\n assembly {\n let returndata_size := mload(returndata)\n revert(add(32, returndata), returndata_size)\n }\n } else {\n revert(errorMessage);\n }\n }\n }\n}\n" + }, + "@openzeppelin/contracts/utils/Context.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Provides information about the current execution context, including the\n * sender of the transaction and its data. While these are generally available\n * via msg.sender and msg.data, they should not be accessed in such a direct\n * manner, since when dealing with meta-transactions the account sending and\n * paying for execution may not be the actual sender (as far as an application\n * is concerned).\n *\n * This contract is only required for intermediate, library-like contracts.\n */\nabstract contract Context {\n function _msgSender() internal view virtual returns (address) {\n return msg.sender;\n }\n\n function _msgData() internal view virtual returns (bytes calldata) {\n return msg.data;\n }\n}\n" + }, + "@openzeppelin/contracts/utils/Counters.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (utils/Counters.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @title Counters\n * @author Matt Condon (@shrugs)\n * @dev Provides counters that can only be incremented, decremented or reset. This can be used e.g. to track the number\n * of elements in a mapping, issuing ERC721 ids, or counting request ids.\n *\n * Include with `using Counters for Counters.Counter;`\n */\nlibrary Counters {\n struct Counter {\n // This variable should never be directly accessed by users of the library: interactions must be restricted to\n // the library's function. As of Solidity v0.5.2, this cannot be enforced, though there is a proposal to add\n // this feature: see https://github.com/ethereum/solidity/issues/4637\n uint256 _value; // default: 0\n }\n\n function current(Counter storage counter) internal view returns (uint256) {\n return counter._value;\n }\n\n function increment(Counter storage counter) internal {\n unchecked {\n counter._value += 1;\n }\n }\n\n function decrement(Counter storage counter) internal {\n uint256 value = counter._value;\n require(value > 0, \"Counter: decrement overflow\");\n unchecked {\n counter._value = value - 1;\n }\n }\n\n function reset(Counter storage counter) internal {\n counter._value = 0;\n }\n}\n" + }, + "@openzeppelin/contracts/utils/cryptography/draft-EIP712.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (utils/cryptography/draft-EIP712.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./ECDSA.sol\";\n\n/**\n * @dev https://eips.ethereum.org/EIPS/eip-712[EIP 712] is a standard for hashing and signing of typed structured data.\n *\n * The encoding specified in the EIP is very generic, and such a generic implementation in Solidity is not feasible,\n * thus this contract does not implement the encoding itself. Protocols need to implement the type-specific encoding\n * they need in their contracts using a combination of `abi.encode` and `keccak256`.\n *\n * This contract implements the EIP 712 domain separator ({_domainSeparatorV4}) that is used as part of the encoding\n * scheme, and the final step of the encoding to obtain the message digest that is then signed via ECDSA\n * ({_hashTypedDataV4}).\n *\n * The implementation of the domain separator was designed to be as efficient as possible while still properly updating\n * the chain id to protect against replay attacks on an eventual fork of the chain.\n *\n * NOTE: This contract implements the version of the encoding known as \"v4\", as implemented by the JSON RPC method\n * https://docs.metamask.io/guide/signing-data.html[`eth_signTypedDataV4` in MetaMask].\n *\n * _Available since v3.4._\n */\nabstract contract EIP712 {\n /* solhint-disable var-name-mixedcase */\n // Cache the domain separator as an immutable value, but also store the chain id that it corresponds to, in order to\n // invalidate the cached domain separator if the chain id changes.\n bytes32 private immutable _CACHED_DOMAIN_SEPARATOR;\n uint256 private immutable _CACHED_CHAIN_ID;\n address private immutable _CACHED_THIS;\n\n bytes32 private immutable _HASHED_NAME;\n bytes32 private immutable _HASHED_VERSION;\n bytes32 private immutable _TYPE_HASH;\n\n /* solhint-enable var-name-mixedcase */\n\n /**\n * @dev Initializes the domain separator and parameter caches.\n *\n * The meaning of `name` and `version` is specified in\n * https://eips.ethereum.org/EIPS/eip-712#definition-of-domainseparator[EIP 712]:\n *\n * - `name`: the user readable name of the signing domain, i.e. the name of the DApp or the protocol.\n * - `version`: the current major version of the signing domain.\n *\n * NOTE: These parameters cannot be changed except through a xref:learn::upgrading-smart-contracts.adoc[smart\n * contract upgrade].\n */\n constructor(string memory name, string memory version) {\n bytes32 hashedName = keccak256(bytes(name));\n bytes32 hashedVersion = keccak256(bytes(version));\n bytes32 typeHash = keccak256(\n \"EIP712Domain(string name,string version,uint256 chainId,address verifyingContract)\"\n );\n _HASHED_NAME = hashedName;\n _HASHED_VERSION = hashedVersion;\n _CACHED_CHAIN_ID = block.chainid;\n _CACHED_DOMAIN_SEPARATOR = _buildDomainSeparator(typeHash, hashedName, hashedVersion);\n _CACHED_THIS = address(this);\n _TYPE_HASH = typeHash;\n }\n\n /**\n * @dev Returns the domain separator for the current chain.\n */\n function _domainSeparatorV4() internal view returns (bytes32) {\n if (address(this) == _CACHED_THIS && block.chainid == _CACHED_CHAIN_ID) {\n return _CACHED_DOMAIN_SEPARATOR;\n } else {\n return _buildDomainSeparator(_TYPE_HASH, _HASHED_NAME, _HASHED_VERSION);\n }\n }\n\n function _buildDomainSeparator(\n bytes32 typeHash,\n bytes32 nameHash,\n bytes32 versionHash\n ) private view returns (bytes32) {\n return keccak256(abi.encode(typeHash, nameHash, versionHash, block.chainid, address(this)));\n }\n\n /**\n * @dev Given an already https://eips.ethereum.org/EIPS/eip-712#definition-of-hashstruct[hashed struct], this\n * function returns the hash of the fully encoded EIP712 message for this domain.\n *\n * This hash can be used together with {ECDSA-recover} to obtain the signer of a message. For example:\n *\n * ```solidity\n * bytes32 digest = _hashTypedDataV4(keccak256(abi.encode(\n * keccak256(\"Mail(address to,string contents)\"),\n * mailTo,\n * keccak256(bytes(mailContents))\n * )));\n * address signer = ECDSA.recover(digest, signature);\n * ```\n */\n function _hashTypedDataV4(bytes32 structHash) internal view virtual returns (bytes32) {\n return ECDSA.toTypedDataHash(_domainSeparatorV4(), structHash);\n }\n}\n" + }, + "@openzeppelin/contracts/utils/cryptography/ECDSA.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (utils/cryptography/ECDSA.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../Strings.sol\";\n\n/**\n * @dev Elliptic Curve Digital Signature Algorithm (ECDSA) operations.\n *\n * These functions can be used to verify that a message was signed by the holder\n * of the private keys of a given address.\n */\nlibrary ECDSA {\n enum RecoverError {\n NoError,\n InvalidSignature,\n InvalidSignatureLength,\n InvalidSignatureS,\n InvalidSignatureV\n }\n\n function _throwError(RecoverError error) private pure {\n if (error == RecoverError.NoError) {\n return; // no error: do nothing\n } else if (error == RecoverError.InvalidSignature) {\n revert(\"ECDSA: invalid signature\");\n } else if (error == RecoverError.InvalidSignatureLength) {\n revert(\"ECDSA: invalid signature length\");\n } else if (error == RecoverError.InvalidSignatureS) {\n revert(\"ECDSA: invalid signature 's' value\");\n } else if (error == RecoverError.InvalidSignatureV) {\n revert(\"ECDSA: invalid signature 'v' value\");\n }\n }\n\n /**\n * @dev Returns the address that signed a hashed message (`hash`) with\n * `signature` or error string. This address can then be used for verification purposes.\n *\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\n * this function rejects them by requiring the `s` value to be in the lower\n * half order, and the `v` value to be either 27 or 28.\n *\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\n * verification to be secure: it is possible to craft signatures that\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\n * this is by receiving a hash of the original message (which may otherwise\n * be too long), and then calling {toEthSignedMessageHash} on it.\n *\n * Documentation for signature generation:\n * - with https://web3js.readthedocs.io/en/v1.3.4/web3-eth-accounts.html#sign[Web3.js]\n * - with https://docs.ethers.io/v5/api/signer/#Signer-signMessage[ethers]\n *\n * _Available since v4.3._\n */\n function tryRecover(bytes32 hash, bytes memory signature) internal pure returns (address, RecoverError) {\n // Check the signature length\n // - case 65: r,s,v signature (standard)\n // - case 64: r,vs signature (cf https://eips.ethereum.org/EIPS/eip-2098) _Available since v4.1._\n if (signature.length == 65) {\n bytes32 r;\n bytes32 s;\n uint8 v;\n // ecrecover takes the signature parameters, and the only way to get them\n // currently is to use assembly.\n /// @solidity memory-safe-assembly\n assembly {\n r := mload(add(signature, 0x20))\n s := mload(add(signature, 0x40))\n v := byte(0, mload(add(signature, 0x60)))\n }\n return tryRecover(hash, v, r, s);\n } else if (signature.length == 64) {\n bytes32 r;\n bytes32 vs;\n // ecrecover takes the signature parameters, and the only way to get them\n // currently is to use assembly.\n /// @solidity memory-safe-assembly\n assembly {\n r := mload(add(signature, 0x20))\n vs := mload(add(signature, 0x40))\n }\n return tryRecover(hash, r, vs);\n } else {\n return (address(0), RecoverError.InvalidSignatureLength);\n }\n }\n\n /**\n * @dev Returns the address that signed a hashed message (`hash`) with\n * `signature`. This address can then be used for verification purposes.\n *\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\n * this function rejects them by requiring the `s` value to be in the lower\n * half order, and the `v` value to be either 27 or 28.\n *\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\n * verification to be secure: it is possible to craft signatures that\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\n * this is by receiving a hash of the original message (which may otherwise\n * be too long), and then calling {toEthSignedMessageHash} on it.\n */\n function recover(bytes32 hash, bytes memory signature) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, signature);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Overload of {ECDSA-tryRecover} that receives the `r` and `vs` short-signature fields separately.\n *\n * See https://eips.ethereum.org/EIPS/eip-2098[EIP-2098 short signatures]\n *\n * _Available since v4.3._\n */\n function tryRecover(\n bytes32 hash,\n bytes32 r,\n bytes32 vs\n ) internal pure returns (address, RecoverError) {\n bytes32 s = vs & bytes32(0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff);\n uint8 v = uint8((uint256(vs) >> 255) + 27);\n return tryRecover(hash, v, r, s);\n }\n\n /**\n * @dev Overload of {ECDSA-recover} that receives the `r and `vs` short-signature fields separately.\n *\n * _Available since v4.2._\n */\n function recover(\n bytes32 hash,\n bytes32 r,\n bytes32 vs\n ) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, r, vs);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Overload of {ECDSA-tryRecover} that receives the `v`,\n * `r` and `s` signature fields separately.\n *\n * _Available since v4.3._\n */\n function tryRecover(\n bytes32 hash,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) internal pure returns (address, RecoverError) {\n // EIP-2 still allows signature malleability for ecrecover(). Remove this possibility and make the signature\n // unique. Appendix F in the Ethereum Yellow paper (https://ethereum.github.io/yellowpaper/paper.pdf), defines\n // the valid range for s in (301): 0 < s < secp256k1n ÷ 2 + 1, and for v in (302): v ∈ {27, 28}. Most\n // signatures from current libraries generate a unique signature with an s-value in the lower half order.\n //\n // If your library generates malleable signatures, such as s-values in the upper range, calculate a new s-value\n // with 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141 - s1 and flip v from 27 to 28 or\n // vice versa. If your library also generates signatures with 0/1 for v instead 27/28, add 27 to v to accept\n // these malleable signatures as well.\n if (uint256(s) > 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D576E7357A4501DDFE92F46681B20A0) {\n return (address(0), RecoverError.InvalidSignatureS);\n }\n if (v != 27 && v != 28) {\n return (address(0), RecoverError.InvalidSignatureV);\n }\n\n // If the signature is valid (and not malleable), return the signer address\n address signer = ecrecover(hash, v, r, s);\n if (signer == address(0)) {\n return (address(0), RecoverError.InvalidSignature);\n }\n\n return (signer, RecoverError.NoError);\n }\n\n /**\n * @dev Overload of {ECDSA-recover} that receives the `v`,\n * `r` and `s` signature fields separately.\n */\n function recover(\n bytes32 hash,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, v, r, s);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Returns an Ethereum Signed Message, created from a `hash`. This\n * produces hash corresponding to the one signed with the\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\n * JSON-RPC method as part of EIP-191.\n *\n * See {recover}.\n */\n function toEthSignedMessageHash(bytes32 hash) internal pure returns (bytes32) {\n // 32 is the length in bytes of hash,\n // enforced by the type signature above\n return keccak256(abi.encodePacked(\"\\x19Ethereum Signed Message:\\n32\", hash));\n }\n\n /**\n * @dev Returns an Ethereum Signed Message, created from `s`. This\n * produces hash corresponding to the one signed with the\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\n * JSON-RPC method as part of EIP-191.\n *\n * See {recover}.\n */\n function toEthSignedMessageHash(bytes memory s) internal pure returns (bytes32) {\n return keccak256(abi.encodePacked(\"\\x19Ethereum Signed Message:\\n\", Strings.toString(s.length), s));\n }\n\n /**\n * @dev Returns an Ethereum Signed Typed Data, created from a\n * `domainSeparator` and a `structHash`. This produces hash corresponding\n * to the one signed with the\n * https://eips.ethereum.org/EIPS/eip-712[`eth_signTypedData`]\n * JSON-RPC method as part of EIP-712.\n *\n * See {recover}.\n */\n function toTypedDataHash(bytes32 domainSeparator, bytes32 structHash) internal pure returns (bytes32) {\n return keccak256(abi.encodePacked(\"\\x19\\x01\", domainSeparator, structHash));\n }\n}\n" + }, + "@openzeppelin/contracts/utils/introspection/IERC165.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (utils/introspection/IERC165.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Interface of the ERC165 standard, as defined in the\n * https://eips.ethereum.org/EIPS/eip-165[EIP].\n *\n * Implementers can declare support of contract interfaces, which can then be\n * queried by others ({ERC165Checker}).\n *\n * For an implementation, see {ERC165}.\n */\ninterface IERC165 {\n /**\n * @dev Returns true if this contract implements the interface defined by\n * `interfaceId`. See the corresponding\n * https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified[EIP section]\n * to learn more about how these ids are created.\n *\n * This function call must use less than 30 000 gas.\n */\n function supportsInterface(bytes4 interfaceId) external view returns (bool);\n}\n" + }, + "@openzeppelin/contracts/utils/StorageSlot.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (utils/StorageSlot.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Library for reading and writing primitive types to specific storage slots.\n *\n * Storage slots are often used to avoid storage conflict when dealing with upgradeable contracts.\n * This library helps with reading and writing to such slots without the need for inline assembly.\n *\n * The functions in this library return Slot structs that contain a `value` member that can be used to read or write.\n *\n * Example usage to set ERC1967 implementation slot:\n * ```\n * contract ERC1967 {\n * bytes32 internal constant _IMPLEMENTATION_SLOT = 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc;\n *\n * function _getImplementation() internal view returns (address) {\n * return StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value;\n * }\n *\n * function _setImplementation(address newImplementation) internal {\n * require(Address.isContract(newImplementation), \"ERC1967: new implementation is not a contract\");\n * StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value = newImplementation;\n * }\n * }\n * ```\n *\n * _Available since v4.1 for `address`, `bool`, `bytes32`, and `uint256`._\n */\nlibrary StorageSlot {\n struct AddressSlot {\n address value;\n }\n\n struct BooleanSlot {\n bool value;\n }\n\n struct Bytes32Slot {\n bytes32 value;\n }\n\n struct Uint256Slot {\n uint256 value;\n }\n\n /**\n * @dev Returns an `AddressSlot` with member `value` located at `slot`.\n */\n function getAddressSlot(bytes32 slot) internal pure returns (AddressSlot storage r) {\n /// @solidity memory-safe-assembly\n assembly {\n r.slot := slot\n }\n }\n\n /**\n * @dev Returns an `BooleanSlot` with member `value` located at `slot`.\n */\n function getBooleanSlot(bytes32 slot) internal pure returns (BooleanSlot storage r) {\n /// @solidity memory-safe-assembly\n assembly {\n r.slot := slot\n }\n }\n\n /**\n * @dev Returns an `Bytes32Slot` with member `value` located at `slot`.\n */\n function getBytes32Slot(bytes32 slot) internal pure returns (Bytes32Slot storage r) {\n /// @solidity memory-safe-assembly\n assembly {\n r.slot := slot\n }\n }\n\n /**\n * @dev Returns an `Uint256Slot` with member `value` located at `slot`.\n */\n function getUint256Slot(bytes32 slot) internal pure returns (Uint256Slot storage r) {\n /// @solidity memory-safe-assembly\n assembly {\n r.slot := slot\n }\n }\n}\n" + }, + "@openzeppelin/contracts/utils/Strings.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (utils/Strings.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev String operations.\n */\nlibrary Strings {\n bytes16 private constant _HEX_SYMBOLS = \"0123456789abcdef\";\n uint8 private constant _ADDRESS_LENGTH = 20;\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` decimal representation.\n */\n function toString(uint256 value) internal pure returns (string memory) {\n // Inspired by OraclizeAPI's implementation - MIT licence\n // https://github.com/oraclize/ethereum-api/blob/b42146b063c7d6ee1358846c198246239e9360e8/oraclizeAPI_0.4.25.sol\n\n if (value == 0) {\n return \"0\";\n }\n uint256 temp = value;\n uint256 digits;\n while (temp != 0) {\n digits++;\n temp /= 10;\n }\n bytes memory buffer = new bytes(digits);\n while (value != 0) {\n digits -= 1;\n buffer[digits] = bytes1(uint8(48 + uint256(value % 10)));\n value /= 10;\n }\n return string(buffer);\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation.\n */\n function toHexString(uint256 value) internal pure returns (string memory) {\n if (value == 0) {\n return \"0x00\";\n }\n uint256 temp = value;\n uint256 length = 0;\n while (temp != 0) {\n length++;\n temp >>= 8;\n }\n return toHexString(value, length);\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length.\n */\n function toHexString(uint256 value, uint256 length) internal pure returns (string memory) {\n bytes memory buffer = new bytes(2 * length + 2);\n buffer[0] = \"0\";\n buffer[1] = \"x\";\n for (uint256 i = 2 * length + 1; i > 1; --i) {\n buffer[i] = _HEX_SYMBOLS[value & 0xf];\n value >>= 4;\n }\n require(value == 0, \"Strings: hex length insufficient\");\n return string(buffer);\n }\n\n /**\n * @dev Converts an `address` with fixed length of 20 bytes to its not checksummed ASCII `string` hexadecimal representation.\n */\n function toHexString(address addr) internal pure returns (string memory) {\n return toHexString(uint256(uint160(addr)), _ADDRESS_LENGTH);\n }\n}\n" + }, + "contracts/agToken/AgEUR.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\nimport \"../interfaces/IAgToken.sol\";\nimport \"../interfaces/coreModule/IStableMaster.sol\";\nimport \"../interfaces/ITreasury.sol\";\nimport \"@openzeppelin/contracts-upgradeable/token/ERC20/extensions/draft-ERC20PermitUpgradeable.sol\";\n\n/// @title AgEUR\n/// @author Angle Labs, Inc.\n/// @notice Base contract for agEUR, Angle's Euro stablecoin\n/// @dev This contract is an upgraded version of the agEUR contract that was first deployed on Ethereum mainnet\ncontract AgEUR is IAgToken, ERC20PermitUpgradeable {\n // ================================= REFERENCES ================================\n\n /// @notice Reference to the `StableMaster` contract associated to agEUR\n address public stableMaster;\n\n /// @custom:oz-upgrades-unsafe-allow constructor\n constructor() initializer {}\n\n // ============================== ADDED PARAMETERS =============================\n\n /// @inheritdoc IAgToken\n mapping(address => bool) public isMinter;\n /// @notice Reference to the treasury contract which can grant minting rights\n address public treasury;\n /// @notice Boolean used to check whether the contract had been reinitialized after an upgrade\n bool public treasuryInitialized;\n\n // =================================== EVENTS ==================================\n\n event TreasuryUpdated(address indexed _treasury);\n event MinterToggled(address indexed minter);\n\n // =================================== ERRORS ==================================\n\n error BurnAmountExceedsAllowance();\n error InvalidSender();\n error InvalidTreasury();\n error NotGovernor();\n error NotMinter();\n error NotTreasury();\n error TreasuryAlreadyInitialized();\n\n // ================================= MODIFIERS =================================\n\n /// @notice Checks to see if it is the `Treasury` calling this contract\n modifier onlyTreasury() {\n if (msg.sender != treasury) revert NotTreasury();\n _;\n }\n\n /// @notice Checks whether the sender has the minting right\n modifier onlyMinter() {\n if (!isMinter[msg.sender]) revert NotMinter();\n _;\n }\n\n // ============================= EXTERNAL FUNCTION =============================\n\n /// @notice Allows anyone to burn stablecoins\n /// @param amount Amount of stablecoins to burn\n /// @dev This function can typically be called if there is a settlement mechanism to burn stablecoins\n function burnStablecoin(uint256 amount) external {\n _burn(msg.sender, amount);\n }\n\n // ========================= MINTER ROLE ONLY FUNCTIONS ========================\n\n /// @inheritdoc IAgToken\n function burnSelf(uint256 amount, address burner) external onlyMinter {\n _burn(burner, amount);\n }\n\n /// @inheritdoc IAgToken\n function burnFrom(uint256 amount, address burner, address sender) external onlyMinter {\n if (burner != sender) {\n uint256 currentAllowance = allowance(burner, sender);\n if (currentAllowance < amount) revert BurnAmountExceedsAllowance();\n _approve(burner, sender, currentAllowance - amount);\n }\n _burn(burner, amount);\n }\n\n /// @inheritdoc IAgToken\n function mint(address account, uint256 amount) external onlyMinter {\n _mint(account, amount);\n }\n\n // ========================== TREASURY ONLY FUNCTIONS ==========================\n\n /// @inheritdoc IAgToken\n function addMinter(address minter) external onlyTreasury {\n isMinter[minter] = true;\n emit MinterToggled(minter);\n }\n\n /// @inheritdoc IAgToken\n function removeMinter(address minter) external {\n if (msg.sender != minter && msg.sender != address(treasury)) revert InvalidSender();\n isMinter[minter] = false;\n emit MinterToggled(minter);\n }\n\n /// @inheritdoc IAgToken\n function setTreasury(address _treasury) external onlyTreasury {\n treasury = _treasury;\n emit TreasuryUpdated(_treasury);\n }\n}\n" + }, + "contracts/agToken/AgToken.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\n/*\n * █ \n ***** ▓▓▓ \n * ▓▓▓▓▓▓▓ \n * ///. ▓▓▓▓▓▓▓▓▓▓▓▓▓ \n ***** //////// ▓▓▓▓▓▓▓ \n * ///////////// ▓▓▓ \n ▓▓ ////////////////// █ ▓▓ \n ▓▓ ▓▓ /////////////////////// ▓▓ ▓▓ \n ▓▓ ▓▓ //////////////////////////// ▓▓ ▓▓ \n ▓▓ ▓▓ /////////▓▓▓///////▓▓▓///////// ▓▓ ▓▓ \n ▓▓ ,////////////////////////////////////// ▓▓ ▓▓ \n ▓▓ ////////////////////////////////////////// ▓▓ \n ▓▓ //////////////////////▓▓▓▓///////////////////// \n ,//////////////////////////////////////////////////// \n .////////////////////////////////////////////////////////// \n .//////////////////////////██.,//////////////////////////█ \n .//////////////////////████..,./////////////////////██ \n ...////////////////███████.....,.////////////////███ \n ,.,////////////████████ ........,///////////████ \n .,.,//////█████████ ,.......///////████ \n ,..//████████ ........./████ \n ..,██████ .....,███ \n .██ ,.,█ \n \n \n \n ▓▓ ▓▓▓▓▓▓▓▓▓▓ ▓▓▓▓▓▓▓▓▓▓ ▓▓ ▓▓▓▓▓▓▓▓▓▓ \n ▓▓▓▓▓▓ ▓▓▓ ▓▓▓ ▓▓▓ ▓▓ ▓▓ ▓▓▓▓ \n ▓▓▓ ▓▓▓ ▓▓▓ ▓▓▓ ▓▓▓ ▓▓▓ ▓▓ ▓▓▓▓▓ \n ▓▓▓ ▓▓ ▓▓▓ ▓▓▓ ▓▓▓▓▓▓▓▓▓▓ ▓▓▓▓▓▓▓▓▓▓ ▓▓▓▓▓▓▓▓▓▓ \n*/\n\nimport \"../interfaces/IAgToken.sol\";\nimport \"../interfaces/ITreasury.sol\";\nimport \"@openzeppelin/contracts-upgradeable/token/ERC20/extensions/draft-ERC20PermitUpgradeable.sol\";\n\n/// @title AgToken\n/// @author Angle Labs, Inc.\n/// @notice Base contract for Angle agTokens on Ethereum and on other chains\n/// @dev By default, agTokens are ERC-20 tokens with 18 decimals\ncontract AgToken is IAgToken, ERC20PermitUpgradeable {\n // =========================== PARAMETERS / VARIABLES ==========================\n\n /// @inheritdoc IAgToken\n mapping(address => bool) public isMinter;\n /// @notice Reference to the treasury contract which can grant minting rights\n address public treasury;\n\n // =================================== EVENTS ==================================\n\n event TreasuryUpdated(address indexed _treasury);\n event MinterToggled(address indexed minter);\n\n // =================================== ERRORS ==================================\n\n error BurnAmountExceedsAllowance();\n error InvalidSender();\n error InvalidTreasury();\n error NotMinter();\n error NotTreasury();\n\n // ================================ CONSTRUCTOR ================================\n\n /// @custom:oz-upgrades-unsafe-allow constructor\n constructor() initializer {}\n\n /// @notice Initializes the `AgToken` contract\n function initialize(string memory name_, string memory symbol_, address _treasury) external {\n _initialize(name_, symbol_, _treasury);\n }\n\n /// @notice Initializes the contract\n function _initialize(string memory name_, string memory symbol_, address _treasury) internal virtual initializer {\n if (address(ITreasury(_treasury).stablecoin()) != address(this)) revert InvalidTreasury();\n __ERC20Permit_init(name_);\n __ERC20_init(name_, symbol_);\n treasury = _treasury;\n emit TreasuryUpdated(_treasury);\n }\n\n // ================================= MODIFIERS =================================\n\n /// @notice Checks to see if it is the `Treasury` calling this contract\n modifier onlyTreasury() {\n if (msg.sender != treasury) revert NotTreasury();\n _;\n }\n\n /// @notice Checks whether the sender has the minting right\n modifier onlyMinter() {\n if (!isMinter[msg.sender]) revert NotMinter();\n _;\n }\n\n // ============================= EXTERNAL FUNCTION =============================\n\n /// @notice Allows anyone to burn stablecoins\n /// @param amount Amount of stablecoins to burn\n /// @dev This function can typically be called if there is a settlement mechanism to burn stablecoins\n function burnStablecoin(uint256 amount) external {\n _burn(msg.sender, amount);\n }\n\n // ========================= MINTER ROLE ONLY FUNCTIONS ========================\n\n /// @inheritdoc IAgToken\n function burnSelf(uint256 amount, address burner) external onlyMinter {\n _burn(burner, amount);\n }\n\n /// @inheritdoc IAgToken\n function burnFrom(uint256 amount, address burner, address sender) external onlyMinter {\n if (burner != sender) {\n uint256 currentAllowance = allowance(burner, sender);\n if (currentAllowance < amount) revert BurnAmountExceedsAllowance();\n _approve(burner, sender, currentAllowance - amount);\n }\n _burn(burner, amount);\n }\n\n /// @inheritdoc IAgToken\n function mint(address account, uint256 amount) external onlyMinter {\n _mint(account, amount);\n }\n\n // ========================== GOVERNANCE ONLY FUNCTIONS ==========================\n\n /// @inheritdoc IAgToken\n function addMinter(address minter) external onlyTreasury {\n isMinter[minter] = true;\n emit MinterToggled(minter);\n }\n\n /// @inheritdoc IAgToken\n function removeMinter(address minter) external {\n if (msg.sender != address(treasury) && msg.sender != minter) revert InvalidSender();\n isMinter[minter] = false;\n emit MinterToggled(minter);\n }\n\n /// @inheritdoc IAgToken\n function setTreasury(address _treasury) external virtual onlyTreasury {\n treasury = _treasury;\n emit TreasuryUpdated(_treasury);\n }\n}\n" + }, + "contracts/agToken/AgTokenSideChainMultiBridge.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\nimport \"./AgToken.sol\";\nimport \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\nimport \"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\";\n\n/// @title AgTokenSideChainMultiBridge\n/// @author Angle Labs, Inc.\n/// @notice Contract for Angle agTokens on other chains than Ethereum mainnet\n/// @dev This contract supports bridge tokens having a minting right on the stablecoin (also referred to as the canonical\n/// or the native token)\ncontract AgTokenSideChainMultiBridge is AgToken {\n using SafeERC20 for IERC20;\n\n /// @notice Base used for fee computation\n uint256 public constant BASE_PARAMS = 1e9;\n\n // =============================== BRIDGING DATA ===============================\n\n /// @notice Struct with some data about a specific bridge token\n struct BridgeDetails {\n // Limit on the balance of bridge token held by the contract: it is designed\n // to reduce the exposure of the system to hacks\n uint256 limit;\n // Limit on the hourly volume of token minted through this bridge\n // Technically the limit over a rolling hour is hourlyLimit x2 as hourly limit\n // is enforced only between x:00 and x+1:00\n uint256 hourlyLimit;\n // Fee taken for swapping in and out the token\n uint64 fee;\n // Whether the associated token is allowed or not\n bool allowed;\n // Whether swapping in and out from the associated token is paused or not\n bool paused;\n }\n\n /// @notice Maps a bridge token to data\n mapping(address => BridgeDetails) public bridges;\n /// @notice List of all bridge tokens\n address[] public bridgeTokensList;\n /// @notice Maps a bridge token to the associated hourly volume\n mapping(address => mapping(uint256 => uint256)) public usage;\n /// @notice Maps an address to whether it is exempt of fees for when it comes to swapping in and out\n mapping(address => uint256) public isFeeExempt;\n /// @notice Limit to the amount of tokens that can be sent from that chain to another chain\n uint256 public chainTotalHourlyLimit;\n /// @notice Usage per hour on that chain. Maps an hourly timestamp to the total volume swapped out on the chain\n mapping(uint256 => uint256) public chainTotalUsage;\n\n // =================================== EVENTS ==================================\n\n event BridgeTokenAdded(address indexed bridgeToken, uint256 limit, uint256 hourlyLimit, uint64 fee, bool paused);\n event BridgeTokenToggled(address indexed bridgeToken, bool toggleStatus);\n event BridgeTokenRemoved(address indexed bridgeToken);\n event BridgeTokenFeeUpdated(address indexed bridgeToken, uint64 fee);\n event BridgeTokenLimitUpdated(address indexed bridgeToken, uint256 limit);\n event BridgeTokenHourlyLimitUpdated(address indexed bridgeToken, uint256 hourlyLimit);\n event HourlyLimitUpdated(uint256 hourlyLimit);\n event Recovered(address indexed token, address indexed to, uint256 amount);\n event FeeToggled(address indexed theAddress, uint256 toggleStatus);\n\n // =================================== ERRORS ==================================\n\n error AssetStillControlledInReserves();\n error HourlyLimitExceeded();\n error InvalidToken();\n error NotGovernor();\n error NotGovernorOrGuardian();\n error TooBigAmount();\n error TooHighParameterValue();\n error ZeroAddress();\n\n // ================================= MODIFIERS =================================\n\n /// @notice Checks whether the `msg.sender` has the governor role or not\n modifier onlyGovernor() {\n if (!ITreasury(treasury).isGovernor(msg.sender)) revert NotGovernor();\n _;\n }\n\n /// @notice Checks whether the `msg.sender` has the governor role or the guardian role\n modifier onlyGovernorOrGuardian() {\n if (!ITreasury(treasury).isGovernorOrGuardian(msg.sender)) revert NotGovernorOrGuardian();\n _;\n }\n\n // ===================== EXTERNAL PERMISSIONLESS FUNCTIONS =====================\n\n /// @notice Returns the list of all supported bridge tokens\n /// @dev Helpful for UIs\n function allBridgeTokens() external view returns (address[] memory) {\n return bridgeTokensList;\n }\n\n /// @notice Returns the current volume for a bridge, for the current hour\n /// @param bridgeToken Bridge used to mint\n /// @dev Helpful for UIs\n function currentUsage(address bridgeToken) external view returns (uint256) {\n return usage[bridgeToken][block.timestamp / 3600];\n }\n\n /// @notice Returns the current total volume on the chain for the current hour\n /// @dev Helpful for UIs\n function currentTotalUsage() external view returns (uint256) {\n return chainTotalUsage[block.timestamp / 3600];\n }\n\n /// @notice Mints the canonical token from a supported bridge token\n /// @param bridgeToken Bridge token to use to mint\n /// @param amount Amount of bridge tokens to send\n /// @param to Address to which the stablecoin should be sent\n /// @return Amount of the canonical stablecoin actually minted\n /// @dev Some fees may be taken by the protocol depending on the token used and on the address calling\n function swapIn(address bridgeToken, uint256 amount, address to) external returns (uint256) {\n BridgeDetails memory bridgeDetails = bridges[bridgeToken];\n if (!bridgeDetails.allowed || bridgeDetails.paused) revert InvalidToken();\n uint256 balance = IERC20(bridgeToken).balanceOf(address(this));\n if (balance + amount > bridgeDetails.limit) {\n // In case someone maliciously sends tokens to this contract\n // Or the limit changes\n if (bridgeDetails.limit > balance) amount = bridgeDetails.limit - balance;\n else {\n amount = 0;\n }\n }\n\n // Checking requirement on the hourly volume\n uint256 hour = block.timestamp / 3600;\n uint256 hourlyUsage = usage[bridgeToken][hour];\n if (hourlyUsage + amount > bridgeDetails.hourlyLimit) {\n // Edge case when the hourly limit changes\n amount = bridgeDetails.hourlyLimit > hourlyUsage ? bridgeDetails.hourlyLimit - hourlyUsage : 0;\n }\n usage[bridgeToken][hour] = hourlyUsage + amount;\n\n IERC20(bridgeToken).safeTransferFrom(msg.sender, address(this), amount);\n uint256 canonicalOut = amount;\n // Computing fees\n if (isFeeExempt[msg.sender] == 0) {\n canonicalOut -= (canonicalOut * bridgeDetails.fee) / BASE_PARAMS;\n }\n _mint(to, canonicalOut);\n return canonicalOut;\n }\n\n /// @notice Burns the canonical token in exchange for a bridge token\n /// @param bridgeToken Bridge token required\n /// @param amount Amount of canonical tokens to burn\n /// @param to Address to which the bridge token should be sent\n /// @return Amount of bridge tokens actually sent back\n /// @dev Some fees may be taken by the protocol depending on the token used and on the address calling\n function swapOut(address bridgeToken, uint256 amount, address to) external returns (uint256) {\n BridgeDetails memory bridgeDetails = bridges[bridgeToken];\n if (!bridgeDetails.allowed || bridgeDetails.paused) revert InvalidToken();\n\n uint256 hour = block.timestamp / 3600;\n uint256 hourlyUsage = chainTotalUsage[hour] + amount;\n // If the amount being swapped out exceeds the limit, we revert\n // We don't want to change the amount being swapped out.\n // The user can decide to send another tx with the correct amount to reach the limit\n if (hourlyUsage > chainTotalHourlyLimit) revert HourlyLimitExceeded();\n chainTotalUsage[hour] = hourlyUsage;\n\n _burn(msg.sender, amount);\n uint256 bridgeOut = amount;\n if (isFeeExempt[msg.sender] == 0) {\n bridgeOut -= (bridgeOut * bridgeDetails.fee) / BASE_PARAMS;\n }\n IERC20(bridgeToken).safeTransfer(to, bridgeOut);\n return bridgeOut;\n }\n\n // ============================ GOVERNANCE FUNCTIONS ===========================\n\n /// @notice Adds support for a bridge token\n /// @param bridgeToken Bridge token to add: it should be a version of the stablecoin from another bridge\n /// @param limit Limit on the balance of bridge token this contract could hold\n /// @param hourlyLimit Limit on the hourly volume for this bridge\n /// @param paused Whether swapping for this token should be paused or not\n /// @param fee Fee taken upon swapping for or against this token\n function addBridgeToken(\n address bridgeToken,\n uint256 limit,\n uint256 hourlyLimit,\n uint64 fee,\n bool paused\n ) external onlyGovernor {\n if (bridges[bridgeToken].allowed || bridgeToken == address(0)) revert InvalidToken();\n if (fee > BASE_PARAMS) revert TooHighParameterValue();\n BridgeDetails memory _bridge;\n _bridge.limit = limit;\n _bridge.hourlyLimit = hourlyLimit;\n _bridge.paused = paused;\n _bridge.fee = fee;\n _bridge.allowed = true;\n bridges[bridgeToken] = _bridge;\n bridgeTokensList.push(bridgeToken);\n emit BridgeTokenAdded(bridgeToken, limit, hourlyLimit, fee, paused);\n }\n\n /// @notice Removes support for a token\n /// @param bridgeToken Address of the bridge token to remove support for\n function removeBridgeToken(address bridgeToken) external onlyGovernor {\n if (IERC20(bridgeToken).balanceOf(address(this)) != 0) revert AssetStillControlledInReserves();\n delete bridges[bridgeToken];\n // Deletion from `bridgeTokensList` loop\n uint256 bridgeTokensListLength = bridgeTokensList.length;\n for (uint256 i; i < bridgeTokensListLength - 1; ++i) {\n if (bridgeTokensList[i] == bridgeToken) {\n // Replace the `bridgeToken` to remove with the last of the list\n bridgeTokensList[i] = bridgeTokensList[bridgeTokensListLength - 1];\n break;\n }\n }\n // Remove last element in array\n bridgeTokensList.pop();\n emit BridgeTokenRemoved(bridgeToken);\n }\n\n /// @notice Recovers any ERC20 token\n /// @dev Can be used to withdraw bridge tokens for them to be de-bridged on mainnet\n function recoverERC20(address tokenAddress, address to, uint256 amountToRecover) external onlyGovernor {\n IERC20(tokenAddress).safeTransfer(to, amountToRecover);\n emit Recovered(tokenAddress, to, amountToRecover);\n }\n\n /// @notice Updates the `limit` amount for `bridgeToken`\n function setLimit(address bridgeToken, uint256 limit) external onlyGovernorOrGuardian {\n if (!bridges[bridgeToken].allowed) revert InvalidToken();\n bridges[bridgeToken].limit = limit;\n emit BridgeTokenLimitUpdated(bridgeToken, limit);\n }\n\n /// @notice Updates the `hourlyLimit` amount for `bridgeToken`\n function setHourlyLimit(address bridgeToken, uint256 hourlyLimit) external onlyGovernorOrGuardian {\n if (!bridges[bridgeToken].allowed) revert InvalidToken();\n bridges[bridgeToken].hourlyLimit = hourlyLimit;\n emit BridgeTokenHourlyLimitUpdated(bridgeToken, hourlyLimit);\n }\n\n /// @notice Updates the `chainTotalHourlyLimit` amount\n function setChainTotalHourlyLimit(uint256 hourlyLimit) external onlyGovernorOrGuardian {\n chainTotalHourlyLimit = hourlyLimit;\n emit HourlyLimitUpdated(hourlyLimit);\n }\n\n /// @notice Updates the `fee` value for `bridgeToken`\n function setSwapFee(address bridgeToken, uint64 fee) external onlyGovernorOrGuardian {\n if (!bridges[bridgeToken].allowed) revert InvalidToken();\n if (fee > BASE_PARAMS) revert TooHighParameterValue();\n bridges[bridgeToken].fee = fee;\n emit BridgeTokenFeeUpdated(bridgeToken, fee);\n }\n\n /// @notice Pauses or unpauses swapping in and out for a token\n function toggleBridge(address bridgeToken) external onlyGovernorOrGuardian {\n if (!bridges[bridgeToken].allowed) revert InvalidToken();\n bool pausedStatus = bridges[bridgeToken].paused;\n bridges[bridgeToken].paused = !pausedStatus;\n emit BridgeTokenToggled(bridgeToken, !pausedStatus);\n }\n\n /// @notice Toggles fees for the address `theAddress`\n function toggleFeesForAddress(address theAddress) external onlyGovernorOrGuardian {\n uint256 feeExemptStatus = 1 - isFeeExempt[theAddress];\n isFeeExempt[theAddress] = feeExemptStatus;\n emit FeeToggled(theAddress, feeExemptStatus);\n }\n}\n" + }, + "contracts/agToken/layerZero/LayerZeroBridge.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.12;\n\nimport \"./utils/OFTCore.sol\";\nimport \"@openzeppelin/contracts-upgradeable/security/PausableUpgradeable.sol\";\nimport \"@openzeppelin/contracts/token/ERC20/extensions/draft-IERC20Permit.sol\";\n\n/// @title LayerZeroBridge\n/// @author Angle Labs, Inc., forked from https://github.com/LayerZero-Labs/solidity-examples/blob/main/contracts/token/oft/OFT.sol\n/// @notice Contract to be deployed on Ethereum for bridging an AgToken using a bridge intermediate token and LayerZero\ncontract LayerZeroBridge is OFTCore, PausableUpgradeable {\n /// @notice Name of the contract for indexing purposes\n string public name;\n\n /// @notice Address of the bridgeable token\n /// @dev Immutable\n IERC20 public canonicalToken;\n\n /// @notice Maps an address to the amount of token bridged but not received\n mapping(address => uint256) public balanceOf;\n\n // ================================ CONSTRUCTOR ================================\n /// @notice Initializes the contract\n /// @param _name Name of the token corresponding to this contract\n /// @param _lzEndpoint Layer zero endpoint to pass messages\n /// @param _treasury Address of the treasury contract used for access control\n function initialize(string memory _name, address _lzEndpoint, address _treasury) external initializer {\n __LzAppUpgradeable_init(_lzEndpoint, _treasury);\n name = _name;\n canonicalToken = IERC20(address(ITreasury(_treasury).stablecoin()));\n }\n\n /// @custom:oz-upgrades-unsafe-allow constructor\n constructor() initializer {}\n\n // ===================== EXTERNAL PERMISSIONLESS FUNCTIONS =====================\n\n /// @inheritdoc OFTCore\n function sendWithPermit(\n uint16 _dstChainId,\n bytes memory _toAddress,\n uint256 _amount,\n address payable _refundAddress,\n address _zroPaymentAddress,\n bytes memory _adapterParams,\n uint256 deadline,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) public payable override {\n IERC20Permit(address(canonicalToken)).permit(msg.sender, address(this), _amount, deadline, v, r, s);\n send(_dstChainId, _toAddress, _amount, _refundAddress, _zroPaymentAddress, _adapterParams);\n }\n\n /// @inheritdoc OFTCore\n function withdraw(uint256 amount, address recipient) external override returns (uint256) {\n return _withdraw(amount, msg.sender, recipient);\n }\n\n /// @notice Withdraws amount of `token` from the contract and sends it to the recipient\n /// @param amount Amount to withdraw\n /// @param recipient Address to withdraw for\n /// @return The amount of canonical token sent\n function withdrawFor(uint256 amount, address recipient) external returns (uint256) {\n return _withdraw(amount, recipient, recipient);\n }\n\n // ============================= INTERNAL FUNCTIONS ============================\n\n /// @notice Withdraws `amount` from the balance of the `from` address and sends these tokens to the `to` address\n /// @dev It's important to make sure that `from` is either the `msg.sender` or that `from` and `to` are the same\n /// addresses\n function _withdraw(uint256 amount, address from, address to) internal whenNotPaused returns (uint256) {\n balanceOf[from] -= amount; // Will overflow if the amount is too big\n canonicalToken.transfer(to, amount);\n return amount;\n }\n\n /// @inheritdoc OFTCore\n function _debitFrom(uint16, bytes memory, uint256 _amount) internal override whenNotPaused returns (uint256) {\n // No need to use safeTransferFrom as we know this implementation reverts on failure\n canonicalToken.transferFrom(msg.sender, address(this), _amount);\n return _amount;\n }\n\n /// @inheritdoc OFTCore\n function _debitCreditFrom(uint16, bytes memory, uint256 _amount) internal override whenNotPaused returns (uint256) {\n balanceOf[msg.sender] -= _amount;\n return _amount;\n }\n\n /// @inheritdoc OFTCore\n function _creditTo(uint16, address _toAddress, uint256 _amount) internal override whenNotPaused returns (uint256) {\n // Should never revert as all the LayerZero bridge tokens come from\n // this contract\n uint256 balance = canonicalToken.balanceOf(address(this));\n if (balance < _amount) {\n balanceOf[_toAddress] = _amount - balance;\n if (balance != 0) canonicalToken.transfer(_toAddress, balance);\n } else {\n canonicalToken.transfer(_toAddress, _amount);\n }\n return _amount;\n }\n\n // =============================== VIEW FUNCTIONS ==============================\n\n /// @inheritdoc ERC165Upgradeable\n function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {\n return interfaceId == type(IOFTCore).interfaceId || super.supportsInterface(interfaceId);\n }\n\n // ============================ GOVERNANCE FUNCTIONS ===========================\n\n /// @notice Pauses bridging through the contract\n /// @param pause Future pause status\n function pauseSendTokens(bool pause) external onlyGovernorOrGuardian {\n pause ? _pause() : _unpause();\n }\n\n /// @notice Decreases the balance of an address\n /// @param amount Amount to withdraw from balance\n /// @param recipient Address to withdraw from\n function sweep(uint256 amount, address recipient) external onlyGovernorOrGuardian {\n balanceOf[recipient] -= amount; // Will overflow if the amount is too big\n }\n\n uint256[47] private __gap;\n}\n" + }, + "contracts/agToken/layerZero/LayerZeroBridgeToken.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.12;\n\nimport \"./utils/OFTCore.sol\";\nimport \"../../interfaces/IAgTokenSideChainMultiBridge.sol\";\nimport \"@openzeppelin/contracts-upgradeable/security/PausableUpgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/token/ERC20/ERC20Upgradeable.sol\";\n\n/// @title LayerZeroBridgeToken\n/// @author Angle Labs, Inc., forked from https://github.com/LayerZero-Labs/solidity-examples/blob/main/contracts/token/oft/OFT.sol\n/// @notice Contract to be deployed on a L2/sidechain for bridging an AgToken using a bridge intermediate token and LayerZero\ncontract LayerZeroBridgeToken is OFTCore, ERC20Upgradeable, PausableUpgradeable {\n /// @notice Address of the bridgeable token\n /// @dev Immutable\n IAgTokenSideChainMultiBridge public canonicalToken;\n\n // =================================== ERROR ===================================\n\n error InvalidAllowance();\n\n // ================================ CONSTRUCTOR ================================\n\n /// @notice Initializes the contract\n /// @param _name Name of the token corresponding to this contract\n /// @param _symbol Symbol of the token corresponding to this contract\n /// @param _lzEndpoint Layer zero endpoint to pass messages\n /// @param _treasury Address of the treasury contract used for access control\n /// @param initialSupply Initial supply to mint to the canonical token address\n /// @dev The initial supply corresponds to the initial amount that could be bridged using this OFT\n function initialize(\n string memory _name,\n string memory _symbol,\n address _lzEndpoint,\n address _treasury,\n uint256 initialSupply\n ) external initializer {\n __ERC20_init_unchained(_name, _symbol);\n __LzAppUpgradeable_init(_lzEndpoint, _treasury);\n\n canonicalToken = IAgTokenSideChainMultiBridge(address(ITreasury(_treasury).stablecoin()));\n _approve(address(this), address(canonicalToken), type(uint256).max);\n _mint(address(canonicalToken), initialSupply);\n }\n\n /// @custom:oz-upgrades-unsafe-allow constructor\n constructor() initializer {}\n\n // ===================== EXTERNAL PERMISSIONLESS FUNCTIONS =====================\n\n /// @inheritdoc OFTCore\n function sendWithPermit(\n uint16 _dstChainId,\n bytes memory _toAddress,\n uint256 _amount,\n address payable _refundAddress,\n address _zroPaymentAddress,\n bytes memory _adapterParams,\n uint256 deadline,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) public payable override {\n canonicalToken.permit(msg.sender, address(this), _amount, deadline, v, r, s);\n send(_dstChainId, _toAddress, _amount, _refundAddress, _zroPaymentAddress, _adapterParams);\n }\n\n /// @inheritdoc OFTCore\n function withdraw(uint256 amount, address recipient) external override returns (uint256 amountMinted) {\n // Does not check allowances as transfers from `msg.sender`\n _transfer(msg.sender, address(this), amount);\n amountMinted = canonicalToken.swapIn(address(this), amount, recipient);\n uint256 leftover = balanceOf(address(this));\n if (leftover != 0) {\n _transfer(address(this), msg.sender, leftover);\n }\n }\n\n // ============================= INTERNAL FUNCTIONS ============================\n\n /// @inheritdoc OFTCore\n function _debitFrom(\n uint16,\n bytes memory,\n uint256 _amount\n ) internal override whenNotPaused returns (uint256 amountSwapped) {\n // No need to use safeTransferFrom as we know this implementation reverts on failure\n canonicalToken.transferFrom(msg.sender, address(this), _amount);\n\n // Swap canonical for this bridge token. There may be some fees\n amountSwapped = canonicalToken.swapOut(address(this), _amount, address(this));\n _burn(address(this), amountSwapped);\n }\n\n /// @inheritdoc OFTCore\n function _debitCreditFrom(uint16, bytes memory, uint256 _amount) internal override whenNotPaused returns (uint256) {\n _burn(msg.sender, _amount);\n return _amount;\n }\n\n /// @inheritdoc OFTCore\n function _creditTo(\n uint16,\n address _toAddress,\n uint256 _amount\n ) internal override whenNotPaused returns (uint256 amountMinted) {\n _mint(address(this), _amount);\n amountMinted = canonicalToken.swapIn(address(this), _amount, _toAddress);\n uint256 leftover = balanceOf(address(this));\n if (leftover != 0) {\n _transfer(address(this), _toAddress, leftover);\n }\n }\n\n // =============================== VIEW FUNCTIONS ==============================\n\n /// @inheritdoc ERC165Upgradeable\n function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {\n return\n interfaceId == type(IOFT).interfaceId ||\n interfaceId == type(IERC20).interfaceId ||\n super.supportsInterface(interfaceId);\n }\n\n // ============================ GOVERNANCE FUNCTIONS ===========================\n\n /// @notice Mints the intermediate contract to the `canonicalToken`\n /// @dev Used to increase the bridging capacity\n function mint(uint256 amount) external onlyGovernorOrGuardian {\n _mint(address(canonicalToken), amount);\n }\n\n /// @notice Burns the intermediate contract from the `canonicalToken`\n /// @dev Used to decrease the bridging capacity\n function burn(uint256 amount) external onlyGovernorOrGuardian {\n _burn(address(canonicalToken), amount);\n }\n\n /// @notice Increases allowance of the `canonicalToken`\n function setupAllowance() public onlyGovernorOrGuardian {\n _approve(address(this), address(canonicalToken), type(uint256).max);\n }\n\n /// @notice Pauses bridging through the contract\n /// @param pause Future pause status\n function pauseSendTokens(bool pause) external onlyGovernorOrGuardian {\n pause ? _pause() : _unpause();\n }\n\n uint256[49] private __gap;\n}\n" + }, + "contracts/agToken/layerZero/utils/IOFTCore.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.12;\n\nimport \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\nimport \"@openzeppelin/contracts/utils/introspection/IERC165.sol\";\n\n/**\n * @dev Interface of the IOFT core standard\n * @dev Forked from https://github.com/LayerZero-Labs/solidity-examples/blob/main/contracts/token/oft/IOFTCore.sol\n */\ninterface IOFTCore is IERC165 {\n /// @notice Estimates send token `_tokenId` to (`_dstChainId`, `_toAddress`)\n /// @param _dstChainId L0 defined chain id to send tokens too\n /// @param _toAddress dynamic bytes array which contains the address to whom you are sending tokens to on the dstChain\n /// @param _amount amount of the tokens to transfer\n /// @param _useZro indicates to use zro to pay L0 fees\n /// @param _adapterParams flexible bytes array to indicate messaging adapter services in L0\n function estimateSendFee(\n uint16 _dstChainId,\n bytes calldata _toAddress,\n uint256 _amount,\n bool _useZro,\n bytes calldata _adapterParams\n ) external view returns (uint256 nativeFee, uint256 zroFee);\n\n /// @notice Sends `_amount` amount of token to (`_dstChainId`, `_toAddress`)\n /// @param _dstChainId the destination chain identifier\n /// @param _toAddress can be any size depending on the `dstChainId`.\n /// @param _amount the quantity of tokens in wei\n /// @param _refundAddress the address LayerZero refunds if too much message fee is sent\n /// @param _zroPaymentAddress set to address(0x0) if not paying in ZRO (LayerZero Token)\n /// @param _adapterParams is a flexible bytes array to indicate messaging adapter services\n function send(\n uint16 _dstChainId,\n bytes calldata _toAddress,\n uint256 _amount,\n address payable _refundAddress,\n address _zroPaymentAddress,\n bytes calldata _adapterParams\n ) external payable;\n\n /// @notice Sends `_amount` amount of credit to (`_dstChainId`, `_toAddress`)\n /// @param _dstChainId the destination chain identifier\n /// @param _toAddress can be any size depending on the `dstChainId`.\n /// @param _amount the quantity of credit to send in wei\n /// @param _refundAddress the address LayerZero refunds if too much message fee is sent\n /// @param _zroPaymentAddress set to address(0x0) if not paying in ZRO (LayerZero Token)\n /// @param _adapterParams is a flexible bytes array to indicate messaging adapter services\n function sendCredit(\n uint16 _dstChainId,\n bytes calldata _toAddress,\n uint256 _amount,\n address payable _refundAddress,\n address _zroPaymentAddress,\n bytes calldata _adapterParams\n ) external payable;\n\n /// @notice Sends `_amount` amount of token to (`_dstChainId`, `_toAddress`)\n /// @param _dstChainId The destination chain identifier\n /// @param _toAddress Can be any size depending on the `dstChainId`.\n /// @param _amount Quantity of tokens in wei\n /// @param _refundAddress Address LayerZero refunds if too much message fee is sent\n /// @param _zroPaymentAddress Set to address(0x0) if not paying in ZRO (LayerZero Token)\n /// @param _adapterParams Flexible bytes array to indicate messaging adapter services\n /// @param deadline Deadline parameter for the signature to be valid\n /// @dev The `v`, `r`, and `s` parameters are used as signature data\n function sendWithPermit(\n uint16 _dstChainId,\n bytes memory _toAddress,\n uint256 _amount,\n address payable _refundAddress,\n address _zroPaymentAddress,\n bytes memory _adapterParams,\n uint256 deadline,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) external payable;\n\n /// @notice Withdraws amount of canonical token from the `msg.sender` balance and sends it to the recipient\n /// @param amount Amount to withdraw\n /// @param recipient Address to send the canonical token to\n /// @return The amount of canonical token sent\n function withdraw(uint256 amount, address recipient) external returns (uint256);\n\n /// @dev Emitted when `_amount` tokens are moved from the `_sender` to (`_dstChainId`, `_toAddress`)\n /// `_nonce` is the outbound nonce\n event SendToChain(\n address indexed _sender,\n uint16 indexed _dstChainId,\n bytes indexed _toAddress,\n uint256 _amount,\n uint64 _nonce\n );\n\n /// @dev Emitted when `_amount` tokens are received from `_srcChainId` into the `_toAddress` on the local chain.\n /// `_nonce` is the inbound nonce.\n event ReceiveFromChain(\n uint16 indexed _srcChainId,\n bytes indexed _srcAddress,\n address indexed _toAddress,\n uint256 _amount,\n uint64 _nonce\n );\n}\n\n/// @dev Interface of the OFT standard\ninterface IOFT is IOFTCore, IERC20 {\n\n}\n" + }, + "contracts/agToken/layerZero/utils/NonblockingLzApp.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.12;\n\nimport \"@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol\";\nimport \"../../../interfaces/external/layerZero/ILayerZeroReceiver.sol\";\nimport \"../../../interfaces/external/layerZero/ILayerZeroUserApplicationConfig.sol\";\nimport \"../../../interfaces/external/layerZero/ILayerZeroEndpoint.sol\";\nimport \"../../../interfaces/ITreasury.sol\";\n\n/// @title NonblockingLzApp\n/// @author Angle Labs, Inc., forked from https://github.com/LayerZero-Labs/solidity-examples/\n/// @notice Base contract for bridging using LayerZero\nabstract contract NonblockingLzApp is Initializable, ILayerZeroReceiver, ILayerZeroUserApplicationConfig {\n /// @notice Layer Zero endpoint\n ILayerZeroEndpoint public lzEndpoint;\n\n /// @notice Maps chainIds to failed messages to retry them\n mapping(uint16 => mapping(bytes => mapping(uint64 => bytes32))) public failedMessages;\n\n /// @notice Maps chainIds to their OFT address\n mapping(uint16 => bytes) public trustedRemoteLookup;\n\n /// @notice Reference to the treasury contract to fetch access control\n address public treasury;\n\n /// @notice Maps pairs of (`to` chain, `packetType`) to the minimum amount of gas needed on the destination chain\n mapping(uint16 => mapping(uint16 => uint256)) public minDstGasLookup;\n\n /// @notice For future LayerZero compatibility\n address public precrime;\n\n // ================================== Events ===================================\n\n event SetTrustedRemote(uint16 _srcChainId, bytes _srcAddress);\n event MessageFailed(uint16 _srcChainId, bytes _srcAddress, uint64 _nonce, bytes _payload);\n\n // =============================== Errors ================================\n\n error NotGovernor();\n error NotGovernorOrGuardian();\n error InsufficientGas();\n error InvalidEndpoint();\n error InvalidSource();\n error InvalidCaller();\n error InvalidParams();\n error InvalidPayload();\n error ZeroAddress();\n\n // ============================= Constructor ===================================\n\n //solhint-disable-next-line\n function __LzAppUpgradeable_init(address _endpoint, address _treasury) internal {\n if (_endpoint == address(0) || _treasury == address(0)) revert ZeroAddress();\n lzEndpoint = ILayerZeroEndpoint(_endpoint);\n treasury = _treasury;\n }\n\n // =============================== Modifiers ===================================\n\n /// @notice Checks whether the `msg.sender` has the governor role or the guardian role\n modifier onlyGovernorOrGuardian() {\n if (!ITreasury(treasury).isGovernorOrGuardian(msg.sender)) revert NotGovernorOrGuardian();\n _;\n }\n\n // ==================== External Permissionless Functions ======================\n\n /// @notice Receives a message from the LZ endpoint and process it\n /// @param _srcChainId ChainId of the source chain - LayerZero standard\n /// @param _srcAddress Sender of the source chain\n /// @param _nonce Nounce of the message\n /// @param _payload Data: recipient address and amount\n function lzReceive(\n uint16 _srcChainId,\n bytes memory _srcAddress,\n uint64 _nonce,\n bytes memory _payload\n ) public virtual override {\n // lzReceive must be called by the endpoint for security\n if (msg.sender != address(lzEndpoint)) revert InvalidEndpoint();\n\n bytes memory trustedRemote = trustedRemoteLookup[_srcChainId];\n // if will still block the message pathway from (srcChainId, srcAddress). should not receive message from untrusted remote.\n if (_srcAddress.length != trustedRemote.length || keccak256(_srcAddress) != keccak256(trustedRemote))\n revert InvalidSource();\n\n _blockingLzReceive(_srcChainId, _srcAddress, _nonce, _payload);\n }\n\n /// @notice Retries a message that previously failed and was stored\n /// @param _srcChainId ChainId of the source chain - LayerZero standard\n /// @param _srcAddress Sender of the source chain\n /// @param _nonce Nounce of the message\n /// @param _payload Data: recipient address and amount\n function retryMessage(\n uint16 _srcChainId,\n bytes memory _srcAddress,\n uint64 _nonce,\n bytes memory _payload\n ) public payable virtual {\n // assert there is message to retry\n bytes32 payloadHash = failedMessages[_srcChainId][_srcAddress][_nonce];\n if (payloadHash == bytes32(0) || keccak256(_payload) != payloadHash) revert InvalidPayload();\n // clear the stored message\n failedMessages[_srcChainId][_srcAddress][_nonce] = bytes32(0);\n // execute the message. revert if it fails again\n _nonblockingLzReceive(_srcChainId, _srcAddress, _nonce, _payload);\n }\n\n // ============================= Internal Functions ===================================\n\n /// @notice Handles message receptions in a non blocking way\n /// @param _srcChainId ChainId of the source chain - LayerZero standard\n /// @param _srcAddress Sender of the source chain\n /// @param _nonce Nounce of the message\n /// @param _payload Data: recipient address and amount\n /// @dev public for the needs of try / catch but effectively internal\n function nonblockingLzReceive(\n uint16 _srcChainId,\n bytes memory _srcAddress,\n uint64 _nonce,\n bytes memory _payload\n ) public virtual {\n // only internal transaction\n if (msg.sender != address(this)) revert InvalidCaller();\n _nonblockingLzReceive(_srcChainId, _srcAddress, _nonce, _payload);\n }\n\n /// @notice Handles message receptions in a non blocking way\n /// @param _srcChainId ChainId of the source chain - LayerZero standard\n /// @param _srcAddress Sender of the source chain\n /// @param _nonce Nounce of the message\n /// @param _payload Data: recipient address and amount\n function _nonblockingLzReceive(\n uint16 _srcChainId,\n bytes memory _srcAddress,\n uint64 _nonce,\n bytes memory _payload\n ) internal virtual;\n\n /// @notice Handles message receptions in a blocking way\n /// @param _srcChainId ChainId of the source chain - LayerZero standard\n /// @param _srcAddress Sender of the source chain\n /// @param _nonce Nounce of the message\n /// @param _payload Data: recipient address and amount\n function _blockingLzReceive(\n uint16 _srcChainId,\n bytes memory _srcAddress,\n uint64 _nonce,\n bytes memory _payload\n ) internal {\n // try-catch all errors/exceptions\n try this.nonblockingLzReceive(_srcChainId, _srcAddress, _nonce, _payload) {\n // do nothing\n } catch {\n // error / exception\n failedMessages[_srcChainId][_srcAddress][_nonce] = keccak256(_payload);\n emit MessageFailed(_srcChainId, _srcAddress, _nonce, _payload);\n }\n }\n\n /// @notice Sends a message to the LZ endpoint and process it\n /// @param _dstChainId L0 defined chain id to send tokens too\n /// @param _payload Data: recipient address and amount\n /// @param _refundAddress Address LayerZero refunds if too much message fee is sent\n /// @param _zroPaymentAddress Set to address(0x0) if not paying in ZRO (LayerZero Token)\n /// @param _adapterParams Flexible bytes array to indicate messaging adapter services in L0\n function _lzSend(\n uint16 _dstChainId,\n bytes memory _payload,\n address payable _refundAddress,\n address _zroPaymentAddress,\n bytes memory _adapterParams\n ) internal virtual {\n bytes memory trustedRemote = trustedRemoteLookup[_dstChainId];\n if (trustedRemote.length == 0) revert InvalidSource();\n //solhint-disable-next-line\n lzEndpoint.send{ value: msg.value }(\n _dstChainId,\n trustedRemote,\n _payload,\n _refundAddress,\n _zroPaymentAddress,\n _adapterParams\n );\n }\n\n /// @notice Checks the gas limit of a given transaction\n function _checkGasLimit(\n uint16 _dstChainId,\n uint16 _type,\n bytes memory _adapterParams,\n uint256 _extraGas\n ) internal view virtual {\n uint256 minGasLimit = minDstGasLookup[_dstChainId][_type] + _extraGas;\n if (minGasLimit == 0 || minGasLimit > _getGasLimit(_adapterParams)) revert InsufficientGas();\n }\n\n /// @notice Gets the gas limit from the `_adapterParams` parameter\n function _getGasLimit(bytes memory _adapterParams) internal pure virtual returns (uint256 gasLimit) {\n if (_adapterParams.length < 34) revert InvalidParams();\n // solhint-disable-next-line\n assembly {\n gasLimit := mload(add(_adapterParams, 34))\n }\n }\n\n // ======================= Governance Functions ================================\n\n /// @notice Sets the corresponding address on an other chain.\n /// @param _srcChainId ChainId of the source chain - LayerZero standard\n /// @param _srcAddress Address on the source chain\n /// @dev Used for both receiving and sending message\n /// @dev There can only be one trusted source per chain\n /// @dev Allows owner to set it multiple times.\n function setTrustedRemote(uint16 _srcChainId, bytes calldata _srcAddress) external onlyGovernorOrGuardian {\n trustedRemoteLookup[_srcChainId] = _srcAddress;\n emit SetTrustedRemote(_srcChainId, _srcAddress);\n }\n\n /// @notice Fetches the default LZ config\n function getConfig(\n uint16 _version,\n uint16 _chainId,\n address,\n uint256 _configType\n ) external view returns (bytes memory) {\n return lzEndpoint.getConfig(_version, _chainId, address(this), _configType);\n }\n\n /// @notice Overrides the default LZ config\n function setConfig(\n uint16 _version,\n uint16 _chainId,\n uint256 _configType,\n bytes calldata _config\n ) external override onlyGovernorOrGuardian {\n lzEndpoint.setConfig(_version, _chainId, _configType, _config);\n }\n\n /// @notice Overrides the default LZ config\n function setSendVersion(uint16 _version) external override onlyGovernorOrGuardian {\n lzEndpoint.setSendVersion(_version);\n }\n\n /// @notice Overrides the default LZ config\n function setReceiveVersion(uint16 _version) external override onlyGovernorOrGuardian {\n lzEndpoint.setReceiveVersion(_version);\n }\n\n /// @notice Unpauses the receive functionalities\n function forceResumeReceive(\n uint16 _srcChainId,\n bytes calldata _srcAddress\n ) external override onlyGovernorOrGuardian {\n lzEndpoint.forceResumeReceive(_srcChainId, _srcAddress);\n }\n\n /// @notice Sets the minimum gas parameter for a packet type on a given chain\n function setMinDstGas(uint16 _dstChainId, uint16 _packetType, uint256 _minGas) external onlyGovernorOrGuardian {\n if (_minGas == 0) revert InvalidParams();\n minDstGasLookup[_dstChainId][_packetType] = _minGas;\n }\n\n /// @notice Sets the precrime variable\n function setPrecrime(address _precrime) external onlyGovernorOrGuardian {\n precrime = _precrime;\n }\n\n // ======================= View Functions ================================\n\n /// @notice Checks if the `_srcAddress` corresponds to the trusted source\n function isTrustedRemote(uint16 _srcChainId, bytes calldata _srcAddress) external view returns (bool) {\n bytes memory trustedSource = trustedRemoteLookup[_srcChainId];\n return keccak256(trustedSource) == keccak256(_srcAddress);\n }\n\n uint256[44] private __gap;\n}\n" + }, + "contracts/agToken/layerZero/utils/OFTCore.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.12;\n\nimport \"./NonblockingLzApp.sol\";\nimport \"./IOFTCore.sol\";\nimport \"@openzeppelin/contracts-upgradeable/utils/introspection/ERC165Upgradeable.sol\";\n\n/// @title OFTCore\n/// @author Forked from https://github.com/LayerZero-Labs/solidity-examples/blob/main/contracts/token/oft/OFTCore.sol\n/// but with slight modifications from the Angle Labs, Inc. which added return values to the `_creditTo` and `_debitFrom` functions\n/// @notice Base contract for bridging using LayerZero\nabstract contract OFTCore is NonblockingLzApp, ERC165Upgradeable, IOFTCore {\n /// @notice Amount of additional gas specified\n uint256 public constant EXTRA_GAS = 200000;\n /// @notice Packet type for token transfer\n uint16 public constant PT_SEND = 0;\n\n /// @notice Whether to use custom parameters in transactions\n uint8 public useCustomAdapterParams;\n\n // ==================== External Permissionless Functions ======================\n\n /// @inheritdoc IOFTCore\n function sendWithPermit(\n uint16 _dstChainId,\n bytes memory _toAddress,\n uint256 _amount,\n address payable _refundAddress,\n address _zroPaymentAddress,\n bytes memory _adapterParams,\n uint256 deadline,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) public payable virtual;\n\n /// @inheritdoc IOFTCore\n function send(\n uint16 _dstChainId,\n bytes memory _toAddress,\n uint256 _amount,\n address payable _refundAddress,\n address _zroPaymentAddress,\n bytes memory _adapterParams\n ) public payable virtual {\n _checkAdapterParams(_dstChainId, PT_SEND, _adapterParams, EXTRA_GAS);\n _amount = _debitFrom(_dstChainId, _toAddress, _amount);\n\n bytes memory payload = abi.encode(_toAddress, _amount);\n _lzSend(_dstChainId, payload, _refundAddress, _zroPaymentAddress, _adapterParams);\n\n uint64 nonce = lzEndpoint.getOutboundNonce(_dstChainId, address(this));\n emit SendToChain(msg.sender, _dstChainId, _toAddress, _amount, nonce);\n }\n\n /// @inheritdoc IOFTCore\n function sendCredit(\n uint16 _dstChainId,\n bytes memory _toAddress,\n uint256 _amount,\n address payable _refundAddress,\n address _zroPaymentAddress,\n bytes memory _adapterParams\n ) public payable virtual {\n _checkAdapterParams(_dstChainId, PT_SEND, _adapterParams, EXTRA_GAS);\n _amount = _debitCreditFrom(_dstChainId, _toAddress, _amount);\n\n _send(_dstChainId, _toAddress, _amount, _refundAddress, _zroPaymentAddress, _adapterParams);\n }\n\n /// @inheritdoc IOFTCore\n function withdraw(uint256 amount, address recipient) external virtual returns (uint256);\n\n /// @notice Sets whether custom adapter parameters can be used or not\n function setUseCustomAdapterParams(uint8 _useCustomAdapterParams) public virtual onlyGovernorOrGuardian {\n useCustomAdapterParams = _useCustomAdapterParams;\n }\n\n // =========================== Internal Functions ==============================\n\n /// @notice Internal function to send `_amount` amount of token to (`_dstChainId`, `_toAddress`)\n /// @param _dstChainId the destination chain identifier\n /// @param _toAddress can be any size depending on the `dstChainId`.\n /// @param _amount the quantity of tokens in wei\n /// @param _refundAddress the address LayerZero refunds if too much message fee is sent\n /// @param _zroPaymentAddress set to address(0x0) if not paying in ZRO (LayerZero Token)\n /// @param _adapterParams is a flexible bytes array to indicate messaging adapter services\n /// @dev Accounting and checks should be performed beforehand\n function _send(\n uint16 _dstChainId,\n bytes memory _toAddress,\n uint256 _amount,\n address payable _refundAddress,\n address _zroPaymentAddress,\n bytes memory _adapterParams\n ) internal {\n bytes memory payload = abi.encode(_toAddress, _amount);\n _lzSend(_dstChainId, payload, _refundAddress, _zroPaymentAddress, _adapterParams);\n\n uint64 nonce = lzEndpoint.getOutboundNonce(_dstChainId, address(this));\n emit SendToChain(msg.sender, _dstChainId, _toAddress, _amount, nonce);\n }\n\n /// @inheritdoc NonblockingLzApp\n function _nonblockingLzReceive(\n uint16 _srcChainId,\n bytes memory _srcAddress,\n uint64 _nonce,\n bytes memory _payload\n ) internal virtual override {\n // decode and load the toAddress\n (bytes memory toAddressBytes, uint256 amount) = abi.decode(_payload, (bytes, uint256));\n address toAddress;\n //solhint-disable-next-line\n assembly {\n toAddress := mload(add(toAddressBytes, 20))\n }\n amount = _creditTo(_srcChainId, toAddress, amount);\n\n emit ReceiveFromChain(_srcChainId, _srcAddress, toAddress, amount, _nonce);\n }\n\n /// @notice Checks the adapter parameters given during the smart contract call\n function _checkAdapterParams(\n uint16 _dstChainId,\n uint16 _pkType,\n bytes memory _adapterParams,\n uint256 _extraGas\n ) internal virtual {\n if (useCustomAdapterParams > 0) _checkGasLimit(_dstChainId, _pkType, _adapterParams, _extraGas);\n else if (_adapterParams.length != 0) revert InvalidParams();\n }\n\n /// @notice Makes accountability when bridging from this contract using canonical token\n /// @param _dstChainId ChainId of the destination chain - LayerZero standard\n /// @param _toAddress Recipient on the destination chain\n /// @param _amount Amount to bridge\n function _debitFrom(\n uint16 _dstChainId,\n bytes memory _toAddress,\n uint256 _amount\n ) internal virtual returns (uint256);\n\n /// @notice Makes accountability when bridging from this contract's credit\n /// @param _dstChainId ChainId of the destination chain - LayerZero standard\n /// @param _toAddress Recipient on the destination chain\n /// @param _amount Amount to bridge\n function _debitCreditFrom(\n uint16 _dstChainId,\n bytes memory _toAddress,\n uint256 _amount\n ) internal virtual returns (uint256);\n\n /// @notice Makes accountability when bridging to this contract\n /// @param _srcChainId ChainId of the source chain - LayerZero standard\n /// @param _toAddress Recipient on this chain\n /// @param _amount Amount to bridge\n function _creditTo(uint16 _srcChainId, address _toAddress, uint256 _amount) internal virtual returns (uint256);\n\n // ========================== View Functions ===================================\n\n /// @inheritdoc ERC165Upgradeable\n function supportsInterface(\n bytes4 interfaceId\n ) public view virtual override(ERC165Upgradeable, IERC165) returns (bool) {\n return interfaceId == type(IOFTCore).interfaceId || super.supportsInterface(interfaceId);\n }\n\n /// @inheritdoc IOFTCore\n function estimateSendFee(\n uint16 _dstChainId,\n bytes memory _toAddress,\n uint256 _amount,\n bool _useZro,\n bytes memory _adapterParams\n ) public view virtual override returns (uint256 nativeFee, uint256 zroFee) {\n // mock the payload for send()\n bytes memory payload = abi.encode(_toAddress, _amount);\n return lzEndpoint.estimateFees(_dstChainId, address(this), payload, _useZro, _adapterParams);\n }\n\n uint256[49] private __gap;\n}\n" + }, + "contracts/agToken/polygon/TokenPolygonUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.12;\n\nimport \"./utils/ERC20UpgradeableCustom.sol\";\nimport \"@openzeppelin/contracts-upgradeable/access/AccessControlUpgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/utils/cryptography/draft-EIP712Upgradeable.sol\";\nimport \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\nimport \"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\";\n\nimport \"../../interfaces/IAgToken.sol\";\nimport \"../../interfaces/ITreasury.sol\";\n\ninterface IChildToken {\n function deposit(address user, bytes calldata depositData) external;\n\n function withdraw(uint256 amount) external;\n}\n\ncontract TokenPolygonUpgradeable is\n Initializable,\n ERC20UpgradeableCustom,\n AccessControlUpgradeable,\n EIP712Upgradeable,\n IChildToken\n{\n bytes32 public constant DEPOSITOR_ROLE = keccak256(\"DEPOSITOR_ROLE\");\n\n /// @dev Emitted when the child chain manager changes\n event ChildChainManagerAdded(address newAddress);\n event ChildChainManagerRevoked(address oldAddress);\n\n constructor() initializer {}\n\n function initialize(\n string memory _name,\n string memory _symbol,\n address childChainManager,\n address guardian\n ) public initializer {\n __ERC20_init(_name, _symbol);\n __AccessControl_init();\n _setupRole(DEFAULT_ADMIN_ROLE, guardian);\n _setupRole(DEPOSITOR_ROLE, childChainManager);\n __EIP712_init(_name, \"1\");\n }\n\n /**\n * @notice Called when the bridge has tokens to mint\n * @param user Address to mint the token to\n * @param depositData Encoded amount to mint\n */\n function deposit(address user, bytes calldata depositData) external override {\n require(hasRole(DEPOSITOR_ROLE, msg.sender));\n uint256 amount = abi.decode(depositData, (uint256));\n _mint(user, amount);\n }\n\n /**\n * @notice Called when user wants to withdraw tokens back to root chain\n * @dev Should burn user's tokens. This transaction will be verified when exiting on root chain\n * @param amount Amount of tokens to withdraw\n */\n function withdraw(uint256 amount) external override {\n _burn(_msgSender(), amount);\n }\n\n // =============================================================================\n // ======================= New data added for the upgrade ======================\n // =============================================================================\n\n mapping(address => bool) public isMinter;\n /// @notice Reference to the treasury contract which can grant minting rights\n address public treasury;\n /// @notice Boolean to check whether the contract has been reinitialized after its upgrade\n bool public treasuryInitialized;\n\n using SafeERC20 for IERC20;\n\n /// @notice Base used for fee computation\n uint256 public constant BASE_PARAMS = 10 ** 9;\n\n // =============================== Bridging Data ===============================\n\n /// @notice Struct with some data about a specific bridge token\n struct BridgeDetails {\n // Limit on the balance of bridge token held by the contract: it is designed\n // to reduce the exposure of the system to hacks\n uint256 limit;\n // Limit on the hourly volume of token minted through this bridge\n // Technically the limit over a rolling hour is hourlyLimit x2 as hourly limit\n // is enforced only between x:00 and x+1:00\n uint256 hourlyLimit;\n // Fee taken for swapping in and out the token\n uint64 fee;\n // Whether the associated token is allowed or not\n bool allowed;\n // Whether swapping in and out from the associated token is paused or not\n bool paused;\n }\n\n /// @notice Maps a bridge token to data\n mapping(address => BridgeDetails) public bridges;\n /// @notice List of all bridge tokens\n address[] public bridgeTokensList;\n /// @notice Maps a bridge token to the associated hourly volume\n mapping(address => mapping(uint256 => uint256)) public usage;\n /// @notice Maps an address to whether it is exempt of fees for when it comes to swapping in and out\n mapping(address => uint256) public isFeeExempt;\n /// @notice Limit to the amount of tokens that can be sent from that chain to another chain\n uint256 public chainTotalHourlyLimit;\n /// @notice Usage per hour on that chain. Maps an hourly timestamp to the total volume swapped out on the chain\n mapping(uint256 => uint256) public chainTotalUsage;\n\n uint256[42] private __gap;\n\n // ================================== Events ===================================\n\n event BridgeTokenAdded(address indexed bridgeToken, uint256 limit, uint256 hourlyLimit, uint64 fee, bool paused);\n event BridgeTokenToggled(address indexed bridgeToken, bool toggleStatus);\n event BridgeTokenRemoved(address indexed bridgeToken);\n event BridgeTokenFeeUpdated(address indexed bridgeToken, uint64 fee);\n event BridgeTokenLimitUpdated(address indexed bridgeToken, uint256 limit);\n event BridgeTokenHourlyLimitUpdated(address indexed bridgeToken, uint256 hourlyLimit);\n event HourlyLimitUpdated(uint256 hourlyLimit);\n event FeeToggled(address indexed theAddress, uint256 toggleStatus);\n event KeeperToggled(address indexed keeper, bool toggleStatus);\n event MinterToggled(address indexed minter);\n event Recovered(address indexed token, address indexed to, uint256 amount);\n event TreasuryUpdated(address indexed _treasury);\n\n // ================================== Errors ===================================\n\n error AssetStillControlledInReserves();\n error BurnAmountExceedsAllowance();\n error HourlyLimitExceeded();\n error InvalidSender();\n error InvalidToken();\n error InvalidTreasury();\n error NotGovernor();\n error NotGovernorOrGuardian();\n error NotMinter();\n error NotTreasury();\n error TooBigAmount();\n error TooHighParameterValue();\n error TreasuryAlreadyInitialized();\n error ZeroAddress();\n\n /// @notice Checks to see if it is the `Treasury` calling this contract\n /// @dev There is no Access Control here, because it can be handled cheaply through this modifier\n modifier onlyTreasury() {\n if (msg.sender != treasury) revert NotTreasury();\n _;\n }\n\n /// @notice Checks whether the sender has the minting right\n modifier onlyMinter() {\n if (!isMinter[msg.sender]) revert NotMinter();\n _;\n }\n\n /// @notice Checks whether the `msg.sender` has the governor role or not\n modifier onlyGovernor() {\n if (!ITreasury(treasury).isGovernor(msg.sender)) revert NotGovernor();\n _;\n }\n\n /// @notice Checks whether the `msg.sender` has the governor role or the guardian role\n modifier onlyGovernorOrGuardian() {\n if (!ITreasury(treasury).isGovernorOrGuardian(msg.sender)) revert NotGovernorOrGuardian();\n _;\n }\n\n /// @notice Sets up the treasury contract on Polygon after the upgrade\n /// @param _treasury Address of the treasury contract\n function setUpTreasury(address _treasury) external {\n // Only governor on Polygon\n if (msg.sender != 0xdA2D2f638D6fcbE306236583845e5822554c02EA) revert NotGovernor();\n if (address(ITreasury(_treasury).stablecoin()) != address(this)) revert InvalidTreasury();\n if (treasuryInitialized) revert TreasuryAlreadyInitialized();\n treasury = _treasury;\n treasuryInitialized = true;\n emit TreasuryUpdated(_treasury);\n }\n\n // =========================== External Function ===============================\n\n /// @notice Allows anyone to burn agToken without redeeming collateral back\n /// @param amount Amount of stablecoins to burn\n /// @dev This function can typically be called if there is a settlement mechanism to burn stablecoins\n function burnStablecoin(uint256 amount) external {\n _burnCustom(msg.sender, amount);\n }\n\n // ======================= Minter Role Only Functions ==========================\n\n function burnSelf(uint256 amount, address burner) external onlyMinter {\n _burnCustom(burner, amount);\n }\n\n function burnFrom(uint256 amount, address burner, address sender) external onlyMinter {\n _burnFromNoRedeem(amount, burner, sender);\n }\n\n function mint(address account, uint256 amount) external onlyMinter {\n _mint(account, amount);\n }\n\n // ======================= Treasury Only Functions =============================\n\n function addMinter(address minter) external onlyTreasury {\n isMinter[minter] = true;\n emit MinterToggled(minter);\n }\n\n function removeMinter(address minter) external {\n if (msg.sender != address(treasury) && msg.sender != minter) revert InvalidSender();\n isMinter[minter] = false;\n emit MinterToggled(minter);\n }\n\n function setTreasury(address _treasury) external onlyTreasury {\n treasury = _treasury;\n emit TreasuryUpdated(_treasury);\n }\n\n // ============================ Internal Function ==============================\n\n /// @notice Internal version of the function `burnFromNoRedeem`\n /// @param amount Amount to burn\n /// @dev It is at the level of this function that allowance checks are performed\n function _burnFromNoRedeem(uint256 amount, address burner, address sender) internal {\n if (burner != sender) {\n uint256 currentAllowance = allowance(burner, sender);\n if (currentAllowance < amount) revert BurnAmountExceedsAllowance();\n _approve(burner, sender, currentAllowance - amount);\n }\n _burnCustom(burner, amount);\n }\n\n // ==================== External Permissionless Functions ======================\n\n /// @notice Returns the list of all supported bridge tokens\n /// @dev Helpful for UIs\n function allBridgeTokens() external view returns (address[] memory) {\n return bridgeTokensList;\n }\n\n /// @notice Returns the current volume for a bridge, for the current hour\n /// @dev Helpful for UIs\n function currentUsage(address bridge) external view returns (uint256) {\n return usage[bridge][block.timestamp / 3600];\n }\n\n /// @notice Returns the current total volume on the chain for the current hour\n /// @dev Helpful for UIs\n function currentTotalUsage() external view returns (uint256) {\n return chainTotalUsage[block.timestamp / 3600];\n }\n\n /// @notice Mints the canonical token from a supported bridge token\n /// @param bridgeToken Bridge token to use to mint\n /// @param amount Amount of bridge tokens to send\n /// @param to Address to which the stablecoin should be sent\n /// @dev Some fees may be taken by the protocol depending on the token used and on the address calling\n function swapIn(address bridgeToken, uint256 amount, address to) external returns (uint256) {\n BridgeDetails memory bridgeDetails = bridges[bridgeToken];\n if (!bridgeDetails.allowed || bridgeDetails.paused) revert InvalidToken();\n uint256 balance = IERC20(bridgeToken).balanceOf(address(this));\n if (balance + amount > bridgeDetails.limit) {\n // In case someone maliciously sends tokens to this contract\n // Or the limit changes\n if (bridgeDetails.limit > balance) amount = bridgeDetails.limit - balance;\n else {\n amount = 0;\n }\n }\n\n // Checking requirement on the hourly volume\n uint256 hour = block.timestamp / 3600;\n uint256 hourlyUsage = usage[bridgeToken][hour] + amount;\n if (hourlyUsage > bridgeDetails.hourlyLimit) {\n // Edge case when the hourly limit changes\n if (bridgeDetails.hourlyLimit > usage[bridgeToken][hour])\n amount = bridgeDetails.hourlyLimit - usage[bridgeToken][hour];\n else {\n amount = 0;\n }\n }\n usage[bridgeToken][hour] += amount;\n\n IERC20(bridgeToken).safeTransferFrom(msg.sender, address(this), amount);\n uint256 canonicalOut = amount;\n // Computing fees\n if (isFeeExempt[msg.sender] == 0) {\n canonicalOut -= (canonicalOut * bridgeDetails.fee) / BASE_PARAMS;\n }\n _mint(to, canonicalOut);\n return canonicalOut;\n }\n\n /// @notice Burns the canonical token in exchange for a bridge token\n /// @param bridgeToken Bridge token required\n /// @param amount Amount of canonical tokens to burn\n /// @param to Address to which the bridge token should be sent\n /// @dev Some fees may be taken by the protocol depending on the token used and on the address calling\n function swapOut(address bridgeToken, uint256 amount, address to) external returns (uint256) {\n BridgeDetails memory bridgeDetails = bridges[bridgeToken];\n if (!bridgeDetails.allowed || bridgeDetails.paused) revert InvalidToken();\n\n uint256 hour = block.timestamp / 3600;\n uint256 hourlyUsage = chainTotalUsage[hour] + amount;\n // If the amount being swapped out exceeds the limit, we revert\n // We don't want to change the amount being swapped out.\n // The user can decide to send another tx with the correct amount to reach the limit\n if (hourlyUsage > chainTotalHourlyLimit) revert HourlyLimitExceeded();\n chainTotalUsage[hour] = hourlyUsage;\n\n _burnCustom(msg.sender, amount);\n uint256 bridgeOut = amount;\n if (isFeeExempt[msg.sender] == 0) {\n bridgeOut -= (bridgeOut * bridgeDetails.fee) / BASE_PARAMS;\n }\n IERC20(bridgeToken).safeTransfer(to, bridgeOut);\n return bridgeOut;\n }\n\n // ======================= Governance Functions ================================\n\n /// @notice Adds support for a bridge token\n /// @param bridgeToken Bridge token to add: it should be a version of the stablecoin from another bridge\n /// @param limit Limit on the balance of bridge token this contract could hold\n /// @param hourlyLimit Limit on the hourly volume for this bridge\n /// @param paused Whether swapping for this token should be paused or not\n /// @param fee Fee taken upon swapping for or against this token\n function addBridgeToken(\n address bridgeToken,\n uint256 limit,\n uint256 hourlyLimit,\n uint64 fee,\n bool paused\n ) external onlyGovernor {\n if (bridges[bridgeToken].allowed || bridgeToken == address(0)) revert InvalidToken();\n if (fee > BASE_PARAMS) revert TooHighParameterValue();\n BridgeDetails memory _bridge;\n _bridge.limit = limit;\n _bridge.hourlyLimit = hourlyLimit;\n _bridge.paused = paused;\n _bridge.fee = fee;\n _bridge.allowed = true;\n bridges[bridgeToken] = _bridge;\n bridgeTokensList.push(bridgeToken);\n emit BridgeTokenAdded(bridgeToken, limit, hourlyLimit, fee, paused);\n }\n\n /// @notice Removes support for a token\n /// @param bridgeToken Address of the bridge token to remove support for\n function removeBridgeToken(address bridgeToken) external onlyGovernor {\n if (IERC20(bridgeToken).balanceOf(address(this)) != 0) revert AssetStillControlledInReserves();\n delete bridges[bridgeToken];\n // Deletion from `bridgeTokensList` loop\n uint256 bridgeTokensListLength = bridgeTokensList.length;\n for (uint256 i; i < bridgeTokensListLength - 1; ++i) {\n if (bridgeTokensList[i] == bridgeToken) {\n // Replace the `bridgeToken` to remove with the last of the list\n bridgeTokensList[i] = bridgeTokensList[bridgeTokensListLength - 1];\n break;\n }\n }\n // Remove last element in array\n bridgeTokensList.pop();\n emit BridgeTokenRemoved(bridgeToken);\n }\n\n /// @notice Recovers any ERC20 token\n /// @dev Can be used to withdraw bridge tokens for them to be de-bridged on mainnet\n function recoverERC20(address tokenAddress, address to, uint256 amountToRecover) external onlyGovernor {\n IERC20(tokenAddress).safeTransfer(to, amountToRecover);\n emit Recovered(tokenAddress, to, amountToRecover);\n }\n\n /// @notice Updates the `limit` amount for `bridgeToken`\n function setLimit(address bridgeToken, uint256 limit) external onlyGovernorOrGuardian {\n if (!bridges[bridgeToken].allowed) revert InvalidToken();\n bridges[bridgeToken].limit = limit;\n emit BridgeTokenLimitUpdated(bridgeToken, limit);\n }\n\n /// @notice Updates the `hourlyLimit` amount for `bridgeToken`\n function setHourlyLimit(address bridgeToken, uint256 hourlyLimit) external onlyGovernorOrGuardian {\n if (!bridges[bridgeToken].allowed) revert InvalidToken();\n bridges[bridgeToken].hourlyLimit = hourlyLimit;\n emit BridgeTokenHourlyLimitUpdated(bridgeToken, hourlyLimit);\n }\n\n /// @notice Updates the `chainTotalHourlyLimit` amount\n function setChainTotalHourlyLimit(uint256 hourlyLimit) external onlyGovernorOrGuardian {\n chainTotalHourlyLimit = hourlyLimit;\n emit HourlyLimitUpdated(hourlyLimit);\n }\n\n /// @notice Updates the `fee` value for `bridgeToken`\n function setSwapFee(address bridgeToken, uint64 fee) external onlyGovernorOrGuardian {\n if (!bridges[bridgeToken].allowed) revert InvalidToken();\n if (fee > BASE_PARAMS) revert TooHighParameterValue();\n bridges[bridgeToken].fee = fee;\n emit BridgeTokenFeeUpdated(bridgeToken, fee);\n }\n\n /// @notice Pauses or unpauses swapping in and out for a token\n function toggleBridge(address bridgeToken) external onlyGovernorOrGuardian {\n if (!bridges[bridgeToken].allowed) revert InvalidToken();\n bool pausedStatus = bridges[bridgeToken].paused;\n bridges[bridgeToken].paused = !pausedStatus;\n emit BridgeTokenToggled(bridgeToken, !pausedStatus);\n }\n\n /// @notice Toggles fees for the address `theAddress`\n function toggleFeesForAddress(address theAddress) external onlyGovernorOrGuardian {\n uint256 feeExemptStatus = 1 - isFeeExempt[theAddress];\n isFeeExempt[theAddress] = feeExemptStatus;\n emit FeeToggled(theAddress, feeExemptStatus);\n }\n}\n" + }, + "contracts/agToken/polygon/utils/ERC20UpgradeableCustom.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (token/ERC20/ERC20.sol)\n\npragma solidity ^0.8.0;\n\nimport \"@openzeppelin/contracts-upgradeable/token/ERC20/IERC20Upgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/token/ERC20/extensions/IERC20MetadataUpgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/utils/ContextUpgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol\";\n\n/**\n * @dev Implementation of the {IERC20} interface modified by Angle Labs, Inc.\n *\n * This implementation has a custom burn function to avoid having a {Transfer} event to the zero address\n * in some specific burn cases to avoid having Polygon PoS bridge catching this event\n *\n * TIP: For a detailed writeup see our guide\n * https://forum.zeppelin.solutions/t/how-to-implement-erc20-supply-mechanisms/226[How\n * to implement supply mechanisms].\n *\n * We have followed general OpenZeppelin Contracts guidelines: functions revert\n * instead returning `false` on failure. This behavior is nonetheless\n * conventional and does not conflict with the expectations of ERC20\n * applications.\n *\n * Additionally, an {Approval} event is emitted on calls to {transferFrom}.\n * This allows applications to reconstruct the allowance for all accounts just\n * by listening to said events. Other implementations of the EIP may not emit\n * these events, as it isn't required by the specification.\n *\n * Finally, the non-standard {decreaseAllowance} and {increaseAllowance}\n * functions have been added to mitigate the well-known issues around setting\n * allowances. See {IERC20-approve}.\n */\ncontract ERC20UpgradeableCustom is Initializable, ContextUpgradeable, IERC20Upgradeable, IERC20MetadataUpgradeable {\n mapping(address => uint256) private _balances;\n\n mapping(address => mapping(address => uint256)) private _allowances;\n\n uint256 private _totalSupply;\n\n string private _name;\n string private _symbol;\n\n /**\n * @dev Sets the values for {name} and {symbol}.\n *\n * The default value of {decimals} is 18. To select a different value for\n * {decimals} you should overload it.\n *\n * All two of these values are immutable: they can only be set once during\n * construction.\n */\n //solhint-disable-next-line\n function __ERC20_init(string memory name_, string memory symbol_) internal onlyInitializing {\n __Context_init_unchained();\n __ERC20_init_unchained(name_, symbol_);\n }\n\n //solhint-disable-next-line\n function __ERC20_init_unchained(string memory name_, string memory symbol_) internal onlyInitializing {\n _name = name_;\n _symbol = symbol_;\n }\n\n /**\n * @dev Returns the name of the token.\n */\n function name() public view virtual override returns (string memory) {\n return _name;\n }\n\n /**\n * @dev Returns the symbol of the token, usually a shorter version of the\n * name.\n */\n function symbol() public view virtual override returns (string memory) {\n return _symbol;\n }\n\n /**\n * @dev Returns the number of decimals used to get its user representation.\n * For example, if `decimals` equals `2`, a balance of `505` tokens should\n * be displayed to a user as `5.05` (`505 / 10 ** 2`).\n *\n * Tokens usually opt for a value of 18, imitating the relationship between\n * Ether and Wei. This is the value {ERC20} uses, unless this function is\n * overridden;\n *\n * NOTE: This information is only used for _display_ purposes: it in\n * no way affects any of the arithmetic of the contract, including\n * {IERC20-balanceOf} and {IERC20-transfer}.\n */\n function decimals() public view virtual override returns (uint8) {\n return 18;\n }\n\n /**\n * @dev See {IERC20-totalSupply}.\n */\n function totalSupply() public view virtual override returns (uint256) {\n return _totalSupply;\n }\n\n /**\n * @dev See {IERC20-balanceOf}.\n */\n function balanceOf(address account) public view virtual override returns (uint256) {\n return _balances[account];\n }\n\n /**\n * @dev See {IERC20-transfer}.\n *\n * Requirements:\n *\n * - `recipient` cannot be the zero address.\n * - the caller must have a balance of at least `amount`.\n */\n function transfer(address recipient, uint256 amount) public virtual override returns (bool) {\n _transfer(_msgSender(), recipient, amount);\n return true;\n }\n\n /**\n * @dev See {IERC20-allowance}.\n */\n function allowance(address owner, address spender) public view virtual override returns (uint256) {\n return _allowances[owner][spender];\n }\n\n /**\n * @dev See {IERC20-approve}.\n *\n * Requirements:\n *\n * - `spender` cannot be the zero address.\n */\n function approve(address spender, uint256 amount) public virtual override returns (bool) {\n _approve(_msgSender(), spender, amount);\n return true;\n }\n\n /**\n * @dev See {IERC20-transferFrom}.\n *\n * Emits an {Approval} event indicating the updated allowance. This is not\n * required by the EIP. See the note at the beginning of {ERC20}.\n *\n * Requirements:\n *\n * - `sender` and `recipient` cannot be the zero address.\n * - `sender` must have a balance of at least `amount`.\n * - the caller must have allowance for `sender`'s tokens of at least\n * `amount`.\n */\n function transferFrom(address sender, address recipient, uint256 amount) public virtual override returns (bool) {\n _transfer(sender, recipient, amount);\n\n uint256 currentAllowance = _allowances[sender][_msgSender()];\n require(currentAllowance >= amount, \"ERC20: transfer amount exceeds allowance\");\n unchecked {\n _approve(sender, _msgSender(), currentAllowance - amount);\n }\n\n return true;\n }\n\n /**\n * @dev Atomically increases the allowance granted to `spender` by the caller.\n *\n * This is an alternative to {approve} that can be used as a mitigation for\n * problems described in {IERC20-approve}.\n *\n * Emits an {Approval} event indicating the updated allowance.\n *\n * Requirements:\n *\n * - `spender` cannot be the zero address.\n */\n function increaseAllowance(address spender, uint256 addedValue) public virtual returns (bool) {\n _approve(_msgSender(), spender, _allowances[_msgSender()][spender] + addedValue);\n return true;\n }\n\n /**\n * @dev Atomically decreases the allowance granted to `spender` by the caller.\n *\n * This is an alternative to {approve} that can be used as a mitigation for\n * problems described in {IERC20-approve}.\n *\n * Emits an {Approval} event indicating the updated allowance.\n *\n * Requirements:\n *\n * - `spender` cannot be the zero address.\n * - `spender` must have allowance for the caller of at least\n * `subtractedValue`.\n */\n function decreaseAllowance(address spender, uint256 subtractedValue) public virtual returns (bool) {\n uint256 currentAllowance = _allowances[_msgSender()][spender];\n require(currentAllowance >= subtractedValue, \"ERC20: decreased allowance below zero\");\n unchecked {\n _approve(_msgSender(), spender, currentAllowance - subtractedValue);\n }\n\n return true;\n }\n\n /**\n * @dev Moves `amount` of tokens from `sender` to `recipient`.\n *\n * This internal function is equivalent to {transfer}, and can be used to\n * e.g. implement automatic token fees, slashing mechanisms, etc.\n *\n * Emits a {Transfer} event.\n *\n * Requirements:\n *\n * - `sender` cannot be the zero address.\n * - `recipient` cannot be the zero address.\n * - `sender` must have a balance of at least `amount`.\n */\n function _transfer(address sender, address recipient, uint256 amount) internal virtual {\n require(sender != address(0), \"ERC20: transfer from the zero address\");\n require(recipient != address(0), \"ERC20: transfer to the zero address\");\n\n _beforeTokenTransfer(sender, recipient, amount);\n\n uint256 senderBalance = _balances[sender];\n require(senderBalance >= amount, \"ERC20: transfer amount exceeds balance\");\n unchecked {\n _balances[sender] = senderBalance - amount;\n }\n _balances[recipient] += amount;\n\n emit Transfer(sender, recipient, amount);\n\n _afterTokenTransfer(sender, recipient, amount);\n }\n\n /** @dev Creates `amount` tokens and assigns them to `account`, increasing\n * the total supply.\n *\n * Emits a {Transfer} event with `from` set to the zero address.\n *\n * Requirements:\n *\n * - `account` cannot be the zero address.\n */\n function _mint(address account, uint256 amount) internal virtual {\n require(account != address(0), \"ERC20: mint to the zero address\");\n\n _beforeTokenTransfer(address(0), account, amount);\n\n _totalSupply += amount;\n _balances[account] += amount;\n emit Transfer(address(0), account, amount);\n\n _afterTokenTransfer(address(0), account, amount);\n }\n\n /**\n * @dev Destroys `amount` tokens from `account`, reducing the\n * total supply.\n *\n * Emits a {Transfer} event with `to` set to the zero address.\n *\n * Requirements:\n *\n * - `account` cannot be the zero address.\n * - `account` must have at least `amount` tokens.\n */\n function _burn(address account, uint256 amount) internal virtual {\n require(account != address(0), \"ERC20: burn from the zero address\");\n\n _beforeTokenTransfer(account, address(0), amount);\n\n uint256 accountBalance = _balances[account];\n require(accountBalance >= amount, \"ERC20: burn amount exceeds balance\");\n unchecked {\n _balances[account] = accountBalance - amount;\n }\n _totalSupply -= amount;\n\n emit Transfer(account, address(0), amount);\n\n _afterTokenTransfer(account, address(0), amount);\n }\n\n /**\n * @dev Destroys `amount` tokens from `account`, reducing the\n * total supply.\n *\n * Contrary to the other `burn` function, the {Transfer} event is not to the zero address\n * but rather to this address: the reason is that not all burn events should be caught up\n * by the PoS bridge\n *\n * Requirements:\n *\n * - `account` cannot be the zero address.\n * - `account` must have at least `amount` tokens.\n */\n function _burnCustom(address account, uint256 amount) internal virtual {\n require(account != address(0), \"ERC20: burn from the zero address\");\n\n _beforeTokenTransfer(account, address(0), amount);\n\n uint256 accountBalance = _balances[account];\n require(accountBalance >= amount, \"ERC20: burn amount exceeds balance\");\n unchecked {\n _balances[account] = accountBalance - amount;\n }\n _totalSupply -= amount;\n\n emit Transfer(account, address(this), amount);\n\n _afterTokenTransfer(account, address(0), amount);\n }\n\n /**\n * @dev Sets `amount` as the allowance of `spender` over the `owner` s tokens.\n *\n * This internal function is equivalent to `approve`, and can be used to\n * e.g. set automatic allowances for certain subsystems, etc.\n *\n * Emits an {Approval} event.\n *\n * Requirements:\n *\n * - `owner` cannot be the zero address.\n * - `spender` cannot be the zero address.\n */\n function _approve(address owner, address spender, uint256 amount) internal virtual {\n require(owner != address(0), \"ERC20: approve from the zero address\");\n require(spender != address(0), \"ERC20: approve to the zero address\");\n\n _allowances[owner][spender] = amount;\n emit Approval(owner, spender, amount);\n }\n\n /**\n * @dev Hook that is called before any transfer of tokens. This includes\n * minting and burning.\n *\n * Calling conditions:\n *\n * - when `from` and `to` are both non-zero, `amount` of `from`'s tokens\n * will be transferred to `to`.\n * - when `from` is zero, `amount` tokens will be minted for `to`.\n * - when `to` is zero, `amount` of `from`'s tokens will be burned.\n * - `from` and `to` are never both zero.\n *\n * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].\n */\n function _beforeTokenTransfer(address from, address to, uint256 amount) internal virtual {}\n\n /**\n * @dev Hook that is called after any transfer of tokens. This includes\n * minting and burning.\n *\n * Calling conditions:\n *\n * - when `from` and `to` are both non-zero, `amount` of `from`'s tokens\n * has been transferred to `to`.\n * - when `from` is zero, `amount` tokens have been minted for `to`.\n * - when `to` is zero, `amount` of `from`'s tokens have been burned.\n * - `from` and `to` are never both zero.\n *\n * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].\n */\n function _afterTokenTransfer(address from, address to, uint256 amount) internal virtual {}\n\n uint256[45] private __gap;\n}\n" + }, + "contracts/coreBorrow/CoreBorrow.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\n/*\n * █ \n ***** ▓▓▓ \n * ▓▓▓▓▓▓▓ \n * ///. ▓▓▓▓▓▓▓▓▓▓▓▓▓ \n ***** //////// ▓▓▓▓▓▓▓ \n * ///////////// ▓▓▓ \n ▓▓ ////////////////// █ ▓▓ \n ▓▓ ▓▓ /////////////////////// ▓▓ ▓▓ \n ▓▓ ▓▓ //////////////////////////// ▓▓ ▓▓ \n ▓▓ ▓▓ /////////▓▓▓///////▓▓▓///////// ▓▓ ▓▓ \n ▓▓ ,////////////////////////////////////// ▓▓ ▓▓ \n ▓▓ ////////////////////////////////////////// ▓▓ \n ▓▓ //////////////////////▓▓▓▓///////////////////// \n ,//////////////////////////////////////////////////// \n .////////////////////////////////////////////////////////// \n .//////////////////////////██.,//////////////////////////█ \n .//////////////////////████..,./////////////////////██ \n ...////////////////███████.....,.////////////////███ \n ,.,////////////████████ ........,///////////████ \n .,.,//////█████████ ,.......///////████ \n ,..//████████ ........./████ \n ..,██████ .....,███ \n .██ ,.,█ \n \n \n \n ▓▓ ▓▓▓▓▓▓▓▓▓▓ ▓▓▓▓▓▓▓▓▓▓ ▓▓ ▓▓▓▓▓▓▓▓▓▓ \n ▓▓▓▓▓▓ ▓▓▓ ▓▓▓ ▓▓▓ ▓▓ ▓▓ ▓▓▓▓ \n ▓▓▓ ▓▓▓ ▓▓▓ ▓▓▓ ▓▓▓ ▓▓▓ ▓▓ ▓▓▓▓▓ \n ▓▓▓ ▓▓ ▓▓▓ ▓▓▓ ▓▓▓▓▓▓▓▓▓▓ ▓▓▓▓▓▓▓▓▓▓ ▓▓▓▓▓▓▓▓▓▓ \n*/\n\npragma solidity ^0.8.12;\n\nimport \"@openzeppelin/contracts-upgradeable/access/AccessControlEnumerableUpgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol\";\n\nimport \"../interfaces/ICoreBorrow.sol\";\nimport \"../interfaces/IFlashAngle.sol\";\nimport \"../interfaces/ITreasury.sol\";\n\n/// @title CoreBorrow\n/// @author Angle Labs, Inc.\n/// @notice Core contract of the borrowing module. This contract handles the access control across all contracts\n/// (it is read by all treasury contracts), and manages the `flashLoanModule`. It has no minting rights over the\n/// stablecoin contracts\ncontract CoreBorrow is ICoreBorrow, Initializable, AccessControlEnumerableUpgradeable {\n /// @notice Role for guardians\n bytes32 public constant GUARDIAN_ROLE = keccak256(\"GUARDIAN_ROLE\");\n /// @notice Role for governors\n bytes32 public constant GOVERNOR_ROLE = keccak256(\"GOVERNOR_ROLE\");\n /// @notice Role for treasury contract\n bytes32 public constant FLASHLOANER_TREASURY_ROLE = keccak256(\"FLASHLOANER_TREASURY_ROLE\");\n\n // ============================= Reference =====================================\n\n /// @notice Reference to the `flashLoanModule` with minting rights over the different stablecoins of the protocol\n address public flashLoanModule;\n\n // =============================== Events ======================================\n\n event FlashLoanModuleUpdated(address indexed _flashloanModule);\n event CoreUpdated(address indexed _core);\n\n // =============================== Errors ======================================\n\n error InvalidCore();\n error IncompatibleGovernorAndGuardian();\n error NotEnoughGovernorsLeft();\n error ZeroAddress();\n\n /// @notice Initializes the `CoreBorrow` contract and the access control of the borrowing module\n /// @param governor Address of the governor of the Angle Protocol\n /// @param guardian Guardian address of the protocol\n function initialize(address governor, address guardian) public initializer {\n if (governor == address(0) || guardian == address(0)) revert ZeroAddress();\n if (governor == guardian) revert IncompatibleGovernorAndGuardian();\n _setupRole(GOVERNOR_ROLE, governor);\n _setupRole(GUARDIAN_ROLE, guardian);\n _setupRole(GUARDIAN_ROLE, governor);\n _setRoleAdmin(GUARDIAN_ROLE, GOVERNOR_ROLE);\n _setRoleAdmin(GOVERNOR_ROLE, GOVERNOR_ROLE);\n _setRoleAdmin(FLASHLOANER_TREASURY_ROLE, GOVERNOR_ROLE);\n }\n\n /// @custom:oz-upgrades-unsafe-allow constructor\n constructor() initializer {}\n\n // =========================== View Functions ==================================\n\n /// @inheritdoc ICoreBorrow\n function isFlashLoanerTreasury(address treasury) external view returns (bool) {\n return hasRole(FLASHLOANER_TREASURY_ROLE, treasury);\n }\n\n /// @inheritdoc ICoreBorrow\n function isGovernor(address admin) external view returns (bool) {\n return hasRole(GOVERNOR_ROLE, admin);\n }\n\n /// @inheritdoc ICoreBorrow\n function isGovernorOrGuardian(address admin) external view returns (bool) {\n return hasRole(GUARDIAN_ROLE, admin);\n }\n\n // =========================== Governor Functions ==============================\n\n /// @notice Grants the `FLASHLOANER_TREASURY_ROLE` to a `treasury` contract\n /// @param treasury Contract to grant the role to\n /// @dev This function can be used to allow flash loans on a stablecoin of the protocol\n function addFlashLoanerTreasuryRole(address treasury) external {\n grantRole(FLASHLOANER_TREASURY_ROLE, treasury);\n address _flashLoanModule = flashLoanModule;\n if (_flashLoanModule != address(0)) {\n // This call will revert if `treasury` is the zero address or if it is not linked\n // to this `CoreBorrow` contract\n ITreasury(treasury).setFlashLoanModule(_flashLoanModule);\n IFlashAngle(_flashLoanModule).addStablecoinSupport(treasury);\n }\n }\n\n /// @notice Adds a governor in the protocol\n /// @param governor Address to grant the role to\n /// @dev It is necessary to call this function to grant a governor role to make sure\n /// all governors also have the guardian role\n function addGovernor(address governor) external {\n grantRole(GOVERNOR_ROLE, governor);\n grantRole(GUARDIAN_ROLE, governor);\n }\n\n /// @notice Revokes the flash loan ability for a stablecoin\n /// @param treasury Treasury address associated with the stablecoin for which flash loans\n /// should no longer be available\n function removeFlashLoanerTreasuryRole(address treasury) external {\n revokeRole(FLASHLOANER_TREASURY_ROLE, treasury);\n ITreasury(treasury).setFlashLoanModule(address(0));\n address _flashLoanModule = flashLoanModule;\n if (_flashLoanModule != address(0)) {\n IFlashAngle(flashLoanModule).removeStablecoinSupport(treasury);\n }\n }\n\n /// @notice Revokes a governor from the protocol\n /// @param governor Address to remove the role to\n /// @dev It is necessary to call this function to remove a governor role to make sure\n /// the address also loses its guardian role\n function removeGovernor(address governor) external {\n if (getRoleMemberCount(GOVERNOR_ROLE) <= 1) revert NotEnoughGovernorsLeft();\n revokeRole(GUARDIAN_ROLE, governor);\n revokeRole(GOVERNOR_ROLE, governor);\n }\n\n /// @notice Changes the `flashLoanModule` of the protocol\n /// @param _flashLoanModule Address of the new flash loan module\n function setFlashLoanModule(address _flashLoanModule) external onlyRole(GOVERNOR_ROLE) {\n if (_flashLoanModule != address(0)) {\n if (address(IFlashAngle(_flashLoanModule).core()) != address(this)) revert InvalidCore();\n }\n uint256 count = getRoleMemberCount(FLASHLOANER_TREASURY_ROLE);\n for (uint256 i; i < count; ++i) {\n ITreasury(getRoleMember(FLASHLOANER_TREASURY_ROLE, i)).setFlashLoanModule(_flashLoanModule);\n }\n flashLoanModule = _flashLoanModule;\n emit FlashLoanModuleUpdated(_flashLoanModule);\n }\n\n /// @notice Changes the core contract of the protocol\n /// @param _core New core contract\n /// @dev This function verifies that all governors of the current core contract are also governors\n /// of the new core contract. It also notifies the `flashLoanModule` of the change.\n /// @dev Governance wishing to change the core contract should also make sure to call `setCore`\n /// in the different treasury contracts\n function setCore(ICoreBorrow _core) external onlyRole(GOVERNOR_ROLE) {\n uint256 count = getRoleMemberCount(GOVERNOR_ROLE);\n bool success;\n for (uint256 i; i < count; ++i) {\n success = _core.isGovernor(getRoleMember(GOVERNOR_ROLE, i));\n if (!success) break;\n }\n if (!success) revert InvalidCore();\n address _flashLoanModule = flashLoanModule;\n if (_flashLoanModule != address(0)) IFlashAngle(_flashLoanModule).setCore(address(_core));\n emit CoreUpdated(address(_core));\n }\n}\n" + }, + "contracts/deprecated/AgTokenIntermediateUpgrade.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\nimport \"../interfaces/IAgToken.sol\";\nimport \"../interfaces/coreModule/IStableMaster.sol\";\n// OpenZeppelin may update its version of the ERC20PermitUpgradeable token\nimport \"@openzeppelin/contracts-upgradeable/token/ERC20/extensions/draft-ERC20PermitUpgradeable.sol\";\n\n/// @title AgTokenIntermediateUpgrade\n/// @author Angle Labs, Inc.\n/// @notice Base contract for agToken, that is to say Angle's stablecoins\n/// @dev This contract is used to create and handle the stablecoins of Angle protocol\n/// @dev It is still possible for any address to burn its agTokens without redeeming collateral in exchange\n/// @dev This contract is the upgraded version of the AgToken that was first deployed on Ethereum mainnet and is used to\n/// add other minters as needed by AMOs\ncontract AgTokenIntermediateUpgrade is ERC20PermitUpgradeable {\n // ========================= References to other contracts =====================\n\n /// @notice Reference to the `StableMaster` contract associated to this `AgToken`\n address public stableMaster;\n\n // ============================= Constructor ===================================\n\n /// @notice Initializes the `AgToken` contract\n /// @param name_ Name of the token\n /// @param symbol_ Symbol of the token\n /// @param stableMaster_ Reference to the `StableMaster` contract associated to this agToken\n /// @dev By default, agTokens are ERC-20 tokens with 18 decimals\n function initialize(string memory name_, string memory symbol_, address stableMaster_) external initializer {\n __ERC20Permit_init(name_);\n __ERC20_init(name_, symbol_);\n require(stableMaster_ != address(0), \"0\");\n stableMaster = stableMaster_;\n }\n\n /// @custom:oz-upgrades-unsafe-allow constructor\n constructor() initializer {}\n\n // ======= Added Parameters and Variables from the first implementation ========\n\n /// @notice Checks whether an address has the right to mint agTokens\n mapping(address => bool) public isMinter;\n\n // =============================== Added Events ================================\n\n event MinterToggled(address indexed minter);\n\n // =============================== Setup Function ==============================\n\n /// @notice Sets up the minter role and gives it to the governor\n /// @dev This function just has to be called once\n function setUpMinter() external {\n address governor = 0xdC4e6DFe07EFCa50a197DF15D9200883eF4Eb1c8;\n require(msg.sender == governor);\n isMinter[governor] = true;\n emit MinterToggled(governor);\n }\n\n // =============================== Modifiers ===================================\n\n /// @notice Checks whether the sender has the minting right\n modifier onlyMinter() {\n require(isMinter[msg.sender] || msg.sender == stableMaster, \"35\");\n _;\n }\n\n // ========================= External Functions ================================\n // The following functions allow anyone to burn stablecoins without redeeming collateral\n // in exchange for that\n\n /// @notice Destroys `amount` token from the caller without giving collateral back\n /// @param amount Amount to burn\n /// @param poolManager Reference to the `PoolManager` contract for which the `stocksUsers` will\n /// need to be updated\n /// @dev When calling this function, people should specify the `poolManager` for which they want to decrease\n /// the `stocksUsers`: this is a way for the protocol to maintain healthy accounting variables\n function burnNoRedeem(uint256 amount, address poolManager) external {\n _burn(msg.sender, amount);\n IStableMaster(stableMaster).updateStocksUsers(amount, poolManager);\n }\n\n /// @notice Burns `amount` of agToken on behalf of another account without redeeming collateral back\n /// @param account Account to burn on behalf of\n /// @param amount Amount to burn\n /// @param poolManager Reference to the `PoolManager` contract for which the `stocksUsers` will need to be updated\n function burnFromNoRedeem(address account, uint256 amount, address poolManager) external {\n _burnFromNoRedeem(amount, account, msg.sender);\n IStableMaster(stableMaster).updateStocksUsers(amount, poolManager);\n }\n\n // ======================= Minter Role Only Functions ==========================\n\n /// @notice Burns `amount` tokens from a `burner` address\n /// @param amount Amount of tokens to burn\n /// @param burner Address to burn from\n /// @dev This method is to be called by a contract with a minter right on the AgToken after being\n /// requested to do so by an address willing to burn tokens from its address\n function burnSelf(uint256 amount, address burner) external onlyMinter {\n _burn(burner, amount);\n }\n\n /// @notice Burns `amount` tokens from a `burner` address after being asked to by `sender`\n /// @param amount Amount of tokens to burn\n /// @param burner Address to burn from\n /// @param sender Address which requested the burn from `burner`\n /// @dev This method is to be called by a contract with the minter right after being requested\n /// to do so by a `sender` address willing to burn tokens from another `burner` address\n /// @dev The method checks the allowance between the `sender` and the `burner`\n function burnFrom(uint256 amount, address burner, address sender) external onlyMinter {\n _burnFromNoRedeem(amount, burner, sender);\n }\n\n /// @notice Lets the `StableMaster` contract or another whitelisted contract mint agTokens\n /// @param account Address to mint to\n /// @param amount Amount to mint\n /// @dev The contracts allowed to issue agTokens are the `StableMaster` contract, `VaultManager` contracts\n /// associated to this stablecoin as well as the flash loan module (if activated) and potentially contracts\n /// whitelisted by governance\n function mint(address account, uint256 amount) external onlyMinter {\n _mint(account, amount);\n }\n\n // ======================= Minter Only Functions ===============================\n\n /// @notice Adds a minter in the contract\n /// @param minter Minter address to add\n function addMinter(address minter) external onlyMinter {\n isMinter[minter] = true;\n emit MinterToggled(minter);\n }\n\n /// @notice Removes a minter from the contract\n /// @param minter Minter address to remove\n /// @dev This function can at the moment only be called by a minter wishing to revoke itself\n function removeMinter(address minter) external {\n require(msg.sender == minter && isMinter[msg.sender], \"36\");\n isMinter[minter] = false;\n emit MinterToggled(minter);\n }\n\n // ============================ Internal Function ==============================\n\n /// @notice Internal version of the function `burnFromNoRedeem`\n /// @param amount Amount to burn\n /// @dev It is at the level of this function that allowance checks are performed\n function _burnFromNoRedeem(uint256 amount, address burner, address sender) internal {\n if (burner != sender) {\n uint256 currentAllowance = allowance(burner, sender);\n require(currentAllowance >= amount, \"23\");\n _approve(burner, sender, currentAllowance - amount);\n }\n _burn(burner, amount);\n }\n}\n" + }, + "contracts/deprecated/layerZero/OldLayerZeroBridgeToken.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.12;\n\nimport \"./OldOFTCore.sol\";\nimport \"../../interfaces/IAgTokenSideChainMultiBridge.sol\";\nimport \"@openzeppelin/contracts-upgradeable/security/PausableUpgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/token/ERC20/ERC20Upgradeable.sol\";\n\n/// @title LayerZeroBridgeToken\n/// @author Angle Labs, Inc., forked from https://github.com/LayerZero-Labs/solidity-examples/blob/main/contracts/token/oft/OFT.sol\n/// @notice Contract to be deployed on a L2/sidechain for bridging an AgToken using a bridge intermediate token and LayerZero\ncontract OldLayerZeroBridgeToken is OldOFTCore, ERC20Upgradeable, PausableUpgradeable {\n /// @notice Address of the bridgeable token\n /// @dev Immutable\n IAgTokenSideChainMultiBridge public canonicalToken;\n\n // =============================== Errors ================================\n\n error InvalidAllowance();\n\n // ============================= Constructor ===================================\n\n /// @notice Initializes the contract\n /// @param _name Name of the token corresponding to this contract\n /// @param _symbol Symbol of the token corresponding to this contract\n /// @param _lzEndpoint Layer zero endpoint to pass messages\n /// @param _treasury Address of the treasury contract used for access control\n /// @param initialSupply Initial supply to mint to the canonical token address\n /// @dev The initial supply corresponds to the initial amount that could be bridged using this OFT\n function initialize(\n string memory _name,\n string memory _symbol,\n address _lzEndpoint,\n address _treasury,\n uint256 initialSupply\n ) external initializer {\n __ERC20_init_unchained(_name, _symbol);\n __LzAppUpgradeable_init(_lzEndpoint, _treasury);\n\n canonicalToken = IAgTokenSideChainMultiBridge(address(ITreasury(_treasury).stablecoin()));\n _approve(address(this), address(canonicalToken), type(uint256).max);\n _mint(address(canonicalToken), initialSupply);\n }\n\n /// @custom:oz-upgrades-unsafe-allow constructor\n constructor() initializer {}\n\n // ==================== External Permissionless Functions ======================\n\n function sendWithPermit(\n uint16 _dstChainId,\n bytes memory _toAddress,\n uint256 _amount,\n address payable _refundAddress,\n address _zroPaymentAddress,\n bytes memory _adapterParams,\n uint256 deadline,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) public payable override {\n canonicalToken.permit(msg.sender, address(this), _amount, deadline, v, r, s);\n send(_dstChainId, _toAddress, _amount, _refundAddress, _zroPaymentAddress, _adapterParams);\n }\n\n function withdraw(uint256 amount, address recipient) external override returns (uint256 amountMinted) {\n // Does not check allowances as transfers from `msg.sender`\n _transfer(msg.sender, address(this), amount);\n amountMinted = canonicalToken.swapIn(address(this), amount, recipient);\n uint256 leftover = balanceOf(address(this));\n if (leftover != 0) {\n _transfer(address(this), msg.sender, leftover);\n }\n }\n\n // ============================= Internal Functions ===================================\n\n function _debitFrom(\n uint16,\n bytes memory,\n uint256 _amount\n ) internal override whenNotPaused returns (uint256 amountSwapped) {\n // No need to use safeTransferFrom as we know this implementation reverts on failure\n canonicalToken.transferFrom(msg.sender, address(this), _amount);\n\n // Swap canonical for this bridge token. There may be some fees\n amountSwapped = canonicalToken.swapOut(address(this), _amount, address(this));\n _burn(address(this), amountSwapped);\n }\n\n function _debitCreditFrom(uint16, bytes memory, uint256 _amount) internal override whenNotPaused returns (uint256) {\n _burn(msg.sender, _amount);\n return _amount;\n }\n\n function _creditTo(\n uint16,\n address _toAddress,\n uint256 _amount\n ) internal override whenNotPaused returns (uint256 amountMinted) {\n _mint(address(this), _amount);\n amountMinted = canonicalToken.swapIn(address(this), _amount, _toAddress);\n uint256 leftover = balanceOf(address(this));\n if (leftover != 0) {\n _transfer(address(this), _toAddress, leftover);\n }\n }\n\n // ======================= View Functions ================================\n\n /// @inheritdoc ERC165Upgradeable\n function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {\n return\n interfaceId == type(IOFT).interfaceId ||\n interfaceId == type(IERC20).interfaceId ||\n super.supportsInterface(interfaceId);\n }\n\n // ======================= Governance Functions ================================\n\n /// @notice Mints the intermediate contract to the `canonicalToken`\n /// @dev Used to increase the bridging capacity\n function mint(uint256 amount) external onlyGovernorOrGuardian {\n _mint(address(canonicalToken), amount);\n }\n\n /// @notice Burns the intermediate contract from the `canonicalToken`\n /// @dev Used to decrease the bridging capacity\n function burn(uint256 amount) external onlyGovernorOrGuardian {\n _burn(address(canonicalToken), amount);\n }\n\n /// @notice Increases allowance of the `canonicalToken`\n function setupAllowance() public onlyGovernorOrGuardian {\n _approve(address(this), address(canonicalToken), type(uint256).max);\n }\n\n /// @notice Pauses bridging through the contract\n /// @param pause Future pause status\n function pauseSendTokens(bool pause) external onlyGovernorOrGuardian {\n pause ? _pause() : _unpause();\n }\n\n uint256[49] private __gap;\n}\n" + }, + "contracts/deprecated/layerZero/OldNonblockingLzApp.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.12;\n\nimport \"@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol\";\nimport \"../../interfaces/external/layerZero/ILayerZeroReceiver.sol\";\nimport \"../../interfaces/external/layerZero/ILayerZeroUserApplicationConfig.sol\";\nimport \"../../interfaces/external/layerZero/ILayerZeroEndpoint.sol\";\nimport \"../../interfaces/ITreasury.sol\";\n\n/// @title OldNonblockingLzApp\n/// @author Angle Labs, Inc., forked from https://github.com/LayerZero-Labs/solidity-examples/\n/// @notice Base contract for bridging using LayerZero\nabstract contract OldNonblockingLzApp is Initializable, ILayerZeroReceiver, ILayerZeroUserApplicationConfig {\n /// @notice Layer Zero endpoint\n ILayerZeroEndpoint public lzEndpoint;\n\n /// @notice Maps chainIds to failed messages to retry them\n mapping(uint16 => mapping(bytes => mapping(uint64 => bytes32))) public failedMessages;\n\n /// @notice Maps chainIds to their OFT address\n mapping(uint16 => bytes) public trustedRemoteLookup;\n\n /// @notice Reference to the treasury contract to fetch access control\n address public treasury;\n\n // ================================== Events ===================================\n\n event SetTrustedRemote(uint16 _srcChainId, bytes _srcAddress);\n event MessageFailed(uint16 _srcChainId, bytes _srcAddress, uint64 _nonce, bytes _payload);\n\n // =============================== Errors ================================\n\n error NotGovernor();\n error NotGovernorOrGuardian();\n error InsufficientGas();\n error InvalidEndpoint();\n error InvalidSource();\n error InvalidCaller();\n error InvalidParams();\n error InvalidPayload();\n error ZeroAddress();\n\n // ============================= Constructor ===================================\n\n //solhint-disable-next-line\n function __LzAppUpgradeable_init(address _endpoint, address _treasury) internal {\n if (_endpoint == address(0) || _treasury == address(0)) revert ZeroAddress();\n lzEndpoint = ILayerZeroEndpoint(_endpoint);\n treasury = _treasury;\n }\n\n // =============================== Modifiers ===================================\n\n /// @notice Checks whether the `msg.sender` has the governor role or the guardian role\n modifier onlyGovernorOrGuardian() {\n if (!ITreasury(treasury).isGovernorOrGuardian(msg.sender)) revert NotGovernorOrGuardian();\n _;\n }\n\n // ==================== External Permissionless Functions ======================\n\n /// @notice Receives a message from the LZ endpoint and process it\n /// @param _srcChainId ChainId of the source chain - LayerZero standard\n /// @param _srcAddress Sender of the source chain\n /// @param _nonce Nounce of the message\n /// @param _payload Data: recipient address and amount\n function lzReceive(\n uint16 _srcChainId,\n bytes memory _srcAddress,\n uint64 _nonce,\n bytes memory _payload\n ) public virtual override {\n // lzReceive must be called by the endpoint for security\n if (msg.sender != address(lzEndpoint)) revert InvalidEndpoint();\n\n bytes memory trustedRemote = trustedRemoteLookup[_srcChainId];\n // if will still block the message pathway from (srcChainId, srcAddress). should not receive message from untrusted remote.\n if (_srcAddress.length != trustedRemote.length || keccak256(_srcAddress) != keccak256(trustedRemote))\n revert InvalidSource();\n\n _blockingLzReceive(_srcChainId, _srcAddress, _nonce, _payload);\n }\n\n /// @notice Retries a message that previously failed and was stored\n /// @param _srcChainId ChainId of the source chain - LayerZero standard\n /// @param _srcAddress Sender of the source chain\n /// @param _nonce Nounce of the message\n /// @param _payload Data: recipient address and amount\n function retryMessage(\n uint16 _srcChainId,\n bytes memory _srcAddress,\n uint64 _nonce,\n bytes memory _payload\n ) public payable virtual {\n // assert there is message to retry\n bytes32 payloadHash = failedMessages[_srcChainId][_srcAddress][_nonce];\n if (payloadHash == bytes32(0) || keccak256(_payload) != payloadHash) revert InvalidPayload();\n // clear the stored message\n failedMessages[_srcChainId][_srcAddress][_nonce] = bytes32(0);\n // execute the message. revert if it fails again\n _nonblockingLzReceive(_srcChainId, _srcAddress, _nonce, _payload);\n }\n\n // ============================= Internal Functions ===================================\n\n /// @notice Handles message receptions in a non blocking way\n /// @param _srcChainId ChainId of the source chain - LayerZero standard\n /// @param _srcAddress Sender of the source chain\n /// @param _nonce Nounce of the message\n /// @param _payload Data: recipient address and amount\n /// @dev public for the needs of try / catch but effectively internal\n function nonblockingLzReceive(\n uint16 _srcChainId,\n bytes memory _srcAddress,\n uint64 _nonce,\n bytes memory _payload\n ) public virtual {\n // only internal transaction\n if (msg.sender != address(this)) revert InvalidCaller();\n _nonblockingLzReceive(_srcChainId, _srcAddress, _nonce, _payload);\n }\n\n /// @notice Handles message receptions in a non blocking way\n /// @param _srcChainId ChainId of the source chain - LayerZero standard\n /// @param _srcAddress Sender of the source chain\n /// @param _nonce Nounce of the message\n /// @param _payload Data: recipient address and amount\n function _nonblockingLzReceive(\n uint16 _srcChainId,\n bytes memory _srcAddress,\n uint64 _nonce,\n bytes memory _payload\n ) internal virtual;\n\n /// @notice Handles message receptions in a blocking way\n /// @param _srcChainId ChainId of the source chain - LayerZero standard\n /// @param _srcAddress Sender of the source chain\n /// @param _nonce Nounce of the message\n /// @param _payload Data: recipient address and amount\n function _blockingLzReceive(\n uint16 _srcChainId,\n bytes memory _srcAddress,\n uint64 _nonce,\n bytes memory _payload\n ) internal {\n // try-catch all errors/exceptions\n try this.nonblockingLzReceive(_srcChainId, _srcAddress, _nonce, _payload) {\n // do nothing\n } catch {\n // error / exception\n failedMessages[_srcChainId][_srcAddress][_nonce] = keccak256(_payload);\n emit MessageFailed(_srcChainId, _srcAddress, _nonce, _payload);\n }\n }\n\n /// @notice Sends a message to the LZ endpoint and process it\n /// @param _dstChainId L0 defined chain id to send tokens too\n /// @param _payload Data: recipient address and amount\n /// @param _refundAddress Address LayerZero refunds if too much message fee is sent\n /// @param _zroPaymentAddress Set to address(0x0) if not paying in ZRO (LayerZero Token)\n /// @param _adapterParams Flexible bytes array to indicate messaging adapter services in L0\n function _lzSend(\n uint16 _dstChainId,\n bytes memory _payload,\n address payable _refundAddress,\n address _zroPaymentAddress,\n bytes memory _adapterParams\n ) internal virtual {\n bytes memory trustedRemote = trustedRemoteLookup[_dstChainId];\n if (trustedRemote.length == 0) revert InvalidSource();\n //solhint-disable-next-line\n lzEndpoint.send{ value: msg.value }(\n _dstChainId,\n trustedRemote,\n _payload,\n _refundAddress,\n _zroPaymentAddress,\n _adapterParams\n );\n }\n\n // ======================= Governance Functions ================================\n\n /// @notice Sets the corresponding address on an other chain.\n /// @param _srcChainId ChainId of the source chain - LayerZero standard\n /// @param _srcAddress Address on the source chain\n /// @dev Used for both receiving and sending message\n /// @dev There can only be one trusted source per chain\n /// @dev Allows owner to set it multiple times.\n function setTrustedRemote(uint16 _srcChainId, bytes calldata _srcAddress) external onlyGovernorOrGuardian {\n trustedRemoteLookup[_srcChainId] = _srcAddress;\n emit SetTrustedRemote(_srcChainId, _srcAddress);\n }\n\n /// @notice Fetches the default LZ config\n function getConfig(\n uint16 _version,\n uint16 _chainId,\n address,\n uint256 _configType\n ) external view returns (bytes memory) {\n return lzEndpoint.getConfig(_version, _chainId, address(this), _configType);\n }\n\n /// @notice Overrides the default LZ config\n function setConfig(\n uint16 _version,\n uint16 _chainId,\n uint256 _configType,\n bytes calldata _config\n ) external override onlyGovernorOrGuardian {\n lzEndpoint.setConfig(_version, _chainId, _configType, _config);\n }\n\n /// @notice Overrides the default LZ config\n function setSendVersion(uint16 _version) external override onlyGovernorOrGuardian {\n lzEndpoint.setSendVersion(_version);\n }\n\n /// @notice Overrides the default LZ config\n function setReceiveVersion(uint16 _version) external override onlyGovernorOrGuardian {\n lzEndpoint.setReceiveVersion(_version);\n }\n\n /// @notice Unpauses the receive functionalities\n function forceResumeReceive(\n uint16 _srcChainId,\n bytes calldata _srcAddress\n ) external override onlyGovernorOrGuardian {\n lzEndpoint.forceResumeReceive(_srcChainId, _srcAddress);\n }\n\n // ======================= View Functions ================================\n\n /// @notice Checks if the `_srcAddress` corresponds to the trusted source\n function isTrustedRemote(uint16 _srcChainId, bytes calldata _srcAddress) external view returns (bool) {\n bytes memory trustedSource = trustedRemoteLookup[_srcChainId];\n return keccak256(trustedSource) == keccak256(_srcAddress);\n }\n\n uint256[46] private __gap;\n}\n" + }, + "contracts/deprecated/layerZero/OldOFTCore.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.12;\n\nimport \"./OldNonblockingLzApp.sol\";\nimport \"../../agToken/layerZero/utils/IOFTCore.sol\";\nimport \"@openzeppelin/contracts-upgradeable/utils/introspection/ERC165Upgradeable.sol\";\n\n/// @title OFTCore\n/// @author Forked from https://github.com/LayerZero-Labs/solidity-examples/blob/main/contracts/token/oft/OFTCore.sol\n/// but with slight modifications from the Angle Labs, Inc. which added return values to the `_creditTo` and `_debitFrom` functions\n/// @notice Base contract for bridging using LayerZero\nabstract contract OldOFTCore is OldNonblockingLzApp, ERC165Upgradeable, IOFTCore {\n // ==================== External Permissionless Functions ======================\n\n /// @inheritdoc IOFTCore\n function sendWithPermit(\n uint16 _dstChainId,\n bytes memory _toAddress,\n uint256 _amount,\n address payable _refundAddress,\n address _zroPaymentAddress,\n bytes memory _adapterParams,\n uint256 deadline,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) public payable virtual;\n\n /// @inheritdoc IOFTCore\n function send(\n uint16 _dstChainId,\n bytes memory _toAddress,\n uint256 _amount,\n address payable _refundAddress,\n address _zroPaymentAddress,\n bytes memory _adapterParams\n ) public payable virtual {\n _amount = _debitFrom(_dstChainId, _toAddress, _amount);\n\n bytes memory payload = abi.encode(_toAddress, _amount);\n _lzSend(_dstChainId, payload, _refundAddress, _zroPaymentAddress, _adapterParams);\n\n uint64 nonce = lzEndpoint.getOutboundNonce(_dstChainId, address(this));\n emit SendToChain(msg.sender, _dstChainId, _toAddress, _amount, nonce);\n }\n\n /// @inheritdoc IOFTCore\n function sendCredit(\n uint16 _dstChainId,\n bytes memory _toAddress,\n uint256 _amount,\n address payable _refundAddress,\n address _zroPaymentAddress,\n bytes memory _adapterParams\n ) public payable virtual {\n _amount = _debitCreditFrom(_dstChainId, _toAddress, _amount);\n\n _send(_dstChainId, _toAddress, _amount, _refundAddress, _zroPaymentAddress, _adapterParams);\n }\n\n /// @inheritdoc IOFTCore\n function withdraw(uint256 amount, address recipient) external virtual returns (uint256);\n\n // =========================== Internal Functions ==============================\n\n /// @notice Internal function to send `_amount` amount of token to (`_dstChainId`, `_toAddress`)\n /// @param _dstChainId the destination chain identifier\n /// @param _toAddress can be any size depending on the `dstChainId`.\n /// @param _amount the quantity of tokens in wei\n /// @param _refundAddress the address LayerZero refunds if too much message fee is sent\n /// @param _zroPaymentAddress set to address(0x0) if not paying in ZRO (LayerZero Token)\n /// @param _adapterParams is a flexible bytes array to indicate messaging adapter services\n /// @dev Accounting and checks should be performed beforehand\n function _send(\n uint16 _dstChainId,\n bytes memory _toAddress,\n uint256 _amount,\n address payable _refundAddress,\n address _zroPaymentAddress,\n bytes memory _adapterParams\n ) internal {\n bytes memory payload = abi.encode(_toAddress, _amount);\n _lzSend(_dstChainId, payload, _refundAddress, _zroPaymentAddress, _adapterParams);\n\n uint64 nonce = lzEndpoint.getOutboundNonce(_dstChainId, address(this));\n emit SendToChain(msg.sender, _dstChainId, _toAddress, _amount, nonce);\n }\n\n function _nonblockingLzReceive(\n uint16 _srcChainId,\n bytes memory _srcAddress,\n uint64 _nonce,\n bytes memory _payload\n ) internal virtual override {\n // decode and load the toAddress\n (bytes memory toAddressBytes, uint256 amount) = abi.decode(_payload, (bytes, uint256));\n address toAddress;\n //solhint-disable-next-line\n assembly {\n toAddress := mload(add(toAddressBytes, 20))\n }\n amount = _creditTo(_srcChainId, toAddress, amount);\n\n emit ReceiveFromChain(_srcChainId, _srcAddress, toAddress, amount, _nonce);\n }\n\n /// @notice Makes accountability when bridging from this contract using canonical token\n /// @param _dstChainId ChainId of the destination chain - LayerZero standard\n /// @param _toAddress Recipient on the destination chain\n /// @param _amount Amount to bridge\n function _debitFrom(\n uint16 _dstChainId,\n bytes memory _toAddress,\n uint256 _amount\n ) internal virtual returns (uint256);\n\n /// @notice Makes accountability when bridging from this contract's credit\n /// @param _dstChainId ChainId of the destination chain - LayerZero standard\n /// @param _toAddress Recipient on the destination chain\n /// @param _amount Amount to bridge\n function _debitCreditFrom(\n uint16 _dstChainId,\n bytes memory _toAddress,\n uint256 _amount\n ) internal virtual returns (uint256);\n\n /// @notice Makes accountability when bridging to this contract\n /// @param _srcChainId ChainId of the source chain - LayerZero standard\n /// @param _toAddress Recipient on this chain\n /// @param _amount Amount to bridge\n function _creditTo(uint16 _srcChainId, address _toAddress, uint256 _amount) internal virtual returns (uint256);\n\n // ========================== View Functions ===================================\n\n /// @inheritdoc ERC165Upgradeable\n function supportsInterface(\n bytes4 interfaceId\n ) public view virtual override(ERC165Upgradeable, IERC165) returns (bool) {\n return interfaceId == type(IOFTCore).interfaceId || super.supportsInterface(interfaceId);\n }\n\n /// @inheritdoc IOFTCore\n function estimateSendFee(\n uint16 _dstChainId,\n bytes memory _toAddress,\n uint256 _amount,\n bool _useZro,\n bytes memory _adapterParams\n ) public view virtual override returns (uint256 nativeFee, uint256 zroFee) {\n // mock the payload for send()\n bytes memory payload = abi.encode(_toAddress, _amount);\n return lzEndpoint.estimateFees(_dstChainId, address(this), payload, _useZro, _adapterParams);\n }\n\n uint256[50] private __gap;\n}\n" + }, + "contracts/deprecated/OldAgEUR.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\nimport \"../interfaces/IAgToken.sol\";\nimport \"../interfaces/coreModule/IStableMaster.sol\";\nimport \"../interfaces/ITreasury.sol\";\n// OpenZeppelin may update its version of the ERC20PermitUpgradeable token\nimport \"@openzeppelin/contracts-upgradeable/token/ERC20/extensions/draft-ERC20PermitUpgradeable.sol\";\n\n/// @title AgToken\n/// @author Angle Labs, Inc.\n/// @notice Base contract for agToken, that is to say Angle's stablecoins\n/// @dev This contract is used to create and handle the stablecoins of Angle protocol\n/// @dev It is still possible for any address to burn its agTokens without redeeming collateral in exchange\n/// @dev This contract is the upgraded version of the AgToken that was first deployed on Ethereum mainnet\ncontract OldAgEUR is IAgToken, ERC20PermitUpgradeable {\n // ========================= References to other contracts =====================\n\n /// @notice Reference to the `StableMaster` contract associated to this `AgToken`\n address public stableMaster;\n\n // ============================= Constructor ===================================\n\n /// @notice Initializes the `AgToken` contract\n /// @param name_ Name of the token\n /// @param symbol_ Symbol of the token\n /// @param stableMaster_ Reference to the `StableMaster` contract associated to this agToken\n /// @dev By default, agTokens are ERC-20 tokens with 18 decimals\n function initialize(string memory name_, string memory symbol_, address stableMaster_) external initializer {\n __ERC20Permit_init(name_);\n __ERC20_init(name_, symbol_);\n require(stableMaster_ != address(0), \"0\");\n stableMaster = stableMaster_;\n }\n\n /// @custom:oz-upgrades-unsafe-allow constructor\n constructor() initializer {}\n\n // ======= Added Parameters and Variables from the first implementation ========\n\n /// @inheritdoc IAgToken\n mapping(address => bool) public isMinter;\n /// @notice Reference to the treasury contract which can grant minting rights\n address public treasury;\n /// @notice Boolean to check whether the contract has been reinitialized after its upgrade\n bool public treasuryInitialized;\n\n // =============================== Added Events ================================\n\n event TreasuryUpdated(address indexed _treasury);\n event MinterToggled(address indexed minter);\n\n // =============================== Added Errors ================================\n\n error BurnAmountExceedsAllowance();\n error InvalidSender();\n error InvalidTreasury();\n error NotGovernor();\n error NotMinter();\n error NotTreasury();\n error TreasuryAlreadyInitialized();\n\n // =============================== Setup Function ==============================\n\n /// @notice Sets up the treasury contract in this AgToken contract\n /// @param _treasury Treasury contract to add\n /// @dev The address calling this function has to be hard-coded in the contract\n /// @dev Can be called only once\n function setUpTreasury(address _treasury) external {\n // Only governor\n if (msg.sender != 0xdC4e6DFe07EFCa50a197DF15D9200883eF4Eb1c8) revert NotGovernor();\n if (address(ITreasury(_treasury).stablecoin()) != address(this)) revert InvalidTreasury();\n if (treasuryInitialized) revert TreasuryAlreadyInitialized();\n treasury = _treasury;\n treasuryInitialized = true;\n isMinter[stableMaster] = true;\n emit TreasuryUpdated(_treasury);\n }\n\n // =============================== Modifiers ===================================\n\n /// @notice Checks to see if it is the `Treasury` calling this contract\n /// @dev There is no Access Control here, because it can be handled cheaply through this modifier\n modifier onlyTreasury() {\n if (msg.sender != treasury) revert NotTreasury();\n _;\n }\n\n /// @notice Checks whether the sender has the minting right\n modifier onlyMinter() {\n if (!isMinter[msg.sender]) revert NotMinter();\n _;\n }\n\n // ========================= External Functions ================================\n // The following functions allow anyone to burn stablecoins without redeeming collateral\n // in exchange for that\n\n /// @notice Destroys `amount` token from the caller without giving collateral back\n /// @param amount Amount to burn\n /// @param poolManager Reference to the `PoolManager` contract for which the `stocksUsers` will\n /// need to be updated\n /// @dev When calling this function, people should specify the `poolManager` for which they want to decrease\n /// the `stocksUsers`: this is a way for the protocol to maintain healthy accounting variables\n function burnNoRedeem(uint256 amount, address poolManager) external {\n _burn(msg.sender, amount);\n IStableMaster(stableMaster).updateStocksUsers(amount, poolManager);\n }\n\n /// @notice Burns `amount` of agToken on behalf of another account without redeeming collateral back\n /// @param account Account to burn on behalf of\n /// @param amount Amount to burn\n /// @param poolManager Reference to the `PoolManager` contract for which the `stocksUsers` will need to be updated\n function burnFromNoRedeem(address account, uint256 amount, address poolManager) external {\n _burnFromNoRedeem(amount, account, msg.sender);\n IStableMaster(stableMaster).updateStocksUsers(amount, poolManager);\n }\n\n /// @notice Allows anyone to burn agToken without redeeming collateral back\n /// @param amount Amount of stablecoins to burn\n /// @dev This function can typically be called if there is a settlement mechanism to burn stablecoins\n function burnStablecoin(uint256 amount) external {\n _burn(msg.sender, amount);\n }\n\n // ======================= Minter Role Only Functions ==========================\n\n /// @inheritdoc IAgToken\n function burnSelf(uint256 amount, address burner) external onlyMinter {\n _burn(burner, amount);\n }\n\n /// @inheritdoc IAgToken\n function burnFrom(uint256 amount, address burner, address sender) external onlyMinter {\n _burnFromNoRedeem(amount, burner, sender);\n }\n\n /// @inheritdoc IAgToken\n function mint(address account, uint256 amount) external onlyMinter {\n _mint(account, amount);\n }\n\n // ======================= Treasury Only Functions =============================\n\n /// @inheritdoc IAgToken\n function addMinter(address minter) external onlyTreasury {\n isMinter[minter] = true;\n emit MinterToggled(minter);\n }\n\n /// @inheritdoc IAgToken\n function removeMinter(address minter) external {\n // The `treasury` contract cannot remove the `stableMaster`\n if (msg.sender != minter && (msg.sender != address(treasury) || minter == stableMaster)) revert InvalidSender();\n isMinter[minter] = false;\n emit MinterToggled(minter);\n }\n\n /// @inheritdoc IAgToken\n function setTreasury(address _treasury) external onlyTreasury {\n treasury = _treasury;\n emit TreasuryUpdated(_treasury);\n }\n\n // ============================ Internal Function ==============================\n\n /// @notice Internal version of the function `burnFromNoRedeem`\n /// @param amount Amount to burn\n /// @dev It is at the level of this function that allowance checks are performed\n function _burnFromNoRedeem(uint256 amount, address burner, address sender) internal {\n if (burner != sender) {\n uint256 currentAllowance = allowance(burner, sender);\n if (currentAllowance < amount) revert BurnAmountExceedsAllowance();\n _approve(burner, sender, currentAllowance - amount);\n }\n _burn(burner, amount);\n }\n}\n" + }, + "contracts/deprecated/OldAngleHelpers.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\nimport \"../interfaces/IAngleRouter.sol\";\nimport \"../interfaces/coreModule/IAgTokenMainnet.sol\";\nimport \"../interfaces/coreModule/ICore.sol\";\nimport \"../interfaces/coreModule/IOracleCore.sol\";\nimport \"../interfaces/coreModule/IPerpetualManager.sol\";\nimport \"../interfaces/coreModule/IPoolManager.sol\";\nimport \"../interfaces/coreModule/IStableMaster.sol\";\nimport \"@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol\";\nimport \"../interfaces/IVaultManager.sol\";\n\npragma solidity ^0.8.12;\n\nstruct Parameters {\n SLPData slpData;\n MintBurnData feeData;\n PerpetualManagerFeeData perpFeeData;\n PerpetualManagerParamData perpParam;\n}\n\nstruct PerpetualManagerFeeData {\n uint64[] xHAFeesDeposit;\n uint64[] yHAFeesDeposit;\n uint64[] xHAFeesWithdraw;\n uint64[] yHAFeesWithdraw;\n uint64 haBonusMalusDeposit;\n uint64 haBonusMalusWithdraw;\n}\n\nstruct PerpetualManagerParamData {\n uint64 maintenanceMargin;\n uint64 maxLeverage;\n uint64 targetHAHedge;\n uint64 limitHAHedge;\n uint64 lockTime;\n}\n\nstruct CollateralAddresses {\n address stableMaster;\n address poolManager;\n address perpetualManager;\n address sanToken;\n address oracle;\n address gauge;\n address feeManager;\n address[] strategies;\n}\n\n/// @title AngleHelpers\n/// @author Angle Labs, Inc.\n/// @notice Contract with view functions designed to facilitate integrations on the Core module of the Angle Protocol\n/// @dev This contract only contains view functions to be queried off-chain. It was thus not optimized for gas consumption\ncontract OldAngleHelpers is Initializable {\n // ======================== Helper View Functions ==============================\n\n /// @notice Gives the amount of `agToken` you'd be getting if you were executing in the same block a mint transaction\n /// with `amount` of `collateral` in the Core module of the Angle protocol as well as the value of the fees\n /// (in `BASE_PARAMS`) that would be applied during the mint\n /// @return Amount of `agToken` that would be obtained with a mint transaction in the same block\n /// @return Percentage of fees that would be taken during a mint transaction in the same block\n /// @dev This function reverts if the mint transaction was to revert in the same conditions (without taking into account\n /// potential approval problems to the `StableMaster` contract)\n function previewMintAndFees(\n uint256 amount,\n address agToken,\n address collateral\n ) external view returns (uint256, uint256) {\n return _previewMintAndFees(amount, agToken, collateral);\n }\n\n /// @notice Gives the amount of `collateral` you'd be getting if you were executing in the same block a burn transaction\n /// with `amount` of `agToken` in the Core module of the Angle protocol as well as the value of the fees\n /// (in `BASE_PARAMS`) that would be applied during the burn\n /// @return Amount of `collateral` that would be obtained with a burn transaction in the same block\n /// @return Percentage of fees that would be taken during a burn transaction in the same block\n /// @dev This function reverts if the burn transaction was to revert in the same conditions (without taking into account\n /// potential approval problems to the `StableMaster` contract or agToken balance prior to the call)\n function previewBurnAndFees(\n uint256 amount,\n address agToken,\n address collateral\n ) external view returns (uint256, uint256) {\n return _previewBurnAndFees(amount, agToken, collateral);\n }\n\n /// @notice Returns all the addresses associated to the (`agToken`,`collateral`) pair given\n /// @return addresses A struct with all the addresses associated in the Core module\n function getCollateralAddresses(\n address agToken,\n address collateral\n ) external view returns (CollateralAddresses memory addresses) {\n address stableMaster = IAgTokenMainnet(agToken).stableMaster();\n (address poolManager, address perpetualManager, address sanToken, address gauge) = ROUTER.mapPoolManagers(\n stableMaster,\n collateral\n );\n (, , , IOracleCore oracle, , , , , ) = IStableMaster(stableMaster).collateralMap(poolManager);\n addresses.stableMaster = stableMaster;\n addresses.poolManager = poolManager;\n addresses.perpetualManager = perpetualManager;\n addresses.sanToken = sanToken;\n addresses.gauge = gauge;\n addresses.oracle = address(oracle);\n addresses.feeManager = IPoolManager(poolManager).feeManager();\n\n uint256 length = 0;\n while (true) {\n try IPoolManager(poolManager).strategyList(length) returns (address) {\n length += 1;\n } catch {\n break;\n }\n }\n address[] memory strategies = new address[](length);\n for (uint256 i; i < length; ++i) {\n strategies[i] = IPoolManager(poolManager).strategyList(i);\n }\n addresses.strategies = strategies;\n }\n\n /// @notice Gets the addresses of all the `StableMaster` contracts and their associated `AgToken` addresses\n /// @return List of the `StableMaster` addresses of the Angle protocol\n /// @return List of the `AgToken` addresses of the protocol\n /// @dev The place of an agToken address in the list is the same as the corresponding `StableMaster` address\n function getStablecoinAddresses() external view returns (address[] memory, address[] memory) {\n address[] memory stableMasterAddresses = CORE.stablecoinList();\n address[] memory agTokenAddresses = new address[](stableMasterAddresses.length);\n for (uint256 i; i < stableMasterAddresses.length; ++i) {\n agTokenAddresses[i] = IStableMaster(stableMasterAddresses[i]).agToken();\n }\n return (stableMasterAddresses, agTokenAddresses);\n }\n\n /// @notice Returns most of the governance parameters associated to the (`agToken`,`collateral`) pair given\n /// @return params Struct with most of the parameters in the `StableMaster` and `PerpetualManager` contracts\n /// @dev Check out the struct `Parameters` for the meaning of the return values\n function getCollateralParameters(\n address agToken,\n address collateral\n ) external view returns (Parameters memory params) {\n (address stableMaster, address poolManager) = _getStableMasterAndPoolManager(agToken, collateral);\n (\n ,\n ,\n IPerpetualManager perpetualManager,\n ,\n ,\n ,\n ,\n SLPData memory slpData,\n MintBurnData memory feeData\n ) = IStableMaster(stableMaster).collateralMap(poolManager);\n\n params.slpData = slpData;\n params.feeData = feeData;\n params.perpParam.maintenanceMargin = perpetualManager.maintenanceMargin();\n params.perpParam.maxLeverage = perpetualManager.maxLeverage();\n params.perpParam.targetHAHedge = perpetualManager.targetHAHedge();\n params.perpParam.limitHAHedge = perpetualManager.limitHAHedge();\n params.perpParam.lockTime = perpetualManager.lockTime();\n\n params.perpFeeData.haBonusMalusDeposit = perpetualManager.haBonusMalusDeposit();\n params.perpFeeData.haBonusMalusWithdraw = perpetualManager.haBonusMalusWithdraw();\n\n uint256 length = 0;\n while (true) {\n try perpetualManager.xHAFeesDeposit(length) returns (uint64) {\n length += 1;\n } catch {\n break;\n }\n }\n uint64[] memory data = new uint64[](length);\n uint64[] memory data2 = new uint64[](length);\n for (uint256 i; i < length; ++i) {\n data[i] = perpetualManager.xHAFeesDeposit(i);\n data2[i] = perpetualManager.yHAFeesDeposit(i);\n }\n params.perpFeeData.xHAFeesDeposit = data;\n params.perpFeeData.yHAFeesDeposit = data2;\n\n length = 0;\n while (true) {\n try perpetualManager.xHAFeesWithdraw(length) returns (uint64) {\n length += 1;\n } catch {\n break;\n }\n }\n data = new uint64[](length);\n data2 = new uint64[](length);\n for (uint256 i; i < length; ++i) {\n data[i] = perpetualManager.xHAFeesWithdraw(i);\n data2[i] = perpetualManager.yHAFeesWithdraw(i);\n }\n params.perpFeeData.xHAFeesWithdraw = data;\n params.perpFeeData.yHAFeesWithdraw = data2;\n }\n\n /// @notice Returns the address of the poolManager associated to an (`agToken`, `collateral`) pair\n /// in the Core module of the protocol\n function getPoolManager(address agToken, address collateral) public view returns (address poolManager) {\n (, poolManager) = _getStableMasterAndPoolManager(agToken, collateral);\n }\n\n // ======================== Replica Functions ==================================\n // These replicate what is done in the other contracts of the protocol\n\n function _previewBurnAndFees(\n uint256 amount,\n address agToken,\n address collateral\n ) internal view returns (uint256 amountForUserInCollat, uint256 feePercent) {\n (address stableMaster, address poolManager) = _getStableMasterAndPoolManager(agToken, collateral);\n (\n address token,\n ,\n IPerpetualManager perpetualManager,\n IOracleCore oracle,\n uint256 stocksUsers,\n ,\n uint256 collatBase,\n ,\n MintBurnData memory feeData\n ) = IStableMaster(stableMaster).collateralMap(poolManager);\n if (token == address(0) || IStableMaster(stableMaster).paused(keccak256(abi.encodePacked(STABLE, poolManager))))\n revert NotInitialized();\n if (amount > stocksUsers) revert InvalidAmount();\n\n if (feeData.xFeeBurn.length == 1) {\n feePercent = feeData.yFeeBurn[0];\n } else {\n bytes memory data = abi.encode(address(perpetualManager), feeData.targetHAHedge);\n uint64 hedgeRatio = _computeHedgeRatio(stocksUsers - amount, data);\n feePercent = _piecewiseLinear(hedgeRatio, feeData.xFeeBurn, feeData.yFeeBurn);\n }\n feePercent = (feePercent * feeData.bonusMalusBurn) / BASE_PARAMS;\n\n amountForUserInCollat = (amount * (BASE_PARAMS - feePercent) * collatBase) / (oracle.readUpper() * BASE_PARAMS);\n }\n\n function _previewMintAndFees(\n uint256 amount,\n address agToken,\n address collateral\n ) internal view returns (uint256 amountForUserInStable, uint256 feePercent) {\n (address stableMaster, address poolManager) = _getStableMasterAndPoolManager(agToken, collateral);\n (\n address token,\n ,\n IPerpetualManager perpetualManager,\n IOracleCore oracle,\n uint256 stocksUsers,\n ,\n ,\n ,\n MintBurnData memory feeData\n ) = IStableMaster(stableMaster).collateralMap(poolManager);\n if (token == address(0) || IStableMaster(stableMaster).paused(keccak256(abi.encodePacked(STABLE, poolManager))))\n revert NotInitialized();\n\n amountForUserInStable = oracle.readQuoteLower(amount);\n\n if (feeData.xFeeMint.length == 1) feePercent = feeData.yFeeMint[0];\n else {\n bytes memory data = abi.encode(address(perpetualManager), feeData.targetHAHedge);\n uint64 hedgeRatio = _computeHedgeRatio(amountForUserInStable + stocksUsers, data);\n feePercent = _piecewiseLinear(hedgeRatio, feeData.xFeeMint, feeData.yFeeMint);\n }\n feePercent = (feePercent * feeData.bonusMalusMint) / BASE_PARAMS;\n\n amountForUserInStable = (amountForUserInStable * (BASE_PARAMS - feePercent)) / BASE_PARAMS;\n if (stocksUsers + amountForUserInStable > feeData.capOnStableMinted) revert InvalidAmount();\n }\n\n // ======================== Utility Functions ==================================\n // These utility functions are taken from other contracts of the protocol\n\n function _computeHedgeRatio(uint256 newStocksUsers, bytes memory data) internal view returns (uint64 ratio) {\n (address perpetualManager, uint64 targetHAHedge) = abi.decode(data, (address, uint64));\n uint256 totalHedgeAmount = IPerpetualManager(perpetualManager).totalHedgeAmount();\n newStocksUsers = (targetHAHedge * newStocksUsers) / BASE_PARAMS;\n if (newStocksUsers > totalHedgeAmount) ratio = uint64((totalHedgeAmount * BASE_PARAMS) / newStocksUsers);\n else ratio = uint64(BASE_PARAMS);\n }\n\n function _piecewiseLinear(uint64 x, uint64[] memory xArray, uint64[] memory yArray) internal pure returns (uint64) {\n if (x >= xArray[xArray.length - 1]) {\n return yArray[xArray.length - 1];\n } else if (x <= xArray[0]) {\n return yArray[0];\n } else {\n uint256 lower;\n uint256 upper = xArray.length - 1;\n uint256 mid;\n while (upper - lower > 1) {\n mid = lower + (upper - lower) / 2;\n if (xArray[mid] <= x) {\n lower = mid;\n } else {\n upper = mid;\n }\n }\n if (yArray[upper] > yArray[lower]) {\n return\n yArray[lower] +\n ((yArray[upper] - yArray[lower]) * (x - xArray[lower])) /\n (xArray[upper] - xArray[lower]);\n } else {\n return\n yArray[lower] -\n ((yArray[lower] - yArray[upper]) * (x - xArray[lower])) /\n (xArray[upper] - xArray[lower]);\n }\n }\n }\n\n function _getStableMasterAndPoolManager(\n address agToken,\n address collateral\n ) internal view returns (address stableMaster, address poolManager) {\n stableMaster = IAgTokenMainnet(agToken).stableMaster();\n (poolManager, , , ) = ROUTER.mapPoolManagers(stableMaster, collateral);\n }\n\n // ====================== Constants and Initializers ===========================\n\n IAngleRouter public constant ROUTER = IAngleRouter(0xBB755240596530be0c1DE5DFD77ec6398471561d);\n ICore public constant CORE = ICore(0x61ed74de9Ca5796cF2F8fD60D54160D47E30B7c3);\n\n bytes32 public constant STABLE = keccak256(\"STABLE\");\n uint256 public constant BASE_PARAMS = 10 ** 9;\n\n error NotInitialized();\n error InvalidAmount();\n\n /// @custom:oz-upgrades-unsafe-allow constructor\n constructor() initializer {}\n}\n" + }, + "contracts/deprecated/vaultManager/OldVaultManagerERC721.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\nimport \"./OldVaultManagerStorage.sol\";\n\n/// @title VaultManagerERC721\n/// @author Angle Labs, Inc.\n/// @dev Base ERC721 Implementation of VaultManager\nabstract contract OldVaultManagerERC721 is IERC721MetadataUpgradeable, OldVaultManagerStorage {\n using SafeERC20 for IERC20;\n using Address for address;\n\n /// @inheritdoc IERC721MetadataUpgradeable\n string public name;\n /// @inheritdoc IERC721MetadataUpgradeable\n string public symbol;\n\n // ================================= MODIFIERS =================================\n\n /// @notice Checks if the person interacting with the vault with `vaultID` is approved\n /// @param caller Address of the person seeking to interact with the vault\n /// @param vaultID ID of the concerned vault\n modifier onlyApprovedOrOwner(address caller, uint256 vaultID) {\n if (!_isApprovedOrOwner(caller, vaultID)) revert NotApproved();\n _;\n }\n\n // ================================ ERC721 LOGIC ===============================\n\n /// @notice Checks whether a given address is approved for a vault or owns this vault\n /// @param spender Address for which vault ownership should be checked\n /// @param vaultID ID of the vault to check\n /// @return Whether the `spender` address owns or is approved for `vaultID`\n function isApprovedOrOwner(address spender, uint256 vaultID) external view returns (bool) {\n return _isApprovedOrOwner(spender, vaultID);\n }\n\n /// @inheritdoc IERC721MetadataUpgradeable\n function tokenURI(uint256 vaultID) external view returns (string memory) {\n if (!_exists(vaultID)) revert NonexistentVault();\n // There is no vault with `vaultID` equal to 0, so the following variable is\n // always greater than zero\n uint256 temp = vaultID;\n uint256 digits;\n while (temp != 0) {\n digits++;\n temp /= 10;\n }\n bytes memory buffer = new bytes(digits);\n while (vaultID != 0) {\n digits -= 1;\n buffer[digits] = bytes1(uint8(48 + uint256(vaultID % 10)));\n vaultID /= 10;\n }\n return bytes(_baseURI).length > 0 ? string(abi.encodePacked(_baseURI, string(buffer))) : \"\";\n }\n\n /// @inheritdoc IERC721Upgradeable\n function balanceOf(address owner) external view returns (uint256) {\n if (owner == address(0)) revert ZeroAddress();\n return _balances[owner];\n }\n\n /// @inheritdoc IERC721Upgradeable\n function ownerOf(uint256 vaultID) external view returns (address) {\n return _ownerOf(vaultID);\n }\n\n /// @inheritdoc IERC721Upgradeable\n function approve(address to, uint256 vaultID) external {\n address owner = _ownerOf(vaultID);\n if (to == owner) revert ApprovalToOwner();\n if (msg.sender != owner && !isApprovedForAll(owner, msg.sender)) revert NotApproved();\n\n _approve(to, vaultID);\n }\n\n /// @inheritdoc IERC721Upgradeable\n function getApproved(uint256 vaultID) external view returns (address) {\n if (!_exists(vaultID)) revert NonexistentVault();\n return _getApproved(vaultID);\n }\n\n /// @inheritdoc IERC721Upgradeable\n function setApprovalForAll(address operator, bool approved) external {\n _setApprovalForAll(msg.sender, operator, approved);\n }\n\n /// @inheritdoc IERC721Upgradeable\n function isApprovedForAll(address owner, address operator) public view returns (bool) {\n return _operatorApprovals[owner][operator] == 1;\n }\n\n /// @inheritdoc IERC721Upgradeable\n function transferFrom(address from, address to, uint256 vaultID) external onlyApprovedOrOwner(msg.sender, vaultID) {\n _transfer(from, to, vaultID);\n }\n\n /// @inheritdoc IERC721Upgradeable\n function safeTransferFrom(address from, address to, uint256 vaultID) external {\n safeTransferFrom(from, to, vaultID, \"\");\n }\n\n /// @inheritdoc IERC721Upgradeable\n function safeTransferFrom(\n address from,\n address to,\n uint256 vaultID,\n bytes memory _data\n ) public onlyApprovedOrOwner(msg.sender, vaultID) {\n _safeTransfer(from, to, vaultID, _data);\n }\n\n // ================================ ERC165 LOGIC ===============================\n\n /// @inheritdoc IERC165Upgradeable\n function supportsInterface(bytes4 interfaceId) external pure returns (bool) {\n return\n interfaceId == type(IERC721MetadataUpgradeable).interfaceId ||\n interfaceId == type(IERC721Upgradeable).interfaceId ||\n interfaceId == type(IVaultManager).interfaceId ||\n interfaceId == type(IERC165Upgradeable).interfaceId;\n }\n\n // ================== INTERNAL FUNCTIONS FOR THE ERC721 LOGIC ==================\n\n /// @notice Internal version of the `ownerOf` function\n function _ownerOf(uint256 vaultID) internal view returns (address owner) {\n owner = _owners[vaultID];\n if (owner == address(0)) revert NonexistentVault();\n }\n\n /// @notice Internal version of the `getApproved` function\n function _getApproved(uint256 vaultID) internal view returns (address) {\n return _vaultApprovals[vaultID];\n }\n\n /// @notice Internal version of the `safeTransferFrom` function (with the data parameter)\n function _safeTransfer(address from, address to, uint256 vaultID, bytes memory _data) internal {\n _transfer(from, to, vaultID);\n if (!_checkOnERC721Received(from, to, vaultID, _data)) revert NonERC721Receiver();\n }\n\n /// @notice Checks whether a vault exists\n /// @param vaultID ID of the vault to check\n /// @return Whether `vaultID` has been created\n function _exists(uint256 vaultID) internal view returns (bool) {\n return _owners[vaultID] != address(0);\n }\n\n /// @notice Internal version of the `isApprovedOrOwner` function\n function _isApprovedOrOwner(address spender, uint256 vaultID) internal view returns (bool) {\n // The following checks if the vault exists\n address owner = _ownerOf(vaultID);\n return (spender == owner || _getApproved(vaultID) == spender || _operatorApprovals[owner][spender] == 1);\n }\n\n /// @notice Internal version of the `createVault` function\n /// Mints `vaultID` and transfers it to `to`\n /// @dev This method is equivalent to the `_safeMint` method used in OpenZeppelin ERC721 contract\n /// @dev Emits a {Transfer} event\n function _mint(address to) internal returns (uint256 vaultID) {\n if (whitelistingActivated && (isWhitelisted[to] != 1 || isWhitelisted[msg.sender] != 1))\n revert NotWhitelisted();\n if (to == address(0)) revert ZeroAddress();\n\n unchecked {\n vaultIDCount += 1;\n }\n\n vaultID = vaultIDCount;\n _beforeTokenTransfer(address(0), to, vaultID);\n\n unchecked {\n _balances[to] += 1;\n }\n\n _owners[vaultID] = to;\n emit Transfer(address(0), to, vaultID);\n if (!_checkOnERC721Received(address(0), to, vaultID, \"\")) revert NonERC721Receiver();\n }\n\n /// @notice Destroys `vaultID`\n /// @dev `vaultID` must exist\n /// @dev Emits a {Transfer} event\n function _burn(uint256 vaultID) internal {\n address owner = _ownerOf(vaultID);\n\n _beforeTokenTransfer(owner, address(0), vaultID);\n // Clear approvals\n _approve(address(0), vaultID);\n // The following line cannot underflow as the owner's balance is necessarily\n // greater than 1\n unchecked {\n _balances[owner] -= 1;\n }\n delete _owners[vaultID];\n delete vaultData[vaultID];\n\n emit Transfer(owner, address(0), vaultID);\n }\n\n /// @notice Transfers `vaultID` from `from` to `to` as opposed to {transferFrom},\n /// this imposes no restrictions on msg.sender\n /// @dev `to` cannot be the zero address and `perpetualID` must be owned by `from`\n /// @dev Emits a {Transfer} event\n /// @dev A whitelist check is performed if necessary on the `to` address\n function _transfer(address from, address to, uint256 vaultID) internal {\n if (_ownerOf(vaultID) != from) revert NotApproved();\n if (to == address(0)) revert ZeroAddress();\n if (whitelistingActivated && isWhitelisted[to] != 1) revert NotWhitelisted();\n\n _beforeTokenTransfer(from, to, vaultID);\n\n // Clear approvals from the previous owner\n _approve(address(0), vaultID);\n unchecked {\n _balances[from] -= 1;\n _balances[to] += 1;\n }\n _owners[vaultID] = to;\n\n emit Transfer(from, to, vaultID);\n }\n\n /// @notice Approves `to` to operate on `vaultID`\n function _approve(address to, uint256 vaultID) internal {\n _vaultApprovals[vaultID] = to;\n emit Approval(_ownerOf(vaultID), to, vaultID);\n }\n\n /// @notice Internal version of the `setApprovalForAll` function\n /// @dev It contains an `approver` field to be used in case someone signs a permit for a particular\n /// address, and this signature is given to the contract by another address (like a router)\n function _setApprovalForAll(address approver, address operator, bool approved) internal {\n if (operator == approver) revert ApprovalToCaller();\n uint256 approval = approved ? 1 : 0;\n _operatorApprovals[approver][operator] = approval;\n emit ApprovalForAll(approver, operator, approved);\n }\n\n /// @notice Internal function to invoke {IERC721Receiver-onERC721Received} on a target address\n /// The call is not executed if the target address is not a contract\n /// @param from Address representing the previous owner of the given token ID\n /// @param to Target address that will receive the tokens\n /// @param vaultID ID of the token to be transferred\n /// @param _data Bytes optional data to send along with the call\n /// @return Bool whether the call correctly returned the expected value\n function _checkOnERC721Received(\n address from,\n address to,\n uint256 vaultID,\n bytes memory _data\n ) private returns (bool) {\n if (to.isContract()) {\n try IERC721ReceiverUpgradeable(to).onERC721Received(msg.sender, from, vaultID, _data) returns (\n bytes4 retval\n ) {\n return retval == IERC721ReceiverUpgradeable.onERC721Received.selector;\n } catch (bytes memory reason) {\n if (reason.length == 0) {\n revert NonERC721Receiver();\n } else {\n // solhint-disable-next-line no-inline-assembly\n assembly {\n revert(add(32, reason), mload(reason))\n }\n }\n }\n } else {\n return true;\n }\n }\n\n /// @notice Hook that is called before any token transfer. This includes minting and burning.\n /// Calling conditions:\n ///\n /// - When `from` and `to` are both non-zero, `from`'s `vaultID` will be\n /// transferred to `to`.\n /// - When `from` is zero, `vaultID` will be minted for `to`.\n /// - When `to` is zero, `from`'s `vaultID` will be burned.\n /// - `from` and `to` are never both zero.\n function _beforeTokenTransfer(address from, address to, uint256 vaultID) internal virtual {}\n}\n" + }, + "contracts/deprecated/vaultManager/OldVaultManagerPermit.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\nimport \"./OldVaultManagerERC721.sol\";\nimport \"../../interfaces/external/IERC1271.sol\";\n\n/// @title VaultManagerPermit\n/// @author Angle Labs, Inc.\n/// @dev Base Implementation of permit functions for the `VaultManager` contract\nabstract contract OldVaultManagerPermit is Initializable, OldVaultManagerERC721 {\n using Address for address;\n\n mapping(address => uint256) private _nonces;\n /* solhint-disable var-name-mixedcase */\n bytes32 private _HASHED_NAME;\n bytes32 private _HASHED_VERSION;\n bytes32 private _PERMIT_TYPEHASH;\n /* solhint-enable var-name-mixedcase */\n\n error ExpiredDeadline();\n error InvalidSignature();\n\n //solhint-disable-next-line\n function __ERC721Permit_init(string memory _name) internal onlyInitializing {\n _PERMIT_TYPEHASH = keccak256(\n \"Permit(address owner,address spender,bool approved,uint256 nonce,uint256 deadline)\"\n );\n _HASHED_NAME = keccak256(bytes(_name));\n _HASHED_VERSION = keccak256(bytes(\"1\"));\n }\n\n /// @notice Allows an address to give or revoke approval for all its vaults to another address\n /// @param owner Address signing the permit and giving (or revoking) its approval for all the controlled vaults\n /// @param spender Address to give approval to\n /// @param approved Whether to give or revoke the approval\n /// @param deadline Deadline parameter for the signature to be valid\n /// @dev The `v`, `r`, and `s` parameters are used as signature data\n function permit(\n address owner,\n address spender,\n bool approved,\n uint256 deadline,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) external {\n if (block.timestamp > deadline) revert ExpiredDeadline();\n // Additional signature checks performed in the `ECDSAUpgradeable.recover` function\n if (uint256(s) > 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D576E7357A4501DDFE92F46681B20A0 || (v != 27 && v != 28))\n revert InvalidSignature();\n\n bytes32 digest = keccak256(\n abi.encodePacked(\n \"\\x19\\x01\",\n _domainSeparatorV4(),\n keccak256(\n abi.encode(\n _PERMIT_TYPEHASH,\n // 0x3f43a9c6bafb5c7aab4e0cfe239dc5d4c15caf0381c6104188191f78a6640bd8,\n owner,\n spender,\n approved,\n _useNonce(owner),\n deadline\n )\n )\n )\n );\n if (owner.isContract()) {\n if (IERC1271(owner).isValidSignature(digest, abi.encodePacked(r, s, v)) != 0x1626ba7e)\n revert InvalidSignature();\n } else {\n address signer = ecrecover(digest, v, r, s);\n if (signer != owner || signer == address(0)) revert InvalidSignature();\n }\n\n _setApprovalForAll(owner, spender, approved);\n }\n\n /// @notice Returns the current nonce for an `owner` address\n function nonces(address owner) public view returns (uint256) {\n return _nonces[owner];\n }\n\n /// @notice Returns the domain separator for the current chain.\n // solhint-disable-next-line func-name-mixedcase\n function DOMAIN_SEPARATOR() external view returns (bytes32) {\n return _domainSeparatorV4();\n }\n\n /// @notice Internal version of the `DOMAIN_SEPARATOR` function\n function _domainSeparatorV4() internal view returns (bytes32) {\n return\n keccak256(\n abi.encode(\n // keccak256('EIP712Domain(string name,string version,uint256 chainId,address verifyingContract)')\n 0x8b73c3c69bb8fe3d512ecc4cf759cc79239f7b179b0ffacaa9a75d522b39400f,\n _HASHED_NAME,\n _HASHED_VERSION,\n block.chainid,\n address(this)\n )\n );\n }\n\n /// @notice Consumes a nonce for an address: returns the current value and increments it\n function _useNonce(address owner) internal returns (uint256 current) {\n current = _nonces[owner];\n _nonces[owner] = current + 1;\n }\n\n uint256[49] private __gap;\n}\n" + }, + "contracts/deprecated/vaultManager/OldVaultManagerStorage.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\nimport \"@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/token/ERC20/extensions/draft-IERC20PermitUpgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/token/ERC721/IERC721ReceiverUpgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/interfaces/IERC721MetadataUpgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/utils/introspection/IERC165Upgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/utils/AddressUpgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/security/ReentrancyGuardUpgradeable.sol\";\nimport \"@openzeppelin/contracts/token/ERC20/extensions/IERC20Metadata.sol\";\nimport \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\nimport \"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\";\n\nimport \"../../interfaces/IAgToken.sol\";\nimport \"../../interfaces/IOracle.sol\";\nimport \"../../interfaces/ISwapper.sol\";\nimport \"../../interfaces/ITreasury.sol\";\nimport \"../../interfaces/IVaultManager.sol\";\nimport \"../../interfaces/governance/IVeBoostProxy.sol\";\n\n/// @title VaultManagerStorage\n/// @author Angle Labs, Inc.\n/// @dev Variables, references, parameters and events needed in the `VaultManager` contract\n// solhint-disable-next-line max-states-count\ncontract OldVaultManagerStorage is IVaultManagerStorage, Initializable, ReentrancyGuardUpgradeable {\n /// @notice Base used for parameter computation: almost all the parameters of this contract are set in `BASE_PARAMS`\n uint256 public constant BASE_PARAMS = 10 ** 9;\n /// @notice Base used for interest rate computation\n uint256 public constant BASE_INTEREST = 10 ** 27;\n /// @notice Used for interest rate computation\n uint256 public constant HALF_BASE_INTEREST = 10 ** 27 / 2;\n\n // ================================= REFERENCES ================================\n\n /// @inheritdoc IVaultManagerStorage\n ITreasury public treasury;\n /// @inheritdoc IVaultManagerStorage\n IERC20 public collateral;\n /// @inheritdoc IVaultManagerStorage\n IAgToken public stablecoin;\n /// @inheritdoc IVaultManagerStorage\n IOracle public oracle;\n /// @notice Reference to the contract which computes adjusted veANGLE balances for liquidators boosts\n IVeBoostProxy public veBoostProxy;\n /// @notice Base of the collateral\n uint256 internal _collatBase;\n\n // ================================= PARAMETERS ================================\n // Unless specified otherwise, parameters of this contract are expressed in `BASE_PARAMS`\n\n /// @notice Maximum amount of stablecoins that can be issued with this contract (in `BASE_TOKENS`). This parameter should\n /// not be bigger than `type(uint256).max / BASE_INTEREST` otherwise there may be some overflows in the `increaseDebt` function\n uint256 public debtCeiling;\n /// @notice Threshold veANGLE balance values for the computation of the boost for liquidators: the length of this array\n /// should normally be 2. The base of the x-values in this array should be `BASE_TOKENS`\n uint256[] public xLiquidationBoost;\n /// @notice Values of the liquidation boost at the threshold values of x\n uint256[] public yLiquidationBoost;\n /// @inheritdoc IVaultManagerStorage\n uint64 public collateralFactor;\n /// @notice Maximum Health factor at which a vault can end up after a liquidation (unless it's fully liquidated)\n uint64 public targetHealthFactor;\n /// @notice Upfront fee taken when borrowing stablecoins: this fee is optional and should in practice not be used\n uint64 public borrowFee;\n /// @notice Upfront fee taken when repaying stablecoins: this fee is optional as well. It should be smaller\n /// than the liquidation surcharge (cf below) to avoid exploits where people voluntarily get liquidated at a 0\n /// discount to pay smaller repaying fees\n uint64 public repayFee;\n /// @notice Per second interest taken to borrowers taking agToken loans. Contrarily to other parameters, it is set in `BASE_INTEREST`\n /// that is to say in base 10**27\n uint64 public interestRate;\n /// @notice Fee taken by the protocol during a liquidation. Technically, this value is not the fee per se, it's 1 - fee.\n /// For instance for a 2% fee, `liquidationSurcharge` should be 98%\n uint64 public liquidationSurcharge;\n /// @notice Maximum discount given to liquidators\n uint64 public maxLiquidationDiscount;\n /// @notice Whether whitelisting is required to own a vault or not\n bool public whitelistingActivated;\n /// @notice Whether the contract is paused or not\n bool public paused;\n\n // ================================= VARIABLES =================================\n\n /// @notice Timestamp at which the `interestAccumulator` was updated\n uint256 public lastInterestAccumulatorUpdated;\n /// @inheritdoc IVaultManagerStorage\n uint256 public interestAccumulator;\n /// @inheritdoc IVaultManagerStorage\n uint256 public totalNormalizedDebt;\n /// @notice Surplus accumulated by the contract: surplus is always in stablecoins, and is then reset\n /// when the value is communicated to the treasury contract\n uint256 public surplus;\n /// @notice Bad debt made from liquidated vaults which ended up having no collateral and a positive amount\n /// of stablecoins\n uint256 public badDebt;\n\n // ================================== MAPPINGS =================================\n\n /// @inheritdoc IVaultManagerStorage\n mapping(uint256 => Vault) public vaultData;\n /// @notice Maps an address to 1 if it's whitelisted and can open or own a vault\n mapping(address => uint256) public isWhitelisted;\n\n // ================================ ERC721 DATA ================================\n\n /// @inheritdoc IVaultManagerStorage\n uint256 public vaultIDCount;\n\n /// @notice URI\n string internal _baseURI;\n\n // Mapping from `vaultID` to owner address\n mapping(uint256 => address) internal _owners;\n\n // Mapping from owner address to vault owned count\n mapping(address => uint256) internal _balances;\n\n // Mapping from `vaultID` to approved address\n mapping(uint256 => address) internal _vaultApprovals;\n\n // Mapping from owner to operator approvals\n mapping(address => mapping(address => uint256)) internal _operatorApprovals;\n\n uint256[50] private __gap;\n\n // =================================== EVENTS ==================================\n\n event AccruedToTreasury(uint256 surplusEndValue, uint256 badDebtEndValue);\n event CollateralAmountUpdated(uint256 vaultID, uint256 collateralAmount, uint8 isIncrease);\n event InterestAccumulatorUpdated(uint256 value, uint256 timestamp);\n event InternalDebtUpdated(uint256 vaultID, uint256 internalAmount, uint8 isIncrease);\n event FiledUint64(uint64 param, bytes32 what);\n event DebtCeilingUpdated(uint256 debtCeiling);\n event LiquidationBoostParametersUpdated(address indexed _veBoostProxy, uint256[] xBoost, uint256[] yBoost);\n event LiquidatedVaults(uint256[] vaultIDs);\n event DebtTransferred(uint256 srcVaultID, uint256 dstVaultID, address dstVaultManager, uint256 amount);\n\n // =================================== ERRORS ==================================\n\n error ApprovalToOwner();\n error ApprovalToCaller();\n error DustyLeftoverAmount();\n error DebtCeilingExceeded();\n error HealthyVault();\n error IncompatibleLengths();\n error InsolventVault();\n error InvalidParameterValue();\n error InvalidParameterType();\n error InvalidSetOfParameters();\n error InvalidTreasury();\n error NonERC721Receiver();\n error NonexistentVault();\n error NotApproved();\n error NotGovernor();\n error NotGovernorOrGuardian();\n error NotTreasury();\n error NotWhitelisted();\n error NotVaultManager();\n error Paused();\n error TooHighParameterValue();\n error TooSmallParameterValue();\n error ZeroAddress();\n\n /// @custom:oz-upgrades-unsafe-allow constructor\n constructor() initializer {}\n}\n" + }, + "contracts/external/ProxyAdmin.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\nimport \"./TransparentUpgradeableProxy.sol\";\nimport \"@openzeppelin/contracts/access/Ownable.sol\";\n\n/**\n * @dev This is an auxiliary contract meant to be assigned as the admin of a {TransparentUpgradeableProxy}. For an\n * explanation of why you would want to use this see the documentation for {TransparentUpgradeableProxy}.\n * This contract was fully forked from OpenZeppelin `ProxyAdmin`\n */\ncontract ProxyAdmin is Ownable {\n /**\n * @dev Returns the current implementation of `proxy`.\n *\n * Requirements:\n *\n * - This contract must be the admin of `proxy`.\n */\n function getProxyImplementation(TransparentUpgradeableProxy proxy) public view virtual returns (address) {\n // We need to manually run the static call since the getter cannot be flagged as view\n // bytes4(keccak256(\"implementation()\")) == 0x5c60da1b\n (bool success, bytes memory returndata) = address(proxy).staticcall(hex\"5c60da1b\");\n require(success);\n return abi.decode(returndata, (address));\n }\n\n /**\n * @dev Returns the current admin of `proxy`.\n *\n * Requirements:\n *\n * - This contract must be the admin of `proxy`.\n */\n function getProxyAdmin(TransparentUpgradeableProxy proxy) public view virtual returns (address) {\n // We need to manually run the static call since the getter cannot be flagged as view\n // bytes4(keccak256(\"admin()\")) == 0xf851a440\n (bool success, bytes memory returndata) = address(proxy).staticcall(hex\"f851a440\");\n require(success);\n return abi.decode(returndata, (address));\n }\n\n /**\n * @dev Changes the admin of `proxy` to `newAdmin`.\n *\n * Requirements:\n *\n * - This contract must be the current admin of `proxy`.\n */\n function changeProxyAdmin(TransparentUpgradeableProxy proxy, address newAdmin) public virtual onlyOwner {\n proxy.changeAdmin(newAdmin);\n }\n\n /**\n * @dev Upgrades `proxy` to `implementation`. See {TransparentUpgradeableProxy-upgradeTo}.\n *\n * Requirements:\n *\n * - This contract must be the admin of `proxy`.\n */\n function upgrade(TransparentUpgradeableProxy proxy, address implementation) public virtual onlyOwner {\n proxy.upgradeTo(implementation);\n }\n\n /**\n * @dev Upgrades `proxy` to `implementation` and calls a function on the new implementation. See\n * {TransparentUpgradeableProxy-upgradeToAndCall}.\n *\n * Requirements:\n *\n * - This contract must be the admin of `proxy`.\n */\n function upgradeAndCall(\n TransparentUpgradeableProxy proxy,\n address implementation,\n bytes memory data\n ) public payable virtual onlyOwner {\n proxy.upgradeToAndCall{ value: msg.value }(implementation, data);\n }\n}\n" + }, + "contracts/external/TransparentUpgradeableProxy.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\nimport \"@openzeppelin/contracts/proxy/ERC1967/ERC1967Proxy.sol\";\n\n/**\n * @dev This contract implements a proxy that is upgradeable by an admin. It is fully forked from OpenZeppelin\n * `TransparentUpgradeableProxy`\n *\n * To avoid https://medium.com/nomic-labs-blog/malicious-backdoors-in-ethereum-proxies-62629adf3357[proxy selector\n * clashing], which can potentially be used in an attack, this contract uses the\n * https://blog.openzeppelin.com/the-transparent-proxy-pattern/[transparent proxy pattern]. This pattern implies two\n * things that go hand in hand:\n *\n * 1. If any account other than the admin calls the proxy, the call will be forwarded to the implementation, even if\n * that call matches one of the admin functions exposed by the proxy itself.\n * 2. If the admin calls the proxy, it can access the admin functions, but its calls will never be forwarded to the\n * implementation. If the admin tries to call a function on the implementation it will fail with an error that says\n * \"admin cannot fallback to proxy target\".\n *\n * These properties mean that the admin account can only be used for admin actions like upgrading the proxy or changing\n * the admin, so it's best if it's a dedicated account that is not used for anything else. This will avoid headaches due\n * to sudden errors when trying to call a function from the proxy implementation.\n *\n * Our recommendation is for the dedicated account to be an instance of the {ProxyAdmin} contract. If set up this way,\n * you should think of the `ProxyAdmin` instance as the real administrative interface of your proxy.\n */\ncontract TransparentUpgradeableProxy is ERC1967Proxy {\n /**\n * @dev Initializes an upgradeable proxy managed by `_admin`, backed by the implementation at `_logic`, and\n * optionally initialized with `_data` as explained in {ERC1967Proxy-constructor}.\n */\n constructor(address _logic, address admin_, bytes memory _data) payable ERC1967Proxy(_logic, _data) {\n assert(_ADMIN_SLOT == bytes32(uint256(keccak256(\"eip1967.proxy.admin\")) - 1));\n _changeAdmin(admin_);\n }\n\n /**\n * @dev Modifier used internally that will delegate the call to the implementation unless the sender is the admin.\n */\n modifier ifAdmin() {\n if (msg.sender == _getAdmin()) {\n _;\n } else {\n _fallback();\n }\n }\n\n /**\n * @dev Returns the current admin.\n *\n * NOTE: Only the admin can call this function. See {ProxyAdmin-getProxyAdmin}.\n *\n * TIP: To get this value clients can read directly from the storage slot shown below (specified by EIP1967) using the\n * https://eth.wiki/json-rpc/API#eth_getstorageat[`eth_getStorageAt`] RPC call.\n * `0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103`\n */\n function admin() external ifAdmin returns (address admin_) {\n admin_ = _getAdmin();\n }\n\n /**\n * @dev Returns the current implementation.\n *\n * NOTE: Only the admin can call this function. See {ProxyAdmin-getProxyImplementation}.\n *\n * TIP: To get this value clients can read directly from the storage slot shown below (specified by EIP1967) using the\n * https://eth.wiki/json-rpc/API#eth_getstorageat[`eth_getStorageAt`] RPC call.\n * `0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc`\n */\n function implementation() external ifAdmin returns (address implementation_) {\n implementation_ = _implementation();\n }\n\n /**\n * @dev Changes the admin of the proxy.\n *\n * Emits an {AdminChanged} event.\n *\n * NOTE: Only the admin can call this function. See {ProxyAdmin-changeProxyAdmin}.\n */\n function changeAdmin(address newAdmin) external virtual ifAdmin {\n _changeAdmin(newAdmin);\n }\n\n /**\n * @dev Upgrade the implementation of the proxy.\n *\n * NOTE: Only the admin can call this function. See {ProxyAdmin-upgrade}.\n */\n function upgradeTo(address newImplementation) external ifAdmin {\n _upgradeToAndCall(newImplementation, bytes(\"\"), false);\n }\n\n /**\n * @dev Upgrade the implementation of the proxy, and then call a function from the new implementation as specified\n * by `data`, which should be an encoded function call. This is useful to initialize new storage variables in the\n * proxied contract.\n *\n * NOTE: Only the admin can call this function. See {ProxyAdmin-upgradeAndCall}.\n */\n function upgradeToAndCall(address newImplementation, bytes calldata data) external payable ifAdmin {\n _upgradeToAndCall(newImplementation, data, true);\n }\n\n /**\n * @dev Returns the current admin.\n */\n function _admin() internal view virtual returns (address) {\n return _getAdmin();\n }\n\n /**\n * @dev Makes sure the admin cannot access the fallback function. See {Proxy-_beforeFallback}.\n */\n function _beforeFallback() internal virtual override {\n require(msg.sender != _getAdmin(), \"TransparentUpgradeableProxy: admin cannot fallback to proxy target\");\n super._beforeFallback();\n }\n}\n" + }, + "contracts/flashloan/FlashAngle.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\nimport \"@openzeppelin/contracts-upgradeable/security/ReentrancyGuardUpgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol\";\nimport \"@openzeppelin/contracts/interfaces/IERC3156FlashBorrower.sol\";\nimport \"@openzeppelin/contracts/interfaces/IERC3156FlashLender.sol\";\nimport \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\nimport \"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\";\n\nimport \"../interfaces/IAgToken.sol\";\nimport \"../interfaces/ICoreBorrow.sol\";\nimport \"../interfaces/IFlashAngle.sol\";\nimport \"../interfaces/ITreasury.sol\";\n\n/// @title FlashAngle\n/// @author Angle Labs, Inc.\n/// @notice Contract to take flash loans on top of several AgToken contracts\ncontract FlashAngle is IERC3156FlashLender, IFlashAngle, Initializable, ReentrancyGuardUpgradeable {\n using SafeERC20 for IERC20;\n /// @notice Base used for parameter computation\n uint256 public constant BASE_PARAMS = 10 ** 9;\n /// @notice Success message received when calling a `FlashBorrower` contract\n bytes32 public constant CALLBACK_SUCCESS = keccak256(\"ERC3156FlashBorrower.onFlashLoan\");\n\n /// @notice Struct encoding for a given stablecoin the parameters\n struct StablecoinData {\n // Maximum amount borrowable for this stablecoin\n uint256 maxBorrowable;\n // Flash loan fee taken by the protocol for a flash loan on this stablecoin\n uint64 flashLoanFee;\n // Treasury address responsible of the stablecoin\n address treasury;\n }\n\n // ======================= Parameters and References ===========================\n\n /// @notice Maps a stablecoin to the data and parameters for flash loans\n mapping(IAgToken => StablecoinData) public stablecoinMap;\n /// @inheritdoc IFlashAngle\n ICoreBorrow public core;\n\n // =============================== Event =======================================\n\n event FlashLoan(address indexed stablecoin, uint256 amount, IERC3156FlashBorrower indexed receiver);\n event FlashLoanParametersUpdated(IAgToken indexed stablecoin, uint64 _flashLoanFee, uint256 _maxBorrowable);\n\n // =============================== Errors ======================================\n\n error InvalidReturnMessage();\n error NotCore();\n error NotGovernorOrGuardian();\n error NotTreasury();\n error TooBigAmount();\n error TooHighParameterValue();\n error UnsupportedStablecoin();\n error ZeroAddress();\n\n /// @notice Initializes the contract\n /// @param _core Core address handling this module\n function initialize(ICoreBorrow _core) public initializer {\n if (address(_core) == address(0)) revert ZeroAddress();\n core = _core;\n }\n\n /// @custom:oz-upgrades-unsafe-allow constructor\n constructor() initializer {}\n\n // =================================== Modifiers ===============================\n\n /// @notice Checks whether the sender is the core contract\n modifier onlyCore() {\n if (msg.sender != address(core)) revert NotCore();\n _;\n }\n\n /// @notice Checks whether a given stablecoin has been initialized in this contract\n /// @param stablecoin Stablecoin to check\n /// @dev To check whether a stablecoin has been initialized, we just need to check whether its associated\n /// `treasury` address is not null in the `stablecoinMap`. This is what's checked in the `CoreBorrow` contract\n /// when adding support for a stablecoin\n modifier onlyExistingStablecoin(IAgToken stablecoin) {\n if (stablecoinMap[stablecoin].treasury == address(0)) revert UnsupportedStablecoin();\n _;\n }\n\n // ================================ ERC3156 Spec ===============================\n\n /// @inheritdoc IERC3156FlashLender\n function flashFee(address token, uint256 amount) external view returns (uint256) {\n return _flashFee(token, amount);\n }\n\n /// @inheritdoc IERC3156FlashLender\n function maxFlashLoan(address token) external view returns (uint256) {\n // It will be 0 anyway if the token was not added\n return stablecoinMap[IAgToken(token)].maxBorrowable;\n }\n\n /// @inheritdoc IERC3156FlashLender\n function flashLoan(\n IERC3156FlashBorrower receiver,\n address token,\n uint256 amount,\n bytes calldata data\n ) external nonReentrant returns (bool) {\n uint256 fee = _flashFee(token, amount);\n if (amount > stablecoinMap[IAgToken(token)].maxBorrowable) revert TooBigAmount();\n IAgToken(token).mint(address(receiver), amount);\n if (receiver.onFlashLoan(msg.sender, token, amount, fee, data) != CALLBACK_SUCCESS)\n revert InvalidReturnMessage();\n // Token must be an agToken here so normally no need to use `safeTransferFrom`, but out of safety\n // and in case governance whitelists an agToken which does not have a correct implementation, we prefer\n // to use `safeTransferFrom` here\n IERC20(token).safeTransferFrom(address(receiver), address(this), amount + fee);\n IAgToken(token).burnSelf(amount, address(this));\n emit FlashLoan(token, amount, receiver);\n return true;\n }\n\n /// @notice Internal function to compute the fee induced for taking a flash loan of `amount` of `token`\n /// @param token The loan currency\n /// @param amount The amount of tokens lent\n /// @dev This function will revert if the `token` requested is not whitelisted here\n function _flashFee(\n address token,\n uint256 amount\n ) internal view onlyExistingStablecoin(IAgToken(token)) returns (uint256) {\n return (amount * stablecoinMap[IAgToken(token)].flashLoanFee) / BASE_PARAMS;\n }\n\n // ============================ Treasury Only Function =========================\n\n /// @inheritdoc IFlashAngle\n function accrueInterestToTreasury(IAgToken stablecoin) external returns (uint256 balance) {\n address treasury = stablecoinMap[stablecoin].treasury;\n if (msg.sender != treasury) revert NotTreasury();\n balance = stablecoin.balanceOf(address(this));\n IERC20(address(stablecoin)).safeTransfer(treasury, balance);\n }\n\n // =========================== Governance Only Function ========================\n\n /// @notice Sets the parameters for a given stablecoin\n /// @param stablecoin Stablecoin to change the parameters for\n /// @param _flashLoanFee New flash loan fee for this stablecoin\n /// @param _maxBorrowable Maximum amount that can be borrowed in a single flash loan\n /// @dev Setting a `maxBorrowable` parameter equal to 0 is a way to pause the functionality\n /// @dev Parameters can only be modified for whitelisted stablecoins\n function setFlashLoanParameters(\n IAgToken stablecoin,\n uint64 _flashLoanFee,\n uint256 _maxBorrowable\n ) external onlyExistingStablecoin(stablecoin) {\n if (!core.isGovernorOrGuardian(msg.sender)) revert NotGovernorOrGuardian();\n if (_flashLoanFee > BASE_PARAMS) revert TooHighParameterValue();\n stablecoinMap[stablecoin].flashLoanFee = _flashLoanFee;\n stablecoinMap[stablecoin].maxBorrowable = _maxBorrowable;\n emit FlashLoanParametersUpdated(stablecoin, _flashLoanFee, _maxBorrowable);\n }\n\n // =========================== CoreBorrow Only Functions =======================\n\n /// @inheritdoc IFlashAngle\n function addStablecoinSupport(address _treasury) external onlyCore {\n stablecoinMap[IAgToken(ITreasury(_treasury).stablecoin())].treasury = _treasury;\n }\n\n /// @inheritdoc IFlashAngle\n function removeStablecoinSupport(address _treasury) external onlyCore {\n delete stablecoinMap[IAgToken(ITreasury(_treasury).stablecoin())];\n }\n\n /// @inheritdoc IFlashAngle\n function setCore(address _core) external onlyCore {\n core = ICoreBorrow(_core);\n }\n}\n" + }, + "contracts/interfaces/coreModule/IAgTokenMainnet.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\n/// @title IAgTokenMainnet\n/// @author Angle Labs, Inc.\ninterface IAgTokenMainnet {\n function stableMaster() external view returns (address);\n}\n" + }, + "contracts/interfaces/coreModule/ICore.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\n/// @title ICore\n/// @author Angle Labs, Inc.\ninterface ICore {\n function stablecoinList() external view returns (address[] memory);\n}\n" + }, + "contracts/interfaces/coreModule/ILiquidityGauge.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\ninterface ILiquidityGauge {\n function deposit(\n uint256 _value,\n address _addr,\n // solhint-disable-next-line\n bool _claim_rewards\n ) external;\n\n function withdraw(\n uint256 _value,\n // solhint-disable-next-line\n bool _claim_rewards\n ) external;\n\n // solhint-disable-next-line\n function claim_rewards(address _addr, address _receiver) external;\n\n // solhint-disable-next-line\n function claimable_reward(address _addr, address _reward_token) external view returns (uint256 amount);\n}\n" + }, + "contracts/interfaces/coreModule/IOracleCore.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\n/// @title IOracleCore\n/// @author Angle Labs, Inc.\ninterface IOracleCore {\n function readUpper() external view returns (uint256);\n\n function readQuoteLower(uint256 baseAmount) external view returns (uint256);\n}\n" + }, + "contracts/interfaces/coreModule/IPerpetualManager.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\n/// @title IPerpetualManager\n/// @author Angle Labs, Inc.\ninterface IPerpetualManager {\n function totalHedgeAmount() external view returns (uint256);\n\n function maintenanceMargin() external view returns (uint64);\n\n function maxLeverage() external view returns (uint64);\n\n function targetHAHedge() external view returns (uint64);\n\n function limitHAHedge() external view returns (uint64);\n\n function lockTime() external view returns (uint64);\n\n function haBonusMalusDeposit() external view returns (uint64);\n\n function haBonusMalusWithdraw() external view returns (uint64);\n\n function xHAFeesDeposit(uint256) external view returns (uint64);\n\n function yHAFeesDeposit(uint256) external view returns (uint64);\n\n function xHAFeesWithdraw(uint256) external view returns (uint64);\n\n function yHAFeesWithdraw(uint256) external view returns (uint64);\n}\n" + }, + "contracts/interfaces/coreModule/IPoolManager.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\n/// @title IPoolManager\n/// @author Angle Labs, Inc.\ninterface IPoolManager {\n function feeManager() external view returns (address);\n\n function strategyList(uint256) external view returns (address);\n}\n" + }, + "contracts/interfaces/coreModule/IStableMaster.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\nimport \"./IPerpetualManager.sol\";\nimport \"./IOracleCore.sol\";\n\n// Struct to handle all the parameters to manage the fees\n// related to a given collateral pool (associated to the stablecoin)\nstruct MintBurnData {\n // Values of the thresholds to compute the minting fees\n // depending on HA hedge (scaled by `BASE_PARAMS`)\n uint64[] xFeeMint;\n // Values of the fees at thresholds (scaled by `BASE_PARAMS`)\n uint64[] yFeeMint;\n // Values of the thresholds to compute the burning fees\n // depending on HA hedge (scaled by `BASE_PARAMS`)\n uint64[] xFeeBurn;\n // Values of the fees at thresholds (scaled by `BASE_PARAMS`)\n uint64[] yFeeBurn;\n // Max proportion of collateral from users that can be covered by HAs\n // It is exactly the same as the parameter of the same name in `PerpetualManager`, whenever one is updated\n // the other changes accordingly\n uint64 targetHAHedge;\n // Minting fees correction set by the `FeeManager` contract: they are going to be multiplied\n // to the value of the fees computed using the hedge curve\n // Scaled by `BASE_PARAMS`\n uint64 bonusMalusMint;\n // Burning fees correction set by the `FeeManager` contract: they are going to be multiplied\n // to the value of the fees computed using the hedge curve\n // Scaled by `BASE_PARAMS`\n uint64 bonusMalusBurn;\n // Parameter used to limit the number of stablecoins that can be issued using the concerned collateral\n uint256 capOnStableMinted;\n}\n\n// Struct to handle all the variables and parameters to handle SLPs in the protocol\n// including the fraction of interests they receive or the fees to be distributed to\n// them\nstruct SLPData {\n // Last timestamp at which the `sanRate` has been updated for SLPs\n uint256 lastBlockUpdated;\n // Fees accumulated from previous blocks and to be distributed to SLPs\n uint256 lockedInterests;\n // Max interests used to update the `sanRate` in a single block\n // Should be in collateral token base\n uint256 maxInterestsDistributed;\n // Amount of fees left aside for SLPs and that will be distributed\n // when the protocol is collateralized back again\n uint256 feesAside;\n // Part of the fees normally going to SLPs that is left aside\n // before the protocol is collateralized back again (depends on collateral ratio)\n // Updated by keepers and scaled by `BASE_PARAMS`\n uint64 slippageFee;\n // Portion of the fees from users minting and burning\n // that goes to SLPs (the rest goes to surplus)\n uint64 feesForSLPs;\n // Slippage factor that's applied to SLPs exiting (depends on collateral ratio)\n // If `slippage = BASE_PARAMS`, SLPs can get nothing, if `slippage = 0` they get their full claim\n // Updated by keepers and scaled by `BASE_PARAMS`\n uint64 slippage;\n // Portion of the interests from lending\n // that goes to SLPs (the rest goes to surplus)\n uint64 interestsForSLPs;\n}\n\n/// @title IStableMaster\n/// @author Angle Labs, Inc.\ninterface IStableMaster {\n function agToken() external view returns (address);\n\n function updateStocksUsers(uint256 amount, address poolManager) external;\n\n function collateralMap(\n address poolManager\n )\n external\n view\n returns (\n address token,\n address sanToken,\n IPerpetualManager perpetualManager,\n IOracleCore oracle,\n uint256 stocksUsers,\n uint256 sanRate,\n uint256 collatBase,\n SLPData memory slpData,\n MintBurnData memory feeData\n );\n\n function paused(bytes32) external view returns (bool);\n\n function deposit(uint256 amount, address user, address poolManager) external;\n\n function withdraw(uint256 amount, address burner, address dest, address poolManager) external;\n}\n" + }, + "contracts/interfaces/external/create2/ImmutableCreate2Factory.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\ninterface ImmutableCreate2Factory {\n function safeCreate2(bytes32 salt, bytes memory initCode) external payable returns (address deploymentAddress);\n\n function findCreate2Address(\n bytes32 salt,\n bytes calldata initCode\n ) external view returns (address deploymentAddress);\n\n function findCreate2AddressViaHash(\n bytes32 salt,\n bytes32 initCodeHash\n ) external view returns (address deploymentAddress);\n}\n" + }, + "contracts/interfaces/external/IERC1271.sol": { + "content": "// SPDX-License-Identifier: GPL-2.0-or-later\npragma solidity ^0.8.12;\n\n/// @title Interface for verifying contract-based account signatures\n/// @notice Interface that verifies provided signature for the data\n/// @dev Interface defined by EIP-1271\ninterface IERC1271 {\n /// @notice Returns whether the provided signature is valid for the provided data\n /// @dev MUST return the bytes4 magic value 0x1626ba7e when function passes.\n /// MUST NOT modify state (using STATICCALL for solc < 0.5, view modifier for solc > 0.5).\n /// MUST allow external calls.\n /// @param hash Hash of the data to be signed\n /// @param signature Signature byte array associated with _data\n /// @return magicValue The bytes4 magic value 0x1626ba7e\n function isValidSignature(bytes32 hash, bytes memory signature) external view returns (bytes4 magicValue);\n}\n" + }, + "contracts/interfaces/external/IERC4626.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\npragma solidity >=0.8.0;\n\nimport \"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\";\nimport \"@openzeppelin/contracts/token/ERC20/ERC20.sol\";\n\n/// @notice Minimal IERC4646 tokenized Vault interface.\n/// @author Forked from Solmate (https://github.com/Rari-Capital/solmate/blob/main/src/mixins/ERC4626.sol)\n/// @dev Do not use in production! ERC-4626 is still in the review stage and is subject to change.\ninterface IERC4626 {\n event Deposit(address indexed from, address indexed to, uint256 amount, uint256 shares);\n event Withdraw(address indexed from, address indexed to, uint256 amount, uint256 shares);\n\n /// @notice Transfers a given amount of asset to the reactor and mint shares accordingly\n /// @param amount Given amount of asset\n /// @param to Address to mint shares to\n /// @return shares Amount of shares minted to `to`\n function deposit(uint256 amount, address to) external returns (uint256 shares);\n\n /// @notice Mints a given amount of shares to the reactor and transfer assets accordingly\n /// @param shares Given amount of shares\n /// @param to Address to mint shares to\n /// @return amount Amount of `asset` taken to the `msg.sender` to mint `shares`\n function mint(uint256 shares, address to) external returns (uint256 amount);\n\n /// @notice Transfers a given amount of asset from the reactor and burn shares accordingly\n /// @param amount Given amount of asset\n /// @param to Address to transfer assets to\n /// @param from Address to burn shares from\n /// @return shares Amount of shares burnt in the operation\n function withdraw(uint256 amount, address to, address from) external returns (uint256 shares);\n\n /// @notice Burns a given amount of shares to the reactor and transfer assets accordingly\n /// @param shares Given amount of shares\n /// @param to Address to transfer assets to\n /// @param from Address to burn shares from\n /// @return amount Amount of assets redeemed in the operation\n function redeem(uint256 shares, address to, address from) external returns (uint256 amount);\n\n /// @notice Returns the total assets managed by this reactor\n function totalAssets() external view returns (uint256);\n\n /// @notice Converts an amount of assets to the corresponding amount of reactor shares\n /// @param assets Amount of asset to convert\n /// @return Shares corresponding to the amount of assets obtained\n function convertToShares(uint256 assets) external view returns (uint256);\n\n /// @notice Converts an amount of shares to its current value in asset\n /// @param shares Amount of shares to convert\n /// @return Amount of assets corresponding to the amount of assets given\n function convertToAssets(uint256 shares) external view returns (uint256);\n\n /// @notice Computes how many shares one would get by depositing `assets`\n /// @param assets Amount of asset to convert\n function previewDeposit(uint256 assets) external view returns (uint256);\n\n /// @notice Computes how many assets one would need to mint `shares`\n /// @param shares Amount of shares required\n function previewMint(uint256 shares) external view returns (uint256);\n\n /// @notice Computes how many shares one would need to withdraw assets\n /// @param assets Amount of asset to withdraw\n function previewWithdraw(uint256 assets) external view returns (uint256);\n\n /// @notice Computes how many assets one would get by burning shares\n /// @param shares Amount of shares to burn\n function previewRedeem(uint256 shares) external view returns (uint256);\n\n /// @notice Max deposit allowed for a user\n /// @param user Address of the user to check\n function maxDeposit(address user) external returns (uint256);\n\n /// @notice Max mint allowed for a user\n /// @param user Address of the user to check\n function maxMint(address user) external returns (uint256);\n\n /// @notice Max withdraw allowed for a user\n /// @param user Address of the user to check\n function maxWithdraw(address user) external returns (uint256);\n\n /// @notice Max redeem allowed for a user\n /// @param user Address of the user to check\n function maxRedeem(address user) external returns (uint256);\n}\n" + }, + "contracts/interfaces/external/IWETH9.sol": { + "content": "// SPDX-License-Identifier: GPL-2.0-or-later\npragma solidity ^0.8.12;\n\nimport \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\n\n/// @title Interface for WETH9\ninterface IWETH9 is IERC20 {\n /// @notice Deposit ether to get wrapped ether\n function deposit() external payable;\n\n /// @notice Withdraw wrapped ether to get ether\n function withdraw(uint256) external;\n}\n" + }, + "contracts/interfaces/external/layerZero/ILayerZeroEndpoint.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity >=0.5.0;\n\nimport \"./ILayerZeroUserApplicationConfig.sol\";\n\ninterface ILayerZeroEndpoint is ILayerZeroUserApplicationConfig {\n // @notice send a LayerZero message to the specified address at a LayerZero endpoint.\n // @param _dstChainId - the destination chain identifier\n // @param _destination - the address on destination chain (in bytes). address length/format may vary by chains\n // @param _payload - a custom bytes payload to send to the destination contract\n // @param _refundAddress - if the source transaction is cheaper than the amount of value passed, refund the additional amount to this address\n // @param _zroPaymentAddress - the address of the ZRO token holder who would pay for the transaction\n // @param _adapterParams - parameters for custom functionality. e.g. receive airdropped native gas from the relayer on destination\n function send(\n uint16 _dstChainId,\n bytes calldata _destination,\n bytes calldata _payload,\n address payable _refundAddress,\n address _zroPaymentAddress,\n bytes calldata _adapterParams\n ) external payable;\n\n // @notice used by the messaging library to publish verified payload\n // @param _srcChainId - the source chain identifier\n // @param _srcAddress - the source contract (as bytes) at the source chain\n // @param _dstAddress - the address on destination chain\n // @param _nonce - the unbound message ordering nonce\n // @param _gasLimit - the gas limit for external contract execution\n // @param _payload - verified payload to send to the destination contract\n function receivePayload(\n uint16 _srcChainId,\n bytes calldata _srcAddress,\n address _dstAddress,\n uint64 _nonce,\n uint256 _gasLimit,\n bytes calldata _payload\n ) external;\n\n // @notice get the inboundNonce of a lzApp from a source chain which could be EVM or non-EVM chain\n // @param _srcChainId - the source chain identifier\n // @param _srcAddress - the source chain contract address\n function getInboundNonce(uint16 _srcChainId, bytes calldata _srcAddress) external view returns (uint64);\n\n // @notice get the outboundNonce from this source chain which, consequently, is always an EVM\n // @param _srcAddress - the source chain contract address\n function getOutboundNonce(uint16 _dstChainId, address _srcAddress) external view returns (uint64);\n\n // @notice gets a quote in source native gas, for the amount that send() requires to pay for message delivery\n // @param _dstChainId - the destination chain identifier\n // @param _userApplication - the user app address on this EVM chain\n // @param _payload - the custom message to send over LayerZero\n // @param _payInZRO - if false, user app pays the protocol fee in native token\n // @param _adapterParam - parameters for the adapter service, e.g. send some dust native token to dstChain\n function estimateFees(\n uint16 _dstChainId,\n address _userApplication,\n bytes calldata _payload,\n bool _payInZRO,\n bytes calldata _adapterParam\n ) external view returns (uint256 nativeFee, uint256 zroFee);\n\n // @notice get this Endpoint's immutable source identifier\n function getChainId() external view returns (uint16);\n\n // @notice the interface to retry failed message on this Endpoint destination\n // @param _srcChainId - the source chain identifier\n // @param _srcAddress - the source chain contract address\n // @param _payload - the payload to be retried\n function retryPayload(uint16 _srcChainId, bytes calldata _srcAddress, bytes calldata _payload) external;\n\n // @notice query if any STORED payload (message blocking) at the endpoint.\n // @param _srcChainId - the source chain identifier\n // @param _srcAddress - the source chain contract address\n function hasStoredPayload(uint16 _srcChainId, bytes calldata _srcAddress) external view returns (bool);\n\n // @notice query if the _libraryAddress is valid for sending msgs.\n // @param _userApplication - the user app address on this EVM chain\n function getSendLibraryAddress(address _userApplication) external view returns (address);\n\n // @notice query if the _libraryAddress is valid for receiving msgs.\n // @param _userApplication - the user app address on this EVM chain\n function getReceiveLibraryAddress(address _userApplication) external view returns (address);\n\n // @notice query if the non-reentrancy guard for send() is on\n // @return true if the guard is on. false otherwise\n function isSendingPayload() external view returns (bool);\n\n // @notice query if the non-reentrancy guard for receive() is on\n // @return true if the guard is on. false otherwise\n function isReceivingPayload() external view returns (bool);\n\n // @notice get the configuration of the LayerZero messaging library of the specified version\n // @param _version - messaging library version\n // @param _chainId - the chainId for the pending config change\n // @param _userApplication - the contract address of the user application\n // @param _configType - type of configuration. every messaging library has its own convention.\n function getConfig(\n uint16 _version,\n uint16 _chainId,\n address _userApplication,\n uint256 _configType\n ) external view returns (bytes memory);\n\n // @notice get the send() LayerZero messaging library version\n // @param _userApplication - the contract address of the user application\n function getSendVersion(address _userApplication) external view returns (uint16);\n\n // @notice get the lzReceive() LayerZero messaging library version\n // @param _userApplication - the contract address of the user application\n function getReceiveVersion(address _userApplication) external view returns (uint16);\n}\n" + }, + "contracts/interfaces/external/layerZero/ILayerZeroReceiver.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity >=0.5.0;\n\ninterface ILayerZeroReceiver {\n // @notice LayerZero endpoint will invoke this function to deliver the message on the destination\n // @param _srcChainId - the source endpoint identifier\n // @param _srcAddress - the source sending contract address from the source chain\n // @param _nonce - the ordered message nonce\n // @param _payload - the signed payload is the UA bytes has encoded to be sent\n function lzReceive(uint16 _srcChainId, bytes calldata _srcAddress, uint64 _nonce, bytes calldata _payload) external;\n}\n" + }, + "contracts/interfaces/external/layerZero/ILayerZeroUserApplicationConfig.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity >=0.5.0;\n\ninterface ILayerZeroUserApplicationConfig {\n // @notice set the configuration of the LayerZero messaging library of the specified version\n // @param _version - messaging library version\n // @param _chainId - the chainId for the pending config change\n // @param _configType - type of configuration. every messaging library has its own convention.\n // @param _config - configuration in the bytes. can encode arbitrary content.\n function setConfig(uint16 _version, uint16 _chainId, uint256 _configType, bytes calldata _config) external;\n\n // @notice set the send() LayerZero messaging library version to _version\n // @param _version - new messaging library version\n function setSendVersion(uint16 _version) external;\n\n // @notice set the lzReceive() LayerZero messaging library version to _version\n // @param _version - new messaging library version\n function setReceiveVersion(uint16 _version) external;\n\n // @notice Only when the UA needs to resume the message flow in blocking mode and clear the stored payload\n // @param _srcChainId - the chainId of the source chain\n // @param _srcAddress - the contract address of the source contract at the source chain\n function forceResumeReceive(uint16 _srcChainId, bytes calldata _srcAddress) external;\n}\n" + }, + "contracts/interfaces/external/lido/IStETH.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\n/// @title IStETH\n/// @author Angle Labs, Inc.\n/// @notice Interface for the `StETH` contract\n/// @dev This interface only contains functions of the `StETH` which are called by other contracts\n/// of this module\ninterface IStETH {\n function getPooledEthByShares(uint256 _sharesAmount) external view returns (uint256);\n\n event Submitted(address sender, uint256 amount, address referral);\n\n function submit(address) external payable returns (uint256);\n\n function getSharesByPooledEth(uint256 _ethAmount) external view returns (uint256);\n}\n" + }, + "contracts/interfaces/external/lido/IWStETH.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\n/// @title IWStETH\n/// @author Angle Labs, Inc.\n/// @notice Interface for the `WStETH` contract\n/// @dev This interface only contains functions of the `WStETH` which are called by other contracts\n/// of this module\ninterface IWStETH {\n function wrap(uint256 _stETHAmount) external returns (uint256);\n\n function stETH() external view returns (address);\n}\n" + }, + "contracts/interfaces/external/uniswap/IUniswapRouter.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\nstruct ExactInputParams {\n bytes path;\n address recipient;\n uint256 deadline;\n uint256 amountIn;\n uint256 amountOutMinimum;\n}\n\n/// @title Router token swapping functionality\n/// @notice Functions for swapping tokens via Uniswap V3\ninterface IUniswapV3Router {\n /// @notice Swaps `amountIn` of one token for as much as possible of another along the specified path\n /// @param params The parameters necessary for the multi-hop swap, encoded as `ExactInputParams` in calldata\n /// @return amountOut The amount of the received token\n function exactInput(ExactInputParams calldata params) external payable returns (uint256 amountOut);\n}\n\n/// @title Router for price estimation functionality\n/// @notice Functions for getting the price of one token with respect to another using Uniswap V2\n/// @dev This interface is only used for non critical elements of the protocol\ninterface IUniswapV2Router {\n /// @notice Given an input asset amount, returns the maximum output amount of the\n /// other asset (accounting for fees) given reserves.\n /// @param path Addresses of the pools used to get prices\n function getAmountsOut(uint256 amountIn, address[] calldata path) external view returns (uint256[] memory amounts);\n\n function swapExactTokensForTokens(\n uint256 swapAmount,\n uint256 minExpected,\n address[] calldata path,\n address receiver,\n uint256 swapDeadline\n ) external;\n}\n" + }, + "contracts/interfaces/external/uniswap/IUniswapV3Pool.sol": { + "content": "// SPDX-License-Identifier: GPL-2.0-or-later\npragma solidity >=0.5.0;\n\n/// @title Pool state that never changes\n/// @notice These parameters are fixed for a pool forever, i.e., the methods will always return the same values\ninterface IUniswapV3Pool {\n /// @notice The first of the two tokens of the pool, sorted by address\n /// @return The token contract address\n function token0() external view returns (address);\n\n /// @notice The second of the two tokens of the pool, sorted by address\n /// @return The token contract address\n function token1() external view returns (address);\n}\n" + }, + "contracts/interfaces/governance/IVeBoostProxy.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\n/// @title IVeBoostProxy\n/// @author Angle Labs, Inc.\n/// @notice Interface for the `VeBoostProxy` contract\n/// @dev This interface only contains functions of the contract which are called by other contracts\n/// of this module\n/// @dev The `veBoostProxy` contract used by Angle is a full fork of Curve Finance implementation\ninterface IVeBoostProxy {\n /// @notice Reads the adjusted veANGLE balance of an address (adjusted by delegation)\n //solhint-disable-next-line\n function adjusted_balance_of(address) external view returns (uint256);\n}\n" + }, + "contracts/interfaces/IAgToken.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\nimport \"@openzeppelin/contracts-upgradeable/token/ERC20/IERC20Upgradeable.sol\";\n\n/// @title IAgToken\n/// @author Angle Labs, Inc.\n/// @notice Interface for the stablecoins `AgToken` contracts\n/// @dev This interface only contains functions of the `AgToken` contract which are called by other contracts\n/// of this module or of the first module of the Angle Protocol\ninterface IAgToken is IERC20Upgradeable {\n // ======================= Minter Role Only Functions ===========================\n\n /// @notice Lets the `StableMaster` contract or another whitelisted contract mint agTokens\n /// @param account Address to mint to\n /// @param amount Amount to mint\n /// @dev The contracts allowed to issue agTokens are the `StableMaster` contract, `VaultManager` contracts\n /// associated to this stablecoin as well as the flash loan module (if activated) and potentially contracts\n /// whitelisted by governance\n function mint(address account, uint256 amount) external;\n\n /// @notice Burns `amount` tokens from a `burner` address after being asked to by `sender`\n /// @param amount Amount of tokens to burn\n /// @param burner Address to burn from\n /// @param sender Address which requested the burn from `burner`\n /// @dev This method is to be called by a contract with the minter right after being requested\n /// to do so by a `sender` address willing to burn tokens from another `burner` address\n /// @dev The method checks the allowance between the `sender` and the `burner`\n function burnFrom(uint256 amount, address burner, address sender) external;\n\n /// @notice Burns `amount` tokens from a `burner` address\n /// @param amount Amount of tokens to burn\n /// @param burner Address to burn from\n /// @dev This method is to be called by a contract with a minter right on the AgToken after being\n /// requested to do so by an address willing to burn tokens from its address\n function burnSelf(uint256 amount, address burner) external;\n\n // ========================= Treasury Only Functions ===========================\n\n /// @notice Adds a minter in the contract\n /// @param minter Minter address to add\n /// @dev Zero address checks are performed directly in the `Treasury` contract\n function addMinter(address minter) external;\n\n /// @notice Removes a minter from the contract\n /// @param minter Minter address to remove\n /// @dev This function can also be called by a minter wishing to revoke itself\n function removeMinter(address minter) external;\n\n /// @notice Sets a new treasury contract\n /// @param _treasury New treasury address\n function setTreasury(address _treasury) external;\n\n // ========================= External functions ================================\n\n /// @notice Checks whether an address has the right to mint agTokens\n /// @param minter Address for which the minting right should be checked\n /// @return Whether the address has the right to mint agTokens or not\n function isMinter(address minter) external view returns (bool);\n\n /// @notice Get the associated treasury\n function treasury() external view returns (address);\n}\n" + }, + "contracts/interfaces/IAgTokenSideChainMultiBridge.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\nimport \"@openzeppelin/contracts-upgradeable/token/ERC20/extensions/draft-IERC20PermitUpgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/token/ERC20/IERC20Upgradeable.sol\";\n\n/// @title IAgTokenSideChainMultiBridge\n/// @author Angle Labs, Inc.\n/// @notice Interface for the canonical `AgToken` contracts\n/// @dev This interface only contains functions useful for bridge tokens to interact with the canonical token\ninterface IAgTokenSideChainMultiBridge is IERC20PermitUpgradeable, IERC20Upgradeable {\n /// @notice Mints the canonical token from a supported bridge token\n /// @param bridgeToken Bridge token to use to mint\n /// @param amount Amount of bridge tokens to send\n /// @param to Address to which the stablecoin should be sent\n /// @return Amount of the canonical stablecoin actually minted\n /// @dev Some fees may be taken by the protocol depending on the token used and on the address calling\n function swapIn(address bridgeToken, uint256 amount, address to) external returns (uint256);\n\n /// @notice Burns the canonical token in exchange for a bridge token\n /// @param bridgeToken Bridge token required\n /// @param amount Amount of canonical tokens to burn\n /// @param to Address to which the bridge token should be sent\n /// @return Amount of bridge tokens actually sent back\n /// @dev Some fees may be taken by the protocol depending on the token used and on the address calling\n function swapOut(address bridgeToken, uint256 amount, address to) external returns (uint256);\n}\n" + }, + "contracts/interfaces/IAngleRouter.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\n/// @title IAngleRouter\n/// @author Angle Labs, Inc.\n/// @notice Interface for the `AngleRouter` contract\n/// @dev This interface only contains functions of the `AngleRouter01` contract which are called by other contracts\n/// of this module\ninterface IAngleRouter {\n function mint(\n address user,\n uint256 amount,\n uint256 minStableAmount,\n address stablecoin,\n address collateral\n ) external;\n\n function burn(address user, uint256 amount, uint256 minAmountOut, address stablecoin, address collateral) external;\n\n function mapPoolManagers(\n address stableMaster,\n address collateral\n ) external view returns (address poolManager, address perpetualManager, address sanToken, address gauge);\n}\n" + }, + "contracts/interfaces/IAngleRouterSidechain.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\n/// @notice Action types\nenum ActionType {\n transfer,\n wrap,\n wrapNative,\n sweep,\n sweepNative,\n unwrap,\n unwrapNative,\n swapIn,\n swapOut,\n uniswapV3,\n oneInch,\n claimRewards,\n gaugeDeposit,\n borrower\n}\n\n/// @notice Data needed to get permits\nstruct PermitType {\n address token;\n address owner;\n uint256 value;\n uint256 deadline;\n uint8 v;\n bytes32 r;\n bytes32 s;\n}\n\n/// @title IAngleRouterSidechain\n/// @author Angle Labs, Inc.\n/// @notice Interface for the `AngleRouter` contract on other chains\ninterface IAngleRouterSidechain {\n function mixer(PermitType[] memory paramsPermit, ActionType[] memory actions, bytes[] calldata data) external;\n}\n" + }, + "contracts/interfaces/ICoreBorrow.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\n/// @title ICoreBorrow\n/// @author Angle Labs, Inc.\n/// @notice Interface for the `CoreBorrow` contract\n/// @dev This interface only contains functions of the `CoreBorrow` contract which are called by other contracts\n/// of this module\ninterface ICoreBorrow {\n /// @notice Checks if an address corresponds to a treasury of a stablecoin with a flash loan\n /// module initialized on it\n /// @param treasury Address to check\n /// @return Whether the address has the `FLASHLOANER_TREASURY_ROLE` or not\n function isFlashLoanerTreasury(address treasury) external view returns (bool);\n\n /// @notice Checks whether an address is governor of the Angle Protocol or not\n /// @param admin Address to check\n /// @return Whether the address has the `GOVERNOR_ROLE` or not\n function isGovernor(address admin) external view returns (bool);\n\n /// @notice Checks whether an address is governor or a guardian of the Angle Protocol or not\n /// @param admin Address to check\n /// @return Whether the address has the `GUARDIAN_ROLE` or not\n /// @dev Governance should make sure when adding a governor to also give this governor the guardian\n /// role by calling the `addGovernor` function\n function isGovernorOrGuardian(address admin) external view returns (bool);\n}\n" + }, + "contracts/interfaces/IFlashAngle.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\nimport \"./IAgToken.sol\";\nimport \"./ICoreBorrow.sol\";\n\n/// @title IFlashAngle\n/// @author Angle Labs, Inc.\n/// @notice Interface for the `FlashAngle` contract\n/// @dev This interface only contains functions of the contract which are called by other contracts\n/// of this module\ninterface IFlashAngle {\n /// @notice Reference to the `CoreBorrow` contract managing the FlashLoan module\n function core() external view returns (ICoreBorrow);\n\n /// @notice Sends the fees taken from flash loans to the treasury contract associated to the stablecoin\n /// @param stablecoin Stablecoin from which profits should be sent\n /// @return balance Amount of profits sent\n /// @dev This function can only be called by the treasury contract\n function accrueInterestToTreasury(IAgToken stablecoin) external returns (uint256 balance);\n\n /// @notice Adds support for a stablecoin\n /// @param _treasury Treasury associated to the stablecoin to add support for\n /// @dev This function can only be called by the `CoreBorrow` contract\n function addStablecoinSupport(address _treasury) external;\n\n /// @notice Removes support for a stablecoin\n /// @param _treasury Treasury associated to the stablecoin to remove support for\n /// @dev This function can only be called by the `CoreBorrow` contract\n function removeStablecoinSupport(address _treasury) external;\n\n /// @notice Sets a new core contract\n /// @param _core Core contract address to set\n /// @dev This function can only be called by the `CoreBorrow` contract\n function setCore(address _core) external;\n}\n" + }, + "contracts/interfaces/IKeeperRegistry.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\nimport \"@openzeppelin/contracts-upgradeable/token/ERC20/IERC20Upgradeable.sol\";\n\n/// @title IKeeperRegistry\n/// @author Angle Labs, Inc.\ninterface IKeeperRegistry {\n /// @notice Checks whether an address is whitelisted during oracle updates\n /// @param caller Address for which the whitelist should be checked\n /// @return Whether the address is trusted or not\n function isTrusted(address caller) external view returns (bool);\n}\n" + }, + "contracts/interfaces/ILiquidityGauge.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.7;\n\ninterface ILiquidityGauge {\n function deposit(\n uint256 _value,\n address _addr,\n // solhint-disable-next-line\n bool _claim_rewards\n ) external;\n\n function withdraw(\n uint256 _value,\n // solhint-disable-next-line\n bool _claim_rewards\n ) external;\n\n // solhint-disable-next-line\n function claim_rewards(address _addr, address _receiver) external;\n\n // solhint-disable-next-line\n function claimable_reward(address _addr, address _reward_token) external view returns (uint256 amount);\n\n /// @dev Only for testing purposes\n // solhint-disable-next-line\n function deposit_reward_token(address _rewardToken, uint256 _amount) external;\n}\n" + }, + "contracts/interfaces/IOracle.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\nimport \"./ITreasury.sol\";\nimport \"@chainlink/contracts/src/v0.8/interfaces/AggregatorV3Interface.sol\";\n\n/// @title IOracle\n/// @author Angle Labs, Inc.\n/// @notice Interface for the `Oracle` contract\n/// @dev This interface only contains functions of the contract which are called by other contracts\n/// of this module\ninterface IOracle {\n /// @notice Reads the rate from the Chainlink circuit and other data provided\n /// @return quoteAmount The current rate between the in-currency and out-currency in the base\n /// of the out currency\n /// @dev For instance if the out currency is EUR (and hence agEUR), then the base of the returned\n /// value is 10**18\n function read() external view returns (uint256);\n\n /// @notice Changes the treasury contract\n /// @param _treasury Address of the new treasury contract\n /// @dev This function can be called by an approved `VaultManager` contract which can call\n /// this function after being requested to do so by a `treasury` contract\n /// @dev In some situations (like reactor contracts), the `VaultManager` may not directly be linked\n /// to the `oracle` contract and as such we may need governors to be able to call this function as well\n function setTreasury(address _treasury) external;\n\n /// @notice Reference to the `treasury` contract handling this `VaultManager`\n function treasury() external view returns (ITreasury treasury);\n\n /// @notice Array with the list of Chainlink feeds in the order in which they are read\n function circuitChainlink() external view returns (AggregatorV3Interface[] memory);\n}\n" + }, + "contracts/interfaces/ISwapper.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\nimport \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\n\n/// @title ISwapper\n/// @author Angle Labs, Inc.\n/// @notice Interface for Swapper contracts\n/// @dev This interface defines the key functions `Swapper` contracts should have when interacting with\n/// Angle\ninterface ISwapper {\n /// @notice Notifies a contract that an address should be given `outToken` from `inToken`\n /// @param inToken Address of the token received\n /// @param outToken Address of the token to obtain\n /// @param outTokenRecipient Address to which the outToken should be sent\n /// @param outTokenOwed Minimum amount of outToken the `outTokenRecipient` address should have at the end of the call\n /// @param inTokenObtained Amount of collateral obtained by a related address prior\n /// to the call to this function\n /// @param data Extra data needed (to encode Uniswap swaps for instance)\n function swap(\n IERC20 inToken,\n IERC20 outToken,\n address outTokenRecipient,\n uint256 outTokenOwed,\n uint256 inTokenObtained,\n bytes calldata data\n ) external;\n}\n" + }, + "contracts/interfaces/ITreasury.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\nimport \"./IAgToken.sol\";\nimport \"./ICoreBorrow.sol\";\nimport \"./IFlashAngle.sol\";\n\n/// @title ITreasury\n/// @author Angle Labs, Inc.\n/// @notice Interface for the `Treasury` contract\n/// @dev This interface only contains functions of the `Treasury` which are called by other contracts\n/// of this module\ninterface ITreasury {\n /// @notice Stablecoin handled by this `treasury` contract\n function stablecoin() external view returns (IAgToken);\n\n /// @notice Checks whether a given address has the governor role\n /// @param admin Address to check\n /// @return Whether the address has the governor role\n /// @dev Access control is only kept in the `CoreBorrow` contract\n function isGovernor(address admin) external view returns (bool);\n\n /// @notice Checks whether a given address has the guardian or the governor role\n /// @param admin Address to check\n /// @return Whether the address has the guardian or the governor role\n /// @dev Access control is only kept in the `CoreBorrow` contract which means that this function\n /// queries the `CoreBorrow` contract\n function isGovernorOrGuardian(address admin) external view returns (bool);\n\n /// @notice Checks whether a given address has well been initialized in this contract\n /// as a `VaultManager`\n /// @param _vaultManager Address to check\n /// @return Whether the address has been initialized or not\n function isVaultManager(address _vaultManager) external view returns (bool);\n\n /// @notice Sets a new flash loan module for this stablecoin\n /// @param _flashLoanModule Reference to the new flash loan module\n /// @dev This function removes the minting right to the old flash loan module and grants\n /// it to the new module\n function setFlashLoanModule(address _flashLoanModule) external;\n\n /// @notice Gets the vault manager list\n function vaultManagerList(uint256 i) external returns (address);\n}\n" + }, + "contracts/interfaces/IVaultManager.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\nimport \"@openzeppelin/contracts/interfaces/IERC721Metadata.sol\";\nimport \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\nimport \"./ITreasury.sol\";\nimport \"./IOracle.sol\";\n\n// ========================= Key Structs and Enums =============================\n\n/// @notice Parameters associated to a given `VaultManager` contract: these all correspond\n/// to parameters which signification is detailed in the `VaultManagerStorage` file\nstruct VaultParameters {\n uint256 debtCeiling;\n uint64 collateralFactor;\n uint64 targetHealthFactor;\n uint64 interestRate;\n uint64 liquidationSurcharge;\n uint64 maxLiquidationDiscount;\n bool whitelistingActivated;\n uint256 baseBoost;\n}\n\n/// @notice Data stored to track someone's loan (or equivalently called position)\nstruct Vault {\n // Amount of collateral deposited in the vault, in collateral decimals. For example, if the collateral\n // is USDC with 6 decimals, then `collateralAmount` will be in base 10**6\n uint256 collateralAmount;\n // Normalized value of the debt (that is to say of the stablecoins borrowed). It is expressed\n // in the base of Angle stablecoins (i.e. `BASE_TOKENS = 10**18`)\n uint256 normalizedDebt;\n}\n\n/// @notice For a given `vaultID`, this encodes a liquidation opportunity that is to say details about the maximum\n/// amount that could be repaid by liquidating the position\n/// @dev All the values are null in the case of a vault which cannot be liquidated under these conditions\nstruct LiquidationOpportunity {\n // Maximum stablecoin amount that can be repaid upon liquidating the vault\n uint256 maxStablecoinAmountToRepay;\n // Collateral amount given to the person in the case where the maximum amount to repay is given\n uint256 maxCollateralAmountGiven;\n // Threshold value of stablecoin amount to repay: it is ok for a liquidator to repay below threshold,\n // but if this threshold is non null and the liquidator wants to repay more than threshold, it should repay\n // the max stablecoin amount given in this vault\n uint256 thresholdRepayAmount;\n // Discount proposed to the liquidator on the collateral\n uint256 discount;\n // Amount of debt in the vault\n uint256 currentDebt;\n}\n\n/// @notice Data stored during a liquidation process to keep in memory what's due to a liquidator and some\n/// essential data for vaults being liquidated\nstruct LiquidatorData {\n // Current amount of stablecoins the liquidator should give to the contract\n uint256 stablecoinAmountToReceive;\n // Current amount of collateral the contract should give to the liquidator\n uint256 collateralAmountToGive;\n // Bad debt accrued across the liquidation process\n uint256 badDebtFromLiquidation;\n // Oracle value (in stablecoin base) at the time of the liquidation\n uint256 oracleValue;\n // Value of the `interestAccumulator` at the time of the call\n uint256 newInterestAccumulator;\n}\n\n/// @notice Data to track during a series of action the amount to give or receive in stablecoins and collateral\n/// to the caller or associated addresses\nstruct PaymentData {\n // Stablecoin amount the contract should give\n uint256 stablecoinAmountToGive;\n // Stablecoin amount owed to the contract\n uint256 stablecoinAmountToReceive;\n // Collateral amount the contract should give\n uint256 collateralAmountToGive;\n // Collateral amount owed to the contract\n uint256 collateralAmountToReceive;\n}\n\n/// @notice Actions possible when composing calls to the different entry functions proposed\nenum ActionType {\n createVault,\n closeVault,\n addCollateral,\n removeCollateral,\n repayDebt,\n borrow,\n getDebtIn,\n permit\n}\n\n// ========================= Interfaces =============================\n\n/// @title IVaultManagerFunctions\n/// @author Angle Labs, Inc.\n/// @notice Interface for the `VaultManager` contract\n/// @dev This interface only contains functions of the contract which are called by other contracts\n/// of this module (without getters)\ninterface IVaultManagerFunctions {\n /// @notice Accrues interest accumulated across all vaults to the surplus and sends the surplus to the treasury\n /// @return surplusValue Value of the surplus communicated to the `Treasury`\n /// @return badDebtValue Value of the bad debt communicated to the `Treasury`\n /// @dev `surplus` and `badDebt` should be reset to 0 once their current value have been given to the `treasury` contract\n function accrueInterestToTreasury() external returns (uint256 surplusValue, uint256 badDebtValue);\n\n /// @notice Removes debt from a vault after being requested to do so by another `VaultManager` contract\n /// @param vaultID ID of the vault to remove debt from\n /// @param amountStablecoins Amount of stablecoins to remove from the debt: this amount is to be converted to an\n /// internal debt amount\n /// @param senderBorrowFee Borrowing fees from the contract which requested this: this is to make sure that people are not\n /// arbitraging difference in minting fees\n /// @param senderRepayFee Repay fees from the contract which requested this: this is to make sure that people are not arbitraging\n /// differences in repay fees\n /// @dev This function can only be called from a vaultManager registered in the same Treasury\n function getDebtOut(\n uint256 vaultID,\n uint256 amountStablecoins,\n uint256 senderBorrowFee,\n uint256 senderRepayFee\n ) external;\n\n /// @notice Gets the current debt of a vault\n /// @param vaultID ID of the vault to check\n /// @return Debt of the vault\n function getVaultDebt(uint256 vaultID) external view returns (uint256);\n\n /// @notice Gets the total debt across all vaults\n /// @return Total debt across all vaults, taking into account the interest accumulated\n /// over time\n function getTotalDebt() external view returns (uint256);\n\n /// @notice Sets the treasury contract\n /// @param _treasury New treasury contract\n /// @dev All required checks when setting up a treasury contract are performed in the contract\n /// calling this function\n function setTreasury(address _treasury) external;\n\n /// @notice Creates a vault\n /// @param toVault Address for which the va\n /// @return vaultID ID of the vault created\n /// @dev This function just creates the vault without doing any collateral or\n function createVault(address toVault) external returns (uint256);\n\n /// @notice Allows composability between calls to the different entry points of this module. Any user calling\n /// this function can perform any of the allowed actions in the order of their choice\n /// @param actions Set of actions to perform\n /// @param datas Data to be decoded for each action: it can include like the `vaultID` or the `stablecoinAmount` to borrow\n /// @param from Address from which stablecoins will be taken if one action includes burning stablecoins. This address\n /// should either be the `msg.sender` or be approved by the latter\n /// @param to Address to which stablecoins and/or collateral will be sent in case of\n /// @param who Address of the contract to handle in case of repayment of stablecoins from received collateral\n /// @param repayData Data to pass to the repayment contract in case of\n /// @return paymentData Struct containing the accounting changes from the protocol's perspective (like how much of collateral\n /// or how much has been received). Note that the values in the struct are not aggregated and you could have in the output\n /// a positive amount of stablecoins to receive as well as a positive amount of stablecoins to give\n /// @dev This function is optimized to reduce gas cost due to payment from or to the user and that expensive calls\n /// or computations (like `oracleValue`) are done only once\n /// @dev When specifying `vaultID` in `data`, it is important to know that if you specify `vaultID = 0`, it will simply\n /// use the latest `vaultID`. This is the default behavior, and unless you're engaging into some complex protocol actions\n /// it is encouraged to use `vaultID = 0` only when the first action of the batch is `createVault`\n function angle(\n ActionType[] memory actions,\n bytes[] memory datas,\n address from,\n address to,\n address who,\n bytes memory repayData\n ) external returns (PaymentData memory paymentData);\n\n /// @notice This function is a wrapper built on top of the function above. It enables users to interact with the contract\n /// without having to provide `who` and `repayData` parameters\n function angle(\n ActionType[] memory actions,\n bytes[] memory datas,\n address from,\n address to\n ) external returns (PaymentData memory paymentData);\n\n /// @notice Initializes the `VaultManager` contract\n /// @param _treasury Treasury address handling the contract\n /// @param _collateral Collateral supported by this contract\n /// @param _oracle Oracle contract used\n /// @param _symbol Symbol used to define the `VaultManager` name and symbol\n /// @dev The parameters and the oracle are the only elements which could be modified once the\n /// contract has been initialized\n /// @dev For the contract to be fully initialized, governance needs to set the parameters for the liquidation\n /// boost\n function initialize(\n ITreasury _treasury,\n IERC20 _collateral,\n IOracle _oracle,\n VaultParameters calldata params,\n string memory _symbol\n ) external;\n\n /// @notice Minimum amount of debt a vault can have, expressed in `BASE_TOKENS` that is to say the base of the agTokens\n function dust() external view returns (uint256);\n\n /// @notice Pauses external permissionless functions of the contract\n function togglePause() external;\n}\n\n/// @title IVaultManagerStorage\n/// @author Angle Labs, Inc.\n/// @notice Interface for the `VaultManager` contract\n/// @dev This interface contains getters of the contract's public variables used by other contracts\n/// of this module\ninterface IVaultManagerStorage {\n /// @notice Encodes the maximum ratio stablecoin/collateral a vault can have before being liquidated. It's what\n /// determines the minimum collateral ratio of a position\n function collateralFactor() external view returns (uint64);\n\n /// @notice Stablecoin handled by this contract. Another `VaultManager` contract could have\n /// the same rights as this `VaultManager` on the stablecoin contract\n function stablecoin() external view returns (IAgToken);\n\n /// @notice Reference to the `treasury` contract handling this `VaultManager`\n function treasury() external view returns (ITreasury);\n\n /// @notice Oracle contract to get access to the price of the collateral with respect to the stablecoin\n function oracle() external view returns (IOracle);\n\n /// @notice The `interestAccumulator` variable keeps track of the interest that should accrue to the protocol.\n /// The stored value is not necessarily the true value: this one is recomputed every time an action takes place\n /// within the protocol. It is in base `BASE_INTEREST`\n function interestAccumulator() external view returns (uint256);\n\n /// @notice Reference to the collateral handled by this `VaultManager`\n function collateral() external view returns (IERC20);\n\n /// @notice Total normalized amount of stablecoins borrowed, not taking into account the potential bad debt accumulated\n /// This value is expressed in the base of Angle stablecoins (`BASE_TOKENS = 10**18`)\n function totalNormalizedDebt() external view returns (uint256);\n\n /// @notice Maximum amount of stablecoins that can be issued with this contract. It is expressed in `BASE_TOKENS`\n function debtCeiling() external view returns (uint256);\n\n /// @notice Maps a `vaultID` to its data (namely collateral amount and normalized debt)\n function vaultData(uint256 vaultID) external view returns (uint256 collateralAmount, uint256 normalizedDebt);\n\n /// @notice ID of the last vault created. The `vaultIDCount` variables serves as a counter to generate a unique\n /// `vaultID` for each vault: it is like `tokenID` in basic ERC721 contracts\n function vaultIDCount() external view returns (uint256);\n}\n\n/// @title IVaultManager\n/// @author Angle Labs, Inc.\n/// @notice Interface for the `VaultManager` contract\ninterface IVaultManager is IVaultManagerFunctions, IVaultManagerStorage, IERC721Metadata {\n function isApprovedOrOwner(address spender, uint256 vaultID) external view returns (bool);\n}\n\n/// @title IVaultManagerListing\n/// @author Angle Labs, Inc.\n/// @notice Interface for the `VaultManagerListing` contract\ninterface IVaultManagerListing is IVaultManager {\n /// @notice Get the collateral owned by `user` in the contract\n /// @dev This function effectively sums the collateral amounts of all the vaults owned by `user`\n function getUserCollateral(address user) external view returns (uint256);\n}\n" + }, + "contracts/keeperMulticall/KeeperMulticall.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\nimport \"@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/access/AccessControlUpgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol\";\nimport \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\nimport \"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\";\nimport \"./RevertReasonParser.sol\";\n\n/// @title KeeperMulticall\n/// @notice Allows an authorized caller (keeper) to execute multiple actions in a single tx.\n/// @author Angle Labs, Inc.\n/// @dev Special features:\n/// - ability to pay the miner (for private Flashbots transactions)\n/// - swap tokens through 1inch\n/// @dev Tx need to be encoded as an array of Action. The flag `isDelegateCall` is used for calling functions within this same contract\ncontract KeeperMulticall is Initializable, AccessControlUpgradeable {\n using SafeERC20 for IERC20;\n\n bytes32 public constant KEEPER_ROLE = keccak256(\"KEEPER_ROLE\");\n\n //solhint-disable-next-line\n address private constant _oneInch = 0x1111111254fb6c44bAC0beD2854e76F90643097d;\n\n struct Action {\n address target;\n bytes data;\n bool isDelegateCall;\n }\n\n event LogAction(address indexed target, bytes data);\n event SentToMiner(uint256 indexed value);\n event Recovered(address indexed tokenAddress, address indexed to, uint256 amount);\n\n error AmountOutTooLow(uint256 amount, uint256 min);\n error BalanceTooLow();\n error FlashbotsErrorPayingMiner(uint256 value);\n error IncompatibleLengths();\n error RevertBytes();\n error WrongAmount();\n error ZeroAddress();\n\n constructor() initializer {}\n\n function initialize(address keeper) external initializer {\n __AccessControl_init();\n\n _setupRole(KEEPER_ROLE, keeper);\n _setRoleAdmin(KEEPER_ROLE, KEEPER_ROLE);\n }\n\n /// @notice Allows an authorized keeper to execute multiple actions in a single step\n /// @param actions Actions to be executed\n /// @param percentageToMiner Percentage to pay to miner expressed in bps (10000)\n /// @dev This is the main entry point for actions to be executed. The `isDelegateCall` flag is used for calling function inside this `KeeperMulticall` contract,\n /// if we call other contracts, the flag should be false\n function executeActions(\n Action[] memory actions,\n uint256 percentageToMiner\n ) external payable onlyRole(KEEPER_ROLE) returns (bytes[] memory) {\n uint256 numberOfActions = actions.length;\n if (numberOfActions == 0) revert IncompatibleLengths();\n\n bytes[] memory returnValues = new bytes[](numberOfActions + 1);\n\n uint256 balanceBefore = address(this).balance;\n\n for (uint256 i; i < numberOfActions; ++i) {\n returnValues[i] = _executeAction(actions[i]);\n }\n\n if (percentageToMiner != 0) {\n if (percentageToMiner >= 10000) revert WrongAmount();\n uint256 balanceAfter = address(this).balance;\n if (balanceAfter > balanceBefore) {\n uint256 amountToMiner = ((balanceAfter - balanceBefore) * percentageToMiner) / 10000;\n returnValues[numberOfActions] = payFlashbots(amountToMiner);\n }\n }\n\n return returnValues;\n }\n\n /// @notice Gets the action address and data and executes it\n /// @param action Action to be executed\n function _executeAction(Action memory action) internal returns (bytes memory) {\n bool success;\n bytes memory response;\n\n if (action.isDelegateCall) {\n //solhint-disable-next-line\n (success, response) = action.target.delegatecall(action.data);\n } else {\n //solhint-disable-next-line\n (success, response) = action.target.call(action.data);\n }\n\n require(success, RevertReasonParser.parse(response, \"action reverted: \"));\n emit LogAction(action.target, action.data);\n return response;\n }\n\n /// @notice Ability to pay miner directly. Used for Flashbots to execute private transactions\n /// @param value Value to be sent\n function payFlashbots(uint256 value) public payable onlyRole(KEEPER_ROLE) returns (bytes memory) {\n //solhint-disable-next-line\n (bool success, bytes memory response) = block.coinbase.call{ value: value }(\"\");\n if (!success) revert FlashbotsErrorPayingMiner(value);\n emit SentToMiner(value);\n return response;\n }\n\n /// @notice Used to check the balances the token holds for each token. If we don't have enough of a token, we revert the tx\n /// @param tokens Array of tokens to check\n /// @param minBalances Array of balances for each token\n function finalBalanceCheck(IERC20[] memory tokens, uint256[] memory minBalances) external view returns (bool) {\n uint256 tokensLength = tokens.length;\n if (tokensLength == 0 || tokensLength != minBalances.length) revert IncompatibleLengths();\n\n for (uint256 i; i < tokensLength; ++i) {\n if (address(tokens[i]) == 0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE) {\n if (address(this).balance < minBalances[i]) revert BalanceTooLow();\n } else {\n if (tokens[i].balanceOf(address(this)) < minBalances[i]) revert BalanceTooLow();\n }\n }\n\n return true;\n }\n\n /// @notice Swap token to another through 1Inch\n /// @param minAmountOut Minimum amount of `out` token to receive for the swap to happen\n /// @param payload Bytes needed for 1Inch API\n function swapToken(uint256 minAmountOut, bytes memory payload) external onlyRole(KEEPER_ROLE) {\n //solhint-disable-next-line\n (bool success, bytes memory result) = _oneInch.call(payload);\n if (!success) _revertBytes(result);\n\n uint256 amountOut = abi.decode(result, (uint256));\n if (amountOut < minAmountOut) revert AmountOutTooLow(amountOut, minAmountOut);\n }\n\n /// @notice Copied from 1Inch contract, used to revert if there is an error\n function _revertBytes(bytes memory errMsg) internal pure {\n if (errMsg.length != 0) {\n //solhint-disable-next-line\n assembly {\n revert(add(32, errMsg), mload(errMsg))\n }\n }\n revert RevertBytes();\n }\n\n /// @notice Approve a `spender` for `token`\n /// @param token Address of the token to approve\n /// @param spender Address of the spender to approve\n /// @param amount Amount to approve\n function approve(IERC20 token, address spender, uint256 amount) external onlyRole(KEEPER_ROLE) {\n uint256 currentAllowance = token.allowance(address(this), spender);\n if (currentAllowance < amount) {\n token.safeIncreaseAllowance(spender, amount - currentAllowance);\n } else if (currentAllowance > amount) {\n token.safeDecreaseAllowance(spender, currentAllowance - amount);\n }\n }\n\n receive() external payable {}\n\n /// @notice Withdraw stuck funds\n /// @param token Address of the token to recover\n /// @param receiver Address where to send the tokens\n /// @param amount Amount to recover\n function withdrawStuckFunds(address token, address receiver, uint256 amount) external onlyRole(KEEPER_ROLE) {\n if (receiver == address(0)) revert ZeroAddress();\n if (token == 0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE) {\n payable(receiver).transfer(amount);\n } else {\n IERC20(token).safeTransfer(receiver, amount);\n }\n\n emit Recovered(token, receiver, amount);\n }\n}\n" + }, + "contracts/keeperMulticall/MulticallWithFailure.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.12;\n\n/// @title MultiCallWithFailure\n/// @author Angle Labs, Inc.\n/// @notice Multicall contract allowing subcalls to fail without reverting the entire call\ncontract MultiCallWithFailure {\n error SubcallFailed();\n\n struct Call {\n address target;\n bytes data;\n bool canFail;\n }\n\n function multiCall(Call[] memory calls) external view returns (bytes[] memory) {\n bytes[] memory results = new bytes[](calls.length);\n\n for (uint256 i; i < calls.length; ++i) {\n (bool success, bytes memory result) = calls[i].target.staticcall(calls[i].data);\n if (!calls[i].canFail) {\n if (!success) {\n revert SubcallFailed();\n }\n }\n results[i] = result;\n }\n\n return results;\n }\n}\n" + }, + "contracts/keeperMulticall/RevertReasonParser.sol": { + "content": "// SPDX-License-Identifier: GNU-3\n\npragma solidity ^0.8.12;\n\n/// @title RevertReasonParser\n/// @author 1Inch team, taken from:\n/// - https://docs.1inch.io/docs/limit-order-protocol/smart-contract/libraries/RevertReasonParser/\n/// - https://etherscan.io/address/0x1111111254fb6c44bAC0beD2854e76F90643097d#code\nlibrary RevertReasonParser {\n bytes4 private constant _PANIC_SELECTOR = bytes4(keccak256(\"Panic(uint256)\"));\n bytes4 private constant _ERROR_SELECTOR = bytes4(keccak256(\"Error(string)\"));\n\n function parse(bytes memory data, string memory prefix) internal pure returns (string memory) {\n if (data.length >= 4) {\n bytes4 selector;\n //solhint-disable-next-line\n assembly {\n selector := mload(add(data, 0x20))\n }\n\n // 68 = 4-byte selector + 32 bytes offset + 32 bytes length\n if (selector == _ERROR_SELECTOR && data.length >= 68) {\n uint256 offset;\n bytes memory reason;\n // solhint-disable no-inline-assembly\n assembly {\n // 36 = 32 bytes data length + 4-byte selector\n offset := mload(add(data, 36))\n reason := add(data, add(36, offset))\n }\n /*\n revert reason is padded up to 32 bytes with ABI encoder: Error(string)\n also sometimes there is extra 32 bytes of zeros padded in the end:\n https://github.com/ethereum/solidity/issues/10170\n because of that we can't check for equality and instead check\n that offset + string length + extra 36 bytes is less than overall data length\n */\n require(data.length >= 36 + offset + reason.length, \"Invalid revert reason\");\n return string(abi.encodePacked(prefix, \"Error(\", reason, \")\"));\n }\n // 36 = 4-byte selector + 32 bytes integer\n else if (selector == _PANIC_SELECTOR && data.length == 36) {\n uint256 code;\n // solhint-disable no-inline-assembly\n assembly {\n // 36 = 32 bytes data length + 4-byte selector\n code := mload(add(data, 36))\n }\n return string(abi.encodePacked(prefix, \"Panic(\", _toHex(code), \")\"));\n }\n }\n\n return string(abi.encodePacked(prefix, \"Unknown(\", _toHex(data), \")\"));\n }\n\n function _toHex(uint256 value) private pure returns (string memory) {\n return _toHex(abi.encodePacked(value));\n }\n\n function _toHex(bytes memory data) private pure returns (string memory) {\n bytes16 alphabet = 0x30313233343536373839616263646566;\n bytes memory str = new bytes(2 + data.length * 2);\n str[0] = \"0\";\n str[1] = \"x\";\n for (uint256 i; i < data.length; ++i) {\n str[2 * i + 2] = alphabet[uint8(data[i] >> 4)];\n str[2 * i + 3] = alphabet[uint8(data[i] & 0x0f)];\n }\n return string(str);\n }\n}\n" + }, + "contracts/mock/Mock1Inch.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.12;\n\nimport \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\nimport \"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\";\n\ncontract Mock1Inch {\n using SafeERC20 for IERC20;\n\n function swap(address tokenIn, uint256 amountIn, address to, address tokenOut, uint256 amountOut) external {\n IERC20(tokenIn).safeTransferFrom(msg.sender, to, amountIn);\n if (tokenOut == 0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE) {\n //solhint-disable-next-line\n (bool sent, bytes memory data) = msg.sender.call{ value: amountOut }(\"\");\n data;\n require(sent, \"Failed to send Ether\");\n } else {\n IERC20(tokenOut).safeTransferFrom(to, msg.sender, amountOut);\n }\n }\n\n receive() external payable {}\n}\n" + }, + "contracts/mock/MockAnything.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.12;\n\ncontract MockAnything {\n uint256 public stateVar = 1;\n\n error CustomError();\n error CustomErrorWithValue(uint256);\n\n function fail(uint256 value) external view returns (uint256) {\n stateVar;\n if (value < 10) {\n revert CustomError();\n }\n if (value < 20) {\n revert CustomErrorWithValue(value);\n }\n return value + 1;\n }\n\n function modifyState(uint256 value) external {\n stateVar = value;\n }\n}\n" + }, + "contracts/mock/MockChainlinkOracle.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.7;\n\ninterface MockAggregatorV3Interface {\n function decimals() external view returns (uint8);\n\n function description() external view returns (string memory);\n\n function version() external view returns (uint256);\n\n function getRoundData(\n uint80 _roundId\n )\n external\n view\n returns (uint80 roundId, int256 answer, uint256 startedAt, uint256 updatedAt, uint80 answeredInRound);\n\n function latestRoundData()\n external\n view\n returns (uint80 roundId, int256 answer, uint256 startedAt, uint256 updatedAt, uint80 answeredInRound);\n}\n\ncontract MockChainlinkOracle is MockAggregatorV3Interface {\n uint80 public roundId = 0;\n uint8 public keyDecimals = 0;\n\n struct Entry {\n uint80 roundId;\n int256 answer;\n uint256 startedAt;\n uint256 updatedAt;\n uint80 answeredInRound;\n }\n\n mapping(uint256 => Entry) public entries;\n\n bool public latestRoundDataShouldRevert;\n\n string public desc;\n\n constructor() {}\n\n // Mock setup function\n function setLatestAnswer(int256 answer, uint256 timestamp) external {\n roundId++;\n entries[roundId] = Entry({\n roundId: roundId,\n answer: answer,\n startedAt: timestamp,\n updatedAt: timestamp,\n answeredInRound: roundId\n });\n }\n\n function setLatestAnswerWithRound(int256 answer, uint256 timestamp, uint80 _roundId) external {\n roundId = _roundId;\n entries[roundId] = Entry({\n roundId: roundId,\n answer: answer,\n startedAt: timestamp,\n updatedAt: timestamp,\n answeredInRound: roundId\n });\n }\n\n function setLatestAnswerRevert(int256 answer, uint256 timestamp) external {\n roundId++;\n entries[roundId] = Entry({\n roundId: roundId,\n answer: answer,\n startedAt: timestamp,\n updatedAt: timestamp,\n answeredInRound: roundId - 1\n });\n }\n\n function setLatestRoundDataShouldRevert(bool _shouldRevert) external {\n latestRoundDataShouldRevert = _shouldRevert;\n }\n\n function setDecimals(uint8 _decimals) external {\n keyDecimals = _decimals;\n }\n\n function setDescritpion(string memory _desc) external {\n desc = _desc;\n }\n\n function description() external view override returns (string memory) {\n return desc;\n }\n\n function version() external view override returns (uint256) {\n roundId;\n return 0;\n }\n\n function latestRoundData() external view override returns (uint80, int256, uint256, uint256, uint80) {\n if (latestRoundDataShouldRevert) {\n revert(\"latestRoundData reverted\");\n }\n return getRoundData(uint80(roundId));\n }\n\n function decimals() external view override returns (uint8) {\n return keyDecimals;\n }\n\n function getRoundData(uint80 _roundId) public view override returns (uint80, int256, uint256, uint256, uint80) {\n Entry memory entry = entries[_roundId];\n // Emulate a Chainlink aggregator\n require(entry.updatedAt > 0, \"No data present\");\n return (entry.roundId, entry.answer, entry.startedAt, entry.updatedAt, entry.answeredInRound);\n }\n}\n" + }, + "contracts/mock/MockCoreBorrow.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\nimport \"../interfaces/ICoreBorrow.sol\";\nimport \"../interfaces/IFlashAngle.sol\";\nimport \"../interfaces/ITreasury.sol\";\n\ncontract MockCoreBorrow is ICoreBorrow {\n mapping(address => bool) public flashLoaners;\n mapping(address => bool) public governors;\n mapping(address => bool) public guardians;\n\n function isFlashLoanerTreasury(address treasury) external view override returns (bool) {\n return flashLoaners[treasury];\n }\n\n function isGovernor(address admin) external view override returns (bool) {\n return governors[admin];\n }\n\n function isGovernorOrGuardian(address admin) external view override returns (bool) {\n return governors[admin] || guardians[admin];\n }\n\n function toggleGovernor(address admin) external {\n governors[admin] = !governors[admin];\n }\n\n function toggleGuardian(address admin) external {\n guardians[admin] = !guardians[admin];\n }\n\n function toggleFlashLoaners(address admin) external {\n flashLoaners[admin] = !flashLoaners[admin];\n }\n\n function addStablecoinSupport(IFlashAngle flashAngle, address _treasury) external {\n flashAngle.addStablecoinSupport(_treasury);\n }\n\n function removeStablecoinSupport(IFlashAngle flashAngle, address _treasury) external {\n flashAngle.removeStablecoinSupport(_treasury);\n }\n\n function setCore(IFlashAngle flashAngle, address _core) external {\n flashAngle.setCore(_core);\n }\n\n function setFlashLoanModule(ITreasury _treasury, address _flashLoanModule) external {\n _treasury.setFlashLoanModule(_flashLoanModule);\n }\n}\n" + }, + "contracts/mock/MockERC1271.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.12;\n\nimport \"../interfaces/external/IERC1271.sol\";\n\ncontract MockERC1271 is IERC1271 {\n uint256 public mode = 0;\n\n function setMode(uint256 _mode) public {\n mode = _mode;\n }\n\n /// @notice Returns whether the provided signature is valid for the provided data\n /// @dev MUST return the bytes4 magic value 0x1626ba7e when function passes.\n /// MUST NOT modify state (using STATICCALL for solc < 0.5, view modifier for solc > 0.5).\n /// MUST allow external calls.\n /// @return magicValue The bytes4 magic value 0x1626ba7e\n function isValidSignature(bytes32, bytes memory) external view returns (bytes4 magicValue) {\n if (mode == 1) magicValue = 0x1626ba7e;\n }\n}\n" + }, + "contracts/mock/MockERC721Receiver.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (token/ERC721/utils/ERC721Holder.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Implementation of the {IERC721Receiver} interface.\n *\n * Accepts all token transfers.\n * Make sure the contract is able to use its token with {IERC721-safeTransferFrom}, {IERC721-approve} or {IERC721-setApprovalForAll}.\n */\ncontract MockERC721Receiver {\n uint256 public mode = 0;\n\n function setMode(uint256 _mode) public {\n mode = _mode;\n }\n\n function onERC721Received(address, address, uint256, bytes memory) public view returns (bytes4) {\n require(mode != 1, \"0x1111111\");\n if (mode == 2) return this.setMode.selector;\n return this.onERC721Received.selector;\n }\n}\n" + }, + "contracts/mock/MockEulerPool.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\nimport \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\n\ncontract MockEulerPool {\n IERC20 public collateral;\n uint256 public poolSize;\n //solhint-disable-next-line\n uint256 public MAX_SANE_AMOUNT;\n\n mapping(address => uint256) public users;\n uint256 public interestRateAccumulator;\n\n constructor(IERC20 collateral_, uint256 poolSize_) {\n collateral = collateral_;\n poolSize = poolSize_;\n interestRateAccumulator = 10 ** 18;\n MAX_SANE_AMOUNT = type(uint112).max;\n }\n\n function setPoolSize(uint256 poolSize_) external {\n uint256 balance = collateral.balanceOf(address(this));\n poolSize = poolSize_;\n if (balance > poolSize_) collateral.transfer(msg.sender, balance - poolSize_);\n if (balance < poolSize_) collateral.transferFrom(msg.sender, address(this), poolSize_ - balance);\n }\n\n function setInterestRateAccumulator(uint256 interestRateAccumulator_) external {\n interestRateAccumulator = interestRateAccumulator_;\n }\n\n //solhint-disable-next-line\n function setMAXSANEAMOUNT(uint256 MAX_SANE_AMOUNT_) external {\n MAX_SANE_AMOUNT = MAX_SANE_AMOUNT_;\n }\n\n function balanceOfUnderlying(address account) external view returns (uint256) {\n return (users[account] * interestRateAccumulator) / 10 ** 18;\n }\n\n function deposit(uint256, uint256 amount) external {\n users[msg.sender] += (amount * 10 ** 18) / interestRateAccumulator;\n poolSize += amount;\n collateral.transferFrom(msg.sender, address(this), amount);\n }\n\n function withdraw(uint256, uint256 amount) external {\n if (amount == type(uint256).max) amount = (users[msg.sender] * interestRateAccumulator) / 10 ** 18;\n\n require(amount <= poolSize, \"4\");\n users[msg.sender] -= (amount * 10 ** 18) / interestRateAccumulator;\n collateral.transfer(msg.sender, amount);\n }\n}\n" + }, + "contracts/mock/MockFlashLoanModule.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\nimport \"../interfaces/IFlashAngle.sol\";\nimport \"../interfaces/ICoreBorrow.sol\";\n\ncontract MockFlashLoanModule is IFlashAngle {\n ICoreBorrow public override core;\n mapping(address => bool) public stablecoinsSupported;\n mapping(IAgToken => uint256) public interestAccrued;\n uint256 public surplusValue;\n\n constructor(ICoreBorrow _core) {\n core = _core;\n }\n\n function accrueInterestToTreasury(IAgToken stablecoin) external override returns (uint256 balance) {\n balance = surplusValue;\n interestAccrued[stablecoin] += balance;\n }\n\n function addStablecoinSupport(address _treasury) external override {\n stablecoinsSupported[_treasury] = true;\n }\n\n function removeStablecoinSupport(address _treasury) external override {\n stablecoinsSupported[_treasury] = false;\n }\n\n function setCore(address _core) external override {\n core = ICoreBorrow(_core);\n }\n\n function setSurplusValue(uint256 _surplusValue) external {\n surplusValue = _surplusValue;\n }\n}\n" + }, + "contracts/mock/MockFlashLoanReceiver.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.7;\n\nimport \"@openzeppelin/contracts/token/ERC20/ERC20.sol\";\n\nimport \"@openzeppelin/contracts/interfaces/IERC3156FlashBorrower.sol\";\n\nimport \"@openzeppelin/contracts/interfaces/IERC3156FlashLender.sol\";\n\ncontract MockFlashLoanReceiver is IERC3156FlashBorrower {\n bytes32 public constant CALLBACK_SUCCESS = keccak256(\"ERC3156FlashBorrower.onFlashLoan\");\n\n constructor() {}\n\n function onFlashLoan(\n address,\n address token,\n uint256 amount,\n uint256 fee,\n bytes calldata data\n ) external override returns (bytes32) {\n IERC20(token).approve(msg.sender, amount + fee);\n if (amount >= 10 ** 21) return keccak256(\"error\");\n if (amount == 2 * 10 ** 18) {\n IERC3156FlashLender(msg.sender).flashLoan(IERC3156FlashBorrower(address(this)), token, amount, data);\n return keccak256(\"reentrant\");\n } else return CALLBACK_SUCCESS;\n }\n}\n" + }, + "contracts/mock/MockInterestRateComputer.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\ncontract MockInterestRateComputer {\n uint256 public interestRate;\n uint256 public interestAccumulator;\n uint256 public immutable baseInterest;\n uint256 public immutable halfBase;\n\n uint256 public constant WEEK = 7 * 86400;\n\n constructor(uint256 _baseInterest, uint256 _interestRate) {\n interestAccumulator = _baseInterest;\n baseInterest = _baseInterest;\n halfBase = _baseInterest / 2;\n interestRate = _interestRate;\n }\n\n function _calculateAngle(uint256 exp, uint256 _interestAccumulator) internal view returns (uint256) {\n uint256 ratePerSecond = interestRate;\n if (exp == 0 || ratePerSecond == 0) return _interestAccumulator;\n uint256 expMinusOne = exp - 1;\n uint256 expMinusTwo = exp > 2 ? exp - 2 : 0;\n uint256 basePowerTwo = (ratePerSecond * ratePerSecond) / baseInterest;\n uint256 basePowerThree = (basePowerTwo * ratePerSecond) / baseInterest;\n uint256 secondTerm = (exp * expMinusOne * basePowerTwo) / 2;\n uint256 thirdTerm = (exp * expMinusOne * expMinusTwo * basePowerThree) / 6;\n return (_interestAccumulator * (baseInterest + ratePerSecond * exp + secondTerm + thirdTerm)) / baseInterest;\n }\n\n function _calculateAave(uint256 exp, uint256 _interestAccumulator) internal view returns (uint256) {\n uint256 ratePerSecond = interestRate;\n if (exp == 0 || ratePerSecond == 0) return _interestAccumulator;\n uint256 expMinusOne = exp - 1;\n uint256 expMinusTwo = exp > 2 ? exp - 2 : 0;\n uint256 basePowerTwo = (ratePerSecond * ratePerSecond + halfBase) / baseInterest;\n uint256 basePowerThree = (basePowerTwo * ratePerSecond + halfBase) / baseInterest;\n uint256 secondTerm = (exp * expMinusOne * basePowerTwo) / 2;\n uint256 thirdTerm = (exp * expMinusOne * expMinusTwo * basePowerThree) / 6;\n return (_interestAccumulator * (baseInterest + ratePerSecond * exp + secondTerm + thirdTerm)) / baseInterest;\n }\n\n function _calculateCompound(uint256 exp, uint256 _interestAccumulator) internal view returns (uint256) {\n return _interestAccumulator * (baseInterest + interestRate * exp);\n }\n\n function _rpow(uint256 x, uint256 n, uint256 base) internal pure returns (uint256 z) {\n //solhint-disable-next-line\n assembly {\n switch x\n case 0 {\n switch n\n case 0 {\n z := base\n }\n default {\n z := 0\n }\n }\n default {\n switch mod(n, 2)\n case 0 {\n z := base\n }\n default {\n z := x\n }\n let half := div(base, 2) // for rounding.\n for {\n n := div(n, 2)\n } n {\n n := div(n, 2)\n } {\n let xx := mul(x, x)\n if iszero(eq(div(xx, x), x)) {\n revert(0, 0)\n }\n let xxRound := add(xx, half)\n if lt(xxRound, xx) {\n revert(0, 0)\n }\n x := div(xxRound, base)\n if mod(n, 2) {\n let zx := mul(z, x)\n if and(iszero(iszero(x)), iszero(eq(div(zx, x), z))) {\n revert(0, 0)\n }\n let zxRound := add(zx, half)\n if lt(zxRound, zx) {\n revert(0, 0)\n }\n z := div(zxRound, base)\n }\n }\n }\n }\n }\n\n function _calculateMaker(uint256 delta, uint256 _interestAccumulator) internal view returns (uint256) {\n return (_rpow(baseInterest + interestRate, delta, baseInterest) * _interestAccumulator) / baseInterest;\n }\n\n function calculateAngle(uint256 delta) external view returns (uint256) {\n return _calculateAngle(delta, interestAccumulator);\n }\n\n function calculateAave(uint256 delta) external view returns (uint256) {\n return _calculateAave(delta, interestAccumulator);\n }\n\n function calculateMaker(uint256 delta) external view returns (uint256) {\n return _calculateMaker(delta, interestAccumulator);\n }\n\n function calculateAngle1Year() external view returns (uint256) {\n uint256 _interestAccumulator = interestAccumulator;\n for (uint256 i; i < 52; ++i) {\n _interestAccumulator = _calculateAngle(WEEK, _interestAccumulator);\n }\n return _interestAccumulator;\n }\n\n function calculateAave1Year() external view returns (uint256) {\n uint256 _interestAccumulator = interestAccumulator;\n for (uint256 i; i < 52; ++i) {\n _interestAccumulator = _calculateAave(WEEK, _interestAccumulator);\n }\n return _interestAccumulator;\n }\n\n function calculateMaker1Year() external view returns (uint256) {\n uint256 _interestAccumulator = interestAccumulator;\n for (uint256 i; i < 52; ++i) {\n _interestAccumulator = _calculateMaker(WEEK, _interestAccumulator);\n }\n return _interestAccumulator;\n }\n\n function calculateAngle1YearDirect() external view returns (uint256) {\n uint256 _interestAccumulator = interestAccumulator;\n _interestAccumulator = _calculateAngle(52 * WEEK, _interestAccumulator);\n\n return _interestAccumulator;\n }\n\n function calculateAave1YearDirect() external view returns (uint256) {\n uint256 _interestAccumulator = interestAccumulator;\n _interestAccumulator = _calculateAave(52 * WEEK, _interestAccumulator);\n\n return _interestAccumulator;\n }\n\n function calculateMaker1YearDirect() external view returns (uint256) {\n uint256 _interestAccumulator = interestAccumulator;\n _interestAccumulator = _calculateMaker(52 * WEEK, _interestAccumulator);\n\n return _interestAccumulator;\n }\n\n function calculateCompound1YearDirect() external view returns (uint256) {\n uint256 _interestAccumulator = interestAccumulator;\n _interestAccumulator = _calculateCompound(52 * WEEK, _interestAccumulator);\n\n return _interestAccumulator;\n }\n}\n" + }, + "contracts/mock/MockKeeperMulticall.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.12;\n\nimport \"@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/access/AccessControlUpgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol\";\nimport \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\nimport \"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\";\n\ncontract MockKeeperMulticall is Initializable, AccessControlUpgradeable {\n using SafeERC20 for IERC20;\n\n bytes32 public constant KEEPER_ROLE = keccak256(\"KEEPER_ROLE\");\n\n //solhint-disable-next-line\n address private constant _oneInch = 0x1111111254fb6c44bAC0beD2854e76F90643097d;\n\n struct Action {\n address target;\n bytes data;\n bool isDelegateCall;\n }\n\n event LogAction(address indexed target, bytes data);\n event SentToMiner(uint256 indexed value);\n event Recovered(address indexed tokenAddress, address indexed to, uint256 amount);\n\n error AmountOutTooLow(uint256 amount, uint256 min);\n error BalanceTooLow();\n error FlashbotsErrorPayingMiner(uint256 value);\n error IncompatibleLengths();\n error RevertBytes();\n error ZeroAddress();\n\n constructor() initializer {}\n\n function initialize(address keeper) public initializer {\n __AccessControl_init();\n\n _setupRole(KEEPER_ROLE, keeper);\n _setRoleAdmin(KEEPER_ROLE, KEEPER_ROLE);\n }\n}\n\ncontract MockKeeperMulticall2 {\n uint256 public varTest = 1;\n\n bytes32 public constant KEEPER_ROLE = keccak256(\"KEEPER_ROLE\");\n\n //solhint-disable-next-line\n address private constant _oneInch = 0x1111111254fb6c44bAC0beD2854e76F90643097d;\n\n struct Action {\n address target;\n bytes data;\n bool isDelegateCall;\n }\n\n event LogAction(address indexed target, bytes data);\n event SentToMiner(uint256 indexed value);\n event Recovered(address indexed tokenAddress, address indexed to, uint256 amount);\n\n error AmountOutTooLow(uint256 amount, uint256 min);\n error BalanceTooLow();\n error FlashbotsErrorPayingMiner(uint256 value);\n error IncompatibleLengths();\n error RevertBytes();\n error ZeroAddress();\n\n function functionTest() external pure returns (bool) {\n return true;\n }\n}\n" + }, + "contracts/mock/MockLayerZero.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\ninterface ILzApp {\n function lzReceive(uint16 _srcChainId, bytes memory _srcAddress, uint64 _nonce, bytes memory _payload) external;\n}\n\ncontract MockLayerZero {\n mapping(uint16 => uint256) public counters;\n uint256 public config;\n mapping(uint16 => uint64) public outboundNonce;\n uint256 public resumeReceived;\n uint256 public sendVersion;\n uint256 public receiveVersion;\n\n /// @notice Initiate with a fixe change rate\n constructor() {}\n\n function send(\n uint16 _dstChainId,\n bytes calldata,\n bytes calldata,\n address,\n address,\n bytes calldata\n ) external payable {\n counters[_dstChainId] += 1;\n }\n\n function getOutboundNonce(uint16 _dstChainId, address) external view returns (uint64) {\n return outboundNonce[_dstChainId];\n }\n\n function setOutBoundNonce(uint16 _from, uint64 value) external {\n outboundNonce[_from] = value;\n }\n\n function lzReceive(\n address lzApp,\n uint16 _srcChainId,\n bytes memory _srcAddress,\n uint64 _nonce,\n bytes memory _payload\n ) public {\n ILzApp(lzApp).lzReceive(_srcChainId, _srcAddress, _nonce, _payload);\n }\n\n function estimateFees(\n uint16,\n address,\n bytes calldata,\n bool,\n bytes calldata\n ) external pure returns (uint256 nativeFee, uint256 zroFee) {\n return (123, 456);\n }\n\n function setConfig(uint16, uint16, uint256 _configType, bytes calldata) external {\n config = _configType;\n }\n\n function getConfig(uint16, uint16, address, uint256) external view returns (bytes memory) {\n return abi.encodePacked(config);\n }\n\n function setSendVersion(uint16 _version) external {\n sendVersion = _version;\n }\n\n function setReceiveVersion(uint16 _version) external {\n receiveVersion = _version;\n }\n\n function forceResumeReceive(uint16, bytes calldata) external {\n resumeReceived = 1 - resumeReceived;\n }\n}\n" + }, + "contracts/mock/MockLiquidityGauge.sol": { + "content": "// SPDX-License-Identifier: UNLICENSED\npragma solidity ^0.8.12;\n\nimport { ILiquidityGauge } from \"../interfaces/coreModule/ILiquidityGauge.sol\";\nimport \"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\";\nimport \"@openzeppelin/contracts/token/ERC20/ERC20.sol\";\n\ncontract MockLiquidityGauge is ILiquidityGauge, ERC20 {\n using SafeERC20 for IERC20;\n\n IERC20 internal _ANGLE = IERC20(0x31429d1856aD1377A8A0079410B297e1a9e214c2);\n IERC20 internal _token;\n mapping(address => uint256) public rewards;\n\n constructor(string memory name_, string memory symbol_, address token_) ERC20(name_, symbol_) {\n _token = IERC20(token_);\n }\n\n function deposit(\n uint256 _value,\n address _addr,\n // solhint-disable-next-line\n bool\n ) external {\n _token.safeTransferFrom(msg.sender, address(this), _value);\n _mint(_addr, _value);\n }\n\n function withdraw(\n uint256 _value,\n // solhint-disable-next-line\n bool\n ) external {\n _burn(msg.sender, _value);\n _token.safeTransfer(msg.sender, _value);\n }\n\n // solhint-disable-next-line\n function claim_rewards(address _addr, address _receiver) external {\n if (_receiver == address(0)) _receiver = _addr;\n _ANGLE.safeTransfer(_receiver, rewards[_addr]);\n rewards[_addr] = 0;\n }\n\n // solhint-disable-next-line\n function claimable_reward(address _addr, address) external view returns (uint256 amount) {\n return rewards[_addr];\n }\n\n function setReward(address receiver_, uint256 amount) external {\n rewards[receiver_] = amount;\n }\n}\n" + }, + "contracts/mock/MockOracle.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.7;\n\nimport \"../interfaces/IOracle.sol\";\n\ncontract MockOracle is IOracle {\n event Update(uint256 _peg);\n\n ITreasury public treasury;\n\n uint256 public base = 1 ether;\n uint256 public precision = 1 ether;\n uint256 public rate;\n bool public outdated;\n\n /// @notice Initiate with a fixe change rate\n constructor(uint256 rate_, ITreasury _treasury) {\n rate = rate_;\n treasury = _treasury;\n }\n\n /// @notice Mock read\n function read() external view override returns (uint256) {\n return rate;\n }\n\n /// @notice change oracle rate\n function update(uint256 newRate) external {\n rate = newRate;\n }\n\n function setTreasury(address _treasury) external override {\n treasury = ITreasury(_treasury);\n }\n\n function circuitChainlink() external pure override returns (AggregatorV3Interface[] memory) {}\n}\n" + }, + "contracts/mock/MockPolygonAgEUR.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.12;\n\nimport \"../agToken/polygon/utils/ERC20UpgradeableCustom.sol\";\nimport \"@openzeppelin/contracts-upgradeable/access/AccessControlUpgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/utils/cryptography/draft-EIP712Upgradeable.sol\";\nimport \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\nimport \"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\";\n\nimport \"../interfaces/IAgToken.sol\";\nimport \"../interfaces/ITreasury.sol\";\n\ninterface IChildToken {\n function deposit(address user, bytes calldata depositData) external;\n\n function withdraw(uint256 amount) external;\n}\n\ncontract MockPolygonAgEUR is\n Initializable,\n ERC20UpgradeableCustom,\n AccessControlUpgradeable,\n EIP712Upgradeable,\n IChildToken\n{\n bytes32 public constant DEPOSITOR_ROLE = keccak256(\"DEPOSITOR_ROLE\");\n\n /// @dev Emitted when the child chain manager changes\n event ChildChainManagerAdded(address newAddress);\n event ChildChainManagerRevoked(address oldAddress);\n\n constructor() initializer {}\n\n function initialize(\n string memory _name,\n string memory _symbol,\n address childChainManager,\n address guardian\n ) public initializer {\n __ERC20_init(_name, _symbol);\n __AccessControl_init();\n _setupRole(DEFAULT_ADMIN_ROLE, guardian);\n _setupRole(DEPOSITOR_ROLE, childChainManager);\n __EIP712_init(_name, \"1\");\n }\n\n /**\n * @notice Called when the bridge has tokens to mint\n * @param user Address to mint the token to\n * @param depositData Encoded amount to mint\n */\n function deposit(address user, bytes calldata depositData) external override {\n require(hasRole(DEPOSITOR_ROLE, msg.sender));\n uint256 amount = abi.decode(depositData, (uint256));\n _mint(user, amount);\n }\n\n /**\n * @notice Called when user wants to withdraw tokens back to root chain\n * @dev Should burn user's tokens. This transaction will be verified when exiting on root chain\n * @param amount Amount of tokens to withdraw\n */\n function withdraw(uint256 amount) external override {\n _burn(_msgSender(), amount);\n }\n\n // =============================================================================\n // ======================= New data added for the upgrade ======================\n // =============================================================================\n\n mapping(address => bool) public isMinter;\n /// @notice Reference to the treasury contract which can grant minting rights\n address public treasury;\n /// @notice Boolean to check whether the contract has been reinitialized after its upgrade\n bool public treasuryInitialized;\n\n using SafeERC20 for IERC20;\n\n /// @notice Base used for fee computation\n uint256 public constant BASE_PARAMS = 10 ** 9;\n\n // =============================== Bridging Data ===============================\n\n /// @notice Struct with some data about a specific bridge token\n struct BridgeDetails {\n // Limit on the balance of bridge token held by the contract: it is designed\n // to reduce the exposure of the system to hacks\n uint256 limit;\n // Limit on the hourly volume of token minted through this bridge\n // Technically the limit over a rolling hour is hourlyLimit x2 as hourly limit\n // is enforced only between x:00 and x+1:00\n uint256 hourlyLimit;\n // Fee taken for swapping in and out the token\n uint64 fee;\n // Whether the associated token is allowed or not\n bool allowed;\n // Whether swapping in and out from the associated token is paused or not\n bool paused;\n }\n\n /// @notice Maps a bridge token to data\n mapping(address => BridgeDetails) public bridges;\n /// @notice List of all bridge tokens\n address[] public bridgeTokensList;\n /// @notice Maps a bridge token to the associated hourly volume\n mapping(address => mapping(uint256 => uint256)) public usage;\n /// @notice Maps an address to whether it is exempt of fees for when it comes to swapping in and out\n mapping(address => uint256) public isFeeExempt;\n\n uint256[44] private __gap;\n\n // ================================== Events ===================================\n\n event BridgeTokenAdded(address indexed bridgeToken, uint256 limit, uint256 hourlyLimit, uint64 fee, bool paused);\n event BridgeTokenToggled(address indexed bridgeToken, bool toggleStatus);\n event BridgeTokenRemoved(address indexed bridgeToken);\n event BridgeTokenFeeUpdated(address indexed bridgeToken, uint64 fee);\n event BridgeTokenLimitUpdated(address indexed bridgeToken, uint256 limit);\n event BridgeTokenHourlyLimitUpdated(address indexed bridgeToken, uint256 hourlyLimit);\n event HourlyLimitUpdated(uint256 hourlyLimit);\n event FeeToggled(address indexed theAddress, uint256 toggleStatus);\n event KeeperToggled(address indexed keeper, bool toggleStatus);\n event MinterToggled(address indexed minter);\n event Recovered(address indexed token, address indexed to, uint256 amount);\n event TreasuryUpdated(address indexed _treasury);\n\n // ================================== Errors ===================================\n\n error AssetStillControlledInReserves();\n error BurnAmountExceedsAllowance();\n error HourlyLimitExceeded();\n error InvalidSender();\n error InvalidToken();\n error InvalidTreasury();\n error NotGovernor();\n error NotGovernorOrGuardian();\n error NotMinter();\n error NotTreasury();\n error TooBigAmount();\n error TooHighParameterValue();\n error TreasuryAlreadyInitialized();\n error ZeroAddress();\n\n /// @notice Checks to see if it is the `Treasury` calling this contract\n /// @dev There is no Access Control here, because it can be handled cheaply through this modifier\n modifier onlyTreasury() {\n if (msg.sender != treasury) revert NotTreasury();\n _;\n }\n\n /// @notice Checks whether the sender has the minting right\n modifier onlyMinter() {\n if (!isMinter[msg.sender]) revert NotMinter();\n _;\n }\n\n /// @notice Checks whether the `msg.sender` has the governor role or not\n modifier onlyGovernor() {\n if (!ITreasury(treasury).isGovernor(msg.sender)) revert NotGovernor();\n _;\n }\n\n /// @notice Checks whether the `msg.sender` has the governor role or the guardian role\n modifier onlyGovernorOrGuardian() {\n if (!ITreasury(treasury).isGovernorOrGuardian(msg.sender)) revert NotGovernorOrGuardian();\n _;\n }\n\n /// @notice Sets up the treasury contract on Polygon after the upgrade\n /// @param _treasury Address of the treasury contract\n function setUpTreasury(address _treasury) external {\n // Only governor on Polygon\n if (msg.sender != 0xdA2D2f638D6fcbE306236583845e5822554c02EA) revert NotGovernor();\n if (address(ITreasury(_treasury).stablecoin()) != address(this)) revert InvalidTreasury();\n if (treasuryInitialized) revert TreasuryAlreadyInitialized();\n treasury = _treasury;\n treasuryInitialized = true;\n emit TreasuryUpdated(_treasury);\n }\n\n // =========================== External Function ===============================\n\n /// @notice Allows anyone to burn agToken without redeeming collateral back\n /// @param amount Amount of stablecoins to burn\n /// @dev This function can typically be called if there is a settlement mechanism to burn stablecoins\n function burnStablecoin(uint256 amount) external {\n _burnCustom(msg.sender, amount);\n }\n\n // ======================= Minter Role Only Functions ==========================\n\n function burnSelf(uint256 amount, address burner) external onlyMinter {\n _burnCustom(burner, amount);\n }\n\n function burnFrom(uint256 amount, address burner, address sender) external onlyMinter {\n _burnFromNoRedeem(amount, burner, sender);\n }\n\n function mint(address account, uint256 amount) external onlyMinter {\n _mint(account, amount);\n }\n\n // ======================= Treasury Only Functions =============================\n\n function addMinter(address minter) external onlyTreasury {\n isMinter[minter] = true;\n emit MinterToggled(minter);\n }\n\n function removeMinter(address minter) external {\n if (msg.sender != address(treasury) && msg.sender != minter) revert InvalidSender();\n isMinter[minter] = false;\n emit MinterToggled(minter);\n }\n\n function setTreasury(address _treasury) external onlyTreasury {\n treasury = _treasury;\n emit TreasuryUpdated(_treasury);\n }\n\n // ============================ Internal Function ==============================\n\n /// @notice Internal version of the function `burnFromNoRedeem`\n /// @param amount Amount to burn\n /// @dev It is at the level of this function that allowance checks are performed\n function _burnFromNoRedeem(uint256 amount, address burner, address sender) internal {\n if (burner != sender) {\n uint256 currentAllowance = allowance(burner, sender);\n if (currentAllowance < amount) revert BurnAmountExceedsAllowance();\n _approve(burner, sender, currentAllowance - amount);\n }\n _burnCustom(burner, amount);\n }\n\n // ==================== External Permissionless Functions ======================\n\n /// @notice Returns the list of all supported bridge tokens\n /// @dev Helpful for UIs\n function allBridgeTokens() external view returns (address[] memory) {\n return bridgeTokensList;\n }\n\n /// @notice Returns the current volume for a bridge, for the current hour\n /// @dev Helpful for UIs\n function currentUsage(address bridge) external view returns (uint256) {\n return usage[bridge][block.timestamp / 3600];\n }\n\n /// @notice Mints the canonical token from a supported bridge token\n /// @param bridgeToken Bridge token to use to mint\n /// @param amount Amount of bridge tokens to send\n /// @param to Address to which the stablecoin should be sent\n /// @dev Some fees may be taken by the protocol depending on the token used and on the address calling\n function swapIn(address bridgeToken, uint256 amount, address to) external returns (uint256) {\n BridgeDetails memory bridgeDetails = bridges[bridgeToken];\n if (!bridgeDetails.allowed || bridgeDetails.paused) revert InvalidToken();\n uint256 balance = IERC20(bridgeToken).balanceOf(address(this));\n if (balance + amount > bridgeDetails.limit) {\n // In case someone maliciously sends tokens to this contract\n // Or the limit changes\n if (bridgeDetails.limit > balance) amount = bridgeDetails.limit - balance;\n else {\n amount = 0;\n }\n }\n\n // Checking requirement on the hourly volume\n uint256 hour = block.timestamp / 3600;\n uint256 hourlyUsage = usage[bridgeToken][hour] + amount;\n if (hourlyUsage > bridgeDetails.hourlyLimit) {\n // Edge case when the hourly limit changes\n if (bridgeDetails.hourlyLimit > usage[bridgeToken][hour])\n amount = bridgeDetails.hourlyLimit - usage[bridgeToken][hour];\n else {\n amount = 0;\n }\n }\n usage[bridgeToken][hour] = usage[bridgeToken][hour] + amount;\n\n IERC20(bridgeToken).safeTransferFrom(msg.sender, address(this), amount);\n uint256 canonicalOut = amount;\n // Computing fees\n if (isFeeExempt[msg.sender] == 0) {\n canonicalOut -= (canonicalOut * bridgeDetails.fee) / BASE_PARAMS;\n }\n _mint(to, canonicalOut);\n return canonicalOut;\n }\n\n /// @notice Burns the canonical token in exchange for a bridge token\n /// @param bridgeToken Bridge token required\n /// @param amount Amount of canonical tokens to burn\n /// @param to Address to which the bridge token should be sent\n /// @dev Some fees may be taken by the protocol depending on the token used and on the address calling\n function swapOut(address bridgeToken, uint256 amount, address to) external returns (uint256) {\n BridgeDetails memory bridgeDetails = bridges[bridgeToken];\n if (!bridgeDetails.allowed || bridgeDetails.paused) revert InvalidToken();\n\n _burnCustom(msg.sender, amount);\n uint256 bridgeOut = amount;\n if (isFeeExempt[msg.sender] == 0) {\n bridgeOut -= (bridgeOut * bridgeDetails.fee) / BASE_PARAMS;\n }\n IERC20(bridgeToken).safeTransfer(to, bridgeOut);\n return bridgeOut;\n }\n\n // ======================= Governance Functions ================================\n\n /// @notice Adds support for a bridge token\n /// @param bridgeToken Bridge token to add: it should be a version of the stablecoin from another bridge\n /// @param limit Limit on the balance of bridge token this contract could hold\n /// @param hourlyLimit Limit on the hourly volume for this bridge\n /// @param paused Whether swapping for this token should be paused or not\n /// @param fee Fee taken upon swapping for or against this token\n function addBridgeToken(\n address bridgeToken,\n uint256 limit,\n uint256 hourlyLimit,\n uint64 fee,\n bool paused\n ) external onlyGovernor {\n if (bridges[bridgeToken].allowed || bridgeToken == address(0)) revert InvalidToken();\n if (fee > BASE_PARAMS) revert TooHighParameterValue();\n BridgeDetails memory _bridge;\n _bridge.limit = limit;\n _bridge.hourlyLimit = hourlyLimit;\n _bridge.paused = paused;\n _bridge.fee = fee;\n _bridge.allowed = true;\n bridges[bridgeToken] = _bridge;\n bridgeTokensList.push(bridgeToken);\n emit BridgeTokenAdded(bridgeToken, limit, hourlyLimit, fee, paused);\n }\n\n /// @notice Removes support for a token\n /// @param bridgeToken Address of the bridge token to remove support for\n function removeBridgeToken(address bridgeToken) external onlyGovernor {\n if (IERC20(bridgeToken).balanceOf(address(this)) != 0) revert AssetStillControlledInReserves();\n delete bridges[bridgeToken];\n // Deletion from `bridgeTokensList` loop\n uint256 bridgeTokensListLength = bridgeTokensList.length;\n for (uint256 i; i < bridgeTokensListLength - 1; ++i) {\n if (bridgeTokensList[i] == bridgeToken) {\n // Replace the `bridgeToken` to remove with the last of the list\n bridgeTokensList[i] = bridgeTokensList[bridgeTokensListLength - 1];\n break;\n }\n }\n // Remove last element in array\n bridgeTokensList.pop();\n emit BridgeTokenRemoved(bridgeToken);\n }\n\n /// @notice Recovers any ERC20 token\n /// @dev Can be used to withdraw bridge tokens for them to be de-bridged on mainnet\n function recoverERC20(address tokenAddress, address to, uint256 amountToRecover) external onlyGovernor {\n IERC20(tokenAddress).safeTransfer(to, amountToRecover);\n emit Recovered(tokenAddress, to, amountToRecover);\n }\n\n /// @notice Updates the `limit` amount for `bridgeToken`\n function setLimit(address bridgeToken, uint256 limit) external onlyGovernorOrGuardian {\n if (!bridges[bridgeToken].allowed) revert InvalidToken();\n bridges[bridgeToken].limit = limit;\n emit BridgeTokenLimitUpdated(bridgeToken, limit);\n }\n\n /// @notice Updates the `hourlyLimit` amount for `bridgeToken`\n function setHourlyLimit(address bridgeToken, uint256 hourlyLimit) external onlyGovernorOrGuardian {\n if (!bridges[bridgeToken].allowed) revert InvalidToken();\n bridges[bridgeToken].hourlyLimit = hourlyLimit;\n emit BridgeTokenHourlyLimitUpdated(bridgeToken, hourlyLimit);\n }\n\n /// @notice Updates the `fee` value for `bridgeToken`\n function setSwapFee(address bridgeToken, uint64 fee) external onlyGovernorOrGuardian {\n if (!bridges[bridgeToken].allowed) revert InvalidToken();\n if (fee > BASE_PARAMS) revert TooHighParameterValue();\n bridges[bridgeToken].fee = fee;\n emit BridgeTokenFeeUpdated(bridgeToken, fee);\n }\n\n /// @notice Pauses or unpauses swapping in and out for a token\n function toggleBridge(address bridgeToken) external onlyGovernorOrGuardian {\n if (!bridges[bridgeToken].allowed) revert InvalidToken();\n bool pausedStatus = bridges[bridgeToken].paused;\n bridges[bridgeToken].paused = !pausedStatus;\n emit BridgeTokenToggled(bridgeToken, !pausedStatus);\n }\n\n /// @notice Toggles fees for the address `theAddress`\n function toggleFeesForAddress(address theAddress) external onlyGovernorOrGuardian {\n uint256 feeExemptStatus = 1 - isFeeExempt[theAddress];\n isFeeExempt[theAddress] = feeExemptStatus;\n emit FeeToggled(theAddress, feeExemptStatus);\n }\n}\n" + }, + "contracts/mock/MockRouter.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\nimport \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\nimport \"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\";\n\nimport \"../interfaces/IAngleRouter.sol\";\nimport \"../interfaces/external/uniswap/IUniswapRouter.sol\";\nimport \"../interfaces/external/lido/IWStETH.sol\";\n\ncontract MockRouter is IUniswapV3Router, IWStETH {\n using SafeERC20 for IERC20;\n\n uint256 public counterAngleMint;\n uint256 public counterAngleBurn;\n uint256 public counter1Inch;\n uint256 public counterUni;\n uint256 public counterWrap;\n uint256 public counterMixer;\n uint256 public amountOutUni;\n uint256 public multiplierMintBurn;\n uint256 public stETHMultiplier;\n address public inToken;\n address public outToken;\n\n address public stETH;\n\n /// @notice Action types\n enum ActionType {\n transfer,\n wrap,\n wrapNative,\n sweep,\n sweepNative,\n unwrap,\n unwrapNative,\n swapIn,\n swapOut,\n uniswapV3,\n oneInch,\n claimRewards,\n gaugeDeposit,\n borrower\n }\n\n /// @notice Data needed to get permits\n struct PermitType {\n address token;\n address owner;\n uint256 value;\n uint256 deadline;\n uint8 v;\n bytes32 r;\n bytes32 s;\n }\n\n constructor() {}\n\n function mint(address user, uint256 amount, uint256, address stablecoin, address collateral) external {\n counterAngleMint += 1;\n IERC20(collateral).safeTransferFrom(msg.sender, address(this), amount);\n IERC20(stablecoin).safeTransfer(user, (amount * 10 ** 9) / multiplierMintBurn);\n }\n\n function setStETH(address _stETH) external {\n stETH = _stETH;\n }\n\n function burn(address user, uint256 amount, uint256, address stablecoin, address collateral) external {\n counterAngleBurn += 1;\n IERC20(stablecoin).safeTransferFrom(msg.sender, address(this), amount);\n IERC20(collateral).safeTransfer(user, (amount * multiplierMintBurn) / 10 ** 9);\n }\n\n function mixer(\n PermitType[] memory paramsPermit,\n ActionType[] memory actions,\n bytes[] calldata data\n ) public payable virtual {\n paramsPermit;\n counterMixer += 1;\n for (uint256 i; i < actions.length; ++i) {\n if (actions[i] == ActionType.transfer) {\n (address transferToken, uint256 amount) = abi.decode(data[i], (address, uint256));\n IERC20(transferToken).safeTransferFrom(msg.sender, address(this), amount);\n }\n }\n }\n\n function wrap(uint256 amount) external returns (uint256 amountOut) {\n amountOut = (amount * stETHMultiplier) / 10 ** 9;\n counterWrap += 1;\n IERC20(stETH).safeTransferFrom(msg.sender, address(this), amount);\n IERC20(outToken).safeTransfer(msg.sender, amountOut);\n }\n\n function oneInch(uint256 amountIn) external returns (uint256 amountOut) {\n counter1Inch += 1;\n amountOut = (amountOutUni * amountIn) / 10 ** 9;\n IERC20(inToken).safeTransferFrom(msg.sender, address(this), amountIn);\n IERC20(outToken).safeTransfer(msg.sender, amountOut);\n }\n\n function oneInchReverts() external {\n counter1Inch += 1;\n revert(\"wrong swap\");\n }\n\n function oneInchRevertsWithoutMessage() external {\n counter1Inch += 1;\n require(false);\n }\n\n function exactInput(ExactInputParams calldata params) external payable returns (uint256 amountOut) {\n counterUni += 1;\n amountOut = (params.amountIn * amountOutUni) / 10 ** 9;\n IERC20(inToken).safeTransferFrom(msg.sender, address(this), params.amountIn);\n IERC20(outToken).safeTransfer(params.recipient, amountOut);\n require(amountOut >= params.amountOutMinimum);\n }\n\n function setMultipliers(uint256 a, uint256 b) external {\n amountOutUni = a;\n multiplierMintBurn = b;\n }\n\n function setStETHMultiplier(uint256 value) external {\n stETHMultiplier = value;\n }\n\n function setInOut(address _collateral, address _stablecoin) external {\n inToken = _collateral;\n outToken = _stablecoin;\n }\n}\n" + }, + "contracts/mock/MockSidechainAgEUR.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\nimport \"../agToken/AgToken.sol\";\nimport \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\nimport \"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\";\n\n/// @title AgTokenSideChainMultiBridge\n/// @author Angle Labs, Inc.\n/// @notice Contract for Angle agTokens on other chains than Ethereum mainnet\n/// @dev This contract supports bridge tokens having a minting right on the stablecoin (also referred to as the canonical\n/// or the native token)\n/// @dev References:\n/// - FRAX implementation: https://polygonscan.com/address/0x45c32fA6DF82ead1e2EF74d17b76547EDdFaFF89#code\n/// - QiDAO implementation: https://snowtrace.io/address/0x5c49b268c9841AFF1Cc3B0a418ff5c3442eE3F3b#code\ncontract MockSidechainAgEUR is AgToken {\n using SafeERC20 for IERC20;\n\n /// @notice Base used for fee computation\n uint256 public constant BASE_PARAMS = 10 ** 9;\n\n // =============================== Bridging Data ===============================\n\n /// @notice Struct with some data about a specific bridge token\n struct BridgeDetails {\n // Limit on the balance of bridge token held by the contract: it is designed\n // to reduce the exposure of the system to hacks\n uint256 limit;\n // Limit on the hourly volume of token minted through this bridge\n // Technically the limit over a rolling hour is hourlyLimit x2 as hourly limit\n // is enforced only between x:00 and x+1:00\n uint256 hourlyLimit;\n // Fee taken for swapping in and out the token\n uint64 fee;\n // Whether the associated token is allowed or not\n bool allowed;\n // Whether swapping in and out from the associated token is paused or not\n bool paused;\n }\n\n /// @notice Maps a bridge token to data\n mapping(address => BridgeDetails) public bridges;\n /// @notice List of all bridge tokens\n address[] public bridgeTokensList;\n /// @notice Maps a bridge token to the associated hourly volume\n mapping(address => mapping(uint256 => uint256)) public usage;\n /// @notice Maps an address to whether it is exempt of fees for when it comes to swapping in and out\n mapping(address => uint256) public isFeeExempt;\n\n // ================================== Events ===================================\n\n event BridgeTokenAdded(address indexed bridgeToken, uint256 limit, uint256 hourlyLimit, uint64 fee, bool paused);\n event BridgeTokenToggled(address indexed bridgeToken, bool toggleStatus);\n event BridgeTokenRemoved(address indexed bridgeToken);\n event BridgeTokenFeeUpdated(address indexed bridgeToken, uint64 fee);\n event BridgeTokenLimitUpdated(address indexed bridgeToken, uint256 limit);\n event BridgeTokenHourlyLimitUpdated(address indexed bridgeToken, uint256 hourlyLimit);\n event HourlyLimitUpdated(uint256 hourlyLimit);\n event Recovered(address indexed token, address indexed to, uint256 amount);\n event FeeToggled(address indexed theAddress, uint256 toggleStatus);\n\n // =============================== Errors ================================\n\n error AssetStillControlledInReserves();\n error HourlyLimitExceeded();\n error InvalidToken();\n error NotGovernor();\n error NotGovernorOrGuardian();\n error TooBigAmount();\n error TooHighParameterValue();\n error ZeroAddress();\n\n // ============================= Constructor ===================================\n\n /// @notice Checks whether the `msg.sender` has the governor role or not\n modifier onlyGovernor() {\n if (!ITreasury(treasury).isGovernor(msg.sender)) revert NotGovernor();\n _;\n }\n\n /// @notice Checks whether the `msg.sender` has the governor role or the guardian role\n modifier onlyGovernorOrGuardian() {\n if (!ITreasury(treasury).isGovernorOrGuardian(msg.sender)) revert NotGovernorOrGuardian();\n _;\n }\n\n // ==================== External Permissionless Functions ======================\n\n /// @notice Returns the list of all supported bridge tokens\n /// @dev Helpful for UIs\n function allBridgeTokens() external view returns (address[] memory) {\n return bridgeTokensList;\n }\n\n /// @notice Returns the current volume for a bridge, for the current hour\n /// @param bridgeToken Bridge used to mint\n /// @dev Helpful for UIs\n function currentUsage(address bridgeToken) external view returns (uint256) {\n return usage[bridgeToken][block.timestamp / 3600];\n }\n\n /// @notice Mints the canonical token from a supported bridge token\n /// @param bridgeToken Bridge token to use to mint\n /// @param amount Amount of bridge tokens to send\n /// @param to Address to which the stablecoin should be sent\n /// @return Amount of the canonical stablecoin actually minted\n /// @dev Some fees may be taken by the protocol depending on the token used and on the address calling\n function swapIn(address bridgeToken, uint256 amount, address to) external returns (uint256) {\n BridgeDetails memory bridgeDetails = bridges[bridgeToken];\n if (!bridgeDetails.allowed || bridgeDetails.paused) revert InvalidToken();\n uint256 balance = IERC20(bridgeToken).balanceOf(address(this));\n if (balance + amount > bridgeDetails.limit) {\n // In case someone maliciously sends tokens to this contract\n // Or the limit changes\n if (bridgeDetails.limit > balance) amount = bridgeDetails.limit - balance;\n else {\n amount = 0;\n }\n }\n\n // Checking requirement on the hourly volume\n uint256 hour = block.timestamp / 3600;\n uint256 hourlyUsage = usage[bridgeToken][hour] + amount;\n if (hourlyUsage > bridgeDetails.hourlyLimit) {\n // Edge case when the hourly limit changes\n if (bridgeDetails.hourlyLimit > usage[bridgeToken][hour])\n amount = bridgeDetails.hourlyLimit - usage[bridgeToken][hour];\n else {\n amount = 0;\n }\n }\n usage[bridgeToken][hour] = usage[bridgeToken][hour] + amount;\n\n IERC20(bridgeToken).safeTransferFrom(msg.sender, address(this), amount);\n uint256 canonicalOut = amount;\n // Computing fees\n if (isFeeExempt[msg.sender] == 0) {\n canonicalOut -= (canonicalOut * bridgeDetails.fee) / BASE_PARAMS;\n }\n _mint(to, canonicalOut);\n return canonicalOut;\n }\n\n /// @notice Burns the canonical token in exchange for a bridge token\n /// @param bridgeToken Bridge token required\n /// @param amount Amount of canonical tokens to burn\n /// @param to Address to which the bridge token should be sent\n /// @return Amount of bridge tokens actually sent back\n /// @dev Some fees may be taken by the protocol depending on the token used and on the address calling\n function swapOut(address bridgeToken, uint256 amount, address to) external returns (uint256) {\n BridgeDetails memory bridgeDetails = bridges[bridgeToken];\n if (!bridgeDetails.allowed || bridgeDetails.paused) revert InvalidToken();\n\n _burn(msg.sender, amount);\n uint256 bridgeOut = amount;\n if (isFeeExempt[msg.sender] == 0) {\n bridgeOut -= (bridgeOut * bridgeDetails.fee) / BASE_PARAMS;\n }\n IERC20(bridgeToken).safeTransfer(to, bridgeOut);\n return bridgeOut;\n }\n\n // ======================= Governance Functions ================================\n\n /// @notice Adds support for a bridge token\n /// @param bridgeToken Bridge token to add: it should be a version of the stablecoin from another bridge\n /// @param limit Limit on the balance of bridge token this contract could hold\n /// @param hourlyLimit Limit on the hourly volume for this bridge\n /// @param paused Whether swapping for this token should be paused or not\n /// @param fee Fee taken upon swapping for or against this token\n function addBridgeToken(\n address bridgeToken,\n uint256 limit,\n uint256 hourlyLimit,\n uint64 fee,\n bool paused\n ) external onlyGovernor {\n if (bridges[bridgeToken].allowed || bridgeToken == address(0)) revert InvalidToken();\n if (fee > BASE_PARAMS) revert TooHighParameterValue();\n BridgeDetails memory _bridge;\n _bridge.limit = limit;\n _bridge.hourlyLimit = hourlyLimit;\n _bridge.paused = paused;\n _bridge.fee = fee;\n _bridge.allowed = true;\n bridges[bridgeToken] = _bridge;\n bridgeTokensList.push(bridgeToken);\n emit BridgeTokenAdded(bridgeToken, limit, hourlyLimit, fee, paused);\n }\n\n /// @notice Removes support for a token\n /// @param bridgeToken Address of the bridge token to remove support for\n function removeBridgeToken(address bridgeToken) external onlyGovernor {\n if (IERC20(bridgeToken).balanceOf(address(this)) != 0) revert AssetStillControlledInReserves();\n delete bridges[bridgeToken];\n // Deletion from `bridgeTokensList` loop\n uint256 bridgeTokensListLength = bridgeTokensList.length;\n for (uint256 i; i < bridgeTokensListLength - 1; ++i) {\n if (bridgeTokensList[i] == bridgeToken) {\n // Replace the `bridgeToken` to remove with the last of the list\n bridgeTokensList[i] = bridgeTokensList[bridgeTokensListLength - 1];\n break;\n }\n }\n // Remove last element in array\n bridgeTokensList.pop();\n emit BridgeTokenRemoved(bridgeToken);\n }\n\n /// @notice Recovers any ERC20 token\n /// @dev Can be used to withdraw bridge tokens for them to be de-bridged on mainnet\n function recoverERC20(address tokenAddress, address to, uint256 amountToRecover) external onlyGovernor {\n IERC20(tokenAddress).safeTransfer(to, amountToRecover);\n emit Recovered(tokenAddress, to, amountToRecover);\n }\n\n /// @notice Updates the `limit` amount for `bridgeToken`\n function setLimit(address bridgeToken, uint256 limit) external onlyGovernorOrGuardian {\n if (!bridges[bridgeToken].allowed) revert InvalidToken();\n bridges[bridgeToken].limit = limit;\n emit BridgeTokenLimitUpdated(bridgeToken, limit);\n }\n\n /// @notice Updates the `hourlyLimit` amount for `bridgeToken`\n function setHourlyLimit(address bridgeToken, uint256 hourlyLimit) external onlyGovernorOrGuardian {\n if (!bridges[bridgeToken].allowed) revert InvalidToken();\n bridges[bridgeToken].hourlyLimit = hourlyLimit;\n emit BridgeTokenHourlyLimitUpdated(bridgeToken, hourlyLimit);\n }\n\n /// @notice Updates the `fee` value for `bridgeToken`\n function setSwapFee(address bridgeToken, uint64 fee) external onlyGovernorOrGuardian {\n if (!bridges[bridgeToken].allowed) revert InvalidToken();\n if (fee > BASE_PARAMS) revert TooHighParameterValue();\n bridges[bridgeToken].fee = fee;\n emit BridgeTokenFeeUpdated(bridgeToken, fee);\n }\n\n /// @notice Pauses or unpauses swapping in and out for a token\n function toggleBridge(address bridgeToken) external onlyGovernorOrGuardian {\n if (!bridges[bridgeToken].allowed) revert InvalidToken();\n bool pausedStatus = bridges[bridgeToken].paused;\n bridges[bridgeToken].paused = !pausedStatus;\n emit BridgeTokenToggled(bridgeToken, !pausedStatus);\n }\n\n /// @notice Toggles fees for the address `theAddress`\n function toggleFeesForAddress(address theAddress) external onlyGovernorOrGuardian {\n uint256 feeExemptStatus = 1 - isFeeExempt[theAddress];\n isFeeExempt[theAddress] = feeExemptStatus;\n emit FeeToggled(theAddress, feeExemptStatus);\n }\n}\n" + }, + "contracts/mock/MockStableMaster.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\nimport \"../interfaces/IAgToken.sol\";\nimport \"./MockToken.sol\";\nimport \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\nimport \"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\";\nimport { SLPData, MintBurnData } from \"../interfaces/coreModule/IStableMaster.sol\";\n\n// All the details about a collateral that are going to be stored in `StableMaster`\nstruct Collateral {\n // Interface for the token accepted by the underlying `PoolManager` contract\n IERC20 token;\n // Reference to the `SanToken` for the pool\n MockToken sanToken;\n // Reference to the `PerpetualManager` for the pool\n address perpetualManager;\n // Adress of the oracle for the change rate between\n // collateral and the corresponding stablecoin\n address oracle;\n // Amount of collateral in the reserves that comes from users\n // converted in stablecoin value. Updated at minting and burning.\n // A `stocksUsers` of 10 for a collateral type means that overall the balance of the collateral from users\n // that minted/burnt stablecoins using this collateral is worth 10 of stablecoins\n uint256 stocksUsers;\n // Exchange rate between sanToken and collateral\n uint256 sanRate;\n // Base used in the collateral implementation (ERC20 decimal)\n uint256 collatBase;\n // Parameters for SLPs and update of the `sanRate`\n SLPData slpData;\n // All the fees parameters\n MintBurnData feeData;\n}\n\ncontract MockStableMaster {\n mapping(address => uint256) public poolManagerMap;\n\n constructor() {}\n\n function updateStocksUsers(uint256 amount, address poolManager) external {\n poolManagerMap[poolManager] += amount;\n }\n\n function burnSelf(IAgToken agToken, uint256 amount, address burner) external {\n agToken.burnSelf(amount, burner);\n }\n\n function burnFrom(IAgToken agToken, uint256 amount, address burner, address sender) external {\n agToken.burnFrom(amount, burner, sender);\n }\n\n function mint(IAgToken agToken, address account, uint256 amount) external {\n agToken.mint(account, amount);\n }\n}\n\ncontract MockStableMasterSanWrapper is MockStableMaster {\n using SafeERC20 for IERC20;\n\n /// @notice Maps a `PoolManager` contract handling a collateral for this stablecoin to the properties of the struct above\n mapping(address => Collateral) public collateralMap;\n\n constructor() MockStableMaster() {}\n\n uint256 internal constant _BASE_TOKENS = 10 ** 18;\n uint256 internal constant _BASE_PARAMS = 10 ** 9;\n IERC20 public token;\n\n function deposit(uint256 assets, address receiver, address poolManager) external {\n token.safeTransferFrom(msg.sender, address(this), assets);\n Collateral storage col = collateralMap[poolManager];\n _updateSanRate(col);\n uint256 amount = (assets * _BASE_TOKENS) / col.sanRate;\n col.sanToken.mint(receiver, amount);\n }\n\n function withdraw(uint256 assets, address sender, address receiver, address poolManager) external {\n Collateral storage col = collateralMap[poolManager];\n _updateSanRate(col);\n col.sanToken.burn(sender, assets);\n // Computing the amount of collateral to give back to the SLP depending on slippage and on the `sanRate`\n uint256 redeemInC = (assets * (_BASE_PARAMS - col.slpData.slippage) * col.sanRate) /\n (_BASE_TOKENS * _BASE_PARAMS);\n token.safeTransfer(receiver, redeemInC);\n }\n\n function setPoolManagerToken(address, address token_) external {\n token = MockToken(token_);\n }\n\n function setPoolManagerSanToken(address poolManager, address sanToken_) external {\n Collateral storage col = collateralMap[poolManager];\n col.sanToken = MockToken(sanToken_);\n }\n\n function setSanRate(address poolManager, uint256 sanRate_) external {\n Collateral storage col = collateralMap[poolManager];\n col.sanRate = sanRate_;\n }\n\n function _updateSanRate(Collateral storage col) internal {\n uint256 _lockedInterests = col.slpData.lockedInterests;\n // Checking if the `sanRate` has been updated in the current block using past block fees\n // This is a way to prevent flash loans attacks when an important amount of fees are going to be distributed\n // in a block: fees are stored but will just be distributed to SLPs who will be here during next blocks\n if (block.timestamp != col.slpData.lastBlockUpdated && _lockedInterests > 0) {\n uint256 sanMint = col.sanToken.totalSupply();\n if (sanMint != 0) {\n // Checking if the update is too important and should be made in multiple blocks\n if (_lockedInterests > col.slpData.maxInterestsDistributed) {\n // `sanRate` is expressed in `BASE_TOKENS`\n col.sanRate += (col.slpData.maxInterestsDistributed * 10 ** 18) / sanMint;\n _lockedInterests -= col.slpData.maxInterestsDistributed;\n } else {\n col.sanRate += (_lockedInterests * 10 ** 18) / sanMint;\n _lockedInterests = 0;\n }\n } else {\n _lockedInterests = 0;\n }\n }\n col.slpData.lockedInterests = _lockedInterests;\n col.slpData.lastBlockUpdated = block.timestamp;\n }\n\n // copy paste from the deployed contract\n function estimateSanRate(address poolManager) external view returns (uint256 sanRate, uint64 slippage) {\n Collateral memory col = collateralMap[poolManager];\n uint256 _lockedInterests = col.slpData.lockedInterests;\n // Checking if the `sanRate` has been updated in the current block using past block fees\n // This is a way to prevent flash loans attacks when an important amount of fees are going to be distributed\n // in a block: fees are stored but will just be distributed to SLPs who will be here during next blocks\n if (block.timestamp != col.slpData.lastBlockUpdated && _lockedInterests > 0) {\n uint256 sanMint = col.sanToken.totalSupply();\n if (sanMint != 0) {\n // Checking if the update is too important and should be made in multiple blocks\n if (_lockedInterests > col.slpData.maxInterestsDistributed) {\n // `sanRate` is expressed in `BASE_TOKENS`\n col.sanRate += (col.slpData.maxInterestsDistributed * 10 ** 18) / sanMint;\n _lockedInterests -= col.slpData.maxInterestsDistributed;\n } else {\n col.sanRate += (_lockedInterests * 10 ** 18) / sanMint;\n _lockedInterests = 0;\n }\n } else {\n _lockedInterests = 0;\n }\n }\n return (col.sanRate, col.slpData.slippage);\n }\n\n function setSLPData(\n address poolManager,\n uint256 lockedInterests,\n uint256 maxInterestsDistributed,\n uint64 slippage\n ) external {\n Collateral storage col = collateralMap[poolManager];\n col.slpData.lockedInterests = lockedInterests;\n col.slpData.maxInterestsDistributed = maxInterestsDistributed;\n col.slpData.slippage = slippage;\n }\n}\n" + }, + "contracts/mock/MockSwapper.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\nimport \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\nimport \"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\";\n\nimport \"../interfaces/ISwapper.sol\";\n\ncontract MockSwapper is ISwapper {\n bytes32 public constant CALLBACK_SUCCESS = keccak256(\"ERC3156FlashBorrower.onFlashLoan\");\n\n uint256 public counter;\n\n constructor() {}\n\n function swap(IERC20, IERC20, address, uint256, uint256, bytes calldata data) external {\n counter += 1;\n data;\n }\n}\n\ncontract MockSwapperWithSwap is ISwapper {\n using SafeERC20 for IERC20;\n bytes32 public constant CALLBACK_SUCCESS = keccak256(\"ERC3156FlashBorrower.onFlashLoan\");\n\n uint256 public counter;\n\n constructor() {}\n\n function swap(\n IERC20,\n IERC20 outToken,\n address outTokenRecipient,\n uint256 outTokenOwed,\n uint256,\n bytes calldata data\n ) external {\n counter += 1;\n outToken.safeTransfer(outTokenRecipient, outTokenOwed);\n\n data;\n }\n}\n" + }, + "contracts/mock/MockSwapperSidechain.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\nimport \"../swapper/Swapper.sol\";\n\n/// @title MockSwapperSidechain\n/// @author Angle Labs, Inc.\ncontract MockSwapperSidechain is Swapper {\n error NotImplemented();\n\n /// @notice Constructor of the contract\n /// @param _core Core address\n /// @param _uniV3Router UniswapV3 Router address\n /// @param _oneInch 1Inch Router address\n /// @param _angleRouter AngleRouter contract address\n constructor(\n ICoreBorrow _core,\n IUniswapV3Router _uniV3Router,\n address _oneInch,\n IAngleRouterSidechain _angleRouter\n ) Swapper(_core, _uniV3Router, _oneInch, _angleRouter) {}\n\n function _swapLeverage(bytes memory) internal pure override returns (uint256) {\n revert NotImplemented();\n }\n}\n" + }, + "contracts/mock/MockToken.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.7;\n\nimport \"@openzeppelin/contracts/token/ERC20/ERC20.sol\";\n\ncontract MockToken is ERC20 {\n event Minting(address indexed _to, address indexed _minter, uint256 _amount);\n\n event Burning(address indexed _from, address indexed _burner, uint256 _amount);\n\n uint8 internal _decimal;\n mapping(address => bool) public minters;\n address public treasury;\n\n constructor(string memory name_, string memory symbol_, uint8 decimal_) ERC20(name_, symbol_) {\n _decimal = decimal_;\n }\n\n function decimals() public view override returns (uint8) {\n return _decimal;\n }\n\n function mint(address account, uint256 amount) external {\n _mint(account, amount);\n emit Minting(account, msg.sender, amount);\n }\n\n function burn(address account, uint256 amount) public {\n _burn(account, amount);\n emit Burning(account, msg.sender, amount);\n }\n\n function setAllowance(address from, address to) public {\n _approve(from, to, type(uint256).max);\n }\n\n function burnSelf(uint256 amount, address account) public {\n _burn(account, amount);\n emit Burning(account, msg.sender, amount);\n }\n\n function addMinter(address minter) public {\n minters[minter] = true;\n }\n\n function removeMinter(address minter) public {\n minters[minter] = false;\n }\n\n function setTreasury(address _treasury) public {\n treasury = _treasury;\n }\n}\n" + }, + "contracts/mock/MockTokenPermit.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.7;\n\nimport \"@openzeppelin/contracts/token/ERC20/extensions/draft-ERC20Permit.sol\";\nimport \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\nimport \"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\";\n\ncontract MockTokenPermit is ERC20Permit {\n using SafeERC20 for IERC20;\n event Minting(address indexed _to, address indexed _minter, uint256 _amount);\n\n event Burning(address indexed _from, address indexed _burner, uint256 _amount);\n\n uint8 internal _decimal;\n mapping(address => bool) public minters;\n address public treasury;\n uint256 public fees;\n\n bool public reverts;\n\n constructor(string memory name_, string memory symbol_, uint8 decimal_) ERC20Permit(name_) ERC20(name_, symbol_) {\n _decimal = decimal_;\n }\n\n function decimals() public view override returns (uint8) {\n return _decimal;\n }\n\n function mint(address account, uint256 amount) external {\n _mint(account, amount);\n emit Minting(account, msg.sender, amount);\n }\n\n function burn(address account, uint256 amount) public {\n _burn(account, amount);\n emit Burning(account, msg.sender, amount);\n }\n\n function setAllowance(address from, address to) public {\n _approve(from, to, type(uint256).max);\n }\n\n function burnSelf(uint256 amount, address account) public {\n _burn(account, amount);\n emit Burning(account, msg.sender, amount);\n }\n\n function addMinter(address minter) public {\n minters[minter] = true;\n }\n\n function removeMinter(address minter) public {\n minters[minter] = false;\n }\n\n function setTreasury(address _treasury) public {\n treasury = _treasury;\n }\n\n function setFees(uint256 _fees) public {\n fees = _fees;\n }\n\n function recoverERC20(IERC20 token, address to, uint256 amount) external {\n token.safeTransfer(to, amount);\n }\n\n function swapIn(address bridgeToken, uint256 amount, address to) external returns (uint256) {\n require(!reverts);\n\n IERC20(bridgeToken).safeTransferFrom(msg.sender, address(this), amount);\n uint256 canonicalOut = amount;\n canonicalOut -= (canonicalOut * fees) / 10 ** 9;\n _mint(to, canonicalOut);\n return canonicalOut;\n }\n\n function swapOut(address bridgeToken, uint256 amount, address to) external returns (uint256) {\n require(!reverts);\n _burn(msg.sender, amount);\n uint256 bridgeOut = amount;\n bridgeOut -= (bridgeOut * fees) / 10 ** 9;\n IERC20(bridgeToken).safeTransfer(to, bridgeOut);\n return bridgeOut;\n }\n}\n" + }, + "contracts/mock/MockTreasury.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\nimport \"../interfaces/ITreasury.sol\";\nimport \"../interfaces/IFlashAngle.sol\";\nimport \"../interfaces/IVaultManager.sol\";\n\ncontract MockTreasury is ITreasury {\n IAgToken public override stablecoin;\n address public governor;\n address public guardian;\n address public vaultManager1;\n address public vaultManager2;\n address public flashLoanModule;\n address[] public vaultManagerList;\n\n constructor(\n IAgToken _stablecoin,\n address _governor,\n address _guardian,\n address _vaultManager1,\n address _vaultManager2,\n address _flashLoanModule\n ) {\n stablecoin = _stablecoin;\n governor = _governor;\n guardian = _guardian;\n vaultManager1 = _vaultManager1;\n vaultManager2 = _vaultManager2;\n flashLoanModule = _flashLoanModule;\n }\n\n function isGovernor(address admin) external view override returns (bool) {\n return (admin == governor);\n }\n\n function isGovernorOrGuardian(address admin) external view override returns (bool) {\n return (admin == governor || admin == guardian);\n }\n\n function isVaultManager(address _vaultManager) external view override returns (bool) {\n return (_vaultManager == vaultManager1 || _vaultManager == vaultManager2);\n }\n\n function setStablecoin(IAgToken _stablecoin) external {\n stablecoin = _stablecoin;\n }\n\n function setFlashLoanModule(address _flashLoanModule) external override {\n flashLoanModule = _flashLoanModule;\n }\n\n function setGovernor(address _governor) external {\n governor = _governor;\n }\n\n function setVaultManager(address _vaultManager) external {\n vaultManager1 = _vaultManager;\n }\n\n function setVaultManager2(address _vaultManager) external {\n vaultManager2 = _vaultManager;\n }\n\n function setTreasury(address _agTokenOrVaultManager, address _treasury) external {\n IAgToken(_agTokenOrVaultManager).setTreasury(_treasury);\n }\n\n function addMinter(IAgToken _agToken, address _minter) external {\n _agToken.addMinter(_minter);\n }\n\n function removeMinter(IAgToken _agToken, address _minter) external {\n _agToken.removeMinter(_minter);\n }\n\n function accrueInterestToTreasury(IFlashAngle flashAngle) external returns (uint256 balance) {\n balance = flashAngle.accrueInterestToTreasury(stablecoin);\n }\n\n function accrueInterestToTreasuryVaultManager(IVaultManager _vaultManager) external returns (uint256, uint256) {\n return _vaultManager.accrueInterestToTreasury();\n }\n}\n" + }, + "contracts/mock/MockUniswapV3Pool.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.7;\n\ncontract MockUniswapV3Pool {\n address public token0;\n address public token1;\n uint32 public constant EPOCH_DURATION = 24 * 3600 * 7;\n\n function setToken(address token, uint256 who) external {\n if (who == 0) token0 = token;\n else token1 = token;\n }\n\n function round(uint256 amount) external pure returns (uint256) {\n return (amount / EPOCH_DURATION) * EPOCH_DURATION;\n }\n}\n" + }, + "contracts/mock/MockVaultManager.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\nimport \"../interfaces/IVaultManager.sol\";\nimport \"../interfaces/ITreasury.sol\";\nimport \"@openzeppelin/contracts/token/ERC20/ERC20.sol\";\n\ncontract MockVaultManager {\n ITreasury public treasury;\n mapping(uint256 => Vault) public vaultData;\n mapping(uint256 => address) public ownerOf;\n uint256 public surplus;\n uint256 public badDebt;\n IAgToken public token;\n address public oracle = address(this);\n\n address public governor;\n address public collateral;\n address public stablecoin;\n uint256 public oracleValue;\n uint256 public interestAccumulator;\n uint256 public collateralFactor;\n uint256 public totalNormalizedDebt;\n\n constructor(address _treasury) {\n treasury = ITreasury(_treasury);\n }\n\n function accrueInterestToTreasury() external returns (uint256, uint256) {\n // Avoid the function to be view\n if (surplus >= badDebt) {\n token.mint(msg.sender, surplus - badDebt);\n }\n return (surplus, badDebt);\n }\n\n function read() external view returns (uint256) {\n return oracleValue;\n }\n\n function setParams(\n address _governor,\n address _collateral,\n address _stablecoin,\n uint256 _oracleValue,\n uint256 _interestAccumulator,\n uint256 _collateralFactor,\n uint256 _totalNormalizedDebt\n ) external {\n governor = _governor;\n collateral = _collateral;\n stablecoin = _stablecoin;\n interestAccumulator = _interestAccumulator;\n collateralFactor = _collateralFactor;\n totalNormalizedDebt = _totalNormalizedDebt;\n oracleValue = _oracleValue;\n }\n\n function setOwner(uint256 vaultID, address owner) external virtual {\n ownerOf[vaultID] = owner;\n }\n\n function setVaultData(uint256 normalizedDebt, uint256 collateralAmount, uint256 vaultID) external {\n vaultData[vaultID].normalizedDebt = normalizedDebt;\n vaultData[vaultID].collateralAmount = collateralAmount;\n }\n\n function isGovernor(address admin) external view returns (bool) {\n return admin == governor;\n }\n\n function setSurplusBadDebt(uint256 _surplus, uint256 _badDebt, IAgToken _token) external {\n surplus = _surplus;\n badDebt = _badDebt;\n token = _token;\n }\n\n function getDebtOut(uint256 vaultID, uint256 amountStablecoins, uint256 senderBorrowFee) external {}\n\n function setTreasury(address _treasury) external {\n treasury = ITreasury(_treasury);\n }\n\n function getVaultDebt(uint256 vaultID) external view returns (uint256) {\n vaultID;\n token;\n return 0;\n }\n\n function createVault(address toVault) external view returns (uint256) {\n toVault;\n token;\n return 0;\n }\n}\n\ncontract MockVaultManagerListing is MockVaultManager {\n // @notice Mapping from owner address to all his vaults\n mapping(address => uint256[]) internal _ownerListVaults;\n\n constructor(address _treasury) MockVaultManager(_treasury) {}\n\n function getUserVaults(address owner) public view returns (uint256[] memory) {\n return _ownerListVaults[owner];\n }\n\n function getUserCollateral(address owner) public view returns (uint256 totalCollateral) {\n uint256[] memory vaultList = _ownerListVaults[owner];\n uint256 vaultListLength = vaultList.length;\n for (uint256 k; k < vaultListLength; ++k) {\n totalCollateral += vaultData[vaultList[k]].collateralAmount;\n }\n return totalCollateral;\n }\n\n function setOwner(uint256 vaultID, address owner) external override {\n if (ownerOf[vaultID] != address(0)) _removeVaultFromList(ownerOf[vaultID], vaultID);\n _ownerListVaults[owner].push(vaultID);\n ownerOf[vaultID] = owner;\n }\n\n /// @notice Remove `vaultID` from `user` stroed vault list\n /// @param user Address to look out for the vault list\n /// @param vaultID VaultId to remove from the list\n /// @dev The vault is necessarily in the list\n function _removeVaultFromList(address user, uint256 vaultID) internal {\n uint256[] storage vaultList = _ownerListVaults[user];\n uint256 vaultListLength = vaultList.length;\n for (uint256 i; i < vaultListLength - 1; ++i) {\n if (vaultList[i] == vaultID) {\n vaultList[i] = vaultList[vaultListLength - 1];\n break;\n }\n }\n vaultList.pop();\n }\n}\n" + }, + "contracts/mock/MockVeBoostProxy.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\nimport \"../interfaces/governance/IVeBoostProxy.sol\";\n\ncontract MockVeBoostProxy is IVeBoostProxy {\n //solhint-disable-next-line\n mapping(address => uint256) public adjusted_balance_of;\n\n constructor() {}\n\n function setBalance(address concerned, uint256 balance) external {\n adjusted_balance_of[concerned] = balance;\n }\n}\n" + }, + "contracts/oracle/BaseOracleChainlinkMulti.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\n/*\n * █ \n ***** ▓▓▓ \n * ▓▓▓▓▓▓▓ \n * ///. ▓▓▓▓▓▓▓▓▓▓▓▓▓ \n ***** //////// ▓▓▓▓▓▓▓ \n * ///////////// ▓▓▓ \n ▓▓ ////////////////// █ ▓▓ \n ▓▓ ▓▓ /////////////////////// ▓▓ ▓▓ \n ▓▓ ▓▓ //////////////////////////// ▓▓ ▓▓ \n ▓▓ ▓▓ /////////▓▓▓///////▓▓▓///////// ▓▓ ▓▓ \n ▓▓ ,////////////////////////////////////// ▓▓ ▓▓ \n ▓▓ ////////////////////////////////////////// ▓▓ \n ▓▓ //////////////////////▓▓▓▓///////////////////// \n ,//////////////////////////////////////////////////// \n .////////////////////////////////////////////////////////// \n .//////////////////////////██.,//////////////////////////█ \n .//////////////////////████..,./////////////////////██ \n ...////////////////███████.....,.////////////////███ \n ,.,////////////████████ ........,///////////████ \n .,.,//////█████████ ,.......///////████ \n ,..//████████ ........./████ \n ..,██████ .....,███ \n .██ ,.,█ \n \n \n \n ▓▓ ▓▓▓▓▓▓▓▓▓▓ ▓▓▓▓▓▓▓▓▓▓ ▓▓ ▓▓▓▓▓▓▓▓▓▓ \n ▓▓▓▓▓▓ ▓▓▓ ▓▓▓ ▓▓▓ ▓▓ ▓▓ ▓▓▓▓ \n ▓▓▓ ▓▓▓ ▓▓▓ ▓▓▓ ▓▓▓ ▓▓▓ ▓▓ ▓▓▓▓▓ \n ▓▓▓ ▓▓ ▓▓▓ ▓▓▓ ▓▓▓▓▓▓▓▓▓▓ ▓▓▓▓▓▓▓▓▓▓ ▓▓▓▓▓▓▓▓▓▓ \n*/\n\npragma solidity ^0.8.12;\n\nimport \"@chainlink/contracts/src/v0.8/interfaces/AggregatorV3Interface.sol\";\n\nimport \"../interfaces/IOracle.sol\";\nimport \"../interfaces/ITreasury.sol\";\n\n/// @title BaseOracleChainlinkMulti\n/// @author Angle Labs, Inc.\n/// @notice Base Contract to be overriden by all contracts of the protocol\n/// @dev This base contract concerns an oracle that uses Chainlink with multiple pools to read from\n/// @dev All gas-efficient implementation of the `OracleChainlinkMulti` contract should inherit from this\nabstract contract BaseOracleChainlinkMulti is IOracle {\n // ========================= Parameters and References =========================\n\n /// @inheritdoc IOracle\n ITreasury public override treasury;\n /// @notice Represent the maximum amount of time (in seconds) between each Chainlink update\n /// before the price feed is considered stale\n uint32 public stalePeriod;\n\n // =================================== Event ===================================\n\n event StalePeriodUpdated(uint32 _stalePeriod);\n\n // =================================== Errors ===================================\n\n error InvalidChainlinkRate();\n error NotGovernorOrGuardian();\n error NotVaultManagerOrGovernor();\n\n /// @notice Constructor for an oracle using Chainlink with multiple pools to read from\n /// @param _stalePeriod Minimum feed update frequency for the oracle to not revert\n /// @param _treasury Treasury associated to the VaultManager which reads from this feed\n constructor(uint32 _stalePeriod, address _treasury) {\n stalePeriod = _stalePeriod;\n treasury = ITreasury(_treasury);\n }\n\n // ============================= Reading Oracles ===============================\n\n /// @inheritdoc IOracle\n function read() external view virtual override returns (uint256 quoteAmount);\n\n /// @inheritdoc IOracle\n function circuitChainlink() public view virtual returns (AggregatorV3Interface[] memory);\n\n /// @notice Reads a Chainlink feed using a quote amount and converts the quote amount to\n /// the out-currency\n /// @param quoteAmount The amount for which to compute the price expressed with base decimal\n /// @param feed Chainlink feed to query\n /// @param multiplied Whether the ratio outputted by Chainlink should be multiplied or divided\n /// to the `quoteAmount`\n /// @param decimals Number of decimals of the corresponding Chainlink pair\n /// @return The `quoteAmount` converted in out-currency\n function _readChainlinkFeed(\n uint256 quoteAmount,\n AggregatorV3Interface feed,\n uint8 multiplied,\n uint256 decimals\n ) internal view returns (uint256) {\n (uint80 roundId, int256 ratio, , uint256 updatedAt, uint80 answeredInRound) = feed.latestRoundData();\n if (ratio <= 0 || roundId > answeredInRound || block.timestamp - updatedAt > stalePeriod)\n revert InvalidChainlinkRate();\n uint256 castedRatio = uint256(ratio);\n // Checking whether we should multiply or divide by the ratio computed\n if (multiplied == 1) return (quoteAmount * castedRatio) / (10 ** decimals);\n else return (quoteAmount * (10 ** decimals)) / castedRatio;\n }\n\n // ======================= Governance Related Functions ========================\n\n /// @notice Changes the stale period\n /// @param _stalePeriod New stale period (in seconds)\n function changeStalePeriod(uint32 _stalePeriod) external {\n if (!treasury.isGovernorOrGuardian(msg.sender)) revert NotGovernorOrGuardian();\n stalePeriod = _stalePeriod;\n emit StalePeriodUpdated(_stalePeriod);\n }\n\n /// @inheritdoc IOracle\n function setTreasury(address _treasury) external override {\n if (!treasury.isVaultManager(msg.sender) && !treasury.isGovernor(msg.sender))\n revert NotVaultManagerOrGovernor();\n treasury = ITreasury(_treasury);\n }\n}\n" + }, + "contracts/oracle/BaseOracleChainlinkMultiTwoFeeds.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\nimport \"@chainlink/contracts/src/v0.8/interfaces/AggregatorV3Interface.sol\";\n\nimport \"./BaseOracleChainlinkMulti.sol\";\n\n/// @title BaseOracleChainlinkMultiTwoFeeds\n/// @author Angle Labs, Inc.\n/// @notice Base contract for an oracle that reads into two Chainlink feeds (including an EUR/USD feed) which both have\n/// 8 decimals\nabstract contract BaseOracleChainlinkMultiTwoFeeds is BaseOracleChainlinkMulti {\n constructor(uint32 _stalePeriod, address _treasury) BaseOracleChainlinkMulti(_stalePeriod, _treasury) {}\n\n /// @notice Returns the quote amount of the oracle contract\n function _getQuoteAmount() internal view virtual returns (uint256) {\n return 10 ** 18;\n }\n\n /// @inheritdoc IOracle\n function read() external view virtual override returns (uint256 quoteAmount) {\n quoteAmount = _getQuoteAmount();\n AggregatorV3Interface[] memory _circuitChainlink = circuitChainlink();\n uint8[2] memory circuitChainIsMultiplied = [1, 0];\n uint8[2] memory chainlinkDecimals = [8, 8];\n uint256 circuitLength = _circuitChainlink.length;\n for (uint256 i; i < circuitLength; ++i) {\n quoteAmount = _readChainlinkFeed(\n quoteAmount,\n _circuitChainlink[i],\n circuitChainIsMultiplied[i],\n chainlinkDecimals[i]\n );\n }\n }\n}\n" + }, + "contracts/oracle/BaseOracleChainlinkOneFeed.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\nimport \"@chainlink/contracts/src/v0.8/interfaces/AggregatorV3Interface.sol\";\n\nimport \"./BaseOracleChainlinkMulti.sol\";\n\n/// @title BaseOracleChainlinkOneFeed\n/// @author Angle Labs, Inc.\n/// @notice Base contract for an oracle that reads into one Chainlink feeds with 8 decimals\nabstract contract BaseOracleChainlinkOneFeed is BaseOracleChainlinkMulti {\n constructor(uint32 _stalePeriod, address _treasury) BaseOracleChainlinkMulti(_stalePeriod, _treasury) {}\n\n /// @notice Returns the quote amount of the oracle contract\n function _getQuoteAmount() internal view virtual returns (uint256) {\n return 10 ** 18;\n }\n\n /// @inheritdoc IOracle\n function read() external view virtual override returns (uint256 quoteAmount) {\n AggregatorV3Interface[] memory _circuitChainlink = circuitChainlink();\n quoteAmount = _readChainlinkFeed(_getQuoteAmount(), _circuitChainlink[0], 1, 8);\n }\n}\n" + }, + "contracts/oracle/implementations/arbitrum/EUR/OracleBTCEURChainlinkArbitrum.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\nimport \"@chainlink/contracts/src/v0.8/interfaces/AggregatorV3Interface.sol\";\n\nimport \"../../../BaseOracleChainlinkMultiTwoFeeds.sol\";\n\n/// @title OracleBTCEURChainlinkArbitrum\n/// @author Angle Labs, Inc.\n/// @notice Gives the price of BTC in Euro in base 18\n/// @dev This contract is built to be deployed on Arbitrum\ncontract OracleBTCEURChainlinkArbitrum is BaseOracleChainlinkMultiTwoFeeds {\n string public constant DESCRIPTION = \"BTC/EUR Oracle\";\n\n constructor(uint32 _stalePeriod, address _treasury) BaseOracleChainlinkMultiTwoFeeds(_stalePeriod, _treasury) {}\n\n /// @inheritdoc IOracle\n function circuitChainlink() public pure override returns (AggregatorV3Interface[] memory) {\n AggregatorV3Interface[] memory _circuitChainlink = new AggregatorV3Interface[](2);\n // Oracle BTC/USD\n _circuitChainlink[0] = AggregatorV3Interface(0x6ce185860a4963106506C203335A2910413708e9);\n // Oracle EUR/USD\n _circuitChainlink[1] = AggregatorV3Interface(0xA14d53bC1F1c0F31B4aA3BD109344E5009051a84);\n return _circuitChainlink;\n }\n}\n" + }, + "contracts/oracle/implementations/arbitrum/EUR/OracleETHEURChainlinkArbitrum.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\nimport \"@chainlink/contracts/src/v0.8/interfaces/AggregatorV3Interface.sol\";\n\nimport \"../../../BaseOracleChainlinkMultiTwoFeeds.sol\";\n\n/// @title OracleETHEURChainlinkArbitrum\n/// @author Angle Labs, Inc.\n/// @notice Gives the price of ETH in Euro in base 18\n/// @dev This contract is built to be deployed on Arbitrum\ncontract OracleETHEURChainlinkArbitrum is BaseOracleChainlinkMultiTwoFeeds {\n string public constant DESCRIPTION = \"ETH/EUR Oracle\";\n\n constructor(uint32 _stalePeriod, address _treasury) BaseOracleChainlinkMultiTwoFeeds(_stalePeriod, _treasury) {}\n\n /// @inheritdoc IOracle\n function circuitChainlink() public pure override returns (AggregatorV3Interface[] memory) {\n AggregatorV3Interface[] memory _circuitChainlink = new AggregatorV3Interface[](2);\n // Oracle ETH/USD\n _circuitChainlink[0] = AggregatorV3Interface(0x639Fe6ab55C921f74e7fac1ee960C0B6293ba612);\n // Oracle EUR/USD\n _circuitChainlink[1] = AggregatorV3Interface(0xA14d53bC1F1c0F31B4aA3BD109344E5009051a84);\n return _circuitChainlink;\n }\n}\n" + }, + "contracts/oracle/implementations/arbitrum/EUR/OracleUSDCEURChainlinkArbitrum.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\nimport \"@chainlink/contracts/src/v0.8/interfaces/AggregatorV3Interface.sol\";\n\nimport \"../../../BaseOracleChainlinkMultiTwoFeeds.sol\";\n\n/// @title OracleUSDCEURChainlinkArbitrum\n/// @author Angle Labs, Inc.\n/// @notice Gives the price of USDC in Euro in base 18\n/// @dev This contract is built to be deployed on Arbitrum\ncontract OracleUSDCEURChainlinkArbitrum is BaseOracleChainlinkMultiTwoFeeds {\n string public constant DESCRIPTION = \"USDC/EUR Oracle\";\n\n constructor(uint32 _stalePeriod, address _treasury) BaseOracleChainlinkMultiTwoFeeds(_stalePeriod, _treasury) {}\n\n /// @inheritdoc IOracle\n function circuitChainlink() public pure override returns (AggregatorV3Interface[] memory) {\n AggregatorV3Interface[] memory _circuitChainlink = new AggregatorV3Interface[](2);\n // Oracle ETH/USD\n _circuitChainlink[0] = AggregatorV3Interface(0x50834F3163758fcC1Df9973b6e91f0F0F0434aD3);\n // Oracle EUR/USD\n _circuitChainlink[1] = AggregatorV3Interface(0xA14d53bC1F1c0F31B4aA3BD109344E5009051a84);\n return _circuitChainlink;\n }\n}\n" + }, + "contracts/oracle/implementations/avalanche/EUR/OracleAVAXEURChainlinkAvalanche.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\nimport \"@chainlink/contracts/src/v0.8/interfaces/AggregatorV3Interface.sol\";\n\nimport \"../../../BaseOracleChainlinkMultiTwoFeeds.sol\";\n\n/// @title OracleAVAXEURChainlinkAvalanche\n/// @author Angle Labs, Inc.\n/// @notice Gives the price of AVAX in Euro in base 18\n/// @dev This contract is built to be deployed on Avalanche\ncontract OracleAVAXEURChainlinkAvalanche is BaseOracleChainlinkMultiTwoFeeds {\n string public constant DESCRIPTION = \"AVAX/EUR Oracle\";\n\n constructor(uint32 _stalePeriod, address _treasury) BaseOracleChainlinkMultiTwoFeeds(_stalePeriod, _treasury) {}\n\n /// @inheritdoc IOracle\n function circuitChainlink() public pure override returns (AggregatorV3Interface[] memory) {\n AggregatorV3Interface[] memory _circuitChainlink = new AggregatorV3Interface[](2);\n // Oracle AVAX/USD\n _circuitChainlink[0] = AggregatorV3Interface(0x0A77230d17318075983913bC2145DB16C7366156);\n // Oracle EUR/USD\n _circuitChainlink[1] = AggregatorV3Interface(0x192f2DBA961Bb0277520C082d6bfa87D5961333E);\n return _circuitChainlink;\n }\n}\n" + }, + "contracts/oracle/implementations/avalanche/EUR/OracleUSDCEURChainlinkAvalanche.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\nimport \"@chainlink/contracts/src/v0.8/interfaces/AggregatorV3Interface.sol\";\n\nimport \"../../../BaseOracleChainlinkMultiTwoFeeds.sol\";\n\n/// @title OracleUSDCEURChainlinkAvalanche\n/// @author Angle Labs, Inc.\n/// @notice Gives the price of USDC in Euro in base 18\n/// @dev This contract is built to be deployed on Avalanche\ncontract OracleUSDCEURChainlinkAvalanche is BaseOracleChainlinkMultiTwoFeeds {\n string public constant DESCRIPTION = \"USDC/EUR Oracle\";\n\n constructor(uint32 _stalePeriod, address _treasury) BaseOracleChainlinkMultiTwoFeeds(_stalePeriod, _treasury) {}\n\n /// @inheritdoc IOracle\n function circuitChainlink() public pure override returns (AggregatorV3Interface[] memory) {\n AggregatorV3Interface[] memory _circuitChainlink = new AggregatorV3Interface[](2);\n // Oracle USDC/USD\n _circuitChainlink[0] = AggregatorV3Interface(0xF096872672F44d6EBA71458D74fe67F9a77a23B9);\n // Oracle EUR/USD\n _circuitChainlink[1] = AggregatorV3Interface(0x192f2DBA961Bb0277520C082d6bfa87D5961333E);\n return _circuitChainlink;\n }\n}\n" + }, + "contracts/oracle/implementations/mainnet/EUR/OracleBTCEURChainlink.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\nimport \"@chainlink/contracts/src/v0.8/interfaces/AggregatorV3Interface.sol\";\n\nimport \"../../../BaseOracleChainlinkMultiTwoFeeds.sol\";\n\n/// @title OracleBTCEURChainlink\n/// @author Angle Labs, Inc.\n/// @notice Gives the price of BTC in Euro in base 18\ncontract OracleBTCEURChainlink is BaseOracleChainlinkMultiTwoFeeds {\n string public constant DESCRIPTION = \"BTC/EUR Oracle\";\n\n constructor(uint32 _stalePeriod, address _treasury) BaseOracleChainlinkMultiTwoFeeds(_stalePeriod, _treasury) {}\n\n /// @inheritdoc IOracle\n function circuitChainlink() public pure override returns (AggregatorV3Interface[] memory) {\n AggregatorV3Interface[] memory _circuitChainlink = new AggregatorV3Interface[](2);\n // Oracle BTC/USD\n _circuitChainlink[0] = AggregatorV3Interface(0xF4030086522a5bEEa4988F8cA5B36dbC97BeE88c);\n // Oracle EUR/USD\n _circuitChainlink[1] = AggregatorV3Interface(0xb49f677943BC038e9857d61E7d053CaA2C1734C1);\n return _circuitChainlink;\n }\n}\n" + }, + "contracts/oracle/implementations/mainnet/EUR/OracleCBETHEURChainlink.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\nimport \"@chainlink/contracts/src/v0.8/interfaces/AggregatorV3Interface.sol\";\n\nimport \"../../../BaseOracleChainlinkMultiTwoFeeds.sol\";\n\n/// @title OracleCBETHEURChainlink\n/// @author Angle Labs, Inc.\n/// @notice Gives the price of cbETH in Euro in base 18\ncontract OracleCBETHEURChainlink is BaseOracleChainlinkMultiTwoFeeds {\n string public constant DESCRIPTION = \"cbETH/EUR Oracle\";\n\n constructor(uint32 _stalePeriod, address _treasury) BaseOracleChainlinkMultiTwoFeeds(_stalePeriod, _treasury) {}\n\n /// @inheritdoc IOracle\n function circuitChainlink() public pure override returns (AggregatorV3Interface[] memory) {\n AggregatorV3Interface[] memory _circuitChainlink = new AggregatorV3Interface[](3);\n // Oracle cbETH/ETH\n _circuitChainlink[0] = AggregatorV3Interface(0xF017fcB346A1885194689bA23Eff2fE6fA5C483b);\n // Oracle ETH/USD\n _circuitChainlink[1] = AggregatorV3Interface(0x5f4eC3Df9cbd43714FE2740f5E3616155c5b8419);\n // Oracle EUR/USD\n _circuitChainlink[2] = AggregatorV3Interface(0xb49f677943BC038e9857d61E7d053CaA2C1734C1);\n return _circuitChainlink;\n }\n\n /// @inheritdoc BaseOracleChainlinkMultiTwoFeeds\n function read() external view virtual override returns (uint256 quoteAmount) {\n quoteAmount = _getQuoteAmount();\n AggregatorV3Interface[] memory _circuitChainlink = circuitChainlink();\n uint8[3] memory circuitChainIsMultiplied = [1, 1, 0];\n uint8[3] memory chainlinkDecimals = [18, 8, 8];\n uint256 circuitLength = _circuitChainlink.length;\n for (uint256 i; i < circuitLength; ++i) {\n quoteAmount = _readChainlinkFeed(\n quoteAmount,\n _circuitChainlink[i],\n circuitChainIsMultiplied[i],\n chainlinkDecimals[i]\n );\n }\n }\n}\n" + }, + "contracts/oracle/implementations/mainnet/EUR/OracleETHEURChainlink.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\nimport \"@chainlink/contracts/src/v0.8/interfaces/AggregatorV3Interface.sol\";\n\nimport \"../../../BaseOracleChainlinkMultiTwoFeeds.sol\";\n\n/// @title OracleETHEURChainlink\n/// @author Angle Labs, Inc.\n/// @notice Gives the price of ETH in Euro in base 18\ncontract OracleETHEURChainlink is BaseOracleChainlinkMultiTwoFeeds {\n string public constant DESCRIPTION = \"ETH/EUR Oracle\";\n\n constructor(uint32 _stalePeriod, address _treasury) BaseOracleChainlinkMultiTwoFeeds(_stalePeriod, _treasury) {}\n\n /// @inheritdoc IOracle\n function circuitChainlink() public pure override returns (AggregatorV3Interface[] memory) {\n AggregatorV3Interface[] memory _circuitChainlink = new AggregatorV3Interface[](2);\n // Oracle ETH/USD\n _circuitChainlink[0] = AggregatorV3Interface(0x5f4eC3Df9cbd43714FE2740f5E3616155c5b8419);\n // Oracle EUR/USD\n _circuitChainlink[1] = AggregatorV3Interface(0xb49f677943BC038e9857d61E7d053CaA2C1734C1);\n return _circuitChainlink;\n }\n}\n" + }, + "contracts/oracle/implementations/mainnet/EUR/OracleHIGHEURChainlink.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\nimport \"@chainlink/contracts/src/v0.8/interfaces/AggregatorV3Interface.sol\";\n\nimport \"../../../BaseOracleChainlinkMultiTwoFeeds.sol\";\n\n/// @title OracleHIGHEURChainlink\n/// @author Angle Labs, Inc.\n/// @notice Gives the price of HIGH in Euro in base 18\ncontract OracleHIGHEURChainlink is BaseOracleChainlinkMultiTwoFeeds {\n string public constant DESCRIPTION = \"HIGH/EUR Oracle\";\n\n constructor(uint32 _stalePeriod, address _treasury) BaseOracleChainlinkMultiTwoFeeds(_stalePeriod, _treasury) {}\n\n /// @inheritdoc IOracle\n function circuitChainlink() public pure override returns (AggregatorV3Interface[] memory) {\n AggregatorV3Interface[] memory _circuitChainlink = new AggregatorV3Interface[](1);\n // Oracle HIGH/EUR\n _circuitChainlink[0] = AggregatorV3Interface(0x9E8E794ad6Ecdb6d5c7eaBE059D30E907F58859b);\n return _circuitChainlink;\n }\n\n /// @inheritdoc BaseOracleChainlinkMultiTwoFeeds\n function read() external view override returns (uint256 quoteAmount) {\n quoteAmount = _readChainlinkFeed(_getQuoteAmount(), circuitChainlink()[0], 1, 8);\n }\n}\n" + }, + "contracts/oracle/implementations/mainnet/EUR/OracleIB01EURChainlink.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\nimport \"@chainlink/contracts/src/v0.8/interfaces/AggregatorV3Interface.sol\";\n\nimport \"../../../BaseOracleChainlinkMultiTwoFeeds.sol\";\n\n/// @title OracleIB01EURChainlink\n/// @author Angle Labs, Inc.\n/// @notice Gives the price of IB01 in Euro in base 18\ncontract OracleIB01EURChainlink is BaseOracleChainlinkMultiTwoFeeds {\n string public constant DESCRIPTION = \"IB01/EUR Oracle\";\n\n constructor(uint32 _stalePeriod, address _treasury) BaseOracleChainlinkMultiTwoFeeds(_stalePeriod, _treasury) {}\n\n /// @inheritdoc IOracle\n function circuitChainlink() public pure override returns (AggregatorV3Interface[] memory) {\n AggregatorV3Interface[] memory _circuitChainlink = new AggregatorV3Interface[](2);\n // Oracle IB01/USD\n _circuitChainlink[0] = AggregatorV3Interface(0x32d1463EB53b73C095625719Afa544D5426354cB);\n // Oracle EUR/USD\n _circuitChainlink[1] = AggregatorV3Interface(0xb49f677943BC038e9857d61E7d053CaA2C1734C1);\n return _circuitChainlink;\n }\n}\n" + }, + "contracts/oracle/implementations/mainnet/EUR/OracleLUSDEURChainlink.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\nimport \"@chainlink/contracts/src/v0.8/interfaces/AggregatorV3Interface.sol\";\n\nimport \"../../../BaseOracleChainlinkMultiTwoFeeds.sol\";\n\n/// @title OracleLUSDEURChainlink\n/// @author Angle Labs, Inc.\n/// @notice Gives the price of LUSD in Euro in base 18\ncontract OracleLUSDEURChainlink is BaseOracleChainlinkMultiTwoFeeds {\n string public constant DESCRIPTION = \"LUSD/EUR Oracle\";\n\n constructor(uint32 _stalePeriod, address _treasury) BaseOracleChainlinkMultiTwoFeeds(_stalePeriod, _treasury) {}\n\n /// @inheritdoc IOracle\n function circuitChainlink() public pure override returns (AggregatorV3Interface[] memory) {\n AggregatorV3Interface[] memory _circuitChainlink = new AggregatorV3Interface[](2);\n // Oracle LUSD/USD\n _circuitChainlink[0] = AggregatorV3Interface(0x3D7aE7E594f2f2091Ad8798313450130d0Aba3a0);\n // Oracle EUR/USD\n _circuitChainlink[1] = AggregatorV3Interface(0xb49f677943BC038e9857d61E7d053CaA2C1734C1);\n return _circuitChainlink;\n }\n}\n" + }, + "contracts/oracle/implementations/mainnet/EUR/OracleUSDCEURChainlink.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\nimport \"@chainlink/contracts/src/v0.8/interfaces/AggregatorV3Interface.sol\";\n\nimport \"../../../BaseOracleChainlinkMultiTwoFeeds.sol\";\n\n/// @title OracleUSDCEURChainlink\n/// @author Angle Labs, Inc.\n/// @notice Gives the price of USDC in Euro in base 18\ncontract OracleUSDCEURChainlink is BaseOracleChainlinkMultiTwoFeeds {\n string public constant DESCRIPTION = \"USDC/EUR Oracle\";\n\n constructor(uint32 _stalePeriod, address _treasury) BaseOracleChainlinkMultiTwoFeeds(_stalePeriod, _treasury) {}\n\n /// @inheritdoc IOracle\n function circuitChainlink() public pure override returns (AggregatorV3Interface[] memory) {\n AggregatorV3Interface[] memory _circuitChainlink = new AggregatorV3Interface[](2);\n // Oracle USDC/USD\n _circuitChainlink[0] = AggregatorV3Interface(0x8fFfFfd4AfB6115b954Bd326cbe7B4BA576818f6);\n // Oracle EUR/USD\n _circuitChainlink[1] = AggregatorV3Interface(0xb49f677943BC038e9857d61E7d053CaA2C1734C1);\n return _circuitChainlink;\n }\n}\n" + }, + "contracts/oracle/implementations/mainnet/EUR/OracleWSTETHEURChainlink.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\nimport \"@chainlink/contracts/src/v0.8/interfaces/AggregatorV3Interface.sol\";\n\nimport \"../../../BaseOracleChainlinkMultiTwoFeeds.sol\";\nimport \"../../../../interfaces/external/lido/IStETH.sol\";\n\n/// @title OracleWSTETHEURChainlink\n/// @author Angle Labs, Inc.\n/// @notice Gives the price of wSTETH in Euro in base 18\ncontract OracleWSTETHEURChainlink is BaseOracleChainlinkMultiTwoFeeds {\n string public constant DESCRIPTION = \"wSTETH/EUR Oracle\";\n IStETH public constant STETH = IStETH(0xae7ab96520DE3A18E5e111B5EaAb095312D7fE84);\n\n constructor(uint32 _stalePeriod, address _treasury) BaseOracleChainlinkMultiTwoFeeds(_stalePeriod, _treasury) {}\n\n /// @inheritdoc IOracle\n function circuitChainlink() public pure override returns (AggregatorV3Interface[] memory) {\n AggregatorV3Interface[] memory _circuitChainlink = new AggregatorV3Interface[](2);\n // Oracle stETH/USD\n _circuitChainlink[0] = AggregatorV3Interface(0xCfE54B5cD566aB89272946F602D76Ea879CAb4a8);\n // Oracle EUR/USD\n _circuitChainlink[1] = AggregatorV3Interface(0xb49f677943BC038e9857d61E7d053CaA2C1734C1);\n return _circuitChainlink;\n }\n\n /// @inheritdoc BaseOracleChainlinkMultiTwoFeeds\n function _getQuoteAmount() internal view override returns (uint256) {\n return STETH.getPooledEthByShares(1 ether);\n }\n}\n" + }, + "contracts/oracle/implementations/mainnet/USD/OracleWSTETHUSDChainlink.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\nimport \"@chainlink/contracts/src/v0.8/interfaces/AggregatorV3Interface.sol\";\n\nimport \"../../../BaseOracleChainlinkOneFeed.sol\";\nimport \"../../../../interfaces/external/lido/IStETH.sol\";\n\n/// @title OracleWSTETHUSDChainlink\n/// @author Angle Labs, Inc.\n/// @notice Gives the price of wSTETH in USD in base 18\ncontract OracleWSTETHUSDChainlink is BaseOracleChainlinkOneFeed {\n string public constant DESCRIPTION = \"wSTETH/USD Oracle\";\n IStETH public constant STETH = IStETH(0xae7ab96520DE3A18E5e111B5EaAb095312D7fE84);\n\n constructor(uint32 _stalePeriod, address _treasury) BaseOracleChainlinkOneFeed(_stalePeriod, _treasury) {}\n\n /// @inheritdoc IOracle\n function circuitChainlink() public pure override returns (AggregatorV3Interface[] memory) {\n AggregatorV3Interface[] memory _circuitChainlink = new AggregatorV3Interface[](1);\n // Oracle stETH/USD\n _circuitChainlink[0] = AggregatorV3Interface(0xCfE54B5cD566aB89272946F602D76Ea879CAb4a8);\n return _circuitChainlink;\n }\n\n /// @inheritdoc BaseOracleChainlinkOneFeed\n function _getQuoteAmount() internal view override returns (uint256) {\n return STETH.getPooledEthByShares(1 ether);\n }\n}\n" + }, + "contracts/oracle/implementations/mainnet/XAU/OracleETHXAUChainlink.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\nimport \"@chainlink/contracts/src/v0.8/interfaces/AggregatorV3Interface.sol\";\n\nimport \"../../../BaseOracleChainlinkMultiTwoFeeds.sol\";\n\n/// @title OracleETHXAUChainlink\n/// @author Angle Labs, Inc.\n/// @notice Gives the price of ETH in XAU in base 18\ncontract OracleETHXAUChainlink is BaseOracleChainlinkMultiTwoFeeds {\n string public constant DESCRIPTION = \"ETH/GOLD Oracle\";\n\n constructor(uint32 _stalePeriod, address _treasury) BaseOracleChainlinkMultiTwoFeeds(_stalePeriod, _treasury) {}\n\n /// @inheritdoc IOracle\n function circuitChainlink() public pure override returns (AggregatorV3Interface[] memory) {\n AggregatorV3Interface[] memory _circuitChainlink = new AggregatorV3Interface[](2);\n // Oracle ETH/USD\n _circuitChainlink[0] = AggregatorV3Interface(0x5f4eC3Df9cbd43714FE2740f5E3616155c5b8419);\n // Oracle XAU/USD\n _circuitChainlink[1] = AggregatorV3Interface(0x214eD9Da11D2fbe465a6fc601a91E62EbEc1a0D6);\n return _circuitChainlink;\n }\n}\n" + }, + "contracts/oracle/implementations/mainnet/XAU/OracleLUSDXAUChainlink.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\nimport \"@chainlink/contracts/src/v0.8/interfaces/AggregatorV3Interface.sol\";\n\nimport \"../../../BaseOracleChainlinkMultiTwoFeeds.sol\";\n\n/// @title OracleLUSDXAUChainlink\n/// @author Angle Labs, Inc.\n/// @notice Gives the price of LUSD in XAU in base 18\ncontract OracleLUSDXAUChainlink is BaseOracleChainlinkMultiTwoFeeds {\n string public constant DESCRIPTION = \"LUSD/GOLD Oracle\";\n\n constructor(uint32 _stalePeriod, address _treasury) BaseOracleChainlinkMultiTwoFeeds(_stalePeriod, _treasury) {}\n\n /// @inheritdoc IOracle\n function circuitChainlink() public pure override returns (AggregatorV3Interface[] memory) {\n AggregatorV3Interface[] memory _circuitChainlink = new AggregatorV3Interface[](2);\n // Oracle LUSD/USD\n _circuitChainlink[0] = AggregatorV3Interface(0x3D7aE7E594f2f2091Ad8798313450130d0Aba3a0);\n // Oracle XAU/USD\n _circuitChainlink[1] = AggregatorV3Interface(0x214eD9Da11D2fbe465a6fc601a91E62EbEc1a0D6);\n return _circuitChainlink;\n }\n}\n" + }, + "contracts/oracle/implementations/mainnet/XAU/OracleUSDCXAUChainlink.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\nimport \"@chainlink/contracts/src/v0.8/interfaces/AggregatorV3Interface.sol\";\n\nimport \"../../../BaseOracleChainlinkMultiTwoFeeds.sol\";\n\n/// @title OracleUSDCXAUChainlink\n/// @author Angle Labs, Inc.\n/// @notice Gives the price of USDC in XAU in base 18\ncontract OracleUSDCXAUChainlink is BaseOracleChainlinkMultiTwoFeeds {\n string public constant DESCRIPTION = \"USDC/GOLD Oracle\";\n\n constructor(uint32 _stalePeriod, address _treasury) BaseOracleChainlinkMultiTwoFeeds(_stalePeriod, _treasury) {}\n\n /// @inheritdoc IOracle\n function circuitChainlink() public pure override returns (AggregatorV3Interface[] memory) {\n AggregatorV3Interface[] memory _circuitChainlink = new AggregatorV3Interface[](2);\n // Oracle USDC/USD\n _circuitChainlink[0] = AggregatorV3Interface(0x8fFfFfd4AfB6115b954Bd326cbe7B4BA576818f6);\n // Oracle XAU/USD\n _circuitChainlink[1] = AggregatorV3Interface(0x214eD9Da11D2fbe465a6fc601a91E62EbEc1a0D6);\n return _circuitChainlink;\n }\n}\n" + }, + "contracts/oracle/implementations/mainnet/XAU/OracleWSTETHXAUChainlink.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\nimport \"@chainlink/contracts/src/v0.8/interfaces/AggregatorV3Interface.sol\";\n\nimport \"../../../BaseOracleChainlinkMultiTwoFeeds.sol\";\nimport \"../../../../interfaces/external/lido/IStETH.sol\";\n\n/// @title OracleWSTETHXAUChainlink\n/// @author Angle Labs, Inc.\n/// @notice Gives the price of wSTETH in XAU in base 18\ncontract OracleWSTETHXAUChainlink is BaseOracleChainlinkMultiTwoFeeds {\n string public constant DESCRIPTION = \"wSTETH/XAU Oracle\";\n IStETH public constant STETH = IStETH(0xae7ab96520DE3A18E5e111B5EaAb095312D7fE84);\n\n constructor(uint32 _stalePeriod, address _treasury) BaseOracleChainlinkMultiTwoFeeds(_stalePeriod, _treasury) {}\n\n /// @inheritdoc IOracle\n function circuitChainlink() public pure override returns (AggregatorV3Interface[] memory) {\n AggregatorV3Interface[] memory _circuitChainlink = new AggregatorV3Interface[](2);\n // Oracle stETH/USD\n _circuitChainlink[0] = AggregatorV3Interface(0xCfE54B5cD566aB89272946F602D76Ea879CAb4a8);\n // Oracle XAU/USD\n _circuitChainlink[1] = AggregatorV3Interface(0x214eD9Da11D2fbe465a6fc601a91E62EbEc1a0D6);\n return _circuitChainlink;\n }\n\n /// @inheritdoc BaseOracleChainlinkMultiTwoFeeds\n function _getQuoteAmount() internal view override returns (uint256) {\n return STETH.getPooledEthByShares(1 ether);\n }\n}\n" + }, + "contracts/oracle/implementations/optimism/EUR/OracleETHEURChainlinkOptimism.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\nimport \"@chainlink/contracts/src/v0.8/interfaces/AggregatorV3Interface.sol\";\n\nimport \"../../../BaseOracleChainlinkMultiTwoFeeds.sol\";\n\n/// @title OracleETHEURChainlinkOptimism\n/// @author Angle Labs, Inc.\n/// @notice Gives the price of ETH in Euro in base 18\n/// @dev This contract is built to be deployed on Optimism\ncontract OracleETHEURChainlinkOptimism is BaseOracleChainlinkMultiTwoFeeds {\n string public constant DESCRIPTION = \"ETH/EUR Oracle\";\n\n constructor(uint32 _stalePeriod, address _treasury) BaseOracleChainlinkMultiTwoFeeds(_stalePeriod, _treasury) {}\n\n /// @inheritdoc IOracle\n function circuitChainlink() public pure override returns (AggregatorV3Interface[] memory) {\n AggregatorV3Interface[] memory _circuitChainlink = new AggregatorV3Interface[](2);\n // Oracle ETH/USD\n _circuitChainlink[0] = AggregatorV3Interface(0x13e3Ee699D1909E989722E753853AE30b17e08c5);\n // Oracle EUR/USD\n _circuitChainlink[1] = AggregatorV3Interface(0x3626369857A10CcC6cc3A6e4f5C2f5984a519F20);\n return _circuitChainlink;\n }\n}\n" + }, + "contracts/oracle/implementations/optimism/EUR/OracleOPEURChainlinkOptimism.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\nimport \"@chainlink/contracts/src/v0.8/interfaces/AggregatorV3Interface.sol\";\n\nimport \"../../../BaseOracleChainlinkMultiTwoFeeds.sol\";\n\n/// @title OracleOPEURChainlinkOptimism\n/// @author Angle Labs, Inc.\n/// @notice Gives the price of OP in Euro in base 18\n/// @dev This contract is built to be deployed on Optimism\ncontract OracleOPEURChainlinkOptimism is BaseOracleChainlinkMultiTwoFeeds {\n string public constant DESCRIPTION = \"OP/EUR Oracle\";\n\n constructor(uint32 _stalePeriod, address _treasury) BaseOracleChainlinkMultiTwoFeeds(_stalePeriod, _treasury) {}\n\n /// @inheritdoc IOracle\n function circuitChainlink() public pure override returns (AggregatorV3Interface[] memory) {\n AggregatorV3Interface[] memory _circuitChainlink = new AggregatorV3Interface[](2);\n // Oracle OP/USD\n _circuitChainlink[0] = AggregatorV3Interface(0x0D276FC14719f9292D5C1eA2198673d1f4269246);\n // Oracle EUR/USD\n _circuitChainlink[1] = AggregatorV3Interface(0x3626369857A10CcC6cc3A6e4f5C2f5984a519F20);\n return _circuitChainlink;\n }\n}\n" + }, + "contracts/oracle/implementations/optimism/EUR/OracleUSDCEURChainlinkOptimism.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\nimport \"@chainlink/contracts/src/v0.8/interfaces/AggregatorV3Interface.sol\";\n\nimport \"../../../BaseOracleChainlinkMultiTwoFeeds.sol\";\n\n/// @title OracleUSDCEURChainlinkOptimism\n/// @author Angle Labs, Inc.\n/// @notice Gives the price of USDC in Euro in base 18\n/// @dev This contract is built to be deployed on Optimism\ncontract OracleUSDCEURChainlinkOptimism is BaseOracleChainlinkMultiTwoFeeds {\n string public constant DESCRIPTION = \"USDC/EUR Oracle\";\n\n constructor(uint32 _stalePeriod, address _treasury) BaseOracleChainlinkMultiTwoFeeds(_stalePeriod, _treasury) {}\n\n /// @inheritdoc IOracle\n function circuitChainlink() public pure override returns (AggregatorV3Interface[] memory) {\n AggregatorV3Interface[] memory _circuitChainlink = new AggregatorV3Interface[](2);\n // Oracle USDC/USD\n _circuitChainlink[0] = AggregatorV3Interface(0x16a9FA2FDa030272Ce99B29CF780dFA30361E0f3);\n // Oracle EUR/USD\n _circuitChainlink[1] = AggregatorV3Interface(0x3626369857A10CcC6cc3A6e4f5C2f5984a519F20);\n return _circuitChainlink;\n }\n}\n" + }, + "contracts/oracle/implementations/polygon/EUR/OracleBTCEURChainlinkPolygon.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\nimport \"@chainlink/contracts/src/v0.8/interfaces/AggregatorV3Interface.sol\";\n\nimport \"../../../BaseOracleChainlinkMultiTwoFeeds.sol\";\n\n/// @title OracleBTCEURChainlinkPolygon\n/// @author Angle Labs, Inc.\n/// @notice Gives the price of BTC in Euro in base 18\n/// @dev This contract is built to be deployed on Polygon\ncontract OracleBTCEURChainlinkPolygon is BaseOracleChainlinkMultiTwoFeeds {\n string public constant DESCRIPTION = \"BTC/EUR Oracle\";\n\n constructor(uint32 _stalePeriod, address _treasury) BaseOracleChainlinkMultiTwoFeeds(_stalePeriod, _treasury) {}\n\n /// @inheritdoc IOracle\n function circuitChainlink() public pure override returns (AggregatorV3Interface[] memory) {\n AggregatorV3Interface[] memory _circuitChainlink = new AggregatorV3Interface[](2);\n // Oracle BTC/USD\n _circuitChainlink[0] = AggregatorV3Interface(0xc907E116054Ad103354f2D350FD2514433D57F6f);\n // Oracle EUR/USD\n _circuitChainlink[1] = AggregatorV3Interface(0x73366Fe0AA0Ded304479862808e02506FE556a98);\n return _circuitChainlink;\n }\n}\n" + }, + "contracts/oracle/implementations/polygon/EUR/OracleETHEURChainlinkPolygon.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\nimport \"@chainlink/contracts/src/v0.8/interfaces/AggregatorV3Interface.sol\";\n\nimport \"../../../BaseOracleChainlinkMultiTwoFeeds.sol\";\n\n/// @title OracleETHEURChainlinkPolygon\n/// @author Angle Labs, Inc.\n/// @notice Gives the price of ETH in Euro in base 18\n/// @dev This contract is built to be deployed on Polygon\ncontract OracleETHEURChainlinkPolygon is BaseOracleChainlinkMultiTwoFeeds {\n string public constant DESCRIPTION = \"ETH/EUR Oracle\";\n\n constructor(uint32 _stalePeriod, address _treasury) BaseOracleChainlinkMultiTwoFeeds(_stalePeriod, _treasury) {}\n\n /// @inheritdoc IOracle\n function circuitChainlink() public pure override returns (AggregatorV3Interface[] memory) {\n AggregatorV3Interface[] memory _circuitChainlink = new AggregatorV3Interface[](2);\n // Oracle ETH/USD\n _circuitChainlink[0] = AggregatorV3Interface(0xF9680D99D6C9589e2a93a78A04A279e509205945);\n // Oracle EUR/USD\n _circuitChainlink[1] = AggregatorV3Interface(0x73366Fe0AA0Ded304479862808e02506FE556a98);\n return _circuitChainlink;\n }\n}\n" + }, + "contracts/oracle/implementations/polygon/EUR/OracleMAIEURChainlinkPolygon.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\nimport \"@chainlink/contracts/src/v0.8/interfaces/AggregatorV3Interface.sol\";\n\nimport \"../../../BaseOracleChainlinkMultiTwoFeeds.sol\";\n\n/// @title OracleMAIEURChainlinkPolygon\n/// @author Angle Labs, Inc.\n/// @notice Gives the price of MAI in Euro in base 18\n/// @dev This contract is built to be deployed on Polygon\ncontract OracleMAIEURChainlinkPolygon is BaseOracleChainlinkMultiTwoFeeds {\n string public constant DESCRIPTION = \"MAI/EUR Oracle\";\n\n constructor(uint32 _stalePeriod, address _treasury) BaseOracleChainlinkMultiTwoFeeds(_stalePeriod, _treasury) {}\n\n /// @inheritdoc IOracle\n function circuitChainlink() public pure override returns (AggregatorV3Interface[] memory) {\n AggregatorV3Interface[] memory _circuitChainlink = new AggregatorV3Interface[](2);\n // Oracle MAI/USD\n _circuitChainlink[0] = AggregatorV3Interface(0xd8d483d813547CfB624b8Dc33a00F2fcbCd2D428);\n // Oracle EUR/USD\n _circuitChainlink[1] = AggregatorV3Interface(0x73366Fe0AA0Ded304479862808e02506FE556a98);\n return _circuitChainlink;\n }\n}\n" + }, + "contracts/oracle/implementations/polygon/EUR/OracleMATICEURChainlinkPolygon.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\nimport \"@chainlink/contracts/src/v0.8/interfaces/AggregatorV3Interface.sol\";\n\nimport \"../../../BaseOracleChainlinkMultiTwoFeeds.sol\";\n\n/// @title OracleMATICEURChainlinkPolygon\n/// @author Angle Labs, Inc.\n/// @notice Gives the price of MATIC in Euro in base 18\n/// @dev This contract is built to be deployed on Polygon\ncontract OracleMATICEURChainlinkPolygon is BaseOracleChainlinkMultiTwoFeeds {\n string public constant DESCRIPTION = \"MATIC/EUR Oracle\";\n\n constructor(uint32 _stalePeriod, address _treasury) BaseOracleChainlinkMultiTwoFeeds(_stalePeriod, _treasury) {}\n\n /// @inheritdoc IOracle\n function circuitChainlink() public pure override returns (AggregatorV3Interface[] memory) {\n AggregatorV3Interface[] memory _circuitChainlink = new AggregatorV3Interface[](2);\n // Oracle MATIC/USD\n _circuitChainlink[0] = AggregatorV3Interface(0xAB594600376Ec9fD91F8e885dADF0CE036862dE0);\n // Oracle EUR/USD\n _circuitChainlink[1] = AggregatorV3Interface(0x73366Fe0AA0Ded304479862808e02506FE556a98);\n return _circuitChainlink;\n }\n}\n" + }, + "contracts/oracle/implementations/polygon/EUR/OracleUSDCEURChainlinkPolygon.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\nimport \"../../../BaseOracleChainlinkMultiTwoFeeds.sol\";\n\n/// @title OracleUSDCEURChainlinkPolygon\n/// @author Angle Labs, Inc.\n/// @notice Gives the price of USDC in Euro in base 18\n/// @dev This contract is built to be deployed on Polygon\ncontract OracleUSDCEURChainlinkPolygon is BaseOracleChainlinkMultiTwoFeeds {\n string public constant DESCRIPTION = \"USDC/EUR Oracle\";\n\n constructor(uint32 _stalePeriod, address _treasury) BaseOracleChainlinkMultiTwoFeeds(_stalePeriod, _treasury) {}\n\n /// @inheritdoc IOracle\n function circuitChainlink() public pure override returns (AggregatorV3Interface[] memory) {\n AggregatorV3Interface[] memory _circuitChainlink = new AggregatorV3Interface[](2);\n // Oracle USDC/USD\n _circuitChainlink[0] = AggregatorV3Interface(0xfE4A8cc5b5B2366C1B58Bea3858e81843581b2F7);\n // Oracle EUR/USD\n _circuitChainlink[1] = AggregatorV3Interface(0x73366Fe0AA0Ded304479862808e02506FE556a98);\n return _circuitChainlink;\n }\n}\n" + }, + "contracts/oracle/implementations/polygon/XAU/OracleETHXAUChainlinkPolygon.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\nimport \"@chainlink/contracts/src/v0.8/interfaces/AggregatorV3Interface.sol\";\n\nimport \"../../../BaseOracleChainlinkMultiTwoFeeds.sol\";\n\n/// @title OracleETHXAUChainlinkPolygon\n/// @author Angle Labs, Inc.\n/// @notice Gives the price of ETH in XAU in base 18\n/// @dev This contract is built to be deployed on Polygon\ncontract OracleETHXAUChainlinkPolygon is BaseOracleChainlinkMultiTwoFeeds {\n string public constant DESCRIPTION = \"ETH/GOLD Oracle\";\n\n constructor(uint32 _stalePeriod, address _treasury) BaseOracleChainlinkMultiTwoFeeds(_stalePeriod, _treasury) {}\n\n /// @inheritdoc IOracle\n function circuitChainlink() public pure override returns (AggregatorV3Interface[] memory) {\n AggregatorV3Interface[] memory _circuitChainlink = new AggregatorV3Interface[](2);\n // Oracle ETH/USD\n _circuitChainlink[0] = AggregatorV3Interface(0xF9680D99D6C9589e2a93a78A04A279e509205945);\n // Oracle XAU/USD\n _circuitChainlink[1] = AggregatorV3Interface(0x0C466540B2ee1a31b441671eac0ca886e051E410);\n return _circuitChainlink;\n }\n}\n" + }, + "contracts/oracle/KeeperRegistry.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\nimport \"@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol\";\nimport \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\nimport \"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\";\n\nimport \"../interfaces/ICoreBorrow.sol\";\nimport \"../interfaces/IKeeperRegistry.sol\";\n\n/// @title KeeperRegistry\n/// @notice Maintains a mapping of keepers authorized to use the core module just after oracle updates\n/// @author Angle Labs, Inc.\ncontract KeeperRegistry is Initializable, IKeeperRegistry {\n using SafeERC20 for IERC20;\n\n /// @notice Contract handling access control\n ICoreBorrow public coreBorrow;\n\n /// @notice Trusted EOAs - needs to be tx.origin\n mapping(address => uint256) public trusted;\n\n uint256[48] private __gap;\n\n // =================================== EVENTS ==================================\n\n event TrustedToggled(address indexed wallet, bool trust);\n\n // =================================== ERRORS ==================================\n\n error NotGovernorOrGuardian();\n error NotTrusted();\n error ZeroAddress();\n\n // ================================= MODIFIERS =================================\n\n /// @notice Checks whether the `msg.sender` has the governor role or the guardian role\n modifier onlyGovernorOrGuardian() {\n if (!coreBorrow.isGovernorOrGuardian(msg.sender)) revert NotGovernorOrGuardian();\n _;\n }\n\n // ================================ CONSTRUCTOR ================================\n\n constructor() initializer {}\n\n function initialize(ICoreBorrow _coreBorrow) public initializer {\n if (address(_coreBorrow) == address(0)) revert ZeroAddress();\n coreBorrow = _coreBorrow;\n }\n\n // =============================== MAIN FUNCTIONS ==============================\n\n /// @notice Adds or removes a trusted keeper bot\n function toggleTrusted(address eoa) external onlyGovernorOrGuardian {\n uint256 trustedStatus = 1 - trusted[eoa];\n trusted[eoa] = trustedStatus;\n emit TrustedToggled(eoa, trustedStatus == 1);\n }\n\n /// @inheritdoc IKeeperRegistry\n function isTrusted(address caller) external view returns (bool) {\n return trusted[caller] == 1;\n }\n}\n" + }, + "contracts/oracle/OracleChainlinkMulti.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\nimport \"@chainlink/contracts/src/v0.8/interfaces/AggregatorV3Interface.sol\";\n\nimport \"./BaseOracleChainlinkMulti.sol\";\n\n/// @title OracleChainlinkMulti\n/// @author Angle Labs, Inc.\n/// @notice Oracle contract, one contract is deployed per collateral/stablecoin pair\n/// @dev This contract concerns an oracle that uses Chainlink with multiple pools to read from\n/// @dev Typically we expect to use this contract to read like the ETH/USD and then USD/EUR feed\ncontract OracleChainlinkMulti is BaseOracleChainlinkMulti {\n // ========================= Parameters and References =========================\n\n /// @notice Chainlink pools, the order of the pools has to be the order in which they are read for the computation\n /// of the price\n AggregatorV3Interface[] internal _circuitChainlink;\n /// @notice Whether each rate for the pairs in `circuitChainlink` should be multiplied or divided\n uint8[] public circuitChainIsMultiplied;\n /// @notice Decimals for each Chainlink pairs\n uint8[] public chainlinkDecimals;\n /// @notice Unit of the stablecoin\n uint256 public immutable outBase;\n /// @notice Description of the assets concerned by the oracle and the price outputted\n string public description;\n\n // ===================================== Error =================================\n\n error IncompatibleLengths();\n\n /// @notice Constructor for an oracle using Chainlink with multiple pools to read from\n /// @param circuitChainlink_ Chainlink pool addresses (in order)\n /// @param _circuitChainIsMultiplied Whether we should multiply or divide by this rate\n /// @param _outBase Unit of the stablecoin (or the out asset) associated to the oracle\n /// @param _stalePeriod Minimum feed update frequency for the oracle to not revert\n /// @param _treasury Treasury associated to the VaultManager which reads from this feed\n /// @param _description Description of the assets concerned by the oracle\n /// @dev For instance, if this oracle is supposed to give the price of ETH in EUR, and if the agEUR\n /// stablecoin associated to EUR has 18 decimals, then `outBase` should be 10**18\n constructor(\n address[] memory circuitChainlink_,\n uint8[] memory _circuitChainIsMultiplied,\n uint256 _outBase,\n uint32 _stalePeriod,\n address _treasury,\n string memory _description\n ) BaseOracleChainlinkMulti(_stalePeriod, _treasury) {\n outBase = _outBase;\n description = _description;\n uint256 circuitLength = circuitChainlink_.length;\n if (circuitLength == 0 || circuitLength != _circuitChainIsMultiplied.length) revert IncompatibleLengths();\n for (uint256 i; i < circuitLength; ++i) {\n AggregatorV3Interface _pool = AggregatorV3Interface(circuitChainlink_[i]);\n _circuitChainlink.push(_pool);\n chainlinkDecimals.push(_pool.decimals());\n }\n circuitChainIsMultiplied = _circuitChainIsMultiplied;\n }\n\n // ============================= Reading Oracles ===============================\n\n /// @inheritdoc IOracle\n function circuitChainlink() public view override returns (AggregatorV3Interface[] memory) {\n return _circuitChainlink;\n }\n\n /// @inheritdoc IOracle\n function read() external view override returns (uint256 quoteAmount) {\n quoteAmount = outBase;\n uint256 circuitLength = _circuitChainlink.length;\n for (uint256 i; i < circuitLength; ++i) {\n quoteAmount = _readChainlinkFeed(\n quoteAmount,\n _circuitChainlink[i],\n circuitChainIsMultiplied[i],\n chainlinkDecimals[i]\n );\n }\n }\n}\n" + }, + "contracts/settlement/Settlement.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\nimport \"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\";\nimport \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\nimport \"@openzeppelin/contracts/token/ERC20/extensions/IERC20Metadata.sol\";\n\nimport \"../interfaces/IAgToken.sol\";\nimport \"../interfaces/ISwapper.sol\";\nimport \"../interfaces/IVaultManager.sol\";\n\n/// @title Settlement\n/// @author Angle Labs, Inc.\n/// @notice Settlement Contract for a VaultManager\n/// @dev This settlement contract should be activated by a careful governance which needs to have performed\n/// some key operations before activating this contract\n/// @dev In case of global settlement, there should be one settlement contract per `VaultManager`\ncontract Settlement {\n using SafeERC20 for IERC20;\n\n /// @notice Base used for parameter computation\n uint256 public constant BASE_PARAMS = 10 ** 9;\n /// @notice Base used for interest computation\n uint256 public constant BASE_INTEREST = 10 ** 27;\n /// @notice Base used for exchange rate computation. It is assumed\n /// that stablecoins have this base\n uint256 public constant BASE_STABLECOIN = 10 ** 18;\n /// @notice Duration of the claim period for over-collateralized vaults\n uint256 public constant OVER_COLLATERALIZED_CLAIM_DURATION = 3 * 24 * 3600;\n\n // =============== Immutable references set in the constructor =================\n\n /// @notice `VaultManager` of this settlement contract\n IVaultManager public immutable vaultManager;\n /// @notice Reference to the stablecoin supported by the `VaultManager` contract\n IAgToken public immutable stablecoin;\n /// @notice Reference to the collateral supported by the `VaultManager`\n IERC20 public immutable collateral;\n /// @notice Base of the collateral\n uint256 internal immutable _collatBase;\n\n // ================ Variables frozen at settlement activation ==================\n\n /// @notice Value of the oracle for the collateral/stablecoin pair\n uint256 public oracleValue;\n /// @notice Value of the interest accumulator at settlement activation\n uint256 public interestAccumulator;\n /// @notice Timestamp at which settlement was activated\n uint256 public activationTimestamp;\n /// @notice Collateral factor of the `VaultManager`\n uint64 public collateralFactor;\n\n // =================== Variables updated during the process ====================\n\n /// @notice How much collateral you can get from stablecoins\n uint256 public collateralStablecoinExchangeRate;\n /// @notice Amount of collateral that will be left over at the end of the process\n uint256 public leftOverCollateral;\n /// @notice Whether the `collateralStablecoinExchangeRate` has been computed\n bool public exchangeRateComputed;\n /// @notice Maps a vault to 1 if it was claimed by its owner\n mapping(uint256 => uint256) public vaultCheck;\n\n // ================================ Events =====================================\n\n event GlobalClaimPeriodActivated(uint256 _collateralStablecoinExchangeRate);\n event Recovered(address indexed tokenAddress, address indexed to, uint256 amount);\n event SettlementActivated(uint256 startTimestamp);\n event VaultClaimed(uint256 vaultID, uint256 stablecoinAmount, uint256 collateralAmount);\n\n // ================================ Errors =====================================\n\n error GlobalClaimPeriodNotStarted();\n error InsolventVault();\n error NotGovernor();\n error NotOwner();\n error RestrictedClaimPeriodNotEnded();\n error SettlementNotInitialized();\n error VaultAlreadyClaimed();\n\n /// @notice Constructor of the contract\n /// @param _vaultManager Address of the `VaultManager` associated to this `Settlement` contract\n /// @dev Out of safety, this constructor reads values from the `VaultManager` contract directly\n constructor(IVaultManager _vaultManager) {\n vaultManager = _vaultManager;\n stablecoin = _vaultManager.stablecoin();\n collateral = _vaultManager.collateral();\n _collatBase = 10 ** (IERC20Metadata(address(collateral)).decimals());\n }\n\n /// @notice Checks whether the `msg.sender` has the governor role or not\n modifier onlyGovernor() {\n if (!(vaultManager.treasury().isGovernor(msg.sender))) revert NotGovernor();\n _;\n }\n\n /// @notice Activates the settlement contract\n /// @dev When calling this function governance should make sure to have:\n /// 1. Accrued the interest rate on the contract\n /// 2. Paused the contract\n /// 3. Recovered all the collateral available in the `VaultManager` contract either\n /// by doing a contract upgrade or by calling a `recoverERC20` method if supported\n function activateSettlement() external onlyGovernor {\n oracleValue = (vaultManager.oracle()).read();\n interestAccumulator = vaultManager.interestAccumulator();\n activationTimestamp = block.timestamp;\n collateralFactor = vaultManager.collateralFactor();\n emit SettlementActivated(block.timestamp);\n }\n\n /// @notice Allows the owner of an over-collateralized vault to claim its collateral upon bringing back all owed stablecoins\n /// @param vaultID ID of the vault to claim\n /// @param to Address to which collateral should be sent\n /// @param who Address which should be notified if needed of the transfer of stablecoins and collateral\n /// @param data Data to pass to the `who` contract for it to successfully give the correct amount of stablecoins\n /// to the `msg.sender` address\n /// @return Amount of collateral sent to the `to` address\n /// @return Amount of stablecoins sent to the contract\n /// @dev Claiming can only happen short after settlement activation\n /// @dev A vault cannot be claimed twice and only the owner of the vault can claim it (regardless of the approval logic)\n /// @dev Only over-collateralized vaults can be claimed from this medium\n function claimOverCollateralizedVault(\n uint256 vaultID,\n address to,\n address who,\n bytes memory data\n ) external returns (uint256, uint256) {\n if (activationTimestamp == 0 || block.timestamp > activationTimestamp + OVER_COLLATERALIZED_CLAIM_DURATION)\n revert SettlementNotInitialized();\n if (vaultCheck[vaultID] == 1) revert VaultAlreadyClaimed();\n if (vaultManager.ownerOf(vaultID) != msg.sender) revert NotOwner();\n (uint256 collateralAmount, uint256 normalizedDebt) = vaultManager.vaultData(vaultID);\n uint256 vaultDebt = (normalizedDebt * interestAccumulator) / BASE_INTEREST;\n if (collateralAmount * oracleValue * collateralFactor < vaultDebt * BASE_PARAMS * _collatBase)\n revert InsolventVault();\n vaultCheck[vaultID] = 1;\n emit VaultClaimed(vaultID, vaultDebt, collateralAmount);\n return _handleRepay(collateralAmount, vaultDebt, to, who, data);\n }\n\n /// @notice Activates the global claim period by setting the `collateralStablecoinExchangeRate` which is going to\n /// dictate how much of collateral will be recoverable for each stablecoin\n /// @dev This function can only be called by the governor in order to allow it in case multiple settlements happen across\n /// different `VaultManager` to rebalance the amount of stablecoins on each to make sure that across all settlement contracts\n /// a similar value of collateral can be obtained against a similar value of stablecoins\n function activateGlobalClaimPeriod() external onlyGovernor {\n if (activationTimestamp == 0 || block.timestamp <= activationTimestamp + OVER_COLLATERALIZED_CLAIM_DURATION)\n revert RestrictedClaimPeriodNotEnded();\n uint256 collateralBalance = collateral.balanceOf(address(this));\n uint256 leftOverDebt = (vaultManager.totalNormalizedDebt() * interestAccumulator) / BASE_INTEREST;\n uint256 stablecoinBalance = stablecoin.balanceOf(address(this));\n // How much 1 of stablecoin will give you in collateral\n uint256 _collateralStablecoinExchangeRate;\n\n if (stablecoinBalance < leftOverDebt) {\n // The left over debt is the total debt minus the stablecoins which have already been accumulated\n // in the first phase\n leftOverDebt -= stablecoinBalance;\n // If you control all the debt, then you are entitled to get all the collateral left in the protocol\n _collateralStablecoinExchangeRate = (collateralBalance * BASE_STABLECOIN) / leftOverDebt;\n // But at the same time, you cannot get more collateral than the value of the stablecoins you brought\n uint256 maxExchangeRate = (BASE_STABLECOIN * _collatBase) / oracleValue;\n if (_collateralStablecoinExchangeRate >= maxExchangeRate) {\n // In this situation, we're sure that `leftOverCollateral` will be positive: governance should be wary\n // to call `recoverERC20` short after though as there's nothing that is going to prevent people to redeem\n // more stablecoins than the `leftOverDebt`\n leftOverCollateral = collateralBalance - (leftOverDebt * _collatBase) / oracleValue;\n _collateralStablecoinExchangeRate = maxExchangeRate;\n }\n }\n exchangeRateComputed = true;\n // In the else case where there is no debt left, you cannot get anything from your stablecoins\n // and so the `collateralStablecoinExchangeRate` is null\n collateralStablecoinExchangeRate = _collateralStablecoinExchangeRate;\n emit GlobalClaimPeriodActivated(_collateralStablecoinExchangeRate);\n }\n\n /// @notice Allows to claim collateral from stablecoins\n /// @param to Address to which collateral should be sent\n /// @param who Address which should be notified if needed of the transfer of stablecoins and collateral\n /// @param data Data to pass to the `who` contract for it to successfully give the correct amount of stablecoins\n /// to the `msg.sender` address\n /// @return Amount of collateral sent to the `to` address\n /// @return Amount of stablecoins sent to the contract\n /// @dev This function reverts if the `collateralStablecoinExchangeRate` is null and hence if the global claim period has\n /// not been activated\n function claimCollateralFromStablecoins(\n uint256 stablecoinAmount,\n address to,\n address who,\n bytes memory data\n ) external returns (uint256, uint256) {\n if (!exchangeRateComputed) revert GlobalClaimPeriodNotStarted();\n return\n _handleRepay(\n (stablecoinAmount * collateralStablecoinExchangeRate) / BASE_STABLECOIN,\n stablecoinAmount,\n to,\n who,\n data\n );\n }\n\n /// @notice Handles the simultaneous repayment of stablecoins with a transfer of collateral\n /// @param collateralAmountToGive Amount of collateral the contract should give\n /// @param stableAmountToRepay Amount of stablecoins the contract should burn from the call\n /// @param to Address to which stablecoins should be sent\n /// @param who Address which should be notified if needed of the transfer\n /// @param data Data to pass to the `who` contract for it to successfully give the correct amount of stablecoins\n /// to the `msg.sender` address\n /// @dev This function allows for capital-efficient claims of collateral from stablecoins\n function _handleRepay(\n uint256 collateralAmountToGive,\n uint256 stableAmountToRepay,\n address to,\n address who,\n bytes memory data\n ) internal returns (uint256, uint256) {\n collateral.safeTransfer(to, collateralAmountToGive);\n if (data.length != 0) {\n ISwapper(who).swap(\n collateral,\n IERC20(address(stablecoin)),\n msg.sender,\n stableAmountToRepay,\n collateralAmountToGive,\n data\n );\n }\n stablecoin.transferFrom(msg.sender, address(this), stableAmountToRepay);\n return (collateralAmountToGive, stableAmountToRepay);\n }\n\n /// @notice Recovers leftover tokens from the contract or tokens that were mistakenly sent to the contract\n /// @param tokenAddress Address of the token to recover\n /// @param to Address to send the remaining tokens to\n /// @param amountToRecover Amount to recover from the contract\n /// @dev Governors cannot recover more collateral than what would be leftover from the contract\n /// @dev This function can be used to rebalance stablecoin balances across different settlement contracts\n /// to make sure every stablecoin can be redeemed for the same value of collateral\n /// @dev It can also be used to recover tokens that are mistakenly sent to this contract\n function recoverERC20(address tokenAddress, address to, uint256 amountToRecover) external onlyGovernor {\n if (tokenAddress == address(collateral)) {\n if (!exchangeRateComputed) revert GlobalClaimPeriodNotStarted();\n leftOverCollateral -= amountToRecover;\n collateral.safeTransfer(to, amountToRecover);\n } else {\n IERC20(tokenAddress).safeTransfer(to, amountToRecover);\n }\n emit Recovered(tokenAddress, to, amountToRecover);\n }\n}\n" + }, + "contracts/swapper/Swapper.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\n/*\n * █ \n ***** ▓▓▓ \n * ▓▓▓▓▓▓▓ \n * ///. ▓▓▓▓▓▓▓▓▓▓▓▓▓ \n ***** //////// ▓▓▓▓▓▓▓ \n * ///////////// ▓▓▓ \n ▓▓ ////////////////// █ ▓▓ \n ▓▓ ▓▓ /////////////////////// ▓▓ ▓▓ \n ▓▓ ▓▓ //////////////////////////// ▓▓ ▓▓ \n ▓▓ ▓▓ /////////▓▓▓///////▓▓▓///////// ▓▓ ▓▓ \n ▓▓ ,////////////////////////////////////// ▓▓ ▓▓ \n ▓▓ ////////////////////////////////////////// ▓▓ \n ▓▓ //////////////////////▓▓▓▓///////////////////// \n ,//////////////////////////////////////////////////// \n .////////////////////////////////////////////////////////// \n .//////////////////////////██.,//////////////////////////█ \n .//////////////////////████..,./////////////////////██ \n ...////////////////███████.....,.////////////////███ \n ,.,////////////████████ ........,///////////████ \n .,.,//////█████████ ,.......///////████ \n ,..//████████ ........./████ \n ..,██████ .....,███ \n .██ ,.,█ \n \n \n \n ▓▓ ▓▓▓▓▓▓▓▓▓▓ ▓▓▓▓▓▓▓▓▓▓ ▓▓ ▓▓▓▓▓▓▓▓▓▓ \n ▓▓▓▓▓▓ ▓▓▓ ▓▓▓ ▓▓▓ ▓▓ ▓▓ ▓▓▓▓ \n ▓▓▓ ▓▓▓ ▓▓▓ ▓▓▓ ▓▓▓ ▓▓▓ ▓▓ ▓▓▓▓▓ \n ▓▓▓ ▓▓ ▓▓▓ ▓▓▓ ▓▓▓▓▓▓▓▓▓▓ ▓▓▓▓▓▓▓▓▓▓ ▓▓▓▓▓▓▓▓▓▓ \n*/\n\npragma solidity ^0.8.12;\n\nimport \"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\";\nimport \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\n\nimport \"../interfaces/IAngleRouterSidechain.sol\";\nimport \"../interfaces/ICoreBorrow.sol\";\nimport \"../interfaces/ISwapper.sol\";\nimport \"../interfaces/external/lido/IWStETH.sol\";\nimport \"../interfaces/external/uniswap/IUniswapRouter.sol\";\n\n// ==================================== ENUM ===================================\n\n/// @notice All possible swaps\nenum SwapType {\n UniswapV3,\n oneInch,\n AngleRouter,\n Leverage,\n None\n}\n\n/// @title Swapper\n/// @author Angle Labs, Inc.\n/// @notice Swapper contract facilitating interactions with Angle VaultManager contracts, notably\n/// liquidation and leverage transactions\ncontract Swapper is ISwapper {\n using SafeERC20 for IERC20;\n\n // ===================== CONSTANTS AND IMMUTABLE VARIABLES =====================\n\n /// @notice Reference to the `CoreBorrow` contract of the module which handles all AccessControl logic\n ICoreBorrow public immutable core;\n /// @notice Uniswap Router contract\n IUniswapV3Router public immutable uniV3Router;\n /// @notice 1inch Router\n address public immutable oneInch;\n /// @notice AngleRouter\n IAngleRouterSidechain public immutable angleRouter;\n\n // =================================== ERRORS ==================================\n\n error EmptyReturnMessage();\n error IncompatibleLengths();\n error NotGovernorOrGuardian();\n error TooSmallAmountOut();\n error ZeroAddress();\n\n /// @notice Constructor of the contract\n /// @param _core Core address\n /// @param _uniV3Router UniswapV3 Router address\n /// @param _oneInch 1inch Router address\n /// @param _angleRouter AngleRouter contract address\n constructor(\n ICoreBorrow _core,\n IUniswapV3Router _uniV3Router,\n address _oneInch,\n IAngleRouterSidechain _angleRouter\n ) {\n if (address(_core) == address(0) || _oneInch == address(0) || address(_angleRouter) == address(0))\n revert ZeroAddress();\n core = _core;\n uniV3Router = _uniV3Router;\n oneInch = _oneInch;\n angleRouter = _angleRouter;\n }\n\n // ========================= EXTERNAL ACCESS FUNCTIONS =========================\n\n /// @inheritdoc ISwapper\n /// @dev This function swaps the `inToken` to the `outToken` by doing a UniV3 swap, a 1inch swap or by interacting\n /// with the `AngleRouter` contract\n /// @dev One slippage check is performed at the end of the call\n /// @dev In this implementation, the function tries to make sure that the `outTokenRecipient` address has at the end\n /// of the call `outTokenOwed`, leftover tokens are sent to a `to` address which by default is the `outTokenRecipient`\n function swap(\n IERC20 inToken,\n IERC20 outToken,\n address outTokenRecipient,\n uint256 outTokenOwed,\n uint256 inTokenObtained,\n bytes memory data\n ) external {\n // Address to receive the surplus amount of token at the end of the call\n address to;\n // For slippage protection, it is checked at the end of the call\n uint256 minAmountOut;\n // Type of the swap to execute: if `swapType == 4`, then it is optional to swap\n uint256 swapType;\n // We're reusing the `data` variable (it can be `path` on UniswapV3, a payload for 1inch or like encoded actions\n // for a router call)\n (to, minAmountOut, swapType, data) = abi.decode(data, (address, uint256, uint256, bytes));\n\n to = (to == address(0)) ? outTokenRecipient : to;\n\n _swap(inToken, inTokenObtained, SwapType(swapType), data);\n\n // A final slippage check is performed after the swaps\n uint256 outTokenBalance = outToken.balanceOf(address(this));\n if (outTokenBalance < minAmountOut) revert TooSmallAmountOut();\n\n // The `outTokenRecipient` may already have enough in balance, in which case there's no need to transfer\n // to this address the token and everything can be given to the `to` address\n uint256 outTokenBalanceRecipient = outToken.balanceOf(outTokenRecipient);\n if (outTokenBalanceRecipient >= outTokenOwed || to == outTokenRecipient)\n outToken.safeTransfer(to, outTokenBalance);\n else {\n // The `outTokenRecipient` should receive the delta to make sure its end balance is equal to `outTokenOwed`\n // Any leftover in this case is sent to the `to` address\n // The function reverts if it did not obtain more than `outTokenOwed - outTokenBalanceRecipient` from the swap\n outToken.safeTransfer(outTokenRecipient, outTokenOwed - outTokenBalanceRecipient);\n outToken.safeTransfer(to, outTokenBalanceRecipient + outTokenBalance - outTokenOwed);\n }\n // Reusing the `inTokenObtained` variable for the `inToken` balance\n // Sending back the remaining amount of inTokens to the `to` address: it is possible that not the full `inTokenObtained`\n // is swapped to `outToken` if we're using the `1inch` payload\n inTokenObtained = inToken.balanceOf(address(this));\n if (inTokenObtained != 0) inToken.safeTransfer(to, inTokenObtained);\n }\n\n // ============================ GOVERNANCE FUNCTION ============================\n\n /// @notice Changes allowances of this contract for different tokens\n /// @param tokens Addresses of the tokens to allow\n /// @param spenders Addresses to allow transfer\n /// @param amounts Amounts to allow\n function changeAllowance(\n IERC20[] calldata tokens,\n address[] calldata spenders,\n uint256[] calldata amounts\n ) external {\n if (!core.isGovernorOrGuardian(msg.sender)) revert NotGovernorOrGuardian();\n uint256 tokensLength = tokens.length;\n if (tokensLength != spenders.length || tokensLength != amounts.length) revert IncompatibleLengths();\n for (uint256 i; i < tokensLength; ++i) {\n _changeAllowance(tokens[i], spenders[i], amounts[i]);\n }\n }\n\n // ========================= INTERNAL UTILITY FUNCTIONS ========================\n\n /// @notice Internal version of the `_changeAllowance` function\n function _changeAllowance(IERC20 token, address spender, uint256 amount) internal {\n uint256 currentAllowance = token.allowance(address(this), spender);\n // In case `currentAllowance < type(uint256).max / 2` and we want to increase it:\n // Do nothing (to handle tokens that need reapprovals to 0 and save gas)\n if (currentAllowance < amount && currentAllowance < type(uint256).max / 2) {\n token.safeIncreaseAllowance(spender, amount - currentAllowance);\n } else if (currentAllowance > amount) {\n token.safeDecreaseAllowance(spender, currentAllowance - amount);\n }\n }\n\n /// @notice Checks the allowance for a contract and updates it to the max if it is not big enough\n /// @param token Token for which allowance should be checked\n /// @param spender Address to grant allowance to\n /// @param amount Minimum amount of tokens needed for the allowance\n function _checkAllowance(IERC20 token, address spender, uint256 amount) internal {\n uint256 currentAllowance = token.allowance(address(this), spender);\n if (currentAllowance < amount) token.safeIncreaseAllowance(spender, type(uint256).max - currentAllowance);\n }\n\n /// @notice Performs a swap using either Uniswap, 1inch. This function can also stake stETH to wstETH\n /// @param inToken Token to swap\n /// @param amount Amount of tokens to swap\n /// @param swapType Type of the swap to perform\n /// @param args Extra args for the swap: in the case of Uniswap it should be a path, for 1inch it should be\n /// a payload\n /// @dev This function does nothing if `swapType` is None and it simply passes on the `amount` it received\n /// @dev No slippage is specified in the actions given here as a final slippage check is performed\n /// after the call to this function\n function _swap(IERC20 inToken, uint256 amount, SwapType swapType, bytes memory args) internal {\n if (swapType == SwapType.UniswapV3) _swapOnUniswapV3(inToken, amount, args);\n else if (swapType == SwapType.oneInch) _swapOn1inch(inToken, args);\n else if (swapType == SwapType.AngleRouter) _angleRouterActions(inToken, args);\n else if (swapType == SwapType.Leverage) _swapLeverage(args);\n }\n\n /// @notice Performs a UniswapV3 swap\n /// @param inToken Token to swap\n /// @param amount Amount of tokens to swap\n /// @param path Path for the UniswapV3 swap: this encodes the out token that is going to be obtained\n /// @dev This function does not check the out token obtained here: if it is wrongly specified, either\n /// the `swap` function could fail or these tokens could stay on the contract\n function _swapOnUniswapV3(IERC20 inToken, uint256 amount, bytes memory path) internal returns (uint256 amountOut) {\n // We need more than `amount` of allowance to the contract\n _checkAllowance(inToken, address(uniV3Router), amount);\n amountOut = uniV3Router.exactInput(ExactInputParams(path, address(this), block.timestamp, amount, 0));\n }\n\n /// @notice Allows to swap any token to an accepted collateral via 1inch API\n /// @param inToken Token received for the 1inch swap\n /// @param payload Bytes needed for 1inch API\n function _swapOn1inch(IERC20 inToken, bytes memory payload) internal returns (uint256 amountOut) {\n _changeAllowance(inToken, oneInch, type(uint256).max);\n //solhint-disable-next-line\n (bool success, bytes memory result) = oneInch.call(payload);\n if (!success) _revertBytes(result);\n amountOut = abi.decode(result, (uint256));\n }\n\n /// @notice Performs actions with the router contract of the protocol on the corresponding chain\n /// @param inToken Token concerned by the action and for which\n function _angleRouterActions(IERC20 inToken, bytes memory args) internal {\n (ActionType[] memory actions, bytes[] memory actionData) = abi.decode(args, (ActionType[], bytes[]));\n _changeAllowance(inToken, address(angleRouter), type(uint256).max);\n PermitType[] memory permits;\n angleRouter.mixer(permits, actions, actionData);\n }\n\n /// @notice Allows to take leverage or deleverage via a specific contract\n /// @param payload Bytes needed for 1inch API\n /// @dev This function is to be implemented if the swapper concerns a token that requires some actions\n /// not supported by 1inch or UniV3\n function _swapLeverage(bytes memory payload) internal virtual returns (uint256 amountOut) {}\n\n /// @notice Internal function used for error handling\n /// @param errMsg Error message received\n function _revertBytes(bytes memory errMsg) internal pure {\n if (errMsg.length != 0) {\n //solhint-disable-next-line\n assembly {\n revert(add(32, errMsg), mload(errMsg))\n }\n }\n revert EmptyReturnMessage();\n }\n}\n" + }, + "contracts/treasury/Treasury.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\n/*\n * █ \n ***** ▓▓▓ \n * ▓▓▓▓▓▓▓ \n * ///. ▓▓▓▓▓▓▓▓▓▓▓▓▓ \n ***** //////// ▓▓▓▓▓▓▓ \n * ///////////// ▓▓▓ \n ▓▓ ////////////////// █ ▓▓ \n ▓▓ ▓▓ /////////////////////// ▓▓ ▓▓ \n ▓▓ ▓▓ //////////////////////////// ▓▓ ▓▓ \n ▓▓ ▓▓ /////////▓▓▓///////▓▓▓///////// ▓▓ ▓▓ \n ▓▓ ,////////////////////////////////////// ▓▓ ▓▓ \n ▓▓ ////////////////////////////////////////// ▓▓ \n ▓▓ //////////////////////▓▓▓▓///////////////////// \n ,//////////////////////////////////////////////////// \n .////////////////////////////////////////////////////////// \n .//////////////////////////██.,//////////////////////////█ \n .//////////////////////████..,./////////////////////██ \n ...////////////////███████.....,.////////////////███ \n ,.,////////////████████ ........,///////////████ \n .,.,//////█████████ ,.......///////████ \n ,..//████████ ........./████ \n ..,██████ .....,███ \n .██ ,.,█ \n \n \n \n ▓▓ ▓▓▓▓▓▓▓▓▓▓ ▓▓▓▓▓▓▓▓▓▓ ▓▓ ▓▓▓▓▓▓▓▓▓▓ \n ▓▓▓▓▓▓ ▓▓▓ ▓▓▓ ▓▓▓ ▓▓ ▓▓ ▓▓▓▓ \n ▓▓▓ ▓▓▓ ▓▓▓ ▓▓▓ ▓▓▓ ▓▓▓ ▓▓ ▓▓▓▓▓ \n ▓▓▓ ▓▓ ▓▓▓ ▓▓▓ ▓▓▓▓▓▓▓▓▓▓ ▓▓▓▓▓▓▓▓▓▓ ▓▓▓▓▓▓▓▓▓▓ \n*/\n\npragma solidity ^0.8.12;\n\nimport \"@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol\";\nimport \"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\";\nimport \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\n\nimport \"../interfaces/IAgToken.sol\";\nimport \"../interfaces/ICoreBorrow.sol\";\nimport \"../interfaces/IFlashAngle.sol\";\nimport \"../interfaces/ITreasury.sol\";\nimport \"../interfaces/IVaultManager.sol\";\n\n/// @title Treasury\n/// @author Angle Labs, Inc.\n/// @notice Treasury of Angle Borrowing Module doing the accounting across all VaultManagers for\n/// a given stablecoin\ncontract Treasury is ITreasury, Initializable {\n using SafeERC20 for IERC20;\n\n /// @notice Base used for parameter computation\n uint256 public constant BASE_9 = 1e9;\n\n // ================================= REFERENCES ================================\n\n /// @notice Reference to the `CoreBorrow` contract of the module which handles all AccessControl logic\n ICoreBorrow public core;\n /// @notice Flash Loan Module with a minter right on the stablecoin\n IFlashAngle public flashLoanModule;\n /// @inheritdoc ITreasury\n IAgToken public stablecoin;\n /// @notice Address responsible for handling the surplus made by the treasury\n address public surplusManager;\n /// @notice List of the accepted `VaultManager` of the protocol\n address[] public vaultManagerList;\n /// @notice Maps an address to 1 if it was initialized as a `VaultManager` contract\n mapping(address => uint256) public vaultManagerMap;\n\n // ================================= VARIABLES =================================\n\n /// @notice Amount of bad debt (unbacked stablecoin) accumulated across all `VaultManager` contracts\n /// linked to this stablecoin\n uint256 public badDebt;\n /// @notice Surplus amount accumulated by the contract waiting to be distributed to governance. Technically\n /// only a share of this `surplusBuffer` will go to governance. Once a share of the surplus buffer has been\n /// given to governance, then this surplus is reset\n uint256 public surplusBuffer;\n\n // ================================= PARAMETER =================================\n\n /// @notice Share of the `surplusBuffer` distributed to governance (in `BASE_9`)\n uint64 public surplusForGovernance;\n\n // =================================== EVENTS ==================================\n\n event BadDebtUpdated(uint256 badDebtValue);\n event CoreUpdated(address indexed _core);\n event NewTreasurySet(address indexed _treasury);\n event Recovered(address indexed token, address indexed to, uint256 amount);\n event SurplusBufferUpdated(uint256 surplusBufferValue);\n event SurplusForGovernanceUpdated(uint64 _surplusForGovernance);\n event SurplusManagerUpdated(address indexed _surplusManager);\n event VaultManagerToggled(address indexed vaultManager);\n\n // =================================== ERRORS ==================================\n\n error AlreadyVaultManager();\n error InvalidAddress();\n error InvalidTreasury();\n error NotCore();\n error NotGovernor();\n error NotVaultManager();\n error RightsNotRemoved();\n error TooBigAmount();\n error TooHighParameterValue();\n error ZeroAddress();\n\n // ================================== MODIFIER =================================\n\n /// @notice Checks whether the `msg.sender` has the governor role or not\n modifier onlyGovernor() {\n if (!core.isGovernor(msg.sender)) revert NotGovernor();\n _;\n }\n\n /// @notice Initializes the treasury contract\n /// @param _core Address of the `CoreBorrow` contract of the module\n /// @param _stablecoin Address of the stablecoin\n function initialize(ICoreBorrow _core, IAgToken _stablecoin) public virtual initializer {\n if (address(_stablecoin) == address(0) || address(_core) == address(0)) revert ZeroAddress();\n core = _core;\n stablecoin = _stablecoin;\n }\n\n /// @custom:oz-upgrades-unsafe-allow constructor\n constructor() initializer {}\n\n // =============================== VIEW FUNCTIONS ==============================\n\n /// @inheritdoc ITreasury\n function isGovernor(address admin) external view returns (bool) {\n return core.isGovernor(admin);\n }\n\n /// @inheritdoc ITreasury\n function isGovernorOrGuardian(address admin) external view returns (bool) {\n return core.isGovernorOrGuardian(admin);\n }\n\n /// @inheritdoc ITreasury\n function isVaultManager(address _vaultManager) external view returns (bool) {\n return vaultManagerMap[_vaultManager] == 1;\n }\n\n // ===================== EXTERNAL PERMISSIONLESS FUNCTIONS =====================\n\n /// @notice Fetches the surplus accrued across all the `VaultManager` contracts controlled by this\n /// `Treasury` contract as well as from the fees of the `FlashLoan` module\n /// @return Surplus buffer value at the end of the call\n /// @return Bad debt value at the end of the call\n /// @dev This function pools surplus and bad debt across all contracts and then updates the `surplusBuffer`\n /// (or the `badDebt` if more losses were made than profits)\n function fetchSurplusFromAll() external returns (uint256, uint256) {\n return _fetchSurplusFromAll();\n }\n\n /// @notice Fetches the surplus accrued in the flash loan module and updates the `surplusBuffer`\n /// @return Surplus buffer value at the end of the call\n /// @return Bad debt value at the end of the call\n /// @dev This function fails if the `flashLoanModule` has not been initialized yet\n function fetchSurplusFromFlashLoan() external returns (uint256, uint256) {\n uint256 surplusBufferValue = surplusBuffer + flashLoanModule.accrueInterestToTreasury(stablecoin);\n return _updateSurplusAndBadDebt(surplusBufferValue, badDebt);\n }\n\n /// @notice Pushes the surplus buffer to the `surplusManager` contract\n /// @return governanceAllocation Amount transferred to governance\n /// @dev It makes sure to fetch the surplus from all the contracts handled by this treasury to avoid\n /// the situation where rewards are still distributed to governance even though a `VaultManager` has made\n /// a big loss\n /// @dev Typically this function is to be called once every week by a keeper to distribute rewards to veANGLE\n /// holders\n /// @dev `stablecoin` must be an AgToken and hence `transfer` reverts if the call is not successful\n function pushSurplus() external returns (uint256 governanceAllocation) {\n address _surplusManager = surplusManager;\n if (_surplusManager == address(0)) {\n revert ZeroAddress();\n }\n (uint256 surplusBufferValue, ) = _fetchSurplusFromAll();\n surplusBuffer = 0;\n emit SurplusBufferUpdated(0);\n governanceAllocation = (surplusForGovernance * surplusBufferValue) / BASE_9;\n stablecoin.transfer(_surplusManager, governanceAllocation);\n }\n\n /// @notice Updates the bad debt of the protocol in case where the protocol has accumulated some revenue\n /// from an external source\n /// @param amount Amount to reduce the bad debt of\n /// @return badDebtValue Value of the bad debt at the end of the call\n /// @dev If the protocol has made a loss and managed to make some profits to recover for this loss (through\n /// a program like Olympus Pro), then this function needs to be called\n /// @dev `badDebt` is simply reduced here by burning stablecoins\n /// @dev It is impossible to burn more than the `badDebt` otherwise this function could be used to manipulate\n /// the `surplusBuffer` and hence the amount going to governance\n function updateBadDebt(uint256 amount) external returns (uint256 badDebtValue) {\n stablecoin.burnSelf(amount, address(this));\n badDebtValue = badDebt - amount;\n badDebt = badDebtValue;\n emit BadDebtUpdated(badDebtValue);\n }\n\n // ========================= INTERNAL UTILITY FUNCTIONS ========================\n\n /// @notice Internal version of the `fetchSurplusFromAll` function\n function _fetchSurplusFromAll() internal returns (uint256 surplusBufferValue, uint256 badDebtValue) {\n (surplusBufferValue, badDebtValue) = _fetchSurplusFromList(vaultManagerList);\n // It will fail anyway if the `flashLoanModule` is the zero address\n if (address(flashLoanModule) != address(0))\n surplusBufferValue += flashLoanModule.accrueInterestToTreasury(stablecoin);\n (surplusBufferValue, badDebtValue) = _updateSurplusAndBadDebt(surplusBufferValue, badDebtValue);\n }\n\n /// @notice Fetches the surplus from a list of `VaultManager` addresses without modifying the\n /// `surplusBuffer` and `badDebtValue`\n /// @return surplusBufferValue Value the `surplusBuffer` should have after the call if it was updated\n /// @return badDebtValue Value the `badDebt` should have after the call if it was updated\n /// @dev This internal function is never to be called alone, and should always be called in conjunction\n /// with the `_updateSurplusAndBadDebt` function\n function _fetchSurplusFromList(\n address[] memory vaultManagers\n ) internal returns (uint256 surplusBufferValue, uint256 badDebtValue) {\n badDebtValue = badDebt;\n surplusBufferValue = surplusBuffer;\n uint256 newSurplus;\n uint256 newBadDebt;\n uint256 vaultManagersLength = vaultManagers.length;\n for (uint256 i; i < vaultManagersLength; ++i) {\n (newSurplus, newBadDebt) = IVaultManager(vaultManagers[i]).accrueInterestToTreasury();\n surplusBufferValue += newSurplus;\n badDebtValue += newBadDebt;\n }\n }\n\n /// @notice Updates the `surplusBuffer` and the `badDebt` from updated values after calling the flash loan module\n /// and/or a list of `VaultManager` contracts\n /// @param surplusBufferValue Value of the surplus buffer after the calls to the different modules\n /// @param badDebtValue Value of the bad debt after the calls to the different modules\n /// @return Value of the `surplusBuffer` corrected from the `badDebt`\n /// @return Value of the `badDebt` corrected from the `surplusBuffer` and from the surplus the treasury had accumulated\n /// previously\n /// @dev When calling this function, it is possible that there is a positive `surplusBufferValue` and `badDebtValue`,\n /// this function tries to reconcile both values and makes sure that we either have surplus or bad debt but not both\n /// at the same time\n function _updateSurplusAndBadDebt(\n uint256 surplusBufferValue,\n uint256 badDebtValue\n ) internal returns (uint256, uint256) {\n if (badDebtValue != 0) {\n // If we have bad debt we need to burn stablecoins that accrued to the protocol\n // We still need to make sure that we're not burning too much or as much as we can if the debt is big\n uint256 balance = stablecoin.balanceOf(address(this));\n // We are going to burn `min(balance, badDebtValue)`\n uint256 toBurn = balance <= badDebtValue ? balance : badDebtValue;\n stablecoin.burnSelf(toBurn, address(this));\n // If we burned more than `surplusBuffer`, we set surplus to 0. It means we had to tap into Treasury reserve\n surplusBufferValue = toBurn >= surplusBufferValue ? 0 : surplusBufferValue - toBurn;\n badDebtValue -= toBurn;\n // Note here that the stablecoin balance is necessarily greater than the surplus buffer, and so if\n // `surplusBuffer >= toBurn`, then `badDebtValue = toBurn`\n }\n surplusBuffer = surplusBufferValue;\n badDebt = badDebtValue;\n emit SurplusBufferUpdated(surplusBufferValue);\n emit BadDebtUpdated(badDebtValue);\n return (surplusBufferValue, badDebtValue);\n }\n\n /// @notice Adds a new `VaultManager`\n /// @param vaultManager `VaultManager` contract to add\n /// @dev This contract should have already been initialized with a correct treasury address\n /// @dev It's this function that gives the minter right to the `VaultManager`\n function _addVaultManager(address vaultManager) internal virtual {\n if (vaultManagerMap[vaultManager] == 1) revert AlreadyVaultManager();\n if (address(IVaultManager(vaultManager).treasury()) != address(this)) revert InvalidTreasury();\n vaultManagerMap[vaultManager] = 1;\n vaultManagerList.push(vaultManager);\n emit VaultManagerToggled(vaultManager);\n stablecoin.addMinter(vaultManager);\n }\n\n // ============================= GOVERNOR FUNCTIONS ============================\n\n /// @notice Adds a new minter for the stablecoin\n /// @param minter Minter address to add\n function addMinter(address minter) external virtual onlyGovernor {\n if (minter == address(0)) revert ZeroAddress();\n stablecoin.addMinter(minter);\n }\n\n /// @notice External wrapper for `_addVaultManager`\n function addVaultManager(address vaultManager) external virtual onlyGovernor {\n _addVaultManager(vaultManager);\n }\n\n /// @notice Removes a minter from the stablecoin contract\n /// @param minter Minter address to remove\n function removeMinter(address minter) external virtual onlyGovernor {\n // To remove the minter role to a `VaultManager` you have to go through the `removeVaultManager` function\n if (vaultManagerMap[minter] == 1) revert InvalidAddress();\n stablecoin.removeMinter(minter);\n }\n\n /// @notice Removes a `VaultManager`\n /// @param vaultManager `VaultManager` contract to remove\n /// @dev A removed `VaultManager` loses its minter right on the stablecoin\n function removeVaultManager(address vaultManager) external onlyGovernor {\n if (vaultManagerMap[vaultManager] != 1) revert NotVaultManager();\n delete vaultManagerMap[vaultManager];\n // deletion from `vaultManagerList` loop\n uint256 vaultManagerListLength = vaultManagerList.length;\n for (uint256 i; i < vaultManagerListLength - 1; ++i) {\n if (vaultManagerList[i] == vaultManager) {\n // replace the `VaultManager` to remove with the last of the list\n vaultManagerList[i] = vaultManagerList[vaultManagerListLength - 1];\n break;\n }\n }\n // remove last element in array\n vaultManagerList.pop();\n emit VaultManagerToggled(vaultManager);\n stablecoin.removeMinter(vaultManager);\n }\n\n /// @notice Allows to recover any ERC20 token, including the stablecoin handled by this contract, and to send it\n /// to a contract\n /// @param tokenAddress Address of the token to recover\n /// @param to Address of the contract to send collateral to\n /// @param amountToRecover Amount of collateral to transfer\n /// @dev It is impossible to recover the stablecoin of the protocol if there is some bad debt for it\n /// @dev In this case, the function makes sure to fetch the surplus/bad debt from all the `VaultManager` contracts\n /// and from the flash loan module\n /// @dev If the token to recover is the stablecoin, tokens recovered are fetched\n /// from the surplus and not from the `surplusBuffer`\n function recoverERC20(address tokenAddress, address to, uint256 amountToRecover) external onlyGovernor {\n // Cannot recover stablecoin if badDebt or tap into the surplus buffer\n if (tokenAddress == address(stablecoin)) {\n _fetchSurplusFromAll();\n // If balance is non zero then this means, after the call to `fetchSurplusFromAll` that\n // bad debt is necessarily null\n uint256 balance = stablecoin.balanceOf(address(this));\n if (amountToRecover + surplusBuffer > balance) revert TooBigAmount();\n stablecoin.transfer(to, amountToRecover);\n } else {\n IERC20(tokenAddress).safeTransfer(to, amountToRecover);\n }\n emit Recovered(tokenAddress, to, amountToRecover);\n }\n\n /// @notice Changes the treasury contract and communicates this change to all `VaultManager` contract\n /// @param _treasury New treasury address for this stablecoin\n /// @dev This function is basically a way to remove rights to this contract and grant them to a new one\n /// @dev It could be used to set a new core contract\n function setTreasury(address _treasury) external virtual onlyGovernor {\n if (ITreasury(_treasury).stablecoin() != stablecoin) revert InvalidTreasury();\n // Flash loan role should be removed before calling this function\n if (core.isFlashLoanerTreasury(address(this))) revert RightsNotRemoved();\n emit NewTreasurySet(_treasury);\n uint256 vaultManagerListLength = vaultManagerList.length;\n for (uint256 i; i < vaultManagerListLength; ++i) {\n IVaultManager(vaultManagerList[i]).setTreasury(_treasury);\n }\n // A `TreasuryUpdated` event is triggered in the stablecoin\n stablecoin.setTreasury(_treasury);\n }\n\n /// @notice Sets the `surplusForGovernance` parameter\n /// @param _surplusForGovernance New value of the parameter\n /// @dev To pause surplus distribution, governance needs to set a zero value for `surplusForGovernance`\n /// which means\n function setSurplusForGovernance(uint64 _surplusForGovernance) external onlyGovernor {\n if (_surplusForGovernance > BASE_9) revert TooHighParameterValue();\n surplusForGovernance = _surplusForGovernance;\n emit SurplusForGovernanceUpdated(_surplusForGovernance);\n }\n\n /// @notice Sets the `surplusManager` contract responsible for handling the surplus of the\n /// protocol\n /// @param _surplusManager New address responsible for handling the surplus\n function setSurplusManager(address _surplusManager) external onlyGovernor {\n if (_surplusManager == address(0)) revert ZeroAddress();\n surplusManager = _surplusManager;\n emit SurplusManagerUpdated(_surplusManager);\n }\n\n /// @notice Sets a new `core` contract\n /// @dev This function should typically be called on all treasury contracts after the `setCore`\n /// function has been called on the `CoreBorrow` contract\n /// @dev One sanity check that can be performed here is to verify whether at least the governor\n /// calling the contract is still a governor in the new core\n function setCore(ICoreBorrow _core) external onlyGovernor {\n if (!_core.isGovernor(msg.sender)) revert NotGovernor();\n core = ICoreBorrow(_core);\n emit CoreUpdated(address(_core));\n }\n\n /// @inheritdoc ITreasury\n function setFlashLoanModule(address _flashLoanModule) external {\n if (msg.sender != address(core)) revert NotCore();\n address oldFlashLoanModule = address(flashLoanModule);\n flashLoanModule = IFlashAngle(_flashLoanModule);\n if (oldFlashLoanModule != address(0)) {\n stablecoin.removeMinter(oldFlashLoanModule);\n }\n // We may want to cancel the module\n if (_flashLoanModule != address(0)) {\n stablecoin.addMinter(_flashLoanModule);\n }\n }\n}\n" + }, + "contracts/ui-helpers/AngleBorrowHelpers.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\n/*\n * █ \n ***** ▓▓▓ \n * ▓▓▓▓▓▓▓ \n * ///. ▓▓▓▓▓▓▓▓▓▓▓▓▓ \n ***** //////// ▓▓▓▓▓▓▓ \n * ///////////// ▓▓▓ \n ▓▓ ////////////////// █ ▓▓ \n ▓▓ ▓▓ /////////////////////// ▓▓ ▓▓ \n ▓▓ ▓▓ //////////////////////////// ▓▓ ▓▓ \n ▓▓ ▓▓ /////////▓▓▓///////▓▓▓///////// ▓▓ ▓▓ \n ▓▓ ,////////////////////////////////////// ▓▓ ▓▓ \n ▓▓ ////////////////////////////////////////// ▓▓ \n ▓▓ //////////////////////▓▓▓▓///////////////////// \n ,//////////////////////////////////////////////////// \n .////////////////////////////////////////////////////////// \n .//////////////////////////██.,//////////////////////////█ \n .//////////////////////████..,./////////////////////██ \n ...////////////////███████.....,.////////////////███ \n ,.,////////////████████ ........,///////////████ \n .,.,//////█████████ ,.......///////████ \n ,..//████████ ........./████ \n ..,██████ .....,███ \n .██ ,.,█ \n \n \n \n ▓▓ ▓▓▓▓▓▓▓▓▓▓ ▓▓▓▓▓▓▓▓▓▓ ▓▓ ▓▓▓▓▓▓▓▓▓▓ \n ▓▓▓▓▓▓ ▓▓▓ ▓▓▓ ▓▓▓ ▓▓ ▓▓ ▓▓▓▓ \n ▓▓▓ ▓▓▓ ▓▓▓ ▓▓▓ ▓▓▓ ▓▓▓ ▓▓ ▓▓▓▓▓ \n ▓▓▓ ▓▓ ▓▓▓ ▓▓▓ ▓▓▓▓▓▓▓▓▓▓ ▓▓▓▓▓▓▓▓▓▓ ▓▓▓▓▓▓▓▓▓▓ \n*/\n\nimport \"@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol\";\nimport \"../interfaces/IVaultManager.sol\";\n\npragma solidity ^0.8.12;\n\n/// @title AngleBorrowHelpers\n/// @author Angle Labs, Inc.\n/// @notice Contract with view functions designed to facilitate integrations on the Borrow module of the Angle Protocol\n/// @dev This contract only contains view functions to be queried off-chain. It was thus not optimized for gas consumption\ncontract AngleBorrowHelpers is Initializable {\n /// @notice Returns all the vaults owned or controlled (under the form of approval) by an address\n /// @param vaultManager VaultManager address to query vaultIDs on\n /// @param spender Address for which vault ownerships should be checked\n /// @return List of `vaultID` controlled by this address\n /// @return Count of vaults owned by the address\n /// @dev This function is never to be called on-chain since it iterates over all vaultIDs. It is here\n /// to reduce dependency on an external graph to link an ID to its owner\n function getControlledVaults(\n IVaultManager vaultManager,\n address spender\n ) external view returns (uint256[] memory, uint256) {\n uint256 arraySize = vaultManager.vaultIDCount();\n uint256[] memory vaultsControlled = new uint256[](arraySize);\n uint256 count;\n for (uint256 i = 1; i <= arraySize; ++i) {\n try vaultManager.isApprovedOrOwner(spender, i) returns (bool _isApprovedOrOwner) {\n if (_isApprovedOrOwner) {\n vaultsControlled[count] = i;\n count += 1;\n }\n } catch {\n continue;\n } // This happens if nobody owns the vaultID=i (if there has been a burn)\n }\n return (vaultsControlled, count);\n }\n\n /// @custom:oz-upgrades-unsafe-allow constructor\n constructor() initializer {}\n}\n" + }, + "contracts/ui-helpers/AngleHelpers.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\nimport \"../interfaces/IAngleRouter.sol\";\nimport \"../interfaces/coreModule/IAgTokenMainnet.sol\";\nimport \"../interfaces/coreModule/ICore.sol\";\nimport \"../interfaces/coreModule/IOracleCore.sol\";\nimport \"../interfaces/coreModule/IPerpetualManager.sol\";\nimport \"../interfaces/coreModule/IPoolManager.sol\";\nimport \"../interfaces/coreModule/IStableMaster.sol\";\nimport \"./AngleBorrowHelpers.sol\";\n\npragma solidity ^0.8.12;\n\nstruct Parameters {\n SLPData slpData;\n MintBurnData feeData;\n PerpetualManagerFeeData perpFeeData;\n PerpetualManagerParamData perpParam;\n}\n\nstruct PerpetualManagerFeeData {\n uint64[] xHAFeesDeposit;\n uint64[] yHAFeesDeposit;\n uint64[] xHAFeesWithdraw;\n uint64[] yHAFeesWithdraw;\n uint64 haBonusMalusDeposit;\n uint64 haBonusMalusWithdraw;\n}\n\nstruct PerpetualManagerParamData {\n uint64 maintenanceMargin;\n uint64 maxLeverage;\n uint64 targetHAHedge;\n uint64 limitHAHedge;\n uint64 lockTime;\n}\n\nstruct CollateralAddresses {\n address stableMaster;\n address poolManager;\n address perpetualManager;\n address sanToken;\n address oracle;\n address gauge;\n address feeManager;\n address[] strategies;\n}\n\n/// @title AngleHelpers\n/// @author Angle Labs, Inc.\n/// @notice Contract with view functions designed to facilitate integrations on the Core and Borrow module of the Angle Protocol\n/// @dev This contract only contains view functions to be queried off-chain. It was thus not optimized for gas consumption\ncontract AngleHelpers is AngleBorrowHelpers {\n // =========================== HELPER VIEW FUNCTIONS ===========================\n\n /// @notice Gives the amount of `agToken` you'd be getting if you were executing in the same block a mint transaction\n /// with `amount` of `collateral` in the Core module of the Angle protocol as well as the value of the fees\n /// (in `BASE_PARAMS`) that would be applied during the mint\n /// @return Amount of `agToken` that would be obtained with a mint transaction in the same block\n /// @return Percentage of fees that would be taken during a mint transaction in the same block\n /// @dev This function reverts if the mint transaction was to revert in the same conditions (without taking into account\n /// potential approval problems to the `StableMaster` contract)\n function previewMintAndFees(\n uint256 amount,\n address agToken,\n address collateral\n ) external view returns (uint256, uint256) {\n return _previewMintAndFees(amount, agToken, collateral);\n }\n\n /// @notice Gives the amount of `collateral` you'd be getting if you were executing in the same block a burn transaction\n /// with `amount` of `agToken` in the Core module of the Angle protocol as well as the value of the fees\n /// (in `BASE_PARAMS`) that would be applied during the burn\n /// @return Amount of `collateral` that would be obtained with a burn transaction in the same block\n /// @return Percentage of fees that would be taken during a burn transaction in the same block\n /// @dev This function reverts if the burn transaction was to revert in the same conditions (without taking into account\n /// potential approval problems to the `StableMaster` contract or agToken balance prior to the call)\n function previewBurnAndFees(\n uint256 amount,\n address agToken,\n address collateral\n ) external view returns (uint256, uint256) {\n return _previewBurnAndFees(amount, agToken, collateral);\n }\n\n /// @notice Returns all the addresses associated to the (`agToken`,`collateral`) pair given\n /// @return addresses A struct with all the addresses associated in the Core module\n function getCollateralAddresses(\n address agToken,\n address collateral\n ) external view returns (CollateralAddresses memory addresses) {\n address stableMaster = IAgTokenMainnet(agToken).stableMaster();\n (address poolManager, address perpetualManager, address sanToken, address gauge) = ROUTER.mapPoolManagers(\n stableMaster,\n collateral\n );\n (, , , IOracleCore oracle, , , , , ) = IStableMaster(stableMaster).collateralMap(poolManager);\n addresses.stableMaster = stableMaster;\n addresses.poolManager = poolManager;\n addresses.perpetualManager = perpetualManager;\n addresses.sanToken = sanToken;\n addresses.gauge = gauge;\n addresses.oracle = address(oracle);\n addresses.feeManager = IPoolManager(poolManager).feeManager();\n\n uint256 length;\n while (true) {\n try IPoolManager(poolManager).strategyList(length) returns (address) {\n length += 1;\n } catch {\n break;\n }\n }\n address[] memory strategies = new address[](length);\n for (uint256 i; i < length; ++i) {\n strategies[i] = IPoolManager(poolManager).strategyList(i);\n }\n addresses.strategies = strategies;\n }\n\n /// @notice Gets the addresses of all the `StableMaster` contracts and their associated `AgToken` addresses\n /// @return List of the `StableMaster` addresses of the Angle protocol\n /// @return List of the `AgToken` addresses of the protocol\n /// @dev The place of an agToken address in the list is the same as the corresponding `StableMaster` address\n function getStablecoinAddresses() external view returns (address[] memory, address[] memory) {\n address[] memory stableMasterAddresses = CORE.stablecoinList();\n address[] memory agTokenAddresses = new address[](stableMasterAddresses.length);\n for (uint256 i; i < stableMasterAddresses.length; ++i) {\n agTokenAddresses[i] = IStableMaster(stableMasterAddresses[i]).agToken();\n }\n return (stableMasterAddresses, agTokenAddresses);\n }\n\n /// @notice Returns most of the governance parameters associated to the (`agToken`,`collateral`) pair given\n /// @return params Struct with most of the parameters in the `StableMaster` and `PerpetualManager` contracts\n /// @dev Check out the struct `Parameters` for the meaning of the return values\n function getCollateralParameters(\n address agToken,\n address collateral\n ) external view returns (Parameters memory params) {\n (address stableMaster, address poolManager) = _getStableMasterAndPoolManager(agToken, collateral);\n (\n ,\n ,\n IPerpetualManager perpetualManager,\n ,\n ,\n ,\n ,\n SLPData memory slpData,\n MintBurnData memory feeData\n ) = IStableMaster(stableMaster).collateralMap(poolManager);\n\n params.slpData = slpData;\n params.feeData = feeData;\n params.perpParam.maintenanceMargin = perpetualManager.maintenanceMargin();\n params.perpParam.maxLeverage = perpetualManager.maxLeverage();\n params.perpParam.targetHAHedge = perpetualManager.targetHAHedge();\n params.perpParam.limitHAHedge = perpetualManager.limitHAHedge();\n params.perpParam.lockTime = perpetualManager.lockTime();\n\n params.perpFeeData.haBonusMalusDeposit = perpetualManager.haBonusMalusDeposit();\n params.perpFeeData.haBonusMalusWithdraw = perpetualManager.haBonusMalusWithdraw();\n\n uint256 length;\n while (true) {\n try perpetualManager.xHAFeesDeposit(length) returns (uint64) {\n length += 1;\n } catch {\n break;\n }\n }\n uint64[] memory data = new uint64[](length);\n uint64[] memory data2 = new uint64[](length);\n for (uint256 i; i < length; ++i) {\n data[i] = perpetualManager.xHAFeesDeposit(i);\n data2[i] = perpetualManager.yHAFeesDeposit(i);\n }\n params.perpFeeData.xHAFeesDeposit = data;\n params.perpFeeData.yHAFeesDeposit = data2;\n\n length = 0;\n while (true) {\n try perpetualManager.xHAFeesWithdraw(length) returns (uint64) {\n length += 1;\n } catch {\n break;\n }\n }\n data = new uint64[](length);\n data2 = new uint64[](length);\n for (uint256 i; i < length; ++i) {\n data[i] = perpetualManager.xHAFeesWithdraw(i);\n data2[i] = perpetualManager.yHAFeesWithdraw(i);\n }\n params.perpFeeData.xHAFeesWithdraw = data;\n params.perpFeeData.yHAFeesWithdraw = data2;\n }\n\n /// @notice Returns the address of the poolManager associated to an (`agToken`, `collateral`) pair\n /// in the Core module of the protocol\n function getPoolManager(address agToken, address collateral) public view returns (address poolManager) {\n (, poolManager) = _getStableMasterAndPoolManager(agToken, collateral);\n }\n\n // ============================= REPLICA FUNCTIONS =============================\n // These replicate what is done in the other contracts of the protocol\n\n function _previewBurnAndFees(\n uint256 amount,\n address agToken,\n address collateral\n ) internal view returns (uint256 amountForUserInCollat, uint256 feePercent) {\n (address stableMaster, address poolManager) = _getStableMasterAndPoolManager(agToken, collateral);\n (\n address token,\n ,\n IPerpetualManager perpetualManager,\n IOracleCore oracle,\n uint256 stocksUsers,\n ,\n uint256 collatBase,\n ,\n MintBurnData memory feeData\n ) = IStableMaster(stableMaster).collateralMap(poolManager);\n if (token == address(0) || IStableMaster(stableMaster).paused(keccak256(abi.encodePacked(STABLE, poolManager))))\n revert NotInitialized();\n if (amount > stocksUsers) revert InvalidAmount();\n\n if (feeData.xFeeBurn.length == 1) {\n feePercent = feeData.yFeeBurn[0];\n } else {\n bytes memory data = abi.encode(address(perpetualManager), feeData.targetHAHedge);\n uint64 hedgeRatio = _computeHedgeRatio(stocksUsers - amount, data);\n feePercent = _piecewiseLinear(hedgeRatio, feeData.xFeeBurn, feeData.yFeeBurn);\n }\n feePercent = (feePercent * feeData.bonusMalusBurn) / BASE_PARAMS;\n\n amountForUserInCollat = (amount * (BASE_PARAMS - feePercent) * collatBase) / (oracle.readUpper() * BASE_PARAMS);\n }\n\n function _previewMintAndFees(\n uint256 amount,\n address agToken,\n address collateral\n ) internal view returns (uint256 amountForUserInStable, uint256 feePercent) {\n (address stableMaster, address poolManager) = _getStableMasterAndPoolManager(agToken, collateral);\n (\n address token,\n ,\n IPerpetualManager perpetualManager,\n IOracleCore oracle,\n uint256 stocksUsers,\n ,\n ,\n ,\n MintBurnData memory feeData\n ) = IStableMaster(stableMaster).collateralMap(poolManager);\n if (token == address(0) || IStableMaster(stableMaster).paused(keccak256(abi.encodePacked(STABLE, poolManager))))\n revert NotInitialized();\n\n amountForUserInStable = oracle.readQuoteLower(amount);\n\n if (feeData.xFeeMint.length == 1) feePercent = feeData.yFeeMint[0];\n else {\n bytes memory data = abi.encode(address(perpetualManager), feeData.targetHAHedge);\n uint64 hedgeRatio = _computeHedgeRatio(amountForUserInStable + stocksUsers, data);\n feePercent = _piecewiseLinear(hedgeRatio, feeData.xFeeMint, feeData.yFeeMint);\n }\n feePercent = (feePercent * feeData.bonusMalusMint) / BASE_PARAMS;\n\n amountForUserInStable = (amountForUserInStable * (BASE_PARAMS - feePercent)) / BASE_PARAMS;\n if (stocksUsers + amountForUserInStable > feeData.capOnStableMinted) revert InvalidAmount();\n }\n\n // ============================= UTILITY FUNCTIONS =============================\n // These utility functions are taken from other contracts of the protocol\n\n function _computeHedgeRatio(uint256 newStocksUsers, bytes memory data) internal view returns (uint64 ratio) {\n (address perpetualManager, uint64 targetHAHedge) = abi.decode(data, (address, uint64));\n uint256 totalHedgeAmount = IPerpetualManager(perpetualManager).totalHedgeAmount();\n newStocksUsers = (targetHAHedge * newStocksUsers) / BASE_PARAMS;\n if (newStocksUsers > totalHedgeAmount) ratio = uint64((totalHedgeAmount * BASE_PARAMS) / newStocksUsers);\n else ratio = uint64(BASE_PARAMS);\n }\n\n function _piecewiseLinear(uint64 x, uint64[] memory xArray, uint64[] memory yArray) internal pure returns (uint64) {\n if (x >= xArray[xArray.length - 1]) {\n return yArray[xArray.length - 1];\n } else if (x <= xArray[0]) {\n return yArray[0];\n } else {\n uint256 lower;\n uint256 upper = xArray.length - 1;\n uint256 mid;\n while (upper - lower > 1) {\n mid = lower + (upper - lower) / 2;\n if (xArray[mid] <= x) {\n lower = mid;\n } else {\n upper = mid;\n }\n }\n if (yArray[upper] > yArray[lower]) {\n return\n yArray[lower] +\n ((yArray[upper] - yArray[lower]) * (x - xArray[lower])) /\n (xArray[upper] - xArray[lower]);\n } else {\n return\n yArray[lower] -\n ((yArray[lower] - yArray[upper]) * (x - xArray[lower])) /\n (xArray[upper] - xArray[lower]);\n }\n }\n }\n\n function _getStableMasterAndPoolManager(\n address agToken,\n address collateral\n ) internal view returns (address stableMaster, address poolManager) {\n stableMaster = IAgTokenMainnet(agToken).stableMaster();\n (poolManager, , , ) = ROUTER.mapPoolManagers(stableMaster, collateral);\n }\n\n // ========================= CONSTANTS AND INITIALIZERS ========================\n\n IAngleRouter public constant ROUTER = IAngleRouter(0xBB755240596530be0c1DE5DFD77ec6398471561d);\n ICore public constant CORE = ICore(0x61ed74de9Ca5796cF2F8fD60D54160D47E30B7c3);\n\n bytes32 public constant STABLE = keccak256(\"STABLE\");\n uint256 public constant BASE_PARAMS = 10 ** 9;\n\n error NotInitialized();\n error InvalidAmount();\n}\n" + }, + "contracts/utils/Constants.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\nerror InsufficientAssets();\n\n/// @title Constants\n/// @author Angle Labs, Inc.\n/// @notice Constants and errors for Angle Protocol contracts\ncontract Constants {\n uint256 internal constant _BASE_9 = 1e9;\n uint256 internal constant _BASE_18 = 1e18;\n uint256 internal constant _BASE_27 = 1e27;\n uint256 internal constant _BASE_36 = 1e36;\n}\n" + }, + "contracts/vaultManager/VaultManagerERC721.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\nimport \"./VaultManagerStorage.sol\";\n\n/// @title VaultManagerERC721\n/// @author Angle Labs, Inc.\n/// @dev Base ERC721 Implementation of VaultManager\nabstract contract VaultManagerERC721 is IERC721MetadataUpgradeable, VaultManagerStorage {\n using SafeERC20 for IERC20;\n using Address for address;\n\n /// @inheritdoc IERC721MetadataUpgradeable\n string public name;\n /// @inheritdoc IERC721MetadataUpgradeable\n string public symbol;\n\n // ================================= MODIFIERS =================================\n\n /// @notice Checks if the person interacting with the vault with `vaultID` is approved\n /// @param caller Address of the person seeking to interact with the vault\n /// @param vaultID ID of the concerned vault\n modifier onlyApprovedOrOwner(address caller, uint256 vaultID) {\n if (!_isApprovedOrOwner(caller, vaultID)) revert NotApproved();\n _;\n }\n\n // ================================ ERC721 LOGIC ===============================\n\n /// @notice Checks whether a given address is approved for a vault or owns this vault\n /// @param spender Address for which vault ownership should be checked\n /// @param vaultID ID of the vault to check\n /// @return Whether the `spender` address owns or is approved for `vaultID`\n function isApprovedOrOwner(address spender, uint256 vaultID) external view returns (bool) {\n return _isApprovedOrOwner(spender, vaultID);\n }\n\n /// @inheritdoc IERC721MetadataUpgradeable\n function tokenURI(uint256 vaultID) external view returns (string memory) {\n if (!_exists(vaultID)) revert NonexistentVault();\n // There is no vault with `vaultID` equal to 0, so the following variable is\n // always greater than zero\n uint256 temp = vaultID;\n uint256 digits;\n while (temp != 0) {\n ++digits;\n temp /= 10;\n }\n bytes memory buffer = new bytes(digits);\n while (vaultID != 0) {\n digits -= 1;\n buffer[digits] = bytes1(uint8(48 + uint256(vaultID % 10)));\n vaultID /= 10;\n }\n return bytes(_baseURI).length != 0 ? string(abi.encodePacked(_baseURI, string(buffer))) : \"\";\n }\n\n /// @inheritdoc IERC721Upgradeable\n function balanceOf(address owner) external view returns (uint256) {\n if (owner == address(0)) revert ZeroAddress();\n return _balances[owner];\n }\n\n /// @inheritdoc IERC721Upgradeable\n function ownerOf(uint256 vaultID) external view returns (address) {\n return _ownerOf(vaultID);\n }\n\n /// @inheritdoc IERC721Upgradeable\n function approve(address to, uint256 vaultID) external {\n address owner = _ownerOf(vaultID);\n if (to == owner) revert ApprovalToOwner();\n if (msg.sender != owner && !isApprovedForAll(owner, msg.sender)) revert NotApproved();\n\n _approve(to, vaultID);\n }\n\n /// @inheritdoc IERC721Upgradeable\n function getApproved(uint256 vaultID) external view returns (address) {\n if (!_exists(vaultID)) revert NonexistentVault();\n return _getApproved(vaultID);\n }\n\n /// @inheritdoc IERC721Upgradeable\n function setApprovalForAll(address operator, bool approved) external {\n _setApprovalForAll(msg.sender, operator, approved);\n }\n\n /// @inheritdoc IERC721Upgradeable\n function isApprovedForAll(address owner, address operator) public view returns (bool) {\n return _operatorApprovals[owner][operator] == 1;\n }\n\n /// @inheritdoc IERC721Upgradeable\n function transferFrom(address from, address to, uint256 vaultID) external onlyApprovedOrOwner(msg.sender, vaultID) {\n _transfer(from, to, vaultID);\n }\n\n /// @inheritdoc IERC721Upgradeable\n function safeTransferFrom(address from, address to, uint256 vaultID) external {\n safeTransferFrom(from, to, vaultID, \"\");\n }\n\n /// @inheritdoc IERC721Upgradeable\n function safeTransferFrom(\n address from,\n address to,\n uint256 vaultID,\n bytes memory _data\n ) public onlyApprovedOrOwner(msg.sender, vaultID) {\n _safeTransfer(from, to, vaultID, _data);\n }\n\n // ================================ ERC165 LOGIC ===============================\n\n /// @inheritdoc IERC165Upgradeable\n function supportsInterface(bytes4 interfaceId) external pure returns (bool) {\n return\n interfaceId == type(IERC721MetadataUpgradeable).interfaceId ||\n interfaceId == type(IERC721Upgradeable).interfaceId ||\n interfaceId == type(IVaultManager).interfaceId ||\n interfaceId == type(IERC165Upgradeable).interfaceId;\n }\n\n // ================== INTERNAL FUNCTIONS FOR THE ERC721 LOGIC ==================\n\n /// @notice Internal version of the `ownerOf` function\n function _ownerOf(uint256 vaultID) internal view returns (address owner) {\n owner = _owners[vaultID];\n if (owner == address(0)) revert NonexistentVault();\n }\n\n /// @notice Internal version of the `getApproved` function\n function _getApproved(uint256 vaultID) internal view returns (address) {\n return _vaultApprovals[vaultID];\n }\n\n /// @notice Internal version of the `safeTransferFrom` function (with the data parameter)\n function _safeTransfer(address from, address to, uint256 vaultID, bytes memory _data) internal {\n _transfer(from, to, vaultID);\n if (!_checkOnERC721Received(from, to, vaultID, _data)) revert NonERC721Receiver();\n }\n\n /// @notice Checks whether a vault exists\n /// @param vaultID ID of the vault to check\n /// @return Whether `vaultID` has been created\n function _exists(uint256 vaultID) internal view returns (bool) {\n return _owners[vaultID] != address(0);\n }\n\n /// @notice Internal version of the `isApprovedOrOwner` function\n function _isApprovedOrOwner(address spender, uint256 vaultID) internal view returns (bool) {\n // The following checks if the vault exists\n address owner = _ownerOf(vaultID);\n return (spender == owner || _getApproved(vaultID) == spender || _operatorApprovals[owner][spender] == 1);\n }\n\n /// @notice Internal version of the `createVault` function\n /// Mints `vaultID` and transfers it to `to`\n /// @dev This method is equivalent to the `_safeMint` method used in OpenZeppelin ERC721 contract\n /// @dev Emits a {Transfer} event\n function _mint(address to) internal returns (uint256 vaultID) {\n if (to == address(0)) revert ZeroAddress();\n\n unchecked {\n vaultIDCount += 1;\n }\n\n vaultID = vaultIDCount;\n _beforeTokenTransfer(address(0), to, vaultID);\n\n unchecked {\n _balances[to] += 1;\n }\n\n _owners[vaultID] = to;\n emit Transfer(address(0), to, vaultID);\n if (!_checkOnERC721Received(address(0), to, vaultID, \"\")) revert NonERC721Receiver();\n }\n\n /// @notice Destroys `vaultID`\n /// @dev `vaultID` must exist\n /// @dev Emits a {Transfer} event\n function _burn(uint256 vaultID) internal {\n address owner = _ownerOf(vaultID);\n\n _beforeTokenTransfer(owner, address(0), vaultID);\n // Clear approvals\n _approve(address(0), vaultID);\n // The following line cannot underflow as the owner's balance is necessarily\n // greater than 1\n unchecked {\n _balances[owner] -= 1;\n }\n delete _owners[vaultID];\n delete vaultData[vaultID];\n\n emit Transfer(owner, address(0), vaultID);\n }\n\n /// @notice Transfers `vaultID` from `from` to `to` as opposed to {transferFrom},\n /// this imposes no restrictions on msg.sender\n /// @dev `to` cannot be the zero address and `perpetualID` must be owned by `from`\n /// @dev Emits a {Transfer} event\n function _transfer(address from, address to, uint256 vaultID) internal {\n if (_ownerOf(vaultID) != from) revert NotApproved();\n if (to == address(0)) revert ZeroAddress();\n\n _beforeTokenTransfer(from, to, vaultID);\n\n // Clear approvals from the previous owner\n _approve(address(0), vaultID);\n unchecked {\n _balances[from] -= 1;\n _balances[to] += 1;\n }\n _owners[vaultID] = to;\n\n emit Transfer(from, to, vaultID);\n }\n\n /// @notice Approves `to` to operate on `vaultID`\n function _approve(address to, uint256 vaultID) internal {\n _vaultApprovals[vaultID] = to;\n emit Approval(_ownerOf(vaultID), to, vaultID);\n }\n\n /// @notice Internal version of the `setApprovalForAll` function\n /// @dev It contains an `approver` field to be used in case someone signs a permit for a particular\n /// address, and this signature is given to the contract by another address (like a router)\n function _setApprovalForAll(address approver, address operator, bool approved) internal {\n if (operator == approver) revert ApprovalToCaller();\n uint256 approval = approved ? 1 : 0;\n _operatorApprovals[approver][operator] = approval;\n emit ApprovalForAll(approver, operator, approved);\n }\n\n /// @notice Internal function to invoke {IERC721Receiver-onERC721Received} on a target address\n /// The call is not executed if the target address is not a contract\n /// @param from Address representing the previous owner of the given token ID\n /// @param to Target address that will receive the tokens\n /// @param vaultID ID of the token to be transferred\n /// @param _data Bytes optional data to send along with the call\n /// @return Bool whether the call correctly returned the expected value\n function _checkOnERC721Received(\n address from,\n address to,\n uint256 vaultID,\n bytes memory _data\n ) private returns (bool) {\n if (to.isContract()) {\n try IERC721ReceiverUpgradeable(to).onERC721Received(msg.sender, from, vaultID, _data) returns (\n bytes4 retval\n ) {\n return retval == IERC721ReceiverUpgradeable.onERC721Received.selector;\n } catch (bytes memory reason) {\n if (reason.length == 0) {\n revert NonERC721Receiver();\n } else {\n // solhint-disable-next-line no-inline-assembly\n assembly {\n revert(add(32, reason), mload(reason))\n }\n }\n }\n } else {\n return true;\n }\n }\n\n /// @notice Hook that is called before any token transfer. This includes minting and burning.\n /// Calling conditions:\n ///\n /// - When `from` and `to` are both non-zero, `from`'s `vaultID` will be\n /// transferred to `to`.\n /// - When `from` is zero, `vaultID` will be minted for `to`.\n /// - When `to` is zero, `from`'s `vaultID` will be burned.\n /// - `from` and `to` are never both zero.\n function _beforeTokenTransfer(address from, address to, uint256 vaultID) internal virtual {}\n\n /// @notice Get `whitelistingActivated` in storage only if needed\n function _whitelistingActivated() internal view virtual returns (bool) {\n return whitelistingActivated;\n }\n}\n" + }, + "contracts/vaultManager/VaultManagerPermit.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\nimport \"./VaultManagerERC721.sol\";\nimport \"../interfaces/external/IERC1271.sol\";\n\n/// @title VaultManagerPermit\n/// @author Angle Labs, Inc.\n/// @dev Base Implementation of permit functions for the `VaultManager` contract\nabstract contract VaultManagerPermit is Initializable, VaultManagerERC721 {\n using Address for address;\n\n mapping(address => uint256) private _nonces;\n /* solhint-disable var-name-mixedcase */\n bytes32 private _HASHED_NAME;\n bytes32 private _HASHED_VERSION;\n bytes32 private _PERMIT_TYPEHASH;\n /* solhint-enable var-name-mixedcase */\n\n error ExpiredDeadline();\n error InvalidSignature();\n\n //solhint-disable-next-line\n function __ERC721Permit_init(string memory _name) internal onlyInitializing {\n _PERMIT_TYPEHASH = keccak256(\n \"Permit(address owner,address spender,bool approved,uint256 nonce,uint256 deadline)\"\n );\n _HASHED_NAME = keccak256(bytes(_name));\n _HASHED_VERSION = keccak256(bytes(\"1\"));\n }\n\n /// @notice Allows an address to give or revoke approval for all its vaults to another address\n /// @param owner Address signing the permit and giving (or revoking) its approval for all the controlled vaults\n /// @param spender Address to give approval to\n /// @param approved Whether to give or revoke the approval\n /// @param deadline Deadline parameter for the signature to be valid\n /// @dev The `v`, `r`, and `s` parameters are used as signature data\n function permit(\n address owner,\n address spender,\n bool approved,\n uint256 deadline,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) external {\n if (block.timestamp > deadline) revert ExpiredDeadline();\n // Additional signature checks performed in the `ECDSAUpgradeable.recover` function\n if (uint256(s) > 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D576E7357A4501DDFE92F46681B20A0 || (v != 27 && v != 28))\n revert InvalidSignature();\n\n bytes32 digest = keccak256(\n abi.encodePacked(\n \"\\x19\\x01\",\n _domainSeparatorV4(),\n keccak256(\n abi.encode(\n _PERMIT_TYPEHASH,\n // 0x3f43a9c6bafb5c7aab4e0cfe239dc5d4c15caf0381c6104188191f78a6640bd8,\n owner,\n spender,\n approved,\n _useNonce(owner),\n deadline\n )\n )\n )\n );\n if (owner.isContract()) {\n if (IERC1271(owner).isValidSignature(digest, abi.encodePacked(r, s, v)) != 0x1626ba7e)\n revert InvalidSignature();\n } else {\n address signer = ecrecover(digest, v, r, s);\n if (signer != owner || signer == address(0)) revert InvalidSignature();\n }\n\n _setApprovalForAll(owner, spender, approved);\n }\n\n /// @notice Returns the current nonce for an `owner` address\n function nonces(address owner) public view returns (uint256) {\n return _nonces[owner];\n }\n\n /// @notice Returns the domain separator for the current chain.\n // solhint-disable-next-line func-name-mixedcase\n function DOMAIN_SEPARATOR() external view returns (bytes32) {\n return _domainSeparatorV4();\n }\n\n /// @notice Internal version of the `DOMAIN_SEPARATOR` function\n function _domainSeparatorV4() internal view returns (bytes32) {\n return\n keccak256(\n abi.encode(\n // keccak256('EIP712Domain(string name,string version,uint256 chainId,address verifyingContract)')\n 0x8b73c3c69bb8fe3d512ecc4cf759cc79239f7b179b0ffacaa9a75d522b39400f,\n _HASHED_NAME,\n _HASHED_VERSION,\n block.chainid,\n address(this)\n )\n );\n }\n\n /// @notice Consumes a nonce for an address: returns the current value and increments it\n function _useNonce(address owner) internal returns (uint256 current) {\n current = _nonces[owner];\n _nonces[owner] = current + 1;\n }\n\n uint256[49] private __gap;\n}\n" + }, + "contracts/vaultManager/VaultManagerStorage.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\nimport \"@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/token/ERC20/extensions/draft-IERC20PermitUpgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/token/ERC721/IERC721ReceiverUpgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/interfaces/IERC721MetadataUpgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/utils/introspection/IERC165Upgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/utils/AddressUpgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/security/ReentrancyGuardUpgradeable.sol\";\nimport \"@openzeppelin/contracts/token/ERC20/extensions/IERC20Metadata.sol\";\nimport \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\nimport \"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\";\n\nimport \"../interfaces/IAgToken.sol\";\nimport \"../interfaces/IOracle.sol\";\nimport \"../interfaces/ISwapper.sol\";\nimport \"../interfaces/ITreasury.sol\";\nimport \"../interfaces/IVaultManager.sol\";\nimport \"../interfaces/governance/IVeBoostProxy.sol\";\n\n/// @title VaultManagerStorage\n/// @author Angle Labs, Inc.\n/// @dev Variables, references, parameters and events needed in the `VaultManager` contract\n// solhint-disable-next-line max-states-count\ncontract VaultManagerStorage is IVaultManagerStorage, Initializable, ReentrancyGuardUpgradeable {\n /// @notice Base used for parameter computation: almost all the parameters of this contract are set in `BASE_PARAMS`\n uint256 public constant BASE_PARAMS = 10 ** 9;\n /// @notice Base used for interest rate computation\n uint256 public constant BASE_INTEREST = 10 ** 27;\n /// @notice Used for interest rate computation\n uint256 public constant HALF_BASE_INTEREST = 10 ** 27 / 2;\n\n // ================================= REFERENCES ================================\n\n /// @inheritdoc IVaultManagerStorage\n ITreasury public treasury;\n /// @inheritdoc IVaultManagerStorage\n IERC20 public collateral;\n /// @inheritdoc IVaultManagerStorage\n IAgToken public stablecoin;\n /// @inheritdoc IVaultManagerStorage\n IOracle public oracle;\n /// @notice Reference to the contract which computes adjusted veANGLE balances for liquidators boosts\n IVeBoostProxy public veBoostProxy;\n /// @notice Base of the collateral\n uint256 internal _collatBase;\n\n // ================================= PARAMETERS ================================\n // Unless specified otherwise, parameters of this contract are expressed in `BASE_PARAMS`\n\n /// @notice Maximum amount of stablecoins that can be issued with this contract (in `BASE_TOKENS`). This parameter should\n /// not be bigger than `type(uint256).max / BASE_INTEREST` otherwise there may be some overflows in the `increaseDebt` function\n uint256 public debtCeiling;\n /// @notice Threshold veANGLE balance values for the computation of the boost for liquidators: the length of this array\n /// should normally be 2. The base of the x-values in this array should be `BASE_TOKENS`\n uint256[] public xLiquidationBoost;\n /// @notice Values of the liquidation boost at the threshold values of x\n uint256[] public yLiquidationBoost;\n /// @inheritdoc IVaultManagerStorage\n uint64 public collateralFactor;\n /// @notice Maximum Health factor at which a vault can end up after a liquidation (unless it's fully liquidated)\n uint64 public targetHealthFactor;\n /// @notice Upfront fee taken when borrowing stablecoins: this fee is optional and should in practice not be used\n uint64 public borrowFee;\n /// @notice Upfront fee taken when repaying stablecoins: this fee is optional as well. It should be smaller\n /// than the liquidation surcharge (cf below) to avoid exploits where people voluntarily get liquidated at a 0\n /// discount to pay smaller repaying fees\n uint64 public repayFee;\n /// @notice Per second interest taken to borrowers taking agToken loans. Contrarily to other parameters, it is set in `BASE_INTEREST`\n /// that is to say in base 10**27\n uint64 public interestRate;\n /// @notice Fee taken by the protocol during a liquidation. Technically, this value is not the fee per se, it's 1 - fee.\n /// For instance for a 2% fee, `liquidationSurcharge` should be 98%\n uint64 public liquidationSurcharge;\n /// @notice Maximum discount given to liquidators\n uint64 public maxLiquidationDiscount;\n /// @notice Whether whitelisting is required to own a vault or not\n bool public whitelistingActivated;\n /// @notice Whether the contract is paused or not\n bool public paused;\n\n // ================================= VARIABLES =================================\n\n /// @notice Timestamp at which the `interestAccumulator` was updated\n uint256 public lastInterestAccumulatorUpdated;\n /// @inheritdoc IVaultManagerStorage\n uint256 public interestAccumulator;\n /// @inheritdoc IVaultManagerStorage\n uint256 public totalNormalizedDebt;\n /// @notice Surplus accumulated by the contract: surplus is always in stablecoins, and is then reset\n /// when the value is communicated to the treasury contract\n uint256 public surplus;\n /// @notice Bad debt made from liquidated vaults which ended up having no collateral and a positive amount\n /// of stablecoins\n uint256 public badDebt;\n\n // ================================== MAPPINGS =================================\n\n /// @inheritdoc IVaultManagerStorage\n mapping(uint256 => Vault) public vaultData;\n /// @notice Maps an address to 1 if it's whitelisted and can open or own a vault\n mapping(address => uint256) public isWhitelisted;\n\n // ================================ ERC721 DATA ================================\n\n /// @inheritdoc IVaultManagerStorage\n uint256 public vaultIDCount;\n\n /// @notice URI\n string internal _baseURI;\n\n // Mapping from `vaultID` to owner address\n mapping(uint256 => address) internal _owners;\n\n // Mapping from owner address to vault owned count\n mapping(address => uint256) internal _balances;\n\n // Mapping from `vaultID` to approved address\n mapping(uint256 => address) internal _vaultApprovals;\n\n // Mapping from owner to operator approvals\n mapping(address => mapping(address => uint256)) internal _operatorApprovals;\n\n uint256[50] private __gap;\n\n // =================================== EVENTS ==================================\n\n event AccruedToTreasury(uint256 surplusEndValue, uint256 badDebtEndValue);\n event CollateralAmountUpdated(uint256 vaultID, uint256 collateralAmount, uint8 isIncrease);\n event InterestAccumulatorUpdated(uint256 value, uint256 timestamp);\n event InternalDebtUpdated(uint256 vaultID, uint256 internalAmount, uint8 isIncrease);\n event FiledUint64(uint64 param, bytes32 what);\n event DebtCeilingUpdated(uint256 debtCeiling);\n event LiquidationBoostParametersUpdated(address indexed _veBoostProxy, uint256[] xBoost, uint256[] yBoost);\n event LiquidatedVaults(uint256[] vaultIDs);\n event DebtTransferred(uint256 srcVaultID, uint256 dstVaultID, address dstVaultManager, uint256 amount);\n\n // =================================== ERRORS ==================================\n\n error ApprovalToOwner();\n error ApprovalToCaller();\n error DustyLeftoverAmount();\n error DebtCeilingExceeded();\n error HealthyVault();\n error IncompatibleLengths();\n error InsolventVault();\n error InvalidParameterValue();\n error InvalidParameterType();\n error InvalidSetOfParameters();\n error InvalidTreasury();\n error NonERC721Receiver();\n error NonexistentVault();\n error NotApproved();\n error NotGovernor();\n error NotGovernorOrGuardian();\n error NotTreasury();\n error NotWhitelisted();\n error NotVaultManager();\n error Paused();\n error TooHighParameterValue();\n error TooSmallParameterValue();\n error ZeroAddress();\n\n /// @custom:oz-upgrades-unsafe-allow constructor\n constructor() initializer {}\n}\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 1000000 + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers", + "metadata", + "devdoc", + "userdoc", + "storageLayout", + "evm.gasEstimates", + "devdoc", + "userdoc" + ], + "": [ + "ast" + ] + } + }, + "metadata": { + "useLiteralContent": true + } + } +} \ No newline at end of file diff --git a/deployments/linea/AgTokenSideChainMultiBridge_Implementation.json b/deployments/linea/AgTokenSideChainMultiBridge_Implementation.json index 58b7bd03..d5810275 100644 --- a/deployments/linea/AgTokenSideChainMultiBridge_Implementation.json +++ b/deployments/linea/AgTokenSideChainMultiBridge_Implementation.json @@ -1,5 +1,5 @@ { - "address": "0xA61BeB4A3d02decb01039e378237032B351125B4", + "address": "0xa014A485D64efb236423004AB1a99C0aaa97a549", "abi": [ { "inputs": [], @@ -1211,44 +1211,44 @@ "type": "function" } ], - "transactionHash": "0x96f807103f29adf8f1ac267c8ed08d500b1f8dcadc759de38be0f9d221c93edd", + "transactionHash": "0x988ce2777f1dd4e88b910504b5f0d0beb4ce3b21fa7ef2294465652fd7dc0e2a", "receipt": { "to": null, "from": "0xfdA462548Ce04282f4B6D6619823a7C64Fdc0185", - "contractAddress": "0xA61BeB4A3d02decb01039e378237032B351125B4", - "transactionIndex": 13, - "gasUsed": "3970836", - "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000080000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000", - "blockHash": "0x9286405f3386180e644a0f67db073ca8a7a823303658d713c024892e2a0e7510", - "transactionHash": "0x96f807103f29adf8f1ac267c8ed08d500b1f8dcadc759de38be0f9d221c93edd", + "contractAddress": "0xa014A485D64efb236423004AB1a99C0aaa97a549", + "transactionIndex": 4, + "gasUsed": "3964995", + "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000080000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000008000000000040000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000", + "blockHash": "0xcef82c32a681fc2cd4e9d10d2ed77da06b3653eccf9df7d4c1a14a0963dc14a6", + "transactionHash": "0x988ce2777f1dd4e88b910504b5f0d0beb4ce3b21fa7ef2294465652fd7dc0e2a", "logs": [ { - "transactionIndex": 13, - "blockNumber": 597279, - "transactionHash": "0x96f807103f29adf8f1ac267c8ed08d500b1f8dcadc759de38be0f9d221c93edd", - "address": "0xA61BeB4A3d02decb01039e378237032B351125B4", + "transactionIndex": 4, + "blockNumber": 1596318, + "transactionHash": "0x988ce2777f1dd4e88b910504b5f0d0beb4ce3b21fa7ef2294465652fd7dc0e2a", + "address": "0xa014A485D64efb236423004AB1a99C0aaa97a549", "topics": [ "0x7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb3847402498" ], "data": "0x0000000000000000000000000000000000000000000000000000000000000001", - "logIndex": 15, - "blockHash": "0x9286405f3386180e644a0f67db073ca8a7a823303658d713c024892e2a0e7510" + "logIndex": 9, + "blockHash": "0xcef82c32a681fc2cd4e9d10d2ed77da06b3653eccf9df7d4c1a14a0963dc14a6" } ], - "blockNumber": 597279, - "cumulativeGasUsed": "5550258", + "blockNumber": 1596318, + "cumulativeGasUsed": "4399320", "status": 1, "byzantium": true }, "args": [], - "numDeployments": 1, - "solcInputHash": "5b32b398159a217fe332309d645e3f53", - "metadata": "{\"compiler\":{\"version\":\"0.8.17+commit.8df45f5f\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[],\"name\":\"AssetStillControlledInReserves\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"BurnAmountExceedsAllowance\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"HourlyLimitExceeded\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidSender\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidToken\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidTreasury\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"NotGovernor\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"NotGovernorOrGuardian\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"NotMinter\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"NotTreasury\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"TooBigAmount\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"TooHighParameterValue\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ZeroAddress\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"spender\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"}],\"name\":\"Approval\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"bridgeToken\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"limit\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"hourlyLimit\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"fee\",\"type\":\"uint64\"},{\"indexed\":false,\"internalType\":\"bool\",\"name\":\"paused\",\"type\":\"bool\"}],\"name\":\"BridgeTokenAdded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"bridgeToken\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"fee\",\"type\":\"uint64\"}],\"name\":\"BridgeTokenFeeUpdated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"bridgeToken\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"hourlyLimit\",\"type\":\"uint256\"}],\"name\":\"BridgeTokenHourlyLimitUpdated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"bridgeToken\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"limit\",\"type\":\"uint256\"}],\"name\":\"BridgeTokenLimitUpdated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"bridgeToken\",\"type\":\"address\"}],\"name\":\"BridgeTokenRemoved\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"bridgeToken\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"bool\",\"name\":\"toggleStatus\",\"type\":\"bool\"}],\"name\":\"BridgeTokenToggled\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"theAddress\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"toggleStatus\",\"type\":\"uint256\"}],\"name\":\"FeeToggled\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"hourlyLimit\",\"type\":\"uint256\"}],\"name\":\"HourlyLimitUpdated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint8\",\"name\":\"version\",\"type\":\"uint8\"}],\"name\":\"Initialized\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"minter\",\"type\":\"address\"}],\"name\":\"MinterToggled\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"Recovered\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"}],\"name\":\"Transfer\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"_treasury\",\"type\":\"address\"}],\"name\":\"TreasuryUpdated\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"BASE_PARAMS\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"DOMAIN_SEPARATOR\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"bridgeToken\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"limit\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"hourlyLimit\",\"type\":\"uint256\"},{\"internalType\":\"uint64\",\"name\":\"fee\",\"type\":\"uint64\"},{\"internalType\":\"bool\",\"name\":\"paused\",\"type\":\"bool\"}],\"name\":\"addBridgeToken\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"minter\",\"type\":\"address\"}],\"name\":\"addMinter\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"allBridgeTokens\",\"outputs\":[{\"internalType\":\"address[]\",\"name\":\"\",\"type\":\"address[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"spender\",\"type\":\"address\"}],\"name\":\"allowance\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"spender\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"approve\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"}],\"name\":\"balanceOf\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"name\":\"bridgeTokensList\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"bridges\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"limit\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"hourlyLimit\",\"type\":\"uint256\"},{\"internalType\":\"uint64\",\"name\":\"fee\",\"type\":\"uint64\"},{\"internalType\":\"bool\",\"name\":\"allowed\",\"type\":\"bool\"},{\"internalType\":\"bool\",\"name\":\"paused\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"burner\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"}],\"name\":\"burnFrom\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"burner\",\"type\":\"address\"}],\"name\":\"burnSelf\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"burnStablecoin\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"chainTotalHourlyLimit\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"name\":\"chainTotalUsage\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"currentTotalUsage\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"bridgeToken\",\"type\":\"address\"}],\"name\":\"currentUsage\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"decimals\",\"outputs\":[{\"internalType\":\"uint8\",\"name\":\"\",\"type\":\"uint8\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"spender\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"subtractedValue\",\"type\":\"uint256\"}],\"name\":\"decreaseAllowance\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"spender\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"addedValue\",\"type\":\"uint256\"}],\"name\":\"increaseAllowance\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"string\",\"name\":\"name_\",\"type\":\"string\"},{\"internalType\":\"string\",\"name\":\"symbol_\",\"type\":\"string\"},{\"internalType\":\"address\",\"name\":\"_treasury\",\"type\":\"address\"}],\"name\":\"initialize\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"isFeeExempt\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"isMinter\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"mint\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"name\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"}],\"name\":\"nonces\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"spender\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"deadline\",\"type\":\"uint256\"},{\"internalType\":\"uint8\",\"name\":\"v\",\"type\":\"uint8\"},{\"internalType\":\"bytes32\",\"name\":\"r\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32\",\"name\":\"s\",\"type\":\"bytes32\"}],\"name\":\"permit\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"tokenAddress\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amountToRecover\",\"type\":\"uint256\"}],\"name\":\"recoverERC20\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"bridgeToken\",\"type\":\"address\"}],\"name\":\"removeBridgeToken\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"minter\",\"type\":\"address\"}],\"name\":\"removeMinter\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"hourlyLimit\",\"type\":\"uint256\"}],\"name\":\"setChainTotalHourlyLimit\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"bridgeToken\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"hourlyLimit\",\"type\":\"uint256\"}],\"name\":\"setHourlyLimit\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"bridgeToken\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"limit\",\"type\":\"uint256\"}],\"name\":\"setLimit\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"bridgeToken\",\"type\":\"address\"},{\"internalType\":\"uint64\",\"name\":\"fee\",\"type\":\"uint64\"}],\"name\":\"setSwapFee\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_treasury\",\"type\":\"address\"}],\"name\":\"setTreasury\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"bridgeToken\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"swapIn\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"bridgeToken\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"swapOut\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"symbol\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"bridgeToken\",\"type\":\"address\"}],\"name\":\"toggleBridge\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"theAddress\",\"type\":\"address\"}],\"name\":\"toggleFeesForAddress\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"totalSupply\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"transfer\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"transferFrom\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"treasury\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"name\":\"usage\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"}],\"devdoc\":{\"author\":\"Angle Labs, Inc.\",\"details\":\"This contract supports bridge tokens having a minting right on the stablecoin (also referred to as the canonical or the native token)References: - FRAX implementation: https://polygonscan.com/address/0x45c32fA6DF82ead1e2EF74d17b76547EDdFaFF89#code - QiDAO implementation: https://snowtrace.io/address/0x5c49b268c9841AFF1Cc3B0a418ff5c3442eE3F3b#code\",\"kind\":\"dev\",\"methods\":{\"DOMAIN_SEPARATOR()\":{\"details\":\"See {IERC20Permit-DOMAIN_SEPARATOR}.\"},\"addBridgeToken(address,uint256,uint256,uint64,bool)\":{\"params\":{\"bridgeToken\":\"Bridge token to add: it should be a version of the stablecoin from another bridge\",\"fee\":\"Fee taken upon swapping for or against this token\",\"hourlyLimit\":\"Limit on the hourly volume for this bridge\",\"limit\":\"Limit on the balance of bridge token this contract could hold\",\"paused\":\"Whether swapping for this token should be paused or not\"}},\"addMinter(address)\":{\"details\":\"Zero address checks are performed directly in the `Treasury` contract\",\"params\":{\"minter\":\"Minter address to add\"}},\"allBridgeTokens()\":{\"details\":\"Helpful for UIs\"},\"allowance(address,address)\":{\"details\":\"See {IERC20-allowance}.\"},\"approve(address,uint256)\":{\"details\":\"See {IERC20-approve}. NOTE: If `amount` is the maximum `uint256`, the allowance is not updated on `transferFrom`. This is semantically equivalent to an infinite approval. Requirements: - `spender` cannot be the zero address.\"},\"balanceOf(address)\":{\"details\":\"See {IERC20-balanceOf}.\"},\"burnFrom(uint256,address,address)\":{\"details\":\"This method is to be called by a contract with the minter right after being requested to do so by a `sender` address willing to burn tokens from another `burner` addressThe method checks the allowance between the `sender` and the `burner`\",\"params\":{\"amount\":\"Amount of tokens to burn\",\"burner\":\"Address to burn from\",\"sender\":\"Address which requested the burn from `burner`\"}},\"burnSelf(uint256,address)\":{\"details\":\"This method is to be called by a contract with a minter right on the AgToken after being requested to do so by an address willing to burn tokens from its address\",\"params\":{\"amount\":\"Amount of tokens to burn\",\"burner\":\"Address to burn from\"}},\"burnStablecoin(uint256)\":{\"details\":\"This function can typically be called if there is a settlement mechanism to burn stablecoins\",\"params\":{\"amount\":\"Amount of stablecoins to burn\"}},\"currentTotalUsage()\":{\"details\":\"Helpful for UIs\"},\"currentUsage(address)\":{\"details\":\"Helpful for UIs\",\"params\":{\"bridgeToken\":\"Bridge used to mint\"}},\"decimals()\":{\"details\":\"Returns the number of decimals used to get its user representation. For example, if `decimals` equals `2`, a balance of `505` tokens should be displayed to a user as `5.05` (`505 / 10 ** 2`). Tokens usually opt for a value of 18, imitating the relationship between Ether and Wei. This is the value {ERC20} uses, unless this function is overridden; NOTE: This information is only used for _display_ purposes: it in no way affects any of the arithmetic of the contract, including {IERC20-balanceOf} and {IERC20-transfer}.\"},\"decreaseAllowance(address,uint256)\":{\"details\":\"Atomically decreases the allowance granted to `spender` by the caller. This is an alternative to {approve} that can be used as a mitigation for problems described in {IERC20-approve}. Emits an {Approval} event indicating the updated allowance. Requirements: - `spender` cannot be the zero address. - `spender` must have allowance for the caller of at least `subtractedValue`.\"},\"increaseAllowance(address,uint256)\":{\"details\":\"Atomically increases the allowance granted to `spender` by the caller. This is an alternative to {approve} that can be used as a mitigation for problems described in {IERC20-approve}. Emits an {Approval} event indicating the updated allowance. Requirements: - `spender` cannot be the zero address.\"},\"initialize(string,string,address)\":{\"details\":\"By default, agTokens are ERC-20 tokens with 18 decimals\",\"params\":{\"_treasury\":\"Reference to the `Treasury` contract associated to this agToken\",\"name_\":\"Name of the token\",\"symbol_\":\"Symbol of the token\"}},\"mint(address,uint256)\":{\"details\":\"The contracts allowed to issue agTokens are the `StableMaster` contract, `VaultManager` contracts associated to this stablecoin as well as the flash loan module (if activated) and potentially contracts whitelisted by governance\",\"params\":{\"account\":\"Address to mint to\",\"amount\":\"Amount to mint\"}},\"name()\":{\"details\":\"Returns the name of the token.\"},\"nonces(address)\":{\"details\":\"See {IERC20Permit-nonces}.\"},\"permit(address,address,uint256,uint256,uint8,bytes32,bytes32)\":{\"details\":\"See {IERC20Permit-permit}.\"},\"recoverERC20(address,address,uint256)\":{\"details\":\"Can be used to withdraw bridge tokens for them to be de-bridged on mainnet\"},\"removeBridgeToken(address)\":{\"params\":{\"bridgeToken\":\"Address of the bridge token to remove support for\"}},\"removeMinter(address)\":{\"details\":\"This function can also be called by a minter wishing to revoke itself\",\"params\":{\"minter\":\"Minter address to remove\"}},\"setTreasury(address)\":{\"params\":{\"_treasury\":\"New treasury address\"}},\"swapIn(address,uint256,address)\":{\"details\":\"Some fees may be taken by the protocol depending on the token used and on the address calling\",\"params\":{\"amount\":\"Amount of bridge tokens to send\",\"bridgeToken\":\"Bridge token to use to mint\",\"to\":\"Address to which the stablecoin should be sent\"},\"returns\":{\"_0\":\"Amount of the canonical stablecoin actually minted\"}},\"swapOut(address,uint256,address)\":{\"details\":\"Some fees may be taken by the protocol depending on the token used and on the address calling\",\"params\":{\"amount\":\"Amount of canonical tokens to burn\",\"bridgeToken\":\"Bridge token required\",\"to\":\"Address to which the bridge token should be sent\"},\"returns\":{\"_0\":\"Amount of bridge tokens actually sent back\"}},\"symbol()\":{\"details\":\"Returns the symbol of the token, usually a shorter version of the name.\"},\"totalSupply()\":{\"details\":\"See {IERC20-totalSupply}.\"},\"transfer(address,uint256)\":{\"details\":\"See {IERC20-transfer}. Requirements: - `to` cannot be the zero address. - the caller must have a balance of at least `amount`.\"},\"transferFrom(address,address,uint256)\":{\"details\":\"See {IERC20-transferFrom}. Emits an {Approval} event indicating the updated allowance. This is not required by the EIP. See the note at the beginning of {ERC20}. NOTE: Does not update the allowance if the current allowance is the maximum `uint256`. Requirements: - `from` and `to` cannot be the zero address. - `from` must have a balance of at least `amount`. - the caller must have allowance for ``from``'s tokens of at least `amount`.\"}},\"title\":\"AgTokenSideChainMultiBridge\",\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{\"BASE_PARAMS()\":{\"notice\":\"Base used for fee computation\"},\"addBridgeToken(address,uint256,uint256,uint64,bool)\":{\"notice\":\"Adds support for a bridge token\"},\"addMinter(address)\":{\"notice\":\"Adds a minter in the contract\"},\"allBridgeTokens()\":{\"notice\":\"Returns the list of all supported bridge tokens\"},\"bridgeTokensList(uint256)\":{\"notice\":\"List of all bridge tokens\"},\"bridges(address)\":{\"notice\":\"Maps a bridge token to data\"},\"burnFrom(uint256,address,address)\":{\"notice\":\"Burns `amount` tokens from a `burner` address after being asked to by `sender`\"},\"burnSelf(uint256,address)\":{\"notice\":\"Burns `amount` tokens from a `burner` address\"},\"burnStablecoin(uint256)\":{\"notice\":\"Allows anyone to burn agToken without redeeming collateral back\"},\"chainTotalHourlyLimit()\":{\"notice\":\"Limit to the amount of tokens that can be sent from that chain to another chain\"},\"chainTotalUsage(uint256)\":{\"notice\":\"Usage per hour on that chain. Maps an hourly timestamp to the total volume swapped out on the chain\"},\"currentTotalUsage()\":{\"notice\":\"Returns the current total volume on the chain for the current hour\"},\"currentUsage(address)\":{\"notice\":\"Returns the current volume for a bridge, for the current hour\"},\"initialize(string,string,address)\":{\"notice\":\"Initializes the `AgToken` contract\"},\"isFeeExempt(address)\":{\"notice\":\"Maps an address to whether it is exempt of fees for when it comes to swapping in and out\"},\"isMinter(address)\":{\"notice\":\"Checks whether an address has the right to mint agTokens\"},\"mint(address,uint256)\":{\"notice\":\"Lets the `StableMaster` contract or another whitelisted contract mint agTokens\"},\"recoverERC20(address,address,uint256)\":{\"notice\":\"Recovers any ERC20 token\"},\"removeBridgeToken(address)\":{\"notice\":\"Removes support for a token\"},\"removeMinter(address)\":{\"notice\":\"Removes a minter from the contract\"},\"setChainTotalHourlyLimit(uint256)\":{\"notice\":\"Updates the `chainTotalHourlyLimit` amount\"},\"setHourlyLimit(address,uint256)\":{\"notice\":\"Updates the `hourlyLimit` amount for `bridgeToken`\"},\"setLimit(address,uint256)\":{\"notice\":\"Updates the `limit` amount for `bridgeToken`\"},\"setSwapFee(address,uint64)\":{\"notice\":\"Updates the `fee` value for `bridgeToken`\"},\"setTreasury(address)\":{\"notice\":\"Sets a new treasury contract\"},\"swapIn(address,uint256,address)\":{\"notice\":\"Mints the canonical token from a supported bridge token\"},\"swapOut(address,uint256,address)\":{\"notice\":\"Burns the canonical token in exchange for a bridge token\"},\"toggleBridge(address)\":{\"notice\":\"Pauses or unpauses swapping in and out for a token\"},\"toggleFeesForAddress(address)\":{\"notice\":\"Toggles fees for the address `theAddress`\"},\"treasury()\":{\"notice\":\"Reference to the treasury contract which can grant minting rights\"},\"usage(address,uint256)\":{\"notice\":\"Maps a bridge token to the associated hourly volume\"}},\"notice\":\"Contract for Angle agTokens on other chains than Ethereum mainnet\",\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/agToken/AgTokenSideChainMultiBridge.sol\":\"AgTokenSideChainMultiBridge\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":1000000},\"remappings\":[]},\"sources\":{\"@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.7.0) (proxy/utils/Initializable.sol)\\n\\npragma solidity ^0.8.2;\\n\\nimport \\\"../../utils/AddressUpgradeable.sol\\\";\\n\\n/**\\n * @dev This is a base contract to aid in writing upgradeable contracts, or any kind of contract that will be deployed\\n * behind a proxy. Since proxied contracts do not make use of a constructor, it's common to move constructor logic to an\\n * external initializer function, usually called `initialize`. It then becomes necessary to protect this initializer\\n * function so it can only be called once. The {initializer} modifier provided by this contract will have this effect.\\n *\\n * The initialization functions use a version number. Once a version number is used, it is consumed and cannot be\\n * reused. This mechanism prevents re-execution of each \\\"step\\\" but allows the creation of new initialization steps in\\n * case an upgrade adds a module that needs to be initialized.\\n *\\n * For example:\\n *\\n * [.hljs-theme-light.nopadding]\\n * ```\\n * contract MyToken is ERC20Upgradeable {\\n * function initialize() initializer public {\\n * __ERC20_init(\\\"MyToken\\\", \\\"MTK\\\");\\n * }\\n * }\\n * contract MyTokenV2 is MyToken, ERC20PermitUpgradeable {\\n * function initializeV2() reinitializer(2) public {\\n * __ERC20Permit_init(\\\"MyToken\\\");\\n * }\\n * }\\n * ```\\n *\\n * TIP: To avoid leaving the proxy in an uninitialized state, the initializer function should be called as early as\\n * possible by providing the encoded function call as the `_data` argument to {ERC1967Proxy-constructor}.\\n *\\n * CAUTION: When used with inheritance, manual care must be taken to not invoke a parent initializer twice, or to ensure\\n * that all initializers are idempotent. This is not verified automatically as constructors are by Solidity.\\n *\\n * [CAUTION]\\n * ====\\n * Avoid leaving a contract uninitialized.\\n *\\n * An uninitialized contract can be taken over by an attacker. This applies to both a proxy and its implementation\\n * contract, which may impact the proxy. To prevent the implementation contract from being used, you should invoke\\n * the {_disableInitializers} function in the constructor to automatically lock it when it is deployed:\\n *\\n * [.hljs-theme-light.nopadding]\\n * ```\\n * /// @custom:oz-upgrades-unsafe-allow constructor\\n * constructor() {\\n * _disableInitializers();\\n * }\\n * ```\\n * ====\\n */\\nabstract contract Initializable {\\n /**\\n * @dev Indicates that the contract has been initialized.\\n * @custom:oz-retyped-from bool\\n */\\n uint8 private _initialized;\\n\\n /**\\n * @dev Indicates that the contract is in the process of being initialized.\\n */\\n bool private _initializing;\\n\\n /**\\n * @dev Triggered when the contract has been initialized or reinitialized.\\n */\\n event Initialized(uint8 version);\\n\\n /**\\n * @dev A modifier that defines a protected initializer function that can be invoked at most once. In its scope,\\n * `onlyInitializing` functions can be used to initialize parent contracts. Equivalent to `reinitializer(1)`.\\n */\\n modifier initializer() {\\n bool isTopLevelCall = !_initializing;\\n require(\\n (isTopLevelCall && _initialized < 1) || (!AddressUpgradeable.isContract(address(this)) && _initialized == 1),\\n \\\"Initializable: contract is already initialized\\\"\\n );\\n _initialized = 1;\\n if (isTopLevelCall) {\\n _initializing = true;\\n }\\n _;\\n if (isTopLevelCall) {\\n _initializing = false;\\n emit Initialized(1);\\n }\\n }\\n\\n /**\\n * @dev A modifier that defines a protected reinitializer function that can be invoked at most once, and only if the\\n * contract hasn't been initialized to a greater version before. In its scope, `onlyInitializing` functions can be\\n * used to initialize parent contracts.\\n *\\n * `initializer` is equivalent to `reinitializer(1)`, so a reinitializer may be used after the original\\n * initialization step. This is essential to configure modules that are added through upgrades and that require\\n * initialization.\\n *\\n * Note that versions can jump in increments greater than 1; this implies that if multiple reinitializers coexist in\\n * a contract, executing them in the right order is up to the developer or operator.\\n */\\n modifier reinitializer(uint8 version) {\\n require(!_initializing && _initialized < version, \\\"Initializable: contract is already initialized\\\");\\n _initialized = version;\\n _initializing = true;\\n _;\\n _initializing = false;\\n emit Initialized(version);\\n }\\n\\n /**\\n * @dev Modifier to protect an initialization function so that it can only be invoked by functions with the\\n * {initializer} and {reinitializer} modifiers, directly or indirectly.\\n */\\n modifier onlyInitializing() {\\n require(_initializing, \\\"Initializable: contract is not initializing\\\");\\n _;\\n }\\n\\n /**\\n * @dev Locks the contract, preventing any future reinitialization. This cannot be part of an initializer call.\\n * Calling this in the constructor of a contract will prevent that contract from being initialized or reinitialized\\n * to any version. It is recommended to use this to lock implementation contracts that are designed to be called\\n * through proxies.\\n */\\n function _disableInitializers() internal virtual {\\n require(!_initializing, \\\"Initializable: contract is initializing\\\");\\n if (_initialized < type(uint8).max) {\\n _initialized = type(uint8).max;\\n emit Initialized(type(uint8).max);\\n }\\n }\\n}\\n\",\"keccak256\":\"0x0203dcadc5737d9ef2c211d6fa15d18ebc3b30dfa51903b64870b01a062b0b4e\",\"license\":\"MIT\"},\"@openzeppelin/contracts-upgradeable/token/ERC20/ERC20Upgradeable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.7.0) (token/ERC20/ERC20.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"./IERC20Upgradeable.sol\\\";\\nimport \\\"./extensions/IERC20MetadataUpgradeable.sol\\\";\\nimport \\\"../../utils/ContextUpgradeable.sol\\\";\\nimport \\\"../../proxy/utils/Initializable.sol\\\";\\n\\n/**\\n * @dev Implementation of the {IERC20} interface.\\n *\\n * This implementation is agnostic to the way tokens are created. This means\\n * that a supply mechanism has to be added in a derived contract using {_mint}.\\n * For a generic mechanism see {ERC20PresetMinterPauser}.\\n *\\n * TIP: For a detailed writeup see our guide\\n * https://forum.zeppelin.solutions/t/how-to-implement-erc20-supply-mechanisms/226[How\\n * to implement supply mechanisms].\\n *\\n * We have followed general OpenZeppelin Contracts guidelines: functions revert\\n * instead returning `false` on failure. This behavior is nonetheless\\n * conventional and does not conflict with the expectations of ERC20\\n * applications.\\n *\\n * Additionally, an {Approval} event is emitted on calls to {transferFrom}.\\n * This allows applications to reconstruct the allowance for all accounts just\\n * by listening to said events. Other implementations of the EIP may not emit\\n * these events, as it isn't required by the specification.\\n *\\n * Finally, the non-standard {decreaseAllowance} and {increaseAllowance}\\n * functions have been added to mitigate the well-known issues around setting\\n * allowances. See {IERC20-approve}.\\n */\\ncontract ERC20Upgradeable is Initializable, ContextUpgradeable, IERC20Upgradeable, IERC20MetadataUpgradeable {\\n mapping(address => uint256) private _balances;\\n\\n mapping(address => mapping(address => uint256)) private _allowances;\\n\\n uint256 private _totalSupply;\\n\\n string private _name;\\n string private _symbol;\\n\\n /**\\n * @dev Sets the values for {name} and {symbol}.\\n *\\n * The default value of {decimals} is 18. To select a different value for\\n * {decimals} you should overload it.\\n *\\n * All two of these values are immutable: they can only be set once during\\n * construction.\\n */\\n function __ERC20_init(string memory name_, string memory symbol_) internal onlyInitializing {\\n __ERC20_init_unchained(name_, symbol_);\\n }\\n\\n function __ERC20_init_unchained(string memory name_, string memory symbol_) internal onlyInitializing {\\n _name = name_;\\n _symbol = symbol_;\\n }\\n\\n /**\\n * @dev Returns the name of the token.\\n */\\n function name() public view virtual override returns (string memory) {\\n return _name;\\n }\\n\\n /**\\n * @dev Returns the symbol of the token, usually a shorter version of the\\n * name.\\n */\\n function symbol() public view virtual override returns (string memory) {\\n return _symbol;\\n }\\n\\n /**\\n * @dev Returns the number of decimals used to get its user representation.\\n * For example, if `decimals` equals `2`, a balance of `505` tokens should\\n * be displayed to a user as `5.05` (`505 / 10 ** 2`).\\n *\\n * Tokens usually opt for a value of 18, imitating the relationship between\\n * Ether and Wei. This is the value {ERC20} uses, unless this function is\\n * overridden;\\n *\\n * NOTE: This information is only used for _display_ purposes: it in\\n * no way affects any of the arithmetic of the contract, including\\n * {IERC20-balanceOf} and {IERC20-transfer}.\\n */\\n function decimals() public view virtual override returns (uint8) {\\n return 18;\\n }\\n\\n /**\\n * @dev See {IERC20-totalSupply}.\\n */\\n function totalSupply() public view virtual override returns (uint256) {\\n return _totalSupply;\\n }\\n\\n /**\\n * @dev See {IERC20-balanceOf}.\\n */\\n function balanceOf(address account) public view virtual override returns (uint256) {\\n return _balances[account];\\n }\\n\\n /**\\n * @dev See {IERC20-transfer}.\\n *\\n * Requirements:\\n *\\n * - `to` cannot be the zero address.\\n * - the caller must have a balance of at least `amount`.\\n */\\n function transfer(address to, uint256 amount) public virtual override returns (bool) {\\n address owner = _msgSender();\\n _transfer(owner, to, amount);\\n return true;\\n }\\n\\n /**\\n * @dev See {IERC20-allowance}.\\n */\\n function allowance(address owner, address spender) public view virtual override returns (uint256) {\\n return _allowances[owner][spender];\\n }\\n\\n /**\\n * @dev See {IERC20-approve}.\\n *\\n * NOTE: If `amount` is the maximum `uint256`, the allowance is not updated on\\n * `transferFrom`. This is semantically equivalent to an infinite approval.\\n *\\n * Requirements:\\n *\\n * - `spender` cannot be the zero address.\\n */\\n function approve(address spender, uint256 amount) public virtual override returns (bool) {\\n address owner = _msgSender();\\n _approve(owner, spender, amount);\\n return true;\\n }\\n\\n /**\\n * @dev See {IERC20-transferFrom}.\\n *\\n * Emits an {Approval} event indicating the updated allowance. This is not\\n * required by the EIP. See the note at the beginning of {ERC20}.\\n *\\n * NOTE: Does not update the allowance if the current allowance\\n * is the maximum `uint256`.\\n *\\n * Requirements:\\n *\\n * - `from` and `to` cannot be the zero address.\\n * - `from` must have a balance of at least `amount`.\\n * - the caller must have allowance for ``from``'s tokens of at least\\n * `amount`.\\n */\\n function transferFrom(\\n address from,\\n address to,\\n uint256 amount\\n ) public virtual override returns (bool) {\\n address spender = _msgSender();\\n _spendAllowance(from, spender, amount);\\n _transfer(from, to, amount);\\n return true;\\n }\\n\\n /**\\n * @dev Atomically increases the allowance granted to `spender` by the caller.\\n *\\n * This is an alternative to {approve} that can be used as a mitigation for\\n * problems described in {IERC20-approve}.\\n *\\n * Emits an {Approval} event indicating the updated allowance.\\n *\\n * Requirements:\\n *\\n * - `spender` cannot be the zero address.\\n */\\n function increaseAllowance(address spender, uint256 addedValue) public virtual returns (bool) {\\n address owner = _msgSender();\\n _approve(owner, spender, allowance(owner, spender) + addedValue);\\n return true;\\n }\\n\\n /**\\n * @dev Atomically decreases the allowance granted to `spender` by the caller.\\n *\\n * This is an alternative to {approve} that can be used as a mitigation for\\n * problems described in {IERC20-approve}.\\n *\\n * Emits an {Approval} event indicating the updated allowance.\\n *\\n * Requirements:\\n *\\n * - `spender` cannot be the zero address.\\n * - `spender` must have allowance for the caller of at least\\n * `subtractedValue`.\\n */\\n function decreaseAllowance(address spender, uint256 subtractedValue) public virtual returns (bool) {\\n address owner = _msgSender();\\n uint256 currentAllowance = allowance(owner, spender);\\n require(currentAllowance >= subtractedValue, \\\"ERC20: decreased allowance below zero\\\");\\n unchecked {\\n _approve(owner, spender, currentAllowance - subtractedValue);\\n }\\n\\n return true;\\n }\\n\\n /**\\n * @dev Moves `amount` of tokens from `from` to `to`.\\n *\\n * This internal function is equivalent to {transfer}, and can be used to\\n * e.g. implement automatic token fees, slashing mechanisms, etc.\\n *\\n * Emits a {Transfer} event.\\n *\\n * Requirements:\\n *\\n * - `from` cannot be the zero address.\\n * - `to` cannot be the zero address.\\n * - `from` must have a balance of at least `amount`.\\n */\\n function _transfer(\\n address from,\\n address to,\\n uint256 amount\\n ) internal virtual {\\n require(from != address(0), \\\"ERC20: transfer from the zero address\\\");\\n require(to != address(0), \\\"ERC20: transfer to the zero address\\\");\\n\\n _beforeTokenTransfer(from, to, amount);\\n\\n uint256 fromBalance = _balances[from];\\n require(fromBalance >= amount, \\\"ERC20: transfer amount exceeds balance\\\");\\n unchecked {\\n _balances[from] = fromBalance - amount;\\n }\\n _balances[to] += amount;\\n\\n emit Transfer(from, to, amount);\\n\\n _afterTokenTransfer(from, to, amount);\\n }\\n\\n /** @dev Creates `amount` tokens and assigns them to `account`, increasing\\n * the total supply.\\n *\\n * Emits a {Transfer} event with `from` set to the zero address.\\n *\\n * Requirements:\\n *\\n * - `account` cannot be the zero address.\\n */\\n function _mint(address account, uint256 amount) internal virtual {\\n require(account != address(0), \\\"ERC20: mint to the zero address\\\");\\n\\n _beforeTokenTransfer(address(0), account, amount);\\n\\n _totalSupply += amount;\\n _balances[account] += amount;\\n emit Transfer(address(0), account, amount);\\n\\n _afterTokenTransfer(address(0), account, amount);\\n }\\n\\n /**\\n * @dev Destroys `amount` tokens from `account`, reducing the\\n * total supply.\\n *\\n * Emits a {Transfer} event with `to` set to the zero address.\\n *\\n * Requirements:\\n *\\n * - `account` cannot be the zero address.\\n * - `account` must have at least `amount` tokens.\\n */\\n function _burn(address account, uint256 amount) internal virtual {\\n require(account != address(0), \\\"ERC20: burn from the zero address\\\");\\n\\n _beforeTokenTransfer(account, address(0), amount);\\n\\n uint256 accountBalance = _balances[account];\\n require(accountBalance >= amount, \\\"ERC20: burn amount exceeds balance\\\");\\n unchecked {\\n _balances[account] = accountBalance - amount;\\n }\\n _totalSupply -= amount;\\n\\n emit Transfer(account, address(0), amount);\\n\\n _afterTokenTransfer(account, address(0), amount);\\n }\\n\\n /**\\n * @dev Sets `amount` as the allowance of `spender` over the `owner` s tokens.\\n *\\n * This internal function is equivalent to `approve`, and can be used to\\n * e.g. set automatic allowances for certain subsystems, etc.\\n *\\n * Emits an {Approval} event.\\n *\\n * Requirements:\\n *\\n * - `owner` cannot be the zero address.\\n * - `spender` cannot be the zero address.\\n */\\n function _approve(\\n address owner,\\n address spender,\\n uint256 amount\\n ) internal virtual {\\n require(owner != address(0), \\\"ERC20: approve from the zero address\\\");\\n require(spender != address(0), \\\"ERC20: approve to the zero address\\\");\\n\\n _allowances[owner][spender] = amount;\\n emit Approval(owner, spender, amount);\\n }\\n\\n /**\\n * @dev Updates `owner` s allowance for `spender` based on spent `amount`.\\n *\\n * Does not update the allowance amount in case of infinite allowance.\\n * Revert if not enough allowance is available.\\n *\\n * Might emit an {Approval} event.\\n */\\n function _spendAllowance(\\n address owner,\\n address spender,\\n uint256 amount\\n ) internal virtual {\\n uint256 currentAllowance = allowance(owner, spender);\\n if (currentAllowance != type(uint256).max) {\\n require(currentAllowance >= amount, \\\"ERC20: insufficient allowance\\\");\\n unchecked {\\n _approve(owner, spender, currentAllowance - amount);\\n }\\n }\\n }\\n\\n /**\\n * @dev Hook that is called before any transfer of tokens. This includes\\n * minting and burning.\\n *\\n * Calling conditions:\\n *\\n * - when `from` and `to` are both non-zero, `amount` of ``from``'s tokens\\n * will be transferred to `to`.\\n * - when `from` is zero, `amount` tokens will be minted for `to`.\\n * - when `to` is zero, `amount` of ``from``'s tokens will be burned.\\n * - `from` and `to` are never both zero.\\n *\\n * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].\\n */\\n function _beforeTokenTransfer(\\n address from,\\n address to,\\n uint256 amount\\n ) internal virtual {}\\n\\n /**\\n * @dev Hook that is called after any transfer of tokens. This includes\\n * minting and burning.\\n *\\n * Calling conditions:\\n *\\n * - when `from` and `to` are both non-zero, `amount` of ``from``'s tokens\\n * has been transferred to `to`.\\n * - when `from` is zero, `amount` tokens have been minted for `to`.\\n * - when `to` is zero, `amount` of ``from``'s tokens have been burned.\\n * - `from` and `to` are never both zero.\\n *\\n * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].\\n */\\n function _afterTokenTransfer(\\n address from,\\n address to,\\n uint256 amount\\n ) internal virtual {}\\n\\n /**\\n * @dev This empty reserved space is put in place to allow future versions to add new\\n * variables without shifting down storage in the inheritance chain.\\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\\n */\\n uint256[45] private __gap;\\n}\\n\",\"keccak256\":\"0x7c7ac0bc6c340a7f320524b9a4b4b079ee9da3c51258080d4bab237f329a427c\",\"license\":\"MIT\"},\"@openzeppelin/contracts-upgradeable/token/ERC20/IERC20Upgradeable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.6.0) (token/ERC20/IERC20.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Interface of the ERC20 standard as defined in the EIP.\\n */\\ninterface IERC20Upgradeable {\\n /**\\n * @dev Emitted when `value` tokens are moved from one account (`from`) to\\n * another (`to`).\\n *\\n * Note that `value` may be zero.\\n */\\n event Transfer(address indexed from, address indexed to, uint256 value);\\n\\n /**\\n * @dev Emitted when the allowance of a `spender` for an `owner` is set by\\n * a call to {approve}. `value` is the new allowance.\\n */\\n event Approval(address indexed owner, address indexed spender, uint256 value);\\n\\n /**\\n * @dev Returns the amount of tokens in existence.\\n */\\n function totalSupply() external view returns (uint256);\\n\\n /**\\n * @dev Returns the amount of tokens owned by `account`.\\n */\\n function balanceOf(address account) external view returns (uint256);\\n\\n /**\\n * @dev Moves `amount` tokens from the caller's account to `to`.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * Emits a {Transfer} event.\\n */\\n function transfer(address to, uint256 amount) external returns (bool);\\n\\n /**\\n * @dev Returns the remaining number of tokens that `spender` will be\\n * allowed to spend on behalf of `owner` through {transferFrom}. This is\\n * zero by default.\\n *\\n * This value changes when {approve} or {transferFrom} are called.\\n */\\n function allowance(address owner, address spender) external view returns (uint256);\\n\\n /**\\n * @dev Sets `amount` as the allowance of `spender` over the caller's tokens.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * IMPORTANT: Beware that changing an allowance with this method brings the risk\\n * that someone may use both the old and the new allowance by unfortunate\\n * transaction ordering. One possible solution to mitigate this race\\n * condition is to first reduce the spender's allowance to 0 and set the\\n * desired value afterwards:\\n * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729\\n *\\n * Emits an {Approval} event.\\n */\\n function approve(address spender, uint256 amount) external returns (bool);\\n\\n /**\\n * @dev Moves `amount` tokens from `from` to `to` using the\\n * allowance mechanism. `amount` is then deducted from the caller's\\n * allowance.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * Emits a {Transfer} event.\\n */\\n function transferFrom(\\n address from,\\n address to,\\n uint256 amount\\n ) external returns (bool);\\n}\\n\",\"keccak256\":\"0x4e733d3164f73f461eaf9d8087a7ad1ea180bdc8ba0d3d61b0e1ae16d8e63dff\",\"license\":\"MIT\"},\"@openzeppelin/contracts-upgradeable/token/ERC20/extensions/IERC20MetadataUpgradeable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (token/ERC20/extensions/IERC20Metadata.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../IERC20Upgradeable.sol\\\";\\n\\n/**\\n * @dev Interface for the optional metadata functions from the ERC20 standard.\\n *\\n * _Available since v4.1._\\n */\\ninterface IERC20MetadataUpgradeable is IERC20Upgradeable {\\n /**\\n * @dev Returns the name of the token.\\n */\\n function name() external view returns (string memory);\\n\\n /**\\n * @dev Returns the symbol of the token.\\n */\\n function symbol() external view returns (string memory);\\n\\n /**\\n * @dev Returns the decimals places of the token.\\n */\\n function decimals() external view returns (uint8);\\n}\\n\",\"keccak256\":\"0x605434219ebbe4653f703640f06969faa5a1d78f0bfef878e5ddbb1ca369ceeb\",\"license\":\"MIT\"},\"@openzeppelin/contracts-upgradeable/token/ERC20/extensions/draft-ERC20PermitUpgradeable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.6.0) (token/ERC20/extensions/draft-ERC20Permit.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"./draft-IERC20PermitUpgradeable.sol\\\";\\nimport \\\"../ERC20Upgradeable.sol\\\";\\nimport \\\"../../../utils/cryptography/draft-EIP712Upgradeable.sol\\\";\\nimport \\\"../../../utils/cryptography/ECDSAUpgradeable.sol\\\";\\nimport \\\"../../../utils/CountersUpgradeable.sol\\\";\\nimport \\\"../../../proxy/utils/Initializable.sol\\\";\\n\\n/**\\n * @dev Implementation of the ERC20 Permit extension allowing approvals to be made via signatures, as defined in\\n * https://eips.ethereum.org/EIPS/eip-2612[EIP-2612].\\n *\\n * Adds the {permit} method, which can be used to change an account's ERC20 allowance (see {IERC20-allowance}) by\\n * presenting a message signed by the account. By not relying on `{IERC20-approve}`, the token holder account doesn't\\n * need to send a transaction, and thus is not required to hold Ether at all.\\n *\\n * _Available since v3.4._\\n *\\n * @custom:storage-size 51\\n */\\nabstract contract ERC20PermitUpgradeable is Initializable, ERC20Upgradeable, IERC20PermitUpgradeable, EIP712Upgradeable {\\n using CountersUpgradeable for CountersUpgradeable.Counter;\\n\\n mapping(address => CountersUpgradeable.Counter) private _nonces;\\n\\n // solhint-disable-next-line var-name-mixedcase\\n bytes32 private constant _PERMIT_TYPEHASH =\\n keccak256(\\\"Permit(address owner,address spender,uint256 value,uint256 nonce,uint256 deadline)\\\");\\n /**\\n * @dev In previous versions `_PERMIT_TYPEHASH` was declared as `immutable`.\\n * However, to ensure consistency with the upgradeable transpiler, we will continue\\n * to reserve a slot.\\n * @custom:oz-renamed-from _PERMIT_TYPEHASH\\n */\\n // solhint-disable-next-line var-name-mixedcase\\n bytes32 private _PERMIT_TYPEHASH_DEPRECATED_SLOT;\\n\\n /**\\n * @dev Initializes the {EIP712} domain separator using the `name` parameter, and setting `version` to `\\\"1\\\"`.\\n *\\n * It's a good idea to use the same `name` that is defined as the ERC20 token name.\\n */\\n function __ERC20Permit_init(string memory name) internal onlyInitializing {\\n __EIP712_init_unchained(name, \\\"1\\\");\\n }\\n\\n function __ERC20Permit_init_unchained(string memory) internal onlyInitializing {}\\n\\n /**\\n * @dev See {IERC20Permit-permit}.\\n */\\n function permit(\\n address owner,\\n address spender,\\n uint256 value,\\n uint256 deadline,\\n uint8 v,\\n bytes32 r,\\n bytes32 s\\n ) public virtual override {\\n require(block.timestamp <= deadline, \\\"ERC20Permit: expired deadline\\\");\\n\\n bytes32 structHash = keccak256(abi.encode(_PERMIT_TYPEHASH, owner, spender, value, _useNonce(owner), deadline));\\n\\n bytes32 hash = _hashTypedDataV4(structHash);\\n\\n address signer = ECDSAUpgradeable.recover(hash, v, r, s);\\n require(signer == owner, \\\"ERC20Permit: invalid signature\\\");\\n\\n _approve(owner, spender, value);\\n }\\n\\n /**\\n * @dev See {IERC20Permit-nonces}.\\n */\\n function nonces(address owner) public view virtual override returns (uint256) {\\n return _nonces[owner].current();\\n }\\n\\n /**\\n * @dev See {IERC20Permit-DOMAIN_SEPARATOR}.\\n */\\n // solhint-disable-next-line func-name-mixedcase\\n function DOMAIN_SEPARATOR() external view override returns (bytes32) {\\n return _domainSeparatorV4();\\n }\\n\\n /**\\n * @dev \\\"Consume a nonce\\\": return the current value and increment.\\n *\\n * _Available since v4.1._\\n */\\n function _useNonce(address owner) internal virtual returns (uint256 current) {\\n CountersUpgradeable.Counter storage nonce = _nonces[owner];\\n current = nonce.current();\\n nonce.increment();\\n }\\n\\n /**\\n * @dev This empty reserved space is put in place to allow future versions to add new\\n * variables without shifting down storage in the inheritance chain.\\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\\n */\\n uint256[49] private __gap;\\n}\\n\",\"keccak256\":\"0x564385ebed633694decce3e13d687f3ac7e8eaef64f7a504bfb3f03ad210601f\",\"license\":\"MIT\"},\"@openzeppelin/contracts-upgradeable/token/ERC20/extensions/draft-IERC20PermitUpgradeable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (token/ERC20/extensions/draft-IERC20Permit.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Interface of the ERC20 Permit extension allowing approvals to be made via signatures, as defined in\\n * https://eips.ethereum.org/EIPS/eip-2612[EIP-2612].\\n *\\n * Adds the {permit} method, which can be used to change an account's ERC20 allowance (see {IERC20-allowance}) by\\n * presenting a message signed by the account. By not relying on {IERC20-approve}, the token holder account doesn't\\n * need to send a transaction, and thus is not required to hold Ether at all.\\n */\\ninterface IERC20PermitUpgradeable {\\n /**\\n * @dev Sets `value` as the allowance of `spender` over ``owner``'s tokens,\\n * given ``owner``'s signed approval.\\n *\\n * IMPORTANT: The same issues {IERC20-approve} has related to transaction\\n * ordering also apply here.\\n *\\n * Emits an {Approval} event.\\n *\\n * Requirements:\\n *\\n * - `spender` cannot be the zero address.\\n * - `deadline` must be a timestamp in the future.\\n * - `v`, `r` and `s` must be a valid `secp256k1` signature from `owner`\\n * over the EIP712-formatted function arguments.\\n * - the signature must use ``owner``'s current nonce (see {nonces}).\\n *\\n * For more information on the signature format, see the\\n * https://eips.ethereum.org/EIPS/eip-2612#specification[relevant EIP\\n * section].\\n */\\n function permit(\\n address owner,\\n address spender,\\n uint256 value,\\n uint256 deadline,\\n uint8 v,\\n bytes32 r,\\n bytes32 s\\n ) external;\\n\\n /**\\n * @dev Returns the current nonce for `owner`. This value must be\\n * included whenever a signature is generated for {permit}.\\n *\\n * Every successful call to {permit} increases ``owner``'s nonce by one. This\\n * prevents a signature from being used multiple times.\\n */\\n function nonces(address owner) external view returns (uint256);\\n\\n /**\\n * @dev Returns the domain separator used in the encoding of the signature for {permit}, as defined by {EIP712}.\\n */\\n // solhint-disable-next-line func-name-mixedcase\\n function DOMAIN_SEPARATOR() external view returns (bytes32);\\n}\\n\",\"keccak256\":\"0xcc70d8e2281fb3ff69e8ab242500f10142cd0a7fa8dd9e45882be270d4d09024\",\"license\":\"MIT\"},\"@openzeppelin/contracts-upgradeable/utils/AddressUpgradeable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.7.0) (utils/Address.sol)\\n\\npragma solidity ^0.8.1;\\n\\n/**\\n * @dev Collection of functions related to the address type\\n */\\nlibrary AddressUpgradeable {\\n /**\\n * @dev Returns true if `account` is a contract.\\n *\\n * [IMPORTANT]\\n * ====\\n * It is unsafe to assume that an address for which this function returns\\n * false is an externally-owned account (EOA) and not a contract.\\n *\\n * Among others, `isContract` will return false for the following\\n * types of addresses:\\n *\\n * - an externally-owned account\\n * - a contract in construction\\n * - an address where a contract will be created\\n * - an address where a contract lived, but was destroyed\\n * ====\\n *\\n * [IMPORTANT]\\n * ====\\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\\n *\\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\\n * constructor.\\n * ====\\n */\\n function isContract(address account) internal view returns (bool) {\\n // This method relies on extcodesize/address.code.length, which returns 0\\n // for contracts in construction, since the code is only stored at the end\\n // of the constructor execution.\\n\\n return account.code.length > 0;\\n }\\n\\n /**\\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\\n * `recipient`, forwarding all available gas and reverting on errors.\\n *\\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\\n * imposed by `transfer`, making them unable to receive funds via\\n * `transfer`. {sendValue} removes this limitation.\\n *\\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\\n *\\n * IMPORTANT: because control is transferred to `recipient`, care must be\\n * taken to not create reentrancy vulnerabilities. Consider using\\n * {ReentrancyGuard} or the\\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\\n */\\n function sendValue(address payable recipient, uint256 amount) internal {\\n require(address(this).balance >= amount, \\\"Address: insufficient balance\\\");\\n\\n (bool success, ) = recipient.call{value: amount}(\\\"\\\");\\n require(success, \\\"Address: unable to send value, recipient may have reverted\\\");\\n }\\n\\n /**\\n * @dev Performs a Solidity function call using a low level `call`. A\\n * plain `call` is an unsafe replacement for a function call: use this\\n * function instead.\\n *\\n * If `target` reverts with a revert reason, it is bubbled up by this\\n * function (like regular Solidity function calls).\\n *\\n * Returns the raw returned data. To convert to the expected return value,\\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\\n *\\n * Requirements:\\n *\\n * - `target` must be a contract.\\n * - calling `target` with `data` must not revert.\\n *\\n * _Available since v3.1._\\n */\\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\\n return functionCall(target, data, \\\"Address: low-level call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\\n * `errorMessage` as a fallback revert reason when `target` reverts.\\n *\\n * _Available since v3.1._\\n */\\n function functionCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n return functionCallWithValue(target, data, 0, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but also transferring `value` wei to `target`.\\n *\\n * Requirements:\\n *\\n * - the calling contract must have an ETH balance of at least `value`.\\n * - the called Solidity function must be `payable`.\\n *\\n * _Available since v3.1._\\n */\\n function functionCallWithValue(\\n address target,\\n bytes memory data,\\n uint256 value\\n ) internal returns (bytes memory) {\\n return functionCallWithValue(target, data, value, \\\"Address: low-level call with value failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\\n * with `errorMessage` as a fallback revert reason when `target` reverts.\\n *\\n * _Available since v3.1._\\n */\\n function functionCallWithValue(\\n address target,\\n bytes memory data,\\n uint256 value,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n require(address(this).balance >= value, \\\"Address: insufficient balance for call\\\");\\n require(isContract(target), \\\"Address: call to non-contract\\\");\\n\\n (bool success, bytes memory returndata) = target.call{value: value}(data);\\n return verifyCallResult(success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but performing a static call.\\n *\\n * _Available since v3.3._\\n */\\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\\n return functionStaticCall(target, data, \\\"Address: low-level static call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\\n * but performing a static call.\\n *\\n * _Available since v3.3._\\n */\\n function functionStaticCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal view returns (bytes memory) {\\n require(isContract(target), \\\"Address: static call to non-contract\\\");\\n\\n (bool success, bytes memory returndata) = target.staticcall(data);\\n return verifyCallResult(success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the\\n * revert reason using the provided one.\\n *\\n * _Available since v4.3._\\n */\\n function verifyCallResult(\\n bool success,\\n bytes memory returndata,\\n string memory errorMessage\\n ) internal pure returns (bytes memory) {\\n if (success) {\\n return returndata;\\n } else {\\n // Look for revert reason and bubble it up if present\\n if (returndata.length > 0) {\\n // The easiest way to bubble the revert reason is using memory via assembly\\n /// @solidity memory-safe-assembly\\n assembly {\\n let returndata_size := mload(returndata)\\n revert(add(32, returndata), returndata_size)\\n }\\n } else {\\n revert(errorMessage);\\n }\\n }\\n }\\n}\\n\",\"keccak256\":\"0x611aa3f23e59cfdd1863c536776407b3e33d695152a266fa7cfb34440a29a8a3\",\"license\":\"MIT\"},\"@openzeppelin/contracts-upgradeable/utils/ContextUpgradeable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)\\n\\npragma solidity ^0.8.0;\\nimport \\\"../proxy/utils/Initializable.sol\\\";\\n\\n/**\\n * @dev Provides information about the current execution context, including the\\n * sender of the transaction and its data. While these are generally available\\n * via msg.sender and msg.data, they should not be accessed in such a direct\\n * manner, since when dealing with meta-transactions the account sending and\\n * paying for execution may not be the actual sender (as far as an application\\n * is concerned).\\n *\\n * This contract is only required for intermediate, library-like contracts.\\n */\\nabstract contract ContextUpgradeable is Initializable {\\n function __Context_init() internal onlyInitializing {\\n }\\n\\n function __Context_init_unchained() internal onlyInitializing {\\n }\\n function _msgSender() internal view virtual returns (address) {\\n return msg.sender;\\n }\\n\\n function _msgData() internal view virtual returns (bytes calldata) {\\n return msg.data;\\n }\\n\\n /**\\n * @dev This empty reserved space is put in place to allow future versions to add new\\n * variables without shifting down storage in the inheritance chain.\\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\\n */\\n uint256[50] private __gap;\\n}\\n\",\"keccak256\":\"0x963ea7f0b48b032eef72fe3a7582edf78408d6f834115b9feadd673a4d5bd149\",\"license\":\"MIT\"},\"@openzeppelin/contracts-upgradeable/utils/CountersUpgradeable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (utils/Counters.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @title Counters\\n * @author Matt Condon (@shrugs)\\n * @dev Provides counters that can only be incremented, decremented or reset. This can be used e.g. to track the number\\n * of elements in a mapping, issuing ERC721 ids, or counting request ids.\\n *\\n * Include with `using Counters for Counters.Counter;`\\n */\\nlibrary CountersUpgradeable {\\n struct Counter {\\n // This variable should never be directly accessed by users of the library: interactions must be restricted to\\n // the library's function. As of Solidity v0.5.2, this cannot be enforced, though there is a proposal to add\\n // this feature: see https://github.com/ethereum/solidity/issues/4637\\n uint256 _value; // default: 0\\n }\\n\\n function current(Counter storage counter) internal view returns (uint256) {\\n return counter._value;\\n }\\n\\n function increment(Counter storage counter) internal {\\n unchecked {\\n counter._value += 1;\\n }\\n }\\n\\n function decrement(Counter storage counter) internal {\\n uint256 value = counter._value;\\n require(value > 0, \\\"Counter: decrement overflow\\\");\\n unchecked {\\n counter._value = value - 1;\\n }\\n }\\n\\n function reset(Counter storage counter) internal {\\n counter._value = 0;\\n }\\n}\\n\",\"keccak256\":\"0x798741e231b22b81e2dd2eddaaf8832dee4baf5cd8e2dbaa5c1dd12a1c053c4d\",\"license\":\"MIT\"},\"@openzeppelin/contracts-upgradeable/utils/StringsUpgradeable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.7.0) (utils/Strings.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev String operations.\\n */\\nlibrary StringsUpgradeable {\\n bytes16 private constant _HEX_SYMBOLS = \\\"0123456789abcdef\\\";\\n uint8 private constant _ADDRESS_LENGTH = 20;\\n\\n /**\\n * @dev Converts a `uint256` to its ASCII `string` decimal representation.\\n */\\n function toString(uint256 value) internal pure returns (string memory) {\\n // Inspired by OraclizeAPI's implementation - MIT licence\\n // https://github.com/oraclize/ethereum-api/blob/b42146b063c7d6ee1358846c198246239e9360e8/oraclizeAPI_0.4.25.sol\\n\\n if (value == 0) {\\n return \\\"0\\\";\\n }\\n uint256 temp = value;\\n uint256 digits;\\n while (temp != 0) {\\n digits++;\\n temp /= 10;\\n }\\n bytes memory buffer = new bytes(digits);\\n while (value != 0) {\\n digits -= 1;\\n buffer[digits] = bytes1(uint8(48 + uint256(value % 10)));\\n value /= 10;\\n }\\n return string(buffer);\\n }\\n\\n /**\\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation.\\n */\\n function toHexString(uint256 value) internal pure returns (string memory) {\\n if (value == 0) {\\n return \\\"0x00\\\";\\n }\\n uint256 temp = value;\\n uint256 length = 0;\\n while (temp != 0) {\\n length++;\\n temp >>= 8;\\n }\\n return toHexString(value, length);\\n }\\n\\n /**\\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length.\\n */\\n function toHexString(uint256 value, uint256 length) internal pure returns (string memory) {\\n bytes memory buffer = new bytes(2 * length + 2);\\n buffer[0] = \\\"0\\\";\\n buffer[1] = \\\"x\\\";\\n for (uint256 i = 2 * length + 1; i > 1; --i) {\\n buffer[i] = _HEX_SYMBOLS[value & 0xf];\\n value >>= 4;\\n }\\n require(value == 0, \\\"Strings: hex length insufficient\\\");\\n return string(buffer);\\n }\\n\\n /**\\n * @dev Converts an `address` with fixed length of 20 bytes to its not checksummed ASCII `string` hexadecimal representation.\\n */\\n function toHexString(address addr) internal pure returns (string memory) {\\n return toHexString(uint256(uint160(addr)), _ADDRESS_LENGTH);\\n }\\n}\\n\",\"keccak256\":\"0xea5339a7fff0ed42b45be56a88efdd0b2ddde9fa480dc99fef9a6a4c5b776863\",\"license\":\"MIT\"},\"@openzeppelin/contracts-upgradeable/utils/cryptography/ECDSAUpgradeable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.7.0) (utils/cryptography/ECDSA.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../StringsUpgradeable.sol\\\";\\n\\n/**\\n * @dev Elliptic Curve Digital Signature Algorithm (ECDSA) operations.\\n *\\n * These functions can be used to verify that a message was signed by the holder\\n * of the private keys of a given address.\\n */\\nlibrary ECDSAUpgradeable {\\n enum RecoverError {\\n NoError,\\n InvalidSignature,\\n InvalidSignatureLength,\\n InvalidSignatureS,\\n InvalidSignatureV\\n }\\n\\n function _throwError(RecoverError error) private pure {\\n if (error == RecoverError.NoError) {\\n return; // no error: do nothing\\n } else if (error == RecoverError.InvalidSignature) {\\n revert(\\\"ECDSA: invalid signature\\\");\\n } else if (error == RecoverError.InvalidSignatureLength) {\\n revert(\\\"ECDSA: invalid signature length\\\");\\n } else if (error == RecoverError.InvalidSignatureS) {\\n revert(\\\"ECDSA: invalid signature 's' value\\\");\\n } else if (error == RecoverError.InvalidSignatureV) {\\n revert(\\\"ECDSA: invalid signature 'v' value\\\");\\n }\\n }\\n\\n /**\\n * @dev Returns the address that signed a hashed message (`hash`) with\\n * `signature` or error string. This address can then be used for verification purposes.\\n *\\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\\n * this function rejects them by requiring the `s` value to be in the lower\\n * half order, and the `v` value to be either 27 or 28.\\n *\\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\\n * verification to be secure: it is possible to craft signatures that\\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\\n * this is by receiving a hash of the original message (which may otherwise\\n * be too long), and then calling {toEthSignedMessageHash} on it.\\n *\\n * Documentation for signature generation:\\n * - with https://web3js.readthedocs.io/en/v1.3.4/web3-eth-accounts.html#sign[Web3.js]\\n * - with https://docs.ethers.io/v5/api/signer/#Signer-signMessage[ethers]\\n *\\n * _Available since v4.3._\\n */\\n function tryRecover(bytes32 hash, bytes memory signature) internal pure returns (address, RecoverError) {\\n // Check the signature length\\n // - case 65: r,s,v signature (standard)\\n // - case 64: r,vs signature (cf https://eips.ethereum.org/EIPS/eip-2098) _Available since v4.1._\\n if (signature.length == 65) {\\n bytes32 r;\\n bytes32 s;\\n uint8 v;\\n // ecrecover takes the signature parameters, and the only way to get them\\n // currently is to use assembly.\\n /// @solidity memory-safe-assembly\\n assembly {\\n r := mload(add(signature, 0x20))\\n s := mload(add(signature, 0x40))\\n v := byte(0, mload(add(signature, 0x60)))\\n }\\n return tryRecover(hash, v, r, s);\\n } else if (signature.length == 64) {\\n bytes32 r;\\n bytes32 vs;\\n // ecrecover takes the signature parameters, and the only way to get them\\n // currently is to use assembly.\\n /// @solidity memory-safe-assembly\\n assembly {\\n r := mload(add(signature, 0x20))\\n vs := mload(add(signature, 0x40))\\n }\\n return tryRecover(hash, r, vs);\\n } else {\\n return (address(0), RecoverError.InvalidSignatureLength);\\n }\\n }\\n\\n /**\\n * @dev Returns the address that signed a hashed message (`hash`) with\\n * `signature`. This address can then be used for verification purposes.\\n *\\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\\n * this function rejects them by requiring the `s` value to be in the lower\\n * half order, and the `v` value to be either 27 or 28.\\n *\\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\\n * verification to be secure: it is possible to craft signatures that\\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\\n * this is by receiving a hash of the original message (which may otherwise\\n * be too long), and then calling {toEthSignedMessageHash} on it.\\n */\\n function recover(bytes32 hash, bytes memory signature) internal pure returns (address) {\\n (address recovered, RecoverError error) = tryRecover(hash, signature);\\n _throwError(error);\\n return recovered;\\n }\\n\\n /**\\n * @dev Overload of {ECDSA-tryRecover} that receives the `r` and `vs` short-signature fields separately.\\n *\\n * See https://eips.ethereum.org/EIPS/eip-2098[EIP-2098 short signatures]\\n *\\n * _Available since v4.3._\\n */\\n function tryRecover(\\n bytes32 hash,\\n bytes32 r,\\n bytes32 vs\\n ) internal pure returns (address, RecoverError) {\\n bytes32 s = vs & bytes32(0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff);\\n uint8 v = uint8((uint256(vs) >> 255) + 27);\\n return tryRecover(hash, v, r, s);\\n }\\n\\n /**\\n * @dev Overload of {ECDSA-recover} that receives the `r and `vs` short-signature fields separately.\\n *\\n * _Available since v4.2._\\n */\\n function recover(\\n bytes32 hash,\\n bytes32 r,\\n bytes32 vs\\n ) internal pure returns (address) {\\n (address recovered, RecoverError error) = tryRecover(hash, r, vs);\\n _throwError(error);\\n return recovered;\\n }\\n\\n /**\\n * @dev Overload of {ECDSA-tryRecover} that receives the `v`,\\n * `r` and `s` signature fields separately.\\n *\\n * _Available since v4.3._\\n */\\n function tryRecover(\\n bytes32 hash,\\n uint8 v,\\n bytes32 r,\\n bytes32 s\\n ) internal pure returns (address, RecoverError) {\\n // EIP-2 still allows signature malleability for ecrecover(). Remove this possibility and make the signature\\n // unique. Appendix F in the Ethereum Yellow paper (https://ethereum.github.io/yellowpaper/paper.pdf), defines\\n // the valid range for s in (301): 0 < s < secp256k1n \\u00f7 2 + 1, and for v in (302): v \\u2208 {27, 28}. Most\\n // signatures from current libraries generate a unique signature with an s-value in the lower half order.\\n //\\n // If your library generates malleable signatures, such as s-values in the upper range, calculate a new s-value\\n // with 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141 - s1 and flip v from 27 to 28 or\\n // vice versa. If your library also generates signatures with 0/1 for v instead 27/28, add 27 to v to accept\\n // these malleable signatures as well.\\n if (uint256(s) > 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D576E7357A4501DDFE92F46681B20A0) {\\n return (address(0), RecoverError.InvalidSignatureS);\\n }\\n if (v != 27 && v != 28) {\\n return (address(0), RecoverError.InvalidSignatureV);\\n }\\n\\n // If the signature is valid (and not malleable), return the signer address\\n address signer = ecrecover(hash, v, r, s);\\n if (signer == address(0)) {\\n return (address(0), RecoverError.InvalidSignature);\\n }\\n\\n return (signer, RecoverError.NoError);\\n }\\n\\n /**\\n * @dev Overload of {ECDSA-recover} that receives the `v`,\\n * `r` and `s` signature fields separately.\\n */\\n function recover(\\n bytes32 hash,\\n uint8 v,\\n bytes32 r,\\n bytes32 s\\n ) internal pure returns (address) {\\n (address recovered, RecoverError error) = tryRecover(hash, v, r, s);\\n _throwError(error);\\n return recovered;\\n }\\n\\n /**\\n * @dev Returns an Ethereum Signed Message, created from a `hash`. This\\n * produces hash corresponding to the one signed with the\\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\\n * JSON-RPC method as part of EIP-191.\\n *\\n * See {recover}.\\n */\\n function toEthSignedMessageHash(bytes32 hash) internal pure returns (bytes32) {\\n // 32 is the length in bytes of hash,\\n // enforced by the type signature above\\n return keccak256(abi.encodePacked(\\\"\\\\x19Ethereum Signed Message:\\\\n32\\\", hash));\\n }\\n\\n /**\\n * @dev Returns an Ethereum Signed Message, created from `s`. This\\n * produces hash corresponding to the one signed with the\\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\\n * JSON-RPC method as part of EIP-191.\\n *\\n * See {recover}.\\n */\\n function toEthSignedMessageHash(bytes memory s) internal pure returns (bytes32) {\\n return keccak256(abi.encodePacked(\\\"\\\\x19Ethereum Signed Message:\\\\n\\\", StringsUpgradeable.toString(s.length), s));\\n }\\n\\n /**\\n * @dev Returns an Ethereum Signed Typed Data, created from a\\n * `domainSeparator` and a `structHash`. This produces hash corresponding\\n * to the one signed with the\\n * https://eips.ethereum.org/EIPS/eip-712[`eth_signTypedData`]\\n * JSON-RPC method as part of EIP-712.\\n *\\n * See {recover}.\\n */\\n function toTypedDataHash(bytes32 domainSeparator, bytes32 structHash) internal pure returns (bytes32) {\\n return keccak256(abi.encodePacked(\\\"\\\\x19\\\\x01\\\", domainSeparator, structHash));\\n }\\n}\\n\",\"keccak256\":\"0xe8c62ca00ed2d0a4d9b7e3c4bf7d62c821618b2cdb3c844da91a1193986851bf\",\"license\":\"MIT\"},\"@openzeppelin/contracts-upgradeable/utils/cryptography/draft-EIP712Upgradeable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (utils/cryptography/draft-EIP712.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"./ECDSAUpgradeable.sol\\\";\\nimport \\\"../../proxy/utils/Initializable.sol\\\";\\n\\n/**\\n * @dev https://eips.ethereum.org/EIPS/eip-712[EIP 712] is a standard for hashing and signing of typed structured data.\\n *\\n * The encoding specified in the EIP is very generic, and such a generic implementation in Solidity is not feasible,\\n * thus this contract does not implement the encoding itself. Protocols need to implement the type-specific encoding\\n * they need in their contracts using a combination of `abi.encode` and `keccak256`.\\n *\\n * This contract implements the EIP 712 domain separator ({_domainSeparatorV4}) that is used as part of the encoding\\n * scheme, and the final step of the encoding to obtain the message digest that is then signed via ECDSA\\n * ({_hashTypedDataV4}).\\n *\\n * The implementation of the domain separator was designed to be as efficient as possible while still properly updating\\n * the chain id to protect against replay attacks on an eventual fork of the chain.\\n *\\n * NOTE: This contract implements the version of the encoding known as \\\"v4\\\", as implemented by the JSON RPC method\\n * https://docs.metamask.io/guide/signing-data.html[`eth_signTypedDataV4` in MetaMask].\\n *\\n * _Available since v3.4._\\n *\\n * @custom:storage-size 52\\n */\\nabstract contract EIP712Upgradeable is Initializable {\\n /* solhint-disable var-name-mixedcase */\\n bytes32 private _HASHED_NAME;\\n bytes32 private _HASHED_VERSION;\\n bytes32 private constant _TYPE_HASH = keccak256(\\\"EIP712Domain(string name,string version,uint256 chainId,address verifyingContract)\\\");\\n\\n /* solhint-enable var-name-mixedcase */\\n\\n /**\\n * @dev Initializes the domain separator and parameter caches.\\n *\\n * The meaning of `name` and `version` is specified in\\n * https://eips.ethereum.org/EIPS/eip-712#definition-of-domainseparator[EIP 712]:\\n *\\n * - `name`: the user readable name of the signing domain, i.e. the name of the DApp or the protocol.\\n * - `version`: the current major version of the signing domain.\\n *\\n * NOTE: These parameters cannot be changed except through a xref:learn::upgrading-smart-contracts.adoc[smart\\n * contract upgrade].\\n */\\n function __EIP712_init(string memory name, string memory version) internal onlyInitializing {\\n __EIP712_init_unchained(name, version);\\n }\\n\\n function __EIP712_init_unchained(string memory name, string memory version) internal onlyInitializing {\\n bytes32 hashedName = keccak256(bytes(name));\\n bytes32 hashedVersion = keccak256(bytes(version));\\n _HASHED_NAME = hashedName;\\n _HASHED_VERSION = hashedVersion;\\n }\\n\\n /**\\n * @dev Returns the domain separator for the current chain.\\n */\\n function _domainSeparatorV4() internal view returns (bytes32) {\\n return _buildDomainSeparator(_TYPE_HASH, _EIP712NameHash(), _EIP712VersionHash());\\n }\\n\\n function _buildDomainSeparator(\\n bytes32 typeHash,\\n bytes32 nameHash,\\n bytes32 versionHash\\n ) private view returns (bytes32) {\\n return keccak256(abi.encode(typeHash, nameHash, versionHash, block.chainid, address(this)));\\n }\\n\\n /**\\n * @dev Given an already https://eips.ethereum.org/EIPS/eip-712#definition-of-hashstruct[hashed struct], this\\n * function returns the hash of the fully encoded EIP712 message for this domain.\\n *\\n * This hash can be used together with {ECDSA-recover} to obtain the signer of a message. For example:\\n *\\n * ```solidity\\n * bytes32 digest = _hashTypedDataV4(keccak256(abi.encode(\\n * keccak256(\\\"Mail(address to,string contents)\\\"),\\n * mailTo,\\n * keccak256(bytes(mailContents))\\n * )));\\n * address signer = ECDSA.recover(digest, signature);\\n * ```\\n */\\n function _hashTypedDataV4(bytes32 structHash) internal view virtual returns (bytes32) {\\n return ECDSAUpgradeable.toTypedDataHash(_domainSeparatorV4(), structHash);\\n }\\n\\n /**\\n * @dev The hash of the name parameter for the EIP712 domain.\\n *\\n * NOTE: This function reads from storage by default, but can be redefined to return a constant value if gas costs\\n * are a concern.\\n */\\n function _EIP712NameHash() internal virtual view returns (bytes32) {\\n return _HASHED_NAME;\\n }\\n\\n /**\\n * @dev The hash of the version parameter for the EIP712 domain.\\n *\\n * NOTE: This function reads from storage by default, but can be redefined to return a constant value if gas costs\\n * are a concern.\\n */\\n function _EIP712VersionHash() internal virtual view returns (bytes32) {\\n return _HASHED_VERSION;\\n }\\n\\n /**\\n * @dev This empty reserved space is put in place to allow future versions to add new\\n * variables without shifting down storage in the inheritance chain.\\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\\n */\\n uint256[50] private __gap;\\n}\\n\",\"keccak256\":\"0xaf5a96100f421d61693605349511e43221d3c2e47d4b3efa87af2b936e2567fc\",\"license\":\"MIT\"},\"@openzeppelin/contracts/token/ERC20/IERC20.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.6.0) (token/ERC20/IERC20.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Interface of the ERC20 standard as defined in the EIP.\\n */\\ninterface IERC20 {\\n /**\\n * @dev Emitted when `value` tokens are moved from one account (`from`) to\\n * another (`to`).\\n *\\n * Note that `value` may be zero.\\n */\\n event Transfer(address indexed from, address indexed to, uint256 value);\\n\\n /**\\n * @dev Emitted when the allowance of a `spender` for an `owner` is set by\\n * a call to {approve}. `value` is the new allowance.\\n */\\n event Approval(address indexed owner, address indexed spender, uint256 value);\\n\\n /**\\n * @dev Returns the amount of tokens in existence.\\n */\\n function totalSupply() external view returns (uint256);\\n\\n /**\\n * @dev Returns the amount of tokens owned by `account`.\\n */\\n function balanceOf(address account) external view returns (uint256);\\n\\n /**\\n * @dev Moves `amount` tokens from the caller's account to `to`.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * Emits a {Transfer} event.\\n */\\n function transfer(address to, uint256 amount) external returns (bool);\\n\\n /**\\n * @dev Returns the remaining number of tokens that `spender` will be\\n * allowed to spend on behalf of `owner` through {transferFrom}. This is\\n * zero by default.\\n *\\n * This value changes when {approve} or {transferFrom} are called.\\n */\\n function allowance(address owner, address spender) external view returns (uint256);\\n\\n /**\\n * @dev Sets `amount` as the allowance of `spender` over the caller's tokens.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * IMPORTANT: Beware that changing an allowance with this method brings the risk\\n * that someone may use both the old and the new allowance by unfortunate\\n * transaction ordering. One possible solution to mitigate this race\\n * condition is to first reduce the spender's allowance to 0 and set the\\n * desired value afterwards:\\n * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729\\n *\\n * Emits an {Approval} event.\\n */\\n function approve(address spender, uint256 amount) external returns (bool);\\n\\n /**\\n * @dev Moves `amount` tokens from `from` to `to` using the\\n * allowance mechanism. `amount` is then deducted from the caller's\\n * allowance.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * Emits a {Transfer} event.\\n */\\n function transferFrom(\\n address from,\\n address to,\\n uint256 amount\\n ) external returns (bool);\\n}\\n\",\"keccak256\":\"0x9750c6b834f7b43000631af5cc30001c5f547b3ceb3635488f140f60e897ea6b\",\"license\":\"MIT\"},\"@openzeppelin/contracts/token/ERC20/extensions/draft-IERC20Permit.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (token/ERC20/extensions/draft-IERC20Permit.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Interface of the ERC20 Permit extension allowing approvals to be made via signatures, as defined in\\n * https://eips.ethereum.org/EIPS/eip-2612[EIP-2612].\\n *\\n * Adds the {permit} method, which can be used to change an account's ERC20 allowance (see {IERC20-allowance}) by\\n * presenting a message signed by the account. By not relying on {IERC20-approve}, the token holder account doesn't\\n * need to send a transaction, and thus is not required to hold Ether at all.\\n */\\ninterface IERC20Permit {\\n /**\\n * @dev Sets `value` as the allowance of `spender` over ``owner``'s tokens,\\n * given ``owner``'s signed approval.\\n *\\n * IMPORTANT: The same issues {IERC20-approve} has related to transaction\\n * ordering also apply here.\\n *\\n * Emits an {Approval} event.\\n *\\n * Requirements:\\n *\\n * - `spender` cannot be the zero address.\\n * - `deadline` must be a timestamp in the future.\\n * - `v`, `r` and `s` must be a valid `secp256k1` signature from `owner`\\n * over the EIP712-formatted function arguments.\\n * - the signature must use ``owner``'s current nonce (see {nonces}).\\n *\\n * For more information on the signature format, see the\\n * https://eips.ethereum.org/EIPS/eip-2612#specification[relevant EIP\\n * section].\\n */\\n function permit(\\n address owner,\\n address spender,\\n uint256 value,\\n uint256 deadline,\\n uint8 v,\\n bytes32 r,\\n bytes32 s\\n ) external;\\n\\n /**\\n * @dev Returns the current nonce for `owner`. This value must be\\n * included whenever a signature is generated for {permit}.\\n *\\n * Every successful call to {permit} increases ``owner``'s nonce by one. This\\n * prevents a signature from being used multiple times.\\n */\\n function nonces(address owner) external view returns (uint256);\\n\\n /**\\n * @dev Returns the domain separator used in the encoding of the signature for {permit}, as defined by {EIP712}.\\n */\\n // solhint-disable-next-line func-name-mixedcase\\n function DOMAIN_SEPARATOR() external view returns (bytes32);\\n}\\n\",\"keccak256\":\"0xf41ca991f30855bf80ffd11e9347856a517b977f0a6c2d52e6421a99b7840329\",\"license\":\"MIT\"},\"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.7.0) (token/ERC20/utils/SafeERC20.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../IERC20.sol\\\";\\nimport \\\"../extensions/draft-IERC20Permit.sol\\\";\\nimport \\\"../../../utils/Address.sol\\\";\\n\\n/**\\n * @title SafeERC20\\n * @dev Wrappers around ERC20 operations that throw on failure (when the token\\n * contract returns false). Tokens that return no value (and instead revert or\\n * throw on failure) are also supported, non-reverting calls are assumed to be\\n * successful.\\n * To use this library you can add a `using SafeERC20 for IERC20;` statement to your contract,\\n * which allows you to call the safe operations as `token.safeTransfer(...)`, etc.\\n */\\nlibrary SafeERC20 {\\n using Address for address;\\n\\n function safeTransfer(\\n IERC20 token,\\n address to,\\n uint256 value\\n ) internal {\\n _callOptionalReturn(token, abi.encodeWithSelector(token.transfer.selector, to, value));\\n }\\n\\n function safeTransferFrom(\\n IERC20 token,\\n address from,\\n address to,\\n uint256 value\\n ) internal {\\n _callOptionalReturn(token, abi.encodeWithSelector(token.transferFrom.selector, from, to, value));\\n }\\n\\n /**\\n * @dev Deprecated. This function has issues similar to the ones found in\\n * {IERC20-approve}, and its usage is discouraged.\\n *\\n * Whenever possible, use {safeIncreaseAllowance} and\\n * {safeDecreaseAllowance} instead.\\n */\\n function safeApprove(\\n IERC20 token,\\n address spender,\\n uint256 value\\n ) internal {\\n // safeApprove should only be called when setting an initial allowance,\\n // or when resetting it to zero. To increase and decrease it, use\\n // 'safeIncreaseAllowance' and 'safeDecreaseAllowance'\\n require(\\n (value == 0) || (token.allowance(address(this), spender) == 0),\\n \\\"SafeERC20: approve from non-zero to non-zero allowance\\\"\\n );\\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, value));\\n }\\n\\n function safeIncreaseAllowance(\\n IERC20 token,\\n address spender,\\n uint256 value\\n ) internal {\\n uint256 newAllowance = token.allowance(address(this), spender) + value;\\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));\\n }\\n\\n function safeDecreaseAllowance(\\n IERC20 token,\\n address spender,\\n uint256 value\\n ) internal {\\n unchecked {\\n uint256 oldAllowance = token.allowance(address(this), spender);\\n require(oldAllowance >= value, \\\"SafeERC20: decreased allowance below zero\\\");\\n uint256 newAllowance = oldAllowance - value;\\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));\\n }\\n }\\n\\n function safePermit(\\n IERC20Permit token,\\n address owner,\\n address spender,\\n uint256 value,\\n uint256 deadline,\\n uint8 v,\\n bytes32 r,\\n bytes32 s\\n ) internal {\\n uint256 nonceBefore = token.nonces(owner);\\n token.permit(owner, spender, value, deadline, v, r, s);\\n uint256 nonceAfter = token.nonces(owner);\\n require(nonceAfter == nonceBefore + 1, \\\"SafeERC20: permit did not succeed\\\");\\n }\\n\\n /**\\n * @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement\\n * on the return value: the return value is optional (but if data is returned, it must not be false).\\n * @param token The token targeted by the call.\\n * @param data The call data (encoded using abi.encode or one of its variants).\\n */\\n function _callOptionalReturn(IERC20 token, bytes memory data) private {\\n // We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since\\n // we're implementing it ourselves. We use {Address.functionCall} to perform this call, which verifies that\\n // the target address contains contract code and also asserts for success in the low-level call.\\n\\n bytes memory returndata = address(token).functionCall(data, \\\"SafeERC20: low-level call failed\\\");\\n if (returndata.length > 0) {\\n // Return data is optional\\n require(abi.decode(returndata, (bool)), \\\"SafeERC20: ERC20 operation did not succeed\\\");\\n }\\n }\\n}\\n\",\"keccak256\":\"0x032807210d1d7d218963d7355d62e021a84bf1b3339f4f50be2f63b53cccaf29\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/Address.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.7.0) (utils/Address.sol)\\n\\npragma solidity ^0.8.1;\\n\\n/**\\n * @dev Collection of functions related to the address type\\n */\\nlibrary Address {\\n /**\\n * @dev Returns true if `account` is a contract.\\n *\\n * [IMPORTANT]\\n * ====\\n * It is unsafe to assume that an address for which this function returns\\n * false is an externally-owned account (EOA) and not a contract.\\n *\\n * Among others, `isContract` will return false for the following\\n * types of addresses:\\n *\\n * - an externally-owned account\\n * - a contract in construction\\n * - an address where a contract will be created\\n * - an address where a contract lived, but was destroyed\\n * ====\\n *\\n * [IMPORTANT]\\n * ====\\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\\n *\\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\\n * constructor.\\n * ====\\n */\\n function isContract(address account) internal view returns (bool) {\\n // This method relies on extcodesize/address.code.length, which returns 0\\n // for contracts in construction, since the code is only stored at the end\\n // of the constructor execution.\\n\\n return account.code.length > 0;\\n }\\n\\n /**\\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\\n * `recipient`, forwarding all available gas and reverting on errors.\\n *\\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\\n * imposed by `transfer`, making them unable to receive funds via\\n * `transfer`. {sendValue} removes this limitation.\\n *\\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\\n *\\n * IMPORTANT: because control is transferred to `recipient`, care must be\\n * taken to not create reentrancy vulnerabilities. Consider using\\n * {ReentrancyGuard} or the\\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\\n */\\n function sendValue(address payable recipient, uint256 amount) internal {\\n require(address(this).balance >= amount, \\\"Address: insufficient balance\\\");\\n\\n (bool success, ) = recipient.call{value: amount}(\\\"\\\");\\n require(success, \\\"Address: unable to send value, recipient may have reverted\\\");\\n }\\n\\n /**\\n * @dev Performs a Solidity function call using a low level `call`. A\\n * plain `call` is an unsafe replacement for a function call: use this\\n * function instead.\\n *\\n * If `target` reverts with a revert reason, it is bubbled up by this\\n * function (like regular Solidity function calls).\\n *\\n * Returns the raw returned data. To convert to the expected return value,\\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\\n *\\n * Requirements:\\n *\\n * - `target` must be a contract.\\n * - calling `target` with `data` must not revert.\\n *\\n * _Available since v3.1._\\n */\\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\\n return functionCall(target, data, \\\"Address: low-level call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\\n * `errorMessage` as a fallback revert reason when `target` reverts.\\n *\\n * _Available since v3.1._\\n */\\n function functionCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n return functionCallWithValue(target, data, 0, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but also transferring `value` wei to `target`.\\n *\\n * Requirements:\\n *\\n * - the calling contract must have an ETH balance of at least `value`.\\n * - the called Solidity function must be `payable`.\\n *\\n * _Available since v3.1._\\n */\\n function functionCallWithValue(\\n address target,\\n bytes memory data,\\n uint256 value\\n ) internal returns (bytes memory) {\\n return functionCallWithValue(target, data, value, \\\"Address: low-level call with value failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\\n * with `errorMessage` as a fallback revert reason when `target` reverts.\\n *\\n * _Available since v3.1._\\n */\\n function functionCallWithValue(\\n address target,\\n bytes memory data,\\n uint256 value,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n require(address(this).balance >= value, \\\"Address: insufficient balance for call\\\");\\n require(isContract(target), \\\"Address: call to non-contract\\\");\\n\\n (bool success, bytes memory returndata) = target.call{value: value}(data);\\n return verifyCallResult(success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but performing a static call.\\n *\\n * _Available since v3.3._\\n */\\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\\n return functionStaticCall(target, data, \\\"Address: low-level static call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\\n * but performing a static call.\\n *\\n * _Available since v3.3._\\n */\\n function functionStaticCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal view returns (bytes memory) {\\n require(isContract(target), \\\"Address: static call to non-contract\\\");\\n\\n (bool success, bytes memory returndata) = target.staticcall(data);\\n return verifyCallResult(success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but performing a delegate call.\\n *\\n * _Available since v3.4._\\n */\\n function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {\\n return functionDelegateCall(target, data, \\\"Address: low-level delegate call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\\n * but performing a delegate call.\\n *\\n * _Available since v3.4._\\n */\\n function functionDelegateCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n require(isContract(target), \\\"Address: delegate call to non-contract\\\");\\n\\n (bool success, bytes memory returndata) = target.delegatecall(data);\\n return verifyCallResult(success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the\\n * revert reason using the provided one.\\n *\\n * _Available since v4.3._\\n */\\n function verifyCallResult(\\n bool success,\\n bytes memory returndata,\\n string memory errorMessage\\n ) internal pure returns (bytes memory) {\\n if (success) {\\n return returndata;\\n } else {\\n // Look for revert reason and bubble it up if present\\n if (returndata.length > 0) {\\n // The easiest way to bubble the revert reason is using memory via assembly\\n /// @solidity memory-safe-assembly\\n assembly {\\n let returndata_size := mload(returndata)\\n revert(add(32, returndata), returndata_size)\\n }\\n } else {\\n revert(errorMessage);\\n }\\n }\\n }\\n}\\n\",\"keccak256\":\"0xd6153ce99bcdcce22b124f755e72553295be6abcd63804cfdffceb188b8bef10\",\"license\":\"MIT\"},\"contracts/agToken/AgTokenSideChainMultiBridge.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-3.0\\n\\npragma solidity ^0.8.12;\\n\\nimport \\\"./BaseAgTokenSideChain.sol\\\";\\nimport \\\"@openzeppelin/contracts/token/ERC20/IERC20.sol\\\";\\nimport \\\"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\\\";\\n\\n/// @title AgTokenSideChainMultiBridge\\n/// @author Angle Labs, Inc.\\n/// @notice Contract for Angle agTokens on other chains than Ethereum mainnet\\n/// @dev This contract supports bridge tokens having a minting right on the stablecoin (also referred to as the canonical\\n/// or the native token)\\n/// @dev References:\\n/// - FRAX implementation: https://polygonscan.com/address/0x45c32fA6DF82ead1e2EF74d17b76547EDdFaFF89#code\\n/// - QiDAO implementation: https://snowtrace.io/address/0x5c49b268c9841AFF1Cc3B0a418ff5c3442eE3F3b#code\\ncontract AgTokenSideChainMultiBridge is BaseAgTokenSideChain {\\n using SafeERC20 for IERC20;\\n\\n /// @notice Base used for fee computation\\n uint256 public constant BASE_PARAMS = 10**9;\\n\\n // =============================== Bridging Data ===============================\\n\\n /// @notice Struct with some data about a specific bridge token\\n struct BridgeDetails {\\n // Limit on the balance of bridge token held by the contract: it is designed\\n // to reduce the exposure of the system to hacks\\n uint256 limit;\\n // Limit on the hourly volume of token minted through this bridge\\n // Technically the limit over a rolling hour is hourlyLimit x2 as hourly limit\\n // is enforced only between x:00 and x+1:00\\n uint256 hourlyLimit;\\n // Fee taken for swapping in and out the token\\n uint64 fee;\\n // Whether the associated token is allowed or not\\n bool allowed;\\n // Whether swapping in and out from the associated token is paused or not\\n bool paused;\\n }\\n\\n /// @notice Maps a bridge token to data\\n mapping(address => BridgeDetails) public bridges;\\n /// @notice List of all bridge tokens\\n address[] public bridgeTokensList;\\n /// @notice Maps a bridge token to the associated hourly volume\\n mapping(address => mapping(uint256 => uint256)) public usage;\\n /// @notice Maps an address to whether it is exempt of fees for when it comes to swapping in and out\\n mapping(address => uint256) public isFeeExempt;\\n /// @notice Limit to the amount of tokens that can be sent from that chain to another chain\\n uint256 public chainTotalHourlyLimit;\\n /// @notice Usage per hour on that chain. Maps an hourly timestamp to the total volume swapped out on the chain\\n mapping(uint256 => uint256) public chainTotalUsage;\\n\\n // ================================== Events ===================================\\n\\n event BridgeTokenAdded(address indexed bridgeToken, uint256 limit, uint256 hourlyLimit, uint64 fee, bool paused);\\n event BridgeTokenToggled(address indexed bridgeToken, bool toggleStatus);\\n event BridgeTokenRemoved(address indexed bridgeToken);\\n event BridgeTokenFeeUpdated(address indexed bridgeToken, uint64 fee);\\n event BridgeTokenLimitUpdated(address indexed bridgeToken, uint256 limit);\\n event BridgeTokenHourlyLimitUpdated(address indexed bridgeToken, uint256 hourlyLimit);\\n event HourlyLimitUpdated(uint256 hourlyLimit);\\n event Recovered(address indexed token, address indexed to, uint256 amount);\\n event FeeToggled(address indexed theAddress, uint256 toggleStatus);\\n\\n // =============================== Errors ================================\\n\\n error AssetStillControlledInReserves();\\n error HourlyLimitExceeded();\\n error InvalidToken();\\n error NotGovernor();\\n error NotGovernorOrGuardian();\\n error TooBigAmount();\\n error TooHighParameterValue();\\n error ZeroAddress();\\n\\n // ============================= Constructor ===================================\\n\\n /// @notice Initializes the `AgToken` contract\\n /// @param name_ Name of the token\\n /// @param symbol_ Symbol of the token\\n /// @param _treasury Reference to the `Treasury` contract associated to this agToken\\n /// @dev By default, agTokens are ERC-20 tokens with 18 decimals\\n function initialize(\\n string memory name_,\\n string memory symbol_,\\n address _treasury\\n ) external {\\n _initialize(name_, symbol_, _treasury);\\n }\\n\\n // =============================== Modifiers ===================================\\n\\n /// @notice Checks whether the `msg.sender` has the governor role or not\\n modifier onlyGovernor() {\\n if (!ITreasury(treasury).isGovernor(msg.sender)) revert NotGovernor();\\n _;\\n }\\n\\n /// @notice Checks whether the `msg.sender` has the governor role or the guardian role\\n modifier onlyGovernorOrGuardian() {\\n if (!ITreasury(treasury).isGovernorOrGuardian(msg.sender)) revert NotGovernorOrGuardian();\\n _;\\n }\\n\\n // ==================== External Permissionless Functions ======================\\n\\n /// @notice Returns the list of all supported bridge tokens\\n /// @dev Helpful for UIs\\n function allBridgeTokens() external view returns (address[] memory) {\\n return bridgeTokensList;\\n }\\n\\n /// @notice Returns the current volume for a bridge, for the current hour\\n /// @param bridgeToken Bridge used to mint\\n /// @dev Helpful for UIs\\n function currentUsage(address bridgeToken) external view returns (uint256) {\\n return usage[bridgeToken][block.timestamp / 3600];\\n }\\n\\n /// @notice Returns the current total volume on the chain for the current hour\\n /// @dev Helpful for UIs\\n function currentTotalUsage() external view returns (uint256) {\\n return chainTotalUsage[block.timestamp / 3600];\\n }\\n\\n /// @notice Mints the canonical token from a supported bridge token\\n /// @param bridgeToken Bridge token to use to mint\\n /// @param amount Amount of bridge tokens to send\\n /// @param to Address to which the stablecoin should be sent\\n /// @return Amount of the canonical stablecoin actually minted\\n /// @dev Some fees may be taken by the protocol depending on the token used and on the address calling\\n function swapIn(\\n address bridgeToken,\\n uint256 amount,\\n address to\\n ) external returns (uint256) {\\n BridgeDetails memory bridgeDetails = bridges[bridgeToken];\\n if (!bridgeDetails.allowed || bridgeDetails.paused) revert InvalidToken();\\n uint256 balance = IERC20(bridgeToken).balanceOf(address(this));\\n if (balance + amount > bridgeDetails.limit) {\\n // In case someone maliciously sends tokens to this contract\\n // Or the limit changes\\n if (bridgeDetails.limit > balance) amount = bridgeDetails.limit - balance;\\n else {\\n amount = 0;\\n }\\n }\\n\\n // Checking requirement on the hourly volume\\n uint256 hour = block.timestamp / 3600;\\n uint256 hourlyUsage = usage[bridgeToken][hour];\\n if (hourlyUsage + amount > bridgeDetails.hourlyLimit) {\\n // Edge case when the hourly limit changes\\n amount = bridgeDetails.hourlyLimit > hourlyUsage ? bridgeDetails.hourlyLimit - hourlyUsage : 0;\\n }\\n usage[bridgeToken][hour] = hourlyUsage + amount;\\n\\n IERC20(bridgeToken).safeTransferFrom(msg.sender, address(this), amount);\\n uint256 canonicalOut = amount;\\n // Computing fees\\n if (isFeeExempt[msg.sender] == 0) {\\n canonicalOut -= (canonicalOut * bridgeDetails.fee) / BASE_PARAMS;\\n }\\n _mint(to, canonicalOut);\\n return canonicalOut;\\n }\\n\\n /// @notice Burns the canonical token in exchange for a bridge token\\n /// @param bridgeToken Bridge token required\\n /// @param amount Amount of canonical tokens to burn\\n /// @param to Address to which the bridge token should be sent\\n /// @return Amount of bridge tokens actually sent back\\n /// @dev Some fees may be taken by the protocol depending on the token used and on the address calling\\n function swapOut(\\n address bridgeToken,\\n uint256 amount,\\n address to\\n ) external returns (uint256) {\\n BridgeDetails memory bridgeDetails = bridges[bridgeToken];\\n if (!bridgeDetails.allowed || bridgeDetails.paused) revert InvalidToken();\\n\\n uint256 hour = block.timestamp / 3600;\\n uint256 hourlyUsage = chainTotalUsage[hour] + amount;\\n // If the amount being swapped out exceeds the limit, we revert\\n // We don't want to change the amount being swapped out.\\n // The user can decide to send another tx with the correct amount to reach the limit\\n if (hourlyUsage > chainTotalHourlyLimit) revert HourlyLimitExceeded();\\n chainTotalUsage[hour] = hourlyUsage;\\n\\n _burn(msg.sender, amount);\\n uint256 bridgeOut = amount;\\n if (isFeeExempt[msg.sender] == 0) {\\n bridgeOut -= (bridgeOut * bridgeDetails.fee) / BASE_PARAMS;\\n }\\n IERC20(bridgeToken).safeTransfer(to, bridgeOut);\\n return bridgeOut;\\n }\\n\\n // ======================= Governance Functions ================================\\n\\n /// @notice Adds support for a bridge token\\n /// @param bridgeToken Bridge token to add: it should be a version of the stablecoin from another bridge\\n /// @param limit Limit on the balance of bridge token this contract could hold\\n /// @param hourlyLimit Limit on the hourly volume for this bridge\\n /// @param paused Whether swapping for this token should be paused or not\\n /// @param fee Fee taken upon swapping for or against this token\\n function addBridgeToken(\\n address bridgeToken,\\n uint256 limit,\\n uint256 hourlyLimit,\\n uint64 fee,\\n bool paused\\n ) external onlyGovernor {\\n if (bridges[bridgeToken].allowed || bridgeToken == address(0)) revert InvalidToken();\\n if (fee > BASE_PARAMS) revert TooHighParameterValue();\\n BridgeDetails memory _bridge;\\n _bridge.limit = limit;\\n _bridge.hourlyLimit = hourlyLimit;\\n _bridge.paused = paused;\\n _bridge.fee = fee;\\n _bridge.allowed = true;\\n bridges[bridgeToken] = _bridge;\\n bridgeTokensList.push(bridgeToken);\\n emit BridgeTokenAdded(bridgeToken, limit, hourlyLimit, fee, paused);\\n }\\n\\n /// @notice Removes support for a token\\n /// @param bridgeToken Address of the bridge token to remove support for\\n function removeBridgeToken(address bridgeToken) external onlyGovernor {\\n if (IERC20(bridgeToken).balanceOf(address(this)) != 0) revert AssetStillControlledInReserves();\\n delete bridges[bridgeToken];\\n // Deletion from `bridgeTokensList` loop\\n uint256 bridgeTokensListLength = bridgeTokensList.length;\\n for (uint256 i; i < bridgeTokensListLength - 1; ++i) {\\n if (bridgeTokensList[i] == bridgeToken) {\\n // Replace the `bridgeToken` to remove with the last of the list\\n bridgeTokensList[i] = bridgeTokensList[bridgeTokensListLength - 1];\\n break;\\n }\\n }\\n // Remove last element in array\\n bridgeTokensList.pop();\\n emit BridgeTokenRemoved(bridgeToken);\\n }\\n\\n /// @notice Recovers any ERC20 token\\n /// @dev Can be used to withdraw bridge tokens for them to be de-bridged on mainnet\\n function recoverERC20(\\n address tokenAddress,\\n address to,\\n uint256 amountToRecover\\n ) external onlyGovernor {\\n IERC20(tokenAddress).safeTransfer(to, amountToRecover);\\n emit Recovered(tokenAddress, to, amountToRecover);\\n }\\n\\n /// @notice Updates the `limit` amount for `bridgeToken`\\n function setLimit(address bridgeToken, uint256 limit) external onlyGovernorOrGuardian {\\n if (!bridges[bridgeToken].allowed) revert InvalidToken();\\n bridges[bridgeToken].limit = limit;\\n emit BridgeTokenLimitUpdated(bridgeToken, limit);\\n }\\n\\n /// @notice Updates the `hourlyLimit` amount for `bridgeToken`\\n function setHourlyLimit(address bridgeToken, uint256 hourlyLimit) external onlyGovernorOrGuardian {\\n if (!bridges[bridgeToken].allowed) revert InvalidToken();\\n bridges[bridgeToken].hourlyLimit = hourlyLimit;\\n emit BridgeTokenHourlyLimitUpdated(bridgeToken, hourlyLimit);\\n }\\n\\n /// @notice Updates the `chainTotalHourlyLimit` amount\\n function setChainTotalHourlyLimit(uint256 hourlyLimit) external onlyGovernorOrGuardian {\\n chainTotalHourlyLimit = hourlyLimit;\\n emit HourlyLimitUpdated(hourlyLimit);\\n }\\n\\n /// @notice Updates the `fee` value for `bridgeToken`\\n function setSwapFee(address bridgeToken, uint64 fee) external onlyGovernorOrGuardian {\\n if (!bridges[bridgeToken].allowed) revert InvalidToken();\\n if (fee > BASE_PARAMS) revert TooHighParameterValue();\\n bridges[bridgeToken].fee = fee;\\n emit BridgeTokenFeeUpdated(bridgeToken, fee);\\n }\\n\\n /// @notice Pauses or unpauses swapping in and out for a token\\n function toggleBridge(address bridgeToken) external onlyGovernorOrGuardian {\\n if (!bridges[bridgeToken].allowed) revert InvalidToken();\\n bool pausedStatus = bridges[bridgeToken].paused;\\n bridges[bridgeToken].paused = !pausedStatus;\\n emit BridgeTokenToggled(bridgeToken, !pausedStatus);\\n }\\n\\n /// @notice Toggles fees for the address `theAddress`\\n function toggleFeesForAddress(address theAddress) external onlyGovernorOrGuardian {\\n uint256 feeExemptStatus = 1 - isFeeExempt[theAddress];\\n isFeeExempt[theAddress] = feeExemptStatus;\\n emit FeeToggled(theAddress, feeExemptStatus);\\n }\\n}\\n\",\"keccak256\":\"0x03d7733482f57983ff12e1ea50ad9f7ba089f747e566c11d27ee199c59ff229c\",\"license\":\"GPL-3.0\"},\"contracts/agToken/BaseAgTokenSideChain.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-3.0\\n\\npragma solidity ^0.8.12;\\n\\n/*\\n * \\u2588 \\n ***** \\u2593\\u2593\\u2593 \\n * \\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593 \\n * ///. \\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593 \\n ***** //////// \\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593 \\n * ///////////// \\u2593\\u2593\\u2593 \\n \\u2593\\u2593 ////////////////// \\u2588 \\u2593\\u2593 \\n \\u2593\\u2593 \\u2593\\u2593 /////////////////////// \\u2593\\u2593 \\u2593\\u2593 \\n \\u2593\\u2593 \\u2593\\u2593 //////////////////////////// \\u2593\\u2593 \\u2593\\u2593 \\n \\u2593\\u2593 \\u2593\\u2593 /////////\\u2593\\u2593\\u2593///////\\u2593\\u2593\\u2593///////// \\u2593\\u2593 \\u2593\\u2593 \\n \\u2593\\u2593 ,////////////////////////////////////// \\u2593\\u2593 \\u2593\\u2593 \\n \\u2593\\u2593 ////////////////////////////////////////// \\u2593\\u2593 \\n \\u2593\\u2593 //////////////////////\\u2593\\u2593\\u2593\\u2593///////////////////// \\n ,//////////////////////////////////////////////////// \\n .////////////////////////////////////////////////////////// \\n .//////////////////////////\\u2588\\u2588.,//////////////////////////\\u2588 \\n .//////////////////////\\u2588\\u2588\\u2588\\u2588..,./////////////////////\\u2588\\u2588 \\n ...////////////////\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588.....,.////////////////\\u2588\\u2588\\u2588 \\n ,.,////////////\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588 ........,///////////\\u2588\\u2588\\u2588\\u2588 \\n .,.,//////\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588 ,.......///////\\u2588\\u2588\\u2588\\u2588 \\n ,..//\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588 ........./\\u2588\\u2588\\u2588\\u2588 \\n ..,\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588 .....,\\u2588\\u2588\\u2588 \\n .\\u2588\\u2588 ,.,\\u2588 \\n \\n \\n \\n \\u2593\\u2593 \\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593 \\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593 \\u2593\\u2593 \\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593 \\n \\u2593\\u2593\\u2593\\u2593\\u2593\\u2593 \\u2593\\u2593\\u2593 \\u2593\\u2593\\u2593 \\u2593\\u2593\\u2593 \\u2593\\u2593 \\u2593\\u2593 \\u2593\\u2593\\u2593\\u2593 \\n \\u2593\\u2593\\u2593 \\u2593\\u2593\\u2593 \\u2593\\u2593\\u2593 \\u2593\\u2593\\u2593 \\u2593\\u2593\\u2593 \\u2593\\u2593\\u2593 \\u2593\\u2593 \\u2593\\u2593\\u2593\\u2593\\u2593 \\n \\u2593\\u2593\\u2593 \\u2593\\u2593 \\u2593\\u2593\\u2593 \\u2593\\u2593\\u2593 \\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593 \\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593 \\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593 \\n*/\\n\\nimport \\\"../interfaces/IAgToken.sol\\\";\\nimport \\\"../interfaces/ITreasury.sol\\\";\\nimport \\\"@openzeppelin/contracts-upgradeable/token/ERC20/extensions/draft-ERC20PermitUpgradeable.sol\\\";\\n\\n/// @title BaseAgTokenSideChain\\n/// @author Angle Labs, Inc.\\n/// @notice Base contract for Angle agTokens on Ethereum and on other chains\\n/// @dev By default, agTokens are ERC-20 tokens with 18 decimals\\ncontract BaseAgTokenSideChain is IAgToken, ERC20PermitUpgradeable {\\n // =========================== PARAMETERS / VARIABLES ==========================\\n\\n /// @inheritdoc IAgToken\\n mapping(address => bool) public isMinter;\\n /// @notice Reference to the treasury contract which can grant minting rights\\n address public treasury;\\n\\n // =================================== EVENTS ==================================\\n\\n event TreasuryUpdated(address indexed _treasury);\\n event MinterToggled(address indexed minter);\\n\\n // =================================== ERRORS ==================================\\n\\n error BurnAmountExceedsAllowance();\\n error InvalidSender();\\n error InvalidTreasury();\\n error NotMinter();\\n error NotTreasury();\\n\\n // ================================ CONSTRUCTOR ================================\\n\\n /// @notice Wraps `_initializeBase` for `BaseAgTokenSideChain` and makes a safety check\\n /// on `_treasury`\\n function _initialize(string memory name_, string memory symbol_, address _treasury) internal virtual initializer {\\n if (address(ITreasury(_treasury).stablecoin()) != address(this)) revert InvalidTreasury();\\n _initializeBase(name_, symbol_, _treasury);\\n }\\n\\n /// @custom:oz-upgrades-unsafe-allow constructor\\n constructor() initializer {}\\n\\n /// @notice Initializes the contract\\n /// @param name_ Name of the token\\n /// @param symbol_ Symbol of the token\\n /// @param _treasury Reference to the `Treasury` contract associated to this agToken implementation\\n function _initializeBase(string memory name_, string memory symbol_, address _treasury) internal virtual {\\n __ERC20Permit_init(name_);\\n __ERC20_init(name_, symbol_);\\n treasury = _treasury;\\n emit TreasuryUpdated(address(_treasury));\\n }\\n\\n // ================================= MODIFIERS =================================\\n\\n /// @notice Checks to see if it is the `Treasury` calling this contract\\n /// @dev There is no Access Control here, because it can be handled cheaply through this modifier\\n modifier onlyTreasury() {\\n if (msg.sender != address(treasury)) revert NotTreasury();\\n _;\\n }\\n\\n /// @notice Checks whether the sender has the minting right\\n modifier onlyMinter() {\\n if (!isMinter[msg.sender]) revert NotMinter();\\n _;\\n }\\n\\n // ============================= EXTERNAL FUNCTION =============================\\n\\n /// @notice Allows anyone to burn agToken without redeeming collateral back\\n /// @param amount Amount of stablecoins to burn\\n /// @dev This function can typically be called if there is a settlement mechanism to burn stablecoins\\n function burnStablecoin(uint256 amount) external {\\n _burn(msg.sender, amount);\\n }\\n\\n // ========================= MINTER ROLE ONLY FUNCTIONS ========================\\n\\n /// @inheritdoc IAgToken\\n function burnSelf(uint256 amount, address burner) external onlyMinter {\\n _burn(burner, amount);\\n }\\n\\n /// @inheritdoc IAgToken\\n function burnFrom(uint256 amount, address burner, address sender) external onlyMinter {\\n _burnFromNoRedeem(amount, burner, sender);\\n }\\n\\n /// @inheritdoc IAgToken\\n function mint(address account, uint256 amount) external onlyMinter {\\n _mint(account, amount);\\n }\\n\\n // ========================== TREASURY ONLY FUNCTIONS ==========================\\n\\n /// @inheritdoc IAgToken\\n function addMinter(address minter) external onlyTreasury {\\n isMinter[minter] = true;\\n emit MinterToggled(minter);\\n }\\n\\n /// @inheritdoc IAgToken\\n function removeMinter(address minter) external {\\n if (msg.sender != address(treasury) && msg.sender != minter) revert InvalidSender();\\n isMinter[minter] = false;\\n emit MinterToggled(minter);\\n }\\n\\n /// @inheritdoc IAgToken\\n function setTreasury(address _treasury) external virtual onlyTreasury {\\n treasury = _treasury;\\n emit TreasuryUpdated(_treasury);\\n }\\n\\n // ============================= INTERNAL FUNCTION =============================\\n\\n /// @notice Internal version of the function `burnFromNoRedeem`\\n /// @param amount Amount to burn\\n /// @dev It is at the level of this function that allowance checks are performed\\n function _burnFromNoRedeem(uint256 amount, address burner, address sender) internal {\\n if (burner != sender) {\\n uint256 currentAllowance = allowance(burner, sender);\\n if (currentAllowance < amount) revert BurnAmountExceedsAllowance();\\n _approve(burner, sender, currentAllowance - amount);\\n }\\n _burn(burner, amount);\\n }\\n}\\n\",\"keccak256\":\"0x3a120df43d66baf21914de14312a36c51fb22d7d10b7ef704ff0ec847c128943\",\"license\":\"GPL-3.0\"},\"contracts/interfaces/IAgToken.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-3.0\\n\\npragma solidity ^0.8.12;\\n\\nimport \\\"@openzeppelin/contracts-upgradeable/token/ERC20/IERC20Upgradeable.sol\\\";\\n\\n/// @title IAgToken\\n/// @author Angle Labs, Inc.\\n/// @notice Interface for the stablecoins `AgToken` contracts\\n/// @dev This interface only contains functions of the `AgToken` contract which are called by other contracts\\n/// of this module or of the first module of the Angle Protocol\\ninterface IAgToken is IERC20Upgradeable {\\n // ======================= Minter Role Only Functions ===========================\\n\\n /// @notice Lets the `StableMaster` contract or another whitelisted contract mint agTokens\\n /// @param account Address to mint to\\n /// @param amount Amount to mint\\n /// @dev The contracts allowed to issue agTokens are the `StableMaster` contract, `VaultManager` contracts\\n /// associated to this stablecoin as well as the flash loan module (if activated) and potentially contracts\\n /// whitelisted by governance\\n function mint(address account, uint256 amount) external;\\n\\n /// @notice Burns `amount` tokens from a `burner` address after being asked to by `sender`\\n /// @param amount Amount of tokens to burn\\n /// @param burner Address to burn from\\n /// @param sender Address which requested the burn from `burner`\\n /// @dev This method is to be called by a contract with the minter right after being requested\\n /// to do so by a `sender` address willing to burn tokens from another `burner` address\\n /// @dev The method checks the allowance between the `sender` and the `burner`\\n function burnFrom(\\n uint256 amount,\\n address burner,\\n address sender\\n ) external;\\n\\n /// @notice Burns `amount` tokens from a `burner` address\\n /// @param amount Amount of tokens to burn\\n /// @param burner Address to burn from\\n /// @dev This method is to be called by a contract with a minter right on the AgToken after being\\n /// requested to do so by an address willing to burn tokens from its address\\n function burnSelf(uint256 amount, address burner) external;\\n\\n // ========================= Treasury Only Functions ===========================\\n\\n /// @notice Adds a minter in the contract\\n /// @param minter Minter address to add\\n /// @dev Zero address checks are performed directly in the `Treasury` contract\\n function addMinter(address minter) external;\\n\\n /// @notice Removes a minter from the contract\\n /// @param minter Minter address to remove\\n /// @dev This function can also be called by a minter wishing to revoke itself\\n function removeMinter(address minter) external;\\n\\n /// @notice Sets a new treasury contract\\n /// @param _treasury New treasury address\\n function setTreasury(address _treasury) external;\\n\\n // ========================= External functions ================================\\n\\n /// @notice Checks whether an address has the right to mint agTokens\\n /// @param minter Address for which the minting right should be checked\\n /// @return Whether the address has the right to mint agTokens or not\\n function isMinter(address minter) external view returns (bool);\\n\\n /// @notice Get the associated treasury\\n function treasury() external view returns (address);\\n}\\n\",\"keccak256\":\"0xd671dbd00b28a86b839fd455ada4d1ef9203694d06142be76853e00a91f80b5f\",\"license\":\"GPL-3.0\"},\"contracts/interfaces/ICoreBorrow.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-3.0\\n\\npragma solidity ^0.8.12;\\n\\n/// @title ICoreBorrow\\n/// @author Angle Labs, Inc.\\n/// @notice Interface for the `CoreBorrow` contract\\n/// @dev This interface only contains functions of the `CoreBorrow` contract which are called by other contracts\\n/// of this module\\ninterface ICoreBorrow {\\n /// @notice Checks if an address corresponds to a treasury of a stablecoin with a flash loan\\n /// module initialized on it\\n /// @param treasury Address to check\\n /// @return Whether the address has the `FLASHLOANER_TREASURY_ROLE` or not\\n function isFlashLoanerTreasury(address treasury) external view returns (bool);\\n\\n /// @notice Checks whether an address is governor of the Angle Protocol or not\\n /// @param admin Address to check\\n /// @return Whether the address has the `GOVERNOR_ROLE` or not\\n function isGovernor(address admin) external view returns (bool);\\n\\n /// @notice Checks whether an address is governor or a guardian of the Angle Protocol or not\\n /// @param admin Address to check\\n /// @return Whether the address has the `GUARDIAN_ROLE` or not\\n /// @dev Governance should make sure when adding a governor to also give this governor the guardian\\n /// role by calling the `addGovernor` function\\n function isGovernorOrGuardian(address admin) external view returns (bool);\\n}\\n\",\"keccak256\":\"0x10249210cbf522775f040baf981d7d037472168ce2746d87473ac7c29a34e62e\",\"license\":\"GPL-3.0\"},\"contracts/interfaces/IFlashAngle.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-3.0\\n\\npragma solidity ^0.8.12;\\n\\nimport \\\"./IAgToken.sol\\\";\\nimport \\\"./ICoreBorrow.sol\\\";\\n\\n/// @title IFlashAngle\\n/// @author Angle Labs, Inc.\\n/// @notice Interface for the `FlashAngle` contract\\n/// @dev This interface only contains functions of the contract which are called by other contracts\\n/// of this module\\ninterface IFlashAngle {\\n /// @notice Reference to the `CoreBorrow` contract managing the FlashLoan module\\n function core() external view returns (ICoreBorrow);\\n\\n /// @notice Sends the fees taken from flash loans to the treasury contract associated to the stablecoin\\n /// @param stablecoin Stablecoin from which profits should be sent\\n /// @return balance Amount of profits sent\\n /// @dev This function can only be called by the treasury contract\\n function accrueInterestToTreasury(IAgToken stablecoin) external returns (uint256 balance);\\n\\n /// @notice Adds support for a stablecoin\\n /// @param _treasury Treasury associated to the stablecoin to add support for\\n /// @dev This function can only be called by the `CoreBorrow` contract\\n function addStablecoinSupport(address _treasury) external;\\n\\n /// @notice Removes support for a stablecoin\\n /// @param _treasury Treasury associated to the stablecoin to remove support for\\n /// @dev This function can only be called by the `CoreBorrow` contract\\n function removeStablecoinSupport(address _treasury) external;\\n\\n /// @notice Sets a new core contract\\n /// @param _core Core contract address to set\\n /// @dev This function can only be called by the `CoreBorrow` contract\\n function setCore(address _core) external;\\n}\\n\",\"keccak256\":\"0x39b0097f695b9e934bccdc72676c91513f1077cc5d0fd151908fd25a7c5cfbe4\",\"license\":\"GPL-3.0\"},\"contracts/interfaces/ITreasury.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-3.0\\n\\npragma solidity ^0.8.12;\\n\\nimport \\\"./IAgToken.sol\\\";\\nimport \\\"./ICoreBorrow.sol\\\";\\nimport \\\"./IFlashAngle.sol\\\";\\n\\n/// @title ITreasury\\n/// @author Angle Labs, Inc.\\n/// @notice Interface for the `Treasury` contract\\n/// @dev This interface only contains functions of the `Treasury` which are called by other contracts\\n/// of this module\\ninterface ITreasury {\\n /// @notice Stablecoin handled by this `treasury` contract\\n function stablecoin() external view returns (IAgToken);\\n\\n /// @notice Checks whether a given address has the governor role\\n /// @param admin Address to check\\n /// @return Whether the address has the governor role\\n /// @dev Access control is only kept in the `CoreBorrow` contract\\n function isGovernor(address admin) external view returns (bool);\\n\\n /// @notice Checks whether a given address has the guardian or the governor role\\n /// @param admin Address to check\\n /// @return Whether the address has the guardian or the governor role\\n /// @dev Access control is only kept in the `CoreBorrow` contract which means that this function\\n /// queries the `CoreBorrow` contract\\n function isGovernorOrGuardian(address admin) external view returns (bool);\\n\\n /// @notice Checks whether a given address has well been initialized in this contract\\n /// as a `VaultManager`\\n /// @param _vaultManager Address to check\\n /// @return Whether the address has been initialized or not\\n function isVaultManager(address _vaultManager) external view returns (bool);\\n\\n /// @notice Sets a new flash loan module for this stablecoin\\n /// @param _flashLoanModule Reference to the new flash loan module\\n /// @dev This function removes the minting right to the old flash loan module and grants\\n /// it to the new module\\n function setFlashLoanModule(address _flashLoanModule) external;\\n\\n /// @notice Gets the vault manager list\\n function vaultManagerList(uint256 i) external returns (address);\\n}\\n\",\"keccak256\":\"0x06c2f781c08732ce1b5845c083af5742716245baa6c519bd737f32b230a884c1\",\"license\":\"GPL-3.0\"}},\"version\":1}", - "bytecode": "0x60806040523480156200001157600080fd5b50600054610100900460ff1615808015620000335750600054600160ff909116105b8062000063575062000050306200013d60201b6200268a1760201c565b15801562000063575060005460ff166001145b620000cb5760405162461bcd60e51b815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201526d191e481a5b9a5d1a585b1a5e995960921b606482015260840160405180910390fd5b6000805460ff191660011790558015620000ef576000805461ff0019166101001790555b801562000136576000805461ff0019169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15b506200014c565b6001600160a01b03163b151590565b6146eb806200015c6000396000f3fe608060405234801561001057600080fd5b50600436106102ff5760003560e01c806361d027b31161019c5780639f48118f116100ee578063ced67f0c11610097578063dd62ed3e11610071578063dd62ed3e14610724578063e3e286551461076a578063f0f442601461077d57600080fd5b8063ced67f0c1461066b578063d44ad63f146106fe578063d505accf1461071157600080fd5b8063aa271e1a116100c8578063aa271e1a14610620578063ba330bd714610643578063cd4839ca1461065657600080fd5b80639f48118f146105ef578063a457c2d7146105fa578063a9059cbb1461060d57600080fd5b80637ecebe001161015057806395d89b411161012a57806395d89b41146105c1578063983b2d56146105c95780639e4e0dae146105dc57600080fd5b80637ecebe00146105705780638933fb791461058357806390218cff146105ae57600080fd5b80637334d020116101815780637334d020146105425780637d4c9c2d146105555780637d74e25f1461056857600080fd5b806361d027b3146104c757806370a082311461050c57600080fd5b80633092afd511610255578063395093511161020957806340c10f19116101e357806340c10f19146104815780634dc32fcc146104945780635bfbec96146104a757600080fd5b8063395093511461043b5780633a55f89d1461044e5780633f4218e01461046157600080fd5b8063350ebe041161023a578063350ebe041461040d5780633644e5151461042057806336db43b51461042857600080fd5b80633092afd5146103eb578063313ce567146103fe57600080fd5b8063151dd755116102b757806323b872dd1161029157806323b872dd146103b25780632b471d8e146103c55780632e403e14146103d857600080fd5b8063151dd7551461038057806318160ddd146103a15780632342fb0e146103a957600080fd5b80630919a951116102e85780630919a95114610337578063095ea7b31461034a5780631171bda91461036d57600080fd5b806306fdde0314610304578063077f224a14610322575b600080fd5b61030c610790565b6040516103199190613e63565b60405180910390f35b610335610330366004613fb0565b610822565b005b610335610345366004614028565b610832565b61035d610358366004614045565b610995565b6040519015158152602001610319565b61033561037b366004614071565b6109af565b61039361038e3660046140b2565b610b04565b604051908152602001610319565b603554610393565b61039360d25481565b61035d6103c0366004614071565b610dbe565b6103356103d33660046140e9565b610de2565b6103356103e6366004614028565b610e39565b6103356103f9366004614028565b6111e8565b60405160128152602001610319565b61033561041b366004614119565b6112d1565b610393611325565b610335610436366004614045565b611334565b61035d610449366004614045565b6114c4565b61033561045c366004614150565b611510565b61039361046f366004614028565b60d16020526000908152604090205481565b61033561048f366004614045565b611613565b6103936104a2366004614028565b611666565b6103936104b5366004614150565b60d36020526000908152604090205481565b60cd546104e79073ffffffffffffffffffffffffffffffffffffffff1681565b60405173ffffffffffffffffffffffffffffffffffffffff9091168152602001610319565b61039361051a366004614028565b73ffffffffffffffffffffffffffffffffffffffff1660009081526033602052604090205490565b610335610550366004614045565b6116ae565b610335610563366004614194565b611841565b610393611ba9565b61039361057e366004614028565b611bce565b610393610591366004614045565b60d060209081526000928352604080842090915290825290205481565b6103356105bc366004614150565b611bf9565b61030c611c06565b6103356105d7366004614028565b611c15565b6103356105ea3660046141f1565b611cdd565b610393633b9aca0081565b61035d610608366004614045565b611ee9565b61035d61061b366004614045565b611fbf565b61035d61062e366004614028565b60cc6020526000908152604090205460ff1681565b6104e7610651366004614150565b611fcd565b61065e612004565b6040516103199190614226565b6106c5610679366004614028565b60ce6020526000908152604090208054600182015460029092015490919067ffffffffffffffff81169060ff680100000000000000008204811691690100000000000000000090041685565b60408051958652602086019490945267ffffffffffffffff9092169284019290925290151560608301521515608082015260a001610319565b61039361070c3660046140b2565b612072565b61033561071f366004614280565b612237565b6103936107323660046142f7565b73ffffffffffffffffffffffffffffffffffffffff918216600090815260346020908152604080832093909416825291909152205490565b610335610778366004614028565b6123f6565b61033561078b366004614028565b6125ca565b60606036805461079f90614325565b80601f01602080910402602001604051908101604052809291908181526020018280546107cb90614325565b80156108185780601f106107ed57610100808354040283529160200191610818565b820191906000526020600020905b8154815290600101906020018083116107fb57829003601f168201915b5050505050905090565b61082d8383836126a6565b505050565b60cd546040517f521d4de900000000000000000000000000000000000000000000000000000000815233600482015273ffffffffffffffffffffffffffffffffffffffff9091169063521d4de990602401602060405180830381865afa1580156108a0573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906108c49190614372565b6108fa576040517f99e120bc00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff8116600090815260d1602052604081205461092b9060016143be565b73ffffffffffffffffffffffffffffffffffffffff8316600081815260d160205260409081902083905551919250907f979ef83e7e7a87cb48064e296dd7e997870d50f43acf8d7ad221313526c8ca0f906109899084815260200190565b60405180910390a25050565b6000336109a3818585612911565b60019150505b92915050565b60cd546040517fe43581b800000000000000000000000000000000000000000000000000000000815233600482015273ffffffffffffffffffffffffffffffffffffffff9091169063e43581b890602401602060405180830381865afa158015610a1d573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610a419190614372565b610a77576040517fee3675d400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b610a9873ffffffffffffffffffffffffffffffffffffffff84168383612abc565b8173ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff167ffff3b3844276f57024e0b42afec1a37f75db36511e43819a4f2a63ab7862b64883604051610af791815260200190565b60405180910390a3505050565b73ffffffffffffffffffffffffffffffffffffffff8316600090815260ce60209081526040808320815160a081018352815481526001820154938101939093526002015467ffffffffffffffff81169183019190915260ff680100000000000000008204811615801560608501526901000000000000000000909204161515608083015280610b94575080608001515b15610bcb576040517fc1ab6dc100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015260009073ffffffffffffffffffffffffffffffffffffffff8716906370a0823190602401602060405180830381865afa158015610c38573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610c5c91906143d1565b8251909150610c6b86836143ea565b1115610c93578151811015610c8e578151610c879082906143be565b9450610c93565b600094505b6000610ca1610e10426143fd565b73ffffffffffffffffffffffffffffffffffffffff8816600090815260d0602090815260408083208484528252909120549085015191925090610ce488836143ea565b1115610d0f5780846020015111610cfc576000610d0c565b808460200151610d0c91906143be565b96505b610d1987826143ea565b73ffffffffffffffffffffffffffffffffffffffff8916600081815260d060209081526040808320878452909152902091909155610d599033308a612b90565b33600090815260d16020526040812054889103610da657633b9aca00856040015167ffffffffffffffff1682610d8f9190614438565b610d9991906143fd565b610da390826143be565b90505b610db08782612bee565b9450505050505b9392505050565b600033610dcc858285612d0e565b610dd7858585612ddf565b506001949350505050565b33600090815260cc602052604090205460ff16610e2b576040517ff8d2906c00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b610e358183613092565b5050565b60cd546040517fe43581b800000000000000000000000000000000000000000000000000000000815233600482015273ffffffffffffffffffffffffffffffffffffffff9091169063e43581b890602401602060405180830381865afa158015610ea7573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610ecb9190614372565b610f01576040517fee3675d400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015273ffffffffffffffffffffffffffffffffffffffff8216906370a0823190602401602060405180830381865afa158015610f6b573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610f8f91906143d1565b15610fc6576040517f2ef630ec00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff8116600090815260ce602052604081208181556001810182905560020180547fffffffffffffffffffffffffffffffffffffffffffff0000000000000000000016905560cf54905b61102e6001836143be565b811015611139578273ffffffffffffffffffffffffffffffffffffffff1660cf828154811061105f5761105f61444f565b60009182526020909120015473ffffffffffffffffffffffffffffffffffffffff16036111295760cf6110936001846143be565b815481106110a3576110a361444f565b60009182526020909120015460cf805473ffffffffffffffffffffffffffffffffffffffff90921691839081106110dc576110dc61444f565b9060005260206000200160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550611139565b6111328161447e565b9050611023565b5060cf80548061114b5761114b6144b6565b60008281526020812082017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff90810180547fffffffffffffffffffffffff000000000000000000000000000000000000000016905590910190915560405173ffffffffffffffffffffffffffffffffffffffff8416917f5c95b49c4d59d97a2f044167723f29c74b30f99702e3fd406c3830160aa9ccb891a25050565b60cd5473ffffffffffffffffffffffffffffffffffffffff16331480159061122657503373ffffffffffffffffffffffffffffffffffffffff821614155b1561125d576040517fddb5de5e00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff8116600081815260cc602052604080822080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00169055517f98c15241d6c02bc5ee0b780e11b3ea737a2defd9d04877edbe9f9497065bd02f9190a250565b33600090815260cc602052604090205460ff1661131a576040517ff8d2906c00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b61082d83838361327f565b600061132f61333a565b905090565b60cd546040517f521d4de900000000000000000000000000000000000000000000000000000000815233600482015273ffffffffffffffffffffffffffffffffffffffff9091169063521d4de990602401602060405180830381865afa1580156113a2573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906113c69190614372565b6113fc576040517f99e120bc00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff8216600090815260ce602052604090206002015468010000000000000000900460ff1661146a576040517fc1ab6dc100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff8216600081815260ce602052604090819020839055517fe7b113fba37131b6396680a0c55790a697ec975e198ff8cfd89dac90a6379e61906109899084815260200190565b33600081815260346020908152604080832073ffffffffffffffffffffffffffffffffffffffff871684529091528120549091906109a3908290869061150b9087906143ea565b612911565b60cd546040517f521d4de900000000000000000000000000000000000000000000000000000000815233600482015273ffffffffffffffffffffffffffffffffffffffff9091169063521d4de990602401602060405180830381865afa15801561157e573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906115a29190614372565b6115d8576040517f99e120bc00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60d28190556040518181527fc3b69829afe2345596a02c8b587d41f796ba0094481d899e1b2e07b7532a1e219060200160405180910390a150565b33600090815260cc602052604090205460ff1661165c576040517ff8d2906c00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b610e358282612bee565b73ffffffffffffffffffffffffffffffffffffffff8116600090815260d06020526040812081611698610e10426143fd565b8152602001908152602001600020549050919050565b60cd546040517f521d4de900000000000000000000000000000000000000000000000000000000815233600482015273ffffffffffffffffffffffffffffffffffffffff9091169063521d4de990602401602060405180830381865afa15801561171c573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906117409190614372565b611776576040517f99e120bc00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff8216600090815260ce602052604090206002015468010000000000000000900460ff166117e4576040517fc1ab6dc100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff8216600081815260ce602052604090819020600101839055517fe13ac9338b2ee623233f83c1b3ceab16490fa3e3737fac7f0970d0830a9f4871906109899084815260200190565b60cd546040517fe43581b800000000000000000000000000000000000000000000000000000000815233600482015273ffffffffffffffffffffffffffffffffffffffff9091169063e43581b890602401602060405180830381865afa1580156118af573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906118d39190614372565b611909576040517fee3675d400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff8516600090815260ce602052604090206002015468010000000000000000900460ff1680611960575073ffffffffffffffffffffffffffffffffffffffff8516155b15611997576040517fc1ab6dc100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b633b9aca008267ffffffffffffffff1611156119df576040517feca1d2c600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040805160a08101825260008082526020820181905291810182905260608101829052608081019190915284815260208082018581528315156080840190815267ffffffffffffffff808716604080870191825260016060880181815273ffffffffffffffffffffffffffffffffffffffff8e16600081815260ce9099528389208a5181559751888401559351600290970180549151965115156901000000000000000000027fffffffffffffffffffffffffffffffffffffffffffff00ffffffffffffffffff97151568010000000000000000027fffffffffffffffffffffffffffffffffffffffffffffff000000000000000000909316989096169790971717949094169290921790935560cf805492830181559093527facb8d954e2cfef495862221e91bd7523613cf8808827cb33edfe4904cc51bf290180547fffffffffffffffffffffffff0000000000000000000000000000000000000000168217905590517f53087ff85d80a7671594bd2e86b92af22e0b3c2c441c8033bba7399b7b5cbe2390611b99908890889088908890938452602084019290925267ffffffffffffffff1660408301521515606082015260800190565b60405180910390a2505050505050565b600060d381611bba610e10426143fd565b815260200190815260200160002054905090565b73ffffffffffffffffffffffffffffffffffffffff81166000908152609960205260408120546109a9565b611c033382613092565b50565b60606037805461079f90614325565b60cd5473ffffffffffffffffffffffffffffffffffffffff163314611c66576040517fb90cdbb100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff8116600081815260cc602052604080822080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00166001179055517f98c15241d6c02bc5ee0b780e11b3ea737a2defd9d04877edbe9f9497065bd02f9190a250565b60cd546040517f521d4de900000000000000000000000000000000000000000000000000000000815233600482015273ffffffffffffffffffffffffffffffffffffffff9091169063521d4de990602401602060405180830381865afa158015611d4b573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611d6f9190614372565b611da5576040517f99e120bc00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff8216600090815260ce602052604090206002015468010000000000000000900460ff16611e13576040517fc1ab6dc100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b633b9aca008167ffffffffffffffff161115611e5b576040517feca1d2c600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff8216600081815260ce602090815260409182902060020180547fffffffffffffffffffffffffffffffffffffffffffffffff00000000000000001667ffffffffffffffff861690811790915591519182527f901f9de19b475adc8da4110434b8df940dce085afd05e2281c86807f3a899d299101610989565b33600081815260346020908152604080832073ffffffffffffffffffffffffffffffffffffffff8716845290915281205490919083811015611fb2576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602560248201527f45524332303a2064656372656173656420616c6c6f77616e63652062656c6f7760448201527f207a65726f00000000000000000000000000000000000000000000000000000060648201526084015b60405180910390fd5b610dd78286868403612911565b6000336109a3818585612ddf565b60cf8181548110611fdd57600080fd5b60009182526020909120015473ffffffffffffffffffffffffffffffffffffffff16905081565b606060cf80548060200260200160405190810160405280929190818152602001828054801561081857602002820191906000526020600020905b815473ffffffffffffffffffffffffffffffffffffffff16815260019091019060200180831161203e575050505050905090565b73ffffffffffffffffffffffffffffffffffffffff8316600090815260ce60209081526040808320815160a081018352815481526001820154938101939093526002015467ffffffffffffffff81169183019190915260ff680100000000000000008204811615801560608501526901000000000000000000909204161515608083015280612102575080608001515b15612139576040517fc1ab6dc100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000612147610e10426143fd565b600081815260d36020526040812054919250906121659087906143ea565b905060d2548111156121a3576040517f6d43d1ac00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600082815260d3602052604090208190556121be3387613092565b33600090815260d1602052604081205487910361220b57633b9aca00846040015167ffffffffffffffff16826121f49190614438565b6121fe91906143fd565b61220890826143be565b90505b61222c73ffffffffffffffffffffffffffffffffffffffff89168783612abc565b979650505050505050565b834211156122a1576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f45524332305065726d69743a206578706972656420646561646c696e650000006044820152606401611fa9565b60007f6e71edae12b1b97f4d1f60370fef10105fa2faae0126114a169c64845d6126c98888886122d08c6133b5565b60408051602081019690965273ffffffffffffffffffffffffffffffffffffffff94851690860152929091166060840152608083015260a082015260c0810186905260e0016040516020818303038152906040528051906020012090506000612338826133ea565b9050600061234882878787613453565b90508973ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16146123df576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601e60248201527f45524332305065726d69743a20696e76616c6964207369676e617475726500006044820152606401611fa9565b6123ea8a8a8a612911565b50505050505050505050565b60cd546040517f521d4de900000000000000000000000000000000000000000000000000000000815233600482015273ffffffffffffffffffffffffffffffffffffffff9091169063521d4de990602401602060405180830381865afa158015612464573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906124889190614372565b6124be576040517f99e120bc00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff8116600090815260ce602052604090206002015468010000000000000000900460ff1661252c576040517fc1ab6dc100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff8116600081815260ce602090815260409182902060020180547fffffffffffffffffffffffffffffffffffffffffffff00ffffffffffffffffff811669010000000000000000009182900460ff16801592830291909117909255925192835292917ff7c93079dcbf699749d66345a351afab7d24219bb1d915c9f4fc4cf03f00d3979101610989565b60cd5473ffffffffffffffffffffffffffffffffffffffff16331461261b576040517fb90cdbb100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60cd80547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83169081179091556040517f7dae230f18360d76a040c81f050aa14eb9d6dc7901b20fc5d855e2a20fe814d190600090a250565b73ffffffffffffffffffffffffffffffffffffffff163b151590565b600054610100900460ff16158080156126c65750600054600160ff909116105b806126e05750303b1580156126e0575060005460ff166001145b61276c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201527f647920696e697469616c697a65640000000000000000000000000000000000006064820152608401611fa9565b600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0016600117905580156127ca57600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff166101001790555b3073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1663e9cbd8226040518163ffffffff1660e01b8152600401602060405180830381865afa15801561282c573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061285091906144e5565b73ffffffffffffffffffffffffffffffffffffffff161461289d576040517f14bcf5c800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6128a884848461347b565b801561290b57600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15b50505050565b73ffffffffffffffffffffffffffffffffffffffff83166129b3576040517f08c379a0000000000000000000000000000000000000000000000000000000008152602060048201526024808201527f45524332303a20617070726f76652066726f6d20746865207a65726f2061646460448201527f72657373000000000000000000000000000000000000000000000000000000006064820152608401611fa9565b73ffffffffffffffffffffffffffffffffffffffff8216612a56576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602260248201527f45524332303a20617070726f766520746f20746865207a65726f20616464726560448201527f73730000000000000000000000000000000000000000000000000000000000006064820152608401611fa9565b73ffffffffffffffffffffffffffffffffffffffff83811660008181526034602090815260408083209487168084529482529182902085905590518481527f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b9259101610af7565b60405173ffffffffffffffffffffffffffffffffffffffff831660248201526044810182905261082d9084907fa9059cbb00000000000000000000000000000000000000000000000000000000906064015b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff00000000000000000000000000000000000000000000000000000000909316929092179091526134ff565b60405173ffffffffffffffffffffffffffffffffffffffff8085166024830152831660448201526064810182905261290b9085907f23b872dd0000000000000000000000000000000000000000000000000000000090608401612b0e565b73ffffffffffffffffffffffffffffffffffffffff8216612c6b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601f60248201527f45524332303a206d696e7420746f20746865207a65726f2061646472657373006044820152606401611fa9565b8060356000828254612c7d91906143ea565b909155505073ffffffffffffffffffffffffffffffffffffffff821660009081526033602052604081208054839290612cb79084906143ea565b909155505060405181815273ffffffffffffffffffffffffffffffffffffffff8316906000907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef9060200160405180910390a35050565b73ffffffffffffffffffffffffffffffffffffffff8381166000908152603460209081526040808320938616835292905220547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff811461290b5781811015612dd2576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f45524332303a20696e73756666696369656e7420616c6c6f77616e63650000006044820152606401611fa9565b61290b8484848403612911565b73ffffffffffffffffffffffffffffffffffffffff8316612e82576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602560248201527f45524332303a207472616e736665722066726f6d20746865207a65726f20616460448201527f64726573730000000000000000000000000000000000000000000000000000006064820152608401611fa9565b73ffffffffffffffffffffffffffffffffffffffff8216612f25576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602360248201527f45524332303a207472616e7366657220746f20746865207a65726f206164647260448201527f65737300000000000000000000000000000000000000000000000000000000006064820152608401611fa9565b73ffffffffffffffffffffffffffffffffffffffff831660009081526033602052604090205481811015612fdb576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f45524332303a207472616e7366657220616d6f756e742065786365656473206260448201527f616c616e636500000000000000000000000000000000000000000000000000006064820152608401611fa9565b73ffffffffffffffffffffffffffffffffffffffff80851660009081526033602052604080822085850390559185168152908120805484929061301f9084906143ea565b925050819055508273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef8460405161308591815260200190565b60405180910390a361290b565b73ffffffffffffffffffffffffffffffffffffffff8216613135576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602160248201527f45524332303a206275726e2066726f6d20746865207a65726f2061646472657360448201527f73000000000000000000000000000000000000000000000000000000000000006064820152608401611fa9565b73ffffffffffffffffffffffffffffffffffffffff8216600090815260336020526040902054818110156131eb576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602260248201527f45524332303a206275726e20616d6f756e7420657863656564732062616c616e60448201527f63650000000000000000000000000000000000000000000000000000000000006064820152608401611fa9565b73ffffffffffffffffffffffffffffffffffffffff831660009081526033602052604081208383039055603580548492906132279084906143be565b909155505060405182815260009073ffffffffffffffffffffffffffffffffffffffff8516907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef9060200160405180910390a3505050565b8073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff16146133305773ffffffffffffffffffffffffffffffffffffffff8281166000908152603460209081526040808320938516835292905220548381101561331f576040517f715ec26c00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b61332e838361150b87856143be565b505b61082d8284613092565b600061132f7f8b73c3c69bb8fe3d512ecc4cf759cc79239f7b179b0ffacaa9a75d522b39400f61336960655490565b6066546040805160208101859052908101839052606081018290524660808201523060a082015260009060c0016040516020818303038152906040528051906020012090509392505050565b73ffffffffffffffffffffffffffffffffffffffff811660009081526099602052604090208054600181018255905b50919050565b60006109a96133f761333a565b836040517f19010000000000000000000000000000000000000000000000000000000000006020820152602281018390526042810182905260009060620160405160208183030381529060405280519060200120905092915050565b60008060006134648787878761360b565b9150915061347181613723565b5095945050505050565b61348483613977565b61348e8383613a4d565b60cd80547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83169081179091556040517f7dae230f18360d76a040c81f050aa14eb9d6dc7901b20fc5d855e2a20fe814d190600090a2505050565b6000613561826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c65648152508573ffffffffffffffffffffffffffffffffffffffff16613aee9092919063ffffffff16565b80519091501561082d578080602001905181019061357f9190614372565b61082d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e60448201527f6f742073756363656564000000000000000000000000000000000000000000006064820152608401611fa9565b6000807f7fffffffffffffffffffffffffffffff5d576e7357a4501ddfe92f46681b20a0831115613642575060009050600361371a565b8460ff16601b1415801561365a57508460ff16601c14155b1561366b575060009050600461371a565b6040805160008082526020820180845289905260ff881692820192909252606081018690526080810185905260019060a0016020604051602081039080840390855afa1580156136bf573d6000803e3d6000fd5b50506040517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0015191505073ffffffffffffffffffffffffffffffffffffffff81166137135760006001925092505061371a565b9150600090505b94509492505050565b600081600481111561373757613737614502565b0361373f5750565b600181600481111561375357613753614502565b036137ba576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601860248201527f45434453413a20696e76616c6964207369676e617475726500000000000000006044820152606401611fa9565b60028160048111156137ce576137ce614502565b03613835576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601f60248201527f45434453413a20696e76616c6964207369676e6174757265206c656e677468006044820152606401611fa9565b600381600481111561384957613849614502565b036138d6576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602260248201527f45434453413a20696e76616c6964207369676e6174757265202773272076616c60448201527f75650000000000000000000000000000000000000000000000000000000000006064820152608401611fa9565b60048160048111156138ea576138ea614502565b03611c03576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602260248201527f45434453413a20696e76616c6964207369676e6174757265202776272076616c60448201527f75650000000000000000000000000000000000000000000000000000000000006064820152608401611fa9565b600054610100900460ff16613a0e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201527f6e697469616c697a696e670000000000000000000000000000000000000000006064820152608401611fa9565b611c03816040518060400160405280600181526020017f3100000000000000000000000000000000000000000000000000000000000000815250613b05565b600054610100900460ff16613ae4576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201527f6e697469616c697a696e670000000000000000000000000000000000000000006064820152608401611fa9565b610e358282613bb6565b6060613afd8484600085613c66565b949350505050565b600054610100900460ff16613b9c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201527f6e697469616c697a696e670000000000000000000000000000000000000000006064820152608401611fa9565b815160209283012081519190920120606591909155606655565b600054610100900460ff16613c4d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201527f6e697469616c697a696e670000000000000000000000000000000000000000006064820152608401611fa9565b6036613c59838261457f565b50603761082d828261457f565b606082471015613cf8576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f60448201527f722063616c6c00000000000000000000000000000000000000000000000000006064820152608401611fa9565b73ffffffffffffffffffffffffffffffffffffffff85163b613d76576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006044820152606401611fa9565b6000808673ffffffffffffffffffffffffffffffffffffffff168587604051613d9f9190614699565b60006040518083038185875af1925050503d8060008114613ddc576040519150601f19603f3d011682016040523d82523d6000602084013e613de1565b606091505b509150915061222c82828660608315613dfb575081610db7565b825115613e0b5782518084602001fd5b816040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611fa99190613e63565b60005b83811015613e5a578181015183820152602001613e42565b50506000910152565b6020815260008251806020840152613e82816040850160208701613e3f565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169190910160400192915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b600082601f830112613ef457600080fd5b813567ffffffffffffffff80821115613f0f57613f0f613eb4565b604051601f83017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0908116603f01168101908282118183101715613f5557613f55613eb4565b81604052838152866020858801011115613f6e57600080fd5b836020870160208301376000602085830101528094505050505092915050565b73ffffffffffffffffffffffffffffffffffffffff81168114611c0357600080fd5b600080600060608486031215613fc557600080fd5b833567ffffffffffffffff80821115613fdd57600080fd5b613fe987838801613ee3565b94506020860135915080821115613fff57600080fd5b5061400c86828701613ee3565b925050604084013561401d81613f8e565b809150509250925092565b60006020828403121561403a57600080fd5b8135610db781613f8e565b6000806040838503121561405857600080fd5b823561406381613f8e565b946020939093013593505050565b60008060006060848603121561408657600080fd5b833561409181613f8e565b925060208401356140a181613f8e565b929592945050506040919091013590565b6000806000606084860312156140c757600080fd5b83356140d281613f8e565b925060208401359150604084013561401d81613f8e565b600080604083850312156140fc57600080fd5b82359150602083013561410e81613f8e565b809150509250929050565b60008060006060848603121561412e57600080fd5b83359250602084013561414081613f8e565b9150604084013561401d81613f8e565b60006020828403121561416257600080fd5b5035919050565b803567ffffffffffffffff8116811461418157600080fd5b919050565b8015158114611c0357600080fd5b600080600080600060a086880312156141ac57600080fd5b85356141b781613f8e565b945060208601359350604086013592506141d360608701614169565b915060808601356141e381614186565b809150509295509295909350565b6000806040838503121561420457600080fd5b823561420f81613f8e565b915061421d60208401614169565b90509250929050565b6020808252825182820181905260009190848201906040850190845b8181101561427457835173ffffffffffffffffffffffffffffffffffffffff1683529284019291840191600101614242565b50909695505050505050565b600080600080600080600060e0888a03121561429b57600080fd5b87356142a681613f8e565b965060208801356142b681613f8e565b95506040880135945060608801359350608088013560ff811681146142da57600080fd5b9699959850939692959460a0840135945060c09093013592915050565b6000806040838503121561430a57600080fd5b823561431581613f8e565b9150602083013561410e81613f8e565b600181811c9082168061433957607f821691505b6020821081036133e4577f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b60006020828403121561438457600080fd5b8151610db781614186565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b818103818111156109a9576109a961438f565b6000602082840312156143e357600080fd5b5051919050565b808201808211156109a9576109a961438f565b600082614433577f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b500490565b80820281158282048414176109a9576109a961438f565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82036144af576144af61438f565b5060010190565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603160045260246000fd5b6000602082840312156144f757600080fd5b8151610db781613f8e565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b601f82111561082d57600081815260208120601f850160051c810160208610156145585750805b601f850160051c820191505b8181101561457757828155600101614564565b505050505050565b815167ffffffffffffffff81111561459957614599613eb4565b6145ad816145a78454614325565b84614531565b602080601f83116001811461460057600084156145ca5750858301515b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600386901b1c1916600185901b178555614577565b6000858152602081207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08616915b8281101561464d5788860151825594840194600190910190840161462e565b508582101561468957878501517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600388901b60f8161c191681555b5050505050600190811b01905550565b600082516146ab818460208701613e3f565b919091019291505056fea264697066735822122063a1b6264cdcf054e5097307e409d188b47c62ad909903d6edaf55a3d2b19dee64736f6c63430008110033", - "deployedBytecode": "0x608060405234801561001057600080fd5b50600436106102ff5760003560e01c806361d027b31161019c5780639f48118f116100ee578063ced67f0c11610097578063dd62ed3e11610071578063dd62ed3e14610724578063e3e286551461076a578063f0f442601461077d57600080fd5b8063ced67f0c1461066b578063d44ad63f146106fe578063d505accf1461071157600080fd5b8063aa271e1a116100c8578063aa271e1a14610620578063ba330bd714610643578063cd4839ca1461065657600080fd5b80639f48118f146105ef578063a457c2d7146105fa578063a9059cbb1461060d57600080fd5b80637ecebe001161015057806395d89b411161012a57806395d89b41146105c1578063983b2d56146105c95780639e4e0dae146105dc57600080fd5b80637ecebe00146105705780638933fb791461058357806390218cff146105ae57600080fd5b80637334d020116101815780637334d020146105425780637d4c9c2d146105555780637d74e25f1461056857600080fd5b806361d027b3146104c757806370a082311461050c57600080fd5b80633092afd511610255578063395093511161020957806340c10f19116101e357806340c10f19146104815780634dc32fcc146104945780635bfbec96146104a757600080fd5b8063395093511461043b5780633a55f89d1461044e5780633f4218e01461046157600080fd5b8063350ebe041161023a578063350ebe041461040d5780633644e5151461042057806336db43b51461042857600080fd5b80633092afd5146103eb578063313ce567146103fe57600080fd5b8063151dd755116102b757806323b872dd1161029157806323b872dd146103b25780632b471d8e146103c55780632e403e14146103d857600080fd5b8063151dd7551461038057806318160ddd146103a15780632342fb0e146103a957600080fd5b80630919a951116102e85780630919a95114610337578063095ea7b31461034a5780631171bda91461036d57600080fd5b806306fdde0314610304578063077f224a14610322575b600080fd5b61030c610790565b6040516103199190613e63565b60405180910390f35b610335610330366004613fb0565b610822565b005b610335610345366004614028565b610832565b61035d610358366004614045565b610995565b6040519015158152602001610319565b61033561037b366004614071565b6109af565b61039361038e3660046140b2565b610b04565b604051908152602001610319565b603554610393565b61039360d25481565b61035d6103c0366004614071565b610dbe565b6103356103d33660046140e9565b610de2565b6103356103e6366004614028565b610e39565b6103356103f9366004614028565b6111e8565b60405160128152602001610319565b61033561041b366004614119565b6112d1565b610393611325565b610335610436366004614045565b611334565b61035d610449366004614045565b6114c4565b61033561045c366004614150565b611510565b61039361046f366004614028565b60d16020526000908152604090205481565b61033561048f366004614045565b611613565b6103936104a2366004614028565b611666565b6103936104b5366004614150565b60d36020526000908152604090205481565b60cd546104e79073ffffffffffffffffffffffffffffffffffffffff1681565b60405173ffffffffffffffffffffffffffffffffffffffff9091168152602001610319565b61039361051a366004614028565b73ffffffffffffffffffffffffffffffffffffffff1660009081526033602052604090205490565b610335610550366004614045565b6116ae565b610335610563366004614194565b611841565b610393611ba9565b61039361057e366004614028565b611bce565b610393610591366004614045565b60d060209081526000928352604080842090915290825290205481565b6103356105bc366004614150565b611bf9565b61030c611c06565b6103356105d7366004614028565b611c15565b6103356105ea3660046141f1565b611cdd565b610393633b9aca0081565b61035d610608366004614045565b611ee9565b61035d61061b366004614045565b611fbf565b61035d61062e366004614028565b60cc6020526000908152604090205460ff1681565b6104e7610651366004614150565b611fcd565b61065e612004565b6040516103199190614226565b6106c5610679366004614028565b60ce6020526000908152604090208054600182015460029092015490919067ffffffffffffffff81169060ff680100000000000000008204811691690100000000000000000090041685565b60408051958652602086019490945267ffffffffffffffff9092169284019290925290151560608301521515608082015260a001610319565b61039361070c3660046140b2565b612072565b61033561071f366004614280565b612237565b6103936107323660046142f7565b73ffffffffffffffffffffffffffffffffffffffff918216600090815260346020908152604080832093909416825291909152205490565b610335610778366004614028565b6123f6565b61033561078b366004614028565b6125ca565b60606036805461079f90614325565b80601f01602080910402602001604051908101604052809291908181526020018280546107cb90614325565b80156108185780601f106107ed57610100808354040283529160200191610818565b820191906000526020600020905b8154815290600101906020018083116107fb57829003601f168201915b5050505050905090565b61082d8383836126a6565b505050565b60cd546040517f521d4de900000000000000000000000000000000000000000000000000000000815233600482015273ffffffffffffffffffffffffffffffffffffffff9091169063521d4de990602401602060405180830381865afa1580156108a0573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906108c49190614372565b6108fa576040517f99e120bc00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff8116600090815260d1602052604081205461092b9060016143be565b73ffffffffffffffffffffffffffffffffffffffff8316600081815260d160205260409081902083905551919250907f979ef83e7e7a87cb48064e296dd7e997870d50f43acf8d7ad221313526c8ca0f906109899084815260200190565b60405180910390a25050565b6000336109a3818585612911565b60019150505b92915050565b60cd546040517fe43581b800000000000000000000000000000000000000000000000000000000815233600482015273ffffffffffffffffffffffffffffffffffffffff9091169063e43581b890602401602060405180830381865afa158015610a1d573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610a419190614372565b610a77576040517fee3675d400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b610a9873ffffffffffffffffffffffffffffffffffffffff84168383612abc565b8173ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff167ffff3b3844276f57024e0b42afec1a37f75db36511e43819a4f2a63ab7862b64883604051610af791815260200190565b60405180910390a3505050565b73ffffffffffffffffffffffffffffffffffffffff8316600090815260ce60209081526040808320815160a081018352815481526001820154938101939093526002015467ffffffffffffffff81169183019190915260ff680100000000000000008204811615801560608501526901000000000000000000909204161515608083015280610b94575080608001515b15610bcb576040517fc1ab6dc100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015260009073ffffffffffffffffffffffffffffffffffffffff8716906370a0823190602401602060405180830381865afa158015610c38573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610c5c91906143d1565b8251909150610c6b86836143ea565b1115610c93578151811015610c8e578151610c879082906143be565b9450610c93565b600094505b6000610ca1610e10426143fd565b73ffffffffffffffffffffffffffffffffffffffff8816600090815260d0602090815260408083208484528252909120549085015191925090610ce488836143ea565b1115610d0f5780846020015111610cfc576000610d0c565b808460200151610d0c91906143be565b96505b610d1987826143ea565b73ffffffffffffffffffffffffffffffffffffffff8916600081815260d060209081526040808320878452909152902091909155610d599033308a612b90565b33600090815260d16020526040812054889103610da657633b9aca00856040015167ffffffffffffffff1682610d8f9190614438565b610d9991906143fd565b610da390826143be565b90505b610db08782612bee565b9450505050505b9392505050565b600033610dcc858285612d0e565b610dd7858585612ddf565b506001949350505050565b33600090815260cc602052604090205460ff16610e2b576040517ff8d2906c00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b610e358183613092565b5050565b60cd546040517fe43581b800000000000000000000000000000000000000000000000000000000815233600482015273ffffffffffffffffffffffffffffffffffffffff9091169063e43581b890602401602060405180830381865afa158015610ea7573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610ecb9190614372565b610f01576040517fee3675d400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015273ffffffffffffffffffffffffffffffffffffffff8216906370a0823190602401602060405180830381865afa158015610f6b573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610f8f91906143d1565b15610fc6576040517f2ef630ec00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff8116600090815260ce602052604081208181556001810182905560020180547fffffffffffffffffffffffffffffffffffffffffffff0000000000000000000016905560cf54905b61102e6001836143be565b811015611139578273ffffffffffffffffffffffffffffffffffffffff1660cf828154811061105f5761105f61444f565b60009182526020909120015473ffffffffffffffffffffffffffffffffffffffff16036111295760cf6110936001846143be565b815481106110a3576110a361444f565b60009182526020909120015460cf805473ffffffffffffffffffffffffffffffffffffffff90921691839081106110dc576110dc61444f565b9060005260206000200160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550611139565b6111328161447e565b9050611023565b5060cf80548061114b5761114b6144b6565b60008281526020812082017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff90810180547fffffffffffffffffffffffff000000000000000000000000000000000000000016905590910190915560405173ffffffffffffffffffffffffffffffffffffffff8416917f5c95b49c4d59d97a2f044167723f29c74b30f99702e3fd406c3830160aa9ccb891a25050565b60cd5473ffffffffffffffffffffffffffffffffffffffff16331480159061122657503373ffffffffffffffffffffffffffffffffffffffff821614155b1561125d576040517fddb5de5e00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff8116600081815260cc602052604080822080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00169055517f98c15241d6c02bc5ee0b780e11b3ea737a2defd9d04877edbe9f9497065bd02f9190a250565b33600090815260cc602052604090205460ff1661131a576040517ff8d2906c00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b61082d83838361327f565b600061132f61333a565b905090565b60cd546040517f521d4de900000000000000000000000000000000000000000000000000000000815233600482015273ffffffffffffffffffffffffffffffffffffffff9091169063521d4de990602401602060405180830381865afa1580156113a2573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906113c69190614372565b6113fc576040517f99e120bc00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff8216600090815260ce602052604090206002015468010000000000000000900460ff1661146a576040517fc1ab6dc100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff8216600081815260ce602052604090819020839055517fe7b113fba37131b6396680a0c55790a697ec975e198ff8cfd89dac90a6379e61906109899084815260200190565b33600081815260346020908152604080832073ffffffffffffffffffffffffffffffffffffffff871684529091528120549091906109a3908290869061150b9087906143ea565b612911565b60cd546040517f521d4de900000000000000000000000000000000000000000000000000000000815233600482015273ffffffffffffffffffffffffffffffffffffffff9091169063521d4de990602401602060405180830381865afa15801561157e573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906115a29190614372565b6115d8576040517f99e120bc00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60d28190556040518181527fc3b69829afe2345596a02c8b587d41f796ba0094481d899e1b2e07b7532a1e219060200160405180910390a150565b33600090815260cc602052604090205460ff1661165c576040517ff8d2906c00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b610e358282612bee565b73ffffffffffffffffffffffffffffffffffffffff8116600090815260d06020526040812081611698610e10426143fd565b8152602001908152602001600020549050919050565b60cd546040517f521d4de900000000000000000000000000000000000000000000000000000000815233600482015273ffffffffffffffffffffffffffffffffffffffff9091169063521d4de990602401602060405180830381865afa15801561171c573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906117409190614372565b611776576040517f99e120bc00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff8216600090815260ce602052604090206002015468010000000000000000900460ff166117e4576040517fc1ab6dc100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff8216600081815260ce602052604090819020600101839055517fe13ac9338b2ee623233f83c1b3ceab16490fa3e3737fac7f0970d0830a9f4871906109899084815260200190565b60cd546040517fe43581b800000000000000000000000000000000000000000000000000000000815233600482015273ffffffffffffffffffffffffffffffffffffffff9091169063e43581b890602401602060405180830381865afa1580156118af573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906118d39190614372565b611909576040517fee3675d400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff8516600090815260ce602052604090206002015468010000000000000000900460ff1680611960575073ffffffffffffffffffffffffffffffffffffffff8516155b15611997576040517fc1ab6dc100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b633b9aca008267ffffffffffffffff1611156119df576040517feca1d2c600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040805160a08101825260008082526020820181905291810182905260608101829052608081019190915284815260208082018581528315156080840190815267ffffffffffffffff808716604080870191825260016060880181815273ffffffffffffffffffffffffffffffffffffffff8e16600081815260ce9099528389208a5181559751888401559351600290970180549151965115156901000000000000000000027fffffffffffffffffffffffffffffffffffffffffffff00ffffffffffffffffff97151568010000000000000000027fffffffffffffffffffffffffffffffffffffffffffffff000000000000000000909316989096169790971717949094169290921790935560cf805492830181559093527facb8d954e2cfef495862221e91bd7523613cf8808827cb33edfe4904cc51bf290180547fffffffffffffffffffffffff0000000000000000000000000000000000000000168217905590517f53087ff85d80a7671594bd2e86b92af22e0b3c2c441c8033bba7399b7b5cbe2390611b99908890889088908890938452602084019290925267ffffffffffffffff1660408301521515606082015260800190565b60405180910390a2505050505050565b600060d381611bba610e10426143fd565b815260200190815260200160002054905090565b73ffffffffffffffffffffffffffffffffffffffff81166000908152609960205260408120546109a9565b611c033382613092565b50565b60606037805461079f90614325565b60cd5473ffffffffffffffffffffffffffffffffffffffff163314611c66576040517fb90cdbb100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff8116600081815260cc602052604080822080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00166001179055517f98c15241d6c02bc5ee0b780e11b3ea737a2defd9d04877edbe9f9497065bd02f9190a250565b60cd546040517f521d4de900000000000000000000000000000000000000000000000000000000815233600482015273ffffffffffffffffffffffffffffffffffffffff9091169063521d4de990602401602060405180830381865afa158015611d4b573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611d6f9190614372565b611da5576040517f99e120bc00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff8216600090815260ce602052604090206002015468010000000000000000900460ff16611e13576040517fc1ab6dc100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b633b9aca008167ffffffffffffffff161115611e5b576040517feca1d2c600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff8216600081815260ce602090815260409182902060020180547fffffffffffffffffffffffffffffffffffffffffffffffff00000000000000001667ffffffffffffffff861690811790915591519182527f901f9de19b475adc8da4110434b8df940dce085afd05e2281c86807f3a899d299101610989565b33600081815260346020908152604080832073ffffffffffffffffffffffffffffffffffffffff8716845290915281205490919083811015611fb2576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602560248201527f45524332303a2064656372656173656420616c6c6f77616e63652062656c6f7760448201527f207a65726f00000000000000000000000000000000000000000000000000000060648201526084015b60405180910390fd5b610dd78286868403612911565b6000336109a3818585612ddf565b60cf8181548110611fdd57600080fd5b60009182526020909120015473ffffffffffffffffffffffffffffffffffffffff16905081565b606060cf80548060200260200160405190810160405280929190818152602001828054801561081857602002820191906000526020600020905b815473ffffffffffffffffffffffffffffffffffffffff16815260019091019060200180831161203e575050505050905090565b73ffffffffffffffffffffffffffffffffffffffff8316600090815260ce60209081526040808320815160a081018352815481526001820154938101939093526002015467ffffffffffffffff81169183019190915260ff680100000000000000008204811615801560608501526901000000000000000000909204161515608083015280612102575080608001515b15612139576040517fc1ab6dc100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000612147610e10426143fd565b600081815260d36020526040812054919250906121659087906143ea565b905060d2548111156121a3576040517f6d43d1ac00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600082815260d3602052604090208190556121be3387613092565b33600090815260d1602052604081205487910361220b57633b9aca00846040015167ffffffffffffffff16826121f49190614438565b6121fe91906143fd565b61220890826143be565b90505b61222c73ffffffffffffffffffffffffffffffffffffffff89168783612abc565b979650505050505050565b834211156122a1576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f45524332305065726d69743a206578706972656420646561646c696e650000006044820152606401611fa9565b60007f6e71edae12b1b97f4d1f60370fef10105fa2faae0126114a169c64845d6126c98888886122d08c6133b5565b60408051602081019690965273ffffffffffffffffffffffffffffffffffffffff94851690860152929091166060840152608083015260a082015260c0810186905260e0016040516020818303038152906040528051906020012090506000612338826133ea565b9050600061234882878787613453565b90508973ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16146123df576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601e60248201527f45524332305065726d69743a20696e76616c6964207369676e617475726500006044820152606401611fa9565b6123ea8a8a8a612911565b50505050505050505050565b60cd546040517f521d4de900000000000000000000000000000000000000000000000000000000815233600482015273ffffffffffffffffffffffffffffffffffffffff9091169063521d4de990602401602060405180830381865afa158015612464573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906124889190614372565b6124be576040517f99e120bc00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff8116600090815260ce602052604090206002015468010000000000000000900460ff1661252c576040517fc1ab6dc100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff8116600081815260ce602090815260409182902060020180547fffffffffffffffffffffffffffffffffffffffffffff00ffffffffffffffffff811669010000000000000000009182900460ff16801592830291909117909255925192835292917ff7c93079dcbf699749d66345a351afab7d24219bb1d915c9f4fc4cf03f00d3979101610989565b60cd5473ffffffffffffffffffffffffffffffffffffffff16331461261b576040517fb90cdbb100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60cd80547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83169081179091556040517f7dae230f18360d76a040c81f050aa14eb9d6dc7901b20fc5d855e2a20fe814d190600090a250565b73ffffffffffffffffffffffffffffffffffffffff163b151590565b600054610100900460ff16158080156126c65750600054600160ff909116105b806126e05750303b1580156126e0575060005460ff166001145b61276c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201527f647920696e697469616c697a65640000000000000000000000000000000000006064820152608401611fa9565b600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0016600117905580156127ca57600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff166101001790555b3073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1663e9cbd8226040518163ffffffff1660e01b8152600401602060405180830381865afa15801561282c573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061285091906144e5565b73ffffffffffffffffffffffffffffffffffffffff161461289d576040517f14bcf5c800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6128a884848461347b565b801561290b57600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15b50505050565b73ffffffffffffffffffffffffffffffffffffffff83166129b3576040517f08c379a0000000000000000000000000000000000000000000000000000000008152602060048201526024808201527f45524332303a20617070726f76652066726f6d20746865207a65726f2061646460448201527f72657373000000000000000000000000000000000000000000000000000000006064820152608401611fa9565b73ffffffffffffffffffffffffffffffffffffffff8216612a56576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602260248201527f45524332303a20617070726f766520746f20746865207a65726f20616464726560448201527f73730000000000000000000000000000000000000000000000000000000000006064820152608401611fa9565b73ffffffffffffffffffffffffffffffffffffffff83811660008181526034602090815260408083209487168084529482529182902085905590518481527f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b9259101610af7565b60405173ffffffffffffffffffffffffffffffffffffffff831660248201526044810182905261082d9084907fa9059cbb00000000000000000000000000000000000000000000000000000000906064015b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff00000000000000000000000000000000000000000000000000000000909316929092179091526134ff565b60405173ffffffffffffffffffffffffffffffffffffffff8085166024830152831660448201526064810182905261290b9085907f23b872dd0000000000000000000000000000000000000000000000000000000090608401612b0e565b73ffffffffffffffffffffffffffffffffffffffff8216612c6b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601f60248201527f45524332303a206d696e7420746f20746865207a65726f2061646472657373006044820152606401611fa9565b8060356000828254612c7d91906143ea565b909155505073ffffffffffffffffffffffffffffffffffffffff821660009081526033602052604081208054839290612cb79084906143ea565b909155505060405181815273ffffffffffffffffffffffffffffffffffffffff8316906000907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef9060200160405180910390a35050565b73ffffffffffffffffffffffffffffffffffffffff8381166000908152603460209081526040808320938616835292905220547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff811461290b5781811015612dd2576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f45524332303a20696e73756666696369656e7420616c6c6f77616e63650000006044820152606401611fa9565b61290b8484848403612911565b73ffffffffffffffffffffffffffffffffffffffff8316612e82576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602560248201527f45524332303a207472616e736665722066726f6d20746865207a65726f20616460448201527f64726573730000000000000000000000000000000000000000000000000000006064820152608401611fa9565b73ffffffffffffffffffffffffffffffffffffffff8216612f25576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602360248201527f45524332303a207472616e7366657220746f20746865207a65726f206164647260448201527f65737300000000000000000000000000000000000000000000000000000000006064820152608401611fa9565b73ffffffffffffffffffffffffffffffffffffffff831660009081526033602052604090205481811015612fdb576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f45524332303a207472616e7366657220616d6f756e742065786365656473206260448201527f616c616e636500000000000000000000000000000000000000000000000000006064820152608401611fa9565b73ffffffffffffffffffffffffffffffffffffffff80851660009081526033602052604080822085850390559185168152908120805484929061301f9084906143ea565b925050819055508273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef8460405161308591815260200190565b60405180910390a361290b565b73ffffffffffffffffffffffffffffffffffffffff8216613135576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602160248201527f45524332303a206275726e2066726f6d20746865207a65726f2061646472657360448201527f73000000000000000000000000000000000000000000000000000000000000006064820152608401611fa9565b73ffffffffffffffffffffffffffffffffffffffff8216600090815260336020526040902054818110156131eb576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602260248201527f45524332303a206275726e20616d6f756e7420657863656564732062616c616e60448201527f63650000000000000000000000000000000000000000000000000000000000006064820152608401611fa9565b73ffffffffffffffffffffffffffffffffffffffff831660009081526033602052604081208383039055603580548492906132279084906143be565b909155505060405182815260009073ffffffffffffffffffffffffffffffffffffffff8516907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef9060200160405180910390a3505050565b8073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff16146133305773ffffffffffffffffffffffffffffffffffffffff8281166000908152603460209081526040808320938516835292905220548381101561331f576040517f715ec26c00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b61332e838361150b87856143be565b505b61082d8284613092565b600061132f7f8b73c3c69bb8fe3d512ecc4cf759cc79239f7b179b0ffacaa9a75d522b39400f61336960655490565b6066546040805160208101859052908101839052606081018290524660808201523060a082015260009060c0016040516020818303038152906040528051906020012090509392505050565b73ffffffffffffffffffffffffffffffffffffffff811660009081526099602052604090208054600181018255905b50919050565b60006109a96133f761333a565b836040517f19010000000000000000000000000000000000000000000000000000000000006020820152602281018390526042810182905260009060620160405160208183030381529060405280519060200120905092915050565b60008060006134648787878761360b565b9150915061347181613723565b5095945050505050565b61348483613977565b61348e8383613a4d565b60cd80547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83169081179091556040517f7dae230f18360d76a040c81f050aa14eb9d6dc7901b20fc5d855e2a20fe814d190600090a2505050565b6000613561826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c65648152508573ffffffffffffffffffffffffffffffffffffffff16613aee9092919063ffffffff16565b80519091501561082d578080602001905181019061357f9190614372565b61082d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e60448201527f6f742073756363656564000000000000000000000000000000000000000000006064820152608401611fa9565b6000807f7fffffffffffffffffffffffffffffff5d576e7357a4501ddfe92f46681b20a0831115613642575060009050600361371a565b8460ff16601b1415801561365a57508460ff16601c14155b1561366b575060009050600461371a565b6040805160008082526020820180845289905260ff881692820192909252606081018690526080810185905260019060a0016020604051602081039080840390855afa1580156136bf573d6000803e3d6000fd5b50506040517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0015191505073ffffffffffffffffffffffffffffffffffffffff81166137135760006001925092505061371a565b9150600090505b94509492505050565b600081600481111561373757613737614502565b0361373f5750565b600181600481111561375357613753614502565b036137ba576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601860248201527f45434453413a20696e76616c6964207369676e617475726500000000000000006044820152606401611fa9565b60028160048111156137ce576137ce614502565b03613835576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601f60248201527f45434453413a20696e76616c6964207369676e6174757265206c656e677468006044820152606401611fa9565b600381600481111561384957613849614502565b036138d6576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602260248201527f45434453413a20696e76616c6964207369676e6174757265202773272076616c60448201527f75650000000000000000000000000000000000000000000000000000000000006064820152608401611fa9565b60048160048111156138ea576138ea614502565b03611c03576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602260248201527f45434453413a20696e76616c6964207369676e6174757265202776272076616c60448201527f75650000000000000000000000000000000000000000000000000000000000006064820152608401611fa9565b600054610100900460ff16613a0e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201527f6e697469616c697a696e670000000000000000000000000000000000000000006064820152608401611fa9565b611c03816040518060400160405280600181526020017f3100000000000000000000000000000000000000000000000000000000000000815250613b05565b600054610100900460ff16613ae4576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201527f6e697469616c697a696e670000000000000000000000000000000000000000006064820152608401611fa9565b610e358282613bb6565b6060613afd8484600085613c66565b949350505050565b600054610100900460ff16613b9c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201527f6e697469616c697a696e670000000000000000000000000000000000000000006064820152608401611fa9565b815160209283012081519190920120606591909155606655565b600054610100900460ff16613c4d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201527f6e697469616c697a696e670000000000000000000000000000000000000000006064820152608401611fa9565b6036613c59838261457f565b50603761082d828261457f565b606082471015613cf8576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f60448201527f722063616c6c00000000000000000000000000000000000000000000000000006064820152608401611fa9565b73ffffffffffffffffffffffffffffffffffffffff85163b613d76576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006044820152606401611fa9565b6000808673ffffffffffffffffffffffffffffffffffffffff168587604051613d9f9190614699565b60006040518083038185875af1925050503d8060008114613ddc576040519150601f19603f3d011682016040523d82523d6000602084013e613de1565b606091505b509150915061222c82828660608315613dfb575081610db7565b825115613e0b5782518084602001fd5b816040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611fa99190613e63565b60005b83811015613e5a578181015183820152602001613e42565b50506000910152565b6020815260008251806020840152613e82816040850160208701613e3f565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169190910160400192915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b600082601f830112613ef457600080fd5b813567ffffffffffffffff80821115613f0f57613f0f613eb4565b604051601f83017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0908116603f01168101908282118183101715613f5557613f55613eb4565b81604052838152866020858801011115613f6e57600080fd5b836020870160208301376000602085830101528094505050505092915050565b73ffffffffffffffffffffffffffffffffffffffff81168114611c0357600080fd5b600080600060608486031215613fc557600080fd5b833567ffffffffffffffff80821115613fdd57600080fd5b613fe987838801613ee3565b94506020860135915080821115613fff57600080fd5b5061400c86828701613ee3565b925050604084013561401d81613f8e565b809150509250925092565b60006020828403121561403a57600080fd5b8135610db781613f8e565b6000806040838503121561405857600080fd5b823561406381613f8e565b946020939093013593505050565b60008060006060848603121561408657600080fd5b833561409181613f8e565b925060208401356140a181613f8e565b929592945050506040919091013590565b6000806000606084860312156140c757600080fd5b83356140d281613f8e565b925060208401359150604084013561401d81613f8e565b600080604083850312156140fc57600080fd5b82359150602083013561410e81613f8e565b809150509250929050565b60008060006060848603121561412e57600080fd5b83359250602084013561414081613f8e565b9150604084013561401d81613f8e565b60006020828403121561416257600080fd5b5035919050565b803567ffffffffffffffff8116811461418157600080fd5b919050565b8015158114611c0357600080fd5b600080600080600060a086880312156141ac57600080fd5b85356141b781613f8e565b945060208601359350604086013592506141d360608701614169565b915060808601356141e381614186565b809150509295509295909350565b6000806040838503121561420457600080fd5b823561420f81613f8e565b915061421d60208401614169565b90509250929050565b6020808252825182820181905260009190848201906040850190845b8181101561427457835173ffffffffffffffffffffffffffffffffffffffff1683529284019291840191600101614242565b50909695505050505050565b600080600080600080600060e0888a03121561429b57600080fd5b87356142a681613f8e565b965060208801356142b681613f8e565b95506040880135945060608801359350608088013560ff811681146142da57600080fd5b9699959850939692959460a0840135945060c09093013592915050565b6000806040838503121561430a57600080fd5b823561431581613f8e565b9150602083013561410e81613f8e565b600181811c9082168061433957607f821691505b6020821081036133e4577f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b60006020828403121561438457600080fd5b8151610db781614186565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b818103818111156109a9576109a961438f565b6000602082840312156143e357600080fd5b5051919050565b808201808211156109a9576109a961438f565b600082614433577f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b500490565b80820281158282048414176109a9576109a961438f565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82036144af576144af61438f565b5060010190565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603160045260246000fd5b6000602082840312156144f757600080fd5b8151610db781613f8e565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b601f82111561082d57600081815260208120601f850160051c810160208610156145585750805b601f850160051c820191505b8181101561457757828155600101614564565b505050505050565b815167ffffffffffffffff81111561459957614599613eb4565b6145ad816145a78454614325565b84614531565b602080601f83116001811461460057600084156145ca5750858301515b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600386901b1c1916600185901b178555614577565b6000858152602081207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08616915b8281101561464d5788860151825594840194600190910190840161462e565b508582101561468957878501517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600388901b60f8161c191681555b5050505050600190811b01905550565b600082516146ab818460208701613e3f565b919091019291505056fea264697066735822122063a1b6264cdcf054e5097307e409d188b47c62ad909903d6edaf55a3d2b19dee64736f6c63430008110033", + "numDeployments": 2, + "solcInputHash": "871924e0c138825a2736b76def8fef8d", + "metadata": "{\"compiler\":{\"version\":\"0.8.17+commit.8df45f5f\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[],\"name\":\"AssetStillControlledInReserves\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"BurnAmountExceedsAllowance\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"HourlyLimitExceeded\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidSender\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidToken\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidTreasury\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"NotGovernor\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"NotGovernorOrGuardian\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"NotMinter\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"NotTreasury\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"TooBigAmount\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"TooHighParameterValue\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ZeroAddress\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"spender\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"}],\"name\":\"Approval\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"bridgeToken\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"limit\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"hourlyLimit\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"fee\",\"type\":\"uint64\"},{\"indexed\":false,\"internalType\":\"bool\",\"name\":\"paused\",\"type\":\"bool\"}],\"name\":\"BridgeTokenAdded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"bridgeToken\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"fee\",\"type\":\"uint64\"}],\"name\":\"BridgeTokenFeeUpdated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"bridgeToken\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"hourlyLimit\",\"type\":\"uint256\"}],\"name\":\"BridgeTokenHourlyLimitUpdated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"bridgeToken\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"limit\",\"type\":\"uint256\"}],\"name\":\"BridgeTokenLimitUpdated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"bridgeToken\",\"type\":\"address\"}],\"name\":\"BridgeTokenRemoved\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"bridgeToken\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"bool\",\"name\":\"toggleStatus\",\"type\":\"bool\"}],\"name\":\"BridgeTokenToggled\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"theAddress\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"toggleStatus\",\"type\":\"uint256\"}],\"name\":\"FeeToggled\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"hourlyLimit\",\"type\":\"uint256\"}],\"name\":\"HourlyLimitUpdated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint8\",\"name\":\"version\",\"type\":\"uint8\"}],\"name\":\"Initialized\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"minter\",\"type\":\"address\"}],\"name\":\"MinterToggled\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"Recovered\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"}],\"name\":\"Transfer\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"_treasury\",\"type\":\"address\"}],\"name\":\"TreasuryUpdated\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"BASE_PARAMS\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"DOMAIN_SEPARATOR\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"bridgeToken\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"limit\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"hourlyLimit\",\"type\":\"uint256\"},{\"internalType\":\"uint64\",\"name\":\"fee\",\"type\":\"uint64\"},{\"internalType\":\"bool\",\"name\":\"paused\",\"type\":\"bool\"}],\"name\":\"addBridgeToken\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"minter\",\"type\":\"address\"}],\"name\":\"addMinter\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"allBridgeTokens\",\"outputs\":[{\"internalType\":\"address[]\",\"name\":\"\",\"type\":\"address[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"spender\",\"type\":\"address\"}],\"name\":\"allowance\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"spender\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"approve\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"}],\"name\":\"balanceOf\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"name\":\"bridgeTokensList\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"bridges\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"limit\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"hourlyLimit\",\"type\":\"uint256\"},{\"internalType\":\"uint64\",\"name\":\"fee\",\"type\":\"uint64\"},{\"internalType\":\"bool\",\"name\":\"allowed\",\"type\":\"bool\"},{\"internalType\":\"bool\",\"name\":\"paused\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"burner\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"}],\"name\":\"burnFrom\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"burner\",\"type\":\"address\"}],\"name\":\"burnSelf\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"burnStablecoin\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"chainTotalHourlyLimit\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"name\":\"chainTotalUsage\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"currentTotalUsage\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"bridgeToken\",\"type\":\"address\"}],\"name\":\"currentUsage\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"decimals\",\"outputs\":[{\"internalType\":\"uint8\",\"name\":\"\",\"type\":\"uint8\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"spender\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"subtractedValue\",\"type\":\"uint256\"}],\"name\":\"decreaseAllowance\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"spender\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"addedValue\",\"type\":\"uint256\"}],\"name\":\"increaseAllowance\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"string\",\"name\":\"name_\",\"type\":\"string\"},{\"internalType\":\"string\",\"name\":\"symbol_\",\"type\":\"string\"},{\"internalType\":\"address\",\"name\":\"_treasury\",\"type\":\"address\"}],\"name\":\"initialize\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"isFeeExempt\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"isMinter\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"mint\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"name\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"}],\"name\":\"nonces\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"spender\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"deadline\",\"type\":\"uint256\"},{\"internalType\":\"uint8\",\"name\":\"v\",\"type\":\"uint8\"},{\"internalType\":\"bytes32\",\"name\":\"r\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32\",\"name\":\"s\",\"type\":\"bytes32\"}],\"name\":\"permit\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"tokenAddress\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amountToRecover\",\"type\":\"uint256\"}],\"name\":\"recoverERC20\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"bridgeToken\",\"type\":\"address\"}],\"name\":\"removeBridgeToken\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"minter\",\"type\":\"address\"}],\"name\":\"removeMinter\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"hourlyLimit\",\"type\":\"uint256\"}],\"name\":\"setChainTotalHourlyLimit\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"bridgeToken\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"hourlyLimit\",\"type\":\"uint256\"}],\"name\":\"setHourlyLimit\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"bridgeToken\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"limit\",\"type\":\"uint256\"}],\"name\":\"setLimit\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"bridgeToken\",\"type\":\"address\"},{\"internalType\":\"uint64\",\"name\":\"fee\",\"type\":\"uint64\"}],\"name\":\"setSwapFee\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_treasury\",\"type\":\"address\"}],\"name\":\"setTreasury\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"bridgeToken\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"swapIn\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"bridgeToken\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"swapOut\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"symbol\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"bridgeToken\",\"type\":\"address\"}],\"name\":\"toggleBridge\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"theAddress\",\"type\":\"address\"}],\"name\":\"toggleFeesForAddress\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"totalSupply\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"transfer\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"transferFrom\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"treasury\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"name\":\"usage\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"}],\"devdoc\":{\"author\":\"Angle Labs, Inc.\",\"details\":\"This contract supports bridge tokens having a minting right on the stablecoin (also referred to as the canonical or the native token)\",\"kind\":\"dev\",\"methods\":{\"DOMAIN_SEPARATOR()\":{\"details\":\"See {IERC20Permit-DOMAIN_SEPARATOR}.\"},\"addBridgeToken(address,uint256,uint256,uint64,bool)\":{\"params\":{\"bridgeToken\":\"Bridge token to add: it should be a version of the stablecoin from another bridge\",\"fee\":\"Fee taken upon swapping for or against this token\",\"hourlyLimit\":\"Limit on the hourly volume for this bridge\",\"limit\":\"Limit on the balance of bridge token this contract could hold\",\"paused\":\"Whether swapping for this token should be paused or not\"}},\"addMinter(address)\":{\"details\":\"Zero address checks are performed directly in the `Treasury` contract\",\"params\":{\"minter\":\"Minter address to add\"}},\"allBridgeTokens()\":{\"details\":\"Helpful for UIs\"},\"allowance(address,address)\":{\"details\":\"See {IERC20-allowance}.\"},\"approve(address,uint256)\":{\"details\":\"See {IERC20-approve}. NOTE: If `amount` is the maximum `uint256`, the allowance is not updated on `transferFrom`. This is semantically equivalent to an infinite approval. Requirements: - `spender` cannot be the zero address.\"},\"balanceOf(address)\":{\"details\":\"See {IERC20-balanceOf}.\"},\"burnFrom(uint256,address,address)\":{\"details\":\"This method is to be called by a contract with the minter right after being requested to do so by a `sender` address willing to burn tokens from another `burner` addressThe method checks the allowance between the `sender` and the `burner`\",\"params\":{\"amount\":\"Amount of tokens to burn\",\"burner\":\"Address to burn from\",\"sender\":\"Address which requested the burn from `burner`\"}},\"burnSelf(uint256,address)\":{\"details\":\"This method is to be called by a contract with a minter right on the AgToken after being requested to do so by an address willing to burn tokens from its address\",\"params\":{\"amount\":\"Amount of tokens to burn\",\"burner\":\"Address to burn from\"}},\"burnStablecoin(uint256)\":{\"details\":\"This function can typically be called if there is a settlement mechanism to burn stablecoins\",\"params\":{\"amount\":\"Amount of stablecoins to burn\"}},\"currentTotalUsage()\":{\"details\":\"Helpful for UIs\"},\"currentUsage(address)\":{\"details\":\"Helpful for UIs\",\"params\":{\"bridgeToken\":\"Bridge used to mint\"}},\"decimals()\":{\"details\":\"Returns the number of decimals used to get its user representation. For example, if `decimals` equals `2`, a balance of `505` tokens should be displayed to a user as `5.05` (`505 / 10 ** 2`). Tokens usually opt for a value of 18, imitating the relationship between Ether and Wei. This is the value {ERC20} uses, unless this function is overridden; NOTE: This information is only used for _display_ purposes: it in no way affects any of the arithmetic of the contract, including {IERC20-balanceOf} and {IERC20-transfer}.\"},\"decreaseAllowance(address,uint256)\":{\"details\":\"Atomically decreases the allowance granted to `spender` by the caller. This is an alternative to {approve} that can be used as a mitigation for problems described in {IERC20-approve}. Emits an {Approval} event indicating the updated allowance. Requirements: - `spender` cannot be the zero address. - `spender` must have allowance for the caller of at least `subtractedValue`.\"},\"increaseAllowance(address,uint256)\":{\"details\":\"Atomically increases the allowance granted to `spender` by the caller. This is an alternative to {approve} that can be used as a mitigation for problems described in {IERC20-approve}. Emits an {Approval} event indicating the updated allowance. Requirements: - `spender` cannot be the zero address.\"},\"mint(address,uint256)\":{\"details\":\"The contracts allowed to issue agTokens are the `StableMaster` contract, `VaultManager` contracts associated to this stablecoin as well as the flash loan module (if activated) and potentially contracts whitelisted by governance\",\"params\":{\"account\":\"Address to mint to\",\"amount\":\"Amount to mint\"}},\"name()\":{\"details\":\"Returns the name of the token.\"},\"nonces(address)\":{\"details\":\"See {IERC20Permit-nonces}.\"},\"permit(address,address,uint256,uint256,uint8,bytes32,bytes32)\":{\"details\":\"See {IERC20Permit-permit}.\"},\"recoverERC20(address,address,uint256)\":{\"details\":\"Can be used to withdraw bridge tokens for them to be de-bridged on mainnet\"},\"removeBridgeToken(address)\":{\"params\":{\"bridgeToken\":\"Address of the bridge token to remove support for\"}},\"removeMinter(address)\":{\"details\":\"This function can also be called by a minter wishing to revoke itself\",\"params\":{\"minter\":\"Minter address to remove\"}},\"setTreasury(address)\":{\"params\":{\"_treasury\":\"New treasury address\"}},\"swapIn(address,uint256,address)\":{\"details\":\"Some fees may be taken by the protocol depending on the token used and on the address calling\",\"params\":{\"amount\":\"Amount of bridge tokens to send\",\"bridgeToken\":\"Bridge token to use to mint\",\"to\":\"Address to which the stablecoin should be sent\"},\"returns\":{\"_0\":\"Amount of the canonical stablecoin actually minted\"}},\"swapOut(address,uint256,address)\":{\"details\":\"Some fees may be taken by the protocol depending on the token used and on the address calling\",\"params\":{\"amount\":\"Amount of canonical tokens to burn\",\"bridgeToken\":\"Bridge token required\",\"to\":\"Address to which the bridge token should be sent\"},\"returns\":{\"_0\":\"Amount of bridge tokens actually sent back\"}},\"symbol()\":{\"details\":\"Returns the symbol of the token, usually a shorter version of the name.\"},\"totalSupply()\":{\"details\":\"See {IERC20-totalSupply}.\"},\"transfer(address,uint256)\":{\"details\":\"See {IERC20-transfer}. Requirements: - `to` cannot be the zero address. - the caller must have a balance of at least `amount`.\"},\"transferFrom(address,address,uint256)\":{\"details\":\"See {IERC20-transferFrom}. Emits an {Approval} event indicating the updated allowance. This is not required by the EIP. See the note at the beginning of {ERC20}. NOTE: Does not update the allowance if the current allowance is the maximum `uint256`. Requirements: - `from` and `to` cannot be the zero address. - `from` must have a balance of at least `amount`. - the caller must have allowance for ``from``'s tokens of at least `amount`.\"}},\"title\":\"AgTokenSideChainMultiBridge\",\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{\"BASE_PARAMS()\":{\"notice\":\"Base used for fee computation\"},\"addBridgeToken(address,uint256,uint256,uint64,bool)\":{\"notice\":\"Adds support for a bridge token\"},\"addMinter(address)\":{\"notice\":\"Adds a minter in the contract\"},\"allBridgeTokens()\":{\"notice\":\"Returns the list of all supported bridge tokens\"},\"bridgeTokensList(uint256)\":{\"notice\":\"List of all bridge tokens\"},\"bridges(address)\":{\"notice\":\"Maps a bridge token to data\"},\"burnFrom(uint256,address,address)\":{\"notice\":\"Burns `amount` tokens from a `burner` address after being asked to by `sender`\"},\"burnSelf(uint256,address)\":{\"notice\":\"Burns `amount` tokens from a `burner` address\"},\"burnStablecoin(uint256)\":{\"notice\":\"Allows anyone to burn stablecoins\"},\"chainTotalHourlyLimit()\":{\"notice\":\"Limit to the amount of tokens that can be sent from that chain to another chain\"},\"chainTotalUsage(uint256)\":{\"notice\":\"Usage per hour on that chain. Maps an hourly timestamp to the total volume swapped out on the chain\"},\"currentTotalUsage()\":{\"notice\":\"Returns the current total volume on the chain for the current hour\"},\"currentUsage(address)\":{\"notice\":\"Returns the current volume for a bridge, for the current hour\"},\"initialize(string,string,address)\":{\"notice\":\"Initializes the `AgToken` contract\"},\"isFeeExempt(address)\":{\"notice\":\"Maps an address to whether it is exempt of fees for when it comes to swapping in and out\"},\"isMinter(address)\":{\"notice\":\"Checks whether an address has the right to mint agTokens\"},\"mint(address,uint256)\":{\"notice\":\"Lets the `StableMaster` contract or another whitelisted contract mint agTokens\"},\"recoverERC20(address,address,uint256)\":{\"notice\":\"Recovers any ERC20 token\"},\"removeBridgeToken(address)\":{\"notice\":\"Removes support for a token\"},\"removeMinter(address)\":{\"notice\":\"Removes a minter from the contract\"},\"setChainTotalHourlyLimit(uint256)\":{\"notice\":\"Updates the `chainTotalHourlyLimit` amount\"},\"setHourlyLimit(address,uint256)\":{\"notice\":\"Updates the `hourlyLimit` amount for `bridgeToken`\"},\"setLimit(address,uint256)\":{\"notice\":\"Updates the `limit` amount for `bridgeToken`\"},\"setSwapFee(address,uint64)\":{\"notice\":\"Updates the `fee` value for `bridgeToken`\"},\"setTreasury(address)\":{\"notice\":\"Sets a new treasury contract\"},\"swapIn(address,uint256,address)\":{\"notice\":\"Mints the canonical token from a supported bridge token\"},\"swapOut(address,uint256,address)\":{\"notice\":\"Burns the canonical token in exchange for a bridge token\"},\"toggleBridge(address)\":{\"notice\":\"Pauses or unpauses swapping in and out for a token\"},\"toggleFeesForAddress(address)\":{\"notice\":\"Toggles fees for the address `theAddress`\"},\"treasury()\":{\"notice\":\"Reference to the treasury contract which can grant minting rights\"},\"usage(address,uint256)\":{\"notice\":\"Maps a bridge token to the associated hourly volume\"}},\"notice\":\"Contract for Angle agTokens on other chains than Ethereum mainnet\",\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/agToken/AgTokenSideChainMultiBridge.sol\":\"AgTokenSideChainMultiBridge\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":1000000},\"remappings\":[]},\"sources\":{\"@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.7.0) (proxy/utils/Initializable.sol)\\n\\npragma solidity ^0.8.2;\\n\\nimport \\\"../../utils/AddressUpgradeable.sol\\\";\\n\\n/**\\n * @dev This is a base contract to aid in writing upgradeable contracts, or any kind of contract that will be deployed\\n * behind a proxy. Since proxied contracts do not make use of a constructor, it's common to move constructor logic to an\\n * external initializer function, usually called `initialize`. It then becomes necessary to protect this initializer\\n * function so it can only be called once. The {initializer} modifier provided by this contract will have this effect.\\n *\\n * The initialization functions use a version number. Once a version number is used, it is consumed and cannot be\\n * reused. This mechanism prevents re-execution of each \\\"step\\\" but allows the creation of new initialization steps in\\n * case an upgrade adds a module that needs to be initialized.\\n *\\n * For example:\\n *\\n * [.hljs-theme-light.nopadding]\\n * ```\\n * contract MyToken is ERC20Upgradeable {\\n * function initialize() initializer public {\\n * __ERC20_init(\\\"MyToken\\\", \\\"MTK\\\");\\n * }\\n * }\\n * contract MyTokenV2 is MyToken, ERC20PermitUpgradeable {\\n * function initializeV2() reinitializer(2) public {\\n * __ERC20Permit_init(\\\"MyToken\\\");\\n * }\\n * }\\n * ```\\n *\\n * TIP: To avoid leaving the proxy in an uninitialized state, the initializer function should be called as early as\\n * possible by providing the encoded function call as the `_data` argument to {ERC1967Proxy-constructor}.\\n *\\n * CAUTION: When used with inheritance, manual care must be taken to not invoke a parent initializer twice, or to ensure\\n * that all initializers are idempotent. This is not verified automatically as constructors are by Solidity.\\n *\\n * [CAUTION]\\n * ====\\n * Avoid leaving a contract uninitialized.\\n *\\n * An uninitialized contract can be taken over by an attacker. This applies to both a proxy and its implementation\\n * contract, which may impact the proxy. To prevent the implementation contract from being used, you should invoke\\n * the {_disableInitializers} function in the constructor to automatically lock it when it is deployed:\\n *\\n * [.hljs-theme-light.nopadding]\\n * ```\\n * /// @custom:oz-upgrades-unsafe-allow constructor\\n * constructor() {\\n * _disableInitializers();\\n * }\\n * ```\\n * ====\\n */\\nabstract contract Initializable {\\n /**\\n * @dev Indicates that the contract has been initialized.\\n * @custom:oz-retyped-from bool\\n */\\n uint8 private _initialized;\\n\\n /**\\n * @dev Indicates that the contract is in the process of being initialized.\\n */\\n bool private _initializing;\\n\\n /**\\n * @dev Triggered when the contract has been initialized or reinitialized.\\n */\\n event Initialized(uint8 version);\\n\\n /**\\n * @dev A modifier that defines a protected initializer function that can be invoked at most once. In its scope,\\n * `onlyInitializing` functions can be used to initialize parent contracts. Equivalent to `reinitializer(1)`.\\n */\\n modifier initializer() {\\n bool isTopLevelCall = !_initializing;\\n require(\\n (isTopLevelCall && _initialized < 1) || (!AddressUpgradeable.isContract(address(this)) && _initialized == 1),\\n \\\"Initializable: contract is already initialized\\\"\\n );\\n _initialized = 1;\\n if (isTopLevelCall) {\\n _initializing = true;\\n }\\n _;\\n if (isTopLevelCall) {\\n _initializing = false;\\n emit Initialized(1);\\n }\\n }\\n\\n /**\\n * @dev A modifier that defines a protected reinitializer function that can be invoked at most once, and only if the\\n * contract hasn't been initialized to a greater version before. In its scope, `onlyInitializing` functions can be\\n * used to initialize parent contracts.\\n *\\n * `initializer` is equivalent to `reinitializer(1)`, so a reinitializer may be used after the original\\n * initialization step. This is essential to configure modules that are added through upgrades and that require\\n * initialization.\\n *\\n * Note that versions can jump in increments greater than 1; this implies that if multiple reinitializers coexist in\\n * a contract, executing them in the right order is up to the developer or operator.\\n */\\n modifier reinitializer(uint8 version) {\\n require(!_initializing && _initialized < version, \\\"Initializable: contract is already initialized\\\");\\n _initialized = version;\\n _initializing = true;\\n _;\\n _initializing = false;\\n emit Initialized(version);\\n }\\n\\n /**\\n * @dev Modifier to protect an initialization function so that it can only be invoked by functions with the\\n * {initializer} and {reinitializer} modifiers, directly or indirectly.\\n */\\n modifier onlyInitializing() {\\n require(_initializing, \\\"Initializable: contract is not initializing\\\");\\n _;\\n }\\n\\n /**\\n * @dev Locks the contract, preventing any future reinitialization. This cannot be part of an initializer call.\\n * Calling this in the constructor of a contract will prevent that contract from being initialized or reinitialized\\n * to any version. It is recommended to use this to lock implementation contracts that are designed to be called\\n * through proxies.\\n */\\n function _disableInitializers() internal virtual {\\n require(!_initializing, \\\"Initializable: contract is initializing\\\");\\n if (_initialized < type(uint8).max) {\\n _initialized = type(uint8).max;\\n emit Initialized(type(uint8).max);\\n }\\n }\\n}\\n\",\"keccak256\":\"0x0203dcadc5737d9ef2c211d6fa15d18ebc3b30dfa51903b64870b01a062b0b4e\",\"license\":\"MIT\"},\"@openzeppelin/contracts-upgradeable/token/ERC20/ERC20Upgradeable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.7.0) (token/ERC20/ERC20.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"./IERC20Upgradeable.sol\\\";\\nimport \\\"./extensions/IERC20MetadataUpgradeable.sol\\\";\\nimport \\\"../../utils/ContextUpgradeable.sol\\\";\\nimport \\\"../../proxy/utils/Initializable.sol\\\";\\n\\n/**\\n * @dev Implementation of the {IERC20} interface.\\n *\\n * This implementation is agnostic to the way tokens are created. This means\\n * that a supply mechanism has to be added in a derived contract using {_mint}.\\n * For a generic mechanism see {ERC20PresetMinterPauser}.\\n *\\n * TIP: For a detailed writeup see our guide\\n * https://forum.zeppelin.solutions/t/how-to-implement-erc20-supply-mechanisms/226[How\\n * to implement supply mechanisms].\\n *\\n * We have followed general OpenZeppelin Contracts guidelines: functions revert\\n * instead returning `false` on failure. This behavior is nonetheless\\n * conventional and does not conflict with the expectations of ERC20\\n * applications.\\n *\\n * Additionally, an {Approval} event is emitted on calls to {transferFrom}.\\n * This allows applications to reconstruct the allowance for all accounts just\\n * by listening to said events. Other implementations of the EIP may not emit\\n * these events, as it isn't required by the specification.\\n *\\n * Finally, the non-standard {decreaseAllowance} and {increaseAllowance}\\n * functions have been added to mitigate the well-known issues around setting\\n * allowances. See {IERC20-approve}.\\n */\\ncontract ERC20Upgradeable is Initializable, ContextUpgradeable, IERC20Upgradeable, IERC20MetadataUpgradeable {\\n mapping(address => uint256) private _balances;\\n\\n mapping(address => mapping(address => uint256)) private _allowances;\\n\\n uint256 private _totalSupply;\\n\\n string private _name;\\n string private _symbol;\\n\\n /**\\n * @dev Sets the values for {name} and {symbol}.\\n *\\n * The default value of {decimals} is 18. To select a different value for\\n * {decimals} you should overload it.\\n *\\n * All two of these values are immutable: they can only be set once during\\n * construction.\\n */\\n function __ERC20_init(string memory name_, string memory symbol_) internal onlyInitializing {\\n __ERC20_init_unchained(name_, symbol_);\\n }\\n\\n function __ERC20_init_unchained(string memory name_, string memory symbol_) internal onlyInitializing {\\n _name = name_;\\n _symbol = symbol_;\\n }\\n\\n /**\\n * @dev Returns the name of the token.\\n */\\n function name() public view virtual override returns (string memory) {\\n return _name;\\n }\\n\\n /**\\n * @dev Returns the symbol of the token, usually a shorter version of the\\n * name.\\n */\\n function symbol() public view virtual override returns (string memory) {\\n return _symbol;\\n }\\n\\n /**\\n * @dev Returns the number of decimals used to get its user representation.\\n * For example, if `decimals` equals `2`, a balance of `505` tokens should\\n * be displayed to a user as `5.05` (`505 / 10 ** 2`).\\n *\\n * Tokens usually opt for a value of 18, imitating the relationship between\\n * Ether and Wei. This is the value {ERC20} uses, unless this function is\\n * overridden;\\n *\\n * NOTE: This information is only used for _display_ purposes: it in\\n * no way affects any of the arithmetic of the contract, including\\n * {IERC20-balanceOf} and {IERC20-transfer}.\\n */\\n function decimals() public view virtual override returns (uint8) {\\n return 18;\\n }\\n\\n /**\\n * @dev See {IERC20-totalSupply}.\\n */\\n function totalSupply() public view virtual override returns (uint256) {\\n return _totalSupply;\\n }\\n\\n /**\\n * @dev See {IERC20-balanceOf}.\\n */\\n function balanceOf(address account) public view virtual override returns (uint256) {\\n return _balances[account];\\n }\\n\\n /**\\n * @dev See {IERC20-transfer}.\\n *\\n * Requirements:\\n *\\n * - `to` cannot be the zero address.\\n * - the caller must have a balance of at least `amount`.\\n */\\n function transfer(address to, uint256 amount) public virtual override returns (bool) {\\n address owner = _msgSender();\\n _transfer(owner, to, amount);\\n return true;\\n }\\n\\n /**\\n * @dev See {IERC20-allowance}.\\n */\\n function allowance(address owner, address spender) public view virtual override returns (uint256) {\\n return _allowances[owner][spender];\\n }\\n\\n /**\\n * @dev See {IERC20-approve}.\\n *\\n * NOTE: If `amount` is the maximum `uint256`, the allowance is not updated on\\n * `transferFrom`. This is semantically equivalent to an infinite approval.\\n *\\n * Requirements:\\n *\\n * - `spender` cannot be the zero address.\\n */\\n function approve(address spender, uint256 amount) public virtual override returns (bool) {\\n address owner = _msgSender();\\n _approve(owner, spender, amount);\\n return true;\\n }\\n\\n /**\\n * @dev See {IERC20-transferFrom}.\\n *\\n * Emits an {Approval} event indicating the updated allowance. This is not\\n * required by the EIP. See the note at the beginning of {ERC20}.\\n *\\n * NOTE: Does not update the allowance if the current allowance\\n * is the maximum `uint256`.\\n *\\n * Requirements:\\n *\\n * - `from` and `to` cannot be the zero address.\\n * - `from` must have a balance of at least `amount`.\\n * - the caller must have allowance for ``from``'s tokens of at least\\n * `amount`.\\n */\\n function transferFrom(\\n address from,\\n address to,\\n uint256 amount\\n ) public virtual override returns (bool) {\\n address spender = _msgSender();\\n _spendAllowance(from, spender, amount);\\n _transfer(from, to, amount);\\n return true;\\n }\\n\\n /**\\n * @dev Atomically increases the allowance granted to `spender` by the caller.\\n *\\n * This is an alternative to {approve} that can be used as a mitigation for\\n * problems described in {IERC20-approve}.\\n *\\n * Emits an {Approval} event indicating the updated allowance.\\n *\\n * Requirements:\\n *\\n * - `spender` cannot be the zero address.\\n */\\n function increaseAllowance(address spender, uint256 addedValue) public virtual returns (bool) {\\n address owner = _msgSender();\\n _approve(owner, spender, allowance(owner, spender) + addedValue);\\n return true;\\n }\\n\\n /**\\n * @dev Atomically decreases the allowance granted to `spender` by the caller.\\n *\\n * This is an alternative to {approve} that can be used as a mitigation for\\n * problems described in {IERC20-approve}.\\n *\\n * Emits an {Approval} event indicating the updated allowance.\\n *\\n * Requirements:\\n *\\n * - `spender` cannot be the zero address.\\n * - `spender` must have allowance for the caller of at least\\n * `subtractedValue`.\\n */\\n function decreaseAllowance(address spender, uint256 subtractedValue) public virtual returns (bool) {\\n address owner = _msgSender();\\n uint256 currentAllowance = allowance(owner, spender);\\n require(currentAllowance >= subtractedValue, \\\"ERC20: decreased allowance below zero\\\");\\n unchecked {\\n _approve(owner, spender, currentAllowance - subtractedValue);\\n }\\n\\n return true;\\n }\\n\\n /**\\n * @dev Moves `amount` of tokens from `from` to `to`.\\n *\\n * This internal function is equivalent to {transfer}, and can be used to\\n * e.g. implement automatic token fees, slashing mechanisms, etc.\\n *\\n * Emits a {Transfer} event.\\n *\\n * Requirements:\\n *\\n * - `from` cannot be the zero address.\\n * - `to` cannot be the zero address.\\n * - `from` must have a balance of at least `amount`.\\n */\\n function _transfer(\\n address from,\\n address to,\\n uint256 amount\\n ) internal virtual {\\n require(from != address(0), \\\"ERC20: transfer from the zero address\\\");\\n require(to != address(0), \\\"ERC20: transfer to the zero address\\\");\\n\\n _beforeTokenTransfer(from, to, amount);\\n\\n uint256 fromBalance = _balances[from];\\n require(fromBalance >= amount, \\\"ERC20: transfer amount exceeds balance\\\");\\n unchecked {\\n _balances[from] = fromBalance - amount;\\n }\\n _balances[to] += amount;\\n\\n emit Transfer(from, to, amount);\\n\\n _afterTokenTransfer(from, to, amount);\\n }\\n\\n /** @dev Creates `amount` tokens and assigns them to `account`, increasing\\n * the total supply.\\n *\\n * Emits a {Transfer} event with `from` set to the zero address.\\n *\\n * Requirements:\\n *\\n * - `account` cannot be the zero address.\\n */\\n function _mint(address account, uint256 amount) internal virtual {\\n require(account != address(0), \\\"ERC20: mint to the zero address\\\");\\n\\n _beforeTokenTransfer(address(0), account, amount);\\n\\n _totalSupply += amount;\\n _balances[account] += amount;\\n emit Transfer(address(0), account, amount);\\n\\n _afterTokenTransfer(address(0), account, amount);\\n }\\n\\n /**\\n * @dev Destroys `amount` tokens from `account`, reducing the\\n * total supply.\\n *\\n * Emits a {Transfer} event with `to` set to the zero address.\\n *\\n * Requirements:\\n *\\n * - `account` cannot be the zero address.\\n * - `account` must have at least `amount` tokens.\\n */\\n function _burn(address account, uint256 amount) internal virtual {\\n require(account != address(0), \\\"ERC20: burn from the zero address\\\");\\n\\n _beforeTokenTransfer(account, address(0), amount);\\n\\n uint256 accountBalance = _balances[account];\\n require(accountBalance >= amount, \\\"ERC20: burn amount exceeds balance\\\");\\n unchecked {\\n _balances[account] = accountBalance - amount;\\n }\\n _totalSupply -= amount;\\n\\n emit Transfer(account, address(0), amount);\\n\\n _afterTokenTransfer(account, address(0), amount);\\n }\\n\\n /**\\n * @dev Sets `amount` as the allowance of `spender` over the `owner` s tokens.\\n *\\n * This internal function is equivalent to `approve`, and can be used to\\n * e.g. set automatic allowances for certain subsystems, etc.\\n *\\n * Emits an {Approval} event.\\n *\\n * Requirements:\\n *\\n * - `owner` cannot be the zero address.\\n * - `spender` cannot be the zero address.\\n */\\n function _approve(\\n address owner,\\n address spender,\\n uint256 amount\\n ) internal virtual {\\n require(owner != address(0), \\\"ERC20: approve from the zero address\\\");\\n require(spender != address(0), \\\"ERC20: approve to the zero address\\\");\\n\\n _allowances[owner][spender] = amount;\\n emit Approval(owner, spender, amount);\\n }\\n\\n /**\\n * @dev Updates `owner` s allowance for `spender` based on spent `amount`.\\n *\\n * Does not update the allowance amount in case of infinite allowance.\\n * Revert if not enough allowance is available.\\n *\\n * Might emit an {Approval} event.\\n */\\n function _spendAllowance(\\n address owner,\\n address spender,\\n uint256 amount\\n ) internal virtual {\\n uint256 currentAllowance = allowance(owner, spender);\\n if (currentAllowance != type(uint256).max) {\\n require(currentAllowance >= amount, \\\"ERC20: insufficient allowance\\\");\\n unchecked {\\n _approve(owner, spender, currentAllowance - amount);\\n }\\n }\\n }\\n\\n /**\\n * @dev Hook that is called before any transfer of tokens. This includes\\n * minting and burning.\\n *\\n * Calling conditions:\\n *\\n * - when `from` and `to` are both non-zero, `amount` of ``from``'s tokens\\n * will be transferred to `to`.\\n * - when `from` is zero, `amount` tokens will be minted for `to`.\\n * - when `to` is zero, `amount` of ``from``'s tokens will be burned.\\n * - `from` and `to` are never both zero.\\n *\\n * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].\\n */\\n function _beforeTokenTransfer(\\n address from,\\n address to,\\n uint256 amount\\n ) internal virtual {}\\n\\n /**\\n * @dev Hook that is called after any transfer of tokens. This includes\\n * minting and burning.\\n *\\n * Calling conditions:\\n *\\n * - when `from` and `to` are both non-zero, `amount` of ``from``'s tokens\\n * has been transferred to `to`.\\n * - when `from` is zero, `amount` tokens have been minted for `to`.\\n * - when `to` is zero, `amount` of ``from``'s tokens have been burned.\\n * - `from` and `to` are never both zero.\\n *\\n * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].\\n */\\n function _afterTokenTransfer(\\n address from,\\n address to,\\n uint256 amount\\n ) internal virtual {}\\n\\n /**\\n * @dev This empty reserved space is put in place to allow future versions to add new\\n * variables without shifting down storage in the inheritance chain.\\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\\n */\\n uint256[45] private __gap;\\n}\\n\",\"keccak256\":\"0x7c7ac0bc6c340a7f320524b9a4b4b079ee9da3c51258080d4bab237f329a427c\",\"license\":\"MIT\"},\"@openzeppelin/contracts-upgradeable/token/ERC20/IERC20Upgradeable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.6.0) (token/ERC20/IERC20.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Interface of the ERC20 standard as defined in the EIP.\\n */\\ninterface IERC20Upgradeable {\\n /**\\n * @dev Emitted when `value` tokens are moved from one account (`from`) to\\n * another (`to`).\\n *\\n * Note that `value` may be zero.\\n */\\n event Transfer(address indexed from, address indexed to, uint256 value);\\n\\n /**\\n * @dev Emitted when the allowance of a `spender` for an `owner` is set by\\n * a call to {approve}. `value` is the new allowance.\\n */\\n event Approval(address indexed owner, address indexed spender, uint256 value);\\n\\n /**\\n * @dev Returns the amount of tokens in existence.\\n */\\n function totalSupply() external view returns (uint256);\\n\\n /**\\n * @dev Returns the amount of tokens owned by `account`.\\n */\\n function balanceOf(address account) external view returns (uint256);\\n\\n /**\\n * @dev Moves `amount` tokens from the caller's account to `to`.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * Emits a {Transfer} event.\\n */\\n function transfer(address to, uint256 amount) external returns (bool);\\n\\n /**\\n * @dev Returns the remaining number of tokens that `spender` will be\\n * allowed to spend on behalf of `owner` through {transferFrom}. This is\\n * zero by default.\\n *\\n * This value changes when {approve} or {transferFrom} are called.\\n */\\n function allowance(address owner, address spender) external view returns (uint256);\\n\\n /**\\n * @dev Sets `amount` as the allowance of `spender` over the caller's tokens.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * IMPORTANT: Beware that changing an allowance with this method brings the risk\\n * that someone may use both the old and the new allowance by unfortunate\\n * transaction ordering. One possible solution to mitigate this race\\n * condition is to first reduce the spender's allowance to 0 and set the\\n * desired value afterwards:\\n * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729\\n *\\n * Emits an {Approval} event.\\n */\\n function approve(address spender, uint256 amount) external returns (bool);\\n\\n /**\\n * @dev Moves `amount` tokens from `from` to `to` using the\\n * allowance mechanism. `amount` is then deducted from the caller's\\n * allowance.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * Emits a {Transfer} event.\\n */\\n function transferFrom(\\n address from,\\n address to,\\n uint256 amount\\n ) external returns (bool);\\n}\\n\",\"keccak256\":\"0x4e733d3164f73f461eaf9d8087a7ad1ea180bdc8ba0d3d61b0e1ae16d8e63dff\",\"license\":\"MIT\"},\"@openzeppelin/contracts-upgradeable/token/ERC20/extensions/IERC20MetadataUpgradeable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (token/ERC20/extensions/IERC20Metadata.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../IERC20Upgradeable.sol\\\";\\n\\n/**\\n * @dev Interface for the optional metadata functions from the ERC20 standard.\\n *\\n * _Available since v4.1._\\n */\\ninterface IERC20MetadataUpgradeable is IERC20Upgradeable {\\n /**\\n * @dev Returns the name of the token.\\n */\\n function name() external view returns (string memory);\\n\\n /**\\n * @dev Returns the symbol of the token.\\n */\\n function symbol() external view returns (string memory);\\n\\n /**\\n * @dev Returns the decimals places of the token.\\n */\\n function decimals() external view returns (uint8);\\n}\\n\",\"keccak256\":\"0x605434219ebbe4653f703640f06969faa5a1d78f0bfef878e5ddbb1ca369ceeb\",\"license\":\"MIT\"},\"@openzeppelin/contracts-upgradeable/token/ERC20/extensions/draft-ERC20PermitUpgradeable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.6.0) (token/ERC20/extensions/draft-ERC20Permit.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"./draft-IERC20PermitUpgradeable.sol\\\";\\nimport \\\"../ERC20Upgradeable.sol\\\";\\nimport \\\"../../../utils/cryptography/draft-EIP712Upgradeable.sol\\\";\\nimport \\\"../../../utils/cryptography/ECDSAUpgradeable.sol\\\";\\nimport \\\"../../../utils/CountersUpgradeable.sol\\\";\\nimport \\\"../../../proxy/utils/Initializable.sol\\\";\\n\\n/**\\n * @dev Implementation of the ERC20 Permit extension allowing approvals to be made via signatures, as defined in\\n * https://eips.ethereum.org/EIPS/eip-2612[EIP-2612].\\n *\\n * Adds the {permit} method, which can be used to change an account's ERC20 allowance (see {IERC20-allowance}) by\\n * presenting a message signed by the account. By not relying on `{IERC20-approve}`, the token holder account doesn't\\n * need to send a transaction, and thus is not required to hold Ether at all.\\n *\\n * _Available since v3.4._\\n *\\n * @custom:storage-size 51\\n */\\nabstract contract ERC20PermitUpgradeable is Initializable, ERC20Upgradeable, IERC20PermitUpgradeable, EIP712Upgradeable {\\n using CountersUpgradeable for CountersUpgradeable.Counter;\\n\\n mapping(address => CountersUpgradeable.Counter) private _nonces;\\n\\n // solhint-disable-next-line var-name-mixedcase\\n bytes32 private constant _PERMIT_TYPEHASH =\\n keccak256(\\\"Permit(address owner,address spender,uint256 value,uint256 nonce,uint256 deadline)\\\");\\n /**\\n * @dev In previous versions `_PERMIT_TYPEHASH` was declared as `immutable`.\\n * However, to ensure consistency with the upgradeable transpiler, we will continue\\n * to reserve a slot.\\n * @custom:oz-renamed-from _PERMIT_TYPEHASH\\n */\\n // solhint-disable-next-line var-name-mixedcase\\n bytes32 private _PERMIT_TYPEHASH_DEPRECATED_SLOT;\\n\\n /**\\n * @dev Initializes the {EIP712} domain separator using the `name` parameter, and setting `version` to `\\\"1\\\"`.\\n *\\n * It's a good idea to use the same `name` that is defined as the ERC20 token name.\\n */\\n function __ERC20Permit_init(string memory name) internal onlyInitializing {\\n __EIP712_init_unchained(name, \\\"1\\\");\\n }\\n\\n function __ERC20Permit_init_unchained(string memory) internal onlyInitializing {}\\n\\n /**\\n * @dev See {IERC20Permit-permit}.\\n */\\n function permit(\\n address owner,\\n address spender,\\n uint256 value,\\n uint256 deadline,\\n uint8 v,\\n bytes32 r,\\n bytes32 s\\n ) public virtual override {\\n require(block.timestamp <= deadline, \\\"ERC20Permit: expired deadline\\\");\\n\\n bytes32 structHash = keccak256(abi.encode(_PERMIT_TYPEHASH, owner, spender, value, _useNonce(owner), deadline));\\n\\n bytes32 hash = _hashTypedDataV4(structHash);\\n\\n address signer = ECDSAUpgradeable.recover(hash, v, r, s);\\n require(signer == owner, \\\"ERC20Permit: invalid signature\\\");\\n\\n _approve(owner, spender, value);\\n }\\n\\n /**\\n * @dev See {IERC20Permit-nonces}.\\n */\\n function nonces(address owner) public view virtual override returns (uint256) {\\n return _nonces[owner].current();\\n }\\n\\n /**\\n * @dev See {IERC20Permit-DOMAIN_SEPARATOR}.\\n */\\n // solhint-disable-next-line func-name-mixedcase\\n function DOMAIN_SEPARATOR() external view override returns (bytes32) {\\n return _domainSeparatorV4();\\n }\\n\\n /**\\n * @dev \\\"Consume a nonce\\\": return the current value and increment.\\n *\\n * _Available since v4.1._\\n */\\n function _useNonce(address owner) internal virtual returns (uint256 current) {\\n CountersUpgradeable.Counter storage nonce = _nonces[owner];\\n current = nonce.current();\\n nonce.increment();\\n }\\n\\n /**\\n * @dev This empty reserved space is put in place to allow future versions to add new\\n * variables without shifting down storage in the inheritance chain.\\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\\n */\\n uint256[49] private __gap;\\n}\\n\",\"keccak256\":\"0x564385ebed633694decce3e13d687f3ac7e8eaef64f7a504bfb3f03ad210601f\",\"license\":\"MIT\"},\"@openzeppelin/contracts-upgradeable/token/ERC20/extensions/draft-IERC20PermitUpgradeable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (token/ERC20/extensions/draft-IERC20Permit.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Interface of the ERC20 Permit extension allowing approvals to be made via signatures, as defined in\\n * https://eips.ethereum.org/EIPS/eip-2612[EIP-2612].\\n *\\n * Adds the {permit} method, which can be used to change an account's ERC20 allowance (see {IERC20-allowance}) by\\n * presenting a message signed by the account. By not relying on {IERC20-approve}, the token holder account doesn't\\n * need to send a transaction, and thus is not required to hold Ether at all.\\n */\\ninterface IERC20PermitUpgradeable {\\n /**\\n * @dev Sets `value` as the allowance of `spender` over ``owner``'s tokens,\\n * given ``owner``'s signed approval.\\n *\\n * IMPORTANT: The same issues {IERC20-approve} has related to transaction\\n * ordering also apply here.\\n *\\n * Emits an {Approval} event.\\n *\\n * Requirements:\\n *\\n * - `spender` cannot be the zero address.\\n * - `deadline` must be a timestamp in the future.\\n * - `v`, `r` and `s` must be a valid `secp256k1` signature from `owner`\\n * over the EIP712-formatted function arguments.\\n * - the signature must use ``owner``'s current nonce (see {nonces}).\\n *\\n * For more information on the signature format, see the\\n * https://eips.ethereum.org/EIPS/eip-2612#specification[relevant EIP\\n * section].\\n */\\n function permit(\\n address owner,\\n address spender,\\n uint256 value,\\n uint256 deadline,\\n uint8 v,\\n bytes32 r,\\n bytes32 s\\n ) external;\\n\\n /**\\n * @dev Returns the current nonce for `owner`. This value must be\\n * included whenever a signature is generated for {permit}.\\n *\\n * Every successful call to {permit} increases ``owner``'s nonce by one. This\\n * prevents a signature from being used multiple times.\\n */\\n function nonces(address owner) external view returns (uint256);\\n\\n /**\\n * @dev Returns the domain separator used in the encoding of the signature for {permit}, as defined by {EIP712}.\\n */\\n // solhint-disable-next-line func-name-mixedcase\\n function DOMAIN_SEPARATOR() external view returns (bytes32);\\n}\\n\",\"keccak256\":\"0xcc70d8e2281fb3ff69e8ab242500f10142cd0a7fa8dd9e45882be270d4d09024\",\"license\":\"MIT\"},\"@openzeppelin/contracts-upgradeable/utils/AddressUpgradeable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.7.0) (utils/Address.sol)\\n\\npragma solidity ^0.8.1;\\n\\n/**\\n * @dev Collection of functions related to the address type\\n */\\nlibrary AddressUpgradeable {\\n /**\\n * @dev Returns true if `account` is a contract.\\n *\\n * [IMPORTANT]\\n * ====\\n * It is unsafe to assume that an address for which this function returns\\n * false is an externally-owned account (EOA) and not a contract.\\n *\\n * Among others, `isContract` will return false for the following\\n * types of addresses:\\n *\\n * - an externally-owned account\\n * - a contract in construction\\n * - an address where a contract will be created\\n * - an address where a contract lived, but was destroyed\\n * ====\\n *\\n * [IMPORTANT]\\n * ====\\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\\n *\\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\\n * constructor.\\n * ====\\n */\\n function isContract(address account) internal view returns (bool) {\\n // This method relies on extcodesize/address.code.length, which returns 0\\n // for contracts in construction, since the code is only stored at the end\\n // of the constructor execution.\\n\\n return account.code.length > 0;\\n }\\n\\n /**\\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\\n * `recipient`, forwarding all available gas and reverting on errors.\\n *\\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\\n * imposed by `transfer`, making them unable to receive funds via\\n * `transfer`. {sendValue} removes this limitation.\\n *\\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\\n *\\n * IMPORTANT: because control is transferred to `recipient`, care must be\\n * taken to not create reentrancy vulnerabilities. Consider using\\n * {ReentrancyGuard} or the\\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\\n */\\n function sendValue(address payable recipient, uint256 amount) internal {\\n require(address(this).balance >= amount, \\\"Address: insufficient balance\\\");\\n\\n (bool success, ) = recipient.call{value: amount}(\\\"\\\");\\n require(success, \\\"Address: unable to send value, recipient may have reverted\\\");\\n }\\n\\n /**\\n * @dev Performs a Solidity function call using a low level `call`. A\\n * plain `call` is an unsafe replacement for a function call: use this\\n * function instead.\\n *\\n * If `target` reverts with a revert reason, it is bubbled up by this\\n * function (like regular Solidity function calls).\\n *\\n * Returns the raw returned data. To convert to the expected return value,\\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\\n *\\n * Requirements:\\n *\\n * - `target` must be a contract.\\n * - calling `target` with `data` must not revert.\\n *\\n * _Available since v3.1._\\n */\\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\\n return functionCall(target, data, \\\"Address: low-level call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\\n * `errorMessage` as a fallback revert reason when `target` reverts.\\n *\\n * _Available since v3.1._\\n */\\n function functionCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n return functionCallWithValue(target, data, 0, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but also transferring `value` wei to `target`.\\n *\\n * Requirements:\\n *\\n * - the calling contract must have an ETH balance of at least `value`.\\n * - the called Solidity function must be `payable`.\\n *\\n * _Available since v3.1._\\n */\\n function functionCallWithValue(\\n address target,\\n bytes memory data,\\n uint256 value\\n ) internal returns (bytes memory) {\\n return functionCallWithValue(target, data, value, \\\"Address: low-level call with value failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\\n * with `errorMessage` as a fallback revert reason when `target` reverts.\\n *\\n * _Available since v3.1._\\n */\\n function functionCallWithValue(\\n address target,\\n bytes memory data,\\n uint256 value,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n require(address(this).balance >= value, \\\"Address: insufficient balance for call\\\");\\n require(isContract(target), \\\"Address: call to non-contract\\\");\\n\\n (bool success, bytes memory returndata) = target.call{value: value}(data);\\n return verifyCallResult(success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but performing a static call.\\n *\\n * _Available since v3.3._\\n */\\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\\n return functionStaticCall(target, data, \\\"Address: low-level static call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\\n * but performing a static call.\\n *\\n * _Available since v3.3._\\n */\\n function functionStaticCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal view returns (bytes memory) {\\n require(isContract(target), \\\"Address: static call to non-contract\\\");\\n\\n (bool success, bytes memory returndata) = target.staticcall(data);\\n return verifyCallResult(success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the\\n * revert reason using the provided one.\\n *\\n * _Available since v4.3._\\n */\\n function verifyCallResult(\\n bool success,\\n bytes memory returndata,\\n string memory errorMessage\\n ) internal pure returns (bytes memory) {\\n if (success) {\\n return returndata;\\n } else {\\n // Look for revert reason and bubble it up if present\\n if (returndata.length > 0) {\\n // The easiest way to bubble the revert reason is using memory via assembly\\n /// @solidity memory-safe-assembly\\n assembly {\\n let returndata_size := mload(returndata)\\n revert(add(32, returndata), returndata_size)\\n }\\n } else {\\n revert(errorMessage);\\n }\\n }\\n }\\n}\\n\",\"keccak256\":\"0x611aa3f23e59cfdd1863c536776407b3e33d695152a266fa7cfb34440a29a8a3\",\"license\":\"MIT\"},\"@openzeppelin/contracts-upgradeable/utils/ContextUpgradeable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)\\n\\npragma solidity ^0.8.0;\\nimport \\\"../proxy/utils/Initializable.sol\\\";\\n\\n/**\\n * @dev Provides information about the current execution context, including the\\n * sender of the transaction and its data. While these are generally available\\n * via msg.sender and msg.data, they should not be accessed in such a direct\\n * manner, since when dealing with meta-transactions the account sending and\\n * paying for execution may not be the actual sender (as far as an application\\n * is concerned).\\n *\\n * This contract is only required for intermediate, library-like contracts.\\n */\\nabstract contract ContextUpgradeable is Initializable {\\n function __Context_init() internal onlyInitializing {\\n }\\n\\n function __Context_init_unchained() internal onlyInitializing {\\n }\\n function _msgSender() internal view virtual returns (address) {\\n return msg.sender;\\n }\\n\\n function _msgData() internal view virtual returns (bytes calldata) {\\n return msg.data;\\n }\\n\\n /**\\n * @dev This empty reserved space is put in place to allow future versions to add new\\n * variables without shifting down storage in the inheritance chain.\\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\\n */\\n uint256[50] private __gap;\\n}\\n\",\"keccak256\":\"0x963ea7f0b48b032eef72fe3a7582edf78408d6f834115b9feadd673a4d5bd149\",\"license\":\"MIT\"},\"@openzeppelin/contracts-upgradeable/utils/CountersUpgradeable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (utils/Counters.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @title Counters\\n * @author Matt Condon (@shrugs)\\n * @dev Provides counters that can only be incremented, decremented or reset. This can be used e.g. to track the number\\n * of elements in a mapping, issuing ERC721 ids, or counting request ids.\\n *\\n * Include with `using Counters for Counters.Counter;`\\n */\\nlibrary CountersUpgradeable {\\n struct Counter {\\n // This variable should never be directly accessed by users of the library: interactions must be restricted to\\n // the library's function. As of Solidity v0.5.2, this cannot be enforced, though there is a proposal to add\\n // this feature: see https://github.com/ethereum/solidity/issues/4637\\n uint256 _value; // default: 0\\n }\\n\\n function current(Counter storage counter) internal view returns (uint256) {\\n return counter._value;\\n }\\n\\n function increment(Counter storage counter) internal {\\n unchecked {\\n counter._value += 1;\\n }\\n }\\n\\n function decrement(Counter storage counter) internal {\\n uint256 value = counter._value;\\n require(value > 0, \\\"Counter: decrement overflow\\\");\\n unchecked {\\n counter._value = value - 1;\\n }\\n }\\n\\n function reset(Counter storage counter) internal {\\n counter._value = 0;\\n }\\n}\\n\",\"keccak256\":\"0x798741e231b22b81e2dd2eddaaf8832dee4baf5cd8e2dbaa5c1dd12a1c053c4d\",\"license\":\"MIT\"},\"@openzeppelin/contracts-upgradeable/utils/StringsUpgradeable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.7.0) (utils/Strings.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev String operations.\\n */\\nlibrary StringsUpgradeable {\\n bytes16 private constant _HEX_SYMBOLS = \\\"0123456789abcdef\\\";\\n uint8 private constant _ADDRESS_LENGTH = 20;\\n\\n /**\\n * @dev Converts a `uint256` to its ASCII `string` decimal representation.\\n */\\n function toString(uint256 value) internal pure returns (string memory) {\\n // Inspired by OraclizeAPI's implementation - MIT licence\\n // https://github.com/oraclize/ethereum-api/blob/b42146b063c7d6ee1358846c198246239e9360e8/oraclizeAPI_0.4.25.sol\\n\\n if (value == 0) {\\n return \\\"0\\\";\\n }\\n uint256 temp = value;\\n uint256 digits;\\n while (temp != 0) {\\n digits++;\\n temp /= 10;\\n }\\n bytes memory buffer = new bytes(digits);\\n while (value != 0) {\\n digits -= 1;\\n buffer[digits] = bytes1(uint8(48 + uint256(value % 10)));\\n value /= 10;\\n }\\n return string(buffer);\\n }\\n\\n /**\\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation.\\n */\\n function toHexString(uint256 value) internal pure returns (string memory) {\\n if (value == 0) {\\n return \\\"0x00\\\";\\n }\\n uint256 temp = value;\\n uint256 length = 0;\\n while (temp != 0) {\\n length++;\\n temp >>= 8;\\n }\\n return toHexString(value, length);\\n }\\n\\n /**\\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length.\\n */\\n function toHexString(uint256 value, uint256 length) internal pure returns (string memory) {\\n bytes memory buffer = new bytes(2 * length + 2);\\n buffer[0] = \\\"0\\\";\\n buffer[1] = \\\"x\\\";\\n for (uint256 i = 2 * length + 1; i > 1; --i) {\\n buffer[i] = _HEX_SYMBOLS[value & 0xf];\\n value >>= 4;\\n }\\n require(value == 0, \\\"Strings: hex length insufficient\\\");\\n return string(buffer);\\n }\\n\\n /**\\n * @dev Converts an `address` with fixed length of 20 bytes to its not checksummed ASCII `string` hexadecimal representation.\\n */\\n function toHexString(address addr) internal pure returns (string memory) {\\n return toHexString(uint256(uint160(addr)), _ADDRESS_LENGTH);\\n }\\n}\\n\",\"keccak256\":\"0xea5339a7fff0ed42b45be56a88efdd0b2ddde9fa480dc99fef9a6a4c5b776863\",\"license\":\"MIT\"},\"@openzeppelin/contracts-upgradeable/utils/cryptography/ECDSAUpgradeable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.7.0) (utils/cryptography/ECDSA.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../StringsUpgradeable.sol\\\";\\n\\n/**\\n * @dev Elliptic Curve Digital Signature Algorithm (ECDSA) operations.\\n *\\n * These functions can be used to verify that a message was signed by the holder\\n * of the private keys of a given address.\\n */\\nlibrary ECDSAUpgradeable {\\n enum RecoverError {\\n NoError,\\n InvalidSignature,\\n InvalidSignatureLength,\\n InvalidSignatureS,\\n InvalidSignatureV\\n }\\n\\n function _throwError(RecoverError error) private pure {\\n if (error == RecoverError.NoError) {\\n return; // no error: do nothing\\n } else if (error == RecoverError.InvalidSignature) {\\n revert(\\\"ECDSA: invalid signature\\\");\\n } else if (error == RecoverError.InvalidSignatureLength) {\\n revert(\\\"ECDSA: invalid signature length\\\");\\n } else if (error == RecoverError.InvalidSignatureS) {\\n revert(\\\"ECDSA: invalid signature 's' value\\\");\\n } else if (error == RecoverError.InvalidSignatureV) {\\n revert(\\\"ECDSA: invalid signature 'v' value\\\");\\n }\\n }\\n\\n /**\\n * @dev Returns the address that signed a hashed message (`hash`) with\\n * `signature` or error string. This address can then be used for verification purposes.\\n *\\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\\n * this function rejects them by requiring the `s` value to be in the lower\\n * half order, and the `v` value to be either 27 or 28.\\n *\\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\\n * verification to be secure: it is possible to craft signatures that\\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\\n * this is by receiving a hash of the original message (which may otherwise\\n * be too long), and then calling {toEthSignedMessageHash} on it.\\n *\\n * Documentation for signature generation:\\n * - with https://web3js.readthedocs.io/en/v1.3.4/web3-eth-accounts.html#sign[Web3.js]\\n * - with https://docs.ethers.io/v5/api/signer/#Signer-signMessage[ethers]\\n *\\n * _Available since v4.3._\\n */\\n function tryRecover(bytes32 hash, bytes memory signature) internal pure returns (address, RecoverError) {\\n // Check the signature length\\n // - case 65: r,s,v signature (standard)\\n // - case 64: r,vs signature (cf https://eips.ethereum.org/EIPS/eip-2098) _Available since v4.1._\\n if (signature.length == 65) {\\n bytes32 r;\\n bytes32 s;\\n uint8 v;\\n // ecrecover takes the signature parameters, and the only way to get them\\n // currently is to use assembly.\\n /// @solidity memory-safe-assembly\\n assembly {\\n r := mload(add(signature, 0x20))\\n s := mload(add(signature, 0x40))\\n v := byte(0, mload(add(signature, 0x60)))\\n }\\n return tryRecover(hash, v, r, s);\\n } else if (signature.length == 64) {\\n bytes32 r;\\n bytes32 vs;\\n // ecrecover takes the signature parameters, and the only way to get them\\n // currently is to use assembly.\\n /// @solidity memory-safe-assembly\\n assembly {\\n r := mload(add(signature, 0x20))\\n vs := mload(add(signature, 0x40))\\n }\\n return tryRecover(hash, r, vs);\\n } else {\\n return (address(0), RecoverError.InvalidSignatureLength);\\n }\\n }\\n\\n /**\\n * @dev Returns the address that signed a hashed message (`hash`) with\\n * `signature`. This address can then be used for verification purposes.\\n *\\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\\n * this function rejects them by requiring the `s` value to be in the lower\\n * half order, and the `v` value to be either 27 or 28.\\n *\\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\\n * verification to be secure: it is possible to craft signatures that\\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\\n * this is by receiving a hash of the original message (which may otherwise\\n * be too long), and then calling {toEthSignedMessageHash} on it.\\n */\\n function recover(bytes32 hash, bytes memory signature) internal pure returns (address) {\\n (address recovered, RecoverError error) = tryRecover(hash, signature);\\n _throwError(error);\\n return recovered;\\n }\\n\\n /**\\n * @dev Overload of {ECDSA-tryRecover} that receives the `r` and `vs` short-signature fields separately.\\n *\\n * See https://eips.ethereum.org/EIPS/eip-2098[EIP-2098 short signatures]\\n *\\n * _Available since v4.3._\\n */\\n function tryRecover(\\n bytes32 hash,\\n bytes32 r,\\n bytes32 vs\\n ) internal pure returns (address, RecoverError) {\\n bytes32 s = vs & bytes32(0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff);\\n uint8 v = uint8((uint256(vs) >> 255) + 27);\\n return tryRecover(hash, v, r, s);\\n }\\n\\n /**\\n * @dev Overload of {ECDSA-recover} that receives the `r and `vs` short-signature fields separately.\\n *\\n * _Available since v4.2._\\n */\\n function recover(\\n bytes32 hash,\\n bytes32 r,\\n bytes32 vs\\n ) internal pure returns (address) {\\n (address recovered, RecoverError error) = tryRecover(hash, r, vs);\\n _throwError(error);\\n return recovered;\\n }\\n\\n /**\\n * @dev Overload of {ECDSA-tryRecover} that receives the `v`,\\n * `r` and `s` signature fields separately.\\n *\\n * _Available since v4.3._\\n */\\n function tryRecover(\\n bytes32 hash,\\n uint8 v,\\n bytes32 r,\\n bytes32 s\\n ) internal pure returns (address, RecoverError) {\\n // EIP-2 still allows signature malleability for ecrecover(). Remove this possibility and make the signature\\n // unique. Appendix F in the Ethereum Yellow paper (https://ethereum.github.io/yellowpaper/paper.pdf), defines\\n // the valid range for s in (301): 0 < s < secp256k1n \\u00f7 2 + 1, and for v in (302): v \\u2208 {27, 28}. Most\\n // signatures from current libraries generate a unique signature with an s-value in the lower half order.\\n //\\n // If your library generates malleable signatures, such as s-values in the upper range, calculate a new s-value\\n // with 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141 - s1 and flip v from 27 to 28 or\\n // vice versa. If your library also generates signatures with 0/1 for v instead 27/28, add 27 to v to accept\\n // these malleable signatures as well.\\n if (uint256(s) > 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D576E7357A4501DDFE92F46681B20A0) {\\n return (address(0), RecoverError.InvalidSignatureS);\\n }\\n if (v != 27 && v != 28) {\\n return (address(0), RecoverError.InvalidSignatureV);\\n }\\n\\n // If the signature is valid (and not malleable), return the signer address\\n address signer = ecrecover(hash, v, r, s);\\n if (signer == address(0)) {\\n return (address(0), RecoverError.InvalidSignature);\\n }\\n\\n return (signer, RecoverError.NoError);\\n }\\n\\n /**\\n * @dev Overload of {ECDSA-recover} that receives the `v`,\\n * `r` and `s` signature fields separately.\\n */\\n function recover(\\n bytes32 hash,\\n uint8 v,\\n bytes32 r,\\n bytes32 s\\n ) internal pure returns (address) {\\n (address recovered, RecoverError error) = tryRecover(hash, v, r, s);\\n _throwError(error);\\n return recovered;\\n }\\n\\n /**\\n * @dev Returns an Ethereum Signed Message, created from a `hash`. This\\n * produces hash corresponding to the one signed with the\\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\\n * JSON-RPC method as part of EIP-191.\\n *\\n * See {recover}.\\n */\\n function toEthSignedMessageHash(bytes32 hash) internal pure returns (bytes32) {\\n // 32 is the length in bytes of hash,\\n // enforced by the type signature above\\n return keccak256(abi.encodePacked(\\\"\\\\x19Ethereum Signed Message:\\\\n32\\\", hash));\\n }\\n\\n /**\\n * @dev Returns an Ethereum Signed Message, created from `s`. This\\n * produces hash corresponding to the one signed with the\\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\\n * JSON-RPC method as part of EIP-191.\\n *\\n * See {recover}.\\n */\\n function toEthSignedMessageHash(bytes memory s) internal pure returns (bytes32) {\\n return keccak256(abi.encodePacked(\\\"\\\\x19Ethereum Signed Message:\\\\n\\\", StringsUpgradeable.toString(s.length), s));\\n }\\n\\n /**\\n * @dev Returns an Ethereum Signed Typed Data, created from a\\n * `domainSeparator` and a `structHash`. This produces hash corresponding\\n * to the one signed with the\\n * https://eips.ethereum.org/EIPS/eip-712[`eth_signTypedData`]\\n * JSON-RPC method as part of EIP-712.\\n *\\n * See {recover}.\\n */\\n function toTypedDataHash(bytes32 domainSeparator, bytes32 structHash) internal pure returns (bytes32) {\\n return keccak256(abi.encodePacked(\\\"\\\\x19\\\\x01\\\", domainSeparator, structHash));\\n }\\n}\\n\",\"keccak256\":\"0xe8c62ca00ed2d0a4d9b7e3c4bf7d62c821618b2cdb3c844da91a1193986851bf\",\"license\":\"MIT\"},\"@openzeppelin/contracts-upgradeable/utils/cryptography/draft-EIP712Upgradeable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (utils/cryptography/draft-EIP712.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"./ECDSAUpgradeable.sol\\\";\\nimport \\\"../../proxy/utils/Initializable.sol\\\";\\n\\n/**\\n * @dev https://eips.ethereum.org/EIPS/eip-712[EIP 712] is a standard for hashing and signing of typed structured data.\\n *\\n * The encoding specified in the EIP is very generic, and such a generic implementation in Solidity is not feasible,\\n * thus this contract does not implement the encoding itself. Protocols need to implement the type-specific encoding\\n * they need in their contracts using a combination of `abi.encode` and `keccak256`.\\n *\\n * This contract implements the EIP 712 domain separator ({_domainSeparatorV4}) that is used as part of the encoding\\n * scheme, and the final step of the encoding to obtain the message digest that is then signed via ECDSA\\n * ({_hashTypedDataV4}).\\n *\\n * The implementation of the domain separator was designed to be as efficient as possible while still properly updating\\n * the chain id to protect against replay attacks on an eventual fork of the chain.\\n *\\n * NOTE: This contract implements the version of the encoding known as \\\"v4\\\", as implemented by the JSON RPC method\\n * https://docs.metamask.io/guide/signing-data.html[`eth_signTypedDataV4` in MetaMask].\\n *\\n * _Available since v3.4._\\n *\\n * @custom:storage-size 52\\n */\\nabstract contract EIP712Upgradeable is Initializable {\\n /* solhint-disable var-name-mixedcase */\\n bytes32 private _HASHED_NAME;\\n bytes32 private _HASHED_VERSION;\\n bytes32 private constant _TYPE_HASH = keccak256(\\\"EIP712Domain(string name,string version,uint256 chainId,address verifyingContract)\\\");\\n\\n /* solhint-enable var-name-mixedcase */\\n\\n /**\\n * @dev Initializes the domain separator and parameter caches.\\n *\\n * The meaning of `name` and `version` is specified in\\n * https://eips.ethereum.org/EIPS/eip-712#definition-of-domainseparator[EIP 712]:\\n *\\n * - `name`: the user readable name of the signing domain, i.e. the name of the DApp or the protocol.\\n * - `version`: the current major version of the signing domain.\\n *\\n * NOTE: These parameters cannot be changed except through a xref:learn::upgrading-smart-contracts.adoc[smart\\n * contract upgrade].\\n */\\n function __EIP712_init(string memory name, string memory version) internal onlyInitializing {\\n __EIP712_init_unchained(name, version);\\n }\\n\\n function __EIP712_init_unchained(string memory name, string memory version) internal onlyInitializing {\\n bytes32 hashedName = keccak256(bytes(name));\\n bytes32 hashedVersion = keccak256(bytes(version));\\n _HASHED_NAME = hashedName;\\n _HASHED_VERSION = hashedVersion;\\n }\\n\\n /**\\n * @dev Returns the domain separator for the current chain.\\n */\\n function _domainSeparatorV4() internal view returns (bytes32) {\\n return _buildDomainSeparator(_TYPE_HASH, _EIP712NameHash(), _EIP712VersionHash());\\n }\\n\\n function _buildDomainSeparator(\\n bytes32 typeHash,\\n bytes32 nameHash,\\n bytes32 versionHash\\n ) private view returns (bytes32) {\\n return keccak256(abi.encode(typeHash, nameHash, versionHash, block.chainid, address(this)));\\n }\\n\\n /**\\n * @dev Given an already https://eips.ethereum.org/EIPS/eip-712#definition-of-hashstruct[hashed struct], this\\n * function returns the hash of the fully encoded EIP712 message for this domain.\\n *\\n * This hash can be used together with {ECDSA-recover} to obtain the signer of a message. For example:\\n *\\n * ```solidity\\n * bytes32 digest = _hashTypedDataV4(keccak256(abi.encode(\\n * keccak256(\\\"Mail(address to,string contents)\\\"),\\n * mailTo,\\n * keccak256(bytes(mailContents))\\n * )));\\n * address signer = ECDSA.recover(digest, signature);\\n * ```\\n */\\n function _hashTypedDataV4(bytes32 structHash) internal view virtual returns (bytes32) {\\n return ECDSAUpgradeable.toTypedDataHash(_domainSeparatorV4(), structHash);\\n }\\n\\n /**\\n * @dev The hash of the name parameter for the EIP712 domain.\\n *\\n * NOTE: This function reads from storage by default, but can be redefined to return a constant value if gas costs\\n * are a concern.\\n */\\n function _EIP712NameHash() internal virtual view returns (bytes32) {\\n return _HASHED_NAME;\\n }\\n\\n /**\\n * @dev The hash of the version parameter for the EIP712 domain.\\n *\\n * NOTE: This function reads from storage by default, but can be redefined to return a constant value if gas costs\\n * are a concern.\\n */\\n function _EIP712VersionHash() internal virtual view returns (bytes32) {\\n return _HASHED_VERSION;\\n }\\n\\n /**\\n * @dev This empty reserved space is put in place to allow future versions to add new\\n * variables without shifting down storage in the inheritance chain.\\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\\n */\\n uint256[50] private __gap;\\n}\\n\",\"keccak256\":\"0xaf5a96100f421d61693605349511e43221d3c2e47d4b3efa87af2b936e2567fc\",\"license\":\"MIT\"},\"@openzeppelin/contracts/token/ERC20/IERC20.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.6.0) (token/ERC20/IERC20.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Interface of the ERC20 standard as defined in the EIP.\\n */\\ninterface IERC20 {\\n /**\\n * @dev Emitted when `value` tokens are moved from one account (`from`) to\\n * another (`to`).\\n *\\n * Note that `value` may be zero.\\n */\\n event Transfer(address indexed from, address indexed to, uint256 value);\\n\\n /**\\n * @dev Emitted when the allowance of a `spender` for an `owner` is set by\\n * a call to {approve}. `value` is the new allowance.\\n */\\n event Approval(address indexed owner, address indexed spender, uint256 value);\\n\\n /**\\n * @dev Returns the amount of tokens in existence.\\n */\\n function totalSupply() external view returns (uint256);\\n\\n /**\\n * @dev Returns the amount of tokens owned by `account`.\\n */\\n function balanceOf(address account) external view returns (uint256);\\n\\n /**\\n * @dev Moves `amount` tokens from the caller's account to `to`.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * Emits a {Transfer} event.\\n */\\n function transfer(address to, uint256 amount) external returns (bool);\\n\\n /**\\n * @dev Returns the remaining number of tokens that `spender` will be\\n * allowed to spend on behalf of `owner` through {transferFrom}. This is\\n * zero by default.\\n *\\n * This value changes when {approve} or {transferFrom} are called.\\n */\\n function allowance(address owner, address spender) external view returns (uint256);\\n\\n /**\\n * @dev Sets `amount` as the allowance of `spender` over the caller's tokens.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * IMPORTANT: Beware that changing an allowance with this method brings the risk\\n * that someone may use both the old and the new allowance by unfortunate\\n * transaction ordering. One possible solution to mitigate this race\\n * condition is to first reduce the spender's allowance to 0 and set the\\n * desired value afterwards:\\n * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729\\n *\\n * Emits an {Approval} event.\\n */\\n function approve(address spender, uint256 amount) external returns (bool);\\n\\n /**\\n * @dev Moves `amount` tokens from `from` to `to` using the\\n * allowance mechanism. `amount` is then deducted from the caller's\\n * allowance.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * Emits a {Transfer} event.\\n */\\n function transferFrom(\\n address from,\\n address to,\\n uint256 amount\\n ) external returns (bool);\\n}\\n\",\"keccak256\":\"0x9750c6b834f7b43000631af5cc30001c5f547b3ceb3635488f140f60e897ea6b\",\"license\":\"MIT\"},\"@openzeppelin/contracts/token/ERC20/extensions/draft-IERC20Permit.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (token/ERC20/extensions/draft-IERC20Permit.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Interface of the ERC20 Permit extension allowing approvals to be made via signatures, as defined in\\n * https://eips.ethereum.org/EIPS/eip-2612[EIP-2612].\\n *\\n * Adds the {permit} method, which can be used to change an account's ERC20 allowance (see {IERC20-allowance}) by\\n * presenting a message signed by the account. By not relying on {IERC20-approve}, the token holder account doesn't\\n * need to send a transaction, and thus is not required to hold Ether at all.\\n */\\ninterface IERC20Permit {\\n /**\\n * @dev Sets `value` as the allowance of `spender` over ``owner``'s tokens,\\n * given ``owner``'s signed approval.\\n *\\n * IMPORTANT: The same issues {IERC20-approve} has related to transaction\\n * ordering also apply here.\\n *\\n * Emits an {Approval} event.\\n *\\n * Requirements:\\n *\\n * - `spender` cannot be the zero address.\\n * - `deadline` must be a timestamp in the future.\\n * - `v`, `r` and `s` must be a valid `secp256k1` signature from `owner`\\n * over the EIP712-formatted function arguments.\\n * - the signature must use ``owner``'s current nonce (see {nonces}).\\n *\\n * For more information on the signature format, see the\\n * https://eips.ethereum.org/EIPS/eip-2612#specification[relevant EIP\\n * section].\\n */\\n function permit(\\n address owner,\\n address spender,\\n uint256 value,\\n uint256 deadline,\\n uint8 v,\\n bytes32 r,\\n bytes32 s\\n ) external;\\n\\n /**\\n * @dev Returns the current nonce for `owner`. This value must be\\n * included whenever a signature is generated for {permit}.\\n *\\n * Every successful call to {permit} increases ``owner``'s nonce by one. This\\n * prevents a signature from being used multiple times.\\n */\\n function nonces(address owner) external view returns (uint256);\\n\\n /**\\n * @dev Returns the domain separator used in the encoding of the signature for {permit}, as defined by {EIP712}.\\n */\\n // solhint-disable-next-line func-name-mixedcase\\n function DOMAIN_SEPARATOR() external view returns (bytes32);\\n}\\n\",\"keccak256\":\"0xf41ca991f30855bf80ffd11e9347856a517b977f0a6c2d52e6421a99b7840329\",\"license\":\"MIT\"},\"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.7.0) (token/ERC20/utils/SafeERC20.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../IERC20.sol\\\";\\nimport \\\"../extensions/draft-IERC20Permit.sol\\\";\\nimport \\\"../../../utils/Address.sol\\\";\\n\\n/**\\n * @title SafeERC20\\n * @dev Wrappers around ERC20 operations that throw on failure (when the token\\n * contract returns false). Tokens that return no value (and instead revert or\\n * throw on failure) are also supported, non-reverting calls are assumed to be\\n * successful.\\n * To use this library you can add a `using SafeERC20 for IERC20;` statement to your contract,\\n * which allows you to call the safe operations as `token.safeTransfer(...)`, etc.\\n */\\nlibrary SafeERC20 {\\n using Address for address;\\n\\n function safeTransfer(\\n IERC20 token,\\n address to,\\n uint256 value\\n ) internal {\\n _callOptionalReturn(token, abi.encodeWithSelector(token.transfer.selector, to, value));\\n }\\n\\n function safeTransferFrom(\\n IERC20 token,\\n address from,\\n address to,\\n uint256 value\\n ) internal {\\n _callOptionalReturn(token, abi.encodeWithSelector(token.transferFrom.selector, from, to, value));\\n }\\n\\n /**\\n * @dev Deprecated. This function has issues similar to the ones found in\\n * {IERC20-approve}, and its usage is discouraged.\\n *\\n * Whenever possible, use {safeIncreaseAllowance} and\\n * {safeDecreaseAllowance} instead.\\n */\\n function safeApprove(\\n IERC20 token,\\n address spender,\\n uint256 value\\n ) internal {\\n // safeApprove should only be called when setting an initial allowance,\\n // or when resetting it to zero. To increase and decrease it, use\\n // 'safeIncreaseAllowance' and 'safeDecreaseAllowance'\\n require(\\n (value == 0) || (token.allowance(address(this), spender) == 0),\\n \\\"SafeERC20: approve from non-zero to non-zero allowance\\\"\\n );\\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, value));\\n }\\n\\n function safeIncreaseAllowance(\\n IERC20 token,\\n address spender,\\n uint256 value\\n ) internal {\\n uint256 newAllowance = token.allowance(address(this), spender) + value;\\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));\\n }\\n\\n function safeDecreaseAllowance(\\n IERC20 token,\\n address spender,\\n uint256 value\\n ) internal {\\n unchecked {\\n uint256 oldAllowance = token.allowance(address(this), spender);\\n require(oldAllowance >= value, \\\"SafeERC20: decreased allowance below zero\\\");\\n uint256 newAllowance = oldAllowance - value;\\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));\\n }\\n }\\n\\n function safePermit(\\n IERC20Permit token,\\n address owner,\\n address spender,\\n uint256 value,\\n uint256 deadline,\\n uint8 v,\\n bytes32 r,\\n bytes32 s\\n ) internal {\\n uint256 nonceBefore = token.nonces(owner);\\n token.permit(owner, spender, value, deadline, v, r, s);\\n uint256 nonceAfter = token.nonces(owner);\\n require(nonceAfter == nonceBefore + 1, \\\"SafeERC20: permit did not succeed\\\");\\n }\\n\\n /**\\n * @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement\\n * on the return value: the return value is optional (but if data is returned, it must not be false).\\n * @param token The token targeted by the call.\\n * @param data The call data (encoded using abi.encode or one of its variants).\\n */\\n function _callOptionalReturn(IERC20 token, bytes memory data) private {\\n // We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since\\n // we're implementing it ourselves. We use {Address.functionCall} to perform this call, which verifies that\\n // the target address contains contract code and also asserts for success in the low-level call.\\n\\n bytes memory returndata = address(token).functionCall(data, \\\"SafeERC20: low-level call failed\\\");\\n if (returndata.length > 0) {\\n // Return data is optional\\n require(abi.decode(returndata, (bool)), \\\"SafeERC20: ERC20 operation did not succeed\\\");\\n }\\n }\\n}\\n\",\"keccak256\":\"0x032807210d1d7d218963d7355d62e021a84bf1b3339f4f50be2f63b53cccaf29\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/Address.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.7.0) (utils/Address.sol)\\n\\npragma solidity ^0.8.1;\\n\\n/**\\n * @dev Collection of functions related to the address type\\n */\\nlibrary Address {\\n /**\\n * @dev Returns true if `account` is a contract.\\n *\\n * [IMPORTANT]\\n * ====\\n * It is unsafe to assume that an address for which this function returns\\n * false is an externally-owned account (EOA) and not a contract.\\n *\\n * Among others, `isContract` will return false for the following\\n * types of addresses:\\n *\\n * - an externally-owned account\\n * - a contract in construction\\n * - an address where a contract will be created\\n * - an address where a contract lived, but was destroyed\\n * ====\\n *\\n * [IMPORTANT]\\n * ====\\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\\n *\\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\\n * constructor.\\n * ====\\n */\\n function isContract(address account) internal view returns (bool) {\\n // This method relies on extcodesize/address.code.length, which returns 0\\n // for contracts in construction, since the code is only stored at the end\\n // of the constructor execution.\\n\\n return account.code.length > 0;\\n }\\n\\n /**\\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\\n * `recipient`, forwarding all available gas and reverting on errors.\\n *\\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\\n * imposed by `transfer`, making them unable to receive funds via\\n * `transfer`. {sendValue} removes this limitation.\\n *\\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\\n *\\n * IMPORTANT: because control is transferred to `recipient`, care must be\\n * taken to not create reentrancy vulnerabilities. Consider using\\n * {ReentrancyGuard} or the\\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\\n */\\n function sendValue(address payable recipient, uint256 amount) internal {\\n require(address(this).balance >= amount, \\\"Address: insufficient balance\\\");\\n\\n (bool success, ) = recipient.call{value: amount}(\\\"\\\");\\n require(success, \\\"Address: unable to send value, recipient may have reverted\\\");\\n }\\n\\n /**\\n * @dev Performs a Solidity function call using a low level `call`. A\\n * plain `call` is an unsafe replacement for a function call: use this\\n * function instead.\\n *\\n * If `target` reverts with a revert reason, it is bubbled up by this\\n * function (like regular Solidity function calls).\\n *\\n * Returns the raw returned data. To convert to the expected return value,\\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\\n *\\n * Requirements:\\n *\\n * - `target` must be a contract.\\n * - calling `target` with `data` must not revert.\\n *\\n * _Available since v3.1._\\n */\\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\\n return functionCall(target, data, \\\"Address: low-level call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\\n * `errorMessage` as a fallback revert reason when `target` reverts.\\n *\\n * _Available since v3.1._\\n */\\n function functionCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n return functionCallWithValue(target, data, 0, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but also transferring `value` wei to `target`.\\n *\\n * Requirements:\\n *\\n * - the calling contract must have an ETH balance of at least `value`.\\n * - the called Solidity function must be `payable`.\\n *\\n * _Available since v3.1._\\n */\\n function functionCallWithValue(\\n address target,\\n bytes memory data,\\n uint256 value\\n ) internal returns (bytes memory) {\\n return functionCallWithValue(target, data, value, \\\"Address: low-level call with value failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\\n * with `errorMessage` as a fallback revert reason when `target` reverts.\\n *\\n * _Available since v3.1._\\n */\\n function functionCallWithValue(\\n address target,\\n bytes memory data,\\n uint256 value,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n require(address(this).balance >= value, \\\"Address: insufficient balance for call\\\");\\n require(isContract(target), \\\"Address: call to non-contract\\\");\\n\\n (bool success, bytes memory returndata) = target.call{value: value}(data);\\n return verifyCallResult(success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but performing a static call.\\n *\\n * _Available since v3.3._\\n */\\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\\n return functionStaticCall(target, data, \\\"Address: low-level static call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\\n * but performing a static call.\\n *\\n * _Available since v3.3._\\n */\\n function functionStaticCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal view returns (bytes memory) {\\n require(isContract(target), \\\"Address: static call to non-contract\\\");\\n\\n (bool success, bytes memory returndata) = target.staticcall(data);\\n return verifyCallResult(success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but performing a delegate call.\\n *\\n * _Available since v3.4._\\n */\\n function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {\\n return functionDelegateCall(target, data, \\\"Address: low-level delegate call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\\n * but performing a delegate call.\\n *\\n * _Available since v3.4._\\n */\\n function functionDelegateCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n require(isContract(target), \\\"Address: delegate call to non-contract\\\");\\n\\n (bool success, bytes memory returndata) = target.delegatecall(data);\\n return verifyCallResult(success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the\\n * revert reason using the provided one.\\n *\\n * _Available since v4.3._\\n */\\n function verifyCallResult(\\n bool success,\\n bytes memory returndata,\\n string memory errorMessage\\n ) internal pure returns (bytes memory) {\\n if (success) {\\n return returndata;\\n } else {\\n // Look for revert reason and bubble it up if present\\n if (returndata.length > 0) {\\n // The easiest way to bubble the revert reason is using memory via assembly\\n /// @solidity memory-safe-assembly\\n assembly {\\n let returndata_size := mload(returndata)\\n revert(add(32, returndata), returndata_size)\\n }\\n } else {\\n revert(errorMessage);\\n }\\n }\\n }\\n}\\n\",\"keccak256\":\"0xd6153ce99bcdcce22b124f755e72553295be6abcd63804cfdffceb188b8bef10\",\"license\":\"MIT\"},\"contracts/agToken/AgToken.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-3.0\\n\\npragma solidity ^0.8.12;\\n\\n/*\\n * \\u2588 \\n ***** \\u2593\\u2593\\u2593 \\n * \\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593 \\n * ///. \\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593 \\n ***** //////// \\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593 \\n * ///////////// \\u2593\\u2593\\u2593 \\n \\u2593\\u2593 ////////////////// \\u2588 \\u2593\\u2593 \\n \\u2593\\u2593 \\u2593\\u2593 /////////////////////// \\u2593\\u2593 \\u2593\\u2593 \\n \\u2593\\u2593 \\u2593\\u2593 //////////////////////////// \\u2593\\u2593 \\u2593\\u2593 \\n \\u2593\\u2593 \\u2593\\u2593 /////////\\u2593\\u2593\\u2593///////\\u2593\\u2593\\u2593///////// \\u2593\\u2593 \\u2593\\u2593 \\n \\u2593\\u2593 ,////////////////////////////////////// \\u2593\\u2593 \\u2593\\u2593 \\n \\u2593\\u2593 ////////////////////////////////////////// \\u2593\\u2593 \\n \\u2593\\u2593 //////////////////////\\u2593\\u2593\\u2593\\u2593///////////////////// \\n ,//////////////////////////////////////////////////// \\n .////////////////////////////////////////////////////////// \\n .//////////////////////////\\u2588\\u2588.,//////////////////////////\\u2588 \\n .//////////////////////\\u2588\\u2588\\u2588\\u2588..,./////////////////////\\u2588\\u2588 \\n ...////////////////\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588.....,.////////////////\\u2588\\u2588\\u2588 \\n ,.,////////////\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588 ........,///////////\\u2588\\u2588\\u2588\\u2588 \\n .,.,//////\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588 ,.......///////\\u2588\\u2588\\u2588\\u2588 \\n ,..//\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588 ........./\\u2588\\u2588\\u2588\\u2588 \\n ..,\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588 .....,\\u2588\\u2588\\u2588 \\n .\\u2588\\u2588 ,.,\\u2588 \\n \\n \\n \\n \\u2593\\u2593 \\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593 \\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593 \\u2593\\u2593 \\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593 \\n \\u2593\\u2593\\u2593\\u2593\\u2593\\u2593 \\u2593\\u2593\\u2593 \\u2593\\u2593\\u2593 \\u2593\\u2593\\u2593 \\u2593\\u2593 \\u2593\\u2593 \\u2593\\u2593\\u2593\\u2593 \\n \\u2593\\u2593\\u2593 \\u2593\\u2593\\u2593 \\u2593\\u2593\\u2593 \\u2593\\u2593\\u2593 \\u2593\\u2593\\u2593 \\u2593\\u2593\\u2593 \\u2593\\u2593 \\u2593\\u2593\\u2593\\u2593\\u2593 \\n \\u2593\\u2593\\u2593 \\u2593\\u2593 \\u2593\\u2593\\u2593 \\u2593\\u2593\\u2593 \\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593 \\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593 \\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593 \\n*/\\n\\nimport \\\"../interfaces/IAgToken.sol\\\";\\nimport \\\"../interfaces/ITreasury.sol\\\";\\nimport \\\"@openzeppelin/contracts-upgradeable/token/ERC20/extensions/draft-ERC20PermitUpgradeable.sol\\\";\\n\\n/// @title AgToken\\n/// @author Angle Labs, Inc.\\n/// @notice Base contract for Angle agTokens on Ethereum and on other chains\\n/// @dev By default, agTokens are ERC-20 tokens with 18 decimals\\ncontract AgToken is IAgToken, ERC20PermitUpgradeable {\\n // =========================== PARAMETERS / VARIABLES ==========================\\n\\n /// @inheritdoc IAgToken\\n mapping(address => bool) public isMinter;\\n /// @notice Reference to the treasury contract which can grant minting rights\\n address public treasury;\\n\\n // =================================== EVENTS ==================================\\n\\n event TreasuryUpdated(address indexed _treasury);\\n event MinterToggled(address indexed minter);\\n\\n // =================================== ERRORS ==================================\\n\\n error BurnAmountExceedsAllowance();\\n error InvalidSender();\\n error InvalidTreasury();\\n error NotMinter();\\n error NotTreasury();\\n\\n // ================================ CONSTRUCTOR ================================\\n\\n /// @custom:oz-upgrades-unsafe-allow constructor\\n constructor() initializer {}\\n\\n /// @notice Initializes the `AgToken` contract\\n function initialize(string memory name_, string memory symbol_, address _treasury) external {\\n _initialize(name_, symbol_, _treasury);\\n }\\n\\n /// @notice Initializes the contract\\n function _initialize(string memory name_, string memory symbol_, address _treasury) internal virtual initializer {\\n if (address(ITreasury(_treasury).stablecoin()) != address(this)) revert InvalidTreasury();\\n __ERC20Permit_init(name_);\\n __ERC20_init(name_, symbol_);\\n treasury = _treasury;\\n emit TreasuryUpdated(_treasury);\\n }\\n\\n // ================================= MODIFIERS =================================\\n\\n /// @notice Checks to see if it is the `Treasury` calling this contract\\n modifier onlyTreasury() {\\n if (msg.sender != treasury) revert NotTreasury();\\n _;\\n }\\n\\n /// @notice Checks whether the sender has the minting right\\n modifier onlyMinter() {\\n if (!isMinter[msg.sender]) revert NotMinter();\\n _;\\n }\\n\\n // ============================= EXTERNAL FUNCTION =============================\\n\\n /// @notice Allows anyone to burn stablecoins\\n /// @param amount Amount of stablecoins to burn\\n /// @dev This function can typically be called if there is a settlement mechanism to burn stablecoins\\n function burnStablecoin(uint256 amount) external {\\n _burn(msg.sender, amount);\\n }\\n\\n // ========================= MINTER ROLE ONLY FUNCTIONS ========================\\n\\n /// @inheritdoc IAgToken\\n function burnSelf(uint256 amount, address burner) external onlyMinter {\\n _burn(burner, amount);\\n }\\n\\n /// @inheritdoc IAgToken\\n function burnFrom(uint256 amount, address burner, address sender) external onlyMinter {\\n if (burner != sender) {\\n uint256 currentAllowance = allowance(burner, sender);\\n if (currentAllowance < amount) revert BurnAmountExceedsAllowance();\\n _approve(burner, sender, currentAllowance - amount);\\n }\\n _burn(burner, amount);\\n }\\n\\n /// @inheritdoc IAgToken\\n function mint(address account, uint256 amount) external onlyMinter {\\n _mint(account, amount);\\n }\\n\\n // ========================== GOVERNANCE ONLY FUNCTIONS ==========================\\n\\n /// @inheritdoc IAgToken\\n function addMinter(address minter) external onlyTreasury {\\n isMinter[minter] = true;\\n emit MinterToggled(minter);\\n }\\n\\n /// @inheritdoc IAgToken\\n function removeMinter(address minter) external {\\n if (msg.sender != address(treasury) && msg.sender != minter) revert InvalidSender();\\n isMinter[minter] = false;\\n emit MinterToggled(minter);\\n }\\n\\n /// @inheritdoc IAgToken\\n function setTreasury(address _treasury) external virtual onlyTreasury {\\n treasury = _treasury;\\n emit TreasuryUpdated(_treasury);\\n }\\n}\\n\",\"keccak256\":\"0x671d54d7840179050e859cf09662fe0e2c34cfaf5ec3782148d6c29e77c54d17\",\"license\":\"GPL-3.0\"},\"contracts/agToken/AgTokenSideChainMultiBridge.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-3.0\\n\\npragma solidity ^0.8.12;\\n\\nimport \\\"./AgToken.sol\\\";\\nimport \\\"@openzeppelin/contracts/token/ERC20/IERC20.sol\\\";\\nimport \\\"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\\\";\\n\\n/// @title AgTokenSideChainMultiBridge\\n/// @author Angle Labs, Inc.\\n/// @notice Contract for Angle agTokens on other chains than Ethereum mainnet\\n/// @dev This contract supports bridge tokens having a minting right on the stablecoin (also referred to as the canonical\\n/// or the native token)\\ncontract AgTokenSideChainMultiBridge is AgToken {\\n using SafeERC20 for IERC20;\\n\\n /// @notice Base used for fee computation\\n uint256 public constant BASE_PARAMS = 1e9;\\n\\n // =============================== BRIDGING DATA ===============================\\n\\n /// @notice Struct with some data about a specific bridge token\\n struct BridgeDetails {\\n // Limit on the balance of bridge token held by the contract: it is designed\\n // to reduce the exposure of the system to hacks\\n uint256 limit;\\n // Limit on the hourly volume of token minted through this bridge\\n // Technically the limit over a rolling hour is hourlyLimit x2 as hourly limit\\n // is enforced only between x:00 and x+1:00\\n uint256 hourlyLimit;\\n // Fee taken for swapping in and out the token\\n uint64 fee;\\n // Whether the associated token is allowed or not\\n bool allowed;\\n // Whether swapping in and out from the associated token is paused or not\\n bool paused;\\n }\\n\\n /// @notice Maps a bridge token to data\\n mapping(address => BridgeDetails) public bridges;\\n /// @notice List of all bridge tokens\\n address[] public bridgeTokensList;\\n /// @notice Maps a bridge token to the associated hourly volume\\n mapping(address => mapping(uint256 => uint256)) public usage;\\n /// @notice Maps an address to whether it is exempt of fees for when it comes to swapping in and out\\n mapping(address => uint256) public isFeeExempt;\\n /// @notice Limit to the amount of tokens that can be sent from that chain to another chain\\n uint256 public chainTotalHourlyLimit;\\n /// @notice Usage per hour on that chain. Maps an hourly timestamp to the total volume swapped out on the chain\\n mapping(uint256 => uint256) public chainTotalUsage;\\n\\n // =================================== EVENTS ==================================\\n\\n event BridgeTokenAdded(address indexed bridgeToken, uint256 limit, uint256 hourlyLimit, uint64 fee, bool paused);\\n event BridgeTokenToggled(address indexed bridgeToken, bool toggleStatus);\\n event BridgeTokenRemoved(address indexed bridgeToken);\\n event BridgeTokenFeeUpdated(address indexed bridgeToken, uint64 fee);\\n event BridgeTokenLimitUpdated(address indexed bridgeToken, uint256 limit);\\n event BridgeTokenHourlyLimitUpdated(address indexed bridgeToken, uint256 hourlyLimit);\\n event HourlyLimitUpdated(uint256 hourlyLimit);\\n event Recovered(address indexed token, address indexed to, uint256 amount);\\n event FeeToggled(address indexed theAddress, uint256 toggleStatus);\\n\\n // =================================== ERRORS ==================================\\n\\n error AssetStillControlledInReserves();\\n error HourlyLimitExceeded();\\n error InvalidToken();\\n error NotGovernor();\\n error NotGovernorOrGuardian();\\n error TooBigAmount();\\n error TooHighParameterValue();\\n error ZeroAddress();\\n\\n // ================================= MODIFIERS =================================\\n\\n /// @notice Checks whether the `msg.sender` has the governor role or not\\n modifier onlyGovernor() {\\n if (!ITreasury(treasury).isGovernor(msg.sender)) revert NotGovernor();\\n _;\\n }\\n\\n /// @notice Checks whether the `msg.sender` has the governor role or the guardian role\\n modifier onlyGovernorOrGuardian() {\\n if (!ITreasury(treasury).isGovernorOrGuardian(msg.sender)) revert NotGovernorOrGuardian();\\n _;\\n }\\n\\n // ===================== EXTERNAL PERMISSIONLESS FUNCTIONS =====================\\n\\n /// @notice Returns the list of all supported bridge tokens\\n /// @dev Helpful for UIs\\n function allBridgeTokens() external view returns (address[] memory) {\\n return bridgeTokensList;\\n }\\n\\n /// @notice Returns the current volume for a bridge, for the current hour\\n /// @param bridgeToken Bridge used to mint\\n /// @dev Helpful for UIs\\n function currentUsage(address bridgeToken) external view returns (uint256) {\\n return usage[bridgeToken][block.timestamp / 3600];\\n }\\n\\n /// @notice Returns the current total volume on the chain for the current hour\\n /// @dev Helpful for UIs\\n function currentTotalUsage() external view returns (uint256) {\\n return chainTotalUsage[block.timestamp / 3600];\\n }\\n\\n /// @notice Mints the canonical token from a supported bridge token\\n /// @param bridgeToken Bridge token to use to mint\\n /// @param amount Amount of bridge tokens to send\\n /// @param to Address to which the stablecoin should be sent\\n /// @return Amount of the canonical stablecoin actually minted\\n /// @dev Some fees may be taken by the protocol depending on the token used and on the address calling\\n function swapIn(address bridgeToken, uint256 amount, address to) external returns (uint256) {\\n BridgeDetails memory bridgeDetails = bridges[bridgeToken];\\n if (!bridgeDetails.allowed || bridgeDetails.paused) revert InvalidToken();\\n uint256 balance = IERC20(bridgeToken).balanceOf(address(this));\\n if (balance + amount > bridgeDetails.limit) {\\n // In case someone maliciously sends tokens to this contract\\n // Or the limit changes\\n if (bridgeDetails.limit > balance) amount = bridgeDetails.limit - balance;\\n else {\\n amount = 0;\\n }\\n }\\n\\n // Checking requirement on the hourly volume\\n uint256 hour = block.timestamp / 3600;\\n uint256 hourlyUsage = usage[bridgeToken][hour];\\n if (hourlyUsage + amount > bridgeDetails.hourlyLimit) {\\n // Edge case when the hourly limit changes\\n amount = bridgeDetails.hourlyLimit > hourlyUsage ? bridgeDetails.hourlyLimit - hourlyUsage : 0;\\n }\\n usage[bridgeToken][hour] = hourlyUsage + amount;\\n\\n IERC20(bridgeToken).safeTransferFrom(msg.sender, address(this), amount);\\n uint256 canonicalOut = amount;\\n // Computing fees\\n if (isFeeExempt[msg.sender] == 0) {\\n canonicalOut -= (canonicalOut * bridgeDetails.fee) / BASE_PARAMS;\\n }\\n _mint(to, canonicalOut);\\n return canonicalOut;\\n }\\n\\n /// @notice Burns the canonical token in exchange for a bridge token\\n /// @param bridgeToken Bridge token required\\n /// @param amount Amount of canonical tokens to burn\\n /// @param to Address to which the bridge token should be sent\\n /// @return Amount of bridge tokens actually sent back\\n /// @dev Some fees may be taken by the protocol depending on the token used and on the address calling\\n function swapOut(address bridgeToken, uint256 amount, address to) external returns (uint256) {\\n BridgeDetails memory bridgeDetails = bridges[bridgeToken];\\n if (!bridgeDetails.allowed || bridgeDetails.paused) revert InvalidToken();\\n\\n uint256 hour = block.timestamp / 3600;\\n uint256 hourlyUsage = chainTotalUsage[hour] + amount;\\n // If the amount being swapped out exceeds the limit, we revert\\n // We don't want to change the amount being swapped out.\\n // The user can decide to send another tx with the correct amount to reach the limit\\n if (hourlyUsage > chainTotalHourlyLimit) revert HourlyLimitExceeded();\\n chainTotalUsage[hour] = hourlyUsage;\\n\\n _burn(msg.sender, amount);\\n uint256 bridgeOut = amount;\\n if (isFeeExempt[msg.sender] == 0) {\\n bridgeOut -= (bridgeOut * bridgeDetails.fee) / BASE_PARAMS;\\n }\\n IERC20(bridgeToken).safeTransfer(to, bridgeOut);\\n return bridgeOut;\\n }\\n\\n // ============================ GOVERNANCE FUNCTIONS ===========================\\n\\n /// @notice Adds support for a bridge token\\n /// @param bridgeToken Bridge token to add: it should be a version of the stablecoin from another bridge\\n /// @param limit Limit on the balance of bridge token this contract could hold\\n /// @param hourlyLimit Limit on the hourly volume for this bridge\\n /// @param paused Whether swapping for this token should be paused or not\\n /// @param fee Fee taken upon swapping for or against this token\\n function addBridgeToken(\\n address bridgeToken,\\n uint256 limit,\\n uint256 hourlyLimit,\\n uint64 fee,\\n bool paused\\n ) external onlyGovernor {\\n if (bridges[bridgeToken].allowed || bridgeToken == address(0)) revert InvalidToken();\\n if (fee > BASE_PARAMS) revert TooHighParameterValue();\\n BridgeDetails memory _bridge;\\n _bridge.limit = limit;\\n _bridge.hourlyLimit = hourlyLimit;\\n _bridge.paused = paused;\\n _bridge.fee = fee;\\n _bridge.allowed = true;\\n bridges[bridgeToken] = _bridge;\\n bridgeTokensList.push(bridgeToken);\\n emit BridgeTokenAdded(bridgeToken, limit, hourlyLimit, fee, paused);\\n }\\n\\n /// @notice Removes support for a token\\n /// @param bridgeToken Address of the bridge token to remove support for\\n function removeBridgeToken(address bridgeToken) external onlyGovernor {\\n if (IERC20(bridgeToken).balanceOf(address(this)) != 0) revert AssetStillControlledInReserves();\\n delete bridges[bridgeToken];\\n // Deletion from `bridgeTokensList` loop\\n uint256 bridgeTokensListLength = bridgeTokensList.length;\\n for (uint256 i; i < bridgeTokensListLength - 1; ++i) {\\n if (bridgeTokensList[i] == bridgeToken) {\\n // Replace the `bridgeToken` to remove with the last of the list\\n bridgeTokensList[i] = bridgeTokensList[bridgeTokensListLength - 1];\\n break;\\n }\\n }\\n // Remove last element in array\\n bridgeTokensList.pop();\\n emit BridgeTokenRemoved(bridgeToken);\\n }\\n\\n /// @notice Recovers any ERC20 token\\n /// @dev Can be used to withdraw bridge tokens for them to be de-bridged on mainnet\\n function recoverERC20(address tokenAddress, address to, uint256 amountToRecover) external onlyGovernor {\\n IERC20(tokenAddress).safeTransfer(to, amountToRecover);\\n emit Recovered(tokenAddress, to, amountToRecover);\\n }\\n\\n /// @notice Updates the `limit` amount for `bridgeToken`\\n function setLimit(address bridgeToken, uint256 limit) external onlyGovernorOrGuardian {\\n if (!bridges[bridgeToken].allowed) revert InvalidToken();\\n bridges[bridgeToken].limit = limit;\\n emit BridgeTokenLimitUpdated(bridgeToken, limit);\\n }\\n\\n /// @notice Updates the `hourlyLimit` amount for `bridgeToken`\\n function setHourlyLimit(address bridgeToken, uint256 hourlyLimit) external onlyGovernorOrGuardian {\\n if (!bridges[bridgeToken].allowed) revert InvalidToken();\\n bridges[bridgeToken].hourlyLimit = hourlyLimit;\\n emit BridgeTokenHourlyLimitUpdated(bridgeToken, hourlyLimit);\\n }\\n\\n /// @notice Updates the `chainTotalHourlyLimit` amount\\n function setChainTotalHourlyLimit(uint256 hourlyLimit) external onlyGovernorOrGuardian {\\n chainTotalHourlyLimit = hourlyLimit;\\n emit HourlyLimitUpdated(hourlyLimit);\\n }\\n\\n /// @notice Updates the `fee` value for `bridgeToken`\\n function setSwapFee(address bridgeToken, uint64 fee) external onlyGovernorOrGuardian {\\n if (!bridges[bridgeToken].allowed) revert InvalidToken();\\n if (fee > BASE_PARAMS) revert TooHighParameterValue();\\n bridges[bridgeToken].fee = fee;\\n emit BridgeTokenFeeUpdated(bridgeToken, fee);\\n }\\n\\n /// @notice Pauses or unpauses swapping in and out for a token\\n function toggleBridge(address bridgeToken) external onlyGovernorOrGuardian {\\n if (!bridges[bridgeToken].allowed) revert InvalidToken();\\n bool pausedStatus = bridges[bridgeToken].paused;\\n bridges[bridgeToken].paused = !pausedStatus;\\n emit BridgeTokenToggled(bridgeToken, !pausedStatus);\\n }\\n\\n /// @notice Toggles fees for the address `theAddress`\\n function toggleFeesForAddress(address theAddress) external onlyGovernorOrGuardian {\\n uint256 feeExemptStatus = 1 - isFeeExempt[theAddress];\\n isFeeExempt[theAddress] = feeExemptStatus;\\n emit FeeToggled(theAddress, feeExemptStatus);\\n }\\n}\\n\",\"keccak256\":\"0x9782497e84a1dc4bc468778ede4aceb35cebf74e4159e2af8f469f49312c3841\",\"license\":\"GPL-3.0\"},\"contracts/interfaces/IAgToken.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-3.0\\n\\npragma solidity ^0.8.12;\\n\\nimport \\\"@openzeppelin/contracts-upgradeable/token/ERC20/IERC20Upgradeable.sol\\\";\\n\\n/// @title IAgToken\\n/// @author Angle Labs, Inc.\\n/// @notice Interface for the stablecoins `AgToken` contracts\\n/// @dev This interface only contains functions of the `AgToken` contract which are called by other contracts\\n/// of this module or of the first module of the Angle Protocol\\ninterface IAgToken is IERC20Upgradeable {\\n // ======================= Minter Role Only Functions ===========================\\n\\n /// @notice Lets the `StableMaster` contract or another whitelisted contract mint agTokens\\n /// @param account Address to mint to\\n /// @param amount Amount to mint\\n /// @dev The contracts allowed to issue agTokens are the `StableMaster` contract, `VaultManager` contracts\\n /// associated to this stablecoin as well as the flash loan module (if activated) and potentially contracts\\n /// whitelisted by governance\\n function mint(address account, uint256 amount) external;\\n\\n /// @notice Burns `amount` tokens from a `burner` address after being asked to by `sender`\\n /// @param amount Amount of tokens to burn\\n /// @param burner Address to burn from\\n /// @param sender Address which requested the burn from `burner`\\n /// @dev This method is to be called by a contract with the minter right after being requested\\n /// to do so by a `sender` address willing to burn tokens from another `burner` address\\n /// @dev The method checks the allowance between the `sender` and the `burner`\\n function burnFrom(uint256 amount, address burner, address sender) external;\\n\\n /// @notice Burns `amount` tokens from a `burner` address\\n /// @param amount Amount of tokens to burn\\n /// @param burner Address to burn from\\n /// @dev This method is to be called by a contract with a minter right on the AgToken after being\\n /// requested to do so by an address willing to burn tokens from its address\\n function burnSelf(uint256 amount, address burner) external;\\n\\n // ========================= Treasury Only Functions ===========================\\n\\n /// @notice Adds a minter in the contract\\n /// @param minter Minter address to add\\n /// @dev Zero address checks are performed directly in the `Treasury` contract\\n function addMinter(address minter) external;\\n\\n /// @notice Removes a minter from the contract\\n /// @param minter Minter address to remove\\n /// @dev This function can also be called by a minter wishing to revoke itself\\n function removeMinter(address minter) external;\\n\\n /// @notice Sets a new treasury contract\\n /// @param _treasury New treasury address\\n function setTreasury(address _treasury) external;\\n\\n // ========================= External functions ================================\\n\\n /// @notice Checks whether an address has the right to mint agTokens\\n /// @param minter Address for which the minting right should be checked\\n /// @return Whether the address has the right to mint agTokens or not\\n function isMinter(address minter) external view returns (bool);\\n\\n /// @notice Get the associated treasury\\n function treasury() external view returns (address);\\n}\\n\",\"keccak256\":\"0x0c83efcfc1fb9ae9ba830f7b89e3dab9abf6ad7a6205a31aa35fbccaa837dcdc\",\"license\":\"GPL-3.0\"},\"contracts/interfaces/ICoreBorrow.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-3.0\\n\\npragma solidity ^0.8.12;\\n\\n/// @title ICoreBorrow\\n/// @author Angle Labs, Inc.\\n/// @notice Interface for the `CoreBorrow` contract\\n/// @dev This interface only contains functions of the `CoreBorrow` contract which are called by other contracts\\n/// of this module\\ninterface ICoreBorrow {\\n /// @notice Checks if an address corresponds to a treasury of a stablecoin with a flash loan\\n /// module initialized on it\\n /// @param treasury Address to check\\n /// @return Whether the address has the `FLASHLOANER_TREASURY_ROLE` or not\\n function isFlashLoanerTreasury(address treasury) external view returns (bool);\\n\\n /// @notice Checks whether an address is governor of the Angle Protocol or not\\n /// @param admin Address to check\\n /// @return Whether the address has the `GOVERNOR_ROLE` or not\\n function isGovernor(address admin) external view returns (bool);\\n\\n /// @notice Checks whether an address is governor or a guardian of the Angle Protocol or not\\n /// @param admin Address to check\\n /// @return Whether the address has the `GUARDIAN_ROLE` or not\\n /// @dev Governance should make sure when adding a governor to also give this governor the guardian\\n /// role by calling the `addGovernor` function\\n function isGovernorOrGuardian(address admin) external view returns (bool);\\n}\\n\",\"keccak256\":\"0x10249210cbf522775f040baf981d7d037472168ce2746d87473ac7c29a34e62e\",\"license\":\"GPL-3.0\"},\"contracts/interfaces/IFlashAngle.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-3.0\\n\\npragma solidity ^0.8.12;\\n\\nimport \\\"./IAgToken.sol\\\";\\nimport \\\"./ICoreBorrow.sol\\\";\\n\\n/// @title IFlashAngle\\n/// @author Angle Labs, Inc.\\n/// @notice Interface for the `FlashAngle` contract\\n/// @dev This interface only contains functions of the contract which are called by other contracts\\n/// of this module\\ninterface IFlashAngle {\\n /// @notice Reference to the `CoreBorrow` contract managing the FlashLoan module\\n function core() external view returns (ICoreBorrow);\\n\\n /// @notice Sends the fees taken from flash loans to the treasury contract associated to the stablecoin\\n /// @param stablecoin Stablecoin from which profits should be sent\\n /// @return balance Amount of profits sent\\n /// @dev This function can only be called by the treasury contract\\n function accrueInterestToTreasury(IAgToken stablecoin) external returns (uint256 balance);\\n\\n /// @notice Adds support for a stablecoin\\n /// @param _treasury Treasury associated to the stablecoin to add support for\\n /// @dev This function can only be called by the `CoreBorrow` contract\\n function addStablecoinSupport(address _treasury) external;\\n\\n /// @notice Removes support for a stablecoin\\n /// @param _treasury Treasury associated to the stablecoin to remove support for\\n /// @dev This function can only be called by the `CoreBorrow` contract\\n function removeStablecoinSupport(address _treasury) external;\\n\\n /// @notice Sets a new core contract\\n /// @param _core Core contract address to set\\n /// @dev This function can only be called by the `CoreBorrow` contract\\n function setCore(address _core) external;\\n}\\n\",\"keccak256\":\"0x39b0097f695b9e934bccdc72676c91513f1077cc5d0fd151908fd25a7c5cfbe4\",\"license\":\"GPL-3.0\"},\"contracts/interfaces/ITreasury.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-3.0\\n\\npragma solidity ^0.8.12;\\n\\nimport \\\"./IAgToken.sol\\\";\\nimport \\\"./ICoreBorrow.sol\\\";\\nimport \\\"./IFlashAngle.sol\\\";\\n\\n/// @title ITreasury\\n/// @author Angle Labs, Inc.\\n/// @notice Interface for the `Treasury` contract\\n/// @dev This interface only contains functions of the `Treasury` which are called by other contracts\\n/// of this module\\ninterface ITreasury {\\n /// @notice Stablecoin handled by this `treasury` contract\\n function stablecoin() external view returns (IAgToken);\\n\\n /// @notice Checks whether a given address has the governor role\\n /// @param admin Address to check\\n /// @return Whether the address has the governor role\\n /// @dev Access control is only kept in the `CoreBorrow` contract\\n function isGovernor(address admin) external view returns (bool);\\n\\n /// @notice Checks whether a given address has the guardian or the governor role\\n /// @param admin Address to check\\n /// @return Whether the address has the guardian or the governor role\\n /// @dev Access control is only kept in the `CoreBorrow` contract which means that this function\\n /// queries the `CoreBorrow` contract\\n function isGovernorOrGuardian(address admin) external view returns (bool);\\n\\n /// @notice Checks whether a given address has well been initialized in this contract\\n /// as a `VaultManager`\\n /// @param _vaultManager Address to check\\n /// @return Whether the address has been initialized or not\\n function isVaultManager(address _vaultManager) external view returns (bool);\\n\\n /// @notice Sets a new flash loan module for this stablecoin\\n /// @param _flashLoanModule Reference to the new flash loan module\\n /// @dev This function removes the minting right to the old flash loan module and grants\\n /// it to the new module\\n function setFlashLoanModule(address _flashLoanModule) external;\\n\\n /// @notice Gets the vault manager list\\n function vaultManagerList(uint256 i) external returns (address);\\n}\\n\",\"keccak256\":\"0x06c2f781c08732ce1b5845c083af5742716245baa6c519bd737f32b230a884c1\",\"license\":\"GPL-3.0\"}},\"version\":1}", + "bytecode": "0x60806040523480156200001157600080fd5b50600054610100900460ff1615808015620000335750600054600160ff909116105b8062000063575062000050306200013d60201b6200273a1760201c565b15801562000063575060005460ff166001145b620000cb5760405162461bcd60e51b815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201526d191e481a5b9a5d1a585b1a5e995960921b606482015260840160405180910390fd5b6000805460ff191660011790558015620000ef576000805461ff0019166101001790555b801562000136576000805461ff0019169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15b506200014c565b6001600160a01b03163b151590565b6146d0806200015c6000396000f3fe608060405234801561001057600080fd5b50600436106102ff5760003560e01c806361d027b31161019c5780639f48118f116100ee578063ced67f0c11610097578063dd62ed3e11610071578063dd62ed3e14610724578063e3e286551461076a578063f0f442601461077d57600080fd5b8063ced67f0c1461066b578063d44ad63f146106fe578063d505accf1461071157600080fd5b8063aa271e1a116100c8578063aa271e1a14610620578063ba330bd714610643578063cd4839ca1461065657600080fd5b80639f48118f146105ef578063a457c2d7146105fa578063a9059cbb1461060d57600080fd5b80637ecebe001161015057806395d89b411161012a57806395d89b41146105c1578063983b2d56146105c95780639e4e0dae146105dc57600080fd5b80637ecebe00146105705780638933fb791461058357806390218cff146105ae57600080fd5b80637334d020116101815780637334d020146105425780637d4c9c2d146105555780637d74e25f1461056857600080fd5b806361d027b3146104c757806370a082311461050c57600080fd5b80633092afd511610255578063395093511161020957806340c10f19116101e357806340c10f19146104815780634dc32fcc146104945780635bfbec96146104a757600080fd5b8063395093511461043b5780633a55f89d1461044e5780633f4218e01461046157600080fd5b8063350ebe041161023a578063350ebe041461040d5780633644e5151461042057806336db43b51461042857600080fd5b80633092afd5146103eb578063313ce567146103fe57600080fd5b8063151dd755116102b757806323b872dd1161029157806323b872dd146103b25780632b471d8e146103c55780632e403e14146103d857600080fd5b8063151dd7551461038057806318160ddd146103a15780632342fb0e146103a957600080fd5b80630919a951116102e85780630919a95114610337578063095ea7b31461034a5780631171bda91461036d57600080fd5b806306fdde0314610304578063077f224a14610322575b600080fd5b61030c610790565b6040516103199190613e48565b60405180910390f35b610335610330366004613f95565b610822565b005b61033561034536600461400d565b610832565b61035d61035836600461402a565b610995565b6040519015158152602001610319565b61033561037b366004614056565b6109af565b61039361038e366004614097565b610b04565b604051908152602001610319565b603554610393565b61039360d25481565b61035d6103c0366004614056565b610dbe565b6103356103d33660046140ce565b610de2565b6103356103e636600461400d565b610e39565b6103356103f936600461400d565b6111e8565b60405160128152602001610319565b61033561041b3660046140fe565b6112d1565b6103936113da565b61033561043636600461402a565b6113e9565b61035d61044936600461402a565b611579565b61033561045c366004614135565b6115c0565b61039361046f36600461400d565b60d16020526000908152604090205481565b61033561048f36600461402a565b6116c3565b6103936104a236600461400d565b611716565b6103936104b5366004614135565b60d36020526000908152604090205481565b60cd546104e79073ffffffffffffffffffffffffffffffffffffffff1681565b60405173ffffffffffffffffffffffffffffffffffffffff9091168152602001610319565b61039361051a36600461400d565b73ffffffffffffffffffffffffffffffffffffffff1660009081526033602052604090205490565b61033561055036600461402a565b61175e565b610335610563366004614179565b6118f1565b610393611c59565b61039361057e36600461400d565b611c7e565b61039361059136600461402a565b60d060209081526000928352604080842090915290825290205481565b6103356105bc366004614135565b611ca9565b61030c611cb6565b6103356105d736600461400d565b611cc5565b6103356105ea3660046141d6565b611d8d565b610393633b9aca0081565b61035d61060836600461402a565b611f99565b61035d61061b36600461402a565b61206f565b61035d61062e36600461400d565b60cc6020526000908152604090205460ff1681565b6104e7610651366004614135565b61207d565b61065e6120b4565b604051610319919061420b565b6106c561067936600461400d565b60ce6020526000908152604090208054600182015460029092015490919067ffffffffffffffff81169060ff680100000000000000008204811691690100000000000000000090041685565b60408051958652602086019490945267ffffffffffffffff9092169284019290925290151560608301521515608082015260a001610319565b61039361070c366004614097565b612122565b61033561071f366004614265565b6122e7565b6103936107323660046142dc565b73ffffffffffffffffffffffffffffffffffffffff918216600090815260346020908152604080832093909416825291909152205490565b61033561077836600461400d565b6124a6565b61033561078b36600461400d565b61267a565b60606036805461079f9061430a565b80601f01602080910402602001604051908101604052809291908181526020018280546107cb9061430a565b80156108185780601f106107ed57610100808354040283529160200191610818565b820191906000526020600020905b8154815290600101906020018083116107fb57829003601f168201915b5050505050905090565b61082d838383612756565b505050565b60cd546040517f521d4de900000000000000000000000000000000000000000000000000000000815233600482015273ffffffffffffffffffffffffffffffffffffffff9091169063521d4de990602401602060405180830381865afa1580156108a0573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906108c49190614357565b6108fa576040517f99e120bc00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff8116600090815260d1602052604081205461092b9060016143a3565b73ffffffffffffffffffffffffffffffffffffffff8316600081815260d160205260409081902083905551919250907f979ef83e7e7a87cb48064e296dd7e997870d50f43acf8d7ad221313526c8ca0f906109899084815260200190565b60405180910390a25050565b6000336109a3818585612a35565b60019150505b92915050565b60cd546040517fe43581b800000000000000000000000000000000000000000000000000000000815233600482015273ffffffffffffffffffffffffffffffffffffffff9091169063e43581b890602401602060405180830381865afa158015610a1d573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610a419190614357565b610a77576040517fee3675d400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b610a9873ffffffffffffffffffffffffffffffffffffffff84168383612be0565b8173ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff167ffff3b3844276f57024e0b42afec1a37f75db36511e43819a4f2a63ab7862b64883604051610af791815260200190565b60405180910390a3505050565b73ffffffffffffffffffffffffffffffffffffffff8316600090815260ce60209081526040808320815160a081018352815481526001820154938101939093526002015467ffffffffffffffff81169183019190915260ff680100000000000000008204811615801560608501526901000000000000000000909204161515608083015280610b94575080608001515b15610bcb576040517fc1ab6dc100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015260009073ffffffffffffffffffffffffffffffffffffffff8716906370a0823190602401602060405180830381865afa158015610c38573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610c5c91906143b6565b8251909150610c6b86836143cf565b1115610c93578151811015610c8e578151610c879082906143a3565b9450610c93565b600094505b6000610ca1610e10426143e2565b73ffffffffffffffffffffffffffffffffffffffff8816600090815260d0602090815260408083208484528252909120549085015191925090610ce488836143cf565b1115610d0f5780846020015111610cfc576000610d0c565b808460200151610d0c91906143a3565b96505b610d1987826143cf565b73ffffffffffffffffffffffffffffffffffffffff8916600081815260d060209081526040808320878452909152902091909155610d599033308a612cb4565b33600090815260d16020526040812054889103610da657633b9aca00856040015167ffffffffffffffff1682610d8f919061441d565b610d9991906143e2565b610da390826143a3565b90505b610db08782612d12565b9450505050505b9392505050565b600033610dcc858285612e32565b610dd7858585612f03565b506001949350505050565b33600090815260cc602052604090205460ff16610e2b576040517ff8d2906c00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b610e3581836131b6565b5050565b60cd546040517fe43581b800000000000000000000000000000000000000000000000000000000815233600482015273ffffffffffffffffffffffffffffffffffffffff9091169063e43581b890602401602060405180830381865afa158015610ea7573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610ecb9190614357565b610f01576040517fee3675d400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015273ffffffffffffffffffffffffffffffffffffffff8216906370a0823190602401602060405180830381865afa158015610f6b573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610f8f91906143b6565b15610fc6576040517f2ef630ec00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff8116600090815260ce602052604081208181556001810182905560020180547fffffffffffffffffffffffffffffffffffffffffffff0000000000000000000016905560cf54905b61102e6001836143a3565b811015611139578273ffffffffffffffffffffffffffffffffffffffff1660cf828154811061105f5761105f614434565b60009182526020909120015473ffffffffffffffffffffffffffffffffffffffff16036111295760cf6110936001846143a3565b815481106110a3576110a3614434565b60009182526020909120015460cf805473ffffffffffffffffffffffffffffffffffffffff90921691839081106110dc576110dc614434565b9060005260206000200160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550611139565b61113281614463565b9050611023565b5060cf80548061114b5761114b61449b565b60008281526020812082017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff90810180547fffffffffffffffffffffffff000000000000000000000000000000000000000016905590910190915560405173ffffffffffffffffffffffffffffffffffffffff8416917f5c95b49c4d59d97a2f044167723f29c74b30f99702e3fd406c3830160aa9ccb891a25050565b60cd5473ffffffffffffffffffffffffffffffffffffffff16331480159061122657503373ffffffffffffffffffffffffffffffffffffffff821614155b1561125d576040517fddb5de5e00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff8116600081815260cc602052604080822080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00169055517f98c15241d6c02bc5ee0b780e11b3ea737a2defd9d04877edbe9f9497065bd02f9190a250565b33600090815260cc602052604090205460ff1661131a576040517ff8d2906c00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff16146113d05773ffffffffffffffffffffffffffffffffffffffff828116600090815260346020908152604080832093851683529290522054838110156113ba576040517f715ec26c00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6113ce83836113c987856143a3565b612a35565b505b61082d82846131b6565b60006113e46133a3565b905090565b60cd546040517f521d4de900000000000000000000000000000000000000000000000000000000815233600482015273ffffffffffffffffffffffffffffffffffffffff9091169063521d4de990602401602060405180830381865afa158015611457573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061147b9190614357565b6114b1576040517f99e120bc00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff8216600090815260ce602052604090206002015468010000000000000000900460ff1661151f576040517fc1ab6dc100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff8216600081815260ce602052604090819020839055517fe7b113fba37131b6396680a0c55790a697ec975e198ff8cfd89dac90a6379e61906109899084815260200190565b33600081815260346020908152604080832073ffffffffffffffffffffffffffffffffffffffff871684529091528120549091906109a390829086906113c99087906143cf565b60cd546040517f521d4de900000000000000000000000000000000000000000000000000000000815233600482015273ffffffffffffffffffffffffffffffffffffffff9091169063521d4de990602401602060405180830381865afa15801561162e573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906116529190614357565b611688576040517f99e120bc00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60d28190556040518181527fc3b69829afe2345596a02c8b587d41f796ba0094481d899e1b2e07b7532a1e219060200160405180910390a150565b33600090815260cc602052604090205460ff1661170c576040517ff8d2906c00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b610e358282612d12565b73ffffffffffffffffffffffffffffffffffffffff8116600090815260d06020526040812081611748610e10426143e2565b8152602001908152602001600020549050919050565b60cd546040517f521d4de900000000000000000000000000000000000000000000000000000000815233600482015273ffffffffffffffffffffffffffffffffffffffff9091169063521d4de990602401602060405180830381865afa1580156117cc573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906117f09190614357565b611826576040517f99e120bc00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff8216600090815260ce602052604090206002015468010000000000000000900460ff16611894576040517fc1ab6dc100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff8216600081815260ce602052604090819020600101839055517fe13ac9338b2ee623233f83c1b3ceab16490fa3e3737fac7f0970d0830a9f4871906109899084815260200190565b60cd546040517fe43581b800000000000000000000000000000000000000000000000000000000815233600482015273ffffffffffffffffffffffffffffffffffffffff9091169063e43581b890602401602060405180830381865afa15801561195f573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906119839190614357565b6119b9576040517fee3675d400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff8516600090815260ce602052604090206002015468010000000000000000900460ff1680611a10575073ffffffffffffffffffffffffffffffffffffffff8516155b15611a47576040517fc1ab6dc100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b633b9aca008267ffffffffffffffff161115611a8f576040517feca1d2c600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040805160a08101825260008082526020820181905291810182905260608101829052608081019190915284815260208082018581528315156080840190815267ffffffffffffffff808716604080870191825260016060880181815273ffffffffffffffffffffffffffffffffffffffff8e16600081815260ce9099528389208a5181559751888401559351600290970180549151965115156901000000000000000000027fffffffffffffffffffffffffffffffffffffffffffff00ffffffffffffffffff97151568010000000000000000027fffffffffffffffffffffffffffffffffffffffffffffff000000000000000000909316989096169790971717949094169290921790935560cf805492830181559093527facb8d954e2cfef495862221e91bd7523613cf8808827cb33edfe4904cc51bf290180547fffffffffffffffffffffffff0000000000000000000000000000000000000000168217905590517f53087ff85d80a7671594bd2e86b92af22e0b3c2c441c8033bba7399b7b5cbe2390611c49908890889088908890938452602084019290925267ffffffffffffffff1660408301521515606082015260800190565b60405180910390a2505050505050565b600060d381611c6a610e10426143e2565b815260200190815260200160002054905090565b73ffffffffffffffffffffffffffffffffffffffff81166000908152609960205260408120546109a9565b611cb333826131b6565b50565b60606037805461079f9061430a565b60cd5473ffffffffffffffffffffffffffffffffffffffff163314611d16576040517fb90cdbb100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff8116600081815260cc602052604080822080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00166001179055517f98c15241d6c02bc5ee0b780e11b3ea737a2defd9d04877edbe9f9497065bd02f9190a250565b60cd546040517f521d4de900000000000000000000000000000000000000000000000000000000815233600482015273ffffffffffffffffffffffffffffffffffffffff9091169063521d4de990602401602060405180830381865afa158015611dfb573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611e1f9190614357565b611e55576040517f99e120bc00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff8216600090815260ce602052604090206002015468010000000000000000900460ff16611ec3576040517fc1ab6dc100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b633b9aca008167ffffffffffffffff161115611f0b576040517feca1d2c600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff8216600081815260ce602090815260409182902060020180547fffffffffffffffffffffffffffffffffffffffffffffffff00000000000000001667ffffffffffffffff861690811790915591519182527f901f9de19b475adc8da4110434b8df940dce085afd05e2281c86807f3a899d299101610989565b33600081815260346020908152604080832073ffffffffffffffffffffffffffffffffffffffff8716845290915281205490919083811015612062576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602560248201527f45524332303a2064656372656173656420616c6c6f77616e63652062656c6f7760448201527f207a65726f00000000000000000000000000000000000000000000000000000060648201526084015b60405180910390fd5b610dd78286868403612a35565b6000336109a3818585612f03565b60cf818154811061208d57600080fd5b60009182526020909120015473ffffffffffffffffffffffffffffffffffffffff16905081565b606060cf80548060200260200160405190810160405280929190818152602001828054801561081857602002820191906000526020600020905b815473ffffffffffffffffffffffffffffffffffffffff1681526001909101906020018083116120ee575050505050905090565b73ffffffffffffffffffffffffffffffffffffffff8316600090815260ce60209081526040808320815160a081018352815481526001820154938101939093526002015467ffffffffffffffff81169183019190915260ff6801000000000000000082048116158015606085015269010000000000000000009092041615156080830152806121b2575080608001515b156121e9576040517fc1ab6dc100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60006121f7610e10426143e2565b600081815260d36020526040812054919250906122159087906143cf565b905060d254811115612253576040517f6d43d1ac00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600082815260d36020526040902081905561226e33876131b6565b33600090815260d160205260408120548791036122bb57633b9aca00846040015167ffffffffffffffff16826122a4919061441d565b6122ae91906143e2565b6122b890826143a3565b90505b6122dc73ffffffffffffffffffffffffffffffffffffffff89168783612be0565b979650505050505050565b83421115612351576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f45524332305065726d69743a206578706972656420646561646c696e650000006044820152606401612059565b60007f6e71edae12b1b97f4d1f60370fef10105fa2faae0126114a169c64845d6126c98888886123808c61341e565b60408051602081019690965273ffffffffffffffffffffffffffffffffffffffff94851690860152929091166060840152608083015260a082015260c0810186905260e00160405160208183030381529060405280519060200120905060006123e882613453565b905060006123f8828787876134bc565b90508973ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff161461248f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601e60248201527f45524332305065726d69743a20696e76616c6964207369676e617475726500006044820152606401612059565b61249a8a8a8a612a35565b50505050505050505050565b60cd546040517f521d4de900000000000000000000000000000000000000000000000000000000815233600482015273ffffffffffffffffffffffffffffffffffffffff9091169063521d4de990602401602060405180830381865afa158015612514573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906125389190614357565b61256e576040517f99e120bc00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff8116600090815260ce602052604090206002015468010000000000000000900460ff166125dc576040517fc1ab6dc100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff8116600081815260ce602090815260409182902060020180547fffffffffffffffffffffffffffffffffffffffffffff00ffffffffffffffffff811669010000000000000000009182900460ff16801592830291909117909255925192835292917ff7c93079dcbf699749d66345a351afab7d24219bb1d915c9f4fc4cf03f00d3979101610989565b60cd5473ffffffffffffffffffffffffffffffffffffffff1633146126cb576040517fb90cdbb100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60cd80547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83169081179091556040517f7dae230f18360d76a040c81f050aa14eb9d6dc7901b20fc5d855e2a20fe814d190600090a250565b73ffffffffffffffffffffffffffffffffffffffff163b151590565b600054610100900460ff16158080156127765750600054600160ff909116105b806127905750303b158015612790575060005460ff166001145b61281c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201527f647920696e697469616c697a65640000000000000000000000000000000000006064820152608401612059565b600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00166001179055801561287a57600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff166101001790555b3073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1663e9cbd8226040518163ffffffff1660e01b8152600401602060405180830381865afa1580156128dc573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061290091906144ca565b73ffffffffffffffffffffffffffffffffffffffff161461294d576040517f14bcf5c800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b612956846134e4565b61296084846135ba565b60cd80547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff84169081179091556040517f7dae230f18360d76a040c81f050aa14eb9d6dc7901b20fc5d855e2a20fe814d190600090a28015612a2f57600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15b50505050565b73ffffffffffffffffffffffffffffffffffffffff8316612ad7576040517f08c379a0000000000000000000000000000000000000000000000000000000008152602060048201526024808201527f45524332303a20617070726f76652066726f6d20746865207a65726f2061646460448201527f72657373000000000000000000000000000000000000000000000000000000006064820152608401612059565b73ffffffffffffffffffffffffffffffffffffffff8216612b7a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602260248201527f45524332303a20617070726f766520746f20746865207a65726f20616464726560448201527f73730000000000000000000000000000000000000000000000000000000000006064820152608401612059565b73ffffffffffffffffffffffffffffffffffffffff83811660008181526034602090815260408083209487168084529482529182902085905590518481527f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b9259101610af7565b60405173ffffffffffffffffffffffffffffffffffffffff831660248201526044810182905261082d9084907fa9059cbb00000000000000000000000000000000000000000000000000000000906064015b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff000000000000000000000000000000000000000000000000000000009093169290921790915261365b565b60405173ffffffffffffffffffffffffffffffffffffffff80851660248301528316604482015260648101829052612a2f9085907f23b872dd0000000000000000000000000000000000000000000000000000000090608401612c32565b73ffffffffffffffffffffffffffffffffffffffff8216612d8f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601f60248201527f45524332303a206d696e7420746f20746865207a65726f2061646472657373006044820152606401612059565b8060356000828254612da191906143cf565b909155505073ffffffffffffffffffffffffffffffffffffffff821660009081526033602052604081208054839290612ddb9084906143cf565b909155505060405181815273ffffffffffffffffffffffffffffffffffffffff8316906000907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef9060200160405180910390a35050565b73ffffffffffffffffffffffffffffffffffffffff8381166000908152603460209081526040808320938616835292905220547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8114612a2f5781811015612ef6576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f45524332303a20696e73756666696369656e7420616c6c6f77616e63650000006044820152606401612059565b612a2f8484848403612a35565b73ffffffffffffffffffffffffffffffffffffffff8316612fa6576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602560248201527f45524332303a207472616e736665722066726f6d20746865207a65726f20616460448201527f64726573730000000000000000000000000000000000000000000000000000006064820152608401612059565b73ffffffffffffffffffffffffffffffffffffffff8216613049576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602360248201527f45524332303a207472616e7366657220746f20746865207a65726f206164647260448201527f65737300000000000000000000000000000000000000000000000000000000006064820152608401612059565b73ffffffffffffffffffffffffffffffffffffffff8316600090815260336020526040902054818110156130ff576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f45524332303a207472616e7366657220616d6f756e742065786365656473206260448201527f616c616e636500000000000000000000000000000000000000000000000000006064820152608401612059565b73ffffffffffffffffffffffffffffffffffffffff8085166000908152603360205260408082208585039055918516815290812080548492906131439084906143cf565b925050819055508273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef846040516131a991815260200190565b60405180910390a3612a2f565b73ffffffffffffffffffffffffffffffffffffffff8216613259576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602160248201527f45524332303a206275726e2066726f6d20746865207a65726f2061646472657360448201527f73000000000000000000000000000000000000000000000000000000000000006064820152608401612059565b73ffffffffffffffffffffffffffffffffffffffff82166000908152603360205260409020548181101561330f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602260248201527f45524332303a206275726e20616d6f756e7420657863656564732062616c616e60448201527f63650000000000000000000000000000000000000000000000000000000000006064820152608401612059565b73ffffffffffffffffffffffffffffffffffffffff8316600090815260336020526040812083830390556035805484929061334b9084906143a3565b909155505060405182815260009073ffffffffffffffffffffffffffffffffffffffff8516907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef9060200160405180910390a3505050565b60006113e47f8b73c3c69bb8fe3d512ecc4cf759cc79239f7b179b0ffacaa9a75d522b39400f6133d260655490565b6066546040805160208101859052908101839052606081018290524660808201523060a082015260009060c0016040516020818303038152906040528051906020012090509392505050565b73ffffffffffffffffffffffffffffffffffffffff811660009081526099602052604090208054600181018255905b50919050565b60006109a96134606133a3565b836040517f19010000000000000000000000000000000000000000000000000000000000006020820152602281018390526042810182905260009060620160405160208183030381529060405280519060200120905092915050565b60008060006134cd87878787613767565b915091506134da8161387f565b5095945050505050565b600054610100900460ff1661357b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201527f6e697469616c697a696e670000000000000000000000000000000000000000006064820152608401612059565b611cb3816040518060400160405280600181526020017f3100000000000000000000000000000000000000000000000000000000000000815250613ad3565b600054610100900460ff16613651576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201527f6e697469616c697a696e670000000000000000000000000000000000000000006064820152608401612059565b610e358282613b84565b60006136bd826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c65648152508573ffffffffffffffffffffffffffffffffffffffff16613c349092919063ffffffff16565b80519091501561082d57808060200190518101906136db9190614357565b61082d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e60448201527f6f742073756363656564000000000000000000000000000000000000000000006064820152608401612059565b6000807f7fffffffffffffffffffffffffffffff5d576e7357a4501ddfe92f46681b20a083111561379e5750600090506003613876565b8460ff16601b141580156137b657508460ff16601c14155b156137c75750600090506004613876565b6040805160008082526020820180845289905260ff881692820192909252606081018690526080810185905260019060a0016020604051602081039080840390855afa15801561381b573d6000803e3d6000fd5b50506040517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0015191505073ffffffffffffffffffffffffffffffffffffffff811661386f57600060019250925050613876565b9150600090505b94509492505050565b6000816004811115613893576138936144e7565b0361389b5750565b60018160048111156138af576138af6144e7565b03613916576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601860248201527f45434453413a20696e76616c6964207369676e617475726500000000000000006044820152606401612059565b600281600481111561392a5761392a6144e7565b03613991576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601f60248201527f45434453413a20696e76616c6964207369676e6174757265206c656e677468006044820152606401612059565b60038160048111156139a5576139a56144e7565b03613a32576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602260248201527f45434453413a20696e76616c6964207369676e6174757265202773272076616c60448201527f75650000000000000000000000000000000000000000000000000000000000006064820152608401612059565b6004816004811115613a4657613a466144e7565b03611cb3576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602260248201527f45434453413a20696e76616c6964207369676e6174757265202776272076616c60448201527f75650000000000000000000000000000000000000000000000000000000000006064820152608401612059565b600054610100900460ff16613b6a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201527f6e697469616c697a696e670000000000000000000000000000000000000000006064820152608401612059565b815160209283012081519190920120606591909155606655565b600054610100900460ff16613c1b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201527f6e697469616c697a696e670000000000000000000000000000000000000000006064820152608401612059565b6036613c278382614564565b50603761082d8282614564565b6060613c438484600085613c4b565b949350505050565b606082471015613cdd576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f60448201527f722063616c6c00000000000000000000000000000000000000000000000000006064820152608401612059565b73ffffffffffffffffffffffffffffffffffffffff85163b613d5b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006044820152606401612059565b6000808673ffffffffffffffffffffffffffffffffffffffff168587604051613d84919061467e565b60006040518083038185875af1925050503d8060008114613dc1576040519150601f19603f3d011682016040523d82523d6000602084013e613dc6565b606091505b50915091506122dc82828660608315613de0575081610db7565b825115613df05782518084602001fd5b816040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016120599190613e48565b60005b83811015613e3f578181015183820152602001613e27565b50506000910152565b6020815260008251806020840152613e67816040850160208701613e24565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169190910160400192915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b600082601f830112613ed957600080fd5b813567ffffffffffffffff80821115613ef457613ef4613e99565b604051601f83017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0908116603f01168101908282118183101715613f3a57613f3a613e99565b81604052838152866020858801011115613f5357600080fd5b836020870160208301376000602085830101528094505050505092915050565b73ffffffffffffffffffffffffffffffffffffffff81168114611cb357600080fd5b600080600060608486031215613faa57600080fd5b833567ffffffffffffffff80821115613fc257600080fd5b613fce87838801613ec8565b94506020860135915080821115613fe457600080fd5b50613ff186828701613ec8565b925050604084013561400281613f73565b809150509250925092565b60006020828403121561401f57600080fd5b8135610db781613f73565b6000806040838503121561403d57600080fd5b823561404881613f73565b946020939093013593505050565b60008060006060848603121561406b57600080fd5b833561407681613f73565b9250602084013561408681613f73565b929592945050506040919091013590565b6000806000606084860312156140ac57600080fd5b83356140b781613f73565b925060208401359150604084013561400281613f73565b600080604083850312156140e157600080fd5b8235915060208301356140f381613f73565b809150509250929050565b60008060006060848603121561411357600080fd5b83359250602084013561412581613f73565b9150604084013561400281613f73565b60006020828403121561414757600080fd5b5035919050565b803567ffffffffffffffff8116811461416657600080fd5b919050565b8015158114611cb357600080fd5b600080600080600060a0868803121561419157600080fd5b853561419c81613f73565b945060208601359350604086013592506141b86060870161414e565b915060808601356141c88161416b565b809150509295509295909350565b600080604083850312156141e957600080fd5b82356141f481613f73565b91506142026020840161414e565b90509250929050565b6020808252825182820181905260009190848201906040850190845b8181101561425957835173ffffffffffffffffffffffffffffffffffffffff1683529284019291840191600101614227565b50909695505050505050565b600080600080600080600060e0888a03121561428057600080fd5b873561428b81613f73565b9650602088013561429b81613f73565b95506040880135945060608801359350608088013560ff811681146142bf57600080fd5b9699959850939692959460a0840135945060c09093013592915050565b600080604083850312156142ef57600080fd5b82356142fa81613f73565b915060208301356140f381613f73565b600181811c9082168061431e57607f821691505b60208210810361344d577f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b60006020828403121561436957600080fd5b8151610db78161416b565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b818103818111156109a9576109a9614374565b6000602082840312156143c857600080fd5b5051919050565b808201808211156109a9576109a9614374565b600082614418577f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b500490565b80820281158282048414176109a9576109a9614374565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff820361449457614494614374565b5060010190565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603160045260246000fd5b6000602082840312156144dc57600080fd5b8151610db781613f73565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b601f82111561082d57600081815260208120601f850160051c8101602086101561453d5750805b601f850160051c820191505b8181101561455c57828155600101614549565b505050505050565b815167ffffffffffffffff81111561457e5761457e613e99565b6145928161458c845461430a565b84614516565b602080601f8311600181146145e557600084156145af5750858301515b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600386901b1c1916600185901b17855561455c565b6000858152602081207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08616915b8281101561463257888601518255948401946001909101908401614613565b508582101561466e57878501517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600388901b60f8161c191681555b5050505050600190811b01905550565b60008251614690818460208701613e24565b919091019291505056fea2646970667358221220f2eb02bac1667a72be85ab617a5b5aa3d8f7a9b09b4d1fde9756b7a5636daf2164736f6c63430008110033", + "deployedBytecode": "0x608060405234801561001057600080fd5b50600436106102ff5760003560e01c806361d027b31161019c5780639f48118f116100ee578063ced67f0c11610097578063dd62ed3e11610071578063dd62ed3e14610724578063e3e286551461076a578063f0f442601461077d57600080fd5b8063ced67f0c1461066b578063d44ad63f146106fe578063d505accf1461071157600080fd5b8063aa271e1a116100c8578063aa271e1a14610620578063ba330bd714610643578063cd4839ca1461065657600080fd5b80639f48118f146105ef578063a457c2d7146105fa578063a9059cbb1461060d57600080fd5b80637ecebe001161015057806395d89b411161012a57806395d89b41146105c1578063983b2d56146105c95780639e4e0dae146105dc57600080fd5b80637ecebe00146105705780638933fb791461058357806390218cff146105ae57600080fd5b80637334d020116101815780637334d020146105425780637d4c9c2d146105555780637d74e25f1461056857600080fd5b806361d027b3146104c757806370a082311461050c57600080fd5b80633092afd511610255578063395093511161020957806340c10f19116101e357806340c10f19146104815780634dc32fcc146104945780635bfbec96146104a757600080fd5b8063395093511461043b5780633a55f89d1461044e5780633f4218e01461046157600080fd5b8063350ebe041161023a578063350ebe041461040d5780633644e5151461042057806336db43b51461042857600080fd5b80633092afd5146103eb578063313ce567146103fe57600080fd5b8063151dd755116102b757806323b872dd1161029157806323b872dd146103b25780632b471d8e146103c55780632e403e14146103d857600080fd5b8063151dd7551461038057806318160ddd146103a15780632342fb0e146103a957600080fd5b80630919a951116102e85780630919a95114610337578063095ea7b31461034a5780631171bda91461036d57600080fd5b806306fdde0314610304578063077f224a14610322575b600080fd5b61030c610790565b6040516103199190613e48565b60405180910390f35b610335610330366004613f95565b610822565b005b61033561034536600461400d565b610832565b61035d61035836600461402a565b610995565b6040519015158152602001610319565b61033561037b366004614056565b6109af565b61039361038e366004614097565b610b04565b604051908152602001610319565b603554610393565b61039360d25481565b61035d6103c0366004614056565b610dbe565b6103356103d33660046140ce565b610de2565b6103356103e636600461400d565b610e39565b6103356103f936600461400d565b6111e8565b60405160128152602001610319565b61033561041b3660046140fe565b6112d1565b6103936113da565b61033561043636600461402a565b6113e9565b61035d61044936600461402a565b611579565b61033561045c366004614135565b6115c0565b61039361046f36600461400d565b60d16020526000908152604090205481565b61033561048f36600461402a565b6116c3565b6103936104a236600461400d565b611716565b6103936104b5366004614135565b60d36020526000908152604090205481565b60cd546104e79073ffffffffffffffffffffffffffffffffffffffff1681565b60405173ffffffffffffffffffffffffffffffffffffffff9091168152602001610319565b61039361051a36600461400d565b73ffffffffffffffffffffffffffffffffffffffff1660009081526033602052604090205490565b61033561055036600461402a565b61175e565b610335610563366004614179565b6118f1565b610393611c59565b61039361057e36600461400d565b611c7e565b61039361059136600461402a565b60d060209081526000928352604080842090915290825290205481565b6103356105bc366004614135565b611ca9565b61030c611cb6565b6103356105d736600461400d565b611cc5565b6103356105ea3660046141d6565b611d8d565b610393633b9aca0081565b61035d61060836600461402a565b611f99565b61035d61061b36600461402a565b61206f565b61035d61062e36600461400d565b60cc6020526000908152604090205460ff1681565b6104e7610651366004614135565b61207d565b61065e6120b4565b604051610319919061420b565b6106c561067936600461400d565b60ce6020526000908152604090208054600182015460029092015490919067ffffffffffffffff81169060ff680100000000000000008204811691690100000000000000000090041685565b60408051958652602086019490945267ffffffffffffffff9092169284019290925290151560608301521515608082015260a001610319565b61039361070c366004614097565b612122565b61033561071f366004614265565b6122e7565b6103936107323660046142dc565b73ffffffffffffffffffffffffffffffffffffffff918216600090815260346020908152604080832093909416825291909152205490565b61033561077836600461400d565b6124a6565b61033561078b36600461400d565b61267a565b60606036805461079f9061430a565b80601f01602080910402602001604051908101604052809291908181526020018280546107cb9061430a565b80156108185780601f106107ed57610100808354040283529160200191610818565b820191906000526020600020905b8154815290600101906020018083116107fb57829003601f168201915b5050505050905090565b61082d838383612756565b505050565b60cd546040517f521d4de900000000000000000000000000000000000000000000000000000000815233600482015273ffffffffffffffffffffffffffffffffffffffff9091169063521d4de990602401602060405180830381865afa1580156108a0573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906108c49190614357565b6108fa576040517f99e120bc00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff8116600090815260d1602052604081205461092b9060016143a3565b73ffffffffffffffffffffffffffffffffffffffff8316600081815260d160205260409081902083905551919250907f979ef83e7e7a87cb48064e296dd7e997870d50f43acf8d7ad221313526c8ca0f906109899084815260200190565b60405180910390a25050565b6000336109a3818585612a35565b60019150505b92915050565b60cd546040517fe43581b800000000000000000000000000000000000000000000000000000000815233600482015273ffffffffffffffffffffffffffffffffffffffff9091169063e43581b890602401602060405180830381865afa158015610a1d573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610a419190614357565b610a77576040517fee3675d400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b610a9873ffffffffffffffffffffffffffffffffffffffff84168383612be0565b8173ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff167ffff3b3844276f57024e0b42afec1a37f75db36511e43819a4f2a63ab7862b64883604051610af791815260200190565b60405180910390a3505050565b73ffffffffffffffffffffffffffffffffffffffff8316600090815260ce60209081526040808320815160a081018352815481526001820154938101939093526002015467ffffffffffffffff81169183019190915260ff680100000000000000008204811615801560608501526901000000000000000000909204161515608083015280610b94575080608001515b15610bcb576040517fc1ab6dc100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015260009073ffffffffffffffffffffffffffffffffffffffff8716906370a0823190602401602060405180830381865afa158015610c38573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610c5c91906143b6565b8251909150610c6b86836143cf565b1115610c93578151811015610c8e578151610c879082906143a3565b9450610c93565b600094505b6000610ca1610e10426143e2565b73ffffffffffffffffffffffffffffffffffffffff8816600090815260d0602090815260408083208484528252909120549085015191925090610ce488836143cf565b1115610d0f5780846020015111610cfc576000610d0c565b808460200151610d0c91906143a3565b96505b610d1987826143cf565b73ffffffffffffffffffffffffffffffffffffffff8916600081815260d060209081526040808320878452909152902091909155610d599033308a612cb4565b33600090815260d16020526040812054889103610da657633b9aca00856040015167ffffffffffffffff1682610d8f919061441d565b610d9991906143e2565b610da390826143a3565b90505b610db08782612d12565b9450505050505b9392505050565b600033610dcc858285612e32565b610dd7858585612f03565b506001949350505050565b33600090815260cc602052604090205460ff16610e2b576040517ff8d2906c00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b610e3581836131b6565b5050565b60cd546040517fe43581b800000000000000000000000000000000000000000000000000000000815233600482015273ffffffffffffffffffffffffffffffffffffffff9091169063e43581b890602401602060405180830381865afa158015610ea7573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610ecb9190614357565b610f01576040517fee3675d400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015273ffffffffffffffffffffffffffffffffffffffff8216906370a0823190602401602060405180830381865afa158015610f6b573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610f8f91906143b6565b15610fc6576040517f2ef630ec00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff8116600090815260ce602052604081208181556001810182905560020180547fffffffffffffffffffffffffffffffffffffffffffff0000000000000000000016905560cf54905b61102e6001836143a3565b811015611139578273ffffffffffffffffffffffffffffffffffffffff1660cf828154811061105f5761105f614434565b60009182526020909120015473ffffffffffffffffffffffffffffffffffffffff16036111295760cf6110936001846143a3565b815481106110a3576110a3614434565b60009182526020909120015460cf805473ffffffffffffffffffffffffffffffffffffffff90921691839081106110dc576110dc614434565b9060005260206000200160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550611139565b61113281614463565b9050611023565b5060cf80548061114b5761114b61449b565b60008281526020812082017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff90810180547fffffffffffffffffffffffff000000000000000000000000000000000000000016905590910190915560405173ffffffffffffffffffffffffffffffffffffffff8416917f5c95b49c4d59d97a2f044167723f29c74b30f99702e3fd406c3830160aa9ccb891a25050565b60cd5473ffffffffffffffffffffffffffffffffffffffff16331480159061122657503373ffffffffffffffffffffffffffffffffffffffff821614155b1561125d576040517fddb5de5e00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff8116600081815260cc602052604080822080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00169055517f98c15241d6c02bc5ee0b780e11b3ea737a2defd9d04877edbe9f9497065bd02f9190a250565b33600090815260cc602052604090205460ff1661131a576040517ff8d2906c00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff16146113d05773ffffffffffffffffffffffffffffffffffffffff828116600090815260346020908152604080832093851683529290522054838110156113ba576040517f715ec26c00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6113ce83836113c987856143a3565b612a35565b505b61082d82846131b6565b60006113e46133a3565b905090565b60cd546040517f521d4de900000000000000000000000000000000000000000000000000000000815233600482015273ffffffffffffffffffffffffffffffffffffffff9091169063521d4de990602401602060405180830381865afa158015611457573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061147b9190614357565b6114b1576040517f99e120bc00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff8216600090815260ce602052604090206002015468010000000000000000900460ff1661151f576040517fc1ab6dc100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff8216600081815260ce602052604090819020839055517fe7b113fba37131b6396680a0c55790a697ec975e198ff8cfd89dac90a6379e61906109899084815260200190565b33600081815260346020908152604080832073ffffffffffffffffffffffffffffffffffffffff871684529091528120549091906109a390829086906113c99087906143cf565b60cd546040517f521d4de900000000000000000000000000000000000000000000000000000000815233600482015273ffffffffffffffffffffffffffffffffffffffff9091169063521d4de990602401602060405180830381865afa15801561162e573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906116529190614357565b611688576040517f99e120bc00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60d28190556040518181527fc3b69829afe2345596a02c8b587d41f796ba0094481d899e1b2e07b7532a1e219060200160405180910390a150565b33600090815260cc602052604090205460ff1661170c576040517ff8d2906c00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b610e358282612d12565b73ffffffffffffffffffffffffffffffffffffffff8116600090815260d06020526040812081611748610e10426143e2565b8152602001908152602001600020549050919050565b60cd546040517f521d4de900000000000000000000000000000000000000000000000000000000815233600482015273ffffffffffffffffffffffffffffffffffffffff9091169063521d4de990602401602060405180830381865afa1580156117cc573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906117f09190614357565b611826576040517f99e120bc00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff8216600090815260ce602052604090206002015468010000000000000000900460ff16611894576040517fc1ab6dc100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff8216600081815260ce602052604090819020600101839055517fe13ac9338b2ee623233f83c1b3ceab16490fa3e3737fac7f0970d0830a9f4871906109899084815260200190565b60cd546040517fe43581b800000000000000000000000000000000000000000000000000000000815233600482015273ffffffffffffffffffffffffffffffffffffffff9091169063e43581b890602401602060405180830381865afa15801561195f573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906119839190614357565b6119b9576040517fee3675d400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff8516600090815260ce602052604090206002015468010000000000000000900460ff1680611a10575073ffffffffffffffffffffffffffffffffffffffff8516155b15611a47576040517fc1ab6dc100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b633b9aca008267ffffffffffffffff161115611a8f576040517feca1d2c600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040805160a08101825260008082526020820181905291810182905260608101829052608081019190915284815260208082018581528315156080840190815267ffffffffffffffff808716604080870191825260016060880181815273ffffffffffffffffffffffffffffffffffffffff8e16600081815260ce9099528389208a5181559751888401559351600290970180549151965115156901000000000000000000027fffffffffffffffffffffffffffffffffffffffffffff00ffffffffffffffffff97151568010000000000000000027fffffffffffffffffffffffffffffffffffffffffffffff000000000000000000909316989096169790971717949094169290921790935560cf805492830181559093527facb8d954e2cfef495862221e91bd7523613cf8808827cb33edfe4904cc51bf290180547fffffffffffffffffffffffff0000000000000000000000000000000000000000168217905590517f53087ff85d80a7671594bd2e86b92af22e0b3c2c441c8033bba7399b7b5cbe2390611c49908890889088908890938452602084019290925267ffffffffffffffff1660408301521515606082015260800190565b60405180910390a2505050505050565b600060d381611c6a610e10426143e2565b815260200190815260200160002054905090565b73ffffffffffffffffffffffffffffffffffffffff81166000908152609960205260408120546109a9565b611cb333826131b6565b50565b60606037805461079f9061430a565b60cd5473ffffffffffffffffffffffffffffffffffffffff163314611d16576040517fb90cdbb100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff8116600081815260cc602052604080822080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00166001179055517f98c15241d6c02bc5ee0b780e11b3ea737a2defd9d04877edbe9f9497065bd02f9190a250565b60cd546040517f521d4de900000000000000000000000000000000000000000000000000000000815233600482015273ffffffffffffffffffffffffffffffffffffffff9091169063521d4de990602401602060405180830381865afa158015611dfb573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611e1f9190614357565b611e55576040517f99e120bc00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff8216600090815260ce602052604090206002015468010000000000000000900460ff16611ec3576040517fc1ab6dc100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b633b9aca008167ffffffffffffffff161115611f0b576040517feca1d2c600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff8216600081815260ce602090815260409182902060020180547fffffffffffffffffffffffffffffffffffffffffffffffff00000000000000001667ffffffffffffffff861690811790915591519182527f901f9de19b475adc8da4110434b8df940dce085afd05e2281c86807f3a899d299101610989565b33600081815260346020908152604080832073ffffffffffffffffffffffffffffffffffffffff8716845290915281205490919083811015612062576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602560248201527f45524332303a2064656372656173656420616c6c6f77616e63652062656c6f7760448201527f207a65726f00000000000000000000000000000000000000000000000000000060648201526084015b60405180910390fd5b610dd78286868403612a35565b6000336109a3818585612f03565b60cf818154811061208d57600080fd5b60009182526020909120015473ffffffffffffffffffffffffffffffffffffffff16905081565b606060cf80548060200260200160405190810160405280929190818152602001828054801561081857602002820191906000526020600020905b815473ffffffffffffffffffffffffffffffffffffffff1681526001909101906020018083116120ee575050505050905090565b73ffffffffffffffffffffffffffffffffffffffff8316600090815260ce60209081526040808320815160a081018352815481526001820154938101939093526002015467ffffffffffffffff81169183019190915260ff6801000000000000000082048116158015606085015269010000000000000000009092041615156080830152806121b2575080608001515b156121e9576040517fc1ab6dc100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60006121f7610e10426143e2565b600081815260d36020526040812054919250906122159087906143cf565b905060d254811115612253576040517f6d43d1ac00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600082815260d36020526040902081905561226e33876131b6565b33600090815260d160205260408120548791036122bb57633b9aca00846040015167ffffffffffffffff16826122a4919061441d565b6122ae91906143e2565b6122b890826143a3565b90505b6122dc73ffffffffffffffffffffffffffffffffffffffff89168783612be0565b979650505050505050565b83421115612351576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f45524332305065726d69743a206578706972656420646561646c696e650000006044820152606401612059565b60007f6e71edae12b1b97f4d1f60370fef10105fa2faae0126114a169c64845d6126c98888886123808c61341e565b60408051602081019690965273ffffffffffffffffffffffffffffffffffffffff94851690860152929091166060840152608083015260a082015260c0810186905260e00160405160208183030381529060405280519060200120905060006123e882613453565b905060006123f8828787876134bc565b90508973ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff161461248f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601e60248201527f45524332305065726d69743a20696e76616c6964207369676e617475726500006044820152606401612059565b61249a8a8a8a612a35565b50505050505050505050565b60cd546040517f521d4de900000000000000000000000000000000000000000000000000000000815233600482015273ffffffffffffffffffffffffffffffffffffffff9091169063521d4de990602401602060405180830381865afa158015612514573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906125389190614357565b61256e576040517f99e120bc00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff8116600090815260ce602052604090206002015468010000000000000000900460ff166125dc576040517fc1ab6dc100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff8116600081815260ce602090815260409182902060020180547fffffffffffffffffffffffffffffffffffffffffffff00ffffffffffffffffff811669010000000000000000009182900460ff16801592830291909117909255925192835292917ff7c93079dcbf699749d66345a351afab7d24219bb1d915c9f4fc4cf03f00d3979101610989565b60cd5473ffffffffffffffffffffffffffffffffffffffff1633146126cb576040517fb90cdbb100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60cd80547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83169081179091556040517f7dae230f18360d76a040c81f050aa14eb9d6dc7901b20fc5d855e2a20fe814d190600090a250565b73ffffffffffffffffffffffffffffffffffffffff163b151590565b600054610100900460ff16158080156127765750600054600160ff909116105b806127905750303b158015612790575060005460ff166001145b61281c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201527f647920696e697469616c697a65640000000000000000000000000000000000006064820152608401612059565b600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00166001179055801561287a57600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff166101001790555b3073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1663e9cbd8226040518163ffffffff1660e01b8152600401602060405180830381865afa1580156128dc573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061290091906144ca565b73ffffffffffffffffffffffffffffffffffffffff161461294d576040517f14bcf5c800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b612956846134e4565b61296084846135ba565b60cd80547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff84169081179091556040517f7dae230f18360d76a040c81f050aa14eb9d6dc7901b20fc5d855e2a20fe814d190600090a28015612a2f57600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15b50505050565b73ffffffffffffffffffffffffffffffffffffffff8316612ad7576040517f08c379a0000000000000000000000000000000000000000000000000000000008152602060048201526024808201527f45524332303a20617070726f76652066726f6d20746865207a65726f2061646460448201527f72657373000000000000000000000000000000000000000000000000000000006064820152608401612059565b73ffffffffffffffffffffffffffffffffffffffff8216612b7a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602260248201527f45524332303a20617070726f766520746f20746865207a65726f20616464726560448201527f73730000000000000000000000000000000000000000000000000000000000006064820152608401612059565b73ffffffffffffffffffffffffffffffffffffffff83811660008181526034602090815260408083209487168084529482529182902085905590518481527f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b9259101610af7565b60405173ffffffffffffffffffffffffffffffffffffffff831660248201526044810182905261082d9084907fa9059cbb00000000000000000000000000000000000000000000000000000000906064015b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff000000000000000000000000000000000000000000000000000000009093169290921790915261365b565b60405173ffffffffffffffffffffffffffffffffffffffff80851660248301528316604482015260648101829052612a2f9085907f23b872dd0000000000000000000000000000000000000000000000000000000090608401612c32565b73ffffffffffffffffffffffffffffffffffffffff8216612d8f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601f60248201527f45524332303a206d696e7420746f20746865207a65726f2061646472657373006044820152606401612059565b8060356000828254612da191906143cf565b909155505073ffffffffffffffffffffffffffffffffffffffff821660009081526033602052604081208054839290612ddb9084906143cf565b909155505060405181815273ffffffffffffffffffffffffffffffffffffffff8316906000907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef9060200160405180910390a35050565b73ffffffffffffffffffffffffffffffffffffffff8381166000908152603460209081526040808320938616835292905220547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8114612a2f5781811015612ef6576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f45524332303a20696e73756666696369656e7420616c6c6f77616e63650000006044820152606401612059565b612a2f8484848403612a35565b73ffffffffffffffffffffffffffffffffffffffff8316612fa6576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602560248201527f45524332303a207472616e736665722066726f6d20746865207a65726f20616460448201527f64726573730000000000000000000000000000000000000000000000000000006064820152608401612059565b73ffffffffffffffffffffffffffffffffffffffff8216613049576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602360248201527f45524332303a207472616e7366657220746f20746865207a65726f206164647260448201527f65737300000000000000000000000000000000000000000000000000000000006064820152608401612059565b73ffffffffffffffffffffffffffffffffffffffff8316600090815260336020526040902054818110156130ff576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f45524332303a207472616e7366657220616d6f756e742065786365656473206260448201527f616c616e636500000000000000000000000000000000000000000000000000006064820152608401612059565b73ffffffffffffffffffffffffffffffffffffffff8085166000908152603360205260408082208585039055918516815290812080548492906131439084906143cf565b925050819055508273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef846040516131a991815260200190565b60405180910390a3612a2f565b73ffffffffffffffffffffffffffffffffffffffff8216613259576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602160248201527f45524332303a206275726e2066726f6d20746865207a65726f2061646472657360448201527f73000000000000000000000000000000000000000000000000000000000000006064820152608401612059565b73ffffffffffffffffffffffffffffffffffffffff82166000908152603360205260409020548181101561330f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602260248201527f45524332303a206275726e20616d6f756e7420657863656564732062616c616e60448201527f63650000000000000000000000000000000000000000000000000000000000006064820152608401612059565b73ffffffffffffffffffffffffffffffffffffffff8316600090815260336020526040812083830390556035805484929061334b9084906143a3565b909155505060405182815260009073ffffffffffffffffffffffffffffffffffffffff8516907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef9060200160405180910390a3505050565b60006113e47f8b73c3c69bb8fe3d512ecc4cf759cc79239f7b179b0ffacaa9a75d522b39400f6133d260655490565b6066546040805160208101859052908101839052606081018290524660808201523060a082015260009060c0016040516020818303038152906040528051906020012090509392505050565b73ffffffffffffffffffffffffffffffffffffffff811660009081526099602052604090208054600181018255905b50919050565b60006109a96134606133a3565b836040517f19010000000000000000000000000000000000000000000000000000000000006020820152602281018390526042810182905260009060620160405160208183030381529060405280519060200120905092915050565b60008060006134cd87878787613767565b915091506134da8161387f565b5095945050505050565b600054610100900460ff1661357b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201527f6e697469616c697a696e670000000000000000000000000000000000000000006064820152608401612059565b611cb3816040518060400160405280600181526020017f3100000000000000000000000000000000000000000000000000000000000000815250613ad3565b600054610100900460ff16613651576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201527f6e697469616c697a696e670000000000000000000000000000000000000000006064820152608401612059565b610e358282613b84565b60006136bd826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c65648152508573ffffffffffffffffffffffffffffffffffffffff16613c349092919063ffffffff16565b80519091501561082d57808060200190518101906136db9190614357565b61082d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e60448201527f6f742073756363656564000000000000000000000000000000000000000000006064820152608401612059565b6000807f7fffffffffffffffffffffffffffffff5d576e7357a4501ddfe92f46681b20a083111561379e5750600090506003613876565b8460ff16601b141580156137b657508460ff16601c14155b156137c75750600090506004613876565b6040805160008082526020820180845289905260ff881692820192909252606081018690526080810185905260019060a0016020604051602081039080840390855afa15801561381b573d6000803e3d6000fd5b50506040517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0015191505073ffffffffffffffffffffffffffffffffffffffff811661386f57600060019250925050613876565b9150600090505b94509492505050565b6000816004811115613893576138936144e7565b0361389b5750565b60018160048111156138af576138af6144e7565b03613916576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601860248201527f45434453413a20696e76616c6964207369676e617475726500000000000000006044820152606401612059565b600281600481111561392a5761392a6144e7565b03613991576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601f60248201527f45434453413a20696e76616c6964207369676e6174757265206c656e677468006044820152606401612059565b60038160048111156139a5576139a56144e7565b03613a32576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602260248201527f45434453413a20696e76616c6964207369676e6174757265202773272076616c60448201527f75650000000000000000000000000000000000000000000000000000000000006064820152608401612059565b6004816004811115613a4657613a466144e7565b03611cb3576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602260248201527f45434453413a20696e76616c6964207369676e6174757265202776272076616c60448201527f75650000000000000000000000000000000000000000000000000000000000006064820152608401612059565b600054610100900460ff16613b6a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201527f6e697469616c697a696e670000000000000000000000000000000000000000006064820152608401612059565b815160209283012081519190920120606591909155606655565b600054610100900460ff16613c1b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201527f6e697469616c697a696e670000000000000000000000000000000000000000006064820152608401612059565b6036613c278382614564565b50603761082d8282614564565b6060613c438484600085613c4b565b949350505050565b606082471015613cdd576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f60448201527f722063616c6c00000000000000000000000000000000000000000000000000006064820152608401612059565b73ffffffffffffffffffffffffffffffffffffffff85163b613d5b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006044820152606401612059565b6000808673ffffffffffffffffffffffffffffffffffffffff168587604051613d84919061467e565b60006040518083038185875af1925050503d8060008114613dc1576040519150601f19603f3d011682016040523d82523d6000602084013e613dc6565b606091505b50915091506122dc82828660608315613de0575081610db7565b825115613df05782518084602001fd5b816040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016120599190613e48565b60005b83811015613e3f578181015183820152602001613e27565b50506000910152565b6020815260008251806020840152613e67816040850160208701613e24565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169190910160400192915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b600082601f830112613ed957600080fd5b813567ffffffffffffffff80821115613ef457613ef4613e99565b604051601f83017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0908116603f01168101908282118183101715613f3a57613f3a613e99565b81604052838152866020858801011115613f5357600080fd5b836020870160208301376000602085830101528094505050505092915050565b73ffffffffffffffffffffffffffffffffffffffff81168114611cb357600080fd5b600080600060608486031215613faa57600080fd5b833567ffffffffffffffff80821115613fc257600080fd5b613fce87838801613ec8565b94506020860135915080821115613fe457600080fd5b50613ff186828701613ec8565b925050604084013561400281613f73565b809150509250925092565b60006020828403121561401f57600080fd5b8135610db781613f73565b6000806040838503121561403d57600080fd5b823561404881613f73565b946020939093013593505050565b60008060006060848603121561406b57600080fd5b833561407681613f73565b9250602084013561408681613f73565b929592945050506040919091013590565b6000806000606084860312156140ac57600080fd5b83356140b781613f73565b925060208401359150604084013561400281613f73565b600080604083850312156140e157600080fd5b8235915060208301356140f381613f73565b809150509250929050565b60008060006060848603121561411357600080fd5b83359250602084013561412581613f73565b9150604084013561400281613f73565b60006020828403121561414757600080fd5b5035919050565b803567ffffffffffffffff8116811461416657600080fd5b919050565b8015158114611cb357600080fd5b600080600080600060a0868803121561419157600080fd5b853561419c81613f73565b945060208601359350604086013592506141b86060870161414e565b915060808601356141c88161416b565b809150509295509295909350565b600080604083850312156141e957600080fd5b82356141f481613f73565b91506142026020840161414e565b90509250929050565b6020808252825182820181905260009190848201906040850190845b8181101561425957835173ffffffffffffffffffffffffffffffffffffffff1683529284019291840191600101614227565b50909695505050505050565b600080600080600080600060e0888a03121561428057600080fd5b873561428b81613f73565b9650602088013561429b81613f73565b95506040880135945060608801359350608088013560ff811681146142bf57600080fd5b9699959850939692959460a0840135945060c09093013592915050565b600080604083850312156142ef57600080fd5b82356142fa81613f73565b915060208301356140f381613f73565b600181811c9082168061431e57607f821691505b60208210810361344d577f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b60006020828403121561436957600080fd5b8151610db78161416b565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b818103818111156109a9576109a9614374565b6000602082840312156143c857600080fd5b5051919050565b808201808211156109a9576109a9614374565b600082614418577f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b500490565b80820281158282048414176109a9576109a9614374565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff820361449457614494614374565b5060010190565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603160045260246000fd5b6000602082840312156144dc57600080fd5b8151610db781613f73565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b601f82111561082d57600081815260208120601f850160051c8101602086101561453d5750805b601f850160051c820191505b8181101561455c57828155600101614549565b505050505050565b815167ffffffffffffffff81111561457e5761457e613e99565b6145928161458c845461430a565b84614516565b602080601f8311600181146145e557600084156145af5750858301515b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600386901b1c1916600185901b17855561455c565b6000858152602081207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08616915b8281101561463257888601518255948401946001909101908401614613565b508582101561466e57878501517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600388901b60f8161c191681555b5050505050600190811b01905550565b60008251614690818460208701613e24565b919091019291505056fea2646970667358221220f2eb02bac1667a72be85ab617a5b5aa3d8f7a9b09b4d1fde9756b7a5636daf2164736f6c63430008110033", "devdoc": { "author": "Angle Labs, Inc.", - "details": "This contract supports bridge tokens having a minting right on the stablecoin (also referred to as the canonical or the native token)References: - FRAX implementation: https://polygonscan.com/address/0x45c32fA6DF82ead1e2EF74d17b76547EDdFaFF89#code - QiDAO implementation: https://snowtrace.io/address/0x5c49b268c9841AFF1Cc3B0a418ff5c3442eE3F3b#code", + "details": "This contract supports bridge tokens having a minting right on the stablecoin (also referred to as the canonical or the native token)", "kind": "dev", "methods": { "DOMAIN_SEPARATOR()": { @@ -1320,14 +1320,6 @@ "increaseAllowance(address,uint256)": { "details": "Atomically increases the allowance granted to `spender` by the caller. This is an alternative to {approve} that can be used as a mitigation for problems described in {IERC20-approve}. Emits an {Approval} event indicating the updated allowance. Requirements: - `spender` cannot be the zero address." }, - "initialize(string,string,address)": { - "details": "By default, agTokens are ERC-20 tokens with 18 decimals", - "params": { - "_treasury": "Reference to the `Treasury` contract associated to this agToken", - "name_": "Name of the token", - "symbol_": "Symbol of the token" - } - }, "mint(address,uint256)": { "details": "The contracts allowed to issue agTokens are the `StableMaster` contract, `VaultManager` contracts associated to this stablecoin as well as the flash loan module (if activated) and potentially contracts whitelisted by governance", "params": { @@ -1429,7 +1421,7 @@ "notice": "Burns `amount` tokens from a `burner` address" }, "burnStablecoin(uint256)": { - "notice": "Allows anyone to burn agToken without redeeming collateral back" + "notice": "Allows anyone to burn stablecoins" }, "chainTotalHourlyLimit()": { "notice": "Limit to the amount of tokens that can be sent from that chain to another chain" @@ -1624,7 +1616,7 @@ "type": "t_array(t_uint256)49_storage" }, { - "astId": 8510, + "astId": 7427, "contract": "contracts/agToken/AgTokenSideChainMultiBridge.sol:AgTokenSideChainMultiBridge", "label": "isMinter", "offset": 0, @@ -1632,7 +1624,7 @@ "type": "t_mapping(t_address,t_bool)" }, { - "astId": 8513, + "astId": 7430, "contract": "contracts/agToken/AgTokenSideChainMultiBridge.sol:AgTokenSideChainMultiBridge", "label": "treasury", "offset": 0, @@ -1640,15 +1632,15 @@ "type": "t_address" }, { - "astId": 7671, + "astId": 7739, "contract": "contracts/agToken/AgTokenSideChainMultiBridge.sol:AgTokenSideChainMultiBridge", "label": "bridges", "offset": 0, "slot": "206", - "type": "t_mapping(t_address,t_struct(BridgeDetails)7665_storage)" + "type": "t_mapping(t_address,t_struct(BridgeDetails)7733_storage)" }, { - "astId": 7675, + "astId": 7743, "contract": "contracts/agToken/AgTokenSideChainMultiBridge.sol:AgTokenSideChainMultiBridge", "label": "bridgeTokensList", "offset": 0, @@ -1656,7 +1648,7 @@ "type": "t_array(t_address)dyn_storage" }, { - "astId": 7682, + "astId": 7750, "contract": "contracts/agToken/AgTokenSideChainMultiBridge.sol:AgTokenSideChainMultiBridge", "label": "usage", "offset": 0, @@ -1664,7 +1656,7 @@ "type": "t_mapping(t_address,t_mapping(t_uint256,t_uint256))" }, { - "astId": 7687, + "astId": 7755, "contract": "contracts/agToken/AgTokenSideChainMultiBridge.sol:AgTokenSideChainMultiBridge", "label": "isFeeExempt", "offset": 0, @@ -1672,7 +1664,7 @@ "type": "t_mapping(t_address,t_uint256)" }, { - "astId": 7690, + "astId": 7758, "contract": "contracts/agToken/AgTokenSideChainMultiBridge.sol:AgTokenSideChainMultiBridge", "label": "chainTotalHourlyLimit", "offset": 0, @@ -1680,7 +1672,7 @@ "type": "t_uint256" }, { - "astId": 7695, + "astId": 7763, "contract": "contracts/agToken/AgTokenSideChainMultiBridge.sol:AgTokenSideChainMultiBridge", "label": "chainTotalUsage", "offset": 0, @@ -1749,12 +1741,12 @@ "numberOfBytes": "32", "value": "t_mapping(t_uint256,t_uint256)" }, - "t_mapping(t_address,t_struct(BridgeDetails)7665_storage)": { + "t_mapping(t_address,t_struct(BridgeDetails)7733_storage)": { "encoding": "mapping", "key": "t_address", "label": "mapping(address => struct AgTokenSideChainMultiBridge.BridgeDetails)", "numberOfBytes": "32", - "value": "t_struct(BridgeDetails)7665_storage" + "value": "t_struct(BridgeDetails)7733_storage" }, "t_mapping(t_address,t_struct(Counter)2493_storage)": { "encoding": "mapping", @@ -1782,12 +1774,12 @@ "label": "string", "numberOfBytes": "32" }, - "t_struct(BridgeDetails)7665_storage": { + "t_struct(BridgeDetails)7733_storage": { "encoding": "inplace", "label": "struct AgTokenSideChainMultiBridge.BridgeDetails", "members": [ { - "astId": 7656, + "astId": 7724, "contract": "contracts/agToken/AgTokenSideChainMultiBridge.sol:AgTokenSideChainMultiBridge", "label": "limit", "offset": 0, @@ -1795,7 +1787,7 @@ "type": "t_uint256" }, { - "astId": 7658, + "astId": 7726, "contract": "contracts/agToken/AgTokenSideChainMultiBridge.sol:AgTokenSideChainMultiBridge", "label": "hourlyLimit", "offset": 0, @@ -1803,7 +1795,7 @@ "type": "t_uint256" }, { - "astId": 7660, + "astId": 7728, "contract": "contracts/agToken/AgTokenSideChainMultiBridge.sol:AgTokenSideChainMultiBridge", "label": "fee", "offset": 0, @@ -1811,7 +1803,7 @@ "type": "t_uint64" }, { - "astId": 7662, + "astId": 7730, "contract": "contracts/agToken/AgTokenSideChainMultiBridge.sol:AgTokenSideChainMultiBridge", "label": "allowed", "offset": 8, @@ -1819,7 +1811,7 @@ "type": "t_bool" }, { - "astId": 7664, + "astId": 7732, "contract": "contracts/agToken/AgTokenSideChainMultiBridge.sol:AgTokenSideChainMultiBridge", "label": "paused", "offset": 9, diff --git a/deployments/linea/CoreBorrowTest.json b/deployments/linea/CoreBorrowTest.json new file mode 100644 index 00000000..52f76711 --- /dev/null +++ b/deployments/linea/CoreBorrowTest.json @@ -0,0 +1,337 @@ +{ + "address": "0x16cd38b1B54E7abf307Cb2697E2D9321e843d5AA", + "abi": [ + { + "inputs": [ + { + "internalType": "address", + "name": "_logic", + "type": "address" + }, + { + "internalType": "address", + "name": "admin_", + "type": "address" + }, + { + "internalType": "bytes", + "name": "_data", + "type": "bytes" + } + ], + "stateMutability": "payable", + "type": "constructor" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "previousAdmin", + "type": "address" + }, + { + "indexed": false, + "internalType": "address", + "name": "newAdmin", + "type": "address" + } + ], + "name": "AdminChanged", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "beacon", + "type": "address" + } + ], + "name": "BeaconUpgraded", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "implementation", + "type": "address" + } + ], + "name": "Upgraded", + "type": "event" + }, + { + "stateMutability": "payable", + "type": "fallback" + }, + { + "inputs": [], + "name": "admin", + "outputs": [ + { + "internalType": "address", + "name": "admin_", + "type": "address" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "newAdmin", + "type": "address" + } + ], + "name": "changeAdmin", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "implementation", + "outputs": [ + { + "internalType": "address", + "name": "implementation_", + "type": "address" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "newImplementation", + "type": "address" + } + ], + "name": "upgradeTo", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "newImplementation", + "type": "address" + }, + { + "internalType": "bytes", + "name": "data", + "type": "bytes" + } + ], + "name": "upgradeToAndCall", + "outputs": [], + "stateMutability": "payable", + "type": "function" + }, + { + "stateMutability": "payable", + "type": "receive" + } + ], + "transactionHash": "0xb9f987f8b6f297beb56638b839326254e9f4444f29e5dc91efc4df32d36baf18", + "receipt": { + "to": null, + "from": "0xfdA462548Ce04282f4B6D6619823a7C64Fdc0185", + "contractAddress": "0x16cd38b1B54E7abf307Cb2697E2D9321e843d5AA", + "transactionIndex": 3, + "gasUsed": "1038531", + "logsBloom": "0x00000004000000000800000401000000480000000020000000000000200000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000002000000000000000000000080000000000000000000020000400000000000000800000000800000000000000000000400000000000000000000004000000000000000000003000080000000000000804000000000000000000000000000000400000000000000000000001000000000001000000020020000000000008000040000000800000400800100000000010020000000800000000000000000000000000408000000000000000000000000040000", + "blockHash": "0xd0cc4a0839c260030401069952680b40a53cd9226dbdc4b0b1b51818ef96beed", + "transactionHash": "0xb9f987f8b6f297beb56638b839326254e9f4444f29e5dc91efc4df32d36baf18", + "logs": [ + { + "transactionIndex": 3, + "blockNumber": 1596316, + "transactionHash": "0xb9f987f8b6f297beb56638b839326254e9f4444f29e5dc91efc4df32d36baf18", + "address": "0x16cd38b1B54E7abf307Cb2697E2D9321e843d5AA", + "topics": [ + "0xbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b", + "0x00000000000000000000000059153e939c5b4721543251ff3049ea04c755373b" + ], + "data": "0x", + "logIndex": 5, + "blockHash": "0xd0cc4a0839c260030401069952680b40a53cd9226dbdc4b0b1b51818ef96beed" + }, + { + "transactionIndex": 3, + "blockNumber": 1596316, + "transactionHash": "0xb9f987f8b6f297beb56638b839326254e9f4444f29e5dc91efc4df32d36baf18", + "address": "0x16cd38b1B54E7abf307Cb2697E2D9321e843d5AA", + "topics": [ + "0x2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d", + "0x7935bd0ae54bc31f548c14dba4d37c5c64b3f8ca900cb468fb8abd54d5894f55", + "0x000000000000000000000000fda462548ce04282f4b6d6619823a7c64fdc0185", + "0x000000000000000000000000fda462548ce04282f4b6d6619823a7c64fdc0185" + ], + "data": "0x", + "logIndex": 6, + "blockHash": "0xd0cc4a0839c260030401069952680b40a53cd9226dbdc4b0b1b51818ef96beed" + }, + { + "transactionIndex": 3, + "blockNumber": 1596316, + "transactionHash": "0xb9f987f8b6f297beb56638b839326254e9f4444f29e5dc91efc4df32d36baf18", + "address": "0x16cd38b1B54E7abf307Cb2697E2D9321e843d5AA", + "topics": [ + "0x2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d", + "0x55435dd261a4b9b3364963f7738a7a662ad9c84396d64be3365284bb7f0a5041", + "0x000000000000000000000000007475b60d88b02663d6f975927b70bb4335e4b3", + "0x000000000000000000000000fda462548ce04282f4b6d6619823a7c64fdc0185" + ], + "data": "0x", + "logIndex": 7, + "blockHash": "0xd0cc4a0839c260030401069952680b40a53cd9226dbdc4b0b1b51818ef96beed" + }, + { + "transactionIndex": 3, + "blockNumber": 1596316, + "transactionHash": "0xb9f987f8b6f297beb56638b839326254e9f4444f29e5dc91efc4df32d36baf18", + "address": "0x16cd38b1B54E7abf307Cb2697E2D9321e843d5AA", + "topics": [ + "0x2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d", + "0x55435dd261a4b9b3364963f7738a7a662ad9c84396d64be3365284bb7f0a5041", + "0x000000000000000000000000fda462548ce04282f4b6d6619823a7c64fdc0185", + "0x000000000000000000000000fda462548ce04282f4b6d6619823a7c64fdc0185" + ], + "data": "0x", + "logIndex": 8, + "blockHash": "0xd0cc4a0839c260030401069952680b40a53cd9226dbdc4b0b1b51818ef96beed" + }, + { + "transactionIndex": 3, + "blockNumber": 1596316, + "transactionHash": "0xb9f987f8b6f297beb56638b839326254e9f4444f29e5dc91efc4df32d36baf18", + "address": "0x16cd38b1B54E7abf307Cb2697E2D9321e843d5AA", + "topics": [ + "0xbd79b86ffe0ab8e8776151514217cd7cacd52c909f66475c3af44e129f0b00ff", + "0x55435dd261a4b9b3364963f7738a7a662ad9c84396d64be3365284bb7f0a5041", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x7935bd0ae54bc31f548c14dba4d37c5c64b3f8ca900cb468fb8abd54d5894f55" + ], + "data": "0x", + "logIndex": 9, + "blockHash": "0xd0cc4a0839c260030401069952680b40a53cd9226dbdc4b0b1b51818ef96beed" + }, + { + "transactionIndex": 3, + "blockNumber": 1596316, + "transactionHash": "0xb9f987f8b6f297beb56638b839326254e9f4444f29e5dc91efc4df32d36baf18", + "address": "0x16cd38b1B54E7abf307Cb2697E2D9321e843d5AA", + "topics": [ + "0xbd79b86ffe0ab8e8776151514217cd7cacd52c909f66475c3af44e129f0b00ff", + "0x7935bd0ae54bc31f548c14dba4d37c5c64b3f8ca900cb468fb8abd54d5894f55", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x7935bd0ae54bc31f548c14dba4d37c5c64b3f8ca900cb468fb8abd54d5894f55" + ], + "data": "0x", + "logIndex": 10, + "blockHash": "0xd0cc4a0839c260030401069952680b40a53cd9226dbdc4b0b1b51818ef96beed" + }, + { + "transactionIndex": 3, + "blockNumber": 1596316, + "transactionHash": "0xb9f987f8b6f297beb56638b839326254e9f4444f29e5dc91efc4df32d36baf18", + "address": "0x16cd38b1B54E7abf307Cb2697E2D9321e843d5AA", + "topics": [ + "0xbd79b86ffe0ab8e8776151514217cd7cacd52c909f66475c3af44e129f0b00ff", + "0x0ae0130c6b34f32239dfe5e419a3fbd7546b44e99783257f2d93526d5a936d46", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x7935bd0ae54bc31f548c14dba4d37c5c64b3f8ca900cb468fb8abd54d5894f55" + ], + "data": "0x", + "logIndex": 11, + "blockHash": "0xd0cc4a0839c260030401069952680b40a53cd9226dbdc4b0b1b51818ef96beed" + }, + { + "transactionIndex": 3, + "blockNumber": 1596316, + "transactionHash": "0xb9f987f8b6f297beb56638b839326254e9f4444f29e5dc91efc4df32d36baf18", + "address": "0x16cd38b1B54E7abf307Cb2697E2D9321e843d5AA", + "topics": [ + "0x7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb3847402498" + ], + "data": "0x0000000000000000000000000000000000000000000000000000000000000001", + "logIndex": 12, + "blockHash": "0xd0cc4a0839c260030401069952680b40a53cd9226dbdc4b0b1b51818ef96beed" + }, + { + "transactionIndex": 3, + "blockNumber": 1596316, + "transactionHash": "0xb9f987f8b6f297beb56638b839326254e9f4444f29e5dc91efc4df32d36baf18", + "address": "0x16cd38b1B54E7abf307Cb2697E2D9321e843d5AA", + "topics": [ + "0x7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f" + ], + "data": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000001d941ef0d3bba4ad67dbfbcee5262f4cee53a32b", + "logIndex": 13, + "blockHash": "0xd0cc4a0839c260030401069952680b40a53cd9226dbdc4b0b1b51818ef96beed" + } + ], + "blockNumber": 1596316, + "cumulativeGasUsed": "1285364", + "status": 1, + "byzantium": true + }, + "args": [ + "0x59153e939c5b4721543251ff3049Ea04c755373B", + "0x1D941EF0D3Bba4ad67DBfBCeE5262F4CEE53A32b", + "0x485cc955000000000000000000000000fda462548ce04282f4b6d6619823a7c64fdc0185000000000000000000000000007475b60d88b02663d6f975927b70bb4335e4b3" + ], + "numDeployments": 1, + "solcInputHash": "871924e0c138825a2736b76def8fef8d", + "metadata": "{\"compiler\":{\"version\":\"0.8.17+commit.8df45f5f\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_logic\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"admin_\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"_data\",\"type\":\"bytes\"}],\"stateMutability\":\"payable\",\"type\":\"constructor\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"previousAdmin\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"newAdmin\",\"type\":\"address\"}],\"name\":\"AdminChanged\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"beacon\",\"type\":\"address\"}],\"name\":\"BeaconUpgraded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"implementation\",\"type\":\"address\"}],\"name\":\"Upgraded\",\"type\":\"event\"},{\"stateMutability\":\"payable\",\"type\":\"fallback\"},{\"inputs\":[],\"name\":\"admin\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"admin_\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newAdmin\",\"type\":\"address\"}],\"name\":\"changeAdmin\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"implementation\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"implementation_\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newImplementation\",\"type\":\"address\"}],\"name\":\"upgradeTo\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newImplementation\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"}],\"name\":\"upgradeToAndCall\",\"outputs\":[],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"stateMutability\":\"payable\",\"type\":\"receive\"}],\"devdoc\":{\"details\":\"This contract implements a proxy that is upgradeable by an admin. It is fully forked from OpenZeppelin `TransparentUpgradeableProxy` To avoid https://medium.com/nomic-labs-blog/malicious-backdoors-in-ethereum-proxies-62629adf3357[proxy selector clashing], which can potentially be used in an attack, this contract uses the https://blog.openzeppelin.com/the-transparent-proxy-pattern/[transparent proxy pattern]. This pattern implies two things that go hand in hand: 1. If any account other than the admin calls the proxy, the call will be forwarded to the implementation, even if that call matches one of the admin functions exposed by the proxy itself. 2. If the admin calls the proxy, it can access the admin functions, but its calls will never be forwarded to the implementation. If the admin tries to call a function on the implementation it will fail with an error that says \\\"admin cannot fallback to proxy target\\\". These properties mean that the admin account can only be used for admin actions like upgrading the proxy or changing the admin, so it's best if it's a dedicated account that is not used for anything else. This will avoid headaches due to sudden errors when trying to call a function from the proxy implementation. Our recommendation is for the dedicated account to be an instance of the {ProxyAdmin} contract. If set up this way, you should think of the `ProxyAdmin` instance as the real administrative interface of your proxy.\",\"kind\":\"dev\",\"methods\":{\"admin()\":{\"details\":\"Returns the current admin. NOTE: Only the admin can call this function. See {ProxyAdmin-getProxyAdmin}. TIP: To get this value clients can read directly from the storage slot shown below (specified by EIP1967) using the https://eth.wiki/json-rpc/API#eth_getstorageat[`eth_getStorageAt`] RPC call. `0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103`\"},\"changeAdmin(address)\":{\"details\":\"Changes the admin of the proxy. Emits an {AdminChanged} event. NOTE: Only the admin can call this function. See {ProxyAdmin-changeProxyAdmin}.\"},\"constructor\":{\"details\":\"Initializes an upgradeable proxy managed by `_admin`, backed by the implementation at `_logic`, and optionally initialized with `_data` as explained in {ERC1967Proxy-constructor}.\"},\"implementation()\":{\"details\":\"Returns the current implementation. NOTE: Only the admin can call this function. See {ProxyAdmin-getProxyImplementation}. TIP: To get this value clients can read directly from the storage slot shown below (specified by EIP1967) using the https://eth.wiki/json-rpc/API#eth_getstorageat[`eth_getStorageAt`] RPC call. `0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc`\"},\"upgradeTo(address)\":{\"details\":\"Upgrade the implementation of the proxy. NOTE: Only the admin can call this function. See {ProxyAdmin-upgrade}.\"},\"upgradeToAndCall(address,bytes)\":{\"details\":\"Upgrade the implementation of the proxy, and then call a function from the new implementation as specified by `data`, which should be an encoded function call. This is useful to initialize new storage variables in the proxied contract. NOTE: Only the admin can call this function. See {ProxyAdmin-upgradeAndCall}.\"}},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/external/TransparentUpgradeableProxy.sol\":\"TransparentUpgradeableProxy\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":1000000},\"remappings\":[]},\"sources\":{\"@openzeppelin/contracts/interfaces/draft-IERC1822.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.5.0) (interfaces/draft-IERC1822.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev ERC1822: Universal Upgradeable Proxy Standard (UUPS) documents a method for upgradeability through a simplified\\n * proxy whose upgrades are fully controlled by the current implementation.\\n */\\ninterface IERC1822Proxiable {\\n /**\\n * @dev Returns the storage slot that the proxiable contract assumes is being used to store the implementation\\n * address.\\n *\\n * IMPORTANT: A proxy pointing at a proxiable contract should not be considered proxiable itself, because this risks\\n * bricking a proxy that upgrades to it, by delegating to itself until out of gas. Thus it is critical that this\\n * function revert if invoked through a proxy.\\n */\\n function proxiableUUID() external view returns (bytes32);\\n}\\n\",\"keccak256\":\"0x1d4afe6cb24200cc4545eed814ecf5847277dfe5d613a1707aad5fceecebcfff\",\"license\":\"MIT\"},\"@openzeppelin/contracts/proxy/ERC1967/ERC1967Proxy.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.7.0) (proxy/ERC1967/ERC1967Proxy.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../Proxy.sol\\\";\\nimport \\\"./ERC1967Upgrade.sol\\\";\\n\\n/**\\n * @dev This contract implements an upgradeable proxy. It is upgradeable because calls are delegated to an\\n * implementation address that can be changed. This address is stored in storage in the location specified by\\n * https://eips.ethereum.org/EIPS/eip-1967[EIP1967], so that it doesn't conflict with the storage layout of the\\n * implementation behind the proxy.\\n */\\ncontract ERC1967Proxy is Proxy, ERC1967Upgrade {\\n /**\\n * @dev Initializes the upgradeable proxy with an initial implementation specified by `_logic`.\\n *\\n * If `_data` is nonempty, it's used as data in a delegate call to `_logic`. This will typically be an encoded\\n * function call, and allows initializing the storage of the proxy like a Solidity constructor.\\n */\\n constructor(address _logic, bytes memory _data) payable {\\n _upgradeToAndCall(_logic, _data, false);\\n }\\n\\n /**\\n * @dev Returns the current implementation address.\\n */\\n function _implementation() internal view virtual override returns (address impl) {\\n return ERC1967Upgrade._getImplementation();\\n }\\n}\\n\",\"keccak256\":\"0xa2b22da3032e50b55f95ec1d13336102d675f341167aa76db571ef7f8bb7975d\",\"license\":\"MIT\"},\"@openzeppelin/contracts/proxy/ERC1967/ERC1967Upgrade.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.5.0) (proxy/ERC1967/ERC1967Upgrade.sol)\\n\\npragma solidity ^0.8.2;\\n\\nimport \\\"../beacon/IBeacon.sol\\\";\\nimport \\\"../../interfaces/draft-IERC1822.sol\\\";\\nimport \\\"../../utils/Address.sol\\\";\\nimport \\\"../../utils/StorageSlot.sol\\\";\\n\\n/**\\n * @dev This abstract contract provides getters and event emitting update functions for\\n * https://eips.ethereum.org/EIPS/eip-1967[EIP1967] slots.\\n *\\n * _Available since v4.1._\\n *\\n * @custom:oz-upgrades-unsafe-allow delegatecall\\n */\\nabstract contract ERC1967Upgrade {\\n // This is the keccak-256 hash of \\\"eip1967.proxy.rollback\\\" subtracted by 1\\n bytes32 private constant _ROLLBACK_SLOT = 0x4910fdfa16fed3260ed0e7147f7cc6da11a60208b5b9406d12a635614ffd9143;\\n\\n /**\\n * @dev Storage slot with the address of the current implementation.\\n * This is the keccak-256 hash of \\\"eip1967.proxy.implementation\\\" subtracted by 1, and is\\n * validated in the constructor.\\n */\\n bytes32 internal constant _IMPLEMENTATION_SLOT = 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc;\\n\\n /**\\n * @dev Emitted when the implementation is upgraded.\\n */\\n event Upgraded(address indexed implementation);\\n\\n /**\\n * @dev Returns the current implementation address.\\n */\\n function _getImplementation() internal view returns (address) {\\n return StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value;\\n }\\n\\n /**\\n * @dev Stores a new address in the EIP1967 implementation slot.\\n */\\n function _setImplementation(address newImplementation) private {\\n require(Address.isContract(newImplementation), \\\"ERC1967: new implementation is not a contract\\\");\\n StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value = newImplementation;\\n }\\n\\n /**\\n * @dev Perform implementation upgrade\\n *\\n * Emits an {Upgraded} event.\\n */\\n function _upgradeTo(address newImplementation) internal {\\n _setImplementation(newImplementation);\\n emit Upgraded(newImplementation);\\n }\\n\\n /**\\n * @dev Perform implementation upgrade with additional setup call.\\n *\\n * Emits an {Upgraded} event.\\n */\\n function _upgradeToAndCall(\\n address newImplementation,\\n bytes memory data,\\n bool forceCall\\n ) internal {\\n _upgradeTo(newImplementation);\\n if (data.length > 0 || forceCall) {\\n Address.functionDelegateCall(newImplementation, data);\\n }\\n }\\n\\n /**\\n * @dev Perform implementation upgrade with security checks for UUPS proxies, and additional setup call.\\n *\\n * Emits an {Upgraded} event.\\n */\\n function _upgradeToAndCallUUPS(\\n address newImplementation,\\n bytes memory data,\\n bool forceCall\\n ) internal {\\n // Upgrades from old implementations will perform a rollback test. This test requires the new\\n // implementation to upgrade back to the old, non-ERC1822 compliant, implementation. Removing\\n // this special case will break upgrade paths from old UUPS implementation to new ones.\\n if (StorageSlot.getBooleanSlot(_ROLLBACK_SLOT).value) {\\n _setImplementation(newImplementation);\\n } else {\\n try IERC1822Proxiable(newImplementation).proxiableUUID() returns (bytes32 slot) {\\n require(slot == _IMPLEMENTATION_SLOT, \\\"ERC1967Upgrade: unsupported proxiableUUID\\\");\\n } catch {\\n revert(\\\"ERC1967Upgrade: new implementation is not UUPS\\\");\\n }\\n _upgradeToAndCall(newImplementation, data, forceCall);\\n }\\n }\\n\\n /**\\n * @dev Storage slot with the admin of the contract.\\n * This is the keccak-256 hash of \\\"eip1967.proxy.admin\\\" subtracted by 1, and is\\n * validated in the constructor.\\n */\\n bytes32 internal constant _ADMIN_SLOT = 0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103;\\n\\n /**\\n * @dev Emitted when the admin account has changed.\\n */\\n event AdminChanged(address previousAdmin, address newAdmin);\\n\\n /**\\n * @dev Returns the current admin.\\n */\\n function _getAdmin() internal view returns (address) {\\n return StorageSlot.getAddressSlot(_ADMIN_SLOT).value;\\n }\\n\\n /**\\n * @dev Stores a new address in the EIP1967 admin slot.\\n */\\n function _setAdmin(address newAdmin) private {\\n require(newAdmin != address(0), \\\"ERC1967: new admin is the zero address\\\");\\n StorageSlot.getAddressSlot(_ADMIN_SLOT).value = newAdmin;\\n }\\n\\n /**\\n * @dev Changes the admin of the proxy.\\n *\\n * Emits an {AdminChanged} event.\\n */\\n function _changeAdmin(address newAdmin) internal {\\n emit AdminChanged(_getAdmin(), newAdmin);\\n _setAdmin(newAdmin);\\n }\\n\\n /**\\n * @dev The storage slot of the UpgradeableBeacon contract which defines the implementation for this proxy.\\n * This is bytes32(uint256(keccak256('eip1967.proxy.beacon')) - 1)) and is validated in the constructor.\\n */\\n bytes32 internal constant _BEACON_SLOT = 0xa3f0ad74e5423aebfd80d3ef4346578335a9a72aeaee59ff6cb3582b35133d50;\\n\\n /**\\n * @dev Emitted when the beacon is upgraded.\\n */\\n event BeaconUpgraded(address indexed beacon);\\n\\n /**\\n * @dev Returns the current beacon.\\n */\\n function _getBeacon() internal view returns (address) {\\n return StorageSlot.getAddressSlot(_BEACON_SLOT).value;\\n }\\n\\n /**\\n * @dev Stores a new beacon in the EIP1967 beacon slot.\\n */\\n function _setBeacon(address newBeacon) private {\\n require(Address.isContract(newBeacon), \\\"ERC1967: new beacon is not a contract\\\");\\n require(\\n Address.isContract(IBeacon(newBeacon).implementation()),\\n \\\"ERC1967: beacon implementation is not a contract\\\"\\n );\\n StorageSlot.getAddressSlot(_BEACON_SLOT).value = newBeacon;\\n }\\n\\n /**\\n * @dev Perform beacon upgrade with additional setup call. Note: This upgrades the address of the beacon, it does\\n * not upgrade the implementation contained in the beacon (see {UpgradeableBeacon-_setImplementation} for that).\\n *\\n * Emits a {BeaconUpgraded} event.\\n */\\n function _upgradeBeaconToAndCall(\\n address newBeacon,\\n bytes memory data,\\n bool forceCall\\n ) internal {\\n _setBeacon(newBeacon);\\n emit BeaconUpgraded(newBeacon);\\n if (data.length > 0 || forceCall) {\\n Address.functionDelegateCall(IBeacon(newBeacon).implementation(), data);\\n }\\n }\\n}\\n\",\"keccak256\":\"0xabf3f59bc0e5423eae45e459dbe92e7052c6983628d39008590edc852a62f94a\",\"license\":\"MIT\"},\"@openzeppelin/contracts/proxy/Proxy.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.6.0) (proxy/Proxy.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev This abstract contract provides a fallback function that delegates all calls to another contract using the EVM\\n * instruction `delegatecall`. We refer to the second contract as the _implementation_ behind the proxy, and it has to\\n * be specified by overriding the virtual {_implementation} function.\\n *\\n * Additionally, delegation to the implementation can be triggered manually through the {_fallback} function, or to a\\n * different contract through the {_delegate} function.\\n *\\n * The success and return data of the delegated call will be returned back to the caller of the proxy.\\n */\\nabstract contract Proxy {\\n /**\\n * @dev Delegates the current call to `implementation`.\\n *\\n * This function does not return to its internal call site, it will return directly to the external caller.\\n */\\n function _delegate(address implementation) internal virtual {\\n assembly {\\n // Copy msg.data. We take full control of memory in this inline assembly\\n // block because it will not return to Solidity code. We overwrite the\\n // Solidity scratch pad at memory position 0.\\n calldatacopy(0, 0, calldatasize())\\n\\n // Call the implementation.\\n // out and outsize are 0 because we don't know the size yet.\\n let result := delegatecall(gas(), implementation, 0, calldatasize(), 0, 0)\\n\\n // Copy the returned data.\\n returndatacopy(0, 0, returndatasize())\\n\\n switch result\\n // delegatecall returns 0 on error.\\n case 0 {\\n revert(0, returndatasize())\\n }\\n default {\\n return(0, returndatasize())\\n }\\n }\\n }\\n\\n /**\\n * @dev This is a virtual function that should be overridden so it returns the address to which the fallback function\\n * and {_fallback} should delegate.\\n */\\n function _implementation() internal view virtual returns (address);\\n\\n /**\\n * @dev Delegates the current call to the address returned by `_implementation()`.\\n *\\n * This function does not return to its internal call site, it will return directly to the external caller.\\n */\\n function _fallback() internal virtual {\\n _beforeFallback();\\n _delegate(_implementation());\\n }\\n\\n /**\\n * @dev Fallback function that delegates calls to the address returned by `_implementation()`. Will run if no other\\n * function in the contract matches the call data.\\n */\\n fallback() external payable virtual {\\n _fallback();\\n }\\n\\n /**\\n * @dev Fallback function that delegates calls to the address returned by `_implementation()`. Will run if call data\\n * is empty.\\n */\\n receive() external payable virtual {\\n _fallback();\\n }\\n\\n /**\\n * @dev Hook that is called before falling back to the implementation. Can happen as part of a manual `_fallback`\\n * call, or as part of the Solidity `fallback` or `receive` functions.\\n *\\n * If overridden should call `super._beforeFallback()`.\\n */\\n function _beforeFallback() internal virtual {}\\n}\\n\",\"keccak256\":\"0xc130fe33f1b2132158531a87734153293f6d07bc263ff4ac90e85da9c82c0e27\",\"license\":\"MIT\"},\"@openzeppelin/contracts/proxy/beacon/IBeacon.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (proxy/beacon/IBeacon.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev This is the interface that {BeaconProxy} expects of its beacon.\\n */\\ninterface IBeacon {\\n /**\\n * @dev Must return an address that can be used as a delegate call target.\\n *\\n * {BeaconProxy} will check that this address is a contract.\\n */\\n function implementation() external view returns (address);\\n}\\n\",\"keccak256\":\"0xd50a3421ac379ccb1be435fa646d66a65c986b4924f0849839f08692f39dde61\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/Address.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.7.0) (utils/Address.sol)\\n\\npragma solidity ^0.8.1;\\n\\n/**\\n * @dev Collection of functions related to the address type\\n */\\nlibrary Address {\\n /**\\n * @dev Returns true if `account` is a contract.\\n *\\n * [IMPORTANT]\\n * ====\\n * It is unsafe to assume that an address for which this function returns\\n * false is an externally-owned account (EOA) and not a contract.\\n *\\n * Among others, `isContract` will return false for the following\\n * types of addresses:\\n *\\n * - an externally-owned account\\n * - a contract in construction\\n * - an address where a contract will be created\\n * - an address where a contract lived, but was destroyed\\n * ====\\n *\\n * [IMPORTANT]\\n * ====\\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\\n *\\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\\n * constructor.\\n * ====\\n */\\n function isContract(address account) internal view returns (bool) {\\n // This method relies on extcodesize/address.code.length, which returns 0\\n // for contracts in construction, since the code is only stored at the end\\n // of the constructor execution.\\n\\n return account.code.length > 0;\\n }\\n\\n /**\\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\\n * `recipient`, forwarding all available gas and reverting on errors.\\n *\\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\\n * imposed by `transfer`, making them unable to receive funds via\\n * `transfer`. {sendValue} removes this limitation.\\n *\\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\\n *\\n * IMPORTANT: because control is transferred to `recipient`, care must be\\n * taken to not create reentrancy vulnerabilities. Consider using\\n * {ReentrancyGuard} or the\\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\\n */\\n function sendValue(address payable recipient, uint256 amount) internal {\\n require(address(this).balance >= amount, \\\"Address: insufficient balance\\\");\\n\\n (bool success, ) = recipient.call{value: amount}(\\\"\\\");\\n require(success, \\\"Address: unable to send value, recipient may have reverted\\\");\\n }\\n\\n /**\\n * @dev Performs a Solidity function call using a low level `call`. A\\n * plain `call` is an unsafe replacement for a function call: use this\\n * function instead.\\n *\\n * If `target` reverts with a revert reason, it is bubbled up by this\\n * function (like regular Solidity function calls).\\n *\\n * Returns the raw returned data. To convert to the expected return value,\\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\\n *\\n * Requirements:\\n *\\n * - `target` must be a contract.\\n * - calling `target` with `data` must not revert.\\n *\\n * _Available since v3.1._\\n */\\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\\n return functionCall(target, data, \\\"Address: low-level call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\\n * `errorMessage` as a fallback revert reason when `target` reverts.\\n *\\n * _Available since v3.1._\\n */\\n function functionCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n return functionCallWithValue(target, data, 0, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but also transferring `value` wei to `target`.\\n *\\n * Requirements:\\n *\\n * - the calling contract must have an ETH balance of at least `value`.\\n * - the called Solidity function must be `payable`.\\n *\\n * _Available since v3.1._\\n */\\n function functionCallWithValue(\\n address target,\\n bytes memory data,\\n uint256 value\\n ) internal returns (bytes memory) {\\n return functionCallWithValue(target, data, value, \\\"Address: low-level call with value failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\\n * with `errorMessage` as a fallback revert reason when `target` reverts.\\n *\\n * _Available since v3.1._\\n */\\n function functionCallWithValue(\\n address target,\\n bytes memory data,\\n uint256 value,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n require(address(this).balance >= value, \\\"Address: insufficient balance for call\\\");\\n require(isContract(target), \\\"Address: call to non-contract\\\");\\n\\n (bool success, bytes memory returndata) = target.call{value: value}(data);\\n return verifyCallResult(success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but performing a static call.\\n *\\n * _Available since v3.3._\\n */\\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\\n return functionStaticCall(target, data, \\\"Address: low-level static call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\\n * but performing a static call.\\n *\\n * _Available since v3.3._\\n */\\n function functionStaticCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal view returns (bytes memory) {\\n require(isContract(target), \\\"Address: static call to non-contract\\\");\\n\\n (bool success, bytes memory returndata) = target.staticcall(data);\\n return verifyCallResult(success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but performing a delegate call.\\n *\\n * _Available since v3.4._\\n */\\n function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {\\n return functionDelegateCall(target, data, \\\"Address: low-level delegate call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\\n * but performing a delegate call.\\n *\\n * _Available since v3.4._\\n */\\n function functionDelegateCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n require(isContract(target), \\\"Address: delegate call to non-contract\\\");\\n\\n (bool success, bytes memory returndata) = target.delegatecall(data);\\n return verifyCallResult(success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the\\n * revert reason using the provided one.\\n *\\n * _Available since v4.3._\\n */\\n function verifyCallResult(\\n bool success,\\n bytes memory returndata,\\n string memory errorMessage\\n ) internal pure returns (bytes memory) {\\n if (success) {\\n return returndata;\\n } else {\\n // Look for revert reason and bubble it up if present\\n if (returndata.length > 0) {\\n // The easiest way to bubble the revert reason is using memory via assembly\\n /// @solidity memory-safe-assembly\\n assembly {\\n let returndata_size := mload(returndata)\\n revert(add(32, returndata), returndata_size)\\n }\\n } else {\\n revert(errorMessage);\\n }\\n }\\n }\\n}\\n\",\"keccak256\":\"0xd6153ce99bcdcce22b124f755e72553295be6abcd63804cfdffceb188b8bef10\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/StorageSlot.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.7.0) (utils/StorageSlot.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Library for reading and writing primitive types to specific storage slots.\\n *\\n * Storage slots are often used to avoid storage conflict when dealing with upgradeable contracts.\\n * This library helps with reading and writing to such slots without the need for inline assembly.\\n *\\n * The functions in this library return Slot structs that contain a `value` member that can be used to read or write.\\n *\\n * Example usage to set ERC1967 implementation slot:\\n * ```\\n * contract ERC1967 {\\n * bytes32 internal constant _IMPLEMENTATION_SLOT = 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc;\\n *\\n * function _getImplementation() internal view returns (address) {\\n * return StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value;\\n * }\\n *\\n * function _setImplementation(address newImplementation) internal {\\n * require(Address.isContract(newImplementation), \\\"ERC1967: new implementation is not a contract\\\");\\n * StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value = newImplementation;\\n * }\\n * }\\n * ```\\n *\\n * _Available since v4.1 for `address`, `bool`, `bytes32`, and `uint256`._\\n */\\nlibrary StorageSlot {\\n struct AddressSlot {\\n address value;\\n }\\n\\n struct BooleanSlot {\\n bool value;\\n }\\n\\n struct Bytes32Slot {\\n bytes32 value;\\n }\\n\\n struct Uint256Slot {\\n uint256 value;\\n }\\n\\n /**\\n * @dev Returns an `AddressSlot` with member `value` located at `slot`.\\n */\\n function getAddressSlot(bytes32 slot) internal pure returns (AddressSlot storage r) {\\n /// @solidity memory-safe-assembly\\n assembly {\\n r.slot := slot\\n }\\n }\\n\\n /**\\n * @dev Returns an `BooleanSlot` with member `value` located at `slot`.\\n */\\n function getBooleanSlot(bytes32 slot) internal pure returns (BooleanSlot storage r) {\\n /// @solidity memory-safe-assembly\\n assembly {\\n r.slot := slot\\n }\\n }\\n\\n /**\\n * @dev Returns an `Bytes32Slot` with member `value` located at `slot`.\\n */\\n function getBytes32Slot(bytes32 slot) internal pure returns (Bytes32Slot storage r) {\\n /// @solidity memory-safe-assembly\\n assembly {\\n r.slot := slot\\n }\\n }\\n\\n /**\\n * @dev Returns an `Uint256Slot` with member `value` located at `slot`.\\n */\\n function getUint256Slot(bytes32 slot) internal pure returns (Uint256Slot storage r) {\\n /// @solidity memory-safe-assembly\\n assembly {\\n r.slot := slot\\n }\\n }\\n}\\n\",\"keccak256\":\"0xd5c50c54bf02740ebd122ff06832546cb5fa84486d52695a9ccfd11666e0c81d\",\"license\":\"MIT\"},\"contracts/external/TransparentUpgradeableProxy.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-3.0\\n\\npragma solidity ^0.8.12;\\n\\nimport \\\"@openzeppelin/contracts/proxy/ERC1967/ERC1967Proxy.sol\\\";\\n\\n/**\\n * @dev This contract implements a proxy that is upgradeable by an admin. It is fully forked from OpenZeppelin\\n * `TransparentUpgradeableProxy`\\n *\\n * To avoid https://medium.com/nomic-labs-blog/malicious-backdoors-in-ethereum-proxies-62629adf3357[proxy selector\\n * clashing], which can potentially be used in an attack, this contract uses the\\n * https://blog.openzeppelin.com/the-transparent-proxy-pattern/[transparent proxy pattern]. This pattern implies two\\n * things that go hand in hand:\\n *\\n * 1. If any account other than the admin calls the proxy, the call will be forwarded to the implementation, even if\\n * that call matches one of the admin functions exposed by the proxy itself.\\n * 2. If the admin calls the proxy, it can access the admin functions, but its calls will never be forwarded to the\\n * implementation. If the admin tries to call a function on the implementation it will fail with an error that says\\n * \\\"admin cannot fallback to proxy target\\\".\\n *\\n * These properties mean that the admin account can only be used for admin actions like upgrading the proxy or changing\\n * the admin, so it's best if it's a dedicated account that is not used for anything else. This will avoid headaches due\\n * to sudden errors when trying to call a function from the proxy implementation.\\n *\\n * Our recommendation is for the dedicated account to be an instance of the {ProxyAdmin} contract. If set up this way,\\n * you should think of the `ProxyAdmin` instance as the real administrative interface of your proxy.\\n */\\ncontract TransparentUpgradeableProxy is ERC1967Proxy {\\n /**\\n * @dev Initializes an upgradeable proxy managed by `_admin`, backed by the implementation at `_logic`, and\\n * optionally initialized with `_data` as explained in {ERC1967Proxy-constructor}.\\n */\\n constructor(address _logic, address admin_, bytes memory _data) payable ERC1967Proxy(_logic, _data) {\\n assert(_ADMIN_SLOT == bytes32(uint256(keccak256(\\\"eip1967.proxy.admin\\\")) - 1));\\n _changeAdmin(admin_);\\n }\\n\\n /**\\n * @dev Modifier used internally that will delegate the call to the implementation unless the sender is the admin.\\n */\\n modifier ifAdmin() {\\n if (msg.sender == _getAdmin()) {\\n _;\\n } else {\\n _fallback();\\n }\\n }\\n\\n /**\\n * @dev Returns the current admin.\\n *\\n * NOTE: Only the admin can call this function. See {ProxyAdmin-getProxyAdmin}.\\n *\\n * TIP: To get this value clients can read directly from the storage slot shown below (specified by EIP1967) using the\\n * https://eth.wiki/json-rpc/API#eth_getstorageat[`eth_getStorageAt`] RPC call.\\n * `0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103`\\n */\\n function admin() external ifAdmin returns (address admin_) {\\n admin_ = _getAdmin();\\n }\\n\\n /**\\n * @dev Returns the current implementation.\\n *\\n * NOTE: Only the admin can call this function. See {ProxyAdmin-getProxyImplementation}.\\n *\\n * TIP: To get this value clients can read directly from the storage slot shown below (specified by EIP1967) using the\\n * https://eth.wiki/json-rpc/API#eth_getstorageat[`eth_getStorageAt`] RPC call.\\n * `0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc`\\n */\\n function implementation() external ifAdmin returns (address implementation_) {\\n implementation_ = _implementation();\\n }\\n\\n /**\\n * @dev Changes the admin of the proxy.\\n *\\n * Emits an {AdminChanged} event.\\n *\\n * NOTE: Only the admin can call this function. See {ProxyAdmin-changeProxyAdmin}.\\n */\\n function changeAdmin(address newAdmin) external virtual ifAdmin {\\n _changeAdmin(newAdmin);\\n }\\n\\n /**\\n * @dev Upgrade the implementation of the proxy.\\n *\\n * NOTE: Only the admin can call this function. See {ProxyAdmin-upgrade}.\\n */\\n function upgradeTo(address newImplementation) external ifAdmin {\\n _upgradeToAndCall(newImplementation, bytes(\\\"\\\"), false);\\n }\\n\\n /**\\n * @dev Upgrade the implementation of the proxy, and then call a function from the new implementation as specified\\n * by `data`, which should be an encoded function call. This is useful to initialize new storage variables in the\\n * proxied contract.\\n *\\n * NOTE: Only the admin can call this function. See {ProxyAdmin-upgradeAndCall}.\\n */\\n function upgradeToAndCall(address newImplementation, bytes calldata data) external payable ifAdmin {\\n _upgradeToAndCall(newImplementation, data, true);\\n }\\n\\n /**\\n * @dev Returns the current admin.\\n */\\n function _admin() internal view virtual returns (address) {\\n return _getAdmin();\\n }\\n\\n /**\\n * @dev Makes sure the admin cannot access the fallback function. See {Proxy-_beforeFallback}.\\n */\\n function _beforeFallback() internal virtual override {\\n require(msg.sender != _getAdmin(), \\\"TransparentUpgradeableProxy: admin cannot fallback to proxy target\\\");\\n super._beforeFallback();\\n }\\n}\\n\",\"keccak256\":\"0x93a67a0f612ea3ff2a76315e138a6a88267270a1379d3cc7be52845fbbe611e2\",\"license\":\"GPL-3.0\"}},\"version\":1}", + "bytecode": "0x6080604052604051620010bb380380620010bb8339810160408190526200002691620004d8565b828162000036828260006200009a565b5062000066905060017fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6104620005b8565b6000805160206200107483398151915214620000865762000086620005da565b6200009182620000d7565b50505062000643565b620000a58362000132565b600082511180620000b35750805b15620000d257620000d083836200017460201b6200028c1760201c565b505b505050565b7f7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f62000102620001a5565b604080516001600160a01b03928316815291841660208301520160405180910390a16200012f81620001de565b50565b6200013d8162000293565b6040516001600160a01b038216907fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b90600090a250565b60606200019c8383604051806060016040528060278152602001620010946027913962000347565b90505b92915050565b6000620001cf6000805160206200107483398151915260001b6200042f60201b6200022e1760201c565b546001600160a01b0316919050565b6001600160a01b038116620002495760405162461bcd60e51b815260206004820152602660248201527f455243313936373a206e65772061646d696e20697320746865207a65726f206160448201526564647265737360d01b60648201526084015b60405180910390fd5b80620002726000805160206200107483398151915260001b6200042f60201b6200022e1760201c565b80546001600160a01b0319166001600160a01b039290921691909117905550565b620002a9816200043260201b620002b81760201c565b6200030d5760405162461bcd60e51b815260206004820152602d60248201527f455243313936373a206e657720696d706c656d656e746174696f6e206973206e60448201526c1bdd08184818dbdb9d1c9858dd609a1b606482015260840162000240565b80620002727f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc60001b6200042f60201b6200022e1760201c565b60606001600160a01b0384163b620003b15760405162461bcd60e51b815260206004820152602660248201527f416464726573733a2064656c65676174652063616c6c20746f206e6f6e2d636f6044820152651b9d1c9858dd60d21b606482015260840162000240565b600080856001600160a01b031685604051620003ce9190620005f0565b600060405180830381855af49150503d80600081146200040b576040519150601f19603f3d011682016040523d82523d6000602084013e62000410565b606091505b5090925090506200042382828662000441565b925050505b9392505050565b90565b6001600160a01b03163b151590565b606083156200045257508162000428565b825115620004635782518084602001fd5b8160405162461bcd60e51b81526004016200024091906200060e565b80516001600160a01b03811681146200049757600080fd5b919050565b634e487b7160e01b600052604160045260246000fd5b60005b83811015620004cf578181015183820152602001620004b5565b50506000910152565b600080600060608486031215620004ee57600080fd5b620004f9846200047f565b925062000509602085016200047f565b60408501519092506001600160401b03808211156200052757600080fd5b818601915086601f8301126200053c57600080fd5b8151818111156200055157620005516200049c565b604051601f8201601f19908116603f011681019083821181831017156200057c576200057c6200049c565b816040528281528960208487010111156200059657600080fd5b620005a9836020830160208801620004b2565b80955050505050509250925092565b818103818111156200019f57634e487b7160e01b600052601160045260246000fd5b634e487b7160e01b600052600160045260246000fd5b6000825162000604818460208701620004b2565b9190910192915050565b60208152600082518060208401526200062f816040850160208701620004b2565b601f01601f19169190910160400192915050565b610a2180620006536000396000f3fe60806040526004361061005e5760003560e01c80635c60da1b116100435780635c60da1b146100a85780638f283970146100e6578063f851a440146101065761006d565b80633659cfe6146100755780634f1ef286146100955761006d565b3661006d5761006b61011b565b005b61006b61011b565b34801561008157600080fd5b5061006b610090366004610895565b610135565b61006b6100a33660046108b0565b61017f565b3480156100b457600080fd5b506100bd6101f3565b60405173ffffffffffffffffffffffffffffffffffffffff909116815260200160405180910390f35b3480156100f257600080fd5b5061006b610101366004610895565b610231565b34801561011257600080fd5b506100bd61025e565b6101236102d4565b61013361012e6103ab565b6103b5565b565b61013d6103d9565b73ffffffffffffffffffffffffffffffffffffffff1633036101775761017481604051806020016040528060008152506000610419565b50565b61017461011b565b6101876103d9565b73ffffffffffffffffffffffffffffffffffffffff1633036101eb576101e68383838080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525060019250610419915050565b505050565b6101e661011b565b60006101fd6103d9565b73ffffffffffffffffffffffffffffffffffffffff163303610226576102216103ab565b905090565b61022e61011b565b90565b6102396103d9565b73ffffffffffffffffffffffffffffffffffffffff1633036101775761017481610444565b60006102686103d9565b73ffffffffffffffffffffffffffffffffffffffff163303610226576102216103d9565b60606102b183836040518060600160405280602781526020016109c5602791396104a5565b9392505050565b73ffffffffffffffffffffffffffffffffffffffff163b151590565b6102dc6103d9565b73ffffffffffffffffffffffffffffffffffffffff163303610133576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604260248201527f5472616e73706172656e745570677261646561626c6550726f78793a2061646d60448201527f696e2063616e6e6f742066616c6c6261636b20746f2070726f7879207461726760648201527f6574000000000000000000000000000000000000000000000000000000000000608482015260a4015b60405180910390fd5b60006102216105cd565b3660008037600080366000845af43d6000803e8080156103d4573d6000f35b3d6000fd5b60007fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035b5473ffffffffffffffffffffffffffffffffffffffff16919050565b610422836105f5565b60008251118061042f5750805b156101e65761043e838361028c565b50505050565b7f7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f61046d6103d9565b6040805173ffffffffffffffffffffffffffffffffffffffff928316815291841660208301520160405180910390a161017481610642565b606073ffffffffffffffffffffffffffffffffffffffff84163b61054b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f416464726573733a2064656c65676174652063616c6c20746f206e6f6e2d636f60448201527f6e7472616374000000000000000000000000000000000000000000000000000060648201526084016103a2565b6000808573ffffffffffffffffffffffffffffffffffffffff16856040516105739190610957565b600060405180830381855af49150503d80600081146105ae576040519150601f19603f3d011682016040523d82523d6000602084013e6105b3565b606091505b50915091506105c382828661074e565b9695505050505050565b60007f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc6103fd565b6105fe816107a1565b60405173ffffffffffffffffffffffffffffffffffffffff8216907fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b90600090a250565b73ffffffffffffffffffffffffffffffffffffffff81166106e5576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f455243313936373a206e65772061646d696e20697320746865207a65726f206160448201527f646472657373000000000000000000000000000000000000000000000000000060648201526084016103a2565b807fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035b80547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff9290921691909117905550565b6060831561075d5750816102b1565b82511561076d5782518084602001fd5b816040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016103a29190610973565b73ffffffffffffffffffffffffffffffffffffffff81163b610845576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602d60248201527f455243313936373a206e657720696d706c656d656e746174696f6e206973206e60448201527f6f74206120636f6e74726163740000000000000000000000000000000000000060648201526084016103a2565b807f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc610708565b803573ffffffffffffffffffffffffffffffffffffffff8116811461089057600080fd5b919050565b6000602082840312156108a757600080fd5b6102b18261086c565b6000806000604084860312156108c557600080fd5b6108ce8461086c565b9250602084013567ffffffffffffffff808211156108eb57600080fd5b818601915086601f8301126108ff57600080fd5b81358181111561090e57600080fd5b87602082850101111561092057600080fd5b6020830194508093505050509250925092565b60005b8381101561094e578181015183820152602001610936565b50506000910152565b60008251610969818460208701610933565b9190910192915050565b6020815260008251806020840152610992816040850160208701610933565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016919091016040019291505056fe416464726573733a206c6f772d6c6576656c2064656c65676174652063616c6c206661696c6564a2646970667358221220e96638b07fb1675d93a95c49e417bc8111448b23a59918698cdcd8fd488dd7cf64736f6c63430008110033b53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103416464726573733a206c6f772d6c6576656c2064656c65676174652063616c6c206661696c6564", + "deployedBytecode": "0x60806040526004361061005e5760003560e01c80635c60da1b116100435780635c60da1b146100a85780638f283970146100e6578063f851a440146101065761006d565b80633659cfe6146100755780634f1ef286146100955761006d565b3661006d5761006b61011b565b005b61006b61011b565b34801561008157600080fd5b5061006b610090366004610895565b610135565b61006b6100a33660046108b0565b61017f565b3480156100b457600080fd5b506100bd6101f3565b60405173ffffffffffffffffffffffffffffffffffffffff909116815260200160405180910390f35b3480156100f257600080fd5b5061006b610101366004610895565b610231565b34801561011257600080fd5b506100bd61025e565b6101236102d4565b61013361012e6103ab565b6103b5565b565b61013d6103d9565b73ffffffffffffffffffffffffffffffffffffffff1633036101775761017481604051806020016040528060008152506000610419565b50565b61017461011b565b6101876103d9565b73ffffffffffffffffffffffffffffffffffffffff1633036101eb576101e68383838080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525060019250610419915050565b505050565b6101e661011b565b60006101fd6103d9565b73ffffffffffffffffffffffffffffffffffffffff163303610226576102216103ab565b905090565b61022e61011b565b90565b6102396103d9565b73ffffffffffffffffffffffffffffffffffffffff1633036101775761017481610444565b60006102686103d9565b73ffffffffffffffffffffffffffffffffffffffff163303610226576102216103d9565b60606102b183836040518060600160405280602781526020016109c5602791396104a5565b9392505050565b73ffffffffffffffffffffffffffffffffffffffff163b151590565b6102dc6103d9565b73ffffffffffffffffffffffffffffffffffffffff163303610133576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604260248201527f5472616e73706172656e745570677261646561626c6550726f78793a2061646d60448201527f696e2063616e6e6f742066616c6c6261636b20746f2070726f7879207461726760648201527f6574000000000000000000000000000000000000000000000000000000000000608482015260a4015b60405180910390fd5b60006102216105cd565b3660008037600080366000845af43d6000803e8080156103d4573d6000f35b3d6000fd5b60007fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035b5473ffffffffffffffffffffffffffffffffffffffff16919050565b610422836105f5565b60008251118061042f5750805b156101e65761043e838361028c565b50505050565b7f7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f61046d6103d9565b6040805173ffffffffffffffffffffffffffffffffffffffff928316815291841660208301520160405180910390a161017481610642565b606073ffffffffffffffffffffffffffffffffffffffff84163b61054b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f416464726573733a2064656c65676174652063616c6c20746f206e6f6e2d636f60448201527f6e7472616374000000000000000000000000000000000000000000000000000060648201526084016103a2565b6000808573ffffffffffffffffffffffffffffffffffffffff16856040516105739190610957565b600060405180830381855af49150503d80600081146105ae576040519150601f19603f3d011682016040523d82523d6000602084013e6105b3565b606091505b50915091506105c382828661074e565b9695505050505050565b60007f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc6103fd565b6105fe816107a1565b60405173ffffffffffffffffffffffffffffffffffffffff8216907fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b90600090a250565b73ffffffffffffffffffffffffffffffffffffffff81166106e5576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f455243313936373a206e65772061646d696e20697320746865207a65726f206160448201527f646472657373000000000000000000000000000000000000000000000000000060648201526084016103a2565b807fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035b80547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff9290921691909117905550565b6060831561075d5750816102b1565b82511561076d5782518084602001fd5b816040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016103a29190610973565b73ffffffffffffffffffffffffffffffffffffffff81163b610845576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602d60248201527f455243313936373a206e657720696d706c656d656e746174696f6e206973206e60448201527f6f74206120636f6e74726163740000000000000000000000000000000000000060648201526084016103a2565b807f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc610708565b803573ffffffffffffffffffffffffffffffffffffffff8116811461089057600080fd5b919050565b6000602082840312156108a757600080fd5b6102b18261086c565b6000806000604084860312156108c557600080fd5b6108ce8461086c565b9250602084013567ffffffffffffffff808211156108eb57600080fd5b818601915086601f8301126108ff57600080fd5b81358181111561090e57600080fd5b87602082850101111561092057600080fd5b6020830194508093505050509250925092565b60005b8381101561094e578181015183820152602001610936565b50506000910152565b60008251610969818460208701610933565b9190910192915050565b6020815260008251806020840152610992816040850160208701610933565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016919091016040019291505056fe416464726573733a206c6f772d6c6576656c2064656c65676174652063616c6c206661696c6564a2646970667358221220e96638b07fb1675d93a95c49e417bc8111448b23a59918698cdcd8fd488dd7cf64736f6c63430008110033", + "devdoc": { + "details": "This contract implements a proxy that is upgradeable by an admin. It is fully forked from OpenZeppelin `TransparentUpgradeableProxy` To avoid https://medium.com/nomic-labs-blog/malicious-backdoors-in-ethereum-proxies-62629adf3357[proxy selector clashing], which can potentially be used in an attack, this contract uses the https://blog.openzeppelin.com/the-transparent-proxy-pattern/[transparent proxy pattern]. This pattern implies two things that go hand in hand: 1. If any account other than the admin calls the proxy, the call will be forwarded to the implementation, even if that call matches one of the admin functions exposed by the proxy itself. 2. If the admin calls the proxy, it can access the admin functions, but its calls will never be forwarded to the implementation. If the admin tries to call a function on the implementation it will fail with an error that says \"admin cannot fallback to proxy target\". These properties mean that the admin account can only be used for admin actions like upgrading the proxy or changing the admin, so it's best if it's a dedicated account that is not used for anything else. This will avoid headaches due to sudden errors when trying to call a function from the proxy implementation. Our recommendation is for the dedicated account to be an instance of the {ProxyAdmin} contract. If set up this way, you should think of the `ProxyAdmin` instance as the real administrative interface of your proxy.", + "kind": "dev", + "methods": { + "admin()": { + "details": "Returns the current admin. NOTE: Only the admin can call this function. See {ProxyAdmin-getProxyAdmin}. TIP: To get this value clients can read directly from the storage slot shown below (specified by EIP1967) using the https://eth.wiki/json-rpc/API#eth_getstorageat[`eth_getStorageAt`] RPC call. `0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103`" + }, + "changeAdmin(address)": { + "details": "Changes the admin of the proxy. Emits an {AdminChanged} event. NOTE: Only the admin can call this function. See {ProxyAdmin-changeProxyAdmin}." + }, + "constructor": { + "details": "Initializes an upgradeable proxy managed by `_admin`, backed by the implementation at `_logic`, and optionally initialized with `_data` as explained in {ERC1967Proxy-constructor}." + }, + "implementation()": { + "details": "Returns the current implementation. NOTE: Only the admin can call this function. See {ProxyAdmin-getProxyImplementation}. TIP: To get this value clients can read directly from the storage slot shown below (specified by EIP1967) using the https://eth.wiki/json-rpc/API#eth_getstorageat[`eth_getStorageAt`] RPC call. `0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc`" + }, + "upgradeTo(address)": { + "details": "Upgrade the implementation of the proxy. NOTE: Only the admin can call this function. See {ProxyAdmin-upgrade}." + }, + "upgradeToAndCall(address,bytes)": { + "details": "Upgrade the implementation of the proxy, and then call a function from the new implementation as specified by `data`, which should be an encoded function call. This is useful to initialize new storage variables in the proxied contract. NOTE: Only the admin can call this function. See {ProxyAdmin-upgradeAndCall}." + } + }, + "version": 1 + }, + "userdoc": { + "kind": "user", + "methods": {}, + "version": 1 + }, + "storageLayout": { + "storage": [], + "types": null + } +} \ No newline at end of file diff --git a/deployments/linea/LayerZeroBridge_USD.json b/deployments/linea/LayerZeroBridge_USD.json new file mode 100644 index 00000000..b83c5951 --- /dev/null +++ b/deployments/linea/LayerZeroBridge_USD.json @@ -0,0 +1,275 @@ +{ + "address": "0x07C89CC845D046aEad377DddC61114AA9D920Ac0", + "abi": [ + { + "inputs": [ + { + "internalType": "address", + "name": "_logic", + "type": "address" + }, + { + "internalType": "address", + "name": "admin_", + "type": "address" + }, + { + "internalType": "bytes", + "name": "_data", + "type": "bytes" + } + ], + "stateMutability": "payable", + "type": "constructor" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "previousAdmin", + "type": "address" + }, + { + "indexed": false, + "internalType": "address", + "name": "newAdmin", + "type": "address" + } + ], + "name": "AdminChanged", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "beacon", + "type": "address" + } + ], + "name": "BeaconUpgraded", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "implementation", + "type": "address" + } + ], + "name": "Upgraded", + "type": "event" + }, + { + "stateMutability": "payable", + "type": "fallback" + }, + { + "inputs": [], + "name": "admin", + "outputs": [ + { + "internalType": "address", + "name": "admin_", + "type": "address" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "newAdmin", + "type": "address" + } + ], + "name": "changeAdmin", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "implementation", + "outputs": [ + { + "internalType": "address", + "name": "implementation_", + "type": "address" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "newImplementation", + "type": "address" + } + ], + "name": "upgradeTo", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "newImplementation", + "type": "address" + }, + { + "internalType": "bytes", + "name": "data", + "type": "bytes" + } + ], + "name": "upgradeToAndCall", + "outputs": [], + "stateMutability": "payable", + "type": "function" + }, + { + "stateMutability": "payable", + "type": "receive" + } + ], + "transactionHash": "0x6202f092efd48101698f59aab594a9ddcfa4ab7cc2088d9d7b547c28077c09c6", + "receipt": { + "to": null, + "from": "0xfdA462548Ce04282f4B6D6619823a7C64Fdc0185", + "contractAddress": "0x07C89CC845D046aEad377DddC61114AA9D920Ac0", + "transactionIndex": 6, + "gasUsed": "849932", + "logsBloom": "0x00000000000000000000000000000000400000000000000000000000000000000000041000000000000000000000000000000000000000000000000000200000000004000000000000000008000002000000000000000000000000000500000000000000020000000010000000000800000000800000000000000010000000000000000000020000100000000000000000000000000080000000000000800000020000000000000000000000000400000000000000000000100000000000000000000022000000000000000000040000000000000400400000000000000020000010000000000000000000000000000000000000000000000800000000000200", + "blockHash": "0x1e5e151a2f688145d388cdcd046df4ef745e31ae636b4b11bacb12b30e7aa2b0", + "transactionHash": "0x6202f092efd48101698f59aab594a9ddcfa4ab7cc2088d9d7b547c28077c09c6", + "logs": [ + { + "transactionIndex": 6, + "blockNumber": 1596326, + "transactionHash": "0x6202f092efd48101698f59aab594a9ddcfa4ab7cc2088d9d7b547c28077c09c6", + "address": "0x07C89CC845D046aEad377DddC61114AA9D920Ac0", + "topics": [ + "0xbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b", + "0x0000000000000000000000002859a4ebcb58c8dd5cac1419c4f63a071b642b20" + ], + "data": "0x", + "logIndex": 18, + "blockHash": "0x1e5e151a2f688145d388cdcd046df4ef745e31ae636b4b11bacb12b30e7aa2b0" + }, + { + "transactionIndex": 6, + "blockNumber": 1596326, + "transactionHash": "0x6202f092efd48101698f59aab594a9ddcfa4ab7cc2088d9d7b547c28077c09c6", + "address": "0x07C89CC845D046aEad377DddC61114AA9D920Ac0", + "topics": [ + "0x8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925", + "0x00000000000000000000000007c89cc845d046aead377dddc61114aa9d920ac0", + "0x0000000000000000000000000000206329b97db379d5e1bf586bbdb969c63274" + ], + "data": "0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", + "logIndex": 19, + "blockHash": "0x1e5e151a2f688145d388cdcd046df4ef745e31ae636b4b11bacb12b30e7aa2b0" + }, + { + "transactionIndex": 6, + "blockNumber": 1596326, + "transactionHash": "0x6202f092efd48101698f59aab594a9ddcfa4ab7cc2088d9d7b547c28077c09c6", + "address": "0x07C89CC845D046aEad377DddC61114AA9D920Ac0", + "topics": [ + "0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000206329b97db379d5e1bf586bbdb969c63274" + ], + "data": "0x0000000000000000000000000000000000000000000000000000000000000000", + "logIndex": 20, + "blockHash": "0x1e5e151a2f688145d388cdcd046df4ef745e31ae636b4b11bacb12b30e7aa2b0" + }, + { + "transactionIndex": 6, + "blockNumber": 1596326, + "transactionHash": "0x6202f092efd48101698f59aab594a9ddcfa4ab7cc2088d9d7b547c28077c09c6", + "address": "0x07C89CC845D046aEad377DddC61114AA9D920Ac0", + "topics": [ + "0x7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb3847402498" + ], + "data": "0x0000000000000000000000000000000000000000000000000000000000000001", + "logIndex": 21, + "blockHash": "0x1e5e151a2f688145d388cdcd046df4ef745e31ae636b4b11bacb12b30e7aa2b0" + }, + { + "transactionIndex": 6, + "blockNumber": 1596326, + "transactionHash": "0x6202f092efd48101698f59aab594a9ddcfa4ab7cc2088d9d7b547c28077c09c6", + "address": "0x07C89CC845D046aEad377DddC61114AA9D920Ac0", + "topics": [ + "0x7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f" + ], + "data": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000001d941ef0d3bba4ad67dbfbcee5262f4cee53a32b", + "logIndex": 22, + "blockHash": "0x1e5e151a2f688145d388cdcd046df4ef745e31ae636b4b11bacb12b30e7aa2b0" + } + ], + "blockNumber": 1596326, + "cumulativeGasUsed": "1735968", + "status": 1, + "byzantium": true + }, + "args": [ + "0x2859a4eBcB58c8Dd5cAC1419C4F63A071b642B20", + "0x1D941EF0D3Bba4ad67DBfBCeE5262F4CEE53A32b", + "0xc9aba0aa00000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000000e0000000000000000000000000b6319cc6c8c27a8f5daf0dd3df91ea35c4720dd7000000000000000000000000840b25c87b626a259ca5ac32124fa752f0230a72000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000164c617965725a65726f204272696467652061675553440000000000000000000000000000000000000000000000000000000000000000000000000000000000084c5a2d6167555344000000000000000000000000000000000000000000000000" + ], + "numDeployments": 1, + "solcInputHash": "871924e0c138825a2736b76def8fef8d", + "metadata": "{\"compiler\":{\"version\":\"0.8.17+commit.8df45f5f\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_logic\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"admin_\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"_data\",\"type\":\"bytes\"}],\"stateMutability\":\"payable\",\"type\":\"constructor\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"previousAdmin\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"newAdmin\",\"type\":\"address\"}],\"name\":\"AdminChanged\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"beacon\",\"type\":\"address\"}],\"name\":\"BeaconUpgraded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"implementation\",\"type\":\"address\"}],\"name\":\"Upgraded\",\"type\":\"event\"},{\"stateMutability\":\"payable\",\"type\":\"fallback\"},{\"inputs\":[],\"name\":\"admin\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"admin_\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newAdmin\",\"type\":\"address\"}],\"name\":\"changeAdmin\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"implementation\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"implementation_\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newImplementation\",\"type\":\"address\"}],\"name\":\"upgradeTo\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newImplementation\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"}],\"name\":\"upgradeToAndCall\",\"outputs\":[],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"stateMutability\":\"payable\",\"type\":\"receive\"}],\"devdoc\":{\"details\":\"This contract implements a proxy that is upgradeable by an admin. It is fully forked from OpenZeppelin `TransparentUpgradeableProxy` To avoid https://medium.com/nomic-labs-blog/malicious-backdoors-in-ethereum-proxies-62629adf3357[proxy selector clashing], which can potentially be used in an attack, this contract uses the https://blog.openzeppelin.com/the-transparent-proxy-pattern/[transparent proxy pattern]. This pattern implies two things that go hand in hand: 1. If any account other than the admin calls the proxy, the call will be forwarded to the implementation, even if that call matches one of the admin functions exposed by the proxy itself. 2. If the admin calls the proxy, it can access the admin functions, but its calls will never be forwarded to the implementation. If the admin tries to call a function on the implementation it will fail with an error that says \\\"admin cannot fallback to proxy target\\\". These properties mean that the admin account can only be used for admin actions like upgrading the proxy or changing the admin, so it's best if it's a dedicated account that is not used for anything else. This will avoid headaches due to sudden errors when trying to call a function from the proxy implementation. Our recommendation is for the dedicated account to be an instance of the {ProxyAdmin} contract. If set up this way, you should think of the `ProxyAdmin` instance as the real administrative interface of your proxy.\",\"kind\":\"dev\",\"methods\":{\"admin()\":{\"details\":\"Returns the current admin. NOTE: Only the admin can call this function. See {ProxyAdmin-getProxyAdmin}. TIP: To get this value clients can read directly from the storage slot shown below (specified by EIP1967) using the https://eth.wiki/json-rpc/API#eth_getstorageat[`eth_getStorageAt`] RPC call. `0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103`\"},\"changeAdmin(address)\":{\"details\":\"Changes the admin of the proxy. Emits an {AdminChanged} event. NOTE: Only the admin can call this function. See {ProxyAdmin-changeProxyAdmin}.\"},\"constructor\":{\"details\":\"Initializes an upgradeable proxy managed by `_admin`, backed by the implementation at `_logic`, and optionally initialized with `_data` as explained in {ERC1967Proxy-constructor}.\"},\"implementation()\":{\"details\":\"Returns the current implementation. NOTE: Only the admin can call this function. See {ProxyAdmin-getProxyImplementation}. TIP: To get this value clients can read directly from the storage slot shown below (specified by EIP1967) using the https://eth.wiki/json-rpc/API#eth_getstorageat[`eth_getStorageAt`] RPC call. `0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc`\"},\"upgradeTo(address)\":{\"details\":\"Upgrade the implementation of the proxy. NOTE: Only the admin can call this function. See {ProxyAdmin-upgrade}.\"},\"upgradeToAndCall(address,bytes)\":{\"details\":\"Upgrade the implementation of the proxy, and then call a function from the new implementation as specified by `data`, which should be an encoded function call. This is useful to initialize new storage variables in the proxied contract. NOTE: Only the admin can call this function. See {ProxyAdmin-upgradeAndCall}.\"}},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/external/TransparentUpgradeableProxy.sol\":\"TransparentUpgradeableProxy\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":1000000},\"remappings\":[]},\"sources\":{\"@openzeppelin/contracts/interfaces/draft-IERC1822.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.5.0) (interfaces/draft-IERC1822.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev ERC1822: Universal Upgradeable Proxy Standard (UUPS) documents a method for upgradeability through a simplified\\n * proxy whose upgrades are fully controlled by the current implementation.\\n */\\ninterface IERC1822Proxiable {\\n /**\\n * @dev Returns the storage slot that the proxiable contract assumes is being used to store the implementation\\n * address.\\n *\\n * IMPORTANT: A proxy pointing at a proxiable contract should not be considered proxiable itself, because this risks\\n * bricking a proxy that upgrades to it, by delegating to itself until out of gas. Thus it is critical that this\\n * function revert if invoked through a proxy.\\n */\\n function proxiableUUID() external view returns (bytes32);\\n}\\n\",\"keccak256\":\"0x1d4afe6cb24200cc4545eed814ecf5847277dfe5d613a1707aad5fceecebcfff\",\"license\":\"MIT\"},\"@openzeppelin/contracts/proxy/ERC1967/ERC1967Proxy.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.7.0) (proxy/ERC1967/ERC1967Proxy.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../Proxy.sol\\\";\\nimport \\\"./ERC1967Upgrade.sol\\\";\\n\\n/**\\n * @dev This contract implements an upgradeable proxy. It is upgradeable because calls are delegated to an\\n * implementation address that can be changed. This address is stored in storage in the location specified by\\n * https://eips.ethereum.org/EIPS/eip-1967[EIP1967], so that it doesn't conflict with the storage layout of the\\n * implementation behind the proxy.\\n */\\ncontract ERC1967Proxy is Proxy, ERC1967Upgrade {\\n /**\\n * @dev Initializes the upgradeable proxy with an initial implementation specified by `_logic`.\\n *\\n * If `_data` is nonempty, it's used as data in a delegate call to `_logic`. This will typically be an encoded\\n * function call, and allows initializing the storage of the proxy like a Solidity constructor.\\n */\\n constructor(address _logic, bytes memory _data) payable {\\n _upgradeToAndCall(_logic, _data, false);\\n }\\n\\n /**\\n * @dev Returns the current implementation address.\\n */\\n function _implementation() internal view virtual override returns (address impl) {\\n return ERC1967Upgrade._getImplementation();\\n }\\n}\\n\",\"keccak256\":\"0xa2b22da3032e50b55f95ec1d13336102d675f341167aa76db571ef7f8bb7975d\",\"license\":\"MIT\"},\"@openzeppelin/contracts/proxy/ERC1967/ERC1967Upgrade.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.5.0) (proxy/ERC1967/ERC1967Upgrade.sol)\\n\\npragma solidity ^0.8.2;\\n\\nimport \\\"../beacon/IBeacon.sol\\\";\\nimport \\\"../../interfaces/draft-IERC1822.sol\\\";\\nimport \\\"../../utils/Address.sol\\\";\\nimport \\\"../../utils/StorageSlot.sol\\\";\\n\\n/**\\n * @dev This abstract contract provides getters and event emitting update functions for\\n * https://eips.ethereum.org/EIPS/eip-1967[EIP1967] slots.\\n *\\n * _Available since v4.1._\\n *\\n * @custom:oz-upgrades-unsafe-allow delegatecall\\n */\\nabstract contract ERC1967Upgrade {\\n // This is the keccak-256 hash of \\\"eip1967.proxy.rollback\\\" subtracted by 1\\n bytes32 private constant _ROLLBACK_SLOT = 0x4910fdfa16fed3260ed0e7147f7cc6da11a60208b5b9406d12a635614ffd9143;\\n\\n /**\\n * @dev Storage slot with the address of the current implementation.\\n * This is the keccak-256 hash of \\\"eip1967.proxy.implementation\\\" subtracted by 1, and is\\n * validated in the constructor.\\n */\\n bytes32 internal constant _IMPLEMENTATION_SLOT = 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc;\\n\\n /**\\n * @dev Emitted when the implementation is upgraded.\\n */\\n event Upgraded(address indexed implementation);\\n\\n /**\\n * @dev Returns the current implementation address.\\n */\\n function _getImplementation() internal view returns (address) {\\n return StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value;\\n }\\n\\n /**\\n * @dev Stores a new address in the EIP1967 implementation slot.\\n */\\n function _setImplementation(address newImplementation) private {\\n require(Address.isContract(newImplementation), \\\"ERC1967: new implementation is not a contract\\\");\\n StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value = newImplementation;\\n }\\n\\n /**\\n * @dev Perform implementation upgrade\\n *\\n * Emits an {Upgraded} event.\\n */\\n function _upgradeTo(address newImplementation) internal {\\n _setImplementation(newImplementation);\\n emit Upgraded(newImplementation);\\n }\\n\\n /**\\n * @dev Perform implementation upgrade with additional setup call.\\n *\\n * Emits an {Upgraded} event.\\n */\\n function _upgradeToAndCall(\\n address newImplementation,\\n bytes memory data,\\n bool forceCall\\n ) internal {\\n _upgradeTo(newImplementation);\\n if (data.length > 0 || forceCall) {\\n Address.functionDelegateCall(newImplementation, data);\\n }\\n }\\n\\n /**\\n * @dev Perform implementation upgrade with security checks for UUPS proxies, and additional setup call.\\n *\\n * Emits an {Upgraded} event.\\n */\\n function _upgradeToAndCallUUPS(\\n address newImplementation,\\n bytes memory data,\\n bool forceCall\\n ) internal {\\n // Upgrades from old implementations will perform a rollback test. This test requires the new\\n // implementation to upgrade back to the old, non-ERC1822 compliant, implementation. Removing\\n // this special case will break upgrade paths from old UUPS implementation to new ones.\\n if (StorageSlot.getBooleanSlot(_ROLLBACK_SLOT).value) {\\n _setImplementation(newImplementation);\\n } else {\\n try IERC1822Proxiable(newImplementation).proxiableUUID() returns (bytes32 slot) {\\n require(slot == _IMPLEMENTATION_SLOT, \\\"ERC1967Upgrade: unsupported proxiableUUID\\\");\\n } catch {\\n revert(\\\"ERC1967Upgrade: new implementation is not UUPS\\\");\\n }\\n _upgradeToAndCall(newImplementation, data, forceCall);\\n }\\n }\\n\\n /**\\n * @dev Storage slot with the admin of the contract.\\n * This is the keccak-256 hash of \\\"eip1967.proxy.admin\\\" subtracted by 1, and is\\n * validated in the constructor.\\n */\\n bytes32 internal constant _ADMIN_SLOT = 0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103;\\n\\n /**\\n * @dev Emitted when the admin account has changed.\\n */\\n event AdminChanged(address previousAdmin, address newAdmin);\\n\\n /**\\n * @dev Returns the current admin.\\n */\\n function _getAdmin() internal view returns (address) {\\n return StorageSlot.getAddressSlot(_ADMIN_SLOT).value;\\n }\\n\\n /**\\n * @dev Stores a new address in the EIP1967 admin slot.\\n */\\n function _setAdmin(address newAdmin) private {\\n require(newAdmin != address(0), \\\"ERC1967: new admin is the zero address\\\");\\n StorageSlot.getAddressSlot(_ADMIN_SLOT).value = newAdmin;\\n }\\n\\n /**\\n * @dev Changes the admin of the proxy.\\n *\\n * Emits an {AdminChanged} event.\\n */\\n function _changeAdmin(address newAdmin) internal {\\n emit AdminChanged(_getAdmin(), newAdmin);\\n _setAdmin(newAdmin);\\n }\\n\\n /**\\n * @dev The storage slot of the UpgradeableBeacon contract which defines the implementation for this proxy.\\n * This is bytes32(uint256(keccak256('eip1967.proxy.beacon')) - 1)) and is validated in the constructor.\\n */\\n bytes32 internal constant _BEACON_SLOT = 0xa3f0ad74e5423aebfd80d3ef4346578335a9a72aeaee59ff6cb3582b35133d50;\\n\\n /**\\n * @dev Emitted when the beacon is upgraded.\\n */\\n event BeaconUpgraded(address indexed beacon);\\n\\n /**\\n * @dev Returns the current beacon.\\n */\\n function _getBeacon() internal view returns (address) {\\n return StorageSlot.getAddressSlot(_BEACON_SLOT).value;\\n }\\n\\n /**\\n * @dev Stores a new beacon in the EIP1967 beacon slot.\\n */\\n function _setBeacon(address newBeacon) private {\\n require(Address.isContract(newBeacon), \\\"ERC1967: new beacon is not a contract\\\");\\n require(\\n Address.isContract(IBeacon(newBeacon).implementation()),\\n \\\"ERC1967: beacon implementation is not a contract\\\"\\n );\\n StorageSlot.getAddressSlot(_BEACON_SLOT).value = newBeacon;\\n }\\n\\n /**\\n * @dev Perform beacon upgrade with additional setup call. Note: This upgrades the address of the beacon, it does\\n * not upgrade the implementation contained in the beacon (see {UpgradeableBeacon-_setImplementation} for that).\\n *\\n * Emits a {BeaconUpgraded} event.\\n */\\n function _upgradeBeaconToAndCall(\\n address newBeacon,\\n bytes memory data,\\n bool forceCall\\n ) internal {\\n _setBeacon(newBeacon);\\n emit BeaconUpgraded(newBeacon);\\n if (data.length > 0 || forceCall) {\\n Address.functionDelegateCall(IBeacon(newBeacon).implementation(), data);\\n }\\n }\\n}\\n\",\"keccak256\":\"0xabf3f59bc0e5423eae45e459dbe92e7052c6983628d39008590edc852a62f94a\",\"license\":\"MIT\"},\"@openzeppelin/contracts/proxy/Proxy.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.6.0) (proxy/Proxy.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev This abstract contract provides a fallback function that delegates all calls to another contract using the EVM\\n * instruction `delegatecall`. We refer to the second contract as the _implementation_ behind the proxy, and it has to\\n * be specified by overriding the virtual {_implementation} function.\\n *\\n * Additionally, delegation to the implementation can be triggered manually through the {_fallback} function, or to a\\n * different contract through the {_delegate} function.\\n *\\n * The success and return data of the delegated call will be returned back to the caller of the proxy.\\n */\\nabstract contract Proxy {\\n /**\\n * @dev Delegates the current call to `implementation`.\\n *\\n * This function does not return to its internal call site, it will return directly to the external caller.\\n */\\n function _delegate(address implementation) internal virtual {\\n assembly {\\n // Copy msg.data. We take full control of memory in this inline assembly\\n // block because it will not return to Solidity code. We overwrite the\\n // Solidity scratch pad at memory position 0.\\n calldatacopy(0, 0, calldatasize())\\n\\n // Call the implementation.\\n // out and outsize are 0 because we don't know the size yet.\\n let result := delegatecall(gas(), implementation, 0, calldatasize(), 0, 0)\\n\\n // Copy the returned data.\\n returndatacopy(0, 0, returndatasize())\\n\\n switch result\\n // delegatecall returns 0 on error.\\n case 0 {\\n revert(0, returndatasize())\\n }\\n default {\\n return(0, returndatasize())\\n }\\n }\\n }\\n\\n /**\\n * @dev This is a virtual function that should be overridden so it returns the address to which the fallback function\\n * and {_fallback} should delegate.\\n */\\n function _implementation() internal view virtual returns (address);\\n\\n /**\\n * @dev Delegates the current call to the address returned by `_implementation()`.\\n *\\n * This function does not return to its internal call site, it will return directly to the external caller.\\n */\\n function _fallback() internal virtual {\\n _beforeFallback();\\n _delegate(_implementation());\\n }\\n\\n /**\\n * @dev Fallback function that delegates calls to the address returned by `_implementation()`. Will run if no other\\n * function in the contract matches the call data.\\n */\\n fallback() external payable virtual {\\n _fallback();\\n }\\n\\n /**\\n * @dev Fallback function that delegates calls to the address returned by `_implementation()`. Will run if call data\\n * is empty.\\n */\\n receive() external payable virtual {\\n _fallback();\\n }\\n\\n /**\\n * @dev Hook that is called before falling back to the implementation. Can happen as part of a manual `_fallback`\\n * call, or as part of the Solidity `fallback` or `receive` functions.\\n *\\n * If overridden should call `super._beforeFallback()`.\\n */\\n function _beforeFallback() internal virtual {}\\n}\\n\",\"keccak256\":\"0xc130fe33f1b2132158531a87734153293f6d07bc263ff4ac90e85da9c82c0e27\",\"license\":\"MIT\"},\"@openzeppelin/contracts/proxy/beacon/IBeacon.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (proxy/beacon/IBeacon.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev This is the interface that {BeaconProxy} expects of its beacon.\\n */\\ninterface IBeacon {\\n /**\\n * @dev Must return an address that can be used as a delegate call target.\\n *\\n * {BeaconProxy} will check that this address is a contract.\\n */\\n function implementation() external view returns (address);\\n}\\n\",\"keccak256\":\"0xd50a3421ac379ccb1be435fa646d66a65c986b4924f0849839f08692f39dde61\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/Address.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.7.0) (utils/Address.sol)\\n\\npragma solidity ^0.8.1;\\n\\n/**\\n * @dev Collection of functions related to the address type\\n */\\nlibrary Address {\\n /**\\n * @dev Returns true if `account` is a contract.\\n *\\n * [IMPORTANT]\\n * ====\\n * It is unsafe to assume that an address for which this function returns\\n * false is an externally-owned account (EOA) and not a contract.\\n *\\n * Among others, `isContract` will return false for the following\\n * types of addresses:\\n *\\n * - an externally-owned account\\n * - a contract in construction\\n * - an address where a contract will be created\\n * - an address where a contract lived, but was destroyed\\n * ====\\n *\\n * [IMPORTANT]\\n * ====\\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\\n *\\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\\n * constructor.\\n * ====\\n */\\n function isContract(address account) internal view returns (bool) {\\n // This method relies on extcodesize/address.code.length, which returns 0\\n // for contracts in construction, since the code is only stored at the end\\n // of the constructor execution.\\n\\n return account.code.length > 0;\\n }\\n\\n /**\\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\\n * `recipient`, forwarding all available gas and reverting on errors.\\n *\\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\\n * imposed by `transfer`, making them unable to receive funds via\\n * `transfer`. {sendValue} removes this limitation.\\n *\\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\\n *\\n * IMPORTANT: because control is transferred to `recipient`, care must be\\n * taken to not create reentrancy vulnerabilities. Consider using\\n * {ReentrancyGuard} or the\\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\\n */\\n function sendValue(address payable recipient, uint256 amount) internal {\\n require(address(this).balance >= amount, \\\"Address: insufficient balance\\\");\\n\\n (bool success, ) = recipient.call{value: amount}(\\\"\\\");\\n require(success, \\\"Address: unable to send value, recipient may have reverted\\\");\\n }\\n\\n /**\\n * @dev Performs a Solidity function call using a low level `call`. A\\n * plain `call` is an unsafe replacement for a function call: use this\\n * function instead.\\n *\\n * If `target` reverts with a revert reason, it is bubbled up by this\\n * function (like regular Solidity function calls).\\n *\\n * Returns the raw returned data. To convert to the expected return value,\\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\\n *\\n * Requirements:\\n *\\n * - `target` must be a contract.\\n * - calling `target` with `data` must not revert.\\n *\\n * _Available since v3.1._\\n */\\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\\n return functionCall(target, data, \\\"Address: low-level call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\\n * `errorMessage` as a fallback revert reason when `target` reverts.\\n *\\n * _Available since v3.1._\\n */\\n function functionCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n return functionCallWithValue(target, data, 0, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but also transferring `value` wei to `target`.\\n *\\n * Requirements:\\n *\\n * - the calling contract must have an ETH balance of at least `value`.\\n * - the called Solidity function must be `payable`.\\n *\\n * _Available since v3.1._\\n */\\n function functionCallWithValue(\\n address target,\\n bytes memory data,\\n uint256 value\\n ) internal returns (bytes memory) {\\n return functionCallWithValue(target, data, value, \\\"Address: low-level call with value failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\\n * with `errorMessage` as a fallback revert reason when `target` reverts.\\n *\\n * _Available since v3.1._\\n */\\n function functionCallWithValue(\\n address target,\\n bytes memory data,\\n uint256 value,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n require(address(this).balance >= value, \\\"Address: insufficient balance for call\\\");\\n require(isContract(target), \\\"Address: call to non-contract\\\");\\n\\n (bool success, bytes memory returndata) = target.call{value: value}(data);\\n return verifyCallResult(success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but performing a static call.\\n *\\n * _Available since v3.3._\\n */\\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\\n return functionStaticCall(target, data, \\\"Address: low-level static call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\\n * but performing a static call.\\n *\\n * _Available since v3.3._\\n */\\n function functionStaticCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal view returns (bytes memory) {\\n require(isContract(target), \\\"Address: static call to non-contract\\\");\\n\\n (bool success, bytes memory returndata) = target.staticcall(data);\\n return verifyCallResult(success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but performing a delegate call.\\n *\\n * _Available since v3.4._\\n */\\n function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {\\n return functionDelegateCall(target, data, \\\"Address: low-level delegate call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\\n * but performing a delegate call.\\n *\\n * _Available since v3.4._\\n */\\n function functionDelegateCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n require(isContract(target), \\\"Address: delegate call to non-contract\\\");\\n\\n (bool success, bytes memory returndata) = target.delegatecall(data);\\n return verifyCallResult(success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the\\n * revert reason using the provided one.\\n *\\n * _Available since v4.3._\\n */\\n function verifyCallResult(\\n bool success,\\n bytes memory returndata,\\n string memory errorMessage\\n ) internal pure returns (bytes memory) {\\n if (success) {\\n return returndata;\\n } else {\\n // Look for revert reason and bubble it up if present\\n if (returndata.length > 0) {\\n // The easiest way to bubble the revert reason is using memory via assembly\\n /// @solidity memory-safe-assembly\\n assembly {\\n let returndata_size := mload(returndata)\\n revert(add(32, returndata), returndata_size)\\n }\\n } else {\\n revert(errorMessage);\\n }\\n }\\n }\\n}\\n\",\"keccak256\":\"0xd6153ce99bcdcce22b124f755e72553295be6abcd63804cfdffceb188b8bef10\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/StorageSlot.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.7.0) (utils/StorageSlot.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Library for reading and writing primitive types to specific storage slots.\\n *\\n * Storage slots are often used to avoid storage conflict when dealing with upgradeable contracts.\\n * This library helps with reading and writing to such slots without the need for inline assembly.\\n *\\n * The functions in this library return Slot structs that contain a `value` member that can be used to read or write.\\n *\\n * Example usage to set ERC1967 implementation slot:\\n * ```\\n * contract ERC1967 {\\n * bytes32 internal constant _IMPLEMENTATION_SLOT = 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc;\\n *\\n * function _getImplementation() internal view returns (address) {\\n * return StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value;\\n * }\\n *\\n * function _setImplementation(address newImplementation) internal {\\n * require(Address.isContract(newImplementation), \\\"ERC1967: new implementation is not a contract\\\");\\n * StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value = newImplementation;\\n * }\\n * }\\n * ```\\n *\\n * _Available since v4.1 for `address`, `bool`, `bytes32`, and `uint256`._\\n */\\nlibrary StorageSlot {\\n struct AddressSlot {\\n address value;\\n }\\n\\n struct BooleanSlot {\\n bool value;\\n }\\n\\n struct Bytes32Slot {\\n bytes32 value;\\n }\\n\\n struct Uint256Slot {\\n uint256 value;\\n }\\n\\n /**\\n * @dev Returns an `AddressSlot` with member `value` located at `slot`.\\n */\\n function getAddressSlot(bytes32 slot) internal pure returns (AddressSlot storage r) {\\n /// @solidity memory-safe-assembly\\n assembly {\\n r.slot := slot\\n }\\n }\\n\\n /**\\n * @dev Returns an `BooleanSlot` with member `value` located at `slot`.\\n */\\n function getBooleanSlot(bytes32 slot) internal pure returns (BooleanSlot storage r) {\\n /// @solidity memory-safe-assembly\\n assembly {\\n r.slot := slot\\n }\\n }\\n\\n /**\\n * @dev Returns an `Bytes32Slot` with member `value` located at `slot`.\\n */\\n function getBytes32Slot(bytes32 slot) internal pure returns (Bytes32Slot storage r) {\\n /// @solidity memory-safe-assembly\\n assembly {\\n r.slot := slot\\n }\\n }\\n\\n /**\\n * @dev Returns an `Uint256Slot` with member `value` located at `slot`.\\n */\\n function getUint256Slot(bytes32 slot) internal pure returns (Uint256Slot storage r) {\\n /// @solidity memory-safe-assembly\\n assembly {\\n r.slot := slot\\n }\\n }\\n}\\n\",\"keccak256\":\"0xd5c50c54bf02740ebd122ff06832546cb5fa84486d52695a9ccfd11666e0c81d\",\"license\":\"MIT\"},\"contracts/external/TransparentUpgradeableProxy.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-3.0\\n\\npragma solidity ^0.8.12;\\n\\nimport \\\"@openzeppelin/contracts/proxy/ERC1967/ERC1967Proxy.sol\\\";\\n\\n/**\\n * @dev This contract implements a proxy that is upgradeable by an admin. It is fully forked from OpenZeppelin\\n * `TransparentUpgradeableProxy`\\n *\\n * To avoid https://medium.com/nomic-labs-blog/malicious-backdoors-in-ethereum-proxies-62629adf3357[proxy selector\\n * clashing], which can potentially be used in an attack, this contract uses the\\n * https://blog.openzeppelin.com/the-transparent-proxy-pattern/[transparent proxy pattern]. This pattern implies two\\n * things that go hand in hand:\\n *\\n * 1. If any account other than the admin calls the proxy, the call will be forwarded to the implementation, even if\\n * that call matches one of the admin functions exposed by the proxy itself.\\n * 2. If the admin calls the proxy, it can access the admin functions, but its calls will never be forwarded to the\\n * implementation. If the admin tries to call a function on the implementation it will fail with an error that says\\n * \\\"admin cannot fallback to proxy target\\\".\\n *\\n * These properties mean that the admin account can only be used for admin actions like upgrading the proxy or changing\\n * the admin, so it's best if it's a dedicated account that is not used for anything else. This will avoid headaches due\\n * to sudden errors when trying to call a function from the proxy implementation.\\n *\\n * Our recommendation is for the dedicated account to be an instance of the {ProxyAdmin} contract. If set up this way,\\n * you should think of the `ProxyAdmin` instance as the real administrative interface of your proxy.\\n */\\ncontract TransparentUpgradeableProxy is ERC1967Proxy {\\n /**\\n * @dev Initializes an upgradeable proxy managed by `_admin`, backed by the implementation at `_logic`, and\\n * optionally initialized with `_data` as explained in {ERC1967Proxy-constructor}.\\n */\\n constructor(address _logic, address admin_, bytes memory _data) payable ERC1967Proxy(_logic, _data) {\\n assert(_ADMIN_SLOT == bytes32(uint256(keccak256(\\\"eip1967.proxy.admin\\\")) - 1));\\n _changeAdmin(admin_);\\n }\\n\\n /**\\n * @dev Modifier used internally that will delegate the call to the implementation unless the sender is the admin.\\n */\\n modifier ifAdmin() {\\n if (msg.sender == _getAdmin()) {\\n _;\\n } else {\\n _fallback();\\n }\\n }\\n\\n /**\\n * @dev Returns the current admin.\\n *\\n * NOTE: Only the admin can call this function. See {ProxyAdmin-getProxyAdmin}.\\n *\\n * TIP: To get this value clients can read directly from the storage slot shown below (specified by EIP1967) using the\\n * https://eth.wiki/json-rpc/API#eth_getstorageat[`eth_getStorageAt`] RPC call.\\n * `0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103`\\n */\\n function admin() external ifAdmin returns (address admin_) {\\n admin_ = _getAdmin();\\n }\\n\\n /**\\n * @dev Returns the current implementation.\\n *\\n * NOTE: Only the admin can call this function. See {ProxyAdmin-getProxyImplementation}.\\n *\\n * TIP: To get this value clients can read directly from the storage slot shown below (specified by EIP1967) using the\\n * https://eth.wiki/json-rpc/API#eth_getstorageat[`eth_getStorageAt`] RPC call.\\n * `0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc`\\n */\\n function implementation() external ifAdmin returns (address implementation_) {\\n implementation_ = _implementation();\\n }\\n\\n /**\\n * @dev Changes the admin of the proxy.\\n *\\n * Emits an {AdminChanged} event.\\n *\\n * NOTE: Only the admin can call this function. See {ProxyAdmin-changeProxyAdmin}.\\n */\\n function changeAdmin(address newAdmin) external virtual ifAdmin {\\n _changeAdmin(newAdmin);\\n }\\n\\n /**\\n * @dev Upgrade the implementation of the proxy.\\n *\\n * NOTE: Only the admin can call this function. See {ProxyAdmin-upgrade}.\\n */\\n function upgradeTo(address newImplementation) external ifAdmin {\\n _upgradeToAndCall(newImplementation, bytes(\\\"\\\"), false);\\n }\\n\\n /**\\n * @dev Upgrade the implementation of the proxy, and then call a function from the new implementation as specified\\n * by `data`, which should be an encoded function call. This is useful to initialize new storage variables in the\\n * proxied contract.\\n *\\n * NOTE: Only the admin can call this function. See {ProxyAdmin-upgradeAndCall}.\\n */\\n function upgradeToAndCall(address newImplementation, bytes calldata data) external payable ifAdmin {\\n _upgradeToAndCall(newImplementation, data, true);\\n }\\n\\n /**\\n * @dev Returns the current admin.\\n */\\n function _admin() internal view virtual returns (address) {\\n return _getAdmin();\\n }\\n\\n /**\\n * @dev Makes sure the admin cannot access the fallback function. See {Proxy-_beforeFallback}.\\n */\\n function _beforeFallback() internal virtual override {\\n require(msg.sender != _getAdmin(), \\\"TransparentUpgradeableProxy: admin cannot fallback to proxy target\\\");\\n super._beforeFallback();\\n }\\n}\\n\",\"keccak256\":\"0x93a67a0f612ea3ff2a76315e138a6a88267270a1379d3cc7be52845fbbe611e2\",\"license\":\"GPL-3.0\"}},\"version\":1}", + "bytecode": "0x6080604052604051620010bb380380620010bb8339810160408190526200002691620004d8565b828162000036828260006200009a565b5062000066905060017fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6104620005b8565b6000805160206200107483398151915214620000865762000086620005da565b6200009182620000d7565b50505062000643565b620000a58362000132565b600082511180620000b35750805b15620000d257620000d083836200017460201b6200028c1760201c565b505b505050565b7f7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f62000102620001a5565b604080516001600160a01b03928316815291841660208301520160405180910390a16200012f81620001de565b50565b6200013d8162000293565b6040516001600160a01b038216907fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b90600090a250565b60606200019c8383604051806060016040528060278152602001620010946027913962000347565b90505b92915050565b6000620001cf6000805160206200107483398151915260001b6200042f60201b6200022e1760201c565b546001600160a01b0316919050565b6001600160a01b038116620002495760405162461bcd60e51b815260206004820152602660248201527f455243313936373a206e65772061646d696e20697320746865207a65726f206160448201526564647265737360d01b60648201526084015b60405180910390fd5b80620002726000805160206200107483398151915260001b6200042f60201b6200022e1760201c565b80546001600160a01b0319166001600160a01b039290921691909117905550565b620002a9816200043260201b620002b81760201c565b6200030d5760405162461bcd60e51b815260206004820152602d60248201527f455243313936373a206e657720696d706c656d656e746174696f6e206973206e60448201526c1bdd08184818dbdb9d1c9858dd609a1b606482015260840162000240565b80620002727f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc60001b6200042f60201b6200022e1760201c565b60606001600160a01b0384163b620003b15760405162461bcd60e51b815260206004820152602660248201527f416464726573733a2064656c65676174652063616c6c20746f206e6f6e2d636f6044820152651b9d1c9858dd60d21b606482015260840162000240565b600080856001600160a01b031685604051620003ce9190620005f0565b600060405180830381855af49150503d80600081146200040b576040519150601f19603f3d011682016040523d82523d6000602084013e62000410565b606091505b5090925090506200042382828662000441565b925050505b9392505050565b90565b6001600160a01b03163b151590565b606083156200045257508162000428565b825115620004635782518084602001fd5b8160405162461bcd60e51b81526004016200024091906200060e565b80516001600160a01b03811681146200049757600080fd5b919050565b634e487b7160e01b600052604160045260246000fd5b60005b83811015620004cf578181015183820152602001620004b5565b50506000910152565b600080600060608486031215620004ee57600080fd5b620004f9846200047f565b925062000509602085016200047f565b60408501519092506001600160401b03808211156200052757600080fd5b818601915086601f8301126200053c57600080fd5b8151818111156200055157620005516200049c565b604051601f8201601f19908116603f011681019083821181831017156200057c576200057c6200049c565b816040528281528960208487010111156200059657600080fd5b620005a9836020830160208801620004b2565b80955050505050509250925092565b818103818111156200019f57634e487b7160e01b600052601160045260246000fd5b634e487b7160e01b600052600160045260246000fd5b6000825162000604818460208701620004b2565b9190910192915050565b60208152600082518060208401526200062f816040850160208701620004b2565b601f01601f19169190910160400192915050565b610a2180620006536000396000f3fe60806040526004361061005e5760003560e01c80635c60da1b116100435780635c60da1b146100a85780638f283970146100e6578063f851a440146101065761006d565b80633659cfe6146100755780634f1ef286146100955761006d565b3661006d5761006b61011b565b005b61006b61011b565b34801561008157600080fd5b5061006b610090366004610895565b610135565b61006b6100a33660046108b0565b61017f565b3480156100b457600080fd5b506100bd6101f3565b60405173ffffffffffffffffffffffffffffffffffffffff909116815260200160405180910390f35b3480156100f257600080fd5b5061006b610101366004610895565b610231565b34801561011257600080fd5b506100bd61025e565b6101236102d4565b61013361012e6103ab565b6103b5565b565b61013d6103d9565b73ffffffffffffffffffffffffffffffffffffffff1633036101775761017481604051806020016040528060008152506000610419565b50565b61017461011b565b6101876103d9565b73ffffffffffffffffffffffffffffffffffffffff1633036101eb576101e68383838080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525060019250610419915050565b505050565b6101e661011b565b60006101fd6103d9565b73ffffffffffffffffffffffffffffffffffffffff163303610226576102216103ab565b905090565b61022e61011b565b90565b6102396103d9565b73ffffffffffffffffffffffffffffffffffffffff1633036101775761017481610444565b60006102686103d9565b73ffffffffffffffffffffffffffffffffffffffff163303610226576102216103d9565b60606102b183836040518060600160405280602781526020016109c5602791396104a5565b9392505050565b73ffffffffffffffffffffffffffffffffffffffff163b151590565b6102dc6103d9565b73ffffffffffffffffffffffffffffffffffffffff163303610133576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604260248201527f5472616e73706172656e745570677261646561626c6550726f78793a2061646d60448201527f696e2063616e6e6f742066616c6c6261636b20746f2070726f7879207461726760648201527f6574000000000000000000000000000000000000000000000000000000000000608482015260a4015b60405180910390fd5b60006102216105cd565b3660008037600080366000845af43d6000803e8080156103d4573d6000f35b3d6000fd5b60007fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035b5473ffffffffffffffffffffffffffffffffffffffff16919050565b610422836105f5565b60008251118061042f5750805b156101e65761043e838361028c565b50505050565b7f7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f61046d6103d9565b6040805173ffffffffffffffffffffffffffffffffffffffff928316815291841660208301520160405180910390a161017481610642565b606073ffffffffffffffffffffffffffffffffffffffff84163b61054b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f416464726573733a2064656c65676174652063616c6c20746f206e6f6e2d636f60448201527f6e7472616374000000000000000000000000000000000000000000000000000060648201526084016103a2565b6000808573ffffffffffffffffffffffffffffffffffffffff16856040516105739190610957565b600060405180830381855af49150503d80600081146105ae576040519150601f19603f3d011682016040523d82523d6000602084013e6105b3565b606091505b50915091506105c382828661074e565b9695505050505050565b60007f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc6103fd565b6105fe816107a1565b60405173ffffffffffffffffffffffffffffffffffffffff8216907fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b90600090a250565b73ffffffffffffffffffffffffffffffffffffffff81166106e5576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f455243313936373a206e65772061646d696e20697320746865207a65726f206160448201527f646472657373000000000000000000000000000000000000000000000000000060648201526084016103a2565b807fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035b80547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff9290921691909117905550565b6060831561075d5750816102b1565b82511561076d5782518084602001fd5b816040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016103a29190610973565b73ffffffffffffffffffffffffffffffffffffffff81163b610845576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602d60248201527f455243313936373a206e657720696d706c656d656e746174696f6e206973206e60448201527f6f74206120636f6e74726163740000000000000000000000000000000000000060648201526084016103a2565b807f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc610708565b803573ffffffffffffffffffffffffffffffffffffffff8116811461089057600080fd5b919050565b6000602082840312156108a757600080fd5b6102b18261086c565b6000806000604084860312156108c557600080fd5b6108ce8461086c565b9250602084013567ffffffffffffffff808211156108eb57600080fd5b818601915086601f8301126108ff57600080fd5b81358181111561090e57600080fd5b87602082850101111561092057600080fd5b6020830194508093505050509250925092565b60005b8381101561094e578181015183820152602001610936565b50506000910152565b60008251610969818460208701610933565b9190910192915050565b6020815260008251806020840152610992816040850160208701610933565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016919091016040019291505056fe416464726573733a206c6f772d6c6576656c2064656c65676174652063616c6c206661696c6564a2646970667358221220e96638b07fb1675d93a95c49e417bc8111448b23a59918698cdcd8fd488dd7cf64736f6c63430008110033b53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103416464726573733a206c6f772d6c6576656c2064656c65676174652063616c6c206661696c6564", + "deployedBytecode": "0x60806040526004361061005e5760003560e01c80635c60da1b116100435780635c60da1b146100a85780638f283970146100e6578063f851a440146101065761006d565b80633659cfe6146100755780634f1ef286146100955761006d565b3661006d5761006b61011b565b005b61006b61011b565b34801561008157600080fd5b5061006b610090366004610895565b610135565b61006b6100a33660046108b0565b61017f565b3480156100b457600080fd5b506100bd6101f3565b60405173ffffffffffffffffffffffffffffffffffffffff909116815260200160405180910390f35b3480156100f257600080fd5b5061006b610101366004610895565b610231565b34801561011257600080fd5b506100bd61025e565b6101236102d4565b61013361012e6103ab565b6103b5565b565b61013d6103d9565b73ffffffffffffffffffffffffffffffffffffffff1633036101775761017481604051806020016040528060008152506000610419565b50565b61017461011b565b6101876103d9565b73ffffffffffffffffffffffffffffffffffffffff1633036101eb576101e68383838080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525060019250610419915050565b505050565b6101e661011b565b60006101fd6103d9565b73ffffffffffffffffffffffffffffffffffffffff163303610226576102216103ab565b905090565b61022e61011b565b90565b6102396103d9565b73ffffffffffffffffffffffffffffffffffffffff1633036101775761017481610444565b60006102686103d9565b73ffffffffffffffffffffffffffffffffffffffff163303610226576102216103d9565b60606102b183836040518060600160405280602781526020016109c5602791396104a5565b9392505050565b73ffffffffffffffffffffffffffffffffffffffff163b151590565b6102dc6103d9565b73ffffffffffffffffffffffffffffffffffffffff163303610133576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604260248201527f5472616e73706172656e745570677261646561626c6550726f78793a2061646d60448201527f696e2063616e6e6f742066616c6c6261636b20746f2070726f7879207461726760648201527f6574000000000000000000000000000000000000000000000000000000000000608482015260a4015b60405180910390fd5b60006102216105cd565b3660008037600080366000845af43d6000803e8080156103d4573d6000f35b3d6000fd5b60007fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035b5473ffffffffffffffffffffffffffffffffffffffff16919050565b610422836105f5565b60008251118061042f5750805b156101e65761043e838361028c565b50505050565b7f7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f61046d6103d9565b6040805173ffffffffffffffffffffffffffffffffffffffff928316815291841660208301520160405180910390a161017481610642565b606073ffffffffffffffffffffffffffffffffffffffff84163b61054b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f416464726573733a2064656c65676174652063616c6c20746f206e6f6e2d636f60448201527f6e7472616374000000000000000000000000000000000000000000000000000060648201526084016103a2565b6000808573ffffffffffffffffffffffffffffffffffffffff16856040516105739190610957565b600060405180830381855af49150503d80600081146105ae576040519150601f19603f3d011682016040523d82523d6000602084013e6105b3565b606091505b50915091506105c382828661074e565b9695505050505050565b60007f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc6103fd565b6105fe816107a1565b60405173ffffffffffffffffffffffffffffffffffffffff8216907fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b90600090a250565b73ffffffffffffffffffffffffffffffffffffffff81166106e5576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f455243313936373a206e65772061646d696e20697320746865207a65726f206160448201527f646472657373000000000000000000000000000000000000000000000000000060648201526084016103a2565b807fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035b80547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff9290921691909117905550565b6060831561075d5750816102b1565b82511561076d5782518084602001fd5b816040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016103a29190610973565b73ffffffffffffffffffffffffffffffffffffffff81163b610845576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602d60248201527f455243313936373a206e657720696d706c656d656e746174696f6e206973206e60448201527f6f74206120636f6e74726163740000000000000000000000000000000000000060648201526084016103a2565b807f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc610708565b803573ffffffffffffffffffffffffffffffffffffffff8116811461089057600080fd5b919050565b6000602082840312156108a757600080fd5b6102b18261086c565b6000806000604084860312156108c557600080fd5b6108ce8461086c565b9250602084013567ffffffffffffffff808211156108eb57600080fd5b818601915086601f8301126108ff57600080fd5b81358181111561090e57600080fd5b87602082850101111561092057600080fd5b6020830194508093505050509250925092565b60005b8381101561094e578181015183820152602001610936565b50506000910152565b60008251610969818460208701610933565b9190910192915050565b6020815260008251806020840152610992816040850160208701610933565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016919091016040019291505056fe416464726573733a206c6f772d6c6576656c2064656c65676174652063616c6c206661696c6564a2646970667358221220e96638b07fb1675d93a95c49e417bc8111448b23a59918698cdcd8fd488dd7cf64736f6c63430008110033", + "devdoc": { + "details": "This contract implements a proxy that is upgradeable by an admin. It is fully forked from OpenZeppelin `TransparentUpgradeableProxy` To avoid https://medium.com/nomic-labs-blog/malicious-backdoors-in-ethereum-proxies-62629adf3357[proxy selector clashing], which can potentially be used in an attack, this contract uses the https://blog.openzeppelin.com/the-transparent-proxy-pattern/[transparent proxy pattern]. This pattern implies two things that go hand in hand: 1. If any account other than the admin calls the proxy, the call will be forwarded to the implementation, even if that call matches one of the admin functions exposed by the proxy itself. 2. If the admin calls the proxy, it can access the admin functions, but its calls will never be forwarded to the implementation. If the admin tries to call a function on the implementation it will fail with an error that says \"admin cannot fallback to proxy target\". These properties mean that the admin account can only be used for admin actions like upgrading the proxy or changing the admin, so it's best if it's a dedicated account that is not used for anything else. This will avoid headaches due to sudden errors when trying to call a function from the proxy implementation. Our recommendation is for the dedicated account to be an instance of the {ProxyAdmin} contract. If set up this way, you should think of the `ProxyAdmin` instance as the real administrative interface of your proxy.", + "kind": "dev", + "methods": { + "admin()": { + "details": "Returns the current admin. NOTE: Only the admin can call this function. See {ProxyAdmin-getProxyAdmin}. TIP: To get this value clients can read directly from the storage slot shown below (specified by EIP1967) using the https://eth.wiki/json-rpc/API#eth_getstorageat[`eth_getStorageAt`] RPC call. `0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103`" + }, + "changeAdmin(address)": { + "details": "Changes the admin of the proxy. Emits an {AdminChanged} event. NOTE: Only the admin can call this function. See {ProxyAdmin-changeProxyAdmin}." + }, + "constructor": { + "details": "Initializes an upgradeable proxy managed by `_admin`, backed by the implementation at `_logic`, and optionally initialized with `_data` as explained in {ERC1967Proxy-constructor}." + }, + "implementation()": { + "details": "Returns the current implementation. NOTE: Only the admin can call this function. See {ProxyAdmin-getProxyImplementation}. TIP: To get this value clients can read directly from the storage slot shown below (specified by EIP1967) using the https://eth.wiki/json-rpc/API#eth_getstorageat[`eth_getStorageAt`] RPC call. `0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc`" + }, + "upgradeTo(address)": { + "details": "Upgrade the implementation of the proxy. NOTE: Only the admin can call this function. See {ProxyAdmin-upgrade}." + }, + "upgradeToAndCall(address,bytes)": { + "details": "Upgrade the implementation of the proxy, and then call a function from the new implementation as specified by `data`, which should be an encoded function call. This is useful to initialize new storage variables in the proxied contract. NOTE: Only the admin can call this function. See {ProxyAdmin-upgradeAndCall}." + } + }, + "version": 1 + }, + "userdoc": { + "kind": "user", + "methods": {}, + "version": 1 + }, + "storageLayout": { + "storage": [], + "types": null + } +} \ No newline at end of file diff --git a/deployments/linea/Treasury_USD.json b/deployments/linea/Treasury_USD.json new file mode 100644 index 00000000..7a82d79b --- /dev/null +++ b/deployments/linea/Treasury_USD.json @@ -0,0 +1,247 @@ +{ + "address": "0x840b25c87B626a259CA5AC32124fA752F0230a72", + "abi": [ + { + "inputs": [ + { + "internalType": "address", + "name": "_logic", + "type": "address" + }, + { + "internalType": "address", + "name": "admin_", + "type": "address" + }, + { + "internalType": "bytes", + "name": "_data", + "type": "bytes" + } + ], + "stateMutability": "payable", + "type": "constructor" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "previousAdmin", + "type": "address" + }, + { + "indexed": false, + "internalType": "address", + "name": "newAdmin", + "type": "address" + } + ], + "name": "AdminChanged", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "beacon", + "type": "address" + } + ], + "name": "BeaconUpgraded", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "implementation", + "type": "address" + } + ], + "name": "Upgraded", + "type": "event" + }, + { + "stateMutability": "payable", + "type": "fallback" + }, + { + "inputs": [], + "name": "admin", + "outputs": [ + { + "internalType": "address", + "name": "admin_", + "type": "address" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "newAdmin", + "type": "address" + } + ], + "name": "changeAdmin", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "implementation", + "outputs": [ + { + "internalType": "address", + "name": "implementation_", + "type": "address" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "newImplementation", + "type": "address" + } + ], + "name": "upgradeTo", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "newImplementation", + "type": "address" + }, + { + "internalType": "bytes", + "name": "data", + "type": "bytes" + } + ], + "name": "upgradeToAndCall", + "outputs": [], + "stateMutability": "payable", + "type": "function" + }, + { + "stateMutability": "payable", + "type": "receive" + } + ], + "transactionHash": "0x89ecafe007331fc0f82586ae72158b6931b0cd92b25d370998a4c9f0a41efd1e", + "receipt": { + "to": null, + "from": "0xfdA462548Ce04282f4B6D6619823a7C64Fdc0185", + "contractAddress": "0x840b25c87B626a259CA5AC32124fA752F0230a72", + "transactionIndex": 4, + "gasUsed": "736150", + "logsBloom": "0x00000000000000000000000000000000400000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000004000000800000000000000000000000000000000000000000000000000000000000000000000080000000000000800000000000400000000000000000000420000000000000001000000000000000000000000020000000000000000000040000000000000400000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "blockHash": "0xfbff0d4c45fbaa3a9af2be4e6144cf271047ffbd3f6b045eedc6e628b430a639", + "transactionHash": "0x89ecafe007331fc0f82586ae72158b6931b0cd92b25d370998a4c9f0a41efd1e", + "logs": [ + { + "transactionIndex": 4, + "blockNumber": 1596324, + "transactionHash": "0x89ecafe007331fc0f82586ae72158b6931b0cd92b25d370998a4c9f0a41efd1e", + "address": "0x840b25c87B626a259CA5AC32124fA752F0230a72", + "topics": [ + "0xbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b", + "0x000000000000000000000000fa5ed56a203466cbbc2430a43c66b9d8723528e7" + ], + "data": "0x", + "logIndex": 12, + "blockHash": "0xfbff0d4c45fbaa3a9af2be4e6144cf271047ffbd3f6b045eedc6e628b430a639" + }, + { + "transactionIndex": 4, + "blockNumber": 1596324, + "transactionHash": "0x89ecafe007331fc0f82586ae72158b6931b0cd92b25d370998a4c9f0a41efd1e", + "address": "0x840b25c87B626a259CA5AC32124fA752F0230a72", + "topics": [ + "0x7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb3847402498" + ], + "data": "0x0000000000000000000000000000000000000000000000000000000000000001", + "logIndex": 13, + "blockHash": "0xfbff0d4c45fbaa3a9af2be4e6144cf271047ffbd3f6b045eedc6e628b430a639" + }, + { + "transactionIndex": 4, + "blockNumber": 1596324, + "transactionHash": "0x89ecafe007331fc0f82586ae72158b6931b0cd92b25d370998a4c9f0a41efd1e", + "address": "0x840b25c87B626a259CA5AC32124fA752F0230a72", + "topics": [ + "0x7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f" + ], + "data": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000001d941ef0d3bba4ad67dbfbcee5262f4cee53a32b", + "logIndex": 14, + "blockHash": "0xfbff0d4c45fbaa3a9af2be4e6144cf271047ffbd3f6b045eedc6e628b430a639" + } + ], + "blockNumber": 1596324, + "cumulativeGasUsed": "1367807", + "status": 1, + "byzantium": true + }, + "args": [ + "0xFA5Ed56A203466CbBC2430a43c66b9D8723528E7", + "0x1D941EF0D3Bba4ad67DBfBCeE5262F4CEE53A32b", + "0x485cc95500000000000000000000000016cd38b1b54e7abf307cb2697e2d9321e843d5aa0000000000000000000000000000206329b97db379d5e1bf586bbdb969c63274" + ], + "numDeployments": 1, + "solcInputHash": "871924e0c138825a2736b76def8fef8d", + "metadata": "{\"compiler\":{\"version\":\"0.8.17+commit.8df45f5f\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_logic\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"admin_\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"_data\",\"type\":\"bytes\"}],\"stateMutability\":\"payable\",\"type\":\"constructor\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"previousAdmin\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"newAdmin\",\"type\":\"address\"}],\"name\":\"AdminChanged\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"beacon\",\"type\":\"address\"}],\"name\":\"BeaconUpgraded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"implementation\",\"type\":\"address\"}],\"name\":\"Upgraded\",\"type\":\"event\"},{\"stateMutability\":\"payable\",\"type\":\"fallback\"},{\"inputs\":[],\"name\":\"admin\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"admin_\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newAdmin\",\"type\":\"address\"}],\"name\":\"changeAdmin\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"implementation\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"implementation_\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newImplementation\",\"type\":\"address\"}],\"name\":\"upgradeTo\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newImplementation\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"}],\"name\":\"upgradeToAndCall\",\"outputs\":[],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"stateMutability\":\"payable\",\"type\":\"receive\"}],\"devdoc\":{\"details\":\"This contract implements a proxy that is upgradeable by an admin. It is fully forked from OpenZeppelin `TransparentUpgradeableProxy` To avoid https://medium.com/nomic-labs-blog/malicious-backdoors-in-ethereum-proxies-62629adf3357[proxy selector clashing], which can potentially be used in an attack, this contract uses the https://blog.openzeppelin.com/the-transparent-proxy-pattern/[transparent proxy pattern]. This pattern implies two things that go hand in hand: 1. If any account other than the admin calls the proxy, the call will be forwarded to the implementation, even if that call matches one of the admin functions exposed by the proxy itself. 2. If the admin calls the proxy, it can access the admin functions, but its calls will never be forwarded to the implementation. If the admin tries to call a function on the implementation it will fail with an error that says \\\"admin cannot fallback to proxy target\\\". These properties mean that the admin account can only be used for admin actions like upgrading the proxy or changing the admin, so it's best if it's a dedicated account that is not used for anything else. This will avoid headaches due to sudden errors when trying to call a function from the proxy implementation. Our recommendation is for the dedicated account to be an instance of the {ProxyAdmin} contract. If set up this way, you should think of the `ProxyAdmin` instance as the real administrative interface of your proxy.\",\"kind\":\"dev\",\"methods\":{\"admin()\":{\"details\":\"Returns the current admin. NOTE: Only the admin can call this function. See {ProxyAdmin-getProxyAdmin}. TIP: To get this value clients can read directly from the storage slot shown below (specified by EIP1967) using the https://eth.wiki/json-rpc/API#eth_getstorageat[`eth_getStorageAt`] RPC call. `0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103`\"},\"changeAdmin(address)\":{\"details\":\"Changes the admin of the proxy. Emits an {AdminChanged} event. NOTE: Only the admin can call this function. See {ProxyAdmin-changeProxyAdmin}.\"},\"constructor\":{\"details\":\"Initializes an upgradeable proxy managed by `_admin`, backed by the implementation at `_logic`, and optionally initialized with `_data` as explained in {ERC1967Proxy-constructor}.\"},\"implementation()\":{\"details\":\"Returns the current implementation. NOTE: Only the admin can call this function. See {ProxyAdmin-getProxyImplementation}. TIP: To get this value clients can read directly from the storage slot shown below (specified by EIP1967) using the https://eth.wiki/json-rpc/API#eth_getstorageat[`eth_getStorageAt`] RPC call. `0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc`\"},\"upgradeTo(address)\":{\"details\":\"Upgrade the implementation of the proxy. NOTE: Only the admin can call this function. See {ProxyAdmin-upgrade}.\"},\"upgradeToAndCall(address,bytes)\":{\"details\":\"Upgrade the implementation of the proxy, and then call a function from the new implementation as specified by `data`, which should be an encoded function call. This is useful to initialize new storage variables in the proxied contract. NOTE: Only the admin can call this function. See {ProxyAdmin-upgradeAndCall}.\"}},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/external/TransparentUpgradeableProxy.sol\":\"TransparentUpgradeableProxy\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":1000000},\"remappings\":[]},\"sources\":{\"@openzeppelin/contracts/interfaces/draft-IERC1822.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.5.0) (interfaces/draft-IERC1822.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev ERC1822: Universal Upgradeable Proxy Standard (UUPS) documents a method for upgradeability through a simplified\\n * proxy whose upgrades are fully controlled by the current implementation.\\n */\\ninterface IERC1822Proxiable {\\n /**\\n * @dev Returns the storage slot that the proxiable contract assumes is being used to store the implementation\\n * address.\\n *\\n * IMPORTANT: A proxy pointing at a proxiable contract should not be considered proxiable itself, because this risks\\n * bricking a proxy that upgrades to it, by delegating to itself until out of gas. Thus it is critical that this\\n * function revert if invoked through a proxy.\\n */\\n function proxiableUUID() external view returns (bytes32);\\n}\\n\",\"keccak256\":\"0x1d4afe6cb24200cc4545eed814ecf5847277dfe5d613a1707aad5fceecebcfff\",\"license\":\"MIT\"},\"@openzeppelin/contracts/proxy/ERC1967/ERC1967Proxy.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.7.0) (proxy/ERC1967/ERC1967Proxy.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../Proxy.sol\\\";\\nimport \\\"./ERC1967Upgrade.sol\\\";\\n\\n/**\\n * @dev This contract implements an upgradeable proxy. It is upgradeable because calls are delegated to an\\n * implementation address that can be changed. This address is stored in storage in the location specified by\\n * https://eips.ethereum.org/EIPS/eip-1967[EIP1967], so that it doesn't conflict with the storage layout of the\\n * implementation behind the proxy.\\n */\\ncontract ERC1967Proxy is Proxy, ERC1967Upgrade {\\n /**\\n * @dev Initializes the upgradeable proxy with an initial implementation specified by `_logic`.\\n *\\n * If `_data` is nonempty, it's used as data in a delegate call to `_logic`. This will typically be an encoded\\n * function call, and allows initializing the storage of the proxy like a Solidity constructor.\\n */\\n constructor(address _logic, bytes memory _data) payable {\\n _upgradeToAndCall(_logic, _data, false);\\n }\\n\\n /**\\n * @dev Returns the current implementation address.\\n */\\n function _implementation() internal view virtual override returns (address impl) {\\n return ERC1967Upgrade._getImplementation();\\n }\\n}\\n\",\"keccak256\":\"0xa2b22da3032e50b55f95ec1d13336102d675f341167aa76db571ef7f8bb7975d\",\"license\":\"MIT\"},\"@openzeppelin/contracts/proxy/ERC1967/ERC1967Upgrade.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.5.0) (proxy/ERC1967/ERC1967Upgrade.sol)\\n\\npragma solidity ^0.8.2;\\n\\nimport \\\"../beacon/IBeacon.sol\\\";\\nimport \\\"../../interfaces/draft-IERC1822.sol\\\";\\nimport \\\"../../utils/Address.sol\\\";\\nimport \\\"../../utils/StorageSlot.sol\\\";\\n\\n/**\\n * @dev This abstract contract provides getters and event emitting update functions for\\n * https://eips.ethereum.org/EIPS/eip-1967[EIP1967] slots.\\n *\\n * _Available since v4.1._\\n *\\n * @custom:oz-upgrades-unsafe-allow delegatecall\\n */\\nabstract contract ERC1967Upgrade {\\n // This is the keccak-256 hash of \\\"eip1967.proxy.rollback\\\" subtracted by 1\\n bytes32 private constant _ROLLBACK_SLOT = 0x4910fdfa16fed3260ed0e7147f7cc6da11a60208b5b9406d12a635614ffd9143;\\n\\n /**\\n * @dev Storage slot with the address of the current implementation.\\n * This is the keccak-256 hash of \\\"eip1967.proxy.implementation\\\" subtracted by 1, and is\\n * validated in the constructor.\\n */\\n bytes32 internal constant _IMPLEMENTATION_SLOT = 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc;\\n\\n /**\\n * @dev Emitted when the implementation is upgraded.\\n */\\n event Upgraded(address indexed implementation);\\n\\n /**\\n * @dev Returns the current implementation address.\\n */\\n function _getImplementation() internal view returns (address) {\\n return StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value;\\n }\\n\\n /**\\n * @dev Stores a new address in the EIP1967 implementation slot.\\n */\\n function _setImplementation(address newImplementation) private {\\n require(Address.isContract(newImplementation), \\\"ERC1967: new implementation is not a contract\\\");\\n StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value = newImplementation;\\n }\\n\\n /**\\n * @dev Perform implementation upgrade\\n *\\n * Emits an {Upgraded} event.\\n */\\n function _upgradeTo(address newImplementation) internal {\\n _setImplementation(newImplementation);\\n emit Upgraded(newImplementation);\\n }\\n\\n /**\\n * @dev Perform implementation upgrade with additional setup call.\\n *\\n * Emits an {Upgraded} event.\\n */\\n function _upgradeToAndCall(\\n address newImplementation,\\n bytes memory data,\\n bool forceCall\\n ) internal {\\n _upgradeTo(newImplementation);\\n if (data.length > 0 || forceCall) {\\n Address.functionDelegateCall(newImplementation, data);\\n }\\n }\\n\\n /**\\n * @dev Perform implementation upgrade with security checks for UUPS proxies, and additional setup call.\\n *\\n * Emits an {Upgraded} event.\\n */\\n function _upgradeToAndCallUUPS(\\n address newImplementation,\\n bytes memory data,\\n bool forceCall\\n ) internal {\\n // Upgrades from old implementations will perform a rollback test. This test requires the new\\n // implementation to upgrade back to the old, non-ERC1822 compliant, implementation. Removing\\n // this special case will break upgrade paths from old UUPS implementation to new ones.\\n if (StorageSlot.getBooleanSlot(_ROLLBACK_SLOT).value) {\\n _setImplementation(newImplementation);\\n } else {\\n try IERC1822Proxiable(newImplementation).proxiableUUID() returns (bytes32 slot) {\\n require(slot == _IMPLEMENTATION_SLOT, \\\"ERC1967Upgrade: unsupported proxiableUUID\\\");\\n } catch {\\n revert(\\\"ERC1967Upgrade: new implementation is not UUPS\\\");\\n }\\n _upgradeToAndCall(newImplementation, data, forceCall);\\n }\\n }\\n\\n /**\\n * @dev Storage slot with the admin of the contract.\\n * This is the keccak-256 hash of \\\"eip1967.proxy.admin\\\" subtracted by 1, and is\\n * validated in the constructor.\\n */\\n bytes32 internal constant _ADMIN_SLOT = 0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103;\\n\\n /**\\n * @dev Emitted when the admin account has changed.\\n */\\n event AdminChanged(address previousAdmin, address newAdmin);\\n\\n /**\\n * @dev Returns the current admin.\\n */\\n function _getAdmin() internal view returns (address) {\\n return StorageSlot.getAddressSlot(_ADMIN_SLOT).value;\\n }\\n\\n /**\\n * @dev Stores a new address in the EIP1967 admin slot.\\n */\\n function _setAdmin(address newAdmin) private {\\n require(newAdmin != address(0), \\\"ERC1967: new admin is the zero address\\\");\\n StorageSlot.getAddressSlot(_ADMIN_SLOT).value = newAdmin;\\n }\\n\\n /**\\n * @dev Changes the admin of the proxy.\\n *\\n * Emits an {AdminChanged} event.\\n */\\n function _changeAdmin(address newAdmin) internal {\\n emit AdminChanged(_getAdmin(), newAdmin);\\n _setAdmin(newAdmin);\\n }\\n\\n /**\\n * @dev The storage slot of the UpgradeableBeacon contract which defines the implementation for this proxy.\\n * This is bytes32(uint256(keccak256('eip1967.proxy.beacon')) - 1)) and is validated in the constructor.\\n */\\n bytes32 internal constant _BEACON_SLOT = 0xa3f0ad74e5423aebfd80d3ef4346578335a9a72aeaee59ff6cb3582b35133d50;\\n\\n /**\\n * @dev Emitted when the beacon is upgraded.\\n */\\n event BeaconUpgraded(address indexed beacon);\\n\\n /**\\n * @dev Returns the current beacon.\\n */\\n function _getBeacon() internal view returns (address) {\\n return StorageSlot.getAddressSlot(_BEACON_SLOT).value;\\n }\\n\\n /**\\n * @dev Stores a new beacon in the EIP1967 beacon slot.\\n */\\n function _setBeacon(address newBeacon) private {\\n require(Address.isContract(newBeacon), \\\"ERC1967: new beacon is not a contract\\\");\\n require(\\n Address.isContract(IBeacon(newBeacon).implementation()),\\n \\\"ERC1967: beacon implementation is not a contract\\\"\\n );\\n StorageSlot.getAddressSlot(_BEACON_SLOT).value = newBeacon;\\n }\\n\\n /**\\n * @dev Perform beacon upgrade with additional setup call. Note: This upgrades the address of the beacon, it does\\n * not upgrade the implementation contained in the beacon (see {UpgradeableBeacon-_setImplementation} for that).\\n *\\n * Emits a {BeaconUpgraded} event.\\n */\\n function _upgradeBeaconToAndCall(\\n address newBeacon,\\n bytes memory data,\\n bool forceCall\\n ) internal {\\n _setBeacon(newBeacon);\\n emit BeaconUpgraded(newBeacon);\\n if (data.length > 0 || forceCall) {\\n Address.functionDelegateCall(IBeacon(newBeacon).implementation(), data);\\n }\\n }\\n}\\n\",\"keccak256\":\"0xabf3f59bc0e5423eae45e459dbe92e7052c6983628d39008590edc852a62f94a\",\"license\":\"MIT\"},\"@openzeppelin/contracts/proxy/Proxy.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.6.0) (proxy/Proxy.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev This abstract contract provides a fallback function that delegates all calls to another contract using the EVM\\n * instruction `delegatecall`. We refer to the second contract as the _implementation_ behind the proxy, and it has to\\n * be specified by overriding the virtual {_implementation} function.\\n *\\n * Additionally, delegation to the implementation can be triggered manually through the {_fallback} function, or to a\\n * different contract through the {_delegate} function.\\n *\\n * The success and return data of the delegated call will be returned back to the caller of the proxy.\\n */\\nabstract contract Proxy {\\n /**\\n * @dev Delegates the current call to `implementation`.\\n *\\n * This function does not return to its internal call site, it will return directly to the external caller.\\n */\\n function _delegate(address implementation) internal virtual {\\n assembly {\\n // Copy msg.data. We take full control of memory in this inline assembly\\n // block because it will not return to Solidity code. We overwrite the\\n // Solidity scratch pad at memory position 0.\\n calldatacopy(0, 0, calldatasize())\\n\\n // Call the implementation.\\n // out and outsize are 0 because we don't know the size yet.\\n let result := delegatecall(gas(), implementation, 0, calldatasize(), 0, 0)\\n\\n // Copy the returned data.\\n returndatacopy(0, 0, returndatasize())\\n\\n switch result\\n // delegatecall returns 0 on error.\\n case 0 {\\n revert(0, returndatasize())\\n }\\n default {\\n return(0, returndatasize())\\n }\\n }\\n }\\n\\n /**\\n * @dev This is a virtual function that should be overridden so it returns the address to which the fallback function\\n * and {_fallback} should delegate.\\n */\\n function _implementation() internal view virtual returns (address);\\n\\n /**\\n * @dev Delegates the current call to the address returned by `_implementation()`.\\n *\\n * This function does not return to its internal call site, it will return directly to the external caller.\\n */\\n function _fallback() internal virtual {\\n _beforeFallback();\\n _delegate(_implementation());\\n }\\n\\n /**\\n * @dev Fallback function that delegates calls to the address returned by `_implementation()`. Will run if no other\\n * function in the contract matches the call data.\\n */\\n fallback() external payable virtual {\\n _fallback();\\n }\\n\\n /**\\n * @dev Fallback function that delegates calls to the address returned by `_implementation()`. Will run if call data\\n * is empty.\\n */\\n receive() external payable virtual {\\n _fallback();\\n }\\n\\n /**\\n * @dev Hook that is called before falling back to the implementation. Can happen as part of a manual `_fallback`\\n * call, or as part of the Solidity `fallback` or `receive` functions.\\n *\\n * If overridden should call `super._beforeFallback()`.\\n */\\n function _beforeFallback() internal virtual {}\\n}\\n\",\"keccak256\":\"0xc130fe33f1b2132158531a87734153293f6d07bc263ff4ac90e85da9c82c0e27\",\"license\":\"MIT\"},\"@openzeppelin/contracts/proxy/beacon/IBeacon.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (proxy/beacon/IBeacon.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev This is the interface that {BeaconProxy} expects of its beacon.\\n */\\ninterface IBeacon {\\n /**\\n * @dev Must return an address that can be used as a delegate call target.\\n *\\n * {BeaconProxy} will check that this address is a contract.\\n */\\n function implementation() external view returns (address);\\n}\\n\",\"keccak256\":\"0xd50a3421ac379ccb1be435fa646d66a65c986b4924f0849839f08692f39dde61\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/Address.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.7.0) (utils/Address.sol)\\n\\npragma solidity ^0.8.1;\\n\\n/**\\n * @dev Collection of functions related to the address type\\n */\\nlibrary Address {\\n /**\\n * @dev Returns true if `account` is a contract.\\n *\\n * [IMPORTANT]\\n * ====\\n * It is unsafe to assume that an address for which this function returns\\n * false is an externally-owned account (EOA) and not a contract.\\n *\\n * Among others, `isContract` will return false for the following\\n * types of addresses:\\n *\\n * - an externally-owned account\\n * - a contract in construction\\n * - an address where a contract will be created\\n * - an address where a contract lived, but was destroyed\\n * ====\\n *\\n * [IMPORTANT]\\n * ====\\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\\n *\\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\\n * constructor.\\n * ====\\n */\\n function isContract(address account) internal view returns (bool) {\\n // This method relies on extcodesize/address.code.length, which returns 0\\n // for contracts in construction, since the code is only stored at the end\\n // of the constructor execution.\\n\\n return account.code.length > 0;\\n }\\n\\n /**\\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\\n * `recipient`, forwarding all available gas and reverting on errors.\\n *\\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\\n * imposed by `transfer`, making them unable to receive funds via\\n * `transfer`. {sendValue} removes this limitation.\\n *\\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\\n *\\n * IMPORTANT: because control is transferred to `recipient`, care must be\\n * taken to not create reentrancy vulnerabilities. Consider using\\n * {ReentrancyGuard} or the\\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\\n */\\n function sendValue(address payable recipient, uint256 amount) internal {\\n require(address(this).balance >= amount, \\\"Address: insufficient balance\\\");\\n\\n (bool success, ) = recipient.call{value: amount}(\\\"\\\");\\n require(success, \\\"Address: unable to send value, recipient may have reverted\\\");\\n }\\n\\n /**\\n * @dev Performs a Solidity function call using a low level `call`. A\\n * plain `call` is an unsafe replacement for a function call: use this\\n * function instead.\\n *\\n * If `target` reverts with a revert reason, it is bubbled up by this\\n * function (like regular Solidity function calls).\\n *\\n * Returns the raw returned data. To convert to the expected return value,\\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\\n *\\n * Requirements:\\n *\\n * - `target` must be a contract.\\n * - calling `target` with `data` must not revert.\\n *\\n * _Available since v3.1._\\n */\\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\\n return functionCall(target, data, \\\"Address: low-level call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\\n * `errorMessage` as a fallback revert reason when `target` reverts.\\n *\\n * _Available since v3.1._\\n */\\n function functionCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n return functionCallWithValue(target, data, 0, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but also transferring `value` wei to `target`.\\n *\\n * Requirements:\\n *\\n * - the calling contract must have an ETH balance of at least `value`.\\n * - the called Solidity function must be `payable`.\\n *\\n * _Available since v3.1._\\n */\\n function functionCallWithValue(\\n address target,\\n bytes memory data,\\n uint256 value\\n ) internal returns (bytes memory) {\\n return functionCallWithValue(target, data, value, \\\"Address: low-level call with value failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\\n * with `errorMessage` as a fallback revert reason when `target` reverts.\\n *\\n * _Available since v3.1._\\n */\\n function functionCallWithValue(\\n address target,\\n bytes memory data,\\n uint256 value,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n require(address(this).balance >= value, \\\"Address: insufficient balance for call\\\");\\n require(isContract(target), \\\"Address: call to non-contract\\\");\\n\\n (bool success, bytes memory returndata) = target.call{value: value}(data);\\n return verifyCallResult(success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but performing a static call.\\n *\\n * _Available since v3.3._\\n */\\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\\n return functionStaticCall(target, data, \\\"Address: low-level static call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\\n * but performing a static call.\\n *\\n * _Available since v3.3._\\n */\\n function functionStaticCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal view returns (bytes memory) {\\n require(isContract(target), \\\"Address: static call to non-contract\\\");\\n\\n (bool success, bytes memory returndata) = target.staticcall(data);\\n return verifyCallResult(success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but performing a delegate call.\\n *\\n * _Available since v3.4._\\n */\\n function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {\\n return functionDelegateCall(target, data, \\\"Address: low-level delegate call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\\n * but performing a delegate call.\\n *\\n * _Available since v3.4._\\n */\\n function functionDelegateCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n require(isContract(target), \\\"Address: delegate call to non-contract\\\");\\n\\n (bool success, bytes memory returndata) = target.delegatecall(data);\\n return verifyCallResult(success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the\\n * revert reason using the provided one.\\n *\\n * _Available since v4.3._\\n */\\n function verifyCallResult(\\n bool success,\\n bytes memory returndata,\\n string memory errorMessage\\n ) internal pure returns (bytes memory) {\\n if (success) {\\n return returndata;\\n } else {\\n // Look for revert reason and bubble it up if present\\n if (returndata.length > 0) {\\n // The easiest way to bubble the revert reason is using memory via assembly\\n /// @solidity memory-safe-assembly\\n assembly {\\n let returndata_size := mload(returndata)\\n revert(add(32, returndata), returndata_size)\\n }\\n } else {\\n revert(errorMessage);\\n }\\n }\\n }\\n}\\n\",\"keccak256\":\"0xd6153ce99bcdcce22b124f755e72553295be6abcd63804cfdffceb188b8bef10\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/StorageSlot.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.7.0) (utils/StorageSlot.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Library for reading and writing primitive types to specific storage slots.\\n *\\n * Storage slots are often used to avoid storage conflict when dealing with upgradeable contracts.\\n * This library helps with reading and writing to such slots without the need for inline assembly.\\n *\\n * The functions in this library return Slot structs that contain a `value` member that can be used to read or write.\\n *\\n * Example usage to set ERC1967 implementation slot:\\n * ```\\n * contract ERC1967 {\\n * bytes32 internal constant _IMPLEMENTATION_SLOT = 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc;\\n *\\n * function _getImplementation() internal view returns (address) {\\n * return StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value;\\n * }\\n *\\n * function _setImplementation(address newImplementation) internal {\\n * require(Address.isContract(newImplementation), \\\"ERC1967: new implementation is not a contract\\\");\\n * StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value = newImplementation;\\n * }\\n * }\\n * ```\\n *\\n * _Available since v4.1 for `address`, `bool`, `bytes32`, and `uint256`._\\n */\\nlibrary StorageSlot {\\n struct AddressSlot {\\n address value;\\n }\\n\\n struct BooleanSlot {\\n bool value;\\n }\\n\\n struct Bytes32Slot {\\n bytes32 value;\\n }\\n\\n struct Uint256Slot {\\n uint256 value;\\n }\\n\\n /**\\n * @dev Returns an `AddressSlot` with member `value` located at `slot`.\\n */\\n function getAddressSlot(bytes32 slot) internal pure returns (AddressSlot storage r) {\\n /// @solidity memory-safe-assembly\\n assembly {\\n r.slot := slot\\n }\\n }\\n\\n /**\\n * @dev Returns an `BooleanSlot` with member `value` located at `slot`.\\n */\\n function getBooleanSlot(bytes32 slot) internal pure returns (BooleanSlot storage r) {\\n /// @solidity memory-safe-assembly\\n assembly {\\n r.slot := slot\\n }\\n }\\n\\n /**\\n * @dev Returns an `Bytes32Slot` with member `value` located at `slot`.\\n */\\n function getBytes32Slot(bytes32 slot) internal pure returns (Bytes32Slot storage r) {\\n /// @solidity memory-safe-assembly\\n assembly {\\n r.slot := slot\\n }\\n }\\n\\n /**\\n * @dev Returns an `Uint256Slot` with member `value` located at `slot`.\\n */\\n function getUint256Slot(bytes32 slot) internal pure returns (Uint256Slot storage r) {\\n /// @solidity memory-safe-assembly\\n assembly {\\n r.slot := slot\\n }\\n }\\n}\\n\",\"keccak256\":\"0xd5c50c54bf02740ebd122ff06832546cb5fa84486d52695a9ccfd11666e0c81d\",\"license\":\"MIT\"},\"contracts/external/TransparentUpgradeableProxy.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-3.0\\n\\npragma solidity ^0.8.12;\\n\\nimport \\\"@openzeppelin/contracts/proxy/ERC1967/ERC1967Proxy.sol\\\";\\n\\n/**\\n * @dev This contract implements a proxy that is upgradeable by an admin. It is fully forked from OpenZeppelin\\n * `TransparentUpgradeableProxy`\\n *\\n * To avoid https://medium.com/nomic-labs-blog/malicious-backdoors-in-ethereum-proxies-62629adf3357[proxy selector\\n * clashing], which can potentially be used in an attack, this contract uses the\\n * https://blog.openzeppelin.com/the-transparent-proxy-pattern/[transparent proxy pattern]. This pattern implies two\\n * things that go hand in hand:\\n *\\n * 1. If any account other than the admin calls the proxy, the call will be forwarded to the implementation, even if\\n * that call matches one of the admin functions exposed by the proxy itself.\\n * 2. If the admin calls the proxy, it can access the admin functions, but its calls will never be forwarded to the\\n * implementation. If the admin tries to call a function on the implementation it will fail with an error that says\\n * \\\"admin cannot fallback to proxy target\\\".\\n *\\n * These properties mean that the admin account can only be used for admin actions like upgrading the proxy or changing\\n * the admin, so it's best if it's a dedicated account that is not used for anything else. This will avoid headaches due\\n * to sudden errors when trying to call a function from the proxy implementation.\\n *\\n * Our recommendation is for the dedicated account to be an instance of the {ProxyAdmin} contract. If set up this way,\\n * you should think of the `ProxyAdmin` instance as the real administrative interface of your proxy.\\n */\\ncontract TransparentUpgradeableProxy is ERC1967Proxy {\\n /**\\n * @dev Initializes an upgradeable proxy managed by `_admin`, backed by the implementation at `_logic`, and\\n * optionally initialized with `_data` as explained in {ERC1967Proxy-constructor}.\\n */\\n constructor(address _logic, address admin_, bytes memory _data) payable ERC1967Proxy(_logic, _data) {\\n assert(_ADMIN_SLOT == bytes32(uint256(keccak256(\\\"eip1967.proxy.admin\\\")) - 1));\\n _changeAdmin(admin_);\\n }\\n\\n /**\\n * @dev Modifier used internally that will delegate the call to the implementation unless the sender is the admin.\\n */\\n modifier ifAdmin() {\\n if (msg.sender == _getAdmin()) {\\n _;\\n } else {\\n _fallback();\\n }\\n }\\n\\n /**\\n * @dev Returns the current admin.\\n *\\n * NOTE: Only the admin can call this function. See {ProxyAdmin-getProxyAdmin}.\\n *\\n * TIP: To get this value clients can read directly from the storage slot shown below (specified by EIP1967) using the\\n * https://eth.wiki/json-rpc/API#eth_getstorageat[`eth_getStorageAt`] RPC call.\\n * `0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103`\\n */\\n function admin() external ifAdmin returns (address admin_) {\\n admin_ = _getAdmin();\\n }\\n\\n /**\\n * @dev Returns the current implementation.\\n *\\n * NOTE: Only the admin can call this function. See {ProxyAdmin-getProxyImplementation}.\\n *\\n * TIP: To get this value clients can read directly from the storage slot shown below (specified by EIP1967) using the\\n * https://eth.wiki/json-rpc/API#eth_getstorageat[`eth_getStorageAt`] RPC call.\\n * `0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc`\\n */\\n function implementation() external ifAdmin returns (address implementation_) {\\n implementation_ = _implementation();\\n }\\n\\n /**\\n * @dev Changes the admin of the proxy.\\n *\\n * Emits an {AdminChanged} event.\\n *\\n * NOTE: Only the admin can call this function. See {ProxyAdmin-changeProxyAdmin}.\\n */\\n function changeAdmin(address newAdmin) external virtual ifAdmin {\\n _changeAdmin(newAdmin);\\n }\\n\\n /**\\n * @dev Upgrade the implementation of the proxy.\\n *\\n * NOTE: Only the admin can call this function. See {ProxyAdmin-upgrade}.\\n */\\n function upgradeTo(address newImplementation) external ifAdmin {\\n _upgradeToAndCall(newImplementation, bytes(\\\"\\\"), false);\\n }\\n\\n /**\\n * @dev Upgrade the implementation of the proxy, and then call a function from the new implementation as specified\\n * by `data`, which should be an encoded function call. This is useful to initialize new storage variables in the\\n * proxied contract.\\n *\\n * NOTE: Only the admin can call this function. See {ProxyAdmin-upgradeAndCall}.\\n */\\n function upgradeToAndCall(address newImplementation, bytes calldata data) external payable ifAdmin {\\n _upgradeToAndCall(newImplementation, data, true);\\n }\\n\\n /**\\n * @dev Returns the current admin.\\n */\\n function _admin() internal view virtual returns (address) {\\n return _getAdmin();\\n }\\n\\n /**\\n * @dev Makes sure the admin cannot access the fallback function. See {Proxy-_beforeFallback}.\\n */\\n function _beforeFallback() internal virtual override {\\n require(msg.sender != _getAdmin(), \\\"TransparentUpgradeableProxy: admin cannot fallback to proxy target\\\");\\n super._beforeFallback();\\n }\\n}\\n\",\"keccak256\":\"0x93a67a0f612ea3ff2a76315e138a6a88267270a1379d3cc7be52845fbbe611e2\",\"license\":\"GPL-3.0\"}},\"version\":1}", + "bytecode": "0x6080604052604051620010bb380380620010bb8339810160408190526200002691620004d8565b828162000036828260006200009a565b5062000066905060017fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6104620005b8565b6000805160206200107483398151915214620000865762000086620005da565b6200009182620000d7565b50505062000643565b620000a58362000132565b600082511180620000b35750805b15620000d257620000d083836200017460201b6200028c1760201c565b505b505050565b7f7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f62000102620001a5565b604080516001600160a01b03928316815291841660208301520160405180910390a16200012f81620001de565b50565b6200013d8162000293565b6040516001600160a01b038216907fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b90600090a250565b60606200019c8383604051806060016040528060278152602001620010946027913962000347565b90505b92915050565b6000620001cf6000805160206200107483398151915260001b6200042f60201b6200022e1760201c565b546001600160a01b0316919050565b6001600160a01b038116620002495760405162461bcd60e51b815260206004820152602660248201527f455243313936373a206e65772061646d696e20697320746865207a65726f206160448201526564647265737360d01b60648201526084015b60405180910390fd5b80620002726000805160206200107483398151915260001b6200042f60201b6200022e1760201c565b80546001600160a01b0319166001600160a01b039290921691909117905550565b620002a9816200043260201b620002b81760201c565b6200030d5760405162461bcd60e51b815260206004820152602d60248201527f455243313936373a206e657720696d706c656d656e746174696f6e206973206e60448201526c1bdd08184818dbdb9d1c9858dd609a1b606482015260840162000240565b80620002727f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc60001b6200042f60201b6200022e1760201c565b60606001600160a01b0384163b620003b15760405162461bcd60e51b815260206004820152602660248201527f416464726573733a2064656c65676174652063616c6c20746f206e6f6e2d636f6044820152651b9d1c9858dd60d21b606482015260840162000240565b600080856001600160a01b031685604051620003ce9190620005f0565b600060405180830381855af49150503d80600081146200040b576040519150601f19603f3d011682016040523d82523d6000602084013e62000410565b606091505b5090925090506200042382828662000441565b925050505b9392505050565b90565b6001600160a01b03163b151590565b606083156200045257508162000428565b825115620004635782518084602001fd5b8160405162461bcd60e51b81526004016200024091906200060e565b80516001600160a01b03811681146200049757600080fd5b919050565b634e487b7160e01b600052604160045260246000fd5b60005b83811015620004cf578181015183820152602001620004b5565b50506000910152565b600080600060608486031215620004ee57600080fd5b620004f9846200047f565b925062000509602085016200047f565b60408501519092506001600160401b03808211156200052757600080fd5b818601915086601f8301126200053c57600080fd5b8151818111156200055157620005516200049c565b604051601f8201601f19908116603f011681019083821181831017156200057c576200057c6200049c565b816040528281528960208487010111156200059657600080fd5b620005a9836020830160208801620004b2565b80955050505050509250925092565b818103818111156200019f57634e487b7160e01b600052601160045260246000fd5b634e487b7160e01b600052600160045260246000fd5b6000825162000604818460208701620004b2565b9190910192915050565b60208152600082518060208401526200062f816040850160208701620004b2565b601f01601f19169190910160400192915050565b610a2180620006536000396000f3fe60806040526004361061005e5760003560e01c80635c60da1b116100435780635c60da1b146100a85780638f283970146100e6578063f851a440146101065761006d565b80633659cfe6146100755780634f1ef286146100955761006d565b3661006d5761006b61011b565b005b61006b61011b565b34801561008157600080fd5b5061006b610090366004610895565b610135565b61006b6100a33660046108b0565b61017f565b3480156100b457600080fd5b506100bd6101f3565b60405173ffffffffffffffffffffffffffffffffffffffff909116815260200160405180910390f35b3480156100f257600080fd5b5061006b610101366004610895565b610231565b34801561011257600080fd5b506100bd61025e565b6101236102d4565b61013361012e6103ab565b6103b5565b565b61013d6103d9565b73ffffffffffffffffffffffffffffffffffffffff1633036101775761017481604051806020016040528060008152506000610419565b50565b61017461011b565b6101876103d9565b73ffffffffffffffffffffffffffffffffffffffff1633036101eb576101e68383838080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525060019250610419915050565b505050565b6101e661011b565b60006101fd6103d9565b73ffffffffffffffffffffffffffffffffffffffff163303610226576102216103ab565b905090565b61022e61011b565b90565b6102396103d9565b73ffffffffffffffffffffffffffffffffffffffff1633036101775761017481610444565b60006102686103d9565b73ffffffffffffffffffffffffffffffffffffffff163303610226576102216103d9565b60606102b183836040518060600160405280602781526020016109c5602791396104a5565b9392505050565b73ffffffffffffffffffffffffffffffffffffffff163b151590565b6102dc6103d9565b73ffffffffffffffffffffffffffffffffffffffff163303610133576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604260248201527f5472616e73706172656e745570677261646561626c6550726f78793a2061646d60448201527f696e2063616e6e6f742066616c6c6261636b20746f2070726f7879207461726760648201527f6574000000000000000000000000000000000000000000000000000000000000608482015260a4015b60405180910390fd5b60006102216105cd565b3660008037600080366000845af43d6000803e8080156103d4573d6000f35b3d6000fd5b60007fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035b5473ffffffffffffffffffffffffffffffffffffffff16919050565b610422836105f5565b60008251118061042f5750805b156101e65761043e838361028c565b50505050565b7f7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f61046d6103d9565b6040805173ffffffffffffffffffffffffffffffffffffffff928316815291841660208301520160405180910390a161017481610642565b606073ffffffffffffffffffffffffffffffffffffffff84163b61054b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f416464726573733a2064656c65676174652063616c6c20746f206e6f6e2d636f60448201527f6e7472616374000000000000000000000000000000000000000000000000000060648201526084016103a2565b6000808573ffffffffffffffffffffffffffffffffffffffff16856040516105739190610957565b600060405180830381855af49150503d80600081146105ae576040519150601f19603f3d011682016040523d82523d6000602084013e6105b3565b606091505b50915091506105c382828661074e565b9695505050505050565b60007f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc6103fd565b6105fe816107a1565b60405173ffffffffffffffffffffffffffffffffffffffff8216907fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b90600090a250565b73ffffffffffffffffffffffffffffffffffffffff81166106e5576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f455243313936373a206e65772061646d696e20697320746865207a65726f206160448201527f646472657373000000000000000000000000000000000000000000000000000060648201526084016103a2565b807fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035b80547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff9290921691909117905550565b6060831561075d5750816102b1565b82511561076d5782518084602001fd5b816040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016103a29190610973565b73ffffffffffffffffffffffffffffffffffffffff81163b610845576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602d60248201527f455243313936373a206e657720696d706c656d656e746174696f6e206973206e60448201527f6f74206120636f6e74726163740000000000000000000000000000000000000060648201526084016103a2565b807f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc610708565b803573ffffffffffffffffffffffffffffffffffffffff8116811461089057600080fd5b919050565b6000602082840312156108a757600080fd5b6102b18261086c565b6000806000604084860312156108c557600080fd5b6108ce8461086c565b9250602084013567ffffffffffffffff808211156108eb57600080fd5b818601915086601f8301126108ff57600080fd5b81358181111561090e57600080fd5b87602082850101111561092057600080fd5b6020830194508093505050509250925092565b60005b8381101561094e578181015183820152602001610936565b50506000910152565b60008251610969818460208701610933565b9190910192915050565b6020815260008251806020840152610992816040850160208701610933565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016919091016040019291505056fe416464726573733a206c6f772d6c6576656c2064656c65676174652063616c6c206661696c6564a2646970667358221220e96638b07fb1675d93a95c49e417bc8111448b23a59918698cdcd8fd488dd7cf64736f6c63430008110033b53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103416464726573733a206c6f772d6c6576656c2064656c65676174652063616c6c206661696c6564", + "deployedBytecode": "0x60806040526004361061005e5760003560e01c80635c60da1b116100435780635c60da1b146100a85780638f283970146100e6578063f851a440146101065761006d565b80633659cfe6146100755780634f1ef286146100955761006d565b3661006d5761006b61011b565b005b61006b61011b565b34801561008157600080fd5b5061006b610090366004610895565b610135565b61006b6100a33660046108b0565b61017f565b3480156100b457600080fd5b506100bd6101f3565b60405173ffffffffffffffffffffffffffffffffffffffff909116815260200160405180910390f35b3480156100f257600080fd5b5061006b610101366004610895565b610231565b34801561011257600080fd5b506100bd61025e565b6101236102d4565b61013361012e6103ab565b6103b5565b565b61013d6103d9565b73ffffffffffffffffffffffffffffffffffffffff1633036101775761017481604051806020016040528060008152506000610419565b50565b61017461011b565b6101876103d9565b73ffffffffffffffffffffffffffffffffffffffff1633036101eb576101e68383838080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525060019250610419915050565b505050565b6101e661011b565b60006101fd6103d9565b73ffffffffffffffffffffffffffffffffffffffff163303610226576102216103ab565b905090565b61022e61011b565b90565b6102396103d9565b73ffffffffffffffffffffffffffffffffffffffff1633036101775761017481610444565b60006102686103d9565b73ffffffffffffffffffffffffffffffffffffffff163303610226576102216103d9565b60606102b183836040518060600160405280602781526020016109c5602791396104a5565b9392505050565b73ffffffffffffffffffffffffffffffffffffffff163b151590565b6102dc6103d9565b73ffffffffffffffffffffffffffffffffffffffff163303610133576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604260248201527f5472616e73706172656e745570677261646561626c6550726f78793a2061646d60448201527f696e2063616e6e6f742066616c6c6261636b20746f2070726f7879207461726760648201527f6574000000000000000000000000000000000000000000000000000000000000608482015260a4015b60405180910390fd5b60006102216105cd565b3660008037600080366000845af43d6000803e8080156103d4573d6000f35b3d6000fd5b60007fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035b5473ffffffffffffffffffffffffffffffffffffffff16919050565b610422836105f5565b60008251118061042f5750805b156101e65761043e838361028c565b50505050565b7f7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f61046d6103d9565b6040805173ffffffffffffffffffffffffffffffffffffffff928316815291841660208301520160405180910390a161017481610642565b606073ffffffffffffffffffffffffffffffffffffffff84163b61054b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f416464726573733a2064656c65676174652063616c6c20746f206e6f6e2d636f60448201527f6e7472616374000000000000000000000000000000000000000000000000000060648201526084016103a2565b6000808573ffffffffffffffffffffffffffffffffffffffff16856040516105739190610957565b600060405180830381855af49150503d80600081146105ae576040519150601f19603f3d011682016040523d82523d6000602084013e6105b3565b606091505b50915091506105c382828661074e565b9695505050505050565b60007f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc6103fd565b6105fe816107a1565b60405173ffffffffffffffffffffffffffffffffffffffff8216907fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b90600090a250565b73ffffffffffffffffffffffffffffffffffffffff81166106e5576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f455243313936373a206e65772061646d696e20697320746865207a65726f206160448201527f646472657373000000000000000000000000000000000000000000000000000060648201526084016103a2565b807fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035b80547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff9290921691909117905550565b6060831561075d5750816102b1565b82511561076d5782518084602001fd5b816040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016103a29190610973565b73ffffffffffffffffffffffffffffffffffffffff81163b610845576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602d60248201527f455243313936373a206e657720696d706c656d656e746174696f6e206973206e60448201527f6f74206120636f6e74726163740000000000000000000000000000000000000060648201526084016103a2565b807f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc610708565b803573ffffffffffffffffffffffffffffffffffffffff8116811461089057600080fd5b919050565b6000602082840312156108a757600080fd5b6102b18261086c565b6000806000604084860312156108c557600080fd5b6108ce8461086c565b9250602084013567ffffffffffffffff808211156108eb57600080fd5b818601915086601f8301126108ff57600080fd5b81358181111561090e57600080fd5b87602082850101111561092057600080fd5b6020830194508093505050509250925092565b60005b8381101561094e578181015183820152602001610936565b50506000910152565b60008251610969818460208701610933565b9190910192915050565b6020815260008251806020840152610992816040850160208701610933565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016919091016040019291505056fe416464726573733a206c6f772d6c6576656c2064656c65676174652063616c6c206661696c6564a2646970667358221220e96638b07fb1675d93a95c49e417bc8111448b23a59918698cdcd8fd488dd7cf64736f6c63430008110033", + "devdoc": { + "details": "This contract implements a proxy that is upgradeable by an admin. It is fully forked from OpenZeppelin `TransparentUpgradeableProxy` To avoid https://medium.com/nomic-labs-blog/malicious-backdoors-in-ethereum-proxies-62629adf3357[proxy selector clashing], which can potentially be used in an attack, this contract uses the https://blog.openzeppelin.com/the-transparent-proxy-pattern/[transparent proxy pattern]. This pattern implies two things that go hand in hand: 1. If any account other than the admin calls the proxy, the call will be forwarded to the implementation, even if that call matches one of the admin functions exposed by the proxy itself. 2. If the admin calls the proxy, it can access the admin functions, but its calls will never be forwarded to the implementation. If the admin tries to call a function on the implementation it will fail with an error that says \"admin cannot fallback to proxy target\". These properties mean that the admin account can only be used for admin actions like upgrading the proxy or changing the admin, so it's best if it's a dedicated account that is not used for anything else. This will avoid headaches due to sudden errors when trying to call a function from the proxy implementation. Our recommendation is for the dedicated account to be an instance of the {ProxyAdmin} contract. If set up this way, you should think of the `ProxyAdmin` instance as the real administrative interface of your proxy.", + "kind": "dev", + "methods": { + "admin()": { + "details": "Returns the current admin. NOTE: Only the admin can call this function. See {ProxyAdmin-getProxyAdmin}. TIP: To get this value clients can read directly from the storage slot shown below (specified by EIP1967) using the https://eth.wiki/json-rpc/API#eth_getstorageat[`eth_getStorageAt`] RPC call. `0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103`" + }, + "changeAdmin(address)": { + "details": "Changes the admin of the proxy. Emits an {AdminChanged} event. NOTE: Only the admin can call this function. See {ProxyAdmin-changeProxyAdmin}." + }, + "constructor": { + "details": "Initializes an upgradeable proxy managed by `_admin`, backed by the implementation at `_logic`, and optionally initialized with `_data` as explained in {ERC1967Proxy-constructor}." + }, + "implementation()": { + "details": "Returns the current implementation. NOTE: Only the admin can call this function. See {ProxyAdmin-getProxyImplementation}. TIP: To get this value clients can read directly from the storage slot shown below (specified by EIP1967) using the https://eth.wiki/json-rpc/API#eth_getstorageat[`eth_getStorageAt`] RPC call. `0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc`" + }, + "upgradeTo(address)": { + "details": "Upgrade the implementation of the proxy. NOTE: Only the admin can call this function. See {ProxyAdmin-upgrade}." + }, + "upgradeToAndCall(address,bytes)": { + "details": "Upgrade the implementation of the proxy, and then call a function from the new implementation as specified by `data`, which should be an encoded function call. This is useful to initialize new storage variables in the proxied contract. NOTE: Only the admin can call this function. See {ProxyAdmin-upgradeAndCall}." + } + }, + "version": 1 + }, + "userdoc": { + "kind": "user", + "methods": {}, + "version": 1 + }, + "storageLayout": { + "storage": [], + "types": null + } +} \ No newline at end of file diff --git a/deployments/linea/solcInputs/871924e0c138825a2736b76def8fef8d.json b/deployments/linea/solcInputs/871924e0c138825a2736b76def8fef8d.json new file mode 100644 index 00000000..57454028 --- /dev/null +++ b/deployments/linea/solcInputs/871924e0c138825a2736b76def8fef8d.json @@ -0,0 +1,562 @@ +{ + "language": "Solidity", + "sources": { + "@chainlink/contracts/src/v0.8/interfaces/AggregatorV3Interface.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.0;\n\ninterface AggregatorV3Interface {\n\n function decimals()\n external\n view\n returns (\n uint8\n );\n\n function description()\n external\n view\n returns (\n string memory\n );\n\n function version()\n external\n view\n returns (\n uint256\n );\n\n // getRoundData and latestRoundData should both raise \"No data present\"\n // if they do not have data to report, instead of returning unset values\n // which could be misinterpreted as actual reported values.\n function getRoundData(\n uint80 _roundId\n )\n external\n view\n returns (\n uint80 roundId,\n int256 answer,\n uint256 startedAt,\n uint256 updatedAt,\n uint80 answeredInRound\n );\n\n function latestRoundData()\n external\n view\n returns (\n uint80 roundId,\n int256 answer,\n uint256 startedAt,\n uint256 updatedAt,\n uint80 answeredInRound\n );\n\n}\n" + }, + "@openzeppelin/contracts-upgradeable/access/AccessControlEnumerableUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.5.0) (access/AccessControlEnumerable.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./IAccessControlEnumerableUpgradeable.sol\";\nimport \"./AccessControlUpgradeable.sol\";\nimport \"../utils/structs/EnumerableSetUpgradeable.sol\";\nimport \"../proxy/utils/Initializable.sol\";\n\n/**\n * @dev Extension of {AccessControl} that allows enumerating the members of each role.\n */\nabstract contract AccessControlEnumerableUpgradeable is Initializable, IAccessControlEnumerableUpgradeable, AccessControlUpgradeable {\n function __AccessControlEnumerable_init() internal onlyInitializing {\n }\n\n function __AccessControlEnumerable_init_unchained() internal onlyInitializing {\n }\n using EnumerableSetUpgradeable for EnumerableSetUpgradeable.AddressSet;\n\n mapping(bytes32 => EnumerableSetUpgradeable.AddressSet) private _roleMembers;\n\n /**\n * @dev See {IERC165-supportsInterface}.\n */\n function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {\n return interfaceId == type(IAccessControlEnumerableUpgradeable).interfaceId || super.supportsInterface(interfaceId);\n }\n\n /**\n * @dev Returns one of the accounts that have `role`. `index` must be a\n * value between 0 and {getRoleMemberCount}, non-inclusive.\n *\n * Role bearers are not sorted in any particular way, and their ordering may\n * change at any point.\n *\n * WARNING: When using {getRoleMember} and {getRoleMemberCount}, make sure\n * you perform all queries on the same block. See the following\n * https://forum.openzeppelin.com/t/iterating-over-elements-on-enumerableset-in-openzeppelin-contracts/2296[forum post]\n * for more information.\n */\n function getRoleMember(bytes32 role, uint256 index) public view virtual override returns (address) {\n return _roleMembers[role].at(index);\n }\n\n /**\n * @dev Returns the number of accounts that have `role`. Can be used\n * together with {getRoleMember} to enumerate all bearers of a role.\n */\n function getRoleMemberCount(bytes32 role) public view virtual override returns (uint256) {\n return _roleMembers[role].length();\n }\n\n /**\n * @dev Overload {_grantRole} to track enumerable memberships\n */\n function _grantRole(bytes32 role, address account) internal virtual override {\n super._grantRole(role, account);\n _roleMembers[role].add(account);\n }\n\n /**\n * @dev Overload {_revokeRole} to track enumerable memberships\n */\n function _revokeRole(bytes32 role, address account) internal virtual override {\n super._revokeRole(role, account);\n _roleMembers[role].remove(account);\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[49] private __gap;\n}\n" + }, + "@openzeppelin/contracts-upgradeable/access/AccessControlUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (access/AccessControl.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./IAccessControlUpgradeable.sol\";\nimport \"../utils/ContextUpgradeable.sol\";\nimport \"../utils/StringsUpgradeable.sol\";\nimport \"../utils/introspection/ERC165Upgradeable.sol\";\nimport \"../proxy/utils/Initializable.sol\";\n\n/**\n * @dev Contract module that allows children to implement role-based access\n * control mechanisms. This is a lightweight version that doesn't allow enumerating role\n * members except through off-chain means by accessing the contract event logs. Some\n * applications may benefit from on-chain enumerability, for those cases see\n * {AccessControlEnumerable}.\n *\n * Roles are referred to by their `bytes32` identifier. These should be exposed\n * in the external API and be unique. The best way to achieve this is by\n * using `public constant` hash digests:\n *\n * ```\n * bytes32 public constant MY_ROLE = keccak256(\"MY_ROLE\");\n * ```\n *\n * Roles can be used to represent a set of permissions. To restrict access to a\n * function call, use {hasRole}:\n *\n * ```\n * function foo() public {\n * require(hasRole(MY_ROLE, msg.sender));\n * ...\n * }\n * ```\n *\n * Roles can be granted and revoked dynamically via the {grantRole} and\n * {revokeRole} functions. Each role has an associated admin role, and only\n * accounts that have a role's admin role can call {grantRole} and {revokeRole}.\n *\n * By default, the admin role for all roles is `DEFAULT_ADMIN_ROLE`, which means\n * that only accounts with this role will be able to grant or revoke other\n * roles. More complex role relationships can be created by using\n * {_setRoleAdmin}.\n *\n * WARNING: The `DEFAULT_ADMIN_ROLE` is also its own admin: it has permission to\n * grant and revoke this role. Extra precautions should be taken to secure\n * accounts that have been granted it.\n */\nabstract contract AccessControlUpgradeable is Initializable, ContextUpgradeable, IAccessControlUpgradeable, ERC165Upgradeable {\n function __AccessControl_init() internal onlyInitializing {\n }\n\n function __AccessControl_init_unchained() internal onlyInitializing {\n }\n struct RoleData {\n mapping(address => bool) members;\n bytes32 adminRole;\n }\n\n mapping(bytes32 => RoleData) private _roles;\n\n bytes32 public constant DEFAULT_ADMIN_ROLE = 0x00;\n\n /**\n * @dev Modifier that checks that an account has a specific role. Reverts\n * with a standardized message including the required role.\n *\n * The format of the revert reason is given by the following regular expression:\n *\n * /^AccessControl: account (0x[0-9a-f]{40}) is missing role (0x[0-9a-f]{64})$/\n *\n * _Available since v4.1._\n */\n modifier onlyRole(bytes32 role) {\n _checkRole(role);\n _;\n }\n\n /**\n * @dev See {IERC165-supportsInterface}.\n */\n function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {\n return interfaceId == type(IAccessControlUpgradeable).interfaceId || super.supportsInterface(interfaceId);\n }\n\n /**\n * @dev Returns `true` if `account` has been granted `role`.\n */\n function hasRole(bytes32 role, address account) public view virtual override returns (bool) {\n return _roles[role].members[account];\n }\n\n /**\n * @dev Revert with a standard message if `_msgSender()` is missing `role`.\n * Overriding this function changes the behavior of the {onlyRole} modifier.\n *\n * Format of the revert message is described in {_checkRole}.\n *\n * _Available since v4.6._\n */\n function _checkRole(bytes32 role) internal view virtual {\n _checkRole(role, _msgSender());\n }\n\n /**\n * @dev Revert with a standard message if `account` is missing `role`.\n *\n * The format of the revert reason is given by the following regular expression:\n *\n * /^AccessControl: account (0x[0-9a-f]{40}) is missing role (0x[0-9a-f]{64})$/\n */\n function _checkRole(bytes32 role, address account) internal view virtual {\n if (!hasRole(role, account)) {\n revert(\n string(\n abi.encodePacked(\n \"AccessControl: account \",\n StringsUpgradeable.toHexString(uint160(account), 20),\n \" is missing role \",\n StringsUpgradeable.toHexString(uint256(role), 32)\n )\n )\n );\n }\n }\n\n /**\n * @dev Returns the admin role that controls `role`. See {grantRole} and\n * {revokeRole}.\n *\n * To change a role's admin, use {_setRoleAdmin}.\n */\n function getRoleAdmin(bytes32 role) public view virtual override returns (bytes32) {\n return _roles[role].adminRole;\n }\n\n /**\n * @dev Grants `role` to `account`.\n *\n * If `account` had not been already granted `role`, emits a {RoleGranted}\n * event.\n *\n * Requirements:\n *\n * - the caller must have ``role``'s admin role.\n *\n * May emit a {RoleGranted} event.\n */\n function grantRole(bytes32 role, address account) public virtual override onlyRole(getRoleAdmin(role)) {\n _grantRole(role, account);\n }\n\n /**\n * @dev Revokes `role` from `account`.\n *\n * If `account` had been granted `role`, emits a {RoleRevoked} event.\n *\n * Requirements:\n *\n * - the caller must have ``role``'s admin role.\n *\n * May emit a {RoleRevoked} event.\n */\n function revokeRole(bytes32 role, address account) public virtual override onlyRole(getRoleAdmin(role)) {\n _revokeRole(role, account);\n }\n\n /**\n * @dev Revokes `role` from the calling account.\n *\n * Roles are often managed via {grantRole} and {revokeRole}: this function's\n * purpose is to provide a mechanism for accounts to lose their privileges\n * if they are compromised (such as when a trusted device is misplaced).\n *\n * If the calling account had been revoked `role`, emits a {RoleRevoked}\n * event.\n *\n * Requirements:\n *\n * - the caller must be `account`.\n *\n * May emit a {RoleRevoked} event.\n */\n function renounceRole(bytes32 role, address account) public virtual override {\n require(account == _msgSender(), \"AccessControl: can only renounce roles for self\");\n\n _revokeRole(role, account);\n }\n\n /**\n * @dev Grants `role` to `account`.\n *\n * If `account` had not been already granted `role`, emits a {RoleGranted}\n * event. Note that unlike {grantRole}, this function doesn't perform any\n * checks on the calling account.\n *\n * May emit a {RoleGranted} event.\n *\n * [WARNING]\n * ====\n * This function should only be called from the constructor when setting\n * up the initial roles for the system.\n *\n * Using this function in any other way is effectively circumventing the admin\n * system imposed by {AccessControl}.\n * ====\n *\n * NOTE: This function is deprecated in favor of {_grantRole}.\n */\n function _setupRole(bytes32 role, address account) internal virtual {\n _grantRole(role, account);\n }\n\n /**\n * @dev Sets `adminRole` as ``role``'s admin role.\n *\n * Emits a {RoleAdminChanged} event.\n */\n function _setRoleAdmin(bytes32 role, bytes32 adminRole) internal virtual {\n bytes32 previousAdminRole = getRoleAdmin(role);\n _roles[role].adminRole = adminRole;\n emit RoleAdminChanged(role, previousAdminRole, adminRole);\n }\n\n /**\n * @dev Grants `role` to `account`.\n *\n * Internal function without access restriction.\n *\n * May emit a {RoleGranted} event.\n */\n function _grantRole(bytes32 role, address account) internal virtual {\n if (!hasRole(role, account)) {\n _roles[role].members[account] = true;\n emit RoleGranted(role, account, _msgSender());\n }\n }\n\n /**\n * @dev Revokes `role` from `account`.\n *\n * Internal function without access restriction.\n *\n * May emit a {RoleRevoked} event.\n */\n function _revokeRole(bytes32 role, address account) internal virtual {\n if (hasRole(role, account)) {\n _roles[role].members[account] = false;\n emit RoleRevoked(role, account, _msgSender());\n }\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[49] private __gap;\n}\n" + }, + "@openzeppelin/contracts-upgradeable/access/IAccessControlEnumerableUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (access/IAccessControlEnumerable.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./IAccessControlUpgradeable.sol\";\n\n/**\n * @dev External interface of AccessControlEnumerable declared to support ERC165 detection.\n */\ninterface IAccessControlEnumerableUpgradeable is IAccessControlUpgradeable {\n /**\n * @dev Returns one of the accounts that have `role`. `index` must be a\n * value between 0 and {getRoleMemberCount}, non-inclusive.\n *\n * Role bearers are not sorted in any particular way, and their ordering may\n * change at any point.\n *\n * WARNING: When using {getRoleMember} and {getRoleMemberCount}, make sure\n * you perform all queries on the same block. See the following\n * https://forum.openzeppelin.com/t/iterating-over-elements-on-enumerableset-in-openzeppelin-contracts/2296[forum post]\n * for more information.\n */\n function getRoleMember(bytes32 role, uint256 index) external view returns (address);\n\n /**\n * @dev Returns the number of accounts that have `role`. Can be used\n * together with {getRoleMember} to enumerate all bearers of a role.\n */\n function getRoleMemberCount(bytes32 role) external view returns (uint256);\n}\n" + }, + "@openzeppelin/contracts-upgradeable/access/IAccessControlUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (access/IAccessControl.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev External interface of AccessControl declared to support ERC165 detection.\n */\ninterface IAccessControlUpgradeable {\n /**\n * @dev Emitted when `newAdminRole` is set as ``role``'s admin role, replacing `previousAdminRole`\n *\n * `DEFAULT_ADMIN_ROLE` is the starting admin for all roles, despite\n * {RoleAdminChanged} not being emitted signaling this.\n *\n * _Available since v3.1._\n */\n event RoleAdminChanged(bytes32 indexed role, bytes32 indexed previousAdminRole, bytes32 indexed newAdminRole);\n\n /**\n * @dev Emitted when `account` is granted `role`.\n *\n * `sender` is the account that originated the contract call, an admin role\n * bearer except when using {AccessControl-_setupRole}.\n */\n event RoleGranted(bytes32 indexed role, address indexed account, address indexed sender);\n\n /**\n * @dev Emitted when `account` is revoked `role`.\n *\n * `sender` is the account that originated the contract call:\n * - if using `revokeRole`, it is the admin role bearer\n * - if using `renounceRole`, it is the role bearer (i.e. `account`)\n */\n event RoleRevoked(bytes32 indexed role, address indexed account, address indexed sender);\n\n /**\n * @dev Returns `true` if `account` has been granted `role`.\n */\n function hasRole(bytes32 role, address account) external view returns (bool);\n\n /**\n * @dev Returns the admin role that controls `role`. See {grantRole} and\n * {revokeRole}.\n *\n * To change a role's admin, use {AccessControl-_setRoleAdmin}.\n */\n function getRoleAdmin(bytes32 role) external view returns (bytes32);\n\n /**\n * @dev Grants `role` to `account`.\n *\n * If `account` had not been already granted `role`, emits a {RoleGranted}\n * event.\n *\n * Requirements:\n *\n * - the caller must have ``role``'s admin role.\n */\n function grantRole(bytes32 role, address account) external;\n\n /**\n * @dev Revokes `role` from `account`.\n *\n * If `account` had been granted `role`, emits a {RoleRevoked} event.\n *\n * Requirements:\n *\n * - the caller must have ``role``'s admin role.\n */\n function revokeRole(bytes32 role, address account) external;\n\n /**\n * @dev Revokes `role` from the calling account.\n *\n * Roles are often managed via {grantRole} and {revokeRole}: this function's\n * purpose is to provide a mechanism for accounts to lose their privileges\n * if they are compromised (such as when a trusted device is misplaced).\n *\n * If the calling account had been granted `role`, emits a {RoleRevoked}\n * event.\n *\n * Requirements:\n *\n * - the caller must be `account`.\n */\n function renounceRole(bytes32 role, address account) external;\n}\n" + }, + "@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (access/Ownable.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../utils/ContextUpgradeable.sol\";\nimport \"../proxy/utils/Initializable.sol\";\n\n/**\n * @dev Contract module which provides a basic access control mechanism, where\n * there is an account (an owner) that can be granted exclusive access to\n * specific functions.\n *\n * By default, the owner account will be the one that deploys the contract. This\n * can later be changed with {transferOwnership}.\n *\n * This module is used through inheritance. It will make available the modifier\n * `onlyOwner`, which can be applied to your functions to restrict their use to\n * the owner.\n */\nabstract contract OwnableUpgradeable is Initializable, ContextUpgradeable {\n address private _owner;\n\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\n\n /**\n * @dev Initializes the contract setting the deployer as the initial owner.\n */\n function __Ownable_init() internal onlyInitializing {\n __Ownable_init_unchained();\n }\n\n function __Ownable_init_unchained() internal onlyInitializing {\n _transferOwnership(_msgSender());\n }\n\n /**\n * @dev Throws if called by any account other than the owner.\n */\n modifier onlyOwner() {\n _checkOwner();\n _;\n }\n\n /**\n * @dev Returns the address of the current owner.\n */\n function owner() public view virtual returns (address) {\n return _owner;\n }\n\n /**\n * @dev Throws if the sender is not the owner.\n */\n function _checkOwner() internal view virtual {\n require(owner() == _msgSender(), \"Ownable: caller is not the owner\");\n }\n\n /**\n * @dev Leaves the contract without owner. It will not be possible to call\n * `onlyOwner` functions anymore. Can only be called by the current owner.\n *\n * NOTE: Renouncing ownership will leave the contract without an owner,\n * thereby removing any functionality that is only available to the owner.\n */\n function renounceOwnership() public virtual onlyOwner {\n _transferOwnership(address(0));\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Can only be called by the current owner.\n */\n function transferOwnership(address newOwner) public virtual onlyOwner {\n require(newOwner != address(0), \"Ownable: new owner is the zero address\");\n _transferOwnership(newOwner);\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Internal function without access restriction.\n */\n function _transferOwnership(address newOwner) internal virtual {\n address oldOwner = _owner;\n _owner = newOwner;\n emit OwnershipTransferred(oldOwner, newOwner);\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[49] private __gap;\n}\n" + }, + "@openzeppelin/contracts-upgradeable/interfaces/IERC721MetadataUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (interfaces/IERC721Metadata.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../token/ERC721/extensions/IERC721MetadataUpgradeable.sol\";\n" + }, + "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (proxy/utils/Initializable.sol)\n\npragma solidity ^0.8.2;\n\nimport \"../../utils/AddressUpgradeable.sol\";\n\n/**\n * @dev This is a base contract to aid in writing upgradeable contracts, or any kind of contract that will be deployed\n * behind a proxy. Since proxied contracts do not make use of a constructor, it's common to move constructor logic to an\n * external initializer function, usually called `initialize`. It then becomes necessary to protect this initializer\n * function so it can only be called once. The {initializer} modifier provided by this contract will have this effect.\n *\n * The initialization functions use a version number. Once a version number is used, it is consumed and cannot be\n * reused. This mechanism prevents re-execution of each \"step\" but allows the creation of new initialization steps in\n * case an upgrade adds a module that needs to be initialized.\n *\n * For example:\n *\n * [.hljs-theme-light.nopadding]\n * ```\n * contract MyToken is ERC20Upgradeable {\n * function initialize() initializer public {\n * __ERC20_init(\"MyToken\", \"MTK\");\n * }\n * }\n * contract MyTokenV2 is MyToken, ERC20PermitUpgradeable {\n * function initializeV2() reinitializer(2) public {\n * __ERC20Permit_init(\"MyToken\");\n * }\n * }\n * ```\n *\n * TIP: To avoid leaving the proxy in an uninitialized state, the initializer function should be called as early as\n * possible by providing the encoded function call as the `_data` argument to {ERC1967Proxy-constructor}.\n *\n * CAUTION: When used with inheritance, manual care must be taken to not invoke a parent initializer twice, or to ensure\n * that all initializers are idempotent. This is not verified automatically as constructors are by Solidity.\n *\n * [CAUTION]\n * ====\n * Avoid leaving a contract uninitialized.\n *\n * An uninitialized contract can be taken over by an attacker. This applies to both a proxy and its implementation\n * contract, which may impact the proxy. To prevent the implementation contract from being used, you should invoke\n * the {_disableInitializers} function in the constructor to automatically lock it when it is deployed:\n *\n * [.hljs-theme-light.nopadding]\n * ```\n * /// @custom:oz-upgrades-unsafe-allow constructor\n * constructor() {\n * _disableInitializers();\n * }\n * ```\n * ====\n */\nabstract contract Initializable {\n /**\n * @dev Indicates that the contract has been initialized.\n * @custom:oz-retyped-from bool\n */\n uint8 private _initialized;\n\n /**\n * @dev Indicates that the contract is in the process of being initialized.\n */\n bool private _initializing;\n\n /**\n * @dev Triggered when the contract has been initialized or reinitialized.\n */\n event Initialized(uint8 version);\n\n /**\n * @dev A modifier that defines a protected initializer function that can be invoked at most once. In its scope,\n * `onlyInitializing` functions can be used to initialize parent contracts. Equivalent to `reinitializer(1)`.\n */\n modifier initializer() {\n bool isTopLevelCall = !_initializing;\n require(\n (isTopLevelCall && _initialized < 1) || (!AddressUpgradeable.isContract(address(this)) && _initialized == 1),\n \"Initializable: contract is already initialized\"\n );\n _initialized = 1;\n if (isTopLevelCall) {\n _initializing = true;\n }\n _;\n if (isTopLevelCall) {\n _initializing = false;\n emit Initialized(1);\n }\n }\n\n /**\n * @dev A modifier that defines a protected reinitializer function that can be invoked at most once, and only if the\n * contract hasn't been initialized to a greater version before. In its scope, `onlyInitializing` functions can be\n * used to initialize parent contracts.\n *\n * `initializer` is equivalent to `reinitializer(1)`, so a reinitializer may be used after the original\n * initialization step. This is essential to configure modules that are added through upgrades and that require\n * initialization.\n *\n * Note that versions can jump in increments greater than 1; this implies that if multiple reinitializers coexist in\n * a contract, executing them in the right order is up to the developer or operator.\n */\n modifier reinitializer(uint8 version) {\n require(!_initializing && _initialized < version, \"Initializable: contract is already initialized\");\n _initialized = version;\n _initializing = true;\n _;\n _initializing = false;\n emit Initialized(version);\n }\n\n /**\n * @dev Modifier to protect an initialization function so that it can only be invoked by functions with the\n * {initializer} and {reinitializer} modifiers, directly or indirectly.\n */\n modifier onlyInitializing() {\n require(_initializing, \"Initializable: contract is not initializing\");\n _;\n }\n\n /**\n * @dev Locks the contract, preventing any future reinitialization. This cannot be part of an initializer call.\n * Calling this in the constructor of a contract will prevent that contract from being initialized or reinitialized\n * to any version. It is recommended to use this to lock implementation contracts that are designed to be called\n * through proxies.\n */\n function _disableInitializers() internal virtual {\n require(!_initializing, \"Initializable: contract is initializing\");\n if (_initialized < type(uint8).max) {\n _initialized = type(uint8).max;\n emit Initialized(type(uint8).max);\n }\n }\n}\n" + }, + "@openzeppelin/contracts-upgradeable/security/PausableUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (security/Pausable.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../utils/ContextUpgradeable.sol\";\nimport \"../proxy/utils/Initializable.sol\";\n\n/**\n * @dev Contract module which allows children to implement an emergency stop\n * mechanism that can be triggered by an authorized account.\n *\n * This module is used through inheritance. It will make available the\n * modifiers `whenNotPaused` and `whenPaused`, which can be applied to\n * the functions of your contract. Note that they will not be pausable by\n * simply including this module, only once the modifiers are put in place.\n */\nabstract contract PausableUpgradeable is Initializable, ContextUpgradeable {\n /**\n * @dev Emitted when the pause is triggered by `account`.\n */\n event Paused(address account);\n\n /**\n * @dev Emitted when the pause is lifted by `account`.\n */\n event Unpaused(address account);\n\n bool private _paused;\n\n /**\n * @dev Initializes the contract in unpaused state.\n */\n function __Pausable_init() internal onlyInitializing {\n __Pausable_init_unchained();\n }\n\n function __Pausable_init_unchained() internal onlyInitializing {\n _paused = false;\n }\n\n /**\n * @dev Modifier to make a function callable only when the contract is not paused.\n *\n * Requirements:\n *\n * - The contract must not be paused.\n */\n modifier whenNotPaused() {\n _requireNotPaused();\n _;\n }\n\n /**\n * @dev Modifier to make a function callable only when the contract is paused.\n *\n * Requirements:\n *\n * - The contract must be paused.\n */\n modifier whenPaused() {\n _requirePaused();\n _;\n }\n\n /**\n * @dev Returns true if the contract is paused, and false otherwise.\n */\n function paused() public view virtual returns (bool) {\n return _paused;\n }\n\n /**\n * @dev Throws if the contract is paused.\n */\n function _requireNotPaused() internal view virtual {\n require(!paused(), \"Pausable: paused\");\n }\n\n /**\n * @dev Throws if the contract is not paused.\n */\n function _requirePaused() internal view virtual {\n require(paused(), \"Pausable: not paused\");\n }\n\n /**\n * @dev Triggers stopped state.\n *\n * Requirements:\n *\n * - The contract must not be paused.\n */\n function _pause() internal virtual whenNotPaused {\n _paused = true;\n emit Paused(_msgSender());\n }\n\n /**\n * @dev Returns to normal state.\n *\n * Requirements:\n *\n * - The contract must be paused.\n */\n function _unpause() internal virtual whenPaused {\n _paused = false;\n emit Unpaused(_msgSender());\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[49] private __gap;\n}\n" + }, + "@openzeppelin/contracts-upgradeable/security/ReentrancyGuardUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (security/ReentrancyGuard.sol)\n\npragma solidity ^0.8.0;\nimport \"../proxy/utils/Initializable.sol\";\n\n/**\n * @dev Contract module that helps prevent reentrant calls to a function.\n *\n * Inheriting from `ReentrancyGuard` will make the {nonReentrant} modifier\n * available, which can be applied to functions to make sure there are no nested\n * (reentrant) calls to them.\n *\n * Note that because there is a single `nonReentrant` guard, functions marked as\n * `nonReentrant` may not call one another. This can be worked around by making\n * those functions `private`, and then adding `external` `nonReentrant` entry\n * points to them.\n *\n * TIP: If you would like to learn more about reentrancy and alternative ways\n * to protect against it, check out our blog post\n * https://blog.openzeppelin.com/reentrancy-after-istanbul/[Reentrancy After Istanbul].\n */\nabstract contract ReentrancyGuardUpgradeable is Initializable {\n // Booleans are more expensive than uint256 or any type that takes up a full\n // word because each write operation emits an extra SLOAD to first read the\n // slot's contents, replace the bits taken up by the boolean, and then write\n // back. This is the compiler's defense against contract upgrades and\n // pointer aliasing, and it cannot be disabled.\n\n // The values being non-zero value makes deployment a bit more expensive,\n // but in exchange the refund on every call to nonReentrant will be lower in\n // amount. Since refunds are capped to a percentage of the total\n // transaction's gas, it is best to keep them low in cases like this one, to\n // increase the likelihood of the full refund coming into effect.\n uint256 private constant _NOT_ENTERED = 1;\n uint256 private constant _ENTERED = 2;\n\n uint256 private _status;\n\n function __ReentrancyGuard_init() internal onlyInitializing {\n __ReentrancyGuard_init_unchained();\n }\n\n function __ReentrancyGuard_init_unchained() internal onlyInitializing {\n _status = _NOT_ENTERED;\n }\n\n /**\n * @dev Prevents a contract from calling itself, directly or indirectly.\n * Calling a `nonReentrant` function from another `nonReentrant`\n * function is not supported. It is possible to prevent this from happening\n * by making the `nonReentrant` function external, and making it call a\n * `private` function that does the actual work.\n */\n modifier nonReentrant() {\n // On the first call to nonReentrant, _notEntered will be true\n require(_status != _ENTERED, \"ReentrancyGuard: reentrant call\");\n\n // Any calls to nonReentrant after this point will fail\n _status = _ENTERED;\n\n _;\n\n // By storing the original value once again, a refund is triggered (see\n // https://eips.ethereum.org/EIPS/eip-2200)\n _status = _NOT_ENTERED;\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[49] private __gap;\n}\n" + }, + "@openzeppelin/contracts-upgradeable/token/ERC20/ERC20Upgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (token/ERC20/ERC20.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./IERC20Upgradeable.sol\";\nimport \"./extensions/IERC20MetadataUpgradeable.sol\";\nimport \"../../utils/ContextUpgradeable.sol\";\nimport \"../../proxy/utils/Initializable.sol\";\n\n/**\n * @dev Implementation of the {IERC20} interface.\n *\n * This implementation is agnostic to the way tokens are created. This means\n * that a supply mechanism has to be added in a derived contract using {_mint}.\n * For a generic mechanism see {ERC20PresetMinterPauser}.\n *\n * TIP: For a detailed writeup see our guide\n * https://forum.zeppelin.solutions/t/how-to-implement-erc20-supply-mechanisms/226[How\n * to implement supply mechanisms].\n *\n * We have followed general OpenZeppelin Contracts guidelines: functions revert\n * instead returning `false` on failure. This behavior is nonetheless\n * conventional and does not conflict with the expectations of ERC20\n * applications.\n *\n * Additionally, an {Approval} event is emitted on calls to {transferFrom}.\n * This allows applications to reconstruct the allowance for all accounts just\n * by listening to said events. Other implementations of the EIP may not emit\n * these events, as it isn't required by the specification.\n *\n * Finally, the non-standard {decreaseAllowance} and {increaseAllowance}\n * functions have been added to mitigate the well-known issues around setting\n * allowances. See {IERC20-approve}.\n */\ncontract ERC20Upgradeable is Initializable, ContextUpgradeable, IERC20Upgradeable, IERC20MetadataUpgradeable {\n mapping(address => uint256) private _balances;\n\n mapping(address => mapping(address => uint256)) private _allowances;\n\n uint256 private _totalSupply;\n\n string private _name;\n string private _symbol;\n\n /**\n * @dev Sets the values for {name} and {symbol}.\n *\n * The default value of {decimals} is 18. To select a different value for\n * {decimals} you should overload it.\n *\n * All two of these values are immutable: they can only be set once during\n * construction.\n */\n function __ERC20_init(string memory name_, string memory symbol_) internal onlyInitializing {\n __ERC20_init_unchained(name_, symbol_);\n }\n\n function __ERC20_init_unchained(string memory name_, string memory symbol_) internal onlyInitializing {\n _name = name_;\n _symbol = symbol_;\n }\n\n /**\n * @dev Returns the name of the token.\n */\n function name() public view virtual override returns (string memory) {\n return _name;\n }\n\n /**\n * @dev Returns the symbol of the token, usually a shorter version of the\n * name.\n */\n function symbol() public view virtual override returns (string memory) {\n return _symbol;\n }\n\n /**\n * @dev Returns the number of decimals used to get its user representation.\n * For example, if `decimals` equals `2`, a balance of `505` tokens should\n * be displayed to a user as `5.05` (`505 / 10 ** 2`).\n *\n * Tokens usually opt for a value of 18, imitating the relationship between\n * Ether and Wei. This is the value {ERC20} uses, unless this function is\n * overridden;\n *\n * NOTE: This information is only used for _display_ purposes: it in\n * no way affects any of the arithmetic of the contract, including\n * {IERC20-balanceOf} and {IERC20-transfer}.\n */\n function decimals() public view virtual override returns (uint8) {\n return 18;\n }\n\n /**\n * @dev See {IERC20-totalSupply}.\n */\n function totalSupply() public view virtual override returns (uint256) {\n return _totalSupply;\n }\n\n /**\n * @dev See {IERC20-balanceOf}.\n */\n function balanceOf(address account) public view virtual override returns (uint256) {\n return _balances[account];\n }\n\n /**\n * @dev See {IERC20-transfer}.\n *\n * Requirements:\n *\n * - `to` cannot be the zero address.\n * - the caller must have a balance of at least `amount`.\n */\n function transfer(address to, uint256 amount) public virtual override returns (bool) {\n address owner = _msgSender();\n _transfer(owner, to, amount);\n return true;\n }\n\n /**\n * @dev See {IERC20-allowance}.\n */\n function allowance(address owner, address spender) public view virtual override returns (uint256) {\n return _allowances[owner][spender];\n }\n\n /**\n * @dev See {IERC20-approve}.\n *\n * NOTE: If `amount` is the maximum `uint256`, the allowance is not updated on\n * `transferFrom`. This is semantically equivalent to an infinite approval.\n *\n * Requirements:\n *\n * - `spender` cannot be the zero address.\n */\n function approve(address spender, uint256 amount) public virtual override returns (bool) {\n address owner = _msgSender();\n _approve(owner, spender, amount);\n return true;\n }\n\n /**\n * @dev See {IERC20-transferFrom}.\n *\n * Emits an {Approval} event indicating the updated allowance. This is not\n * required by the EIP. See the note at the beginning of {ERC20}.\n *\n * NOTE: Does not update the allowance if the current allowance\n * is the maximum `uint256`.\n *\n * Requirements:\n *\n * - `from` and `to` cannot be the zero address.\n * - `from` must have a balance of at least `amount`.\n * - the caller must have allowance for ``from``'s tokens of at least\n * `amount`.\n */\n function transferFrom(\n address from,\n address to,\n uint256 amount\n ) public virtual override returns (bool) {\n address spender = _msgSender();\n _spendAllowance(from, spender, amount);\n _transfer(from, to, amount);\n return true;\n }\n\n /**\n * @dev Atomically increases the allowance granted to `spender` by the caller.\n *\n * This is an alternative to {approve} that can be used as a mitigation for\n * problems described in {IERC20-approve}.\n *\n * Emits an {Approval} event indicating the updated allowance.\n *\n * Requirements:\n *\n * - `spender` cannot be the zero address.\n */\n function increaseAllowance(address spender, uint256 addedValue) public virtual returns (bool) {\n address owner = _msgSender();\n _approve(owner, spender, allowance(owner, spender) + addedValue);\n return true;\n }\n\n /**\n * @dev Atomically decreases the allowance granted to `spender` by the caller.\n *\n * This is an alternative to {approve} that can be used as a mitigation for\n * problems described in {IERC20-approve}.\n *\n * Emits an {Approval} event indicating the updated allowance.\n *\n * Requirements:\n *\n * - `spender` cannot be the zero address.\n * - `spender` must have allowance for the caller of at least\n * `subtractedValue`.\n */\n function decreaseAllowance(address spender, uint256 subtractedValue) public virtual returns (bool) {\n address owner = _msgSender();\n uint256 currentAllowance = allowance(owner, spender);\n require(currentAllowance >= subtractedValue, \"ERC20: decreased allowance below zero\");\n unchecked {\n _approve(owner, spender, currentAllowance - subtractedValue);\n }\n\n return true;\n }\n\n /**\n * @dev Moves `amount` of tokens from `from` to `to`.\n *\n * This internal function is equivalent to {transfer}, and can be used to\n * e.g. implement automatic token fees, slashing mechanisms, etc.\n *\n * Emits a {Transfer} event.\n *\n * Requirements:\n *\n * - `from` cannot be the zero address.\n * - `to` cannot be the zero address.\n * - `from` must have a balance of at least `amount`.\n */\n function _transfer(\n address from,\n address to,\n uint256 amount\n ) internal virtual {\n require(from != address(0), \"ERC20: transfer from the zero address\");\n require(to != address(0), \"ERC20: transfer to the zero address\");\n\n _beforeTokenTransfer(from, to, amount);\n\n uint256 fromBalance = _balances[from];\n require(fromBalance >= amount, \"ERC20: transfer amount exceeds balance\");\n unchecked {\n _balances[from] = fromBalance - amount;\n }\n _balances[to] += amount;\n\n emit Transfer(from, to, amount);\n\n _afterTokenTransfer(from, to, amount);\n }\n\n /** @dev Creates `amount` tokens and assigns them to `account`, increasing\n * the total supply.\n *\n * Emits a {Transfer} event with `from` set to the zero address.\n *\n * Requirements:\n *\n * - `account` cannot be the zero address.\n */\n function _mint(address account, uint256 amount) internal virtual {\n require(account != address(0), \"ERC20: mint to the zero address\");\n\n _beforeTokenTransfer(address(0), account, amount);\n\n _totalSupply += amount;\n _balances[account] += amount;\n emit Transfer(address(0), account, amount);\n\n _afterTokenTransfer(address(0), account, amount);\n }\n\n /**\n * @dev Destroys `amount` tokens from `account`, reducing the\n * total supply.\n *\n * Emits a {Transfer} event with `to` set to the zero address.\n *\n * Requirements:\n *\n * - `account` cannot be the zero address.\n * - `account` must have at least `amount` tokens.\n */\n function _burn(address account, uint256 amount) internal virtual {\n require(account != address(0), \"ERC20: burn from the zero address\");\n\n _beforeTokenTransfer(account, address(0), amount);\n\n uint256 accountBalance = _balances[account];\n require(accountBalance >= amount, \"ERC20: burn amount exceeds balance\");\n unchecked {\n _balances[account] = accountBalance - amount;\n }\n _totalSupply -= amount;\n\n emit Transfer(account, address(0), amount);\n\n _afterTokenTransfer(account, address(0), amount);\n }\n\n /**\n * @dev Sets `amount` as the allowance of `spender` over the `owner` s tokens.\n *\n * This internal function is equivalent to `approve`, and can be used to\n * e.g. set automatic allowances for certain subsystems, etc.\n *\n * Emits an {Approval} event.\n *\n * Requirements:\n *\n * - `owner` cannot be the zero address.\n * - `spender` cannot be the zero address.\n */\n function _approve(\n address owner,\n address spender,\n uint256 amount\n ) internal virtual {\n require(owner != address(0), \"ERC20: approve from the zero address\");\n require(spender != address(0), \"ERC20: approve to the zero address\");\n\n _allowances[owner][spender] = amount;\n emit Approval(owner, spender, amount);\n }\n\n /**\n * @dev Updates `owner` s allowance for `spender` based on spent `amount`.\n *\n * Does not update the allowance amount in case of infinite allowance.\n * Revert if not enough allowance is available.\n *\n * Might emit an {Approval} event.\n */\n function _spendAllowance(\n address owner,\n address spender,\n uint256 amount\n ) internal virtual {\n uint256 currentAllowance = allowance(owner, spender);\n if (currentAllowance != type(uint256).max) {\n require(currentAllowance >= amount, \"ERC20: insufficient allowance\");\n unchecked {\n _approve(owner, spender, currentAllowance - amount);\n }\n }\n }\n\n /**\n * @dev Hook that is called before any transfer of tokens. This includes\n * minting and burning.\n *\n * Calling conditions:\n *\n * - when `from` and `to` are both non-zero, `amount` of ``from``'s tokens\n * will be transferred to `to`.\n * - when `from` is zero, `amount` tokens will be minted for `to`.\n * - when `to` is zero, `amount` of ``from``'s tokens will be burned.\n * - `from` and `to` are never both zero.\n *\n * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].\n */\n function _beforeTokenTransfer(\n address from,\n address to,\n uint256 amount\n ) internal virtual {}\n\n /**\n * @dev Hook that is called after any transfer of tokens. This includes\n * minting and burning.\n *\n * Calling conditions:\n *\n * - when `from` and `to` are both non-zero, `amount` of ``from``'s tokens\n * has been transferred to `to`.\n * - when `from` is zero, `amount` tokens have been minted for `to`.\n * - when `to` is zero, `amount` of ``from``'s tokens have been burned.\n * - `from` and `to` are never both zero.\n *\n * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].\n */\n function _afterTokenTransfer(\n address from,\n address to,\n uint256 amount\n ) internal virtual {}\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[45] private __gap;\n}\n" + }, + "@openzeppelin/contracts-upgradeable/token/ERC20/extensions/draft-ERC20PermitUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.6.0) (token/ERC20/extensions/draft-ERC20Permit.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./draft-IERC20PermitUpgradeable.sol\";\nimport \"../ERC20Upgradeable.sol\";\nimport \"../../../utils/cryptography/draft-EIP712Upgradeable.sol\";\nimport \"../../../utils/cryptography/ECDSAUpgradeable.sol\";\nimport \"../../../utils/CountersUpgradeable.sol\";\nimport \"../../../proxy/utils/Initializable.sol\";\n\n/**\n * @dev Implementation of the ERC20 Permit extension allowing approvals to be made via signatures, as defined in\n * https://eips.ethereum.org/EIPS/eip-2612[EIP-2612].\n *\n * Adds the {permit} method, which can be used to change an account's ERC20 allowance (see {IERC20-allowance}) by\n * presenting a message signed by the account. By not relying on `{IERC20-approve}`, the token holder account doesn't\n * need to send a transaction, and thus is not required to hold Ether at all.\n *\n * _Available since v3.4._\n *\n * @custom:storage-size 51\n */\nabstract contract ERC20PermitUpgradeable is Initializable, ERC20Upgradeable, IERC20PermitUpgradeable, EIP712Upgradeable {\n using CountersUpgradeable for CountersUpgradeable.Counter;\n\n mapping(address => CountersUpgradeable.Counter) private _nonces;\n\n // solhint-disable-next-line var-name-mixedcase\n bytes32 private constant _PERMIT_TYPEHASH =\n keccak256(\"Permit(address owner,address spender,uint256 value,uint256 nonce,uint256 deadline)\");\n /**\n * @dev In previous versions `_PERMIT_TYPEHASH` was declared as `immutable`.\n * However, to ensure consistency with the upgradeable transpiler, we will continue\n * to reserve a slot.\n * @custom:oz-renamed-from _PERMIT_TYPEHASH\n */\n // solhint-disable-next-line var-name-mixedcase\n bytes32 private _PERMIT_TYPEHASH_DEPRECATED_SLOT;\n\n /**\n * @dev Initializes the {EIP712} domain separator using the `name` parameter, and setting `version` to `\"1\"`.\n *\n * It's a good idea to use the same `name` that is defined as the ERC20 token name.\n */\n function __ERC20Permit_init(string memory name) internal onlyInitializing {\n __EIP712_init_unchained(name, \"1\");\n }\n\n function __ERC20Permit_init_unchained(string memory) internal onlyInitializing {}\n\n /**\n * @dev See {IERC20Permit-permit}.\n */\n function permit(\n address owner,\n address spender,\n uint256 value,\n uint256 deadline,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) public virtual override {\n require(block.timestamp <= deadline, \"ERC20Permit: expired deadline\");\n\n bytes32 structHash = keccak256(abi.encode(_PERMIT_TYPEHASH, owner, spender, value, _useNonce(owner), deadline));\n\n bytes32 hash = _hashTypedDataV4(structHash);\n\n address signer = ECDSAUpgradeable.recover(hash, v, r, s);\n require(signer == owner, \"ERC20Permit: invalid signature\");\n\n _approve(owner, spender, value);\n }\n\n /**\n * @dev See {IERC20Permit-nonces}.\n */\n function nonces(address owner) public view virtual override returns (uint256) {\n return _nonces[owner].current();\n }\n\n /**\n * @dev See {IERC20Permit-DOMAIN_SEPARATOR}.\n */\n // solhint-disable-next-line func-name-mixedcase\n function DOMAIN_SEPARATOR() external view override returns (bytes32) {\n return _domainSeparatorV4();\n }\n\n /**\n * @dev \"Consume a nonce\": return the current value and increment.\n *\n * _Available since v4.1._\n */\n function _useNonce(address owner) internal virtual returns (uint256 current) {\n CountersUpgradeable.Counter storage nonce = _nonces[owner];\n current = nonce.current();\n nonce.increment();\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[49] private __gap;\n}\n" + }, + "@openzeppelin/contracts-upgradeable/token/ERC20/extensions/draft-IERC20PermitUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (token/ERC20/extensions/draft-IERC20Permit.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Interface of the ERC20 Permit extension allowing approvals to be made via signatures, as defined in\n * https://eips.ethereum.org/EIPS/eip-2612[EIP-2612].\n *\n * Adds the {permit} method, which can be used to change an account's ERC20 allowance (see {IERC20-allowance}) by\n * presenting a message signed by the account. By not relying on {IERC20-approve}, the token holder account doesn't\n * need to send a transaction, and thus is not required to hold Ether at all.\n */\ninterface IERC20PermitUpgradeable {\n /**\n * @dev Sets `value` as the allowance of `spender` over ``owner``'s tokens,\n * given ``owner``'s signed approval.\n *\n * IMPORTANT: The same issues {IERC20-approve} has related to transaction\n * ordering also apply here.\n *\n * Emits an {Approval} event.\n *\n * Requirements:\n *\n * - `spender` cannot be the zero address.\n * - `deadline` must be a timestamp in the future.\n * - `v`, `r` and `s` must be a valid `secp256k1` signature from `owner`\n * over the EIP712-formatted function arguments.\n * - the signature must use ``owner``'s current nonce (see {nonces}).\n *\n * For more information on the signature format, see the\n * https://eips.ethereum.org/EIPS/eip-2612#specification[relevant EIP\n * section].\n */\n function permit(\n address owner,\n address spender,\n uint256 value,\n uint256 deadline,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) external;\n\n /**\n * @dev Returns the current nonce for `owner`. This value must be\n * included whenever a signature is generated for {permit}.\n *\n * Every successful call to {permit} increases ``owner``'s nonce by one. This\n * prevents a signature from being used multiple times.\n */\n function nonces(address owner) external view returns (uint256);\n\n /**\n * @dev Returns the domain separator used in the encoding of the signature for {permit}, as defined by {EIP712}.\n */\n // solhint-disable-next-line func-name-mixedcase\n function DOMAIN_SEPARATOR() external view returns (bytes32);\n}\n" + }, + "@openzeppelin/contracts-upgradeable/token/ERC20/extensions/IERC20MetadataUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (token/ERC20/extensions/IERC20Metadata.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../IERC20Upgradeable.sol\";\n\n/**\n * @dev Interface for the optional metadata functions from the ERC20 standard.\n *\n * _Available since v4.1._\n */\ninterface IERC20MetadataUpgradeable is IERC20Upgradeable {\n /**\n * @dev Returns the name of the token.\n */\n function name() external view returns (string memory);\n\n /**\n * @dev Returns the symbol of the token.\n */\n function symbol() external view returns (string memory);\n\n /**\n * @dev Returns the decimals places of the token.\n */\n function decimals() external view returns (uint8);\n}\n" + }, + "@openzeppelin/contracts-upgradeable/token/ERC20/IERC20Upgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.6.0) (token/ERC20/IERC20.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Interface of the ERC20 standard as defined in the EIP.\n */\ninterface IERC20Upgradeable {\n /**\n * @dev Emitted when `value` tokens are moved from one account (`from`) to\n * another (`to`).\n *\n * Note that `value` may be zero.\n */\n event Transfer(address indexed from, address indexed to, uint256 value);\n\n /**\n * @dev Emitted when the allowance of a `spender` for an `owner` is set by\n * a call to {approve}. `value` is the new allowance.\n */\n event Approval(address indexed owner, address indexed spender, uint256 value);\n\n /**\n * @dev Returns the amount of tokens in existence.\n */\n function totalSupply() external view returns (uint256);\n\n /**\n * @dev Returns the amount of tokens owned by `account`.\n */\n function balanceOf(address account) external view returns (uint256);\n\n /**\n * @dev Moves `amount` tokens from the caller's account to `to`.\n *\n * Returns a boolean value indicating whether the operation succeeded.\n *\n * Emits a {Transfer} event.\n */\n function transfer(address to, uint256 amount) external returns (bool);\n\n /**\n * @dev Returns the remaining number of tokens that `spender` will be\n * allowed to spend on behalf of `owner` through {transferFrom}. This is\n * zero by default.\n *\n * This value changes when {approve} or {transferFrom} are called.\n */\n function allowance(address owner, address spender) external view returns (uint256);\n\n /**\n * @dev Sets `amount` as the allowance of `spender` over the caller's tokens.\n *\n * Returns a boolean value indicating whether the operation succeeded.\n *\n * IMPORTANT: Beware that changing an allowance with this method brings the risk\n * that someone may use both the old and the new allowance by unfortunate\n * transaction ordering. One possible solution to mitigate this race\n * condition is to first reduce the spender's allowance to 0 and set the\n * desired value afterwards:\n * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729\n *\n * Emits an {Approval} event.\n */\n function approve(address spender, uint256 amount) external returns (bool);\n\n /**\n * @dev Moves `amount` tokens from `from` to `to` using the\n * allowance mechanism. `amount` is then deducted from the caller's\n * allowance.\n *\n * Returns a boolean value indicating whether the operation succeeded.\n *\n * Emits a {Transfer} event.\n */\n function transferFrom(\n address from,\n address to,\n uint256 amount\n ) external returns (bool);\n}\n" + }, + "@openzeppelin/contracts-upgradeable/token/ERC721/extensions/IERC721MetadataUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (token/ERC721/extensions/IERC721Metadata.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../IERC721Upgradeable.sol\";\n\n/**\n * @title ERC-721 Non-Fungible Token Standard, optional metadata extension\n * @dev See https://eips.ethereum.org/EIPS/eip-721\n */\ninterface IERC721MetadataUpgradeable is IERC721Upgradeable {\n /**\n * @dev Returns the token collection name.\n */\n function name() external view returns (string memory);\n\n /**\n * @dev Returns the token collection symbol.\n */\n function symbol() external view returns (string memory);\n\n /**\n * @dev Returns the Uniform Resource Identifier (URI) for `tokenId` token.\n */\n function tokenURI(uint256 tokenId) external view returns (string memory);\n}\n" + }, + "@openzeppelin/contracts-upgradeable/token/ERC721/IERC721ReceiverUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.6.0) (token/ERC721/IERC721Receiver.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @title ERC721 token receiver interface\n * @dev Interface for any contract that wants to support safeTransfers\n * from ERC721 asset contracts.\n */\ninterface IERC721ReceiverUpgradeable {\n /**\n * @dev Whenever an {IERC721} `tokenId` token is transferred to this contract via {IERC721-safeTransferFrom}\n * by `operator` from `from`, this function is called.\n *\n * It must return its Solidity selector to confirm the token transfer.\n * If any other value is returned or the interface is not implemented by the recipient, the transfer will be reverted.\n *\n * The selector can be obtained in Solidity with `IERC721Receiver.onERC721Received.selector`.\n */\n function onERC721Received(\n address operator,\n address from,\n uint256 tokenId,\n bytes calldata data\n ) external returns (bytes4);\n}\n" + }, + "@openzeppelin/contracts-upgradeable/token/ERC721/IERC721Upgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (token/ERC721/IERC721.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../../utils/introspection/IERC165Upgradeable.sol\";\n\n/**\n * @dev Required interface of an ERC721 compliant contract.\n */\ninterface IERC721Upgradeable is IERC165Upgradeable {\n /**\n * @dev Emitted when `tokenId` token is transferred from `from` to `to`.\n */\n event Transfer(address indexed from, address indexed to, uint256 indexed tokenId);\n\n /**\n * @dev Emitted when `owner` enables `approved` to manage the `tokenId` token.\n */\n event Approval(address indexed owner, address indexed approved, uint256 indexed tokenId);\n\n /**\n * @dev Emitted when `owner` enables or disables (`approved`) `operator` to manage all of its assets.\n */\n event ApprovalForAll(address indexed owner, address indexed operator, bool approved);\n\n /**\n * @dev Returns the number of tokens in ``owner``'s account.\n */\n function balanceOf(address owner) external view returns (uint256 balance);\n\n /**\n * @dev Returns the owner of the `tokenId` token.\n *\n * Requirements:\n *\n * - `tokenId` must exist.\n */\n function ownerOf(uint256 tokenId) external view returns (address owner);\n\n /**\n * @dev Safely transfers `tokenId` token from `from` to `to`.\n *\n * Requirements:\n *\n * - `from` cannot be the zero address.\n * - `to` cannot be the zero address.\n * - `tokenId` token must exist and be owned by `from`.\n * - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}.\n * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.\n *\n * Emits a {Transfer} event.\n */\n function safeTransferFrom(\n address from,\n address to,\n uint256 tokenId,\n bytes calldata data\n ) external;\n\n /**\n * @dev Safely transfers `tokenId` token from `from` to `to`, checking first that contract recipients\n * are aware of the ERC721 protocol to prevent tokens from being forever locked.\n *\n * Requirements:\n *\n * - `from` cannot be the zero address.\n * - `to` cannot be the zero address.\n * - `tokenId` token must exist and be owned by `from`.\n * - If the caller is not `from`, it must have been allowed to move this token by either {approve} or {setApprovalForAll}.\n * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.\n *\n * Emits a {Transfer} event.\n */\n function safeTransferFrom(\n address from,\n address to,\n uint256 tokenId\n ) external;\n\n /**\n * @dev Transfers `tokenId` token from `from` to `to`.\n *\n * WARNING: Usage of this method is discouraged, use {safeTransferFrom} whenever possible.\n *\n * Requirements:\n *\n * - `from` cannot be the zero address.\n * - `to` cannot be the zero address.\n * - `tokenId` token must be owned by `from`.\n * - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}.\n *\n * Emits a {Transfer} event.\n */\n function transferFrom(\n address from,\n address to,\n uint256 tokenId\n ) external;\n\n /**\n * @dev Gives permission to `to` to transfer `tokenId` token to another account.\n * The approval is cleared when the token is transferred.\n *\n * Only a single account can be approved at a time, so approving the zero address clears previous approvals.\n *\n * Requirements:\n *\n * - The caller must own the token or be an approved operator.\n * - `tokenId` must exist.\n *\n * Emits an {Approval} event.\n */\n function approve(address to, uint256 tokenId) external;\n\n /**\n * @dev Approve or remove `operator` as an operator for the caller.\n * Operators can call {transferFrom} or {safeTransferFrom} for any token owned by the caller.\n *\n * Requirements:\n *\n * - The `operator` cannot be the caller.\n *\n * Emits an {ApprovalForAll} event.\n */\n function setApprovalForAll(address operator, bool _approved) external;\n\n /**\n * @dev Returns the account approved for `tokenId` token.\n *\n * Requirements:\n *\n * - `tokenId` must exist.\n */\n function getApproved(uint256 tokenId) external view returns (address operator);\n\n /**\n * @dev Returns if the `operator` is allowed to manage all of the assets of `owner`.\n *\n * See {setApprovalForAll}\n */\n function isApprovedForAll(address owner, address operator) external view returns (bool);\n}\n" + }, + "@openzeppelin/contracts-upgradeable/utils/AddressUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (utils/Address.sol)\n\npragma solidity ^0.8.1;\n\n/**\n * @dev Collection of functions related to the address type\n */\nlibrary AddressUpgradeable {\n /**\n * @dev Returns true if `account` is a contract.\n *\n * [IMPORTANT]\n * ====\n * It is unsafe to assume that an address for which this function returns\n * false is an externally-owned account (EOA) and not a contract.\n *\n * Among others, `isContract` will return false for the following\n * types of addresses:\n *\n * - an externally-owned account\n * - a contract in construction\n * - an address where a contract will be created\n * - an address where a contract lived, but was destroyed\n * ====\n *\n * [IMPORTANT]\n * ====\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\n *\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\n * constructor.\n * ====\n */\n function isContract(address account) internal view returns (bool) {\n // This method relies on extcodesize/address.code.length, which returns 0\n // for contracts in construction, since the code is only stored at the end\n // of the constructor execution.\n\n return account.code.length > 0;\n }\n\n /**\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\n * `recipient`, forwarding all available gas and reverting on errors.\n *\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\n * imposed by `transfer`, making them unable to receive funds via\n * `transfer`. {sendValue} removes this limitation.\n *\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\n *\n * IMPORTANT: because control is transferred to `recipient`, care must be\n * taken to not create reentrancy vulnerabilities. Consider using\n * {ReentrancyGuard} or the\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\n */\n function sendValue(address payable recipient, uint256 amount) internal {\n require(address(this).balance >= amount, \"Address: insufficient balance\");\n\n (bool success, ) = recipient.call{value: amount}(\"\");\n require(success, \"Address: unable to send value, recipient may have reverted\");\n }\n\n /**\n * @dev Performs a Solidity function call using a low level `call`. A\n * plain `call` is an unsafe replacement for a function call: use this\n * function instead.\n *\n * If `target` reverts with a revert reason, it is bubbled up by this\n * function (like regular Solidity function calls).\n *\n * Returns the raw returned data. To convert to the expected return value,\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\n *\n * Requirements:\n *\n * - `target` must be a contract.\n * - calling `target` with `data` must not revert.\n *\n * _Available since v3.1._\n */\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionCall(target, data, \"Address: low-level call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\n * `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, 0, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but also transferring `value` wei to `target`.\n *\n * Requirements:\n *\n * - the calling contract must have an ETH balance of at least `value`.\n * - the called Solidity function must be `payable`.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, value, \"Address: low-level call with value failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\n * with `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(address(this).balance >= value, \"Address: insufficient balance for call\");\n require(isContract(target), \"Address: call to non-contract\");\n\n (bool success, bytes memory returndata) = target.call{value: value}(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\n return functionStaticCall(target, data, \"Address: low-level static call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal view returns (bytes memory) {\n require(isContract(target), \"Address: static call to non-contract\");\n\n (bool success, bytes memory returndata) = target.staticcall(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the\n * revert reason using the provided one.\n *\n * _Available since v4.3._\n */\n function verifyCallResult(\n bool success,\n bytes memory returndata,\n string memory errorMessage\n ) internal pure returns (bytes memory) {\n if (success) {\n return returndata;\n } else {\n // Look for revert reason and bubble it up if present\n if (returndata.length > 0) {\n // The easiest way to bubble the revert reason is using memory via assembly\n /// @solidity memory-safe-assembly\n assembly {\n let returndata_size := mload(returndata)\n revert(add(32, returndata), returndata_size)\n }\n } else {\n revert(errorMessage);\n }\n }\n }\n}\n" + }, + "@openzeppelin/contracts-upgradeable/utils/ContextUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)\n\npragma solidity ^0.8.0;\nimport \"../proxy/utils/Initializable.sol\";\n\n/**\n * @dev Provides information about the current execution context, including the\n * sender of the transaction and its data. While these are generally available\n * via msg.sender and msg.data, they should not be accessed in such a direct\n * manner, since when dealing with meta-transactions the account sending and\n * paying for execution may not be the actual sender (as far as an application\n * is concerned).\n *\n * This contract is only required for intermediate, library-like contracts.\n */\nabstract contract ContextUpgradeable is Initializable {\n function __Context_init() internal onlyInitializing {\n }\n\n function __Context_init_unchained() internal onlyInitializing {\n }\n function _msgSender() internal view virtual returns (address) {\n return msg.sender;\n }\n\n function _msgData() internal view virtual returns (bytes calldata) {\n return msg.data;\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[50] private __gap;\n}\n" + }, + "@openzeppelin/contracts-upgradeable/utils/CountersUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (utils/Counters.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @title Counters\n * @author Matt Condon (@shrugs)\n * @dev Provides counters that can only be incremented, decremented or reset. This can be used e.g. to track the number\n * of elements in a mapping, issuing ERC721 ids, or counting request ids.\n *\n * Include with `using Counters for Counters.Counter;`\n */\nlibrary CountersUpgradeable {\n struct Counter {\n // This variable should never be directly accessed by users of the library: interactions must be restricted to\n // the library's function. As of Solidity v0.5.2, this cannot be enforced, though there is a proposal to add\n // this feature: see https://github.com/ethereum/solidity/issues/4637\n uint256 _value; // default: 0\n }\n\n function current(Counter storage counter) internal view returns (uint256) {\n return counter._value;\n }\n\n function increment(Counter storage counter) internal {\n unchecked {\n counter._value += 1;\n }\n }\n\n function decrement(Counter storage counter) internal {\n uint256 value = counter._value;\n require(value > 0, \"Counter: decrement overflow\");\n unchecked {\n counter._value = value - 1;\n }\n }\n\n function reset(Counter storage counter) internal {\n counter._value = 0;\n }\n}\n" + }, + "@openzeppelin/contracts-upgradeable/utils/cryptography/draft-EIP712Upgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (utils/cryptography/draft-EIP712.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./ECDSAUpgradeable.sol\";\nimport \"../../proxy/utils/Initializable.sol\";\n\n/**\n * @dev https://eips.ethereum.org/EIPS/eip-712[EIP 712] is a standard for hashing and signing of typed structured data.\n *\n * The encoding specified in the EIP is very generic, and such a generic implementation in Solidity is not feasible,\n * thus this contract does not implement the encoding itself. Protocols need to implement the type-specific encoding\n * they need in their contracts using a combination of `abi.encode` and `keccak256`.\n *\n * This contract implements the EIP 712 domain separator ({_domainSeparatorV4}) that is used as part of the encoding\n * scheme, and the final step of the encoding to obtain the message digest that is then signed via ECDSA\n * ({_hashTypedDataV4}).\n *\n * The implementation of the domain separator was designed to be as efficient as possible while still properly updating\n * the chain id to protect against replay attacks on an eventual fork of the chain.\n *\n * NOTE: This contract implements the version of the encoding known as \"v4\", as implemented by the JSON RPC method\n * https://docs.metamask.io/guide/signing-data.html[`eth_signTypedDataV4` in MetaMask].\n *\n * _Available since v3.4._\n *\n * @custom:storage-size 52\n */\nabstract contract EIP712Upgradeable is Initializable {\n /* solhint-disable var-name-mixedcase */\n bytes32 private _HASHED_NAME;\n bytes32 private _HASHED_VERSION;\n bytes32 private constant _TYPE_HASH = keccak256(\"EIP712Domain(string name,string version,uint256 chainId,address verifyingContract)\");\n\n /* solhint-enable var-name-mixedcase */\n\n /**\n * @dev Initializes the domain separator and parameter caches.\n *\n * The meaning of `name` and `version` is specified in\n * https://eips.ethereum.org/EIPS/eip-712#definition-of-domainseparator[EIP 712]:\n *\n * - `name`: the user readable name of the signing domain, i.e. the name of the DApp or the protocol.\n * - `version`: the current major version of the signing domain.\n *\n * NOTE: These parameters cannot be changed except through a xref:learn::upgrading-smart-contracts.adoc[smart\n * contract upgrade].\n */\n function __EIP712_init(string memory name, string memory version) internal onlyInitializing {\n __EIP712_init_unchained(name, version);\n }\n\n function __EIP712_init_unchained(string memory name, string memory version) internal onlyInitializing {\n bytes32 hashedName = keccak256(bytes(name));\n bytes32 hashedVersion = keccak256(bytes(version));\n _HASHED_NAME = hashedName;\n _HASHED_VERSION = hashedVersion;\n }\n\n /**\n * @dev Returns the domain separator for the current chain.\n */\n function _domainSeparatorV4() internal view returns (bytes32) {\n return _buildDomainSeparator(_TYPE_HASH, _EIP712NameHash(), _EIP712VersionHash());\n }\n\n function _buildDomainSeparator(\n bytes32 typeHash,\n bytes32 nameHash,\n bytes32 versionHash\n ) private view returns (bytes32) {\n return keccak256(abi.encode(typeHash, nameHash, versionHash, block.chainid, address(this)));\n }\n\n /**\n * @dev Given an already https://eips.ethereum.org/EIPS/eip-712#definition-of-hashstruct[hashed struct], this\n * function returns the hash of the fully encoded EIP712 message for this domain.\n *\n * This hash can be used together with {ECDSA-recover} to obtain the signer of a message. For example:\n *\n * ```solidity\n * bytes32 digest = _hashTypedDataV4(keccak256(abi.encode(\n * keccak256(\"Mail(address to,string contents)\"),\n * mailTo,\n * keccak256(bytes(mailContents))\n * )));\n * address signer = ECDSA.recover(digest, signature);\n * ```\n */\n function _hashTypedDataV4(bytes32 structHash) internal view virtual returns (bytes32) {\n return ECDSAUpgradeable.toTypedDataHash(_domainSeparatorV4(), structHash);\n }\n\n /**\n * @dev The hash of the name parameter for the EIP712 domain.\n *\n * NOTE: This function reads from storage by default, but can be redefined to return a constant value if gas costs\n * are a concern.\n */\n function _EIP712NameHash() internal virtual view returns (bytes32) {\n return _HASHED_NAME;\n }\n\n /**\n * @dev The hash of the version parameter for the EIP712 domain.\n *\n * NOTE: This function reads from storage by default, but can be redefined to return a constant value if gas costs\n * are a concern.\n */\n function _EIP712VersionHash() internal virtual view returns (bytes32) {\n return _HASHED_VERSION;\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[50] private __gap;\n}\n" + }, + "@openzeppelin/contracts-upgradeable/utils/cryptography/ECDSAUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (utils/cryptography/ECDSA.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../StringsUpgradeable.sol\";\n\n/**\n * @dev Elliptic Curve Digital Signature Algorithm (ECDSA) operations.\n *\n * These functions can be used to verify that a message was signed by the holder\n * of the private keys of a given address.\n */\nlibrary ECDSAUpgradeable {\n enum RecoverError {\n NoError,\n InvalidSignature,\n InvalidSignatureLength,\n InvalidSignatureS,\n InvalidSignatureV\n }\n\n function _throwError(RecoverError error) private pure {\n if (error == RecoverError.NoError) {\n return; // no error: do nothing\n } else if (error == RecoverError.InvalidSignature) {\n revert(\"ECDSA: invalid signature\");\n } else if (error == RecoverError.InvalidSignatureLength) {\n revert(\"ECDSA: invalid signature length\");\n } else if (error == RecoverError.InvalidSignatureS) {\n revert(\"ECDSA: invalid signature 's' value\");\n } else if (error == RecoverError.InvalidSignatureV) {\n revert(\"ECDSA: invalid signature 'v' value\");\n }\n }\n\n /**\n * @dev Returns the address that signed a hashed message (`hash`) with\n * `signature` or error string. This address can then be used for verification purposes.\n *\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\n * this function rejects them by requiring the `s` value to be in the lower\n * half order, and the `v` value to be either 27 or 28.\n *\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\n * verification to be secure: it is possible to craft signatures that\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\n * this is by receiving a hash of the original message (which may otherwise\n * be too long), and then calling {toEthSignedMessageHash} on it.\n *\n * Documentation for signature generation:\n * - with https://web3js.readthedocs.io/en/v1.3.4/web3-eth-accounts.html#sign[Web3.js]\n * - with https://docs.ethers.io/v5/api/signer/#Signer-signMessage[ethers]\n *\n * _Available since v4.3._\n */\n function tryRecover(bytes32 hash, bytes memory signature) internal pure returns (address, RecoverError) {\n // Check the signature length\n // - case 65: r,s,v signature (standard)\n // - case 64: r,vs signature (cf https://eips.ethereum.org/EIPS/eip-2098) _Available since v4.1._\n if (signature.length == 65) {\n bytes32 r;\n bytes32 s;\n uint8 v;\n // ecrecover takes the signature parameters, and the only way to get them\n // currently is to use assembly.\n /// @solidity memory-safe-assembly\n assembly {\n r := mload(add(signature, 0x20))\n s := mload(add(signature, 0x40))\n v := byte(0, mload(add(signature, 0x60)))\n }\n return tryRecover(hash, v, r, s);\n } else if (signature.length == 64) {\n bytes32 r;\n bytes32 vs;\n // ecrecover takes the signature parameters, and the only way to get them\n // currently is to use assembly.\n /// @solidity memory-safe-assembly\n assembly {\n r := mload(add(signature, 0x20))\n vs := mload(add(signature, 0x40))\n }\n return tryRecover(hash, r, vs);\n } else {\n return (address(0), RecoverError.InvalidSignatureLength);\n }\n }\n\n /**\n * @dev Returns the address that signed a hashed message (`hash`) with\n * `signature`. This address can then be used for verification purposes.\n *\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\n * this function rejects them by requiring the `s` value to be in the lower\n * half order, and the `v` value to be either 27 or 28.\n *\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\n * verification to be secure: it is possible to craft signatures that\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\n * this is by receiving a hash of the original message (which may otherwise\n * be too long), and then calling {toEthSignedMessageHash} on it.\n */\n function recover(bytes32 hash, bytes memory signature) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, signature);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Overload of {ECDSA-tryRecover} that receives the `r` and `vs` short-signature fields separately.\n *\n * See https://eips.ethereum.org/EIPS/eip-2098[EIP-2098 short signatures]\n *\n * _Available since v4.3._\n */\n function tryRecover(\n bytes32 hash,\n bytes32 r,\n bytes32 vs\n ) internal pure returns (address, RecoverError) {\n bytes32 s = vs & bytes32(0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff);\n uint8 v = uint8((uint256(vs) >> 255) + 27);\n return tryRecover(hash, v, r, s);\n }\n\n /**\n * @dev Overload of {ECDSA-recover} that receives the `r and `vs` short-signature fields separately.\n *\n * _Available since v4.2._\n */\n function recover(\n bytes32 hash,\n bytes32 r,\n bytes32 vs\n ) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, r, vs);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Overload of {ECDSA-tryRecover} that receives the `v`,\n * `r` and `s` signature fields separately.\n *\n * _Available since v4.3._\n */\n function tryRecover(\n bytes32 hash,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) internal pure returns (address, RecoverError) {\n // EIP-2 still allows signature malleability for ecrecover(). Remove this possibility and make the signature\n // unique. Appendix F in the Ethereum Yellow paper (https://ethereum.github.io/yellowpaper/paper.pdf), defines\n // the valid range for s in (301): 0 < s < secp256k1n ÷ 2 + 1, and for v in (302): v ∈ {27, 28}. Most\n // signatures from current libraries generate a unique signature with an s-value in the lower half order.\n //\n // If your library generates malleable signatures, such as s-values in the upper range, calculate a new s-value\n // with 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141 - s1 and flip v from 27 to 28 or\n // vice versa. If your library also generates signatures with 0/1 for v instead 27/28, add 27 to v to accept\n // these malleable signatures as well.\n if (uint256(s) > 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D576E7357A4501DDFE92F46681B20A0) {\n return (address(0), RecoverError.InvalidSignatureS);\n }\n if (v != 27 && v != 28) {\n return (address(0), RecoverError.InvalidSignatureV);\n }\n\n // If the signature is valid (and not malleable), return the signer address\n address signer = ecrecover(hash, v, r, s);\n if (signer == address(0)) {\n return (address(0), RecoverError.InvalidSignature);\n }\n\n return (signer, RecoverError.NoError);\n }\n\n /**\n * @dev Overload of {ECDSA-recover} that receives the `v`,\n * `r` and `s` signature fields separately.\n */\n function recover(\n bytes32 hash,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, v, r, s);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Returns an Ethereum Signed Message, created from a `hash`. This\n * produces hash corresponding to the one signed with the\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\n * JSON-RPC method as part of EIP-191.\n *\n * See {recover}.\n */\n function toEthSignedMessageHash(bytes32 hash) internal pure returns (bytes32) {\n // 32 is the length in bytes of hash,\n // enforced by the type signature above\n return keccak256(abi.encodePacked(\"\\x19Ethereum Signed Message:\\n32\", hash));\n }\n\n /**\n * @dev Returns an Ethereum Signed Message, created from `s`. This\n * produces hash corresponding to the one signed with the\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\n * JSON-RPC method as part of EIP-191.\n *\n * See {recover}.\n */\n function toEthSignedMessageHash(bytes memory s) internal pure returns (bytes32) {\n return keccak256(abi.encodePacked(\"\\x19Ethereum Signed Message:\\n\", StringsUpgradeable.toString(s.length), s));\n }\n\n /**\n * @dev Returns an Ethereum Signed Typed Data, created from a\n * `domainSeparator` and a `structHash`. This produces hash corresponding\n * to the one signed with the\n * https://eips.ethereum.org/EIPS/eip-712[`eth_signTypedData`]\n * JSON-RPC method as part of EIP-712.\n *\n * See {recover}.\n */\n function toTypedDataHash(bytes32 domainSeparator, bytes32 structHash) internal pure returns (bytes32) {\n return keccak256(abi.encodePacked(\"\\x19\\x01\", domainSeparator, structHash));\n }\n}\n" + }, + "@openzeppelin/contracts-upgradeable/utils/introspection/ERC165Upgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (utils/introspection/ERC165.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./IERC165Upgradeable.sol\";\nimport \"../../proxy/utils/Initializable.sol\";\n\n/**\n * @dev Implementation of the {IERC165} interface.\n *\n * Contracts that want to implement ERC165 should inherit from this contract and override {supportsInterface} to check\n * for the additional interface id that will be supported. For example:\n *\n * ```solidity\n * function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {\n * return interfaceId == type(MyInterface).interfaceId || super.supportsInterface(interfaceId);\n * }\n * ```\n *\n * Alternatively, {ERC165Storage} provides an easier to use but more expensive implementation.\n */\nabstract contract ERC165Upgradeable is Initializable, IERC165Upgradeable {\n function __ERC165_init() internal onlyInitializing {\n }\n\n function __ERC165_init_unchained() internal onlyInitializing {\n }\n /**\n * @dev See {IERC165-supportsInterface}.\n */\n function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {\n return interfaceId == type(IERC165Upgradeable).interfaceId;\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[50] private __gap;\n}\n" + }, + "@openzeppelin/contracts-upgradeable/utils/introspection/IERC165Upgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (utils/introspection/IERC165.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Interface of the ERC165 standard, as defined in the\n * https://eips.ethereum.org/EIPS/eip-165[EIP].\n *\n * Implementers can declare support of contract interfaces, which can then be\n * queried by others ({ERC165Checker}).\n *\n * For an implementation, see {ERC165}.\n */\ninterface IERC165Upgradeable {\n /**\n * @dev Returns true if this contract implements the interface defined by\n * `interfaceId`. See the corresponding\n * https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified[EIP section]\n * to learn more about how these ids are created.\n *\n * This function call must use less than 30 000 gas.\n */\n function supportsInterface(bytes4 interfaceId) external view returns (bool);\n}\n" + }, + "@openzeppelin/contracts-upgradeable/utils/StringsUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (utils/Strings.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev String operations.\n */\nlibrary StringsUpgradeable {\n bytes16 private constant _HEX_SYMBOLS = \"0123456789abcdef\";\n uint8 private constant _ADDRESS_LENGTH = 20;\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` decimal representation.\n */\n function toString(uint256 value) internal pure returns (string memory) {\n // Inspired by OraclizeAPI's implementation - MIT licence\n // https://github.com/oraclize/ethereum-api/blob/b42146b063c7d6ee1358846c198246239e9360e8/oraclizeAPI_0.4.25.sol\n\n if (value == 0) {\n return \"0\";\n }\n uint256 temp = value;\n uint256 digits;\n while (temp != 0) {\n digits++;\n temp /= 10;\n }\n bytes memory buffer = new bytes(digits);\n while (value != 0) {\n digits -= 1;\n buffer[digits] = bytes1(uint8(48 + uint256(value % 10)));\n value /= 10;\n }\n return string(buffer);\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation.\n */\n function toHexString(uint256 value) internal pure returns (string memory) {\n if (value == 0) {\n return \"0x00\";\n }\n uint256 temp = value;\n uint256 length = 0;\n while (temp != 0) {\n length++;\n temp >>= 8;\n }\n return toHexString(value, length);\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length.\n */\n function toHexString(uint256 value, uint256 length) internal pure returns (string memory) {\n bytes memory buffer = new bytes(2 * length + 2);\n buffer[0] = \"0\";\n buffer[1] = \"x\";\n for (uint256 i = 2 * length + 1; i > 1; --i) {\n buffer[i] = _HEX_SYMBOLS[value & 0xf];\n value >>= 4;\n }\n require(value == 0, \"Strings: hex length insufficient\");\n return string(buffer);\n }\n\n /**\n * @dev Converts an `address` with fixed length of 20 bytes to its not checksummed ASCII `string` hexadecimal representation.\n */\n function toHexString(address addr) internal pure returns (string memory) {\n return toHexString(uint256(uint160(addr)), _ADDRESS_LENGTH);\n }\n}\n" + }, + "@openzeppelin/contracts-upgradeable/utils/structs/EnumerableSetUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (utils/structs/EnumerableSet.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Library for managing\n * https://en.wikipedia.org/wiki/Set_(abstract_data_type)[sets] of primitive\n * types.\n *\n * Sets have the following properties:\n *\n * - Elements are added, removed, and checked for existence in constant time\n * (O(1)).\n * - Elements are enumerated in O(n). No guarantees are made on the ordering.\n *\n * ```\n * contract Example {\n * // Add the library methods\n * using EnumerableSet for EnumerableSet.AddressSet;\n *\n * // Declare a set state variable\n * EnumerableSet.AddressSet private mySet;\n * }\n * ```\n *\n * As of v3.3.0, sets of type `bytes32` (`Bytes32Set`), `address` (`AddressSet`)\n * and `uint256` (`UintSet`) are supported.\n *\n * [WARNING]\n * ====\n * Trying to delete such a structure from storage will likely result in data corruption, rendering the structure unusable.\n * See https://github.com/ethereum/solidity/pull/11843[ethereum/solidity#11843] for more info.\n *\n * In order to clean an EnumerableSet, you can either remove all elements one by one or create a fresh instance using an array of EnumerableSet.\n * ====\n */\nlibrary EnumerableSetUpgradeable {\n // To implement this library for multiple types with as little code\n // repetition as possible, we write it in terms of a generic Set type with\n // bytes32 values.\n // The Set implementation uses private functions, and user-facing\n // implementations (such as AddressSet) are just wrappers around the\n // underlying Set.\n // This means that we can only create new EnumerableSets for types that fit\n // in bytes32.\n\n struct Set {\n // Storage of set values\n bytes32[] _values;\n // Position of the value in the `values` array, plus 1 because index 0\n // means a value is not in the set.\n mapping(bytes32 => uint256) _indexes;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function _add(Set storage set, bytes32 value) private returns (bool) {\n if (!_contains(set, value)) {\n set._values.push(value);\n // The value is stored at length-1, but we add 1 to all indexes\n // and use 0 as a sentinel value\n set._indexes[value] = set._values.length;\n return true;\n } else {\n return false;\n }\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function _remove(Set storage set, bytes32 value) private returns (bool) {\n // We read and store the value's index to prevent multiple reads from the same storage slot\n uint256 valueIndex = set._indexes[value];\n\n if (valueIndex != 0) {\n // Equivalent to contains(set, value)\n // To delete an element from the _values array in O(1), we swap the element to delete with the last one in\n // the array, and then remove the last element (sometimes called as 'swap and pop').\n // This modifies the order of the array, as noted in {at}.\n\n uint256 toDeleteIndex = valueIndex - 1;\n uint256 lastIndex = set._values.length - 1;\n\n if (lastIndex != toDeleteIndex) {\n bytes32 lastValue = set._values[lastIndex];\n\n // Move the last value to the index where the value to delete is\n set._values[toDeleteIndex] = lastValue;\n // Update the index for the moved value\n set._indexes[lastValue] = valueIndex; // Replace lastValue's index to valueIndex\n }\n\n // Delete the slot where the moved value was stored\n set._values.pop();\n\n // Delete the index for the deleted slot\n delete set._indexes[value];\n\n return true;\n } else {\n return false;\n }\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function _contains(Set storage set, bytes32 value) private view returns (bool) {\n return set._indexes[value] != 0;\n }\n\n /**\n * @dev Returns the number of values on the set. O(1).\n */\n function _length(Set storage set) private view returns (uint256) {\n return set._values.length;\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function _at(Set storage set, uint256 index) private view returns (bytes32) {\n return set._values[index];\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function _values(Set storage set) private view returns (bytes32[] memory) {\n return set._values;\n }\n\n // Bytes32Set\n\n struct Bytes32Set {\n Set _inner;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function add(Bytes32Set storage set, bytes32 value) internal returns (bool) {\n return _add(set._inner, value);\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function remove(Bytes32Set storage set, bytes32 value) internal returns (bool) {\n return _remove(set._inner, value);\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function contains(Bytes32Set storage set, bytes32 value) internal view returns (bool) {\n return _contains(set._inner, value);\n }\n\n /**\n * @dev Returns the number of values in the set. O(1).\n */\n function length(Bytes32Set storage set) internal view returns (uint256) {\n return _length(set._inner);\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function at(Bytes32Set storage set, uint256 index) internal view returns (bytes32) {\n return _at(set._inner, index);\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function values(Bytes32Set storage set) internal view returns (bytes32[] memory) {\n return _values(set._inner);\n }\n\n // AddressSet\n\n struct AddressSet {\n Set _inner;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function add(AddressSet storage set, address value) internal returns (bool) {\n return _add(set._inner, bytes32(uint256(uint160(value))));\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function remove(AddressSet storage set, address value) internal returns (bool) {\n return _remove(set._inner, bytes32(uint256(uint160(value))));\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function contains(AddressSet storage set, address value) internal view returns (bool) {\n return _contains(set._inner, bytes32(uint256(uint160(value))));\n }\n\n /**\n * @dev Returns the number of values in the set. O(1).\n */\n function length(AddressSet storage set) internal view returns (uint256) {\n return _length(set._inner);\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function at(AddressSet storage set, uint256 index) internal view returns (address) {\n return address(uint160(uint256(_at(set._inner, index))));\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function values(AddressSet storage set) internal view returns (address[] memory) {\n bytes32[] memory store = _values(set._inner);\n address[] memory result;\n\n /// @solidity memory-safe-assembly\n assembly {\n result := store\n }\n\n return result;\n }\n\n // UintSet\n\n struct UintSet {\n Set _inner;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function add(UintSet storage set, uint256 value) internal returns (bool) {\n return _add(set._inner, bytes32(value));\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function remove(UintSet storage set, uint256 value) internal returns (bool) {\n return _remove(set._inner, bytes32(value));\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function contains(UintSet storage set, uint256 value) internal view returns (bool) {\n return _contains(set._inner, bytes32(value));\n }\n\n /**\n * @dev Returns the number of values on the set. O(1).\n */\n function length(UintSet storage set) internal view returns (uint256) {\n return _length(set._inner);\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function at(UintSet storage set, uint256 index) internal view returns (uint256) {\n return uint256(_at(set._inner, index));\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function values(UintSet storage set) internal view returns (uint256[] memory) {\n bytes32[] memory store = _values(set._inner);\n uint256[] memory result;\n\n /// @solidity memory-safe-assembly\n assembly {\n result := store\n }\n\n return result;\n }\n}\n" + }, + "@openzeppelin/contracts/access/Ownable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (access/Ownable.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../utils/Context.sol\";\n\n/**\n * @dev Contract module which provides a basic access control mechanism, where\n * there is an account (an owner) that can be granted exclusive access to\n * specific functions.\n *\n * By default, the owner account will be the one that deploys the contract. This\n * can later be changed with {transferOwnership}.\n *\n * This module is used through inheritance. It will make available the modifier\n * `onlyOwner`, which can be applied to your functions to restrict their use to\n * the owner.\n */\nabstract contract Ownable is Context {\n address private _owner;\n\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\n\n /**\n * @dev Initializes the contract setting the deployer as the initial owner.\n */\n constructor() {\n _transferOwnership(_msgSender());\n }\n\n /**\n * @dev Throws if called by any account other than the owner.\n */\n modifier onlyOwner() {\n _checkOwner();\n _;\n }\n\n /**\n * @dev Returns the address of the current owner.\n */\n function owner() public view virtual returns (address) {\n return _owner;\n }\n\n /**\n * @dev Throws if the sender is not the owner.\n */\n function _checkOwner() internal view virtual {\n require(owner() == _msgSender(), \"Ownable: caller is not the owner\");\n }\n\n /**\n * @dev Leaves the contract without owner. It will not be possible to call\n * `onlyOwner` functions anymore. Can only be called by the current owner.\n *\n * NOTE: Renouncing ownership will leave the contract without an owner,\n * thereby removing any functionality that is only available to the owner.\n */\n function renounceOwnership() public virtual onlyOwner {\n _transferOwnership(address(0));\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Can only be called by the current owner.\n */\n function transferOwnership(address newOwner) public virtual onlyOwner {\n require(newOwner != address(0), \"Ownable: new owner is the zero address\");\n _transferOwnership(newOwner);\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Internal function without access restriction.\n */\n function _transferOwnership(address newOwner) internal virtual {\n address oldOwner = _owner;\n _owner = newOwner;\n emit OwnershipTransferred(oldOwner, newOwner);\n }\n}\n" + }, + "@openzeppelin/contracts/interfaces/draft-IERC1822.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.5.0) (interfaces/draft-IERC1822.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev ERC1822: Universal Upgradeable Proxy Standard (UUPS) documents a method for upgradeability through a simplified\n * proxy whose upgrades are fully controlled by the current implementation.\n */\ninterface IERC1822Proxiable {\n /**\n * @dev Returns the storage slot that the proxiable contract assumes is being used to store the implementation\n * address.\n *\n * IMPORTANT: A proxy pointing at a proxiable contract should not be considered proxiable itself, because this risks\n * bricking a proxy that upgrades to it, by delegating to itself until out of gas. Thus it is critical that this\n * function revert if invoked through a proxy.\n */\n function proxiableUUID() external view returns (bytes32);\n}\n" + }, + "@openzeppelin/contracts/interfaces/IERC3156FlashBorrower.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (interfaces/IERC3156FlashBorrower.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Interface of the ERC3156 FlashBorrower, as defined in\n * https://eips.ethereum.org/EIPS/eip-3156[ERC-3156].\n *\n * _Available since v4.1._\n */\ninterface IERC3156FlashBorrower {\n /**\n * @dev Receive a flash loan.\n * @param initiator The initiator of the loan.\n * @param token The loan currency.\n * @param amount The amount of tokens lent.\n * @param fee The additional amount of tokens to repay.\n * @param data Arbitrary data structure, intended to contain user-defined parameters.\n * @return The keccak256 hash of \"IERC3156FlashBorrower.onFlashLoan\"\n */\n function onFlashLoan(\n address initiator,\n address token,\n uint256 amount,\n uint256 fee,\n bytes calldata data\n ) external returns (bytes32);\n}\n" + }, + "@openzeppelin/contracts/interfaces/IERC3156FlashLender.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (interfaces/IERC3156FlashLender.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./IERC3156FlashBorrower.sol\";\n\n/**\n * @dev Interface of the ERC3156 FlashLender, as defined in\n * https://eips.ethereum.org/EIPS/eip-3156[ERC-3156].\n *\n * _Available since v4.1._\n */\ninterface IERC3156FlashLender {\n /**\n * @dev The amount of currency available to be lended.\n * @param token The loan currency.\n * @return The amount of `token` that can be borrowed.\n */\n function maxFlashLoan(address token) external view returns (uint256);\n\n /**\n * @dev The fee to be charged for a given loan.\n * @param token The loan currency.\n * @param amount The amount of tokens lent.\n * @return The amount of `token` to be charged for the loan, on top of the returned principal.\n */\n function flashFee(address token, uint256 amount) external view returns (uint256);\n\n /**\n * @dev Initiate a flash loan.\n * @param receiver The receiver of the tokens in the loan, and the receiver of the callback.\n * @param token The loan currency.\n * @param amount The amount of tokens lent.\n * @param data Arbitrary data structure, intended to contain user-defined parameters.\n */\n function flashLoan(\n IERC3156FlashBorrower receiver,\n address token,\n uint256 amount,\n bytes calldata data\n ) external returns (bool);\n}\n" + }, + "@openzeppelin/contracts/interfaces/IERC721Metadata.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (interfaces/IERC721Metadata.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../token/ERC721/extensions/IERC721Metadata.sol\";\n" + }, + "@openzeppelin/contracts/proxy/beacon/IBeacon.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (proxy/beacon/IBeacon.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev This is the interface that {BeaconProxy} expects of its beacon.\n */\ninterface IBeacon {\n /**\n * @dev Must return an address that can be used as a delegate call target.\n *\n * {BeaconProxy} will check that this address is a contract.\n */\n function implementation() external view returns (address);\n}\n" + }, + "@openzeppelin/contracts/proxy/ERC1967/ERC1967Proxy.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (proxy/ERC1967/ERC1967Proxy.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../Proxy.sol\";\nimport \"./ERC1967Upgrade.sol\";\n\n/**\n * @dev This contract implements an upgradeable proxy. It is upgradeable because calls are delegated to an\n * implementation address that can be changed. This address is stored in storage in the location specified by\n * https://eips.ethereum.org/EIPS/eip-1967[EIP1967], so that it doesn't conflict with the storage layout of the\n * implementation behind the proxy.\n */\ncontract ERC1967Proxy is Proxy, ERC1967Upgrade {\n /**\n * @dev Initializes the upgradeable proxy with an initial implementation specified by `_logic`.\n *\n * If `_data` is nonempty, it's used as data in a delegate call to `_logic`. This will typically be an encoded\n * function call, and allows initializing the storage of the proxy like a Solidity constructor.\n */\n constructor(address _logic, bytes memory _data) payable {\n _upgradeToAndCall(_logic, _data, false);\n }\n\n /**\n * @dev Returns the current implementation address.\n */\n function _implementation() internal view virtual override returns (address impl) {\n return ERC1967Upgrade._getImplementation();\n }\n}\n" + }, + "@openzeppelin/contracts/proxy/ERC1967/ERC1967Upgrade.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.5.0) (proxy/ERC1967/ERC1967Upgrade.sol)\n\npragma solidity ^0.8.2;\n\nimport \"../beacon/IBeacon.sol\";\nimport \"../../interfaces/draft-IERC1822.sol\";\nimport \"../../utils/Address.sol\";\nimport \"../../utils/StorageSlot.sol\";\n\n/**\n * @dev This abstract contract provides getters and event emitting update functions for\n * https://eips.ethereum.org/EIPS/eip-1967[EIP1967] slots.\n *\n * _Available since v4.1._\n *\n * @custom:oz-upgrades-unsafe-allow delegatecall\n */\nabstract contract ERC1967Upgrade {\n // This is the keccak-256 hash of \"eip1967.proxy.rollback\" subtracted by 1\n bytes32 private constant _ROLLBACK_SLOT = 0x4910fdfa16fed3260ed0e7147f7cc6da11a60208b5b9406d12a635614ffd9143;\n\n /**\n * @dev Storage slot with the address of the current implementation.\n * This is the keccak-256 hash of \"eip1967.proxy.implementation\" subtracted by 1, and is\n * validated in the constructor.\n */\n bytes32 internal constant _IMPLEMENTATION_SLOT = 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc;\n\n /**\n * @dev Emitted when the implementation is upgraded.\n */\n event Upgraded(address indexed implementation);\n\n /**\n * @dev Returns the current implementation address.\n */\n function _getImplementation() internal view returns (address) {\n return StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value;\n }\n\n /**\n * @dev Stores a new address in the EIP1967 implementation slot.\n */\n function _setImplementation(address newImplementation) private {\n require(Address.isContract(newImplementation), \"ERC1967: new implementation is not a contract\");\n StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value = newImplementation;\n }\n\n /**\n * @dev Perform implementation upgrade\n *\n * Emits an {Upgraded} event.\n */\n function _upgradeTo(address newImplementation) internal {\n _setImplementation(newImplementation);\n emit Upgraded(newImplementation);\n }\n\n /**\n * @dev Perform implementation upgrade with additional setup call.\n *\n * Emits an {Upgraded} event.\n */\n function _upgradeToAndCall(\n address newImplementation,\n bytes memory data,\n bool forceCall\n ) internal {\n _upgradeTo(newImplementation);\n if (data.length > 0 || forceCall) {\n Address.functionDelegateCall(newImplementation, data);\n }\n }\n\n /**\n * @dev Perform implementation upgrade with security checks for UUPS proxies, and additional setup call.\n *\n * Emits an {Upgraded} event.\n */\n function _upgradeToAndCallUUPS(\n address newImplementation,\n bytes memory data,\n bool forceCall\n ) internal {\n // Upgrades from old implementations will perform a rollback test. This test requires the new\n // implementation to upgrade back to the old, non-ERC1822 compliant, implementation. Removing\n // this special case will break upgrade paths from old UUPS implementation to new ones.\n if (StorageSlot.getBooleanSlot(_ROLLBACK_SLOT).value) {\n _setImplementation(newImplementation);\n } else {\n try IERC1822Proxiable(newImplementation).proxiableUUID() returns (bytes32 slot) {\n require(slot == _IMPLEMENTATION_SLOT, \"ERC1967Upgrade: unsupported proxiableUUID\");\n } catch {\n revert(\"ERC1967Upgrade: new implementation is not UUPS\");\n }\n _upgradeToAndCall(newImplementation, data, forceCall);\n }\n }\n\n /**\n * @dev Storage slot with the admin of the contract.\n * This is the keccak-256 hash of \"eip1967.proxy.admin\" subtracted by 1, and is\n * validated in the constructor.\n */\n bytes32 internal constant _ADMIN_SLOT = 0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103;\n\n /**\n * @dev Emitted when the admin account has changed.\n */\n event AdminChanged(address previousAdmin, address newAdmin);\n\n /**\n * @dev Returns the current admin.\n */\n function _getAdmin() internal view returns (address) {\n return StorageSlot.getAddressSlot(_ADMIN_SLOT).value;\n }\n\n /**\n * @dev Stores a new address in the EIP1967 admin slot.\n */\n function _setAdmin(address newAdmin) private {\n require(newAdmin != address(0), \"ERC1967: new admin is the zero address\");\n StorageSlot.getAddressSlot(_ADMIN_SLOT).value = newAdmin;\n }\n\n /**\n * @dev Changes the admin of the proxy.\n *\n * Emits an {AdminChanged} event.\n */\n function _changeAdmin(address newAdmin) internal {\n emit AdminChanged(_getAdmin(), newAdmin);\n _setAdmin(newAdmin);\n }\n\n /**\n * @dev The storage slot of the UpgradeableBeacon contract which defines the implementation for this proxy.\n * This is bytes32(uint256(keccak256('eip1967.proxy.beacon')) - 1)) and is validated in the constructor.\n */\n bytes32 internal constant _BEACON_SLOT = 0xa3f0ad74e5423aebfd80d3ef4346578335a9a72aeaee59ff6cb3582b35133d50;\n\n /**\n * @dev Emitted when the beacon is upgraded.\n */\n event BeaconUpgraded(address indexed beacon);\n\n /**\n * @dev Returns the current beacon.\n */\n function _getBeacon() internal view returns (address) {\n return StorageSlot.getAddressSlot(_BEACON_SLOT).value;\n }\n\n /**\n * @dev Stores a new beacon in the EIP1967 beacon slot.\n */\n function _setBeacon(address newBeacon) private {\n require(Address.isContract(newBeacon), \"ERC1967: new beacon is not a contract\");\n require(\n Address.isContract(IBeacon(newBeacon).implementation()),\n \"ERC1967: beacon implementation is not a contract\"\n );\n StorageSlot.getAddressSlot(_BEACON_SLOT).value = newBeacon;\n }\n\n /**\n * @dev Perform beacon upgrade with additional setup call. Note: This upgrades the address of the beacon, it does\n * not upgrade the implementation contained in the beacon (see {UpgradeableBeacon-_setImplementation} for that).\n *\n * Emits a {BeaconUpgraded} event.\n */\n function _upgradeBeaconToAndCall(\n address newBeacon,\n bytes memory data,\n bool forceCall\n ) internal {\n _setBeacon(newBeacon);\n emit BeaconUpgraded(newBeacon);\n if (data.length > 0 || forceCall) {\n Address.functionDelegateCall(IBeacon(newBeacon).implementation(), data);\n }\n }\n}\n" + }, + "@openzeppelin/contracts/proxy/Proxy.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.6.0) (proxy/Proxy.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev This abstract contract provides a fallback function that delegates all calls to another contract using the EVM\n * instruction `delegatecall`. We refer to the second contract as the _implementation_ behind the proxy, and it has to\n * be specified by overriding the virtual {_implementation} function.\n *\n * Additionally, delegation to the implementation can be triggered manually through the {_fallback} function, or to a\n * different contract through the {_delegate} function.\n *\n * The success and return data of the delegated call will be returned back to the caller of the proxy.\n */\nabstract contract Proxy {\n /**\n * @dev Delegates the current call to `implementation`.\n *\n * This function does not return to its internal call site, it will return directly to the external caller.\n */\n function _delegate(address implementation) internal virtual {\n assembly {\n // Copy msg.data. We take full control of memory in this inline assembly\n // block because it will not return to Solidity code. We overwrite the\n // Solidity scratch pad at memory position 0.\n calldatacopy(0, 0, calldatasize())\n\n // Call the implementation.\n // out and outsize are 0 because we don't know the size yet.\n let result := delegatecall(gas(), implementation, 0, calldatasize(), 0, 0)\n\n // Copy the returned data.\n returndatacopy(0, 0, returndatasize())\n\n switch result\n // delegatecall returns 0 on error.\n case 0 {\n revert(0, returndatasize())\n }\n default {\n return(0, returndatasize())\n }\n }\n }\n\n /**\n * @dev This is a virtual function that should be overridden so it returns the address to which the fallback function\n * and {_fallback} should delegate.\n */\n function _implementation() internal view virtual returns (address);\n\n /**\n * @dev Delegates the current call to the address returned by `_implementation()`.\n *\n * This function does not return to its internal call site, it will return directly to the external caller.\n */\n function _fallback() internal virtual {\n _beforeFallback();\n _delegate(_implementation());\n }\n\n /**\n * @dev Fallback function that delegates calls to the address returned by `_implementation()`. Will run if no other\n * function in the contract matches the call data.\n */\n fallback() external payable virtual {\n _fallback();\n }\n\n /**\n * @dev Fallback function that delegates calls to the address returned by `_implementation()`. Will run if call data\n * is empty.\n */\n receive() external payable virtual {\n _fallback();\n }\n\n /**\n * @dev Hook that is called before falling back to the implementation. Can happen as part of a manual `_fallback`\n * call, or as part of the Solidity `fallback` or `receive` functions.\n *\n * If overridden should call `super._beforeFallback()`.\n */\n function _beforeFallback() internal virtual {}\n}\n" + }, + "@openzeppelin/contracts/token/ERC20/ERC20.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (token/ERC20/ERC20.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./IERC20.sol\";\nimport \"./extensions/IERC20Metadata.sol\";\nimport \"../../utils/Context.sol\";\n\n/**\n * @dev Implementation of the {IERC20} interface.\n *\n * This implementation is agnostic to the way tokens are created. This means\n * that a supply mechanism has to be added in a derived contract using {_mint}.\n * For a generic mechanism see {ERC20PresetMinterPauser}.\n *\n * TIP: For a detailed writeup see our guide\n * https://forum.zeppelin.solutions/t/how-to-implement-erc20-supply-mechanisms/226[How\n * to implement supply mechanisms].\n *\n * We have followed general OpenZeppelin Contracts guidelines: functions revert\n * instead returning `false` on failure. This behavior is nonetheless\n * conventional and does not conflict with the expectations of ERC20\n * applications.\n *\n * Additionally, an {Approval} event is emitted on calls to {transferFrom}.\n * This allows applications to reconstruct the allowance for all accounts just\n * by listening to said events. Other implementations of the EIP may not emit\n * these events, as it isn't required by the specification.\n *\n * Finally, the non-standard {decreaseAllowance} and {increaseAllowance}\n * functions have been added to mitigate the well-known issues around setting\n * allowances. See {IERC20-approve}.\n */\ncontract ERC20 is Context, IERC20, IERC20Metadata {\n mapping(address => uint256) private _balances;\n\n mapping(address => mapping(address => uint256)) private _allowances;\n\n uint256 private _totalSupply;\n\n string private _name;\n string private _symbol;\n\n /**\n * @dev Sets the values for {name} and {symbol}.\n *\n * The default value of {decimals} is 18. To select a different value for\n * {decimals} you should overload it.\n *\n * All two of these values are immutable: they can only be set once during\n * construction.\n */\n constructor(string memory name_, string memory symbol_) {\n _name = name_;\n _symbol = symbol_;\n }\n\n /**\n * @dev Returns the name of the token.\n */\n function name() public view virtual override returns (string memory) {\n return _name;\n }\n\n /**\n * @dev Returns the symbol of the token, usually a shorter version of the\n * name.\n */\n function symbol() public view virtual override returns (string memory) {\n return _symbol;\n }\n\n /**\n * @dev Returns the number of decimals used to get its user representation.\n * For example, if `decimals` equals `2`, a balance of `505` tokens should\n * be displayed to a user as `5.05` (`505 / 10 ** 2`).\n *\n * Tokens usually opt for a value of 18, imitating the relationship between\n * Ether and Wei. This is the value {ERC20} uses, unless this function is\n * overridden;\n *\n * NOTE: This information is only used for _display_ purposes: it in\n * no way affects any of the arithmetic of the contract, including\n * {IERC20-balanceOf} and {IERC20-transfer}.\n */\n function decimals() public view virtual override returns (uint8) {\n return 18;\n }\n\n /**\n * @dev See {IERC20-totalSupply}.\n */\n function totalSupply() public view virtual override returns (uint256) {\n return _totalSupply;\n }\n\n /**\n * @dev See {IERC20-balanceOf}.\n */\n function balanceOf(address account) public view virtual override returns (uint256) {\n return _balances[account];\n }\n\n /**\n * @dev See {IERC20-transfer}.\n *\n * Requirements:\n *\n * - `to` cannot be the zero address.\n * - the caller must have a balance of at least `amount`.\n */\n function transfer(address to, uint256 amount) public virtual override returns (bool) {\n address owner = _msgSender();\n _transfer(owner, to, amount);\n return true;\n }\n\n /**\n * @dev See {IERC20-allowance}.\n */\n function allowance(address owner, address spender) public view virtual override returns (uint256) {\n return _allowances[owner][spender];\n }\n\n /**\n * @dev See {IERC20-approve}.\n *\n * NOTE: If `amount` is the maximum `uint256`, the allowance is not updated on\n * `transferFrom`. This is semantically equivalent to an infinite approval.\n *\n * Requirements:\n *\n * - `spender` cannot be the zero address.\n */\n function approve(address spender, uint256 amount) public virtual override returns (bool) {\n address owner = _msgSender();\n _approve(owner, spender, amount);\n return true;\n }\n\n /**\n * @dev See {IERC20-transferFrom}.\n *\n * Emits an {Approval} event indicating the updated allowance. This is not\n * required by the EIP. See the note at the beginning of {ERC20}.\n *\n * NOTE: Does not update the allowance if the current allowance\n * is the maximum `uint256`.\n *\n * Requirements:\n *\n * - `from` and `to` cannot be the zero address.\n * - `from` must have a balance of at least `amount`.\n * - the caller must have allowance for ``from``'s tokens of at least\n * `amount`.\n */\n function transferFrom(\n address from,\n address to,\n uint256 amount\n ) public virtual override returns (bool) {\n address spender = _msgSender();\n _spendAllowance(from, spender, amount);\n _transfer(from, to, amount);\n return true;\n }\n\n /**\n * @dev Atomically increases the allowance granted to `spender` by the caller.\n *\n * This is an alternative to {approve} that can be used as a mitigation for\n * problems described in {IERC20-approve}.\n *\n * Emits an {Approval} event indicating the updated allowance.\n *\n * Requirements:\n *\n * - `spender` cannot be the zero address.\n */\n function increaseAllowance(address spender, uint256 addedValue) public virtual returns (bool) {\n address owner = _msgSender();\n _approve(owner, spender, allowance(owner, spender) + addedValue);\n return true;\n }\n\n /**\n * @dev Atomically decreases the allowance granted to `spender` by the caller.\n *\n * This is an alternative to {approve} that can be used as a mitigation for\n * problems described in {IERC20-approve}.\n *\n * Emits an {Approval} event indicating the updated allowance.\n *\n * Requirements:\n *\n * - `spender` cannot be the zero address.\n * - `spender` must have allowance for the caller of at least\n * `subtractedValue`.\n */\n function decreaseAllowance(address spender, uint256 subtractedValue) public virtual returns (bool) {\n address owner = _msgSender();\n uint256 currentAllowance = allowance(owner, spender);\n require(currentAllowance >= subtractedValue, \"ERC20: decreased allowance below zero\");\n unchecked {\n _approve(owner, spender, currentAllowance - subtractedValue);\n }\n\n return true;\n }\n\n /**\n * @dev Moves `amount` of tokens from `from` to `to`.\n *\n * This internal function is equivalent to {transfer}, and can be used to\n * e.g. implement automatic token fees, slashing mechanisms, etc.\n *\n * Emits a {Transfer} event.\n *\n * Requirements:\n *\n * - `from` cannot be the zero address.\n * - `to` cannot be the zero address.\n * - `from` must have a balance of at least `amount`.\n */\n function _transfer(\n address from,\n address to,\n uint256 amount\n ) internal virtual {\n require(from != address(0), \"ERC20: transfer from the zero address\");\n require(to != address(0), \"ERC20: transfer to the zero address\");\n\n _beforeTokenTransfer(from, to, amount);\n\n uint256 fromBalance = _balances[from];\n require(fromBalance >= amount, \"ERC20: transfer amount exceeds balance\");\n unchecked {\n _balances[from] = fromBalance - amount;\n }\n _balances[to] += amount;\n\n emit Transfer(from, to, amount);\n\n _afterTokenTransfer(from, to, amount);\n }\n\n /** @dev Creates `amount` tokens and assigns them to `account`, increasing\n * the total supply.\n *\n * Emits a {Transfer} event with `from` set to the zero address.\n *\n * Requirements:\n *\n * - `account` cannot be the zero address.\n */\n function _mint(address account, uint256 amount) internal virtual {\n require(account != address(0), \"ERC20: mint to the zero address\");\n\n _beforeTokenTransfer(address(0), account, amount);\n\n _totalSupply += amount;\n _balances[account] += amount;\n emit Transfer(address(0), account, amount);\n\n _afterTokenTransfer(address(0), account, amount);\n }\n\n /**\n * @dev Destroys `amount` tokens from `account`, reducing the\n * total supply.\n *\n * Emits a {Transfer} event with `to` set to the zero address.\n *\n * Requirements:\n *\n * - `account` cannot be the zero address.\n * - `account` must have at least `amount` tokens.\n */\n function _burn(address account, uint256 amount) internal virtual {\n require(account != address(0), \"ERC20: burn from the zero address\");\n\n _beforeTokenTransfer(account, address(0), amount);\n\n uint256 accountBalance = _balances[account];\n require(accountBalance >= amount, \"ERC20: burn amount exceeds balance\");\n unchecked {\n _balances[account] = accountBalance - amount;\n }\n _totalSupply -= amount;\n\n emit Transfer(account, address(0), amount);\n\n _afterTokenTransfer(account, address(0), amount);\n }\n\n /**\n * @dev Sets `amount` as the allowance of `spender` over the `owner` s tokens.\n *\n * This internal function is equivalent to `approve`, and can be used to\n * e.g. set automatic allowances for certain subsystems, etc.\n *\n * Emits an {Approval} event.\n *\n * Requirements:\n *\n * - `owner` cannot be the zero address.\n * - `spender` cannot be the zero address.\n */\n function _approve(\n address owner,\n address spender,\n uint256 amount\n ) internal virtual {\n require(owner != address(0), \"ERC20: approve from the zero address\");\n require(spender != address(0), \"ERC20: approve to the zero address\");\n\n _allowances[owner][spender] = amount;\n emit Approval(owner, spender, amount);\n }\n\n /**\n * @dev Updates `owner` s allowance for `spender` based on spent `amount`.\n *\n * Does not update the allowance amount in case of infinite allowance.\n * Revert if not enough allowance is available.\n *\n * Might emit an {Approval} event.\n */\n function _spendAllowance(\n address owner,\n address spender,\n uint256 amount\n ) internal virtual {\n uint256 currentAllowance = allowance(owner, spender);\n if (currentAllowance != type(uint256).max) {\n require(currentAllowance >= amount, \"ERC20: insufficient allowance\");\n unchecked {\n _approve(owner, spender, currentAllowance - amount);\n }\n }\n }\n\n /**\n * @dev Hook that is called before any transfer of tokens. This includes\n * minting and burning.\n *\n * Calling conditions:\n *\n * - when `from` and `to` are both non-zero, `amount` of ``from``'s tokens\n * will be transferred to `to`.\n * - when `from` is zero, `amount` tokens will be minted for `to`.\n * - when `to` is zero, `amount` of ``from``'s tokens will be burned.\n * - `from` and `to` are never both zero.\n *\n * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].\n */\n function _beforeTokenTransfer(\n address from,\n address to,\n uint256 amount\n ) internal virtual {}\n\n /**\n * @dev Hook that is called after any transfer of tokens. This includes\n * minting and burning.\n *\n * Calling conditions:\n *\n * - when `from` and `to` are both non-zero, `amount` of ``from``'s tokens\n * has been transferred to `to`.\n * - when `from` is zero, `amount` tokens have been minted for `to`.\n * - when `to` is zero, `amount` of ``from``'s tokens have been burned.\n * - `from` and `to` are never both zero.\n *\n * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].\n */\n function _afterTokenTransfer(\n address from,\n address to,\n uint256 amount\n ) internal virtual {}\n}\n" + }, + "@openzeppelin/contracts/token/ERC20/extensions/draft-ERC20Permit.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.6.0) (token/ERC20/extensions/draft-ERC20Permit.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./draft-IERC20Permit.sol\";\nimport \"../ERC20.sol\";\nimport \"../../../utils/cryptography/draft-EIP712.sol\";\nimport \"../../../utils/cryptography/ECDSA.sol\";\nimport \"../../../utils/Counters.sol\";\n\n/**\n * @dev Implementation of the ERC20 Permit extension allowing approvals to be made via signatures, as defined in\n * https://eips.ethereum.org/EIPS/eip-2612[EIP-2612].\n *\n * Adds the {permit} method, which can be used to change an account's ERC20 allowance (see {IERC20-allowance}) by\n * presenting a message signed by the account. By not relying on `{IERC20-approve}`, the token holder account doesn't\n * need to send a transaction, and thus is not required to hold Ether at all.\n *\n * _Available since v3.4._\n */\nabstract contract ERC20Permit is ERC20, IERC20Permit, EIP712 {\n using Counters for Counters.Counter;\n\n mapping(address => Counters.Counter) private _nonces;\n\n // solhint-disable-next-line var-name-mixedcase\n bytes32 private constant _PERMIT_TYPEHASH =\n keccak256(\"Permit(address owner,address spender,uint256 value,uint256 nonce,uint256 deadline)\");\n /**\n * @dev In previous versions `_PERMIT_TYPEHASH` was declared as `immutable`.\n * However, to ensure consistency with the upgradeable transpiler, we will continue\n * to reserve a slot.\n * @custom:oz-renamed-from _PERMIT_TYPEHASH\n */\n // solhint-disable-next-line var-name-mixedcase\n bytes32 private _PERMIT_TYPEHASH_DEPRECATED_SLOT;\n\n /**\n * @dev Initializes the {EIP712} domain separator using the `name` parameter, and setting `version` to `\"1\"`.\n *\n * It's a good idea to use the same `name` that is defined as the ERC20 token name.\n */\n constructor(string memory name) EIP712(name, \"1\") {}\n\n /**\n * @dev See {IERC20Permit-permit}.\n */\n function permit(\n address owner,\n address spender,\n uint256 value,\n uint256 deadline,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) public virtual override {\n require(block.timestamp <= deadline, \"ERC20Permit: expired deadline\");\n\n bytes32 structHash = keccak256(abi.encode(_PERMIT_TYPEHASH, owner, spender, value, _useNonce(owner), deadline));\n\n bytes32 hash = _hashTypedDataV4(structHash);\n\n address signer = ECDSA.recover(hash, v, r, s);\n require(signer == owner, \"ERC20Permit: invalid signature\");\n\n _approve(owner, spender, value);\n }\n\n /**\n * @dev See {IERC20Permit-nonces}.\n */\n function nonces(address owner) public view virtual override returns (uint256) {\n return _nonces[owner].current();\n }\n\n /**\n * @dev See {IERC20Permit-DOMAIN_SEPARATOR}.\n */\n // solhint-disable-next-line func-name-mixedcase\n function DOMAIN_SEPARATOR() external view override returns (bytes32) {\n return _domainSeparatorV4();\n }\n\n /**\n * @dev \"Consume a nonce\": return the current value and increment.\n *\n * _Available since v4.1._\n */\n function _useNonce(address owner) internal virtual returns (uint256 current) {\n Counters.Counter storage nonce = _nonces[owner];\n current = nonce.current();\n nonce.increment();\n }\n}\n" + }, + "@openzeppelin/contracts/token/ERC20/extensions/draft-IERC20Permit.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (token/ERC20/extensions/draft-IERC20Permit.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Interface of the ERC20 Permit extension allowing approvals to be made via signatures, as defined in\n * https://eips.ethereum.org/EIPS/eip-2612[EIP-2612].\n *\n * Adds the {permit} method, which can be used to change an account's ERC20 allowance (see {IERC20-allowance}) by\n * presenting a message signed by the account. By not relying on {IERC20-approve}, the token holder account doesn't\n * need to send a transaction, and thus is not required to hold Ether at all.\n */\ninterface IERC20Permit {\n /**\n * @dev Sets `value` as the allowance of `spender` over ``owner``'s tokens,\n * given ``owner``'s signed approval.\n *\n * IMPORTANT: The same issues {IERC20-approve} has related to transaction\n * ordering also apply here.\n *\n * Emits an {Approval} event.\n *\n * Requirements:\n *\n * - `spender` cannot be the zero address.\n * - `deadline` must be a timestamp in the future.\n * - `v`, `r` and `s` must be a valid `secp256k1` signature from `owner`\n * over the EIP712-formatted function arguments.\n * - the signature must use ``owner``'s current nonce (see {nonces}).\n *\n * For more information on the signature format, see the\n * https://eips.ethereum.org/EIPS/eip-2612#specification[relevant EIP\n * section].\n */\n function permit(\n address owner,\n address spender,\n uint256 value,\n uint256 deadline,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) external;\n\n /**\n * @dev Returns the current nonce for `owner`. This value must be\n * included whenever a signature is generated for {permit}.\n *\n * Every successful call to {permit} increases ``owner``'s nonce by one. This\n * prevents a signature from being used multiple times.\n */\n function nonces(address owner) external view returns (uint256);\n\n /**\n * @dev Returns the domain separator used in the encoding of the signature for {permit}, as defined by {EIP712}.\n */\n // solhint-disable-next-line func-name-mixedcase\n function DOMAIN_SEPARATOR() external view returns (bytes32);\n}\n" + }, + "@openzeppelin/contracts/token/ERC20/extensions/IERC20Metadata.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (token/ERC20/extensions/IERC20Metadata.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../IERC20.sol\";\n\n/**\n * @dev Interface for the optional metadata functions from the ERC20 standard.\n *\n * _Available since v4.1._\n */\ninterface IERC20Metadata is IERC20 {\n /**\n * @dev Returns the name of the token.\n */\n function name() external view returns (string memory);\n\n /**\n * @dev Returns the symbol of the token.\n */\n function symbol() external view returns (string memory);\n\n /**\n * @dev Returns the decimals places of the token.\n */\n function decimals() external view returns (uint8);\n}\n" + }, + "@openzeppelin/contracts/token/ERC20/IERC20.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.6.0) (token/ERC20/IERC20.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Interface of the ERC20 standard as defined in the EIP.\n */\ninterface IERC20 {\n /**\n * @dev Emitted when `value` tokens are moved from one account (`from`) to\n * another (`to`).\n *\n * Note that `value` may be zero.\n */\n event Transfer(address indexed from, address indexed to, uint256 value);\n\n /**\n * @dev Emitted when the allowance of a `spender` for an `owner` is set by\n * a call to {approve}. `value` is the new allowance.\n */\n event Approval(address indexed owner, address indexed spender, uint256 value);\n\n /**\n * @dev Returns the amount of tokens in existence.\n */\n function totalSupply() external view returns (uint256);\n\n /**\n * @dev Returns the amount of tokens owned by `account`.\n */\n function balanceOf(address account) external view returns (uint256);\n\n /**\n * @dev Moves `amount` tokens from the caller's account to `to`.\n *\n * Returns a boolean value indicating whether the operation succeeded.\n *\n * Emits a {Transfer} event.\n */\n function transfer(address to, uint256 amount) external returns (bool);\n\n /**\n * @dev Returns the remaining number of tokens that `spender` will be\n * allowed to spend on behalf of `owner` through {transferFrom}. This is\n * zero by default.\n *\n * This value changes when {approve} or {transferFrom} are called.\n */\n function allowance(address owner, address spender) external view returns (uint256);\n\n /**\n * @dev Sets `amount` as the allowance of `spender` over the caller's tokens.\n *\n * Returns a boolean value indicating whether the operation succeeded.\n *\n * IMPORTANT: Beware that changing an allowance with this method brings the risk\n * that someone may use both the old and the new allowance by unfortunate\n * transaction ordering. One possible solution to mitigate this race\n * condition is to first reduce the spender's allowance to 0 and set the\n * desired value afterwards:\n * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729\n *\n * Emits an {Approval} event.\n */\n function approve(address spender, uint256 amount) external returns (bool);\n\n /**\n * @dev Moves `amount` tokens from `from` to `to` using the\n * allowance mechanism. `amount` is then deducted from the caller's\n * allowance.\n *\n * Returns a boolean value indicating whether the operation succeeded.\n *\n * Emits a {Transfer} event.\n */\n function transferFrom(\n address from,\n address to,\n uint256 amount\n ) external returns (bool);\n}\n" + }, + "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (token/ERC20/utils/SafeERC20.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../IERC20.sol\";\nimport \"../extensions/draft-IERC20Permit.sol\";\nimport \"../../../utils/Address.sol\";\n\n/**\n * @title SafeERC20\n * @dev Wrappers around ERC20 operations that throw on failure (when the token\n * contract returns false). Tokens that return no value (and instead revert or\n * throw on failure) are also supported, non-reverting calls are assumed to be\n * successful.\n * To use this library you can add a `using SafeERC20 for IERC20;` statement to your contract,\n * which allows you to call the safe operations as `token.safeTransfer(...)`, etc.\n */\nlibrary SafeERC20 {\n using Address for address;\n\n function safeTransfer(\n IERC20 token,\n address to,\n uint256 value\n ) internal {\n _callOptionalReturn(token, abi.encodeWithSelector(token.transfer.selector, to, value));\n }\n\n function safeTransferFrom(\n IERC20 token,\n address from,\n address to,\n uint256 value\n ) internal {\n _callOptionalReturn(token, abi.encodeWithSelector(token.transferFrom.selector, from, to, value));\n }\n\n /**\n * @dev Deprecated. This function has issues similar to the ones found in\n * {IERC20-approve}, and its usage is discouraged.\n *\n * Whenever possible, use {safeIncreaseAllowance} and\n * {safeDecreaseAllowance} instead.\n */\n function safeApprove(\n IERC20 token,\n address spender,\n uint256 value\n ) internal {\n // safeApprove should only be called when setting an initial allowance,\n // or when resetting it to zero. To increase and decrease it, use\n // 'safeIncreaseAllowance' and 'safeDecreaseAllowance'\n require(\n (value == 0) || (token.allowance(address(this), spender) == 0),\n \"SafeERC20: approve from non-zero to non-zero allowance\"\n );\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, value));\n }\n\n function safeIncreaseAllowance(\n IERC20 token,\n address spender,\n uint256 value\n ) internal {\n uint256 newAllowance = token.allowance(address(this), spender) + value;\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));\n }\n\n function safeDecreaseAllowance(\n IERC20 token,\n address spender,\n uint256 value\n ) internal {\n unchecked {\n uint256 oldAllowance = token.allowance(address(this), spender);\n require(oldAllowance >= value, \"SafeERC20: decreased allowance below zero\");\n uint256 newAllowance = oldAllowance - value;\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));\n }\n }\n\n function safePermit(\n IERC20Permit token,\n address owner,\n address spender,\n uint256 value,\n uint256 deadline,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) internal {\n uint256 nonceBefore = token.nonces(owner);\n token.permit(owner, spender, value, deadline, v, r, s);\n uint256 nonceAfter = token.nonces(owner);\n require(nonceAfter == nonceBefore + 1, \"SafeERC20: permit did not succeed\");\n }\n\n /**\n * @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement\n * on the return value: the return value is optional (but if data is returned, it must not be false).\n * @param token The token targeted by the call.\n * @param data The call data (encoded using abi.encode or one of its variants).\n */\n function _callOptionalReturn(IERC20 token, bytes memory data) private {\n // We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since\n // we're implementing it ourselves. We use {Address.functionCall} to perform this call, which verifies that\n // the target address contains contract code and also asserts for success in the low-level call.\n\n bytes memory returndata = address(token).functionCall(data, \"SafeERC20: low-level call failed\");\n if (returndata.length > 0) {\n // Return data is optional\n require(abi.decode(returndata, (bool)), \"SafeERC20: ERC20 operation did not succeed\");\n }\n }\n}\n" + }, + "@openzeppelin/contracts/token/ERC721/extensions/IERC721Metadata.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (token/ERC721/extensions/IERC721Metadata.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../IERC721.sol\";\n\n/**\n * @title ERC-721 Non-Fungible Token Standard, optional metadata extension\n * @dev See https://eips.ethereum.org/EIPS/eip-721\n */\ninterface IERC721Metadata is IERC721 {\n /**\n * @dev Returns the token collection name.\n */\n function name() external view returns (string memory);\n\n /**\n * @dev Returns the token collection symbol.\n */\n function symbol() external view returns (string memory);\n\n /**\n * @dev Returns the Uniform Resource Identifier (URI) for `tokenId` token.\n */\n function tokenURI(uint256 tokenId) external view returns (string memory);\n}\n" + }, + "@openzeppelin/contracts/token/ERC721/IERC721.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (token/ERC721/IERC721.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../../utils/introspection/IERC165.sol\";\n\n/**\n * @dev Required interface of an ERC721 compliant contract.\n */\ninterface IERC721 is IERC165 {\n /**\n * @dev Emitted when `tokenId` token is transferred from `from` to `to`.\n */\n event Transfer(address indexed from, address indexed to, uint256 indexed tokenId);\n\n /**\n * @dev Emitted when `owner` enables `approved` to manage the `tokenId` token.\n */\n event Approval(address indexed owner, address indexed approved, uint256 indexed tokenId);\n\n /**\n * @dev Emitted when `owner` enables or disables (`approved`) `operator` to manage all of its assets.\n */\n event ApprovalForAll(address indexed owner, address indexed operator, bool approved);\n\n /**\n * @dev Returns the number of tokens in ``owner``'s account.\n */\n function balanceOf(address owner) external view returns (uint256 balance);\n\n /**\n * @dev Returns the owner of the `tokenId` token.\n *\n * Requirements:\n *\n * - `tokenId` must exist.\n */\n function ownerOf(uint256 tokenId) external view returns (address owner);\n\n /**\n * @dev Safely transfers `tokenId` token from `from` to `to`.\n *\n * Requirements:\n *\n * - `from` cannot be the zero address.\n * - `to` cannot be the zero address.\n * - `tokenId` token must exist and be owned by `from`.\n * - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}.\n * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.\n *\n * Emits a {Transfer} event.\n */\n function safeTransferFrom(\n address from,\n address to,\n uint256 tokenId,\n bytes calldata data\n ) external;\n\n /**\n * @dev Safely transfers `tokenId` token from `from` to `to`, checking first that contract recipients\n * are aware of the ERC721 protocol to prevent tokens from being forever locked.\n *\n * Requirements:\n *\n * - `from` cannot be the zero address.\n * - `to` cannot be the zero address.\n * - `tokenId` token must exist and be owned by `from`.\n * - If the caller is not `from`, it must have been allowed to move this token by either {approve} or {setApprovalForAll}.\n * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.\n *\n * Emits a {Transfer} event.\n */\n function safeTransferFrom(\n address from,\n address to,\n uint256 tokenId\n ) external;\n\n /**\n * @dev Transfers `tokenId` token from `from` to `to`.\n *\n * WARNING: Usage of this method is discouraged, use {safeTransferFrom} whenever possible.\n *\n * Requirements:\n *\n * - `from` cannot be the zero address.\n * - `to` cannot be the zero address.\n * - `tokenId` token must be owned by `from`.\n * - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}.\n *\n * Emits a {Transfer} event.\n */\n function transferFrom(\n address from,\n address to,\n uint256 tokenId\n ) external;\n\n /**\n * @dev Gives permission to `to` to transfer `tokenId` token to another account.\n * The approval is cleared when the token is transferred.\n *\n * Only a single account can be approved at a time, so approving the zero address clears previous approvals.\n *\n * Requirements:\n *\n * - The caller must own the token or be an approved operator.\n * - `tokenId` must exist.\n *\n * Emits an {Approval} event.\n */\n function approve(address to, uint256 tokenId) external;\n\n /**\n * @dev Approve or remove `operator` as an operator for the caller.\n * Operators can call {transferFrom} or {safeTransferFrom} for any token owned by the caller.\n *\n * Requirements:\n *\n * - The `operator` cannot be the caller.\n *\n * Emits an {ApprovalForAll} event.\n */\n function setApprovalForAll(address operator, bool _approved) external;\n\n /**\n * @dev Returns the account approved for `tokenId` token.\n *\n * Requirements:\n *\n * - `tokenId` must exist.\n */\n function getApproved(uint256 tokenId) external view returns (address operator);\n\n /**\n * @dev Returns if the `operator` is allowed to manage all of the assets of `owner`.\n *\n * See {setApprovalForAll}\n */\n function isApprovedForAll(address owner, address operator) external view returns (bool);\n}\n" + }, + "@openzeppelin/contracts/utils/Address.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (utils/Address.sol)\n\npragma solidity ^0.8.1;\n\n/**\n * @dev Collection of functions related to the address type\n */\nlibrary Address {\n /**\n * @dev Returns true if `account` is a contract.\n *\n * [IMPORTANT]\n * ====\n * It is unsafe to assume that an address for which this function returns\n * false is an externally-owned account (EOA) and not a contract.\n *\n * Among others, `isContract` will return false for the following\n * types of addresses:\n *\n * - an externally-owned account\n * - a contract in construction\n * - an address where a contract will be created\n * - an address where a contract lived, but was destroyed\n * ====\n *\n * [IMPORTANT]\n * ====\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\n *\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\n * constructor.\n * ====\n */\n function isContract(address account) internal view returns (bool) {\n // This method relies on extcodesize/address.code.length, which returns 0\n // for contracts in construction, since the code is only stored at the end\n // of the constructor execution.\n\n return account.code.length > 0;\n }\n\n /**\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\n * `recipient`, forwarding all available gas and reverting on errors.\n *\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\n * imposed by `transfer`, making them unable to receive funds via\n * `transfer`. {sendValue} removes this limitation.\n *\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\n *\n * IMPORTANT: because control is transferred to `recipient`, care must be\n * taken to not create reentrancy vulnerabilities. Consider using\n * {ReentrancyGuard} or the\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\n */\n function sendValue(address payable recipient, uint256 amount) internal {\n require(address(this).balance >= amount, \"Address: insufficient balance\");\n\n (bool success, ) = recipient.call{value: amount}(\"\");\n require(success, \"Address: unable to send value, recipient may have reverted\");\n }\n\n /**\n * @dev Performs a Solidity function call using a low level `call`. A\n * plain `call` is an unsafe replacement for a function call: use this\n * function instead.\n *\n * If `target` reverts with a revert reason, it is bubbled up by this\n * function (like regular Solidity function calls).\n *\n * Returns the raw returned data. To convert to the expected return value,\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\n *\n * Requirements:\n *\n * - `target` must be a contract.\n * - calling `target` with `data` must not revert.\n *\n * _Available since v3.1._\n */\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionCall(target, data, \"Address: low-level call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\n * `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, 0, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but also transferring `value` wei to `target`.\n *\n * Requirements:\n *\n * - the calling contract must have an ETH balance of at least `value`.\n * - the called Solidity function must be `payable`.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, value, \"Address: low-level call with value failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\n * with `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(address(this).balance >= value, \"Address: insufficient balance for call\");\n require(isContract(target), \"Address: call to non-contract\");\n\n (bool success, bytes memory returndata) = target.call{value: value}(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\n return functionStaticCall(target, data, \"Address: low-level static call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal view returns (bytes memory) {\n require(isContract(target), \"Address: static call to non-contract\");\n\n (bool success, bytes memory returndata) = target.staticcall(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a delegate call.\n *\n * _Available since v3.4._\n */\n function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionDelegateCall(target, data, \"Address: low-level delegate call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a delegate call.\n *\n * _Available since v3.4._\n */\n function functionDelegateCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(isContract(target), \"Address: delegate call to non-contract\");\n\n (bool success, bytes memory returndata) = target.delegatecall(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the\n * revert reason using the provided one.\n *\n * _Available since v4.3._\n */\n function verifyCallResult(\n bool success,\n bytes memory returndata,\n string memory errorMessage\n ) internal pure returns (bytes memory) {\n if (success) {\n return returndata;\n } else {\n // Look for revert reason and bubble it up if present\n if (returndata.length > 0) {\n // The easiest way to bubble the revert reason is using memory via assembly\n /// @solidity memory-safe-assembly\n assembly {\n let returndata_size := mload(returndata)\n revert(add(32, returndata), returndata_size)\n }\n } else {\n revert(errorMessage);\n }\n }\n }\n}\n" + }, + "@openzeppelin/contracts/utils/Context.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Provides information about the current execution context, including the\n * sender of the transaction and its data. While these are generally available\n * via msg.sender and msg.data, they should not be accessed in such a direct\n * manner, since when dealing with meta-transactions the account sending and\n * paying for execution may not be the actual sender (as far as an application\n * is concerned).\n *\n * This contract is only required for intermediate, library-like contracts.\n */\nabstract contract Context {\n function _msgSender() internal view virtual returns (address) {\n return msg.sender;\n }\n\n function _msgData() internal view virtual returns (bytes calldata) {\n return msg.data;\n }\n}\n" + }, + "@openzeppelin/contracts/utils/Counters.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (utils/Counters.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @title Counters\n * @author Matt Condon (@shrugs)\n * @dev Provides counters that can only be incremented, decremented or reset. This can be used e.g. to track the number\n * of elements in a mapping, issuing ERC721 ids, or counting request ids.\n *\n * Include with `using Counters for Counters.Counter;`\n */\nlibrary Counters {\n struct Counter {\n // This variable should never be directly accessed by users of the library: interactions must be restricted to\n // the library's function. As of Solidity v0.5.2, this cannot be enforced, though there is a proposal to add\n // this feature: see https://github.com/ethereum/solidity/issues/4637\n uint256 _value; // default: 0\n }\n\n function current(Counter storage counter) internal view returns (uint256) {\n return counter._value;\n }\n\n function increment(Counter storage counter) internal {\n unchecked {\n counter._value += 1;\n }\n }\n\n function decrement(Counter storage counter) internal {\n uint256 value = counter._value;\n require(value > 0, \"Counter: decrement overflow\");\n unchecked {\n counter._value = value - 1;\n }\n }\n\n function reset(Counter storage counter) internal {\n counter._value = 0;\n }\n}\n" + }, + "@openzeppelin/contracts/utils/cryptography/draft-EIP712.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (utils/cryptography/draft-EIP712.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./ECDSA.sol\";\n\n/**\n * @dev https://eips.ethereum.org/EIPS/eip-712[EIP 712] is a standard for hashing and signing of typed structured data.\n *\n * The encoding specified in the EIP is very generic, and such a generic implementation in Solidity is not feasible,\n * thus this contract does not implement the encoding itself. Protocols need to implement the type-specific encoding\n * they need in their contracts using a combination of `abi.encode` and `keccak256`.\n *\n * This contract implements the EIP 712 domain separator ({_domainSeparatorV4}) that is used as part of the encoding\n * scheme, and the final step of the encoding to obtain the message digest that is then signed via ECDSA\n * ({_hashTypedDataV4}).\n *\n * The implementation of the domain separator was designed to be as efficient as possible while still properly updating\n * the chain id to protect against replay attacks on an eventual fork of the chain.\n *\n * NOTE: This contract implements the version of the encoding known as \"v4\", as implemented by the JSON RPC method\n * https://docs.metamask.io/guide/signing-data.html[`eth_signTypedDataV4` in MetaMask].\n *\n * _Available since v3.4._\n */\nabstract contract EIP712 {\n /* solhint-disable var-name-mixedcase */\n // Cache the domain separator as an immutable value, but also store the chain id that it corresponds to, in order to\n // invalidate the cached domain separator if the chain id changes.\n bytes32 private immutable _CACHED_DOMAIN_SEPARATOR;\n uint256 private immutable _CACHED_CHAIN_ID;\n address private immutable _CACHED_THIS;\n\n bytes32 private immutable _HASHED_NAME;\n bytes32 private immutable _HASHED_VERSION;\n bytes32 private immutable _TYPE_HASH;\n\n /* solhint-enable var-name-mixedcase */\n\n /**\n * @dev Initializes the domain separator and parameter caches.\n *\n * The meaning of `name` and `version` is specified in\n * https://eips.ethereum.org/EIPS/eip-712#definition-of-domainseparator[EIP 712]:\n *\n * - `name`: the user readable name of the signing domain, i.e. the name of the DApp or the protocol.\n * - `version`: the current major version of the signing domain.\n *\n * NOTE: These parameters cannot be changed except through a xref:learn::upgrading-smart-contracts.adoc[smart\n * contract upgrade].\n */\n constructor(string memory name, string memory version) {\n bytes32 hashedName = keccak256(bytes(name));\n bytes32 hashedVersion = keccak256(bytes(version));\n bytes32 typeHash = keccak256(\n \"EIP712Domain(string name,string version,uint256 chainId,address verifyingContract)\"\n );\n _HASHED_NAME = hashedName;\n _HASHED_VERSION = hashedVersion;\n _CACHED_CHAIN_ID = block.chainid;\n _CACHED_DOMAIN_SEPARATOR = _buildDomainSeparator(typeHash, hashedName, hashedVersion);\n _CACHED_THIS = address(this);\n _TYPE_HASH = typeHash;\n }\n\n /**\n * @dev Returns the domain separator for the current chain.\n */\n function _domainSeparatorV4() internal view returns (bytes32) {\n if (address(this) == _CACHED_THIS && block.chainid == _CACHED_CHAIN_ID) {\n return _CACHED_DOMAIN_SEPARATOR;\n } else {\n return _buildDomainSeparator(_TYPE_HASH, _HASHED_NAME, _HASHED_VERSION);\n }\n }\n\n function _buildDomainSeparator(\n bytes32 typeHash,\n bytes32 nameHash,\n bytes32 versionHash\n ) private view returns (bytes32) {\n return keccak256(abi.encode(typeHash, nameHash, versionHash, block.chainid, address(this)));\n }\n\n /**\n * @dev Given an already https://eips.ethereum.org/EIPS/eip-712#definition-of-hashstruct[hashed struct], this\n * function returns the hash of the fully encoded EIP712 message for this domain.\n *\n * This hash can be used together with {ECDSA-recover} to obtain the signer of a message. For example:\n *\n * ```solidity\n * bytes32 digest = _hashTypedDataV4(keccak256(abi.encode(\n * keccak256(\"Mail(address to,string contents)\"),\n * mailTo,\n * keccak256(bytes(mailContents))\n * )));\n * address signer = ECDSA.recover(digest, signature);\n * ```\n */\n function _hashTypedDataV4(bytes32 structHash) internal view virtual returns (bytes32) {\n return ECDSA.toTypedDataHash(_domainSeparatorV4(), structHash);\n }\n}\n" + }, + "@openzeppelin/contracts/utils/cryptography/ECDSA.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (utils/cryptography/ECDSA.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../Strings.sol\";\n\n/**\n * @dev Elliptic Curve Digital Signature Algorithm (ECDSA) operations.\n *\n * These functions can be used to verify that a message was signed by the holder\n * of the private keys of a given address.\n */\nlibrary ECDSA {\n enum RecoverError {\n NoError,\n InvalidSignature,\n InvalidSignatureLength,\n InvalidSignatureS,\n InvalidSignatureV\n }\n\n function _throwError(RecoverError error) private pure {\n if (error == RecoverError.NoError) {\n return; // no error: do nothing\n } else if (error == RecoverError.InvalidSignature) {\n revert(\"ECDSA: invalid signature\");\n } else if (error == RecoverError.InvalidSignatureLength) {\n revert(\"ECDSA: invalid signature length\");\n } else if (error == RecoverError.InvalidSignatureS) {\n revert(\"ECDSA: invalid signature 's' value\");\n } else if (error == RecoverError.InvalidSignatureV) {\n revert(\"ECDSA: invalid signature 'v' value\");\n }\n }\n\n /**\n * @dev Returns the address that signed a hashed message (`hash`) with\n * `signature` or error string. This address can then be used for verification purposes.\n *\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\n * this function rejects them by requiring the `s` value to be in the lower\n * half order, and the `v` value to be either 27 or 28.\n *\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\n * verification to be secure: it is possible to craft signatures that\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\n * this is by receiving a hash of the original message (which may otherwise\n * be too long), and then calling {toEthSignedMessageHash} on it.\n *\n * Documentation for signature generation:\n * - with https://web3js.readthedocs.io/en/v1.3.4/web3-eth-accounts.html#sign[Web3.js]\n * - with https://docs.ethers.io/v5/api/signer/#Signer-signMessage[ethers]\n *\n * _Available since v4.3._\n */\n function tryRecover(bytes32 hash, bytes memory signature) internal pure returns (address, RecoverError) {\n // Check the signature length\n // - case 65: r,s,v signature (standard)\n // - case 64: r,vs signature (cf https://eips.ethereum.org/EIPS/eip-2098) _Available since v4.1._\n if (signature.length == 65) {\n bytes32 r;\n bytes32 s;\n uint8 v;\n // ecrecover takes the signature parameters, and the only way to get them\n // currently is to use assembly.\n /// @solidity memory-safe-assembly\n assembly {\n r := mload(add(signature, 0x20))\n s := mload(add(signature, 0x40))\n v := byte(0, mload(add(signature, 0x60)))\n }\n return tryRecover(hash, v, r, s);\n } else if (signature.length == 64) {\n bytes32 r;\n bytes32 vs;\n // ecrecover takes the signature parameters, and the only way to get them\n // currently is to use assembly.\n /// @solidity memory-safe-assembly\n assembly {\n r := mload(add(signature, 0x20))\n vs := mload(add(signature, 0x40))\n }\n return tryRecover(hash, r, vs);\n } else {\n return (address(0), RecoverError.InvalidSignatureLength);\n }\n }\n\n /**\n * @dev Returns the address that signed a hashed message (`hash`) with\n * `signature`. This address can then be used for verification purposes.\n *\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\n * this function rejects them by requiring the `s` value to be in the lower\n * half order, and the `v` value to be either 27 or 28.\n *\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\n * verification to be secure: it is possible to craft signatures that\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\n * this is by receiving a hash of the original message (which may otherwise\n * be too long), and then calling {toEthSignedMessageHash} on it.\n */\n function recover(bytes32 hash, bytes memory signature) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, signature);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Overload of {ECDSA-tryRecover} that receives the `r` and `vs` short-signature fields separately.\n *\n * See https://eips.ethereum.org/EIPS/eip-2098[EIP-2098 short signatures]\n *\n * _Available since v4.3._\n */\n function tryRecover(\n bytes32 hash,\n bytes32 r,\n bytes32 vs\n ) internal pure returns (address, RecoverError) {\n bytes32 s = vs & bytes32(0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff);\n uint8 v = uint8((uint256(vs) >> 255) + 27);\n return tryRecover(hash, v, r, s);\n }\n\n /**\n * @dev Overload of {ECDSA-recover} that receives the `r and `vs` short-signature fields separately.\n *\n * _Available since v4.2._\n */\n function recover(\n bytes32 hash,\n bytes32 r,\n bytes32 vs\n ) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, r, vs);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Overload of {ECDSA-tryRecover} that receives the `v`,\n * `r` and `s` signature fields separately.\n *\n * _Available since v4.3._\n */\n function tryRecover(\n bytes32 hash,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) internal pure returns (address, RecoverError) {\n // EIP-2 still allows signature malleability for ecrecover(). Remove this possibility and make the signature\n // unique. Appendix F in the Ethereum Yellow paper (https://ethereum.github.io/yellowpaper/paper.pdf), defines\n // the valid range for s in (301): 0 < s < secp256k1n ÷ 2 + 1, and for v in (302): v ∈ {27, 28}. Most\n // signatures from current libraries generate a unique signature with an s-value in the lower half order.\n //\n // If your library generates malleable signatures, such as s-values in the upper range, calculate a new s-value\n // with 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141 - s1 and flip v from 27 to 28 or\n // vice versa. If your library also generates signatures with 0/1 for v instead 27/28, add 27 to v to accept\n // these malleable signatures as well.\n if (uint256(s) > 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D576E7357A4501DDFE92F46681B20A0) {\n return (address(0), RecoverError.InvalidSignatureS);\n }\n if (v != 27 && v != 28) {\n return (address(0), RecoverError.InvalidSignatureV);\n }\n\n // If the signature is valid (and not malleable), return the signer address\n address signer = ecrecover(hash, v, r, s);\n if (signer == address(0)) {\n return (address(0), RecoverError.InvalidSignature);\n }\n\n return (signer, RecoverError.NoError);\n }\n\n /**\n * @dev Overload of {ECDSA-recover} that receives the `v`,\n * `r` and `s` signature fields separately.\n */\n function recover(\n bytes32 hash,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, v, r, s);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Returns an Ethereum Signed Message, created from a `hash`. This\n * produces hash corresponding to the one signed with the\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\n * JSON-RPC method as part of EIP-191.\n *\n * See {recover}.\n */\n function toEthSignedMessageHash(bytes32 hash) internal pure returns (bytes32) {\n // 32 is the length in bytes of hash,\n // enforced by the type signature above\n return keccak256(abi.encodePacked(\"\\x19Ethereum Signed Message:\\n32\", hash));\n }\n\n /**\n * @dev Returns an Ethereum Signed Message, created from `s`. This\n * produces hash corresponding to the one signed with the\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\n * JSON-RPC method as part of EIP-191.\n *\n * See {recover}.\n */\n function toEthSignedMessageHash(bytes memory s) internal pure returns (bytes32) {\n return keccak256(abi.encodePacked(\"\\x19Ethereum Signed Message:\\n\", Strings.toString(s.length), s));\n }\n\n /**\n * @dev Returns an Ethereum Signed Typed Data, created from a\n * `domainSeparator` and a `structHash`. This produces hash corresponding\n * to the one signed with the\n * https://eips.ethereum.org/EIPS/eip-712[`eth_signTypedData`]\n * JSON-RPC method as part of EIP-712.\n *\n * See {recover}.\n */\n function toTypedDataHash(bytes32 domainSeparator, bytes32 structHash) internal pure returns (bytes32) {\n return keccak256(abi.encodePacked(\"\\x19\\x01\", domainSeparator, structHash));\n }\n}\n" + }, + "@openzeppelin/contracts/utils/introspection/IERC165.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (utils/introspection/IERC165.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Interface of the ERC165 standard, as defined in the\n * https://eips.ethereum.org/EIPS/eip-165[EIP].\n *\n * Implementers can declare support of contract interfaces, which can then be\n * queried by others ({ERC165Checker}).\n *\n * For an implementation, see {ERC165}.\n */\ninterface IERC165 {\n /**\n * @dev Returns true if this contract implements the interface defined by\n * `interfaceId`. See the corresponding\n * https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified[EIP section]\n * to learn more about how these ids are created.\n *\n * This function call must use less than 30 000 gas.\n */\n function supportsInterface(bytes4 interfaceId) external view returns (bool);\n}\n" + }, + "@openzeppelin/contracts/utils/StorageSlot.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (utils/StorageSlot.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Library for reading and writing primitive types to specific storage slots.\n *\n * Storage slots are often used to avoid storage conflict when dealing with upgradeable contracts.\n * This library helps with reading and writing to such slots without the need for inline assembly.\n *\n * The functions in this library return Slot structs that contain a `value` member that can be used to read or write.\n *\n * Example usage to set ERC1967 implementation slot:\n * ```\n * contract ERC1967 {\n * bytes32 internal constant _IMPLEMENTATION_SLOT = 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc;\n *\n * function _getImplementation() internal view returns (address) {\n * return StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value;\n * }\n *\n * function _setImplementation(address newImplementation) internal {\n * require(Address.isContract(newImplementation), \"ERC1967: new implementation is not a contract\");\n * StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value = newImplementation;\n * }\n * }\n * ```\n *\n * _Available since v4.1 for `address`, `bool`, `bytes32`, and `uint256`._\n */\nlibrary StorageSlot {\n struct AddressSlot {\n address value;\n }\n\n struct BooleanSlot {\n bool value;\n }\n\n struct Bytes32Slot {\n bytes32 value;\n }\n\n struct Uint256Slot {\n uint256 value;\n }\n\n /**\n * @dev Returns an `AddressSlot` with member `value` located at `slot`.\n */\n function getAddressSlot(bytes32 slot) internal pure returns (AddressSlot storage r) {\n /// @solidity memory-safe-assembly\n assembly {\n r.slot := slot\n }\n }\n\n /**\n * @dev Returns an `BooleanSlot` with member `value` located at `slot`.\n */\n function getBooleanSlot(bytes32 slot) internal pure returns (BooleanSlot storage r) {\n /// @solidity memory-safe-assembly\n assembly {\n r.slot := slot\n }\n }\n\n /**\n * @dev Returns an `Bytes32Slot` with member `value` located at `slot`.\n */\n function getBytes32Slot(bytes32 slot) internal pure returns (Bytes32Slot storage r) {\n /// @solidity memory-safe-assembly\n assembly {\n r.slot := slot\n }\n }\n\n /**\n * @dev Returns an `Uint256Slot` with member `value` located at `slot`.\n */\n function getUint256Slot(bytes32 slot) internal pure returns (Uint256Slot storage r) {\n /// @solidity memory-safe-assembly\n assembly {\n r.slot := slot\n }\n }\n}\n" + }, + "@openzeppelin/contracts/utils/Strings.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (utils/Strings.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev String operations.\n */\nlibrary Strings {\n bytes16 private constant _HEX_SYMBOLS = \"0123456789abcdef\";\n uint8 private constant _ADDRESS_LENGTH = 20;\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` decimal representation.\n */\n function toString(uint256 value) internal pure returns (string memory) {\n // Inspired by OraclizeAPI's implementation - MIT licence\n // https://github.com/oraclize/ethereum-api/blob/b42146b063c7d6ee1358846c198246239e9360e8/oraclizeAPI_0.4.25.sol\n\n if (value == 0) {\n return \"0\";\n }\n uint256 temp = value;\n uint256 digits;\n while (temp != 0) {\n digits++;\n temp /= 10;\n }\n bytes memory buffer = new bytes(digits);\n while (value != 0) {\n digits -= 1;\n buffer[digits] = bytes1(uint8(48 + uint256(value % 10)));\n value /= 10;\n }\n return string(buffer);\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation.\n */\n function toHexString(uint256 value) internal pure returns (string memory) {\n if (value == 0) {\n return \"0x00\";\n }\n uint256 temp = value;\n uint256 length = 0;\n while (temp != 0) {\n length++;\n temp >>= 8;\n }\n return toHexString(value, length);\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length.\n */\n function toHexString(uint256 value, uint256 length) internal pure returns (string memory) {\n bytes memory buffer = new bytes(2 * length + 2);\n buffer[0] = \"0\";\n buffer[1] = \"x\";\n for (uint256 i = 2 * length + 1; i > 1; --i) {\n buffer[i] = _HEX_SYMBOLS[value & 0xf];\n value >>= 4;\n }\n require(value == 0, \"Strings: hex length insufficient\");\n return string(buffer);\n }\n\n /**\n * @dev Converts an `address` with fixed length of 20 bytes to its not checksummed ASCII `string` hexadecimal representation.\n */\n function toHexString(address addr) internal pure returns (string memory) {\n return toHexString(uint256(uint160(addr)), _ADDRESS_LENGTH);\n }\n}\n" + }, + "contracts/agToken/AgEUR.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\nimport \"../interfaces/IAgToken.sol\";\nimport \"../interfaces/coreModule/IStableMaster.sol\";\nimport \"../interfaces/ITreasury.sol\";\nimport \"@openzeppelin/contracts-upgradeable/token/ERC20/extensions/draft-ERC20PermitUpgradeable.sol\";\n\n/// @title AgEUR\n/// @author Angle Labs, Inc.\n/// @notice Base contract for agEUR, Angle's Euro stablecoin\n/// @dev This contract is an upgraded version of the agEUR contract that was first deployed on Ethereum mainnet\ncontract AgEUR is IAgToken, ERC20PermitUpgradeable {\n // ================================= REFERENCES ================================\n\n /// @notice Reference to the `StableMaster` contract associated to agEUR\n address public stableMaster;\n\n /// @custom:oz-upgrades-unsafe-allow constructor\n constructor() initializer {}\n\n // ============================== ADDED PARAMETERS =============================\n\n /// @inheritdoc IAgToken\n mapping(address => bool) public isMinter;\n /// @notice Reference to the treasury contract which can grant minting rights\n address public treasury;\n /// @notice Boolean used to check whether the contract had been reinitialized after an upgrade\n bool public treasuryInitialized;\n\n // =================================== EVENTS ==================================\n\n event TreasuryUpdated(address indexed _treasury);\n event MinterToggled(address indexed minter);\n\n // =================================== ERRORS ==================================\n\n error BurnAmountExceedsAllowance();\n error InvalidSender();\n error InvalidTreasury();\n error NotGovernor();\n error NotMinter();\n error NotTreasury();\n error TreasuryAlreadyInitialized();\n\n // ================================= MODIFIERS =================================\n\n /// @notice Checks to see if it is the `Treasury` calling this contract\n modifier onlyTreasury() {\n if (msg.sender != treasury) revert NotTreasury();\n _;\n }\n\n /// @notice Checks whether the sender has the minting right\n modifier onlyMinter() {\n if (!isMinter[msg.sender]) revert NotMinter();\n _;\n }\n\n // ============================= EXTERNAL FUNCTION =============================\n\n /// @notice Allows anyone to burn stablecoins\n /// @param amount Amount of stablecoins to burn\n /// @dev This function can typically be called if there is a settlement mechanism to burn stablecoins\n function burnStablecoin(uint256 amount) external {\n _burn(msg.sender, amount);\n }\n\n // ========================= MINTER ROLE ONLY FUNCTIONS ========================\n\n /// @inheritdoc IAgToken\n function burnSelf(uint256 amount, address burner) external onlyMinter {\n _burn(burner, amount);\n }\n\n /// @inheritdoc IAgToken\n function burnFrom(uint256 amount, address burner, address sender) external onlyMinter {\n if (burner != sender) {\n uint256 currentAllowance = allowance(burner, sender);\n if (currentAllowance < amount) revert BurnAmountExceedsAllowance();\n _approve(burner, sender, currentAllowance - amount);\n }\n _burn(burner, amount);\n }\n\n /// @inheritdoc IAgToken\n function mint(address account, uint256 amount) external onlyMinter {\n _mint(account, amount);\n }\n\n // ========================== TREASURY ONLY FUNCTIONS ==========================\n\n /// @inheritdoc IAgToken\n function addMinter(address minter) external onlyTreasury {\n isMinter[minter] = true;\n emit MinterToggled(minter);\n }\n\n /// @inheritdoc IAgToken\n function removeMinter(address minter) external {\n if (msg.sender != minter && msg.sender != address(treasury)) revert InvalidSender();\n isMinter[minter] = false;\n emit MinterToggled(minter);\n }\n\n /// @inheritdoc IAgToken\n function setTreasury(address _treasury) external onlyTreasury {\n treasury = _treasury;\n emit TreasuryUpdated(_treasury);\n }\n}\n" + }, + "contracts/agToken/AgToken.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\n/*\n * █ \n ***** ▓▓▓ \n * ▓▓▓▓▓▓▓ \n * ///. ▓▓▓▓▓▓▓▓▓▓▓▓▓ \n ***** //////// ▓▓▓▓▓▓▓ \n * ///////////// ▓▓▓ \n ▓▓ ////////////////// █ ▓▓ \n ▓▓ ▓▓ /////////////////////// ▓▓ ▓▓ \n ▓▓ ▓▓ //////////////////////////// ▓▓ ▓▓ \n ▓▓ ▓▓ /////////▓▓▓///////▓▓▓///////// ▓▓ ▓▓ \n ▓▓ ,////////////////////////////////////// ▓▓ ▓▓ \n ▓▓ ////////////////////////////////////////// ▓▓ \n ▓▓ //////////////////////▓▓▓▓///////////////////// \n ,//////////////////////////////////////////////////// \n .////////////////////////////////////////////////////////// \n .//////////////////////////██.,//////////////////////////█ \n .//////////////////////████..,./////////////////////██ \n ...////////////////███████.....,.////////////////███ \n ,.,////////////████████ ........,///////////████ \n .,.,//////█████████ ,.......///////████ \n ,..//████████ ........./████ \n ..,██████ .....,███ \n .██ ,.,█ \n \n \n \n ▓▓ ▓▓▓▓▓▓▓▓▓▓ ▓▓▓▓▓▓▓▓▓▓ ▓▓ ▓▓▓▓▓▓▓▓▓▓ \n ▓▓▓▓▓▓ ▓▓▓ ▓▓▓ ▓▓▓ ▓▓ ▓▓ ▓▓▓▓ \n ▓▓▓ ▓▓▓ ▓▓▓ ▓▓▓ ▓▓▓ ▓▓▓ ▓▓ ▓▓▓▓▓ \n ▓▓▓ ▓▓ ▓▓▓ ▓▓▓ ▓▓▓▓▓▓▓▓▓▓ ▓▓▓▓▓▓▓▓▓▓ ▓▓▓▓▓▓▓▓▓▓ \n*/\n\nimport \"../interfaces/IAgToken.sol\";\nimport \"../interfaces/ITreasury.sol\";\nimport \"@openzeppelin/contracts-upgradeable/token/ERC20/extensions/draft-ERC20PermitUpgradeable.sol\";\n\n/// @title AgToken\n/// @author Angle Labs, Inc.\n/// @notice Base contract for Angle agTokens on Ethereum and on other chains\n/// @dev By default, agTokens are ERC-20 tokens with 18 decimals\ncontract AgToken is IAgToken, ERC20PermitUpgradeable {\n // =========================== PARAMETERS / VARIABLES ==========================\n\n /// @inheritdoc IAgToken\n mapping(address => bool) public isMinter;\n /// @notice Reference to the treasury contract which can grant minting rights\n address public treasury;\n\n // =================================== EVENTS ==================================\n\n event TreasuryUpdated(address indexed _treasury);\n event MinterToggled(address indexed minter);\n\n // =================================== ERRORS ==================================\n\n error BurnAmountExceedsAllowance();\n error InvalidSender();\n error InvalidTreasury();\n error NotMinter();\n error NotTreasury();\n\n // ================================ CONSTRUCTOR ================================\n\n /// @custom:oz-upgrades-unsafe-allow constructor\n constructor() initializer {}\n\n /// @notice Initializes the `AgToken` contract\n function initialize(string memory name_, string memory symbol_, address _treasury) external {\n _initialize(name_, symbol_, _treasury);\n }\n\n /// @notice Initializes the contract\n function _initialize(string memory name_, string memory symbol_, address _treasury) internal virtual initializer {\n if (address(ITreasury(_treasury).stablecoin()) != address(this)) revert InvalidTreasury();\n __ERC20Permit_init(name_);\n __ERC20_init(name_, symbol_);\n treasury = _treasury;\n emit TreasuryUpdated(_treasury);\n }\n\n // ================================= MODIFIERS =================================\n\n /// @notice Checks to see if it is the `Treasury` calling this contract\n modifier onlyTreasury() {\n if (msg.sender != treasury) revert NotTreasury();\n _;\n }\n\n /// @notice Checks whether the sender has the minting right\n modifier onlyMinter() {\n if (!isMinter[msg.sender]) revert NotMinter();\n _;\n }\n\n // ============================= EXTERNAL FUNCTION =============================\n\n /// @notice Allows anyone to burn stablecoins\n /// @param amount Amount of stablecoins to burn\n /// @dev This function can typically be called if there is a settlement mechanism to burn stablecoins\n function burnStablecoin(uint256 amount) external {\n _burn(msg.sender, amount);\n }\n\n // ========================= MINTER ROLE ONLY FUNCTIONS ========================\n\n /// @inheritdoc IAgToken\n function burnSelf(uint256 amount, address burner) external onlyMinter {\n _burn(burner, amount);\n }\n\n /// @inheritdoc IAgToken\n function burnFrom(uint256 amount, address burner, address sender) external onlyMinter {\n if (burner != sender) {\n uint256 currentAllowance = allowance(burner, sender);\n if (currentAllowance < amount) revert BurnAmountExceedsAllowance();\n _approve(burner, sender, currentAllowance - amount);\n }\n _burn(burner, amount);\n }\n\n /// @inheritdoc IAgToken\n function mint(address account, uint256 amount) external onlyMinter {\n _mint(account, amount);\n }\n\n // ========================== GOVERNANCE ONLY FUNCTIONS ==========================\n\n /// @inheritdoc IAgToken\n function addMinter(address minter) external onlyTreasury {\n isMinter[minter] = true;\n emit MinterToggled(minter);\n }\n\n /// @inheritdoc IAgToken\n function removeMinter(address minter) external {\n if (msg.sender != address(treasury) && msg.sender != minter) revert InvalidSender();\n isMinter[minter] = false;\n emit MinterToggled(minter);\n }\n\n /// @inheritdoc IAgToken\n function setTreasury(address _treasury) external virtual onlyTreasury {\n treasury = _treasury;\n emit TreasuryUpdated(_treasury);\n }\n}\n" + }, + "contracts/agToken/AgTokenSideChainMultiBridge.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\nimport \"./AgToken.sol\";\nimport \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\nimport \"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\";\n\n/// @title AgTokenSideChainMultiBridge\n/// @author Angle Labs, Inc.\n/// @notice Contract for Angle agTokens on other chains than Ethereum mainnet\n/// @dev This contract supports bridge tokens having a minting right on the stablecoin (also referred to as the canonical\n/// or the native token)\ncontract AgTokenSideChainMultiBridge is AgToken {\n using SafeERC20 for IERC20;\n\n /// @notice Base used for fee computation\n uint256 public constant BASE_PARAMS = 1e9;\n\n // =============================== BRIDGING DATA ===============================\n\n /// @notice Struct with some data about a specific bridge token\n struct BridgeDetails {\n // Limit on the balance of bridge token held by the contract: it is designed\n // to reduce the exposure of the system to hacks\n uint256 limit;\n // Limit on the hourly volume of token minted through this bridge\n // Technically the limit over a rolling hour is hourlyLimit x2 as hourly limit\n // is enforced only between x:00 and x+1:00\n uint256 hourlyLimit;\n // Fee taken for swapping in and out the token\n uint64 fee;\n // Whether the associated token is allowed or not\n bool allowed;\n // Whether swapping in and out from the associated token is paused or not\n bool paused;\n }\n\n /// @notice Maps a bridge token to data\n mapping(address => BridgeDetails) public bridges;\n /// @notice List of all bridge tokens\n address[] public bridgeTokensList;\n /// @notice Maps a bridge token to the associated hourly volume\n mapping(address => mapping(uint256 => uint256)) public usage;\n /// @notice Maps an address to whether it is exempt of fees for when it comes to swapping in and out\n mapping(address => uint256) public isFeeExempt;\n /// @notice Limit to the amount of tokens that can be sent from that chain to another chain\n uint256 public chainTotalHourlyLimit;\n /// @notice Usage per hour on that chain. Maps an hourly timestamp to the total volume swapped out on the chain\n mapping(uint256 => uint256) public chainTotalUsage;\n\n // =================================== EVENTS ==================================\n\n event BridgeTokenAdded(address indexed bridgeToken, uint256 limit, uint256 hourlyLimit, uint64 fee, bool paused);\n event BridgeTokenToggled(address indexed bridgeToken, bool toggleStatus);\n event BridgeTokenRemoved(address indexed bridgeToken);\n event BridgeTokenFeeUpdated(address indexed bridgeToken, uint64 fee);\n event BridgeTokenLimitUpdated(address indexed bridgeToken, uint256 limit);\n event BridgeTokenHourlyLimitUpdated(address indexed bridgeToken, uint256 hourlyLimit);\n event HourlyLimitUpdated(uint256 hourlyLimit);\n event Recovered(address indexed token, address indexed to, uint256 amount);\n event FeeToggled(address indexed theAddress, uint256 toggleStatus);\n\n // =================================== ERRORS ==================================\n\n error AssetStillControlledInReserves();\n error HourlyLimitExceeded();\n error InvalidToken();\n error NotGovernor();\n error NotGovernorOrGuardian();\n error TooBigAmount();\n error TooHighParameterValue();\n error ZeroAddress();\n\n // ================================= MODIFIERS =================================\n\n /// @notice Checks whether the `msg.sender` has the governor role or not\n modifier onlyGovernor() {\n if (!ITreasury(treasury).isGovernor(msg.sender)) revert NotGovernor();\n _;\n }\n\n /// @notice Checks whether the `msg.sender` has the governor role or the guardian role\n modifier onlyGovernorOrGuardian() {\n if (!ITreasury(treasury).isGovernorOrGuardian(msg.sender)) revert NotGovernorOrGuardian();\n _;\n }\n\n // ===================== EXTERNAL PERMISSIONLESS FUNCTIONS =====================\n\n /// @notice Returns the list of all supported bridge tokens\n /// @dev Helpful for UIs\n function allBridgeTokens() external view returns (address[] memory) {\n return bridgeTokensList;\n }\n\n /// @notice Returns the current volume for a bridge, for the current hour\n /// @param bridgeToken Bridge used to mint\n /// @dev Helpful for UIs\n function currentUsage(address bridgeToken) external view returns (uint256) {\n return usage[bridgeToken][block.timestamp / 3600];\n }\n\n /// @notice Returns the current total volume on the chain for the current hour\n /// @dev Helpful for UIs\n function currentTotalUsage() external view returns (uint256) {\n return chainTotalUsage[block.timestamp / 3600];\n }\n\n /// @notice Mints the canonical token from a supported bridge token\n /// @param bridgeToken Bridge token to use to mint\n /// @param amount Amount of bridge tokens to send\n /// @param to Address to which the stablecoin should be sent\n /// @return Amount of the canonical stablecoin actually minted\n /// @dev Some fees may be taken by the protocol depending on the token used and on the address calling\n function swapIn(address bridgeToken, uint256 amount, address to) external returns (uint256) {\n BridgeDetails memory bridgeDetails = bridges[bridgeToken];\n if (!bridgeDetails.allowed || bridgeDetails.paused) revert InvalidToken();\n uint256 balance = IERC20(bridgeToken).balanceOf(address(this));\n if (balance + amount > bridgeDetails.limit) {\n // In case someone maliciously sends tokens to this contract\n // Or the limit changes\n if (bridgeDetails.limit > balance) amount = bridgeDetails.limit - balance;\n else {\n amount = 0;\n }\n }\n\n // Checking requirement on the hourly volume\n uint256 hour = block.timestamp / 3600;\n uint256 hourlyUsage = usage[bridgeToken][hour];\n if (hourlyUsage + amount > bridgeDetails.hourlyLimit) {\n // Edge case when the hourly limit changes\n amount = bridgeDetails.hourlyLimit > hourlyUsage ? bridgeDetails.hourlyLimit - hourlyUsage : 0;\n }\n usage[bridgeToken][hour] = hourlyUsage + amount;\n\n IERC20(bridgeToken).safeTransferFrom(msg.sender, address(this), amount);\n uint256 canonicalOut = amount;\n // Computing fees\n if (isFeeExempt[msg.sender] == 0) {\n canonicalOut -= (canonicalOut * bridgeDetails.fee) / BASE_PARAMS;\n }\n _mint(to, canonicalOut);\n return canonicalOut;\n }\n\n /// @notice Burns the canonical token in exchange for a bridge token\n /// @param bridgeToken Bridge token required\n /// @param amount Amount of canonical tokens to burn\n /// @param to Address to which the bridge token should be sent\n /// @return Amount of bridge tokens actually sent back\n /// @dev Some fees may be taken by the protocol depending on the token used and on the address calling\n function swapOut(address bridgeToken, uint256 amount, address to) external returns (uint256) {\n BridgeDetails memory bridgeDetails = bridges[bridgeToken];\n if (!bridgeDetails.allowed || bridgeDetails.paused) revert InvalidToken();\n\n uint256 hour = block.timestamp / 3600;\n uint256 hourlyUsage = chainTotalUsage[hour] + amount;\n // If the amount being swapped out exceeds the limit, we revert\n // We don't want to change the amount being swapped out.\n // The user can decide to send another tx with the correct amount to reach the limit\n if (hourlyUsage > chainTotalHourlyLimit) revert HourlyLimitExceeded();\n chainTotalUsage[hour] = hourlyUsage;\n\n _burn(msg.sender, amount);\n uint256 bridgeOut = amount;\n if (isFeeExempt[msg.sender] == 0) {\n bridgeOut -= (bridgeOut * bridgeDetails.fee) / BASE_PARAMS;\n }\n IERC20(bridgeToken).safeTransfer(to, bridgeOut);\n return bridgeOut;\n }\n\n // ============================ GOVERNANCE FUNCTIONS ===========================\n\n /// @notice Adds support for a bridge token\n /// @param bridgeToken Bridge token to add: it should be a version of the stablecoin from another bridge\n /// @param limit Limit on the balance of bridge token this contract could hold\n /// @param hourlyLimit Limit on the hourly volume for this bridge\n /// @param paused Whether swapping for this token should be paused or not\n /// @param fee Fee taken upon swapping for or against this token\n function addBridgeToken(\n address bridgeToken,\n uint256 limit,\n uint256 hourlyLimit,\n uint64 fee,\n bool paused\n ) external onlyGovernor {\n if (bridges[bridgeToken].allowed || bridgeToken == address(0)) revert InvalidToken();\n if (fee > BASE_PARAMS) revert TooHighParameterValue();\n BridgeDetails memory _bridge;\n _bridge.limit = limit;\n _bridge.hourlyLimit = hourlyLimit;\n _bridge.paused = paused;\n _bridge.fee = fee;\n _bridge.allowed = true;\n bridges[bridgeToken] = _bridge;\n bridgeTokensList.push(bridgeToken);\n emit BridgeTokenAdded(bridgeToken, limit, hourlyLimit, fee, paused);\n }\n\n /// @notice Removes support for a token\n /// @param bridgeToken Address of the bridge token to remove support for\n function removeBridgeToken(address bridgeToken) external onlyGovernor {\n if (IERC20(bridgeToken).balanceOf(address(this)) != 0) revert AssetStillControlledInReserves();\n delete bridges[bridgeToken];\n // Deletion from `bridgeTokensList` loop\n uint256 bridgeTokensListLength = bridgeTokensList.length;\n for (uint256 i; i < bridgeTokensListLength - 1; ++i) {\n if (bridgeTokensList[i] == bridgeToken) {\n // Replace the `bridgeToken` to remove with the last of the list\n bridgeTokensList[i] = bridgeTokensList[bridgeTokensListLength - 1];\n break;\n }\n }\n // Remove last element in array\n bridgeTokensList.pop();\n emit BridgeTokenRemoved(bridgeToken);\n }\n\n /// @notice Recovers any ERC20 token\n /// @dev Can be used to withdraw bridge tokens for them to be de-bridged on mainnet\n function recoverERC20(address tokenAddress, address to, uint256 amountToRecover) external onlyGovernor {\n IERC20(tokenAddress).safeTransfer(to, amountToRecover);\n emit Recovered(tokenAddress, to, amountToRecover);\n }\n\n /// @notice Updates the `limit` amount for `bridgeToken`\n function setLimit(address bridgeToken, uint256 limit) external onlyGovernorOrGuardian {\n if (!bridges[bridgeToken].allowed) revert InvalidToken();\n bridges[bridgeToken].limit = limit;\n emit BridgeTokenLimitUpdated(bridgeToken, limit);\n }\n\n /// @notice Updates the `hourlyLimit` amount for `bridgeToken`\n function setHourlyLimit(address bridgeToken, uint256 hourlyLimit) external onlyGovernorOrGuardian {\n if (!bridges[bridgeToken].allowed) revert InvalidToken();\n bridges[bridgeToken].hourlyLimit = hourlyLimit;\n emit BridgeTokenHourlyLimitUpdated(bridgeToken, hourlyLimit);\n }\n\n /// @notice Updates the `chainTotalHourlyLimit` amount\n function setChainTotalHourlyLimit(uint256 hourlyLimit) external onlyGovernorOrGuardian {\n chainTotalHourlyLimit = hourlyLimit;\n emit HourlyLimitUpdated(hourlyLimit);\n }\n\n /// @notice Updates the `fee` value for `bridgeToken`\n function setSwapFee(address bridgeToken, uint64 fee) external onlyGovernorOrGuardian {\n if (!bridges[bridgeToken].allowed) revert InvalidToken();\n if (fee > BASE_PARAMS) revert TooHighParameterValue();\n bridges[bridgeToken].fee = fee;\n emit BridgeTokenFeeUpdated(bridgeToken, fee);\n }\n\n /// @notice Pauses or unpauses swapping in and out for a token\n function toggleBridge(address bridgeToken) external onlyGovernorOrGuardian {\n if (!bridges[bridgeToken].allowed) revert InvalidToken();\n bool pausedStatus = bridges[bridgeToken].paused;\n bridges[bridgeToken].paused = !pausedStatus;\n emit BridgeTokenToggled(bridgeToken, !pausedStatus);\n }\n\n /// @notice Toggles fees for the address `theAddress`\n function toggleFeesForAddress(address theAddress) external onlyGovernorOrGuardian {\n uint256 feeExemptStatus = 1 - isFeeExempt[theAddress];\n isFeeExempt[theAddress] = feeExemptStatus;\n emit FeeToggled(theAddress, feeExemptStatus);\n }\n}\n" + }, + "contracts/agToken/layerZero/LayerZeroBridge.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.12;\n\nimport \"./utils/OFTCore.sol\";\nimport \"@openzeppelin/contracts-upgradeable/security/PausableUpgradeable.sol\";\nimport \"@openzeppelin/contracts/token/ERC20/extensions/draft-IERC20Permit.sol\";\n\n/// @title LayerZeroBridge\n/// @author Angle Labs, Inc., forked from https://github.com/LayerZero-Labs/solidity-examples/blob/main/contracts/token/oft/OFT.sol\n/// @notice Contract to be deployed on Ethereum for bridging an AgToken using a bridge intermediate token and LayerZero\ncontract LayerZeroBridge is OFTCore, PausableUpgradeable {\n /// @notice Name of the contract for indexing purposes\n string public name;\n\n /// @notice Address of the bridgeable token\n /// @dev Immutable\n IERC20 public canonicalToken;\n\n /// @notice Maps an address to the amount of token bridged but not received\n mapping(address => uint256) public balanceOf;\n\n // ================================ CONSTRUCTOR ================================\n /// @notice Initializes the contract\n /// @param _name Name of the token corresponding to this contract\n /// @param _lzEndpoint Layer zero endpoint to pass messages\n /// @param _treasury Address of the treasury contract used for access control\n function initialize(string memory _name, address _lzEndpoint, address _treasury) external initializer {\n __LzAppUpgradeable_init(_lzEndpoint, _treasury);\n name = _name;\n canonicalToken = IERC20(address(ITreasury(_treasury).stablecoin()));\n }\n\n /// @custom:oz-upgrades-unsafe-allow constructor\n constructor() initializer {}\n\n // ===================== EXTERNAL PERMISSIONLESS FUNCTIONS =====================\n\n /// @inheritdoc OFTCore\n function sendWithPermit(\n uint16 _dstChainId,\n bytes memory _toAddress,\n uint256 _amount,\n address payable _refundAddress,\n address _zroPaymentAddress,\n bytes memory _adapterParams,\n uint256 deadline,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) public payable override {\n IERC20Permit(address(canonicalToken)).permit(msg.sender, address(this), _amount, deadline, v, r, s);\n send(_dstChainId, _toAddress, _amount, _refundAddress, _zroPaymentAddress, _adapterParams);\n }\n\n /// @inheritdoc OFTCore\n function withdraw(uint256 amount, address recipient) external override returns (uint256) {\n return _withdraw(amount, msg.sender, recipient);\n }\n\n /// @notice Withdraws amount of `token` from the contract and sends it to the recipient\n /// @param amount Amount to withdraw\n /// @param recipient Address to withdraw for\n /// @return The amount of canonical token sent\n function withdrawFor(uint256 amount, address recipient) external returns (uint256) {\n return _withdraw(amount, recipient, recipient);\n }\n\n // ============================= INTERNAL FUNCTIONS ============================\n\n /// @notice Withdraws `amount` from the balance of the `from` address and sends these tokens to the `to` address\n /// @dev It's important to make sure that `from` is either the `msg.sender` or that `from` and `to` are the same\n /// addresses\n function _withdraw(uint256 amount, address from, address to) internal whenNotPaused returns (uint256) {\n balanceOf[from] -= amount; // Will overflow if the amount is too big\n canonicalToken.transfer(to, amount);\n return amount;\n }\n\n /// @inheritdoc OFTCore\n function _debitFrom(uint16, bytes memory, uint256 _amount) internal override whenNotPaused returns (uint256) {\n // No need to use safeTransferFrom as we know this implementation reverts on failure\n canonicalToken.transferFrom(msg.sender, address(this), _amount);\n return _amount;\n }\n\n /// @inheritdoc OFTCore\n function _debitCreditFrom(uint16, bytes memory, uint256 _amount) internal override whenNotPaused returns (uint256) {\n balanceOf[msg.sender] -= _amount;\n return _amount;\n }\n\n /// @inheritdoc OFTCore\n function _creditTo(uint16, address _toAddress, uint256 _amount) internal override whenNotPaused returns (uint256) {\n // Should never revert as all the LayerZero bridge tokens come from\n // this contract\n uint256 balance = canonicalToken.balanceOf(address(this));\n if (balance < _amount) {\n balanceOf[_toAddress] = _amount - balance;\n if (balance != 0) canonicalToken.transfer(_toAddress, balance);\n } else {\n canonicalToken.transfer(_toAddress, _amount);\n }\n return _amount;\n }\n\n // =============================== VIEW FUNCTIONS ==============================\n\n /// @inheritdoc ERC165Upgradeable\n function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {\n return interfaceId == type(IOFTCore).interfaceId || super.supportsInterface(interfaceId);\n }\n\n // ============================ GOVERNANCE FUNCTIONS ===========================\n\n /// @notice Pauses bridging through the contract\n /// @param pause Future pause status\n function pauseSendTokens(bool pause) external onlyGovernorOrGuardian {\n pause ? _pause() : _unpause();\n }\n\n /// @notice Decreases the balance of an address\n /// @param amount Amount to withdraw from balance\n /// @param recipient Address to withdraw from\n function sweep(uint256 amount, address recipient) external onlyGovernorOrGuardian {\n balanceOf[recipient] -= amount; // Will overflow if the amount is too big\n }\n\n uint256[47] private __gap;\n}\n" + }, + "contracts/agToken/layerZero/LayerZeroBridgeToken.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.12;\n\nimport \"./utils/OFTCore.sol\";\nimport \"../../interfaces/IAgTokenSideChainMultiBridge.sol\";\nimport \"@openzeppelin/contracts-upgradeable/security/PausableUpgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/token/ERC20/ERC20Upgradeable.sol\";\n\n/// @title LayerZeroBridgeToken\n/// @author Angle Labs, Inc., forked from https://github.com/LayerZero-Labs/solidity-examples/blob/main/contracts/token/oft/OFT.sol\n/// @notice Contract to be deployed on a L2/sidechain for bridging an AgToken using a bridge intermediate token and LayerZero\ncontract LayerZeroBridgeToken is OFTCore, ERC20Upgradeable, PausableUpgradeable {\n /// @notice Address of the bridgeable token\n /// @dev Immutable\n IAgTokenSideChainMultiBridge public canonicalToken;\n\n // =================================== ERROR ===================================\n\n error InvalidAllowance();\n\n // ================================ CONSTRUCTOR ================================\n\n /// @notice Initializes the contract\n /// @param _name Name of the token corresponding to this contract\n /// @param _symbol Symbol of the token corresponding to this contract\n /// @param _lzEndpoint Layer zero endpoint to pass messages\n /// @param _treasury Address of the treasury contract used for access control\n /// @param initialSupply Initial supply to mint to the canonical token address\n /// @dev The initial supply corresponds to the initial amount that could be bridged using this OFT\n function initialize(\n string memory _name,\n string memory _symbol,\n address _lzEndpoint,\n address _treasury,\n uint256 initialSupply\n ) external initializer {\n __ERC20_init_unchained(_name, _symbol);\n __LzAppUpgradeable_init(_lzEndpoint, _treasury);\n\n canonicalToken = IAgTokenSideChainMultiBridge(address(ITreasury(_treasury).stablecoin()));\n _approve(address(this), address(canonicalToken), type(uint256).max);\n _mint(address(canonicalToken), initialSupply);\n }\n\n /// @custom:oz-upgrades-unsafe-allow constructor\n constructor() initializer {}\n\n // ===================== EXTERNAL PERMISSIONLESS FUNCTIONS =====================\n\n /// @inheritdoc OFTCore\n function sendWithPermit(\n uint16 _dstChainId,\n bytes memory _toAddress,\n uint256 _amount,\n address payable _refundAddress,\n address _zroPaymentAddress,\n bytes memory _adapterParams,\n uint256 deadline,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) public payable override {\n canonicalToken.permit(msg.sender, address(this), _amount, deadline, v, r, s);\n send(_dstChainId, _toAddress, _amount, _refundAddress, _zroPaymentAddress, _adapterParams);\n }\n\n /// @inheritdoc OFTCore\n function withdraw(uint256 amount, address recipient) external override returns (uint256 amountMinted) {\n // Does not check allowances as transfers from `msg.sender`\n _transfer(msg.sender, address(this), amount);\n amountMinted = canonicalToken.swapIn(address(this), amount, recipient);\n uint256 leftover = balanceOf(address(this));\n if (leftover != 0) {\n _transfer(address(this), msg.sender, leftover);\n }\n }\n\n // ============================= INTERNAL FUNCTIONS ============================\n\n /// @inheritdoc OFTCore\n function _debitFrom(\n uint16,\n bytes memory,\n uint256 _amount\n ) internal override whenNotPaused returns (uint256 amountSwapped) {\n // No need to use safeTransferFrom as we know this implementation reverts on failure\n canonicalToken.transferFrom(msg.sender, address(this), _amount);\n\n // Swap canonical for this bridge token. There may be some fees\n amountSwapped = canonicalToken.swapOut(address(this), _amount, address(this));\n _burn(address(this), amountSwapped);\n }\n\n /// @inheritdoc OFTCore\n function _debitCreditFrom(uint16, bytes memory, uint256 _amount) internal override whenNotPaused returns (uint256) {\n _burn(msg.sender, _amount);\n return _amount;\n }\n\n /// @inheritdoc OFTCore\n function _creditTo(\n uint16,\n address _toAddress,\n uint256 _amount\n ) internal override whenNotPaused returns (uint256 amountMinted) {\n _mint(address(this), _amount);\n amountMinted = canonicalToken.swapIn(address(this), _amount, _toAddress);\n uint256 leftover = balanceOf(address(this));\n if (leftover != 0) {\n _transfer(address(this), _toAddress, leftover);\n }\n }\n\n // =============================== VIEW FUNCTIONS ==============================\n\n /// @inheritdoc ERC165Upgradeable\n function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {\n return\n interfaceId == type(IOFT).interfaceId ||\n interfaceId == type(IERC20).interfaceId ||\n super.supportsInterface(interfaceId);\n }\n\n // ============================ GOVERNANCE FUNCTIONS ===========================\n\n /// @notice Mints the intermediate contract to the `canonicalToken`\n /// @dev Used to increase the bridging capacity\n function mint(uint256 amount) external onlyGovernorOrGuardian {\n _mint(address(canonicalToken), amount);\n }\n\n /// @notice Burns the intermediate contract from the `canonicalToken`\n /// @dev Used to decrease the bridging capacity\n function burn(uint256 amount) external onlyGovernorOrGuardian {\n _burn(address(canonicalToken), amount);\n }\n\n /// @notice Increases allowance of the `canonicalToken`\n function setupAllowance() public onlyGovernorOrGuardian {\n _approve(address(this), address(canonicalToken), type(uint256).max);\n }\n\n /// @notice Pauses bridging through the contract\n /// @param pause Future pause status\n function pauseSendTokens(bool pause) external onlyGovernorOrGuardian {\n pause ? _pause() : _unpause();\n }\n\n uint256[49] private __gap;\n}\n" + }, + "contracts/agToken/layerZero/utils/IOFTCore.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.12;\n\nimport \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\nimport \"@openzeppelin/contracts/utils/introspection/IERC165.sol\";\n\n/**\n * @dev Interface of the IOFT core standard\n * @dev Forked from https://github.com/LayerZero-Labs/solidity-examples/blob/main/contracts/token/oft/IOFTCore.sol\n */\ninterface IOFTCore is IERC165 {\n /// @notice Estimates send token `_tokenId` to (`_dstChainId`, `_toAddress`)\n /// @param _dstChainId L0 defined chain id to send tokens too\n /// @param _toAddress dynamic bytes array which contains the address to whom you are sending tokens to on the dstChain\n /// @param _amount amount of the tokens to transfer\n /// @param _useZro indicates to use zro to pay L0 fees\n /// @param _adapterParams flexible bytes array to indicate messaging adapter services in L0\n function estimateSendFee(\n uint16 _dstChainId,\n bytes calldata _toAddress,\n uint256 _amount,\n bool _useZro,\n bytes calldata _adapterParams\n ) external view returns (uint256 nativeFee, uint256 zroFee);\n\n /// @notice Sends `_amount` amount of token to (`_dstChainId`, `_toAddress`)\n /// @param _dstChainId the destination chain identifier\n /// @param _toAddress can be any size depending on the `dstChainId`.\n /// @param _amount the quantity of tokens in wei\n /// @param _refundAddress the address LayerZero refunds if too much message fee is sent\n /// @param _zroPaymentAddress set to address(0x0) if not paying in ZRO (LayerZero Token)\n /// @param _adapterParams is a flexible bytes array to indicate messaging adapter services\n function send(\n uint16 _dstChainId,\n bytes calldata _toAddress,\n uint256 _amount,\n address payable _refundAddress,\n address _zroPaymentAddress,\n bytes calldata _adapterParams\n ) external payable;\n\n /// @notice Sends `_amount` amount of credit to (`_dstChainId`, `_toAddress`)\n /// @param _dstChainId the destination chain identifier\n /// @param _toAddress can be any size depending on the `dstChainId`.\n /// @param _amount the quantity of credit to send in wei\n /// @param _refundAddress the address LayerZero refunds if too much message fee is sent\n /// @param _zroPaymentAddress set to address(0x0) if not paying in ZRO (LayerZero Token)\n /// @param _adapterParams is a flexible bytes array to indicate messaging adapter services\n function sendCredit(\n uint16 _dstChainId,\n bytes calldata _toAddress,\n uint256 _amount,\n address payable _refundAddress,\n address _zroPaymentAddress,\n bytes calldata _adapterParams\n ) external payable;\n\n /// @notice Sends `_amount` amount of token to (`_dstChainId`, `_toAddress`)\n /// @param _dstChainId The destination chain identifier\n /// @param _toAddress Can be any size depending on the `dstChainId`.\n /// @param _amount Quantity of tokens in wei\n /// @param _refundAddress Address LayerZero refunds if too much message fee is sent\n /// @param _zroPaymentAddress Set to address(0x0) if not paying in ZRO (LayerZero Token)\n /// @param _adapterParams Flexible bytes array to indicate messaging adapter services\n /// @param deadline Deadline parameter for the signature to be valid\n /// @dev The `v`, `r`, and `s` parameters are used as signature data\n function sendWithPermit(\n uint16 _dstChainId,\n bytes memory _toAddress,\n uint256 _amount,\n address payable _refundAddress,\n address _zroPaymentAddress,\n bytes memory _adapterParams,\n uint256 deadline,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) external payable;\n\n /// @notice Withdraws amount of canonical token from the `msg.sender` balance and sends it to the recipient\n /// @param amount Amount to withdraw\n /// @param recipient Address to send the canonical token to\n /// @return The amount of canonical token sent\n function withdraw(uint256 amount, address recipient) external returns (uint256);\n\n /// @dev Emitted when `_amount` tokens are moved from the `_sender` to (`_dstChainId`, `_toAddress`)\n /// `_nonce` is the outbound nonce\n event SendToChain(\n address indexed _sender,\n uint16 indexed _dstChainId,\n bytes indexed _toAddress,\n uint256 _amount,\n uint64 _nonce\n );\n\n /// @dev Emitted when `_amount` tokens are received from `_srcChainId` into the `_toAddress` on the local chain.\n /// `_nonce` is the inbound nonce.\n event ReceiveFromChain(\n uint16 indexed _srcChainId,\n bytes indexed _srcAddress,\n address indexed _toAddress,\n uint256 _amount,\n uint64 _nonce\n );\n}\n\n/// @dev Interface of the OFT standard\ninterface IOFT is IOFTCore, IERC20 {\n\n}\n" + }, + "contracts/agToken/layerZero/utils/NonblockingLzApp.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.12;\n\nimport \"@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol\";\nimport \"../../../interfaces/external/layerZero/ILayerZeroReceiver.sol\";\nimport \"../../../interfaces/external/layerZero/ILayerZeroUserApplicationConfig.sol\";\nimport \"../../../interfaces/external/layerZero/ILayerZeroEndpoint.sol\";\nimport \"../../../interfaces/ITreasury.sol\";\n\n/// @title NonblockingLzApp\n/// @author Angle Labs, Inc., forked from https://github.com/LayerZero-Labs/solidity-examples/\n/// @notice Base contract for bridging using LayerZero\nabstract contract NonblockingLzApp is Initializable, ILayerZeroReceiver, ILayerZeroUserApplicationConfig {\n /// @notice Layer Zero endpoint\n ILayerZeroEndpoint public lzEndpoint;\n\n /// @notice Maps chainIds to failed messages to retry them\n mapping(uint16 => mapping(bytes => mapping(uint64 => bytes32))) public failedMessages;\n\n /// @notice Maps chainIds to their OFT address\n mapping(uint16 => bytes) public trustedRemoteLookup;\n\n /// @notice Reference to the treasury contract to fetch access control\n address public treasury;\n\n /// @notice Maps pairs of (`to` chain, `packetType`) to the minimum amount of gas needed on the destination chain\n mapping(uint16 => mapping(uint16 => uint256)) public minDstGasLookup;\n\n /// @notice For future LayerZero compatibility\n address public precrime;\n\n // ================================== Events ===================================\n\n event SetTrustedRemote(uint16 _srcChainId, bytes _srcAddress);\n event MessageFailed(uint16 _srcChainId, bytes _srcAddress, uint64 _nonce, bytes _payload);\n\n // =============================== Errors ================================\n\n error NotGovernor();\n error NotGovernorOrGuardian();\n error InsufficientGas();\n error InvalidEndpoint();\n error InvalidSource();\n error InvalidCaller();\n error InvalidParams();\n error InvalidPayload();\n error ZeroAddress();\n\n // ============================= Constructor ===================================\n\n //solhint-disable-next-line\n function __LzAppUpgradeable_init(address _endpoint, address _treasury) internal {\n if (_endpoint == address(0) || _treasury == address(0)) revert ZeroAddress();\n lzEndpoint = ILayerZeroEndpoint(_endpoint);\n treasury = _treasury;\n }\n\n // =============================== Modifiers ===================================\n\n /// @notice Checks whether the `msg.sender` has the governor role or the guardian role\n modifier onlyGovernorOrGuardian() {\n if (!ITreasury(treasury).isGovernorOrGuardian(msg.sender)) revert NotGovernorOrGuardian();\n _;\n }\n\n // ==================== External Permissionless Functions ======================\n\n /// @notice Receives a message from the LZ endpoint and process it\n /// @param _srcChainId ChainId of the source chain - LayerZero standard\n /// @param _srcAddress Sender of the source chain\n /// @param _nonce Nounce of the message\n /// @param _payload Data: recipient address and amount\n function lzReceive(\n uint16 _srcChainId,\n bytes memory _srcAddress,\n uint64 _nonce,\n bytes memory _payload\n ) public virtual override {\n // lzReceive must be called by the endpoint for security\n if (msg.sender != address(lzEndpoint)) revert InvalidEndpoint();\n\n bytes memory trustedRemote = trustedRemoteLookup[_srcChainId];\n // if will still block the message pathway from (srcChainId, srcAddress). should not receive message from untrusted remote.\n if (_srcAddress.length != trustedRemote.length || keccak256(_srcAddress) != keccak256(trustedRemote))\n revert InvalidSource();\n\n _blockingLzReceive(_srcChainId, _srcAddress, _nonce, _payload);\n }\n\n /// @notice Retries a message that previously failed and was stored\n /// @param _srcChainId ChainId of the source chain - LayerZero standard\n /// @param _srcAddress Sender of the source chain\n /// @param _nonce Nounce of the message\n /// @param _payload Data: recipient address and amount\n function retryMessage(\n uint16 _srcChainId,\n bytes memory _srcAddress,\n uint64 _nonce,\n bytes memory _payload\n ) public payable virtual {\n // assert there is message to retry\n bytes32 payloadHash = failedMessages[_srcChainId][_srcAddress][_nonce];\n if (payloadHash == bytes32(0) || keccak256(_payload) != payloadHash) revert InvalidPayload();\n // clear the stored message\n failedMessages[_srcChainId][_srcAddress][_nonce] = bytes32(0);\n // execute the message. revert if it fails again\n _nonblockingLzReceive(_srcChainId, _srcAddress, _nonce, _payload);\n }\n\n // ============================= Internal Functions ===================================\n\n /// @notice Handles message receptions in a non blocking way\n /// @param _srcChainId ChainId of the source chain - LayerZero standard\n /// @param _srcAddress Sender of the source chain\n /// @param _nonce Nounce of the message\n /// @param _payload Data: recipient address and amount\n /// @dev public for the needs of try / catch but effectively internal\n function nonblockingLzReceive(\n uint16 _srcChainId,\n bytes memory _srcAddress,\n uint64 _nonce,\n bytes memory _payload\n ) public virtual {\n // only internal transaction\n if (msg.sender != address(this)) revert InvalidCaller();\n _nonblockingLzReceive(_srcChainId, _srcAddress, _nonce, _payload);\n }\n\n /// @notice Handles message receptions in a non blocking way\n /// @param _srcChainId ChainId of the source chain - LayerZero standard\n /// @param _srcAddress Sender of the source chain\n /// @param _nonce Nounce of the message\n /// @param _payload Data: recipient address and amount\n function _nonblockingLzReceive(\n uint16 _srcChainId,\n bytes memory _srcAddress,\n uint64 _nonce,\n bytes memory _payload\n ) internal virtual;\n\n /// @notice Handles message receptions in a blocking way\n /// @param _srcChainId ChainId of the source chain - LayerZero standard\n /// @param _srcAddress Sender of the source chain\n /// @param _nonce Nounce of the message\n /// @param _payload Data: recipient address and amount\n function _blockingLzReceive(\n uint16 _srcChainId,\n bytes memory _srcAddress,\n uint64 _nonce,\n bytes memory _payload\n ) internal {\n // try-catch all errors/exceptions\n try this.nonblockingLzReceive(_srcChainId, _srcAddress, _nonce, _payload) {\n // do nothing\n } catch {\n // error / exception\n failedMessages[_srcChainId][_srcAddress][_nonce] = keccak256(_payload);\n emit MessageFailed(_srcChainId, _srcAddress, _nonce, _payload);\n }\n }\n\n /// @notice Sends a message to the LZ endpoint and process it\n /// @param _dstChainId L0 defined chain id to send tokens too\n /// @param _payload Data: recipient address and amount\n /// @param _refundAddress Address LayerZero refunds if too much message fee is sent\n /// @param _zroPaymentAddress Set to address(0x0) if not paying in ZRO (LayerZero Token)\n /// @param _adapterParams Flexible bytes array to indicate messaging adapter services in L0\n function _lzSend(\n uint16 _dstChainId,\n bytes memory _payload,\n address payable _refundAddress,\n address _zroPaymentAddress,\n bytes memory _adapterParams\n ) internal virtual {\n bytes memory trustedRemote = trustedRemoteLookup[_dstChainId];\n if (trustedRemote.length == 0) revert InvalidSource();\n //solhint-disable-next-line\n lzEndpoint.send{ value: msg.value }(\n _dstChainId,\n trustedRemote,\n _payload,\n _refundAddress,\n _zroPaymentAddress,\n _adapterParams\n );\n }\n\n /// @notice Checks the gas limit of a given transaction\n function _checkGasLimit(\n uint16 _dstChainId,\n uint16 _type,\n bytes memory _adapterParams,\n uint256 _extraGas\n ) internal view virtual {\n uint256 minGasLimit = minDstGasLookup[_dstChainId][_type] + _extraGas;\n if (minGasLimit == 0 || minGasLimit > _getGasLimit(_adapterParams)) revert InsufficientGas();\n }\n\n /// @notice Gets the gas limit from the `_adapterParams` parameter\n function _getGasLimit(bytes memory _adapterParams) internal pure virtual returns (uint256 gasLimit) {\n if (_adapterParams.length < 34) revert InvalidParams();\n // solhint-disable-next-line\n assembly {\n gasLimit := mload(add(_adapterParams, 34))\n }\n }\n\n // ======================= Governance Functions ================================\n\n /// @notice Sets the corresponding address on an other chain.\n /// @param _srcChainId ChainId of the source chain - LayerZero standard\n /// @param _srcAddress Address on the source chain\n /// @dev Used for both receiving and sending message\n /// @dev There can only be one trusted source per chain\n /// @dev Allows owner to set it multiple times.\n function setTrustedRemote(uint16 _srcChainId, bytes calldata _srcAddress) external onlyGovernorOrGuardian {\n trustedRemoteLookup[_srcChainId] = _srcAddress;\n emit SetTrustedRemote(_srcChainId, _srcAddress);\n }\n\n /// @notice Fetches the default LZ config\n function getConfig(\n uint16 _version,\n uint16 _chainId,\n address,\n uint256 _configType\n ) external view returns (bytes memory) {\n return lzEndpoint.getConfig(_version, _chainId, address(this), _configType);\n }\n\n /// @notice Overrides the default LZ config\n function setConfig(\n uint16 _version,\n uint16 _chainId,\n uint256 _configType,\n bytes calldata _config\n ) external override onlyGovernorOrGuardian {\n lzEndpoint.setConfig(_version, _chainId, _configType, _config);\n }\n\n /// @notice Overrides the default LZ config\n function setSendVersion(uint16 _version) external override onlyGovernorOrGuardian {\n lzEndpoint.setSendVersion(_version);\n }\n\n /// @notice Overrides the default LZ config\n function setReceiveVersion(uint16 _version) external override onlyGovernorOrGuardian {\n lzEndpoint.setReceiveVersion(_version);\n }\n\n /// @notice Unpauses the receive functionalities\n function forceResumeReceive(\n uint16 _srcChainId,\n bytes calldata _srcAddress\n ) external override onlyGovernorOrGuardian {\n lzEndpoint.forceResumeReceive(_srcChainId, _srcAddress);\n }\n\n /// @notice Sets the minimum gas parameter for a packet type on a given chain\n function setMinDstGas(uint16 _dstChainId, uint16 _packetType, uint256 _minGas) external onlyGovernorOrGuardian {\n if (_minGas == 0) revert InvalidParams();\n minDstGasLookup[_dstChainId][_packetType] = _minGas;\n }\n\n /// @notice Sets the precrime variable\n function setPrecrime(address _precrime) external onlyGovernorOrGuardian {\n precrime = _precrime;\n }\n\n // ======================= View Functions ================================\n\n /// @notice Checks if the `_srcAddress` corresponds to the trusted source\n function isTrustedRemote(uint16 _srcChainId, bytes calldata _srcAddress) external view returns (bool) {\n bytes memory trustedSource = trustedRemoteLookup[_srcChainId];\n return keccak256(trustedSource) == keccak256(_srcAddress);\n }\n\n uint256[44] private __gap;\n}\n" + }, + "contracts/agToken/layerZero/utils/OFTCore.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.12;\n\nimport \"./NonblockingLzApp.sol\";\nimport \"./IOFTCore.sol\";\nimport \"@openzeppelin/contracts-upgradeable/utils/introspection/ERC165Upgradeable.sol\";\n\n/// @title OFTCore\n/// @author Forked from https://github.com/LayerZero-Labs/solidity-examples/blob/main/contracts/token/oft/OFTCore.sol\n/// but with slight modifications from the Angle Labs, Inc. which added return values to the `_creditTo` and `_debitFrom` functions\n/// @notice Base contract for bridging using LayerZero\nabstract contract OFTCore is NonblockingLzApp, ERC165Upgradeable, IOFTCore {\n /// @notice Amount of additional gas specified\n uint256 public constant EXTRA_GAS = 200000;\n /// @notice Packet type for token transfer\n uint16 public constant PT_SEND = 0;\n\n /// @notice Whether to use custom parameters in transactions\n uint8 public useCustomAdapterParams;\n\n // ==================== External Permissionless Functions ======================\n\n /// @inheritdoc IOFTCore\n function sendWithPermit(\n uint16 _dstChainId,\n bytes memory _toAddress,\n uint256 _amount,\n address payable _refundAddress,\n address _zroPaymentAddress,\n bytes memory _adapterParams,\n uint256 deadline,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) public payable virtual;\n\n /// @inheritdoc IOFTCore\n function send(\n uint16 _dstChainId,\n bytes memory _toAddress,\n uint256 _amount,\n address payable _refundAddress,\n address _zroPaymentAddress,\n bytes memory _adapterParams\n ) public payable virtual {\n _checkAdapterParams(_dstChainId, PT_SEND, _adapterParams, EXTRA_GAS);\n _amount = _debitFrom(_dstChainId, _toAddress, _amount);\n\n bytes memory payload = abi.encode(_toAddress, _amount);\n _lzSend(_dstChainId, payload, _refundAddress, _zroPaymentAddress, _adapterParams);\n\n uint64 nonce = lzEndpoint.getOutboundNonce(_dstChainId, address(this));\n emit SendToChain(msg.sender, _dstChainId, _toAddress, _amount, nonce);\n }\n\n /// @inheritdoc IOFTCore\n function sendCredit(\n uint16 _dstChainId,\n bytes memory _toAddress,\n uint256 _amount,\n address payable _refundAddress,\n address _zroPaymentAddress,\n bytes memory _adapterParams\n ) public payable virtual {\n _checkAdapterParams(_dstChainId, PT_SEND, _adapterParams, EXTRA_GAS);\n _amount = _debitCreditFrom(_dstChainId, _toAddress, _amount);\n\n _send(_dstChainId, _toAddress, _amount, _refundAddress, _zroPaymentAddress, _adapterParams);\n }\n\n /// @inheritdoc IOFTCore\n function withdraw(uint256 amount, address recipient) external virtual returns (uint256);\n\n /// @notice Sets whether custom adapter parameters can be used or not\n function setUseCustomAdapterParams(uint8 _useCustomAdapterParams) public virtual onlyGovernorOrGuardian {\n useCustomAdapterParams = _useCustomAdapterParams;\n }\n\n // =========================== Internal Functions ==============================\n\n /// @notice Internal function to send `_amount` amount of token to (`_dstChainId`, `_toAddress`)\n /// @param _dstChainId the destination chain identifier\n /// @param _toAddress can be any size depending on the `dstChainId`.\n /// @param _amount the quantity of tokens in wei\n /// @param _refundAddress the address LayerZero refunds if too much message fee is sent\n /// @param _zroPaymentAddress set to address(0x0) if not paying in ZRO (LayerZero Token)\n /// @param _adapterParams is a flexible bytes array to indicate messaging adapter services\n /// @dev Accounting and checks should be performed beforehand\n function _send(\n uint16 _dstChainId,\n bytes memory _toAddress,\n uint256 _amount,\n address payable _refundAddress,\n address _zroPaymentAddress,\n bytes memory _adapterParams\n ) internal {\n bytes memory payload = abi.encode(_toAddress, _amount);\n _lzSend(_dstChainId, payload, _refundAddress, _zroPaymentAddress, _adapterParams);\n\n uint64 nonce = lzEndpoint.getOutboundNonce(_dstChainId, address(this));\n emit SendToChain(msg.sender, _dstChainId, _toAddress, _amount, nonce);\n }\n\n /// @inheritdoc NonblockingLzApp\n function _nonblockingLzReceive(\n uint16 _srcChainId,\n bytes memory _srcAddress,\n uint64 _nonce,\n bytes memory _payload\n ) internal virtual override {\n // decode and load the toAddress\n (bytes memory toAddressBytes, uint256 amount) = abi.decode(_payload, (bytes, uint256));\n address toAddress;\n //solhint-disable-next-line\n assembly {\n toAddress := mload(add(toAddressBytes, 20))\n }\n amount = _creditTo(_srcChainId, toAddress, amount);\n\n emit ReceiveFromChain(_srcChainId, _srcAddress, toAddress, amount, _nonce);\n }\n\n /// @notice Checks the adapter parameters given during the smart contract call\n function _checkAdapterParams(\n uint16 _dstChainId,\n uint16 _pkType,\n bytes memory _adapterParams,\n uint256 _extraGas\n ) internal virtual {\n if (useCustomAdapterParams > 0) _checkGasLimit(_dstChainId, _pkType, _adapterParams, _extraGas);\n else if (_adapterParams.length != 0) revert InvalidParams();\n }\n\n /// @notice Makes accountability when bridging from this contract using canonical token\n /// @param _dstChainId ChainId of the destination chain - LayerZero standard\n /// @param _toAddress Recipient on the destination chain\n /// @param _amount Amount to bridge\n function _debitFrom(\n uint16 _dstChainId,\n bytes memory _toAddress,\n uint256 _amount\n ) internal virtual returns (uint256);\n\n /// @notice Makes accountability when bridging from this contract's credit\n /// @param _dstChainId ChainId of the destination chain - LayerZero standard\n /// @param _toAddress Recipient on the destination chain\n /// @param _amount Amount to bridge\n function _debitCreditFrom(\n uint16 _dstChainId,\n bytes memory _toAddress,\n uint256 _amount\n ) internal virtual returns (uint256);\n\n /// @notice Makes accountability when bridging to this contract\n /// @param _srcChainId ChainId of the source chain - LayerZero standard\n /// @param _toAddress Recipient on this chain\n /// @param _amount Amount to bridge\n function _creditTo(uint16 _srcChainId, address _toAddress, uint256 _amount) internal virtual returns (uint256);\n\n // ========================== View Functions ===================================\n\n /// @inheritdoc ERC165Upgradeable\n function supportsInterface(\n bytes4 interfaceId\n ) public view virtual override(ERC165Upgradeable, IERC165) returns (bool) {\n return interfaceId == type(IOFTCore).interfaceId || super.supportsInterface(interfaceId);\n }\n\n /// @inheritdoc IOFTCore\n function estimateSendFee(\n uint16 _dstChainId,\n bytes memory _toAddress,\n uint256 _amount,\n bool _useZro,\n bytes memory _adapterParams\n ) public view virtual override returns (uint256 nativeFee, uint256 zroFee) {\n // mock the payload for send()\n bytes memory payload = abi.encode(_toAddress, _amount);\n return lzEndpoint.estimateFees(_dstChainId, address(this), payload, _useZro, _adapterParams);\n }\n\n uint256[49] private __gap;\n}\n" + }, + "contracts/agToken/polygon/TokenPolygonUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.12;\n\nimport \"./utils/ERC20UpgradeableCustom.sol\";\nimport \"@openzeppelin/contracts-upgradeable/access/AccessControlUpgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/utils/cryptography/draft-EIP712Upgradeable.sol\";\nimport \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\nimport \"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\";\n\nimport \"../../interfaces/IAgToken.sol\";\nimport \"../../interfaces/ITreasury.sol\";\n\ninterface IChildToken {\n function deposit(address user, bytes calldata depositData) external;\n\n function withdraw(uint256 amount) external;\n}\n\ncontract TokenPolygonUpgradeable is\n Initializable,\n ERC20UpgradeableCustom,\n AccessControlUpgradeable,\n EIP712Upgradeable,\n IChildToken\n{\n bytes32 public constant DEPOSITOR_ROLE = keccak256(\"DEPOSITOR_ROLE\");\n\n /// @dev Emitted when the child chain manager changes\n event ChildChainManagerAdded(address newAddress);\n event ChildChainManagerRevoked(address oldAddress);\n\n constructor() initializer {}\n\n function initialize(\n string memory _name,\n string memory _symbol,\n address childChainManager,\n address guardian\n ) public initializer {\n __ERC20_init(_name, _symbol);\n __AccessControl_init();\n _setupRole(DEFAULT_ADMIN_ROLE, guardian);\n _setupRole(DEPOSITOR_ROLE, childChainManager);\n __EIP712_init(_name, \"1\");\n }\n\n /**\n * @notice Called when the bridge has tokens to mint\n * @param user Address to mint the token to\n * @param depositData Encoded amount to mint\n */\n function deposit(address user, bytes calldata depositData) external override {\n require(hasRole(DEPOSITOR_ROLE, msg.sender));\n uint256 amount = abi.decode(depositData, (uint256));\n _mint(user, amount);\n }\n\n /**\n * @notice Called when user wants to withdraw tokens back to root chain\n * @dev Should burn user's tokens. This transaction will be verified when exiting on root chain\n * @param amount Amount of tokens to withdraw\n */\n function withdraw(uint256 amount) external override {\n _burn(_msgSender(), amount);\n }\n\n // =============================================================================\n // ======================= New data added for the upgrade ======================\n // =============================================================================\n\n mapping(address => bool) public isMinter;\n /// @notice Reference to the treasury contract which can grant minting rights\n address public treasury;\n /// @notice Boolean to check whether the contract has been reinitialized after its upgrade\n bool public treasuryInitialized;\n\n using SafeERC20 for IERC20;\n\n /// @notice Base used for fee computation\n uint256 public constant BASE_PARAMS = 10 ** 9;\n\n // =============================== Bridging Data ===============================\n\n /// @notice Struct with some data about a specific bridge token\n struct BridgeDetails {\n // Limit on the balance of bridge token held by the contract: it is designed\n // to reduce the exposure of the system to hacks\n uint256 limit;\n // Limit on the hourly volume of token minted through this bridge\n // Technically the limit over a rolling hour is hourlyLimit x2 as hourly limit\n // is enforced only between x:00 and x+1:00\n uint256 hourlyLimit;\n // Fee taken for swapping in and out the token\n uint64 fee;\n // Whether the associated token is allowed or not\n bool allowed;\n // Whether swapping in and out from the associated token is paused or not\n bool paused;\n }\n\n /// @notice Maps a bridge token to data\n mapping(address => BridgeDetails) public bridges;\n /// @notice List of all bridge tokens\n address[] public bridgeTokensList;\n /// @notice Maps a bridge token to the associated hourly volume\n mapping(address => mapping(uint256 => uint256)) public usage;\n /// @notice Maps an address to whether it is exempt of fees for when it comes to swapping in and out\n mapping(address => uint256) public isFeeExempt;\n /// @notice Limit to the amount of tokens that can be sent from that chain to another chain\n uint256 public chainTotalHourlyLimit;\n /// @notice Usage per hour on that chain. Maps an hourly timestamp to the total volume swapped out on the chain\n mapping(uint256 => uint256) public chainTotalUsage;\n\n uint256[42] private __gap;\n\n // ================================== Events ===================================\n\n event BridgeTokenAdded(address indexed bridgeToken, uint256 limit, uint256 hourlyLimit, uint64 fee, bool paused);\n event BridgeTokenToggled(address indexed bridgeToken, bool toggleStatus);\n event BridgeTokenRemoved(address indexed bridgeToken);\n event BridgeTokenFeeUpdated(address indexed bridgeToken, uint64 fee);\n event BridgeTokenLimitUpdated(address indexed bridgeToken, uint256 limit);\n event BridgeTokenHourlyLimitUpdated(address indexed bridgeToken, uint256 hourlyLimit);\n event HourlyLimitUpdated(uint256 hourlyLimit);\n event FeeToggled(address indexed theAddress, uint256 toggleStatus);\n event KeeperToggled(address indexed keeper, bool toggleStatus);\n event MinterToggled(address indexed minter);\n event Recovered(address indexed token, address indexed to, uint256 amount);\n event TreasuryUpdated(address indexed _treasury);\n\n // ================================== Errors ===================================\n\n error AssetStillControlledInReserves();\n error BurnAmountExceedsAllowance();\n error HourlyLimitExceeded();\n error InvalidSender();\n error InvalidToken();\n error InvalidTreasury();\n error NotGovernor();\n error NotGovernorOrGuardian();\n error NotMinter();\n error NotTreasury();\n error TooBigAmount();\n error TooHighParameterValue();\n error TreasuryAlreadyInitialized();\n error ZeroAddress();\n\n /// @notice Checks to see if it is the `Treasury` calling this contract\n /// @dev There is no Access Control here, because it can be handled cheaply through this modifier\n modifier onlyTreasury() {\n if (msg.sender != treasury) revert NotTreasury();\n _;\n }\n\n /// @notice Checks whether the sender has the minting right\n modifier onlyMinter() {\n if (!isMinter[msg.sender]) revert NotMinter();\n _;\n }\n\n /// @notice Checks whether the `msg.sender` has the governor role or not\n modifier onlyGovernor() {\n if (!ITreasury(treasury).isGovernor(msg.sender)) revert NotGovernor();\n _;\n }\n\n /// @notice Checks whether the `msg.sender` has the governor role or the guardian role\n modifier onlyGovernorOrGuardian() {\n if (!ITreasury(treasury).isGovernorOrGuardian(msg.sender)) revert NotGovernorOrGuardian();\n _;\n }\n\n /// @notice Sets up the treasury contract on Polygon after the upgrade\n /// @param _treasury Address of the treasury contract\n function setUpTreasury(address _treasury) external {\n // Only governor on Polygon\n if (msg.sender != 0xdA2D2f638D6fcbE306236583845e5822554c02EA) revert NotGovernor();\n if (address(ITreasury(_treasury).stablecoin()) != address(this)) revert InvalidTreasury();\n if (treasuryInitialized) revert TreasuryAlreadyInitialized();\n treasury = _treasury;\n treasuryInitialized = true;\n emit TreasuryUpdated(_treasury);\n }\n\n // =========================== External Function ===============================\n\n /// @notice Allows anyone to burn agToken without redeeming collateral back\n /// @param amount Amount of stablecoins to burn\n /// @dev This function can typically be called if there is a settlement mechanism to burn stablecoins\n function burnStablecoin(uint256 amount) external {\n _burnCustom(msg.sender, amount);\n }\n\n // ======================= Minter Role Only Functions ==========================\n\n function burnSelf(uint256 amount, address burner) external onlyMinter {\n _burnCustom(burner, amount);\n }\n\n function burnFrom(uint256 amount, address burner, address sender) external onlyMinter {\n _burnFromNoRedeem(amount, burner, sender);\n }\n\n function mint(address account, uint256 amount) external onlyMinter {\n _mint(account, amount);\n }\n\n // ======================= Treasury Only Functions =============================\n\n function addMinter(address minter) external onlyTreasury {\n isMinter[minter] = true;\n emit MinterToggled(minter);\n }\n\n function removeMinter(address minter) external {\n if (msg.sender != address(treasury) && msg.sender != minter) revert InvalidSender();\n isMinter[minter] = false;\n emit MinterToggled(minter);\n }\n\n function setTreasury(address _treasury) external onlyTreasury {\n treasury = _treasury;\n emit TreasuryUpdated(_treasury);\n }\n\n // ============================ Internal Function ==============================\n\n /// @notice Internal version of the function `burnFromNoRedeem`\n /// @param amount Amount to burn\n /// @dev It is at the level of this function that allowance checks are performed\n function _burnFromNoRedeem(uint256 amount, address burner, address sender) internal {\n if (burner != sender) {\n uint256 currentAllowance = allowance(burner, sender);\n if (currentAllowance < amount) revert BurnAmountExceedsAllowance();\n _approve(burner, sender, currentAllowance - amount);\n }\n _burnCustom(burner, amount);\n }\n\n // ==================== External Permissionless Functions ======================\n\n /// @notice Returns the list of all supported bridge tokens\n /// @dev Helpful for UIs\n function allBridgeTokens() external view returns (address[] memory) {\n return bridgeTokensList;\n }\n\n /// @notice Returns the current volume for a bridge, for the current hour\n /// @dev Helpful for UIs\n function currentUsage(address bridge) external view returns (uint256) {\n return usage[bridge][block.timestamp / 3600];\n }\n\n /// @notice Returns the current total volume on the chain for the current hour\n /// @dev Helpful for UIs\n function currentTotalUsage() external view returns (uint256) {\n return chainTotalUsage[block.timestamp / 3600];\n }\n\n /// @notice Mints the canonical token from a supported bridge token\n /// @param bridgeToken Bridge token to use to mint\n /// @param amount Amount of bridge tokens to send\n /// @param to Address to which the stablecoin should be sent\n /// @dev Some fees may be taken by the protocol depending on the token used and on the address calling\n function swapIn(address bridgeToken, uint256 amount, address to) external returns (uint256) {\n BridgeDetails memory bridgeDetails = bridges[bridgeToken];\n if (!bridgeDetails.allowed || bridgeDetails.paused) revert InvalidToken();\n uint256 balance = IERC20(bridgeToken).balanceOf(address(this));\n if (balance + amount > bridgeDetails.limit) {\n // In case someone maliciously sends tokens to this contract\n // Or the limit changes\n if (bridgeDetails.limit > balance) amount = bridgeDetails.limit - balance;\n else {\n amount = 0;\n }\n }\n\n // Checking requirement on the hourly volume\n uint256 hour = block.timestamp / 3600;\n uint256 hourlyUsage = usage[bridgeToken][hour] + amount;\n if (hourlyUsage > bridgeDetails.hourlyLimit) {\n // Edge case when the hourly limit changes\n if (bridgeDetails.hourlyLimit > usage[bridgeToken][hour])\n amount = bridgeDetails.hourlyLimit - usage[bridgeToken][hour];\n else {\n amount = 0;\n }\n }\n usage[bridgeToken][hour] += amount;\n\n IERC20(bridgeToken).safeTransferFrom(msg.sender, address(this), amount);\n uint256 canonicalOut = amount;\n // Computing fees\n if (isFeeExempt[msg.sender] == 0) {\n canonicalOut -= (canonicalOut * bridgeDetails.fee) / BASE_PARAMS;\n }\n _mint(to, canonicalOut);\n return canonicalOut;\n }\n\n /// @notice Burns the canonical token in exchange for a bridge token\n /// @param bridgeToken Bridge token required\n /// @param amount Amount of canonical tokens to burn\n /// @param to Address to which the bridge token should be sent\n /// @dev Some fees may be taken by the protocol depending on the token used and on the address calling\n function swapOut(address bridgeToken, uint256 amount, address to) external returns (uint256) {\n BridgeDetails memory bridgeDetails = bridges[bridgeToken];\n if (!bridgeDetails.allowed || bridgeDetails.paused) revert InvalidToken();\n\n uint256 hour = block.timestamp / 3600;\n uint256 hourlyUsage = chainTotalUsage[hour] + amount;\n // If the amount being swapped out exceeds the limit, we revert\n // We don't want to change the amount being swapped out.\n // The user can decide to send another tx with the correct amount to reach the limit\n if (hourlyUsage > chainTotalHourlyLimit) revert HourlyLimitExceeded();\n chainTotalUsage[hour] = hourlyUsage;\n\n _burnCustom(msg.sender, amount);\n uint256 bridgeOut = amount;\n if (isFeeExempt[msg.sender] == 0) {\n bridgeOut -= (bridgeOut * bridgeDetails.fee) / BASE_PARAMS;\n }\n IERC20(bridgeToken).safeTransfer(to, bridgeOut);\n return bridgeOut;\n }\n\n // ======================= Governance Functions ================================\n\n /// @notice Adds support for a bridge token\n /// @param bridgeToken Bridge token to add: it should be a version of the stablecoin from another bridge\n /// @param limit Limit on the balance of bridge token this contract could hold\n /// @param hourlyLimit Limit on the hourly volume for this bridge\n /// @param paused Whether swapping for this token should be paused or not\n /// @param fee Fee taken upon swapping for or against this token\n function addBridgeToken(\n address bridgeToken,\n uint256 limit,\n uint256 hourlyLimit,\n uint64 fee,\n bool paused\n ) external onlyGovernor {\n if (bridges[bridgeToken].allowed || bridgeToken == address(0)) revert InvalidToken();\n if (fee > BASE_PARAMS) revert TooHighParameterValue();\n BridgeDetails memory _bridge;\n _bridge.limit = limit;\n _bridge.hourlyLimit = hourlyLimit;\n _bridge.paused = paused;\n _bridge.fee = fee;\n _bridge.allowed = true;\n bridges[bridgeToken] = _bridge;\n bridgeTokensList.push(bridgeToken);\n emit BridgeTokenAdded(bridgeToken, limit, hourlyLimit, fee, paused);\n }\n\n /// @notice Removes support for a token\n /// @param bridgeToken Address of the bridge token to remove support for\n function removeBridgeToken(address bridgeToken) external onlyGovernor {\n if (IERC20(bridgeToken).balanceOf(address(this)) != 0) revert AssetStillControlledInReserves();\n delete bridges[bridgeToken];\n // Deletion from `bridgeTokensList` loop\n uint256 bridgeTokensListLength = bridgeTokensList.length;\n for (uint256 i; i < bridgeTokensListLength - 1; ++i) {\n if (bridgeTokensList[i] == bridgeToken) {\n // Replace the `bridgeToken` to remove with the last of the list\n bridgeTokensList[i] = bridgeTokensList[bridgeTokensListLength - 1];\n break;\n }\n }\n // Remove last element in array\n bridgeTokensList.pop();\n emit BridgeTokenRemoved(bridgeToken);\n }\n\n /// @notice Recovers any ERC20 token\n /// @dev Can be used to withdraw bridge tokens for them to be de-bridged on mainnet\n function recoverERC20(address tokenAddress, address to, uint256 amountToRecover) external onlyGovernor {\n IERC20(tokenAddress).safeTransfer(to, amountToRecover);\n emit Recovered(tokenAddress, to, amountToRecover);\n }\n\n /// @notice Updates the `limit` amount for `bridgeToken`\n function setLimit(address bridgeToken, uint256 limit) external onlyGovernorOrGuardian {\n if (!bridges[bridgeToken].allowed) revert InvalidToken();\n bridges[bridgeToken].limit = limit;\n emit BridgeTokenLimitUpdated(bridgeToken, limit);\n }\n\n /// @notice Updates the `hourlyLimit` amount for `bridgeToken`\n function setHourlyLimit(address bridgeToken, uint256 hourlyLimit) external onlyGovernorOrGuardian {\n if (!bridges[bridgeToken].allowed) revert InvalidToken();\n bridges[bridgeToken].hourlyLimit = hourlyLimit;\n emit BridgeTokenHourlyLimitUpdated(bridgeToken, hourlyLimit);\n }\n\n /// @notice Updates the `chainTotalHourlyLimit` amount\n function setChainTotalHourlyLimit(uint256 hourlyLimit) external onlyGovernorOrGuardian {\n chainTotalHourlyLimit = hourlyLimit;\n emit HourlyLimitUpdated(hourlyLimit);\n }\n\n /// @notice Updates the `fee` value for `bridgeToken`\n function setSwapFee(address bridgeToken, uint64 fee) external onlyGovernorOrGuardian {\n if (!bridges[bridgeToken].allowed) revert InvalidToken();\n if (fee > BASE_PARAMS) revert TooHighParameterValue();\n bridges[bridgeToken].fee = fee;\n emit BridgeTokenFeeUpdated(bridgeToken, fee);\n }\n\n /// @notice Pauses or unpauses swapping in and out for a token\n function toggleBridge(address bridgeToken) external onlyGovernorOrGuardian {\n if (!bridges[bridgeToken].allowed) revert InvalidToken();\n bool pausedStatus = bridges[bridgeToken].paused;\n bridges[bridgeToken].paused = !pausedStatus;\n emit BridgeTokenToggled(bridgeToken, !pausedStatus);\n }\n\n /// @notice Toggles fees for the address `theAddress`\n function toggleFeesForAddress(address theAddress) external onlyGovernorOrGuardian {\n uint256 feeExemptStatus = 1 - isFeeExempt[theAddress];\n isFeeExempt[theAddress] = feeExemptStatus;\n emit FeeToggled(theAddress, feeExemptStatus);\n }\n}\n" + }, + "contracts/agToken/polygon/utils/ERC20UpgradeableCustom.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (token/ERC20/ERC20.sol)\n\npragma solidity ^0.8.0;\n\nimport \"@openzeppelin/contracts-upgradeable/token/ERC20/IERC20Upgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/token/ERC20/extensions/IERC20MetadataUpgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/utils/ContextUpgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol\";\n\n/**\n * @dev Implementation of the {IERC20} interface modified by Angle Labs, Inc.\n *\n * This implementation has a custom burn function to avoid having a {Transfer} event to the zero address\n * in some specific burn cases to avoid having Polygon PoS bridge catching this event\n *\n * TIP: For a detailed writeup see our guide\n * https://forum.zeppelin.solutions/t/how-to-implement-erc20-supply-mechanisms/226[How\n * to implement supply mechanisms].\n *\n * We have followed general OpenZeppelin Contracts guidelines: functions revert\n * instead returning `false` on failure. This behavior is nonetheless\n * conventional and does not conflict with the expectations of ERC20\n * applications.\n *\n * Additionally, an {Approval} event is emitted on calls to {transferFrom}.\n * This allows applications to reconstruct the allowance for all accounts just\n * by listening to said events. Other implementations of the EIP may not emit\n * these events, as it isn't required by the specification.\n *\n * Finally, the non-standard {decreaseAllowance} and {increaseAllowance}\n * functions have been added to mitigate the well-known issues around setting\n * allowances. See {IERC20-approve}.\n */\ncontract ERC20UpgradeableCustom is Initializable, ContextUpgradeable, IERC20Upgradeable, IERC20MetadataUpgradeable {\n mapping(address => uint256) private _balances;\n\n mapping(address => mapping(address => uint256)) private _allowances;\n\n uint256 private _totalSupply;\n\n string private _name;\n string private _symbol;\n\n /**\n * @dev Sets the values for {name} and {symbol}.\n *\n * The default value of {decimals} is 18. To select a different value for\n * {decimals} you should overload it.\n *\n * All two of these values are immutable: they can only be set once during\n * construction.\n */\n //solhint-disable-next-line\n function __ERC20_init(string memory name_, string memory symbol_) internal onlyInitializing {\n __Context_init_unchained();\n __ERC20_init_unchained(name_, symbol_);\n }\n\n //solhint-disable-next-line\n function __ERC20_init_unchained(string memory name_, string memory symbol_) internal onlyInitializing {\n _name = name_;\n _symbol = symbol_;\n }\n\n /**\n * @dev Returns the name of the token.\n */\n function name() public view virtual override returns (string memory) {\n return _name;\n }\n\n /**\n * @dev Returns the symbol of the token, usually a shorter version of the\n * name.\n */\n function symbol() public view virtual override returns (string memory) {\n return _symbol;\n }\n\n /**\n * @dev Returns the number of decimals used to get its user representation.\n * For example, if `decimals` equals `2`, a balance of `505` tokens should\n * be displayed to a user as `5.05` (`505 / 10 ** 2`).\n *\n * Tokens usually opt for a value of 18, imitating the relationship between\n * Ether and Wei. This is the value {ERC20} uses, unless this function is\n * overridden;\n *\n * NOTE: This information is only used for _display_ purposes: it in\n * no way affects any of the arithmetic of the contract, including\n * {IERC20-balanceOf} and {IERC20-transfer}.\n */\n function decimals() public view virtual override returns (uint8) {\n return 18;\n }\n\n /**\n * @dev See {IERC20-totalSupply}.\n */\n function totalSupply() public view virtual override returns (uint256) {\n return _totalSupply;\n }\n\n /**\n * @dev See {IERC20-balanceOf}.\n */\n function balanceOf(address account) public view virtual override returns (uint256) {\n return _balances[account];\n }\n\n /**\n * @dev See {IERC20-transfer}.\n *\n * Requirements:\n *\n * - `recipient` cannot be the zero address.\n * - the caller must have a balance of at least `amount`.\n */\n function transfer(address recipient, uint256 amount) public virtual override returns (bool) {\n _transfer(_msgSender(), recipient, amount);\n return true;\n }\n\n /**\n * @dev See {IERC20-allowance}.\n */\n function allowance(address owner, address spender) public view virtual override returns (uint256) {\n return _allowances[owner][spender];\n }\n\n /**\n * @dev See {IERC20-approve}.\n *\n * Requirements:\n *\n * - `spender` cannot be the zero address.\n */\n function approve(address spender, uint256 amount) public virtual override returns (bool) {\n _approve(_msgSender(), spender, amount);\n return true;\n }\n\n /**\n * @dev See {IERC20-transferFrom}.\n *\n * Emits an {Approval} event indicating the updated allowance. This is not\n * required by the EIP. See the note at the beginning of {ERC20}.\n *\n * Requirements:\n *\n * - `sender` and `recipient` cannot be the zero address.\n * - `sender` must have a balance of at least `amount`.\n * - the caller must have allowance for `sender`'s tokens of at least\n * `amount`.\n */\n function transferFrom(address sender, address recipient, uint256 amount) public virtual override returns (bool) {\n _transfer(sender, recipient, amount);\n\n uint256 currentAllowance = _allowances[sender][_msgSender()];\n require(currentAllowance >= amount, \"ERC20: transfer amount exceeds allowance\");\n unchecked {\n _approve(sender, _msgSender(), currentAllowance - amount);\n }\n\n return true;\n }\n\n /**\n * @dev Atomically increases the allowance granted to `spender` by the caller.\n *\n * This is an alternative to {approve} that can be used as a mitigation for\n * problems described in {IERC20-approve}.\n *\n * Emits an {Approval} event indicating the updated allowance.\n *\n * Requirements:\n *\n * - `spender` cannot be the zero address.\n */\n function increaseAllowance(address spender, uint256 addedValue) public virtual returns (bool) {\n _approve(_msgSender(), spender, _allowances[_msgSender()][spender] + addedValue);\n return true;\n }\n\n /**\n * @dev Atomically decreases the allowance granted to `spender` by the caller.\n *\n * This is an alternative to {approve} that can be used as a mitigation for\n * problems described in {IERC20-approve}.\n *\n * Emits an {Approval} event indicating the updated allowance.\n *\n * Requirements:\n *\n * - `spender` cannot be the zero address.\n * - `spender` must have allowance for the caller of at least\n * `subtractedValue`.\n */\n function decreaseAllowance(address spender, uint256 subtractedValue) public virtual returns (bool) {\n uint256 currentAllowance = _allowances[_msgSender()][spender];\n require(currentAllowance >= subtractedValue, \"ERC20: decreased allowance below zero\");\n unchecked {\n _approve(_msgSender(), spender, currentAllowance - subtractedValue);\n }\n\n return true;\n }\n\n /**\n * @dev Moves `amount` of tokens from `sender` to `recipient`.\n *\n * This internal function is equivalent to {transfer}, and can be used to\n * e.g. implement automatic token fees, slashing mechanisms, etc.\n *\n * Emits a {Transfer} event.\n *\n * Requirements:\n *\n * - `sender` cannot be the zero address.\n * - `recipient` cannot be the zero address.\n * - `sender` must have a balance of at least `amount`.\n */\n function _transfer(address sender, address recipient, uint256 amount) internal virtual {\n require(sender != address(0), \"ERC20: transfer from the zero address\");\n require(recipient != address(0), \"ERC20: transfer to the zero address\");\n\n _beforeTokenTransfer(sender, recipient, amount);\n\n uint256 senderBalance = _balances[sender];\n require(senderBalance >= amount, \"ERC20: transfer amount exceeds balance\");\n unchecked {\n _balances[sender] = senderBalance - amount;\n }\n _balances[recipient] += amount;\n\n emit Transfer(sender, recipient, amount);\n\n _afterTokenTransfer(sender, recipient, amount);\n }\n\n /** @dev Creates `amount` tokens and assigns them to `account`, increasing\n * the total supply.\n *\n * Emits a {Transfer} event with `from` set to the zero address.\n *\n * Requirements:\n *\n * - `account` cannot be the zero address.\n */\n function _mint(address account, uint256 amount) internal virtual {\n require(account != address(0), \"ERC20: mint to the zero address\");\n\n _beforeTokenTransfer(address(0), account, amount);\n\n _totalSupply += amount;\n _balances[account] += amount;\n emit Transfer(address(0), account, amount);\n\n _afterTokenTransfer(address(0), account, amount);\n }\n\n /**\n * @dev Destroys `amount` tokens from `account`, reducing the\n * total supply.\n *\n * Emits a {Transfer} event with `to` set to the zero address.\n *\n * Requirements:\n *\n * - `account` cannot be the zero address.\n * - `account` must have at least `amount` tokens.\n */\n function _burn(address account, uint256 amount) internal virtual {\n require(account != address(0), \"ERC20: burn from the zero address\");\n\n _beforeTokenTransfer(account, address(0), amount);\n\n uint256 accountBalance = _balances[account];\n require(accountBalance >= amount, \"ERC20: burn amount exceeds balance\");\n unchecked {\n _balances[account] = accountBalance - amount;\n }\n _totalSupply -= amount;\n\n emit Transfer(account, address(0), amount);\n\n _afterTokenTransfer(account, address(0), amount);\n }\n\n /**\n * @dev Destroys `amount` tokens from `account`, reducing the\n * total supply.\n *\n * Contrary to the other `burn` function, the {Transfer} event is not to the zero address\n * but rather to this address: the reason is that not all burn events should be caught up\n * by the PoS bridge\n *\n * Requirements:\n *\n * - `account` cannot be the zero address.\n * - `account` must have at least `amount` tokens.\n */\n function _burnCustom(address account, uint256 amount) internal virtual {\n require(account != address(0), \"ERC20: burn from the zero address\");\n\n _beforeTokenTransfer(account, address(0), amount);\n\n uint256 accountBalance = _balances[account];\n require(accountBalance >= amount, \"ERC20: burn amount exceeds balance\");\n unchecked {\n _balances[account] = accountBalance - amount;\n }\n _totalSupply -= amount;\n\n emit Transfer(account, address(this), amount);\n\n _afterTokenTransfer(account, address(0), amount);\n }\n\n /**\n * @dev Sets `amount` as the allowance of `spender` over the `owner` s tokens.\n *\n * This internal function is equivalent to `approve`, and can be used to\n * e.g. set automatic allowances for certain subsystems, etc.\n *\n * Emits an {Approval} event.\n *\n * Requirements:\n *\n * - `owner` cannot be the zero address.\n * - `spender` cannot be the zero address.\n */\n function _approve(address owner, address spender, uint256 amount) internal virtual {\n require(owner != address(0), \"ERC20: approve from the zero address\");\n require(spender != address(0), \"ERC20: approve to the zero address\");\n\n _allowances[owner][spender] = amount;\n emit Approval(owner, spender, amount);\n }\n\n /**\n * @dev Hook that is called before any transfer of tokens. This includes\n * minting and burning.\n *\n * Calling conditions:\n *\n * - when `from` and `to` are both non-zero, `amount` of `from`'s tokens\n * will be transferred to `to`.\n * - when `from` is zero, `amount` tokens will be minted for `to`.\n * - when `to` is zero, `amount` of `from`'s tokens will be burned.\n * - `from` and `to` are never both zero.\n *\n * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].\n */\n function _beforeTokenTransfer(address from, address to, uint256 amount) internal virtual {}\n\n /**\n * @dev Hook that is called after any transfer of tokens. This includes\n * minting and burning.\n *\n * Calling conditions:\n *\n * - when `from` and `to` are both non-zero, `amount` of `from`'s tokens\n * has been transferred to `to`.\n * - when `from` is zero, `amount` tokens have been minted for `to`.\n * - when `to` is zero, `amount` of `from`'s tokens have been burned.\n * - `from` and `to` are never both zero.\n *\n * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].\n */\n function _afterTokenTransfer(address from, address to, uint256 amount) internal virtual {}\n\n uint256[45] private __gap;\n}\n" + }, + "contracts/coreBorrow/CoreBorrow.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\n/*\n * █ \n ***** ▓▓▓ \n * ▓▓▓▓▓▓▓ \n * ///. ▓▓▓▓▓▓▓▓▓▓▓▓▓ \n ***** //////// ▓▓▓▓▓▓▓ \n * ///////////// ▓▓▓ \n ▓▓ ////////////////// █ ▓▓ \n ▓▓ ▓▓ /////////////////////// ▓▓ ▓▓ \n ▓▓ ▓▓ //////////////////////////// ▓▓ ▓▓ \n ▓▓ ▓▓ /////////▓▓▓///////▓▓▓///////// ▓▓ ▓▓ \n ▓▓ ,////////////////////////////////////// ▓▓ ▓▓ \n ▓▓ ////////////////////////////////////////// ▓▓ \n ▓▓ //////////////////////▓▓▓▓///////////////////// \n ,//////////////////////////////////////////////////// \n .////////////////////////////////////////////////////////// \n .//////////////////////////██.,//////////////////////////█ \n .//////////////////////████..,./////////////////////██ \n ...////////////////███████.....,.////////////////███ \n ,.,////////////████████ ........,///////////████ \n .,.,//////█████████ ,.......///////████ \n ,..//████████ ........./████ \n ..,██████ .....,███ \n .██ ,.,█ \n \n \n \n ▓▓ ▓▓▓▓▓▓▓▓▓▓ ▓▓▓▓▓▓▓▓▓▓ ▓▓ ▓▓▓▓▓▓▓▓▓▓ \n ▓▓▓▓▓▓ ▓▓▓ ▓▓▓ ▓▓▓ ▓▓ ▓▓ ▓▓▓▓ \n ▓▓▓ ▓▓▓ ▓▓▓ ▓▓▓ ▓▓▓ ▓▓▓ ▓▓ ▓▓▓▓▓ \n ▓▓▓ ▓▓ ▓▓▓ ▓▓▓ ▓▓▓▓▓▓▓▓▓▓ ▓▓▓▓▓▓▓▓▓▓ ▓▓▓▓▓▓▓▓▓▓ \n*/\n\npragma solidity ^0.8.12;\n\nimport \"@openzeppelin/contracts-upgradeable/access/AccessControlEnumerableUpgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol\";\n\nimport \"../interfaces/ICoreBorrow.sol\";\nimport \"../interfaces/IFlashAngle.sol\";\nimport \"../interfaces/ITreasury.sol\";\n\n/// @title CoreBorrow\n/// @author Angle Labs, Inc.\n/// @notice Core contract of the borrowing module. This contract handles the access control across all contracts\n/// (it is read by all treasury contracts), and manages the `flashLoanModule`. It has no minting rights over the\n/// stablecoin contracts\ncontract CoreBorrow is ICoreBorrow, Initializable, AccessControlEnumerableUpgradeable {\n /// @notice Role for guardians\n bytes32 public constant GUARDIAN_ROLE = keccak256(\"GUARDIAN_ROLE\");\n /// @notice Role for governors\n bytes32 public constant GOVERNOR_ROLE = keccak256(\"GOVERNOR_ROLE\");\n /// @notice Role for treasury contract\n bytes32 public constant FLASHLOANER_TREASURY_ROLE = keccak256(\"FLASHLOANER_TREASURY_ROLE\");\n\n // ============================= Reference =====================================\n\n /// @notice Reference to the `flashLoanModule` with minting rights over the different stablecoins of the protocol\n address public flashLoanModule;\n\n // =============================== Events ======================================\n\n event FlashLoanModuleUpdated(address indexed _flashloanModule);\n event CoreUpdated(address indexed _core);\n\n // =============================== Errors ======================================\n\n error InvalidCore();\n error IncompatibleGovernorAndGuardian();\n error NotEnoughGovernorsLeft();\n error ZeroAddress();\n\n /// @notice Initializes the `CoreBorrow` contract and the access control of the borrowing module\n /// @param governor Address of the governor of the Angle Protocol\n /// @param guardian Guardian address of the protocol\n function initialize(address governor, address guardian) public initializer {\n if (governor == address(0) || guardian == address(0)) revert ZeroAddress();\n if (governor == guardian) revert IncompatibleGovernorAndGuardian();\n _setupRole(GOVERNOR_ROLE, governor);\n _setupRole(GUARDIAN_ROLE, guardian);\n _setupRole(GUARDIAN_ROLE, governor);\n _setRoleAdmin(GUARDIAN_ROLE, GOVERNOR_ROLE);\n _setRoleAdmin(GOVERNOR_ROLE, GOVERNOR_ROLE);\n _setRoleAdmin(FLASHLOANER_TREASURY_ROLE, GOVERNOR_ROLE);\n }\n\n /// @custom:oz-upgrades-unsafe-allow constructor\n constructor() initializer {}\n\n // =========================== View Functions ==================================\n\n /// @inheritdoc ICoreBorrow\n function isFlashLoanerTreasury(address treasury) external view returns (bool) {\n return hasRole(FLASHLOANER_TREASURY_ROLE, treasury);\n }\n\n /// @inheritdoc ICoreBorrow\n function isGovernor(address admin) external view returns (bool) {\n return hasRole(GOVERNOR_ROLE, admin);\n }\n\n /// @inheritdoc ICoreBorrow\n function isGovernorOrGuardian(address admin) external view returns (bool) {\n return hasRole(GUARDIAN_ROLE, admin);\n }\n\n // =========================== Governor Functions ==============================\n\n /// @notice Grants the `FLASHLOANER_TREASURY_ROLE` to a `treasury` contract\n /// @param treasury Contract to grant the role to\n /// @dev This function can be used to allow flash loans on a stablecoin of the protocol\n function addFlashLoanerTreasuryRole(address treasury) external {\n grantRole(FLASHLOANER_TREASURY_ROLE, treasury);\n address _flashLoanModule = flashLoanModule;\n if (_flashLoanModule != address(0)) {\n // This call will revert if `treasury` is the zero address or if it is not linked\n // to this `CoreBorrow` contract\n ITreasury(treasury).setFlashLoanModule(_flashLoanModule);\n IFlashAngle(_flashLoanModule).addStablecoinSupport(treasury);\n }\n }\n\n /// @notice Adds a governor in the protocol\n /// @param governor Address to grant the role to\n /// @dev It is necessary to call this function to grant a governor role to make sure\n /// all governors also have the guardian role\n function addGovernor(address governor) external {\n grantRole(GOVERNOR_ROLE, governor);\n grantRole(GUARDIAN_ROLE, governor);\n }\n\n /// @notice Revokes the flash loan ability for a stablecoin\n /// @param treasury Treasury address associated with the stablecoin for which flash loans\n /// should no longer be available\n function removeFlashLoanerTreasuryRole(address treasury) external {\n revokeRole(FLASHLOANER_TREASURY_ROLE, treasury);\n ITreasury(treasury).setFlashLoanModule(address(0));\n address _flashLoanModule = flashLoanModule;\n if (_flashLoanModule != address(0)) {\n IFlashAngle(flashLoanModule).removeStablecoinSupport(treasury);\n }\n }\n\n /// @notice Revokes a governor from the protocol\n /// @param governor Address to remove the role to\n /// @dev It is necessary to call this function to remove a governor role to make sure\n /// the address also loses its guardian role\n function removeGovernor(address governor) external {\n if (getRoleMemberCount(GOVERNOR_ROLE) <= 1) revert NotEnoughGovernorsLeft();\n revokeRole(GUARDIAN_ROLE, governor);\n revokeRole(GOVERNOR_ROLE, governor);\n }\n\n /// @notice Changes the `flashLoanModule` of the protocol\n /// @param _flashLoanModule Address of the new flash loan module\n function setFlashLoanModule(address _flashLoanModule) external onlyRole(GOVERNOR_ROLE) {\n if (_flashLoanModule != address(0)) {\n if (address(IFlashAngle(_flashLoanModule).core()) != address(this)) revert InvalidCore();\n }\n uint256 count = getRoleMemberCount(FLASHLOANER_TREASURY_ROLE);\n for (uint256 i; i < count; ++i) {\n ITreasury(getRoleMember(FLASHLOANER_TREASURY_ROLE, i)).setFlashLoanModule(_flashLoanModule);\n }\n flashLoanModule = _flashLoanModule;\n emit FlashLoanModuleUpdated(_flashLoanModule);\n }\n\n /// @notice Changes the core contract of the protocol\n /// @param _core New core contract\n /// @dev This function verifies that all governors of the current core contract are also governors\n /// of the new core contract. It also notifies the `flashLoanModule` of the change.\n /// @dev Governance wishing to change the core contract should also make sure to call `setCore`\n /// in the different treasury contracts\n function setCore(ICoreBorrow _core) external onlyRole(GOVERNOR_ROLE) {\n uint256 count = getRoleMemberCount(GOVERNOR_ROLE);\n bool success;\n for (uint256 i; i < count; ++i) {\n success = _core.isGovernor(getRoleMember(GOVERNOR_ROLE, i));\n if (!success) break;\n }\n if (!success) revert InvalidCore();\n address _flashLoanModule = flashLoanModule;\n if (_flashLoanModule != address(0)) IFlashAngle(_flashLoanModule).setCore(address(_core));\n emit CoreUpdated(address(_core));\n }\n}\n" + }, + "contracts/deprecated/AgTokenIntermediateUpgrade.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\nimport \"../interfaces/IAgToken.sol\";\nimport \"../interfaces/coreModule/IStableMaster.sol\";\n// OpenZeppelin may update its version of the ERC20PermitUpgradeable token\nimport \"@openzeppelin/contracts-upgradeable/token/ERC20/extensions/draft-ERC20PermitUpgradeable.sol\";\n\n/// @title AgTokenIntermediateUpgrade\n/// @author Angle Labs, Inc.\n/// @notice Base contract for agToken, that is to say Angle's stablecoins\n/// @dev This contract is used to create and handle the stablecoins of Angle protocol\n/// @dev It is still possible for any address to burn its agTokens without redeeming collateral in exchange\n/// @dev This contract is the upgraded version of the AgToken that was first deployed on Ethereum mainnet and is used to\n/// add other minters as needed by AMOs\ncontract AgTokenIntermediateUpgrade is ERC20PermitUpgradeable {\n // ========================= References to other contracts =====================\n\n /// @notice Reference to the `StableMaster` contract associated to this `AgToken`\n address public stableMaster;\n\n // ============================= Constructor ===================================\n\n /// @notice Initializes the `AgToken` contract\n /// @param name_ Name of the token\n /// @param symbol_ Symbol of the token\n /// @param stableMaster_ Reference to the `StableMaster` contract associated to this agToken\n /// @dev By default, agTokens are ERC-20 tokens with 18 decimals\n function initialize(string memory name_, string memory symbol_, address stableMaster_) external initializer {\n __ERC20Permit_init(name_);\n __ERC20_init(name_, symbol_);\n require(stableMaster_ != address(0), \"0\");\n stableMaster = stableMaster_;\n }\n\n /// @custom:oz-upgrades-unsafe-allow constructor\n constructor() initializer {}\n\n // ======= Added Parameters and Variables from the first implementation ========\n\n /// @notice Checks whether an address has the right to mint agTokens\n mapping(address => bool) public isMinter;\n\n // =============================== Added Events ================================\n\n event MinterToggled(address indexed minter);\n\n // =============================== Setup Function ==============================\n\n /// @notice Sets up the minter role and gives it to the governor\n /// @dev This function just has to be called once\n function setUpMinter() external {\n address governor = 0xdC4e6DFe07EFCa50a197DF15D9200883eF4Eb1c8;\n require(msg.sender == governor);\n isMinter[governor] = true;\n emit MinterToggled(governor);\n }\n\n // =============================== Modifiers ===================================\n\n /// @notice Checks whether the sender has the minting right\n modifier onlyMinter() {\n require(isMinter[msg.sender] || msg.sender == stableMaster, \"35\");\n _;\n }\n\n // ========================= External Functions ================================\n // The following functions allow anyone to burn stablecoins without redeeming collateral\n // in exchange for that\n\n /// @notice Destroys `amount` token from the caller without giving collateral back\n /// @param amount Amount to burn\n /// @param poolManager Reference to the `PoolManager` contract for which the `stocksUsers` will\n /// need to be updated\n /// @dev When calling this function, people should specify the `poolManager` for which they want to decrease\n /// the `stocksUsers`: this is a way for the protocol to maintain healthy accounting variables\n function burnNoRedeem(uint256 amount, address poolManager) external {\n _burn(msg.sender, amount);\n IStableMaster(stableMaster).updateStocksUsers(amount, poolManager);\n }\n\n /// @notice Burns `amount` of agToken on behalf of another account without redeeming collateral back\n /// @param account Account to burn on behalf of\n /// @param amount Amount to burn\n /// @param poolManager Reference to the `PoolManager` contract for which the `stocksUsers` will need to be updated\n function burnFromNoRedeem(address account, uint256 amount, address poolManager) external {\n _burnFromNoRedeem(amount, account, msg.sender);\n IStableMaster(stableMaster).updateStocksUsers(amount, poolManager);\n }\n\n // ======================= Minter Role Only Functions ==========================\n\n /// @notice Burns `amount` tokens from a `burner` address\n /// @param amount Amount of tokens to burn\n /// @param burner Address to burn from\n /// @dev This method is to be called by a contract with a minter right on the AgToken after being\n /// requested to do so by an address willing to burn tokens from its address\n function burnSelf(uint256 amount, address burner) external onlyMinter {\n _burn(burner, amount);\n }\n\n /// @notice Burns `amount` tokens from a `burner` address after being asked to by `sender`\n /// @param amount Amount of tokens to burn\n /// @param burner Address to burn from\n /// @param sender Address which requested the burn from `burner`\n /// @dev This method is to be called by a contract with the minter right after being requested\n /// to do so by a `sender` address willing to burn tokens from another `burner` address\n /// @dev The method checks the allowance between the `sender` and the `burner`\n function burnFrom(uint256 amount, address burner, address sender) external onlyMinter {\n _burnFromNoRedeem(amount, burner, sender);\n }\n\n /// @notice Lets the `StableMaster` contract or another whitelisted contract mint agTokens\n /// @param account Address to mint to\n /// @param amount Amount to mint\n /// @dev The contracts allowed to issue agTokens are the `StableMaster` contract, `VaultManager` contracts\n /// associated to this stablecoin as well as the flash loan module (if activated) and potentially contracts\n /// whitelisted by governance\n function mint(address account, uint256 amount) external onlyMinter {\n _mint(account, amount);\n }\n\n // ======================= Minter Only Functions ===============================\n\n /// @notice Adds a minter in the contract\n /// @param minter Minter address to add\n function addMinter(address minter) external onlyMinter {\n isMinter[minter] = true;\n emit MinterToggled(minter);\n }\n\n /// @notice Removes a minter from the contract\n /// @param minter Minter address to remove\n /// @dev This function can at the moment only be called by a minter wishing to revoke itself\n function removeMinter(address minter) external {\n require(msg.sender == minter && isMinter[msg.sender], \"36\");\n isMinter[minter] = false;\n emit MinterToggled(minter);\n }\n\n // ============================ Internal Function ==============================\n\n /// @notice Internal version of the function `burnFromNoRedeem`\n /// @param amount Amount to burn\n /// @dev It is at the level of this function that allowance checks are performed\n function _burnFromNoRedeem(uint256 amount, address burner, address sender) internal {\n if (burner != sender) {\n uint256 currentAllowance = allowance(burner, sender);\n require(currentAllowance >= amount, \"23\");\n _approve(burner, sender, currentAllowance - amount);\n }\n _burn(burner, amount);\n }\n}\n" + }, + "contracts/deprecated/layerZero/OldLayerZeroBridgeToken.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.12;\n\nimport \"./OldOFTCore.sol\";\nimport \"../../interfaces/IAgTokenSideChainMultiBridge.sol\";\nimport \"@openzeppelin/contracts-upgradeable/security/PausableUpgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/token/ERC20/ERC20Upgradeable.sol\";\n\n/// @title LayerZeroBridgeToken\n/// @author Angle Labs, Inc., forked from https://github.com/LayerZero-Labs/solidity-examples/blob/main/contracts/token/oft/OFT.sol\n/// @notice Contract to be deployed on a L2/sidechain for bridging an AgToken using a bridge intermediate token and LayerZero\ncontract OldLayerZeroBridgeToken is OldOFTCore, ERC20Upgradeable, PausableUpgradeable {\n /// @notice Address of the bridgeable token\n /// @dev Immutable\n IAgTokenSideChainMultiBridge public canonicalToken;\n\n // =============================== Errors ================================\n\n error InvalidAllowance();\n\n // ============================= Constructor ===================================\n\n /// @notice Initializes the contract\n /// @param _name Name of the token corresponding to this contract\n /// @param _symbol Symbol of the token corresponding to this contract\n /// @param _lzEndpoint Layer zero endpoint to pass messages\n /// @param _treasury Address of the treasury contract used for access control\n /// @param initialSupply Initial supply to mint to the canonical token address\n /// @dev The initial supply corresponds to the initial amount that could be bridged using this OFT\n function initialize(\n string memory _name,\n string memory _symbol,\n address _lzEndpoint,\n address _treasury,\n uint256 initialSupply\n ) external initializer {\n __ERC20_init_unchained(_name, _symbol);\n __LzAppUpgradeable_init(_lzEndpoint, _treasury);\n\n canonicalToken = IAgTokenSideChainMultiBridge(address(ITreasury(_treasury).stablecoin()));\n _approve(address(this), address(canonicalToken), type(uint256).max);\n _mint(address(canonicalToken), initialSupply);\n }\n\n /// @custom:oz-upgrades-unsafe-allow constructor\n constructor() initializer {}\n\n // ==================== External Permissionless Functions ======================\n\n function sendWithPermit(\n uint16 _dstChainId,\n bytes memory _toAddress,\n uint256 _amount,\n address payable _refundAddress,\n address _zroPaymentAddress,\n bytes memory _adapterParams,\n uint256 deadline,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) public payable override {\n canonicalToken.permit(msg.sender, address(this), _amount, deadline, v, r, s);\n send(_dstChainId, _toAddress, _amount, _refundAddress, _zroPaymentAddress, _adapterParams);\n }\n\n function withdraw(uint256 amount, address recipient) external override returns (uint256 amountMinted) {\n // Does not check allowances as transfers from `msg.sender`\n _transfer(msg.sender, address(this), amount);\n amountMinted = canonicalToken.swapIn(address(this), amount, recipient);\n uint256 leftover = balanceOf(address(this));\n if (leftover != 0) {\n _transfer(address(this), msg.sender, leftover);\n }\n }\n\n // ============================= Internal Functions ===================================\n\n function _debitFrom(\n uint16,\n bytes memory,\n uint256 _amount\n ) internal override whenNotPaused returns (uint256 amountSwapped) {\n // No need to use safeTransferFrom as we know this implementation reverts on failure\n canonicalToken.transferFrom(msg.sender, address(this), _amount);\n\n // Swap canonical for this bridge token. There may be some fees\n amountSwapped = canonicalToken.swapOut(address(this), _amount, address(this));\n _burn(address(this), amountSwapped);\n }\n\n function _debitCreditFrom(uint16, bytes memory, uint256 _amount) internal override whenNotPaused returns (uint256) {\n _burn(msg.sender, _amount);\n return _amount;\n }\n\n function _creditTo(\n uint16,\n address _toAddress,\n uint256 _amount\n ) internal override whenNotPaused returns (uint256 amountMinted) {\n _mint(address(this), _amount);\n amountMinted = canonicalToken.swapIn(address(this), _amount, _toAddress);\n uint256 leftover = balanceOf(address(this));\n if (leftover != 0) {\n _transfer(address(this), _toAddress, leftover);\n }\n }\n\n // ======================= View Functions ================================\n\n /// @inheritdoc ERC165Upgradeable\n function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {\n return\n interfaceId == type(IOFT).interfaceId ||\n interfaceId == type(IERC20).interfaceId ||\n super.supportsInterface(interfaceId);\n }\n\n // ======================= Governance Functions ================================\n\n /// @notice Mints the intermediate contract to the `canonicalToken`\n /// @dev Used to increase the bridging capacity\n function mint(uint256 amount) external onlyGovernorOrGuardian {\n _mint(address(canonicalToken), amount);\n }\n\n /// @notice Burns the intermediate contract from the `canonicalToken`\n /// @dev Used to decrease the bridging capacity\n function burn(uint256 amount) external onlyGovernorOrGuardian {\n _burn(address(canonicalToken), amount);\n }\n\n /// @notice Increases allowance of the `canonicalToken`\n function setupAllowance() public onlyGovernorOrGuardian {\n _approve(address(this), address(canonicalToken), type(uint256).max);\n }\n\n /// @notice Pauses bridging through the contract\n /// @param pause Future pause status\n function pauseSendTokens(bool pause) external onlyGovernorOrGuardian {\n pause ? _pause() : _unpause();\n }\n\n uint256[49] private __gap;\n}\n" + }, + "contracts/deprecated/layerZero/OldNonblockingLzApp.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.12;\n\nimport \"@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol\";\nimport \"../../interfaces/external/layerZero/ILayerZeroReceiver.sol\";\nimport \"../../interfaces/external/layerZero/ILayerZeroUserApplicationConfig.sol\";\nimport \"../../interfaces/external/layerZero/ILayerZeroEndpoint.sol\";\nimport \"../../interfaces/ITreasury.sol\";\n\n/// @title OldNonblockingLzApp\n/// @author Angle Labs, Inc., forked from https://github.com/LayerZero-Labs/solidity-examples/\n/// @notice Base contract for bridging using LayerZero\nabstract contract OldNonblockingLzApp is Initializable, ILayerZeroReceiver, ILayerZeroUserApplicationConfig {\n /// @notice Layer Zero endpoint\n ILayerZeroEndpoint public lzEndpoint;\n\n /// @notice Maps chainIds to failed messages to retry them\n mapping(uint16 => mapping(bytes => mapping(uint64 => bytes32))) public failedMessages;\n\n /// @notice Maps chainIds to their OFT address\n mapping(uint16 => bytes) public trustedRemoteLookup;\n\n /// @notice Reference to the treasury contract to fetch access control\n address public treasury;\n\n // ================================== Events ===================================\n\n event SetTrustedRemote(uint16 _srcChainId, bytes _srcAddress);\n event MessageFailed(uint16 _srcChainId, bytes _srcAddress, uint64 _nonce, bytes _payload);\n\n // =============================== Errors ================================\n\n error NotGovernor();\n error NotGovernorOrGuardian();\n error InsufficientGas();\n error InvalidEndpoint();\n error InvalidSource();\n error InvalidCaller();\n error InvalidParams();\n error InvalidPayload();\n error ZeroAddress();\n\n // ============================= Constructor ===================================\n\n //solhint-disable-next-line\n function __LzAppUpgradeable_init(address _endpoint, address _treasury) internal {\n if (_endpoint == address(0) || _treasury == address(0)) revert ZeroAddress();\n lzEndpoint = ILayerZeroEndpoint(_endpoint);\n treasury = _treasury;\n }\n\n // =============================== Modifiers ===================================\n\n /// @notice Checks whether the `msg.sender` has the governor role or the guardian role\n modifier onlyGovernorOrGuardian() {\n if (!ITreasury(treasury).isGovernorOrGuardian(msg.sender)) revert NotGovernorOrGuardian();\n _;\n }\n\n // ==================== External Permissionless Functions ======================\n\n /// @notice Receives a message from the LZ endpoint and process it\n /// @param _srcChainId ChainId of the source chain - LayerZero standard\n /// @param _srcAddress Sender of the source chain\n /// @param _nonce Nounce of the message\n /// @param _payload Data: recipient address and amount\n function lzReceive(\n uint16 _srcChainId,\n bytes memory _srcAddress,\n uint64 _nonce,\n bytes memory _payload\n ) public virtual override {\n // lzReceive must be called by the endpoint for security\n if (msg.sender != address(lzEndpoint)) revert InvalidEndpoint();\n\n bytes memory trustedRemote = trustedRemoteLookup[_srcChainId];\n // if will still block the message pathway from (srcChainId, srcAddress). should not receive message from untrusted remote.\n if (_srcAddress.length != trustedRemote.length || keccak256(_srcAddress) != keccak256(trustedRemote))\n revert InvalidSource();\n\n _blockingLzReceive(_srcChainId, _srcAddress, _nonce, _payload);\n }\n\n /// @notice Retries a message that previously failed and was stored\n /// @param _srcChainId ChainId of the source chain - LayerZero standard\n /// @param _srcAddress Sender of the source chain\n /// @param _nonce Nounce of the message\n /// @param _payload Data: recipient address and amount\n function retryMessage(\n uint16 _srcChainId,\n bytes memory _srcAddress,\n uint64 _nonce,\n bytes memory _payload\n ) public payable virtual {\n // assert there is message to retry\n bytes32 payloadHash = failedMessages[_srcChainId][_srcAddress][_nonce];\n if (payloadHash == bytes32(0) || keccak256(_payload) != payloadHash) revert InvalidPayload();\n // clear the stored message\n failedMessages[_srcChainId][_srcAddress][_nonce] = bytes32(0);\n // execute the message. revert if it fails again\n _nonblockingLzReceive(_srcChainId, _srcAddress, _nonce, _payload);\n }\n\n // ============================= Internal Functions ===================================\n\n /// @notice Handles message receptions in a non blocking way\n /// @param _srcChainId ChainId of the source chain - LayerZero standard\n /// @param _srcAddress Sender of the source chain\n /// @param _nonce Nounce of the message\n /// @param _payload Data: recipient address and amount\n /// @dev public for the needs of try / catch but effectively internal\n function nonblockingLzReceive(\n uint16 _srcChainId,\n bytes memory _srcAddress,\n uint64 _nonce,\n bytes memory _payload\n ) public virtual {\n // only internal transaction\n if (msg.sender != address(this)) revert InvalidCaller();\n _nonblockingLzReceive(_srcChainId, _srcAddress, _nonce, _payload);\n }\n\n /// @notice Handles message receptions in a non blocking way\n /// @param _srcChainId ChainId of the source chain - LayerZero standard\n /// @param _srcAddress Sender of the source chain\n /// @param _nonce Nounce of the message\n /// @param _payload Data: recipient address and amount\n function _nonblockingLzReceive(\n uint16 _srcChainId,\n bytes memory _srcAddress,\n uint64 _nonce,\n bytes memory _payload\n ) internal virtual;\n\n /// @notice Handles message receptions in a blocking way\n /// @param _srcChainId ChainId of the source chain - LayerZero standard\n /// @param _srcAddress Sender of the source chain\n /// @param _nonce Nounce of the message\n /// @param _payload Data: recipient address and amount\n function _blockingLzReceive(\n uint16 _srcChainId,\n bytes memory _srcAddress,\n uint64 _nonce,\n bytes memory _payload\n ) internal {\n // try-catch all errors/exceptions\n try this.nonblockingLzReceive(_srcChainId, _srcAddress, _nonce, _payload) {\n // do nothing\n } catch {\n // error / exception\n failedMessages[_srcChainId][_srcAddress][_nonce] = keccak256(_payload);\n emit MessageFailed(_srcChainId, _srcAddress, _nonce, _payload);\n }\n }\n\n /// @notice Sends a message to the LZ endpoint and process it\n /// @param _dstChainId L0 defined chain id to send tokens too\n /// @param _payload Data: recipient address and amount\n /// @param _refundAddress Address LayerZero refunds if too much message fee is sent\n /// @param _zroPaymentAddress Set to address(0x0) if not paying in ZRO (LayerZero Token)\n /// @param _adapterParams Flexible bytes array to indicate messaging adapter services in L0\n function _lzSend(\n uint16 _dstChainId,\n bytes memory _payload,\n address payable _refundAddress,\n address _zroPaymentAddress,\n bytes memory _adapterParams\n ) internal virtual {\n bytes memory trustedRemote = trustedRemoteLookup[_dstChainId];\n if (trustedRemote.length == 0) revert InvalidSource();\n //solhint-disable-next-line\n lzEndpoint.send{ value: msg.value }(\n _dstChainId,\n trustedRemote,\n _payload,\n _refundAddress,\n _zroPaymentAddress,\n _adapterParams\n );\n }\n\n // ======================= Governance Functions ================================\n\n /// @notice Sets the corresponding address on an other chain.\n /// @param _srcChainId ChainId of the source chain - LayerZero standard\n /// @param _srcAddress Address on the source chain\n /// @dev Used for both receiving and sending message\n /// @dev There can only be one trusted source per chain\n /// @dev Allows owner to set it multiple times.\n function setTrustedRemote(uint16 _srcChainId, bytes calldata _srcAddress) external onlyGovernorOrGuardian {\n trustedRemoteLookup[_srcChainId] = _srcAddress;\n emit SetTrustedRemote(_srcChainId, _srcAddress);\n }\n\n /// @notice Fetches the default LZ config\n function getConfig(\n uint16 _version,\n uint16 _chainId,\n address,\n uint256 _configType\n ) external view returns (bytes memory) {\n return lzEndpoint.getConfig(_version, _chainId, address(this), _configType);\n }\n\n /// @notice Overrides the default LZ config\n function setConfig(\n uint16 _version,\n uint16 _chainId,\n uint256 _configType,\n bytes calldata _config\n ) external override onlyGovernorOrGuardian {\n lzEndpoint.setConfig(_version, _chainId, _configType, _config);\n }\n\n /// @notice Overrides the default LZ config\n function setSendVersion(uint16 _version) external override onlyGovernorOrGuardian {\n lzEndpoint.setSendVersion(_version);\n }\n\n /// @notice Overrides the default LZ config\n function setReceiveVersion(uint16 _version) external override onlyGovernorOrGuardian {\n lzEndpoint.setReceiveVersion(_version);\n }\n\n /// @notice Unpauses the receive functionalities\n function forceResumeReceive(\n uint16 _srcChainId,\n bytes calldata _srcAddress\n ) external override onlyGovernorOrGuardian {\n lzEndpoint.forceResumeReceive(_srcChainId, _srcAddress);\n }\n\n // ======================= View Functions ================================\n\n /// @notice Checks if the `_srcAddress` corresponds to the trusted source\n function isTrustedRemote(uint16 _srcChainId, bytes calldata _srcAddress) external view returns (bool) {\n bytes memory trustedSource = trustedRemoteLookup[_srcChainId];\n return keccak256(trustedSource) == keccak256(_srcAddress);\n }\n\n uint256[46] private __gap;\n}\n" + }, + "contracts/deprecated/layerZero/OldOFTCore.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.12;\n\nimport \"./OldNonblockingLzApp.sol\";\nimport \"../../agToken/layerZero/utils/IOFTCore.sol\";\nimport \"@openzeppelin/contracts-upgradeable/utils/introspection/ERC165Upgradeable.sol\";\n\n/// @title OFTCore\n/// @author Forked from https://github.com/LayerZero-Labs/solidity-examples/blob/main/contracts/token/oft/OFTCore.sol\n/// but with slight modifications from the Angle Labs, Inc. which added return values to the `_creditTo` and `_debitFrom` functions\n/// @notice Base contract for bridging using LayerZero\nabstract contract OldOFTCore is OldNonblockingLzApp, ERC165Upgradeable, IOFTCore {\n // ==================== External Permissionless Functions ======================\n\n /// @inheritdoc IOFTCore\n function sendWithPermit(\n uint16 _dstChainId,\n bytes memory _toAddress,\n uint256 _amount,\n address payable _refundAddress,\n address _zroPaymentAddress,\n bytes memory _adapterParams,\n uint256 deadline,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) public payable virtual;\n\n /// @inheritdoc IOFTCore\n function send(\n uint16 _dstChainId,\n bytes memory _toAddress,\n uint256 _amount,\n address payable _refundAddress,\n address _zroPaymentAddress,\n bytes memory _adapterParams\n ) public payable virtual {\n _amount = _debitFrom(_dstChainId, _toAddress, _amount);\n\n bytes memory payload = abi.encode(_toAddress, _amount);\n _lzSend(_dstChainId, payload, _refundAddress, _zroPaymentAddress, _adapterParams);\n\n uint64 nonce = lzEndpoint.getOutboundNonce(_dstChainId, address(this));\n emit SendToChain(msg.sender, _dstChainId, _toAddress, _amount, nonce);\n }\n\n /// @inheritdoc IOFTCore\n function sendCredit(\n uint16 _dstChainId,\n bytes memory _toAddress,\n uint256 _amount,\n address payable _refundAddress,\n address _zroPaymentAddress,\n bytes memory _adapterParams\n ) public payable virtual {\n _amount = _debitCreditFrom(_dstChainId, _toAddress, _amount);\n\n _send(_dstChainId, _toAddress, _amount, _refundAddress, _zroPaymentAddress, _adapterParams);\n }\n\n /// @inheritdoc IOFTCore\n function withdraw(uint256 amount, address recipient) external virtual returns (uint256);\n\n // =========================== Internal Functions ==============================\n\n /// @notice Internal function to send `_amount` amount of token to (`_dstChainId`, `_toAddress`)\n /// @param _dstChainId the destination chain identifier\n /// @param _toAddress can be any size depending on the `dstChainId`.\n /// @param _amount the quantity of tokens in wei\n /// @param _refundAddress the address LayerZero refunds if too much message fee is sent\n /// @param _zroPaymentAddress set to address(0x0) if not paying in ZRO (LayerZero Token)\n /// @param _adapterParams is a flexible bytes array to indicate messaging adapter services\n /// @dev Accounting and checks should be performed beforehand\n function _send(\n uint16 _dstChainId,\n bytes memory _toAddress,\n uint256 _amount,\n address payable _refundAddress,\n address _zroPaymentAddress,\n bytes memory _adapterParams\n ) internal {\n bytes memory payload = abi.encode(_toAddress, _amount);\n _lzSend(_dstChainId, payload, _refundAddress, _zroPaymentAddress, _adapterParams);\n\n uint64 nonce = lzEndpoint.getOutboundNonce(_dstChainId, address(this));\n emit SendToChain(msg.sender, _dstChainId, _toAddress, _amount, nonce);\n }\n\n function _nonblockingLzReceive(\n uint16 _srcChainId,\n bytes memory _srcAddress,\n uint64 _nonce,\n bytes memory _payload\n ) internal virtual override {\n // decode and load the toAddress\n (bytes memory toAddressBytes, uint256 amount) = abi.decode(_payload, (bytes, uint256));\n address toAddress;\n //solhint-disable-next-line\n assembly {\n toAddress := mload(add(toAddressBytes, 20))\n }\n amount = _creditTo(_srcChainId, toAddress, amount);\n\n emit ReceiveFromChain(_srcChainId, _srcAddress, toAddress, amount, _nonce);\n }\n\n /// @notice Makes accountability when bridging from this contract using canonical token\n /// @param _dstChainId ChainId of the destination chain - LayerZero standard\n /// @param _toAddress Recipient on the destination chain\n /// @param _amount Amount to bridge\n function _debitFrom(\n uint16 _dstChainId,\n bytes memory _toAddress,\n uint256 _amount\n ) internal virtual returns (uint256);\n\n /// @notice Makes accountability when bridging from this contract's credit\n /// @param _dstChainId ChainId of the destination chain - LayerZero standard\n /// @param _toAddress Recipient on the destination chain\n /// @param _amount Amount to bridge\n function _debitCreditFrom(\n uint16 _dstChainId,\n bytes memory _toAddress,\n uint256 _amount\n ) internal virtual returns (uint256);\n\n /// @notice Makes accountability when bridging to this contract\n /// @param _srcChainId ChainId of the source chain - LayerZero standard\n /// @param _toAddress Recipient on this chain\n /// @param _amount Amount to bridge\n function _creditTo(uint16 _srcChainId, address _toAddress, uint256 _amount) internal virtual returns (uint256);\n\n // ========================== View Functions ===================================\n\n /// @inheritdoc ERC165Upgradeable\n function supportsInterface(\n bytes4 interfaceId\n ) public view virtual override(ERC165Upgradeable, IERC165) returns (bool) {\n return interfaceId == type(IOFTCore).interfaceId || super.supportsInterface(interfaceId);\n }\n\n /// @inheritdoc IOFTCore\n function estimateSendFee(\n uint16 _dstChainId,\n bytes memory _toAddress,\n uint256 _amount,\n bool _useZro,\n bytes memory _adapterParams\n ) public view virtual override returns (uint256 nativeFee, uint256 zroFee) {\n // mock the payload for send()\n bytes memory payload = abi.encode(_toAddress, _amount);\n return lzEndpoint.estimateFees(_dstChainId, address(this), payload, _useZro, _adapterParams);\n }\n\n uint256[50] private __gap;\n}\n" + }, + "contracts/deprecated/OldAgEUR.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\nimport \"../interfaces/IAgToken.sol\";\nimport \"../interfaces/coreModule/IStableMaster.sol\";\nimport \"../interfaces/ITreasury.sol\";\n// OpenZeppelin may update its version of the ERC20PermitUpgradeable token\nimport \"@openzeppelin/contracts-upgradeable/token/ERC20/extensions/draft-ERC20PermitUpgradeable.sol\";\n\n/// @title AgToken\n/// @author Angle Labs, Inc.\n/// @notice Base contract for agToken, that is to say Angle's stablecoins\n/// @dev This contract is used to create and handle the stablecoins of Angle protocol\n/// @dev It is still possible for any address to burn its agTokens without redeeming collateral in exchange\n/// @dev This contract is the upgraded version of the AgToken that was first deployed on Ethereum mainnet\ncontract OldAgEUR is IAgToken, ERC20PermitUpgradeable {\n // ========================= References to other contracts =====================\n\n /// @notice Reference to the `StableMaster` contract associated to this `AgToken`\n address public stableMaster;\n\n // ============================= Constructor ===================================\n\n /// @notice Initializes the `AgToken` contract\n /// @param name_ Name of the token\n /// @param symbol_ Symbol of the token\n /// @param stableMaster_ Reference to the `StableMaster` contract associated to this agToken\n /// @dev By default, agTokens are ERC-20 tokens with 18 decimals\n function initialize(string memory name_, string memory symbol_, address stableMaster_) external initializer {\n __ERC20Permit_init(name_);\n __ERC20_init(name_, symbol_);\n require(stableMaster_ != address(0), \"0\");\n stableMaster = stableMaster_;\n }\n\n /// @custom:oz-upgrades-unsafe-allow constructor\n constructor() initializer {}\n\n // ======= Added Parameters and Variables from the first implementation ========\n\n /// @inheritdoc IAgToken\n mapping(address => bool) public isMinter;\n /// @notice Reference to the treasury contract which can grant minting rights\n address public treasury;\n /// @notice Boolean to check whether the contract has been reinitialized after its upgrade\n bool public treasuryInitialized;\n\n // =============================== Added Events ================================\n\n event TreasuryUpdated(address indexed _treasury);\n event MinterToggled(address indexed minter);\n\n // =============================== Added Errors ================================\n\n error BurnAmountExceedsAllowance();\n error InvalidSender();\n error InvalidTreasury();\n error NotGovernor();\n error NotMinter();\n error NotTreasury();\n error TreasuryAlreadyInitialized();\n\n // =============================== Setup Function ==============================\n\n /// @notice Sets up the treasury contract in this AgToken contract\n /// @param _treasury Treasury contract to add\n /// @dev The address calling this function has to be hard-coded in the contract\n /// @dev Can be called only once\n function setUpTreasury(address _treasury) external {\n // Only governor\n if (msg.sender != 0xdC4e6DFe07EFCa50a197DF15D9200883eF4Eb1c8) revert NotGovernor();\n if (address(ITreasury(_treasury).stablecoin()) != address(this)) revert InvalidTreasury();\n if (treasuryInitialized) revert TreasuryAlreadyInitialized();\n treasury = _treasury;\n treasuryInitialized = true;\n isMinter[stableMaster] = true;\n emit TreasuryUpdated(_treasury);\n }\n\n // =============================== Modifiers ===================================\n\n /// @notice Checks to see if it is the `Treasury` calling this contract\n /// @dev There is no Access Control here, because it can be handled cheaply through this modifier\n modifier onlyTreasury() {\n if (msg.sender != treasury) revert NotTreasury();\n _;\n }\n\n /// @notice Checks whether the sender has the minting right\n modifier onlyMinter() {\n if (!isMinter[msg.sender]) revert NotMinter();\n _;\n }\n\n // ========================= External Functions ================================\n // The following functions allow anyone to burn stablecoins without redeeming collateral\n // in exchange for that\n\n /// @notice Destroys `amount` token from the caller without giving collateral back\n /// @param amount Amount to burn\n /// @param poolManager Reference to the `PoolManager` contract for which the `stocksUsers` will\n /// need to be updated\n /// @dev When calling this function, people should specify the `poolManager` for which they want to decrease\n /// the `stocksUsers`: this is a way for the protocol to maintain healthy accounting variables\n function burnNoRedeem(uint256 amount, address poolManager) external {\n _burn(msg.sender, amount);\n IStableMaster(stableMaster).updateStocksUsers(amount, poolManager);\n }\n\n /// @notice Burns `amount` of agToken on behalf of another account without redeeming collateral back\n /// @param account Account to burn on behalf of\n /// @param amount Amount to burn\n /// @param poolManager Reference to the `PoolManager` contract for which the `stocksUsers` will need to be updated\n function burnFromNoRedeem(address account, uint256 amount, address poolManager) external {\n _burnFromNoRedeem(amount, account, msg.sender);\n IStableMaster(stableMaster).updateStocksUsers(amount, poolManager);\n }\n\n /// @notice Allows anyone to burn agToken without redeeming collateral back\n /// @param amount Amount of stablecoins to burn\n /// @dev This function can typically be called if there is a settlement mechanism to burn stablecoins\n function burnStablecoin(uint256 amount) external {\n _burn(msg.sender, amount);\n }\n\n // ======================= Minter Role Only Functions ==========================\n\n /// @inheritdoc IAgToken\n function burnSelf(uint256 amount, address burner) external onlyMinter {\n _burn(burner, amount);\n }\n\n /// @inheritdoc IAgToken\n function burnFrom(uint256 amount, address burner, address sender) external onlyMinter {\n _burnFromNoRedeem(amount, burner, sender);\n }\n\n /// @inheritdoc IAgToken\n function mint(address account, uint256 amount) external onlyMinter {\n _mint(account, amount);\n }\n\n // ======================= Treasury Only Functions =============================\n\n /// @inheritdoc IAgToken\n function addMinter(address minter) external onlyTreasury {\n isMinter[minter] = true;\n emit MinterToggled(minter);\n }\n\n /// @inheritdoc IAgToken\n function removeMinter(address minter) external {\n // The `treasury` contract cannot remove the `stableMaster`\n if (msg.sender != minter && (msg.sender != address(treasury) || minter == stableMaster)) revert InvalidSender();\n isMinter[minter] = false;\n emit MinterToggled(minter);\n }\n\n /// @inheritdoc IAgToken\n function setTreasury(address _treasury) external onlyTreasury {\n treasury = _treasury;\n emit TreasuryUpdated(_treasury);\n }\n\n // ============================ Internal Function ==============================\n\n /// @notice Internal version of the function `burnFromNoRedeem`\n /// @param amount Amount to burn\n /// @dev It is at the level of this function that allowance checks are performed\n function _burnFromNoRedeem(uint256 amount, address burner, address sender) internal {\n if (burner != sender) {\n uint256 currentAllowance = allowance(burner, sender);\n if (currentAllowance < amount) revert BurnAmountExceedsAllowance();\n _approve(burner, sender, currentAllowance - amount);\n }\n _burn(burner, amount);\n }\n}\n" + }, + "contracts/deprecated/OldAngleHelpers.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\nimport \"../interfaces/IAngleRouter.sol\";\nimport \"../interfaces/coreModule/IAgTokenMainnet.sol\";\nimport \"../interfaces/coreModule/ICore.sol\";\nimport \"../interfaces/coreModule/IOracleCore.sol\";\nimport \"../interfaces/coreModule/IPerpetualManager.sol\";\nimport \"../interfaces/coreModule/IPoolManager.sol\";\nimport \"../interfaces/coreModule/IStableMaster.sol\";\nimport \"@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol\";\nimport \"../interfaces/IVaultManager.sol\";\n\npragma solidity ^0.8.12;\n\nstruct Parameters {\n SLPData slpData;\n MintBurnData feeData;\n PerpetualManagerFeeData perpFeeData;\n PerpetualManagerParamData perpParam;\n}\n\nstruct PerpetualManagerFeeData {\n uint64[] xHAFeesDeposit;\n uint64[] yHAFeesDeposit;\n uint64[] xHAFeesWithdraw;\n uint64[] yHAFeesWithdraw;\n uint64 haBonusMalusDeposit;\n uint64 haBonusMalusWithdraw;\n}\n\nstruct PerpetualManagerParamData {\n uint64 maintenanceMargin;\n uint64 maxLeverage;\n uint64 targetHAHedge;\n uint64 limitHAHedge;\n uint64 lockTime;\n}\n\nstruct CollateralAddresses {\n address stableMaster;\n address poolManager;\n address perpetualManager;\n address sanToken;\n address oracle;\n address gauge;\n address feeManager;\n address[] strategies;\n}\n\n/// @title AngleHelpers\n/// @author Angle Labs, Inc.\n/// @notice Contract with view functions designed to facilitate integrations on the Core module of the Angle Protocol\n/// @dev This contract only contains view functions to be queried off-chain. It was thus not optimized for gas consumption\ncontract OldAngleHelpers is Initializable {\n // ======================== Helper View Functions ==============================\n\n /// @notice Gives the amount of `agToken` you'd be getting if you were executing in the same block a mint transaction\n /// with `amount` of `collateral` in the Core module of the Angle protocol as well as the value of the fees\n /// (in `BASE_PARAMS`) that would be applied during the mint\n /// @return Amount of `agToken` that would be obtained with a mint transaction in the same block\n /// @return Percentage of fees that would be taken during a mint transaction in the same block\n /// @dev This function reverts if the mint transaction was to revert in the same conditions (without taking into account\n /// potential approval problems to the `StableMaster` contract)\n function previewMintAndFees(\n uint256 amount,\n address agToken,\n address collateral\n ) external view returns (uint256, uint256) {\n return _previewMintAndFees(amount, agToken, collateral);\n }\n\n /// @notice Gives the amount of `collateral` you'd be getting if you were executing in the same block a burn transaction\n /// with `amount` of `agToken` in the Core module of the Angle protocol as well as the value of the fees\n /// (in `BASE_PARAMS`) that would be applied during the burn\n /// @return Amount of `collateral` that would be obtained with a burn transaction in the same block\n /// @return Percentage of fees that would be taken during a burn transaction in the same block\n /// @dev This function reverts if the burn transaction was to revert in the same conditions (without taking into account\n /// potential approval problems to the `StableMaster` contract or agToken balance prior to the call)\n function previewBurnAndFees(\n uint256 amount,\n address agToken,\n address collateral\n ) external view returns (uint256, uint256) {\n return _previewBurnAndFees(amount, agToken, collateral);\n }\n\n /// @notice Returns all the addresses associated to the (`agToken`,`collateral`) pair given\n /// @return addresses A struct with all the addresses associated in the Core module\n function getCollateralAddresses(\n address agToken,\n address collateral\n ) external view returns (CollateralAddresses memory addresses) {\n address stableMaster = IAgTokenMainnet(agToken).stableMaster();\n (address poolManager, address perpetualManager, address sanToken, address gauge) = ROUTER.mapPoolManagers(\n stableMaster,\n collateral\n );\n (, , , IOracleCore oracle, , , , , ) = IStableMaster(stableMaster).collateralMap(poolManager);\n addresses.stableMaster = stableMaster;\n addresses.poolManager = poolManager;\n addresses.perpetualManager = perpetualManager;\n addresses.sanToken = sanToken;\n addresses.gauge = gauge;\n addresses.oracle = address(oracle);\n addresses.feeManager = IPoolManager(poolManager).feeManager();\n\n uint256 length = 0;\n while (true) {\n try IPoolManager(poolManager).strategyList(length) returns (address) {\n length += 1;\n } catch {\n break;\n }\n }\n address[] memory strategies = new address[](length);\n for (uint256 i; i < length; ++i) {\n strategies[i] = IPoolManager(poolManager).strategyList(i);\n }\n addresses.strategies = strategies;\n }\n\n /// @notice Gets the addresses of all the `StableMaster` contracts and their associated `AgToken` addresses\n /// @return List of the `StableMaster` addresses of the Angle protocol\n /// @return List of the `AgToken` addresses of the protocol\n /// @dev The place of an agToken address in the list is the same as the corresponding `StableMaster` address\n function getStablecoinAddresses() external view returns (address[] memory, address[] memory) {\n address[] memory stableMasterAddresses = CORE.stablecoinList();\n address[] memory agTokenAddresses = new address[](stableMasterAddresses.length);\n for (uint256 i; i < stableMasterAddresses.length; ++i) {\n agTokenAddresses[i] = IStableMaster(stableMasterAddresses[i]).agToken();\n }\n return (stableMasterAddresses, agTokenAddresses);\n }\n\n /// @notice Returns most of the governance parameters associated to the (`agToken`,`collateral`) pair given\n /// @return params Struct with most of the parameters in the `StableMaster` and `PerpetualManager` contracts\n /// @dev Check out the struct `Parameters` for the meaning of the return values\n function getCollateralParameters(\n address agToken,\n address collateral\n ) external view returns (Parameters memory params) {\n (address stableMaster, address poolManager) = _getStableMasterAndPoolManager(agToken, collateral);\n (\n ,\n ,\n IPerpetualManager perpetualManager,\n ,\n ,\n ,\n ,\n SLPData memory slpData,\n MintBurnData memory feeData\n ) = IStableMaster(stableMaster).collateralMap(poolManager);\n\n params.slpData = slpData;\n params.feeData = feeData;\n params.perpParam.maintenanceMargin = perpetualManager.maintenanceMargin();\n params.perpParam.maxLeverage = perpetualManager.maxLeverage();\n params.perpParam.targetHAHedge = perpetualManager.targetHAHedge();\n params.perpParam.limitHAHedge = perpetualManager.limitHAHedge();\n params.perpParam.lockTime = perpetualManager.lockTime();\n\n params.perpFeeData.haBonusMalusDeposit = perpetualManager.haBonusMalusDeposit();\n params.perpFeeData.haBonusMalusWithdraw = perpetualManager.haBonusMalusWithdraw();\n\n uint256 length = 0;\n while (true) {\n try perpetualManager.xHAFeesDeposit(length) returns (uint64) {\n length += 1;\n } catch {\n break;\n }\n }\n uint64[] memory data = new uint64[](length);\n uint64[] memory data2 = new uint64[](length);\n for (uint256 i; i < length; ++i) {\n data[i] = perpetualManager.xHAFeesDeposit(i);\n data2[i] = perpetualManager.yHAFeesDeposit(i);\n }\n params.perpFeeData.xHAFeesDeposit = data;\n params.perpFeeData.yHAFeesDeposit = data2;\n\n length = 0;\n while (true) {\n try perpetualManager.xHAFeesWithdraw(length) returns (uint64) {\n length += 1;\n } catch {\n break;\n }\n }\n data = new uint64[](length);\n data2 = new uint64[](length);\n for (uint256 i; i < length; ++i) {\n data[i] = perpetualManager.xHAFeesWithdraw(i);\n data2[i] = perpetualManager.yHAFeesWithdraw(i);\n }\n params.perpFeeData.xHAFeesWithdraw = data;\n params.perpFeeData.yHAFeesWithdraw = data2;\n }\n\n /// @notice Returns the address of the poolManager associated to an (`agToken`, `collateral`) pair\n /// in the Core module of the protocol\n function getPoolManager(address agToken, address collateral) public view returns (address poolManager) {\n (, poolManager) = _getStableMasterAndPoolManager(agToken, collateral);\n }\n\n // ======================== Replica Functions ==================================\n // These replicate what is done in the other contracts of the protocol\n\n function _previewBurnAndFees(\n uint256 amount,\n address agToken,\n address collateral\n ) internal view returns (uint256 amountForUserInCollat, uint256 feePercent) {\n (address stableMaster, address poolManager) = _getStableMasterAndPoolManager(agToken, collateral);\n (\n address token,\n ,\n IPerpetualManager perpetualManager,\n IOracleCore oracle,\n uint256 stocksUsers,\n ,\n uint256 collatBase,\n ,\n MintBurnData memory feeData\n ) = IStableMaster(stableMaster).collateralMap(poolManager);\n if (token == address(0) || IStableMaster(stableMaster).paused(keccak256(abi.encodePacked(STABLE, poolManager))))\n revert NotInitialized();\n if (amount > stocksUsers) revert InvalidAmount();\n\n if (feeData.xFeeBurn.length == 1) {\n feePercent = feeData.yFeeBurn[0];\n } else {\n bytes memory data = abi.encode(address(perpetualManager), feeData.targetHAHedge);\n uint64 hedgeRatio = _computeHedgeRatio(stocksUsers - amount, data);\n feePercent = _piecewiseLinear(hedgeRatio, feeData.xFeeBurn, feeData.yFeeBurn);\n }\n feePercent = (feePercent * feeData.bonusMalusBurn) / BASE_PARAMS;\n\n amountForUserInCollat = (amount * (BASE_PARAMS - feePercent) * collatBase) / (oracle.readUpper() * BASE_PARAMS);\n }\n\n function _previewMintAndFees(\n uint256 amount,\n address agToken,\n address collateral\n ) internal view returns (uint256 amountForUserInStable, uint256 feePercent) {\n (address stableMaster, address poolManager) = _getStableMasterAndPoolManager(agToken, collateral);\n (\n address token,\n ,\n IPerpetualManager perpetualManager,\n IOracleCore oracle,\n uint256 stocksUsers,\n ,\n ,\n ,\n MintBurnData memory feeData\n ) = IStableMaster(stableMaster).collateralMap(poolManager);\n if (token == address(0) || IStableMaster(stableMaster).paused(keccak256(abi.encodePacked(STABLE, poolManager))))\n revert NotInitialized();\n\n amountForUserInStable = oracle.readQuoteLower(amount);\n\n if (feeData.xFeeMint.length == 1) feePercent = feeData.yFeeMint[0];\n else {\n bytes memory data = abi.encode(address(perpetualManager), feeData.targetHAHedge);\n uint64 hedgeRatio = _computeHedgeRatio(amountForUserInStable + stocksUsers, data);\n feePercent = _piecewiseLinear(hedgeRatio, feeData.xFeeMint, feeData.yFeeMint);\n }\n feePercent = (feePercent * feeData.bonusMalusMint) / BASE_PARAMS;\n\n amountForUserInStable = (amountForUserInStable * (BASE_PARAMS - feePercent)) / BASE_PARAMS;\n if (stocksUsers + amountForUserInStable > feeData.capOnStableMinted) revert InvalidAmount();\n }\n\n // ======================== Utility Functions ==================================\n // These utility functions are taken from other contracts of the protocol\n\n function _computeHedgeRatio(uint256 newStocksUsers, bytes memory data) internal view returns (uint64 ratio) {\n (address perpetualManager, uint64 targetHAHedge) = abi.decode(data, (address, uint64));\n uint256 totalHedgeAmount = IPerpetualManager(perpetualManager).totalHedgeAmount();\n newStocksUsers = (targetHAHedge * newStocksUsers) / BASE_PARAMS;\n if (newStocksUsers > totalHedgeAmount) ratio = uint64((totalHedgeAmount * BASE_PARAMS) / newStocksUsers);\n else ratio = uint64(BASE_PARAMS);\n }\n\n function _piecewiseLinear(uint64 x, uint64[] memory xArray, uint64[] memory yArray) internal pure returns (uint64) {\n if (x >= xArray[xArray.length - 1]) {\n return yArray[xArray.length - 1];\n } else if (x <= xArray[0]) {\n return yArray[0];\n } else {\n uint256 lower;\n uint256 upper = xArray.length - 1;\n uint256 mid;\n while (upper - lower > 1) {\n mid = lower + (upper - lower) / 2;\n if (xArray[mid] <= x) {\n lower = mid;\n } else {\n upper = mid;\n }\n }\n if (yArray[upper] > yArray[lower]) {\n return\n yArray[lower] +\n ((yArray[upper] - yArray[lower]) * (x - xArray[lower])) /\n (xArray[upper] - xArray[lower]);\n } else {\n return\n yArray[lower] -\n ((yArray[lower] - yArray[upper]) * (x - xArray[lower])) /\n (xArray[upper] - xArray[lower]);\n }\n }\n }\n\n function _getStableMasterAndPoolManager(\n address agToken,\n address collateral\n ) internal view returns (address stableMaster, address poolManager) {\n stableMaster = IAgTokenMainnet(agToken).stableMaster();\n (poolManager, , , ) = ROUTER.mapPoolManagers(stableMaster, collateral);\n }\n\n // ====================== Constants and Initializers ===========================\n\n IAngleRouter public constant ROUTER = IAngleRouter(0xBB755240596530be0c1DE5DFD77ec6398471561d);\n ICore public constant CORE = ICore(0x61ed74de9Ca5796cF2F8fD60D54160D47E30B7c3);\n\n bytes32 public constant STABLE = keccak256(\"STABLE\");\n uint256 public constant BASE_PARAMS = 10 ** 9;\n\n error NotInitialized();\n error InvalidAmount();\n\n /// @custom:oz-upgrades-unsafe-allow constructor\n constructor() initializer {}\n}\n" + }, + "contracts/deprecated/vaultManager/OldVaultManagerERC721.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\nimport \"./OldVaultManagerStorage.sol\";\n\n/// @title VaultManagerERC721\n/// @author Angle Labs, Inc.\n/// @dev Base ERC721 Implementation of VaultManager\nabstract contract OldVaultManagerERC721 is IERC721MetadataUpgradeable, OldVaultManagerStorage {\n using SafeERC20 for IERC20;\n using Address for address;\n\n /// @inheritdoc IERC721MetadataUpgradeable\n string public name;\n /// @inheritdoc IERC721MetadataUpgradeable\n string public symbol;\n\n // ================================= MODIFIERS =================================\n\n /// @notice Checks if the person interacting with the vault with `vaultID` is approved\n /// @param caller Address of the person seeking to interact with the vault\n /// @param vaultID ID of the concerned vault\n modifier onlyApprovedOrOwner(address caller, uint256 vaultID) {\n if (!_isApprovedOrOwner(caller, vaultID)) revert NotApproved();\n _;\n }\n\n // ================================ ERC721 LOGIC ===============================\n\n /// @notice Checks whether a given address is approved for a vault or owns this vault\n /// @param spender Address for which vault ownership should be checked\n /// @param vaultID ID of the vault to check\n /// @return Whether the `spender` address owns or is approved for `vaultID`\n function isApprovedOrOwner(address spender, uint256 vaultID) external view returns (bool) {\n return _isApprovedOrOwner(spender, vaultID);\n }\n\n /// @inheritdoc IERC721MetadataUpgradeable\n function tokenURI(uint256 vaultID) external view returns (string memory) {\n if (!_exists(vaultID)) revert NonexistentVault();\n // There is no vault with `vaultID` equal to 0, so the following variable is\n // always greater than zero\n uint256 temp = vaultID;\n uint256 digits;\n while (temp != 0) {\n digits++;\n temp /= 10;\n }\n bytes memory buffer = new bytes(digits);\n while (vaultID != 0) {\n digits -= 1;\n buffer[digits] = bytes1(uint8(48 + uint256(vaultID % 10)));\n vaultID /= 10;\n }\n return bytes(_baseURI).length > 0 ? string(abi.encodePacked(_baseURI, string(buffer))) : \"\";\n }\n\n /// @inheritdoc IERC721Upgradeable\n function balanceOf(address owner) external view returns (uint256) {\n if (owner == address(0)) revert ZeroAddress();\n return _balances[owner];\n }\n\n /// @inheritdoc IERC721Upgradeable\n function ownerOf(uint256 vaultID) external view returns (address) {\n return _ownerOf(vaultID);\n }\n\n /// @inheritdoc IERC721Upgradeable\n function approve(address to, uint256 vaultID) external {\n address owner = _ownerOf(vaultID);\n if (to == owner) revert ApprovalToOwner();\n if (msg.sender != owner && !isApprovedForAll(owner, msg.sender)) revert NotApproved();\n\n _approve(to, vaultID);\n }\n\n /// @inheritdoc IERC721Upgradeable\n function getApproved(uint256 vaultID) external view returns (address) {\n if (!_exists(vaultID)) revert NonexistentVault();\n return _getApproved(vaultID);\n }\n\n /// @inheritdoc IERC721Upgradeable\n function setApprovalForAll(address operator, bool approved) external {\n _setApprovalForAll(msg.sender, operator, approved);\n }\n\n /// @inheritdoc IERC721Upgradeable\n function isApprovedForAll(address owner, address operator) public view returns (bool) {\n return _operatorApprovals[owner][operator] == 1;\n }\n\n /// @inheritdoc IERC721Upgradeable\n function transferFrom(address from, address to, uint256 vaultID) external onlyApprovedOrOwner(msg.sender, vaultID) {\n _transfer(from, to, vaultID);\n }\n\n /// @inheritdoc IERC721Upgradeable\n function safeTransferFrom(address from, address to, uint256 vaultID) external {\n safeTransferFrom(from, to, vaultID, \"\");\n }\n\n /// @inheritdoc IERC721Upgradeable\n function safeTransferFrom(\n address from,\n address to,\n uint256 vaultID,\n bytes memory _data\n ) public onlyApprovedOrOwner(msg.sender, vaultID) {\n _safeTransfer(from, to, vaultID, _data);\n }\n\n // ================================ ERC165 LOGIC ===============================\n\n /// @inheritdoc IERC165Upgradeable\n function supportsInterface(bytes4 interfaceId) external pure returns (bool) {\n return\n interfaceId == type(IERC721MetadataUpgradeable).interfaceId ||\n interfaceId == type(IERC721Upgradeable).interfaceId ||\n interfaceId == type(IVaultManager).interfaceId ||\n interfaceId == type(IERC165Upgradeable).interfaceId;\n }\n\n // ================== INTERNAL FUNCTIONS FOR THE ERC721 LOGIC ==================\n\n /// @notice Internal version of the `ownerOf` function\n function _ownerOf(uint256 vaultID) internal view returns (address owner) {\n owner = _owners[vaultID];\n if (owner == address(0)) revert NonexistentVault();\n }\n\n /// @notice Internal version of the `getApproved` function\n function _getApproved(uint256 vaultID) internal view returns (address) {\n return _vaultApprovals[vaultID];\n }\n\n /// @notice Internal version of the `safeTransferFrom` function (with the data parameter)\n function _safeTransfer(address from, address to, uint256 vaultID, bytes memory _data) internal {\n _transfer(from, to, vaultID);\n if (!_checkOnERC721Received(from, to, vaultID, _data)) revert NonERC721Receiver();\n }\n\n /// @notice Checks whether a vault exists\n /// @param vaultID ID of the vault to check\n /// @return Whether `vaultID` has been created\n function _exists(uint256 vaultID) internal view returns (bool) {\n return _owners[vaultID] != address(0);\n }\n\n /// @notice Internal version of the `isApprovedOrOwner` function\n function _isApprovedOrOwner(address spender, uint256 vaultID) internal view returns (bool) {\n // The following checks if the vault exists\n address owner = _ownerOf(vaultID);\n return (spender == owner || _getApproved(vaultID) == spender || _operatorApprovals[owner][spender] == 1);\n }\n\n /// @notice Internal version of the `createVault` function\n /// Mints `vaultID` and transfers it to `to`\n /// @dev This method is equivalent to the `_safeMint` method used in OpenZeppelin ERC721 contract\n /// @dev Emits a {Transfer} event\n function _mint(address to) internal returns (uint256 vaultID) {\n if (whitelistingActivated && (isWhitelisted[to] != 1 || isWhitelisted[msg.sender] != 1))\n revert NotWhitelisted();\n if (to == address(0)) revert ZeroAddress();\n\n unchecked {\n vaultIDCount += 1;\n }\n\n vaultID = vaultIDCount;\n _beforeTokenTransfer(address(0), to, vaultID);\n\n unchecked {\n _balances[to] += 1;\n }\n\n _owners[vaultID] = to;\n emit Transfer(address(0), to, vaultID);\n if (!_checkOnERC721Received(address(0), to, vaultID, \"\")) revert NonERC721Receiver();\n }\n\n /// @notice Destroys `vaultID`\n /// @dev `vaultID` must exist\n /// @dev Emits a {Transfer} event\n function _burn(uint256 vaultID) internal {\n address owner = _ownerOf(vaultID);\n\n _beforeTokenTransfer(owner, address(0), vaultID);\n // Clear approvals\n _approve(address(0), vaultID);\n // The following line cannot underflow as the owner's balance is necessarily\n // greater than 1\n unchecked {\n _balances[owner] -= 1;\n }\n delete _owners[vaultID];\n delete vaultData[vaultID];\n\n emit Transfer(owner, address(0), vaultID);\n }\n\n /// @notice Transfers `vaultID` from `from` to `to` as opposed to {transferFrom},\n /// this imposes no restrictions on msg.sender\n /// @dev `to` cannot be the zero address and `perpetualID` must be owned by `from`\n /// @dev Emits a {Transfer} event\n /// @dev A whitelist check is performed if necessary on the `to` address\n function _transfer(address from, address to, uint256 vaultID) internal {\n if (_ownerOf(vaultID) != from) revert NotApproved();\n if (to == address(0)) revert ZeroAddress();\n if (whitelistingActivated && isWhitelisted[to] != 1) revert NotWhitelisted();\n\n _beforeTokenTransfer(from, to, vaultID);\n\n // Clear approvals from the previous owner\n _approve(address(0), vaultID);\n unchecked {\n _balances[from] -= 1;\n _balances[to] += 1;\n }\n _owners[vaultID] = to;\n\n emit Transfer(from, to, vaultID);\n }\n\n /// @notice Approves `to` to operate on `vaultID`\n function _approve(address to, uint256 vaultID) internal {\n _vaultApprovals[vaultID] = to;\n emit Approval(_ownerOf(vaultID), to, vaultID);\n }\n\n /// @notice Internal version of the `setApprovalForAll` function\n /// @dev It contains an `approver` field to be used in case someone signs a permit for a particular\n /// address, and this signature is given to the contract by another address (like a router)\n function _setApprovalForAll(address approver, address operator, bool approved) internal {\n if (operator == approver) revert ApprovalToCaller();\n uint256 approval = approved ? 1 : 0;\n _operatorApprovals[approver][operator] = approval;\n emit ApprovalForAll(approver, operator, approved);\n }\n\n /// @notice Internal function to invoke {IERC721Receiver-onERC721Received} on a target address\n /// The call is not executed if the target address is not a contract\n /// @param from Address representing the previous owner of the given token ID\n /// @param to Target address that will receive the tokens\n /// @param vaultID ID of the token to be transferred\n /// @param _data Bytes optional data to send along with the call\n /// @return Bool whether the call correctly returned the expected value\n function _checkOnERC721Received(\n address from,\n address to,\n uint256 vaultID,\n bytes memory _data\n ) private returns (bool) {\n if (to.isContract()) {\n try IERC721ReceiverUpgradeable(to).onERC721Received(msg.sender, from, vaultID, _data) returns (\n bytes4 retval\n ) {\n return retval == IERC721ReceiverUpgradeable.onERC721Received.selector;\n } catch (bytes memory reason) {\n if (reason.length == 0) {\n revert NonERC721Receiver();\n } else {\n // solhint-disable-next-line no-inline-assembly\n assembly {\n revert(add(32, reason), mload(reason))\n }\n }\n }\n } else {\n return true;\n }\n }\n\n /// @notice Hook that is called before any token transfer. This includes minting and burning.\n /// Calling conditions:\n ///\n /// - When `from` and `to` are both non-zero, `from`'s `vaultID` will be\n /// transferred to `to`.\n /// - When `from` is zero, `vaultID` will be minted for `to`.\n /// - When `to` is zero, `from`'s `vaultID` will be burned.\n /// - `from` and `to` are never both zero.\n function _beforeTokenTransfer(address from, address to, uint256 vaultID) internal virtual {}\n}\n" + }, + "contracts/deprecated/vaultManager/OldVaultManagerPermit.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\nimport \"./OldVaultManagerERC721.sol\";\nimport \"../../interfaces/external/IERC1271.sol\";\n\n/// @title VaultManagerPermit\n/// @author Angle Labs, Inc.\n/// @dev Base Implementation of permit functions for the `VaultManager` contract\nabstract contract OldVaultManagerPermit is Initializable, OldVaultManagerERC721 {\n using Address for address;\n\n mapping(address => uint256) private _nonces;\n /* solhint-disable var-name-mixedcase */\n bytes32 private _HASHED_NAME;\n bytes32 private _HASHED_VERSION;\n bytes32 private _PERMIT_TYPEHASH;\n /* solhint-enable var-name-mixedcase */\n\n error ExpiredDeadline();\n error InvalidSignature();\n\n //solhint-disable-next-line\n function __ERC721Permit_init(string memory _name) internal onlyInitializing {\n _PERMIT_TYPEHASH = keccak256(\n \"Permit(address owner,address spender,bool approved,uint256 nonce,uint256 deadline)\"\n );\n _HASHED_NAME = keccak256(bytes(_name));\n _HASHED_VERSION = keccak256(bytes(\"1\"));\n }\n\n /// @notice Allows an address to give or revoke approval for all its vaults to another address\n /// @param owner Address signing the permit and giving (or revoking) its approval for all the controlled vaults\n /// @param spender Address to give approval to\n /// @param approved Whether to give or revoke the approval\n /// @param deadline Deadline parameter for the signature to be valid\n /// @dev The `v`, `r`, and `s` parameters are used as signature data\n function permit(\n address owner,\n address spender,\n bool approved,\n uint256 deadline,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) external {\n if (block.timestamp > deadline) revert ExpiredDeadline();\n // Additional signature checks performed in the `ECDSAUpgradeable.recover` function\n if (uint256(s) > 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D576E7357A4501DDFE92F46681B20A0 || (v != 27 && v != 28))\n revert InvalidSignature();\n\n bytes32 digest = keccak256(\n abi.encodePacked(\n \"\\x19\\x01\",\n _domainSeparatorV4(),\n keccak256(\n abi.encode(\n _PERMIT_TYPEHASH,\n // 0x3f43a9c6bafb5c7aab4e0cfe239dc5d4c15caf0381c6104188191f78a6640bd8,\n owner,\n spender,\n approved,\n _useNonce(owner),\n deadline\n )\n )\n )\n );\n if (owner.isContract()) {\n if (IERC1271(owner).isValidSignature(digest, abi.encodePacked(r, s, v)) != 0x1626ba7e)\n revert InvalidSignature();\n } else {\n address signer = ecrecover(digest, v, r, s);\n if (signer != owner || signer == address(0)) revert InvalidSignature();\n }\n\n _setApprovalForAll(owner, spender, approved);\n }\n\n /// @notice Returns the current nonce for an `owner` address\n function nonces(address owner) public view returns (uint256) {\n return _nonces[owner];\n }\n\n /// @notice Returns the domain separator for the current chain.\n // solhint-disable-next-line func-name-mixedcase\n function DOMAIN_SEPARATOR() external view returns (bytes32) {\n return _domainSeparatorV4();\n }\n\n /// @notice Internal version of the `DOMAIN_SEPARATOR` function\n function _domainSeparatorV4() internal view returns (bytes32) {\n return\n keccak256(\n abi.encode(\n // keccak256('EIP712Domain(string name,string version,uint256 chainId,address verifyingContract)')\n 0x8b73c3c69bb8fe3d512ecc4cf759cc79239f7b179b0ffacaa9a75d522b39400f,\n _HASHED_NAME,\n _HASHED_VERSION,\n block.chainid,\n address(this)\n )\n );\n }\n\n /// @notice Consumes a nonce for an address: returns the current value and increments it\n function _useNonce(address owner) internal returns (uint256 current) {\n current = _nonces[owner];\n _nonces[owner] = current + 1;\n }\n\n uint256[49] private __gap;\n}\n" + }, + "contracts/deprecated/vaultManager/OldVaultManagerStorage.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\nimport \"@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/token/ERC20/extensions/draft-IERC20PermitUpgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/token/ERC721/IERC721ReceiverUpgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/interfaces/IERC721MetadataUpgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/utils/introspection/IERC165Upgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/utils/AddressUpgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/security/ReentrancyGuardUpgradeable.sol\";\nimport \"@openzeppelin/contracts/token/ERC20/extensions/IERC20Metadata.sol\";\nimport \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\nimport \"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\";\n\nimport \"../../interfaces/IAgToken.sol\";\nimport \"../../interfaces/IOracle.sol\";\nimport \"../../interfaces/ISwapper.sol\";\nimport \"../../interfaces/ITreasury.sol\";\nimport \"../../interfaces/IVaultManager.sol\";\nimport \"../../interfaces/governance/IVeBoostProxy.sol\";\n\n/// @title VaultManagerStorage\n/// @author Angle Labs, Inc.\n/// @dev Variables, references, parameters and events needed in the `VaultManager` contract\n// solhint-disable-next-line max-states-count\ncontract OldVaultManagerStorage is IVaultManagerStorage, Initializable, ReentrancyGuardUpgradeable {\n /// @notice Base used for parameter computation: almost all the parameters of this contract are set in `BASE_PARAMS`\n uint256 public constant BASE_PARAMS = 10 ** 9;\n /// @notice Base used for interest rate computation\n uint256 public constant BASE_INTEREST = 10 ** 27;\n /// @notice Used for interest rate computation\n uint256 public constant HALF_BASE_INTEREST = 10 ** 27 / 2;\n\n // ================================= REFERENCES ================================\n\n /// @inheritdoc IVaultManagerStorage\n ITreasury public treasury;\n /// @inheritdoc IVaultManagerStorage\n IERC20 public collateral;\n /// @inheritdoc IVaultManagerStorage\n IAgToken public stablecoin;\n /// @inheritdoc IVaultManagerStorage\n IOracle public oracle;\n /// @notice Reference to the contract which computes adjusted veANGLE balances for liquidators boosts\n IVeBoostProxy public veBoostProxy;\n /// @notice Base of the collateral\n uint256 internal _collatBase;\n\n // ================================= PARAMETERS ================================\n // Unless specified otherwise, parameters of this contract are expressed in `BASE_PARAMS`\n\n /// @notice Maximum amount of stablecoins that can be issued with this contract (in `BASE_TOKENS`). This parameter should\n /// not be bigger than `type(uint256).max / BASE_INTEREST` otherwise there may be some overflows in the `increaseDebt` function\n uint256 public debtCeiling;\n /// @notice Threshold veANGLE balance values for the computation of the boost for liquidators: the length of this array\n /// should normally be 2. The base of the x-values in this array should be `BASE_TOKENS`\n uint256[] public xLiquidationBoost;\n /// @notice Values of the liquidation boost at the threshold values of x\n uint256[] public yLiquidationBoost;\n /// @inheritdoc IVaultManagerStorage\n uint64 public collateralFactor;\n /// @notice Maximum Health factor at which a vault can end up after a liquidation (unless it's fully liquidated)\n uint64 public targetHealthFactor;\n /// @notice Upfront fee taken when borrowing stablecoins: this fee is optional and should in practice not be used\n uint64 public borrowFee;\n /// @notice Upfront fee taken when repaying stablecoins: this fee is optional as well. It should be smaller\n /// than the liquidation surcharge (cf below) to avoid exploits where people voluntarily get liquidated at a 0\n /// discount to pay smaller repaying fees\n uint64 public repayFee;\n /// @notice Per second interest taken to borrowers taking agToken loans. Contrarily to other parameters, it is set in `BASE_INTEREST`\n /// that is to say in base 10**27\n uint64 public interestRate;\n /// @notice Fee taken by the protocol during a liquidation. Technically, this value is not the fee per se, it's 1 - fee.\n /// For instance for a 2% fee, `liquidationSurcharge` should be 98%\n uint64 public liquidationSurcharge;\n /// @notice Maximum discount given to liquidators\n uint64 public maxLiquidationDiscount;\n /// @notice Whether whitelisting is required to own a vault or not\n bool public whitelistingActivated;\n /// @notice Whether the contract is paused or not\n bool public paused;\n\n // ================================= VARIABLES =================================\n\n /// @notice Timestamp at which the `interestAccumulator` was updated\n uint256 public lastInterestAccumulatorUpdated;\n /// @inheritdoc IVaultManagerStorage\n uint256 public interestAccumulator;\n /// @inheritdoc IVaultManagerStorage\n uint256 public totalNormalizedDebt;\n /// @notice Surplus accumulated by the contract: surplus is always in stablecoins, and is then reset\n /// when the value is communicated to the treasury contract\n uint256 public surplus;\n /// @notice Bad debt made from liquidated vaults which ended up having no collateral and a positive amount\n /// of stablecoins\n uint256 public badDebt;\n\n // ================================== MAPPINGS =================================\n\n /// @inheritdoc IVaultManagerStorage\n mapping(uint256 => Vault) public vaultData;\n /// @notice Maps an address to 1 if it's whitelisted and can open or own a vault\n mapping(address => uint256) public isWhitelisted;\n\n // ================================ ERC721 DATA ================================\n\n /// @inheritdoc IVaultManagerStorage\n uint256 public vaultIDCount;\n\n /// @notice URI\n string internal _baseURI;\n\n // Mapping from `vaultID` to owner address\n mapping(uint256 => address) internal _owners;\n\n // Mapping from owner address to vault owned count\n mapping(address => uint256) internal _balances;\n\n // Mapping from `vaultID` to approved address\n mapping(uint256 => address) internal _vaultApprovals;\n\n // Mapping from owner to operator approvals\n mapping(address => mapping(address => uint256)) internal _operatorApprovals;\n\n uint256[50] private __gap;\n\n // =================================== EVENTS ==================================\n\n event AccruedToTreasury(uint256 surplusEndValue, uint256 badDebtEndValue);\n event CollateralAmountUpdated(uint256 vaultID, uint256 collateralAmount, uint8 isIncrease);\n event InterestAccumulatorUpdated(uint256 value, uint256 timestamp);\n event InternalDebtUpdated(uint256 vaultID, uint256 internalAmount, uint8 isIncrease);\n event FiledUint64(uint64 param, bytes32 what);\n event DebtCeilingUpdated(uint256 debtCeiling);\n event LiquidationBoostParametersUpdated(address indexed _veBoostProxy, uint256[] xBoost, uint256[] yBoost);\n event LiquidatedVaults(uint256[] vaultIDs);\n event DebtTransferred(uint256 srcVaultID, uint256 dstVaultID, address dstVaultManager, uint256 amount);\n\n // =================================== ERRORS ==================================\n\n error ApprovalToOwner();\n error ApprovalToCaller();\n error DustyLeftoverAmount();\n error DebtCeilingExceeded();\n error HealthyVault();\n error IncompatibleLengths();\n error InsolventVault();\n error InvalidParameterValue();\n error InvalidParameterType();\n error InvalidSetOfParameters();\n error InvalidTreasury();\n error NonERC721Receiver();\n error NonexistentVault();\n error NotApproved();\n error NotGovernor();\n error NotGovernorOrGuardian();\n error NotTreasury();\n error NotWhitelisted();\n error NotVaultManager();\n error Paused();\n error TooHighParameterValue();\n error TooSmallParameterValue();\n error ZeroAddress();\n\n /// @custom:oz-upgrades-unsafe-allow constructor\n constructor() initializer {}\n}\n" + }, + "contracts/external/ProxyAdmin.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\nimport \"./TransparentUpgradeableProxy.sol\";\nimport \"@openzeppelin/contracts/access/Ownable.sol\";\n\n/**\n * @dev This is an auxiliary contract meant to be assigned as the admin of a {TransparentUpgradeableProxy}. For an\n * explanation of why you would want to use this see the documentation for {TransparentUpgradeableProxy}.\n * This contract was fully forked from OpenZeppelin `ProxyAdmin`\n */\ncontract ProxyAdmin is Ownable {\n /**\n * @dev Returns the current implementation of `proxy`.\n *\n * Requirements:\n *\n * - This contract must be the admin of `proxy`.\n */\n function getProxyImplementation(TransparentUpgradeableProxy proxy) public view virtual returns (address) {\n // We need to manually run the static call since the getter cannot be flagged as view\n // bytes4(keccak256(\"implementation()\")) == 0x5c60da1b\n (bool success, bytes memory returndata) = address(proxy).staticcall(hex\"5c60da1b\");\n require(success);\n return abi.decode(returndata, (address));\n }\n\n /**\n * @dev Returns the current admin of `proxy`.\n *\n * Requirements:\n *\n * - This contract must be the admin of `proxy`.\n */\n function getProxyAdmin(TransparentUpgradeableProxy proxy) public view virtual returns (address) {\n // We need to manually run the static call since the getter cannot be flagged as view\n // bytes4(keccak256(\"admin()\")) == 0xf851a440\n (bool success, bytes memory returndata) = address(proxy).staticcall(hex\"f851a440\");\n require(success);\n return abi.decode(returndata, (address));\n }\n\n /**\n * @dev Changes the admin of `proxy` to `newAdmin`.\n *\n * Requirements:\n *\n * - This contract must be the current admin of `proxy`.\n */\n function changeProxyAdmin(TransparentUpgradeableProxy proxy, address newAdmin) public virtual onlyOwner {\n proxy.changeAdmin(newAdmin);\n }\n\n /**\n * @dev Upgrades `proxy` to `implementation`. See {TransparentUpgradeableProxy-upgradeTo}.\n *\n * Requirements:\n *\n * - This contract must be the admin of `proxy`.\n */\n function upgrade(TransparentUpgradeableProxy proxy, address implementation) public virtual onlyOwner {\n proxy.upgradeTo(implementation);\n }\n\n /**\n * @dev Upgrades `proxy` to `implementation` and calls a function on the new implementation. See\n * {TransparentUpgradeableProxy-upgradeToAndCall}.\n *\n * Requirements:\n *\n * - This contract must be the admin of `proxy`.\n */\n function upgradeAndCall(\n TransparentUpgradeableProxy proxy,\n address implementation,\n bytes memory data\n ) public payable virtual onlyOwner {\n proxy.upgradeToAndCall{ value: msg.value }(implementation, data);\n }\n}\n" + }, + "contracts/external/TransparentUpgradeableProxy.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\nimport \"@openzeppelin/contracts/proxy/ERC1967/ERC1967Proxy.sol\";\n\n/**\n * @dev This contract implements a proxy that is upgradeable by an admin. It is fully forked from OpenZeppelin\n * `TransparentUpgradeableProxy`\n *\n * To avoid https://medium.com/nomic-labs-blog/malicious-backdoors-in-ethereum-proxies-62629adf3357[proxy selector\n * clashing], which can potentially be used in an attack, this contract uses the\n * https://blog.openzeppelin.com/the-transparent-proxy-pattern/[transparent proxy pattern]. This pattern implies two\n * things that go hand in hand:\n *\n * 1. If any account other than the admin calls the proxy, the call will be forwarded to the implementation, even if\n * that call matches one of the admin functions exposed by the proxy itself.\n * 2. If the admin calls the proxy, it can access the admin functions, but its calls will never be forwarded to the\n * implementation. If the admin tries to call a function on the implementation it will fail with an error that says\n * \"admin cannot fallback to proxy target\".\n *\n * These properties mean that the admin account can only be used for admin actions like upgrading the proxy or changing\n * the admin, so it's best if it's a dedicated account that is not used for anything else. This will avoid headaches due\n * to sudden errors when trying to call a function from the proxy implementation.\n *\n * Our recommendation is for the dedicated account to be an instance of the {ProxyAdmin} contract. If set up this way,\n * you should think of the `ProxyAdmin` instance as the real administrative interface of your proxy.\n */\ncontract TransparentUpgradeableProxy is ERC1967Proxy {\n /**\n * @dev Initializes an upgradeable proxy managed by `_admin`, backed by the implementation at `_logic`, and\n * optionally initialized with `_data` as explained in {ERC1967Proxy-constructor}.\n */\n constructor(address _logic, address admin_, bytes memory _data) payable ERC1967Proxy(_logic, _data) {\n assert(_ADMIN_SLOT == bytes32(uint256(keccak256(\"eip1967.proxy.admin\")) - 1));\n _changeAdmin(admin_);\n }\n\n /**\n * @dev Modifier used internally that will delegate the call to the implementation unless the sender is the admin.\n */\n modifier ifAdmin() {\n if (msg.sender == _getAdmin()) {\n _;\n } else {\n _fallback();\n }\n }\n\n /**\n * @dev Returns the current admin.\n *\n * NOTE: Only the admin can call this function. See {ProxyAdmin-getProxyAdmin}.\n *\n * TIP: To get this value clients can read directly from the storage slot shown below (specified by EIP1967) using the\n * https://eth.wiki/json-rpc/API#eth_getstorageat[`eth_getStorageAt`] RPC call.\n * `0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103`\n */\n function admin() external ifAdmin returns (address admin_) {\n admin_ = _getAdmin();\n }\n\n /**\n * @dev Returns the current implementation.\n *\n * NOTE: Only the admin can call this function. See {ProxyAdmin-getProxyImplementation}.\n *\n * TIP: To get this value clients can read directly from the storage slot shown below (specified by EIP1967) using the\n * https://eth.wiki/json-rpc/API#eth_getstorageat[`eth_getStorageAt`] RPC call.\n * `0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc`\n */\n function implementation() external ifAdmin returns (address implementation_) {\n implementation_ = _implementation();\n }\n\n /**\n * @dev Changes the admin of the proxy.\n *\n * Emits an {AdminChanged} event.\n *\n * NOTE: Only the admin can call this function. See {ProxyAdmin-changeProxyAdmin}.\n */\n function changeAdmin(address newAdmin) external virtual ifAdmin {\n _changeAdmin(newAdmin);\n }\n\n /**\n * @dev Upgrade the implementation of the proxy.\n *\n * NOTE: Only the admin can call this function. See {ProxyAdmin-upgrade}.\n */\n function upgradeTo(address newImplementation) external ifAdmin {\n _upgradeToAndCall(newImplementation, bytes(\"\"), false);\n }\n\n /**\n * @dev Upgrade the implementation of the proxy, and then call a function from the new implementation as specified\n * by `data`, which should be an encoded function call. This is useful to initialize new storage variables in the\n * proxied contract.\n *\n * NOTE: Only the admin can call this function. See {ProxyAdmin-upgradeAndCall}.\n */\n function upgradeToAndCall(address newImplementation, bytes calldata data) external payable ifAdmin {\n _upgradeToAndCall(newImplementation, data, true);\n }\n\n /**\n * @dev Returns the current admin.\n */\n function _admin() internal view virtual returns (address) {\n return _getAdmin();\n }\n\n /**\n * @dev Makes sure the admin cannot access the fallback function. See {Proxy-_beforeFallback}.\n */\n function _beforeFallback() internal virtual override {\n require(msg.sender != _getAdmin(), \"TransparentUpgradeableProxy: admin cannot fallback to proxy target\");\n super._beforeFallback();\n }\n}\n" + }, + "contracts/flashloan/FlashAngle.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\nimport \"@openzeppelin/contracts-upgradeable/security/ReentrancyGuardUpgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol\";\nimport \"@openzeppelin/contracts/interfaces/IERC3156FlashBorrower.sol\";\nimport \"@openzeppelin/contracts/interfaces/IERC3156FlashLender.sol\";\nimport \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\nimport \"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\";\n\nimport \"../interfaces/IAgToken.sol\";\nimport \"../interfaces/ICoreBorrow.sol\";\nimport \"../interfaces/IFlashAngle.sol\";\nimport \"../interfaces/ITreasury.sol\";\n\n/// @title FlashAngle\n/// @author Angle Labs, Inc.\n/// @notice Contract to take flash loans on top of several AgToken contracts\ncontract FlashAngle is IERC3156FlashLender, IFlashAngle, Initializable, ReentrancyGuardUpgradeable {\n using SafeERC20 for IERC20;\n /// @notice Base used for parameter computation\n uint256 public constant BASE_PARAMS = 10 ** 9;\n /// @notice Success message received when calling a `FlashBorrower` contract\n bytes32 public constant CALLBACK_SUCCESS = keccak256(\"ERC3156FlashBorrower.onFlashLoan\");\n\n /// @notice Struct encoding for a given stablecoin the parameters\n struct StablecoinData {\n // Maximum amount borrowable for this stablecoin\n uint256 maxBorrowable;\n // Flash loan fee taken by the protocol for a flash loan on this stablecoin\n uint64 flashLoanFee;\n // Treasury address responsible of the stablecoin\n address treasury;\n }\n\n // ======================= Parameters and References ===========================\n\n /// @notice Maps a stablecoin to the data and parameters for flash loans\n mapping(IAgToken => StablecoinData) public stablecoinMap;\n /// @inheritdoc IFlashAngle\n ICoreBorrow public core;\n\n // =============================== Event =======================================\n\n event FlashLoan(address indexed stablecoin, uint256 amount, IERC3156FlashBorrower indexed receiver);\n event FlashLoanParametersUpdated(IAgToken indexed stablecoin, uint64 _flashLoanFee, uint256 _maxBorrowable);\n\n // =============================== Errors ======================================\n\n error InvalidReturnMessage();\n error NotCore();\n error NotGovernorOrGuardian();\n error NotTreasury();\n error TooBigAmount();\n error TooHighParameterValue();\n error UnsupportedStablecoin();\n error ZeroAddress();\n\n /// @notice Initializes the contract\n /// @param _core Core address handling this module\n function initialize(ICoreBorrow _core) public initializer {\n if (address(_core) == address(0)) revert ZeroAddress();\n core = _core;\n }\n\n /// @custom:oz-upgrades-unsafe-allow constructor\n constructor() initializer {}\n\n // =================================== Modifiers ===============================\n\n /// @notice Checks whether the sender is the core contract\n modifier onlyCore() {\n if (msg.sender != address(core)) revert NotCore();\n _;\n }\n\n /// @notice Checks whether a given stablecoin has been initialized in this contract\n /// @param stablecoin Stablecoin to check\n /// @dev To check whether a stablecoin has been initialized, we just need to check whether its associated\n /// `treasury` address is not null in the `stablecoinMap`. This is what's checked in the `CoreBorrow` contract\n /// when adding support for a stablecoin\n modifier onlyExistingStablecoin(IAgToken stablecoin) {\n if (stablecoinMap[stablecoin].treasury == address(0)) revert UnsupportedStablecoin();\n _;\n }\n\n // ================================ ERC3156 Spec ===============================\n\n /// @inheritdoc IERC3156FlashLender\n function flashFee(address token, uint256 amount) external view returns (uint256) {\n return _flashFee(token, amount);\n }\n\n /// @inheritdoc IERC3156FlashLender\n function maxFlashLoan(address token) external view returns (uint256) {\n // It will be 0 anyway if the token was not added\n return stablecoinMap[IAgToken(token)].maxBorrowable;\n }\n\n /// @inheritdoc IERC3156FlashLender\n function flashLoan(\n IERC3156FlashBorrower receiver,\n address token,\n uint256 amount,\n bytes calldata data\n ) external nonReentrant returns (bool) {\n uint256 fee = _flashFee(token, amount);\n if (amount > stablecoinMap[IAgToken(token)].maxBorrowable) revert TooBigAmount();\n IAgToken(token).mint(address(receiver), amount);\n if (receiver.onFlashLoan(msg.sender, token, amount, fee, data) != CALLBACK_SUCCESS)\n revert InvalidReturnMessage();\n // Token must be an agToken here so normally no need to use `safeTransferFrom`, but out of safety\n // and in case governance whitelists an agToken which does not have a correct implementation, we prefer\n // to use `safeTransferFrom` here\n IERC20(token).safeTransferFrom(address(receiver), address(this), amount + fee);\n IAgToken(token).burnSelf(amount, address(this));\n emit FlashLoan(token, amount, receiver);\n return true;\n }\n\n /// @notice Internal function to compute the fee induced for taking a flash loan of `amount` of `token`\n /// @param token The loan currency\n /// @param amount The amount of tokens lent\n /// @dev This function will revert if the `token` requested is not whitelisted here\n function _flashFee(\n address token,\n uint256 amount\n ) internal view onlyExistingStablecoin(IAgToken(token)) returns (uint256) {\n return (amount * stablecoinMap[IAgToken(token)].flashLoanFee) / BASE_PARAMS;\n }\n\n // ============================ Treasury Only Function =========================\n\n /// @inheritdoc IFlashAngle\n function accrueInterestToTreasury(IAgToken stablecoin) external returns (uint256 balance) {\n address treasury = stablecoinMap[stablecoin].treasury;\n if (msg.sender != treasury) revert NotTreasury();\n balance = stablecoin.balanceOf(address(this));\n IERC20(address(stablecoin)).safeTransfer(treasury, balance);\n }\n\n // =========================== Governance Only Function ========================\n\n /// @notice Sets the parameters for a given stablecoin\n /// @param stablecoin Stablecoin to change the parameters for\n /// @param _flashLoanFee New flash loan fee for this stablecoin\n /// @param _maxBorrowable Maximum amount that can be borrowed in a single flash loan\n /// @dev Setting a `maxBorrowable` parameter equal to 0 is a way to pause the functionality\n /// @dev Parameters can only be modified for whitelisted stablecoins\n function setFlashLoanParameters(\n IAgToken stablecoin,\n uint64 _flashLoanFee,\n uint256 _maxBorrowable\n ) external onlyExistingStablecoin(stablecoin) {\n if (!core.isGovernorOrGuardian(msg.sender)) revert NotGovernorOrGuardian();\n if (_flashLoanFee > BASE_PARAMS) revert TooHighParameterValue();\n stablecoinMap[stablecoin].flashLoanFee = _flashLoanFee;\n stablecoinMap[stablecoin].maxBorrowable = _maxBorrowable;\n emit FlashLoanParametersUpdated(stablecoin, _flashLoanFee, _maxBorrowable);\n }\n\n // =========================== CoreBorrow Only Functions =======================\n\n /// @inheritdoc IFlashAngle\n function addStablecoinSupport(address _treasury) external onlyCore {\n stablecoinMap[IAgToken(ITreasury(_treasury).stablecoin())].treasury = _treasury;\n }\n\n /// @inheritdoc IFlashAngle\n function removeStablecoinSupport(address _treasury) external onlyCore {\n delete stablecoinMap[IAgToken(ITreasury(_treasury).stablecoin())];\n }\n\n /// @inheritdoc IFlashAngle\n function setCore(address _core) external onlyCore {\n core = ICoreBorrow(_core);\n }\n}\n" + }, + "contracts/interfaces/coreModule/IAgTokenMainnet.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\n/// @title IAgTokenMainnet\n/// @author Angle Labs, Inc.\ninterface IAgTokenMainnet {\n function stableMaster() external view returns (address);\n}\n" + }, + "contracts/interfaces/coreModule/ICore.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\n/// @title ICore\n/// @author Angle Labs, Inc.\ninterface ICore {\n function stablecoinList() external view returns (address[] memory);\n}\n" + }, + "contracts/interfaces/coreModule/ILiquidityGauge.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\ninterface ILiquidityGauge {\n function deposit(\n uint256 _value,\n address _addr,\n // solhint-disable-next-line\n bool _claim_rewards\n ) external;\n\n function withdraw(\n uint256 _value,\n // solhint-disable-next-line\n bool _claim_rewards\n ) external;\n\n // solhint-disable-next-line\n function claim_rewards(address _addr, address _receiver) external;\n\n // solhint-disable-next-line\n function claimable_reward(address _addr, address _reward_token) external view returns (uint256 amount);\n}\n" + }, + "contracts/interfaces/coreModule/IOracleCore.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\n/// @title IOracleCore\n/// @author Angle Labs, Inc.\ninterface IOracleCore {\n function readUpper() external view returns (uint256);\n\n function readQuoteLower(uint256 baseAmount) external view returns (uint256);\n}\n" + }, + "contracts/interfaces/coreModule/IPerpetualManager.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\n/// @title IPerpetualManager\n/// @author Angle Labs, Inc.\ninterface IPerpetualManager {\n function totalHedgeAmount() external view returns (uint256);\n\n function maintenanceMargin() external view returns (uint64);\n\n function maxLeverage() external view returns (uint64);\n\n function targetHAHedge() external view returns (uint64);\n\n function limitHAHedge() external view returns (uint64);\n\n function lockTime() external view returns (uint64);\n\n function haBonusMalusDeposit() external view returns (uint64);\n\n function haBonusMalusWithdraw() external view returns (uint64);\n\n function xHAFeesDeposit(uint256) external view returns (uint64);\n\n function yHAFeesDeposit(uint256) external view returns (uint64);\n\n function xHAFeesWithdraw(uint256) external view returns (uint64);\n\n function yHAFeesWithdraw(uint256) external view returns (uint64);\n}\n" + }, + "contracts/interfaces/coreModule/IPoolManager.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\n/// @title IPoolManager\n/// @author Angle Labs, Inc.\ninterface IPoolManager {\n function feeManager() external view returns (address);\n\n function strategyList(uint256) external view returns (address);\n}\n" + }, + "contracts/interfaces/coreModule/IStableMaster.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\nimport \"./IPerpetualManager.sol\";\nimport \"./IOracleCore.sol\";\n\n// Struct to handle all the parameters to manage the fees\n// related to a given collateral pool (associated to the stablecoin)\nstruct MintBurnData {\n // Values of the thresholds to compute the minting fees\n // depending on HA hedge (scaled by `BASE_PARAMS`)\n uint64[] xFeeMint;\n // Values of the fees at thresholds (scaled by `BASE_PARAMS`)\n uint64[] yFeeMint;\n // Values of the thresholds to compute the burning fees\n // depending on HA hedge (scaled by `BASE_PARAMS`)\n uint64[] xFeeBurn;\n // Values of the fees at thresholds (scaled by `BASE_PARAMS`)\n uint64[] yFeeBurn;\n // Max proportion of collateral from users that can be covered by HAs\n // It is exactly the same as the parameter of the same name in `PerpetualManager`, whenever one is updated\n // the other changes accordingly\n uint64 targetHAHedge;\n // Minting fees correction set by the `FeeManager` contract: they are going to be multiplied\n // to the value of the fees computed using the hedge curve\n // Scaled by `BASE_PARAMS`\n uint64 bonusMalusMint;\n // Burning fees correction set by the `FeeManager` contract: they are going to be multiplied\n // to the value of the fees computed using the hedge curve\n // Scaled by `BASE_PARAMS`\n uint64 bonusMalusBurn;\n // Parameter used to limit the number of stablecoins that can be issued using the concerned collateral\n uint256 capOnStableMinted;\n}\n\n// Struct to handle all the variables and parameters to handle SLPs in the protocol\n// including the fraction of interests they receive or the fees to be distributed to\n// them\nstruct SLPData {\n // Last timestamp at which the `sanRate` has been updated for SLPs\n uint256 lastBlockUpdated;\n // Fees accumulated from previous blocks and to be distributed to SLPs\n uint256 lockedInterests;\n // Max interests used to update the `sanRate` in a single block\n // Should be in collateral token base\n uint256 maxInterestsDistributed;\n // Amount of fees left aside for SLPs and that will be distributed\n // when the protocol is collateralized back again\n uint256 feesAside;\n // Part of the fees normally going to SLPs that is left aside\n // before the protocol is collateralized back again (depends on collateral ratio)\n // Updated by keepers and scaled by `BASE_PARAMS`\n uint64 slippageFee;\n // Portion of the fees from users minting and burning\n // that goes to SLPs (the rest goes to surplus)\n uint64 feesForSLPs;\n // Slippage factor that's applied to SLPs exiting (depends on collateral ratio)\n // If `slippage = BASE_PARAMS`, SLPs can get nothing, if `slippage = 0` they get their full claim\n // Updated by keepers and scaled by `BASE_PARAMS`\n uint64 slippage;\n // Portion of the interests from lending\n // that goes to SLPs (the rest goes to surplus)\n uint64 interestsForSLPs;\n}\n\n/// @title IStableMaster\n/// @author Angle Labs, Inc.\ninterface IStableMaster {\n function agToken() external view returns (address);\n\n function updateStocksUsers(uint256 amount, address poolManager) external;\n\n function collateralMap(\n address poolManager\n )\n external\n view\n returns (\n address token,\n address sanToken,\n IPerpetualManager perpetualManager,\n IOracleCore oracle,\n uint256 stocksUsers,\n uint256 sanRate,\n uint256 collatBase,\n SLPData memory slpData,\n MintBurnData memory feeData\n );\n\n function paused(bytes32) external view returns (bool);\n\n function deposit(uint256 amount, address user, address poolManager) external;\n\n function withdraw(uint256 amount, address burner, address dest, address poolManager) external;\n}\n" + }, + "contracts/interfaces/external/create2/ImmutableCreate2Factory.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\ninterface ImmutableCreate2Factory {\n function safeCreate2(bytes32 salt, bytes memory initCode) external payable returns (address deploymentAddress);\n\n function findCreate2Address(\n bytes32 salt,\n bytes calldata initCode\n ) external view returns (address deploymentAddress);\n\n function findCreate2AddressViaHash(\n bytes32 salt,\n bytes32 initCodeHash\n ) external view returns (address deploymentAddress);\n}\n" + }, + "contracts/interfaces/external/IERC1271.sol": { + "content": "// SPDX-License-Identifier: GPL-2.0-or-later\npragma solidity ^0.8.12;\n\n/// @title Interface for verifying contract-based account signatures\n/// @notice Interface that verifies provided signature for the data\n/// @dev Interface defined by EIP-1271\ninterface IERC1271 {\n /// @notice Returns whether the provided signature is valid for the provided data\n /// @dev MUST return the bytes4 magic value 0x1626ba7e when function passes.\n /// MUST NOT modify state (using STATICCALL for solc < 0.5, view modifier for solc > 0.5).\n /// MUST allow external calls.\n /// @param hash Hash of the data to be signed\n /// @param signature Signature byte array associated with _data\n /// @return magicValue The bytes4 magic value 0x1626ba7e\n function isValidSignature(bytes32 hash, bytes memory signature) external view returns (bytes4 magicValue);\n}\n" + }, + "contracts/interfaces/external/IERC4626.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\npragma solidity >=0.8.0;\n\nimport \"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\";\nimport \"@openzeppelin/contracts/token/ERC20/ERC20.sol\";\n\n/// @notice Minimal IERC4646 tokenized Vault interface.\n/// @author Forked from Solmate (https://github.com/Rari-Capital/solmate/blob/main/src/mixins/ERC4626.sol)\n/// @dev Do not use in production! ERC-4626 is still in the review stage and is subject to change.\ninterface IERC4626 {\n event Deposit(address indexed from, address indexed to, uint256 amount, uint256 shares);\n event Withdraw(address indexed from, address indexed to, uint256 amount, uint256 shares);\n\n /// @notice Transfers a given amount of asset to the reactor and mint shares accordingly\n /// @param amount Given amount of asset\n /// @param to Address to mint shares to\n /// @return shares Amount of shares minted to `to`\n function deposit(uint256 amount, address to) external returns (uint256 shares);\n\n /// @notice Mints a given amount of shares to the reactor and transfer assets accordingly\n /// @param shares Given amount of shares\n /// @param to Address to mint shares to\n /// @return amount Amount of `asset` taken to the `msg.sender` to mint `shares`\n function mint(uint256 shares, address to) external returns (uint256 amount);\n\n /// @notice Transfers a given amount of asset from the reactor and burn shares accordingly\n /// @param amount Given amount of asset\n /// @param to Address to transfer assets to\n /// @param from Address to burn shares from\n /// @return shares Amount of shares burnt in the operation\n function withdraw(uint256 amount, address to, address from) external returns (uint256 shares);\n\n /// @notice Burns a given amount of shares to the reactor and transfer assets accordingly\n /// @param shares Given amount of shares\n /// @param to Address to transfer assets to\n /// @param from Address to burn shares from\n /// @return amount Amount of assets redeemed in the operation\n function redeem(uint256 shares, address to, address from) external returns (uint256 amount);\n\n /// @notice Returns the total assets managed by this reactor\n function totalAssets() external view returns (uint256);\n\n /// @notice Converts an amount of assets to the corresponding amount of reactor shares\n /// @param assets Amount of asset to convert\n /// @return Shares corresponding to the amount of assets obtained\n function convertToShares(uint256 assets) external view returns (uint256);\n\n /// @notice Converts an amount of shares to its current value in asset\n /// @param shares Amount of shares to convert\n /// @return Amount of assets corresponding to the amount of assets given\n function convertToAssets(uint256 shares) external view returns (uint256);\n\n /// @notice Computes how many shares one would get by depositing `assets`\n /// @param assets Amount of asset to convert\n function previewDeposit(uint256 assets) external view returns (uint256);\n\n /// @notice Computes how many assets one would need to mint `shares`\n /// @param shares Amount of shares required\n function previewMint(uint256 shares) external view returns (uint256);\n\n /// @notice Computes how many shares one would need to withdraw assets\n /// @param assets Amount of asset to withdraw\n function previewWithdraw(uint256 assets) external view returns (uint256);\n\n /// @notice Computes how many assets one would get by burning shares\n /// @param shares Amount of shares to burn\n function previewRedeem(uint256 shares) external view returns (uint256);\n\n /// @notice Max deposit allowed for a user\n /// @param user Address of the user to check\n function maxDeposit(address user) external returns (uint256);\n\n /// @notice Max mint allowed for a user\n /// @param user Address of the user to check\n function maxMint(address user) external returns (uint256);\n\n /// @notice Max withdraw allowed for a user\n /// @param user Address of the user to check\n function maxWithdraw(address user) external returns (uint256);\n\n /// @notice Max redeem allowed for a user\n /// @param user Address of the user to check\n function maxRedeem(address user) external returns (uint256);\n}\n" + }, + "contracts/interfaces/external/IWETH9.sol": { + "content": "// SPDX-License-Identifier: GPL-2.0-or-later\npragma solidity ^0.8.12;\n\nimport \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\n\n/// @title Interface for WETH9\ninterface IWETH9 is IERC20 {\n /// @notice Deposit ether to get wrapped ether\n function deposit() external payable;\n\n /// @notice Withdraw wrapped ether to get ether\n function withdraw(uint256) external;\n}\n" + }, + "contracts/interfaces/external/layerZero/ILayerZeroEndpoint.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity >=0.5.0;\n\nimport \"./ILayerZeroUserApplicationConfig.sol\";\n\ninterface ILayerZeroEndpoint is ILayerZeroUserApplicationConfig {\n // @notice send a LayerZero message to the specified address at a LayerZero endpoint.\n // @param _dstChainId - the destination chain identifier\n // @param _destination - the address on destination chain (in bytes). address length/format may vary by chains\n // @param _payload - a custom bytes payload to send to the destination contract\n // @param _refundAddress - if the source transaction is cheaper than the amount of value passed, refund the additional amount to this address\n // @param _zroPaymentAddress - the address of the ZRO token holder who would pay for the transaction\n // @param _adapterParams - parameters for custom functionality. e.g. receive airdropped native gas from the relayer on destination\n function send(\n uint16 _dstChainId,\n bytes calldata _destination,\n bytes calldata _payload,\n address payable _refundAddress,\n address _zroPaymentAddress,\n bytes calldata _adapterParams\n ) external payable;\n\n // @notice used by the messaging library to publish verified payload\n // @param _srcChainId - the source chain identifier\n // @param _srcAddress - the source contract (as bytes) at the source chain\n // @param _dstAddress - the address on destination chain\n // @param _nonce - the unbound message ordering nonce\n // @param _gasLimit - the gas limit for external contract execution\n // @param _payload - verified payload to send to the destination contract\n function receivePayload(\n uint16 _srcChainId,\n bytes calldata _srcAddress,\n address _dstAddress,\n uint64 _nonce,\n uint256 _gasLimit,\n bytes calldata _payload\n ) external;\n\n // @notice get the inboundNonce of a lzApp from a source chain which could be EVM or non-EVM chain\n // @param _srcChainId - the source chain identifier\n // @param _srcAddress - the source chain contract address\n function getInboundNonce(uint16 _srcChainId, bytes calldata _srcAddress) external view returns (uint64);\n\n // @notice get the outboundNonce from this source chain which, consequently, is always an EVM\n // @param _srcAddress - the source chain contract address\n function getOutboundNonce(uint16 _dstChainId, address _srcAddress) external view returns (uint64);\n\n // @notice gets a quote in source native gas, for the amount that send() requires to pay for message delivery\n // @param _dstChainId - the destination chain identifier\n // @param _userApplication - the user app address on this EVM chain\n // @param _payload - the custom message to send over LayerZero\n // @param _payInZRO - if false, user app pays the protocol fee in native token\n // @param _adapterParam - parameters for the adapter service, e.g. send some dust native token to dstChain\n function estimateFees(\n uint16 _dstChainId,\n address _userApplication,\n bytes calldata _payload,\n bool _payInZRO,\n bytes calldata _adapterParam\n ) external view returns (uint256 nativeFee, uint256 zroFee);\n\n // @notice get this Endpoint's immutable source identifier\n function getChainId() external view returns (uint16);\n\n // @notice the interface to retry failed message on this Endpoint destination\n // @param _srcChainId - the source chain identifier\n // @param _srcAddress - the source chain contract address\n // @param _payload - the payload to be retried\n function retryPayload(uint16 _srcChainId, bytes calldata _srcAddress, bytes calldata _payload) external;\n\n // @notice query if any STORED payload (message blocking) at the endpoint.\n // @param _srcChainId - the source chain identifier\n // @param _srcAddress - the source chain contract address\n function hasStoredPayload(uint16 _srcChainId, bytes calldata _srcAddress) external view returns (bool);\n\n // @notice query if the _libraryAddress is valid for sending msgs.\n // @param _userApplication - the user app address on this EVM chain\n function getSendLibraryAddress(address _userApplication) external view returns (address);\n\n // @notice query if the _libraryAddress is valid for receiving msgs.\n // @param _userApplication - the user app address on this EVM chain\n function getReceiveLibraryAddress(address _userApplication) external view returns (address);\n\n // @notice query if the non-reentrancy guard for send() is on\n // @return true if the guard is on. false otherwise\n function isSendingPayload() external view returns (bool);\n\n // @notice query if the non-reentrancy guard for receive() is on\n // @return true if the guard is on. false otherwise\n function isReceivingPayload() external view returns (bool);\n\n // @notice get the configuration of the LayerZero messaging library of the specified version\n // @param _version - messaging library version\n // @param _chainId - the chainId for the pending config change\n // @param _userApplication - the contract address of the user application\n // @param _configType - type of configuration. every messaging library has its own convention.\n function getConfig(\n uint16 _version,\n uint16 _chainId,\n address _userApplication,\n uint256 _configType\n ) external view returns (bytes memory);\n\n // @notice get the send() LayerZero messaging library version\n // @param _userApplication - the contract address of the user application\n function getSendVersion(address _userApplication) external view returns (uint16);\n\n // @notice get the lzReceive() LayerZero messaging library version\n // @param _userApplication - the contract address of the user application\n function getReceiveVersion(address _userApplication) external view returns (uint16);\n}\n" + }, + "contracts/interfaces/external/layerZero/ILayerZeroReceiver.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity >=0.5.0;\n\ninterface ILayerZeroReceiver {\n // @notice LayerZero endpoint will invoke this function to deliver the message on the destination\n // @param _srcChainId - the source endpoint identifier\n // @param _srcAddress - the source sending contract address from the source chain\n // @param _nonce - the ordered message nonce\n // @param _payload - the signed payload is the UA bytes has encoded to be sent\n function lzReceive(uint16 _srcChainId, bytes calldata _srcAddress, uint64 _nonce, bytes calldata _payload) external;\n}\n" + }, + "contracts/interfaces/external/layerZero/ILayerZeroUserApplicationConfig.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity >=0.5.0;\n\ninterface ILayerZeroUserApplicationConfig {\n // @notice set the configuration of the LayerZero messaging library of the specified version\n // @param _version - messaging library version\n // @param _chainId - the chainId for the pending config change\n // @param _configType - type of configuration. every messaging library has its own convention.\n // @param _config - configuration in the bytes. can encode arbitrary content.\n function setConfig(uint16 _version, uint16 _chainId, uint256 _configType, bytes calldata _config) external;\n\n // @notice set the send() LayerZero messaging library version to _version\n // @param _version - new messaging library version\n function setSendVersion(uint16 _version) external;\n\n // @notice set the lzReceive() LayerZero messaging library version to _version\n // @param _version - new messaging library version\n function setReceiveVersion(uint16 _version) external;\n\n // @notice Only when the UA needs to resume the message flow in blocking mode and clear the stored payload\n // @param _srcChainId - the chainId of the source chain\n // @param _srcAddress - the contract address of the source contract at the source chain\n function forceResumeReceive(uint16 _srcChainId, bytes calldata _srcAddress) external;\n}\n" + }, + "contracts/interfaces/external/lido/IStETH.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\n/// @title IStETH\n/// @author Angle Labs, Inc.\n/// @notice Interface for the `StETH` contract\n/// @dev This interface only contains functions of the `StETH` which are called by other contracts\n/// of this module\ninterface IStETH {\n function getPooledEthByShares(uint256 _sharesAmount) external view returns (uint256);\n\n event Submitted(address sender, uint256 amount, address referral);\n\n function submit(address) external payable returns (uint256);\n\n function getSharesByPooledEth(uint256 _ethAmount) external view returns (uint256);\n}\n" + }, + "contracts/interfaces/external/lido/IWStETH.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\n/// @title IWStETH\n/// @author Angle Labs, Inc.\n/// @notice Interface for the `WStETH` contract\n/// @dev This interface only contains functions of the `WStETH` which are called by other contracts\n/// of this module\ninterface IWStETH {\n function wrap(uint256 _stETHAmount) external returns (uint256);\n\n function stETH() external view returns (address);\n}\n" + }, + "contracts/interfaces/external/uniswap/IUniswapRouter.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\nstruct ExactInputParams {\n bytes path;\n address recipient;\n uint256 deadline;\n uint256 amountIn;\n uint256 amountOutMinimum;\n}\n\n/// @title Router token swapping functionality\n/// @notice Functions for swapping tokens via Uniswap V3\ninterface IUniswapV3Router {\n /// @notice Swaps `amountIn` of one token for as much as possible of another along the specified path\n /// @param params The parameters necessary for the multi-hop swap, encoded as `ExactInputParams` in calldata\n /// @return amountOut The amount of the received token\n function exactInput(ExactInputParams calldata params) external payable returns (uint256 amountOut);\n}\n\n/// @title Router for price estimation functionality\n/// @notice Functions for getting the price of one token with respect to another using Uniswap V2\n/// @dev This interface is only used for non critical elements of the protocol\ninterface IUniswapV2Router {\n /// @notice Given an input asset amount, returns the maximum output amount of the\n /// other asset (accounting for fees) given reserves.\n /// @param path Addresses of the pools used to get prices\n function getAmountsOut(uint256 amountIn, address[] calldata path) external view returns (uint256[] memory amounts);\n\n function swapExactTokensForTokens(\n uint256 swapAmount,\n uint256 minExpected,\n address[] calldata path,\n address receiver,\n uint256 swapDeadline\n ) external;\n}\n" + }, + "contracts/interfaces/external/uniswap/IUniswapV3Pool.sol": { + "content": "// SPDX-License-Identifier: GPL-2.0-or-later\npragma solidity >=0.5.0;\n\n/// @title Pool state that never changes\n/// @notice These parameters are fixed for a pool forever, i.e., the methods will always return the same values\ninterface IUniswapV3Pool {\n /// @notice The first of the two tokens of the pool, sorted by address\n /// @return The token contract address\n function token0() external view returns (address);\n\n /// @notice The second of the two tokens of the pool, sorted by address\n /// @return The token contract address\n function token1() external view returns (address);\n}\n" + }, + "contracts/interfaces/governance/IVeBoostProxy.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\n/// @title IVeBoostProxy\n/// @author Angle Labs, Inc.\n/// @notice Interface for the `VeBoostProxy` contract\n/// @dev This interface only contains functions of the contract which are called by other contracts\n/// of this module\n/// @dev The `veBoostProxy` contract used by Angle is a full fork of Curve Finance implementation\ninterface IVeBoostProxy {\n /// @notice Reads the adjusted veANGLE balance of an address (adjusted by delegation)\n //solhint-disable-next-line\n function adjusted_balance_of(address) external view returns (uint256);\n}\n" + }, + "contracts/interfaces/IAgToken.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\nimport \"@openzeppelin/contracts-upgradeable/token/ERC20/IERC20Upgradeable.sol\";\n\n/// @title IAgToken\n/// @author Angle Labs, Inc.\n/// @notice Interface for the stablecoins `AgToken` contracts\n/// @dev This interface only contains functions of the `AgToken` contract which are called by other contracts\n/// of this module or of the first module of the Angle Protocol\ninterface IAgToken is IERC20Upgradeable {\n // ======================= Minter Role Only Functions ===========================\n\n /// @notice Lets the `StableMaster` contract or another whitelisted contract mint agTokens\n /// @param account Address to mint to\n /// @param amount Amount to mint\n /// @dev The contracts allowed to issue agTokens are the `StableMaster` contract, `VaultManager` contracts\n /// associated to this stablecoin as well as the flash loan module (if activated) and potentially contracts\n /// whitelisted by governance\n function mint(address account, uint256 amount) external;\n\n /// @notice Burns `amount` tokens from a `burner` address after being asked to by `sender`\n /// @param amount Amount of tokens to burn\n /// @param burner Address to burn from\n /// @param sender Address which requested the burn from `burner`\n /// @dev This method is to be called by a contract with the minter right after being requested\n /// to do so by a `sender` address willing to burn tokens from another `burner` address\n /// @dev The method checks the allowance between the `sender` and the `burner`\n function burnFrom(uint256 amount, address burner, address sender) external;\n\n /// @notice Burns `amount` tokens from a `burner` address\n /// @param amount Amount of tokens to burn\n /// @param burner Address to burn from\n /// @dev This method is to be called by a contract with a minter right on the AgToken after being\n /// requested to do so by an address willing to burn tokens from its address\n function burnSelf(uint256 amount, address burner) external;\n\n // ========================= Treasury Only Functions ===========================\n\n /// @notice Adds a minter in the contract\n /// @param minter Minter address to add\n /// @dev Zero address checks are performed directly in the `Treasury` contract\n function addMinter(address minter) external;\n\n /// @notice Removes a minter from the contract\n /// @param minter Minter address to remove\n /// @dev This function can also be called by a minter wishing to revoke itself\n function removeMinter(address minter) external;\n\n /// @notice Sets a new treasury contract\n /// @param _treasury New treasury address\n function setTreasury(address _treasury) external;\n\n // ========================= External functions ================================\n\n /// @notice Checks whether an address has the right to mint agTokens\n /// @param minter Address for which the minting right should be checked\n /// @return Whether the address has the right to mint agTokens or not\n function isMinter(address minter) external view returns (bool);\n\n /// @notice Get the associated treasury\n function treasury() external view returns (address);\n}\n" + }, + "contracts/interfaces/IAgTokenSideChainMultiBridge.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\nimport \"@openzeppelin/contracts-upgradeable/token/ERC20/extensions/draft-IERC20PermitUpgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/token/ERC20/IERC20Upgradeable.sol\";\n\n/// @title IAgTokenSideChainMultiBridge\n/// @author Angle Labs, Inc.\n/// @notice Interface for the canonical `AgToken` contracts\n/// @dev This interface only contains functions useful for bridge tokens to interact with the canonical token\ninterface IAgTokenSideChainMultiBridge is IERC20PermitUpgradeable, IERC20Upgradeable {\n /// @notice Mints the canonical token from a supported bridge token\n /// @param bridgeToken Bridge token to use to mint\n /// @param amount Amount of bridge tokens to send\n /// @param to Address to which the stablecoin should be sent\n /// @return Amount of the canonical stablecoin actually minted\n /// @dev Some fees may be taken by the protocol depending on the token used and on the address calling\n function swapIn(address bridgeToken, uint256 amount, address to) external returns (uint256);\n\n /// @notice Burns the canonical token in exchange for a bridge token\n /// @param bridgeToken Bridge token required\n /// @param amount Amount of canonical tokens to burn\n /// @param to Address to which the bridge token should be sent\n /// @return Amount of bridge tokens actually sent back\n /// @dev Some fees may be taken by the protocol depending on the token used and on the address calling\n function swapOut(address bridgeToken, uint256 amount, address to) external returns (uint256);\n}\n" + }, + "contracts/interfaces/IAngleRouter.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\n/// @title IAngleRouter\n/// @author Angle Labs, Inc.\n/// @notice Interface for the `AngleRouter` contract\n/// @dev This interface only contains functions of the `AngleRouter01` contract which are called by other contracts\n/// of this module\ninterface IAngleRouter {\n function mint(\n address user,\n uint256 amount,\n uint256 minStableAmount,\n address stablecoin,\n address collateral\n ) external;\n\n function burn(address user, uint256 amount, uint256 minAmountOut, address stablecoin, address collateral) external;\n\n function mapPoolManagers(\n address stableMaster,\n address collateral\n ) external view returns (address poolManager, address perpetualManager, address sanToken, address gauge);\n}\n" + }, + "contracts/interfaces/IAngleRouterSidechain.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\n/// @notice Action types\nenum ActionType {\n transfer,\n wrap,\n wrapNative,\n sweep,\n sweepNative,\n unwrap,\n unwrapNative,\n swapIn,\n swapOut,\n uniswapV3,\n oneInch,\n claimRewards,\n gaugeDeposit,\n borrower\n}\n\n/// @notice Data needed to get permits\nstruct PermitType {\n address token;\n address owner;\n uint256 value;\n uint256 deadline;\n uint8 v;\n bytes32 r;\n bytes32 s;\n}\n\n/// @title IAngleRouterSidechain\n/// @author Angle Labs, Inc.\n/// @notice Interface for the `AngleRouter` contract on other chains\ninterface IAngleRouterSidechain {\n function mixer(PermitType[] memory paramsPermit, ActionType[] memory actions, bytes[] calldata data) external;\n}\n" + }, + "contracts/interfaces/ICoreBorrow.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\n/// @title ICoreBorrow\n/// @author Angle Labs, Inc.\n/// @notice Interface for the `CoreBorrow` contract\n/// @dev This interface only contains functions of the `CoreBorrow` contract which are called by other contracts\n/// of this module\ninterface ICoreBorrow {\n /// @notice Checks if an address corresponds to a treasury of a stablecoin with a flash loan\n /// module initialized on it\n /// @param treasury Address to check\n /// @return Whether the address has the `FLASHLOANER_TREASURY_ROLE` or not\n function isFlashLoanerTreasury(address treasury) external view returns (bool);\n\n /// @notice Checks whether an address is governor of the Angle Protocol or not\n /// @param admin Address to check\n /// @return Whether the address has the `GOVERNOR_ROLE` or not\n function isGovernor(address admin) external view returns (bool);\n\n /// @notice Checks whether an address is governor or a guardian of the Angle Protocol or not\n /// @param admin Address to check\n /// @return Whether the address has the `GUARDIAN_ROLE` or not\n /// @dev Governance should make sure when adding a governor to also give this governor the guardian\n /// role by calling the `addGovernor` function\n function isGovernorOrGuardian(address admin) external view returns (bool);\n}\n" + }, + "contracts/interfaces/IFlashAngle.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\nimport \"./IAgToken.sol\";\nimport \"./ICoreBorrow.sol\";\n\n/// @title IFlashAngle\n/// @author Angle Labs, Inc.\n/// @notice Interface for the `FlashAngle` contract\n/// @dev This interface only contains functions of the contract which are called by other contracts\n/// of this module\ninterface IFlashAngle {\n /// @notice Reference to the `CoreBorrow` contract managing the FlashLoan module\n function core() external view returns (ICoreBorrow);\n\n /// @notice Sends the fees taken from flash loans to the treasury contract associated to the stablecoin\n /// @param stablecoin Stablecoin from which profits should be sent\n /// @return balance Amount of profits sent\n /// @dev This function can only be called by the treasury contract\n function accrueInterestToTreasury(IAgToken stablecoin) external returns (uint256 balance);\n\n /// @notice Adds support for a stablecoin\n /// @param _treasury Treasury associated to the stablecoin to add support for\n /// @dev This function can only be called by the `CoreBorrow` contract\n function addStablecoinSupport(address _treasury) external;\n\n /// @notice Removes support for a stablecoin\n /// @param _treasury Treasury associated to the stablecoin to remove support for\n /// @dev This function can only be called by the `CoreBorrow` contract\n function removeStablecoinSupport(address _treasury) external;\n\n /// @notice Sets a new core contract\n /// @param _core Core contract address to set\n /// @dev This function can only be called by the `CoreBorrow` contract\n function setCore(address _core) external;\n}\n" + }, + "contracts/interfaces/IKeeperRegistry.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\nimport \"@openzeppelin/contracts-upgradeable/token/ERC20/IERC20Upgradeable.sol\";\n\n/// @title IKeeperRegistry\n/// @author Angle Labs, Inc.\ninterface IKeeperRegistry {\n /// @notice Checks whether an address is whitelisted during oracle updates\n /// @param caller Address for which the whitelist should be checked\n /// @return Whether the address is trusted or not\n function isTrusted(address caller) external view returns (bool);\n}\n" + }, + "contracts/interfaces/ILiquidityGauge.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.7;\n\ninterface ILiquidityGauge {\n function deposit(\n uint256 _value,\n address _addr,\n // solhint-disable-next-line\n bool _claim_rewards\n ) external;\n\n function withdraw(\n uint256 _value,\n // solhint-disable-next-line\n bool _claim_rewards\n ) external;\n\n // solhint-disable-next-line\n function claim_rewards(address _addr, address _receiver) external;\n\n // solhint-disable-next-line\n function claimable_reward(address _addr, address _reward_token) external view returns (uint256 amount);\n\n /// @dev Only for testing purposes\n // solhint-disable-next-line\n function deposit_reward_token(address _rewardToken, uint256 _amount) external;\n}\n" + }, + "contracts/interfaces/IOracle.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\nimport \"./ITreasury.sol\";\nimport \"@chainlink/contracts/src/v0.8/interfaces/AggregatorV3Interface.sol\";\n\n/// @title IOracle\n/// @author Angle Labs, Inc.\n/// @notice Interface for the `Oracle` contract\n/// @dev This interface only contains functions of the contract which are called by other contracts\n/// of this module\ninterface IOracle {\n /// @notice Reads the rate from the Chainlink circuit and other data provided\n /// @return quoteAmount The current rate between the in-currency and out-currency in the base\n /// of the out currency\n /// @dev For instance if the out currency is EUR (and hence agEUR), then the base of the returned\n /// value is 10**18\n function read() external view returns (uint256);\n\n /// @notice Changes the treasury contract\n /// @param _treasury Address of the new treasury contract\n /// @dev This function can be called by an approved `VaultManager` contract which can call\n /// this function after being requested to do so by a `treasury` contract\n /// @dev In some situations (like reactor contracts), the `VaultManager` may not directly be linked\n /// to the `oracle` contract and as such we may need governors to be able to call this function as well\n function setTreasury(address _treasury) external;\n\n /// @notice Reference to the `treasury` contract handling this `VaultManager`\n function treasury() external view returns (ITreasury treasury);\n\n /// @notice Array with the list of Chainlink feeds in the order in which they are read\n function circuitChainlink() external view returns (AggregatorV3Interface[] memory);\n}\n" + }, + "contracts/interfaces/ISwapper.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\nimport \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\n\n/// @title ISwapper\n/// @author Angle Labs, Inc.\n/// @notice Interface for Swapper contracts\n/// @dev This interface defines the key functions `Swapper` contracts should have when interacting with\n/// Angle\ninterface ISwapper {\n /// @notice Notifies a contract that an address should be given `outToken` from `inToken`\n /// @param inToken Address of the token received\n /// @param outToken Address of the token to obtain\n /// @param outTokenRecipient Address to which the outToken should be sent\n /// @param outTokenOwed Minimum amount of outToken the `outTokenRecipient` address should have at the end of the call\n /// @param inTokenObtained Amount of collateral obtained by a related address prior\n /// to the call to this function\n /// @param data Extra data needed (to encode Uniswap swaps for instance)\n function swap(\n IERC20 inToken,\n IERC20 outToken,\n address outTokenRecipient,\n uint256 outTokenOwed,\n uint256 inTokenObtained,\n bytes calldata data\n ) external;\n}\n" + }, + "contracts/interfaces/ITreasury.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\nimport \"./IAgToken.sol\";\nimport \"./ICoreBorrow.sol\";\nimport \"./IFlashAngle.sol\";\n\n/// @title ITreasury\n/// @author Angle Labs, Inc.\n/// @notice Interface for the `Treasury` contract\n/// @dev This interface only contains functions of the `Treasury` which are called by other contracts\n/// of this module\ninterface ITreasury {\n /// @notice Stablecoin handled by this `treasury` contract\n function stablecoin() external view returns (IAgToken);\n\n /// @notice Checks whether a given address has the governor role\n /// @param admin Address to check\n /// @return Whether the address has the governor role\n /// @dev Access control is only kept in the `CoreBorrow` contract\n function isGovernor(address admin) external view returns (bool);\n\n /// @notice Checks whether a given address has the guardian or the governor role\n /// @param admin Address to check\n /// @return Whether the address has the guardian or the governor role\n /// @dev Access control is only kept in the `CoreBorrow` contract which means that this function\n /// queries the `CoreBorrow` contract\n function isGovernorOrGuardian(address admin) external view returns (bool);\n\n /// @notice Checks whether a given address has well been initialized in this contract\n /// as a `VaultManager`\n /// @param _vaultManager Address to check\n /// @return Whether the address has been initialized or not\n function isVaultManager(address _vaultManager) external view returns (bool);\n\n /// @notice Sets a new flash loan module for this stablecoin\n /// @param _flashLoanModule Reference to the new flash loan module\n /// @dev This function removes the minting right to the old flash loan module and grants\n /// it to the new module\n function setFlashLoanModule(address _flashLoanModule) external;\n\n /// @notice Gets the vault manager list\n function vaultManagerList(uint256 i) external returns (address);\n}\n" + }, + "contracts/interfaces/IVaultManager.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\nimport \"@openzeppelin/contracts/interfaces/IERC721Metadata.sol\";\nimport \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\nimport \"./ITreasury.sol\";\nimport \"./IOracle.sol\";\n\n// ========================= Key Structs and Enums =============================\n\n/// @notice Parameters associated to a given `VaultManager` contract: these all correspond\n/// to parameters which signification is detailed in the `VaultManagerStorage` file\nstruct VaultParameters {\n uint256 debtCeiling;\n uint64 collateralFactor;\n uint64 targetHealthFactor;\n uint64 interestRate;\n uint64 liquidationSurcharge;\n uint64 maxLiquidationDiscount;\n bool whitelistingActivated;\n uint256 baseBoost;\n}\n\n/// @notice Data stored to track someone's loan (or equivalently called position)\nstruct Vault {\n // Amount of collateral deposited in the vault, in collateral decimals. For example, if the collateral\n // is USDC with 6 decimals, then `collateralAmount` will be in base 10**6\n uint256 collateralAmount;\n // Normalized value of the debt (that is to say of the stablecoins borrowed). It is expressed\n // in the base of Angle stablecoins (i.e. `BASE_TOKENS = 10**18`)\n uint256 normalizedDebt;\n}\n\n/// @notice For a given `vaultID`, this encodes a liquidation opportunity that is to say details about the maximum\n/// amount that could be repaid by liquidating the position\n/// @dev All the values are null in the case of a vault which cannot be liquidated under these conditions\nstruct LiquidationOpportunity {\n // Maximum stablecoin amount that can be repaid upon liquidating the vault\n uint256 maxStablecoinAmountToRepay;\n // Collateral amount given to the person in the case where the maximum amount to repay is given\n uint256 maxCollateralAmountGiven;\n // Threshold value of stablecoin amount to repay: it is ok for a liquidator to repay below threshold,\n // but if this threshold is non null and the liquidator wants to repay more than threshold, it should repay\n // the max stablecoin amount given in this vault\n uint256 thresholdRepayAmount;\n // Discount proposed to the liquidator on the collateral\n uint256 discount;\n // Amount of debt in the vault\n uint256 currentDebt;\n}\n\n/// @notice Data stored during a liquidation process to keep in memory what's due to a liquidator and some\n/// essential data for vaults being liquidated\nstruct LiquidatorData {\n // Current amount of stablecoins the liquidator should give to the contract\n uint256 stablecoinAmountToReceive;\n // Current amount of collateral the contract should give to the liquidator\n uint256 collateralAmountToGive;\n // Bad debt accrued across the liquidation process\n uint256 badDebtFromLiquidation;\n // Oracle value (in stablecoin base) at the time of the liquidation\n uint256 oracleValue;\n // Value of the `interestAccumulator` at the time of the call\n uint256 newInterestAccumulator;\n}\n\n/// @notice Data to track during a series of action the amount to give or receive in stablecoins and collateral\n/// to the caller or associated addresses\nstruct PaymentData {\n // Stablecoin amount the contract should give\n uint256 stablecoinAmountToGive;\n // Stablecoin amount owed to the contract\n uint256 stablecoinAmountToReceive;\n // Collateral amount the contract should give\n uint256 collateralAmountToGive;\n // Collateral amount owed to the contract\n uint256 collateralAmountToReceive;\n}\n\n/// @notice Actions possible when composing calls to the different entry functions proposed\nenum ActionType {\n createVault,\n closeVault,\n addCollateral,\n removeCollateral,\n repayDebt,\n borrow,\n getDebtIn,\n permit\n}\n\n// ========================= Interfaces =============================\n\n/// @title IVaultManagerFunctions\n/// @author Angle Labs, Inc.\n/// @notice Interface for the `VaultManager` contract\n/// @dev This interface only contains functions of the contract which are called by other contracts\n/// of this module (without getters)\ninterface IVaultManagerFunctions {\n /// @notice Accrues interest accumulated across all vaults to the surplus and sends the surplus to the treasury\n /// @return surplusValue Value of the surplus communicated to the `Treasury`\n /// @return badDebtValue Value of the bad debt communicated to the `Treasury`\n /// @dev `surplus` and `badDebt` should be reset to 0 once their current value have been given to the `treasury` contract\n function accrueInterestToTreasury() external returns (uint256 surplusValue, uint256 badDebtValue);\n\n /// @notice Removes debt from a vault after being requested to do so by another `VaultManager` contract\n /// @param vaultID ID of the vault to remove debt from\n /// @param amountStablecoins Amount of stablecoins to remove from the debt: this amount is to be converted to an\n /// internal debt amount\n /// @param senderBorrowFee Borrowing fees from the contract which requested this: this is to make sure that people are not\n /// arbitraging difference in minting fees\n /// @param senderRepayFee Repay fees from the contract which requested this: this is to make sure that people are not arbitraging\n /// differences in repay fees\n /// @dev This function can only be called from a vaultManager registered in the same Treasury\n function getDebtOut(\n uint256 vaultID,\n uint256 amountStablecoins,\n uint256 senderBorrowFee,\n uint256 senderRepayFee\n ) external;\n\n /// @notice Gets the current debt of a vault\n /// @param vaultID ID of the vault to check\n /// @return Debt of the vault\n function getVaultDebt(uint256 vaultID) external view returns (uint256);\n\n /// @notice Gets the total debt across all vaults\n /// @return Total debt across all vaults, taking into account the interest accumulated\n /// over time\n function getTotalDebt() external view returns (uint256);\n\n /// @notice Sets the treasury contract\n /// @param _treasury New treasury contract\n /// @dev All required checks when setting up a treasury contract are performed in the contract\n /// calling this function\n function setTreasury(address _treasury) external;\n\n /// @notice Creates a vault\n /// @param toVault Address for which the va\n /// @return vaultID ID of the vault created\n /// @dev This function just creates the vault without doing any collateral or\n function createVault(address toVault) external returns (uint256);\n\n /// @notice Allows composability between calls to the different entry points of this module. Any user calling\n /// this function can perform any of the allowed actions in the order of their choice\n /// @param actions Set of actions to perform\n /// @param datas Data to be decoded for each action: it can include like the `vaultID` or the `stablecoinAmount` to borrow\n /// @param from Address from which stablecoins will be taken if one action includes burning stablecoins. This address\n /// should either be the `msg.sender` or be approved by the latter\n /// @param to Address to which stablecoins and/or collateral will be sent in case of\n /// @param who Address of the contract to handle in case of repayment of stablecoins from received collateral\n /// @param repayData Data to pass to the repayment contract in case of\n /// @return paymentData Struct containing the accounting changes from the protocol's perspective (like how much of collateral\n /// or how much has been received). Note that the values in the struct are not aggregated and you could have in the output\n /// a positive amount of stablecoins to receive as well as a positive amount of stablecoins to give\n /// @dev This function is optimized to reduce gas cost due to payment from or to the user and that expensive calls\n /// or computations (like `oracleValue`) are done only once\n /// @dev When specifying `vaultID` in `data`, it is important to know that if you specify `vaultID = 0`, it will simply\n /// use the latest `vaultID`. This is the default behavior, and unless you're engaging into some complex protocol actions\n /// it is encouraged to use `vaultID = 0` only when the first action of the batch is `createVault`\n function angle(\n ActionType[] memory actions,\n bytes[] memory datas,\n address from,\n address to,\n address who,\n bytes memory repayData\n ) external returns (PaymentData memory paymentData);\n\n /// @notice This function is a wrapper built on top of the function above. It enables users to interact with the contract\n /// without having to provide `who` and `repayData` parameters\n function angle(\n ActionType[] memory actions,\n bytes[] memory datas,\n address from,\n address to\n ) external returns (PaymentData memory paymentData);\n\n /// @notice Initializes the `VaultManager` contract\n /// @param _treasury Treasury address handling the contract\n /// @param _collateral Collateral supported by this contract\n /// @param _oracle Oracle contract used\n /// @param _symbol Symbol used to define the `VaultManager` name and symbol\n /// @dev The parameters and the oracle are the only elements which could be modified once the\n /// contract has been initialized\n /// @dev For the contract to be fully initialized, governance needs to set the parameters for the liquidation\n /// boost\n function initialize(\n ITreasury _treasury,\n IERC20 _collateral,\n IOracle _oracle,\n VaultParameters calldata params,\n string memory _symbol\n ) external;\n\n /// @notice Minimum amount of debt a vault can have, expressed in `BASE_TOKENS` that is to say the base of the agTokens\n function dust() external view returns (uint256);\n\n /// @notice Pauses external permissionless functions of the contract\n function togglePause() external;\n}\n\n/// @title IVaultManagerStorage\n/// @author Angle Labs, Inc.\n/// @notice Interface for the `VaultManager` contract\n/// @dev This interface contains getters of the contract's public variables used by other contracts\n/// of this module\ninterface IVaultManagerStorage {\n /// @notice Encodes the maximum ratio stablecoin/collateral a vault can have before being liquidated. It's what\n /// determines the minimum collateral ratio of a position\n function collateralFactor() external view returns (uint64);\n\n /// @notice Stablecoin handled by this contract. Another `VaultManager` contract could have\n /// the same rights as this `VaultManager` on the stablecoin contract\n function stablecoin() external view returns (IAgToken);\n\n /// @notice Reference to the `treasury` contract handling this `VaultManager`\n function treasury() external view returns (ITreasury);\n\n /// @notice Oracle contract to get access to the price of the collateral with respect to the stablecoin\n function oracle() external view returns (IOracle);\n\n /// @notice The `interestAccumulator` variable keeps track of the interest that should accrue to the protocol.\n /// The stored value is not necessarily the true value: this one is recomputed every time an action takes place\n /// within the protocol. It is in base `BASE_INTEREST`\n function interestAccumulator() external view returns (uint256);\n\n /// @notice Reference to the collateral handled by this `VaultManager`\n function collateral() external view returns (IERC20);\n\n /// @notice Total normalized amount of stablecoins borrowed, not taking into account the potential bad debt accumulated\n /// This value is expressed in the base of Angle stablecoins (`BASE_TOKENS = 10**18`)\n function totalNormalizedDebt() external view returns (uint256);\n\n /// @notice Maximum amount of stablecoins that can be issued with this contract. It is expressed in `BASE_TOKENS`\n function debtCeiling() external view returns (uint256);\n\n /// @notice Maps a `vaultID` to its data (namely collateral amount and normalized debt)\n function vaultData(uint256 vaultID) external view returns (uint256 collateralAmount, uint256 normalizedDebt);\n\n /// @notice ID of the last vault created. The `vaultIDCount` variables serves as a counter to generate a unique\n /// `vaultID` for each vault: it is like `tokenID` in basic ERC721 contracts\n function vaultIDCount() external view returns (uint256);\n}\n\n/// @title IVaultManager\n/// @author Angle Labs, Inc.\n/// @notice Interface for the `VaultManager` contract\ninterface IVaultManager is IVaultManagerFunctions, IVaultManagerStorage, IERC721Metadata {\n function isApprovedOrOwner(address spender, uint256 vaultID) external view returns (bool);\n}\n\n/// @title IVaultManagerListing\n/// @author Angle Labs, Inc.\n/// @notice Interface for the `VaultManagerListing` contract\ninterface IVaultManagerListing is IVaultManager {\n /// @notice Get the collateral owned by `user` in the contract\n /// @dev This function effectively sums the collateral amounts of all the vaults owned by `user`\n function getUserCollateral(address user) external view returns (uint256);\n}\n" + }, + "contracts/keeperMulticall/KeeperMulticall.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\nimport \"@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/access/AccessControlUpgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol\";\nimport \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\nimport \"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\";\nimport \"./RevertReasonParser.sol\";\n\n/// @title KeeperMulticall\n/// @notice Allows an authorized caller (keeper) to execute multiple actions in a single tx.\n/// @author Angle Labs, Inc.\n/// @dev Special features:\n/// - ability to pay the miner (for private Flashbots transactions)\n/// - swap tokens through 1inch\n/// @dev Tx need to be encoded as an array of Action. The flag `isDelegateCall` is used for calling functions within this same contract\ncontract KeeperMulticall is Initializable, AccessControlUpgradeable {\n using SafeERC20 for IERC20;\n\n bytes32 public constant KEEPER_ROLE = keccak256(\"KEEPER_ROLE\");\n\n //solhint-disable-next-line\n address private constant _oneInch = 0x1111111254fb6c44bAC0beD2854e76F90643097d;\n\n struct Action {\n address target;\n bytes data;\n bool isDelegateCall;\n }\n\n event LogAction(address indexed target, bytes data);\n event SentToMiner(uint256 indexed value);\n event Recovered(address indexed tokenAddress, address indexed to, uint256 amount);\n\n error AmountOutTooLow(uint256 amount, uint256 min);\n error BalanceTooLow();\n error FlashbotsErrorPayingMiner(uint256 value);\n error IncompatibleLengths();\n error RevertBytes();\n error WrongAmount();\n error ZeroAddress();\n\n constructor() initializer {}\n\n function initialize(address keeper) external initializer {\n __AccessControl_init();\n\n _setupRole(KEEPER_ROLE, keeper);\n _setRoleAdmin(KEEPER_ROLE, KEEPER_ROLE);\n }\n\n /// @notice Allows an authorized keeper to execute multiple actions in a single step\n /// @param actions Actions to be executed\n /// @param percentageToMiner Percentage to pay to miner expressed in bps (10000)\n /// @dev This is the main entry point for actions to be executed. The `isDelegateCall` flag is used for calling function inside this `KeeperMulticall` contract,\n /// if we call other contracts, the flag should be false\n function executeActions(\n Action[] memory actions,\n uint256 percentageToMiner\n ) external payable onlyRole(KEEPER_ROLE) returns (bytes[] memory) {\n uint256 numberOfActions = actions.length;\n if (numberOfActions == 0) revert IncompatibleLengths();\n\n bytes[] memory returnValues = new bytes[](numberOfActions + 1);\n\n uint256 balanceBefore = address(this).balance;\n\n for (uint256 i; i < numberOfActions; ++i) {\n returnValues[i] = _executeAction(actions[i]);\n }\n\n if (percentageToMiner != 0) {\n if (percentageToMiner >= 10000) revert WrongAmount();\n uint256 balanceAfter = address(this).balance;\n if (balanceAfter > balanceBefore) {\n uint256 amountToMiner = ((balanceAfter - balanceBefore) * percentageToMiner) / 10000;\n returnValues[numberOfActions] = payFlashbots(amountToMiner);\n }\n }\n\n return returnValues;\n }\n\n /// @notice Gets the action address and data and executes it\n /// @param action Action to be executed\n function _executeAction(Action memory action) internal returns (bytes memory) {\n bool success;\n bytes memory response;\n\n if (action.isDelegateCall) {\n //solhint-disable-next-line\n (success, response) = action.target.delegatecall(action.data);\n } else {\n //solhint-disable-next-line\n (success, response) = action.target.call(action.data);\n }\n\n require(success, RevertReasonParser.parse(response, \"action reverted: \"));\n emit LogAction(action.target, action.data);\n return response;\n }\n\n /// @notice Ability to pay miner directly. Used for Flashbots to execute private transactions\n /// @param value Value to be sent\n function payFlashbots(uint256 value) public payable onlyRole(KEEPER_ROLE) returns (bytes memory) {\n //solhint-disable-next-line\n (bool success, bytes memory response) = block.coinbase.call{ value: value }(\"\");\n if (!success) revert FlashbotsErrorPayingMiner(value);\n emit SentToMiner(value);\n return response;\n }\n\n /// @notice Used to check the balances the token holds for each token. If we don't have enough of a token, we revert the tx\n /// @param tokens Array of tokens to check\n /// @param minBalances Array of balances for each token\n function finalBalanceCheck(IERC20[] memory tokens, uint256[] memory minBalances) external view returns (bool) {\n uint256 tokensLength = tokens.length;\n if (tokensLength == 0 || tokensLength != minBalances.length) revert IncompatibleLengths();\n\n for (uint256 i; i < tokensLength; ++i) {\n if (address(tokens[i]) == 0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE) {\n if (address(this).balance < minBalances[i]) revert BalanceTooLow();\n } else {\n if (tokens[i].balanceOf(address(this)) < minBalances[i]) revert BalanceTooLow();\n }\n }\n\n return true;\n }\n\n /// @notice Swap token to another through 1Inch\n /// @param minAmountOut Minimum amount of `out` token to receive for the swap to happen\n /// @param payload Bytes needed for 1Inch API\n function swapToken(uint256 minAmountOut, bytes memory payload) external onlyRole(KEEPER_ROLE) {\n //solhint-disable-next-line\n (bool success, bytes memory result) = _oneInch.call(payload);\n if (!success) _revertBytes(result);\n\n uint256 amountOut = abi.decode(result, (uint256));\n if (amountOut < minAmountOut) revert AmountOutTooLow(amountOut, minAmountOut);\n }\n\n /// @notice Copied from 1Inch contract, used to revert if there is an error\n function _revertBytes(bytes memory errMsg) internal pure {\n if (errMsg.length != 0) {\n //solhint-disable-next-line\n assembly {\n revert(add(32, errMsg), mload(errMsg))\n }\n }\n revert RevertBytes();\n }\n\n /// @notice Approve a `spender` for `token`\n /// @param token Address of the token to approve\n /// @param spender Address of the spender to approve\n /// @param amount Amount to approve\n function approve(IERC20 token, address spender, uint256 amount) external onlyRole(KEEPER_ROLE) {\n uint256 currentAllowance = token.allowance(address(this), spender);\n if (currentAllowance < amount) {\n token.safeIncreaseAllowance(spender, amount - currentAllowance);\n } else if (currentAllowance > amount) {\n token.safeDecreaseAllowance(spender, currentAllowance - amount);\n }\n }\n\n receive() external payable {}\n\n /// @notice Withdraw stuck funds\n /// @param token Address of the token to recover\n /// @param receiver Address where to send the tokens\n /// @param amount Amount to recover\n function withdrawStuckFunds(address token, address receiver, uint256 amount) external onlyRole(KEEPER_ROLE) {\n if (receiver == address(0)) revert ZeroAddress();\n if (token == 0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE) {\n payable(receiver).transfer(amount);\n } else {\n IERC20(token).safeTransfer(receiver, amount);\n }\n\n emit Recovered(token, receiver, amount);\n }\n}\n" + }, + "contracts/keeperMulticall/MulticallWithFailure.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.12;\n\n/// @title MultiCallWithFailure\n/// @author Angle Labs, Inc.\n/// @notice Multicall contract allowing subcalls to fail without reverting the entire call\ncontract MultiCallWithFailure {\n error SubcallFailed();\n\n struct Call {\n address target;\n bytes data;\n bool canFail;\n }\n\n function multiCall(Call[] memory calls) external view returns (bytes[] memory) {\n bytes[] memory results = new bytes[](calls.length);\n\n for (uint256 i; i < calls.length; ++i) {\n (bool success, bytes memory result) = calls[i].target.staticcall(calls[i].data);\n if (!calls[i].canFail) {\n if (!success) {\n revert SubcallFailed();\n }\n }\n results[i] = result;\n }\n\n return results;\n }\n}\n" + }, + "contracts/keeperMulticall/RevertReasonParser.sol": { + "content": "// SPDX-License-Identifier: GNU-3\n\npragma solidity ^0.8.12;\n\n/// @title RevertReasonParser\n/// @author 1Inch team, taken from:\n/// - https://docs.1inch.io/docs/limit-order-protocol/smart-contract/libraries/RevertReasonParser/\n/// - https://etherscan.io/address/0x1111111254fb6c44bAC0beD2854e76F90643097d#code\nlibrary RevertReasonParser {\n bytes4 private constant _PANIC_SELECTOR = bytes4(keccak256(\"Panic(uint256)\"));\n bytes4 private constant _ERROR_SELECTOR = bytes4(keccak256(\"Error(string)\"));\n\n function parse(bytes memory data, string memory prefix) internal pure returns (string memory) {\n if (data.length >= 4) {\n bytes4 selector;\n //solhint-disable-next-line\n assembly {\n selector := mload(add(data, 0x20))\n }\n\n // 68 = 4-byte selector + 32 bytes offset + 32 bytes length\n if (selector == _ERROR_SELECTOR && data.length >= 68) {\n uint256 offset;\n bytes memory reason;\n // solhint-disable no-inline-assembly\n assembly {\n // 36 = 32 bytes data length + 4-byte selector\n offset := mload(add(data, 36))\n reason := add(data, add(36, offset))\n }\n /*\n revert reason is padded up to 32 bytes with ABI encoder: Error(string)\n also sometimes there is extra 32 bytes of zeros padded in the end:\n https://github.com/ethereum/solidity/issues/10170\n because of that we can't check for equality and instead check\n that offset + string length + extra 36 bytes is less than overall data length\n */\n require(data.length >= 36 + offset + reason.length, \"Invalid revert reason\");\n return string(abi.encodePacked(prefix, \"Error(\", reason, \")\"));\n }\n // 36 = 4-byte selector + 32 bytes integer\n else if (selector == _PANIC_SELECTOR && data.length == 36) {\n uint256 code;\n // solhint-disable no-inline-assembly\n assembly {\n // 36 = 32 bytes data length + 4-byte selector\n code := mload(add(data, 36))\n }\n return string(abi.encodePacked(prefix, \"Panic(\", _toHex(code), \")\"));\n }\n }\n\n return string(abi.encodePacked(prefix, \"Unknown(\", _toHex(data), \")\"));\n }\n\n function _toHex(uint256 value) private pure returns (string memory) {\n return _toHex(abi.encodePacked(value));\n }\n\n function _toHex(bytes memory data) private pure returns (string memory) {\n bytes16 alphabet = 0x30313233343536373839616263646566;\n bytes memory str = new bytes(2 + data.length * 2);\n str[0] = \"0\";\n str[1] = \"x\";\n for (uint256 i; i < data.length; ++i) {\n str[2 * i + 2] = alphabet[uint8(data[i] >> 4)];\n str[2 * i + 3] = alphabet[uint8(data[i] & 0x0f)];\n }\n return string(str);\n }\n}\n" + }, + "contracts/mock/Mock1Inch.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.12;\n\nimport \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\nimport \"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\";\n\ncontract Mock1Inch {\n using SafeERC20 for IERC20;\n\n function swap(address tokenIn, uint256 amountIn, address to, address tokenOut, uint256 amountOut) external {\n IERC20(tokenIn).safeTransferFrom(msg.sender, to, amountIn);\n if (tokenOut == 0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE) {\n //solhint-disable-next-line\n (bool sent, bytes memory data) = msg.sender.call{ value: amountOut }(\"\");\n data;\n require(sent, \"Failed to send Ether\");\n } else {\n IERC20(tokenOut).safeTransferFrom(to, msg.sender, amountOut);\n }\n }\n\n receive() external payable {}\n}\n" + }, + "contracts/mock/MockAnything.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.12;\n\ncontract MockAnything {\n uint256 public stateVar = 1;\n\n error CustomError();\n error CustomErrorWithValue(uint256);\n\n function fail(uint256 value) external view returns (uint256) {\n stateVar;\n if (value < 10) {\n revert CustomError();\n }\n if (value < 20) {\n revert CustomErrorWithValue(value);\n }\n return value + 1;\n }\n\n function modifyState(uint256 value) external {\n stateVar = value;\n }\n}\n" + }, + "contracts/mock/MockChainlinkOracle.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.7;\n\ninterface MockAggregatorV3Interface {\n function decimals() external view returns (uint8);\n\n function description() external view returns (string memory);\n\n function version() external view returns (uint256);\n\n function getRoundData(\n uint80 _roundId\n )\n external\n view\n returns (uint80 roundId, int256 answer, uint256 startedAt, uint256 updatedAt, uint80 answeredInRound);\n\n function latestRoundData()\n external\n view\n returns (uint80 roundId, int256 answer, uint256 startedAt, uint256 updatedAt, uint80 answeredInRound);\n}\n\ncontract MockChainlinkOracle is MockAggregatorV3Interface {\n uint80 public roundId = 0;\n uint8 public keyDecimals = 0;\n\n struct Entry {\n uint80 roundId;\n int256 answer;\n uint256 startedAt;\n uint256 updatedAt;\n uint80 answeredInRound;\n }\n\n mapping(uint256 => Entry) public entries;\n\n bool public latestRoundDataShouldRevert;\n\n string public desc;\n\n constructor() {}\n\n // Mock setup function\n function setLatestAnswer(int256 answer, uint256 timestamp) external {\n roundId++;\n entries[roundId] = Entry({\n roundId: roundId,\n answer: answer,\n startedAt: timestamp,\n updatedAt: timestamp,\n answeredInRound: roundId\n });\n }\n\n function setLatestAnswerWithRound(int256 answer, uint256 timestamp, uint80 _roundId) external {\n roundId = _roundId;\n entries[roundId] = Entry({\n roundId: roundId,\n answer: answer,\n startedAt: timestamp,\n updatedAt: timestamp,\n answeredInRound: roundId\n });\n }\n\n function setLatestAnswerRevert(int256 answer, uint256 timestamp) external {\n roundId++;\n entries[roundId] = Entry({\n roundId: roundId,\n answer: answer,\n startedAt: timestamp,\n updatedAt: timestamp,\n answeredInRound: roundId - 1\n });\n }\n\n function setLatestRoundDataShouldRevert(bool _shouldRevert) external {\n latestRoundDataShouldRevert = _shouldRevert;\n }\n\n function setDecimals(uint8 _decimals) external {\n keyDecimals = _decimals;\n }\n\n function setDescritpion(string memory _desc) external {\n desc = _desc;\n }\n\n function description() external view override returns (string memory) {\n return desc;\n }\n\n function version() external view override returns (uint256) {\n roundId;\n return 0;\n }\n\n function latestRoundData() external view override returns (uint80, int256, uint256, uint256, uint80) {\n if (latestRoundDataShouldRevert) {\n revert(\"latestRoundData reverted\");\n }\n return getRoundData(uint80(roundId));\n }\n\n function decimals() external view override returns (uint8) {\n return keyDecimals;\n }\n\n function getRoundData(uint80 _roundId) public view override returns (uint80, int256, uint256, uint256, uint80) {\n Entry memory entry = entries[_roundId];\n // Emulate a Chainlink aggregator\n require(entry.updatedAt > 0, \"No data present\");\n return (entry.roundId, entry.answer, entry.startedAt, entry.updatedAt, entry.answeredInRound);\n }\n}\n" + }, + "contracts/mock/MockCoreBorrow.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\nimport \"../interfaces/ICoreBorrow.sol\";\nimport \"../interfaces/IFlashAngle.sol\";\nimport \"../interfaces/ITreasury.sol\";\n\ncontract MockCoreBorrow is ICoreBorrow {\n mapping(address => bool) public flashLoaners;\n mapping(address => bool) public governors;\n mapping(address => bool) public guardians;\n\n function isFlashLoanerTreasury(address treasury) external view override returns (bool) {\n return flashLoaners[treasury];\n }\n\n function isGovernor(address admin) external view override returns (bool) {\n return governors[admin];\n }\n\n function isGovernorOrGuardian(address admin) external view override returns (bool) {\n return governors[admin] || guardians[admin];\n }\n\n function toggleGovernor(address admin) external {\n governors[admin] = !governors[admin];\n }\n\n function toggleGuardian(address admin) external {\n guardians[admin] = !guardians[admin];\n }\n\n function toggleFlashLoaners(address admin) external {\n flashLoaners[admin] = !flashLoaners[admin];\n }\n\n function addStablecoinSupport(IFlashAngle flashAngle, address _treasury) external {\n flashAngle.addStablecoinSupport(_treasury);\n }\n\n function removeStablecoinSupport(IFlashAngle flashAngle, address _treasury) external {\n flashAngle.removeStablecoinSupport(_treasury);\n }\n\n function setCore(IFlashAngle flashAngle, address _core) external {\n flashAngle.setCore(_core);\n }\n\n function setFlashLoanModule(ITreasury _treasury, address _flashLoanModule) external {\n _treasury.setFlashLoanModule(_flashLoanModule);\n }\n}\n" + }, + "contracts/mock/MockERC1271.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.12;\n\nimport \"../interfaces/external/IERC1271.sol\";\n\ncontract MockERC1271 is IERC1271 {\n uint256 public mode = 0;\n\n function setMode(uint256 _mode) public {\n mode = _mode;\n }\n\n /// @notice Returns whether the provided signature is valid for the provided data\n /// @dev MUST return the bytes4 magic value 0x1626ba7e when function passes.\n /// MUST NOT modify state (using STATICCALL for solc < 0.5, view modifier for solc > 0.5).\n /// MUST allow external calls.\n /// @return magicValue The bytes4 magic value 0x1626ba7e\n function isValidSignature(bytes32, bytes memory) external view returns (bytes4 magicValue) {\n if (mode == 1) magicValue = 0x1626ba7e;\n }\n}\n" + }, + "contracts/mock/MockERC721Receiver.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (token/ERC721/utils/ERC721Holder.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Implementation of the {IERC721Receiver} interface.\n *\n * Accepts all token transfers.\n * Make sure the contract is able to use its token with {IERC721-safeTransferFrom}, {IERC721-approve} or {IERC721-setApprovalForAll}.\n */\ncontract MockERC721Receiver {\n uint256 public mode = 0;\n\n function setMode(uint256 _mode) public {\n mode = _mode;\n }\n\n function onERC721Received(address, address, uint256, bytes memory) public view returns (bytes4) {\n require(mode != 1, \"0x1111111\");\n if (mode == 2) return this.setMode.selector;\n return this.onERC721Received.selector;\n }\n}\n" + }, + "contracts/mock/MockEulerPool.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\nimport \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\n\ncontract MockEulerPool {\n IERC20 public collateral;\n uint256 public poolSize;\n //solhint-disable-next-line\n uint256 public MAX_SANE_AMOUNT;\n\n mapping(address => uint256) public users;\n uint256 public interestRateAccumulator;\n\n constructor(IERC20 collateral_, uint256 poolSize_) {\n collateral = collateral_;\n poolSize = poolSize_;\n interestRateAccumulator = 10 ** 18;\n MAX_SANE_AMOUNT = type(uint112).max;\n }\n\n function setPoolSize(uint256 poolSize_) external {\n uint256 balance = collateral.balanceOf(address(this));\n poolSize = poolSize_;\n if (balance > poolSize_) collateral.transfer(msg.sender, balance - poolSize_);\n if (balance < poolSize_) collateral.transferFrom(msg.sender, address(this), poolSize_ - balance);\n }\n\n function setInterestRateAccumulator(uint256 interestRateAccumulator_) external {\n interestRateAccumulator = interestRateAccumulator_;\n }\n\n //solhint-disable-next-line\n function setMAXSANEAMOUNT(uint256 MAX_SANE_AMOUNT_) external {\n MAX_SANE_AMOUNT = MAX_SANE_AMOUNT_;\n }\n\n function balanceOfUnderlying(address account) external view returns (uint256) {\n return (users[account] * interestRateAccumulator) / 10 ** 18;\n }\n\n function deposit(uint256, uint256 amount) external {\n users[msg.sender] += (amount * 10 ** 18) / interestRateAccumulator;\n poolSize += amount;\n collateral.transferFrom(msg.sender, address(this), amount);\n }\n\n function withdraw(uint256, uint256 amount) external {\n if (amount == type(uint256).max) amount = (users[msg.sender] * interestRateAccumulator) / 10 ** 18;\n\n require(amount <= poolSize, \"4\");\n users[msg.sender] -= (amount * 10 ** 18) / interestRateAccumulator;\n collateral.transfer(msg.sender, amount);\n }\n}\n" + }, + "contracts/mock/MockFlashLoanModule.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\nimport \"../interfaces/IFlashAngle.sol\";\nimport \"../interfaces/ICoreBorrow.sol\";\n\ncontract MockFlashLoanModule is IFlashAngle {\n ICoreBorrow public override core;\n mapping(address => bool) public stablecoinsSupported;\n mapping(IAgToken => uint256) public interestAccrued;\n uint256 public surplusValue;\n\n constructor(ICoreBorrow _core) {\n core = _core;\n }\n\n function accrueInterestToTreasury(IAgToken stablecoin) external override returns (uint256 balance) {\n balance = surplusValue;\n interestAccrued[stablecoin] += balance;\n }\n\n function addStablecoinSupport(address _treasury) external override {\n stablecoinsSupported[_treasury] = true;\n }\n\n function removeStablecoinSupport(address _treasury) external override {\n stablecoinsSupported[_treasury] = false;\n }\n\n function setCore(address _core) external override {\n core = ICoreBorrow(_core);\n }\n\n function setSurplusValue(uint256 _surplusValue) external {\n surplusValue = _surplusValue;\n }\n}\n" + }, + "contracts/mock/MockFlashLoanReceiver.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.7;\n\nimport \"@openzeppelin/contracts/token/ERC20/ERC20.sol\";\n\nimport \"@openzeppelin/contracts/interfaces/IERC3156FlashBorrower.sol\";\n\nimport \"@openzeppelin/contracts/interfaces/IERC3156FlashLender.sol\";\n\ncontract MockFlashLoanReceiver is IERC3156FlashBorrower {\n bytes32 public constant CALLBACK_SUCCESS = keccak256(\"ERC3156FlashBorrower.onFlashLoan\");\n\n constructor() {}\n\n function onFlashLoan(\n address,\n address token,\n uint256 amount,\n uint256 fee,\n bytes calldata data\n ) external override returns (bytes32) {\n IERC20(token).approve(msg.sender, amount + fee);\n if (amount >= 10 ** 21) return keccak256(\"error\");\n if (amount == 2 * 10 ** 18) {\n IERC3156FlashLender(msg.sender).flashLoan(IERC3156FlashBorrower(address(this)), token, amount, data);\n return keccak256(\"reentrant\");\n } else return CALLBACK_SUCCESS;\n }\n}\n" + }, + "contracts/mock/MockInterestRateComputer.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\ncontract MockInterestRateComputer {\n uint256 public interestRate;\n uint256 public interestAccumulator;\n uint256 public immutable baseInterest;\n uint256 public immutable halfBase;\n\n uint256 public constant WEEK = 7 * 86400;\n\n constructor(uint256 _baseInterest, uint256 _interestRate) {\n interestAccumulator = _baseInterest;\n baseInterest = _baseInterest;\n halfBase = _baseInterest / 2;\n interestRate = _interestRate;\n }\n\n function _calculateAngle(uint256 exp, uint256 _interestAccumulator) internal view returns (uint256) {\n uint256 ratePerSecond = interestRate;\n if (exp == 0 || ratePerSecond == 0) return _interestAccumulator;\n uint256 expMinusOne = exp - 1;\n uint256 expMinusTwo = exp > 2 ? exp - 2 : 0;\n uint256 basePowerTwo = (ratePerSecond * ratePerSecond) / baseInterest;\n uint256 basePowerThree = (basePowerTwo * ratePerSecond) / baseInterest;\n uint256 secondTerm = (exp * expMinusOne * basePowerTwo) / 2;\n uint256 thirdTerm = (exp * expMinusOne * expMinusTwo * basePowerThree) / 6;\n return (_interestAccumulator * (baseInterest + ratePerSecond * exp + secondTerm + thirdTerm)) / baseInterest;\n }\n\n function _calculateAave(uint256 exp, uint256 _interestAccumulator) internal view returns (uint256) {\n uint256 ratePerSecond = interestRate;\n if (exp == 0 || ratePerSecond == 0) return _interestAccumulator;\n uint256 expMinusOne = exp - 1;\n uint256 expMinusTwo = exp > 2 ? exp - 2 : 0;\n uint256 basePowerTwo = (ratePerSecond * ratePerSecond + halfBase) / baseInterest;\n uint256 basePowerThree = (basePowerTwo * ratePerSecond + halfBase) / baseInterest;\n uint256 secondTerm = (exp * expMinusOne * basePowerTwo) / 2;\n uint256 thirdTerm = (exp * expMinusOne * expMinusTwo * basePowerThree) / 6;\n return (_interestAccumulator * (baseInterest + ratePerSecond * exp + secondTerm + thirdTerm)) / baseInterest;\n }\n\n function _calculateCompound(uint256 exp, uint256 _interestAccumulator) internal view returns (uint256) {\n return _interestAccumulator * (baseInterest + interestRate * exp);\n }\n\n function _rpow(uint256 x, uint256 n, uint256 base) internal pure returns (uint256 z) {\n //solhint-disable-next-line\n assembly {\n switch x\n case 0 {\n switch n\n case 0 {\n z := base\n }\n default {\n z := 0\n }\n }\n default {\n switch mod(n, 2)\n case 0 {\n z := base\n }\n default {\n z := x\n }\n let half := div(base, 2) // for rounding.\n for {\n n := div(n, 2)\n } n {\n n := div(n, 2)\n } {\n let xx := mul(x, x)\n if iszero(eq(div(xx, x), x)) {\n revert(0, 0)\n }\n let xxRound := add(xx, half)\n if lt(xxRound, xx) {\n revert(0, 0)\n }\n x := div(xxRound, base)\n if mod(n, 2) {\n let zx := mul(z, x)\n if and(iszero(iszero(x)), iszero(eq(div(zx, x), z))) {\n revert(0, 0)\n }\n let zxRound := add(zx, half)\n if lt(zxRound, zx) {\n revert(0, 0)\n }\n z := div(zxRound, base)\n }\n }\n }\n }\n }\n\n function _calculateMaker(uint256 delta, uint256 _interestAccumulator) internal view returns (uint256) {\n return (_rpow(baseInterest + interestRate, delta, baseInterest) * _interestAccumulator) / baseInterest;\n }\n\n function calculateAngle(uint256 delta) external view returns (uint256) {\n return _calculateAngle(delta, interestAccumulator);\n }\n\n function calculateAave(uint256 delta) external view returns (uint256) {\n return _calculateAave(delta, interestAccumulator);\n }\n\n function calculateMaker(uint256 delta) external view returns (uint256) {\n return _calculateMaker(delta, interestAccumulator);\n }\n\n function calculateAngle1Year() external view returns (uint256) {\n uint256 _interestAccumulator = interestAccumulator;\n for (uint256 i; i < 52; ++i) {\n _interestAccumulator = _calculateAngle(WEEK, _interestAccumulator);\n }\n return _interestAccumulator;\n }\n\n function calculateAave1Year() external view returns (uint256) {\n uint256 _interestAccumulator = interestAccumulator;\n for (uint256 i; i < 52; ++i) {\n _interestAccumulator = _calculateAave(WEEK, _interestAccumulator);\n }\n return _interestAccumulator;\n }\n\n function calculateMaker1Year() external view returns (uint256) {\n uint256 _interestAccumulator = interestAccumulator;\n for (uint256 i; i < 52; ++i) {\n _interestAccumulator = _calculateMaker(WEEK, _interestAccumulator);\n }\n return _interestAccumulator;\n }\n\n function calculateAngle1YearDirect() external view returns (uint256) {\n uint256 _interestAccumulator = interestAccumulator;\n _interestAccumulator = _calculateAngle(52 * WEEK, _interestAccumulator);\n\n return _interestAccumulator;\n }\n\n function calculateAave1YearDirect() external view returns (uint256) {\n uint256 _interestAccumulator = interestAccumulator;\n _interestAccumulator = _calculateAave(52 * WEEK, _interestAccumulator);\n\n return _interestAccumulator;\n }\n\n function calculateMaker1YearDirect() external view returns (uint256) {\n uint256 _interestAccumulator = interestAccumulator;\n _interestAccumulator = _calculateMaker(52 * WEEK, _interestAccumulator);\n\n return _interestAccumulator;\n }\n\n function calculateCompound1YearDirect() external view returns (uint256) {\n uint256 _interestAccumulator = interestAccumulator;\n _interestAccumulator = _calculateCompound(52 * WEEK, _interestAccumulator);\n\n return _interestAccumulator;\n }\n}\n" + }, + "contracts/mock/MockKeeperMulticall.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.12;\n\nimport \"@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/access/AccessControlUpgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol\";\nimport \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\nimport \"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\";\n\ncontract MockKeeperMulticall is Initializable, AccessControlUpgradeable {\n using SafeERC20 for IERC20;\n\n bytes32 public constant KEEPER_ROLE = keccak256(\"KEEPER_ROLE\");\n\n //solhint-disable-next-line\n address private constant _oneInch = 0x1111111254fb6c44bAC0beD2854e76F90643097d;\n\n struct Action {\n address target;\n bytes data;\n bool isDelegateCall;\n }\n\n event LogAction(address indexed target, bytes data);\n event SentToMiner(uint256 indexed value);\n event Recovered(address indexed tokenAddress, address indexed to, uint256 amount);\n\n error AmountOutTooLow(uint256 amount, uint256 min);\n error BalanceTooLow();\n error FlashbotsErrorPayingMiner(uint256 value);\n error IncompatibleLengths();\n error RevertBytes();\n error ZeroAddress();\n\n constructor() initializer {}\n\n function initialize(address keeper) public initializer {\n __AccessControl_init();\n\n _setupRole(KEEPER_ROLE, keeper);\n _setRoleAdmin(KEEPER_ROLE, KEEPER_ROLE);\n }\n}\n\ncontract MockKeeperMulticall2 {\n uint256 public varTest = 1;\n\n bytes32 public constant KEEPER_ROLE = keccak256(\"KEEPER_ROLE\");\n\n //solhint-disable-next-line\n address private constant _oneInch = 0x1111111254fb6c44bAC0beD2854e76F90643097d;\n\n struct Action {\n address target;\n bytes data;\n bool isDelegateCall;\n }\n\n event LogAction(address indexed target, bytes data);\n event SentToMiner(uint256 indexed value);\n event Recovered(address indexed tokenAddress, address indexed to, uint256 amount);\n\n error AmountOutTooLow(uint256 amount, uint256 min);\n error BalanceTooLow();\n error FlashbotsErrorPayingMiner(uint256 value);\n error IncompatibleLengths();\n error RevertBytes();\n error ZeroAddress();\n\n function functionTest() external pure returns (bool) {\n return true;\n }\n}\n" + }, + "contracts/mock/MockLayerZero.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\ninterface ILzApp {\n function lzReceive(uint16 _srcChainId, bytes memory _srcAddress, uint64 _nonce, bytes memory _payload) external;\n}\n\ncontract MockLayerZero {\n mapping(uint16 => uint256) public counters;\n uint256 public config;\n mapping(uint16 => uint64) public outboundNonce;\n uint256 public resumeReceived;\n uint256 public sendVersion;\n uint256 public receiveVersion;\n\n /// @notice Initiate with a fixe change rate\n constructor() {}\n\n function send(\n uint16 _dstChainId,\n bytes calldata,\n bytes calldata,\n address,\n address,\n bytes calldata\n ) external payable {\n counters[_dstChainId] += 1;\n }\n\n function getOutboundNonce(uint16 _dstChainId, address) external view returns (uint64) {\n return outboundNonce[_dstChainId];\n }\n\n function setOutBoundNonce(uint16 _from, uint64 value) external {\n outboundNonce[_from] = value;\n }\n\n function lzReceive(\n address lzApp,\n uint16 _srcChainId,\n bytes memory _srcAddress,\n uint64 _nonce,\n bytes memory _payload\n ) public {\n ILzApp(lzApp).lzReceive(_srcChainId, _srcAddress, _nonce, _payload);\n }\n\n function estimateFees(\n uint16,\n address,\n bytes calldata,\n bool,\n bytes calldata\n ) external pure returns (uint256 nativeFee, uint256 zroFee) {\n return (123, 456);\n }\n\n function setConfig(uint16, uint16, uint256 _configType, bytes calldata) external {\n config = _configType;\n }\n\n function getConfig(uint16, uint16, address, uint256) external view returns (bytes memory) {\n return abi.encodePacked(config);\n }\n\n function setSendVersion(uint16 _version) external {\n sendVersion = _version;\n }\n\n function setReceiveVersion(uint16 _version) external {\n receiveVersion = _version;\n }\n\n function forceResumeReceive(uint16, bytes calldata) external {\n resumeReceived = 1 - resumeReceived;\n }\n}\n" + }, + "contracts/mock/MockLiquidityGauge.sol": { + "content": "// SPDX-License-Identifier: UNLICENSED\npragma solidity ^0.8.12;\n\nimport { ILiquidityGauge } from \"../interfaces/coreModule/ILiquidityGauge.sol\";\nimport \"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\";\nimport \"@openzeppelin/contracts/token/ERC20/ERC20.sol\";\n\ncontract MockLiquidityGauge is ILiquidityGauge, ERC20 {\n using SafeERC20 for IERC20;\n\n IERC20 internal _ANGLE = IERC20(0x31429d1856aD1377A8A0079410B297e1a9e214c2);\n IERC20 internal _token;\n mapping(address => uint256) public rewards;\n\n constructor(string memory name_, string memory symbol_, address token_) ERC20(name_, symbol_) {\n _token = IERC20(token_);\n }\n\n function deposit(\n uint256 _value,\n address _addr,\n // solhint-disable-next-line\n bool\n ) external {\n _token.safeTransferFrom(msg.sender, address(this), _value);\n _mint(_addr, _value);\n }\n\n function withdraw(\n uint256 _value,\n // solhint-disable-next-line\n bool\n ) external {\n _burn(msg.sender, _value);\n _token.safeTransfer(msg.sender, _value);\n }\n\n // solhint-disable-next-line\n function claim_rewards(address _addr, address _receiver) external {\n if (_receiver == address(0)) _receiver = _addr;\n _ANGLE.safeTransfer(_receiver, rewards[_addr]);\n rewards[_addr] = 0;\n }\n\n // solhint-disable-next-line\n function claimable_reward(address _addr, address) external view returns (uint256 amount) {\n return rewards[_addr];\n }\n\n function setReward(address receiver_, uint256 amount) external {\n rewards[receiver_] = amount;\n }\n}\n" + }, + "contracts/mock/MockOracle.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.7;\n\nimport \"../interfaces/IOracle.sol\";\n\ncontract MockOracle is IOracle {\n event Update(uint256 _peg);\n\n ITreasury public treasury;\n\n uint256 public base = 1 ether;\n uint256 public precision = 1 ether;\n uint256 public rate;\n bool public outdated;\n\n /// @notice Initiate with a fixe change rate\n constructor(uint256 rate_, ITreasury _treasury) {\n rate = rate_;\n treasury = _treasury;\n }\n\n /// @notice Mock read\n function read() external view override returns (uint256) {\n return rate;\n }\n\n /// @notice change oracle rate\n function update(uint256 newRate) external {\n rate = newRate;\n }\n\n function setTreasury(address _treasury) external override {\n treasury = ITreasury(_treasury);\n }\n\n function circuitChainlink() external pure override returns (AggregatorV3Interface[] memory) {}\n}\n" + }, + "contracts/mock/MockPolygonAgEUR.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.12;\n\nimport \"../agToken/polygon/utils/ERC20UpgradeableCustom.sol\";\nimport \"@openzeppelin/contracts-upgradeable/access/AccessControlUpgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/utils/cryptography/draft-EIP712Upgradeable.sol\";\nimport \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\nimport \"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\";\n\nimport \"../interfaces/IAgToken.sol\";\nimport \"../interfaces/ITreasury.sol\";\n\ninterface IChildToken {\n function deposit(address user, bytes calldata depositData) external;\n\n function withdraw(uint256 amount) external;\n}\n\ncontract MockPolygonAgEUR is\n Initializable,\n ERC20UpgradeableCustom,\n AccessControlUpgradeable,\n EIP712Upgradeable,\n IChildToken\n{\n bytes32 public constant DEPOSITOR_ROLE = keccak256(\"DEPOSITOR_ROLE\");\n\n /// @dev Emitted when the child chain manager changes\n event ChildChainManagerAdded(address newAddress);\n event ChildChainManagerRevoked(address oldAddress);\n\n constructor() initializer {}\n\n function initialize(\n string memory _name,\n string memory _symbol,\n address childChainManager,\n address guardian\n ) public initializer {\n __ERC20_init(_name, _symbol);\n __AccessControl_init();\n _setupRole(DEFAULT_ADMIN_ROLE, guardian);\n _setupRole(DEPOSITOR_ROLE, childChainManager);\n __EIP712_init(_name, \"1\");\n }\n\n /**\n * @notice Called when the bridge has tokens to mint\n * @param user Address to mint the token to\n * @param depositData Encoded amount to mint\n */\n function deposit(address user, bytes calldata depositData) external override {\n require(hasRole(DEPOSITOR_ROLE, msg.sender));\n uint256 amount = abi.decode(depositData, (uint256));\n _mint(user, amount);\n }\n\n /**\n * @notice Called when user wants to withdraw tokens back to root chain\n * @dev Should burn user's tokens. This transaction will be verified when exiting on root chain\n * @param amount Amount of tokens to withdraw\n */\n function withdraw(uint256 amount) external override {\n _burn(_msgSender(), amount);\n }\n\n // =============================================================================\n // ======================= New data added for the upgrade ======================\n // =============================================================================\n\n mapping(address => bool) public isMinter;\n /// @notice Reference to the treasury contract which can grant minting rights\n address public treasury;\n /// @notice Boolean to check whether the contract has been reinitialized after its upgrade\n bool public treasuryInitialized;\n\n using SafeERC20 for IERC20;\n\n /// @notice Base used for fee computation\n uint256 public constant BASE_PARAMS = 10 ** 9;\n\n // =============================== Bridging Data ===============================\n\n /// @notice Struct with some data about a specific bridge token\n struct BridgeDetails {\n // Limit on the balance of bridge token held by the contract: it is designed\n // to reduce the exposure of the system to hacks\n uint256 limit;\n // Limit on the hourly volume of token minted through this bridge\n // Technically the limit over a rolling hour is hourlyLimit x2 as hourly limit\n // is enforced only between x:00 and x+1:00\n uint256 hourlyLimit;\n // Fee taken for swapping in and out the token\n uint64 fee;\n // Whether the associated token is allowed or not\n bool allowed;\n // Whether swapping in and out from the associated token is paused or not\n bool paused;\n }\n\n /// @notice Maps a bridge token to data\n mapping(address => BridgeDetails) public bridges;\n /// @notice List of all bridge tokens\n address[] public bridgeTokensList;\n /// @notice Maps a bridge token to the associated hourly volume\n mapping(address => mapping(uint256 => uint256)) public usage;\n /// @notice Maps an address to whether it is exempt of fees for when it comes to swapping in and out\n mapping(address => uint256) public isFeeExempt;\n\n uint256[44] private __gap;\n\n // ================================== Events ===================================\n\n event BridgeTokenAdded(address indexed bridgeToken, uint256 limit, uint256 hourlyLimit, uint64 fee, bool paused);\n event BridgeTokenToggled(address indexed bridgeToken, bool toggleStatus);\n event BridgeTokenRemoved(address indexed bridgeToken);\n event BridgeTokenFeeUpdated(address indexed bridgeToken, uint64 fee);\n event BridgeTokenLimitUpdated(address indexed bridgeToken, uint256 limit);\n event BridgeTokenHourlyLimitUpdated(address indexed bridgeToken, uint256 hourlyLimit);\n event HourlyLimitUpdated(uint256 hourlyLimit);\n event FeeToggled(address indexed theAddress, uint256 toggleStatus);\n event KeeperToggled(address indexed keeper, bool toggleStatus);\n event MinterToggled(address indexed minter);\n event Recovered(address indexed token, address indexed to, uint256 amount);\n event TreasuryUpdated(address indexed _treasury);\n\n // ================================== Errors ===================================\n\n error AssetStillControlledInReserves();\n error BurnAmountExceedsAllowance();\n error HourlyLimitExceeded();\n error InvalidSender();\n error InvalidToken();\n error InvalidTreasury();\n error NotGovernor();\n error NotGovernorOrGuardian();\n error NotMinter();\n error NotTreasury();\n error TooBigAmount();\n error TooHighParameterValue();\n error TreasuryAlreadyInitialized();\n error ZeroAddress();\n\n /// @notice Checks to see if it is the `Treasury` calling this contract\n /// @dev There is no Access Control here, because it can be handled cheaply through this modifier\n modifier onlyTreasury() {\n if (msg.sender != treasury) revert NotTreasury();\n _;\n }\n\n /// @notice Checks whether the sender has the minting right\n modifier onlyMinter() {\n if (!isMinter[msg.sender]) revert NotMinter();\n _;\n }\n\n /// @notice Checks whether the `msg.sender` has the governor role or not\n modifier onlyGovernor() {\n if (!ITreasury(treasury).isGovernor(msg.sender)) revert NotGovernor();\n _;\n }\n\n /// @notice Checks whether the `msg.sender` has the governor role or the guardian role\n modifier onlyGovernorOrGuardian() {\n if (!ITreasury(treasury).isGovernorOrGuardian(msg.sender)) revert NotGovernorOrGuardian();\n _;\n }\n\n /// @notice Sets up the treasury contract on Polygon after the upgrade\n /// @param _treasury Address of the treasury contract\n function setUpTreasury(address _treasury) external {\n // Only governor on Polygon\n if (msg.sender != 0xdA2D2f638D6fcbE306236583845e5822554c02EA) revert NotGovernor();\n if (address(ITreasury(_treasury).stablecoin()) != address(this)) revert InvalidTreasury();\n if (treasuryInitialized) revert TreasuryAlreadyInitialized();\n treasury = _treasury;\n treasuryInitialized = true;\n emit TreasuryUpdated(_treasury);\n }\n\n // =========================== External Function ===============================\n\n /// @notice Allows anyone to burn agToken without redeeming collateral back\n /// @param amount Amount of stablecoins to burn\n /// @dev This function can typically be called if there is a settlement mechanism to burn stablecoins\n function burnStablecoin(uint256 amount) external {\n _burnCustom(msg.sender, amount);\n }\n\n // ======================= Minter Role Only Functions ==========================\n\n function burnSelf(uint256 amount, address burner) external onlyMinter {\n _burnCustom(burner, amount);\n }\n\n function burnFrom(uint256 amount, address burner, address sender) external onlyMinter {\n _burnFromNoRedeem(amount, burner, sender);\n }\n\n function mint(address account, uint256 amount) external onlyMinter {\n _mint(account, amount);\n }\n\n // ======================= Treasury Only Functions =============================\n\n function addMinter(address minter) external onlyTreasury {\n isMinter[minter] = true;\n emit MinterToggled(minter);\n }\n\n function removeMinter(address minter) external {\n if (msg.sender != address(treasury) && msg.sender != minter) revert InvalidSender();\n isMinter[minter] = false;\n emit MinterToggled(minter);\n }\n\n function setTreasury(address _treasury) external onlyTreasury {\n treasury = _treasury;\n emit TreasuryUpdated(_treasury);\n }\n\n // ============================ Internal Function ==============================\n\n /// @notice Internal version of the function `burnFromNoRedeem`\n /// @param amount Amount to burn\n /// @dev It is at the level of this function that allowance checks are performed\n function _burnFromNoRedeem(uint256 amount, address burner, address sender) internal {\n if (burner != sender) {\n uint256 currentAllowance = allowance(burner, sender);\n if (currentAllowance < amount) revert BurnAmountExceedsAllowance();\n _approve(burner, sender, currentAllowance - amount);\n }\n _burnCustom(burner, amount);\n }\n\n // ==================== External Permissionless Functions ======================\n\n /// @notice Returns the list of all supported bridge tokens\n /// @dev Helpful for UIs\n function allBridgeTokens() external view returns (address[] memory) {\n return bridgeTokensList;\n }\n\n /// @notice Returns the current volume for a bridge, for the current hour\n /// @dev Helpful for UIs\n function currentUsage(address bridge) external view returns (uint256) {\n return usage[bridge][block.timestamp / 3600];\n }\n\n /// @notice Mints the canonical token from a supported bridge token\n /// @param bridgeToken Bridge token to use to mint\n /// @param amount Amount of bridge tokens to send\n /// @param to Address to which the stablecoin should be sent\n /// @dev Some fees may be taken by the protocol depending on the token used and on the address calling\n function swapIn(address bridgeToken, uint256 amount, address to) external returns (uint256) {\n BridgeDetails memory bridgeDetails = bridges[bridgeToken];\n if (!bridgeDetails.allowed || bridgeDetails.paused) revert InvalidToken();\n uint256 balance = IERC20(bridgeToken).balanceOf(address(this));\n if (balance + amount > bridgeDetails.limit) {\n // In case someone maliciously sends tokens to this contract\n // Or the limit changes\n if (bridgeDetails.limit > balance) amount = bridgeDetails.limit - balance;\n else {\n amount = 0;\n }\n }\n\n // Checking requirement on the hourly volume\n uint256 hour = block.timestamp / 3600;\n uint256 hourlyUsage = usage[bridgeToken][hour] + amount;\n if (hourlyUsage > bridgeDetails.hourlyLimit) {\n // Edge case when the hourly limit changes\n if (bridgeDetails.hourlyLimit > usage[bridgeToken][hour])\n amount = bridgeDetails.hourlyLimit - usage[bridgeToken][hour];\n else {\n amount = 0;\n }\n }\n usage[bridgeToken][hour] = usage[bridgeToken][hour] + amount;\n\n IERC20(bridgeToken).safeTransferFrom(msg.sender, address(this), amount);\n uint256 canonicalOut = amount;\n // Computing fees\n if (isFeeExempt[msg.sender] == 0) {\n canonicalOut -= (canonicalOut * bridgeDetails.fee) / BASE_PARAMS;\n }\n _mint(to, canonicalOut);\n return canonicalOut;\n }\n\n /// @notice Burns the canonical token in exchange for a bridge token\n /// @param bridgeToken Bridge token required\n /// @param amount Amount of canonical tokens to burn\n /// @param to Address to which the bridge token should be sent\n /// @dev Some fees may be taken by the protocol depending on the token used and on the address calling\n function swapOut(address bridgeToken, uint256 amount, address to) external returns (uint256) {\n BridgeDetails memory bridgeDetails = bridges[bridgeToken];\n if (!bridgeDetails.allowed || bridgeDetails.paused) revert InvalidToken();\n\n _burnCustom(msg.sender, amount);\n uint256 bridgeOut = amount;\n if (isFeeExempt[msg.sender] == 0) {\n bridgeOut -= (bridgeOut * bridgeDetails.fee) / BASE_PARAMS;\n }\n IERC20(bridgeToken).safeTransfer(to, bridgeOut);\n return bridgeOut;\n }\n\n // ======================= Governance Functions ================================\n\n /// @notice Adds support for a bridge token\n /// @param bridgeToken Bridge token to add: it should be a version of the stablecoin from another bridge\n /// @param limit Limit on the balance of bridge token this contract could hold\n /// @param hourlyLimit Limit on the hourly volume for this bridge\n /// @param paused Whether swapping for this token should be paused or not\n /// @param fee Fee taken upon swapping for or against this token\n function addBridgeToken(\n address bridgeToken,\n uint256 limit,\n uint256 hourlyLimit,\n uint64 fee,\n bool paused\n ) external onlyGovernor {\n if (bridges[bridgeToken].allowed || bridgeToken == address(0)) revert InvalidToken();\n if (fee > BASE_PARAMS) revert TooHighParameterValue();\n BridgeDetails memory _bridge;\n _bridge.limit = limit;\n _bridge.hourlyLimit = hourlyLimit;\n _bridge.paused = paused;\n _bridge.fee = fee;\n _bridge.allowed = true;\n bridges[bridgeToken] = _bridge;\n bridgeTokensList.push(bridgeToken);\n emit BridgeTokenAdded(bridgeToken, limit, hourlyLimit, fee, paused);\n }\n\n /// @notice Removes support for a token\n /// @param bridgeToken Address of the bridge token to remove support for\n function removeBridgeToken(address bridgeToken) external onlyGovernor {\n if (IERC20(bridgeToken).balanceOf(address(this)) != 0) revert AssetStillControlledInReserves();\n delete bridges[bridgeToken];\n // Deletion from `bridgeTokensList` loop\n uint256 bridgeTokensListLength = bridgeTokensList.length;\n for (uint256 i; i < bridgeTokensListLength - 1; ++i) {\n if (bridgeTokensList[i] == bridgeToken) {\n // Replace the `bridgeToken` to remove with the last of the list\n bridgeTokensList[i] = bridgeTokensList[bridgeTokensListLength - 1];\n break;\n }\n }\n // Remove last element in array\n bridgeTokensList.pop();\n emit BridgeTokenRemoved(bridgeToken);\n }\n\n /// @notice Recovers any ERC20 token\n /// @dev Can be used to withdraw bridge tokens for them to be de-bridged on mainnet\n function recoverERC20(address tokenAddress, address to, uint256 amountToRecover) external onlyGovernor {\n IERC20(tokenAddress).safeTransfer(to, amountToRecover);\n emit Recovered(tokenAddress, to, amountToRecover);\n }\n\n /// @notice Updates the `limit` amount for `bridgeToken`\n function setLimit(address bridgeToken, uint256 limit) external onlyGovernorOrGuardian {\n if (!bridges[bridgeToken].allowed) revert InvalidToken();\n bridges[bridgeToken].limit = limit;\n emit BridgeTokenLimitUpdated(bridgeToken, limit);\n }\n\n /// @notice Updates the `hourlyLimit` amount for `bridgeToken`\n function setHourlyLimit(address bridgeToken, uint256 hourlyLimit) external onlyGovernorOrGuardian {\n if (!bridges[bridgeToken].allowed) revert InvalidToken();\n bridges[bridgeToken].hourlyLimit = hourlyLimit;\n emit BridgeTokenHourlyLimitUpdated(bridgeToken, hourlyLimit);\n }\n\n /// @notice Updates the `fee` value for `bridgeToken`\n function setSwapFee(address bridgeToken, uint64 fee) external onlyGovernorOrGuardian {\n if (!bridges[bridgeToken].allowed) revert InvalidToken();\n if (fee > BASE_PARAMS) revert TooHighParameterValue();\n bridges[bridgeToken].fee = fee;\n emit BridgeTokenFeeUpdated(bridgeToken, fee);\n }\n\n /// @notice Pauses or unpauses swapping in and out for a token\n function toggleBridge(address bridgeToken) external onlyGovernorOrGuardian {\n if (!bridges[bridgeToken].allowed) revert InvalidToken();\n bool pausedStatus = bridges[bridgeToken].paused;\n bridges[bridgeToken].paused = !pausedStatus;\n emit BridgeTokenToggled(bridgeToken, !pausedStatus);\n }\n\n /// @notice Toggles fees for the address `theAddress`\n function toggleFeesForAddress(address theAddress) external onlyGovernorOrGuardian {\n uint256 feeExemptStatus = 1 - isFeeExempt[theAddress];\n isFeeExempt[theAddress] = feeExemptStatus;\n emit FeeToggled(theAddress, feeExemptStatus);\n }\n}\n" + }, + "contracts/mock/MockRouter.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\nimport \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\nimport \"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\";\n\nimport \"../interfaces/IAngleRouter.sol\";\nimport \"../interfaces/external/uniswap/IUniswapRouter.sol\";\nimport \"../interfaces/external/lido/IWStETH.sol\";\n\ncontract MockRouter is IUniswapV3Router, IWStETH {\n using SafeERC20 for IERC20;\n\n uint256 public counterAngleMint;\n uint256 public counterAngleBurn;\n uint256 public counter1Inch;\n uint256 public counterUni;\n uint256 public counterWrap;\n uint256 public counterMixer;\n uint256 public amountOutUni;\n uint256 public multiplierMintBurn;\n uint256 public stETHMultiplier;\n address public inToken;\n address public outToken;\n\n address public stETH;\n\n /// @notice Action types\n enum ActionType {\n transfer,\n wrap,\n wrapNative,\n sweep,\n sweepNative,\n unwrap,\n unwrapNative,\n swapIn,\n swapOut,\n uniswapV3,\n oneInch,\n claimRewards,\n gaugeDeposit,\n borrower\n }\n\n /// @notice Data needed to get permits\n struct PermitType {\n address token;\n address owner;\n uint256 value;\n uint256 deadline;\n uint8 v;\n bytes32 r;\n bytes32 s;\n }\n\n constructor() {}\n\n function mint(address user, uint256 amount, uint256, address stablecoin, address collateral) external {\n counterAngleMint += 1;\n IERC20(collateral).safeTransferFrom(msg.sender, address(this), amount);\n IERC20(stablecoin).safeTransfer(user, (amount * 10 ** 9) / multiplierMintBurn);\n }\n\n function setStETH(address _stETH) external {\n stETH = _stETH;\n }\n\n function burn(address user, uint256 amount, uint256, address stablecoin, address collateral) external {\n counterAngleBurn += 1;\n IERC20(stablecoin).safeTransferFrom(msg.sender, address(this), amount);\n IERC20(collateral).safeTransfer(user, (amount * multiplierMintBurn) / 10 ** 9);\n }\n\n function mixer(\n PermitType[] memory paramsPermit,\n ActionType[] memory actions,\n bytes[] calldata data\n ) public payable virtual {\n paramsPermit;\n counterMixer += 1;\n for (uint256 i; i < actions.length; ++i) {\n if (actions[i] == ActionType.transfer) {\n (address transferToken, uint256 amount) = abi.decode(data[i], (address, uint256));\n IERC20(transferToken).safeTransferFrom(msg.sender, address(this), amount);\n }\n }\n }\n\n function wrap(uint256 amount) external returns (uint256 amountOut) {\n amountOut = (amount * stETHMultiplier) / 10 ** 9;\n counterWrap += 1;\n IERC20(stETH).safeTransferFrom(msg.sender, address(this), amount);\n IERC20(outToken).safeTransfer(msg.sender, amountOut);\n }\n\n function oneInch(uint256 amountIn) external returns (uint256 amountOut) {\n counter1Inch += 1;\n amountOut = (amountOutUni * amountIn) / 10 ** 9;\n IERC20(inToken).safeTransferFrom(msg.sender, address(this), amountIn);\n IERC20(outToken).safeTransfer(msg.sender, amountOut);\n }\n\n function oneInchReverts() external {\n counter1Inch += 1;\n revert(\"wrong swap\");\n }\n\n function oneInchRevertsWithoutMessage() external {\n counter1Inch += 1;\n require(false);\n }\n\n function exactInput(ExactInputParams calldata params) external payable returns (uint256 amountOut) {\n counterUni += 1;\n amountOut = (params.amountIn * amountOutUni) / 10 ** 9;\n IERC20(inToken).safeTransferFrom(msg.sender, address(this), params.amountIn);\n IERC20(outToken).safeTransfer(params.recipient, amountOut);\n require(amountOut >= params.amountOutMinimum);\n }\n\n function setMultipliers(uint256 a, uint256 b) external {\n amountOutUni = a;\n multiplierMintBurn = b;\n }\n\n function setStETHMultiplier(uint256 value) external {\n stETHMultiplier = value;\n }\n\n function setInOut(address _collateral, address _stablecoin) external {\n inToken = _collateral;\n outToken = _stablecoin;\n }\n}\n" + }, + "contracts/mock/MockSidechainAgEUR.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\nimport \"../agToken/AgToken.sol\";\nimport \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\nimport \"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\";\n\n/// @title AgTokenSideChainMultiBridge\n/// @author Angle Labs, Inc.\n/// @notice Contract for Angle agTokens on other chains than Ethereum mainnet\n/// @dev This contract supports bridge tokens having a minting right on the stablecoin (also referred to as the canonical\n/// or the native token)\n/// @dev References:\n/// - FRAX implementation: https://polygonscan.com/address/0x45c32fA6DF82ead1e2EF74d17b76547EDdFaFF89#code\n/// - QiDAO implementation: https://snowtrace.io/address/0x5c49b268c9841AFF1Cc3B0a418ff5c3442eE3F3b#code\ncontract MockSidechainAgEUR is AgToken {\n using SafeERC20 for IERC20;\n\n /// @notice Base used for fee computation\n uint256 public constant BASE_PARAMS = 10 ** 9;\n\n // =============================== Bridging Data ===============================\n\n /// @notice Struct with some data about a specific bridge token\n struct BridgeDetails {\n // Limit on the balance of bridge token held by the contract: it is designed\n // to reduce the exposure of the system to hacks\n uint256 limit;\n // Limit on the hourly volume of token minted through this bridge\n // Technically the limit over a rolling hour is hourlyLimit x2 as hourly limit\n // is enforced only between x:00 and x+1:00\n uint256 hourlyLimit;\n // Fee taken for swapping in and out the token\n uint64 fee;\n // Whether the associated token is allowed or not\n bool allowed;\n // Whether swapping in and out from the associated token is paused or not\n bool paused;\n }\n\n /// @notice Maps a bridge token to data\n mapping(address => BridgeDetails) public bridges;\n /// @notice List of all bridge tokens\n address[] public bridgeTokensList;\n /// @notice Maps a bridge token to the associated hourly volume\n mapping(address => mapping(uint256 => uint256)) public usage;\n /// @notice Maps an address to whether it is exempt of fees for when it comes to swapping in and out\n mapping(address => uint256) public isFeeExempt;\n\n // ================================== Events ===================================\n\n event BridgeTokenAdded(address indexed bridgeToken, uint256 limit, uint256 hourlyLimit, uint64 fee, bool paused);\n event BridgeTokenToggled(address indexed bridgeToken, bool toggleStatus);\n event BridgeTokenRemoved(address indexed bridgeToken);\n event BridgeTokenFeeUpdated(address indexed bridgeToken, uint64 fee);\n event BridgeTokenLimitUpdated(address indexed bridgeToken, uint256 limit);\n event BridgeTokenHourlyLimitUpdated(address indexed bridgeToken, uint256 hourlyLimit);\n event HourlyLimitUpdated(uint256 hourlyLimit);\n event Recovered(address indexed token, address indexed to, uint256 amount);\n event FeeToggled(address indexed theAddress, uint256 toggleStatus);\n\n // =============================== Errors ================================\n\n error AssetStillControlledInReserves();\n error HourlyLimitExceeded();\n error InvalidToken();\n error NotGovernor();\n error NotGovernorOrGuardian();\n error TooBigAmount();\n error TooHighParameterValue();\n error ZeroAddress();\n\n // ============================= Constructor ===================================\n\n /// @notice Checks whether the `msg.sender` has the governor role or not\n modifier onlyGovernor() {\n if (!ITreasury(treasury).isGovernor(msg.sender)) revert NotGovernor();\n _;\n }\n\n /// @notice Checks whether the `msg.sender` has the governor role or the guardian role\n modifier onlyGovernorOrGuardian() {\n if (!ITreasury(treasury).isGovernorOrGuardian(msg.sender)) revert NotGovernorOrGuardian();\n _;\n }\n\n // ==================== External Permissionless Functions ======================\n\n /// @notice Returns the list of all supported bridge tokens\n /// @dev Helpful for UIs\n function allBridgeTokens() external view returns (address[] memory) {\n return bridgeTokensList;\n }\n\n /// @notice Returns the current volume for a bridge, for the current hour\n /// @param bridgeToken Bridge used to mint\n /// @dev Helpful for UIs\n function currentUsage(address bridgeToken) external view returns (uint256) {\n return usage[bridgeToken][block.timestamp / 3600];\n }\n\n /// @notice Mints the canonical token from a supported bridge token\n /// @param bridgeToken Bridge token to use to mint\n /// @param amount Amount of bridge tokens to send\n /// @param to Address to which the stablecoin should be sent\n /// @return Amount of the canonical stablecoin actually minted\n /// @dev Some fees may be taken by the protocol depending on the token used and on the address calling\n function swapIn(address bridgeToken, uint256 amount, address to) external returns (uint256) {\n BridgeDetails memory bridgeDetails = bridges[bridgeToken];\n if (!bridgeDetails.allowed || bridgeDetails.paused) revert InvalidToken();\n uint256 balance = IERC20(bridgeToken).balanceOf(address(this));\n if (balance + amount > bridgeDetails.limit) {\n // In case someone maliciously sends tokens to this contract\n // Or the limit changes\n if (bridgeDetails.limit > balance) amount = bridgeDetails.limit - balance;\n else {\n amount = 0;\n }\n }\n\n // Checking requirement on the hourly volume\n uint256 hour = block.timestamp / 3600;\n uint256 hourlyUsage = usage[bridgeToken][hour] + amount;\n if (hourlyUsage > bridgeDetails.hourlyLimit) {\n // Edge case when the hourly limit changes\n if (bridgeDetails.hourlyLimit > usage[bridgeToken][hour])\n amount = bridgeDetails.hourlyLimit - usage[bridgeToken][hour];\n else {\n amount = 0;\n }\n }\n usage[bridgeToken][hour] = usage[bridgeToken][hour] + amount;\n\n IERC20(bridgeToken).safeTransferFrom(msg.sender, address(this), amount);\n uint256 canonicalOut = amount;\n // Computing fees\n if (isFeeExempt[msg.sender] == 0) {\n canonicalOut -= (canonicalOut * bridgeDetails.fee) / BASE_PARAMS;\n }\n _mint(to, canonicalOut);\n return canonicalOut;\n }\n\n /// @notice Burns the canonical token in exchange for a bridge token\n /// @param bridgeToken Bridge token required\n /// @param amount Amount of canonical tokens to burn\n /// @param to Address to which the bridge token should be sent\n /// @return Amount of bridge tokens actually sent back\n /// @dev Some fees may be taken by the protocol depending on the token used and on the address calling\n function swapOut(address bridgeToken, uint256 amount, address to) external returns (uint256) {\n BridgeDetails memory bridgeDetails = bridges[bridgeToken];\n if (!bridgeDetails.allowed || bridgeDetails.paused) revert InvalidToken();\n\n _burn(msg.sender, amount);\n uint256 bridgeOut = amount;\n if (isFeeExempt[msg.sender] == 0) {\n bridgeOut -= (bridgeOut * bridgeDetails.fee) / BASE_PARAMS;\n }\n IERC20(bridgeToken).safeTransfer(to, bridgeOut);\n return bridgeOut;\n }\n\n // ======================= Governance Functions ================================\n\n /// @notice Adds support for a bridge token\n /// @param bridgeToken Bridge token to add: it should be a version of the stablecoin from another bridge\n /// @param limit Limit on the balance of bridge token this contract could hold\n /// @param hourlyLimit Limit on the hourly volume for this bridge\n /// @param paused Whether swapping for this token should be paused or not\n /// @param fee Fee taken upon swapping for or against this token\n function addBridgeToken(\n address bridgeToken,\n uint256 limit,\n uint256 hourlyLimit,\n uint64 fee,\n bool paused\n ) external onlyGovernor {\n if (bridges[bridgeToken].allowed || bridgeToken == address(0)) revert InvalidToken();\n if (fee > BASE_PARAMS) revert TooHighParameterValue();\n BridgeDetails memory _bridge;\n _bridge.limit = limit;\n _bridge.hourlyLimit = hourlyLimit;\n _bridge.paused = paused;\n _bridge.fee = fee;\n _bridge.allowed = true;\n bridges[bridgeToken] = _bridge;\n bridgeTokensList.push(bridgeToken);\n emit BridgeTokenAdded(bridgeToken, limit, hourlyLimit, fee, paused);\n }\n\n /// @notice Removes support for a token\n /// @param bridgeToken Address of the bridge token to remove support for\n function removeBridgeToken(address bridgeToken) external onlyGovernor {\n if (IERC20(bridgeToken).balanceOf(address(this)) != 0) revert AssetStillControlledInReserves();\n delete bridges[bridgeToken];\n // Deletion from `bridgeTokensList` loop\n uint256 bridgeTokensListLength = bridgeTokensList.length;\n for (uint256 i; i < bridgeTokensListLength - 1; ++i) {\n if (bridgeTokensList[i] == bridgeToken) {\n // Replace the `bridgeToken` to remove with the last of the list\n bridgeTokensList[i] = bridgeTokensList[bridgeTokensListLength - 1];\n break;\n }\n }\n // Remove last element in array\n bridgeTokensList.pop();\n emit BridgeTokenRemoved(bridgeToken);\n }\n\n /// @notice Recovers any ERC20 token\n /// @dev Can be used to withdraw bridge tokens for them to be de-bridged on mainnet\n function recoverERC20(address tokenAddress, address to, uint256 amountToRecover) external onlyGovernor {\n IERC20(tokenAddress).safeTransfer(to, amountToRecover);\n emit Recovered(tokenAddress, to, amountToRecover);\n }\n\n /// @notice Updates the `limit` amount for `bridgeToken`\n function setLimit(address bridgeToken, uint256 limit) external onlyGovernorOrGuardian {\n if (!bridges[bridgeToken].allowed) revert InvalidToken();\n bridges[bridgeToken].limit = limit;\n emit BridgeTokenLimitUpdated(bridgeToken, limit);\n }\n\n /// @notice Updates the `hourlyLimit` amount for `bridgeToken`\n function setHourlyLimit(address bridgeToken, uint256 hourlyLimit) external onlyGovernorOrGuardian {\n if (!bridges[bridgeToken].allowed) revert InvalidToken();\n bridges[bridgeToken].hourlyLimit = hourlyLimit;\n emit BridgeTokenHourlyLimitUpdated(bridgeToken, hourlyLimit);\n }\n\n /// @notice Updates the `fee` value for `bridgeToken`\n function setSwapFee(address bridgeToken, uint64 fee) external onlyGovernorOrGuardian {\n if (!bridges[bridgeToken].allowed) revert InvalidToken();\n if (fee > BASE_PARAMS) revert TooHighParameterValue();\n bridges[bridgeToken].fee = fee;\n emit BridgeTokenFeeUpdated(bridgeToken, fee);\n }\n\n /// @notice Pauses or unpauses swapping in and out for a token\n function toggleBridge(address bridgeToken) external onlyGovernorOrGuardian {\n if (!bridges[bridgeToken].allowed) revert InvalidToken();\n bool pausedStatus = bridges[bridgeToken].paused;\n bridges[bridgeToken].paused = !pausedStatus;\n emit BridgeTokenToggled(bridgeToken, !pausedStatus);\n }\n\n /// @notice Toggles fees for the address `theAddress`\n function toggleFeesForAddress(address theAddress) external onlyGovernorOrGuardian {\n uint256 feeExemptStatus = 1 - isFeeExempt[theAddress];\n isFeeExempt[theAddress] = feeExemptStatus;\n emit FeeToggled(theAddress, feeExemptStatus);\n }\n}\n" + }, + "contracts/mock/MockStableMaster.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\nimport \"../interfaces/IAgToken.sol\";\nimport \"./MockToken.sol\";\nimport \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\nimport \"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\";\nimport { SLPData, MintBurnData } from \"../interfaces/coreModule/IStableMaster.sol\";\n\n// All the details about a collateral that are going to be stored in `StableMaster`\nstruct Collateral {\n // Interface for the token accepted by the underlying `PoolManager` contract\n IERC20 token;\n // Reference to the `SanToken` for the pool\n MockToken sanToken;\n // Reference to the `PerpetualManager` for the pool\n address perpetualManager;\n // Adress of the oracle for the change rate between\n // collateral and the corresponding stablecoin\n address oracle;\n // Amount of collateral in the reserves that comes from users\n // converted in stablecoin value. Updated at minting and burning.\n // A `stocksUsers` of 10 for a collateral type means that overall the balance of the collateral from users\n // that minted/burnt stablecoins using this collateral is worth 10 of stablecoins\n uint256 stocksUsers;\n // Exchange rate between sanToken and collateral\n uint256 sanRate;\n // Base used in the collateral implementation (ERC20 decimal)\n uint256 collatBase;\n // Parameters for SLPs and update of the `sanRate`\n SLPData slpData;\n // All the fees parameters\n MintBurnData feeData;\n}\n\ncontract MockStableMaster {\n mapping(address => uint256) public poolManagerMap;\n\n constructor() {}\n\n function updateStocksUsers(uint256 amount, address poolManager) external {\n poolManagerMap[poolManager] += amount;\n }\n\n function burnSelf(IAgToken agToken, uint256 amount, address burner) external {\n agToken.burnSelf(amount, burner);\n }\n\n function burnFrom(IAgToken agToken, uint256 amount, address burner, address sender) external {\n agToken.burnFrom(amount, burner, sender);\n }\n\n function mint(IAgToken agToken, address account, uint256 amount) external {\n agToken.mint(account, amount);\n }\n}\n\ncontract MockStableMasterSanWrapper is MockStableMaster {\n using SafeERC20 for IERC20;\n\n /// @notice Maps a `PoolManager` contract handling a collateral for this stablecoin to the properties of the struct above\n mapping(address => Collateral) public collateralMap;\n\n constructor() MockStableMaster() {}\n\n uint256 internal constant _BASE_TOKENS = 10 ** 18;\n uint256 internal constant _BASE_PARAMS = 10 ** 9;\n IERC20 public token;\n\n function deposit(uint256 assets, address receiver, address poolManager) external {\n token.safeTransferFrom(msg.sender, address(this), assets);\n Collateral storage col = collateralMap[poolManager];\n _updateSanRate(col);\n uint256 amount = (assets * _BASE_TOKENS) / col.sanRate;\n col.sanToken.mint(receiver, amount);\n }\n\n function withdraw(uint256 assets, address sender, address receiver, address poolManager) external {\n Collateral storage col = collateralMap[poolManager];\n _updateSanRate(col);\n col.sanToken.burn(sender, assets);\n // Computing the amount of collateral to give back to the SLP depending on slippage and on the `sanRate`\n uint256 redeemInC = (assets * (_BASE_PARAMS - col.slpData.slippage) * col.sanRate) /\n (_BASE_TOKENS * _BASE_PARAMS);\n token.safeTransfer(receiver, redeemInC);\n }\n\n function setPoolManagerToken(address, address token_) external {\n token = MockToken(token_);\n }\n\n function setPoolManagerSanToken(address poolManager, address sanToken_) external {\n Collateral storage col = collateralMap[poolManager];\n col.sanToken = MockToken(sanToken_);\n }\n\n function setSanRate(address poolManager, uint256 sanRate_) external {\n Collateral storage col = collateralMap[poolManager];\n col.sanRate = sanRate_;\n }\n\n function _updateSanRate(Collateral storage col) internal {\n uint256 _lockedInterests = col.slpData.lockedInterests;\n // Checking if the `sanRate` has been updated in the current block using past block fees\n // This is a way to prevent flash loans attacks when an important amount of fees are going to be distributed\n // in a block: fees are stored but will just be distributed to SLPs who will be here during next blocks\n if (block.timestamp != col.slpData.lastBlockUpdated && _lockedInterests > 0) {\n uint256 sanMint = col.sanToken.totalSupply();\n if (sanMint != 0) {\n // Checking if the update is too important and should be made in multiple blocks\n if (_lockedInterests > col.slpData.maxInterestsDistributed) {\n // `sanRate` is expressed in `BASE_TOKENS`\n col.sanRate += (col.slpData.maxInterestsDistributed * 10 ** 18) / sanMint;\n _lockedInterests -= col.slpData.maxInterestsDistributed;\n } else {\n col.sanRate += (_lockedInterests * 10 ** 18) / sanMint;\n _lockedInterests = 0;\n }\n } else {\n _lockedInterests = 0;\n }\n }\n col.slpData.lockedInterests = _lockedInterests;\n col.slpData.lastBlockUpdated = block.timestamp;\n }\n\n // copy paste from the deployed contract\n function estimateSanRate(address poolManager) external view returns (uint256 sanRate, uint64 slippage) {\n Collateral memory col = collateralMap[poolManager];\n uint256 _lockedInterests = col.slpData.lockedInterests;\n // Checking if the `sanRate` has been updated in the current block using past block fees\n // This is a way to prevent flash loans attacks when an important amount of fees are going to be distributed\n // in a block: fees are stored but will just be distributed to SLPs who will be here during next blocks\n if (block.timestamp != col.slpData.lastBlockUpdated && _lockedInterests > 0) {\n uint256 sanMint = col.sanToken.totalSupply();\n if (sanMint != 0) {\n // Checking if the update is too important and should be made in multiple blocks\n if (_lockedInterests > col.slpData.maxInterestsDistributed) {\n // `sanRate` is expressed in `BASE_TOKENS`\n col.sanRate += (col.slpData.maxInterestsDistributed * 10 ** 18) / sanMint;\n _lockedInterests -= col.slpData.maxInterestsDistributed;\n } else {\n col.sanRate += (_lockedInterests * 10 ** 18) / sanMint;\n _lockedInterests = 0;\n }\n } else {\n _lockedInterests = 0;\n }\n }\n return (col.sanRate, col.slpData.slippage);\n }\n\n function setSLPData(\n address poolManager,\n uint256 lockedInterests,\n uint256 maxInterestsDistributed,\n uint64 slippage\n ) external {\n Collateral storage col = collateralMap[poolManager];\n col.slpData.lockedInterests = lockedInterests;\n col.slpData.maxInterestsDistributed = maxInterestsDistributed;\n col.slpData.slippage = slippage;\n }\n}\n" + }, + "contracts/mock/MockSwapper.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\nimport \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\nimport \"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\";\n\nimport \"../interfaces/ISwapper.sol\";\n\ncontract MockSwapper is ISwapper {\n bytes32 public constant CALLBACK_SUCCESS = keccak256(\"ERC3156FlashBorrower.onFlashLoan\");\n\n uint256 public counter;\n\n constructor() {}\n\n function swap(IERC20, IERC20, address, uint256, uint256, bytes calldata data) external {\n counter += 1;\n data;\n }\n}\n\ncontract MockSwapperWithSwap is ISwapper {\n using SafeERC20 for IERC20;\n bytes32 public constant CALLBACK_SUCCESS = keccak256(\"ERC3156FlashBorrower.onFlashLoan\");\n\n uint256 public counter;\n\n constructor() {}\n\n function swap(\n IERC20,\n IERC20 outToken,\n address outTokenRecipient,\n uint256 outTokenOwed,\n uint256,\n bytes calldata data\n ) external {\n counter += 1;\n outToken.safeTransfer(outTokenRecipient, outTokenOwed);\n\n data;\n }\n}\n" + }, + "contracts/mock/MockSwapperSidechain.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\nimport \"../swapper/Swapper.sol\";\n\n/// @title MockSwapperSidechain\n/// @author Angle Labs, Inc.\ncontract MockSwapperSidechain is Swapper {\n error NotImplemented();\n\n /// @notice Constructor of the contract\n /// @param _core Core address\n /// @param _uniV3Router UniswapV3 Router address\n /// @param _oneInch 1Inch Router address\n /// @param _angleRouter AngleRouter contract address\n constructor(\n ICoreBorrow _core,\n IUniswapV3Router _uniV3Router,\n address _oneInch,\n IAngleRouterSidechain _angleRouter\n ) Swapper(_core, _uniV3Router, _oneInch, _angleRouter) {}\n\n function _swapLeverage(bytes memory) internal pure override returns (uint256) {\n revert NotImplemented();\n }\n}\n" + }, + "contracts/mock/MockToken.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.7;\n\nimport \"@openzeppelin/contracts/token/ERC20/ERC20.sol\";\n\ncontract MockToken is ERC20 {\n event Minting(address indexed _to, address indexed _minter, uint256 _amount);\n\n event Burning(address indexed _from, address indexed _burner, uint256 _amount);\n\n uint8 internal _decimal;\n mapping(address => bool) public minters;\n address public treasury;\n\n constructor(string memory name_, string memory symbol_, uint8 decimal_) ERC20(name_, symbol_) {\n _decimal = decimal_;\n }\n\n function decimals() public view override returns (uint8) {\n return _decimal;\n }\n\n function mint(address account, uint256 amount) external {\n _mint(account, amount);\n emit Minting(account, msg.sender, amount);\n }\n\n function burn(address account, uint256 amount) public {\n _burn(account, amount);\n emit Burning(account, msg.sender, amount);\n }\n\n function setAllowance(address from, address to) public {\n _approve(from, to, type(uint256).max);\n }\n\n function burnSelf(uint256 amount, address account) public {\n _burn(account, amount);\n emit Burning(account, msg.sender, amount);\n }\n\n function addMinter(address minter) public {\n minters[minter] = true;\n }\n\n function removeMinter(address minter) public {\n minters[minter] = false;\n }\n\n function setTreasury(address _treasury) public {\n treasury = _treasury;\n }\n}\n" + }, + "contracts/mock/MockTokenPermit.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.7;\n\nimport \"@openzeppelin/contracts/token/ERC20/extensions/draft-ERC20Permit.sol\";\nimport \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\nimport \"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\";\n\ncontract MockTokenPermit is ERC20Permit {\n using SafeERC20 for IERC20;\n event Minting(address indexed _to, address indexed _minter, uint256 _amount);\n\n event Burning(address indexed _from, address indexed _burner, uint256 _amount);\n\n uint8 internal _decimal;\n mapping(address => bool) public minters;\n address public treasury;\n uint256 public fees;\n\n bool public reverts;\n\n constructor(string memory name_, string memory symbol_, uint8 decimal_) ERC20Permit(name_) ERC20(name_, symbol_) {\n _decimal = decimal_;\n }\n\n function decimals() public view override returns (uint8) {\n return _decimal;\n }\n\n function mint(address account, uint256 amount) external {\n _mint(account, amount);\n emit Minting(account, msg.sender, amount);\n }\n\n function burn(address account, uint256 amount) public {\n _burn(account, amount);\n emit Burning(account, msg.sender, amount);\n }\n\n function setAllowance(address from, address to) public {\n _approve(from, to, type(uint256).max);\n }\n\n function burnSelf(uint256 amount, address account) public {\n _burn(account, amount);\n emit Burning(account, msg.sender, amount);\n }\n\n function addMinter(address minter) public {\n minters[minter] = true;\n }\n\n function removeMinter(address minter) public {\n minters[minter] = false;\n }\n\n function setTreasury(address _treasury) public {\n treasury = _treasury;\n }\n\n function setFees(uint256 _fees) public {\n fees = _fees;\n }\n\n function recoverERC20(IERC20 token, address to, uint256 amount) external {\n token.safeTransfer(to, amount);\n }\n\n function swapIn(address bridgeToken, uint256 amount, address to) external returns (uint256) {\n require(!reverts);\n\n IERC20(bridgeToken).safeTransferFrom(msg.sender, address(this), amount);\n uint256 canonicalOut = amount;\n canonicalOut -= (canonicalOut * fees) / 10 ** 9;\n _mint(to, canonicalOut);\n return canonicalOut;\n }\n\n function swapOut(address bridgeToken, uint256 amount, address to) external returns (uint256) {\n require(!reverts);\n _burn(msg.sender, amount);\n uint256 bridgeOut = amount;\n bridgeOut -= (bridgeOut * fees) / 10 ** 9;\n IERC20(bridgeToken).safeTransfer(to, bridgeOut);\n return bridgeOut;\n }\n}\n" + }, + "contracts/mock/MockTreasury.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\nimport \"../interfaces/ITreasury.sol\";\nimport \"../interfaces/IFlashAngle.sol\";\nimport \"../interfaces/IVaultManager.sol\";\n\ncontract MockTreasury is ITreasury {\n IAgToken public override stablecoin;\n address public governor;\n address public guardian;\n address public vaultManager1;\n address public vaultManager2;\n address public flashLoanModule;\n address[] public vaultManagerList;\n\n constructor(\n IAgToken _stablecoin,\n address _governor,\n address _guardian,\n address _vaultManager1,\n address _vaultManager2,\n address _flashLoanModule\n ) {\n stablecoin = _stablecoin;\n governor = _governor;\n guardian = _guardian;\n vaultManager1 = _vaultManager1;\n vaultManager2 = _vaultManager2;\n flashLoanModule = _flashLoanModule;\n }\n\n function isGovernor(address admin) external view override returns (bool) {\n return (admin == governor);\n }\n\n function isGovernorOrGuardian(address admin) external view override returns (bool) {\n return (admin == governor || admin == guardian);\n }\n\n function isVaultManager(address _vaultManager) external view override returns (bool) {\n return (_vaultManager == vaultManager1 || _vaultManager == vaultManager2);\n }\n\n function setStablecoin(IAgToken _stablecoin) external {\n stablecoin = _stablecoin;\n }\n\n function setFlashLoanModule(address _flashLoanModule) external override {\n flashLoanModule = _flashLoanModule;\n }\n\n function setGovernor(address _governor) external {\n governor = _governor;\n }\n\n function setVaultManager(address _vaultManager) external {\n vaultManager1 = _vaultManager;\n }\n\n function setVaultManager2(address _vaultManager) external {\n vaultManager2 = _vaultManager;\n }\n\n function setTreasury(address _agTokenOrVaultManager, address _treasury) external {\n IAgToken(_agTokenOrVaultManager).setTreasury(_treasury);\n }\n\n function addMinter(IAgToken _agToken, address _minter) external {\n _agToken.addMinter(_minter);\n }\n\n function removeMinter(IAgToken _agToken, address _minter) external {\n _agToken.removeMinter(_minter);\n }\n\n function accrueInterestToTreasury(IFlashAngle flashAngle) external returns (uint256 balance) {\n balance = flashAngle.accrueInterestToTreasury(stablecoin);\n }\n\n function accrueInterestToTreasuryVaultManager(IVaultManager _vaultManager) external returns (uint256, uint256) {\n return _vaultManager.accrueInterestToTreasury();\n }\n}\n" + }, + "contracts/mock/MockUniswapV3Pool.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.7;\n\ncontract MockUniswapV3Pool {\n address public token0;\n address public token1;\n uint32 public constant EPOCH_DURATION = 24 * 3600 * 7;\n\n function setToken(address token, uint256 who) external {\n if (who == 0) token0 = token;\n else token1 = token;\n }\n\n function round(uint256 amount) external pure returns (uint256) {\n return (amount / EPOCH_DURATION) * EPOCH_DURATION;\n }\n}\n" + }, + "contracts/mock/MockVaultManager.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\nimport \"../interfaces/IVaultManager.sol\";\nimport \"../interfaces/ITreasury.sol\";\nimport \"@openzeppelin/contracts/token/ERC20/ERC20.sol\";\n\ncontract MockVaultManager {\n ITreasury public treasury;\n mapping(uint256 => Vault) public vaultData;\n mapping(uint256 => address) public ownerOf;\n uint256 public surplus;\n uint256 public badDebt;\n IAgToken public token;\n address public oracle = address(this);\n\n address public governor;\n address public collateral;\n address public stablecoin;\n uint256 public oracleValue;\n uint256 public interestAccumulator;\n uint256 public collateralFactor;\n uint256 public totalNormalizedDebt;\n\n constructor(address _treasury) {\n treasury = ITreasury(_treasury);\n }\n\n function accrueInterestToTreasury() external returns (uint256, uint256) {\n // Avoid the function to be view\n if (surplus >= badDebt) {\n token.mint(msg.sender, surplus - badDebt);\n }\n return (surplus, badDebt);\n }\n\n function read() external view returns (uint256) {\n return oracleValue;\n }\n\n function setParams(\n address _governor,\n address _collateral,\n address _stablecoin,\n uint256 _oracleValue,\n uint256 _interestAccumulator,\n uint256 _collateralFactor,\n uint256 _totalNormalizedDebt\n ) external {\n governor = _governor;\n collateral = _collateral;\n stablecoin = _stablecoin;\n interestAccumulator = _interestAccumulator;\n collateralFactor = _collateralFactor;\n totalNormalizedDebt = _totalNormalizedDebt;\n oracleValue = _oracleValue;\n }\n\n function setOwner(uint256 vaultID, address owner) external virtual {\n ownerOf[vaultID] = owner;\n }\n\n function setVaultData(uint256 normalizedDebt, uint256 collateralAmount, uint256 vaultID) external {\n vaultData[vaultID].normalizedDebt = normalizedDebt;\n vaultData[vaultID].collateralAmount = collateralAmount;\n }\n\n function isGovernor(address admin) external view returns (bool) {\n return admin == governor;\n }\n\n function setSurplusBadDebt(uint256 _surplus, uint256 _badDebt, IAgToken _token) external {\n surplus = _surplus;\n badDebt = _badDebt;\n token = _token;\n }\n\n function getDebtOut(uint256 vaultID, uint256 amountStablecoins, uint256 senderBorrowFee) external {}\n\n function setTreasury(address _treasury) external {\n treasury = ITreasury(_treasury);\n }\n\n function getVaultDebt(uint256 vaultID) external view returns (uint256) {\n vaultID;\n token;\n return 0;\n }\n\n function createVault(address toVault) external view returns (uint256) {\n toVault;\n token;\n return 0;\n }\n}\n\ncontract MockVaultManagerListing is MockVaultManager {\n // @notice Mapping from owner address to all his vaults\n mapping(address => uint256[]) internal _ownerListVaults;\n\n constructor(address _treasury) MockVaultManager(_treasury) {}\n\n function getUserVaults(address owner) public view returns (uint256[] memory) {\n return _ownerListVaults[owner];\n }\n\n function getUserCollateral(address owner) public view returns (uint256 totalCollateral) {\n uint256[] memory vaultList = _ownerListVaults[owner];\n uint256 vaultListLength = vaultList.length;\n for (uint256 k; k < vaultListLength; ++k) {\n totalCollateral += vaultData[vaultList[k]].collateralAmount;\n }\n return totalCollateral;\n }\n\n function setOwner(uint256 vaultID, address owner) external override {\n if (ownerOf[vaultID] != address(0)) _removeVaultFromList(ownerOf[vaultID], vaultID);\n _ownerListVaults[owner].push(vaultID);\n ownerOf[vaultID] = owner;\n }\n\n /// @notice Remove `vaultID` from `user` stroed vault list\n /// @param user Address to look out for the vault list\n /// @param vaultID VaultId to remove from the list\n /// @dev The vault is necessarily in the list\n function _removeVaultFromList(address user, uint256 vaultID) internal {\n uint256[] storage vaultList = _ownerListVaults[user];\n uint256 vaultListLength = vaultList.length;\n for (uint256 i; i < vaultListLength - 1; ++i) {\n if (vaultList[i] == vaultID) {\n vaultList[i] = vaultList[vaultListLength - 1];\n break;\n }\n }\n vaultList.pop();\n }\n}\n" + }, + "contracts/mock/MockVeBoostProxy.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\nimport \"../interfaces/governance/IVeBoostProxy.sol\";\n\ncontract MockVeBoostProxy is IVeBoostProxy {\n //solhint-disable-next-line\n mapping(address => uint256) public adjusted_balance_of;\n\n constructor() {}\n\n function setBalance(address concerned, uint256 balance) external {\n adjusted_balance_of[concerned] = balance;\n }\n}\n" + }, + "contracts/oracle/BaseOracleChainlinkMulti.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\n/*\n * █ \n ***** ▓▓▓ \n * ▓▓▓▓▓▓▓ \n * ///. ▓▓▓▓▓▓▓▓▓▓▓▓▓ \n ***** //////// ▓▓▓▓▓▓▓ \n * ///////////// ▓▓▓ \n ▓▓ ////////////////// █ ▓▓ \n ▓▓ ▓▓ /////////////////////// ▓▓ ▓▓ \n ▓▓ ▓▓ //////////////////////////// ▓▓ ▓▓ \n ▓▓ ▓▓ /////////▓▓▓///////▓▓▓///////// ▓▓ ▓▓ \n ▓▓ ,////////////////////////////////////// ▓▓ ▓▓ \n ▓▓ ////////////////////////////////////////// ▓▓ \n ▓▓ //////////////////////▓▓▓▓///////////////////// \n ,//////////////////////////////////////////////////// \n .////////////////////////////////////////////////////////// \n .//////////////////////////██.,//////////////////////////█ \n .//////////////////////████..,./////////////////////██ \n ...////////////////███████.....,.////////////////███ \n ,.,////////////████████ ........,///////////████ \n .,.,//////█████████ ,.......///////████ \n ,..//████████ ........./████ \n ..,██████ .....,███ \n .██ ,.,█ \n \n \n \n ▓▓ ▓▓▓▓▓▓▓▓▓▓ ▓▓▓▓▓▓▓▓▓▓ ▓▓ ▓▓▓▓▓▓▓▓▓▓ \n ▓▓▓▓▓▓ ▓▓▓ ▓▓▓ ▓▓▓ ▓▓ ▓▓ ▓▓▓▓ \n ▓▓▓ ▓▓▓ ▓▓▓ ▓▓▓ ▓▓▓ ▓▓▓ ▓▓ ▓▓▓▓▓ \n ▓▓▓ ▓▓ ▓▓▓ ▓▓▓ ▓▓▓▓▓▓▓▓▓▓ ▓▓▓▓▓▓▓▓▓▓ ▓▓▓▓▓▓▓▓▓▓ \n*/\n\npragma solidity ^0.8.12;\n\nimport \"@chainlink/contracts/src/v0.8/interfaces/AggregatorV3Interface.sol\";\n\nimport \"../interfaces/IOracle.sol\";\nimport \"../interfaces/ITreasury.sol\";\n\n/// @title BaseOracleChainlinkMulti\n/// @author Angle Labs, Inc.\n/// @notice Base Contract to be overriden by all contracts of the protocol\n/// @dev This base contract concerns an oracle that uses Chainlink with multiple pools to read from\n/// @dev All gas-efficient implementation of the `OracleChainlinkMulti` contract should inherit from this\nabstract contract BaseOracleChainlinkMulti is IOracle {\n // ========================= Parameters and References =========================\n\n /// @inheritdoc IOracle\n ITreasury public override treasury;\n /// @notice Represent the maximum amount of time (in seconds) between each Chainlink update\n /// before the price feed is considered stale\n uint32 public stalePeriod;\n\n // =================================== Event ===================================\n\n event StalePeriodUpdated(uint32 _stalePeriod);\n\n // =================================== Errors ===================================\n\n error InvalidChainlinkRate();\n error NotGovernorOrGuardian();\n error NotVaultManagerOrGovernor();\n\n /// @notice Constructor for an oracle using Chainlink with multiple pools to read from\n /// @param _stalePeriod Minimum feed update frequency for the oracle to not revert\n /// @param _treasury Treasury associated to the VaultManager which reads from this feed\n constructor(uint32 _stalePeriod, address _treasury) {\n stalePeriod = _stalePeriod;\n treasury = ITreasury(_treasury);\n }\n\n // ============================= Reading Oracles ===============================\n\n /// @inheritdoc IOracle\n function read() external view virtual override returns (uint256 quoteAmount);\n\n /// @inheritdoc IOracle\n function circuitChainlink() public view virtual returns (AggregatorV3Interface[] memory);\n\n /// @notice Reads a Chainlink feed using a quote amount and converts the quote amount to\n /// the out-currency\n /// @param quoteAmount The amount for which to compute the price expressed with base decimal\n /// @param feed Chainlink feed to query\n /// @param multiplied Whether the ratio outputted by Chainlink should be multiplied or divided\n /// to the `quoteAmount`\n /// @param decimals Number of decimals of the corresponding Chainlink pair\n /// @return The `quoteAmount` converted in out-currency\n function _readChainlinkFeed(\n uint256 quoteAmount,\n AggregatorV3Interface feed,\n uint8 multiplied,\n uint256 decimals\n ) internal view returns (uint256) {\n (uint80 roundId, int256 ratio, , uint256 updatedAt, uint80 answeredInRound) = feed.latestRoundData();\n if (ratio <= 0 || roundId > answeredInRound || block.timestamp - updatedAt > stalePeriod)\n revert InvalidChainlinkRate();\n uint256 castedRatio = uint256(ratio);\n // Checking whether we should multiply or divide by the ratio computed\n if (multiplied == 1) return (quoteAmount * castedRatio) / (10 ** decimals);\n else return (quoteAmount * (10 ** decimals)) / castedRatio;\n }\n\n // ======================= Governance Related Functions ========================\n\n /// @notice Changes the stale period\n /// @param _stalePeriod New stale period (in seconds)\n function changeStalePeriod(uint32 _stalePeriod) external {\n if (!treasury.isGovernorOrGuardian(msg.sender)) revert NotGovernorOrGuardian();\n stalePeriod = _stalePeriod;\n emit StalePeriodUpdated(_stalePeriod);\n }\n\n /// @inheritdoc IOracle\n function setTreasury(address _treasury) external override {\n if (!treasury.isVaultManager(msg.sender) && !treasury.isGovernor(msg.sender))\n revert NotVaultManagerOrGovernor();\n treasury = ITreasury(_treasury);\n }\n}\n" + }, + "contracts/oracle/BaseOracleChainlinkMultiTwoFeeds.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\nimport \"@chainlink/contracts/src/v0.8/interfaces/AggregatorV3Interface.sol\";\n\nimport \"./BaseOracleChainlinkMulti.sol\";\n\n/// @title BaseOracleChainlinkMultiTwoFeeds\n/// @author Angle Labs, Inc.\n/// @notice Base contract for an oracle that reads into two Chainlink feeds (including an EUR/USD feed) which both have\n/// 8 decimals\nabstract contract BaseOracleChainlinkMultiTwoFeeds is BaseOracleChainlinkMulti {\n constructor(uint32 _stalePeriod, address _treasury) BaseOracleChainlinkMulti(_stalePeriod, _treasury) {}\n\n /// @notice Returns the quote amount of the oracle contract\n function _getQuoteAmount() internal view virtual returns (uint256) {\n return 10 ** 18;\n }\n\n /// @inheritdoc IOracle\n function read() external view virtual override returns (uint256 quoteAmount) {\n quoteAmount = _getQuoteAmount();\n AggregatorV3Interface[] memory _circuitChainlink = circuitChainlink();\n uint8[2] memory circuitChainIsMultiplied = [1, 0];\n uint8[2] memory chainlinkDecimals = [8, 8];\n uint256 circuitLength = _circuitChainlink.length;\n for (uint256 i; i < circuitLength; ++i) {\n quoteAmount = _readChainlinkFeed(\n quoteAmount,\n _circuitChainlink[i],\n circuitChainIsMultiplied[i],\n chainlinkDecimals[i]\n );\n }\n }\n}\n" + }, + "contracts/oracle/BaseOracleChainlinkOneFeed.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\nimport \"@chainlink/contracts/src/v0.8/interfaces/AggregatorV3Interface.sol\";\n\nimport \"./BaseOracleChainlinkMulti.sol\";\n\n/// @title BaseOracleChainlinkOneFeed\n/// @author Angle Labs, Inc.\n/// @notice Base contract for an oracle that reads into one Chainlink feeds with 8 decimals\nabstract contract BaseOracleChainlinkOneFeed is BaseOracleChainlinkMulti {\n constructor(uint32 _stalePeriod, address _treasury) BaseOracleChainlinkMulti(_stalePeriod, _treasury) {}\n\n /// @notice Returns the quote amount of the oracle contract\n function _getQuoteAmount() internal view virtual returns (uint256) {\n return 10 ** 18;\n }\n\n /// @inheritdoc IOracle\n function read() external view virtual override returns (uint256 quoteAmount) {\n AggregatorV3Interface[] memory _circuitChainlink = circuitChainlink();\n quoteAmount = _readChainlinkFeed(_getQuoteAmount(), _circuitChainlink[0], 1, 8);\n }\n}\n" + }, + "contracts/oracle/implementations/arbitrum/EUR/OracleBTCEURChainlinkArbitrum.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\nimport \"@chainlink/contracts/src/v0.8/interfaces/AggregatorV3Interface.sol\";\n\nimport \"../../../BaseOracleChainlinkMultiTwoFeeds.sol\";\n\n/// @title OracleBTCEURChainlinkArbitrum\n/// @author Angle Labs, Inc.\n/// @notice Gives the price of BTC in Euro in base 18\n/// @dev This contract is built to be deployed on Arbitrum\ncontract OracleBTCEURChainlinkArbitrum is BaseOracleChainlinkMultiTwoFeeds {\n string public constant DESCRIPTION = \"BTC/EUR Oracle\";\n\n constructor(uint32 _stalePeriod, address _treasury) BaseOracleChainlinkMultiTwoFeeds(_stalePeriod, _treasury) {}\n\n /// @inheritdoc IOracle\n function circuitChainlink() public pure override returns (AggregatorV3Interface[] memory) {\n AggregatorV3Interface[] memory _circuitChainlink = new AggregatorV3Interface[](2);\n // Oracle BTC/USD\n _circuitChainlink[0] = AggregatorV3Interface(0x6ce185860a4963106506C203335A2910413708e9);\n // Oracle EUR/USD\n _circuitChainlink[1] = AggregatorV3Interface(0xA14d53bC1F1c0F31B4aA3BD109344E5009051a84);\n return _circuitChainlink;\n }\n}\n" + }, + "contracts/oracle/implementations/arbitrum/EUR/OracleETHEURChainlinkArbitrum.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\nimport \"@chainlink/contracts/src/v0.8/interfaces/AggregatorV3Interface.sol\";\n\nimport \"../../../BaseOracleChainlinkMultiTwoFeeds.sol\";\n\n/// @title OracleETHEURChainlinkArbitrum\n/// @author Angle Labs, Inc.\n/// @notice Gives the price of ETH in Euro in base 18\n/// @dev This contract is built to be deployed on Arbitrum\ncontract OracleETHEURChainlinkArbitrum is BaseOracleChainlinkMultiTwoFeeds {\n string public constant DESCRIPTION = \"ETH/EUR Oracle\";\n\n constructor(uint32 _stalePeriod, address _treasury) BaseOracleChainlinkMultiTwoFeeds(_stalePeriod, _treasury) {}\n\n /// @inheritdoc IOracle\n function circuitChainlink() public pure override returns (AggregatorV3Interface[] memory) {\n AggregatorV3Interface[] memory _circuitChainlink = new AggregatorV3Interface[](2);\n // Oracle ETH/USD\n _circuitChainlink[0] = AggregatorV3Interface(0x639Fe6ab55C921f74e7fac1ee960C0B6293ba612);\n // Oracle EUR/USD\n _circuitChainlink[1] = AggregatorV3Interface(0xA14d53bC1F1c0F31B4aA3BD109344E5009051a84);\n return _circuitChainlink;\n }\n}\n" + }, + "contracts/oracle/implementations/arbitrum/EUR/OracleUSDCEURChainlinkArbitrum.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\nimport \"@chainlink/contracts/src/v0.8/interfaces/AggregatorV3Interface.sol\";\n\nimport \"../../../BaseOracleChainlinkMultiTwoFeeds.sol\";\n\n/// @title OracleUSDCEURChainlinkArbitrum\n/// @author Angle Labs, Inc.\n/// @notice Gives the price of USDC in Euro in base 18\n/// @dev This contract is built to be deployed on Arbitrum\ncontract OracleUSDCEURChainlinkArbitrum is BaseOracleChainlinkMultiTwoFeeds {\n string public constant DESCRIPTION = \"USDC/EUR Oracle\";\n\n constructor(uint32 _stalePeriod, address _treasury) BaseOracleChainlinkMultiTwoFeeds(_stalePeriod, _treasury) {}\n\n /// @inheritdoc IOracle\n function circuitChainlink() public pure override returns (AggregatorV3Interface[] memory) {\n AggregatorV3Interface[] memory _circuitChainlink = new AggregatorV3Interface[](2);\n // Oracle ETH/USD\n _circuitChainlink[0] = AggregatorV3Interface(0x50834F3163758fcC1Df9973b6e91f0F0F0434aD3);\n // Oracle EUR/USD\n _circuitChainlink[1] = AggregatorV3Interface(0xA14d53bC1F1c0F31B4aA3BD109344E5009051a84);\n return _circuitChainlink;\n }\n}\n" + }, + "contracts/oracle/implementations/avalanche/EUR/OracleAVAXEURChainlinkAvalanche.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\nimport \"@chainlink/contracts/src/v0.8/interfaces/AggregatorV3Interface.sol\";\n\nimport \"../../../BaseOracleChainlinkMultiTwoFeeds.sol\";\n\n/// @title OracleAVAXEURChainlinkAvalanche\n/// @author Angle Labs, Inc.\n/// @notice Gives the price of AVAX in Euro in base 18\n/// @dev This contract is built to be deployed on Avalanche\ncontract OracleAVAXEURChainlinkAvalanche is BaseOracleChainlinkMultiTwoFeeds {\n string public constant DESCRIPTION = \"AVAX/EUR Oracle\";\n\n constructor(uint32 _stalePeriod, address _treasury) BaseOracleChainlinkMultiTwoFeeds(_stalePeriod, _treasury) {}\n\n /// @inheritdoc IOracle\n function circuitChainlink() public pure override returns (AggregatorV3Interface[] memory) {\n AggregatorV3Interface[] memory _circuitChainlink = new AggregatorV3Interface[](2);\n // Oracle AVAX/USD\n _circuitChainlink[0] = AggregatorV3Interface(0x0A77230d17318075983913bC2145DB16C7366156);\n // Oracle EUR/USD\n _circuitChainlink[1] = AggregatorV3Interface(0x192f2DBA961Bb0277520C082d6bfa87D5961333E);\n return _circuitChainlink;\n }\n}\n" + }, + "contracts/oracle/implementations/avalanche/EUR/OracleUSDCEURChainlinkAvalanche.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\nimport \"@chainlink/contracts/src/v0.8/interfaces/AggregatorV3Interface.sol\";\n\nimport \"../../../BaseOracleChainlinkMultiTwoFeeds.sol\";\n\n/// @title OracleUSDCEURChainlinkAvalanche\n/// @author Angle Labs, Inc.\n/// @notice Gives the price of USDC in Euro in base 18\n/// @dev This contract is built to be deployed on Avalanche\ncontract OracleUSDCEURChainlinkAvalanche is BaseOracleChainlinkMultiTwoFeeds {\n string public constant DESCRIPTION = \"USDC/EUR Oracle\";\n\n constructor(uint32 _stalePeriod, address _treasury) BaseOracleChainlinkMultiTwoFeeds(_stalePeriod, _treasury) {}\n\n /// @inheritdoc IOracle\n function circuitChainlink() public pure override returns (AggregatorV3Interface[] memory) {\n AggregatorV3Interface[] memory _circuitChainlink = new AggregatorV3Interface[](2);\n // Oracle USDC/USD\n _circuitChainlink[0] = AggregatorV3Interface(0xF096872672F44d6EBA71458D74fe67F9a77a23B9);\n // Oracle EUR/USD\n _circuitChainlink[1] = AggregatorV3Interface(0x192f2DBA961Bb0277520C082d6bfa87D5961333E);\n return _circuitChainlink;\n }\n}\n" + }, + "contracts/oracle/implementations/mainnet/EUR/OracleBTCEURChainlink.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\nimport \"@chainlink/contracts/src/v0.8/interfaces/AggregatorV3Interface.sol\";\n\nimport \"../../../BaseOracleChainlinkMultiTwoFeeds.sol\";\n\n/// @title OracleBTCEURChainlink\n/// @author Angle Labs, Inc.\n/// @notice Gives the price of BTC in Euro in base 18\ncontract OracleBTCEURChainlink is BaseOracleChainlinkMultiTwoFeeds {\n string public constant DESCRIPTION = \"BTC/EUR Oracle\";\n\n constructor(uint32 _stalePeriod, address _treasury) BaseOracleChainlinkMultiTwoFeeds(_stalePeriod, _treasury) {}\n\n /// @inheritdoc IOracle\n function circuitChainlink() public pure override returns (AggregatorV3Interface[] memory) {\n AggregatorV3Interface[] memory _circuitChainlink = new AggregatorV3Interface[](2);\n // Oracle BTC/USD\n _circuitChainlink[0] = AggregatorV3Interface(0xF4030086522a5bEEa4988F8cA5B36dbC97BeE88c);\n // Oracle EUR/USD\n _circuitChainlink[1] = AggregatorV3Interface(0xb49f677943BC038e9857d61E7d053CaA2C1734C1);\n return _circuitChainlink;\n }\n}\n" + }, + "contracts/oracle/implementations/mainnet/EUR/OracleCBETHEURChainlink.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\nimport \"@chainlink/contracts/src/v0.8/interfaces/AggregatorV3Interface.sol\";\n\nimport \"../../../BaseOracleChainlinkMultiTwoFeeds.sol\";\n\n/// @title OracleCBETHEURChainlink\n/// @author Angle Labs, Inc.\n/// @notice Gives the price of cbETH in Euro in base 18\ncontract OracleCBETHEURChainlink is BaseOracleChainlinkMultiTwoFeeds {\n string public constant DESCRIPTION = \"cbETH/EUR Oracle\";\n\n constructor(uint32 _stalePeriod, address _treasury) BaseOracleChainlinkMultiTwoFeeds(_stalePeriod, _treasury) {}\n\n /// @inheritdoc IOracle\n function circuitChainlink() public pure override returns (AggregatorV3Interface[] memory) {\n AggregatorV3Interface[] memory _circuitChainlink = new AggregatorV3Interface[](3);\n // Oracle cbETH/ETH\n _circuitChainlink[0] = AggregatorV3Interface(0xF017fcB346A1885194689bA23Eff2fE6fA5C483b);\n // Oracle ETH/USD\n _circuitChainlink[1] = AggregatorV3Interface(0x5f4eC3Df9cbd43714FE2740f5E3616155c5b8419);\n // Oracle EUR/USD\n _circuitChainlink[2] = AggregatorV3Interface(0xb49f677943BC038e9857d61E7d053CaA2C1734C1);\n return _circuitChainlink;\n }\n\n /// @inheritdoc BaseOracleChainlinkMultiTwoFeeds\n function read() external view virtual override returns (uint256 quoteAmount) {\n quoteAmount = _getQuoteAmount();\n AggregatorV3Interface[] memory _circuitChainlink = circuitChainlink();\n uint8[3] memory circuitChainIsMultiplied = [1, 1, 0];\n uint8[3] memory chainlinkDecimals = [18, 8, 8];\n uint256 circuitLength = _circuitChainlink.length;\n for (uint256 i; i < circuitLength; ++i) {\n quoteAmount = _readChainlinkFeed(\n quoteAmount,\n _circuitChainlink[i],\n circuitChainIsMultiplied[i],\n chainlinkDecimals[i]\n );\n }\n }\n}\n" + }, + "contracts/oracle/implementations/mainnet/EUR/OracleETHEURChainlink.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\nimport \"@chainlink/contracts/src/v0.8/interfaces/AggregatorV3Interface.sol\";\n\nimport \"../../../BaseOracleChainlinkMultiTwoFeeds.sol\";\n\n/// @title OracleETHEURChainlink\n/// @author Angle Labs, Inc.\n/// @notice Gives the price of ETH in Euro in base 18\ncontract OracleETHEURChainlink is BaseOracleChainlinkMultiTwoFeeds {\n string public constant DESCRIPTION = \"ETH/EUR Oracle\";\n\n constructor(uint32 _stalePeriod, address _treasury) BaseOracleChainlinkMultiTwoFeeds(_stalePeriod, _treasury) {}\n\n /// @inheritdoc IOracle\n function circuitChainlink() public pure override returns (AggregatorV3Interface[] memory) {\n AggregatorV3Interface[] memory _circuitChainlink = new AggregatorV3Interface[](2);\n // Oracle ETH/USD\n _circuitChainlink[0] = AggregatorV3Interface(0x5f4eC3Df9cbd43714FE2740f5E3616155c5b8419);\n // Oracle EUR/USD\n _circuitChainlink[1] = AggregatorV3Interface(0xb49f677943BC038e9857d61E7d053CaA2C1734C1);\n return _circuitChainlink;\n }\n}\n" + }, + "contracts/oracle/implementations/mainnet/EUR/OracleHIGHEURChainlink.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\nimport \"@chainlink/contracts/src/v0.8/interfaces/AggregatorV3Interface.sol\";\n\nimport \"../../../BaseOracleChainlinkMultiTwoFeeds.sol\";\n\n/// @title OracleHIGHEURChainlink\n/// @author Angle Labs, Inc.\n/// @notice Gives the price of HIGH in Euro in base 18\ncontract OracleHIGHEURChainlink is BaseOracleChainlinkMultiTwoFeeds {\n string public constant DESCRIPTION = \"HIGH/EUR Oracle\";\n\n constructor(uint32 _stalePeriod, address _treasury) BaseOracleChainlinkMultiTwoFeeds(_stalePeriod, _treasury) {}\n\n /// @inheritdoc IOracle\n function circuitChainlink() public pure override returns (AggregatorV3Interface[] memory) {\n AggregatorV3Interface[] memory _circuitChainlink = new AggregatorV3Interface[](1);\n // Oracle HIGH/EUR\n _circuitChainlink[0] = AggregatorV3Interface(0x9E8E794ad6Ecdb6d5c7eaBE059D30E907F58859b);\n return _circuitChainlink;\n }\n\n /// @inheritdoc BaseOracleChainlinkMultiTwoFeeds\n function read() external view override returns (uint256 quoteAmount) {\n quoteAmount = _readChainlinkFeed(_getQuoteAmount(), circuitChainlink()[0], 1, 8);\n }\n}\n" + }, + "contracts/oracle/implementations/mainnet/EUR/OracleIB01EURChainlink.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\nimport \"@chainlink/contracts/src/v0.8/interfaces/AggregatorV3Interface.sol\";\n\nimport \"../../../BaseOracleChainlinkMultiTwoFeeds.sol\";\n\n/// @title OracleIB01EURChainlink\n/// @author Angle Labs, Inc.\n/// @notice Gives the price of IB01 in Euro in base 18\ncontract OracleIB01EURChainlink is BaseOracleChainlinkMultiTwoFeeds {\n string public constant DESCRIPTION = \"IB01/EUR Oracle\";\n\n constructor(uint32 _stalePeriod, address _treasury) BaseOracleChainlinkMultiTwoFeeds(_stalePeriod, _treasury) {}\n\n /// @inheritdoc IOracle\n function circuitChainlink() public pure override returns (AggregatorV3Interface[] memory) {\n AggregatorV3Interface[] memory _circuitChainlink = new AggregatorV3Interface[](2);\n // Oracle IB01/USD\n _circuitChainlink[0] = AggregatorV3Interface(0x32d1463EB53b73C095625719Afa544D5426354cB);\n // Oracle EUR/USD\n _circuitChainlink[1] = AggregatorV3Interface(0xb49f677943BC038e9857d61E7d053CaA2C1734C1);\n return _circuitChainlink;\n }\n}\n" + }, + "contracts/oracle/implementations/mainnet/EUR/OracleLUSDEURChainlink.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\nimport \"@chainlink/contracts/src/v0.8/interfaces/AggregatorV3Interface.sol\";\n\nimport \"../../../BaseOracleChainlinkMultiTwoFeeds.sol\";\n\n/// @title OracleLUSDEURChainlink\n/// @author Angle Labs, Inc.\n/// @notice Gives the price of LUSD in Euro in base 18\ncontract OracleLUSDEURChainlink is BaseOracleChainlinkMultiTwoFeeds {\n string public constant DESCRIPTION = \"LUSD/EUR Oracle\";\n\n constructor(uint32 _stalePeriod, address _treasury) BaseOracleChainlinkMultiTwoFeeds(_stalePeriod, _treasury) {}\n\n /// @inheritdoc IOracle\n function circuitChainlink() public pure override returns (AggregatorV3Interface[] memory) {\n AggregatorV3Interface[] memory _circuitChainlink = new AggregatorV3Interface[](2);\n // Oracle LUSD/USD\n _circuitChainlink[0] = AggregatorV3Interface(0x3D7aE7E594f2f2091Ad8798313450130d0Aba3a0);\n // Oracle EUR/USD\n _circuitChainlink[1] = AggregatorV3Interface(0xb49f677943BC038e9857d61E7d053CaA2C1734C1);\n return _circuitChainlink;\n }\n}\n" + }, + "contracts/oracle/implementations/mainnet/EUR/OracleUSDCEURChainlink.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\nimport \"@chainlink/contracts/src/v0.8/interfaces/AggregatorV3Interface.sol\";\n\nimport \"../../../BaseOracleChainlinkMultiTwoFeeds.sol\";\n\n/// @title OracleUSDCEURChainlink\n/// @author Angle Labs, Inc.\n/// @notice Gives the price of USDC in Euro in base 18\ncontract OracleUSDCEURChainlink is BaseOracleChainlinkMultiTwoFeeds {\n string public constant DESCRIPTION = \"USDC/EUR Oracle\";\n\n constructor(uint32 _stalePeriod, address _treasury) BaseOracleChainlinkMultiTwoFeeds(_stalePeriod, _treasury) {}\n\n /// @inheritdoc IOracle\n function circuitChainlink() public pure override returns (AggregatorV3Interface[] memory) {\n AggregatorV3Interface[] memory _circuitChainlink = new AggregatorV3Interface[](2);\n // Oracle USDC/USD\n _circuitChainlink[0] = AggregatorV3Interface(0x8fFfFfd4AfB6115b954Bd326cbe7B4BA576818f6);\n // Oracle EUR/USD\n _circuitChainlink[1] = AggregatorV3Interface(0xb49f677943BC038e9857d61E7d053CaA2C1734C1);\n return _circuitChainlink;\n }\n}\n" + }, + "contracts/oracle/implementations/mainnet/EUR/OracleWSTETHEURChainlink.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\nimport \"@chainlink/contracts/src/v0.8/interfaces/AggregatorV3Interface.sol\";\n\nimport \"../../../BaseOracleChainlinkMultiTwoFeeds.sol\";\nimport \"../../../../interfaces/external/lido/IStETH.sol\";\n\n/// @title OracleWSTETHEURChainlink\n/// @author Angle Labs, Inc.\n/// @notice Gives the price of wSTETH in Euro in base 18\ncontract OracleWSTETHEURChainlink is BaseOracleChainlinkMultiTwoFeeds {\n string public constant DESCRIPTION = \"wSTETH/EUR Oracle\";\n IStETH public constant STETH = IStETH(0xae7ab96520DE3A18E5e111B5EaAb095312D7fE84);\n\n constructor(uint32 _stalePeriod, address _treasury) BaseOracleChainlinkMultiTwoFeeds(_stalePeriod, _treasury) {}\n\n /// @inheritdoc IOracle\n function circuitChainlink() public pure override returns (AggregatorV3Interface[] memory) {\n AggregatorV3Interface[] memory _circuitChainlink = new AggregatorV3Interface[](2);\n // Oracle stETH/USD\n _circuitChainlink[0] = AggregatorV3Interface(0xCfE54B5cD566aB89272946F602D76Ea879CAb4a8);\n // Oracle EUR/USD\n _circuitChainlink[1] = AggregatorV3Interface(0xb49f677943BC038e9857d61E7d053CaA2C1734C1);\n return _circuitChainlink;\n }\n\n /// @inheritdoc BaseOracleChainlinkMultiTwoFeeds\n function _getQuoteAmount() internal view override returns (uint256) {\n return STETH.getPooledEthByShares(1 ether);\n }\n}\n" + }, + "contracts/oracle/implementations/mainnet/USD/OracleWSTETHUSDChainlink.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\nimport \"@chainlink/contracts/src/v0.8/interfaces/AggregatorV3Interface.sol\";\n\nimport \"../../../BaseOracleChainlinkOneFeed.sol\";\nimport \"../../../../interfaces/external/lido/IStETH.sol\";\n\n/// @title OracleWSTETHUSDChainlink\n/// @author Angle Labs, Inc.\n/// @notice Gives the price of wSTETH in USD in base 18\ncontract OracleWSTETHUSDChainlink is BaseOracleChainlinkOneFeed {\n string public constant DESCRIPTION = \"wSTETH/USD Oracle\";\n IStETH public constant STETH = IStETH(0xae7ab96520DE3A18E5e111B5EaAb095312D7fE84);\n\n constructor(uint32 _stalePeriod, address _treasury) BaseOracleChainlinkOneFeed(_stalePeriod, _treasury) {}\n\n /// @inheritdoc IOracle\n function circuitChainlink() public pure override returns (AggregatorV3Interface[] memory) {\n AggregatorV3Interface[] memory _circuitChainlink = new AggregatorV3Interface[](1);\n // Oracle stETH/USD\n _circuitChainlink[0] = AggregatorV3Interface(0xCfE54B5cD566aB89272946F602D76Ea879CAb4a8);\n return _circuitChainlink;\n }\n\n /// @inheritdoc BaseOracleChainlinkOneFeed\n function _getQuoteAmount() internal view override returns (uint256) {\n return STETH.getPooledEthByShares(1 ether);\n }\n}\n" + }, + "contracts/oracle/implementations/mainnet/XAU/OracleETHXAUChainlink.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\nimport \"@chainlink/contracts/src/v0.8/interfaces/AggregatorV3Interface.sol\";\n\nimport \"../../../BaseOracleChainlinkMultiTwoFeeds.sol\";\n\n/// @title OracleETHXAUChainlink\n/// @author Angle Labs, Inc.\n/// @notice Gives the price of ETH in XAU in base 18\ncontract OracleETHXAUChainlink is BaseOracleChainlinkMultiTwoFeeds {\n string public constant DESCRIPTION = \"ETH/GOLD Oracle\";\n\n constructor(uint32 _stalePeriod, address _treasury) BaseOracleChainlinkMultiTwoFeeds(_stalePeriod, _treasury) {}\n\n /// @inheritdoc IOracle\n function circuitChainlink() public pure override returns (AggregatorV3Interface[] memory) {\n AggregatorV3Interface[] memory _circuitChainlink = new AggregatorV3Interface[](2);\n // Oracle ETH/USD\n _circuitChainlink[0] = AggregatorV3Interface(0x5f4eC3Df9cbd43714FE2740f5E3616155c5b8419);\n // Oracle XAU/USD\n _circuitChainlink[1] = AggregatorV3Interface(0x214eD9Da11D2fbe465a6fc601a91E62EbEc1a0D6);\n return _circuitChainlink;\n }\n}\n" + }, + "contracts/oracle/implementations/mainnet/XAU/OracleLUSDXAUChainlink.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\nimport \"@chainlink/contracts/src/v0.8/interfaces/AggregatorV3Interface.sol\";\n\nimport \"../../../BaseOracleChainlinkMultiTwoFeeds.sol\";\n\n/// @title OracleLUSDXAUChainlink\n/// @author Angle Labs, Inc.\n/// @notice Gives the price of LUSD in XAU in base 18\ncontract OracleLUSDXAUChainlink is BaseOracleChainlinkMultiTwoFeeds {\n string public constant DESCRIPTION = \"LUSD/GOLD Oracle\";\n\n constructor(uint32 _stalePeriod, address _treasury) BaseOracleChainlinkMultiTwoFeeds(_stalePeriod, _treasury) {}\n\n /// @inheritdoc IOracle\n function circuitChainlink() public pure override returns (AggregatorV3Interface[] memory) {\n AggregatorV3Interface[] memory _circuitChainlink = new AggregatorV3Interface[](2);\n // Oracle LUSD/USD\n _circuitChainlink[0] = AggregatorV3Interface(0x3D7aE7E594f2f2091Ad8798313450130d0Aba3a0);\n // Oracle XAU/USD\n _circuitChainlink[1] = AggregatorV3Interface(0x214eD9Da11D2fbe465a6fc601a91E62EbEc1a0D6);\n return _circuitChainlink;\n }\n}\n" + }, + "contracts/oracle/implementations/mainnet/XAU/OracleUSDCXAUChainlink.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\nimport \"@chainlink/contracts/src/v0.8/interfaces/AggregatorV3Interface.sol\";\n\nimport \"../../../BaseOracleChainlinkMultiTwoFeeds.sol\";\n\n/// @title OracleUSDCXAUChainlink\n/// @author Angle Labs, Inc.\n/// @notice Gives the price of USDC in XAU in base 18\ncontract OracleUSDCXAUChainlink is BaseOracleChainlinkMultiTwoFeeds {\n string public constant DESCRIPTION = \"USDC/GOLD Oracle\";\n\n constructor(uint32 _stalePeriod, address _treasury) BaseOracleChainlinkMultiTwoFeeds(_stalePeriod, _treasury) {}\n\n /// @inheritdoc IOracle\n function circuitChainlink() public pure override returns (AggregatorV3Interface[] memory) {\n AggregatorV3Interface[] memory _circuitChainlink = new AggregatorV3Interface[](2);\n // Oracle USDC/USD\n _circuitChainlink[0] = AggregatorV3Interface(0x8fFfFfd4AfB6115b954Bd326cbe7B4BA576818f6);\n // Oracle XAU/USD\n _circuitChainlink[1] = AggregatorV3Interface(0x214eD9Da11D2fbe465a6fc601a91E62EbEc1a0D6);\n return _circuitChainlink;\n }\n}\n" + }, + "contracts/oracle/implementations/mainnet/XAU/OracleWSTETHXAUChainlink.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\nimport \"@chainlink/contracts/src/v0.8/interfaces/AggregatorV3Interface.sol\";\n\nimport \"../../../BaseOracleChainlinkMultiTwoFeeds.sol\";\nimport \"../../../../interfaces/external/lido/IStETH.sol\";\n\n/// @title OracleWSTETHXAUChainlink\n/// @author Angle Labs, Inc.\n/// @notice Gives the price of wSTETH in XAU in base 18\ncontract OracleWSTETHXAUChainlink is BaseOracleChainlinkMultiTwoFeeds {\n string public constant DESCRIPTION = \"wSTETH/XAU Oracle\";\n IStETH public constant STETH = IStETH(0xae7ab96520DE3A18E5e111B5EaAb095312D7fE84);\n\n constructor(uint32 _stalePeriod, address _treasury) BaseOracleChainlinkMultiTwoFeeds(_stalePeriod, _treasury) {}\n\n /// @inheritdoc IOracle\n function circuitChainlink() public pure override returns (AggregatorV3Interface[] memory) {\n AggregatorV3Interface[] memory _circuitChainlink = new AggregatorV3Interface[](2);\n // Oracle stETH/USD\n _circuitChainlink[0] = AggregatorV3Interface(0xCfE54B5cD566aB89272946F602D76Ea879CAb4a8);\n // Oracle XAU/USD\n _circuitChainlink[1] = AggregatorV3Interface(0x214eD9Da11D2fbe465a6fc601a91E62EbEc1a0D6);\n return _circuitChainlink;\n }\n\n /// @inheritdoc BaseOracleChainlinkMultiTwoFeeds\n function _getQuoteAmount() internal view override returns (uint256) {\n return STETH.getPooledEthByShares(1 ether);\n }\n}\n" + }, + "contracts/oracle/implementations/optimism/EUR/OracleETHEURChainlinkOptimism.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\nimport \"@chainlink/contracts/src/v0.8/interfaces/AggregatorV3Interface.sol\";\n\nimport \"../../../BaseOracleChainlinkMultiTwoFeeds.sol\";\n\n/// @title OracleETHEURChainlinkOptimism\n/// @author Angle Labs, Inc.\n/// @notice Gives the price of ETH in Euro in base 18\n/// @dev This contract is built to be deployed on Optimism\ncontract OracleETHEURChainlinkOptimism is BaseOracleChainlinkMultiTwoFeeds {\n string public constant DESCRIPTION = \"ETH/EUR Oracle\";\n\n constructor(uint32 _stalePeriod, address _treasury) BaseOracleChainlinkMultiTwoFeeds(_stalePeriod, _treasury) {}\n\n /// @inheritdoc IOracle\n function circuitChainlink() public pure override returns (AggregatorV3Interface[] memory) {\n AggregatorV3Interface[] memory _circuitChainlink = new AggregatorV3Interface[](2);\n // Oracle ETH/USD\n _circuitChainlink[0] = AggregatorV3Interface(0x13e3Ee699D1909E989722E753853AE30b17e08c5);\n // Oracle EUR/USD\n _circuitChainlink[1] = AggregatorV3Interface(0x3626369857A10CcC6cc3A6e4f5C2f5984a519F20);\n return _circuitChainlink;\n }\n}\n" + }, + "contracts/oracle/implementations/optimism/EUR/OracleOPEURChainlinkOptimism.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\nimport \"@chainlink/contracts/src/v0.8/interfaces/AggregatorV3Interface.sol\";\n\nimport \"../../../BaseOracleChainlinkMultiTwoFeeds.sol\";\n\n/// @title OracleOPEURChainlinkOptimism\n/// @author Angle Labs, Inc.\n/// @notice Gives the price of OP in Euro in base 18\n/// @dev This contract is built to be deployed on Optimism\ncontract OracleOPEURChainlinkOptimism is BaseOracleChainlinkMultiTwoFeeds {\n string public constant DESCRIPTION = \"OP/EUR Oracle\";\n\n constructor(uint32 _stalePeriod, address _treasury) BaseOracleChainlinkMultiTwoFeeds(_stalePeriod, _treasury) {}\n\n /// @inheritdoc IOracle\n function circuitChainlink() public pure override returns (AggregatorV3Interface[] memory) {\n AggregatorV3Interface[] memory _circuitChainlink = new AggregatorV3Interface[](2);\n // Oracle OP/USD\n _circuitChainlink[0] = AggregatorV3Interface(0x0D276FC14719f9292D5C1eA2198673d1f4269246);\n // Oracle EUR/USD\n _circuitChainlink[1] = AggregatorV3Interface(0x3626369857A10CcC6cc3A6e4f5C2f5984a519F20);\n return _circuitChainlink;\n }\n}\n" + }, + "contracts/oracle/implementations/optimism/EUR/OracleUSDCEURChainlinkOptimism.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\nimport \"@chainlink/contracts/src/v0.8/interfaces/AggregatorV3Interface.sol\";\n\nimport \"../../../BaseOracleChainlinkMultiTwoFeeds.sol\";\n\n/// @title OracleUSDCEURChainlinkOptimism\n/// @author Angle Labs, Inc.\n/// @notice Gives the price of USDC in Euro in base 18\n/// @dev This contract is built to be deployed on Optimism\ncontract OracleUSDCEURChainlinkOptimism is BaseOracleChainlinkMultiTwoFeeds {\n string public constant DESCRIPTION = \"USDC/EUR Oracle\";\n\n constructor(uint32 _stalePeriod, address _treasury) BaseOracleChainlinkMultiTwoFeeds(_stalePeriod, _treasury) {}\n\n /// @inheritdoc IOracle\n function circuitChainlink() public pure override returns (AggregatorV3Interface[] memory) {\n AggregatorV3Interface[] memory _circuitChainlink = new AggregatorV3Interface[](2);\n // Oracle USDC/USD\n _circuitChainlink[0] = AggregatorV3Interface(0x16a9FA2FDa030272Ce99B29CF780dFA30361E0f3);\n // Oracle EUR/USD\n _circuitChainlink[1] = AggregatorV3Interface(0x3626369857A10CcC6cc3A6e4f5C2f5984a519F20);\n return _circuitChainlink;\n }\n}\n" + }, + "contracts/oracle/implementations/polygon/EUR/OracleBTCEURChainlinkPolygon.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\nimport \"@chainlink/contracts/src/v0.8/interfaces/AggregatorV3Interface.sol\";\n\nimport \"../../../BaseOracleChainlinkMultiTwoFeeds.sol\";\n\n/// @title OracleBTCEURChainlinkPolygon\n/// @author Angle Labs, Inc.\n/// @notice Gives the price of BTC in Euro in base 18\n/// @dev This contract is built to be deployed on Polygon\ncontract OracleBTCEURChainlinkPolygon is BaseOracleChainlinkMultiTwoFeeds {\n string public constant DESCRIPTION = \"BTC/EUR Oracle\";\n\n constructor(uint32 _stalePeriod, address _treasury) BaseOracleChainlinkMultiTwoFeeds(_stalePeriod, _treasury) {}\n\n /// @inheritdoc IOracle\n function circuitChainlink() public pure override returns (AggregatorV3Interface[] memory) {\n AggregatorV3Interface[] memory _circuitChainlink = new AggregatorV3Interface[](2);\n // Oracle BTC/USD\n _circuitChainlink[0] = AggregatorV3Interface(0xc907E116054Ad103354f2D350FD2514433D57F6f);\n // Oracle EUR/USD\n _circuitChainlink[1] = AggregatorV3Interface(0x73366Fe0AA0Ded304479862808e02506FE556a98);\n return _circuitChainlink;\n }\n}\n" + }, + "contracts/oracle/implementations/polygon/EUR/OracleETHEURChainlinkPolygon.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\nimport \"@chainlink/contracts/src/v0.8/interfaces/AggregatorV3Interface.sol\";\n\nimport \"../../../BaseOracleChainlinkMultiTwoFeeds.sol\";\n\n/// @title OracleETHEURChainlinkPolygon\n/// @author Angle Labs, Inc.\n/// @notice Gives the price of ETH in Euro in base 18\n/// @dev This contract is built to be deployed on Polygon\ncontract OracleETHEURChainlinkPolygon is BaseOracleChainlinkMultiTwoFeeds {\n string public constant DESCRIPTION = \"ETH/EUR Oracle\";\n\n constructor(uint32 _stalePeriod, address _treasury) BaseOracleChainlinkMultiTwoFeeds(_stalePeriod, _treasury) {}\n\n /// @inheritdoc IOracle\n function circuitChainlink() public pure override returns (AggregatorV3Interface[] memory) {\n AggregatorV3Interface[] memory _circuitChainlink = new AggregatorV3Interface[](2);\n // Oracle ETH/USD\n _circuitChainlink[0] = AggregatorV3Interface(0xF9680D99D6C9589e2a93a78A04A279e509205945);\n // Oracle EUR/USD\n _circuitChainlink[1] = AggregatorV3Interface(0x73366Fe0AA0Ded304479862808e02506FE556a98);\n return _circuitChainlink;\n }\n}\n" + }, + "contracts/oracle/implementations/polygon/EUR/OracleMAIEURChainlinkPolygon.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\nimport \"@chainlink/contracts/src/v0.8/interfaces/AggregatorV3Interface.sol\";\n\nimport \"../../../BaseOracleChainlinkMultiTwoFeeds.sol\";\n\n/// @title OracleMAIEURChainlinkPolygon\n/// @author Angle Labs, Inc.\n/// @notice Gives the price of MAI in Euro in base 18\n/// @dev This contract is built to be deployed on Polygon\ncontract OracleMAIEURChainlinkPolygon is BaseOracleChainlinkMultiTwoFeeds {\n string public constant DESCRIPTION = \"MAI/EUR Oracle\";\n\n constructor(uint32 _stalePeriod, address _treasury) BaseOracleChainlinkMultiTwoFeeds(_stalePeriod, _treasury) {}\n\n /// @inheritdoc IOracle\n function circuitChainlink() public pure override returns (AggregatorV3Interface[] memory) {\n AggregatorV3Interface[] memory _circuitChainlink = new AggregatorV3Interface[](2);\n // Oracle MAI/USD\n _circuitChainlink[0] = AggregatorV3Interface(0xd8d483d813547CfB624b8Dc33a00F2fcbCd2D428);\n // Oracle EUR/USD\n _circuitChainlink[1] = AggregatorV3Interface(0x73366Fe0AA0Ded304479862808e02506FE556a98);\n return _circuitChainlink;\n }\n}\n" + }, + "contracts/oracle/implementations/polygon/EUR/OracleMATICEURChainlinkPolygon.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\nimport \"@chainlink/contracts/src/v0.8/interfaces/AggregatorV3Interface.sol\";\n\nimport \"../../../BaseOracleChainlinkMultiTwoFeeds.sol\";\n\n/// @title OracleMATICEURChainlinkPolygon\n/// @author Angle Labs, Inc.\n/// @notice Gives the price of MATIC in Euro in base 18\n/// @dev This contract is built to be deployed on Polygon\ncontract OracleMATICEURChainlinkPolygon is BaseOracleChainlinkMultiTwoFeeds {\n string public constant DESCRIPTION = \"MATIC/EUR Oracle\";\n\n constructor(uint32 _stalePeriod, address _treasury) BaseOracleChainlinkMultiTwoFeeds(_stalePeriod, _treasury) {}\n\n /// @inheritdoc IOracle\n function circuitChainlink() public pure override returns (AggregatorV3Interface[] memory) {\n AggregatorV3Interface[] memory _circuitChainlink = new AggregatorV3Interface[](2);\n // Oracle MATIC/USD\n _circuitChainlink[0] = AggregatorV3Interface(0xAB594600376Ec9fD91F8e885dADF0CE036862dE0);\n // Oracle EUR/USD\n _circuitChainlink[1] = AggregatorV3Interface(0x73366Fe0AA0Ded304479862808e02506FE556a98);\n return _circuitChainlink;\n }\n}\n" + }, + "contracts/oracle/implementations/polygon/EUR/OracleUSDCEURChainlinkPolygon.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\nimport \"../../../BaseOracleChainlinkMultiTwoFeeds.sol\";\n\n/// @title OracleUSDCEURChainlinkPolygon\n/// @author Angle Labs, Inc.\n/// @notice Gives the price of USDC in Euro in base 18\n/// @dev This contract is built to be deployed on Polygon\ncontract OracleUSDCEURChainlinkPolygon is BaseOracleChainlinkMultiTwoFeeds {\n string public constant DESCRIPTION = \"USDC/EUR Oracle\";\n\n constructor(uint32 _stalePeriod, address _treasury) BaseOracleChainlinkMultiTwoFeeds(_stalePeriod, _treasury) {}\n\n /// @inheritdoc IOracle\n function circuitChainlink() public pure override returns (AggregatorV3Interface[] memory) {\n AggregatorV3Interface[] memory _circuitChainlink = new AggregatorV3Interface[](2);\n // Oracle USDC/USD\n _circuitChainlink[0] = AggregatorV3Interface(0xfE4A8cc5b5B2366C1B58Bea3858e81843581b2F7);\n // Oracle EUR/USD\n _circuitChainlink[1] = AggregatorV3Interface(0x73366Fe0AA0Ded304479862808e02506FE556a98);\n return _circuitChainlink;\n }\n}\n" + }, + "contracts/oracle/implementations/polygon/XAU/OracleETHXAUChainlinkPolygon.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\nimport \"@chainlink/contracts/src/v0.8/interfaces/AggregatorV3Interface.sol\";\n\nimport \"../../../BaseOracleChainlinkMultiTwoFeeds.sol\";\n\n/// @title OracleETHXAUChainlinkPolygon\n/// @author Angle Labs, Inc.\n/// @notice Gives the price of ETH in XAU in base 18\n/// @dev This contract is built to be deployed on Polygon\ncontract OracleETHXAUChainlinkPolygon is BaseOracleChainlinkMultiTwoFeeds {\n string public constant DESCRIPTION = \"ETH/GOLD Oracle\";\n\n constructor(uint32 _stalePeriod, address _treasury) BaseOracleChainlinkMultiTwoFeeds(_stalePeriod, _treasury) {}\n\n /// @inheritdoc IOracle\n function circuitChainlink() public pure override returns (AggregatorV3Interface[] memory) {\n AggregatorV3Interface[] memory _circuitChainlink = new AggregatorV3Interface[](2);\n // Oracle ETH/USD\n _circuitChainlink[0] = AggregatorV3Interface(0xF9680D99D6C9589e2a93a78A04A279e509205945);\n // Oracle XAU/USD\n _circuitChainlink[1] = AggregatorV3Interface(0x0C466540B2ee1a31b441671eac0ca886e051E410);\n return _circuitChainlink;\n }\n}\n" + }, + "contracts/oracle/KeeperRegistry.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\nimport \"@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol\";\nimport \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\nimport \"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\";\n\nimport \"../interfaces/ICoreBorrow.sol\";\nimport \"../interfaces/IKeeperRegistry.sol\";\n\n/// @title KeeperRegistry\n/// @notice Maintains a mapping of keepers authorized to use the core module just after oracle updates\n/// @author Angle Labs, Inc.\ncontract KeeperRegistry is Initializable, IKeeperRegistry {\n using SafeERC20 for IERC20;\n\n /// @notice Contract handling access control\n ICoreBorrow public coreBorrow;\n\n /// @notice Trusted EOAs - needs to be tx.origin\n mapping(address => uint256) public trusted;\n\n uint256[48] private __gap;\n\n // =================================== EVENTS ==================================\n\n event TrustedToggled(address indexed wallet, bool trust);\n\n // =================================== ERRORS ==================================\n\n error NotGovernorOrGuardian();\n error NotTrusted();\n error ZeroAddress();\n\n // ================================= MODIFIERS =================================\n\n /// @notice Checks whether the `msg.sender` has the governor role or the guardian role\n modifier onlyGovernorOrGuardian() {\n if (!coreBorrow.isGovernorOrGuardian(msg.sender)) revert NotGovernorOrGuardian();\n _;\n }\n\n // ================================ CONSTRUCTOR ================================\n\n constructor() initializer {}\n\n function initialize(ICoreBorrow _coreBorrow) public initializer {\n if (address(_coreBorrow) == address(0)) revert ZeroAddress();\n coreBorrow = _coreBorrow;\n }\n\n // =============================== MAIN FUNCTIONS ==============================\n\n /// @notice Adds or removes a trusted keeper bot\n function toggleTrusted(address eoa) external onlyGovernorOrGuardian {\n uint256 trustedStatus = 1 - trusted[eoa];\n trusted[eoa] = trustedStatus;\n emit TrustedToggled(eoa, trustedStatus == 1);\n }\n\n /// @inheritdoc IKeeperRegistry\n function isTrusted(address caller) external view returns (bool) {\n return trusted[caller] == 1;\n }\n}\n" + }, + "contracts/oracle/OracleChainlinkMulti.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\nimport \"@chainlink/contracts/src/v0.8/interfaces/AggregatorV3Interface.sol\";\n\nimport \"./BaseOracleChainlinkMulti.sol\";\n\n/// @title OracleChainlinkMulti\n/// @author Angle Labs, Inc.\n/// @notice Oracle contract, one contract is deployed per collateral/stablecoin pair\n/// @dev This contract concerns an oracle that uses Chainlink with multiple pools to read from\n/// @dev Typically we expect to use this contract to read like the ETH/USD and then USD/EUR feed\ncontract OracleChainlinkMulti is BaseOracleChainlinkMulti {\n // ========================= Parameters and References =========================\n\n /// @notice Chainlink pools, the order of the pools has to be the order in which they are read for the computation\n /// of the price\n AggregatorV3Interface[] internal _circuitChainlink;\n /// @notice Whether each rate for the pairs in `circuitChainlink` should be multiplied or divided\n uint8[] public circuitChainIsMultiplied;\n /// @notice Decimals for each Chainlink pairs\n uint8[] public chainlinkDecimals;\n /// @notice Unit of the stablecoin\n uint256 public immutable outBase;\n /// @notice Description of the assets concerned by the oracle and the price outputted\n string public description;\n\n // ===================================== Error =================================\n\n error IncompatibleLengths();\n\n /// @notice Constructor for an oracle using Chainlink with multiple pools to read from\n /// @param circuitChainlink_ Chainlink pool addresses (in order)\n /// @param _circuitChainIsMultiplied Whether we should multiply or divide by this rate\n /// @param _outBase Unit of the stablecoin (or the out asset) associated to the oracle\n /// @param _stalePeriod Minimum feed update frequency for the oracle to not revert\n /// @param _treasury Treasury associated to the VaultManager which reads from this feed\n /// @param _description Description of the assets concerned by the oracle\n /// @dev For instance, if this oracle is supposed to give the price of ETH in EUR, and if the agEUR\n /// stablecoin associated to EUR has 18 decimals, then `outBase` should be 10**18\n constructor(\n address[] memory circuitChainlink_,\n uint8[] memory _circuitChainIsMultiplied,\n uint256 _outBase,\n uint32 _stalePeriod,\n address _treasury,\n string memory _description\n ) BaseOracleChainlinkMulti(_stalePeriod, _treasury) {\n outBase = _outBase;\n description = _description;\n uint256 circuitLength = circuitChainlink_.length;\n if (circuitLength == 0 || circuitLength != _circuitChainIsMultiplied.length) revert IncompatibleLengths();\n for (uint256 i; i < circuitLength; ++i) {\n AggregatorV3Interface _pool = AggregatorV3Interface(circuitChainlink_[i]);\n _circuitChainlink.push(_pool);\n chainlinkDecimals.push(_pool.decimals());\n }\n circuitChainIsMultiplied = _circuitChainIsMultiplied;\n }\n\n // ============================= Reading Oracles ===============================\n\n /// @inheritdoc IOracle\n function circuitChainlink() public view override returns (AggregatorV3Interface[] memory) {\n return _circuitChainlink;\n }\n\n /// @inheritdoc IOracle\n function read() external view override returns (uint256 quoteAmount) {\n quoteAmount = outBase;\n uint256 circuitLength = _circuitChainlink.length;\n for (uint256 i; i < circuitLength; ++i) {\n quoteAmount = _readChainlinkFeed(\n quoteAmount,\n _circuitChainlink[i],\n circuitChainIsMultiplied[i],\n chainlinkDecimals[i]\n );\n }\n }\n}\n" + }, + "contracts/settlement/Settlement.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\nimport \"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\";\nimport \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\nimport \"@openzeppelin/contracts/token/ERC20/extensions/IERC20Metadata.sol\";\n\nimport \"../interfaces/IAgToken.sol\";\nimport \"../interfaces/ISwapper.sol\";\nimport \"../interfaces/IVaultManager.sol\";\n\n/// @title Settlement\n/// @author Angle Labs, Inc.\n/// @notice Settlement Contract for a VaultManager\n/// @dev This settlement contract should be activated by a careful governance which needs to have performed\n/// some key operations before activating this contract\n/// @dev In case of global settlement, there should be one settlement contract per `VaultManager`\ncontract Settlement {\n using SafeERC20 for IERC20;\n\n /// @notice Base used for parameter computation\n uint256 public constant BASE_PARAMS = 10 ** 9;\n /// @notice Base used for interest computation\n uint256 public constant BASE_INTEREST = 10 ** 27;\n /// @notice Base used for exchange rate computation. It is assumed\n /// that stablecoins have this base\n uint256 public constant BASE_STABLECOIN = 10 ** 18;\n /// @notice Duration of the claim period for over-collateralized vaults\n uint256 public constant OVER_COLLATERALIZED_CLAIM_DURATION = 3 * 24 * 3600;\n\n // =============== Immutable references set in the constructor =================\n\n /// @notice `VaultManager` of this settlement contract\n IVaultManager public immutable vaultManager;\n /// @notice Reference to the stablecoin supported by the `VaultManager` contract\n IAgToken public immutable stablecoin;\n /// @notice Reference to the collateral supported by the `VaultManager`\n IERC20 public immutable collateral;\n /// @notice Base of the collateral\n uint256 internal immutable _collatBase;\n\n // ================ Variables frozen at settlement activation ==================\n\n /// @notice Value of the oracle for the collateral/stablecoin pair\n uint256 public oracleValue;\n /// @notice Value of the interest accumulator at settlement activation\n uint256 public interestAccumulator;\n /// @notice Timestamp at which settlement was activated\n uint256 public activationTimestamp;\n /// @notice Collateral factor of the `VaultManager`\n uint64 public collateralFactor;\n\n // =================== Variables updated during the process ====================\n\n /// @notice How much collateral you can get from stablecoins\n uint256 public collateralStablecoinExchangeRate;\n /// @notice Amount of collateral that will be left over at the end of the process\n uint256 public leftOverCollateral;\n /// @notice Whether the `collateralStablecoinExchangeRate` has been computed\n bool public exchangeRateComputed;\n /// @notice Maps a vault to 1 if it was claimed by its owner\n mapping(uint256 => uint256) public vaultCheck;\n\n // ================================ Events =====================================\n\n event GlobalClaimPeriodActivated(uint256 _collateralStablecoinExchangeRate);\n event Recovered(address indexed tokenAddress, address indexed to, uint256 amount);\n event SettlementActivated(uint256 startTimestamp);\n event VaultClaimed(uint256 vaultID, uint256 stablecoinAmount, uint256 collateralAmount);\n\n // ================================ Errors =====================================\n\n error GlobalClaimPeriodNotStarted();\n error InsolventVault();\n error NotGovernor();\n error NotOwner();\n error RestrictedClaimPeriodNotEnded();\n error SettlementNotInitialized();\n error VaultAlreadyClaimed();\n\n /// @notice Constructor of the contract\n /// @param _vaultManager Address of the `VaultManager` associated to this `Settlement` contract\n /// @dev Out of safety, this constructor reads values from the `VaultManager` contract directly\n constructor(IVaultManager _vaultManager) {\n vaultManager = _vaultManager;\n stablecoin = _vaultManager.stablecoin();\n collateral = _vaultManager.collateral();\n _collatBase = 10 ** (IERC20Metadata(address(collateral)).decimals());\n }\n\n /// @notice Checks whether the `msg.sender` has the governor role or not\n modifier onlyGovernor() {\n if (!(vaultManager.treasury().isGovernor(msg.sender))) revert NotGovernor();\n _;\n }\n\n /// @notice Activates the settlement contract\n /// @dev When calling this function governance should make sure to have:\n /// 1. Accrued the interest rate on the contract\n /// 2. Paused the contract\n /// 3. Recovered all the collateral available in the `VaultManager` contract either\n /// by doing a contract upgrade or by calling a `recoverERC20` method if supported\n function activateSettlement() external onlyGovernor {\n oracleValue = (vaultManager.oracle()).read();\n interestAccumulator = vaultManager.interestAccumulator();\n activationTimestamp = block.timestamp;\n collateralFactor = vaultManager.collateralFactor();\n emit SettlementActivated(block.timestamp);\n }\n\n /// @notice Allows the owner of an over-collateralized vault to claim its collateral upon bringing back all owed stablecoins\n /// @param vaultID ID of the vault to claim\n /// @param to Address to which collateral should be sent\n /// @param who Address which should be notified if needed of the transfer of stablecoins and collateral\n /// @param data Data to pass to the `who` contract for it to successfully give the correct amount of stablecoins\n /// to the `msg.sender` address\n /// @return Amount of collateral sent to the `to` address\n /// @return Amount of stablecoins sent to the contract\n /// @dev Claiming can only happen short after settlement activation\n /// @dev A vault cannot be claimed twice and only the owner of the vault can claim it (regardless of the approval logic)\n /// @dev Only over-collateralized vaults can be claimed from this medium\n function claimOverCollateralizedVault(\n uint256 vaultID,\n address to,\n address who,\n bytes memory data\n ) external returns (uint256, uint256) {\n if (activationTimestamp == 0 || block.timestamp > activationTimestamp + OVER_COLLATERALIZED_CLAIM_DURATION)\n revert SettlementNotInitialized();\n if (vaultCheck[vaultID] == 1) revert VaultAlreadyClaimed();\n if (vaultManager.ownerOf(vaultID) != msg.sender) revert NotOwner();\n (uint256 collateralAmount, uint256 normalizedDebt) = vaultManager.vaultData(vaultID);\n uint256 vaultDebt = (normalizedDebt * interestAccumulator) / BASE_INTEREST;\n if (collateralAmount * oracleValue * collateralFactor < vaultDebt * BASE_PARAMS * _collatBase)\n revert InsolventVault();\n vaultCheck[vaultID] = 1;\n emit VaultClaimed(vaultID, vaultDebt, collateralAmount);\n return _handleRepay(collateralAmount, vaultDebt, to, who, data);\n }\n\n /// @notice Activates the global claim period by setting the `collateralStablecoinExchangeRate` which is going to\n /// dictate how much of collateral will be recoverable for each stablecoin\n /// @dev This function can only be called by the governor in order to allow it in case multiple settlements happen across\n /// different `VaultManager` to rebalance the amount of stablecoins on each to make sure that across all settlement contracts\n /// a similar value of collateral can be obtained against a similar value of stablecoins\n function activateGlobalClaimPeriod() external onlyGovernor {\n if (activationTimestamp == 0 || block.timestamp <= activationTimestamp + OVER_COLLATERALIZED_CLAIM_DURATION)\n revert RestrictedClaimPeriodNotEnded();\n uint256 collateralBalance = collateral.balanceOf(address(this));\n uint256 leftOverDebt = (vaultManager.totalNormalizedDebt() * interestAccumulator) / BASE_INTEREST;\n uint256 stablecoinBalance = stablecoin.balanceOf(address(this));\n // How much 1 of stablecoin will give you in collateral\n uint256 _collateralStablecoinExchangeRate;\n\n if (stablecoinBalance < leftOverDebt) {\n // The left over debt is the total debt minus the stablecoins which have already been accumulated\n // in the first phase\n leftOverDebt -= stablecoinBalance;\n // If you control all the debt, then you are entitled to get all the collateral left in the protocol\n _collateralStablecoinExchangeRate = (collateralBalance * BASE_STABLECOIN) / leftOverDebt;\n // But at the same time, you cannot get more collateral than the value of the stablecoins you brought\n uint256 maxExchangeRate = (BASE_STABLECOIN * _collatBase) / oracleValue;\n if (_collateralStablecoinExchangeRate >= maxExchangeRate) {\n // In this situation, we're sure that `leftOverCollateral` will be positive: governance should be wary\n // to call `recoverERC20` short after though as there's nothing that is going to prevent people to redeem\n // more stablecoins than the `leftOverDebt`\n leftOverCollateral = collateralBalance - (leftOverDebt * _collatBase) / oracleValue;\n _collateralStablecoinExchangeRate = maxExchangeRate;\n }\n }\n exchangeRateComputed = true;\n // In the else case where there is no debt left, you cannot get anything from your stablecoins\n // and so the `collateralStablecoinExchangeRate` is null\n collateralStablecoinExchangeRate = _collateralStablecoinExchangeRate;\n emit GlobalClaimPeriodActivated(_collateralStablecoinExchangeRate);\n }\n\n /// @notice Allows to claim collateral from stablecoins\n /// @param to Address to which collateral should be sent\n /// @param who Address which should be notified if needed of the transfer of stablecoins and collateral\n /// @param data Data to pass to the `who` contract for it to successfully give the correct amount of stablecoins\n /// to the `msg.sender` address\n /// @return Amount of collateral sent to the `to` address\n /// @return Amount of stablecoins sent to the contract\n /// @dev This function reverts if the `collateralStablecoinExchangeRate` is null and hence if the global claim period has\n /// not been activated\n function claimCollateralFromStablecoins(\n uint256 stablecoinAmount,\n address to,\n address who,\n bytes memory data\n ) external returns (uint256, uint256) {\n if (!exchangeRateComputed) revert GlobalClaimPeriodNotStarted();\n return\n _handleRepay(\n (stablecoinAmount * collateralStablecoinExchangeRate) / BASE_STABLECOIN,\n stablecoinAmount,\n to,\n who,\n data\n );\n }\n\n /// @notice Handles the simultaneous repayment of stablecoins with a transfer of collateral\n /// @param collateralAmountToGive Amount of collateral the contract should give\n /// @param stableAmountToRepay Amount of stablecoins the contract should burn from the call\n /// @param to Address to which stablecoins should be sent\n /// @param who Address which should be notified if needed of the transfer\n /// @param data Data to pass to the `who` contract for it to successfully give the correct amount of stablecoins\n /// to the `msg.sender` address\n /// @dev This function allows for capital-efficient claims of collateral from stablecoins\n function _handleRepay(\n uint256 collateralAmountToGive,\n uint256 stableAmountToRepay,\n address to,\n address who,\n bytes memory data\n ) internal returns (uint256, uint256) {\n collateral.safeTransfer(to, collateralAmountToGive);\n if (data.length != 0) {\n ISwapper(who).swap(\n collateral,\n IERC20(address(stablecoin)),\n msg.sender,\n stableAmountToRepay,\n collateralAmountToGive,\n data\n );\n }\n stablecoin.transferFrom(msg.sender, address(this), stableAmountToRepay);\n return (collateralAmountToGive, stableAmountToRepay);\n }\n\n /// @notice Recovers leftover tokens from the contract or tokens that were mistakenly sent to the contract\n /// @param tokenAddress Address of the token to recover\n /// @param to Address to send the remaining tokens to\n /// @param amountToRecover Amount to recover from the contract\n /// @dev Governors cannot recover more collateral than what would be leftover from the contract\n /// @dev This function can be used to rebalance stablecoin balances across different settlement contracts\n /// to make sure every stablecoin can be redeemed for the same value of collateral\n /// @dev It can also be used to recover tokens that are mistakenly sent to this contract\n function recoverERC20(address tokenAddress, address to, uint256 amountToRecover) external onlyGovernor {\n if (tokenAddress == address(collateral)) {\n if (!exchangeRateComputed) revert GlobalClaimPeriodNotStarted();\n leftOverCollateral -= amountToRecover;\n collateral.safeTransfer(to, amountToRecover);\n } else {\n IERC20(tokenAddress).safeTransfer(to, amountToRecover);\n }\n emit Recovered(tokenAddress, to, amountToRecover);\n }\n}\n" + }, + "contracts/swapper/Swapper.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\n/*\n * █ \n ***** ▓▓▓ \n * ▓▓▓▓▓▓▓ \n * ///. ▓▓▓▓▓▓▓▓▓▓▓▓▓ \n ***** //////// ▓▓▓▓▓▓▓ \n * ///////////// ▓▓▓ \n ▓▓ ////////////////// █ ▓▓ \n ▓▓ ▓▓ /////////////////////// ▓▓ ▓▓ \n ▓▓ ▓▓ //////////////////////////// ▓▓ ▓▓ \n ▓▓ ▓▓ /////////▓▓▓///////▓▓▓///////// ▓▓ ▓▓ \n ▓▓ ,////////////////////////////////////// ▓▓ ▓▓ \n ▓▓ ////////////////////////////////////////// ▓▓ \n ▓▓ //////////////////////▓▓▓▓///////////////////// \n ,//////////////////////////////////////////////////// \n .////////////////////////////////////////////////////////// \n .//////////////////////////██.,//////////////////////////█ \n .//////////////////////████..,./////////////////////██ \n ...////////////////███████.....,.////////////////███ \n ,.,////////////████████ ........,///////////████ \n .,.,//////█████████ ,.......///////████ \n ,..//████████ ........./████ \n ..,██████ .....,███ \n .██ ,.,█ \n \n \n \n ▓▓ ▓▓▓▓▓▓▓▓▓▓ ▓▓▓▓▓▓▓▓▓▓ ▓▓ ▓▓▓▓▓▓▓▓▓▓ \n ▓▓▓▓▓▓ ▓▓▓ ▓▓▓ ▓▓▓ ▓▓ ▓▓ ▓▓▓▓ \n ▓▓▓ ▓▓▓ ▓▓▓ ▓▓▓ ▓▓▓ ▓▓▓ ▓▓ ▓▓▓▓▓ \n ▓▓▓ ▓▓ ▓▓▓ ▓▓▓ ▓▓▓▓▓▓▓▓▓▓ ▓▓▓▓▓▓▓▓▓▓ ▓▓▓▓▓▓▓▓▓▓ \n*/\n\npragma solidity ^0.8.12;\n\nimport \"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\";\nimport \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\n\nimport \"../interfaces/IAngleRouterSidechain.sol\";\nimport \"../interfaces/ICoreBorrow.sol\";\nimport \"../interfaces/ISwapper.sol\";\nimport \"../interfaces/external/lido/IWStETH.sol\";\nimport \"../interfaces/external/uniswap/IUniswapRouter.sol\";\n\n// ==================================== ENUM ===================================\n\n/// @notice All possible swaps\nenum SwapType {\n UniswapV3,\n oneInch,\n AngleRouter,\n Leverage,\n None\n}\n\n/// @title Swapper\n/// @author Angle Labs, Inc.\n/// @notice Swapper contract facilitating interactions with Angle VaultManager contracts, notably\n/// liquidation and leverage transactions\ncontract Swapper is ISwapper {\n using SafeERC20 for IERC20;\n\n // ===================== CONSTANTS AND IMMUTABLE VARIABLES =====================\n\n /// @notice Reference to the `CoreBorrow` contract of the module which handles all AccessControl logic\n ICoreBorrow public immutable core;\n /// @notice Uniswap Router contract\n IUniswapV3Router public immutable uniV3Router;\n /// @notice 1inch Router\n address public immutable oneInch;\n /// @notice AngleRouter\n IAngleRouterSidechain public immutable angleRouter;\n\n // =================================== ERRORS ==================================\n\n error EmptyReturnMessage();\n error IncompatibleLengths();\n error NotGovernorOrGuardian();\n error TooSmallAmountOut();\n error ZeroAddress();\n\n /// @notice Constructor of the contract\n /// @param _core Core address\n /// @param _uniV3Router UniswapV3 Router address\n /// @param _oneInch 1inch Router address\n /// @param _angleRouter AngleRouter contract address\n constructor(\n ICoreBorrow _core,\n IUniswapV3Router _uniV3Router,\n address _oneInch,\n IAngleRouterSidechain _angleRouter\n ) {\n if (address(_core) == address(0) || _oneInch == address(0) || address(_angleRouter) == address(0))\n revert ZeroAddress();\n core = _core;\n uniV3Router = _uniV3Router;\n oneInch = _oneInch;\n angleRouter = _angleRouter;\n }\n\n // ========================= EXTERNAL ACCESS FUNCTIONS =========================\n\n /// @inheritdoc ISwapper\n /// @dev This function swaps the `inToken` to the `outToken` by doing a UniV3 swap, a 1inch swap or by interacting\n /// with the `AngleRouter` contract\n /// @dev One slippage check is performed at the end of the call\n /// @dev In this implementation, the function tries to make sure that the `outTokenRecipient` address has at the end\n /// of the call `outTokenOwed`, leftover tokens are sent to a `to` address which by default is the `outTokenRecipient`\n function swap(\n IERC20 inToken,\n IERC20 outToken,\n address outTokenRecipient,\n uint256 outTokenOwed,\n uint256 inTokenObtained,\n bytes memory data\n ) external {\n // Address to receive the surplus amount of token at the end of the call\n address to;\n // For slippage protection, it is checked at the end of the call\n uint256 minAmountOut;\n // Type of the swap to execute: if `swapType == 4`, then it is optional to swap\n uint256 swapType;\n // We're reusing the `data` variable (it can be `path` on UniswapV3, a payload for 1inch or like encoded actions\n // for a router call)\n (to, minAmountOut, swapType, data) = abi.decode(data, (address, uint256, uint256, bytes));\n\n to = (to == address(0)) ? outTokenRecipient : to;\n\n _swap(inToken, inTokenObtained, SwapType(swapType), data);\n\n // A final slippage check is performed after the swaps\n uint256 outTokenBalance = outToken.balanceOf(address(this));\n if (outTokenBalance < minAmountOut) revert TooSmallAmountOut();\n\n // The `outTokenRecipient` may already have enough in balance, in which case there's no need to transfer\n // to this address the token and everything can be given to the `to` address\n uint256 outTokenBalanceRecipient = outToken.balanceOf(outTokenRecipient);\n if (outTokenBalanceRecipient >= outTokenOwed || to == outTokenRecipient)\n outToken.safeTransfer(to, outTokenBalance);\n else {\n // The `outTokenRecipient` should receive the delta to make sure its end balance is equal to `outTokenOwed`\n // Any leftover in this case is sent to the `to` address\n // The function reverts if it did not obtain more than `outTokenOwed - outTokenBalanceRecipient` from the swap\n outToken.safeTransfer(outTokenRecipient, outTokenOwed - outTokenBalanceRecipient);\n outToken.safeTransfer(to, outTokenBalanceRecipient + outTokenBalance - outTokenOwed);\n }\n // Reusing the `inTokenObtained` variable for the `inToken` balance\n // Sending back the remaining amount of inTokens to the `to` address: it is possible that not the full `inTokenObtained`\n // is swapped to `outToken` if we're using the `1inch` payload\n inTokenObtained = inToken.balanceOf(address(this));\n if (inTokenObtained != 0) inToken.safeTransfer(to, inTokenObtained);\n }\n\n // ============================ GOVERNANCE FUNCTION ============================\n\n /// @notice Changes allowances of this contract for different tokens\n /// @param tokens Addresses of the tokens to allow\n /// @param spenders Addresses to allow transfer\n /// @param amounts Amounts to allow\n function changeAllowance(\n IERC20[] calldata tokens,\n address[] calldata spenders,\n uint256[] calldata amounts\n ) external {\n if (!core.isGovernorOrGuardian(msg.sender)) revert NotGovernorOrGuardian();\n uint256 tokensLength = tokens.length;\n if (tokensLength != spenders.length || tokensLength != amounts.length) revert IncompatibleLengths();\n for (uint256 i; i < tokensLength; ++i) {\n _changeAllowance(tokens[i], spenders[i], amounts[i]);\n }\n }\n\n // ========================= INTERNAL UTILITY FUNCTIONS ========================\n\n /// @notice Internal version of the `_changeAllowance` function\n function _changeAllowance(IERC20 token, address spender, uint256 amount) internal {\n uint256 currentAllowance = token.allowance(address(this), spender);\n // In case `currentAllowance < type(uint256).max / 2` and we want to increase it:\n // Do nothing (to handle tokens that need reapprovals to 0 and save gas)\n if (currentAllowance < amount && currentAllowance < type(uint256).max / 2) {\n token.safeIncreaseAllowance(spender, amount - currentAllowance);\n } else if (currentAllowance > amount) {\n token.safeDecreaseAllowance(spender, currentAllowance - amount);\n }\n }\n\n /// @notice Checks the allowance for a contract and updates it to the max if it is not big enough\n /// @param token Token for which allowance should be checked\n /// @param spender Address to grant allowance to\n /// @param amount Minimum amount of tokens needed for the allowance\n function _checkAllowance(IERC20 token, address spender, uint256 amount) internal {\n uint256 currentAllowance = token.allowance(address(this), spender);\n if (currentAllowance < amount) token.safeIncreaseAllowance(spender, type(uint256).max - currentAllowance);\n }\n\n /// @notice Performs a swap using either Uniswap, 1inch. This function can also stake stETH to wstETH\n /// @param inToken Token to swap\n /// @param amount Amount of tokens to swap\n /// @param swapType Type of the swap to perform\n /// @param args Extra args for the swap: in the case of Uniswap it should be a path, for 1inch it should be\n /// a payload\n /// @dev This function does nothing if `swapType` is None and it simply passes on the `amount` it received\n /// @dev No slippage is specified in the actions given here as a final slippage check is performed\n /// after the call to this function\n function _swap(IERC20 inToken, uint256 amount, SwapType swapType, bytes memory args) internal {\n if (swapType == SwapType.UniswapV3) _swapOnUniswapV3(inToken, amount, args);\n else if (swapType == SwapType.oneInch) _swapOn1inch(inToken, args);\n else if (swapType == SwapType.AngleRouter) _angleRouterActions(inToken, args);\n else if (swapType == SwapType.Leverage) _swapLeverage(args);\n }\n\n /// @notice Performs a UniswapV3 swap\n /// @param inToken Token to swap\n /// @param amount Amount of tokens to swap\n /// @param path Path for the UniswapV3 swap: this encodes the out token that is going to be obtained\n /// @dev This function does not check the out token obtained here: if it is wrongly specified, either\n /// the `swap` function could fail or these tokens could stay on the contract\n function _swapOnUniswapV3(IERC20 inToken, uint256 amount, bytes memory path) internal returns (uint256 amountOut) {\n // We need more than `amount` of allowance to the contract\n _checkAllowance(inToken, address(uniV3Router), amount);\n amountOut = uniV3Router.exactInput(ExactInputParams(path, address(this), block.timestamp, amount, 0));\n }\n\n /// @notice Allows to swap any token to an accepted collateral via 1inch API\n /// @param inToken Token received for the 1inch swap\n /// @param payload Bytes needed for 1inch API\n function _swapOn1inch(IERC20 inToken, bytes memory payload) internal returns (uint256 amountOut) {\n _changeAllowance(inToken, oneInch, type(uint256).max);\n //solhint-disable-next-line\n (bool success, bytes memory result) = oneInch.call(payload);\n if (!success) _revertBytes(result);\n amountOut = abi.decode(result, (uint256));\n }\n\n /// @notice Performs actions with the router contract of the protocol on the corresponding chain\n /// @param inToken Token concerned by the action and for which\n function _angleRouterActions(IERC20 inToken, bytes memory args) internal {\n (ActionType[] memory actions, bytes[] memory actionData) = abi.decode(args, (ActionType[], bytes[]));\n _changeAllowance(inToken, address(angleRouter), type(uint256).max);\n PermitType[] memory permits;\n angleRouter.mixer(permits, actions, actionData);\n }\n\n /// @notice Allows to take leverage or deleverage via a specific contract\n /// @param payload Bytes needed for 1inch API\n /// @dev This function is to be implemented if the swapper concerns a token that requires some actions\n /// not supported by 1inch or UniV3\n function _swapLeverage(bytes memory payload) internal virtual returns (uint256 amountOut) {}\n\n /// @notice Internal function used for error handling\n /// @param errMsg Error message received\n function _revertBytes(bytes memory errMsg) internal pure {\n if (errMsg.length != 0) {\n //solhint-disable-next-line\n assembly {\n revert(add(32, errMsg), mload(errMsg))\n }\n }\n revert EmptyReturnMessage();\n }\n}\n" + }, + "contracts/treasury/Treasury.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\n/*\n * █ \n ***** ▓▓▓ \n * ▓▓▓▓▓▓▓ \n * ///. ▓▓▓▓▓▓▓▓▓▓▓▓▓ \n ***** //////// ▓▓▓▓▓▓▓ \n * ///////////// ▓▓▓ \n ▓▓ ////////////////// █ ▓▓ \n ▓▓ ▓▓ /////////////////////// ▓▓ ▓▓ \n ▓▓ ▓▓ //////////////////////////// ▓▓ ▓▓ \n ▓▓ ▓▓ /////////▓▓▓///////▓▓▓///////// ▓▓ ▓▓ \n ▓▓ ,////////////////////////////////////// ▓▓ ▓▓ \n ▓▓ ////////////////////////////////////////// ▓▓ \n ▓▓ //////////////////////▓▓▓▓///////////////////// \n ,//////////////////////////////////////////////////// \n .////////////////////////////////////////////////////////// \n .//////////////////////////██.,//////////////////////////█ \n .//////////////////////████..,./////////////////////██ \n ...////////////////███████.....,.////////////////███ \n ,.,////////////████████ ........,///////////████ \n .,.,//////█████████ ,.......///////████ \n ,..//████████ ........./████ \n ..,██████ .....,███ \n .██ ,.,█ \n \n \n \n ▓▓ ▓▓▓▓▓▓▓▓▓▓ ▓▓▓▓▓▓▓▓▓▓ ▓▓ ▓▓▓▓▓▓▓▓▓▓ \n ▓▓▓▓▓▓ ▓▓▓ ▓▓▓ ▓▓▓ ▓▓ ▓▓ ▓▓▓▓ \n ▓▓▓ ▓▓▓ ▓▓▓ ▓▓▓ ▓▓▓ ▓▓▓ ▓▓ ▓▓▓▓▓ \n ▓▓▓ ▓▓ ▓▓▓ ▓▓▓ ▓▓▓▓▓▓▓▓▓▓ ▓▓▓▓▓▓▓▓▓▓ ▓▓▓▓▓▓▓▓▓▓ \n*/\n\npragma solidity ^0.8.12;\n\nimport \"@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol\";\nimport \"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\";\nimport \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\n\nimport \"../interfaces/IAgToken.sol\";\nimport \"../interfaces/ICoreBorrow.sol\";\nimport \"../interfaces/IFlashAngle.sol\";\nimport \"../interfaces/ITreasury.sol\";\nimport \"../interfaces/IVaultManager.sol\";\n\n/// @title Treasury\n/// @author Angle Labs, Inc.\n/// @notice Treasury of Angle Borrowing Module doing the accounting across all VaultManagers for\n/// a given stablecoin\ncontract Treasury is ITreasury, Initializable {\n using SafeERC20 for IERC20;\n\n /// @notice Base used for parameter computation\n uint256 public constant BASE_9 = 1e9;\n\n // ================================= REFERENCES ================================\n\n /// @notice Reference to the `CoreBorrow` contract of the module which handles all AccessControl logic\n ICoreBorrow public core;\n /// @notice Flash Loan Module with a minter right on the stablecoin\n IFlashAngle public flashLoanModule;\n /// @inheritdoc ITreasury\n IAgToken public stablecoin;\n /// @notice Address responsible for handling the surplus made by the treasury\n address public surplusManager;\n /// @notice List of the accepted `VaultManager` of the protocol\n address[] public vaultManagerList;\n /// @notice Maps an address to 1 if it was initialized as a `VaultManager` contract\n mapping(address => uint256) public vaultManagerMap;\n\n // ================================= VARIABLES =================================\n\n /// @notice Amount of bad debt (unbacked stablecoin) accumulated across all `VaultManager` contracts\n /// linked to this stablecoin\n uint256 public badDebt;\n /// @notice Surplus amount accumulated by the contract waiting to be distributed to governance. Technically\n /// only a share of this `surplusBuffer` will go to governance. Once a share of the surplus buffer has been\n /// given to governance, then this surplus is reset\n uint256 public surplusBuffer;\n\n // ================================= PARAMETER =================================\n\n /// @notice Share of the `surplusBuffer` distributed to governance (in `BASE_9`)\n uint64 public surplusForGovernance;\n\n // =================================== EVENTS ==================================\n\n event BadDebtUpdated(uint256 badDebtValue);\n event CoreUpdated(address indexed _core);\n event NewTreasurySet(address indexed _treasury);\n event Recovered(address indexed token, address indexed to, uint256 amount);\n event SurplusBufferUpdated(uint256 surplusBufferValue);\n event SurplusForGovernanceUpdated(uint64 _surplusForGovernance);\n event SurplusManagerUpdated(address indexed _surplusManager);\n event VaultManagerToggled(address indexed vaultManager);\n\n // =================================== ERRORS ==================================\n\n error AlreadyVaultManager();\n error InvalidAddress();\n error InvalidTreasury();\n error NotCore();\n error NotGovernor();\n error NotVaultManager();\n error RightsNotRemoved();\n error TooBigAmount();\n error TooHighParameterValue();\n error ZeroAddress();\n\n // ================================== MODIFIER =================================\n\n /// @notice Checks whether the `msg.sender` has the governor role or not\n modifier onlyGovernor() {\n if (!core.isGovernor(msg.sender)) revert NotGovernor();\n _;\n }\n\n /// @notice Initializes the treasury contract\n /// @param _core Address of the `CoreBorrow` contract of the module\n /// @param _stablecoin Address of the stablecoin\n function initialize(ICoreBorrow _core, IAgToken _stablecoin) public virtual initializer {\n if (address(_stablecoin) == address(0) || address(_core) == address(0)) revert ZeroAddress();\n core = _core;\n stablecoin = _stablecoin;\n }\n\n /// @custom:oz-upgrades-unsafe-allow constructor\n constructor() initializer {}\n\n // =============================== VIEW FUNCTIONS ==============================\n\n /// @inheritdoc ITreasury\n function isGovernor(address admin) external view returns (bool) {\n return core.isGovernor(admin);\n }\n\n /// @inheritdoc ITreasury\n function isGovernorOrGuardian(address admin) external view returns (bool) {\n return core.isGovernorOrGuardian(admin);\n }\n\n /// @inheritdoc ITreasury\n function isVaultManager(address _vaultManager) external view returns (bool) {\n return vaultManagerMap[_vaultManager] == 1;\n }\n\n // ===================== EXTERNAL PERMISSIONLESS FUNCTIONS =====================\n\n /// @notice Fetches the surplus accrued across all the `VaultManager` contracts controlled by this\n /// `Treasury` contract as well as from the fees of the `FlashLoan` module\n /// @return Surplus buffer value at the end of the call\n /// @return Bad debt value at the end of the call\n /// @dev This function pools surplus and bad debt across all contracts and then updates the `surplusBuffer`\n /// (or the `badDebt` if more losses were made than profits)\n function fetchSurplusFromAll() external returns (uint256, uint256) {\n return _fetchSurplusFromAll();\n }\n\n /// @notice Fetches the surplus accrued in the flash loan module and updates the `surplusBuffer`\n /// @return Surplus buffer value at the end of the call\n /// @return Bad debt value at the end of the call\n /// @dev This function fails if the `flashLoanModule` has not been initialized yet\n function fetchSurplusFromFlashLoan() external returns (uint256, uint256) {\n uint256 surplusBufferValue = surplusBuffer + flashLoanModule.accrueInterestToTreasury(stablecoin);\n return _updateSurplusAndBadDebt(surplusBufferValue, badDebt);\n }\n\n /// @notice Pushes the surplus buffer to the `surplusManager` contract\n /// @return governanceAllocation Amount transferred to governance\n /// @dev It makes sure to fetch the surplus from all the contracts handled by this treasury to avoid\n /// the situation where rewards are still distributed to governance even though a `VaultManager` has made\n /// a big loss\n /// @dev Typically this function is to be called once every week by a keeper to distribute rewards to veANGLE\n /// holders\n /// @dev `stablecoin` must be an AgToken and hence `transfer` reverts if the call is not successful\n function pushSurplus() external returns (uint256 governanceAllocation) {\n address _surplusManager = surplusManager;\n if (_surplusManager == address(0)) {\n revert ZeroAddress();\n }\n (uint256 surplusBufferValue, ) = _fetchSurplusFromAll();\n surplusBuffer = 0;\n emit SurplusBufferUpdated(0);\n governanceAllocation = (surplusForGovernance * surplusBufferValue) / BASE_9;\n stablecoin.transfer(_surplusManager, governanceAllocation);\n }\n\n /// @notice Updates the bad debt of the protocol in case where the protocol has accumulated some revenue\n /// from an external source\n /// @param amount Amount to reduce the bad debt of\n /// @return badDebtValue Value of the bad debt at the end of the call\n /// @dev If the protocol has made a loss and managed to make some profits to recover for this loss (through\n /// a program like Olympus Pro), then this function needs to be called\n /// @dev `badDebt` is simply reduced here by burning stablecoins\n /// @dev It is impossible to burn more than the `badDebt` otherwise this function could be used to manipulate\n /// the `surplusBuffer` and hence the amount going to governance\n function updateBadDebt(uint256 amount) external returns (uint256 badDebtValue) {\n stablecoin.burnSelf(amount, address(this));\n badDebtValue = badDebt - amount;\n badDebt = badDebtValue;\n emit BadDebtUpdated(badDebtValue);\n }\n\n // ========================= INTERNAL UTILITY FUNCTIONS ========================\n\n /// @notice Internal version of the `fetchSurplusFromAll` function\n function _fetchSurplusFromAll() internal returns (uint256 surplusBufferValue, uint256 badDebtValue) {\n (surplusBufferValue, badDebtValue) = _fetchSurplusFromList(vaultManagerList);\n // It will fail anyway if the `flashLoanModule` is the zero address\n if (address(flashLoanModule) != address(0))\n surplusBufferValue += flashLoanModule.accrueInterestToTreasury(stablecoin);\n (surplusBufferValue, badDebtValue) = _updateSurplusAndBadDebt(surplusBufferValue, badDebtValue);\n }\n\n /// @notice Fetches the surplus from a list of `VaultManager` addresses without modifying the\n /// `surplusBuffer` and `badDebtValue`\n /// @return surplusBufferValue Value the `surplusBuffer` should have after the call if it was updated\n /// @return badDebtValue Value the `badDebt` should have after the call if it was updated\n /// @dev This internal function is never to be called alone, and should always be called in conjunction\n /// with the `_updateSurplusAndBadDebt` function\n function _fetchSurplusFromList(\n address[] memory vaultManagers\n ) internal returns (uint256 surplusBufferValue, uint256 badDebtValue) {\n badDebtValue = badDebt;\n surplusBufferValue = surplusBuffer;\n uint256 newSurplus;\n uint256 newBadDebt;\n uint256 vaultManagersLength = vaultManagers.length;\n for (uint256 i; i < vaultManagersLength; ++i) {\n (newSurplus, newBadDebt) = IVaultManager(vaultManagers[i]).accrueInterestToTreasury();\n surplusBufferValue += newSurplus;\n badDebtValue += newBadDebt;\n }\n }\n\n /// @notice Updates the `surplusBuffer` and the `badDebt` from updated values after calling the flash loan module\n /// and/or a list of `VaultManager` contracts\n /// @param surplusBufferValue Value of the surplus buffer after the calls to the different modules\n /// @param badDebtValue Value of the bad debt after the calls to the different modules\n /// @return Value of the `surplusBuffer` corrected from the `badDebt`\n /// @return Value of the `badDebt` corrected from the `surplusBuffer` and from the surplus the treasury had accumulated\n /// previously\n /// @dev When calling this function, it is possible that there is a positive `surplusBufferValue` and `badDebtValue`,\n /// this function tries to reconcile both values and makes sure that we either have surplus or bad debt but not both\n /// at the same time\n function _updateSurplusAndBadDebt(\n uint256 surplusBufferValue,\n uint256 badDebtValue\n ) internal returns (uint256, uint256) {\n if (badDebtValue != 0) {\n // If we have bad debt we need to burn stablecoins that accrued to the protocol\n // We still need to make sure that we're not burning too much or as much as we can if the debt is big\n uint256 balance = stablecoin.balanceOf(address(this));\n // We are going to burn `min(balance, badDebtValue)`\n uint256 toBurn = balance <= badDebtValue ? balance : badDebtValue;\n stablecoin.burnSelf(toBurn, address(this));\n // If we burned more than `surplusBuffer`, we set surplus to 0. It means we had to tap into Treasury reserve\n surplusBufferValue = toBurn >= surplusBufferValue ? 0 : surplusBufferValue - toBurn;\n badDebtValue -= toBurn;\n // Note here that the stablecoin balance is necessarily greater than the surplus buffer, and so if\n // `surplusBuffer >= toBurn`, then `badDebtValue = toBurn`\n }\n surplusBuffer = surplusBufferValue;\n badDebt = badDebtValue;\n emit SurplusBufferUpdated(surplusBufferValue);\n emit BadDebtUpdated(badDebtValue);\n return (surplusBufferValue, badDebtValue);\n }\n\n /// @notice Adds a new `VaultManager`\n /// @param vaultManager `VaultManager` contract to add\n /// @dev This contract should have already been initialized with a correct treasury address\n /// @dev It's this function that gives the minter right to the `VaultManager`\n function _addVaultManager(address vaultManager) internal virtual {\n if (vaultManagerMap[vaultManager] == 1) revert AlreadyVaultManager();\n if (address(IVaultManager(vaultManager).treasury()) != address(this)) revert InvalidTreasury();\n vaultManagerMap[vaultManager] = 1;\n vaultManagerList.push(vaultManager);\n emit VaultManagerToggled(vaultManager);\n stablecoin.addMinter(vaultManager);\n }\n\n // ============================= GOVERNOR FUNCTIONS ============================\n\n /// @notice Adds a new minter for the stablecoin\n /// @param minter Minter address to add\n function addMinter(address minter) external virtual onlyGovernor {\n if (minter == address(0)) revert ZeroAddress();\n stablecoin.addMinter(minter);\n }\n\n /// @notice External wrapper for `_addVaultManager`\n function addVaultManager(address vaultManager) external virtual onlyGovernor {\n _addVaultManager(vaultManager);\n }\n\n /// @notice Removes a minter from the stablecoin contract\n /// @param minter Minter address to remove\n function removeMinter(address minter) external virtual onlyGovernor {\n // To remove the minter role to a `VaultManager` you have to go through the `removeVaultManager` function\n if (vaultManagerMap[minter] == 1) revert InvalidAddress();\n stablecoin.removeMinter(minter);\n }\n\n /// @notice Removes a `VaultManager`\n /// @param vaultManager `VaultManager` contract to remove\n /// @dev A removed `VaultManager` loses its minter right on the stablecoin\n function removeVaultManager(address vaultManager) external onlyGovernor {\n if (vaultManagerMap[vaultManager] != 1) revert NotVaultManager();\n delete vaultManagerMap[vaultManager];\n // deletion from `vaultManagerList` loop\n uint256 vaultManagerListLength = vaultManagerList.length;\n for (uint256 i; i < vaultManagerListLength - 1; ++i) {\n if (vaultManagerList[i] == vaultManager) {\n // replace the `VaultManager` to remove with the last of the list\n vaultManagerList[i] = vaultManagerList[vaultManagerListLength - 1];\n break;\n }\n }\n // remove last element in array\n vaultManagerList.pop();\n emit VaultManagerToggled(vaultManager);\n stablecoin.removeMinter(vaultManager);\n }\n\n /// @notice Allows to recover any ERC20 token, including the stablecoin handled by this contract, and to send it\n /// to a contract\n /// @param tokenAddress Address of the token to recover\n /// @param to Address of the contract to send collateral to\n /// @param amountToRecover Amount of collateral to transfer\n /// @dev It is impossible to recover the stablecoin of the protocol if there is some bad debt for it\n /// @dev In this case, the function makes sure to fetch the surplus/bad debt from all the `VaultManager` contracts\n /// and from the flash loan module\n /// @dev If the token to recover is the stablecoin, tokens recovered are fetched\n /// from the surplus and not from the `surplusBuffer`\n function recoverERC20(address tokenAddress, address to, uint256 amountToRecover) external onlyGovernor {\n // Cannot recover stablecoin if badDebt or tap into the surplus buffer\n if (tokenAddress == address(stablecoin)) {\n _fetchSurplusFromAll();\n // If balance is non zero then this means, after the call to `fetchSurplusFromAll` that\n // bad debt is necessarily null\n uint256 balance = stablecoin.balanceOf(address(this));\n if (amountToRecover + surplusBuffer > balance) revert TooBigAmount();\n stablecoin.transfer(to, amountToRecover);\n } else {\n IERC20(tokenAddress).safeTransfer(to, amountToRecover);\n }\n emit Recovered(tokenAddress, to, amountToRecover);\n }\n\n /// @notice Changes the treasury contract and communicates this change to all `VaultManager` contract\n /// @param _treasury New treasury address for this stablecoin\n /// @dev This function is basically a way to remove rights to this contract and grant them to a new one\n /// @dev It could be used to set a new core contract\n function setTreasury(address _treasury) external virtual onlyGovernor {\n if (ITreasury(_treasury).stablecoin() != stablecoin) revert InvalidTreasury();\n // Flash loan role should be removed before calling this function\n if (core.isFlashLoanerTreasury(address(this))) revert RightsNotRemoved();\n emit NewTreasurySet(_treasury);\n uint256 vaultManagerListLength = vaultManagerList.length;\n for (uint256 i; i < vaultManagerListLength; ++i) {\n IVaultManager(vaultManagerList[i]).setTreasury(_treasury);\n }\n // A `TreasuryUpdated` event is triggered in the stablecoin\n stablecoin.setTreasury(_treasury);\n }\n\n /// @notice Sets the `surplusForGovernance` parameter\n /// @param _surplusForGovernance New value of the parameter\n /// @dev To pause surplus distribution, governance needs to set a zero value for `surplusForGovernance`\n /// which means\n function setSurplusForGovernance(uint64 _surplusForGovernance) external onlyGovernor {\n if (_surplusForGovernance > BASE_9) revert TooHighParameterValue();\n surplusForGovernance = _surplusForGovernance;\n emit SurplusForGovernanceUpdated(_surplusForGovernance);\n }\n\n /// @notice Sets the `surplusManager` contract responsible for handling the surplus of the\n /// protocol\n /// @param _surplusManager New address responsible for handling the surplus\n function setSurplusManager(address _surplusManager) external onlyGovernor {\n if (_surplusManager == address(0)) revert ZeroAddress();\n surplusManager = _surplusManager;\n emit SurplusManagerUpdated(_surplusManager);\n }\n\n /// @notice Sets a new `core` contract\n /// @dev This function should typically be called on all treasury contracts after the `setCore`\n /// function has been called on the `CoreBorrow` contract\n /// @dev One sanity check that can be performed here is to verify whether at least the governor\n /// calling the contract is still a governor in the new core\n function setCore(ICoreBorrow _core) external onlyGovernor {\n if (!_core.isGovernor(msg.sender)) revert NotGovernor();\n core = ICoreBorrow(_core);\n emit CoreUpdated(address(_core));\n }\n\n /// @inheritdoc ITreasury\n function setFlashLoanModule(address _flashLoanModule) external {\n if (msg.sender != address(core)) revert NotCore();\n address oldFlashLoanModule = address(flashLoanModule);\n flashLoanModule = IFlashAngle(_flashLoanModule);\n if (oldFlashLoanModule != address(0)) {\n stablecoin.removeMinter(oldFlashLoanModule);\n }\n // We may want to cancel the module\n if (_flashLoanModule != address(0)) {\n stablecoin.addMinter(_flashLoanModule);\n }\n }\n}\n" + }, + "contracts/ui-helpers/AngleBorrowHelpers.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\n/*\n * █ \n ***** ▓▓▓ \n * ▓▓▓▓▓▓▓ \n * ///. ▓▓▓▓▓▓▓▓▓▓▓▓▓ \n ***** //////// ▓▓▓▓▓▓▓ \n * ///////////// ▓▓▓ \n ▓▓ ////////////////// █ ▓▓ \n ▓▓ ▓▓ /////////////////////// ▓▓ ▓▓ \n ▓▓ ▓▓ //////////////////////////// ▓▓ ▓▓ \n ▓▓ ▓▓ /////////▓▓▓///////▓▓▓///////// ▓▓ ▓▓ \n ▓▓ ,////////////////////////////////////// ▓▓ ▓▓ \n ▓▓ ////////////////////////////////////////// ▓▓ \n ▓▓ //////////////////////▓▓▓▓///////////////////// \n ,//////////////////////////////////////////////////// \n .////////////////////////////////////////////////////////// \n .//////////////////////////██.,//////////////////////////█ \n .//////////////////////████..,./////////////////////██ \n ...////////////////███████.....,.////////////////███ \n ,.,////////////████████ ........,///////////████ \n .,.,//////█████████ ,.......///////████ \n ,..//████████ ........./████ \n ..,██████ .....,███ \n .██ ,.,█ \n \n \n \n ▓▓ ▓▓▓▓▓▓▓▓▓▓ ▓▓▓▓▓▓▓▓▓▓ ▓▓ ▓▓▓▓▓▓▓▓▓▓ \n ▓▓▓▓▓▓ ▓▓▓ ▓▓▓ ▓▓▓ ▓▓ ▓▓ ▓▓▓▓ \n ▓▓▓ ▓▓▓ ▓▓▓ ▓▓▓ ▓▓▓ ▓▓▓ ▓▓ ▓▓▓▓▓ \n ▓▓▓ ▓▓ ▓▓▓ ▓▓▓ ▓▓▓▓▓▓▓▓▓▓ ▓▓▓▓▓▓▓▓▓▓ ▓▓▓▓▓▓▓▓▓▓ \n*/\n\nimport \"@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol\";\nimport \"../interfaces/IVaultManager.sol\";\n\npragma solidity ^0.8.12;\n\n/// @title AngleBorrowHelpers\n/// @author Angle Labs, Inc.\n/// @notice Contract with view functions designed to facilitate integrations on the Borrow module of the Angle Protocol\n/// @dev This contract only contains view functions to be queried off-chain. It was thus not optimized for gas consumption\ncontract AngleBorrowHelpers is Initializable {\n /// @notice Returns all the vaults owned or controlled (under the form of approval) by an address\n /// @param vaultManager VaultManager address to query vaultIDs on\n /// @param spender Address for which vault ownerships should be checked\n /// @return List of `vaultID` controlled by this address\n /// @return Count of vaults owned by the address\n /// @dev This function is never to be called on-chain since it iterates over all vaultIDs. It is here\n /// to reduce dependency on an external graph to link an ID to its owner\n function getControlledVaults(\n IVaultManager vaultManager,\n address spender\n ) external view returns (uint256[] memory, uint256) {\n uint256 arraySize = vaultManager.vaultIDCount();\n uint256[] memory vaultsControlled = new uint256[](arraySize);\n uint256 count;\n for (uint256 i = 1; i <= arraySize; ++i) {\n try vaultManager.isApprovedOrOwner(spender, i) returns (bool _isApprovedOrOwner) {\n if (_isApprovedOrOwner) {\n vaultsControlled[count] = i;\n count += 1;\n }\n } catch {\n continue;\n } // This happens if nobody owns the vaultID=i (if there has been a burn)\n }\n return (vaultsControlled, count);\n }\n\n /// @custom:oz-upgrades-unsafe-allow constructor\n constructor() initializer {}\n}\n" + }, + "contracts/ui-helpers/AngleHelpers.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\nimport \"../interfaces/IAngleRouter.sol\";\nimport \"../interfaces/coreModule/IAgTokenMainnet.sol\";\nimport \"../interfaces/coreModule/ICore.sol\";\nimport \"../interfaces/coreModule/IOracleCore.sol\";\nimport \"../interfaces/coreModule/IPerpetualManager.sol\";\nimport \"../interfaces/coreModule/IPoolManager.sol\";\nimport \"../interfaces/coreModule/IStableMaster.sol\";\nimport \"./AngleBorrowHelpers.sol\";\n\npragma solidity ^0.8.12;\n\nstruct Parameters {\n SLPData slpData;\n MintBurnData feeData;\n PerpetualManagerFeeData perpFeeData;\n PerpetualManagerParamData perpParam;\n}\n\nstruct PerpetualManagerFeeData {\n uint64[] xHAFeesDeposit;\n uint64[] yHAFeesDeposit;\n uint64[] xHAFeesWithdraw;\n uint64[] yHAFeesWithdraw;\n uint64 haBonusMalusDeposit;\n uint64 haBonusMalusWithdraw;\n}\n\nstruct PerpetualManagerParamData {\n uint64 maintenanceMargin;\n uint64 maxLeverage;\n uint64 targetHAHedge;\n uint64 limitHAHedge;\n uint64 lockTime;\n}\n\nstruct CollateralAddresses {\n address stableMaster;\n address poolManager;\n address perpetualManager;\n address sanToken;\n address oracle;\n address gauge;\n address feeManager;\n address[] strategies;\n}\n\n/// @title AngleHelpers\n/// @author Angle Labs, Inc.\n/// @notice Contract with view functions designed to facilitate integrations on the Core and Borrow module of the Angle Protocol\n/// @dev This contract only contains view functions to be queried off-chain. It was thus not optimized for gas consumption\ncontract AngleHelpers is AngleBorrowHelpers {\n // =========================== HELPER VIEW FUNCTIONS ===========================\n\n /// @notice Gives the amount of `agToken` you'd be getting if you were executing in the same block a mint transaction\n /// with `amount` of `collateral` in the Core module of the Angle protocol as well as the value of the fees\n /// (in `BASE_PARAMS`) that would be applied during the mint\n /// @return Amount of `agToken` that would be obtained with a mint transaction in the same block\n /// @return Percentage of fees that would be taken during a mint transaction in the same block\n /// @dev This function reverts if the mint transaction was to revert in the same conditions (without taking into account\n /// potential approval problems to the `StableMaster` contract)\n function previewMintAndFees(\n uint256 amount,\n address agToken,\n address collateral\n ) external view returns (uint256, uint256) {\n return _previewMintAndFees(amount, agToken, collateral);\n }\n\n /// @notice Gives the amount of `collateral` you'd be getting if you were executing in the same block a burn transaction\n /// with `amount` of `agToken` in the Core module of the Angle protocol as well as the value of the fees\n /// (in `BASE_PARAMS`) that would be applied during the burn\n /// @return Amount of `collateral` that would be obtained with a burn transaction in the same block\n /// @return Percentage of fees that would be taken during a burn transaction in the same block\n /// @dev This function reverts if the burn transaction was to revert in the same conditions (without taking into account\n /// potential approval problems to the `StableMaster` contract or agToken balance prior to the call)\n function previewBurnAndFees(\n uint256 amount,\n address agToken,\n address collateral\n ) external view returns (uint256, uint256) {\n return _previewBurnAndFees(amount, agToken, collateral);\n }\n\n /// @notice Returns all the addresses associated to the (`agToken`,`collateral`) pair given\n /// @return addresses A struct with all the addresses associated in the Core module\n function getCollateralAddresses(\n address agToken,\n address collateral\n ) external view returns (CollateralAddresses memory addresses) {\n address stableMaster = IAgTokenMainnet(agToken).stableMaster();\n (address poolManager, address perpetualManager, address sanToken, address gauge) = ROUTER.mapPoolManagers(\n stableMaster,\n collateral\n );\n (, , , IOracleCore oracle, , , , , ) = IStableMaster(stableMaster).collateralMap(poolManager);\n addresses.stableMaster = stableMaster;\n addresses.poolManager = poolManager;\n addresses.perpetualManager = perpetualManager;\n addresses.sanToken = sanToken;\n addresses.gauge = gauge;\n addresses.oracle = address(oracle);\n addresses.feeManager = IPoolManager(poolManager).feeManager();\n\n uint256 length;\n while (true) {\n try IPoolManager(poolManager).strategyList(length) returns (address) {\n length += 1;\n } catch {\n break;\n }\n }\n address[] memory strategies = new address[](length);\n for (uint256 i; i < length; ++i) {\n strategies[i] = IPoolManager(poolManager).strategyList(i);\n }\n addresses.strategies = strategies;\n }\n\n /// @notice Gets the addresses of all the `StableMaster` contracts and their associated `AgToken` addresses\n /// @return List of the `StableMaster` addresses of the Angle protocol\n /// @return List of the `AgToken` addresses of the protocol\n /// @dev The place of an agToken address in the list is the same as the corresponding `StableMaster` address\n function getStablecoinAddresses() external view returns (address[] memory, address[] memory) {\n address[] memory stableMasterAddresses = CORE.stablecoinList();\n address[] memory agTokenAddresses = new address[](stableMasterAddresses.length);\n for (uint256 i; i < stableMasterAddresses.length; ++i) {\n agTokenAddresses[i] = IStableMaster(stableMasterAddresses[i]).agToken();\n }\n return (stableMasterAddresses, agTokenAddresses);\n }\n\n /// @notice Returns most of the governance parameters associated to the (`agToken`,`collateral`) pair given\n /// @return params Struct with most of the parameters in the `StableMaster` and `PerpetualManager` contracts\n /// @dev Check out the struct `Parameters` for the meaning of the return values\n function getCollateralParameters(\n address agToken,\n address collateral\n ) external view returns (Parameters memory params) {\n (address stableMaster, address poolManager) = _getStableMasterAndPoolManager(agToken, collateral);\n (\n ,\n ,\n IPerpetualManager perpetualManager,\n ,\n ,\n ,\n ,\n SLPData memory slpData,\n MintBurnData memory feeData\n ) = IStableMaster(stableMaster).collateralMap(poolManager);\n\n params.slpData = slpData;\n params.feeData = feeData;\n params.perpParam.maintenanceMargin = perpetualManager.maintenanceMargin();\n params.perpParam.maxLeverage = perpetualManager.maxLeverage();\n params.perpParam.targetHAHedge = perpetualManager.targetHAHedge();\n params.perpParam.limitHAHedge = perpetualManager.limitHAHedge();\n params.perpParam.lockTime = perpetualManager.lockTime();\n\n params.perpFeeData.haBonusMalusDeposit = perpetualManager.haBonusMalusDeposit();\n params.perpFeeData.haBonusMalusWithdraw = perpetualManager.haBonusMalusWithdraw();\n\n uint256 length;\n while (true) {\n try perpetualManager.xHAFeesDeposit(length) returns (uint64) {\n length += 1;\n } catch {\n break;\n }\n }\n uint64[] memory data = new uint64[](length);\n uint64[] memory data2 = new uint64[](length);\n for (uint256 i; i < length; ++i) {\n data[i] = perpetualManager.xHAFeesDeposit(i);\n data2[i] = perpetualManager.yHAFeesDeposit(i);\n }\n params.perpFeeData.xHAFeesDeposit = data;\n params.perpFeeData.yHAFeesDeposit = data2;\n\n length = 0;\n while (true) {\n try perpetualManager.xHAFeesWithdraw(length) returns (uint64) {\n length += 1;\n } catch {\n break;\n }\n }\n data = new uint64[](length);\n data2 = new uint64[](length);\n for (uint256 i; i < length; ++i) {\n data[i] = perpetualManager.xHAFeesWithdraw(i);\n data2[i] = perpetualManager.yHAFeesWithdraw(i);\n }\n params.perpFeeData.xHAFeesWithdraw = data;\n params.perpFeeData.yHAFeesWithdraw = data2;\n }\n\n /// @notice Returns the address of the poolManager associated to an (`agToken`, `collateral`) pair\n /// in the Core module of the protocol\n function getPoolManager(address agToken, address collateral) public view returns (address poolManager) {\n (, poolManager) = _getStableMasterAndPoolManager(agToken, collateral);\n }\n\n // ============================= REPLICA FUNCTIONS =============================\n // These replicate what is done in the other contracts of the protocol\n\n function _previewBurnAndFees(\n uint256 amount,\n address agToken,\n address collateral\n ) internal view returns (uint256 amountForUserInCollat, uint256 feePercent) {\n (address stableMaster, address poolManager) = _getStableMasterAndPoolManager(agToken, collateral);\n (\n address token,\n ,\n IPerpetualManager perpetualManager,\n IOracleCore oracle,\n uint256 stocksUsers,\n ,\n uint256 collatBase,\n ,\n MintBurnData memory feeData\n ) = IStableMaster(stableMaster).collateralMap(poolManager);\n if (token == address(0) || IStableMaster(stableMaster).paused(keccak256(abi.encodePacked(STABLE, poolManager))))\n revert NotInitialized();\n if (amount > stocksUsers) revert InvalidAmount();\n\n if (feeData.xFeeBurn.length == 1) {\n feePercent = feeData.yFeeBurn[0];\n } else {\n bytes memory data = abi.encode(address(perpetualManager), feeData.targetHAHedge);\n uint64 hedgeRatio = _computeHedgeRatio(stocksUsers - amount, data);\n feePercent = _piecewiseLinear(hedgeRatio, feeData.xFeeBurn, feeData.yFeeBurn);\n }\n feePercent = (feePercent * feeData.bonusMalusBurn) / BASE_PARAMS;\n\n amountForUserInCollat = (amount * (BASE_PARAMS - feePercent) * collatBase) / (oracle.readUpper() * BASE_PARAMS);\n }\n\n function _previewMintAndFees(\n uint256 amount,\n address agToken,\n address collateral\n ) internal view returns (uint256 amountForUserInStable, uint256 feePercent) {\n (address stableMaster, address poolManager) = _getStableMasterAndPoolManager(agToken, collateral);\n (\n address token,\n ,\n IPerpetualManager perpetualManager,\n IOracleCore oracle,\n uint256 stocksUsers,\n ,\n ,\n ,\n MintBurnData memory feeData\n ) = IStableMaster(stableMaster).collateralMap(poolManager);\n if (token == address(0) || IStableMaster(stableMaster).paused(keccak256(abi.encodePacked(STABLE, poolManager))))\n revert NotInitialized();\n\n amountForUserInStable = oracle.readQuoteLower(amount);\n\n if (feeData.xFeeMint.length == 1) feePercent = feeData.yFeeMint[0];\n else {\n bytes memory data = abi.encode(address(perpetualManager), feeData.targetHAHedge);\n uint64 hedgeRatio = _computeHedgeRatio(amountForUserInStable + stocksUsers, data);\n feePercent = _piecewiseLinear(hedgeRatio, feeData.xFeeMint, feeData.yFeeMint);\n }\n feePercent = (feePercent * feeData.bonusMalusMint) / BASE_PARAMS;\n\n amountForUserInStable = (amountForUserInStable * (BASE_PARAMS - feePercent)) / BASE_PARAMS;\n if (stocksUsers + amountForUserInStable > feeData.capOnStableMinted) revert InvalidAmount();\n }\n\n // ============================= UTILITY FUNCTIONS =============================\n // These utility functions are taken from other contracts of the protocol\n\n function _computeHedgeRatio(uint256 newStocksUsers, bytes memory data) internal view returns (uint64 ratio) {\n (address perpetualManager, uint64 targetHAHedge) = abi.decode(data, (address, uint64));\n uint256 totalHedgeAmount = IPerpetualManager(perpetualManager).totalHedgeAmount();\n newStocksUsers = (targetHAHedge * newStocksUsers) / BASE_PARAMS;\n if (newStocksUsers > totalHedgeAmount) ratio = uint64((totalHedgeAmount * BASE_PARAMS) / newStocksUsers);\n else ratio = uint64(BASE_PARAMS);\n }\n\n function _piecewiseLinear(uint64 x, uint64[] memory xArray, uint64[] memory yArray) internal pure returns (uint64) {\n if (x >= xArray[xArray.length - 1]) {\n return yArray[xArray.length - 1];\n } else if (x <= xArray[0]) {\n return yArray[0];\n } else {\n uint256 lower;\n uint256 upper = xArray.length - 1;\n uint256 mid;\n while (upper - lower > 1) {\n mid = lower + (upper - lower) / 2;\n if (xArray[mid] <= x) {\n lower = mid;\n } else {\n upper = mid;\n }\n }\n if (yArray[upper] > yArray[lower]) {\n return\n yArray[lower] +\n ((yArray[upper] - yArray[lower]) * (x - xArray[lower])) /\n (xArray[upper] - xArray[lower]);\n } else {\n return\n yArray[lower] -\n ((yArray[lower] - yArray[upper]) * (x - xArray[lower])) /\n (xArray[upper] - xArray[lower]);\n }\n }\n }\n\n function _getStableMasterAndPoolManager(\n address agToken,\n address collateral\n ) internal view returns (address stableMaster, address poolManager) {\n stableMaster = IAgTokenMainnet(agToken).stableMaster();\n (poolManager, , , ) = ROUTER.mapPoolManagers(stableMaster, collateral);\n }\n\n // ========================= CONSTANTS AND INITIALIZERS ========================\n\n IAngleRouter public constant ROUTER = IAngleRouter(0xBB755240596530be0c1DE5DFD77ec6398471561d);\n ICore public constant CORE = ICore(0x61ed74de9Ca5796cF2F8fD60D54160D47E30B7c3);\n\n bytes32 public constant STABLE = keccak256(\"STABLE\");\n uint256 public constant BASE_PARAMS = 10 ** 9;\n\n error NotInitialized();\n error InvalidAmount();\n}\n" + }, + "contracts/utils/Constants.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\nerror InsufficientAssets();\n\n/// @title Constants\n/// @author Angle Labs, Inc.\n/// @notice Constants and errors for Angle Protocol contracts\ncontract Constants {\n uint256 internal constant _BASE_9 = 1e9;\n uint256 internal constant _BASE_18 = 1e18;\n uint256 internal constant _BASE_27 = 1e27;\n uint256 internal constant _BASE_36 = 1e36;\n}\n" + }, + "contracts/vaultManager/VaultManagerERC721.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\nimport \"./VaultManagerStorage.sol\";\n\n/// @title VaultManagerERC721\n/// @author Angle Labs, Inc.\n/// @dev Base ERC721 Implementation of VaultManager\nabstract contract VaultManagerERC721 is IERC721MetadataUpgradeable, VaultManagerStorage {\n using SafeERC20 for IERC20;\n using Address for address;\n\n /// @inheritdoc IERC721MetadataUpgradeable\n string public name;\n /// @inheritdoc IERC721MetadataUpgradeable\n string public symbol;\n\n // ================================= MODIFIERS =================================\n\n /// @notice Checks if the person interacting with the vault with `vaultID` is approved\n /// @param caller Address of the person seeking to interact with the vault\n /// @param vaultID ID of the concerned vault\n modifier onlyApprovedOrOwner(address caller, uint256 vaultID) {\n if (!_isApprovedOrOwner(caller, vaultID)) revert NotApproved();\n _;\n }\n\n // ================================ ERC721 LOGIC ===============================\n\n /// @notice Checks whether a given address is approved for a vault or owns this vault\n /// @param spender Address for which vault ownership should be checked\n /// @param vaultID ID of the vault to check\n /// @return Whether the `spender` address owns or is approved for `vaultID`\n function isApprovedOrOwner(address spender, uint256 vaultID) external view returns (bool) {\n return _isApprovedOrOwner(spender, vaultID);\n }\n\n /// @inheritdoc IERC721MetadataUpgradeable\n function tokenURI(uint256 vaultID) external view returns (string memory) {\n if (!_exists(vaultID)) revert NonexistentVault();\n // There is no vault with `vaultID` equal to 0, so the following variable is\n // always greater than zero\n uint256 temp = vaultID;\n uint256 digits;\n while (temp != 0) {\n ++digits;\n temp /= 10;\n }\n bytes memory buffer = new bytes(digits);\n while (vaultID != 0) {\n digits -= 1;\n buffer[digits] = bytes1(uint8(48 + uint256(vaultID % 10)));\n vaultID /= 10;\n }\n return bytes(_baseURI).length != 0 ? string(abi.encodePacked(_baseURI, string(buffer))) : \"\";\n }\n\n /// @inheritdoc IERC721Upgradeable\n function balanceOf(address owner) external view returns (uint256) {\n if (owner == address(0)) revert ZeroAddress();\n return _balances[owner];\n }\n\n /// @inheritdoc IERC721Upgradeable\n function ownerOf(uint256 vaultID) external view returns (address) {\n return _ownerOf(vaultID);\n }\n\n /// @inheritdoc IERC721Upgradeable\n function approve(address to, uint256 vaultID) external {\n address owner = _ownerOf(vaultID);\n if (to == owner) revert ApprovalToOwner();\n if (msg.sender != owner && !isApprovedForAll(owner, msg.sender)) revert NotApproved();\n\n _approve(to, vaultID);\n }\n\n /// @inheritdoc IERC721Upgradeable\n function getApproved(uint256 vaultID) external view returns (address) {\n if (!_exists(vaultID)) revert NonexistentVault();\n return _getApproved(vaultID);\n }\n\n /// @inheritdoc IERC721Upgradeable\n function setApprovalForAll(address operator, bool approved) external {\n _setApprovalForAll(msg.sender, operator, approved);\n }\n\n /// @inheritdoc IERC721Upgradeable\n function isApprovedForAll(address owner, address operator) public view returns (bool) {\n return _operatorApprovals[owner][operator] == 1;\n }\n\n /// @inheritdoc IERC721Upgradeable\n function transferFrom(address from, address to, uint256 vaultID) external onlyApprovedOrOwner(msg.sender, vaultID) {\n _transfer(from, to, vaultID);\n }\n\n /// @inheritdoc IERC721Upgradeable\n function safeTransferFrom(address from, address to, uint256 vaultID) external {\n safeTransferFrom(from, to, vaultID, \"\");\n }\n\n /// @inheritdoc IERC721Upgradeable\n function safeTransferFrom(\n address from,\n address to,\n uint256 vaultID,\n bytes memory _data\n ) public onlyApprovedOrOwner(msg.sender, vaultID) {\n _safeTransfer(from, to, vaultID, _data);\n }\n\n // ================================ ERC165 LOGIC ===============================\n\n /// @inheritdoc IERC165Upgradeable\n function supportsInterface(bytes4 interfaceId) external pure returns (bool) {\n return\n interfaceId == type(IERC721MetadataUpgradeable).interfaceId ||\n interfaceId == type(IERC721Upgradeable).interfaceId ||\n interfaceId == type(IVaultManager).interfaceId ||\n interfaceId == type(IERC165Upgradeable).interfaceId;\n }\n\n // ================== INTERNAL FUNCTIONS FOR THE ERC721 LOGIC ==================\n\n /// @notice Internal version of the `ownerOf` function\n function _ownerOf(uint256 vaultID) internal view returns (address owner) {\n owner = _owners[vaultID];\n if (owner == address(0)) revert NonexistentVault();\n }\n\n /// @notice Internal version of the `getApproved` function\n function _getApproved(uint256 vaultID) internal view returns (address) {\n return _vaultApprovals[vaultID];\n }\n\n /// @notice Internal version of the `safeTransferFrom` function (with the data parameter)\n function _safeTransfer(address from, address to, uint256 vaultID, bytes memory _data) internal {\n _transfer(from, to, vaultID);\n if (!_checkOnERC721Received(from, to, vaultID, _data)) revert NonERC721Receiver();\n }\n\n /// @notice Checks whether a vault exists\n /// @param vaultID ID of the vault to check\n /// @return Whether `vaultID` has been created\n function _exists(uint256 vaultID) internal view returns (bool) {\n return _owners[vaultID] != address(0);\n }\n\n /// @notice Internal version of the `isApprovedOrOwner` function\n function _isApprovedOrOwner(address spender, uint256 vaultID) internal view returns (bool) {\n // The following checks if the vault exists\n address owner = _ownerOf(vaultID);\n return (spender == owner || _getApproved(vaultID) == spender || _operatorApprovals[owner][spender] == 1);\n }\n\n /// @notice Internal version of the `createVault` function\n /// Mints `vaultID` and transfers it to `to`\n /// @dev This method is equivalent to the `_safeMint` method used in OpenZeppelin ERC721 contract\n /// @dev Emits a {Transfer} event\n function _mint(address to) internal returns (uint256 vaultID) {\n if (to == address(0)) revert ZeroAddress();\n\n unchecked {\n vaultIDCount += 1;\n }\n\n vaultID = vaultIDCount;\n _beforeTokenTransfer(address(0), to, vaultID);\n\n unchecked {\n _balances[to] += 1;\n }\n\n _owners[vaultID] = to;\n emit Transfer(address(0), to, vaultID);\n if (!_checkOnERC721Received(address(0), to, vaultID, \"\")) revert NonERC721Receiver();\n }\n\n /// @notice Destroys `vaultID`\n /// @dev `vaultID` must exist\n /// @dev Emits a {Transfer} event\n function _burn(uint256 vaultID) internal {\n address owner = _ownerOf(vaultID);\n\n _beforeTokenTransfer(owner, address(0), vaultID);\n // Clear approvals\n _approve(address(0), vaultID);\n // The following line cannot underflow as the owner's balance is necessarily\n // greater than 1\n unchecked {\n _balances[owner] -= 1;\n }\n delete _owners[vaultID];\n delete vaultData[vaultID];\n\n emit Transfer(owner, address(0), vaultID);\n }\n\n /// @notice Transfers `vaultID` from `from` to `to` as opposed to {transferFrom},\n /// this imposes no restrictions on msg.sender\n /// @dev `to` cannot be the zero address and `perpetualID` must be owned by `from`\n /// @dev Emits a {Transfer} event\n function _transfer(address from, address to, uint256 vaultID) internal {\n if (_ownerOf(vaultID) != from) revert NotApproved();\n if (to == address(0)) revert ZeroAddress();\n\n _beforeTokenTransfer(from, to, vaultID);\n\n // Clear approvals from the previous owner\n _approve(address(0), vaultID);\n unchecked {\n _balances[from] -= 1;\n _balances[to] += 1;\n }\n _owners[vaultID] = to;\n\n emit Transfer(from, to, vaultID);\n }\n\n /// @notice Approves `to` to operate on `vaultID`\n function _approve(address to, uint256 vaultID) internal {\n _vaultApprovals[vaultID] = to;\n emit Approval(_ownerOf(vaultID), to, vaultID);\n }\n\n /// @notice Internal version of the `setApprovalForAll` function\n /// @dev It contains an `approver` field to be used in case someone signs a permit for a particular\n /// address, and this signature is given to the contract by another address (like a router)\n function _setApprovalForAll(address approver, address operator, bool approved) internal {\n if (operator == approver) revert ApprovalToCaller();\n uint256 approval = approved ? 1 : 0;\n _operatorApprovals[approver][operator] = approval;\n emit ApprovalForAll(approver, operator, approved);\n }\n\n /// @notice Internal function to invoke {IERC721Receiver-onERC721Received} on a target address\n /// The call is not executed if the target address is not a contract\n /// @param from Address representing the previous owner of the given token ID\n /// @param to Target address that will receive the tokens\n /// @param vaultID ID of the token to be transferred\n /// @param _data Bytes optional data to send along with the call\n /// @return Bool whether the call correctly returned the expected value\n function _checkOnERC721Received(\n address from,\n address to,\n uint256 vaultID,\n bytes memory _data\n ) private returns (bool) {\n if (to.isContract()) {\n try IERC721ReceiverUpgradeable(to).onERC721Received(msg.sender, from, vaultID, _data) returns (\n bytes4 retval\n ) {\n return retval == IERC721ReceiverUpgradeable.onERC721Received.selector;\n } catch (bytes memory reason) {\n if (reason.length == 0) {\n revert NonERC721Receiver();\n } else {\n // solhint-disable-next-line no-inline-assembly\n assembly {\n revert(add(32, reason), mload(reason))\n }\n }\n }\n } else {\n return true;\n }\n }\n\n /// @notice Hook that is called before any token transfer. This includes minting and burning.\n /// Calling conditions:\n ///\n /// - When `from` and `to` are both non-zero, `from`'s `vaultID` will be\n /// transferred to `to`.\n /// - When `from` is zero, `vaultID` will be minted for `to`.\n /// - When `to` is zero, `from`'s `vaultID` will be burned.\n /// - `from` and `to` are never both zero.\n function _beforeTokenTransfer(address from, address to, uint256 vaultID) internal virtual {}\n\n /// @notice Get `whitelistingActivated` in storage only if needed\n function _whitelistingActivated() internal view virtual returns (bool) {\n return whitelistingActivated;\n }\n}\n" + }, + "contracts/vaultManager/VaultManagerPermit.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\nimport \"./VaultManagerERC721.sol\";\nimport \"../interfaces/external/IERC1271.sol\";\n\n/// @title VaultManagerPermit\n/// @author Angle Labs, Inc.\n/// @dev Base Implementation of permit functions for the `VaultManager` contract\nabstract contract VaultManagerPermit is Initializable, VaultManagerERC721 {\n using Address for address;\n\n mapping(address => uint256) private _nonces;\n /* solhint-disable var-name-mixedcase */\n bytes32 private _HASHED_NAME;\n bytes32 private _HASHED_VERSION;\n bytes32 private _PERMIT_TYPEHASH;\n /* solhint-enable var-name-mixedcase */\n\n error ExpiredDeadline();\n error InvalidSignature();\n\n //solhint-disable-next-line\n function __ERC721Permit_init(string memory _name) internal onlyInitializing {\n _PERMIT_TYPEHASH = keccak256(\n \"Permit(address owner,address spender,bool approved,uint256 nonce,uint256 deadline)\"\n );\n _HASHED_NAME = keccak256(bytes(_name));\n _HASHED_VERSION = keccak256(bytes(\"1\"));\n }\n\n /// @notice Allows an address to give or revoke approval for all its vaults to another address\n /// @param owner Address signing the permit and giving (or revoking) its approval for all the controlled vaults\n /// @param spender Address to give approval to\n /// @param approved Whether to give or revoke the approval\n /// @param deadline Deadline parameter for the signature to be valid\n /// @dev The `v`, `r`, and `s` parameters are used as signature data\n function permit(\n address owner,\n address spender,\n bool approved,\n uint256 deadline,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) external {\n if (block.timestamp > deadline) revert ExpiredDeadline();\n // Additional signature checks performed in the `ECDSAUpgradeable.recover` function\n if (uint256(s) > 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D576E7357A4501DDFE92F46681B20A0 || (v != 27 && v != 28))\n revert InvalidSignature();\n\n bytes32 digest = keccak256(\n abi.encodePacked(\n \"\\x19\\x01\",\n _domainSeparatorV4(),\n keccak256(\n abi.encode(\n _PERMIT_TYPEHASH,\n // 0x3f43a9c6bafb5c7aab4e0cfe239dc5d4c15caf0381c6104188191f78a6640bd8,\n owner,\n spender,\n approved,\n _useNonce(owner),\n deadline\n )\n )\n )\n );\n if (owner.isContract()) {\n if (IERC1271(owner).isValidSignature(digest, abi.encodePacked(r, s, v)) != 0x1626ba7e)\n revert InvalidSignature();\n } else {\n address signer = ecrecover(digest, v, r, s);\n if (signer != owner || signer == address(0)) revert InvalidSignature();\n }\n\n _setApprovalForAll(owner, spender, approved);\n }\n\n /// @notice Returns the current nonce for an `owner` address\n function nonces(address owner) public view returns (uint256) {\n return _nonces[owner];\n }\n\n /// @notice Returns the domain separator for the current chain.\n // solhint-disable-next-line func-name-mixedcase\n function DOMAIN_SEPARATOR() external view returns (bytes32) {\n return _domainSeparatorV4();\n }\n\n /// @notice Internal version of the `DOMAIN_SEPARATOR` function\n function _domainSeparatorV4() internal view returns (bytes32) {\n return\n keccak256(\n abi.encode(\n // keccak256('EIP712Domain(string name,string version,uint256 chainId,address verifyingContract)')\n 0x8b73c3c69bb8fe3d512ecc4cf759cc79239f7b179b0ffacaa9a75d522b39400f,\n _HASHED_NAME,\n _HASHED_VERSION,\n block.chainid,\n address(this)\n )\n );\n }\n\n /// @notice Consumes a nonce for an address: returns the current value and increments it\n function _useNonce(address owner) internal returns (uint256 current) {\n current = _nonces[owner];\n _nonces[owner] = current + 1;\n }\n\n uint256[49] private __gap;\n}\n" + }, + "contracts/vaultManager/VaultManagerStorage.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\nimport \"@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/token/ERC20/extensions/draft-IERC20PermitUpgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/token/ERC721/IERC721ReceiverUpgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/interfaces/IERC721MetadataUpgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/utils/introspection/IERC165Upgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/utils/AddressUpgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/security/ReentrancyGuardUpgradeable.sol\";\nimport \"@openzeppelin/contracts/token/ERC20/extensions/IERC20Metadata.sol\";\nimport \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\nimport \"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\";\n\nimport \"../interfaces/IAgToken.sol\";\nimport \"../interfaces/IOracle.sol\";\nimport \"../interfaces/ISwapper.sol\";\nimport \"../interfaces/ITreasury.sol\";\nimport \"../interfaces/IVaultManager.sol\";\nimport \"../interfaces/governance/IVeBoostProxy.sol\";\n\n/// @title VaultManagerStorage\n/// @author Angle Labs, Inc.\n/// @dev Variables, references, parameters and events needed in the `VaultManager` contract\n// solhint-disable-next-line max-states-count\ncontract VaultManagerStorage is IVaultManagerStorage, Initializable, ReentrancyGuardUpgradeable {\n /// @notice Base used for parameter computation: almost all the parameters of this contract are set in `BASE_PARAMS`\n uint256 public constant BASE_PARAMS = 10 ** 9;\n /// @notice Base used for interest rate computation\n uint256 public constant BASE_INTEREST = 10 ** 27;\n /// @notice Used for interest rate computation\n uint256 public constant HALF_BASE_INTEREST = 10 ** 27 / 2;\n\n // ================================= REFERENCES ================================\n\n /// @inheritdoc IVaultManagerStorage\n ITreasury public treasury;\n /// @inheritdoc IVaultManagerStorage\n IERC20 public collateral;\n /// @inheritdoc IVaultManagerStorage\n IAgToken public stablecoin;\n /// @inheritdoc IVaultManagerStorage\n IOracle public oracle;\n /// @notice Reference to the contract which computes adjusted veANGLE balances for liquidators boosts\n IVeBoostProxy public veBoostProxy;\n /// @notice Base of the collateral\n uint256 internal _collatBase;\n\n // ================================= PARAMETERS ================================\n // Unless specified otherwise, parameters of this contract are expressed in `BASE_PARAMS`\n\n /// @notice Maximum amount of stablecoins that can be issued with this contract (in `BASE_TOKENS`). This parameter should\n /// not be bigger than `type(uint256).max / BASE_INTEREST` otherwise there may be some overflows in the `increaseDebt` function\n uint256 public debtCeiling;\n /// @notice Threshold veANGLE balance values for the computation of the boost for liquidators: the length of this array\n /// should normally be 2. The base of the x-values in this array should be `BASE_TOKENS`\n uint256[] public xLiquidationBoost;\n /// @notice Values of the liquidation boost at the threshold values of x\n uint256[] public yLiquidationBoost;\n /// @inheritdoc IVaultManagerStorage\n uint64 public collateralFactor;\n /// @notice Maximum Health factor at which a vault can end up after a liquidation (unless it's fully liquidated)\n uint64 public targetHealthFactor;\n /// @notice Upfront fee taken when borrowing stablecoins: this fee is optional and should in practice not be used\n uint64 public borrowFee;\n /// @notice Upfront fee taken when repaying stablecoins: this fee is optional as well. It should be smaller\n /// than the liquidation surcharge (cf below) to avoid exploits where people voluntarily get liquidated at a 0\n /// discount to pay smaller repaying fees\n uint64 public repayFee;\n /// @notice Per second interest taken to borrowers taking agToken loans. Contrarily to other parameters, it is set in `BASE_INTEREST`\n /// that is to say in base 10**27\n uint64 public interestRate;\n /// @notice Fee taken by the protocol during a liquidation. Technically, this value is not the fee per se, it's 1 - fee.\n /// For instance for a 2% fee, `liquidationSurcharge` should be 98%\n uint64 public liquidationSurcharge;\n /// @notice Maximum discount given to liquidators\n uint64 public maxLiquidationDiscount;\n /// @notice Whether whitelisting is required to own a vault or not\n bool public whitelistingActivated;\n /// @notice Whether the contract is paused or not\n bool public paused;\n\n // ================================= VARIABLES =================================\n\n /// @notice Timestamp at which the `interestAccumulator` was updated\n uint256 public lastInterestAccumulatorUpdated;\n /// @inheritdoc IVaultManagerStorage\n uint256 public interestAccumulator;\n /// @inheritdoc IVaultManagerStorage\n uint256 public totalNormalizedDebt;\n /// @notice Surplus accumulated by the contract: surplus is always in stablecoins, and is then reset\n /// when the value is communicated to the treasury contract\n uint256 public surplus;\n /// @notice Bad debt made from liquidated vaults which ended up having no collateral and a positive amount\n /// of stablecoins\n uint256 public badDebt;\n\n // ================================== MAPPINGS =================================\n\n /// @inheritdoc IVaultManagerStorage\n mapping(uint256 => Vault) public vaultData;\n /// @notice Maps an address to 1 if it's whitelisted and can open or own a vault\n mapping(address => uint256) public isWhitelisted;\n\n // ================================ ERC721 DATA ================================\n\n /// @inheritdoc IVaultManagerStorage\n uint256 public vaultIDCount;\n\n /// @notice URI\n string internal _baseURI;\n\n // Mapping from `vaultID` to owner address\n mapping(uint256 => address) internal _owners;\n\n // Mapping from owner address to vault owned count\n mapping(address => uint256) internal _balances;\n\n // Mapping from `vaultID` to approved address\n mapping(uint256 => address) internal _vaultApprovals;\n\n // Mapping from owner to operator approvals\n mapping(address => mapping(address => uint256)) internal _operatorApprovals;\n\n uint256[50] private __gap;\n\n // =================================== EVENTS ==================================\n\n event AccruedToTreasury(uint256 surplusEndValue, uint256 badDebtEndValue);\n event CollateralAmountUpdated(uint256 vaultID, uint256 collateralAmount, uint8 isIncrease);\n event InterestAccumulatorUpdated(uint256 value, uint256 timestamp);\n event InternalDebtUpdated(uint256 vaultID, uint256 internalAmount, uint8 isIncrease);\n event FiledUint64(uint64 param, bytes32 what);\n event DebtCeilingUpdated(uint256 debtCeiling);\n event LiquidationBoostParametersUpdated(address indexed _veBoostProxy, uint256[] xBoost, uint256[] yBoost);\n event LiquidatedVaults(uint256[] vaultIDs);\n event DebtTransferred(uint256 srcVaultID, uint256 dstVaultID, address dstVaultManager, uint256 amount);\n\n // =================================== ERRORS ==================================\n\n error ApprovalToOwner();\n error ApprovalToCaller();\n error DustyLeftoverAmount();\n error DebtCeilingExceeded();\n error HealthyVault();\n error IncompatibleLengths();\n error InsolventVault();\n error InvalidParameterValue();\n error InvalidParameterType();\n error InvalidSetOfParameters();\n error InvalidTreasury();\n error NonERC721Receiver();\n error NonexistentVault();\n error NotApproved();\n error NotGovernor();\n error NotGovernorOrGuardian();\n error NotTreasury();\n error NotWhitelisted();\n error NotVaultManager();\n error Paused();\n error TooHighParameterValue();\n error TooSmallParameterValue();\n error ZeroAddress();\n\n /// @custom:oz-upgrades-unsafe-allow constructor\n constructor() initializer {}\n}\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 1000000 + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers", + "metadata", + "devdoc", + "userdoc", + "storageLayout", + "evm.gasEstimates", + "devdoc", + "userdoc" + ], + "": [ + "ast" + ] + } + }, + "metadata": { + "useLiteralContent": true + } + } +} \ No newline at end of file diff --git a/deployments/mainnet/AgToken_Implementation.json b/deployments/mainnet/AgToken_Implementation.json index 11f403dc..6b57f526 100644 --- a/deployments/mainnet/AgToken_Implementation.json +++ b/deployments/mainnet/AgToken_Implementation.json @@ -1,5 +1,5 @@ { - "address": "0xe59D2c2CfE8459c53917D908177aa25fea5B919b", + "address": "0x7a19A7F19b664eE8BEe9aE5F7dB5005Eaaa7644e", "abi": [ { "inputs": [], @@ -21,11 +21,6 @@ "name": "InvalidTreasury", "type": "error" }, - { - "inputs": [], - "name": "NotGovernor", - "type": "error" - }, { "inputs": [], "name": "NotMinter", @@ -36,11 +31,6 @@ "name": "NotTreasury", "type": "error" }, - { - "inputs": [], - "name": "TreasuryAlreadyInitialized", - "type": "error" - }, { "anonymous": false, "inputs": [ @@ -66,6 +56,19 @@ "name": "Approval", "type": "event" }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint8", + "name": "version", + "type": "uint8" + } + ], + "name": "Initialized", + "type": "event" + }, { "anonymous": false, "inputs": [ @@ -233,47 +236,6 @@ "stateMutability": "nonpayable", "type": "function" }, - { - "inputs": [ - { - "internalType": "address", - "name": "account", - "type": "address" - }, - { - "internalType": "uint256", - "name": "amount", - "type": "uint256" - }, - { - "internalType": "address", - "name": "poolManager", - "type": "address" - } - ], - "name": "burnFromNoRedeem", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "uint256", - "name": "amount", - "type": "uint256" - }, - { - "internalType": "address", - "name": "poolManager", - "type": "address" - } - ], - "name": "burnNoRedeem", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, { "inputs": [ { @@ -380,7 +342,7 @@ }, { "internalType": "address", - "name": "stableMaster_", + "name": "_treasury", "type": "address" } ], @@ -527,32 +489,6 @@ "stateMutability": "nonpayable", "type": "function" }, - { - "inputs": [ - { - "internalType": "address", - "name": "_treasury", - "type": "address" - } - ], - "name": "setUpTreasury", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [], - "name": "stableMaster", - "outputs": [ - { - "internalType": "address", - "name": "", - "type": "address" - } - ], - "stateMutability": "view", - "type": "function" - }, { "inputs": [], "name": "symbol", @@ -583,7 +519,7 @@ "inputs": [ { "internalType": "address", - "name": "recipient", + "name": "to", "type": "address" }, { @@ -607,12 +543,12 @@ "inputs": [ { "internalType": "address", - "name": "sender", + "name": "from", "type": "address" }, { "internalType": "address", - "name": "recipient", + "name": "to", "type": "address" }, { @@ -644,45 +580,46 @@ ], "stateMutability": "view", "type": "function" - }, - { - "inputs": [], - "name": "treasuryInitialized", - "outputs": [ - { - "internalType": "bool", - "name": "", - "type": "bool" - } - ], - "stateMutability": "view", - "type": "function" } ], - "transactionHash": "0x14d11d7bed3f43bd3c4be6ddb6b6fc9a51236e990288cd19bdec05602f3c4c5f", + "transactionHash": "0xa45eb8c054eb2731115a43d0275647e4d0088187e90215b47c991ff28d8e016a", "receipt": { "to": null, "from": "0xfdA462548Ce04282f4B6D6619823a7C64Fdc0185", - "contractAddress": "0xe59D2c2CfE8459c53917D908177aa25fea5B919b", - "transactionIndex": 45, - "gasUsed": "2337625", - "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", - "blockHash": "0x1d9e8e30151e5135ece2bb04a1e3a0055e73ad778f6cd705c0037db2700097eb", - "transactionHash": "0x14d11d7bed3f43bd3c4be6ddb6b6fc9a51236e990288cd19bdec05602f3c4c5f", - "logs": [], - "blockNumber": 14966360, - "cumulativeGasUsed": "3864270", + "contractAddress": "0x7a19A7F19b664eE8BEe9aE5F7dB5005Eaaa7644e", + "transactionIndex": 32, + "gasUsed": "2120717", + "logsBloom": "0x00000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000020000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000080000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "blockHash": "0x1271c7db4add0ff119daa7daa266d0be39350775d0205f14b97d3ef961a0ae5c", + "transactionHash": "0xa45eb8c054eb2731115a43d0275647e4d0088187e90215b47c991ff28d8e016a", + "logs": [ + { + "transactionIndex": 32, + "blockNumber": 18975606, + "transactionHash": "0xa45eb8c054eb2731115a43d0275647e4d0088187e90215b47c991ff28d8e016a", + "address": "0x7a19A7F19b664eE8BEe9aE5F7dB5005Eaaa7644e", + "topics": [ + "0x7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb3847402498" + ], + "data": "0x0000000000000000000000000000000000000000000000000000000000000001", + "logIndex": 36, + "blockHash": "0x1271c7db4add0ff119daa7daa266d0be39350775d0205f14b97d3ef961a0ae5c" + } + ], + "blockNumber": 18975606, + "cumulativeGasUsed": "3840706", "status": 1, "byzantium": true }, "args": [], - "solcInputHash": "eb7de3603cc573bcb7c8cc81b533de56", - "metadata": "{\"compiler\":{\"version\":\"0.8.12+commit.f00d7308\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[],\"name\":\"BurnAmountExceedsAllowance\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidSender\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidTreasury\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"NotGovernor\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"NotMinter\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"NotTreasury\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"TreasuryAlreadyInitialized\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"spender\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"}],\"name\":\"Approval\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"minter\",\"type\":\"address\"}],\"name\":\"MinterToggled\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"}],\"name\":\"Transfer\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"_treasury\",\"type\":\"address\"}],\"name\":\"TreasuryUpdated\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"DOMAIN_SEPARATOR\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"minter\",\"type\":\"address\"}],\"name\":\"addMinter\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"spender\",\"type\":\"address\"}],\"name\":\"allowance\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"spender\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"approve\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"}],\"name\":\"balanceOf\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"burner\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"}],\"name\":\"burnFrom\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"poolManager\",\"type\":\"address\"}],\"name\":\"burnFromNoRedeem\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"poolManager\",\"type\":\"address\"}],\"name\":\"burnNoRedeem\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"burner\",\"type\":\"address\"}],\"name\":\"burnSelf\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"burnStablecoin\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"decimals\",\"outputs\":[{\"internalType\":\"uint8\",\"name\":\"\",\"type\":\"uint8\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"spender\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"subtractedValue\",\"type\":\"uint256\"}],\"name\":\"decreaseAllowance\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"spender\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"addedValue\",\"type\":\"uint256\"}],\"name\":\"increaseAllowance\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"string\",\"name\":\"name_\",\"type\":\"string\"},{\"internalType\":\"string\",\"name\":\"symbol_\",\"type\":\"string\"},{\"internalType\":\"address\",\"name\":\"stableMaster_\",\"type\":\"address\"}],\"name\":\"initialize\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"isMinter\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"mint\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"name\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"}],\"name\":\"nonces\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"spender\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"deadline\",\"type\":\"uint256\"},{\"internalType\":\"uint8\",\"name\":\"v\",\"type\":\"uint8\"},{\"internalType\":\"bytes32\",\"name\":\"r\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32\",\"name\":\"s\",\"type\":\"bytes32\"}],\"name\":\"permit\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"minter\",\"type\":\"address\"}],\"name\":\"removeMinter\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_treasury\",\"type\":\"address\"}],\"name\":\"setTreasury\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_treasury\",\"type\":\"address\"}],\"name\":\"setUpTreasury\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"stableMaster\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"symbol\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"totalSupply\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"recipient\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"transfer\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"recipient\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"transferFrom\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"treasury\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"treasuryInitialized\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"}],\"devdoc\":{\"author\":\"Angle Core Team\",\"details\":\"This contract is used to create and handle the stablecoins of Angle protocolIt is still possible for any address to burn its agTokens without redeeming collateral in exchangeThis contract is the upgraded version of the AgToken that was first deployed on Ethereum mainnet\",\"kind\":\"dev\",\"methods\":{\"DOMAIN_SEPARATOR()\":{\"details\":\"See {IERC20Permit-DOMAIN_SEPARATOR}.\"},\"addMinter(address)\":{\"details\":\"Zero address checks are performed directly in the `Treasury` contract\",\"params\":{\"minter\":\"Minter address to add\"}},\"allowance(address,address)\":{\"details\":\"See {IERC20-allowance}.\"},\"approve(address,uint256)\":{\"details\":\"See {IERC20-approve}. Requirements: - `spender` cannot be the zero address.\"},\"balanceOf(address)\":{\"details\":\"See {IERC20-balanceOf}.\"},\"burnFrom(uint256,address,address)\":{\"details\":\"This method is to be called by a contract with the minter right after being requested to do so by a `sender` address willing to burn tokens from another `burner` addressThe method checks the allowance between the `sender` and the `burner`\",\"params\":{\"amount\":\"Amount of tokens to burn\",\"burner\":\"Address to burn from\",\"sender\":\"Address which requested the burn from `burner`\"}},\"burnFromNoRedeem(address,uint256,address)\":{\"params\":{\"account\":\"Account to burn on behalf of\",\"amount\":\"Amount to burn\",\"poolManager\":\"Reference to the `PoolManager` contract for which the `stocksUsers` will need to be updated\"}},\"burnNoRedeem(uint256,address)\":{\"details\":\"When calling this function, people should specify the `poolManager` for which they want to decrease the `stocksUsers`: this is a way for the protocol to maintain healthy accounting variables\",\"params\":{\"amount\":\"Amount to burn\",\"poolManager\":\"Reference to the `PoolManager` contract for which the `stocksUsers` will need to be updated\"}},\"burnSelf(uint256,address)\":{\"details\":\"This method is to be called by a contract with a minter right on the AgToken after being requested to do so by an address willing to burn tokens from its address\",\"params\":{\"amount\":\"Amount of tokens to burn\",\"burner\":\"Address to burn from\"}},\"burnStablecoin(uint256)\":{\"details\":\"This function can typically be called if there is a settlement mechanism to burn stablecoins\",\"params\":{\"amount\":\"Amount of stablecoins to burn\"}},\"constructor\":{\"custom:oz-upgrades-unsafe-allow\":\"constructor\"},\"decimals()\":{\"details\":\"Returns the number of decimals used to get its user representation. For example, if `decimals` equals `2`, a balance of `505` tokens should be displayed to a user as `5.05` (`505 / 10 ** 2`). Tokens usually opt for a value of 18, imitating the relationship between Ether and Wei. This is the value {ERC20} uses, unless this function is overridden; NOTE: This information is only used for _display_ purposes: it in no way affects any of the arithmetic of the contract, including {IERC20-balanceOf} and {IERC20-transfer}.\"},\"decreaseAllowance(address,uint256)\":{\"details\":\"Atomically decreases the allowance granted to `spender` by the caller. This is an alternative to {approve} that can be used as a mitigation for problems described in {IERC20-approve}. Emits an {Approval} event indicating the updated allowance. Requirements: - `spender` cannot be the zero address. - `spender` must have allowance for the caller of at least `subtractedValue`.\"},\"increaseAllowance(address,uint256)\":{\"details\":\"Atomically increases the allowance granted to `spender` by the caller. This is an alternative to {approve} that can be used as a mitigation for problems described in {IERC20-approve}. Emits an {Approval} event indicating the updated allowance. Requirements: - `spender` cannot be the zero address.\"},\"initialize(string,string,address)\":{\"details\":\"By default, agTokens are ERC-20 tokens with 18 decimals\",\"params\":{\"name_\":\"Name of the token\",\"stableMaster_\":\"Reference to the `StableMaster` contract associated to this agToken\",\"symbol_\":\"Symbol of the token\"}},\"mint(address,uint256)\":{\"details\":\"The contracts allowed to issue agTokens are the `StableMaster` contract, `VaultManager` contracts associated to this stablecoin as well as the flash loan module (if activated) and potentially contracts whitelisted by governance\",\"params\":{\"account\":\"Address to mint to\",\"amount\":\"Amount to mint\"}},\"name()\":{\"details\":\"Returns the name of the token.\"},\"nonces(address)\":{\"details\":\"See {IERC20Permit-nonces}.\"},\"permit(address,address,uint256,uint256,uint8,bytes32,bytes32)\":{\"details\":\"See {IERC20Permit-permit}.\"},\"removeMinter(address)\":{\"details\":\"This function can also be called by a minter wishing to revoke itself\",\"params\":{\"minter\":\"Minter address to remove\"}},\"setTreasury(address)\":{\"params\":{\"_treasury\":\"New treasury address\"}},\"setUpTreasury(address)\":{\"details\":\"The address calling this function has to be hard-coded in the contractCan be called only once\",\"params\":{\"_treasury\":\"Treasury contract to add\"}},\"symbol()\":{\"details\":\"Returns the symbol of the token, usually a shorter version of the name.\"},\"totalSupply()\":{\"details\":\"See {IERC20-totalSupply}.\"},\"transfer(address,uint256)\":{\"details\":\"See {IERC20-transfer}. Requirements: - `recipient` cannot be the zero address. - the caller must have a balance of at least `amount`.\"},\"transferFrom(address,address,uint256)\":{\"details\":\"See {IERC20-transferFrom}. Emits an {Approval} event indicating the updated allowance. This is not required by the EIP. See the note at the beginning of {ERC20}. Requirements: - `sender` and `recipient` cannot be the zero address. - `sender` must have a balance of at least `amount`. - the caller must have allowance for ``sender``'s tokens of at least `amount`.\"}},\"stateVariables\":{\"isMinter\":{\"params\":{\"minter\":\"Address for which the minting right should be checked\"},\"return\":\"Whether the address has the right to mint agTokens or not\",\"returns\":{\"_0\":\"Whether the address has the right to mint agTokens or not\"}}},\"title\":\"AgToken\",\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{\"addMinter(address)\":{\"notice\":\"Adds a minter in the contract\"},\"burnFrom(uint256,address,address)\":{\"notice\":\"Burns `amount` tokens from a `burner` address after being asked to by `sender`\"},\"burnFromNoRedeem(address,uint256,address)\":{\"notice\":\"Burns `amount` of agToken on behalf of another account without redeeming collateral back\"},\"burnNoRedeem(uint256,address)\":{\"notice\":\"Destroys `amount` token from the caller without giving collateral back\"},\"burnSelf(uint256,address)\":{\"notice\":\"Burns `amount` tokens from a `burner` address\"},\"burnStablecoin(uint256)\":{\"notice\":\"Allows anyone to burn agToken without redeeming collateral back\"},\"initialize(string,string,address)\":{\"notice\":\"Initializes the `AgToken` contract\"},\"isMinter(address)\":{\"notice\":\"Checks whether an address has the right to mint agTokens\"},\"mint(address,uint256)\":{\"notice\":\"Lets the `StableMaster` contract or another whitelisted contract mint agTokens\"},\"removeMinter(address)\":{\"notice\":\"Removes a minter from the contract\"},\"setTreasury(address)\":{\"notice\":\"Sets a new treasury contract\"},\"setUpTreasury(address)\":{\"notice\":\"Sets up the treasury contract in this AgToken contract\"},\"stableMaster()\":{\"notice\":\"Reference to the `StableMaster` contract associated to this `AgToken`\"},\"treasury()\":{\"notice\":\"Reference to the treasury contract which can grant minting rights\"},\"treasuryInitialized()\":{\"notice\":\"Boolean to check whether the contract has been reinitialized after its upgrade\"}},\"notice\":\"Base contract for agToken, that is to say Angle's stablecoins\",\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/agToken/AgToken.sol\":\"AgToken\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":1000000},\"remappings\":[]},\"sources\":{\"@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (proxy/utils/Initializable.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../../utils/AddressUpgradeable.sol\\\";\\n\\n/**\\n * @dev This is a base contract to aid in writing upgradeable contracts, or any kind of contract that will be deployed\\n * behind a proxy. Since a proxied contract can't have a constructor, it's common to move constructor logic to an\\n * external initializer function, usually called `initialize`. It then becomes necessary to protect this initializer\\n * function so it can only be called once. The {initializer} modifier provided by this contract will have this effect.\\n *\\n * TIP: To avoid leaving the proxy in an uninitialized state, the initializer function should be called as early as\\n * possible by providing the encoded function call as the `_data` argument to {ERC1967Proxy-constructor}.\\n *\\n * CAUTION: When used with inheritance, manual care must be taken to not invoke a parent initializer twice, or to ensure\\n * that all initializers are idempotent. This is not verified automatically as constructors are by Solidity.\\n *\\n * [CAUTION]\\n * ====\\n * Avoid leaving a contract uninitialized.\\n *\\n * An uninitialized contract can be taken over by an attacker. This applies to both a proxy and its implementation\\n * contract, which may impact the proxy. To initialize the implementation contract, you can either invoke the\\n * initializer manually, or you can include a constructor to automatically mark it as initialized when it is deployed:\\n *\\n * [.hljs-theme-light.nopadding]\\n * ```\\n * /// @custom:oz-upgrades-unsafe-allow constructor\\n * constructor() initializer {}\\n * ```\\n * ====\\n */\\nabstract contract Initializable {\\n /**\\n * @dev Indicates that the contract has been initialized.\\n */\\n bool private _initialized;\\n\\n /**\\n * @dev Indicates that the contract is in the process of being initialized.\\n */\\n bool private _initializing;\\n\\n /**\\n * @dev Modifier to protect an initializer function from being invoked twice.\\n */\\n modifier initializer() {\\n // If the contract is initializing we ignore whether _initialized is set in order to support multiple\\n // inheritance patterns, but we only do this in the context of a constructor, because in other contexts the\\n // contract may have been reentered.\\n require(_initializing ? _isConstructor() : !_initialized, \\\"Initializable: contract is already initialized\\\");\\n\\n bool isTopLevelCall = !_initializing;\\n if (isTopLevelCall) {\\n _initializing = true;\\n _initialized = true;\\n }\\n\\n _;\\n\\n if (isTopLevelCall) {\\n _initializing = false;\\n }\\n }\\n\\n /**\\n * @dev Modifier to protect an initialization function so that it can only be invoked by functions with the\\n * {initializer} modifier, directly or indirectly.\\n */\\n modifier onlyInitializing() {\\n require(_initializing, \\\"Initializable: contract is not initializing\\\");\\n _;\\n }\\n\\n function _isConstructor() private view returns (bool) {\\n return !AddressUpgradeable.isContract(address(this));\\n }\\n}\\n\",\"keccak256\":\"0x68861bcc80cacbd498efde75aab6c74a486cc48262660d326c8d7530d9752097\",\"license\":\"MIT\"},\"@openzeppelin/contracts-upgradeable/token/ERC20/ERC20Upgradeable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (token/ERC20/ERC20.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"./IERC20Upgradeable.sol\\\";\\nimport \\\"./extensions/IERC20MetadataUpgradeable.sol\\\";\\nimport \\\"../../utils/ContextUpgradeable.sol\\\";\\nimport \\\"../../proxy/utils/Initializable.sol\\\";\\n\\n/**\\n * @dev Implementation of the {IERC20} interface.\\n *\\n * This implementation is agnostic to the way tokens are created. This means\\n * that a supply mechanism has to be added in a derived contract using {_mint}.\\n * For a generic mechanism see {ERC20PresetMinterPauser}.\\n *\\n * TIP: For a detailed writeup see our guide\\n * https://forum.zeppelin.solutions/t/how-to-implement-erc20-supply-mechanisms/226[How\\n * to implement supply mechanisms].\\n *\\n * We have followed general OpenZeppelin Contracts guidelines: functions revert\\n * instead returning `false` on failure. This behavior is nonetheless\\n * conventional and does not conflict with the expectations of ERC20\\n * applications.\\n *\\n * Additionally, an {Approval} event is emitted on calls to {transferFrom}.\\n * This allows applications to reconstruct the allowance for all accounts just\\n * by listening to said events. Other implementations of the EIP may not emit\\n * these events, as it isn't required by the specification.\\n *\\n * Finally, the non-standard {decreaseAllowance} and {increaseAllowance}\\n * functions have been added to mitigate the well-known issues around setting\\n * allowances. See {IERC20-approve}.\\n */\\ncontract ERC20Upgradeable is Initializable, ContextUpgradeable, IERC20Upgradeable, IERC20MetadataUpgradeable {\\n mapping(address => uint256) private _balances;\\n\\n mapping(address => mapping(address => uint256)) private _allowances;\\n\\n uint256 private _totalSupply;\\n\\n string private _name;\\n string private _symbol;\\n\\n /**\\n * @dev Sets the values for {name} and {symbol}.\\n *\\n * The default value of {decimals} is 18. To select a different value for\\n * {decimals} you should overload it.\\n *\\n * All two of these values are immutable: they can only be set once during\\n * construction.\\n */\\n function __ERC20_init(string memory name_, string memory symbol_) internal onlyInitializing {\\n __Context_init_unchained();\\n __ERC20_init_unchained(name_, symbol_);\\n }\\n\\n function __ERC20_init_unchained(string memory name_, string memory symbol_) internal onlyInitializing {\\n _name = name_;\\n _symbol = symbol_;\\n }\\n\\n /**\\n * @dev Returns the name of the token.\\n */\\n function name() public view virtual override returns (string memory) {\\n return _name;\\n }\\n\\n /**\\n * @dev Returns the symbol of the token, usually a shorter version of the\\n * name.\\n */\\n function symbol() public view virtual override returns (string memory) {\\n return _symbol;\\n }\\n\\n /**\\n * @dev Returns the number of decimals used to get its user representation.\\n * For example, if `decimals` equals `2`, a balance of `505` tokens should\\n * be displayed to a user as `5.05` (`505 / 10 ** 2`).\\n *\\n * Tokens usually opt for a value of 18, imitating the relationship between\\n * Ether and Wei. This is the value {ERC20} uses, unless this function is\\n * overridden;\\n *\\n * NOTE: This information is only used for _display_ purposes: it in\\n * no way affects any of the arithmetic of the contract, including\\n * {IERC20-balanceOf} and {IERC20-transfer}.\\n */\\n function decimals() public view virtual override returns (uint8) {\\n return 18;\\n }\\n\\n /**\\n * @dev See {IERC20-totalSupply}.\\n */\\n function totalSupply() public view virtual override returns (uint256) {\\n return _totalSupply;\\n }\\n\\n /**\\n * @dev See {IERC20-balanceOf}.\\n */\\n function balanceOf(address account) public view virtual override returns (uint256) {\\n return _balances[account];\\n }\\n\\n /**\\n * @dev See {IERC20-transfer}.\\n *\\n * Requirements:\\n *\\n * - `recipient` cannot be the zero address.\\n * - the caller must have a balance of at least `amount`.\\n */\\n function transfer(address recipient, uint256 amount) public virtual override returns (bool) {\\n _transfer(_msgSender(), recipient, amount);\\n return true;\\n }\\n\\n /**\\n * @dev See {IERC20-allowance}.\\n */\\n function allowance(address owner, address spender) public view virtual override returns (uint256) {\\n return _allowances[owner][spender];\\n }\\n\\n /**\\n * @dev See {IERC20-approve}.\\n *\\n * Requirements:\\n *\\n * - `spender` cannot be the zero address.\\n */\\n function approve(address spender, uint256 amount) public virtual override returns (bool) {\\n _approve(_msgSender(), spender, amount);\\n return true;\\n }\\n\\n /**\\n * @dev See {IERC20-transferFrom}.\\n *\\n * Emits an {Approval} event indicating the updated allowance. This is not\\n * required by the EIP. See the note at the beginning of {ERC20}.\\n *\\n * Requirements:\\n *\\n * - `sender` and `recipient` cannot be the zero address.\\n * - `sender` must have a balance of at least `amount`.\\n * - the caller must have allowance for ``sender``'s tokens of at least\\n * `amount`.\\n */\\n function transferFrom(\\n address sender,\\n address recipient,\\n uint256 amount\\n ) public virtual override returns (bool) {\\n _transfer(sender, recipient, amount);\\n\\n uint256 currentAllowance = _allowances[sender][_msgSender()];\\n require(currentAllowance >= amount, \\\"ERC20: transfer amount exceeds allowance\\\");\\n unchecked {\\n _approve(sender, _msgSender(), currentAllowance - amount);\\n }\\n\\n return true;\\n }\\n\\n /**\\n * @dev Atomically increases the allowance granted to `spender` by the caller.\\n *\\n * This is an alternative to {approve} that can be used as a mitigation for\\n * problems described in {IERC20-approve}.\\n *\\n * Emits an {Approval} event indicating the updated allowance.\\n *\\n * Requirements:\\n *\\n * - `spender` cannot be the zero address.\\n */\\n function increaseAllowance(address spender, uint256 addedValue) public virtual returns (bool) {\\n _approve(_msgSender(), spender, _allowances[_msgSender()][spender] + addedValue);\\n return true;\\n }\\n\\n /**\\n * @dev Atomically decreases the allowance granted to `spender` by the caller.\\n *\\n * This is an alternative to {approve} that can be used as a mitigation for\\n * problems described in {IERC20-approve}.\\n *\\n * Emits an {Approval} event indicating the updated allowance.\\n *\\n * Requirements:\\n *\\n * - `spender` cannot be the zero address.\\n * - `spender` must have allowance for the caller of at least\\n * `subtractedValue`.\\n */\\n function decreaseAllowance(address spender, uint256 subtractedValue) public virtual returns (bool) {\\n uint256 currentAllowance = _allowances[_msgSender()][spender];\\n require(currentAllowance >= subtractedValue, \\\"ERC20: decreased allowance below zero\\\");\\n unchecked {\\n _approve(_msgSender(), spender, currentAllowance - subtractedValue);\\n }\\n\\n return true;\\n }\\n\\n /**\\n * @dev Moves `amount` of tokens from `sender` to `recipient`.\\n *\\n * This internal function is equivalent to {transfer}, and can be used to\\n * e.g. implement automatic token fees, slashing mechanisms, etc.\\n *\\n * Emits a {Transfer} event.\\n *\\n * Requirements:\\n *\\n * - `sender` cannot be the zero address.\\n * - `recipient` cannot be the zero address.\\n * - `sender` must have a balance of at least `amount`.\\n */\\n function _transfer(\\n address sender,\\n address recipient,\\n uint256 amount\\n ) internal virtual {\\n require(sender != address(0), \\\"ERC20: transfer from the zero address\\\");\\n require(recipient != address(0), \\\"ERC20: transfer to the zero address\\\");\\n\\n _beforeTokenTransfer(sender, recipient, amount);\\n\\n uint256 senderBalance = _balances[sender];\\n require(senderBalance >= amount, \\\"ERC20: transfer amount exceeds balance\\\");\\n unchecked {\\n _balances[sender] = senderBalance - amount;\\n }\\n _balances[recipient] += amount;\\n\\n emit Transfer(sender, recipient, amount);\\n\\n _afterTokenTransfer(sender, recipient, amount);\\n }\\n\\n /** @dev Creates `amount` tokens and assigns them to `account`, increasing\\n * the total supply.\\n *\\n * Emits a {Transfer} event with `from` set to the zero address.\\n *\\n * Requirements:\\n *\\n * - `account` cannot be the zero address.\\n */\\n function _mint(address account, uint256 amount) internal virtual {\\n require(account != address(0), \\\"ERC20: mint to the zero address\\\");\\n\\n _beforeTokenTransfer(address(0), account, amount);\\n\\n _totalSupply += amount;\\n _balances[account] += amount;\\n emit Transfer(address(0), account, amount);\\n\\n _afterTokenTransfer(address(0), account, amount);\\n }\\n\\n /**\\n * @dev Destroys `amount` tokens from `account`, reducing the\\n * total supply.\\n *\\n * Emits a {Transfer} event with `to` set to the zero address.\\n *\\n * Requirements:\\n *\\n * - `account` cannot be the zero address.\\n * - `account` must have at least `amount` tokens.\\n */\\n function _burn(address account, uint256 amount) internal virtual {\\n require(account != address(0), \\\"ERC20: burn from the zero address\\\");\\n\\n _beforeTokenTransfer(account, address(0), amount);\\n\\n uint256 accountBalance = _balances[account];\\n require(accountBalance >= amount, \\\"ERC20: burn amount exceeds balance\\\");\\n unchecked {\\n _balances[account] = accountBalance - amount;\\n }\\n _totalSupply -= amount;\\n\\n emit Transfer(account, address(0), amount);\\n\\n _afterTokenTransfer(account, address(0), amount);\\n }\\n\\n /**\\n * @dev Sets `amount` as the allowance of `spender` over the `owner` s tokens.\\n *\\n * This internal function is equivalent to `approve`, and can be used to\\n * e.g. set automatic allowances for certain subsystems, etc.\\n *\\n * Emits an {Approval} event.\\n *\\n * Requirements:\\n *\\n * - `owner` cannot be the zero address.\\n * - `spender` cannot be the zero address.\\n */\\n function _approve(\\n address owner,\\n address spender,\\n uint256 amount\\n ) internal virtual {\\n require(owner != address(0), \\\"ERC20: approve from the zero address\\\");\\n require(spender != address(0), \\\"ERC20: approve to the zero address\\\");\\n\\n _allowances[owner][spender] = amount;\\n emit Approval(owner, spender, amount);\\n }\\n\\n /**\\n * @dev Hook that is called before any transfer of tokens. This includes\\n * minting and burning.\\n *\\n * Calling conditions:\\n *\\n * - when `from` and `to` are both non-zero, `amount` of ``from``'s tokens\\n * will be transferred to `to`.\\n * - when `from` is zero, `amount` tokens will be minted for `to`.\\n * - when `to` is zero, `amount` of ``from``'s tokens will be burned.\\n * - `from` and `to` are never both zero.\\n *\\n * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].\\n */\\n function _beforeTokenTransfer(\\n address from,\\n address to,\\n uint256 amount\\n ) internal virtual {}\\n\\n /**\\n * @dev Hook that is called after any transfer of tokens. This includes\\n * minting and burning.\\n *\\n * Calling conditions:\\n *\\n * - when `from` and `to` are both non-zero, `amount` of ``from``'s tokens\\n * has been transferred to `to`.\\n * - when `from` is zero, `amount` tokens have been minted for `to`.\\n * - when `to` is zero, `amount` of ``from``'s tokens have been burned.\\n * - `from` and `to` are never both zero.\\n *\\n * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].\\n */\\n function _afterTokenTransfer(\\n address from,\\n address to,\\n uint256 amount\\n ) internal virtual {}\\n uint256[45] private __gap;\\n}\\n\",\"keccak256\":\"0x23a373902059fb51db98e32e13f89a0ef0c570039081a1345022e66bc7e315d4\",\"license\":\"MIT\"},\"@openzeppelin/contracts-upgradeable/token/ERC20/IERC20Upgradeable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (token/ERC20/IERC20.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Interface of the ERC20 standard as defined in the EIP.\\n */\\ninterface IERC20Upgradeable {\\n /**\\n * @dev Returns the amount of tokens in existence.\\n */\\n function totalSupply() external view returns (uint256);\\n\\n /**\\n * @dev Returns the amount of tokens owned by `account`.\\n */\\n function balanceOf(address account) external view returns (uint256);\\n\\n /**\\n * @dev Moves `amount` tokens from the caller's account to `recipient`.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * Emits a {Transfer} event.\\n */\\n function transfer(address recipient, uint256 amount) external returns (bool);\\n\\n /**\\n * @dev Returns the remaining number of tokens that `spender` will be\\n * allowed to spend on behalf of `owner` through {transferFrom}. This is\\n * zero by default.\\n *\\n * This value changes when {approve} or {transferFrom} are called.\\n */\\n function allowance(address owner, address spender) external view returns (uint256);\\n\\n /**\\n * @dev Sets `amount` as the allowance of `spender` over the caller's tokens.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * IMPORTANT: Beware that changing an allowance with this method brings the risk\\n * that someone may use both the old and the new allowance by unfortunate\\n * transaction ordering. One possible solution to mitigate this race\\n * condition is to first reduce the spender's allowance to 0 and set the\\n * desired value afterwards:\\n * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729\\n *\\n * Emits an {Approval} event.\\n */\\n function approve(address spender, uint256 amount) external returns (bool);\\n\\n /**\\n * @dev Moves `amount` tokens from `sender` to `recipient` using the\\n * allowance mechanism. `amount` is then deducted from the caller's\\n * allowance.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * Emits a {Transfer} event.\\n */\\n function transferFrom(\\n address sender,\\n address recipient,\\n uint256 amount\\n ) external returns (bool);\\n\\n /**\\n * @dev Emitted when `value` tokens are moved from one account (`from`) to\\n * another (`to`).\\n *\\n * Note that `value` may be zero.\\n */\\n event Transfer(address indexed from, address indexed to, uint256 value);\\n\\n /**\\n * @dev Emitted when the allowance of a `spender` for an `owner` is set by\\n * a call to {approve}. `value` is the new allowance.\\n */\\n event Approval(address indexed owner, address indexed spender, uint256 value);\\n}\\n\",\"keccak256\":\"0x5ca0eb1120133a6d0799752532d4638048391823a2b623c4fe9ff46e262266fb\",\"license\":\"MIT\"},\"@openzeppelin/contracts-upgradeable/token/ERC20/extensions/IERC20MetadataUpgradeable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (token/ERC20/extensions/IERC20Metadata.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../IERC20Upgradeable.sol\\\";\\n\\n/**\\n * @dev Interface for the optional metadata functions from the ERC20 standard.\\n *\\n * _Available since v4.1._\\n */\\ninterface IERC20MetadataUpgradeable is IERC20Upgradeable {\\n /**\\n * @dev Returns the name of the token.\\n */\\n function name() external view returns (string memory);\\n\\n /**\\n * @dev Returns the symbol of the token.\\n */\\n function symbol() external view returns (string memory);\\n\\n /**\\n * @dev Returns the decimals places of the token.\\n */\\n function decimals() external view returns (uint8);\\n}\\n\",\"keccak256\":\"0x605434219ebbe4653f703640f06969faa5a1d78f0bfef878e5ddbb1ca369ceeb\",\"license\":\"MIT\"},\"@openzeppelin/contracts-upgradeable/token/ERC20/extensions/draft-ERC20PermitUpgradeable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (token/ERC20/extensions/draft-ERC20Permit.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"./draft-IERC20PermitUpgradeable.sol\\\";\\nimport \\\"../ERC20Upgradeable.sol\\\";\\nimport \\\"../../../utils/cryptography/draft-EIP712Upgradeable.sol\\\";\\nimport \\\"../../../utils/cryptography/ECDSAUpgradeable.sol\\\";\\nimport \\\"../../../utils/CountersUpgradeable.sol\\\";\\nimport \\\"../../../proxy/utils/Initializable.sol\\\";\\n\\n/**\\n * @dev Implementation of the ERC20 Permit extension allowing approvals to be made via signatures, as defined in\\n * https://eips.ethereum.org/EIPS/eip-2612[EIP-2612].\\n *\\n * Adds the {permit} method, which can be used to change an account's ERC20 allowance (see {IERC20-allowance}) by\\n * presenting a message signed by the account. By not relying on `{IERC20-approve}`, the token holder account doesn't\\n * need to send a transaction, and thus is not required to hold Ether at all.\\n *\\n * _Available since v3.4._\\n */\\nabstract contract ERC20PermitUpgradeable is Initializable, ERC20Upgradeable, IERC20PermitUpgradeable, EIP712Upgradeable {\\n using CountersUpgradeable for CountersUpgradeable.Counter;\\n\\n mapping(address => CountersUpgradeable.Counter) private _nonces;\\n\\n // solhint-disable-next-line var-name-mixedcase\\n bytes32 private _PERMIT_TYPEHASH;\\n\\n /**\\n * @dev Initializes the {EIP712} domain separator using the `name` parameter, and setting `version` to `\\\"1\\\"`.\\n *\\n * It's a good idea to use the same `name` that is defined as the ERC20 token name.\\n */\\n function __ERC20Permit_init(string memory name) internal onlyInitializing {\\n __Context_init_unchained();\\n __EIP712_init_unchained(name, \\\"1\\\");\\n __ERC20Permit_init_unchained(name);\\n }\\n\\n function __ERC20Permit_init_unchained(string memory name) internal onlyInitializing {\\n _PERMIT_TYPEHASH = keccak256(\\\"Permit(address owner,address spender,uint256 value,uint256 nonce,uint256 deadline)\\\");}\\n\\n /**\\n * @dev See {IERC20Permit-permit}.\\n */\\n function permit(\\n address owner,\\n address spender,\\n uint256 value,\\n uint256 deadline,\\n uint8 v,\\n bytes32 r,\\n bytes32 s\\n ) public virtual override {\\n require(block.timestamp <= deadline, \\\"ERC20Permit: expired deadline\\\");\\n\\n bytes32 structHash = keccak256(abi.encode(_PERMIT_TYPEHASH, owner, spender, value, _useNonce(owner), deadline));\\n\\n bytes32 hash = _hashTypedDataV4(structHash);\\n\\n address signer = ECDSAUpgradeable.recover(hash, v, r, s);\\n require(signer == owner, \\\"ERC20Permit: invalid signature\\\");\\n\\n _approve(owner, spender, value);\\n }\\n\\n /**\\n * @dev See {IERC20Permit-nonces}.\\n */\\n function nonces(address owner) public view virtual override returns (uint256) {\\n return _nonces[owner].current();\\n }\\n\\n /**\\n * @dev See {IERC20Permit-DOMAIN_SEPARATOR}.\\n */\\n // solhint-disable-next-line func-name-mixedcase\\n function DOMAIN_SEPARATOR() external view override returns (bytes32) {\\n return _domainSeparatorV4();\\n }\\n\\n /**\\n * @dev \\\"Consume a nonce\\\": return the current value and increment.\\n *\\n * _Available since v4.1._\\n */\\n function _useNonce(address owner) internal virtual returns (uint256 current) {\\n CountersUpgradeable.Counter storage nonce = _nonces[owner];\\n current = nonce.current();\\n nonce.increment();\\n }\\n uint256[49] private __gap;\\n}\\n\",\"keccak256\":\"0x7fb71e823080ba5e320f036c7dbda29f3676f3d516db4dcdb8b0adbfbae5d830\",\"license\":\"MIT\"},\"@openzeppelin/contracts-upgradeable/token/ERC20/extensions/draft-IERC20PermitUpgradeable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (token/ERC20/extensions/draft-IERC20Permit.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Interface of the ERC20 Permit extension allowing approvals to be made via signatures, as defined in\\n * https://eips.ethereum.org/EIPS/eip-2612[EIP-2612].\\n *\\n * Adds the {permit} method, which can be used to change an account's ERC20 allowance (see {IERC20-allowance}) by\\n * presenting a message signed by the account. By not relying on {IERC20-approve}, the token holder account doesn't\\n * need to send a transaction, and thus is not required to hold Ether at all.\\n */\\ninterface IERC20PermitUpgradeable {\\n /**\\n * @dev Sets `value` as the allowance of `spender` over ``owner``'s tokens,\\n * given ``owner``'s signed approval.\\n *\\n * IMPORTANT: The same issues {IERC20-approve} has related to transaction\\n * ordering also apply here.\\n *\\n * Emits an {Approval} event.\\n *\\n * Requirements:\\n *\\n * - `spender` cannot be the zero address.\\n * - `deadline` must be a timestamp in the future.\\n * - `v`, `r` and `s` must be a valid `secp256k1` signature from `owner`\\n * over the EIP712-formatted function arguments.\\n * - the signature must use ``owner``'s current nonce (see {nonces}).\\n *\\n * For more information on the signature format, see the\\n * https://eips.ethereum.org/EIPS/eip-2612#specification[relevant EIP\\n * section].\\n */\\n function permit(\\n address owner,\\n address spender,\\n uint256 value,\\n uint256 deadline,\\n uint8 v,\\n bytes32 r,\\n bytes32 s\\n ) external;\\n\\n /**\\n * @dev Returns the current nonce for `owner`. This value must be\\n * included whenever a signature is generated for {permit}.\\n *\\n * Every successful call to {permit} increases ``owner``'s nonce by one. This\\n * prevents a signature from being used multiple times.\\n */\\n function nonces(address owner) external view returns (uint256);\\n\\n /**\\n * @dev Returns the domain separator used in the encoding of the signature for {permit}, as defined by {EIP712}.\\n */\\n // solhint-disable-next-line func-name-mixedcase\\n function DOMAIN_SEPARATOR() external view returns (bytes32);\\n}\\n\",\"keccak256\":\"0xcc70d8e2281fb3ff69e8ab242500f10142cd0a7fa8dd9e45882be270d4d09024\",\"license\":\"MIT\"},\"@openzeppelin/contracts-upgradeable/utils/AddressUpgradeable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (utils/Address.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Collection of functions related to the address type\\n */\\nlibrary AddressUpgradeable {\\n /**\\n * @dev Returns true if `account` is a contract.\\n *\\n * [IMPORTANT]\\n * ====\\n * It is unsafe to assume that an address for which this function returns\\n * false is an externally-owned account (EOA) and not a contract.\\n *\\n * Among others, `isContract` will return false for the following\\n * types of addresses:\\n *\\n * - an externally-owned account\\n * - a contract in construction\\n * - an address where a contract will be created\\n * - an address where a contract lived, but was destroyed\\n * ====\\n */\\n function isContract(address account) internal view returns (bool) {\\n // This method relies on extcodesize, which returns 0 for contracts in\\n // construction, since the code is only stored at the end of the\\n // constructor execution.\\n\\n uint256 size;\\n assembly {\\n size := extcodesize(account)\\n }\\n return size > 0;\\n }\\n\\n /**\\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\\n * `recipient`, forwarding all available gas and reverting on errors.\\n *\\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\\n * imposed by `transfer`, making them unable to receive funds via\\n * `transfer`. {sendValue} removes this limitation.\\n *\\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\\n *\\n * IMPORTANT: because control is transferred to `recipient`, care must be\\n * taken to not create reentrancy vulnerabilities. Consider using\\n * {ReentrancyGuard} or the\\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\\n */\\n function sendValue(address payable recipient, uint256 amount) internal {\\n require(address(this).balance >= amount, \\\"Address: insufficient balance\\\");\\n\\n (bool success, ) = recipient.call{value: amount}(\\\"\\\");\\n require(success, \\\"Address: unable to send value, recipient may have reverted\\\");\\n }\\n\\n /**\\n * @dev Performs a Solidity function call using a low level `call`. A\\n * plain `call` is an unsafe replacement for a function call: use this\\n * function instead.\\n *\\n * If `target` reverts with a revert reason, it is bubbled up by this\\n * function (like regular Solidity function calls).\\n *\\n * Returns the raw returned data. To convert to the expected return value,\\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\\n *\\n * Requirements:\\n *\\n * - `target` must be a contract.\\n * - calling `target` with `data` must not revert.\\n *\\n * _Available since v3.1._\\n */\\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\\n return functionCall(target, data, \\\"Address: low-level call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\\n * `errorMessage` as a fallback revert reason when `target` reverts.\\n *\\n * _Available since v3.1._\\n */\\n function functionCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n return functionCallWithValue(target, data, 0, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but also transferring `value` wei to `target`.\\n *\\n * Requirements:\\n *\\n * - the calling contract must have an ETH balance of at least `value`.\\n * - the called Solidity function must be `payable`.\\n *\\n * _Available since v3.1._\\n */\\n function functionCallWithValue(\\n address target,\\n bytes memory data,\\n uint256 value\\n ) internal returns (bytes memory) {\\n return functionCallWithValue(target, data, value, \\\"Address: low-level call with value failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\\n * with `errorMessage` as a fallback revert reason when `target` reverts.\\n *\\n * _Available since v3.1._\\n */\\n function functionCallWithValue(\\n address target,\\n bytes memory data,\\n uint256 value,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n require(address(this).balance >= value, \\\"Address: insufficient balance for call\\\");\\n require(isContract(target), \\\"Address: call to non-contract\\\");\\n\\n (bool success, bytes memory returndata) = target.call{value: value}(data);\\n return verifyCallResult(success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but performing a static call.\\n *\\n * _Available since v3.3._\\n */\\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\\n return functionStaticCall(target, data, \\\"Address: low-level static call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\\n * but performing a static call.\\n *\\n * _Available since v3.3._\\n */\\n function functionStaticCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal view returns (bytes memory) {\\n require(isContract(target), \\\"Address: static call to non-contract\\\");\\n\\n (bool success, bytes memory returndata) = target.staticcall(data);\\n return verifyCallResult(success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the\\n * revert reason using the provided one.\\n *\\n * _Available since v4.3._\\n */\\n function verifyCallResult(\\n bool success,\\n bytes memory returndata,\\n string memory errorMessage\\n ) internal pure returns (bytes memory) {\\n if (success) {\\n return returndata;\\n } else {\\n // Look for revert reason and bubble it up if present\\n if (returndata.length > 0) {\\n // The easiest way to bubble the revert reason is using memory via assembly\\n\\n assembly {\\n let returndata_size := mload(returndata)\\n revert(add(32, returndata), returndata_size)\\n }\\n } else {\\n revert(errorMessage);\\n }\\n }\\n }\\n}\\n\",\"keccak256\":\"0x3f0f878c796dfc7feba6d3c4e3e526c14c7deae8b7bfc71088e3f38fab0d77b3\",\"license\":\"MIT\"},\"@openzeppelin/contracts-upgradeable/utils/ContextUpgradeable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)\\n\\npragma solidity ^0.8.0;\\nimport \\\"../proxy/utils/Initializable.sol\\\";\\n\\n/**\\n * @dev Provides information about the current execution context, including the\\n * sender of the transaction and its data. While these are generally available\\n * via msg.sender and msg.data, they should not be accessed in such a direct\\n * manner, since when dealing with meta-transactions the account sending and\\n * paying for execution may not be the actual sender (as far as an application\\n * is concerned).\\n *\\n * This contract is only required for intermediate, library-like contracts.\\n */\\nabstract contract ContextUpgradeable is Initializable {\\n function __Context_init() internal onlyInitializing {\\n __Context_init_unchained();\\n }\\n\\n function __Context_init_unchained() internal onlyInitializing {\\n }\\n function _msgSender() internal view virtual returns (address) {\\n return msg.sender;\\n }\\n\\n function _msgData() internal view virtual returns (bytes calldata) {\\n return msg.data;\\n }\\n uint256[50] private __gap;\\n}\\n\",\"keccak256\":\"0x0b0d548f6381370d394f7a434f994dc678b3ef3e755de106109d61343a685ea7\",\"license\":\"MIT\"},\"@openzeppelin/contracts-upgradeable/utils/CountersUpgradeable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (utils/Counters.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @title Counters\\n * @author Matt Condon (@shrugs)\\n * @dev Provides counters that can only be incremented, decremented or reset. This can be used e.g. to track the number\\n * of elements in a mapping, issuing ERC721 ids, or counting request ids.\\n *\\n * Include with `using Counters for Counters.Counter;`\\n */\\nlibrary CountersUpgradeable {\\n struct Counter {\\n // This variable should never be directly accessed by users of the library: interactions must be restricted to\\n // the library's function. As of Solidity v0.5.2, this cannot be enforced, though there is a proposal to add\\n // this feature: see https://github.com/ethereum/solidity/issues/4637\\n uint256 _value; // default: 0\\n }\\n\\n function current(Counter storage counter) internal view returns (uint256) {\\n return counter._value;\\n }\\n\\n function increment(Counter storage counter) internal {\\n unchecked {\\n counter._value += 1;\\n }\\n }\\n\\n function decrement(Counter storage counter) internal {\\n uint256 value = counter._value;\\n require(value > 0, \\\"Counter: decrement overflow\\\");\\n unchecked {\\n counter._value = value - 1;\\n }\\n }\\n\\n function reset(Counter storage counter) internal {\\n counter._value = 0;\\n }\\n}\\n\",\"keccak256\":\"0x798741e231b22b81e2dd2eddaaf8832dee4baf5cd8e2dbaa5c1dd12a1c053c4d\",\"license\":\"MIT\"},\"@openzeppelin/contracts-upgradeable/utils/StringsUpgradeable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (utils/Strings.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev String operations.\\n */\\nlibrary StringsUpgradeable {\\n bytes16 private constant _HEX_SYMBOLS = \\\"0123456789abcdef\\\";\\n\\n /**\\n * @dev Converts a `uint256` to its ASCII `string` decimal representation.\\n */\\n function toString(uint256 value) internal pure returns (string memory) {\\n // Inspired by OraclizeAPI's implementation - MIT licence\\n // https://github.com/oraclize/ethereum-api/blob/b42146b063c7d6ee1358846c198246239e9360e8/oraclizeAPI_0.4.25.sol\\n\\n if (value == 0) {\\n return \\\"0\\\";\\n }\\n uint256 temp = value;\\n uint256 digits;\\n while (temp != 0) {\\n digits++;\\n temp /= 10;\\n }\\n bytes memory buffer = new bytes(digits);\\n while (value != 0) {\\n digits -= 1;\\n buffer[digits] = bytes1(uint8(48 + uint256(value % 10)));\\n value /= 10;\\n }\\n return string(buffer);\\n }\\n\\n /**\\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation.\\n */\\n function toHexString(uint256 value) internal pure returns (string memory) {\\n if (value == 0) {\\n return \\\"0x00\\\";\\n }\\n uint256 temp = value;\\n uint256 length = 0;\\n while (temp != 0) {\\n length++;\\n temp >>= 8;\\n }\\n return toHexString(value, length);\\n }\\n\\n /**\\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length.\\n */\\n function toHexString(uint256 value, uint256 length) internal pure returns (string memory) {\\n bytes memory buffer = new bytes(2 * length + 2);\\n buffer[0] = \\\"0\\\";\\n buffer[1] = \\\"x\\\";\\n for (uint256 i = 2 * length + 1; i > 1; --i) {\\n buffer[i] = _HEX_SYMBOLS[value & 0xf];\\n value >>= 4;\\n }\\n require(value == 0, \\\"Strings: hex length insufficient\\\");\\n return string(buffer);\\n }\\n}\\n\",\"keccak256\":\"0x398d3323c1932a5986bf36be7c57593e121e69d5db5b6574b4ee0d031443de37\",\"license\":\"MIT\"},\"@openzeppelin/contracts-upgradeable/utils/cryptography/ECDSAUpgradeable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (utils/cryptography/ECDSA.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../StringsUpgradeable.sol\\\";\\n\\n/**\\n * @dev Elliptic Curve Digital Signature Algorithm (ECDSA) operations.\\n *\\n * These functions can be used to verify that a message was signed by the holder\\n * of the private keys of a given address.\\n */\\nlibrary ECDSAUpgradeable {\\n enum RecoverError {\\n NoError,\\n InvalidSignature,\\n InvalidSignatureLength,\\n InvalidSignatureS,\\n InvalidSignatureV\\n }\\n\\n function _throwError(RecoverError error) private pure {\\n if (error == RecoverError.NoError) {\\n return; // no error: do nothing\\n } else if (error == RecoverError.InvalidSignature) {\\n revert(\\\"ECDSA: invalid signature\\\");\\n } else if (error == RecoverError.InvalidSignatureLength) {\\n revert(\\\"ECDSA: invalid signature length\\\");\\n } else if (error == RecoverError.InvalidSignatureS) {\\n revert(\\\"ECDSA: invalid signature 's' value\\\");\\n } else if (error == RecoverError.InvalidSignatureV) {\\n revert(\\\"ECDSA: invalid signature 'v' value\\\");\\n }\\n }\\n\\n /**\\n * @dev Returns the address that signed a hashed message (`hash`) with\\n * `signature` or error string. This address can then be used for verification purposes.\\n *\\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\\n * this function rejects them by requiring the `s` value to be in the lower\\n * half order, and the `v` value to be either 27 or 28.\\n *\\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\\n * verification to be secure: it is possible to craft signatures that\\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\\n * this is by receiving a hash of the original message (which may otherwise\\n * be too long), and then calling {toEthSignedMessageHash} on it.\\n *\\n * Documentation for signature generation:\\n * - with https://web3js.readthedocs.io/en/v1.3.4/web3-eth-accounts.html#sign[Web3.js]\\n * - with https://docs.ethers.io/v5/api/signer/#Signer-signMessage[ethers]\\n *\\n * _Available since v4.3._\\n */\\n function tryRecover(bytes32 hash, bytes memory signature) internal pure returns (address, RecoverError) {\\n // Check the signature length\\n // - case 65: r,s,v signature (standard)\\n // - case 64: r,vs signature (cf https://eips.ethereum.org/EIPS/eip-2098) _Available since v4.1._\\n if (signature.length == 65) {\\n bytes32 r;\\n bytes32 s;\\n uint8 v;\\n // ecrecover takes the signature parameters, and the only way to get them\\n // currently is to use assembly.\\n assembly {\\n r := mload(add(signature, 0x20))\\n s := mload(add(signature, 0x40))\\n v := byte(0, mload(add(signature, 0x60)))\\n }\\n return tryRecover(hash, v, r, s);\\n } else if (signature.length == 64) {\\n bytes32 r;\\n bytes32 vs;\\n // ecrecover takes the signature parameters, and the only way to get them\\n // currently is to use assembly.\\n assembly {\\n r := mload(add(signature, 0x20))\\n vs := mload(add(signature, 0x40))\\n }\\n return tryRecover(hash, r, vs);\\n } else {\\n return (address(0), RecoverError.InvalidSignatureLength);\\n }\\n }\\n\\n /**\\n * @dev Returns the address that signed a hashed message (`hash`) with\\n * `signature`. This address can then be used for verification purposes.\\n *\\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\\n * this function rejects them by requiring the `s` value to be in the lower\\n * half order, and the `v` value to be either 27 or 28.\\n *\\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\\n * verification to be secure: it is possible to craft signatures that\\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\\n * this is by receiving a hash of the original message (which may otherwise\\n * be too long), and then calling {toEthSignedMessageHash} on it.\\n */\\n function recover(bytes32 hash, bytes memory signature) internal pure returns (address) {\\n (address recovered, RecoverError error) = tryRecover(hash, signature);\\n _throwError(error);\\n return recovered;\\n }\\n\\n /**\\n * @dev Overload of {ECDSA-tryRecover} that receives the `r` and `vs` short-signature fields separately.\\n *\\n * See https://eips.ethereum.org/EIPS/eip-2098[EIP-2098 short signatures]\\n *\\n * _Available since v4.3._\\n */\\n function tryRecover(\\n bytes32 hash,\\n bytes32 r,\\n bytes32 vs\\n ) internal pure returns (address, RecoverError) {\\n bytes32 s;\\n uint8 v;\\n assembly {\\n s := and(vs, 0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff)\\n v := add(shr(255, vs), 27)\\n }\\n return tryRecover(hash, v, r, s);\\n }\\n\\n /**\\n * @dev Overload of {ECDSA-recover} that receives the `r and `vs` short-signature fields separately.\\n *\\n * _Available since v4.2._\\n */\\n function recover(\\n bytes32 hash,\\n bytes32 r,\\n bytes32 vs\\n ) internal pure returns (address) {\\n (address recovered, RecoverError error) = tryRecover(hash, r, vs);\\n _throwError(error);\\n return recovered;\\n }\\n\\n /**\\n * @dev Overload of {ECDSA-tryRecover} that receives the `v`,\\n * `r` and `s` signature fields separately.\\n *\\n * _Available since v4.3._\\n */\\n function tryRecover(\\n bytes32 hash,\\n uint8 v,\\n bytes32 r,\\n bytes32 s\\n ) internal pure returns (address, RecoverError) {\\n // EIP-2 still allows signature malleability for ecrecover(). Remove this possibility and make the signature\\n // unique. Appendix F in the Ethereum Yellow paper (https://ethereum.github.io/yellowpaper/paper.pdf), defines\\n // the valid range for s in (301): 0 < s < secp256k1n \\u00f7 2 + 1, and for v in (302): v \\u2208 {27, 28}. Most\\n // signatures from current libraries generate a unique signature with an s-value in the lower half order.\\n //\\n // If your library generates malleable signatures, such as s-values in the upper range, calculate a new s-value\\n // with 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141 - s1 and flip v from 27 to 28 or\\n // vice versa. If your library also generates signatures with 0/1 for v instead 27/28, add 27 to v to accept\\n // these malleable signatures as well.\\n if (uint256(s) > 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D576E7357A4501DDFE92F46681B20A0) {\\n return (address(0), RecoverError.InvalidSignatureS);\\n }\\n if (v != 27 && v != 28) {\\n return (address(0), RecoverError.InvalidSignatureV);\\n }\\n\\n // If the signature is valid (and not malleable), return the signer address\\n address signer = ecrecover(hash, v, r, s);\\n if (signer == address(0)) {\\n return (address(0), RecoverError.InvalidSignature);\\n }\\n\\n return (signer, RecoverError.NoError);\\n }\\n\\n /**\\n * @dev Overload of {ECDSA-recover} that receives the `v`,\\n * `r` and `s` signature fields separately.\\n */\\n function recover(\\n bytes32 hash,\\n uint8 v,\\n bytes32 r,\\n bytes32 s\\n ) internal pure returns (address) {\\n (address recovered, RecoverError error) = tryRecover(hash, v, r, s);\\n _throwError(error);\\n return recovered;\\n }\\n\\n /**\\n * @dev Returns an Ethereum Signed Message, created from a `hash`. This\\n * produces hash corresponding to the one signed with the\\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\\n * JSON-RPC method as part of EIP-191.\\n *\\n * See {recover}.\\n */\\n function toEthSignedMessageHash(bytes32 hash) internal pure returns (bytes32) {\\n // 32 is the length in bytes of hash,\\n // enforced by the type signature above\\n return keccak256(abi.encodePacked(\\\"\\\\x19Ethereum Signed Message:\\\\n32\\\", hash));\\n }\\n\\n /**\\n * @dev Returns an Ethereum Signed Message, created from `s`. This\\n * produces hash corresponding to the one signed with the\\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\\n * JSON-RPC method as part of EIP-191.\\n *\\n * See {recover}.\\n */\\n function toEthSignedMessageHash(bytes memory s) internal pure returns (bytes32) {\\n return keccak256(abi.encodePacked(\\\"\\\\x19Ethereum Signed Message:\\\\n\\\", StringsUpgradeable.toString(s.length), s));\\n }\\n\\n /**\\n * @dev Returns an Ethereum Signed Typed Data, created from a\\n * `domainSeparator` and a `structHash`. This produces hash corresponding\\n * to the one signed with the\\n * https://eips.ethereum.org/EIPS/eip-712[`eth_signTypedData`]\\n * JSON-RPC method as part of EIP-712.\\n *\\n * See {recover}.\\n */\\n function toTypedDataHash(bytes32 domainSeparator, bytes32 structHash) internal pure returns (bytes32) {\\n return keccak256(abi.encodePacked(\\\"\\\\x19\\\\x01\\\", domainSeparator, structHash));\\n }\\n}\\n\",\"keccak256\":\"0x1762ac67d230279d7fb183567ce22bbe202054ce08f94224d8794f9d19546d51\",\"license\":\"MIT\"},\"@openzeppelin/contracts-upgradeable/utils/cryptography/draft-EIP712Upgradeable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (utils/cryptography/draft-EIP712.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"./ECDSAUpgradeable.sol\\\";\\nimport \\\"../../proxy/utils/Initializable.sol\\\";\\n\\n/**\\n * @dev https://eips.ethereum.org/EIPS/eip-712[EIP 712] is a standard for hashing and signing of typed structured data.\\n *\\n * The encoding specified in the EIP is very generic, and such a generic implementation in Solidity is not feasible,\\n * thus this contract does not implement the encoding itself. Protocols need to implement the type-specific encoding\\n * they need in their contracts using a combination of `abi.encode` and `keccak256`.\\n *\\n * This contract implements the EIP 712 domain separator ({_domainSeparatorV4}) that is used as part of the encoding\\n * scheme, and the final step of the encoding to obtain the message digest that is then signed via ECDSA\\n * ({_hashTypedDataV4}).\\n *\\n * The implementation of the domain separator was designed to be as efficient as possible while still properly updating\\n * the chain id to protect against replay attacks on an eventual fork of the chain.\\n *\\n * NOTE: This contract implements the version of the encoding known as \\\"v4\\\", as implemented by the JSON RPC method\\n * https://docs.metamask.io/guide/signing-data.html[`eth_signTypedDataV4` in MetaMask].\\n *\\n * _Available since v3.4._\\n */\\nabstract contract EIP712Upgradeable is Initializable {\\n /* solhint-disable var-name-mixedcase */\\n bytes32 private _HASHED_NAME;\\n bytes32 private _HASHED_VERSION;\\n bytes32 private constant _TYPE_HASH = keccak256(\\\"EIP712Domain(string name,string version,uint256 chainId,address verifyingContract)\\\");\\n\\n /* solhint-enable var-name-mixedcase */\\n\\n /**\\n * @dev Initializes the domain separator and parameter caches.\\n *\\n * The meaning of `name` and `version` is specified in\\n * https://eips.ethereum.org/EIPS/eip-712#definition-of-domainseparator[EIP 712]:\\n *\\n * - `name`: the user readable name of the signing domain, i.e. the name of the DApp or the protocol.\\n * - `version`: the current major version of the signing domain.\\n *\\n * NOTE: These parameters cannot be changed except through a xref:learn::upgrading-smart-contracts.adoc[smart\\n * contract upgrade].\\n */\\n function __EIP712_init(string memory name, string memory version) internal onlyInitializing {\\n __EIP712_init_unchained(name, version);\\n }\\n\\n function __EIP712_init_unchained(string memory name, string memory version) internal onlyInitializing {\\n bytes32 hashedName = keccak256(bytes(name));\\n bytes32 hashedVersion = keccak256(bytes(version));\\n _HASHED_NAME = hashedName;\\n _HASHED_VERSION = hashedVersion;\\n }\\n\\n /**\\n * @dev Returns the domain separator for the current chain.\\n */\\n function _domainSeparatorV4() internal view returns (bytes32) {\\n return _buildDomainSeparator(_TYPE_HASH, _EIP712NameHash(), _EIP712VersionHash());\\n }\\n\\n function _buildDomainSeparator(\\n bytes32 typeHash,\\n bytes32 nameHash,\\n bytes32 versionHash\\n ) private view returns (bytes32) {\\n return keccak256(abi.encode(typeHash, nameHash, versionHash, block.chainid, address(this)));\\n }\\n\\n /**\\n * @dev Given an already https://eips.ethereum.org/EIPS/eip-712#definition-of-hashstruct[hashed struct], this\\n * function returns the hash of the fully encoded EIP712 message for this domain.\\n *\\n * This hash can be used together with {ECDSA-recover} to obtain the signer of a message. For example:\\n *\\n * ```solidity\\n * bytes32 digest = _hashTypedDataV4(keccak256(abi.encode(\\n * keccak256(\\\"Mail(address to,string contents)\\\"),\\n * mailTo,\\n * keccak256(bytes(mailContents))\\n * )));\\n * address signer = ECDSA.recover(digest, signature);\\n * ```\\n */\\n function _hashTypedDataV4(bytes32 structHash) internal view virtual returns (bytes32) {\\n return ECDSAUpgradeable.toTypedDataHash(_domainSeparatorV4(), structHash);\\n }\\n\\n /**\\n * @dev The hash of the name parameter for the EIP712 domain.\\n *\\n * NOTE: This function reads from storage by default, but can be redefined to return a constant value if gas costs\\n * are a concern.\\n */\\n function _EIP712NameHash() internal virtual view returns (bytes32) {\\n return _HASHED_NAME;\\n }\\n\\n /**\\n * @dev The hash of the version parameter for the EIP712 domain.\\n *\\n * NOTE: This function reads from storage by default, but can be redefined to return a constant value if gas costs\\n * are a concern.\\n */\\n function _EIP712VersionHash() internal virtual view returns (bytes32) {\\n return _HASHED_VERSION;\\n }\\n uint256[50] private __gap;\\n}\\n\",\"keccak256\":\"0x92e61d8dd5ba90b513769c06da820e0a8f5d93810a9c6d5207308af345815011\",\"license\":\"MIT\"},\"contracts/agToken/AgToken.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-3.0\\n\\npragma solidity 0.8.12;\\n\\nimport \\\"../interfaces/IAgToken.sol\\\";\\nimport \\\"../interfaces/coreModule/IStableMaster.sol\\\";\\nimport \\\"../interfaces/ITreasury.sol\\\";\\n// OpenZeppelin may update its version of the ERC20PermitUpgradeable token\\nimport \\\"@openzeppelin/contracts-upgradeable/token/ERC20/extensions/draft-ERC20PermitUpgradeable.sol\\\";\\n\\n/// @title AgToken\\n/// @author Angle Core Team\\n/// @notice Base contract for agToken, that is to say Angle's stablecoins\\n/// @dev This contract is used to create and handle the stablecoins of Angle protocol\\n/// @dev It is still possible for any address to burn its agTokens without redeeming collateral in exchange\\n/// @dev This contract is the upgraded version of the AgToken that was first deployed on Ethereum mainnet\\ncontract AgToken is IAgToken, ERC20PermitUpgradeable {\\n // ========================= References to other contracts =====================\\n\\n /// @notice Reference to the `StableMaster` contract associated to this `AgToken`\\n address public stableMaster;\\n\\n // ============================= Constructor ===================================\\n\\n /// @notice Initializes the `AgToken` contract\\n /// @param name_ Name of the token\\n /// @param symbol_ Symbol of the token\\n /// @param stableMaster_ Reference to the `StableMaster` contract associated to this agToken\\n /// @dev By default, agTokens are ERC-20 tokens with 18 decimals\\n function initialize(\\n string memory name_,\\n string memory symbol_,\\n address stableMaster_\\n ) external initializer {\\n __ERC20Permit_init(name_);\\n __ERC20_init(name_, symbol_);\\n require(stableMaster_ != address(0), \\\"0\\\");\\n stableMaster = stableMaster_;\\n }\\n\\n /// @custom:oz-upgrades-unsafe-allow constructor\\n constructor() initializer {}\\n\\n // ======= Added Parameters and Variables from the first implementation ========\\n\\n /// @inheritdoc IAgToken\\n mapping(address => bool) public isMinter;\\n /// @notice Reference to the treasury contract which can grant minting rights\\n address public treasury;\\n /// @notice Boolean to check whether the contract has been reinitialized after its upgrade\\n bool public treasuryInitialized;\\n\\n // =============================== Added Events ================================\\n\\n event TreasuryUpdated(address indexed _treasury);\\n event MinterToggled(address indexed minter);\\n\\n // =============================== Added Errors ================================\\n\\n error BurnAmountExceedsAllowance();\\n error InvalidSender();\\n error InvalidTreasury();\\n error NotGovernor();\\n error NotMinter();\\n error NotTreasury();\\n error TreasuryAlreadyInitialized();\\n\\n // =============================== Setup Function ==============================\\n\\n /// @notice Sets up the treasury contract in this AgToken contract\\n /// @param _treasury Treasury contract to add\\n /// @dev The address calling this function has to be hard-coded in the contract\\n /// @dev Can be called only once\\n function setUpTreasury(address _treasury) external {\\n // Only governor\\n if (msg.sender != 0xdC4e6DFe07EFCa50a197DF15D9200883eF4Eb1c8) revert NotGovernor();\\n if (address(ITreasury(_treasury).stablecoin()) != address(this)) revert InvalidTreasury();\\n if (treasuryInitialized) revert TreasuryAlreadyInitialized();\\n treasury = _treasury;\\n treasuryInitialized = true;\\n isMinter[stableMaster] = true;\\n emit TreasuryUpdated(_treasury);\\n }\\n\\n // =============================== Modifiers ===================================\\n\\n /// @notice Checks to see if it is the `Treasury` calling this contract\\n /// @dev There is no Access Control here, because it can be handled cheaply through this modifier\\n modifier onlyTreasury() {\\n if (msg.sender != treasury) revert NotTreasury();\\n _;\\n }\\n\\n /// @notice Checks whether the sender has the minting right\\n modifier onlyMinter() {\\n if (!isMinter[msg.sender]) revert NotMinter();\\n _;\\n }\\n\\n // ========================= External Functions ================================\\n // The following functions allow anyone to burn stablecoins without redeeming collateral\\n // in exchange for that\\n\\n /// @notice Destroys `amount` token from the caller without giving collateral back\\n /// @param amount Amount to burn\\n /// @param poolManager Reference to the `PoolManager` contract for which the `stocksUsers` will\\n /// need to be updated\\n /// @dev When calling this function, people should specify the `poolManager` for which they want to decrease\\n /// the `stocksUsers`: this is a way for the protocol to maintain healthy accounting variables\\n function burnNoRedeem(uint256 amount, address poolManager) external {\\n _burn(msg.sender, amount);\\n IStableMaster(stableMaster).updateStocksUsers(amount, poolManager);\\n }\\n\\n /// @notice Burns `amount` of agToken on behalf of another account without redeeming collateral back\\n /// @param account Account to burn on behalf of\\n /// @param amount Amount to burn\\n /// @param poolManager Reference to the `PoolManager` contract for which the `stocksUsers` will need to be updated\\n function burnFromNoRedeem(\\n address account,\\n uint256 amount,\\n address poolManager\\n ) external {\\n _burnFromNoRedeem(amount, account, msg.sender);\\n IStableMaster(stableMaster).updateStocksUsers(amount, poolManager);\\n }\\n\\n /// @notice Allows anyone to burn agToken without redeeming collateral back\\n /// @param amount Amount of stablecoins to burn\\n /// @dev This function can typically be called if there is a settlement mechanism to burn stablecoins\\n function burnStablecoin(uint256 amount) external {\\n _burn(msg.sender, amount);\\n }\\n\\n // ======================= Minter Role Only Functions ==========================\\n\\n /// @inheritdoc IAgToken\\n function burnSelf(uint256 amount, address burner) external onlyMinter {\\n _burn(burner, amount);\\n }\\n\\n /// @inheritdoc IAgToken\\n function burnFrom(\\n uint256 amount,\\n address burner,\\n address sender\\n ) external onlyMinter {\\n _burnFromNoRedeem(amount, burner, sender);\\n }\\n\\n /// @inheritdoc IAgToken\\n function mint(address account, uint256 amount) external onlyMinter {\\n _mint(account, amount);\\n }\\n\\n // ======================= Treasury Only Functions =============================\\n\\n /// @inheritdoc IAgToken\\n function addMinter(address minter) external onlyTreasury {\\n isMinter[minter] = true;\\n emit MinterToggled(minter);\\n }\\n\\n /// @inheritdoc IAgToken\\n function removeMinter(address minter) external {\\n // The `treasury` contract cannot remove the `stableMaster`\\n if (msg.sender != minter && (msg.sender != address(treasury) || minter == stableMaster)) revert InvalidSender();\\n isMinter[minter] = false;\\n emit MinterToggled(minter);\\n }\\n\\n /// @inheritdoc IAgToken\\n function setTreasury(address _treasury) external onlyTreasury {\\n treasury = _treasury;\\n emit TreasuryUpdated(_treasury);\\n }\\n\\n // ============================ Internal Function ==============================\\n\\n /// @notice Internal version of the function `burnFromNoRedeem`\\n /// @param amount Amount to burn\\n /// @dev It is at the level of this function that allowance checks are performed\\n function _burnFromNoRedeem(\\n uint256 amount,\\n address burner,\\n address sender\\n ) internal {\\n if (burner != sender) {\\n uint256 currentAllowance = allowance(burner, sender);\\n if (currentAllowance < amount) revert BurnAmountExceedsAllowance();\\n _approve(burner, sender, currentAllowance - amount);\\n }\\n _burn(burner, amount);\\n }\\n}\\n\",\"keccak256\":\"0x52932d2a1a962bdfa846c76a3905497dfa15a68c1265973e02ca0e22c9476950\",\"license\":\"GPL-3.0\"},\"contracts/interfaces/IAgToken.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-3.0\\n\\npragma solidity 0.8.12;\\n\\nimport \\\"@openzeppelin/contracts-upgradeable/token/ERC20/IERC20Upgradeable.sol\\\";\\n\\n/// @title IAgToken\\n/// @author Angle Core Team\\n/// @notice Interface for the stablecoins `AgToken` contracts\\n/// @dev This interface only contains functions of the `AgToken` contract which are called by other contracts\\n/// of this module or of the first module of the Angle Protocol\\ninterface IAgToken is IERC20Upgradeable {\\n // ======================= Minter Role Only Functions ===========================\\n\\n /// @notice Lets the `StableMaster` contract or another whitelisted contract mint agTokens\\n /// @param account Address to mint to\\n /// @param amount Amount to mint\\n /// @dev The contracts allowed to issue agTokens are the `StableMaster` contract, `VaultManager` contracts\\n /// associated to this stablecoin as well as the flash loan module (if activated) and potentially contracts\\n /// whitelisted by governance\\n function mint(address account, uint256 amount) external;\\n\\n /// @notice Burns `amount` tokens from a `burner` address after being asked to by `sender`\\n /// @param amount Amount of tokens to burn\\n /// @param burner Address to burn from\\n /// @param sender Address which requested the burn from `burner`\\n /// @dev This method is to be called by a contract with the minter right after being requested\\n /// to do so by a `sender` address willing to burn tokens from another `burner` address\\n /// @dev The method checks the allowance between the `sender` and the `burner`\\n function burnFrom(\\n uint256 amount,\\n address burner,\\n address sender\\n ) external;\\n\\n /// @notice Burns `amount` tokens from a `burner` address\\n /// @param amount Amount of tokens to burn\\n /// @param burner Address to burn from\\n /// @dev This method is to be called by a contract with a minter right on the AgToken after being\\n /// requested to do so by an address willing to burn tokens from its address\\n function burnSelf(uint256 amount, address burner) external;\\n\\n // ========================= Treasury Only Functions ===========================\\n\\n /// @notice Adds a minter in the contract\\n /// @param minter Minter address to add\\n /// @dev Zero address checks are performed directly in the `Treasury` contract\\n function addMinter(address minter) external;\\n\\n /// @notice Removes a minter from the contract\\n /// @param minter Minter address to remove\\n /// @dev This function can also be called by a minter wishing to revoke itself\\n function removeMinter(address minter) external;\\n\\n /// @notice Sets a new treasury contract\\n /// @param _treasury New treasury address\\n function setTreasury(address _treasury) external;\\n\\n // ========================= External functions ================================\\n\\n /// @notice Checks whether an address has the right to mint agTokens\\n /// @param minter Address for which the minting right should be checked\\n /// @return Whether the address has the right to mint agTokens or not\\n function isMinter(address minter) external view returns (bool);\\n}\\n\",\"keccak256\":\"0xcd50d86128e457543483981ea6127cb8dac03584b919614352aa89d7e991405c\",\"license\":\"GPL-3.0\"},\"contracts/interfaces/ICoreBorrow.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-3.0\\n\\npragma solidity 0.8.12;\\n\\n/// @title ICoreBorrow\\n/// @author Angle Core Team\\n/// @notice Interface for the `CoreBorrow` contract\\n/// @dev This interface only contains functions of the `CoreBorrow` contract which are called by other contracts\\n/// of this module\\ninterface ICoreBorrow {\\n /// @notice Checks if an address corresponds to a treasury of a stablecoin with a flash loan\\n /// module initialized on it\\n /// @param treasury Address to check\\n /// @return Whether the address has the `FLASHLOANER_TREASURY_ROLE` or not\\n function isFlashLoanerTreasury(address treasury) external view returns (bool);\\n\\n /// @notice Checks whether an address is governor of the Angle Protocol or not\\n /// @param admin Address to check\\n /// @return Whether the address has the `GOVERNOR_ROLE` or not\\n function isGovernor(address admin) external view returns (bool);\\n\\n /// @notice Checks whether an address is governor or a guardian of the Angle Protocol or not\\n /// @param admin Address to check\\n /// @return Whether the address has the `GUARDIAN_ROLE` or not\\n /// @dev Governance should make sure when adding a governor to also give this governor the guardian\\n /// role by calling the `addGovernor` function\\n function isGovernorOrGuardian(address admin) external view returns (bool);\\n}\\n\",\"keccak256\":\"0x25b65b3f506ca91745a444502a36f0556585d82d9d60f4bd32fbcaabc12840d4\",\"license\":\"GPL-3.0\"},\"contracts/interfaces/IFlashAngle.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-3.0\\n\\npragma solidity 0.8.12;\\n\\nimport \\\"./IAgToken.sol\\\";\\nimport \\\"./ICoreBorrow.sol\\\";\\n\\n/// @title IFlashAngle\\n/// @author Angle Core Team\\n/// @notice Interface for the `FlashAngle` contract\\n/// @dev This interface only contains functions of the contract which are called by other contracts\\n/// of this module\\ninterface IFlashAngle {\\n /// @notice Reference to the `CoreBorrow` contract managing the FlashLoan module\\n function core() external view returns (ICoreBorrow);\\n\\n /// @notice Sends the fees taken from flash loans to the treasury contract associated to the stablecoin\\n /// @param stablecoin Stablecoin from which profits should be sent\\n /// @return balance Amount of profits sent\\n /// @dev This function can only be called by the treasury contract\\n function accrueInterestToTreasury(IAgToken stablecoin) external returns (uint256 balance);\\n\\n /// @notice Adds support for a stablecoin\\n /// @param _treasury Treasury associated to the stablecoin to add support for\\n /// @dev This function can only be called by the `CoreBorrow` contract\\n function addStablecoinSupport(address _treasury) external;\\n\\n /// @notice Removes support for a stablecoin\\n /// @param _treasury Treasury associated to the stablecoin to remove support for\\n /// @dev This function can only be called by the `CoreBorrow` contract\\n function removeStablecoinSupport(address _treasury) external;\\n\\n /// @notice Sets a new core contract\\n /// @param _core Core contract address to set\\n /// @dev This function can only be called by the `CoreBorrow` contract\\n function setCore(address _core) external;\\n}\\n\",\"keccak256\":\"0xc17654e512897efe41e3f1173c07dd4676e8c699a72b859d14b473d1e8300e45\",\"license\":\"GPL-3.0\"},\"contracts/interfaces/ITreasury.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-3.0\\n\\npragma solidity 0.8.12;\\n\\nimport \\\"./IAgToken.sol\\\";\\nimport \\\"./ICoreBorrow.sol\\\";\\nimport \\\"./IFlashAngle.sol\\\";\\n\\n/// @title ITreasury\\n/// @author Angle Core Team\\n/// @notice Interface for the `Treasury` contract\\n/// @dev This interface only contains functions of the `Treasury` which are called by other contracts\\n/// of this module\\ninterface ITreasury {\\n /// @notice Stablecoin handled by this `treasury` contract\\n function stablecoin() external view returns (IAgToken);\\n\\n /// @notice Checks whether a given address has the governor role\\n /// @param admin Address to check\\n /// @return Whether the address has the governor role\\n /// @dev Access control is only kept in the `CoreBorrow` contract\\n function isGovernor(address admin) external view returns (bool);\\n\\n /// @notice Checks whether a given address has the guardian or the governor role\\n /// @param admin Address to check\\n /// @return Whether the address has the guardian or the governor role\\n /// @dev Access control is only kept in the `CoreBorrow` contract which means that this function\\n /// queries the `CoreBorrow` contract\\n function isGovernorOrGuardian(address admin) external view returns (bool);\\n\\n /// @notice Checks whether a given address has well been initialized in this contract\\n /// as a `VaultManager``\\n /// @param _vaultManager Address to check\\n /// @return Whether the address has been initialized or not\\n function isVaultManager(address _vaultManager) external view returns (bool);\\n\\n /// @notice Sets a new flash loan module for this stablecoin\\n /// @param _flashLoanModule Reference to the new flash loan module\\n /// @dev This function removes the minting right to the old flash loan module and grants\\n /// it to the new module\\n function setFlashLoanModule(address _flashLoanModule) external;\\n}\\n\",\"keccak256\":\"0xced9b7256fcbedc75682037e11ce51fe9116e5604794b8545e00dea0607629cc\",\"license\":\"GPL-3.0\"},\"contracts/interfaces/coreModule/IStableMaster.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-3.0\\n\\npragma solidity 0.8.12;\\n\\n/// @title IStableMaster\\n/// @author Angle Core Team\\n/// @notice Previous interface with additionnal getters for public variables and mappings\\ninterface IStableMaster {\\n function agToken() external returns (address);\\n\\n function updateStocksUsers(uint256 amount, address poolManager) external;\\n}\\n\",\"keccak256\":\"0x96fe48e27ca36fbcab00ef59e55d8d8dd9450c6f701214158eb75bd1a1a2ec8a\",\"license\":\"GPL-3.0\"}},\"version\":1}", - "bytecode": "0x60806040523480156200001157600080fd5b50600054610100900460ff166200002f5760005460ff161562000039565b62000039620000de565b620000a15760405162461bcd60e51b815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201526d191e481a5b9a5d1a585b1a5e995960921b606482015260840160405180910390fd5b600054610100900460ff16158015620000c4576000805461ffff19166101011790555b8015620000d7576000805461ff00191690555b5062000102565b6000620000f630620000fc60201b620012611760201c565b15905090565b3b151590565b61293880620001126000396000f3fe608060405234801561001057600080fd5b50600436106101cf5760003560e01c806370a0823111610104578063a457c2d7116100a2578063d505accf11610071578063d505accf14610423578063dd62ed3e14610436578063f0f442601461047c578063f1cc2dea1461048f57600080fd5b8063a457c2d7146103c7578063a9059cbb146103da578063aa271e1a146103ed578063cdc5aa9d1461041057600080fd5b806393bd6f69116100de57806393bd6f691461038657806395d89b411461039957806397536325146103a1578063983b2d56146103b457600080fd5b806370a082311461032a5780637ecebe001461036057806390218cff1461037357600080fd5b8063313ce56711610171578063395093511161014b578063395093511461029f57806340c10f19146102b257806361d027b3146102c55780636ac5dc461461030a57600080fd5b8063313ce56714610275578063350ebe04146102845780633644e5151461029757600080fd5b806318160ddd116101ad57806318160ddd1461022a57806323b872dd1461023c5780632b471d8e1461024f5780633092afd51461026257600080fd5b806306fdde03146101d4578063077f224a146101f2578063095ea7b314610207575b600080fd5b6101dc6104b4565b6040516101e99190612436565b60405180910390f35b6102056102003660046125a5565b610546565b005b61021a61021536600461261d565b61073a565b60405190151581526020016101e9565b6035545b6040519081526020016101e9565b61021a61024a366004612649565b610750565b61020561025d36600461268a565b610836565b6102056102703660046126ba565b61088d565b604051601281526020016101e9565b6102056102923660046126de565b61099a565b61022e6109f3565b61021a6102ad36600461261d565b610a02565b6102056102c036600461261d565b610a4b565b60ce546102e59073ffffffffffffffffffffffffffffffffffffffff1681565b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020016101e9565b60cc546102e59073ffffffffffffffffffffffffffffffffffffffff1681565b61022e6103383660046126ba565b73ffffffffffffffffffffffffffffffffffffffff1660009081526033602052604090205490565b61022e61036e3660046126ba565b610a9e565b610205610381366004612715565b610acb565b61020561039436600461268a565b610ad8565b6101dc610b72565b6102056103af36600461272e565b610b81565b6102056103c23660046126ba565b610c1d565b61021a6103d536600461261d565b610ce5565b61021a6103e836600461261d565b610dbd565b61021a6103fb3660046126ba565b60cd6020526000908152604090205460ff1681565b61020561041e3660046126ba565b610dca565b610205610431366004612765565b611000565b61022e6104443660046127dc565b73ffffffffffffffffffffffffffffffffffffffff918216600090815260346020908152604080832093909416825291909152205490565b61020561048a3660046126ba565b6111a1565b60ce5461021a9074010000000000000000000000000000000000000000900460ff1681565b6060603680546104c39061280a565b80601f01602080910402602001604051908101604052809291908181526020018280546104ef9061280a565b801561053c5780601f106105115761010080835404028352916020019161053c565b820191906000526020600020905b81548152906001019060200180831161051f57829003601f168201915b5050505050905090565b600054610100900460ff166105615760005460ff1615610565565b303b155b6105f6576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201527f647920696e697469616c697a656400000000000000000000000000000000000060648201526084015b60405180910390fd5b600054610100900460ff1615801561063557600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0000166101011790555b61063e84611267565b610648848461134e565b73ffffffffffffffffffffffffffffffffffffffff82166106c5576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600160248201527f300000000000000000000000000000000000000000000000000000000000000060448201526064016105ed565b60cc80547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff8416179055801561073457600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff1690555b50505050565b60006107473384846113f7565b50600192915050565b600061075d8484846115aa565b73ffffffffffffffffffffffffffffffffffffffff841660009081526034602090815260408083203384529091529020548281101561081e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602860248201527f45524332303a207472616e7366657220616d6f756e742065786365656473206160448201527f6c6c6f77616e636500000000000000000000000000000000000000000000000060648201526084016105ed565b61082b85338584036113f7565b506001949350505050565b33600090815260cd602052604090205460ff1661087f576040517ff8d2906c00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b610889818361185d565b5050565b3373ffffffffffffffffffffffffffffffffffffffff8216148015906108ef575060ce5473ffffffffffffffffffffffffffffffffffffffff16331415806108ef575060cc5473ffffffffffffffffffffffffffffffffffffffff8281169116145b15610926576040517fddb5de5e00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff8116600081815260cd602052604080822080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00169055517f98c15241d6c02bc5ee0b780e11b3ea737a2defd9d04877edbe9f9497065bd02f9190a250565b33600090815260cd602052604090205460ff166109e3576040517ff8d2906c00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6109ee838383611a4a565b505050565b60006109fd611b05565b905090565b33600081815260346020908152604080832073ffffffffffffffffffffffffffffffffffffffff871684529091528120549091610747918590610a46908690612887565b6113f7565b33600090815260cd602052604090205460ff16610a94576040517ff8d2906c00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6108898282611b80565b73ffffffffffffffffffffffffffffffffffffffff81166000908152609960205260408120545b92915050565b610ad5338261185d565b50565b610ae2338361185d565b60cc546040517f251ad8730000000000000000000000000000000000000000000000000000000081526004810184905273ffffffffffffffffffffffffffffffffffffffff83811660248301529091169063251ad87390604401600060405180830381600087803b158015610b5657600080fd5b505af1158015610b6a573d6000803e3d6000fd5b505050505050565b6060603780546104c39061280a565b610b8c828433611a4a565b60cc546040517f251ad8730000000000000000000000000000000000000000000000000000000081526004810184905273ffffffffffffffffffffffffffffffffffffffff83811660248301529091169063251ad87390604401600060405180830381600087803b158015610c0057600080fd5b505af1158015610c14573d6000803e3d6000fd5b50505050505050565b60ce5473ffffffffffffffffffffffffffffffffffffffff163314610c6e576040517fb90cdbb100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff8116600081815260cd602052604080822080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00166001179055517f98c15241d6c02bc5ee0b780e11b3ea737a2defd9d04877edbe9f9497065bd02f9190a250565b33600090815260346020908152604080832073ffffffffffffffffffffffffffffffffffffffff8616845290915281205482811015610da6576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602560248201527f45524332303a2064656372656173656420616c6c6f77616e63652062656c6f7760448201527f207a65726f00000000000000000000000000000000000000000000000000000060648201526084016105ed565b610db333858584036113f7565b5060019392505050565b60006107473384846115aa565b73dc4e6dfe07efca50a197df15d9200883ef4eb1c83314610e17576040517fee3675d400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b3073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1663e9cbd8226040518163ffffffff1660e01b8152600401602060405180830381865afa158015610e79573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610e9d919061289f565b73ffffffffffffffffffffffffffffffffffffffff1614610eea576040517f14bcf5c800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60ce5474010000000000000000000000000000000000000000900460ff1615610f3f576040517fe1a1cccf00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60ce80547fffffffffffffffffffffff0000000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff808416918217740100000000000000000000000000000000000000001790925560cc54909116600090815260cd602052604080822080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00166001179055517f7dae230f18360d76a040c81f050aa14eb9d6dc7901b20fc5d855e2a20fe814d19190a250565b8342111561106a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f45524332305065726d69743a206578706972656420646561646c696e6500000060448201526064016105ed565b6000609a5488888861107b8c611ca0565b60408051602081019690965273ffffffffffffffffffffffffffffffffffffffff94851690860152929091166060840152608083015260a082015260c0810186905260e00160405160208183030381529060405280519060200120905060006110e382611cd5565b905060006110f382878787611d3e565b90508973ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff161461118a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601e60248201527f45524332305065726d69743a20696e76616c6964207369676e6174757265000060448201526064016105ed565b6111958a8a8a6113f7565b50505050505050505050565b60ce5473ffffffffffffffffffffffffffffffffffffffff1633146111f2576040517fb90cdbb100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60ce80547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83169081179091556040517f7dae230f18360d76a040c81f050aa14eb9d6dc7901b20fc5d855e2a20fe814d190600090a250565b3b151590565b600054610100900460ff166112fe576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201527f6e697469616c697a696e6700000000000000000000000000000000000000000060648201526084016105ed565b611306611d66565b611345816040518060400160405280600181526020017f3100000000000000000000000000000000000000000000000000000000000000815250611dff565b610ad581611eb0565b600054610100900460ff166113e5576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201527f6e697469616c697a696e6700000000000000000000000000000000000000000060648201526084016105ed565b6113ed611d66565b6108898282611f6e565b73ffffffffffffffffffffffffffffffffffffffff8316611499576040517f08c379a0000000000000000000000000000000000000000000000000000000008152602060048201526024808201527f45524332303a20617070726f76652066726f6d20746865207a65726f2061646460448201527f726573730000000000000000000000000000000000000000000000000000000060648201526084016105ed565b73ffffffffffffffffffffffffffffffffffffffff821661153c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602260248201527f45524332303a20617070726f766520746f20746865207a65726f20616464726560448201527f737300000000000000000000000000000000000000000000000000000000000060648201526084016105ed565b73ffffffffffffffffffffffffffffffffffffffff83811660008181526034602090815260408083209487168084529482529182902085905590518481527f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925910160405180910390a3505050565b73ffffffffffffffffffffffffffffffffffffffff831661164d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602560248201527f45524332303a207472616e736665722066726f6d20746865207a65726f20616460448201527f647265737300000000000000000000000000000000000000000000000000000060648201526084016105ed565b73ffffffffffffffffffffffffffffffffffffffff82166116f0576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602360248201527f45524332303a207472616e7366657220746f20746865207a65726f206164647260448201527f657373000000000000000000000000000000000000000000000000000000000060648201526084016105ed565b73ffffffffffffffffffffffffffffffffffffffff8316600090815260336020526040902054818110156117a6576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f45524332303a207472616e7366657220616d6f756e742065786365656473206260448201527f616c616e6365000000000000000000000000000000000000000000000000000060648201526084016105ed565b73ffffffffffffffffffffffffffffffffffffffff8085166000908152603360205260408082208585039055918516815290812080548492906117ea908490612887565b925050819055508273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef8460405161185091815260200190565b60405180910390a3610734565b73ffffffffffffffffffffffffffffffffffffffff8216611900576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602160248201527f45524332303a206275726e2066726f6d20746865207a65726f2061646472657360448201527f730000000000000000000000000000000000000000000000000000000000000060648201526084016105ed565b73ffffffffffffffffffffffffffffffffffffffff8216600090815260336020526040902054818110156119b6576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602260248201527f45524332303a206275726e20616d6f756e7420657863656564732062616c616e60448201527f636500000000000000000000000000000000000000000000000000000000000060648201526084016105ed565b73ffffffffffffffffffffffffffffffffffffffff831660009081526033602052604081208383039055603580548492906119f29084906128bc565b909155505060405182815260009073ffffffffffffffffffffffffffffffffffffffff8516907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef9060200160405180910390a3505050565b8073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1614611afb5773ffffffffffffffffffffffffffffffffffffffff82811660009081526034602090815260408083209385168352929052205483811015611aea576040517f715ec26c00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b611af98383610a4687856128bc565b505b6109ee828461185d565b60006109fd7f8b73c3c69bb8fe3d512ecc4cf759cc79239f7b179b0ffacaa9a75d522b39400f611b3460655490565b6066546040805160208101859052908101839052606081018290524660808201523060a082015260009060c0016040516020818303038152906040528051906020012090509392505050565b73ffffffffffffffffffffffffffffffffffffffff8216611bfd576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601f60248201527f45524332303a206d696e7420746f20746865207a65726f20616464726573730060448201526064016105ed565b8060356000828254611c0f9190612887565b909155505073ffffffffffffffffffffffffffffffffffffffff821660009081526033602052604081208054839290611c49908490612887565b909155505060405181815273ffffffffffffffffffffffffffffffffffffffff8316906000907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef9060200160405180910390a35050565b73ffffffffffffffffffffffffffffffffffffffff811660009081526099602052604090208054600181018255905b50919050565b6000610ac5611ce2611b05565b836040517f19010000000000000000000000000000000000000000000000000000000000006020820152602281018390526042810182905260009060620160405160208183030381529060405280519060200120905092915050565b6000806000611d4f8787878761202c565b91509150611d5c81612144565b5095945050505050565b600054610100900460ff16611dfd576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201527f6e697469616c697a696e6700000000000000000000000000000000000000000060648201526084016105ed565b565b600054610100900460ff16611e96576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201527f6e697469616c697a696e6700000000000000000000000000000000000000000060648201526084016105ed565b815160209283012081519190920120606591909155606655565b600054610100900460ff16611f47576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201527f6e697469616c697a696e6700000000000000000000000000000000000000000060648201526084016105ed565b507f6e71edae12b1b97f4d1f60370fef10105fa2faae0126114a169c64845d6126c9609a55565b600054610100900460ff16612005576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201527f6e697469616c697a696e6700000000000000000000000000000000000000000060648201526084016105ed565b815161201890603690602085019061239d565b5080516109ee90603790602084019061239d565b6000807f7fffffffffffffffffffffffffffffff5d576e7357a4501ddfe92f46681b20a0831115612063575060009050600361213b565b8460ff16601b1415801561207b57508460ff16601c14155b1561208c575060009050600461213b565b6040805160008082526020820180845289905260ff881692820192909252606081018690526080810185905260019060a0016020604051602081039080840390855afa1580156120e0573d6000803e3d6000fd5b50506040517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0015191505073ffffffffffffffffffffffffffffffffffffffff81166121345760006001925092505061213b565b9150600090505b94509492505050565b6000816004811115612158576121586128d3565b14156121615750565b6001816004811115612175576121756128d3565b14156121dd576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601860248201527f45434453413a20696e76616c6964207369676e6174757265000000000000000060448201526064016105ed565b60028160048111156121f1576121f16128d3565b1415612259576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601f60248201527f45434453413a20696e76616c6964207369676e6174757265206c656e6774680060448201526064016105ed565b600381600481111561226d5761226d6128d3565b14156122fb576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602260248201527f45434453413a20696e76616c6964207369676e6174757265202773272076616c60448201527f756500000000000000000000000000000000000000000000000000000000000060648201526084016105ed565b600481600481111561230f5761230f6128d3565b1415610ad5576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602260248201527f45434453413a20696e76616c6964207369676e6174757265202776272076616c60448201527f756500000000000000000000000000000000000000000000000000000000000060648201526084016105ed565b8280546123a99061280a565b90600052602060002090601f0160209004810192826123cb5760008555612411565b82601f106123e457805160ff1916838001178555612411565b82800160010185558215612411579182015b828111156124115782518255916020019190600101906123f6565b5061241d929150612421565b5090565b5b8082111561241d5760008155600101612422565b600060208083528351808285015260005b8181101561246357858101830151858201604001528201612447565b81811115612475576000604083870101525b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016929092016040019392505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b600082601f8301126124e957600080fd5b813567ffffffffffffffff80821115612504576125046124a9565b604051601f83017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0908116603f0116810190828211818310171561254a5761254a6124a9565b8160405283815286602085880101111561256357600080fd5b836020870160208301376000602085830101528094505050505092915050565b73ffffffffffffffffffffffffffffffffffffffff81168114610ad557600080fd5b6000806000606084860312156125ba57600080fd5b833567ffffffffffffffff808211156125d257600080fd5b6125de878388016124d8565b945060208601359150808211156125f457600080fd5b50612601868287016124d8565b925050604084013561261281612583565b809150509250925092565b6000806040838503121561263057600080fd5b823561263b81612583565b946020939093013593505050565b60008060006060848603121561265e57600080fd5b833561266981612583565b9250602084013561267981612583565b929592945050506040919091013590565b6000806040838503121561269d57600080fd5b8235915060208301356126af81612583565b809150509250929050565b6000602082840312156126cc57600080fd5b81356126d781612583565b9392505050565b6000806000606084860312156126f357600080fd5b83359250602084013561270581612583565b9150604084013561261281612583565b60006020828403121561272757600080fd5b5035919050565b60008060006060848603121561274357600080fd5b833561274e81612583565b925060208401359150604084013561261281612583565b600080600080600080600060e0888a03121561278057600080fd5b873561278b81612583565b9650602088013561279b81612583565b95506040880135945060608801359350608088013560ff811681146127bf57600080fd5b9699959850939692959460a0840135945060c09093013592915050565b600080604083850312156127ef57600080fd5b82356127fa81612583565b915060208301356126af81612583565b600181811c9082168061281e57607f821691505b60208210811415611ccf577f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b6000821982111561289a5761289a612858565b500190565b6000602082840312156128b157600080fd5b81516126d781612583565b6000828210156128ce576128ce612858565b500390565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fdfea264697066735822122022fc1ef28c90996ff73bc899418c4c5f537e126c89de7eff091c2ae8e408647e64736f6c634300080c0033", - "deployedBytecode": "0x608060405234801561001057600080fd5b50600436106101cf5760003560e01c806370a0823111610104578063a457c2d7116100a2578063d505accf11610071578063d505accf14610423578063dd62ed3e14610436578063f0f442601461047c578063f1cc2dea1461048f57600080fd5b8063a457c2d7146103c7578063a9059cbb146103da578063aa271e1a146103ed578063cdc5aa9d1461041057600080fd5b806393bd6f69116100de57806393bd6f691461038657806395d89b411461039957806397536325146103a1578063983b2d56146103b457600080fd5b806370a082311461032a5780637ecebe001461036057806390218cff1461037357600080fd5b8063313ce56711610171578063395093511161014b578063395093511461029f57806340c10f19146102b257806361d027b3146102c55780636ac5dc461461030a57600080fd5b8063313ce56714610275578063350ebe04146102845780633644e5151461029757600080fd5b806318160ddd116101ad57806318160ddd1461022a57806323b872dd1461023c5780632b471d8e1461024f5780633092afd51461026257600080fd5b806306fdde03146101d4578063077f224a146101f2578063095ea7b314610207575b600080fd5b6101dc6104b4565b6040516101e99190612436565b60405180910390f35b6102056102003660046125a5565b610546565b005b61021a61021536600461261d565b61073a565b60405190151581526020016101e9565b6035545b6040519081526020016101e9565b61021a61024a366004612649565b610750565b61020561025d36600461268a565b610836565b6102056102703660046126ba565b61088d565b604051601281526020016101e9565b6102056102923660046126de565b61099a565b61022e6109f3565b61021a6102ad36600461261d565b610a02565b6102056102c036600461261d565b610a4b565b60ce546102e59073ffffffffffffffffffffffffffffffffffffffff1681565b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020016101e9565b60cc546102e59073ffffffffffffffffffffffffffffffffffffffff1681565b61022e6103383660046126ba565b73ffffffffffffffffffffffffffffffffffffffff1660009081526033602052604090205490565b61022e61036e3660046126ba565b610a9e565b610205610381366004612715565b610acb565b61020561039436600461268a565b610ad8565b6101dc610b72565b6102056103af36600461272e565b610b81565b6102056103c23660046126ba565b610c1d565b61021a6103d536600461261d565b610ce5565b61021a6103e836600461261d565b610dbd565b61021a6103fb3660046126ba565b60cd6020526000908152604090205460ff1681565b61020561041e3660046126ba565b610dca565b610205610431366004612765565b611000565b61022e6104443660046127dc565b73ffffffffffffffffffffffffffffffffffffffff918216600090815260346020908152604080832093909416825291909152205490565b61020561048a3660046126ba565b6111a1565b60ce5461021a9074010000000000000000000000000000000000000000900460ff1681565b6060603680546104c39061280a565b80601f01602080910402602001604051908101604052809291908181526020018280546104ef9061280a565b801561053c5780601f106105115761010080835404028352916020019161053c565b820191906000526020600020905b81548152906001019060200180831161051f57829003601f168201915b5050505050905090565b600054610100900460ff166105615760005460ff1615610565565b303b155b6105f6576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201527f647920696e697469616c697a656400000000000000000000000000000000000060648201526084015b60405180910390fd5b600054610100900460ff1615801561063557600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0000166101011790555b61063e84611267565b610648848461134e565b73ffffffffffffffffffffffffffffffffffffffff82166106c5576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600160248201527f300000000000000000000000000000000000000000000000000000000000000060448201526064016105ed565b60cc80547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff8416179055801561073457600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff1690555b50505050565b60006107473384846113f7565b50600192915050565b600061075d8484846115aa565b73ffffffffffffffffffffffffffffffffffffffff841660009081526034602090815260408083203384529091529020548281101561081e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602860248201527f45524332303a207472616e7366657220616d6f756e742065786365656473206160448201527f6c6c6f77616e636500000000000000000000000000000000000000000000000060648201526084016105ed565b61082b85338584036113f7565b506001949350505050565b33600090815260cd602052604090205460ff1661087f576040517ff8d2906c00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b610889818361185d565b5050565b3373ffffffffffffffffffffffffffffffffffffffff8216148015906108ef575060ce5473ffffffffffffffffffffffffffffffffffffffff16331415806108ef575060cc5473ffffffffffffffffffffffffffffffffffffffff8281169116145b15610926576040517fddb5de5e00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff8116600081815260cd602052604080822080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00169055517f98c15241d6c02bc5ee0b780e11b3ea737a2defd9d04877edbe9f9497065bd02f9190a250565b33600090815260cd602052604090205460ff166109e3576040517ff8d2906c00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6109ee838383611a4a565b505050565b60006109fd611b05565b905090565b33600081815260346020908152604080832073ffffffffffffffffffffffffffffffffffffffff871684529091528120549091610747918590610a46908690612887565b6113f7565b33600090815260cd602052604090205460ff16610a94576040517ff8d2906c00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6108898282611b80565b73ffffffffffffffffffffffffffffffffffffffff81166000908152609960205260408120545b92915050565b610ad5338261185d565b50565b610ae2338361185d565b60cc546040517f251ad8730000000000000000000000000000000000000000000000000000000081526004810184905273ffffffffffffffffffffffffffffffffffffffff83811660248301529091169063251ad87390604401600060405180830381600087803b158015610b5657600080fd5b505af1158015610b6a573d6000803e3d6000fd5b505050505050565b6060603780546104c39061280a565b610b8c828433611a4a565b60cc546040517f251ad8730000000000000000000000000000000000000000000000000000000081526004810184905273ffffffffffffffffffffffffffffffffffffffff83811660248301529091169063251ad87390604401600060405180830381600087803b158015610c0057600080fd5b505af1158015610c14573d6000803e3d6000fd5b50505050505050565b60ce5473ffffffffffffffffffffffffffffffffffffffff163314610c6e576040517fb90cdbb100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff8116600081815260cd602052604080822080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00166001179055517f98c15241d6c02bc5ee0b780e11b3ea737a2defd9d04877edbe9f9497065bd02f9190a250565b33600090815260346020908152604080832073ffffffffffffffffffffffffffffffffffffffff8616845290915281205482811015610da6576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602560248201527f45524332303a2064656372656173656420616c6c6f77616e63652062656c6f7760448201527f207a65726f00000000000000000000000000000000000000000000000000000060648201526084016105ed565b610db333858584036113f7565b5060019392505050565b60006107473384846115aa565b73dc4e6dfe07efca50a197df15d9200883ef4eb1c83314610e17576040517fee3675d400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b3073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1663e9cbd8226040518163ffffffff1660e01b8152600401602060405180830381865afa158015610e79573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610e9d919061289f565b73ffffffffffffffffffffffffffffffffffffffff1614610eea576040517f14bcf5c800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60ce5474010000000000000000000000000000000000000000900460ff1615610f3f576040517fe1a1cccf00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60ce80547fffffffffffffffffffffff0000000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff808416918217740100000000000000000000000000000000000000001790925560cc54909116600090815260cd602052604080822080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00166001179055517f7dae230f18360d76a040c81f050aa14eb9d6dc7901b20fc5d855e2a20fe814d19190a250565b8342111561106a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f45524332305065726d69743a206578706972656420646561646c696e6500000060448201526064016105ed565b6000609a5488888861107b8c611ca0565b60408051602081019690965273ffffffffffffffffffffffffffffffffffffffff94851690860152929091166060840152608083015260a082015260c0810186905260e00160405160208183030381529060405280519060200120905060006110e382611cd5565b905060006110f382878787611d3e565b90508973ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff161461118a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601e60248201527f45524332305065726d69743a20696e76616c6964207369676e6174757265000060448201526064016105ed565b6111958a8a8a6113f7565b50505050505050505050565b60ce5473ffffffffffffffffffffffffffffffffffffffff1633146111f2576040517fb90cdbb100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60ce80547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83169081179091556040517f7dae230f18360d76a040c81f050aa14eb9d6dc7901b20fc5d855e2a20fe814d190600090a250565b3b151590565b600054610100900460ff166112fe576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201527f6e697469616c697a696e6700000000000000000000000000000000000000000060648201526084016105ed565b611306611d66565b611345816040518060400160405280600181526020017f3100000000000000000000000000000000000000000000000000000000000000815250611dff565b610ad581611eb0565b600054610100900460ff166113e5576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201527f6e697469616c697a696e6700000000000000000000000000000000000000000060648201526084016105ed565b6113ed611d66565b6108898282611f6e565b73ffffffffffffffffffffffffffffffffffffffff8316611499576040517f08c379a0000000000000000000000000000000000000000000000000000000008152602060048201526024808201527f45524332303a20617070726f76652066726f6d20746865207a65726f2061646460448201527f726573730000000000000000000000000000000000000000000000000000000060648201526084016105ed565b73ffffffffffffffffffffffffffffffffffffffff821661153c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602260248201527f45524332303a20617070726f766520746f20746865207a65726f20616464726560448201527f737300000000000000000000000000000000000000000000000000000000000060648201526084016105ed565b73ffffffffffffffffffffffffffffffffffffffff83811660008181526034602090815260408083209487168084529482529182902085905590518481527f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925910160405180910390a3505050565b73ffffffffffffffffffffffffffffffffffffffff831661164d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602560248201527f45524332303a207472616e736665722066726f6d20746865207a65726f20616460448201527f647265737300000000000000000000000000000000000000000000000000000060648201526084016105ed565b73ffffffffffffffffffffffffffffffffffffffff82166116f0576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602360248201527f45524332303a207472616e7366657220746f20746865207a65726f206164647260448201527f657373000000000000000000000000000000000000000000000000000000000060648201526084016105ed565b73ffffffffffffffffffffffffffffffffffffffff8316600090815260336020526040902054818110156117a6576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f45524332303a207472616e7366657220616d6f756e742065786365656473206260448201527f616c616e6365000000000000000000000000000000000000000000000000000060648201526084016105ed565b73ffffffffffffffffffffffffffffffffffffffff8085166000908152603360205260408082208585039055918516815290812080548492906117ea908490612887565b925050819055508273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef8460405161185091815260200190565b60405180910390a3610734565b73ffffffffffffffffffffffffffffffffffffffff8216611900576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602160248201527f45524332303a206275726e2066726f6d20746865207a65726f2061646472657360448201527f730000000000000000000000000000000000000000000000000000000000000060648201526084016105ed565b73ffffffffffffffffffffffffffffffffffffffff8216600090815260336020526040902054818110156119b6576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602260248201527f45524332303a206275726e20616d6f756e7420657863656564732062616c616e60448201527f636500000000000000000000000000000000000000000000000000000000000060648201526084016105ed565b73ffffffffffffffffffffffffffffffffffffffff831660009081526033602052604081208383039055603580548492906119f29084906128bc565b909155505060405182815260009073ffffffffffffffffffffffffffffffffffffffff8516907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef9060200160405180910390a3505050565b8073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1614611afb5773ffffffffffffffffffffffffffffffffffffffff82811660009081526034602090815260408083209385168352929052205483811015611aea576040517f715ec26c00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b611af98383610a4687856128bc565b505b6109ee828461185d565b60006109fd7f8b73c3c69bb8fe3d512ecc4cf759cc79239f7b179b0ffacaa9a75d522b39400f611b3460655490565b6066546040805160208101859052908101839052606081018290524660808201523060a082015260009060c0016040516020818303038152906040528051906020012090509392505050565b73ffffffffffffffffffffffffffffffffffffffff8216611bfd576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601f60248201527f45524332303a206d696e7420746f20746865207a65726f20616464726573730060448201526064016105ed565b8060356000828254611c0f9190612887565b909155505073ffffffffffffffffffffffffffffffffffffffff821660009081526033602052604081208054839290611c49908490612887565b909155505060405181815273ffffffffffffffffffffffffffffffffffffffff8316906000907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef9060200160405180910390a35050565b73ffffffffffffffffffffffffffffffffffffffff811660009081526099602052604090208054600181018255905b50919050565b6000610ac5611ce2611b05565b836040517f19010000000000000000000000000000000000000000000000000000000000006020820152602281018390526042810182905260009060620160405160208183030381529060405280519060200120905092915050565b6000806000611d4f8787878761202c565b91509150611d5c81612144565b5095945050505050565b600054610100900460ff16611dfd576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201527f6e697469616c697a696e6700000000000000000000000000000000000000000060648201526084016105ed565b565b600054610100900460ff16611e96576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201527f6e697469616c697a696e6700000000000000000000000000000000000000000060648201526084016105ed565b815160209283012081519190920120606591909155606655565b600054610100900460ff16611f47576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201527f6e697469616c697a696e6700000000000000000000000000000000000000000060648201526084016105ed565b507f6e71edae12b1b97f4d1f60370fef10105fa2faae0126114a169c64845d6126c9609a55565b600054610100900460ff16612005576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201527f6e697469616c697a696e6700000000000000000000000000000000000000000060648201526084016105ed565b815161201890603690602085019061239d565b5080516109ee90603790602084019061239d565b6000807f7fffffffffffffffffffffffffffffff5d576e7357a4501ddfe92f46681b20a0831115612063575060009050600361213b565b8460ff16601b1415801561207b57508460ff16601c14155b1561208c575060009050600461213b565b6040805160008082526020820180845289905260ff881692820192909252606081018690526080810185905260019060a0016020604051602081039080840390855afa1580156120e0573d6000803e3d6000fd5b50506040517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0015191505073ffffffffffffffffffffffffffffffffffffffff81166121345760006001925092505061213b565b9150600090505b94509492505050565b6000816004811115612158576121586128d3565b14156121615750565b6001816004811115612175576121756128d3565b14156121dd576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601860248201527f45434453413a20696e76616c6964207369676e6174757265000000000000000060448201526064016105ed565b60028160048111156121f1576121f16128d3565b1415612259576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601f60248201527f45434453413a20696e76616c6964207369676e6174757265206c656e6774680060448201526064016105ed565b600381600481111561226d5761226d6128d3565b14156122fb576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602260248201527f45434453413a20696e76616c6964207369676e6174757265202773272076616c60448201527f756500000000000000000000000000000000000000000000000000000000000060648201526084016105ed565b600481600481111561230f5761230f6128d3565b1415610ad5576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602260248201527f45434453413a20696e76616c6964207369676e6174757265202776272076616c60448201527f756500000000000000000000000000000000000000000000000000000000000060648201526084016105ed565b8280546123a99061280a565b90600052602060002090601f0160209004810192826123cb5760008555612411565b82601f106123e457805160ff1916838001178555612411565b82800160010185558215612411579182015b828111156124115782518255916020019190600101906123f6565b5061241d929150612421565b5090565b5b8082111561241d5760008155600101612422565b600060208083528351808285015260005b8181101561246357858101830151858201604001528201612447565b81811115612475576000604083870101525b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016929092016040019392505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b600082601f8301126124e957600080fd5b813567ffffffffffffffff80821115612504576125046124a9565b604051601f83017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0908116603f0116810190828211818310171561254a5761254a6124a9565b8160405283815286602085880101111561256357600080fd5b836020870160208301376000602085830101528094505050505092915050565b73ffffffffffffffffffffffffffffffffffffffff81168114610ad557600080fd5b6000806000606084860312156125ba57600080fd5b833567ffffffffffffffff808211156125d257600080fd5b6125de878388016124d8565b945060208601359150808211156125f457600080fd5b50612601868287016124d8565b925050604084013561261281612583565b809150509250925092565b6000806040838503121561263057600080fd5b823561263b81612583565b946020939093013593505050565b60008060006060848603121561265e57600080fd5b833561266981612583565b9250602084013561267981612583565b929592945050506040919091013590565b6000806040838503121561269d57600080fd5b8235915060208301356126af81612583565b809150509250929050565b6000602082840312156126cc57600080fd5b81356126d781612583565b9392505050565b6000806000606084860312156126f357600080fd5b83359250602084013561270581612583565b9150604084013561261281612583565b60006020828403121561272757600080fd5b5035919050565b60008060006060848603121561274357600080fd5b833561274e81612583565b925060208401359150604084013561261281612583565b600080600080600080600060e0888a03121561278057600080fd5b873561278b81612583565b9650602088013561279b81612583565b95506040880135945060608801359350608088013560ff811681146127bf57600080fd5b9699959850939692959460a0840135945060c09093013592915050565b600080604083850312156127ef57600080fd5b82356127fa81612583565b915060208301356126af81612583565b600181811c9082168061281e57607f821691505b60208210811415611ccf577f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b6000821982111561289a5761289a612858565b500190565b6000602082840312156128b157600080fd5b81516126d781612583565b6000828210156128ce576128ce612858565b500390565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fdfea264697066735822122022fc1ef28c90996ff73bc899418c4c5f537e126c89de7eff091c2ae8e408647e64736f6c634300080c0033", + "numDeployments": 2, + "solcInputHash": "871924e0c138825a2736b76def8fef8d", + "metadata": "{\"compiler\":{\"version\":\"0.8.17+commit.8df45f5f\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[],\"name\":\"BurnAmountExceedsAllowance\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidSender\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidTreasury\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"NotMinter\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"NotTreasury\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"spender\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"}],\"name\":\"Approval\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint8\",\"name\":\"version\",\"type\":\"uint8\"}],\"name\":\"Initialized\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"minter\",\"type\":\"address\"}],\"name\":\"MinterToggled\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"}],\"name\":\"Transfer\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"_treasury\",\"type\":\"address\"}],\"name\":\"TreasuryUpdated\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"DOMAIN_SEPARATOR\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"minter\",\"type\":\"address\"}],\"name\":\"addMinter\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"spender\",\"type\":\"address\"}],\"name\":\"allowance\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"spender\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"approve\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"}],\"name\":\"balanceOf\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"burner\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"}],\"name\":\"burnFrom\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"burner\",\"type\":\"address\"}],\"name\":\"burnSelf\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"burnStablecoin\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"decimals\",\"outputs\":[{\"internalType\":\"uint8\",\"name\":\"\",\"type\":\"uint8\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"spender\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"subtractedValue\",\"type\":\"uint256\"}],\"name\":\"decreaseAllowance\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"spender\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"addedValue\",\"type\":\"uint256\"}],\"name\":\"increaseAllowance\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"string\",\"name\":\"name_\",\"type\":\"string\"},{\"internalType\":\"string\",\"name\":\"symbol_\",\"type\":\"string\"},{\"internalType\":\"address\",\"name\":\"_treasury\",\"type\":\"address\"}],\"name\":\"initialize\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"isMinter\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"mint\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"name\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"}],\"name\":\"nonces\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"spender\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"deadline\",\"type\":\"uint256\"},{\"internalType\":\"uint8\",\"name\":\"v\",\"type\":\"uint8\"},{\"internalType\":\"bytes32\",\"name\":\"r\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32\",\"name\":\"s\",\"type\":\"bytes32\"}],\"name\":\"permit\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"minter\",\"type\":\"address\"}],\"name\":\"removeMinter\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_treasury\",\"type\":\"address\"}],\"name\":\"setTreasury\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"symbol\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"totalSupply\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"transfer\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"transferFrom\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"treasury\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"}],\"devdoc\":{\"author\":\"Angle Labs, Inc.\",\"details\":\"By default, agTokens are ERC-20 tokens with 18 decimals\",\"kind\":\"dev\",\"methods\":{\"DOMAIN_SEPARATOR()\":{\"details\":\"See {IERC20Permit-DOMAIN_SEPARATOR}.\"},\"addMinter(address)\":{\"details\":\"Zero address checks are performed directly in the `Treasury` contract\",\"params\":{\"minter\":\"Minter address to add\"}},\"allowance(address,address)\":{\"details\":\"See {IERC20-allowance}.\"},\"approve(address,uint256)\":{\"details\":\"See {IERC20-approve}. NOTE: If `amount` is the maximum `uint256`, the allowance is not updated on `transferFrom`. This is semantically equivalent to an infinite approval. Requirements: - `spender` cannot be the zero address.\"},\"balanceOf(address)\":{\"details\":\"See {IERC20-balanceOf}.\"},\"burnFrom(uint256,address,address)\":{\"details\":\"This method is to be called by a contract with the minter right after being requested to do so by a `sender` address willing to burn tokens from another `burner` addressThe method checks the allowance between the `sender` and the `burner`\",\"params\":{\"amount\":\"Amount of tokens to burn\",\"burner\":\"Address to burn from\",\"sender\":\"Address which requested the burn from `burner`\"}},\"burnSelf(uint256,address)\":{\"details\":\"This method is to be called by a contract with a minter right on the AgToken after being requested to do so by an address willing to burn tokens from its address\",\"params\":{\"amount\":\"Amount of tokens to burn\",\"burner\":\"Address to burn from\"}},\"burnStablecoin(uint256)\":{\"details\":\"This function can typically be called if there is a settlement mechanism to burn stablecoins\",\"params\":{\"amount\":\"Amount of stablecoins to burn\"}},\"constructor\":{\"custom:oz-upgrades-unsafe-allow\":\"constructor\"},\"decimals()\":{\"details\":\"Returns the number of decimals used to get its user representation. For example, if `decimals` equals `2`, a balance of `505` tokens should be displayed to a user as `5.05` (`505 / 10 ** 2`). Tokens usually opt for a value of 18, imitating the relationship between Ether and Wei. This is the value {ERC20} uses, unless this function is overridden; NOTE: This information is only used for _display_ purposes: it in no way affects any of the arithmetic of the contract, including {IERC20-balanceOf} and {IERC20-transfer}.\"},\"decreaseAllowance(address,uint256)\":{\"details\":\"Atomically decreases the allowance granted to `spender` by the caller. This is an alternative to {approve} that can be used as a mitigation for problems described in {IERC20-approve}. Emits an {Approval} event indicating the updated allowance. Requirements: - `spender` cannot be the zero address. - `spender` must have allowance for the caller of at least `subtractedValue`.\"},\"increaseAllowance(address,uint256)\":{\"details\":\"Atomically increases the allowance granted to `spender` by the caller. This is an alternative to {approve} that can be used as a mitigation for problems described in {IERC20-approve}. Emits an {Approval} event indicating the updated allowance. Requirements: - `spender` cannot be the zero address.\"},\"mint(address,uint256)\":{\"details\":\"The contracts allowed to issue agTokens are the `StableMaster` contract, `VaultManager` contracts associated to this stablecoin as well as the flash loan module (if activated) and potentially contracts whitelisted by governance\",\"params\":{\"account\":\"Address to mint to\",\"amount\":\"Amount to mint\"}},\"name()\":{\"details\":\"Returns the name of the token.\"},\"nonces(address)\":{\"details\":\"See {IERC20Permit-nonces}.\"},\"permit(address,address,uint256,uint256,uint8,bytes32,bytes32)\":{\"details\":\"See {IERC20Permit-permit}.\"},\"removeMinter(address)\":{\"details\":\"This function can also be called by a minter wishing to revoke itself\",\"params\":{\"minter\":\"Minter address to remove\"}},\"setTreasury(address)\":{\"params\":{\"_treasury\":\"New treasury address\"}},\"symbol()\":{\"details\":\"Returns the symbol of the token, usually a shorter version of the name.\"},\"totalSupply()\":{\"details\":\"See {IERC20-totalSupply}.\"},\"transfer(address,uint256)\":{\"details\":\"See {IERC20-transfer}. Requirements: - `to` cannot be the zero address. - the caller must have a balance of at least `amount`.\"},\"transferFrom(address,address,uint256)\":{\"details\":\"See {IERC20-transferFrom}. Emits an {Approval} event indicating the updated allowance. This is not required by the EIP. See the note at the beginning of {ERC20}. NOTE: Does not update the allowance if the current allowance is the maximum `uint256`. Requirements: - `from` and `to` cannot be the zero address. - `from` must have a balance of at least `amount`. - the caller must have allowance for ``from``'s tokens of at least `amount`.\"}},\"stateVariables\":{\"isMinter\":{\"params\":{\"minter\":\"Address for which the minting right should be checked\"},\"return\":\"Whether the address has the right to mint agTokens or not\",\"returns\":{\"_0\":\"Whether the address has the right to mint agTokens or not\"}}},\"title\":\"AgToken\",\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{\"addMinter(address)\":{\"notice\":\"Adds a minter in the contract\"},\"burnFrom(uint256,address,address)\":{\"notice\":\"Burns `amount` tokens from a `burner` address after being asked to by `sender`\"},\"burnSelf(uint256,address)\":{\"notice\":\"Burns `amount` tokens from a `burner` address\"},\"burnStablecoin(uint256)\":{\"notice\":\"Allows anyone to burn stablecoins\"},\"initialize(string,string,address)\":{\"notice\":\"Initializes the `AgToken` contract\"},\"isMinter(address)\":{\"notice\":\"Checks whether an address has the right to mint agTokens\"},\"mint(address,uint256)\":{\"notice\":\"Lets the `StableMaster` contract or another whitelisted contract mint agTokens\"},\"removeMinter(address)\":{\"notice\":\"Removes a minter from the contract\"},\"setTreasury(address)\":{\"notice\":\"Sets a new treasury contract\"},\"treasury()\":{\"notice\":\"Reference to the treasury contract which can grant minting rights\"}},\"notice\":\"Base contract for Angle agTokens on Ethereum and on other chains\",\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/agToken/AgToken.sol\":\"AgToken\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":1000000},\"remappings\":[]},\"sources\":{\"@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.7.0) (proxy/utils/Initializable.sol)\\n\\npragma solidity ^0.8.2;\\n\\nimport \\\"../../utils/AddressUpgradeable.sol\\\";\\n\\n/**\\n * @dev This is a base contract to aid in writing upgradeable contracts, or any kind of contract that will be deployed\\n * behind a proxy. Since proxied contracts do not make use of a constructor, it's common to move constructor logic to an\\n * external initializer function, usually called `initialize`. It then becomes necessary to protect this initializer\\n * function so it can only be called once. The {initializer} modifier provided by this contract will have this effect.\\n *\\n * The initialization functions use a version number. Once a version number is used, it is consumed and cannot be\\n * reused. This mechanism prevents re-execution of each \\\"step\\\" but allows the creation of new initialization steps in\\n * case an upgrade adds a module that needs to be initialized.\\n *\\n * For example:\\n *\\n * [.hljs-theme-light.nopadding]\\n * ```\\n * contract MyToken is ERC20Upgradeable {\\n * function initialize() initializer public {\\n * __ERC20_init(\\\"MyToken\\\", \\\"MTK\\\");\\n * }\\n * }\\n * contract MyTokenV2 is MyToken, ERC20PermitUpgradeable {\\n * function initializeV2() reinitializer(2) public {\\n * __ERC20Permit_init(\\\"MyToken\\\");\\n * }\\n * }\\n * ```\\n *\\n * TIP: To avoid leaving the proxy in an uninitialized state, the initializer function should be called as early as\\n * possible by providing the encoded function call as the `_data` argument to {ERC1967Proxy-constructor}.\\n *\\n * CAUTION: When used with inheritance, manual care must be taken to not invoke a parent initializer twice, or to ensure\\n * that all initializers are idempotent. This is not verified automatically as constructors are by Solidity.\\n *\\n * [CAUTION]\\n * ====\\n * Avoid leaving a contract uninitialized.\\n *\\n * An uninitialized contract can be taken over by an attacker. This applies to both a proxy and its implementation\\n * contract, which may impact the proxy. To prevent the implementation contract from being used, you should invoke\\n * the {_disableInitializers} function in the constructor to automatically lock it when it is deployed:\\n *\\n * [.hljs-theme-light.nopadding]\\n * ```\\n * /// @custom:oz-upgrades-unsafe-allow constructor\\n * constructor() {\\n * _disableInitializers();\\n * }\\n * ```\\n * ====\\n */\\nabstract contract Initializable {\\n /**\\n * @dev Indicates that the contract has been initialized.\\n * @custom:oz-retyped-from bool\\n */\\n uint8 private _initialized;\\n\\n /**\\n * @dev Indicates that the contract is in the process of being initialized.\\n */\\n bool private _initializing;\\n\\n /**\\n * @dev Triggered when the contract has been initialized or reinitialized.\\n */\\n event Initialized(uint8 version);\\n\\n /**\\n * @dev A modifier that defines a protected initializer function that can be invoked at most once. In its scope,\\n * `onlyInitializing` functions can be used to initialize parent contracts. Equivalent to `reinitializer(1)`.\\n */\\n modifier initializer() {\\n bool isTopLevelCall = !_initializing;\\n require(\\n (isTopLevelCall && _initialized < 1) || (!AddressUpgradeable.isContract(address(this)) && _initialized == 1),\\n \\\"Initializable: contract is already initialized\\\"\\n );\\n _initialized = 1;\\n if (isTopLevelCall) {\\n _initializing = true;\\n }\\n _;\\n if (isTopLevelCall) {\\n _initializing = false;\\n emit Initialized(1);\\n }\\n }\\n\\n /**\\n * @dev A modifier that defines a protected reinitializer function that can be invoked at most once, and only if the\\n * contract hasn't been initialized to a greater version before. In its scope, `onlyInitializing` functions can be\\n * used to initialize parent contracts.\\n *\\n * `initializer` is equivalent to `reinitializer(1)`, so a reinitializer may be used after the original\\n * initialization step. This is essential to configure modules that are added through upgrades and that require\\n * initialization.\\n *\\n * Note that versions can jump in increments greater than 1; this implies that if multiple reinitializers coexist in\\n * a contract, executing them in the right order is up to the developer or operator.\\n */\\n modifier reinitializer(uint8 version) {\\n require(!_initializing && _initialized < version, \\\"Initializable: contract is already initialized\\\");\\n _initialized = version;\\n _initializing = true;\\n _;\\n _initializing = false;\\n emit Initialized(version);\\n }\\n\\n /**\\n * @dev Modifier to protect an initialization function so that it can only be invoked by functions with the\\n * {initializer} and {reinitializer} modifiers, directly or indirectly.\\n */\\n modifier onlyInitializing() {\\n require(_initializing, \\\"Initializable: contract is not initializing\\\");\\n _;\\n }\\n\\n /**\\n * @dev Locks the contract, preventing any future reinitialization. This cannot be part of an initializer call.\\n * Calling this in the constructor of a contract will prevent that contract from being initialized or reinitialized\\n * to any version. It is recommended to use this to lock implementation contracts that are designed to be called\\n * through proxies.\\n */\\n function _disableInitializers() internal virtual {\\n require(!_initializing, \\\"Initializable: contract is initializing\\\");\\n if (_initialized < type(uint8).max) {\\n _initialized = type(uint8).max;\\n emit Initialized(type(uint8).max);\\n }\\n }\\n}\\n\",\"keccak256\":\"0x0203dcadc5737d9ef2c211d6fa15d18ebc3b30dfa51903b64870b01a062b0b4e\",\"license\":\"MIT\"},\"@openzeppelin/contracts-upgradeable/token/ERC20/ERC20Upgradeable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.7.0) (token/ERC20/ERC20.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"./IERC20Upgradeable.sol\\\";\\nimport \\\"./extensions/IERC20MetadataUpgradeable.sol\\\";\\nimport \\\"../../utils/ContextUpgradeable.sol\\\";\\nimport \\\"../../proxy/utils/Initializable.sol\\\";\\n\\n/**\\n * @dev Implementation of the {IERC20} interface.\\n *\\n * This implementation is agnostic to the way tokens are created. This means\\n * that a supply mechanism has to be added in a derived contract using {_mint}.\\n * For a generic mechanism see {ERC20PresetMinterPauser}.\\n *\\n * TIP: For a detailed writeup see our guide\\n * https://forum.zeppelin.solutions/t/how-to-implement-erc20-supply-mechanisms/226[How\\n * to implement supply mechanisms].\\n *\\n * We have followed general OpenZeppelin Contracts guidelines: functions revert\\n * instead returning `false` on failure. This behavior is nonetheless\\n * conventional and does not conflict with the expectations of ERC20\\n * applications.\\n *\\n * Additionally, an {Approval} event is emitted on calls to {transferFrom}.\\n * This allows applications to reconstruct the allowance for all accounts just\\n * by listening to said events. Other implementations of the EIP may not emit\\n * these events, as it isn't required by the specification.\\n *\\n * Finally, the non-standard {decreaseAllowance} and {increaseAllowance}\\n * functions have been added to mitigate the well-known issues around setting\\n * allowances. See {IERC20-approve}.\\n */\\ncontract ERC20Upgradeable is Initializable, ContextUpgradeable, IERC20Upgradeable, IERC20MetadataUpgradeable {\\n mapping(address => uint256) private _balances;\\n\\n mapping(address => mapping(address => uint256)) private _allowances;\\n\\n uint256 private _totalSupply;\\n\\n string private _name;\\n string private _symbol;\\n\\n /**\\n * @dev Sets the values for {name} and {symbol}.\\n *\\n * The default value of {decimals} is 18. To select a different value for\\n * {decimals} you should overload it.\\n *\\n * All two of these values are immutable: they can only be set once during\\n * construction.\\n */\\n function __ERC20_init(string memory name_, string memory symbol_) internal onlyInitializing {\\n __ERC20_init_unchained(name_, symbol_);\\n }\\n\\n function __ERC20_init_unchained(string memory name_, string memory symbol_) internal onlyInitializing {\\n _name = name_;\\n _symbol = symbol_;\\n }\\n\\n /**\\n * @dev Returns the name of the token.\\n */\\n function name() public view virtual override returns (string memory) {\\n return _name;\\n }\\n\\n /**\\n * @dev Returns the symbol of the token, usually a shorter version of the\\n * name.\\n */\\n function symbol() public view virtual override returns (string memory) {\\n return _symbol;\\n }\\n\\n /**\\n * @dev Returns the number of decimals used to get its user representation.\\n * For example, if `decimals` equals `2`, a balance of `505` tokens should\\n * be displayed to a user as `5.05` (`505 / 10 ** 2`).\\n *\\n * Tokens usually opt for a value of 18, imitating the relationship between\\n * Ether and Wei. This is the value {ERC20} uses, unless this function is\\n * overridden;\\n *\\n * NOTE: This information is only used for _display_ purposes: it in\\n * no way affects any of the arithmetic of the contract, including\\n * {IERC20-balanceOf} and {IERC20-transfer}.\\n */\\n function decimals() public view virtual override returns (uint8) {\\n return 18;\\n }\\n\\n /**\\n * @dev See {IERC20-totalSupply}.\\n */\\n function totalSupply() public view virtual override returns (uint256) {\\n return _totalSupply;\\n }\\n\\n /**\\n * @dev See {IERC20-balanceOf}.\\n */\\n function balanceOf(address account) public view virtual override returns (uint256) {\\n return _balances[account];\\n }\\n\\n /**\\n * @dev See {IERC20-transfer}.\\n *\\n * Requirements:\\n *\\n * - `to` cannot be the zero address.\\n * - the caller must have a balance of at least `amount`.\\n */\\n function transfer(address to, uint256 amount) public virtual override returns (bool) {\\n address owner = _msgSender();\\n _transfer(owner, to, amount);\\n return true;\\n }\\n\\n /**\\n * @dev See {IERC20-allowance}.\\n */\\n function allowance(address owner, address spender) public view virtual override returns (uint256) {\\n return _allowances[owner][spender];\\n }\\n\\n /**\\n * @dev See {IERC20-approve}.\\n *\\n * NOTE: If `amount` is the maximum `uint256`, the allowance is not updated on\\n * `transferFrom`. This is semantically equivalent to an infinite approval.\\n *\\n * Requirements:\\n *\\n * - `spender` cannot be the zero address.\\n */\\n function approve(address spender, uint256 amount) public virtual override returns (bool) {\\n address owner = _msgSender();\\n _approve(owner, spender, amount);\\n return true;\\n }\\n\\n /**\\n * @dev See {IERC20-transferFrom}.\\n *\\n * Emits an {Approval} event indicating the updated allowance. This is not\\n * required by the EIP. See the note at the beginning of {ERC20}.\\n *\\n * NOTE: Does not update the allowance if the current allowance\\n * is the maximum `uint256`.\\n *\\n * Requirements:\\n *\\n * - `from` and `to` cannot be the zero address.\\n * - `from` must have a balance of at least `amount`.\\n * - the caller must have allowance for ``from``'s tokens of at least\\n * `amount`.\\n */\\n function transferFrom(\\n address from,\\n address to,\\n uint256 amount\\n ) public virtual override returns (bool) {\\n address spender = _msgSender();\\n _spendAllowance(from, spender, amount);\\n _transfer(from, to, amount);\\n return true;\\n }\\n\\n /**\\n * @dev Atomically increases the allowance granted to `spender` by the caller.\\n *\\n * This is an alternative to {approve} that can be used as a mitigation for\\n * problems described in {IERC20-approve}.\\n *\\n * Emits an {Approval} event indicating the updated allowance.\\n *\\n * Requirements:\\n *\\n * - `spender` cannot be the zero address.\\n */\\n function increaseAllowance(address spender, uint256 addedValue) public virtual returns (bool) {\\n address owner = _msgSender();\\n _approve(owner, spender, allowance(owner, spender) + addedValue);\\n return true;\\n }\\n\\n /**\\n * @dev Atomically decreases the allowance granted to `spender` by the caller.\\n *\\n * This is an alternative to {approve} that can be used as a mitigation for\\n * problems described in {IERC20-approve}.\\n *\\n * Emits an {Approval} event indicating the updated allowance.\\n *\\n * Requirements:\\n *\\n * - `spender` cannot be the zero address.\\n * - `spender` must have allowance for the caller of at least\\n * `subtractedValue`.\\n */\\n function decreaseAllowance(address spender, uint256 subtractedValue) public virtual returns (bool) {\\n address owner = _msgSender();\\n uint256 currentAllowance = allowance(owner, spender);\\n require(currentAllowance >= subtractedValue, \\\"ERC20: decreased allowance below zero\\\");\\n unchecked {\\n _approve(owner, spender, currentAllowance - subtractedValue);\\n }\\n\\n return true;\\n }\\n\\n /**\\n * @dev Moves `amount` of tokens from `from` to `to`.\\n *\\n * This internal function is equivalent to {transfer}, and can be used to\\n * e.g. implement automatic token fees, slashing mechanisms, etc.\\n *\\n * Emits a {Transfer} event.\\n *\\n * Requirements:\\n *\\n * - `from` cannot be the zero address.\\n * - `to` cannot be the zero address.\\n * - `from` must have a balance of at least `amount`.\\n */\\n function _transfer(\\n address from,\\n address to,\\n uint256 amount\\n ) internal virtual {\\n require(from != address(0), \\\"ERC20: transfer from the zero address\\\");\\n require(to != address(0), \\\"ERC20: transfer to the zero address\\\");\\n\\n _beforeTokenTransfer(from, to, amount);\\n\\n uint256 fromBalance = _balances[from];\\n require(fromBalance >= amount, \\\"ERC20: transfer amount exceeds balance\\\");\\n unchecked {\\n _balances[from] = fromBalance - amount;\\n }\\n _balances[to] += amount;\\n\\n emit Transfer(from, to, amount);\\n\\n _afterTokenTransfer(from, to, amount);\\n }\\n\\n /** @dev Creates `amount` tokens and assigns them to `account`, increasing\\n * the total supply.\\n *\\n * Emits a {Transfer} event with `from` set to the zero address.\\n *\\n * Requirements:\\n *\\n * - `account` cannot be the zero address.\\n */\\n function _mint(address account, uint256 amount) internal virtual {\\n require(account != address(0), \\\"ERC20: mint to the zero address\\\");\\n\\n _beforeTokenTransfer(address(0), account, amount);\\n\\n _totalSupply += amount;\\n _balances[account] += amount;\\n emit Transfer(address(0), account, amount);\\n\\n _afterTokenTransfer(address(0), account, amount);\\n }\\n\\n /**\\n * @dev Destroys `amount` tokens from `account`, reducing the\\n * total supply.\\n *\\n * Emits a {Transfer} event with `to` set to the zero address.\\n *\\n * Requirements:\\n *\\n * - `account` cannot be the zero address.\\n * - `account` must have at least `amount` tokens.\\n */\\n function _burn(address account, uint256 amount) internal virtual {\\n require(account != address(0), \\\"ERC20: burn from the zero address\\\");\\n\\n _beforeTokenTransfer(account, address(0), amount);\\n\\n uint256 accountBalance = _balances[account];\\n require(accountBalance >= amount, \\\"ERC20: burn amount exceeds balance\\\");\\n unchecked {\\n _balances[account] = accountBalance - amount;\\n }\\n _totalSupply -= amount;\\n\\n emit Transfer(account, address(0), amount);\\n\\n _afterTokenTransfer(account, address(0), amount);\\n }\\n\\n /**\\n * @dev Sets `amount` as the allowance of `spender` over the `owner` s tokens.\\n *\\n * This internal function is equivalent to `approve`, and can be used to\\n * e.g. set automatic allowances for certain subsystems, etc.\\n *\\n * Emits an {Approval} event.\\n *\\n * Requirements:\\n *\\n * - `owner` cannot be the zero address.\\n * - `spender` cannot be the zero address.\\n */\\n function _approve(\\n address owner,\\n address spender,\\n uint256 amount\\n ) internal virtual {\\n require(owner != address(0), \\\"ERC20: approve from the zero address\\\");\\n require(spender != address(0), \\\"ERC20: approve to the zero address\\\");\\n\\n _allowances[owner][spender] = amount;\\n emit Approval(owner, spender, amount);\\n }\\n\\n /**\\n * @dev Updates `owner` s allowance for `spender` based on spent `amount`.\\n *\\n * Does not update the allowance amount in case of infinite allowance.\\n * Revert if not enough allowance is available.\\n *\\n * Might emit an {Approval} event.\\n */\\n function _spendAllowance(\\n address owner,\\n address spender,\\n uint256 amount\\n ) internal virtual {\\n uint256 currentAllowance = allowance(owner, spender);\\n if (currentAllowance != type(uint256).max) {\\n require(currentAllowance >= amount, \\\"ERC20: insufficient allowance\\\");\\n unchecked {\\n _approve(owner, spender, currentAllowance - amount);\\n }\\n }\\n }\\n\\n /**\\n * @dev Hook that is called before any transfer of tokens. This includes\\n * minting and burning.\\n *\\n * Calling conditions:\\n *\\n * - when `from` and `to` are both non-zero, `amount` of ``from``'s tokens\\n * will be transferred to `to`.\\n * - when `from` is zero, `amount` tokens will be minted for `to`.\\n * - when `to` is zero, `amount` of ``from``'s tokens will be burned.\\n * - `from` and `to` are never both zero.\\n *\\n * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].\\n */\\n function _beforeTokenTransfer(\\n address from,\\n address to,\\n uint256 amount\\n ) internal virtual {}\\n\\n /**\\n * @dev Hook that is called after any transfer of tokens. This includes\\n * minting and burning.\\n *\\n * Calling conditions:\\n *\\n * - when `from` and `to` are both non-zero, `amount` of ``from``'s tokens\\n * has been transferred to `to`.\\n * - when `from` is zero, `amount` tokens have been minted for `to`.\\n * - when `to` is zero, `amount` of ``from``'s tokens have been burned.\\n * - `from` and `to` are never both zero.\\n *\\n * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].\\n */\\n function _afterTokenTransfer(\\n address from,\\n address to,\\n uint256 amount\\n ) internal virtual {}\\n\\n /**\\n * @dev This empty reserved space is put in place to allow future versions to add new\\n * variables without shifting down storage in the inheritance chain.\\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\\n */\\n uint256[45] private __gap;\\n}\\n\",\"keccak256\":\"0x7c7ac0bc6c340a7f320524b9a4b4b079ee9da3c51258080d4bab237f329a427c\",\"license\":\"MIT\"},\"@openzeppelin/contracts-upgradeable/token/ERC20/IERC20Upgradeable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.6.0) (token/ERC20/IERC20.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Interface of the ERC20 standard as defined in the EIP.\\n */\\ninterface IERC20Upgradeable {\\n /**\\n * @dev Emitted when `value` tokens are moved from one account (`from`) to\\n * another (`to`).\\n *\\n * Note that `value` may be zero.\\n */\\n event Transfer(address indexed from, address indexed to, uint256 value);\\n\\n /**\\n * @dev Emitted when the allowance of a `spender` for an `owner` is set by\\n * a call to {approve}. `value` is the new allowance.\\n */\\n event Approval(address indexed owner, address indexed spender, uint256 value);\\n\\n /**\\n * @dev Returns the amount of tokens in existence.\\n */\\n function totalSupply() external view returns (uint256);\\n\\n /**\\n * @dev Returns the amount of tokens owned by `account`.\\n */\\n function balanceOf(address account) external view returns (uint256);\\n\\n /**\\n * @dev Moves `amount` tokens from the caller's account to `to`.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * Emits a {Transfer} event.\\n */\\n function transfer(address to, uint256 amount) external returns (bool);\\n\\n /**\\n * @dev Returns the remaining number of tokens that `spender` will be\\n * allowed to spend on behalf of `owner` through {transferFrom}. This is\\n * zero by default.\\n *\\n * This value changes when {approve} or {transferFrom} are called.\\n */\\n function allowance(address owner, address spender) external view returns (uint256);\\n\\n /**\\n * @dev Sets `amount` as the allowance of `spender` over the caller's tokens.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * IMPORTANT: Beware that changing an allowance with this method brings the risk\\n * that someone may use both the old and the new allowance by unfortunate\\n * transaction ordering. One possible solution to mitigate this race\\n * condition is to first reduce the spender's allowance to 0 and set the\\n * desired value afterwards:\\n * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729\\n *\\n * Emits an {Approval} event.\\n */\\n function approve(address spender, uint256 amount) external returns (bool);\\n\\n /**\\n * @dev Moves `amount` tokens from `from` to `to` using the\\n * allowance mechanism. `amount` is then deducted from the caller's\\n * allowance.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * Emits a {Transfer} event.\\n */\\n function transferFrom(\\n address from,\\n address to,\\n uint256 amount\\n ) external returns (bool);\\n}\\n\",\"keccak256\":\"0x4e733d3164f73f461eaf9d8087a7ad1ea180bdc8ba0d3d61b0e1ae16d8e63dff\",\"license\":\"MIT\"},\"@openzeppelin/contracts-upgradeable/token/ERC20/extensions/IERC20MetadataUpgradeable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (token/ERC20/extensions/IERC20Metadata.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../IERC20Upgradeable.sol\\\";\\n\\n/**\\n * @dev Interface for the optional metadata functions from the ERC20 standard.\\n *\\n * _Available since v4.1._\\n */\\ninterface IERC20MetadataUpgradeable is IERC20Upgradeable {\\n /**\\n * @dev Returns the name of the token.\\n */\\n function name() external view returns (string memory);\\n\\n /**\\n * @dev Returns the symbol of the token.\\n */\\n function symbol() external view returns (string memory);\\n\\n /**\\n * @dev Returns the decimals places of the token.\\n */\\n function decimals() external view returns (uint8);\\n}\\n\",\"keccak256\":\"0x605434219ebbe4653f703640f06969faa5a1d78f0bfef878e5ddbb1ca369ceeb\",\"license\":\"MIT\"},\"@openzeppelin/contracts-upgradeable/token/ERC20/extensions/draft-ERC20PermitUpgradeable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.6.0) (token/ERC20/extensions/draft-ERC20Permit.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"./draft-IERC20PermitUpgradeable.sol\\\";\\nimport \\\"../ERC20Upgradeable.sol\\\";\\nimport \\\"../../../utils/cryptography/draft-EIP712Upgradeable.sol\\\";\\nimport \\\"../../../utils/cryptography/ECDSAUpgradeable.sol\\\";\\nimport \\\"../../../utils/CountersUpgradeable.sol\\\";\\nimport \\\"../../../proxy/utils/Initializable.sol\\\";\\n\\n/**\\n * @dev Implementation of the ERC20 Permit extension allowing approvals to be made via signatures, as defined in\\n * https://eips.ethereum.org/EIPS/eip-2612[EIP-2612].\\n *\\n * Adds the {permit} method, which can be used to change an account's ERC20 allowance (see {IERC20-allowance}) by\\n * presenting a message signed by the account. By not relying on `{IERC20-approve}`, the token holder account doesn't\\n * need to send a transaction, and thus is not required to hold Ether at all.\\n *\\n * _Available since v3.4._\\n *\\n * @custom:storage-size 51\\n */\\nabstract contract ERC20PermitUpgradeable is Initializable, ERC20Upgradeable, IERC20PermitUpgradeable, EIP712Upgradeable {\\n using CountersUpgradeable for CountersUpgradeable.Counter;\\n\\n mapping(address => CountersUpgradeable.Counter) private _nonces;\\n\\n // solhint-disable-next-line var-name-mixedcase\\n bytes32 private constant _PERMIT_TYPEHASH =\\n keccak256(\\\"Permit(address owner,address spender,uint256 value,uint256 nonce,uint256 deadline)\\\");\\n /**\\n * @dev In previous versions `_PERMIT_TYPEHASH` was declared as `immutable`.\\n * However, to ensure consistency with the upgradeable transpiler, we will continue\\n * to reserve a slot.\\n * @custom:oz-renamed-from _PERMIT_TYPEHASH\\n */\\n // solhint-disable-next-line var-name-mixedcase\\n bytes32 private _PERMIT_TYPEHASH_DEPRECATED_SLOT;\\n\\n /**\\n * @dev Initializes the {EIP712} domain separator using the `name` parameter, and setting `version` to `\\\"1\\\"`.\\n *\\n * It's a good idea to use the same `name` that is defined as the ERC20 token name.\\n */\\n function __ERC20Permit_init(string memory name) internal onlyInitializing {\\n __EIP712_init_unchained(name, \\\"1\\\");\\n }\\n\\n function __ERC20Permit_init_unchained(string memory) internal onlyInitializing {}\\n\\n /**\\n * @dev See {IERC20Permit-permit}.\\n */\\n function permit(\\n address owner,\\n address spender,\\n uint256 value,\\n uint256 deadline,\\n uint8 v,\\n bytes32 r,\\n bytes32 s\\n ) public virtual override {\\n require(block.timestamp <= deadline, \\\"ERC20Permit: expired deadline\\\");\\n\\n bytes32 structHash = keccak256(abi.encode(_PERMIT_TYPEHASH, owner, spender, value, _useNonce(owner), deadline));\\n\\n bytes32 hash = _hashTypedDataV4(structHash);\\n\\n address signer = ECDSAUpgradeable.recover(hash, v, r, s);\\n require(signer == owner, \\\"ERC20Permit: invalid signature\\\");\\n\\n _approve(owner, spender, value);\\n }\\n\\n /**\\n * @dev See {IERC20Permit-nonces}.\\n */\\n function nonces(address owner) public view virtual override returns (uint256) {\\n return _nonces[owner].current();\\n }\\n\\n /**\\n * @dev See {IERC20Permit-DOMAIN_SEPARATOR}.\\n */\\n // solhint-disable-next-line func-name-mixedcase\\n function DOMAIN_SEPARATOR() external view override returns (bytes32) {\\n return _domainSeparatorV4();\\n }\\n\\n /**\\n * @dev \\\"Consume a nonce\\\": return the current value and increment.\\n *\\n * _Available since v4.1._\\n */\\n function _useNonce(address owner) internal virtual returns (uint256 current) {\\n CountersUpgradeable.Counter storage nonce = _nonces[owner];\\n current = nonce.current();\\n nonce.increment();\\n }\\n\\n /**\\n * @dev This empty reserved space is put in place to allow future versions to add new\\n * variables without shifting down storage in the inheritance chain.\\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\\n */\\n uint256[49] private __gap;\\n}\\n\",\"keccak256\":\"0x564385ebed633694decce3e13d687f3ac7e8eaef64f7a504bfb3f03ad210601f\",\"license\":\"MIT\"},\"@openzeppelin/contracts-upgradeable/token/ERC20/extensions/draft-IERC20PermitUpgradeable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (token/ERC20/extensions/draft-IERC20Permit.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Interface of the ERC20 Permit extension allowing approvals to be made via signatures, as defined in\\n * https://eips.ethereum.org/EIPS/eip-2612[EIP-2612].\\n *\\n * Adds the {permit} method, which can be used to change an account's ERC20 allowance (see {IERC20-allowance}) by\\n * presenting a message signed by the account. By not relying on {IERC20-approve}, the token holder account doesn't\\n * need to send a transaction, and thus is not required to hold Ether at all.\\n */\\ninterface IERC20PermitUpgradeable {\\n /**\\n * @dev Sets `value` as the allowance of `spender` over ``owner``'s tokens,\\n * given ``owner``'s signed approval.\\n *\\n * IMPORTANT: The same issues {IERC20-approve} has related to transaction\\n * ordering also apply here.\\n *\\n * Emits an {Approval} event.\\n *\\n * Requirements:\\n *\\n * - `spender` cannot be the zero address.\\n * - `deadline` must be a timestamp in the future.\\n * - `v`, `r` and `s` must be a valid `secp256k1` signature from `owner`\\n * over the EIP712-formatted function arguments.\\n * - the signature must use ``owner``'s current nonce (see {nonces}).\\n *\\n * For more information on the signature format, see the\\n * https://eips.ethereum.org/EIPS/eip-2612#specification[relevant EIP\\n * section].\\n */\\n function permit(\\n address owner,\\n address spender,\\n uint256 value,\\n uint256 deadline,\\n uint8 v,\\n bytes32 r,\\n bytes32 s\\n ) external;\\n\\n /**\\n * @dev Returns the current nonce for `owner`. This value must be\\n * included whenever a signature is generated for {permit}.\\n *\\n * Every successful call to {permit} increases ``owner``'s nonce by one. This\\n * prevents a signature from being used multiple times.\\n */\\n function nonces(address owner) external view returns (uint256);\\n\\n /**\\n * @dev Returns the domain separator used in the encoding of the signature for {permit}, as defined by {EIP712}.\\n */\\n // solhint-disable-next-line func-name-mixedcase\\n function DOMAIN_SEPARATOR() external view returns (bytes32);\\n}\\n\",\"keccak256\":\"0xcc70d8e2281fb3ff69e8ab242500f10142cd0a7fa8dd9e45882be270d4d09024\",\"license\":\"MIT\"},\"@openzeppelin/contracts-upgradeable/utils/AddressUpgradeable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.7.0) (utils/Address.sol)\\n\\npragma solidity ^0.8.1;\\n\\n/**\\n * @dev Collection of functions related to the address type\\n */\\nlibrary AddressUpgradeable {\\n /**\\n * @dev Returns true if `account` is a contract.\\n *\\n * [IMPORTANT]\\n * ====\\n * It is unsafe to assume that an address for which this function returns\\n * false is an externally-owned account (EOA) and not a contract.\\n *\\n * Among others, `isContract` will return false for the following\\n * types of addresses:\\n *\\n * - an externally-owned account\\n * - a contract in construction\\n * - an address where a contract will be created\\n * - an address where a contract lived, but was destroyed\\n * ====\\n *\\n * [IMPORTANT]\\n * ====\\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\\n *\\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\\n * constructor.\\n * ====\\n */\\n function isContract(address account) internal view returns (bool) {\\n // This method relies on extcodesize/address.code.length, which returns 0\\n // for contracts in construction, since the code is only stored at the end\\n // of the constructor execution.\\n\\n return account.code.length > 0;\\n }\\n\\n /**\\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\\n * `recipient`, forwarding all available gas and reverting on errors.\\n *\\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\\n * imposed by `transfer`, making them unable to receive funds via\\n * `transfer`. {sendValue} removes this limitation.\\n *\\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\\n *\\n * IMPORTANT: because control is transferred to `recipient`, care must be\\n * taken to not create reentrancy vulnerabilities. Consider using\\n * {ReentrancyGuard} or the\\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\\n */\\n function sendValue(address payable recipient, uint256 amount) internal {\\n require(address(this).balance >= amount, \\\"Address: insufficient balance\\\");\\n\\n (bool success, ) = recipient.call{value: amount}(\\\"\\\");\\n require(success, \\\"Address: unable to send value, recipient may have reverted\\\");\\n }\\n\\n /**\\n * @dev Performs a Solidity function call using a low level `call`. A\\n * plain `call` is an unsafe replacement for a function call: use this\\n * function instead.\\n *\\n * If `target` reverts with a revert reason, it is bubbled up by this\\n * function (like regular Solidity function calls).\\n *\\n * Returns the raw returned data. To convert to the expected return value,\\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\\n *\\n * Requirements:\\n *\\n * - `target` must be a contract.\\n * - calling `target` with `data` must not revert.\\n *\\n * _Available since v3.1._\\n */\\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\\n return functionCall(target, data, \\\"Address: low-level call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\\n * `errorMessage` as a fallback revert reason when `target` reverts.\\n *\\n * _Available since v3.1._\\n */\\n function functionCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n return functionCallWithValue(target, data, 0, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but also transferring `value` wei to `target`.\\n *\\n * Requirements:\\n *\\n * - the calling contract must have an ETH balance of at least `value`.\\n * - the called Solidity function must be `payable`.\\n *\\n * _Available since v3.1._\\n */\\n function functionCallWithValue(\\n address target,\\n bytes memory data,\\n uint256 value\\n ) internal returns (bytes memory) {\\n return functionCallWithValue(target, data, value, \\\"Address: low-level call with value failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\\n * with `errorMessage` as a fallback revert reason when `target` reverts.\\n *\\n * _Available since v3.1._\\n */\\n function functionCallWithValue(\\n address target,\\n bytes memory data,\\n uint256 value,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n require(address(this).balance >= value, \\\"Address: insufficient balance for call\\\");\\n require(isContract(target), \\\"Address: call to non-contract\\\");\\n\\n (bool success, bytes memory returndata) = target.call{value: value}(data);\\n return verifyCallResult(success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but performing a static call.\\n *\\n * _Available since v3.3._\\n */\\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\\n return functionStaticCall(target, data, \\\"Address: low-level static call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\\n * but performing a static call.\\n *\\n * _Available since v3.3._\\n */\\n function functionStaticCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal view returns (bytes memory) {\\n require(isContract(target), \\\"Address: static call to non-contract\\\");\\n\\n (bool success, bytes memory returndata) = target.staticcall(data);\\n return verifyCallResult(success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the\\n * revert reason using the provided one.\\n *\\n * _Available since v4.3._\\n */\\n function verifyCallResult(\\n bool success,\\n bytes memory returndata,\\n string memory errorMessage\\n ) internal pure returns (bytes memory) {\\n if (success) {\\n return returndata;\\n } else {\\n // Look for revert reason and bubble it up if present\\n if (returndata.length > 0) {\\n // The easiest way to bubble the revert reason is using memory via assembly\\n /// @solidity memory-safe-assembly\\n assembly {\\n let returndata_size := mload(returndata)\\n revert(add(32, returndata), returndata_size)\\n }\\n } else {\\n revert(errorMessage);\\n }\\n }\\n }\\n}\\n\",\"keccak256\":\"0x611aa3f23e59cfdd1863c536776407b3e33d695152a266fa7cfb34440a29a8a3\",\"license\":\"MIT\"},\"@openzeppelin/contracts-upgradeable/utils/ContextUpgradeable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)\\n\\npragma solidity ^0.8.0;\\nimport \\\"../proxy/utils/Initializable.sol\\\";\\n\\n/**\\n * @dev Provides information about the current execution context, including the\\n * sender of the transaction and its data. While these are generally available\\n * via msg.sender and msg.data, they should not be accessed in such a direct\\n * manner, since when dealing with meta-transactions the account sending and\\n * paying for execution may not be the actual sender (as far as an application\\n * is concerned).\\n *\\n * This contract is only required for intermediate, library-like contracts.\\n */\\nabstract contract ContextUpgradeable is Initializable {\\n function __Context_init() internal onlyInitializing {\\n }\\n\\n function __Context_init_unchained() internal onlyInitializing {\\n }\\n function _msgSender() internal view virtual returns (address) {\\n return msg.sender;\\n }\\n\\n function _msgData() internal view virtual returns (bytes calldata) {\\n return msg.data;\\n }\\n\\n /**\\n * @dev This empty reserved space is put in place to allow future versions to add new\\n * variables without shifting down storage in the inheritance chain.\\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\\n */\\n uint256[50] private __gap;\\n}\\n\",\"keccak256\":\"0x963ea7f0b48b032eef72fe3a7582edf78408d6f834115b9feadd673a4d5bd149\",\"license\":\"MIT\"},\"@openzeppelin/contracts-upgradeable/utils/CountersUpgradeable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (utils/Counters.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @title Counters\\n * @author Matt Condon (@shrugs)\\n * @dev Provides counters that can only be incremented, decremented or reset. This can be used e.g. to track the number\\n * of elements in a mapping, issuing ERC721 ids, or counting request ids.\\n *\\n * Include with `using Counters for Counters.Counter;`\\n */\\nlibrary CountersUpgradeable {\\n struct Counter {\\n // This variable should never be directly accessed by users of the library: interactions must be restricted to\\n // the library's function. As of Solidity v0.5.2, this cannot be enforced, though there is a proposal to add\\n // this feature: see https://github.com/ethereum/solidity/issues/4637\\n uint256 _value; // default: 0\\n }\\n\\n function current(Counter storage counter) internal view returns (uint256) {\\n return counter._value;\\n }\\n\\n function increment(Counter storage counter) internal {\\n unchecked {\\n counter._value += 1;\\n }\\n }\\n\\n function decrement(Counter storage counter) internal {\\n uint256 value = counter._value;\\n require(value > 0, \\\"Counter: decrement overflow\\\");\\n unchecked {\\n counter._value = value - 1;\\n }\\n }\\n\\n function reset(Counter storage counter) internal {\\n counter._value = 0;\\n }\\n}\\n\",\"keccak256\":\"0x798741e231b22b81e2dd2eddaaf8832dee4baf5cd8e2dbaa5c1dd12a1c053c4d\",\"license\":\"MIT\"},\"@openzeppelin/contracts-upgradeable/utils/StringsUpgradeable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.7.0) (utils/Strings.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev String operations.\\n */\\nlibrary StringsUpgradeable {\\n bytes16 private constant _HEX_SYMBOLS = \\\"0123456789abcdef\\\";\\n uint8 private constant _ADDRESS_LENGTH = 20;\\n\\n /**\\n * @dev Converts a `uint256` to its ASCII `string` decimal representation.\\n */\\n function toString(uint256 value) internal pure returns (string memory) {\\n // Inspired by OraclizeAPI's implementation - MIT licence\\n // https://github.com/oraclize/ethereum-api/blob/b42146b063c7d6ee1358846c198246239e9360e8/oraclizeAPI_0.4.25.sol\\n\\n if (value == 0) {\\n return \\\"0\\\";\\n }\\n uint256 temp = value;\\n uint256 digits;\\n while (temp != 0) {\\n digits++;\\n temp /= 10;\\n }\\n bytes memory buffer = new bytes(digits);\\n while (value != 0) {\\n digits -= 1;\\n buffer[digits] = bytes1(uint8(48 + uint256(value % 10)));\\n value /= 10;\\n }\\n return string(buffer);\\n }\\n\\n /**\\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation.\\n */\\n function toHexString(uint256 value) internal pure returns (string memory) {\\n if (value == 0) {\\n return \\\"0x00\\\";\\n }\\n uint256 temp = value;\\n uint256 length = 0;\\n while (temp != 0) {\\n length++;\\n temp >>= 8;\\n }\\n return toHexString(value, length);\\n }\\n\\n /**\\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length.\\n */\\n function toHexString(uint256 value, uint256 length) internal pure returns (string memory) {\\n bytes memory buffer = new bytes(2 * length + 2);\\n buffer[0] = \\\"0\\\";\\n buffer[1] = \\\"x\\\";\\n for (uint256 i = 2 * length + 1; i > 1; --i) {\\n buffer[i] = _HEX_SYMBOLS[value & 0xf];\\n value >>= 4;\\n }\\n require(value == 0, \\\"Strings: hex length insufficient\\\");\\n return string(buffer);\\n }\\n\\n /**\\n * @dev Converts an `address` with fixed length of 20 bytes to its not checksummed ASCII `string` hexadecimal representation.\\n */\\n function toHexString(address addr) internal pure returns (string memory) {\\n return toHexString(uint256(uint160(addr)), _ADDRESS_LENGTH);\\n }\\n}\\n\",\"keccak256\":\"0xea5339a7fff0ed42b45be56a88efdd0b2ddde9fa480dc99fef9a6a4c5b776863\",\"license\":\"MIT\"},\"@openzeppelin/contracts-upgradeable/utils/cryptography/ECDSAUpgradeable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.7.0) (utils/cryptography/ECDSA.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../StringsUpgradeable.sol\\\";\\n\\n/**\\n * @dev Elliptic Curve Digital Signature Algorithm (ECDSA) operations.\\n *\\n * These functions can be used to verify that a message was signed by the holder\\n * of the private keys of a given address.\\n */\\nlibrary ECDSAUpgradeable {\\n enum RecoverError {\\n NoError,\\n InvalidSignature,\\n InvalidSignatureLength,\\n InvalidSignatureS,\\n InvalidSignatureV\\n }\\n\\n function _throwError(RecoverError error) private pure {\\n if (error == RecoverError.NoError) {\\n return; // no error: do nothing\\n } else if (error == RecoverError.InvalidSignature) {\\n revert(\\\"ECDSA: invalid signature\\\");\\n } else if (error == RecoverError.InvalidSignatureLength) {\\n revert(\\\"ECDSA: invalid signature length\\\");\\n } else if (error == RecoverError.InvalidSignatureS) {\\n revert(\\\"ECDSA: invalid signature 's' value\\\");\\n } else if (error == RecoverError.InvalidSignatureV) {\\n revert(\\\"ECDSA: invalid signature 'v' value\\\");\\n }\\n }\\n\\n /**\\n * @dev Returns the address that signed a hashed message (`hash`) with\\n * `signature` or error string. This address can then be used for verification purposes.\\n *\\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\\n * this function rejects them by requiring the `s` value to be in the lower\\n * half order, and the `v` value to be either 27 or 28.\\n *\\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\\n * verification to be secure: it is possible to craft signatures that\\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\\n * this is by receiving a hash of the original message (which may otherwise\\n * be too long), and then calling {toEthSignedMessageHash} on it.\\n *\\n * Documentation for signature generation:\\n * - with https://web3js.readthedocs.io/en/v1.3.4/web3-eth-accounts.html#sign[Web3.js]\\n * - with https://docs.ethers.io/v5/api/signer/#Signer-signMessage[ethers]\\n *\\n * _Available since v4.3._\\n */\\n function tryRecover(bytes32 hash, bytes memory signature) internal pure returns (address, RecoverError) {\\n // Check the signature length\\n // - case 65: r,s,v signature (standard)\\n // - case 64: r,vs signature (cf https://eips.ethereum.org/EIPS/eip-2098) _Available since v4.1._\\n if (signature.length == 65) {\\n bytes32 r;\\n bytes32 s;\\n uint8 v;\\n // ecrecover takes the signature parameters, and the only way to get them\\n // currently is to use assembly.\\n /// @solidity memory-safe-assembly\\n assembly {\\n r := mload(add(signature, 0x20))\\n s := mload(add(signature, 0x40))\\n v := byte(0, mload(add(signature, 0x60)))\\n }\\n return tryRecover(hash, v, r, s);\\n } else if (signature.length == 64) {\\n bytes32 r;\\n bytes32 vs;\\n // ecrecover takes the signature parameters, and the only way to get them\\n // currently is to use assembly.\\n /// @solidity memory-safe-assembly\\n assembly {\\n r := mload(add(signature, 0x20))\\n vs := mload(add(signature, 0x40))\\n }\\n return tryRecover(hash, r, vs);\\n } else {\\n return (address(0), RecoverError.InvalidSignatureLength);\\n }\\n }\\n\\n /**\\n * @dev Returns the address that signed a hashed message (`hash`) with\\n * `signature`. This address can then be used for verification purposes.\\n *\\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\\n * this function rejects them by requiring the `s` value to be in the lower\\n * half order, and the `v` value to be either 27 or 28.\\n *\\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\\n * verification to be secure: it is possible to craft signatures that\\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\\n * this is by receiving a hash of the original message (which may otherwise\\n * be too long), and then calling {toEthSignedMessageHash} on it.\\n */\\n function recover(bytes32 hash, bytes memory signature) internal pure returns (address) {\\n (address recovered, RecoverError error) = tryRecover(hash, signature);\\n _throwError(error);\\n return recovered;\\n }\\n\\n /**\\n * @dev Overload of {ECDSA-tryRecover} that receives the `r` and `vs` short-signature fields separately.\\n *\\n * See https://eips.ethereum.org/EIPS/eip-2098[EIP-2098 short signatures]\\n *\\n * _Available since v4.3._\\n */\\n function tryRecover(\\n bytes32 hash,\\n bytes32 r,\\n bytes32 vs\\n ) internal pure returns (address, RecoverError) {\\n bytes32 s = vs & bytes32(0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff);\\n uint8 v = uint8((uint256(vs) >> 255) + 27);\\n return tryRecover(hash, v, r, s);\\n }\\n\\n /**\\n * @dev Overload of {ECDSA-recover} that receives the `r and `vs` short-signature fields separately.\\n *\\n * _Available since v4.2._\\n */\\n function recover(\\n bytes32 hash,\\n bytes32 r,\\n bytes32 vs\\n ) internal pure returns (address) {\\n (address recovered, RecoverError error) = tryRecover(hash, r, vs);\\n _throwError(error);\\n return recovered;\\n }\\n\\n /**\\n * @dev Overload of {ECDSA-tryRecover} that receives the `v`,\\n * `r` and `s` signature fields separately.\\n *\\n * _Available since v4.3._\\n */\\n function tryRecover(\\n bytes32 hash,\\n uint8 v,\\n bytes32 r,\\n bytes32 s\\n ) internal pure returns (address, RecoverError) {\\n // EIP-2 still allows signature malleability for ecrecover(). Remove this possibility and make the signature\\n // unique. Appendix F in the Ethereum Yellow paper (https://ethereum.github.io/yellowpaper/paper.pdf), defines\\n // the valid range for s in (301): 0 < s < secp256k1n \\u00f7 2 + 1, and for v in (302): v \\u2208 {27, 28}. Most\\n // signatures from current libraries generate a unique signature with an s-value in the lower half order.\\n //\\n // If your library generates malleable signatures, such as s-values in the upper range, calculate a new s-value\\n // with 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141 - s1 and flip v from 27 to 28 or\\n // vice versa. If your library also generates signatures with 0/1 for v instead 27/28, add 27 to v to accept\\n // these malleable signatures as well.\\n if (uint256(s) > 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D576E7357A4501DDFE92F46681B20A0) {\\n return (address(0), RecoverError.InvalidSignatureS);\\n }\\n if (v != 27 && v != 28) {\\n return (address(0), RecoverError.InvalidSignatureV);\\n }\\n\\n // If the signature is valid (and not malleable), return the signer address\\n address signer = ecrecover(hash, v, r, s);\\n if (signer == address(0)) {\\n return (address(0), RecoverError.InvalidSignature);\\n }\\n\\n return (signer, RecoverError.NoError);\\n }\\n\\n /**\\n * @dev Overload of {ECDSA-recover} that receives the `v`,\\n * `r` and `s` signature fields separately.\\n */\\n function recover(\\n bytes32 hash,\\n uint8 v,\\n bytes32 r,\\n bytes32 s\\n ) internal pure returns (address) {\\n (address recovered, RecoverError error) = tryRecover(hash, v, r, s);\\n _throwError(error);\\n return recovered;\\n }\\n\\n /**\\n * @dev Returns an Ethereum Signed Message, created from a `hash`. This\\n * produces hash corresponding to the one signed with the\\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\\n * JSON-RPC method as part of EIP-191.\\n *\\n * See {recover}.\\n */\\n function toEthSignedMessageHash(bytes32 hash) internal pure returns (bytes32) {\\n // 32 is the length in bytes of hash,\\n // enforced by the type signature above\\n return keccak256(abi.encodePacked(\\\"\\\\x19Ethereum Signed Message:\\\\n32\\\", hash));\\n }\\n\\n /**\\n * @dev Returns an Ethereum Signed Message, created from `s`. This\\n * produces hash corresponding to the one signed with the\\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\\n * JSON-RPC method as part of EIP-191.\\n *\\n * See {recover}.\\n */\\n function toEthSignedMessageHash(bytes memory s) internal pure returns (bytes32) {\\n return keccak256(abi.encodePacked(\\\"\\\\x19Ethereum Signed Message:\\\\n\\\", StringsUpgradeable.toString(s.length), s));\\n }\\n\\n /**\\n * @dev Returns an Ethereum Signed Typed Data, created from a\\n * `domainSeparator` and a `structHash`. This produces hash corresponding\\n * to the one signed with the\\n * https://eips.ethereum.org/EIPS/eip-712[`eth_signTypedData`]\\n * JSON-RPC method as part of EIP-712.\\n *\\n * See {recover}.\\n */\\n function toTypedDataHash(bytes32 domainSeparator, bytes32 structHash) internal pure returns (bytes32) {\\n return keccak256(abi.encodePacked(\\\"\\\\x19\\\\x01\\\", domainSeparator, structHash));\\n }\\n}\\n\",\"keccak256\":\"0xe8c62ca00ed2d0a4d9b7e3c4bf7d62c821618b2cdb3c844da91a1193986851bf\",\"license\":\"MIT\"},\"@openzeppelin/contracts-upgradeable/utils/cryptography/draft-EIP712Upgradeable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (utils/cryptography/draft-EIP712.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"./ECDSAUpgradeable.sol\\\";\\nimport \\\"../../proxy/utils/Initializable.sol\\\";\\n\\n/**\\n * @dev https://eips.ethereum.org/EIPS/eip-712[EIP 712] is a standard for hashing and signing of typed structured data.\\n *\\n * The encoding specified in the EIP is very generic, and such a generic implementation in Solidity is not feasible,\\n * thus this contract does not implement the encoding itself. Protocols need to implement the type-specific encoding\\n * they need in their contracts using a combination of `abi.encode` and `keccak256`.\\n *\\n * This contract implements the EIP 712 domain separator ({_domainSeparatorV4}) that is used as part of the encoding\\n * scheme, and the final step of the encoding to obtain the message digest that is then signed via ECDSA\\n * ({_hashTypedDataV4}).\\n *\\n * The implementation of the domain separator was designed to be as efficient as possible while still properly updating\\n * the chain id to protect against replay attacks on an eventual fork of the chain.\\n *\\n * NOTE: This contract implements the version of the encoding known as \\\"v4\\\", as implemented by the JSON RPC method\\n * https://docs.metamask.io/guide/signing-data.html[`eth_signTypedDataV4` in MetaMask].\\n *\\n * _Available since v3.4._\\n *\\n * @custom:storage-size 52\\n */\\nabstract contract EIP712Upgradeable is Initializable {\\n /* solhint-disable var-name-mixedcase */\\n bytes32 private _HASHED_NAME;\\n bytes32 private _HASHED_VERSION;\\n bytes32 private constant _TYPE_HASH = keccak256(\\\"EIP712Domain(string name,string version,uint256 chainId,address verifyingContract)\\\");\\n\\n /* solhint-enable var-name-mixedcase */\\n\\n /**\\n * @dev Initializes the domain separator and parameter caches.\\n *\\n * The meaning of `name` and `version` is specified in\\n * https://eips.ethereum.org/EIPS/eip-712#definition-of-domainseparator[EIP 712]:\\n *\\n * - `name`: the user readable name of the signing domain, i.e. the name of the DApp or the protocol.\\n * - `version`: the current major version of the signing domain.\\n *\\n * NOTE: These parameters cannot be changed except through a xref:learn::upgrading-smart-contracts.adoc[smart\\n * contract upgrade].\\n */\\n function __EIP712_init(string memory name, string memory version) internal onlyInitializing {\\n __EIP712_init_unchained(name, version);\\n }\\n\\n function __EIP712_init_unchained(string memory name, string memory version) internal onlyInitializing {\\n bytes32 hashedName = keccak256(bytes(name));\\n bytes32 hashedVersion = keccak256(bytes(version));\\n _HASHED_NAME = hashedName;\\n _HASHED_VERSION = hashedVersion;\\n }\\n\\n /**\\n * @dev Returns the domain separator for the current chain.\\n */\\n function _domainSeparatorV4() internal view returns (bytes32) {\\n return _buildDomainSeparator(_TYPE_HASH, _EIP712NameHash(), _EIP712VersionHash());\\n }\\n\\n function _buildDomainSeparator(\\n bytes32 typeHash,\\n bytes32 nameHash,\\n bytes32 versionHash\\n ) private view returns (bytes32) {\\n return keccak256(abi.encode(typeHash, nameHash, versionHash, block.chainid, address(this)));\\n }\\n\\n /**\\n * @dev Given an already https://eips.ethereum.org/EIPS/eip-712#definition-of-hashstruct[hashed struct], this\\n * function returns the hash of the fully encoded EIP712 message for this domain.\\n *\\n * This hash can be used together with {ECDSA-recover} to obtain the signer of a message. For example:\\n *\\n * ```solidity\\n * bytes32 digest = _hashTypedDataV4(keccak256(abi.encode(\\n * keccak256(\\\"Mail(address to,string contents)\\\"),\\n * mailTo,\\n * keccak256(bytes(mailContents))\\n * )));\\n * address signer = ECDSA.recover(digest, signature);\\n * ```\\n */\\n function _hashTypedDataV4(bytes32 structHash) internal view virtual returns (bytes32) {\\n return ECDSAUpgradeable.toTypedDataHash(_domainSeparatorV4(), structHash);\\n }\\n\\n /**\\n * @dev The hash of the name parameter for the EIP712 domain.\\n *\\n * NOTE: This function reads from storage by default, but can be redefined to return a constant value if gas costs\\n * are a concern.\\n */\\n function _EIP712NameHash() internal virtual view returns (bytes32) {\\n return _HASHED_NAME;\\n }\\n\\n /**\\n * @dev The hash of the version parameter for the EIP712 domain.\\n *\\n * NOTE: This function reads from storage by default, but can be redefined to return a constant value if gas costs\\n * are a concern.\\n */\\n function _EIP712VersionHash() internal virtual view returns (bytes32) {\\n return _HASHED_VERSION;\\n }\\n\\n /**\\n * @dev This empty reserved space is put in place to allow future versions to add new\\n * variables without shifting down storage in the inheritance chain.\\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\\n */\\n uint256[50] private __gap;\\n}\\n\",\"keccak256\":\"0xaf5a96100f421d61693605349511e43221d3c2e47d4b3efa87af2b936e2567fc\",\"license\":\"MIT\"},\"contracts/agToken/AgToken.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-3.0\\n\\npragma solidity ^0.8.12;\\n\\n/*\\n * \\u2588 \\n ***** \\u2593\\u2593\\u2593 \\n * \\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593 \\n * ///. \\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593 \\n ***** //////// \\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593 \\n * ///////////// \\u2593\\u2593\\u2593 \\n \\u2593\\u2593 ////////////////// \\u2588 \\u2593\\u2593 \\n \\u2593\\u2593 \\u2593\\u2593 /////////////////////// \\u2593\\u2593 \\u2593\\u2593 \\n \\u2593\\u2593 \\u2593\\u2593 //////////////////////////// \\u2593\\u2593 \\u2593\\u2593 \\n \\u2593\\u2593 \\u2593\\u2593 /////////\\u2593\\u2593\\u2593///////\\u2593\\u2593\\u2593///////// \\u2593\\u2593 \\u2593\\u2593 \\n \\u2593\\u2593 ,////////////////////////////////////// \\u2593\\u2593 \\u2593\\u2593 \\n \\u2593\\u2593 ////////////////////////////////////////// \\u2593\\u2593 \\n \\u2593\\u2593 //////////////////////\\u2593\\u2593\\u2593\\u2593///////////////////// \\n ,//////////////////////////////////////////////////// \\n .////////////////////////////////////////////////////////// \\n .//////////////////////////\\u2588\\u2588.,//////////////////////////\\u2588 \\n .//////////////////////\\u2588\\u2588\\u2588\\u2588..,./////////////////////\\u2588\\u2588 \\n ...////////////////\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588.....,.////////////////\\u2588\\u2588\\u2588 \\n ,.,////////////\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588 ........,///////////\\u2588\\u2588\\u2588\\u2588 \\n .,.,//////\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588 ,.......///////\\u2588\\u2588\\u2588\\u2588 \\n ,..//\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588 ........./\\u2588\\u2588\\u2588\\u2588 \\n ..,\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588 .....,\\u2588\\u2588\\u2588 \\n .\\u2588\\u2588 ,.,\\u2588 \\n \\n \\n \\n \\u2593\\u2593 \\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593 \\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593 \\u2593\\u2593 \\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593 \\n \\u2593\\u2593\\u2593\\u2593\\u2593\\u2593 \\u2593\\u2593\\u2593 \\u2593\\u2593\\u2593 \\u2593\\u2593\\u2593 \\u2593\\u2593 \\u2593\\u2593 \\u2593\\u2593\\u2593\\u2593 \\n \\u2593\\u2593\\u2593 \\u2593\\u2593\\u2593 \\u2593\\u2593\\u2593 \\u2593\\u2593\\u2593 \\u2593\\u2593\\u2593 \\u2593\\u2593\\u2593 \\u2593\\u2593 \\u2593\\u2593\\u2593\\u2593\\u2593 \\n \\u2593\\u2593\\u2593 \\u2593\\u2593 \\u2593\\u2593\\u2593 \\u2593\\u2593\\u2593 \\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593 \\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593 \\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593 \\n*/\\n\\nimport \\\"../interfaces/IAgToken.sol\\\";\\nimport \\\"../interfaces/ITreasury.sol\\\";\\nimport \\\"@openzeppelin/contracts-upgradeable/token/ERC20/extensions/draft-ERC20PermitUpgradeable.sol\\\";\\n\\n/// @title AgToken\\n/// @author Angle Labs, Inc.\\n/// @notice Base contract for Angle agTokens on Ethereum and on other chains\\n/// @dev By default, agTokens are ERC-20 tokens with 18 decimals\\ncontract AgToken is IAgToken, ERC20PermitUpgradeable {\\n // =========================== PARAMETERS / VARIABLES ==========================\\n\\n /// @inheritdoc IAgToken\\n mapping(address => bool) public isMinter;\\n /// @notice Reference to the treasury contract which can grant minting rights\\n address public treasury;\\n\\n // =================================== EVENTS ==================================\\n\\n event TreasuryUpdated(address indexed _treasury);\\n event MinterToggled(address indexed minter);\\n\\n // =================================== ERRORS ==================================\\n\\n error BurnAmountExceedsAllowance();\\n error InvalidSender();\\n error InvalidTreasury();\\n error NotMinter();\\n error NotTreasury();\\n\\n // ================================ CONSTRUCTOR ================================\\n\\n /// @custom:oz-upgrades-unsafe-allow constructor\\n constructor() initializer {}\\n\\n /// @notice Initializes the `AgToken` contract\\n function initialize(string memory name_, string memory symbol_, address _treasury) external {\\n _initialize(name_, symbol_, _treasury);\\n }\\n\\n /// @notice Initializes the contract\\n function _initialize(string memory name_, string memory symbol_, address _treasury) internal virtual initializer {\\n if (address(ITreasury(_treasury).stablecoin()) != address(this)) revert InvalidTreasury();\\n __ERC20Permit_init(name_);\\n __ERC20_init(name_, symbol_);\\n treasury = _treasury;\\n emit TreasuryUpdated(_treasury);\\n }\\n\\n // ================================= MODIFIERS =================================\\n\\n /// @notice Checks to see if it is the `Treasury` calling this contract\\n modifier onlyTreasury() {\\n if (msg.sender != treasury) revert NotTreasury();\\n _;\\n }\\n\\n /// @notice Checks whether the sender has the minting right\\n modifier onlyMinter() {\\n if (!isMinter[msg.sender]) revert NotMinter();\\n _;\\n }\\n\\n // ============================= EXTERNAL FUNCTION =============================\\n\\n /// @notice Allows anyone to burn stablecoins\\n /// @param amount Amount of stablecoins to burn\\n /// @dev This function can typically be called if there is a settlement mechanism to burn stablecoins\\n function burnStablecoin(uint256 amount) external {\\n _burn(msg.sender, amount);\\n }\\n\\n // ========================= MINTER ROLE ONLY FUNCTIONS ========================\\n\\n /// @inheritdoc IAgToken\\n function burnSelf(uint256 amount, address burner) external onlyMinter {\\n _burn(burner, amount);\\n }\\n\\n /// @inheritdoc IAgToken\\n function burnFrom(uint256 amount, address burner, address sender) external onlyMinter {\\n if (burner != sender) {\\n uint256 currentAllowance = allowance(burner, sender);\\n if (currentAllowance < amount) revert BurnAmountExceedsAllowance();\\n _approve(burner, sender, currentAllowance - amount);\\n }\\n _burn(burner, amount);\\n }\\n\\n /// @inheritdoc IAgToken\\n function mint(address account, uint256 amount) external onlyMinter {\\n _mint(account, amount);\\n }\\n\\n // ========================== GOVERNANCE ONLY FUNCTIONS ==========================\\n\\n /// @inheritdoc IAgToken\\n function addMinter(address minter) external onlyTreasury {\\n isMinter[minter] = true;\\n emit MinterToggled(minter);\\n }\\n\\n /// @inheritdoc IAgToken\\n function removeMinter(address minter) external {\\n if (msg.sender != address(treasury) && msg.sender != minter) revert InvalidSender();\\n isMinter[minter] = false;\\n emit MinterToggled(minter);\\n }\\n\\n /// @inheritdoc IAgToken\\n function setTreasury(address _treasury) external virtual onlyTreasury {\\n treasury = _treasury;\\n emit TreasuryUpdated(_treasury);\\n }\\n}\\n\",\"keccak256\":\"0x671d54d7840179050e859cf09662fe0e2c34cfaf5ec3782148d6c29e77c54d17\",\"license\":\"GPL-3.0\"},\"contracts/interfaces/IAgToken.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-3.0\\n\\npragma solidity ^0.8.12;\\n\\nimport \\\"@openzeppelin/contracts-upgradeable/token/ERC20/IERC20Upgradeable.sol\\\";\\n\\n/// @title IAgToken\\n/// @author Angle Labs, Inc.\\n/// @notice Interface for the stablecoins `AgToken` contracts\\n/// @dev This interface only contains functions of the `AgToken` contract which are called by other contracts\\n/// of this module or of the first module of the Angle Protocol\\ninterface IAgToken is IERC20Upgradeable {\\n // ======================= Minter Role Only Functions ===========================\\n\\n /// @notice Lets the `StableMaster` contract or another whitelisted contract mint agTokens\\n /// @param account Address to mint to\\n /// @param amount Amount to mint\\n /// @dev The contracts allowed to issue agTokens are the `StableMaster` contract, `VaultManager` contracts\\n /// associated to this stablecoin as well as the flash loan module (if activated) and potentially contracts\\n /// whitelisted by governance\\n function mint(address account, uint256 amount) external;\\n\\n /// @notice Burns `amount` tokens from a `burner` address after being asked to by `sender`\\n /// @param amount Amount of tokens to burn\\n /// @param burner Address to burn from\\n /// @param sender Address which requested the burn from `burner`\\n /// @dev This method is to be called by a contract with the minter right after being requested\\n /// to do so by a `sender` address willing to burn tokens from another `burner` address\\n /// @dev The method checks the allowance between the `sender` and the `burner`\\n function burnFrom(uint256 amount, address burner, address sender) external;\\n\\n /// @notice Burns `amount` tokens from a `burner` address\\n /// @param amount Amount of tokens to burn\\n /// @param burner Address to burn from\\n /// @dev This method is to be called by a contract with a minter right on the AgToken after being\\n /// requested to do so by an address willing to burn tokens from its address\\n function burnSelf(uint256 amount, address burner) external;\\n\\n // ========================= Treasury Only Functions ===========================\\n\\n /// @notice Adds a minter in the contract\\n /// @param minter Minter address to add\\n /// @dev Zero address checks are performed directly in the `Treasury` contract\\n function addMinter(address minter) external;\\n\\n /// @notice Removes a minter from the contract\\n /// @param minter Minter address to remove\\n /// @dev This function can also be called by a minter wishing to revoke itself\\n function removeMinter(address minter) external;\\n\\n /// @notice Sets a new treasury contract\\n /// @param _treasury New treasury address\\n function setTreasury(address _treasury) external;\\n\\n // ========================= External functions ================================\\n\\n /// @notice Checks whether an address has the right to mint agTokens\\n /// @param minter Address for which the minting right should be checked\\n /// @return Whether the address has the right to mint agTokens or not\\n function isMinter(address minter) external view returns (bool);\\n\\n /// @notice Get the associated treasury\\n function treasury() external view returns (address);\\n}\\n\",\"keccak256\":\"0x0c83efcfc1fb9ae9ba830f7b89e3dab9abf6ad7a6205a31aa35fbccaa837dcdc\",\"license\":\"GPL-3.0\"},\"contracts/interfaces/ICoreBorrow.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-3.0\\n\\npragma solidity ^0.8.12;\\n\\n/// @title ICoreBorrow\\n/// @author Angle Labs, Inc.\\n/// @notice Interface for the `CoreBorrow` contract\\n/// @dev This interface only contains functions of the `CoreBorrow` contract which are called by other contracts\\n/// of this module\\ninterface ICoreBorrow {\\n /// @notice Checks if an address corresponds to a treasury of a stablecoin with a flash loan\\n /// module initialized on it\\n /// @param treasury Address to check\\n /// @return Whether the address has the `FLASHLOANER_TREASURY_ROLE` or not\\n function isFlashLoanerTreasury(address treasury) external view returns (bool);\\n\\n /// @notice Checks whether an address is governor of the Angle Protocol or not\\n /// @param admin Address to check\\n /// @return Whether the address has the `GOVERNOR_ROLE` or not\\n function isGovernor(address admin) external view returns (bool);\\n\\n /// @notice Checks whether an address is governor or a guardian of the Angle Protocol or not\\n /// @param admin Address to check\\n /// @return Whether the address has the `GUARDIAN_ROLE` or not\\n /// @dev Governance should make sure when adding a governor to also give this governor the guardian\\n /// role by calling the `addGovernor` function\\n function isGovernorOrGuardian(address admin) external view returns (bool);\\n}\\n\",\"keccak256\":\"0x10249210cbf522775f040baf981d7d037472168ce2746d87473ac7c29a34e62e\",\"license\":\"GPL-3.0\"},\"contracts/interfaces/IFlashAngle.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-3.0\\n\\npragma solidity ^0.8.12;\\n\\nimport \\\"./IAgToken.sol\\\";\\nimport \\\"./ICoreBorrow.sol\\\";\\n\\n/// @title IFlashAngle\\n/// @author Angle Labs, Inc.\\n/// @notice Interface for the `FlashAngle` contract\\n/// @dev This interface only contains functions of the contract which are called by other contracts\\n/// of this module\\ninterface IFlashAngle {\\n /// @notice Reference to the `CoreBorrow` contract managing the FlashLoan module\\n function core() external view returns (ICoreBorrow);\\n\\n /// @notice Sends the fees taken from flash loans to the treasury contract associated to the stablecoin\\n /// @param stablecoin Stablecoin from which profits should be sent\\n /// @return balance Amount of profits sent\\n /// @dev This function can only be called by the treasury contract\\n function accrueInterestToTreasury(IAgToken stablecoin) external returns (uint256 balance);\\n\\n /// @notice Adds support for a stablecoin\\n /// @param _treasury Treasury associated to the stablecoin to add support for\\n /// @dev This function can only be called by the `CoreBorrow` contract\\n function addStablecoinSupport(address _treasury) external;\\n\\n /// @notice Removes support for a stablecoin\\n /// @param _treasury Treasury associated to the stablecoin to remove support for\\n /// @dev This function can only be called by the `CoreBorrow` contract\\n function removeStablecoinSupport(address _treasury) external;\\n\\n /// @notice Sets a new core contract\\n /// @param _core Core contract address to set\\n /// @dev This function can only be called by the `CoreBorrow` contract\\n function setCore(address _core) external;\\n}\\n\",\"keccak256\":\"0x39b0097f695b9e934bccdc72676c91513f1077cc5d0fd151908fd25a7c5cfbe4\",\"license\":\"GPL-3.0\"},\"contracts/interfaces/ITreasury.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-3.0\\n\\npragma solidity ^0.8.12;\\n\\nimport \\\"./IAgToken.sol\\\";\\nimport \\\"./ICoreBorrow.sol\\\";\\nimport \\\"./IFlashAngle.sol\\\";\\n\\n/// @title ITreasury\\n/// @author Angle Labs, Inc.\\n/// @notice Interface for the `Treasury` contract\\n/// @dev This interface only contains functions of the `Treasury` which are called by other contracts\\n/// of this module\\ninterface ITreasury {\\n /// @notice Stablecoin handled by this `treasury` contract\\n function stablecoin() external view returns (IAgToken);\\n\\n /// @notice Checks whether a given address has the governor role\\n /// @param admin Address to check\\n /// @return Whether the address has the governor role\\n /// @dev Access control is only kept in the `CoreBorrow` contract\\n function isGovernor(address admin) external view returns (bool);\\n\\n /// @notice Checks whether a given address has the guardian or the governor role\\n /// @param admin Address to check\\n /// @return Whether the address has the guardian or the governor role\\n /// @dev Access control is only kept in the `CoreBorrow` contract which means that this function\\n /// queries the `CoreBorrow` contract\\n function isGovernorOrGuardian(address admin) external view returns (bool);\\n\\n /// @notice Checks whether a given address has well been initialized in this contract\\n /// as a `VaultManager`\\n /// @param _vaultManager Address to check\\n /// @return Whether the address has been initialized or not\\n function isVaultManager(address _vaultManager) external view returns (bool);\\n\\n /// @notice Sets a new flash loan module for this stablecoin\\n /// @param _flashLoanModule Reference to the new flash loan module\\n /// @dev This function removes the minting right to the old flash loan module and grants\\n /// it to the new module\\n function setFlashLoanModule(address _flashLoanModule) external;\\n\\n /// @notice Gets the vault manager list\\n function vaultManagerList(uint256 i) external returns (address);\\n}\\n\",\"keccak256\":\"0x06c2f781c08732ce1b5845c083af5742716245baa6c519bd737f32b230a884c1\",\"license\":\"GPL-3.0\"}},\"version\":1}", + "bytecode": "0x60806040523480156200001157600080fd5b50600054610100900460ff1615808015620000335750600054600160ff909116105b8062000063575062000050306200013d60201b62000c431760201c565b15801562000063575060005460ff166001145b620000cb5760405162461bcd60e51b815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201526d191e481a5b9a5d1a585b1a5e995960921b606482015260840160405180910390fd5b6000805460ff191660011790558015620000ef576000805461ff0019166101001790555b801562000136576000805461ff0019169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15b506200014c565b6001600160a01b03163b151590565b612529806200015c6000396000f3fe608060405234801561001057600080fd5b50600436106101985760003560e01c806361d027b3116100e3578063a457c2d71161008c578063d505accf11610066578063d505accf14610393578063dd62ed3e146103a6578063f0f44260146103ec57600080fd5b8063a457c2d71461034a578063a9059cbb1461035d578063aa271e1a1461037057600080fd5b806390218cff116100bd57806390218cff1461031c57806395d89b411461032f578063983b2d561461033757600080fd5b806361d027b31461028e57806370a08231146102d35780637ecebe001461030957600080fd5b80633092afd5116101455780633644e5151161011f5780633644e51514610260578063395093511461026857806340c10f191461027b57600080fd5b80633092afd51461022b578063313ce5671461023e578063350ebe041461024d57600080fd5b806318160ddd1161017657806318160ddd146101f357806323b872dd146102055780632b471d8e1461021857600080fd5b806306fdde031461019d578063077f224a146101bb578063095ea7b3146101d0575b600080fd5b6101a56103ff565b6040516101b29190611f07565b60405180910390f35b6101ce6101c936600461206f565b610491565b005b6101e36101de3660046120e7565b6104a1565b60405190151581526020016101b2565b6035545b6040519081526020016101b2565b6101e3610213366004612113565b6104bb565b6101ce610226366004612154565b6104df565b6101ce610239366004612184565b610536565b604051601281526020016101b2565b6101ce61025b3660046121a8565b61061f565b6101f7610728565b6101e36102763660046120e7565b610737565b6101ce6102893660046120e7565b61077e565b60cd546102ae9073ffffffffffffffffffffffffffffffffffffffff1681565b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020016101b2565b6101f76102e1366004612184565b73ffffffffffffffffffffffffffffffffffffffff1660009081526033602052604090205490565b6101f7610317366004612184565b6107d1565b6101ce61032a3660046121df565b6107fc565b6101a5610809565b6101ce610345366004612184565b610818565b6101e36103583660046120e7565b6108e0565b6101e361036b3660046120e7565b6109b6565b6101e361037e366004612184565b60cc6020526000908152604090205460ff1681565b6101ce6103a13660046121f8565b6109c4565b6101f76103b436600461226f565b73ffffffffffffffffffffffffffffffffffffffff918216600090815260346020908152604080832093909416825291909152205490565b6101ce6103fa366004612184565b610b83565b60606036805461040e9061229d565b80601f016020809104026020016040519081016040528092919081815260200182805461043a9061229d565b80156104875780601f1061045c57610100808354040283529160200191610487565b820191906000526020600020905b81548152906001019060200180831161046a57829003601f168201915b5050505050905090565b61049c838383610c5f565b505050565b6000336104af818585610f3e565b60019150505b92915050565b6000336104c98582856110f1565b6104d48585856111c2565b506001949350505050565b33600090815260cc602052604090205460ff16610528576040517ff8d2906c00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6105328183611475565b5050565b60cd5473ffffffffffffffffffffffffffffffffffffffff16331480159061057457503373ffffffffffffffffffffffffffffffffffffffff821614155b156105ab576040517fddb5de5e00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff8116600081815260cc602052604080822080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00169055517f98c15241d6c02bc5ee0b780e11b3ea737a2defd9d04877edbe9f9497065bd02f9190a250565b33600090815260cc602052604090205460ff16610668576040517ff8d2906c00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff161461071e5773ffffffffffffffffffffffffffffffffffffffff82811660009081526034602090815260408083209385168352929052205483811015610708576040517f715ec26c00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b61071c83836107178785612319565b610f3e565b505b61049c8284611475565b6000610732611662565b905090565b33600081815260346020908152604080832073ffffffffffffffffffffffffffffffffffffffff871684529091528120549091906104af908290869061071790879061232c565b33600090815260cc602052604090205460ff166107c7576040517ff8d2906c00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b61053282826116dd565b73ffffffffffffffffffffffffffffffffffffffff81166000908152609960205260408120546104b5565b6108063382611475565b50565b60606037805461040e9061229d565b60cd5473ffffffffffffffffffffffffffffffffffffffff163314610869576040517fb90cdbb100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff8116600081815260cc602052604080822080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00166001179055517f98c15241d6c02bc5ee0b780e11b3ea737a2defd9d04877edbe9f9497065bd02f9190a250565b33600081815260346020908152604080832073ffffffffffffffffffffffffffffffffffffffff87168452909152812054909190838110156109a9576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602560248201527f45524332303a2064656372656173656420616c6c6f77616e63652062656c6f7760448201527f207a65726f00000000000000000000000000000000000000000000000000000060648201526084015b60405180910390fd5b6104d48286868403610f3e565b6000336104af8185856111c2565b83421115610a2e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f45524332305065726d69743a206578706972656420646561646c696e6500000060448201526064016109a0565b60007f6e71edae12b1b97f4d1f60370fef10105fa2faae0126114a169c64845d6126c9888888610a5d8c6117fd565b60408051602081019690965273ffffffffffffffffffffffffffffffffffffffff94851690860152929091166060840152608083015260a082015260c0810186905260e0016040516020818303038152906040528051906020012090506000610ac582611832565b90506000610ad58287878761189b565b90508973ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614610b6c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601e60248201527f45524332305065726d69743a20696e76616c6964207369676e6174757265000060448201526064016109a0565b610b778a8a8a610f3e565b50505050505050505050565b60cd5473ffffffffffffffffffffffffffffffffffffffff163314610bd4576040517fb90cdbb100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60cd80547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83169081179091556040517f7dae230f18360d76a040c81f050aa14eb9d6dc7901b20fc5d855e2a20fe814d190600090a250565b73ffffffffffffffffffffffffffffffffffffffff163b151590565b600054610100900460ff1615808015610c7f5750600054600160ff909116105b80610c995750303b158015610c99575060005460ff166001145b610d25576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201527f647920696e697469616c697a656400000000000000000000000000000000000060648201526084016109a0565b600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001660011790558015610d8357600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff166101001790555b3073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1663e9cbd8226040518163ffffffff1660e01b8152600401602060405180830381865afa158015610de5573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610e09919061233f565b73ffffffffffffffffffffffffffffffffffffffff1614610e56576040517f14bcf5c800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b610e5f846118c3565b610e698484611999565b60cd80547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff84169081179091556040517f7dae230f18360d76a040c81f050aa14eb9d6dc7901b20fc5d855e2a20fe814d190600090a28015610f3857600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15b50505050565b73ffffffffffffffffffffffffffffffffffffffff8316610fe0576040517f08c379a0000000000000000000000000000000000000000000000000000000008152602060048201526024808201527f45524332303a20617070726f76652066726f6d20746865207a65726f2061646460448201527f726573730000000000000000000000000000000000000000000000000000000060648201526084016109a0565b73ffffffffffffffffffffffffffffffffffffffff8216611083576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602260248201527f45524332303a20617070726f766520746f20746865207a65726f20616464726560448201527f737300000000000000000000000000000000000000000000000000000000000060648201526084016109a0565b73ffffffffffffffffffffffffffffffffffffffff83811660008181526034602090815260408083209487168084529482529182902085905590518481527f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925910160405180910390a3505050565b73ffffffffffffffffffffffffffffffffffffffff8381166000908152603460209081526040808320938616835292905220547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8114610f3857818110156111b5576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f45524332303a20696e73756666696369656e7420616c6c6f77616e636500000060448201526064016109a0565b610f388484848403610f3e565b73ffffffffffffffffffffffffffffffffffffffff8316611265576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602560248201527f45524332303a207472616e736665722066726f6d20746865207a65726f20616460448201527f647265737300000000000000000000000000000000000000000000000000000060648201526084016109a0565b73ffffffffffffffffffffffffffffffffffffffff8216611308576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602360248201527f45524332303a207472616e7366657220746f20746865207a65726f206164647260448201527f657373000000000000000000000000000000000000000000000000000000000060648201526084016109a0565b73ffffffffffffffffffffffffffffffffffffffff8316600090815260336020526040902054818110156113be576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f45524332303a207472616e7366657220616d6f756e742065786365656473206260448201527f616c616e6365000000000000000000000000000000000000000000000000000060648201526084016109a0565b73ffffffffffffffffffffffffffffffffffffffff80851660009081526033602052604080822085850390559185168152908120805484929061140290849061232c565b925050819055508273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef8460405161146891815260200190565b60405180910390a3610f38565b73ffffffffffffffffffffffffffffffffffffffff8216611518576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602160248201527f45524332303a206275726e2066726f6d20746865207a65726f2061646472657360448201527f730000000000000000000000000000000000000000000000000000000000000060648201526084016109a0565b73ffffffffffffffffffffffffffffffffffffffff8216600090815260336020526040902054818110156115ce576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602260248201527f45524332303a206275726e20616d6f756e7420657863656564732062616c616e60448201527f636500000000000000000000000000000000000000000000000000000000000060648201526084016109a0565b73ffffffffffffffffffffffffffffffffffffffff8316600090815260336020526040812083830390556035805484929061160a908490612319565b909155505060405182815260009073ffffffffffffffffffffffffffffffffffffffff8516907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef9060200160405180910390a3505050565b60006107327f8b73c3c69bb8fe3d512ecc4cf759cc79239f7b179b0ffacaa9a75d522b39400f61169160655490565b6066546040805160208101859052908101839052606081018290524660808201523060a082015260009060c0016040516020818303038152906040528051906020012090509392505050565b73ffffffffffffffffffffffffffffffffffffffff821661175a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601f60248201527f45524332303a206d696e7420746f20746865207a65726f20616464726573730060448201526064016109a0565b806035600082825461176c919061232c565b909155505073ffffffffffffffffffffffffffffffffffffffff8216600090815260336020526040812080548392906117a690849061232c565b909155505060405181815273ffffffffffffffffffffffffffffffffffffffff8316906000907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef9060200160405180910390a35050565b73ffffffffffffffffffffffffffffffffffffffff811660009081526099602052604090208054600181018255905b50919050565b60006104b561183f611662565b836040517f19010000000000000000000000000000000000000000000000000000000000006020820152602281018390526042810182905260009060620160405160208183030381529060405280519060200120905092915050565b60008060006118ac87878787611a3a565b915091506118b981611b52565b5095945050505050565b600054610100900460ff1661195a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201527f6e697469616c697a696e6700000000000000000000000000000000000000000060648201526084016109a0565b610806816040518060400160405280600181526020017f3100000000000000000000000000000000000000000000000000000000000000815250611da6565b600054610100900460ff16611a30576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201527f6e697469616c697a696e6700000000000000000000000000000000000000000060648201526084016109a0565b6105328282611e57565b6000807f7fffffffffffffffffffffffffffffff5d576e7357a4501ddfe92f46681b20a0831115611a715750600090506003611b49565b8460ff16601b14158015611a8957508460ff16601c14155b15611a9a5750600090506004611b49565b6040805160008082526020820180845289905260ff881692820192909252606081018690526080810185905260019060a0016020604051602081039080840390855afa158015611aee573d6000803e3d6000fd5b50506040517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0015191505073ffffffffffffffffffffffffffffffffffffffff8116611b4257600060019250925050611b49565b9150600090505b94509492505050565b6000816004811115611b6657611b6661235c565b03611b6e5750565b6001816004811115611b8257611b8261235c565b03611be9576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601860248201527f45434453413a20696e76616c6964207369676e6174757265000000000000000060448201526064016109a0565b6002816004811115611bfd57611bfd61235c565b03611c64576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601f60248201527f45434453413a20696e76616c6964207369676e6174757265206c656e6774680060448201526064016109a0565b6003816004811115611c7857611c7861235c565b03611d05576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602260248201527f45434453413a20696e76616c6964207369676e6174757265202773272076616c60448201527f756500000000000000000000000000000000000000000000000000000000000060648201526084016109a0565b6004816004811115611d1957611d1961235c565b03610806576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602260248201527f45434453413a20696e76616c6964207369676e6174757265202776272076616c60448201527f756500000000000000000000000000000000000000000000000000000000000060648201526084016109a0565b600054610100900460ff16611e3d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201527f6e697469616c697a696e6700000000000000000000000000000000000000000060648201526084016109a0565b815160209283012081519190920120606591909155606655565b600054610100900460ff16611eee576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201527f6e697469616c697a696e6700000000000000000000000000000000000000000060648201526084016109a0565b6036611efa83826123d9565b50603761049c82826123d9565b600060208083528351808285015260005b81811015611f3457858101830151858201604001528201611f18565b5060006040828601015260407fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f8301168501019250505092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b600082601f830112611fb357600080fd5b813567ffffffffffffffff80821115611fce57611fce611f73565b604051601f83017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0908116603f0116810190828211818310171561201457612014611f73565b8160405283815286602085880101111561202d57600080fd5b836020870160208301376000602085830101528094505050505092915050565b73ffffffffffffffffffffffffffffffffffffffff8116811461080657600080fd5b60008060006060848603121561208457600080fd5b833567ffffffffffffffff8082111561209c57600080fd5b6120a887838801611fa2565b945060208601359150808211156120be57600080fd5b506120cb86828701611fa2565b92505060408401356120dc8161204d565b809150509250925092565b600080604083850312156120fa57600080fd5b82356121058161204d565b946020939093013593505050565b60008060006060848603121561212857600080fd5b83356121338161204d565b925060208401356121438161204d565b929592945050506040919091013590565b6000806040838503121561216757600080fd5b8235915060208301356121798161204d565b809150509250929050565b60006020828403121561219657600080fd5b81356121a18161204d565b9392505050565b6000806000606084860312156121bd57600080fd5b8335925060208401356121cf8161204d565b915060408401356120dc8161204d565b6000602082840312156121f157600080fd5b5035919050565b600080600080600080600060e0888a03121561221357600080fd5b873561221e8161204d565b9650602088013561222e8161204d565b95506040880135945060608801359350608088013560ff8116811461225257600080fd5b9699959850939692959460a0840135945060c09093013592915050565b6000806040838503121561228257600080fd5b823561228d8161204d565b915060208301356121798161204d565b600181811c908216806122b157607f821691505b60208210810361182c577f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b818103818111156104b5576104b56122ea565b808201808211156104b5576104b56122ea565b60006020828403121561235157600080fd5b81516121a18161204d565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b601f82111561049c57600081815260208120601f850160051c810160208610156123b25750805b601f850160051c820191505b818110156123d1578281556001016123be565b505050505050565b815167ffffffffffffffff8111156123f3576123f3611f73565b61240781612401845461229d565b8461238b565b602080601f83116001811461245a57600084156124245750858301515b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600386901b1c1916600185901b1785556123d1565b6000858152602081207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08616915b828110156124a757888601518255948401946001909101908401612488565b50858210156124e357878501517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600388901b60f8161c191681555b5050505050600190811b0190555056fea26469706673582212202531848f607b77ccac985cb622c78a992378ddd97de077b69970087c07e1678364736f6c63430008110033", + "deployedBytecode": "0x608060405234801561001057600080fd5b50600436106101985760003560e01c806361d027b3116100e3578063a457c2d71161008c578063d505accf11610066578063d505accf14610393578063dd62ed3e146103a6578063f0f44260146103ec57600080fd5b8063a457c2d71461034a578063a9059cbb1461035d578063aa271e1a1461037057600080fd5b806390218cff116100bd57806390218cff1461031c57806395d89b411461032f578063983b2d561461033757600080fd5b806361d027b31461028e57806370a08231146102d35780637ecebe001461030957600080fd5b80633092afd5116101455780633644e5151161011f5780633644e51514610260578063395093511461026857806340c10f191461027b57600080fd5b80633092afd51461022b578063313ce5671461023e578063350ebe041461024d57600080fd5b806318160ddd1161017657806318160ddd146101f357806323b872dd146102055780632b471d8e1461021857600080fd5b806306fdde031461019d578063077f224a146101bb578063095ea7b3146101d0575b600080fd5b6101a56103ff565b6040516101b29190611f07565b60405180910390f35b6101ce6101c936600461206f565b610491565b005b6101e36101de3660046120e7565b6104a1565b60405190151581526020016101b2565b6035545b6040519081526020016101b2565b6101e3610213366004612113565b6104bb565b6101ce610226366004612154565b6104df565b6101ce610239366004612184565b610536565b604051601281526020016101b2565b6101ce61025b3660046121a8565b61061f565b6101f7610728565b6101e36102763660046120e7565b610737565b6101ce6102893660046120e7565b61077e565b60cd546102ae9073ffffffffffffffffffffffffffffffffffffffff1681565b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020016101b2565b6101f76102e1366004612184565b73ffffffffffffffffffffffffffffffffffffffff1660009081526033602052604090205490565b6101f7610317366004612184565b6107d1565b6101ce61032a3660046121df565b6107fc565b6101a5610809565b6101ce610345366004612184565b610818565b6101e36103583660046120e7565b6108e0565b6101e361036b3660046120e7565b6109b6565b6101e361037e366004612184565b60cc6020526000908152604090205460ff1681565b6101ce6103a13660046121f8565b6109c4565b6101f76103b436600461226f565b73ffffffffffffffffffffffffffffffffffffffff918216600090815260346020908152604080832093909416825291909152205490565b6101ce6103fa366004612184565b610b83565b60606036805461040e9061229d565b80601f016020809104026020016040519081016040528092919081815260200182805461043a9061229d565b80156104875780601f1061045c57610100808354040283529160200191610487565b820191906000526020600020905b81548152906001019060200180831161046a57829003601f168201915b5050505050905090565b61049c838383610c5f565b505050565b6000336104af818585610f3e565b60019150505b92915050565b6000336104c98582856110f1565b6104d48585856111c2565b506001949350505050565b33600090815260cc602052604090205460ff16610528576040517ff8d2906c00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6105328183611475565b5050565b60cd5473ffffffffffffffffffffffffffffffffffffffff16331480159061057457503373ffffffffffffffffffffffffffffffffffffffff821614155b156105ab576040517fddb5de5e00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff8116600081815260cc602052604080822080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00169055517f98c15241d6c02bc5ee0b780e11b3ea737a2defd9d04877edbe9f9497065bd02f9190a250565b33600090815260cc602052604090205460ff16610668576040517ff8d2906c00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff161461071e5773ffffffffffffffffffffffffffffffffffffffff82811660009081526034602090815260408083209385168352929052205483811015610708576040517f715ec26c00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b61071c83836107178785612319565b610f3e565b505b61049c8284611475565b6000610732611662565b905090565b33600081815260346020908152604080832073ffffffffffffffffffffffffffffffffffffffff871684529091528120549091906104af908290869061071790879061232c565b33600090815260cc602052604090205460ff166107c7576040517ff8d2906c00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b61053282826116dd565b73ffffffffffffffffffffffffffffffffffffffff81166000908152609960205260408120546104b5565b6108063382611475565b50565b60606037805461040e9061229d565b60cd5473ffffffffffffffffffffffffffffffffffffffff163314610869576040517fb90cdbb100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff8116600081815260cc602052604080822080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00166001179055517f98c15241d6c02bc5ee0b780e11b3ea737a2defd9d04877edbe9f9497065bd02f9190a250565b33600081815260346020908152604080832073ffffffffffffffffffffffffffffffffffffffff87168452909152812054909190838110156109a9576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602560248201527f45524332303a2064656372656173656420616c6c6f77616e63652062656c6f7760448201527f207a65726f00000000000000000000000000000000000000000000000000000060648201526084015b60405180910390fd5b6104d48286868403610f3e565b6000336104af8185856111c2565b83421115610a2e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f45524332305065726d69743a206578706972656420646561646c696e6500000060448201526064016109a0565b60007f6e71edae12b1b97f4d1f60370fef10105fa2faae0126114a169c64845d6126c9888888610a5d8c6117fd565b60408051602081019690965273ffffffffffffffffffffffffffffffffffffffff94851690860152929091166060840152608083015260a082015260c0810186905260e0016040516020818303038152906040528051906020012090506000610ac582611832565b90506000610ad58287878761189b565b90508973ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614610b6c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601e60248201527f45524332305065726d69743a20696e76616c6964207369676e6174757265000060448201526064016109a0565b610b778a8a8a610f3e565b50505050505050505050565b60cd5473ffffffffffffffffffffffffffffffffffffffff163314610bd4576040517fb90cdbb100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60cd80547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83169081179091556040517f7dae230f18360d76a040c81f050aa14eb9d6dc7901b20fc5d855e2a20fe814d190600090a250565b73ffffffffffffffffffffffffffffffffffffffff163b151590565b600054610100900460ff1615808015610c7f5750600054600160ff909116105b80610c995750303b158015610c99575060005460ff166001145b610d25576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201527f647920696e697469616c697a656400000000000000000000000000000000000060648201526084016109a0565b600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001660011790558015610d8357600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff166101001790555b3073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1663e9cbd8226040518163ffffffff1660e01b8152600401602060405180830381865afa158015610de5573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610e09919061233f565b73ffffffffffffffffffffffffffffffffffffffff1614610e56576040517f14bcf5c800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b610e5f846118c3565b610e698484611999565b60cd80547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff84169081179091556040517f7dae230f18360d76a040c81f050aa14eb9d6dc7901b20fc5d855e2a20fe814d190600090a28015610f3857600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15b50505050565b73ffffffffffffffffffffffffffffffffffffffff8316610fe0576040517f08c379a0000000000000000000000000000000000000000000000000000000008152602060048201526024808201527f45524332303a20617070726f76652066726f6d20746865207a65726f2061646460448201527f726573730000000000000000000000000000000000000000000000000000000060648201526084016109a0565b73ffffffffffffffffffffffffffffffffffffffff8216611083576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602260248201527f45524332303a20617070726f766520746f20746865207a65726f20616464726560448201527f737300000000000000000000000000000000000000000000000000000000000060648201526084016109a0565b73ffffffffffffffffffffffffffffffffffffffff83811660008181526034602090815260408083209487168084529482529182902085905590518481527f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925910160405180910390a3505050565b73ffffffffffffffffffffffffffffffffffffffff8381166000908152603460209081526040808320938616835292905220547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8114610f3857818110156111b5576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f45524332303a20696e73756666696369656e7420616c6c6f77616e636500000060448201526064016109a0565b610f388484848403610f3e565b73ffffffffffffffffffffffffffffffffffffffff8316611265576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602560248201527f45524332303a207472616e736665722066726f6d20746865207a65726f20616460448201527f647265737300000000000000000000000000000000000000000000000000000060648201526084016109a0565b73ffffffffffffffffffffffffffffffffffffffff8216611308576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602360248201527f45524332303a207472616e7366657220746f20746865207a65726f206164647260448201527f657373000000000000000000000000000000000000000000000000000000000060648201526084016109a0565b73ffffffffffffffffffffffffffffffffffffffff8316600090815260336020526040902054818110156113be576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f45524332303a207472616e7366657220616d6f756e742065786365656473206260448201527f616c616e6365000000000000000000000000000000000000000000000000000060648201526084016109a0565b73ffffffffffffffffffffffffffffffffffffffff80851660009081526033602052604080822085850390559185168152908120805484929061140290849061232c565b925050819055508273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef8460405161146891815260200190565b60405180910390a3610f38565b73ffffffffffffffffffffffffffffffffffffffff8216611518576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602160248201527f45524332303a206275726e2066726f6d20746865207a65726f2061646472657360448201527f730000000000000000000000000000000000000000000000000000000000000060648201526084016109a0565b73ffffffffffffffffffffffffffffffffffffffff8216600090815260336020526040902054818110156115ce576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602260248201527f45524332303a206275726e20616d6f756e7420657863656564732062616c616e60448201527f636500000000000000000000000000000000000000000000000000000000000060648201526084016109a0565b73ffffffffffffffffffffffffffffffffffffffff8316600090815260336020526040812083830390556035805484929061160a908490612319565b909155505060405182815260009073ffffffffffffffffffffffffffffffffffffffff8516907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef9060200160405180910390a3505050565b60006107327f8b73c3c69bb8fe3d512ecc4cf759cc79239f7b179b0ffacaa9a75d522b39400f61169160655490565b6066546040805160208101859052908101839052606081018290524660808201523060a082015260009060c0016040516020818303038152906040528051906020012090509392505050565b73ffffffffffffffffffffffffffffffffffffffff821661175a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601f60248201527f45524332303a206d696e7420746f20746865207a65726f20616464726573730060448201526064016109a0565b806035600082825461176c919061232c565b909155505073ffffffffffffffffffffffffffffffffffffffff8216600090815260336020526040812080548392906117a690849061232c565b909155505060405181815273ffffffffffffffffffffffffffffffffffffffff8316906000907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef9060200160405180910390a35050565b73ffffffffffffffffffffffffffffffffffffffff811660009081526099602052604090208054600181018255905b50919050565b60006104b561183f611662565b836040517f19010000000000000000000000000000000000000000000000000000000000006020820152602281018390526042810182905260009060620160405160208183030381529060405280519060200120905092915050565b60008060006118ac87878787611a3a565b915091506118b981611b52565b5095945050505050565b600054610100900460ff1661195a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201527f6e697469616c697a696e6700000000000000000000000000000000000000000060648201526084016109a0565b610806816040518060400160405280600181526020017f3100000000000000000000000000000000000000000000000000000000000000815250611da6565b600054610100900460ff16611a30576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201527f6e697469616c697a696e6700000000000000000000000000000000000000000060648201526084016109a0565b6105328282611e57565b6000807f7fffffffffffffffffffffffffffffff5d576e7357a4501ddfe92f46681b20a0831115611a715750600090506003611b49565b8460ff16601b14158015611a8957508460ff16601c14155b15611a9a5750600090506004611b49565b6040805160008082526020820180845289905260ff881692820192909252606081018690526080810185905260019060a0016020604051602081039080840390855afa158015611aee573d6000803e3d6000fd5b50506040517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0015191505073ffffffffffffffffffffffffffffffffffffffff8116611b4257600060019250925050611b49565b9150600090505b94509492505050565b6000816004811115611b6657611b6661235c565b03611b6e5750565b6001816004811115611b8257611b8261235c565b03611be9576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601860248201527f45434453413a20696e76616c6964207369676e6174757265000000000000000060448201526064016109a0565b6002816004811115611bfd57611bfd61235c565b03611c64576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601f60248201527f45434453413a20696e76616c6964207369676e6174757265206c656e6774680060448201526064016109a0565b6003816004811115611c7857611c7861235c565b03611d05576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602260248201527f45434453413a20696e76616c6964207369676e6174757265202773272076616c60448201527f756500000000000000000000000000000000000000000000000000000000000060648201526084016109a0565b6004816004811115611d1957611d1961235c565b03610806576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602260248201527f45434453413a20696e76616c6964207369676e6174757265202776272076616c60448201527f756500000000000000000000000000000000000000000000000000000000000060648201526084016109a0565b600054610100900460ff16611e3d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201527f6e697469616c697a696e6700000000000000000000000000000000000000000060648201526084016109a0565b815160209283012081519190920120606591909155606655565b600054610100900460ff16611eee576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201527f6e697469616c697a696e6700000000000000000000000000000000000000000060648201526084016109a0565b6036611efa83826123d9565b50603761049c82826123d9565b600060208083528351808285015260005b81811015611f3457858101830151858201604001528201611f18565b5060006040828601015260407fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f8301168501019250505092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b600082601f830112611fb357600080fd5b813567ffffffffffffffff80821115611fce57611fce611f73565b604051601f83017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0908116603f0116810190828211818310171561201457612014611f73565b8160405283815286602085880101111561202d57600080fd5b836020870160208301376000602085830101528094505050505092915050565b73ffffffffffffffffffffffffffffffffffffffff8116811461080657600080fd5b60008060006060848603121561208457600080fd5b833567ffffffffffffffff8082111561209c57600080fd5b6120a887838801611fa2565b945060208601359150808211156120be57600080fd5b506120cb86828701611fa2565b92505060408401356120dc8161204d565b809150509250925092565b600080604083850312156120fa57600080fd5b82356121058161204d565b946020939093013593505050565b60008060006060848603121561212857600080fd5b83356121338161204d565b925060208401356121438161204d565b929592945050506040919091013590565b6000806040838503121561216757600080fd5b8235915060208301356121798161204d565b809150509250929050565b60006020828403121561219657600080fd5b81356121a18161204d565b9392505050565b6000806000606084860312156121bd57600080fd5b8335925060208401356121cf8161204d565b915060408401356120dc8161204d565b6000602082840312156121f157600080fd5b5035919050565b600080600080600080600060e0888a03121561221357600080fd5b873561221e8161204d565b9650602088013561222e8161204d565b95506040880135945060608801359350608088013560ff8116811461225257600080fd5b9699959850939692959460a0840135945060c09093013592915050565b6000806040838503121561228257600080fd5b823561228d8161204d565b915060208301356121798161204d565b600181811c908216806122b157607f821691505b60208210810361182c577f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b818103818111156104b5576104b56122ea565b808201808211156104b5576104b56122ea565b60006020828403121561235157600080fd5b81516121a18161204d565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b601f82111561049c57600081815260208120601f850160051c810160208610156123b25750805b601f850160051c820191505b818110156123d1578281556001016123be565b505050505050565b815167ffffffffffffffff8111156123f3576123f3611f73565b61240781612401845461229d565b8461238b565b602080601f83116001811461245a57600084156124245750858301515b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600386901b1c1916600185901b1785556123d1565b6000858152602081207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08616915b828110156124a757888601518255948401946001909101908401612488565b50858210156124e357878501517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600388901b60f8161c191681555b5050505050600190811b0190555056fea26469706673582212202531848f607b77ccac985cb622c78a992378ddd97de077b69970087c07e1678364736f6c63430008110033", "devdoc": { - "author": "Angle Core Team", - "details": "This contract is used to create and handle the stablecoins of Angle protocolIt is still possible for any address to burn its agTokens without redeeming collateral in exchangeThis contract is the upgraded version of the AgToken that was first deployed on Ethereum mainnet", + "author": "Angle Labs, Inc.", + "details": "By default, agTokens are ERC-20 tokens with 18 decimals", "kind": "dev", "methods": { "DOMAIN_SEPARATOR()": { @@ -698,7 +635,7 @@ "details": "See {IERC20-allowance}." }, "approve(address,uint256)": { - "details": "See {IERC20-approve}. Requirements: - `spender` cannot be the zero address." + "details": "See {IERC20-approve}. NOTE: If `amount` is the maximum `uint256`, the allowance is not updated on `transferFrom`. This is semantically equivalent to an infinite approval. Requirements: - `spender` cannot be the zero address." }, "balanceOf(address)": { "details": "See {IERC20-balanceOf}." @@ -711,20 +648,6 @@ "sender": "Address which requested the burn from `burner`" } }, - "burnFromNoRedeem(address,uint256,address)": { - "params": { - "account": "Account to burn on behalf of", - "amount": "Amount to burn", - "poolManager": "Reference to the `PoolManager` contract for which the `stocksUsers` will need to be updated" - } - }, - "burnNoRedeem(uint256,address)": { - "details": "When calling this function, people should specify the `poolManager` for which they want to decrease the `stocksUsers`: this is a way for the protocol to maintain healthy accounting variables", - "params": { - "amount": "Amount to burn", - "poolManager": "Reference to the `PoolManager` contract for which the `stocksUsers` will need to be updated" - } - }, "burnSelf(uint256,address)": { "details": "This method is to be called by a contract with a minter right on the AgToken after being requested to do so by an address willing to burn tokens from its address", "params": { @@ -750,14 +673,6 @@ "increaseAllowance(address,uint256)": { "details": "Atomically increases the allowance granted to `spender` by the caller. This is an alternative to {approve} that can be used as a mitigation for problems described in {IERC20-approve}. Emits an {Approval} event indicating the updated allowance. Requirements: - `spender` cannot be the zero address." }, - "initialize(string,string,address)": { - "details": "By default, agTokens are ERC-20 tokens with 18 decimals", - "params": { - "name_": "Name of the token", - "stableMaster_": "Reference to the `StableMaster` contract associated to this agToken", - "symbol_": "Symbol of the token" - } - }, "mint(address,uint256)": { "details": "The contracts allowed to issue agTokens are the `StableMaster` contract, `VaultManager` contracts associated to this stablecoin as well as the flash loan module (if activated) and potentially contracts whitelisted by governance", "params": { @@ -785,12 +700,6 @@ "_treasury": "New treasury address" } }, - "setUpTreasury(address)": { - "details": "The address calling this function has to be hard-coded in the contractCan be called only once", - "params": { - "_treasury": "Treasury contract to add" - } - }, "symbol()": { "details": "Returns the symbol of the token, usually a shorter version of the name." }, @@ -798,10 +707,10 @@ "details": "See {IERC20-totalSupply}." }, "transfer(address,uint256)": { - "details": "See {IERC20-transfer}. Requirements: - `recipient` cannot be the zero address. - the caller must have a balance of at least `amount`." + "details": "See {IERC20-transfer}. Requirements: - `to` cannot be the zero address. - the caller must have a balance of at least `amount`." }, "transferFrom(address,address,uint256)": { - "details": "See {IERC20-transferFrom}. Emits an {Approval} event indicating the updated allowance. This is not required by the EIP. See the note at the beginning of {ERC20}. Requirements: - `sender` and `recipient` cannot be the zero address. - `sender` must have a balance of at least `amount`. - the caller must have allowance for ``sender``'s tokens of at least `amount`." + "details": "See {IERC20-transferFrom}. Emits an {Approval} event indicating the updated allowance. This is not required by the EIP. See the note at the beginning of {ERC20}. NOTE: Does not update the allowance if the current allowance is the maximum `uint256`. Requirements: - `from` and `to` cannot be the zero address. - `from` must have a balance of at least `amount`. - the caller must have allowance for ``from``'s tokens of at least `amount`." } }, "stateVariables": { @@ -827,17 +736,11 @@ "burnFrom(uint256,address,address)": { "notice": "Burns `amount` tokens from a `burner` address after being asked to by `sender`" }, - "burnFromNoRedeem(address,uint256,address)": { - "notice": "Burns `amount` of agToken on behalf of another account without redeeming collateral back" - }, - "burnNoRedeem(uint256,address)": { - "notice": "Destroys `amount` token from the caller without giving collateral back" - }, "burnSelf(uint256,address)": { "notice": "Burns `amount` tokens from a `burner` address" }, "burnStablecoin(uint256)": { - "notice": "Allows anyone to burn agToken without redeeming collateral back" + "notice": "Allows anyone to burn stablecoins" }, "initialize(string,string,address)": { "notice": "Initializes the `AgToken` contract" @@ -854,34 +757,25 @@ "setTreasury(address)": { "notice": "Sets a new treasury contract" }, - "setUpTreasury(address)": { - "notice": "Sets up the treasury contract in this AgToken contract" - }, - "stableMaster()": { - "notice": "Reference to the `StableMaster` contract associated to this `AgToken`" - }, "treasury()": { "notice": "Reference to the treasury contract which can grant minting rights" - }, - "treasuryInitialized()": { - "notice": "Boolean to check whether the contract has been reinitialized after its upgrade" } }, - "notice": "Base contract for agToken, that is to say Angle's stablecoins", + "notice": "Base contract for Angle agTokens on Ethereum and on other chains", "version": 1 }, "storageLayout": { "storage": [ { - "astId": 772, + "astId": 770, "contract": "contracts/agToken/AgToken.sol:AgToken", "label": "_initialized", "offset": 0, "slot": "0", - "type": "t_bool" + "type": "t_uint8" }, { - "astId": 775, + "astId": 773, "contract": "contracts/agToken/AgToken.sol:AgToken", "label": "_initializing", "offset": 1, @@ -889,7 +783,7 @@ "type": "t_bool" }, { - "astId": 2479, + "astId": 2486, "contract": "contracts/agToken/AgToken.sol:AgToken", "label": "__gap", "offset": 0, @@ -897,7 +791,7 @@ "type": "t_array(t_uint256)50_storage" }, { - "astId": 916, + "astId": 1119, "contract": "contracts/agToken/AgToken.sol:AgToken", "label": "_balances", "offset": 0, @@ -905,7 +799,7 @@ "type": "t_mapping(t_address,t_uint256)" }, { - "astId": 922, + "astId": 1125, "contract": "contracts/agToken/AgToken.sol:AgToken", "label": "_allowances", "offset": 0, @@ -913,7 +807,7 @@ "type": "t_mapping(t_address,t_mapping(t_address,t_uint256))" }, { - "astId": 924, + "astId": 1127, "contract": "contracts/agToken/AgToken.sol:AgToken", "label": "_totalSupply", "offset": 0, @@ -921,7 +815,7 @@ "type": "t_uint256" }, { - "astId": 926, + "astId": 1129, "contract": "contracts/agToken/AgToken.sol:AgToken", "label": "_name", "offset": 0, @@ -929,7 +823,7 @@ "type": "t_string_storage" }, { - "astId": 928, + "astId": 1131, "contract": "contracts/agToken/AgToken.sol:AgToken", "label": "_symbol", "offset": 0, @@ -937,7 +831,7 @@ "type": "t_string_storage" }, { - "astId": 1469, + "astId": 1710, "contract": "contracts/agToken/AgToken.sol:AgToken", "label": "__gap", "offset": 0, @@ -945,7 +839,7 @@ "type": "t_array(t_uint256)45_storage" }, { - "astId": 3156, + "astId": 3203, "contract": "contracts/agToken/AgToken.sol:AgToken", "label": "_HASHED_NAME", "offset": 0, @@ -953,7 +847,7 @@ "type": "t_bytes32" }, { - "astId": 3158, + "astId": 3205, "contract": "contracts/agToken/AgToken.sol:AgToken", "label": "_HASHED_VERSION", "offset": 0, @@ -961,7 +855,7 @@ "type": "t_bytes32" }, { - "astId": 3295, + "astId": 3343, "contract": "contracts/agToken/AgToken.sol:AgToken", "label": "__gap", "offset": 0, @@ -969,23 +863,23 @@ "type": "t_array(t_uint256)50_storage" }, { - "astId": 1599, + "astId": 1840, "contract": "contracts/agToken/AgToken.sol:AgToken", "label": "_nonces", "offset": 0, "slot": "153", - "type": "t_mapping(t_address,t_struct(Counter)2486_storage)" + "type": "t_mapping(t_address,t_struct(Counter)2493_storage)" }, { - "astId": 1601, + "astId": 1848, "contract": "contracts/agToken/AgToken.sol:AgToken", - "label": "_PERMIT_TYPEHASH", + "label": "_PERMIT_TYPEHASH_DEPRECATED_SLOT", "offset": 0, "slot": "154", "type": "t_bytes32" }, { - "astId": 1769, + "astId": 2004, "contract": "contracts/agToken/AgToken.sol:AgToken", "label": "__gap", "offset": 0, @@ -993,36 +887,20 @@ "type": "t_array(t_uint256)49_storage" }, { - "astId": 7118, - "contract": "contracts/agToken/AgToken.sol:AgToken", - "label": "stableMaster", - "offset": 0, - "slot": "204", - "type": "t_address" - }, - { - "astId": 7166, + "astId": 7427, "contract": "contracts/agToken/AgToken.sol:AgToken", "label": "isMinter", "offset": 0, - "slot": "205", + "slot": "204", "type": "t_mapping(t_address,t_bool)" }, { - "astId": 7169, + "astId": 7430, "contract": "contracts/agToken/AgToken.sol:AgToken", "label": "treasury", "offset": 0, - "slot": "206", + "slot": "205", "type": "t_address" - }, - { - "astId": 7172, - "contract": "contracts/agToken/AgToken.sol:AgToken", - "label": "treasuryInitialized", - "offset": 20, - "slot": "206", - "type": "t_bool" } ], "types": { @@ -1073,12 +951,12 @@ "numberOfBytes": "32", "value": "t_mapping(t_address,t_uint256)" }, - "t_mapping(t_address,t_struct(Counter)2486_storage)": { + "t_mapping(t_address,t_struct(Counter)2493_storage)": { "encoding": "mapping", "key": "t_address", "label": "mapping(address => struct CountersUpgradeable.Counter)", "numberOfBytes": "32", - "value": "t_struct(Counter)2486_storage" + "value": "t_struct(Counter)2493_storage" }, "t_mapping(t_address,t_uint256)": { "encoding": "mapping", @@ -1092,12 +970,12 @@ "label": "string", "numberOfBytes": "32" }, - "t_struct(Counter)2486_storage": { + "t_struct(Counter)2493_storage": { "encoding": "inplace", "label": "struct CountersUpgradeable.Counter", "members": [ { - "astId": 2485, + "astId": 2492, "contract": "contracts/agToken/AgToken.sol:AgToken", "label": "_value", "offset": 0, @@ -1111,6 +989,11 @@ "encoding": "inplace", "label": "uint256", "numberOfBytes": "32" + }, + "t_uint8": { + "encoding": "inplace", + "label": "uint8", + "numberOfBytes": "1" } } } diff --git a/deployments/mainnet/CoreBorrowTest.json b/deployments/mainnet/CoreBorrowTest.json new file mode 100644 index 00000000..b7a886b8 --- /dev/null +++ b/deployments/mainnet/CoreBorrowTest.json @@ -0,0 +1,325 @@ +{ + "address": "0x3fc5a1bd4d0A435c55374208A6A81535A1923039", + "abi": [ + { + "inputs": [ + { + "internalType": "address", + "name": "_logic", + "type": "address" + }, + { + "internalType": "address", + "name": "admin_", + "type": "address" + }, + { + "internalType": "bytes", + "name": "_data", + "type": "bytes" + } + ], + "stateMutability": "payable", + "type": "constructor" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "previousAdmin", + "type": "address" + }, + { + "indexed": false, + "internalType": "address", + "name": "newAdmin", + "type": "address" + } + ], + "name": "AdminChanged", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "beacon", + "type": "address" + } + ], + "name": "BeaconUpgraded", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "implementation", + "type": "address" + } + ], + "name": "Upgraded", + "type": "event" + }, + { + "stateMutability": "payable", + "type": "fallback" + }, + { + "inputs": [], + "name": "admin", + "outputs": [ + { + "internalType": "address", + "name": "admin_", + "type": "address" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "newAdmin", + "type": "address" + } + ], + "name": "changeAdmin", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "implementation", + "outputs": [ + { + "internalType": "address", + "name": "implementation_", + "type": "address" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "newImplementation", + "type": "address" + } + ], + "name": "upgradeTo", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "newImplementation", + "type": "address" + }, + { + "internalType": "bytes", + "name": "data", + "type": "bytes" + } + ], + "name": "upgradeToAndCall", + "outputs": [], + "stateMutability": "payable", + "type": "function" + }, + { + "stateMutability": "payable", + "type": "receive" + } + ], + "transactionHash": "0xb5d4601c43d71141f8354bfbe0423aac9283124105ba8ca472aa95877e97d2ee", + "receipt": { + "to": null, + "from": "0xfdA462548Ce04282f4B6D6619823a7C64Fdc0185", + "contractAddress": "0x3fc5a1bd4d0A435c55374208A6A81535A1923039", + "transactionIndex": 64, + "gasUsed": "1037644", + "logsBloom": "0x00000004000000000800000400000000480000000000000000000000200000000000000000000000000000000000000000000000000000000000000000000000000020000000000000000000000002000000000000000000000000000000000000000000020000400000000000000800000000800010000000100000000000000000000000000000004000000000000100000003000000000000000000804000000000000000000000000000000000000000800000000800001000000000001000000020020000000000008000000000000800000400000100000000000020000000800000000000000010000000000400000000000000000000000000040000", + "blockHash": "0xb3aa1ac69fea20e35f61be120547c4fe44584cab3dd4fa2d66f8e72ddb9039be", + "transactionHash": "0xb5d4601c43d71141f8354bfbe0423aac9283124105ba8ca472aa95877e97d2ee", + "logs": [ + { + "transactionIndex": 64, + "blockNumber": 18975605, + "transactionHash": "0xb5d4601c43d71141f8354bfbe0423aac9283124105ba8ca472aa95877e97d2ee", + "address": "0x3fc5a1bd4d0A435c55374208A6A81535A1923039", + "topics": [ + "0xbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b", + "0x0000000000000000000000004d144b7355bc2c33fa091339279e9d77261461fe" + ], + "data": "0x", + "logIndex": 159, + "blockHash": "0xb3aa1ac69fea20e35f61be120547c4fe44584cab3dd4fa2d66f8e72ddb9039be" + }, + { + "transactionIndex": 64, + "blockNumber": 18975605, + "transactionHash": "0xb5d4601c43d71141f8354bfbe0423aac9283124105ba8ca472aa95877e97d2ee", + "address": "0x3fc5a1bd4d0A435c55374208A6A81535A1923039", + "topics": [ + "0x2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d", + "0x7935bd0ae54bc31f548c14dba4d37c5c64b3f8ca900cb468fb8abd54d5894f55", + "0x000000000000000000000000fda462548ce04282f4b6d6619823a7c64fdc0185", + "0x000000000000000000000000fda462548ce04282f4b6d6619823a7c64fdc0185" + ], + "data": "0x", + "logIndex": 160, + "blockHash": "0xb3aa1ac69fea20e35f61be120547c4fe44584cab3dd4fa2d66f8e72ddb9039be" + }, + { + "transactionIndex": 64, + "blockNumber": 18975605, + "transactionHash": "0xb5d4601c43d71141f8354bfbe0423aac9283124105ba8ca472aa95877e97d2ee", + "address": "0x3fc5a1bd4d0A435c55374208A6A81535A1923039", + "topics": [ + "0x2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d", + "0x55435dd261a4b9b3364963f7738a7a662ad9c84396d64be3365284bb7f0a5041", + "0x0000000000000000000000000c2553e4b9dfa9f83b1a6d3eab96c4baab42d430", + "0x000000000000000000000000fda462548ce04282f4b6d6619823a7c64fdc0185" + ], + "data": "0x", + "logIndex": 161, + "blockHash": "0xb3aa1ac69fea20e35f61be120547c4fe44584cab3dd4fa2d66f8e72ddb9039be" + }, + { + "transactionIndex": 64, + "blockNumber": 18975605, + "transactionHash": "0xb5d4601c43d71141f8354bfbe0423aac9283124105ba8ca472aa95877e97d2ee", + "address": "0x3fc5a1bd4d0A435c55374208A6A81535A1923039", + "topics": [ + "0x2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d", + "0x55435dd261a4b9b3364963f7738a7a662ad9c84396d64be3365284bb7f0a5041", + "0x000000000000000000000000fda462548ce04282f4b6d6619823a7c64fdc0185", + "0x000000000000000000000000fda462548ce04282f4b6d6619823a7c64fdc0185" + ], + "data": "0x", + "logIndex": 162, + "blockHash": "0xb3aa1ac69fea20e35f61be120547c4fe44584cab3dd4fa2d66f8e72ddb9039be" + }, + { + "transactionIndex": 64, + "blockNumber": 18975605, + "transactionHash": "0xb5d4601c43d71141f8354bfbe0423aac9283124105ba8ca472aa95877e97d2ee", + "address": "0x3fc5a1bd4d0A435c55374208A6A81535A1923039", + "topics": [ + "0xbd79b86ffe0ab8e8776151514217cd7cacd52c909f66475c3af44e129f0b00ff", + "0x55435dd261a4b9b3364963f7738a7a662ad9c84396d64be3365284bb7f0a5041", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x7935bd0ae54bc31f548c14dba4d37c5c64b3f8ca900cb468fb8abd54d5894f55" + ], + "data": "0x", + "logIndex": 163, + "blockHash": "0xb3aa1ac69fea20e35f61be120547c4fe44584cab3dd4fa2d66f8e72ddb9039be" + }, + { + "transactionIndex": 64, + "blockNumber": 18975605, + "transactionHash": "0xb5d4601c43d71141f8354bfbe0423aac9283124105ba8ca472aa95877e97d2ee", + "address": "0x3fc5a1bd4d0A435c55374208A6A81535A1923039", + "topics": [ + "0xbd79b86ffe0ab8e8776151514217cd7cacd52c909f66475c3af44e129f0b00ff", + "0x7935bd0ae54bc31f548c14dba4d37c5c64b3f8ca900cb468fb8abd54d5894f55", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x7935bd0ae54bc31f548c14dba4d37c5c64b3f8ca900cb468fb8abd54d5894f55" + ], + "data": "0x", + "logIndex": 164, + "blockHash": "0xb3aa1ac69fea20e35f61be120547c4fe44584cab3dd4fa2d66f8e72ddb9039be" + }, + { + "transactionIndex": 64, + "blockNumber": 18975605, + "transactionHash": "0xb5d4601c43d71141f8354bfbe0423aac9283124105ba8ca472aa95877e97d2ee", + "address": "0x3fc5a1bd4d0A435c55374208A6A81535A1923039", + "topics": [ + "0xbd79b86ffe0ab8e8776151514217cd7cacd52c909f66475c3af44e129f0b00ff", + "0x0ae0130c6b34f32239dfe5e419a3fbd7546b44e99783257f2d93526d5a936d46", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x7935bd0ae54bc31f548c14dba4d37c5c64b3f8ca900cb468fb8abd54d5894f55" + ], + "data": "0x", + "logIndex": 165, + "blockHash": "0xb3aa1ac69fea20e35f61be120547c4fe44584cab3dd4fa2d66f8e72ddb9039be" + }, + { + "transactionIndex": 64, + "blockNumber": 18975605, + "transactionHash": "0xb5d4601c43d71141f8354bfbe0423aac9283124105ba8ca472aa95877e97d2ee", + "address": "0x3fc5a1bd4d0A435c55374208A6A81535A1923039", + "topics": [ + "0x7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f" + ], + "data": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000001d941ef0d3bba4ad67dbfbcee5262f4cee53a32b", + "logIndex": 166, + "blockHash": "0xb3aa1ac69fea20e35f61be120547c4fe44584cab3dd4fa2d66f8e72ddb9039be" + } + ], + "blockNumber": 18975605, + "cumulativeGasUsed": "7827510", + "status": 1, + "byzantium": true + }, + "args": [ + "0x4D144B7355bC2C33FA091339279e9D77261461fE", + "0x1D941EF0D3Bba4ad67DBfBCeE5262F4CEE53A32b", + "0x485cc955000000000000000000000000fda462548ce04282f4b6d6619823a7c64fdc01850000000000000000000000000c2553e4b9dfa9f83b1a6d3eab96c4baab42d430" + ], + "numDeployments": 1, + "solcInputHash": "871924e0c138825a2736b76def8fef8d", + "metadata": "{\"compiler\":{\"version\":\"0.8.17+commit.8df45f5f\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_logic\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"admin_\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"_data\",\"type\":\"bytes\"}],\"stateMutability\":\"payable\",\"type\":\"constructor\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"previousAdmin\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"newAdmin\",\"type\":\"address\"}],\"name\":\"AdminChanged\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"beacon\",\"type\":\"address\"}],\"name\":\"BeaconUpgraded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"implementation\",\"type\":\"address\"}],\"name\":\"Upgraded\",\"type\":\"event\"},{\"stateMutability\":\"payable\",\"type\":\"fallback\"},{\"inputs\":[],\"name\":\"admin\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"admin_\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newAdmin\",\"type\":\"address\"}],\"name\":\"changeAdmin\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"implementation\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"implementation_\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newImplementation\",\"type\":\"address\"}],\"name\":\"upgradeTo\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newImplementation\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"}],\"name\":\"upgradeToAndCall\",\"outputs\":[],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"stateMutability\":\"payable\",\"type\":\"receive\"}],\"devdoc\":{\"details\":\"This contract implements a proxy that is upgradeable by an admin. It is fully forked from OpenZeppelin `TransparentUpgradeableProxy` To avoid https://medium.com/nomic-labs-blog/malicious-backdoors-in-ethereum-proxies-62629adf3357[proxy selector clashing], which can potentially be used in an attack, this contract uses the https://blog.openzeppelin.com/the-transparent-proxy-pattern/[transparent proxy pattern]. This pattern implies two things that go hand in hand: 1. If any account other than the admin calls the proxy, the call will be forwarded to the implementation, even if that call matches one of the admin functions exposed by the proxy itself. 2. If the admin calls the proxy, it can access the admin functions, but its calls will never be forwarded to the implementation. If the admin tries to call a function on the implementation it will fail with an error that says \\\"admin cannot fallback to proxy target\\\". These properties mean that the admin account can only be used for admin actions like upgrading the proxy or changing the admin, so it's best if it's a dedicated account that is not used for anything else. This will avoid headaches due to sudden errors when trying to call a function from the proxy implementation. Our recommendation is for the dedicated account to be an instance of the {ProxyAdmin} contract. If set up this way, you should think of the `ProxyAdmin` instance as the real administrative interface of your proxy.\",\"kind\":\"dev\",\"methods\":{\"admin()\":{\"details\":\"Returns the current admin. NOTE: Only the admin can call this function. See {ProxyAdmin-getProxyAdmin}. TIP: To get this value clients can read directly from the storage slot shown below (specified by EIP1967) using the https://eth.wiki/json-rpc/API#eth_getstorageat[`eth_getStorageAt`] RPC call. `0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103`\"},\"changeAdmin(address)\":{\"details\":\"Changes the admin of the proxy. Emits an {AdminChanged} event. NOTE: Only the admin can call this function. See {ProxyAdmin-changeProxyAdmin}.\"},\"constructor\":{\"details\":\"Initializes an upgradeable proxy managed by `_admin`, backed by the implementation at `_logic`, and optionally initialized with `_data` as explained in {ERC1967Proxy-constructor}.\"},\"implementation()\":{\"details\":\"Returns the current implementation. NOTE: Only the admin can call this function. See {ProxyAdmin-getProxyImplementation}. TIP: To get this value clients can read directly from the storage slot shown below (specified by EIP1967) using the https://eth.wiki/json-rpc/API#eth_getstorageat[`eth_getStorageAt`] RPC call. `0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc`\"},\"upgradeTo(address)\":{\"details\":\"Upgrade the implementation of the proxy. NOTE: Only the admin can call this function. See {ProxyAdmin-upgrade}.\"},\"upgradeToAndCall(address,bytes)\":{\"details\":\"Upgrade the implementation of the proxy, and then call a function from the new implementation as specified by `data`, which should be an encoded function call. This is useful to initialize new storage variables in the proxied contract. NOTE: Only the admin can call this function. See {ProxyAdmin-upgradeAndCall}.\"}},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/external/TransparentUpgradeableProxy.sol\":\"TransparentUpgradeableProxy\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":1000000},\"remappings\":[]},\"sources\":{\"@openzeppelin/contracts/interfaces/draft-IERC1822.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.5.0) (interfaces/draft-IERC1822.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev ERC1822: Universal Upgradeable Proxy Standard (UUPS) documents a method for upgradeability through a simplified\\n * proxy whose upgrades are fully controlled by the current implementation.\\n */\\ninterface IERC1822Proxiable {\\n /**\\n * @dev Returns the storage slot that the proxiable contract assumes is being used to store the implementation\\n * address.\\n *\\n * IMPORTANT: A proxy pointing at a proxiable contract should not be considered proxiable itself, because this risks\\n * bricking a proxy that upgrades to it, by delegating to itself until out of gas. Thus it is critical that this\\n * function revert if invoked through a proxy.\\n */\\n function proxiableUUID() external view returns (bytes32);\\n}\\n\",\"keccak256\":\"0x1d4afe6cb24200cc4545eed814ecf5847277dfe5d613a1707aad5fceecebcfff\",\"license\":\"MIT\"},\"@openzeppelin/contracts/proxy/ERC1967/ERC1967Proxy.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.7.0) (proxy/ERC1967/ERC1967Proxy.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../Proxy.sol\\\";\\nimport \\\"./ERC1967Upgrade.sol\\\";\\n\\n/**\\n * @dev This contract implements an upgradeable proxy. It is upgradeable because calls are delegated to an\\n * implementation address that can be changed. This address is stored in storage in the location specified by\\n * https://eips.ethereum.org/EIPS/eip-1967[EIP1967], so that it doesn't conflict with the storage layout of the\\n * implementation behind the proxy.\\n */\\ncontract ERC1967Proxy is Proxy, ERC1967Upgrade {\\n /**\\n * @dev Initializes the upgradeable proxy with an initial implementation specified by `_logic`.\\n *\\n * If `_data` is nonempty, it's used as data in a delegate call to `_logic`. This will typically be an encoded\\n * function call, and allows initializing the storage of the proxy like a Solidity constructor.\\n */\\n constructor(address _logic, bytes memory _data) payable {\\n _upgradeToAndCall(_logic, _data, false);\\n }\\n\\n /**\\n * @dev Returns the current implementation address.\\n */\\n function _implementation() internal view virtual override returns (address impl) {\\n return ERC1967Upgrade._getImplementation();\\n }\\n}\\n\",\"keccak256\":\"0xa2b22da3032e50b55f95ec1d13336102d675f341167aa76db571ef7f8bb7975d\",\"license\":\"MIT\"},\"@openzeppelin/contracts/proxy/ERC1967/ERC1967Upgrade.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.5.0) (proxy/ERC1967/ERC1967Upgrade.sol)\\n\\npragma solidity ^0.8.2;\\n\\nimport \\\"../beacon/IBeacon.sol\\\";\\nimport \\\"../../interfaces/draft-IERC1822.sol\\\";\\nimport \\\"../../utils/Address.sol\\\";\\nimport \\\"../../utils/StorageSlot.sol\\\";\\n\\n/**\\n * @dev This abstract contract provides getters and event emitting update functions for\\n * https://eips.ethereum.org/EIPS/eip-1967[EIP1967] slots.\\n *\\n * _Available since v4.1._\\n *\\n * @custom:oz-upgrades-unsafe-allow delegatecall\\n */\\nabstract contract ERC1967Upgrade {\\n // This is the keccak-256 hash of \\\"eip1967.proxy.rollback\\\" subtracted by 1\\n bytes32 private constant _ROLLBACK_SLOT = 0x4910fdfa16fed3260ed0e7147f7cc6da11a60208b5b9406d12a635614ffd9143;\\n\\n /**\\n * @dev Storage slot with the address of the current implementation.\\n * This is the keccak-256 hash of \\\"eip1967.proxy.implementation\\\" subtracted by 1, and is\\n * validated in the constructor.\\n */\\n bytes32 internal constant _IMPLEMENTATION_SLOT = 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc;\\n\\n /**\\n * @dev Emitted when the implementation is upgraded.\\n */\\n event Upgraded(address indexed implementation);\\n\\n /**\\n * @dev Returns the current implementation address.\\n */\\n function _getImplementation() internal view returns (address) {\\n return StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value;\\n }\\n\\n /**\\n * @dev Stores a new address in the EIP1967 implementation slot.\\n */\\n function _setImplementation(address newImplementation) private {\\n require(Address.isContract(newImplementation), \\\"ERC1967: new implementation is not a contract\\\");\\n StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value = newImplementation;\\n }\\n\\n /**\\n * @dev Perform implementation upgrade\\n *\\n * Emits an {Upgraded} event.\\n */\\n function _upgradeTo(address newImplementation) internal {\\n _setImplementation(newImplementation);\\n emit Upgraded(newImplementation);\\n }\\n\\n /**\\n * @dev Perform implementation upgrade with additional setup call.\\n *\\n * Emits an {Upgraded} event.\\n */\\n function _upgradeToAndCall(\\n address newImplementation,\\n bytes memory data,\\n bool forceCall\\n ) internal {\\n _upgradeTo(newImplementation);\\n if (data.length > 0 || forceCall) {\\n Address.functionDelegateCall(newImplementation, data);\\n }\\n }\\n\\n /**\\n * @dev Perform implementation upgrade with security checks for UUPS proxies, and additional setup call.\\n *\\n * Emits an {Upgraded} event.\\n */\\n function _upgradeToAndCallUUPS(\\n address newImplementation,\\n bytes memory data,\\n bool forceCall\\n ) internal {\\n // Upgrades from old implementations will perform a rollback test. This test requires the new\\n // implementation to upgrade back to the old, non-ERC1822 compliant, implementation. Removing\\n // this special case will break upgrade paths from old UUPS implementation to new ones.\\n if (StorageSlot.getBooleanSlot(_ROLLBACK_SLOT).value) {\\n _setImplementation(newImplementation);\\n } else {\\n try IERC1822Proxiable(newImplementation).proxiableUUID() returns (bytes32 slot) {\\n require(slot == _IMPLEMENTATION_SLOT, \\\"ERC1967Upgrade: unsupported proxiableUUID\\\");\\n } catch {\\n revert(\\\"ERC1967Upgrade: new implementation is not UUPS\\\");\\n }\\n _upgradeToAndCall(newImplementation, data, forceCall);\\n }\\n }\\n\\n /**\\n * @dev Storage slot with the admin of the contract.\\n * This is the keccak-256 hash of \\\"eip1967.proxy.admin\\\" subtracted by 1, and is\\n * validated in the constructor.\\n */\\n bytes32 internal constant _ADMIN_SLOT = 0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103;\\n\\n /**\\n * @dev Emitted when the admin account has changed.\\n */\\n event AdminChanged(address previousAdmin, address newAdmin);\\n\\n /**\\n * @dev Returns the current admin.\\n */\\n function _getAdmin() internal view returns (address) {\\n return StorageSlot.getAddressSlot(_ADMIN_SLOT).value;\\n }\\n\\n /**\\n * @dev Stores a new address in the EIP1967 admin slot.\\n */\\n function _setAdmin(address newAdmin) private {\\n require(newAdmin != address(0), \\\"ERC1967: new admin is the zero address\\\");\\n StorageSlot.getAddressSlot(_ADMIN_SLOT).value = newAdmin;\\n }\\n\\n /**\\n * @dev Changes the admin of the proxy.\\n *\\n * Emits an {AdminChanged} event.\\n */\\n function _changeAdmin(address newAdmin) internal {\\n emit AdminChanged(_getAdmin(), newAdmin);\\n _setAdmin(newAdmin);\\n }\\n\\n /**\\n * @dev The storage slot of the UpgradeableBeacon contract which defines the implementation for this proxy.\\n * This is bytes32(uint256(keccak256('eip1967.proxy.beacon')) - 1)) and is validated in the constructor.\\n */\\n bytes32 internal constant _BEACON_SLOT = 0xa3f0ad74e5423aebfd80d3ef4346578335a9a72aeaee59ff6cb3582b35133d50;\\n\\n /**\\n * @dev Emitted when the beacon is upgraded.\\n */\\n event BeaconUpgraded(address indexed beacon);\\n\\n /**\\n * @dev Returns the current beacon.\\n */\\n function _getBeacon() internal view returns (address) {\\n return StorageSlot.getAddressSlot(_BEACON_SLOT).value;\\n }\\n\\n /**\\n * @dev Stores a new beacon in the EIP1967 beacon slot.\\n */\\n function _setBeacon(address newBeacon) private {\\n require(Address.isContract(newBeacon), \\\"ERC1967: new beacon is not a contract\\\");\\n require(\\n Address.isContract(IBeacon(newBeacon).implementation()),\\n \\\"ERC1967: beacon implementation is not a contract\\\"\\n );\\n StorageSlot.getAddressSlot(_BEACON_SLOT).value = newBeacon;\\n }\\n\\n /**\\n * @dev Perform beacon upgrade with additional setup call. Note: This upgrades the address of the beacon, it does\\n * not upgrade the implementation contained in the beacon (see {UpgradeableBeacon-_setImplementation} for that).\\n *\\n * Emits a {BeaconUpgraded} event.\\n */\\n function _upgradeBeaconToAndCall(\\n address newBeacon,\\n bytes memory data,\\n bool forceCall\\n ) internal {\\n _setBeacon(newBeacon);\\n emit BeaconUpgraded(newBeacon);\\n if (data.length > 0 || forceCall) {\\n Address.functionDelegateCall(IBeacon(newBeacon).implementation(), data);\\n }\\n }\\n}\\n\",\"keccak256\":\"0xabf3f59bc0e5423eae45e459dbe92e7052c6983628d39008590edc852a62f94a\",\"license\":\"MIT\"},\"@openzeppelin/contracts/proxy/Proxy.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.6.0) (proxy/Proxy.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev This abstract contract provides a fallback function that delegates all calls to another contract using the EVM\\n * instruction `delegatecall`. We refer to the second contract as the _implementation_ behind the proxy, and it has to\\n * be specified by overriding the virtual {_implementation} function.\\n *\\n * Additionally, delegation to the implementation can be triggered manually through the {_fallback} function, or to a\\n * different contract through the {_delegate} function.\\n *\\n * The success and return data of the delegated call will be returned back to the caller of the proxy.\\n */\\nabstract contract Proxy {\\n /**\\n * @dev Delegates the current call to `implementation`.\\n *\\n * This function does not return to its internal call site, it will return directly to the external caller.\\n */\\n function _delegate(address implementation) internal virtual {\\n assembly {\\n // Copy msg.data. We take full control of memory in this inline assembly\\n // block because it will not return to Solidity code. We overwrite the\\n // Solidity scratch pad at memory position 0.\\n calldatacopy(0, 0, calldatasize())\\n\\n // Call the implementation.\\n // out and outsize are 0 because we don't know the size yet.\\n let result := delegatecall(gas(), implementation, 0, calldatasize(), 0, 0)\\n\\n // Copy the returned data.\\n returndatacopy(0, 0, returndatasize())\\n\\n switch result\\n // delegatecall returns 0 on error.\\n case 0 {\\n revert(0, returndatasize())\\n }\\n default {\\n return(0, returndatasize())\\n }\\n }\\n }\\n\\n /**\\n * @dev This is a virtual function that should be overridden so it returns the address to which the fallback function\\n * and {_fallback} should delegate.\\n */\\n function _implementation() internal view virtual returns (address);\\n\\n /**\\n * @dev Delegates the current call to the address returned by `_implementation()`.\\n *\\n * This function does not return to its internal call site, it will return directly to the external caller.\\n */\\n function _fallback() internal virtual {\\n _beforeFallback();\\n _delegate(_implementation());\\n }\\n\\n /**\\n * @dev Fallback function that delegates calls to the address returned by `_implementation()`. Will run if no other\\n * function in the contract matches the call data.\\n */\\n fallback() external payable virtual {\\n _fallback();\\n }\\n\\n /**\\n * @dev Fallback function that delegates calls to the address returned by `_implementation()`. Will run if call data\\n * is empty.\\n */\\n receive() external payable virtual {\\n _fallback();\\n }\\n\\n /**\\n * @dev Hook that is called before falling back to the implementation. Can happen as part of a manual `_fallback`\\n * call, or as part of the Solidity `fallback` or `receive` functions.\\n *\\n * If overridden should call `super._beforeFallback()`.\\n */\\n function _beforeFallback() internal virtual {}\\n}\\n\",\"keccak256\":\"0xc130fe33f1b2132158531a87734153293f6d07bc263ff4ac90e85da9c82c0e27\",\"license\":\"MIT\"},\"@openzeppelin/contracts/proxy/beacon/IBeacon.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (proxy/beacon/IBeacon.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev This is the interface that {BeaconProxy} expects of its beacon.\\n */\\ninterface IBeacon {\\n /**\\n * @dev Must return an address that can be used as a delegate call target.\\n *\\n * {BeaconProxy} will check that this address is a contract.\\n */\\n function implementation() external view returns (address);\\n}\\n\",\"keccak256\":\"0xd50a3421ac379ccb1be435fa646d66a65c986b4924f0849839f08692f39dde61\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/Address.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.7.0) (utils/Address.sol)\\n\\npragma solidity ^0.8.1;\\n\\n/**\\n * @dev Collection of functions related to the address type\\n */\\nlibrary Address {\\n /**\\n * @dev Returns true if `account` is a contract.\\n *\\n * [IMPORTANT]\\n * ====\\n * It is unsafe to assume that an address for which this function returns\\n * false is an externally-owned account (EOA) and not a contract.\\n *\\n * Among others, `isContract` will return false for the following\\n * types of addresses:\\n *\\n * - an externally-owned account\\n * - a contract in construction\\n * - an address where a contract will be created\\n * - an address where a contract lived, but was destroyed\\n * ====\\n *\\n * [IMPORTANT]\\n * ====\\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\\n *\\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\\n * constructor.\\n * ====\\n */\\n function isContract(address account) internal view returns (bool) {\\n // This method relies on extcodesize/address.code.length, which returns 0\\n // for contracts in construction, since the code is only stored at the end\\n // of the constructor execution.\\n\\n return account.code.length > 0;\\n }\\n\\n /**\\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\\n * `recipient`, forwarding all available gas and reverting on errors.\\n *\\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\\n * imposed by `transfer`, making them unable to receive funds via\\n * `transfer`. {sendValue} removes this limitation.\\n *\\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\\n *\\n * IMPORTANT: because control is transferred to `recipient`, care must be\\n * taken to not create reentrancy vulnerabilities. Consider using\\n * {ReentrancyGuard} or the\\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\\n */\\n function sendValue(address payable recipient, uint256 amount) internal {\\n require(address(this).balance >= amount, \\\"Address: insufficient balance\\\");\\n\\n (bool success, ) = recipient.call{value: amount}(\\\"\\\");\\n require(success, \\\"Address: unable to send value, recipient may have reverted\\\");\\n }\\n\\n /**\\n * @dev Performs a Solidity function call using a low level `call`. A\\n * plain `call` is an unsafe replacement for a function call: use this\\n * function instead.\\n *\\n * If `target` reverts with a revert reason, it is bubbled up by this\\n * function (like regular Solidity function calls).\\n *\\n * Returns the raw returned data. To convert to the expected return value,\\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\\n *\\n * Requirements:\\n *\\n * - `target` must be a contract.\\n * - calling `target` with `data` must not revert.\\n *\\n * _Available since v3.1._\\n */\\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\\n return functionCall(target, data, \\\"Address: low-level call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\\n * `errorMessage` as a fallback revert reason when `target` reverts.\\n *\\n * _Available since v3.1._\\n */\\n function functionCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n return functionCallWithValue(target, data, 0, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but also transferring `value` wei to `target`.\\n *\\n * Requirements:\\n *\\n * - the calling contract must have an ETH balance of at least `value`.\\n * - the called Solidity function must be `payable`.\\n *\\n * _Available since v3.1._\\n */\\n function functionCallWithValue(\\n address target,\\n bytes memory data,\\n uint256 value\\n ) internal returns (bytes memory) {\\n return functionCallWithValue(target, data, value, \\\"Address: low-level call with value failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\\n * with `errorMessage` as a fallback revert reason when `target` reverts.\\n *\\n * _Available since v3.1._\\n */\\n function functionCallWithValue(\\n address target,\\n bytes memory data,\\n uint256 value,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n require(address(this).balance >= value, \\\"Address: insufficient balance for call\\\");\\n require(isContract(target), \\\"Address: call to non-contract\\\");\\n\\n (bool success, bytes memory returndata) = target.call{value: value}(data);\\n return verifyCallResult(success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but performing a static call.\\n *\\n * _Available since v3.3._\\n */\\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\\n return functionStaticCall(target, data, \\\"Address: low-level static call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\\n * but performing a static call.\\n *\\n * _Available since v3.3._\\n */\\n function functionStaticCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal view returns (bytes memory) {\\n require(isContract(target), \\\"Address: static call to non-contract\\\");\\n\\n (bool success, bytes memory returndata) = target.staticcall(data);\\n return verifyCallResult(success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but performing a delegate call.\\n *\\n * _Available since v3.4._\\n */\\n function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {\\n return functionDelegateCall(target, data, \\\"Address: low-level delegate call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\\n * but performing a delegate call.\\n *\\n * _Available since v3.4._\\n */\\n function functionDelegateCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n require(isContract(target), \\\"Address: delegate call to non-contract\\\");\\n\\n (bool success, bytes memory returndata) = target.delegatecall(data);\\n return verifyCallResult(success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the\\n * revert reason using the provided one.\\n *\\n * _Available since v4.3._\\n */\\n function verifyCallResult(\\n bool success,\\n bytes memory returndata,\\n string memory errorMessage\\n ) internal pure returns (bytes memory) {\\n if (success) {\\n return returndata;\\n } else {\\n // Look for revert reason and bubble it up if present\\n if (returndata.length > 0) {\\n // The easiest way to bubble the revert reason is using memory via assembly\\n /// @solidity memory-safe-assembly\\n assembly {\\n let returndata_size := mload(returndata)\\n revert(add(32, returndata), returndata_size)\\n }\\n } else {\\n revert(errorMessage);\\n }\\n }\\n }\\n}\\n\",\"keccak256\":\"0xd6153ce99bcdcce22b124f755e72553295be6abcd63804cfdffceb188b8bef10\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/StorageSlot.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.7.0) (utils/StorageSlot.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Library for reading and writing primitive types to specific storage slots.\\n *\\n * Storage slots are often used to avoid storage conflict when dealing with upgradeable contracts.\\n * This library helps with reading and writing to such slots without the need for inline assembly.\\n *\\n * The functions in this library return Slot structs that contain a `value` member that can be used to read or write.\\n *\\n * Example usage to set ERC1967 implementation slot:\\n * ```\\n * contract ERC1967 {\\n * bytes32 internal constant _IMPLEMENTATION_SLOT = 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc;\\n *\\n * function _getImplementation() internal view returns (address) {\\n * return StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value;\\n * }\\n *\\n * function _setImplementation(address newImplementation) internal {\\n * require(Address.isContract(newImplementation), \\\"ERC1967: new implementation is not a contract\\\");\\n * StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value = newImplementation;\\n * }\\n * }\\n * ```\\n *\\n * _Available since v4.1 for `address`, `bool`, `bytes32`, and `uint256`._\\n */\\nlibrary StorageSlot {\\n struct AddressSlot {\\n address value;\\n }\\n\\n struct BooleanSlot {\\n bool value;\\n }\\n\\n struct Bytes32Slot {\\n bytes32 value;\\n }\\n\\n struct Uint256Slot {\\n uint256 value;\\n }\\n\\n /**\\n * @dev Returns an `AddressSlot` with member `value` located at `slot`.\\n */\\n function getAddressSlot(bytes32 slot) internal pure returns (AddressSlot storage r) {\\n /// @solidity memory-safe-assembly\\n assembly {\\n r.slot := slot\\n }\\n }\\n\\n /**\\n * @dev Returns an `BooleanSlot` with member `value` located at `slot`.\\n */\\n function getBooleanSlot(bytes32 slot) internal pure returns (BooleanSlot storage r) {\\n /// @solidity memory-safe-assembly\\n assembly {\\n r.slot := slot\\n }\\n }\\n\\n /**\\n * @dev Returns an `Bytes32Slot` with member `value` located at `slot`.\\n */\\n function getBytes32Slot(bytes32 slot) internal pure returns (Bytes32Slot storage r) {\\n /// @solidity memory-safe-assembly\\n assembly {\\n r.slot := slot\\n }\\n }\\n\\n /**\\n * @dev Returns an `Uint256Slot` with member `value` located at `slot`.\\n */\\n function getUint256Slot(bytes32 slot) internal pure returns (Uint256Slot storage r) {\\n /// @solidity memory-safe-assembly\\n assembly {\\n r.slot := slot\\n }\\n }\\n}\\n\",\"keccak256\":\"0xd5c50c54bf02740ebd122ff06832546cb5fa84486d52695a9ccfd11666e0c81d\",\"license\":\"MIT\"},\"contracts/external/TransparentUpgradeableProxy.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-3.0\\n\\npragma solidity ^0.8.12;\\n\\nimport \\\"@openzeppelin/contracts/proxy/ERC1967/ERC1967Proxy.sol\\\";\\n\\n/**\\n * @dev This contract implements a proxy that is upgradeable by an admin. It is fully forked from OpenZeppelin\\n * `TransparentUpgradeableProxy`\\n *\\n * To avoid https://medium.com/nomic-labs-blog/malicious-backdoors-in-ethereum-proxies-62629adf3357[proxy selector\\n * clashing], which can potentially be used in an attack, this contract uses the\\n * https://blog.openzeppelin.com/the-transparent-proxy-pattern/[transparent proxy pattern]. This pattern implies two\\n * things that go hand in hand:\\n *\\n * 1. If any account other than the admin calls the proxy, the call will be forwarded to the implementation, even if\\n * that call matches one of the admin functions exposed by the proxy itself.\\n * 2. If the admin calls the proxy, it can access the admin functions, but its calls will never be forwarded to the\\n * implementation. If the admin tries to call a function on the implementation it will fail with an error that says\\n * \\\"admin cannot fallback to proxy target\\\".\\n *\\n * These properties mean that the admin account can only be used for admin actions like upgrading the proxy or changing\\n * the admin, so it's best if it's a dedicated account that is not used for anything else. This will avoid headaches due\\n * to sudden errors when trying to call a function from the proxy implementation.\\n *\\n * Our recommendation is for the dedicated account to be an instance of the {ProxyAdmin} contract. If set up this way,\\n * you should think of the `ProxyAdmin` instance as the real administrative interface of your proxy.\\n */\\ncontract TransparentUpgradeableProxy is ERC1967Proxy {\\n /**\\n * @dev Initializes an upgradeable proxy managed by `_admin`, backed by the implementation at `_logic`, and\\n * optionally initialized with `_data` as explained in {ERC1967Proxy-constructor}.\\n */\\n constructor(address _logic, address admin_, bytes memory _data) payable ERC1967Proxy(_logic, _data) {\\n assert(_ADMIN_SLOT == bytes32(uint256(keccak256(\\\"eip1967.proxy.admin\\\")) - 1));\\n _changeAdmin(admin_);\\n }\\n\\n /**\\n * @dev Modifier used internally that will delegate the call to the implementation unless the sender is the admin.\\n */\\n modifier ifAdmin() {\\n if (msg.sender == _getAdmin()) {\\n _;\\n } else {\\n _fallback();\\n }\\n }\\n\\n /**\\n * @dev Returns the current admin.\\n *\\n * NOTE: Only the admin can call this function. See {ProxyAdmin-getProxyAdmin}.\\n *\\n * TIP: To get this value clients can read directly from the storage slot shown below (specified by EIP1967) using the\\n * https://eth.wiki/json-rpc/API#eth_getstorageat[`eth_getStorageAt`] RPC call.\\n * `0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103`\\n */\\n function admin() external ifAdmin returns (address admin_) {\\n admin_ = _getAdmin();\\n }\\n\\n /**\\n * @dev Returns the current implementation.\\n *\\n * NOTE: Only the admin can call this function. See {ProxyAdmin-getProxyImplementation}.\\n *\\n * TIP: To get this value clients can read directly from the storage slot shown below (specified by EIP1967) using the\\n * https://eth.wiki/json-rpc/API#eth_getstorageat[`eth_getStorageAt`] RPC call.\\n * `0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc`\\n */\\n function implementation() external ifAdmin returns (address implementation_) {\\n implementation_ = _implementation();\\n }\\n\\n /**\\n * @dev Changes the admin of the proxy.\\n *\\n * Emits an {AdminChanged} event.\\n *\\n * NOTE: Only the admin can call this function. See {ProxyAdmin-changeProxyAdmin}.\\n */\\n function changeAdmin(address newAdmin) external virtual ifAdmin {\\n _changeAdmin(newAdmin);\\n }\\n\\n /**\\n * @dev Upgrade the implementation of the proxy.\\n *\\n * NOTE: Only the admin can call this function. See {ProxyAdmin-upgrade}.\\n */\\n function upgradeTo(address newImplementation) external ifAdmin {\\n _upgradeToAndCall(newImplementation, bytes(\\\"\\\"), false);\\n }\\n\\n /**\\n * @dev Upgrade the implementation of the proxy, and then call a function from the new implementation as specified\\n * by `data`, which should be an encoded function call. This is useful to initialize new storage variables in the\\n * proxied contract.\\n *\\n * NOTE: Only the admin can call this function. See {ProxyAdmin-upgradeAndCall}.\\n */\\n function upgradeToAndCall(address newImplementation, bytes calldata data) external payable ifAdmin {\\n _upgradeToAndCall(newImplementation, data, true);\\n }\\n\\n /**\\n * @dev Returns the current admin.\\n */\\n function _admin() internal view virtual returns (address) {\\n return _getAdmin();\\n }\\n\\n /**\\n * @dev Makes sure the admin cannot access the fallback function. See {Proxy-_beforeFallback}.\\n */\\n function _beforeFallback() internal virtual override {\\n require(msg.sender != _getAdmin(), \\\"TransparentUpgradeableProxy: admin cannot fallback to proxy target\\\");\\n super._beforeFallback();\\n }\\n}\\n\",\"keccak256\":\"0x93a67a0f612ea3ff2a76315e138a6a88267270a1379d3cc7be52845fbbe611e2\",\"license\":\"GPL-3.0\"}},\"version\":1}", + "bytecode": "0x6080604052604051620010bb380380620010bb8339810160408190526200002691620004d8565b828162000036828260006200009a565b5062000066905060017fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6104620005b8565b6000805160206200107483398151915214620000865762000086620005da565b6200009182620000d7565b50505062000643565b620000a58362000132565b600082511180620000b35750805b15620000d257620000d083836200017460201b6200028c1760201c565b505b505050565b7f7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f62000102620001a5565b604080516001600160a01b03928316815291841660208301520160405180910390a16200012f81620001de565b50565b6200013d8162000293565b6040516001600160a01b038216907fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b90600090a250565b60606200019c8383604051806060016040528060278152602001620010946027913962000347565b90505b92915050565b6000620001cf6000805160206200107483398151915260001b6200042f60201b6200022e1760201c565b546001600160a01b0316919050565b6001600160a01b038116620002495760405162461bcd60e51b815260206004820152602660248201527f455243313936373a206e65772061646d696e20697320746865207a65726f206160448201526564647265737360d01b60648201526084015b60405180910390fd5b80620002726000805160206200107483398151915260001b6200042f60201b6200022e1760201c565b80546001600160a01b0319166001600160a01b039290921691909117905550565b620002a9816200043260201b620002b81760201c565b6200030d5760405162461bcd60e51b815260206004820152602d60248201527f455243313936373a206e657720696d706c656d656e746174696f6e206973206e60448201526c1bdd08184818dbdb9d1c9858dd609a1b606482015260840162000240565b80620002727f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc60001b6200042f60201b6200022e1760201c565b60606001600160a01b0384163b620003b15760405162461bcd60e51b815260206004820152602660248201527f416464726573733a2064656c65676174652063616c6c20746f206e6f6e2d636f6044820152651b9d1c9858dd60d21b606482015260840162000240565b600080856001600160a01b031685604051620003ce9190620005f0565b600060405180830381855af49150503d80600081146200040b576040519150601f19603f3d011682016040523d82523d6000602084013e62000410565b606091505b5090925090506200042382828662000441565b925050505b9392505050565b90565b6001600160a01b03163b151590565b606083156200045257508162000428565b825115620004635782518084602001fd5b8160405162461bcd60e51b81526004016200024091906200060e565b80516001600160a01b03811681146200049757600080fd5b919050565b634e487b7160e01b600052604160045260246000fd5b60005b83811015620004cf578181015183820152602001620004b5565b50506000910152565b600080600060608486031215620004ee57600080fd5b620004f9846200047f565b925062000509602085016200047f565b60408501519092506001600160401b03808211156200052757600080fd5b818601915086601f8301126200053c57600080fd5b8151818111156200055157620005516200049c565b604051601f8201601f19908116603f011681019083821181831017156200057c576200057c6200049c565b816040528281528960208487010111156200059657600080fd5b620005a9836020830160208801620004b2565b80955050505050509250925092565b818103818111156200019f57634e487b7160e01b600052601160045260246000fd5b634e487b7160e01b600052600160045260246000fd5b6000825162000604818460208701620004b2565b9190910192915050565b60208152600082518060208401526200062f816040850160208701620004b2565b601f01601f19169190910160400192915050565b610a2180620006536000396000f3fe60806040526004361061005e5760003560e01c80635c60da1b116100435780635c60da1b146100a85780638f283970146100e6578063f851a440146101065761006d565b80633659cfe6146100755780634f1ef286146100955761006d565b3661006d5761006b61011b565b005b61006b61011b565b34801561008157600080fd5b5061006b610090366004610895565b610135565b61006b6100a33660046108b0565b61017f565b3480156100b457600080fd5b506100bd6101f3565b60405173ffffffffffffffffffffffffffffffffffffffff909116815260200160405180910390f35b3480156100f257600080fd5b5061006b610101366004610895565b610231565b34801561011257600080fd5b506100bd61025e565b6101236102d4565b61013361012e6103ab565b6103b5565b565b61013d6103d9565b73ffffffffffffffffffffffffffffffffffffffff1633036101775761017481604051806020016040528060008152506000610419565b50565b61017461011b565b6101876103d9565b73ffffffffffffffffffffffffffffffffffffffff1633036101eb576101e68383838080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525060019250610419915050565b505050565b6101e661011b565b60006101fd6103d9565b73ffffffffffffffffffffffffffffffffffffffff163303610226576102216103ab565b905090565b61022e61011b565b90565b6102396103d9565b73ffffffffffffffffffffffffffffffffffffffff1633036101775761017481610444565b60006102686103d9565b73ffffffffffffffffffffffffffffffffffffffff163303610226576102216103d9565b60606102b183836040518060600160405280602781526020016109c5602791396104a5565b9392505050565b73ffffffffffffffffffffffffffffffffffffffff163b151590565b6102dc6103d9565b73ffffffffffffffffffffffffffffffffffffffff163303610133576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604260248201527f5472616e73706172656e745570677261646561626c6550726f78793a2061646d60448201527f696e2063616e6e6f742066616c6c6261636b20746f2070726f7879207461726760648201527f6574000000000000000000000000000000000000000000000000000000000000608482015260a4015b60405180910390fd5b60006102216105cd565b3660008037600080366000845af43d6000803e8080156103d4573d6000f35b3d6000fd5b60007fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035b5473ffffffffffffffffffffffffffffffffffffffff16919050565b610422836105f5565b60008251118061042f5750805b156101e65761043e838361028c565b50505050565b7f7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f61046d6103d9565b6040805173ffffffffffffffffffffffffffffffffffffffff928316815291841660208301520160405180910390a161017481610642565b606073ffffffffffffffffffffffffffffffffffffffff84163b61054b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f416464726573733a2064656c65676174652063616c6c20746f206e6f6e2d636f60448201527f6e7472616374000000000000000000000000000000000000000000000000000060648201526084016103a2565b6000808573ffffffffffffffffffffffffffffffffffffffff16856040516105739190610957565b600060405180830381855af49150503d80600081146105ae576040519150601f19603f3d011682016040523d82523d6000602084013e6105b3565b606091505b50915091506105c382828661074e565b9695505050505050565b60007f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc6103fd565b6105fe816107a1565b60405173ffffffffffffffffffffffffffffffffffffffff8216907fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b90600090a250565b73ffffffffffffffffffffffffffffffffffffffff81166106e5576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f455243313936373a206e65772061646d696e20697320746865207a65726f206160448201527f646472657373000000000000000000000000000000000000000000000000000060648201526084016103a2565b807fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035b80547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff9290921691909117905550565b6060831561075d5750816102b1565b82511561076d5782518084602001fd5b816040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016103a29190610973565b73ffffffffffffffffffffffffffffffffffffffff81163b610845576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602d60248201527f455243313936373a206e657720696d706c656d656e746174696f6e206973206e60448201527f6f74206120636f6e74726163740000000000000000000000000000000000000060648201526084016103a2565b807f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc610708565b803573ffffffffffffffffffffffffffffffffffffffff8116811461089057600080fd5b919050565b6000602082840312156108a757600080fd5b6102b18261086c565b6000806000604084860312156108c557600080fd5b6108ce8461086c565b9250602084013567ffffffffffffffff808211156108eb57600080fd5b818601915086601f8301126108ff57600080fd5b81358181111561090e57600080fd5b87602082850101111561092057600080fd5b6020830194508093505050509250925092565b60005b8381101561094e578181015183820152602001610936565b50506000910152565b60008251610969818460208701610933565b9190910192915050565b6020815260008251806020840152610992816040850160208701610933565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016919091016040019291505056fe416464726573733a206c6f772d6c6576656c2064656c65676174652063616c6c206661696c6564a2646970667358221220e96638b07fb1675d93a95c49e417bc8111448b23a59918698cdcd8fd488dd7cf64736f6c63430008110033b53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103416464726573733a206c6f772d6c6576656c2064656c65676174652063616c6c206661696c6564", + "deployedBytecode": "0x60806040526004361061005e5760003560e01c80635c60da1b116100435780635c60da1b146100a85780638f283970146100e6578063f851a440146101065761006d565b80633659cfe6146100755780634f1ef286146100955761006d565b3661006d5761006b61011b565b005b61006b61011b565b34801561008157600080fd5b5061006b610090366004610895565b610135565b61006b6100a33660046108b0565b61017f565b3480156100b457600080fd5b506100bd6101f3565b60405173ffffffffffffffffffffffffffffffffffffffff909116815260200160405180910390f35b3480156100f257600080fd5b5061006b610101366004610895565b610231565b34801561011257600080fd5b506100bd61025e565b6101236102d4565b61013361012e6103ab565b6103b5565b565b61013d6103d9565b73ffffffffffffffffffffffffffffffffffffffff1633036101775761017481604051806020016040528060008152506000610419565b50565b61017461011b565b6101876103d9565b73ffffffffffffffffffffffffffffffffffffffff1633036101eb576101e68383838080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525060019250610419915050565b505050565b6101e661011b565b60006101fd6103d9565b73ffffffffffffffffffffffffffffffffffffffff163303610226576102216103ab565b905090565b61022e61011b565b90565b6102396103d9565b73ffffffffffffffffffffffffffffffffffffffff1633036101775761017481610444565b60006102686103d9565b73ffffffffffffffffffffffffffffffffffffffff163303610226576102216103d9565b60606102b183836040518060600160405280602781526020016109c5602791396104a5565b9392505050565b73ffffffffffffffffffffffffffffffffffffffff163b151590565b6102dc6103d9565b73ffffffffffffffffffffffffffffffffffffffff163303610133576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604260248201527f5472616e73706172656e745570677261646561626c6550726f78793a2061646d60448201527f696e2063616e6e6f742066616c6c6261636b20746f2070726f7879207461726760648201527f6574000000000000000000000000000000000000000000000000000000000000608482015260a4015b60405180910390fd5b60006102216105cd565b3660008037600080366000845af43d6000803e8080156103d4573d6000f35b3d6000fd5b60007fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035b5473ffffffffffffffffffffffffffffffffffffffff16919050565b610422836105f5565b60008251118061042f5750805b156101e65761043e838361028c565b50505050565b7f7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f61046d6103d9565b6040805173ffffffffffffffffffffffffffffffffffffffff928316815291841660208301520160405180910390a161017481610642565b606073ffffffffffffffffffffffffffffffffffffffff84163b61054b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f416464726573733a2064656c65676174652063616c6c20746f206e6f6e2d636f60448201527f6e7472616374000000000000000000000000000000000000000000000000000060648201526084016103a2565b6000808573ffffffffffffffffffffffffffffffffffffffff16856040516105739190610957565b600060405180830381855af49150503d80600081146105ae576040519150601f19603f3d011682016040523d82523d6000602084013e6105b3565b606091505b50915091506105c382828661074e565b9695505050505050565b60007f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc6103fd565b6105fe816107a1565b60405173ffffffffffffffffffffffffffffffffffffffff8216907fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b90600090a250565b73ffffffffffffffffffffffffffffffffffffffff81166106e5576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f455243313936373a206e65772061646d696e20697320746865207a65726f206160448201527f646472657373000000000000000000000000000000000000000000000000000060648201526084016103a2565b807fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035b80547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff9290921691909117905550565b6060831561075d5750816102b1565b82511561076d5782518084602001fd5b816040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016103a29190610973565b73ffffffffffffffffffffffffffffffffffffffff81163b610845576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602d60248201527f455243313936373a206e657720696d706c656d656e746174696f6e206973206e60448201527f6f74206120636f6e74726163740000000000000000000000000000000000000060648201526084016103a2565b807f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc610708565b803573ffffffffffffffffffffffffffffffffffffffff8116811461089057600080fd5b919050565b6000602082840312156108a757600080fd5b6102b18261086c565b6000806000604084860312156108c557600080fd5b6108ce8461086c565b9250602084013567ffffffffffffffff808211156108eb57600080fd5b818601915086601f8301126108ff57600080fd5b81358181111561090e57600080fd5b87602082850101111561092057600080fd5b6020830194508093505050509250925092565b60005b8381101561094e578181015183820152602001610936565b50506000910152565b60008251610969818460208701610933565b9190910192915050565b6020815260008251806020840152610992816040850160208701610933565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016919091016040019291505056fe416464726573733a206c6f772d6c6576656c2064656c65676174652063616c6c206661696c6564a2646970667358221220e96638b07fb1675d93a95c49e417bc8111448b23a59918698cdcd8fd488dd7cf64736f6c63430008110033", + "devdoc": { + "details": "This contract implements a proxy that is upgradeable by an admin. It is fully forked from OpenZeppelin `TransparentUpgradeableProxy` To avoid https://medium.com/nomic-labs-blog/malicious-backdoors-in-ethereum-proxies-62629adf3357[proxy selector clashing], which can potentially be used in an attack, this contract uses the https://blog.openzeppelin.com/the-transparent-proxy-pattern/[transparent proxy pattern]. This pattern implies two things that go hand in hand: 1. If any account other than the admin calls the proxy, the call will be forwarded to the implementation, even if that call matches one of the admin functions exposed by the proxy itself. 2. If the admin calls the proxy, it can access the admin functions, but its calls will never be forwarded to the implementation. If the admin tries to call a function on the implementation it will fail with an error that says \"admin cannot fallback to proxy target\". These properties mean that the admin account can only be used for admin actions like upgrading the proxy or changing the admin, so it's best if it's a dedicated account that is not used for anything else. This will avoid headaches due to sudden errors when trying to call a function from the proxy implementation. Our recommendation is for the dedicated account to be an instance of the {ProxyAdmin} contract. If set up this way, you should think of the `ProxyAdmin` instance as the real administrative interface of your proxy.", + "kind": "dev", + "methods": { + "admin()": { + "details": "Returns the current admin. NOTE: Only the admin can call this function. See {ProxyAdmin-getProxyAdmin}. TIP: To get this value clients can read directly from the storage slot shown below (specified by EIP1967) using the https://eth.wiki/json-rpc/API#eth_getstorageat[`eth_getStorageAt`] RPC call. `0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103`" + }, + "changeAdmin(address)": { + "details": "Changes the admin of the proxy. Emits an {AdminChanged} event. NOTE: Only the admin can call this function. See {ProxyAdmin-changeProxyAdmin}." + }, + "constructor": { + "details": "Initializes an upgradeable proxy managed by `_admin`, backed by the implementation at `_logic`, and optionally initialized with `_data` as explained in {ERC1967Proxy-constructor}." + }, + "implementation()": { + "details": "Returns the current implementation. NOTE: Only the admin can call this function. See {ProxyAdmin-getProxyImplementation}. TIP: To get this value clients can read directly from the storage slot shown below (specified by EIP1967) using the https://eth.wiki/json-rpc/API#eth_getstorageat[`eth_getStorageAt`] RPC call. `0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc`" + }, + "upgradeTo(address)": { + "details": "Upgrade the implementation of the proxy. NOTE: Only the admin can call this function. See {ProxyAdmin-upgrade}." + }, + "upgradeToAndCall(address,bytes)": { + "details": "Upgrade the implementation of the proxy, and then call a function from the new implementation as specified by `data`, which should be an encoded function call. This is useful to initialize new storage variables in the proxied contract. NOTE: Only the admin can call this function. See {ProxyAdmin-upgradeAndCall}." + } + }, + "version": 1 + }, + "userdoc": { + "kind": "user", + "methods": {}, + "version": 1 + }, + "storageLayout": { + "storage": [], + "types": null + } +} \ No newline at end of file diff --git a/deployments/mainnet/LayerZeroBridge_USD.json b/deployments/mainnet/LayerZeroBridge_USD.json new file mode 100644 index 00000000..e23466c6 --- /dev/null +++ b/deployments/mainnet/LayerZeroBridge_USD.json @@ -0,0 +1,235 @@ +{ + "address": "0xEc0B13b2271E212E1a74D55D51932BD52A002961", + "abi": [ + { + "inputs": [ + { + "internalType": "address", + "name": "_logic", + "type": "address" + }, + { + "internalType": "address", + "name": "admin_", + "type": "address" + }, + { + "internalType": "bytes", + "name": "_data", + "type": "bytes" + } + ], + "stateMutability": "payable", + "type": "constructor" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "previousAdmin", + "type": "address" + }, + { + "indexed": false, + "internalType": "address", + "name": "newAdmin", + "type": "address" + } + ], + "name": "AdminChanged", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "beacon", + "type": "address" + } + ], + "name": "BeaconUpgraded", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "implementation", + "type": "address" + } + ], + "name": "Upgraded", + "type": "event" + }, + { + "stateMutability": "payable", + "type": "fallback" + }, + { + "inputs": [], + "name": "admin", + "outputs": [ + { + "internalType": "address", + "name": "admin_", + "type": "address" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "newAdmin", + "type": "address" + } + ], + "name": "changeAdmin", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "implementation", + "outputs": [ + { + "internalType": "address", + "name": "implementation_", + "type": "address" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "newImplementation", + "type": "address" + } + ], + "name": "upgradeTo", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "newImplementation", + "type": "address" + }, + { + "internalType": "bytes", + "name": "data", + "type": "bytes" + } + ], + "name": "upgradeToAndCall", + "outputs": [], + "stateMutability": "payable", + "type": "function" + }, + { + "stateMutability": "payable", + "type": "receive" + } + ], + "transactionHash": "0x08860f500217423df14fb24fa2b74434c3fc7b8faa87b2401fa4cb35cbecc891", + "receipt": { + "to": null, + "from": "0xfdA462548Ce04282f4B6D6619823a7C64Fdc0185", + "contractAddress": "0xEc0B13b2271E212E1a74D55D51932BD52A002961", + "transactionIndex": 82, + "gasUsed": "793930", + "logsBloom": "0x00000000000000400000000000000000400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004000000000000000000020000002000000000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000100000000000000000000800000000000000000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000400000000000000000000800000000000000400000000000000000000000000000000000000000000000000", + "blockHash": "0x05c541af5f58c4df3a14a101ec76ec4220532b7b333d432dbc0586ca8fe27a44", + "transactionHash": "0x08860f500217423df14fb24fa2b74434c3fc7b8faa87b2401fa4cb35cbecc891", + "logs": [ + { + "transactionIndex": 82, + "blockNumber": 18975619, + "transactionHash": "0x08860f500217423df14fb24fa2b74434c3fc7b8faa87b2401fa4cb35cbecc891", + "address": "0xEc0B13b2271E212E1a74D55D51932BD52A002961", + "topics": [ + "0xbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b", + "0x000000000000000000000000d735611ae930d2fd3788aabf7696e6d8f664d15e" + ], + "data": "0x", + "logIndex": 194, + "blockHash": "0x05c541af5f58c4df3a14a101ec76ec4220532b7b333d432dbc0586ca8fe27a44" + }, + { + "transactionIndex": 82, + "blockNumber": 18975619, + "transactionHash": "0x08860f500217423df14fb24fa2b74434c3fc7b8faa87b2401fa4cb35cbecc891", + "address": "0xEc0B13b2271E212E1a74D55D51932BD52A002961", + "topics": [ + "0x7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f" + ], + "data": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000001d941ef0d3bba4ad67dbfbcee5262f4cee53a32b", + "logIndex": 195, + "blockHash": "0x05c541af5f58c4df3a14a101ec76ec4220532b7b333d432dbc0586ca8fe27a44" + } + ], + "blockNumber": 18975619, + "cumulativeGasUsed": "7762934", + "status": 1, + "byzantium": true + }, + "args": [ + "0xd735611AE930D2fd3788AAbf7696e6D8f664d15e", + "0x1D941EF0D3Bba4ad67DBfBCeE5262F4CEE53A32b", + "0x463fd1af000000000000000000000000000000000000000000000000000000000000006000000000000000000000000066a71dcef29a0ffbdbe3c6a460a3b5bc225cd675000000000000000000000000f8588520e760bb0b3bdd62ecb25186a28b0830ee00000000000000000000000000000000000000000000000000000000000000164c617965725a65726f2042726964676520616755534400000000000000000000" + ], + "numDeployments": 1, + "solcInputHash": "871924e0c138825a2736b76def8fef8d", + "metadata": "{\"compiler\":{\"version\":\"0.8.17+commit.8df45f5f\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_logic\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"admin_\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"_data\",\"type\":\"bytes\"}],\"stateMutability\":\"payable\",\"type\":\"constructor\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"previousAdmin\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"newAdmin\",\"type\":\"address\"}],\"name\":\"AdminChanged\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"beacon\",\"type\":\"address\"}],\"name\":\"BeaconUpgraded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"implementation\",\"type\":\"address\"}],\"name\":\"Upgraded\",\"type\":\"event\"},{\"stateMutability\":\"payable\",\"type\":\"fallback\"},{\"inputs\":[],\"name\":\"admin\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"admin_\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newAdmin\",\"type\":\"address\"}],\"name\":\"changeAdmin\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"implementation\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"implementation_\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newImplementation\",\"type\":\"address\"}],\"name\":\"upgradeTo\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newImplementation\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"}],\"name\":\"upgradeToAndCall\",\"outputs\":[],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"stateMutability\":\"payable\",\"type\":\"receive\"}],\"devdoc\":{\"details\":\"This contract implements a proxy that is upgradeable by an admin. It is fully forked from OpenZeppelin `TransparentUpgradeableProxy` To avoid https://medium.com/nomic-labs-blog/malicious-backdoors-in-ethereum-proxies-62629adf3357[proxy selector clashing], which can potentially be used in an attack, this contract uses the https://blog.openzeppelin.com/the-transparent-proxy-pattern/[transparent proxy pattern]. This pattern implies two things that go hand in hand: 1. If any account other than the admin calls the proxy, the call will be forwarded to the implementation, even if that call matches one of the admin functions exposed by the proxy itself. 2. If the admin calls the proxy, it can access the admin functions, but its calls will never be forwarded to the implementation. If the admin tries to call a function on the implementation it will fail with an error that says \\\"admin cannot fallback to proxy target\\\". These properties mean that the admin account can only be used for admin actions like upgrading the proxy or changing the admin, so it's best if it's a dedicated account that is not used for anything else. This will avoid headaches due to sudden errors when trying to call a function from the proxy implementation. Our recommendation is for the dedicated account to be an instance of the {ProxyAdmin} contract. If set up this way, you should think of the `ProxyAdmin` instance as the real administrative interface of your proxy.\",\"kind\":\"dev\",\"methods\":{\"admin()\":{\"details\":\"Returns the current admin. NOTE: Only the admin can call this function. See {ProxyAdmin-getProxyAdmin}. TIP: To get this value clients can read directly from the storage slot shown below (specified by EIP1967) using the https://eth.wiki/json-rpc/API#eth_getstorageat[`eth_getStorageAt`] RPC call. `0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103`\"},\"changeAdmin(address)\":{\"details\":\"Changes the admin of the proxy. Emits an {AdminChanged} event. NOTE: Only the admin can call this function. See {ProxyAdmin-changeProxyAdmin}.\"},\"constructor\":{\"details\":\"Initializes an upgradeable proxy managed by `_admin`, backed by the implementation at `_logic`, and optionally initialized with `_data` as explained in {ERC1967Proxy-constructor}.\"},\"implementation()\":{\"details\":\"Returns the current implementation. NOTE: Only the admin can call this function. See {ProxyAdmin-getProxyImplementation}. TIP: To get this value clients can read directly from the storage slot shown below (specified by EIP1967) using the https://eth.wiki/json-rpc/API#eth_getstorageat[`eth_getStorageAt`] RPC call. `0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc`\"},\"upgradeTo(address)\":{\"details\":\"Upgrade the implementation of the proxy. NOTE: Only the admin can call this function. See {ProxyAdmin-upgrade}.\"},\"upgradeToAndCall(address,bytes)\":{\"details\":\"Upgrade the implementation of the proxy, and then call a function from the new implementation as specified by `data`, which should be an encoded function call. This is useful to initialize new storage variables in the proxied contract. NOTE: Only the admin can call this function. See {ProxyAdmin-upgradeAndCall}.\"}},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/external/TransparentUpgradeableProxy.sol\":\"TransparentUpgradeableProxy\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":1000000},\"remappings\":[]},\"sources\":{\"@openzeppelin/contracts/interfaces/draft-IERC1822.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.5.0) (interfaces/draft-IERC1822.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev ERC1822: Universal Upgradeable Proxy Standard (UUPS) documents a method for upgradeability through a simplified\\n * proxy whose upgrades are fully controlled by the current implementation.\\n */\\ninterface IERC1822Proxiable {\\n /**\\n * @dev Returns the storage slot that the proxiable contract assumes is being used to store the implementation\\n * address.\\n *\\n * IMPORTANT: A proxy pointing at a proxiable contract should not be considered proxiable itself, because this risks\\n * bricking a proxy that upgrades to it, by delegating to itself until out of gas. Thus it is critical that this\\n * function revert if invoked through a proxy.\\n */\\n function proxiableUUID() external view returns (bytes32);\\n}\\n\",\"keccak256\":\"0x1d4afe6cb24200cc4545eed814ecf5847277dfe5d613a1707aad5fceecebcfff\",\"license\":\"MIT\"},\"@openzeppelin/contracts/proxy/ERC1967/ERC1967Proxy.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.7.0) (proxy/ERC1967/ERC1967Proxy.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../Proxy.sol\\\";\\nimport \\\"./ERC1967Upgrade.sol\\\";\\n\\n/**\\n * @dev This contract implements an upgradeable proxy. It is upgradeable because calls are delegated to an\\n * implementation address that can be changed. This address is stored in storage in the location specified by\\n * https://eips.ethereum.org/EIPS/eip-1967[EIP1967], so that it doesn't conflict with the storage layout of the\\n * implementation behind the proxy.\\n */\\ncontract ERC1967Proxy is Proxy, ERC1967Upgrade {\\n /**\\n * @dev Initializes the upgradeable proxy with an initial implementation specified by `_logic`.\\n *\\n * If `_data` is nonempty, it's used as data in a delegate call to `_logic`. This will typically be an encoded\\n * function call, and allows initializing the storage of the proxy like a Solidity constructor.\\n */\\n constructor(address _logic, bytes memory _data) payable {\\n _upgradeToAndCall(_logic, _data, false);\\n }\\n\\n /**\\n * @dev Returns the current implementation address.\\n */\\n function _implementation() internal view virtual override returns (address impl) {\\n return ERC1967Upgrade._getImplementation();\\n }\\n}\\n\",\"keccak256\":\"0xa2b22da3032e50b55f95ec1d13336102d675f341167aa76db571ef7f8bb7975d\",\"license\":\"MIT\"},\"@openzeppelin/contracts/proxy/ERC1967/ERC1967Upgrade.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.5.0) (proxy/ERC1967/ERC1967Upgrade.sol)\\n\\npragma solidity ^0.8.2;\\n\\nimport \\\"../beacon/IBeacon.sol\\\";\\nimport \\\"../../interfaces/draft-IERC1822.sol\\\";\\nimport \\\"../../utils/Address.sol\\\";\\nimport \\\"../../utils/StorageSlot.sol\\\";\\n\\n/**\\n * @dev This abstract contract provides getters and event emitting update functions for\\n * https://eips.ethereum.org/EIPS/eip-1967[EIP1967] slots.\\n *\\n * _Available since v4.1._\\n *\\n * @custom:oz-upgrades-unsafe-allow delegatecall\\n */\\nabstract contract ERC1967Upgrade {\\n // This is the keccak-256 hash of \\\"eip1967.proxy.rollback\\\" subtracted by 1\\n bytes32 private constant _ROLLBACK_SLOT = 0x4910fdfa16fed3260ed0e7147f7cc6da11a60208b5b9406d12a635614ffd9143;\\n\\n /**\\n * @dev Storage slot with the address of the current implementation.\\n * This is the keccak-256 hash of \\\"eip1967.proxy.implementation\\\" subtracted by 1, and is\\n * validated in the constructor.\\n */\\n bytes32 internal constant _IMPLEMENTATION_SLOT = 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc;\\n\\n /**\\n * @dev Emitted when the implementation is upgraded.\\n */\\n event Upgraded(address indexed implementation);\\n\\n /**\\n * @dev Returns the current implementation address.\\n */\\n function _getImplementation() internal view returns (address) {\\n return StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value;\\n }\\n\\n /**\\n * @dev Stores a new address in the EIP1967 implementation slot.\\n */\\n function _setImplementation(address newImplementation) private {\\n require(Address.isContract(newImplementation), \\\"ERC1967: new implementation is not a contract\\\");\\n StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value = newImplementation;\\n }\\n\\n /**\\n * @dev Perform implementation upgrade\\n *\\n * Emits an {Upgraded} event.\\n */\\n function _upgradeTo(address newImplementation) internal {\\n _setImplementation(newImplementation);\\n emit Upgraded(newImplementation);\\n }\\n\\n /**\\n * @dev Perform implementation upgrade with additional setup call.\\n *\\n * Emits an {Upgraded} event.\\n */\\n function _upgradeToAndCall(\\n address newImplementation,\\n bytes memory data,\\n bool forceCall\\n ) internal {\\n _upgradeTo(newImplementation);\\n if (data.length > 0 || forceCall) {\\n Address.functionDelegateCall(newImplementation, data);\\n }\\n }\\n\\n /**\\n * @dev Perform implementation upgrade with security checks for UUPS proxies, and additional setup call.\\n *\\n * Emits an {Upgraded} event.\\n */\\n function _upgradeToAndCallUUPS(\\n address newImplementation,\\n bytes memory data,\\n bool forceCall\\n ) internal {\\n // Upgrades from old implementations will perform a rollback test. This test requires the new\\n // implementation to upgrade back to the old, non-ERC1822 compliant, implementation. Removing\\n // this special case will break upgrade paths from old UUPS implementation to new ones.\\n if (StorageSlot.getBooleanSlot(_ROLLBACK_SLOT).value) {\\n _setImplementation(newImplementation);\\n } else {\\n try IERC1822Proxiable(newImplementation).proxiableUUID() returns (bytes32 slot) {\\n require(slot == _IMPLEMENTATION_SLOT, \\\"ERC1967Upgrade: unsupported proxiableUUID\\\");\\n } catch {\\n revert(\\\"ERC1967Upgrade: new implementation is not UUPS\\\");\\n }\\n _upgradeToAndCall(newImplementation, data, forceCall);\\n }\\n }\\n\\n /**\\n * @dev Storage slot with the admin of the contract.\\n * This is the keccak-256 hash of \\\"eip1967.proxy.admin\\\" subtracted by 1, and is\\n * validated in the constructor.\\n */\\n bytes32 internal constant _ADMIN_SLOT = 0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103;\\n\\n /**\\n * @dev Emitted when the admin account has changed.\\n */\\n event AdminChanged(address previousAdmin, address newAdmin);\\n\\n /**\\n * @dev Returns the current admin.\\n */\\n function _getAdmin() internal view returns (address) {\\n return StorageSlot.getAddressSlot(_ADMIN_SLOT).value;\\n }\\n\\n /**\\n * @dev Stores a new address in the EIP1967 admin slot.\\n */\\n function _setAdmin(address newAdmin) private {\\n require(newAdmin != address(0), \\\"ERC1967: new admin is the zero address\\\");\\n StorageSlot.getAddressSlot(_ADMIN_SLOT).value = newAdmin;\\n }\\n\\n /**\\n * @dev Changes the admin of the proxy.\\n *\\n * Emits an {AdminChanged} event.\\n */\\n function _changeAdmin(address newAdmin) internal {\\n emit AdminChanged(_getAdmin(), newAdmin);\\n _setAdmin(newAdmin);\\n }\\n\\n /**\\n * @dev The storage slot of the UpgradeableBeacon contract which defines the implementation for this proxy.\\n * This is bytes32(uint256(keccak256('eip1967.proxy.beacon')) - 1)) and is validated in the constructor.\\n */\\n bytes32 internal constant _BEACON_SLOT = 0xa3f0ad74e5423aebfd80d3ef4346578335a9a72aeaee59ff6cb3582b35133d50;\\n\\n /**\\n * @dev Emitted when the beacon is upgraded.\\n */\\n event BeaconUpgraded(address indexed beacon);\\n\\n /**\\n * @dev Returns the current beacon.\\n */\\n function _getBeacon() internal view returns (address) {\\n return StorageSlot.getAddressSlot(_BEACON_SLOT).value;\\n }\\n\\n /**\\n * @dev Stores a new beacon in the EIP1967 beacon slot.\\n */\\n function _setBeacon(address newBeacon) private {\\n require(Address.isContract(newBeacon), \\\"ERC1967: new beacon is not a contract\\\");\\n require(\\n Address.isContract(IBeacon(newBeacon).implementation()),\\n \\\"ERC1967: beacon implementation is not a contract\\\"\\n );\\n StorageSlot.getAddressSlot(_BEACON_SLOT).value = newBeacon;\\n }\\n\\n /**\\n * @dev Perform beacon upgrade with additional setup call. Note: This upgrades the address of the beacon, it does\\n * not upgrade the implementation contained in the beacon (see {UpgradeableBeacon-_setImplementation} for that).\\n *\\n * Emits a {BeaconUpgraded} event.\\n */\\n function _upgradeBeaconToAndCall(\\n address newBeacon,\\n bytes memory data,\\n bool forceCall\\n ) internal {\\n _setBeacon(newBeacon);\\n emit BeaconUpgraded(newBeacon);\\n if (data.length > 0 || forceCall) {\\n Address.functionDelegateCall(IBeacon(newBeacon).implementation(), data);\\n }\\n }\\n}\\n\",\"keccak256\":\"0xabf3f59bc0e5423eae45e459dbe92e7052c6983628d39008590edc852a62f94a\",\"license\":\"MIT\"},\"@openzeppelin/contracts/proxy/Proxy.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.6.0) (proxy/Proxy.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev This abstract contract provides a fallback function that delegates all calls to another contract using the EVM\\n * instruction `delegatecall`. We refer to the second contract as the _implementation_ behind the proxy, and it has to\\n * be specified by overriding the virtual {_implementation} function.\\n *\\n * Additionally, delegation to the implementation can be triggered manually through the {_fallback} function, or to a\\n * different contract through the {_delegate} function.\\n *\\n * The success and return data of the delegated call will be returned back to the caller of the proxy.\\n */\\nabstract contract Proxy {\\n /**\\n * @dev Delegates the current call to `implementation`.\\n *\\n * This function does not return to its internal call site, it will return directly to the external caller.\\n */\\n function _delegate(address implementation) internal virtual {\\n assembly {\\n // Copy msg.data. We take full control of memory in this inline assembly\\n // block because it will not return to Solidity code. We overwrite the\\n // Solidity scratch pad at memory position 0.\\n calldatacopy(0, 0, calldatasize())\\n\\n // Call the implementation.\\n // out and outsize are 0 because we don't know the size yet.\\n let result := delegatecall(gas(), implementation, 0, calldatasize(), 0, 0)\\n\\n // Copy the returned data.\\n returndatacopy(0, 0, returndatasize())\\n\\n switch result\\n // delegatecall returns 0 on error.\\n case 0 {\\n revert(0, returndatasize())\\n }\\n default {\\n return(0, returndatasize())\\n }\\n }\\n }\\n\\n /**\\n * @dev This is a virtual function that should be overridden so it returns the address to which the fallback function\\n * and {_fallback} should delegate.\\n */\\n function _implementation() internal view virtual returns (address);\\n\\n /**\\n * @dev Delegates the current call to the address returned by `_implementation()`.\\n *\\n * This function does not return to its internal call site, it will return directly to the external caller.\\n */\\n function _fallback() internal virtual {\\n _beforeFallback();\\n _delegate(_implementation());\\n }\\n\\n /**\\n * @dev Fallback function that delegates calls to the address returned by `_implementation()`. Will run if no other\\n * function in the contract matches the call data.\\n */\\n fallback() external payable virtual {\\n _fallback();\\n }\\n\\n /**\\n * @dev Fallback function that delegates calls to the address returned by `_implementation()`. Will run if call data\\n * is empty.\\n */\\n receive() external payable virtual {\\n _fallback();\\n }\\n\\n /**\\n * @dev Hook that is called before falling back to the implementation. Can happen as part of a manual `_fallback`\\n * call, or as part of the Solidity `fallback` or `receive` functions.\\n *\\n * If overridden should call `super._beforeFallback()`.\\n */\\n function _beforeFallback() internal virtual {}\\n}\\n\",\"keccak256\":\"0xc130fe33f1b2132158531a87734153293f6d07bc263ff4ac90e85da9c82c0e27\",\"license\":\"MIT\"},\"@openzeppelin/contracts/proxy/beacon/IBeacon.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (proxy/beacon/IBeacon.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev This is the interface that {BeaconProxy} expects of its beacon.\\n */\\ninterface IBeacon {\\n /**\\n * @dev Must return an address that can be used as a delegate call target.\\n *\\n * {BeaconProxy} will check that this address is a contract.\\n */\\n function implementation() external view returns (address);\\n}\\n\",\"keccak256\":\"0xd50a3421ac379ccb1be435fa646d66a65c986b4924f0849839f08692f39dde61\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/Address.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.7.0) (utils/Address.sol)\\n\\npragma solidity ^0.8.1;\\n\\n/**\\n * @dev Collection of functions related to the address type\\n */\\nlibrary Address {\\n /**\\n * @dev Returns true if `account` is a contract.\\n *\\n * [IMPORTANT]\\n * ====\\n * It is unsafe to assume that an address for which this function returns\\n * false is an externally-owned account (EOA) and not a contract.\\n *\\n * Among others, `isContract` will return false for the following\\n * types of addresses:\\n *\\n * - an externally-owned account\\n * - a contract in construction\\n * - an address where a contract will be created\\n * - an address where a contract lived, but was destroyed\\n * ====\\n *\\n * [IMPORTANT]\\n * ====\\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\\n *\\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\\n * constructor.\\n * ====\\n */\\n function isContract(address account) internal view returns (bool) {\\n // This method relies on extcodesize/address.code.length, which returns 0\\n // for contracts in construction, since the code is only stored at the end\\n // of the constructor execution.\\n\\n return account.code.length > 0;\\n }\\n\\n /**\\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\\n * `recipient`, forwarding all available gas and reverting on errors.\\n *\\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\\n * imposed by `transfer`, making them unable to receive funds via\\n * `transfer`. {sendValue} removes this limitation.\\n *\\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\\n *\\n * IMPORTANT: because control is transferred to `recipient`, care must be\\n * taken to not create reentrancy vulnerabilities. Consider using\\n * {ReentrancyGuard} or the\\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\\n */\\n function sendValue(address payable recipient, uint256 amount) internal {\\n require(address(this).balance >= amount, \\\"Address: insufficient balance\\\");\\n\\n (bool success, ) = recipient.call{value: amount}(\\\"\\\");\\n require(success, \\\"Address: unable to send value, recipient may have reverted\\\");\\n }\\n\\n /**\\n * @dev Performs a Solidity function call using a low level `call`. A\\n * plain `call` is an unsafe replacement for a function call: use this\\n * function instead.\\n *\\n * If `target` reverts with a revert reason, it is bubbled up by this\\n * function (like regular Solidity function calls).\\n *\\n * Returns the raw returned data. To convert to the expected return value,\\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\\n *\\n * Requirements:\\n *\\n * - `target` must be a contract.\\n * - calling `target` with `data` must not revert.\\n *\\n * _Available since v3.1._\\n */\\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\\n return functionCall(target, data, \\\"Address: low-level call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\\n * `errorMessage` as a fallback revert reason when `target` reverts.\\n *\\n * _Available since v3.1._\\n */\\n function functionCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n return functionCallWithValue(target, data, 0, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but also transferring `value` wei to `target`.\\n *\\n * Requirements:\\n *\\n * - the calling contract must have an ETH balance of at least `value`.\\n * - the called Solidity function must be `payable`.\\n *\\n * _Available since v3.1._\\n */\\n function functionCallWithValue(\\n address target,\\n bytes memory data,\\n uint256 value\\n ) internal returns (bytes memory) {\\n return functionCallWithValue(target, data, value, \\\"Address: low-level call with value failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\\n * with `errorMessage` as a fallback revert reason when `target` reverts.\\n *\\n * _Available since v3.1._\\n */\\n function functionCallWithValue(\\n address target,\\n bytes memory data,\\n uint256 value,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n require(address(this).balance >= value, \\\"Address: insufficient balance for call\\\");\\n require(isContract(target), \\\"Address: call to non-contract\\\");\\n\\n (bool success, bytes memory returndata) = target.call{value: value}(data);\\n return verifyCallResult(success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but performing a static call.\\n *\\n * _Available since v3.3._\\n */\\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\\n return functionStaticCall(target, data, \\\"Address: low-level static call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\\n * but performing a static call.\\n *\\n * _Available since v3.3._\\n */\\n function functionStaticCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal view returns (bytes memory) {\\n require(isContract(target), \\\"Address: static call to non-contract\\\");\\n\\n (bool success, bytes memory returndata) = target.staticcall(data);\\n return verifyCallResult(success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but performing a delegate call.\\n *\\n * _Available since v3.4._\\n */\\n function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {\\n return functionDelegateCall(target, data, \\\"Address: low-level delegate call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\\n * but performing a delegate call.\\n *\\n * _Available since v3.4._\\n */\\n function functionDelegateCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n require(isContract(target), \\\"Address: delegate call to non-contract\\\");\\n\\n (bool success, bytes memory returndata) = target.delegatecall(data);\\n return verifyCallResult(success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the\\n * revert reason using the provided one.\\n *\\n * _Available since v4.3._\\n */\\n function verifyCallResult(\\n bool success,\\n bytes memory returndata,\\n string memory errorMessage\\n ) internal pure returns (bytes memory) {\\n if (success) {\\n return returndata;\\n } else {\\n // Look for revert reason and bubble it up if present\\n if (returndata.length > 0) {\\n // The easiest way to bubble the revert reason is using memory via assembly\\n /// @solidity memory-safe-assembly\\n assembly {\\n let returndata_size := mload(returndata)\\n revert(add(32, returndata), returndata_size)\\n }\\n } else {\\n revert(errorMessage);\\n }\\n }\\n }\\n}\\n\",\"keccak256\":\"0xd6153ce99bcdcce22b124f755e72553295be6abcd63804cfdffceb188b8bef10\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/StorageSlot.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.7.0) (utils/StorageSlot.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Library for reading and writing primitive types to specific storage slots.\\n *\\n * Storage slots are often used to avoid storage conflict when dealing with upgradeable contracts.\\n * This library helps with reading and writing to such slots without the need for inline assembly.\\n *\\n * The functions in this library return Slot structs that contain a `value` member that can be used to read or write.\\n *\\n * Example usage to set ERC1967 implementation slot:\\n * ```\\n * contract ERC1967 {\\n * bytes32 internal constant _IMPLEMENTATION_SLOT = 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc;\\n *\\n * function _getImplementation() internal view returns (address) {\\n * return StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value;\\n * }\\n *\\n * function _setImplementation(address newImplementation) internal {\\n * require(Address.isContract(newImplementation), \\\"ERC1967: new implementation is not a contract\\\");\\n * StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value = newImplementation;\\n * }\\n * }\\n * ```\\n *\\n * _Available since v4.1 for `address`, `bool`, `bytes32`, and `uint256`._\\n */\\nlibrary StorageSlot {\\n struct AddressSlot {\\n address value;\\n }\\n\\n struct BooleanSlot {\\n bool value;\\n }\\n\\n struct Bytes32Slot {\\n bytes32 value;\\n }\\n\\n struct Uint256Slot {\\n uint256 value;\\n }\\n\\n /**\\n * @dev Returns an `AddressSlot` with member `value` located at `slot`.\\n */\\n function getAddressSlot(bytes32 slot) internal pure returns (AddressSlot storage r) {\\n /// @solidity memory-safe-assembly\\n assembly {\\n r.slot := slot\\n }\\n }\\n\\n /**\\n * @dev Returns an `BooleanSlot` with member `value` located at `slot`.\\n */\\n function getBooleanSlot(bytes32 slot) internal pure returns (BooleanSlot storage r) {\\n /// @solidity memory-safe-assembly\\n assembly {\\n r.slot := slot\\n }\\n }\\n\\n /**\\n * @dev Returns an `Bytes32Slot` with member `value` located at `slot`.\\n */\\n function getBytes32Slot(bytes32 slot) internal pure returns (Bytes32Slot storage r) {\\n /// @solidity memory-safe-assembly\\n assembly {\\n r.slot := slot\\n }\\n }\\n\\n /**\\n * @dev Returns an `Uint256Slot` with member `value` located at `slot`.\\n */\\n function getUint256Slot(bytes32 slot) internal pure returns (Uint256Slot storage r) {\\n /// @solidity memory-safe-assembly\\n assembly {\\n r.slot := slot\\n }\\n }\\n}\\n\",\"keccak256\":\"0xd5c50c54bf02740ebd122ff06832546cb5fa84486d52695a9ccfd11666e0c81d\",\"license\":\"MIT\"},\"contracts/external/TransparentUpgradeableProxy.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-3.0\\n\\npragma solidity ^0.8.12;\\n\\nimport \\\"@openzeppelin/contracts/proxy/ERC1967/ERC1967Proxy.sol\\\";\\n\\n/**\\n * @dev This contract implements a proxy that is upgradeable by an admin. It is fully forked from OpenZeppelin\\n * `TransparentUpgradeableProxy`\\n *\\n * To avoid https://medium.com/nomic-labs-blog/malicious-backdoors-in-ethereum-proxies-62629adf3357[proxy selector\\n * clashing], which can potentially be used in an attack, this contract uses the\\n * https://blog.openzeppelin.com/the-transparent-proxy-pattern/[transparent proxy pattern]. This pattern implies two\\n * things that go hand in hand:\\n *\\n * 1. If any account other than the admin calls the proxy, the call will be forwarded to the implementation, even if\\n * that call matches one of the admin functions exposed by the proxy itself.\\n * 2. If the admin calls the proxy, it can access the admin functions, but its calls will never be forwarded to the\\n * implementation. If the admin tries to call a function on the implementation it will fail with an error that says\\n * \\\"admin cannot fallback to proxy target\\\".\\n *\\n * These properties mean that the admin account can only be used for admin actions like upgrading the proxy or changing\\n * the admin, so it's best if it's a dedicated account that is not used for anything else. This will avoid headaches due\\n * to sudden errors when trying to call a function from the proxy implementation.\\n *\\n * Our recommendation is for the dedicated account to be an instance of the {ProxyAdmin} contract. If set up this way,\\n * you should think of the `ProxyAdmin` instance as the real administrative interface of your proxy.\\n */\\ncontract TransparentUpgradeableProxy is ERC1967Proxy {\\n /**\\n * @dev Initializes an upgradeable proxy managed by `_admin`, backed by the implementation at `_logic`, and\\n * optionally initialized with `_data` as explained in {ERC1967Proxy-constructor}.\\n */\\n constructor(address _logic, address admin_, bytes memory _data) payable ERC1967Proxy(_logic, _data) {\\n assert(_ADMIN_SLOT == bytes32(uint256(keccak256(\\\"eip1967.proxy.admin\\\")) - 1));\\n _changeAdmin(admin_);\\n }\\n\\n /**\\n * @dev Modifier used internally that will delegate the call to the implementation unless the sender is the admin.\\n */\\n modifier ifAdmin() {\\n if (msg.sender == _getAdmin()) {\\n _;\\n } else {\\n _fallback();\\n }\\n }\\n\\n /**\\n * @dev Returns the current admin.\\n *\\n * NOTE: Only the admin can call this function. See {ProxyAdmin-getProxyAdmin}.\\n *\\n * TIP: To get this value clients can read directly from the storage slot shown below (specified by EIP1967) using the\\n * https://eth.wiki/json-rpc/API#eth_getstorageat[`eth_getStorageAt`] RPC call.\\n * `0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103`\\n */\\n function admin() external ifAdmin returns (address admin_) {\\n admin_ = _getAdmin();\\n }\\n\\n /**\\n * @dev Returns the current implementation.\\n *\\n * NOTE: Only the admin can call this function. See {ProxyAdmin-getProxyImplementation}.\\n *\\n * TIP: To get this value clients can read directly from the storage slot shown below (specified by EIP1967) using the\\n * https://eth.wiki/json-rpc/API#eth_getstorageat[`eth_getStorageAt`] RPC call.\\n * `0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc`\\n */\\n function implementation() external ifAdmin returns (address implementation_) {\\n implementation_ = _implementation();\\n }\\n\\n /**\\n * @dev Changes the admin of the proxy.\\n *\\n * Emits an {AdminChanged} event.\\n *\\n * NOTE: Only the admin can call this function. See {ProxyAdmin-changeProxyAdmin}.\\n */\\n function changeAdmin(address newAdmin) external virtual ifAdmin {\\n _changeAdmin(newAdmin);\\n }\\n\\n /**\\n * @dev Upgrade the implementation of the proxy.\\n *\\n * NOTE: Only the admin can call this function. See {ProxyAdmin-upgrade}.\\n */\\n function upgradeTo(address newImplementation) external ifAdmin {\\n _upgradeToAndCall(newImplementation, bytes(\\\"\\\"), false);\\n }\\n\\n /**\\n * @dev Upgrade the implementation of the proxy, and then call a function from the new implementation as specified\\n * by `data`, which should be an encoded function call. This is useful to initialize new storage variables in the\\n * proxied contract.\\n *\\n * NOTE: Only the admin can call this function. See {ProxyAdmin-upgradeAndCall}.\\n */\\n function upgradeToAndCall(address newImplementation, bytes calldata data) external payable ifAdmin {\\n _upgradeToAndCall(newImplementation, data, true);\\n }\\n\\n /**\\n * @dev Returns the current admin.\\n */\\n function _admin() internal view virtual returns (address) {\\n return _getAdmin();\\n }\\n\\n /**\\n * @dev Makes sure the admin cannot access the fallback function. See {Proxy-_beforeFallback}.\\n */\\n function _beforeFallback() internal virtual override {\\n require(msg.sender != _getAdmin(), \\\"TransparentUpgradeableProxy: admin cannot fallback to proxy target\\\");\\n super._beforeFallback();\\n }\\n}\\n\",\"keccak256\":\"0x93a67a0f612ea3ff2a76315e138a6a88267270a1379d3cc7be52845fbbe611e2\",\"license\":\"GPL-3.0\"}},\"version\":1}", + "bytecode": "0x6080604052604051620010bb380380620010bb8339810160408190526200002691620004d8565b828162000036828260006200009a565b5062000066905060017fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6104620005b8565b6000805160206200107483398151915214620000865762000086620005da565b6200009182620000d7565b50505062000643565b620000a58362000132565b600082511180620000b35750805b15620000d257620000d083836200017460201b6200028c1760201c565b505b505050565b7f7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f62000102620001a5565b604080516001600160a01b03928316815291841660208301520160405180910390a16200012f81620001de565b50565b6200013d8162000293565b6040516001600160a01b038216907fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b90600090a250565b60606200019c8383604051806060016040528060278152602001620010946027913962000347565b90505b92915050565b6000620001cf6000805160206200107483398151915260001b6200042f60201b6200022e1760201c565b546001600160a01b0316919050565b6001600160a01b038116620002495760405162461bcd60e51b815260206004820152602660248201527f455243313936373a206e65772061646d696e20697320746865207a65726f206160448201526564647265737360d01b60648201526084015b60405180910390fd5b80620002726000805160206200107483398151915260001b6200042f60201b6200022e1760201c565b80546001600160a01b0319166001600160a01b039290921691909117905550565b620002a9816200043260201b620002b81760201c565b6200030d5760405162461bcd60e51b815260206004820152602d60248201527f455243313936373a206e657720696d706c656d656e746174696f6e206973206e60448201526c1bdd08184818dbdb9d1c9858dd609a1b606482015260840162000240565b80620002727f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc60001b6200042f60201b6200022e1760201c565b60606001600160a01b0384163b620003b15760405162461bcd60e51b815260206004820152602660248201527f416464726573733a2064656c65676174652063616c6c20746f206e6f6e2d636f6044820152651b9d1c9858dd60d21b606482015260840162000240565b600080856001600160a01b031685604051620003ce9190620005f0565b600060405180830381855af49150503d80600081146200040b576040519150601f19603f3d011682016040523d82523d6000602084013e62000410565b606091505b5090925090506200042382828662000441565b925050505b9392505050565b90565b6001600160a01b03163b151590565b606083156200045257508162000428565b825115620004635782518084602001fd5b8160405162461bcd60e51b81526004016200024091906200060e565b80516001600160a01b03811681146200049757600080fd5b919050565b634e487b7160e01b600052604160045260246000fd5b60005b83811015620004cf578181015183820152602001620004b5565b50506000910152565b600080600060608486031215620004ee57600080fd5b620004f9846200047f565b925062000509602085016200047f565b60408501519092506001600160401b03808211156200052757600080fd5b818601915086601f8301126200053c57600080fd5b8151818111156200055157620005516200049c565b604051601f8201601f19908116603f011681019083821181831017156200057c576200057c6200049c565b816040528281528960208487010111156200059657600080fd5b620005a9836020830160208801620004b2565b80955050505050509250925092565b818103818111156200019f57634e487b7160e01b600052601160045260246000fd5b634e487b7160e01b600052600160045260246000fd5b6000825162000604818460208701620004b2565b9190910192915050565b60208152600082518060208401526200062f816040850160208701620004b2565b601f01601f19169190910160400192915050565b610a2180620006536000396000f3fe60806040526004361061005e5760003560e01c80635c60da1b116100435780635c60da1b146100a85780638f283970146100e6578063f851a440146101065761006d565b80633659cfe6146100755780634f1ef286146100955761006d565b3661006d5761006b61011b565b005b61006b61011b565b34801561008157600080fd5b5061006b610090366004610895565b610135565b61006b6100a33660046108b0565b61017f565b3480156100b457600080fd5b506100bd6101f3565b60405173ffffffffffffffffffffffffffffffffffffffff909116815260200160405180910390f35b3480156100f257600080fd5b5061006b610101366004610895565b610231565b34801561011257600080fd5b506100bd61025e565b6101236102d4565b61013361012e6103ab565b6103b5565b565b61013d6103d9565b73ffffffffffffffffffffffffffffffffffffffff1633036101775761017481604051806020016040528060008152506000610419565b50565b61017461011b565b6101876103d9565b73ffffffffffffffffffffffffffffffffffffffff1633036101eb576101e68383838080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525060019250610419915050565b505050565b6101e661011b565b60006101fd6103d9565b73ffffffffffffffffffffffffffffffffffffffff163303610226576102216103ab565b905090565b61022e61011b565b90565b6102396103d9565b73ffffffffffffffffffffffffffffffffffffffff1633036101775761017481610444565b60006102686103d9565b73ffffffffffffffffffffffffffffffffffffffff163303610226576102216103d9565b60606102b183836040518060600160405280602781526020016109c5602791396104a5565b9392505050565b73ffffffffffffffffffffffffffffffffffffffff163b151590565b6102dc6103d9565b73ffffffffffffffffffffffffffffffffffffffff163303610133576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604260248201527f5472616e73706172656e745570677261646561626c6550726f78793a2061646d60448201527f696e2063616e6e6f742066616c6c6261636b20746f2070726f7879207461726760648201527f6574000000000000000000000000000000000000000000000000000000000000608482015260a4015b60405180910390fd5b60006102216105cd565b3660008037600080366000845af43d6000803e8080156103d4573d6000f35b3d6000fd5b60007fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035b5473ffffffffffffffffffffffffffffffffffffffff16919050565b610422836105f5565b60008251118061042f5750805b156101e65761043e838361028c565b50505050565b7f7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f61046d6103d9565b6040805173ffffffffffffffffffffffffffffffffffffffff928316815291841660208301520160405180910390a161017481610642565b606073ffffffffffffffffffffffffffffffffffffffff84163b61054b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f416464726573733a2064656c65676174652063616c6c20746f206e6f6e2d636f60448201527f6e7472616374000000000000000000000000000000000000000000000000000060648201526084016103a2565b6000808573ffffffffffffffffffffffffffffffffffffffff16856040516105739190610957565b600060405180830381855af49150503d80600081146105ae576040519150601f19603f3d011682016040523d82523d6000602084013e6105b3565b606091505b50915091506105c382828661074e565b9695505050505050565b60007f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc6103fd565b6105fe816107a1565b60405173ffffffffffffffffffffffffffffffffffffffff8216907fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b90600090a250565b73ffffffffffffffffffffffffffffffffffffffff81166106e5576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f455243313936373a206e65772061646d696e20697320746865207a65726f206160448201527f646472657373000000000000000000000000000000000000000000000000000060648201526084016103a2565b807fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035b80547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff9290921691909117905550565b6060831561075d5750816102b1565b82511561076d5782518084602001fd5b816040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016103a29190610973565b73ffffffffffffffffffffffffffffffffffffffff81163b610845576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602d60248201527f455243313936373a206e657720696d706c656d656e746174696f6e206973206e60448201527f6f74206120636f6e74726163740000000000000000000000000000000000000060648201526084016103a2565b807f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc610708565b803573ffffffffffffffffffffffffffffffffffffffff8116811461089057600080fd5b919050565b6000602082840312156108a757600080fd5b6102b18261086c565b6000806000604084860312156108c557600080fd5b6108ce8461086c565b9250602084013567ffffffffffffffff808211156108eb57600080fd5b818601915086601f8301126108ff57600080fd5b81358181111561090e57600080fd5b87602082850101111561092057600080fd5b6020830194508093505050509250925092565b60005b8381101561094e578181015183820152602001610936565b50506000910152565b60008251610969818460208701610933565b9190910192915050565b6020815260008251806020840152610992816040850160208701610933565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016919091016040019291505056fe416464726573733a206c6f772d6c6576656c2064656c65676174652063616c6c206661696c6564a2646970667358221220e96638b07fb1675d93a95c49e417bc8111448b23a59918698cdcd8fd488dd7cf64736f6c63430008110033b53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103416464726573733a206c6f772d6c6576656c2064656c65676174652063616c6c206661696c6564", + "deployedBytecode": "0x60806040526004361061005e5760003560e01c80635c60da1b116100435780635c60da1b146100a85780638f283970146100e6578063f851a440146101065761006d565b80633659cfe6146100755780634f1ef286146100955761006d565b3661006d5761006b61011b565b005b61006b61011b565b34801561008157600080fd5b5061006b610090366004610895565b610135565b61006b6100a33660046108b0565b61017f565b3480156100b457600080fd5b506100bd6101f3565b60405173ffffffffffffffffffffffffffffffffffffffff909116815260200160405180910390f35b3480156100f257600080fd5b5061006b610101366004610895565b610231565b34801561011257600080fd5b506100bd61025e565b6101236102d4565b61013361012e6103ab565b6103b5565b565b61013d6103d9565b73ffffffffffffffffffffffffffffffffffffffff1633036101775761017481604051806020016040528060008152506000610419565b50565b61017461011b565b6101876103d9565b73ffffffffffffffffffffffffffffffffffffffff1633036101eb576101e68383838080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525060019250610419915050565b505050565b6101e661011b565b60006101fd6103d9565b73ffffffffffffffffffffffffffffffffffffffff163303610226576102216103ab565b905090565b61022e61011b565b90565b6102396103d9565b73ffffffffffffffffffffffffffffffffffffffff1633036101775761017481610444565b60006102686103d9565b73ffffffffffffffffffffffffffffffffffffffff163303610226576102216103d9565b60606102b183836040518060600160405280602781526020016109c5602791396104a5565b9392505050565b73ffffffffffffffffffffffffffffffffffffffff163b151590565b6102dc6103d9565b73ffffffffffffffffffffffffffffffffffffffff163303610133576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604260248201527f5472616e73706172656e745570677261646561626c6550726f78793a2061646d60448201527f696e2063616e6e6f742066616c6c6261636b20746f2070726f7879207461726760648201527f6574000000000000000000000000000000000000000000000000000000000000608482015260a4015b60405180910390fd5b60006102216105cd565b3660008037600080366000845af43d6000803e8080156103d4573d6000f35b3d6000fd5b60007fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035b5473ffffffffffffffffffffffffffffffffffffffff16919050565b610422836105f5565b60008251118061042f5750805b156101e65761043e838361028c565b50505050565b7f7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f61046d6103d9565b6040805173ffffffffffffffffffffffffffffffffffffffff928316815291841660208301520160405180910390a161017481610642565b606073ffffffffffffffffffffffffffffffffffffffff84163b61054b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f416464726573733a2064656c65676174652063616c6c20746f206e6f6e2d636f60448201527f6e7472616374000000000000000000000000000000000000000000000000000060648201526084016103a2565b6000808573ffffffffffffffffffffffffffffffffffffffff16856040516105739190610957565b600060405180830381855af49150503d80600081146105ae576040519150601f19603f3d011682016040523d82523d6000602084013e6105b3565b606091505b50915091506105c382828661074e565b9695505050505050565b60007f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc6103fd565b6105fe816107a1565b60405173ffffffffffffffffffffffffffffffffffffffff8216907fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b90600090a250565b73ffffffffffffffffffffffffffffffffffffffff81166106e5576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f455243313936373a206e65772061646d696e20697320746865207a65726f206160448201527f646472657373000000000000000000000000000000000000000000000000000060648201526084016103a2565b807fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035b80547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff9290921691909117905550565b6060831561075d5750816102b1565b82511561076d5782518084602001fd5b816040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016103a29190610973565b73ffffffffffffffffffffffffffffffffffffffff81163b610845576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602d60248201527f455243313936373a206e657720696d706c656d656e746174696f6e206973206e60448201527f6f74206120636f6e74726163740000000000000000000000000000000000000060648201526084016103a2565b807f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc610708565b803573ffffffffffffffffffffffffffffffffffffffff8116811461089057600080fd5b919050565b6000602082840312156108a757600080fd5b6102b18261086c565b6000806000604084860312156108c557600080fd5b6108ce8461086c565b9250602084013567ffffffffffffffff808211156108eb57600080fd5b818601915086601f8301126108ff57600080fd5b81358181111561090e57600080fd5b87602082850101111561092057600080fd5b6020830194508093505050509250925092565b60005b8381101561094e578181015183820152602001610936565b50506000910152565b60008251610969818460208701610933565b9190910192915050565b6020815260008251806020840152610992816040850160208701610933565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016919091016040019291505056fe416464726573733a206c6f772d6c6576656c2064656c65676174652063616c6c206661696c6564a2646970667358221220e96638b07fb1675d93a95c49e417bc8111448b23a59918698cdcd8fd488dd7cf64736f6c63430008110033", + "devdoc": { + "details": "This contract implements a proxy that is upgradeable by an admin. It is fully forked from OpenZeppelin `TransparentUpgradeableProxy` To avoid https://medium.com/nomic-labs-blog/malicious-backdoors-in-ethereum-proxies-62629adf3357[proxy selector clashing], which can potentially be used in an attack, this contract uses the https://blog.openzeppelin.com/the-transparent-proxy-pattern/[transparent proxy pattern]. This pattern implies two things that go hand in hand: 1. If any account other than the admin calls the proxy, the call will be forwarded to the implementation, even if that call matches one of the admin functions exposed by the proxy itself. 2. If the admin calls the proxy, it can access the admin functions, but its calls will never be forwarded to the implementation. If the admin tries to call a function on the implementation it will fail with an error that says \"admin cannot fallback to proxy target\". These properties mean that the admin account can only be used for admin actions like upgrading the proxy or changing the admin, so it's best if it's a dedicated account that is not used for anything else. This will avoid headaches due to sudden errors when trying to call a function from the proxy implementation. Our recommendation is for the dedicated account to be an instance of the {ProxyAdmin} contract. If set up this way, you should think of the `ProxyAdmin` instance as the real administrative interface of your proxy.", + "kind": "dev", + "methods": { + "admin()": { + "details": "Returns the current admin. NOTE: Only the admin can call this function. See {ProxyAdmin-getProxyAdmin}. TIP: To get this value clients can read directly from the storage slot shown below (specified by EIP1967) using the https://eth.wiki/json-rpc/API#eth_getstorageat[`eth_getStorageAt`] RPC call. `0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103`" + }, + "changeAdmin(address)": { + "details": "Changes the admin of the proxy. Emits an {AdminChanged} event. NOTE: Only the admin can call this function. See {ProxyAdmin-changeProxyAdmin}." + }, + "constructor": { + "details": "Initializes an upgradeable proxy managed by `_admin`, backed by the implementation at `_logic`, and optionally initialized with `_data` as explained in {ERC1967Proxy-constructor}." + }, + "implementation()": { + "details": "Returns the current implementation. NOTE: Only the admin can call this function. See {ProxyAdmin-getProxyImplementation}. TIP: To get this value clients can read directly from the storage slot shown below (specified by EIP1967) using the https://eth.wiki/json-rpc/API#eth_getstorageat[`eth_getStorageAt`] RPC call. `0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc`" + }, + "upgradeTo(address)": { + "details": "Upgrade the implementation of the proxy. NOTE: Only the admin can call this function. See {ProxyAdmin-upgrade}." + }, + "upgradeToAndCall(address,bytes)": { + "details": "Upgrade the implementation of the proxy, and then call a function from the new implementation as specified by `data`, which should be an encoded function call. This is useful to initialize new storage variables in the proxied contract. NOTE: Only the admin can call this function. See {ProxyAdmin-upgradeAndCall}." + } + }, + "version": 1 + }, + "userdoc": { + "kind": "user", + "methods": {}, + "version": 1 + }, + "storageLayout": { + "storage": [], + "types": null + } +} \ No newline at end of file diff --git a/deployments/mainnet/Oracle_WSTETH_USD.json b/deployments/mainnet/Oracle_WSTETH_USD.json new file mode 100644 index 00000000..ea805643 --- /dev/null +++ b/deployments/mainnet/Oracle_WSTETH_USD.json @@ -0,0 +1,260 @@ +{ + "address": "0xCf1AE61e2F65149355D8a340c47B592e1bCe6568", + "abi": [ + { + "inputs": [ + { + "internalType": "uint32", + "name": "_stalePeriod", + "type": "uint32" + }, + { + "internalType": "address", + "name": "_treasury", + "type": "address" + } + ], + "stateMutability": "nonpayable", + "type": "constructor" + }, + { + "inputs": [], + "name": "InvalidChainlinkRate", + "type": "error" + }, + { + "inputs": [], + "name": "NotGovernorOrGuardian", + "type": "error" + }, + { + "inputs": [], + "name": "NotVaultManagerOrGovernor", + "type": "error" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint32", + "name": "_stalePeriod", + "type": "uint32" + } + ], + "name": "StalePeriodUpdated", + "type": "event" + }, + { + "inputs": [], + "name": "DESCRIPTION", + "outputs": [ + { + "internalType": "string", + "name": "", + "type": "string" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "STETH", + "outputs": [ + { + "internalType": "contract IStETH", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint32", + "name": "_stalePeriod", + "type": "uint32" + } + ], + "name": "changeStalePeriod", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "circuitChainlink", + "outputs": [ + { + "internalType": "contract AggregatorV3Interface[]", + "name": "", + "type": "address[]" + } + ], + "stateMutability": "pure", + "type": "function" + }, + { + "inputs": [], + "name": "read", + "outputs": [ + { + "internalType": "uint256", + "name": "quoteAmount", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_treasury", + "type": "address" + } + ], + "name": "setTreasury", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "stalePeriod", + "outputs": [ + { + "internalType": "uint32", + "name": "", + "type": "uint32" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "treasury", + "outputs": [ + { + "internalType": "contract ITreasury", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + } + ], + "transactionHash": "0xe6a82b7b9e002312a9998f593a8154cf4b8e7f20bdcf29f2880b3756518e5753", + "receipt": { + "to": null, + "from": "0xfdA462548Ce04282f4B6D6619823a7C64Fdc0185", + "contractAddress": "0xCf1AE61e2F65149355D8a340c47B592e1bCe6568", + "transactionIndex": 18, + "gasUsed": "710322", + "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "blockHash": "0x3f77b016971e1856a1c74b048f889c49c5626fdabdac500456b3fc198128c9bc", + "transactionHash": "0xe6a82b7b9e002312a9998f593a8154cf4b8e7f20bdcf29f2880b3756518e5753", + "logs": [], + "blockNumber": 18975613, + "cumulativeGasUsed": "6334709", + "status": 1, + "byzantium": true + }, + "args": [ + 86400, + "0xf8588520E760BB0b3bDD62Ecb25186A28b0830ee" + ], + "numDeployments": 1, + "solcInputHash": "871924e0c138825a2736b76def8fef8d", + "metadata": "{\"compiler\":{\"version\":\"0.8.17+commit.8df45f5f\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[{\"internalType\":\"uint32\",\"name\":\"_stalePeriod\",\"type\":\"uint32\"},{\"internalType\":\"address\",\"name\":\"_treasury\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[],\"name\":\"InvalidChainlinkRate\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"NotGovernorOrGuardian\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"NotVaultManagerOrGovernor\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint32\",\"name\":\"_stalePeriod\",\"type\":\"uint32\"}],\"name\":\"StalePeriodUpdated\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"DESCRIPTION\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"STETH\",\"outputs\":[{\"internalType\":\"contract IStETH\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint32\",\"name\":\"_stalePeriod\",\"type\":\"uint32\"}],\"name\":\"changeStalePeriod\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"circuitChainlink\",\"outputs\":[{\"internalType\":\"contract AggregatorV3Interface[]\",\"name\":\"\",\"type\":\"address[]\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"read\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"quoteAmount\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_treasury\",\"type\":\"address\"}],\"name\":\"setTreasury\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"stalePeriod\",\"outputs\":[{\"internalType\":\"uint32\",\"name\":\"\",\"type\":\"uint32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"treasury\",\"outputs\":[{\"internalType\":\"contract ITreasury\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"}],\"devdoc\":{\"author\":\"Angle Labs, Inc.\",\"kind\":\"dev\",\"methods\":{\"changeStalePeriod(uint32)\":{\"params\":{\"_stalePeriod\":\"New stale period (in seconds)\"}},\"read()\":{\"details\":\"For instance if the out currency is EUR (and hence agEUR), then the base of the returned value is 10**18\",\"returns\":{\"quoteAmount\":\"The current rate between the in-currency and out-currency in the base of the out currency\"}},\"setTreasury(address)\":{\"details\":\"This function can be called by an approved `VaultManager` contract which can call this function after being requested to do so by a `treasury` contractIn some situations (like reactor contracts), the `VaultManager` may not directly be linked to the `oracle` contract and as such we may need governors to be able to call this function as well\",\"params\":{\"_treasury\":\"Address of the new treasury contract\"}}},\"title\":\"OracleWSTETHUSDChainlink\",\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{\"changeStalePeriod(uint32)\":{\"notice\":\"Changes the stale period\"},\"circuitChainlink()\":{\"notice\":\"Array with the list of Chainlink feeds in the order in which they are read\"},\"read()\":{\"notice\":\"Reads the rate from the Chainlink circuit and other data provided\"},\"setTreasury(address)\":{\"notice\":\"Changes the treasury contract\"},\"stalePeriod()\":{\"notice\":\"Represent the maximum amount of time (in seconds) between each Chainlink update before the price feed is considered stale\"},\"treasury()\":{\"notice\":\"Reference to the `treasury` contract handling this `VaultManager`\"}},\"notice\":\"Gives the price of wSTETH in USD in base 18\",\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/oracle/implementations/mainnet/USD/OracleWSTETHUSDChainlink.sol\":\"OracleWSTETHUSDChainlink\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":1000000},\"remappings\":[]},\"sources\":{\"@chainlink/contracts/src/v0.8/interfaces/AggregatorV3Interface.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.0;\\n\\ninterface AggregatorV3Interface {\\n\\n function decimals()\\n external\\n view\\n returns (\\n uint8\\n );\\n\\n function description()\\n external\\n view\\n returns (\\n string memory\\n );\\n\\n function version()\\n external\\n view\\n returns (\\n uint256\\n );\\n\\n // getRoundData and latestRoundData should both raise \\\"No data present\\\"\\n // if they do not have data to report, instead of returning unset values\\n // which could be misinterpreted as actual reported values.\\n function getRoundData(\\n uint80 _roundId\\n )\\n external\\n view\\n returns (\\n uint80 roundId,\\n int256 answer,\\n uint256 startedAt,\\n uint256 updatedAt,\\n uint80 answeredInRound\\n );\\n\\n function latestRoundData()\\n external\\n view\\n returns (\\n uint80 roundId,\\n int256 answer,\\n uint256 startedAt,\\n uint256 updatedAt,\\n uint80 answeredInRound\\n );\\n\\n}\\n\",\"keccak256\":\"0xe6f5ac8c47f3b9b6135051efb9216f9ba5b312a6ecc20209b4f66a780443c328\",\"license\":\"MIT\"},\"@openzeppelin/contracts-upgradeable/token/ERC20/IERC20Upgradeable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.6.0) (token/ERC20/IERC20.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Interface of the ERC20 standard as defined in the EIP.\\n */\\ninterface IERC20Upgradeable {\\n /**\\n * @dev Emitted when `value` tokens are moved from one account (`from`) to\\n * another (`to`).\\n *\\n * Note that `value` may be zero.\\n */\\n event Transfer(address indexed from, address indexed to, uint256 value);\\n\\n /**\\n * @dev Emitted when the allowance of a `spender` for an `owner` is set by\\n * a call to {approve}. `value` is the new allowance.\\n */\\n event Approval(address indexed owner, address indexed spender, uint256 value);\\n\\n /**\\n * @dev Returns the amount of tokens in existence.\\n */\\n function totalSupply() external view returns (uint256);\\n\\n /**\\n * @dev Returns the amount of tokens owned by `account`.\\n */\\n function balanceOf(address account) external view returns (uint256);\\n\\n /**\\n * @dev Moves `amount` tokens from the caller's account to `to`.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * Emits a {Transfer} event.\\n */\\n function transfer(address to, uint256 amount) external returns (bool);\\n\\n /**\\n * @dev Returns the remaining number of tokens that `spender` will be\\n * allowed to spend on behalf of `owner` through {transferFrom}. This is\\n * zero by default.\\n *\\n * This value changes when {approve} or {transferFrom} are called.\\n */\\n function allowance(address owner, address spender) external view returns (uint256);\\n\\n /**\\n * @dev Sets `amount` as the allowance of `spender` over the caller's tokens.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * IMPORTANT: Beware that changing an allowance with this method brings the risk\\n * that someone may use both the old and the new allowance by unfortunate\\n * transaction ordering. One possible solution to mitigate this race\\n * condition is to first reduce the spender's allowance to 0 and set the\\n * desired value afterwards:\\n * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729\\n *\\n * Emits an {Approval} event.\\n */\\n function approve(address spender, uint256 amount) external returns (bool);\\n\\n /**\\n * @dev Moves `amount` tokens from `from` to `to` using the\\n * allowance mechanism. `amount` is then deducted from the caller's\\n * allowance.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * Emits a {Transfer} event.\\n */\\n function transferFrom(\\n address from,\\n address to,\\n uint256 amount\\n ) external returns (bool);\\n}\\n\",\"keccak256\":\"0x4e733d3164f73f461eaf9d8087a7ad1ea180bdc8ba0d3d61b0e1ae16d8e63dff\",\"license\":\"MIT\"},\"contracts/interfaces/IAgToken.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-3.0\\n\\npragma solidity ^0.8.12;\\n\\nimport \\\"@openzeppelin/contracts-upgradeable/token/ERC20/IERC20Upgradeable.sol\\\";\\n\\n/// @title IAgToken\\n/// @author Angle Labs, Inc.\\n/// @notice Interface for the stablecoins `AgToken` contracts\\n/// @dev This interface only contains functions of the `AgToken` contract which are called by other contracts\\n/// of this module or of the first module of the Angle Protocol\\ninterface IAgToken is IERC20Upgradeable {\\n // ======================= Minter Role Only Functions ===========================\\n\\n /// @notice Lets the `StableMaster` contract or another whitelisted contract mint agTokens\\n /// @param account Address to mint to\\n /// @param amount Amount to mint\\n /// @dev The contracts allowed to issue agTokens are the `StableMaster` contract, `VaultManager` contracts\\n /// associated to this stablecoin as well as the flash loan module (if activated) and potentially contracts\\n /// whitelisted by governance\\n function mint(address account, uint256 amount) external;\\n\\n /// @notice Burns `amount` tokens from a `burner` address after being asked to by `sender`\\n /// @param amount Amount of tokens to burn\\n /// @param burner Address to burn from\\n /// @param sender Address which requested the burn from `burner`\\n /// @dev This method is to be called by a contract with the minter right after being requested\\n /// to do so by a `sender` address willing to burn tokens from another `burner` address\\n /// @dev The method checks the allowance between the `sender` and the `burner`\\n function burnFrom(uint256 amount, address burner, address sender) external;\\n\\n /// @notice Burns `amount` tokens from a `burner` address\\n /// @param amount Amount of tokens to burn\\n /// @param burner Address to burn from\\n /// @dev This method is to be called by a contract with a minter right on the AgToken after being\\n /// requested to do so by an address willing to burn tokens from its address\\n function burnSelf(uint256 amount, address burner) external;\\n\\n // ========================= Treasury Only Functions ===========================\\n\\n /// @notice Adds a minter in the contract\\n /// @param minter Minter address to add\\n /// @dev Zero address checks are performed directly in the `Treasury` contract\\n function addMinter(address minter) external;\\n\\n /// @notice Removes a minter from the contract\\n /// @param minter Minter address to remove\\n /// @dev This function can also be called by a minter wishing to revoke itself\\n function removeMinter(address minter) external;\\n\\n /// @notice Sets a new treasury contract\\n /// @param _treasury New treasury address\\n function setTreasury(address _treasury) external;\\n\\n // ========================= External functions ================================\\n\\n /// @notice Checks whether an address has the right to mint agTokens\\n /// @param minter Address for which the minting right should be checked\\n /// @return Whether the address has the right to mint agTokens or not\\n function isMinter(address minter) external view returns (bool);\\n\\n /// @notice Get the associated treasury\\n function treasury() external view returns (address);\\n}\\n\",\"keccak256\":\"0x0c83efcfc1fb9ae9ba830f7b89e3dab9abf6ad7a6205a31aa35fbccaa837dcdc\",\"license\":\"GPL-3.0\"},\"contracts/interfaces/ICoreBorrow.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-3.0\\n\\npragma solidity ^0.8.12;\\n\\n/// @title ICoreBorrow\\n/// @author Angle Labs, Inc.\\n/// @notice Interface for the `CoreBorrow` contract\\n/// @dev This interface only contains functions of the `CoreBorrow` contract which are called by other contracts\\n/// of this module\\ninterface ICoreBorrow {\\n /// @notice Checks if an address corresponds to a treasury of a stablecoin with a flash loan\\n /// module initialized on it\\n /// @param treasury Address to check\\n /// @return Whether the address has the `FLASHLOANER_TREASURY_ROLE` or not\\n function isFlashLoanerTreasury(address treasury) external view returns (bool);\\n\\n /// @notice Checks whether an address is governor of the Angle Protocol or not\\n /// @param admin Address to check\\n /// @return Whether the address has the `GOVERNOR_ROLE` or not\\n function isGovernor(address admin) external view returns (bool);\\n\\n /// @notice Checks whether an address is governor or a guardian of the Angle Protocol or not\\n /// @param admin Address to check\\n /// @return Whether the address has the `GUARDIAN_ROLE` or not\\n /// @dev Governance should make sure when adding a governor to also give this governor the guardian\\n /// role by calling the `addGovernor` function\\n function isGovernorOrGuardian(address admin) external view returns (bool);\\n}\\n\",\"keccak256\":\"0x10249210cbf522775f040baf981d7d037472168ce2746d87473ac7c29a34e62e\",\"license\":\"GPL-3.0\"},\"contracts/interfaces/IFlashAngle.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-3.0\\n\\npragma solidity ^0.8.12;\\n\\nimport \\\"./IAgToken.sol\\\";\\nimport \\\"./ICoreBorrow.sol\\\";\\n\\n/// @title IFlashAngle\\n/// @author Angle Labs, Inc.\\n/// @notice Interface for the `FlashAngle` contract\\n/// @dev This interface only contains functions of the contract which are called by other contracts\\n/// of this module\\ninterface IFlashAngle {\\n /// @notice Reference to the `CoreBorrow` contract managing the FlashLoan module\\n function core() external view returns (ICoreBorrow);\\n\\n /// @notice Sends the fees taken from flash loans to the treasury contract associated to the stablecoin\\n /// @param stablecoin Stablecoin from which profits should be sent\\n /// @return balance Amount of profits sent\\n /// @dev This function can only be called by the treasury contract\\n function accrueInterestToTreasury(IAgToken stablecoin) external returns (uint256 balance);\\n\\n /// @notice Adds support for a stablecoin\\n /// @param _treasury Treasury associated to the stablecoin to add support for\\n /// @dev This function can only be called by the `CoreBorrow` contract\\n function addStablecoinSupport(address _treasury) external;\\n\\n /// @notice Removes support for a stablecoin\\n /// @param _treasury Treasury associated to the stablecoin to remove support for\\n /// @dev This function can only be called by the `CoreBorrow` contract\\n function removeStablecoinSupport(address _treasury) external;\\n\\n /// @notice Sets a new core contract\\n /// @param _core Core contract address to set\\n /// @dev This function can only be called by the `CoreBorrow` contract\\n function setCore(address _core) external;\\n}\\n\",\"keccak256\":\"0x39b0097f695b9e934bccdc72676c91513f1077cc5d0fd151908fd25a7c5cfbe4\",\"license\":\"GPL-3.0\"},\"contracts/interfaces/IOracle.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-3.0\\n\\npragma solidity ^0.8.12;\\n\\nimport \\\"./ITreasury.sol\\\";\\nimport \\\"@chainlink/contracts/src/v0.8/interfaces/AggregatorV3Interface.sol\\\";\\n\\n/// @title IOracle\\n/// @author Angle Labs, Inc.\\n/// @notice Interface for the `Oracle` contract\\n/// @dev This interface only contains functions of the contract which are called by other contracts\\n/// of this module\\ninterface IOracle {\\n /// @notice Reads the rate from the Chainlink circuit and other data provided\\n /// @return quoteAmount The current rate between the in-currency and out-currency in the base\\n /// of the out currency\\n /// @dev For instance if the out currency is EUR (and hence agEUR), then the base of the returned\\n /// value is 10**18\\n function read() external view returns (uint256);\\n\\n /// @notice Changes the treasury contract\\n /// @param _treasury Address of the new treasury contract\\n /// @dev This function can be called by an approved `VaultManager` contract which can call\\n /// this function after being requested to do so by a `treasury` contract\\n /// @dev In some situations (like reactor contracts), the `VaultManager` may not directly be linked\\n /// to the `oracle` contract and as such we may need governors to be able to call this function as well\\n function setTreasury(address _treasury) external;\\n\\n /// @notice Reference to the `treasury` contract handling this `VaultManager`\\n function treasury() external view returns (ITreasury treasury);\\n\\n /// @notice Array with the list of Chainlink feeds in the order in which they are read\\n function circuitChainlink() external view returns (AggregatorV3Interface[] memory);\\n}\\n\",\"keccak256\":\"0x66fe2bb27f26b86e5832fc7d1ebd320cac8b3d79c5998ce148cf7279b2b359be\",\"license\":\"GPL-3.0\"},\"contracts/interfaces/ITreasury.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-3.0\\n\\npragma solidity ^0.8.12;\\n\\nimport \\\"./IAgToken.sol\\\";\\nimport \\\"./ICoreBorrow.sol\\\";\\nimport \\\"./IFlashAngle.sol\\\";\\n\\n/// @title ITreasury\\n/// @author Angle Labs, Inc.\\n/// @notice Interface for the `Treasury` contract\\n/// @dev This interface only contains functions of the `Treasury` which are called by other contracts\\n/// of this module\\ninterface ITreasury {\\n /// @notice Stablecoin handled by this `treasury` contract\\n function stablecoin() external view returns (IAgToken);\\n\\n /// @notice Checks whether a given address has the governor role\\n /// @param admin Address to check\\n /// @return Whether the address has the governor role\\n /// @dev Access control is only kept in the `CoreBorrow` contract\\n function isGovernor(address admin) external view returns (bool);\\n\\n /// @notice Checks whether a given address has the guardian or the governor role\\n /// @param admin Address to check\\n /// @return Whether the address has the guardian or the governor role\\n /// @dev Access control is only kept in the `CoreBorrow` contract which means that this function\\n /// queries the `CoreBorrow` contract\\n function isGovernorOrGuardian(address admin) external view returns (bool);\\n\\n /// @notice Checks whether a given address has well been initialized in this contract\\n /// as a `VaultManager`\\n /// @param _vaultManager Address to check\\n /// @return Whether the address has been initialized or not\\n function isVaultManager(address _vaultManager) external view returns (bool);\\n\\n /// @notice Sets a new flash loan module for this stablecoin\\n /// @param _flashLoanModule Reference to the new flash loan module\\n /// @dev This function removes the minting right to the old flash loan module and grants\\n /// it to the new module\\n function setFlashLoanModule(address _flashLoanModule) external;\\n\\n /// @notice Gets the vault manager list\\n function vaultManagerList(uint256 i) external returns (address);\\n}\\n\",\"keccak256\":\"0x06c2f781c08732ce1b5845c083af5742716245baa6c519bd737f32b230a884c1\",\"license\":\"GPL-3.0\"},\"contracts/interfaces/external/lido/IStETH.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-3.0\\n\\npragma solidity ^0.8.12;\\n\\n/// @title IStETH\\n/// @author Angle Labs, Inc.\\n/// @notice Interface for the `StETH` contract\\n/// @dev This interface only contains functions of the `StETH` which are called by other contracts\\n/// of this module\\ninterface IStETH {\\n function getPooledEthByShares(uint256 _sharesAmount) external view returns (uint256);\\n\\n event Submitted(address sender, uint256 amount, address referral);\\n\\n function submit(address) external payable returns (uint256);\\n\\n function getSharesByPooledEth(uint256 _ethAmount) external view returns (uint256);\\n}\\n\",\"keccak256\":\"0x6943f531d9648953692c83b228e4aa795c8b09d465f3eb5307a4705a788c1cc1\",\"license\":\"GPL-3.0\"},\"contracts/oracle/BaseOracleChainlinkMulti.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-3.0\\n\\n/*\\n * \\u2588 \\n ***** \\u2593\\u2593\\u2593 \\n * \\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593 \\n * ///. \\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593 \\n ***** //////// \\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593 \\n * ///////////// \\u2593\\u2593\\u2593 \\n \\u2593\\u2593 ////////////////// \\u2588 \\u2593\\u2593 \\n \\u2593\\u2593 \\u2593\\u2593 /////////////////////// \\u2593\\u2593 \\u2593\\u2593 \\n \\u2593\\u2593 \\u2593\\u2593 //////////////////////////// \\u2593\\u2593 \\u2593\\u2593 \\n \\u2593\\u2593 \\u2593\\u2593 /////////\\u2593\\u2593\\u2593///////\\u2593\\u2593\\u2593///////// \\u2593\\u2593 \\u2593\\u2593 \\n \\u2593\\u2593 ,////////////////////////////////////// \\u2593\\u2593 \\u2593\\u2593 \\n \\u2593\\u2593 ////////////////////////////////////////// \\u2593\\u2593 \\n \\u2593\\u2593 //////////////////////\\u2593\\u2593\\u2593\\u2593///////////////////// \\n ,//////////////////////////////////////////////////// \\n .////////////////////////////////////////////////////////// \\n .//////////////////////////\\u2588\\u2588.,//////////////////////////\\u2588 \\n .//////////////////////\\u2588\\u2588\\u2588\\u2588..,./////////////////////\\u2588\\u2588 \\n ...////////////////\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588.....,.////////////////\\u2588\\u2588\\u2588 \\n ,.,////////////\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588 ........,///////////\\u2588\\u2588\\u2588\\u2588 \\n .,.,//////\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588 ,.......///////\\u2588\\u2588\\u2588\\u2588 \\n ,..//\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588 ........./\\u2588\\u2588\\u2588\\u2588 \\n ..,\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588 .....,\\u2588\\u2588\\u2588 \\n .\\u2588\\u2588 ,.,\\u2588 \\n \\n \\n \\n \\u2593\\u2593 \\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593 \\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593 \\u2593\\u2593 \\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593 \\n \\u2593\\u2593\\u2593\\u2593\\u2593\\u2593 \\u2593\\u2593\\u2593 \\u2593\\u2593\\u2593 \\u2593\\u2593\\u2593 \\u2593\\u2593 \\u2593\\u2593 \\u2593\\u2593\\u2593\\u2593 \\n \\u2593\\u2593\\u2593 \\u2593\\u2593\\u2593 \\u2593\\u2593\\u2593 \\u2593\\u2593\\u2593 \\u2593\\u2593\\u2593 \\u2593\\u2593\\u2593 \\u2593\\u2593 \\u2593\\u2593\\u2593\\u2593\\u2593 \\n \\u2593\\u2593\\u2593 \\u2593\\u2593 \\u2593\\u2593\\u2593 \\u2593\\u2593\\u2593 \\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593 \\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593 \\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593 \\n*/\\n\\npragma solidity ^0.8.12;\\n\\nimport \\\"@chainlink/contracts/src/v0.8/interfaces/AggregatorV3Interface.sol\\\";\\n\\nimport \\\"../interfaces/IOracle.sol\\\";\\nimport \\\"../interfaces/ITreasury.sol\\\";\\n\\n/// @title BaseOracleChainlinkMulti\\n/// @author Angle Labs, Inc.\\n/// @notice Base Contract to be overriden by all contracts of the protocol\\n/// @dev This base contract concerns an oracle that uses Chainlink with multiple pools to read from\\n/// @dev All gas-efficient implementation of the `OracleChainlinkMulti` contract should inherit from this\\nabstract contract BaseOracleChainlinkMulti is IOracle {\\n // ========================= Parameters and References =========================\\n\\n /// @inheritdoc IOracle\\n ITreasury public override treasury;\\n /// @notice Represent the maximum amount of time (in seconds) between each Chainlink update\\n /// before the price feed is considered stale\\n uint32 public stalePeriod;\\n\\n // =================================== Event ===================================\\n\\n event StalePeriodUpdated(uint32 _stalePeriod);\\n\\n // =================================== Errors ===================================\\n\\n error InvalidChainlinkRate();\\n error NotGovernorOrGuardian();\\n error NotVaultManagerOrGovernor();\\n\\n /// @notice Constructor for an oracle using Chainlink with multiple pools to read from\\n /// @param _stalePeriod Minimum feed update frequency for the oracle to not revert\\n /// @param _treasury Treasury associated to the VaultManager which reads from this feed\\n constructor(uint32 _stalePeriod, address _treasury) {\\n stalePeriod = _stalePeriod;\\n treasury = ITreasury(_treasury);\\n }\\n\\n // ============================= Reading Oracles ===============================\\n\\n /// @inheritdoc IOracle\\n function read() external view virtual override returns (uint256 quoteAmount);\\n\\n /// @inheritdoc IOracle\\n function circuitChainlink() public view virtual returns (AggregatorV3Interface[] memory);\\n\\n /// @notice Reads a Chainlink feed using a quote amount and converts the quote amount to\\n /// the out-currency\\n /// @param quoteAmount The amount for which to compute the price expressed with base decimal\\n /// @param feed Chainlink feed to query\\n /// @param multiplied Whether the ratio outputted by Chainlink should be multiplied or divided\\n /// to the `quoteAmount`\\n /// @param decimals Number of decimals of the corresponding Chainlink pair\\n /// @return The `quoteAmount` converted in out-currency\\n function _readChainlinkFeed(\\n uint256 quoteAmount,\\n AggregatorV3Interface feed,\\n uint8 multiplied,\\n uint256 decimals\\n ) internal view returns (uint256) {\\n (uint80 roundId, int256 ratio, , uint256 updatedAt, uint80 answeredInRound) = feed.latestRoundData();\\n if (ratio <= 0 || roundId > answeredInRound || block.timestamp - updatedAt > stalePeriod)\\n revert InvalidChainlinkRate();\\n uint256 castedRatio = uint256(ratio);\\n // Checking whether we should multiply or divide by the ratio computed\\n if (multiplied == 1) return (quoteAmount * castedRatio) / (10 ** decimals);\\n else return (quoteAmount * (10 ** decimals)) / castedRatio;\\n }\\n\\n // ======================= Governance Related Functions ========================\\n\\n /// @notice Changes the stale period\\n /// @param _stalePeriod New stale period (in seconds)\\n function changeStalePeriod(uint32 _stalePeriod) external {\\n if (!treasury.isGovernorOrGuardian(msg.sender)) revert NotGovernorOrGuardian();\\n stalePeriod = _stalePeriod;\\n emit StalePeriodUpdated(_stalePeriod);\\n }\\n\\n /// @inheritdoc IOracle\\n function setTreasury(address _treasury) external override {\\n if (!treasury.isVaultManager(msg.sender) && !treasury.isGovernor(msg.sender))\\n revert NotVaultManagerOrGovernor();\\n treasury = ITreasury(_treasury);\\n }\\n}\\n\",\"keccak256\":\"0x6dc796277e844596455ea6d486fd5d439e407688ba4573055ab0b61c924588ed\",\"license\":\"GPL-3.0\"},\"contracts/oracle/BaseOracleChainlinkOneFeed.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-3.0\\n\\npragma solidity ^0.8.12;\\n\\nimport \\\"@chainlink/contracts/src/v0.8/interfaces/AggregatorV3Interface.sol\\\";\\n\\nimport \\\"./BaseOracleChainlinkMulti.sol\\\";\\n\\n/// @title BaseOracleChainlinkOneFeed\\n/// @author Angle Labs, Inc.\\n/// @notice Base contract for an oracle that reads into one Chainlink feeds with 8 decimals\\nabstract contract BaseOracleChainlinkOneFeed is BaseOracleChainlinkMulti {\\n constructor(uint32 _stalePeriod, address _treasury) BaseOracleChainlinkMulti(_stalePeriod, _treasury) {}\\n\\n /// @notice Returns the quote amount of the oracle contract\\n function _getQuoteAmount() internal view virtual returns (uint256) {\\n return 10 ** 18;\\n }\\n\\n /// @inheritdoc IOracle\\n function read() external view virtual override returns (uint256 quoteAmount) {\\n AggregatorV3Interface[] memory _circuitChainlink = circuitChainlink();\\n quoteAmount = _readChainlinkFeed(_getQuoteAmount(), _circuitChainlink[0], 1, 8);\\n }\\n}\\n\",\"keccak256\":\"0xb4a10dafe6b36602b3cdcad667f52b55e53143aef1af80ad7c98e5906c5386dd\",\"license\":\"GPL-3.0\"},\"contracts/oracle/implementations/mainnet/USD/OracleWSTETHUSDChainlink.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-3.0\\n\\npragma solidity ^0.8.12;\\n\\nimport \\\"@chainlink/contracts/src/v0.8/interfaces/AggregatorV3Interface.sol\\\";\\n\\nimport \\\"../../../BaseOracleChainlinkOneFeed.sol\\\";\\nimport \\\"../../../../interfaces/external/lido/IStETH.sol\\\";\\n\\n/// @title OracleWSTETHUSDChainlink\\n/// @author Angle Labs, Inc.\\n/// @notice Gives the price of wSTETH in USD in base 18\\ncontract OracleWSTETHUSDChainlink is BaseOracleChainlinkOneFeed {\\n string public constant DESCRIPTION = \\\"wSTETH/USD Oracle\\\";\\n IStETH public constant STETH = IStETH(0xae7ab96520DE3A18E5e111B5EaAb095312D7fE84);\\n\\n constructor(uint32 _stalePeriod, address _treasury) BaseOracleChainlinkOneFeed(_stalePeriod, _treasury) {}\\n\\n /// @inheritdoc IOracle\\n function circuitChainlink() public pure override returns (AggregatorV3Interface[] memory) {\\n AggregatorV3Interface[] memory _circuitChainlink = new AggregatorV3Interface[](1);\\n // Oracle stETH/USD\\n _circuitChainlink[0] = AggregatorV3Interface(0xCfE54B5cD566aB89272946F602D76Ea879CAb4a8);\\n return _circuitChainlink;\\n }\\n\\n /// @inheritdoc BaseOracleChainlinkOneFeed\\n function _getQuoteAmount() internal view override returns (uint256) {\\n return STETH.getPooledEthByShares(1 ether);\\n }\\n}\\n\",\"keccak256\":\"0xfa96f4a55e287c569e5c7bd2b93e3eb3bdef6444a28d6513d744fd90583ff8fc\",\"license\":\"GPL-3.0\"}},\"version\":1}", + "bytecode": "0x608060405234801561001057600080fd5b50604051610c4f380380610c4f83398101604081905261002f91610071565b600080546001600160c01b031916600160a01b63ffffffff94909416939093026001600160a01b031916929092176001600160a01b03919091161790556100c0565b6000806040838503121561008457600080fd5b825163ffffffff8116811461009857600080fd5b60208401519092506001600160a01b03811681146100b557600080fd5b809150509250929050565b610b80806100cf6000396000f3fe608060405234801561001057600080fd5b50600436106100885760003560e01c8063a5b36a361161005b578063a5b36a361461011b578063e00bfe5014610158578063f0f4426014610173578063f1ae88561461018657600080fd5b80634994cc671461008d57806357de26a4146100ab57806361d027b3146100c1578063630914d114610106575b600080fd5b6100956101cf565b6040516100a29190610782565b60405180910390f35b6100b3610247565b6040519081526020016100a2565b6000546100e19073ffffffffffffffffffffffffffffffffffffffff1681565b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020016100a2565b6101196101143660046107dc565b610289565b005b6000546101439074010000000000000000000000000000000000000000900463ffffffff1681565b60405163ffffffff90911681526020016100a2565b6100e173ae7ab96520de3a18e5e111b5eaab095312d7fe8481565b610119610181366004610809565b6103d4565b6101c26040518060400160405280601181526020017f7753544554482f555344204f7261636c6500000000000000000000000000000081525081565b6040516100a2919061083f565b604080516001808252818301909252606091600091906020808301908036833701905050905073cfe54b5cd566ab89272946f602d76ea879cab4a88160008151811061021d5761021d6108ab565b73ffffffffffffffffffffffffffffffffffffffff90921660209283029190910190910152919050565b6000806102526101cf565b905061028361025f610580565b82600081518110610272576102726108ab565b60200260200101516001600861061c565b91505090565b6000546040517f521d4de900000000000000000000000000000000000000000000000000000000815233600482015273ffffffffffffffffffffffffffffffffffffffff9091169063521d4de990602401602060405180830381865afa1580156102f7573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061031b91906108da565b610351576040517f99e120bc00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600080547fffffffffffffffff00000000ffffffffffffffffffffffffffffffffffffffff167401000000000000000000000000000000000000000063ffffffff8416908102919091179091556040519081527f4040b15332969bfd8b2035c1a701c8e13f2b5d62ce89b311684a601b2eb44e019060200160405180910390a150565b6000546040517f676a553e00000000000000000000000000000000000000000000000000000000815233600482015273ffffffffffffffffffffffffffffffffffffffff9091169063676a553e90602401602060405180830381865afa158015610442573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061046691906108da565b15801561050257506000546040517fe43581b800000000000000000000000000000000000000000000000000000000815233600482015273ffffffffffffffffffffffffffffffffffffffff9091169063e43581b890602401602060405180830381865afa1580156104dc573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061050091906108da565b155b15610539576040517fb05b9b9f00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600080547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff92909216919091179055565b6040517f7a28fb88000000000000000000000000000000000000000000000000000000008152670de0b6b3a7640000600482015260009073ae7ab96520de3a18e5e111b5eaab095312d7fe8490637a28fb8890602401602060405180830381865afa1580156105f3573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061061791906108fc565b905090565b60008060008060008773ffffffffffffffffffffffffffffffffffffffff1663feaf968c6040518163ffffffff1660e01b815260040160a060405180830381865afa15801561066f573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906106939190610934565b9450945050935093506000831315806106c357508069ffffffffffffffffffff168469ffffffffffffffffffff16115b806106f6575060005474010000000000000000000000000000000000000000900463ffffffff166106f483426109b3565b115b1561072d576040517fae19356300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8260ff88166001036107645761074487600a610aec565b61074e828c610af8565b6107589190610b0f565b9550505050505061077a565b8061077088600a610aec565b61074e908c610af8565b949350505050565b6020808252825182820181905260009190848201906040850190845b818110156107d057835173ffffffffffffffffffffffffffffffffffffffff168352928401929184019160010161079e565b50909695505050505050565b6000602082840312156107ee57600080fd5b813563ffffffff8116811461080257600080fd5b9392505050565b60006020828403121561081b57600080fd5b813573ffffffffffffffffffffffffffffffffffffffff8116811461080257600080fd5b600060208083528351808285015260005b8181101561086c57858101830151858201604001528201610850565b5060006040828601015260407fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f8301168501019250505092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b6000602082840312156108ec57600080fd5b8151801515811461080257600080fd5b60006020828403121561090e57600080fd5b5051919050565b805169ffffffffffffffffffff8116811461092f57600080fd5b919050565b600080600080600060a0868803121561094c57600080fd5b61095586610915565b945060208601519350604086015192506060860151915061097860808701610915565b90509295509295909350565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b818103818111156109c6576109c6610984565b92915050565b600181815b80851115610a2557817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff04821115610a0b57610a0b610984565b80851615610a1857918102915b93841c93908002906109d1565b509250929050565b600082610a3c575060016109c6565b81610a49575060006109c6565b8160018114610a5f5760028114610a6957610a85565b60019150506109c6565b60ff841115610a7a57610a7a610984565b50506001821b6109c6565b5060208310610133831016604e8410600b8410161715610aa8575081810a6109c6565b610ab283836109cc565b807fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff04821115610ae457610ae4610984565b029392505050565b60006108028383610a2d565b80820281158282048414176109c6576109c6610984565b600082610b45577f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b50049056fea2646970667358221220193846081cd3acea9f4551c2d0c960400c3da7b00d900f8559969720c854993464736f6c63430008110033", + "deployedBytecode": "0x608060405234801561001057600080fd5b50600436106100885760003560e01c8063a5b36a361161005b578063a5b36a361461011b578063e00bfe5014610158578063f0f4426014610173578063f1ae88561461018657600080fd5b80634994cc671461008d57806357de26a4146100ab57806361d027b3146100c1578063630914d114610106575b600080fd5b6100956101cf565b6040516100a29190610782565b60405180910390f35b6100b3610247565b6040519081526020016100a2565b6000546100e19073ffffffffffffffffffffffffffffffffffffffff1681565b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020016100a2565b6101196101143660046107dc565b610289565b005b6000546101439074010000000000000000000000000000000000000000900463ffffffff1681565b60405163ffffffff90911681526020016100a2565b6100e173ae7ab96520de3a18e5e111b5eaab095312d7fe8481565b610119610181366004610809565b6103d4565b6101c26040518060400160405280601181526020017f7753544554482f555344204f7261636c6500000000000000000000000000000081525081565b6040516100a2919061083f565b604080516001808252818301909252606091600091906020808301908036833701905050905073cfe54b5cd566ab89272946f602d76ea879cab4a88160008151811061021d5761021d6108ab565b73ffffffffffffffffffffffffffffffffffffffff90921660209283029190910190910152919050565b6000806102526101cf565b905061028361025f610580565b82600081518110610272576102726108ab565b60200260200101516001600861061c565b91505090565b6000546040517f521d4de900000000000000000000000000000000000000000000000000000000815233600482015273ffffffffffffffffffffffffffffffffffffffff9091169063521d4de990602401602060405180830381865afa1580156102f7573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061031b91906108da565b610351576040517f99e120bc00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600080547fffffffffffffffff00000000ffffffffffffffffffffffffffffffffffffffff167401000000000000000000000000000000000000000063ffffffff8416908102919091179091556040519081527f4040b15332969bfd8b2035c1a701c8e13f2b5d62ce89b311684a601b2eb44e019060200160405180910390a150565b6000546040517f676a553e00000000000000000000000000000000000000000000000000000000815233600482015273ffffffffffffffffffffffffffffffffffffffff9091169063676a553e90602401602060405180830381865afa158015610442573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061046691906108da565b15801561050257506000546040517fe43581b800000000000000000000000000000000000000000000000000000000815233600482015273ffffffffffffffffffffffffffffffffffffffff9091169063e43581b890602401602060405180830381865afa1580156104dc573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061050091906108da565b155b15610539576040517fb05b9b9f00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600080547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff92909216919091179055565b6040517f7a28fb88000000000000000000000000000000000000000000000000000000008152670de0b6b3a7640000600482015260009073ae7ab96520de3a18e5e111b5eaab095312d7fe8490637a28fb8890602401602060405180830381865afa1580156105f3573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061061791906108fc565b905090565b60008060008060008773ffffffffffffffffffffffffffffffffffffffff1663feaf968c6040518163ffffffff1660e01b815260040160a060405180830381865afa15801561066f573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906106939190610934565b9450945050935093506000831315806106c357508069ffffffffffffffffffff168469ffffffffffffffffffff16115b806106f6575060005474010000000000000000000000000000000000000000900463ffffffff166106f483426109b3565b115b1561072d576040517fae19356300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8260ff88166001036107645761074487600a610aec565b61074e828c610af8565b6107589190610b0f565b9550505050505061077a565b8061077088600a610aec565b61074e908c610af8565b949350505050565b6020808252825182820181905260009190848201906040850190845b818110156107d057835173ffffffffffffffffffffffffffffffffffffffff168352928401929184019160010161079e565b50909695505050505050565b6000602082840312156107ee57600080fd5b813563ffffffff8116811461080257600080fd5b9392505050565b60006020828403121561081b57600080fd5b813573ffffffffffffffffffffffffffffffffffffffff8116811461080257600080fd5b600060208083528351808285015260005b8181101561086c57858101830151858201604001528201610850565b5060006040828601015260407fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f8301168501019250505092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b6000602082840312156108ec57600080fd5b8151801515811461080257600080fd5b60006020828403121561090e57600080fd5b5051919050565b805169ffffffffffffffffffff8116811461092f57600080fd5b919050565b600080600080600060a0868803121561094c57600080fd5b61095586610915565b945060208601519350604086015192506060860151915061097860808701610915565b90509295509295909350565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b818103818111156109c6576109c6610984565b92915050565b600181815b80851115610a2557817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff04821115610a0b57610a0b610984565b80851615610a1857918102915b93841c93908002906109d1565b509250929050565b600082610a3c575060016109c6565b81610a49575060006109c6565b8160018114610a5f5760028114610a6957610a85565b60019150506109c6565b60ff841115610a7a57610a7a610984565b50506001821b6109c6565b5060208310610133831016604e8410600b8410161715610aa8575081810a6109c6565b610ab283836109cc565b807fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff04821115610ae457610ae4610984565b029392505050565b60006108028383610a2d565b80820281158282048414176109c6576109c6610984565b600082610b45577f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b50049056fea2646970667358221220193846081cd3acea9f4551c2d0c960400c3da7b00d900f8559969720c854993464736f6c63430008110033", + "devdoc": { + "author": "Angle Labs, Inc.", + "kind": "dev", + "methods": { + "changeStalePeriod(uint32)": { + "params": { + "_stalePeriod": "New stale period (in seconds)" + } + }, + "read()": { + "details": "For instance if the out currency is EUR (and hence agEUR), then the base of the returned value is 10**18", + "returns": { + "quoteAmount": "The current rate between the in-currency and out-currency in the base of the out currency" + } + }, + "setTreasury(address)": { + "details": "This function can be called by an approved `VaultManager` contract which can call this function after being requested to do so by a `treasury` contractIn some situations (like reactor contracts), the `VaultManager` may not directly be linked to the `oracle` contract and as such we may need governors to be able to call this function as well", + "params": { + "_treasury": "Address of the new treasury contract" + } + } + }, + "title": "OracleWSTETHUSDChainlink", + "version": 1 + }, + "userdoc": { + "kind": "user", + "methods": { + "changeStalePeriod(uint32)": { + "notice": "Changes the stale period" + }, + "circuitChainlink()": { + "notice": "Array with the list of Chainlink feeds in the order in which they are read" + }, + "read()": { + "notice": "Reads the rate from the Chainlink circuit and other data provided" + }, + "setTreasury(address)": { + "notice": "Changes the treasury contract" + }, + "stalePeriod()": { + "notice": "Represent the maximum amount of time (in seconds) between each Chainlink update before the price feed is considered stale" + }, + "treasury()": { + "notice": "Reference to the `treasury` contract handling this `VaultManager`" + } + }, + "notice": "Gives the price of wSTETH in USD in base 18", + "version": 1 + }, + "storageLayout": { + "storage": [ + { + "astId": 27276, + "contract": "contracts/oracle/implementations/mainnet/USD/OracleWSTETHUSDChainlink.sol:OracleWSTETHUSDChainlink", + "label": "treasury", + "offset": 0, + "slot": "0", + "type": "t_contract(ITreasury)18699" + }, + { + "astId": 27279, + "contract": "contracts/oracle/implementations/mainnet/USD/OracleWSTETHUSDChainlink.sol:OracleWSTETHUSDChainlink", + "label": "stalePeriod", + "offset": 20, + "slot": "0", + "type": "t_uint32" + } + ], + "types": { + "t_contract(ITreasury)18699": { + "encoding": "inplace", + "label": "contract ITreasury", + "numberOfBytes": "20" + }, + "t_uint32": { + "encoding": "inplace", + "label": "uint32", + "numberOfBytes": "4" + } + } + } +} \ No newline at end of file diff --git a/deployments/mainnet/Treasury_USD.json b/deployments/mainnet/Treasury_USD.json new file mode 100644 index 00000000..44a0f4e1 --- /dev/null +++ b/deployments/mainnet/Treasury_USD.json @@ -0,0 +1,235 @@ +{ + "address": "0xf8588520E760BB0b3bDD62Ecb25186A28b0830ee", + "abi": [ + { + "inputs": [ + { + "internalType": "address", + "name": "_logic", + "type": "address" + }, + { + "internalType": "address", + "name": "admin_", + "type": "address" + }, + { + "internalType": "bytes", + "name": "_data", + "type": "bytes" + } + ], + "stateMutability": "payable", + "type": "constructor" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "previousAdmin", + "type": "address" + }, + { + "indexed": false, + "internalType": "address", + "name": "newAdmin", + "type": "address" + } + ], + "name": "AdminChanged", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "beacon", + "type": "address" + } + ], + "name": "BeaconUpgraded", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "implementation", + "type": "address" + } + ], + "name": "Upgraded", + "type": "event" + }, + { + "stateMutability": "payable", + "type": "fallback" + }, + { + "inputs": [], + "name": "admin", + "outputs": [ + { + "internalType": "address", + "name": "admin_", + "type": "address" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "newAdmin", + "type": "address" + } + ], + "name": "changeAdmin", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "implementation", + "outputs": [ + { + "internalType": "address", + "name": "implementation_", + "type": "address" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "newImplementation", + "type": "address" + } + ], + "name": "upgradeTo", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "newImplementation", + "type": "address" + }, + { + "internalType": "bytes", + "name": "data", + "type": "bytes" + } + ], + "name": "upgradeToAndCall", + "outputs": [], + "stateMutability": "payable", + "type": "function" + }, + { + "stateMutability": "payable", + "type": "receive" + } + ], + "transactionHash": "0xd1d3ee46f5577e2c4fa3afd7810f460d256c0d38e77526f8fea654920a08b01e", + "receipt": { + "to": null, + "from": "0xfdA462548Ce04282f4B6D6619823a7C64Fdc0185", + "contractAddress": "0xf8588520E760BB0b3bDD62Ecb25186A28b0830ee", + "transactionIndex": 61, + "gasUsed": "735248", + "logsBloom": "0x00000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000002000000002000000002000000000000000000000080000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000400000000000000000000000000800000000000000000000000000000000002000000000000000000000000", + "blockHash": "0x3c300b5c4490e98f184bb4ac6598b21bc58a1a1b928467795678329ad96dccb4", + "transactionHash": "0xd1d3ee46f5577e2c4fa3afd7810f460d256c0d38e77526f8fea654920a08b01e", + "logs": [ + { + "transactionIndex": 61, + "blockNumber": 18975611, + "transactionHash": "0xd1d3ee46f5577e2c4fa3afd7810f460d256c0d38e77526f8fea654920a08b01e", + "address": "0xf8588520E760BB0b3bDD62Ecb25186A28b0830ee", + "topics": [ + "0xbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b", + "0x000000000000000000000000c772519b23426c4764c1ef0e67aab05db8063831" + ], + "data": "0x", + "logIndex": 133, + "blockHash": "0x3c300b5c4490e98f184bb4ac6598b21bc58a1a1b928467795678329ad96dccb4" + }, + { + "transactionIndex": 61, + "blockNumber": 18975611, + "transactionHash": "0xd1d3ee46f5577e2c4fa3afd7810f460d256c0d38e77526f8fea654920a08b01e", + "address": "0xf8588520E760BB0b3bDD62Ecb25186A28b0830ee", + "topics": [ + "0x7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f" + ], + "data": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000001d941ef0d3bba4ad67dbfbcee5262f4cee53a32b", + "logIndex": 134, + "blockHash": "0x3c300b5c4490e98f184bb4ac6598b21bc58a1a1b928467795678329ad96dccb4" + } + ], + "blockNumber": 18975611, + "cumulativeGasUsed": "5695288", + "status": 1, + "byzantium": true + }, + "args": [ + "0xc772519B23426c4764c1EF0e67aAB05db8063831", + "0x1D941EF0D3Bba4ad67DBfBCeE5262F4CEE53A32b", + "0x485cc9550000000000000000000000003fc5a1bd4d0a435c55374208a6a81535a19230390000000000000000000000000000206329b97db379d5e1bf586bbdb969c63274" + ], + "numDeployments": 1, + "solcInputHash": "871924e0c138825a2736b76def8fef8d", + "metadata": "{\"compiler\":{\"version\":\"0.8.17+commit.8df45f5f\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_logic\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"admin_\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"_data\",\"type\":\"bytes\"}],\"stateMutability\":\"payable\",\"type\":\"constructor\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"previousAdmin\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"newAdmin\",\"type\":\"address\"}],\"name\":\"AdminChanged\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"beacon\",\"type\":\"address\"}],\"name\":\"BeaconUpgraded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"implementation\",\"type\":\"address\"}],\"name\":\"Upgraded\",\"type\":\"event\"},{\"stateMutability\":\"payable\",\"type\":\"fallback\"},{\"inputs\":[],\"name\":\"admin\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"admin_\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newAdmin\",\"type\":\"address\"}],\"name\":\"changeAdmin\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"implementation\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"implementation_\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newImplementation\",\"type\":\"address\"}],\"name\":\"upgradeTo\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newImplementation\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"}],\"name\":\"upgradeToAndCall\",\"outputs\":[],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"stateMutability\":\"payable\",\"type\":\"receive\"}],\"devdoc\":{\"details\":\"This contract implements a proxy that is upgradeable by an admin. It is fully forked from OpenZeppelin `TransparentUpgradeableProxy` To avoid https://medium.com/nomic-labs-blog/malicious-backdoors-in-ethereum-proxies-62629adf3357[proxy selector clashing], which can potentially be used in an attack, this contract uses the https://blog.openzeppelin.com/the-transparent-proxy-pattern/[transparent proxy pattern]. This pattern implies two things that go hand in hand: 1. If any account other than the admin calls the proxy, the call will be forwarded to the implementation, even if that call matches one of the admin functions exposed by the proxy itself. 2. If the admin calls the proxy, it can access the admin functions, but its calls will never be forwarded to the implementation. If the admin tries to call a function on the implementation it will fail with an error that says \\\"admin cannot fallback to proxy target\\\". These properties mean that the admin account can only be used for admin actions like upgrading the proxy or changing the admin, so it's best if it's a dedicated account that is not used for anything else. This will avoid headaches due to sudden errors when trying to call a function from the proxy implementation. Our recommendation is for the dedicated account to be an instance of the {ProxyAdmin} contract. If set up this way, you should think of the `ProxyAdmin` instance as the real administrative interface of your proxy.\",\"kind\":\"dev\",\"methods\":{\"admin()\":{\"details\":\"Returns the current admin. NOTE: Only the admin can call this function. See {ProxyAdmin-getProxyAdmin}. TIP: To get this value clients can read directly from the storage slot shown below (specified by EIP1967) using the https://eth.wiki/json-rpc/API#eth_getstorageat[`eth_getStorageAt`] RPC call. `0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103`\"},\"changeAdmin(address)\":{\"details\":\"Changes the admin of the proxy. Emits an {AdminChanged} event. NOTE: Only the admin can call this function. See {ProxyAdmin-changeProxyAdmin}.\"},\"constructor\":{\"details\":\"Initializes an upgradeable proxy managed by `_admin`, backed by the implementation at `_logic`, and optionally initialized with `_data` as explained in {ERC1967Proxy-constructor}.\"},\"implementation()\":{\"details\":\"Returns the current implementation. NOTE: Only the admin can call this function. See {ProxyAdmin-getProxyImplementation}. TIP: To get this value clients can read directly from the storage slot shown below (specified by EIP1967) using the https://eth.wiki/json-rpc/API#eth_getstorageat[`eth_getStorageAt`] RPC call. `0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc`\"},\"upgradeTo(address)\":{\"details\":\"Upgrade the implementation of the proxy. NOTE: Only the admin can call this function. See {ProxyAdmin-upgrade}.\"},\"upgradeToAndCall(address,bytes)\":{\"details\":\"Upgrade the implementation of the proxy, and then call a function from the new implementation as specified by `data`, which should be an encoded function call. This is useful to initialize new storage variables in the proxied contract. NOTE: Only the admin can call this function. See {ProxyAdmin-upgradeAndCall}.\"}},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/external/TransparentUpgradeableProxy.sol\":\"TransparentUpgradeableProxy\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":1000000},\"remappings\":[]},\"sources\":{\"@openzeppelin/contracts/interfaces/draft-IERC1822.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.5.0) (interfaces/draft-IERC1822.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev ERC1822: Universal Upgradeable Proxy Standard (UUPS) documents a method for upgradeability through a simplified\\n * proxy whose upgrades are fully controlled by the current implementation.\\n */\\ninterface IERC1822Proxiable {\\n /**\\n * @dev Returns the storage slot that the proxiable contract assumes is being used to store the implementation\\n * address.\\n *\\n * IMPORTANT: A proxy pointing at a proxiable contract should not be considered proxiable itself, because this risks\\n * bricking a proxy that upgrades to it, by delegating to itself until out of gas. Thus it is critical that this\\n * function revert if invoked through a proxy.\\n */\\n function proxiableUUID() external view returns (bytes32);\\n}\\n\",\"keccak256\":\"0x1d4afe6cb24200cc4545eed814ecf5847277dfe5d613a1707aad5fceecebcfff\",\"license\":\"MIT\"},\"@openzeppelin/contracts/proxy/ERC1967/ERC1967Proxy.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.7.0) (proxy/ERC1967/ERC1967Proxy.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../Proxy.sol\\\";\\nimport \\\"./ERC1967Upgrade.sol\\\";\\n\\n/**\\n * @dev This contract implements an upgradeable proxy. It is upgradeable because calls are delegated to an\\n * implementation address that can be changed. This address is stored in storage in the location specified by\\n * https://eips.ethereum.org/EIPS/eip-1967[EIP1967], so that it doesn't conflict with the storage layout of the\\n * implementation behind the proxy.\\n */\\ncontract ERC1967Proxy is Proxy, ERC1967Upgrade {\\n /**\\n * @dev Initializes the upgradeable proxy with an initial implementation specified by `_logic`.\\n *\\n * If `_data` is nonempty, it's used as data in a delegate call to `_logic`. This will typically be an encoded\\n * function call, and allows initializing the storage of the proxy like a Solidity constructor.\\n */\\n constructor(address _logic, bytes memory _data) payable {\\n _upgradeToAndCall(_logic, _data, false);\\n }\\n\\n /**\\n * @dev Returns the current implementation address.\\n */\\n function _implementation() internal view virtual override returns (address impl) {\\n return ERC1967Upgrade._getImplementation();\\n }\\n}\\n\",\"keccak256\":\"0xa2b22da3032e50b55f95ec1d13336102d675f341167aa76db571ef7f8bb7975d\",\"license\":\"MIT\"},\"@openzeppelin/contracts/proxy/ERC1967/ERC1967Upgrade.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.5.0) (proxy/ERC1967/ERC1967Upgrade.sol)\\n\\npragma solidity ^0.8.2;\\n\\nimport \\\"../beacon/IBeacon.sol\\\";\\nimport \\\"../../interfaces/draft-IERC1822.sol\\\";\\nimport \\\"../../utils/Address.sol\\\";\\nimport \\\"../../utils/StorageSlot.sol\\\";\\n\\n/**\\n * @dev This abstract contract provides getters and event emitting update functions for\\n * https://eips.ethereum.org/EIPS/eip-1967[EIP1967] slots.\\n *\\n * _Available since v4.1._\\n *\\n * @custom:oz-upgrades-unsafe-allow delegatecall\\n */\\nabstract contract ERC1967Upgrade {\\n // This is the keccak-256 hash of \\\"eip1967.proxy.rollback\\\" subtracted by 1\\n bytes32 private constant _ROLLBACK_SLOT = 0x4910fdfa16fed3260ed0e7147f7cc6da11a60208b5b9406d12a635614ffd9143;\\n\\n /**\\n * @dev Storage slot with the address of the current implementation.\\n * This is the keccak-256 hash of \\\"eip1967.proxy.implementation\\\" subtracted by 1, and is\\n * validated in the constructor.\\n */\\n bytes32 internal constant _IMPLEMENTATION_SLOT = 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc;\\n\\n /**\\n * @dev Emitted when the implementation is upgraded.\\n */\\n event Upgraded(address indexed implementation);\\n\\n /**\\n * @dev Returns the current implementation address.\\n */\\n function _getImplementation() internal view returns (address) {\\n return StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value;\\n }\\n\\n /**\\n * @dev Stores a new address in the EIP1967 implementation slot.\\n */\\n function _setImplementation(address newImplementation) private {\\n require(Address.isContract(newImplementation), \\\"ERC1967: new implementation is not a contract\\\");\\n StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value = newImplementation;\\n }\\n\\n /**\\n * @dev Perform implementation upgrade\\n *\\n * Emits an {Upgraded} event.\\n */\\n function _upgradeTo(address newImplementation) internal {\\n _setImplementation(newImplementation);\\n emit Upgraded(newImplementation);\\n }\\n\\n /**\\n * @dev Perform implementation upgrade with additional setup call.\\n *\\n * Emits an {Upgraded} event.\\n */\\n function _upgradeToAndCall(\\n address newImplementation,\\n bytes memory data,\\n bool forceCall\\n ) internal {\\n _upgradeTo(newImplementation);\\n if (data.length > 0 || forceCall) {\\n Address.functionDelegateCall(newImplementation, data);\\n }\\n }\\n\\n /**\\n * @dev Perform implementation upgrade with security checks for UUPS proxies, and additional setup call.\\n *\\n * Emits an {Upgraded} event.\\n */\\n function _upgradeToAndCallUUPS(\\n address newImplementation,\\n bytes memory data,\\n bool forceCall\\n ) internal {\\n // Upgrades from old implementations will perform a rollback test. This test requires the new\\n // implementation to upgrade back to the old, non-ERC1822 compliant, implementation. Removing\\n // this special case will break upgrade paths from old UUPS implementation to new ones.\\n if (StorageSlot.getBooleanSlot(_ROLLBACK_SLOT).value) {\\n _setImplementation(newImplementation);\\n } else {\\n try IERC1822Proxiable(newImplementation).proxiableUUID() returns (bytes32 slot) {\\n require(slot == _IMPLEMENTATION_SLOT, \\\"ERC1967Upgrade: unsupported proxiableUUID\\\");\\n } catch {\\n revert(\\\"ERC1967Upgrade: new implementation is not UUPS\\\");\\n }\\n _upgradeToAndCall(newImplementation, data, forceCall);\\n }\\n }\\n\\n /**\\n * @dev Storage slot with the admin of the contract.\\n * This is the keccak-256 hash of \\\"eip1967.proxy.admin\\\" subtracted by 1, and is\\n * validated in the constructor.\\n */\\n bytes32 internal constant _ADMIN_SLOT = 0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103;\\n\\n /**\\n * @dev Emitted when the admin account has changed.\\n */\\n event AdminChanged(address previousAdmin, address newAdmin);\\n\\n /**\\n * @dev Returns the current admin.\\n */\\n function _getAdmin() internal view returns (address) {\\n return StorageSlot.getAddressSlot(_ADMIN_SLOT).value;\\n }\\n\\n /**\\n * @dev Stores a new address in the EIP1967 admin slot.\\n */\\n function _setAdmin(address newAdmin) private {\\n require(newAdmin != address(0), \\\"ERC1967: new admin is the zero address\\\");\\n StorageSlot.getAddressSlot(_ADMIN_SLOT).value = newAdmin;\\n }\\n\\n /**\\n * @dev Changes the admin of the proxy.\\n *\\n * Emits an {AdminChanged} event.\\n */\\n function _changeAdmin(address newAdmin) internal {\\n emit AdminChanged(_getAdmin(), newAdmin);\\n _setAdmin(newAdmin);\\n }\\n\\n /**\\n * @dev The storage slot of the UpgradeableBeacon contract which defines the implementation for this proxy.\\n * This is bytes32(uint256(keccak256('eip1967.proxy.beacon')) - 1)) and is validated in the constructor.\\n */\\n bytes32 internal constant _BEACON_SLOT = 0xa3f0ad74e5423aebfd80d3ef4346578335a9a72aeaee59ff6cb3582b35133d50;\\n\\n /**\\n * @dev Emitted when the beacon is upgraded.\\n */\\n event BeaconUpgraded(address indexed beacon);\\n\\n /**\\n * @dev Returns the current beacon.\\n */\\n function _getBeacon() internal view returns (address) {\\n return StorageSlot.getAddressSlot(_BEACON_SLOT).value;\\n }\\n\\n /**\\n * @dev Stores a new beacon in the EIP1967 beacon slot.\\n */\\n function _setBeacon(address newBeacon) private {\\n require(Address.isContract(newBeacon), \\\"ERC1967: new beacon is not a contract\\\");\\n require(\\n Address.isContract(IBeacon(newBeacon).implementation()),\\n \\\"ERC1967: beacon implementation is not a contract\\\"\\n );\\n StorageSlot.getAddressSlot(_BEACON_SLOT).value = newBeacon;\\n }\\n\\n /**\\n * @dev Perform beacon upgrade with additional setup call. Note: This upgrades the address of the beacon, it does\\n * not upgrade the implementation contained in the beacon (see {UpgradeableBeacon-_setImplementation} for that).\\n *\\n * Emits a {BeaconUpgraded} event.\\n */\\n function _upgradeBeaconToAndCall(\\n address newBeacon,\\n bytes memory data,\\n bool forceCall\\n ) internal {\\n _setBeacon(newBeacon);\\n emit BeaconUpgraded(newBeacon);\\n if (data.length > 0 || forceCall) {\\n Address.functionDelegateCall(IBeacon(newBeacon).implementation(), data);\\n }\\n }\\n}\\n\",\"keccak256\":\"0xabf3f59bc0e5423eae45e459dbe92e7052c6983628d39008590edc852a62f94a\",\"license\":\"MIT\"},\"@openzeppelin/contracts/proxy/Proxy.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.6.0) (proxy/Proxy.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev This abstract contract provides a fallback function that delegates all calls to another contract using the EVM\\n * instruction `delegatecall`. We refer to the second contract as the _implementation_ behind the proxy, and it has to\\n * be specified by overriding the virtual {_implementation} function.\\n *\\n * Additionally, delegation to the implementation can be triggered manually through the {_fallback} function, or to a\\n * different contract through the {_delegate} function.\\n *\\n * The success and return data of the delegated call will be returned back to the caller of the proxy.\\n */\\nabstract contract Proxy {\\n /**\\n * @dev Delegates the current call to `implementation`.\\n *\\n * This function does not return to its internal call site, it will return directly to the external caller.\\n */\\n function _delegate(address implementation) internal virtual {\\n assembly {\\n // Copy msg.data. We take full control of memory in this inline assembly\\n // block because it will not return to Solidity code. We overwrite the\\n // Solidity scratch pad at memory position 0.\\n calldatacopy(0, 0, calldatasize())\\n\\n // Call the implementation.\\n // out and outsize are 0 because we don't know the size yet.\\n let result := delegatecall(gas(), implementation, 0, calldatasize(), 0, 0)\\n\\n // Copy the returned data.\\n returndatacopy(0, 0, returndatasize())\\n\\n switch result\\n // delegatecall returns 0 on error.\\n case 0 {\\n revert(0, returndatasize())\\n }\\n default {\\n return(0, returndatasize())\\n }\\n }\\n }\\n\\n /**\\n * @dev This is a virtual function that should be overridden so it returns the address to which the fallback function\\n * and {_fallback} should delegate.\\n */\\n function _implementation() internal view virtual returns (address);\\n\\n /**\\n * @dev Delegates the current call to the address returned by `_implementation()`.\\n *\\n * This function does not return to its internal call site, it will return directly to the external caller.\\n */\\n function _fallback() internal virtual {\\n _beforeFallback();\\n _delegate(_implementation());\\n }\\n\\n /**\\n * @dev Fallback function that delegates calls to the address returned by `_implementation()`. Will run if no other\\n * function in the contract matches the call data.\\n */\\n fallback() external payable virtual {\\n _fallback();\\n }\\n\\n /**\\n * @dev Fallback function that delegates calls to the address returned by `_implementation()`. Will run if call data\\n * is empty.\\n */\\n receive() external payable virtual {\\n _fallback();\\n }\\n\\n /**\\n * @dev Hook that is called before falling back to the implementation. Can happen as part of a manual `_fallback`\\n * call, or as part of the Solidity `fallback` or `receive` functions.\\n *\\n * If overridden should call `super._beforeFallback()`.\\n */\\n function _beforeFallback() internal virtual {}\\n}\\n\",\"keccak256\":\"0xc130fe33f1b2132158531a87734153293f6d07bc263ff4ac90e85da9c82c0e27\",\"license\":\"MIT\"},\"@openzeppelin/contracts/proxy/beacon/IBeacon.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (proxy/beacon/IBeacon.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev This is the interface that {BeaconProxy} expects of its beacon.\\n */\\ninterface IBeacon {\\n /**\\n * @dev Must return an address that can be used as a delegate call target.\\n *\\n * {BeaconProxy} will check that this address is a contract.\\n */\\n function implementation() external view returns (address);\\n}\\n\",\"keccak256\":\"0xd50a3421ac379ccb1be435fa646d66a65c986b4924f0849839f08692f39dde61\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/Address.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.7.0) (utils/Address.sol)\\n\\npragma solidity ^0.8.1;\\n\\n/**\\n * @dev Collection of functions related to the address type\\n */\\nlibrary Address {\\n /**\\n * @dev Returns true if `account` is a contract.\\n *\\n * [IMPORTANT]\\n * ====\\n * It is unsafe to assume that an address for which this function returns\\n * false is an externally-owned account (EOA) and not a contract.\\n *\\n * Among others, `isContract` will return false for the following\\n * types of addresses:\\n *\\n * - an externally-owned account\\n * - a contract in construction\\n * - an address where a contract will be created\\n * - an address where a contract lived, but was destroyed\\n * ====\\n *\\n * [IMPORTANT]\\n * ====\\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\\n *\\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\\n * constructor.\\n * ====\\n */\\n function isContract(address account) internal view returns (bool) {\\n // This method relies on extcodesize/address.code.length, which returns 0\\n // for contracts in construction, since the code is only stored at the end\\n // of the constructor execution.\\n\\n return account.code.length > 0;\\n }\\n\\n /**\\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\\n * `recipient`, forwarding all available gas and reverting on errors.\\n *\\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\\n * imposed by `transfer`, making them unable to receive funds via\\n * `transfer`. {sendValue} removes this limitation.\\n *\\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\\n *\\n * IMPORTANT: because control is transferred to `recipient`, care must be\\n * taken to not create reentrancy vulnerabilities. Consider using\\n * {ReentrancyGuard} or the\\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\\n */\\n function sendValue(address payable recipient, uint256 amount) internal {\\n require(address(this).balance >= amount, \\\"Address: insufficient balance\\\");\\n\\n (bool success, ) = recipient.call{value: amount}(\\\"\\\");\\n require(success, \\\"Address: unable to send value, recipient may have reverted\\\");\\n }\\n\\n /**\\n * @dev Performs a Solidity function call using a low level `call`. A\\n * plain `call` is an unsafe replacement for a function call: use this\\n * function instead.\\n *\\n * If `target` reverts with a revert reason, it is bubbled up by this\\n * function (like regular Solidity function calls).\\n *\\n * Returns the raw returned data. To convert to the expected return value,\\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\\n *\\n * Requirements:\\n *\\n * - `target` must be a contract.\\n * - calling `target` with `data` must not revert.\\n *\\n * _Available since v3.1._\\n */\\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\\n return functionCall(target, data, \\\"Address: low-level call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\\n * `errorMessage` as a fallback revert reason when `target` reverts.\\n *\\n * _Available since v3.1._\\n */\\n function functionCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n return functionCallWithValue(target, data, 0, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but also transferring `value` wei to `target`.\\n *\\n * Requirements:\\n *\\n * - the calling contract must have an ETH balance of at least `value`.\\n * - the called Solidity function must be `payable`.\\n *\\n * _Available since v3.1._\\n */\\n function functionCallWithValue(\\n address target,\\n bytes memory data,\\n uint256 value\\n ) internal returns (bytes memory) {\\n return functionCallWithValue(target, data, value, \\\"Address: low-level call with value failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\\n * with `errorMessage` as a fallback revert reason when `target` reverts.\\n *\\n * _Available since v3.1._\\n */\\n function functionCallWithValue(\\n address target,\\n bytes memory data,\\n uint256 value,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n require(address(this).balance >= value, \\\"Address: insufficient balance for call\\\");\\n require(isContract(target), \\\"Address: call to non-contract\\\");\\n\\n (bool success, bytes memory returndata) = target.call{value: value}(data);\\n return verifyCallResult(success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but performing a static call.\\n *\\n * _Available since v3.3._\\n */\\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\\n return functionStaticCall(target, data, \\\"Address: low-level static call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\\n * but performing a static call.\\n *\\n * _Available since v3.3._\\n */\\n function functionStaticCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal view returns (bytes memory) {\\n require(isContract(target), \\\"Address: static call to non-contract\\\");\\n\\n (bool success, bytes memory returndata) = target.staticcall(data);\\n return verifyCallResult(success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but performing a delegate call.\\n *\\n * _Available since v3.4._\\n */\\n function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {\\n return functionDelegateCall(target, data, \\\"Address: low-level delegate call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\\n * but performing a delegate call.\\n *\\n * _Available since v3.4._\\n */\\n function functionDelegateCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n require(isContract(target), \\\"Address: delegate call to non-contract\\\");\\n\\n (bool success, bytes memory returndata) = target.delegatecall(data);\\n return verifyCallResult(success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the\\n * revert reason using the provided one.\\n *\\n * _Available since v4.3._\\n */\\n function verifyCallResult(\\n bool success,\\n bytes memory returndata,\\n string memory errorMessage\\n ) internal pure returns (bytes memory) {\\n if (success) {\\n return returndata;\\n } else {\\n // Look for revert reason and bubble it up if present\\n if (returndata.length > 0) {\\n // The easiest way to bubble the revert reason is using memory via assembly\\n /// @solidity memory-safe-assembly\\n assembly {\\n let returndata_size := mload(returndata)\\n revert(add(32, returndata), returndata_size)\\n }\\n } else {\\n revert(errorMessage);\\n }\\n }\\n }\\n}\\n\",\"keccak256\":\"0xd6153ce99bcdcce22b124f755e72553295be6abcd63804cfdffceb188b8bef10\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/StorageSlot.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.7.0) (utils/StorageSlot.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Library for reading and writing primitive types to specific storage slots.\\n *\\n * Storage slots are often used to avoid storage conflict when dealing with upgradeable contracts.\\n * This library helps with reading and writing to such slots without the need for inline assembly.\\n *\\n * The functions in this library return Slot structs that contain a `value` member that can be used to read or write.\\n *\\n * Example usage to set ERC1967 implementation slot:\\n * ```\\n * contract ERC1967 {\\n * bytes32 internal constant _IMPLEMENTATION_SLOT = 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc;\\n *\\n * function _getImplementation() internal view returns (address) {\\n * return StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value;\\n * }\\n *\\n * function _setImplementation(address newImplementation) internal {\\n * require(Address.isContract(newImplementation), \\\"ERC1967: new implementation is not a contract\\\");\\n * StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value = newImplementation;\\n * }\\n * }\\n * ```\\n *\\n * _Available since v4.1 for `address`, `bool`, `bytes32`, and `uint256`._\\n */\\nlibrary StorageSlot {\\n struct AddressSlot {\\n address value;\\n }\\n\\n struct BooleanSlot {\\n bool value;\\n }\\n\\n struct Bytes32Slot {\\n bytes32 value;\\n }\\n\\n struct Uint256Slot {\\n uint256 value;\\n }\\n\\n /**\\n * @dev Returns an `AddressSlot` with member `value` located at `slot`.\\n */\\n function getAddressSlot(bytes32 slot) internal pure returns (AddressSlot storage r) {\\n /// @solidity memory-safe-assembly\\n assembly {\\n r.slot := slot\\n }\\n }\\n\\n /**\\n * @dev Returns an `BooleanSlot` with member `value` located at `slot`.\\n */\\n function getBooleanSlot(bytes32 slot) internal pure returns (BooleanSlot storage r) {\\n /// @solidity memory-safe-assembly\\n assembly {\\n r.slot := slot\\n }\\n }\\n\\n /**\\n * @dev Returns an `Bytes32Slot` with member `value` located at `slot`.\\n */\\n function getBytes32Slot(bytes32 slot) internal pure returns (Bytes32Slot storage r) {\\n /// @solidity memory-safe-assembly\\n assembly {\\n r.slot := slot\\n }\\n }\\n\\n /**\\n * @dev Returns an `Uint256Slot` with member `value` located at `slot`.\\n */\\n function getUint256Slot(bytes32 slot) internal pure returns (Uint256Slot storage r) {\\n /// @solidity memory-safe-assembly\\n assembly {\\n r.slot := slot\\n }\\n }\\n}\\n\",\"keccak256\":\"0xd5c50c54bf02740ebd122ff06832546cb5fa84486d52695a9ccfd11666e0c81d\",\"license\":\"MIT\"},\"contracts/external/TransparentUpgradeableProxy.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-3.0\\n\\npragma solidity ^0.8.12;\\n\\nimport \\\"@openzeppelin/contracts/proxy/ERC1967/ERC1967Proxy.sol\\\";\\n\\n/**\\n * @dev This contract implements a proxy that is upgradeable by an admin. It is fully forked from OpenZeppelin\\n * `TransparentUpgradeableProxy`\\n *\\n * To avoid https://medium.com/nomic-labs-blog/malicious-backdoors-in-ethereum-proxies-62629adf3357[proxy selector\\n * clashing], which can potentially be used in an attack, this contract uses the\\n * https://blog.openzeppelin.com/the-transparent-proxy-pattern/[transparent proxy pattern]. This pattern implies two\\n * things that go hand in hand:\\n *\\n * 1. If any account other than the admin calls the proxy, the call will be forwarded to the implementation, even if\\n * that call matches one of the admin functions exposed by the proxy itself.\\n * 2. If the admin calls the proxy, it can access the admin functions, but its calls will never be forwarded to the\\n * implementation. If the admin tries to call a function on the implementation it will fail with an error that says\\n * \\\"admin cannot fallback to proxy target\\\".\\n *\\n * These properties mean that the admin account can only be used for admin actions like upgrading the proxy or changing\\n * the admin, so it's best if it's a dedicated account that is not used for anything else. This will avoid headaches due\\n * to sudden errors when trying to call a function from the proxy implementation.\\n *\\n * Our recommendation is for the dedicated account to be an instance of the {ProxyAdmin} contract. If set up this way,\\n * you should think of the `ProxyAdmin` instance as the real administrative interface of your proxy.\\n */\\ncontract TransparentUpgradeableProxy is ERC1967Proxy {\\n /**\\n * @dev Initializes an upgradeable proxy managed by `_admin`, backed by the implementation at `_logic`, and\\n * optionally initialized with `_data` as explained in {ERC1967Proxy-constructor}.\\n */\\n constructor(address _logic, address admin_, bytes memory _data) payable ERC1967Proxy(_logic, _data) {\\n assert(_ADMIN_SLOT == bytes32(uint256(keccak256(\\\"eip1967.proxy.admin\\\")) - 1));\\n _changeAdmin(admin_);\\n }\\n\\n /**\\n * @dev Modifier used internally that will delegate the call to the implementation unless the sender is the admin.\\n */\\n modifier ifAdmin() {\\n if (msg.sender == _getAdmin()) {\\n _;\\n } else {\\n _fallback();\\n }\\n }\\n\\n /**\\n * @dev Returns the current admin.\\n *\\n * NOTE: Only the admin can call this function. See {ProxyAdmin-getProxyAdmin}.\\n *\\n * TIP: To get this value clients can read directly from the storage slot shown below (specified by EIP1967) using the\\n * https://eth.wiki/json-rpc/API#eth_getstorageat[`eth_getStorageAt`] RPC call.\\n * `0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103`\\n */\\n function admin() external ifAdmin returns (address admin_) {\\n admin_ = _getAdmin();\\n }\\n\\n /**\\n * @dev Returns the current implementation.\\n *\\n * NOTE: Only the admin can call this function. See {ProxyAdmin-getProxyImplementation}.\\n *\\n * TIP: To get this value clients can read directly from the storage slot shown below (specified by EIP1967) using the\\n * https://eth.wiki/json-rpc/API#eth_getstorageat[`eth_getStorageAt`] RPC call.\\n * `0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc`\\n */\\n function implementation() external ifAdmin returns (address implementation_) {\\n implementation_ = _implementation();\\n }\\n\\n /**\\n * @dev Changes the admin of the proxy.\\n *\\n * Emits an {AdminChanged} event.\\n *\\n * NOTE: Only the admin can call this function. See {ProxyAdmin-changeProxyAdmin}.\\n */\\n function changeAdmin(address newAdmin) external virtual ifAdmin {\\n _changeAdmin(newAdmin);\\n }\\n\\n /**\\n * @dev Upgrade the implementation of the proxy.\\n *\\n * NOTE: Only the admin can call this function. See {ProxyAdmin-upgrade}.\\n */\\n function upgradeTo(address newImplementation) external ifAdmin {\\n _upgradeToAndCall(newImplementation, bytes(\\\"\\\"), false);\\n }\\n\\n /**\\n * @dev Upgrade the implementation of the proxy, and then call a function from the new implementation as specified\\n * by `data`, which should be an encoded function call. This is useful to initialize new storage variables in the\\n * proxied contract.\\n *\\n * NOTE: Only the admin can call this function. See {ProxyAdmin-upgradeAndCall}.\\n */\\n function upgradeToAndCall(address newImplementation, bytes calldata data) external payable ifAdmin {\\n _upgradeToAndCall(newImplementation, data, true);\\n }\\n\\n /**\\n * @dev Returns the current admin.\\n */\\n function _admin() internal view virtual returns (address) {\\n return _getAdmin();\\n }\\n\\n /**\\n * @dev Makes sure the admin cannot access the fallback function. See {Proxy-_beforeFallback}.\\n */\\n function _beforeFallback() internal virtual override {\\n require(msg.sender != _getAdmin(), \\\"TransparentUpgradeableProxy: admin cannot fallback to proxy target\\\");\\n super._beforeFallback();\\n }\\n}\\n\",\"keccak256\":\"0x93a67a0f612ea3ff2a76315e138a6a88267270a1379d3cc7be52845fbbe611e2\",\"license\":\"GPL-3.0\"}},\"version\":1}", + "bytecode": "0x6080604052604051620010bb380380620010bb8339810160408190526200002691620004d8565b828162000036828260006200009a565b5062000066905060017fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6104620005b8565b6000805160206200107483398151915214620000865762000086620005da565b6200009182620000d7565b50505062000643565b620000a58362000132565b600082511180620000b35750805b15620000d257620000d083836200017460201b6200028c1760201c565b505b505050565b7f7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f62000102620001a5565b604080516001600160a01b03928316815291841660208301520160405180910390a16200012f81620001de565b50565b6200013d8162000293565b6040516001600160a01b038216907fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b90600090a250565b60606200019c8383604051806060016040528060278152602001620010946027913962000347565b90505b92915050565b6000620001cf6000805160206200107483398151915260001b6200042f60201b6200022e1760201c565b546001600160a01b0316919050565b6001600160a01b038116620002495760405162461bcd60e51b815260206004820152602660248201527f455243313936373a206e65772061646d696e20697320746865207a65726f206160448201526564647265737360d01b60648201526084015b60405180910390fd5b80620002726000805160206200107483398151915260001b6200042f60201b6200022e1760201c565b80546001600160a01b0319166001600160a01b039290921691909117905550565b620002a9816200043260201b620002b81760201c565b6200030d5760405162461bcd60e51b815260206004820152602d60248201527f455243313936373a206e657720696d706c656d656e746174696f6e206973206e60448201526c1bdd08184818dbdb9d1c9858dd609a1b606482015260840162000240565b80620002727f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc60001b6200042f60201b6200022e1760201c565b60606001600160a01b0384163b620003b15760405162461bcd60e51b815260206004820152602660248201527f416464726573733a2064656c65676174652063616c6c20746f206e6f6e2d636f6044820152651b9d1c9858dd60d21b606482015260840162000240565b600080856001600160a01b031685604051620003ce9190620005f0565b600060405180830381855af49150503d80600081146200040b576040519150601f19603f3d011682016040523d82523d6000602084013e62000410565b606091505b5090925090506200042382828662000441565b925050505b9392505050565b90565b6001600160a01b03163b151590565b606083156200045257508162000428565b825115620004635782518084602001fd5b8160405162461bcd60e51b81526004016200024091906200060e565b80516001600160a01b03811681146200049757600080fd5b919050565b634e487b7160e01b600052604160045260246000fd5b60005b83811015620004cf578181015183820152602001620004b5565b50506000910152565b600080600060608486031215620004ee57600080fd5b620004f9846200047f565b925062000509602085016200047f565b60408501519092506001600160401b03808211156200052757600080fd5b818601915086601f8301126200053c57600080fd5b8151818111156200055157620005516200049c565b604051601f8201601f19908116603f011681019083821181831017156200057c576200057c6200049c565b816040528281528960208487010111156200059657600080fd5b620005a9836020830160208801620004b2565b80955050505050509250925092565b818103818111156200019f57634e487b7160e01b600052601160045260246000fd5b634e487b7160e01b600052600160045260246000fd5b6000825162000604818460208701620004b2565b9190910192915050565b60208152600082518060208401526200062f816040850160208701620004b2565b601f01601f19169190910160400192915050565b610a2180620006536000396000f3fe60806040526004361061005e5760003560e01c80635c60da1b116100435780635c60da1b146100a85780638f283970146100e6578063f851a440146101065761006d565b80633659cfe6146100755780634f1ef286146100955761006d565b3661006d5761006b61011b565b005b61006b61011b565b34801561008157600080fd5b5061006b610090366004610895565b610135565b61006b6100a33660046108b0565b61017f565b3480156100b457600080fd5b506100bd6101f3565b60405173ffffffffffffffffffffffffffffffffffffffff909116815260200160405180910390f35b3480156100f257600080fd5b5061006b610101366004610895565b610231565b34801561011257600080fd5b506100bd61025e565b6101236102d4565b61013361012e6103ab565b6103b5565b565b61013d6103d9565b73ffffffffffffffffffffffffffffffffffffffff1633036101775761017481604051806020016040528060008152506000610419565b50565b61017461011b565b6101876103d9565b73ffffffffffffffffffffffffffffffffffffffff1633036101eb576101e68383838080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525060019250610419915050565b505050565b6101e661011b565b60006101fd6103d9565b73ffffffffffffffffffffffffffffffffffffffff163303610226576102216103ab565b905090565b61022e61011b565b90565b6102396103d9565b73ffffffffffffffffffffffffffffffffffffffff1633036101775761017481610444565b60006102686103d9565b73ffffffffffffffffffffffffffffffffffffffff163303610226576102216103d9565b60606102b183836040518060600160405280602781526020016109c5602791396104a5565b9392505050565b73ffffffffffffffffffffffffffffffffffffffff163b151590565b6102dc6103d9565b73ffffffffffffffffffffffffffffffffffffffff163303610133576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604260248201527f5472616e73706172656e745570677261646561626c6550726f78793a2061646d60448201527f696e2063616e6e6f742066616c6c6261636b20746f2070726f7879207461726760648201527f6574000000000000000000000000000000000000000000000000000000000000608482015260a4015b60405180910390fd5b60006102216105cd565b3660008037600080366000845af43d6000803e8080156103d4573d6000f35b3d6000fd5b60007fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035b5473ffffffffffffffffffffffffffffffffffffffff16919050565b610422836105f5565b60008251118061042f5750805b156101e65761043e838361028c565b50505050565b7f7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f61046d6103d9565b6040805173ffffffffffffffffffffffffffffffffffffffff928316815291841660208301520160405180910390a161017481610642565b606073ffffffffffffffffffffffffffffffffffffffff84163b61054b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f416464726573733a2064656c65676174652063616c6c20746f206e6f6e2d636f60448201527f6e7472616374000000000000000000000000000000000000000000000000000060648201526084016103a2565b6000808573ffffffffffffffffffffffffffffffffffffffff16856040516105739190610957565b600060405180830381855af49150503d80600081146105ae576040519150601f19603f3d011682016040523d82523d6000602084013e6105b3565b606091505b50915091506105c382828661074e565b9695505050505050565b60007f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc6103fd565b6105fe816107a1565b60405173ffffffffffffffffffffffffffffffffffffffff8216907fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b90600090a250565b73ffffffffffffffffffffffffffffffffffffffff81166106e5576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f455243313936373a206e65772061646d696e20697320746865207a65726f206160448201527f646472657373000000000000000000000000000000000000000000000000000060648201526084016103a2565b807fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035b80547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff9290921691909117905550565b6060831561075d5750816102b1565b82511561076d5782518084602001fd5b816040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016103a29190610973565b73ffffffffffffffffffffffffffffffffffffffff81163b610845576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602d60248201527f455243313936373a206e657720696d706c656d656e746174696f6e206973206e60448201527f6f74206120636f6e74726163740000000000000000000000000000000000000060648201526084016103a2565b807f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc610708565b803573ffffffffffffffffffffffffffffffffffffffff8116811461089057600080fd5b919050565b6000602082840312156108a757600080fd5b6102b18261086c565b6000806000604084860312156108c557600080fd5b6108ce8461086c565b9250602084013567ffffffffffffffff808211156108eb57600080fd5b818601915086601f8301126108ff57600080fd5b81358181111561090e57600080fd5b87602082850101111561092057600080fd5b6020830194508093505050509250925092565b60005b8381101561094e578181015183820152602001610936565b50506000910152565b60008251610969818460208701610933565b9190910192915050565b6020815260008251806020840152610992816040850160208701610933565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016919091016040019291505056fe416464726573733a206c6f772d6c6576656c2064656c65676174652063616c6c206661696c6564a2646970667358221220e96638b07fb1675d93a95c49e417bc8111448b23a59918698cdcd8fd488dd7cf64736f6c63430008110033b53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103416464726573733a206c6f772d6c6576656c2064656c65676174652063616c6c206661696c6564", + "deployedBytecode": "0x60806040526004361061005e5760003560e01c80635c60da1b116100435780635c60da1b146100a85780638f283970146100e6578063f851a440146101065761006d565b80633659cfe6146100755780634f1ef286146100955761006d565b3661006d5761006b61011b565b005b61006b61011b565b34801561008157600080fd5b5061006b610090366004610895565b610135565b61006b6100a33660046108b0565b61017f565b3480156100b457600080fd5b506100bd6101f3565b60405173ffffffffffffffffffffffffffffffffffffffff909116815260200160405180910390f35b3480156100f257600080fd5b5061006b610101366004610895565b610231565b34801561011257600080fd5b506100bd61025e565b6101236102d4565b61013361012e6103ab565b6103b5565b565b61013d6103d9565b73ffffffffffffffffffffffffffffffffffffffff1633036101775761017481604051806020016040528060008152506000610419565b50565b61017461011b565b6101876103d9565b73ffffffffffffffffffffffffffffffffffffffff1633036101eb576101e68383838080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525060019250610419915050565b505050565b6101e661011b565b60006101fd6103d9565b73ffffffffffffffffffffffffffffffffffffffff163303610226576102216103ab565b905090565b61022e61011b565b90565b6102396103d9565b73ffffffffffffffffffffffffffffffffffffffff1633036101775761017481610444565b60006102686103d9565b73ffffffffffffffffffffffffffffffffffffffff163303610226576102216103d9565b60606102b183836040518060600160405280602781526020016109c5602791396104a5565b9392505050565b73ffffffffffffffffffffffffffffffffffffffff163b151590565b6102dc6103d9565b73ffffffffffffffffffffffffffffffffffffffff163303610133576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604260248201527f5472616e73706172656e745570677261646561626c6550726f78793a2061646d60448201527f696e2063616e6e6f742066616c6c6261636b20746f2070726f7879207461726760648201527f6574000000000000000000000000000000000000000000000000000000000000608482015260a4015b60405180910390fd5b60006102216105cd565b3660008037600080366000845af43d6000803e8080156103d4573d6000f35b3d6000fd5b60007fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035b5473ffffffffffffffffffffffffffffffffffffffff16919050565b610422836105f5565b60008251118061042f5750805b156101e65761043e838361028c565b50505050565b7f7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f61046d6103d9565b6040805173ffffffffffffffffffffffffffffffffffffffff928316815291841660208301520160405180910390a161017481610642565b606073ffffffffffffffffffffffffffffffffffffffff84163b61054b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f416464726573733a2064656c65676174652063616c6c20746f206e6f6e2d636f60448201527f6e7472616374000000000000000000000000000000000000000000000000000060648201526084016103a2565b6000808573ffffffffffffffffffffffffffffffffffffffff16856040516105739190610957565b600060405180830381855af49150503d80600081146105ae576040519150601f19603f3d011682016040523d82523d6000602084013e6105b3565b606091505b50915091506105c382828661074e565b9695505050505050565b60007f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc6103fd565b6105fe816107a1565b60405173ffffffffffffffffffffffffffffffffffffffff8216907fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b90600090a250565b73ffffffffffffffffffffffffffffffffffffffff81166106e5576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f455243313936373a206e65772061646d696e20697320746865207a65726f206160448201527f646472657373000000000000000000000000000000000000000000000000000060648201526084016103a2565b807fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035b80547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff9290921691909117905550565b6060831561075d5750816102b1565b82511561076d5782518084602001fd5b816040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016103a29190610973565b73ffffffffffffffffffffffffffffffffffffffff81163b610845576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602d60248201527f455243313936373a206e657720696d706c656d656e746174696f6e206973206e60448201527f6f74206120636f6e74726163740000000000000000000000000000000000000060648201526084016103a2565b807f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc610708565b803573ffffffffffffffffffffffffffffffffffffffff8116811461089057600080fd5b919050565b6000602082840312156108a757600080fd5b6102b18261086c565b6000806000604084860312156108c557600080fd5b6108ce8461086c565b9250602084013567ffffffffffffffff808211156108eb57600080fd5b818601915086601f8301126108ff57600080fd5b81358181111561090e57600080fd5b87602082850101111561092057600080fd5b6020830194508093505050509250925092565b60005b8381101561094e578181015183820152602001610936565b50506000910152565b60008251610969818460208701610933565b9190910192915050565b6020815260008251806020840152610992816040850160208701610933565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016919091016040019291505056fe416464726573733a206c6f772d6c6576656c2064656c65676174652063616c6c206661696c6564a2646970667358221220e96638b07fb1675d93a95c49e417bc8111448b23a59918698cdcd8fd488dd7cf64736f6c63430008110033", + "devdoc": { + "details": "This contract implements a proxy that is upgradeable by an admin. It is fully forked from OpenZeppelin `TransparentUpgradeableProxy` To avoid https://medium.com/nomic-labs-blog/malicious-backdoors-in-ethereum-proxies-62629adf3357[proxy selector clashing], which can potentially be used in an attack, this contract uses the https://blog.openzeppelin.com/the-transparent-proxy-pattern/[transparent proxy pattern]. This pattern implies two things that go hand in hand: 1. If any account other than the admin calls the proxy, the call will be forwarded to the implementation, even if that call matches one of the admin functions exposed by the proxy itself. 2. If the admin calls the proxy, it can access the admin functions, but its calls will never be forwarded to the implementation. If the admin tries to call a function on the implementation it will fail with an error that says \"admin cannot fallback to proxy target\". These properties mean that the admin account can only be used for admin actions like upgrading the proxy or changing the admin, so it's best if it's a dedicated account that is not used for anything else. This will avoid headaches due to sudden errors when trying to call a function from the proxy implementation. Our recommendation is for the dedicated account to be an instance of the {ProxyAdmin} contract. If set up this way, you should think of the `ProxyAdmin` instance as the real administrative interface of your proxy.", + "kind": "dev", + "methods": { + "admin()": { + "details": "Returns the current admin. NOTE: Only the admin can call this function. See {ProxyAdmin-getProxyAdmin}. TIP: To get this value clients can read directly from the storage slot shown below (specified by EIP1967) using the https://eth.wiki/json-rpc/API#eth_getstorageat[`eth_getStorageAt`] RPC call. `0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103`" + }, + "changeAdmin(address)": { + "details": "Changes the admin of the proxy. Emits an {AdminChanged} event. NOTE: Only the admin can call this function. See {ProxyAdmin-changeProxyAdmin}." + }, + "constructor": { + "details": "Initializes an upgradeable proxy managed by `_admin`, backed by the implementation at `_logic`, and optionally initialized with `_data` as explained in {ERC1967Proxy-constructor}." + }, + "implementation()": { + "details": "Returns the current implementation. NOTE: Only the admin can call this function. See {ProxyAdmin-getProxyImplementation}. TIP: To get this value clients can read directly from the storage slot shown below (specified by EIP1967) using the https://eth.wiki/json-rpc/API#eth_getstorageat[`eth_getStorageAt`] RPC call. `0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc`" + }, + "upgradeTo(address)": { + "details": "Upgrade the implementation of the proxy. NOTE: Only the admin can call this function. See {ProxyAdmin-upgrade}." + }, + "upgradeToAndCall(address,bytes)": { + "details": "Upgrade the implementation of the proxy, and then call a function from the new implementation as specified by `data`, which should be an encoded function call. This is useful to initialize new storage variables in the proxied contract. NOTE: Only the admin can call this function. See {ProxyAdmin-upgradeAndCall}." + } + }, + "version": 1 + }, + "userdoc": { + "kind": "user", + "methods": {}, + "version": 1 + }, + "storageLayout": { + "storage": [], + "types": null + } +} \ No newline at end of file diff --git a/deployments/mainnet/VaultManager_NoDust.json b/deployments/mainnet/VaultManager_NoDust.json new file mode 100644 index 00000000..d5f7ff71 --- /dev/null +++ b/deployments/mainnet/VaultManager_NoDust.json @@ -0,0 +1,1828 @@ +{ + "address": "0xAe4D5A4308DB411f70B572f0D5ace4e41E3346A7", + "abi": [ + { + "inputs": [], + "name": "ApprovalToCaller", + "type": "error" + }, + { + "inputs": [], + "name": "ApprovalToOwner", + "type": "error" + }, + { + "inputs": [], + "name": "DebtCeilingExceeded", + "type": "error" + }, + { + "inputs": [], + "name": "DustyLeftoverAmount", + "type": "error" + }, + { + "inputs": [], + "name": "ExpiredDeadline", + "type": "error" + }, + { + "inputs": [], + "name": "HealthyVault", + "type": "error" + }, + { + "inputs": [], + "name": "IncompatibleLengths", + "type": "error" + }, + { + "inputs": [], + "name": "InsolventVault", + "type": "error" + }, + { + "inputs": [], + "name": "InvalidParameterType", + "type": "error" + }, + { + "inputs": [], + "name": "InvalidParameterValue", + "type": "error" + }, + { + "inputs": [], + "name": "InvalidSetOfParameters", + "type": "error" + }, + { + "inputs": [], + "name": "InvalidSignature", + "type": "error" + }, + { + "inputs": [], + "name": "InvalidTreasury", + "type": "error" + }, + { + "inputs": [], + "name": "NonERC721Receiver", + "type": "error" + }, + { + "inputs": [], + "name": "NonexistentVault", + "type": "error" + }, + { + "inputs": [], + "name": "NotApproved", + "type": "error" + }, + { + "inputs": [], + "name": "NotGovernor", + "type": "error" + }, + { + "inputs": [], + "name": "NotGovernorOrGuardian", + "type": "error" + }, + { + "inputs": [], + "name": "NotTreasury", + "type": "error" + }, + { + "inputs": [], + "name": "NotVaultManager", + "type": "error" + }, + { + "inputs": [], + "name": "NotWhitelisted", + "type": "error" + }, + { + "inputs": [], + "name": "Paused", + "type": "error" + }, + { + "inputs": [], + "name": "TooHighParameterValue", + "type": "error" + }, + { + "inputs": [], + "name": "TooSmallParameterValue", + "type": "error" + }, + { + "inputs": [], + "name": "ZeroAddress", + "type": "error" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint256", + "name": "surplusEndValue", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "badDebtEndValue", + "type": "uint256" + } + ], + "name": "AccruedToTreasury", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "owner", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "approved", + "type": "address" + }, + { + "indexed": true, + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + } + ], + "name": "Approval", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "owner", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "operator", + "type": "address" + }, + { + "indexed": false, + "internalType": "bool", + "name": "approved", + "type": "bool" + } + ], + "name": "ApprovalForAll", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint256", + "name": "vaultID", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "collateralAmount", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint8", + "name": "isIncrease", + "type": "uint8" + } + ], + "name": "CollateralAmountUpdated", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint256", + "name": "debtCeiling", + "type": "uint256" + } + ], + "name": "DebtCeilingUpdated", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint256", + "name": "srcVaultID", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "dstVaultID", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "address", + "name": "dstVaultManager", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "DebtTransferred", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint64", + "name": "param", + "type": "uint64" + }, + { + "indexed": false, + "internalType": "bytes32", + "name": "what", + "type": "bytes32" + } + ], + "name": "FiledUint64", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint8", + "name": "version", + "type": "uint8" + } + ], + "name": "Initialized", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint256", + "name": "value", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "timestamp", + "type": "uint256" + } + ], + "name": "InterestAccumulatorUpdated", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint256", + "name": "vaultID", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "internalAmount", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint8", + "name": "isIncrease", + "type": "uint8" + } + ], + "name": "InternalDebtUpdated", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint256[]", + "name": "vaultIDs", + "type": "uint256[]" + } + ], + "name": "LiquidatedVaults", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "_veBoostProxy", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256[]", + "name": "xBoost", + "type": "uint256[]" + }, + { + "indexed": false, + "internalType": "uint256[]", + "name": "yBoost", + "type": "uint256[]" + } + ], + "name": "LiquidationBoostParametersUpdated", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "from", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "indexed": true, + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + } + ], + "name": "Transfer", + "type": "event" + }, + { + "inputs": [], + "name": "BASE_INTEREST", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "BASE_PARAMS", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "DOMAIN_SEPARATOR", + "outputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "HALF_BASE_INTEREST", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "accrueInterestToTreasury", + "outputs": [ + { + "internalType": "uint256", + "name": "surplusValue", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "badDebtValue", + "type": "uint256" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "enum ActionType[]", + "name": "actions", + "type": "uint8[]" + }, + { + "internalType": "bytes[]", + "name": "datas", + "type": "bytes[]" + }, + { + "internalType": "address", + "name": "from", + "type": "address" + }, + { + "internalType": "address", + "name": "to", + "type": "address" + } + ], + "name": "angle", + "outputs": [ + { + "components": [ + { + "internalType": "uint256", + "name": "stablecoinAmountToGive", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "stablecoinAmountToReceive", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "collateralAmountToGive", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "collateralAmountToReceive", + "type": "uint256" + } + ], + "internalType": "struct PaymentData", + "name": "", + "type": "tuple" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "enum ActionType[]", + "name": "actions", + "type": "uint8[]" + }, + { + "internalType": "bytes[]", + "name": "datas", + "type": "bytes[]" + }, + { + "internalType": "address", + "name": "from", + "type": "address" + }, + { + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "internalType": "address", + "name": "who", + "type": "address" + }, + { + "internalType": "bytes", + "name": "repayData", + "type": "bytes" + } + ], + "name": "angle", + "outputs": [ + { + "components": [ + { + "internalType": "uint256", + "name": "stablecoinAmountToGive", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "stablecoinAmountToReceive", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "collateralAmountToGive", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "collateralAmountToReceive", + "type": "uint256" + } + ], + "internalType": "struct PaymentData", + "name": "paymentData", + "type": "tuple" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "internalType": "uint256", + "name": "vaultID", + "type": "uint256" + } + ], + "name": "approve", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "badDebt", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "owner", + "type": "address" + } + ], + "name": "balanceOf", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "borrowFee", + "outputs": [ + { + "internalType": "uint64", + "name": "", + "type": "uint64" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "vaultID", + "type": "uint256" + }, + { + "internalType": "address", + "name": "liquidator", + "type": "address" + } + ], + "name": "checkLiquidation", + "outputs": [ + { + "components": [ + { + "internalType": "uint256", + "name": "maxStablecoinAmountToRepay", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "maxCollateralAmountGiven", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "thresholdRepayAmount", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "discount", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "currentDebt", + "type": "uint256" + } + ], + "internalType": "struct LiquidationOpportunity", + "name": "liqOpp", + "type": "tuple" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "collateral", + "outputs": [ + { + "internalType": "contract IERC20", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "collateralFactor", + "outputs": [ + { + "internalType": "uint64", + "name": "", + "type": "uint64" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "toVault", + "type": "address" + } + ], + "name": "createVault", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "debtCeiling", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "dust", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "dustLiquidation", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "vaultID", + "type": "uint256" + } + ], + "name": "getApproved", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "vaultID", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "stablecoinAmount", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "senderBorrowFee", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "senderRepayFee", + "type": "uint256" + } + ], + "name": "getDebtOut", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "getTotalDebt", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "vaultID", + "type": "uint256" + } + ], + "name": "getVaultDebt", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "contract ITreasury", + "name": "_treasury", + "type": "address" + }, + { + "internalType": "contract IERC20", + "name": "_collateral", + "type": "address" + }, + { + "internalType": "contract IOracle", + "name": "_oracle", + "type": "address" + }, + { + "components": [ + { + "internalType": "uint256", + "name": "debtCeiling", + "type": "uint256" + }, + { + "internalType": "uint64", + "name": "collateralFactor", + "type": "uint64" + }, + { + "internalType": "uint64", + "name": "targetHealthFactor", + "type": "uint64" + }, + { + "internalType": "uint64", + "name": "interestRate", + "type": "uint64" + }, + { + "internalType": "uint64", + "name": "liquidationSurcharge", + "type": "uint64" + }, + { + "internalType": "uint64", + "name": "maxLiquidationDiscount", + "type": "uint64" + }, + { + "internalType": "bool", + "name": "whitelistingActivated", + "type": "bool" + }, + { + "internalType": "uint256", + "name": "baseBoost", + "type": "uint256" + } + ], + "internalType": "struct VaultParameters", + "name": "params", + "type": "tuple" + }, + { + "internalType": "string", + "name": "_symbol", + "type": "string" + } + ], + "name": "initialize", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "interestAccumulator", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "interestRate", + "outputs": [ + { + "internalType": "uint64", + "name": "", + "type": "uint64" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "owner", + "type": "address" + }, + { + "internalType": "address", + "name": "operator", + "type": "address" + } + ], + "name": "isApprovedForAll", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "spender", + "type": "address" + }, + { + "internalType": "uint256", + "name": "vaultID", + "type": "uint256" + } + ], + "name": "isApprovedOrOwner", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "isWhitelisted", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "lastInterestAccumulatorUpdated", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256[]", + "name": "vaultIDs", + "type": "uint256[]" + }, + { + "internalType": "uint256[]", + "name": "amounts", + "type": "uint256[]" + }, + { + "internalType": "address", + "name": "from", + "type": "address" + }, + { + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "internalType": "address", + "name": "who", + "type": "address" + }, + { + "internalType": "bytes", + "name": "data", + "type": "bytes" + } + ], + "name": "liquidate", + "outputs": [ + { + "components": [ + { + "internalType": "uint256", + "name": "stablecoinAmountToReceive", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "collateralAmountToGive", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "badDebtFromLiquidation", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "oracleValue", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "newInterestAccumulator", + "type": "uint256" + } + ], + "internalType": "struct LiquidatorData", + "name": "liqData", + "type": "tuple" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256[]", + "name": "vaultIDs", + "type": "uint256[]" + }, + { + "internalType": "uint256[]", + "name": "amounts", + "type": "uint256[]" + }, + { + "internalType": "address", + "name": "from", + "type": "address" + }, + { + "internalType": "address", + "name": "to", + "type": "address" + } + ], + "name": "liquidate", + "outputs": [ + { + "components": [ + { + "internalType": "uint256", + "name": "stablecoinAmountToReceive", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "collateralAmountToGive", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "badDebtFromLiquidation", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "oracleValue", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "newInterestAccumulator", + "type": "uint256" + } + ], + "internalType": "struct LiquidatorData", + "name": "", + "type": "tuple" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "liquidationSurcharge", + "outputs": [ + { + "internalType": "uint64", + "name": "", + "type": "uint64" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "maxLiquidationDiscount", + "outputs": [ + { + "internalType": "uint64", + "name": "", + "type": "uint64" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "name", + "outputs": [ + { + "internalType": "string", + "name": "", + "type": "string" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "owner", + "type": "address" + } + ], + "name": "nonces", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "oracle", + "outputs": [ + { + "internalType": "contract IOracle", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "vaultID", + "type": "uint256" + } + ], + "name": "ownerOf", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "paused", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "owner", + "type": "address" + }, + { + "internalType": "address", + "name": "spender", + "type": "address" + }, + { + "internalType": "bool", + "name": "approved", + "type": "bool" + }, + { + "internalType": "uint256", + "name": "deadline", + "type": "uint256" + }, + { + "internalType": "uint8", + "name": "v", + "type": "uint8" + }, + { + "internalType": "bytes32", + "name": "r", + "type": "bytes32" + }, + { + "internalType": "bytes32", + "name": "s", + "type": "bytes32" + } + ], + "name": "permit", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "repayFee", + "outputs": [ + { + "internalType": "uint64", + "name": "", + "type": "uint64" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "from", + "type": "address" + }, + { + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "internalType": "uint256", + "name": "vaultID", + "type": "uint256" + } + ], + "name": "safeTransferFrom", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "from", + "type": "address" + }, + { + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "internalType": "uint256", + "name": "vaultID", + "type": "uint256" + }, + { + "internalType": "bytes", + "name": "_data", + "type": "bytes" + } + ], + "name": "safeTransferFrom", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "operator", + "type": "address" + }, + { + "internalType": "bool", + "name": "approved", + "type": "bool" + } + ], + "name": "setApprovalForAll", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "string", + "name": "baseURI_", + "type": "string" + } + ], + "name": "setBaseURI", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_debtCeiling", + "type": "uint256" + } + ], + "name": "setDebtCeiling", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_dust", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "_dustLiquidation", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "dustCollateral_", + "type": "uint256" + } + ], + "name": "setDusts", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_veBoostProxy", + "type": "address" + }, + { + "internalType": "uint256[]", + "name": "xBoost", + "type": "uint256[]" + }, + { + "internalType": "uint256[]", + "name": "yBoost", + "type": "uint256[]" + } + ], + "name": "setLiquidationBoostParameters", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_oracle", + "type": "address" + } + ], + "name": "setOracle", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_treasury", + "type": "address" + } + ], + "name": "setTreasury", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint64", + "name": "param", + "type": "uint64" + }, + { + "internalType": "bytes32", + "name": "what", + "type": "bytes32" + } + ], + "name": "setUint64", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "stablecoin", + "outputs": [ + { + "internalType": "contract IAgToken", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes4", + "name": "interfaceId", + "type": "bytes4" + } + ], + "name": "supportsInterface", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "pure", + "type": "function" + }, + { + "inputs": [], + "name": "surplus", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "symbol", + "outputs": [ + { + "internalType": "string", + "name": "", + "type": "string" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "targetHealthFactor", + "outputs": [ + { + "internalType": "uint64", + "name": "", + "type": "uint64" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "togglePause", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "target", + "type": "address" + } + ], + "name": "toggleWhitelist", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "vaultID", + "type": "uint256" + } + ], + "name": "tokenURI", + "outputs": [ + { + "internalType": "string", + "name": "", + "type": "string" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "totalNormalizedDebt", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "from", + "type": "address" + }, + { + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "internalType": "uint256", + "name": "vaultID", + "type": "uint256" + } + ], + "name": "transferFrom", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "treasury", + "outputs": [ + { + "internalType": "contract ITreasury", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "name": "vaultData", + "outputs": [ + { + "internalType": "uint256", + "name": "collateralAmount", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "normalizedDebt", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "vaultIDCount", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "veBoostProxy", + "outputs": [ + { + "internalType": "contract IVeBoostProxy", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "whitelistingActivated", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "name": "xLiquidationBoost", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "name": "yLiquidationBoost", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + } + ], + "transactionHash": "0x6ac2b24ed7eb740372d631cba32b6b99769e9dd16180b0a9a83de716152244c4", + "receipt": { + "to": null, + "from": "0xfdA462548Ce04282f4B6D6619823a7C64Fdc0185", + "contractAddress": "0xAe4D5A4308DB411f70B572f0D5ace4e41E3346A7", + "transactionIndex": 112, + "gasUsed": "5346322", + "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000080000000000000000000000000000000000000000000000400000000000000000008000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000", + "blockHash": "0x0cf39faa8356a3a8b3dcd660acc55b5d7b425663c6019e3f1cc19e6ea6a8a531", + "transactionHash": "0x6ac2b24ed7eb740372d631cba32b6b99769e9dd16180b0a9a83de716152244c4", + "logs": [ + { + "transactionIndex": 112, + "blockNumber": 18975614, + "transactionHash": "0x6ac2b24ed7eb740372d631cba32b6b99769e9dd16180b0a9a83de716152244c4", + "address": "0xAe4D5A4308DB411f70B572f0D5ace4e41E3346A7", + "topics": [ + "0x7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb3847402498" + ], + "data": "0x0000000000000000000000000000000000000000000000000000000000000001", + "logIndex": 108, + "blockHash": "0x0cf39faa8356a3a8b3dcd660acc55b5d7b425663c6019e3f1cc19e6ea6a8a531" + } + ], + "blockNumber": 18975614, + "cumulativeGasUsed": "12803196", + "status": 1, + "byzantium": true + }, + "args": [], + "numDeployments": 1, + "solcInputHash": "0938660e7382a0ccf0ba8a2485ec5da6", + "metadata": "{\"compiler\":{\"version\":\"0.8.12+commit.f00d7308\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[],\"name\":\"ApprovalToCaller\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ApprovalToOwner\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"DebtCeilingExceeded\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"DustyLeftoverAmount\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ExpiredDeadline\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"HealthyVault\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"IncompatibleLengths\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InsolventVault\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidParameterType\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidParameterValue\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidSetOfParameters\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidSignature\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidTreasury\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"NonERC721Receiver\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"NonexistentVault\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"NotApproved\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"NotGovernor\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"NotGovernorOrGuardian\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"NotTreasury\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"NotVaultManager\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"NotWhitelisted\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"Paused\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"TooHighParameterValue\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"TooSmallParameterValue\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ZeroAddress\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"surplusEndValue\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"badDebtEndValue\",\"type\":\"uint256\"}],\"name\":\"AccruedToTreasury\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"approved\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"tokenId\",\"type\":\"uint256\"}],\"name\":\"Approval\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"operator\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"bool\",\"name\":\"approved\",\"type\":\"bool\"}],\"name\":\"ApprovalForAll\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"vaultID\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"collateralAmount\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint8\",\"name\":\"isIncrease\",\"type\":\"uint8\"}],\"name\":\"CollateralAmountUpdated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"debtCeiling\",\"type\":\"uint256\"}],\"name\":\"DebtCeilingUpdated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"srcVaultID\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"dstVaultID\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"dstVaultManager\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"DebtTransferred\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"param\",\"type\":\"uint64\"},{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"what\",\"type\":\"bytes32\"}],\"name\":\"FiledUint64\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint8\",\"name\":\"version\",\"type\":\"uint8\"}],\"name\":\"Initialized\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"timestamp\",\"type\":\"uint256\"}],\"name\":\"InterestAccumulatorUpdated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"vaultID\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"internalAmount\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint8\",\"name\":\"isIncrease\",\"type\":\"uint8\"}],\"name\":\"InternalDebtUpdated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint256[]\",\"name\":\"vaultIDs\",\"type\":\"uint256[]\"}],\"name\":\"LiquidatedVaults\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"_veBoostProxy\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256[]\",\"name\":\"xBoost\",\"type\":\"uint256[]\"},{\"indexed\":false,\"internalType\":\"uint256[]\",\"name\":\"yBoost\",\"type\":\"uint256[]\"}],\"name\":\"LiquidationBoostParametersUpdated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"tokenId\",\"type\":\"uint256\"}],\"name\":\"Transfer\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"BASE_INTEREST\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"BASE_PARAMS\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"DOMAIN_SEPARATOR\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"HALF_BASE_INTEREST\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"accrueInterestToTreasury\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"surplusValue\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"badDebtValue\",\"type\":\"uint256\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"enum ActionType[]\",\"name\":\"actions\",\"type\":\"uint8[]\"},{\"internalType\":\"bytes[]\",\"name\":\"datas\",\"type\":\"bytes[]\"},{\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"angle\",\"outputs\":[{\"components\":[{\"internalType\":\"uint256\",\"name\":\"stablecoinAmountToGive\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"stablecoinAmountToReceive\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"collateralAmountToGive\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"collateralAmountToReceive\",\"type\":\"uint256\"}],\"internalType\":\"struct PaymentData\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"enum ActionType[]\",\"name\":\"actions\",\"type\":\"uint8[]\"},{\"internalType\":\"bytes[]\",\"name\":\"datas\",\"type\":\"bytes[]\"},{\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"who\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"repayData\",\"type\":\"bytes\"}],\"name\":\"angle\",\"outputs\":[{\"components\":[{\"internalType\":\"uint256\",\"name\":\"stablecoinAmountToGive\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"stablecoinAmountToReceive\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"collateralAmountToGive\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"collateralAmountToReceive\",\"type\":\"uint256\"}],\"internalType\":\"struct PaymentData\",\"name\":\"paymentData\",\"type\":\"tuple\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"vaultID\",\"type\":\"uint256\"}],\"name\":\"approve\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"badDebt\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"}],\"name\":\"balanceOf\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"borrowFee\",\"outputs\":[{\"internalType\":\"uint64\",\"name\":\"\",\"type\":\"uint64\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"vaultID\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"liquidator\",\"type\":\"address\"}],\"name\":\"checkLiquidation\",\"outputs\":[{\"components\":[{\"internalType\":\"uint256\",\"name\":\"maxStablecoinAmountToRepay\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"maxCollateralAmountGiven\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"thresholdRepayAmount\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"discount\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"currentDebt\",\"type\":\"uint256\"}],\"internalType\":\"struct LiquidationOpportunity\",\"name\":\"liqOpp\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"collateral\",\"outputs\":[{\"internalType\":\"contract IERC20\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"collateralFactor\",\"outputs\":[{\"internalType\":\"uint64\",\"name\":\"\",\"type\":\"uint64\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"toVault\",\"type\":\"address\"}],\"name\":\"createVault\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"debtCeiling\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"dust\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"dustLiquidation\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"vaultID\",\"type\":\"uint256\"}],\"name\":\"getApproved\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"vaultID\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"stablecoinAmount\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"senderBorrowFee\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"senderRepayFee\",\"type\":\"uint256\"}],\"name\":\"getDebtOut\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getTotalDebt\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"vaultID\",\"type\":\"uint256\"}],\"name\":\"getVaultDebt\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"contract ITreasury\",\"name\":\"_treasury\",\"type\":\"address\"},{\"internalType\":\"contract IERC20\",\"name\":\"_collateral\",\"type\":\"address\"},{\"internalType\":\"contract IOracle\",\"name\":\"_oracle\",\"type\":\"address\"},{\"components\":[{\"internalType\":\"uint256\",\"name\":\"debtCeiling\",\"type\":\"uint256\"},{\"internalType\":\"uint64\",\"name\":\"collateralFactor\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"targetHealthFactor\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"interestRate\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"liquidationSurcharge\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"maxLiquidationDiscount\",\"type\":\"uint64\"},{\"internalType\":\"bool\",\"name\":\"whitelistingActivated\",\"type\":\"bool\"},{\"internalType\":\"uint256\",\"name\":\"baseBoost\",\"type\":\"uint256\"}],\"internalType\":\"struct VaultParameters\",\"name\":\"params\",\"type\":\"tuple\"},{\"internalType\":\"string\",\"name\":\"_symbol\",\"type\":\"string\"}],\"name\":\"initialize\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"interestAccumulator\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"interestRate\",\"outputs\":[{\"internalType\":\"uint64\",\"name\":\"\",\"type\":\"uint64\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"operator\",\"type\":\"address\"}],\"name\":\"isApprovedForAll\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"spender\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"vaultID\",\"type\":\"uint256\"}],\"name\":\"isApprovedOrOwner\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"isWhitelisted\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"lastInterestAccumulatorUpdated\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256[]\",\"name\":\"vaultIDs\",\"type\":\"uint256[]\"},{\"internalType\":\"uint256[]\",\"name\":\"amounts\",\"type\":\"uint256[]\"},{\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"who\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"}],\"name\":\"liquidate\",\"outputs\":[{\"components\":[{\"internalType\":\"uint256\",\"name\":\"stablecoinAmountToReceive\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"collateralAmountToGive\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"badDebtFromLiquidation\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"oracleValue\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"newInterestAccumulator\",\"type\":\"uint256\"}],\"internalType\":\"struct LiquidatorData\",\"name\":\"liqData\",\"type\":\"tuple\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256[]\",\"name\":\"vaultIDs\",\"type\":\"uint256[]\"},{\"internalType\":\"uint256[]\",\"name\":\"amounts\",\"type\":\"uint256[]\"},{\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"liquidate\",\"outputs\":[{\"components\":[{\"internalType\":\"uint256\",\"name\":\"stablecoinAmountToReceive\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"collateralAmountToGive\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"badDebtFromLiquidation\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"oracleValue\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"newInterestAccumulator\",\"type\":\"uint256\"}],\"internalType\":\"struct LiquidatorData\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"liquidationSurcharge\",\"outputs\":[{\"internalType\":\"uint64\",\"name\":\"\",\"type\":\"uint64\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"maxLiquidationDiscount\",\"outputs\":[{\"internalType\":\"uint64\",\"name\":\"\",\"type\":\"uint64\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"name\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"}],\"name\":\"nonces\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"oracle\",\"outputs\":[{\"internalType\":\"contract IOracle\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"vaultID\",\"type\":\"uint256\"}],\"name\":\"ownerOf\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"paused\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"spender\",\"type\":\"address\"},{\"internalType\":\"bool\",\"name\":\"approved\",\"type\":\"bool\"},{\"internalType\":\"uint256\",\"name\":\"deadline\",\"type\":\"uint256\"},{\"internalType\":\"uint8\",\"name\":\"v\",\"type\":\"uint8\"},{\"internalType\":\"bytes32\",\"name\":\"r\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32\",\"name\":\"s\",\"type\":\"bytes32\"}],\"name\":\"permit\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"repayFee\",\"outputs\":[{\"internalType\":\"uint64\",\"name\":\"\",\"type\":\"uint64\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"vaultID\",\"type\":\"uint256\"}],\"name\":\"safeTransferFrom\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"vaultID\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"_data\",\"type\":\"bytes\"}],\"name\":\"safeTransferFrom\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"operator\",\"type\":\"address\"},{\"internalType\":\"bool\",\"name\":\"approved\",\"type\":\"bool\"}],\"name\":\"setApprovalForAll\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"string\",\"name\":\"baseURI_\",\"type\":\"string\"}],\"name\":\"setBaseURI\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_debtCeiling\",\"type\":\"uint256\"}],\"name\":\"setDebtCeiling\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_dust\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"_dustLiquidation\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"dustCollateral_\",\"type\":\"uint256\"}],\"name\":\"setDusts\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_veBoostProxy\",\"type\":\"address\"},{\"internalType\":\"uint256[]\",\"name\":\"xBoost\",\"type\":\"uint256[]\"},{\"internalType\":\"uint256[]\",\"name\":\"yBoost\",\"type\":\"uint256[]\"}],\"name\":\"setLiquidationBoostParameters\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_oracle\",\"type\":\"address\"}],\"name\":\"setOracle\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_treasury\",\"type\":\"address\"}],\"name\":\"setTreasury\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"param\",\"type\":\"uint64\"},{\"internalType\":\"bytes32\",\"name\":\"what\",\"type\":\"bytes32\"}],\"name\":\"setUint64\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"stablecoin\",\"outputs\":[{\"internalType\":\"contract IAgToken\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes4\",\"name\":\"interfaceId\",\"type\":\"bytes4\"}],\"name\":\"supportsInterface\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"surplus\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"symbol\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"targetHealthFactor\",\"outputs\":[{\"internalType\":\"uint64\",\"name\":\"\",\"type\":\"uint64\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"togglePause\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"target\",\"type\":\"address\"}],\"name\":\"toggleWhitelist\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"vaultID\",\"type\":\"uint256\"}],\"name\":\"tokenURI\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"totalNormalizedDebt\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"vaultID\",\"type\":\"uint256\"}],\"name\":\"transferFrom\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"treasury\",\"outputs\":[{\"internalType\":\"contract ITreasury\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"name\":\"vaultData\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"collateralAmount\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"normalizedDebt\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"vaultIDCount\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"veBoostProxy\",\"outputs\":[{\"internalType\":\"contract IVeBoostProxy\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"whitelistingActivated\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"name\":\"xLiquidationBoost\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"name\":\"yLiquidationBoost\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"}],\"devdoc\":{\"author\":\"Angle Labs, Inc.\",\"kind\":\"dev\",\"methods\":{\"accrueInterestToTreasury()\":{\"details\":\"`surplus` and `badDebt` should be reset to 0 once their current value have been given to the `treasury` contract\",\"returns\":{\"badDebtValue\":\"Value of the bad debt communicated to the `Treasury`\",\"surplusValue\":\"Value of the surplus communicated to the `Treasury`\"}},\"angle(uint8[],bytes[],address,address,address,bytes)\":{\"details\":\"This function is optimized to reduce gas cost due to payment from or to the user and that expensive calls or computations (like `oracleValue`) are done only onceWhen specifying `vaultID` in `data`, it is important to know that if you specify `vaultID = 0`, it will simply use the latest `vaultID`. This is the default behavior, and unless you're engaging into some complex protocol actions it is encouraged to use `vaultID = 0` only when the first action of the batch is `createVault`\",\"params\":{\"actions\":\"Set of actions to perform\",\"datas\":\"Data to be decoded for each action: it can include like the `vaultID` or the `stablecoinAmount` to borrow\",\"from\":\"Address from which stablecoins will be taken if one action includes burning stablecoins. This address should either be the `msg.sender` or be approved by the latter\",\"repayData\":\"Data to pass to the repayment contract in case of\",\"to\":\"Address to which stablecoins and/or collateral will be sent in case of\",\"who\":\"Address of the contract to handle in case of repayment of stablecoins from received collateral\"},\"returns\":{\"paymentData\":\"Struct containing the accounting changes from the protocol's perspective (like how much of collateral or how much has been received). Note that the values in the struct are not aggregated and you could have in the output a positive amount of stablecoins to receive as well as a positive amount of stablecoins to give\"}},\"approve(address,uint256)\":{\"details\":\"Gives permission to `to` to transfer `tokenId` token to another account. The approval is cleared when the token is transferred. Only a single account can be approved at a time, so approving the zero address clears previous approvals. Requirements: - The caller must own the token or be an approved operator. - `tokenId` must exist. Emits an {Approval} event.\"},\"balanceOf(address)\":{\"details\":\"Returns the number of tokens in ``owner``'s account.\"},\"checkLiquidation(uint256,address)\":{\"details\":\"This function will revert if it's called on a vault that does not exist\",\"params\":{\"liquidator\":\"Address of the liquidator which will be performing the liquidation\",\"vaultID\":\"ID of the vault to check\"},\"returns\":{\"liqOpp\":\"Description of the opportunity of liquidation\"}},\"createVault(address)\":{\"details\":\"This function just creates the vault without doing any collateral or\",\"params\":{\"toVault\":\"Address for which the va\"},\"returns\":{\"_0\":\"vaultID ID of the vault created\"}},\"getApproved(uint256)\":{\"details\":\"Returns the account approved for `tokenId` token. Requirements: - `tokenId` must exist.\"},\"getDebtOut(uint256,uint256,uint256,uint256)\":{\"details\":\"This function can only be called from a vaultManager registered in the same Treasury\",\"params\":{\"amountStablecoins\":\"Amount of stablecoins to remove from the debt: this amount is to be converted to an internal debt amount\",\"senderBorrowFee\":\"Borrowing fees from the contract which requested this: this is to make sure that people are not arbitraging difference in minting fees\",\"senderRepayFee\":\"Repay fees from the contract which requested this: this is to make sure that people are not arbitraging differences in repay fees\",\"vaultID\":\"ID of the vault to remove debt from\"}},\"getTotalDebt()\":{\"returns\":{\"_0\":\"Total debt across all vaults, taking into account the interest accumulated over time\"}},\"getVaultDebt(uint256)\":{\"params\":{\"vaultID\":\"ID of the vault to check\"},\"returns\":{\"_0\":\"Debt of the vault\"}},\"initialize(address,address,address,(uint256,uint64,uint64,uint64,uint64,uint64,bool,uint256),string)\":{\"details\":\"The parameters and the oracle are the only elements which could be modified once the contract has been initializedFor the contract to be fully initialized, governance needs to set the parameters for the liquidation boost\",\"params\":{\"_collateral\":\"Collateral supported by this contract\",\"_oracle\":\"Oracle contract used\",\"_symbol\":\"Symbol used to define the `VaultManager` name and symbol\",\"_treasury\":\"Treasury address handling the contract\"}},\"isApprovedForAll(address,address)\":{\"details\":\"Returns if the `operator` is allowed to manage all of the assets of `owner`. See {setApprovalForAll}\"},\"isApprovedOrOwner(address,uint256)\":{\"params\":{\"spender\":\"Address for which vault ownership should be checked\",\"vaultID\":\"ID of the vault to check\"},\"returns\":{\"_0\":\"Whether the `spender` address owns or is approved for `vaultID`\"}},\"liquidate(uint256[],uint256[],address,address)\":{\"details\":\"This function is a simplified wrapper of the function below. It is built to remove for liquidators the need to specify a `who` and a `data` parameter\"},\"liquidate(uint256[],uint256[],address,address,address,bytes)\":{\"details\":\"This function will revert if it's called on a vault that cannot be liquidated or that does not existA whitelist check may be performed on the address liquidating the vault or on the address receiving the funds from the liquidiation\",\"params\":{\"amounts\":\"Amount of stablecoin to bring for the liquidation of each vault\",\"data\":\"Data to pass to the repayment contract in case of. If empty, liquidators simply have to bring the exact amount of stablecoins to get the discounted collateral. If not, it is used by the repayment contract to swap a portion or all of the collateral received to stablecoins to be sent to the `from` address. More details in the `_handleRepay` function\",\"from\":\"Address from which the stablecoins for the liquidation should be taken: this address should be the `msg.sender` or have received an approval\",\"to\":\"Address to which discounted collateral should be sent\",\"vaultIDs\":\"List of the vaults to liquidate\",\"who\":\"Address of the contract to handle repayment of stablecoins from received collateral\"},\"returns\":{\"liqData\":\"Data about the liquidation process for the liquidator to track everything that has been going on (like how much stablecoins have been repaid, how much collateral has been received)\"}},\"ownerOf(uint256)\":{\"details\":\"Returns the owner of the `tokenId` token. Requirements: - `tokenId` must exist.\"},\"permit(address,address,bool,uint256,uint8,bytes32,bytes32)\":{\"details\":\"The `v`, `r`, and `s` parameters are used as signature data\",\"params\":{\"approved\":\"Whether to give or revoke the approval\",\"deadline\":\"Deadline parameter for the signature to be valid\",\"owner\":\"Address signing the permit and giving (or revoking) its approval for all the controlled vaults\",\"spender\":\"Address to give approval to\"}},\"safeTransferFrom(address,address,uint256)\":{\"details\":\"Safely transfers `tokenId` token from `from` to `to`, checking first that contract recipients are aware of the ERC721 protocol to prevent tokens from being forever locked. Requirements: - `from` cannot be the zero address. - `to` cannot be the zero address. - `tokenId` token must exist and be owned by `from`. - If the caller is not `from`, it must have been allowed to move this token by either {approve} or {setApprovalForAll}. - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer. Emits a {Transfer} event.\"},\"safeTransferFrom(address,address,uint256,bytes)\":{\"details\":\"Safely transfers `tokenId` token from `from` to `to`. Requirements: - `from` cannot be the zero address. - `to` cannot be the zero address. - `tokenId` token must exist and be owned by `from`. - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}. - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer. Emits a {Transfer} event.\"},\"setApprovalForAll(address,bool)\":{\"details\":\"Approve or remove `operator` as an operator for the caller. Operators can call {transferFrom} or {safeTransferFrom} for any token owned by the caller. Requirements: - The `operator` cannot be the caller. Emits an {ApprovalForAll} event.\"},\"setDebtCeiling(uint256)\":{\"details\":\"`debtCeiling` should not be bigger than `type(uint256).max / 10**27` otherwise there could be overflows\",\"params\":{\"_debtCeiling\":\"New value for `debtCeiling`\"}},\"setDusts(uint256,uint256,uint256)\":{\"details\":\"dustCollateral_ is in stable value\",\"params\":{\"_dust\":\"New minimum debt allowed\",\"_dustLiquidation\":\"New `dustLiquidation` value\",\"dustCollateral_\":\"New minimum collateral allowed in a vault after a liquidation\"}},\"setLiquidationBoostParameters(address,uint256[],uint256[])\":{\"details\":\"There are 2 modes: When boost is enabled, `xBoost` and `yBoost` should have a length of 2, but if they have a higher length contract will still work as expected. Contract will also work as expected if their length differ When boost is disabled, `_veBoostProxy` needs to be zero address and `yBoost[0]` is the base boost\",\"params\":{\"_veBoostProxy\":\"Address which queries veANGLE balances and adjusted balances from delegation\",\"xBoost\":\"Threshold values of veANGLE adjusted balances\",\"yBoost\":\"Values of the liquidation boost at the threshold values of x\"}},\"setOracle(address)\":{\"params\":{\"_oracle\":\"Reference to the oracle contract\"}},\"setTreasury(address)\":{\"details\":\"All required checks when setting up a treasury contract are performed in the contract calling this function\",\"params\":{\"_treasury\":\"New treasury contract\"}},\"setUint64(uint64,bytes32)\":{\"details\":\"This function performs the required checks when updating a parameterWhen setting parameters governance or the guardian should make sure that when `HF < CF/((1-surcharge)(1-discount))` and hence when liquidating a vault is going to decrease its health factor, `discount = max discount`. Otherwise, it may be profitable for the liquidator to liquidate in multiple times: as it will decrease the HF and therefore increase the discount between each time\",\"params\":{\"param\":\"Value for the parameter\",\"what\":\"Parameter to change\"}},\"supportsInterface(bytes4)\":{\"details\":\"Returns true if this contract implements the interface defined by `interfaceId`. See the corresponding https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified[EIP section] to learn more about how these ids are created. This function call must use less than 30 000 gas.\"},\"toggleWhitelist(address)\":{\"details\":\"If the `target` address is the zero address then this function toggles whitelisting for all addresses\",\"params\":{\"target\":\"Address to toggle\"}},\"tokenURI(uint256)\":{\"details\":\"Returns the Uniform Resource Identifier (URI) for `tokenId` token.\"},\"transferFrom(address,address,uint256)\":{\"details\":\"Transfers `tokenId` token from `from` to `to`. WARNING: Usage of this method is discouraged, use {safeTransferFrom} whenever possible. Requirements: - `from` cannot be the zero address. - `to` cannot be the zero address. - `tokenId` token must be owned by `from`. - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}. Emits a {Transfer} event.\"}},\"title\":\"VaultManagerLiquidationBoost\",\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{\"BASE_INTEREST()\":{\"notice\":\"Base used for interest rate computation\"},\"BASE_PARAMS()\":{\"notice\":\"Base used for parameter computation: almost all the parameters of this contract are set in `BASE_PARAMS`\"},\"DOMAIN_SEPARATOR()\":{\"notice\":\"Returns the domain separator for the current chain.\"},\"HALF_BASE_INTEREST()\":{\"notice\":\"Used for interest rate computation\"},\"accrueInterestToTreasury()\":{\"notice\":\"Accrues interest accumulated across all vaults to the surplus and sends the surplus to the treasury\"},\"angle(uint8[],bytes[],address,address)\":{\"notice\":\"This function is a wrapper built on top of the function above. It enables users to interact with the contract without having to provide `who` and `repayData` parameters\"},\"angle(uint8[],bytes[],address,address,address,bytes)\":{\"notice\":\"Allows composability between calls to the different entry points of this module. Any user calling this function can perform any of the allowed actions in the order of their choice\"},\"badDebt()\":{\"notice\":\"Bad debt made from liquidated vaults which ended up having no collateral and a positive amount of stablecoins\"},\"borrowFee()\":{\"notice\":\"Upfront fee taken when borrowing stablecoins: this fee is optional and should in practice not be used\"},\"checkLiquidation(uint256,address)\":{\"notice\":\"Checks whether a given vault is liquidable and if yes gives information regarding its liquidation\"},\"collateral()\":{\"notice\":\"Reference to the collateral handled by this `VaultManager`\"},\"collateralFactor()\":{\"notice\":\"Encodes the maximum ratio stablecoin/collateral a vault can have before being liquidated. It's what determines the minimum collateral ratio of a position\"},\"createVault(address)\":{\"notice\":\"Creates a vault\"},\"debtCeiling()\":{\"notice\":\"Maximum amount of stablecoins that can be issued with this contract (in `BASE_TOKENS`). This parameter should not be bigger than `type(uint256).max / BASE_INTEREST` otherwise there may be some overflows in the `increaseDebt` function\"},\"dust()\":{\"notice\":\"Minimum amount of debt a vault can have, expressed in `BASE_TOKENS` that is to say the base of the agTokens\"},\"dustLiquidation()\":{\"notice\":\"If the amount of debt of a vault that gets liquidated is below this amount, then the liquidator can liquidate all the debt of the vault (and not just what's needed to get to the target health factor)\"},\"getDebtOut(uint256,uint256,uint256,uint256)\":{\"notice\":\"Removes debt from a vault after being requested to do so by another `VaultManager` contract\"},\"getTotalDebt()\":{\"notice\":\"Gets the total debt across all vaults\"},\"getVaultDebt(uint256)\":{\"notice\":\"Gets the current debt of a vault\"},\"initialize(address,address,address,(uint256,uint64,uint64,uint64,uint64,uint64,bool,uint256),string)\":{\"notice\":\"Initializes the `VaultManager` contract\"},\"interestAccumulator()\":{\"notice\":\"The `interestAccumulator` variable keeps track of the interest that should accrue to the protocol. The stored value is not necessarily the true value: this one is recomputed every time an action takes place within the protocol. It is in base `BASE_INTEREST`\"},\"interestRate()\":{\"notice\":\"Per second interest taken to borrowers taking agToken loans. Contrarily to other parameters, it is set in `BASE_INTEREST` that is to say in base 10**27\"},\"isApprovedOrOwner(address,uint256)\":{\"notice\":\"Checks whether a given address is approved for a vault or owns this vault\"},\"isWhitelisted(address)\":{\"notice\":\"Maps an address to 1 if it's whitelisted and can open or own a vault\"},\"lastInterestAccumulatorUpdated()\":{\"notice\":\"Timestamp at which the `interestAccumulator` was updated\"},\"liquidate(uint256[],uint256[],address,address)\":{\"notice\":\"Liquidates an ensemble of vaults specified by their IDs\"},\"liquidate(uint256[],uint256[],address,address,address,bytes)\":{\"notice\":\"Liquidates an ensemble of vaults specified by their IDs\"},\"liquidationSurcharge()\":{\"notice\":\"Fee taken by the protocol during a liquidation. Technically, this value is not the fee per se, it's 1 - fee. For instance for a 2% fee, `liquidationSurcharge` should be 98%\"},\"maxLiquidationDiscount()\":{\"notice\":\"Maximum discount given to liquidators\"},\"nonces(address)\":{\"notice\":\"Returns the current nonce for an `owner` address\"},\"oracle()\":{\"notice\":\"Oracle contract to get access to the price of the collateral with respect to the stablecoin\"},\"paused()\":{\"notice\":\"Whether the contract is paused or not\"},\"permit(address,address,bool,uint256,uint8,bytes32,bytes32)\":{\"notice\":\"Allows an address to give or revoke approval for all its vaults to another address\"},\"repayFee()\":{\"notice\":\"Upfront fee taken when repaying stablecoins: this fee is optional as well. It should be smaller than the liquidation surcharge (cf below) to avoid exploits where people voluntarily get liquidated at a 0 discount to pay smaller repaying fees\"},\"setBaseURI(string)\":{\"notice\":\"Changes the ERC721 metadata URI\"},\"setDebtCeiling(uint256)\":{\"notice\":\"Sets `debtCeiling`\"},\"setDusts(uint256,uint256,uint256)\":{\"notice\":\"Sets the dust variables\"},\"setLiquidationBoostParameters(address,uint256[],uint256[])\":{\"notice\":\"Sets the parameters for the liquidation booster which encodes the slope of the discount\"},\"setOracle(address)\":{\"notice\":\"Changes the reference to the oracle contract used to get the price of the oracle\"},\"setTreasury(address)\":{\"notice\":\"Sets the treasury contract\"},\"setUint64(uint64,bytes32)\":{\"notice\":\"Sets parameters encoded as uint64\"},\"stablecoin()\":{\"notice\":\"Stablecoin handled by this contract. Another `VaultManager` contract could have the same rights as this `VaultManager` on the stablecoin contract\"},\"surplus()\":{\"notice\":\"Surplus accumulated by the contract: surplus is always in stablecoins, and is then reset when the value is communicated to the treasury contract\"},\"targetHealthFactor()\":{\"notice\":\"Maximum Health factor at which a vault can end up after a liquidation (unless it's fully liquidated)\"},\"togglePause()\":{\"notice\":\"Pauses external permissionless functions of the contract\"},\"toggleWhitelist(address)\":{\"notice\":\"Changes the whitelisting of an address\"},\"totalNormalizedDebt()\":{\"notice\":\"Total normalized amount of stablecoins borrowed, not taking into account the potential bad debt accumulated This value is expressed in the base of Angle stablecoins (`BASE_TOKENS = 10**18`)\"},\"treasury()\":{\"notice\":\"Reference to the `treasury` contract handling this `VaultManager`\"},\"vaultData(uint256)\":{\"notice\":\"Maps a `vaultID` to its data (namely collateral amount and normalized debt)\"},\"vaultIDCount()\":{\"notice\":\"ID of the last vault created. The `vaultIDCount` variables serves as a counter to generate a unique `vaultID` for each vault: it is like `tokenID` in basic ERC721 contracts\"},\"veBoostProxy()\":{\"notice\":\"Reference to the contract which computes adjusted veANGLE balances for liquidators boosts\"},\"whitelistingActivated()\":{\"notice\":\"Whether whitelisting is required to own a vault or not\"},\"xLiquidationBoost(uint256)\":{\"notice\":\"Threshold veANGLE balance values for the computation of the boost for liquidators: the length of this array should normally be 2. The base of the x-values in this array should be `BASE_TOKENS`\"},\"yLiquidationBoost(uint256)\":{\"notice\":\"Values of the liquidation boost at the threshold values of x\"}},\"notice\":\"Liquidation discount depending also on the liquidator veANGLE balance\",\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/vaultManager/VaultManagerLiquidationBoost.sol\":\"VaultManagerLiquidationBoost\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\"},\"optimizer\":{\"enabled\":true,\"runs\":1},\"remappings\":[]},\"sources\":{\"@chainlink/contracts/src/v0.8/interfaces/AggregatorV3Interface.sol\":{\"keccak256\":\"0xe6f5ac8c47f3b9b6135051efb9216f9ba5b312a6ecc20209b4f66a780443c328\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://ded4aa77b7b8f222a2d992eb95b03592be3250b826b6a38a4c790d2dec8b0d47\",\"dweb:/ipfs/QmNUKpTKXWsBBNMyzZuYvEZ2pUhZ2zEhQuyvxYZpTwo4eT\"]},\"@openzeppelin/contracts-upgradeable/interfaces/IERC721MetadataUpgradeable.sol\":{\"keccak256\":\"0xc0e1ac396ac591a4c38ddcdd220321128eb94424d73e41a573cf58d5c643af38\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://2bd729caa85e0c3740b2d3a28a91fac0fd1ef66e0907145005a37f1927ae7a22\",\"dweb:/ipfs/QmcfVoLnE2PZj3U6KbACk6ykqE5WXuAM3hsXLJxC2sxZGt\"]},\"@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol\":{\"keccak256\":\"0x0203dcadc5737d9ef2c211d6fa15d18ebc3b30dfa51903b64870b01a062b0b4e\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://6eb2fd1e9894dbe778f4b8131adecebe570689e63cf892f4e21257bfe1252497\",\"dweb:/ipfs/QmXgUGNfZvrn6N2miv3nooSs7Jm34A41qz94fu2GtDFcx8\"]},\"@openzeppelin/contracts-upgradeable/security/ReentrancyGuardUpgradeable.sol\":{\"keccak256\":\"0x8cc03c5ac17e8a7396e487cda41fc1f1dfdb91db7d528e6da84bee3b6dd7e167\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://607818f1b44548c2d8268176f73cdb290e1faed971b1061930d92698366e2a11\",\"dweb:/ipfs/QmQibMe3r5no95b6q7isGT5R75V8xSofWEDLXzp95b7LgZ\"]},\"@openzeppelin/contracts-upgradeable/token/ERC20/IERC20Upgradeable.sol\":{\"keccak256\":\"0x4e733d3164f73f461eaf9d8087a7ad1ea180bdc8ba0d3d61b0e1ae16d8e63dff\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://75b47c3aeca7b66ea6752f8be020ec5c1c502de6ec9065272dae23d3a52196e2\",\"dweb:/ipfs/QmUebPMHv16tYKFh5BmBQkMfRFb5b8UZ2RgVwdjxCeufVF\"]},\"@openzeppelin/contracts-upgradeable/token/ERC20/extensions/draft-IERC20PermitUpgradeable.sol\":{\"keccak256\":\"0xcc70d8e2281fb3ff69e8ab242500f10142cd0a7fa8dd9e45882be270d4d09024\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://17a4063bc918df0f7bb9cbf04c6f0bb4977afab3f2fc212bc138a178312a221d\",\"dweb:/ipfs/QmZMdvsHP5mDEAAdrK4bNeNh47TfmSFgN9qEBFTbie7zmm\"]},\"@openzeppelin/contracts-upgradeable/token/ERC721/IERC721ReceiverUpgradeable.sol\":{\"keccak256\":\"0xbb2ed8106d94aeae6858e2551a1e7174df73994b77b13ebd120ccaaef80155f5\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://8bc3c6a456dba727d8dd9fd33420febede490abb49a07469f61d2a3ace66a95a\",\"dweb:/ipfs/QmVAWtEVj7K5AbvgJa9Dz22KiDq9eoptCjnVZqsTMtKXyd\"]},\"@openzeppelin/contracts-upgradeable/token/ERC721/IERC721Upgradeable.sol\":{\"keccak256\":\"0x016298e66a5810253c6c905e61966bb31c8775c3f3517bf946ff56ee31d6c005\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://1723de5ae414f210db039b19e6487c19c2d643483c9be7c445cf481a80c199d2\",\"dweb:/ipfs/QmcBLbmPdZsNngYhA1KDadNUqQZoGACytFWuUH74RC4AXC\"]},\"@openzeppelin/contracts-upgradeable/token/ERC721/extensions/IERC721MetadataUpgradeable.sol\":{\"keccak256\":\"0x95a471796eb5f030fdc438660bebec121ad5d063763e64d92376ffb4b5ce8b70\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://4ffbd627e6958983d288801acdedbf3491ee0ebf1a430338bce47c96481ce9e3\",\"dweb:/ipfs/QmUM1vpmNgBV34sYf946SthDJNGhwwqjoRggmj4TUUQmdB\"]},\"@openzeppelin/contracts-upgradeable/utils/AddressUpgradeable.sol\":{\"keccak256\":\"0x611aa3f23e59cfdd1863c536776407b3e33d695152a266fa7cfb34440a29a8a3\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://9b4b2110b7f2b3eb32951bc08046fa90feccffa594e1176cb91cdfb0e94726b4\",\"dweb:/ipfs/QmSxLwYjicf9zWFuieRc8WQwE4FisA1Um5jp1iSa731TGt\"]},\"@openzeppelin/contracts-upgradeable/utils/introspection/IERC165Upgradeable.sol\":{\"keccak256\":\"0xc6cef87559d0aeffdf0a99803de655938a7779ec0a3cd5d4383483ad85565a09\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://92ad7e572cf44e6b4b37631b44b62f9eb9fb1cf14d9ce51c1504d5dc7ccaf758\",\"dweb:/ipfs/QmcnbqX85tsWnUXPmtuPLE4SczME2sJaTfmqEFkuAJvWhy\"]},\"@openzeppelin/contracts/interfaces/IERC721Metadata.sol\":{\"keccak256\":\"0x1e88abdf82fcbbf98f97be17ea56c924376350637896bc37366ec9f89b7c2628\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://c8eb8afc411b87c9718cfe5c68669d5210d7012a96890c520c0fc321f74f0992\",\"dweb:/ipfs/Qmcr74gEtRpWER5qjFN86AKUep66pGuzp9WDYueaNtt97n\"]},\"@openzeppelin/contracts/token/ERC20/IERC20.sol\":{\"keccak256\":\"0x9750c6b834f7b43000631af5cc30001c5f547b3ceb3635488f140f60e897ea6b\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://5a7d5b1ef5d8d5889ad2ed89d8619c09383b80b72ab226e0fe7bde1636481e34\",\"dweb:/ipfs/QmebXWgtEfumQGBdVeM6c71McLixYXQP5Bk6kKXuoY4Bmr\"]},\"@openzeppelin/contracts/token/ERC20/extensions/IERC20Metadata.sol\":{\"keccak256\":\"0x8de418a5503946cabe331f35fe242d3201a73f67f77aaeb7110acb1f30423aca\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://5a376d3dda2cb70536c0a45c208b29b34ac560c4cb4f513a42079f96ba47d2dd\",\"dweb:/ipfs/QmZQg6gn1sUpM8wHzwNvSnihumUCAhxD119MpXeKp8B9s8\"]},\"@openzeppelin/contracts/token/ERC20/extensions/draft-IERC20Permit.sol\":{\"keccak256\":\"0xf41ca991f30855bf80ffd11e9347856a517b977f0a6c2d52e6421a99b7840329\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://b2717fd2bdac99daa960a6de500754ea1b932093c946388c381da48658234b95\",\"dweb:/ipfs/QmP6QVMn6UeA3ByahyJbYQr5M6coHKBKsf3ySZSfbyA8R7\"]},\"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\":{\"keccak256\":\"0x032807210d1d7d218963d7355d62e021a84bf1b3339f4f50be2f63b53cccaf29\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://11756f42121f6541a35a8339ea899ee7514cfaa2e6d740625fcc844419296aa6\",\"dweb:/ipfs/QmekMuk6BY4DAjzeXr4MSbKdgoqqsZnA8JPtuyWc6CwXHf\"]},\"@openzeppelin/contracts/token/ERC721/IERC721.sol\":{\"keccak256\":\"0xed6a749c5373af398105ce6ee3ac4763aa450ea7285d268c85d9eeca809cdb1f\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://20a97f891d06f0fe91560ea1a142aaa26fdd22bed1b51606b7d48f670deeb50f\",\"dweb:/ipfs/QmTbCtZKChpaX5H2iRiTDMcSz29GSLCpTCDgJpcMR4wg8x\"]},\"@openzeppelin/contracts/token/ERC721/extensions/IERC721Metadata.sol\":{\"keccak256\":\"0x75b829ff2f26c14355d1cba20e16fe7b29ca58eb5fef665ede48bc0f9c6c74b9\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://a0a107160525724f9e1bbbab031defc2f298296dd9e331f16a6f7130cec32146\",\"dweb:/ipfs/QmemujxSd7gX8A9M8UwmNbz4Ms3U9FG9QfudUgxwvTmPWf\"]},\"@openzeppelin/contracts/utils/Address.sol\":{\"keccak256\":\"0xd6153ce99bcdcce22b124f755e72553295be6abcd63804cfdffceb188b8bef10\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://35c47bece3c03caaa07fab37dd2bb3413bfbca20db7bd9895024390e0a469487\",\"dweb:/ipfs/QmPGWT2x3QHcKxqe6gRmAkdakhbaRgx3DLzcakHz5M4eXG\"]},\"@openzeppelin/contracts/utils/introspection/IERC165.sol\":{\"keccak256\":\"0x447a5f3ddc18419d41ff92b3773fb86471b1db25773e07f877f548918a185bf1\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://be161e54f24e5c6fae81a12db1a8ae87bc5ae1b0ddc805d82a1440a68455088f\",\"dweb:/ipfs/QmP7C3CHdY9urF4dEMb9wmsp1wMxHF6nhA2yQE5SKiPAdy\"]},\"contracts/interfaces/IAgToken.sol\":{\"keccak256\":\"0x0c83efcfc1fb9ae9ba830f7b89e3dab9abf6ad7a6205a31aa35fbccaa837dcdc\",\"license\":\"GPL-3.0\",\"urls\":[\"bzz-raw://fa016d95e3649b4a98085d42666c77d29bb402af704cc67e5473f09c760eb875\",\"dweb:/ipfs/QmVLLPrCqL7rFYaUwEfdEuc727N8sfyP3brrcZpBhvsxK6\"]},\"contracts/interfaces/ICoreBorrow.sol\":{\"keccak256\":\"0x10249210cbf522775f040baf981d7d037472168ce2746d87473ac7c29a34e62e\",\"license\":\"GPL-3.0\",\"urls\":[\"bzz-raw://5662508bcc221233db54b5b311c4e371bd8616b3c5c3572ae207c04060758b67\",\"dweb:/ipfs/QmZCQVyMFbWkBZJnwwB3vxLZkvSXGxEg3Hu1UFJQfpV9fi\"]},\"contracts/interfaces/IFlashAngle.sol\":{\"keccak256\":\"0x39b0097f695b9e934bccdc72676c91513f1077cc5d0fd151908fd25a7c5cfbe4\",\"license\":\"GPL-3.0\",\"urls\":[\"bzz-raw://5b0f3c3581f390b0242d8252a4a215dd04b4c5b74e1efb7396bbba72c3922a02\",\"dweb:/ipfs/Qmc7BxyifSkpKtneN2gMsKkworGPDwVfBdT2t66iGMDerm\"]},\"contracts/interfaces/IOracle.sol\":{\"keccak256\":\"0x66fe2bb27f26b86e5832fc7d1ebd320cac8b3d79c5998ce148cf7279b2b359be\",\"license\":\"GPL-3.0\",\"urls\":[\"bzz-raw://6fb1e0a9e4d71e8ba0ecce45d86b0459a8a12ad575e49278d277d40a85ed9850\",\"dweb:/ipfs/QmXCjer5F4aGUwJaN5b2jgXK19q5Q7fuZQ3sCPQjnQvAFQ\"]},\"contracts/interfaces/ISwapper.sol\":{\"keccak256\":\"0x2c18883cbff92d1e558e670480f5e2f517bce8c95c202cc3f6602ac276222609\",\"license\":\"GPL-3.0\",\"urls\":[\"bzz-raw://948ebdaf95b08d6617f490aa0651a90d8cc3ef3d4c0b9edc3a50e4fe6df73013\",\"dweb:/ipfs/QmejFnT3zzN2StAUnVDHS62iFxZ4e5ZQBTQ3kghDPXRR9g\"]},\"contracts/interfaces/ITreasury.sol\":{\"keccak256\":\"0x06c2f781c08732ce1b5845c083af5742716245baa6c519bd737f32b230a884c1\",\"license\":\"GPL-3.0\",\"urls\":[\"bzz-raw://bdd772d505d001385e131ba5103a94607ad2b195f8e60cb73d15ae0865bc93f6\",\"dweb:/ipfs/QmeAASi2TZqDK3Nu5VSoFQ4zJgyLZ8kAXzguw6eikNNWaC\"]},\"contracts/interfaces/IVaultManager.sol\":{\"keccak256\":\"0x9182de4d6ff41a768d2da1d53bc448cfbdc0db8336d0c9fc00b9f655177bfe22\",\"license\":\"GPL-3.0\",\"urls\":[\"bzz-raw://c3c156b7736db233c7043595816d97aa9a3a0db01d9b87b66bf17a5a42619a73\",\"dweb:/ipfs/QmbRtii3Zues9XyTzjZaT5ZZuH7sWVtMQB6coWn8MFkUos\"]},\"contracts/interfaces/external/IERC1271.sol\":{\"keccak256\":\"0x6887d50d488064e481dfba3a9c54c049430b1ffc0a5536387fa89ff5133e6479\",\"license\":\"GPL-2.0-or-later\",\"urls\":[\"bzz-raw://0b080810d65481a97abbb7306b31ed944cd01dd19cb27a7a8e779f81bd9b6d11\",\"dweb:/ipfs/QmZUoJgs3JxAeki6CkbFD8uxBypipefhMS8uuVkQcxnsug\"]},\"contracts/interfaces/governance/IVeBoostProxy.sol\":{\"keccak256\":\"0xce73b8dcafcfaba4d01216f02f49930c078617e11223290004c6f662fc900d6b\",\"license\":\"GPL-3.0\",\"urls\":[\"bzz-raw://eb1eec1ea1c000dc07fa89e4f5f8e7009c1777a03960d7e02dcf3fa6f1630333\",\"dweb:/ipfs/QmbMqqz6nBHQmY57EqfhQA5Ep8WVnQSjaejW79XWtowHzv\"]},\"contracts/vaultManager/VaultManager.sol\":{\"keccak256\":\"0x61131646792ae020fde502ad828dd3028dc0363bce1f81f906b0ee20ac2ebb57\",\"license\":\"GPL-3.0\",\"urls\":[\"bzz-raw://5917b86f047547efbc1092a0a58ba273581cddb5e36e0b89c369ac1a60001059\",\"dweb:/ipfs/QmY51bCfdLR2Lt14GZk1JwSnCJaQFEQNDQfRKh95ut9F61\"]},\"contracts/vaultManager/VaultManagerERC721.sol\":{\"keccak256\":\"0x1169ae296e188224be8716c6c4be19cb6de30e2a55ee7b4e1d4a554ba07573b1\",\"license\":\"GPL-3.0\",\"urls\":[\"bzz-raw://9e87a1905680d1c9d4a3ac07b0a009d0b82e3c73d7ca735b85f6eda042a283bf\",\"dweb:/ipfs/QmczgGUKMzChBV8XAVkxaYftc7wWstx3FLTLCMTFVt8WbT\"]},\"contracts/vaultManager/VaultManagerLiquidationBoost.sol\":{\"keccak256\":\"0xbe2a172d8bd96149ac6bd0113644d59337a40c99b8e9eff0a6393efc3ae8de81\",\"license\":\"GPL-3.0\",\"urls\":[\"bzz-raw://e114f045f071084f504b96d28796d391867346a95cf9004b3f47e10ce906bee1\",\"dweb:/ipfs/QmXSW6XnDTpCredi8KEjwNgntPL6kRPb1mMX5YF9QgHiXQ\"]},\"contracts/vaultManager/VaultManagerPermit.sol\":{\"keccak256\":\"0x1303785eb96597effcbf7d7969be0c5c40c0c7d5a5c6b5b2f7eb20325f07e61f\",\"license\":\"GPL-3.0\",\"urls\":[\"bzz-raw://e9c853c15dc80a49de107cb02788b55006a0797f4ac6c003ea7db2dc62b80ea5\",\"dweb:/ipfs/QmT1XyC5L8u95fYti9DnGTXsyWCQLBcvqGoEKmDazf8pog\"]},\"contracts/vaultManager/VaultManagerStorage.sol\":{\"keccak256\":\"0x273408229fc3dd53f0505466b0c2d94db8b58bfc9fa83791b1d9a9a3dde58721\",\"license\":\"GPL-3.0\",\"urls\":[\"bzz-raw://6fe7585950551e93d2b608d3cbe9cefbc463cb2505e78d79fd2da9a93afafe77\",\"dweb:/ipfs/QmVdko67oqD9suZCzyFdUX4JjYiMPKQHoMPyCW2FEWCVdd\"]}},\"version\":1}", + "bytecode": "0x60806040523480156200001157600080fd5b50600054610100900460ff1615808015620000335750600054600160ff909116105b8062000063575062000050306200013d60201b62002f931760201c565b15801562000063575060005460ff166001145b620000cb5760405162461bcd60e51b815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201526d191e481a5b9a5d1a585b1a5e995960921b606482015260840160405180910390fd5b6000805460ff191660011790558015620000ef576000805461ff0019166101001790555b801562000136576000805461ff0019169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15b506200014c565b6001600160a01b03163b151590565b615f2f806200015c6000396000f3fe608060405234801561001057600080fd5b50600436106103015760003560e01c8063010db1951461030657806301ffc9a71461032f57806306fdde0314610352578063081812fc14610367578063087a60071461037a578063095ea7b3146103915780630e198f22146103a657806313888565146103af57806323b872dd146103b8578063254cf439146103cb578063307439af146103fd57806334ce998a1461041d57806335836f15146104255780633644e5151461043857806339393ac91461044057806339eb4dc6146104535780633ae2325f146104675780633af32abf1461047a5780633c2e941b1461049a57806342842e0e146104a3578063430c2081146104b65780634f7e43df146104c957806355f804b3146104e35780635c975abb146104f657806361d027b31461050a5780636352211e1461051d57806370a082311461053057806374107543146105435780637aacfffa146105565780637adbf973146105925780637c0f59f4146105a55780637c3a00fd146105bf5780637dc0d1d0146105d25780637e53bd97146105e55780637e56d47c146105f85780637ecebe001461060b578063835986b41461063457806389050f1d1461064757806395d89b41146106595780639a3b6f2f146106615780639f48118f146106a7578063a22cb465146106b2578063af2c8c2e146106c5578063b1511cc9146106ce578063b4bd6f46146106e1578063b88d4fde146106f4578063bbcac55714610707578063bfc7ad2e14610710578063c13cacae14610719578063c4ae31681461072c578063c66d8b0114610734578063c87b56dd1461074e578063d8dfeb4514610761578063d9b1cb5b14610774578063de1f776514610787578063de8fc69814610799578063df011c41146107ac578063e182b883146107bf578063e1c84ea4146107d2578063e626648a146107db578063e985e9c5146107f5578063e9cbd82214610808578063f0f442601461081b578063f51cc7dd1461082e578063fad9aba314610841578063fc29b0211461084a578063fd527cf81461085d575b600080fd5b603754610319906001600160a01b031681565b6040516103269190614e36565b60405180910390f35b61034261033d366004614e60565b610865565b6040519015158152602001610326565b61035a6108d2565b6040516103269190614ed5565b610319610375366004614ee8565b610960565b610383603f5481565b604051908152602001610326565b6103a461039f366004614f16565b610991565b005b610383603e5481565b61038360415481565b6103a46103c6366004614f42565b610a1e565b603c546103e590600160401b90046001600160401b031681565b6040516001600160401b039091168152602001610326565b61041061040b366004614f83565b610a59565b6040516103269190614fb3565b610383610b0b565b610383610433366004614ee8565b610b3d565b610383610b79565b6103a461044e366004614fec565b610b83565b603d5461034290600160c01b900460ff1681565b610383610475366004614ee8565b610c83565b610383610488366004614fec565b60446020526000908152604090205481565b61038360455481565b6103a46104b1366004614f42565b610ca4565b6103426104c4366004614f16565b610cbf565b603d546103e590600160801b90046001600160401b031681565b6103a46104f13660046150be565b610ccb565b603d5461034290600160c81b900460ff1681565b603354610319906001600160a01b031681565b61031961052b366004614ee8565b610d70565b61038361053e366004614fec565b610d7b565b6103a4610551366004615109565b610dc0565b61057d610564366004614ee8565b6043602052600090815260409020805460019091015482565b60408051928352602083019190915201610326565b6103a46105a0366004614fec565b61118c565b603c546103e590600160c01b90046001600160401b031681565b603d546103e5906001600160401b031681565b603654610319906001600160a01b031681565b6103a46105f33660046151b3565b6112d3565b610410610606366004615228565b6114c4565b610383610619366004614fec565b6001600160a01b03166000908152607f602052604090205490565b6103a46106423660046152ec565b611ad8565b610383676765c793fa10079d601a1b81565b61035a611c79565b61067461066f366004615406565b611c86565b60405161032691908151815260208083015190820152604080830151908201526060918201519181019190915260800190565b610383633b9aca0081565b6103a46106c036600461549c565b611cbb565b61038360405481565b6103a46106dc366004614ee8565b611cc6565b6103836106ef366004614fec565b611d8f565b6103a46107023660046154ca565b611dc5565b61038360425481565b61038360b65481565b6103a4610727366004615535565b611e02565b6103a4611ebf565b603d546103e590600160401b90046001600160401b031681565b61035a61075c366004614ee8565b611f6e565b603454610319906001600160a01b031681565b6103a4610782366004615561565b6120c3565b610383676765c793fa10079d601b1b81565b6106746107a73660046155f5565b61222f565b603c546103e5906001600160401b031681565b6103836107cd366004614ee8565b612aad565b61038360395481565b603c546103e590600160801b90046001600160401b031681565b610342610803366004615653565b612abd565b603554610319906001600160a01b031681565b6103a4610829366004614fec565b612aeb565b6103a461083c366004615690565b612b8b565b61038360b45481565b61041061085836600461570a565b612e4a565b61057d612e74565b60006001600160e01b03198216635b5e139f60e01b148061089657506001600160e01b031982166380ac58cd60e01b145b806108b157506001600160e01b0319821663430c208160e01b145b806108cc57506001600160e01b031982166301ffc9a760e01b145b92915050565b607d80546108df90615766565b80601f016020809104026020016040519081016040528092919081815260200182805461090b90615766565b80156109585780601f1061092d57610100808354040283529160200191610958565b820191906000526020600020905b81548152906001019060200180831161093b57829003601f168201915b505050505081565b600061096b82612fa2565b6109885760405163062a39dd60e11b815260040160405180910390fd5b6108cc82612fbf565b600061099c82612fda565b9050806001600160a01b0316836001600160a01b031614156109d1576040516349fa8bc360e11b815260040160405180910390fd5b336001600160a01b038216148015906109f157506109ef8133612abd565b155b15610a0f5760405163c19f17a960e01b815260040160405180910390fd5b610a198383613010565b505050565b3381610a2a828261307e565b610a475760405163c19f17a960e01b815260040160405180910390fd5b610a528585856130fc565b5050505050565b610a61614d0c565b60008381526043602090815260409182902082518084018452815481526001909101548183015260365483516315f789a960e21b81529351610b0494929387936001600160a01b03909316926357de26a492600480830193928290030181865afa158015610ad3573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610af7919061579b565b610aff6131d3565b613368565b9392505050565b6000676765c793fa10079d601b1b610b216131d3565b604054610b2e91906157ca565b610b3891906157ff565b905090565b6000676765c793fa10079d601b1b610b536131d3565b600084815260436020526040902060010154610b6f91906157ca565b6108cc91906157ff565b6000610b386136d1565b603354604051631c86b03760e31b81526001600160a01b039091169063e43581b890610bb3903390600401614e36565b602060405180830381865afa158015610bd0573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610bf49190615813565b610c1157604051633b8d9d7560e21b815260040160405180910390fd5b6001600160a01b03811615610c60576001600160a01b038116600090815260446020526040902054610c44906001615830565b6001600160a01b03821660009081526044602052604090205550565b603d805460ff60c01b198116600160c01b9182900460ff16159091021790555b50565b603b8181548110610c9357600080fd5b600091825260209091200154905081565b610a1983838360405180602001604052806000815250611dc5565b6000610b04838361307e565b60335460405163521d4de960e01b81526001600160a01b039091169063521d4de990610cfb903390600401614e36565b602060405180830381865afa158015610d18573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610d3c9190615813565b610d5957604051632678482f60e21b815260040160405180910390fd5b8051610d6c906046906020840190614d3b565b5050565b60006108cc82612fda565b60006001600160a01b038216610da45760405163d92e233d60e01b815260040160405180910390fd5b506001600160a01b031660009081526048602052604090205490565b60335460405163521d4de960e01b81526001600160a01b039091169063521d4de990610df0903390600401614e36565b602060405180830381865afa158015610e0d573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610e319190615813565b610e4e57604051632678482f60e21b815260040160405180910390fd5b806121a360f11b1415610eb257603d546001600160401b03600160401b90910481169083161115610e9257604051637650e96360e11b815260040160405180910390fd5b603c80546001600160401b0319166001600160401b038416179055611145565b80622a242360e91b1415610f1757633b9aca00826001600160401b03161015610eee5760405163da6a17b960e01b815260040160405180910390fd5b603c8054600160401b600160801b031916600160401b6001600160401b03851602179055611145565b8061212360f11b1415610f7b57633b9aca00826001600160401b03161115610f5257604051637650e96360e11b815260040160405180910390fd5b603c8054600160801b600160c01b031916600160801b6001600160401b03851602179055611145565b8061292360f11b1415610ff857603d54633b9aca0090610fab90600160401b90046001600160401b031684615847565b6001600160401b03161115610fd357604051637650e96360e11b815260040160405180910390fd5b603c80546001600160c01b0316600160c01b6001600160401b03851602179055611145565b806124a960f11b141561102e5761100d61373d565b50603d80546001600160401b0319166001600160401b038416179055611145565b80614c5360f01b14156110c757603c546001600160401b03808416911611806110805750603c54633b9aca009061107590600160c01b90046001600160401b031684615847565b6001600160401b0316115b1561109e5760405163180d062b60e31b815260040160405180910390fd5b603d8054600160401b600160801b031916600160401b6001600160401b03851602179055611145565b806213531160ea1b141561112c57633b9aca00826001600160401b0316111561110357604051637650e96360e11b815260040160405180910390fd5b603d8054600160801b600160c01b031916600160801b6001600160401b03851602179055611145565b60405163e1daa9cf60e01b815260040160405180910390fd5b604080516001600160401b0384168152602081018390527f13b367dac93b85d1ed9b3d8961d8b48e1a677c9800bb1613b4b0416b2d5b61d091015b60405180910390a15050565b603354604051631c86b03760e31b81526001600160a01b039091169063e43581b8906111bc903390600401614e36565b602060405180830381865afa1580156111d9573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906111fd9190615813565b61121a57604051633b8d9d7560e21b815260040160405180910390fd5b603354604080516361d027b360e01b815290516001600160a01b03928316928416916361d027b39160048083019260209291908290030181865afa158015611266573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061128a9190615872565b6001600160a01b0316146112b1576040516302979eb960e31b815260040160405180910390fd5b603680546001600160a01b0319166001600160a01b0392909216919091179055565b60335460405163521d4de960e01b81526001600160a01b039091169063521d4de990611303903390600401614e36565b602060405180830381865afa158015611320573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906113449190615813565b61136157604051632678482f60e21b815260040160405180910390fd5b8051825114158061138c5750806000815181106113805761138061588f565b60200260200101516000145b8061141b57506001600160a01b0383161580159061141b5750816000815181106113b8576113b861588f565b6020026020010151826001815181106113d3576113d361588f565b602002602001015111158061141b5750806000815181106113f6576113f661588f565b6020026020010151816001815181106114115761141161588f565b6020026020010151105b1561143957604051631746545d60e11b815260040160405180910390fd5b603780546001600160a01b0319166001600160a01b038516179055815161146790603a906020850190614dbf565b50805161147b90603b906020840190614dbf565b50826001600160a01b03167feb74d4d9fea592587c926aeb35eb6a7893fb28db0c1c8eb2eb3c586e7164b76c83836040516114b79291906158e0565b60405180910390a2505050565b6114cc614d0c565b6114d46137de565b156114f2576040516313d0ff5960e31b815260040160405180910390fd5b6002600154141561151e5760405162461bcd60e51b815260040161151590615905565b60405180910390fd5b6002600155603d54600160c01b900460ff16801561154c575033600090815260446020526040902054600114155b801561157157506001600160a01b038416600090815260446020526040902054600114155b1561158f57604051630b094f2760e31b815260040160405180910390fd5b865186518114158061159f575080155b156115bd576040516346282e8d60e01b815260040160405180910390fd5b603660009054906101000a90046001600160a01b03166001600160a01b03166357de26a46040518163ffffffff1660e01b8152600401602060405180830381865afa158015611610573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611634919061579b565b606083015261164161373d565b60808301526040517f965a177723c641ee49150b583a0b9ad4730bb20d3474e00ae5a65e777c00d67b90611676908a9061593c565b60405180910390a160005b81811015611a48576000604360008b84815181106116a1576116a161588f565b6020026020010151815260200190815260200160002060405180604001604052908160008201548152602001600182015481525050905060006116ee823387606001518860800151613368565b90508060400151600014158015611722575080604001518a84815181106117175761171761588f565b602002602001015110155b80611749575080600001518a848151811061173f5761173f61588f565b6020026020010151115b156117725780600001518a84815181106117655761176561588f565b6020026020010181815250505b60008560600151826060015161178891906157ca565b603854633b9aca008d87815181106117a2576117a261588f565b60200260200101516117b491906157ca565b6117be91906157ca565b6117c891906157ff565b90506117f68c85815181106117df576117df61588f565b60200260200101518285600001511115610c805750565b8251811061192c57508151602083015160408054600090611818908490615830565b92505081905550604360008d86815181106118355761183561588f565b60209081029190910181015182528101919091526040016000908120818155600101819055603d548c51633b9aca0091600160401b90046001600160401b0316908e90889081106118885761188861588f565b602002602001015161189a91906157ca565b6118a491906157ff565b9050826080015181106118b85760006118c8565b8083608001516118c89190615830565b876040018181516118d9919061594f565b905250508b51600080516020615e9a833981519152908d90869081106119015761190161588f565b60200260200101518460200151600060405161191f93929190615967565b60405180910390a16119ed565b80604360008e87815181106119435761194361588f565b60200260200101518152602001908152602001600020600001600082825461196b9190615830565b925050819055506119eb8c85815181106119875761198761588f565b6020026020010151633b9aca00603d60089054906101000a90046001600160401b03166001600160401b03168e88815181106119c5576119c561588f565b60200260200101516119d791906157ca565b6119e191906157ff565b88608001516137ee565b505b80866020018181516119ff919061594f565b9052508a518b9085908110611a1657611a1661588f565b602002602001015186600001818151611a2f919061594f565b905250611a4192508391506159809050565b9050611681565b50603d54633b9aca0090611a6c90600160401b90046001600160401b031682615830565b8351611a7891906157ca565b611a8291906157ff565b60416000828254611a93919061594f565b9091555050604082015160428054600090611aaf90849061594f565b909155505060208201518251611ac991908888888861391d565b50600180559695505050505050565b611ae06137de565b15611afe576040516313d0ff5960e31b815260040160405180910390fd5b6033546040516333b52a9f60e11b81526001600160a01b039091169063676a553e90611b2e903390600401614e36565b602060405180830381865afa158015611b4b573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611b6f9190615813565b611b8c5760405163027f480760e01b815260040160405180910390fd5b600080611b97613a27565b6001600160401b0316905082811115611bb757611bb48382615830565b91505b50603c54600090600160801b90046001600160401b0316841115611bf557603c54611bf290600160801b90046001600160401b031685615830565b90505b6000611c066002633b9aca00615a7f565b611c1483633b9aca00615830565b611c2285633b9aca00615830565b611c2c90896157ca565b611c3691906157ca565b611c4091906157ff565b9050611c4c8187615830565b60416000828254611c5d919061594f565b90915550611c6f9050878260006137ee565b5050505050505050565b607e80546108df90615766565b611c8e614df9565b60408051600080825260208201909252611cb09187918791879187919061222f565b90505b949350505050565b610d6c338383613a3d565b60335460405163521d4de960e01b81526001600160a01b039091169063521d4de990611cf6903390600401614e36565b602060405180830381865afa158015611d13573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611d379190615813565b611d5457604051632678482f60e21b815260040160405180910390fd5b60398190556040518181527fdd63b3dcdbebad734892f7c7a26d0f647fbc7eec973e0775f5229018ac4ab47a9060200160405180910390a150565b6000611d996137de565b15611db7576040516313d0ff5960e31b815260040160405180910390fd5b6108cc82613af3565b919050565b3382611dd1828261307e565b611dee5760405163c19f17a960e01b815260040160405180910390fd5b611dfa86868686613bb6565b505050505050565b603354604051631c86b03760e31b81526001600160a01b039091169063e43581b890611e32903390600401614e36565b602060405180830381865afa158015611e4f573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611e739190615813565b611e9057604051633b8d9d7560e21b815260040160405180910390fd5b81831115611eb15760405163180d062b60e31b815260040160405180910390fd5b60b49290925560b65560b555565b60335460405163521d4de960e01b81526001600160a01b039091169063521d4de990611eef903390600401614e36565b602060405180830381865afa158015611f0c573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611f309190615813565b611f4d57604051632678482f60e21b815260040160405180910390fd5b603d805460ff60c81b198116600160c81b9182900460ff1615909102179055565b6060611f7982612fa2565b611f965760405163062a39dd60e11b815260040160405180910390fd5b8160005b8115611fbd57611fa981615980565b9050611fb6600a836157ff565b9150611f9a565b6000816001600160401b03811115611fd757611fd7615009565b6040519080825280601f01601f191660200182016040528015612001576020820181803683370190505b5090505b841561206c57612016600183615830565b9150612023600a86615a8e565b61202e90603061594f565b60f81b8183815181106120435761204361588f565b60200101906001600160f81b031916908160001a905350612065600a866157ff565b9450612005565b6046805461207990615766565b1515905061209657604051806020016040528060008152506120ba565b6046816040516020016120aa929190615abe565b6040516020818303038152906040525b95945050505050565b600054610100900460ff16158080156120e35750600054600160ff909116105b8061210457506120f230612f93565b158015612104575060005460ff166001145b6121675760405162461bcd60e51b815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201526d191e481a5b9a5d1a585b1a5e995960921b6064820152608401611515565b6000805460ff19166001179055801561218a576000805461ff0019166101001790555b6121a586868661219f36889003880188615b5c565b86613bf0565b6121b560e0840160c08501615c1a565b603d805460ff60c81b19921515600160c01b029290921661ffff60c01b1990921691909117600160c81b1790558015611dfa576000805461ff0019169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a1505050505050565b612237614df9565b61223f6137de565b1561225d576040516313d0ff5960e31b815260040160405180910390fd5b600260015414156122805760405162461bcd60e51b815260040161151590615905565b60026001558551875114158061229557508651155b156122b3576040516346282e8d60e01b815260040160405180910390fd5b6000806000806000805b8c518110156128165760008d82815181106122da576122da61588f565b60200260200101519050600060078111156122f7576122f7615c37565b81600781111561230957612309615c37565b141561234a576123448d83815181106123245761232461588f565b602002602001015180602001905181019061233f9190615872565b613af3565b50612805565b600281600781111561235e5761235e615c37565b14156123c4578c82815181106123765761237661588f565b60200260200101518060200190518101906123919190615c4d565b95509250826123a05760455492505b6123aa8386613f79565b84886060018181516123bc919061594f565b905250612805565b60078160078111156123d8576123d8615c37565b14156124b15760008060008f85815181106123f5576123f561588f565b60200260200101518060200190518101906124109190615c71565b60345460405163d505accf60e01b81526001600160a01b038089166004830152306024830152604482018890526064820187905260ff8616608483015260a4820185905260c48201849052969f50939d50939b509497509550929350169063d505accf9060e401600060405180830381600087803b15801561249157600080fd5b505af11580156124a5573d6000803e3d6000fd5b50505050505050612805565b866124c1576124be61373d565b96505b60048160078111156124d5576124d5615c37565b141561259d578c82815181106124ed576124ed61588f565b60200260200101518060200190518101906125089190615c4d565b94509250826125175760455492505b6125228385896137ee565b9350600061252e613a27565b612545906001600160401b0316633b9aca00615830565b612553633b9aca00876157ca565b61255d91906157ff565b90506125698582615830565b6041600082825461257a919061594f565b925050819055508089602001818151612593919061594f565b9052506128059050565b8561261c57603660009054906101000a90046001600160a01b03166001600160a01b03166357de26a46040518163ffffffff1660e01b8152600401602060405180830381865afa1580156125f5573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612619919061579b565b95505b600181600781111561263057612630615c37565b14156126ac578c82815181106126485761264861588f565b6020026020010151806020019051810190612663919061579b565b9250826126705760455492505b61267b838789613fe5565b80965081955050508488604001818151612695919061594f565b9052506020880180518591906123bc90839061594f565b60038160078111156126c0576126c0615c37565b1415612720578c82815181106126d8576126d861588f565b60200260200101518060200190518101906126f39190615c4d565b95509250826127025760455492505b61270e8386888a614102565b84886040018181516123bc919061594f565b600581600781111561273457612734615c37565b1415612796578c828151811061274c5761274c61588f565b60200260200101518060200190518101906127679190615c4d565b94509250826127765760455492505b6127828385888a6141dc565b935083886000018181516123bc919061594f565b60068160078111156127aa576127aa615c37565b1415612805576000808e84815181106127c5576127c561588f565b60200260200101518060200190518101906127e09190615cc4565b985091965092509050846127f45760455494505b612802858383898c8e614277565b50505b5061280f81615980565b90506122bd565b50855160208701511061290d578551602087015160009161283691615830565b9050866060015187604001511061286d576128688760600151886040015161285e9190615830565b828d8d8d8d61391d565b612907565b80156128da57603554604051630d43af8160e21b81526001600160a01b039091169063350ebe04906128a79084908f903390600401615d02565b600060405180830381600087803b1580156128c157600080fd5b505af11580156128d5573d6000803e3d6000fd5b505050505b612907333089604001518a606001516128f39190615830565b6034546001600160a01b03169291906143c7565b50612a99565b6020860151865160009161292091615830565b6035546040516340c10f1960e01b81529192506001600160a01b0316906340c10f1990612953908d908590600401615d21565b600060405180830381600087803b15801561296d57600080fd5b505af1158015612981573d6000803e3d6000fd5b505050508660600151876040015111156129c5576129c08a886060015189604001516129ad9190615830565b6034546001600160a01b03169190614432565b612a97565b6000876040015188606001516129db9190615830565b90508015612a9557885115612a7d57896001600160a01b031663a5d4096b603560009054906101000a90046001600160a01b0316603460009054906101000a90046001600160a01b03163385878f6040518763ffffffff1660e01b8152600401612a4a96959493929190615d3a565b600060405180830381600087803b158015612a6457600080fd5b505af1158015612a78573d6000803e3d6000fd5b505050505b603454612a95906001600160a01b03163330846143c7565b505b505b505060018055509198975050505050505050565b603a8181548110610c9357600080fd5b6001600160a01b039182166000908152604a6020908152604080832093909416825291909152205460011490565b6033546001600160a01b03163314612b165760405163b90cdbb160e01b815260040160405180910390fd5b603380546001600160a01b0319166001600160a01b0383811691909117909155603654604051630787a21360e51b815291169063f0f4426090612b5d908490600401614e36565b600060405180830381600087803b158015612b7757600080fd5b505af1158015610a52573d6000803e3d6000fd5b83421115612bac5760405163f87d927160e01b815260040160405180910390fd5b6fa2a8918ca85bafe22016d0b997e4df60600160ff1b03811180612be357508260ff16601b14158015612be357508260ff16601c14155b15612c0157604051638baa579f60e01b815260040160405180910390fd5b6000612c0b6136d1565b608254898989612c1a8d614451565b6040805160208101969096526001600160a01b03948516908601529290911660608401521515608083015260a082015260c0810187905260e00160405160208183030381529060405280519060200120604051602001612c9192919061190160f01b81526002810192909252602282015260420190565b604051602081830303815290604052805190602001209050612cbb886001600160a01b0316612f93565b15612d9757604080516020810185905280820184905260f886901b6001600160f81b0319166060820152815160418183030181526061820192839052630b135d3f60e11b9092526001600160a01b038a1691631626ba7e91612d21918591606501615d7c565b602060405180830381865afa158015612d3e573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612d629190615d95565b6001600160e01b031916631626ba7e60e01b14612d9257604051638baa579f60e01b815260040160405180910390fd5b612e3f565b6040805160008082526020820180845284905260ff871692820192909252606081018590526080810184905260019060a0016020604051602081039080840390855afa158015612deb573d6000803e3d6000fd5b505050602060405103519050886001600160a01b0316816001600160a01b0316141580612e1f57506001600160a01b038116155b15612e3d57604051638baa579f60e01b815260040160405180910390fd5b505b611c6f888888613a3d565b612e52614d0c565b60408051600080825260208201909252611cb0918791879187918791906114c4565b60335460009081906001600160a01b03163314612ea45760405163b90cdbb160e01b815260040160405180910390fd5b612eac61373d565b505060418054604280546000938490559290559150808210612f4557612ed28183615830565b6035546033546040516340c10f1960e01b8152929450600093506001600160a01b03918216926340c10f1992612f0e9216908690600401615d21565b600060405180830381600087803b158015612f2857600080fd5b505af1158015612f3c573d6000803e3d6000fd5b50505050612f56565b612f4f8282615830565b9050600091505b60408051838152602081018390527ffeb12225c131aab793a00c5239afb778932d170fa28ce6e9d23703e4bd892121910160405180910390a19091565b6001600160a01b03163b151590565b6000908152604760205260409020546001600160a01b0316151590565b6000908152604960205260409020546001600160a01b031690565b6000818152604760205260409020546001600160a01b031680611dc05760405163062a39dd60e11b815260040160405180910390fd5b600081815260496020526040902080546001600160a01b0319166001600160a01b038416908117909155819061304582612fda565b6001600160a01b03167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92560405160405180910390a45050565b60008061308a83612fda565b9050806001600160a01b0316846001600160a01b031614806130c55750836001600160a01b03166130ba84612fbf565b6001600160a01b0316145b80611cb357506001600160a01b038082166000908152604a6020908152604080832093881683529290522054600114949350505050565b826001600160a01b031661310f82612fda565b6001600160a01b0316146131365760405163c19f17a960e01b815260040160405180910390fd5b6001600160a01b03821661315d5760405163d92e233d60e01b815260040160405180910390fd5b613168600082613010565b6001600160a01b038084166000818152604860209081526040808320805460001901905593861680835284832080546001019055858352604790915283822080546001600160a01b03191682179055925184939291600080516020615eda83398151915291a4505050565b600080603e54426131e49190615830565b603d549091506001600160401b03168115806131fe575080155b1561320d57603f549250505090565b600061321a600184615830565b905060006002841161322d576000613238565b613238600285615830565b90506000676765c793fa10079d601b1b676765c793fa10079d601a1b61325e86806157ca565b613268919061594f565b61327291906157ff565b90506000676765c793fa10079d601b1b676765c793fa10079d601a1b61329887856157ca565b6132a2919061594f565b6132ac91906157ff565b905060006002836132bd878a6157ca565b6132c791906157ca565b6132d191906157ff565b90506000600683866132e3898c6157ca565b6132ed91906157ca565b6132f791906157ca565b61330191906157ff565b9050676765c793fa10079d601b1b818361331b8b8b6157ca565b61333090676765c793fa10079d601b1b61594f565b61333a919061594f565b613344919061594f565b603f5461335191906157ca565b61335b91906157ff565b9850505050505050505090565b613370614d0c565b6000806000613380888787614495565b925092509250633b9aca0083106133aa576040516315fe9b6160e21b815260040160405180910390fd5b6000633b9aca006133bb8582615830565b6133c48a61451e565b6133ce91906157ca565b6133d891906157ff565b603d54909150600160801b90046001600160401b03168110156134085761340381633b9aca00615830565b613429565b603d5461342990600160801b90046001600160401b0316633b9aca00615830565b603d54909150600160401b90046001600160401b03166000806134516002633b9aca00615a7f565b603c5461346791906001600160401b03166157ca565b83613472868a6157ca565b61347c91906157ca565b1061360157603c546001600160401b031661349c6002633b9aca00615a7f565b6134a691906157ca565b603c5485906134c590600160401b90046001600160401b0316866157ca565b6134cf91906157ca565b6134d99190615830565b603c548590633b9aca00906134f7906001600160401b0316896157ca565b603c54613515908b90600160401b90046001600160401b03166157ca565b61351f9190615830565b61352991906157ca565b61353391906157ca565b61353d91906157ff565b60b654909250613551633b9aca00826157ca565b61355b85856157ca565b613565919061594f565b613573633b9aca00896157ca565b116135fb5761358d676765c793fa10079d601b1b856157ca565b633b9aca008b8f602001516135a291906157ca565b6135ac91906157ca565b6135b691906157ff565b6135c190600161594f565b9250808711156135f65783633b9aca006135db838a615830565b6135e591906157ca565b6135ef91906157ff565b91506135fb565b600191505b5061367f565b60385461361290633b9aca006157ca565b8c518b906136219087906157ca565b61362b91906157ca565b61363591906157ff565b61364090600161594f565b915060b55485111561367b57633b9aca008460b554876136609190615830565b61366a91906157ca565b61367491906157ff565b905061367f565b5060015b81885261368c848b6157ca565b60385461369d633b9aca00856157ca565b6136a791906157ca565b6136b191906157ff565b602089015260408801525050606085015250608083015250949350505050565b60808054608154604080517f8b73c3c69bb8fe3d512ecc4cf759cc79239f7b179b0ffacaa9a75d522b39400f602082015290810192909252606082015246918101919091523060a082015260009060c00160405160208183030381529060405280519060200120905090565b60006137476131d3565b90506000676765c793fa10079d601b1b603f54836137659190615830565b60405461377291906157ca565b61377c91906157ff565b90508060416000828254613790919061594f565b9091555050603f82905542603e8190556040805184815260208101929092527fd1fa8ba00a3bf20274346919dce0de62d2a140af2c71fe7e29fa6472eea3bb9d910160405180910390a15090565b603d54600160c81b900460ff1690565b600081613800576137fd61373d565b91505b60008481526043602052604081206001015490676765c793fa10079d601b1b61382985846157ca565b61383391906157ff565b905080851061384457935080613867565b8361385a676765c793fa10079d601b1b876157ca565b61386491906157ff565b90505b6138718183615830565b915080604060008282546138859190615830565b909155505081158015906138ba5750676765c793fa10079d601b1b60b4546138ad91906157ca565b6138b785846157ca565b11155b156138d85760405163228af07f60e21b815260040160405180910390fd5b60008681526043602052604080822060010184905551600080516020615e9a8339815191529161390b9189918591615967565b60405180910390a15092949350505050565b851561393a5760345461393a906001600160a01b03168488614432565b8415611dfa578051156139b95760345460355460405163a5d4096b60e01b81526001600160a01b038086169363a5d4096b936139869391831692169089908b908d908990600401615d3a565b600060405180830381600087803b1580156139a057600080fd5b505af11580156139b4573d6000803e3d6000fd5b505050505b603554604051630d43af8160e21b81526001600160a01b039091169063350ebe04906139ed90889088903390600401615d02565b600060405180830381600087803b158015613a0757600080fd5b505af1158015613a1b573d6000803e3d6000fd5b50505050505050505050565b603c54600160c01b90046001600160401b031690565b826001600160a01b0316826001600160a01b03161415613a70576040516320c5195360e21b815260040160405180910390fd5b600081613a7e576000613a81565b60015b6001600160a01b038581166000818152604a602090815260408083209489168084529482529182902060ff959095169485905590518615158152939450919290917f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c31910160405180910390a350505050565b60006001600160a01b038216613b1c5760405163d92e233d60e01b815260040160405180910390fd5b5060458054600101908190556001600160a01b038216600081815260486020908152604080832080546001019055848352604790915280822080546001600160a01b031916841790555183929190600080516020615eda833981519152908290a4613b99600083836040518060200160405280600081525061474d565b611dc0576040516320149b4360e21b815260040160405180910390fd5b613bc18484846130fc565b613bcd8484848461474d565b613bea576040516320149b4360e21b815260040160405180910390fd5b50505050565b846001600160a01b0316836001600160a01b03166361d027b36040518163ffffffff1660e01b8152600401602060405180830381865afa158015613c38573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613c5c9190615872565b6001600160a01b031614613c83576040516302979eb960e31b815260040160405180910390fd5b603380546001600160a01b038088166001600160a01b0319928316179092556034805492871692909116821790556040805163313ce56760e01b8152905163313ce567916004808201926020929091908290030181865afa158015613cec573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613d109190615db2565b613d1b90600a615a7f565b603881905550846001600160a01b031663e9cbd8226040518163ffffffff1660e01b8152600401602060405180830381865afa158015613d5f573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613d839190615872565b603580546001600160a01b03199081166001600160a01b039384161790915560368054909116918516919091179055604051600090613dc6908390602001615dcf565b60408051601f198184030181529190528051909150613dec90607d906020840190614d3b565b50613df681614850565b81604051602001613e079190615e16565b604051602081830303815290604052607e9080519060200190613e2b929190614d3b565b50676765c793fa10079d601b1b603f5542603e55608083015160208401516001600160401b0391821691161180613e725750633b9aca0083608001516001600160401b0316115b80613e8d575082604001516001600160401b0316633b9aca00115b80613ea95750633b9aca008360a001516001600160401b031610155b80613eb6575060e0830151155b15613ed457604051631746545d60e11b815260040160405180910390fd5b8251603955602080840151603c80546040808801516001600160401b039485166001600160801b031993841617600160401b9186168202179093556060880151603d805460808b015160a08c0151938816919095161793861690940292909217600160801b600160c01b031916600160801b92909416919091029290921790558051918201905260e08401518152613f7090603b906001614dbf565b50505050505050565b613f8282612fa2565b613f9f5760405163062a39dd60e11b815260040160405180910390fd5b60008281526043602052604081208054839290613fbd90849061594f565b9091555050604051600080516020615eba833981519152906111809084908490600190615967565b6000803385613ff4828261307e565b6140115760405163c19f17a960e01b815260040160405180910390fd5b600087815260436020908152604080832081518083019092528054825260010154918101919091529080614046838a8a614495565b5091509150633b9aca00821161406f57604051631527804d60e31b815260040160405180910390fd5b8260200151604060008282546140859190615830565b9091555061409490508a614926565b600061409e613a27565b6140b5906001600160401b0316633b9aca00615830565b6140c3633b9aca00846157ca565b6140cd91906157ff565b90506140d98282615830565b604160008282546140ea919061594f565b90915550509251929a92995091975050505050505050565b338461410e828261307e565b61412b5760405163c19f17a960e01b815260040160405180910390fd5b60008681526043602052604081208054879290614149908490615830565b909155505060008681526043602090815260408083208151808301909252805482526001015491810191909152614181908686614495565b50509050633b9aca0081116141a957604051631527804d60e31b815260040160405180910390fd5b600080516020615eba833981519152878760006040516141cb93929190615967565b60405180910390a150505050505050565b600033856141ea828261307e565b6142075760405163c19f17a960e01b815260040160405180910390fd5b614213878787876149a5565b603c54909650600090633b9aca009061423d908990600160801b90046001600160401b03166157ca565b61424791906157ff565b9050806041600082825461425b919061594f565b9091555061426b90508188615830565b98975050505050505050565b3386614283828261307e565b6142a05760405163c19f17a960e01b815260040160405180910390fd5b60408051898152602081018890526001600160a01b038916818301526060810187905290517fddd3b70af631334f7552aadb582ed091018e62e103fa8b150ca66cc700d4dac69181900360800190a16142fb888686866149a5565b94506001600160a01b03871630141561431f576143198686856137ee565b50611c6f565b866001600160a01b031663835986b48787603c60109054906101000a90046001600160401b031661434e613a27565b6040516001600160e01b031960e087901b168152600481019490945260248401929092526001600160401b039081166044840152166064820152608401600060405180830381600087803b1580156143a557600080fd5b505af11580156143b9573d6000803e3d6000fd5b505050505050505050505050565b6040516001600160a01b0380851660248301528316604482015260648101829052613bea9085906323b872dd60e01b906084015b60408051601f198184030181529190526020810180516001600160e01b03166001600160e01b031990931692909217909152614b38565b610a198363a9059cbb60e01b84846040516024016143fb929190615d21565b6001600160a01b0381166000908152607f602052604090205461447581600161594f565b6001600160a01b039092166000908152607f602052604090209190915590565b6000806000676765c793fa10079d601b1b8487602001516144b691906157ca565b6144c091906157ff565b91506038548587600001516144d591906157ca565b6144df91906157ff565b9050816144f0576000199250614515565b603c548290614508906001600160401b0316836157ca565b61451291906157ff565b92505b93509350939050565b6037546000906001600160a01b031661455757603b6000815481106145455761454561588f565b90600052602060002001549050919050565b603754604051635dfba04560e11b81526000916001600160a01b03169063bbf7408a90614588908690600401614e36565b602060405180830381865afa1580156145a5573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906145c9919061579b565b9050603a6001815481106145df576145df61588f565b9060005260206000200154811061461757603b6001815481106146045761460461588f565b9060005260206000200154915050919050565b603a60008154811061462b5761462b61588f565b9060005260206000200154811161465057603b6000815481106146045761460461588f565b603a6000815481106146645761466461588f565b9060005260206000200154603a6001815481106146835761468361588f565b90600052602060002001546146989190615830565b603a6000815481106146ac576146ac61588f565b9060005260206000200154826146c29190615830565b603b6000815481106146d6576146d661588f565b9060005260206000200154603b6001815481106146f5576146f561588f565b906000526020600020015461470a9190615830565b61471491906157ca565b61471e91906157ff565b603b6000815481106147325761473261588f565b9060005260206000200154610b04919061594f565b50919050565b6000614761846001600160a01b0316612f93565b1561484857604051630a85bd0160e11b81526001600160a01b0385169063150b7a0290614798903390899088908890600401615e40565b6020604051808303816000875af19250505080156147d3575060408051601f3d908101601f191682019092526147d091810190615d95565b60015b61482e573d808015614801576040519150601f19603f3d011682016040523d82523d6000602084013e614806565b606091505b508051614826576040516320149b4360e21b815260040160405180910390fd5b805181602001fd5b6001600160e01b031916630a85bd0160e11b149050611cb3565b506001611cb3565b600054610100900460ff166148bb5760405162461bcd60e51b815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201526a6e697469616c697a696e6760a81b6064820152608401611515565b7f3f43a9c6bafb5c7aab4e0cfe239dc5d4c15caf0381c6104188191f78a6640bd860825580516020918201206080556040805180820190915260018152603160f81b9101527fc89efdaa54c0f20c7adf612882df0950f5a951637e0307cdcb4c672f298b8bc6608155565b600061493182612fda565b905061493e600083613010565b6001600160a01b038116600081815260486020908152604080832080546000190190558583526047825280832080546001600160a01b0319169055604390915280822082815560010182905551849290600080516020615eda833981519152908390a45050565b600080826149be676765c793fa10079d601b1b876157ca565b6149c891906157ff565b600087815260436020526040902060010154909150614a035760b4548511614a035760405163228af07f60e21b815260040160405180910390fd5b60008681526043602052604081206001018054839290614a2490849061594f565b925050819055508060406000828254614a3d919061594f565b9091555050603954614a5b90676765c793fa10079d601b1b906157ca565b83604054614a6991906157ca565b1115614a88576040516371239a6160e11b815260040160405180910390fd5b60008681526043602090815260408083208151808301909252805482526001015491810191909152614abb908686614495565b50509050633b9aca008111614ae357604051631527804d60e31b815260040160405180910390fd5b600080516020615e9a83398151915287836001604051614b0593929190615967565b60405180910390a1676765c793fa10079d601b1b614b2385846157ca565b614b2d91906157ff565b979650505050505050565b6000614b8d826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564815250856001600160a01b0316614c0a9092919063ffffffff16565b805190915015610a195780806020019051810190614bab9190615813565b610a195760405162461bcd60e51b815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e6044820152691bdd081cdd58d8d9595960b21b6064820152608401611515565b6060611cb3848460008585614c1e85612f93565b614c6a5760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006044820152606401611515565b600080866001600160a01b03168587604051614c869190615e7d565b60006040518083038185875af1925050503d8060008114614cc3576040519150601f19603f3d011682016040523d82523d6000602084013e614cc8565b606091505b5091509150614b2d82828660608315614ce2575081610b04565b825115614cf25782518084602001fd5b8160405162461bcd60e51b81526004016115159190614ed5565b6040518060a0016040528060008152602001600081526020016000815260200160008152602001600081525090565b828054614d4790615766565b90600052602060002090601f016020900481019282614d695760008555614daf565b82601f10614d8257805160ff1916838001178555614daf565b82800160010185558215614daf579182015b82811115614daf578251825591602001919060010190614d94565b50614dbb929150614e21565b5090565b828054828255906000526020600020908101928215614daf5791602002820182811115614daf578251825591602001919060010190614d94565b6040518060800160405280600081526020016000815260200160008152602001600081525090565b5b80821115614dbb5760008155600101614e22565b6001600160a01b0391909116815260200190565b6001600160e01b031981168114610c8057600080fd5b600060208284031215614e7257600080fd5b8135610b0481614e4a565b60005b83811015614e98578181015183820152602001614e80565b83811115613bea5750506000910152565b60008151808452614ec1816020860160208601614e7d565b601f01601f19169290920160200192915050565b602081526000610b046020830184614ea9565b600060208284031215614efa57600080fd5b5035919050565b6001600160a01b0381168114610c8057600080fd5b60008060408385031215614f2957600080fd5b8235614f3481614f01565b946020939093013593505050565b600080600060608486031215614f5757600080fd5b8335614f6281614f01565b92506020840135614f7281614f01565b929592945050506040919091013590565b60008060408385031215614f9657600080fd5b823591506020830135614fa881614f01565b809150509250929050565b60a081016108cc828480518252602081015160208301526040810151604083015260608101516060830152608081015160808301525050565b600060208284031215614ffe57600080fd5b8135610b0481614f01565b634e487b7160e01b600052604160045260246000fd5b604051601f8201601f191681016001600160401b038111828210171561504757615047615009565b604052919050565b600082601f83011261506057600080fd5b81356001600160401b0381111561507957615079615009565b61508c601f8201601f191660200161501f565b8181528460208386010111156150a157600080fd5b816020850160208301376000918101602001919091529392505050565b6000602082840312156150d057600080fd5b81356001600160401b038111156150e657600080fd5b611cb38482850161504f565b80356001600160401b0381168114611dc057600080fd5b6000806040838503121561511c57600080fd5b614f34836150f2565b60006001600160401b0382111561513e5761513e615009565b5060051b60200190565b600082601f83011261515957600080fd5b8135602061516e61516983615125565b61501f565b82815260059290921b8401810191818101908684111561518d57600080fd5b8286015b848110156151a85780358352918301918301615191565b509695505050505050565b6000806000606084860312156151c857600080fd5b83356151d381614f01565b925060208401356001600160401b03808211156151ef57600080fd5b6151fb87838801615148565b9350604086013591508082111561521157600080fd5b5061521e86828701615148565b9150509250925092565b60008060008060008060c0878903121561524157600080fd5b86356001600160401b038082111561525857600080fd5b6152648a838b01615148565b9750602089013591508082111561527a57600080fd5b6152868a838b01615148565b96506040890135915061529882614f01565b9094506060880135906152aa82614f01565b9093506080880135906152bc82614f01565b90925060a088013590808211156152d257600080fd5b506152df89828a0161504f565b9150509295509295509295565b6000806000806080858703121561530257600080fd5b5050823594602084013594506040840135936060013592509050565b600082601f83011261532f57600080fd5b8135602061533f61516983615125565b82815260059290921b8401810191818101908684111561535e57600080fd5b8286015b848110156151a85780356008811061537a5760008081fd5b8352918301918301615362565b600082601f83011261539857600080fd5b813560206153a861516983615125565b82815260059290921b840181019181810190868411156153c757600080fd5b8286015b848110156151a85780356001600160401b038111156153ea5760008081fd5b6153f88986838b010161504f565b8452509183019183016153cb565b6000806000806080858703121561541c57600080fd5b84356001600160401b038082111561543357600080fd5b61543f8883890161531e565b9550602087013591508082111561545557600080fd5b5061546287828801615387565b935050604085013561547381614f01565b9150606085013561548381614f01565b939692955090935050565b8015158114610c8057600080fd5b600080604083850312156154af57600080fd5b82356154ba81614f01565b91506020830135614fa88161548e565b600080600080608085870312156154e057600080fd5b84356154eb81614f01565b935060208501356154fb81614f01565b92506040850135915060608501356001600160401b0381111561551d57600080fd5b6155298782880161504f565b91505092959194509250565b60008060006060848603121561554a57600080fd5b505081359360208301359350604090920135919050565b600080600080600085870361018081121561557b57600080fd5b863561558681614f01565b9550602087013561559681614f01565b945060408701356155a681614f01565b9350610100605f19820112156155bb57600080fd5b506060860191506101608601356001600160401b038111156155dc57600080fd5b6155e88882890161504f565b9150509295509295909350565b60008060008060008060c0878903121561560e57600080fd5b86356001600160401b038082111561562557600080fd5b6156318a838b0161531e565b9750602089013591508082111561564757600080fd5b6152868a838b01615387565b6000806040838503121561566657600080fd5b823561567181614f01565b91506020830135614fa881614f01565b60ff81168114610c8057600080fd5b600080600080600080600060e0888a0312156156ab57600080fd5b87356156b681614f01565b965060208801356156c681614f01565b955060408801356156d68161548e565b94506060880135935060808801356156ed81615681565b9699959850939692959460a0840135945060c09093013592915050565b6000806000806080858703121561572057600080fd5b84356001600160401b038082111561573757600080fd5b61574388838901615148565b9550602087013591508082111561575957600080fd5b5061546287828801615148565b600181811c9082168061577a57607f821691505b6020821081141561474757634e487b7160e01b600052602260045260246000fd5b6000602082840312156157ad57600080fd5b5051919050565b634e487b7160e01b600052601160045260246000fd5b60008160001904831182151516156157e4576157e46157b4565b500290565b634e487b7160e01b600052601260045260246000fd5b60008261580e5761580e6157e9565b500490565b60006020828403121561582557600080fd5b8151610b048161548e565b600082821015615842576158426157b4565b500390565b60006001600160401b03828116848216808303821115615869576158696157b4565b01949350505050565b60006020828403121561588457600080fd5b8151610b0481614f01565b634e487b7160e01b600052603260045260246000fd5b600081518084526020808501945080840160005b838110156158d5578151875295820195908201906001016158b9565b509495945050505050565b6040815260006158f360408301856158a5565b82810360208401526120ba81856158a5565b6020808252601f908201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c00604082015260600190565b602081526000610b0460208301846158a5565b60008219821115615962576159626157b4565b500190565b928352602083019190915260ff16604082015260600190565b6000600019821415615994576159946157b4565b5060010190565b600181815b808511156159d65781600019048211156159bc576159bc6157b4565b808516156159c957918102915b93841c93908002906159a0565b509250929050565b6000826159ed575060016108cc565b816159fa575060006108cc565b8160018114615a105760028114615a1a57615a36565b60019150506108cc565b60ff841115615a2b57615a2b6157b4565b50506001821b6108cc565b5060208310610133831016604e8410600b8410161715615a59575081810a6108cc565b615a63838361599b565b8060001904821115615a7757615a776157b4565b029392505050565b6000610b0460ff8416836159de565b600082615a9d57615a9d6157e9565b500690565b60008151615ab4818560208601614e7d565b9290920192915050565b600080845481600182811c915080831680615ada57607f831692505b6020808410821415615afa57634e487b7160e01b86526022600452602486fd5b818015615b0e5760018114615b1f57615b4c565b60ff19861689528489019650615b4c565b60008b81526020902060005b86811015615b445781548b820152908501908301615b2b565b505084890196505b5050505050506120ba8185615aa2565b6000610100808385031215615b7057600080fd5b604051908101906001600160401b0382118183101715615b9257615b92615009565b8160405283358152615ba6602085016150f2565b6020820152615bb7604085016150f2565b6040820152615bc8606085016150f2565b6060820152615bd9608085016150f2565b6080820152615bea60a085016150f2565b60a082015260c08401359150615bff8261548e565b8160c082015260e084013560e0820152809250505092915050565b600060208284031215615c2c57600080fd5b8135610b048161548e565b634e487b7160e01b600052602160045260246000fd5b60008060408385031215615c6057600080fd5b505080516020909101519092909150565b60008060008060008060c08789031215615c8a57600080fd5b8651615c9581614f01565b6020880151604089015160608a015160808b015160a0909b0151939c929b509099909850965090945092505050565b60008060008060808587031215615cda57600080fd5b845193506020850151615cec81614f01565b6040860151606090960151949790965092505050565b9283526001600160a01b03918216602084015216604082015260600190565b6001600160a01b03929092168252602082015260400190565b6001600160a01b038781168252868116602083015285166040820152606081018490526080810183905260c060a0820181905260009061426b90830184614ea9565b828152604060208201526000611cb36040830184614ea9565b600060208284031215615da757600080fd5b8151610b0481614e4a565b600060208284031215615dc457600080fd5b8151610b0481615681565b6e020b733b63290283937ba37b1b7b61608d1b815260008251615df981600f850160208701614e7d565b650815985d5b1d60d21b600f939091019283015250601501919050565b60008251615e28818460208701614e7d565b650b5d985d5b1d60d21b920191825250600601919050565b6001600160a01b0385811682528416602082015260408101839052608060608201819052600090615e7390830184614ea9565b9695505050505050565b60008251615e8f818460208701614e7d565b919091019291505056fe70cf49afe7355562d5b022e594790f22b71ad8cc7eec902fa5feac7c67f71091722cb71fa87c947148cefc06dd890af5802a6a00207c5ddecf1191bf71ce3cd4ddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3efa264697066735822122029352036c6a66a56f3ad49626f0de6724b08985c9d99e8be94a8f63afacfef3464736f6c634300080c0033", + "deployedBytecode": "0x608060405234801561001057600080fd5b50600436106103015760003560e01c8063010db1951461030657806301ffc9a71461032f57806306fdde0314610352578063081812fc14610367578063087a60071461037a578063095ea7b3146103915780630e198f22146103a657806313888565146103af57806323b872dd146103b8578063254cf439146103cb578063307439af146103fd57806334ce998a1461041d57806335836f15146104255780633644e5151461043857806339393ac91461044057806339eb4dc6146104535780633ae2325f146104675780633af32abf1461047a5780633c2e941b1461049a57806342842e0e146104a3578063430c2081146104b65780634f7e43df146104c957806355f804b3146104e35780635c975abb146104f657806361d027b31461050a5780636352211e1461051d57806370a082311461053057806374107543146105435780637aacfffa146105565780637adbf973146105925780637c0f59f4146105a55780637c3a00fd146105bf5780637dc0d1d0146105d25780637e53bd97146105e55780637e56d47c146105f85780637ecebe001461060b578063835986b41461063457806389050f1d1461064757806395d89b41146106595780639a3b6f2f146106615780639f48118f146106a7578063a22cb465146106b2578063af2c8c2e146106c5578063b1511cc9146106ce578063b4bd6f46146106e1578063b88d4fde146106f4578063bbcac55714610707578063bfc7ad2e14610710578063c13cacae14610719578063c4ae31681461072c578063c66d8b0114610734578063c87b56dd1461074e578063d8dfeb4514610761578063d9b1cb5b14610774578063de1f776514610787578063de8fc69814610799578063df011c41146107ac578063e182b883146107bf578063e1c84ea4146107d2578063e626648a146107db578063e985e9c5146107f5578063e9cbd82214610808578063f0f442601461081b578063f51cc7dd1461082e578063fad9aba314610841578063fc29b0211461084a578063fd527cf81461085d575b600080fd5b603754610319906001600160a01b031681565b6040516103269190614e36565b60405180910390f35b61034261033d366004614e60565b610865565b6040519015158152602001610326565b61035a6108d2565b6040516103269190614ed5565b610319610375366004614ee8565b610960565b610383603f5481565b604051908152602001610326565b6103a461039f366004614f16565b610991565b005b610383603e5481565b61038360415481565b6103a46103c6366004614f42565b610a1e565b603c546103e590600160401b90046001600160401b031681565b6040516001600160401b039091168152602001610326565b61041061040b366004614f83565b610a59565b6040516103269190614fb3565b610383610b0b565b610383610433366004614ee8565b610b3d565b610383610b79565b6103a461044e366004614fec565b610b83565b603d5461034290600160c01b900460ff1681565b610383610475366004614ee8565b610c83565b610383610488366004614fec565b60446020526000908152604090205481565b61038360455481565b6103a46104b1366004614f42565b610ca4565b6103426104c4366004614f16565b610cbf565b603d546103e590600160801b90046001600160401b031681565b6103a46104f13660046150be565b610ccb565b603d5461034290600160c81b900460ff1681565b603354610319906001600160a01b031681565b61031961052b366004614ee8565b610d70565b61038361053e366004614fec565b610d7b565b6103a4610551366004615109565b610dc0565b61057d610564366004614ee8565b6043602052600090815260409020805460019091015482565b60408051928352602083019190915201610326565b6103a46105a0366004614fec565b61118c565b603c546103e590600160c01b90046001600160401b031681565b603d546103e5906001600160401b031681565b603654610319906001600160a01b031681565b6103a46105f33660046151b3565b6112d3565b610410610606366004615228565b6114c4565b610383610619366004614fec565b6001600160a01b03166000908152607f602052604090205490565b6103a46106423660046152ec565b611ad8565b610383676765c793fa10079d601a1b81565b61035a611c79565b61067461066f366004615406565b611c86565b60405161032691908151815260208083015190820152604080830151908201526060918201519181019190915260800190565b610383633b9aca0081565b6103a46106c036600461549c565b611cbb565b61038360405481565b6103a46106dc366004614ee8565b611cc6565b6103836106ef366004614fec565b611d8f565b6103a46107023660046154ca565b611dc5565b61038360425481565b61038360b65481565b6103a4610727366004615535565b611e02565b6103a4611ebf565b603d546103e590600160401b90046001600160401b031681565b61035a61075c366004614ee8565b611f6e565b603454610319906001600160a01b031681565b6103a4610782366004615561565b6120c3565b610383676765c793fa10079d601b1b81565b6106746107a73660046155f5565b61222f565b603c546103e5906001600160401b031681565b6103836107cd366004614ee8565b612aad565b61038360395481565b603c546103e590600160801b90046001600160401b031681565b610342610803366004615653565b612abd565b603554610319906001600160a01b031681565b6103a4610829366004614fec565b612aeb565b6103a461083c366004615690565b612b8b565b61038360b45481565b61041061085836600461570a565b612e4a565b61057d612e74565b60006001600160e01b03198216635b5e139f60e01b148061089657506001600160e01b031982166380ac58cd60e01b145b806108b157506001600160e01b0319821663430c208160e01b145b806108cc57506001600160e01b031982166301ffc9a760e01b145b92915050565b607d80546108df90615766565b80601f016020809104026020016040519081016040528092919081815260200182805461090b90615766565b80156109585780601f1061092d57610100808354040283529160200191610958565b820191906000526020600020905b81548152906001019060200180831161093b57829003601f168201915b505050505081565b600061096b82612fa2565b6109885760405163062a39dd60e11b815260040160405180910390fd5b6108cc82612fbf565b600061099c82612fda565b9050806001600160a01b0316836001600160a01b031614156109d1576040516349fa8bc360e11b815260040160405180910390fd5b336001600160a01b038216148015906109f157506109ef8133612abd565b155b15610a0f5760405163c19f17a960e01b815260040160405180910390fd5b610a198383613010565b505050565b3381610a2a828261307e565b610a475760405163c19f17a960e01b815260040160405180910390fd5b610a528585856130fc565b5050505050565b610a61614d0c565b60008381526043602090815260409182902082518084018452815481526001909101548183015260365483516315f789a960e21b81529351610b0494929387936001600160a01b03909316926357de26a492600480830193928290030181865afa158015610ad3573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610af7919061579b565b610aff6131d3565b613368565b9392505050565b6000676765c793fa10079d601b1b610b216131d3565b604054610b2e91906157ca565b610b3891906157ff565b905090565b6000676765c793fa10079d601b1b610b536131d3565b600084815260436020526040902060010154610b6f91906157ca565b6108cc91906157ff565b6000610b386136d1565b603354604051631c86b03760e31b81526001600160a01b039091169063e43581b890610bb3903390600401614e36565b602060405180830381865afa158015610bd0573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610bf49190615813565b610c1157604051633b8d9d7560e21b815260040160405180910390fd5b6001600160a01b03811615610c60576001600160a01b038116600090815260446020526040902054610c44906001615830565b6001600160a01b03821660009081526044602052604090205550565b603d805460ff60c01b198116600160c01b9182900460ff16159091021790555b50565b603b8181548110610c9357600080fd5b600091825260209091200154905081565b610a1983838360405180602001604052806000815250611dc5565b6000610b04838361307e565b60335460405163521d4de960e01b81526001600160a01b039091169063521d4de990610cfb903390600401614e36565b602060405180830381865afa158015610d18573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610d3c9190615813565b610d5957604051632678482f60e21b815260040160405180910390fd5b8051610d6c906046906020840190614d3b565b5050565b60006108cc82612fda565b60006001600160a01b038216610da45760405163d92e233d60e01b815260040160405180910390fd5b506001600160a01b031660009081526048602052604090205490565b60335460405163521d4de960e01b81526001600160a01b039091169063521d4de990610df0903390600401614e36565b602060405180830381865afa158015610e0d573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610e319190615813565b610e4e57604051632678482f60e21b815260040160405180910390fd5b806121a360f11b1415610eb257603d546001600160401b03600160401b90910481169083161115610e9257604051637650e96360e11b815260040160405180910390fd5b603c80546001600160401b0319166001600160401b038416179055611145565b80622a242360e91b1415610f1757633b9aca00826001600160401b03161015610eee5760405163da6a17b960e01b815260040160405180910390fd5b603c8054600160401b600160801b031916600160401b6001600160401b03851602179055611145565b8061212360f11b1415610f7b57633b9aca00826001600160401b03161115610f5257604051637650e96360e11b815260040160405180910390fd5b603c8054600160801b600160c01b031916600160801b6001600160401b03851602179055611145565b8061292360f11b1415610ff857603d54633b9aca0090610fab90600160401b90046001600160401b031684615847565b6001600160401b03161115610fd357604051637650e96360e11b815260040160405180910390fd5b603c80546001600160c01b0316600160c01b6001600160401b03851602179055611145565b806124a960f11b141561102e5761100d61373d565b50603d80546001600160401b0319166001600160401b038416179055611145565b80614c5360f01b14156110c757603c546001600160401b03808416911611806110805750603c54633b9aca009061107590600160c01b90046001600160401b031684615847565b6001600160401b0316115b1561109e5760405163180d062b60e31b815260040160405180910390fd5b603d8054600160401b600160801b031916600160401b6001600160401b03851602179055611145565b806213531160ea1b141561112c57633b9aca00826001600160401b0316111561110357604051637650e96360e11b815260040160405180910390fd5b603d8054600160801b600160c01b031916600160801b6001600160401b03851602179055611145565b60405163e1daa9cf60e01b815260040160405180910390fd5b604080516001600160401b0384168152602081018390527f13b367dac93b85d1ed9b3d8961d8b48e1a677c9800bb1613b4b0416b2d5b61d091015b60405180910390a15050565b603354604051631c86b03760e31b81526001600160a01b039091169063e43581b8906111bc903390600401614e36565b602060405180830381865afa1580156111d9573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906111fd9190615813565b61121a57604051633b8d9d7560e21b815260040160405180910390fd5b603354604080516361d027b360e01b815290516001600160a01b03928316928416916361d027b39160048083019260209291908290030181865afa158015611266573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061128a9190615872565b6001600160a01b0316146112b1576040516302979eb960e31b815260040160405180910390fd5b603680546001600160a01b0319166001600160a01b0392909216919091179055565b60335460405163521d4de960e01b81526001600160a01b039091169063521d4de990611303903390600401614e36565b602060405180830381865afa158015611320573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906113449190615813565b61136157604051632678482f60e21b815260040160405180910390fd5b8051825114158061138c5750806000815181106113805761138061588f565b60200260200101516000145b8061141b57506001600160a01b0383161580159061141b5750816000815181106113b8576113b861588f565b6020026020010151826001815181106113d3576113d361588f565b602002602001015111158061141b5750806000815181106113f6576113f661588f565b6020026020010151816001815181106114115761141161588f565b6020026020010151105b1561143957604051631746545d60e11b815260040160405180910390fd5b603780546001600160a01b0319166001600160a01b038516179055815161146790603a906020850190614dbf565b50805161147b90603b906020840190614dbf565b50826001600160a01b03167feb74d4d9fea592587c926aeb35eb6a7893fb28db0c1c8eb2eb3c586e7164b76c83836040516114b79291906158e0565b60405180910390a2505050565b6114cc614d0c565b6114d46137de565b156114f2576040516313d0ff5960e31b815260040160405180910390fd5b6002600154141561151e5760405162461bcd60e51b815260040161151590615905565b60405180910390fd5b6002600155603d54600160c01b900460ff16801561154c575033600090815260446020526040902054600114155b801561157157506001600160a01b038416600090815260446020526040902054600114155b1561158f57604051630b094f2760e31b815260040160405180910390fd5b865186518114158061159f575080155b156115bd576040516346282e8d60e01b815260040160405180910390fd5b603660009054906101000a90046001600160a01b03166001600160a01b03166357de26a46040518163ffffffff1660e01b8152600401602060405180830381865afa158015611610573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611634919061579b565b606083015261164161373d565b60808301526040517f965a177723c641ee49150b583a0b9ad4730bb20d3474e00ae5a65e777c00d67b90611676908a9061593c565b60405180910390a160005b81811015611a48576000604360008b84815181106116a1576116a161588f565b6020026020010151815260200190815260200160002060405180604001604052908160008201548152602001600182015481525050905060006116ee823387606001518860800151613368565b90508060400151600014158015611722575080604001518a84815181106117175761171761588f565b602002602001015110155b80611749575080600001518a848151811061173f5761173f61588f565b6020026020010151115b156117725780600001518a84815181106117655761176561588f565b6020026020010181815250505b60008560600151826060015161178891906157ca565b603854633b9aca008d87815181106117a2576117a261588f565b60200260200101516117b491906157ca565b6117be91906157ca565b6117c891906157ff565b90506117f68c85815181106117df576117df61588f565b60200260200101518285600001511115610c805750565b8251811061192c57508151602083015160408054600090611818908490615830565b92505081905550604360008d86815181106118355761183561588f565b60209081029190910181015182528101919091526040016000908120818155600101819055603d548c51633b9aca0091600160401b90046001600160401b0316908e90889081106118885761188861588f565b602002602001015161189a91906157ca565b6118a491906157ff565b9050826080015181106118b85760006118c8565b8083608001516118c89190615830565b876040018181516118d9919061594f565b905250508b51600080516020615e9a833981519152908d90869081106119015761190161588f565b60200260200101518460200151600060405161191f93929190615967565b60405180910390a16119ed565b80604360008e87815181106119435761194361588f565b60200260200101518152602001908152602001600020600001600082825461196b9190615830565b925050819055506119eb8c85815181106119875761198761588f565b6020026020010151633b9aca00603d60089054906101000a90046001600160401b03166001600160401b03168e88815181106119c5576119c561588f565b60200260200101516119d791906157ca565b6119e191906157ff565b88608001516137ee565b505b80866020018181516119ff919061594f565b9052508a518b9085908110611a1657611a1661588f565b602002602001015186600001818151611a2f919061594f565b905250611a4192508391506159809050565b9050611681565b50603d54633b9aca0090611a6c90600160401b90046001600160401b031682615830565b8351611a7891906157ca565b611a8291906157ff565b60416000828254611a93919061594f565b9091555050604082015160428054600090611aaf90849061594f565b909155505060208201518251611ac991908888888861391d565b50600180559695505050505050565b611ae06137de565b15611afe576040516313d0ff5960e31b815260040160405180910390fd5b6033546040516333b52a9f60e11b81526001600160a01b039091169063676a553e90611b2e903390600401614e36565b602060405180830381865afa158015611b4b573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611b6f9190615813565b611b8c5760405163027f480760e01b815260040160405180910390fd5b600080611b97613a27565b6001600160401b0316905082811115611bb757611bb48382615830565b91505b50603c54600090600160801b90046001600160401b0316841115611bf557603c54611bf290600160801b90046001600160401b031685615830565b90505b6000611c066002633b9aca00615a7f565b611c1483633b9aca00615830565b611c2285633b9aca00615830565b611c2c90896157ca565b611c3691906157ca565b611c4091906157ff565b9050611c4c8187615830565b60416000828254611c5d919061594f565b90915550611c6f9050878260006137ee565b5050505050505050565b607e80546108df90615766565b611c8e614df9565b60408051600080825260208201909252611cb09187918791879187919061222f565b90505b949350505050565b610d6c338383613a3d565b60335460405163521d4de960e01b81526001600160a01b039091169063521d4de990611cf6903390600401614e36565b602060405180830381865afa158015611d13573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611d379190615813565b611d5457604051632678482f60e21b815260040160405180910390fd5b60398190556040518181527fdd63b3dcdbebad734892f7c7a26d0f647fbc7eec973e0775f5229018ac4ab47a9060200160405180910390a150565b6000611d996137de565b15611db7576040516313d0ff5960e31b815260040160405180910390fd5b6108cc82613af3565b919050565b3382611dd1828261307e565b611dee5760405163c19f17a960e01b815260040160405180910390fd5b611dfa86868686613bb6565b505050505050565b603354604051631c86b03760e31b81526001600160a01b039091169063e43581b890611e32903390600401614e36565b602060405180830381865afa158015611e4f573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611e739190615813565b611e9057604051633b8d9d7560e21b815260040160405180910390fd5b81831115611eb15760405163180d062b60e31b815260040160405180910390fd5b60b49290925560b65560b555565b60335460405163521d4de960e01b81526001600160a01b039091169063521d4de990611eef903390600401614e36565b602060405180830381865afa158015611f0c573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611f309190615813565b611f4d57604051632678482f60e21b815260040160405180910390fd5b603d805460ff60c81b198116600160c81b9182900460ff1615909102179055565b6060611f7982612fa2565b611f965760405163062a39dd60e11b815260040160405180910390fd5b8160005b8115611fbd57611fa981615980565b9050611fb6600a836157ff565b9150611f9a565b6000816001600160401b03811115611fd757611fd7615009565b6040519080825280601f01601f191660200182016040528015612001576020820181803683370190505b5090505b841561206c57612016600183615830565b9150612023600a86615a8e565b61202e90603061594f565b60f81b8183815181106120435761204361588f565b60200101906001600160f81b031916908160001a905350612065600a866157ff565b9450612005565b6046805461207990615766565b1515905061209657604051806020016040528060008152506120ba565b6046816040516020016120aa929190615abe565b6040516020818303038152906040525b95945050505050565b600054610100900460ff16158080156120e35750600054600160ff909116105b8061210457506120f230612f93565b158015612104575060005460ff166001145b6121675760405162461bcd60e51b815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201526d191e481a5b9a5d1a585b1a5e995960921b6064820152608401611515565b6000805460ff19166001179055801561218a576000805461ff0019166101001790555b6121a586868661219f36889003880188615b5c565b86613bf0565b6121b560e0840160c08501615c1a565b603d805460ff60c81b19921515600160c01b029290921661ffff60c01b1990921691909117600160c81b1790558015611dfa576000805461ff0019169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a1505050505050565b612237614df9565b61223f6137de565b1561225d576040516313d0ff5960e31b815260040160405180910390fd5b600260015414156122805760405162461bcd60e51b815260040161151590615905565b60026001558551875114158061229557508651155b156122b3576040516346282e8d60e01b815260040160405180910390fd5b6000806000806000805b8c518110156128165760008d82815181106122da576122da61588f565b60200260200101519050600060078111156122f7576122f7615c37565b81600781111561230957612309615c37565b141561234a576123448d83815181106123245761232461588f565b602002602001015180602001905181019061233f9190615872565b613af3565b50612805565b600281600781111561235e5761235e615c37565b14156123c4578c82815181106123765761237661588f565b60200260200101518060200190518101906123919190615c4d565b95509250826123a05760455492505b6123aa8386613f79565b84886060018181516123bc919061594f565b905250612805565b60078160078111156123d8576123d8615c37565b14156124b15760008060008f85815181106123f5576123f561588f565b60200260200101518060200190518101906124109190615c71565b60345460405163d505accf60e01b81526001600160a01b038089166004830152306024830152604482018890526064820187905260ff8616608483015260a4820185905260c48201849052969f50939d50939b509497509550929350169063d505accf9060e401600060405180830381600087803b15801561249157600080fd5b505af11580156124a5573d6000803e3d6000fd5b50505050505050612805565b866124c1576124be61373d565b96505b60048160078111156124d5576124d5615c37565b141561259d578c82815181106124ed576124ed61588f565b60200260200101518060200190518101906125089190615c4d565b94509250826125175760455492505b6125228385896137ee565b9350600061252e613a27565b612545906001600160401b0316633b9aca00615830565b612553633b9aca00876157ca565b61255d91906157ff565b90506125698582615830565b6041600082825461257a919061594f565b925050819055508089602001818151612593919061594f565b9052506128059050565b8561261c57603660009054906101000a90046001600160a01b03166001600160a01b03166357de26a46040518163ffffffff1660e01b8152600401602060405180830381865afa1580156125f5573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612619919061579b565b95505b600181600781111561263057612630615c37565b14156126ac578c82815181106126485761264861588f565b6020026020010151806020019051810190612663919061579b565b9250826126705760455492505b61267b838789613fe5565b80965081955050508488604001818151612695919061594f565b9052506020880180518591906123bc90839061594f565b60038160078111156126c0576126c0615c37565b1415612720578c82815181106126d8576126d861588f565b60200260200101518060200190518101906126f39190615c4d565b95509250826127025760455492505b61270e8386888a614102565b84886040018181516123bc919061594f565b600581600781111561273457612734615c37565b1415612796578c828151811061274c5761274c61588f565b60200260200101518060200190518101906127679190615c4d565b94509250826127765760455492505b6127828385888a6141dc565b935083886000018181516123bc919061594f565b60068160078111156127aa576127aa615c37565b1415612805576000808e84815181106127c5576127c561588f565b60200260200101518060200190518101906127e09190615cc4565b985091965092509050846127f45760455494505b612802858383898c8e614277565b50505b5061280f81615980565b90506122bd565b50855160208701511061290d578551602087015160009161283691615830565b9050866060015187604001511061286d576128688760600151886040015161285e9190615830565b828d8d8d8d61391d565b612907565b80156128da57603554604051630d43af8160e21b81526001600160a01b039091169063350ebe04906128a79084908f903390600401615d02565b600060405180830381600087803b1580156128c157600080fd5b505af11580156128d5573d6000803e3d6000fd5b505050505b612907333089604001518a606001516128f39190615830565b6034546001600160a01b03169291906143c7565b50612a99565b6020860151865160009161292091615830565b6035546040516340c10f1960e01b81529192506001600160a01b0316906340c10f1990612953908d908590600401615d21565b600060405180830381600087803b15801561296d57600080fd5b505af1158015612981573d6000803e3d6000fd5b505050508660600151876040015111156129c5576129c08a886060015189604001516129ad9190615830565b6034546001600160a01b03169190614432565b612a97565b6000876040015188606001516129db9190615830565b90508015612a9557885115612a7d57896001600160a01b031663a5d4096b603560009054906101000a90046001600160a01b0316603460009054906101000a90046001600160a01b03163385878f6040518763ffffffff1660e01b8152600401612a4a96959493929190615d3a565b600060405180830381600087803b158015612a6457600080fd5b505af1158015612a78573d6000803e3d6000fd5b505050505b603454612a95906001600160a01b03163330846143c7565b505b505b505060018055509198975050505050505050565b603a8181548110610c9357600080fd5b6001600160a01b039182166000908152604a6020908152604080832093909416825291909152205460011490565b6033546001600160a01b03163314612b165760405163b90cdbb160e01b815260040160405180910390fd5b603380546001600160a01b0319166001600160a01b0383811691909117909155603654604051630787a21360e51b815291169063f0f4426090612b5d908490600401614e36565b600060405180830381600087803b158015612b7757600080fd5b505af1158015610a52573d6000803e3d6000fd5b83421115612bac5760405163f87d927160e01b815260040160405180910390fd5b6fa2a8918ca85bafe22016d0b997e4df60600160ff1b03811180612be357508260ff16601b14158015612be357508260ff16601c14155b15612c0157604051638baa579f60e01b815260040160405180910390fd5b6000612c0b6136d1565b608254898989612c1a8d614451565b6040805160208101969096526001600160a01b03948516908601529290911660608401521515608083015260a082015260c0810187905260e00160405160208183030381529060405280519060200120604051602001612c9192919061190160f01b81526002810192909252602282015260420190565b604051602081830303815290604052805190602001209050612cbb886001600160a01b0316612f93565b15612d9757604080516020810185905280820184905260f886901b6001600160f81b0319166060820152815160418183030181526061820192839052630b135d3f60e11b9092526001600160a01b038a1691631626ba7e91612d21918591606501615d7c565b602060405180830381865afa158015612d3e573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612d629190615d95565b6001600160e01b031916631626ba7e60e01b14612d9257604051638baa579f60e01b815260040160405180910390fd5b612e3f565b6040805160008082526020820180845284905260ff871692820192909252606081018590526080810184905260019060a0016020604051602081039080840390855afa158015612deb573d6000803e3d6000fd5b505050602060405103519050886001600160a01b0316816001600160a01b0316141580612e1f57506001600160a01b038116155b15612e3d57604051638baa579f60e01b815260040160405180910390fd5b505b611c6f888888613a3d565b612e52614d0c565b60408051600080825260208201909252611cb0918791879187918791906114c4565b60335460009081906001600160a01b03163314612ea45760405163b90cdbb160e01b815260040160405180910390fd5b612eac61373d565b505060418054604280546000938490559290559150808210612f4557612ed28183615830565b6035546033546040516340c10f1960e01b8152929450600093506001600160a01b03918216926340c10f1992612f0e9216908690600401615d21565b600060405180830381600087803b158015612f2857600080fd5b505af1158015612f3c573d6000803e3d6000fd5b50505050612f56565b612f4f8282615830565b9050600091505b60408051838152602081018390527ffeb12225c131aab793a00c5239afb778932d170fa28ce6e9d23703e4bd892121910160405180910390a19091565b6001600160a01b03163b151590565b6000908152604760205260409020546001600160a01b0316151590565b6000908152604960205260409020546001600160a01b031690565b6000818152604760205260409020546001600160a01b031680611dc05760405163062a39dd60e11b815260040160405180910390fd5b600081815260496020526040902080546001600160a01b0319166001600160a01b038416908117909155819061304582612fda565b6001600160a01b03167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92560405160405180910390a45050565b60008061308a83612fda565b9050806001600160a01b0316846001600160a01b031614806130c55750836001600160a01b03166130ba84612fbf565b6001600160a01b0316145b80611cb357506001600160a01b038082166000908152604a6020908152604080832093881683529290522054600114949350505050565b826001600160a01b031661310f82612fda565b6001600160a01b0316146131365760405163c19f17a960e01b815260040160405180910390fd5b6001600160a01b03821661315d5760405163d92e233d60e01b815260040160405180910390fd5b613168600082613010565b6001600160a01b038084166000818152604860209081526040808320805460001901905593861680835284832080546001019055858352604790915283822080546001600160a01b03191682179055925184939291600080516020615eda83398151915291a4505050565b600080603e54426131e49190615830565b603d549091506001600160401b03168115806131fe575080155b1561320d57603f549250505090565b600061321a600184615830565b905060006002841161322d576000613238565b613238600285615830565b90506000676765c793fa10079d601b1b676765c793fa10079d601a1b61325e86806157ca565b613268919061594f565b61327291906157ff565b90506000676765c793fa10079d601b1b676765c793fa10079d601a1b61329887856157ca565b6132a2919061594f565b6132ac91906157ff565b905060006002836132bd878a6157ca565b6132c791906157ca565b6132d191906157ff565b90506000600683866132e3898c6157ca565b6132ed91906157ca565b6132f791906157ca565b61330191906157ff565b9050676765c793fa10079d601b1b818361331b8b8b6157ca565b61333090676765c793fa10079d601b1b61594f565b61333a919061594f565b613344919061594f565b603f5461335191906157ca565b61335b91906157ff565b9850505050505050505090565b613370614d0c565b6000806000613380888787614495565b925092509250633b9aca0083106133aa576040516315fe9b6160e21b815260040160405180910390fd5b6000633b9aca006133bb8582615830565b6133c48a61451e565b6133ce91906157ca565b6133d891906157ff565b603d54909150600160801b90046001600160401b03168110156134085761340381633b9aca00615830565b613429565b603d5461342990600160801b90046001600160401b0316633b9aca00615830565b603d54909150600160401b90046001600160401b03166000806134516002633b9aca00615a7f565b603c5461346791906001600160401b03166157ca565b83613472868a6157ca565b61347c91906157ca565b1061360157603c546001600160401b031661349c6002633b9aca00615a7f565b6134a691906157ca565b603c5485906134c590600160401b90046001600160401b0316866157ca565b6134cf91906157ca565b6134d99190615830565b603c548590633b9aca00906134f7906001600160401b0316896157ca565b603c54613515908b90600160401b90046001600160401b03166157ca565b61351f9190615830565b61352991906157ca565b61353391906157ca565b61353d91906157ff565b60b654909250613551633b9aca00826157ca565b61355b85856157ca565b613565919061594f565b613573633b9aca00896157ca565b116135fb5761358d676765c793fa10079d601b1b856157ca565b633b9aca008b8f602001516135a291906157ca565b6135ac91906157ca565b6135b691906157ff565b6135c190600161594f565b9250808711156135f65783633b9aca006135db838a615830565b6135e591906157ca565b6135ef91906157ff565b91506135fb565b600191505b5061367f565b60385461361290633b9aca006157ca565b8c518b906136219087906157ca565b61362b91906157ca565b61363591906157ff565b61364090600161594f565b915060b55485111561367b57633b9aca008460b554876136609190615830565b61366a91906157ca565b61367491906157ff565b905061367f565b5060015b81885261368c848b6157ca565b60385461369d633b9aca00856157ca565b6136a791906157ca565b6136b191906157ff565b602089015260408801525050606085015250608083015250949350505050565b60808054608154604080517f8b73c3c69bb8fe3d512ecc4cf759cc79239f7b179b0ffacaa9a75d522b39400f602082015290810192909252606082015246918101919091523060a082015260009060c00160405160208183030381529060405280519060200120905090565b60006137476131d3565b90506000676765c793fa10079d601b1b603f54836137659190615830565b60405461377291906157ca565b61377c91906157ff565b90508060416000828254613790919061594f565b9091555050603f82905542603e8190556040805184815260208101929092527fd1fa8ba00a3bf20274346919dce0de62d2a140af2c71fe7e29fa6472eea3bb9d910160405180910390a15090565b603d54600160c81b900460ff1690565b600081613800576137fd61373d565b91505b60008481526043602052604081206001015490676765c793fa10079d601b1b61382985846157ca565b61383391906157ff565b905080851061384457935080613867565b8361385a676765c793fa10079d601b1b876157ca565b61386491906157ff565b90505b6138718183615830565b915080604060008282546138859190615830565b909155505081158015906138ba5750676765c793fa10079d601b1b60b4546138ad91906157ca565b6138b785846157ca565b11155b156138d85760405163228af07f60e21b815260040160405180910390fd5b60008681526043602052604080822060010184905551600080516020615e9a8339815191529161390b9189918591615967565b60405180910390a15092949350505050565b851561393a5760345461393a906001600160a01b03168488614432565b8415611dfa578051156139b95760345460355460405163a5d4096b60e01b81526001600160a01b038086169363a5d4096b936139869391831692169089908b908d908990600401615d3a565b600060405180830381600087803b1580156139a057600080fd5b505af11580156139b4573d6000803e3d6000fd5b505050505b603554604051630d43af8160e21b81526001600160a01b039091169063350ebe04906139ed90889088903390600401615d02565b600060405180830381600087803b158015613a0757600080fd5b505af1158015613a1b573d6000803e3d6000fd5b50505050505050505050565b603c54600160c01b90046001600160401b031690565b826001600160a01b0316826001600160a01b03161415613a70576040516320c5195360e21b815260040160405180910390fd5b600081613a7e576000613a81565b60015b6001600160a01b038581166000818152604a602090815260408083209489168084529482529182902060ff959095169485905590518615158152939450919290917f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c31910160405180910390a350505050565b60006001600160a01b038216613b1c5760405163d92e233d60e01b815260040160405180910390fd5b5060458054600101908190556001600160a01b038216600081815260486020908152604080832080546001019055848352604790915280822080546001600160a01b031916841790555183929190600080516020615eda833981519152908290a4613b99600083836040518060200160405280600081525061474d565b611dc0576040516320149b4360e21b815260040160405180910390fd5b613bc18484846130fc565b613bcd8484848461474d565b613bea576040516320149b4360e21b815260040160405180910390fd5b50505050565b846001600160a01b0316836001600160a01b03166361d027b36040518163ffffffff1660e01b8152600401602060405180830381865afa158015613c38573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613c5c9190615872565b6001600160a01b031614613c83576040516302979eb960e31b815260040160405180910390fd5b603380546001600160a01b038088166001600160a01b0319928316179092556034805492871692909116821790556040805163313ce56760e01b8152905163313ce567916004808201926020929091908290030181865afa158015613cec573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613d109190615db2565b613d1b90600a615a7f565b603881905550846001600160a01b031663e9cbd8226040518163ffffffff1660e01b8152600401602060405180830381865afa158015613d5f573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613d839190615872565b603580546001600160a01b03199081166001600160a01b039384161790915560368054909116918516919091179055604051600090613dc6908390602001615dcf565b60408051601f198184030181529190528051909150613dec90607d906020840190614d3b565b50613df681614850565b81604051602001613e079190615e16565b604051602081830303815290604052607e9080519060200190613e2b929190614d3b565b50676765c793fa10079d601b1b603f5542603e55608083015160208401516001600160401b0391821691161180613e725750633b9aca0083608001516001600160401b0316115b80613e8d575082604001516001600160401b0316633b9aca00115b80613ea95750633b9aca008360a001516001600160401b031610155b80613eb6575060e0830151155b15613ed457604051631746545d60e11b815260040160405180910390fd5b8251603955602080840151603c80546040808801516001600160401b039485166001600160801b031993841617600160401b9186168202179093556060880151603d805460808b015160a08c0151938816919095161793861690940292909217600160801b600160c01b031916600160801b92909416919091029290921790558051918201905260e08401518152613f7090603b906001614dbf565b50505050505050565b613f8282612fa2565b613f9f5760405163062a39dd60e11b815260040160405180910390fd5b60008281526043602052604081208054839290613fbd90849061594f565b9091555050604051600080516020615eba833981519152906111809084908490600190615967565b6000803385613ff4828261307e565b6140115760405163c19f17a960e01b815260040160405180910390fd5b600087815260436020908152604080832081518083019092528054825260010154918101919091529080614046838a8a614495565b5091509150633b9aca00821161406f57604051631527804d60e31b815260040160405180910390fd5b8260200151604060008282546140859190615830565b9091555061409490508a614926565b600061409e613a27565b6140b5906001600160401b0316633b9aca00615830565b6140c3633b9aca00846157ca565b6140cd91906157ff565b90506140d98282615830565b604160008282546140ea919061594f565b90915550509251929a92995091975050505050505050565b338461410e828261307e565b61412b5760405163c19f17a960e01b815260040160405180910390fd5b60008681526043602052604081208054879290614149908490615830565b909155505060008681526043602090815260408083208151808301909252805482526001015491810191909152614181908686614495565b50509050633b9aca0081116141a957604051631527804d60e31b815260040160405180910390fd5b600080516020615eba833981519152878760006040516141cb93929190615967565b60405180910390a150505050505050565b600033856141ea828261307e565b6142075760405163c19f17a960e01b815260040160405180910390fd5b614213878787876149a5565b603c54909650600090633b9aca009061423d908990600160801b90046001600160401b03166157ca565b61424791906157ff565b9050806041600082825461425b919061594f565b9091555061426b90508188615830565b98975050505050505050565b3386614283828261307e565b6142a05760405163c19f17a960e01b815260040160405180910390fd5b60408051898152602081018890526001600160a01b038916818301526060810187905290517fddd3b70af631334f7552aadb582ed091018e62e103fa8b150ca66cc700d4dac69181900360800190a16142fb888686866149a5565b94506001600160a01b03871630141561431f576143198686856137ee565b50611c6f565b866001600160a01b031663835986b48787603c60109054906101000a90046001600160401b031661434e613a27565b6040516001600160e01b031960e087901b168152600481019490945260248401929092526001600160401b039081166044840152166064820152608401600060405180830381600087803b1580156143a557600080fd5b505af11580156143b9573d6000803e3d6000fd5b505050505050505050505050565b6040516001600160a01b0380851660248301528316604482015260648101829052613bea9085906323b872dd60e01b906084015b60408051601f198184030181529190526020810180516001600160e01b03166001600160e01b031990931692909217909152614b38565b610a198363a9059cbb60e01b84846040516024016143fb929190615d21565b6001600160a01b0381166000908152607f602052604090205461447581600161594f565b6001600160a01b039092166000908152607f602052604090209190915590565b6000806000676765c793fa10079d601b1b8487602001516144b691906157ca565b6144c091906157ff565b91506038548587600001516144d591906157ca565b6144df91906157ff565b9050816144f0576000199250614515565b603c548290614508906001600160401b0316836157ca565b61451291906157ff565b92505b93509350939050565b6037546000906001600160a01b031661455757603b6000815481106145455761454561588f565b90600052602060002001549050919050565b603754604051635dfba04560e11b81526000916001600160a01b03169063bbf7408a90614588908690600401614e36565b602060405180830381865afa1580156145a5573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906145c9919061579b565b9050603a6001815481106145df576145df61588f565b9060005260206000200154811061461757603b6001815481106146045761460461588f565b9060005260206000200154915050919050565b603a60008154811061462b5761462b61588f565b9060005260206000200154811161465057603b6000815481106146045761460461588f565b603a6000815481106146645761466461588f565b9060005260206000200154603a6001815481106146835761468361588f565b90600052602060002001546146989190615830565b603a6000815481106146ac576146ac61588f565b9060005260206000200154826146c29190615830565b603b6000815481106146d6576146d661588f565b9060005260206000200154603b6001815481106146f5576146f561588f565b906000526020600020015461470a9190615830565b61471491906157ca565b61471e91906157ff565b603b6000815481106147325761473261588f565b9060005260206000200154610b04919061594f565b50919050565b6000614761846001600160a01b0316612f93565b1561484857604051630a85bd0160e11b81526001600160a01b0385169063150b7a0290614798903390899088908890600401615e40565b6020604051808303816000875af19250505080156147d3575060408051601f3d908101601f191682019092526147d091810190615d95565b60015b61482e573d808015614801576040519150601f19603f3d011682016040523d82523d6000602084013e614806565b606091505b508051614826576040516320149b4360e21b815260040160405180910390fd5b805181602001fd5b6001600160e01b031916630a85bd0160e11b149050611cb3565b506001611cb3565b600054610100900460ff166148bb5760405162461bcd60e51b815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201526a6e697469616c697a696e6760a81b6064820152608401611515565b7f3f43a9c6bafb5c7aab4e0cfe239dc5d4c15caf0381c6104188191f78a6640bd860825580516020918201206080556040805180820190915260018152603160f81b9101527fc89efdaa54c0f20c7adf612882df0950f5a951637e0307cdcb4c672f298b8bc6608155565b600061493182612fda565b905061493e600083613010565b6001600160a01b038116600081815260486020908152604080832080546000190190558583526047825280832080546001600160a01b0319169055604390915280822082815560010182905551849290600080516020615eda833981519152908390a45050565b600080826149be676765c793fa10079d601b1b876157ca565b6149c891906157ff565b600087815260436020526040902060010154909150614a035760b4548511614a035760405163228af07f60e21b815260040160405180910390fd5b60008681526043602052604081206001018054839290614a2490849061594f565b925050819055508060406000828254614a3d919061594f565b9091555050603954614a5b90676765c793fa10079d601b1b906157ca565b83604054614a6991906157ca565b1115614a88576040516371239a6160e11b815260040160405180910390fd5b60008681526043602090815260408083208151808301909252805482526001015491810191909152614abb908686614495565b50509050633b9aca008111614ae357604051631527804d60e31b815260040160405180910390fd5b600080516020615e9a83398151915287836001604051614b0593929190615967565b60405180910390a1676765c793fa10079d601b1b614b2385846157ca565b614b2d91906157ff565b979650505050505050565b6000614b8d826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564815250856001600160a01b0316614c0a9092919063ffffffff16565b805190915015610a195780806020019051810190614bab9190615813565b610a195760405162461bcd60e51b815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e6044820152691bdd081cdd58d8d9595960b21b6064820152608401611515565b6060611cb3848460008585614c1e85612f93565b614c6a5760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006044820152606401611515565b600080866001600160a01b03168587604051614c869190615e7d565b60006040518083038185875af1925050503d8060008114614cc3576040519150601f19603f3d011682016040523d82523d6000602084013e614cc8565b606091505b5091509150614b2d82828660608315614ce2575081610b04565b825115614cf25782518084602001fd5b8160405162461bcd60e51b81526004016115159190614ed5565b6040518060a0016040528060008152602001600081526020016000815260200160008152602001600081525090565b828054614d4790615766565b90600052602060002090601f016020900481019282614d695760008555614daf565b82601f10614d8257805160ff1916838001178555614daf565b82800160010185558215614daf579182015b82811115614daf578251825591602001919060010190614d94565b50614dbb929150614e21565b5090565b828054828255906000526020600020908101928215614daf5791602002820182811115614daf578251825591602001919060010190614d94565b6040518060800160405280600081526020016000815260200160008152602001600081525090565b5b80821115614dbb5760008155600101614e22565b6001600160a01b0391909116815260200190565b6001600160e01b031981168114610c8057600080fd5b600060208284031215614e7257600080fd5b8135610b0481614e4a565b60005b83811015614e98578181015183820152602001614e80565b83811115613bea5750506000910152565b60008151808452614ec1816020860160208601614e7d565b601f01601f19169290920160200192915050565b602081526000610b046020830184614ea9565b600060208284031215614efa57600080fd5b5035919050565b6001600160a01b0381168114610c8057600080fd5b60008060408385031215614f2957600080fd5b8235614f3481614f01565b946020939093013593505050565b600080600060608486031215614f5757600080fd5b8335614f6281614f01565b92506020840135614f7281614f01565b929592945050506040919091013590565b60008060408385031215614f9657600080fd5b823591506020830135614fa881614f01565b809150509250929050565b60a081016108cc828480518252602081015160208301526040810151604083015260608101516060830152608081015160808301525050565b600060208284031215614ffe57600080fd5b8135610b0481614f01565b634e487b7160e01b600052604160045260246000fd5b604051601f8201601f191681016001600160401b038111828210171561504757615047615009565b604052919050565b600082601f83011261506057600080fd5b81356001600160401b0381111561507957615079615009565b61508c601f8201601f191660200161501f565b8181528460208386010111156150a157600080fd5b816020850160208301376000918101602001919091529392505050565b6000602082840312156150d057600080fd5b81356001600160401b038111156150e657600080fd5b611cb38482850161504f565b80356001600160401b0381168114611dc057600080fd5b6000806040838503121561511c57600080fd5b614f34836150f2565b60006001600160401b0382111561513e5761513e615009565b5060051b60200190565b600082601f83011261515957600080fd5b8135602061516e61516983615125565b61501f565b82815260059290921b8401810191818101908684111561518d57600080fd5b8286015b848110156151a85780358352918301918301615191565b509695505050505050565b6000806000606084860312156151c857600080fd5b83356151d381614f01565b925060208401356001600160401b03808211156151ef57600080fd5b6151fb87838801615148565b9350604086013591508082111561521157600080fd5b5061521e86828701615148565b9150509250925092565b60008060008060008060c0878903121561524157600080fd5b86356001600160401b038082111561525857600080fd5b6152648a838b01615148565b9750602089013591508082111561527a57600080fd5b6152868a838b01615148565b96506040890135915061529882614f01565b9094506060880135906152aa82614f01565b9093506080880135906152bc82614f01565b90925060a088013590808211156152d257600080fd5b506152df89828a0161504f565b9150509295509295509295565b6000806000806080858703121561530257600080fd5b5050823594602084013594506040840135936060013592509050565b600082601f83011261532f57600080fd5b8135602061533f61516983615125565b82815260059290921b8401810191818101908684111561535e57600080fd5b8286015b848110156151a85780356008811061537a5760008081fd5b8352918301918301615362565b600082601f83011261539857600080fd5b813560206153a861516983615125565b82815260059290921b840181019181810190868411156153c757600080fd5b8286015b848110156151a85780356001600160401b038111156153ea5760008081fd5b6153f88986838b010161504f565b8452509183019183016153cb565b6000806000806080858703121561541c57600080fd5b84356001600160401b038082111561543357600080fd5b61543f8883890161531e565b9550602087013591508082111561545557600080fd5b5061546287828801615387565b935050604085013561547381614f01565b9150606085013561548381614f01565b939692955090935050565b8015158114610c8057600080fd5b600080604083850312156154af57600080fd5b82356154ba81614f01565b91506020830135614fa88161548e565b600080600080608085870312156154e057600080fd5b84356154eb81614f01565b935060208501356154fb81614f01565b92506040850135915060608501356001600160401b0381111561551d57600080fd5b6155298782880161504f565b91505092959194509250565b60008060006060848603121561554a57600080fd5b505081359360208301359350604090920135919050565b600080600080600085870361018081121561557b57600080fd5b863561558681614f01565b9550602087013561559681614f01565b945060408701356155a681614f01565b9350610100605f19820112156155bb57600080fd5b506060860191506101608601356001600160401b038111156155dc57600080fd5b6155e88882890161504f565b9150509295509295909350565b60008060008060008060c0878903121561560e57600080fd5b86356001600160401b038082111561562557600080fd5b6156318a838b0161531e565b9750602089013591508082111561564757600080fd5b6152868a838b01615387565b6000806040838503121561566657600080fd5b823561567181614f01565b91506020830135614fa881614f01565b60ff81168114610c8057600080fd5b600080600080600080600060e0888a0312156156ab57600080fd5b87356156b681614f01565b965060208801356156c681614f01565b955060408801356156d68161548e565b94506060880135935060808801356156ed81615681565b9699959850939692959460a0840135945060c09093013592915050565b6000806000806080858703121561572057600080fd5b84356001600160401b038082111561573757600080fd5b61574388838901615148565b9550602087013591508082111561575957600080fd5b5061546287828801615148565b600181811c9082168061577a57607f821691505b6020821081141561474757634e487b7160e01b600052602260045260246000fd5b6000602082840312156157ad57600080fd5b5051919050565b634e487b7160e01b600052601160045260246000fd5b60008160001904831182151516156157e4576157e46157b4565b500290565b634e487b7160e01b600052601260045260246000fd5b60008261580e5761580e6157e9565b500490565b60006020828403121561582557600080fd5b8151610b048161548e565b600082821015615842576158426157b4565b500390565b60006001600160401b03828116848216808303821115615869576158696157b4565b01949350505050565b60006020828403121561588457600080fd5b8151610b0481614f01565b634e487b7160e01b600052603260045260246000fd5b600081518084526020808501945080840160005b838110156158d5578151875295820195908201906001016158b9565b509495945050505050565b6040815260006158f360408301856158a5565b82810360208401526120ba81856158a5565b6020808252601f908201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c00604082015260600190565b602081526000610b0460208301846158a5565b60008219821115615962576159626157b4565b500190565b928352602083019190915260ff16604082015260600190565b6000600019821415615994576159946157b4565b5060010190565b600181815b808511156159d65781600019048211156159bc576159bc6157b4565b808516156159c957918102915b93841c93908002906159a0565b509250929050565b6000826159ed575060016108cc565b816159fa575060006108cc565b8160018114615a105760028114615a1a57615a36565b60019150506108cc565b60ff841115615a2b57615a2b6157b4565b50506001821b6108cc565b5060208310610133831016604e8410600b8410161715615a59575081810a6108cc565b615a63838361599b565b8060001904821115615a7757615a776157b4565b029392505050565b6000610b0460ff8416836159de565b600082615a9d57615a9d6157e9565b500690565b60008151615ab4818560208601614e7d565b9290920192915050565b600080845481600182811c915080831680615ada57607f831692505b6020808410821415615afa57634e487b7160e01b86526022600452602486fd5b818015615b0e5760018114615b1f57615b4c565b60ff19861689528489019650615b4c565b60008b81526020902060005b86811015615b445781548b820152908501908301615b2b565b505084890196505b5050505050506120ba8185615aa2565b6000610100808385031215615b7057600080fd5b604051908101906001600160401b0382118183101715615b9257615b92615009565b8160405283358152615ba6602085016150f2565b6020820152615bb7604085016150f2565b6040820152615bc8606085016150f2565b6060820152615bd9608085016150f2565b6080820152615bea60a085016150f2565b60a082015260c08401359150615bff8261548e565b8160c082015260e084013560e0820152809250505092915050565b600060208284031215615c2c57600080fd5b8135610b048161548e565b634e487b7160e01b600052602160045260246000fd5b60008060408385031215615c6057600080fd5b505080516020909101519092909150565b60008060008060008060c08789031215615c8a57600080fd5b8651615c9581614f01565b6020880151604089015160608a015160808b015160a0909b0151939c929b509099909850965090945092505050565b60008060008060808587031215615cda57600080fd5b845193506020850151615cec81614f01565b6040860151606090960151949790965092505050565b9283526001600160a01b03918216602084015216604082015260600190565b6001600160a01b03929092168252602082015260400190565b6001600160a01b038781168252868116602083015285166040820152606081018490526080810183905260c060a0820181905260009061426b90830184614ea9565b828152604060208201526000611cb36040830184614ea9565b600060208284031215615da757600080fd5b8151610b0481614e4a565b600060208284031215615dc457600080fd5b8151610b0481615681565b6e020b733b63290283937ba37b1b7b61608d1b815260008251615df981600f850160208701614e7d565b650815985d5b1d60d21b600f939091019283015250601501919050565b60008251615e28818460208701614e7d565b650b5d985d5b1d60d21b920191825250600601919050565b6001600160a01b0385811682528416602082015260408101839052608060608201819052600090615e7390830184614ea9565b9695505050505050565b60008251615e8f818460208701614e7d565b919091019291505056fe70cf49afe7355562d5b022e594790f22b71ad8cc7eec902fa5feac7c67f71091722cb71fa87c947148cefc06dd890af5802a6a00207c5ddecf1191bf71ce3cd4ddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3efa264697066735822122029352036c6a66a56f3ad49626f0de6724b08985c9d99e8be94a8f63afacfef3464736f6c634300080c0033" +} \ No newline at end of file diff --git a/deployments/mainnet/VaultManager_wstETH_USD.json b/deployments/mainnet/VaultManager_wstETH_USD.json new file mode 100644 index 00000000..79b5a9ec --- /dev/null +++ b/deployments/mainnet/VaultManager_wstETH_USD.json @@ -0,0 +1,247 @@ +{ + "address": "0xca2d7991a2F6Fdf542046E4F1Dc2FD7d59C3DEc1", + "abi": [ + { + "inputs": [ + { + "internalType": "address", + "name": "_logic", + "type": "address" + }, + { + "internalType": "address", + "name": "admin_", + "type": "address" + }, + { + "internalType": "bytes", + "name": "_data", + "type": "bytes" + } + ], + "stateMutability": "payable", + "type": "constructor" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "previousAdmin", + "type": "address" + }, + { + "indexed": false, + "internalType": "address", + "name": "newAdmin", + "type": "address" + } + ], + "name": "AdminChanged", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "beacon", + "type": "address" + } + ], + "name": "BeaconUpgraded", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "implementation", + "type": "address" + } + ], + "name": "Upgraded", + "type": "event" + }, + { + "stateMutability": "payable", + "type": "fallback" + }, + { + "inputs": [], + "name": "admin", + "outputs": [ + { + "internalType": "address", + "name": "admin_", + "type": "address" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "newAdmin", + "type": "address" + } + ], + "name": "changeAdmin", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "implementation", + "outputs": [ + { + "internalType": "address", + "name": "implementation_", + "type": "address" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "newImplementation", + "type": "address" + } + ], + "name": "upgradeTo", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "newImplementation", + "type": "address" + }, + { + "internalType": "bytes", + "name": "data", + "type": "bytes" + } + ], + "name": "upgradeToAndCall", + "outputs": [], + "stateMutability": "payable", + "type": "function" + }, + { + "stateMutability": "payable", + "type": "receive" + } + ], + "transactionHash": "0x0f67f467194c4310f3c6bf9a571af646cdcea6829864440b8ad5fca7649d56a9", + "receipt": { + "to": null, + "from": "0xfdA462548Ce04282f4B6D6619823a7C64Fdc0185", + "contractAddress": "0xca2d7991a2F6Fdf542046E4F1Dc2FD7d59C3DEc1", + "transactionIndex": 82, + "gasUsed": "1123128", + "logsBloom": "0x00000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000400000000002000000000000100000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000100000000000000000000080001000000000800000000000000000000000000000000400000000000000000000000000000200000000000020000000000000000000040000000000000400000000000000000000000000000000000000000000000000000000000000000000000000000000010000", + "blockHash": "0x604f4f41b3062f0a812abfdec7492748ffacf76ea9871af9ea1c9da4023d408c", + "transactionHash": "0x0f67f467194c4310f3c6bf9a571af646cdcea6829864440b8ad5fca7649d56a9", + "logs": [ + { + "transactionIndex": 82, + "blockNumber": 18975615, + "transactionHash": "0x0f67f467194c4310f3c6bf9a571af646cdcea6829864440b8ad5fca7649d56a9", + "address": "0xca2d7991a2F6Fdf542046E4F1Dc2FD7d59C3DEc1", + "topics": [ + "0xbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b", + "0x000000000000000000000000ae4d5a4308db411f70b572f0d5ace4e41e3346a7" + ], + "data": "0x", + "logIndex": 107, + "blockHash": "0x604f4f41b3062f0a812abfdec7492748ffacf76ea9871af9ea1c9da4023d408c" + }, + { + "transactionIndex": 82, + "blockNumber": 18975615, + "transactionHash": "0x0f67f467194c4310f3c6bf9a571af646cdcea6829864440b8ad5fca7649d56a9", + "address": "0xca2d7991a2F6Fdf542046E4F1Dc2FD7d59C3DEc1", + "topics": [ + "0x7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb3847402498" + ], + "data": "0x0000000000000000000000000000000000000000000000000000000000000001", + "logIndex": 108, + "blockHash": "0x604f4f41b3062f0a812abfdec7492748ffacf76ea9871af9ea1c9da4023d408c" + }, + { + "transactionIndex": 82, + "blockNumber": 18975615, + "transactionHash": "0x0f67f467194c4310f3c6bf9a571af646cdcea6829864440b8ad5fca7649d56a9", + "address": "0xca2d7991a2F6Fdf542046E4F1Dc2FD7d59C3DEc1", + "topics": [ + "0x7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f" + ], + "data": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000001d941ef0d3bba4ad67dbfbcee5262f4cee53a32b", + "logIndex": 109, + "blockHash": "0x604f4f41b3062f0a812abfdec7492748ffacf76ea9871af9ea1c9da4023d408c" + } + ], + "blockNumber": 18975615, + "cumulativeGasUsed": "6408066", + "status": 1, + "byzantium": true + }, + "args": [ + "0xAe4D5A4308DB411f70B572f0D5ace4e41E3346A7", + "0x1D941EF0D3Bba4ad67DBfBCeE5262F4CEE53A32b", + "0xd9b1cb5b000000000000000000000000f8588520e760bb0b3bdd62ecb25186a28b0830ee0000000000000000000000007f39c581f595b53c5cb19bd0b3f8da6c935e2ca0000000000000000000000000cf1ae61e2f65149355d8a340c47b592e1bce656800000000000000000000000000000000000000000000003635c9adc5dea00000000000000000000000000000000000000000000000000000000000002cb41780000000000000000000000000000000000000000000000000000000003e95ba8000000000000000000000000000000000000000000000000015787ee2686ca800000000000000000000000000000000000000000000000000000000003a699d000000000000000000000000000000000000000000000000000000000005f5e10000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000059682f000000000000000000000000000000000000000000000000000000000000000180000000000000000000000000000000000000000000000000000000000000000a7773744554482d55534400000000000000000000000000000000000000000000" + ], + "numDeployments": 1, + "solcInputHash": "871924e0c138825a2736b76def8fef8d", + "metadata": "{\"compiler\":{\"version\":\"0.8.17+commit.8df45f5f\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_logic\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"admin_\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"_data\",\"type\":\"bytes\"}],\"stateMutability\":\"payable\",\"type\":\"constructor\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"previousAdmin\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"newAdmin\",\"type\":\"address\"}],\"name\":\"AdminChanged\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"beacon\",\"type\":\"address\"}],\"name\":\"BeaconUpgraded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"implementation\",\"type\":\"address\"}],\"name\":\"Upgraded\",\"type\":\"event\"},{\"stateMutability\":\"payable\",\"type\":\"fallback\"},{\"inputs\":[],\"name\":\"admin\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"admin_\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newAdmin\",\"type\":\"address\"}],\"name\":\"changeAdmin\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"implementation\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"implementation_\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newImplementation\",\"type\":\"address\"}],\"name\":\"upgradeTo\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newImplementation\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"}],\"name\":\"upgradeToAndCall\",\"outputs\":[],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"stateMutability\":\"payable\",\"type\":\"receive\"}],\"devdoc\":{\"details\":\"This contract implements a proxy that is upgradeable by an admin. It is fully forked from OpenZeppelin `TransparentUpgradeableProxy` To avoid https://medium.com/nomic-labs-blog/malicious-backdoors-in-ethereum-proxies-62629adf3357[proxy selector clashing], which can potentially be used in an attack, this contract uses the https://blog.openzeppelin.com/the-transparent-proxy-pattern/[transparent proxy pattern]. This pattern implies two things that go hand in hand: 1. If any account other than the admin calls the proxy, the call will be forwarded to the implementation, even if that call matches one of the admin functions exposed by the proxy itself. 2. If the admin calls the proxy, it can access the admin functions, but its calls will never be forwarded to the implementation. If the admin tries to call a function on the implementation it will fail with an error that says \\\"admin cannot fallback to proxy target\\\". These properties mean that the admin account can only be used for admin actions like upgrading the proxy or changing the admin, so it's best if it's a dedicated account that is not used for anything else. This will avoid headaches due to sudden errors when trying to call a function from the proxy implementation. Our recommendation is for the dedicated account to be an instance of the {ProxyAdmin} contract. If set up this way, you should think of the `ProxyAdmin` instance as the real administrative interface of your proxy.\",\"kind\":\"dev\",\"methods\":{\"admin()\":{\"details\":\"Returns the current admin. NOTE: Only the admin can call this function. See {ProxyAdmin-getProxyAdmin}. TIP: To get this value clients can read directly from the storage slot shown below (specified by EIP1967) using the https://eth.wiki/json-rpc/API#eth_getstorageat[`eth_getStorageAt`] RPC call. `0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103`\"},\"changeAdmin(address)\":{\"details\":\"Changes the admin of the proxy. Emits an {AdminChanged} event. NOTE: Only the admin can call this function. See {ProxyAdmin-changeProxyAdmin}.\"},\"constructor\":{\"details\":\"Initializes an upgradeable proxy managed by `_admin`, backed by the implementation at `_logic`, and optionally initialized with `_data` as explained in {ERC1967Proxy-constructor}.\"},\"implementation()\":{\"details\":\"Returns the current implementation. NOTE: Only the admin can call this function. See {ProxyAdmin-getProxyImplementation}. TIP: To get this value clients can read directly from the storage slot shown below (specified by EIP1967) using the https://eth.wiki/json-rpc/API#eth_getstorageat[`eth_getStorageAt`] RPC call. `0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc`\"},\"upgradeTo(address)\":{\"details\":\"Upgrade the implementation of the proxy. NOTE: Only the admin can call this function. See {ProxyAdmin-upgrade}.\"},\"upgradeToAndCall(address,bytes)\":{\"details\":\"Upgrade the implementation of the proxy, and then call a function from the new implementation as specified by `data`, which should be an encoded function call. This is useful to initialize new storage variables in the proxied contract. NOTE: Only the admin can call this function. See {ProxyAdmin-upgradeAndCall}.\"}},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/external/TransparentUpgradeableProxy.sol\":\"TransparentUpgradeableProxy\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":1000000},\"remappings\":[]},\"sources\":{\"@openzeppelin/contracts/interfaces/draft-IERC1822.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.5.0) (interfaces/draft-IERC1822.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev ERC1822: Universal Upgradeable Proxy Standard (UUPS) documents a method for upgradeability through a simplified\\n * proxy whose upgrades are fully controlled by the current implementation.\\n */\\ninterface IERC1822Proxiable {\\n /**\\n * @dev Returns the storage slot that the proxiable contract assumes is being used to store the implementation\\n * address.\\n *\\n * IMPORTANT: A proxy pointing at a proxiable contract should not be considered proxiable itself, because this risks\\n * bricking a proxy that upgrades to it, by delegating to itself until out of gas. Thus it is critical that this\\n * function revert if invoked through a proxy.\\n */\\n function proxiableUUID() external view returns (bytes32);\\n}\\n\",\"keccak256\":\"0x1d4afe6cb24200cc4545eed814ecf5847277dfe5d613a1707aad5fceecebcfff\",\"license\":\"MIT\"},\"@openzeppelin/contracts/proxy/ERC1967/ERC1967Proxy.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.7.0) (proxy/ERC1967/ERC1967Proxy.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../Proxy.sol\\\";\\nimport \\\"./ERC1967Upgrade.sol\\\";\\n\\n/**\\n * @dev This contract implements an upgradeable proxy. It is upgradeable because calls are delegated to an\\n * implementation address that can be changed. This address is stored in storage in the location specified by\\n * https://eips.ethereum.org/EIPS/eip-1967[EIP1967], so that it doesn't conflict with the storage layout of the\\n * implementation behind the proxy.\\n */\\ncontract ERC1967Proxy is Proxy, ERC1967Upgrade {\\n /**\\n * @dev Initializes the upgradeable proxy with an initial implementation specified by `_logic`.\\n *\\n * If `_data` is nonempty, it's used as data in a delegate call to `_logic`. This will typically be an encoded\\n * function call, and allows initializing the storage of the proxy like a Solidity constructor.\\n */\\n constructor(address _logic, bytes memory _data) payable {\\n _upgradeToAndCall(_logic, _data, false);\\n }\\n\\n /**\\n * @dev Returns the current implementation address.\\n */\\n function _implementation() internal view virtual override returns (address impl) {\\n return ERC1967Upgrade._getImplementation();\\n }\\n}\\n\",\"keccak256\":\"0xa2b22da3032e50b55f95ec1d13336102d675f341167aa76db571ef7f8bb7975d\",\"license\":\"MIT\"},\"@openzeppelin/contracts/proxy/ERC1967/ERC1967Upgrade.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.5.0) (proxy/ERC1967/ERC1967Upgrade.sol)\\n\\npragma solidity ^0.8.2;\\n\\nimport \\\"../beacon/IBeacon.sol\\\";\\nimport \\\"../../interfaces/draft-IERC1822.sol\\\";\\nimport \\\"../../utils/Address.sol\\\";\\nimport \\\"../../utils/StorageSlot.sol\\\";\\n\\n/**\\n * @dev This abstract contract provides getters and event emitting update functions for\\n * https://eips.ethereum.org/EIPS/eip-1967[EIP1967] slots.\\n *\\n * _Available since v4.1._\\n *\\n * @custom:oz-upgrades-unsafe-allow delegatecall\\n */\\nabstract contract ERC1967Upgrade {\\n // This is the keccak-256 hash of \\\"eip1967.proxy.rollback\\\" subtracted by 1\\n bytes32 private constant _ROLLBACK_SLOT = 0x4910fdfa16fed3260ed0e7147f7cc6da11a60208b5b9406d12a635614ffd9143;\\n\\n /**\\n * @dev Storage slot with the address of the current implementation.\\n * This is the keccak-256 hash of \\\"eip1967.proxy.implementation\\\" subtracted by 1, and is\\n * validated in the constructor.\\n */\\n bytes32 internal constant _IMPLEMENTATION_SLOT = 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc;\\n\\n /**\\n * @dev Emitted when the implementation is upgraded.\\n */\\n event Upgraded(address indexed implementation);\\n\\n /**\\n * @dev Returns the current implementation address.\\n */\\n function _getImplementation() internal view returns (address) {\\n return StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value;\\n }\\n\\n /**\\n * @dev Stores a new address in the EIP1967 implementation slot.\\n */\\n function _setImplementation(address newImplementation) private {\\n require(Address.isContract(newImplementation), \\\"ERC1967: new implementation is not a contract\\\");\\n StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value = newImplementation;\\n }\\n\\n /**\\n * @dev Perform implementation upgrade\\n *\\n * Emits an {Upgraded} event.\\n */\\n function _upgradeTo(address newImplementation) internal {\\n _setImplementation(newImplementation);\\n emit Upgraded(newImplementation);\\n }\\n\\n /**\\n * @dev Perform implementation upgrade with additional setup call.\\n *\\n * Emits an {Upgraded} event.\\n */\\n function _upgradeToAndCall(\\n address newImplementation,\\n bytes memory data,\\n bool forceCall\\n ) internal {\\n _upgradeTo(newImplementation);\\n if (data.length > 0 || forceCall) {\\n Address.functionDelegateCall(newImplementation, data);\\n }\\n }\\n\\n /**\\n * @dev Perform implementation upgrade with security checks for UUPS proxies, and additional setup call.\\n *\\n * Emits an {Upgraded} event.\\n */\\n function _upgradeToAndCallUUPS(\\n address newImplementation,\\n bytes memory data,\\n bool forceCall\\n ) internal {\\n // Upgrades from old implementations will perform a rollback test. This test requires the new\\n // implementation to upgrade back to the old, non-ERC1822 compliant, implementation. Removing\\n // this special case will break upgrade paths from old UUPS implementation to new ones.\\n if (StorageSlot.getBooleanSlot(_ROLLBACK_SLOT).value) {\\n _setImplementation(newImplementation);\\n } else {\\n try IERC1822Proxiable(newImplementation).proxiableUUID() returns (bytes32 slot) {\\n require(slot == _IMPLEMENTATION_SLOT, \\\"ERC1967Upgrade: unsupported proxiableUUID\\\");\\n } catch {\\n revert(\\\"ERC1967Upgrade: new implementation is not UUPS\\\");\\n }\\n _upgradeToAndCall(newImplementation, data, forceCall);\\n }\\n }\\n\\n /**\\n * @dev Storage slot with the admin of the contract.\\n * This is the keccak-256 hash of \\\"eip1967.proxy.admin\\\" subtracted by 1, and is\\n * validated in the constructor.\\n */\\n bytes32 internal constant _ADMIN_SLOT = 0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103;\\n\\n /**\\n * @dev Emitted when the admin account has changed.\\n */\\n event AdminChanged(address previousAdmin, address newAdmin);\\n\\n /**\\n * @dev Returns the current admin.\\n */\\n function _getAdmin() internal view returns (address) {\\n return StorageSlot.getAddressSlot(_ADMIN_SLOT).value;\\n }\\n\\n /**\\n * @dev Stores a new address in the EIP1967 admin slot.\\n */\\n function _setAdmin(address newAdmin) private {\\n require(newAdmin != address(0), \\\"ERC1967: new admin is the zero address\\\");\\n StorageSlot.getAddressSlot(_ADMIN_SLOT).value = newAdmin;\\n }\\n\\n /**\\n * @dev Changes the admin of the proxy.\\n *\\n * Emits an {AdminChanged} event.\\n */\\n function _changeAdmin(address newAdmin) internal {\\n emit AdminChanged(_getAdmin(), newAdmin);\\n _setAdmin(newAdmin);\\n }\\n\\n /**\\n * @dev The storage slot of the UpgradeableBeacon contract which defines the implementation for this proxy.\\n * This is bytes32(uint256(keccak256('eip1967.proxy.beacon')) - 1)) and is validated in the constructor.\\n */\\n bytes32 internal constant _BEACON_SLOT = 0xa3f0ad74e5423aebfd80d3ef4346578335a9a72aeaee59ff6cb3582b35133d50;\\n\\n /**\\n * @dev Emitted when the beacon is upgraded.\\n */\\n event BeaconUpgraded(address indexed beacon);\\n\\n /**\\n * @dev Returns the current beacon.\\n */\\n function _getBeacon() internal view returns (address) {\\n return StorageSlot.getAddressSlot(_BEACON_SLOT).value;\\n }\\n\\n /**\\n * @dev Stores a new beacon in the EIP1967 beacon slot.\\n */\\n function _setBeacon(address newBeacon) private {\\n require(Address.isContract(newBeacon), \\\"ERC1967: new beacon is not a contract\\\");\\n require(\\n Address.isContract(IBeacon(newBeacon).implementation()),\\n \\\"ERC1967: beacon implementation is not a contract\\\"\\n );\\n StorageSlot.getAddressSlot(_BEACON_SLOT).value = newBeacon;\\n }\\n\\n /**\\n * @dev Perform beacon upgrade with additional setup call. Note: This upgrades the address of the beacon, it does\\n * not upgrade the implementation contained in the beacon (see {UpgradeableBeacon-_setImplementation} for that).\\n *\\n * Emits a {BeaconUpgraded} event.\\n */\\n function _upgradeBeaconToAndCall(\\n address newBeacon,\\n bytes memory data,\\n bool forceCall\\n ) internal {\\n _setBeacon(newBeacon);\\n emit BeaconUpgraded(newBeacon);\\n if (data.length > 0 || forceCall) {\\n Address.functionDelegateCall(IBeacon(newBeacon).implementation(), data);\\n }\\n }\\n}\\n\",\"keccak256\":\"0xabf3f59bc0e5423eae45e459dbe92e7052c6983628d39008590edc852a62f94a\",\"license\":\"MIT\"},\"@openzeppelin/contracts/proxy/Proxy.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.6.0) (proxy/Proxy.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev This abstract contract provides a fallback function that delegates all calls to another contract using the EVM\\n * instruction `delegatecall`. We refer to the second contract as the _implementation_ behind the proxy, and it has to\\n * be specified by overriding the virtual {_implementation} function.\\n *\\n * Additionally, delegation to the implementation can be triggered manually through the {_fallback} function, or to a\\n * different contract through the {_delegate} function.\\n *\\n * The success and return data of the delegated call will be returned back to the caller of the proxy.\\n */\\nabstract contract Proxy {\\n /**\\n * @dev Delegates the current call to `implementation`.\\n *\\n * This function does not return to its internal call site, it will return directly to the external caller.\\n */\\n function _delegate(address implementation) internal virtual {\\n assembly {\\n // Copy msg.data. We take full control of memory in this inline assembly\\n // block because it will not return to Solidity code. We overwrite the\\n // Solidity scratch pad at memory position 0.\\n calldatacopy(0, 0, calldatasize())\\n\\n // Call the implementation.\\n // out and outsize are 0 because we don't know the size yet.\\n let result := delegatecall(gas(), implementation, 0, calldatasize(), 0, 0)\\n\\n // Copy the returned data.\\n returndatacopy(0, 0, returndatasize())\\n\\n switch result\\n // delegatecall returns 0 on error.\\n case 0 {\\n revert(0, returndatasize())\\n }\\n default {\\n return(0, returndatasize())\\n }\\n }\\n }\\n\\n /**\\n * @dev This is a virtual function that should be overridden so it returns the address to which the fallback function\\n * and {_fallback} should delegate.\\n */\\n function _implementation() internal view virtual returns (address);\\n\\n /**\\n * @dev Delegates the current call to the address returned by `_implementation()`.\\n *\\n * This function does not return to its internal call site, it will return directly to the external caller.\\n */\\n function _fallback() internal virtual {\\n _beforeFallback();\\n _delegate(_implementation());\\n }\\n\\n /**\\n * @dev Fallback function that delegates calls to the address returned by `_implementation()`. Will run if no other\\n * function in the contract matches the call data.\\n */\\n fallback() external payable virtual {\\n _fallback();\\n }\\n\\n /**\\n * @dev Fallback function that delegates calls to the address returned by `_implementation()`. Will run if call data\\n * is empty.\\n */\\n receive() external payable virtual {\\n _fallback();\\n }\\n\\n /**\\n * @dev Hook that is called before falling back to the implementation. Can happen as part of a manual `_fallback`\\n * call, or as part of the Solidity `fallback` or `receive` functions.\\n *\\n * If overridden should call `super._beforeFallback()`.\\n */\\n function _beforeFallback() internal virtual {}\\n}\\n\",\"keccak256\":\"0xc130fe33f1b2132158531a87734153293f6d07bc263ff4ac90e85da9c82c0e27\",\"license\":\"MIT\"},\"@openzeppelin/contracts/proxy/beacon/IBeacon.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (proxy/beacon/IBeacon.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev This is the interface that {BeaconProxy} expects of its beacon.\\n */\\ninterface IBeacon {\\n /**\\n * @dev Must return an address that can be used as a delegate call target.\\n *\\n * {BeaconProxy} will check that this address is a contract.\\n */\\n function implementation() external view returns (address);\\n}\\n\",\"keccak256\":\"0xd50a3421ac379ccb1be435fa646d66a65c986b4924f0849839f08692f39dde61\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/Address.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.7.0) (utils/Address.sol)\\n\\npragma solidity ^0.8.1;\\n\\n/**\\n * @dev Collection of functions related to the address type\\n */\\nlibrary Address {\\n /**\\n * @dev Returns true if `account` is a contract.\\n *\\n * [IMPORTANT]\\n * ====\\n * It is unsafe to assume that an address for which this function returns\\n * false is an externally-owned account (EOA) and not a contract.\\n *\\n * Among others, `isContract` will return false for the following\\n * types of addresses:\\n *\\n * - an externally-owned account\\n * - a contract in construction\\n * - an address where a contract will be created\\n * - an address where a contract lived, but was destroyed\\n * ====\\n *\\n * [IMPORTANT]\\n * ====\\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\\n *\\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\\n * constructor.\\n * ====\\n */\\n function isContract(address account) internal view returns (bool) {\\n // This method relies on extcodesize/address.code.length, which returns 0\\n // for contracts in construction, since the code is only stored at the end\\n // of the constructor execution.\\n\\n return account.code.length > 0;\\n }\\n\\n /**\\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\\n * `recipient`, forwarding all available gas and reverting on errors.\\n *\\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\\n * imposed by `transfer`, making them unable to receive funds via\\n * `transfer`. {sendValue} removes this limitation.\\n *\\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\\n *\\n * IMPORTANT: because control is transferred to `recipient`, care must be\\n * taken to not create reentrancy vulnerabilities. Consider using\\n * {ReentrancyGuard} or the\\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\\n */\\n function sendValue(address payable recipient, uint256 amount) internal {\\n require(address(this).balance >= amount, \\\"Address: insufficient balance\\\");\\n\\n (bool success, ) = recipient.call{value: amount}(\\\"\\\");\\n require(success, \\\"Address: unable to send value, recipient may have reverted\\\");\\n }\\n\\n /**\\n * @dev Performs a Solidity function call using a low level `call`. A\\n * plain `call` is an unsafe replacement for a function call: use this\\n * function instead.\\n *\\n * If `target` reverts with a revert reason, it is bubbled up by this\\n * function (like regular Solidity function calls).\\n *\\n * Returns the raw returned data. To convert to the expected return value,\\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\\n *\\n * Requirements:\\n *\\n * - `target` must be a contract.\\n * - calling `target` with `data` must not revert.\\n *\\n * _Available since v3.1._\\n */\\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\\n return functionCall(target, data, \\\"Address: low-level call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\\n * `errorMessage` as a fallback revert reason when `target` reverts.\\n *\\n * _Available since v3.1._\\n */\\n function functionCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n return functionCallWithValue(target, data, 0, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but also transferring `value` wei to `target`.\\n *\\n * Requirements:\\n *\\n * - the calling contract must have an ETH balance of at least `value`.\\n * - the called Solidity function must be `payable`.\\n *\\n * _Available since v3.1._\\n */\\n function functionCallWithValue(\\n address target,\\n bytes memory data,\\n uint256 value\\n ) internal returns (bytes memory) {\\n return functionCallWithValue(target, data, value, \\\"Address: low-level call with value failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\\n * with `errorMessage` as a fallback revert reason when `target` reverts.\\n *\\n * _Available since v3.1._\\n */\\n function functionCallWithValue(\\n address target,\\n bytes memory data,\\n uint256 value,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n require(address(this).balance >= value, \\\"Address: insufficient balance for call\\\");\\n require(isContract(target), \\\"Address: call to non-contract\\\");\\n\\n (bool success, bytes memory returndata) = target.call{value: value}(data);\\n return verifyCallResult(success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but performing a static call.\\n *\\n * _Available since v3.3._\\n */\\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\\n return functionStaticCall(target, data, \\\"Address: low-level static call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\\n * but performing a static call.\\n *\\n * _Available since v3.3._\\n */\\n function functionStaticCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal view returns (bytes memory) {\\n require(isContract(target), \\\"Address: static call to non-contract\\\");\\n\\n (bool success, bytes memory returndata) = target.staticcall(data);\\n return verifyCallResult(success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but performing a delegate call.\\n *\\n * _Available since v3.4._\\n */\\n function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {\\n return functionDelegateCall(target, data, \\\"Address: low-level delegate call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\\n * but performing a delegate call.\\n *\\n * _Available since v3.4._\\n */\\n function functionDelegateCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n require(isContract(target), \\\"Address: delegate call to non-contract\\\");\\n\\n (bool success, bytes memory returndata) = target.delegatecall(data);\\n return verifyCallResult(success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the\\n * revert reason using the provided one.\\n *\\n * _Available since v4.3._\\n */\\n function verifyCallResult(\\n bool success,\\n bytes memory returndata,\\n string memory errorMessage\\n ) internal pure returns (bytes memory) {\\n if (success) {\\n return returndata;\\n } else {\\n // Look for revert reason and bubble it up if present\\n if (returndata.length > 0) {\\n // The easiest way to bubble the revert reason is using memory via assembly\\n /// @solidity memory-safe-assembly\\n assembly {\\n let returndata_size := mload(returndata)\\n revert(add(32, returndata), returndata_size)\\n }\\n } else {\\n revert(errorMessage);\\n }\\n }\\n }\\n}\\n\",\"keccak256\":\"0xd6153ce99bcdcce22b124f755e72553295be6abcd63804cfdffceb188b8bef10\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/StorageSlot.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.7.0) (utils/StorageSlot.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Library for reading and writing primitive types to specific storage slots.\\n *\\n * Storage slots are often used to avoid storage conflict when dealing with upgradeable contracts.\\n * This library helps with reading and writing to such slots without the need for inline assembly.\\n *\\n * The functions in this library return Slot structs that contain a `value` member that can be used to read or write.\\n *\\n * Example usage to set ERC1967 implementation slot:\\n * ```\\n * contract ERC1967 {\\n * bytes32 internal constant _IMPLEMENTATION_SLOT = 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc;\\n *\\n * function _getImplementation() internal view returns (address) {\\n * return StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value;\\n * }\\n *\\n * function _setImplementation(address newImplementation) internal {\\n * require(Address.isContract(newImplementation), \\\"ERC1967: new implementation is not a contract\\\");\\n * StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value = newImplementation;\\n * }\\n * }\\n * ```\\n *\\n * _Available since v4.1 for `address`, `bool`, `bytes32`, and `uint256`._\\n */\\nlibrary StorageSlot {\\n struct AddressSlot {\\n address value;\\n }\\n\\n struct BooleanSlot {\\n bool value;\\n }\\n\\n struct Bytes32Slot {\\n bytes32 value;\\n }\\n\\n struct Uint256Slot {\\n uint256 value;\\n }\\n\\n /**\\n * @dev Returns an `AddressSlot` with member `value` located at `slot`.\\n */\\n function getAddressSlot(bytes32 slot) internal pure returns (AddressSlot storage r) {\\n /// @solidity memory-safe-assembly\\n assembly {\\n r.slot := slot\\n }\\n }\\n\\n /**\\n * @dev Returns an `BooleanSlot` with member `value` located at `slot`.\\n */\\n function getBooleanSlot(bytes32 slot) internal pure returns (BooleanSlot storage r) {\\n /// @solidity memory-safe-assembly\\n assembly {\\n r.slot := slot\\n }\\n }\\n\\n /**\\n * @dev Returns an `Bytes32Slot` with member `value` located at `slot`.\\n */\\n function getBytes32Slot(bytes32 slot) internal pure returns (Bytes32Slot storage r) {\\n /// @solidity memory-safe-assembly\\n assembly {\\n r.slot := slot\\n }\\n }\\n\\n /**\\n * @dev Returns an `Uint256Slot` with member `value` located at `slot`.\\n */\\n function getUint256Slot(bytes32 slot) internal pure returns (Uint256Slot storage r) {\\n /// @solidity memory-safe-assembly\\n assembly {\\n r.slot := slot\\n }\\n }\\n}\\n\",\"keccak256\":\"0xd5c50c54bf02740ebd122ff06832546cb5fa84486d52695a9ccfd11666e0c81d\",\"license\":\"MIT\"},\"contracts/external/TransparentUpgradeableProxy.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-3.0\\n\\npragma solidity ^0.8.12;\\n\\nimport \\\"@openzeppelin/contracts/proxy/ERC1967/ERC1967Proxy.sol\\\";\\n\\n/**\\n * @dev This contract implements a proxy that is upgradeable by an admin. It is fully forked from OpenZeppelin\\n * `TransparentUpgradeableProxy`\\n *\\n * To avoid https://medium.com/nomic-labs-blog/malicious-backdoors-in-ethereum-proxies-62629adf3357[proxy selector\\n * clashing], which can potentially be used in an attack, this contract uses the\\n * https://blog.openzeppelin.com/the-transparent-proxy-pattern/[transparent proxy pattern]. This pattern implies two\\n * things that go hand in hand:\\n *\\n * 1. If any account other than the admin calls the proxy, the call will be forwarded to the implementation, even if\\n * that call matches one of the admin functions exposed by the proxy itself.\\n * 2. If the admin calls the proxy, it can access the admin functions, but its calls will never be forwarded to the\\n * implementation. If the admin tries to call a function on the implementation it will fail with an error that says\\n * \\\"admin cannot fallback to proxy target\\\".\\n *\\n * These properties mean that the admin account can only be used for admin actions like upgrading the proxy or changing\\n * the admin, so it's best if it's a dedicated account that is not used for anything else. This will avoid headaches due\\n * to sudden errors when trying to call a function from the proxy implementation.\\n *\\n * Our recommendation is for the dedicated account to be an instance of the {ProxyAdmin} contract. If set up this way,\\n * you should think of the `ProxyAdmin` instance as the real administrative interface of your proxy.\\n */\\ncontract TransparentUpgradeableProxy is ERC1967Proxy {\\n /**\\n * @dev Initializes an upgradeable proxy managed by `_admin`, backed by the implementation at `_logic`, and\\n * optionally initialized with `_data` as explained in {ERC1967Proxy-constructor}.\\n */\\n constructor(address _logic, address admin_, bytes memory _data) payable ERC1967Proxy(_logic, _data) {\\n assert(_ADMIN_SLOT == bytes32(uint256(keccak256(\\\"eip1967.proxy.admin\\\")) - 1));\\n _changeAdmin(admin_);\\n }\\n\\n /**\\n * @dev Modifier used internally that will delegate the call to the implementation unless the sender is the admin.\\n */\\n modifier ifAdmin() {\\n if (msg.sender == _getAdmin()) {\\n _;\\n } else {\\n _fallback();\\n }\\n }\\n\\n /**\\n * @dev Returns the current admin.\\n *\\n * NOTE: Only the admin can call this function. See {ProxyAdmin-getProxyAdmin}.\\n *\\n * TIP: To get this value clients can read directly from the storage slot shown below (specified by EIP1967) using the\\n * https://eth.wiki/json-rpc/API#eth_getstorageat[`eth_getStorageAt`] RPC call.\\n * `0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103`\\n */\\n function admin() external ifAdmin returns (address admin_) {\\n admin_ = _getAdmin();\\n }\\n\\n /**\\n * @dev Returns the current implementation.\\n *\\n * NOTE: Only the admin can call this function. See {ProxyAdmin-getProxyImplementation}.\\n *\\n * TIP: To get this value clients can read directly from the storage slot shown below (specified by EIP1967) using the\\n * https://eth.wiki/json-rpc/API#eth_getstorageat[`eth_getStorageAt`] RPC call.\\n * `0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc`\\n */\\n function implementation() external ifAdmin returns (address implementation_) {\\n implementation_ = _implementation();\\n }\\n\\n /**\\n * @dev Changes the admin of the proxy.\\n *\\n * Emits an {AdminChanged} event.\\n *\\n * NOTE: Only the admin can call this function. See {ProxyAdmin-changeProxyAdmin}.\\n */\\n function changeAdmin(address newAdmin) external virtual ifAdmin {\\n _changeAdmin(newAdmin);\\n }\\n\\n /**\\n * @dev Upgrade the implementation of the proxy.\\n *\\n * NOTE: Only the admin can call this function. See {ProxyAdmin-upgrade}.\\n */\\n function upgradeTo(address newImplementation) external ifAdmin {\\n _upgradeToAndCall(newImplementation, bytes(\\\"\\\"), false);\\n }\\n\\n /**\\n * @dev Upgrade the implementation of the proxy, and then call a function from the new implementation as specified\\n * by `data`, which should be an encoded function call. This is useful to initialize new storage variables in the\\n * proxied contract.\\n *\\n * NOTE: Only the admin can call this function. See {ProxyAdmin-upgradeAndCall}.\\n */\\n function upgradeToAndCall(address newImplementation, bytes calldata data) external payable ifAdmin {\\n _upgradeToAndCall(newImplementation, data, true);\\n }\\n\\n /**\\n * @dev Returns the current admin.\\n */\\n function _admin() internal view virtual returns (address) {\\n return _getAdmin();\\n }\\n\\n /**\\n * @dev Makes sure the admin cannot access the fallback function. See {Proxy-_beforeFallback}.\\n */\\n function _beforeFallback() internal virtual override {\\n require(msg.sender != _getAdmin(), \\\"TransparentUpgradeableProxy: admin cannot fallback to proxy target\\\");\\n super._beforeFallback();\\n }\\n}\\n\",\"keccak256\":\"0x93a67a0f612ea3ff2a76315e138a6a88267270a1379d3cc7be52845fbbe611e2\",\"license\":\"GPL-3.0\"}},\"version\":1}", + "bytecode": "0x6080604052604051620010bb380380620010bb8339810160408190526200002691620004d8565b828162000036828260006200009a565b5062000066905060017fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6104620005b8565b6000805160206200107483398151915214620000865762000086620005da565b6200009182620000d7565b50505062000643565b620000a58362000132565b600082511180620000b35750805b15620000d257620000d083836200017460201b6200028c1760201c565b505b505050565b7f7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f62000102620001a5565b604080516001600160a01b03928316815291841660208301520160405180910390a16200012f81620001de565b50565b6200013d8162000293565b6040516001600160a01b038216907fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b90600090a250565b60606200019c8383604051806060016040528060278152602001620010946027913962000347565b90505b92915050565b6000620001cf6000805160206200107483398151915260001b6200042f60201b6200022e1760201c565b546001600160a01b0316919050565b6001600160a01b038116620002495760405162461bcd60e51b815260206004820152602660248201527f455243313936373a206e65772061646d696e20697320746865207a65726f206160448201526564647265737360d01b60648201526084015b60405180910390fd5b80620002726000805160206200107483398151915260001b6200042f60201b6200022e1760201c565b80546001600160a01b0319166001600160a01b039290921691909117905550565b620002a9816200043260201b620002b81760201c565b6200030d5760405162461bcd60e51b815260206004820152602d60248201527f455243313936373a206e657720696d706c656d656e746174696f6e206973206e60448201526c1bdd08184818dbdb9d1c9858dd609a1b606482015260840162000240565b80620002727f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc60001b6200042f60201b6200022e1760201c565b60606001600160a01b0384163b620003b15760405162461bcd60e51b815260206004820152602660248201527f416464726573733a2064656c65676174652063616c6c20746f206e6f6e2d636f6044820152651b9d1c9858dd60d21b606482015260840162000240565b600080856001600160a01b031685604051620003ce9190620005f0565b600060405180830381855af49150503d80600081146200040b576040519150601f19603f3d011682016040523d82523d6000602084013e62000410565b606091505b5090925090506200042382828662000441565b925050505b9392505050565b90565b6001600160a01b03163b151590565b606083156200045257508162000428565b825115620004635782518084602001fd5b8160405162461bcd60e51b81526004016200024091906200060e565b80516001600160a01b03811681146200049757600080fd5b919050565b634e487b7160e01b600052604160045260246000fd5b60005b83811015620004cf578181015183820152602001620004b5565b50506000910152565b600080600060608486031215620004ee57600080fd5b620004f9846200047f565b925062000509602085016200047f565b60408501519092506001600160401b03808211156200052757600080fd5b818601915086601f8301126200053c57600080fd5b8151818111156200055157620005516200049c565b604051601f8201601f19908116603f011681019083821181831017156200057c576200057c6200049c565b816040528281528960208487010111156200059657600080fd5b620005a9836020830160208801620004b2565b80955050505050509250925092565b818103818111156200019f57634e487b7160e01b600052601160045260246000fd5b634e487b7160e01b600052600160045260246000fd5b6000825162000604818460208701620004b2565b9190910192915050565b60208152600082518060208401526200062f816040850160208701620004b2565b601f01601f19169190910160400192915050565b610a2180620006536000396000f3fe60806040526004361061005e5760003560e01c80635c60da1b116100435780635c60da1b146100a85780638f283970146100e6578063f851a440146101065761006d565b80633659cfe6146100755780634f1ef286146100955761006d565b3661006d5761006b61011b565b005b61006b61011b565b34801561008157600080fd5b5061006b610090366004610895565b610135565b61006b6100a33660046108b0565b61017f565b3480156100b457600080fd5b506100bd6101f3565b60405173ffffffffffffffffffffffffffffffffffffffff909116815260200160405180910390f35b3480156100f257600080fd5b5061006b610101366004610895565b610231565b34801561011257600080fd5b506100bd61025e565b6101236102d4565b61013361012e6103ab565b6103b5565b565b61013d6103d9565b73ffffffffffffffffffffffffffffffffffffffff1633036101775761017481604051806020016040528060008152506000610419565b50565b61017461011b565b6101876103d9565b73ffffffffffffffffffffffffffffffffffffffff1633036101eb576101e68383838080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525060019250610419915050565b505050565b6101e661011b565b60006101fd6103d9565b73ffffffffffffffffffffffffffffffffffffffff163303610226576102216103ab565b905090565b61022e61011b565b90565b6102396103d9565b73ffffffffffffffffffffffffffffffffffffffff1633036101775761017481610444565b60006102686103d9565b73ffffffffffffffffffffffffffffffffffffffff163303610226576102216103d9565b60606102b183836040518060600160405280602781526020016109c5602791396104a5565b9392505050565b73ffffffffffffffffffffffffffffffffffffffff163b151590565b6102dc6103d9565b73ffffffffffffffffffffffffffffffffffffffff163303610133576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604260248201527f5472616e73706172656e745570677261646561626c6550726f78793a2061646d60448201527f696e2063616e6e6f742066616c6c6261636b20746f2070726f7879207461726760648201527f6574000000000000000000000000000000000000000000000000000000000000608482015260a4015b60405180910390fd5b60006102216105cd565b3660008037600080366000845af43d6000803e8080156103d4573d6000f35b3d6000fd5b60007fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035b5473ffffffffffffffffffffffffffffffffffffffff16919050565b610422836105f5565b60008251118061042f5750805b156101e65761043e838361028c565b50505050565b7f7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f61046d6103d9565b6040805173ffffffffffffffffffffffffffffffffffffffff928316815291841660208301520160405180910390a161017481610642565b606073ffffffffffffffffffffffffffffffffffffffff84163b61054b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f416464726573733a2064656c65676174652063616c6c20746f206e6f6e2d636f60448201527f6e7472616374000000000000000000000000000000000000000000000000000060648201526084016103a2565b6000808573ffffffffffffffffffffffffffffffffffffffff16856040516105739190610957565b600060405180830381855af49150503d80600081146105ae576040519150601f19603f3d011682016040523d82523d6000602084013e6105b3565b606091505b50915091506105c382828661074e565b9695505050505050565b60007f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc6103fd565b6105fe816107a1565b60405173ffffffffffffffffffffffffffffffffffffffff8216907fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b90600090a250565b73ffffffffffffffffffffffffffffffffffffffff81166106e5576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f455243313936373a206e65772061646d696e20697320746865207a65726f206160448201527f646472657373000000000000000000000000000000000000000000000000000060648201526084016103a2565b807fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035b80547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff9290921691909117905550565b6060831561075d5750816102b1565b82511561076d5782518084602001fd5b816040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016103a29190610973565b73ffffffffffffffffffffffffffffffffffffffff81163b610845576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602d60248201527f455243313936373a206e657720696d706c656d656e746174696f6e206973206e60448201527f6f74206120636f6e74726163740000000000000000000000000000000000000060648201526084016103a2565b807f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc610708565b803573ffffffffffffffffffffffffffffffffffffffff8116811461089057600080fd5b919050565b6000602082840312156108a757600080fd5b6102b18261086c565b6000806000604084860312156108c557600080fd5b6108ce8461086c565b9250602084013567ffffffffffffffff808211156108eb57600080fd5b818601915086601f8301126108ff57600080fd5b81358181111561090e57600080fd5b87602082850101111561092057600080fd5b6020830194508093505050509250925092565b60005b8381101561094e578181015183820152602001610936565b50506000910152565b60008251610969818460208701610933565b9190910192915050565b6020815260008251806020840152610992816040850160208701610933565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016919091016040019291505056fe416464726573733a206c6f772d6c6576656c2064656c65676174652063616c6c206661696c6564a2646970667358221220e96638b07fb1675d93a95c49e417bc8111448b23a59918698cdcd8fd488dd7cf64736f6c63430008110033b53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103416464726573733a206c6f772d6c6576656c2064656c65676174652063616c6c206661696c6564", + "deployedBytecode": "0x60806040526004361061005e5760003560e01c80635c60da1b116100435780635c60da1b146100a85780638f283970146100e6578063f851a440146101065761006d565b80633659cfe6146100755780634f1ef286146100955761006d565b3661006d5761006b61011b565b005b61006b61011b565b34801561008157600080fd5b5061006b610090366004610895565b610135565b61006b6100a33660046108b0565b61017f565b3480156100b457600080fd5b506100bd6101f3565b60405173ffffffffffffffffffffffffffffffffffffffff909116815260200160405180910390f35b3480156100f257600080fd5b5061006b610101366004610895565b610231565b34801561011257600080fd5b506100bd61025e565b6101236102d4565b61013361012e6103ab565b6103b5565b565b61013d6103d9565b73ffffffffffffffffffffffffffffffffffffffff1633036101775761017481604051806020016040528060008152506000610419565b50565b61017461011b565b6101876103d9565b73ffffffffffffffffffffffffffffffffffffffff1633036101eb576101e68383838080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525060019250610419915050565b505050565b6101e661011b565b60006101fd6103d9565b73ffffffffffffffffffffffffffffffffffffffff163303610226576102216103ab565b905090565b61022e61011b565b90565b6102396103d9565b73ffffffffffffffffffffffffffffffffffffffff1633036101775761017481610444565b60006102686103d9565b73ffffffffffffffffffffffffffffffffffffffff163303610226576102216103d9565b60606102b183836040518060600160405280602781526020016109c5602791396104a5565b9392505050565b73ffffffffffffffffffffffffffffffffffffffff163b151590565b6102dc6103d9565b73ffffffffffffffffffffffffffffffffffffffff163303610133576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604260248201527f5472616e73706172656e745570677261646561626c6550726f78793a2061646d60448201527f696e2063616e6e6f742066616c6c6261636b20746f2070726f7879207461726760648201527f6574000000000000000000000000000000000000000000000000000000000000608482015260a4015b60405180910390fd5b60006102216105cd565b3660008037600080366000845af43d6000803e8080156103d4573d6000f35b3d6000fd5b60007fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035b5473ffffffffffffffffffffffffffffffffffffffff16919050565b610422836105f5565b60008251118061042f5750805b156101e65761043e838361028c565b50505050565b7f7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f61046d6103d9565b6040805173ffffffffffffffffffffffffffffffffffffffff928316815291841660208301520160405180910390a161017481610642565b606073ffffffffffffffffffffffffffffffffffffffff84163b61054b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f416464726573733a2064656c65676174652063616c6c20746f206e6f6e2d636f60448201527f6e7472616374000000000000000000000000000000000000000000000000000060648201526084016103a2565b6000808573ffffffffffffffffffffffffffffffffffffffff16856040516105739190610957565b600060405180830381855af49150503d80600081146105ae576040519150601f19603f3d011682016040523d82523d6000602084013e6105b3565b606091505b50915091506105c382828661074e565b9695505050505050565b60007f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc6103fd565b6105fe816107a1565b60405173ffffffffffffffffffffffffffffffffffffffff8216907fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b90600090a250565b73ffffffffffffffffffffffffffffffffffffffff81166106e5576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f455243313936373a206e65772061646d696e20697320746865207a65726f206160448201527f646472657373000000000000000000000000000000000000000000000000000060648201526084016103a2565b807fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035b80547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff9290921691909117905550565b6060831561075d5750816102b1565b82511561076d5782518084602001fd5b816040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016103a29190610973565b73ffffffffffffffffffffffffffffffffffffffff81163b610845576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602d60248201527f455243313936373a206e657720696d706c656d656e746174696f6e206973206e60448201527f6f74206120636f6e74726163740000000000000000000000000000000000000060648201526084016103a2565b807f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc610708565b803573ffffffffffffffffffffffffffffffffffffffff8116811461089057600080fd5b919050565b6000602082840312156108a757600080fd5b6102b18261086c565b6000806000604084860312156108c557600080fd5b6108ce8461086c565b9250602084013567ffffffffffffffff808211156108eb57600080fd5b818601915086601f8301126108ff57600080fd5b81358181111561090e57600080fd5b87602082850101111561092057600080fd5b6020830194508093505050509250925092565b60005b8381101561094e578181015183820152602001610936565b50506000910152565b60008251610969818460208701610933565b9190910192915050565b6020815260008251806020840152610992816040850160208701610933565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016919091016040019291505056fe416464726573733a206c6f772d6c6576656c2064656c65676174652063616c6c206661696c6564a2646970667358221220e96638b07fb1675d93a95c49e417bc8111448b23a59918698cdcd8fd488dd7cf64736f6c63430008110033", + "devdoc": { + "details": "This contract implements a proxy that is upgradeable by an admin. It is fully forked from OpenZeppelin `TransparentUpgradeableProxy` To avoid https://medium.com/nomic-labs-blog/malicious-backdoors-in-ethereum-proxies-62629adf3357[proxy selector clashing], which can potentially be used in an attack, this contract uses the https://blog.openzeppelin.com/the-transparent-proxy-pattern/[transparent proxy pattern]. This pattern implies two things that go hand in hand: 1. If any account other than the admin calls the proxy, the call will be forwarded to the implementation, even if that call matches one of the admin functions exposed by the proxy itself. 2. If the admin calls the proxy, it can access the admin functions, but its calls will never be forwarded to the implementation. If the admin tries to call a function on the implementation it will fail with an error that says \"admin cannot fallback to proxy target\". These properties mean that the admin account can only be used for admin actions like upgrading the proxy or changing the admin, so it's best if it's a dedicated account that is not used for anything else. This will avoid headaches due to sudden errors when trying to call a function from the proxy implementation. Our recommendation is for the dedicated account to be an instance of the {ProxyAdmin} contract. If set up this way, you should think of the `ProxyAdmin` instance as the real administrative interface of your proxy.", + "kind": "dev", + "methods": { + "admin()": { + "details": "Returns the current admin. NOTE: Only the admin can call this function. See {ProxyAdmin-getProxyAdmin}. TIP: To get this value clients can read directly from the storage slot shown below (specified by EIP1967) using the https://eth.wiki/json-rpc/API#eth_getstorageat[`eth_getStorageAt`] RPC call. `0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103`" + }, + "changeAdmin(address)": { + "details": "Changes the admin of the proxy. Emits an {AdminChanged} event. NOTE: Only the admin can call this function. See {ProxyAdmin-changeProxyAdmin}." + }, + "constructor": { + "details": "Initializes an upgradeable proxy managed by `_admin`, backed by the implementation at `_logic`, and optionally initialized with `_data` as explained in {ERC1967Proxy-constructor}." + }, + "implementation()": { + "details": "Returns the current implementation. NOTE: Only the admin can call this function. See {ProxyAdmin-getProxyImplementation}. TIP: To get this value clients can read directly from the storage slot shown below (specified by EIP1967) using the https://eth.wiki/json-rpc/API#eth_getstorageat[`eth_getStorageAt`] RPC call. `0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc`" + }, + "upgradeTo(address)": { + "details": "Upgrade the implementation of the proxy. NOTE: Only the admin can call this function. See {ProxyAdmin-upgrade}." + }, + "upgradeToAndCall(address,bytes)": { + "details": "Upgrade the implementation of the proxy, and then call a function from the new implementation as specified by `data`, which should be an encoded function call. This is useful to initialize new storage variables in the proxied contract. NOTE: Only the admin can call this function. See {ProxyAdmin-upgradeAndCall}." + } + }, + "version": 1 + }, + "userdoc": { + "kind": "user", + "methods": {}, + "version": 1 + }, + "storageLayout": { + "storage": [], + "types": null + } +} \ No newline at end of file diff --git a/deployments/mainnet/solcInputs/0938660e7382a0ccf0ba8a2485ec5da6.json b/deployments/mainnet/solcInputs/0938660e7382a0ccf0ba8a2485ec5da6.json new file mode 100644 index 00000000..307ab752 --- /dev/null +++ b/deployments/mainnet/solcInputs/0938660e7382a0ccf0ba8a2485ec5da6.json @@ -0,0 +1,127 @@ +{ + "language": "Solidity", + "sources": { + "@chainlink/contracts/src/v0.8/interfaces/AggregatorV3Interface.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.0;\n\ninterface AggregatorV3Interface {\n\n function decimals()\n external\n view\n returns (\n uint8\n );\n\n function description()\n external\n view\n returns (\n string memory\n );\n\n function version()\n external\n view\n returns (\n uint256\n );\n\n // getRoundData and latestRoundData should both raise \"No data present\"\n // if they do not have data to report, instead of returning unset values\n // which could be misinterpreted as actual reported values.\n function getRoundData(\n uint80 _roundId\n )\n external\n view\n returns (\n uint80 roundId,\n int256 answer,\n uint256 startedAt,\n uint256 updatedAt,\n uint80 answeredInRound\n );\n\n function latestRoundData()\n external\n view\n returns (\n uint80 roundId,\n int256 answer,\n uint256 startedAt,\n uint256 updatedAt,\n uint80 answeredInRound\n );\n\n}\n" + }, + "@openzeppelin/contracts-upgradeable/interfaces/IERC721MetadataUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (interfaces/IERC721Metadata.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../token/ERC721/extensions/IERC721MetadataUpgradeable.sol\";\n" + }, + "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (proxy/utils/Initializable.sol)\n\npragma solidity ^0.8.2;\n\nimport \"../../utils/AddressUpgradeable.sol\";\n\n/**\n * @dev This is a base contract to aid in writing upgradeable contracts, or any kind of contract that will be deployed\n * behind a proxy. Since proxied contracts do not make use of a constructor, it's common to move constructor logic to an\n * external initializer function, usually called `initialize`. It then becomes necessary to protect this initializer\n * function so it can only be called once. The {initializer} modifier provided by this contract will have this effect.\n *\n * The initialization functions use a version number. Once a version number is used, it is consumed and cannot be\n * reused. This mechanism prevents re-execution of each \"step\" but allows the creation of new initialization steps in\n * case an upgrade adds a module that needs to be initialized.\n *\n * For example:\n *\n * [.hljs-theme-light.nopadding]\n * ```\n * contract MyToken is ERC20Upgradeable {\n * function initialize() initializer public {\n * __ERC20_init(\"MyToken\", \"MTK\");\n * }\n * }\n * contract MyTokenV2 is MyToken, ERC20PermitUpgradeable {\n * function initializeV2() reinitializer(2) public {\n * __ERC20Permit_init(\"MyToken\");\n * }\n * }\n * ```\n *\n * TIP: To avoid leaving the proxy in an uninitialized state, the initializer function should be called as early as\n * possible by providing the encoded function call as the `_data` argument to {ERC1967Proxy-constructor}.\n *\n * CAUTION: When used with inheritance, manual care must be taken to not invoke a parent initializer twice, or to ensure\n * that all initializers are idempotent. This is not verified automatically as constructors are by Solidity.\n *\n * [CAUTION]\n * ====\n * Avoid leaving a contract uninitialized.\n *\n * An uninitialized contract can be taken over by an attacker. This applies to both a proxy and its implementation\n * contract, which may impact the proxy. To prevent the implementation contract from being used, you should invoke\n * the {_disableInitializers} function in the constructor to automatically lock it when it is deployed:\n *\n * [.hljs-theme-light.nopadding]\n * ```\n * /// @custom:oz-upgrades-unsafe-allow constructor\n * constructor() {\n * _disableInitializers();\n * }\n * ```\n * ====\n */\nabstract contract Initializable {\n /**\n * @dev Indicates that the contract has been initialized.\n * @custom:oz-retyped-from bool\n */\n uint8 private _initialized;\n\n /**\n * @dev Indicates that the contract is in the process of being initialized.\n */\n bool private _initializing;\n\n /**\n * @dev Triggered when the contract has been initialized or reinitialized.\n */\n event Initialized(uint8 version);\n\n /**\n * @dev A modifier that defines a protected initializer function that can be invoked at most once. In its scope,\n * `onlyInitializing` functions can be used to initialize parent contracts. Equivalent to `reinitializer(1)`.\n */\n modifier initializer() {\n bool isTopLevelCall = !_initializing;\n require(\n (isTopLevelCall && _initialized < 1) || (!AddressUpgradeable.isContract(address(this)) && _initialized == 1),\n \"Initializable: contract is already initialized\"\n );\n _initialized = 1;\n if (isTopLevelCall) {\n _initializing = true;\n }\n _;\n if (isTopLevelCall) {\n _initializing = false;\n emit Initialized(1);\n }\n }\n\n /**\n * @dev A modifier that defines a protected reinitializer function that can be invoked at most once, and only if the\n * contract hasn't been initialized to a greater version before. In its scope, `onlyInitializing` functions can be\n * used to initialize parent contracts.\n *\n * `initializer` is equivalent to `reinitializer(1)`, so a reinitializer may be used after the original\n * initialization step. This is essential to configure modules that are added through upgrades and that require\n * initialization.\n *\n * Note that versions can jump in increments greater than 1; this implies that if multiple reinitializers coexist in\n * a contract, executing them in the right order is up to the developer or operator.\n */\n modifier reinitializer(uint8 version) {\n require(!_initializing && _initialized < version, \"Initializable: contract is already initialized\");\n _initialized = version;\n _initializing = true;\n _;\n _initializing = false;\n emit Initialized(version);\n }\n\n /**\n * @dev Modifier to protect an initialization function so that it can only be invoked by functions with the\n * {initializer} and {reinitializer} modifiers, directly or indirectly.\n */\n modifier onlyInitializing() {\n require(_initializing, \"Initializable: contract is not initializing\");\n _;\n }\n\n /**\n * @dev Locks the contract, preventing any future reinitialization. This cannot be part of an initializer call.\n * Calling this in the constructor of a contract will prevent that contract from being initialized or reinitialized\n * to any version. It is recommended to use this to lock implementation contracts that are designed to be called\n * through proxies.\n */\n function _disableInitializers() internal virtual {\n require(!_initializing, \"Initializable: contract is initializing\");\n if (_initialized < type(uint8).max) {\n _initialized = type(uint8).max;\n emit Initialized(type(uint8).max);\n }\n }\n}\n" + }, + "@openzeppelin/contracts-upgradeable/security/ReentrancyGuardUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (security/ReentrancyGuard.sol)\n\npragma solidity ^0.8.0;\nimport \"../proxy/utils/Initializable.sol\";\n\n/**\n * @dev Contract module that helps prevent reentrant calls to a function.\n *\n * Inheriting from `ReentrancyGuard` will make the {nonReentrant} modifier\n * available, which can be applied to functions to make sure there are no nested\n * (reentrant) calls to them.\n *\n * Note that because there is a single `nonReentrant` guard, functions marked as\n * `nonReentrant` may not call one another. This can be worked around by making\n * those functions `private`, and then adding `external` `nonReentrant` entry\n * points to them.\n *\n * TIP: If you would like to learn more about reentrancy and alternative ways\n * to protect against it, check out our blog post\n * https://blog.openzeppelin.com/reentrancy-after-istanbul/[Reentrancy After Istanbul].\n */\nabstract contract ReentrancyGuardUpgradeable is Initializable {\n // Booleans are more expensive than uint256 or any type that takes up a full\n // word because each write operation emits an extra SLOAD to first read the\n // slot's contents, replace the bits taken up by the boolean, and then write\n // back. This is the compiler's defense against contract upgrades and\n // pointer aliasing, and it cannot be disabled.\n\n // The values being non-zero value makes deployment a bit more expensive,\n // but in exchange the refund on every call to nonReentrant will be lower in\n // amount. Since refunds are capped to a percentage of the total\n // transaction's gas, it is best to keep them low in cases like this one, to\n // increase the likelihood of the full refund coming into effect.\n uint256 private constant _NOT_ENTERED = 1;\n uint256 private constant _ENTERED = 2;\n\n uint256 private _status;\n\n function __ReentrancyGuard_init() internal onlyInitializing {\n __ReentrancyGuard_init_unchained();\n }\n\n function __ReentrancyGuard_init_unchained() internal onlyInitializing {\n _status = _NOT_ENTERED;\n }\n\n /**\n * @dev Prevents a contract from calling itself, directly or indirectly.\n * Calling a `nonReentrant` function from another `nonReentrant`\n * function is not supported. It is possible to prevent this from happening\n * by making the `nonReentrant` function external, and making it call a\n * `private` function that does the actual work.\n */\n modifier nonReentrant() {\n // On the first call to nonReentrant, _notEntered will be true\n require(_status != _ENTERED, \"ReentrancyGuard: reentrant call\");\n\n // Any calls to nonReentrant after this point will fail\n _status = _ENTERED;\n\n _;\n\n // By storing the original value once again, a refund is triggered (see\n // https://eips.ethereum.org/EIPS/eip-2200)\n _status = _NOT_ENTERED;\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[49] private __gap;\n}\n" + }, + "@openzeppelin/contracts-upgradeable/token/ERC20/extensions/draft-IERC20PermitUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (token/ERC20/extensions/draft-IERC20Permit.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Interface of the ERC20 Permit extension allowing approvals to be made via signatures, as defined in\n * https://eips.ethereum.org/EIPS/eip-2612[EIP-2612].\n *\n * Adds the {permit} method, which can be used to change an account's ERC20 allowance (see {IERC20-allowance}) by\n * presenting a message signed by the account. By not relying on {IERC20-approve}, the token holder account doesn't\n * need to send a transaction, and thus is not required to hold Ether at all.\n */\ninterface IERC20PermitUpgradeable {\n /**\n * @dev Sets `value` as the allowance of `spender` over ``owner``'s tokens,\n * given ``owner``'s signed approval.\n *\n * IMPORTANT: The same issues {IERC20-approve} has related to transaction\n * ordering also apply here.\n *\n * Emits an {Approval} event.\n *\n * Requirements:\n *\n * - `spender` cannot be the zero address.\n * - `deadline` must be a timestamp in the future.\n * - `v`, `r` and `s` must be a valid `secp256k1` signature from `owner`\n * over the EIP712-formatted function arguments.\n * - the signature must use ``owner``'s current nonce (see {nonces}).\n *\n * For more information on the signature format, see the\n * https://eips.ethereum.org/EIPS/eip-2612#specification[relevant EIP\n * section].\n */\n function permit(\n address owner,\n address spender,\n uint256 value,\n uint256 deadline,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) external;\n\n /**\n * @dev Returns the current nonce for `owner`. This value must be\n * included whenever a signature is generated for {permit}.\n *\n * Every successful call to {permit} increases ``owner``'s nonce by one. This\n * prevents a signature from being used multiple times.\n */\n function nonces(address owner) external view returns (uint256);\n\n /**\n * @dev Returns the domain separator used in the encoding of the signature for {permit}, as defined by {EIP712}.\n */\n // solhint-disable-next-line func-name-mixedcase\n function DOMAIN_SEPARATOR() external view returns (bytes32);\n}\n" + }, + "@openzeppelin/contracts-upgradeable/token/ERC20/IERC20Upgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.6.0) (token/ERC20/IERC20.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Interface of the ERC20 standard as defined in the EIP.\n */\ninterface IERC20Upgradeable {\n /**\n * @dev Emitted when `value` tokens are moved from one account (`from`) to\n * another (`to`).\n *\n * Note that `value` may be zero.\n */\n event Transfer(address indexed from, address indexed to, uint256 value);\n\n /**\n * @dev Emitted when the allowance of a `spender` for an `owner` is set by\n * a call to {approve}. `value` is the new allowance.\n */\n event Approval(address indexed owner, address indexed spender, uint256 value);\n\n /**\n * @dev Returns the amount of tokens in existence.\n */\n function totalSupply() external view returns (uint256);\n\n /**\n * @dev Returns the amount of tokens owned by `account`.\n */\n function balanceOf(address account) external view returns (uint256);\n\n /**\n * @dev Moves `amount` tokens from the caller's account to `to`.\n *\n * Returns a boolean value indicating whether the operation succeeded.\n *\n * Emits a {Transfer} event.\n */\n function transfer(address to, uint256 amount) external returns (bool);\n\n /**\n * @dev Returns the remaining number of tokens that `spender` will be\n * allowed to spend on behalf of `owner` through {transferFrom}. This is\n * zero by default.\n *\n * This value changes when {approve} or {transferFrom} are called.\n */\n function allowance(address owner, address spender) external view returns (uint256);\n\n /**\n * @dev Sets `amount` as the allowance of `spender` over the caller's tokens.\n *\n * Returns a boolean value indicating whether the operation succeeded.\n *\n * IMPORTANT: Beware that changing an allowance with this method brings the risk\n * that someone may use both the old and the new allowance by unfortunate\n * transaction ordering. One possible solution to mitigate this race\n * condition is to first reduce the spender's allowance to 0 and set the\n * desired value afterwards:\n * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729\n *\n * Emits an {Approval} event.\n */\n function approve(address spender, uint256 amount) external returns (bool);\n\n /**\n * @dev Moves `amount` tokens from `from` to `to` using the\n * allowance mechanism. `amount` is then deducted from the caller's\n * allowance.\n *\n * Returns a boolean value indicating whether the operation succeeded.\n *\n * Emits a {Transfer} event.\n */\n function transferFrom(\n address from,\n address to,\n uint256 amount\n ) external returns (bool);\n}\n" + }, + "@openzeppelin/contracts-upgradeable/token/ERC721/extensions/IERC721MetadataUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (token/ERC721/extensions/IERC721Metadata.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../IERC721Upgradeable.sol\";\n\n/**\n * @title ERC-721 Non-Fungible Token Standard, optional metadata extension\n * @dev See https://eips.ethereum.org/EIPS/eip-721\n */\ninterface IERC721MetadataUpgradeable is IERC721Upgradeable {\n /**\n * @dev Returns the token collection name.\n */\n function name() external view returns (string memory);\n\n /**\n * @dev Returns the token collection symbol.\n */\n function symbol() external view returns (string memory);\n\n /**\n * @dev Returns the Uniform Resource Identifier (URI) for `tokenId` token.\n */\n function tokenURI(uint256 tokenId) external view returns (string memory);\n}\n" + }, + "@openzeppelin/contracts-upgradeable/token/ERC721/IERC721ReceiverUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.6.0) (token/ERC721/IERC721Receiver.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @title ERC721 token receiver interface\n * @dev Interface for any contract that wants to support safeTransfers\n * from ERC721 asset contracts.\n */\ninterface IERC721ReceiverUpgradeable {\n /**\n * @dev Whenever an {IERC721} `tokenId` token is transferred to this contract via {IERC721-safeTransferFrom}\n * by `operator` from `from`, this function is called.\n *\n * It must return its Solidity selector to confirm the token transfer.\n * If any other value is returned or the interface is not implemented by the recipient, the transfer will be reverted.\n *\n * The selector can be obtained in Solidity with `IERC721Receiver.onERC721Received.selector`.\n */\n function onERC721Received(\n address operator,\n address from,\n uint256 tokenId,\n bytes calldata data\n ) external returns (bytes4);\n}\n" + }, + "@openzeppelin/contracts-upgradeable/token/ERC721/IERC721Upgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (token/ERC721/IERC721.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../../utils/introspection/IERC165Upgradeable.sol\";\n\n/**\n * @dev Required interface of an ERC721 compliant contract.\n */\ninterface IERC721Upgradeable is IERC165Upgradeable {\n /**\n * @dev Emitted when `tokenId` token is transferred from `from` to `to`.\n */\n event Transfer(address indexed from, address indexed to, uint256 indexed tokenId);\n\n /**\n * @dev Emitted when `owner` enables `approved` to manage the `tokenId` token.\n */\n event Approval(address indexed owner, address indexed approved, uint256 indexed tokenId);\n\n /**\n * @dev Emitted when `owner` enables or disables (`approved`) `operator` to manage all of its assets.\n */\n event ApprovalForAll(address indexed owner, address indexed operator, bool approved);\n\n /**\n * @dev Returns the number of tokens in ``owner``'s account.\n */\n function balanceOf(address owner) external view returns (uint256 balance);\n\n /**\n * @dev Returns the owner of the `tokenId` token.\n *\n * Requirements:\n *\n * - `tokenId` must exist.\n */\n function ownerOf(uint256 tokenId) external view returns (address owner);\n\n /**\n * @dev Safely transfers `tokenId` token from `from` to `to`.\n *\n * Requirements:\n *\n * - `from` cannot be the zero address.\n * - `to` cannot be the zero address.\n * - `tokenId` token must exist and be owned by `from`.\n * - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}.\n * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.\n *\n * Emits a {Transfer} event.\n */\n function safeTransferFrom(\n address from,\n address to,\n uint256 tokenId,\n bytes calldata data\n ) external;\n\n /**\n * @dev Safely transfers `tokenId` token from `from` to `to`, checking first that contract recipients\n * are aware of the ERC721 protocol to prevent tokens from being forever locked.\n *\n * Requirements:\n *\n * - `from` cannot be the zero address.\n * - `to` cannot be the zero address.\n * - `tokenId` token must exist and be owned by `from`.\n * - If the caller is not `from`, it must have been allowed to move this token by either {approve} or {setApprovalForAll}.\n * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.\n *\n * Emits a {Transfer} event.\n */\n function safeTransferFrom(\n address from,\n address to,\n uint256 tokenId\n ) external;\n\n /**\n * @dev Transfers `tokenId` token from `from` to `to`.\n *\n * WARNING: Usage of this method is discouraged, use {safeTransferFrom} whenever possible.\n *\n * Requirements:\n *\n * - `from` cannot be the zero address.\n * - `to` cannot be the zero address.\n * - `tokenId` token must be owned by `from`.\n * - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}.\n *\n * Emits a {Transfer} event.\n */\n function transferFrom(\n address from,\n address to,\n uint256 tokenId\n ) external;\n\n /**\n * @dev Gives permission to `to` to transfer `tokenId` token to another account.\n * The approval is cleared when the token is transferred.\n *\n * Only a single account can be approved at a time, so approving the zero address clears previous approvals.\n *\n * Requirements:\n *\n * - The caller must own the token or be an approved operator.\n * - `tokenId` must exist.\n *\n * Emits an {Approval} event.\n */\n function approve(address to, uint256 tokenId) external;\n\n /**\n * @dev Approve or remove `operator` as an operator for the caller.\n * Operators can call {transferFrom} or {safeTransferFrom} for any token owned by the caller.\n *\n * Requirements:\n *\n * - The `operator` cannot be the caller.\n *\n * Emits an {ApprovalForAll} event.\n */\n function setApprovalForAll(address operator, bool _approved) external;\n\n /**\n * @dev Returns the account approved for `tokenId` token.\n *\n * Requirements:\n *\n * - `tokenId` must exist.\n */\n function getApproved(uint256 tokenId) external view returns (address operator);\n\n /**\n * @dev Returns if the `operator` is allowed to manage all of the assets of `owner`.\n *\n * See {setApprovalForAll}\n */\n function isApprovedForAll(address owner, address operator) external view returns (bool);\n}\n" + }, + "@openzeppelin/contracts-upgradeable/utils/AddressUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (utils/Address.sol)\n\npragma solidity ^0.8.1;\n\n/**\n * @dev Collection of functions related to the address type\n */\nlibrary AddressUpgradeable {\n /**\n * @dev Returns true if `account` is a contract.\n *\n * [IMPORTANT]\n * ====\n * It is unsafe to assume that an address for which this function returns\n * false is an externally-owned account (EOA) and not a contract.\n *\n * Among others, `isContract` will return false for the following\n * types of addresses:\n *\n * - an externally-owned account\n * - a contract in construction\n * - an address where a contract will be created\n * - an address where a contract lived, but was destroyed\n * ====\n *\n * [IMPORTANT]\n * ====\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\n *\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\n * constructor.\n * ====\n */\n function isContract(address account) internal view returns (bool) {\n // This method relies on extcodesize/address.code.length, which returns 0\n // for contracts in construction, since the code is only stored at the end\n // of the constructor execution.\n\n return account.code.length > 0;\n }\n\n /**\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\n * `recipient`, forwarding all available gas and reverting on errors.\n *\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\n * imposed by `transfer`, making them unable to receive funds via\n * `transfer`. {sendValue} removes this limitation.\n *\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\n *\n * IMPORTANT: because control is transferred to `recipient`, care must be\n * taken to not create reentrancy vulnerabilities. Consider using\n * {ReentrancyGuard} or the\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\n */\n function sendValue(address payable recipient, uint256 amount) internal {\n require(address(this).balance >= amount, \"Address: insufficient balance\");\n\n (bool success, ) = recipient.call{value: amount}(\"\");\n require(success, \"Address: unable to send value, recipient may have reverted\");\n }\n\n /**\n * @dev Performs a Solidity function call using a low level `call`. A\n * plain `call` is an unsafe replacement for a function call: use this\n * function instead.\n *\n * If `target` reverts with a revert reason, it is bubbled up by this\n * function (like regular Solidity function calls).\n *\n * Returns the raw returned data. To convert to the expected return value,\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\n *\n * Requirements:\n *\n * - `target` must be a contract.\n * - calling `target` with `data` must not revert.\n *\n * _Available since v3.1._\n */\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionCall(target, data, \"Address: low-level call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\n * `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, 0, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but also transferring `value` wei to `target`.\n *\n * Requirements:\n *\n * - the calling contract must have an ETH balance of at least `value`.\n * - the called Solidity function must be `payable`.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, value, \"Address: low-level call with value failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\n * with `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(address(this).balance >= value, \"Address: insufficient balance for call\");\n require(isContract(target), \"Address: call to non-contract\");\n\n (bool success, bytes memory returndata) = target.call{value: value}(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\n return functionStaticCall(target, data, \"Address: low-level static call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal view returns (bytes memory) {\n require(isContract(target), \"Address: static call to non-contract\");\n\n (bool success, bytes memory returndata) = target.staticcall(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the\n * revert reason using the provided one.\n *\n * _Available since v4.3._\n */\n function verifyCallResult(\n bool success,\n bytes memory returndata,\n string memory errorMessage\n ) internal pure returns (bytes memory) {\n if (success) {\n return returndata;\n } else {\n // Look for revert reason and bubble it up if present\n if (returndata.length > 0) {\n // The easiest way to bubble the revert reason is using memory via assembly\n /// @solidity memory-safe-assembly\n assembly {\n let returndata_size := mload(returndata)\n revert(add(32, returndata), returndata_size)\n }\n } else {\n revert(errorMessage);\n }\n }\n }\n}\n" + }, + "@openzeppelin/contracts-upgradeable/utils/introspection/IERC165Upgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (utils/introspection/IERC165.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Interface of the ERC165 standard, as defined in the\n * https://eips.ethereum.org/EIPS/eip-165[EIP].\n *\n * Implementers can declare support of contract interfaces, which can then be\n * queried by others ({ERC165Checker}).\n *\n * For an implementation, see {ERC165}.\n */\ninterface IERC165Upgradeable {\n /**\n * @dev Returns true if this contract implements the interface defined by\n * `interfaceId`. See the corresponding\n * https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified[EIP section]\n * to learn more about how these ids are created.\n *\n * This function call must use less than 30 000 gas.\n */\n function supportsInterface(bytes4 interfaceId) external view returns (bool);\n}\n" + }, + "@openzeppelin/contracts/interfaces/IERC721Metadata.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (interfaces/IERC721Metadata.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../token/ERC721/extensions/IERC721Metadata.sol\";\n" + }, + "@openzeppelin/contracts/token/ERC20/extensions/draft-IERC20Permit.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (token/ERC20/extensions/draft-IERC20Permit.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Interface of the ERC20 Permit extension allowing approvals to be made via signatures, as defined in\n * https://eips.ethereum.org/EIPS/eip-2612[EIP-2612].\n *\n * Adds the {permit} method, which can be used to change an account's ERC20 allowance (see {IERC20-allowance}) by\n * presenting a message signed by the account. By not relying on {IERC20-approve}, the token holder account doesn't\n * need to send a transaction, and thus is not required to hold Ether at all.\n */\ninterface IERC20Permit {\n /**\n * @dev Sets `value` as the allowance of `spender` over ``owner``'s tokens,\n * given ``owner``'s signed approval.\n *\n * IMPORTANT: The same issues {IERC20-approve} has related to transaction\n * ordering also apply here.\n *\n * Emits an {Approval} event.\n *\n * Requirements:\n *\n * - `spender` cannot be the zero address.\n * - `deadline` must be a timestamp in the future.\n * - `v`, `r` and `s` must be a valid `secp256k1` signature from `owner`\n * over the EIP712-formatted function arguments.\n * - the signature must use ``owner``'s current nonce (see {nonces}).\n *\n * For more information on the signature format, see the\n * https://eips.ethereum.org/EIPS/eip-2612#specification[relevant EIP\n * section].\n */\n function permit(\n address owner,\n address spender,\n uint256 value,\n uint256 deadline,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) external;\n\n /**\n * @dev Returns the current nonce for `owner`. This value must be\n * included whenever a signature is generated for {permit}.\n *\n * Every successful call to {permit} increases ``owner``'s nonce by one. This\n * prevents a signature from being used multiple times.\n */\n function nonces(address owner) external view returns (uint256);\n\n /**\n * @dev Returns the domain separator used in the encoding of the signature for {permit}, as defined by {EIP712}.\n */\n // solhint-disable-next-line func-name-mixedcase\n function DOMAIN_SEPARATOR() external view returns (bytes32);\n}\n" + }, + "@openzeppelin/contracts/token/ERC20/extensions/IERC20Metadata.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (token/ERC20/extensions/IERC20Metadata.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../IERC20.sol\";\n\n/**\n * @dev Interface for the optional metadata functions from the ERC20 standard.\n *\n * _Available since v4.1._\n */\ninterface IERC20Metadata is IERC20 {\n /**\n * @dev Returns the name of the token.\n */\n function name() external view returns (string memory);\n\n /**\n * @dev Returns the symbol of the token.\n */\n function symbol() external view returns (string memory);\n\n /**\n * @dev Returns the decimals places of the token.\n */\n function decimals() external view returns (uint8);\n}\n" + }, + "@openzeppelin/contracts/token/ERC20/IERC20.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.6.0) (token/ERC20/IERC20.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Interface of the ERC20 standard as defined in the EIP.\n */\ninterface IERC20 {\n /**\n * @dev Emitted when `value` tokens are moved from one account (`from`) to\n * another (`to`).\n *\n * Note that `value` may be zero.\n */\n event Transfer(address indexed from, address indexed to, uint256 value);\n\n /**\n * @dev Emitted when the allowance of a `spender` for an `owner` is set by\n * a call to {approve}. `value` is the new allowance.\n */\n event Approval(address indexed owner, address indexed spender, uint256 value);\n\n /**\n * @dev Returns the amount of tokens in existence.\n */\n function totalSupply() external view returns (uint256);\n\n /**\n * @dev Returns the amount of tokens owned by `account`.\n */\n function balanceOf(address account) external view returns (uint256);\n\n /**\n * @dev Moves `amount` tokens from the caller's account to `to`.\n *\n * Returns a boolean value indicating whether the operation succeeded.\n *\n * Emits a {Transfer} event.\n */\n function transfer(address to, uint256 amount) external returns (bool);\n\n /**\n * @dev Returns the remaining number of tokens that `spender` will be\n * allowed to spend on behalf of `owner` through {transferFrom}. This is\n * zero by default.\n *\n * This value changes when {approve} or {transferFrom} are called.\n */\n function allowance(address owner, address spender) external view returns (uint256);\n\n /**\n * @dev Sets `amount` as the allowance of `spender` over the caller's tokens.\n *\n * Returns a boolean value indicating whether the operation succeeded.\n *\n * IMPORTANT: Beware that changing an allowance with this method brings the risk\n * that someone may use both the old and the new allowance by unfortunate\n * transaction ordering. One possible solution to mitigate this race\n * condition is to first reduce the spender's allowance to 0 and set the\n * desired value afterwards:\n * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729\n *\n * Emits an {Approval} event.\n */\n function approve(address spender, uint256 amount) external returns (bool);\n\n /**\n * @dev Moves `amount` tokens from `from` to `to` using the\n * allowance mechanism. `amount` is then deducted from the caller's\n * allowance.\n *\n * Returns a boolean value indicating whether the operation succeeded.\n *\n * Emits a {Transfer} event.\n */\n function transferFrom(\n address from,\n address to,\n uint256 amount\n ) external returns (bool);\n}\n" + }, + "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (token/ERC20/utils/SafeERC20.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../IERC20.sol\";\nimport \"../extensions/draft-IERC20Permit.sol\";\nimport \"../../../utils/Address.sol\";\n\n/**\n * @title SafeERC20\n * @dev Wrappers around ERC20 operations that throw on failure (when the token\n * contract returns false). Tokens that return no value (and instead revert or\n * throw on failure) are also supported, non-reverting calls are assumed to be\n * successful.\n * To use this library you can add a `using SafeERC20 for IERC20;` statement to your contract,\n * which allows you to call the safe operations as `token.safeTransfer(...)`, etc.\n */\nlibrary SafeERC20 {\n using Address for address;\n\n function safeTransfer(\n IERC20 token,\n address to,\n uint256 value\n ) internal {\n _callOptionalReturn(token, abi.encodeWithSelector(token.transfer.selector, to, value));\n }\n\n function safeTransferFrom(\n IERC20 token,\n address from,\n address to,\n uint256 value\n ) internal {\n _callOptionalReturn(token, abi.encodeWithSelector(token.transferFrom.selector, from, to, value));\n }\n\n /**\n * @dev Deprecated. This function has issues similar to the ones found in\n * {IERC20-approve}, and its usage is discouraged.\n *\n * Whenever possible, use {safeIncreaseAllowance} and\n * {safeDecreaseAllowance} instead.\n */\n function safeApprove(\n IERC20 token,\n address spender,\n uint256 value\n ) internal {\n // safeApprove should only be called when setting an initial allowance,\n // or when resetting it to zero. To increase and decrease it, use\n // 'safeIncreaseAllowance' and 'safeDecreaseAllowance'\n require(\n (value == 0) || (token.allowance(address(this), spender) == 0),\n \"SafeERC20: approve from non-zero to non-zero allowance\"\n );\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, value));\n }\n\n function safeIncreaseAllowance(\n IERC20 token,\n address spender,\n uint256 value\n ) internal {\n uint256 newAllowance = token.allowance(address(this), spender) + value;\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));\n }\n\n function safeDecreaseAllowance(\n IERC20 token,\n address spender,\n uint256 value\n ) internal {\n unchecked {\n uint256 oldAllowance = token.allowance(address(this), spender);\n require(oldAllowance >= value, \"SafeERC20: decreased allowance below zero\");\n uint256 newAllowance = oldAllowance - value;\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));\n }\n }\n\n function safePermit(\n IERC20Permit token,\n address owner,\n address spender,\n uint256 value,\n uint256 deadline,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) internal {\n uint256 nonceBefore = token.nonces(owner);\n token.permit(owner, spender, value, deadline, v, r, s);\n uint256 nonceAfter = token.nonces(owner);\n require(nonceAfter == nonceBefore + 1, \"SafeERC20: permit did not succeed\");\n }\n\n /**\n * @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement\n * on the return value: the return value is optional (but if data is returned, it must not be false).\n * @param token The token targeted by the call.\n * @param data The call data (encoded using abi.encode or one of its variants).\n */\n function _callOptionalReturn(IERC20 token, bytes memory data) private {\n // We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since\n // we're implementing it ourselves. We use {Address.functionCall} to perform this call, which verifies that\n // the target address contains contract code and also asserts for success in the low-level call.\n\n bytes memory returndata = address(token).functionCall(data, \"SafeERC20: low-level call failed\");\n if (returndata.length > 0) {\n // Return data is optional\n require(abi.decode(returndata, (bool)), \"SafeERC20: ERC20 operation did not succeed\");\n }\n }\n}\n" + }, + "@openzeppelin/contracts/token/ERC721/extensions/IERC721Metadata.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (token/ERC721/extensions/IERC721Metadata.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../IERC721.sol\";\n\n/**\n * @title ERC-721 Non-Fungible Token Standard, optional metadata extension\n * @dev See https://eips.ethereum.org/EIPS/eip-721\n */\ninterface IERC721Metadata is IERC721 {\n /**\n * @dev Returns the token collection name.\n */\n function name() external view returns (string memory);\n\n /**\n * @dev Returns the token collection symbol.\n */\n function symbol() external view returns (string memory);\n\n /**\n * @dev Returns the Uniform Resource Identifier (URI) for `tokenId` token.\n */\n function tokenURI(uint256 tokenId) external view returns (string memory);\n}\n" + }, + "@openzeppelin/contracts/token/ERC721/IERC721.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (token/ERC721/IERC721.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../../utils/introspection/IERC165.sol\";\n\n/**\n * @dev Required interface of an ERC721 compliant contract.\n */\ninterface IERC721 is IERC165 {\n /**\n * @dev Emitted when `tokenId` token is transferred from `from` to `to`.\n */\n event Transfer(address indexed from, address indexed to, uint256 indexed tokenId);\n\n /**\n * @dev Emitted when `owner` enables `approved` to manage the `tokenId` token.\n */\n event Approval(address indexed owner, address indexed approved, uint256 indexed tokenId);\n\n /**\n * @dev Emitted when `owner` enables or disables (`approved`) `operator` to manage all of its assets.\n */\n event ApprovalForAll(address indexed owner, address indexed operator, bool approved);\n\n /**\n * @dev Returns the number of tokens in ``owner``'s account.\n */\n function balanceOf(address owner) external view returns (uint256 balance);\n\n /**\n * @dev Returns the owner of the `tokenId` token.\n *\n * Requirements:\n *\n * - `tokenId` must exist.\n */\n function ownerOf(uint256 tokenId) external view returns (address owner);\n\n /**\n * @dev Safely transfers `tokenId` token from `from` to `to`.\n *\n * Requirements:\n *\n * - `from` cannot be the zero address.\n * - `to` cannot be the zero address.\n * - `tokenId` token must exist and be owned by `from`.\n * - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}.\n * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.\n *\n * Emits a {Transfer} event.\n */\n function safeTransferFrom(\n address from,\n address to,\n uint256 tokenId,\n bytes calldata data\n ) external;\n\n /**\n * @dev Safely transfers `tokenId` token from `from` to `to`, checking first that contract recipients\n * are aware of the ERC721 protocol to prevent tokens from being forever locked.\n *\n * Requirements:\n *\n * - `from` cannot be the zero address.\n * - `to` cannot be the zero address.\n * - `tokenId` token must exist and be owned by `from`.\n * - If the caller is not `from`, it must have been allowed to move this token by either {approve} or {setApprovalForAll}.\n * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.\n *\n * Emits a {Transfer} event.\n */\n function safeTransferFrom(\n address from,\n address to,\n uint256 tokenId\n ) external;\n\n /**\n * @dev Transfers `tokenId` token from `from` to `to`.\n *\n * WARNING: Usage of this method is discouraged, use {safeTransferFrom} whenever possible.\n *\n * Requirements:\n *\n * - `from` cannot be the zero address.\n * - `to` cannot be the zero address.\n * - `tokenId` token must be owned by `from`.\n * - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}.\n *\n * Emits a {Transfer} event.\n */\n function transferFrom(\n address from,\n address to,\n uint256 tokenId\n ) external;\n\n /**\n * @dev Gives permission to `to` to transfer `tokenId` token to another account.\n * The approval is cleared when the token is transferred.\n *\n * Only a single account can be approved at a time, so approving the zero address clears previous approvals.\n *\n * Requirements:\n *\n * - The caller must own the token or be an approved operator.\n * - `tokenId` must exist.\n *\n * Emits an {Approval} event.\n */\n function approve(address to, uint256 tokenId) external;\n\n /**\n * @dev Approve or remove `operator` as an operator for the caller.\n * Operators can call {transferFrom} or {safeTransferFrom} for any token owned by the caller.\n *\n * Requirements:\n *\n * - The `operator` cannot be the caller.\n *\n * Emits an {ApprovalForAll} event.\n */\n function setApprovalForAll(address operator, bool _approved) external;\n\n /**\n * @dev Returns the account approved for `tokenId` token.\n *\n * Requirements:\n *\n * - `tokenId` must exist.\n */\n function getApproved(uint256 tokenId) external view returns (address operator);\n\n /**\n * @dev Returns if the `operator` is allowed to manage all of the assets of `owner`.\n *\n * See {setApprovalForAll}\n */\n function isApprovedForAll(address owner, address operator) external view returns (bool);\n}\n" + }, + "@openzeppelin/contracts/utils/Address.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (utils/Address.sol)\n\npragma solidity ^0.8.1;\n\n/**\n * @dev Collection of functions related to the address type\n */\nlibrary Address {\n /**\n * @dev Returns true if `account` is a contract.\n *\n * [IMPORTANT]\n * ====\n * It is unsafe to assume that an address for which this function returns\n * false is an externally-owned account (EOA) and not a contract.\n *\n * Among others, `isContract` will return false for the following\n * types of addresses:\n *\n * - an externally-owned account\n * - a contract in construction\n * - an address where a contract will be created\n * - an address where a contract lived, but was destroyed\n * ====\n *\n * [IMPORTANT]\n * ====\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\n *\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\n * constructor.\n * ====\n */\n function isContract(address account) internal view returns (bool) {\n // This method relies on extcodesize/address.code.length, which returns 0\n // for contracts in construction, since the code is only stored at the end\n // of the constructor execution.\n\n return account.code.length > 0;\n }\n\n /**\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\n * `recipient`, forwarding all available gas and reverting on errors.\n *\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\n * imposed by `transfer`, making them unable to receive funds via\n * `transfer`. {sendValue} removes this limitation.\n *\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\n *\n * IMPORTANT: because control is transferred to `recipient`, care must be\n * taken to not create reentrancy vulnerabilities. Consider using\n * {ReentrancyGuard} or the\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\n */\n function sendValue(address payable recipient, uint256 amount) internal {\n require(address(this).balance >= amount, \"Address: insufficient balance\");\n\n (bool success, ) = recipient.call{value: amount}(\"\");\n require(success, \"Address: unable to send value, recipient may have reverted\");\n }\n\n /**\n * @dev Performs a Solidity function call using a low level `call`. A\n * plain `call` is an unsafe replacement for a function call: use this\n * function instead.\n *\n * If `target` reverts with a revert reason, it is bubbled up by this\n * function (like regular Solidity function calls).\n *\n * Returns the raw returned data. To convert to the expected return value,\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\n *\n * Requirements:\n *\n * - `target` must be a contract.\n * - calling `target` with `data` must not revert.\n *\n * _Available since v3.1._\n */\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionCall(target, data, \"Address: low-level call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\n * `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, 0, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but also transferring `value` wei to `target`.\n *\n * Requirements:\n *\n * - the calling contract must have an ETH balance of at least `value`.\n * - the called Solidity function must be `payable`.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, value, \"Address: low-level call with value failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\n * with `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(address(this).balance >= value, \"Address: insufficient balance for call\");\n require(isContract(target), \"Address: call to non-contract\");\n\n (bool success, bytes memory returndata) = target.call{value: value}(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\n return functionStaticCall(target, data, \"Address: low-level static call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal view returns (bytes memory) {\n require(isContract(target), \"Address: static call to non-contract\");\n\n (bool success, bytes memory returndata) = target.staticcall(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a delegate call.\n *\n * _Available since v3.4._\n */\n function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionDelegateCall(target, data, \"Address: low-level delegate call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a delegate call.\n *\n * _Available since v3.4._\n */\n function functionDelegateCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(isContract(target), \"Address: delegate call to non-contract\");\n\n (bool success, bytes memory returndata) = target.delegatecall(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the\n * revert reason using the provided one.\n *\n * _Available since v4.3._\n */\n function verifyCallResult(\n bool success,\n bytes memory returndata,\n string memory errorMessage\n ) internal pure returns (bytes memory) {\n if (success) {\n return returndata;\n } else {\n // Look for revert reason and bubble it up if present\n if (returndata.length > 0) {\n // The easiest way to bubble the revert reason is using memory via assembly\n /// @solidity memory-safe-assembly\n assembly {\n let returndata_size := mload(returndata)\n revert(add(32, returndata), returndata_size)\n }\n } else {\n revert(errorMessage);\n }\n }\n }\n}\n" + }, + "@openzeppelin/contracts/utils/introspection/IERC165.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (utils/introspection/IERC165.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Interface of the ERC165 standard, as defined in the\n * https://eips.ethereum.org/EIPS/eip-165[EIP].\n *\n * Implementers can declare support of contract interfaces, which can then be\n * queried by others ({ERC165Checker}).\n *\n * For an implementation, see {ERC165}.\n */\ninterface IERC165 {\n /**\n * @dev Returns true if this contract implements the interface defined by\n * `interfaceId`. See the corresponding\n * https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified[EIP section]\n * to learn more about how these ids are created.\n *\n * This function call must use less than 30 000 gas.\n */\n function supportsInterface(bytes4 interfaceId) external view returns (bool);\n}\n" + }, + "contracts/interfaces/external/IERC1271.sol": { + "content": "// SPDX-License-Identifier: GPL-2.0-or-later\npragma solidity ^0.8.12;\n\n/// @title Interface for verifying contract-based account signatures\n/// @notice Interface that verifies provided signature for the data\n/// @dev Interface defined by EIP-1271\ninterface IERC1271 {\n /// @notice Returns whether the provided signature is valid for the provided data\n /// @dev MUST return the bytes4 magic value 0x1626ba7e when function passes.\n /// MUST NOT modify state (using STATICCALL for solc < 0.5, view modifier for solc > 0.5).\n /// MUST allow external calls.\n /// @param hash Hash of the data to be signed\n /// @param signature Signature byte array associated with _data\n /// @return magicValue The bytes4 magic value 0x1626ba7e\n function isValidSignature(bytes32 hash, bytes memory signature) external view returns (bytes4 magicValue);\n}\n" + }, + "contracts/interfaces/governance/IVeBoostProxy.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\n/// @title IVeBoostProxy\n/// @author Angle Labs, Inc.\n/// @notice Interface for the `VeBoostProxy` contract\n/// @dev This interface only contains functions of the contract which are called by other contracts\n/// of this module\n/// @dev The `veBoostProxy` contract used by Angle is a full fork of Curve Finance implementation\ninterface IVeBoostProxy {\n /// @notice Reads the adjusted veANGLE balance of an address (adjusted by delegation)\n //solhint-disable-next-line\n function adjusted_balance_of(address) external view returns (uint256);\n}\n" + }, + "contracts/interfaces/IAgToken.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\nimport \"@openzeppelin/contracts-upgradeable/token/ERC20/IERC20Upgradeable.sol\";\n\n/// @title IAgToken\n/// @author Angle Labs, Inc.\n/// @notice Interface for the stablecoins `AgToken` contracts\n/// @dev This interface only contains functions of the `AgToken` contract which are called by other contracts\n/// of this module or of the first module of the Angle Protocol\ninterface IAgToken is IERC20Upgradeable {\n // ======================= Minter Role Only Functions ===========================\n\n /// @notice Lets the `StableMaster` contract or another whitelisted contract mint agTokens\n /// @param account Address to mint to\n /// @param amount Amount to mint\n /// @dev The contracts allowed to issue agTokens are the `StableMaster` contract, `VaultManager` contracts\n /// associated to this stablecoin as well as the flash loan module (if activated) and potentially contracts\n /// whitelisted by governance\n function mint(address account, uint256 amount) external;\n\n /// @notice Burns `amount` tokens from a `burner` address after being asked to by `sender`\n /// @param amount Amount of tokens to burn\n /// @param burner Address to burn from\n /// @param sender Address which requested the burn from `burner`\n /// @dev This method is to be called by a contract with the minter right after being requested\n /// to do so by a `sender` address willing to burn tokens from another `burner` address\n /// @dev The method checks the allowance between the `sender` and the `burner`\n function burnFrom(uint256 amount, address burner, address sender) external;\n\n /// @notice Burns `amount` tokens from a `burner` address\n /// @param amount Amount of tokens to burn\n /// @param burner Address to burn from\n /// @dev This method is to be called by a contract with a minter right on the AgToken after being\n /// requested to do so by an address willing to burn tokens from its address\n function burnSelf(uint256 amount, address burner) external;\n\n // ========================= Treasury Only Functions ===========================\n\n /// @notice Adds a minter in the contract\n /// @param minter Minter address to add\n /// @dev Zero address checks are performed directly in the `Treasury` contract\n function addMinter(address minter) external;\n\n /// @notice Removes a minter from the contract\n /// @param minter Minter address to remove\n /// @dev This function can also be called by a minter wishing to revoke itself\n function removeMinter(address minter) external;\n\n /// @notice Sets a new treasury contract\n /// @param _treasury New treasury address\n function setTreasury(address _treasury) external;\n\n // ========================= External functions ================================\n\n /// @notice Checks whether an address has the right to mint agTokens\n /// @param minter Address for which the minting right should be checked\n /// @return Whether the address has the right to mint agTokens or not\n function isMinter(address minter) external view returns (bool);\n\n /// @notice Get the associated treasury\n function treasury() external view returns (address);\n}\n" + }, + "contracts/interfaces/ICoreBorrow.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\n/// @title ICoreBorrow\n/// @author Angle Labs, Inc.\n/// @notice Interface for the `CoreBorrow` contract\n/// @dev This interface only contains functions of the `CoreBorrow` contract which are called by other contracts\n/// of this module\ninterface ICoreBorrow {\n /// @notice Checks if an address corresponds to a treasury of a stablecoin with a flash loan\n /// module initialized on it\n /// @param treasury Address to check\n /// @return Whether the address has the `FLASHLOANER_TREASURY_ROLE` or not\n function isFlashLoanerTreasury(address treasury) external view returns (bool);\n\n /// @notice Checks whether an address is governor of the Angle Protocol or not\n /// @param admin Address to check\n /// @return Whether the address has the `GOVERNOR_ROLE` or not\n function isGovernor(address admin) external view returns (bool);\n\n /// @notice Checks whether an address is governor or a guardian of the Angle Protocol or not\n /// @param admin Address to check\n /// @return Whether the address has the `GUARDIAN_ROLE` or not\n /// @dev Governance should make sure when adding a governor to also give this governor the guardian\n /// role by calling the `addGovernor` function\n function isGovernorOrGuardian(address admin) external view returns (bool);\n}\n" + }, + "contracts/interfaces/IFlashAngle.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\nimport \"./IAgToken.sol\";\nimport \"./ICoreBorrow.sol\";\n\n/// @title IFlashAngle\n/// @author Angle Labs, Inc.\n/// @notice Interface for the `FlashAngle` contract\n/// @dev This interface only contains functions of the contract which are called by other contracts\n/// of this module\ninterface IFlashAngle {\n /// @notice Reference to the `CoreBorrow` contract managing the FlashLoan module\n function core() external view returns (ICoreBorrow);\n\n /// @notice Sends the fees taken from flash loans to the treasury contract associated to the stablecoin\n /// @param stablecoin Stablecoin from which profits should be sent\n /// @return balance Amount of profits sent\n /// @dev This function can only be called by the treasury contract\n function accrueInterestToTreasury(IAgToken stablecoin) external returns (uint256 balance);\n\n /// @notice Adds support for a stablecoin\n /// @param _treasury Treasury associated to the stablecoin to add support for\n /// @dev This function can only be called by the `CoreBorrow` contract\n function addStablecoinSupport(address _treasury) external;\n\n /// @notice Removes support for a stablecoin\n /// @param _treasury Treasury associated to the stablecoin to remove support for\n /// @dev This function can only be called by the `CoreBorrow` contract\n function removeStablecoinSupport(address _treasury) external;\n\n /// @notice Sets a new core contract\n /// @param _core Core contract address to set\n /// @dev This function can only be called by the `CoreBorrow` contract\n function setCore(address _core) external;\n}\n" + }, + "contracts/interfaces/IOracle.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\nimport \"./ITreasury.sol\";\nimport \"@chainlink/contracts/src/v0.8/interfaces/AggregatorV3Interface.sol\";\n\n/// @title IOracle\n/// @author Angle Labs, Inc.\n/// @notice Interface for the `Oracle` contract\n/// @dev This interface only contains functions of the contract which are called by other contracts\n/// of this module\ninterface IOracle {\n /// @notice Reads the rate from the Chainlink circuit and other data provided\n /// @return quoteAmount The current rate between the in-currency and out-currency in the base\n /// of the out currency\n /// @dev For instance if the out currency is EUR (and hence agEUR), then the base of the returned\n /// value is 10**18\n function read() external view returns (uint256);\n\n /// @notice Changes the treasury contract\n /// @param _treasury Address of the new treasury contract\n /// @dev This function can be called by an approved `VaultManager` contract which can call\n /// this function after being requested to do so by a `treasury` contract\n /// @dev In some situations (like reactor contracts), the `VaultManager` may not directly be linked\n /// to the `oracle` contract and as such we may need governors to be able to call this function as well\n function setTreasury(address _treasury) external;\n\n /// @notice Reference to the `treasury` contract handling this `VaultManager`\n function treasury() external view returns (ITreasury treasury);\n\n /// @notice Array with the list of Chainlink feeds in the order in which they are read\n function circuitChainlink() external view returns (AggregatorV3Interface[] memory);\n}\n" + }, + "contracts/interfaces/ISwapper.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\nimport \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\n\n/// @title ISwapper\n/// @author Angle Labs, Inc.\n/// @notice Interface for Swapper contracts\n/// @dev This interface defines the key functions `Swapper` contracts should have when interacting with\n/// Angle\ninterface ISwapper {\n /// @notice Notifies a contract that an address should be given `outToken` from `inToken`\n /// @param inToken Address of the token received\n /// @param outToken Address of the token to obtain\n /// @param outTokenRecipient Address to which the outToken should be sent\n /// @param outTokenOwed Minimum amount of outToken the `outTokenRecipient` address should have at the end of the call\n /// @param inTokenObtained Amount of collateral obtained by a related address prior\n /// to the call to this function\n /// @param data Extra data needed (to encode Uniswap swaps for instance)\n function swap(\n IERC20 inToken,\n IERC20 outToken,\n address outTokenRecipient,\n uint256 outTokenOwed,\n uint256 inTokenObtained,\n bytes calldata data\n ) external;\n}\n" + }, + "contracts/interfaces/ITreasury.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\nimport \"./IAgToken.sol\";\nimport \"./ICoreBorrow.sol\";\nimport \"./IFlashAngle.sol\";\n\n/// @title ITreasury\n/// @author Angle Labs, Inc.\n/// @notice Interface for the `Treasury` contract\n/// @dev This interface only contains functions of the `Treasury` which are called by other contracts\n/// of this module\ninterface ITreasury {\n /// @notice Stablecoin handled by this `treasury` contract\n function stablecoin() external view returns (IAgToken);\n\n /// @notice Checks whether a given address has the governor role\n /// @param admin Address to check\n /// @return Whether the address has the governor role\n /// @dev Access control is only kept in the `CoreBorrow` contract\n function isGovernor(address admin) external view returns (bool);\n\n /// @notice Checks whether a given address has the guardian or the governor role\n /// @param admin Address to check\n /// @return Whether the address has the guardian or the governor role\n /// @dev Access control is only kept in the `CoreBorrow` contract which means that this function\n /// queries the `CoreBorrow` contract\n function isGovernorOrGuardian(address admin) external view returns (bool);\n\n /// @notice Checks whether a given address has well been initialized in this contract\n /// as a `VaultManager`\n /// @param _vaultManager Address to check\n /// @return Whether the address has been initialized or not\n function isVaultManager(address _vaultManager) external view returns (bool);\n\n /// @notice Sets a new flash loan module for this stablecoin\n /// @param _flashLoanModule Reference to the new flash loan module\n /// @dev This function removes the minting right to the old flash loan module and grants\n /// it to the new module\n function setFlashLoanModule(address _flashLoanModule) external;\n\n /// @notice Gets the vault manager list\n function vaultManagerList(uint256 i) external returns (address);\n}\n" + }, + "contracts/interfaces/IVaultManager.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\nimport \"@openzeppelin/contracts/interfaces/IERC721Metadata.sol\";\nimport \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\nimport \"./ITreasury.sol\";\nimport \"./IOracle.sol\";\n\n// ========================= Key Structs and Enums =============================\n\n/// @notice Parameters associated to a given `VaultManager` contract: these all correspond\n/// to parameters which signification is detailed in the `VaultManagerStorage` file\nstruct VaultParameters {\n uint256 debtCeiling;\n uint64 collateralFactor;\n uint64 targetHealthFactor;\n uint64 interestRate;\n uint64 liquidationSurcharge;\n uint64 maxLiquidationDiscount;\n bool whitelistingActivated;\n uint256 baseBoost;\n}\n\n/// @notice Data stored to track someone's loan (or equivalently called position)\nstruct Vault {\n // Amount of collateral deposited in the vault, in collateral decimals. For example, if the collateral\n // is USDC with 6 decimals, then `collateralAmount` will be in base 10**6\n uint256 collateralAmount;\n // Normalized value of the debt (that is to say of the stablecoins borrowed). It is expressed\n // in the base of Angle stablecoins (i.e. `BASE_TOKENS = 10**18`)\n uint256 normalizedDebt;\n}\n\n/// @notice For a given `vaultID`, this encodes a liquidation opportunity that is to say details about the maximum\n/// amount that could be repaid by liquidating the position\n/// @dev All the values are null in the case of a vault which cannot be liquidated under these conditions\nstruct LiquidationOpportunity {\n // Maximum stablecoin amount that can be repaid upon liquidating the vault\n uint256 maxStablecoinAmountToRepay;\n // Collateral amount given to the person in the case where the maximum amount to repay is given\n uint256 maxCollateralAmountGiven;\n // Threshold value of stablecoin amount to repay: it is ok for a liquidator to repay below threshold,\n // but if this threshold is non null and the liquidator wants to repay more than threshold, it should repay\n // the max stablecoin amount given in this vault\n uint256 thresholdRepayAmount;\n // Discount proposed to the liquidator on the collateral\n uint256 discount;\n // Amount of debt in the vault\n uint256 currentDebt;\n}\n\n/// @notice Data stored during a liquidation process to keep in memory what's due to a liquidator and some\n/// essential data for vaults being liquidated\nstruct LiquidatorData {\n // Current amount of stablecoins the liquidator should give to the contract\n uint256 stablecoinAmountToReceive;\n // Current amount of collateral the contract should give to the liquidator\n uint256 collateralAmountToGive;\n // Bad debt accrued across the liquidation process\n uint256 badDebtFromLiquidation;\n // Oracle value (in stablecoin base) at the time of the liquidation\n uint256 oracleValue;\n // Value of the `interestAccumulator` at the time of the call\n uint256 newInterestAccumulator;\n}\n\n/// @notice Data to track during a series of action the amount to give or receive in stablecoins and collateral\n/// to the caller or associated addresses\nstruct PaymentData {\n // Stablecoin amount the contract should give\n uint256 stablecoinAmountToGive;\n // Stablecoin amount owed to the contract\n uint256 stablecoinAmountToReceive;\n // Collateral amount the contract should give\n uint256 collateralAmountToGive;\n // Collateral amount owed to the contract\n uint256 collateralAmountToReceive;\n}\n\n/// @notice Actions possible when composing calls to the different entry functions proposed\nenum ActionType {\n createVault,\n closeVault,\n addCollateral,\n removeCollateral,\n repayDebt,\n borrow,\n getDebtIn,\n permit\n}\n\n// ========================= Interfaces =============================\n\n/// @title IVaultManagerFunctions\n/// @author Angle Labs, Inc.\n/// @notice Interface for the `VaultManager` contract\n/// @dev This interface only contains functions of the contract which are called by other contracts\n/// of this module (without getters)\ninterface IVaultManagerFunctions {\n /// @notice Accrues interest accumulated across all vaults to the surplus and sends the surplus to the treasury\n /// @return surplusValue Value of the surplus communicated to the `Treasury`\n /// @return badDebtValue Value of the bad debt communicated to the `Treasury`\n /// @dev `surplus` and `badDebt` should be reset to 0 once their current value have been given to the `treasury` contract\n function accrueInterestToTreasury() external returns (uint256 surplusValue, uint256 badDebtValue);\n\n /// @notice Removes debt from a vault after being requested to do so by another `VaultManager` contract\n /// @param vaultID ID of the vault to remove debt from\n /// @param amountStablecoins Amount of stablecoins to remove from the debt: this amount is to be converted to an\n /// internal debt amount\n /// @param senderBorrowFee Borrowing fees from the contract which requested this: this is to make sure that people are not\n /// arbitraging difference in minting fees\n /// @param senderRepayFee Repay fees from the contract which requested this: this is to make sure that people are not arbitraging\n /// differences in repay fees\n /// @dev This function can only be called from a vaultManager registered in the same Treasury\n function getDebtOut(\n uint256 vaultID,\n uint256 amountStablecoins,\n uint256 senderBorrowFee,\n uint256 senderRepayFee\n ) external;\n\n /// @notice Gets the current debt of a vault\n /// @param vaultID ID of the vault to check\n /// @return Debt of the vault\n function getVaultDebt(uint256 vaultID) external view returns (uint256);\n\n /// @notice Gets the total debt across all vaults\n /// @return Total debt across all vaults, taking into account the interest accumulated\n /// over time\n function getTotalDebt() external view returns (uint256);\n\n /// @notice Sets the treasury contract\n /// @param _treasury New treasury contract\n /// @dev All required checks when setting up a treasury contract are performed in the contract\n /// calling this function\n function setTreasury(address _treasury) external;\n\n /// @notice Creates a vault\n /// @param toVault Address for which the va\n /// @return vaultID ID of the vault created\n /// @dev This function just creates the vault without doing any collateral or\n function createVault(address toVault) external returns (uint256);\n\n /// @notice Allows composability between calls to the different entry points of this module. Any user calling\n /// this function can perform any of the allowed actions in the order of their choice\n /// @param actions Set of actions to perform\n /// @param datas Data to be decoded for each action: it can include like the `vaultID` or the `stablecoinAmount` to borrow\n /// @param from Address from which stablecoins will be taken if one action includes burning stablecoins. This address\n /// should either be the `msg.sender` or be approved by the latter\n /// @param to Address to which stablecoins and/or collateral will be sent in case of\n /// @param who Address of the contract to handle in case of repayment of stablecoins from received collateral\n /// @param repayData Data to pass to the repayment contract in case of\n /// @return paymentData Struct containing the accounting changes from the protocol's perspective (like how much of collateral\n /// or how much has been received). Note that the values in the struct are not aggregated and you could have in the output\n /// a positive amount of stablecoins to receive as well as a positive amount of stablecoins to give\n /// @dev This function is optimized to reduce gas cost due to payment from or to the user and that expensive calls\n /// or computations (like `oracleValue`) are done only once\n /// @dev When specifying `vaultID` in `data`, it is important to know that if you specify `vaultID = 0`, it will simply\n /// use the latest `vaultID`. This is the default behavior, and unless you're engaging into some complex protocol actions\n /// it is encouraged to use `vaultID = 0` only when the first action of the batch is `createVault`\n function angle(\n ActionType[] memory actions,\n bytes[] memory datas,\n address from,\n address to,\n address who,\n bytes memory repayData\n ) external returns (PaymentData memory paymentData);\n\n /// @notice This function is a wrapper built on top of the function above. It enables users to interact with the contract\n /// without having to provide `who` and `repayData` parameters\n function angle(\n ActionType[] memory actions,\n bytes[] memory datas,\n address from,\n address to\n ) external returns (PaymentData memory paymentData);\n\n /// @notice Initializes the `VaultManager` contract\n /// @param _treasury Treasury address handling the contract\n /// @param _collateral Collateral supported by this contract\n /// @param _oracle Oracle contract used\n /// @param _symbol Symbol used to define the `VaultManager` name and symbol\n /// @dev The parameters and the oracle are the only elements which could be modified once the\n /// contract has been initialized\n /// @dev For the contract to be fully initialized, governance needs to set the parameters for the liquidation\n /// boost\n function initialize(\n ITreasury _treasury,\n IERC20 _collateral,\n IOracle _oracle,\n VaultParameters calldata params,\n string memory _symbol\n ) external;\n\n /// @notice Minimum amount of debt a vault can have, expressed in `BASE_TOKENS` that is to say the base of the agTokens\n function dust() external view returns (uint256);\n\n /// @notice Pauses external permissionless functions of the contract\n function togglePause() external;\n}\n\n/// @title IVaultManagerStorage\n/// @author Angle Labs, Inc.\n/// @notice Interface for the `VaultManager` contract\n/// @dev This interface contains getters of the contract's public variables used by other contracts\n/// of this module\ninterface IVaultManagerStorage {\n /// @notice Encodes the maximum ratio stablecoin/collateral a vault can have before being liquidated. It's what\n /// determines the minimum collateral ratio of a position\n function collateralFactor() external view returns (uint64);\n\n /// @notice Stablecoin handled by this contract. Another `VaultManager` contract could have\n /// the same rights as this `VaultManager` on the stablecoin contract\n function stablecoin() external view returns (IAgToken);\n\n /// @notice Reference to the `treasury` contract handling this `VaultManager`\n function treasury() external view returns (ITreasury);\n\n /// @notice Oracle contract to get access to the price of the collateral with respect to the stablecoin\n function oracle() external view returns (IOracle);\n\n /// @notice The `interestAccumulator` variable keeps track of the interest that should accrue to the protocol.\n /// The stored value is not necessarily the true value: this one is recomputed every time an action takes place\n /// within the protocol. It is in base `BASE_INTEREST`\n function interestAccumulator() external view returns (uint256);\n\n /// @notice Reference to the collateral handled by this `VaultManager`\n function collateral() external view returns (IERC20);\n\n /// @notice Total normalized amount of stablecoins borrowed, not taking into account the potential bad debt accumulated\n /// This value is expressed in the base of Angle stablecoins (`BASE_TOKENS = 10**18`)\n function totalNormalizedDebt() external view returns (uint256);\n\n /// @notice Maximum amount of stablecoins that can be issued with this contract. It is expressed in `BASE_TOKENS`\n function debtCeiling() external view returns (uint256);\n\n /// @notice Maps a `vaultID` to its data (namely collateral amount and normalized debt)\n function vaultData(uint256 vaultID) external view returns (uint256 collateralAmount, uint256 normalizedDebt);\n\n /// @notice ID of the last vault created. The `vaultIDCount` variables serves as a counter to generate a unique\n /// `vaultID` for each vault: it is like `tokenID` in basic ERC721 contracts\n function vaultIDCount() external view returns (uint256);\n}\n\n/// @title IVaultManager\n/// @author Angle Labs, Inc.\n/// @notice Interface for the `VaultManager` contract\ninterface IVaultManager is IVaultManagerFunctions, IVaultManagerStorage, IERC721Metadata {\n function isApprovedOrOwner(address spender, uint256 vaultID) external view returns (bool);\n}\n\n/// @title IVaultManagerListing\n/// @author Angle Labs, Inc.\n/// @notice Interface for the `VaultManagerListing` contract\ninterface IVaultManagerListing is IVaultManager {\n /// @notice Get the collateral owned by `user` in the contract\n /// @dev This function effectively sums the collateral amounts of all the vaults owned by `user`\n function getUserCollateral(address user) external view returns (uint256);\n}\n" + }, + "contracts/vaultManager/VaultManager.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\n/*\n * █ \n ***** ▓▓▓ \n * ▓▓▓▓▓▓▓ \n * ///. ▓▓▓▓▓▓▓▓▓▓▓▓▓ \n ***** //////// ▓▓▓▓▓▓▓ \n * ///////////// ▓▓▓ \n ▓▓ ////////////////// █ ▓▓ \n ▓▓ ▓▓ /////////////////////// ▓▓ ▓▓ \n ▓▓ ▓▓ //////////////////////////// ▓▓ ▓▓ \n ▓▓ ▓▓ /////////▓▓▓///////▓▓▓///////// ▓▓ ▓▓ \n ▓▓ ,////////////////////////////////////// ▓▓ ▓▓ \n ▓▓ ////////////////////////////////////////// ▓▓ \n ▓▓ //////////////////////▓▓▓▓///////////////////// \n ,//////////////////////////////////////////////////// \n .////////////////////////////////////////////////////////// \n .//////////////////////////██.,//////////////////////////█ \n .//////////////////////████..,./////////////////////██ \n ...////////////////███████.....,.////////////////███ \n ,.,////////////████████ ........,///////////████ \n .,.,//////█████████ ,.......///////████ \n ,..//████████ ........./████ \n ..,██████ .....,███ \n .██ ,.,█ \n \n \n \n ▓▓ ▓▓▓▓▓▓▓▓▓▓ ▓▓▓▓▓▓▓▓▓▓ ▓▓ ▓▓▓▓▓▓▓▓▓▓ \n ▓▓▓▓▓▓ ▓▓▓ ▓▓▓ ▓▓▓ ▓▓ ▓▓ ▓▓▓▓ \n ▓▓▓ ▓▓▓ ▓▓▓ ▓▓▓ ▓▓▓ ▓▓▓ ▓▓ ▓▓▓▓▓ \n ▓▓▓ ▓▓ ▓▓▓ ▓▓▓ ▓▓▓▓▓▓▓▓▓▓ ▓▓▓▓▓▓▓▓▓▓ ▓▓▓▓▓▓▓▓▓▓ \n*/\n\npragma solidity ^0.8.12;\n\nimport \"./VaultManagerPermit.sol\";\n\n/// @title VaultManager\n/// @author Angle Labs, Inc.\n/// @notice This contract allows people to deposit collateral and open up loans of a given AgToken. It handles all the loan\n/// logic (fees and interest rate) as well as the liquidation logic\n/// @dev This implementation only supports non-rebasing ERC20 tokens as collateral\n/// @dev This contract is encoded as a NFT contract\ncontract VaultManager is VaultManagerPermit, IVaultManagerFunctions {\n using SafeERC20 for IERC20;\n using Address for address;\n\n /// @inheritdoc IVaultManagerFunctions\n uint256 public dust;\n\n /// @notice Minimum amount of collateral (in stablecoin value, e.g in `BASE_TOKENS = 10**18`) that can be left\n /// in a vault during a liquidation where the health factor function is decreasing\n uint256 internal _dustCollateral;\n\n /// @notice If the amount of debt of a vault that gets liquidated is below this amount, then the liquidator\n /// can liquidate all the debt of the vault (and not just what's needed to get to the target health factor)\n uint256 public dustLiquidation;\n\n uint256[47] private __gapVaultManager;\n\n /// @inheritdoc IVaultManagerFunctions\n function initialize(\n ITreasury _treasury,\n IERC20 _collateral,\n IOracle _oracle,\n VaultParameters calldata params,\n string memory _symbol\n ) external virtual initializer {\n _initialize(_treasury, _collateral, _oracle, params, _symbol);\n whitelistingActivated = params.whitelistingActivated;\n paused = true;\n }\n\n /// @notice Internal logic to `initialize`\n function _initialize(\n ITreasury _treasury,\n IERC20 _collateral,\n IOracle _oracle,\n VaultParameters memory params,\n string memory _symbol\n ) internal virtual {\n if (_oracle.treasury() != _treasury) revert InvalidTreasury();\n treasury = _treasury;\n collateral = _collateral;\n _collatBase = 10 ** (IERC20Metadata(address(collateral)).decimals());\n stablecoin = IAgToken(_treasury.stablecoin());\n oracle = _oracle;\n string memory _name = string.concat(\"Angle Protocol \", _symbol, \" Vault\");\n name = _name;\n __ERC721Permit_init(_name);\n symbol = string.concat(_symbol, \"-vault\");\n\n interestAccumulator = BASE_INTEREST;\n lastInterestAccumulatorUpdated = block.timestamp;\n\n // Checking if the parameters have been correctly initialized\n if (\n params.collateralFactor > params.liquidationSurcharge ||\n params.liquidationSurcharge > BASE_PARAMS ||\n BASE_PARAMS > params.targetHealthFactor ||\n params.maxLiquidationDiscount >= BASE_PARAMS ||\n params.baseBoost == 0\n ) revert InvalidSetOfParameters();\n\n debtCeiling = params.debtCeiling;\n collateralFactor = params.collateralFactor;\n targetHealthFactor = params.targetHealthFactor;\n interestRate = params.interestRate;\n liquidationSurcharge = params.liquidationSurcharge;\n maxLiquidationDiscount = params.maxLiquidationDiscount;\n yLiquidationBoost = [params.baseBoost];\n }\n\n // ================================= MODIFIERS =================================\n\n /// @notice Checks whether the `msg.sender` has the governor role or not\n modifier onlyGovernor() {\n if (!treasury.isGovernor(msg.sender)) revert NotGovernor();\n _;\n }\n\n /// @notice Checks whether the `msg.sender` has the governor role or the guardian role\n modifier onlyGovernorOrGuardian() {\n if (!treasury.isGovernorOrGuardian(msg.sender)) revert NotGovernorOrGuardian();\n _;\n }\n\n /// @notice Checks whether the `msg.sender` is the treasury contract\n modifier onlyTreasury() {\n if (msg.sender != address(treasury)) revert NotTreasury();\n _;\n }\n\n /// @notice Checks whether the contract is paused\n modifier whenNotPaused() {\n if (_paused()) revert Paused();\n _;\n }\n\n // ============================== VAULT FUNCTIONS ==============================\n\n /// @inheritdoc IVaultManagerFunctions\n function createVault(address toVault) external whenNotPaused returns (uint256) {\n return _mint(toVault);\n }\n\n /// @inheritdoc IVaultManagerFunctions\n function angle(\n ActionType[] memory actions,\n bytes[] memory datas,\n address from,\n address to\n ) external returns (PaymentData memory) {\n return angle(actions, datas, from, to, address(0), new bytes(0));\n }\n\n /// @inheritdoc IVaultManagerFunctions\n function angle(\n ActionType[] memory actions,\n bytes[] memory datas,\n address from,\n address to,\n address who,\n bytes memory repayData\n ) public whenNotPaused nonReentrant returns (PaymentData memory paymentData) {\n if (actions.length != datas.length || actions.length == 0) revert IncompatibleLengths();\n // `newInterestAccumulator` and `oracleValue` are expensive to compute. Therefore, they are computed\n // only once inside the first action where they are necessary, then they are passed forward to further actions\n uint256 newInterestAccumulator;\n uint256 oracleValue;\n uint256 collateralAmount;\n uint256 stablecoinAmount;\n uint256 vaultID;\n for (uint256 i; i < actions.length; ++i) {\n ActionType action = actions[i];\n // Processing actions which do not need the value of the oracle or of the `interestAccumulator`\n if (action == ActionType.createVault) {\n _mint(abi.decode(datas[i], (address)));\n } else if (action == ActionType.addCollateral) {\n (vaultID, collateralAmount) = abi.decode(datas[i], (uint256, uint256));\n if (vaultID == 0) vaultID = vaultIDCount;\n _addCollateral(vaultID, collateralAmount);\n paymentData.collateralAmountToReceive += collateralAmount;\n } else if (action == ActionType.permit) {\n address owner;\n bytes32 r;\n bytes32 s;\n // Watch out naming conventions for permit are not respected to save some space and reduce the stack size\n // `vaultID` is used in place of the `deadline` parameter\n // Same for `collateralAmount` used in place of `value`\n // `stablecoinAmount` is used in place of the `v`\n (owner, collateralAmount, vaultID, stablecoinAmount, r, s) = abi.decode(\n datas[i],\n (address, uint256, uint256, uint256, bytes32, bytes32)\n );\n IERC20PermitUpgradeable(address(collateral)).permit(\n owner,\n address(this),\n collateralAmount,\n vaultID,\n uint8(stablecoinAmount),\n r,\n s\n );\n } else {\n // Processing actions which rely on the `interestAccumulator`: first accruing it to make\n // sure surplus is correctly taken into account between debt changes\n if (newInterestAccumulator == 0) newInterestAccumulator = _accrue();\n if (action == ActionType.repayDebt) {\n (vaultID, stablecoinAmount) = abi.decode(datas[i], (uint256, uint256));\n if (vaultID == 0) vaultID = vaultIDCount;\n stablecoinAmount = _repayDebt(vaultID, stablecoinAmount, newInterestAccumulator);\n uint256 stablecoinAmountPlusRepayFee = (stablecoinAmount * BASE_PARAMS) /\n (BASE_PARAMS - _repayFee());\n surplus += stablecoinAmountPlusRepayFee - stablecoinAmount;\n paymentData.stablecoinAmountToReceive += stablecoinAmountPlusRepayFee;\n } else {\n // Processing actions which need the oracle value\n if (oracleValue == 0) oracleValue = oracle.read();\n if (action == ActionType.closeVault) {\n vaultID = abi.decode(datas[i], (uint256));\n if (vaultID == 0) vaultID = vaultIDCount;\n (stablecoinAmount, collateralAmount) = _closeVault(\n vaultID,\n oracleValue,\n newInterestAccumulator\n );\n paymentData.collateralAmountToGive += collateralAmount;\n paymentData.stablecoinAmountToReceive += stablecoinAmount;\n } else if (action == ActionType.removeCollateral) {\n (vaultID, collateralAmount) = abi.decode(datas[i], (uint256, uint256));\n if (vaultID == 0) vaultID = vaultIDCount;\n _removeCollateral(vaultID, collateralAmount, oracleValue, newInterestAccumulator);\n paymentData.collateralAmountToGive += collateralAmount;\n } else if (action == ActionType.borrow) {\n (vaultID, stablecoinAmount) = abi.decode(datas[i], (uint256, uint256));\n if (vaultID == 0) vaultID = vaultIDCount;\n stablecoinAmount = _borrow(vaultID, stablecoinAmount, oracleValue, newInterestAccumulator);\n paymentData.stablecoinAmountToGive += stablecoinAmount;\n } else if (action == ActionType.getDebtIn) {\n address vaultManager;\n uint256 dstVaultID;\n (vaultID, vaultManager, dstVaultID, stablecoinAmount) = abi.decode(\n datas[i],\n (uint256, address, uint256, uint256)\n );\n if (vaultID == 0) vaultID = vaultIDCount;\n _getDebtIn(\n vaultID,\n IVaultManager(vaultManager),\n dstVaultID,\n stablecoinAmount,\n oracleValue,\n newInterestAccumulator\n );\n }\n }\n }\n }\n\n // Processing the different cases for the repayment, there are 4 of them:\n // - (1) Stablecoins to receive + collateral to send\n // - (2) Stablecoins to receive + collateral to receive\n // - (3) Stablecoins to send + collateral to send\n // - (4) Stablecoins to send + collateral to receive\n if (paymentData.stablecoinAmountToReceive >= paymentData.stablecoinAmountToGive) {\n uint256 stablecoinPayment = paymentData.stablecoinAmountToReceive - paymentData.stablecoinAmountToGive;\n if (paymentData.collateralAmountToGive >= paymentData.collateralAmountToReceive) {\n // In the case where all amounts are null, the function will enter here and nothing will be done\n // for the repayment\n _handleRepay(\n // Collateral payment is the difference between what to give and what to receive\n paymentData.collateralAmountToGive - paymentData.collateralAmountToReceive,\n stablecoinPayment,\n from,\n to,\n who,\n repayData\n );\n } else {\n if (stablecoinPayment != 0) stablecoin.burnFrom(stablecoinPayment, from, msg.sender);\n // In this case the collateral amount is necessarily non null\n collateral.safeTransferFrom(\n msg.sender,\n address(this),\n paymentData.collateralAmountToReceive - paymentData.collateralAmountToGive\n );\n }\n } else {\n uint256 stablecoinPayment = paymentData.stablecoinAmountToGive - paymentData.stablecoinAmountToReceive;\n // `stablecoinPayment` is strictly positive in this case\n stablecoin.mint(to, stablecoinPayment);\n if (paymentData.collateralAmountToGive > paymentData.collateralAmountToReceive) {\n collateral.safeTransfer(to, paymentData.collateralAmountToGive - paymentData.collateralAmountToReceive);\n } else {\n uint256 collateralPayment = paymentData.collateralAmountToReceive - paymentData.collateralAmountToGive;\n if (collateralPayment != 0) {\n if (repayData.length != 0) {\n ISwapper(who).swap(\n IERC20(address(stablecoin)),\n collateral,\n msg.sender,\n // As per the `ISwapper` interface, we must first give the amount of token owed by the address before\n // the amount of token it (or another related address) obtained\n collateralPayment,\n stablecoinPayment,\n repayData\n );\n }\n collateral.safeTransferFrom(msg.sender, address(this), collateralPayment);\n }\n }\n }\n }\n\n /// @inheritdoc IVaultManagerFunctions\n function getDebtOut(\n uint256 vaultID,\n uint256 stablecoinAmount,\n uint256 senderBorrowFee,\n uint256 senderRepayFee\n ) external whenNotPaused {\n if (!treasury.isVaultManager(msg.sender)) revert NotVaultManager();\n // Getting debt out of a vault is equivalent to repaying a portion of your debt, and this could leave exploits:\n // someone could borrow from a vault and transfer its debt to a `VaultManager` contract where debt repayment will\n // be cheaper: in which case we're making people pay the delta\n uint256 repayFee_;\n {\n uint256 _repayFeeReceiver = _repayFee();\n if (_repayFeeReceiver > senderRepayFee) {\n repayFee_ = _repayFeeReceiver - senderRepayFee;\n }\n }\n // Checking the delta of borrow fees to eliminate the risk of exploits here: a similar thing could happen: people\n // could mint from where it is cheap to mint and then transfer their debt to places where it is more expensive\n // to mint\n uint256 _borrowFee;\n if (senderBorrowFee > borrowFee) {\n _borrowFee = senderBorrowFee - borrowFee;\n }\n\n uint256 stablecoinAmountLessFeePaid = (stablecoinAmount *\n (BASE_PARAMS - repayFee_) *\n (BASE_PARAMS - _borrowFee)) / (BASE_PARAMS ** 2);\n surplus += stablecoinAmount - stablecoinAmountLessFeePaid;\n _repayDebt(vaultID, stablecoinAmountLessFeePaid, 0);\n }\n\n // =============================== VIEW FUNCTIONS ==============================\n\n /// @inheritdoc IVaultManagerFunctions\n function getVaultDebt(uint256 vaultID) external view returns (uint256) {\n return (vaultData[vaultID].normalizedDebt * _calculateCurrentInterestAccumulator()) / BASE_INTEREST;\n }\n\n /// @inheritdoc IVaultManagerFunctions\n function getTotalDebt() external view returns (uint256) {\n return (totalNormalizedDebt * _calculateCurrentInterestAccumulator()) / BASE_INTEREST;\n }\n\n /// @notice Checks whether a given vault is liquidable and if yes gives information regarding its liquidation\n /// @param vaultID ID of the vault to check\n /// @param liquidator Address of the liquidator which will be performing the liquidation\n /// @return liqOpp Description of the opportunity of liquidation\n /// @dev This function will revert if it's called on a vault that does not exist\n function checkLiquidation(\n uint256 vaultID,\n address liquidator\n ) external view returns (LiquidationOpportunity memory liqOpp) {\n liqOpp = _checkLiquidation(\n vaultData[vaultID],\n liquidator,\n oracle.read(),\n _calculateCurrentInterestAccumulator()\n );\n }\n\n // ====================== INTERNAL UTILITY VIEW FUNCTIONS ======================\n\n /// @notice Computes the health factor of a given vault. This can later be used to check whether a given vault is solvent\n /// (i.e. should be liquidated or not)\n /// @param vault Data of the vault to check\n /// @param oracleValue Oracle value at the time of the call (it is in the base of the stablecoin, that is for agTokens 10**18)\n /// @param newInterestAccumulator Value of the `interestAccumulator` at the time of the call\n /// @return healthFactor Health factor of the vault: if it's inferior to 1 (`BASE_PARAMS` in fact) this means that the vault can be liquidated\n /// @return currentDebt Current value of the debt of the vault (taking into account interest)\n /// @return collateralAmountInStable Collateral in the vault expressed in stablecoin value\n function _isSolvent(\n Vault memory vault,\n uint256 oracleValue,\n uint256 newInterestAccumulator\n ) internal view returns (uint256 healthFactor, uint256 currentDebt, uint256 collateralAmountInStable) {\n currentDebt = (vault.normalizedDebt * newInterestAccumulator) / BASE_INTEREST;\n collateralAmountInStable = (vault.collateralAmount * oracleValue) / _collatBase;\n if (currentDebt == 0) healthFactor = type(uint256).max;\n else healthFactor = (collateralAmountInStable * collateralFactor) / currentDebt;\n }\n\n /// @notice Calculates the current value of the `interestAccumulator` without updating the value\n /// in storage\n /// @dev This function avoids expensive exponentiation and the calculation is performed using a binomial approximation\n /// (1+x)^n = 1+n*x+[n/2*(n-1)]*x^2+[n/6*(n-1)*(n-2)*x^3...\n /// @dev The approximation slightly undercharges borrowers with the advantage of a great gas cost reduction\n /// @dev This function was mostly inspired from Aave implementation\n function _calculateCurrentInterestAccumulator() internal view returns (uint256) {\n uint256 exp = block.timestamp - lastInterestAccumulatorUpdated;\n uint256 ratePerSecond = interestRate;\n if (exp == 0 || ratePerSecond == 0) return interestAccumulator;\n uint256 expMinusOne = exp - 1;\n uint256 expMinusTwo = exp > 2 ? exp - 2 : 0;\n uint256 basePowerTwo = (ratePerSecond * ratePerSecond + HALF_BASE_INTEREST) / BASE_INTEREST;\n uint256 basePowerThree = (basePowerTwo * ratePerSecond + HALF_BASE_INTEREST) / BASE_INTEREST;\n uint256 secondTerm = (exp * expMinusOne * basePowerTwo) / 2;\n uint256 thirdTerm = (exp * expMinusOne * expMinusTwo * basePowerThree) / 6;\n return (interestAccumulator * (BASE_INTEREST + ratePerSecond * exp + secondTerm + thirdTerm)) / BASE_INTEREST;\n }\n\n // ================= INTERNAL UTILITY STATE-MODIFYING FUNCTIONS ================\n\n /// @notice Closes a vault without handling the repayment of the concerned address\n /// @param vaultID ID of the vault to close\n /// @param oracleValue Oracle value at the start of the call\n /// @param newInterestAccumulator Interest rate accumulator value at the start of the call\n /// @return Current debt of the vault to be repaid\n /// @return Value of the collateral in the vault to reimburse\n /// @dev The returned values are here to facilitate composability between calls\n function _closeVault(\n uint256 vaultID,\n uint256 oracleValue,\n uint256 newInterestAccumulator\n ) internal onlyApprovedOrOwner(msg.sender, vaultID) returns (uint256, uint256) {\n Vault memory vault = vaultData[vaultID];\n (uint256 healthFactor, uint256 currentDebt, ) = _isSolvent(vault, oracleValue, newInterestAccumulator);\n if (healthFactor <= BASE_PARAMS) revert InsolventVault();\n totalNormalizedDebt -= vault.normalizedDebt;\n _burn(vaultID);\n uint256 currentDebtPlusRepayFee = (currentDebt * BASE_PARAMS) / (BASE_PARAMS - _repayFee());\n surplus += currentDebtPlusRepayFee - currentDebt;\n return (currentDebtPlusRepayFee, vault.collateralAmount);\n }\n\n /// @notice Increases the collateral balance of a vault\n /// @param vaultID ID of the vault to increase the collateral balance of\n /// @param collateralAmount Amount by which increasing the collateral balance of\n function _addCollateral(uint256 vaultID, uint256 collateralAmount) internal {\n if (!_exists(vaultID)) revert NonexistentVault();\n _checkpointCollateral(vaultID, collateralAmount, true);\n vaultData[vaultID].collateralAmount += collateralAmount;\n emit CollateralAmountUpdated(vaultID, collateralAmount, 1);\n }\n\n /// @notice Decreases the collateral balance from a vault (without proceeding to collateral transfers)\n /// @param vaultID ID of the vault to decrease the collateral balance of\n /// @param collateralAmount Amount of collateral to reduce the balance of\n /// @param oracleValue Oracle value at the start of the call (given here to avoid double computations)\n /// @param interestAccumulator_ Value of the interest rate accumulator (potentially zero if it has not been\n /// computed yet)\n function _removeCollateral(\n uint256 vaultID,\n uint256 collateralAmount,\n uint256 oracleValue,\n uint256 interestAccumulator_\n ) internal onlyApprovedOrOwner(msg.sender, vaultID) {\n _checkpointCollateral(vaultID, collateralAmount, false);\n vaultData[vaultID].collateralAmount -= collateralAmount;\n (uint256 healthFactor, , ) = _isSolvent(vaultData[vaultID], oracleValue, interestAccumulator_);\n if (healthFactor <= BASE_PARAMS) revert InsolventVault();\n emit CollateralAmountUpdated(vaultID, collateralAmount, 0);\n }\n\n /// @notice Increases the debt balance of a vault and takes into account borrowing fees\n /// @param vaultID ID of the vault to increase borrow balance of\n /// @param stablecoinAmount Amount of stablecoins to borrow\n /// @param oracleValue Oracle value at the start of the call\n /// @param newInterestAccumulator Value of the interest rate accumulator\n /// @return toMint Amount of stablecoins to mint\n function _borrow(\n uint256 vaultID,\n uint256 stablecoinAmount,\n uint256 oracleValue,\n uint256 newInterestAccumulator\n ) internal onlyApprovedOrOwner(msg.sender, vaultID) returns (uint256 toMint) {\n stablecoinAmount = _increaseDebt(vaultID, stablecoinAmount, oracleValue, newInterestAccumulator);\n uint256 borrowFeePaid = (borrowFee * stablecoinAmount) / BASE_PARAMS;\n surplus += borrowFeePaid;\n toMint = stablecoinAmount - borrowFeePaid;\n }\n\n /// @notice Gets debt in a vault from another vault potentially in another `VaultManager` contract\n /// @param srcVaultID ID of the vault from this contract for which growing debt\n /// @param vaultManager Address of the `VaultManager` where the targeted vault is\n /// @param dstVaultID ID of the vault in the target contract\n /// @param stablecoinAmount Amount of stablecoins to grow the debt of. This amount will be converted\n /// to a normalized value in both `VaultManager` contracts\n /// @param oracleValue Oracle value at the start of the call (potentially zero if it has not been computed yet)\n /// @param newInterestAccumulator Value of the interest rate accumulator (potentially zero if it has not been\n /// computed yet)\n /// @dev A solvency check is performed after the debt increase in the source `vaultID`\n /// @dev Only approved addresses by the source vault owner can perform this action, however any vault\n /// from any vaultManager contract can see its debt reduced by this means\n function _getDebtIn(\n uint256 srcVaultID,\n IVaultManager vaultManager,\n uint256 dstVaultID,\n uint256 stablecoinAmount,\n uint256 oracleValue,\n uint256 newInterestAccumulator\n ) internal onlyApprovedOrOwner(msg.sender, srcVaultID) {\n emit DebtTransferred(srcVaultID, dstVaultID, address(vaultManager), stablecoinAmount);\n // The `stablecoinAmount` needs to be rounded down in the `_increaseDebt` function to reduce the room for exploits\n stablecoinAmount = _increaseDebt(srcVaultID, stablecoinAmount, oracleValue, newInterestAccumulator);\n if (address(vaultManager) == address(this)) {\n // No repayFees taken in this case, otherwise the same stablecoin may end up paying fees twice\n _repayDebt(dstVaultID, stablecoinAmount, newInterestAccumulator);\n } else {\n // No need to check the integrity of `VaultManager` here because `_getDebtIn` can be entered only through the\n // `angle` function which is non reentrant. Also, `getDebtOut` failing would be at the attacker loss, as they\n // would get their debt increasing in the current vault without decreasing it in the remote vault.\n vaultManager.getDebtOut(dstVaultID, stablecoinAmount, borrowFee, _repayFee());\n }\n }\n\n /// @notice Increases the debt of a given vault and verifies that this vault is still solvent\n /// @param vaultID ID of the vault to increase the debt of\n /// @param stablecoinAmount Amount of stablecoin to increase the debt of: this amount is converted in\n /// normalized debt using the pre-computed (or not) `newInterestAccumulator` value\n /// @param oracleValue Oracle value at the start of the call (given here to avoid double computations)\n /// @param newInterestAccumulator Value of the interest rate accumulator (potentially zero if it has not been\n /// computed yet)\n /// @return Amount of stablecoins to issue from this debt increase\n /// @dev The `stablecoinAmount` outputted need to be rounded down with respect to the change amount so that\n /// amount of stablecoins minted is smaller than the debt increase\n function _increaseDebt(\n uint256 vaultID,\n uint256 stablecoinAmount,\n uint256 oracleValue,\n uint256 newInterestAccumulator\n ) internal returns (uint256) {\n // We normalize the amount by dividing it by `newInterestAccumulator`. This makes accounting easier, since\n // it allows us to process all (past and future) debts like debts created at the inception of the contract.\n uint256 changeAmount = (stablecoinAmount * BASE_INTEREST) / newInterestAccumulator;\n // if there was no previous debt, we have to check that the debt creation will be higher than `dust`\n if (vaultData[vaultID].normalizedDebt == 0)\n if (stablecoinAmount <= dust) revert DustyLeftoverAmount();\n vaultData[vaultID].normalizedDebt += changeAmount;\n totalNormalizedDebt += changeAmount;\n if (totalNormalizedDebt * newInterestAccumulator > debtCeiling * BASE_INTEREST) revert DebtCeilingExceeded();\n (uint256 healthFactor, , ) = _isSolvent(vaultData[vaultID], oracleValue, newInterestAccumulator);\n if (healthFactor <= BASE_PARAMS) revert InsolventVault();\n emit InternalDebtUpdated(vaultID, changeAmount, 1);\n return (changeAmount * newInterestAccumulator) / BASE_INTEREST;\n }\n\n /// @notice Decreases the debt of a given vault and verifies that this vault still has an amount of debt superior\n /// to a dusty amount or no debt at all\n /// @param vaultID ID of the vault to decrease the debt of\n /// @param stablecoinAmount Amount of stablecoin to decrease the debt of: this amount is converted in\n /// normalized debt using the pre-computed (or not) `newInterestAccumulator` value\n /// To repay the whole debt, one can pass `type(uint256).max`\n /// @param newInterestAccumulator Value of the interest rate accumulator (potentially zero if it has not been\n /// computed yet, like in `getDebtOut`)\n /// @return Amount of stablecoins to be burnt to correctly repay the debt\n /// @dev If `stablecoinAmount` is `type(uint256).max`, this function will repay all the debt of the vault\n function _repayDebt(\n uint256 vaultID,\n uint256 stablecoinAmount,\n uint256 newInterestAccumulator\n ) internal returns (uint256) {\n if (newInterestAccumulator == 0) newInterestAccumulator = _accrue();\n uint256 newVaultNormalizedDebt = vaultData[vaultID].normalizedDebt;\n // To save one variable declaration, `changeAmount` is first expressed in stablecoin amount before being converted\n // to a normalized amount. Here we first store the maximum amount that can be repaid given the current debt\n uint256 changeAmount = (newVaultNormalizedDebt * newInterestAccumulator) / BASE_INTEREST;\n // In some situations (e.g. liquidations), the `stablecoinAmount` is rounded above and we want to make\n // sure to avoid underflows in all situations\n if (stablecoinAmount >= changeAmount) {\n stablecoinAmount = changeAmount;\n changeAmount = newVaultNormalizedDebt;\n } else {\n changeAmount = (stablecoinAmount * BASE_INTEREST) / newInterestAccumulator;\n }\n newVaultNormalizedDebt -= changeAmount;\n totalNormalizedDebt -= changeAmount;\n if (newVaultNormalizedDebt != 0 && newVaultNormalizedDebt * newInterestAccumulator <= dust * BASE_INTEREST)\n revert DustyLeftoverAmount();\n vaultData[vaultID].normalizedDebt = newVaultNormalizedDebt;\n emit InternalDebtUpdated(vaultID, changeAmount, 0);\n return stablecoinAmount;\n }\n\n /// @notice Handles the simultaneous repayment of stablecoins with a transfer of collateral\n /// @param collateralAmountToGive Amount of collateral the contract should give\n /// @param stableAmountToRepay Amount of stablecoins the contract should burn from the call\n /// @param from Address from which stablecoins should be burnt: it should be the `msg.sender` or at least\n /// approved by it\n /// @param to Address to which collateral should be sent\n /// @param who Address which should be notified if needed of the transfer\n /// @param data Data to pass to the `who` contract for it to successfully give the correct amount of stablecoins\n /// to the `from` address\n /// @dev This function allows for capital-efficient liquidations and repayments of loans\n function _handleRepay(\n uint256 collateralAmountToGive,\n uint256 stableAmountToRepay,\n address from,\n address to,\n address who,\n bytes memory data\n ) internal {\n if (collateralAmountToGive != 0) collateral.safeTransfer(to, collateralAmountToGive);\n if (stableAmountToRepay != 0) {\n if (data.length != 0) {\n ISwapper(who).swap(\n collateral,\n IERC20(address(stablecoin)),\n from,\n stableAmountToRepay,\n collateralAmountToGive,\n data\n );\n }\n stablecoin.burnFrom(stableAmountToRepay, from, msg.sender);\n }\n }\n\n // ====================== TREASURY RELATIONSHIP FUNCTIONS ======================\n\n /// @inheritdoc IVaultManagerFunctions\n function accrueInterestToTreasury() external onlyTreasury returns (uint256 surplusValue, uint256 badDebtValue) {\n _accrue();\n surplusValue = surplus;\n badDebtValue = badDebt;\n surplus = 0;\n badDebt = 0;\n if (surplusValue >= badDebtValue) {\n surplusValue -= badDebtValue;\n badDebtValue = 0;\n stablecoin.mint(address(treasury), surplusValue);\n } else {\n badDebtValue -= surplusValue;\n surplusValue = 0;\n }\n emit AccruedToTreasury(surplusValue, badDebtValue);\n }\n\n /// @notice Accrues interest accumulated across all vaults to the surplus and updates the `interestAccumulator`\n /// @return newInterestAccumulator Computed value of the interest accumulator\n /// @dev It should also be called when updating the value of the per second interest rate or when the `totalNormalizedDebt`\n /// value is about to change\n function _accrue() internal returns (uint256 newInterestAccumulator) {\n newInterestAccumulator = _calculateCurrentInterestAccumulator();\n uint256 interestAccrued = (totalNormalizedDebt * (newInterestAccumulator - interestAccumulator)) /\n BASE_INTEREST;\n surplus += interestAccrued;\n interestAccumulator = newInterestAccumulator;\n lastInterestAccumulatorUpdated = block.timestamp;\n emit InterestAccumulatorUpdated(newInterestAccumulator, block.timestamp);\n return newInterestAccumulator;\n }\n\n // ================================ LIQUIDATIONS ===============================\n\n /// @notice Liquidates an ensemble of vaults specified by their IDs\n /// @dev This function is a simplified wrapper of the function below. It is built to remove for liquidators the need to specify\n /// a `who` and a `data` parameter\n function liquidate(\n uint256[] memory vaultIDs,\n uint256[] memory amounts,\n address from,\n address to\n ) external returns (LiquidatorData memory) {\n return liquidate(vaultIDs, amounts, from, to, address(0), new bytes(0));\n }\n\n /// @notice Liquidates an ensemble of vaults specified by their IDs\n /// @param vaultIDs List of the vaults to liquidate\n /// @param amounts Amount of stablecoin to bring for the liquidation of each vault\n /// @param from Address from which the stablecoins for the liquidation should be taken: this address should be the `msg.sender`\n /// or have received an approval\n /// @param to Address to which discounted collateral should be sent\n /// @param who Address of the contract to handle repayment of stablecoins from received collateral\n /// @param data Data to pass to the repayment contract in case of. If empty, liquidators simply have to bring the exact amount of\n /// stablecoins to get the discounted collateral. If not, it is used by the repayment contract to swap a portion or all\n /// of the collateral received to stablecoins to be sent to the `from` address. More details in the `_handleRepay` function\n /// @return liqData Data about the liquidation process for the liquidator to track everything that has been going on (like how much\n /// stablecoins have been repaid, how much collateral has been received)\n /// @dev This function will revert if it's called on a vault that cannot be liquidated or that does not exist\n /// @dev A whitelist check may be performed on the address liquidating the vault or on the address receiving\n /// the funds from the liquidiation\n function liquidate(\n uint256[] memory vaultIDs,\n uint256[] memory amounts,\n address from,\n address to,\n address who,\n bytes memory data\n ) public whenNotPaused nonReentrant returns (LiquidatorData memory liqData) {\n if (_whitelistingActivated() && isWhitelisted[msg.sender] != 1 && isWhitelisted[to] != 1)\n revert NotWhitelisted();\n uint256 vaultIDsLength = vaultIDs.length;\n if (vaultIDsLength != amounts.length || vaultIDsLength == 0) revert IncompatibleLengths();\n // Stores all the data about an ongoing liquidation of multiple vaults\n liqData.oracleValue = oracle.read();\n liqData.newInterestAccumulator = _accrue();\n emit LiquidatedVaults(vaultIDs);\n for (uint256 i; i < vaultIDsLength; ++i) {\n Vault memory vault = vaultData[vaultIDs[i]];\n // Computing if liquidation can take place for a vault\n LiquidationOpportunity memory liqOpp = _checkLiquidation(\n vault,\n msg.sender,\n liqData.oracleValue,\n liqData.newInterestAccumulator\n );\n\n // Makes sure not to leave a dusty amount in the vault by either not liquidating too much\n // or everything\n if (\n (liqOpp.thresholdRepayAmount != 0 && amounts[i] >= liqOpp.thresholdRepayAmount) ||\n amounts[i] > liqOpp.maxStablecoinAmountToRepay\n ) amounts[i] = liqOpp.maxStablecoinAmountToRepay;\n\n // liqOpp.discount stores in fact `1-discount`\n uint256 collateralReleased = (amounts[i] * BASE_PARAMS * _collatBase) /\n (liqOpp.discount * liqData.oracleValue);\n\n _checkpointCollateral(\n vaultIDs[i],\n vault.collateralAmount <= collateralReleased ? vault.collateralAmount : collateralReleased,\n false\n );\n // Because we're rounding up in some divisions, `collateralReleased` can be greater than the `collateralAmount` of the vault\n // In this case, `stablecoinAmountToReceive` is still rounded up\n if (vault.collateralAmount <= collateralReleased) {\n // Liquidators should never get more collateral than what's in the vault\n collateralReleased = vault.collateralAmount;\n // Remove all the vault's debt (debt repayed + bad debt) from VaultManager totalDebt\n totalNormalizedDebt -= vault.normalizedDebt;\n // Reinitializing the `vaultID`: we're not burning the vault in this case for integration purposes\n delete vaultData[vaultIDs[i]];\n {\n uint256 debtReimbursed = (amounts[i] * liquidationSurcharge) / BASE_PARAMS;\n liqData.badDebtFromLiquidation += debtReimbursed < liqOpp.currentDebt\n ? liqOpp.currentDebt - debtReimbursed\n : 0;\n }\n // There may be an edge case in which: `amounts[i] = (currentDebt * BASE_PARAMS) / surcharge + 1`\n // In this case, as long as `surcharge < BASE_PARAMS`, there cannot be any underflow in the operation\n // above\n emit InternalDebtUpdated(vaultIDs[i], vault.normalizedDebt, 0);\n } else {\n vaultData[vaultIDs[i]].collateralAmount -= collateralReleased;\n _repayDebt(\n vaultIDs[i],\n (amounts[i] * liquidationSurcharge) / BASE_PARAMS,\n liqData.newInterestAccumulator\n );\n }\n liqData.collateralAmountToGive += collateralReleased;\n liqData.stablecoinAmountToReceive += amounts[i];\n }\n // Normalization of good and bad debt is already handled in the `accrueInterestToTreasury` function\n surplus += (liqData.stablecoinAmountToReceive * (BASE_PARAMS - liquidationSurcharge)) / BASE_PARAMS;\n badDebt += liqData.badDebtFromLiquidation;\n _handleRepay(liqData.collateralAmountToGive, liqData.stablecoinAmountToReceive, from, to, who, data);\n }\n\n /// @notice Internal version of the `checkLiquidation` function\n /// @dev This function takes two additional parameters as when entering this function `oracleValue`\n /// and `newInterestAccumulator` should have always been computed\n function _checkLiquidation(\n Vault memory vault,\n address liquidator,\n uint256 oracleValue,\n uint256 newInterestAccumulator\n ) internal view returns (LiquidationOpportunity memory liqOpp) {\n // Checking if the vault can be liquidated\n (uint256 healthFactor, uint256 currentDebt, uint256 collateralAmountInStable) = _isSolvent(\n vault,\n oracleValue,\n newInterestAccumulator\n );\n // Health factor of a vault that does not exist is `type(uint256).max`\n if (healthFactor >= BASE_PARAMS) revert HealthyVault();\n\n uint256 liquidationDiscount = (_computeLiquidationBoost(liquidator) * (BASE_PARAMS - healthFactor)) /\n BASE_PARAMS;\n // In fact `liquidationDiscount` is stored here as 1 minus discount to save some computation costs\n // This value is necessarily != 0 as `maxLiquidationDiscount < BASE_PARAMS`\n liquidationDiscount = liquidationDiscount >= maxLiquidationDiscount\n ? BASE_PARAMS - maxLiquidationDiscount\n : BASE_PARAMS - liquidationDiscount;\n // Same for the surcharge here: it's in fact 1 - the fee taken by the protocol\n uint256 surcharge = liquidationSurcharge;\n uint256 maxAmountToRepay;\n uint256 thresholdRepayAmount;\n // Checking if we're in a situation where the health factor is an increasing or a decreasing function of the\n // amount repaid. In the first case, the health factor is an increasing function which means that the liquidator\n // can bring the vault to the target health ratio\n if (healthFactor * liquidationDiscount * surcharge >= collateralFactor * BASE_PARAMS ** 2) {\n // This is the max amount to repay that will bring the person to the target health factor\n // Denom is always positive when a vault gets liquidated in this case and when the health factor\n // is an increasing function of the amount of stablecoins repaid\n // And given that most parameters are in base 9, the numerator can very hardly overflow here\n maxAmountToRepay =\n ((targetHealthFactor * currentDebt - collateralAmountInStable * collateralFactor) *\n BASE_PARAMS *\n liquidationDiscount) /\n (surcharge * targetHealthFactor * liquidationDiscount - (BASE_PARAMS ** 2) * collateralFactor);\n // Need to check for the dust as liquidating should not leave a dusty amount in the vault\n uint256 dustParameter = dustLiquidation;\n if (currentDebt * BASE_PARAMS <= maxAmountToRepay * surcharge + dustParameter * BASE_PARAMS) {\n // If liquidating to the target threshold would leave a dusty amount: the liquidator can repay all.\n // We're avoiding here propagation of rounding errors and rounding up the max amount to repay to make\n // sure all the debt ends up being paid\n maxAmountToRepay =\n (vault.normalizedDebt * newInterestAccumulator * BASE_PARAMS) /\n (surcharge * BASE_INTEREST) +\n 1;\n // In this case the threshold amount is such that it leaves just enough dust: amount is rounded\n // down such that if a liquidator repays this amount then there is more than `dustLiquidation` left in\n // the liquidated vault\n if (currentDebt > dustParameter)\n thresholdRepayAmount = ((currentDebt - dustParameter) * BASE_PARAMS) / surcharge;\n // If there is from the beginning a dusty debt, then liquidator should repay everything that's left\n else thresholdRepayAmount = 1;\n }\n } else {\n // In this case, the liquidator can repay stablecoins such that they'll end up getting exactly the collateral\n // in the liquidated vault\n maxAmountToRepay =\n (vault.collateralAmount * liquidationDiscount * oracleValue) /\n (BASE_PARAMS * _collatBase) +\n 1;\n // It should however make sure not to leave a dusty amount of collateral (in stablecoin value) in the vault\n if (collateralAmountInStable > _dustCollateral)\n // There's no issue with this amount being rounded down\n thresholdRepayAmount =\n ((collateralAmountInStable - _dustCollateral) * liquidationDiscount) /\n BASE_PARAMS;\n // If there is from the beginning a dusty amount of collateral, liquidator should repay everything that's left\n else thresholdRepayAmount = 1;\n }\n liqOpp.maxStablecoinAmountToRepay = maxAmountToRepay;\n liqOpp.maxCollateralAmountGiven =\n (maxAmountToRepay * BASE_PARAMS * _collatBase) /\n (oracleValue * liquidationDiscount);\n liqOpp.thresholdRepayAmount = thresholdRepayAmount;\n liqOpp.discount = liquidationDiscount;\n liqOpp.currentDebt = currentDebt;\n }\n\n // ================================== SETTERS ==================================\n\n /// @notice Sets parameters encoded as uint64\n /// @param param Value for the parameter\n /// @param what Parameter to change\n /// @dev This function performs the required checks when updating a parameter\n /// @dev When setting parameters governance or the guardian should make sure that when `HF < CF/((1-surcharge)(1-discount))`\n /// and hence when liquidating a vault is going to decrease its health factor, `discount = max discount`.\n /// Otherwise, it may be profitable for the liquidator to liquidate in multiple times: as it will decrease\n /// the HF and therefore increase the discount between each time\n function setUint64(uint64 param, bytes32 what) external virtual onlyGovernorOrGuardian {\n if (what == \"CF\") {\n if (param > liquidationSurcharge) revert TooHighParameterValue();\n collateralFactor = param;\n } else if (what == \"THF\") {\n if (param < BASE_PARAMS) revert TooSmallParameterValue();\n targetHealthFactor = param;\n } else if (what == \"BF\") {\n if (param > BASE_PARAMS) revert TooHighParameterValue();\n borrowFee = param;\n } else if (what == \"RF\") {\n // As liquidation surcharge is stored as `1-fee` and as we need `repayFee` to be smaller\n // than the liquidation surcharge, we need to have:\n // `liquidationSurcharge <= BASE_PARAMS - repayFee` and as such `liquidationSurcharge + repayFee <= BASE_PARAMS`\n if (param + liquidationSurcharge > BASE_PARAMS) revert TooHighParameterValue();\n repayFee = param;\n } else if (what == \"IR\") {\n _accrue();\n interestRate = param;\n } else if (what == \"LS\") {\n if (collateralFactor > param || param + repayFee > BASE_PARAMS) revert InvalidParameterValue();\n liquidationSurcharge = param;\n } else if (what == \"MLD\") {\n if (param > BASE_PARAMS) revert TooHighParameterValue();\n maxLiquidationDiscount = param;\n } else {\n revert InvalidParameterType();\n }\n emit FiledUint64(param, what);\n }\n\n /// @notice Sets `debtCeiling`\n /// @param _debtCeiling New value for `debtCeiling`\n /// @dev `debtCeiling` should not be bigger than `type(uint256).max / 10**27` otherwise there could be overflows\n function setDebtCeiling(uint256 _debtCeiling) external onlyGovernorOrGuardian {\n debtCeiling = _debtCeiling;\n emit DebtCeilingUpdated(_debtCeiling);\n }\n\n /// @notice Sets the parameters for the liquidation booster which encodes the slope of the discount\n function setLiquidationBoostParameters(\n address _veBoostProxy,\n uint256[] memory xBoost,\n uint256[] memory yBoost\n ) external virtual onlyGovernorOrGuardian {\n if (yBoost[0] == 0) revert InvalidSetOfParameters();\n yLiquidationBoost = yBoost;\n emit LiquidationBoostParametersUpdated(_veBoostProxy, xBoost, yBoost);\n }\n\n /// @inheritdoc IVaultManagerFunctions\n function togglePause() external virtual onlyGovernorOrGuardian {\n paused = !paused;\n }\n\n /// @notice Changes the ERC721 metadata URI\n function setBaseURI(string memory baseURI_) external onlyGovernorOrGuardian {\n _baseURI = baseURI_;\n }\n\n /// @notice Changes the whitelisting of an address\n /// @param target Address to toggle\n /// @dev If the `target` address is the zero address then this function toggles whitelisting\n /// for all addresses\n function toggleWhitelist(address target) external virtual onlyGovernor {\n if (target != address(0)) {\n isWhitelisted[target] = 1 - isWhitelisted[target];\n } else {\n whitelistingActivated = !whitelistingActivated;\n }\n }\n\n /// @notice Changes the reference to the oracle contract used to get the price of the oracle\n /// @param _oracle Reference to the oracle contract\n function setOracle(address _oracle) external virtual onlyGovernor {\n if (IOracle(_oracle).treasury() != treasury) revert InvalidTreasury();\n oracle = IOracle(_oracle);\n }\n\n /// @notice Sets the dust variables\n /// @param _dust New minimum debt allowed\n /// @param _dustLiquidation New `dustLiquidation` value\n /// @param dustCollateral_ New minimum collateral allowed in a vault after a liquidation\n /// @dev dustCollateral_ is in stable value\n function setDusts(uint256 _dust, uint256 _dustLiquidation, uint256 dustCollateral_) external onlyGovernor {\n if (_dust > _dustLiquidation) revert InvalidParameterValue();\n dust = _dust;\n dustLiquidation = _dustLiquidation;\n _dustCollateral = dustCollateral_;\n }\n\n /// @inheritdoc IVaultManagerFunctions\n function setTreasury(address _treasury) external virtual onlyTreasury {\n treasury = ITreasury(_treasury);\n // This function makes sure to propagate the change to the associated contract\n // even though a single oracle contract could be used in different places\n oracle.setTreasury(_treasury);\n }\n\n // ============================= VIRTUAL FUNCTIONS =============================\n\n /// @notice Returns the liquidation boost of a given address, that is the slope of the discount function\n /// @return The slope of the discount function\n function _computeLiquidationBoost(address) internal view virtual returns (uint256) {\n return yLiquidationBoost[0];\n }\n\n /// @notice Hook called before any collateral internal changes\n /// @param vaultID Vault which sees its collateral amount changed\n /// @param amount Collateral amount balance of the owner of vaultID increase/decrease\n /// @param add Whether the balance should be increased/decreased\n /// @param vaultID Vault which sees its collateral amount changed\n function _checkpointCollateral(uint256 vaultID, uint256 amount, bool add) internal virtual {}\n\n /// @notice Get `paused` in storage only if needed\n function _paused() internal view virtual returns (bool) {\n return paused;\n }\n\n /// @notice Get `repayFee` in storage only if needed\n function _repayFee() internal view virtual returns (uint64) {\n return repayFee;\n }\n}\n" + }, + "contracts/vaultManager/VaultManagerERC721.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\nimport \"./VaultManagerStorage.sol\";\n\n/// @title VaultManagerERC721\n/// @author Angle Labs, Inc.\n/// @dev Base ERC721 Implementation of VaultManager\nabstract contract VaultManagerERC721 is IERC721MetadataUpgradeable, VaultManagerStorage {\n using SafeERC20 for IERC20;\n using Address for address;\n\n /// @inheritdoc IERC721MetadataUpgradeable\n string public name;\n /// @inheritdoc IERC721MetadataUpgradeable\n string public symbol;\n\n // ================================= MODIFIERS =================================\n\n /// @notice Checks if the person interacting with the vault with `vaultID` is approved\n /// @param caller Address of the person seeking to interact with the vault\n /// @param vaultID ID of the concerned vault\n modifier onlyApprovedOrOwner(address caller, uint256 vaultID) {\n if (!_isApprovedOrOwner(caller, vaultID)) revert NotApproved();\n _;\n }\n\n // ================================ ERC721 LOGIC ===============================\n\n /// @notice Checks whether a given address is approved for a vault or owns this vault\n /// @param spender Address for which vault ownership should be checked\n /// @param vaultID ID of the vault to check\n /// @return Whether the `spender` address owns or is approved for `vaultID`\n function isApprovedOrOwner(address spender, uint256 vaultID) external view returns (bool) {\n return _isApprovedOrOwner(spender, vaultID);\n }\n\n /// @inheritdoc IERC721MetadataUpgradeable\n function tokenURI(uint256 vaultID) external view returns (string memory) {\n if (!_exists(vaultID)) revert NonexistentVault();\n // There is no vault with `vaultID` equal to 0, so the following variable is\n // always greater than zero\n uint256 temp = vaultID;\n uint256 digits;\n while (temp != 0) {\n ++digits;\n temp /= 10;\n }\n bytes memory buffer = new bytes(digits);\n while (vaultID != 0) {\n digits -= 1;\n buffer[digits] = bytes1(uint8(48 + uint256(vaultID % 10)));\n vaultID /= 10;\n }\n return bytes(_baseURI).length != 0 ? string(abi.encodePacked(_baseURI, string(buffer))) : \"\";\n }\n\n /// @inheritdoc IERC721Upgradeable\n function balanceOf(address owner) external view returns (uint256) {\n if (owner == address(0)) revert ZeroAddress();\n return _balances[owner];\n }\n\n /// @inheritdoc IERC721Upgradeable\n function ownerOf(uint256 vaultID) external view returns (address) {\n return _ownerOf(vaultID);\n }\n\n /// @inheritdoc IERC721Upgradeable\n function approve(address to, uint256 vaultID) external {\n address owner = _ownerOf(vaultID);\n if (to == owner) revert ApprovalToOwner();\n if (msg.sender != owner && !isApprovedForAll(owner, msg.sender)) revert NotApproved();\n\n _approve(to, vaultID);\n }\n\n /// @inheritdoc IERC721Upgradeable\n function getApproved(uint256 vaultID) external view returns (address) {\n if (!_exists(vaultID)) revert NonexistentVault();\n return _getApproved(vaultID);\n }\n\n /// @inheritdoc IERC721Upgradeable\n function setApprovalForAll(address operator, bool approved) external {\n _setApprovalForAll(msg.sender, operator, approved);\n }\n\n /// @inheritdoc IERC721Upgradeable\n function isApprovedForAll(address owner, address operator) public view returns (bool) {\n return _operatorApprovals[owner][operator] == 1;\n }\n\n /// @inheritdoc IERC721Upgradeable\n function transferFrom(address from, address to, uint256 vaultID) external onlyApprovedOrOwner(msg.sender, vaultID) {\n _transfer(from, to, vaultID);\n }\n\n /// @inheritdoc IERC721Upgradeable\n function safeTransferFrom(address from, address to, uint256 vaultID) external {\n safeTransferFrom(from, to, vaultID, \"\");\n }\n\n /// @inheritdoc IERC721Upgradeable\n function safeTransferFrom(\n address from,\n address to,\n uint256 vaultID,\n bytes memory _data\n ) public onlyApprovedOrOwner(msg.sender, vaultID) {\n _safeTransfer(from, to, vaultID, _data);\n }\n\n // ================================ ERC165 LOGIC ===============================\n\n /// @inheritdoc IERC165Upgradeable\n function supportsInterface(bytes4 interfaceId) external pure returns (bool) {\n return\n interfaceId == type(IERC721MetadataUpgradeable).interfaceId ||\n interfaceId == type(IERC721Upgradeable).interfaceId ||\n interfaceId == type(IVaultManager).interfaceId ||\n interfaceId == type(IERC165Upgradeable).interfaceId;\n }\n\n // ================== INTERNAL FUNCTIONS FOR THE ERC721 LOGIC ==================\n\n /// @notice Internal version of the `ownerOf` function\n function _ownerOf(uint256 vaultID) internal view returns (address owner) {\n owner = _owners[vaultID];\n if (owner == address(0)) revert NonexistentVault();\n }\n\n /// @notice Internal version of the `getApproved` function\n function _getApproved(uint256 vaultID) internal view returns (address) {\n return _vaultApprovals[vaultID];\n }\n\n /// @notice Internal version of the `safeTransferFrom` function (with the data parameter)\n function _safeTransfer(address from, address to, uint256 vaultID, bytes memory _data) internal {\n _transfer(from, to, vaultID);\n if (!_checkOnERC721Received(from, to, vaultID, _data)) revert NonERC721Receiver();\n }\n\n /// @notice Checks whether a vault exists\n /// @param vaultID ID of the vault to check\n /// @return Whether `vaultID` has been created\n function _exists(uint256 vaultID) internal view returns (bool) {\n return _owners[vaultID] != address(0);\n }\n\n /// @notice Internal version of the `isApprovedOrOwner` function\n function _isApprovedOrOwner(address spender, uint256 vaultID) internal view returns (bool) {\n // The following checks if the vault exists\n address owner = _ownerOf(vaultID);\n return (spender == owner || _getApproved(vaultID) == spender || _operatorApprovals[owner][spender] == 1);\n }\n\n /// @notice Internal version of the `createVault` function\n /// Mints `vaultID` and transfers it to `to`\n /// @dev This method is equivalent to the `_safeMint` method used in OpenZeppelin ERC721 contract\n /// @dev Emits a {Transfer} event\n function _mint(address to) internal returns (uint256 vaultID) {\n if (to == address(0)) revert ZeroAddress();\n\n unchecked {\n vaultIDCount += 1;\n }\n\n vaultID = vaultIDCount;\n _beforeTokenTransfer(address(0), to, vaultID);\n\n unchecked {\n _balances[to] += 1;\n }\n\n _owners[vaultID] = to;\n emit Transfer(address(0), to, vaultID);\n if (!_checkOnERC721Received(address(0), to, vaultID, \"\")) revert NonERC721Receiver();\n }\n\n /// @notice Destroys `vaultID`\n /// @dev `vaultID` must exist\n /// @dev Emits a {Transfer} event\n function _burn(uint256 vaultID) internal {\n address owner = _ownerOf(vaultID);\n\n _beforeTokenTransfer(owner, address(0), vaultID);\n // Clear approvals\n _approve(address(0), vaultID);\n // The following line cannot underflow as the owner's balance is necessarily\n // greater than 1\n unchecked {\n _balances[owner] -= 1;\n }\n delete _owners[vaultID];\n delete vaultData[vaultID];\n\n emit Transfer(owner, address(0), vaultID);\n }\n\n /// @notice Transfers `vaultID` from `from` to `to` as opposed to {transferFrom},\n /// this imposes no restrictions on msg.sender\n /// @dev `to` cannot be the zero address and `perpetualID` must be owned by `from`\n /// @dev Emits a {Transfer} event\n function _transfer(address from, address to, uint256 vaultID) internal {\n if (_ownerOf(vaultID) != from) revert NotApproved();\n if (to == address(0)) revert ZeroAddress();\n\n _beforeTokenTransfer(from, to, vaultID);\n\n // Clear approvals from the previous owner\n _approve(address(0), vaultID);\n unchecked {\n _balances[from] -= 1;\n _balances[to] += 1;\n }\n _owners[vaultID] = to;\n\n emit Transfer(from, to, vaultID);\n }\n\n /// @notice Approves `to` to operate on `vaultID`\n function _approve(address to, uint256 vaultID) internal {\n _vaultApprovals[vaultID] = to;\n emit Approval(_ownerOf(vaultID), to, vaultID);\n }\n\n /// @notice Internal version of the `setApprovalForAll` function\n /// @dev It contains an `approver` field to be used in case someone signs a permit for a particular\n /// address, and this signature is given to the contract by another address (like a router)\n function _setApprovalForAll(address approver, address operator, bool approved) internal {\n if (operator == approver) revert ApprovalToCaller();\n uint256 approval = approved ? 1 : 0;\n _operatorApprovals[approver][operator] = approval;\n emit ApprovalForAll(approver, operator, approved);\n }\n\n /// @notice Internal function to invoke {IERC721Receiver-onERC721Received} on a target address\n /// The call is not executed if the target address is not a contract\n /// @param from Address representing the previous owner of the given token ID\n /// @param to Target address that will receive the tokens\n /// @param vaultID ID of the token to be transferred\n /// @param _data Bytes optional data to send along with the call\n /// @return Bool whether the call correctly returned the expected value\n function _checkOnERC721Received(\n address from,\n address to,\n uint256 vaultID,\n bytes memory _data\n ) private returns (bool) {\n if (to.isContract()) {\n try IERC721ReceiverUpgradeable(to).onERC721Received(msg.sender, from, vaultID, _data) returns (\n bytes4 retval\n ) {\n return retval == IERC721ReceiverUpgradeable.onERC721Received.selector;\n } catch (bytes memory reason) {\n if (reason.length == 0) {\n revert NonERC721Receiver();\n } else {\n // solhint-disable-next-line no-inline-assembly\n assembly {\n revert(add(32, reason), mload(reason))\n }\n }\n }\n } else {\n return true;\n }\n }\n\n /// @notice Hook that is called before any token transfer. This includes minting and burning.\n /// Calling conditions:\n ///\n /// - When `from` and `to` are both non-zero, `from`'s `vaultID` will be\n /// transferred to `to`.\n /// - When `from` is zero, `vaultID` will be minted for `to`.\n /// - When `to` is zero, `from`'s `vaultID` will be burned.\n /// - `from` and `to` are never both zero.\n function _beforeTokenTransfer(address from, address to, uint256 vaultID) internal virtual {}\n\n /// @notice Get `whitelistingActivated` in storage only if needed\n function _whitelistingActivated() internal view virtual returns (bool) {\n return whitelistingActivated;\n }\n}\n" + }, + "contracts/vaultManager/VaultManagerLiquidationBoost.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\nimport \"./VaultManager.sol\";\n\n/// @title VaultManagerLiquidationBoost\n/// @author Angle Labs, Inc.\n/// @notice Liquidation discount depending also on the liquidator veANGLE balance\ncontract VaultManagerLiquidationBoost is VaultManager {\n using SafeERC20 for IERC20;\n using Address for address;\n\n // =================================== SETTER ==================================\n\n /// @inheritdoc VaultManager\n /// @param _veBoostProxy Address which queries veANGLE balances and adjusted balances from delegation\n /// @param xBoost Threshold values of veANGLE adjusted balances\n /// @param yBoost Values of the liquidation boost at the threshold values of x\n /// @dev There are 2 modes:\n /// When boost is enabled, `xBoost` and `yBoost` should have a length of 2, but if they have a\n /// higher length contract will still work as expected. Contract will also work as expected if their\n /// length differ\n /// When boost is disabled, `_veBoostProxy` needs to be zero address and `yBoost[0]` is the base boost\n function setLiquidationBoostParameters(\n address _veBoostProxy,\n uint256[] memory xBoost,\n uint256[] memory yBoost\n ) external override onlyGovernorOrGuardian {\n if (\n (xBoost.length != yBoost.length) ||\n (yBoost[0] == 0) ||\n ((_veBoostProxy != address(0)) && (xBoost[1] <= xBoost[0] || yBoost[1] < yBoost[0]))\n ) revert InvalidSetOfParameters();\n veBoostProxy = IVeBoostProxy(_veBoostProxy);\n xLiquidationBoost = xBoost;\n yLiquidationBoost = yBoost;\n emit LiquidationBoostParametersUpdated(_veBoostProxy, xBoost, yBoost);\n }\n\n // ======================== OVERRIDEN VIRTUAL FUNCTIONS ========================\n\n /// @inheritdoc VaultManager\n function _computeLiquidationBoost(address liquidator) internal view override returns (uint256) {\n if (address(veBoostProxy) == address(0)) {\n return yLiquidationBoost[0];\n } else {\n uint256 adjustedBalance = veBoostProxy.adjusted_balance_of(liquidator);\n if (adjustedBalance >= xLiquidationBoost[1]) return yLiquidationBoost[1];\n else if (adjustedBalance <= xLiquidationBoost[0]) return yLiquidationBoost[0];\n else\n return\n yLiquidationBoost[0] +\n ((yLiquidationBoost[1] - yLiquidationBoost[0]) * (adjustedBalance - xLiquidationBoost[0])) /\n (xLiquidationBoost[1] - xLiquidationBoost[0]);\n }\n }\n}\n" + }, + "contracts/vaultManager/VaultManagerPermit.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\nimport \"./VaultManagerERC721.sol\";\nimport \"../interfaces/external/IERC1271.sol\";\n\n/// @title VaultManagerPermit\n/// @author Angle Labs, Inc.\n/// @dev Base Implementation of permit functions for the `VaultManager` contract\nabstract contract VaultManagerPermit is Initializable, VaultManagerERC721 {\n using Address for address;\n\n mapping(address => uint256) private _nonces;\n /* solhint-disable var-name-mixedcase */\n bytes32 private _HASHED_NAME;\n bytes32 private _HASHED_VERSION;\n bytes32 private _PERMIT_TYPEHASH;\n /* solhint-enable var-name-mixedcase */\n\n error ExpiredDeadline();\n error InvalidSignature();\n\n //solhint-disable-next-line\n function __ERC721Permit_init(string memory _name) internal onlyInitializing {\n _PERMIT_TYPEHASH = keccak256(\n \"Permit(address owner,address spender,bool approved,uint256 nonce,uint256 deadline)\"\n );\n _HASHED_NAME = keccak256(bytes(_name));\n _HASHED_VERSION = keccak256(bytes(\"1\"));\n }\n\n /// @notice Allows an address to give or revoke approval for all its vaults to another address\n /// @param owner Address signing the permit and giving (or revoking) its approval for all the controlled vaults\n /// @param spender Address to give approval to\n /// @param approved Whether to give or revoke the approval\n /// @param deadline Deadline parameter for the signature to be valid\n /// @dev The `v`, `r`, and `s` parameters are used as signature data\n function permit(\n address owner,\n address spender,\n bool approved,\n uint256 deadline,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) external {\n if (block.timestamp > deadline) revert ExpiredDeadline();\n // Additional signature checks performed in the `ECDSAUpgradeable.recover` function\n if (uint256(s) > 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D576E7357A4501DDFE92F46681B20A0 || (v != 27 && v != 28))\n revert InvalidSignature();\n\n bytes32 digest = keccak256(\n abi.encodePacked(\n \"\\x19\\x01\",\n _domainSeparatorV4(),\n keccak256(\n abi.encode(\n _PERMIT_TYPEHASH,\n // 0x3f43a9c6bafb5c7aab4e0cfe239dc5d4c15caf0381c6104188191f78a6640bd8,\n owner,\n spender,\n approved,\n _useNonce(owner),\n deadline\n )\n )\n )\n );\n if (owner.isContract()) {\n if (IERC1271(owner).isValidSignature(digest, abi.encodePacked(r, s, v)) != 0x1626ba7e)\n revert InvalidSignature();\n } else {\n address signer = ecrecover(digest, v, r, s);\n if (signer != owner || signer == address(0)) revert InvalidSignature();\n }\n\n _setApprovalForAll(owner, spender, approved);\n }\n\n /// @notice Returns the current nonce for an `owner` address\n function nonces(address owner) public view returns (uint256) {\n return _nonces[owner];\n }\n\n /// @notice Returns the domain separator for the current chain.\n // solhint-disable-next-line func-name-mixedcase\n function DOMAIN_SEPARATOR() external view returns (bytes32) {\n return _domainSeparatorV4();\n }\n\n /// @notice Internal version of the `DOMAIN_SEPARATOR` function\n function _domainSeparatorV4() internal view returns (bytes32) {\n return\n keccak256(\n abi.encode(\n // keccak256('EIP712Domain(string name,string version,uint256 chainId,address verifyingContract)')\n 0x8b73c3c69bb8fe3d512ecc4cf759cc79239f7b179b0ffacaa9a75d522b39400f,\n _HASHED_NAME,\n _HASHED_VERSION,\n block.chainid,\n address(this)\n )\n );\n }\n\n /// @notice Consumes a nonce for an address: returns the current value and increments it\n function _useNonce(address owner) internal returns (uint256 current) {\n current = _nonces[owner];\n _nonces[owner] = current + 1;\n }\n\n uint256[49] private __gap;\n}\n" + }, + "contracts/vaultManager/VaultManagerStorage.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\nimport \"@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/token/ERC20/extensions/draft-IERC20PermitUpgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/token/ERC721/IERC721ReceiverUpgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/interfaces/IERC721MetadataUpgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/utils/introspection/IERC165Upgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/utils/AddressUpgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/security/ReentrancyGuardUpgradeable.sol\";\nimport \"@openzeppelin/contracts/token/ERC20/extensions/IERC20Metadata.sol\";\nimport \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\nimport \"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\";\n\nimport \"../interfaces/IAgToken.sol\";\nimport \"../interfaces/IOracle.sol\";\nimport \"../interfaces/ISwapper.sol\";\nimport \"../interfaces/ITreasury.sol\";\nimport \"../interfaces/IVaultManager.sol\";\nimport \"../interfaces/governance/IVeBoostProxy.sol\";\n\n/// @title VaultManagerStorage\n/// @author Angle Labs, Inc.\n/// @dev Variables, references, parameters and events needed in the `VaultManager` contract\n// solhint-disable-next-line max-states-count\ncontract VaultManagerStorage is IVaultManagerStorage, Initializable, ReentrancyGuardUpgradeable {\n /// @notice Base used for parameter computation: almost all the parameters of this contract are set in `BASE_PARAMS`\n uint256 public constant BASE_PARAMS = 10 ** 9;\n /// @notice Base used for interest rate computation\n uint256 public constant BASE_INTEREST = 10 ** 27;\n /// @notice Used for interest rate computation\n uint256 public constant HALF_BASE_INTEREST = 10 ** 27 / 2;\n\n // ================================= REFERENCES ================================\n\n /// @inheritdoc IVaultManagerStorage\n ITreasury public treasury;\n /// @inheritdoc IVaultManagerStorage\n IERC20 public collateral;\n /// @inheritdoc IVaultManagerStorage\n IAgToken public stablecoin;\n /// @inheritdoc IVaultManagerStorage\n IOracle public oracle;\n /// @notice Reference to the contract which computes adjusted veANGLE balances for liquidators boosts\n IVeBoostProxy public veBoostProxy;\n /// @notice Base of the collateral\n uint256 internal _collatBase;\n\n // ================================= PARAMETERS ================================\n // Unless specified otherwise, parameters of this contract are expressed in `BASE_PARAMS`\n\n /// @notice Maximum amount of stablecoins that can be issued with this contract (in `BASE_TOKENS`). This parameter should\n /// not be bigger than `type(uint256).max / BASE_INTEREST` otherwise there may be some overflows in the `increaseDebt` function\n uint256 public debtCeiling;\n /// @notice Threshold veANGLE balance values for the computation of the boost for liquidators: the length of this array\n /// should normally be 2. The base of the x-values in this array should be `BASE_TOKENS`\n uint256[] public xLiquidationBoost;\n /// @notice Values of the liquidation boost at the threshold values of x\n uint256[] public yLiquidationBoost;\n /// @inheritdoc IVaultManagerStorage\n uint64 public collateralFactor;\n /// @notice Maximum Health factor at which a vault can end up after a liquidation (unless it's fully liquidated)\n uint64 public targetHealthFactor;\n /// @notice Upfront fee taken when borrowing stablecoins: this fee is optional and should in practice not be used\n uint64 public borrowFee;\n /// @notice Upfront fee taken when repaying stablecoins: this fee is optional as well. It should be smaller\n /// than the liquidation surcharge (cf below) to avoid exploits where people voluntarily get liquidated at a 0\n /// discount to pay smaller repaying fees\n uint64 public repayFee;\n /// @notice Per second interest taken to borrowers taking agToken loans. Contrarily to other parameters, it is set in `BASE_INTEREST`\n /// that is to say in base 10**27\n uint64 public interestRate;\n /// @notice Fee taken by the protocol during a liquidation. Technically, this value is not the fee per se, it's 1 - fee.\n /// For instance for a 2% fee, `liquidationSurcharge` should be 98%\n uint64 public liquidationSurcharge;\n /// @notice Maximum discount given to liquidators\n uint64 public maxLiquidationDiscount;\n /// @notice Whether whitelisting is required to own a vault or not\n bool public whitelistingActivated;\n /// @notice Whether the contract is paused or not\n bool public paused;\n\n // ================================= VARIABLES =================================\n\n /// @notice Timestamp at which the `interestAccumulator` was updated\n uint256 public lastInterestAccumulatorUpdated;\n /// @inheritdoc IVaultManagerStorage\n uint256 public interestAccumulator;\n /// @inheritdoc IVaultManagerStorage\n uint256 public totalNormalizedDebt;\n /// @notice Surplus accumulated by the contract: surplus is always in stablecoins, and is then reset\n /// when the value is communicated to the treasury contract\n uint256 public surplus;\n /// @notice Bad debt made from liquidated vaults which ended up having no collateral and a positive amount\n /// of stablecoins\n uint256 public badDebt;\n\n // ================================== MAPPINGS =================================\n\n /// @inheritdoc IVaultManagerStorage\n mapping(uint256 => Vault) public vaultData;\n /// @notice Maps an address to 1 if it's whitelisted and can open or own a vault\n mapping(address => uint256) public isWhitelisted;\n\n // ================================ ERC721 DATA ================================\n\n /// @inheritdoc IVaultManagerStorage\n uint256 public vaultIDCount;\n\n /// @notice URI\n string internal _baseURI;\n\n // Mapping from `vaultID` to owner address\n mapping(uint256 => address) internal _owners;\n\n // Mapping from owner address to vault owned count\n mapping(address => uint256) internal _balances;\n\n // Mapping from `vaultID` to approved address\n mapping(uint256 => address) internal _vaultApprovals;\n\n // Mapping from owner to operator approvals\n mapping(address => mapping(address => uint256)) internal _operatorApprovals;\n\n uint256[50] private __gap;\n\n // =================================== EVENTS ==================================\n\n event AccruedToTreasury(uint256 surplusEndValue, uint256 badDebtEndValue);\n event CollateralAmountUpdated(uint256 vaultID, uint256 collateralAmount, uint8 isIncrease);\n event InterestAccumulatorUpdated(uint256 value, uint256 timestamp);\n event InternalDebtUpdated(uint256 vaultID, uint256 internalAmount, uint8 isIncrease);\n event FiledUint64(uint64 param, bytes32 what);\n event DebtCeilingUpdated(uint256 debtCeiling);\n event LiquidationBoostParametersUpdated(address indexed _veBoostProxy, uint256[] xBoost, uint256[] yBoost);\n event LiquidatedVaults(uint256[] vaultIDs);\n event DebtTransferred(uint256 srcVaultID, uint256 dstVaultID, address dstVaultManager, uint256 amount);\n\n // =================================== ERRORS ==================================\n\n error ApprovalToOwner();\n error ApprovalToCaller();\n error DustyLeftoverAmount();\n error DebtCeilingExceeded();\n error HealthyVault();\n error IncompatibleLengths();\n error InsolventVault();\n error InvalidParameterValue();\n error InvalidParameterType();\n error InvalidSetOfParameters();\n error InvalidTreasury();\n error NonERC721Receiver();\n error NonexistentVault();\n error NotApproved();\n error NotGovernor();\n error NotGovernorOrGuardian();\n error NotTreasury();\n error NotWhitelisted();\n error NotVaultManager();\n error Paused();\n error TooHighParameterValue();\n error TooSmallParameterValue();\n error ZeroAddress();\n\n /// @custom:oz-upgrades-unsafe-allow constructor\n constructor() initializer {}\n}\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 1 + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers", + "metadata" + ], + "": [ + "ast" + ] + } + } + } +} \ No newline at end of file diff --git a/deployments/mainnet/solcInputs/871924e0c138825a2736b76def8fef8d.json b/deployments/mainnet/solcInputs/871924e0c138825a2736b76def8fef8d.json new file mode 100644 index 00000000..57454028 --- /dev/null +++ b/deployments/mainnet/solcInputs/871924e0c138825a2736b76def8fef8d.json @@ -0,0 +1,562 @@ +{ + "language": "Solidity", + "sources": { + "@chainlink/contracts/src/v0.8/interfaces/AggregatorV3Interface.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.0;\n\ninterface AggregatorV3Interface {\n\n function decimals()\n external\n view\n returns (\n uint8\n );\n\n function description()\n external\n view\n returns (\n string memory\n );\n\n function version()\n external\n view\n returns (\n uint256\n );\n\n // getRoundData and latestRoundData should both raise \"No data present\"\n // if they do not have data to report, instead of returning unset values\n // which could be misinterpreted as actual reported values.\n function getRoundData(\n uint80 _roundId\n )\n external\n view\n returns (\n uint80 roundId,\n int256 answer,\n uint256 startedAt,\n uint256 updatedAt,\n uint80 answeredInRound\n );\n\n function latestRoundData()\n external\n view\n returns (\n uint80 roundId,\n int256 answer,\n uint256 startedAt,\n uint256 updatedAt,\n uint80 answeredInRound\n );\n\n}\n" + }, + "@openzeppelin/contracts-upgradeable/access/AccessControlEnumerableUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.5.0) (access/AccessControlEnumerable.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./IAccessControlEnumerableUpgradeable.sol\";\nimport \"./AccessControlUpgradeable.sol\";\nimport \"../utils/structs/EnumerableSetUpgradeable.sol\";\nimport \"../proxy/utils/Initializable.sol\";\n\n/**\n * @dev Extension of {AccessControl} that allows enumerating the members of each role.\n */\nabstract contract AccessControlEnumerableUpgradeable is Initializable, IAccessControlEnumerableUpgradeable, AccessControlUpgradeable {\n function __AccessControlEnumerable_init() internal onlyInitializing {\n }\n\n function __AccessControlEnumerable_init_unchained() internal onlyInitializing {\n }\n using EnumerableSetUpgradeable for EnumerableSetUpgradeable.AddressSet;\n\n mapping(bytes32 => EnumerableSetUpgradeable.AddressSet) private _roleMembers;\n\n /**\n * @dev See {IERC165-supportsInterface}.\n */\n function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {\n return interfaceId == type(IAccessControlEnumerableUpgradeable).interfaceId || super.supportsInterface(interfaceId);\n }\n\n /**\n * @dev Returns one of the accounts that have `role`. `index` must be a\n * value between 0 and {getRoleMemberCount}, non-inclusive.\n *\n * Role bearers are not sorted in any particular way, and their ordering may\n * change at any point.\n *\n * WARNING: When using {getRoleMember} and {getRoleMemberCount}, make sure\n * you perform all queries on the same block. See the following\n * https://forum.openzeppelin.com/t/iterating-over-elements-on-enumerableset-in-openzeppelin-contracts/2296[forum post]\n * for more information.\n */\n function getRoleMember(bytes32 role, uint256 index) public view virtual override returns (address) {\n return _roleMembers[role].at(index);\n }\n\n /**\n * @dev Returns the number of accounts that have `role`. Can be used\n * together with {getRoleMember} to enumerate all bearers of a role.\n */\n function getRoleMemberCount(bytes32 role) public view virtual override returns (uint256) {\n return _roleMembers[role].length();\n }\n\n /**\n * @dev Overload {_grantRole} to track enumerable memberships\n */\n function _grantRole(bytes32 role, address account) internal virtual override {\n super._grantRole(role, account);\n _roleMembers[role].add(account);\n }\n\n /**\n * @dev Overload {_revokeRole} to track enumerable memberships\n */\n function _revokeRole(bytes32 role, address account) internal virtual override {\n super._revokeRole(role, account);\n _roleMembers[role].remove(account);\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[49] private __gap;\n}\n" + }, + "@openzeppelin/contracts-upgradeable/access/AccessControlUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (access/AccessControl.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./IAccessControlUpgradeable.sol\";\nimport \"../utils/ContextUpgradeable.sol\";\nimport \"../utils/StringsUpgradeable.sol\";\nimport \"../utils/introspection/ERC165Upgradeable.sol\";\nimport \"../proxy/utils/Initializable.sol\";\n\n/**\n * @dev Contract module that allows children to implement role-based access\n * control mechanisms. This is a lightweight version that doesn't allow enumerating role\n * members except through off-chain means by accessing the contract event logs. Some\n * applications may benefit from on-chain enumerability, for those cases see\n * {AccessControlEnumerable}.\n *\n * Roles are referred to by their `bytes32` identifier. These should be exposed\n * in the external API and be unique. The best way to achieve this is by\n * using `public constant` hash digests:\n *\n * ```\n * bytes32 public constant MY_ROLE = keccak256(\"MY_ROLE\");\n * ```\n *\n * Roles can be used to represent a set of permissions. To restrict access to a\n * function call, use {hasRole}:\n *\n * ```\n * function foo() public {\n * require(hasRole(MY_ROLE, msg.sender));\n * ...\n * }\n * ```\n *\n * Roles can be granted and revoked dynamically via the {grantRole} and\n * {revokeRole} functions. Each role has an associated admin role, and only\n * accounts that have a role's admin role can call {grantRole} and {revokeRole}.\n *\n * By default, the admin role for all roles is `DEFAULT_ADMIN_ROLE`, which means\n * that only accounts with this role will be able to grant or revoke other\n * roles. More complex role relationships can be created by using\n * {_setRoleAdmin}.\n *\n * WARNING: The `DEFAULT_ADMIN_ROLE` is also its own admin: it has permission to\n * grant and revoke this role. Extra precautions should be taken to secure\n * accounts that have been granted it.\n */\nabstract contract AccessControlUpgradeable is Initializable, ContextUpgradeable, IAccessControlUpgradeable, ERC165Upgradeable {\n function __AccessControl_init() internal onlyInitializing {\n }\n\n function __AccessControl_init_unchained() internal onlyInitializing {\n }\n struct RoleData {\n mapping(address => bool) members;\n bytes32 adminRole;\n }\n\n mapping(bytes32 => RoleData) private _roles;\n\n bytes32 public constant DEFAULT_ADMIN_ROLE = 0x00;\n\n /**\n * @dev Modifier that checks that an account has a specific role. Reverts\n * with a standardized message including the required role.\n *\n * The format of the revert reason is given by the following regular expression:\n *\n * /^AccessControl: account (0x[0-9a-f]{40}) is missing role (0x[0-9a-f]{64})$/\n *\n * _Available since v4.1._\n */\n modifier onlyRole(bytes32 role) {\n _checkRole(role);\n _;\n }\n\n /**\n * @dev See {IERC165-supportsInterface}.\n */\n function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {\n return interfaceId == type(IAccessControlUpgradeable).interfaceId || super.supportsInterface(interfaceId);\n }\n\n /**\n * @dev Returns `true` if `account` has been granted `role`.\n */\n function hasRole(bytes32 role, address account) public view virtual override returns (bool) {\n return _roles[role].members[account];\n }\n\n /**\n * @dev Revert with a standard message if `_msgSender()` is missing `role`.\n * Overriding this function changes the behavior of the {onlyRole} modifier.\n *\n * Format of the revert message is described in {_checkRole}.\n *\n * _Available since v4.6._\n */\n function _checkRole(bytes32 role) internal view virtual {\n _checkRole(role, _msgSender());\n }\n\n /**\n * @dev Revert with a standard message if `account` is missing `role`.\n *\n * The format of the revert reason is given by the following regular expression:\n *\n * /^AccessControl: account (0x[0-9a-f]{40}) is missing role (0x[0-9a-f]{64})$/\n */\n function _checkRole(bytes32 role, address account) internal view virtual {\n if (!hasRole(role, account)) {\n revert(\n string(\n abi.encodePacked(\n \"AccessControl: account \",\n StringsUpgradeable.toHexString(uint160(account), 20),\n \" is missing role \",\n StringsUpgradeable.toHexString(uint256(role), 32)\n )\n )\n );\n }\n }\n\n /**\n * @dev Returns the admin role that controls `role`. See {grantRole} and\n * {revokeRole}.\n *\n * To change a role's admin, use {_setRoleAdmin}.\n */\n function getRoleAdmin(bytes32 role) public view virtual override returns (bytes32) {\n return _roles[role].adminRole;\n }\n\n /**\n * @dev Grants `role` to `account`.\n *\n * If `account` had not been already granted `role`, emits a {RoleGranted}\n * event.\n *\n * Requirements:\n *\n * - the caller must have ``role``'s admin role.\n *\n * May emit a {RoleGranted} event.\n */\n function grantRole(bytes32 role, address account) public virtual override onlyRole(getRoleAdmin(role)) {\n _grantRole(role, account);\n }\n\n /**\n * @dev Revokes `role` from `account`.\n *\n * If `account` had been granted `role`, emits a {RoleRevoked} event.\n *\n * Requirements:\n *\n * - the caller must have ``role``'s admin role.\n *\n * May emit a {RoleRevoked} event.\n */\n function revokeRole(bytes32 role, address account) public virtual override onlyRole(getRoleAdmin(role)) {\n _revokeRole(role, account);\n }\n\n /**\n * @dev Revokes `role` from the calling account.\n *\n * Roles are often managed via {grantRole} and {revokeRole}: this function's\n * purpose is to provide a mechanism for accounts to lose their privileges\n * if they are compromised (such as when a trusted device is misplaced).\n *\n * If the calling account had been revoked `role`, emits a {RoleRevoked}\n * event.\n *\n * Requirements:\n *\n * - the caller must be `account`.\n *\n * May emit a {RoleRevoked} event.\n */\n function renounceRole(bytes32 role, address account) public virtual override {\n require(account == _msgSender(), \"AccessControl: can only renounce roles for self\");\n\n _revokeRole(role, account);\n }\n\n /**\n * @dev Grants `role` to `account`.\n *\n * If `account` had not been already granted `role`, emits a {RoleGranted}\n * event. Note that unlike {grantRole}, this function doesn't perform any\n * checks on the calling account.\n *\n * May emit a {RoleGranted} event.\n *\n * [WARNING]\n * ====\n * This function should only be called from the constructor when setting\n * up the initial roles for the system.\n *\n * Using this function in any other way is effectively circumventing the admin\n * system imposed by {AccessControl}.\n * ====\n *\n * NOTE: This function is deprecated in favor of {_grantRole}.\n */\n function _setupRole(bytes32 role, address account) internal virtual {\n _grantRole(role, account);\n }\n\n /**\n * @dev Sets `adminRole` as ``role``'s admin role.\n *\n * Emits a {RoleAdminChanged} event.\n */\n function _setRoleAdmin(bytes32 role, bytes32 adminRole) internal virtual {\n bytes32 previousAdminRole = getRoleAdmin(role);\n _roles[role].adminRole = adminRole;\n emit RoleAdminChanged(role, previousAdminRole, adminRole);\n }\n\n /**\n * @dev Grants `role` to `account`.\n *\n * Internal function without access restriction.\n *\n * May emit a {RoleGranted} event.\n */\n function _grantRole(bytes32 role, address account) internal virtual {\n if (!hasRole(role, account)) {\n _roles[role].members[account] = true;\n emit RoleGranted(role, account, _msgSender());\n }\n }\n\n /**\n * @dev Revokes `role` from `account`.\n *\n * Internal function without access restriction.\n *\n * May emit a {RoleRevoked} event.\n */\n function _revokeRole(bytes32 role, address account) internal virtual {\n if (hasRole(role, account)) {\n _roles[role].members[account] = false;\n emit RoleRevoked(role, account, _msgSender());\n }\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[49] private __gap;\n}\n" + }, + "@openzeppelin/contracts-upgradeable/access/IAccessControlEnumerableUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (access/IAccessControlEnumerable.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./IAccessControlUpgradeable.sol\";\n\n/**\n * @dev External interface of AccessControlEnumerable declared to support ERC165 detection.\n */\ninterface IAccessControlEnumerableUpgradeable is IAccessControlUpgradeable {\n /**\n * @dev Returns one of the accounts that have `role`. `index` must be a\n * value between 0 and {getRoleMemberCount}, non-inclusive.\n *\n * Role bearers are not sorted in any particular way, and their ordering may\n * change at any point.\n *\n * WARNING: When using {getRoleMember} and {getRoleMemberCount}, make sure\n * you perform all queries on the same block. See the following\n * https://forum.openzeppelin.com/t/iterating-over-elements-on-enumerableset-in-openzeppelin-contracts/2296[forum post]\n * for more information.\n */\n function getRoleMember(bytes32 role, uint256 index) external view returns (address);\n\n /**\n * @dev Returns the number of accounts that have `role`. Can be used\n * together with {getRoleMember} to enumerate all bearers of a role.\n */\n function getRoleMemberCount(bytes32 role) external view returns (uint256);\n}\n" + }, + "@openzeppelin/contracts-upgradeable/access/IAccessControlUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (access/IAccessControl.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev External interface of AccessControl declared to support ERC165 detection.\n */\ninterface IAccessControlUpgradeable {\n /**\n * @dev Emitted when `newAdminRole` is set as ``role``'s admin role, replacing `previousAdminRole`\n *\n * `DEFAULT_ADMIN_ROLE` is the starting admin for all roles, despite\n * {RoleAdminChanged} not being emitted signaling this.\n *\n * _Available since v3.1._\n */\n event RoleAdminChanged(bytes32 indexed role, bytes32 indexed previousAdminRole, bytes32 indexed newAdminRole);\n\n /**\n * @dev Emitted when `account` is granted `role`.\n *\n * `sender` is the account that originated the contract call, an admin role\n * bearer except when using {AccessControl-_setupRole}.\n */\n event RoleGranted(bytes32 indexed role, address indexed account, address indexed sender);\n\n /**\n * @dev Emitted when `account` is revoked `role`.\n *\n * `sender` is the account that originated the contract call:\n * - if using `revokeRole`, it is the admin role bearer\n * - if using `renounceRole`, it is the role bearer (i.e. `account`)\n */\n event RoleRevoked(bytes32 indexed role, address indexed account, address indexed sender);\n\n /**\n * @dev Returns `true` if `account` has been granted `role`.\n */\n function hasRole(bytes32 role, address account) external view returns (bool);\n\n /**\n * @dev Returns the admin role that controls `role`. See {grantRole} and\n * {revokeRole}.\n *\n * To change a role's admin, use {AccessControl-_setRoleAdmin}.\n */\n function getRoleAdmin(bytes32 role) external view returns (bytes32);\n\n /**\n * @dev Grants `role` to `account`.\n *\n * If `account` had not been already granted `role`, emits a {RoleGranted}\n * event.\n *\n * Requirements:\n *\n * - the caller must have ``role``'s admin role.\n */\n function grantRole(bytes32 role, address account) external;\n\n /**\n * @dev Revokes `role` from `account`.\n *\n * If `account` had been granted `role`, emits a {RoleRevoked} event.\n *\n * Requirements:\n *\n * - the caller must have ``role``'s admin role.\n */\n function revokeRole(bytes32 role, address account) external;\n\n /**\n * @dev Revokes `role` from the calling account.\n *\n * Roles are often managed via {grantRole} and {revokeRole}: this function's\n * purpose is to provide a mechanism for accounts to lose their privileges\n * if they are compromised (such as when a trusted device is misplaced).\n *\n * If the calling account had been granted `role`, emits a {RoleRevoked}\n * event.\n *\n * Requirements:\n *\n * - the caller must be `account`.\n */\n function renounceRole(bytes32 role, address account) external;\n}\n" + }, + "@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (access/Ownable.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../utils/ContextUpgradeable.sol\";\nimport \"../proxy/utils/Initializable.sol\";\n\n/**\n * @dev Contract module which provides a basic access control mechanism, where\n * there is an account (an owner) that can be granted exclusive access to\n * specific functions.\n *\n * By default, the owner account will be the one that deploys the contract. This\n * can later be changed with {transferOwnership}.\n *\n * This module is used through inheritance. It will make available the modifier\n * `onlyOwner`, which can be applied to your functions to restrict their use to\n * the owner.\n */\nabstract contract OwnableUpgradeable is Initializable, ContextUpgradeable {\n address private _owner;\n\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\n\n /**\n * @dev Initializes the contract setting the deployer as the initial owner.\n */\n function __Ownable_init() internal onlyInitializing {\n __Ownable_init_unchained();\n }\n\n function __Ownable_init_unchained() internal onlyInitializing {\n _transferOwnership(_msgSender());\n }\n\n /**\n * @dev Throws if called by any account other than the owner.\n */\n modifier onlyOwner() {\n _checkOwner();\n _;\n }\n\n /**\n * @dev Returns the address of the current owner.\n */\n function owner() public view virtual returns (address) {\n return _owner;\n }\n\n /**\n * @dev Throws if the sender is not the owner.\n */\n function _checkOwner() internal view virtual {\n require(owner() == _msgSender(), \"Ownable: caller is not the owner\");\n }\n\n /**\n * @dev Leaves the contract without owner. It will not be possible to call\n * `onlyOwner` functions anymore. Can only be called by the current owner.\n *\n * NOTE: Renouncing ownership will leave the contract without an owner,\n * thereby removing any functionality that is only available to the owner.\n */\n function renounceOwnership() public virtual onlyOwner {\n _transferOwnership(address(0));\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Can only be called by the current owner.\n */\n function transferOwnership(address newOwner) public virtual onlyOwner {\n require(newOwner != address(0), \"Ownable: new owner is the zero address\");\n _transferOwnership(newOwner);\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Internal function without access restriction.\n */\n function _transferOwnership(address newOwner) internal virtual {\n address oldOwner = _owner;\n _owner = newOwner;\n emit OwnershipTransferred(oldOwner, newOwner);\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[49] private __gap;\n}\n" + }, + "@openzeppelin/contracts-upgradeable/interfaces/IERC721MetadataUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (interfaces/IERC721Metadata.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../token/ERC721/extensions/IERC721MetadataUpgradeable.sol\";\n" + }, + "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (proxy/utils/Initializable.sol)\n\npragma solidity ^0.8.2;\n\nimport \"../../utils/AddressUpgradeable.sol\";\n\n/**\n * @dev This is a base contract to aid in writing upgradeable contracts, or any kind of contract that will be deployed\n * behind a proxy. Since proxied contracts do not make use of a constructor, it's common to move constructor logic to an\n * external initializer function, usually called `initialize`. It then becomes necessary to protect this initializer\n * function so it can only be called once. The {initializer} modifier provided by this contract will have this effect.\n *\n * The initialization functions use a version number. Once a version number is used, it is consumed and cannot be\n * reused. This mechanism prevents re-execution of each \"step\" but allows the creation of new initialization steps in\n * case an upgrade adds a module that needs to be initialized.\n *\n * For example:\n *\n * [.hljs-theme-light.nopadding]\n * ```\n * contract MyToken is ERC20Upgradeable {\n * function initialize() initializer public {\n * __ERC20_init(\"MyToken\", \"MTK\");\n * }\n * }\n * contract MyTokenV2 is MyToken, ERC20PermitUpgradeable {\n * function initializeV2() reinitializer(2) public {\n * __ERC20Permit_init(\"MyToken\");\n * }\n * }\n * ```\n *\n * TIP: To avoid leaving the proxy in an uninitialized state, the initializer function should be called as early as\n * possible by providing the encoded function call as the `_data` argument to {ERC1967Proxy-constructor}.\n *\n * CAUTION: When used with inheritance, manual care must be taken to not invoke a parent initializer twice, or to ensure\n * that all initializers are idempotent. This is not verified automatically as constructors are by Solidity.\n *\n * [CAUTION]\n * ====\n * Avoid leaving a contract uninitialized.\n *\n * An uninitialized contract can be taken over by an attacker. This applies to both a proxy and its implementation\n * contract, which may impact the proxy. To prevent the implementation contract from being used, you should invoke\n * the {_disableInitializers} function in the constructor to automatically lock it when it is deployed:\n *\n * [.hljs-theme-light.nopadding]\n * ```\n * /// @custom:oz-upgrades-unsafe-allow constructor\n * constructor() {\n * _disableInitializers();\n * }\n * ```\n * ====\n */\nabstract contract Initializable {\n /**\n * @dev Indicates that the contract has been initialized.\n * @custom:oz-retyped-from bool\n */\n uint8 private _initialized;\n\n /**\n * @dev Indicates that the contract is in the process of being initialized.\n */\n bool private _initializing;\n\n /**\n * @dev Triggered when the contract has been initialized or reinitialized.\n */\n event Initialized(uint8 version);\n\n /**\n * @dev A modifier that defines a protected initializer function that can be invoked at most once. In its scope,\n * `onlyInitializing` functions can be used to initialize parent contracts. Equivalent to `reinitializer(1)`.\n */\n modifier initializer() {\n bool isTopLevelCall = !_initializing;\n require(\n (isTopLevelCall && _initialized < 1) || (!AddressUpgradeable.isContract(address(this)) && _initialized == 1),\n \"Initializable: contract is already initialized\"\n );\n _initialized = 1;\n if (isTopLevelCall) {\n _initializing = true;\n }\n _;\n if (isTopLevelCall) {\n _initializing = false;\n emit Initialized(1);\n }\n }\n\n /**\n * @dev A modifier that defines a protected reinitializer function that can be invoked at most once, and only if the\n * contract hasn't been initialized to a greater version before. In its scope, `onlyInitializing` functions can be\n * used to initialize parent contracts.\n *\n * `initializer` is equivalent to `reinitializer(1)`, so a reinitializer may be used after the original\n * initialization step. This is essential to configure modules that are added through upgrades and that require\n * initialization.\n *\n * Note that versions can jump in increments greater than 1; this implies that if multiple reinitializers coexist in\n * a contract, executing them in the right order is up to the developer or operator.\n */\n modifier reinitializer(uint8 version) {\n require(!_initializing && _initialized < version, \"Initializable: contract is already initialized\");\n _initialized = version;\n _initializing = true;\n _;\n _initializing = false;\n emit Initialized(version);\n }\n\n /**\n * @dev Modifier to protect an initialization function so that it can only be invoked by functions with the\n * {initializer} and {reinitializer} modifiers, directly or indirectly.\n */\n modifier onlyInitializing() {\n require(_initializing, \"Initializable: contract is not initializing\");\n _;\n }\n\n /**\n * @dev Locks the contract, preventing any future reinitialization. This cannot be part of an initializer call.\n * Calling this in the constructor of a contract will prevent that contract from being initialized or reinitialized\n * to any version. It is recommended to use this to lock implementation contracts that are designed to be called\n * through proxies.\n */\n function _disableInitializers() internal virtual {\n require(!_initializing, \"Initializable: contract is initializing\");\n if (_initialized < type(uint8).max) {\n _initialized = type(uint8).max;\n emit Initialized(type(uint8).max);\n }\n }\n}\n" + }, + "@openzeppelin/contracts-upgradeable/security/PausableUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (security/Pausable.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../utils/ContextUpgradeable.sol\";\nimport \"../proxy/utils/Initializable.sol\";\n\n/**\n * @dev Contract module which allows children to implement an emergency stop\n * mechanism that can be triggered by an authorized account.\n *\n * This module is used through inheritance. It will make available the\n * modifiers `whenNotPaused` and `whenPaused`, which can be applied to\n * the functions of your contract. Note that they will not be pausable by\n * simply including this module, only once the modifiers are put in place.\n */\nabstract contract PausableUpgradeable is Initializable, ContextUpgradeable {\n /**\n * @dev Emitted when the pause is triggered by `account`.\n */\n event Paused(address account);\n\n /**\n * @dev Emitted when the pause is lifted by `account`.\n */\n event Unpaused(address account);\n\n bool private _paused;\n\n /**\n * @dev Initializes the contract in unpaused state.\n */\n function __Pausable_init() internal onlyInitializing {\n __Pausable_init_unchained();\n }\n\n function __Pausable_init_unchained() internal onlyInitializing {\n _paused = false;\n }\n\n /**\n * @dev Modifier to make a function callable only when the contract is not paused.\n *\n * Requirements:\n *\n * - The contract must not be paused.\n */\n modifier whenNotPaused() {\n _requireNotPaused();\n _;\n }\n\n /**\n * @dev Modifier to make a function callable only when the contract is paused.\n *\n * Requirements:\n *\n * - The contract must be paused.\n */\n modifier whenPaused() {\n _requirePaused();\n _;\n }\n\n /**\n * @dev Returns true if the contract is paused, and false otherwise.\n */\n function paused() public view virtual returns (bool) {\n return _paused;\n }\n\n /**\n * @dev Throws if the contract is paused.\n */\n function _requireNotPaused() internal view virtual {\n require(!paused(), \"Pausable: paused\");\n }\n\n /**\n * @dev Throws if the contract is not paused.\n */\n function _requirePaused() internal view virtual {\n require(paused(), \"Pausable: not paused\");\n }\n\n /**\n * @dev Triggers stopped state.\n *\n * Requirements:\n *\n * - The contract must not be paused.\n */\n function _pause() internal virtual whenNotPaused {\n _paused = true;\n emit Paused(_msgSender());\n }\n\n /**\n * @dev Returns to normal state.\n *\n * Requirements:\n *\n * - The contract must be paused.\n */\n function _unpause() internal virtual whenPaused {\n _paused = false;\n emit Unpaused(_msgSender());\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[49] private __gap;\n}\n" + }, + "@openzeppelin/contracts-upgradeable/security/ReentrancyGuardUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (security/ReentrancyGuard.sol)\n\npragma solidity ^0.8.0;\nimport \"../proxy/utils/Initializable.sol\";\n\n/**\n * @dev Contract module that helps prevent reentrant calls to a function.\n *\n * Inheriting from `ReentrancyGuard` will make the {nonReentrant} modifier\n * available, which can be applied to functions to make sure there are no nested\n * (reentrant) calls to them.\n *\n * Note that because there is a single `nonReentrant` guard, functions marked as\n * `nonReentrant` may not call one another. This can be worked around by making\n * those functions `private`, and then adding `external` `nonReentrant` entry\n * points to them.\n *\n * TIP: If you would like to learn more about reentrancy and alternative ways\n * to protect against it, check out our blog post\n * https://blog.openzeppelin.com/reentrancy-after-istanbul/[Reentrancy After Istanbul].\n */\nabstract contract ReentrancyGuardUpgradeable is Initializable {\n // Booleans are more expensive than uint256 or any type that takes up a full\n // word because each write operation emits an extra SLOAD to first read the\n // slot's contents, replace the bits taken up by the boolean, and then write\n // back. This is the compiler's defense against contract upgrades and\n // pointer aliasing, and it cannot be disabled.\n\n // The values being non-zero value makes deployment a bit more expensive,\n // but in exchange the refund on every call to nonReentrant will be lower in\n // amount. Since refunds are capped to a percentage of the total\n // transaction's gas, it is best to keep them low in cases like this one, to\n // increase the likelihood of the full refund coming into effect.\n uint256 private constant _NOT_ENTERED = 1;\n uint256 private constant _ENTERED = 2;\n\n uint256 private _status;\n\n function __ReentrancyGuard_init() internal onlyInitializing {\n __ReentrancyGuard_init_unchained();\n }\n\n function __ReentrancyGuard_init_unchained() internal onlyInitializing {\n _status = _NOT_ENTERED;\n }\n\n /**\n * @dev Prevents a contract from calling itself, directly or indirectly.\n * Calling a `nonReentrant` function from another `nonReentrant`\n * function is not supported. It is possible to prevent this from happening\n * by making the `nonReentrant` function external, and making it call a\n * `private` function that does the actual work.\n */\n modifier nonReentrant() {\n // On the first call to nonReentrant, _notEntered will be true\n require(_status != _ENTERED, \"ReentrancyGuard: reentrant call\");\n\n // Any calls to nonReentrant after this point will fail\n _status = _ENTERED;\n\n _;\n\n // By storing the original value once again, a refund is triggered (see\n // https://eips.ethereum.org/EIPS/eip-2200)\n _status = _NOT_ENTERED;\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[49] private __gap;\n}\n" + }, + "@openzeppelin/contracts-upgradeable/token/ERC20/ERC20Upgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (token/ERC20/ERC20.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./IERC20Upgradeable.sol\";\nimport \"./extensions/IERC20MetadataUpgradeable.sol\";\nimport \"../../utils/ContextUpgradeable.sol\";\nimport \"../../proxy/utils/Initializable.sol\";\n\n/**\n * @dev Implementation of the {IERC20} interface.\n *\n * This implementation is agnostic to the way tokens are created. This means\n * that a supply mechanism has to be added in a derived contract using {_mint}.\n * For a generic mechanism see {ERC20PresetMinterPauser}.\n *\n * TIP: For a detailed writeup see our guide\n * https://forum.zeppelin.solutions/t/how-to-implement-erc20-supply-mechanisms/226[How\n * to implement supply mechanisms].\n *\n * We have followed general OpenZeppelin Contracts guidelines: functions revert\n * instead returning `false` on failure. This behavior is nonetheless\n * conventional and does not conflict with the expectations of ERC20\n * applications.\n *\n * Additionally, an {Approval} event is emitted on calls to {transferFrom}.\n * This allows applications to reconstruct the allowance for all accounts just\n * by listening to said events. Other implementations of the EIP may not emit\n * these events, as it isn't required by the specification.\n *\n * Finally, the non-standard {decreaseAllowance} and {increaseAllowance}\n * functions have been added to mitigate the well-known issues around setting\n * allowances. See {IERC20-approve}.\n */\ncontract ERC20Upgradeable is Initializable, ContextUpgradeable, IERC20Upgradeable, IERC20MetadataUpgradeable {\n mapping(address => uint256) private _balances;\n\n mapping(address => mapping(address => uint256)) private _allowances;\n\n uint256 private _totalSupply;\n\n string private _name;\n string private _symbol;\n\n /**\n * @dev Sets the values for {name} and {symbol}.\n *\n * The default value of {decimals} is 18. To select a different value for\n * {decimals} you should overload it.\n *\n * All two of these values are immutable: they can only be set once during\n * construction.\n */\n function __ERC20_init(string memory name_, string memory symbol_) internal onlyInitializing {\n __ERC20_init_unchained(name_, symbol_);\n }\n\n function __ERC20_init_unchained(string memory name_, string memory symbol_) internal onlyInitializing {\n _name = name_;\n _symbol = symbol_;\n }\n\n /**\n * @dev Returns the name of the token.\n */\n function name() public view virtual override returns (string memory) {\n return _name;\n }\n\n /**\n * @dev Returns the symbol of the token, usually a shorter version of the\n * name.\n */\n function symbol() public view virtual override returns (string memory) {\n return _symbol;\n }\n\n /**\n * @dev Returns the number of decimals used to get its user representation.\n * For example, if `decimals` equals `2`, a balance of `505` tokens should\n * be displayed to a user as `5.05` (`505 / 10 ** 2`).\n *\n * Tokens usually opt for a value of 18, imitating the relationship between\n * Ether and Wei. This is the value {ERC20} uses, unless this function is\n * overridden;\n *\n * NOTE: This information is only used for _display_ purposes: it in\n * no way affects any of the arithmetic of the contract, including\n * {IERC20-balanceOf} and {IERC20-transfer}.\n */\n function decimals() public view virtual override returns (uint8) {\n return 18;\n }\n\n /**\n * @dev See {IERC20-totalSupply}.\n */\n function totalSupply() public view virtual override returns (uint256) {\n return _totalSupply;\n }\n\n /**\n * @dev See {IERC20-balanceOf}.\n */\n function balanceOf(address account) public view virtual override returns (uint256) {\n return _balances[account];\n }\n\n /**\n * @dev See {IERC20-transfer}.\n *\n * Requirements:\n *\n * - `to` cannot be the zero address.\n * - the caller must have a balance of at least `amount`.\n */\n function transfer(address to, uint256 amount) public virtual override returns (bool) {\n address owner = _msgSender();\n _transfer(owner, to, amount);\n return true;\n }\n\n /**\n * @dev See {IERC20-allowance}.\n */\n function allowance(address owner, address spender) public view virtual override returns (uint256) {\n return _allowances[owner][spender];\n }\n\n /**\n * @dev See {IERC20-approve}.\n *\n * NOTE: If `amount` is the maximum `uint256`, the allowance is not updated on\n * `transferFrom`. This is semantically equivalent to an infinite approval.\n *\n * Requirements:\n *\n * - `spender` cannot be the zero address.\n */\n function approve(address spender, uint256 amount) public virtual override returns (bool) {\n address owner = _msgSender();\n _approve(owner, spender, amount);\n return true;\n }\n\n /**\n * @dev See {IERC20-transferFrom}.\n *\n * Emits an {Approval} event indicating the updated allowance. This is not\n * required by the EIP. See the note at the beginning of {ERC20}.\n *\n * NOTE: Does not update the allowance if the current allowance\n * is the maximum `uint256`.\n *\n * Requirements:\n *\n * - `from` and `to` cannot be the zero address.\n * - `from` must have a balance of at least `amount`.\n * - the caller must have allowance for ``from``'s tokens of at least\n * `amount`.\n */\n function transferFrom(\n address from,\n address to,\n uint256 amount\n ) public virtual override returns (bool) {\n address spender = _msgSender();\n _spendAllowance(from, spender, amount);\n _transfer(from, to, amount);\n return true;\n }\n\n /**\n * @dev Atomically increases the allowance granted to `spender` by the caller.\n *\n * This is an alternative to {approve} that can be used as a mitigation for\n * problems described in {IERC20-approve}.\n *\n * Emits an {Approval} event indicating the updated allowance.\n *\n * Requirements:\n *\n * - `spender` cannot be the zero address.\n */\n function increaseAllowance(address spender, uint256 addedValue) public virtual returns (bool) {\n address owner = _msgSender();\n _approve(owner, spender, allowance(owner, spender) + addedValue);\n return true;\n }\n\n /**\n * @dev Atomically decreases the allowance granted to `spender` by the caller.\n *\n * This is an alternative to {approve} that can be used as a mitigation for\n * problems described in {IERC20-approve}.\n *\n * Emits an {Approval} event indicating the updated allowance.\n *\n * Requirements:\n *\n * - `spender` cannot be the zero address.\n * - `spender` must have allowance for the caller of at least\n * `subtractedValue`.\n */\n function decreaseAllowance(address spender, uint256 subtractedValue) public virtual returns (bool) {\n address owner = _msgSender();\n uint256 currentAllowance = allowance(owner, spender);\n require(currentAllowance >= subtractedValue, \"ERC20: decreased allowance below zero\");\n unchecked {\n _approve(owner, spender, currentAllowance - subtractedValue);\n }\n\n return true;\n }\n\n /**\n * @dev Moves `amount` of tokens from `from` to `to`.\n *\n * This internal function is equivalent to {transfer}, and can be used to\n * e.g. implement automatic token fees, slashing mechanisms, etc.\n *\n * Emits a {Transfer} event.\n *\n * Requirements:\n *\n * - `from` cannot be the zero address.\n * - `to` cannot be the zero address.\n * - `from` must have a balance of at least `amount`.\n */\n function _transfer(\n address from,\n address to,\n uint256 amount\n ) internal virtual {\n require(from != address(0), \"ERC20: transfer from the zero address\");\n require(to != address(0), \"ERC20: transfer to the zero address\");\n\n _beforeTokenTransfer(from, to, amount);\n\n uint256 fromBalance = _balances[from];\n require(fromBalance >= amount, \"ERC20: transfer amount exceeds balance\");\n unchecked {\n _balances[from] = fromBalance - amount;\n }\n _balances[to] += amount;\n\n emit Transfer(from, to, amount);\n\n _afterTokenTransfer(from, to, amount);\n }\n\n /** @dev Creates `amount` tokens and assigns them to `account`, increasing\n * the total supply.\n *\n * Emits a {Transfer} event with `from` set to the zero address.\n *\n * Requirements:\n *\n * - `account` cannot be the zero address.\n */\n function _mint(address account, uint256 amount) internal virtual {\n require(account != address(0), \"ERC20: mint to the zero address\");\n\n _beforeTokenTransfer(address(0), account, amount);\n\n _totalSupply += amount;\n _balances[account] += amount;\n emit Transfer(address(0), account, amount);\n\n _afterTokenTransfer(address(0), account, amount);\n }\n\n /**\n * @dev Destroys `amount` tokens from `account`, reducing the\n * total supply.\n *\n * Emits a {Transfer} event with `to` set to the zero address.\n *\n * Requirements:\n *\n * - `account` cannot be the zero address.\n * - `account` must have at least `amount` tokens.\n */\n function _burn(address account, uint256 amount) internal virtual {\n require(account != address(0), \"ERC20: burn from the zero address\");\n\n _beforeTokenTransfer(account, address(0), amount);\n\n uint256 accountBalance = _balances[account];\n require(accountBalance >= amount, \"ERC20: burn amount exceeds balance\");\n unchecked {\n _balances[account] = accountBalance - amount;\n }\n _totalSupply -= amount;\n\n emit Transfer(account, address(0), amount);\n\n _afterTokenTransfer(account, address(0), amount);\n }\n\n /**\n * @dev Sets `amount` as the allowance of `spender` over the `owner` s tokens.\n *\n * This internal function is equivalent to `approve`, and can be used to\n * e.g. set automatic allowances for certain subsystems, etc.\n *\n * Emits an {Approval} event.\n *\n * Requirements:\n *\n * - `owner` cannot be the zero address.\n * - `spender` cannot be the zero address.\n */\n function _approve(\n address owner,\n address spender,\n uint256 amount\n ) internal virtual {\n require(owner != address(0), \"ERC20: approve from the zero address\");\n require(spender != address(0), \"ERC20: approve to the zero address\");\n\n _allowances[owner][spender] = amount;\n emit Approval(owner, spender, amount);\n }\n\n /**\n * @dev Updates `owner` s allowance for `spender` based on spent `amount`.\n *\n * Does not update the allowance amount in case of infinite allowance.\n * Revert if not enough allowance is available.\n *\n * Might emit an {Approval} event.\n */\n function _spendAllowance(\n address owner,\n address spender,\n uint256 amount\n ) internal virtual {\n uint256 currentAllowance = allowance(owner, spender);\n if (currentAllowance != type(uint256).max) {\n require(currentAllowance >= amount, \"ERC20: insufficient allowance\");\n unchecked {\n _approve(owner, spender, currentAllowance - amount);\n }\n }\n }\n\n /**\n * @dev Hook that is called before any transfer of tokens. This includes\n * minting and burning.\n *\n * Calling conditions:\n *\n * - when `from` and `to` are both non-zero, `amount` of ``from``'s tokens\n * will be transferred to `to`.\n * - when `from` is zero, `amount` tokens will be minted for `to`.\n * - when `to` is zero, `amount` of ``from``'s tokens will be burned.\n * - `from` and `to` are never both zero.\n *\n * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].\n */\n function _beforeTokenTransfer(\n address from,\n address to,\n uint256 amount\n ) internal virtual {}\n\n /**\n * @dev Hook that is called after any transfer of tokens. This includes\n * minting and burning.\n *\n * Calling conditions:\n *\n * - when `from` and `to` are both non-zero, `amount` of ``from``'s tokens\n * has been transferred to `to`.\n * - when `from` is zero, `amount` tokens have been minted for `to`.\n * - when `to` is zero, `amount` of ``from``'s tokens have been burned.\n * - `from` and `to` are never both zero.\n *\n * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].\n */\n function _afterTokenTransfer(\n address from,\n address to,\n uint256 amount\n ) internal virtual {}\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[45] private __gap;\n}\n" + }, + "@openzeppelin/contracts-upgradeable/token/ERC20/extensions/draft-ERC20PermitUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.6.0) (token/ERC20/extensions/draft-ERC20Permit.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./draft-IERC20PermitUpgradeable.sol\";\nimport \"../ERC20Upgradeable.sol\";\nimport \"../../../utils/cryptography/draft-EIP712Upgradeable.sol\";\nimport \"../../../utils/cryptography/ECDSAUpgradeable.sol\";\nimport \"../../../utils/CountersUpgradeable.sol\";\nimport \"../../../proxy/utils/Initializable.sol\";\n\n/**\n * @dev Implementation of the ERC20 Permit extension allowing approvals to be made via signatures, as defined in\n * https://eips.ethereum.org/EIPS/eip-2612[EIP-2612].\n *\n * Adds the {permit} method, which can be used to change an account's ERC20 allowance (see {IERC20-allowance}) by\n * presenting a message signed by the account. By not relying on `{IERC20-approve}`, the token holder account doesn't\n * need to send a transaction, and thus is not required to hold Ether at all.\n *\n * _Available since v3.4._\n *\n * @custom:storage-size 51\n */\nabstract contract ERC20PermitUpgradeable is Initializable, ERC20Upgradeable, IERC20PermitUpgradeable, EIP712Upgradeable {\n using CountersUpgradeable for CountersUpgradeable.Counter;\n\n mapping(address => CountersUpgradeable.Counter) private _nonces;\n\n // solhint-disable-next-line var-name-mixedcase\n bytes32 private constant _PERMIT_TYPEHASH =\n keccak256(\"Permit(address owner,address spender,uint256 value,uint256 nonce,uint256 deadline)\");\n /**\n * @dev In previous versions `_PERMIT_TYPEHASH` was declared as `immutable`.\n * However, to ensure consistency with the upgradeable transpiler, we will continue\n * to reserve a slot.\n * @custom:oz-renamed-from _PERMIT_TYPEHASH\n */\n // solhint-disable-next-line var-name-mixedcase\n bytes32 private _PERMIT_TYPEHASH_DEPRECATED_SLOT;\n\n /**\n * @dev Initializes the {EIP712} domain separator using the `name` parameter, and setting `version` to `\"1\"`.\n *\n * It's a good idea to use the same `name` that is defined as the ERC20 token name.\n */\n function __ERC20Permit_init(string memory name) internal onlyInitializing {\n __EIP712_init_unchained(name, \"1\");\n }\n\n function __ERC20Permit_init_unchained(string memory) internal onlyInitializing {}\n\n /**\n * @dev See {IERC20Permit-permit}.\n */\n function permit(\n address owner,\n address spender,\n uint256 value,\n uint256 deadline,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) public virtual override {\n require(block.timestamp <= deadline, \"ERC20Permit: expired deadline\");\n\n bytes32 structHash = keccak256(abi.encode(_PERMIT_TYPEHASH, owner, spender, value, _useNonce(owner), deadline));\n\n bytes32 hash = _hashTypedDataV4(structHash);\n\n address signer = ECDSAUpgradeable.recover(hash, v, r, s);\n require(signer == owner, \"ERC20Permit: invalid signature\");\n\n _approve(owner, spender, value);\n }\n\n /**\n * @dev See {IERC20Permit-nonces}.\n */\n function nonces(address owner) public view virtual override returns (uint256) {\n return _nonces[owner].current();\n }\n\n /**\n * @dev See {IERC20Permit-DOMAIN_SEPARATOR}.\n */\n // solhint-disable-next-line func-name-mixedcase\n function DOMAIN_SEPARATOR() external view override returns (bytes32) {\n return _domainSeparatorV4();\n }\n\n /**\n * @dev \"Consume a nonce\": return the current value and increment.\n *\n * _Available since v4.1._\n */\n function _useNonce(address owner) internal virtual returns (uint256 current) {\n CountersUpgradeable.Counter storage nonce = _nonces[owner];\n current = nonce.current();\n nonce.increment();\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[49] private __gap;\n}\n" + }, + "@openzeppelin/contracts-upgradeable/token/ERC20/extensions/draft-IERC20PermitUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (token/ERC20/extensions/draft-IERC20Permit.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Interface of the ERC20 Permit extension allowing approvals to be made via signatures, as defined in\n * https://eips.ethereum.org/EIPS/eip-2612[EIP-2612].\n *\n * Adds the {permit} method, which can be used to change an account's ERC20 allowance (see {IERC20-allowance}) by\n * presenting a message signed by the account. By not relying on {IERC20-approve}, the token holder account doesn't\n * need to send a transaction, and thus is not required to hold Ether at all.\n */\ninterface IERC20PermitUpgradeable {\n /**\n * @dev Sets `value` as the allowance of `spender` over ``owner``'s tokens,\n * given ``owner``'s signed approval.\n *\n * IMPORTANT: The same issues {IERC20-approve} has related to transaction\n * ordering also apply here.\n *\n * Emits an {Approval} event.\n *\n * Requirements:\n *\n * - `spender` cannot be the zero address.\n * - `deadline` must be a timestamp in the future.\n * - `v`, `r` and `s` must be a valid `secp256k1` signature from `owner`\n * over the EIP712-formatted function arguments.\n * - the signature must use ``owner``'s current nonce (see {nonces}).\n *\n * For more information on the signature format, see the\n * https://eips.ethereum.org/EIPS/eip-2612#specification[relevant EIP\n * section].\n */\n function permit(\n address owner,\n address spender,\n uint256 value,\n uint256 deadline,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) external;\n\n /**\n * @dev Returns the current nonce for `owner`. This value must be\n * included whenever a signature is generated for {permit}.\n *\n * Every successful call to {permit} increases ``owner``'s nonce by one. This\n * prevents a signature from being used multiple times.\n */\n function nonces(address owner) external view returns (uint256);\n\n /**\n * @dev Returns the domain separator used in the encoding of the signature for {permit}, as defined by {EIP712}.\n */\n // solhint-disable-next-line func-name-mixedcase\n function DOMAIN_SEPARATOR() external view returns (bytes32);\n}\n" + }, + "@openzeppelin/contracts-upgradeable/token/ERC20/extensions/IERC20MetadataUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (token/ERC20/extensions/IERC20Metadata.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../IERC20Upgradeable.sol\";\n\n/**\n * @dev Interface for the optional metadata functions from the ERC20 standard.\n *\n * _Available since v4.1._\n */\ninterface IERC20MetadataUpgradeable is IERC20Upgradeable {\n /**\n * @dev Returns the name of the token.\n */\n function name() external view returns (string memory);\n\n /**\n * @dev Returns the symbol of the token.\n */\n function symbol() external view returns (string memory);\n\n /**\n * @dev Returns the decimals places of the token.\n */\n function decimals() external view returns (uint8);\n}\n" + }, + "@openzeppelin/contracts-upgradeable/token/ERC20/IERC20Upgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.6.0) (token/ERC20/IERC20.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Interface of the ERC20 standard as defined in the EIP.\n */\ninterface IERC20Upgradeable {\n /**\n * @dev Emitted when `value` tokens are moved from one account (`from`) to\n * another (`to`).\n *\n * Note that `value` may be zero.\n */\n event Transfer(address indexed from, address indexed to, uint256 value);\n\n /**\n * @dev Emitted when the allowance of a `spender` for an `owner` is set by\n * a call to {approve}. `value` is the new allowance.\n */\n event Approval(address indexed owner, address indexed spender, uint256 value);\n\n /**\n * @dev Returns the amount of tokens in existence.\n */\n function totalSupply() external view returns (uint256);\n\n /**\n * @dev Returns the amount of tokens owned by `account`.\n */\n function balanceOf(address account) external view returns (uint256);\n\n /**\n * @dev Moves `amount` tokens from the caller's account to `to`.\n *\n * Returns a boolean value indicating whether the operation succeeded.\n *\n * Emits a {Transfer} event.\n */\n function transfer(address to, uint256 amount) external returns (bool);\n\n /**\n * @dev Returns the remaining number of tokens that `spender` will be\n * allowed to spend on behalf of `owner` through {transferFrom}. This is\n * zero by default.\n *\n * This value changes when {approve} or {transferFrom} are called.\n */\n function allowance(address owner, address spender) external view returns (uint256);\n\n /**\n * @dev Sets `amount` as the allowance of `spender` over the caller's tokens.\n *\n * Returns a boolean value indicating whether the operation succeeded.\n *\n * IMPORTANT: Beware that changing an allowance with this method brings the risk\n * that someone may use both the old and the new allowance by unfortunate\n * transaction ordering. One possible solution to mitigate this race\n * condition is to first reduce the spender's allowance to 0 and set the\n * desired value afterwards:\n * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729\n *\n * Emits an {Approval} event.\n */\n function approve(address spender, uint256 amount) external returns (bool);\n\n /**\n * @dev Moves `amount` tokens from `from` to `to` using the\n * allowance mechanism. `amount` is then deducted from the caller's\n * allowance.\n *\n * Returns a boolean value indicating whether the operation succeeded.\n *\n * Emits a {Transfer} event.\n */\n function transferFrom(\n address from,\n address to,\n uint256 amount\n ) external returns (bool);\n}\n" + }, + "@openzeppelin/contracts-upgradeable/token/ERC721/extensions/IERC721MetadataUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (token/ERC721/extensions/IERC721Metadata.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../IERC721Upgradeable.sol\";\n\n/**\n * @title ERC-721 Non-Fungible Token Standard, optional metadata extension\n * @dev See https://eips.ethereum.org/EIPS/eip-721\n */\ninterface IERC721MetadataUpgradeable is IERC721Upgradeable {\n /**\n * @dev Returns the token collection name.\n */\n function name() external view returns (string memory);\n\n /**\n * @dev Returns the token collection symbol.\n */\n function symbol() external view returns (string memory);\n\n /**\n * @dev Returns the Uniform Resource Identifier (URI) for `tokenId` token.\n */\n function tokenURI(uint256 tokenId) external view returns (string memory);\n}\n" + }, + "@openzeppelin/contracts-upgradeable/token/ERC721/IERC721ReceiverUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.6.0) (token/ERC721/IERC721Receiver.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @title ERC721 token receiver interface\n * @dev Interface for any contract that wants to support safeTransfers\n * from ERC721 asset contracts.\n */\ninterface IERC721ReceiverUpgradeable {\n /**\n * @dev Whenever an {IERC721} `tokenId` token is transferred to this contract via {IERC721-safeTransferFrom}\n * by `operator` from `from`, this function is called.\n *\n * It must return its Solidity selector to confirm the token transfer.\n * If any other value is returned or the interface is not implemented by the recipient, the transfer will be reverted.\n *\n * The selector can be obtained in Solidity with `IERC721Receiver.onERC721Received.selector`.\n */\n function onERC721Received(\n address operator,\n address from,\n uint256 tokenId,\n bytes calldata data\n ) external returns (bytes4);\n}\n" + }, + "@openzeppelin/contracts-upgradeable/token/ERC721/IERC721Upgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (token/ERC721/IERC721.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../../utils/introspection/IERC165Upgradeable.sol\";\n\n/**\n * @dev Required interface of an ERC721 compliant contract.\n */\ninterface IERC721Upgradeable is IERC165Upgradeable {\n /**\n * @dev Emitted when `tokenId` token is transferred from `from` to `to`.\n */\n event Transfer(address indexed from, address indexed to, uint256 indexed tokenId);\n\n /**\n * @dev Emitted when `owner` enables `approved` to manage the `tokenId` token.\n */\n event Approval(address indexed owner, address indexed approved, uint256 indexed tokenId);\n\n /**\n * @dev Emitted when `owner` enables or disables (`approved`) `operator` to manage all of its assets.\n */\n event ApprovalForAll(address indexed owner, address indexed operator, bool approved);\n\n /**\n * @dev Returns the number of tokens in ``owner``'s account.\n */\n function balanceOf(address owner) external view returns (uint256 balance);\n\n /**\n * @dev Returns the owner of the `tokenId` token.\n *\n * Requirements:\n *\n * - `tokenId` must exist.\n */\n function ownerOf(uint256 tokenId) external view returns (address owner);\n\n /**\n * @dev Safely transfers `tokenId` token from `from` to `to`.\n *\n * Requirements:\n *\n * - `from` cannot be the zero address.\n * - `to` cannot be the zero address.\n * - `tokenId` token must exist and be owned by `from`.\n * - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}.\n * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.\n *\n * Emits a {Transfer} event.\n */\n function safeTransferFrom(\n address from,\n address to,\n uint256 tokenId,\n bytes calldata data\n ) external;\n\n /**\n * @dev Safely transfers `tokenId` token from `from` to `to`, checking first that contract recipients\n * are aware of the ERC721 protocol to prevent tokens from being forever locked.\n *\n * Requirements:\n *\n * - `from` cannot be the zero address.\n * - `to` cannot be the zero address.\n * - `tokenId` token must exist and be owned by `from`.\n * - If the caller is not `from`, it must have been allowed to move this token by either {approve} or {setApprovalForAll}.\n * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.\n *\n * Emits a {Transfer} event.\n */\n function safeTransferFrom(\n address from,\n address to,\n uint256 tokenId\n ) external;\n\n /**\n * @dev Transfers `tokenId` token from `from` to `to`.\n *\n * WARNING: Usage of this method is discouraged, use {safeTransferFrom} whenever possible.\n *\n * Requirements:\n *\n * - `from` cannot be the zero address.\n * - `to` cannot be the zero address.\n * - `tokenId` token must be owned by `from`.\n * - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}.\n *\n * Emits a {Transfer} event.\n */\n function transferFrom(\n address from,\n address to,\n uint256 tokenId\n ) external;\n\n /**\n * @dev Gives permission to `to` to transfer `tokenId` token to another account.\n * The approval is cleared when the token is transferred.\n *\n * Only a single account can be approved at a time, so approving the zero address clears previous approvals.\n *\n * Requirements:\n *\n * - The caller must own the token or be an approved operator.\n * - `tokenId` must exist.\n *\n * Emits an {Approval} event.\n */\n function approve(address to, uint256 tokenId) external;\n\n /**\n * @dev Approve or remove `operator` as an operator for the caller.\n * Operators can call {transferFrom} or {safeTransferFrom} for any token owned by the caller.\n *\n * Requirements:\n *\n * - The `operator` cannot be the caller.\n *\n * Emits an {ApprovalForAll} event.\n */\n function setApprovalForAll(address operator, bool _approved) external;\n\n /**\n * @dev Returns the account approved for `tokenId` token.\n *\n * Requirements:\n *\n * - `tokenId` must exist.\n */\n function getApproved(uint256 tokenId) external view returns (address operator);\n\n /**\n * @dev Returns if the `operator` is allowed to manage all of the assets of `owner`.\n *\n * See {setApprovalForAll}\n */\n function isApprovedForAll(address owner, address operator) external view returns (bool);\n}\n" + }, + "@openzeppelin/contracts-upgradeable/utils/AddressUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (utils/Address.sol)\n\npragma solidity ^0.8.1;\n\n/**\n * @dev Collection of functions related to the address type\n */\nlibrary AddressUpgradeable {\n /**\n * @dev Returns true if `account` is a contract.\n *\n * [IMPORTANT]\n * ====\n * It is unsafe to assume that an address for which this function returns\n * false is an externally-owned account (EOA) and not a contract.\n *\n * Among others, `isContract` will return false for the following\n * types of addresses:\n *\n * - an externally-owned account\n * - a contract in construction\n * - an address where a contract will be created\n * - an address where a contract lived, but was destroyed\n * ====\n *\n * [IMPORTANT]\n * ====\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\n *\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\n * constructor.\n * ====\n */\n function isContract(address account) internal view returns (bool) {\n // This method relies on extcodesize/address.code.length, which returns 0\n // for contracts in construction, since the code is only stored at the end\n // of the constructor execution.\n\n return account.code.length > 0;\n }\n\n /**\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\n * `recipient`, forwarding all available gas and reverting on errors.\n *\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\n * imposed by `transfer`, making them unable to receive funds via\n * `transfer`. {sendValue} removes this limitation.\n *\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\n *\n * IMPORTANT: because control is transferred to `recipient`, care must be\n * taken to not create reentrancy vulnerabilities. Consider using\n * {ReentrancyGuard} or the\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\n */\n function sendValue(address payable recipient, uint256 amount) internal {\n require(address(this).balance >= amount, \"Address: insufficient balance\");\n\n (bool success, ) = recipient.call{value: amount}(\"\");\n require(success, \"Address: unable to send value, recipient may have reverted\");\n }\n\n /**\n * @dev Performs a Solidity function call using a low level `call`. A\n * plain `call` is an unsafe replacement for a function call: use this\n * function instead.\n *\n * If `target` reverts with a revert reason, it is bubbled up by this\n * function (like regular Solidity function calls).\n *\n * Returns the raw returned data. To convert to the expected return value,\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\n *\n * Requirements:\n *\n * - `target` must be a contract.\n * - calling `target` with `data` must not revert.\n *\n * _Available since v3.1._\n */\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionCall(target, data, \"Address: low-level call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\n * `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, 0, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but also transferring `value` wei to `target`.\n *\n * Requirements:\n *\n * - the calling contract must have an ETH balance of at least `value`.\n * - the called Solidity function must be `payable`.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, value, \"Address: low-level call with value failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\n * with `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(address(this).balance >= value, \"Address: insufficient balance for call\");\n require(isContract(target), \"Address: call to non-contract\");\n\n (bool success, bytes memory returndata) = target.call{value: value}(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\n return functionStaticCall(target, data, \"Address: low-level static call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal view returns (bytes memory) {\n require(isContract(target), \"Address: static call to non-contract\");\n\n (bool success, bytes memory returndata) = target.staticcall(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the\n * revert reason using the provided one.\n *\n * _Available since v4.3._\n */\n function verifyCallResult(\n bool success,\n bytes memory returndata,\n string memory errorMessage\n ) internal pure returns (bytes memory) {\n if (success) {\n return returndata;\n } else {\n // Look for revert reason and bubble it up if present\n if (returndata.length > 0) {\n // The easiest way to bubble the revert reason is using memory via assembly\n /// @solidity memory-safe-assembly\n assembly {\n let returndata_size := mload(returndata)\n revert(add(32, returndata), returndata_size)\n }\n } else {\n revert(errorMessage);\n }\n }\n }\n}\n" + }, + "@openzeppelin/contracts-upgradeable/utils/ContextUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)\n\npragma solidity ^0.8.0;\nimport \"../proxy/utils/Initializable.sol\";\n\n/**\n * @dev Provides information about the current execution context, including the\n * sender of the transaction and its data. While these are generally available\n * via msg.sender and msg.data, they should not be accessed in such a direct\n * manner, since when dealing with meta-transactions the account sending and\n * paying for execution may not be the actual sender (as far as an application\n * is concerned).\n *\n * This contract is only required for intermediate, library-like contracts.\n */\nabstract contract ContextUpgradeable is Initializable {\n function __Context_init() internal onlyInitializing {\n }\n\n function __Context_init_unchained() internal onlyInitializing {\n }\n function _msgSender() internal view virtual returns (address) {\n return msg.sender;\n }\n\n function _msgData() internal view virtual returns (bytes calldata) {\n return msg.data;\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[50] private __gap;\n}\n" + }, + "@openzeppelin/contracts-upgradeable/utils/CountersUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (utils/Counters.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @title Counters\n * @author Matt Condon (@shrugs)\n * @dev Provides counters that can only be incremented, decremented or reset. This can be used e.g. to track the number\n * of elements in a mapping, issuing ERC721 ids, or counting request ids.\n *\n * Include with `using Counters for Counters.Counter;`\n */\nlibrary CountersUpgradeable {\n struct Counter {\n // This variable should never be directly accessed by users of the library: interactions must be restricted to\n // the library's function. As of Solidity v0.5.2, this cannot be enforced, though there is a proposal to add\n // this feature: see https://github.com/ethereum/solidity/issues/4637\n uint256 _value; // default: 0\n }\n\n function current(Counter storage counter) internal view returns (uint256) {\n return counter._value;\n }\n\n function increment(Counter storage counter) internal {\n unchecked {\n counter._value += 1;\n }\n }\n\n function decrement(Counter storage counter) internal {\n uint256 value = counter._value;\n require(value > 0, \"Counter: decrement overflow\");\n unchecked {\n counter._value = value - 1;\n }\n }\n\n function reset(Counter storage counter) internal {\n counter._value = 0;\n }\n}\n" + }, + "@openzeppelin/contracts-upgradeable/utils/cryptography/draft-EIP712Upgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (utils/cryptography/draft-EIP712.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./ECDSAUpgradeable.sol\";\nimport \"../../proxy/utils/Initializable.sol\";\n\n/**\n * @dev https://eips.ethereum.org/EIPS/eip-712[EIP 712] is a standard for hashing and signing of typed structured data.\n *\n * The encoding specified in the EIP is very generic, and such a generic implementation in Solidity is not feasible,\n * thus this contract does not implement the encoding itself. Protocols need to implement the type-specific encoding\n * they need in their contracts using a combination of `abi.encode` and `keccak256`.\n *\n * This contract implements the EIP 712 domain separator ({_domainSeparatorV4}) that is used as part of the encoding\n * scheme, and the final step of the encoding to obtain the message digest that is then signed via ECDSA\n * ({_hashTypedDataV4}).\n *\n * The implementation of the domain separator was designed to be as efficient as possible while still properly updating\n * the chain id to protect against replay attacks on an eventual fork of the chain.\n *\n * NOTE: This contract implements the version of the encoding known as \"v4\", as implemented by the JSON RPC method\n * https://docs.metamask.io/guide/signing-data.html[`eth_signTypedDataV4` in MetaMask].\n *\n * _Available since v3.4._\n *\n * @custom:storage-size 52\n */\nabstract contract EIP712Upgradeable is Initializable {\n /* solhint-disable var-name-mixedcase */\n bytes32 private _HASHED_NAME;\n bytes32 private _HASHED_VERSION;\n bytes32 private constant _TYPE_HASH = keccak256(\"EIP712Domain(string name,string version,uint256 chainId,address verifyingContract)\");\n\n /* solhint-enable var-name-mixedcase */\n\n /**\n * @dev Initializes the domain separator and parameter caches.\n *\n * The meaning of `name` and `version` is specified in\n * https://eips.ethereum.org/EIPS/eip-712#definition-of-domainseparator[EIP 712]:\n *\n * - `name`: the user readable name of the signing domain, i.e. the name of the DApp or the protocol.\n * - `version`: the current major version of the signing domain.\n *\n * NOTE: These parameters cannot be changed except through a xref:learn::upgrading-smart-contracts.adoc[smart\n * contract upgrade].\n */\n function __EIP712_init(string memory name, string memory version) internal onlyInitializing {\n __EIP712_init_unchained(name, version);\n }\n\n function __EIP712_init_unchained(string memory name, string memory version) internal onlyInitializing {\n bytes32 hashedName = keccak256(bytes(name));\n bytes32 hashedVersion = keccak256(bytes(version));\n _HASHED_NAME = hashedName;\n _HASHED_VERSION = hashedVersion;\n }\n\n /**\n * @dev Returns the domain separator for the current chain.\n */\n function _domainSeparatorV4() internal view returns (bytes32) {\n return _buildDomainSeparator(_TYPE_HASH, _EIP712NameHash(), _EIP712VersionHash());\n }\n\n function _buildDomainSeparator(\n bytes32 typeHash,\n bytes32 nameHash,\n bytes32 versionHash\n ) private view returns (bytes32) {\n return keccak256(abi.encode(typeHash, nameHash, versionHash, block.chainid, address(this)));\n }\n\n /**\n * @dev Given an already https://eips.ethereum.org/EIPS/eip-712#definition-of-hashstruct[hashed struct], this\n * function returns the hash of the fully encoded EIP712 message for this domain.\n *\n * This hash can be used together with {ECDSA-recover} to obtain the signer of a message. For example:\n *\n * ```solidity\n * bytes32 digest = _hashTypedDataV4(keccak256(abi.encode(\n * keccak256(\"Mail(address to,string contents)\"),\n * mailTo,\n * keccak256(bytes(mailContents))\n * )));\n * address signer = ECDSA.recover(digest, signature);\n * ```\n */\n function _hashTypedDataV4(bytes32 structHash) internal view virtual returns (bytes32) {\n return ECDSAUpgradeable.toTypedDataHash(_domainSeparatorV4(), structHash);\n }\n\n /**\n * @dev The hash of the name parameter for the EIP712 domain.\n *\n * NOTE: This function reads from storage by default, but can be redefined to return a constant value if gas costs\n * are a concern.\n */\n function _EIP712NameHash() internal virtual view returns (bytes32) {\n return _HASHED_NAME;\n }\n\n /**\n * @dev The hash of the version parameter for the EIP712 domain.\n *\n * NOTE: This function reads from storage by default, but can be redefined to return a constant value if gas costs\n * are a concern.\n */\n function _EIP712VersionHash() internal virtual view returns (bytes32) {\n return _HASHED_VERSION;\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[50] private __gap;\n}\n" + }, + "@openzeppelin/contracts-upgradeable/utils/cryptography/ECDSAUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (utils/cryptography/ECDSA.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../StringsUpgradeable.sol\";\n\n/**\n * @dev Elliptic Curve Digital Signature Algorithm (ECDSA) operations.\n *\n * These functions can be used to verify that a message was signed by the holder\n * of the private keys of a given address.\n */\nlibrary ECDSAUpgradeable {\n enum RecoverError {\n NoError,\n InvalidSignature,\n InvalidSignatureLength,\n InvalidSignatureS,\n InvalidSignatureV\n }\n\n function _throwError(RecoverError error) private pure {\n if (error == RecoverError.NoError) {\n return; // no error: do nothing\n } else if (error == RecoverError.InvalidSignature) {\n revert(\"ECDSA: invalid signature\");\n } else if (error == RecoverError.InvalidSignatureLength) {\n revert(\"ECDSA: invalid signature length\");\n } else if (error == RecoverError.InvalidSignatureS) {\n revert(\"ECDSA: invalid signature 's' value\");\n } else if (error == RecoverError.InvalidSignatureV) {\n revert(\"ECDSA: invalid signature 'v' value\");\n }\n }\n\n /**\n * @dev Returns the address that signed a hashed message (`hash`) with\n * `signature` or error string. This address can then be used for verification purposes.\n *\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\n * this function rejects them by requiring the `s` value to be in the lower\n * half order, and the `v` value to be either 27 or 28.\n *\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\n * verification to be secure: it is possible to craft signatures that\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\n * this is by receiving a hash of the original message (which may otherwise\n * be too long), and then calling {toEthSignedMessageHash} on it.\n *\n * Documentation for signature generation:\n * - with https://web3js.readthedocs.io/en/v1.3.4/web3-eth-accounts.html#sign[Web3.js]\n * - with https://docs.ethers.io/v5/api/signer/#Signer-signMessage[ethers]\n *\n * _Available since v4.3._\n */\n function tryRecover(bytes32 hash, bytes memory signature) internal pure returns (address, RecoverError) {\n // Check the signature length\n // - case 65: r,s,v signature (standard)\n // - case 64: r,vs signature (cf https://eips.ethereum.org/EIPS/eip-2098) _Available since v4.1._\n if (signature.length == 65) {\n bytes32 r;\n bytes32 s;\n uint8 v;\n // ecrecover takes the signature parameters, and the only way to get them\n // currently is to use assembly.\n /// @solidity memory-safe-assembly\n assembly {\n r := mload(add(signature, 0x20))\n s := mload(add(signature, 0x40))\n v := byte(0, mload(add(signature, 0x60)))\n }\n return tryRecover(hash, v, r, s);\n } else if (signature.length == 64) {\n bytes32 r;\n bytes32 vs;\n // ecrecover takes the signature parameters, and the only way to get them\n // currently is to use assembly.\n /// @solidity memory-safe-assembly\n assembly {\n r := mload(add(signature, 0x20))\n vs := mload(add(signature, 0x40))\n }\n return tryRecover(hash, r, vs);\n } else {\n return (address(0), RecoverError.InvalidSignatureLength);\n }\n }\n\n /**\n * @dev Returns the address that signed a hashed message (`hash`) with\n * `signature`. This address can then be used for verification purposes.\n *\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\n * this function rejects them by requiring the `s` value to be in the lower\n * half order, and the `v` value to be either 27 or 28.\n *\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\n * verification to be secure: it is possible to craft signatures that\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\n * this is by receiving a hash of the original message (which may otherwise\n * be too long), and then calling {toEthSignedMessageHash} on it.\n */\n function recover(bytes32 hash, bytes memory signature) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, signature);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Overload of {ECDSA-tryRecover} that receives the `r` and `vs` short-signature fields separately.\n *\n * See https://eips.ethereum.org/EIPS/eip-2098[EIP-2098 short signatures]\n *\n * _Available since v4.3._\n */\n function tryRecover(\n bytes32 hash,\n bytes32 r,\n bytes32 vs\n ) internal pure returns (address, RecoverError) {\n bytes32 s = vs & bytes32(0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff);\n uint8 v = uint8((uint256(vs) >> 255) + 27);\n return tryRecover(hash, v, r, s);\n }\n\n /**\n * @dev Overload of {ECDSA-recover} that receives the `r and `vs` short-signature fields separately.\n *\n * _Available since v4.2._\n */\n function recover(\n bytes32 hash,\n bytes32 r,\n bytes32 vs\n ) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, r, vs);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Overload of {ECDSA-tryRecover} that receives the `v`,\n * `r` and `s` signature fields separately.\n *\n * _Available since v4.3._\n */\n function tryRecover(\n bytes32 hash,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) internal pure returns (address, RecoverError) {\n // EIP-2 still allows signature malleability for ecrecover(). Remove this possibility and make the signature\n // unique. Appendix F in the Ethereum Yellow paper (https://ethereum.github.io/yellowpaper/paper.pdf), defines\n // the valid range for s in (301): 0 < s < secp256k1n ÷ 2 + 1, and for v in (302): v ∈ {27, 28}. Most\n // signatures from current libraries generate a unique signature with an s-value in the lower half order.\n //\n // If your library generates malleable signatures, such as s-values in the upper range, calculate a new s-value\n // with 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141 - s1 and flip v from 27 to 28 or\n // vice versa. If your library also generates signatures with 0/1 for v instead 27/28, add 27 to v to accept\n // these malleable signatures as well.\n if (uint256(s) > 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D576E7357A4501DDFE92F46681B20A0) {\n return (address(0), RecoverError.InvalidSignatureS);\n }\n if (v != 27 && v != 28) {\n return (address(0), RecoverError.InvalidSignatureV);\n }\n\n // If the signature is valid (and not malleable), return the signer address\n address signer = ecrecover(hash, v, r, s);\n if (signer == address(0)) {\n return (address(0), RecoverError.InvalidSignature);\n }\n\n return (signer, RecoverError.NoError);\n }\n\n /**\n * @dev Overload of {ECDSA-recover} that receives the `v`,\n * `r` and `s` signature fields separately.\n */\n function recover(\n bytes32 hash,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, v, r, s);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Returns an Ethereum Signed Message, created from a `hash`. This\n * produces hash corresponding to the one signed with the\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\n * JSON-RPC method as part of EIP-191.\n *\n * See {recover}.\n */\n function toEthSignedMessageHash(bytes32 hash) internal pure returns (bytes32) {\n // 32 is the length in bytes of hash,\n // enforced by the type signature above\n return keccak256(abi.encodePacked(\"\\x19Ethereum Signed Message:\\n32\", hash));\n }\n\n /**\n * @dev Returns an Ethereum Signed Message, created from `s`. This\n * produces hash corresponding to the one signed with the\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\n * JSON-RPC method as part of EIP-191.\n *\n * See {recover}.\n */\n function toEthSignedMessageHash(bytes memory s) internal pure returns (bytes32) {\n return keccak256(abi.encodePacked(\"\\x19Ethereum Signed Message:\\n\", StringsUpgradeable.toString(s.length), s));\n }\n\n /**\n * @dev Returns an Ethereum Signed Typed Data, created from a\n * `domainSeparator` and a `structHash`. This produces hash corresponding\n * to the one signed with the\n * https://eips.ethereum.org/EIPS/eip-712[`eth_signTypedData`]\n * JSON-RPC method as part of EIP-712.\n *\n * See {recover}.\n */\n function toTypedDataHash(bytes32 domainSeparator, bytes32 structHash) internal pure returns (bytes32) {\n return keccak256(abi.encodePacked(\"\\x19\\x01\", domainSeparator, structHash));\n }\n}\n" + }, + "@openzeppelin/contracts-upgradeable/utils/introspection/ERC165Upgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (utils/introspection/ERC165.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./IERC165Upgradeable.sol\";\nimport \"../../proxy/utils/Initializable.sol\";\n\n/**\n * @dev Implementation of the {IERC165} interface.\n *\n * Contracts that want to implement ERC165 should inherit from this contract and override {supportsInterface} to check\n * for the additional interface id that will be supported. For example:\n *\n * ```solidity\n * function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {\n * return interfaceId == type(MyInterface).interfaceId || super.supportsInterface(interfaceId);\n * }\n * ```\n *\n * Alternatively, {ERC165Storage} provides an easier to use but more expensive implementation.\n */\nabstract contract ERC165Upgradeable is Initializable, IERC165Upgradeable {\n function __ERC165_init() internal onlyInitializing {\n }\n\n function __ERC165_init_unchained() internal onlyInitializing {\n }\n /**\n * @dev See {IERC165-supportsInterface}.\n */\n function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {\n return interfaceId == type(IERC165Upgradeable).interfaceId;\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[50] private __gap;\n}\n" + }, + "@openzeppelin/contracts-upgradeable/utils/introspection/IERC165Upgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (utils/introspection/IERC165.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Interface of the ERC165 standard, as defined in the\n * https://eips.ethereum.org/EIPS/eip-165[EIP].\n *\n * Implementers can declare support of contract interfaces, which can then be\n * queried by others ({ERC165Checker}).\n *\n * For an implementation, see {ERC165}.\n */\ninterface IERC165Upgradeable {\n /**\n * @dev Returns true if this contract implements the interface defined by\n * `interfaceId`. See the corresponding\n * https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified[EIP section]\n * to learn more about how these ids are created.\n *\n * This function call must use less than 30 000 gas.\n */\n function supportsInterface(bytes4 interfaceId) external view returns (bool);\n}\n" + }, + "@openzeppelin/contracts-upgradeable/utils/StringsUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (utils/Strings.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev String operations.\n */\nlibrary StringsUpgradeable {\n bytes16 private constant _HEX_SYMBOLS = \"0123456789abcdef\";\n uint8 private constant _ADDRESS_LENGTH = 20;\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` decimal representation.\n */\n function toString(uint256 value) internal pure returns (string memory) {\n // Inspired by OraclizeAPI's implementation - MIT licence\n // https://github.com/oraclize/ethereum-api/blob/b42146b063c7d6ee1358846c198246239e9360e8/oraclizeAPI_0.4.25.sol\n\n if (value == 0) {\n return \"0\";\n }\n uint256 temp = value;\n uint256 digits;\n while (temp != 0) {\n digits++;\n temp /= 10;\n }\n bytes memory buffer = new bytes(digits);\n while (value != 0) {\n digits -= 1;\n buffer[digits] = bytes1(uint8(48 + uint256(value % 10)));\n value /= 10;\n }\n return string(buffer);\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation.\n */\n function toHexString(uint256 value) internal pure returns (string memory) {\n if (value == 0) {\n return \"0x00\";\n }\n uint256 temp = value;\n uint256 length = 0;\n while (temp != 0) {\n length++;\n temp >>= 8;\n }\n return toHexString(value, length);\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length.\n */\n function toHexString(uint256 value, uint256 length) internal pure returns (string memory) {\n bytes memory buffer = new bytes(2 * length + 2);\n buffer[0] = \"0\";\n buffer[1] = \"x\";\n for (uint256 i = 2 * length + 1; i > 1; --i) {\n buffer[i] = _HEX_SYMBOLS[value & 0xf];\n value >>= 4;\n }\n require(value == 0, \"Strings: hex length insufficient\");\n return string(buffer);\n }\n\n /**\n * @dev Converts an `address` with fixed length of 20 bytes to its not checksummed ASCII `string` hexadecimal representation.\n */\n function toHexString(address addr) internal pure returns (string memory) {\n return toHexString(uint256(uint160(addr)), _ADDRESS_LENGTH);\n }\n}\n" + }, + "@openzeppelin/contracts-upgradeable/utils/structs/EnumerableSetUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (utils/structs/EnumerableSet.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Library for managing\n * https://en.wikipedia.org/wiki/Set_(abstract_data_type)[sets] of primitive\n * types.\n *\n * Sets have the following properties:\n *\n * - Elements are added, removed, and checked for existence in constant time\n * (O(1)).\n * - Elements are enumerated in O(n). No guarantees are made on the ordering.\n *\n * ```\n * contract Example {\n * // Add the library methods\n * using EnumerableSet for EnumerableSet.AddressSet;\n *\n * // Declare a set state variable\n * EnumerableSet.AddressSet private mySet;\n * }\n * ```\n *\n * As of v3.3.0, sets of type `bytes32` (`Bytes32Set`), `address` (`AddressSet`)\n * and `uint256` (`UintSet`) are supported.\n *\n * [WARNING]\n * ====\n * Trying to delete such a structure from storage will likely result in data corruption, rendering the structure unusable.\n * See https://github.com/ethereum/solidity/pull/11843[ethereum/solidity#11843] for more info.\n *\n * In order to clean an EnumerableSet, you can either remove all elements one by one or create a fresh instance using an array of EnumerableSet.\n * ====\n */\nlibrary EnumerableSetUpgradeable {\n // To implement this library for multiple types with as little code\n // repetition as possible, we write it in terms of a generic Set type with\n // bytes32 values.\n // The Set implementation uses private functions, and user-facing\n // implementations (such as AddressSet) are just wrappers around the\n // underlying Set.\n // This means that we can only create new EnumerableSets for types that fit\n // in bytes32.\n\n struct Set {\n // Storage of set values\n bytes32[] _values;\n // Position of the value in the `values` array, plus 1 because index 0\n // means a value is not in the set.\n mapping(bytes32 => uint256) _indexes;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function _add(Set storage set, bytes32 value) private returns (bool) {\n if (!_contains(set, value)) {\n set._values.push(value);\n // The value is stored at length-1, but we add 1 to all indexes\n // and use 0 as a sentinel value\n set._indexes[value] = set._values.length;\n return true;\n } else {\n return false;\n }\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function _remove(Set storage set, bytes32 value) private returns (bool) {\n // We read and store the value's index to prevent multiple reads from the same storage slot\n uint256 valueIndex = set._indexes[value];\n\n if (valueIndex != 0) {\n // Equivalent to contains(set, value)\n // To delete an element from the _values array in O(1), we swap the element to delete with the last one in\n // the array, and then remove the last element (sometimes called as 'swap and pop').\n // This modifies the order of the array, as noted in {at}.\n\n uint256 toDeleteIndex = valueIndex - 1;\n uint256 lastIndex = set._values.length - 1;\n\n if (lastIndex != toDeleteIndex) {\n bytes32 lastValue = set._values[lastIndex];\n\n // Move the last value to the index where the value to delete is\n set._values[toDeleteIndex] = lastValue;\n // Update the index for the moved value\n set._indexes[lastValue] = valueIndex; // Replace lastValue's index to valueIndex\n }\n\n // Delete the slot where the moved value was stored\n set._values.pop();\n\n // Delete the index for the deleted slot\n delete set._indexes[value];\n\n return true;\n } else {\n return false;\n }\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function _contains(Set storage set, bytes32 value) private view returns (bool) {\n return set._indexes[value] != 0;\n }\n\n /**\n * @dev Returns the number of values on the set. O(1).\n */\n function _length(Set storage set) private view returns (uint256) {\n return set._values.length;\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function _at(Set storage set, uint256 index) private view returns (bytes32) {\n return set._values[index];\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function _values(Set storage set) private view returns (bytes32[] memory) {\n return set._values;\n }\n\n // Bytes32Set\n\n struct Bytes32Set {\n Set _inner;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function add(Bytes32Set storage set, bytes32 value) internal returns (bool) {\n return _add(set._inner, value);\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function remove(Bytes32Set storage set, bytes32 value) internal returns (bool) {\n return _remove(set._inner, value);\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function contains(Bytes32Set storage set, bytes32 value) internal view returns (bool) {\n return _contains(set._inner, value);\n }\n\n /**\n * @dev Returns the number of values in the set. O(1).\n */\n function length(Bytes32Set storage set) internal view returns (uint256) {\n return _length(set._inner);\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function at(Bytes32Set storage set, uint256 index) internal view returns (bytes32) {\n return _at(set._inner, index);\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function values(Bytes32Set storage set) internal view returns (bytes32[] memory) {\n return _values(set._inner);\n }\n\n // AddressSet\n\n struct AddressSet {\n Set _inner;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function add(AddressSet storage set, address value) internal returns (bool) {\n return _add(set._inner, bytes32(uint256(uint160(value))));\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function remove(AddressSet storage set, address value) internal returns (bool) {\n return _remove(set._inner, bytes32(uint256(uint160(value))));\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function contains(AddressSet storage set, address value) internal view returns (bool) {\n return _contains(set._inner, bytes32(uint256(uint160(value))));\n }\n\n /**\n * @dev Returns the number of values in the set. O(1).\n */\n function length(AddressSet storage set) internal view returns (uint256) {\n return _length(set._inner);\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function at(AddressSet storage set, uint256 index) internal view returns (address) {\n return address(uint160(uint256(_at(set._inner, index))));\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function values(AddressSet storage set) internal view returns (address[] memory) {\n bytes32[] memory store = _values(set._inner);\n address[] memory result;\n\n /// @solidity memory-safe-assembly\n assembly {\n result := store\n }\n\n return result;\n }\n\n // UintSet\n\n struct UintSet {\n Set _inner;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function add(UintSet storage set, uint256 value) internal returns (bool) {\n return _add(set._inner, bytes32(value));\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function remove(UintSet storage set, uint256 value) internal returns (bool) {\n return _remove(set._inner, bytes32(value));\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function contains(UintSet storage set, uint256 value) internal view returns (bool) {\n return _contains(set._inner, bytes32(value));\n }\n\n /**\n * @dev Returns the number of values on the set. O(1).\n */\n function length(UintSet storage set) internal view returns (uint256) {\n return _length(set._inner);\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function at(UintSet storage set, uint256 index) internal view returns (uint256) {\n return uint256(_at(set._inner, index));\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function values(UintSet storage set) internal view returns (uint256[] memory) {\n bytes32[] memory store = _values(set._inner);\n uint256[] memory result;\n\n /// @solidity memory-safe-assembly\n assembly {\n result := store\n }\n\n return result;\n }\n}\n" + }, + "@openzeppelin/contracts/access/Ownable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (access/Ownable.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../utils/Context.sol\";\n\n/**\n * @dev Contract module which provides a basic access control mechanism, where\n * there is an account (an owner) that can be granted exclusive access to\n * specific functions.\n *\n * By default, the owner account will be the one that deploys the contract. This\n * can later be changed with {transferOwnership}.\n *\n * This module is used through inheritance. It will make available the modifier\n * `onlyOwner`, which can be applied to your functions to restrict their use to\n * the owner.\n */\nabstract contract Ownable is Context {\n address private _owner;\n\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\n\n /**\n * @dev Initializes the contract setting the deployer as the initial owner.\n */\n constructor() {\n _transferOwnership(_msgSender());\n }\n\n /**\n * @dev Throws if called by any account other than the owner.\n */\n modifier onlyOwner() {\n _checkOwner();\n _;\n }\n\n /**\n * @dev Returns the address of the current owner.\n */\n function owner() public view virtual returns (address) {\n return _owner;\n }\n\n /**\n * @dev Throws if the sender is not the owner.\n */\n function _checkOwner() internal view virtual {\n require(owner() == _msgSender(), \"Ownable: caller is not the owner\");\n }\n\n /**\n * @dev Leaves the contract without owner. It will not be possible to call\n * `onlyOwner` functions anymore. Can only be called by the current owner.\n *\n * NOTE: Renouncing ownership will leave the contract without an owner,\n * thereby removing any functionality that is only available to the owner.\n */\n function renounceOwnership() public virtual onlyOwner {\n _transferOwnership(address(0));\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Can only be called by the current owner.\n */\n function transferOwnership(address newOwner) public virtual onlyOwner {\n require(newOwner != address(0), \"Ownable: new owner is the zero address\");\n _transferOwnership(newOwner);\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Internal function without access restriction.\n */\n function _transferOwnership(address newOwner) internal virtual {\n address oldOwner = _owner;\n _owner = newOwner;\n emit OwnershipTransferred(oldOwner, newOwner);\n }\n}\n" + }, + "@openzeppelin/contracts/interfaces/draft-IERC1822.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.5.0) (interfaces/draft-IERC1822.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev ERC1822: Universal Upgradeable Proxy Standard (UUPS) documents a method for upgradeability through a simplified\n * proxy whose upgrades are fully controlled by the current implementation.\n */\ninterface IERC1822Proxiable {\n /**\n * @dev Returns the storage slot that the proxiable contract assumes is being used to store the implementation\n * address.\n *\n * IMPORTANT: A proxy pointing at a proxiable contract should not be considered proxiable itself, because this risks\n * bricking a proxy that upgrades to it, by delegating to itself until out of gas. Thus it is critical that this\n * function revert if invoked through a proxy.\n */\n function proxiableUUID() external view returns (bytes32);\n}\n" + }, + "@openzeppelin/contracts/interfaces/IERC3156FlashBorrower.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (interfaces/IERC3156FlashBorrower.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Interface of the ERC3156 FlashBorrower, as defined in\n * https://eips.ethereum.org/EIPS/eip-3156[ERC-3156].\n *\n * _Available since v4.1._\n */\ninterface IERC3156FlashBorrower {\n /**\n * @dev Receive a flash loan.\n * @param initiator The initiator of the loan.\n * @param token The loan currency.\n * @param amount The amount of tokens lent.\n * @param fee The additional amount of tokens to repay.\n * @param data Arbitrary data structure, intended to contain user-defined parameters.\n * @return The keccak256 hash of \"IERC3156FlashBorrower.onFlashLoan\"\n */\n function onFlashLoan(\n address initiator,\n address token,\n uint256 amount,\n uint256 fee,\n bytes calldata data\n ) external returns (bytes32);\n}\n" + }, + "@openzeppelin/contracts/interfaces/IERC3156FlashLender.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (interfaces/IERC3156FlashLender.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./IERC3156FlashBorrower.sol\";\n\n/**\n * @dev Interface of the ERC3156 FlashLender, as defined in\n * https://eips.ethereum.org/EIPS/eip-3156[ERC-3156].\n *\n * _Available since v4.1._\n */\ninterface IERC3156FlashLender {\n /**\n * @dev The amount of currency available to be lended.\n * @param token The loan currency.\n * @return The amount of `token` that can be borrowed.\n */\n function maxFlashLoan(address token) external view returns (uint256);\n\n /**\n * @dev The fee to be charged for a given loan.\n * @param token The loan currency.\n * @param amount The amount of tokens lent.\n * @return The amount of `token` to be charged for the loan, on top of the returned principal.\n */\n function flashFee(address token, uint256 amount) external view returns (uint256);\n\n /**\n * @dev Initiate a flash loan.\n * @param receiver The receiver of the tokens in the loan, and the receiver of the callback.\n * @param token The loan currency.\n * @param amount The amount of tokens lent.\n * @param data Arbitrary data structure, intended to contain user-defined parameters.\n */\n function flashLoan(\n IERC3156FlashBorrower receiver,\n address token,\n uint256 amount,\n bytes calldata data\n ) external returns (bool);\n}\n" + }, + "@openzeppelin/contracts/interfaces/IERC721Metadata.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (interfaces/IERC721Metadata.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../token/ERC721/extensions/IERC721Metadata.sol\";\n" + }, + "@openzeppelin/contracts/proxy/beacon/IBeacon.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (proxy/beacon/IBeacon.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev This is the interface that {BeaconProxy} expects of its beacon.\n */\ninterface IBeacon {\n /**\n * @dev Must return an address that can be used as a delegate call target.\n *\n * {BeaconProxy} will check that this address is a contract.\n */\n function implementation() external view returns (address);\n}\n" + }, + "@openzeppelin/contracts/proxy/ERC1967/ERC1967Proxy.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (proxy/ERC1967/ERC1967Proxy.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../Proxy.sol\";\nimport \"./ERC1967Upgrade.sol\";\n\n/**\n * @dev This contract implements an upgradeable proxy. It is upgradeable because calls are delegated to an\n * implementation address that can be changed. This address is stored in storage in the location specified by\n * https://eips.ethereum.org/EIPS/eip-1967[EIP1967], so that it doesn't conflict with the storage layout of the\n * implementation behind the proxy.\n */\ncontract ERC1967Proxy is Proxy, ERC1967Upgrade {\n /**\n * @dev Initializes the upgradeable proxy with an initial implementation specified by `_logic`.\n *\n * If `_data` is nonempty, it's used as data in a delegate call to `_logic`. This will typically be an encoded\n * function call, and allows initializing the storage of the proxy like a Solidity constructor.\n */\n constructor(address _logic, bytes memory _data) payable {\n _upgradeToAndCall(_logic, _data, false);\n }\n\n /**\n * @dev Returns the current implementation address.\n */\n function _implementation() internal view virtual override returns (address impl) {\n return ERC1967Upgrade._getImplementation();\n }\n}\n" + }, + "@openzeppelin/contracts/proxy/ERC1967/ERC1967Upgrade.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.5.0) (proxy/ERC1967/ERC1967Upgrade.sol)\n\npragma solidity ^0.8.2;\n\nimport \"../beacon/IBeacon.sol\";\nimport \"../../interfaces/draft-IERC1822.sol\";\nimport \"../../utils/Address.sol\";\nimport \"../../utils/StorageSlot.sol\";\n\n/**\n * @dev This abstract contract provides getters and event emitting update functions for\n * https://eips.ethereum.org/EIPS/eip-1967[EIP1967] slots.\n *\n * _Available since v4.1._\n *\n * @custom:oz-upgrades-unsafe-allow delegatecall\n */\nabstract contract ERC1967Upgrade {\n // This is the keccak-256 hash of \"eip1967.proxy.rollback\" subtracted by 1\n bytes32 private constant _ROLLBACK_SLOT = 0x4910fdfa16fed3260ed0e7147f7cc6da11a60208b5b9406d12a635614ffd9143;\n\n /**\n * @dev Storage slot with the address of the current implementation.\n * This is the keccak-256 hash of \"eip1967.proxy.implementation\" subtracted by 1, and is\n * validated in the constructor.\n */\n bytes32 internal constant _IMPLEMENTATION_SLOT = 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc;\n\n /**\n * @dev Emitted when the implementation is upgraded.\n */\n event Upgraded(address indexed implementation);\n\n /**\n * @dev Returns the current implementation address.\n */\n function _getImplementation() internal view returns (address) {\n return StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value;\n }\n\n /**\n * @dev Stores a new address in the EIP1967 implementation slot.\n */\n function _setImplementation(address newImplementation) private {\n require(Address.isContract(newImplementation), \"ERC1967: new implementation is not a contract\");\n StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value = newImplementation;\n }\n\n /**\n * @dev Perform implementation upgrade\n *\n * Emits an {Upgraded} event.\n */\n function _upgradeTo(address newImplementation) internal {\n _setImplementation(newImplementation);\n emit Upgraded(newImplementation);\n }\n\n /**\n * @dev Perform implementation upgrade with additional setup call.\n *\n * Emits an {Upgraded} event.\n */\n function _upgradeToAndCall(\n address newImplementation,\n bytes memory data,\n bool forceCall\n ) internal {\n _upgradeTo(newImplementation);\n if (data.length > 0 || forceCall) {\n Address.functionDelegateCall(newImplementation, data);\n }\n }\n\n /**\n * @dev Perform implementation upgrade with security checks for UUPS proxies, and additional setup call.\n *\n * Emits an {Upgraded} event.\n */\n function _upgradeToAndCallUUPS(\n address newImplementation,\n bytes memory data,\n bool forceCall\n ) internal {\n // Upgrades from old implementations will perform a rollback test. This test requires the new\n // implementation to upgrade back to the old, non-ERC1822 compliant, implementation. Removing\n // this special case will break upgrade paths from old UUPS implementation to new ones.\n if (StorageSlot.getBooleanSlot(_ROLLBACK_SLOT).value) {\n _setImplementation(newImplementation);\n } else {\n try IERC1822Proxiable(newImplementation).proxiableUUID() returns (bytes32 slot) {\n require(slot == _IMPLEMENTATION_SLOT, \"ERC1967Upgrade: unsupported proxiableUUID\");\n } catch {\n revert(\"ERC1967Upgrade: new implementation is not UUPS\");\n }\n _upgradeToAndCall(newImplementation, data, forceCall);\n }\n }\n\n /**\n * @dev Storage slot with the admin of the contract.\n * This is the keccak-256 hash of \"eip1967.proxy.admin\" subtracted by 1, and is\n * validated in the constructor.\n */\n bytes32 internal constant _ADMIN_SLOT = 0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103;\n\n /**\n * @dev Emitted when the admin account has changed.\n */\n event AdminChanged(address previousAdmin, address newAdmin);\n\n /**\n * @dev Returns the current admin.\n */\n function _getAdmin() internal view returns (address) {\n return StorageSlot.getAddressSlot(_ADMIN_SLOT).value;\n }\n\n /**\n * @dev Stores a new address in the EIP1967 admin slot.\n */\n function _setAdmin(address newAdmin) private {\n require(newAdmin != address(0), \"ERC1967: new admin is the zero address\");\n StorageSlot.getAddressSlot(_ADMIN_SLOT).value = newAdmin;\n }\n\n /**\n * @dev Changes the admin of the proxy.\n *\n * Emits an {AdminChanged} event.\n */\n function _changeAdmin(address newAdmin) internal {\n emit AdminChanged(_getAdmin(), newAdmin);\n _setAdmin(newAdmin);\n }\n\n /**\n * @dev The storage slot of the UpgradeableBeacon contract which defines the implementation for this proxy.\n * This is bytes32(uint256(keccak256('eip1967.proxy.beacon')) - 1)) and is validated in the constructor.\n */\n bytes32 internal constant _BEACON_SLOT = 0xa3f0ad74e5423aebfd80d3ef4346578335a9a72aeaee59ff6cb3582b35133d50;\n\n /**\n * @dev Emitted when the beacon is upgraded.\n */\n event BeaconUpgraded(address indexed beacon);\n\n /**\n * @dev Returns the current beacon.\n */\n function _getBeacon() internal view returns (address) {\n return StorageSlot.getAddressSlot(_BEACON_SLOT).value;\n }\n\n /**\n * @dev Stores a new beacon in the EIP1967 beacon slot.\n */\n function _setBeacon(address newBeacon) private {\n require(Address.isContract(newBeacon), \"ERC1967: new beacon is not a contract\");\n require(\n Address.isContract(IBeacon(newBeacon).implementation()),\n \"ERC1967: beacon implementation is not a contract\"\n );\n StorageSlot.getAddressSlot(_BEACON_SLOT).value = newBeacon;\n }\n\n /**\n * @dev Perform beacon upgrade with additional setup call. Note: This upgrades the address of the beacon, it does\n * not upgrade the implementation contained in the beacon (see {UpgradeableBeacon-_setImplementation} for that).\n *\n * Emits a {BeaconUpgraded} event.\n */\n function _upgradeBeaconToAndCall(\n address newBeacon,\n bytes memory data,\n bool forceCall\n ) internal {\n _setBeacon(newBeacon);\n emit BeaconUpgraded(newBeacon);\n if (data.length > 0 || forceCall) {\n Address.functionDelegateCall(IBeacon(newBeacon).implementation(), data);\n }\n }\n}\n" + }, + "@openzeppelin/contracts/proxy/Proxy.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.6.0) (proxy/Proxy.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev This abstract contract provides a fallback function that delegates all calls to another contract using the EVM\n * instruction `delegatecall`. We refer to the second contract as the _implementation_ behind the proxy, and it has to\n * be specified by overriding the virtual {_implementation} function.\n *\n * Additionally, delegation to the implementation can be triggered manually through the {_fallback} function, or to a\n * different contract through the {_delegate} function.\n *\n * The success and return data of the delegated call will be returned back to the caller of the proxy.\n */\nabstract contract Proxy {\n /**\n * @dev Delegates the current call to `implementation`.\n *\n * This function does not return to its internal call site, it will return directly to the external caller.\n */\n function _delegate(address implementation) internal virtual {\n assembly {\n // Copy msg.data. We take full control of memory in this inline assembly\n // block because it will not return to Solidity code. We overwrite the\n // Solidity scratch pad at memory position 0.\n calldatacopy(0, 0, calldatasize())\n\n // Call the implementation.\n // out and outsize are 0 because we don't know the size yet.\n let result := delegatecall(gas(), implementation, 0, calldatasize(), 0, 0)\n\n // Copy the returned data.\n returndatacopy(0, 0, returndatasize())\n\n switch result\n // delegatecall returns 0 on error.\n case 0 {\n revert(0, returndatasize())\n }\n default {\n return(0, returndatasize())\n }\n }\n }\n\n /**\n * @dev This is a virtual function that should be overridden so it returns the address to which the fallback function\n * and {_fallback} should delegate.\n */\n function _implementation() internal view virtual returns (address);\n\n /**\n * @dev Delegates the current call to the address returned by `_implementation()`.\n *\n * This function does not return to its internal call site, it will return directly to the external caller.\n */\n function _fallback() internal virtual {\n _beforeFallback();\n _delegate(_implementation());\n }\n\n /**\n * @dev Fallback function that delegates calls to the address returned by `_implementation()`. Will run if no other\n * function in the contract matches the call data.\n */\n fallback() external payable virtual {\n _fallback();\n }\n\n /**\n * @dev Fallback function that delegates calls to the address returned by `_implementation()`. Will run if call data\n * is empty.\n */\n receive() external payable virtual {\n _fallback();\n }\n\n /**\n * @dev Hook that is called before falling back to the implementation. Can happen as part of a manual `_fallback`\n * call, or as part of the Solidity `fallback` or `receive` functions.\n *\n * If overridden should call `super._beforeFallback()`.\n */\n function _beforeFallback() internal virtual {}\n}\n" + }, + "@openzeppelin/contracts/token/ERC20/ERC20.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (token/ERC20/ERC20.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./IERC20.sol\";\nimport \"./extensions/IERC20Metadata.sol\";\nimport \"../../utils/Context.sol\";\n\n/**\n * @dev Implementation of the {IERC20} interface.\n *\n * This implementation is agnostic to the way tokens are created. This means\n * that a supply mechanism has to be added in a derived contract using {_mint}.\n * For a generic mechanism see {ERC20PresetMinterPauser}.\n *\n * TIP: For a detailed writeup see our guide\n * https://forum.zeppelin.solutions/t/how-to-implement-erc20-supply-mechanisms/226[How\n * to implement supply mechanisms].\n *\n * We have followed general OpenZeppelin Contracts guidelines: functions revert\n * instead returning `false` on failure. This behavior is nonetheless\n * conventional and does not conflict with the expectations of ERC20\n * applications.\n *\n * Additionally, an {Approval} event is emitted on calls to {transferFrom}.\n * This allows applications to reconstruct the allowance for all accounts just\n * by listening to said events. Other implementations of the EIP may not emit\n * these events, as it isn't required by the specification.\n *\n * Finally, the non-standard {decreaseAllowance} and {increaseAllowance}\n * functions have been added to mitigate the well-known issues around setting\n * allowances. See {IERC20-approve}.\n */\ncontract ERC20 is Context, IERC20, IERC20Metadata {\n mapping(address => uint256) private _balances;\n\n mapping(address => mapping(address => uint256)) private _allowances;\n\n uint256 private _totalSupply;\n\n string private _name;\n string private _symbol;\n\n /**\n * @dev Sets the values for {name} and {symbol}.\n *\n * The default value of {decimals} is 18. To select a different value for\n * {decimals} you should overload it.\n *\n * All two of these values are immutable: they can only be set once during\n * construction.\n */\n constructor(string memory name_, string memory symbol_) {\n _name = name_;\n _symbol = symbol_;\n }\n\n /**\n * @dev Returns the name of the token.\n */\n function name() public view virtual override returns (string memory) {\n return _name;\n }\n\n /**\n * @dev Returns the symbol of the token, usually a shorter version of the\n * name.\n */\n function symbol() public view virtual override returns (string memory) {\n return _symbol;\n }\n\n /**\n * @dev Returns the number of decimals used to get its user representation.\n * For example, if `decimals` equals `2`, a balance of `505` tokens should\n * be displayed to a user as `5.05` (`505 / 10 ** 2`).\n *\n * Tokens usually opt for a value of 18, imitating the relationship between\n * Ether and Wei. This is the value {ERC20} uses, unless this function is\n * overridden;\n *\n * NOTE: This information is only used for _display_ purposes: it in\n * no way affects any of the arithmetic of the contract, including\n * {IERC20-balanceOf} and {IERC20-transfer}.\n */\n function decimals() public view virtual override returns (uint8) {\n return 18;\n }\n\n /**\n * @dev See {IERC20-totalSupply}.\n */\n function totalSupply() public view virtual override returns (uint256) {\n return _totalSupply;\n }\n\n /**\n * @dev See {IERC20-balanceOf}.\n */\n function balanceOf(address account) public view virtual override returns (uint256) {\n return _balances[account];\n }\n\n /**\n * @dev See {IERC20-transfer}.\n *\n * Requirements:\n *\n * - `to` cannot be the zero address.\n * - the caller must have a balance of at least `amount`.\n */\n function transfer(address to, uint256 amount) public virtual override returns (bool) {\n address owner = _msgSender();\n _transfer(owner, to, amount);\n return true;\n }\n\n /**\n * @dev See {IERC20-allowance}.\n */\n function allowance(address owner, address spender) public view virtual override returns (uint256) {\n return _allowances[owner][spender];\n }\n\n /**\n * @dev See {IERC20-approve}.\n *\n * NOTE: If `amount` is the maximum `uint256`, the allowance is not updated on\n * `transferFrom`. This is semantically equivalent to an infinite approval.\n *\n * Requirements:\n *\n * - `spender` cannot be the zero address.\n */\n function approve(address spender, uint256 amount) public virtual override returns (bool) {\n address owner = _msgSender();\n _approve(owner, spender, amount);\n return true;\n }\n\n /**\n * @dev See {IERC20-transferFrom}.\n *\n * Emits an {Approval} event indicating the updated allowance. This is not\n * required by the EIP. See the note at the beginning of {ERC20}.\n *\n * NOTE: Does not update the allowance if the current allowance\n * is the maximum `uint256`.\n *\n * Requirements:\n *\n * - `from` and `to` cannot be the zero address.\n * - `from` must have a balance of at least `amount`.\n * - the caller must have allowance for ``from``'s tokens of at least\n * `amount`.\n */\n function transferFrom(\n address from,\n address to,\n uint256 amount\n ) public virtual override returns (bool) {\n address spender = _msgSender();\n _spendAllowance(from, spender, amount);\n _transfer(from, to, amount);\n return true;\n }\n\n /**\n * @dev Atomically increases the allowance granted to `spender` by the caller.\n *\n * This is an alternative to {approve} that can be used as a mitigation for\n * problems described in {IERC20-approve}.\n *\n * Emits an {Approval} event indicating the updated allowance.\n *\n * Requirements:\n *\n * - `spender` cannot be the zero address.\n */\n function increaseAllowance(address spender, uint256 addedValue) public virtual returns (bool) {\n address owner = _msgSender();\n _approve(owner, spender, allowance(owner, spender) + addedValue);\n return true;\n }\n\n /**\n * @dev Atomically decreases the allowance granted to `spender` by the caller.\n *\n * This is an alternative to {approve} that can be used as a mitigation for\n * problems described in {IERC20-approve}.\n *\n * Emits an {Approval} event indicating the updated allowance.\n *\n * Requirements:\n *\n * - `spender` cannot be the zero address.\n * - `spender` must have allowance for the caller of at least\n * `subtractedValue`.\n */\n function decreaseAllowance(address spender, uint256 subtractedValue) public virtual returns (bool) {\n address owner = _msgSender();\n uint256 currentAllowance = allowance(owner, spender);\n require(currentAllowance >= subtractedValue, \"ERC20: decreased allowance below zero\");\n unchecked {\n _approve(owner, spender, currentAllowance - subtractedValue);\n }\n\n return true;\n }\n\n /**\n * @dev Moves `amount` of tokens from `from` to `to`.\n *\n * This internal function is equivalent to {transfer}, and can be used to\n * e.g. implement automatic token fees, slashing mechanisms, etc.\n *\n * Emits a {Transfer} event.\n *\n * Requirements:\n *\n * - `from` cannot be the zero address.\n * - `to` cannot be the zero address.\n * - `from` must have a balance of at least `amount`.\n */\n function _transfer(\n address from,\n address to,\n uint256 amount\n ) internal virtual {\n require(from != address(0), \"ERC20: transfer from the zero address\");\n require(to != address(0), \"ERC20: transfer to the zero address\");\n\n _beforeTokenTransfer(from, to, amount);\n\n uint256 fromBalance = _balances[from];\n require(fromBalance >= amount, \"ERC20: transfer amount exceeds balance\");\n unchecked {\n _balances[from] = fromBalance - amount;\n }\n _balances[to] += amount;\n\n emit Transfer(from, to, amount);\n\n _afterTokenTransfer(from, to, amount);\n }\n\n /** @dev Creates `amount` tokens and assigns them to `account`, increasing\n * the total supply.\n *\n * Emits a {Transfer} event with `from` set to the zero address.\n *\n * Requirements:\n *\n * - `account` cannot be the zero address.\n */\n function _mint(address account, uint256 amount) internal virtual {\n require(account != address(0), \"ERC20: mint to the zero address\");\n\n _beforeTokenTransfer(address(0), account, amount);\n\n _totalSupply += amount;\n _balances[account] += amount;\n emit Transfer(address(0), account, amount);\n\n _afterTokenTransfer(address(0), account, amount);\n }\n\n /**\n * @dev Destroys `amount` tokens from `account`, reducing the\n * total supply.\n *\n * Emits a {Transfer} event with `to` set to the zero address.\n *\n * Requirements:\n *\n * - `account` cannot be the zero address.\n * - `account` must have at least `amount` tokens.\n */\n function _burn(address account, uint256 amount) internal virtual {\n require(account != address(0), \"ERC20: burn from the zero address\");\n\n _beforeTokenTransfer(account, address(0), amount);\n\n uint256 accountBalance = _balances[account];\n require(accountBalance >= amount, \"ERC20: burn amount exceeds balance\");\n unchecked {\n _balances[account] = accountBalance - amount;\n }\n _totalSupply -= amount;\n\n emit Transfer(account, address(0), amount);\n\n _afterTokenTransfer(account, address(0), amount);\n }\n\n /**\n * @dev Sets `amount` as the allowance of `spender` over the `owner` s tokens.\n *\n * This internal function is equivalent to `approve`, and can be used to\n * e.g. set automatic allowances for certain subsystems, etc.\n *\n * Emits an {Approval} event.\n *\n * Requirements:\n *\n * - `owner` cannot be the zero address.\n * - `spender` cannot be the zero address.\n */\n function _approve(\n address owner,\n address spender,\n uint256 amount\n ) internal virtual {\n require(owner != address(0), \"ERC20: approve from the zero address\");\n require(spender != address(0), \"ERC20: approve to the zero address\");\n\n _allowances[owner][spender] = amount;\n emit Approval(owner, spender, amount);\n }\n\n /**\n * @dev Updates `owner` s allowance for `spender` based on spent `amount`.\n *\n * Does not update the allowance amount in case of infinite allowance.\n * Revert if not enough allowance is available.\n *\n * Might emit an {Approval} event.\n */\n function _spendAllowance(\n address owner,\n address spender,\n uint256 amount\n ) internal virtual {\n uint256 currentAllowance = allowance(owner, spender);\n if (currentAllowance != type(uint256).max) {\n require(currentAllowance >= amount, \"ERC20: insufficient allowance\");\n unchecked {\n _approve(owner, spender, currentAllowance - amount);\n }\n }\n }\n\n /**\n * @dev Hook that is called before any transfer of tokens. This includes\n * minting and burning.\n *\n * Calling conditions:\n *\n * - when `from` and `to` are both non-zero, `amount` of ``from``'s tokens\n * will be transferred to `to`.\n * - when `from` is zero, `amount` tokens will be minted for `to`.\n * - when `to` is zero, `amount` of ``from``'s tokens will be burned.\n * - `from` and `to` are never both zero.\n *\n * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].\n */\n function _beforeTokenTransfer(\n address from,\n address to,\n uint256 amount\n ) internal virtual {}\n\n /**\n * @dev Hook that is called after any transfer of tokens. This includes\n * minting and burning.\n *\n * Calling conditions:\n *\n * - when `from` and `to` are both non-zero, `amount` of ``from``'s tokens\n * has been transferred to `to`.\n * - when `from` is zero, `amount` tokens have been minted for `to`.\n * - when `to` is zero, `amount` of ``from``'s tokens have been burned.\n * - `from` and `to` are never both zero.\n *\n * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].\n */\n function _afterTokenTransfer(\n address from,\n address to,\n uint256 amount\n ) internal virtual {}\n}\n" + }, + "@openzeppelin/contracts/token/ERC20/extensions/draft-ERC20Permit.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.6.0) (token/ERC20/extensions/draft-ERC20Permit.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./draft-IERC20Permit.sol\";\nimport \"../ERC20.sol\";\nimport \"../../../utils/cryptography/draft-EIP712.sol\";\nimport \"../../../utils/cryptography/ECDSA.sol\";\nimport \"../../../utils/Counters.sol\";\n\n/**\n * @dev Implementation of the ERC20 Permit extension allowing approvals to be made via signatures, as defined in\n * https://eips.ethereum.org/EIPS/eip-2612[EIP-2612].\n *\n * Adds the {permit} method, which can be used to change an account's ERC20 allowance (see {IERC20-allowance}) by\n * presenting a message signed by the account. By not relying on `{IERC20-approve}`, the token holder account doesn't\n * need to send a transaction, and thus is not required to hold Ether at all.\n *\n * _Available since v3.4._\n */\nabstract contract ERC20Permit is ERC20, IERC20Permit, EIP712 {\n using Counters for Counters.Counter;\n\n mapping(address => Counters.Counter) private _nonces;\n\n // solhint-disable-next-line var-name-mixedcase\n bytes32 private constant _PERMIT_TYPEHASH =\n keccak256(\"Permit(address owner,address spender,uint256 value,uint256 nonce,uint256 deadline)\");\n /**\n * @dev In previous versions `_PERMIT_TYPEHASH` was declared as `immutable`.\n * However, to ensure consistency with the upgradeable transpiler, we will continue\n * to reserve a slot.\n * @custom:oz-renamed-from _PERMIT_TYPEHASH\n */\n // solhint-disable-next-line var-name-mixedcase\n bytes32 private _PERMIT_TYPEHASH_DEPRECATED_SLOT;\n\n /**\n * @dev Initializes the {EIP712} domain separator using the `name` parameter, and setting `version` to `\"1\"`.\n *\n * It's a good idea to use the same `name` that is defined as the ERC20 token name.\n */\n constructor(string memory name) EIP712(name, \"1\") {}\n\n /**\n * @dev See {IERC20Permit-permit}.\n */\n function permit(\n address owner,\n address spender,\n uint256 value,\n uint256 deadline,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) public virtual override {\n require(block.timestamp <= deadline, \"ERC20Permit: expired deadline\");\n\n bytes32 structHash = keccak256(abi.encode(_PERMIT_TYPEHASH, owner, spender, value, _useNonce(owner), deadline));\n\n bytes32 hash = _hashTypedDataV4(structHash);\n\n address signer = ECDSA.recover(hash, v, r, s);\n require(signer == owner, \"ERC20Permit: invalid signature\");\n\n _approve(owner, spender, value);\n }\n\n /**\n * @dev See {IERC20Permit-nonces}.\n */\n function nonces(address owner) public view virtual override returns (uint256) {\n return _nonces[owner].current();\n }\n\n /**\n * @dev See {IERC20Permit-DOMAIN_SEPARATOR}.\n */\n // solhint-disable-next-line func-name-mixedcase\n function DOMAIN_SEPARATOR() external view override returns (bytes32) {\n return _domainSeparatorV4();\n }\n\n /**\n * @dev \"Consume a nonce\": return the current value and increment.\n *\n * _Available since v4.1._\n */\n function _useNonce(address owner) internal virtual returns (uint256 current) {\n Counters.Counter storage nonce = _nonces[owner];\n current = nonce.current();\n nonce.increment();\n }\n}\n" + }, + "@openzeppelin/contracts/token/ERC20/extensions/draft-IERC20Permit.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (token/ERC20/extensions/draft-IERC20Permit.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Interface of the ERC20 Permit extension allowing approvals to be made via signatures, as defined in\n * https://eips.ethereum.org/EIPS/eip-2612[EIP-2612].\n *\n * Adds the {permit} method, which can be used to change an account's ERC20 allowance (see {IERC20-allowance}) by\n * presenting a message signed by the account. By not relying on {IERC20-approve}, the token holder account doesn't\n * need to send a transaction, and thus is not required to hold Ether at all.\n */\ninterface IERC20Permit {\n /**\n * @dev Sets `value` as the allowance of `spender` over ``owner``'s tokens,\n * given ``owner``'s signed approval.\n *\n * IMPORTANT: The same issues {IERC20-approve} has related to transaction\n * ordering also apply here.\n *\n * Emits an {Approval} event.\n *\n * Requirements:\n *\n * - `spender` cannot be the zero address.\n * - `deadline` must be a timestamp in the future.\n * - `v`, `r` and `s` must be a valid `secp256k1` signature from `owner`\n * over the EIP712-formatted function arguments.\n * - the signature must use ``owner``'s current nonce (see {nonces}).\n *\n * For more information on the signature format, see the\n * https://eips.ethereum.org/EIPS/eip-2612#specification[relevant EIP\n * section].\n */\n function permit(\n address owner,\n address spender,\n uint256 value,\n uint256 deadline,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) external;\n\n /**\n * @dev Returns the current nonce for `owner`. This value must be\n * included whenever a signature is generated for {permit}.\n *\n * Every successful call to {permit} increases ``owner``'s nonce by one. This\n * prevents a signature from being used multiple times.\n */\n function nonces(address owner) external view returns (uint256);\n\n /**\n * @dev Returns the domain separator used in the encoding of the signature for {permit}, as defined by {EIP712}.\n */\n // solhint-disable-next-line func-name-mixedcase\n function DOMAIN_SEPARATOR() external view returns (bytes32);\n}\n" + }, + "@openzeppelin/contracts/token/ERC20/extensions/IERC20Metadata.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (token/ERC20/extensions/IERC20Metadata.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../IERC20.sol\";\n\n/**\n * @dev Interface for the optional metadata functions from the ERC20 standard.\n *\n * _Available since v4.1._\n */\ninterface IERC20Metadata is IERC20 {\n /**\n * @dev Returns the name of the token.\n */\n function name() external view returns (string memory);\n\n /**\n * @dev Returns the symbol of the token.\n */\n function symbol() external view returns (string memory);\n\n /**\n * @dev Returns the decimals places of the token.\n */\n function decimals() external view returns (uint8);\n}\n" + }, + "@openzeppelin/contracts/token/ERC20/IERC20.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.6.0) (token/ERC20/IERC20.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Interface of the ERC20 standard as defined in the EIP.\n */\ninterface IERC20 {\n /**\n * @dev Emitted when `value` tokens are moved from one account (`from`) to\n * another (`to`).\n *\n * Note that `value` may be zero.\n */\n event Transfer(address indexed from, address indexed to, uint256 value);\n\n /**\n * @dev Emitted when the allowance of a `spender` for an `owner` is set by\n * a call to {approve}. `value` is the new allowance.\n */\n event Approval(address indexed owner, address indexed spender, uint256 value);\n\n /**\n * @dev Returns the amount of tokens in existence.\n */\n function totalSupply() external view returns (uint256);\n\n /**\n * @dev Returns the amount of tokens owned by `account`.\n */\n function balanceOf(address account) external view returns (uint256);\n\n /**\n * @dev Moves `amount` tokens from the caller's account to `to`.\n *\n * Returns a boolean value indicating whether the operation succeeded.\n *\n * Emits a {Transfer} event.\n */\n function transfer(address to, uint256 amount) external returns (bool);\n\n /**\n * @dev Returns the remaining number of tokens that `spender` will be\n * allowed to spend on behalf of `owner` through {transferFrom}. This is\n * zero by default.\n *\n * This value changes when {approve} or {transferFrom} are called.\n */\n function allowance(address owner, address spender) external view returns (uint256);\n\n /**\n * @dev Sets `amount` as the allowance of `spender` over the caller's tokens.\n *\n * Returns a boolean value indicating whether the operation succeeded.\n *\n * IMPORTANT: Beware that changing an allowance with this method brings the risk\n * that someone may use both the old and the new allowance by unfortunate\n * transaction ordering. One possible solution to mitigate this race\n * condition is to first reduce the spender's allowance to 0 and set the\n * desired value afterwards:\n * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729\n *\n * Emits an {Approval} event.\n */\n function approve(address spender, uint256 amount) external returns (bool);\n\n /**\n * @dev Moves `amount` tokens from `from` to `to` using the\n * allowance mechanism. `amount` is then deducted from the caller's\n * allowance.\n *\n * Returns a boolean value indicating whether the operation succeeded.\n *\n * Emits a {Transfer} event.\n */\n function transferFrom(\n address from,\n address to,\n uint256 amount\n ) external returns (bool);\n}\n" + }, + "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (token/ERC20/utils/SafeERC20.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../IERC20.sol\";\nimport \"../extensions/draft-IERC20Permit.sol\";\nimport \"../../../utils/Address.sol\";\n\n/**\n * @title SafeERC20\n * @dev Wrappers around ERC20 operations that throw on failure (when the token\n * contract returns false). Tokens that return no value (and instead revert or\n * throw on failure) are also supported, non-reverting calls are assumed to be\n * successful.\n * To use this library you can add a `using SafeERC20 for IERC20;` statement to your contract,\n * which allows you to call the safe operations as `token.safeTransfer(...)`, etc.\n */\nlibrary SafeERC20 {\n using Address for address;\n\n function safeTransfer(\n IERC20 token,\n address to,\n uint256 value\n ) internal {\n _callOptionalReturn(token, abi.encodeWithSelector(token.transfer.selector, to, value));\n }\n\n function safeTransferFrom(\n IERC20 token,\n address from,\n address to,\n uint256 value\n ) internal {\n _callOptionalReturn(token, abi.encodeWithSelector(token.transferFrom.selector, from, to, value));\n }\n\n /**\n * @dev Deprecated. This function has issues similar to the ones found in\n * {IERC20-approve}, and its usage is discouraged.\n *\n * Whenever possible, use {safeIncreaseAllowance} and\n * {safeDecreaseAllowance} instead.\n */\n function safeApprove(\n IERC20 token,\n address spender,\n uint256 value\n ) internal {\n // safeApprove should only be called when setting an initial allowance,\n // or when resetting it to zero. To increase and decrease it, use\n // 'safeIncreaseAllowance' and 'safeDecreaseAllowance'\n require(\n (value == 0) || (token.allowance(address(this), spender) == 0),\n \"SafeERC20: approve from non-zero to non-zero allowance\"\n );\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, value));\n }\n\n function safeIncreaseAllowance(\n IERC20 token,\n address spender,\n uint256 value\n ) internal {\n uint256 newAllowance = token.allowance(address(this), spender) + value;\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));\n }\n\n function safeDecreaseAllowance(\n IERC20 token,\n address spender,\n uint256 value\n ) internal {\n unchecked {\n uint256 oldAllowance = token.allowance(address(this), spender);\n require(oldAllowance >= value, \"SafeERC20: decreased allowance below zero\");\n uint256 newAllowance = oldAllowance - value;\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));\n }\n }\n\n function safePermit(\n IERC20Permit token,\n address owner,\n address spender,\n uint256 value,\n uint256 deadline,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) internal {\n uint256 nonceBefore = token.nonces(owner);\n token.permit(owner, spender, value, deadline, v, r, s);\n uint256 nonceAfter = token.nonces(owner);\n require(nonceAfter == nonceBefore + 1, \"SafeERC20: permit did not succeed\");\n }\n\n /**\n * @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement\n * on the return value: the return value is optional (but if data is returned, it must not be false).\n * @param token The token targeted by the call.\n * @param data The call data (encoded using abi.encode or one of its variants).\n */\n function _callOptionalReturn(IERC20 token, bytes memory data) private {\n // We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since\n // we're implementing it ourselves. We use {Address.functionCall} to perform this call, which verifies that\n // the target address contains contract code and also asserts for success in the low-level call.\n\n bytes memory returndata = address(token).functionCall(data, \"SafeERC20: low-level call failed\");\n if (returndata.length > 0) {\n // Return data is optional\n require(abi.decode(returndata, (bool)), \"SafeERC20: ERC20 operation did not succeed\");\n }\n }\n}\n" + }, + "@openzeppelin/contracts/token/ERC721/extensions/IERC721Metadata.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (token/ERC721/extensions/IERC721Metadata.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../IERC721.sol\";\n\n/**\n * @title ERC-721 Non-Fungible Token Standard, optional metadata extension\n * @dev See https://eips.ethereum.org/EIPS/eip-721\n */\ninterface IERC721Metadata is IERC721 {\n /**\n * @dev Returns the token collection name.\n */\n function name() external view returns (string memory);\n\n /**\n * @dev Returns the token collection symbol.\n */\n function symbol() external view returns (string memory);\n\n /**\n * @dev Returns the Uniform Resource Identifier (URI) for `tokenId` token.\n */\n function tokenURI(uint256 tokenId) external view returns (string memory);\n}\n" + }, + "@openzeppelin/contracts/token/ERC721/IERC721.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (token/ERC721/IERC721.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../../utils/introspection/IERC165.sol\";\n\n/**\n * @dev Required interface of an ERC721 compliant contract.\n */\ninterface IERC721 is IERC165 {\n /**\n * @dev Emitted when `tokenId` token is transferred from `from` to `to`.\n */\n event Transfer(address indexed from, address indexed to, uint256 indexed tokenId);\n\n /**\n * @dev Emitted when `owner` enables `approved` to manage the `tokenId` token.\n */\n event Approval(address indexed owner, address indexed approved, uint256 indexed tokenId);\n\n /**\n * @dev Emitted when `owner` enables or disables (`approved`) `operator` to manage all of its assets.\n */\n event ApprovalForAll(address indexed owner, address indexed operator, bool approved);\n\n /**\n * @dev Returns the number of tokens in ``owner``'s account.\n */\n function balanceOf(address owner) external view returns (uint256 balance);\n\n /**\n * @dev Returns the owner of the `tokenId` token.\n *\n * Requirements:\n *\n * - `tokenId` must exist.\n */\n function ownerOf(uint256 tokenId) external view returns (address owner);\n\n /**\n * @dev Safely transfers `tokenId` token from `from` to `to`.\n *\n * Requirements:\n *\n * - `from` cannot be the zero address.\n * - `to` cannot be the zero address.\n * - `tokenId` token must exist and be owned by `from`.\n * - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}.\n * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.\n *\n * Emits a {Transfer} event.\n */\n function safeTransferFrom(\n address from,\n address to,\n uint256 tokenId,\n bytes calldata data\n ) external;\n\n /**\n * @dev Safely transfers `tokenId` token from `from` to `to`, checking first that contract recipients\n * are aware of the ERC721 protocol to prevent tokens from being forever locked.\n *\n * Requirements:\n *\n * - `from` cannot be the zero address.\n * - `to` cannot be the zero address.\n * - `tokenId` token must exist and be owned by `from`.\n * - If the caller is not `from`, it must have been allowed to move this token by either {approve} or {setApprovalForAll}.\n * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.\n *\n * Emits a {Transfer} event.\n */\n function safeTransferFrom(\n address from,\n address to,\n uint256 tokenId\n ) external;\n\n /**\n * @dev Transfers `tokenId` token from `from` to `to`.\n *\n * WARNING: Usage of this method is discouraged, use {safeTransferFrom} whenever possible.\n *\n * Requirements:\n *\n * - `from` cannot be the zero address.\n * - `to` cannot be the zero address.\n * - `tokenId` token must be owned by `from`.\n * - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}.\n *\n * Emits a {Transfer} event.\n */\n function transferFrom(\n address from,\n address to,\n uint256 tokenId\n ) external;\n\n /**\n * @dev Gives permission to `to` to transfer `tokenId` token to another account.\n * The approval is cleared when the token is transferred.\n *\n * Only a single account can be approved at a time, so approving the zero address clears previous approvals.\n *\n * Requirements:\n *\n * - The caller must own the token or be an approved operator.\n * - `tokenId` must exist.\n *\n * Emits an {Approval} event.\n */\n function approve(address to, uint256 tokenId) external;\n\n /**\n * @dev Approve or remove `operator` as an operator for the caller.\n * Operators can call {transferFrom} or {safeTransferFrom} for any token owned by the caller.\n *\n * Requirements:\n *\n * - The `operator` cannot be the caller.\n *\n * Emits an {ApprovalForAll} event.\n */\n function setApprovalForAll(address operator, bool _approved) external;\n\n /**\n * @dev Returns the account approved for `tokenId` token.\n *\n * Requirements:\n *\n * - `tokenId` must exist.\n */\n function getApproved(uint256 tokenId) external view returns (address operator);\n\n /**\n * @dev Returns if the `operator` is allowed to manage all of the assets of `owner`.\n *\n * See {setApprovalForAll}\n */\n function isApprovedForAll(address owner, address operator) external view returns (bool);\n}\n" + }, + "@openzeppelin/contracts/utils/Address.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (utils/Address.sol)\n\npragma solidity ^0.8.1;\n\n/**\n * @dev Collection of functions related to the address type\n */\nlibrary Address {\n /**\n * @dev Returns true if `account` is a contract.\n *\n * [IMPORTANT]\n * ====\n * It is unsafe to assume that an address for which this function returns\n * false is an externally-owned account (EOA) and not a contract.\n *\n * Among others, `isContract` will return false for the following\n * types of addresses:\n *\n * - an externally-owned account\n * - a contract in construction\n * - an address where a contract will be created\n * - an address where a contract lived, but was destroyed\n * ====\n *\n * [IMPORTANT]\n * ====\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\n *\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\n * constructor.\n * ====\n */\n function isContract(address account) internal view returns (bool) {\n // This method relies on extcodesize/address.code.length, which returns 0\n // for contracts in construction, since the code is only stored at the end\n // of the constructor execution.\n\n return account.code.length > 0;\n }\n\n /**\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\n * `recipient`, forwarding all available gas and reverting on errors.\n *\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\n * imposed by `transfer`, making them unable to receive funds via\n * `transfer`. {sendValue} removes this limitation.\n *\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\n *\n * IMPORTANT: because control is transferred to `recipient`, care must be\n * taken to not create reentrancy vulnerabilities. Consider using\n * {ReentrancyGuard} or the\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\n */\n function sendValue(address payable recipient, uint256 amount) internal {\n require(address(this).balance >= amount, \"Address: insufficient balance\");\n\n (bool success, ) = recipient.call{value: amount}(\"\");\n require(success, \"Address: unable to send value, recipient may have reverted\");\n }\n\n /**\n * @dev Performs a Solidity function call using a low level `call`. A\n * plain `call` is an unsafe replacement for a function call: use this\n * function instead.\n *\n * If `target` reverts with a revert reason, it is bubbled up by this\n * function (like regular Solidity function calls).\n *\n * Returns the raw returned data. To convert to the expected return value,\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\n *\n * Requirements:\n *\n * - `target` must be a contract.\n * - calling `target` with `data` must not revert.\n *\n * _Available since v3.1._\n */\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionCall(target, data, \"Address: low-level call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\n * `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, 0, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but also transferring `value` wei to `target`.\n *\n * Requirements:\n *\n * - the calling contract must have an ETH balance of at least `value`.\n * - the called Solidity function must be `payable`.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, value, \"Address: low-level call with value failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\n * with `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(address(this).balance >= value, \"Address: insufficient balance for call\");\n require(isContract(target), \"Address: call to non-contract\");\n\n (bool success, bytes memory returndata) = target.call{value: value}(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\n return functionStaticCall(target, data, \"Address: low-level static call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal view returns (bytes memory) {\n require(isContract(target), \"Address: static call to non-contract\");\n\n (bool success, bytes memory returndata) = target.staticcall(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a delegate call.\n *\n * _Available since v3.4._\n */\n function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionDelegateCall(target, data, \"Address: low-level delegate call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a delegate call.\n *\n * _Available since v3.4._\n */\n function functionDelegateCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(isContract(target), \"Address: delegate call to non-contract\");\n\n (bool success, bytes memory returndata) = target.delegatecall(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the\n * revert reason using the provided one.\n *\n * _Available since v4.3._\n */\n function verifyCallResult(\n bool success,\n bytes memory returndata,\n string memory errorMessage\n ) internal pure returns (bytes memory) {\n if (success) {\n return returndata;\n } else {\n // Look for revert reason and bubble it up if present\n if (returndata.length > 0) {\n // The easiest way to bubble the revert reason is using memory via assembly\n /// @solidity memory-safe-assembly\n assembly {\n let returndata_size := mload(returndata)\n revert(add(32, returndata), returndata_size)\n }\n } else {\n revert(errorMessage);\n }\n }\n }\n}\n" + }, + "@openzeppelin/contracts/utils/Context.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Provides information about the current execution context, including the\n * sender of the transaction and its data. While these are generally available\n * via msg.sender and msg.data, they should not be accessed in such a direct\n * manner, since when dealing with meta-transactions the account sending and\n * paying for execution may not be the actual sender (as far as an application\n * is concerned).\n *\n * This contract is only required for intermediate, library-like contracts.\n */\nabstract contract Context {\n function _msgSender() internal view virtual returns (address) {\n return msg.sender;\n }\n\n function _msgData() internal view virtual returns (bytes calldata) {\n return msg.data;\n }\n}\n" + }, + "@openzeppelin/contracts/utils/Counters.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (utils/Counters.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @title Counters\n * @author Matt Condon (@shrugs)\n * @dev Provides counters that can only be incremented, decremented or reset. This can be used e.g. to track the number\n * of elements in a mapping, issuing ERC721 ids, or counting request ids.\n *\n * Include with `using Counters for Counters.Counter;`\n */\nlibrary Counters {\n struct Counter {\n // This variable should never be directly accessed by users of the library: interactions must be restricted to\n // the library's function. As of Solidity v0.5.2, this cannot be enforced, though there is a proposal to add\n // this feature: see https://github.com/ethereum/solidity/issues/4637\n uint256 _value; // default: 0\n }\n\n function current(Counter storage counter) internal view returns (uint256) {\n return counter._value;\n }\n\n function increment(Counter storage counter) internal {\n unchecked {\n counter._value += 1;\n }\n }\n\n function decrement(Counter storage counter) internal {\n uint256 value = counter._value;\n require(value > 0, \"Counter: decrement overflow\");\n unchecked {\n counter._value = value - 1;\n }\n }\n\n function reset(Counter storage counter) internal {\n counter._value = 0;\n }\n}\n" + }, + "@openzeppelin/contracts/utils/cryptography/draft-EIP712.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (utils/cryptography/draft-EIP712.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./ECDSA.sol\";\n\n/**\n * @dev https://eips.ethereum.org/EIPS/eip-712[EIP 712] is a standard for hashing and signing of typed structured data.\n *\n * The encoding specified in the EIP is very generic, and such a generic implementation in Solidity is not feasible,\n * thus this contract does not implement the encoding itself. Protocols need to implement the type-specific encoding\n * they need in their contracts using a combination of `abi.encode` and `keccak256`.\n *\n * This contract implements the EIP 712 domain separator ({_domainSeparatorV4}) that is used as part of the encoding\n * scheme, and the final step of the encoding to obtain the message digest that is then signed via ECDSA\n * ({_hashTypedDataV4}).\n *\n * The implementation of the domain separator was designed to be as efficient as possible while still properly updating\n * the chain id to protect against replay attacks on an eventual fork of the chain.\n *\n * NOTE: This contract implements the version of the encoding known as \"v4\", as implemented by the JSON RPC method\n * https://docs.metamask.io/guide/signing-data.html[`eth_signTypedDataV4` in MetaMask].\n *\n * _Available since v3.4._\n */\nabstract contract EIP712 {\n /* solhint-disable var-name-mixedcase */\n // Cache the domain separator as an immutable value, but also store the chain id that it corresponds to, in order to\n // invalidate the cached domain separator if the chain id changes.\n bytes32 private immutable _CACHED_DOMAIN_SEPARATOR;\n uint256 private immutable _CACHED_CHAIN_ID;\n address private immutable _CACHED_THIS;\n\n bytes32 private immutable _HASHED_NAME;\n bytes32 private immutable _HASHED_VERSION;\n bytes32 private immutable _TYPE_HASH;\n\n /* solhint-enable var-name-mixedcase */\n\n /**\n * @dev Initializes the domain separator and parameter caches.\n *\n * The meaning of `name` and `version` is specified in\n * https://eips.ethereum.org/EIPS/eip-712#definition-of-domainseparator[EIP 712]:\n *\n * - `name`: the user readable name of the signing domain, i.e. the name of the DApp or the protocol.\n * - `version`: the current major version of the signing domain.\n *\n * NOTE: These parameters cannot be changed except through a xref:learn::upgrading-smart-contracts.adoc[smart\n * contract upgrade].\n */\n constructor(string memory name, string memory version) {\n bytes32 hashedName = keccak256(bytes(name));\n bytes32 hashedVersion = keccak256(bytes(version));\n bytes32 typeHash = keccak256(\n \"EIP712Domain(string name,string version,uint256 chainId,address verifyingContract)\"\n );\n _HASHED_NAME = hashedName;\n _HASHED_VERSION = hashedVersion;\n _CACHED_CHAIN_ID = block.chainid;\n _CACHED_DOMAIN_SEPARATOR = _buildDomainSeparator(typeHash, hashedName, hashedVersion);\n _CACHED_THIS = address(this);\n _TYPE_HASH = typeHash;\n }\n\n /**\n * @dev Returns the domain separator for the current chain.\n */\n function _domainSeparatorV4() internal view returns (bytes32) {\n if (address(this) == _CACHED_THIS && block.chainid == _CACHED_CHAIN_ID) {\n return _CACHED_DOMAIN_SEPARATOR;\n } else {\n return _buildDomainSeparator(_TYPE_HASH, _HASHED_NAME, _HASHED_VERSION);\n }\n }\n\n function _buildDomainSeparator(\n bytes32 typeHash,\n bytes32 nameHash,\n bytes32 versionHash\n ) private view returns (bytes32) {\n return keccak256(abi.encode(typeHash, nameHash, versionHash, block.chainid, address(this)));\n }\n\n /**\n * @dev Given an already https://eips.ethereum.org/EIPS/eip-712#definition-of-hashstruct[hashed struct], this\n * function returns the hash of the fully encoded EIP712 message for this domain.\n *\n * This hash can be used together with {ECDSA-recover} to obtain the signer of a message. For example:\n *\n * ```solidity\n * bytes32 digest = _hashTypedDataV4(keccak256(abi.encode(\n * keccak256(\"Mail(address to,string contents)\"),\n * mailTo,\n * keccak256(bytes(mailContents))\n * )));\n * address signer = ECDSA.recover(digest, signature);\n * ```\n */\n function _hashTypedDataV4(bytes32 structHash) internal view virtual returns (bytes32) {\n return ECDSA.toTypedDataHash(_domainSeparatorV4(), structHash);\n }\n}\n" + }, + "@openzeppelin/contracts/utils/cryptography/ECDSA.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (utils/cryptography/ECDSA.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../Strings.sol\";\n\n/**\n * @dev Elliptic Curve Digital Signature Algorithm (ECDSA) operations.\n *\n * These functions can be used to verify that a message was signed by the holder\n * of the private keys of a given address.\n */\nlibrary ECDSA {\n enum RecoverError {\n NoError,\n InvalidSignature,\n InvalidSignatureLength,\n InvalidSignatureS,\n InvalidSignatureV\n }\n\n function _throwError(RecoverError error) private pure {\n if (error == RecoverError.NoError) {\n return; // no error: do nothing\n } else if (error == RecoverError.InvalidSignature) {\n revert(\"ECDSA: invalid signature\");\n } else if (error == RecoverError.InvalidSignatureLength) {\n revert(\"ECDSA: invalid signature length\");\n } else if (error == RecoverError.InvalidSignatureS) {\n revert(\"ECDSA: invalid signature 's' value\");\n } else if (error == RecoverError.InvalidSignatureV) {\n revert(\"ECDSA: invalid signature 'v' value\");\n }\n }\n\n /**\n * @dev Returns the address that signed a hashed message (`hash`) with\n * `signature` or error string. This address can then be used for verification purposes.\n *\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\n * this function rejects them by requiring the `s` value to be in the lower\n * half order, and the `v` value to be either 27 or 28.\n *\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\n * verification to be secure: it is possible to craft signatures that\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\n * this is by receiving a hash of the original message (which may otherwise\n * be too long), and then calling {toEthSignedMessageHash} on it.\n *\n * Documentation for signature generation:\n * - with https://web3js.readthedocs.io/en/v1.3.4/web3-eth-accounts.html#sign[Web3.js]\n * - with https://docs.ethers.io/v5/api/signer/#Signer-signMessage[ethers]\n *\n * _Available since v4.3._\n */\n function tryRecover(bytes32 hash, bytes memory signature) internal pure returns (address, RecoverError) {\n // Check the signature length\n // - case 65: r,s,v signature (standard)\n // - case 64: r,vs signature (cf https://eips.ethereum.org/EIPS/eip-2098) _Available since v4.1._\n if (signature.length == 65) {\n bytes32 r;\n bytes32 s;\n uint8 v;\n // ecrecover takes the signature parameters, and the only way to get them\n // currently is to use assembly.\n /// @solidity memory-safe-assembly\n assembly {\n r := mload(add(signature, 0x20))\n s := mload(add(signature, 0x40))\n v := byte(0, mload(add(signature, 0x60)))\n }\n return tryRecover(hash, v, r, s);\n } else if (signature.length == 64) {\n bytes32 r;\n bytes32 vs;\n // ecrecover takes the signature parameters, and the only way to get them\n // currently is to use assembly.\n /// @solidity memory-safe-assembly\n assembly {\n r := mload(add(signature, 0x20))\n vs := mload(add(signature, 0x40))\n }\n return tryRecover(hash, r, vs);\n } else {\n return (address(0), RecoverError.InvalidSignatureLength);\n }\n }\n\n /**\n * @dev Returns the address that signed a hashed message (`hash`) with\n * `signature`. This address can then be used for verification purposes.\n *\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\n * this function rejects them by requiring the `s` value to be in the lower\n * half order, and the `v` value to be either 27 or 28.\n *\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\n * verification to be secure: it is possible to craft signatures that\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\n * this is by receiving a hash of the original message (which may otherwise\n * be too long), and then calling {toEthSignedMessageHash} on it.\n */\n function recover(bytes32 hash, bytes memory signature) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, signature);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Overload of {ECDSA-tryRecover} that receives the `r` and `vs` short-signature fields separately.\n *\n * See https://eips.ethereum.org/EIPS/eip-2098[EIP-2098 short signatures]\n *\n * _Available since v4.3._\n */\n function tryRecover(\n bytes32 hash,\n bytes32 r,\n bytes32 vs\n ) internal pure returns (address, RecoverError) {\n bytes32 s = vs & bytes32(0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff);\n uint8 v = uint8((uint256(vs) >> 255) + 27);\n return tryRecover(hash, v, r, s);\n }\n\n /**\n * @dev Overload of {ECDSA-recover} that receives the `r and `vs` short-signature fields separately.\n *\n * _Available since v4.2._\n */\n function recover(\n bytes32 hash,\n bytes32 r,\n bytes32 vs\n ) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, r, vs);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Overload of {ECDSA-tryRecover} that receives the `v`,\n * `r` and `s` signature fields separately.\n *\n * _Available since v4.3._\n */\n function tryRecover(\n bytes32 hash,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) internal pure returns (address, RecoverError) {\n // EIP-2 still allows signature malleability for ecrecover(). Remove this possibility and make the signature\n // unique. Appendix F in the Ethereum Yellow paper (https://ethereum.github.io/yellowpaper/paper.pdf), defines\n // the valid range for s in (301): 0 < s < secp256k1n ÷ 2 + 1, and for v in (302): v ∈ {27, 28}. Most\n // signatures from current libraries generate a unique signature with an s-value in the lower half order.\n //\n // If your library generates malleable signatures, such as s-values in the upper range, calculate a new s-value\n // with 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141 - s1 and flip v from 27 to 28 or\n // vice versa. If your library also generates signatures with 0/1 for v instead 27/28, add 27 to v to accept\n // these malleable signatures as well.\n if (uint256(s) > 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D576E7357A4501DDFE92F46681B20A0) {\n return (address(0), RecoverError.InvalidSignatureS);\n }\n if (v != 27 && v != 28) {\n return (address(0), RecoverError.InvalidSignatureV);\n }\n\n // If the signature is valid (and not malleable), return the signer address\n address signer = ecrecover(hash, v, r, s);\n if (signer == address(0)) {\n return (address(0), RecoverError.InvalidSignature);\n }\n\n return (signer, RecoverError.NoError);\n }\n\n /**\n * @dev Overload of {ECDSA-recover} that receives the `v`,\n * `r` and `s` signature fields separately.\n */\n function recover(\n bytes32 hash,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, v, r, s);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Returns an Ethereum Signed Message, created from a `hash`. This\n * produces hash corresponding to the one signed with the\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\n * JSON-RPC method as part of EIP-191.\n *\n * See {recover}.\n */\n function toEthSignedMessageHash(bytes32 hash) internal pure returns (bytes32) {\n // 32 is the length in bytes of hash,\n // enforced by the type signature above\n return keccak256(abi.encodePacked(\"\\x19Ethereum Signed Message:\\n32\", hash));\n }\n\n /**\n * @dev Returns an Ethereum Signed Message, created from `s`. This\n * produces hash corresponding to the one signed with the\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\n * JSON-RPC method as part of EIP-191.\n *\n * See {recover}.\n */\n function toEthSignedMessageHash(bytes memory s) internal pure returns (bytes32) {\n return keccak256(abi.encodePacked(\"\\x19Ethereum Signed Message:\\n\", Strings.toString(s.length), s));\n }\n\n /**\n * @dev Returns an Ethereum Signed Typed Data, created from a\n * `domainSeparator` and a `structHash`. This produces hash corresponding\n * to the one signed with the\n * https://eips.ethereum.org/EIPS/eip-712[`eth_signTypedData`]\n * JSON-RPC method as part of EIP-712.\n *\n * See {recover}.\n */\n function toTypedDataHash(bytes32 domainSeparator, bytes32 structHash) internal pure returns (bytes32) {\n return keccak256(abi.encodePacked(\"\\x19\\x01\", domainSeparator, structHash));\n }\n}\n" + }, + "@openzeppelin/contracts/utils/introspection/IERC165.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (utils/introspection/IERC165.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Interface of the ERC165 standard, as defined in the\n * https://eips.ethereum.org/EIPS/eip-165[EIP].\n *\n * Implementers can declare support of contract interfaces, which can then be\n * queried by others ({ERC165Checker}).\n *\n * For an implementation, see {ERC165}.\n */\ninterface IERC165 {\n /**\n * @dev Returns true if this contract implements the interface defined by\n * `interfaceId`. See the corresponding\n * https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified[EIP section]\n * to learn more about how these ids are created.\n *\n * This function call must use less than 30 000 gas.\n */\n function supportsInterface(bytes4 interfaceId) external view returns (bool);\n}\n" + }, + "@openzeppelin/contracts/utils/StorageSlot.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (utils/StorageSlot.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Library for reading and writing primitive types to specific storage slots.\n *\n * Storage slots are often used to avoid storage conflict when dealing with upgradeable contracts.\n * This library helps with reading and writing to such slots without the need for inline assembly.\n *\n * The functions in this library return Slot structs that contain a `value` member that can be used to read or write.\n *\n * Example usage to set ERC1967 implementation slot:\n * ```\n * contract ERC1967 {\n * bytes32 internal constant _IMPLEMENTATION_SLOT = 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc;\n *\n * function _getImplementation() internal view returns (address) {\n * return StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value;\n * }\n *\n * function _setImplementation(address newImplementation) internal {\n * require(Address.isContract(newImplementation), \"ERC1967: new implementation is not a contract\");\n * StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value = newImplementation;\n * }\n * }\n * ```\n *\n * _Available since v4.1 for `address`, `bool`, `bytes32`, and `uint256`._\n */\nlibrary StorageSlot {\n struct AddressSlot {\n address value;\n }\n\n struct BooleanSlot {\n bool value;\n }\n\n struct Bytes32Slot {\n bytes32 value;\n }\n\n struct Uint256Slot {\n uint256 value;\n }\n\n /**\n * @dev Returns an `AddressSlot` with member `value` located at `slot`.\n */\n function getAddressSlot(bytes32 slot) internal pure returns (AddressSlot storage r) {\n /// @solidity memory-safe-assembly\n assembly {\n r.slot := slot\n }\n }\n\n /**\n * @dev Returns an `BooleanSlot` with member `value` located at `slot`.\n */\n function getBooleanSlot(bytes32 slot) internal pure returns (BooleanSlot storage r) {\n /// @solidity memory-safe-assembly\n assembly {\n r.slot := slot\n }\n }\n\n /**\n * @dev Returns an `Bytes32Slot` with member `value` located at `slot`.\n */\n function getBytes32Slot(bytes32 slot) internal pure returns (Bytes32Slot storage r) {\n /// @solidity memory-safe-assembly\n assembly {\n r.slot := slot\n }\n }\n\n /**\n * @dev Returns an `Uint256Slot` with member `value` located at `slot`.\n */\n function getUint256Slot(bytes32 slot) internal pure returns (Uint256Slot storage r) {\n /// @solidity memory-safe-assembly\n assembly {\n r.slot := slot\n }\n }\n}\n" + }, + "@openzeppelin/contracts/utils/Strings.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (utils/Strings.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev String operations.\n */\nlibrary Strings {\n bytes16 private constant _HEX_SYMBOLS = \"0123456789abcdef\";\n uint8 private constant _ADDRESS_LENGTH = 20;\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` decimal representation.\n */\n function toString(uint256 value) internal pure returns (string memory) {\n // Inspired by OraclizeAPI's implementation - MIT licence\n // https://github.com/oraclize/ethereum-api/blob/b42146b063c7d6ee1358846c198246239e9360e8/oraclizeAPI_0.4.25.sol\n\n if (value == 0) {\n return \"0\";\n }\n uint256 temp = value;\n uint256 digits;\n while (temp != 0) {\n digits++;\n temp /= 10;\n }\n bytes memory buffer = new bytes(digits);\n while (value != 0) {\n digits -= 1;\n buffer[digits] = bytes1(uint8(48 + uint256(value % 10)));\n value /= 10;\n }\n return string(buffer);\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation.\n */\n function toHexString(uint256 value) internal pure returns (string memory) {\n if (value == 0) {\n return \"0x00\";\n }\n uint256 temp = value;\n uint256 length = 0;\n while (temp != 0) {\n length++;\n temp >>= 8;\n }\n return toHexString(value, length);\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length.\n */\n function toHexString(uint256 value, uint256 length) internal pure returns (string memory) {\n bytes memory buffer = new bytes(2 * length + 2);\n buffer[0] = \"0\";\n buffer[1] = \"x\";\n for (uint256 i = 2 * length + 1; i > 1; --i) {\n buffer[i] = _HEX_SYMBOLS[value & 0xf];\n value >>= 4;\n }\n require(value == 0, \"Strings: hex length insufficient\");\n return string(buffer);\n }\n\n /**\n * @dev Converts an `address` with fixed length of 20 bytes to its not checksummed ASCII `string` hexadecimal representation.\n */\n function toHexString(address addr) internal pure returns (string memory) {\n return toHexString(uint256(uint160(addr)), _ADDRESS_LENGTH);\n }\n}\n" + }, + "contracts/agToken/AgEUR.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\nimport \"../interfaces/IAgToken.sol\";\nimport \"../interfaces/coreModule/IStableMaster.sol\";\nimport \"../interfaces/ITreasury.sol\";\nimport \"@openzeppelin/contracts-upgradeable/token/ERC20/extensions/draft-ERC20PermitUpgradeable.sol\";\n\n/// @title AgEUR\n/// @author Angle Labs, Inc.\n/// @notice Base contract for agEUR, Angle's Euro stablecoin\n/// @dev This contract is an upgraded version of the agEUR contract that was first deployed on Ethereum mainnet\ncontract AgEUR is IAgToken, ERC20PermitUpgradeable {\n // ================================= REFERENCES ================================\n\n /// @notice Reference to the `StableMaster` contract associated to agEUR\n address public stableMaster;\n\n /// @custom:oz-upgrades-unsafe-allow constructor\n constructor() initializer {}\n\n // ============================== ADDED PARAMETERS =============================\n\n /// @inheritdoc IAgToken\n mapping(address => bool) public isMinter;\n /// @notice Reference to the treasury contract which can grant minting rights\n address public treasury;\n /// @notice Boolean used to check whether the contract had been reinitialized after an upgrade\n bool public treasuryInitialized;\n\n // =================================== EVENTS ==================================\n\n event TreasuryUpdated(address indexed _treasury);\n event MinterToggled(address indexed minter);\n\n // =================================== ERRORS ==================================\n\n error BurnAmountExceedsAllowance();\n error InvalidSender();\n error InvalidTreasury();\n error NotGovernor();\n error NotMinter();\n error NotTreasury();\n error TreasuryAlreadyInitialized();\n\n // ================================= MODIFIERS =================================\n\n /// @notice Checks to see if it is the `Treasury` calling this contract\n modifier onlyTreasury() {\n if (msg.sender != treasury) revert NotTreasury();\n _;\n }\n\n /// @notice Checks whether the sender has the minting right\n modifier onlyMinter() {\n if (!isMinter[msg.sender]) revert NotMinter();\n _;\n }\n\n // ============================= EXTERNAL FUNCTION =============================\n\n /// @notice Allows anyone to burn stablecoins\n /// @param amount Amount of stablecoins to burn\n /// @dev This function can typically be called if there is a settlement mechanism to burn stablecoins\n function burnStablecoin(uint256 amount) external {\n _burn(msg.sender, amount);\n }\n\n // ========================= MINTER ROLE ONLY FUNCTIONS ========================\n\n /// @inheritdoc IAgToken\n function burnSelf(uint256 amount, address burner) external onlyMinter {\n _burn(burner, amount);\n }\n\n /// @inheritdoc IAgToken\n function burnFrom(uint256 amount, address burner, address sender) external onlyMinter {\n if (burner != sender) {\n uint256 currentAllowance = allowance(burner, sender);\n if (currentAllowance < amount) revert BurnAmountExceedsAllowance();\n _approve(burner, sender, currentAllowance - amount);\n }\n _burn(burner, amount);\n }\n\n /// @inheritdoc IAgToken\n function mint(address account, uint256 amount) external onlyMinter {\n _mint(account, amount);\n }\n\n // ========================== TREASURY ONLY FUNCTIONS ==========================\n\n /// @inheritdoc IAgToken\n function addMinter(address minter) external onlyTreasury {\n isMinter[minter] = true;\n emit MinterToggled(minter);\n }\n\n /// @inheritdoc IAgToken\n function removeMinter(address minter) external {\n if (msg.sender != minter && msg.sender != address(treasury)) revert InvalidSender();\n isMinter[minter] = false;\n emit MinterToggled(minter);\n }\n\n /// @inheritdoc IAgToken\n function setTreasury(address _treasury) external onlyTreasury {\n treasury = _treasury;\n emit TreasuryUpdated(_treasury);\n }\n}\n" + }, + "contracts/agToken/AgToken.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\n/*\n * █ \n ***** ▓▓▓ \n * ▓▓▓▓▓▓▓ \n * ///. ▓▓▓▓▓▓▓▓▓▓▓▓▓ \n ***** //////// ▓▓▓▓▓▓▓ \n * ///////////// ▓▓▓ \n ▓▓ ////////////////// █ ▓▓ \n ▓▓ ▓▓ /////////////////////// ▓▓ ▓▓ \n ▓▓ ▓▓ //////////////////////////// ▓▓ ▓▓ \n ▓▓ ▓▓ /////////▓▓▓///////▓▓▓///////// ▓▓ ▓▓ \n ▓▓ ,////////////////////////////////////// ▓▓ ▓▓ \n ▓▓ ////////////////////////////////////////// ▓▓ \n ▓▓ //////////////////////▓▓▓▓///////////////////// \n ,//////////////////////////////////////////////////// \n .////////////////////////////////////////////////////////// \n .//////////////////////////██.,//////////////////////////█ \n .//////////////////////████..,./////////////////////██ \n ...////////////////███████.....,.////////////////███ \n ,.,////////////████████ ........,///////////████ \n .,.,//////█████████ ,.......///////████ \n ,..//████████ ........./████ \n ..,██████ .....,███ \n .██ ,.,█ \n \n \n \n ▓▓ ▓▓▓▓▓▓▓▓▓▓ ▓▓▓▓▓▓▓▓▓▓ ▓▓ ▓▓▓▓▓▓▓▓▓▓ \n ▓▓▓▓▓▓ ▓▓▓ ▓▓▓ ▓▓▓ ▓▓ ▓▓ ▓▓▓▓ \n ▓▓▓ ▓▓▓ ▓▓▓ ▓▓▓ ▓▓▓ ▓▓▓ ▓▓ ▓▓▓▓▓ \n ▓▓▓ ▓▓ ▓▓▓ ▓▓▓ ▓▓▓▓▓▓▓▓▓▓ ▓▓▓▓▓▓▓▓▓▓ ▓▓▓▓▓▓▓▓▓▓ \n*/\n\nimport \"../interfaces/IAgToken.sol\";\nimport \"../interfaces/ITreasury.sol\";\nimport \"@openzeppelin/contracts-upgradeable/token/ERC20/extensions/draft-ERC20PermitUpgradeable.sol\";\n\n/// @title AgToken\n/// @author Angle Labs, Inc.\n/// @notice Base contract for Angle agTokens on Ethereum and on other chains\n/// @dev By default, agTokens are ERC-20 tokens with 18 decimals\ncontract AgToken is IAgToken, ERC20PermitUpgradeable {\n // =========================== PARAMETERS / VARIABLES ==========================\n\n /// @inheritdoc IAgToken\n mapping(address => bool) public isMinter;\n /// @notice Reference to the treasury contract which can grant minting rights\n address public treasury;\n\n // =================================== EVENTS ==================================\n\n event TreasuryUpdated(address indexed _treasury);\n event MinterToggled(address indexed minter);\n\n // =================================== ERRORS ==================================\n\n error BurnAmountExceedsAllowance();\n error InvalidSender();\n error InvalidTreasury();\n error NotMinter();\n error NotTreasury();\n\n // ================================ CONSTRUCTOR ================================\n\n /// @custom:oz-upgrades-unsafe-allow constructor\n constructor() initializer {}\n\n /// @notice Initializes the `AgToken` contract\n function initialize(string memory name_, string memory symbol_, address _treasury) external {\n _initialize(name_, symbol_, _treasury);\n }\n\n /// @notice Initializes the contract\n function _initialize(string memory name_, string memory symbol_, address _treasury) internal virtual initializer {\n if (address(ITreasury(_treasury).stablecoin()) != address(this)) revert InvalidTreasury();\n __ERC20Permit_init(name_);\n __ERC20_init(name_, symbol_);\n treasury = _treasury;\n emit TreasuryUpdated(_treasury);\n }\n\n // ================================= MODIFIERS =================================\n\n /// @notice Checks to see if it is the `Treasury` calling this contract\n modifier onlyTreasury() {\n if (msg.sender != treasury) revert NotTreasury();\n _;\n }\n\n /// @notice Checks whether the sender has the minting right\n modifier onlyMinter() {\n if (!isMinter[msg.sender]) revert NotMinter();\n _;\n }\n\n // ============================= EXTERNAL FUNCTION =============================\n\n /// @notice Allows anyone to burn stablecoins\n /// @param amount Amount of stablecoins to burn\n /// @dev This function can typically be called if there is a settlement mechanism to burn stablecoins\n function burnStablecoin(uint256 amount) external {\n _burn(msg.sender, amount);\n }\n\n // ========================= MINTER ROLE ONLY FUNCTIONS ========================\n\n /// @inheritdoc IAgToken\n function burnSelf(uint256 amount, address burner) external onlyMinter {\n _burn(burner, amount);\n }\n\n /// @inheritdoc IAgToken\n function burnFrom(uint256 amount, address burner, address sender) external onlyMinter {\n if (burner != sender) {\n uint256 currentAllowance = allowance(burner, sender);\n if (currentAllowance < amount) revert BurnAmountExceedsAllowance();\n _approve(burner, sender, currentAllowance - amount);\n }\n _burn(burner, amount);\n }\n\n /// @inheritdoc IAgToken\n function mint(address account, uint256 amount) external onlyMinter {\n _mint(account, amount);\n }\n\n // ========================== GOVERNANCE ONLY FUNCTIONS ==========================\n\n /// @inheritdoc IAgToken\n function addMinter(address minter) external onlyTreasury {\n isMinter[minter] = true;\n emit MinterToggled(minter);\n }\n\n /// @inheritdoc IAgToken\n function removeMinter(address minter) external {\n if (msg.sender != address(treasury) && msg.sender != minter) revert InvalidSender();\n isMinter[minter] = false;\n emit MinterToggled(minter);\n }\n\n /// @inheritdoc IAgToken\n function setTreasury(address _treasury) external virtual onlyTreasury {\n treasury = _treasury;\n emit TreasuryUpdated(_treasury);\n }\n}\n" + }, + "contracts/agToken/AgTokenSideChainMultiBridge.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\nimport \"./AgToken.sol\";\nimport \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\nimport \"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\";\n\n/// @title AgTokenSideChainMultiBridge\n/// @author Angle Labs, Inc.\n/// @notice Contract for Angle agTokens on other chains than Ethereum mainnet\n/// @dev This contract supports bridge tokens having a minting right on the stablecoin (also referred to as the canonical\n/// or the native token)\ncontract AgTokenSideChainMultiBridge is AgToken {\n using SafeERC20 for IERC20;\n\n /// @notice Base used for fee computation\n uint256 public constant BASE_PARAMS = 1e9;\n\n // =============================== BRIDGING DATA ===============================\n\n /// @notice Struct with some data about a specific bridge token\n struct BridgeDetails {\n // Limit on the balance of bridge token held by the contract: it is designed\n // to reduce the exposure of the system to hacks\n uint256 limit;\n // Limit on the hourly volume of token minted through this bridge\n // Technically the limit over a rolling hour is hourlyLimit x2 as hourly limit\n // is enforced only between x:00 and x+1:00\n uint256 hourlyLimit;\n // Fee taken for swapping in and out the token\n uint64 fee;\n // Whether the associated token is allowed or not\n bool allowed;\n // Whether swapping in and out from the associated token is paused or not\n bool paused;\n }\n\n /// @notice Maps a bridge token to data\n mapping(address => BridgeDetails) public bridges;\n /// @notice List of all bridge tokens\n address[] public bridgeTokensList;\n /// @notice Maps a bridge token to the associated hourly volume\n mapping(address => mapping(uint256 => uint256)) public usage;\n /// @notice Maps an address to whether it is exempt of fees for when it comes to swapping in and out\n mapping(address => uint256) public isFeeExempt;\n /// @notice Limit to the amount of tokens that can be sent from that chain to another chain\n uint256 public chainTotalHourlyLimit;\n /// @notice Usage per hour on that chain. Maps an hourly timestamp to the total volume swapped out on the chain\n mapping(uint256 => uint256) public chainTotalUsage;\n\n // =================================== EVENTS ==================================\n\n event BridgeTokenAdded(address indexed bridgeToken, uint256 limit, uint256 hourlyLimit, uint64 fee, bool paused);\n event BridgeTokenToggled(address indexed bridgeToken, bool toggleStatus);\n event BridgeTokenRemoved(address indexed bridgeToken);\n event BridgeTokenFeeUpdated(address indexed bridgeToken, uint64 fee);\n event BridgeTokenLimitUpdated(address indexed bridgeToken, uint256 limit);\n event BridgeTokenHourlyLimitUpdated(address indexed bridgeToken, uint256 hourlyLimit);\n event HourlyLimitUpdated(uint256 hourlyLimit);\n event Recovered(address indexed token, address indexed to, uint256 amount);\n event FeeToggled(address indexed theAddress, uint256 toggleStatus);\n\n // =================================== ERRORS ==================================\n\n error AssetStillControlledInReserves();\n error HourlyLimitExceeded();\n error InvalidToken();\n error NotGovernor();\n error NotGovernorOrGuardian();\n error TooBigAmount();\n error TooHighParameterValue();\n error ZeroAddress();\n\n // ================================= MODIFIERS =================================\n\n /// @notice Checks whether the `msg.sender` has the governor role or not\n modifier onlyGovernor() {\n if (!ITreasury(treasury).isGovernor(msg.sender)) revert NotGovernor();\n _;\n }\n\n /// @notice Checks whether the `msg.sender` has the governor role or the guardian role\n modifier onlyGovernorOrGuardian() {\n if (!ITreasury(treasury).isGovernorOrGuardian(msg.sender)) revert NotGovernorOrGuardian();\n _;\n }\n\n // ===================== EXTERNAL PERMISSIONLESS FUNCTIONS =====================\n\n /// @notice Returns the list of all supported bridge tokens\n /// @dev Helpful for UIs\n function allBridgeTokens() external view returns (address[] memory) {\n return bridgeTokensList;\n }\n\n /// @notice Returns the current volume for a bridge, for the current hour\n /// @param bridgeToken Bridge used to mint\n /// @dev Helpful for UIs\n function currentUsage(address bridgeToken) external view returns (uint256) {\n return usage[bridgeToken][block.timestamp / 3600];\n }\n\n /// @notice Returns the current total volume on the chain for the current hour\n /// @dev Helpful for UIs\n function currentTotalUsage() external view returns (uint256) {\n return chainTotalUsage[block.timestamp / 3600];\n }\n\n /// @notice Mints the canonical token from a supported bridge token\n /// @param bridgeToken Bridge token to use to mint\n /// @param amount Amount of bridge tokens to send\n /// @param to Address to which the stablecoin should be sent\n /// @return Amount of the canonical stablecoin actually minted\n /// @dev Some fees may be taken by the protocol depending on the token used and on the address calling\n function swapIn(address bridgeToken, uint256 amount, address to) external returns (uint256) {\n BridgeDetails memory bridgeDetails = bridges[bridgeToken];\n if (!bridgeDetails.allowed || bridgeDetails.paused) revert InvalidToken();\n uint256 balance = IERC20(bridgeToken).balanceOf(address(this));\n if (balance + amount > bridgeDetails.limit) {\n // In case someone maliciously sends tokens to this contract\n // Or the limit changes\n if (bridgeDetails.limit > balance) amount = bridgeDetails.limit - balance;\n else {\n amount = 0;\n }\n }\n\n // Checking requirement on the hourly volume\n uint256 hour = block.timestamp / 3600;\n uint256 hourlyUsage = usage[bridgeToken][hour];\n if (hourlyUsage + amount > bridgeDetails.hourlyLimit) {\n // Edge case when the hourly limit changes\n amount = bridgeDetails.hourlyLimit > hourlyUsage ? bridgeDetails.hourlyLimit - hourlyUsage : 0;\n }\n usage[bridgeToken][hour] = hourlyUsage + amount;\n\n IERC20(bridgeToken).safeTransferFrom(msg.sender, address(this), amount);\n uint256 canonicalOut = amount;\n // Computing fees\n if (isFeeExempt[msg.sender] == 0) {\n canonicalOut -= (canonicalOut * bridgeDetails.fee) / BASE_PARAMS;\n }\n _mint(to, canonicalOut);\n return canonicalOut;\n }\n\n /// @notice Burns the canonical token in exchange for a bridge token\n /// @param bridgeToken Bridge token required\n /// @param amount Amount of canonical tokens to burn\n /// @param to Address to which the bridge token should be sent\n /// @return Amount of bridge tokens actually sent back\n /// @dev Some fees may be taken by the protocol depending on the token used and on the address calling\n function swapOut(address bridgeToken, uint256 amount, address to) external returns (uint256) {\n BridgeDetails memory bridgeDetails = bridges[bridgeToken];\n if (!bridgeDetails.allowed || bridgeDetails.paused) revert InvalidToken();\n\n uint256 hour = block.timestamp / 3600;\n uint256 hourlyUsage = chainTotalUsage[hour] + amount;\n // If the amount being swapped out exceeds the limit, we revert\n // We don't want to change the amount being swapped out.\n // The user can decide to send another tx with the correct amount to reach the limit\n if (hourlyUsage > chainTotalHourlyLimit) revert HourlyLimitExceeded();\n chainTotalUsage[hour] = hourlyUsage;\n\n _burn(msg.sender, amount);\n uint256 bridgeOut = amount;\n if (isFeeExempt[msg.sender] == 0) {\n bridgeOut -= (bridgeOut * bridgeDetails.fee) / BASE_PARAMS;\n }\n IERC20(bridgeToken).safeTransfer(to, bridgeOut);\n return bridgeOut;\n }\n\n // ============================ GOVERNANCE FUNCTIONS ===========================\n\n /// @notice Adds support for a bridge token\n /// @param bridgeToken Bridge token to add: it should be a version of the stablecoin from another bridge\n /// @param limit Limit on the balance of bridge token this contract could hold\n /// @param hourlyLimit Limit on the hourly volume for this bridge\n /// @param paused Whether swapping for this token should be paused or not\n /// @param fee Fee taken upon swapping for or against this token\n function addBridgeToken(\n address bridgeToken,\n uint256 limit,\n uint256 hourlyLimit,\n uint64 fee,\n bool paused\n ) external onlyGovernor {\n if (bridges[bridgeToken].allowed || bridgeToken == address(0)) revert InvalidToken();\n if (fee > BASE_PARAMS) revert TooHighParameterValue();\n BridgeDetails memory _bridge;\n _bridge.limit = limit;\n _bridge.hourlyLimit = hourlyLimit;\n _bridge.paused = paused;\n _bridge.fee = fee;\n _bridge.allowed = true;\n bridges[bridgeToken] = _bridge;\n bridgeTokensList.push(bridgeToken);\n emit BridgeTokenAdded(bridgeToken, limit, hourlyLimit, fee, paused);\n }\n\n /// @notice Removes support for a token\n /// @param bridgeToken Address of the bridge token to remove support for\n function removeBridgeToken(address bridgeToken) external onlyGovernor {\n if (IERC20(bridgeToken).balanceOf(address(this)) != 0) revert AssetStillControlledInReserves();\n delete bridges[bridgeToken];\n // Deletion from `bridgeTokensList` loop\n uint256 bridgeTokensListLength = bridgeTokensList.length;\n for (uint256 i; i < bridgeTokensListLength - 1; ++i) {\n if (bridgeTokensList[i] == bridgeToken) {\n // Replace the `bridgeToken` to remove with the last of the list\n bridgeTokensList[i] = bridgeTokensList[bridgeTokensListLength - 1];\n break;\n }\n }\n // Remove last element in array\n bridgeTokensList.pop();\n emit BridgeTokenRemoved(bridgeToken);\n }\n\n /// @notice Recovers any ERC20 token\n /// @dev Can be used to withdraw bridge tokens for them to be de-bridged on mainnet\n function recoverERC20(address tokenAddress, address to, uint256 amountToRecover) external onlyGovernor {\n IERC20(tokenAddress).safeTransfer(to, amountToRecover);\n emit Recovered(tokenAddress, to, amountToRecover);\n }\n\n /// @notice Updates the `limit` amount for `bridgeToken`\n function setLimit(address bridgeToken, uint256 limit) external onlyGovernorOrGuardian {\n if (!bridges[bridgeToken].allowed) revert InvalidToken();\n bridges[bridgeToken].limit = limit;\n emit BridgeTokenLimitUpdated(bridgeToken, limit);\n }\n\n /// @notice Updates the `hourlyLimit` amount for `bridgeToken`\n function setHourlyLimit(address bridgeToken, uint256 hourlyLimit) external onlyGovernorOrGuardian {\n if (!bridges[bridgeToken].allowed) revert InvalidToken();\n bridges[bridgeToken].hourlyLimit = hourlyLimit;\n emit BridgeTokenHourlyLimitUpdated(bridgeToken, hourlyLimit);\n }\n\n /// @notice Updates the `chainTotalHourlyLimit` amount\n function setChainTotalHourlyLimit(uint256 hourlyLimit) external onlyGovernorOrGuardian {\n chainTotalHourlyLimit = hourlyLimit;\n emit HourlyLimitUpdated(hourlyLimit);\n }\n\n /// @notice Updates the `fee` value for `bridgeToken`\n function setSwapFee(address bridgeToken, uint64 fee) external onlyGovernorOrGuardian {\n if (!bridges[bridgeToken].allowed) revert InvalidToken();\n if (fee > BASE_PARAMS) revert TooHighParameterValue();\n bridges[bridgeToken].fee = fee;\n emit BridgeTokenFeeUpdated(bridgeToken, fee);\n }\n\n /// @notice Pauses or unpauses swapping in and out for a token\n function toggleBridge(address bridgeToken) external onlyGovernorOrGuardian {\n if (!bridges[bridgeToken].allowed) revert InvalidToken();\n bool pausedStatus = bridges[bridgeToken].paused;\n bridges[bridgeToken].paused = !pausedStatus;\n emit BridgeTokenToggled(bridgeToken, !pausedStatus);\n }\n\n /// @notice Toggles fees for the address `theAddress`\n function toggleFeesForAddress(address theAddress) external onlyGovernorOrGuardian {\n uint256 feeExemptStatus = 1 - isFeeExempt[theAddress];\n isFeeExempt[theAddress] = feeExemptStatus;\n emit FeeToggled(theAddress, feeExemptStatus);\n }\n}\n" + }, + "contracts/agToken/layerZero/LayerZeroBridge.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.12;\n\nimport \"./utils/OFTCore.sol\";\nimport \"@openzeppelin/contracts-upgradeable/security/PausableUpgradeable.sol\";\nimport \"@openzeppelin/contracts/token/ERC20/extensions/draft-IERC20Permit.sol\";\n\n/// @title LayerZeroBridge\n/// @author Angle Labs, Inc., forked from https://github.com/LayerZero-Labs/solidity-examples/blob/main/contracts/token/oft/OFT.sol\n/// @notice Contract to be deployed on Ethereum for bridging an AgToken using a bridge intermediate token and LayerZero\ncontract LayerZeroBridge is OFTCore, PausableUpgradeable {\n /// @notice Name of the contract for indexing purposes\n string public name;\n\n /// @notice Address of the bridgeable token\n /// @dev Immutable\n IERC20 public canonicalToken;\n\n /// @notice Maps an address to the amount of token bridged but not received\n mapping(address => uint256) public balanceOf;\n\n // ================================ CONSTRUCTOR ================================\n /// @notice Initializes the contract\n /// @param _name Name of the token corresponding to this contract\n /// @param _lzEndpoint Layer zero endpoint to pass messages\n /// @param _treasury Address of the treasury contract used for access control\n function initialize(string memory _name, address _lzEndpoint, address _treasury) external initializer {\n __LzAppUpgradeable_init(_lzEndpoint, _treasury);\n name = _name;\n canonicalToken = IERC20(address(ITreasury(_treasury).stablecoin()));\n }\n\n /// @custom:oz-upgrades-unsafe-allow constructor\n constructor() initializer {}\n\n // ===================== EXTERNAL PERMISSIONLESS FUNCTIONS =====================\n\n /// @inheritdoc OFTCore\n function sendWithPermit(\n uint16 _dstChainId,\n bytes memory _toAddress,\n uint256 _amount,\n address payable _refundAddress,\n address _zroPaymentAddress,\n bytes memory _adapterParams,\n uint256 deadline,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) public payable override {\n IERC20Permit(address(canonicalToken)).permit(msg.sender, address(this), _amount, deadline, v, r, s);\n send(_dstChainId, _toAddress, _amount, _refundAddress, _zroPaymentAddress, _adapterParams);\n }\n\n /// @inheritdoc OFTCore\n function withdraw(uint256 amount, address recipient) external override returns (uint256) {\n return _withdraw(amount, msg.sender, recipient);\n }\n\n /// @notice Withdraws amount of `token` from the contract and sends it to the recipient\n /// @param amount Amount to withdraw\n /// @param recipient Address to withdraw for\n /// @return The amount of canonical token sent\n function withdrawFor(uint256 amount, address recipient) external returns (uint256) {\n return _withdraw(amount, recipient, recipient);\n }\n\n // ============================= INTERNAL FUNCTIONS ============================\n\n /// @notice Withdraws `amount` from the balance of the `from` address and sends these tokens to the `to` address\n /// @dev It's important to make sure that `from` is either the `msg.sender` or that `from` and `to` are the same\n /// addresses\n function _withdraw(uint256 amount, address from, address to) internal whenNotPaused returns (uint256) {\n balanceOf[from] -= amount; // Will overflow if the amount is too big\n canonicalToken.transfer(to, amount);\n return amount;\n }\n\n /// @inheritdoc OFTCore\n function _debitFrom(uint16, bytes memory, uint256 _amount) internal override whenNotPaused returns (uint256) {\n // No need to use safeTransferFrom as we know this implementation reverts on failure\n canonicalToken.transferFrom(msg.sender, address(this), _amount);\n return _amount;\n }\n\n /// @inheritdoc OFTCore\n function _debitCreditFrom(uint16, bytes memory, uint256 _amount) internal override whenNotPaused returns (uint256) {\n balanceOf[msg.sender] -= _amount;\n return _amount;\n }\n\n /// @inheritdoc OFTCore\n function _creditTo(uint16, address _toAddress, uint256 _amount) internal override whenNotPaused returns (uint256) {\n // Should never revert as all the LayerZero bridge tokens come from\n // this contract\n uint256 balance = canonicalToken.balanceOf(address(this));\n if (balance < _amount) {\n balanceOf[_toAddress] = _amount - balance;\n if (balance != 0) canonicalToken.transfer(_toAddress, balance);\n } else {\n canonicalToken.transfer(_toAddress, _amount);\n }\n return _amount;\n }\n\n // =============================== VIEW FUNCTIONS ==============================\n\n /// @inheritdoc ERC165Upgradeable\n function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {\n return interfaceId == type(IOFTCore).interfaceId || super.supportsInterface(interfaceId);\n }\n\n // ============================ GOVERNANCE FUNCTIONS ===========================\n\n /// @notice Pauses bridging through the contract\n /// @param pause Future pause status\n function pauseSendTokens(bool pause) external onlyGovernorOrGuardian {\n pause ? _pause() : _unpause();\n }\n\n /// @notice Decreases the balance of an address\n /// @param amount Amount to withdraw from balance\n /// @param recipient Address to withdraw from\n function sweep(uint256 amount, address recipient) external onlyGovernorOrGuardian {\n balanceOf[recipient] -= amount; // Will overflow if the amount is too big\n }\n\n uint256[47] private __gap;\n}\n" + }, + "contracts/agToken/layerZero/LayerZeroBridgeToken.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.12;\n\nimport \"./utils/OFTCore.sol\";\nimport \"../../interfaces/IAgTokenSideChainMultiBridge.sol\";\nimport \"@openzeppelin/contracts-upgradeable/security/PausableUpgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/token/ERC20/ERC20Upgradeable.sol\";\n\n/// @title LayerZeroBridgeToken\n/// @author Angle Labs, Inc., forked from https://github.com/LayerZero-Labs/solidity-examples/blob/main/contracts/token/oft/OFT.sol\n/// @notice Contract to be deployed on a L2/sidechain for bridging an AgToken using a bridge intermediate token and LayerZero\ncontract LayerZeroBridgeToken is OFTCore, ERC20Upgradeable, PausableUpgradeable {\n /// @notice Address of the bridgeable token\n /// @dev Immutable\n IAgTokenSideChainMultiBridge public canonicalToken;\n\n // =================================== ERROR ===================================\n\n error InvalidAllowance();\n\n // ================================ CONSTRUCTOR ================================\n\n /// @notice Initializes the contract\n /// @param _name Name of the token corresponding to this contract\n /// @param _symbol Symbol of the token corresponding to this contract\n /// @param _lzEndpoint Layer zero endpoint to pass messages\n /// @param _treasury Address of the treasury contract used for access control\n /// @param initialSupply Initial supply to mint to the canonical token address\n /// @dev The initial supply corresponds to the initial amount that could be bridged using this OFT\n function initialize(\n string memory _name,\n string memory _symbol,\n address _lzEndpoint,\n address _treasury,\n uint256 initialSupply\n ) external initializer {\n __ERC20_init_unchained(_name, _symbol);\n __LzAppUpgradeable_init(_lzEndpoint, _treasury);\n\n canonicalToken = IAgTokenSideChainMultiBridge(address(ITreasury(_treasury).stablecoin()));\n _approve(address(this), address(canonicalToken), type(uint256).max);\n _mint(address(canonicalToken), initialSupply);\n }\n\n /// @custom:oz-upgrades-unsafe-allow constructor\n constructor() initializer {}\n\n // ===================== EXTERNAL PERMISSIONLESS FUNCTIONS =====================\n\n /// @inheritdoc OFTCore\n function sendWithPermit(\n uint16 _dstChainId,\n bytes memory _toAddress,\n uint256 _amount,\n address payable _refundAddress,\n address _zroPaymentAddress,\n bytes memory _adapterParams,\n uint256 deadline,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) public payable override {\n canonicalToken.permit(msg.sender, address(this), _amount, deadline, v, r, s);\n send(_dstChainId, _toAddress, _amount, _refundAddress, _zroPaymentAddress, _adapterParams);\n }\n\n /// @inheritdoc OFTCore\n function withdraw(uint256 amount, address recipient) external override returns (uint256 amountMinted) {\n // Does not check allowances as transfers from `msg.sender`\n _transfer(msg.sender, address(this), amount);\n amountMinted = canonicalToken.swapIn(address(this), amount, recipient);\n uint256 leftover = balanceOf(address(this));\n if (leftover != 0) {\n _transfer(address(this), msg.sender, leftover);\n }\n }\n\n // ============================= INTERNAL FUNCTIONS ============================\n\n /// @inheritdoc OFTCore\n function _debitFrom(\n uint16,\n bytes memory,\n uint256 _amount\n ) internal override whenNotPaused returns (uint256 amountSwapped) {\n // No need to use safeTransferFrom as we know this implementation reverts on failure\n canonicalToken.transferFrom(msg.sender, address(this), _amount);\n\n // Swap canonical for this bridge token. There may be some fees\n amountSwapped = canonicalToken.swapOut(address(this), _amount, address(this));\n _burn(address(this), amountSwapped);\n }\n\n /// @inheritdoc OFTCore\n function _debitCreditFrom(uint16, bytes memory, uint256 _amount) internal override whenNotPaused returns (uint256) {\n _burn(msg.sender, _amount);\n return _amount;\n }\n\n /// @inheritdoc OFTCore\n function _creditTo(\n uint16,\n address _toAddress,\n uint256 _amount\n ) internal override whenNotPaused returns (uint256 amountMinted) {\n _mint(address(this), _amount);\n amountMinted = canonicalToken.swapIn(address(this), _amount, _toAddress);\n uint256 leftover = balanceOf(address(this));\n if (leftover != 0) {\n _transfer(address(this), _toAddress, leftover);\n }\n }\n\n // =============================== VIEW FUNCTIONS ==============================\n\n /// @inheritdoc ERC165Upgradeable\n function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {\n return\n interfaceId == type(IOFT).interfaceId ||\n interfaceId == type(IERC20).interfaceId ||\n super.supportsInterface(interfaceId);\n }\n\n // ============================ GOVERNANCE FUNCTIONS ===========================\n\n /// @notice Mints the intermediate contract to the `canonicalToken`\n /// @dev Used to increase the bridging capacity\n function mint(uint256 amount) external onlyGovernorOrGuardian {\n _mint(address(canonicalToken), amount);\n }\n\n /// @notice Burns the intermediate contract from the `canonicalToken`\n /// @dev Used to decrease the bridging capacity\n function burn(uint256 amount) external onlyGovernorOrGuardian {\n _burn(address(canonicalToken), amount);\n }\n\n /// @notice Increases allowance of the `canonicalToken`\n function setupAllowance() public onlyGovernorOrGuardian {\n _approve(address(this), address(canonicalToken), type(uint256).max);\n }\n\n /// @notice Pauses bridging through the contract\n /// @param pause Future pause status\n function pauseSendTokens(bool pause) external onlyGovernorOrGuardian {\n pause ? _pause() : _unpause();\n }\n\n uint256[49] private __gap;\n}\n" + }, + "contracts/agToken/layerZero/utils/IOFTCore.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.12;\n\nimport \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\nimport \"@openzeppelin/contracts/utils/introspection/IERC165.sol\";\n\n/**\n * @dev Interface of the IOFT core standard\n * @dev Forked from https://github.com/LayerZero-Labs/solidity-examples/blob/main/contracts/token/oft/IOFTCore.sol\n */\ninterface IOFTCore is IERC165 {\n /// @notice Estimates send token `_tokenId` to (`_dstChainId`, `_toAddress`)\n /// @param _dstChainId L0 defined chain id to send tokens too\n /// @param _toAddress dynamic bytes array which contains the address to whom you are sending tokens to on the dstChain\n /// @param _amount amount of the tokens to transfer\n /// @param _useZro indicates to use zro to pay L0 fees\n /// @param _adapterParams flexible bytes array to indicate messaging adapter services in L0\n function estimateSendFee(\n uint16 _dstChainId,\n bytes calldata _toAddress,\n uint256 _amount,\n bool _useZro,\n bytes calldata _adapterParams\n ) external view returns (uint256 nativeFee, uint256 zroFee);\n\n /// @notice Sends `_amount` amount of token to (`_dstChainId`, `_toAddress`)\n /// @param _dstChainId the destination chain identifier\n /// @param _toAddress can be any size depending on the `dstChainId`.\n /// @param _amount the quantity of tokens in wei\n /// @param _refundAddress the address LayerZero refunds if too much message fee is sent\n /// @param _zroPaymentAddress set to address(0x0) if not paying in ZRO (LayerZero Token)\n /// @param _adapterParams is a flexible bytes array to indicate messaging adapter services\n function send(\n uint16 _dstChainId,\n bytes calldata _toAddress,\n uint256 _amount,\n address payable _refundAddress,\n address _zroPaymentAddress,\n bytes calldata _adapterParams\n ) external payable;\n\n /// @notice Sends `_amount` amount of credit to (`_dstChainId`, `_toAddress`)\n /// @param _dstChainId the destination chain identifier\n /// @param _toAddress can be any size depending on the `dstChainId`.\n /// @param _amount the quantity of credit to send in wei\n /// @param _refundAddress the address LayerZero refunds if too much message fee is sent\n /// @param _zroPaymentAddress set to address(0x0) if not paying in ZRO (LayerZero Token)\n /// @param _adapterParams is a flexible bytes array to indicate messaging adapter services\n function sendCredit(\n uint16 _dstChainId,\n bytes calldata _toAddress,\n uint256 _amount,\n address payable _refundAddress,\n address _zroPaymentAddress,\n bytes calldata _adapterParams\n ) external payable;\n\n /// @notice Sends `_amount` amount of token to (`_dstChainId`, `_toAddress`)\n /// @param _dstChainId The destination chain identifier\n /// @param _toAddress Can be any size depending on the `dstChainId`.\n /// @param _amount Quantity of tokens in wei\n /// @param _refundAddress Address LayerZero refunds if too much message fee is sent\n /// @param _zroPaymentAddress Set to address(0x0) if not paying in ZRO (LayerZero Token)\n /// @param _adapterParams Flexible bytes array to indicate messaging adapter services\n /// @param deadline Deadline parameter for the signature to be valid\n /// @dev The `v`, `r`, and `s` parameters are used as signature data\n function sendWithPermit(\n uint16 _dstChainId,\n bytes memory _toAddress,\n uint256 _amount,\n address payable _refundAddress,\n address _zroPaymentAddress,\n bytes memory _adapterParams,\n uint256 deadline,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) external payable;\n\n /// @notice Withdraws amount of canonical token from the `msg.sender` balance and sends it to the recipient\n /// @param amount Amount to withdraw\n /// @param recipient Address to send the canonical token to\n /// @return The amount of canonical token sent\n function withdraw(uint256 amount, address recipient) external returns (uint256);\n\n /// @dev Emitted when `_amount` tokens are moved from the `_sender` to (`_dstChainId`, `_toAddress`)\n /// `_nonce` is the outbound nonce\n event SendToChain(\n address indexed _sender,\n uint16 indexed _dstChainId,\n bytes indexed _toAddress,\n uint256 _amount,\n uint64 _nonce\n );\n\n /// @dev Emitted when `_amount` tokens are received from `_srcChainId` into the `_toAddress` on the local chain.\n /// `_nonce` is the inbound nonce.\n event ReceiveFromChain(\n uint16 indexed _srcChainId,\n bytes indexed _srcAddress,\n address indexed _toAddress,\n uint256 _amount,\n uint64 _nonce\n );\n}\n\n/// @dev Interface of the OFT standard\ninterface IOFT is IOFTCore, IERC20 {\n\n}\n" + }, + "contracts/agToken/layerZero/utils/NonblockingLzApp.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.12;\n\nimport \"@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol\";\nimport \"../../../interfaces/external/layerZero/ILayerZeroReceiver.sol\";\nimport \"../../../interfaces/external/layerZero/ILayerZeroUserApplicationConfig.sol\";\nimport \"../../../interfaces/external/layerZero/ILayerZeroEndpoint.sol\";\nimport \"../../../interfaces/ITreasury.sol\";\n\n/// @title NonblockingLzApp\n/// @author Angle Labs, Inc., forked from https://github.com/LayerZero-Labs/solidity-examples/\n/// @notice Base contract for bridging using LayerZero\nabstract contract NonblockingLzApp is Initializable, ILayerZeroReceiver, ILayerZeroUserApplicationConfig {\n /// @notice Layer Zero endpoint\n ILayerZeroEndpoint public lzEndpoint;\n\n /// @notice Maps chainIds to failed messages to retry them\n mapping(uint16 => mapping(bytes => mapping(uint64 => bytes32))) public failedMessages;\n\n /// @notice Maps chainIds to their OFT address\n mapping(uint16 => bytes) public trustedRemoteLookup;\n\n /// @notice Reference to the treasury contract to fetch access control\n address public treasury;\n\n /// @notice Maps pairs of (`to` chain, `packetType`) to the minimum amount of gas needed on the destination chain\n mapping(uint16 => mapping(uint16 => uint256)) public minDstGasLookup;\n\n /// @notice For future LayerZero compatibility\n address public precrime;\n\n // ================================== Events ===================================\n\n event SetTrustedRemote(uint16 _srcChainId, bytes _srcAddress);\n event MessageFailed(uint16 _srcChainId, bytes _srcAddress, uint64 _nonce, bytes _payload);\n\n // =============================== Errors ================================\n\n error NotGovernor();\n error NotGovernorOrGuardian();\n error InsufficientGas();\n error InvalidEndpoint();\n error InvalidSource();\n error InvalidCaller();\n error InvalidParams();\n error InvalidPayload();\n error ZeroAddress();\n\n // ============================= Constructor ===================================\n\n //solhint-disable-next-line\n function __LzAppUpgradeable_init(address _endpoint, address _treasury) internal {\n if (_endpoint == address(0) || _treasury == address(0)) revert ZeroAddress();\n lzEndpoint = ILayerZeroEndpoint(_endpoint);\n treasury = _treasury;\n }\n\n // =============================== Modifiers ===================================\n\n /// @notice Checks whether the `msg.sender` has the governor role or the guardian role\n modifier onlyGovernorOrGuardian() {\n if (!ITreasury(treasury).isGovernorOrGuardian(msg.sender)) revert NotGovernorOrGuardian();\n _;\n }\n\n // ==================== External Permissionless Functions ======================\n\n /// @notice Receives a message from the LZ endpoint and process it\n /// @param _srcChainId ChainId of the source chain - LayerZero standard\n /// @param _srcAddress Sender of the source chain\n /// @param _nonce Nounce of the message\n /// @param _payload Data: recipient address and amount\n function lzReceive(\n uint16 _srcChainId,\n bytes memory _srcAddress,\n uint64 _nonce,\n bytes memory _payload\n ) public virtual override {\n // lzReceive must be called by the endpoint for security\n if (msg.sender != address(lzEndpoint)) revert InvalidEndpoint();\n\n bytes memory trustedRemote = trustedRemoteLookup[_srcChainId];\n // if will still block the message pathway from (srcChainId, srcAddress). should not receive message from untrusted remote.\n if (_srcAddress.length != trustedRemote.length || keccak256(_srcAddress) != keccak256(trustedRemote))\n revert InvalidSource();\n\n _blockingLzReceive(_srcChainId, _srcAddress, _nonce, _payload);\n }\n\n /// @notice Retries a message that previously failed and was stored\n /// @param _srcChainId ChainId of the source chain - LayerZero standard\n /// @param _srcAddress Sender of the source chain\n /// @param _nonce Nounce of the message\n /// @param _payload Data: recipient address and amount\n function retryMessage(\n uint16 _srcChainId,\n bytes memory _srcAddress,\n uint64 _nonce,\n bytes memory _payload\n ) public payable virtual {\n // assert there is message to retry\n bytes32 payloadHash = failedMessages[_srcChainId][_srcAddress][_nonce];\n if (payloadHash == bytes32(0) || keccak256(_payload) != payloadHash) revert InvalidPayload();\n // clear the stored message\n failedMessages[_srcChainId][_srcAddress][_nonce] = bytes32(0);\n // execute the message. revert if it fails again\n _nonblockingLzReceive(_srcChainId, _srcAddress, _nonce, _payload);\n }\n\n // ============================= Internal Functions ===================================\n\n /// @notice Handles message receptions in a non blocking way\n /// @param _srcChainId ChainId of the source chain - LayerZero standard\n /// @param _srcAddress Sender of the source chain\n /// @param _nonce Nounce of the message\n /// @param _payload Data: recipient address and amount\n /// @dev public for the needs of try / catch but effectively internal\n function nonblockingLzReceive(\n uint16 _srcChainId,\n bytes memory _srcAddress,\n uint64 _nonce,\n bytes memory _payload\n ) public virtual {\n // only internal transaction\n if (msg.sender != address(this)) revert InvalidCaller();\n _nonblockingLzReceive(_srcChainId, _srcAddress, _nonce, _payload);\n }\n\n /// @notice Handles message receptions in a non blocking way\n /// @param _srcChainId ChainId of the source chain - LayerZero standard\n /// @param _srcAddress Sender of the source chain\n /// @param _nonce Nounce of the message\n /// @param _payload Data: recipient address and amount\n function _nonblockingLzReceive(\n uint16 _srcChainId,\n bytes memory _srcAddress,\n uint64 _nonce,\n bytes memory _payload\n ) internal virtual;\n\n /// @notice Handles message receptions in a blocking way\n /// @param _srcChainId ChainId of the source chain - LayerZero standard\n /// @param _srcAddress Sender of the source chain\n /// @param _nonce Nounce of the message\n /// @param _payload Data: recipient address and amount\n function _blockingLzReceive(\n uint16 _srcChainId,\n bytes memory _srcAddress,\n uint64 _nonce,\n bytes memory _payload\n ) internal {\n // try-catch all errors/exceptions\n try this.nonblockingLzReceive(_srcChainId, _srcAddress, _nonce, _payload) {\n // do nothing\n } catch {\n // error / exception\n failedMessages[_srcChainId][_srcAddress][_nonce] = keccak256(_payload);\n emit MessageFailed(_srcChainId, _srcAddress, _nonce, _payload);\n }\n }\n\n /// @notice Sends a message to the LZ endpoint and process it\n /// @param _dstChainId L0 defined chain id to send tokens too\n /// @param _payload Data: recipient address and amount\n /// @param _refundAddress Address LayerZero refunds if too much message fee is sent\n /// @param _zroPaymentAddress Set to address(0x0) if not paying in ZRO (LayerZero Token)\n /// @param _adapterParams Flexible bytes array to indicate messaging adapter services in L0\n function _lzSend(\n uint16 _dstChainId,\n bytes memory _payload,\n address payable _refundAddress,\n address _zroPaymentAddress,\n bytes memory _adapterParams\n ) internal virtual {\n bytes memory trustedRemote = trustedRemoteLookup[_dstChainId];\n if (trustedRemote.length == 0) revert InvalidSource();\n //solhint-disable-next-line\n lzEndpoint.send{ value: msg.value }(\n _dstChainId,\n trustedRemote,\n _payload,\n _refundAddress,\n _zroPaymentAddress,\n _adapterParams\n );\n }\n\n /// @notice Checks the gas limit of a given transaction\n function _checkGasLimit(\n uint16 _dstChainId,\n uint16 _type,\n bytes memory _adapterParams,\n uint256 _extraGas\n ) internal view virtual {\n uint256 minGasLimit = minDstGasLookup[_dstChainId][_type] + _extraGas;\n if (minGasLimit == 0 || minGasLimit > _getGasLimit(_adapterParams)) revert InsufficientGas();\n }\n\n /// @notice Gets the gas limit from the `_adapterParams` parameter\n function _getGasLimit(bytes memory _adapterParams) internal pure virtual returns (uint256 gasLimit) {\n if (_adapterParams.length < 34) revert InvalidParams();\n // solhint-disable-next-line\n assembly {\n gasLimit := mload(add(_adapterParams, 34))\n }\n }\n\n // ======================= Governance Functions ================================\n\n /// @notice Sets the corresponding address on an other chain.\n /// @param _srcChainId ChainId of the source chain - LayerZero standard\n /// @param _srcAddress Address on the source chain\n /// @dev Used for both receiving and sending message\n /// @dev There can only be one trusted source per chain\n /// @dev Allows owner to set it multiple times.\n function setTrustedRemote(uint16 _srcChainId, bytes calldata _srcAddress) external onlyGovernorOrGuardian {\n trustedRemoteLookup[_srcChainId] = _srcAddress;\n emit SetTrustedRemote(_srcChainId, _srcAddress);\n }\n\n /// @notice Fetches the default LZ config\n function getConfig(\n uint16 _version,\n uint16 _chainId,\n address,\n uint256 _configType\n ) external view returns (bytes memory) {\n return lzEndpoint.getConfig(_version, _chainId, address(this), _configType);\n }\n\n /// @notice Overrides the default LZ config\n function setConfig(\n uint16 _version,\n uint16 _chainId,\n uint256 _configType,\n bytes calldata _config\n ) external override onlyGovernorOrGuardian {\n lzEndpoint.setConfig(_version, _chainId, _configType, _config);\n }\n\n /// @notice Overrides the default LZ config\n function setSendVersion(uint16 _version) external override onlyGovernorOrGuardian {\n lzEndpoint.setSendVersion(_version);\n }\n\n /// @notice Overrides the default LZ config\n function setReceiveVersion(uint16 _version) external override onlyGovernorOrGuardian {\n lzEndpoint.setReceiveVersion(_version);\n }\n\n /// @notice Unpauses the receive functionalities\n function forceResumeReceive(\n uint16 _srcChainId,\n bytes calldata _srcAddress\n ) external override onlyGovernorOrGuardian {\n lzEndpoint.forceResumeReceive(_srcChainId, _srcAddress);\n }\n\n /// @notice Sets the minimum gas parameter for a packet type on a given chain\n function setMinDstGas(uint16 _dstChainId, uint16 _packetType, uint256 _minGas) external onlyGovernorOrGuardian {\n if (_minGas == 0) revert InvalidParams();\n minDstGasLookup[_dstChainId][_packetType] = _minGas;\n }\n\n /// @notice Sets the precrime variable\n function setPrecrime(address _precrime) external onlyGovernorOrGuardian {\n precrime = _precrime;\n }\n\n // ======================= View Functions ================================\n\n /// @notice Checks if the `_srcAddress` corresponds to the trusted source\n function isTrustedRemote(uint16 _srcChainId, bytes calldata _srcAddress) external view returns (bool) {\n bytes memory trustedSource = trustedRemoteLookup[_srcChainId];\n return keccak256(trustedSource) == keccak256(_srcAddress);\n }\n\n uint256[44] private __gap;\n}\n" + }, + "contracts/agToken/layerZero/utils/OFTCore.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.12;\n\nimport \"./NonblockingLzApp.sol\";\nimport \"./IOFTCore.sol\";\nimport \"@openzeppelin/contracts-upgradeable/utils/introspection/ERC165Upgradeable.sol\";\n\n/// @title OFTCore\n/// @author Forked from https://github.com/LayerZero-Labs/solidity-examples/blob/main/contracts/token/oft/OFTCore.sol\n/// but with slight modifications from the Angle Labs, Inc. which added return values to the `_creditTo` and `_debitFrom` functions\n/// @notice Base contract for bridging using LayerZero\nabstract contract OFTCore is NonblockingLzApp, ERC165Upgradeable, IOFTCore {\n /// @notice Amount of additional gas specified\n uint256 public constant EXTRA_GAS = 200000;\n /// @notice Packet type for token transfer\n uint16 public constant PT_SEND = 0;\n\n /// @notice Whether to use custom parameters in transactions\n uint8 public useCustomAdapterParams;\n\n // ==================== External Permissionless Functions ======================\n\n /// @inheritdoc IOFTCore\n function sendWithPermit(\n uint16 _dstChainId,\n bytes memory _toAddress,\n uint256 _amount,\n address payable _refundAddress,\n address _zroPaymentAddress,\n bytes memory _adapterParams,\n uint256 deadline,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) public payable virtual;\n\n /// @inheritdoc IOFTCore\n function send(\n uint16 _dstChainId,\n bytes memory _toAddress,\n uint256 _amount,\n address payable _refundAddress,\n address _zroPaymentAddress,\n bytes memory _adapterParams\n ) public payable virtual {\n _checkAdapterParams(_dstChainId, PT_SEND, _adapterParams, EXTRA_GAS);\n _amount = _debitFrom(_dstChainId, _toAddress, _amount);\n\n bytes memory payload = abi.encode(_toAddress, _amount);\n _lzSend(_dstChainId, payload, _refundAddress, _zroPaymentAddress, _adapterParams);\n\n uint64 nonce = lzEndpoint.getOutboundNonce(_dstChainId, address(this));\n emit SendToChain(msg.sender, _dstChainId, _toAddress, _amount, nonce);\n }\n\n /// @inheritdoc IOFTCore\n function sendCredit(\n uint16 _dstChainId,\n bytes memory _toAddress,\n uint256 _amount,\n address payable _refundAddress,\n address _zroPaymentAddress,\n bytes memory _adapterParams\n ) public payable virtual {\n _checkAdapterParams(_dstChainId, PT_SEND, _adapterParams, EXTRA_GAS);\n _amount = _debitCreditFrom(_dstChainId, _toAddress, _amount);\n\n _send(_dstChainId, _toAddress, _amount, _refundAddress, _zroPaymentAddress, _adapterParams);\n }\n\n /// @inheritdoc IOFTCore\n function withdraw(uint256 amount, address recipient) external virtual returns (uint256);\n\n /// @notice Sets whether custom adapter parameters can be used or not\n function setUseCustomAdapterParams(uint8 _useCustomAdapterParams) public virtual onlyGovernorOrGuardian {\n useCustomAdapterParams = _useCustomAdapterParams;\n }\n\n // =========================== Internal Functions ==============================\n\n /// @notice Internal function to send `_amount` amount of token to (`_dstChainId`, `_toAddress`)\n /// @param _dstChainId the destination chain identifier\n /// @param _toAddress can be any size depending on the `dstChainId`.\n /// @param _amount the quantity of tokens in wei\n /// @param _refundAddress the address LayerZero refunds if too much message fee is sent\n /// @param _zroPaymentAddress set to address(0x0) if not paying in ZRO (LayerZero Token)\n /// @param _adapterParams is a flexible bytes array to indicate messaging adapter services\n /// @dev Accounting and checks should be performed beforehand\n function _send(\n uint16 _dstChainId,\n bytes memory _toAddress,\n uint256 _amount,\n address payable _refundAddress,\n address _zroPaymentAddress,\n bytes memory _adapterParams\n ) internal {\n bytes memory payload = abi.encode(_toAddress, _amount);\n _lzSend(_dstChainId, payload, _refundAddress, _zroPaymentAddress, _adapterParams);\n\n uint64 nonce = lzEndpoint.getOutboundNonce(_dstChainId, address(this));\n emit SendToChain(msg.sender, _dstChainId, _toAddress, _amount, nonce);\n }\n\n /// @inheritdoc NonblockingLzApp\n function _nonblockingLzReceive(\n uint16 _srcChainId,\n bytes memory _srcAddress,\n uint64 _nonce,\n bytes memory _payload\n ) internal virtual override {\n // decode and load the toAddress\n (bytes memory toAddressBytes, uint256 amount) = abi.decode(_payload, (bytes, uint256));\n address toAddress;\n //solhint-disable-next-line\n assembly {\n toAddress := mload(add(toAddressBytes, 20))\n }\n amount = _creditTo(_srcChainId, toAddress, amount);\n\n emit ReceiveFromChain(_srcChainId, _srcAddress, toAddress, amount, _nonce);\n }\n\n /// @notice Checks the adapter parameters given during the smart contract call\n function _checkAdapterParams(\n uint16 _dstChainId,\n uint16 _pkType,\n bytes memory _adapterParams,\n uint256 _extraGas\n ) internal virtual {\n if (useCustomAdapterParams > 0) _checkGasLimit(_dstChainId, _pkType, _adapterParams, _extraGas);\n else if (_adapterParams.length != 0) revert InvalidParams();\n }\n\n /// @notice Makes accountability when bridging from this contract using canonical token\n /// @param _dstChainId ChainId of the destination chain - LayerZero standard\n /// @param _toAddress Recipient on the destination chain\n /// @param _amount Amount to bridge\n function _debitFrom(\n uint16 _dstChainId,\n bytes memory _toAddress,\n uint256 _amount\n ) internal virtual returns (uint256);\n\n /// @notice Makes accountability when bridging from this contract's credit\n /// @param _dstChainId ChainId of the destination chain - LayerZero standard\n /// @param _toAddress Recipient on the destination chain\n /// @param _amount Amount to bridge\n function _debitCreditFrom(\n uint16 _dstChainId,\n bytes memory _toAddress,\n uint256 _amount\n ) internal virtual returns (uint256);\n\n /// @notice Makes accountability when bridging to this contract\n /// @param _srcChainId ChainId of the source chain - LayerZero standard\n /// @param _toAddress Recipient on this chain\n /// @param _amount Amount to bridge\n function _creditTo(uint16 _srcChainId, address _toAddress, uint256 _amount) internal virtual returns (uint256);\n\n // ========================== View Functions ===================================\n\n /// @inheritdoc ERC165Upgradeable\n function supportsInterface(\n bytes4 interfaceId\n ) public view virtual override(ERC165Upgradeable, IERC165) returns (bool) {\n return interfaceId == type(IOFTCore).interfaceId || super.supportsInterface(interfaceId);\n }\n\n /// @inheritdoc IOFTCore\n function estimateSendFee(\n uint16 _dstChainId,\n bytes memory _toAddress,\n uint256 _amount,\n bool _useZro,\n bytes memory _adapterParams\n ) public view virtual override returns (uint256 nativeFee, uint256 zroFee) {\n // mock the payload for send()\n bytes memory payload = abi.encode(_toAddress, _amount);\n return lzEndpoint.estimateFees(_dstChainId, address(this), payload, _useZro, _adapterParams);\n }\n\n uint256[49] private __gap;\n}\n" + }, + "contracts/agToken/polygon/TokenPolygonUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.12;\n\nimport \"./utils/ERC20UpgradeableCustom.sol\";\nimport \"@openzeppelin/contracts-upgradeable/access/AccessControlUpgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/utils/cryptography/draft-EIP712Upgradeable.sol\";\nimport \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\nimport \"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\";\n\nimport \"../../interfaces/IAgToken.sol\";\nimport \"../../interfaces/ITreasury.sol\";\n\ninterface IChildToken {\n function deposit(address user, bytes calldata depositData) external;\n\n function withdraw(uint256 amount) external;\n}\n\ncontract TokenPolygonUpgradeable is\n Initializable,\n ERC20UpgradeableCustom,\n AccessControlUpgradeable,\n EIP712Upgradeable,\n IChildToken\n{\n bytes32 public constant DEPOSITOR_ROLE = keccak256(\"DEPOSITOR_ROLE\");\n\n /// @dev Emitted when the child chain manager changes\n event ChildChainManagerAdded(address newAddress);\n event ChildChainManagerRevoked(address oldAddress);\n\n constructor() initializer {}\n\n function initialize(\n string memory _name,\n string memory _symbol,\n address childChainManager,\n address guardian\n ) public initializer {\n __ERC20_init(_name, _symbol);\n __AccessControl_init();\n _setupRole(DEFAULT_ADMIN_ROLE, guardian);\n _setupRole(DEPOSITOR_ROLE, childChainManager);\n __EIP712_init(_name, \"1\");\n }\n\n /**\n * @notice Called when the bridge has tokens to mint\n * @param user Address to mint the token to\n * @param depositData Encoded amount to mint\n */\n function deposit(address user, bytes calldata depositData) external override {\n require(hasRole(DEPOSITOR_ROLE, msg.sender));\n uint256 amount = abi.decode(depositData, (uint256));\n _mint(user, amount);\n }\n\n /**\n * @notice Called when user wants to withdraw tokens back to root chain\n * @dev Should burn user's tokens. This transaction will be verified when exiting on root chain\n * @param amount Amount of tokens to withdraw\n */\n function withdraw(uint256 amount) external override {\n _burn(_msgSender(), amount);\n }\n\n // =============================================================================\n // ======================= New data added for the upgrade ======================\n // =============================================================================\n\n mapping(address => bool) public isMinter;\n /// @notice Reference to the treasury contract which can grant minting rights\n address public treasury;\n /// @notice Boolean to check whether the contract has been reinitialized after its upgrade\n bool public treasuryInitialized;\n\n using SafeERC20 for IERC20;\n\n /// @notice Base used for fee computation\n uint256 public constant BASE_PARAMS = 10 ** 9;\n\n // =============================== Bridging Data ===============================\n\n /// @notice Struct with some data about a specific bridge token\n struct BridgeDetails {\n // Limit on the balance of bridge token held by the contract: it is designed\n // to reduce the exposure of the system to hacks\n uint256 limit;\n // Limit on the hourly volume of token minted through this bridge\n // Technically the limit over a rolling hour is hourlyLimit x2 as hourly limit\n // is enforced only between x:00 and x+1:00\n uint256 hourlyLimit;\n // Fee taken for swapping in and out the token\n uint64 fee;\n // Whether the associated token is allowed or not\n bool allowed;\n // Whether swapping in and out from the associated token is paused or not\n bool paused;\n }\n\n /// @notice Maps a bridge token to data\n mapping(address => BridgeDetails) public bridges;\n /// @notice List of all bridge tokens\n address[] public bridgeTokensList;\n /// @notice Maps a bridge token to the associated hourly volume\n mapping(address => mapping(uint256 => uint256)) public usage;\n /// @notice Maps an address to whether it is exempt of fees for when it comes to swapping in and out\n mapping(address => uint256) public isFeeExempt;\n /// @notice Limit to the amount of tokens that can be sent from that chain to another chain\n uint256 public chainTotalHourlyLimit;\n /// @notice Usage per hour on that chain. Maps an hourly timestamp to the total volume swapped out on the chain\n mapping(uint256 => uint256) public chainTotalUsage;\n\n uint256[42] private __gap;\n\n // ================================== Events ===================================\n\n event BridgeTokenAdded(address indexed bridgeToken, uint256 limit, uint256 hourlyLimit, uint64 fee, bool paused);\n event BridgeTokenToggled(address indexed bridgeToken, bool toggleStatus);\n event BridgeTokenRemoved(address indexed bridgeToken);\n event BridgeTokenFeeUpdated(address indexed bridgeToken, uint64 fee);\n event BridgeTokenLimitUpdated(address indexed bridgeToken, uint256 limit);\n event BridgeTokenHourlyLimitUpdated(address indexed bridgeToken, uint256 hourlyLimit);\n event HourlyLimitUpdated(uint256 hourlyLimit);\n event FeeToggled(address indexed theAddress, uint256 toggleStatus);\n event KeeperToggled(address indexed keeper, bool toggleStatus);\n event MinterToggled(address indexed minter);\n event Recovered(address indexed token, address indexed to, uint256 amount);\n event TreasuryUpdated(address indexed _treasury);\n\n // ================================== Errors ===================================\n\n error AssetStillControlledInReserves();\n error BurnAmountExceedsAllowance();\n error HourlyLimitExceeded();\n error InvalidSender();\n error InvalidToken();\n error InvalidTreasury();\n error NotGovernor();\n error NotGovernorOrGuardian();\n error NotMinter();\n error NotTreasury();\n error TooBigAmount();\n error TooHighParameterValue();\n error TreasuryAlreadyInitialized();\n error ZeroAddress();\n\n /// @notice Checks to see if it is the `Treasury` calling this contract\n /// @dev There is no Access Control here, because it can be handled cheaply through this modifier\n modifier onlyTreasury() {\n if (msg.sender != treasury) revert NotTreasury();\n _;\n }\n\n /// @notice Checks whether the sender has the minting right\n modifier onlyMinter() {\n if (!isMinter[msg.sender]) revert NotMinter();\n _;\n }\n\n /// @notice Checks whether the `msg.sender` has the governor role or not\n modifier onlyGovernor() {\n if (!ITreasury(treasury).isGovernor(msg.sender)) revert NotGovernor();\n _;\n }\n\n /// @notice Checks whether the `msg.sender` has the governor role or the guardian role\n modifier onlyGovernorOrGuardian() {\n if (!ITreasury(treasury).isGovernorOrGuardian(msg.sender)) revert NotGovernorOrGuardian();\n _;\n }\n\n /// @notice Sets up the treasury contract on Polygon after the upgrade\n /// @param _treasury Address of the treasury contract\n function setUpTreasury(address _treasury) external {\n // Only governor on Polygon\n if (msg.sender != 0xdA2D2f638D6fcbE306236583845e5822554c02EA) revert NotGovernor();\n if (address(ITreasury(_treasury).stablecoin()) != address(this)) revert InvalidTreasury();\n if (treasuryInitialized) revert TreasuryAlreadyInitialized();\n treasury = _treasury;\n treasuryInitialized = true;\n emit TreasuryUpdated(_treasury);\n }\n\n // =========================== External Function ===============================\n\n /// @notice Allows anyone to burn agToken without redeeming collateral back\n /// @param amount Amount of stablecoins to burn\n /// @dev This function can typically be called if there is a settlement mechanism to burn stablecoins\n function burnStablecoin(uint256 amount) external {\n _burnCustom(msg.sender, amount);\n }\n\n // ======================= Minter Role Only Functions ==========================\n\n function burnSelf(uint256 amount, address burner) external onlyMinter {\n _burnCustom(burner, amount);\n }\n\n function burnFrom(uint256 amount, address burner, address sender) external onlyMinter {\n _burnFromNoRedeem(amount, burner, sender);\n }\n\n function mint(address account, uint256 amount) external onlyMinter {\n _mint(account, amount);\n }\n\n // ======================= Treasury Only Functions =============================\n\n function addMinter(address minter) external onlyTreasury {\n isMinter[minter] = true;\n emit MinterToggled(minter);\n }\n\n function removeMinter(address minter) external {\n if (msg.sender != address(treasury) && msg.sender != minter) revert InvalidSender();\n isMinter[minter] = false;\n emit MinterToggled(minter);\n }\n\n function setTreasury(address _treasury) external onlyTreasury {\n treasury = _treasury;\n emit TreasuryUpdated(_treasury);\n }\n\n // ============================ Internal Function ==============================\n\n /// @notice Internal version of the function `burnFromNoRedeem`\n /// @param amount Amount to burn\n /// @dev It is at the level of this function that allowance checks are performed\n function _burnFromNoRedeem(uint256 amount, address burner, address sender) internal {\n if (burner != sender) {\n uint256 currentAllowance = allowance(burner, sender);\n if (currentAllowance < amount) revert BurnAmountExceedsAllowance();\n _approve(burner, sender, currentAllowance - amount);\n }\n _burnCustom(burner, amount);\n }\n\n // ==================== External Permissionless Functions ======================\n\n /// @notice Returns the list of all supported bridge tokens\n /// @dev Helpful for UIs\n function allBridgeTokens() external view returns (address[] memory) {\n return bridgeTokensList;\n }\n\n /// @notice Returns the current volume for a bridge, for the current hour\n /// @dev Helpful for UIs\n function currentUsage(address bridge) external view returns (uint256) {\n return usage[bridge][block.timestamp / 3600];\n }\n\n /// @notice Returns the current total volume on the chain for the current hour\n /// @dev Helpful for UIs\n function currentTotalUsage() external view returns (uint256) {\n return chainTotalUsage[block.timestamp / 3600];\n }\n\n /// @notice Mints the canonical token from a supported bridge token\n /// @param bridgeToken Bridge token to use to mint\n /// @param amount Amount of bridge tokens to send\n /// @param to Address to which the stablecoin should be sent\n /// @dev Some fees may be taken by the protocol depending on the token used and on the address calling\n function swapIn(address bridgeToken, uint256 amount, address to) external returns (uint256) {\n BridgeDetails memory bridgeDetails = bridges[bridgeToken];\n if (!bridgeDetails.allowed || bridgeDetails.paused) revert InvalidToken();\n uint256 balance = IERC20(bridgeToken).balanceOf(address(this));\n if (balance + amount > bridgeDetails.limit) {\n // In case someone maliciously sends tokens to this contract\n // Or the limit changes\n if (bridgeDetails.limit > balance) amount = bridgeDetails.limit - balance;\n else {\n amount = 0;\n }\n }\n\n // Checking requirement on the hourly volume\n uint256 hour = block.timestamp / 3600;\n uint256 hourlyUsage = usage[bridgeToken][hour] + amount;\n if (hourlyUsage > bridgeDetails.hourlyLimit) {\n // Edge case when the hourly limit changes\n if (bridgeDetails.hourlyLimit > usage[bridgeToken][hour])\n amount = bridgeDetails.hourlyLimit - usage[bridgeToken][hour];\n else {\n amount = 0;\n }\n }\n usage[bridgeToken][hour] += amount;\n\n IERC20(bridgeToken).safeTransferFrom(msg.sender, address(this), amount);\n uint256 canonicalOut = amount;\n // Computing fees\n if (isFeeExempt[msg.sender] == 0) {\n canonicalOut -= (canonicalOut * bridgeDetails.fee) / BASE_PARAMS;\n }\n _mint(to, canonicalOut);\n return canonicalOut;\n }\n\n /// @notice Burns the canonical token in exchange for a bridge token\n /// @param bridgeToken Bridge token required\n /// @param amount Amount of canonical tokens to burn\n /// @param to Address to which the bridge token should be sent\n /// @dev Some fees may be taken by the protocol depending on the token used and on the address calling\n function swapOut(address bridgeToken, uint256 amount, address to) external returns (uint256) {\n BridgeDetails memory bridgeDetails = bridges[bridgeToken];\n if (!bridgeDetails.allowed || bridgeDetails.paused) revert InvalidToken();\n\n uint256 hour = block.timestamp / 3600;\n uint256 hourlyUsage = chainTotalUsage[hour] + amount;\n // If the amount being swapped out exceeds the limit, we revert\n // We don't want to change the amount being swapped out.\n // The user can decide to send another tx with the correct amount to reach the limit\n if (hourlyUsage > chainTotalHourlyLimit) revert HourlyLimitExceeded();\n chainTotalUsage[hour] = hourlyUsage;\n\n _burnCustom(msg.sender, amount);\n uint256 bridgeOut = amount;\n if (isFeeExempt[msg.sender] == 0) {\n bridgeOut -= (bridgeOut * bridgeDetails.fee) / BASE_PARAMS;\n }\n IERC20(bridgeToken).safeTransfer(to, bridgeOut);\n return bridgeOut;\n }\n\n // ======================= Governance Functions ================================\n\n /// @notice Adds support for a bridge token\n /// @param bridgeToken Bridge token to add: it should be a version of the stablecoin from another bridge\n /// @param limit Limit on the balance of bridge token this contract could hold\n /// @param hourlyLimit Limit on the hourly volume for this bridge\n /// @param paused Whether swapping for this token should be paused or not\n /// @param fee Fee taken upon swapping for or against this token\n function addBridgeToken(\n address bridgeToken,\n uint256 limit,\n uint256 hourlyLimit,\n uint64 fee,\n bool paused\n ) external onlyGovernor {\n if (bridges[bridgeToken].allowed || bridgeToken == address(0)) revert InvalidToken();\n if (fee > BASE_PARAMS) revert TooHighParameterValue();\n BridgeDetails memory _bridge;\n _bridge.limit = limit;\n _bridge.hourlyLimit = hourlyLimit;\n _bridge.paused = paused;\n _bridge.fee = fee;\n _bridge.allowed = true;\n bridges[bridgeToken] = _bridge;\n bridgeTokensList.push(bridgeToken);\n emit BridgeTokenAdded(bridgeToken, limit, hourlyLimit, fee, paused);\n }\n\n /// @notice Removes support for a token\n /// @param bridgeToken Address of the bridge token to remove support for\n function removeBridgeToken(address bridgeToken) external onlyGovernor {\n if (IERC20(bridgeToken).balanceOf(address(this)) != 0) revert AssetStillControlledInReserves();\n delete bridges[bridgeToken];\n // Deletion from `bridgeTokensList` loop\n uint256 bridgeTokensListLength = bridgeTokensList.length;\n for (uint256 i; i < bridgeTokensListLength - 1; ++i) {\n if (bridgeTokensList[i] == bridgeToken) {\n // Replace the `bridgeToken` to remove with the last of the list\n bridgeTokensList[i] = bridgeTokensList[bridgeTokensListLength - 1];\n break;\n }\n }\n // Remove last element in array\n bridgeTokensList.pop();\n emit BridgeTokenRemoved(bridgeToken);\n }\n\n /// @notice Recovers any ERC20 token\n /// @dev Can be used to withdraw bridge tokens for them to be de-bridged on mainnet\n function recoverERC20(address tokenAddress, address to, uint256 amountToRecover) external onlyGovernor {\n IERC20(tokenAddress).safeTransfer(to, amountToRecover);\n emit Recovered(tokenAddress, to, amountToRecover);\n }\n\n /// @notice Updates the `limit` amount for `bridgeToken`\n function setLimit(address bridgeToken, uint256 limit) external onlyGovernorOrGuardian {\n if (!bridges[bridgeToken].allowed) revert InvalidToken();\n bridges[bridgeToken].limit = limit;\n emit BridgeTokenLimitUpdated(bridgeToken, limit);\n }\n\n /// @notice Updates the `hourlyLimit` amount for `bridgeToken`\n function setHourlyLimit(address bridgeToken, uint256 hourlyLimit) external onlyGovernorOrGuardian {\n if (!bridges[bridgeToken].allowed) revert InvalidToken();\n bridges[bridgeToken].hourlyLimit = hourlyLimit;\n emit BridgeTokenHourlyLimitUpdated(bridgeToken, hourlyLimit);\n }\n\n /// @notice Updates the `chainTotalHourlyLimit` amount\n function setChainTotalHourlyLimit(uint256 hourlyLimit) external onlyGovernorOrGuardian {\n chainTotalHourlyLimit = hourlyLimit;\n emit HourlyLimitUpdated(hourlyLimit);\n }\n\n /// @notice Updates the `fee` value for `bridgeToken`\n function setSwapFee(address bridgeToken, uint64 fee) external onlyGovernorOrGuardian {\n if (!bridges[bridgeToken].allowed) revert InvalidToken();\n if (fee > BASE_PARAMS) revert TooHighParameterValue();\n bridges[bridgeToken].fee = fee;\n emit BridgeTokenFeeUpdated(bridgeToken, fee);\n }\n\n /// @notice Pauses or unpauses swapping in and out for a token\n function toggleBridge(address bridgeToken) external onlyGovernorOrGuardian {\n if (!bridges[bridgeToken].allowed) revert InvalidToken();\n bool pausedStatus = bridges[bridgeToken].paused;\n bridges[bridgeToken].paused = !pausedStatus;\n emit BridgeTokenToggled(bridgeToken, !pausedStatus);\n }\n\n /// @notice Toggles fees for the address `theAddress`\n function toggleFeesForAddress(address theAddress) external onlyGovernorOrGuardian {\n uint256 feeExemptStatus = 1 - isFeeExempt[theAddress];\n isFeeExempt[theAddress] = feeExemptStatus;\n emit FeeToggled(theAddress, feeExemptStatus);\n }\n}\n" + }, + "contracts/agToken/polygon/utils/ERC20UpgradeableCustom.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (token/ERC20/ERC20.sol)\n\npragma solidity ^0.8.0;\n\nimport \"@openzeppelin/contracts-upgradeable/token/ERC20/IERC20Upgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/token/ERC20/extensions/IERC20MetadataUpgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/utils/ContextUpgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol\";\n\n/**\n * @dev Implementation of the {IERC20} interface modified by Angle Labs, Inc.\n *\n * This implementation has a custom burn function to avoid having a {Transfer} event to the zero address\n * in some specific burn cases to avoid having Polygon PoS bridge catching this event\n *\n * TIP: For a detailed writeup see our guide\n * https://forum.zeppelin.solutions/t/how-to-implement-erc20-supply-mechanisms/226[How\n * to implement supply mechanisms].\n *\n * We have followed general OpenZeppelin Contracts guidelines: functions revert\n * instead returning `false` on failure. This behavior is nonetheless\n * conventional and does not conflict with the expectations of ERC20\n * applications.\n *\n * Additionally, an {Approval} event is emitted on calls to {transferFrom}.\n * This allows applications to reconstruct the allowance for all accounts just\n * by listening to said events. Other implementations of the EIP may not emit\n * these events, as it isn't required by the specification.\n *\n * Finally, the non-standard {decreaseAllowance} and {increaseAllowance}\n * functions have been added to mitigate the well-known issues around setting\n * allowances. See {IERC20-approve}.\n */\ncontract ERC20UpgradeableCustom is Initializable, ContextUpgradeable, IERC20Upgradeable, IERC20MetadataUpgradeable {\n mapping(address => uint256) private _balances;\n\n mapping(address => mapping(address => uint256)) private _allowances;\n\n uint256 private _totalSupply;\n\n string private _name;\n string private _symbol;\n\n /**\n * @dev Sets the values for {name} and {symbol}.\n *\n * The default value of {decimals} is 18. To select a different value for\n * {decimals} you should overload it.\n *\n * All two of these values are immutable: they can only be set once during\n * construction.\n */\n //solhint-disable-next-line\n function __ERC20_init(string memory name_, string memory symbol_) internal onlyInitializing {\n __Context_init_unchained();\n __ERC20_init_unchained(name_, symbol_);\n }\n\n //solhint-disable-next-line\n function __ERC20_init_unchained(string memory name_, string memory symbol_) internal onlyInitializing {\n _name = name_;\n _symbol = symbol_;\n }\n\n /**\n * @dev Returns the name of the token.\n */\n function name() public view virtual override returns (string memory) {\n return _name;\n }\n\n /**\n * @dev Returns the symbol of the token, usually a shorter version of the\n * name.\n */\n function symbol() public view virtual override returns (string memory) {\n return _symbol;\n }\n\n /**\n * @dev Returns the number of decimals used to get its user representation.\n * For example, if `decimals` equals `2`, a balance of `505` tokens should\n * be displayed to a user as `5.05` (`505 / 10 ** 2`).\n *\n * Tokens usually opt for a value of 18, imitating the relationship between\n * Ether and Wei. This is the value {ERC20} uses, unless this function is\n * overridden;\n *\n * NOTE: This information is only used for _display_ purposes: it in\n * no way affects any of the arithmetic of the contract, including\n * {IERC20-balanceOf} and {IERC20-transfer}.\n */\n function decimals() public view virtual override returns (uint8) {\n return 18;\n }\n\n /**\n * @dev See {IERC20-totalSupply}.\n */\n function totalSupply() public view virtual override returns (uint256) {\n return _totalSupply;\n }\n\n /**\n * @dev See {IERC20-balanceOf}.\n */\n function balanceOf(address account) public view virtual override returns (uint256) {\n return _balances[account];\n }\n\n /**\n * @dev See {IERC20-transfer}.\n *\n * Requirements:\n *\n * - `recipient` cannot be the zero address.\n * - the caller must have a balance of at least `amount`.\n */\n function transfer(address recipient, uint256 amount) public virtual override returns (bool) {\n _transfer(_msgSender(), recipient, amount);\n return true;\n }\n\n /**\n * @dev See {IERC20-allowance}.\n */\n function allowance(address owner, address spender) public view virtual override returns (uint256) {\n return _allowances[owner][spender];\n }\n\n /**\n * @dev See {IERC20-approve}.\n *\n * Requirements:\n *\n * - `spender` cannot be the zero address.\n */\n function approve(address spender, uint256 amount) public virtual override returns (bool) {\n _approve(_msgSender(), spender, amount);\n return true;\n }\n\n /**\n * @dev See {IERC20-transferFrom}.\n *\n * Emits an {Approval} event indicating the updated allowance. This is not\n * required by the EIP. See the note at the beginning of {ERC20}.\n *\n * Requirements:\n *\n * - `sender` and `recipient` cannot be the zero address.\n * - `sender` must have a balance of at least `amount`.\n * - the caller must have allowance for `sender`'s tokens of at least\n * `amount`.\n */\n function transferFrom(address sender, address recipient, uint256 amount) public virtual override returns (bool) {\n _transfer(sender, recipient, amount);\n\n uint256 currentAllowance = _allowances[sender][_msgSender()];\n require(currentAllowance >= amount, \"ERC20: transfer amount exceeds allowance\");\n unchecked {\n _approve(sender, _msgSender(), currentAllowance - amount);\n }\n\n return true;\n }\n\n /**\n * @dev Atomically increases the allowance granted to `spender` by the caller.\n *\n * This is an alternative to {approve} that can be used as a mitigation for\n * problems described in {IERC20-approve}.\n *\n * Emits an {Approval} event indicating the updated allowance.\n *\n * Requirements:\n *\n * - `spender` cannot be the zero address.\n */\n function increaseAllowance(address spender, uint256 addedValue) public virtual returns (bool) {\n _approve(_msgSender(), spender, _allowances[_msgSender()][spender] + addedValue);\n return true;\n }\n\n /**\n * @dev Atomically decreases the allowance granted to `spender` by the caller.\n *\n * This is an alternative to {approve} that can be used as a mitigation for\n * problems described in {IERC20-approve}.\n *\n * Emits an {Approval} event indicating the updated allowance.\n *\n * Requirements:\n *\n * - `spender` cannot be the zero address.\n * - `spender` must have allowance for the caller of at least\n * `subtractedValue`.\n */\n function decreaseAllowance(address spender, uint256 subtractedValue) public virtual returns (bool) {\n uint256 currentAllowance = _allowances[_msgSender()][spender];\n require(currentAllowance >= subtractedValue, \"ERC20: decreased allowance below zero\");\n unchecked {\n _approve(_msgSender(), spender, currentAllowance - subtractedValue);\n }\n\n return true;\n }\n\n /**\n * @dev Moves `amount` of tokens from `sender` to `recipient`.\n *\n * This internal function is equivalent to {transfer}, and can be used to\n * e.g. implement automatic token fees, slashing mechanisms, etc.\n *\n * Emits a {Transfer} event.\n *\n * Requirements:\n *\n * - `sender` cannot be the zero address.\n * - `recipient` cannot be the zero address.\n * - `sender` must have a balance of at least `amount`.\n */\n function _transfer(address sender, address recipient, uint256 amount) internal virtual {\n require(sender != address(0), \"ERC20: transfer from the zero address\");\n require(recipient != address(0), \"ERC20: transfer to the zero address\");\n\n _beforeTokenTransfer(sender, recipient, amount);\n\n uint256 senderBalance = _balances[sender];\n require(senderBalance >= amount, \"ERC20: transfer amount exceeds balance\");\n unchecked {\n _balances[sender] = senderBalance - amount;\n }\n _balances[recipient] += amount;\n\n emit Transfer(sender, recipient, amount);\n\n _afterTokenTransfer(sender, recipient, amount);\n }\n\n /** @dev Creates `amount` tokens and assigns them to `account`, increasing\n * the total supply.\n *\n * Emits a {Transfer} event with `from` set to the zero address.\n *\n * Requirements:\n *\n * - `account` cannot be the zero address.\n */\n function _mint(address account, uint256 amount) internal virtual {\n require(account != address(0), \"ERC20: mint to the zero address\");\n\n _beforeTokenTransfer(address(0), account, amount);\n\n _totalSupply += amount;\n _balances[account] += amount;\n emit Transfer(address(0), account, amount);\n\n _afterTokenTransfer(address(0), account, amount);\n }\n\n /**\n * @dev Destroys `amount` tokens from `account`, reducing the\n * total supply.\n *\n * Emits a {Transfer} event with `to` set to the zero address.\n *\n * Requirements:\n *\n * - `account` cannot be the zero address.\n * - `account` must have at least `amount` tokens.\n */\n function _burn(address account, uint256 amount) internal virtual {\n require(account != address(0), \"ERC20: burn from the zero address\");\n\n _beforeTokenTransfer(account, address(0), amount);\n\n uint256 accountBalance = _balances[account];\n require(accountBalance >= amount, \"ERC20: burn amount exceeds balance\");\n unchecked {\n _balances[account] = accountBalance - amount;\n }\n _totalSupply -= amount;\n\n emit Transfer(account, address(0), amount);\n\n _afterTokenTransfer(account, address(0), amount);\n }\n\n /**\n * @dev Destroys `amount` tokens from `account`, reducing the\n * total supply.\n *\n * Contrary to the other `burn` function, the {Transfer} event is not to the zero address\n * but rather to this address: the reason is that not all burn events should be caught up\n * by the PoS bridge\n *\n * Requirements:\n *\n * - `account` cannot be the zero address.\n * - `account` must have at least `amount` tokens.\n */\n function _burnCustom(address account, uint256 amount) internal virtual {\n require(account != address(0), \"ERC20: burn from the zero address\");\n\n _beforeTokenTransfer(account, address(0), amount);\n\n uint256 accountBalance = _balances[account];\n require(accountBalance >= amount, \"ERC20: burn amount exceeds balance\");\n unchecked {\n _balances[account] = accountBalance - amount;\n }\n _totalSupply -= amount;\n\n emit Transfer(account, address(this), amount);\n\n _afterTokenTransfer(account, address(0), amount);\n }\n\n /**\n * @dev Sets `amount` as the allowance of `spender` over the `owner` s tokens.\n *\n * This internal function is equivalent to `approve`, and can be used to\n * e.g. set automatic allowances for certain subsystems, etc.\n *\n * Emits an {Approval} event.\n *\n * Requirements:\n *\n * - `owner` cannot be the zero address.\n * - `spender` cannot be the zero address.\n */\n function _approve(address owner, address spender, uint256 amount) internal virtual {\n require(owner != address(0), \"ERC20: approve from the zero address\");\n require(spender != address(0), \"ERC20: approve to the zero address\");\n\n _allowances[owner][spender] = amount;\n emit Approval(owner, spender, amount);\n }\n\n /**\n * @dev Hook that is called before any transfer of tokens. This includes\n * minting and burning.\n *\n * Calling conditions:\n *\n * - when `from` and `to` are both non-zero, `amount` of `from`'s tokens\n * will be transferred to `to`.\n * - when `from` is zero, `amount` tokens will be minted for `to`.\n * - when `to` is zero, `amount` of `from`'s tokens will be burned.\n * - `from` and `to` are never both zero.\n *\n * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].\n */\n function _beforeTokenTransfer(address from, address to, uint256 amount) internal virtual {}\n\n /**\n * @dev Hook that is called after any transfer of tokens. This includes\n * minting and burning.\n *\n * Calling conditions:\n *\n * - when `from` and `to` are both non-zero, `amount` of `from`'s tokens\n * has been transferred to `to`.\n * - when `from` is zero, `amount` tokens have been minted for `to`.\n * - when `to` is zero, `amount` of `from`'s tokens have been burned.\n * - `from` and `to` are never both zero.\n *\n * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].\n */\n function _afterTokenTransfer(address from, address to, uint256 amount) internal virtual {}\n\n uint256[45] private __gap;\n}\n" + }, + "contracts/coreBorrow/CoreBorrow.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\n/*\n * █ \n ***** ▓▓▓ \n * ▓▓▓▓▓▓▓ \n * ///. ▓▓▓▓▓▓▓▓▓▓▓▓▓ \n ***** //////// ▓▓▓▓▓▓▓ \n * ///////////// ▓▓▓ \n ▓▓ ////////////////// █ ▓▓ \n ▓▓ ▓▓ /////////////////////// ▓▓ ▓▓ \n ▓▓ ▓▓ //////////////////////////// ▓▓ ▓▓ \n ▓▓ ▓▓ /////////▓▓▓///////▓▓▓///////// ▓▓ ▓▓ \n ▓▓ ,////////////////////////////////////// ▓▓ ▓▓ \n ▓▓ ////////////////////////////////////////// ▓▓ \n ▓▓ //////////////////////▓▓▓▓///////////////////// \n ,//////////////////////////////////////////////////// \n .////////////////////////////////////////////////////////// \n .//////////////////////////██.,//////////////////////////█ \n .//////////////////////████..,./////////////////////██ \n ...////////////////███████.....,.////////////////███ \n ,.,////////////████████ ........,///////////████ \n .,.,//////█████████ ,.......///////████ \n ,..//████████ ........./████ \n ..,██████ .....,███ \n .██ ,.,█ \n \n \n \n ▓▓ ▓▓▓▓▓▓▓▓▓▓ ▓▓▓▓▓▓▓▓▓▓ ▓▓ ▓▓▓▓▓▓▓▓▓▓ \n ▓▓▓▓▓▓ ▓▓▓ ▓▓▓ ▓▓▓ ▓▓ ▓▓ ▓▓▓▓ \n ▓▓▓ ▓▓▓ ▓▓▓ ▓▓▓ ▓▓▓ ▓▓▓ ▓▓ ▓▓▓▓▓ \n ▓▓▓ ▓▓ ▓▓▓ ▓▓▓ ▓▓▓▓▓▓▓▓▓▓ ▓▓▓▓▓▓▓▓▓▓ ▓▓▓▓▓▓▓▓▓▓ \n*/\n\npragma solidity ^0.8.12;\n\nimport \"@openzeppelin/contracts-upgradeable/access/AccessControlEnumerableUpgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol\";\n\nimport \"../interfaces/ICoreBorrow.sol\";\nimport \"../interfaces/IFlashAngle.sol\";\nimport \"../interfaces/ITreasury.sol\";\n\n/// @title CoreBorrow\n/// @author Angle Labs, Inc.\n/// @notice Core contract of the borrowing module. This contract handles the access control across all contracts\n/// (it is read by all treasury contracts), and manages the `flashLoanModule`. It has no minting rights over the\n/// stablecoin contracts\ncontract CoreBorrow is ICoreBorrow, Initializable, AccessControlEnumerableUpgradeable {\n /// @notice Role for guardians\n bytes32 public constant GUARDIAN_ROLE = keccak256(\"GUARDIAN_ROLE\");\n /// @notice Role for governors\n bytes32 public constant GOVERNOR_ROLE = keccak256(\"GOVERNOR_ROLE\");\n /// @notice Role for treasury contract\n bytes32 public constant FLASHLOANER_TREASURY_ROLE = keccak256(\"FLASHLOANER_TREASURY_ROLE\");\n\n // ============================= Reference =====================================\n\n /// @notice Reference to the `flashLoanModule` with minting rights over the different stablecoins of the protocol\n address public flashLoanModule;\n\n // =============================== Events ======================================\n\n event FlashLoanModuleUpdated(address indexed _flashloanModule);\n event CoreUpdated(address indexed _core);\n\n // =============================== Errors ======================================\n\n error InvalidCore();\n error IncompatibleGovernorAndGuardian();\n error NotEnoughGovernorsLeft();\n error ZeroAddress();\n\n /// @notice Initializes the `CoreBorrow` contract and the access control of the borrowing module\n /// @param governor Address of the governor of the Angle Protocol\n /// @param guardian Guardian address of the protocol\n function initialize(address governor, address guardian) public initializer {\n if (governor == address(0) || guardian == address(0)) revert ZeroAddress();\n if (governor == guardian) revert IncompatibleGovernorAndGuardian();\n _setupRole(GOVERNOR_ROLE, governor);\n _setupRole(GUARDIAN_ROLE, guardian);\n _setupRole(GUARDIAN_ROLE, governor);\n _setRoleAdmin(GUARDIAN_ROLE, GOVERNOR_ROLE);\n _setRoleAdmin(GOVERNOR_ROLE, GOVERNOR_ROLE);\n _setRoleAdmin(FLASHLOANER_TREASURY_ROLE, GOVERNOR_ROLE);\n }\n\n /// @custom:oz-upgrades-unsafe-allow constructor\n constructor() initializer {}\n\n // =========================== View Functions ==================================\n\n /// @inheritdoc ICoreBorrow\n function isFlashLoanerTreasury(address treasury) external view returns (bool) {\n return hasRole(FLASHLOANER_TREASURY_ROLE, treasury);\n }\n\n /// @inheritdoc ICoreBorrow\n function isGovernor(address admin) external view returns (bool) {\n return hasRole(GOVERNOR_ROLE, admin);\n }\n\n /// @inheritdoc ICoreBorrow\n function isGovernorOrGuardian(address admin) external view returns (bool) {\n return hasRole(GUARDIAN_ROLE, admin);\n }\n\n // =========================== Governor Functions ==============================\n\n /// @notice Grants the `FLASHLOANER_TREASURY_ROLE` to a `treasury` contract\n /// @param treasury Contract to grant the role to\n /// @dev This function can be used to allow flash loans on a stablecoin of the protocol\n function addFlashLoanerTreasuryRole(address treasury) external {\n grantRole(FLASHLOANER_TREASURY_ROLE, treasury);\n address _flashLoanModule = flashLoanModule;\n if (_flashLoanModule != address(0)) {\n // This call will revert if `treasury` is the zero address or if it is not linked\n // to this `CoreBorrow` contract\n ITreasury(treasury).setFlashLoanModule(_flashLoanModule);\n IFlashAngle(_flashLoanModule).addStablecoinSupport(treasury);\n }\n }\n\n /// @notice Adds a governor in the protocol\n /// @param governor Address to grant the role to\n /// @dev It is necessary to call this function to grant a governor role to make sure\n /// all governors also have the guardian role\n function addGovernor(address governor) external {\n grantRole(GOVERNOR_ROLE, governor);\n grantRole(GUARDIAN_ROLE, governor);\n }\n\n /// @notice Revokes the flash loan ability for a stablecoin\n /// @param treasury Treasury address associated with the stablecoin for which flash loans\n /// should no longer be available\n function removeFlashLoanerTreasuryRole(address treasury) external {\n revokeRole(FLASHLOANER_TREASURY_ROLE, treasury);\n ITreasury(treasury).setFlashLoanModule(address(0));\n address _flashLoanModule = flashLoanModule;\n if (_flashLoanModule != address(0)) {\n IFlashAngle(flashLoanModule).removeStablecoinSupport(treasury);\n }\n }\n\n /// @notice Revokes a governor from the protocol\n /// @param governor Address to remove the role to\n /// @dev It is necessary to call this function to remove a governor role to make sure\n /// the address also loses its guardian role\n function removeGovernor(address governor) external {\n if (getRoleMemberCount(GOVERNOR_ROLE) <= 1) revert NotEnoughGovernorsLeft();\n revokeRole(GUARDIAN_ROLE, governor);\n revokeRole(GOVERNOR_ROLE, governor);\n }\n\n /// @notice Changes the `flashLoanModule` of the protocol\n /// @param _flashLoanModule Address of the new flash loan module\n function setFlashLoanModule(address _flashLoanModule) external onlyRole(GOVERNOR_ROLE) {\n if (_flashLoanModule != address(0)) {\n if (address(IFlashAngle(_flashLoanModule).core()) != address(this)) revert InvalidCore();\n }\n uint256 count = getRoleMemberCount(FLASHLOANER_TREASURY_ROLE);\n for (uint256 i; i < count; ++i) {\n ITreasury(getRoleMember(FLASHLOANER_TREASURY_ROLE, i)).setFlashLoanModule(_flashLoanModule);\n }\n flashLoanModule = _flashLoanModule;\n emit FlashLoanModuleUpdated(_flashLoanModule);\n }\n\n /// @notice Changes the core contract of the protocol\n /// @param _core New core contract\n /// @dev This function verifies that all governors of the current core contract are also governors\n /// of the new core contract. It also notifies the `flashLoanModule` of the change.\n /// @dev Governance wishing to change the core contract should also make sure to call `setCore`\n /// in the different treasury contracts\n function setCore(ICoreBorrow _core) external onlyRole(GOVERNOR_ROLE) {\n uint256 count = getRoleMemberCount(GOVERNOR_ROLE);\n bool success;\n for (uint256 i; i < count; ++i) {\n success = _core.isGovernor(getRoleMember(GOVERNOR_ROLE, i));\n if (!success) break;\n }\n if (!success) revert InvalidCore();\n address _flashLoanModule = flashLoanModule;\n if (_flashLoanModule != address(0)) IFlashAngle(_flashLoanModule).setCore(address(_core));\n emit CoreUpdated(address(_core));\n }\n}\n" + }, + "contracts/deprecated/AgTokenIntermediateUpgrade.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\nimport \"../interfaces/IAgToken.sol\";\nimport \"../interfaces/coreModule/IStableMaster.sol\";\n// OpenZeppelin may update its version of the ERC20PermitUpgradeable token\nimport \"@openzeppelin/contracts-upgradeable/token/ERC20/extensions/draft-ERC20PermitUpgradeable.sol\";\n\n/// @title AgTokenIntermediateUpgrade\n/// @author Angle Labs, Inc.\n/// @notice Base contract for agToken, that is to say Angle's stablecoins\n/// @dev This contract is used to create and handle the stablecoins of Angle protocol\n/// @dev It is still possible for any address to burn its agTokens without redeeming collateral in exchange\n/// @dev This contract is the upgraded version of the AgToken that was first deployed on Ethereum mainnet and is used to\n/// add other minters as needed by AMOs\ncontract AgTokenIntermediateUpgrade is ERC20PermitUpgradeable {\n // ========================= References to other contracts =====================\n\n /// @notice Reference to the `StableMaster` contract associated to this `AgToken`\n address public stableMaster;\n\n // ============================= Constructor ===================================\n\n /// @notice Initializes the `AgToken` contract\n /// @param name_ Name of the token\n /// @param symbol_ Symbol of the token\n /// @param stableMaster_ Reference to the `StableMaster` contract associated to this agToken\n /// @dev By default, agTokens are ERC-20 tokens with 18 decimals\n function initialize(string memory name_, string memory symbol_, address stableMaster_) external initializer {\n __ERC20Permit_init(name_);\n __ERC20_init(name_, symbol_);\n require(stableMaster_ != address(0), \"0\");\n stableMaster = stableMaster_;\n }\n\n /// @custom:oz-upgrades-unsafe-allow constructor\n constructor() initializer {}\n\n // ======= Added Parameters and Variables from the first implementation ========\n\n /// @notice Checks whether an address has the right to mint agTokens\n mapping(address => bool) public isMinter;\n\n // =============================== Added Events ================================\n\n event MinterToggled(address indexed minter);\n\n // =============================== Setup Function ==============================\n\n /// @notice Sets up the minter role and gives it to the governor\n /// @dev This function just has to be called once\n function setUpMinter() external {\n address governor = 0xdC4e6DFe07EFCa50a197DF15D9200883eF4Eb1c8;\n require(msg.sender == governor);\n isMinter[governor] = true;\n emit MinterToggled(governor);\n }\n\n // =============================== Modifiers ===================================\n\n /// @notice Checks whether the sender has the minting right\n modifier onlyMinter() {\n require(isMinter[msg.sender] || msg.sender == stableMaster, \"35\");\n _;\n }\n\n // ========================= External Functions ================================\n // The following functions allow anyone to burn stablecoins without redeeming collateral\n // in exchange for that\n\n /// @notice Destroys `amount` token from the caller without giving collateral back\n /// @param amount Amount to burn\n /// @param poolManager Reference to the `PoolManager` contract for which the `stocksUsers` will\n /// need to be updated\n /// @dev When calling this function, people should specify the `poolManager` for which they want to decrease\n /// the `stocksUsers`: this is a way for the protocol to maintain healthy accounting variables\n function burnNoRedeem(uint256 amount, address poolManager) external {\n _burn(msg.sender, amount);\n IStableMaster(stableMaster).updateStocksUsers(amount, poolManager);\n }\n\n /// @notice Burns `amount` of agToken on behalf of another account without redeeming collateral back\n /// @param account Account to burn on behalf of\n /// @param amount Amount to burn\n /// @param poolManager Reference to the `PoolManager` contract for which the `stocksUsers` will need to be updated\n function burnFromNoRedeem(address account, uint256 amount, address poolManager) external {\n _burnFromNoRedeem(amount, account, msg.sender);\n IStableMaster(stableMaster).updateStocksUsers(amount, poolManager);\n }\n\n // ======================= Minter Role Only Functions ==========================\n\n /// @notice Burns `amount` tokens from a `burner` address\n /// @param amount Amount of tokens to burn\n /// @param burner Address to burn from\n /// @dev This method is to be called by a contract with a minter right on the AgToken after being\n /// requested to do so by an address willing to burn tokens from its address\n function burnSelf(uint256 amount, address burner) external onlyMinter {\n _burn(burner, amount);\n }\n\n /// @notice Burns `amount` tokens from a `burner` address after being asked to by `sender`\n /// @param amount Amount of tokens to burn\n /// @param burner Address to burn from\n /// @param sender Address which requested the burn from `burner`\n /// @dev This method is to be called by a contract with the minter right after being requested\n /// to do so by a `sender` address willing to burn tokens from another `burner` address\n /// @dev The method checks the allowance between the `sender` and the `burner`\n function burnFrom(uint256 amount, address burner, address sender) external onlyMinter {\n _burnFromNoRedeem(amount, burner, sender);\n }\n\n /// @notice Lets the `StableMaster` contract or another whitelisted contract mint agTokens\n /// @param account Address to mint to\n /// @param amount Amount to mint\n /// @dev The contracts allowed to issue agTokens are the `StableMaster` contract, `VaultManager` contracts\n /// associated to this stablecoin as well as the flash loan module (if activated) and potentially contracts\n /// whitelisted by governance\n function mint(address account, uint256 amount) external onlyMinter {\n _mint(account, amount);\n }\n\n // ======================= Minter Only Functions ===============================\n\n /// @notice Adds a minter in the contract\n /// @param minter Minter address to add\n function addMinter(address minter) external onlyMinter {\n isMinter[minter] = true;\n emit MinterToggled(minter);\n }\n\n /// @notice Removes a minter from the contract\n /// @param minter Minter address to remove\n /// @dev This function can at the moment only be called by a minter wishing to revoke itself\n function removeMinter(address minter) external {\n require(msg.sender == minter && isMinter[msg.sender], \"36\");\n isMinter[minter] = false;\n emit MinterToggled(minter);\n }\n\n // ============================ Internal Function ==============================\n\n /// @notice Internal version of the function `burnFromNoRedeem`\n /// @param amount Amount to burn\n /// @dev It is at the level of this function that allowance checks are performed\n function _burnFromNoRedeem(uint256 amount, address burner, address sender) internal {\n if (burner != sender) {\n uint256 currentAllowance = allowance(burner, sender);\n require(currentAllowance >= amount, \"23\");\n _approve(burner, sender, currentAllowance - amount);\n }\n _burn(burner, amount);\n }\n}\n" + }, + "contracts/deprecated/layerZero/OldLayerZeroBridgeToken.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.12;\n\nimport \"./OldOFTCore.sol\";\nimport \"../../interfaces/IAgTokenSideChainMultiBridge.sol\";\nimport \"@openzeppelin/contracts-upgradeable/security/PausableUpgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/token/ERC20/ERC20Upgradeable.sol\";\n\n/// @title LayerZeroBridgeToken\n/// @author Angle Labs, Inc., forked from https://github.com/LayerZero-Labs/solidity-examples/blob/main/contracts/token/oft/OFT.sol\n/// @notice Contract to be deployed on a L2/sidechain for bridging an AgToken using a bridge intermediate token and LayerZero\ncontract OldLayerZeroBridgeToken is OldOFTCore, ERC20Upgradeable, PausableUpgradeable {\n /// @notice Address of the bridgeable token\n /// @dev Immutable\n IAgTokenSideChainMultiBridge public canonicalToken;\n\n // =============================== Errors ================================\n\n error InvalidAllowance();\n\n // ============================= Constructor ===================================\n\n /// @notice Initializes the contract\n /// @param _name Name of the token corresponding to this contract\n /// @param _symbol Symbol of the token corresponding to this contract\n /// @param _lzEndpoint Layer zero endpoint to pass messages\n /// @param _treasury Address of the treasury contract used for access control\n /// @param initialSupply Initial supply to mint to the canonical token address\n /// @dev The initial supply corresponds to the initial amount that could be bridged using this OFT\n function initialize(\n string memory _name,\n string memory _symbol,\n address _lzEndpoint,\n address _treasury,\n uint256 initialSupply\n ) external initializer {\n __ERC20_init_unchained(_name, _symbol);\n __LzAppUpgradeable_init(_lzEndpoint, _treasury);\n\n canonicalToken = IAgTokenSideChainMultiBridge(address(ITreasury(_treasury).stablecoin()));\n _approve(address(this), address(canonicalToken), type(uint256).max);\n _mint(address(canonicalToken), initialSupply);\n }\n\n /// @custom:oz-upgrades-unsafe-allow constructor\n constructor() initializer {}\n\n // ==================== External Permissionless Functions ======================\n\n function sendWithPermit(\n uint16 _dstChainId,\n bytes memory _toAddress,\n uint256 _amount,\n address payable _refundAddress,\n address _zroPaymentAddress,\n bytes memory _adapterParams,\n uint256 deadline,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) public payable override {\n canonicalToken.permit(msg.sender, address(this), _amount, deadline, v, r, s);\n send(_dstChainId, _toAddress, _amount, _refundAddress, _zroPaymentAddress, _adapterParams);\n }\n\n function withdraw(uint256 amount, address recipient) external override returns (uint256 amountMinted) {\n // Does not check allowances as transfers from `msg.sender`\n _transfer(msg.sender, address(this), amount);\n amountMinted = canonicalToken.swapIn(address(this), amount, recipient);\n uint256 leftover = balanceOf(address(this));\n if (leftover != 0) {\n _transfer(address(this), msg.sender, leftover);\n }\n }\n\n // ============================= Internal Functions ===================================\n\n function _debitFrom(\n uint16,\n bytes memory,\n uint256 _amount\n ) internal override whenNotPaused returns (uint256 amountSwapped) {\n // No need to use safeTransferFrom as we know this implementation reverts on failure\n canonicalToken.transferFrom(msg.sender, address(this), _amount);\n\n // Swap canonical for this bridge token. There may be some fees\n amountSwapped = canonicalToken.swapOut(address(this), _amount, address(this));\n _burn(address(this), amountSwapped);\n }\n\n function _debitCreditFrom(uint16, bytes memory, uint256 _amount) internal override whenNotPaused returns (uint256) {\n _burn(msg.sender, _amount);\n return _amount;\n }\n\n function _creditTo(\n uint16,\n address _toAddress,\n uint256 _amount\n ) internal override whenNotPaused returns (uint256 amountMinted) {\n _mint(address(this), _amount);\n amountMinted = canonicalToken.swapIn(address(this), _amount, _toAddress);\n uint256 leftover = balanceOf(address(this));\n if (leftover != 0) {\n _transfer(address(this), _toAddress, leftover);\n }\n }\n\n // ======================= View Functions ================================\n\n /// @inheritdoc ERC165Upgradeable\n function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {\n return\n interfaceId == type(IOFT).interfaceId ||\n interfaceId == type(IERC20).interfaceId ||\n super.supportsInterface(interfaceId);\n }\n\n // ======================= Governance Functions ================================\n\n /// @notice Mints the intermediate contract to the `canonicalToken`\n /// @dev Used to increase the bridging capacity\n function mint(uint256 amount) external onlyGovernorOrGuardian {\n _mint(address(canonicalToken), amount);\n }\n\n /// @notice Burns the intermediate contract from the `canonicalToken`\n /// @dev Used to decrease the bridging capacity\n function burn(uint256 amount) external onlyGovernorOrGuardian {\n _burn(address(canonicalToken), amount);\n }\n\n /// @notice Increases allowance of the `canonicalToken`\n function setupAllowance() public onlyGovernorOrGuardian {\n _approve(address(this), address(canonicalToken), type(uint256).max);\n }\n\n /// @notice Pauses bridging through the contract\n /// @param pause Future pause status\n function pauseSendTokens(bool pause) external onlyGovernorOrGuardian {\n pause ? _pause() : _unpause();\n }\n\n uint256[49] private __gap;\n}\n" + }, + "contracts/deprecated/layerZero/OldNonblockingLzApp.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.12;\n\nimport \"@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol\";\nimport \"../../interfaces/external/layerZero/ILayerZeroReceiver.sol\";\nimport \"../../interfaces/external/layerZero/ILayerZeroUserApplicationConfig.sol\";\nimport \"../../interfaces/external/layerZero/ILayerZeroEndpoint.sol\";\nimport \"../../interfaces/ITreasury.sol\";\n\n/// @title OldNonblockingLzApp\n/// @author Angle Labs, Inc., forked from https://github.com/LayerZero-Labs/solidity-examples/\n/// @notice Base contract for bridging using LayerZero\nabstract contract OldNonblockingLzApp is Initializable, ILayerZeroReceiver, ILayerZeroUserApplicationConfig {\n /// @notice Layer Zero endpoint\n ILayerZeroEndpoint public lzEndpoint;\n\n /// @notice Maps chainIds to failed messages to retry them\n mapping(uint16 => mapping(bytes => mapping(uint64 => bytes32))) public failedMessages;\n\n /// @notice Maps chainIds to their OFT address\n mapping(uint16 => bytes) public trustedRemoteLookup;\n\n /// @notice Reference to the treasury contract to fetch access control\n address public treasury;\n\n // ================================== Events ===================================\n\n event SetTrustedRemote(uint16 _srcChainId, bytes _srcAddress);\n event MessageFailed(uint16 _srcChainId, bytes _srcAddress, uint64 _nonce, bytes _payload);\n\n // =============================== Errors ================================\n\n error NotGovernor();\n error NotGovernorOrGuardian();\n error InsufficientGas();\n error InvalidEndpoint();\n error InvalidSource();\n error InvalidCaller();\n error InvalidParams();\n error InvalidPayload();\n error ZeroAddress();\n\n // ============================= Constructor ===================================\n\n //solhint-disable-next-line\n function __LzAppUpgradeable_init(address _endpoint, address _treasury) internal {\n if (_endpoint == address(0) || _treasury == address(0)) revert ZeroAddress();\n lzEndpoint = ILayerZeroEndpoint(_endpoint);\n treasury = _treasury;\n }\n\n // =============================== Modifiers ===================================\n\n /// @notice Checks whether the `msg.sender` has the governor role or the guardian role\n modifier onlyGovernorOrGuardian() {\n if (!ITreasury(treasury).isGovernorOrGuardian(msg.sender)) revert NotGovernorOrGuardian();\n _;\n }\n\n // ==================== External Permissionless Functions ======================\n\n /// @notice Receives a message from the LZ endpoint and process it\n /// @param _srcChainId ChainId of the source chain - LayerZero standard\n /// @param _srcAddress Sender of the source chain\n /// @param _nonce Nounce of the message\n /// @param _payload Data: recipient address and amount\n function lzReceive(\n uint16 _srcChainId,\n bytes memory _srcAddress,\n uint64 _nonce,\n bytes memory _payload\n ) public virtual override {\n // lzReceive must be called by the endpoint for security\n if (msg.sender != address(lzEndpoint)) revert InvalidEndpoint();\n\n bytes memory trustedRemote = trustedRemoteLookup[_srcChainId];\n // if will still block the message pathway from (srcChainId, srcAddress). should not receive message from untrusted remote.\n if (_srcAddress.length != trustedRemote.length || keccak256(_srcAddress) != keccak256(trustedRemote))\n revert InvalidSource();\n\n _blockingLzReceive(_srcChainId, _srcAddress, _nonce, _payload);\n }\n\n /// @notice Retries a message that previously failed and was stored\n /// @param _srcChainId ChainId of the source chain - LayerZero standard\n /// @param _srcAddress Sender of the source chain\n /// @param _nonce Nounce of the message\n /// @param _payload Data: recipient address and amount\n function retryMessage(\n uint16 _srcChainId,\n bytes memory _srcAddress,\n uint64 _nonce,\n bytes memory _payload\n ) public payable virtual {\n // assert there is message to retry\n bytes32 payloadHash = failedMessages[_srcChainId][_srcAddress][_nonce];\n if (payloadHash == bytes32(0) || keccak256(_payload) != payloadHash) revert InvalidPayload();\n // clear the stored message\n failedMessages[_srcChainId][_srcAddress][_nonce] = bytes32(0);\n // execute the message. revert if it fails again\n _nonblockingLzReceive(_srcChainId, _srcAddress, _nonce, _payload);\n }\n\n // ============================= Internal Functions ===================================\n\n /// @notice Handles message receptions in a non blocking way\n /// @param _srcChainId ChainId of the source chain - LayerZero standard\n /// @param _srcAddress Sender of the source chain\n /// @param _nonce Nounce of the message\n /// @param _payload Data: recipient address and amount\n /// @dev public for the needs of try / catch but effectively internal\n function nonblockingLzReceive(\n uint16 _srcChainId,\n bytes memory _srcAddress,\n uint64 _nonce,\n bytes memory _payload\n ) public virtual {\n // only internal transaction\n if (msg.sender != address(this)) revert InvalidCaller();\n _nonblockingLzReceive(_srcChainId, _srcAddress, _nonce, _payload);\n }\n\n /// @notice Handles message receptions in a non blocking way\n /// @param _srcChainId ChainId of the source chain - LayerZero standard\n /// @param _srcAddress Sender of the source chain\n /// @param _nonce Nounce of the message\n /// @param _payload Data: recipient address and amount\n function _nonblockingLzReceive(\n uint16 _srcChainId,\n bytes memory _srcAddress,\n uint64 _nonce,\n bytes memory _payload\n ) internal virtual;\n\n /// @notice Handles message receptions in a blocking way\n /// @param _srcChainId ChainId of the source chain - LayerZero standard\n /// @param _srcAddress Sender of the source chain\n /// @param _nonce Nounce of the message\n /// @param _payload Data: recipient address and amount\n function _blockingLzReceive(\n uint16 _srcChainId,\n bytes memory _srcAddress,\n uint64 _nonce,\n bytes memory _payload\n ) internal {\n // try-catch all errors/exceptions\n try this.nonblockingLzReceive(_srcChainId, _srcAddress, _nonce, _payload) {\n // do nothing\n } catch {\n // error / exception\n failedMessages[_srcChainId][_srcAddress][_nonce] = keccak256(_payload);\n emit MessageFailed(_srcChainId, _srcAddress, _nonce, _payload);\n }\n }\n\n /// @notice Sends a message to the LZ endpoint and process it\n /// @param _dstChainId L0 defined chain id to send tokens too\n /// @param _payload Data: recipient address and amount\n /// @param _refundAddress Address LayerZero refunds if too much message fee is sent\n /// @param _zroPaymentAddress Set to address(0x0) if not paying in ZRO (LayerZero Token)\n /// @param _adapterParams Flexible bytes array to indicate messaging adapter services in L0\n function _lzSend(\n uint16 _dstChainId,\n bytes memory _payload,\n address payable _refundAddress,\n address _zroPaymentAddress,\n bytes memory _adapterParams\n ) internal virtual {\n bytes memory trustedRemote = trustedRemoteLookup[_dstChainId];\n if (trustedRemote.length == 0) revert InvalidSource();\n //solhint-disable-next-line\n lzEndpoint.send{ value: msg.value }(\n _dstChainId,\n trustedRemote,\n _payload,\n _refundAddress,\n _zroPaymentAddress,\n _adapterParams\n );\n }\n\n // ======================= Governance Functions ================================\n\n /// @notice Sets the corresponding address on an other chain.\n /// @param _srcChainId ChainId of the source chain - LayerZero standard\n /// @param _srcAddress Address on the source chain\n /// @dev Used for both receiving and sending message\n /// @dev There can only be one trusted source per chain\n /// @dev Allows owner to set it multiple times.\n function setTrustedRemote(uint16 _srcChainId, bytes calldata _srcAddress) external onlyGovernorOrGuardian {\n trustedRemoteLookup[_srcChainId] = _srcAddress;\n emit SetTrustedRemote(_srcChainId, _srcAddress);\n }\n\n /// @notice Fetches the default LZ config\n function getConfig(\n uint16 _version,\n uint16 _chainId,\n address,\n uint256 _configType\n ) external view returns (bytes memory) {\n return lzEndpoint.getConfig(_version, _chainId, address(this), _configType);\n }\n\n /// @notice Overrides the default LZ config\n function setConfig(\n uint16 _version,\n uint16 _chainId,\n uint256 _configType,\n bytes calldata _config\n ) external override onlyGovernorOrGuardian {\n lzEndpoint.setConfig(_version, _chainId, _configType, _config);\n }\n\n /// @notice Overrides the default LZ config\n function setSendVersion(uint16 _version) external override onlyGovernorOrGuardian {\n lzEndpoint.setSendVersion(_version);\n }\n\n /// @notice Overrides the default LZ config\n function setReceiveVersion(uint16 _version) external override onlyGovernorOrGuardian {\n lzEndpoint.setReceiveVersion(_version);\n }\n\n /// @notice Unpauses the receive functionalities\n function forceResumeReceive(\n uint16 _srcChainId,\n bytes calldata _srcAddress\n ) external override onlyGovernorOrGuardian {\n lzEndpoint.forceResumeReceive(_srcChainId, _srcAddress);\n }\n\n // ======================= View Functions ================================\n\n /// @notice Checks if the `_srcAddress` corresponds to the trusted source\n function isTrustedRemote(uint16 _srcChainId, bytes calldata _srcAddress) external view returns (bool) {\n bytes memory trustedSource = trustedRemoteLookup[_srcChainId];\n return keccak256(trustedSource) == keccak256(_srcAddress);\n }\n\n uint256[46] private __gap;\n}\n" + }, + "contracts/deprecated/layerZero/OldOFTCore.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.12;\n\nimport \"./OldNonblockingLzApp.sol\";\nimport \"../../agToken/layerZero/utils/IOFTCore.sol\";\nimport \"@openzeppelin/contracts-upgradeable/utils/introspection/ERC165Upgradeable.sol\";\n\n/// @title OFTCore\n/// @author Forked from https://github.com/LayerZero-Labs/solidity-examples/blob/main/contracts/token/oft/OFTCore.sol\n/// but with slight modifications from the Angle Labs, Inc. which added return values to the `_creditTo` and `_debitFrom` functions\n/// @notice Base contract for bridging using LayerZero\nabstract contract OldOFTCore is OldNonblockingLzApp, ERC165Upgradeable, IOFTCore {\n // ==================== External Permissionless Functions ======================\n\n /// @inheritdoc IOFTCore\n function sendWithPermit(\n uint16 _dstChainId,\n bytes memory _toAddress,\n uint256 _amount,\n address payable _refundAddress,\n address _zroPaymentAddress,\n bytes memory _adapterParams,\n uint256 deadline,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) public payable virtual;\n\n /// @inheritdoc IOFTCore\n function send(\n uint16 _dstChainId,\n bytes memory _toAddress,\n uint256 _amount,\n address payable _refundAddress,\n address _zroPaymentAddress,\n bytes memory _adapterParams\n ) public payable virtual {\n _amount = _debitFrom(_dstChainId, _toAddress, _amount);\n\n bytes memory payload = abi.encode(_toAddress, _amount);\n _lzSend(_dstChainId, payload, _refundAddress, _zroPaymentAddress, _adapterParams);\n\n uint64 nonce = lzEndpoint.getOutboundNonce(_dstChainId, address(this));\n emit SendToChain(msg.sender, _dstChainId, _toAddress, _amount, nonce);\n }\n\n /// @inheritdoc IOFTCore\n function sendCredit(\n uint16 _dstChainId,\n bytes memory _toAddress,\n uint256 _amount,\n address payable _refundAddress,\n address _zroPaymentAddress,\n bytes memory _adapterParams\n ) public payable virtual {\n _amount = _debitCreditFrom(_dstChainId, _toAddress, _amount);\n\n _send(_dstChainId, _toAddress, _amount, _refundAddress, _zroPaymentAddress, _adapterParams);\n }\n\n /// @inheritdoc IOFTCore\n function withdraw(uint256 amount, address recipient) external virtual returns (uint256);\n\n // =========================== Internal Functions ==============================\n\n /// @notice Internal function to send `_amount` amount of token to (`_dstChainId`, `_toAddress`)\n /// @param _dstChainId the destination chain identifier\n /// @param _toAddress can be any size depending on the `dstChainId`.\n /// @param _amount the quantity of tokens in wei\n /// @param _refundAddress the address LayerZero refunds if too much message fee is sent\n /// @param _zroPaymentAddress set to address(0x0) if not paying in ZRO (LayerZero Token)\n /// @param _adapterParams is a flexible bytes array to indicate messaging adapter services\n /// @dev Accounting and checks should be performed beforehand\n function _send(\n uint16 _dstChainId,\n bytes memory _toAddress,\n uint256 _amount,\n address payable _refundAddress,\n address _zroPaymentAddress,\n bytes memory _adapterParams\n ) internal {\n bytes memory payload = abi.encode(_toAddress, _amount);\n _lzSend(_dstChainId, payload, _refundAddress, _zroPaymentAddress, _adapterParams);\n\n uint64 nonce = lzEndpoint.getOutboundNonce(_dstChainId, address(this));\n emit SendToChain(msg.sender, _dstChainId, _toAddress, _amount, nonce);\n }\n\n function _nonblockingLzReceive(\n uint16 _srcChainId,\n bytes memory _srcAddress,\n uint64 _nonce,\n bytes memory _payload\n ) internal virtual override {\n // decode and load the toAddress\n (bytes memory toAddressBytes, uint256 amount) = abi.decode(_payload, (bytes, uint256));\n address toAddress;\n //solhint-disable-next-line\n assembly {\n toAddress := mload(add(toAddressBytes, 20))\n }\n amount = _creditTo(_srcChainId, toAddress, amount);\n\n emit ReceiveFromChain(_srcChainId, _srcAddress, toAddress, amount, _nonce);\n }\n\n /// @notice Makes accountability when bridging from this contract using canonical token\n /// @param _dstChainId ChainId of the destination chain - LayerZero standard\n /// @param _toAddress Recipient on the destination chain\n /// @param _amount Amount to bridge\n function _debitFrom(\n uint16 _dstChainId,\n bytes memory _toAddress,\n uint256 _amount\n ) internal virtual returns (uint256);\n\n /// @notice Makes accountability when bridging from this contract's credit\n /// @param _dstChainId ChainId of the destination chain - LayerZero standard\n /// @param _toAddress Recipient on the destination chain\n /// @param _amount Amount to bridge\n function _debitCreditFrom(\n uint16 _dstChainId,\n bytes memory _toAddress,\n uint256 _amount\n ) internal virtual returns (uint256);\n\n /// @notice Makes accountability when bridging to this contract\n /// @param _srcChainId ChainId of the source chain - LayerZero standard\n /// @param _toAddress Recipient on this chain\n /// @param _amount Amount to bridge\n function _creditTo(uint16 _srcChainId, address _toAddress, uint256 _amount) internal virtual returns (uint256);\n\n // ========================== View Functions ===================================\n\n /// @inheritdoc ERC165Upgradeable\n function supportsInterface(\n bytes4 interfaceId\n ) public view virtual override(ERC165Upgradeable, IERC165) returns (bool) {\n return interfaceId == type(IOFTCore).interfaceId || super.supportsInterface(interfaceId);\n }\n\n /// @inheritdoc IOFTCore\n function estimateSendFee(\n uint16 _dstChainId,\n bytes memory _toAddress,\n uint256 _amount,\n bool _useZro,\n bytes memory _adapterParams\n ) public view virtual override returns (uint256 nativeFee, uint256 zroFee) {\n // mock the payload for send()\n bytes memory payload = abi.encode(_toAddress, _amount);\n return lzEndpoint.estimateFees(_dstChainId, address(this), payload, _useZro, _adapterParams);\n }\n\n uint256[50] private __gap;\n}\n" + }, + "contracts/deprecated/OldAgEUR.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\nimport \"../interfaces/IAgToken.sol\";\nimport \"../interfaces/coreModule/IStableMaster.sol\";\nimport \"../interfaces/ITreasury.sol\";\n// OpenZeppelin may update its version of the ERC20PermitUpgradeable token\nimport \"@openzeppelin/contracts-upgradeable/token/ERC20/extensions/draft-ERC20PermitUpgradeable.sol\";\n\n/// @title AgToken\n/// @author Angle Labs, Inc.\n/// @notice Base contract for agToken, that is to say Angle's stablecoins\n/// @dev This contract is used to create and handle the stablecoins of Angle protocol\n/// @dev It is still possible for any address to burn its agTokens without redeeming collateral in exchange\n/// @dev This contract is the upgraded version of the AgToken that was first deployed on Ethereum mainnet\ncontract OldAgEUR is IAgToken, ERC20PermitUpgradeable {\n // ========================= References to other contracts =====================\n\n /// @notice Reference to the `StableMaster` contract associated to this `AgToken`\n address public stableMaster;\n\n // ============================= Constructor ===================================\n\n /// @notice Initializes the `AgToken` contract\n /// @param name_ Name of the token\n /// @param symbol_ Symbol of the token\n /// @param stableMaster_ Reference to the `StableMaster` contract associated to this agToken\n /// @dev By default, agTokens are ERC-20 tokens with 18 decimals\n function initialize(string memory name_, string memory symbol_, address stableMaster_) external initializer {\n __ERC20Permit_init(name_);\n __ERC20_init(name_, symbol_);\n require(stableMaster_ != address(0), \"0\");\n stableMaster = stableMaster_;\n }\n\n /// @custom:oz-upgrades-unsafe-allow constructor\n constructor() initializer {}\n\n // ======= Added Parameters and Variables from the first implementation ========\n\n /// @inheritdoc IAgToken\n mapping(address => bool) public isMinter;\n /// @notice Reference to the treasury contract which can grant minting rights\n address public treasury;\n /// @notice Boolean to check whether the contract has been reinitialized after its upgrade\n bool public treasuryInitialized;\n\n // =============================== Added Events ================================\n\n event TreasuryUpdated(address indexed _treasury);\n event MinterToggled(address indexed minter);\n\n // =============================== Added Errors ================================\n\n error BurnAmountExceedsAllowance();\n error InvalidSender();\n error InvalidTreasury();\n error NotGovernor();\n error NotMinter();\n error NotTreasury();\n error TreasuryAlreadyInitialized();\n\n // =============================== Setup Function ==============================\n\n /// @notice Sets up the treasury contract in this AgToken contract\n /// @param _treasury Treasury contract to add\n /// @dev The address calling this function has to be hard-coded in the contract\n /// @dev Can be called only once\n function setUpTreasury(address _treasury) external {\n // Only governor\n if (msg.sender != 0xdC4e6DFe07EFCa50a197DF15D9200883eF4Eb1c8) revert NotGovernor();\n if (address(ITreasury(_treasury).stablecoin()) != address(this)) revert InvalidTreasury();\n if (treasuryInitialized) revert TreasuryAlreadyInitialized();\n treasury = _treasury;\n treasuryInitialized = true;\n isMinter[stableMaster] = true;\n emit TreasuryUpdated(_treasury);\n }\n\n // =============================== Modifiers ===================================\n\n /// @notice Checks to see if it is the `Treasury` calling this contract\n /// @dev There is no Access Control here, because it can be handled cheaply through this modifier\n modifier onlyTreasury() {\n if (msg.sender != treasury) revert NotTreasury();\n _;\n }\n\n /// @notice Checks whether the sender has the minting right\n modifier onlyMinter() {\n if (!isMinter[msg.sender]) revert NotMinter();\n _;\n }\n\n // ========================= External Functions ================================\n // The following functions allow anyone to burn stablecoins without redeeming collateral\n // in exchange for that\n\n /// @notice Destroys `amount` token from the caller without giving collateral back\n /// @param amount Amount to burn\n /// @param poolManager Reference to the `PoolManager` contract for which the `stocksUsers` will\n /// need to be updated\n /// @dev When calling this function, people should specify the `poolManager` for which they want to decrease\n /// the `stocksUsers`: this is a way for the protocol to maintain healthy accounting variables\n function burnNoRedeem(uint256 amount, address poolManager) external {\n _burn(msg.sender, amount);\n IStableMaster(stableMaster).updateStocksUsers(amount, poolManager);\n }\n\n /// @notice Burns `amount` of agToken on behalf of another account without redeeming collateral back\n /// @param account Account to burn on behalf of\n /// @param amount Amount to burn\n /// @param poolManager Reference to the `PoolManager` contract for which the `stocksUsers` will need to be updated\n function burnFromNoRedeem(address account, uint256 amount, address poolManager) external {\n _burnFromNoRedeem(amount, account, msg.sender);\n IStableMaster(stableMaster).updateStocksUsers(amount, poolManager);\n }\n\n /// @notice Allows anyone to burn agToken without redeeming collateral back\n /// @param amount Amount of stablecoins to burn\n /// @dev This function can typically be called if there is a settlement mechanism to burn stablecoins\n function burnStablecoin(uint256 amount) external {\n _burn(msg.sender, amount);\n }\n\n // ======================= Minter Role Only Functions ==========================\n\n /// @inheritdoc IAgToken\n function burnSelf(uint256 amount, address burner) external onlyMinter {\n _burn(burner, amount);\n }\n\n /// @inheritdoc IAgToken\n function burnFrom(uint256 amount, address burner, address sender) external onlyMinter {\n _burnFromNoRedeem(amount, burner, sender);\n }\n\n /// @inheritdoc IAgToken\n function mint(address account, uint256 amount) external onlyMinter {\n _mint(account, amount);\n }\n\n // ======================= Treasury Only Functions =============================\n\n /// @inheritdoc IAgToken\n function addMinter(address minter) external onlyTreasury {\n isMinter[minter] = true;\n emit MinterToggled(minter);\n }\n\n /// @inheritdoc IAgToken\n function removeMinter(address minter) external {\n // The `treasury` contract cannot remove the `stableMaster`\n if (msg.sender != minter && (msg.sender != address(treasury) || minter == stableMaster)) revert InvalidSender();\n isMinter[minter] = false;\n emit MinterToggled(minter);\n }\n\n /// @inheritdoc IAgToken\n function setTreasury(address _treasury) external onlyTreasury {\n treasury = _treasury;\n emit TreasuryUpdated(_treasury);\n }\n\n // ============================ Internal Function ==============================\n\n /// @notice Internal version of the function `burnFromNoRedeem`\n /// @param amount Amount to burn\n /// @dev It is at the level of this function that allowance checks are performed\n function _burnFromNoRedeem(uint256 amount, address burner, address sender) internal {\n if (burner != sender) {\n uint256 currentAllowance = allowance(burner, sender);\n if (currentAllowance < amount) revert BurnAmountExceedsAllowance();\n _approve(burner, sender, currentAllowance - amount);\n }\n _burn(burner, amount);\n }\n}\n" + }, + "contracts/deprecated/OldAngleHelpers.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\nimport \"../interfaces/IAngleRouter.sol\";\nimport \"../interfaces/coreModule/IAgTokenMainnet.sol\";\nimport \"../interfaces/coreModule/ICore.sol\";\nimport \"../interfaces/coreModule/IOracleCore.sol\";\nimport \"../interfaces/coreModule/IPerpetualManager.sol\";\nimport \"../interfaces/coreModule/IPoolManager.sol\";\nimport \"../interfaces/coreModule/IStableMaster.sol\";\nimport \"@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol\";\nimport \"../interfaces/IVaultManager.sol\";\n\npragma solidity ^0.8.12;\n\nstruct Parameters {\n SLPData slpData;\n MintBurnData feeData;\n PerpetualManagerFeeData perpFeeData;\n PerpetualManagerParamData perpParam;\n}\n\nstruct PerpetualManagerFeeData {\n uint64[] xHAFeesDeposit;\n uint64[] yHAFeesDeposit;\n uint64[] xHAFeesWithdraw;\n uint64[] yHAFeesWithdraw;\n uint64 haBonusMalusDeposit;\n uint64 haBonusMalusWithdraw;\n}\n\nstruct PerpetualManagerParamData {\n uint64 maintenanceMargin;\n uint64 maxLeverage;\n uint64 targetHAHedge;\n uint64 limitHAHedge;\n uint64 lockTime;\n}\n\nstruct CollateralAddresses {\n address stableMaster;\n address poolManager;\n address perpetualManager;\n address sanToken;\n address oracle;\n address gauge;\n address feeManager;\n address[] strategies;\n}\n\n/// @title AngleHelpers\n/// @author Angle Labs, Inc.\n/// @notice Contract with view functions designed to facilitate integrations on the Core module of the Angle Protocol\n/// @dev This contract only contains view functions to be queried off-chain. It was thus not optimized for gas consumption\ncontract OldAngleHelpers is Initializable {\n // ======================== Helper View Functions ==============================\n\n /// @notice Gives the amount of `agToken` you'd be getting if you were executing in the same block a mint transaction\n /// with `amount` of `collateral` in the Core module of the Angle protocol as well as the value of the fees\n /// (in `BASE_PARAMS`) that would be applied during the mint\n /// @return Amount of `agToken` that would be obtained with a mint transaction in the same block\n /// @return Percentage of fees that would be taken during a mint transaction in the same block\n /// @dev This function reverts if the mint transaction was to revert in the same conditions (without taking into account\n /// potential approval problems to the `StableMaster` contract)\n function previewMintAndFees(\n uint256 amount,\n address agToken,\n address collateral\n ) external view returns (uint256, uint256) {\n return _previewMintAndFees(amount, agToken, collateral);\n }\n\n /// @notice Gives the amount of `collateral` you'd be getting if you were executing in the same block a burn transaction\n /// with `amount` of `agToken` in the Core module of the Angle protocol as well as the value of the fees\n /// (in `BASE_PARAMS`) that would be applied during the burn\n /// @return Amount of `collateral` that would be obtained with a burn transaction in the same block\n /// @return Percentage of fees that would be taken during a burn transaction in the same block\n /// @dev This function reverts if the burn transaction was to revert in the same conditions (without taking into account\n /// potential approval problems to the `StableMaster` contract or agToken balance prior to the call)\n function previewBurnAndFees(\n uint256 amount,\n address agToken,\n address collateral\n ) external view returns (uint256, uint256) {\n return _previewBurnAndFees(amount, agToken, collateral);\n }\n\n /// @notice Returns all the addresses associated to the (`agToken`,`collateral`) pair given\n /// @return addresses A struct with all the addresses associated in the Core module\n function getCollateralAddresses(\n address agToken,\n address collateral\n ) external view returns (CollateralAddresses memory addresses) {\n address stableMaster = IAgTokenMainnet(agToken).stableMaster();\n (address poolManager, address perpetualManager, address sanToken, address gauge) = ROUTER.mapPoolManagers(\n stableMaster,\n collateral\n );\n (, , , IOracleCore oracle, , , , , ) = IStableMaster(stableMaster).collateralMap(poolManager);\n addresses.stableMaster = stableMaster;\n addresses.poolManager = poolManager;\n addresses.perpetualManager = perpetualManager;\n addresses.sanToken = sanToken;\n addresses.gauge = gauge;\n addresses.oracle = address(oracle);\n addresses.feeManager = IPoolManager(poolManager).feeManager();\n\n uint256 length = 0;\n while (true) {\n try IPoolManager(poolManager).strategyList(length) returns (address) {\n length += 1;\n } catch {\n break;\n }\n }\n address[] memory strategies = new address[](length);\n for (uint256 i; i < length; ++i) {\n strategies[i] = IPoolManager(poolManager).strategyList(i);\n }\n addresses.strategies = strategies;\n }\n\n /// @notice Gets the addresses of all the `StableMaster` contracts and their associated `AgToken` addresses\n /// @return List of the `StableMaster` addresses of the Angle protocol\n /// @return List of the `AgToken` addresses of the protocol\n /// @dev The place of an agToken address in the list is the same as the corresponding `StableMaster` address\n function getStablecoinAddresses() external view returns (address[] memory, address[] memory) {\n address[] memory stableMasterAddresses = CORE.stablecoinList();\n address[] memory agTokenAddresses = new address[](stableMasterAddresses.length);\n for (uint256 i; i < stableMasterAddresses.length; ++i) {\n agTokenAddresses[i] = IStableMaster(stableMasterAddresses[i]).agToken();\n }\n return (stableMasterAddresses, agTokenAddresses);\n }\n\n /// @notice Returns most of the governance parameters associated to the (`agToken`,`collateral`) pair given\n /// @return params Struct with most of the parameters in the `StableMaster` and `PerpetualManager` contracts\n /// @dev Check out the struct `Parameters` for the meaning of the return values\n function getCollateralParameters(\n address agToken,\n address collateral\n ) external view returns (Parameters memory params) {\n (address stableMaster, address poolManager) = _getStableMasterAndPoolManager(agToken, collateral);\n (\n ,\n ,\n IPerpetualManager perpetualManager,\n ,\n ,\n ,\n ,\n SLPData memory slpData,\n MintBurnData memory feeData\n ) = IStableMaster(stableMaster).collateralMap(poolManager);\n\n params.slpData = slpData;\n params.feeData = feeData;\n params.perpParam.maintenanceMargin = perpetualManager.maintenanceMargin();\n params.perpParam.maxLeverage = perpetualManager.maxLeverage();\n params.perpParam.targetHAHedge = perpetualManager.targetHAHedge();\n params.perpParam.limitHAHedge = perpetualManager.limitHAHedge();\n params.perpParam.lockTime = perpetualManager.lockTime();\n\n params.perpFeeData.haBonusMalusDeposit = perpetualManager.haBonusMalusDeposit();\n params.perpFeeData.haBonusMalusWithdraw = perpetualManager.haBonusMalusWithdraw();\n\n uint256 length = 0;\n while (true) {\n try perpetualManager.xHAFeesDeposit(length) returns (uint64) {\n length += 1;\n } catch {\n break;\n }\n }\n uint64[] memory data = new uint64[](length);\n uint64[] memory data2 = new uint64[](length);\n for (uint256 i; i < length; ++i) {\n data[i] = perpetualManager.xHAFeesDeposit(i);\n data2[i] = perpetualManager.yHAFeesDeposit(i);\n }\n params.perpFeeData.xHAFeesDeposit = data;\n params.perpFeeData.yHAFeesDeposit = data2;\n\n length = 0;\n while (true) {\n try perpetualManager.xHAFeesWithdraw(length) returns (uint64) {\n length += 1;\n } catch {\n break;\n }\n }\n data = new uint64[](length);\n data2 = new uint64[](length);\n for (uint256 i; i < length; ++i) {\n data[i] = perpetualManager.xHAFeesWithdraw(i);\n data2[i] = perpetualManager.yHAFeesWithdraw(i);\n }\n params.perpFeeData.xHAFeesWithdraw = data;\n params.perpFeeData.yHAFeesWithdraw = data2;\n }\n\n /// @notice Returns the address of the poolManager associated to an (`agToken`, `collateral`) pair\n /// in the Core module of the protocol\n function getPoolManager(address agToken, address collateral) public view returns (address poolManager) {\n (, poolManager) = _getStableMasterAndPoolManager(agToken, collateral);\n }\n\n // ======================== Replica Functions ==================================\n // These replicate what is done in the other contracts of the protocol\n\n function _previewBurnAndFees(\n uint256 amount,\n address agToken,\n address collateral\n ) internal view returns (uint256 amountForUserInCollat, uint256 feePercent) {\n (address stableMaster, address poolManager) = _getStableMasterAndPoolManager(agToken, collateral);\n (\n address token,\n ,\n IPerpetualManager perpetualManager,\n IOracleCore oracle,\n uint256 stocksUsers,\n ,\n uint256 collatBase,\n ,\n MintBurnData memory feeData\n ) = IStableMaster(stableMaster).collateralMap(poolManager);\n if (token == address(0) || IStableMaster(stableMaster).paused(keccak256(abi.encodePacked(STABLE, poolManager))))\n revert NotInitialized();\n if (amount > stocksUsers) revert InvalidAmount();\n\n if (feeData.xFeeBurn.length == 1) {\n feePercent = feeData.yFeeBurn[0];\n } else {\n bytes memory data = abi.encode(address(perpetualManager), feeData.targetHAHedge);\n uint64 hedgeRatio = _computeHedgeRatio(stocksUsers - amount, data);\n feePercent = _piecewiseLinear(hedgeRatio, feeData.xFeeBurn, feeData.yFeeBurn);\n }\n feePercent = (feePercent * feeData.bonusMalusBurn) / BASE_PARAMS;\n\n amountForUserInCollat = (amount * (BASE_PARAMS - feePercent) * collatBase) / (oracle.readUpper() * BASE_PARAMS);\n }\n\n function _previewMintAndFees(\n uint256 amount,\n address agToken,\n address collateral\n ) internal view returns (uint256 amountForUserInStable, uint256 feePercent) {\n (address stableMaster, address poolManager) = _getStableMasterAndPoolManager(agToken, collateral);\n (\n address token,\n ,\n IPerpetualManager perpetualManager,\n IOracleCore oracle,\n uint256 stocksUsers,\n ,\n ,\n ,\n MintBurnData memory feeData\n ) = IStableMaster(stableMaster).collateralMap(poolManager);\n if (token == address(0) || IStableMaster(stableMaster).paused(keccak256(abi.encodePacked(STABLE, poolManager))))\n revert NotInitialized();\n\n amountForUserInStable = oracle.readQuoteLower(amount);\n\n if (feeData.xFeeMint.length == 1) feePercent = feeData.yFeeMint[0];\n else {\n bytes memory data = abi.encode(address(perpetualManager), feeData.targetHAHedge);\n uint64 hedgeRatio = _computeHedgeRatio(amountForUserInStable + stocksUsers, data);\n feePercent = _piecewiseLinear(hedgeRatio, feeData.xFeeMint, feeData.yFeeMint);\n }\n feePercent = (feePercent * feeData.bonusMalusMint) / BASE_PARAMS;\n\n amountForUserInStable = (amountForUserInStable * (BASE_PARAMS - feePercent)) / BASE_PARAMS;\n if (stocksUsers + amountForUserInStable > feeData.capOnStableMinted) revert InvalidAmount();\n }\n\n // ======================== Utility Functions ==================================\n // These utility functions are taken from other contracts of the protocol\n\n function _computeHedgeRatio(uint256 newStocksUsers, bytes memory data) internal view returns (uint64 ratio) {\n (address perpetualManager, uint64 targetHAHedge) = abi.decode(data, (address, uint64));\n uint256 totalHedgeAmount = IPerpetualManager(perpetualManager).totalHedgeAmount();\n newStocksUsers = (targetHAHedge * newStocksUsers) / BASE_PARAMS;\n if (newStocksUsers > totalHedgeAmount) ratio = uint64((totalHedgeAmount * BASE_PARAMS) / newStocksUsers);\n else ratio = uint64(BASE_PARAMS);\n }\n\n function _piecewiseLinear(uint64 x, uint64[] memory xArray, uint64[] memory yArray) internal pure returns (uint64) {\n if (x >= xArray[xArray.length - 1]) {\n return yArray[xArray.length - 1];\n } else if (x <= xArray[0]) {\n return yArray[0];\n } else {\n uint256 lower;\n uint256 upper = xArray.length - 1;\n uint256 mid;\n while (upper - lower > 1) {\n mid = lower + (upper - lower) / 2;\n if (xArray[mid] <= x) {\n lower = mid;\n } else {\n upper = mid;\n }\n }\n if (yArray[upper] > yArray[lower]) {\n return\n yArray[lower] +\n ((yArray[upper] - yArray[lower]) * (x - xArray[lower])) /\n (xArray[upper] - xArray[lower]);\n } else {\n return\n yArray[lower] -\n ((yArray[lower] - yArray[upper]) * (x - xArray[lower])) /\n (xArray[upper] - xArray[lower]);\n }\n }\n }\n\n function _getStableMasterAndPoolManager(\n address agToken,\n address collateral\n ) internal view returns (address stableMaster, address poolManager) {\n stableMaster = IAgTokenMainnet(agToken).stableMaster();\n (poolManager, , , ) = ROUTER.mapPoolManagers(stableMaster, collateral);\n }\n\n // ====================== Constants and Initializers ===========================\n\n IAngleRouter public constant ROUTER = IAngleRouter(0xBB755240596530be0c1DE5DFD77ec6398471561d);\n ICore public constant CORE = ICore(0x61ed74de9Ca5796cF2F8fD60D54160D47E30B7c3);\n\n bytes32 public constant STABLE = keccak256(\"STABLE\");\n uint256 public constant BASE_PARAMS = 10 ** 9;\n\n error NotInitialized();\n error InvalidAmount();\n\n /// @custom:oz-upgrades-unsafe-allow constructor\n constructor() initializer {}\n}\n" + }, + "contracts/deprecated/vaultManager/OldVaultManagerERC721.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\nimport \"./OldVaultManagerStorage.sol\";\n\n/// @title VaultManagerERC721\n/// @author Angle Labs, Inc.\n/// @dev Base ERC721 Implementation of VaultManager\nabstract contract OldVaultManagerERC721 is IERC721MetadataUpgradeable, OldVaultManagerStorage {\n using SafeERC20 for IERC20;\n using Address for address;\n\n /// @inheritdoc IERC721MetadataUpgradeable\n string public name;\n /// @inheritdoc IERC721MetadataUpgradeable\n string public symbol;\n\n // ================================= MODIFIERS =================================\n\n /// @notice Checks if the person interacting with the vault with `vaultID` is approved\n /// @param caller Address of the person seeking to interact with the vault\n /// @param vaultID ID of the concerned vault\n modifier onlyApprovedOrOwner(address caller, uint256 vaultID) {\n if (!_isApprovedOrOwner(caller, vaultID)) revert NotApproved();\n _;\n }\n\n // ================================ ERC721 LOGIC ===============================\n\n /// @notice Checks whether a given address is approved for a vault or owns this vault\n /// @param spender Address for which vault ownership should be checked\n /// @param vaultID ID of the vault to check\n /// @return Whether the `spender` address owns or is approved for `vaultID`\n function isApprovedOrOwner(address spender, uint256 vaultID) external view returns (bool) {\n return _isApprovedOrOwner(spender, vaultID);\n }\n\n /// @inheritdoc IERC721MetadataUpgradeable\n function tokenURI(uint256 vaultID) external view returns (string memory) {\n if (!_exists(vaultID)) revert NonexistentVault();\n // There is no vault with `vaultID` equal to 0, so the following variable is\n // always greater than zero\n uint256 temp = vaultID;\n uint256 digits;\n while (temp != 0) {\n digits++;\n temp /= 10;\n }\n bytes memory buffer = new bytes(digits);\n while (vaultID != 0) {\n digits -= 1;\n buffer[digits] = bytes1(uint8(48 + uint256(vaultID % 10)));\n vaultID /= 10;\n }\n return bytes(_baseURI).length > 0 ? string(abi.encodePacked(_baseURI, string(buffer))) : \"\";\n }\n\n /// @inheritdoc IERC721Upgradeable\n function balanceOf(address owner) external view returns (uint256) {\n if (owner == address(0)) revert ZeroAddress();\n return _balances[owner];\n }\n\n /// @inheritdoc IERC721Upgradeable\n function ownerOf(uint256 vaultID) external view returns (address) {\n return _ownerOf(vaultID);\n }\n\n /// @inheritdoc IERC721Upgradeable\n function approve(address to, uint256 vaultID) external {\n address owner = _ownerOf(vaultID);\n if (to == owner) revert ApprovalToOwner();\n if (msg.sender != owner && !isApprovedForAll(owner, msg.sender)) revert NotApproved();\n\n _approve(to, vaultID);\n }\n\n /// @inheritdoc IERC721Upgradeable\n function getApproved(uint256 vaultID) external view returns (address) {\n if (!_exists(vaultID)) revert NonexistentVault();\n return _getApproved(vaultID);\n }\n\n /// @inheritdoc IERC721Upgradeable\n function setApprovalForAll(address operator, bool approved) external {\n _setApprovalForAll(msg.sender, operator, approved);\n }\n\n /// @inheritdoc IERC721Upgradeable\n function isApprovedForAll(address owner, address operator) public view returns (bool) {\n return _operatorApprovals[owner][operator] == 1;\n }\n\n /// @inheritdoc IERC721Upgradeable\n function transferFrom(address from, address to, uint256 vaultID) external onlyApprovedOrOwner(msg.sender, vaultID) {\n _transfer(from, to, vaultID);\n }\n\n /// @inheritdoc IERC721Upgradeable\n function safeTransferFrom(address from, address to, uint256 vaultID) external {\n safeTransferFrom(from, to, vaultID, \"\");\n }\n\n /// @inheritdoc IERC721Upgradeable\n function safeTransferFrom(\n address from,\n address to,\n uint256 vaultID,\n bytes memory _data\n ) public onlyApprovedOrOwner(msg.sender, vaultID) {\n _safeTransfer(from, to, vaultID, _data);\n }\n\n // ================================ ERC165 LOGIC ===============================\n\n /// @inheritdoc IERC165Upgradeable\n function supportsInterface(bytes4 interfaceId) external pure returns (bool) {\n return\n interfaceId == type(IERC721MetadataUpgradeable).interfaceId ||\n interfaceId == type(IERC721Upgradeable).interfaceId ||\n interfaceId == type(IVaultManager).interfaceId ||\n interfaceId == type(IERC165Upgradeable).interfaceId;\n }\n\n // ================== INTERNAL FUNCTIONS FOR THE ERC721 LOGIC ==================\n\n /// @notice Internal version of the `ownerOf` function\n function _ownerOf(uint256 vaultID) internal view returns (address owner) {\n owner = _owners[vaultID];\n if (owner == address(0)) revert NonexistentVault();\n }\n\n /// @notice Internal version of the `getApproved` function\n function _getApproved(uint256 vaultID) internal view returns (address) {\n return _vaultApprovals[vaultID];\n }\n\n /// @notice Internal version of the `safeTransferFrom` function (with the data parameter)\n function _safeTransfer(address from, address to, uint256 vaultID, bytes memory _data) internal {\n _transfer(from, to, vaultID);\n if (!_checkOnERC721Received(from, to, vaultID, _data)) revert NonERC721Receiver();\n }\n\n /// @notice Checks whether a vault exists\n /// @param vaultID ID of the vault to check\n /// @return Whether `vaultID` has been created\n function _exists(uint256 vaultID) internal view returns (bool) {\n return _owners[vaultID] != address(0);\n }\n\n /// @notice Internal version of the `isApprovedOrOwner` function\n function _isApprovedOrOwner(address spender, uint256 vaultID) internal view returns (bool) {\n // The following checks if the vault exists\n address owner = _ownerOf(vaultID);\n return (spender == owner || _getApproved(vaultID) == spender || _operatorApprovals[owner][spender] == 1);\n }\n\n /// @notice Internal version of the `createVault` function\n /// Mints `vaultID` and transfers it to `to`\n /// @dev This method is equivalent to the `_safeMint` method used in OpenZeppelin ERC721 contract\n /// @dev Emits a {Transfer} event\n function _mint(address to) internal returns (uint256 vaultID) {\n if (whitelistingActivated && (isWhitelisted[to] != 1 || isWhitelisted[msg.sender] != 1))\n revert NotWhitelisted();\n if (to == address(0)) revert ZeroAddress();\n\n unchecked {\n vaultIDCount += 1;\n }\n\n vaultID = vaultIDCount;\n _beforeTokenTransfer(address(0), to, vaultID);\n\n unchecked {\n _balances[to] += 1;\n }\n\n _owners[vaultID] = to;\n emit Transfer(address(0), to, vaultID);\n if (!_checkOnERC721Received(address(0), to, vaultID, \"\")) revert NonERC721Receiver();\n }\n\n /// @notice Destroys `vaultID`\n /// @dev `vaultID` must exist\n /// @dev Emits a {Transfer} event\n function _burn(uint256 vaultID) internal {\n address owner = _ownerOf(vaultID);\n\n _beforeTokenTransfer(owner, address(0), vaultID);\n // Clear approvals\n _approve(address(0), vaultID);\n // The following line cannot underflow as the owner's balance is necessarily\n // greater than 1\n unchecked {\n _balances[owner] -= 1;\n }\n delete _owners[vaultID];\n delete vaultData[vaultID];\n\n emit Transfer(owner, address(0), vaultID);\n }\n\n /// @notice Transfers `vaultID` from `from` to `to` as opposed to {transferFrom},\n /// this imposes no restrictions on msg.sender\n /// @dev `to` cannot be the zero address and `perpetualID` must be owned by `from`\n /// @dev Emits a {Transfer} event\n /// @dev A whitelist check is performed if necessary on the `to` address\n function _transfer(address from, address to, uint256 vaultID) internal {\n if (_ownerOf(vaultID) != from) revert NotApproved();\n if (to == address(0)) revert ZeroAddress();\n if (whitelistingActivated && isWhitelisted[to] != 1) revert NotWhitelisted();\n\n _beforeTokenTransfer(from, to, vaultID);\n\n // Clear approvals from the previous owner\n _approve(address(0), vaultID);\n unchecked {\n _balances[from] -= 1;\n _balances[to] += 1;\n }\n _owners[vaultID] = to;\n\n emit Transfer(from, to, vaultID);\n }\n\n /// @notice Approves `to` to operate on `vaultID`\n function _approve(address to, uint256 vaultID) internal {\n _vaultApprovals[vaultID] = to;\n emit Approval(_ownerOf(vaultID), to, vaultID);\n }\n\n /// @notice Internal version of the `setApprovalForAll` function\n /// @dev It contains an `approver` field to be used in case someone signs a permit for a particular\n /// address, and this signature is given to the contract by another address (like a router)\n function _setApprovalForAll(address approver, address operator, bool approved) internal {\n if (operator == approver) revert ApprovalToCaller();\n uint256 approval = approved ? 1 : 0;\n _operatorApprovals[approver][operator] = approval;\n emit ApprovalForAll(approver, operator, approved);\n }\n\n /// @notice Internal function to invoke {IERC721Receiver-onERC721Received} on a target address\n /// The call is not executed if the target address is not a contract\n /// @param from Address representing the previous owner of the given token ID\n /// @param to Target address that will receive the tokens\n /// @param vaultID ID of the token to be transferred\n /// @param _data Bytes optional data to send along with the call\n /// @return Bool whether the call correctly returned the expected value\n function _checkOnERC721Received(\n address from,\n address to,\n uint256 vaultID,\n bytes memory _data\n ) private returns (bool) {\n if (to.isContract()) {\n try IERC721ReceiverUpgradeable(to).onERC721Received(msg.sender, from, vaultID, _data) returns (\n bytes4 retval\n ) {\n return retval == IERC721ReceiverUpgradeable.onERC721Received.selector;\n } catch (bytes memory reason) {\n if (reason.length == 0) {\n revert NonERC721Receiver();\n } else {\n // solhint-disable-next-line no-inline-assembly\n assembly {\n revert(add(32, reason), mload(reason))\n }\n }\n }\n } else {\n return true;\n }\n }\n\n /// @notice Hook that is called before any token transfer. This includes minting and burning.\n /// Calling conditions:\n ///\n /// - When `from` and `to` are both non-zero, `from`'s `vaultID` will be\n /// transferred to `to`.\n /// - When `from` is zero, `vaultID` will be minted for `to`.\n /// - When `to` is zero, `from`'s `vaultID` will be burned.\n /// - `from` and `to` are never both zero.\n function _beforeTokenTransfer(address from, address to, uint256 vaultID) internal virtual {}\n}\n" + }, + "contracts/deprecated/vaultManager/OldVaultManagerPermit.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\nimport \"./OldVaultManagerERC721.sol\";\nimport \"../../interfaces/external/IERC1271.sol\";\n\n/// @title VaultManagerPermit\n/// @author Angle Labs, Inc.\n/// @dev Base Implementation of permit functions for the `VaultManager` contract\nabstract contract OldVaultManagerPermit is Initializable, OldVaultManagerERC721 {\n using Address for address;\n\n mapping(address => uint256) private _nonces;\n /* solhint-disable var-name-mixedcase */\n bytes32 private _HASHED_NAME;\n bytes32 private _HASHED_VERSION;\n bytes32 private _PERMIT_TYPEHASH;\n /* solhint-enable var-name-mixedcase */\n\n error ExpiredDeadline();\n error InvalidSignature();\n\n //solhint-disable-next-line\n function __ERC721Permit_init(string memory _name) internal onlyInitializing {\n _PERMIT_TYPEHASH = keccak256(\n \"Permit(address owner,address spender,bool approved,uint256 nonce,uint256 deadline)\"\n );\n _HASHED_NAME = keccak256(bytes(_name));\n _HASHED_VERSION = keccak256(bytes(\"1\"));\n }\n\n /// @notice Allows an address to give or revoke approval for all its vaults to another address\n /// @param owner Address signing the permit and giving (or revoking) its approval for all the controlled vaults\n /// @param spender Address to give approval to\n /// @param approved Whether to give or revoke the approval\n /// @param deadline Deadline parameter for the signature to be valid\n /// @dev The `v`, `r`, and `s` parameters are used as signature data\n function permit(\n address owner,\n address spender,\n bool approved,\n uint256 deadline,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) external {\n if (block.timestamp > deadline) revert ExpiredDeadline();\n // Additional signature checks performed in the `ECDSAUpgradeable.recover` function\n if (uint256(s) > 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D576E7357A4501DDFE92F46681B20A0 || (v != 27 && v != 28))\n revert InvalidSignature();\n\n bytes32 digest = keccak256(\n abi.encodePacked(\n \"\\x19\\x01\",\n _domainSeparatorV4(),\n keccak256(\n abi.encode(\n _PERMIT_TYPEHASH,\n // 0x3f43a9c6bafb5c7aab4e0cfe239dc5d4c15caf0381c6104188191f78a6640bd8,\n owner,\n spender,\n approved,\n _useNonce(owner),\n deadline\n )\n )\n )\n );\n if (owner.isContract()) {\n if (IERC1271(owner).isValidSignature(digest, abi.encodePacked(r, s, v)) != 0x1626ba7e)\n revert InvalidSignature();\n } else {\n address signer = ecrecover(digest, v, r, s);\n if (signer != owner || signer == address(0)) revert InvalidSignature();\n }\n\n _setApprovalForAll(owner, spender, approved);\n }\n\n /// @notice Returns the current nonce for an `owner` address\n function nonces(address owner) public view returns (uint256) {\n return _nonces[owner];\n }\n\n /// @notice Returns the domain separator for the current chain.\n // solhint-disable-next-line func-name-mixedcase\n function DOMAIN_SEPARATOR() external view returns (bytes32) {\n return _domainSeparatorV4();\n }\n\n /// @notice Internal version of the `DOMAIN_SEPARATOR` function\n function _domainSeparatorV4() internal view returns (bytes32) {\n return\n keccak256(\n abi.encode(\n // keccak256('EIP712Domain(string name,string version,uint256 chainId,address verifyingContract)')\n 0x8b73c3c69bb8fe3d512ecc4cf759cc79239f7b179b0ffacaa9a75d522b39400f,\n _HASHED_NAME,\n _HASHED_VERSION,\n block.chainid,\n address(this)\n )\n );\n }\n\n /// @notice Consumes a nonce for an address: returns the current value and increments it\n function _useNonce(address owner) internal returns (uint256 current) {\n current = _nonces[owner];\n _nonces[owner] = current + 1;\n }\n\n uint256[49] private __gap;\n}\n" + }, + "contracts/deprecated/vaultManager/OldVaultManagerStorage.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\nimport \"@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/token/ERC20/extensions/draft-IERC20PermitUpgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/token/ERC721/IERC721ReceiverUpgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/interfaces/IERC721MetadataUpgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/utils/introspection/IERC165Upgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/utils/AddressUpgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/security/ReentrancyGuardUpgradeable.sol\";\nimport \"@openzeppelin/contracts/token/ERC20/extensions/IERC20Metadata.sol\";\nimport \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\nimport \"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\";\n\nimport \"../../interfaces/IAgToken.sol\";\nimport \"../../interfaces/IOracle.sol\";\nimport \"../../interfaces/ISwapper.sol\";\nimport \"../../interfaces/ITreasury.sol\";\nimport \"../../interfaces/IVaultManager.sol\";\nimport \"../../interfaces/governance/IVeBoostProxy.sol\";\n\n/// @title VaultManagerStorage\n/// @author Angle Labs, Inc.\n/// @dev Variables, references, parameters and events needed in the `VaultManager` contract\n// solhint-disable-next-line max-states-count\ncontract OldVaultManagerStorage is IVaultManagerStorage, Initializable, ReentrancyGuardUpgradeable {\n /// @notice Base used for parameter computation: almost all the parameters of this contract are set in `BASE_PARAMS`\n uint256 public constant BASE_PARAMS = 10 ** 9;\n /// @notice Base used for interest rate computation\n uint256 public constant BASE_INTEREST = 10 ** 27;\n /// @notice Used for interest rate computation\n uint256 public constant HALF_BASE_INTEREST = 10 ** 27 / 2;\n\n // ================================= REFERENCES ================================\n\n /// @inheritdoc IVaultManagerStorage\n ITreasury public treasury;\n /// @inheritdoc IVaultManagerStorage\n IERC20 public collateral;\n /// @inheritdoc IVaultManagerStorage\n IAgToken public stablecoin;\n /// @inheritdoc IVaultManagerStorage\n IOracle public oracle;\n /// @notice Reference to the contract which computes adjusted veANGLE balances for liquidators boosts\n IVeBoostProxy public veBoostProxy;\n /// @notice Base of the collateral\n uint256 internal _collatBase;\n\n // ================================= PARAMETERS ================================\n // Unless specified otherwise, parameters of this contract are expressed in `BASE_PARAMS`\n\n /// @notice Maximum amount of stablecoins that can be issued with this contract (in `BASE_TOKENS`). This parameter should\n /// not be bigger than `type(uint256).max / BASE_INTEREST` otherwise there may be some overflows in the `increaseDebt` function\n uint256 public debtCeiling;\n /// @notice Threshold veANGLE balance values for the computation of the boost for liquidators: the length of this array\n /// should normally be 2. The base of the x-values in this array should be `BASE_TOKENS`\n uint256[] public xLiquidationBoost;\n /// @notice Values of the liquidation boost at the threshold values of x\n uint256[] public yLiquidationBoost;\n /// @inheritdoc IVaultManagerStorage\n uint64 public collateralFactor;\n /// @notice Maximum Health factor at which a vault can end up after a liquidation (unless it's fully liquidated)\n uint64 public targetHealthFactor;\n /// @notice Upfront fee taken when borrowing stablecoins: this fee is optional and should in practice not be used\n uint64 public borrowFee;\n /// @notice Upfront fee taken when repaying stablecoins: this fee is optional as well. It should be smaller\n /// than the liquidation surcharge (cf below) to avoid exploits where people voluntarily get liquidated at a 0\n /// discount to pay smaller repaying fees\n uint64 public repayFee;\n /// @notice Per second interest taken to borrowers taking agToken loans. Contrarily to other parameters, it is set in `BASE_INTEREST`\n /// that is to say in base 10**27\n uint64 public interestRate;\n /// @notice Fee taken by the protocol during a liquidation. Technically, this value is not the fee per se, it's 1 - fee.\n /// For instance for a 2% fee, `liquidationSurcharge` should be 98%\n uint64 public liquidationSurcharge;\n /// @notice Maximum discount given to liquidators\n uint64 public maxLiquidationDiscount;\n /// @notice Whether whitelisting is required to own a vault or not\n bool public whitelistingActivated;\n /// @notice Whether the contract is paused or not\n bool public paused;\n\n // ================================= VARIABLES =================================\n\n /// @notice Timestamp at which the `interestAccumulator` was updated\n uint256 public lastInterestAccumulatorUpdated;\n /// @inheritdoc IVaultManagerStorage\n uint256 public interestAccumulator;\n /// @inheritdoc IVaultManagerStorage\n uint256 public totalNormalizedDebt;\n /// @notice Surplus accumulated by the contract: surplus is always in stablecoins, and is then reset\n /// when the value is communicated to the treasury contract\n uint256 public surplus;\n /// @notice Bad debt made from liquidated vaults which ended up having no collateral and a positive amount\n /// of stablecoins\n uint256 public badDebt;\n\n // ================================== MAPPINGS =================================\n\n /// @inheritdoc IVaultManagerStorage\n mapping(uint256 => Vault) public vaultData;\n /// @notice Maps an address to 1 if it's whitelisted and can open or own a vault\n mapping(address => uint256) public isWhitelisted;\n\n // ================================ ERC721 DATA ================================\n\n /// @inheritdoc IVaultManagerStorage\n uint256 public vaultIDCount;\n\n /// @notice URI\n string internal _baseURI;\n\n // Mapping from `vaultID` to owner address\n mapping(uint256 => address) internal _owners;\n\n // Mapping from owner address to vault owned count\n mapping(address => uint256) internal _balances;\n\n // Mapping from `vaultID` to approved address\n mapping(uint256 => address) internal _vaultApprovals;\n\n // Mapping from owner to operator approvals\n mapping(address => mapping(address => uint256)) internal _operatorApprovals;\n\n uint256[50] private __gap;\n\n // =================================== EVENTS ==================================\n\n event AccruedToTreasury(uint256 surplusEndValue, uint256 badDebtEndValue);\n event CollateralAmountUpdated(uint256 vaultID, uint256 collateralAmount, uint8 isIncrease);\n event InterestAccumulatorUpdated(uint256 value, uint256 timestamp);\n event InternalDebtUpdated(uint256 vaultID, uint256 internalAmount, uint8 isIncrease);\n event FiledUint64(uint64 param, bytes32 what);\n event DebtCeilingUpdated(uint256 debtCeiling);\n event LiquidationBoostParametersUpdated(address indexed _veBoostProxy, uint256[] xBoost, uint256[] yBoost);\n event LiquidatedVaults(uint256[] vaultIDs);\n event DebtTransferred(uint256 srcVaultID, uint256 dstVaultID, address dstVaultManager, uint256 amount);\n\n // =================================== ERRORS ==================================\n\n error ApprovalToOwner();\n error ApprovalToCaller();\n error DustyLeftoverAmount();\n error DebtCeilingExceeded();\n error HealthyVault();\n error IncompatibleLengths();\n error InsolventVault();\n error InvalidParameterValue();\n error InvalidParameterType();\n error InvalidSetOfParameters();\n error InvalidTreasury();\n error NonERC721Receiver();\n error NonexistentVault();\n error NotApproved();\n error NotGovernor();\n error NotGovernorOrGuardian();\n error NotTreasury();\n error NotWhitelisted();\n error NotVaultManager();\n error Paused();\n error TooHighParameterValue();\n error TooSmallParameterValue();\n error ZeroAddress();\n\n /// @custom:oz-upgrades-unsafe-allow constructor\n constructor() initializer {}\n}\n" + }, + "contracts/external/ProxyAdmin.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\nimport \"./TransparentUpgradeableProxy.sol\";\nimport \"@openzeppelin/contracts/access/Ownable.sol\";\n\n/**\n * @dev This is an auxiliary contract meant to be assigned as the admin of a {TransparentUpgradeableProxy}. For an\n * explanation of why you would want to use this see the documentation for {TransparentUpgradeableProxy}.\n * This contract was fully forked from OpenZeppelin `ProxyAdmin`\n */\ncontract ProxyAdmin is Ownable {\n /**\n * @dev Returns the current implementation of `proxy`.\n *\n * Requirements:\n *\n * - This contract must be the admin of `proxy`.\n */\n function getProxyImplementation(TransparentUpgradeableProxy proxy) public view virtual returns (address) {\n // We need to manually run the static call since the getter cannot be flagged as view\n // bytes4(keccak256(\"implementation()\")) == 0x5c60da1b\n (bool success, bytes memory returndata) = address(proxy).staticcall(hex\"5c60da1b\");\n require(success);\n return abi.decode(returndata, (address));\n }\n\n /**\n * @dev Returns the current admin of `proxy`.\n *\n * Requirements:\n *\n * - This contract must be the admin of `proxy`.\n */\n function getProxyAdmin(TransparentUpgradeableProxy proxy) public view virtual returns (address) {\n // We need to manually run the static call since the getter cannot be flagged as view\n // bytes4(keccak256(\"admin()\")) == 0xf851a440\n (bool success, bytes memory returndata) = address(proxy).staticcall(hex\"f851a440\");\n require(success);\n return abi.decode(returndata, (address));\n }\n\n /**\n * @dev Changes the admin of `proxy` to `newAdmin`.\n *\n * Requirements:\n *\n * - This contract must be the current admin of `proxy`.\n */\n function changeProxyAdmin(TransparentUpgradeableProxy proxy, address newAdmin) public virtual onlyOwner {\n proxy.changeAdmin(newAdmin);\n }\n\n /**\n * @dev Upgrades `proxy` to `implementation`. See {TransparentUpgradeableProxy-upgradeTo}.\n *\n * Requirements:\n *\n * - This contract must be the admin of `proxy`.\n */\n function upgrade(TransparentUpgradeableProxy proxy, address implementation) public virtual onlyOwner {\n proxy.upgradeTo(implementation);\n }\n\n /**\n * @dev Upgrades `proxy` to `implementation` and calls a function on the new implementation. See\n * {TransparentUpgradeableProxy-upgradeToAndCall}.\n *\n * Requirements:\n *\n * - This contract must be the admin of `proxy`.\n */\n function upgradeAndCall(\n TransparentUpgradeableProxy proxy,\n address implementation,\n bytes memory data\n ) public payable virtual onlyOwner {\n proxy.upgradeToAndCall{ value: msg.value }(implementation, data);\n }\n}\n" + }, + "contracts/external/TransparentUpgradeableProxy.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\nimport \"@openzeppelin/contracts/proxy/ERC1967/ERC1967Proxy.sol\";\n\n/**\n * @dev This contract implements a proxy that is upgradeable by an admin. It is fully forked from OpenZeppelin\n * `TransparentUpgradeableProxy`\n *\n * To avoid https://medium.com/nomic-labs-blog/malicious-backdoors-in-ethereum-proxies-62629adf3357[proxy selector\n * clashing], which can potentially be used in an attack, this contract uses the\n * https://blog.openzeppelin.com/the-transparent-proxy-pattern/[transparent proxy pattern]. This pattern implies two\n * things that go hand in hand:\n *\n * 1. If any account other than the admin calls the proxy, the call will be forwarded to the implementation, even if\n * that call matches one of the admin functions exposed by the proxy itself.\n * 2. If the admin calls the proxy, it can access the admin functions, but its calls will never be forwarded to the\n * implementation. If the admin tries to call a function on the implementation it will fail with an error that says\n * \"admin cannot fallback to proxy target\".\n *\n * These properties mean that the admin account can only be used for admin actions like upgrading the proxy or changing\n * the admin, so it's best if it's a dedicated account that is not used for anything else. This will avoid headaches due\n * to sudden errors when trying to call a function from the proxy implementation.\n *\n * Our recommendation is for the dedicated account to be an instance of the {ProxyAdmin} contract. If set up this way,\n * you should think of the `ProxyAdmin` instance as the real administrative interface of your proxy.\n */\ncontract TransparentUpgradeableProxy is ERC1967Proxy {\n /**\n * @dev Initializes an upgradeable proxy managed by `_admin`, backed by the implementation at `_logic`, and\n * optionally initialized with `_data` as explained in {ERC1967Proxy-constructor}.\n */\n constructor(address _logic, address admin_, bytes memory _data) payable ERC1967Proxy(_logic, _data) {\n assert(_ADMIN_SLOT == bytes32(uint256(keccak256(\"eip1967.proxy.admin\")) - 1));\n _changeAdmin(admin_);\n }\n\n /**\n * @dev Modifier used internally that will delegate the call to the implementation unless the sender is the admin.\n */\n modifier ifAdmin() {\n if (msg.sender == _getAdmin()) {\n _;\n } else {\n _fallback();\n }\n }\n\n /**\n * @dev Returns the current admin.\n *\n * NOTE: Only the admin can call this function. See {ProxyAdmin-getProxyAdmin}.\n *\n * TIP: To get this value clients can read directly from the storage slot shown below (specified by EIP1967) using the\n * https://eth.wiki/json-rpc/API#eth_getstorageat[`eth_getStorageAt`] RPC call.\n * `0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103`\n */\n function admin() external ifAdmin returns (address admin_) {\n admin_ = _getAdmin();\n }\n\n /**\n * @dev Returns the current implementation.\n *\n * NOTE: Only the admin can call this function. See {ProxyAdmin-getProxyImplementation}.\n *\n * TIP: To get this value clients can read directly from the storage slot shown below (specified by EIP1967) using the\n * https://eth.wiki/json-rpc/API#eth_getstorageat[`eth_getStorageAt`] RPC call.\n * `0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc`\n */\n function implementation() external ifAdmin returns (address implementation_) {\n implementation_ = _implementation();\n }\n\n /**\n * @dev Changes the admin of the proxy.\n *\n * Emits an {AdminChanged} event.\n *\n * NOTE: Only the admin can call this function. See {ProxyAdmin-changeProxyAdmin}.\n */\n function changeAdmin(address newAdmin) external virtual ifAdmin {\n _changeAdmin(newAdmin);\n }\n\n /**\n * @dev Upgrade the implementation of the proxy.\n *\n * NOTE: Only the admin can call this function. See {ProxyAdmin-upgrade}.\n */\n function upgradeTo(address newImplementation) external ifAdmin {\n _upgradeToAndCall(newImplementation, bytes(\"\"), false);\n }\n\n /**\n * @dev Upgrade the implementation of the proxy, and then call a function from the new implementation as specified\n * by `data`, which should be an encoded function call. This is useful to initialize new storage variables in the\n * proxied contract.\n *\n * NOTE: Only the admin can call this function. See {ProxyAdmin-upgradeAndCall}.\n */\n function upgradeToAndCall(address newImplementation, bytes calldata data) external payable ifAdmin {\n _upgradeToAndCall(newImplementation, data, true);\n }\n\n /**\n * @dev Returns the current admin.\n */\n function _admin() internal view virtual returns (address) {\n return _getAdmin();\n }\n\n /**\n * @dev Makes sure the admin cannot access the fallback function. See {Proxy-_beforeFallback}.\n */\n function _beforeFallback() internal virtual override {\n require(msg.sender != _getAdmin(), \"TransparentUpgradeableProxy: admin cannot fallback to proxy target\");\n super._beforeFallback();\n }\n}\n" + }, + "contracts/flashloan/FlashAngle.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\nimport \"@openzeppelin/contracts-upgradeable/security/ReentrancyGuardUpgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol\";\nimport \"@openzeppelin/contracts/interfaces/IERC3156FlashBorrower.sol\";\nimport \"@openzeppelin/contracts/interfaces/IERC3156FlashLender.sol\";\nimport \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\nimport \"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\";\n\nimport \"../interfaces/IAgToken.sol\";\nimport \"../interfaces/ICoreBorrow.sol\";\nimport \"../interfaces/IFlashAngle.sol\";\nimport \"../interfaces/ITreasury.sol\";\n\n/// @title FlashAngle\n/// @author Angle Labs, Inc.\n/// @notice Contract to take flash loans on top of several AgToken contracts\ncontract FlashAngle is IERC3156FlashLender, IFlashAngle, Initializable, ReentrancyGuardUpgradeable {\n using SafeERC20 for IERC20;\n /// @notice Base used for parameter computation\n uint256 public constant BASE_PARAMS = 10 ** 9;\n /// @notice Success message received when calling a `FlashBorrower` contract\n bytes32 public constant CALLBACK_SUCCESS = keccak256(\"ERC3156FlashBorrower.onFlashLoan\");\n\n /// @notice Struct encoding for a given stablecoin the parameters\n struct StablecoinData {\n // Maximum amount borrowable for this stablecoin\n uint256 maxBorrowable;\n // Flash loan fee taken by the protocol for a flash loan on this stablecoin\n uint64 flashLoanFee;\n // Treasury address responsible of the stablecoin\n address treasury;\n }\n\n // ======================= Parameters and References ===========================\n\n /// @notice Maps a stablecoin to the data and parameters for flash loans\n mapping(IAgToken => StablecoinData) public stablecoinMap;\n /// @inheritdoc IFlashAngle\n ICoreBorrow public core;\n\n // =============================== Event =======================================\n\n event FlashLoan(address indexed stablecoin, uint256 amount, IERC3156FlashBorrower indexed receiver);\n event FlashLoanParametersUpdated(IAgToken indexed stablecoin, uint64 _flashLoanFee, uint256 _maxBorrowable);\n\n // =============================== Errors ======================================\n\n error InvalidReturnMessage();\n error NotCore();\n error NotGovernorOrGuardian();\n error NotTreasury();\n error TooBigAmount();\n error TooHighParameterValue();\n error UnsupportedStablecoin();\n error ZeroAddress();\n\n /// @notice Initializes the contract\n /// @param _core Core address handling this module\n function initialize(ICoreBorrow _core) public initializer {\n if (address(_core) == address(0)) revert ZeroAddress();\n core = _core;\n }\n\n /// @custom:oz-upgrades-unsafe-allow constructor\n constructor() initializer {}\n\n // =================================== Modifiers ===============================\n\n /// @notice Checks whether the sender is the core contract\n modifier onlyCore() {\n if (msg.sender != address(core)) revert NotCore();\n _;\n }\n\n /// @notice Checks whether a given stablecoin has been initialized in this contract\n /// @param stablecoin Stablecoin to check\n /// @dev To check whether a stablecoin has been initialized, we just need to check whether its associated\n /// `treasury` address is not null in the `stablecoinMap`. This is what's checked in the `CoreBorrow` contract\n /// when adding support for a stablecoin\n modifier onlyExistingStablecoin(IAgToken stablecoin) {\n if (stablecoinMap[stablecoin].treasury == address(0)) revert UnsupportedStablecoin();\n _;\n }\n\n // ================================ ERC3156 Spec ===============================\n\n /// @inheritdoc IERC3156FlashLender\n function flashFee(address token, uint256 amount) external view returns (uint256) {\n return _flashFee(token, amount);\n }\n\n /// @inheritdoc IERC3156FlashLender\n function maxFlashLoan(address token) external view returns (uint256) {\n // It will be 0 anyway if the token was not added\n return stablecoinMap[IAgToken(token)].maxBorrowable;\n }\n\n /// @inheritdoc IERC3156FlashLender\n function flashLoan(\n IERC3156FlashBorrower receiver,\n address token,\n uint256 amount,\n bytes calldata data\n ) external nonReentrant returns (bool) {\n uint256 fee = _flashFee(token, amount);\n if (amount > stablecoinMap[IAgToken(token)].maxBorrowable) revert TooBigAmount();\n IAgToken(token).mint(address(receiver), amount);\n if (receiver.onFlashLoan(msg.sender, token, amount, fee, data) != CALLBACK_SUCCESS)\n revert InvalidReturnMessage();\n // Token must be an agToken here so normally no need to use `safeTransferFrom`, but out of safety\n // and in case governance whitelists an agToken which does not have a correct implementation, we prefer\n // to use `safeTransferFrom` here\n IERC20(token).safeTransferFrom(address(receiver), address(this), amount + fee);\n IAgToken(token).burnSelf(amount, address(this));\n emit FlashLoan(token, amount, receiver);\n return true;\n }\n\n /// @notice Internal function to compute the fee induced for taking a flash loan of `amount` of `token`\n /// @param token The loan currency\n /// @param amount The amount of tokens lent\n /// @dev This function will revert if the `token` requested is not whitelisted here\n function _flashFee(\n address token,\n uint256 amount\n ) internal view onlyExistingStablecoin(IAgToken(token)) returns (uint256) {\n return (amount * stablecoinMap[IAgToken(token)].flashLoanFee) / BASE_PARAMS;\n }\n\n // ============================ Treasury Only Function =========================\n\n /// @inheritdoc IFlashAngle\n function accrueInterestToTreasury(IAgToken stablecoin) external returns (uint256 balance) {\n address treasury = stablecoinMap[stablecoin].treasury;\n if (msg.sender != treasury) revert NotTreasury();\n balance = stablecoin.balanceOf(address(this));\n IERC20(address(stablecoin)).safeTransfer(treasury, balance);\n }\n\n // =========================== Governance Only Function ========================\n\n /// @notice Sets the parameters for a given stablecoin\n /// @param stablecoin Stablecoin to change the parameters for\n /// @param _flashLoanFee New flash loan fee for this stablecoin\n /// @param _maxBorrowable Maximum amount that can be borrowed in a single flash loan\n /// @dev Setting a `maxBorrowable` parameter equal to 0 is a way to pause the functionality\n /// @dev Parameters can only be modified for whitelisted stablecoins\n function setFlashLoanParameters(\n IAgToken stablecoin,\n uint64 _flashLoanFee,\n uint256 _maxBorrowable\n ) external onlyExistingStablecoin(stablecoin) {\n if (!core.isGovernorOrGuardian(msg.sender)) revert NotGovernorOrGuardian();\n if (_flashLoanFee > BASE_PARAMS) revert TooHighParameterValue();\n stablecoinMap[stablecoin].flashLoanFee = _flashLoanFee;\n stablecoinMap[stablecoin].maxBorrowable = _maxBorrowable;\n emit FlashLoanParametersUpdated(stablecoin, _flashLoanFee, _maxBorrowable);\n }\n\n // =========================== CoreBorrow Only Functions =======================\n\n /// @inheritdoc IFlashAngle\n function addStablecoinSupport(address _treasury) external onlyCore {\n stablecoinMap[IAgToken(ITreasury(_treasury).stablecoin())].treasury = _treasury;\n }\n\n /// @inheritdoc IFlashAngle\n function removeStablecoinSupport(address _treasury) external onlyCore {\n delete stablecoinMap[IAgToken(ITreasury(_treasury).stablecoin())];\n }\n\n /// @inheritdoc IFlashAngle\n function setCore(address _core) external onlyCore {\n core = ICoreBorrow(_core);\n }\n}\n" + }, + "contracts/interfaces/coreModule/IAgTokenMainnet.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\n/// @title IAgTokenMainnet\n/// @author Angle Labs, Inc.\ninterface IAgTokenMainnet {\n function stableMaster() external view returns (address);\n}\n" + }, + "contracts/interfaces/coreModule/ICore.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\n/// @title ICore\n/// @author Angle Labs, Inc.\ninterface ICore {\n function stablecoinList() external view returns (address[] memory);\n}\n" + }, + "contracts/interfaces/coreModule/ILiquidityGauge.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\ninterface ILiquidityGauge {\n function deposit(\n uint256 _value,\n address _addr,\n // solhint-disable-next-line\n bool _claim_rewards\n ) external;\n\n function withdraw(\n uint256 _value,\n // solhint-disable-next-line\n bool _claim_rewards\n ) external;\n\n // solhint-disable-next-line\n function claim_rewards(address _addr, address _receiver) external;\n\n // solhint-disable-next-line\n function claimable_reward(address _addr, address _reward_token) external view returns (uint256 amount);\n}\n" + }, + "contracts/interfaces/coreModule/IOracleCore.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\n/// @title IOracleCore\n/// @author Angle Labs, Inc.\ninterface IOracleCore {\n function readUpper() external view returns (uint256);\n\n function readQuoteLower(uint256 baseAmount) external view returns (uint256);\n}\n" + }, + "contracts/interfaces/coreModule/IPerpetualManager.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\n/// @title IPerpetualManager\n/// @author Angle Labs, Inc.\ninterface IPerpetualManager {\n function totalHedgeAmount() external view returns (uint256);\n\n function maintenanceMargin() external view returns (uint64);\n\n function maxLeverage() external view returns (uint64);\n\n function targetHAHedge() external view returns (uint64);\n\n function limitHAHedge() external view returns (uint64);\n\n function lockTime() external view returns (uint64);\n\n function haBonusMalusDeposit() external view returns (uint64);\n\n function haBonusMalusWithdraw() external view returns (uint64);\n\n function xHAFeesDeposit(uint256) external view returns (uint64);\n\n function yHAFeesDeposit(uint256) external view returns (uint64);\n\n function xHAFeesWithdraw(uint256) external view returns (uint64);\n\n function yHAFeesWithdraw(uint256) external view returns (uint64);\n}\n" + }, + "contracts/interfaces/coreModule/IPoolManager.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\n/// @title IPoolManager\n/// @author Angle Labs, Inc.\ninterface IPoolManager {\n function feeManager() external view returns (address);\n\n function strategyList(uint256) external view returns (address);\n}\n" + }, + "contracts/interfaces/coreModule/IStableMaster.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\nimport \"./IPerpetualManager.sol\";\nimport \"./IOracleCore.sol\";\n\n// Struct to handle all the parameters to manage the fees\n// related to a given collateral pool (associated to the stablecoin)\nstruct MintBurnData {\n // Values of the thresholds to compute the minting fees\n // depending on HA hedge (scaled by `BASE_PARAMS`)\n uint64[] xFeeMint;\n // Values of the fees at thresholds (scaled by `BASE_PARAMS`)\n uint64[] yFeeMint;\n // Values of the thresholds to compute the burning fees\n // depending on HA hedge (scaled by `BASE_PARAMS`)\n uint64[] xFeeBurn;\n // Values of the fees at thresholds (scaled by `BASE_PARAMS`)\n uint64[] yFeeBurn;\n // Max proportion of collateral from users that can be covered by HAs\n // It is exactly the same as the parameter of the same name in `PerpetualManager`, whenever one is updated\n // the other changes accordingly\n uint64 targetHAHedge;\n // Minting fees correction set by the `FeeManager` contract: they are going to be multiplied\n // to the value of the fees computed using the hedge curve\n // Scaled by `BASE_PARAMS`\n uint64 bonusMalusMint;\n // Burning fees correction set by the `FeeManager` contract: they are going to be multiplied\n // to the value of the fees computed using the hedge curve\n // Scaled by `BASE_PARAMS`\n uint64 bonusMalusBurn;\n // Parameter used to limit the number of stablecoins that can be issued using the concerned collateral\n uint256 capOnStableMinted;\n}\n\n// Struct to handle all the variables and parameters to handle SLPs in the protocol\n// including the fraction of interests they receive or the fees to be distributed to\n// them\nstruct SLPData {\n // Last timestamp at which the `sanRate` has been updated for SLPs\n uint256 lastBlockUpdated;\n // Fees accumulated from previous blocks and to be distributed to SLPs\n uint256 lockedInterests;\n // Max interests used to update the `sanRate` in a single block\n // Should be in collateral token base\n uint256 maxInterestsDistributed;\n // Amount of fees left aside for SLPs and that will be distributed\n // when the protocol is collateralized back again\n uint256 feesAside;\n // Part of the fees normally going to SLPs that is left aside\n // before the protocol is collateralized back again (depends on collateral ratio)\n // Updated by keepers and scaled by `BASE_PARAMS`\n uint64 slippageFee;\n // Portion of the fees from users minting and burning\n // that goes to SLPs (the rest goes to surplus)\n uint64 feesForSLPs;\n // Slippage factor that's applied to SLPs exiting (depends on collateral ratio)\n // If `slippage = BASE_PARAMS`, SLPs can get nothing, if `slippage = 0` they get their full claim\n // Updated by keepers and scaled by `BASE_PARAMS`\n uint64 slippage;\n // Portion of the interests from lending\n // that goes to SLPs (the rest goes to surplus)\n uint64 interestsForSLPs;\n}\n\n/// @title IStableMaster\n/// @author Angle Labs, Inc.\ninterface IStableMaster {\n function agToken() external view returns (address);\n\n function updateStocksUsers(uint256 amount, address poolManager) external;\n\n function collateralMap(\n address poolManager\n )\n external\n view\n returns (\n address token,\n address sanToken,\n IPerpetualManager perpetualManager,\n IOracleCore oracle,\n uint256 stocksUsers,\n uint256 sanRate,\n uint256 collatBase,\n SLPData memory slpData,\n MintBurnData memory feeData\n );\n\n function paused(bytes32) external view returns (bool);\n\n function deposit(uint256 amount, address user, address poolManager) external;\n\n function withdraw(uint256 amount, address burner, address dest, address poolManager) external;\n}\n" + }, + "contracts/interfaces/external/create2/ImmutableCreate2Factory.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\ninterface ImmutableCreate2Factory {\n function safeCreate2(bytes32 salt, bytes memory initCode) external payable returns (address deploymentAddress);\n\n function findCreate2Address(\n bytes32 salt,\n bytes calldata initCode\n ) external view returns (address deploymentAddress);\n\n function findCreate2AddressViaHash(\n bytes32 salt,\n bytes32 initCodeHash\n ) external view returns (address deploymentAddress);\n}\n" + }, + "contracts/interfaces/external/IERC1271.sol": { + "content": "// SPDX-License-Identifier: GPL-2.0-or-later\npragma solidity ^0.8.12;\n\n/// @title Interface for verifying contract-based account signatures\n/// @notice Interface that verifies provided signature for the data\n/// @dev Interface defined by EIP-1271\ninterface IERC1271 {\n /// @notice Returns whether the provided signature is valid for the provided data\n /// @dev MUST return the bytes4 magic value 0x1626ba7e when function passes.\n /// MUST NOT modify state (using STATICCALL for solc < 0.5, view modifier for solc > 0.5).\n /// MUST allow external calls.\n /// @param hash Hash of the data to be signed\n /// @param signature Signature byte array associated with _data\n /// @return magicValue The bytes4 magic value 0x1626ba7e\n function isValidSignature(bytes32 hash, bytes memory signature) external view returns (bytes4 magicValue);\n}\n" + }, + "contracts/interfaces/external/IERC4626.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\npragma solidity >=0.8.0;\n\nimport \"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\";\nimport \"@openzeppelin/contracts/token/ERC20/ERC20.sol\";\n\n/// @notice Minimal IERC4646 tokenized Vault interface.\n/// @author Forked from Solmate (https://github.com/Rari-Capital/solmate/blob/main/src/mixins/ERC4626.sol)\n/// @dev Do not use in production! ERC-4626 is still in the review stage and is subject to change.\ninterface IERC4626 {\n event Deposit(address indexed from, address indexed to, uint256 amount, uint256 shares);\n event Withdraw(address indexed from, address indexed to, uint256 amount, uint256 shares);\n\n /// @notice Transfers a given amount of asset to the reactor and mint shares accordingly\n /// @param amount Given amount of asset\n /// @param to Address to mint shares to\n /// @return shares Amount of shares minted to `to`\n function deposit(uint256 amount, address to) external returns (uint256 shares);\n\n /// @notice Mints a given amount of shares to the reactor and transfer assets accordingly\n /// @param shares Given amount of shares\n /// @param to Address to mint shares to\n /// @return amount Amount of `asset` taken to the `msg.sender` to mint `shares`\n function mint(uint256 shares, address to) external returns (uint256 amount);\n\n /// @notice Transfers a given amount of asset from the reactor and burn shares accordingly\n /// @param amount Given amount of asset\n /// @param to Address to transfer assets to\n /// @param from Address to burn shares from\n /// @return shares Amount of shares burnt in the operation\n function withdraw(uint256 amount, address to, address from) external returns (uint256 shares);\n\n /// @notice Burns a given amount of shares to the reactor and transfer assets accordingly\n /// @param shares Given amount of shares\n /// @param to Address to transfer assets to\n /// @param from Address to burn shares from\n /// @return amount Amount of assets redeemed in the operation\n function redeem(uint256 shares, address to, address from) external returns (uint256 amount);\n\n /// @notice Returns the total assets managed by this reactor\n function totalAssets() external view returns (uint256);\n\n /// @notice Converts an amount of assets to the corresponding amount of reactor shares\n /// @param assets Amount of asset to convert\n /// @return Shares corresponding to the amount of assets obtained\n function convertToShares(uint256 assets) external view returns (uint256);\n\n /// @notice Converts an amount of shares to its current value in asset\n /// @param shares Amount of shares to convert\n /// @return Amount of assets corresponding to the amount of assets given\n function convertToAssets(uint256 shares) external view returns (uint256);\n\n /// @notice Computes how many shares one would get by depositing `assets`\n /// @param assets Amount of asset to convert\n function previewDeposit(uint256 assets) external view returns (uint256);\n\n /// @notice Computes how many assets one would need to mint `shares`\n /// @param shares Amount of shares required\n function previewMint(uint256 shares) external view returns (uint256);\n\n /// @notice Computes how many shares one would need to withdraw assets\n /// @param assets Amount of asset to withdraw\n function previewWithdraw(uint256 assets) external view returns (uint256);\n\n /// @notice Computes how many assets one would get by burning shares\n /// @param shares Amount of shares to burn\n function previewRedeem(uint256 shares) external view returns (uint256);\n\n /// @notice Max deposit allowed for a user\n /// @param user Address of the user to check\n function maxDeposit(address user) external returns (uint256);\n\n /// @notice Max mint allowed for a user\n /// @param user Address of the user to check\n function maxMint(address user) external returns (uint256);\n\n /// @notice Max withdraw allowed for a user\n /// @param user Address of the user to check\n function maxWithdraw(address user) external returns (uint256);\n\n /// @notice Max redeem allowed for a user\n /// @param user Address of the user to check\n function maxRedeem(address user) external returns (uint256);\n}\n" + }, + "contracts/interfaces/external/IWETH9.sol": { + "content": "// SPDX-License-Identifier: GPL-2.0-or-later\npragma solidity ^0.8.12;\n\nimport \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\n\n/// @title Interface for WETH9\ninterface IWETH9 is IERC20 {\n /// @notice Deposit ether to get wrapped ether\n function deposit() external payable;\n\n /// @notice Withdraw wrapped ether to get ether\n function withdraw(uint256) external;\n}\n" + }, + "contracts/interfaces/external/layerZero/ILayerZeroEndpoint.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity >=0.5.0;\n\nimport \"./ILayerZeroUserApplicationConfig.sol\";\n\ninterface ILayerZeroEndpoint is ILayerZeroUserApplicationConfig {\n // @notice send a LayerZero message to the specified address at a LayerZero endpoint.\n // @param _dstChainId - the destination chain identifier\n // @param _destination - the address on destination chain (in bytes). address length/format may vary by chains\n // @param _payload - a custom bytes payload to send to the destination contract\n // @param _refundAddress - if the source transaction is cheaper than the amount of value passed, refund the additional amount to this address\n // @param _zroPaymentAddress - the address of the ZRO token holder who would pay for the transaction\n // @param _adapterParams - parameters for custom functionality. e.g. receive airdropped native gas from the relayer on destination\n function send(\n uint16 _dstChainId,\n bytes calldata _destination,\n bytes calldata _payload,\n address payable _refundAddress,\n address _zroPaymentAddress,\n bytes calldata _adapterParams\n ) external payable;\n\n // @notice used by the messaging library to publish verified payload\n // @param _srcChainId - the source chain identifier\n // @param _srcAddress - the source contract (as bytes) at the source chain\n // @param _dstAddress - the address on destination chain\n // @param _nonce - the unbound message ordering nonce\n // @param _gasLimit - the gas limit for external contract execution\n // @param _payload - verified payload to send to the destination contract\n function receivePayload(\n uint16 _srcChainId,\n bytes calldata _srcAddress,\n address _dstAddress,\n uint64 _nonce,\n uint256 _gasLimit,\n bytes calldata _payload\n ) external;\n\n // @notice get the inboundNonce of a lzApp from a source chain which could be EVM or non-EVM chain\n // @param _srcChainId - the source chain identifier\n // @param _srcAddress - the source chain contract address\n function getInboundNonce(uint16 _srcChainId, bytes calldata _srcAddress) external view returns (uint64);\n\n // @notice get the outboundNonce from this source chain which, consequently, is always an EVM\n // @param _srcAddress - the source chain contract address\n function getOutboundNonce(uint16 _dstChainId, address _srcAddress) external view returns (uint64);\n\n // @notice gets a quote in source native gas, for the amount that send() requires to pay for message delivery\n // @param _dstChainId - the destination chain identifier\n // @param _userApplication - the user app address on this EVM chain\n // @param _payload - the custom message to send over LayerZero\n // @param _payInZRO - if false, user app pays the protocol fee in native token\n // @param _adapterParam - parameters for the adapter service, e.g. send some dust native token to dstChain\n function estimateFees(\n uint16 _dstChainId,\n address _userApplication,\n bytes calldata _payload,\n bool _payInZRO,\n bytes calldata _adapterParam\n ) external view returns (uint256 nativeFee, uint256 zroFee);\n\n // @notice get this Endpoint's immutable source identifier\n function getChainId() external view returns (uint16);\n\n // @notice the interface to retry failed message on this Endpoint destination\n // @param _srcChainId - the source chain identifier\n // @param _srcAddress - the source chain contract address\n // @param _payload - the payload to be retried\n function retryPayload(uint16 _srcChainId, bytes calldata _srcAddress, bytes calldata _payload) external;\n\n // @notice query if any STORED payload (message blocking) at the endpoint.\n // @param _srcChainId - the source chain identifier\n // @param _srcAddress - the source chain contract address\n function hasStoredPayload(uint16 _srcChainId, bytes calldata _srcAddress) external view returns (bool);\n\n // @notice query if the _libraryAddress is valid for sending msgs.\n // @param _userApplication - the user app address on this EVM chain\n function getSendLibraryAddress(address _userApplication) external view returns (address);\n\n // @notice query if the _libraryAddress is valid for receiving msgs.\n // @param _userApplication - the user app address on this EVM chain\n function getReceiveLibraryAddress(address _userApplication) external view returns (address);\n\n // @notice query if the non-reentrancy guard for send() is on\n // @return true if the guard is on. false otherwise\n function isSendingPayload() external view returns (bool);\n\n // @notice query if the non-reentrancy guard for receive() is on\n // @return true if the guard is on. false otherwise\n function isReceivingPayload() external view returns (bool);\n\n // @notice get the configuration of the LayerZero messaging library of the specified version\n // @param _version - messaging library version\n // @param _chainId - the chainId for the pending config change\n // @param _userApplication - the contract address of the user application\n // @param _configType - type of configuration. every messaging library has its own convention.\n function getConfig(\n uint16 _version,\n uint16 _chainId,\n address _userApplication,\n uint256 _configType\n ) external view returns (bytes memory);\n\n // @notice get the send() LayerZero messaging library version\n // @param _userApplication - the contract address of the user application\n function getSendVersion(address _userApplication) external view returns (uint16);\n\n // @notice get the lzReceive() LayerZero messaging library version\n // @param _userApplication - the contract address of the user application\n function getReceiveVersion(address _userApplication) external view returns (uint16);\n}\n" + }, + "contracts/interfaces/external/layerZero/ILayerZeroReceiver.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity >=0.5.0;\n\ninterface ILayerZeroReceiver {\n // @notice LayerZero endpoint will invoke this function to deliver the message on the destination\n // @param _srcChainId - the source endpoint identifier\n // @param _srcAddress - the source sending contract address from the source chain\n // @param _nonce - the ordered message nonce\n // @param _payload - the signed payload is the UA bytes has encoded to be sent\n function lzReceive(uint16 _srcChainId, bytes calldata _srcAddress, uint64 _nonce, bytes calldata _payload) external;\n}\n" + }, + "contracts/interfaces/external/layerZero/ILayerZeroUserApplicationConfig.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity >=0.5.0;\n\ninterface ILayerZeroUserApplicationConfig {\n // @notice set the configuration of the LayerZero messaging library of the specified version\n // @param _version - messaging library version\n // @param _chainId - the chainId for the pending config change\n // @param _configType - type of configuration. every messaging library has its own convention.\n // @param _config - configuration in the bytes. can encode arbitrary content.\n function setConfig(uint16 _version, uint16 _chainId, uint256 _configType, bytes calldata _config) external;\n\n // @notice set the send() LayerZero messaging library version to _version\n // @param _version - new messaging library version\n function setSendVersion(uint16 _version) external;\n\n // @notice set the lzReceive() LayerZero messaging library version to _version\n // @param _version - new messaging library version\n function setReceiveVersion(uint16 _version) external;\n\n // @notice Only when the UA needs to resume the message flow in blocking mode and clear the stored payload\n // @param _srcChainId - the chainId of the source chain\n // @param _srcAddress - the contract address of the source contract at the source chain\n function forceResumeReceive(uint16 _srcChainId, bytes calldata _srcAddress) external;\n}\n" + }, + "contracts/interfaces/external/lido/IStETH.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\n/// @title IStETH\n/// @author Angle Labs, Inc.\n/// @notice Interface for the `StETH` contract\n/// @dev This interface only contains functions of the `StETH` which are called by other contracts\n/// of this module\ninterface IStETH {\n function getPooledEthByShares(uint256 _sharesAmount) external view returns (uint256);\n\n event Submitted(address sender, uint256 amount, address referral);\n\n function submit(address) external payable returns (uint256);\n\n function getSharesByPooledEth(uint256 _ethAmount) external view returns (uint256);\n}\n" + }, + "contracts/interfaces/external/lido/IWStETH.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\n/// @title IWStETH\n/// @author Angle Labs, Inc.\n/// @notice Interface for the `WStETH` contract\n/// @dev This interface only contains functions of the `WStETH` which are called by other contracts\n/// of this module\ninterface IWStETH {\n function wrap(uint256 _stETHAmount) external returns (uint256);\n\n function stETH() external view returns (address);\n}\n" + }, + "contracts/interfaces/external/uniswap/IUniswapRouter.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\nstruct ExactInputParams {\n bytes path;\n address recipient;\n uint256 deadline;\n uint256 amountIn;\n uint256 amountOutMinimum;\n}\n\n/// @title Router token swapping functionality\n/// @notice Functions for swapping tokens via Uniswap V3\ninterface IUniswapV3Router {\n /// @notice Swaps `amountIn` of one token for as much as possible of another along the specified path\n /// @param params The parameters necessary for the multi-hop swap, encoded as `ExactInputParams` in calldata\n /// @return amountOut The amount of the received token\n function exactInput(ExactInputParams calldata params) external payable returns (uint256 amountOut);\n}\n\n/// @title Router for price estimation functionality\n/// @notice Functions for getting the price of one token with respect to another using Uniswap V2\n/// @dev This interface is only used for non critical elements of the protocol\ninterface IUniswapV2Router {\n /// @notice Given an input asset amount, returns the maximum output amount of the\n /// other asset (accounting for fees) given reserves.\n /// @param path Addresses of the pools used to get prices\n function getAmountsOut(uint256 amountIn, address[] calldata path) external view returns (uint256[] memory amounts);\n\n function swapExactTokensForTokens(\n uint256 swapAmount,\n uint256 minExpected,\n address[] calldata path,\n address receiver,\n uint256 swapDeadline\n ) external;\n}\n" + }, + "contracts/interfaces/external/uniswap/IUniswapV3Pool.sol": { + "content": "// SPDX-License-Identifier: GPL-2.0-or-later\npragma solidity >=0.5.0;\n\n/// @title Pool state that never changes\n/// @notice These parameters are fixed for a pool forever, i.e., the methods will always return the same values\ninterface IUniswapV3Pool {\n /// @notice The first of the two tokens of the pool, sorted by address\n /// @return The token contract address\n function token0() external view returns (address);\n\n /// @notice The second of the two tokens of the pool, sorted by address\n /// @return The token contract address\n function token1() external view returns (address);\n}\n" + }, + "contracts/interfaces/governance/IVeBoostProxy.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\n/// @title IVeBoostProxy\n/// @author Angle Labs, Inc.\n/// @notice Interface for the `VeBoostProxy` contract\n/// @dev This interface only contains functions of the contract which are called by other contracts\n/// of this module\n/// @dev The `veBoostProxy` contract used by Angle is a full fork of Curve Finance implementation\ninterface IVeBoostProxy {\n /// @notice Reads the adjusted veANGLE balance of an address (adjusted by delegation)\n //solhint-disable-next-line\n function adjusted_balance_of(address) external view returns (uint256);\n}\n" + }, + "contracts/interfaces/IAgToken.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\nimport \"@openzeppelin/contracts-upgradeable/token/ERC20/IERC20Upgradeable.sol\";\n\n/// @title IAgToken\n/// @author Angle Labs, Inc.\n/// @notice Interface for the stablecoins `AgToken` contracts\n/// @dev This interface only contains functions of the `AgToken` contract which are called by other contracts\n/// of this module or of the first module of the Angle Protocol\ninterface IAgToken is IERC20Upgradeable {\n // ======================= Minter Role Only Functions ===========================\n\n /// @notice Lets the `StableMaster` contract or another whitelisted contract mint agTokens\n /// @param account Address to mint to\n /// @param amount Amount to mint\n /// @dev The contracts allowed to issue agTokens are the `StableMaster` contract, `VaultManager` contracts\n /// associated to this stablecoin as well as the flash loan module (if activated) and potentially contracts\n /// whitelisted by governance\n function mint(address account, uint256 amount) external;\n\n /// @notice Burns `amount` tokens from a `burner` address after being asked to by `sender`\n /// @param amount Amount of tokens to burn\n /// @param burner Address to burn from\n /// @param sender Address which requested the burn from `burner`\n /// @dev This method is to be called by a contract with the minter right after being requested\n /// to do so by a `sender` address willing to burn tokens from another `burner` address\n /// @dev The method checks the allowance between the `sender` and the `burner`\n function burnFrom(uint256 amount, address burner, address sender) external;\n\n /// @notice Burns `amount` tokens from a `burner` address\n /// @param amount Amount of tokens to burn\n /// @param burner Address to burn from\n /// @dev This method is to be called by a contract with a minter right on the AgToken after being\n /// requested to do so by an address willing to burn tokens from its address\n function burnSelf(uint256 amount, address burner) external;\n\n // ========================= Treasury Only Functions ===========================\n\n /// @notice Adds a minter in the contract\n /// @param minter Minter address to add\n /// @dev Zero address checks are performed directly in the `Treasury` contract\n function addMinter(address minter) external;\n\n /// @notice Removes a minter from the contract\n /// @param minter Minter address to remove\n /// @dev This function can also be called by a minter wishing to revoke itself\n function removeMinter(address minter) external;\n\n /// @notice Sets a new treasury contract\n /// @param _treasury New treasury address\n function setTreasury(address _treasury) external;\n\n // ========================= External functions ================================\n\n /// @notice Checks whether an address has the right to mint agTokens\n /// @param minter Address for which the minting right should be checked\n /// @return Whether the address has the right to mint agTokens or not\n function isMinter(address minter) external view returns (bool);\n\n /// @notice Get the associated treasury\n function treasury() external view returns (address);\n}\n" + }, + "contracts/interfaces/IAgTokenSideChainMultiBridge.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\nimport \"@openzeppelin/contracts-upgradeable/token/ERC20/extensions/draft-IERC20PermitUpgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/token/ERC20/IERC20Upgradeable.sol\";\n\n/// @title IAgTokenSideChainMultiBridge\n/// @author Angle Labs, Inc.\n/// @notice Interface for the canonical `AgToken` contracts\n/// @dev This interface only contains functions useful for bridge tokens to interact with the canonical token\ninterface IAgTokenSideChainMultiBridge is IERC20PermitUpgradeable, IERC20Upgradeable {\n /// @notice Mints the canonical token from a supported bridge token\n /// @param bridgeToken Bridge token to use to mint\n /// @param amount Amount of bridge tokens to send\n /// @param to Address to which the stablecoin should be sent\n /// @return Amount of the canonical stablecoin actually minted\n /// @dev Some fees may be taken by the protocol depending on the token used and on the address calling\n function swapIn(address bridgeToken, uint256 amount, address to) external returns (uint256);\n\n /// @notice Burns the canonical token in exchange for a bridge token\n /// @param bridgeToken Bridge token required\n /// @param amount Amount of canonical tokens to burn\n /// @param to Address to which the bridge token should be sent\n /// @return Amount of bridge tokens actually sent back\n /// @dev Some fees may be taken by the protocol depending on the token used and on the address calling\n function swapOut(address bridgeToken, uint256 amount, address to) external returns (uint256);\n}\n" + }, + "contracts/interfaces/IAngleRouter.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\n/// @title IAngleRouter\n/// @author Angle Labs, Inc.\n/// @notice Interface for the `AngleRouter` contract\n/// @dev This interface only contains functions of the `AngleRouter01` contract which are called by other contracts\n/// of this module\ninterface IAngleRouter {\n function mint(\n address user,\n uint256 amount,\n uint256 minStableAmount,\n address stablecoin,\n address collateral\n ) external;\n\n function burn(address user, uint256 amount, uint256 minAmountOut, address stablecoin, address collateral) external;\n\n function mapPoolManagers(\n address stableMaster,\n address collateral\n ) external view returns (address poolManager, address perpetualManager, address sanToken, address gauge);\n}\n" + }, + "contracts/interfaces/IAngleRouterSidechain.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\n/// @notice Action types\nenum ActionType {\n transfer,\n wrap,\n wrapNative,\n sweep,\n sweepNative,\n unwrap,\n unwrapNative,\n swapIn,\n swapOut,\n uniswapV3,\n oneInch,\n claimRewards,\n gaugeDeposit,\n borrower\n}\n\n/// @notice Data needed to get permits\nstruct PermitType {\n address token;\n address owner;\n uint256 value;\n uint256 deadline;\n uint8 v;\n bytes32 r;\n bytes32 s;\n}\n\n/// @title IAngleRouterSidechain\n/// @author Angle Labs, Inc.\n/// @notice Interface for the `AngleRouter` contract on other chains\ninterface IAngleRouterSidechain {\n function mixer(PermitType[] memory paramsPermit, ActionType[] memory actions, bytes[] calldata data) external;\n}\n" + }, + "contracts/interfaces/ICoreBorrow.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\n/// @title ICoreBorrow\n/// @author Angle Labs, Inc.\n/// @notice Interface for the `CoreBorrow` contract\n/// @dev This interface only contains functions of the `CoreBorrow` contract which are called by other contracts\n/// of this module\ninterface ICoreBorrow {\n /// @notice Checks if an address corresponds to a treasury of a stablecoin with a flash loan\n /// module initialized on it\n /// @param treasury Address to check\n /// @return Whether the address has the `FLASHLOANER_TREASURY_ROLE` or not\n function isFlashLoanerTreasury(address treasury) external view returns (bool);\n\n /// @notice Checks whether an address is governor of the Angle Protocol or not\n /// @param admin Address to check\n /// @return Whether the address has the `GOVERNOR_ROLE` or not\n function isGovernor(address admin) external view returns (bool);\n\n /// @notice Checks whether an address is governor or a guardian of the Angle Protocol or not\n /// @param admin Address to check\n /// @return Whether the address has the `GUARDIAN_ROLE` or not\n /// @dev Governance should make sure when adding a governor to also give this governor the guardian\n /// role by calling the `addGovernor` function\n function isGovernorOrGuardian(address admin) external view returns (bool);\n}\n" + }, + "contracts/interfaces/IFlashAngle.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\nimport \"./IAgToken.sol\";\nimport \"./ICoreBorrow.sol\";\n\n/// @title IFlashAngle\n/// @author Angle Labs, Inc.\n/// @notice Interface for the `FlashAngle` contract\n/// @dev This interface only contains functions of the contract which are called by other contracts\n/// of this module\ninterface IFlashAngle {\n /// @notice Reference to the `CoreBorrow` contract managing the FlashLoan module\n function core() external view returns (ICoreBorrow);\n\n /// @notice Sends the fees taken from flash loans to the treasury contract associated to the stablecoin\n /// @param stablecoin Stablecoin from which profits should be sent\n /// @return balance Amount of profits sent\n /// @dev This function can only be called by the treasury contract\n function accrueInterestToTreasury(IAgToken stablecoin) external returns (uint256 balance);\n\n /// @notice Adds support for a stablecoin\n /// @param _treasury Treasury associated to the stablecoin to add support for\n /// @dev This function can only be called by the `CoreBorrow` contract\n function addStablecoinSupport(address _treasury) external;\n\n /// @notice Removes support for a stablecoin\n /// @param _treasury Treasury associated to the stablecoin to remove support for\n /// @dev This function can only be called by the `CoreBorrow` contract\n function removeStablecoinSupport(address _treasury) external;\n\n /// @notice Sets a new core contract\n /// @param _core Core contract address to set\n /// @dev This function can only be called by the `CoreBorrow` contract\n function setCore(address _core) external;\n}\n" + }, + "contracts/interfaces/IKeeperRegistry.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\nimport \"@openzeppelin/contracts-upgradeable/token/ERC20/IERC20Upgradeable.sol\";\n\n/// @title IKeeperRegistry\n/// @author Angle Labs, Inc.\ninterface IKeeperRegistry {\n /// @notice Checks whether an address is whitelisted during oracle updates\n /// @param caller Address for which the whitelist should be checked\n /// @return Whether the address is trusted or not\n function isTrusted(address caller) external view returns (bool);\n}\n" + }, + "contracts/interfaces/ILiquidityGauge.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.7;\n\ninterface ILiquidityGauge {\n function deposit(\n uint256 _value,\n address _addr,\n // solhint-disable-next-line\n bool _claim_rewards\n ) external;\n\n function withdraw(\n uint256 _value,\n // solhint-disable-next-line\n bool _claim_rewards\n ) external;\n\n // solhint-disable-next-line\n function claim_rewards(address _addr, address _receiver) external;\n\n // solhint-disable-next-line\n function claimable_reward(address _addr, address _reward_token) external view returns (uint256 amount);\n\n /// @dev Only for testing purposes\n // solhint-disable-next-line\n function deposit_reward_token(address _rewardToken, uint256 _amount) external;\n}\n" + }, + "contracts/interfaces/IOracle.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\nimport \"./ITreasury.sol\";\nimport \"@chainlink/contracts/src/v0.8/interfaces/AggregatorV3Interface.sol\";\n\n/// @title IOracle\n/// @author Angle Labs, Inc.\n/// @notice Interface for the `Oracle` contract\n/// @dev This interface only contains functions of the contract which are called by other contracts\n/// of this module\ninterface IOracle {\n /// @notice Reads the rate from the Chainlink circuit and other data provided\n /// @return quoteAmount The current rate between the in-currency and out-currency in the base\n /// of the out currency\n /// @dev For instance if the out currency is EUR (and hence agEUR), then the base of the returned\n /// value is 10**18\n function read() external view returns (uint256);\n\n /// @notice Changes the treasury contract\n /// @param _treasury Address of the new treasury contract\n /// @dev This function can be called by an approved `VaultManager` contract which can call\n /// this function after being requested to do so by a `treasury` contract\n /// @dev In some situations (like reactor contracts), the `VaultManager` may not directly be linked\n /// to the `oracle` contract and as such we may need governors to be able to call this function as well\n function setTreasury(address _treasury) external;\n\n /// @notice Reference to the `treasury` contract handling this `VaultManager`\n function treasury() external view returns (ITreasury treasury);\n\n /// @notice Array with the list of Chainlink feeds in the order in which they are read\n function circuitChainlink() external view returns (AggregatorV3Interface[] memory);\n}\n" + }, + "contracts/interfaces/ISwapper.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\nimport \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\n\n/// @title ISwapper\n/// @author Angle Labs, Inc.\n/// @notice Interface for Swapper contracts\n/// @dev This interface defines the key functions `Swapper` contracts should have when interacting with\n/// Angle\ninterface ISwapper {\n /// @notice Notifies a contract that an address should be given `outToken` from `inToken`\n /// @param inToken Address of the token received\n /// @param outToken Address of the token to obtain\n /// @param outTokenRecipient Address to which the outToken should be sent\n /// @param outTokenOwed Minimum amount of outToken the `outTokenRecipient` address should have at the end of the call\n /// @param inTokenObtained Amount of collateral obtained by a related address prior\n /// to the call to this function\n /// @param data Extra data needed (to encode Uniswap swaps for instance)\n function swap(\n IERC20 inToken,\n IERC20 outToken,\n address outTokenRecipient,\n uint256 outTokenOwed,\n uint256 inTokenObtained,\n bytes calldata data\n ) external;\n}\n" + }, + "contracts/interfaces/ITreasury.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\nimport \"./IAgToken.sol\";\nimport \"./ICoreBorrow.sol\";\nimport \"./IFlashAngle.sol\";\n\n/// @title ITreasury\n/// @author Angle Labs, Inc.\n/// @notice Interface for the `Treasury` contract\n/// @dev This interface only contains functions of the `Treasury` which are called by other contracts\n/// of this module\ninterface ITreasury {\n /// @notice Stablecoin handled by this `treasury` contract\n function stablecoin() external view returns (IAgToken);\n\n /// @notice Checks whether a given address has the governor role\n /// @param admin Address to check\n /// @return Whether the address has the governor role\n /// @dev Access control is only kept in the `CoreBorrow` contract\n function isGovernor(address admin) external view returns (bool);\n\n /// @notice Checks whether a given address has the guardian or the governor role\n /// @param admin Address to check\n /// @return Whether the address has the guardian or the governor role\n /// @dev Access control is only kept in the `CoreBorrow` contract which means that this function\n /// queries the `CoreBorrow` contract\n function isGovernorOrGuardian(address admin) external view returns (bool);\n\n /// @notice Checks whether a given address has well been initialized in this contract\n /// as a `VaultManager`\n /// @param _vaultManager Address to check\n /// @return Whether the address has been initialized or not\n function isVaultManager(address _vaultManager) external view returns (bool);\n\n /// @notice Sets a new flash loan module for this stablecoin\n /// @param _flashLoanModule Reference to the new flash loan module\n /// @dev This function removes the minting right to the old flash loan module and grants\n /// it to the new module\n function setFlashLoanModule(address _flashLoanModule) external;\n\n /// @notice Gets the vault manager list\n function vaultManagerList(uint256 i) external returns (address);\n}\n" + }, + "contracts/interfaces/IVaultManager.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\nimport \"@openzeppelin/contracts/interfaces/IERC721Metadata.sol\";\nimport \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\nimport \"./ITreasury.sol\";\nimport \"./IOracle.sol\";\n\n// ========================= Key Structs and Enums =============================\n\n/// @notice Parameters associated to a given `VaultManager` contract: these all correspond\n/// to parameters which signification is detailed in the `VaultManagerStorage` file\nstruct VaultParameters {\n uint256 debtCeiling;\n uint64 collateralFactor;\n uint64 targetHealthFactor;\n uint64 interestRate;\n uint64 liquidationSurcharge;\n uint64 maxLiquidationDiscount;\n bool whitelistingActivated;\n uint256 baseBoost;\n}\n\n/// @notice Data stored to track someone's loan (or equivalently called position)\nstruct Vault {\n // Amount of collateral deposited in the vault, in collateral decimals. For example, if the collateral\n // is USDC with 6 decimals, then `collateralAmount` will be in base 10**6\n uint256 collateralAmount;\n // Normalized value of the debt (that is to say of the stablecoins borrowed). It is expressed\n // in the base of Angle stablecoins (i.e. `BASE_TOKENS = 10**18`)\n uint256 normalizedDebt;\n}\n\n/// @notice For a given `vaultID`, this encodes a liquidation opportunity that is to say details about the maximum\n/// amount that could be repaid by liquidating the position\n/// @dev All the values are null in the case of a vault which cannot be liquidated under these conditions\nstruct LiquidationOpportunity {\n // Maximum stablecoin amount that can be repaid upon liquidating the vault\n uint256 maxStablecoinAmountToRepay;\n // Collateral amount given to the person in the case where the maximum amount to repay is given\n uint256 maxCollateralAmountGiven;\n // Threshold value of stablecoin amount to repay: it is ok for a liquidator to repay below threshold,\n // but if this threshold is non null and the liquidator wants to repay more than threshold, it should repay\n // the max stablecoin amount given in this vault\n uint256 thresholdRepayAmount;\n // Discount proposed to the liquidator on the collateral\n uint256 discount;\n // Amount of debt in the vault\n uint256 currentDebt;\n}\n\n/// @notice Data stored during a liquidation process to keep in memory what's due to a liquidator and some\n/// essential data for vaults being liquidated\nstruct LiquidatorData {\n // Current amount of stablecoins the liquidator should give to the contract\n uint256 stablecoinAmountToReceive;\n // Current amount of collateral the contract should give to the liquidator\n uint256 collateralAmountToGive;\n // Bad debt accrued across the liquidation process\n uint256 badDebtFromLiquidation;\n // Oracle value (in stablecoin base) at the time of the liquidation\n uint256 oracleValue;\n // Value of the `interestAccumulator` at the time of the call\n uint256 newInterestAccumulator;\n}\n\n/// @notice Data to track during a series of action the amount to give or receive in stablecoins and collateral\n/// to the caller or associated addresses\nstruct PaymentData {\n // Stablecoin amount the contract should give\n uint256 stablecoinAmountToGive;\n // Stablecoin amount owed to the contract\n uint256 stablecoinAmountToReceive;\n // Collateral amount the contract should give\n uint256 collateralAmountToGive;\n // Collateral amount owed to the contract\n uint256 collateralAmountToReceive;\n}\n\n/// @notice Actions possible when composing calls to the different entry functions proposed\nenum ActionType {\n createVault,\n closeVault,\n addCollateral,\n removeCollateral,\n repayDebt,\n borrow,\n getDebtIn,\n permit\n}\n\n// ========================= Interfaces =============================\n\n/// @title IVaultManagerFunctions\n/// @author Angle Labs, Inc.\n/// @notice Interface for the `VaultManager` contract\n/// @dev This interface only contains functions of the contract which are called by other contracts\n/// of this module (without getters)\ninterface IVaultManagerFunctions {\n /// @notice Accrues interest accumulated across all vaults to the surplus and sends the surplus to the treasury\n /// @return surplusValue Value of the surplus communicated to the `Treasury`\n /// @return badDebtValue Value of the bad debt communicated to the `Treasury`\n /// @dev `surplus` and `badDebt` should be reset to 0 once their current value have been given to the `treasury` contract\n function accrueInterestToTreasury() external returns (uint256 surplusValue, uint256 badDebtValue);\n\n /// @notice Removes debt from a vault after being requested to do so by another `VaultManager` contract\n /// @param vaultID ID of the vault to remove debt from\n /// @param amountStablecoins Amount of stablecoins to remove from the debt: this amount is to be converted to an\n /// internal debt amount\n /// @param senderBorrowFee Borrowing fees from the contract which requested this: this is to make sure that people are not\n /// arbitraging difference in minting fees\n /// @param senderRepayFee Repay fees from the contract which requested this: this is to make sure that people are not arbitraging\n /// differences in repay fees\n /// @dev This function can only be called from a vaultManager registered in the same Treasury\n function getDebtOut(\n uint256 vaultID,\n uint256 amountStablecoins,\n uint256 senderBorrowFee,\n uint256 senderRepayFee\n ) external;\n\n /// @notice Gets the current debt of a vault\n /// @param vaultID ID of the vault to check\n /// @return Debt of the vault\n function getVaultDebt(uint256 vaultID) external view returns (uint256);\n\n /// @notice Gets the total debt across all vaults\n /// @return Total debt across all vaults, taking into account the interest accumulated\n /// over time\n function getTotalDebt() external view returns (uint256);\n\n /// @notice Sets the treasury contract\n /// @param _treasury New treasury contract\n /// @dev All required checks when setting up a treasury contract are performed in the contract\n /// calling this function\n function setTreasury(address _treasury) external;\n\n /// @notice Creates a vault\n /// @param toVault Address for which the va\n /// @return vaultID ID of the vault created\n /// @dev This function just creates the vault without doing any collateral or\n function createVault(address toVault) external returns (uint256);\n\n /// @notice Allows composability between calls to the different entry points of this module. Any user calling\n /// this function can perform any of the allowed actions in the order of their choice\n /// @param actions Set of actions to perform\n /// @param datas Data to be decoded for each action: it can include like the `vaultID` or the `stablecoinAmount` to borrow\n /// @param from Address from which stablecoins will be taken if one action includes burning stablecoins. This address\n /// should either be the `msg.sender` or be approved by the latter\n /// @param to Address to which stablecoins and/or collateral will be sent in case of\n /// @param who Address of the contract to handle in case of repayment of stablecoins from received collateral\n /// @param repayData Data to pass to the repayment contract in case of\n /// @return paymentData Struct containing the accounting changes from the protocol's perspective (like how much of collateral\n /// or how much has been received). Note that the values in the struct are not aggregated and you could have in the output\n /// a positive amount of stablecoins to receive as well as a positive amount of stablecoins to give\n /// @dev This function is optimized to reduce gas cost due to payment from or to the user and that expensive calls\n /// or computations (like `oracleValue`) are done only once\n /// @dev When specifying `vaultID` in `data`, it is important to know that if you specify `vaultID = 0`, it will simply\n /// use the latest `vaultID`. This is the default behavior, and unless you're engaging into some complex protocol actions\n /// it is encouraged to use `vaultID = 0` only when the first action of the batch is `createVault`\n function angle(\n ActionType[] memory actions,\n bytes[] memory datas,\n address from,\n address to,\n address who,\n bytes memory repayData\n ) external returns (PaymentData memory paymentData);\n\n /// @notice This function is a wrapper built on top of the function above. It enables users to interact with the contract\n /// without having to provide `who` and `repayData` parameters\n function angle(\n ActionType[] memory actions,\n bytes[] memory datas,\n address from,\n address to\n ) external returns (PaymentData memory paymentData);\n\n /// @notice Initializes the `VaultManager` contract\n /// @param _treasury Treasury address handling the contract\n /// @param _collateral Collateral supported by this contract\n /// @param _oracle Oracle contract used\n /// @param _symbol Symbol used to define the `VaultManager` name and symbol\n /// @dev The parameters and the oracle are the only elements which could be modified once the\n /// contract has been initialized\n /// @dev For the contract to be fully initialized, governance needs to set the parameters for the liquidation\n /// boost\n function initialize(\n ITreasury _treasury,\n IERC20 _collateral,\n IOracle _oracle,\n VaultParameters calldata params,\n string memory _symbol\n ) external;\n\n /// @notice Minimum amount of debt a vault can have, expressed in `BASE_TOKENS` that is to say the base of the agTokens\n function dust() external view returns (uint256);\n\n /// @notice Pauses external permissionless functions of the contract\n function togglePause() external;\n}\n\n/// @title IVaultManagerStorage\n/// @author Angle Labs, Inc.\n/// @notice Interface for the `VaultManager` contract\n/// @dev This interface contains getters of the contract's public variables used by other contracts\n/// of this module\ninterface IVaultManagerStorage {\n /// @notice Encodes the maximum ratio stablecoin/collateral a vault can have before being liquidated. It's what\n /// determines the minimum collateral ratio of a position\n function collateralFactor() external view returns (uint64);\n\n /// @notice Stablecoin handled by this contract. Another `VaultManager` contract could have\n /// the same rights as this `VaultManager` on the stablecoin contract\n function stablecoin() external view returns (IAgToken);\n\n /// @notice Reference to the `treasury` contract handling this `VaultManager`\n function treasury() external view returns (ITreasury);\n\n /// @notice Oracle contract to get access to the price of the collateral with respect to the stablecoin\n function oracle() external view returns (IOracle);\n\n /// @notice The `interestAccumulator` variable keeps track of the interest that should accrue to the protocol.\n /// The stored value is not necessarily the true value: this one is recomputed every time an action takes place\n /// within the protocol. It is in base `BASE_INTEREST`\n function interestAccumulator() external view returns (uint256);\n\n /// @notice Reference to the collateral handled by this `VaultManager`\n function collateral() external view returns (IERC20);\n\n /// @notice Total normalized amount of stablecoins borrowed, not taking into account the potential bad debt accumulated\n /// This value is expressed in the base of Angle stablecoins (`BASE_TOKENS = 10**18`)\n function totalNormalizedDebt() external view returns (uint256);\n\n /// @notice Maximum amount of stablecoins that can be issued with this contract. It is expressed in `BASE_TOKENS`\n function debtCeiling() external view returns (uint256);\n\n /// @notice Maps a `vaultID` to its data (namely collateral amount and normalized debt)\n function vaultData(uint256 vaultID) external view returns (uint256 collateralAmount, uint256 normalizedDebt);\n\n /// @notice ID of the last vault created. The `vaultIDCount` variables serves as a counter to generate a unique\n /// `vaultID` for each vault: it is like `tokenID` in basic ERC721 contracts\n function vaultIDCount() external view returns (uint256);\n}\n\n/// @title IVaultManager\n/// @author Angle Labs, Inc.\n/// @notice Interface for the `VaultManager` contract\ninterface IVaultManager is IVaultManagerFunctions, IVaultManagerStorage, IERC721Metadata {\n function isApprovedOrOwner(address spender, uint256 vaultID) external view returns (bool);\n}\n\n/// @title IVaultManagerListing\n/// @author Angle Labs, Inc.\n/// @notice Interface for the `VaultManagerListing` contract\ninterface IVaultManagerListing is IVaultManager {\n /// @notice Get the collateral owned by `user` in the contract\n /// @dev This function effectively sums the collateral amounts of all the vaults owned by `user`\n function getUserCollateral(address user) external view returns (uint256);\n}\n" + }, + "contracts/keeperMulticall/KeeperMulticall.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\nimport \"@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/access/AccessControlUpgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol\";\nimport \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\nimport \"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\";\nimport \"./RevertReasonParser.sol\";\n\n/// @title KeeperMulticall\n/// @notice Allows an authorized caller (keeper) to execute multiple actions in a single tx.\n/// @author Angle Labs, Inc.\n/// @dev Special features:\n/// - ability to pay the miner (for private Flashbots transactions)\n/// - swap tokens through 1inch\n/// @dev Tx need to be encoded as an array of Action. The flag `isDelegateCall` is used for calling functions within this same contract\ncontract KeeperMulticall is Initializable, AccessControlUpgradeable {\n using SafeERC20 for IERC20;\n\n bytes32 public constant KEEPER_ROLE = keccak256(\"KEEPER_ROLE\");\n\n //solhint-disable-next-line\n address private constant _oneInch = 0x1111111254fb6c44bAC0beD2854e76F90643097d;\n\n struct Action {\n address target;\n bytes data;\n bool isDelegateCall;\n }\n\n event LogAction(address indexed target, bytes data);\n event SentToMiner(uint256 indexed value);\n event Recovered(address indexed tokenAddress, address indexed to, uint256 amount);\n\n error AmountOutTooLow(uint256 amount, uint256 min);\n error BalanceTooLow();\n error FlashbotsErrorPayingMiner(uint256 value);\n error IncompatibleLengths();\n error RevertBytes();\n error WrongAmount();\n error ZeroAddress();\n\n constructor() initializer {}\n\n function initialize(address keeper) external initializer {\n __AccessControl_init();\n\n _setupRole(KEEPER_ROLE, keeper);\n _setRoleAdmin(KEEPER_ROLE, KEEPER_ROLE);\n }\n\n /// @notice Allows an authorized keeper to execute multiple actions in a single step\n /// @param actions Actions to be executed\n /// @param percentageToMiner Percentage to pay to miner expressed in bps (10000)\n /// @dev This is the main entry point for actions to be executed. The `isDelegateCall` flag is used for calling function inside this `KeeperMulticall` contract,\n /// if we call other contracts, the flag should be false\n function executeActions(\n Action[] memory actions,\n uint256 percentageToMiner\n ) external payable onlyRole(KEEPER_ROLE) returns (bytes[] memory) {\n uint256 numberOfActions = actions.length;\n if (numberOfActions == 0) revert IncompatibleLengths();\n\n bytes[] memory returnValues = new bytes[](numberOfActions + 1);\n\n uint256 balanceBefore = address(this).balance;\n\n for (uint256 i; i < numberOfActions; ++i) {\n returnValues[i] = _executeAction(actions[i]);\n }\n\n if (percentageToMiner != 0) {\n if (percentageToMiner >= 10000) revert WrongAmount();\n uint256 balanceAfter = address(this).balance;\n if (balanceAfter > balanceBefore) {\n uint256 amountToMiner = ((balanceAfter - balanceBefore) * percentageToMiner) / 10000;\n returnValues[numberOfActions] = payFlashbots(amountToMiner);\n }\n }\n\n return returnValues;\n }\n\n /// @notice Gets the action address and data and executes it\n /// @param action Action to be executed\n function _executeAction(Action memory action) internal returns (bytes memory) {\n bool success;\n bytes memory response;\n\n if (action.isDelegateCall) {\n //solhint-disable-next-line\n (success, response) = action.target.delegatecall(action.data);\n } else {\n //solhint-disable-next-line\n (success, response) = action.target.call(action.data);\n }\n\n require(success, RevertReasonParser.parse(response, \"action reverted: \"));\n emit LogAction(action.target, action.data);\n return response;\n }\n\n /// @notice Ability to pay miner directly. Used for Flashbots to execute private transactions\n /// @param value Value to be sent\n function payFlashbots(uint256 value) public payable onlyRole(KEEPER_ROLE) returns (bytes memory) {\n //solhint-disable-next-line\n (bool success, bytes memory response) = block.coinbase.call{ value: value }(\"\");\n if (!success) revert FlashbotsErrorPayingMiner(value);\n emit SentToMiner(value);\n return response;\n }\n\n /// @notice Used to check the balances the token holds for each token. If we don't have enough of a token, we revert the tx\n /// @param tokens Array of tokens to check\n /// @param minBalances Array of balances for each token\n function finalBalanceCheck(IERC20[] memory tokens, uint256[] memory minBalances) external view returns (bool) {\n uint256 tokensLength = tokens.length;\n if (tokensLength == 0 || tokensLength != minBalances.length) revert IncompatibleLengths();\n\n for (uint256 i; i < tokensLength; ++i) {\n if (address(tokens[i]) == 0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE) {\n if (address(this).balance < minBalances[i]) revert BalanceTooLow();\n } else {\n if (tokens[i].balanceOf(address(this)) < minBalances[i]) revert BalanceTooLow();\n }\n }\n\n return true;\n }\n\n /// @notice Swap token to another through 1Inch\n /// @param minAmountOut Minimum amount of `out` token to receive for the swap to happen\n /// @param payload Bytes needed for 1Inch API\n function swapToken(uint256 minAmountOut, bytes memory payload) external onlyRole(KEEPER_ROLE) {\n //solhint-disable-next-line\n (bool success, bytes memory result) = _oneInch.call(payload);\n if (!success) _revertBytes(result);\n\n uint256 amountOut = abi.decode(result, (uint256));\n if (amountOut < minAmountOut) revert AmountOutTooLow(amountOut, minAmountOut);\n }\n\n /// @notice Copied from 1Inch contract, used to revert if there is an error\n function _revertBytes(bytes memory errMsg) internal pure {\n if (errMsg.length != 0) {\n //solhint-disable-next-line\n assembly {\n revert(add(32, errMsg), mload(errMsg))\n }\n }\n revert RevertBytes();\n }\n\n /// @notice Approve a `spender` for `token`\n /// @param token Address of the token to approve\n /// @param spender Address of the spender to approve\n /// @param amount Amount to approve\n function approve(IERC20 token, address spender, uint256 amount) external onlyRole(KEEPER_ROLE) {\n uint256 currentAllowance = token.allowance(address(this), spender);\n if (currentAllowance < amount) {\n token.safeIncreaseAllowance(spender, amount - currentAllowance);\n } else if (currentAllowance > amount) {\n token.safeDecreaseAllowance(spender, currentAllowance - amount);\n }\n }\n\n receive() external payable {}\n\n /// @notice Withdraw stuck funds\n /// @param token Address of the token to recover\n /// @param receiver Address where to send the tokens\n /// @param amount Amount to recover\n function withdrawStuckFunds(address token, address receiver, uint256 amount) external onlyRole(KEEPER_ROLE) {\n if (receiver == address(0)) revert ZeroAddress();\n if (token == 0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE) {\n payable(receiver).transfer(amount);\n } else {\n IERC20(token).safeTransfer(receiver, amount);\n }\n\n emit Recovered(token, receiver, amount);\n }\n}\n" + }, + "contracts/keeperMulticall/MulticallWithFailure.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.12;\n\n/// @title MultiCallWithFailure\n/// @author Angle Labs, Inc.\n/// @notice Multicall contract allowing subcalls to fail without reverting the entire call\ncontract MultiCallWithFailure {\n error SubcallFailed();\n\n struct Call {\n address target;\n bytes data;\n bool canFail;\n }\n\n function multiCall(Call[] memory calls) external view returns (bytes[] memory) {\n bytes[] memory results = new bytes[](calls.length);\n\n for (uint256 i; i < calls.length; ++i) {\n (bool success, bytes memory result) = calls[i].target.staticcall(calls[i].data);\n if (!calls[i].canFail) {\n if (!success) {\n revert SubcallFailed();\n }\n }\n results[i] = result;\n }\n\n return results;\n }\n}\n" + }, + "contracts/keeperMulticall/RevertReasonParser.sol": { + "content": "// SPDX-License-Identifier: GNU-3\n\npragma solidity ^0.8.12;\n\n/// @title RevertReasonParser\n/// @author 1Inch team, taken from:\n/// - https://docs.1inch.io/docs/limit-order-protocol/smart-contract/libraries/RevertReasonParser/\n/// - https://etherscan.io/address/0x1111111254fb6c44bAC0beD2854e76F90643097d#code\nlibrary RevertReasonParser {\n bytes4 private constant _PANIC_SELECTOR = bytes4(keccak256(\"Panic(uint256)\"));\n bytes4 private constant _ERROR_SELECTOR = bytes4(keccak256(\"Error(string)\"));\n\n function parse(bytes memory data, string memory prefix) internal pure returns (string memory) {\n if (data.length >= 4) {\n bytes4 selector;\n //solhint-disable-next-line\n assembly {\n selector := mload(add(data, 0x20))\n }\n\n // 68 = 4-byte selector + 32 bytes offset + 32 bytes length\n if (selector == _ERROR_SELECTOR && data.length >= 68) {\n uint256 offset;\n bytes memory reason;\n // solhint-disable no-inline-assembly\n assembly {\n // 36 = 32 bytes data length + 4-byte selector\n offset := mload(add(data, 36))\n reason := add(data, add(36, offset))\n }\n /*\n revert reason is padded up to 32 bytes with ABI encoder: Error(string)\n also sometimes there is extra 32 bytes of zeros padded in the end:\n https://github.com/ethereum/solidity/issues/10170\n because of that we can't check for equality and instead check\n that offset + string length + extra 36 bytes is less than overall data length\n */\n require(data.length >= 36 + offset + reason.length, \"Invalid revert reason\");\n return string(abi.encodePacked(prefix, \"Error(\", reason, \")\"));\n }\n // 36 = 4-byte selector + 32 bytes integer\n else if (selector == _PANIC_SELECTOR && data.length == 36) {\n uint256 code;\n // solhint-disable no-inline-assembly\n assembly {\n // 36 = 32 bytes data length + 4-byte selector\n code := mload(add(data, 36))\n }\n return string(abi.encodePacked(prefix, \"Panic(\", _toHex(code), \")\"));\n }\n }\n\n return string(abi.encodePacked(prefix, \"Unknown(\", _toHex(data), \")\"));\n }\n\n function _toHex(uint256 value) private pure returns (string memory) {\n return _toHex(abi.encodePacked(value));\n }\n\n function _toHex(bytes memory data) private pure returns (string memory) {\n bytes16 alphabet = 0x30313233343536373839616263646566;\n bytes memory str = new bytes(2 + data.length * 2);\n str[0] = \"0\";\n str[1] = \"x\";\n for (uint256 i; i < data.length; ++i) {\n str[2 * i + 2] = alphabet[uint8(data[i] >> 4)];\n str[2 * i + 3] = alphabet[uint8(data[i] & 0x0f)];\n }\n return string(str);\n }\n}\n" + }, + "contracts/mock/Mock1Inch.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.12;\n\nimport \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\nimport \"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\";\n\ncontract Mock1Inch {\n using SafeERC20 for IERC20;\n\n function swap(address tokenIn, uint256 amountIn, address to, address tokenOut, uint256 amountOut) external {\n IERC20(tokenIn).safeTransferFrom(msg.sender, to, amountIn);\n if (tokenOut == 0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE) {\n //solhint-disable-next-line\n (bool sent, bytes memory data) = msg.sender.call{ value: amountOut }(\"\");\n data;\n require(sent, \"Failed to send Ether\");\n } else {\n IERC20(tokenOut).safeTransferFrom(to, msg.sender, amountOut);\n }\n }\n\n receive() external payable {}\n}\n" + }, + "contracts/mock/MockAnything.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.12;\n\ncontract MockAnything {\n uint256 public stateVar = 1;\n\n error CustomError();\n error CustomErrorWithValue(uint256);\n\n function fail(uint256 value) external view returns (uint256) {\n stateVar;\n if (value < 10) {\n revert CustomError();\n }\n if (value < 20) {\n revert CustomErrorWithValue(value);\n }\n return value + 1;\n }\n\n function modifyState(uint256 value) external {\n stateVar = value;\n }\n}\n" + }, + "contracts/mock/MockChainlinkOracle.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.7;\n\ninterface MockAggregatorV3Interface {\n function decimals() external view returns (uint8);\n\n function description() external view returns (string memory);\n\n function version() external view returns (uint256);\n\n function getRoundData(\n uint80 _roundId\n )\n external\n view\n returns (uint80 roundId, int256 answer, uint256 startedAt, uint256 updatedAt, uint80 answeredInRound);\n\n function latestRoundData()\n external\n view\n returns (uint80 roundId, int256 answer, uint256 startedAt, uint256 updatedAt, uint80 answeredInRound);\n}\n\ncontract MockChainlinkOracle is MockAggregatorV3Interface {\n uint80 public roundId = 0;\n uint8 public keyDecimals = 0;\n\n struct Entry {\n uint80 roundId;\n int256 answer;\n uint256 startedAt;\n uint256 updatedAt;\n uint80 answeredInRound;\n }\n\n mapping(uint256 => Entry) public entries;\n\n bool public latestRoundDataShouldRevert;\n\n string public desc;\n\n constructor() {}\n\n // Mock setup function\n function setLatestAnswer(int256 answer, uint256 timestamp) external {\n roundId++;\n entries[roundId] = Entry({\n roundId: roundId,\n answer: answer,\n startedAt: timestamp,\n updatedAt: timestamp,\n answeredInRound: roundId\n });\n }\n\n function setLatestAnswerWithRound(int256 answer, uint256 timestamp, uint80 _roundId) external {\n roundId = _roundId;\n entries[roundId] = Entry({\n roundId: roundId,\n answer: answer,\n startedAt: timestamp,\n updatedAt: timestamp,\n answeredInRound: roundId\n });\n }\n\n function setLatestAnswerRevert(int256 answer, uint256 timestamp) external {\n roundId++;\n entries[roundId] = Entry({\n roundId: roundId,\n answer: answer,\n startedAt: timestamp,\n updatedAt: timestamp,\n answeredInRound: roundId - 1\n });\n }\n\n function setLatestRoundDataShouldRevert(bool _shouldRevert) external {\n latestRoundDataShouldRevert = _shouldRevert;\n }\n\n function setDecimals(uint8 _decimals) external {\n keyDecimals = _decimals;\n }\n\n function setDescritpion(string memory _desc) external {\n desc = _desc;\n }\n\n function description() external view override returns (string memory) {\n return desc;\n }\n\n function version() external view override returns (uint256) {\n roundId;\n return 0;\n }\n\n function latestRoundData() external view override returns (uint80, int256, uint256, uint256, uint80) {\n if (latestRoundDataShouldRevert) {\n revert(\"latestRoundData reverted\");\n }\n return getRoundData(uint80(roundId));\n }\n\n function decimals() external view override returns (uint8) {\n return keyDecimals;\n }\n\n function getRoundData(uint80 _roundId) public view override returns (uint80, int256, uint256, uint256, uint80) {\n Entry memory entry = entries[_roundId];\n // Emulate a Chainlink aggregator\n require(entry.updatedAt > 0, \"No data present\");\n return (entry.roundId, entry.answer, entry.startedAt, entry.updatedAt, entry.answeredInRound);\n }\n}\n" + }, + "contracts/mock/MockCoreBorrow.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\nimport \"../interfaces/ICoreBorrow.sol\";\nimport \"../interfaces/IFlashAngle.sol\";\nimport \"../interfaces/ITreasury.sol\";\n\ncontract MockCoreBorrow is ICoreBorrow {\n mapping(address => bool) public flashLoaners;\n mapping(address => bool) public governors;\n mapping(address => bool) public guardians;\n\n function isFlashLoanerTreasury(address treasury) external view override returns (bool) {\n return flashLoaners[treasury];\n }\n\n function isGovernor(address admin) external view override returns (bool) {\n return governors[admin];\n }\n\n function isGovernorOrGuardian(address admin) external view override returns (bool) {\n return governors[admin] || guardians[admin];\n }\n\n function toggleGovernor(address admin) external {\n governors[admin] = !governors[admin];\n }\n\n function toggleGuardian(address admin) external {\n guardians[admin] = !guardians[admin];\n }\n\n function toggleFlashLoaners(address admin) external {\n flashLoaners[admin] = !flashLoaners[admin];\n }\n\n function addStablecoinSupport(IFlashAngle flashAngle, address _treasury) external {\n flashAngle.addStablecoinSupport(_treasury);\n }\n\n function removeStablecoinSupport(IFlashAngle flashAngle, address _treasury) external {\n flashAngle.removeStablecoinSupport(_treasury);\n }\n\n function setCore(IFlashAngle flashAngle, address _core) external {\n flashAngle.setCore(_core);\n }\n\n function setFlashLoanModule(ITreasury _treasury, address _flashLoanModule) external {\n _treasury.setFlashLoanModule(_flashLoanModule);\n }\n}\n" + }, + "contracts/mock/MockERC1271.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.12;\n\nimport \"../interfaces/external/IERC1271.sol\";\n\ncontract MockERC1271 is IERC1271 {\n uint256 public mode = 0;\n\n function setMode(uint256 _mode) public {\n mode = _mode;\n }\n\n /// @notice Returns whether the provided signature is valid for the provided data\n /// @dev MUST return the bytes4 magic value 0x1626ba7e when function passes.\n /// MUST NOT modify state (using STATICCALL for solc < 0.5, view modifier for solc > 0.5).\n /// MUST allow external calls.\n /// @return magicValue The bytes4 magic value 0x1626ba7e\n function isValidSignature(bytes32, bytes memory) external view returns (bytes4 magicValue) {\n if (mode == 1) magicValue = 0x1626ba7e;\n }\n}\n" + }, + "contracts/mock/MockERC721Receiver.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (token/ERC721/utils/ERC721Holder.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Implementation of the {IERC721Receiver} interface.\n *\n * Accepts all token transfers.\n * Make sure the contract is able to use its token with {IERC721-safeTransferFrom}, {IERC721-approve} or {IERC721-setApprovalForAll}.\n */\ncontract MockERC721Receiver {\n uint256 public mode = 0;\n\n function setMode(uint256 _mode) public {\n mode = _mode;\n }\n\n function onERC721Received(address, address, uint256, bytes memory) public view returns (bytes4) {\n require(mode != 1, \"0x1111111\");\n if (mode == 2) return this.setMode.selector;\n return this.onERC721Received.selector;\n }\n}\n" + }, + "contracts/mock/MockEulerPool.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\nimport \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\n\ncontract MockEulerPool {\n IERC20 public collateral;\n uint256 public poolSize;\n //solhint-disable-next-line\n uint256 public MAX_SANE_AMOUNT;\n\n mapping(address => uint256) public users;\n uint256 public interestRateAccumulator;\n\n constructor(IERC20 collateral_, uint256 poolSize_) {\n collateral = collateral_;\n poolSize = poolSize_;\n interestRateAccumulator = 10 ** 18;\n MAX_SANE_AMOUNT = type(uint112).max;\n }\n\n function setPoolSize(uint256 poolSize_) external {\n uint256 balance = collateral.balanceOf(address(this));\n poolSize = poolSize_;\n if (balance > poolSize_) collateral.transfer(msg.sender, balance - poolSize_);\n if (balance < poolSize_) collateral.transferFrom(msg.sender, address(this), poolSize_ - balance);\n }\n\n function setInterestRateAccumulator(uint256 interestRateAccumulator_) external {\n interestRateAccumulator = interestRateAccumulator_;\n }\n\n //solhint-disable-next-line\n function setMAXSANEAMOUNT(uint256 MAX_SANE_AMOUNT_) external {\n MAX_SANE_AMOUNT = MAX_SANE_AMOUNT_;\n }\n\n function balanceOfUnderlying(address account) external view returns (uint256) {\n return (users[account] * interestRateAccumulator) / 10 ** 18;\n }\n\n function deposit(uint256, uint256 amount) external {\n users[msg.sender] += (amount * 10 ** 18) / interestRateAccumulator;\n poolSize += amount;\n collateral.transferFrom(msg.sender, address(this), amount);\n }\n\n function withdraw(uint256, uint256 amount) external {\n if (amount == type(uint256).max) amount = (users[msg.sender] * interestRateAccumulator) / 10 ** 18;\n\n require(amount <= poolSize, \"4\");\n users[msg.sender] -= (amount * 10 ** 18) / interestRateAccumulator;\n collateral.transfer(msg.sender, amount);\n }\n}\n" + }, + "contracts/mock/MockFlashLoanModule.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\nimport \"../interfaces/IFlashAngle.sol\";\nimport \"../interfaces/ICoreBorrow.sol\";\n\ncontract MockFlashLoanModule is IFlashAngle {\n ICoreBorrow public override core;\n mapping(address => bool) public stablecoinsSupported;\n mapping(IAgToken => uint256) public interestAccrued;\n uint256 public surplusValue;\n\n constructor(ICoreBorrow _core) {\n core = _core;\n }\n\n function accrueInterestToTreasury(IAgToken stablecoin) external override returns (uint256 balance) {\n balance = surplusValue;\n interestAccrued[stablecoin] += balance;\n }\n\n function addStablecoinSupport(address _treasury) external override {\n stablecoinsSupported[_treasury] = true;\n }\n\n function removeStablecoinSupport(address _treasury) external override {\n stablecoinsSupported[_treasury] = false;\n }\n\n function setCore(address _core) external override {\n core = ICoreBorrow(_core);\n }\n\n function setSurplusValue(uint256 _surplusValue) external {\n surplusValue = _surplusValue;\n }\n}\n" + }, + "contracts/mock/MockFlashLoanReceiver.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.7;\n\nimport \"@openzeppelin/contracts/token/ERC20/ERC20.sol\";\n\nimport \"@openzeppelin/contracts/interfaces/IERC3156FlashBorrower.sol\";\n\nimport \"@openzeppelin/contracts/interfaces/IERC3156FlashLender.sol\";\n\ncontract MockFlashLoanReceiver is IERC3156FlashBorrower {\n bytes32 public constant CALLBACK_SUCCESS = keccak256(\"ERC3156FlashBorrower.onFlashLoan\");\n\n constructor() {}\n\n function onFlashLoan(\n address,\n address token,\n uint256 amount,\n uint256 fee,\n bytes calldata data\n ) external override returns (bytes32) {\n IERC20(token).approve(msg.sender, amount + fee);\n if (amount >= 10 ** 21) return keccak256(\"error\");\n if (amount == 2 * 10 ** 18) {\n IERC3156FlashLender(msg.sender).flashLoan(IERC3156FlashBorrower(address(this)), token, amount, data);\n return keccak256(\"reentrant\");\n } else return CALLBACK_SUCCESS;\n }\n}\n" + }, + "contracts/mock/MockInterestRateComputer.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\ncontract MockInterestRateComputer {\n uint256 public interestRate;\n uint256 public interestAccumulator;\n uint256 public immutable baseInterest;\n uint256 public immutable halfBase;\n\n uint256 public constant WEEK = 7 * 86400;\n\n constructor(uint256 _baseInterest, uint256 _interestRate) {\n interestAccumulator = _baseInterest;\n baseInterest = _baseInterest;\n halfBase = _baseInterest / 2;\n interestRate = _interestRate;\n }\n\n function _calculateAngle(uint256 exp, uint256 _interestAccumulator) internal view returns (uint256) {\n uint256 ratePerSecond = interestRate;\n if (exp == 0 || ratePerSecond == 0) return _interestAccumulator;\n uint256 expMinusOne = exp - 1;\n uint256 expMinusTwo = exp > 2 ? exp - 2 : 0;\n uint256 basePowerTwo = (ratePerSecond * ratePerSecond) / baseInterest;\n uint256 basePowerThree = (basePowerTwo * ratePerSecond) / baseInterest;\n uint256 secondTerm = (exp * expMinusOne * basePowerTwo) / 2;\n uint256 thirdTerm = (exp * expMinusOne * expMinusTwo * basePowerThree) / 6;\n return (_interestAccumulator * (baseInterest + ratePerSecond * exp + secondTerm + thirdTerm)) / baseInterest;\n }\n\n function _calculateAave(uint256 exp, uint256 _interestAccumulator) internal view returns (uint256) {\n uint256 ratePerSecond = interestRate;\n if (exp == 0 || ratePerSecond == 0) return _interestAccumulator;\n uint256 expMinusOne = exp - 1;\n uint256 expMinusTwo = exp > 2 ? exp - 2 : 0;\n uint256 basePowerTwo = (ratePerSecond * ratePerSecond + halfBase) / baseInterest;\n uint256 basePowerThree = (basePowerTwo * ratePerSecond + halfBase) / baseInterest;\n uint256 secondTerm = (exp * expMinusOne * basePowerTwo) / 2;\n uint256 thirdTerm = (exp * expMinusOne * expMinusTwo * basePowerThree) / 6;\n return (_interestAccumulator * (baseInterest + ratePerSecond * exp + secondTerm + thirdTerm)) / baseInterest;\n }\n\n function _calculateCompound(uint256 exp, uint256 _interestAccumulator) internal view returns (uint256) {\n return _interestAccumulator * (baseInterest + interestRate * exp);\n }\n\n function _rpow(uint256 x, uint256 n, uint256 base) internal pure returns (uint256 z) {\n //solhint-disable-next-line\n assembly {\n switch x\n case 0 {\n switch n\n case 0 {\n z := base\n }\n default {\n z := 0\n }\n }\n default {\n switch mod(n, 2)\n case 0 {\n z := base\n }\n default {\n z := x\n }\n let half := div(base, 2) // for rounding.\n for {\n n := div(n, 2)\n } n {\n n := div(n, 2)\n } {\n let xx := mul(x, x)\n if iszero(eq(div(xx, x), x)) {\n revert(0, 0)\n }\n let xxRound := add(xx, half)\n if lt(xxRound, xx) {\n revert(0, 0)\n }\n x := div(xxRound, base)\n if mod(n, 2) {\n let zx := mul(z, x)\n if and(iszero(iszero(x)), iszero(eq(div(zx, x), z))) {\n revert(0, 0)\n }\n let zxRound := add(zx, half)\n if lt(zxRound, zx) {\n revert(0, 0)\n }\n z := div(zxRound, base)\n }\n }\n }\n }\n }\n\n function _calculateMaker(uint256 delta, uint256 _interestAccumulator) internal view returns (uint256) {\n return (_rpow(baseInterest + interestRate, delta, baseInterest) * _interestAccumulator) / baseInterest;\n }\n\n function calculateAngle(uint256 delta) external view returns (uint256) {\n return _calculateAngle(delta, interestAccumulator);\n }\n\n function calculateAave(uint256 delta) external view returns (uint256) {\n return _calculateAave(delta, interestAccumulator);\n }\n\n function calculateMaker(uint256 delta) external view returns (uint256) {\n return _calculateMaker(delta, interestAccumulator);\n }\n\n function calculateAngle1Year() external view returns (uint256) {\n uint256 _interestAccumulator = interestAccumulator;\n for (uint256 i; i < 52; ++i) {\n _interestAccumulator = _calculateAngle(WEEK, _interestAccumulator);\n }\n return _interestAccumulator;\n }\n\n function calculateAave1Year() external view returns (uint256) {\n uint256 _interestAccumulator = interestAccumulator;\n for (uint256 i; i < 52; ++i) {\n _interestAccumulator = _calculateAave(WEEK, _interestAccumulator);\n }\n return _interestAccumulator;\n }\n\n function calculateMaker1Year() external view returns (uint256) {\n uint256 _interestAccumulator = interestAccumulator;\n for (uint256 i; i < 52; ++i) {\n _interestAccumulator = _calculateMaker(WEEK, _interestAccumulator);\n }\n return _interestAccumulator;\n }\n\n function calculateAngle1YearDirect() external view returns (uint256) {\n uint256 _interestAccumulator = interestAccumulator;\n _interestAccumulator = _calculateAngle(52 * WEEK, _interestAccumulator);\n\n return _interestAccumulator;\n }\n\n function calculateAave1YearDirect() external view returns (uint256) {\n uint256 _interestAccumulator = interestAccumulator;\n _interestAccumulator = _calculateAave(52 * WEEK, _interestAccumulator);\n\n return _interestAccumulator;\n }\n\n function calculateMaker1YearDirect() external view returns (uint256) {\n uint256 _interestAccumulator = interestAccumulator;\n _interestAccumulator = _calculateMaker(52 * WEEK, _interestAccumulator);\n\n return _interestAccumulator;\n }\n\n function calculateCompound1YearDirect() external view returns (uint256) {\n uint256 _interestAccumulator = interestAccumulator;\n _interestAccumulator = _calculateCompound(52 * WEEK, _interestAccumulator);\n\n return _interestAccumulator;\n }\n}\n" + }, + "contracts/mock/MockKeeperMulticall.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.12;\n\nimport \"@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/access/AccessControlUpgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol\";\nimport \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\nimport \"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\";\n\ncontract MockKeeperMulticall is Initializable, AccessControlUpgradeable {\n using SafeERC20 for IERC20;\n\n bytes32 public constant KEEPER_ROLE = keccak256(\"KEEPER_ROLE\");\n\n //solhint-disable-next-line\n address private constant _oneInch = 0x1111111254fb6c44bAC0beD2854e76F90643097d;\n\n struct Action {\n address target;\n bytes data;\n bool isDelegateCall;\n }\n\n event LogAction(address indexed target, bytes data);\n event SentToMiner(uint256 indexed value);\n event Recovered(address indexed tokenAddress, address indexed to, uint256 amount);\n\n error AmountOutTooLow(uint256 amount, uint256 min);\n error BalanceTooLow();\n error FlashbotsErrorPayingMiner(uint256 value);\n error IncompatibleLengths();\n error RevertBytes();\n error ZeroAddress();\n\n constructor() initializer {}\n\n function initialize(address keeper) public initializer {\n __AccessControl_init();\n\n _setupRole(KEEPER_ROLE, keeper);\n _setRoleAdmin(KEEPER_ROLE, KEEPER_ROLE);\n }\n}\n\ncontract MockKeeperMulticall2 {\n uint256 public varTest = 1;\n\n bytes32 public constant KEEPER_ROLE = keccak256(\"KEEPER_ROLE\");\n\n //solhint-disable-next-line\n address private constant _oneInch = 0x1111111254fb6c44bAC0beD2854e76F90643097d;\n\n struct Action {\n address target;\n bytes data;\n bool isDelegateCall;\n }\n\n event LogAction(address indexed target, bytes data);\n event SentToMiner(uint256 indexed value);\n event Recovered(address indexed tokenAddress, address indexed to, uint256 amount);\n\n error AmountOutTooLow(uint256 amount, uint256 min);\n error BalanceTooLow();\n error FlashbotsErrorPayingMiner(uint256 value);\n error IncompatibleLengths();\n error RevertBytes();\n error ZeroAddress();\n\n function functionTest() external pure returns (bool) {\n return true;\n }\n}\n" + }, + "contracts/mock/MockLayerZero.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\ninterface ILzApp {\n function lzReceive(uint16 _srcChainId, bytes memory _srcAddress, uint64 _nonce, bytes memory _payload) external;\n}\n\ncontract MockLayerZero {\n mapping(uint16 => uint256) public counters;\n uint256 public config;\n mapping(uint16 => uint64) public outboundNonce;\n uint256 public resumeReceived;\n uint256 public sendVersion;\n uint256 public receiveVersion;\n\n /// @notice Initiate with a fixe change rate\n constructor() {}\n\n function send(\n uint16 _dstChainId,\n bytes calldata,\n bytes calldata,\n address,\n address,\n bytes calldata\n ) external payable {\n counters[_dstChainId] += 1;\n }\n\n function getOutboundNonce(uint16 _dstChainId, address) external view returns (uint64) {\n return outboundNonce[_dstChainId];\n }\n\n function setOutBoundNonce(uint16 _from, uint64 value) external {\n outboundNonce[_from] = value;\n }\n\n function lzReceive(\n address lzApp,\n uint16 _srcChainId,\n bytes memory _srcAddress,\n uint64 _nonce,\n bytes memory _payload\n ) public {\n ILzApp(lzApp).lzReceive(_srcChainId, _srcAddress, _nonce, _payload);\n }\n\n function estimateFees(\n uint16,\n address,\n bytes calldata,\n bool,\n bytes calldata\n ) external pure returns (uint256 nativeFee, uint256 zroFee) {\n return (123, 456);\n }\n\n function setConfig(uint16, uint16, uint256 _configType, bytes calldata) external {\n config = _configType;\n }\n\n function getConfig(uint16, uint16, address, uint256) external view returns (bytes memory) {\n return abi.encodePacked(config);\n }\n\n function setSendVersion(uint16 _version) external {\n sendVersion = _version;\n }\n\n function setReceiveVersion(uint16 _version) external {\n receiveVersion = _version;\n }\n\n function forceResumeReceive(uint16, bytes calldata) external {\n resumeReceived = 1 - resumeReceived;\n }\n}\n" + }, + "contracts/mock/MockLiquidityGauge.sol": { + "content": "// SPDX-License-Identifier: UNLICENSED\npragma solidity ^0.8.12;\n\nimport { ILiquidityGauge } from \"../interfaces/coreModule/ILiquidityGauge.sol\";\nimport \"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\";\nimport \"@openzeppelin/contracts/token/ERC20/ERC20.sol\";\n\ncontract MockLiquidityGauge is ILiquidityGauge, ERC20 {\n using SafeERC20 for IERC20;\n\n IERC20 internal _ANGLE = IERC20(0x31429d1856aD1377A8A0079410B297e1a9e214c2);\n IERC20 internal _token;\n mapping(address => uint256) public rewards;\n\n constructor(string memory name_, string memory symbol_, address token_) ERC20(name_, symbol_) {\n _token = IERC20(token_);\n }\n\n function deposit(\n uint256 _value,\n address _addr,\n // solhint-disable-next-line\n bool\n ) external {\n _token.safeTransferFrom(msg.sender, address(this), _value);\n _mint(_addr, _value);\n }\n\n function withdraw(\n uint256 _value,\n // solhint-disable-next-line\n bool\n ) external {\n _burn(msg.sender, _value);\n _token.safeTransfer(msg.sender, _value);\n }\n\n // solhint-disable-next-line\n function claim_rewards(address _addr, address _receiver) external {\n if (_receiver == address(0)) _receiver = _addr;\n _ANGLE.safeTransfer(_receiver, rewards[_addr]);\n rewards[_addr] = 0;\n }\n\n // solhint-disable-next-line\n function claimable_reward(address _addr, address) external view returns (uint256 amount) {\n return rewards[_addr];\n }\n\n function setReward(address receiver_, uint256 amount) external {\n rewards[receiver_] = amount;\n }\n}\n" + }, + "contracts/mock/MockOracle.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.7;\n\nimport \"../interfaces/IOracle.sol\";\n\ncontract MockOracle is IOracle {\n event Update(uint256 _peg);\n\n ITreasury public treasury;\n\n uint256 public base = 1 ether;\n uint256 public precision = 1 ether;\n uint256 public rate;\n bool public outdated;\n\n /// @notice Initiate with a fixe change rate\n constructor(uint256 rate_, ITreasury _treasury) {\n rate = rate_;\n treasury = _treasury;\n }\n\n /// @notice Mock read\n function read() external view override returns (uint256) {\n return rate;\n }\n\n /// @notice change oracle rate\n function update(uint256 newRate) external {\n rate = newRate;\n }\n\n function setTreasury(address _treasury) external override {\n treasury = ITreasury(_treasury);\n }\n\n function circuitChainlink() external pure override returns (AggregatorV3Interface[] memory) {}\n}\n" + }, + "contracts/mock/MockPolygonAgEUR.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.12;\n\nimport \"../agToken/polygon/utils/ERC20UpgradeableCustom.sol\";\nimport \"@openzeppelin/contracts-upgradeable/access/AccessControlUpgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/utils/cryptography/draft-EIP712Upgradeable.sol\";\nimport \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\nimport \"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\";\n\nimport \"../interfaces/IAgToken.sol\";\nimport \"../interfaces/ITreasury.sol\";\n\ninterface IChildToken {\n function deposit(address user, bytes calldata depositData) external;\n\n function withdraw(uint256 amount) external;\n}\n\ncontract MockPolygonAgEUR is\n Initializable,\n ERC20UpgradeableCustom,\n AccessControlUpgradeable,\n EIP712Upgradeable,\n IChildToken\n{\n bytes32 public constant DEPOSITOR_ROLE = keccak256(\"DEPOSITOR_ROLE\");\n\n /// @dev Emitted when the child chain manager changes\n event ChildChainManagerAdded(address newAddress);\n event ChildChainManagerRevoked(address oldAddress);\n\n constructor() initializer {}\n\n function initialize(\n string memory _name,\n string memory _symbol,\n address childChainManager,\n address guardian\n ) public initializer {\n __ERC20_init(_name, _symbol);\n __AccessControl_init();\n _setupRole(DEFAULT_ADMIN_ROLE, guardian);\n _setupRole(DEPOSITOR_ROLE, childChainManager);\n __EIP712_init(_name, \"1\");\n }\n\n /**\n * @notice Called when the bridge has tokens to mint\n * @param user Address to mint the token to\n * @param depositData Encoded amount to mint\n */\n function deposit(address user, bytes calldata depositData) external override {\n require(hasRole(DEPOSITOR_ROLE, msg.sender));\n uint256 amount = abi.decode(depositData, (uint256));\n _mint(user, amount);\n }\n\n /**\n * @notice Called when user wants to withdraw tokens back to root chain\n * @dev Should burn user's tokens. This transaction will be verified when exiting on root chain\n * @param amount Amount of tokens to withdraw\n */\n function withdraw(uint256 amount) external override {\n _burn(_msgSender(), amount);\n }\n\n // =============================================================================\n // ======================= New data added for the upgrade ======================\n // =============================================================================\n\n mapping(address => bool) public isMinter;\n /// @notice Reference to the treasury contract which can grant minting rights\n address public treasury;\n /// @notice Boolean to check whether the contract has been reinitialized after its upgrade\n bool public treasuryInitialized;\n\n using SafeERC20 for IERC20;\n\n /// @notice Base used for fee computation\n uint256 public constant BASE_PARAMS = 10 ** 9;\n\n // =============================== Bridging Data ===============================\n\n /// @notice Struct with some data about a specific bridge token\n struct BridgeDetails {\n // Limit on the balance of bridge token held by the contract: it is designed\n // to reduce the exposure of the system to hacks\n uint256 limit;\n // Limit on the hourly volume of token minted through this bridge\n // Technically the limit over a rolling hour is hourlyLimit x2 as hourly limit\n // is enforced only between x:00 and x+1:00\n uint256 hourlyLimit;\n // Fee taken for swapping in and out the token\n uint64 fee;\n // Whether the associated token is allowed or not\n bool allowed;\n // Whether swapping in and out from the associated token is paused or not\n bool paused;\n }\n\n /// @notice Maps a bridge token to data\n mapping(address => BridgeDetails) public bridges;\n /// @notice List of all bridge tokens\n address[] public bridgeTokensList;\n /// @notice Maps a bridge token to the associated hourly volume\n mapping(address => mapping(uint256 => uint256)) public usage;\n /// @notice Maps an address to whether it is exempt of fees for when it comes to swapping in and out\n mapping(address => uint256) public isFeeExempt;\n\n uint256[44] private __gap;\n\n // ================================== Events ===================================\n\n event BridgeTokenAdded(address indexed bridgeToken, uint256 limit, uint256 hourlyLimit, uint64 fee, bool paused);\n event BridgeTokenToggled(address indexed bridgeToken, bool toggleStatus);\n event BridgeTokenRemoved(address indexed bridgeToken);\n event BridgeTokenFeeUpdated(address indexed bridgeToken, uint64 fee);\n event BridgeTokenLimitUpdated(address indexed bridgeToken, uint256 limit);\n event BridgeTokenHourlyLimitUpdated(address indexed bridgeToken, uint256 hourlyLimit);\n event HourlyLimitUpdated(uint256 hourlyLimit);\n event FeeToggled(address indexed theAddress, uint256 toggleStatus);\n event KeeperToggled(address indexed keeper, bool toggleStatus);\n event MinterToggled(address indexed minter);\n event Recovered(address indexed token, address indexed to, uint256 amount);\n event TreasuryUpdated(address indexed _treasury);\n\n // ================================== Errors ===================================\n\n error AssetStillControlledInReserves();\n error BurnAmountExceedsAllowance();\n error HourlyLimitExceeded();\n error InvalidSender();\n error InvalidToken();\n error InvalidTreasury();\n error NotGovernor();\n error NotGovernorOrGuardian();\n error NotMinter();\n error NotTreasury();\n error TooBigAmount();\n error TooHighParameterValue();\n error TreasuryAlreadyInitialized();\n error ZeroAddress();\n\n /// @notice Checks to see if it is the `Treasury` calling this contract\n /// @dev There is no Access Control here, because it can be handled cheaply through this modifier\n modifier onlyTreasury() {\n if (msg.sender != treasury) revert NotTreasury();\n _;\n }\n\n /// @notice Checks whether the sender has the minting right\n modifier onlyMinter() {\n if (!isMinter[msg.sender]) revert NotMinter();\n _;\n }\n\n /// @notice Checks whether the `msg.sender` has the governor role or not\n modifier onlyGovernor() {\n if (!ITreasury(treasury).isGovernor(msg.sender)) revert NotGovernor();\n _;\n }\n\n /// @notice Checks whether the `msg.sender` has the governor role or the guardian role\n modifier onlyGovernorOrGuardian() {\n if (!ITreasury(treasury).isGovernorOrGuardian(msg.sender)) revert NotGovernorOrGuardian();\n _;\n }\n\n /// @notice Sets up the treasury contract on Polygon after the upgrade\n /// @param _treasury Address of the treasury contract\n function setUpTreasury(address _treasury) external {\n // Only governor on Polygon\n if (msg.sender != 0xdA2D2f638D6fcbE306236583845e5822554c02EA) revert NotGovernor();\n if (address(ITreasury(_treasury).stablecoin()) != address(this)) revert InvalidTreasury();\n if (treasuryInitialized) revert TreasuryAlreadyInitialized();\n treasury = _treasury;\n treasuryInitialized = true;\n emit TreasuryUpdated(_treasury);\n }\n\n // =========================== External Function ===============================\n\n /// @notice Allows anyone to burn agToken without redeeming collateral back\n /// @param amount Amount of stablecoins to burn\n /// @dev This function can typically be called if there is a settlement mechanism to burn stablecoins\n function burnStablecoin(uint256 amount) external {\n _burnCustom(msg.sender, amount);\n }\n\n // ======================= Minter Role Only Functions ==========================\n\n function burnSelf(uint256 amount, address burner) external onlyMinter {\n _burnCustom(burner, amount);\n }\n\n function burnFrom(uint256 amount, address burner, address sender) external onlyMinter {\n _burnFromNoRedeem(amount, burner, sender);\n }\n\n function mint(address account, uint256 amount) external onlyMinter {\n _mint(account, amount);\n }\n\n // ======================= Treasury Only Functions =============================\n\n function addMinter(address minter) external onlyTreasury {\n isMinter[minter] = true;\n emit MinterToggled(minter);\n }\n\n function removeMinter(address minter) external {\n if (msg.sender != address(treasury) && msg.sender != minter) revert InvalidSender();\n isMinter[minter] = false;\n emit MinterToggled(minter);\n }\n\n function setTreasury(address _treasury) external onlyTreasury {\n treasury = _treasury;\n emit TreasuryUpdated(_treasury);\n }\n\n // ============================ Internal Function ==============================\n\n /// @notice Internal version of the function `burnFromNoRedeem`\n /// @param amount Amount to burn\n /// @dev It is at the level of this function that allowance checks are performed\n function _burnFromNoRedeem(uint256 amount, address burner, address sender) internal {\n if (burner != sender) {\n uint256 currentAllowance = allowance(burner, sender);\n if (currentAllowance < amount) revert BurnAmountExceedsAllowance();\n _approve(burner, sender, currentAllowance - amount);\n }\n _burnCustom(burner, amount);\n }\n\n // ==================== External Permissionless Functions ======================\n\n /// @notice Returns the list of all supported bridge tokens\n /// @dev Helpful for UIs\n function allBridgeTokens() external view returns (address[] memory) {\n return bridgeTokensList;\n }\n\n /// @notice Returns the current volume for a bridge, for the current hour\n /// @dev Helpful for UIs\n function currentUsage(address bridge) external view returns (uint256) {\n return usage[bridge][block.timestamp / 3600];\n }\n\n /// @notice Mints the canonical token from a supported bridge token\n /// @param bridgeToken Bridge token to use to mint\n /// @param amount Amount of bridge tokens to send\n /// @param to Address to which the stablecoin should be sent\n /// @dev Some fees may be taken by the protocol depending on the token used and on the address calling\n function swapIn(address bridgeToken, uint256 amount, address to) external returns (uint256) {\n BridgeDetails memory bridgeDetails = bridges[bridgeToken];\n if (!bridgeDetails.allowed || bridgeDetails.paused) revert InvalidToken();\n uint256 balance = IERC20(bridgeToken).balanceOf(address(this));\n if (balance + amount > bridgeDetails.limit) {\n // In case someone maliciously sends tokens to this contract\n // Or the limit changes\n if (bridgeDetails.limit > balance) amount = bridgeDetails.limit - balance;\n else {\n amount = 0;\n }\n }\n\n // Checking requirement on the hourly volume\n uint256 hour = block.timestamp / 3600;\n uint256 hourlyUsage = usage[bridgeToken][hour] + amount;\n if (hourlyUsage > bridgeDetails.hourlyLimit) {\n // Edge case when the hourly limit changes\n if (bridgeDetails.hourlyLimit > usage[bridgeToken][hour])\n amount = bridgeDetails.hourlyLimit - usage[bridgeToken][hour];\n else {\n amount = 0;\n }\n }\n usage[bridgeToken][hour] = usage[bridgeToken][hour] + amount;\n\n IERC20(bridgeToken).safeTransferFrom(msg.sender, address(this), amount);\n uint256 canonicalOut = amount;\n // Computing fees\n if (isFeeExempt[msg.sender] == 0) {\n canonicalOut -= (canonicalOut * bridgeDetails.fee) / BASE_PARAMS;\n }\n _mint(to, canonicalOut);\n return canonicalOut;\n }\n\n /// @notice Burns the canonical token in exchange for a bridge token\n /// @param bridgeToken Bridge token required\n /// @param amount Amount of canonical tokens to burn\n /// @param to Address to which the bridge token should be sent\n /// @dev Some fees may be taken by the protocol depending on the token used and on the address calling\n function swapOut(address bridgeToken, uint256 amount, address to) external returns (uint256) {\n BridgeDetails memory bridgeDetails = bridges[bridgeToken];\n if (!bridgeDetails.allowed || bridgeDetails.paused) revert InvalidToken();\n\n _burnCustom(msg.sender, amount);\n uint256 bridgeOut = amount;\n if (isFeeExempt[msg.sender] == 0) {\n bridgeOut -= (bridgeOut * bridgeDetails.fee) / BASE_PARAMS;\n }\n IERC20(bridgeToken).safeTransfer(to, bridgeOut);\n return bridgeOut;\n }\n\n // ======================= Governance Functions ================================\n\n /// @notice Adds support for a bridge token\n /// @param bridgeToken Bridge token to add: it should be a version of the stablecoin from another bridge\n /// @param limit Limit on the balance of bridge token this contract could hold\n /// @param hourlyLimit Limit on the hourly volume for this bridge\n /// @param paused Whether swapping for this token should be paused or not\n /// @param fee Fee taken upon swapping for or against this token\n function addBridgeToken(\n address bridgeToken,\n uint256 limit,\n uint256 hourlyLimit,\n uint64 fee,\n bool paused\n ) external onlyGovernor {\n if (bridges[bridgeToken].allowed || bridgeToken == address(0)) revert InvalidToken();\n if (fee > BASE_PARAMS) revert TooHighParameterValue();\n BridgeDetails memory _bridge;\n _bridge.limit = limit;\n _bridge.hourlyLimit = hourlyLimit;\n _bridge.paused = paused;\n _bridge.fee = fee;\n _bridge.allowed = true;\n bridges[bridgeToken] = _bridge;\n bridgeTokensList.push(bridgeToken);\n emit BridgeTokenAdded(bridgeToken, limit, hourlyLimit, fee, paused);\n }\n\n /// @notice Removes support for a token\n /// @param bridgeToken Address of the bridge token to remove support for\n function removeBridgeToken(address bridgeToken) external onlyGovernor {\n if (IERC20(bridgeToken).balanceOf(address(this)) != 0) revert AssetStillControlledInReserves();\n delete bridges[bridgeToken];\n // Deletion from `bridgeTokensList` loop\n uint256 bridgeTokensListLength = bridgeTokensList.length;\n for (uint256 i; i < bridgeTokensListLength - 1; ++i) {\n if (bridgeTokensList[i] == bridgeToken) {\n // Replace the `bridgeToken` to remove with the last of the list\n bridgeTokensList[i] = bridgeTokensList[bridgeTokensListLength - 1];\n break;\n }\n }\n // Remove last element in array\n bridgeTokensList.pop();\n emit BridgeTokenRemoved(bridgeToken);\n }\n\n /// @notice Recovers any ERC20 token\n /// @dev Can be used to withdraw bridge tokens for them to be de-bridged on mainnet\n function recoverERC20(address tokenAddress, address to, uint256 amountToRecover) external onlyGovernor {\n IERC20(tokenAddress).safeTransfer(to, amountToRecover);\n emit Recovered(tokenAddress, to, amountToRecover);\n }\n\n /// @notice Updates the `limit` amount for `bridgeToken`\n function setLimit(address bridgeToken, uint256 limit) external onlyGovernorOrGuardian {\n if (!bridges[bridgeToken].allowed) revert InvalidToken();\n bridges[bridgeToken].limit = limit;\n emit BridgeTokenLimitUpdated(bridgeToken, limit);\n }\n\n /// @notice Updates the `hourlyLimit` amount for `bridgeToken`\n function setHourlyLimit(address bridgeToken, uint256 hourlyLimit) external onlyGovernorOrGuardian {\n if (!bridges[bridgeToken].allowed) revert InvalidToken();\n bridges[bridgeToken].hourlyLimit = hourlyLimit;\n emit BridgeTokenHourlyLimitUpdated(bridgeToken, hourlyLimit);\n }\n\n /// @notice Updates the `fee` value for `bridgeToken`\n function setSwapFee(address bridgeToken, uint64 fee) external onlyGovernorOrGuardian {\n if (!bridges[bridgeToken].allowed) revert InvalidToken();\n if (fee > BASE_PARAMS) revert TooHighParameterValue();\n bridges[bridgeToken].fee = fee;\n emit BridgeTokenFeeUpdated(bridgeToken, fee);\n }\n\n /// @notice Pauses or unpauses swapping in and out for a token\n function toggleBridge(address bridgeToken) external onlyGovernorOrGuardian {\n if (!bridges[bridgeToken].allowed) revert InvalidToken();\n bool pausedStatus = bridges[bridgeToken].paused;\n bridges[bridgeToken].paused = !pausedStatus;\n emit BridgeTokenToggled(bridgeToken, !pausedStatus);\n }\n\n /// @notice Toggles fees for the address `theAddress`\n function toggleFeesForAddress(address theAddress) external onlyGovernorOrGuardian {\n uint256 feeExemptStatus = 1 - isFeeExempt[theAddress];\n isFeeExempt[theAddress] = feeExemptStatus;\n emit FeeToggled(theAddress, feeExemptStatus);\n }\n}\n" + }, + "contracts/mock/MockRouter.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\nimport \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\nimport \"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\";\n\nimport \"../interfaces/IAngleRouter.sol\";\nimport \"../interfaces/external/uniswap/IUniswapRouter.sol\";\nimport \"../interfaces/external/lido/IWStETH.sol\";\n\ncontract MockRouter is IUniswapV3Router, IWStETH {\n using SafeERC20 for IERC20;\n\n uint256 public counterAngleMint;\n uint256 public counterAngleBurn;\n uint256 public counter1Inch;\n uint256 public counterUni;\n uint256 public counterWrap;\n uint256 public counterMixer;\n uint256 public amountOutUni;\n uint256 public multiplierMintBurn;\n uint256 public stETHMultiplier;\n address public inToken;\n address public outToken;\n\n address public stETH;\n\n /// @notice Action types\n enum ActionType {\n transfer,\n wrap,\n wrapNative,\n sweep,\n sweepNative,\n unwrap,\n unwrapNative,\n swapIn,\n swapOut,\n uniswapV3,\n oneInch,\n claimRewards,\n gaugeDeposit,\n borrower\n }\n\n /// @notice Data needed to get permits\n struct PermitType {\n address token;\n address owner;\n uint256 value;\n uint256 deadline;\n uint8 v;\n bytes32 r;\n bytes32 s;\n }\n\n constructor() {}\n\n function mint(address user, uint256 amount, uint256, address stablecoin, address collateral) external {\n counterAngleMint += 1;\n IERC20(collateral).safeTransferFrom(msg.sender, address(this), amount);\n IERC20(stablecoin).safeTransfer(user, (amount * 10 ** 9) / multiplierMintBurn);\n }\n\n function setStETH(address _stETH) external {\n stETH = _stETH;\n }\n\n function burn(address user, uint256 amount, uint256, address stablecoin, address collateral) external {\n counterAngleBurn += 1;\n IERC20(stablecoin).safeTransferFrom(msg.sender, address(this), amount);\n IERC20(collateral).safeTransfer(user, (amount * multiplierMintBurn) / 10 ** 9);\n }\n\n function mixer(\n PermitType[] memory paramsPermit,\n ActionType[] memory actions,\n bytes[] calldata data\n ) public payable virtual {\n paramsPermit;\n counterMixer += 1;\n for (uint256 i; i < actions.length; ++i) {\n if (actions[i] == ActionType.transfer) {\n (address transferToken, uint256 amount) = abi.decode(data[i], (address, uint256));\n IERC20(transferToken).safeTransferFrom(msg.sender, address(this), amount);\n }\n }\n }\n\n function wrap(uint256 amount) external returns (uint256 amountOut) {\n amountOut = (amount * stETHMultiplier) / 10 ** 9;\n counterWrap += 1;\n IERC20(stETH).safeTransferFrom(msg.sender, address(this), amount);\n IERC20(outToken).safeTransfer(msg.sender, amountOut);\n }\n\n function oneInch(uint256 amountIn) external returns (uint256 amountOut) {\n counter1Inch += 1;\n amountOut = (amountOutUni * amountIn) / 10 ** 9;\n IERC20(inToken).safeTransferFrom(msg.sender, address(this), amountIn);\n IERC20(outToken).safeTransfer(msg.sender, amountOut);\n }\n\n function oneInchReverts() external {\n counter1Inch += 1;\n revert(\"wrong swap\");\n }\n\n function oneInchRevertsWithoutMessage() external {\n counter1Inch += 1;\n require(false);\n }\n\n function exactInput(ExactInputParams calldata params) external payable returns (uint256 amountOut) {\n counterUni += 1;\n amountOut = (params.amountIn * amountOutUni) / 10 ** 9;\n IERC20(inToken).safeTransferFrom(msg.sender, address(this), params.amountIn);\n IERC20(outToken).safeTransfer(params.recipient, amountOut);\n require(amountOut >= params.amountOutMinimum);\n }\n\n function setMultipliers(uint256 a, uint256 b) external {\n amountOutUni = a;\n multiplierMintBurn = b;\n }\n\n function setStETHMultiplier(uint256 value) external {\n stETHMultiplier = value;\n }\n\n function setInOut(address _collateral, address _stablecoin) external {\n inToken = _collateral;\n outToken = _stablecoin;\n }\n}\n" + }, + "contracts/mock/MockSidechainAgEUR.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\nimport \"../agToken/AgToken.sol\";\nimport \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\nimport \"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\";\n\n/// @title AgTokenSideChainMultiBridge\n/// @author Angle Labs, Inc.\n/// @notice Contract for Angle agTokens on other chains than Ethereum mainnet\n/// @dev This contract supports bridge tokens having a minting right on the stablecoin (also referred to as the canonical\n/// or the native token)\n/// @dev References:\n/// - FRAX implementation: https://polygonscan.com/address/0x45c32fA6DF82ead1e2EF74d17b76547EDdFaFF89#code\n/// - QiDAO implementation: https://snowtrace.io/address/0x5c49b268c9841AFF1Cc3B0a418ff5c3442eE3F3b#code\ncontract MockSidechainAgEUR is AgToken {\n using SafeERC20 for IERC20;\n\n /// @notice Base used for fee computation\n uint256 public constant BASE_PARAMS = 10 ** 9;\n\n // =============================== Bridging Data ===============================\n\n /// @notice Struct with some data about a specific bridge token\n struct BridgeDetails {\n // Limit on the balance of bridge token held by the contract: it is designed\n // to reduce the exposure of the system to hacks\n uint256 limit;\n // Limit on the hourly volume of token minted through this bridge\n // Technically the limit over a rolling hour is hourlyLimit x2 as hourly limit\n // is enforced only between x:00 and x+1:00\n uint256 hourlyLimit;\n // Fee taken for swapping in and out the token\n uint64 fee;\n // Whether the associated token is allowed or not\n bool allowed;\n // Whether swapping in and out from the associated token is paused or not\n bool paused;\n }\n\n /// @notice Maps a bridge token to data\n mapping(address => BridgeDetails) public bridges;\n /// @notice List of all bridge tokens\n address[] public bridgeTokensList;\n /// @notice Maps a bridge token to the associated hourly volume\n mapping(address => mapping(uint256 => uint256)) public usage;\n /// @notice Maps an address to whether it is exempt of fees for when it comes to swapping in and out\n mapping(address => uint256) public isFeeExempt;\n\n // ================================== Events ===================================\n\n event BridgeTokenAdded(address indexed bridgeToken, uint256 limit, uint256 hourlyLimit, uint64 fee, bool paused);\n event BridgeTokenToggled(address indexed bridgeToken, bool toggleStatus);\n event BridgeTokenRemoved(address indexed bridgeToken);\n event BridgeTokenFeeUpdated(address indexed bridgeToken, uint64 fee);\n event BridgeTokenLimitUpdated(address indexed bridgeToken, uint256 limit);\n event BridgeTokenHourlyLimitUpdated(address indexed bridgeToken, uint256 hourlyLimit);\n event HourlyLimitUpdated(uint256 hourlyLimit);\n event Recovered(address indexed token, address indexed to, uint256 amount);\n event FeeToggled(address indexed theAddress, uint256 toggleStatus);\n\n // =============================== Errors ================================\n\n error AssetStillControlledInReserves();\n error HourlyLimitExceeded();\n error InvalidToken();\n error NotGovernor();\n error NotGovernorOrGuardian();\n error TooBigAmount();\n error TooHighParameterValue();\n error ZeroAddress();\n\n // ============================= Constructor ===================================\n\n /// @notice Checks whether the `msg.sender` has the governor role or not\n modifier onlyGovernor() {\n if (!ITreasury(treasury).isGovernor(msg.sender)) revert NotGovernor();\n _;\n }\n\n /// @notice Checks whether the `msg.sender` has the governor role or the guardian role\n modifier onlyGovernorOrGuardian() {\n if (!ITreasury(treasury).isGovernorOrGuardian(msg.sender)) revert NotGovernorOrGuardian();\n _;\n }\n\n // ==================== External Permissionless Functions ======================\n\n /// @notice Returns the list of all supported bridge tokens\n /// @dev Helpful for UIs\n function allBridgeTokens() external view returns (address[] memory) {\n return bridgeTokensList;\n }\n\n /// @notice Returns the current volume for a bridge, for the current hour\n /// @param bridgeToken Bridge used to mint\n /// @dev Helpful for UIs\n function currentUsage(address bridgeToken) external view returns (uint256) {\n return usage[bridgeToken][block.timestamp / 3600];\n }\n\n /// @notice Mints the canonical token from a supported bridge token\n /// @param bridgeToken Bridge token to use to mint\n /// @param amount Amount of bridge tokens to send\n /// @param to Address to which the stablecoin should be sent\n /// @return Amount of the canonical stablecoin actually minted\n /// @dev Some fees may be taken by the protocol depending on the token used and on the address calling\n function swapIn(address bridgeToken, uint256 amount, address to) external returns (uint256) {\n BridgeDetails memory bridgeDetails = bridges[bridgeToken];\n if (!bridgeDetails.allowed || bridgeDetails.paused) revert InvalidToken();\n uint256 balance = IERC20(bridgeToken).balanceOf(address(this));\n if (balance + amount > bridgeDetails.limit) {\n // In case someone maliciously sends tokens to this contract\n // Or the limit changes\n if (bridgeDetails.limit > balance) amount = bridgeDetails.limit - balance;\n else {\n amount = 0;\n }\n }\n\n // Checking requirement on the hourly volume\n uint256 hour = block.timestamp / 3600;\n uint256 hourlyUsage = usage[bridgeToken][hour] + amount;\n if (hourlyUsage > bridgeDetails.hourlyLimit) {\n // Edge case when the hourly limit changes\n if (bridgeDetails.hourlyLimit > usage[bridgeToken][hour])\n amount = bridgeDetails.hourlyLimit - usage[bridgeToken][hour];\n else {\n amount = 0;\n }\n }\n usage[bridgeToken][hour] = usage[bridgeToken][hour] + amount;\n\n IERC20(bridgeToken).safeTransferFrom(msg.sender, address(this), amount);\n uint256 canonicalOut = amount;\n // Computing fees\n if (isFeeExempt[msg.sender] == 0) {\n canonicalOut -= (canonicalOut * bridgeDetails.fee) / BASE_PARAMS;\n }\n _mint(to, canonicalOut);\n return canonicalOut;\n }\n\n /// @notice Burns the canonical token in exchange for a bridge token\n /// @param bridgeToken Bridge token required\n /// @param amount Amount of canonical tokens to burn\n /// @param to Address to which the bridge token should be sent\n /// @return Amount of bridge tokens actually sent back\n /// @dev Some fees may be taken by the protocol depending on the token used and on the address calling\n function swapOut(address bridgeToken, uint256 amount, address to) external returns (uint256) {\n BridgeDetails memory bridgeDetails = bridges[bridgeToken];\n if (!bridgeDetails.allowed || bridgeDetails.paused) revert InvalidToken();\n\n _burn(msg.sender, amount);\n uint256 bridgeOut = amount;\n if (isFeeExempt[msg.sender] == 0) {\n bridgeOut -= (bridgeOut * bridgeDetails.fee) / BASE_PARAMS;\n }\n IERC20(bridgeToken).safeTransfer(to, bridgeOut);\n return bridgeOut;\n }\n\n // ======================= Governance Functions ================================\n\n /// @notice Adds support for a bridge token\n /// @param bridgeToken Bridge token to add: it should be a version of the stablecoin from another bridge\n /// @param limit Limit on the balance of bridge token this contract could hold\n /// @param hourlyLimit Limit on the hourly volume for this bridge\n /// @param paused Whether swapping for this token should be paused or not\n /// @param fee Fee taken upon swapping for or against this token\n function addBridgeToken(\n address bridgeToken,\n uint256 limit,\n uint256 hourlyLimit,\n uint64 fee,\n bool paused\n ) external onlyGovernor {\n if (bridges[bridgeToken].allowed || bridgeToken == address(0)) revert InvalidToken();\n if (fee > BASE_PARAMS) revert TooHighParameterValue();\n BridgeDetails memory _bridge;\n _bridge.limit = limit;\n _bridge.hourlyLimit = hourlyLimit;\n _bridge.paused = paused;\n _bridge.fee = fee;\n _bridge.allowed = true;\n bridges[bridgeToken] = _bridge;\n bridgeTokensList.push(bridgeToken);\n emit BridgeTokenAdded(bridgeToken, limit, hourlyLimit, fee, paused);\n }\n\n /// @notice Removes support for a token\n /// @param bridgeToken Address of the bridge token to remove support for\n function removeBridgeToken(address bridgeToken) external onlyGovernor {\n if (IERC20(bridgeToken).balanceOf(address(this)) != 0) revert AssetStillControlledInReserves();\n delete bridges[bridgeToken];\n // Deletion from `bridgeTokensList` loop\n uint256 bridgeTokensListLength = bridgeTokensList.length;\n for (uint256 i; i < bridgeTokensListLength - 1; ++i) {\n if (bridgeTokensList[i] == bridgeToken) {\n // Replace the `bridgeToken` to remove with the last of the list\n bridgeTokensList[i] = bridgeTokensList[bridgeTokensListLength - 1];\n break;\n }\n }\n // Remove last element in array\n bridgeTokensList.pop();\n emit BridgeTokenRemoved(bridgeToken);\n }\n\n /// @notice Recovers any ERC20 token\n /// @dev Can be used to withdraw bridge tokens for them to be de-bridged on mainnet\n function recoverERC20(address tokenAddress, address to, uint256 amountToRecover) external onlyGovernor {\n IERC20(tokenAddress).safeTransfer(to, amountToRecover);\n emit Recovered(tokenAddress, to, amountToRecover);\n }\n\n /// @notice Updates the `limit` amount for `bridgeToken`\n function setLimit(address bridgeToken, uint256 limit) external onlyGovernorOrGuardian {\n if (!bridges[bridgeToken].allowed) revert InvalidToken();\n bridges[bridgeToken].limit = limit;\n emit BridgeTokenLimitUpdated(bridgeToken, limit);\n }\n\n /// @notice Updates the `hourlyLimit` amount for `bridgeToken`\n function setHourlyLimit(address bridgeToken, uint256 hourlyLimit) external onlyGovernorOrGuardian {\n if (!bridges[bridgeToken].allowed) revert InvalidToken();\n bridges[bridgeToken].hourlyLimit = hourlyLimit;\n emit BridgeTokenHourlyLimitUpdated(bridgeToken, hourlyLimit);\n }\n\n /// @notice Updates the `fee` value for `bridgeToken`\n function setSwapFee(address bridgeToken, uint64 fee) external onlyGovernorOrGuardian {\n if (!bridges[bridgeToken].allowed) revert InvalidToken();\n if (fee > BASE_PARAMS) revert TooHighParameterValue();\n bridges[bridgeToken].fee = fee;\n emit BridgeTokenFeeUpdated(bridgeToken, fee);\n }\n\n /// @notice Pauses or unpauses swapping in and out for a token\n function toggleBridge(address bridgeToken) external onlyGovernorOrGuardian {\n if (!bridges[bridgeToken].allowed) revert InvalidToken();\n bool pausedStatus = bridges[bridgeToken].paused;\n bridges[bridgeToken].paused = !pausedStatus;\n emit BridgeTokenToggled(bridgeToken, !pausedStatus);\n }\n\n /// @notice Toggles fees for the address `theAddress`\n function toggleFeesForAddress(address theAddress) external onlyGovernorOrGuardian {\n uint256 feeExemptStatus = 1 - isFeeExempt[theAddress];\n isFeeExempt[theAddress] = feeExemptStatus;\n emit FeeToggled(theAddress, feeExemptStatus);\n }\n}\n" + }, + "contracts/mock/MockStableMaster.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\nimport \"../interfaces/IAgToken.sol\";\nimport \"./MockToken.sol\";\nimport \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\nimport \"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\";\nimport { SLPData, MintBurnData } from \"../interfaces/coreModule/IStableMaster.sol\";\n\n// All the details about a collateral that are going to be stored in `StableMaster`\nstruct Collateral {\n // Interface for the token accepted by the underlying `PoolManager` contract\n IERC20 token;\n // Reference to the `SanToken` for the pool\n MockToken sanToken;\n // Reference to the `PerpetualManager` for the pool\n address perpetualManager;\n // Adress of the oracle for the change rate between\n // collateral and the corresponding stablecoin\n address oracle;\n // Amount of collateral in the reserves that comes from users\n // converted in stablecoin value. Updated at minting and burning.\n // A `stocksUsers` of 10 for a collateral type means that overall the balance of the collateral from users\n // that minted/burnt stablecoins using this collateral is worth 10 of stablecoins\n uint256 stocksUsers;\n // Exchange rate between sanToken and collateral\n uint256 sanRate;\n // Base used in the collateral implementation (ERC20 decimal)\n uint256 collatBase;\n // Parameters for SLPs and update of the `sanRate`\n SLPData slpData;\n // All the fees parameters\n MintBurnData feeData;\n}\n\ncontract MockStableMaster {\n mapping(address => uint256) public poolManagerMap;\n\n constructor() {}\n\n function updateStocksUsers(uint256 amount, address poolManager) external {\n poolManagerMap[poolManager] += amount;\n }\n\n function burnSelf(IAgToken agToken, uint256 amount, address burner) external {\n agToken.burnSelf(amount, burner);\n }\n\n function burnFrom(IAgToken agToken, uint256 amount, address burner, address sender) external {\n agToken.burnFrom(amount, burner, sender);\n }\n\n function mint(IAgToken agToken, address account, uint256 amount) external {\n agToken.mint(account, amount);\n }\n}\n\ncontract MockStableMasterSanWrapper is MockStableMaster {\n using SafeERC20 for IERC20;\n\n /// @notice Maps a `PoolManager` contract handling a collateral for this stablecoin to the properties of the struct above\n mapping(address => Collateral) public collateralMap;\n\n constructor() MockStableMaster() {}\n\n uint256 internal constant _BASE_TOKENS = 10 ** 18;\n uint256 internal constant _BASE_PARAMS = 10 ** 9;\n IERC20 public token;\n\n function deposit(uint256 assets, address receiver, address poolManager) external {\n token.safeTransferFrom(msg.sender, address(this), assets);\n Collateral storage col = collateralMap[poolManager];\n _updateSanRate(col);\n uint256 amount = (assets * _BASE_TOKENS) / col.sanRate;\n col.sanToken.mint(receiver, amount);\n }\n\n function withdraw(uint256 assets, address sender, address receiver, address poolManager) external {\n Collateral storage col = collateralMap[poolManager];\n _updateSanRate(col);\n col.sanToken.burn(sender, assets);\n // Computing the amount of collateral to give back to the SLP depending on slippage and on the `sanRate`\n uint256 redeemInC = (assets * (_BASE_PARAMS - col.slpData.slippage) * col.sanRate) /\n (_BASE_TOKENS * _BASE_PARAMS);\n token.safeTransfer(receiver, redeemInC);\n }\n\n function setPoolManagerToken(address, address token_) external {\n token = MockToken(token_);\n }\n\n function setPoolManagerSanToken(address poolManager, address sanToken_) external {\n Collateral storage col = collateralMap[poolManager];\n col.sanToken = MockToken(sanToken_);\n }\n\n function setSanRate(address poolManager, uint256 sanRate_) external {\n Collateral storage col = collateralMap[poolManager];\n col.sanRate = sanRate_;\n }\n\n function _updateSanRate(Collateral storage col) internal {\n uint256 _lockedInterests = col.slpData.lockedInterests;\n // Checking if the `sanRate` has been updated in the current block using past block fees\n // This is a way to prevent flash loans attacks when an important amount of fees are going to be distributed\n // in a block: fees are stored but will just be distributed to SLPs who will be here during next blocks\n if (block.timestamp != col.slpData.lastBlockUpdated && _lockedInterests > 0) {\n uint256 sanMint = col.sanToken.totalSupply();\n if (sanMint != 0) {\n // Checking if the update is too important and should be made in multiple blocks\n if (_lockedInterests > col.slpData.maxInterestsDistributed) {\n // `sanRate` is expressed in `BASE_TOKENS`\n col.sanRate += (col.slpData.maxInterestsDistributed * 10 ** 18) / sanMint;\n _lockedInterests -= col.slpData.maxInterestsDistributed;\n } else {\n col.sanRate += (_lockedInterests * 10 ** 18) / sanMint;\n _lockedInterests = 0;\n }\n } else {\n _lockedInterests = 0;\n }\n }\n col.slpData.lockedInterests = _lockedInterests;\n col.slpData.lastBlockUpdated = block.timestamp;\n }\n\n // copy paste from the deployed contract\n function estimateSanRate(address poolManager) external view returns (uint256 sanRate, uint64 slippage) {\n Collateral memory col = collateralMap[poolManager];\n uint256 _lockedInterests = col.slpData.lockedInterests;\n // Checking if the `sanRate` has been updated in the current block using past block fees\n // This is a way to prevent flash loans attacks when an important amount of fees are going to be distributed\n // in a block: fees are stored but will just be distributed to SLPs who will be here during next blocks\n if (block.timestamp != col.slpData.lastBlockUpdated && _lockedInterests > 0) {\n uint256 sanMint = col.sanToken.totalSupply();\n if (sanMint != 0) {\n // Checking if the update is too important and should be made in multiple blocks\n if (_lockedInterests > col.slpData.maxInterestsDistributed) {\n // `sanRate` is expressed in `BASE_TOKENS`\n col.sanRate += (col.slpData.maxInterestsDistributed * 10 ** 18) / sanMint;\n _lockedInterests -= col.slpData.maxInterestsDistributed;\n } else {\n col.sanRate += (_lockedInterests * 10 ** 18) / sanMint;\n _lockedInterests = 0;\n }\n } else {\n _lockedInterests = 0;\n }\n }\n return (col.sanRate, col.slpData.slippage);\n }\n\n function setSLPData(\n address poolManager,\n uint256 lockedInterests,\n uint256 maxInterestsDistributed,\n uint64 slippage\n ) external {\n Collateral storage col = collateralMap[poolManager];\n col.slpData.lockedInterests = lockedInterests;\n col.slpData.maxInterestsDistributed = maxInterestsDistributed;\n col.slpData.slippage = slippage;\n }\n}\n" + }, + "contracts/mock/MockSwapper.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\nimport \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\nimport \"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\";\n\nimport \"../interfaces/ISwapper.sol\";\n\ncontract MockSwapper is ISwapper {\n bytes32 public constant CALLBACK_SUCCESS = keccak256(\"ERC3156FlashBorrower.onFlashLoan\");\n\n uint256 public counter;\n\n constructor() {}\n\n function swap(IERC20, IERC20, address, uint256, uint256, bytes calldata data) external {\n counter += 1;\n data;\n }\n}\n\ncontract MockSwapperWithSwap is ISwapper {\n using SafeERC20 for IERC20;\n bytes32 public constant CALLBACK_SUCCESS = keccak256(\"ERC3156FlashBorrower.onFlashLoan\");\n\n uint256 public counter;\n\n constructor() {}\n\n function swap(\n IERC20,\n IERC20 outToken,\n address outTokenRecipient,\n uint256 outTokenOwed,\n uint256,\n bytes calldata data\n ) external {\n counter += 1;\n outToken.safeTransfer(outTokenRecipient, outTokenOwed);\n\n data;\n }\n}\n" + }, + "contracts/mock/MockSwapperSidechain.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\nimport \"../swapper/Swapper.sol\";\n\n/// @title MockSwapperSidechain\n/// @author Angle Labs, Inc.\ncontract MockSwapperSidechain is Swapper {\n error NotImplemented();\n\n /// @notice Constructor of the contract\n /// @param _core Core address\n /// @param _uniV3Router UniswapV3 Router address\n /// @param _oneInch 1Inch Router address\n /// @param _angleRouter AngleRouter contract address\n constructor(\n ICoreBorrow _core,\n IUniswapV3Router _uniV3Router,\n address _oneInch,\n IAngleRouterSidechain _angleRouter\n ) Swapper(_core, _uniV3Router, _oneInch, _angleRouter) {}\n\n function _swapLeverage(bytes memory) internal pure override returns (uint256) {\n revert NotImplemented();\n }\n}\n" + }, + "contracts/mock/MockToken.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.7;\n\nimport \"@openzeppelin/contracts/token/ERC20/ERC20.sol\";\n\ncontract MockToken is ERC20 {\n event Minting(address indexed _to, address indexed _minter, uint256 _amount);\n\n event Burning(address indexed _from, address indexed _burner, uint256 _amount);\n\n uint8 internal _decimal;\n mapping(address => bool) public minters;\n address public treasury;\n\n constructor(string memory name_, string memory symbol_, uint8 decimal_) ERC20(name_, symbol_) {\n _decimal = decimal_;\n }\n\n function decimals() public view override returns (uint8) {\n return _decimal;\n }\n\n function mint(address account, uint256 amount) external {\n _mint(account, amount);\n emit Minting(account, msg.sender, amount);\n }\n\n function burn(address account, uint256 amount) public {\n _burn(account, amount);\n emit Burning(account, msg.sender, amount);\n }\n\n function setAllowance(address from, address to) public {\n _approve(from, to, type(uint256).max);\n }\n\n function burnSelf(uint256 amount, address account) public {\n _burn(account, amount);\n emit Burning(account, msg.sender, amount);\n }\n\n function addMinter(address minter) public {\n minters[minter] = true;\n }\n\n function removeMinter(address minter) public {\n minters[minter] = false;\n }\n\n function setTreasury(address _treasury) public {\n treasury = _treasury;\n }\n}\n" + }, + "contracts/mock/MockTokenPermit.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.7;\n\nimport \"@openzeppelin/contracts/token/ERC20/extensions/draft-ERC20Permit.sol\";\nimport \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\nimport \"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\";\n\ncontract MockTokenPermit is ERC20Permit {\n using SafeERC20 for IERC20;\n event Minting(address indexed _to, address indexed _minter, uint256 _amount);\n\n event Burning(address indexed _from, address indexed _burner, uint256 _amount);\n\n uint8 internal _decimal;\n mapping(address => bool) public minters;\n address public treasury;\n uint256 public fees;\n\n bool public reverts;\n\n constructor(string memory name_, string memory symbol_, uint8 decimal_) ERC20Permit(name_) ERC20(name_, symbol_) {\n _decimal = decimal_;\n }\n\n function decimals() public view override returns (uint8) {\n return _decimal;\n }\n\n function mint(address account, uint256 amount) external {\n _mint(account, amount);\n emit Minting(account, msg.sender, amount);\n }\n\n function burn(address account, uint256 amount) public {\n _burn(account, amount);\n emit Burning(account, msg.sender, amount);\n }\n\n function setAllowance(address from, address to) public {\n _approve(from, to, type(uint256).max);\n }\n\n function burnSelf(uint256 amount, address account) public {\n _burn(account, amount);\n emit Burning(account, msg.sender, amount);\n }\n\n function addMinter(address minter) public {\n minters[minter] = true;\n }\n\n function removeMinter(address minter) public {\n minters[minter] = false;\n }\n\n function setTreasury(address _treasury) public {\n treasury = _treasury;\n }\n\n function setFees(uint256 _fees) public {\n fees = _fees;\n }\n\n function recoverERC20(IERC20 token, address to, uint256 amount) external {\n token.safeTransfer(to, amount);\n }\n\n function swapIn(address bridgeToken, uint256 amount, address to) external returns (uint256) {\n require(!reverts);\n\n IERC20(bridgeToken).safeTransferFrom(msg.sender, address(this), amount);\n uint256 canonicalOut = amount;\n canonicalOut -= (canonicalOut * fees) / 10 ** 9;\n _mint(to, canonicalOut);\n return canonicalOut;\n }\n\n function swapOut(address bridgeToken, uint256 amount, address to) external returns (uint256) {\n require(!reverts);\n _burn(msg.sender, amount);\n uint256 bridgeOut = amount;\n bridgeOut -= (bridgeOut * fees) / 10 ** 9;\n IERC20(bridgeToken).safeTransfer(to, bridgeOut);\n return bridgeOut;\n }\n}\n" + }, + "contracts/mock/MockTreasury.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\nimport \"../interfaces/ITreasury.sol\";\nimport \"../interfaces/IFlashAngle.sol\";\nimport \"../interfaces/IVaultManager.sol\";\n\ncontract MockTreasury is ITreasury {\n IAgToken public override stablecoin;\n address public governor;\n address public guardian;\n address public vaultManager1;\n address public vaultManager2;\n address public flashLoanModule;\n address[] public vaultManagerList;\n\n constructor(\n IAgToken _stablecoin,\n address _governor,\n address _guardian,\n address _vaultManager1,\n address _vaultManager2,\n address _flashLoanModule\n ) {\n stablecoin = _stablecoin;\n governor = _governor;\n guardian = _guardian;\n vaultManager1 = _vaultManager1;\n vaultManager2 = _vaultManager2;\n flashLoanModule = _flashLoanModule;\n }\n\n function isGovernor(address admin) external view override returns (bool) {\n return (admin == governor);\n }\n\n function isGovernorOrGuardian(address admin) external view override returns (bool) {\n return (admin == governor || admin == guardian);\n }\n\n function isVaultManager(address _vaultManager) external view override returns (bool) {\n return (_vaultManager == vaultManager1 || _vaultManager == vaultManager2);\n }\n\n function setStablecoin(IAgToken _stablecoin) external {\n stablecoin = _stablecoin;\n }\n\n function setFlashLoanModule(address _flashLoanModule) external override {\n flashLoanModule = _flashLoanModule;\n }\n\n function setGovernor(address _governor) external {\n governor = _governor;\n }\n\n function setVaultManager(address _vaultManager) external {\n vaultManager1 = _vaultManager;\n }\n\n function setVaultManager2(address _vaultManager) external {\n vaultManager2 = _vaultManager;\n }\n\n function setTreasury(address _agTokenOrVaultManager, address _treasury) external {\n IAgToken(_agTokenOrVaultManager).setTreasury(_treasury);\n }\n\n function addMinter(IAgToken _agToken, address _minter) external {\n _agToken.addMinter(_minter);\n }\n\n function removeMinter(IAgToken _agToken, address _minter) external {\n _agToken.removeMinter(_minter);\n }\n\n function accrueInterestToTreasury(IFlashAngle flashAngle) external returns (uint256 balance) {\n balance = flashAngle.accrueInterestToTreasury(stablecoin);\n }\n\n function accrueInterestToTreasuryVaultManager(IVaultManager _vaultManager) external returns (uint256, uint256) {\n return _vaultManager.accrueInterestToTreasury();\n }\n}\n" + }, + "contracts/mock/MockUniswapV3Pool.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.7;\n\ncontract MockUniswapV3Pool {\n address public token0;\n address public token1;\n uint32 public constant EPOCH_DURATION = 24 * 3600 * 7;\n\n function setToken(address token, uint256 who) external {\n if (who == 0) token0 = token;\n else token1 = token;\n }\n\n function round(uint256 amount) external pure returns (uint256) {\n return (amount / EPOCH_DURATION) * EPOCH_DURATION;\n }\n}\n" + }, + "contracts/mock/MockVaultManager.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\nimport \"../interfaces/IVaultManager.sol\";\nimport \"../interfaces/ITreasury.sol\";\nimport \"@openzeppelin/contracts/token/ERC20/ERC20.sol\";\n\ncontract MockVaultManager {\n ITreasury public treasury;\n mapping(uint256 => Vault) public vaultData;\n mapping(uint256 => address) public ownerOf;\n uint256 public surplus;\n uint256 public badDebt;\n IAgToken public token;\n address public oracle = address(this);\n\n address public governor;\n address public collateral;\n address public stablecoin;\n uint256 public oracleValue;\n uint256 public interestAccumulator;\n uint256 public collateralFactor;\n uint256 public totalNormalizedDebt;\n\n constructor(address _treasury) {\n treasury = ITreasury(_treasury);\n }\n\n function accrueInterestToTreasury() external returns (uint256, uint256) {\n // Avoid the function to be view\n if (surplus >= badDebt) {\n token.mint(msg.sender, surplus - badDebt);\n }\n return (surplus, badDebt);\n }\n\n function read() external view returns (uint256) {\n return oracleValue;\n }\n\n function setParams(\n address _governor,\n address _collateral,\n address _stablecoin,\n uint256 _oracleValue,\n uint256 _interestAccumulator,\n uint256 _collateralFactor,\n uint256 _totalNormalizedDebt\n ) external {\n governor = _governor;\n collateral = _collateral;\n stablecoin = _stablecoin;\n interestAccumulator = _interestAccumulator;\n collateralFactor = _collateralFactor;\n totalNormalizedDebt = _totalNormalizedDebt;\n oracleValue = _oracleValue;\n }\n\n function setOwner(uint256 vaultID, address owner) external virtual {\n ownerOf[vaultID] = owner;\n }\n\n function setVaultData(uint256 normalizedDebt, uint256 collateralAmount, uint256 vaultID) external {\n vaultData[vaultID].normalizedDebt = normalizedDebt;\n vaultData[vaultID].collateralAmount = collateralAmount;\n }\n\n function isGovernor(address admin) external view returns (bool) {\n return admin == governor;\n }\n\n function setSurplusBadDebt(uint256 _surplus, uint256 _badDebt, IAgToken _token) external {\n surplus = _surplus;\n badDebt = _badDebt;\n token = _token;\n }\n\n function getDebtOut(uint256 vaultID, uint256 amountStablecoins, uint256 senderBorrowFee) external {}\n\n function setTreasury(address _treasury) external {\n treasury = ITreasury(_treasury);\n }\n\n function getVaultDebt(uint256 vaultID) external view returns (uint256) {\n vaultID;\n token;\n return 0;\n }\n\n function createVault(address toVault) external view returns (uint256) {\n toVault;\n token;\n return 0;\n }\n}\n\ncontract MockVaultManagerListing is MockVaultManager {\n // @notice Mapping from owner address to all his vaults\n mapping(address => uint256[]) internal _ownerListVaults;\n\n constructor(address _treasury) MockVaultManager(_treasury) {}\n\n function getUserVaults(address owner) public view returns (uint256[] memory) {\n return _ownerListVaults[owner];\n }\n\n function getUserCollateral(address owner) public view returns (uint256 totalCollateral) {\n uint256[] memory vaultList = _ownerListVaults[owner];\n uint256 vaultListLength = vaultList.length;\n for (uint256 k; k < vaultListLength; ++k) {\n totalCollateral += vaultData[vaultList[k]].collateralAmount;\n }\n return totalCollateral;\n }\n\n function setOwner(uint256 vaultID, address owner) external override {\n if (ownerOf[vaultID] != address(0)) _removeVaultFromList(ownerOf[vaultID], vaultID);\n _ownerListVaults[owner].push(vaultID);\n ownerOf[vaultID] = owner;\n }\n\n /// @notice Remove `vaultID` from `user` stroed vault list\n /// @param user Address to look out for the vault list\n /// @param vaultID VaultId to remove from the list\n /// @dev The vault is necessarily in the list\n function _removeVaultFromList(address user, uint256 vaultID) internal {\n uint256[] storage vaultList = _ownerListVaults[user];\n uint256 vaultListLength = vaultList.length;\n for (uint256 i; i < vaultListLength - 1; ++i) {\n if (vaultList[i] == vaultID) {\n vaultList[i] = vaultList[vaultListLength - 1];\n break;\n }\n }\n vaultList.pop();\n }\n}\n" + }, + "contracts/mock/MockVeBoostProxy.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\nimport \"../interfaces/governance/IVeBoostProxy.sol\";\n\ncontract MockVeBoostProxy is IVeBoostProxy {\n //solhint-disable-next-line\n mapping(address => uint256) public adjusted_balance_of;\n\n constructor() {}\n\n function setBalance(address concerned, uint256 balance) external {\n adjusted_balance_of[concerned] = balance;\n }\n}\n" + }, + "contracts/oracle/BaseOracleChainlinkMulti.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\n/*\n * █ \n ***** ▓▓▓ \n * ▓▓▓▓▓▓▓ \n * ///. ▓▓▓▓▓▓▓▓▓▓▓▓▓ \n ***** //////// ▓▓▓▓▓▓▓ \n * ///////////// ▓▓▓ \n ▓▓ ////////////////// █ ▓▓ \n ▓▓ ▓▓ /////////////////////// ▓▓ ▓▓ \n ▓▓ ▓▓ //////////////////////////// ▓▓ ▓▓ \n ▓▓ ▓▓ /////////▓▓▓///////▓▓▓///////// ▓▓ ▓▓ \n ▓▓ ,////////////////////////////////////// ▓▓ ▓▓ \n ▓▓ ////////////////////////////////////////// ▓▓ \n ▓▓ //////////////////////▓▓▓▓///////////////////// \n ,//////////////////////////////////////////////////// \n .////////////////////////////////////////////////////////// \n .//////////////////////////██.,//////////////////////////█ \n .//////////////////////████..,./////////////////////██ \n ...////////////////███████.....,.////////////////███ \n ,.,////////////████████ ........,///////////████ \n .,.,//////█████████ ,.......///////████ \n ,..//████████ ........./████ \n ..,██████ .....,███ \n .██ ,.,█ \n \n \n \n ▓▓ ▓▓▓▓▓▓▓▓▓▓ ▓▓▓▓▓▓▓▓▓▓ ▓▓ ▓▓▓▓▓▓▓▓▓▓ \n ▓▓▓▓▓▓ ▓▓▓ ▓▓▓ ▓▓▓ ▓▓ ▓▓ ▓▓▓▓ \n ▓▓▓ ▓▓▓ ▓▓▓ ▓▓▓ ▓▓▓ ▓▓▓ ▓▓ ▓▓▓▓▓ \n ▓▓▓ ▓▓ ▓▓▓ ▓▓▓ ▓▓▓▓▓▓▓▓▓▓ ▓▓▓▓▓▓▓▓▓▓ ▓▓▓▓▓▓▓▓▓▓ \n*/\n\npragma solidity ^0.8.12;\n\nimport \"@chainlink/contracts/src/v0.8/interfaces/AggregatorV3Interface.sol\";\n\nimport \"../interfaces/IOracle.sol\";\nimport \"../interfaces/ITreasury.sol\";\n\n/// @title BaseOracleChainlinkMulti\n/// @author Angle Labs, Inc.\n/// @notice Base Contract to be overriden by all contracts of the protocol\n/// @dev This base contract concerns an oracle that uses Chainlink with multiple pools to read from\n/// @dev All gas-efficient implementation of the `OracleChainlinkMulti` contract should inherit from this\nabstract contract BaseOracleChainlinkMulti is IOracle {\n // ========================= Parameters and References =========================\n\n /// @inheritdoc IOracle\n ITreasury public override treasury;\n /// @notice Represent the maximum amount of time (in seconds) between each Chainlink update\n /// before the price feed is considered stale\n uint32 public stalePeriod;\n\n // =================================== Event ===================================\n\n event StalePeriodUpdated(uint32 _stalePeriod);\n\n // =================================== Errors ===================================\n\n error InvalidChainlinkRate();\n error NotGovernorOrGuardian();\n error NotVaultManagerOrGovernor();\n\n /// @notice Constructor for an oracle using Chainlink with multiple pools to read from\n /// @param _stalePeriod Minimum feed update frequency for the oracle to not revert\n /// @param _treasury Treasury associated to the VaultManager which reads from this feed\n constructor(uint32 _stalePeriod, address _treasury) {\n stalePeriod = _stalePeriod;\n treasury = ITreasury(_treasury);\n }\n\n // ============================= Reading Oracles ===============================\n\n /// @inheritdoc IOracle\n function read() external view virtual override returns (uint256 quoteAmount);\n\n /// @inheritdoc IOracle\n function circuitChainlink() public view virtual returns (AggregatorV3Interface[] memory);\n\n /// @notice Reads a Chainlink feed using a quote amount and converts the quote amount to\n /// the out-currency\n /// @param quoteAmount The amount for which to compute the price expressed with base decimal\n /// @param feed Chainlink feed to query\n /// @param multiplied Whether the ratio outputted by Chainlink should be multiplied or divided\n /// to the `quoteAmount`\n /// @param decimals Number of decimals of the corresponding Chainlink pair\n /// @return The `quoteAmount` converted in out-currency\n function _readChainlinkFeed(\n uint256 quoteAmount,\n AggregatorV3Interface feed,\n uint8 multiplied,\n uint256 decimals\n ) internal view returns (uint256) {\n (uint80 roundId, int256 ratio, , uint256 updatedAt, uint80 answeredInRound) = feed.latestRoundData();\n if (ratio <= 0 || roundId > answeredInRound || block.timestamp - updatedAt > stalePeriod)\n revert InvalidChainlinkRate();\n uint256 castedRatio = uint256(ratio);\n // Checking whether we should multiply or divide by the ratio computed\n if (multiplied == 1) return (quoteAmount * castedRatio) / (10 ** decimals);\n else return (quoteAmount * (10 ** decimals)) / castedRatio;\n }\n\n // ======================= Governance Related Functions ========================\n\n /// @notice Changes the stale period\n /// @param _stalePeriod New stale period (in seconds)\n function changeStalePeriod(uint32 _stalePeriod) external {\n if (!treasury.isGovernorOrGuardian(msg.sender)) revert NotGovernorOrGuardian();\n stalePeriod = _stalePeriod;\n emit StalePeriodUpdated(_stalePeriod);\n }\n\n /// @inheritdoc IOracle\n function setTreasury(address _treasury) external override {\n if (!treasury.isVaultManager(msg.sender) && !treasury.isGovernor(msg.sender))\n revert NotVaultManagerOrGovernor();\n treasury = ITreasury(_treasury);\n }\n}\n" + }, + "contracts/oracle/BaseOracleChainlinkMultiTwoFeeds.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\nimport \"@chainlink/contracts/src/v0.8/interfaces/AggregatorV3Interface.sol\";\n\nimport \"./BaseOracleChainlinkMulti.sol\";\n\n/// @title BaseOracleChainlinkMultiTwoFeeds\n/// @author Angle Labs, Inc.\n/// @notice Base contract for an oracle that reads into two Chainlink feeds (including an EUR/USD feed) which both have\n/// 8 decimals\nabstract contract BaseOracleChainlinkMultiTwoFeeds is BaseOracleChainlinkMulti {\n constructor(uint32 _stalePeriod, address _treasury) BaseOracleChainlinkMulti(_stalePeriod, _treasury) {}\n\n /// @notice Returns the quote amount of the oracle contract\n function _getQuoteAmount() internal view virtual returns (uint256) {\n return 10 ** 18;\n }\n\n /// @inheritdoc IOracle\n function read() external view virtual override returns (uint256 quoteAmount) {\n quoteAmount = _getQuoteAmount();\n AggregatorV3Interface[] memory _circuitChainlink = circuitChainlink();\n uint8[2] memory circuitChainIsMultiplied = [1, 0];\n uint8[2] memory chainlinkDecimals = [8, 8];\n uint256 circuitLength = _circuitChainlink.length;\n for (uint256 i; i < circuitLength; ++i) {\n quoteAmount = _readChainlinkFeed(\n quoteAmount,\n _circuitChainlink[i],\n circuitChainIsMultiplied[i],\n chainlinkDecimals[i]\n );\n }\n }\n}\n" + }, + "contracts/oracle/BaseOracleChainlinkOneFeed.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\nimport \"@chainlink/contracts/src/v0.8/interfaces/AggregatorV3Interface.sol\";\n\nimport \"./BaseOracleChainlinkMulti.sol\";\n\n/// @title BaseOracleChainlinkOneFeed\n/// @author Angle Labs, Inc.\n/// @notice Base contract for an oracle that reads into one Chainlink feeds with 8 decimals\nabstract contract BaseOracleChainlinkOneFeed is BaseOracleChainlinkMulti {\n constructor(uint32 _stalePeriod, address _treasury) BaseOracleChainlinkMulti(_stalePeriod, _treasury) {}\n\n /// @notice Returns the quote amount of the oracle contract\n function _getQuoteAmount() internal view virtual returns (uint256) {\n return 10 ** 18;\n }\n\n /// @inheritdoc IOracle\n function read() external view virtual override returns (uint256 quoteAmount) {\n AggregatorV3Interface[] memory _circuitChainlink = circuitChainlink();\n quoteAmount = _readChainlinkFeed(_getQuoteAmount(), _circuitChainlink[0], 1, 8);\n }\n}\n" + }, + "contracts/oracle/implementations/arbitrum/EUR/OracleBTCEURChainlinkArbitrum.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\nimport \"@chainlink/contracts/src/v0.8/interfaces/AggregatorV3Interface.sol\";\n\nimport \"../../../BaseOracleChainlinkMultiTwoFeeds.sol\";\n\n/// @title OracleBTCEURChainlinkArbitrum\n/// @author Angle Labs, Inc.\n/// @notice Gives the price of BTC in Euro in base 18\n/// @dev This contract is built to be deployed on Arbitrum\ncontract OracleBTCEURChainlinkArbitrum is BaseOracleChainlinkMultiTwoFeeds {\n string public constant DESCRIPTION = \"BTC/EUR Oracle\";\n\n constructor(uint32 _stalePeriod, address _treasury) BaseOracleChainlinkMultiTwoFeeds(_stalePeriod, _treasury) {}\n\n /// @inheritdoc IOracle\n function circuitChainlink() public pure override returns (AggregatorV3Interface[] memory) {\n AggregatorV3Interface[] memory _circuitChainlink = new AggregatorV3Interface[](2);\n // Oracle BTC/USD\n _circuitChainlink[0] = AggregatorV3Interface(0x6ce185860a4963106506C203335A2910413708e9);\n // Oracle EUR/USD\n _circuitChainlink[1] = AggregatorV3Interface(0xA14d53bC1F1c0F31B4aA3BD109344E5009051a84);\n return _circuitChainlink;\n }\n}\n" + }, + "contracts/oracle/implementations/arbitrum/EUR/OracleETHEURChainlinkArbitrum.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\nimport \"@chainlink/contracts/src/v0.8/interfaces/AggregatorV3Interface.sol\";\n\nimport \"../../../BaseOracleChainlinkMultiTwoFeeds.sol\";\n\n/// @title OracleETHEURChainlinkArbitrum\n/// @author Angle Labs, Inc.\n/// @notice Gives the price of ETH in Euro in base 18\n/// @dev This contract is built to be deployed on Arbitrum\ncontract OracleETHEURChainlinkArbitrum is BaseOracleChainlinkMultiTwoFeeds {\n string public constant DESCRIPTION = \"ETH/EUR Oracle\";\n\n constructor(uint32 _stalePeriod, address _treasury) BaseOracleChainlinkMultiTwoFeeds(_stalePeriod, _treasury) {}\n\n /// @inheritdoc IOracle\n function circuitChainlink() public pure override returns (AggregatorV3Interface[] memory) {\n AggregatorV3Interface[] memory _circuitChainlink = new AggregatorV3Interface[](2);\n // Oracle ETH/USD\n _circuitChainlink[0] = AggregatorV3Interface(0x639Fe6ab55C921f74e7fac1ee960C0B6293ba612);\n // Oracle EUR/USD\n _circuitChainlink[1] = AggregatorV3Interface(0xA14d53bC1F1c0F31B4aA3BD109344E5009051a84);\n return _circuitChainlink;\n }\n}\n" + }, + "contracts/oracle/implementations/arbitrum/EUR/OracleUSDCEURChainlinkArbitrum.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\nimport \"@chainlink/contracts/src/v0.8/interfaces/AggregatorV3Interface.sol\";\n\nimport \"../../../BaseOracleChainlinkMultiTwoFeeds.sol\";\n\n/// @title OracleUSDCEURChainlinkArbitrum\n/// @author Angle Labs, Inc.\n/// @notice Gives the price of USDC in Euro in base 18\n/// @dev This contract is built to be deployed on Arbitrum\ncontract OracleUSDCEURChainlinkArbitrum is BaseOracleChainlinkMultiTwoFeeds {\n string public constant DESCRIPTION = \"USDC/EUR Oracle\";\n\n constructor(uint32 _stalePeriod, address _treasury) BaseOracleChainlinkMultiTwoFeeds(_stalePeriod, _treasury) {}\n\n /// @inheritdoc IOracle\n function circuitChainlink() public pure override returns (AggregatorV3Interface[] memory) {\n AggregatorV3Interface[] memory _circuitChainlink = new AggregatorV3Interface[](2);\n // Oracle ETH/USD\n _circuitChainlink[0] = AggregatorV3Interface(0x50834F3163758fcC1Df9973b6e91f0F0F0434aD3);\n // Oracle EUR/USD\n _circuitChainlink[1] = AggregatorV3Interface(0xA14d53bC1F1c0F31B4aA3BD109344E5009051a84);\n return _circuitChainlink;\n }\n}\n" + }, + "contracts/oracle/implementations/avalanche/EUR/OracleAVAXEURChainlinkAvalanche.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\nimport \"@chainlink/contracts/src/v0.8/interfaces/AggregatorV3Interface.sol\";\n\nimport \"../../../BaseOracleChainlinkMultiTwoFeeds.sol\";\n\n/// @title OracleAVAXEURChainlinkAvalanche\n/// @author Angle Labs, Inc.\n/// @notice Gives the price of AVAX in Euro in base 18\n/// @dev This contract is built to be deployed on Avalanche\ncontract OracleAVAXEURChainlinkAvalanche is BaseOracleChainlinkMultiTwoFeeds {\n string public constant DESCRIPTION = \"AVAX/EUR Oracle\";\n\n constructor(uint32 _stalePeriod, address _treasury) BaseOracleChainlinkMultiTwoFeeds(_stalePeriod, _treasury) {}\n\n /// @inheritdoc IOracle\n function circuitChainlink() public pure override returns (AggregatorV3Interface[] memory) {\n AggregatorV3Interface[] memory _circuitChainlink = new AggregatorV3Interface[](2);\n // Oracle AVAX/USD\n _circuitChainlink[0] = AggregatorV3Interface(0x0A77230d17318075983913bC2145DB16C7366156);\n // Oracle EUR/USD\n _circuitChainlink[1] = AggregatorV3Interface(0x192f2DBA961Bb0277520C082d6bfa87D5961333E);\n return _circuitChainlink;\n }\n}\n" + }, + "contracts/oracle/implementations/avalanche/EUR/OracleUSDCEURChainlinkAvalanche.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\nimport \"@chainlink/contracts/src/v0.8/interfaces/AggregatorV3Interface.sol\";\n\nimport \"../../../BaseOracleChainlinkMultiTwoFeeds.sol\";\n\n/// @title OracleUSDCEURChainlinkAvalanche\n/// @author Angle Labs, Inc.\n/// @notice Gives the price of USDC in Euro in base 18\n/// @dev This contract is built to be deployed on Avalanche\ncontract OracleUSDCEURChainlinkAvalanche is BaseOracleChainlinkMultiTwoFeeds {\n string public constant DESCRIPTION = \"USDC/EUR Oracle\";\n\n constructor(uint32 _stalePeriod, address _treasury) BaseOracleChainlinkMultiTwoFeeds(_stalePeriod, _treasury) {}\n\n /// @inheritdoc IOracle\n function circuitChainlink() public pure override returns (AggregatorV3Interface[] memory) {\n AggregatorV3Interface[] memory _circuitChainlink = new AggregatorV3Interface[](2);\n // Oracle USDC/USD\n _circuitChainlink[0] = AggregatorV3Interface(0xF096872672F44d6EBA71458D74fe67F9a77a23B9);\n // Oracle EUR/USD\n _circuitChainlink[1] = AggregatorV3Interface(0x192f2DBA961Bb0277520C082d6bfa87D5961333E);\n return _circuitChainlink;\n }\n}\n" + }, + "contracts/oracle/implementations/mainnet/EUR/OracleBTCEURChainlink.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\nimport \"@chainlink/contracts/src/v0.8/interfaces/AggregatorV3Interface.sol\";\n\nimport \"../../../BaseOracleChainlinkMultiTwoFeeds.sol\";\n\n/// @title OracleBTCEURChainlink\n/// @author Angle Labs, Inc.\n/// @notice Gives the price of BTC in Euro in base 18\ncontract OracleBTCEURChainlink is BaseOracleChainlinkMultiTwoFeeds {\n string public constant DESCRIPTION = \"BTC/EUR Oracle\";\n\n constructor(uint32 _stalePeriod, address _treasury) BaseOracleChainlinkMultiTwoFeeds(_stalePeriod, _treasury) {}\n\n /// @inheritdoc IOracle\n function circuitChainlink() public pure override returns (AggregatorV3Interface[] memory) {\n AggregatorV3Interface[] memory _circuitChainlink = new AggregatorV3Interface[](2);\n // Oracle BTC/USD\n _circuitChainlink[0] = AggregatorV3Interface(0xF4030086522a5bEEa4988F8cA5B36dbC97BeE88c);\n // Oracle EUR/USD\n _circuitChainlink[1] = AggregatorV3Interface(0xb49f677943BC038e9857d61E7d053CaA2C1734C1);\n return _circuitChainlink;\n }\n}\n" + }, + "contracts/oracle/implementations/mainnet/EUR/OracleCBETHEURChainlink.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\nimport \"@chainlink/contracts/src/v0.8/interfaces/AggregatorV3Interface.sol\";\n\nimport \"../../../BaseOracleChainlinkMultiTwoFeeds.sol\";\n\n/// @title OracleCBETHEURChainlink\n/// @author Angle Labs, Inc.\n/// @notice Gives the price of cbETH in Euro in base 18\ncontract OracleCBETHEURChainlink is BaseOracleChainlinkMultiTwoFeeds {\n string public constant DESCRIPTION = \"cbETH/EUR Oracle\";\n\n constructor(uint32 _stalePeriod, address _treasury) BaseOracleChainlinkMultiTwoFeeds(_stalePeriod, _treasury) {}\n\n /// @inheritdoc IOracle\n function circuitChainlink() public pure override returns (AggregatorV3Interface[] memory) {\n AggregatorV3Interface[] memory _circuitChainlink = new AggregatorV3Interface[](3);\n // Oracle cbETH/ETH\n _circuitChainlink[0] = AggregatorV3Interface(0xF017fcB346A1885194689bA23Eff2fE6fA5C483b);\n // Oracle ETH/USD\n _circuitChainlink[1] = AggregatorV3Interface(0x5f4eC3Df9cbd43714FE2740f5E3616155c5b8419);\n // Oracle EUR/USD\n _circuitChainlink[2] = AggregatorV3Interface(0xb49f677943BC038e9857d61E7d053CaA2C1734C1);\n return _circuitChainlink;\n }\n\n /// @inheritdoc BaseOracleChainlinkMultiTwoFeeds\n function read() external view virtual override returns (uint256 quoteAmount) {\n quoteAmount = _getQuoteAmount();\n AggregatorV3Interface[] memory _circuitChainlink = circuitChainlink();\n uint8[3] memory circuitChainIsMultiplied = [1, 1, 0];\n uint8[3] memory chainlinkDecimals = [18, 8, 8];\n uint256 circuitLength = _circuitChainlink.length;\n for (uint256 i; i < circuitLength; ++i) {\n quoteAmount = _readChainlinkFeed(\n quoteAmount,\n _circuitChainlink[i],\n circuitChainIsMultiplied[i],\n chainlinkDecimals[i]\n );\n }\n }\n}\n" + }, + "contracts/oracle/implementations/mainnet/EUR/OracleETHEURChainlink.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\nimport \"@chainlink/contracts/src/v0.8/interfaces/AggregatorV3Interface.sol\";\n\nimport \"../../../BaseOracleChainlinkMultiTwoFeeds.sol\";\n\n/// @title OracleETHEURChainlink\n/// @author Angle Labs, Inc.\n/// @notice Gives the price of ETH in Euro in base 18\ncontract OracleETHEURChainlink is BaseOracleChainlinkMultiTwoFeeds {\n string public constant DESCRIPTION = \"ETH/EUR Oracle\";\n\n constructor(uint32 _stalePeriod, address _treasury) BaseOracleChainlinkMultiTwoFeeds(_stalePeriod, _treasury) {}\n\n /// @inheritdoc IOracle\n function circuitChainlink() public pure override returns (AggregatorV3Interface[] memory) {\n AggregatorV3Interface[] memory _circuitChainlink = new AggregatorV3Interface[](2);\n // Oracle ETH/USD\n _circuitChainlink[0] = AggregatorV3Interface(0x5f4eC3Df9cbd43714FE2740f5E3616155c5b8419);\n // Oracle EUR/USD\n _circuitChainlink[1] = AggregatorV3Interface(0xb49f677943BC038e9857d61E7d053CaA2C1734C1);\n return _circuitChainlink;\n }\n}\n" + }, + "contracts/oracle/implementations/mainnet/EUR/OracleHIGHEURChainlink.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\nimport \"@chainlink/contracts/src/v0.8/interfaces/AggregatorV3Interface.sol\";\n\nimport \"../../../BaseOracleChainlinkMultiTwoFeeds.sol\";\n\n/// @title OracleHIGHEURChainlink\n/// @author Angle Labs, Inc.\n/// @notice Gives the price of HIGH in Euro in base 18\ncontract OracleHIGHEURChainlink is BaseOracleChainlinkMultiTwoFeeds {\n string public constant DESCRIPTION = \"HIGH/EUR Oracle\";\n\n constructor(uint32 _stalePeriod, address _treasury) BaseOracleChainlinkMultiTwoFeeds(_stalePeriod, _treasury) {}\n\n /// @inheritdoc IOracle\n function circuitChainlink() public pure override returns (AggregatorV3Interface[] memory) {\n AggregatorV3Interface[] memory _circuitChainlink = new AggregatorV3Interface[](1);\n // Oracle HIGH/EUR\n _circuitChainlink[0] = AggregatorV3Interface(0x9E8E794ad6Ecdb6d5c7eaBE059D30E907F58859b);\n return _circuitChainlink;\n }\n\n /// @inheritdoc BaseOracleChainlinkMultiTwoFeeds\n function read() external view override returns (uint256 quoteAmount) {\n quoteAmount = _readChainlinkFeed(_getQuoteAmount(), circuitChainlink()[0], 1, 8);\n }\n}\n" + }, + "contracts/oracle/implementations/mainnet/EUR/OracleIB01EURChainlink.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\nimport \"@chainlink/contracts/src/v0.8/interfaces/AggregatorV3Interface.sol\";\n\nimport \"../../../BaseOracleChainlinkMultiTwoFeeds.sol\";\n\n/// @title OracleIB01EURChainlink\n/// @author Angle Labs, Inc.\n/// @notice Gives the price of IB01 in Euro in base 18\ncontract OracleIB01EURChainlink is BaseOracleChainlinkMultiTwoFeeds {\n string public constant DESCRIPTION = \"IB01/EUR Oracle\";\n\n constructor(uint32 _stalePeriod, address _treasury) BaseOracleChainlinkMultiTwoFeeds(_stalePeriod, _treasury) {}\n\n /// @inheritdoc IOracle\n function circuitChainlink() public pure override returns (AggregatorV3Interface[] memory) {\n AggregatorV3Interface[] memory _circuitChainlink = new AggregatorV3Interface[](2);\n // Oracle IB01/USD\n _circuitChainlink[0] = AggregatorV3Interface(0x32d1463EB53b73C095625719Afa544D5426354cB);\n // Oracle EUR/USD\n _circuitChainlink[1] = AggregatorV3Interface(0xb49f677943BC038e9857d61E7d053CaA2C1734C1);\n return _circuitChainlink;\n }\n}\n" + }, + "contracts/oracle/implementations/mainnet/EUR/OracleLUSDEURChainlink.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\nimport \"@chainlink/contracts/src/v0.8/interfaces/AggregatorV3Interface.sol\";\n\nimport \"../../../BaseOracleChainlinkMultiTwoFeeds.sol\";\n\n/// @title OracleLUSDEURChainlink\n/// @author Angle Labs, Inc.\n/// @notice Gives the price of LUSD in Euro in base 18\ncontract OracleLUSDEURChainlink is BaseOracleChainlinkMultiTwoFeeds {\n string public constant DESCRIPTION = \"LUSD/EUR Oracle\";\n\n constructor(uint32 _stalePeriod, address _treasury) BaseOracleChainlinkMultiTwoFeeds(_stalePeriod, _treasury) {}\n\n /// @inheritdoc IOracle\n function circuitChainlink() public pure override returns (AggregatorV3Interface[] memory) {\n AggregatorV3Interface[] memory _circuitChainlink = new AggregatorV3Interface[](2);\n // Oracle LUSD/USD\n _circuitChainlink[0] = AggregatorV3Interface(0x3D7aE7E594f2f2091Ad8798313450130d0Aba3a0);\n // Oracle EUR/USD\n _circuitChainlink[1] = AggregatorV3Interface(0xb49f677943BC038e9857d61E7d053CaA2C1734C1);\n return _circuitChainlink;\n }\n}\n" + }, + "contracts/oracle/implementations/mainnet/EUR/OracleUSDCEURChainlink.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\nimport \"@chainlink/contracts/src/v0.8/interfaces/AggregatorV3Interface.sol\";\n\nimport \"../../../BaseOracleChainlinkMultiTwoFeeds.sol\";\n\n/// @title OracleUSDCEURChainlink\n/// @author Angle Labs, Inc.\n/// @notice Gives the price of USDC in Euro in base 18\ncontract OracleUSDCEURChainlink is BaseOracleChainlinkMultiTwoFeeds {\n string public constant DESCRIPTION = \"USDC/EUR Oracle\";\n\n constructor(uint32 _stalePeriod, address _treasury) BaseOracleChainlinkMultiTwoFeeds(_stalePeriod, _treasury) {}\n\n /// @inheritdoc IOracle\n function circuitChainlink() public pure override returns (AggregatorV3Interface[] memory) {\n AggregatorV3Interface[] memory _circuitChainlink = new AggregatorV3Interface[](2);\n // Oracle USDC/USD\n _circuitChainlink[0] = AggregatorV3Interface(0x8fFfFfd4AfB6115b954Bd326cbe7B4BA576818f6);\n // Oracle EUR/USD\n _circuitChainlink[1] = AggregatorV3Interface(0xb49f677943BC038e9857d61E7d053CaA2C1734C1);\n return _circuitChainlink;\n }\n}\n" + }, + "contracts/oracle/implementations/mainnet/EUR/OracleWSTETHEURChainlink.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\nimport \"@chainlink/contracts/src/v0.8/interfaces/AggregatorV3Interface.sol\";\n\nimport \"../../../BaseOracleChainlinkMultiTwoFeeds.sol\";\nimport \"../../../../interfaces/external/lido/IStETH.sol\";\n\n/// @title OracleWSTETHEURChainlink\n/// @author Angle Labs, Inc.\n/// @notice Gives the price of wSTETH in Euro in base 18\ncontract OracleWSTETHEURChainlink is BaseOracleChainlinkMultiTwoFeeds {\n string public constant DESCRIPTION = \"wSTETH/EUR Oracle\";\n IStETH public constant STETH = IStETH(0xae7ab96520DE3A18E5e111B5EaAb095312D7fE84);\n\n constructor(uint32 _stalePeriod, address _treasury) BaseOracleChainlinkMultiTwoFeeds(_stalePeriod, _treasury) {}\n\n /// @inheritdoc IOracle\n function circuitChainlink() public pure override returns (AggregatorV3Interface[] memory) {\n AggregatorV3Interface[] memory _circuitChainlink = new AggregatorV3Interface[](2);\n // Oracle stETH/USD\n _circuitChainlink[0] = AggregatorV3Interface(0xCfE54B5cD566aB89272946F602D76Ea879CAb4a8);\n // Oracle EUR/USD\n _circuitChainlink[1] = AggregatorV3Interface(0xb49f677943BC038e9857d61E7d053CaA2C1734C1);\n return _circuitChainlink;\n }\n\n /// @inheritdoc BaseOracleChainlinkMultiTwoFeeds\n function _getQuoteAmount() internal view override returns (uint256) {\n return STETH.getPooledEthByShares(1 ether);\n }\n}\n" + }, + "contracts/oracle/implementations/mainnet/USD/OracleWSTETHUSDChainlink.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\nimport \"@chainlink/contracts/src/v0.8/interfaces/AggregatorV3Interface.sol\";\n\nimport \"../../../BaseOracleChainlinkOneFeed.sol\";\nimport \"../../../../interfaces/external/lido/IStETH.sol\";\n\n/// @title OracleWSTETHUSDChainlink\n/// @author Angle Labs, Inc.\n/// @notice Gives the price of wSTETH in USD in base 18\ncontract OracleWSTETHUSDChainlink is BaseOracleChainlinkOneFeed {\n string public constant DESCRIPTION = \"wSTETH/USD Oracle\";\n IStETH public constant STETH = IStETH(0xae7ab96520DE3A18E5e111B5EaAb095312D7fE84);\n\n constructor(uint32 _stalePeriod, address _treasury) BaseOracleChainlinkOneFeed(_stalePeriod, _treasury) {}\n\n /// @inheritdoc IOracle\n function circuitChainlink() public pure override returns (AggregatorV3Interface[] memory) {\n AggregatorV3Interface[] memory _circuitChainlink = new AggregatorV3Interface[](1);\n // Oracle stETH/USD\n _circuitChainlink[0] = AggregatorV3Interface(0xCfE54B5cD566aB89272946F602D76Ea879CAb4a8);\n return _circuitChainlink;\n }\n\n /// @inheritdoc BaseOracleChainlinkOneFeed\n function _getQuoteAmount() internal view override returns (uint256) {\n return STETH.getPooledEthByShares(1 ether);\n }\n}\n" + }, + "contracts/oracle/implementations/mainnet/XAU/OracleETHXAUChainlink.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\nimport \"@chainlink/contracts/src/v0.8/interfaces/AggregatorV3Interface.sol\";\n\nimport \"../../../BaseOracleChainlinkMultiTwoFeeds.sol\";\n\n/// @title OracleETHXAUChainlink\n/// @author Angle Labs, Inc.\n/// @notice Gives the price of ETH in XAU in base 18\ncontract OracleETHXAUChainlink is BaseOracleChainlinkMultiTwoFeeds {\n string public constant DESCRIPTION = \"ETH/GOLD Oracle\";\n\n constructor(uint32 _stalePeriod, address _treasury) BaseOracleChainlinkMultiTwoFeeds(_stalePeriod, _treasury) {}\n\n /// @inheritdoc IOracle\n function circuitChainlink() public pure override returns (AggregatorV3Interface[] memory) {\n AggregatorV3Interface[] memory _circuitChainlink = new AggregatorV3Interface[](2);\n // Oracle ETH/USD\n _circuitChainlink[0] = AggregatorV3Interface(0x5f4eC3Df9cbd43714FE2740f5E3616155c5b8419);\n // Oracle XAU/USD\n _circuitChainlink[1] = AggregatorV3Interface(0x214eD9Da11D2fbe465a6fc601a91E62EbEc1a0D6);\n return _circuitChainlink;\n }\n}\n" + }, + "contracts/oracle/implementations/mainnet/XAU/OracleLUSDXAUChainlink.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\nimport \"@chainlink/contracts/src/v0.8/interfaces/AggregatorV3Interface.sol\";\n\nimport \"../../../BaseOracleChainlinkMultiTwoFeeds.sol\";\n\n/// @title OracleLUSDXAUChainlink\n/// @author Angle Labs, Inc.\n/// @notice Gives the price of LUSD in XAU in base 18\ncontract OracleLUSDXAUChainlink is BaseOracleChainlinkMultiTwoFeeds {\n string public constant DESCRIPTION = \"LUSD/GOLD Oracle\";\n\n constructor(uint32 _stalePeriod, address _treasury) BaseOracleChainlinkMultiTwoFeeds(_stalePeriod, _treasury) {}\n\n /// @inheritdoc IOracle\n function circuitChainlink() public pure override returns (AggregatorV3Interface[] memory) {\n AggregatorV3Interface[] memory _circuitChainlink = new AggregatorV3Interface[](2);\n // Oracle LUSD/USD\n _circuitChainlink[0] = AggregatorV3Interface(0x3D7aE7E594f2f2091Ad8798313450130d0Aba3a0);\n // Oracle XAU/USD\n _circuitChainlink[1] = AggregatorV3Interface(0x214eD9Da11D2fbe465a6fc601a91E62EbEc1a0D6);\n return _circuitChainlink;\n }\n}\n" + }, + "contracts/oracle/implementations/mainnet/XAU/OracleUSDCXAUChainlink.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\nimport \"@chainlink/contracts/src/v0.8/interfaces/AggregatorV3Interface.sol\";\n\nimport \"../../../BaseOracleChainlinkMultiTwoFeeds.sol\";\n\n/// @title OracleUSDCXAUChainlink\n/// @author Angle Labs, Inc.\n/// @notice Gives the price of USDC in XAU in base 18\ncontract OracleUSDCXAUChainlink is BaseOracleChainlinkMultiTwoFeeds {\n string public constant DESCRIPTION = \"USDC/GOLD Oracle\";\n\n constructor(uint32 _stalePeriod, address _treasury) BaseOracleChainlinkMultiTwoFeeds(_stalePeriod, _treasury) {}\n\n /// @inheritdoc IOracle\n function circuitChainlink() public pure override returns (AggregatorV3Interface[] memory) {\n AggregatorV3Interface[] memory _circuitChainlink = new AggregatorV3Interface[](2);\n // Oracle USDC/USD\n _circuitChainlink[0] = AggregatorV3Interface(0x8fFfFfd4AfB6115b954Bd326cbe7B4BA576818f6);\n // Oracle XAU/USD\n _circuitChainlink[1] = AggregatorV3Interface(0x214eD9Da11D2fbe465a6fc601a91E62EbEc1a0D6);\n return _circuitChainlink;\n }\n}\n" + }, + "contracts/oracle/implementations/mainnet/XAU/OracleWSTETHXAUChainlink.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\nimport \"@chainlink/contracts/src/v0.8/interfaces/AggregatorV3Interface.sol\";\n\nimport \"../../../BaseOracleChainlinkMultiTwoFeeds.sol\";\nimport \"../../../../interfaces/external/lido/IStETH.sol\";\n\n/// @title OracleWSTETHXAUChainlink\n/// @author Angle Labs, Inc.\n/// @notice Gives the price of wSTETH in XAU in base 18\ncontract OracleWSTETHXAUChainlink is BaseOracleChainlinkMultiTwoFeeds {\n string public constant DESCRIPTION = \"wSTETH/XAU Oracle\";\n IStETH public constant STETH = IStETH(0xae7ab96520DE3A18E5e111B5EaAb095312D7fE84);\n\n constructor(uint32 _stalePeriod, address _treasury) BaseOracleChainlinkMultiTwoFeeds(_stalePeriod, _treasury) {}\n\n /// @inheritdoc IOracle\n function circuitChainlink() public pure override returns (AggregatorV3Interface[] memory) {\n AggregatorV3Interface[] memory _circuitChainlink = new AggregatorV3Interface[](2);\n // Oracle stETH/USD\n _circuitChainlink[0] = AggregatorV3Interface(0xCfE54B5cD566aB89272946F602D76Ea879CAb4a8);\n // Oracle XAU/USD\n _circuitChainlink[1] = AggregatorV3Interface(0x214eD9Da11D2fbe465a6fc601a91E62EbEc1a0D6);\n return _circuitChainlink;\n }\n\n /// @inheritdoc BaseOracleChainlinkMultiTwoFeeds\n function _getQuoteAmount() internal view override returns (uint256) {\n return STETH.getPooledEthByShares(1 ether);\n }\n}\n" + }, + "contracts/oracle/implementations/optimism/EUR/OracleETHEURChainlinkOptimism.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\nimport \"@chainlink/contracts/src/v0.8/interfaces/AggregatorV3Interface.sol\";\n\nimport \"../../../BaseOracleChainlinkMultiTwoFeeds.sol\";\n\n/// @title OracleETHEURChainlinkOptimism\n/// @author Angle Labs, Inc.\n/// @notice Gives the price of ETH in Euro in base 18\n/// @dev This contract is built to be deployed on Optimism\ncontract OracleETHEURChainlinkOptimism is BaseOracleChainlinkMultiTwoFeeds {\n string public constant DESCRIPTION = \"ETH/EUR Oracle\";\n\n constructor(uint32 _stalePeriod, address _treasury) BaseOracleChainlinkMultiTwoFeeds(_stalePeriod, _treasury) {}\n\n /// @inheritdoc IOracle\n function circuitChainlink() public pure override returns (AggregatorV3Interface[] memory) {\n AggregatorV3Interface[] memory _circuitChainlink = new AggregatorV3Interface[](2);\n // Oracle ETH/USD\n _circuitChainlink[0] = AggregatorV3Interface(0x13e3Ee699D1909E989722E753853AE30b17e08c5);\n // Oracle EUR/USD\n _circuitChainlink[1] = AggregatorV3Interface(0x3626369857A10CcC6cc3A6e4f5C2f5984a519F20);\n return _circuitChainlink;\n }\n}\n" + }, + "contracts/oracle/implementations/optimism/EUR/OracleOPEURChainlinkOptimism.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\nimport \"@chainlink/contracts/src/v0.8/interfaces/AggregatorV3Interface.sol\";\n\nimport \"../../../BaseOracleChainlinkMultiTwoFeeds.sol\";\n\n/// @title OracleOPEURChainlinkOptimism\n/// @author Angle Labs, Inc.\n/// @notice Gives the price of OP in Euro in base 18\n/// @dev This contract is built to be deployed on Optimism\ncontract OracleOPEURChainlinkOptimism is BaseOracleChainlinkMultiTwoFeeds {\n string public constant DESCRIPTION = \"OP/EUR Oracle\";\n\n constructor(uint32 _stalePeriod, address _treasury) BaseOracleChainlinkMultiTwoFeeds(_stalePeriod, _treasury) {}\n\n /// @inheritdoc IOracle\n function circuitChainlink() public pure override returns (AggregatorV3Interface[] memory) {\n AggregatorV3Interface[] memory _circuitChainlink = new AggregatorV3Interface[](2);\n // Oracle OP/USD\n _circuitChainlink[0] = AggregatorV3Interface(0x0D276FC14719f9292D5C1eA2198673d1f4269246);\n // Oracle EUR/USD\n _circuitChainlink[1] = AggregatorV3Interface(0x3626369857A10CcC6cc3A6e4f5C2f5984a519F20);\n return _circuitChainlink;\n }\n}\n" + }, + "contracts/oracle/implementations/optimism/EUR/OracleUSDCEURChainlinkOptimism.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\nimport \"@chainlink/contracts/src/v0.8/interfaces/AggregatorV3Interface.sol\";\n\nimport \"../../../BaseOracleChainlinkMultiTwoFeeds.sol\";\n\n/// @title OracleUSDCEURChainlinkOptimism\n/// @author Angle Labs, Inc.\n/// @notice Gives the price of USDC in Euro in base 18\n/// @dev This contract is built to be deployed on Optimism\ncontract OracleUSDCEURChainlinkOptimism is BaseOracleChainlinkMultiTwoFeeds {\n string public constant DESCRIPTION = \"USDC/EUR Oracle\";\n\n constructor(uint32 _stalePeriod, address _treasury) BaseOracleChainlinkMultiTwoFeeds(_stalePeriod, _treasury) {}\n\n /// @inheritdoc IOracle\n function circuitChainlink() public pure override returns (AggregatorV3Interface[] memory) {\n AggregatorV3Interface[] memory _circuitChainlink = new AggregatorV3Interface[](2);\n // Oracle USDC/USD\n _circuitChainlink[0] = AggregatorV3Interface(0x16a9FA2FDa030272Ce99B29CF780dFA30361E0f3);\n // Oracle EUR/USD\n _circuitChainlink[1] = AggregatorV3Interface(0x3626369857A10CcC6cc3A6e4f5C2f5984a519F20);\n return _circuitChainlink;\n }\n}\n" + }, + "contracts/oracle/implementations/polygon/EUR/OracleBTCEURChainlinkPolygon.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\nimport \"@chainlink/contracts/src/v0.8/interfaces/AggregatorV3Interface.sol\";\n\nimport \"../../../BaseOracleChainlinkMultiTwoFeeds.sol\";\n\n/// @title OracleBTCEURChainlinkPolygon\n/// @author Angle Labs, Inc.\n/// @notice Gives the price of BTC in Euro in base 18\n/// @dev This contract is built to be deployed on Polygon\ncontract OracleBTCEURChainlinkPolygon is BaseOracleChainlinkMultiTwoFeeds {\n string public constant DESCRIPTION = \"BTC/EUR Oracle\";\n\n constructor(uint32 _stalePeriod, address _treasury) BaseOracleChainlinkMultiTwoFeeds(_stalePeriod, _treasury) {}\n\n /// @inheritdoc IOracle\n function circuitChainlink() public pure override returns (AggregatorV3Interface[] memory) {\n AggregatorV3Interface[] memory _circuitChainlink = new AggregatorV3Interface[](2);\n // Oracle BTC/USD\n _circuitChainlink[0] = AggregatorV3Interface(0xc907E116054Ad103354f2D350FD2514433D57F6f);\n // Oracle EUR/USD\n _circuitChainlink[1] = AggregatorV3Interface(0x73366Fe0AA0Ded304479862808e02506FE556a98);\n return _circuitChainlink;\n }\n}\n" + }, + "contracts/oracle/implementations/polygon/EUR/OracleETHEURChainlinkPolygon.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\nimport \"@chainlink/contracts/src/v0.8/interfaces/AggregatorV3Interface.sol\";\n\nimport \"../../../BaseOracleChainlinkMultiTwoFeeds.sol\";\n\n/// @title OracleETHEURChainlinkPolygon\n/// @author Angle Labs, Inc.\n/// @notice Gives the price of ETH in Euro in base 18\n/// @dev This contract is built to be deployed on Polygon\ncontract OracleETHEURChainlinkPolygon is BaseOracleChainlinkMultiTwoFeeds {\n string public constant DESCRIPTION = \"ETH/EUR Oracle\";\n\n constructor(uint32 _stalePeriod, address _treasury) BaseOracleChainlinkMultiTwoFeeds(_stalePeriod, _treasury) {}\n\n /// @inheritdoc IOracle\n function circuitChainlink() public pure override returns (AggregatorV3Interface[] memory) {\n AggregatorV3Interface[] memory _circuitChainlink = new AggregatorV3Interface[](2);\n // Oracle ETH/USD\n _circuitChainlink[0] = AggregatorV3Interface(0xF9680D99D6C9589e2a93a78A04A279e509205945);\n // Oracle EUR/USD\n _circuitChainlink[1] = AggregatorV3Interface(0x73366Fe0AA0Ded304479862808e02506FE556a98);\n return _circuitChainlink;\n }\n}\n" + }, + "contracts/oracle/implementations/polygon/EUR/OracleMAIEURChainlinkPolygon.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\nimport \"@chainlink/contracts/src/v0.8/interfaces/AggregatorV3Interface.sol\";\n\nimport \"../../../BaseOracleChainlinkMultiTwoFeeds.sol\";\n\n/// @title OracleMAIEURChainlinkPolygon\n/// @author Angle Labs, Inc.\n/// @notice Gives the price of MAI in Euro in base 18\n/// @dev This contract is built to be deployed on Polygon\ncontract OracleMAIEURChainlinkPolygon is BaseOracleChainlinkMultiTwoFeeds {\n string public constant DESCRIPTION = \"MAI/EUR Oracle\";\n\n constructor(uint32 _stalePeriod, address _treasury) BaseOracleChainlinkMultiTwoFeeds(_stalePeriod, _treasury) {}\n\n /// @inheritdoc IOracle\n function circuitChainlink() public pure override returns (AggregatorV3Interface[] memory) {\n AggregatorV3Interface[] memory _circuitChainlink = new AggregatorV3Interface[](2);\n // Oracle MAI/USD\n _circuitChainlink[0] = AggregatorV3Interface(0xd8d483d813547CfB624b8Dc33a00F2fcbCd2D428);\n // Oracle EUR/USD\n _circuitChainlink[1] = AggregatorV3Interface(0x73366Fe0AA0Ded304479862808e02506FE556a98);\n return _circuitChainlink;\n }\n}\n" + }, + "contracts/oracle/implementations/polygon/EUR/OracleMATICEURChainlinkPolygon.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\nimport \"@chainlink/contracts/src/v0.8/interfaces/AggregatorV3Interface.sol\";\n\nimport \"../../../BaseOracleChainlinkMultiTwoFeeds.sol\";\n\n/// @title OracleMATICEURChainlinkPolygon\n/// @author Angle Labs, Inc.\n/// @notice Gives the price of MATIC in Euro in base 18\n/// @dev This contract is built to be deployed on Polygon\ncontract OracleMATICEURChainlinkPolygon is BaseOracleChainlinkMultiTwoFeeds {\n string public constant DESCRIPTION = \"MATIC/EUR Oracle\";\n\n constructor(uint32 _stalePeriod, address _treasury) BaseOracleChainlinkMultiTwoFeeds(_stalePeriod, _treasury) {}\n\n /// @inheritdoc IOracle\n function circuitChainlink() public pure override returns (AggregatorV3Interface[] memory) {\n AggregatorV3Interface[] memory _circuitChainlink = new AggregatorV3Interface[](2);\n // Oracle MATIC/USD\n _circuitChainlink[0] = AggregatorV3Interface(0xAB594600376Ec9fD91F8e885dADF0CE036862dE0);\n // Oracle EUR/USD\n _circuitChainlink[1] = AggregatorV3Interface(0x73366Fe0AA0Ded304479862808e02506FE556a98);\n return _circuitChainlink;\n }\n}\n" + }, + "contracts/oracle/implementations/polygon/EUR/OracleUSDCEURChainlinkPolygon.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\nimport \"../../../BaseOracleChainlinkMultiTwoFeeds.sol\";\n\n/// @title OracleUSDCEURChainlinkPolygon\n/// @author Angle Labs, Inc.\n/// @notice Gives the price of USDC in Euro in base 18\n/// @dev This contract is built to be deployed on Polygon\ncontract OracleUSDCEURChainlinkPolygon is BaseOracleChainlinkMultiTwoFeeds {\n string public constant DESCRIPTION = \"USDC/EUR Oracle\";\n\n constructor(uint32 _stalePeriod, address _treasury) BaseOracleChainlinkMultiTwoFeeds(_stalePeriod, _treasury) {}\n\n /// @inheritdoc IOracle\n function circuitChainlink() public pure override returns (AggregatorV3Interface[] memory) {\n AggregatorV3Interface[] memory _circuitChainlink = new AggregatorV3Interface[](2);\n // Oracle USDC/USD\n _circuitChainlink[0] = AggregatorV3Interface(0xfE4A8cc5b5B2366C1B58Bea3858e81843581b2F7);\n // Oracle EUR/USD\n _circuitChainlink[1] = AggregatorV3Interface(0x73366Fe0AA0Ded304479862808e02506FE556a98);\n return _circuitChainlink;\n }\n}\n" + }, + "contracts/oracle/implementations/polygon/XAU/OracleETHXAUChainlinkPolygon.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\nimport \"@chainlink/contracts/src/v0.8/interfaces/AggregatorV3Interface.sol\";\n\nimport \"../../../BaseOracleChainlinkMultiTwoFeeds.sol\";\n\n/// @title OracleETHXAUChainlinkPolygon\n/// @author Angle Labs, Inc.\n/// @notice Gives the price of ETH in XAU in base 18\n/// @dev This contract is built to be deployed on Polygon\ncontract OracleETHXAUChainlinkPolygon is BaseOracleChainlinkMultiTwoFeeds {\n string public constant DESCRIPTION = \"ETH/GOLD Oracle\";\n\n constructor(uint32 _stalePeriod, address _treasury) BaseOracleChainlinkMultiTwoFeeds(_stalePeriod, _treasury) {}\n\n /// @inheritdoc IOracle\n function circuitChainlink() public pure override returns (AggregatorV3Interface[] memory) {\n AggregatorV3Interface[] memory _circuitChainlink = new AggregatorV3Interface[](2);\n // Oracle ETH/USD\n _circuitChainlink[0] = AggregatorV3Interface(0xF9680D99D6C9589e2a93a78A04A279e509205945);\n // Oracle XAU/USD\n _circuitChainlink[1] = AggregatorV3Interface(0x0C466540B2ee1a31b441671eac0ca886e051E410);\n return _circuitChainlink;\n }\n}\n" + }, + "contracts/oracle/KeeperRegistry.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\nimport \"@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol\";\nimport \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\nimport \"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\";\n\nimport \"../interfaces/ICoreBorrow.sol\";\nimport \"../interfaces/IKeeperRegistry.sol\";\n\n/// @title KeeperRegistry\n/// @notice Maintains a mapping of keepers authorized to use the core module just after oracle updates\n/// @author Angle Labs, Inc.\ncontract KeeperRegistry is Initializable, IKeeperRegistry {\n using SafeERC20 for IERC20;\n\n /// @notice Contract handling access control\n ICoreBorrow public coreBorrow;\n\n /// @notice Trusted EOAs - needs to be tx.origin\n mapping(address => uint256) public trusted;\n\n uint256[48] private __gap;\n\n // =================================== EVENTS ==================================\n\n event TrustedToggled(address indexed wallet, bool trust);\n\n // =================================== ERRORS ==================================\n\n error NotGovernorOrGuardian();\n error NotTrusted();\n error ZeroAddress();\n\n // ================================= MODIFIERS =================================\n\n /// @notice Checks whether the `msg.sender` has the governor role or the guardian role\n modifier onlyGovernorOrGuardian() {\n if (!coreBorrow.isGovernorOrGuardian(msg.sender)) revert NotGovernorOrGuardian();\n _;\n }\n\n // ================================ CONSTRUCTOR ================================\n\n constructor() initializer {}\n\n function initialize(ICoreBorrow _coreBorrow) public initializer {\n if (address(_coreBorrow) == address(0)) revert ZeroAddress();\n coreBorrow = _coreBorrow;\n }\n\n // =============================== MAIN FUNCTIONS ==============================\n\n /// @notice Adds or removes a trusted keeper bot\n function toggleTrusted(address eoa) external onlyGovernorOrGuardian {\n uint256 trustedStatus = 1 - trusted[eoa];\n trusted[eoa] = trustedStatus;\n emit TrustedToggled(eoa, trustedStatus == 1);\n }\n\n /// @inheritdoc IKeeperRegistry\n function isTrusted(address caller) external view returns (bool) {\n return trusted[caller] == 1;\n }\n}\n" + }, + "contracts/oracle/OracleChainlinkMulti.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\nimport \"@chainlink/contracts/src/v0.8/interfaces/AggregatorV3Interface.sol\";\n\nimport \"./BaseOracleChainlinkMulti.sol\";\n\n/// @title OracleChainlinkMulti\n/// @author Angle Labs, Inc.\n/// @notice Oracle contract, one contract is deployed per collateral/stablecoin pair\n/// @dev This contract concerns an oracle that uses Chainlink with multiple pools to read from\n/// @dev Typically we expect to use this contract to read like the ETH/USD and then USD/EUR feed\ncontract OracleChainlinkMulti is BaseOracleChainlinkMulti {\n // ========================= Parameters and References =========================\n\n /// @notice Chainlink pools, the order of the pools has to be the order in which they are read for the computation\n /// of the price\n AggregatorV3Interface[] internal _circuitChainlink;\n /// @notice Whether each rate for the pairs in `circuitChainlink` should be multiplied or divided\n uint8[] public circuitChainIsMultiplied;\n /// @notice Decimals for each Chainlink pairs\n uint8[] public chainlinkDecimals;\n /// @notice Unit of the stablecoin\n uint256 public immutable outBase;\n /// @notice Description of the assets concerned by the oracle and the price outputted\n string public description;\n\n // ===================================== Error =================================\n\n error IncompatibleLengths();\n\n /// @notice Constructor for an oracle using Chainlink with multiple pools to read from\n /// @param circuitChainlink_ Chainlink pool addresses (in order)\n /// @param _circuitChainIsMultiplied Whether we should multiply or divide by this rate\n /// @param _outBase Unit of the stablecoin (or the out asset) associated to the oracle\n /// @param _stalePeriod Minimum feed update frequency for the oracle to not revert\n /// @param _treasury Treasury associated to the VaultManager which reads from this feed\n /// @param _description Description of the assets concerned by the oracle\n /// @dev For instance, if this oracle is supposed to give the price of ETH in EUR, and if the agEUR\n /// stablecoin associated to EUR has 18 decimals, then `outBase` should be 10**18\n constructor(\n address[] memory circuitChainlink_,\n uint8[] memory _circuitChainIsMultiplied,\n uint256 _outBase,\n uint32 _stalePeriod,\n address _treasury,\n string memory _description\n ) BaseOracleChainlinkMulti(_stalePeriod, _treasury) {\n outBase = _outBase;\n description = _description;\n uint256 circuitLength = circuitChainlink_.length;\n if (circuitLength == 0 || circuitLength != _circuitChainIsMultiplied.length) revert IncompatibleLengths();\n for (uint256 i; i < circuitLength; ++i) {\n AggregatorV3Interface _pool = AggregatorV3Interface(circuitChainlink_[i]);\n _circuitChainlink.push(_pool);\n chainlinkDecimals.push(_pool.decimals());\n }\n circuitChainIsMultiplied = _circuitChainIsMultiplied;\n }\n\n // ============================= Reading Oracles ===============================\n\n /// @inheritdoc IOracle\n function circuitChainlink() public view override returns (AggregatorV3Interface[] memory) {\n return _circuitChainlink;\n }\n\n /// @inheritdoc IOracle\n function read() external view override returns (uint256 quoteAmount) {\n quoteAmount = outBase;\n uint256 circuitLength = _circuitChainlink.length;\n for (uint256 i; i < circuitLength; ++i) {\n quoteAmount = _readChainlinkFeed(\n quoteAmount,\n _circuitChainlink[i],\n circuitChainIsMultiplied[i],\n chainlinkDecimals[i]\n );\n }\n }\n}\n" + }, + "contracts/settlement/Settlement.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\nimport \"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\";\nimport \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\nimport \"@openzeppelin/contracts/token/ERC20/extensions/IERC20Metadata.sol\";\n\nimport \"../interfaces/IAgToken.sol\";\nimport \"../interfaces/ISwapper.sol\";\nimport \"../interfaces/IVaultManager.sol\";\n\n/// @title Settlement\n/// @author Angle Labs, Inc.\n/// @notice Settlement Contract for a VaultManager\n/// @dev This settlement contract should be activated by a careful governance which needs to have performed\n/// some key operations before activating this contract\n/// @dev In case of global settlement, there should be one settlement contract per `VaultManager`\ncontract Settlement {\n using SafeERC20 for IERC20;\n\n /// @notice Base used for parameter computation\n uint256 public constant BASE_PARAMS = 10 ** 9;\n /// @notice Base used for interest computation\n uint256 public constant BASE_INTEREST = 10 ** 27;\n /// @notice Base used for exchange rate computation. It is assumed\n /// that stablecoins have this base\n uint256 public constant BASE_STABLECOIN = 10 ** 18;\n /// @notice Duration of the claim period for over-collateralized vaults\n uint256 public constant OVER_COLLATERALIZED_CLAIM_DURATION = 3 * 24 * 3600;\n\n // =============== Immutable references set in the constructor =================\n\n /// @notice `VaultManager` of this settlement contract\n IVaultManager public immutable vaultManager;\n /// @notice Reference to the stablecoin supported by the `VaultManager` contract\n IAgToken public immutable stablecoin;\n /// @notice Reference to the collateral supported by the `VaultManager`\n IERC20 public immutable collateral;\n /// @notice Base of the collateral\n uint256 internal immutable _collatBase;\n\n // ================ Variables frozen at settlement activation ==================\n\n /// @notice Value of the oracle for the collateral/stablecoin pair\n uint256 public oracleValue;\n /// @notice Value of the interest accumulator at settlement activation\n uint256 public interestAccumulator;\n /// @notice Timestamp at which settlement was activated\n uint256 public activationTimestamp;\n /// @notice Collateral factor of the `VaultManager`\n uint64 public collateralFactor;\n\n // =================== Variables updated during the process ====================\n\n /// @notice How much collateral you can get from stablecoins\n uint256 public collateralStablecoinExchangeRate;\n /// @notice Amount of collateral that will be left over at the end of the process\n uint256 public leftOverCollateral;\n /// @notice Whether the `collateralStablecoinExchangeRate` has been computed\n bool public exchangeRateComputed;\n /// @notice Maps a vault to 1 if it was claimed by its owner\n mapping(uint256 => uint256) public vaultCheck;\n\n // ================================ Events =====================================\n\n event GlobalClaimPeriodActivated(uint256 _collateralStablecoinExchangeRate);\n event Recovered(address indexed tokenAddress, address indexed to, uint256 amount);\n event SettlementActivated(uint256 startTimestamp);\n event VaultClaimed(uint256 vaultID, uint256 stablecoinAmount, uint256 collateralAmount);\n\n // ================================ Errors =====================================\n\n error GlobalClaimPeriodNotStarted();\n error InsolventVault();\n error NotGovernor();\n error NotOwner();\n error RestrictedClaimPeriodNotEnded();\n error SettlementNotInitialized();\n error VaultAlreadyClaimed();\n\n /// @notice Constructor of the contract\n /// @param _vaultManager Address of the `VaultManager` associated to this `Settlement` contract\n /// @dev Out of safety, this constructor reads values from the `VaultManager` contract directly\n constructor(IVaultManager _vaultManager) {\n vaultManager = _vaultManager;\n stablecoin = _vaultManager.stablecoin();\n collateral = _vaultManager.collateral();\n _collatBase = 10 ** (IERC20Metadata(address(collateral)).decimals());\n }\n\n /// @notice Checks whether the `msg.sender` has the governor role or not\n modifier onlyGovernor() {\n if (!(vaultManager.treasury().isGovernor(msg.sender))) revert NotGovernor();\n _;\n }\n\n /// @notice Activates the settlement contract\n /// @dev When calling this function governance should make sure to have:\n /// 1. Accrued the interest rate on the contract\n /// 2. Paused the contract\n /// 3. Recovered all the collateral available in the `VaultManager` contract either\n /// by doing a contract upgrade or by calling a `recoverERC20` method if supported\n function activateSettlement() external onlyGovernor {\n oracleValue = (vaultManager.oracle()).read();\n interestAccumulator = vaultManager.interestAccumulator();\n activationTimestamp = block.timestamp;\n collateralFactor = vaultManager.collateralFactor();\n emit SettlementActivated(block.timestamp);\n }\n\n /// @notice Allows the owner of an over-collateralized vault to claim its collateral upon bringing back all owed stablecoins\n /// @param vaultID ID of the vault to claim\n /// @param to Address to which collateral should be sent\n /// @param who Address which should be notified if needed of the transfer of stablecoins and collateral\n /// @param data Data to pass to the `who` contract for it to successfully give the correct amount of stablecoins\n /// to the `msg.sender` address\n /// @return Amount of collateral sent to the `to` address\n /// @return Amount of stablecoins sent to the contract\n /// @dev Claiming can only happen short after settlement activation\n /// @dev A vault cannot be claimed twice and only the owner of the vault can claim it (regardless of the approval logic)\n /// @dev Only over-collateralized vaults can be claimed from this medium\n function claimOverCollateralizedVault(\n uint256 vaultID,\n address to,\n address who,\n bytes memory data\n ) external returns (uint256, uint256) {\n if (activationTimestamp == 0 || block.timestamp > activationTimestamp + OVER_COLLATERALIZED_CLAIM_DURATION)\n revert SettlementNotInitialized();\n if (vaultCheck[vaultID] == 1) revert VaultAlreadyClaimed();\n if (vaultManager.ownerOf(vaultID) != msg.sender) revert NotOwner();\n (uint256 collateralAmount, uint256 normalizedDebt) = vaultManager.vaultData(vaultID);\n uint256 vaultDebt = (normalizedDebt * interestAccumulator) / BASE_INTEREST;\n if (collateralAmount * oracleValue * collateralFactor < vaultDebt * BASE_PARAMS * _collatBase)\n revert InsolventVault();\n vaultCheck[vaultID] = 1;\n emit VaultClaimed(vaultID, vaultDebt, collateralAmount);\n return _handleRepay(collateralAmount, vaultDebt, to, who, data);\n }\n\n /// @notice Activates the global claim period by setting the `collateralStablecoinExchangeRate` which is going to\n /// dictate how much of collateral will be recoverable for each stablecoin\n /// @dev This function can only be called by the governor in order to allow it in case multiple settlements happen across\n /// different `VaultManager` to rebalance the amount of stablecoins on each to make sure that across all settlement contracts\n /// a similar value of collateral can be obtained against a similar value of stablecoins\n function activateGlobalClaimPeriod() external onlyGovernor {\n if (activationTimestamp == 0 || block.timestamp <= activationTimestamp + OVER_COLLATERALIZED_CLAIM_DURATION)\n revert RestrictedClaimPeriodNotEnded();\n uint256 collateralBalance = collateral.balanceOf(address(this));\n uint256 leftOverDebt = (vaultManager.totalNormalizedDebt() * interestAccumulator) / BASE_INTEREST;\n uint256 stablecoinBalance = stablecoin.balanceOf(address(this));\n // How much 1 of stablecoin will give you in collateral\n uint256 _collateralStablecoinExchangeRate;\n\n if (stablecoinBalance < leftOverDebt) {\n // The left over debt is the total debt minus the stablecoins which have already been accumulated\n // in the first phase\n leftOverDebt -= stablecoinBalance;\n // If you control all the debt, then you are entitled to get all the collateral left in the protocol\n _collateralStablecoinExchangeRate = (collateralBalance * BASE_STABLECOIN) / leftOverDebt;\n // But at the same time, you cannot get more collateral than the value of the stablecoins you brought\n uint256 maxExchangeRate = (BASE_STABLECOIN * _collatBase) / oracleValue;\n if (_collateralStablecoinExchangeRate >= maxExchangeRate) {\n // In this situation, we're sure that `leftOverCollateral` will be positive: governance should be wary\n // to call `recoverERC20` short after though as there's nothing that is going to prevent people to redeem\n // more stablecoins than the `leftOverDebt`\n leftOverCollateral = collateralBalance - (leftOverDebt * _collatBase) / oracleValue;\n _collateralStablecoinExchangeRate = maxExchangeRate;\n }\n }\n exchangeRateComputed = true;\n // In the else case where there is no debt left, you cannot get anything from your stablecoins\n // and so the `collateralStablecoinExchangeRate` is null\n collateralStablecoinExchangeRate = _collateralStablecoinExchangeRate;\n emit GlobalClaimPeriodActivated(_collateralStablecoinExchangeRate);\n }\n\n /// @notice Allows to claim collateral from stablecoins\n /// @param to Address to which collateral should be sent\n /// @param who Address which should be notified if needed of the transfer of stablecoins and collateral\n /// @param data Data to pass to the `who` contract for it to successfully give the correct amount of stablecoins\n /// to the `msg.sender` address\n /// @return Amount of collateral sent to the `to` address\n /// @return Amount of stablecoins sent to the contract\n /// @dev This function reverts if the `collateralStablecoinExchangeRate` is null and hence if the global claim period has\n /// not been activated\n function claimCollateralFromStablecoins(\n uint256 stablecoinAmount,\n address to,\n address who,\n bytes memory data\n ) external returns (uint256, uint256) {\n if (!exchangeRateComputed) revert GlobalClaimPeriodNotStarted();\n return\n _handleRepay(\n (stablecoinAmount * collateralStablecoinExchangeRate) / BASE_STABLECOIN,\n stablecoinAmount,\n to,\n who,\n data\n );\n }\n\n /// @notice Handles the simultaneous repayment of stablecoins with a transfer of collateral\n /// @param collateralAmountToGive Amount of collateral the contract should give\n /// @param stableAmountToRepay Amount of stablecoins the contract should burn from the call\n /// @param to Address to which stablecoins should be sent\n /// @param who Address which should be notified if needed of the transfer\n /// @param data Data to pass to the `who` contract for it to successfully give the correct amount of stablecoins\n /// to the `msg.sender` address\n /// @dev This function allows for capital-efficient claims of collateral from stablecoins\n function _handleRepay(\n uint256 collateralAmountToGive,\n uint256 stableAmountToRepay,\n address to,\n address who,\n bytes memory data\n ) internal returns (uint256, uint256) {\n collateral.safeTransfer(to, collateralAmountToGive);\n if (data.length != 0) {\n ISwapper(who).swap(\n collateral,\n IERC20(address(stablecoin)),\n msg.sender,\n stableAmountToRepay,\n collateralAmountToGive,\n data\n );\n }\n stablecoin.transferFrom(msg.sender, address(this), stableAmountToRepay);\n return (collateralAmountToGive, stableAmountToRepay);\n }\n\n /// @notice Recovers leftover tokens from the contract or tokens that were mistakenly sent to the contract\n /// @param tokenAddress Address of the token to recover\n /// @param to Address to send the remaining tokens to\n /// @param amountToRecover Amount to recover from the contract\n /// @dev Governors cannot recover more collateral than what would be leftover from the contract\n /// @dev This function can be used to rebalance stablecoin balances across different settlement contracts\n /// to make sure every stablecoin can be redeemed for the same value of collateral\n /// @dev It can also be used to recover tokens that are mistakenly sent to this contract\n function recoverERC20(address tokenAddress, address to, uint256 amountToRecover) external onlyGovernor {\n if (tokenAddress == address(collateral)) {\n if (!exchangeRateComputed) revert GlobalClaimPeriodNotStarted();\n leftOverCollateral -= amountToRecover;\n collateral.safeTransfer(to, amountToRecover);\n } else {\n IERC20(tokenAddress).safeTransfer(to, amountToRecover);\n }\n emit Recovered(tokenAddress, to, amountToRecover);\n }\n}\n" + }, + "contracts/swapper/Swapper.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\n/*\n * █ \n ***** ▓▓▓ \n * ▓▓▓▓▓▓▓ \n * ///. ▓▓▓▓▓▓▓▓▓▓▓▓▓ \n ***** //////// ▓▓▓▓▓▓▓ \n * ///////////// ▓▓▓ \n ▓▓ ////////////////// █ ▓▓ \n ▓▓ ▓▓ /////////////////////// ▓▓ ▓▓ \n ▓▓ ▓▓ //////////////////////////// ▓▓ ▓▓ \n ▓▓ ▓▓ /////////▓▓▓///////▓▓▓///////// ▓▓ ▓▓ \n ▓▓ ,////////////////////////////////////// ▓▓ ▓▓ \n ▓▓ ////////////////////////////////////////// ▓▓ \n ▓▓ //////////////////////▓▓▓▓///////////////////// \n ,//////////////////////////////////////////////////// \n .////////////////////////////////////////////////////////// \n .//////////////////////////██.,//////////////////////////█ \n .//////////////////////████..,./////////////////////██ \n ...////////////////███████.....,.////////////////███ \n ,.,////////////████████ ........,///////////████ \n .,.,//////█████████ ,.......///////████ \n ,..//████████ ........./████ \n ..,██████ .....,███ \n .██ ,.,█ \n \n \n \n ▓▓ ▓▓▓▓▓▓▓▓▓▓ ▓▓▓▓▓▓▓▓▓▓ ▓▓ ▓▓▓▓▓▓▓▓▓▓ \n ▓▓▓▓▓▓ ▓▓▓ ▓▓▓ ▓▓▓ ▓▓ ▓▓ ▓▓▓▓ \n ▓▓▓ ▓▓▓ ▓▓▓ ▓▓▓ ▓▓▓ ▓▓▓ ▓▓ ▓▓▓▓▓ \n ▓▓▓ ▓▓ ▓▓▓ ▓▓▓ ▓▓▓▓▓▓▓▓▓▓ ▓▓▓▓▓▓▓▓▓▓ ▓▓▓▓▓▓▓▓▓▓ \n*/\n\npragma solidity ^0.8.12;\n\nimport \"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\";\nimport \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\n\nimport \"../interfaces/IAngleRouterSidechain.sol\";\nimport \"../interfaces/ICoreBorrow.sol\";\nimport \"../interfaces/ISwapper.sol\";\nimport \"../interfaces/external/lido/IWStETH.sol\";\nimport \"../interfaces/external/uniswap/IUniswapRouter.sol\";\n\n// ==================================== ENUM ===================================\n\n/// @notice All possible swaps\nenum SwapType {\n UniswapV3,\n oneInch,\n AngleRouter,\n Leverage,\n None\n}\n\n/// @title Swapper\n/// @author Angle Labs, Inc.\n/// @notice Swapper contract facilitating interactions with Angle VaultManager contracts, notably\n/// liquidation and leverage transactions\ncontract Swapper is ISwapper {\n using SafeERC20 for IERC20;\n\n // ===================== CONSTANTS AND IMMUTABLE VARIABLES =====================\n\n /// @notice Reference to the `CoreBorrow` contract of the module which handles all AccessControl logic\n ICoreBorrow public immutable core;\n /// @notice Uniswap Router contract\n IUniswapV3Router public immutable uniV3Router;\n /// @notice 1inch Router\n address public immutable oneInch;\n /// @notice AngleRouter\n IAngleRouterSidechain public immutable angleRouter;\n\n // =================================== ERRORS ==================================\n\n error EmptyReturnMessage();\n error IncompatibleLengths();\n error NotGovernorOrGuardian();\n error TooSmallAmountOut();\n error ZeroAddress();\n\n /// @notice Constructor of the contract\n /// @param _core Core address\n /// @param _uniV3Router UniswapV3 Router address\n /// @param _oneInch 1inch Router address\n /// @param _angleRouter AngleRouter contract address\n constructor(\n ICoreBorrow _core,\n IUniswapV3Router _uniV3Router,\n address _oneInch,\n IAngleRouterSidechain _angleRouter\n ) {\n if (address(_core) == address(0) || _oneInch == address(0) || address(_angleRouter) == address(0))\n revert ZeroAddress();\n core = _core;\n uniV3Router = _uniV3Router;\n oneInch = _oneInch;\n angleRouter = _angleRouter;\n }\n\n // ========================= EXTERNAL ACCESS FUNCTIONS =========================\n\n /// @inheritdoc ISwapper\n /// @dev This function swaps the `inToken` to the `outToken` by doing a UniV3 swap, a 1inch swap or by interacting\n /// with the `AngleRouter` contract\n /// @dev One slippage check is performed at the end of the call\n /// @dev In this implementation, the function tries to make sure that the `outTokenRecipient` address has at the end\n /// of the call `outTokenOwed`, leftover tokens are sent to a `to` address which by default is the `outTokenRecipient`\n function swap(\n IERC20 inToken,\n IERC20 outToken,\n address outTokenRecipient,\n uint256 outTokenOwed,\n uint256 inTokenObtained,\n bytes memory data\n ) external {\n // Address to receive the surplus amount of token at the end of the call\n address to;\n // For slippage protection, it is checked at the end of the call\n uint256 minAmountOut;\n // Type of the swap to execute: if `swapType == 4`, then it is optional to swap\n uint256 swapType;\n // We're reusing the `data` variable (it can be `path` on UniswapV3, a payload for 1inch or like encoded actions\n // for a router call)\n (to, minAmountOut, swapType, data) = abi.decode(data, (address, uint256, uint256, bytes));\n\n to = (to == address(0)) ? outTokenRecipient : to;\n\n _swap(inToken, inTokenObtained, SwapType(swapType), data);\n\n // A final slippage check is performed after the swaps\n uint256 outTokenBalance = outToken.balanceOf(address(this));\n if (outTokenBalance < minAmountOut) revert TooSmallAmountOut();\n\n // The `outTokenRecipient` may already have enough in balance, in which case there's no need to transfer\n // to this address the token and everything can be given to the `to` address\n uint256 outTokenBalanceRecipient = outToken.balanceOf(outTokenRecipient);\n if (outTokenBalanceRecipient >= outTokenOwed || to == outTokenRecipient)\n outToken.safeTransfer(to, outTokenBalance);\n else {\n // The `outTokenRecipient` should receive the delta to make sure its end balance is equal to `outTokenOwed`\n // Any leftover in this case is sent to the `to` address\n // The function reverts if it did not obtain more than `outTokenOwed - outTokenBalanceRecipient` from the swap\n outToken.safeTransfer(outTokenRecipient, outTokenOwed - outTokenBalanceRecipient);\n outToken.safeTransfer(to, outTokenBalanceRecipient + outTokenBalance - outTokenOwed);\n }\n // Reusing the `inTokenObtained` variable for the `inToken` balance\n // Sending back the remaining amount of inTokens to the `to` address: it is possible that not the full `inTokenObtained`\n // is swapped to `outToken` if we're using the `1inch` payload\n inTokenObtained = inToken.balanceOf(address(this));\n if (inTokenObtained != 0) inToken.safeTransfer(to, inTokenObtained);\n }\n\n // ============================ GOVERNANCE FUNCTION ============================\n\n /// @notice Changes allowances of this contract for different tokens\n /// @param tokens Addresses of the tokens to allow\n /// @param spenders Addresses to allow transfer\n /// @param amounts Amounts to allow\n function changeAllowance(\n IERC20[] calldata tokens,\n address[] calldata spenders,\n uint256[] calldata amounts\n ) external {\n if (!core.isGovernorOrGuardian(msg.sender)) revert NotGovernorOrGuardian();\n uint256 tokensLength = tokens.length;\n if (tokensLength != spenders.length || tokensLength != amounts.length) revert IncompatibleLengths();\n for (uint256 i; i < tokensLength; ++i) {\n _changeAllowance(tokens[i], spenders[i], amounts[i]);\n }\n }\n\n // ========================= INTERNAL UTILITY FUNCTIONS ========================\n\n /// @notice Internal version of the `_changeAllowance` function\n function _changeAllowance(IERC20 token, address spender, uint256 amount) internal {\n uint256 currentAllowance = token.allowance(address(this), spender);\n // In case `currentAllowance < type(uint256).max / 2` and we want to increase it:\n // Do nothing (to handle tokens that need reapprovals to 0 and save gas)\n if (currentAllowance < amount && currentAllowance < type(uint256).max / 2) {\n token.safeIncreaseAllowance(spender, amount - currentAllowance);\n } else if (currentAllowance > amount) {\n token.safeDecreaseAllowance(spender, currentAllowance - amount);\n }\n }\n\n /// @notice Checks the allowance for a contract and updates it to the max if it is not big enough\n /// @param token Token for which allowance should be checked\n /// @param spender Address to grant allowance to\n /// @param amount Minimum amount of tokens needed for the allowance\n function _checkAllowance(IERC20 token, address spender, uint256 amount) internal {\n uint256 currentAllowance = token.allowance(address(this), spender);\n if (currentAllowance < amount) token.safeIncreaseAllowance(spender, type(uint256).max - currentAllowance);\n }\n\n /// @notice Performs a swap using either Uniswap, 1inch. This function can also stake stETH to wstETH\n /// @param inToken Token to swap\n /// @param amount Amount of tokens to swap\n /// @param swapType Type of the swap to perform\n /// @param args Extra args for the swap: in the case of Uniswap it should be a path, for 1inch it should be\n /// a payload\n /// @dev This function does nothing if `swapType` is None and it simply passes on the `amount` it received\n /// @dev No slippage is specified in the actions given here as a final slippage check is performed\n /// after the call to this function\n function _swap(IERC20 inToken, uint256 amount, SwapType swapType, bytes memory args) internal {\n if (swapType == SwapType.UniswapV3) _swapOnUniswapV3(inToken, amount, args);\n else if (swapType == SwapType.oneInch) _swapOn1inch(inToken, args);\n else if (swapType == SwapType.AngleRouter) _angleRouterActions(inToken, args);\n else if (swapType == SwapType.Leverage) _swapLeverage(args);\n }\n\n /// @notice Performs a UniswapV3 swap\n /// @param inToken Token to swap\n /// @param amount Amount of tokens to swap\n /// @param path Path for the UniswapV3 swap: this encodes the out token that is going to be obtained\n /// @dev This function does not check the out token obtained here: if it is wrongly specified, either\n /// the `swap` function could fail or these tokens could stay on the contract\n function _swapOnUniswapV3(IERC20 inToken, uint256 amount, bytes memory path) internal returns (uint256 amountOut) {\n // We need more than `amount` of allowance to the contract\n _checkAllowance(inToken, address(uniV3Router), amount);\n amountOut = uniV3Router.exactInput(ExactInputParams(path, address(this), block.timestamp, amount, 0));\n }\n\n /// @notice Allows to swap any token to an accepted collateral via 1inch API\n /// @param inToken Token received for the 1inch swap\n /// @param payload Bytes needed for 1inch API\n function _swapOn1inch(IERC20 inToken, bytes memory payload) internal returns (uint256 amountOut) {\n _changeAllowance(inToken, oneInch, type(uint256).max);\n //solhint-disable-next-line\n (bool success, bytes memory result) = oneInch.call(payload);\n if (!success) _revertBytes(result);\n amountOut = abi.decode(result, (uint256));\n }\n\n /// @notice Performs actions with the router contract of the protocol on the corresponding chain\n /// @param inToken Token concerned by the action and for which\n function _angleRouterActions(IERC20 inToken, bytes memory args) internal {\n (ActionType[] memory actions, bytes[] memory actionData) = abi.decode(args, (ActionType[], bytes[]));\n _changeAllowance(inToken, address(angleRouter), type(uint256).max);\n PermitType[] memory permits;\n angleRouter.mixer(permits, actions, actionData);\n }\n\n /// @notice Allows to take leverage or deleverage via a specific contract\n /// @param payload Bytes needed for 1inch API\n /// @dev This function is to be implemented if the swapper concerns a token that requires some actions\n /// not supported by 1inch or UniV3\n function _swapLeverage(bytes memory payload) internal virtual returns (uint256 amountOut) {}\n\n /// @notice Internal function used for error handling\n /// @param errMsg Error message received\n function _revertBytes(bytes memory errMsg) internal pure {\n if (errMsg.length != 0) {\n //solhint-disable-next-line\n assembly {\n revert(add(32, errMsg), mload(errMsg))\n }\n }\n revert EmptyReturnMessage();\n }\n}\n" + }, + "contracts/treasury/Treasury.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\n/*\n * █ \n ***** ▓▓▓ \n * ▓▓▓▓▓▓▓ \n * ///. ▓▓▓▓▓▓▓▓▓▓▓▓▓ \n ***** //////// ▓▓▓▓▓▓▓ \n * ///////////// ▓▓▓ \n ▓▓ ////////////////// █ ▓▓ \n ▓▓ ▓▓ /////////////////////// ▓▓ ▓▓ \n ▓▓ ▓▓ //////////////////////////// ▓▓ ▓▓ \n ▓▓ ▓▓ /////////▓▓▓///////▓▓▓///////// ▓▓ ▓▓ \n ▓▓ ,////////////////////////////////////// ▓▓ ▓▓ \n ▓▓ ////////////////////////////////////////// ▓▓ \n ▓▓ //////////////////////▓▓▓▓///////////////////// \n ,//////////////////////////////////////////////////// \n .////////////////////////////////////////////////////////// \n .//////////////////////////██.,//////////////////////////█ \n .//////////////////////████..,./////////////////////██ \n ...////////////////███████.....,.////////////////███ \n ,.,////////////████████ ........,///////////████ \n .,.,//////█████████ ,.......///////████ \n ,..//████████ ........./████ \n ..,██████ .....,███ \n .██ ,.,█ \n \n \n \n ▓▓ ▓▓▓▓▓▓▓▓▓▓ ▓▓▓▓▓▓▓▓▓▓ ▓▓ ▓▓▓▓▓▓▓▓▓▓ \n ▓▓▓▓▓▓ ▓▓▓ ▓▓▓ ▓▓▓ ▓▓ ▓▓ ▓▓▓▓ \n ▓▓▓ ▓▓▓ ▓▓▓ ▓▓▓ ▓▓▓ ▓▓▓ ▓▓ ▓▓▓▓▓ \n ▓▓▓ ▓▓ ▓▓▓ ▓▓▓ ▓▓▓▓▓▓▓▓▓▓ ▓▓▓▓▓▓▓▓▓▓ ▓▓▓▓▓▓▓▓▓▓ \n*/\n\npragma solidity ^0.8.12;\n\nimport \"@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol\";\nimport \"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\";\nimport \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\n\nimport \"../interfaces/IAgToken.sol\";\nimport \"../interfaces/ICoreBorrow.sol\";\nimport \"../interfaces/IFlashAngle.sol\";\nimport \"../interfaces/ITreasury.sol\";\nimport \"../interfaces/IVaultManager.sol\";\n\n/// @title Treasury\n/// @author Angle Labs, Inc.\n/// @notice Treasury of Angle Borrowing Module doing the accounting across all VaultManagers for\n/// a given stablecoin\ncontract Treasury is ITreasury, Initializable {\n using SafeERC20 for IERC20;\n\n /// @notice Base used for parameter computation\n uint256 public constant BASE_9 = 1e9;\n\n // ================================= REFERENCES ================================\n\n /// @notice Reference to the `CoreBorrow` contract of the module which handles all AccessControl logic\n ICoreBorrow public core;\n /// @notice Flash Loan Module with a minter right on the stablecoin\n IFlashAngle public flashLoanModule;\n /// @inheritdoc ITreasury\n IAgToken public stablecoin;\n /// @notice Address responsible for handling the surplus made by the treasury\n address public surplusManager;\n /// @notice List of the accepted `VaultManager` of the protocol\n address[] public vaultManagerList;\n /// @notice Maps an address to 1 if it was initialized as a `VaultManager` contract\n mapping(address => uint256) public vaultManagerMap;\n\n // ================================= VARIABLES =================================\n\n /// @notice Amount of bad debt (unbacked stablecoin) accumulated across all `VaultManager` contracts\n /// linked to this stablecoin\n uint256 public badDebt;\n /// @notice Surplus amount accumulated by the contract waiting to be distributed to governance. Technically\n /// only a share of this `surplusBuffer` will go to governance. Once a share of the surplus buffer has been\n /// given to governance, then this surplus is reset\n uint256 public surplusBuffer;\n\n // ================================= PARAMETER =================================\n\n /// @notice Share of the `surplusBuffer` distributed to governance (in `BASE_9`)\n uint64 public surplusForGovernance;\n\n // =================================== EVENTS ==================================\n\n event BadDebtUpdated(uint256 badDebtValue);\n event CoreUpdated(address indexed _core);\n event NewTreasurySet(address indexed _treasury);\n event Recovered(address indexed token, address indexed to, uint256 amount);\n event SurplusBufferUpdated(uint256 surplusBufferValue);\n event SurplusForGovernanceUpdated(uint64 _surplusForGovernance);\n event SurplusManagerUpdated(address indexed _surplusManager);\n event VaultManagerToggled(address indexed vaultManager);\n\n // =================================== ERRORS ==================================\n\n error AlreadyVaultManager();\n error InvalidAddress();\n error InvalidTreasury();\n error NotCore();\n error NotGovernor();\n error NotVaultManager();\n error RightsNotRemoved();\n error TooBigAmount();\n error TooHighParameterValue();\n error ZeroAddress();\n\n // ================================== MODIFIER =================================\n\n /// @notice Checks whether the `msg.sender` has the governor role or not\n modifier onlyGovernor() {\n if (!core.isGovernor(msg.sender)) revert NotGovernor();\n _;\n }\n\n /// @notice Initializes the treasury contract\n /// @param _core Address of the `CoreBorrow` contract of the module\n /// @param _stablecoin Address of the stablecoin\n function initialize(ICoreBorrow _core, IAgToken _stablecoin) public virtual initializer {\n if (address(_stablecoin) == address(0) || address(_core) == address(0)) revert ZeroAddress();\n core = _core;\n stablecoin = _stablecoin;\n }\n\n /// @custom:oz-upgrades-unsafe-allow constructor\n constructor() initializer {}\n\n // =============================== VIEW FUNCTIONS ==============================\n\n /// @inheritdoc ITreasury\n function isGovernor(address admin) external view returns (bool) {\n return core.isGovernor(admin);\n }\n\n /// @inheritdoc ITreasury\n function isGovernorOrGuardian(address admin) external view returns (bool) {\n return core.isGovernorOrGuardian(admin);\n }\n\n /// @inheritdoc ITreasury\n function isVaultManager(address _vaultManager) external view returns (bool) {\n return vaultManagerMap[_vaultManager] == 1;\n }\n\n // ===================== EXTERNAL PERMISSIONLESS FUNCTIONS =====================\n\n /// @notice Fetches the surplus accrued across all the `VaultManager` contracts controlled by this\n /// `Treasury` contract as well as from the fees of the `FlashLoan` module\n /// @return Surplus buffer value at the end of the call\n /// @return Bad debt value at the end of the call\n /// @dev This function pools surplus and bad debt across all contracts and then updates the `surplusBuffer`\n /// (or the `badDebt` if more losses were made than profits)\n function fetchSurplusFromAll() external returns (uint256, uint256) {\n return _fetchSurplusFromAll();\n }\n\n /// @notice Fetches the surplus accrued in the flash loan module and updates the `surplusBuffer`\n /// @return Surplus buffer value at the end of the call\n /// @return Bad debt value at the end of the call\n /// @dev This function fails if the `flashLoanModule` has not been initialized yet\n function fetchSurplusFromFlashLoan() external returns (uint256, uint256) {\n uint256 surplusBufferValue = surplusBuffer + flashLoanModule.accrueInterestToTreasury(stablecoin);\n return _updateSurplusAndBadDebt(surplusBufferValue, badDebt);\n }\n\n /// @notice Pushes the surplus buffer to the `surplusManager` contract\n /// @return governanceAllocation Amount transferred to governance\n /// @dev It makes sure to fetch the surplus from all the contracts handled by this treasury to avoid\n /// the situation where rewards are still distributed to governance even though a `VaultManager` has made\n /// a big loss\n /// @dev Typically this function is to be called once every week by a keeper to distribute rewards to veANGLE\n /// holders\n /// @dev `stablecoin` must be an AgToken and hence `transfer` reverts if the call is not successful\n function pushSurplus() external returns (uint256 governanceAllocation) {\n address _surplusManager = surplusManager;\n if (_surplusManager == address(0)) {\n revert ZeroAddress();\n }\n (uint256 surplusBufferValue, ) = _fetchSurplusFromAll();\n surplusBuffer = 0;\n emit SurplusBufferUpdated(0);\n governanceAllocation = (surplusForGovernance * surplusBufferValue) / BASE_9;\n stablecoin.transfer(_surplusManager, governanceAllocation);\n }\n\n /// @notice Updates the bad debt of the protocol in case where the protocol has accumulated some revenue\n /// from an external source\n /// @param amount Amount to reduce the bad debt of\n /// @return badDebtValue Value of the bad debt at the end of the call\n /// @dev If the protocol has made a loss and managed to make some profits to recover for this loss (through\n /// a program like Olympus Pro), then this function needs to be called\n /// @dev `badDebt` is simply reduced here by burning stablecoins\n /// @dev It is impossible to burn more than the `badDebt` otherwise this function could be used to manipulate\n /// the `surplusBuffer` and hence the amount going to governance\n function updateBadDebt(uint256 amount) external returns (uint256 badDebtValue) {\n stablecoin.burnSelf(amount, address(this));\n badDebtValue = badDebt - amount;\n badDebt = badDebtValue;\n emit BadDebtUpdated(badDebtValue);\n }\n\n // ========================= INTERNAL UTILITY FUNCTIONS ========================\n\n /// @notice Internal version of the `fetchSurplusFromAll` function\n function _fetchSurplusFromAll() internal returns (uint256 surplusBufferValue, uint256 badDebtValue) {\n (surplusBufferValue, badDebtValue) = _fetchSurplusFromList(vaultManagerList);\n // It will fail anyway if the `flashLoanModule` is the zero address\n if (address(flashLoanModule) != address(0))\n surplusBufferValue += flashLoanModule.accrueInterestToTreasury(stablecoin);\n (surplusBufferValue, badDebtValue) = _updateSurplusAndBadDebt(surplusBufferValue, badDebtValue);\n }\n\n /// @notice Fetches the surplus from a list of `VaultManager` addresses without modifying the\n /// `surplusBuffer` and `badDebtValue`\n /// @return surplusBufferValue Value the `surplusBuffer` should have after the call if it was updated\n /// @return badDebtValue Value the `badDebt` should have after the call if it was updated\n /// @dev This internal function is never to be called alone, and should always be called in conjunction\n /// with the `_updateSurplusAndBadDebt` function\n function _fetchSurplusFromList(\n address[] memory vaultManagers\n ) internal returns (uint256 surplusBufferValue, uint256 badDebtValue) {\n badDebtValue = badDebt;\n surplusBufferValue = surplusBuffer;\n uint256 newSurplus;\n uint256 newBadDebt;\n uint256 vaultManagersLength = vaultManagers.length;\n for (uint256 i; i < vaultManagersLength; ++i) {\n (newSurplus, newBadDebt) = IVaultManager(vaultManagers[i]).accrueInterestToTreasury();\n surplusBufferValue += newSurplus;\n badDebtValue += newBadDebt;\n }\n }\n\n /// @notice Updates the `surplusBuffer` and the `badDebt` from updated values after calling the flash loan module\n /// and/or a list of `VaultManager` contracts\n /// @param surplusBufferValue Value of the surplus buffer after the calls to the different modules\n /// @param badDebtValue Value of the bad debt after the calls to the different modules\n /// @return Value of the `surplusBuffer` corrected from the `badDebt`\n /// @return Value of the `badDebt` corrected from the `surplusBuffer` and from the surplus the treasury had accumulated\n /// previously\n /// @dev When calling this function, it is possible that there is a positive `surplusBufferValue` and `badDebtValue`,\n /// this function tries to reconcile both values and makes sure that we either have surplus or bad debt but not both\n /// at the same time\n function _updateSurplusAndBadDebt(\n uint256 surplusBufferValue,\n uint256 badDebtValue\n ) internal returns (uint256, uint256) {\n if (badDebtValue != 0) {\n // If we have bad debt we need to burn stablecoins that accrued to the protocol\n // We still need to make sure that we're not burning too much or as much as we can if the debt is big\n uint256 balance = stablecoin.balanceOf(address(this));\n // We are going to burn `min(balance, badDebtValue)`\n uint256 toBurn = balance <= badDebtValue ? balance : badDebtValue;\n stablecoin.burnSelf(toBurn, address(this));\n // If we burned more than `surplusBuffer`, we set surplus to 0. It means we had to tap into Treasury reserve\n surplusBufferValue = toBurn >= surplusBufferValue ? 0 : surplusBufferValue - toBurn;\n badDebtValue -= toBurn;\n // Note here that the stablecoin balance is necessarily greater than the surplus buffer, and so if\n // `surplusBuffer >= toBurn`, then `badDebtValue = toBurn`\n }\n surplusBuffer = surplusBufferValue;\n badDebt = badDebtValue;\n emit SurplusBufferUpdated(surplusBufferValue);\n emit BadDebtUpdated(badDebtValue);\n return (surplusBufferValue, badDebtValue);\n }\n\n /// @notice Adds a new `VaultManager`\n /// @param vaultManager `VaultManager` contract to add\n /// @dev This contract should have already been initialized with a correct treasury address\n /// @dev It's this function that gives the minter right to the `VaultManager`\n function _addVaultManager(address vaultManager) internal virtual {\n if (vaultManagerMap[vaultManager] == 1) revert AlreadyVaultManager();\n if (address(IVaultManager(vaultManager).treasury()) != address(this)) revert InvalidTreasury();\n vaultManagerMap[vaultManager] = 1;\n vaultManagerList.push(vaultManager);\n emit VaultManagerToggled(vaultManager);\n stablecoin.addMinter(vaultManager);\n }\n\n // ============================= GOVERNOR FUNCTIONS ============================\n\n /// @notice Adds a new minter for the stablecoin\n /// @param minter Minter address to add\n function addMinter(address minter) external virtual onlyGovernor {\n if (minter == address(0)) revert ZeroAddress();\n stablecoin.addMinter(minter);\n }\n\n /// @notice External wrapper for `_addVaultManager`\n function addVaultManager(address vaultManager) external virtual onlyGovernor {\n _addVaultManager(vaultManager);\n }\n\n /// @notice Removes a minter from the stablecoin contract\n /// @param minter Minter address to remove\n function removeMinter(address minter) external virtual onlyGovernor {\n // To remove the minter role to a `VaultManager` you have to go through the `removeVaultManager` function\n if (vaultManagerMap[minter] == 1) revert InvalidAddress();\n stablecoin.removeMinter(minter);\n }\n\n /// @notice Removes a `VaultManager`\n /// @param vaultManager `VaultManager` contract to remove\n /// @dev A removed `VaultManager` loses its minter right on the stablecoin\n function removeVaultManager(address vaultManager) external onlyGovernor {\n if (vaultManagerMap[vaultManager] != 1) revert NotVaultManager();\n delete vaultManagerMap[vaultManager];\n // deletion from `vaultManagerList` loop\n uint256 vaultManagerListLength = vaultManagerList.length;\n for (uint256 i; i < vaultManagerListLength - 1; ++i) {\n if (vaultManagerList[i] == vaultManager) {\n // replace the `VaultManager` to remove with the last of the list\n vaultManagerList[i] = vaultManagerList[vaultManagerListLength - 1];\n break;\n }\n }\n // remove last element in array\n vaultManagerList.pop();\n emit VaultManagerToggled(vaultManager);\n stablecoin.removeMinter(vaultManager);\n }\n\n /// @notice Allows to recover any ERC20 token, including the stablecoin handled by this contract, and to send it\n /// to a contract\n /// @param tokenAddress Address of the token to recover\n /// @param to Address of the contract to send collateral to\n /// @param amountToRecover Amount of collateral to transfer\n /// @dev It is impossible to recover the stablecoin of the protocol if there is some bad debt for it\n /// @dev In this case, the function makes sure to fetch the surplus/bad debt from all the `VaultManager` contracts\n /// and from the flash loan module\n /// @dev If the token to recover is the stablecoin, tokens recovered are fetched\n /// from the surplus and not from the `surplusBuffer`\n function recoverERC20(address tokenAddress, address to, uint256 amountToRecover) external onlyGovernor {\n // Cannot recover stablecoin if badDebt or tap into the surplus buffer\n if (tokenAddress == address(stablecoin)) {\n _fetchSurplusFromAll();\n // If balance is non zero then this means, after the call to `fetchSurplusFromAll` that\n // bad debt is necessarily null\n uint256 balance = stablecoin.balanceOf(address(this));\n if (amountToRecover + surplusBuffer > balance) revert TooBigAmount();\n stablecoin.transfer(to, amountToRecover);\n } else {\n IERC20(tokenAddress).safeTransfer(to, amountToRecover);\n }\n emit Recovered(tokenAddress, to, amountToRecover);\n }\n\n /// @notice Changes the treasury contract and communicates this change to all `VaultManager` contract\n /// @param _treasury New treasury address for this stablecoin\n /// @dev This function is basically a way to remove rights to this contract and grant them to a new one\n /// @dev It could be used to set a new core contract\n function setTreasury(address _treasury) external virtual onlyGovernor {\n if (ITreasury(_treasury).stablecoin() != stablecoin) revert InvalidTreasury();\n // Flash loan role should be removed before calling this function\n if (core.isFlashLoanerTreasury(address(this))) revert RightsNotRemoved();\n emit NewTreasurySet(_treasury);\n uint256 vaultManagerListLength = vaultManagerList.length;\n for (uint256 i; i < vaultManagerListLength; ++i) {\n IVaultManager(vaultManagerList[i]).setTreasury(_treasury);\n }\n // A `TreasuryUpdated` event is triggered in the stablecoin\n stablecoin.setTreasury(_treasury);\n }\n\n /// @notice Sets the `surplusForGovernance` parameter\n /// @param _surplusForGovernance New value of the parameter\n /// @dev To pause surplus distribution, governance needs to set a zero value for `surplusForGovernance`\n /// which means\n function setSurplusForGovernance(uint64 _surplusForGovernance) external onlyGovernor {\n if (_surplusForGovernance > BASE_9) revert TooHighParameterValue();\n surplusForGovernance = _surplusForGovernance;\n emit SurplusForGovernanceUpdated(_surplusForGovernance);\n }\n\n /// @notice Sets the `surplusManager` contract responsible for handling the surplus of the\n /// protocol\n /// @param _surplusManager New address responsible for handling the surplus\n function setSurplusManager(address _surplusManager) external onlyGovernor {\n if (_surplusManager == address(0)) revert ZeroAddress();\n surplusManager = _surplusManager;\n emit SurplusManagerUpdated(_surplusManager);\n }\n\n /// @notice Sets a new `core` contract\n /// @dev This function should typically be called on all treasury contracts after the `setCore`\n /// function has been called on the `CoreBorrow` contract\n /// @dev One sanity check that can be performed here is to verify whether at least the governor\n /// calling the contract is still a governor in the new core\n function setCore(ICoreBorrow _core) external onlyGovernor {\n if (!_core.isGovernor(msg.sender)) revert NotGovernor();\n core = ICoreBorrow(_core);\n emit CoreUpdated(address(_core));\n }\n\n /// @inheritdoc ITreasury\n function setFlashLoanModule(address _flashLoanModule) external {\n if (msg.sender != address(core)) revert NotCore();\n address oldFlashLoanModule = address(flashLoanModule);\n flashLoanModule = IFlashAngle(_flashLoanModule);\n if (oldFlashLoanModule != address(0)) {\n stablecoin.removeMinter(oldFlashLoanModule);\n }\n // We may want to cancel the module\n if (_flashLoanModule != address(0)) {\n stablecoin.addMinter(_flashLoanModule);\n }\n }\n}\n" + }, + "contracts/ui-helpers/AngleBorrowHelpers.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\n/*\n * █ \n ***** ▓▓▓ \n * ▓▓▓▓▓▓▓ \n * ///. ▓▓▓▓▓▓▓▓▓▓▓▓▓ \n ***** //////// ▓▓▓▓▓▓▓ \n * ///////////// ▓▓▓ \n ▓▓ ////////////////// █ ▓▓ \n ▓▓ ▓▓ /////////////////////// ▓▓ ▓▓ \n ▓▓ ▓▓ //////////////////////////// ▓▓ ▓▓ \n ▓▓ ▓▓ /////////▓▓▓///////▓▓▓///////// ▓▓ ▓▓ \n ▓▓ ,////////////////////////////////////// ▓▓ ▓▓ \n ▓▓ ////////////////////////////////////////// ▓▓ \n ▓▓ //////////////////////▓▓▓▓///////////////////// \n ,//////////////////////////////////////////////////// \n .////////////////////////////////////////////////////////// \n .//////////////////////////██.,//////////////////////////█ \n .//////////////////////████..,./////////////////////██ \n ...////////////////███████.....,.////////////////███ \n ,.,////////////████████ ........,///////////████ \n .,.,//////█████████ ,.......///////████ \n ,..//████████ ........./████ \n ..,██████ .....,███ \n .██ ,.,█ \n \n \n \n ▓▓ ▓▓▓▓▓▓▓▓▓▓ ▓▓▓▓▓▓▓▓▓▓ ▓▓ ▓▓▓▓▓▓▓▓▓▓ \n ▓▓▓▓▓▓ ▓▓▓ ▓▓▓ ▓▓▓ ▓▓ ▓▓ ▓▓▓▓ \n ▓▓▓ ▓▓▓ ▓▓▓ ▓▓▓ ▓▓▓ ▓▓▓ ▓▓ ▓▓▓▓▓ \n ▓▓▓ ▓▓ ▓▓▓ ▓▓▓ ▓▓▓▓▓▓▓▓▓▓ ▓▓▓▓▓▓▓▓▓▓ ▓▓▓▓▓▓▓▓▓▓ \n*/\n\nimport \"@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol\";\nimport \"../interfaces/IVaultManager.sol\";\n\npragma solidity ^0.8.12;\n\n/// @title AngleBorrowHelpers\n/// @author Angle Labs, Inc.\n/// @notice Contract with view functions designed to facilitate integrations on the Borrow module of the Angle Protocol\n/// @dev This contract only contains view functions to be queried off-chain. It was thus not optimized for gas consumption\ncontract AngleBorrowHelpers is Initializable {\n /// @notice Returns all the vaults owned or controlled (under the form of approval) by an address\n /// @param vaultManager VaultManager address to query vaultIDs on\n /// @param spender Address for which vault ownerships should be checked\n /// @return List of `vaultID` controlled by this address\n /// @return Count of vaults owned by the address\n /// @dev This function is never to be called on-chain since it iterates over all vaultIDs. It is here\n /// to reduce dependency on an external graph to link an ID to its owner\n function getControlledVaults(\n IVaultManager vaultManager,\n address spender\n ) external view returns (uint256[] memory, uint256) {\n uint256 arraySize = vaultManager.vaultIDCount();\n uint256[] memory vaultsControlled = new uint256[](arraySize);\n uint256 count;\n for (uint256 i = 1; i <= arraySize; ++i) {\n try vaultManager.isApprovedOrOwner(spender, i) returns (bool _isApprovedOrOwner) {\n if (_isApprovedOrOwner) {\n vaultsControlled[count] = i;\n count += 1;\n }\n } catch {\n continue;\n } // This happens if nobody owns the vaultID=i (if there has been a burn)\n }\n return (vaultsControlled, count);\n }\n\n /// @custom:oz-upgrades-unsafe-allow constructor\n constructor() initializer {}\n}\n" + }, + "contracts/ui-helpers/AngleHelpers.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\nimport \"../interfaces/IAngleRouter.sol\";\nimport \"../interfaces/coreModule/IAgTokenMainnet.sol\";\nimport \"../interfaces/coreModule/ICore.sol\";\nimport \"../interfaces/coreModule/IOracleCore.sol\";\nimport \"../interfaces/coreModule/IPerpetualManager.sol\";\nimport \"../interfaces/coreModule/IPoolManager.sol\";\nimport \"../interfaces/coreModule/IStableMaster.sol\";\nimport \"./AngleBorrowHelpers.sol\";\n\npragma solidity ^0.8.12;\n\nstruct Parameters {\n SLPData slpData;\n MintBurnData feeData;\n PerpetualManagerFeeData perpFeeData;\n PerpetualManagerParamData perpParam;\n}\n\nstruct PerpetualManagerFeeData {\n uint64[] xHAFeesDeposit;\n uint64[] yHAFeesDeposit;\n uint64[] xHAFeesWithdraw;\n uint64[] yHAFeesWithdraw;\n uint64 haBonusMalusDeposit;\n uint64 haBonusMalusWithdraw;\n}\n\nstruct PerpetualManagerParamData {\n uint64 maintenanceMargin;\n uint64 maxLeverage;\n uint64 targetHAHedge;\n uint64 limitHAHedge;\n uint64 lockTime;\n}\n\nstruct CollateralAddresses {\n address stableMaster;\n address poolManager;\n address perpetualManager;\n address sanToken;\n address oracle;\n address gauge;\n address feeManager;\n address[] strategies;\n}\n\n/// @title AngleHelpers\n/// @author Angle Labs, Inc.\n/// @notice Contract with view functions designed to facilitate integrations on the Core and Borrow module of the Angle Protocol\n/// @dev This contract only contains view functions to be queried off-chain. It was thus not optimized for gas consumption\ncontract AngleHelpers is AngleBorrowHelpers {\n // =========================== HELPER VIEW FUNCTIONS ===========================\n\n /// @notice Gives the amount of `agToken` you'd be getting if you were executing in the same block a mint transaction\n /// with `amount` of `collateral` in the Core module of the Angle protocol as well as the value of the fees\n /// (in `BASE_PARAMS`) that would be applied during the mint\n /// @return Amount of `agToken` that would be obtained with a mint transaction in the same block\n /// @return Percentage of fees that would be taken during a mint transaction in the same block\n /// @dev This function reverts if the mint transaction was to revert in the same conditions (without taking into account\n /// potential approval problems to the `StableMaster` contract)\n function previewMintAndFees(\n uint256 amount,\n address agToken,\n address collateral\n ) external view returns (uint256, uint256) {\n return _previewMintAndFees(amount, agToken, collateral);\n }\n\n /// @notice Gives the amount of `collateral` you'd be getting if you were executing in the same block a burn transaction\n /// with `amount` of `agToken` in the Core module of the Angle protocol as well as the value of the fees\n /// (in `BASE_PARAMS`) that would be applied during the burn\n /// @return Amount of `collateral` that would be obtained with a burn transaction in the same block\n /// @return Percentage of fees that would be taken during a burn transaction in the same block\n /// @dev This function reverts if the burn transaction was to revert in the same conditions (without taking into account\n /// potential approval problems to the `StableMaster` contract or agToken balance prior to the call)\n function previewBurnAndFees(\n uint256 amount,\n address agToken,\n address collateral\n ) external view returns (uint256, uint256) {\n return _previewBurnAndFees(amount, agToken, collateral);\n }\n\n /// @notice Returns all the addresses associated to the (`agToken`,`collateral`) pair given\n /// @return addresses A struct with all the addresses associated in the Core module\n function getCollateralAddresses(\n address agToken,\n address collateral\n ) external view returns (CollateralAddresses memory addresses) {\n address stableMaster = IAgTokenMainnet(agToken).stableMaster();\n (address poolManager, address perpetualManager, address sanToken, address gauge) = ROUTER.mapPoolManagers(\n stableMaster,\n collateral\n );\n (, , , IOracleCore oracle, , , , , ) = IStableMaster(stableMaster).collateralMap(poolManager);\n addresses.stableMaster = stableMaster;\n addresses.poolManager = poolManager;\n addresses.perpetualManager = perpetualManager;\n addresses.sanToken = sanToken;\n addresses.gauge = gauge;\n addresses.oracle = address(oracle);\n addresses.feeManager = IPoolManager(poolManager).feeManager();\n\n uint256 length;\n while (true) {\n try IPoolManager(poolManager).strategyList(length) returns (address) {\n length += 1;\n } catch {\n break;\n }\n }\n address[] memory strategies = new address[](length);\n for (uint256 i; i < length; ++i) {\n strategies[i] = IPoolManager(poolManager).strategyList(i);\n }\n addresses.strategies = strategies;\n }\n\n /// @notice Gets the addresses of all the `StableMaster` contracts and their associated `AgToken` addresses\n /// @return List of the `StableMaster` addresses of the Angle protocol\n /// @return List of the `AgToken` addresses of the protocol\n /// @dev The place of an agToken address in the list is the same as the corresponding `StableMaster` address\n function getStablecoinAddresses() external view returns (address[] memory, address[] memory) {\n address[] memory stableMasterAddresses = CORE.stablecoinList();\n address[] memory agTokenAddresses = new address[](stableMasterAddresses.length);\n for (uint256 i; i < stableMasterAddresses.length; ++i) {\n agTokenAddresses[i] = IStableMaster(stableMasterAddresses[i]).agToken();\n }\n return (stableMasterAddresses, agTokenAddresses);\n }\n\n /// @notice Returns most of the governance parameters associated to the (`agToken`,`collateral`) pair given\n /// @return params Struct with most of the parameters in the `StableMaster` and `PerpetualManager` contracts\n /// @dev Check out the struct `Parameters` for the meaning of the return values\n function getCollateralParameters(\n address agToken,\n address collateral\n ) external view returns (Parameters memory params) {\n (address stableMaster, address poolManager) = _getStableMasterAndPoolManager(agToken, collateral);\n (\n ,\n ,\n IPerpetualManager perpetualManager,\n ,\n ,\n ,\n ,\n SLPData memory slpData,\n MintBurnData memory feeData\n ) = IStableMaster(stableMaster).collateralMap(poolManager);\n\n params.slpData = slpData;\n params.feeData = feeData;\n params.perpParam.maintenanceMargin = perpetualManager.maintenanceMargin();\n params.perpParam.maxLeverage = perpetualManager.maxLeverage();\n params.perpParam.targetHAHedge = perpetualManager.targetHAHedge();\n params.perpParam.limitHAHedge = perpetualManager.limitHAHedge();\n params.perpParam.lockTime = perpetualManager.lockTime();\n\n params.perpFeeData.haBonusMalusDeposit = perpetualManager.haBonusMalusDeposit();\n params.perpFeeData.haBonusMalusWithdraw = perpetualManager.haBonusMalusWithdraw();\n\n uint256 length;\n while (true) {\n try perpetualManager.xHAFeesDeposit(length) returns (uint64) {\n length += 1;\n } catch {\n break;\n }\n }\n uint64[] memory data = new uint64[](length);\n uint64[] memory data2 = new uint64[](length);\n for (uint256 i; i < length; ++i) {\n data[i] = perpetualManager.xHAFeesDeposit(i);\n data2[i] = perpetualManager.yHAFeesDeposit(i);\n }\n params.perpFeeData.xHAFeesDeposit = data;\n params.perpFeeData.yHAFeesDeposit = data2;\n\n length = 0;\n while (true) {\n try perpetualManager.xHAFeesWithdraw(length) returns (uint64) {\n length += 1;\n } catch {\n break;\n }\n }\n data = new uint64[](length);\n data2 = new uint64[](length);\n for (uint256 i; i < length; ++i) {\n data[i] = perpetualManager.xHAFeesWithdraw(i);\n data2[i] = perpetualManager.yHAFeesWithdraw(i);\n }\n params.perpFeeData.xHAFeesWithdraw = data;\n params.perpFeeData.yHAFeesWithdraw = data2;\n }\n\n /// @notice Returns the address of the poolManager associated to an (`agToken`, `collateral`) pair\n /// in the Core module of the protocol\n function getPoolManager(address agToken, address collateral) public view returns (address poolManager) {\n (, poolManager) = _getStableMasterAndPoolManager(agToken, collateral);\n }\n\n // ============================= REPLICA FUNCTIONS =============================\n // These replicate what is done in the other contracts of the protocol\n\n function _previewBurnAndFees(\n uint256 amount,\n address agToken,\n address collateral\n ) internal view returns (uint256 amountForUserInCollat, uint256 feePercent) {\n (address stableMaster, address poolManager) = _getStableMasterAndPoolManager(agToken, collateral);\n (\n address token,\n ,\n IPerpetualManager perpetualManager,\n IOracleCore oracle,\n uint256 stocksUsers,\n ,\n uint256 collatBase,\n ,\n MintBurnData memory feeData\n ) = IStableMaster(stableMaster).collateralMap(poolManager);\n if (token == address(0) || IStableMaster(stableMaster).paused(keccak256(abi.encodePacked(STABLE, poolManager))))\n revert NotInitialized();\n if (amount > stocksUsers) revert InvalidAmount();\n\n if (feeData.xFeeBurn.length == 1) {\n feePercent = feeData.yFeeBurn[0];\n } else {\n bytes memory data = abi.encode(address(perpetualManager), feeData.targetHAHedge);\n uint64 hedgeRatio = _computeHedgeRatio(stocksUsers - amount, data);\n feePercent = _piecewiseLinear(hedgeRatio, feeData.xFeeBurn, feeData.yFeeBurn);\n }\n feePercent = (feePercent * feeData.bonusMalusBurn) / BASE_PARAMS;\n\n amountForUserInCollat = (amount * (BASE_PARAMS - feePercent) * collatBase) / (oracle.readUpper() * BASE_PARAMS);\n }\n\n function _previewMintAndFees(\n uint256 amount,\n address agToken,\n address collateral\n ) internal view returns (uint256 amountForUserInStable, uint256 feePercent) {\n (address stableMaster, address poolManager) = _getStableMasterAndPoolManager(agToken, collateral);\n (\n address token,\n ,\n IPerpetualManager perpetualManager,\n IOracleCore oracle,\n uint256 stocksUsers,\n ,\n ,\n ,\n MintBurnData memory feeData\n ) = IStableMaster(stableMaster).collateralMap(poolManager);\n if (token == address(0) || IStableMaster(stableMaster).paused(keccak256(abi.encodePacked(STABLE, poolManager))))\n revert NotInitialized();\n\n amountForUserInStable = oracle.readQuoteLower(amount);\n\n if (feeData.xFeeMint.length == 1) feePercent = feeData.yFeeMint[0];\n else {\n bytes memory data = abi.encode(address(perpetualManager), feeData.targetHAHedge);\n uint64 hedgeRatio = _computeHedgeRatio(amountForUserInStable + stocksUsers, data);\n feePercent = _piecewiseLinear(hedgeRatio, feeData.xFeeMint, feeData.yFeeMint);\n }\n feePercent = (feePercent * feeData.bonusMalusMint) / BASE_PARAMS;\n\n amountForUserInStable = (amountForUserInStable * (BASE_PARAMS - feePercent)) / BASE_PARAMS;\n if (stocksUsers + amountForUserInStable > feeData.capOnStableMinted) revert InvalidAmount();\n }\n\n // ============================= UTILITY FUNCTIONS =============================\n // These utility functions are taken from other contracts of the protocol\n\n function _computeHedgeRatio(uint256 newStocksUsers, bytes memory data) internal view returns (uint64 ratio) {\n (address perpetualManager, uint64 targetHAHedge) = abi.decode(data, (address, uint64));\n uint256 totalHedgeAmount = IPerpetualManager(perpetualManager).totalHedgeAmount();\n newStocksUsers = (targetHAHedge * newStocksUsers) / BASE_PARAMS;\n if (newStocksUsers > totalHedgeAmount) ratio = uint64((totalHedgeAmount * BASE_PARAMS) / newStocksUsers);\n else ratio = uint64(BASE_PARAMS);\n }\n\n function _piecewiseLinear(uint64 x, uint64[] memory xArray, uint64[] memory yArray) internal pure returns (uint64) {\n if (x >= xArray[xArray.length - 1]) {\n return yArray[xArray.length - 1];\n } else if (x <= xArray[0]) {\n return yArray[0];\n } else {\n uint256 lower;\n uint256 upper = xArray.length - 1;\n uint256 mid;\n while (upper - lower > 1) {\n mid = lower + (upper - lower) / 2;\n if (xArray[mid] <= x) {\n lower = mid;\n } else {\n upper = mid;\n }\n }\n if (yArray[upper] > yArray[lower]) {\n return\n yArray[lower] +\n ((yArray[upper] - yArray[lower]) * (x - xArray[lower])) /\n (xArray[upper] - xArray[lower]);\n } else {\n return\n yArray[lower] -\n ((yArray[lower] - yArray[upper]) * (x - xArray[lower])) /\n (xArray[upper] - xArray[lower]);\n }\n }\n }\n\n function _getStableMasterAndPoolManager(\n address agToken,\n address collateral\n ) internal view returns (address stableMaster, address poolManager) {\n stableMaster = IAgTokenMainnet(agToken).stableMaster();\n (poolManager, , , ) = ROUTER.mapPoolManagers(stableMaster, collateral);\n }\n\n // ========================= CONSTANTS AND INITIALIZERS ========================\n\n IAngleRouter public constant ROUTER = IAngleRouter(0xBB755240596530be0c1DE5DFD77ec6398471561d);\n ICore public constant CORE = ICore(0x61ed74de9Ca5796cF2F8fD60D54160D47E30B7c3);\n\n bytes32 public constant STABLE = keccak256(\"STABLE\");\n uint256 public constant BASE_PARAMS = 10 ** 9;\n\n error NotInitialized();\n error InvalidAmount();\n}\n" + }, + "contracts/utils/Constants.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\nerror InsufficientAssets();\n\n/// @title Constants\n/// @author Angle Labs, Inc.\n/// @notice Constants and errors for Angle Protocol contracts\ncontract Constants {\n uint256 internal constant _BASE_9 = 1e9;\n uint256 internal constant _BASE_18 = 1e18;\n uint256 internal constant _BASE_27 = 1e27;\n uint256 internal constant _BASE_36 = 1e36;\n}\n" + }, + "contracts/vaultManager/VaultManagerERC721.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\nimport \"./VaultManagerStorage.sol\";\n\n/// @title VaultManagerERC721\n/// @author Angle Labs, Inc.\n/// @dev Base ERC721 Implementation of VaultManager\nabstract contract VaultManagerERC721 is IERC721MetadataUpgradeable, VaultManagerStorage {\n using SafeERC20 for IERC20;\n using Address for address;\n\n /// @inheritdoc IERC721MetadataUpgradeable\n string public name;\n /// @inheritdoc IERC721MetadataUpgradeable\n string public symbol;\n\n // ================================= MODIFIERS =================================\n\n /// @notice Checks if the person interacting with the vault with `vaultID` is approved\n /// @param caller Address of the person seeking to interact with the vault\n /// @param vaultID ID of the concerned vault\n modifier onlyApprovedOrOwner(address caller, uint256 vaultID) {\n if (!_isApprovedOrOwner(caller, vaultID)) revert NotApproved();\n _;\n }\n\n // ================================ ERC721 LOGIC ===============================\n\n /// @notice Checks whether a given address is approved for a vault or owns this vault\n /// @param spender Address for which vault ownership should be checked\n /// @param vaultID ID of the vault to check\n /// @return Whether the `spender` address owns or is approved for `vaultID`\n function isApprovedOrOwner(address spender, uint256 vaultID) external view returns (bool) {\n return _isApprovedOrOwner(spender, vaultID);\n }\n\n /// @inheritdoc IERC721MetadataUpgradeable\n function tokenURI(uint256 vaultID) external view returns (string memory) {\n if (!_exists(vaultID)) revert NonexistentVault();\n // There is no vault with `vaultID` equal to 0, so the following variable is\n // always greater than zero\n uint256 temp = vaultID;\n uint256 digits;\n while (temp != 0) {\n ++digits;\n temp /= 10;\n }\n bytes memory buffer = new bytes(digits);\n while (vaultID != 0) {\n digits -= 1;\n buffer[digits] = bytes1(uint8(48 + uint256(vaultID % 10)));\n vaultID /= 10;\n }\n return bytes(_baseURI).length != 0 ? string(abi.encodePacked(_baseURI, string(buffer))) : \"\";\n }\n\n /// @inheritdoc IERC721Upgradeable\n function balanceOf(address owner) external view returns (uint256) {\n if (owner == address(0)) revert ZeroAddress();\n return _balances[owner];\n }\n\n /// @inheritdoc IERC721Upgradeable\n function ownerOf(uint256 vaultID) external view returns (address) {\n return _ownerOf(vaultID);\n }\n\n /// @inheritdoc IERC721Upgradeable\n function approve(address to, uint256 vaultID) external {\n address owner = _ownerOf(vaultID);\n if (to == owner) revert ApprovalToOwner();\n if (msg.sender != owner && !isApprovedForAll(owner, msg.sender)) revert NotApproved();\n\n _approve(to, vaultID);\n }\n\n /// @inheritdoc IERC721Upgradeable\n function getApproved(uint256 vaultID) external view returns (address) {\n if (!_exists(vaultID)) revert NonexistentVault();\n return _getApproved(vaultID);\n }\n\n /// @inheritdoc IERC721Upgradeable\n function setApprovalForAll(address operator, bool approved) external {\n _setApprovalForAll(msg.sender, operator, approved);\n }\n\n /// @inheritdoc IERC721Upgradeable\n function isApprovedForAll(address owner, address operator) public view returns (bool) {\n return _operatorApprovals[owner][operator] == 1;\n }\n\n /// @inheritdoc IERC721Upgradeable\n function transferFrom(address from, address to, uint256 vaultID) external onlyApprovedOrOwner(msg.sender, vaultID) {\n _transfer(from, to, vaultID);\n }\n\n /// @inheritdoc IERC721Upgradeable\n function safeTransferFrom(address from, address to, uint256 vaultID) external {\n safeTransferFrom(from, to, vaultID, \"\");\n }\n\n /// @inheritdoc IERC721Upgradeable\n function safeTransferFrom(\n address from,\n address to,\n uint256 vaultID,\n bytes memory _data\n ) public onlyApprovedOrOwner(msg.sender, vaultID) {\n _safeTransfer(from, to, vaultID, _data);\n }\n\n // ================================ ERC165 LOGIC ===============================\n\n /// @inheritdoc IERC165Upgradeable\n function supportsInterface(bytes4 interfaceId) external pure returns (bool) {\n return\n interfaceId == type(IERC721MetadataUpgradeable).interfaceId ||\n interfaceId == type(IERC721Upgradeable).interfaceId ||\n interfaceId == type(IVaultManager).interfaceId ||\n interfaceId == type(IERC165Upgradeable).interfaceId;\n }\n\n // ================== INTERNAL FUNCTIONS FOR THE ERC721 LOGIC ==================\n\n /// @notice Internal version of the `ownerOf` function\n function _ownerOf(uint256 vaultID) internal view returns (address owner) {\n owner = _owners[vaultID];\n if (owner == address(0)) revert NonexistentVault();\n }\n\n /// @notice Internal version of the `getApproved` function\n function _getApproved(uint256 vaultID) internal view returns (address) {\n return _vaultApprovals[vaultID];\n }\n\n /// @notice Internal version of the `safeTransferFrom` function (with the data parameter)\n function _safeTransfer(address from, address to, uint256 vaultID, bytes memory _data) internal {\n _transfer(from, to, vaultID);\n if (!_checkOnERC721Received(from, to, vaultID, _data)) revert NonERC721Receiver();\n }\n\n /// @notice Checks whether a vault exists\n /// @param vaultID ID of the vault to check\n /// @return Whether `vaultID` has been created\n function _exists(uint256 vaultID) internal view returns (bool) {\n return _owners[vaultID] != address(0);\n }\n\n /// @notice Internal version of the `isApprovedOrOwner` function\n function _isApprovedOrOwner(address spender, uint256 vaultID) internal view returns (bool) {\n // The following checks if the vault exists\n address owner = _ownerOf(vaultID);\n return (spender == owner || _getApproved(vaultID) == spender || _operatorApprovals[owner][spender] == 1);\n }\n\n /// @notice Internal version of the `createVault` function\n /// Mints `vaultID` and transfers it to `to`\n /// @dev This method is equivalent to the `_safeMint` method used in OpenZeppelin ERC721 contract\n /// @dev Emits a {Transfer} event\n function _mint(address to) internal returns (uint256 vaultID) {\n if (to == address(0)) revert ZeroAddress();\n\n unchecked {\n vaultIDCount += 1;\n }\n\n vaultID = vaultIDCount;\n _beforeTokenTransfer(address(0), to, vaultID);\n\n unchecked {\n _balances[to] += 1;\n }\n\n _owners[vaultID] = to;\n emit Transfer(address(0), to, vaultID);\n if (!_checkOnERC721Received(address(0), to, vaultID, \"\")) revert NonERC721Receiver();\n }\n\n /// @notice Destroys `vaultID`\n /// @dev `vaultID` must exist\n /// @dev Emits a {Transfer} event\n function _burn(uint256 vaultID) internal {\n address owner = _ownerOf(vaultID);\n\n _beforeTokenTransfer(owner, address(0), vaultID);\n // Clear approvals\n _approve(address(0), vaultID);\n // The following line cannot underflow as the owner's balance is necessarily\n // greater than 1\n unchecked {\n _balances[owner] -= 1;\n }\n delete _owners[vaultID];\n delete vaultData[vaultID];\n\n emit Transfer(owner, address(0), vaultID);\n }\n\n /// @notice Transfers `vaultID` from `from` to `to` as opposed to {transferFrom},\n /// this imposes no restrictions on msg.sender\n /// @dev `to` cannot be the zero address and `perpetualID` must be owned by `from`\n /// @dev Emits a {Transfer} event\n function _transfer(address from, address to, uint256 vaultID) internal {\n if (_ownerOf(vaultID) != from) revert NotApproved();\n if (to == address(0)) revert ZeroAddress();\n\n _beforeTokenTransfer(from, to, vaultID);\n\n // Clear approvals from the previous owner\n _approve(address(0), vaultID);\n unchecked {\n _balances[from] -= 1;\n _balances[to] += 1;\n }\n _owners[vaultID] = to;\n\n emit Transfer(from, to, vaultID);\n }\n\n /// @notice Approves `to` to operate on `vaultID`\n function _approve(address to, uint256 vaultID) internal {\n _vaultApprovals[vaultID] = to;\n emit Approval(_ownerOf(vaultID), to, vaultID);\n }\n\n /// @notice Internal version of the `setApprovalForAll` function\n /// @dev It contains an `approver` field to be used in case someone signs a permit for a particular\n /// address, and this signature is given to the contract by another address (like a router)\n function _setApprovalForAll(address approver, address operator, bool approved) internal {\n if (operator == approver) revert ApprovalToCaller();\n uint256 approval = approved ? 1 : 0;\n _operatorApprovals[approver][operator] = approval;\n emit ApprovalForAll(approver, operator, approved);\n }\n\n /// @notice Internal function to invoke {IERC721Receiver-onERC721Received} on a target address\n /// The call is not executed if the target address is not a contract\n /// @param from Address representing the previous owner of the given token ID\n /// @param to Target address that will receive the tokens\n /// @param vaultID ID of the token to be transferred\n /// @param _data Bytes optional data to send along with the call\n /// @return Bool whether the call correctly returned the expected value\n function _checkOnERC721Received(\n address from,\n address to,\n uint256 vaultID,\n bytes memory _data\n ) private returns (bool) {\n if (to.isContract()) {\n try IERC721ReceiverUpgradeable(to).onERC721Received(msg.sender, from, vaultID, _data) returns (\n bytes4 retval\n ) {\n return retval == IERC721ReceiverUpgradeable.onERC721Received.selector;\n } catch (bytes memory reason) {\n if (reason.length == 0) {\n revert NonERC721Receiver();\n } else {\n // solhint-disable-next-line no-inline-assembly\n assembly {\n revert(add(32, reason), mload(reason))\n }\n }\n }\n } else {\n return true;\n }\n }\n\n /// @notice Hook that is called before any token transfer. This includes minting and burning.\n /// Calling conditions:\n ///\n /// - When `from` and `to` are both non-zero, `from`'s `vaultID` will be\n /// transferred to `to`.\n /// - When `from` is zero, `vaultID` will be minted for `to`.\n /// - When `to` is zero, `from`'s `vaultID` will be burned.\n /// - `from` and `to` are never both zero.\n function _beforeTokenTransfer(address from, address to, uint256 vaultID) internal virtual {}\n\n /// @notice Get `whitelistingActivated` in storage only if needed\n function _whitelistingActivated() internal view virtual returns (bool) {\n return whitelistingActivated;\n }\n}\n" + }, + "contracts/vaultManager/VaultManagerPermit.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\nimport \"./VaultManagerERC721.sol\";\nimport \"../interfaces/external/IERC1271.sol\";\n\n/// @title VaultManagerPermit\n/// @author Angle Labs, Inc.\n/// @dev Base Implementation of permit functions for the `VaultManager` contract\nabstract contract VaultManagerPermit is Initializable, VaultManagerERC721 {\n using Address for address;\n\n mapping(address => uint256) private _nonces;\n /* solhint-disable var-name-mixedcase */\n bytes32 private _HASHED_NAME;\n bytes32 private _HASHED_VERSION;\n bytes32 private _PERMIT_TYPEHASH;\n /* solhint-enable var-name-mixedcase */\n\n error ExpiredDeadline();\n error InvalidSignature();\n\n //solhint-disable-next-line\n function __ERC721Permit_init(string memory _name) internal onlyInitializing {\n _PERMIT_TYPEHASH = keccak256(\n \"Permit(address owner,address spender,bool approved,uint256 nonce,uint256 deadline)\"\n );\n _HASHED_NAME = keccak256(bytes(_name));\n _HASHED_VERSION = keccak256(bytes(\"1\"));\n }\n\n /// @notice Allows an address to give or revoke approval for all its vaults to another address\n /// @param owner Address signing the permit and giving (or revoking) its approval for all the controlled vaults\n /// @param spender Address to give approval to\n /// @param approved Whether to give or revoke the approval\n /// @param deadline Deadline parameter for the signature to be valid\n /// @dev The `v`, `r`, and `s` parameters are used as signature data\n function permit(\n address owner,\n address spender,\n bool approved,\n uint256 deadline,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) external {\n if (block.timestamp > deadline) revert ExpiredDeadline();\n // Additional signature checks performed in the `ECDSAUpgradeable.recover` function\n if (uint256(s) > 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D576E7357A4501DDFE92F46681B20A0 || (v != 27 && v != 28))\n revert InvalidSignature();\n\n bytes32 digest = keccak256(\n abi.encodePacked(\n \"\\x19\\x01\",\n _domainSeparatorV4(),\n keccak256(\n abi.encode(\n _PERMIT_TYPEHASH,\n // 0x3f43a9c6bafb5c7aab4e0cfe239dc5d4c15caf0381c6104188191f78a6640bd8,\n owner,\n spender,\n approved,\n _useNonce(owner),\n deadline\n )\n )\n )\n );\n if (owner.isContract()) {\n if (IERC1271(owner).isValidSignature(digest, abi.encodePacked(r, s, v)) != 0x1626ba7e)\n revert InvalidSignature();\n } else {\n address signer = ecrecover(digest, v, r, s);\n if (signer != owner || signer == address(0)) revert InvalidSignature();\n }\n\n _setApprovalForAll(owner, spender, approved);\n }\n\n /// @notice Returns the current nonce for an `owner` address\n function nonces(address owner) public view returns (uint256) {\n return _nonces[owner];\n }\n\n /// @notice Returns the domain separator for the current chain.\n // solhint-disable-next-line func-name-mixedcase\n function DOMAIN_SEPARATOR() external view returns (bytes32) {\n return _domainSeparatorV4();\n }\n\n /// @notice Internal version of the `DOMAIN_SEPARATOR` function\n function _domainSeparatorV4() internal view returns (bytes32) {\n return\n keccak256(\n abi.encode(\n // keccak256('EIP712Domain(string name,string version,uint256 chainId,address verifyingContract)')\n 0x8b73c3c69bb8fe3d512ecc4cf759cc79239f7b179b0ffacaa9a75d522b39400f,\n _HASHED_NAME,\n _HASHED_VERSION,\n block.chainid,\n address(this)\n )\n );\n }\n\n /// @notice Consumes a nonce for an address: returns the current value and increments it\n function _useNonce(address owner) internal returns (uint256 current) {\n current = _nonces[owner];\n _nonces[owner] = current + 1;\n }\n\n uint256[49] private __gap;\n}\n" + }, + "contracts/vaultManager/VaultManagerStorage.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\nimport \"@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/token/ERC20/extensions/draft-IERC20PermitUpgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/token/ERC721/IERC721ReceiverUpgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/interfaces/IERC721MetadataUpgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/utils/introspection/IERC165Upgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/utils/AddressUpgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/security/ReentrancyGuardUpgradeable.sol\";\nimport \"@openzeppelin/contracts/token/ERC20/extensions/IERC20Metadata.sol\";\nimport \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\nimport \"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\";\n\nimport \"../interfaces/IAgToken.sol\";\nimport \"../interfaces/IOracle.sol\";\nimport \"../interfaces/ISwapper.sol\";\nimport \"../interfaces/ITreasury.sol\";\nimport \"../interfaces/IVaultManager.sol\";\nimport \"../interfaces/governance/IVeBoostProxy.sol\";\n\n/// @title VaultManagerStorage\n/// @author Angle Labs, Inc.\n/// @dev Variables, references, parameters and events needed in the `VaultManager` contract\n// solhint-disable-next-line max-states-count\ncontract VaultManagerStorage is IVaultManagerStorage, Initializable, ReentrancyGuardUpgradeable {\n /// @notice Base used for parameter computation: almost all the parameters of this contract are set in `BASE_PARAMS`\n uint256 public constant BASE_PARAMS = 10 ** 9;\n /// @notice Base used for interest rate computation\n uint256 public constant BASE_INTEREST = 10 ** 27;\n /// @notice Used for interest rate computation\n uint256 public constant HALF_BASE_INTEREST = 10 ** 27 / 2;\n\n // ================================= REFERENCES ================================\n\n /// @inheritdoc IVaultManagerStorage\n ITreasury public treasury;\n /// @inheritdoc IVaultManagerStorage\n IERC20 public collateral;\n /// @inheritdoc IVaultManagerStorage\n IAgToken public stablecoin;\n /// @inheritdoc IVaultManagerStorage\n IOracle public oracle;\n /// @notice Reference to the contract which computes adjusted veANGLE balances for liquidators boosts\n IVeBoostProxy public veBoostProxy;\n /// @notice Base of the collateral\n uint256 internal _collatBase;\n\n // ================================= PARAMETERS ================================\n // Unless specified otherwise, parameters of this contract are expressed in `BASE_PARAMS`\n\n /// @notice Maximum amount of stablecoins that can be issued with this contract (in `BASE_TOKENS`). This parameter should\n /// not be bigger than `type(uint256).max / BASE_INTEREST` otherwise there may be some overflows in the `increaseDebt` function\n uint256 public debtCeiling;\n /// @notice Threshold veANGLE balance values for the computation of the boost for liquidators: the length of this array\n /// should normally be 2. The base of the x-values in this array should be `BASE_TOKENS`\n uint256[] public xLiquidationBoost;\n /// @notice Values of the liquidation boost at the threshold values of x\n uint256[] public yLiquidationBoost;\n /// @inheritdoc IVaultManagerStorage\n uint64 public collateralFactor;\n /// @notice Maximum Health factor at which a vault can end up after a liquidation (unless it's fully liquidated)\n uint64 public targetHealthFactor;\n /// @notice Upfront fee taken when borrowing stablecoins: this fee is optional and should in practice not be used\n uint64 public borrowFee;\n /// @notice Upfront fee taken when repaying stablecoins: this fee is optional as well. It should be smaller\n /// than the liquidation surcharge (cf below) to avoid exploits where people voluntarily get liquidated at a 0\n /// discount to pay smaller repaying fees\n uint64 public repayFee;\n /// @notice Per second interest taken to borrowers taking agToken loans. Contrarily to other parameters, it is set in `BASE_INTEREST`\n /// that is to say in base 10**27\n uint64 public interestRate;\n /// @notice Fee taken by the protocol during a liquidation. Technically, this value is not the fee per se, it's 1 - fee.\n /// For instance for a 2% fee, `liquidationSurcharge` should be 98%\n uint64 public liquidationSurcharge;\n /// @notice Maximum discount given to liquidators\n uint64 public maxLiquidationDiscount;\n /// @notice Whether whitelisting is required to own a vault or not\n bool public whitelistingActivated;\n /// @notice Whether the contract is paused or not\n bool public paused;\n\n // ================================= VARIABLES =================================\n\n /// @notice Timestamp at which the `interestAccumulator` was updated\n uint256 public lastInterestAccumulatorUpdated;\n /// @inheritdoc IVaultManagerStorage\n uint256 public interestAccumulator;\n /// @inheritdoc IVaultManagerStorage\n uint256 public totalNormalizedDebt;\n /// @notice Surplus accumulated by the contract: surplus is always in stablecoins, and is then reset\n /// when the value is communicated to the treasury contract\n uint256 public surplus;\n /// @notice Bad debt made from liquidated vaults which ended up having no collateral and a positive amount\n /// of stablecoins\n uint256 public badDebt;\n\n // ================================== MAPPINGS =================================\n\n /// @inheritdoc IVaultManagerStorage\n mapping(uint256 => Vault) public vaultData;\n /// @notice Maps an address to 1 if it's whitelisted and can open or own a vault\n mapping(address => uint256) public isWhitelisted;\n\n // ================================ ERC721 DATA ================================\n\n /// @inheritdoc IVaultManagerStorage\n uint256 public vaultIDCount;\n\n /// @notice URI\n string internal _baseURI;\n\n // Mapping from `vaultID` to owner address\n mapping(uint256 => address) internal _owners;\n\n // Mapping from owner address to vault owned count\n mapping(address => uint256) internal _balances;\n\n // Mapping from `vaultID` to approved address\n mapping(uint256 => address) internal _vaultApprovals;\n\n // Mapping from owner to operator approvals\n mapping(address => mapping(address => uint256)) internal _operatorApprovals;\n\n uint256[50] private __gap;\n\n // =================================== EVENTS ==================================\n\n event AccruedToTreasury(uint256 surplusEndValue, uint256 badDebtEndValue);\n event CollateralAmountUpdated(uint256 vaultID, uint256 collateralAmount, uint8 isIncrease);\n event InterestAccumulatorUpdated(uint256 value, uint256 timestamp);\n event InternalDebtUpdated(uint256 vaultID, uint256 internalAmount, uint8 isIncrease);\n event FiledUint64(uint64 param, bytes32 what);\n event DebtCeilingUpdated(uint256 debtCeiling);\n event LiquidationBoostParametersUpdated(address indexed _veBoostProxy, uint256[] xBoost, uint256[] yBoost);\n event LiquidatedVaults(uint256[] vaultIDs);\n event DebtTransferred(uint256 srcVaultID, uint256 dstVaultID, address dstVaultManager, uint256 amount);\n\n // =================================== ERRORS ==================================\n\n error ApprovalToOwner();\n error ApprovalToCaller();\n error DustyLeftoverAmount();\n error DebtCeilingExceeded();\n error HealthyVault();\n error IncompatibleLengths();\n error InsolventVault();\n error InvalidParameterValue();\n error InvalidParameterType();\n error InvalidSetOfParameters();\n error InvalidTreasury();\n error NonERC721Receiver();\n error NonexistentVault();\n error NotApproved();\n error NotGovernor();\n error NotGovernorOrGuardian();\n error NotTreasury();\n error NotWhitelisted();\n error NotVaultManager();\n error Paused();\n error TooHighParameterValue();\n error TooSmallParameterValue();\n error ZeroAddress();\n\n /// @custom:oz-upgrades-unsafe-allow constructor\n constructor() initializer {}\n}\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 1000000 + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers", + "metadata", + "devdoc", + "userdoc", + "storageLayout", + "evm.gasEstimates", + "devdoc", + "userdoc" + ], + "": [ + "ast" + ] + } + }, + "metadata": { + "useLiteralContent": true + } + } +} \ No newline at end of file diff --git a/deployments/optimism/AgTokenSideChainMultiBridge_Implementation.json b/deployments/optimism/AgTokenSideChainMultiBridge_Implementation.json index b0f5413c..6e5bf215 100644 --- a/deployments/optimism/AgTokenSideChainMultiBridge_Implementation.json +++ b/deployments/optimism/AgTokenSideChainMultiBridge_Implementation.json @@ -1,5 +1,5 @@ { - "address": "0x9C215206Da4bf108aE5aEEf9dA7caD3352A36Dad", + "address": "0xd278d822a040457324043619E962a5b093Ba1d4e", "abi": [ { "inputs": [], @@ -249,6 +249,19 @@ "name": "HourlyLimitUpdated", "type": "event" }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint8", + "name": "version", + "type": "uint8" + } + ], + "name": "Initialized", + "type": "event" + }, { "anonymous": false, "inputs": [ @@ -1111,7 +1124,7 @@ "inputs": [ { "internalType": "address", - "name": "recipient", + "name": "to", "type": "address" }, { @@ -1135,12 +1148,12 @@ "inputs": [ { "internalType": "address", - "name": "sender", + "name": "from", "type": "address" }, { "internalType": "address", - "name": "recipient", + "name": "to", "type": "address" }, { @@ -1198,30 +1211,44 @@ "type": "function" } ], - "transactionHash": "0x4093bd1af046029ae2fb62c1241cc6c893c4091ea698e0cc1ec2a23419b6fb58", + "transactionHash": "0x31a09aa0a5eb62d815ca799997e4b342c91838df6b746bf0af43e700ad866496", "receipt": { "to": null, "from": "0xfdA462548Ce04282f4B6D6619823a7C64Fdc0185", - "contractAddress": "0x9C215206Da4bf108aE5aEEf9dA7caD3352A36Dad", - "transactionIndex": 0, - "gasUsed": "4004920", - "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", - "blockHash": "0x4c4949954c351d51e811bc97d7f243c8c2c7b1257c6cde72c21fff13c11ad1fd", - "transactionHash": "0x4093bd1af046029ae2fb62c1241cc6c893c4091ea698e0cc1ec2a23419b6fb58", - "logs": [], - "blockNumber": 14074409, - "cumulativeGasUsed": "4004920", + "contractAddress": "0xd278d822a040457324043619E962a5b093Ba1d4e", + "transactionIndex": 14, + "gasUsed": "3964995", + "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000080000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "blockHash": "0x303a4a1317292f9c582594ff4f1cd3088cdc183ef7235026f4c8902a0b057b1d", + "transactionHash": "0x31a09aa0a5eb62d815ca799997e4b342c91838df6b746bf0af43e700ad866496", + "logs": [ + { + "transactionIndex": 14, + "blockNumber": 114643678, + "transactionHash": "0x31a09aa0a5eb62d815ca799997e4b342c91838df6b746bf0af43e700ad866496", + "address": "0xd278d822a040457324043619E962a5b093Ba1d4e", + "topics": [ + "0x7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb3847402498" + ], + "data": "0x0000000000000000000000000000000000000000000000000000000000000001", + "logIndex": 19, + "blockHash": "0x303a4a1317292f9c582594ff4f1cd3088cdc183ef7235026f4c8902a0b057b1d" + } + ], + "blockNumber": 114643678, + "cumulativeGasUsed": "5422312", "status": 1, "byzantium": true }, "args": [], - "solcInputHash": "8a26d6606024625e1a63f4cee8837487", - "metadata": "{\"compiler\":{\"version\":\"0.8.12+commit.f00d7308\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[],\"name\":\"AssetStillControlledInReserves\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"BurnAmountExceedsAllowance\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"HourlyLimitExceeded\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidSender\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidToken\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidTreasury\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"NotGovernor\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"NotGovernorOrGuardian\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"NotMinter\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"NotTreasury\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"TooBigAmount\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"TooHighParameterValue\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ZeroAddress\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"spender\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"}],\"name\":\"Approval\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"bridgeToken\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"limit\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"hourlyLimit\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"fee\",\"type\":\"uint64\"},{\"indexed\":false,\"internalType\":\"bool\",\"name\":\"paused\",\"type\":\"bool\"}],\"name\":\"BridgeTokenAdded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"bridgeToken\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"fee\",\"type\":\"uint64\"}],\"name\":\"BridgeTokenFeeUpdated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"bridgeToken\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"hourlyLimit\",\"type\":\"uint256\"}],\"name\":\"BridgeTokenHourlyLimitUpdated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"bridgeToken\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"limit\",\"type\":\"uint256\"}],\"name\":\"BridgeTokenLimitUpdated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"bridgeToken\",\"type\":\"address\"}],\"name\":\"BridgeTokenRemoved\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"bridgeToken\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"bool\",\"name\":\"toggleStatus\",\"type\":\"bool\"}],\"name\":\"BridgeTokenToggled\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"theAddress\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"toggleStatus\",\"type\":\"uint256\"}],\"name\":\"FeeToggled\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"hourlyLimit\",\"type\":\"uint256\"}],\"name\":\"HourlyLimitUpdated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"minter\",\"type\":\"address\"}],\"name\":\"MinterToggled\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"Recovered\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"}],\"name\":\"Transfer\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"_treasury\",\"type\":\"address\"}],\"name\":\"TreasuryUpdated\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"BASE_PARAMS\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"DOMAIN_SEPARATOR\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"bridgeToken\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"limit\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"hourlyLimit\",\"type\":\"uint256\"},{\"internalType\":\"uint64\",\"name\":\"fee\",\"type\":\"uint64\"},{\"internalType\":\"bool\",\"name\":\"paused\",\"type\":\"bool\"}],\"name\":\"addBridgeToken\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"minter\",\"type\":\"address\"}],\"name\":\"addMinter\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"allBridgeTokens\",\"outputs\":[{\"internalType\":\"address[]\",\"name\":\"\",\"type\":\"address[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"spender\",\"type\":\"address\"}],\"name\":\"allowance\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"spender\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"approve\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"}],\"name\":\"balanceOf\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"name\":\"bridgeTokensList\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"bridges\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"limit\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"hourlyLimit\",\"type\":\"uint256\"},{\"internalType\":\"uint64\",\"name\":\"fee\",\"type\":\"uint64\"},{\"internalType\":\"bool\",\"name\":\"allowed\",\"type\":\"bool\"},{\"internalType\":\"bool\",\"name\":\"paused\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"burner\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"}],\"name\":\"burnFrom\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"burner\",\"type\":\"address\"}],\"name\":\"burnSelf\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"burnStablecoin\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"chainTotalHourlyLimit\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"name\":\"chainTotalUsage\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"currentTotalUsage\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"bridgeToken\",\"type\":\"address\"}],\"name\":\"currentUsage\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"decimals\",\"outputs\":[{\"internalType\":\"uint8\",\"name\":\"\",\"type\":\"uint8\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"spender\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"subtractedValue\",\"type\":\"uint256\"}],\"name\":\"decreaseAllowance\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"spender\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"addedValue\",\"type\":\"uint256\"}],\"name\":\"increaseAllowance\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"string\",\"name\":\"name_\",\"type\":\"string\"},{\"internalType\":\"string\",\"name\":\"symbol_\",\"type\":\"string\"},{\"internalType\":\"address\",\"name\":\"_treasury\",\"type\":\"address\"}],\"name\":\"initialize\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"isFeeExempt\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"isMinter\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"mint\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"name\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"}],\"name\":\"nonces\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"spender\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"deadline\",\"type\":\"uint256\"},{\"internalType\":\"uint8\",\"name\":\"v\",\"type\":\"uint8\"},{\"internalType\":\"bytes32\",\"name\":\"r\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32\",\"name\":\"s\",\"type\":\"bytes32\"}],\"name\":\"permit\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"tokenAddress\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amountToRecover\",\"type\":\"uint256\"}],\"name\":\"recoverERC20\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"bridgeToken\",\"type\":\"address\"}],\"name\":\"removeBridgeToken\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"minter\",\"type\":\"address\"}],\"name\":\"removeMinter\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"hourlyLimit\",\"type\":\"uint256\"}],\"name\":\"setChainTotalHourlyLimit\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"bridgeToken\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"hourlyLimit\",\"type\":\"uint256\"}],\"name\":\"setHourlyLimit\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"bridgeToken\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"limit\",\"type\":\"uint256\"}],\"name\":\"setLimit\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"bridgeToken\",\"type\":\"address\"},{\"internalType\":\"uint64\",\"name\":\"fee\",\"type\":\"uint64\"}],\"name\":\"setSwapFee\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_treasury\",\"type\":\"address\"}],\"name\":\"setTreasury\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"bridgeToken\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"swapIn\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"bridgeToken\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"swapOut\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"symbol\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"bridgeToken\",\"type\":\"address\"}],\"name\":\"toggleBridge\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"theAddress\",\"type\":\"address\"}],\"name\":\"toggleFeesForAddress\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"totalSupply\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"recipient\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"transfer\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"recipient\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"transferFrom\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"treasury\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"name\":\"usage\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"}],\"devdoc\":{\"author\":\"Angle Core Team\",\"details\":\"This contract supports bridge tokens having a minting right on the stablecoin (also referred to as the canonical or the native token)References: - FRAX implementation: https://polygonscan.com/address/0x45c32fA6DF82ead1e2EF74d17b76547EDdFaFF89#code - QiDAO implementation: https://snowtrace.io/address/0x5c49b268c9841AFF1Cc3B0a418ff5c3442eE3F3b#code\",\"kind\":\"dev\",\"methods\":{\"DOMAIN_SEPARATOR()\":{\"details\":\"See {IERC20Permit-DOMAIN_SEPARATOR}.\"},\"addBridgeToken(address,uint256,uint256,uint64,bool)\":{\"params\":{\"bridgeToken\":\"Bridge token to add: it should be a version of the stablecoin from another bridge\",\"fee\":\"Fee taken upon swapping for or against this token\",\"hourlyLimit\":\"Limit on the hourly volume for this bridge\",\"limit\":\"Limit on the balance of bridge token this contract could hold\",\"paused\":\"Whether swapping for this token should be paused or not\"}},\"addMinter(address)\":{\"details\":\"Zero address checks are performed directly in the `Treasury` contract\",\"params\":{\"minter\":\"Minter address to add\"}},\"allBridgeTokens()\":{\"details\":\"Helpful for UIs\"},\"allowance(address,address)\":{\"details\":\"See {IERC20-allowance}.\"},\"approve(address,uint256)\":{\"details\":\"See {IERC20-approve}. Requirements: - `spender` cannot be the zero address.\"},\"balanceOf(address)\":{\"details\":\"See {IERC20-balanceOf}.\"},\"burnFrom(uint256,address,address)\":{\"details\":\"This method is to be called by a contract with the minter right after being requested to do so by a `sender` address willing to burn tokens from another `burner` addressThe method checks the allowance between the `sender` and the `burner`\",\"params\":{\"amount\":\"Amount of tokens to burn\",\"burner\":\"Address to burn from\",\"sender\":\"Address which requested the burn from `burner`\"}},\"burnSelf(uint256,address)\":{\"details\":\"This method is to be called by a contract with a minter right on the AgToken after being requested to do so by an address willing to burn tokens from its address\",\"params\":{\"amount\":\"Amount of tokens to burn\",\"burner\":\"Address to burn from\"}},\"burnStablecoin(uint256)\":{\"details\":\"This function can typically be called if there is a settlement mechanism to burn stablecoins\",\"params\":{\"amount\":\"Amount of stablecoins to burn\"}},\"currentTotalUsage()\":{\"details\":\"Helpful for UIs\"},\"currentUsage(address)\":{\"details\":\"Helpful for UIs\",\"params\":{\"bridgeToken\":\"Bridge used to mint\"}},\"decimals()\":{\"details\":\"Returns the number of decimals used to get its user representation. For example, if `decimals` equals `2`, a balance of `505` tokens should be displayed to a user as `5.05` (`505 / 10 ** 2`). Tokens usually opt for a value of 18, imitating the relationship between Ether and Wei. This is the value {ERC20} uses, unless this function is overridden; NOTE: This information is only used for _display_ purposes: it in no way affects any of the arithmetic of the contract, including {IERC20-balanceOf} and {IERC20-transfer}.\"},\"decreaseAllowance(address,uint256)\":{\"details\":\"Atomically decreases the allowance granted to `spender` by the caller. This is an alternative to {approve} that can be used as a mitigation for problems described in {IERC20-approve}. Emits an {Approval} event indicating the updated allowance. Requirements: - `spender` cannot be the zero address. - `spender` must have allowance for the caller of at least `subtractedValue`.\"},\"increaseAllowance(address,uint256)\":{\"details\":\"Atomically increases the allowance granted to `spender` by the caller. This is an alternative to {approve} that can be used as a mitigation for problems described in {IERC20-approve}. Emits an {Approval} event indicating the updated allowance. Requirements: - `spender` cannot be the zero address.\"},\"initialize(string,string,address)\":{\"details\":\"By default, agTokens are ERC-20 tokens with 18 decimals\",\"params\":{\"_treasury\":\"Reference to the `Treasury` contract associated to this agToken\",\"name_\":\"Name of the token\",\"symbol_\":\"Symbol of the token\"}},\"mint(address,uint256)\":{\"details\":\"The contracts allowed to issue agTokens are the `StableMaster` contract, `VaultManager` contracts associated to this stablecoin as well as the flash loan module (if activated) and potentially contracts whitelisted by governance\",\"params\":{\"account\":\"Address to mint to\",\"amount\":\"Amount to mint\"}},\"name()\":{\"details\":\"Returns the name of the token.\"},\"nonces(address)\":{\"details\":\"See {IERC20Permit-nonces}.\"},\"permit(address,address,uint256,uint256,uint8,bytes32,bytes32)\":{\"details\":\"See {IERC20Permit-permit}.\"},\"recoverERC20(address,address,uint256)\":{\"details\":\"Can be used to withdraw bridge tokens for them to be de-bridged on mainnet\"},\"removeBridgeToken(address)\":{\"params\":{\"bridgeToken\":\"Address of the bridge token to remove support for\"}},\"removeMinter(address)\":{\"details\":\"This function can also be called by a minter wishing to revoke itself\",\"params\":{\"minter\":\"Minter address to remove\"}},\"setTreasury(address)\":{\"params\":{\"_treasury\":\"New treasury address\"}},\"swapIn(address,uint256,address)\":{\"details\":\"Some fees may be taken by the protocol depending on the token used and on the address calling\",\"params\":{\"amount\":\"Amount of bridge tokens to send\",\"bridgeToken\":\"Bridge token to use to mint\",\"to\":\"Address to which the stablecoin should be sent\"},\"returns\":{\"_0\":\"Amount of the canonical stablecoin actually minted\"}},\"swapOut(address,uint256,address)\":{\"details\":\"Some fees may be taken by the protocol depending on the token used and on the address calling\",\"params\":{\"amount\":\"Amount of canonical tokens to burn\",\"bridgeToken\":\"Bridge token required\",\"to\":\"Address to which the bridge token should be sent\"},\"returns\":{\"_0\":\"Amount of bridge tokens actually sent back\"}},\"symbol()\":{\"details\":\"Returns the symbol of the token, usually a shorter version of the name.\"},\"totalSupply()\":{\"details\":\"See {IERC20-totalSupply}.\"},\"transfer(address,uint256)\":{\"details\":\"See {IERC20-transfer}. Requirements: - `recipient` cannot be the zero address. - the caller must have a balance of at least `amount`.\"},\"transferFrom(address,address,uint256)\":{\"details\":\"See {IERC20-transferFrom}. Emits an {Approval} event indicating the updated allowance. This is not required by the EIP. See the note at the beginning of {ERC20}. Requirements: - `sender` and `recipient` cannot be the zero address. - `sender` must have a balance of at least `amount`. - the caller must have allowance for ``sender``'s tokens of at least `amount`.\"}},\"title\":\"AgTokenSideChainMultiBridge\",\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{\"BASE_PARAMS()\":{\"notice\":\"Base used for fee computation\"},\"addBridgeToken(address,uint256,uint256,uint64,bool)\":{\"notice\":\"Adds support for a bridge token\"},\"addMinter(address)\":{\"notice\":\"Adds a minter in the contract\"},\"allBridgeTokens()\":{\"notice\":\"Returns the list of all supported bridge tokens\"},\"bridgeTokensList(uint256)\":{\"notice\":\"List of all bridge tokens\"},\"bridges(address)\":{\"notice\":\"Maps a bridge token to data\"},\"burnFrom(uint256,address,address)\":{\"notice\":\"Burns `amount` tokens from a `burner` address after being asked to by `sender`\"},\"burnSelf(uint256,address)\":{\"notice\":\"Burns `amount` tokens from a `burner` address\"},\"burnStablecoin(uint256)\":{\"notice\":\"Allows anyone to burn agToken without redeeming collateral back\"},\"chainTotalHourlyLimit()\":{\"notice\":\"Limit to the amount of tokens that can be sent from that chain to another chain\"},\"chainTotalUsage(uint256)\":{\"notice\":\"Usage per hour on that chain. Maps an hourly timestamp to the total volume swapped out on the chain\"},\"currentTotalUsage()\":{\"notice\":\"Returns the current total volume on the chain for the current hour\"},\"currentUsage(address)\":{\"notice\":\"Returns the current volume for a bridge, for the current hour\"},\"initialize(string,string,address)\":{\"notice\":\"Initializes the `AgToken` contract\"},\"isFeeExempt(address)\":{\"notice\":\"Maps an address to whether it is exempt of fees for when it comes to swapping in and out\"},\"isMinter(address)\":{\"notice\":\"Checks whether an address has the right to mint agTokens\"},\"mint(address,uint256)\":{\"notice\":\"Lets the `StableMaster` contract or another whitelisted contract mint agTokens\"},\"recoverERC20(address,address,uint256)\":{\"notice\":\"Recovers any ERC20 token\"},\"removeBridgeToken(address)\":{\"notice\":\"Removes support for a token\"},\"removeMinter(address)\":{\"notice\":\"Removes a minter from the contract\"},\"setChainTotalHourlyLimit(uint256)\":{\"notice\":\"Updates the `chainTotalHourlyLimit` amount\"},\"setHourlyLimit(address,uint256)\":{\"notice\":\"Updates the `hourlyLimit` amount for `bridgeToken`\"},\"setLimit(address,uint256)\":{\"notice\":\"Updates the `limit` amount for `bridgeToken`\"},\"setSwapFee(address,uint64)\":{\"notice\":\"Updates the `fee` value for `bridgeToken`\"},\"setTreasury(address)\":{\"notice\":\"Sets a new treasury contract\"},\"swapIn(address,uint256,address)\":{\"notice\":\"Mints the canonical token from a supported bridge token\"},\"swapOut(address,uint256,address)\":{\"notice\":\"Burns the canonical token in exchange for a bridge token\"},\"toggleBridge(address)\":{\"notice\":\"Pauses or unpauses swapping in and out for a token\"},\"toggleFeesForAddress(address)\":{\"notice\":\"Toggles fees for the address `theAddress`\"},\"treasury()\":{\"notice\":\"Reference to the treasury contract which can grant minting rights\"},\"usage(address,uint256)\":{\"notice\":\"Maps a bridge token to the associated hourly volume\"}},\"notice\":\"Contract for Angle agTokens on other chains than Ethereum mainnet\",\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/agToken/AgTokenSideChainMultiBridge.sol\":\"AgTokenSideChainMultiBridge\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":1000000},\"remappings\":[]},\"sources\":{\"@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (proxy/utils/Initializable.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../../utils/AddressUpgradeable.sol\\\";\\n\\n/**\\n * @dev This is a base contract to aid in writing upgradeable contracts, or any kind of contract that will be deployed\\n * behind a proxy. Since a proxied contract can't have a constructor, it's common to move constructor logic to an\\n * external initializer function, usually called `initialize`. It then becomes necessary to protect this initializer\\n * function so it can only be called once. The {initializer} modifier provided by this contract will have this effect.\\n *\\n * TIP: To avoid leaving the proxy in an uninitialized state, the initializer function should be called as early as\\n * possible by providing the encoded function call as the `_data` argument to {ERC1967Proxy-constructor}.\\n *\\n * CAUTION: When used with inheritance, manual care must be taken to not invoke a parent initializer twice, or to ensure\\n * that all initializers are idempotent. This is not verified automatically as constructors are by Solidity.\\n *\\n * [CAUTION]\\n * ====\\n * Avoid leaving a contract uninitialized.\\n *\\n * An uninitialized contract can be taken over by an attacker. This applies to both a proxy and its implementation\\n * contract, which may impact the proxy. To initialize the implementation contract, you can either invoke the\\n * initializer manually, or you can include a constructor to automatically mark it as initialized when it is deployed:\\n *\\n * [.hljs-theme-light.nopadding]\\n * ```\\n * /// @custom:oz-upgrades-unsafe-allow constructor\\n * constructor() initializer {}\\n * ```\\n * ====\\n */\\nabstract contract Initializable {\\n /**\\n * @dev Indicates that the contract has been initialized.\\n */\\n bool private _initialized;\\n\\n /**\\n * @dev Indicates that the contract is in the process of being initialized.\\n */\\n bool private _initializing;\\n\\n /**\\n * @dev Modifier to protect an initializer function from being invoked twice.\\n */\\n modifier initializer() {\\n // If the contract is initializing we ignore whether _initialized is set in order to support multiple\\n // inheritance patterns, but we only do this in the context of a constructor, because in other contexts the\\n // contract may have been reentered.\\n require(_initializing ? _isConstructor() : !_initialized, \\\"Initializable: contract is already initialized\\\");\\n\\n bool isTopLevelCall = !_initializing;\\n if (isTopLevelCall) {\\n _initializing = true;\\n _initialized = true;\\n }\\n\\n _;\\n\\n if (isTopLevelCall) {\\n _initializing = false;\\n }\\n }\\n\\n /**\\n * @dev Modifier to protect an initialization function so that it can only be invoked by functions with the\\n * {initializer} modifier, directly or indirectly.\\n */\\n modifier onlyInitializing() {\\n require(_initializing, \\\"Initializable: contract is not initializing\\\");\\n _;\\n }\\n\\n function _isConstructor() private view returns (bool) {\\n return !AddressUpgradeable.isContract(address(this));\\n }\\n}\\n\",\"keccak256\":\"0x68861bcc80cacbd498efde75aab6c74a486cc48262660d326c8d7530d9752097\",\"license\":\"MIT\"},\"@openzeppelin/contracts-upgradeable/token/ERC20/ERC20Upgradeable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (token/ERC20/ERC20.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"./IERC20Upgradeable.sol\\\";\\nimport \\\"./extensions/IERC20MetadataUpgradeable.sol\\\";\\nimport \\\"../../utils/ContextUpgradeable.sol\\\";\\nimport \\\"../../proxy/utils/Initializable.sol\\\";\\n\\n/**\\n * @dev Implementation of the {IERC20} interface.\\n *\\n * This implementation is agnostic to the way tokens are created. This means\\n * that a supply mechanism has to be added in a derived contract using {_mint}.\\n * For a generic mechanism see {ERC20PresetMinterPauser}.\\n *\\n * TIP: For a detailed writeup see our guide\\n * https://forum.zeppelin.solutions/t/how-to-implement-erc20-supply-mechanisms/226[How\\n * to implement supply mechanisms].\\n *\\n * We have followed general OpenZeppelin Contracts guidelines: functions revert\\n * instead returning `false` on failure. This behavior is nonetheless\\n * conventional and does not conflict with the expectations of ERC20\\n * applications.\\n *\\n * Additionally, an {Approval} event is emitted on calls to {transferFrom}.\\n * This allows applications to reconstruct the allowance for all accounts just\\n * by listening to said events. Other implementations of the EIP may not emit\\n * these events, as it isn't required by the specification.\\n *\\n * Finally, the non-standard {decreaseAllowance} and {increaseAllowance}\\n * functions have been added to mitigate the well-known issues around setting\\n * allowances. See {IERC20-approve}.\\n */\\ncontract ERC20Upgradeable is Initializable, ContextUpgradeable, IERC20Upgradeable, IERC20MetadataUpgradeable {\\n mapping(address => uint256) private _balances;\\n\\n mapping(address => mapping(address => uint256)) private _allowances;\\n\\n uint256 private _totalSupply;\\n\\n string private _name;\\n string private _symbol;\\n\\n /**\\n * @dev Sets the values for {name} and {symbol}.\\n *\\n * The default value of {decimals} is 18. To select a different value for\\n * {decimals} you should overload it.\\n *\\n * All two of these values are immutable: they can only be set once during\\n * construction.\\n */\\n function __ERC20_init(string memory name_, string memory symbol_) internal onlyInitializing {\\n __Context_init_unchained();\\n __ERC20_init_unchained(name_, symbol_);\\n }\\n\\n function __ERC20_init_unchained(string memory name_, string memory symbol_) internal onlyInitializing {\\n _name = name_;\\n _symbol = symbol_;\\n }\\n\\n /**\\n * @dev Returns the name of the token.\\n */\\n function name() public view virtual override returns (string memory) {\\n return _name;\\n }\\n\\n /**\\n * @dev Returns the symbol of the token, usually a shorter version of the\\n * name.\\n */\\n function symbol() public view virtual override returns (string memory) {\\n return _symbol;\\n }\\n\\n /**\\n * @dev Returns the number of decimals used to get its user representation.\\n * For example, if `decimals` equals `2`, a balance of `505` tokens should\\n * be displayed to a user as `5.05` (`505 / 10 ** 2`).\\n *\\n * Tokens usually opt for a value of 18, imitating the relationship between\\n * Ether and Wei. This is the value {ERC20} uses, unless this function is\\n * overridden;\\n *\\n * NOTE: This information is only used for _display_ purposes: it in\\n * no way affects any of the arithmetic of the contract, including\\n * {IERC20-balanceOf} and {IERC20-transfer}.\\n */\\n function decimals() public view virtual override returns (uint8) {\\n return 18;\\n }\\n\\n /**\\n * @dev See {IERC20-totalSupply}.\\n */\\n function totalSupply() public view virtual override returns (uint256) {\\n return _totalSupply;\\n }\\n\\n /**\\n * @dev See {IERC20-balanceOf}.\\n */\\n function balanceOf(address account) public view virtual override returns (uint256) {\\n return _balances[account];\\n }\\n\\n /**\\n * @dev See {IERC20-transfer}.\\n *\\n * Requirements:\\n *\\n * - `recipient` cannot be the zero address.\\n * - the caller must have a balance of at least `amount`.\\n */\\n function transfer(address recipient, uint256 amount) public virtual override returns (bool) {\\n _transfer(_msgSender(), recipient, amount);\\n return true;\\n }\\n\\n /**\\n * @dev See {IERC20-allowance}.\\n */\\n function allowance(address owner, address spender) public view virtual override returns (uint256) {\\n return _allowances[owner][spender];\\n }\\n\\n /**\\n * @dev See {IERC20-approve}.\\n *\\n * Requirements:\\n *\\n * - `spender` cannot be the zero address.\\n */\\n function approve(address spender, uint256 amount) public virtual override returns (bool) {\\n _approve(_msgSender(), spender, amount);\\n return true;\\n }\\n\\n /**\\n * @dev See {IERC20-transferFrom}.\\n *\\n * Emits an {Approval} event indicating the updated allowance. This is not\\n * required by the EIP. See the note at the beginning of {ERC20}.\\n *\\n * Requirements:\\n *\\n * - `sender` and `recipient` cannot be the zero address.\\n * - `sender` must have a balance of at least `amount`.\\n * - the caller must have allowance for ``sender``'s tokens of at least\\n * `amount`.\\n */\\n function transferFrom(\\n address sender,\\n address recipient,\\n uint256 amount\\n ) public virtual override returns (bool) {\\n _transfer(sender, recipient, amount);\\n\\n uint256 currentAllowance = _allowances[sender][_msgSender()];\\n require(currentAllowance >= amount, \\\"ERC20: transfer amount exceeds allowance\\\");\\n unchecked {\\n _approve(sender, _msgSender(), currentAllowance - amount);\\n }\\n\\n return true;\\n }\\n\\n /**\\n * @dev Atomically increases the allowance granted to `spender` by the caller.\\n *\\n * This is an alternative to {approve} that can be used as a mitigation for\\n * problems described in {IERC20-approve}.\\n *\\n * Emits an {Approval} event indicating the updated allowance.\\n *\\n * Requirements:\\n *\\n * - `spender` cannot be the zero address.\\n */\\n function increaseAllowance(address spender, uint256 addedValue) public virtual returns (bool) {\\n _approve(_msgSender(), spender, _allowances[_msgSender()][spender] + addedValue);\\n return true;\\n }\\n\\n /**\\n * @dev Atomically decreases the allowance granted to `spender` by the caller.\\n *\\n * This is an alternative to {approve} that can be used as a mitigation for\\n * problems described in {IERC20-approve}.\\n *\\n * Emits an {Approval} event indicating the updated allowance.\\n *\\n * Requirements:\\n *\\n * - `spender` cannot be the zero address.\\n * - `spender` must have allowance for the caller of at least\\n * `subtractedValue`.\\n */\\n function decreaseAllowance(address spender, uint256 subtractedValue) public virtual returns (bool) {\\n uint256 currentAllowance = _allowances[_msgSender()][spender];\\n require(currentAllowance >= subtractedValue, \\\"ERC20: decreased allowance below zero\\\");\\n unchecked {\\n _approve(_msgSender(), spender, currentAllowance - subtractedValue);\\n }\\n\\n return true;\\n }\\n\\n /**\\n * @dev Moves `amount` of tokens from `sender` to `recipient`.\\n *\\n * This internal function is equivalent to {transfer}, and can be used to\\n * e.g. implement automatic token fees, slashing mechanisms, etc.\\n *\\n * Emits a {Transfer} event.\\n *\\n * Requirements:\\n *\\n * - `sender` cannot be the zero address.\\n * - `recipient` cannot be the zero address.\\n * - `sender` must have a balance of at least `amount`.\\n */\\n function _transfer(\\n address sender,\\n address recipient,\\n uint256 amount\\n ) internal virtual {\\n require(sender != address(0), \\\"ERC20: transfer from the zero address\\\");\\n require(recipient != address(0), \\\"ERC20: transfer to the zero address\\\");\\n\\n _beforeTokenTransfer(sender, recipient, amount);\\n\\n uint256 senderBalance = _balances[sender];\\n require(senderBalance >= amount, \\\"ERC20: transfer amount exceeds balance\\\");\\n unchecked {\\n _balances[sender] = senderBalance - amount;\\n }\\n _balances[recipient] += amount;\\n\\n emit Transfer(sender, recipient, amount);\\n\\n _afterTokenTransfer(sender, recipient, amount);\\n }\\n\\n /** @dev Creates `amount` tokens and assigns them to `account`, increasing\\n * the total supply.\\n *\\n * Emits a {Transfer} event with `from` set to the zero address.\\n *\\n * Requirements:\\n *\\n * - `account` cannot be the zero address.\\n */\\n function _mint(address account, uint256 amount) internal virtual {\\n require(account != address(0), \\\"ERC20: mint to the zero address\\\");\\n\\n _beforeTokenTransfer(address(0), account, amount);\\n\\n _totalSupply += amount;\\n _balances[account] += amount;\\n emit Transfer(address(0), account, amount);\\n\\n _afterTokenTransfer(address(0), account, amount);\\n }\\n\\n /**\\n * @dev Destroys `amount` tokens from `account`, reducing the\\n * total supply.\\n *\\n * Emits a {Transfer} event with `to` set to the zero address.\\n *\\n * Requirements:\\n *\\n * - `account` cannot be the zero address.\\n * - `account` must have at least `amount` tokens.\\n */\\n function _burn(address account, uint256 amount) internal virtual {\\n require(account != address(0), \\\"ERC20: burn from the zero address\\\");\\n\\n _beforeTokenTransfer(account, address(0), amount);\\n\\n uint256 accountBalance = _balances[account];\\n require(accountBalance >= amount, \\\"ERC20: burn amount exceeds balance\\\");\\n unchecked {\\n _balances[account] = accountBalance - amount;\\n }\\n _totalSupply -= amount;\\n\\n emit Transfer(account, address(0), amount);\\n\\n _afterTokenTransfer(account, address(0), amount);\\n }\\n\\n /**\\n * @dev Sets `amount` as the allowance of `spender` over the `owner` s tokens.\\n *\\n * This internal function is equivalent to `approve`, and can be used to\\n * e.g. set automatic allowances for certain subsystems, etc.\\n *\\n * Emits an {Approval} event.\\n *\\n * Requirements:\\n *\\n * - `owner` cannot be the zero address.\\n * - `spender` cannot be the zero address.\\n */\\n function _approve(\\n address owner,\\n address spender,\\n uint256 amount\\n ) internal virtual {\\n require(owner != address(0), \\\"ERC20: approve from the zero address\\\");\\n require(spender != address(0), \\\"ERC20: approve to the zero address\\\");\\n\\n _allowances[owner][spender] = amount;\\n emit Approval(owner, spender, amount);\\n }\\n\\n /**\\n * @dev Hook that is called before any transfer of tokens. This includes\\n * minting and burning.\\n *\\n * Calling conditions:\\n *\\n * - when `from` and `to` are both non-zero, `amount` of ``from``'s tokens\\n * will be transferred to `to`.\\n * - when `from` is zero, `amount` tokens will be minted for `to`.\\n * - when `to` is zero, `amount` of ``from``'s tokens will be burned.\\n * - `from` and `to` are never both zero.\\n *\\n * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].\\n */\\n function _beforeTokenTransfer(\\n address from,\\n address to,\\n uint256 amount\\n ) internal virtual {}\\n\\n /**\\n * @dev Hook that is called after any transfer of tokens. This includes\\n * minting and burning.\\n *\\n * Calling conditions:\\n *\\n * - when `from` and `to` are both non-zero, `amount` of ``from``'s tokens\\n * has been transferred to `to`.\\n * - when `from` is zero, `amount` tokens have been minted for `to`.\\n * - when `to` is zero, `amount` of ``from``'s tokens have been burned.\\n * - `from` and `to` are never both zero.\\n *\\n * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].\\n */\\n function _afterTokenTransfer(\\n address from,\\n address to,\\n uint256 amount\\n ) internal virtual {}\\n uint256[45] private __gap;\\n}\\n\",\"keccak256\":\"0x23a373902059fb51db98e32e13f89a0ef0c570039081a1345022e66bc7e315d4\",\"license\":\"MIT\"},\"@openzeppelin/contracts-upgradeable/token/ERC20/IERC20Upgradeable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (token/ERC20/IERC20.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Interface of the ERC20 standard as defined in the EIP.\\n */\\ninterface IERC20Upgradeable {\\n /**\\n * @dev Returns the amount of tokens in existence.\\n */\\n function totalSupply() external view returns (uint256);\\n\\n /**\\n * @dev Returns the amount of tokens owned by `account`.\\n */\\n function balanceOf(address account) external view returns (uint256);\\n\\n /**\\n * @dev Moves `amount` tokens from the caller's account to `recipient`.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * Emits a {Transfer} event.\\n */\\n function transfer(address recipient, uint256 amount) external returns (bool);\\n\\n /**\\n * @dev Returns the remaining number of tokens that `spender` will be\\n * allowed to spend on behalf of `owner` through {transferFrom}. This is\\n * zero by default.\\n *\\n * This value changes when {approve} or {transferFrom} are called.\\n */\\n function allowance(address owner, address spender) external view returns (uint256);\\n\\n /**\\n * @dev Sets `amount` as the allowance of `spender` over the caller's tokens.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * IMPORTANT: Beware that changing an allowance with this method brings the risk\\n * that someone may use both the old and the new allowance by unfortunate\\n * transaction ordering. One possible solution to mitigate this race\\n * condition is to first reduce the spender's allowance to 0 and set the\\n * desired value afterwards:\\n * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729\\n *\\n * Emits an {Approval} event.\\n */\\n function approve(address spender, uint256 amount) external returns (bool);\\n\\n /**\\n * @dev Moves `amount` tokens from `sender` to `recipient` using the\\n * allowance mechanism. `amount` is then deducted from the caller's\\n * allowance.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * Emits a {Transfer} event.\\n */\\n function transferFrom(\\n address sender,\\n address recipient,\\n uint256 amount\\n ) external returns (bool);\\n\\n /**\\n * @dev Emitted when `value` tokens are moved from one account (`from`) to\\n * another (`to`).\\n *\\n * Note that `value` may be zero.\\n */\\n event Transfer(address indexed from, address indexed to, uint256 value);\\n\\n /**\\n * @dev Emitted when the allowance of a `spender` for an `owner` is set by\\n * a call to {approve}. `value` is the new allowance.\\n */\\n event Approval(address indexed owner, address indexed spender, uint256 value);\\n}\\n\",\"keccak256\":\"0x5ca0eb1120133a6d0799752532d4638048391823a2b623c4fe9ff46e262266fb\",\"license\":\"MIT\"},\"@openzeppelin/contracts-upgradeable/token/ERC20/extensions/IERC20MetadataUpgradeable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (token/ERC20/extensions/IERC20Metadata.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../IERC20Upgradeable.sol\\\";\\n\\n/**\\n * @dev Interface for the optional metadata functions from the ERC20 standard.\\n *\\n * _Available since v4.1._\\n */\\ninterface IERC20MetadataUpgradeable is IERC20Upgradeable {\\n /**\\n * @dev Returns the name of the token.\\n */\\n function name() external view returns (string memory);\\n\\n /**\\n * @dev Returns the symbol of the token.\\n */\\n function symbol() external view returns (string memory);\\n\\n /**\\n * @dev Returns the decimals places of the token.\\n */\\n function decimals() external view returns (uint8);\\n}\\n\",\"keccak256\":\"0x605434219ebbe4653f703640f06969faa5a1d78f0bfef878e5ddbb1ca369ceeb\",\"license\":\"MIT\"},\"@openzeppelin/contracts-upgradeable/token/ERC20/extensions/draft-ERC20PermitUpgradeable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (token/ERC20/extensions/draft-ERC20Permit.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"./draft-IERC20PermitUpgradeable.sol\\\";\\nimport \\\"../ERC20Upgradeable.sol\\\";\\nimport \\\"../../../utils/cryptography/draft-EIP712Upgradeable.sol\\\";\\nimport \\\"../../../utils/cryptography/ECDSAUpgradeable.sol\\\";\\nimport \\\"../../../utils/CountersUpgradeable.sol\\\";\\nimport \\\"../../../proxy/utils/Initializable.sol\\\";\\n\\n/**\\n * @dev Implementation of the ERC20 Permit extension allowing approvals to be made via signatures, as defined in\\n * https://eips.ethereum.org/EIPS/eip-2612[EIP-2612].\\n *\\n * Adds the {permit} method, which can be used to change an account's ERC20 allowance (see {IERC20-allowance}) by\\n * presenting a message signed by the account. By not relying on `{IERC20-approve}`, the token holder account doesn't\\n * need to send a transaction, and thus is not required to hold Ether at all.\\n *\\n * _Available since v3.4._\\n */\\nabstract contract ERC20PermitUpgradeable is Initializable, ERC20Upgradeable, IERC20PermitUpgradeable, EIP712Upgradeable {\\n using CountersUpgradeable for CountersUpgradeable.Counter;\\n\\n mapping(address => CountersUpgradeable.Counter) private _nonces;\\n\\n // solhint-disable-next-line var-name-mixedcase\\n bytes32 private _PERMIT_TYPEHASH;\\n\\n /**\\n * @dev Initializes the {EIP712} domain separator using the `name` parameter, and setting `version` to `\\\"1\\\"`.\\n *\\n * It's a good idea to use the same `name` that is defined as the ERC20 token name.\\n */\\n function __ERC20Permit_init(string memory name) internal onlyInitializing {\\n __Context_init_unchained();\\n __EIP712_init_unchained(name, \\\"1\\\");\\n __ERC20Permit_init_unchained(name);\\n }\\n\\n function __ERC20Permit_init_unchained(string memory name) internal onlyInitializing {\\n _PERMIT_TYPEHASH = keccak256(\\\"Permit(address owner,address spender,uint256 value,uint256 nonce,uint256 deadline)\\\");}\\n\\n /**\\n * @dev See {IERC20Permit-permit}.\\n */\\n function permit(\\n address owner,\\n address spender,\\n uint256 value,\\n uint256 deadline,\\n uint8 v,\\n bytes32 r,\\n bytes32 s\\n ) public virtual override {\\n require(block.timestamp <= deadline, \\\"ERC20Permit: expired deadline\\\");\\n\\n bytes32 structHash = keccak256(abi.encode(_PERMIT_TYPEHASH, owner, spender, value, _useNonce(owner), deadline));\\n\\n bytes32 hash = _hashTypedDataV4(structHash);\\n\\n address signer = ECDSAUpgradeable.recover(hash, v, r, s);\\n require(signer == owner, \\\"ERC20Permit: invalid signature\\\");\\n\\n _approve(owner, spender, value);\\n }\\n\\n /**\\n * @dev See {IERC20Permit-nonces}.\\n */\\n function nonces(address owner) public view virtual override returns (uint256) {\\n return _nonces[owner].current();\\n }\\n\\n /**\\n * @dev See {IERC20Permit-DOMAIN_SEPARATOR}.\\n */\\n // solhint-disable-next-line func-name-mixedcase\\n function DOMAIN_SEPARATOR() external view override returns (bytes32) {\\n return _domainSeparatorV4();\\n }\\n\\n /**\\n * @dev \\\"Consume a nonce\\\": return the current value and increment.\\n *\\n * _Available since v4.1._\\n */\\n function _useNonce(address owner) internal virtual returns (uint256 current) {\\n CountersUpgradeable.Counter storage nonce = _nonces[owner];\\n current = nonce.current();\\n nonce.increment();\\n }\\n uint256[49] private __gap;\\n}\\n\",\"keccak256\":\"0x7fb71e823080ba5e320f036c7dbda29f3676f3d516db4dcdb8b0adbfbae5d830\",\"license\":\"MIT\"},\"@openzeppelin/contracts-upgradeable/token/ERC20/extensions/draft-IERC20PermitUpgradeable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (token/ERC20/extensions/draft-IERC20Permit.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Interface of the ERC20 Permit extension allowing approvals to be made via signatures, as defined in\\n * https://eips.ethereum.org/EIPS/eip-2612[EIP-2612].\\n *\\n * Adds the {permit} method, which can be used to change an account's ERC20 allowance (see {IERC20-allowance}) by\\n * presenting a message signed by the account. By not relying on {IERC20-approve}, the token holder account doesn't\\n * need to send a transaction, and thus is not required to hold Ether at all.\\n */\\ninterface IERC20PermitUpgradeable {\\n /**\\n * @dev Sets `value` as the allowance of `spender` over ``owner``'s tokens,\\n * given ``owner``'s signed approval.\\n *\\n * IMPORTANT: The same issues {IERC20-approve} has related to transaction\\n * ordering also apply here.\\n *\\n * Emits an {Approval} event.\\n *\\n * Requirements:\\n *\\n * - `spender` cannot be the zero address.\\n * - `deadline` must be a timestamp in the future.\\n * - `v`, `r` and `s` must be a valid `secp256k1` signature from `owner`\\n * over the EIP712-formatted function arguments.\\n * - the signature must use ``owner``'s current nonce (see {nonces}).\\n *\\n * For more information on the signature format, see the\\n * https://eips.ethereum.org/EIPS/eip-2612#specification[relevant EIP\\n * section].\\n */\\n function permit(\\n address owner,\\n address spender,\\n uint256 value,\\n uint256 deadline,\\n uint8 v,\\n bytes32 r,\\n bytes32 s\\n ) external;\\n\\n /**\\n * @dev Returns the current nonce for `owner`. This value must be\\n * included whenever a signature is generated for {permit}.\\n *\\n * Every successful call to {permit} increases ``owner``'s nonce by one. This\\n * prevents a signature from being used multiple times.\\n */\\n function nonces(address owner) external view returns (uint256);\\n\\n /**\\n * @dev Returns the domain separator used in the encoding of the signature for {permit}, as defined by {EIP712}.\\n */\\n // solhint-disable-next-line func-name-mixedcase\\n function DOMAIN_SEPARATOR() external view returns (bytes32);\\n}\\n\",\"keccak256\":\"0xcc70d8e2281fb3ff69e8ab242500f10142cd0a7fa8dd9e45882be270d4d09024\",\"license\":\"MIT\"},\"@openzeppelin/contracts-upgradeable/utils/AddressUpgradeable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (utils/Address.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Collection of functions related to the address type\\n */\\nlibrary AddressUpgradeable {\\n /**\\n * @dev Returns true if `account` is a contract.\\n *\\n * [IMPORTANT]\\n * ====\\n * It is unsafe to assume that an address for which this function returns\\n * false is an externally-owned account (EOA) and not a contract.\\n *\\n * Among others, `isContract` will return false for the following\\n * types of addresses:\\n *\\n * - an externally-owned account\\n * - a contract in construction\\n * - an address where a contract will be created\\n * - an address where a contract lived, but was destroyed\\n * ====\\n */\\n function isContract(address account) internal view returns (bool) {\\n // This method relies on extcodesize, which returns 0 for contracts in\\n // construction, since the code is only stored at the end of the\\n // constructor execution.\\n\\n uint256 size;\\n assembly {\\n size := extcodesize(account)\\n }\\n return size > 0;\\n }\\n\\n /**\\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\\n * `recipient`, forwarding all available gas and reverting on errors.\\n *\\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\\n * imposed by `transfer`, making them unable to receive funds via\\n * `transfer`. {sendValue} removes this limitation.\\n *\\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\\n *\\n * IMPORTANT: because control is transferred to `recipient`, care must be\\n * taken to not create reentrancy vulnerabilities. Consider using\\n * {ReentrancyGuard} or the\\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\\n */\\n function sendValue(address payable recipient, uint256 amount) internal {\\n require(address(this).balance >= amount, \\\"Address: insufficient balance\\\");\\n\\n (bool success, ) = recipient.call{value: amount}(\\\"\\\");\\n require(success, \\\"Address: unable to send value, recipient may have reverted\\\");\\n }\\n\\n /**\\n * @dev Performs a Solidity function call using a low level `call`. A\\n * plain `call` is an unsafe replacement for a function call: use this\\n * function instead.\\n *\\n * If `target` reverts with a revert reason, it is bubbled up by this\\n * function (like regular Solidity function calls).\\n *\\n * Returns the raw returned data. To convert to the expected return value,\\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\\n *\\n * Requirements:\\n *\\n * - `target` must be a contract.\\n * - calling `target` with `data` must not revert.\\n *\\n * _Available since v3.1._\\n */\\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\\n return functionCall(target, data, \\\"Address: low-level call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\\n * `errorMessage` as a fallback revert reason when `target` reverts.\\n *\\n * _Available since v3.1._\\n */\\n function functionCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n return functionCallWithValue(target, data, 0, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but also transferring `value` wei to `target`.\\n *\\n * Requirements:\\n *\\n * - the calling contract must have an ETH balance of at least `value`.\\n * - the called Solidity function must be `payable`.\\n *\\n * _Available since v3.1._\\n */\\n function functionCallWithValue(\\n address target,\\n bytes memory data,\\n uint256 value\\n ) internal returns (bytes memory) {\\n return functionCallWithValue(target, data, value, \\\"Address: low-level call with value failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\\n * with `errorMessage` as a fallback revert reason when `target` reverts.\\n *\\n * _Available since v3.1._\\n */\\n function functionCallWithValue(\\n address target,\\n bytes memory data,\\n uint256 value,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n require(address(this).balance >= value, \\\"Address: insufficient balance for call\\\");\\n require(isContract(target), \\\"Address: call to non-contract\\\");\\n\\n (bool success, bytes memory returndata) = target.call{value: value}(data);\\n return verifyCallResult(success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but performing a static call.\\n *\\n * _Available since v3.3._\\n */\\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\\n return functionStaticCall(target, data, \\\"Address: low-level static call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\\n * but performing a static call.\\n *\\n * _Available since v3.3._\\n */\\n function functionStaticCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal view returns (bytes memory) {\\n require(isContract(target), \\\"Address: static call to non-contract\\\");\\n\\n (bool success, bytes memory returndata) = target.staticcall(data);\\n return verifyCallResult(success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the\\n * revert reason using the provided one.\\n *\\n * _Available since v4.3._\\n */\\n function verifyCallResult(\\n bool success,\\n bytes memory returndata,\\n string memory errorMessage\\n ) internal pure returns (bytes memory) {\\n if (success) {\\n return returndata;\\n } else {\\n // Look for revert reason and bubble it up if present\\n if (returndata.length > 0) {\\n // The easiest way to bubble the revert reason is using memory via assembly\\n\\n assembly {\\n let returndata_size := mload(returndata)\\n revert(add(32, returndata), returndata_size)\\n }\\n } else {\\n revert(errorMessage);\\n }\\n }\\n }\\n}\\n\",\"keccak256\":\"0x3f0f878c796dfc7feba6d3c4e3e526c14c7deae8b7bfc71088e3f38fab0d77b3\",\"license\":\"MIT\"},\"@openzeppelin/contracts-upgradeable/utils/ContextUpgradeable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)\\n\\npragma solidity ^0.8.0;\\nimport \\\"../proxy/utils/Initializable.sol\\\";\\n\\n/**\\n * @dev Provides information about the current execution context, including the\\n * sender of the transaction and its data. While these are generally available\\n * via msg.sender and msg.data, they should not be accessed in such a direct\\n * manner, since when dealing with meta-transactions the account sending and\\n * paying for execution may not be the actual sender (as far as an application\\n * is concerned).\\n *\\n * This contract is only required for intermediate, library-like contracts.\\n */\\nabstract contract ContextUpgradeable is Initializable {\\n function __Context_init() internal onlyInitializing {\\n __Context_init_unchained();\\n }\\n\\n function __Context_init_unchained() internal onlyInitializing {\\n }\\n function _msgSender() internal view virtual returns (address) {\\n return msg.sender;\\n }\\n\\n function _msgData() internal view virtual returns (bytes calldata) {\\n return msg.data;\\n }\\n uint256[50] private __gap;\\n}\\n\",\"keccak256\":\"0x0b0d548f6381370d394f7a434f994dc678b3ef3e755de106109d61343a685ea7\",\"license\":\"MIT\"},\"@openzeppelin/contracts-upgradeable/utils/CountersUpgradeable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (utils/Counters.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @title Counters\\n * @author Matt Condon (@shrugs)\\n * @dev Provides counters that can only be incremented, decremented or reset. This can be used e.g. to track the number\\n * of elements in a mapping, issuing ERC721 ids, or counting request ids.\\n *\\n * Include with `using Counters for Counters.Counter;`\\n */\\nlibrary CountersUpgradeable {\\n struct Counter {\\n // This variable should never be directly accessed by users of the library: interactions must be restricted to\\n // the library's function. As of Solidity v0.5.2, this cannot be enforced, though there is a proposal to add\\n // this feature: see https://github.com/ethereum/solidity/issues/4637\\n uint256 _value; // default: 0\\n }\\n\\n function current(Counter storage counter) internal view returns (uint256) {\\n return counter._value;\\n }\\n\\n function increment(Counter storage counter) internal {\\n unchecked {\\n counter._value += 1;\\n }\\n }\\n\\n function decrement(Counter storage counter) internal {\\n uint256 value = counter._value;\\n require(value > 0, \\\"Counter: decrement overflow\\\");\\n unchecked {\\n counter._value = value - 1;\\n }\\n }\\n\\n function reset(Counter storage counter) internal {\\n counter._value = 0;\\n }\\n}\\n\",\"keccak256\":\"0x798741e231b22b81e2dd2eddaaf8832dee4baf5cd8e2dbaa5c1dd12a1c053c4d\",\"license\":\"MIT\"},\"@openzeppelin/contracts-upgradeable/utils/StringsUpgradeable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (utils/Strings.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev String operations.\\n */\\nlibrary StringsUpgradeable {\\n bytes16 private constant _HEX_SYMBOLS = \\\"0123456789abcdef\\\";\\n\\n /**\\n * @dev Converts a `uint256` to its ASCII `string` decimal representation.\\n */\\n function toString(uint256 value) internal pure returns (string memory) {\\n // Inspired by OraclizeAPI's implementation - MIT licence\\n // https://github.com/oraclize/ethereum-api/blob/b42146b063c7d6ee1358846c198246239e9360e8/oraclizeAPI_0.4.25.sol\\n\\n if (value == 0) {\\n return \\\"0\\\";\\n }\\n uint256 temp = value;\\n uint256 digits;\\n while (temp != 0) {\\n digits++;\\n temp /= 10;\\n }\\n bytes memory buffer = new bytes(digits);\\n while (value != 0) {\\n digits -= 1;\\n buffer[digits] = bytes1(uint8(48 + uint256(value % 10)));\\n value /= 10;\\n }\\n return string(buffer);\\n }\\n\\n /**\\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation.\\n */\\n function toHexString(uint256 value) internal pure returns (string memory) {\\n if (value == 0) {\\n return \\\"0x00\\\";\\n }\\n uint256 temp = value;\\n uint256 length = 0;\\n while (temp != 0) {\\n length++;\\n temp >>= 8;\\n }\\n return toHexString(value, length);\\n }\\n\\n /**\\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length.\\n */\\n function toHexString(uint256 value, uint256 length) internal pure returns (string memory) {\\n bytes memory buffer = new bytes(2 * length + 2);\\n buffer[0] = \\\"0\\\";\\n buffer[1] = \\\"x\\\";\\n for (uint256 i = 2 * length + 1; i > 1; --i) {\\n buffer[i] = _HEX_SYMBOLS[value & 0xf];\\n value >>= 4;\\n }\\n require(value == 0, \\\"Strings: hex length insufficient\\\");\\n return string(buffer);\\n }\\n}\\n\",\"keccak256\":\"0x398d3323c1932a5986bf36be7c57593e121e69d5db5b6574b4ee0d031443de37\",\"license\":\"MIT\"},\"@openzeppelin/contracts-upgradeable/utils/cryptography/ECDSAUpgradeable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (utils/cryptography/ECDSA.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../StringsUpgradeable.sol\\\";\\n\\n/**\\n * @dev Elliptic Curve Digital Signature Algorithm (ECDSA) operations.\\n *\\n * These functions can be used to verify that a message was signed by the holder\\n * of the private keys of a given address.\\n */\\nlibrary ECDSAUpgradeable {\\n enum RecoverError {\\n NoError,\\n InvalidSignature,\\n InvalidSignatureLength,\\n InvalidSignatureS,\\n InvalidSignatureV\\n }\\n\\n function _throwError(RecoverError error) private pure {\\n if (error == RecoverError.NoError) {\\n return; // no error: do nothing\\n } else if (error == RecoverError.InvalidSignature) {\\n revert(\\\"ECDSA: invalid signature\\\");\\n } else if (error == RecoverError.InvalidSignatureLength) {\\n revert(\\\"ECDSA: invalid signature length\\\");\\n } else if (error == RecoverError.InvalidSignatureS) {\\n revert(\\\"ECDSA: invalid signature 's' value\\\");\\n } else if (error == RecoverError.InvalidSignatureV) {\\n revert(\\\"ECDSA: invalid signature 'v' value\\\");\\n }\\n }\\n\\n /**\\n * @dev Returns the address that signed a hashed message (`hash`) with\\n * `signature` or error string. This address can then be used for verification purposes.\\n *\\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\\n * this function rejects them by requiring the `s` value to be in the lower\\n * half order, and the `v` value to be either 27 or 28.\\n *\\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\\n * verification to be secure: it is possible to craft signatures that\\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\\n * this is by receiving a hash of the original message (which may otherwise\\n * be too long), and then calling {toEthSignedMessageHash} on it.\\n *\\n * Documentation for signature generation:\\n * - with https://web3js.readthedocs.io/en/v1.3.4/web3-eth-accounts.html#sign[Web3.js]\\n * - with https://docs.ethers.io/v5/api/signer/#Signer-signMessage[ethers]\\n *\\n * _Available since v4.3._\\n */\\n function tryRecover(bytes32 hash, bytes memory signature) internal pure returns (address, RecoverError) {\\n // Check the signature length\\n // - case 65: r,s,v signature (standard)\\n // - case 64: r,vs signature (cf https://eips.ethereum.org/EIPS/eip-2098) _Available since v4.1._\\n if (signature.length == 65) {\\n bytes32 r;\\n bytes32 s;\\n uint8 v;\\n // ecrecover takes the signature parameters, and the only way to get them\\n // currently is to use assembly.\\n assembly {\\n r := mload(add(signature, 0x20))\\n s := mload(add(signature, 0x40))\\n v := byte(0, mload(add(signature, 0x60)))\\n }\\n return tryRecover(hash, v, r, s);\\n } else if (signature.length == 64) {\\n bytes32 r;\\n bytes32 vs;\\n // ecrecover takes the signature parameters, and the only way to get them\\n // currently is to use assembly.\\n assembly {\\n r := mload(add(signature, 0x20))\\n vs := mload(add(signature, 0x40))\\n }\\n return tryRecover(hash, r, vs);\\n } else {\\n return (address(0), RecoverError.InvalidSignatureLength);\\n }\\n }\\n\\n /**\\n * @dev Returns the address that signed a hashed message (`hash`) with\\n * `signature`. This address can then be used for verification purposes.\\n *\\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\\n * this function rejects them by requiring the `s` value to be in the lower\\n * half order, and the `v` value to be either 27 or 28.\\n *\\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\\n * verification to be secure: it is possible to craft signatures that\\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\\n * this is by receiving a hash of the original message (which may otherwise\\n * be too long), and then calling {toEthSignedMessageHash} on it.\\n */\\n function recover(bytes32 hash, bytes memory signature) internal pure returns (address) {\\n (address recovered, RecoverError error) = tryRecover(hash, signature);\\n _throwError(error);\\n return recovered;\\n }\\n\\n /**\\n * @dev Overload of {ECDSA-tryRecover} that receives the `r` and `vs` short-signature fields separately.\\n *\\n * See https://eips.ethereum.org/EIPS/eip-2098[EIP-2098 short signatures]\\n *\\n * _Available since v4.3._\\n */\\n function tryRecover(\\n bytes32 hash,\\n bytes32 r,\\n bytes32 vs\\n ) internal pure returns (address, RecoverError) {\\n bytes32 s;\\n uint8 v;\\n assembly {\\n s := and(vs, 0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff)\\n v := add(shr(255, vs), 27)\\n }\\n return tryRecover(hash, v, r, s);\\n }\\n\\n /**\\n * @dev Overload of {ECDSA-recover} that receives the `r and `vs` short-signature fields separately.\\n *\\n * _Available since v4.2._\\n */\\n function recover(\\n bytes32 hash,\\n bytes32 r,\\n bytes32 vs\\n ) internal pure returns (address) {\\n (address recovered, RecoverError error) = tryRecover(hash, r, vs);\\n _throwError(error);\\n return recovered;\\n }\\n\\n /**\\n * @dev Overload of {ECDSA-tryRecover} that receives the `v`,\\n * `r` and `s` signature fields separately.\\n *\\n * _Available since v4.3._\\n */\\n function tryRecover(\\n bytes32 hash,\\n uint8 v,\\n bytes32 r,\\n bytes32 s\\n ) internal pure returns (address, RecoverError) {\\n // EIP-2 still allows signature malleability for ecrecover(). Remove this possibility and make the signature\\n // unique. Appendix F in the Ethereum Yellow paper (https://ethereum.github.io/yellowpaper/paper.pdf), defines\\n // the valid range for s in (301): 0 < s < secp256k1n \\u00f7 2 + 1, and for v in (302): v \\u2208 {27, 28}. Most\\n // signatures from current libraries generate a unique signature with an s-value in the lower half order.\\n //\\n // If your library generates malleable signatures, such as s-values in the upper range, calculate a new s-value\\n // with 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141 - s1 and flip v from 27 to 28 or\\n // vice versa. If your library also generates signatures with 0/1 for v instead 27/28, add 27 to v to accept\\n // these malleable signatures as well.\\n if (uint256(s) > 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D576E7357A4501DDFE92F46681B20A0) {\\n return (address(0), RecoverError.InvalidSignatureS);\\n }\\n if (v != 27 && v != 28) {\\n return (address(0), RecoverError.InvalidSignatureV);\\n }\\n\\n // If the signature is valid (and not malleable), return the signer address\\n address signer = ecrecover(hash, v, r, s);\\n if (signer == address(0)) {\\n return (address(0), RecoverError.InvalidSignature);\\n }\\n\\n return (signer, RecoverError.NoError);\\n }\\n\\n /**\\n * @dev Overload of {ECDSA-recover} that receives the `v`,\\n * `r` and `s` signature fields separately.\\n */\\n function recover(\\n bytes32 hash,\\n uint8 v,\\n bytes32 r,\\n bytes32 s\\n ) internal pure returns (address) {\\n (address recovered, RecoverError error) = tryRecover(hash, v, r, s);\\n _throwError(error);\\n return recovered;\\n }\\n\\n /**\\n * @dev Returns an Ethereum Signed Message, created from a `hash`. This\\n * produces hash corresponding to the one signed with the\\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\\n * JSON-RPC method as part of EIP-191.\\n *\\n * See {recover}.\\n */\\n function toEthSignedMessageHash(bytes32 hash) internal pure returns (bytes32) {\\n // 32 is the length in bytes of hash,\\n // enforced by the type signature above\\n return keccak256(abi.encodePacked(\\\"\\\\x19Ethereum Signed Message:\\\\n32\\\", hash));\\n }\\n\\n /**\\n * @dev Returns an Ethereum Signed Message, created from `s`. This\\n * produces hash corresponding to the one signed with the\\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\\n * JSON-RPC method as part of EIP-191.\\n *\\n * See {recover}.\\n */\\n function toEthSignedMessageHash(bytes memory s) internal pure returns (bytes32) {\\n return keccak256(abi.encodePacked(\\\"\\\\x19Ethereum Signed Message:\\\\n\\\", StringsUpgradeable.toString(s.length), s));\\n }\\n\\n /**\\n * @dev Returns an Ethereum Signed Typed Data, created from a\\n * `domainSeparator` and a `structHash`. This produces hash corresponding\\n * to the one signed with the\\n * https://eips.ethereum.org/EIPS/eip-712[`eth_signTypedData`]\\n * JSON-RPC method as part of EIP-712.\\n *\\n * See {recover}.\\n */\\n function toTypedDataHash(bytes32 domainSeparator, bytes32 structHash) internal pure returns (bytes32) {\\n return keccak256(abi.encodePacked(\\\"\\\\x19\\\\x01\\\", domainSeparator, structHash));\\n }\\n}\\n\",\"keccak256\":\"0x1762ac67d230279d7fb183567ce22bbe202054ce08f94224d8794f9d19546d51\",\"license\":\"MIT\"},\"@openzeppelin/contracts-upgradeable/utils/cryptography/draft-EIP712Upgradeable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (utils/cryptography/draft-EIP712.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"./ECDSAUpgradeable.sol\\\";\\nimport \\\"../../proxy/utils/Initializable.sol\\\";\\n\\n/**\\n * @dev https://eips.ethereum.org/EIPS/eip-712[EIP 712] is a standard for hashing and signing of typed structured data.\\n *\\n * The encoding specified in the EIP is very generic, and such a generic implementation in Solidity is not feasible,\\n * thus this contract does not implement the encoding itself. Protocols need to implement the type-specific encoding\\n * they need in their contracts using a combination of `abi.encode` and `keccak256`.\\n *\\n * This contract implements the EIP 712 domain separator ({_domainSeparatorV4}) that is used as part of the encoding\\n * scheme, and the final step of the encoding to obtain the message digest that is then signed via ECDSA\\n * ({_hashTypedDataV4}).\\n *\\n * The implementation of the domain separator was designed to be as efficient as possible while still properly updating\\n * the chain id to protect against replay attacks on an eventual fork of the chain.\\n *\\n * NOTE: This contract implements the version of the encoding known as \\\"v4\\\", as implemented by the JSON RPC method\\n * https://docs.metamask.io/guide/signing-data.html[`eth_signTypedDataV4` in MetaMask].\\n *\\n * _Available since v3.4._\\n */\\nabstract contract EIP712Upgradeable is Initializable {\\n /* solhint-disable var-name-mixedcase */\\n bytes32 private _HASHED_NAME;\\n bytes32 private _HASHED_VERSION;\\n bytes32 private constant _TYPE_HASH = keccak256(\\\"EIP712Domain(string name,string version,uint256 chainId,address verifyingContract)\\\");\\n\\n /* solhint-enable var-name-mixedcase */\\n\\n /**\\n * @dev Initializes the domain separator and parameter caches.\\n *\\n * The meaning of `name` and `version` is specified in\\n * https://eips.ethereum.org/EIPS/eip-712#definition-of-domainseparator[EIP 712]:\\n *\\n * - `name`: the user readable name of the signing domain, i.e. the name of the DApp or the protocol.\\n * - `version`: the current major version of the signing domain.\\n *\\n * NOTE: These parameters cannot be changed except through a xref:learn::upgrading-smart-contracts.adoc[smart\\n * contract upgrade].\\n */\\n function __EIP712_init(string memory name, string memory version) internal onlyInitializing {\\n __EIP712_init_unchained(name, version);\\n }\\n\\n function __EIP712_init_unchained(string memory name, string memory version) internal onlyInitializing {\\n bytes32 hashedName = keccak256(bytes(name));\\n bytes32 hashedVersion = keccak256(bytes(version));\\n _HASHED_NAME = hashedName;\\n _HASHED_VERSION = hashedVersion;\\n }\\n\\n /**\\n * @dev Returns the domain separator for the current chain.\\n */\\n function _domainSeparatorV4() internal view returns (bytes32) {\\n return _buildDomainSeparator(_TYPE_HASH, _EIP712NameHash(), _EIP712VersionHash());\\n }\\n\\n function _buildDomainSeparator(\\n bytes32 typeHash,\\n bytes32 nameHash,\\n bytes32 versionHash\\n ) private view returns (bytes32) {\\n return keccak256(abi.encode(typeHash, nameHash, versionHash, block.chainid, address(this)));\\n }\\n\\n /**\\n * @dev Given an already https://eips.ethereum.org/EIPS/eip-712#definition-of-hashstruct[hashed struct], this\\n * function returns the hash of the fully encoded EIP712 message for this domain.\\n *\\n * This hash can be used together with {ECDSA-recover} to obtain the signer of a message. For example:\\n *\\n * ```solidity\\n * bytes32 digest = _hashTypedDataV4(keccak256(abi.encode(\\n * keccak256(\\\"Mail(address to,string contents)\\\"),\\n * mailTo,\\n * keccak256(bytes(mailContents))\\n * )));\\n * address signer = ECDSA.recover(digest, signature);\\n * ```\\n */\\n function _hashTypedDataV4(bytes32 structHash) internal view virtual returns (bytes32) {\\n return ECDSAUpgradeable.toTypedDataHash(_domainSeparatorV4(), structHash);\\n }\\n\\n /**\\n * @dev The hash of the name parameter for the EIP712 domain.\\n *\\n * NOTE: This function reads from storage by default, but can be redefined to return a constant value if gas costs\\n * are a concern.\\n */\\n function _EIP712NameHash() internal virtual view returns (bytes32) {\\n return _HASHED_NAME;\\n }\\n\\n /**\\n * @dev The hash of the version parameter for the EIP712 domain.\\n *\\n * NOTE: This function reads from storage by default, but can be redefined to return a constant value if gas costs\\n * are a concern.\\n */\\n function _EIP712VersionHash() internal virtual view returns (bytes32) {\\n return _HASHED_VERSION;\\n }\\n uint256[50] private __gap;\\n}\\n\",\"keccak256\":\"0x92e61d8dd5ba90b513769c06da820e0a8f5d93810a9c6d5207308af345815011\",\"license\":\"MIT\"},\"@openzeppelin/contracts/token/ERC20/IERC20.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (token/ERC20/IERC20.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Interface of the ERC20 standard as defined in the EIP.\\n */\\ninterface IERC20 {\\n /**\\n * @dev Returns the amount of tokens in existence.\\n */\\n function totalSupply() external view returns (uint256);\\n\\n /**\\n * @dev Returns the amount of tokens owned by `account`.\\n */\\n function balanceOf(address account) external view returns (uint256);\\n\\n /**\\n * @dev Moves `amount` tokens from the caller's account to `recipient`.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * Emits a {Transfer} event.\\n */\\n function transfer(address recipient, uint256 amount) external returns (bool);\\n\\n /**\\n * @dev Returns the remaining number of tokens that `spender` will be\\n * allowed to spend on behalf of `owner` through {transferFrom}. This is\\n * zero by default.\\n *\\n * This value changes when {approve} or {transferFrom} are called.\\n */\\n function allowance(address owner, address spender) external view returns (uint256);\\n\\n /**\\n * @dev Sets `amount` as the allowance of `spender` over the caller's tokens.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * IMPORTANT: Beware that changing an allowance with this method brings the risk\\n * that someone may use both the old and the new allowance by unfortunate\\n * transaction ordering. One possible solution to mitigate this race\\n * condition is to first reduce the spender's allowance to 0 and set the\\n * desired value afterwards:\\n * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729\\n *\\n * Emits an {Approval} event.\\n */\\n function approve(address spender, uint256 amount) external returns (bool);\\n\\n /**\\n * @dev Moves `amount` tokens from `sender` to `recipient` using the\\n * allowance mechanism. `amount` is then deducted from the caller's\\n * allowance.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * Emits a {Transfer} event.\\n */\\n function transferFrom(\\n address sender,\\n address recipient,\\n uint256 amount\\n ) external returns (bool);\\n\\n /**\\n * @dev Emitted when `value` tokens are moved from one account (`from`) to\\n * another (`to`).\\n *\\n * Note that `value` may be zero.\\n */\\n event Transfer(address indexed from, address indexed to, uint256 value);\\n\\n /**\\n * @dev Emitted when the allowance of a `spender` for an `owner` is set by\\n * a call to {approve}. `value` is the new allowance.\\n */\\n event Approval(address indexed owner, address indexed spender, uint256 value);\\n}\\n\",\"keccak256\":\"0x61437cb513a887a1bbad006e7b1c8b414478427d33de47c5600af3c748f108da\",\"license\":\"MIT\"},\"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (token/ERC20/utils/SafeERC20.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../IERC20.sol\\\";\\nimport \\\"../../../utils/Address.sol\\\";\\n\\n/**\\n * @title SafeERC20\\n * @dev Wrappers around ERC20 operations that throw on failure (when the token\\n * contract returns false). Tokens that return no value (and instead revert or\\n * throw on failure) are also supported, non-reverting calls are assumed to be\\n * successful.\\n * To use this library you can add a `using SafeERC20 for IERC20;` statement to your contract,\\n * which allows you to call the safe operations as `token.safeTransfer(...)`, etc.\\n */\\nlibrary SafeERC20 {\\n using Address for address;\\n\\n function safeTransfer(\\n IERC20 token,\\n address to,\\n uint256 value\\n ) internal {\\n _callOptionalReturn(token, abi.encodeWithSelector(token.transfer.selector, to, value));\\n }\\n\\n function safeTransferFrom(\\n IERC20 token,\\n address from,\\n address to,\\n uint256 value\\n ) internal {\\n _callOptionalReturn(token, abi.encodeWithSelector(token.transferFrom.selector, from, to, value));\\n }\\n\\n /**\\n * @dev Deprecated. This function has issues similar to the ones found in\\n * {IERC20-approve}, and its usage is discouraged.\\n *\\n * Whenever possible, use {safeIncreaseAllowance} and\\n * {safeDecreaseAllowance} instead.\\n */\\n function safeApprove(\\n IERC20 token,\\n address spender,\\n uint256 value\\n ) internal {\\n // safeApprove should only be called when setting an initial allowance,\\n // or when resetting it to zero. To increase and decrease it, use\\n // 'safeIncreaseAllowance' and 'safeDecreaseAllowance'\\n require(\\n (value == 0) || (token.allowance(address(this), spender) == 0),\\n \\\"SafeERC20: approve from non-zero to non-zero allowance\\\"\\n );\\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, value));\\n }\\n\\n function safeIncreaseAllowance(\\n IERC20 token,\\n address spender,\\n uint256 value\\n ) internal {\\n uint256 newAllowance = token.allowance(address(this), spender) + value;\\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));\\n }\\n\\n function safeDecreaseAllowance(\\n IERC20 token,\\n address spender,\\n uint256 value\\n ) internal {\\n unchecked {\\n uint256 oldAllowance = token.allowance(address(this), spender);\\n require(oldAllowance >= value, \\\"SafeERC20: decreased allowance below zero\\\");\\n uint256 newAllowance = oldAllowance - value;\\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));\\n }\\n }\\n\\n /**\\n * @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement\\n * on the return value: the return value is optional (but if data is returned, it must not be false).\\n * @param token The token targeted by the call.\\n * @param data The call data (encoded using abi.encode or one of its variants).\\n */\\n function _callOptionalReturn(IERC20 token, bytes memory data) private {\\n // We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since\\n // we're implementing it ourselves. We use {Address.functionCall} to perform this call, which verifies that\\n // the target address contains contract code and also asserts for success in the low-level call.\\n\\n bytes memory returndata = address(token).functionCall(data, \\\"SafeERC20: low-level call failed\\\");\\n if (returndata.length > 0) {\\n // Return data is optional\\n require(abi.decode(returndata, (bool)), \\\"SafeERC20: ERC20 operation did not succeed\\\");\\n }\\n }\\n}\\n\",\"keccak256\":\"0xc3d946432c0ddbb1f846a0d3985be71299df331b91d06732152117f62f0be2b5\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/Address.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (utils/Address.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Collection of functions related to the address type\\n */\\nlibrary Address {\\n /**\\n * @dev Returns true if `account` is a contract.\\n *\\n * [IMPORTANT]\\n * ====\\n * It is unsafe to assume that an address for which this function returns\\n * false is an externally-owned account (EOA) and not a contract.\\n *\\n * Among others, `isContract` will return false for the following\\n * types of addresses:\\n *\\n * - an externally-owned account\\n * - a contract in construction\\n * - an address where a contract will be created\\n * - an address where a contract lived, but was destroyed\\n * ====\\n */\\n function isContract(address account) internal view returns (bool) {\\n // This method relies on extcodesize, which returns 0 for contracts in\\n // construction, since the code is only stored at the end of the\\n // constructor execution.\\n\\n uint256 size;\\n assembly {\\n size := extcodesize(account)\\n }\\n return size > 0;\\n }\\n\\n /**\\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\\n * `recipient`, forwarding all available gas and reverting on errors.\\n *\\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\\n * imposed by `transfer`, making them unable to receive funds via\\n * `transfer`. {sendValue} removes this limitation.\\n *\\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\\n *\\n * IMPORTANT: because control is transferred to `recipient`, care must be\\n * taken to not create reentrancy vulnerabilities. Consider using\\n * {ReentrancyGuard} or the\\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\\n */\\n function sendValue(address payable recipient, uint256 amount) internal {\\n require(address(this).balance >= amount, \\\"Address: insufficient balance\\\");\\n\\n (bool success, ) = recipient.call{value: amount}(\\\"\\\");\\n require(success, \\\"Address: unable to send value, recipient may have reverted\\\");\\n }\\n\\n /**\\n * @dev Performs a Solidity function call using a low level `call`. A\\n * plain `call` is an unsafe replacement for a function call: use this\\n * function instead.\\n *\\n * If `target` reverts with a revert reason, it is bubbled up by this\\n * function (like regular Solidity function calls).\\n *\\n * Returns the raw returned data. To convert to the expected return value,\\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\\n *\\n * Requirements:\\n *\\n * - `target` must be a contract.\\n * - calling `target` with `data` must not revert.\\n *\\n * _Available since v3.1._\\n */\\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\\n return functionCall(target, data, \\\"Address: low-level call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\\n * `errorMessage` as a fallback revert reason when `target` reverts.\\n *\\n * _Available since v3.1._\\n */\\n function functionCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n return functionCallWithValue(target, data, 0, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but also transferring `value` wei to `target`.\\n *\\n * Requirements:\\n *\\n * - the calling contract must have an ETH balance of at least `value`.\\n * - the called Solidity function must be `payable`.\\n *\\n * _Available since v3.1._\\n */\\n function functionCallWithValue(\\n address target,\\n bytes memory data,\\n uint256 value\\n ) internal returns (bytes memory) {\\n return functionCallWithValue(target, data, value, \\\"Address: low-level call with value failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\\n * with `errorMessage` as a fallback revert reason when `target` reverts.\\n *\\n * _Available since v3.1._\\n */\\n function functionCallWithValue(\\n address target,\\n bytes memory data,\\n uint256 value,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n require(address(this).balance >= value, \\\"Address: insufficient balance for call\\\");\\n require(isContract(target), \\\"Address: call to non-contract\\\");\\n\\n (bool success, bytes memory returndata) = target.call{value: value}(data);\\n return verifyCallResult(success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but performing a static call.\\n *\\n * _Available since v3.3._\\n */\\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\\n return functionStaticCall(target, data, \\\"Address: low-level static call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\\n * but performing a static call.\\n *\\n * _Available since v3.3._\\n */\\n function functionStaticCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal view returns (bytes memory) {\\n require(isContract(target), \\\"Address: static call to non-contract\\\");\\n\\n (bool success, bytes memory returndata) = target.staticcall(data);\\n return verifyCallResult(success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but performing a delegate call.\\n *\\n * _Available since v3.4._\\n */\\n function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {\\n return functionDelegateCall(target, data, \\\"Address: low-level delegate call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\\n * but performing a delegate call.\\n *\\n * _Available since v3.4._\\n */\\n function functionDelegateCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n require(isContract(target), \\\"Address: delegate call to non-contract\\\");\\n\\n (bool success, bytes memory returndata) = target.delegatecall(data);\\n return verifyCallResult(success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the\\n * revert reason using the provided one.\\n *\\n * _Available since v4.3._\\n */\\n function verifyCallResult(\\n bool success,\\n bytes memory returndata,\\n string memory errorMessage\\n ) internal pure returns (bytes memory) {\\n if (success) {\\n return returndata;\\n } else {\\n // Look for revert reason and bubble it up if present\\n if (returndata.length > 0) {\\n // The easiest way to bubble the revert reason is using memory via assembly\\n\\n assembly {\\n let returndata_size := mload(returndata)\\n revert(add(32, returndata), returndata_size)\\n }\\n } else {\\n revert(errorMessage);\\n }\\n }\\n }\\n}\\n\",\"keccak256\":\"0x51b758a8815ecc9596c66c37d56b1d33883a444631a3f916b9fe65cb863ef7c4\",\"license\":\"MIT\"},\"contracts/agToken/AgTokenSideChainMultiBridge.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-3.0\\n\\npragma solidity 0.8.12;\\n\\nimport \\\"./BaseAgTokenSideChain.sol\\\";\\nimport \\\"@openzeppelin/contracts/token/ERC20/IERC20.sol\\\";\\nimport \\\"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\\\";\\n\\n/// @title AgTokenSideChainMultiBridge\\n/// @author Angle Core Team\\n/// @notice Contract for Angle agTokens on other chains than Ethereum mainnet\\n/// @dev This contract supports bridge tokens having a minting right on the stablecoin (also referred to as the canonical\\n/// or the native token)\\n/// @dev References:\\n/// - FRAX implementation: https://polygonscan.com/address/0x45c32fA6DF82ead1e2EF74d17b76547EDdFaFF89#code\\n/// - QiDAO implementation: https://snowtrace.io/address/0x5c49b268c9841AFF1Cc3B0a418ff5c3442eE3F3b#code\\ncontract AgTokenSideChainMultiBridge is BaseAgTokenSideChain {\\n using SafeERC20 for IERC20;\\n\\n /// @notice Base used for fee computation\\n uint256 public constant BASE_PARAMS = 10**9;\\n\\n // =============================== Bridging Data ===============================\\n\\n /// @notice Struct with some data about a specific bridge token\\n struct BridgeDetails {\\n // Limit on the balance of bridge token held by the contract: it is designed\\n // to reduce the exposure of the system to hacks\\n uint256 limit;\\n // Limit on the hourly volume of token minted through this bridge\\n // Technically the limit over a rolling hour is hourlyLimit x2 as hourly limit\\n // is enforced only between x:00 and x+1:00\\n uint256 hourlyLimit;\\n // Fee taken for swapping in and out the token\\n uint64 fee;\\n // Whether the associated token is allowed or not\\n bool allowed;\\n // Whether swapping in and out from the associated token is paused or not\\n bool paused;\\n }\\n\\n /// @notice Maps a bridge token to data\\n mapping(address => BridgeDetails) public bridges;\\n /// @notice List of all bridge tokens\\n address[] public bridgeTokensList;\\n /// @notice Maps a bridge token to the associated hourly volume\\n mapping(address => mapping(uint256 => uint256)) public usage;\\n /// @notice Maps an address to whether it is exempt of fees for when it comes to swapping in and out\\n mapping(address => uint256) public isFeeExempt;\\n /// @notice Limit to the amount of tokens that can be sent from that chain to another chain\\n uint256 public chainTotalHourlyLimit;\\n /// @notice Usage per hour on that chain. Maps an hourly timestamp to the total volume swapped out on the chain\\n mapping(uint256 => uint256) public chainTotalUsage;\\n\\n // ================================== Events ===================================\\n\\n event BridgeTokenAdded(address indexed bridgeToken, uint256 limit, uint256 hourlyLimit, uint64 fee, bool paused);\\n event BridgeTokenToggled(address indexed bridgeToken, bool toggleStatus);\\n event BridgeTokenRemoved(address indexed bridgeToken);\\n event BridgeTokenFeeUpdated(address indexed bridgeToken, uint64 fee);\\n event BridgeTokenLimitUpdated(address indexed bridgeToken, uint256 limit);\\n event BridgeTokenHourlyLimitUpdated(address indexed bridgeToken, uint256 hourlyLimit);\\n event HourlyLimitUpdated(uint256 hourlyLimit);\\n event Recovered(address indexed token, address indexed to, uint256 amount);\\n event FeeToggled(address indexed theAddress, uint256 toggleStatus);\\n\\n // =============================== Errors ================================\\n\\n error AssetStillControlledInReserves();\\n error HourlyLimitExceeded();\\n error InvalidToken();\\n error NotGovernor();\\n error NotGovernorOrGuardian();\\n error TooBigAmount();\\n error TooHighParameterValue();\\n error ZeroAddress();\\n\\n // ============================= Constructor ===================================\\n\\n /// @notice Initializes the `AgToken` contract\\n /// @param name_ Name of the token\\n /// @param symbol_ Symbol of the token\\n /// @param _treasury Reference to the `Treasury` contract associated to this agToken\\n /// @dev By default, agTokens are ERC-20 tokens with 18 decimals\\n function initialize(\\n string memory name_,\\n string memory symbol_,\\n address _treasury\\n ) external {\\n _initialize(name_, symbol_, _treasury);\\n }\\n\\n // =============================== Modifiers ===================================\\n\\n /// @notice Checks whether the `msg.sender` has the governor role or not\\n modifier onlyGovernor() {\\n if (!ITreasury(treasury).isGovernor(msg.sender)) revert NotGovernor();\\n _;\\n }\\n\\n /// @notice Checks whether the `msg.sender` has the governor role or the guardian role\\n modifier onlyGovernorOrGuardian() {\\n if (!ITreasury(treasury).isGovernorOrGuardian(msg.sender)) revert NotGovernorOrGuardian();\\n _;\\n }\\n\\n // ==================== External Permissionless Functions ======================\\n\\n /// @notice Returns the list of all supported bridge tokens\\n /// @dev Helpful for UIs\\n function allBridgeTokens() external view returns (address[] memory) {\\n return bridgeTokensList;\\n }\\n\\n /// @notice Returns the current volume for a bridge, for the current hour\\n /// @param bridgeToken Bridge used to mint\\n /// @dev Helpful for UIs\\n function currentUsage(address bridgeToken) external view returns (uint256) {\\n return usage[bridgeToken][block.timestamp / 3600];\\n }\\n\\n /// @notice Returns the current total volume on the chain for the current hour\\n /// @dev Helpful for UIs\\n function currentTotalUsage() external view returns (uint256) {\\n return chainTotalUsage[block.timestamp / 3600];\\n }\\n\\n /// @notice Mints the canonical token from a supported bridge token\\n /// @param bridgeToken Bridge token to use to mint\\n /// @param amount Amount of bridge tokens to send\\n /// @param to Address to which the stablecoin should be sent\\n /// @return Amount of the canonical stablecoin actually minted\\n /// @dev Some fees may be taken by the protocol depending on the token used and on the address calling\\n function swapIn(\\n address bridgeToken,\\n uint256 amount,\\n address to\\n ) external returns (uint256) {\\n BridgeDetails memory bridgeDetails = bridges[bridgeToken];\\n if (!bridgeDetails.allowed || bridgeDetails.paused) revert InvalidToken();\\n uint256 balance = IERC20(bridgeToken).balanceOf(address(this));\\n if (balance + amount > bridgeDetails.limit) {\\n // In case someone maliciously sends tokens to this contract\\n // Or the limit changes\\n if (bridgeDetails.limit > balance) amount = bridgeDetails.limit - balance;\\n else {\\n amount = 0;\\n }\\n }\\n\\n // Checking requirement on the hourly volume\\n uint256 hour = block.timestamp / 3600;\\n uint256 hourlyUsage = usage[bridgeToken][hour] + amount;\\n if (hourlyUsage > bridgeDetails.hourlyLimit) {\\n // Edge case when the hourly limit changes\\n if (bridgeDetails.hourlyLimit > usage[bridgeToken][hour])\\n amount = bridgeDetails.hourlyLimit - usage[bridgeToken][hour];\\n else {\\n amount = 0;\\n }\\n }\\n usage[bridgeToken][hour] = usage[bridgeToken][hour] + amount;\\n\\n IERC20(bridgeToken).safeTransferFrom(msg.sender, address(this), amount);\\n uint256 canonicalOut = amount;\\n // Computing fees\\n if (isFeeExempt[msg.sender] == 0) {\\n canonicalOut -= (canonicalOut * bridgeDetails.fee) / BASE_PARAMS;\\n }\\n _mint(to, canonicalOut);\\n return canonicalOut;\\n }\\n\\n /// @notice Burns the canonical token in exchange for a bridge token\\n /// @param bridgeToken Bridge token required\\n /// @param amount Amount of canonical tokens to burn\\n /// @param to Address to which the bridge token should be sent\\n /// @return Amount of bridge tokens actually sent back\\n /// @dev Some fees may be taken by the protocol depending on the token used and on the address calling\\n function swapOut(\\n address bridgeToken,\\n uint256 amount,\\n address to\\n ) external returns (uint256) {\\n BridgeDetails memory bridgeDetails = bridges[bridgeToken];\\n if (!bridgeDetails.allowed || bridgeDetails.paused) revert InvalidToken();\\n\\n uint256 hour = block.timestamp / 3600;\\n uint256 hourlyUsage = chainTotalUsage[hour] + amount;\\n // If the amount being swapped out exceeds the limit, we revert\\n // We don't want to change the amount being swapped out.\\n // The user can decide to send another tx with the correct amount to reach the limit\\n if (hourlyUsage > chainTotalHourlyLimit) revert HourlyLimitExceeded();\\n chainTotalUsage[hour] = hourlyUsage;\\n\\n _burn(msg.sender, amount);\\n uint256 bridgeOut = amount;\\n if (isFeeExempt[msg.sender] == 0) {\\n bridgeOut -= (bridgeOut * bridgeDetails.fee) / BASE_PARAMS;\\n }\\n IERC20(bridgeToken).safeTransfer(to, bridgeOut);\\n return bridgeOut;\\n }\\n\\n // ======================= Governance Functions ================================\\n\\n /// @notice Adds support for a bridge token\\n /// @param bridgeToken Bridge token to add: it should be a version of the stablecoin from another bridge\\n /// @param limit Limit on the balance of bridge token this contract could hold\\n /// @param hourlyLimit Limit on the hourly volume for this bridge\\n /// @param paused Whether swapping for this token should be paused or not\\n /// @param fee Fee taken upon swapping for or against this token\\n function addBridgeToken(\\n address bridgeToken,\\n uint256 limit,\\n uint256 hourlyLimit,\\n uint64 fee,\\n bool paused\\n ) external onlyGovernor {\\n if (bridges[bridgeToken].allowed || bridgeToken == address(0)) revert InvalidToken();\\n if (fee > BASE_PARAMS) revert TooHighParameterValue();\\n BridgeDetails memory _bridge;\\n _bridge.limit = limit;\\n _bridge.hourlyLimit = hourlyLimit;\\n _bridge.paused = paused;\\n _bridge.fee = fee;\\n _bridge.allowed = true;\\n bridges[bridgeToken] = _bridge;\\n bridgeTokensList.push(bridgeToken);\\n emit BridgeTokenAdded(bridgeToken, limit, hourlyLimit, fee, paused);\\n }\\n\\n /// @notice Removes support for a token\\n /// @param bridgeToken Address of the bridge token to remove support for\\n function removeBridgeToken(address bridgeToken) external onlyGovernor {\\n if (IERC20(bridgeToken).balanceOf(address(this)) != 0) revert AssetStillControlledInReserves();\\n delete bridges[bridgeToken];\\n // Deletion from `bridgeTokensList` loop\\n uint256 bridgeTokensListLength = bridgeTokensList.length;\\n for (uint256 i = 0; i < bridgeTokensListLength - 1; i++) {\\n if (bridgeTokensList[i] == bridgeToken) {\\n // Replace the `bridgeToken` to remove with the last of the list\\n bridgeTokensList[i] = bridgeTokensList[bridgeTokensListLength - 1];\\n break;\\n }\\n }\\n // Remove last element in array\\n bridgeTokensList.pop();\\n emit BridgeTokenRemoved(bridgeToken);\\n }\\n\\n /// @notice Recovers any ERC20 token\\n /// @dev Can be used to withdraw bridge tokens for them to be de-bridged on mainnet\\n function recoverERC20(\\n address tokenAddress,\\n address to,\\n uint256 amountToRecover\\n ) external onlyGovernor {\\n IERC20(tokenAddress).safeTransfer(to, amountToRecover);\\n emit Recovered(tokenAddress, to, amountToRecover);\\n }\\n\\n /// @notice Updates the `limit` amount for `bridgeToken`\\n function setLimit(address bridgeToken, uint256 limit) external onlyGovernorOrGuardian {\\n if (!bridges[bridgeToken].allowed) revert InvalidToken();\\n bridges[bridgeToken].limit = limit;\\n emit BridgeTokenLimitUpdated(bridgeToken, limit);\\n }\\n\\n /// @notice Updates the `hourlyLimit` amount for `bridgeToken`\\n function setHourlyLimit(address bridgeToken, uint256 hourlyLimit) external onlyGovernorOrGuardian {\\n if (!bridges[bridgeToken].allowed) revert InvalidToken();\\n bridges[bridgeToken].hourlyLimit = hourlyLimit;\\n emit BridgeTokenHourlyLimitUpdated(bridgeToken, hourlyLimit);\\n }\\n\\n /// @notice Updates the `chainTotalHourlyLimit` amount\\n function setChainTotalHourlyLimit(uint256 hourlyLimit) external onlyGovernorOrGuardian {\\n chainTotalHourlyLimit = hourlyLimit;\\n emit HourlyLimitUpdated(hourlyLimit);\\n }\\n\\n /// @notice Updates the `fee` value for `bridgeToken`\\n function setSwapFee(address bridgeToken, uint64 fee) external onlyGovernorOrGuardian {\\n if (!bridges[bridgeToken].allowed) revert InvalidToken();\\n if (fee > BASE_PARAMS) revert TooHighParameterValue();\\n bridges[bridgeToken].fee = fee;\\n emit BridgeTokenFeeUpdated(bridgeToken, fee);\\n }\\n\\n /// @notice Pauses or unpauses swapping in and out for a token\\n function toggleBridge(address bridgeToken) external onlyGovernorOrGuardian {\\n if (!bridges[bridgeToken].allowed) revert InvalidToken();\\n bool pausedStatus = bridges[bridgeToken].paused;\\n bridges[bridgeToken].paused = !pausedStatus;\\n emit BridgeTokenToggled(bridgeToken, !pausedStatus);\\n }\\n\\n /// @notice Toggles fees for the address `theAddress`\\n function toggleFeesForAddress(address theAddress) external onlyGovernorOrGuardian {\\n uint256 feeExemptStatus = 1 - isFeeExempt[theAddress];\\n isFeeExempt[theAddress] = feeExemptStatus;\\n emit FeeToggled(theAddress, feeExemptStatus);\\n }\\n}\\n\",\"keccak256\":\"0xf2f2d77a9504fa20ef62faae227c548cc32d8f796ef427864ec79580617d0cb3\",\"license\":\"GPL-3.0\"},\"contracts/agToken/BaseAgTokenSideChain.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-3.0\\n\\npragma solidity 0.8.12;\\n\\nimport \\\"../interfaces/IAgToken.sol\\\";\\nimport \\\"../interfaces/ITreasury.sol\\\";\\nimport \\\"@openzeppelin/contracts-upgradeable/token/ERC20/extensions/draft-ERC20PermitUpgradeable.sol\\\";\\n\\n/// @title BaseAgTokenSideChain\\n/// @author Angle Core Team\\n/// @notice Base Contract for Angle agTokens on other chains than Ethereum mainnet\\n/// @dev This type of contract can be used to create and handle the stablecoins of Angle protocol in different chains than Ethereum\\ncontract BaseAgTokenSideChain is IAgToken, ERC20PermitUpgradeable {\\n // ======================= Parameters and Variables ============================\\n\\n /// @inheritdoc IAgToken\\n mapping(address => bool) public isMinter;\\n /// @notice Reference to the treasury contract which can grant minting rights\\n address public treasury;\\n\\n // ================================== Events ===================================\\n\\n event TreasuryUpdated(address indexed _treasury);\\n event MinterToggled(address indexed minter);\\n\\n // =============================== Errors ================================\\n\\n error BurnAmountExceedsAllowance();\\n error InvalidSender();\\n error InvalidTreasury();\\n error NotMinter();\\n error NotTreasury();\\n\\n // ============================= Constructor ===================================\\n\\n /// @notice Initializes the contract\\n /// @param name_ Name of the token\\n /// @param symbol_ Symbol of the token\\n /// @param _treasury Reference to the `Treasury` contract associated to this agToken implementation\\n /// @dev By default, agTokens are ERC-20 tokens with 18 decimals\\n function _initialize(\\n string memory name_,\\n string memory symbol_,\\n address _treasury\\n ) internal initializer {\\n __ERC20Permit_init(name_);\\n __ERC20_init(name_, symbol_);\\n if (address(ITreasury(_treasury).stablecoin()) != address(this)) revert InvalidTreasury();\\n treasury = _treasury;\\n emit TreasuryUpdated(address(_treasury));\\n }\\n\\n /// @custom:oz-upgrades-unsafe-allow constructor\\n constructor() initializer {}\\n\\n // =============================== Modifiers ===================================\\n\\n /// @notice Checks to see if it is the `Treasury` calling this contract\\n /// @dev There is no Access Control here, because it can be handled cheaply through this modifier\\n modifier onlyTreasury() {\\n if (msg.sender != address(treasury)) revert NotTreasury();\\n _;\\n }\\n\\n /// @notice Checks whether the sender has the minting right\\n modifier onlyMinter() {\\n if (!isMinter[msg.sender]) revert NotMinter();\\n _;\\n }\\n\\n // =========================== External Function ===============================\\n\\n /// @notice Allows anyone to burn agToken without redeeming collateral back\\n /// @param amount Amount of stablecoins to burn\\n /// @dev This function can typically be called if there is a settlement mechanism to burn stablecoins\\n function burnStablecoin(uint256 amount) external {\\n _burn(msg.sender, amount);\\n }\\n\\n // ======================= Minter Role Only Functions ==========================\\n\\n /// @inheritdoc IAgToken\\n function burnSelf(uint256 amount, address burner) external onlyMinter {\\n _burn(burner, amount);\\n }\\n\\n /// @inheritdoc IAgToken\\n function burnFrom(\\n uint256 amount,\\n address burner,\\n address sender\\n ) external onlyMinter {\\n _burnFromNoRedeem(amount, burner, sender);\\n }\\n\\n /// @inheritdoc IAgToken\\n function mint(address account, uint256 amount) external onlyMinter {\\n _mint(account, amount);\\n }\\n\\n // ======================= Treasury Only Functions =============================\\n\\n /// @inheritdoc IAgToken\\n function addMinter(address minter) external onlyTreasury {\\n isMinter[minter] = true;\\n emit MinterToggled(minter);\\n }\\n\\n /// @inheritdoc IAgToken\\n function removeMinter(address minter) external {\\n if (msg.sender != address(treasury) && msg.sender != minter) revert InvalidSender();\\n isMinter[minter] = false;\\n emit MinterToggled(minter);\\n }\\n\\n /// @inheritdoc IAgToken\\n function setTreasury(address _treasury) external onlyTreasury {\\n treasury = _treasury;\\n emit TreasuryUpdated(_treasury);\\n }\\n\\n // ============================ Internal Function ==============================\\n\\n /// @notice Internal version of the function `burnFromNoRedeem`\\n /// @param amount Amount to burn\\n /// @dev It is at the level of this function that allowance checks are performed\\n function _burnFromNoRedeem(\\n uint256 amount,\\n address burner,\\n address sender\\n ) internal {\\n if (burner != sender) {\\n uint256 currentAllowance = allowance(burner, sender);\\n if (currentAllowance < amount) revert BurnAmountExceedsAllowance();\\n _approve(burner, sender, currentAllowance - amount);\\n }\\n _burn(burner, amount);\\n }\\n}\\n\",\"keccak256\":\"0xf54ef7218eba0e71f2b57da57956646f0227356fc18a55c8984f6c6a8f592077\",\"license\":\"GPL-3.0\"},\"contracts/interfaces/IAgToken.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-3.0\\n\\npragma solidity 0.8.12;\\n\\nimport \\\"@openzeppelin/contracts-upgradeable/token/ERC20/IERC20Upgradeable.sol\\\";\\n\\n/// @title IAgToken\\n/// @author Angle Core Team\\n/// @notice Interface for the stablecoins `AgToken` contracts\\n/// @dev This interface only contains functions of the `AgToken` contract which are called by other contracts\\n/// of this module or of the first module of the Angle Protocol\\ninterface IAgToken is IERC20Upgradeable {\\n // ======================= Minter Role Only Functions ===========================\\n\\n /// @notice Lets the `StableMaster` contract or another whitelisted contract mint agTokens\\n /// @param account Address to mint to\\n /// @param amount Amount to mint\\n /// @dev The contracts allowed to issue agTokens are the `StableMaster` contract, `VaultManager` contracts\\n /// associated to this stablecoin as well as the flash loan module (if activated) and potentially contracts\\n /// whitelisted by governance\\n function mint(address account, uint256 amount) external;\\n\\n /// @notice Burns `amount` tokens from a `burner` address after being asked to by `sender`\\n /// @param amount Amount of tokens to burn\\n /// @param burner Address to burn from\\n /// @param sender Address which requested the burn from `burner`\\n /// @dev This method is to be called by a contract with the minter right after being requested\\n /// to do so by a `sender` address willing to burn tokens from another `burner` address\\n /// @dev The method checks the allowance between the `sender` and the `burner`\\n function burnFrom(\\n uint256 amount,\\n address burner,\\n address sender\\n ) external;\\n\\n /// @notice Burns `amount` tokens from a `burner` address\\n /// @param amount Amount of tokens to burn\\n /// @param burner Address to burn from\\n /// @dev This method is to be called by a contract with a minter right on the AgToken after being\\n /// requested to do so by an address willing to burn tokens from its address\\n function burnSelf(uint256 amount, address burner) external;\\n\\n // ========================= Treasury Only Functions ===========================\\n\\n /// @notice Adds a minter in the contract\\n /// @param minter Minter address to add\\n /// @dev Zero address checks are performed directly in the `Treasury` contract\\n function addMinter(address minter) external;\\n\\n /// @notice Removes a minter from the contract\\n /// @param minter Minter address to remove\\n /// @dev This function can also be called by a minter wishing to revoke itself\\n function removeMinter(address minter) external;\\n\\n /// @notice Sets a new treasury contract\\n /// @param _treasury New treasury address\\n function setTreasury(address _treasury) external;\\n\\n // ========================= External functions ================================\\n\\n /// @notice Checks whether an address has the right to mint agTokens\\n /// @param minter Address for which the minting right should be checked\\n /// @return Whether the address has the right to mint agTokens or not\\n function isMinter(address minter) external view returns (bool);\\n}\\n\",\"keccak256\":\"0xcd50d86128e457543483981ea6127cb8dac03584b919614352aa89d7e991405c\",\"license\":\"GPL-3.0\"},\"contracts/interfaces/ICoreBorrow.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-3.0\\n\\npragma solidity 0.8.12;\\n\\n/// @title ICoreBorrow\\n/// @author Angle Core Team\\n/// @notice Interface for the `CoreBorrow` contract\\n/// @dev This interface only contains functions of the `CoreBorrow` contract which are called by other contracts\\n/// of this module\\ninterface ICoreBorrow {\\n /// @notice Checks if an address corresponds to a treasury of a stablecoin with a flash loan\\n /// module initialized on it\\n /// @param treasury Address to check\\n /// @return Whether the address has the `FLASHLOANER_TREASURY_ROLE` or not\\n function isFlashLoanerTreasury(address treasury) external view returns (bool);\\n\\n /// @notice Checks whether an address is governor of the Angle Protocol or not\\n /// @param admin Address to check\\n /// @return Whether the address has the `GOVERNOR_ROLE` or not\\n function isGovernor(address admin) external view returns (bool);\\n\\n /// @notice Checks whether an address is governor or a guardian of the Angle Protocol or not\\n /// @param admin Address to check\\n /// @return Whether the address has the `GUARDIAN_ROLE` or not\\n /// @dev Governance should make sure when adding a governor to also give this governor the guardian\\n /// role by calling the `addGovernor` function\\n function isGovernorOrGuardian(address admin) external view returns (bool);\\n}\\n\",\"keccak256\":\"0x25b65b3f506ca91745a444502a36f0556585d82d9d60f4bd32fbcaabc12840d4\",\"license\":\"GPL-3.0\"},\"contracts/interfaces/IFlashAngle.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-3.0\\n\\npragma solidity 0.8.12;\\n\\nimport \\\"./IAgToken.sol\\\";\\nimport \\\"./ICoreBorrow.sol\\\";\\n\\n/// @title IFlashAngle\\n/// @author Angle Core Team\\n/// @notice Interface for the `FlashAngle` contract\\n/// @dev This interface only contains functions of the contract which are called by other contracts\\n/// of this module\\ninterface IFlashAngle {\\n /// @notice Reference to the `CoreBorrow` contract managing the FlashLoan module\\n function core() external view returns (ICoreBorrow);\\n\\n /// @notice Sends the fees taken from flash loans to the treasury contract associated to the stablecoin\\n /// @param stablecoin Stablecoin from which profits should be sent\\n /// @return balance Amount of profits sent\\n /// @dev This function can only be called by the treasury contract\\n function accrueInterestToTreasury(IAgToken stablecoin) external returns (uint256 balance);\\n\\n /// @notice Adds support for a stablecoin\\n /// @param _treasury Treasury associated to the stablecoin to add support for\\n /// @dev This function can only be called by the `CoreBorrow` contract\\n function addStablecoinSupport(address _treasury) external;\\n\\n /// @notice Removes support for a stablecoin\\n /// @param _treasury Treasury associated to the stablecoin to remove support for\\n /// @dev This function can only be called by the `CoreBorrow` contract\\n function removeStablecoinSupport(address _treasury) external;\\n\\n /// @notice Sets a new core contract\\n /// @param _core Core contract address to set\\n /// @dev This function can only be called by the `CoreBorrow` contract\\n function setCore(address _core) external;\\n}\\n\",\"keccak256\":\"0xc17654e512897efe41e3f1173c07dd4676e8c699a72b859d14b473d1e8300e45\",\"license\":\"GPL-3.0\"},\"contracts/interfaces/ITreasury.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-3.0\\n\\npragma solidity 0.8.12;\\n\\nimport \\\"./IAgToken.sol\\\";\\nimport \\\"./ICoreBorrow.sol\\\";\\nimport \\\"./IFlashAngle.sol\\\";\\n\\n/// @title ITreasury\\n/// @author Angle Core Team\\n/// @notice Interface for the `Treasury` contract\\n/// @dev This interface only contains functions of the `Treasury` which are called by other contracts\\n/// of this module\\ninterface ITreasury {\\n /// @notice Stablecoin handled by this `treasury` contract\\n function stablecoin() external view returns (IAgToken);\\n\\n /// @notice Checks whether a given address has the governor role\\n /// @param admin Address to check\\n /// @return Whether the address has the governor role\\n /// @dev Access control is only kept in the `CoreBorrow` contract\\n function isGovernor(address admin) external view returns (bool);\\n\\n /// @notice Checks whether a given address has the guardian or the governor role\\n /// @param admin Address to check\\n /// @return Whether the address has the guardian or the governor role\\n /// @dev Access control is only kept in the `CoreBorrow` contract which means that this function\\n /// queries the `CoreBorrow` contract\\n function isGovernorOrGuardian(address admin) external view returns (bool);\\n\\n /// @notice Checks whether a given address has well been initialized in this contract\\n /// as a `VaultManager``\\n /// @param _vaultManager Address to check\\n /// @return Whether the address has been initialized or not\\n function isVaultManager(address _vaultManager) external view returns (bool);\\n\\n /// @notice Sets a new flash loan module for this stablecoin\\n /// @param _flashLoanModule Reference to the new flash loan module\\n /// @dev This function removes the minting right to the old flash loan module and grants\\n /// it to the new module\\n function setFlashLoanModule(address _flashLoanModule) external;\\n}\\n\",\"keccak256\":\"0xced9b7256fcbedc75682037e11ce51fe9116e5604794b8545e00dea0607629cc\",\"license\":\"GPL-3.0\"}},\"version\":1}", - "bytecode": "0x60806040523480156200001157600080fd5b50600054610100900460ff166200002f5760005460ff161562000039565b62000039620000de565b620000a15760405162461bcd60e51b815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201526d191e481a5b9a5d1a585b1a5e995960921b606482015260840160405180910390fd5b600054610100900460ff16158015620000c4576000805461ffff19166101011790555b8015620000d7576000805461ff00191690555b5062000102565b6000620000f630620000fc60201b620027c81760201c565b15905090565b3b151590565b61479b80620001126000396000f3fe608060405234801561001057600080fd5b50600436106102ff5760003560e01c806361d027b31161019c5780639f48118f116100ee578063ced67f0c11610097578063dd62ed3e11610071578063dd62ed3e14610724578063e3e286551461076a578063f0f442601461077d57600080fd5b8063ced67f0c1461066b578063d44ad63f146106fe578063d505accf1461071157600080fd5b8063aa271e1a116100c8578063aa271e1a14610620578063ba330bd714610643578063cd4839ca1461065657600080fd5b80639f48118f146105ef578063a457c2d7146105fa578063a9059cbb1461060d57600080fd5b80637ecebe001161015057806395d89b411161012a57806395d89b41146105c1578063983b2d56146105c95780639e4e0dae146105dc57600080fd5b80637ecebe00146105705780638933fb791461058357806390218cff146105ae57600080fd5b80637334d020116101815780637334d020146105425780637d4c9c2d146105555780637d74e25f1461056857600080fd5b806361d027b3146104c757806370a082311461050c57600080fd5b80633092afd511610255578063395093511161020957806340c10f19116101e357806340c10f19146104815780634dc32fcc146104945780635bfbec96146104a757600080fd5b8063395093511461043b5780633a55f89d1461044e5780633f4218e01461046157600080fd5b8063350ebe041161023a578063350ebe041461040d5780633644e5151461042057806336db43b51461042857600080fd5b80633092afd5146103eb578063313ce567146103fe57600080fd5b8063151dd755116102b757806323b872dd1161029157806323b872dd146103b25780632b471d8e146103c55780632e403e14146103d857600080fd5b8063151dd7551461038057806318160ddd146103a15780632342fb0e146103a957600080fd5b80630919a951116102e85780630919a95114610337578063095ea7b31461034a5780631171bda91461036d57600080fd5b806306fdde0314610304578063077f224a14610322575b600080fd5b61030c610790565b604051610319919061404a565b60405180910390f35b610335610330366004614197565b610822565b005b61033561034536600461420f565b610832565b61035d61035836600461422c565b610995565b6040519015158152602001610319565b61033561037b366004614258565b6109ab565b61039361038e366004614299565b610b00565b604051908152602001610319565b603554610393565b61039360d25481565b61035d6103c0366004614258565b610e51565b6103356103d33660046142d0565b610f3c565b6103356103e636600461420f565b610f93565b6103356103f936600461420f565b611345565b60405160128152602001610319565b61033561041b366004614300565b61142e565b610393611482565b61033561043636600461422c565b611491565b61035d61044936600461422c565b611621565b61033561045c366004614337565b61166a565b61039361046f36600461420f565b60d16020526000908152604090205481565b61033561048f36600461422c565b61176d565b6103936104a236600461420f565b6117c0565b6103936104b5366004614337565b60d36020526000908152604090205481565b60cd546104e79073ffffffffffffffffffffffffffffffffffffffff1681565b60405173ffffffffffffffffffffffffffffffffffffffff9091168152602001610319565b61039361051a36600461420f565b73ffffffffffffffffffffffffffffffffffffffff1660009081526033602052604090205490565b61033561055036600461422c565b611808565b61033561056336600461437b565b61199b565b610393611d03565b61039361057e36600461420f565b611d28565b61039361059136600461422c565b60d060209081526000928352604080842090915290825290205481565b6103356105bc366004614337565b611d55565b61030c611d62565b6103356105d736600461420f565b611d71565b6103356105ea3660046143d8565b611e39565b610393633b9aca0081565b61035d61060836600461422c565b612045565b61035d61061b36600461422c565b61211d565b61035d61062e36600461420f565b60cc6020526000908152604090205460ff1681565b6104e7610651366004614337565b61212a565b61065e612161565b604051610319919061440d565b6106c561067936600461420f565b60ce6020526000908152604090208054600182015460029092015490919067ffffffffffffffff81169060ff680100000000000000008204811691690100000000000000000090041685565b60408051958652602086019490945267ffffffffffffffff9092169284019290925290151560608301521515608082015260a001610319565b61039361070c366004614299565b6121cf565b61033561071f366004614467565b612393565b6103936107323660046144de565b73ffffffffffffffffffffffffffffffffffffffff918216600090815260346020908152604080832093909416825291909152205490565b61033561077836600461420f565b612534565b61033561078b36600461420f565b612708565b60606036805461079f9061450c565b80601f01602080910402602001604051908101604052809291908181526020018280546107cb9061450c565b80156108185780601f106107ed57610100808354040283529160200191610818565b820191906000526020600020905b8154815290600101906020018083116107fb57829003601f168201915b5050505050905090565b61082d8383836127ce565b505050565b60cd546040517f521d4de900000000000000000000000000000000000000000000000000000000815233600482015273ffffffffffffffffffffffffffffffffffffffff9091169063521d4de990602401602060405180830381865afa1580156108a0573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906108c4919061455a565b6108fa576040517f99e120bc00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff8116600090815260d1602052604081205461092b9060016145a6565b73ffffffffffffffffffffffffffffffffffffffff8316600081815260d160205260409081902083905551919250907f979ef83e7e7a87cb48064e296dd7e997870d50f43acf8d7ad221313526c8ca0f906109899084815260200190565b60405180910390a25050565b60006109a2338484612a3f565b50600192915050565b60cd546040517fe43581b800000000000000000000000000000000000000000000000000000000815233600482015273ffffffffffffffffffffffffffffffffffffffff9091169063e43581b890602401602060405180830381865afa158015610a19573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610a3d919061455a565b610a73576040517fee3675d400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b610a9473ffffffffffffffffffffffffffffffffffffffff84168383612bea565b8173ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff167ffff3b3844276f57024e0b42afec1a37f75db36511e43819a4f2a63ab7862b64883604051610af391815260200190565b60405180910390a3505050565b73ffffffffffffffffffffffffffffffffffffffff8316600090815260ce60209081526040808320815160a081018352815481526001820154938101939093526002015467ffffffffffffffff81169183019190915260ff680100000000000000008204811615801560608501526901000000000000000000909204161515608083015280610b90575080608001515b15610bc7576040517fc1ab6dc100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015260009073ffffffffffffffffffffffffffffffffffffffff8716906370a0823190602401602060405180830381865afa158015610c34573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610c5891906145bd565b8251909150610c6786836145d6565b1115610c8f578151811015610c8a578151610c839082906145a6565b9450610c8f565b600094505b6000610c9d610e10426145ee565b73ffffffffffffffffffffffffffffffffffffffff8816600090815260d06020908152604080832084845290915281205491925090610cdd9088906145d6565b90508360200151811115610d715773ffffffffffffffffffffffffffffffffffffffff8816600090815260d060209081526040808320858452825290912054908501511115610d6c5773ffffffffffffffffffffffffffffffffffffffff8816600090815260d06020908152604080832085845282529091205490850151610d6591906145a6565b9650610d71565b600096505b73ffffffffffffffffffffffffffffffffffffffff8816600090815260d060209081526040808320858452909152902054610dad9088906145d6565b73ffffffffffffffffffffffffffffffffffffffff8916600081815260d060209081526040808320878452909152902091909155610ded9033308a612cbe565b33600090815260d160205260409020548790610e3957633b9aca00856040015167ffffffffffffffff1682610e229190614629565b610e2c91906145ee565b610e3690826145a6565b90505b610e438782612d1c565b9450505050505b9392505050565b6000610e5e848484612e3c565b73ffffffffffffffffffffffffffffffffffffffff8416600090815260346020908152604080832033845290915290205482811015610f24576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602860248201527f45524332303a207472616e7366657220616d6f756e742065786365656473206160448201527f6c6c6f77616e636500000000000000000000000000000000000000000000000060648201526084015b60405180910390fd5b610f318533858403612a3f565b506001949350505050565b33600090815260cc602052604090205460ff16610f85576040517ff8d2906c00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b610f8f81836130ef565b5050565b60cd546040517fe43581b800000000000000000000000000000000000000000000000000000000815233600482015273ffffffffffffffffffffffffffffffffffffffff9091169063e43581b890602401602060405180830381865afa158015611001573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611025919061455a565b61105b576040517fee3675d400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015273ffffffffffffffffffffffffffffffffffffffff8216906370a0823190602401602060405180830381865afa1580156110c5573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906110e991906145bd565b15611120576040517f2ef630ec00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff8116600090815260ce602052604081208181556001810182905560020180547fffffffffffffffffffffffffffffffffffffffffffff0000000000000000000016905560cf54905b6111886001836145a6565b811015611296578273ffffffffffffffffffffffffffffffffffffffff1660cf82815481106111b9576111b9614666565b60009182526020909120015473ffffffffffffffffffffffffffffffffffffffff1614156112845760cf6111ee6001846145a6565b815481106111fe576111fe614666565b60009182526020909120015460cf805473ffffffffffffffffffffffffffffffffffffffff909216918390811061123757611237614666565b9060005260206000200160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550611296565b8061128e81614695565b91505061117d565b5060cf8054806112a8576112a86146ce565b60008281526020812082017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff90810180547fffffffffffffffffffffffff000000000000000000000000000000000000000016905590910190915560405173ffffffffffffffffffffffffffffffffffffffff8416917f5c95b49c4d59d97a2f044167723f29c74b30f99702e3fd406c3830160aa9ccb891a25050565b60cd5473ffffffffffffffffffffffffffffffffffffffff16331480159061138357503373ffffffffffffffffffffffffffffffffffffffff821614155b156113ba576040517fddb5de5e00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff8116600081815260cc602052604080822080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00169055517f98c15241d6c02bc5ee0b780e11b3ea737a2defd9d04877edbe9f9497065bd02f9190a250565b33600090815260cc602052604090205460ff16611477576040517ff8d2906c00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b61082d8383836132dc565b600061148c613397565b905090565b60cd546040517f521d4de900000000000000000000000000000000000000000000000000000000815233600482015273ffffffffffffffffffffffffffffffffffffffff9091169063521d4de990602401602060405180830381865afa1580156114ff573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611523919061455a565b611559576040517f99e120bc00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff8216600090815260ce602052604090206002015468010000000000000000900460ff166115c7576040517fc1ab6dc100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff8216600081815260ce602052604090819020839055517fe7b113fba37131b6396680a0c55790a697ec975e198ff8cfd89dac90a6379e61906109899084815260200190565b33600081815260346020908152604080832073ffffffffffffffffffffffffffffffffffffffff8716845290915281205490916109a29185906116659086906145d6565b612a3f565b60cd546040517f521d4de900000000000000000000000000000000000000000000000000000000815233600482015273ffffffffffffffffffffffffffffffffffffffff9091169063521d4de990602401602060405180830381865afa1580156116d8573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906116fc919061455a565b611732576040517f99e120bc00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60d28190556040518181527fc3b69829afe2345596a02c8b587d41f796ba0094481d899e1b2e07b7532a1e219060200160405180910390a150565b33600090815260cc602052604090205460ff166117b6576040517ff8d2906c00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b610f8f8282612d1c565b73ffffffffffffffffffffffffffffffffffffffff8116600090815260d060205260408120816117f2610e10426145ee565b8152602001908152602001600020549050919050565b60cd546040517f521d4de900000000000000000000000000000000000000000000000000000000815233600482015273ffffffffffffffffffffffffffffffffffffffff9091169063521d4de990602401602060405180830381865afa158015611876573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061189a919061455a565b6118d0576040517f99e120bc00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff8216600090815260ce602052604090206002015468010000000000000000900460ff1661193e576040517fc1ab6dc100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff8216600081815260ce602052604090819020600101839055517fe13ac9338b2ee623233f83c1b3ceab16490fa3e3737fac7f0970d0830a9f4871906109899084815260200190565b60cd546040517fe43581b800000000000000000000000000000000000000000000000000000000815233600482015273ffffffffffffffffffffffffffffffffffffffff9091169063e43581b890602401602060405180830381865afa158015611a09573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611a2d919061455a565b611a63576040517fee3675d400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff8516600090815260ce602052604090206002015468010000000000000000900460ff1680611aba575073ffffffffffffffffffffffffffffffffffffffff8516155b15611af1576040517fc1ab6dc100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b633b9aca008267ffffffffffffffff161115611b39576040517feca1d2c600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040805160a08101825260008082526020820181905291810182905260608101829052608081019190915284815260208082018581528315156080840190815267ffffffffffffffff808716604080870191825260016060880181815273ffffffffffffffffffffffffffffffffffffffff8e16600081815260ce9099528389208a5181559751888401559351600290970180549151965115156901000000000000000000027fffffffffffffffffffffffffffffffffffffffffffff00ffffffffffffffffff97151568010000000000000000027fffffffffffffffffffffffffffffffffffffffffffffff000000000000000000909316989096169790971717949094169290921790935560cf805492830181559093527facb8d954e2cfef495862221e91bd7523613cf8808827cb33edfe4904cc51bf290180547fffffffffffffffffffffffff0000000000000000000000000000000000000000168217905590517f53087ff85d80a7671594bd2e86b92af22e0b3c2c441c8033bba7399b7b5cbe2390611cf3908890889088908890938452602084019290925267ffffffffffffffff1660408301521515606082015260800190565b60405180910390a2505050505050565b600060d381611d14610e10426145ee565b815260200190815260200160002054905090565b73ffffffffffffffffffffffffffffffffffffffff81166000908152609960205260408120545b92915050565b611d5f33826130ef565b50565b60606037805461079f9061450c565b60cd5473ffffffffffffffffffffffffffffffffffffffff163314611dc2576040517fb90cdbb100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff8116600081815260cc602052604080822080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00166001179055517f98c15241d6c02bc5ee0b780e11b3ea737a2defd9d04877edbe9f9497065bd02f9190a250565b60cd546040517f521d4de900000000000000000000000000000000000000000000000000000000815233600482015273ffffffffffffffffffffffffffffffffffffffff9091169063521d4de990602401602060405180830381865afa158015611ea7573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611ecb919061455a565b611f01576040517f99e120bc00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff8216600090815260ce602052604090206002015468010000000000000000900460ff16611f6f576040517fc1ab6dc100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b633b9aca008167ffffffffffffffff161115611fb7576040517feca1d2c600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff8216600081815260ce602090815260409182902060020180547fffffffffffffffffffffffffffffffffffffffffffffffff00000000000000001667ffffffffffffffff861690811790915591519182527f901f9de19b475adc8da4110434b8df940dce085afd05e2281c86807f3a899d299101610989565b33600090815260346020908152604080832073ffffffffffffffffffffffffffffffffffffffff8616845290915281205482811015612106576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602560248201527f45524332303a2064656372656173656420616c6c6f77616e63652062656c6f7760448201527f207a65726f0000000000000000000000000000000000000000000000000000006064820152608401610f1b565b6121133385858403612a3f565b5060019392505050565b60006109a2338484612e3c565b60cf818154811061213a57600080fd5b60009182526020909120015473ffffffffffffffffffffffffffffffffffffffff16905081565b606060cf80548060200260200160405190810160405280929190818152602001828054801561081857602002820191906000526020600020905b815473ffffffffffffffffffffffffffffffffffffffff16815260019091019060200180831161219b575050505050905090565b73ffffffffffffffffffffffffffffffffffffffff8316600090815260ce60209081526040808320815160a081018352815481526001820154938101939093526002015467ffffffffffffffff81169183019190915260ff68010000000000000000820481161580156060850152690100000000000000000090920416151560808301528061225f575080608001515b15612296576040517fc1ab6dc100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60006122a4610e10426145ee565b600081815260d36020526040812054919250906122c29087906145d6565b905060d254811115612300576040517f6d43d1ac00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600082815260d36020526040902081905561231b33876130ef565b33600090815260d16020526040902054869061236757633b9aca00846040015167ffffffffffffffff16826123509190614629565b61235a91906145ee565b61236490826145a6565b90505b61238873ffffffffffffffffffffffffffffffffffffffff89168783612bea565b979650505050505050565b834211156123fd576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f45524332305065726d69743a206578706972656420646561646c696e650000006044820152606401610f1b565b6000609a5488888861240e8c613412565b60408051602081019690965273ffffffffffffffffffffffffffffffffffffffff94851690860152929091166060840152608083015260a082015260c0810186905260e001604051602081830303815290604052805190602001209050600061247682613447565b90506000612486828787876134b0565b90508973ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff161461251d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601e60248201527f45524332305065726d69743a20696e76616c6964207369676e617475726500006044820152606401610f1b565b6125288a8a8a612a3f565b50505050505050505050565b60cd546040517f521d4de900000000000000000000000000000000000000000000000000000000815233600482015273ffffffffffffffffffffffffffffffffffffffff9091169063521d4de990602401602060405180830381865afa1580156125a2573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906125c6919061455a565b6125fc576040517f99e120bc00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff8116600090815260ce602052604090206002015468010000000000000000900460ff1661266a576040517fc1ab6dc100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff8116600081815260ce602090815260409182902060020180547fffffffffffffffffffffffffffffffffffffffffffff00ffffffffffffffffff811669010000000000000000009182900460ff16801592830291909117909255925192835292917ff7c93079dcbf699749d66345a351afab7d24219bb1d915c9f4fc4cf03f00d3979101610989565b60cd5473ffffffffffffffffffffffffffffffffffffffff163314612759576040517fb90cdbb100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60cd80547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83169081179091556040517f7dae230f18360d76a040c81f050aa14eb9d6dc7901b20fc5d855e2a20fe814d190600090a250565b3b151590565b600054610100900460ff166127e95760005460ff16156127ed565b303b155b612879576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201527f647920696e697469616c697a65640000000000000000000000000000000000006064820152608401610f1b565b600054610100900460ff161580156128b857600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0000166101011790555b6128c1846134d8565b6128cb84846135bf565b3073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1663e9cbd8226040518163ffffffff1660e01b8152600401602060405180830381865afa15801561292d573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061295191906146fd565b73ffffffffffffffffffffffffffffffffffffffff161461299e576040517f14bcf5c800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60cd80547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff84169081179091556040517f7dae230f18360d76a040c81f050aa14eb9d6dc7901b20fc5d855e2a20fe814d190600090a28015612a3957600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff1690555b50505050565b73ffffffffffffffffffffffffffffffffffffffff8316612ae1576040517f08c379a0000000000000000000000000000000000000000000000000000000008152602060048201526024808201527f45524332303a20617070726f76652066726f6d20746865207a65726f2061646460448201527f72657373000000000000000000000000000000000000000000000000000000006064820152608401610f1b565b73ffffffffffffffffffffffffffffffffffffffff8216612b84576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602260248201527f45524332303a20617070726f766520746f20746865207a65726f20616464726560448201527f73730000000000000000000000000000000000000000000000000000000000006064820152608401610f1b565b73ffffffffffffffffffffffffffffffffffffffff83811660008181526034602090815260408083209487168084529482529182902085905590518481527f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b9259101610af3565b60405173ffffffffffffffffffffffffffffffffffffffff831660248201526044810182905261082d9084907fa9059cbb00000000000000000000000000000000000000000000000000000000906064015b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff0000000000000000000000000000000000000000000000000000000090931692909217909152613668565b60405173ffffffffffffffffffffffffffffffffffffffff80851660248301528316604482015260648101829052612a399085907f23b872dd0000000000000000000000000000000000000000000000000000000090608401612c3c565b73ffffffffffffffffffffffffffffffffffffffff8216612d99576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601f60248201527f45524332303a206d696e7420746f20746865207a65726f2061646472657373006044820152606401610f1b565b8060356000828254612dab91906145d6565b909155505073ffffffffffffffffffffffffffffffffffffffff821660009081526033602052604081208054839290612de59084906145d6565b909155505060405181815273ffffffffffffffffffffffffffffffffffffffff8316906000907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef9060200160405180910390a35050565b73ffffffffffffffffffffffffffffffffffffffff8316612edf576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602560248201527f45524332303a207472616e736665722066726f6d20746865207a65726f20616460448201527f64726573730000000000000000000000000000000000000000000000000000006064820152608401610f1b565b73ffffffffffffffffffffffffffffffffffffffff8216612f82576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602360248201527f45524332303a207472616e7366657220746f20746865207a65726f206164647260448201527f65737300000000000000000000000000000000000000000000000000000000006064820152608401610f1b565b73ffffffffffffffffffffffffffffffffffffffff831660009081526033602052604090205481811015613038576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f45524332303a207472616e7366657220616d6f756e742065786365656473206260448201527f616c616e636500000000000000000000000000000000000000000000000000006064820152608401610f1b565b73ffffffffffffffffffffffffffffffffffffffff80851660009081526033602052604080822085850390559185168152908120805484929061307c9084906145d6565b925050819055508273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef846040516130e291815260200190565b60405180910390a3612a39565b73ffffffffffffffffffffffffffffffffffffffff8216613192576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602160248201527f45524332303a206275726e2066726f6d20746865207a65726f2061646472657360448201527f73000000000000000000000000000000000000000000000000000000000000006064820152608401610f1b565b73ffffffffffffffffffffffffffffffffffffffff821660009081526033602052604090205481811015613248576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602260248201527f45524332303a206275726e20616d6f756e7420657863656564732062616c616e60448201527f63650000000000000000000000000000000000000000000000000000000000006064820152608401610f1b565b73ffffffffffffffffffffffffffffffffffffffff831660009081526033602052604081208383039055603580548492906132849084906145a6565b909155505060405182815260009073ffffffffffffffffffffffffffffffffffffffff8516907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef9060200160405180910390a3505050565b8073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff161461338d5773ffffffffffffffffffffffffffffffffffffffff8281166000908152603460209081526040808320938516835292905220548381101561337c576040517f715ec26c00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b61338b838361166587856145a6565b505b61082d82846130ef565b600061148c7f8b73c3c69bb8fe3d512ecc4cf759cc79239f7b179b0ffacaa9a75d522b39400f6133c660655490565b6066546040805160208101859052908101839052606081018290524660808201523060a082015260009060c0016040516020818303038152906040528051906020012090509392505050565b73ffffffffffffffffffffffffffffffffffffffff811660009081526099602052604090208054600181018255905b50919050565b6000611d4f613454613397565b836040517f19010000000000000000000000000000000000000000000000000000000000006020820152602281018390526042810182905260009060620160405160208183030381529060405280519060200120905092915050565b60008060006134c187878787613774565b915091506134ce8161388c565b5095945050505050565b600054610100900460ff1661356f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201527f6e697469616c697a696e670000000000000000000000000000000000000000006064820152608401610f1b565b613577613ae5565b6135b6816040518060400160405280600181526020017f3100000000000000000000000000000000000000000000000000000000000000815250613b7e565b611d5f81613c2f565b600054610100900460ff16613656576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201527f6e697469616c697a696e670000000000000000000000000000000000000000006064820152608401610f1b565b61365e613ae5565b610f8f8282613ced565b60006136ca826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c65648152508573ffffffffffffffffffffffffffffffffffffffff16613dab9092919063ffffffff16565b80519091501561082d57808060200190518101906136e8919061455a565b61082d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e60448201527f6f742073756363656564000000000000000000000000000000000000000000006064820152608401610f1b565b6000807f7fffffffffffffffffffffffffffffff5d576e7357a4501ddfe92f46681b20a08311156137ab5750600090506003613883565b8460ff16601b141580156137c357508460ff16601c14155b156137d45750600090506004613883565b6040805160008082526020820180845289905260ff881692820192909252606081018690526080810185905260019060a0016020604051602081039080840390855afa158015613828573d6000803e3d6000fd5b50506040517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0015191505073ffffffffffffffffffffffffffffffffffffffff811661387c57600060019250925050613883565b9150600090505b94509492505050565b60008160048111156138a0576138a061471a565b14156138a95750565b60018160048111156138bd576138bd61471a565b1415613925576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601860248201527f45434453413a20696e76616c6964207369676e617475726500000000000000006044820152606401610f1b565b60028160048111156139395761393961471a565b14156139a1576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601f60248201527f45434453413a20696e76616c6964207369676e6174757265206c656e677468006044820152606401610f1b565b60038160048111156139b5576139b561471a565b1415613a43576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602260248201527f45434453413a20696e76616c6964207369676e6174757265202773272076616c60448201527f75650000000000000000000000000000000000000000000000000000000000006064820152608401610f1b565b6004816004811115613a5757613a5761471a565b1415611d5f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602260248201527f45434453413a20696e76616c6964207369676e6174757265202776272076616c60448201527f75650000000000000000000000000000000000000000000000000000000000006064820152608401610f1b565b600054610100900460ff16613b7c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201527f6e697469616c697a696e670000000000000000000000000000000000000000006064820152608401610f1b565b565b600054610100900460ff16613c15576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201527f6e697469616c697a696e670000000000000000000000000000000000000000006064820152608401610f1b565b815160209283012081519190920120606591909155606655565b600054610100900460ff16613cc6576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201527f6e697469616c697a696e670000000000000000000000000000000000000000006064820152608401610f1b565b507f6e71edae12b1b97f4d1f60370fef10105fa2faae0126114a169c64845d6126c9609a55565b600054610100900460ff16613d84576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201527f6e697469616c697a696e670000000000000000000000000000000000000000006064820152608401610f1b565b8151613d97906036906020850190613f85565b50805161082d906037906020840190613f85565b6060613dba8484600085613dc2565b949350505050565b606082471015613e54576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f60448201527f722063616c6c00000000000000000000000000000000000000000000000000006064820152608401610f1b565b843b613ebc576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006044820152606401610f1b565b6000808673ffffffffffffffffffffffffffffffffffffffff168587604051613ee59190614749565b60006040518083038185875af1925050503d8060008114613f22576040519150601f19603f3d011682016040523d82523d6000602084013e613f27565b606091505b509150915061238882828660608315613f41575081610e4a565b825115613f515782518084602001fd5b816040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610f1b919061404a565b828054613f919061450c565b90600052602060002090601f016020900481019282613fb35760008555613ff9565b82601f10613fcc57805160ff1916838001178555613ff9565b82800160010185558215613ff9579182015b82811115613ff9578251825591602001919060010190613fde565b50614005929150614009565b5090565b5b80821115614005576000815560010161400a565b60005b83811015614039578181015183820152602001614021565b83811115612a395750506000910152565b602081526000825180602084015261406981604085016020870161401e565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169190910160400192915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b600082601f8301126140db57600080fd5b813567ffffffffffffffff808211156140f6576140f661409b565b604051601f83017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0908116603f0116810190828211818310171561413c5761413c61409b565b8160405283815286602085880101111561415557600080fd5b836020870160208301376000602085830101528094505050505092915050565b73ffffffffffffffffffffffffffffffffffffffff81168114611d5f57600080fd5b6000806000606084860312156141ac57600080fd5b833567ffffffffffffffff808211156141c457600080fd5b6141d0878388016140ca565b945060208601359150808211156141e657600080fd5b506141f3868287016140ca565b925050604084013561420481614175565b809150509250925092565b60006020828403121561422157600080fd5b8135610e4a81614175565b6000806040838503121561423f57600080fd5b823561424a81614175565b946020939093013593505050565b60008060006060848603121561426d57600080fd5b833561427881614175565b9250602084013561428881614175565b929592945050506040919091013590565b6000806000606084860312156142ae57600080fd5b83356142b981614175565b925060208401359150604084013561420481614175565b600080604083850312156142e357600080fd5b8235915060208301356142f581614175565b809150509250929050565b60008060006060848603121561431557600080fd5b83359250602084013561432781614175565b9150604084013561420481614175565b60006020828403121561434957600080fd5b5035919050565b803567ffffffffffffffff8116811461436857600080fd5b919050565b8015158114611d5f57600080fd5b600080600080600060a0868803121561439357600080fd5b853561439e81614175565b945060208601359350604086013592506143ba60608701614350565b915060808601356143ca8161436d565b809150509295509295909350565b600080604083850312156143eb57600080fd5b82356143f681614175565b915061440460208401614350565b90509250929050565b6020808252825182820181905260009190848201906040850190845b8181101561445b57835173ffffffffffffffffffffffffffffffffffffffff1683529284019291840191600101614429565b50909695505050505050565b600080600080600080600060e0888a03121561448257600080fd5b873561448d81614175565b9650602088013561449d81614175565b95506040880135945060608801359350608088013560ff811681146144c157600080fd5b9699959850939692959460a0840135945060c09093013592915050565b600080604083850312156144f157600080fd5b82356144fc81614175565b915060208301356142f581614175565b600181811c9082168061452057607f821691505b60208210811415613441577f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b60006020828403121561456c57600080fd5b8151610e4a8161436d565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b6000828210156145b8576145b8614577565b500390565b6000602082840312156145cf57600080fd5b5051919050565b600082198211156145e9576145e9614577565b500190565b600082614624577f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b500490565b6000817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff048311821515161561466157614661614577565b500290565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8214156146c7576146c7614577565b5060010190565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603160045260246000fd5b60006020828403121561470f57600080fd5b8151610e4a81614175565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b6000825161475b81846020870161401e565b919091019291505056fea2646970667358221220103b8d652dd7975983cef70f41cb81056a0bf607243b7332223b4013506c7eb664736f6c634300080c0033", - "deployedBytecode": "0x608060405234801561001057600080fd5b50600436106102ff5760003560e01c806361d027b31161019c5780639f48118f116100ee578063ced67f0c11610097578063dd62ed3e11610071578063dd62ed3e14610724578063e3e286551461076a578063f0f442601461077d57600080fd5b8063ced67f0c1461066b578063d44ad63f146106fe578063d505accf1461071157600080fd5b8063aa271e1a116100c8578063aa271e1a14610620578063ba330bd714610643578063cd4839ca1461065657600080fd5b80639f48118f146105ef578063a457c2d7146105fa578063a9059cbb1461060d57600080fd5b80637ecebe001161015057806395d89b411161012a57806395d89b41146105c1578063983b2d56146105c95780639e4e0dae146105dc57600080fd5b80637ecebe00146105705780638933fb791461058357806390218cff146105ae57600080fd5b80637334d020116101815780637334d020146105425780637d4c9c2d146105555780637d74e25f1461056857600080fd5b806361d027b3146104c757806370a082311461050c57600080fd5b80633092afd511610255578063395093511161020957806340c10f19116101e357806340c10f19146104815780634dc32fcc146104945780635bfbec96146104a757600080fd5b8063395093511461043b5780633a55f89d1461044e5780633f4218e01461046157600080fd5b8063350ebe041161023a578063350ebe041461040d5780633644e5151461042057806336db43b51461042857600080fd5b80633092afd5146103eb578063313ce567146103fe57600080fd5b8063151dd755116102b757806323b872dd1161029157806323b872dd146103b25780632b471d8e146103c55780632e403e14146103d857600080fd5b8063151dd7551461038057806318160ddd146103a15780632342fb0e146103a957600080fd5b80630919a951116102e85780630919a95114610337578063095ea7b31461034a5780631171bda91461036d57600080fd5b806306fdde0314610304578063077f224a14610322575b600080fd5b61030c610790565b604051610319919061404a565b60405180910390f35b610335610330366004614197565b610822565b005b61033561034536600461420f565b610832565b61035d61035836600461422c565b610995565b6040519015158152602001610319565b61033561037b366004614258565b6109ab565b61039361038e366004614299565b610b00565b604051908152602001610319565b603554610393565b61039360d25481565b61035d6103c0366004614258565b610e51565b6103356103d33660046142d0565b610f3c565b6103356103e636600461420f565b610f93565b6103356103f936600461420f565b611345565b60405160128152602001610319565b61033561041b366004614300565b61142e565b610393611482565b61033561043636600461422c565b611491565b61035d61044936600461422c565b611621565b61033561045c366004614337565b61166a565b61039361046f36600461420f565b60d16020526000908152604090205481565b61033561048f36600461422c565b61176d565b6103936104a236600461420f565b6117c0565b6103936104b5366004614337565b60d36020526000908152604090205481565b60cd546104e79073ffffffffffffffffffffffffffffffffffffffff1681565b60405173ffffffffffffffffffffffffffffffffffffffff9091168152602001610319565b61039361051a36600461420f565b73ffffffffffffffffffffffffffffffffffffffff1660009081526033602052604090205490565b61033561055036600461422c565b611808565b61033561056336600461437b565b61199b565b610393611d03565b61039361057e36600461420f565b611d28565b61039361059136600461422c565b60d060209081526000928352604080842090915290825290205481565b6103356105bc366004614337565b611d55565b61030c611d62565b6103356105d736600461420f565b611d71565b6103356105ea3660046143d8565b611e39565b610393633b9aca0081565b61035d61060836600461422c565b612045565b61035d61061b36600461422c565b61211d565b61035d61062e36600461420f565b60cc6020526000908152604090205460ff1681565b6104e7610651366004614337565b61212a565b61065e612161565b604051610319919061440d565b6106c561067936600461420f565b60ce6020526000908152604090208054600182015460029092015490919067ffffffffffffffff81169060ff680100000000000000008204811691690100000000000000000090041685565b60408051958652602086019490945267ffffffffffffffff9092169284019290925290151560608301521515608082015260a001610319565b61039361070c366004614299565b6121cf565b61033561071f366004614467565b612393565b6103936107323660046144de565b73ffffffffffffffffffffffffffffffffffffffff918216600090815260346020908152604080832093909416825291909152205490565b61033561077836600461420f565b612534565b61033561078b36600461420f565b612708565b60606036805461079f9061450c565b80601f01602080910402602001604051908101604052809291908181526020018280546107cb9061450c565b80156108185780601f106107ed57610100808354040283529160200191610818565b820191906000526020600020905b8154815290600101906020018083116107fb57829003601f168201915b5050505050905090565b61082d8383836127ce565b505050565b60cd546040517f521d4de900000000000000000000000000000000000000000000000000000000815233600482015273ffffffffffffffffffffffffffffffffffffffff9091169063521d4de990602401602060405180830381865afa1580156108a0573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906108c4919061455a565b6108fa576040517f99e120bc00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff8116600090815260d1602052604081205461092b9060016145a6565b73ffffffffffffffffffffffffffffffffffffffff8316600081815260d160205260409081902083905551919250907f979ef83e7e7a87cb48064e296dd7e997870d50f43acf8d7ad221313526c8ca0f906109899084815260200190565b60405180910390a25050565b60006109a2338484612a3f565b50600192915050565b60cd546040517fe43581b800000000000000000000000000000000000000000000000000000000815233600482015273ffffffffffffffffffffffffffffffffffffffff9091169063e43581b890602401602060405180830381865afa158015610a19573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610a3d919061455a565b610a73576040517fee3675d400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b610a9473ffffffffffffffffffffffffffffffffffffffff84168383612bea565b8173ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff167ffff3b3844276f57024e0b42afec1a37f75db36511e43819a4f2a63ab7862b64883604051610af391815260200190565b60405180910390a3505050565b73ffffffffffffffffffffffffffffffffffffffff8316600090815260ce60209081526040808320815160a081018352815481526001820154938101939093526002015467ffffffffffffffff81169183019190915260ff680100000000000000008204811615801560608501526901000000000000000000909204161515608083015280610b90575080608001515b15610bc7576040517fc1ab6dc100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015260009073ffffffffffffffffffffffffffffffffffffffff8716906370a0823190602401602060405180830381865afa158015610c34573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610c5891906145bd565b8251909150610c6786836145d6565b1115610c8f578151811015610c8a578151610c839082906145a6565b9450610c8f565b600094505b6000610c9d610e10426145ee565b73ffffffffffffffffffffffffffffffffffffffff8816600090815260d06020908152604080832084845290915281205491925090610cdd9088906145d6565b90508360200151811115610d715773ffffffffffffffffffffffffffffffffffffffff8816600090815260d060209081526040808320858452825290912054908501511115610d6c5773ffffffffffffffffffffffffffffffffffffffff8816600090815260d06020908152604080832085845282529091205490850151610d6591906145a6565b9650610d71565b600096505b73ffffffffffffffffffffffffffffffffffffffff8816600090815260d060209081526040808320858452909152902054610dad9088906145d6565b73ffffffffffffffffffffffffffffffffffffffff8916600081815260d060209081526040808320878452909152902091909155610ded9033308a612cbe565b33600090815260d160205260409020548790610e3957633b9aca00856040015167ffffffffffffffff1682610e229190614629565b610e2c91906145ee565b610e3690826145a6565b90505b610e438782612d1c565b9450505050505b9392505050565b6000610e5e848484612e3c565b73ffffffffffffffffffffffffffffffffffffffff8416600090815260346020908152604080832033845290915290205482811015610f24576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602860248201527f45524332303a207472616e7366657220616d6f756e742065786365656473206160448201527f6c6c6f77616e636500000000000000000000000000000000000000000000000060648201526084015b60405180910390fd5b610f318533858403612a3f565b506001949350505050565b33600090815260cc602052604090205460ff16610f85576040517ff8d2906c00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b610f8f81836130ef565b5050565b60cd546040517fe43581b800000000000000000000000000000000000000000000000000000000815233600482015273ffffffffffffffffffffffffffffffffffffffff9091169063e43581b890602401602060405180830381865afa158015611001573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611025919061455a565b61105b576040517fee3675d400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015273ffffffffffffffffffffffffffffffffffffffff8216906370a0823190602401602060405180830381865afa1580156110c5573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906110e991906145bd565b15611120576040517f2ef630ec00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff8116600090815260ce602052604081208181556001810182905560020180547fffffffffffffffffffffffffffffffffffffffffffff0000000000000000000016905560cf54905b6111886001836145a6565b811015611296578273ffffffffffffffffffffffffffffffffffffffff1660cf82815481106111b9576111b9614666565b60009182526020909120015473ffffffffffffffffffffffffffffffffffffffff1614156112845760cf6111ee6001846145a6565b815481106111fe576111fe614666565b60009182526020909120015460cf805473ffffffffffffffffffffffffffffffffffffffff909216918390811061123757611237614666565b9060005260206000200160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550611296565b8061128e81614695565b91505061117d565b5060cf8054806112a8576112a86146ce565b60008281526020812082017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff90810180547fffffffffffffffffffffffff000000000000000000000000000000000000000016905590910190915560405173ffffffffffffffffffffffffffffffffffffffff8416917f5c95b49c4d59d97a2f044167723f29c74b30f99702e3fd406c3830160aa9ccb891a25050565b60cd5473ffffffffffffffffffffffffffffffffffffffff16331480159061138357503373ffffffffffffffffffffffffffffffffffffffff821614155b156113ba576040517fddb5de5e00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff8116600081815260cc602052604080822080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00169055517f98c15241d6c02bc5ee0b780e11b3ea737a2defd9d04877edbe9f9497065bd02f9190a250565b33600090815260cc602052604090205460ff16611477576040517ff8d2906c00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b61082d8383836132dc565b600061148c613397565b905090565b60cd546040517f521d4de900000000000000000000000000000000000000000000000000000000815233600482015273ffffffffffffffffffffffffffffffffffffffff9091169063521d4de990602401602060405180830381865afa1580156114ff573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611523919061455a565b611559576040517f99e120bc00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff8216600090815260ce602052604090206002015468010000000000000000900460ff166115c7576040517fc1ab6dc100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff8216600081815260ce602052604090819020839055517fe7b113fba37131b6396680a0c55790a697ec975e198ff8cfd89dac90a6379e61906109899084815260200190565b33600081815260346020908152604080832073ffffffffffffffffffffffffffffffffffffffff8716845290915281205490916109a29185906116659086906145d6565b612a3f565b60cd546040517f521d4de900000000000000000000000000000000000000000000000000000000815233600482015273ffffffffffffffffffffffffffffffffffffffff9091169063521d4de990602401602060405180830381865afa1580156116d8573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906116fc919061455a565b611732576040517f99e120bc00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60d28190556040518181527fc3b69829afe2345596a02c8b587d41f796ba0094481d899e1b2e07b7532a1e219060200160405180910390a150565b33600090815260cc602052604090205460ff166117b6576040517ff8d2906c00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b610f8f8282612d1c565b73ffffffffffffffffffffffffffffffffffffffff8116600090815260d060205260408120816117f2610e10426145ee565b8152602001908152602001600020549050919050565b60cd546040517f521d4de900000000000000000000000000000000000000000000000000000000815233600482015273ffffffffffffffffffffffffffffffffffffffff9091169063521d4de990602401602060405180830381865afa158015611876573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061189a919061455a565b6118d0576040517f99e120bc00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff8216600090815260ce602052604090206002015468010000000000000000900460ff1661193e576040517fc1ab6dc100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff8216600081815260ce602052604090819020600101839055517fe13ac9338b2ee623233f83c1b3ceab16490fa3e3737fac7f0970d0830a9f4871906109899084815260200190565b60cd546040517fe43581b800000000000000000000000000000000000000000000000000000000815233600482015273ffffffffffffffffffffffffffffffffffffffff9091169063e43581b890602401602060405180830381865afa158015611a09573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611a2d919061455a565b611a63576040517fee3675d400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff8516600090815260ce602052604090206002015468010000000000000000900460ff1680611aba575073ffffffffffffffffffffffffffffffffffffffff8516155b15611af1576040517fc1ab6dc100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b633b9aca008267ffffffffffffffff161115611b39576040517feca1d2c600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040805160a08101825260008082526020820181905291810182905260608101829052608081019190915284815260208082018581528315156080840190815267ffffffffffffffff808716604080870191825260016060880181815273ffffffffffffffffffffffffffffffffffffffff8e16600081815260ce9099528389208a5181559751888401559351600290970180549151965115156901000000000000000000027fffffffffffffffffffffffffffffffffffffffffffff00ffffffffffffffffff97151568010000000000000000027fffffffffffffffffffffffffffffffffffffffffffffff000000000000000000909316989096169790971717949094169290921790935560cf805492830181559093527facb8d954e2cfef495862221e91bd7523613cf8808827cb33edfe4904cc51bf290180547fffffffffffffffffffffffff0000000000000000000000000000000000000000168217905590517f53087ff85d80a7671594bd2e86b92af22e0b3c2c441c8033bba7399b7b5cbe2390611cf3908890889088908890938452602084019290925267ffffffffffffffff1660408301521515606082015260800190565b60405180910390a2505050505050565b600060d381611d14610e10426145ee565b815260200190815260200160002054905090565b73ffffffffffffffffffffffffffffffffffffffff81166000908152609960205260408120545b92915050565b611d5f33826130ef565b50565b60606037805461079f9061450c565b60cd5473ffffffffffffffffffffffffffffffffffffffff163314611dc2576040517fb90cdbb100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff8116600081815260cc602052604080822080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00166001179055517f98c15241d6c02bc5ee0b780e11b3ea737a2defd9d04877edbe9f9497065bd02f9190a250565b60cd546040517f521d4de900000000000000000000000000000000000000000000000000000000815233600482015273ffffffffffffffffffffffffffffffffffffffff9091169063521d4de990602401602060405180830381865afa158015611ea7573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611ecb919061455a565b611f01576040517f99e120bc00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff8216600090815260ce602052604090206002015468010000000000000000900460ff16611f6f576040517fc1ab6dc100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b633b9aca008167ffffffffffffffff161115611fb7576040517feca1d2c600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff8216600081815260ce602090815260409182902060020180547fffffffffffffffffffffffffffffffffffffffffffffffff00000000000000001667ffffffffffffffff861690811790915591519182527f901f9de19b475adc8da4110434b8df940dce085afd05e2281c86807f3a899d299101610989565b33600090815260346020908152604080832073ffffffffffffffffffffffffffffffffffffffff8616845290915281205482811015612106576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602560248201527f45524332303a2064656372656173656420616c6c6f77616e63652062656c6f7760448201527f207a65726f0000000000000000000000000000000000000000000000000000006064820152608401610f1b565b6121133385858403612a3f565b5060019392505050565b60006109a2338484612e3c565b60cf818154811061213a57600080fd5b60009182526020909120015473ffffffffffffffffffffffffffffffffffffffff16905081565b606060cf80548060200260200160405190810160405280929190818152602001828054801561081857602002820191906000526020600020905b815473ffffffffffffffffffffffffffffffffffffffff16815260019091019060200180831161219b575050505050905090565b73ffffffffffffffffffffffffffffffffffffffff8316600090815260ce60209081526040808320815160a081018352815481526001820154938101939093526002015467ffffffffffffffff81169183019190915260ff68010000000000000000820481161580156060850152690100000000000000000090920416151560808301528061225f575080608001515b15612296576040517fc1ab6dc100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60006122a4610e10426145ee565b600081815260d36020526040812054919250906122c29087906145d6565b905060d254811115612300576040517f6d43d1ac00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600082815260d36020526040902081905561231b33876130ef565b33600090815260d16020526040902054869061236757633b9aca00846040015167ffffffffffffffff16826123509190614629565b61235a91906145ee565b61236490826145a6565b90505b61238873ffffffffffffffffffffffffffffffffffffffff89168783612bea565b979650505050505050565b834211156123fd576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f45524332305065726d69743a206578706972656420646561646c696e650000006044820152606401610f1b565b6000609a5488888861240e8c613412565b60408051602081019690965273ffffffffffffffffffffffffffffffffffffffff94851690860152929091166060840152608083015260a082015260c0810186905260e001604051602081830303815290604052805190602001209050600061247682613447565b90506000612486828787876134b0565b90508973ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff161461251d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601e60248201527f45524332305065726d69743a20696e76616c6964207369676e617475726500006044820152606401610f1b565b6125288a8a8a612a3f565b50505050505050505050565b60cd546040517f521d4de900000000000000000000000000000000000000000000000000000000815233600482015273ffffffffffffffffffffffffffffffffffffffff9091169063521d4de990602401602060405180830381865afa1580156125a2573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906125c6919061455a565b6125fc576040517f99e120bc00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff8116600090815260ce602052604090206002015468010000000000000000900460ff1661266a576040517fc1ab6dc100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff8116600081815260ce602090815260409182902060020180547fffffffffffffffffffffffffffffffffffffffffffff00ffffffffffffffffff811669010000000000000000009182900460ff16801592830291909117909255925192835292917ff7c93079dcbf699749d66345a351afab7d24219bb1d915c9f4fc4cf03f00d3979101610989565b60cd5473ffffffffffffffffffffffffffffffffffffffff163314612759576040517fb90cdbb100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60cd80547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83169081179091556040517f7dae230f18360d76a040c81f050aa14eb9d6dc7901b20fc5d855e2a20fe814d190600090a250565b3b151590565b600054610100900460ff166127e95760005460ff16156127ed565b303b155b612879576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201527f647920696e697469616c697a65640000000000000000000000000000000000006064820152608401610f1b565b600054610100900460ff161580156128b857600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0000166101011790555b6128c1846134d8565b6128cb84846135bf565b3073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1663e9cbd8226040518163ffffffff1660e01b8152600401602060405180830381865afa15801561292d573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061295191906146fd565b73ffffffffffffffffffffffffffffffffffffffff161461299e576040517f14bcf5c800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60cd80547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff84169081179091556040517f7dae230f18360d76a040c81f050aa14eb9d6dc7901b20fc5d855e2a20fe814d190600090a28015612a3957600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff1690555b50505050565b73ffffffffffffffffffffffffffffffffffffffff8316612ae1576040517f08c379a0000000000000000000000000000000000000000000000000000000008152602060048201526024808201527f45524332303a20617070726f76652066726f6d20746865207a65726f2061646460448201527f72657373000000000000000000000000000000000000000000000000000000006064820152608401610f1b565b73ffffffffffffffffffffffffffffffffffffffff8216612b84576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602260248201527f45524332303a20617070726f766520746f20746865207a65726f20616464726560448201527f73730000000000000000000000000000000000000000000000000000000000006064820152608401610f1b565b73ffffffffffffffffffffffffffffffffffffffff83811660008181526034602090815260408083209487168084529482529182902085905590518481527f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b9259101610af3565b60405173ffffffffffffffffffffffffffffffffffffffff831660248201526044810182905261082d9084907fa9059cbb00000000000000000000000000000000000000000000000000000000906064015b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff0000000000000000000000000000000000000000000000000000000090931692909217909152613668565b60405173ffffffffffffffffffffffffffffffffffffffff80851660248301528316604482015260648101829052612a399085907f23b872dd0000000000000000000000000000000000000000000000000000000090608401612c3c565b73ffffffffffffffffffffffffffffffffffffffff8216612d99576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601f60248201527f45524332303a206d696e7420746f20746865207a65726f2061646472657373006044820152606401610f1b565b8060356000828254612dab91906145d6565b909155505073ffffffffffffffffffffffffffffffffffffffff821660009081526033602052604081208054839290612de59084906145d6565b909155505060405181815273ffffffffffffffffffffffffffffffffffffffff8316906000907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef9060200160405180910390a35050565b73ffffffffffffffffffffffffffffffffffffffff8316612edf576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602560248201527f45524332303a207472616e736665722066726f6d20746865207a65726f20616460448201527f64726573730000000000000000000000000000000000000000000000000000006064820152608401610f1b565b73ffffffffffffffffffffffffffffffffffffffff8216612f82576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602360248201527f45524332303a207472616e7366657220746f20746865207a65726f206164647260448201527f65737300000000000000000000000000000000000000000000000000000000006064820152608401610f1b565b73ffffffffffffffffffffffffffffffffffffffff831660009081526033602052604090205481811015613038576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f45524332303a207472616e7366657220616d6f756e742065786365656473206260448201527f616c616e636500000000000000000000000000000000000000000000000000006064820152608401610f1b565b73ffffffffffffffffffffffffffffffffffffffff80851660009081526033602052604080822085850390559185168152908120805484929061307c9084906145d6565b925050819055508273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef846040516130e291815260200190565b60405180910390a3612a39565b73ffffffffffffffffffffffffffffffffffffffff8216613192576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602160248201527f45524332303a206275726e2066726f6d20746865207a65726f2061646472657360448201527f73000000000000000000000000000000000000000000000000000000000000006064820152608401610f1b565b73ffffffffffffffffffffffffffffffffffffffff821660009081526033602052604090205481811015613248576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602260248201527f45524332303a206275726e20616d6f756e7420657863656564732062616c616e60448201527f63650000000000000000000000000000000000000000000000000000000000006064820152608401610f1b565b73ffffffffffffffffffffffffffffffffffffffff831660009081526033602052604081208383039055603580548492906132849084906145a6565b909155505060405182815260009073ffffffffffffffffffffffffffffffffffffffff8516907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef9060200160405180910390a3505050565b8073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff161461338d5773ffffffffffffffffffffffffffffffffffffffff8281166000908152603460209081526040808320938516835292905220548381101561337c576040517f715ec26c00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b61338b838361166587856145a6565b505b61082d82846130ef565b600061148c7f8b73c3c69bb8fe3d512ecc4cf759cc79239f7b179b0ffacaa9a75d522b39400f6133c660655490565b6066546040805160208101859052908101839052606081018290524660808201523060a082015260009060c0016040516020818303038152906040528051906020012090509392505050565b73ffffffffffffffffffffffffffffffffffffffff811660009081526099602052604090208054600181018255905b50919050565b6000611d4f613454613397565b836040517f19010000000000000000000000000000000000000000000000000000000000006020820152602281018390526042810182905260009060620160405160208183030381529060405280519060200120905092915050565b60008060006134c187878787613774565b915091506134ce8161388c565b5095945050505050565b600054610100900460ff1661356f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201527f6e697469616c697a696e670000000000000000000000000000000000000000006064820152608401610f1b565b613577613ae5565b6135b6816040518060400160405280600181526020017f3100000000000000000000000000000000000000000000000000000000000000815250613b7e565b611d5f81613c2f565b600054610100900460ff16613656576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201527f6e697469616c697a696e670000000000000000000000000000000000000000006064820152608401610f1b565b61365e613ae5565b610f8f8282613ced565b60006136ca826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c65648152508573ffffffffffffffffffffffffffffffffffffffff16613dab9092919063ffffffff16565b80519091501561082d57808060200190518101906136e8919061455a565b61082d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e60448201527f6f742073756363656564000000000000000000000000000000000000000000006064820152608401610f1b565b6000807f7fffffffffffffffffffffffffffffff5d576e7357a4501ddfe92f46681b20a08311156137ab5750600090506003613883565b8460ff16601b141580156137c357508460ff16601c14155b156137d45750600090506004613883565b6040805160008082526020820180845289905260ff881692820192909252606081018690526080810185905260019060a0016020604051602081039080840390855afa158015613828573d6000803e3d6000fd5b50506040517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0015191505073ffffffffffffffffffffffffffffffffffffffff811661387c57600060019250925050613883565b9150600090505b94509492505050565b60008160048111156138a0576138a061471a565b14156138a95750565b60018160048111156138bd576138bd61471a565b1415613925576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601860248201527f45434453413a20696e76616c6964207369676e617475726500000000000000006044820152606401610f1b565b60028160048111156139395761393961471a565b14156139a1576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601f60248201527f45434453413a20696e76616c6964207369676e6174757265206c656e677468006044820152606401610f1b565b60038160048111156139b5576139b561471a565b1415613a43576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602260248201527f45434453413a20696e76616c6964207369676e6174757265202773272076616c60448201527f75650000000000000000000000000000000000000000000000000000000000006064820152608401610f1b565b6004816004811115613a5757613a5761471a565b1415611d5f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602260248201527f45434453413a20696e76616c6964207369676e6174757265202776272076616c60448201527f75650000000000000000000000000000000000000000000000000000000000006064820152608401610f1b565b600054610100900460ff16613b7c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201527f6e697469616c697a696e670000000000000000000000000000000000000000006064820152608401610f1b565b565b600054610100900460ff16613c15576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201527f6e697469616c697a696e670000000000000000000000000000000000000000006064820152608401610f1b565b815160209283012081519190920120606591909155606655565b600054610100900460ff16613cc6576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201527f6e697469616c697a696e670000000000000000000000000000000000000000006064820152608401610f1b565b507f6e71edae12b1b97f4d1f60370fef10105fa2faae0126114a169c64845d6126c9609a55565b600054610100900460ff16613d84576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201527f6e697469616c697a696e670000000000000000000000000000000000000000006064820152608401610f1b565b8151613d97906036906020850190613f85565b50805161082d906037906020840190613f85565b6060613dba8484600085613dc2565b949350505050565b606082471015613e54576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f60448201527f722063616c6c00000000000000000000000000000000000000000000000000006064820152608401610f1b565b843b613ebc576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006044820152606401610f1b565b6000808673ffffffffffffffffffffffffffffffffffffffff168587604051613ee59190614749565b60006040518083038185875af1925050503d8060008114613f22576040519150601f19603f3d011682016040523d82523d6000602084013e613f27565b606091505b509150915061238882828660608315613f41575081610e4a565b825115613f515782518084602001fd5b816040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610f1b919061404a565b828054613f919061450c565b90600052602060002090601f016020900481019282613fb35760008555613ff9565b82601f10613fcc57805160ff1916838001178555613ff9565b82800160010185558215613ff9579182015b82811115613ff9578251825591602001919060010190613fde565b50614005929150614009565b5090565b5b80821115614005576000815560010161400a565b60005b83811015614039578181015183820152602001614021565b83811115612a395750506000910152565b602081526000825180602084015261406981604085016020870161401e565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169190910160400192915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b600082601f8301126140db57600080fd5b813567ffffffffffffffff808211156140f6576140f661409b565b604051601f83017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0908116603f0116810190828211818310171561413c5761413c61409b565b8160405283815286602085880101111561415557600080fd5b836020870160208301376000602085830101528094505050505092915050565b73ffffffffffffffffffffffffffffffffffffffff81168114611d5f57600080fd5b6000806000606084860312156141ac57600080fd5b833567ffffffffffffffff808211156141c457600080fd5b6141d0878388016140ca565b945060208601359150808211156141e657600080fd5b506141f3868287016140ca565b925050604084013561420481614175565b809150509250925092565b60006020828403121561422157600080fd5b8135610e4a81614175565b6000806040838503121561423f57600080fd5b823561424a81614175565b946020939093013593505050565b60008060006060848603121561426d57600080fd5b833561427881614175565b9250602084013561428881614175565b929592945050506040919091013590565b6000806000606084860312156142ae57600080fd5b83356142b981614175565b925060208401359150604084013561420481614175565b600080604083850312156142e357600080fd5b8235915060208301356142f581614175565b809150509250929050565b60008060006060848603121561431557600080fd5b83359250602084013561432781614175565b9150604084013561420481614175565b60006020828403121561434957600080fd5b5035919050565b803567ffffffffffffffff8116811461436857600080fd5b919050565b8015158114611d5f57600080fd5b600080600080600060a0868803121561439357600080fd5b853561439e81614175565b945060208601359350604086013592506143ba60608701614350565b915060808601356143ca8161436d565b809150509295509295909350565b600080604083850312156143eb57600080fd5b82356143f681614175565b915061440460208401614350565b90509250929050565b6020808252825182820181905260009190848201906040850190845b8181101561445b57835173ffffffffffffffffffffffffffffffffffffffff1683529284019291840191600101614429565b50909695505050505050565b600080600080600080600060e0888a03121561448257600080fd5b873561448d81614175565b9650602088013561449d81614175565b95506040880135945060608801359350608088013560ff811681146144c157600080fd5b9699959850939692959460a0840135945060c09093013592915050565b600080604083850312156144f157600080fd5b82356144fc81614175565b915060208301356142f581614175565b600181811c9082168061452057607f821691505b60208210811415613441577f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b60006020828403121561456c57600080fd5b8151610e4a8161436d565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b6000828210156145b8576145b8614577565b500390565b6000602082840312156145cf57600080fd5b5051919050565b600082198211156145e9576145e9614577565b500190565b600082614624577f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b500490565b6000817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff048311821515161561466157614661614577565b500290565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8214156146c7576146c7614577565b5060010190565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603160045260246000fd5b60006020828403121561470f57600080fd5b8151610e4a81614175565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b6000825161475b81846020870161401e565b919091019291505056fea2646970667358221220103b8d652dd7975983cef70f41cb81056a0bf607243b7332223b4013506c7eb664736f6c634300080c0033", + "numDeployments": 2, + "solcInputHash": "871924e0c138825a2736b76def8fef8d", + "metadata": "{\"compiler\":{\"version\":\"0.8.17+commit.8df45f5f\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[],\"name\":\"AssetStillControlledInReserves\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"BurnAmountExceedsAllowance\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"HourlyLimitExceeded\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidSender\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidToken\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidTreasury\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"NotGovernor\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"NotGovernorOrGuardian\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"NotMinter\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"NotTreasury\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"TooBigAmount\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"TooHighParameterValue\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ZeroAddress\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"spender\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"}],\"name\":\"Approval\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"bridgeToken\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"limit\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"hourlyLimit\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"fee\",\"type\":\"uint64\"},{\"indexed\":false,\"internalType\":\"bool\",\"name\":\"paused\",\"type\":\"bool\"}],\"name\":\"BridgeTokenAdded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"bridgeToken\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"fee\",\"type\":\"uint64\"}],\"name\":\"BridgeTokenFeeUpdated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"bridgeToken\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"hourlyLimit\",\"type\":\"uint256\"}],\"name\":\"BridgeTokenHourlyLimitUpdated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"bridgeToken\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"limit\",\"type\":\"uint256\"}],\"name\":\"BridgeTokenLimitUpdated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"bridgeToken\",\"type\":\"address\"}],\"name\":\"BridgeTokenRemoved\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"bridgeToken\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"bool\",\"name\":\"toggleStatus\",\"type\":\"bool\"}],\"name\":\"BridgeTokenToggled\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"theAddress\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"toggleStatus\",\"type\":\"uint256\"}],\"name\":\"FeeToggled\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"hourlyLimit\",\"type\":\"uint256\"}],\"name\":\"HourlyLimitUpdated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint8\",\"name\":\"version\",\"type\":\"uint8\"}],\"name\":\"Initialized\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"minter\",\"type\":\"address\"}],\"name\":\"MinterToggled\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"Recovered\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"}],\"name\":\"Transfer\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"_treasury\",\"type\":\"address\"}],\"name\":\"TreasuryUpdated\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"BASE_PARAMS\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"DOMAIN_SEPARATOR\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"bridgeToken\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"limit\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"hourlyLimit\",\"type\":\"uint256\"},{\"internalType\":\"uint64\",\"name\":\"fee\",\"type\":\"uint64\"},{\"internalType\":\"bool\",\"name\":\"paused\",\"type\":\"bool\"}],\"name\":\"addBridgeToken\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"minter\",\"type\":\"address\"}],\"name\":\"addMinter\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"allBridgeTokens\",\"outputs\":[{\"internalType\":\"address[]\",\"name\":\"\",\"type\":\"address[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"spender\",\"type\":\"address\"}],\"name\":\"allowance\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"spender\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"approve\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"}],\"name\":\"balanceOf\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"name\":\"bridgeTokensList\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"bridges\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"limit\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"hourlyLimit\",\"type\":\"uint256\"},{\"internalType\":\"uint64\",\"name\":\"fee\",\"type\":\"uint64\"},{\"internalType\":\"bool\",\"name\":\"allowed\",\"type\":\"bool\"},{\"internalType\":\"bool\",\"name\":\"paused\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"burner\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"}],\"name\":\"burnFrom\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"burner\",\"type\":\"address\"}],\"name\":\"burnSelf\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"burnStablecoin\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"chainTotalHourlyLimit\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"name\":\"chainTotalUsage\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"currentTotalUsage\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"bridgeToken\",\"type\":\"address\"}],\"name\":\"currentUsage\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"decimals\",\"outputs\":[{\"internalType\":\"uint8\",\"name\":\"\",\"type\":\"uint8\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"spender\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"subtractedValue\",\"type\":\"uint256\"}],\"name\":\"decreaseAllowance\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"spender\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"addedValue\",\"type\":\"uint256\"}],\"name\":\"increaseAllowance\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"string\",\"name\":\"name_\",\"type\":\"string\"},{\"internalType\":\"string\",\"name\":\"symbol_\",\"type\":\"string\"},{\"internalType\":\"address\",\"name\":\"_treasury\",\"type\":\"address\"}],\"name\":\"initialize\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"isFeeExempt\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"isMinter\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"mint\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"name\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"}],\"name\":\"nonces\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"spender\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"deadline\",\"type\":\"uint256\"},{\"internalType\":\"uint8\",\"name\":\"v\",\"type\":\"uint8\"},{\"internalType\":\"bytes32\",\"name\":\"r\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32\",\"name\":\"s\",\"type\":\"bytes32\"}],\"name\":\"permit\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"tokenAddress\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amountToRecover\",\"type\":\"uint256\"}],\"name\":\"recoverERC20\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"bridgeToken\",\"type\":\"address\"}],\"name\":\"removeBridgeToken\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"minter\",\"type\":\"address\"}],\"name\":\"removeMinter\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"hourlyLimit\",\"type\":\"uint256\"}],\"name\":\"setChainTotalHourlyLimit\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"bridgeToken\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"hourlyLimit\",\"type\":\"uint256\"}],\"name\":\"setHourlyLimit\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"bridgeToken\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"limit\",\"type\":\"uint256\"}],\"name\":\"setLimit\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"bridgeToken\",\"type\":\"address\"},{\"internalType\":\"uint64\",\"name\":\"fee\",\"type\":\"uint64\"}],\"name\":\"setSwapFee\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_treasury\",\"type\":\"address\"}],\"name\":\"setTreasury\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"bridgeToken\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"swapIn\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"bridgeToken\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"swapOut\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"symbol\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"bridgeToken\",\"type\":\"address\"}],\"name\":\"toggleBridge\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"theAddress\",\"type\":\"address\"}],\"name\":\"toggleFeesForAddress\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"totalSupply\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"transfer\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"transferFrom\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"treasury\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"name\":\"usage\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"}],\"devdoc\":{\"author\":\"Angle Labs, Inc.\",\"details\":\"This contract supports bridge tokens having a minting right on the stablecoin (also referred to as the canonical or the native token)\",\"kind\":\"dev\",\"methods\":{\"DOMAIN_SEPARATOR()\":{\"details\":\"See {IERC20Permit-DOMAIN_SEPARATOR}.\"},\"addBridgeToken(address,uint256,uint256,uint64,bool)\":{\"params\":{\"bridgeToken\":\"Bridge token to add: it should be a version of the stablecoin from another bridge\",\"fee\":\"Fee taken upon swapping for or against this token\",\"hourlyLimit\":\"Limit on the hourly volume for this bridge\",\"limit\":\"Limit on the balance of bridge token this contract could hold\",\"paused\":\"Whether swapping for this token should be paused or not\"}},\"addMinter(address)\":{\"details\":\"Zero address checks are performed directly in the `Treasury` contract\",\"params\":{\"minter\":\"Minter address to add\"}},\"allBridgeTokens()\":{\"details\":\"Helpful for UIs\"},\"allowance(address,address)\":{\"details\":\"See {IERC20-allowance}.\"},\"approve(address,uint256)\":{\"details\":\"See {IERC20-approve}. NOTE: If `amount` is the maximum `uint256`, the allowance is not updated on `transferFrom`. This is semantically equivalent to an infinite approval. Requirements: - `spender` cannot be the zero address.\"},\"balanceOf(address)\":{\"details\":\"See {IERC20-balanceOf}.\"},\"burnFrom(uint256,address,address)\":{\"details\":\"This method is to be called by a contract with the minter right after being requested to do so by a `sender` address willing to burn tokens from another `burner` addressThe method checks the allowance between the `sender` and the `burner`\",\"params\":{\"amount\":\"Amount of tokens to burn\",\"burner\":\"Address to burn from\",\"sender\":\"Address which requested the burn from `burner`\"}},\"burnSelf(uint256,address)\":{\"details\":\"This method is to be called by a contract with a minter right on the AgToken after being requested to do so by an address willing to burn tokens from its address\",\"params\":{\"amount\":\"Amount of tokens to burn\",\"burner\":\"Address to burn from\"}},\"burnStablecoin(uint256)\":{\"details\":\"This function can typically be called if there is a settlement mechanism to burn stablecoins\",\"params\":{\"amount\":\"Amount of stablecoins to burn\"}},\"currentTotalUsage()\":{\"details\":\"Helpful for UIs\"},\"currentUsage(address)\":{\"details\":\"Helpful for UIs\",\"params\":{\"bridgeToken\":\"Bridge used to mint\"}},\"decimals()\":{\"details\":\"Returns the number of decimals used to get its user representation. For example, if `decimals` equals `2`, a balance of `505` tokens should be displayed to a user as `5.05` (`505 / 10 ** 2`). Tokens usually opt for a value of 18, imitating the relationship between Ether and Wei. This is the value {ERC20} uses, unless this function is overridden; NOTE: This information is only used for _display_ purposes: it in no way affects any of the arithmetic of the contract, including {IERC20-balanceOf} and {IERC20-transfer}.\"},\"decreaseAllowance(address,uint256)\":{\"details\":\"Atomically decreases the allowance granted to `spender` by the caller. This is an alternative to {approve} that can be used as a mitigation for problems described in {IERC20-approve}. Emits an {Approval} event indicating the updated allowance. Requirements: - `spender` cannot be the zero address. - `spender` must have allowance for the caller of at least `subtractedValue`.\"},\"increaseAllowance(address,uint256)\":{\"details\":\"Atomically increases the allowance granted to `spender` by the caller. This is an alternative to {approve} that can be used as a mitigation for problems described in {IERC20-approve}. Emits an {Approval} event indicating the updated allowance. Requirements: - `spender` cannot be the zero address.\"},\"mint(address,uint256)\":{\"details\":\"The contracts allowed to issue agTokens are the `StableMaster` contract, `VaultManager` contracts associated to this stablecoin as well as the flash loan module (if activated) and potentially contracts whitelisted by governance\",\"params\":{\"account\":\"Address to mint to\",\"amount\":\"Amount to mint\"}},\"name()\":{\"details\":\"Returns the name of the token.\"},\"nonces(address)\":{\"details\":\"See {IERC20Permit-nonces}.\"},\"permit(address,address,uint256,uint256,uint8,bytes32,bytes32)\":{\"details\":\"See {IERC20Permit-permit}.\"},\"recoverERC20(address,address,uint256)\":{\"details\":\"Can be used to withdraw bridge tokens for them to be de-bridged on mainnet\"},\"removeBridgeToken(address)\":{\"params\":{\"bridgeToken\":\"Address of the bridge token to remove support for\"}},\"removeMinter(address)\":{\"details\":\"This function can also be called by a minter wishing to revoke itself\",\"params\":{\"minter\":\"Minter address to remove\"}},\"setTreasury(address)\":{\"params\":{\"_treasury\":\"New treasury address\"}},\"swapIn(address,uint256,address)\":{\"details\":\"Some fees may be taken by the protocol depending on the token used and on the address calling\",\"params\":{\"amount\":\"Amount of bridge tokens to send\",\"bridgeToken\":\"Bridge token to use to mint\",\"to\":\"Address to which the stablecoin should be sent\"},\"returns\":{\"_0\":\"Amount of the canonical stablecoin actually minted\"}},\"swapOut(address,uint256,address)\":{\"details\":\"Some fees may be taken by the protocol depending on the token used and on the address calling\",\"params\":{\"amount\":\"Amount of canonical tokens to burn\",\"bridgeToken\":\"Bridge token required\",\"to\":\"Address to which the bridge token should be sent\"},\"returns\":{\"_0\":\"Amount of bridge tokens actually sent back\"}},\"symbol()\":{\"details\":\"Returns the symbol of the token, usually a shorter version of the name.\"},\"totalSupply()\":{\"details\":\"See {IERC20-totalSupply}.\"},\"transfer(address,uint256)\":{\"details\":\"See {IERC20-transfer}. Requirements: - `to` cannot be the zero address. - the caller must have a balance of at least `amount`.\"},\"transferFrom(address,address,uint256)\":{\"details\":\"See {IERC20-transferFrom}. Emits an {Approval} event indicating the updated allowance. This is not required by the EIP. See the note at the beginning of {ERC20}. NOTE: Does not update the allowance if the current allowance is the maximum `uint256`. Requirements: - `from` and `to` cannot be the zero address. - `from` must have a balance of at least `amount`. - the caller must have allowance for ``from``'s tokens of at least `amount`.\"}},\"title\":\"AgTokenSideChainMultiBridge\",\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{\"BASE_PARAMS()\":{\"notice\":\"Base used for fee computation\"},\"addBridgeToken(address,uint256,uint256,uint64,bool)\":{\"notice\":\"Adds support for a bridge token\"},\"addMinter(address)\":{\"notice\":\"Adds a minter in the contract\"},\"allBridgeTokens()\":{\"notice\":\"Returns the list of all supported bridge tokens\"},\"bridgeTokensList(uint256)\":{\"notice\":\"List of all bridge tokens\"},\"bridges(address)\":{\"notice\":\"Maps a bridge token to data\"},\"burnFrom(uint256,address,address)\":{\"notice\":\"Burns `amount` tokens from a `burner` address after being asked to by `sender`\"},\"burnSelf(uint256,address)\":{\"notice\":\"Burns `amount` tokens from a `burner` address\"},\"burnStablecoin(uint256)\":{\"notice\":\"Allows anyone to burn stablecoins\"},\"chainTotalHourlyLimit()\":{\"notice\":\"Limit to the amount of tokens that can be sent from that chain to another chain\"},\"chainTotalUsage(uint256)\":{\"notice\":\"Usage per hour on that chain. Maps an hourly timestamp to the total volume swapped out on the chain\"},\"currentTotalUsage()\":{\"notice\":\"Returns the current total volume on the chain for the current hour\"},\"currentUsage(address)\":{\"notice\":\"Returns the current volume for a bridge, for the current hour\"},\"initialize(string,string,address)\":{\"notice\":\"Initializes the `AgToken` contract\"},\"isFeeExempt(address)\":{\"notice\":\"Maps an address to whether it is exempt of fees for when it comes to swapping in and out\"},\"isMinter(address)\":{\"notice\":\"Checks whether an address has the right to mint agTokens\"},\"mint(address,uint256)\":{\"notice\":\"Lets the `StableMaster` contract or another whitelisted contract mint agTokens\"},\"recoverERC20(address,address,uint256)\":{\"notice\":\"Recovers any ERC20 token\"},\"removeBridgeToken(address)\":{\"notice\":\"Removes support for a token\"},\"removeMinter(address)\":{\"notice\":\"Removes a minter from the contract\"},\"setChainTotalHourlyLimit(uint256)\":{\"notice\":\"Updates the `chainTotalHourlyLimit` amount\"},\"setHourlyLimit(address,uint256)\":{\"notice\":\"Updates the `hourlyLimit` amount for `bridgeToken`\"},\"setLimit(address,uint256)\":{\"notice\":\"Updates the `limit` amount for `bridgeToken`\"},\"setSwapFee(address,uint64)\":{\"notice\":\"Updates the `fee` value for `bridgeToken`\"},\"setTreasury(address)\":{\"notice\":\"Sets a new treasury contract\"},\"swapIn(address,uint256,address)\":{\"notice\":\"Mints the canonical token from a supported bridge token\"},\"swapOut(address,uint256,address)\":{\"notice\":\"Burns the canonical token in exchange for a bridge token\"},\"toggleBridge(address)\":{\"notice\":\"Pauses or unpauses swapping in and out for a token\"},\"toggleFeesForAddress(address)\":{\"notice\":\"Toggles fees for the address `theAddress`\"},\"treasury()\":{\"notice\":\"Reference to the treasury contract which can grant minting rights\"},\"usage(address,uint256)\":{\"notice\":\"Maps a bridge token to the associated hourly volume\"}},\"notice\":\"Contract for Angle agTokens on other chains than Ethereum mainnet\",\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/agToken/AgTokenSideChainMultiBridge.sol\":\"AgTokenSideChainMultiBridge\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":1000000},\"remappings\":[]},\"sources\":{\"@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.7.0) (proxy/utils/Initializable.sol)\\n\\npragma solidity ^0.8.2;\\n\\nimport \\\"../../utils/AddressUpgradeable.sol\\\";\\n\\n/**\\n * @dev This is a base contract to aid in writing upgradeable contracts, or any kind of contract that will be deployed\\n * behind a proxy. Since proxied contracts do not make use of a constructor, it's common to move constructor logic to an\\n * external initializer function, usually called `initialize`. It then becomes necessary to protect this initializer\\n * function so it can only be called once. The {initializer} modifier provided by this contract will have this effect.\\n *\\n * The initialization functions use a version number. Once a version number is used, it is consumed and cannot be\\n * reused. This mechanism prevents re-execution of each \\\"step\\\" but allows the creation of new initialization steps in\\n * case an upgrade adds a module that needs to be initialized.\\n *\\n * For example:\\n *\\n * [.hljs-theme-light.nopadding]\\n * ```\\n * contract MyToken is ERC20Upgradeable {\\n * function initialize() initializer public {\\n * __ERC20_init(\\\"MyToken\\\", \\\"MTK\\\");\\n * }\\n * }\\n * contract MyTokenV2 is MyToken, ERC20PermitUpgradeable {\\n * function initializeV2() reinitializer(2) public {\\n * __ERC20Permit_init(\\\"MyToken\\\");\\n * }\\n * }\\n * ```\\n *\\n * TIP: To avoid leaving the proxy in an uninitialized state, the initializer function should be called as early as\\n * possible by providing the encoded function call as the `_data` argument to {ERC1967Proxy-constructor}.\\n *\\n * CAUTION: When used with inheritance, manual care must be taken to not invoke a parent initializer twice, or to ensure\\n * that all initializers are idempotent. This is not verified automatically as constructors are by Solidity.\\n *\\n * [CAUTION]\\n * ====\\n * Avoid leaving a contract uninitialized.\\n *\\n * An uninitialized contract can be taken over by an attacker. This applies to both a proxy and its implementation\\n * contract, which may impact the proxy. To prevent the implementation contract from being used, you should invoke\\n * the {_disableInitializers} function in the constructor to automatically lock it when it is deployed:\\n *\\n * [.hljs-theme-light.nopadding]\\n * ```\\n * /// @custom:oz-upgrades-unsafe-allow constructor\\n * constructor() {\\n * _disableInitializers();\\n * }\\n * ```\\n * ====\\n */\\nabstract contract Initializable {\\n /**\\n * @dev Indicates that the contract has been initialized.\\n * @custom:oz-retyped-from bool\\n */\\n uint8 private _initialized;\\n\\n /**\\n * @dev Indicates that the contract is in the process of being initialized.\\n */\\n bool private _initializing;\\n\\n /**\\n * @dev Triggered when the contract has been initialized or reinitialized.\\n */\\n event Initialized(uint8 version);\\n\\n /**\\n * @dev A modifier that defines a protected initializer function that can be invoked at most once. In its scope,\\n * `onlyInitializing` functions can be used to initialize parent contracts. Equivalent to `reinitializer(1)`.\\n */\\n modifier initializer() {\\n bool isTopLevelCall = !_initializing;\\n require(\\n (isTopLevelCall && _initialized < 1) || (!AddressUpgradeable.isContract(address(this)) && _initialized == 1),\\n \\\"Initializable: contract is already initialized\\\"\\n );\\n _initialized = 1;\\n if (isTopLevelCall) {\\n _initializing = true;\\n }\\n _;\\n if (isTopLevelCall) {\\n _initializing = false;\\n emit Initialized(1);\\n }\\n }\\n\\n /**\\n * @dev A modifier that defines a protected reinitializer function that can be invoked at most once, and only if the\\n * contract hasn't been initialized to a greater version before. In its scope, `onlyInitializing` functions can be\\n * used to initialize parent contracts.\\n *\\n * `initializer` is equivalent to `reinitializer(1)`, so a reinitializer may be used after the original\\n * initialization step. This is essential to configure modules that are added through upgrades and that require\\n * initialization.\\n *\\n * Note that versions can jump in increments greater than 1; this implies that if multiple reinitializers coexist in\\n * a contract, executing them in the right order is up to the developer or operator.\\n */\\n modifier reinitializer(uint8 version) {\\n require(!_initializing && _initialized < version, \\\"Initializable: contract is already initialized\\\");\\n _initialized = version;\\n _initializing = true;\\n _;\\n _initializing = false;\\n emit Initialized(version);\\n }\\n\\n /**\\n * @dev Modifier to protect an initialization function so that it can only be invoked by functions with the\\n * {initializer} and {reinitializer} modifiers, directly or indirectly.\\n */\\n modifier onlyInitializing() {\\n require(_initializing, \\\"Initializable: contract is not initializing\\\");\\n _;\\n }\\n\\n /**\\n * @dev Locks the contract, preventing any future reinitialization. This cannot be part of an initializer call.\\n * Calling this in the constructor of a contract will prevent that contract from being initialized or reinitialized\\n * to any version. It is recommended to use this to lock implementation contracts that are designed to be called\\n * through proxies.\\n */\\n function _disableInitializers() internal virtual {\\n require(!_initializing, \\\"Initializable: contract is initializing\\\");\\n if (_initialized < type(uint8).max) {\\n _initialized = type(uint8).max;\\n emit Initialized(type(uint8).max);\\n }\\n }\\n}\\n\",\"keccak256\":\"0x0203dcadc5737d9ef2c211d6fa15d18ebc3b30dfa51903b64870b01a062b0b4e\",\"license\":\"MIT\"},\"@openzeppelin/contracts-upgradeable/token/ERC20/ERC20Upgradeable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.7.0) (token/ERC20/ERC20.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"./IERC20Upgradeable.sol\\\";\\nimport \\\"./extensions/IERC20MetadataUpgradeable.sol\\\";\\nimport \\\"../../utils/ContextUpgradeable.sol\\\";\\nimport \\\"../../proxy/utils/Initializable.sol\\\";\\n\\n/**\\n * @dev Implementation of the {IERC20} interface.\\n *\\n * This implementation is agnostic to the way tokens are created. This means\\n * that a supply mechanism has to be added in a derived contract using {_mint}.\\n * For a generic mechanism see {ERC20PresetMinterPauser}.\\n *\\n * TIP: For a detailed writeup see our guide\\n * https://forum.zeppelin.solutions/t/how-to-implement-erc20-supply-mechanisms/226[How\\n * to implement supply mechanisms].\\n *\\n * We have followed general OpenZeppelin Contracts guidelines: functions revert\\n * instead returning `false` on failure. This behavior is nonetheless\\n * conventional and does not conflict with the expectations of ERC20\\n * applications.\\n *\\n * Additionally, an {Approval} event is emitted on calls to {transferFrom}.\\n * This allows applications to reconstruct the allowance for all accounts just\\n * by listening to said events. Other implementations of the EIP may not emit\\n * these events, as it isn't required by the specification.\\n *\\n * Finally, the non-standard {decreaseAllowance} and {increaseAllowance}\\n * functions have been added to mitigate the well-known issues around setting\\n * allowances. See {IERC20-approve}.\\n */\\ncontract ERC20Upgradeable is Initializable, ContextUpgradeable, IERC20Upgradeable, IERC20MetadataUpgradeable {\\n mapping(address => uint256) private _balances;\\n\\n mapping(address => mapping(address => uint256)) private _allowances;\\n\\n uint256 private _totalSupply;\\n\\n string private _name;\\n string private _symbol;\\n\\n /**\\n * @dev Sets the values for {name} and {symbol}.\\n *\\n * The default value of {decimals} is 18. To select a different value for\\n * {decimals} you should overload it.\\n *\\n * All two of these values are immutable: they can only be set once during\\n * construction.\\n */\\n function __ERC20_init(string memory name_, string memory symbol_) internal onlyInitializing {\\n __ERC20_init_unchained(name_, symbol_);\\n }\\n\\n function __ERC20_init_unchained(string memory name_, string memory symbol_) internal onlyInitializing {\\n _name = name_;\\n _symbol = symbol_;\\n }\\n\\n /**\\n * @dev Returns the name of the token.\\n */\\n function name() public view virtual override returns (string memory) {\\n return _name;\\n }\\n\\n /**\\n * @dev Returns the symbol of the token, usually a shorter version of the\\n * name.\\n */\\n function symbol() public view virtual override returns (string memory) {\\n return _symbol;\\n }\\n\\n /**\\n * @dev Returns the number of decimals used to get its user representation.\\n * For example, if `decimals` equals `2`, a balance of `505` tokens should\\n * be displayed to a user as `5.05` (`505 / 10 ** 2`).\\n *\\n * Tokens usually opt for a value of 18, imitating the relationship between\\n * Ether and Wei. This is the value {ERC20} uses, unless this function is\\n * overridden;\\n *\\n * NOTE: This information is only used for _display_ purposes: it in\\n * no way affects any of the arithmetic of the contract, including\\n * {IERC20-balanceOf} and {IERC20-transfer}.\\n */\\n function decimals() public view virtual override returns (uint8) {\\n return 18;\\n }\\n\\n /**\\n * @dev See {IERC20-totalSupply}.\\n */\\n function totalSupply() public view virtual override returns (uint256) {\\n return _totalSupply;\\n }\\n\\n /**\\n * @dev See {IERC20-balanceOf}.\\n */\\n function balanceOf(address account) public view virtual override returns (uint256) {\\n return _balances[account];\\n }\\n\\n /**\\n * @dev See {IERC20-transfer}.\\n *\\n * Requirements:\\n *\\n * - `to` cannot be the zero address.\\n * - the caller must have a balance of at least `amount`.\\n */\\n function transfer(address to, uint256 amount) public virtual override returns (bool) {\\n address owner = _msgSender();\\n _transfer(owner, to, amount);\\n return true;\\n }\\n\\n /**\\n * @dev See {IERC20-allowance}.\\n */\\n function allowance(address owner, address spender) public view virtual override returns (uint256) {\\n return _allowances[owner][spender];\\n }\\n\\n /**\\n * @dev See {IERC20-approve}.\\n *\\n * NOTE: If `amount` is the maximum `uint256`, the allowance is not updated on\\n * `transferFrom`. This is semantically equivalent to an infinite approval.\\n *\\n * Requirements:\\n *\\n * - `spender` cannot be the zero address.\\n */\\n function approve(address spender, uint256 amount) public virtual override returns (bool) {\\n address owner = _msgSender();\\n _approve(owner, spender, amount);\\n return true;\\n }\\n\\n /**\\n * @dev See {IERC20-transferFrom}.\\n *\\n * Emits an {Approval} event indicating the updated allowance. This is not\\n * required by the EIP. See the note at the beginning of {ERC20}.\\n *\\n * NOTE: Does not update the allowance if the current allowance\\n * is the maximum `uint256`.\\n *\\n * Requirements:\\n *\\n * - `from` and `to` cannot be the zero address.\\n * - `from` must have a balance of at least `amount`.\\n * - the caller must have allowance for ``from``'s tokens of at least\\n * `amount`.\\n */\\n function transferFrom(\\n address from,\\n address to,\\n uint256 amount\\n ) public virtual override returns (bool) {\\n address spender = _msgSender();\\n _spendAllowance(from, spender, amount);\\n _transfer(from, to, amount);\\n return true;\\n }\\n\\n /**\\n * @dev Atomically increases the allowance granted to `spender` by the caller.\\n *\\n * This is an alternative to {approve} that can be used as a mitigation for\\n * problems described in {IERC20-approve}.\\n *\\n * Emits an {Approval} event indicating the updated allowance.\\n *\\n * Requirements:\\n *\\n * - `spender` cannot be the zero address.\\n */\\n function increaseAllowance(address spender, uint256 addedValue) public virtual returns (bool) {\\n address owner = _msgSender();\\n _approve(owner, spender, allowance(owner, spender) + addedValue);\\n return true;\\n }\\n\\n /**\\n * @dev Atomically decreases the allowance granted to `spender` by the caller.\\n *\\n * This is an alternative to {approve} that can be used as a mitigation for\\n * problems described in {IERC20-approve}.\\n *\\n * Emits an {Approval} event indicating the updated allowance.\\n *\\n * Requirements:\\n *\\n * - `spender` cannot be the zero address.\\n * - `spender` must have allowance for the caller of at least\\n * `subtractedValue`.\\n */\\n function decreaseAllowance(address spender, uint256 subtractedValue) public virtual returns (bool) {\\n address owner = _msgSender();\\n uint256 currentAllowance = allowance(owner, spender);\\n require(currentAllowance >= subtractedValue, \\\"ERC20: decreased allowance below zero\\\");\\n unchecked {\\n _approve(owner, spender, currentAllowance - subtractedValue);\\n }\\n\\n return true;\\n }\\n\\n /**\\n * @dev Moves `amount` of tokens from `from` to `to`.\\n *\\n * This internal function is equivalent to {transfer}, and can be used to\\n * e.g. implement automatic token fees, slashing mechanisms, etc.\\n *\\n * Emits a {Transfer} event.\\n *\\n * Requirements:\\n *\\n * - `from` cannot be the zero address.\\n * - `to` cannot be the zero address.\\n * - `from` must have a balance of at least `amount`.\\n */\\n function _transfer(\\n address from,\\n address to,\\n uint256 amount\\n ) internal virtual {\\n require(from != address(0), \\\"ERC20: transfer from the zero address\\\");\\n require(to != address(0), \\\"ERC20: transfer to the zero address\\\");\\n\\n _beforeTokenTransfer(from, to, amount);\\n\\n uint256 fromBalance = _balances[from];\\n require(fromBalance >= amount, \\\"ERC20: transfer amount exceeds balance\\\");\\n unchecked {\\n _balances[from] = fromBalance - amount;\\n }\\n _balances[to] += amount;\\n\\n emit Transfer(from, to, amount);\\n\\n _afterTokenTransfer(from, to, amount);\\n }\\n\\n /** @dev Creates `amount` tokens and assigns them to `account`, increasing\\n * the total supply.\\n *\\n * Emits a {Transfer} event with `from` set to the zero address.\\n *\\n * Requirements:\\n *\\n * - `account` cannot be the zero address.\\n */\\n function _mint(address account, uint256 amount) internal virtual {\\n require(account != address(0), \\\"ERC20: mint to the zero address\\\");\\n\\n _beforeTokenTransfer(address(0), account, amount);\\n\\n _totalSupply += amount;\\n _balances[account] += amount;\\n emit Transfer(address(0), account, amount);\\n\\n _afterTokenTransfer(address(0), account, amount);\\n }\\n\\n /**\\n * @dev Destroys `amount` tokens from `account`, reducing the\\n * total supply.\\n *\\n * Emits a {Transfer} event with `to` set to the zero address.\\n *\\n * Requirements:\\n *\\n * - `account` cannot be the zero address.\\n * - `account` must have at least `amount` tokens.\\n */\\n function _burn(address account, uint256 amount) internal virtual {\\n require(account != address(0), \\\"ERC20: burn from the zero address\\\");\\n\\n _beforeTokenTransfer(account, address(0), amount);\\n\\n uint256 accountBalance = _balances[account];\\n require(accountBalance >= amount, \\\"ERC20: burn amount exceeds balance\\\");\\n unchecked {\\n _balances[account] = accountBalance - amount;\\n }\\n _totalSupply -= amount;\\n\\n emit Transfer(account, address(0), amount);\\n\\n _afterTokenTransfer(account, address(0), amount);\\n }\\n\\n /**\\n * @dev Sets `amount` as the allowance of `spender` over the `owner` s tokens.\\n *\\n * This internal function is equivalent to `approve`, and can be used to\\n * e.g. set automatic allowances for certain subsystems, etc.\\n *\\n * Emits an {Approval} event.\\n *\\n * Requirements:\\n *\\n * - `owner` cannot be the zero address.\\n * - `spender` cannot be the zero address.\\n */\\n function _approve(\\n address owner,\\n address spender,\\n uint256 amount\\n ) internal virtual {\\n require(owner != address(0), \\\"ERC20: approve from the zero address\\\");\\n require(spender != address(0), \\\"ERC20: approve to the zero address\\\");\\n\\n _allowances[owner][spender] = amount;\\n emit Approval(owner, spender, amount);\\n }\\n\\n /**\\n * @dev Updates `owner` s allowance for `spender` based on spent `amount`.\\n *\\n * Does not update the allowance amount in case of infinite allowance.\\n * Revert if not enough allowance is available.\\n *\\n * Might emit an {Approval} event.\\n */\\n function _spendAllowance(\\n address owner,\\n address spender,\\n uint256 amount\\n ) internal virtual {\\n uint256 currentAllowance = allowance(owner, spender);\\n if (currentAllowance != type(uint256).max) {\\n require(currentAllowance >= amount, \\\"ERC20: insufficient allowance\\\");\\n unchecked {\\n _approve(owner, spender, currentAllowance - amount);\\n }\\n }\\n }\\n\\n /**\\n * @dev Hook that is called before any transfer of tokens. This includes\\n * minting and burning.\\n *\\n * Calling conditions:\\n *\\n * - when `from` and `to` are both non-zero, `amount` of ``from``'s tokens\\n * will be transferred to `to`.\\n * - when `from` is zero, `amount` tokens will be minted for `to`.\\n * - when `to` is zero, `amount` of ``from``'s tokens will be burned.\\n * - `from` and `to` are never both zero.\\n *\\n * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].\\n */\\n function _beforeTokenTransfer(\\n address from,\\n address to,\\n uint256 amount\\n ) internal virtual {}\\n\\n /**\\n * @dev Hook that is called after any transfer of tokens. This includes\\n * minting and burning.\\n *\\n * Calling conditions:\\n *\\n * - when `from` and `to` are both non-zero, `amount` of ``from``'s tokens\\n * has been transferred to `to`.\\n * - when `from` is zero, `amount` tokens have been minted for `to`.\\n * - when `to` is zero, `amount` of ``from``'s tokens have been burned.\\n * - `from` and `to` are never both zero.\\n *\\n * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].\\n */\\n function _afterTokenTransfer(\\n address from,\\n address to,\\n uint256 amount\\n ) internal virtual {}\\n\\n /**\\n * @dev This empty reserved space is put in place to allow future versions to add new\\n * variables without shifting down storage in the inheritance chain.\\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\\n */\\n uint256[45] private __gap;\\n}\\n\",\"keccak256\":\"0x7c7ac0bc6c340a7f320524b9a4b4b079ee9da3c51258080d4bab237f329a427c\",\"license\":\"MIT\"},\"@openzeppelin/contracts-upgradeable/token/ERC20/IERC20Upgradeable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.6.0) (token/ERC20/IERC20.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Interface of the ERC20 standard as defined in the EIP.\\n */\\ninterface IERC20Upgradeable {\\n /**\\n * @dev Emitted when `value` tokens are moved from one account (`from`) to\\n * another (`to`).\\n *\\n * Note that `value` may be zero.\\n */\\n event Transfer(address indexed from, address indexed to, uint256 value);\\n\\n /**\\n * @dev Emitted when the allowance of a `spender` for an `owner` is set by\\n * a call to {approve}. `value` is the new allowance.\\n */\\n event Approval(address indexed owner, address indexed spender, uint256 value);\\n\\n /**\\n * @dev Returns the amount of tokens in existence.\\n */\\n function totalSupply() external view returns (uint256);\\n\\n /**\\n * @dev Returns the amount of tokens owned by `account`.\\n */\\n function balanceOf(address account) external view returns (uint256);\\n\\n /**\\n * @dev Moves `amount` tokens from the caller's account to `to`.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * Emits a {Transfer} event.\\n */\\n function transfer(address to, uint256 amount) external returns (bool);\\n\\n /**\\n * @dev Returns the remaining number of tokens that `spender` will be\\n * allowed to spend on behalf of `owner` through {transferFrom}. This is\\n * zero by default.\\n *\\n * This value changes when {approve} or {transferFrom} are called.\\n */\\n function allowance(address owner, address spender) external view returns (uint256);\\n\\n /**\\n * @dev Sets `amount` as the allowance of `spender` over the caller's tokens.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * IMPORTANT: Beware that changing an allowance with this method brings the risk\\n * that someone may use both the old and the new allowance by unfortunate\\n * transaction ordering. One possible solution to mitigate this race\\n * condition is to first reduce the spender's allowance to 0 and set the\\n * desired value afterwards:\\n * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729\\n *\\n * Emits an {Approval} event.\\n */\\n function approve(address spender, uint256 amount) external returns (bool);\\n\\n /**\\n * @dev Moves `amount` tokens from `from` to `to` using the\\n * allowance mechanism. `amount` is then deducted from the caller's\\n * allowance.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * Emits a {Transfer} event.\\n */\\n function transferFrom(\\n address from,\\n address to,\\n uint256 amount\\n ) external returns (bool);\\n}\\n\",\"keccak256\":\"0x4e733d3164f73f461eaf9d8087a7ad1ea180bdc8ba0d3d61b0e1ae16d8e63dff\",\"license\":\"MIT\"},\"@openzeppelin/contracts-upgradeable/token/ERC20/extensions/IERC20MetadataUpgradeable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (token/ERC20/extensions/IERC20Metadata.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../IERC20Upgradeable.sol\\\";\\n\\n/**\\n * @dev Interface for the optional metadata functions from the ERC20 standard.\\n *\\n * _Available since v4.1._\\n */\\ninterface IERC20MetadataUpgradeable is IERC20Upgradeable {\\n /**\\n * @dev Returns the name of the token.\\n */\\n function name() external view returns (string memory);\\n\\n /**\\n * @dev Returns the symbol of the token.\\n */\\n function symbol() external view returns (string memory);\\n\\n /**\\n * @dev Returns the decimals places of the token.\\n */\\n function decimals() external view returns (uint8);\\n}\\n\",\"keccak256\":\"0x605434219ebbe4653f703640f06969faa5a1d78f0bfef878e5ddbb1ca369ceeb\",\"license\":\"MIT\"},\"@openzeppelin/contracts-upgradeable/token/ERC20/extensions/draft-ERC20PermitUpgradeable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.6.0) (token/ERC20/extensions/draft-ERC20Permit.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"./draft-IERC20PermitUpgradeable.sol\\\";\\nimport \\\"../ERC20Upgradeable.sol\\\";\\nimport \\\"../../../utils/cryptography/draft-EIP712Upgradeable.sol\\\";\\nimport \\\"../../../utils/cryptography/ECDSAUpgradeable.sol\\\";\\nimport \\\"../../../utils/CountersUpgradeable.sol\\\";\\nimport \\\"../../../proxy/utils/Initializable.sol\\\";\\n\\n/**\\n * @dev Implementation of the ERC20 Permit extension allowing approvals to be made via signatures, as defined in\\n * https://eips.ethereum.org/EIPS/eip-2612[EIP-2612].\\n *\\n * Adds the {permit} method, which can be used to change an account's ERC20 allowance (see {IERC20-allowance}) by\\n * presenting a message signed by the account. By not relying on `{IERC20-approve}`, the token holder account doesn't\\n * need to send a transaction, and thus is not required to hold Ether at all.\\n *\\n * _Available since v3.4._\\n *\\n * @custom:storage-size 51\\n */\\nabstract contract ERC20PermitUpgradeable is Initializable, ERC20Upgradeable, IERC20PermitUpgradeable, EIP712Upgradeable {\\n using CountersUpgradeable for CountersUpgradeable.Counter;\\n\\n mapping(address => CountersUpgradeable.Counter) private _nonces;\\n\\n // solhint-disable-next-line var-name-mixedcase\\n bytes32 private constant _PERMIT_TYPEHASH =\\n keccak256(\\\"Permit(address owner,address spender,uint256 value,uint256 nonce,uint256 deadline)\\\");\\n /**\\n * @dev In previous versions `_PERMIT_TYPEHASH` was declared as `immutable`.\\n * However, to ensure consistency with the upgradeable transpiler, we will continue\\n * to reserve a slot.\\n * @custom:oz-renamed-from _PERMIT_TYPEHASH\\n */\\n // solhint-disable-next-line var-name-mixedcase\\n bytes32 private _PERMIT_TYPEHASH_DEPRECATED_SLOT;\\n\\n /**\\n * @dev Initializes the {EIP712} domain separator using the `name` parameter, and setting `version` to `\\\"1\\\"`.\\n *\\n * It's a good idea to use the same `name` that is defined as the ERC20 token name.\\n */\\n function __ERC20Permit_init(string memory name) internal onlyInitializing {\\n __EIP712_init_unchained(name, \\\"1\\\");\\n }\\n\\n function __ERC20Permit_init_unchained(string memory) internal onlyInitializing {}\\n\\n /**\\n * @dev See {IERC20Permit-permit}.\\n */\\n function permit(\\n address owner,\\n address spender,\\n uint256 value,\\n uint256 deadline,\\n uint8 v,\\n bytes32 r,\\n bytes32 s\\n ) public virtual override {\\n require(block.timestamp <= deadline, \\\"ERC20Permit: expired deadline\\\");\\n\\n bytes32 structHash = keccak256(abi.encode(_PERMIT_TYPEHASH, owner, spender, value, _useNonce(owner), deadline));\\n\\n bytes32 hash = _hashTypedDataV4(structHash);\\n\\n address signer = ECDSAUpgradeable.recover(hash, v, r, s);\\n require(signer == owner, \\\"ERC20Permit: invalid signature\\\");\\n\\n _approve(owner, spender, value);\\n }\\n\\n /**\\n * @dev See {IERC20Permit-nonces}.\\n */\\n function nonces(address owner) public view virtual override returns (uint256) {\\n return _nonces[owner].current();\\n }\\n\\n /**\\n * @dev See {IERC20Permit-DOMAIN_SEPARATOR}.\\n */\\n // solhint-disable-next-line func-name-mixedcase\\n function DOMAIN_SEPARATOR() external view override returns (bytes32) {\\n return _domainSeparatorV4();\\n }\\n\\n /**\\n * @dev \\\"Consume a nonce\\\": return the current value and increment.\\n *\\n * _Available since v4.1._\\n */\\n function _useNonce(address owner) internal virtual returns (uint256 current) {\\n CountersUpgradeable.Counter storage nonce = _nonces[owner];\\n current = nonce.current();\\n nonce.increment();\\n }\\n\\n /**\\n * @dev This empty reserved space is put in place to allow future versions to add new\\n * variables without shifting down storage in the inheritance chain.\\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\\n */\\n uint256[49] private __gap;\\n}\\n\",\"keccak256\":\"0x564385ebed633694decce3e13d687f3ac7e8eaef64f7a504bfb3f03ad210601f\",\"license\":\"MIT\"},\"@openzeppelin/contracts-upgradeable/token/ERC20/extensions/draft-IERC20PermitUpgradeable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (token/ERC20/extensions/draft-IERC20Permit.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Interface of the ERC20 Permit extension allowing approvals to be made via signatures, as defined in\\n * https://eips.ethereum.org/EIPS/eip-2612[EIP-2612].\\n *\\n * Adds the {permit} method, which can be used to change an account's ERC20 allowance (see {IERC20-allowance}) by\\n * presenting a message signed by the account. By not relying on {IERC20-approve}, the token holder account doesn't\\n * need to send a transaction, and thus is not required to hold Ether at all.\\n */\\ninterface IERC20PermitUpgradeable {\\n /**\\n * @dev Sets `value` as the allowance of `spender` over ``owner``'s tokens,\\n * given ``owner``'s signed approval.\\n *\\n * IMPORTANT: The same issues {IERC20-approve} has related to transaction\\n * ordering also apply here.\\n *\\n * Emits an {Approval} event.\\n *\\n * Requirements:\\n *\\n * - `spender` cannot be the zero address.\\n * - `deadline` must be a timestamp in the future.\\n * - `v`, `r` and `s` must be a valid `secp256k1` signature from `owner`\\n * over the EIP712-formatted function arguments.\\n * - the signature must use ``owner``'s current nonce (see {nonces}).\\n *\\n * For more information on the signature format, see the\\n * https://eips.ethereum.org/EIPS/eip-2612#specification[relevant EIP\\n * section].\\n */\\n function permit(\\n address owner,\\n address spender,\\n uint256 value,\\n uint256 deadline,\\n uint8 v,\\n bytes32 r,\\n bytes32 s\\n ) external;\\n\\n /**\\n * @dev Returns the current nonce for `owner`. This value must be\\n * included whenever a signature is generated for {permit}.\\n *\\n * Every successful call to {permit} increases ``owner``'s nonce by one. This\\n * prevents a signature from being used multiple times.\\n */\\n function nonces(address owner) external view returns (uint256);\\n\\n /**\\n * @dev Returns the domain separator used in the encoding of the signature for {permit}, as defined by {EIP712}.\\n */\\n // solhint-disable-next-line func-name-mixedcase\\n function DOMAIN_SEPARATOR() external view returns (bytes32);\\n}\\n\",\"keccak256\":\"0xcc70d8e2281fb3ff69e8ab242500f10142cd0a7fa8dd9e45882be270d4d09024\",\"license\":\"MIT\"},\"@openzeppelin/contracts-upgradeable/utils/AddressUpgradeable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.7.0) (utils/Address.sol)\\n\\npragma solidity ^0.8.1;\\n\\n/**\\n * @dev Collection of functions related to the address type\\n */\\nlibrary AddressUpgradeable {\\n /**\\n * @dev Returns true if `account` is a contract.\\n *\\n * [IMPORTANT]\\n * ====\\n * It is unsafe to assume that an address for which this function returns\\n * false is an externally-owned account (EOA) and not a contract.\\n *\\n * Among others, `isContract` will return false for the following\\n * types of addresses:\\n *\\n * - an externally-owned account\\n * - a contract in construction\\n * - an address where a contract will be created\\n * - an address where a contract lived, but was destroyed\\n * ====\\n *\\n * [IMPORTANT]\\n * ====\\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\\n *\\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\\n * constructor.\\n * ====\\n */\\n function isContract(address account) internal view returns (bool) {\\n // This method relies on extcodesize/address.code.length, which returns 0\\n // for contracts in construction, since the code is only stored at the end\\n // of the constructor execution.\\n\\n return account.code.length > 0;\\n }\\n\\n /**\\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\\n * `recipient`, forwarding all available gas and reverting on errors.\\n *\\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\\n * imposed by `transfer`, making them unable to receive funds via\\n * `transfer`. {sendValue} removes this limitation.\\n *\\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\\n *\\n * IMPORTANT: because control is transferred to `recipient`, care must be\\n * taken to not create reentrancy vulnerabilities. Consider using\\n * {ReentrancyGuard} or the\\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\\n */\\n function sendValue(address payable recipient, uint256 amount) internal {\\n require(address(this).balance >= amount, \\\"Address: insufficient balance\\\");\\n\\n (bool success, ) = recipient.call{value: amount}(\\\"\\\");\\n require(success, \\\"Address: unable to send value, recipient may have reverted\\\");\\n }\\n\\n /**\\n * @dev Performs a Solidity function call using a low level `call`. A\\n * plain `call` is an unsafe replacement for a function call: use this\\n * function instead.\\n *\\n * If `target` reverts with a revert reason, it is bubbled up by this\\n * function (like regular Solidity function calls).\\n *\\n * Returns the raw returned data. To convert to the expected return value,\\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\\n *\\n * Requirements:\\n *\\n * - `target` must be a contract.\\n * - calling `target` with `data` must not revert.\\n *\\n * _Available since v3.1._\\n */\\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\\n return functionCall(target, data, \\\"Address: low-level call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\\n * `errorMessage` as a fallback revert reason when `target` reverts.\\n *\\n * _Available since v3.1._\\n */\\n function functionCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n return functionCallWithValue(target, data, 0, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but also transferring `value` wei to `target`.\\n *\\n * Requirements:\\n *\\n * - the calling contract must have an ETH balance of at least `value`.\\n * - the called Solidity function must be `payable`.\\n *\\n * _Available since v3.1._\\n */\\n function functionCallWithValue(\\n address target,\\n bytes memory data,\\n uint256 value\\n ) internal returns (bytes memory) {\\n return functionCallWithValue(target, data, value, \\\"Address: low-level call with value failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\\n * with `errorMessage` as a fallback revert reason when `target` reverts.\\n *\\n * _Available since v3.1._\\n */\\n function functionCallWithValue(\\n address target,\\n bytes memory data,\\n uint256 value,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n require(address(this).balance >= value, \\\"Address: insufficient balance for call\\\");\\n require(isContract(target), \\\"Address: call to non-contract\\\");\\n\\n (bool success, bytes memory returndata) = target.call{value: value}(data);\\n return verifyCallResult(success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but performing a static call.\\n *\\n * _Available since v3.3._\\n */\\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\\n return functionStaticCall(target, data, \\\"Address: low-level static call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\\n * but performing a static call.\\n *\\n * _Available since v3.3._\\n */\\n function functionStaticCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal view returns (bytes memory) {\\n require(isContract(target), \\\"Address: static call to non-contract\\\");\\n\\n (bool success, bytes memory returndata) = target.staticcall(data);\\n return verifyCallResult(success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the\\n * revert reason using the provided one.\\n *\\n * _Available since v4.3._\\n */\\n function verifyCallResult(\\n bool success,\\n bytes memory returndata,\\n string memory errorMessage\\n ) internal pure returns (bytes memory) {\\n if (success) {\\n return returndata;\\n } else {\\n // Look for revert reason and bubble it up if present\\n if (returndata.length > 0) {\\n // The easiest way to bubble the revert reason is using memory via assembly\\n /// @solidity memory-safe-assembly\\n assembly {\\n let returndata_size := mload(returndata)\\n revert(add(32, returndata), returndata_size)\\n }\\n } else {\\n revert(errorMessage);\\n }\\n }\\n }\\n}\\n\",\"keccak256\":\"0x611aa3f23e59cfdd1863c536776407b3e33d695152a266fa7cfb34440a29a8a3\",\"license\":\"MIT\"},\"@openzeppelin/contracts-upgradeable/utils/ContextUpgradeable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)\\n\\npragma solidity ^0.8.0;\\nimport \\\"../proxy/utils/Initializable.sol\\\";\\n\\n/**\\n * @dev Provides information about the current execution context, including the\\n * sender of the transaction and its data. While these are generally available\\n * via msg.sender and msg.data, they should not be accessed in such a direct\\n * manner, since when dealing with meta-transactions the account sending and\\n * paying for execution may not be the actual sender (as far as an application\\n * is concerned).\\n *\\n * This contract is only required for intermediate, library-like contracts.\\n */\\nabstract contract ContextUpgradeable is Initializable {\\n function __Context_init() internal onlyInitializing {\\n }\\n\\n function __Context_init_unchained() internal onlyInitializing {\\n }\\n function _msgSender() internal view virtual returns (address) {\\n return msg.sender;\\n }\\n\\n function _msgData() internal view virtual returns (bytes calldata) {\\n return msg.data;\\n }\\n\\n /**\\n * @dev This empty reserved space is put in place to allow future versions to add new\\n * variables without shifting down storage in the inheritance chain.\\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\\n */\\n uint256[50] private __gap;\\n}\\n\",\"keccak256\":\"0x963ea7f0b48b032eef72fe3a7582edf78408d6f834115b9feadd673a4d5bd149\",\"license\":\"MIT\"},\"@openzeppelin/contracts-upgradeable/utils/CountersUpgradeable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (utils/Counters.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @title Counters\\n * @author Matt Condon (@shrugs)\\n * @dev Provides counters that can only be incremented, decremented or reset. This can be used e.g. to track the number\\n * of elements in a mapping, issuing ERC721 ids, or counting request ids.\\n *\\n * Include with `using Counters for Counters.Counter;`\\n */\\nlibrary CountersUpgradeable {\\n struct Counter {\\n // This variable should never be directly accessed by users of the library: interactions must be restricted to\\n // the library's function. As of Solidity v0.5.2, this cannot be enforced, though there is a proposal to add\\n // this feature: see https://github.com/ethereum/solidity/issues/4637\\n uint256 _value; // default: 0\\n }\\n\\n function current(Counter storage counter) internal view returns (uint256) {\\n return counter._value;\\n }\\n\\n function increment(Counter storage counter) internal {\\n unchecked {\\n counter._value += 1;\\n }\\n }\\n\\n function decrement(Counter storage counter) internal {\\n uint256 value = counter._value;\\n require(value > 0, \\\"Counter: decrement overflow\\\");\\n unchecked {\\n counter._value = value - 1;\\n }\\n }\\n\\n function reset(Counter storage counter) internal {\\n counter._value = 0;\\n }\\n}\\n\",\"keccak256\":\"0x798741e231b22b81e2dd2eddaaf8832dee4baf5cd8e2dbaa5c1dd12a1c053c4d\",\"license\":\"MIT\"},\"@openzeppelin/contracts-upgradeable/utils/StringsUpgradeable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.7.0) (utils/Strings.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev String operations.\\n */\\nlibrary StringsUpgradeable {\\n bytes16 private constant _HEX_SYMBOLS = \\\"0123456789abcdef\\\";\\n uint8 private constant _ADDRESS_LENGTH = 20;\\n\\n /**\\n * @dev Converts a `uint256` to its ASCII `string` decimal representation.\\n */\\n function toString(uint256 value) internal pure returns (string memory) {\\n // Inspired by OraclizeAPI's implementation - MIT licence\\n // https://github.com/oraclize/ethereum-api/blob/b42146b063c7d6ee1358846c198246239e9360e8/oraclizeAPI_0.4.25.sol\\n\\n if (value == 0) {\\n return \\\"0\\\";\\n }\\n uint256 temp = value;\\n uint256 digits;\\n while (temp != 0) {\\n digits++;\\n temp /= 10;\\n }\\n bytes memory buffer = new bytes(digits);\\n while (value != 0) {\\n digits -= 1;\\n buffer[digits] = bytes1(uint8(48 + uint256(value % 10)));\\n value /= 10;\\n }\\n return string(buffer);\\n }\\n\\n /**\\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation.\\n */\\n function toHexString(uint256 value) internal pure returns (string memory) {\\n if (value == 0) {\\n return \\\"0x00\\\";\\n }\\n uint256 temp = value;\\n uint256 length = 0;\\n while (temp != 0) {\\n length++;\\n temp >>= 8;\\n }\\n return toHexString(value, length);\\n }\\n\\n /**\\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length.\\n */\\n function toHexString(uint256 value, uint256 length) internal pure returns (string memory) {\\n bytes memory buffer = new bytes(2 * length + 2);\\n buffer[0] = \\\"0\\\";\\n buffer[1] = \\\"x\\\";\\n for (uint256 i = 2 * length + 1; i > 1; --i) {\\n buffer[i] = _HEX_SYMBOLS[value & 0xf];\\n value >>= 4;\\n }\\n require(value == 0, \\\"Strings: hex length insufficient\\\");\\n return string(buffer);\\n }\\n\\n /**\\n * @dev Converts an `address` with fixed length of 20 bytes to its not checksummed ASCII `string` hexadecimal representation.\\n */\\n function toHexString(address addr) internal pure returns (string memory) {\\n return toHexString(uint256(uint160(addr)), _ADDRESS_LENGTH);\\n }\\n}\\n\",\"keccak256\":\"0xea5339a7fff0ed42b45be56a88efdd0b2ddde9fa480dc99fef9a6a4c5b776863\",\"license\":\"MIT\"},\"@openzeppelin/contracts-upgradeable/utils/cryptography/ECDSAUpgradeable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.7.0) (utils/cryptography/ECDSA.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../StringsUpgradeable.sol\\\";\\n\\n/**\\n * @dev Elliptic Curve Digital Signature Algorithm (ECDSA) operations.\\n *\\n * These functions can be used to verify that a message was signed by the holder\\n * of the private keys of a given address.\\n */\\nlibrary ECDSAUpgradeable {\\n enum RecoverError {\\n NoError,\\n InvalidSignature,\\n InvalidSignatureLength,\\n InvalidSignatureS,\\n InvalidSignatureV\\n }\\n\\n function _throwError(RecoverError error) private pure {\\n if (error == RecoverError.NoError) {\\n return; // no error: do nothing\\n } else if (error == RecoverError.InvalidSignature) {\\n revert(\\\"ECDSA: invalid signature\\\");\\n } else if (error == RecoverError.InvalidSignatureLength) {\\n revert(\\\"ECDSA: invalid signature length\\\");\\n } else if (error == RecoverError.InvalidSignatureS) {\\n revert(\\\"ECDSA: invalid signature 's' value\\\");\\n } else if (error == RecoverError.InvalidSignatureV) {\\n revert(\\\"ECDSA: invalid signature 'v' value\\\");\\n }\\n }\\n\\n /**\\n * @dev Returns the address that signed a hashed message (`hash`) with\\n * `signature` or error string. This address can then be used for verification purposes.\\n *\\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\\n * this function rejects them by requiring the `s` value to be in the lower\\n * half order, and the `v` value to be either 27 or 28.\\n *\\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\\n * verification to be secure: it is possible to craft signatures that\\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\\n * this is by receiving a hash of the original message (which may otherwise\\n * be too long), and then calling {toEthSignedMessageHash} on it.\\n *\\n * Documentation for signature generation:\\n * - with https://web3js.readthedocs.io/en/v1.3.4/web3-eth-accounts.html#sign[Web3.js]\\n * - with https://docs.ethers.io/v5/api/signer/#Signer-signMessage[ethers]\\n *\\n * _Available since v4.3._\\n */\\n function tryRecover(bytes32 hash, bytes memory signature) internal pure returns (address, RecoverError) {\\n // Check the signature length\\n // - case 65: r,s,v signature (standard)\\n // - case 64: r,vs signature (cf https://eips.ethereum.org/EIPS/eip-2098) _Available since v4.1._\\n if (signature.length == 65) {\\n bytes32 r;\\n bytes32 s;\\n uint8 v;\\n // ecrecover takes the signature parameters, and the only way to get them\\n // currently is to use assembly.\\n /// @solidity memory-safe-assembly\\n assembly {\\n r := mload(add(signature, 0x20))\\n s := mload(add(signature, 0x40))\\n v := byte(0, mload(add(signature, 0x60)))\\n }\\n return tryRecover(hash, v, r, s);\\n } else if (signature.length == 64) {\\n bytes32 r;\\n bytes32 vs;\\n // ecrecover takes the signature parameters, and the only way to get them\\n // currently is to use assembly.\\n /// @solidity memory-safe-assembly\\n assembly {\\n r := mload(add(signature, 0x20))\\n vs := mload(add(signature, 0x40))\\n }\\n return tryRecover(hash, r, vs);\\n } else {\\n return (address(0), RecoverError.InvalidSignatureLength);\\n }\\n }\\n\\n /**\\n * @dev Returns the address that signed a hashed message (`hash`) with\\n * `signature`. This address can then be used for verification purposes.\\n *\\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\\n * this function rejects them by requiring the `s` value to be in the lower\\n * half order, and the `v` value to be either 27 or 28.\\n *\\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\\n * verification to be secure: it is possible to craft signatures that\\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\\n * this is by receiving a hash of the original message (which may otherwise\\n * be too long), and then calling {toEthSignedMessageHash} on it.\\n */\\n function recover(bytes32 hash, bytes memory signature) internal pure returns (address) {\\n (address recovered, RecoverError error) = tryRecover(hash, signature);\\n _throwError(error);\\n return recovered;\\n }\\n\\n /**\\n * @dev Overload of {ECDSA-tryRecover} that receives the `r` and `vs` short-signature fields separately.\\n *\\n * See https://eips.ethereum.org/EIPS/eip-2098[EIP-2098 short signatures]\\n *\\n * _Available since v4.3._\\n */\\n function tryRecover(\\n bytes32 hash,\\n bytes32 r,\\n bytes32 vs\\n ) internal pure returns (address, RecoverError) {\\n bytes32 s = vs & bytes32(0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff);\\n uint8 v = uint8((uint256(vs) >> 255) + 27);\\n return tryRecover(hash, v, r, s);\\n }\\n\\n /**\\n * @dev Overload of {ECDSA-recover} that receives the `r and `vs` short-signature fields separately.\\n *\\n * _Available since v4.2._\\n */\\n function recover(\\n bytes32 hash,\\n bytes32 r,\\n bytes32 vs\\n ) internal pure returns (address) {\\n (address recovered, RecoverError error) = tryRecover(hash, r, vs);\\n _throwError(error);\\n return recovered;\\n }\\n\\n /**\\n * @dev Overload of {ECDSA-tryRecover} that receives the `v`,\\n * `r` and `s` signature fields separately.\\n *\\n * _Available since v4.3._\\n */\\n function tryRecover(\\n bytes32 hash,\\n uint8 v,\\n bytes32 r,\\n bytes32 s\\n ) internal pure returns (address, RecoverError) {\\n // EIP-2 still allows signature malleability for ecrecover(). Remove this possibility and make the signature\\n // unique. Appendix F in the Ethereum Yellow paper (https://ethereum.github.io/yellowpaper/paper.pdf), defines\\n // the valid range for s in (301): 0 < s < secp256k1n \\u00f7 2 + 1, and for v in (302): v \\u2208 {27, 28}. Most\\n // signatures from current libraries generate a unique signature with an s-value in the lower half order.\\n //\\n // If your library generates malleable signatures, such as s-values in the upper range, calculate a new s-value\\n // with 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141 - s1 and flip v from 27 to 28 or\\n // vice versa. If your library also generates signatures with 0/1 for v instead 27/28, add 27 to v to accept\\n // these malleable signatures as well.\\n if (uint256(s) > 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D576E7357A4501DDFE92F46681B20A0) {\\n return (address(0), RecoverError.InvalidSignatureS);\\n }\\n if (v != 27 && v != 28) {\\n return (address(0), RecoverError.InvalidSignatureV);\\n }\\n\\n // If the signature is valid (and not malleable), return the signer address\\n address signer = ecrecover(hash, v, r, s);\\n if (signer == address(0)) {\\n return (address(0), RecoverError.InvalidSignature);\\n }\\n\\n return (signer, RecoverError.NoError);\\n }\\n\\n /**\\n * @dev Overload of {ECDSA-recover} that receives the `v`,\\n * `r` and `s` signature fields separately.\\n */\\n function recover(\\n bytes32 hash,\\n uint8 v,\\n bytes32 r,\\n bytes32 s\\n ) internal pure returns (address) {\\n (address recovered, RecoverError error) = tryRecover(hash, v, r, s);\\n _throwError(error);\\n return recovered;\\n }\\n\\n /**\\n * @dev Returns an Ethereum Signed Message, created from a `hash`. This\\n * produces hash corresponding to the one signed with the\\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\\n * JSON-RPC method as part of EIP-191.\\n *\\n * See {recover}.\\n */\\n function toEthSignedMessageHash(bytes32 hash) internal pure returns (bytes32) {\\n // 32 is the length in bytes of hash,\\n // enforced by the type signature above\\n return keccak256(abi.encodePacked(\\\"\\\\x19Ethereum Signed Message:\\\\n32\\\", hash));\\n }\\n\\n /**\\n * @dev Returns an Ethereum Signed Message, created from `s`. This\\n * produces hash corresponding to the one signed with the\\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\\n * JSON-RPC method as part of EIP-191.\\n *\\n * See {recover}.\\n */\\n function toEthSignedMessageHash(bytes memory s) internal pure returns (bytes32) {\\n return keccak256(abi.encodePacked(\\\"\\\\x19Ethereum Signed Message:\\\\n\\\", StringsUpgradeable.toString(s.length), s));\\n }\\n\\n /**\\n * @dev Returns an Ethereum Signed Typed Data, created from a\\n * `domainSeparator` and a `structHash`. This produces hash corresponding\\n * to the one signed with the\\n * https://eips.ethereum.org/EIPS/eip-712[`eth_signTypedData`]\\n * JSON-RPC method as part of EIP-712.\\n *\\n * See {recover}.\\n */\\n function toTypedDataHash(bytes32 domainSeparator, bytes32 structHash) internal pure returns (bytes32) {\\n return keccak256(abi.encodePacked(\\\"\\\\x19\\\\x01\\\", domainSeparator, structHash));\\n }\\n}\\n\",\"keccak256\":\"0xe8c62ca00ed2d0a4d9b7e3c4bf7d62c821618b2cdb3c844da91a1193986851bf\",\"license\":\"MIT\"},\"@openzeppelin/contracts-upgradeable/utils/cryptography/draft-EIP712Upgradeable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (utils/cryptography/draft-EIP712.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"./ECDSAUpgradeable.sol\\\";\\nimport \\\"../../proxy/utils/Initializable.sol\\\";\\n\\n/**\\n * @dev https://eips.ethereum.org/EIPS/eip-712[EIP 712] is a standard for hashing and signing of typed structured data.\\n *\\n * The encoding specified in the EIP is very generic, and such a generic implementation in Solidity is not feasible,\\n * thus this contract does not implement the encoding itself. Protocols need to implement the type-specific encoding\\n * they need in their contracts using a combination of `abi.encode` and `keccak256`.\\n *\\n * This contract implements the EIP 712 domain separator ({_domainSeparatorV4}) that is used as part of the encoding\\n * scheme, and the final step of the encoding to obtain the message digest that is then signed via ECDSA\\n * ({_hashTypedDataV4}).\\n *\\n * The implementation of the domain separator was designed to be as efficient as possible while still properly updating\\n * the chain id to protect against replay attacks on an eventual fork of the chain.\\n *\\n * NOTE: This contract implements the version of the encoding known as \\\"v4\\\", as implemented by the JSON RPC method\\n * https://docs.metamask.io/guide/signing-data.html[`eth_signTypedDataV4` in MetaMask].\\n *\\n * _Available since v3.4._\\n *\\n * @custom:storage-size 52\\n */\\nabstract contract EIP712Upgradeable is Initializable {\\n /* solhint-disable var-name-mixedcase */\\n bytes32 private _HASHED_NAME;\\n bytes32 private _HASHED_VERSION;\\n bytes32 private constant _TYPE_HASH = keccak256(\\\"EIP712Domain(string name,string version,uint256 chainId,address verifyingContract)\\\");\\n\\n /* solhint-enable var-name-mixedcase */\\n\\n /**\\n * @dev Initializes the domain separator and parameter caches.\\n *\\n * The meaning of `name` and `version` is specified in\\n * https://eips.ethereum.org/EIPS/eip-712#definition-of-domainseparator[EIP 712]:\\n *\\n * - `name`: the user readable name of the signing domain, i.e. the name of the DApp or the protocol.\\n * - `version`: the current major version of the signing domain.\\n *\\n * NOTE: These parameters cannot be changed except through a xref:learn::upgrading-smart-contracts.adoc[smart\\n * contract upgrade].\\n */\\n function __EIP712_init(string memory name, string memory version) internal onlyInitializing {\\n __EIP712_init_unchained(name, version);\\n }\\n\\n function __EIP712_init_unchained(string memory name, string memory version) internal onlyInitializing {\\n bytes32 hashedName = keccak256(bytes(name));\\n bytes32 hashedVersion = keccak256(bytes(version));\\n _HASHED_NAME = hashedName;\\n _HASHED_VERSION = hashedVersion;\\n }\\n\\n /**\\n * @dev Returns the domain separator for the current chain.\\n */\\n function _domainSeparatorV4() internal view returns (bytes32) {\\n return _buildDomainSeparator(_TYPE_HASH, _EIP712NameHash(), _EIP712VersionHash());\\n }\\n\\n function _buildDomainSeparator(\\n bytes32 typeHash,\\n bytes32 nameHash,\\n bytes32 versionHash\\n ) private view returns (bytes32) {\\n return keccak256(abi.encode(typeHash, nameHash, versionHash, block.chainid, address(this)));\\n }\\n\\n /**\\n * @dev Given an already https://eips.ethereum.org/EIPS/eip-712#definition-of-hashstruct[hashed struct], this\\n * function returns the hash of the fully encoded EIP712 message for this domain.\\n *\\n * This hash can be used together with {ECDSA-recover} to obtain the signer of a message. For example:\\n *\\n * ```solidity\\n * bytes32 digest = _hashTypedDataV4(keccak256(abi.encode(\\n * keccak256(\\\"Mail(address to,string contents)\\\"),\\n * mailTo,\\n * keccak256(bytes(mailContents))\\n * )));\\n * address signer = ECDSA.recover(digest, signature);\\n * ```\\n */\\n function _hashTypedDataV4(bytes32 structHash) internal view virtual returns (bytes32) {\\n return ECDSAUpgradeable.toTypedDataHash(_domainSeparatorV4(), structHash);\\n }\\n\\n /**\\n * @dev The hash of the name parameter for the EIP712 domain.\\n *\\n * NOTE: This function reads from storage by default, but can be redefined to return a constant value if gas costs\\n * are a concern.\\n */\\n function _EIP712NameHash() internal virtual view returns (bytes32) {\\n return _HASHED_NAME;\\n }\\n\\n /**\\n * @dev The hash of the version parameter for the EIP712 domain.\\n *\\n * NOTE: This function reads from storage by default, but can be redefined to return a constant value if gas costs\\n * are a concern.\\n */\\n function _EIP712VersionHash() internal virtual view returns (bytes32) {\\n return _HASHED_VERSION;\\n }\\n\\n /**\\n * @dev This empty reserved space is put in place to allow future versions to add new\\n * variables without shifting down storage in the inheritance chain.\\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\\n */\\n uint256[50] private __gap;\\n}\\n\",\"keccak256\":\"0xaf5a96100f421d61693605349511e43221d3c2e47d4b3efa87af2b936e2567fc\",\"license\":\"MIT\"},\"@openzeppelin/contracts/token/ERC20/IERC20.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.6.0) (token/ERC20/IERC20.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Interface of the ERC20 standard as defined in the EIP.\\n */\\ninterface IERC20 {\\n /**\\n * @dev Emitted when `value` tokens are moved from one account (`from`) to\\n * another (`to`).\\n *\\n * Note that `value` may be zero.\\n */\\n event Transfer(address indexed from, address indexed to, uint256 value);\\n\\n /**\\n * @dev Emitted when the allowance of a `spender` for an `owner` is set by\\n * a call to {approve}. `value` is the new allowance.\\n */\\n event Approval(address indexed owner, address indexed spender, uint256 value);\\n\\n /**\\n * @dev Returns the amount of tokens in existence.\\n */\\n function totalSupply() external view returns (uint256);\\n\\n /**\\n * @dev Returns the amount of tokens owned by `account`.\\n */\\n function balanceOf(address account) external view returns (uint256);\\n\\n /**\\n * @dev Moves `amount` tokens from the caller's account to `to`.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * Emits a {Transfer} event.\\n */\\n function transfer(address to, uint256 amount) external returns (bool);\\n\\n /**\\n * @dev Returns the remaining number of tokens that `spender` will be\\n * allowed to spend on behalf of `owner` through {transferFrom}. This is\\n * zero by default.\\n *\\n * This value changes when {approve} or {transferFrom} are called.\\n */\\n function allowance(address owner, address spender) external view returns (uint256);\\n\\n /**\\n * @dev Sets `amount` as the allowance of `spender` over the caller's tokens.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * IMPORTANT: Beware that changing an allowance with this method brings the risk\\n * that someone may use both the old and the new allowance by unfortunate\\n * transaction ordering. One possible solution to mitigate this race\\n * condition is to first reduce the spender's allowance to 0 and set the\\n * desired value afterwards:\\n * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729\\n *\\n * Emits an {Approval} event.\\n */\\n function approve(address spender, uint256 amount) external returns (bool);\\n\\n /**\\n * @dev Moves `amount` tokens from `from` to `to` using the\\n * allowance mechanism. `amount` is then deducted from the caller's\\n * allowance.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * Emits a {Transfer} event.\\n */\\n function transferFrom(\\n address from,\\n address to,\\n uint256 amount\\n ) external returns (bool);\\n}\\n\",\"keccak256\":\"0x9750c6b834f7b43000631af5cc30001c5f547b3ceb3635488f140f60e897ea6b\",\"license\":\"MIT\"},\"@openzeppelin/contracts/token/ERC20/extensions/draft-IERC20Permit.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (token/ERC20/extensions/draft-IERC20Permit.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Interface of the ERC20 Permit extension allowing approvals to be made via signatures, as defined in\\n * https://eips.ethereum.org/EIPS/eip-2612[EIP-2612].\\n *\\n * Adds the {permit} method, which can be used to change an account's ERC20 allowance (see {IERC20-allowance}) by\\n * presenting a message signed by the account. By not relying on {IERC20-approve}, the token holder account doesn't\\n * need to send a transaction, and thus is not required to hold Ether at all.\\n */\\ninterface IERC20Permit {\\n /**\\n * @dev Sets `value` as the allowance of `spender` over ``owner``'s tokens,\\n * given ``owner``'s signed approval.\\n *\\n * IMPORTANT: The same issues {IERC20-approve} has related to transaction\\n * ordering also apply here.\\n *\\n * Emits an {Approval} event.\\n *\\n * Requirements:\\n *\\n * - `spender` cannot be the zero address.\\n * - `deadline` must be a timestamp in the future.\\n * - `v`, `r` and `s` must be a valid `secp256k1` signature from `owner`\\n * over the EIP712-formatted function arguments.\\n * - the signature must use ``owner``'s current nonce (see {nonces}).\\n *\\n * For more information on the signature format, see the\\n * https://eips.ethereum.org/EIPS/eip-2612#specification[relevant EIP\\n * section].\\n */\\n function permit(\\n address owner,\\n address spender,\\n uint256 value,\\n uint256 deadline,\\n uint8 v,\\n bytes32 r,\\n bytes32 s\\n ) external;\\n\\n /**\\n * @dev Returns the current nonce for `owner`. This value must be\\n * included whenever a signature is generated for {permit}.\\n *\\n * Every successful call to {permit} increases ``owner``'s nonce by one. This\\n * prevents a signature from being used multiple times.\\n */\\n function nonces(address owner) external view returns (uint256);\\n\\n /**\\n * @dev Returns the domain separator used in the encoding of the signature for {permit}, as defined by {EIP712}.\\n */\\n // solhint-disable-next-line func-name-mixedcase\\n function DOMAIN_SEPARATOR() external view returns (bytes32);\\n}\\n\",\"keccak256\":\"0xf41ca991f30855bf80ffd11e9347856a517b977f0a6c2d52e6421a99b7840329\",\"license\":\"MIT\"},\"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.7.0) (token/ERC20/utils/SafeERC20.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../IERC20.sol\\\";\\nimport \\\"../extensions/draft-IERC20Permit.sol\\\";\\nimport \\\"../../../utils/Address.sol\\\";\\n\\n/**\\n * @title SafeERC20\\n * @dev Wrappers around ERC20 operations that throw on failure (when the token\\n * contract returns false). Tokens that return no value (and instead revert or\\n * throw on failure) are also supported, non-reverting calls are assumed to be\\n * successful.\\n * To use this library you can add a `using SafeERC20 for IERC20;` statement to your contract,\\n * which allows you to call the safe operations as `token.safeTransfer(...)`, etc.\\n */\\nlibrary SafeERC20 {\\n using Address for address;\\n\\n function safeTransfer(\\n IERC20 token,\\n address to,\\n uint256 value\\n ) internal {\\n _callOptionalReturn(token, abi.encodeWithSelector(token.transfer.selector, to, value));\\n }\\n\\n function safeTransferFrom(\\n IERC20 token,\\n address from,\\n address to,\\n uint256 value\\n ) internal {\\n _callOptionalReturn(token, abi.encodeWithSelector(token.transferFrom.selector, from, to, value));\\n }\\n\\n /**\\n * @dev Deprecated. This function has issues similar to the ones found in\\n * {IERC20-approve}, and its usage is discouraged.\\n *\\n * Whenever possible, use {safeIncreaseAllowance} and\\n * {safeDecreaseAllowance} instead.\\n */\\n function safeApprove(\\n IERC20 token,\\n address spender,\\n uint256 value\\n ) internal {\\n // safeApprove should only be called when setting an initial allowance,\\n // or when resetting it to zero. To increase and decrease it, use\\n // 'safeIncreaseAllowance' and 'safeDecreaseAllowance'\\n require(\\n (value == 0) || (token.allowance(address(this), spender) == 0),\\n \\\"SafeERC20: approve from non-zero to non-zero allowance\\\"\\n );\\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, value));\\n }\\n\\n function safeIncreaseAllowance(\\n IERC20 token,\\n address spender,\\n uint256 value\\n ) internal {\\n uint256 newAllowance = token.allowance(address(this), spender) + value;\\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));\\n }\\n\\n function safeDecreaseAllowance(\\n IERC20 token,\\n address spender,\\n uint256 value\\n ) internal {\\n unchecked {\\n uint256 oldAllowance = token.allowance(address(this), spender);\\n require(oldAllowance >= value, \\\"SafeERC20: decreased allowance below zero\\\");\\n uint256 newAllowance = oldAllowance - value;\\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));\\n }\\n }\\n\\n function safePermit(\\n IERC20Permit token,\\n address owner,\\n address spender,\\n uint256 value,\\n uint256 deadline,\\n uint8 v,\\n bytes32 r,\\n bytes32 s\\n ) internal {\\n uint256 nonceBefore = token.nonces(owner);\\n token.permit(owner, spender, value, deadline, v, r, s);\\n uint256 nonceAfter = token.nonces(owner);\\n require(nonceAfter == nonceBefore + 1, \\\"SafeERC20: permit did not succeed\\\");\\n }\\n\\n /**\\n * @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement\\n * on the return value: the return value is optional (but if data is returned, it must not be false).\\n * @param token The token targeted by the call.\\n * @param data The call data (encoded using abi.encode or one of its variants).\\n */\\n function _callOptionalReturn(IERC20 token, bytes memory data) private {\\n // We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since\\n // we're implementing it ourselves. We use {Address.functionCall} to perform this call, which verifies that\\n // the target address contains contract code and also asserts for success in the low-level call.\\n\\n bytes memory returndata = address(token).functionCall(data, \\\"SafeERC20: low-level call failed\\\");\\n if (returndata.length > 0) {\\n // Return data is optional\\n require(abi.decode(returndata, (bool)), \\\"SafeERC20: ERC20 operation did not succeed\\\");\\n }\\n }\\n}\\n\",\"keccak256\":\"0x032807210d1d7d218963d7355d62e021a84bf1b3339f4f50be2f63b53cccaf29\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/Address.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.7.0) (utils/Address.sol)\\n\\npragma solidity ^0.8.1;\\n\\n/**\\n * @dev Collection of functions related to the address type\\n */\\nlibrary Address {\\n /**\\n * @dev Returns true if `account` is a contract.\\n *\\n * [IMPORTANT]\\n * ====\\n * It is unsafe to assume that an address for which this function returns\\n * false is an externally-owned account (EOA) and not a contract.\\n *\\n * Among others, `isContract` will return false for the following\\n * types of addresses:\\n *\\n * - an externally-owned account\\n * - a contract in construction\\n * - an address where a contract will be created\\n * - an address where a contract lived, but was destroyed\\n * ====\\n *\\n * [IMPORTANT]\\n * ====\\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\\n *\\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\\n * constructor.\\n * ====\\n */\\n function isContract(address account) internal view returns (bool) {\\n // This method relies on extcodesize/address.code.length, which returns 0\\n // for contracts in construction, since the code is only stored at the end\\n // of the constructor execution.\\n\\n return account.code.length > 0;\\n }\\n\\n /**\\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\\n * `recipient`, forwarding all available gas and reverting on errors.\\n *\\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\\n * imposed by `transfer`, making them unable to receive funds via\\n * `transfer`. {sendValue} removes this limitation.\\n *\\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\\n *\\n * IMPORTANT: because control is transferred to `recipient`, care must be\\n * taken to not create reentrancy vulnerabilities. Consider using\\n * {ReentrancyGuard} or the\\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\\n */\\n function sendValue(address payable recipient, uint256 amount) internal {\\n require(address(this).balance >= amount, \\\"Address: insufficient balance\\\");\\n\\n (bool success, ) = recipient.call{value: amount}(\\\"\\\");\\n require(success, \\\"Address: unable to send value, recipient may have reverted\\\");\\n }\\n\\n /**\\n * @dev Performs a Solidity function call using a low level `call`. A\\n * plain `call` is an unsafe replacement for a function call: use this\\n * function instead.\\n *\\n * If `target` reverts with a revert reason, it is bubbled up by this\\n * function (like regular Solidity function calls).\\n *\\n * Returns the raw returned data. To convert to the expected return value,\\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\\n *\\n * Requirements:\\n *\\n * - `target` must be a contract.\\n * - calling `target` with `data` must not revert.\\n *\\n * _Available since v3.1._\\n */\\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\\n return functionCall(target, data, \\\"Address: low-level call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\\n * `errorMessage` as a fallback revert reason when `target` reverts.\\n *\\n * _Available since v3.1._\\n */\\n function functionCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n return functionCallWithValue(target, data, 0, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but also transferring `value` wei to `target`.\\n *\\n * Requirements:\\n *\\n * - the calling contract must have an ETH balance of at least `value`.\\n * - the called Solidity function must be `payable`.\\n *\\n * _Available since v3.1._\\n */\\n function functionCallWithValue(\\n address target,\\n bytes memory data,\\n uint256 value\\n ) internal returns (bytes memory) {\\n return functionCallWithValue(target, data, value, \\\"Address: low-level call with value failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\\n * with `errorMessage` as a fallback revert reason when `target` reverts.\\n *\\n * _Available since v3.1._\\n */\\n function functionCallWithValue(\\n address target,\\n bytes memory data,\\n uint256 value,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n require(address(this).balance >= value, \\\"Address: insufficient balance for call\\\");\\n require(isContract(target), \\\"Address: call to non-contract\\\");\\n\\n (bool success, bytes memory returndata) = target.call{value: value}(data);\\n return verifyCallResult(success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but performing a static call.\\n *\\n * _Available since v3.3._\\n */\\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\\n return functionStaticCall(target, data, \\\"Address: low-level static call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\\n * but performing a static call.\\n *\\n * _Available since v3.3._\\n */\\n function functionStaticCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal view returns (bytes memory) {\\n require(isContract(target), \\\"Address: static call to non-contract\\\");\\n\\n (bool success, bytes memory returndata) = target.staticcall(data);\\n return verifyCallResult(success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but performing a delegate call.\\n *\\n * _Available since v3.4._\\n */\\n function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {\\n return functionDelegateCall(target, data, \\\"Address: low-level delegate call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\\n * but performing a delegate call.\\n *\\n * _Available since v3.4._\\n */\\n function functionDelegateCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n require(isContract(target), \\\"Address: delegate call to non-contract\\\");\\n\\n (bool success, bytes memory returndata) = target.delegatecall(data);\\n return verifyCallResult(success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the\\n * revert reason using the provided one.\\n *\\n * _Available since v4.3._\\n */\\n function verifyCallResult(\\n bool success,\\n bytes memory returndata,\\n string memory errorMessage\\n ) internal pure returns (bytes memory) {\\n if (success) {\\n return returndata;\\n } else {\\n // Look for revert reason and bubble it up if present\\n if (returndata.length > 0) {\\n // The easiest way to bubble the revert reason is using memory via assembly\\n /// @solidity memory-safe-assembly\\n assembly {\\n let returndata_size := mload(returndata)\\n revert(add(32, returndata), returndata_size)\\n }\\n } else {\\n revert(errorMessage);\\n }\\n }\\n }\\n}\\n\",\"keccak256\":\"0xd6153ce99bcdcce22b124f755e72553295be6abcd63804cfdffceb188b8bef10\",\"license\":\"MIT\"},\"contracts/agToken/AgToken.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-3.0\\n\\npragma solidity ^0.8.12;\\n\\n/*\\n * \\u2588 \\n ***** \\u2593\\u2593\\u2593 \\n * \\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593 \\n * ///. \\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593 \\n ***** //////// \\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593 \\n * ///////////// \\u2593\\u2593\\u2593 \\n \\u2593\\u2593 ////////////////// \\u2588 \\u2593\\u2593 \\n \\u2593\\u2593 \\u2593\\u2593 /////////////////////// \\u2593\\u2593 \\u2593\\u2593 \\n \\u2593\\u2593 \\u2593\\u2593 //////////////////////////// \\u2593\\u2593 \\u2593\\u2593 \\n \\u2593\\u2593 \\u2593\\u2593 /////////\\u2593\\u2593\\u2593///////\\u2593\\u2593\\u2593///////// \\u2593\\u2593 \\u2593\\u2593 \\n \\u2593\\u2593 ,////////////////////////////////////// \\u2593\\u2593 \\u2593\\u2593 \\n \\u2593\\u2593 ////////////////////////////////////////// \\u2593\\u2593 \\n \\u2593\\u2593 //////////////////////\\u2593\\u2593\\u2593\\u2593///////////////////// \\n ,//////////////////////////////////////////////////// \\n .////////////////////////////////////////////////////////// \\n .//////////////////////////\\u2588\\u2588.,//////////////////////////\\u2588 \\n .//////////////////////\\u2588\\u2588\\u2588\\u2588..,./////////////////////\\u2588\\u2588 \\n ...////////////////\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588.....,.////////////////\\u2588\\u2588\\u2588 \\n ,.,////////////\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588 ........,///////////\\u2588\\u2588\\u2588\\u2588 \\n .,.,//////\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588 ,.......///////\\u2588\\u2588\\u2588\\u2588 \\n ,..//\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588 ........./\\u2588\\u2588\\u2588\\u2588 \\n ..,\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588 .....,\\u2588\\u2588\\u2588 \\n .\\u2588\\u2588 ,.,\\u2588 \\n \\n \\n \\n \\u2593\\u2593 \\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593 \\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593 \\u2593\\u2593 \\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593 \\n \\u2593\\u2593\\u2593\\u2593\\u2593\\u2593 \\u2593\\u2593\\u2593 \\u2593\\u2593\\u2593 \\u2593\\u2593\\u2593 \\u2593\\u2593 \\u2593\\u2593 \\u2593\\u2593\\u2593\\u2593 \\n \\u2593\\u2593\\u2593 \\u2593\\u2593\\u2593 \\u2593\\u2593\\u2593 \\u2593\\u2593\\u2593 \\u2593\\u2593\\u2593 \\u2593\\u2593\\u2593 \\u2593\\u2593 \\u2593\\u2593\\u2593\\u2593\\u2593 \\n \\u2593\\u2593\\u2593 \\u2593\\u2593 \\u2593\\u2593\\u2593 \\u2593\\u2593\\u2593 \\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593 \\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593 \\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593 \\n*/\\n\\nimport \\\"../interfaces/IAgToken.sol\\\";\\nimport \\\"../interfaces/ITreasury.sol\\\";\\nimport \\\"@openzeppelin/contracts-upgradeable/token/ERC20/extensions/draft-ERC20PermitUpgradeable.sol\\\";\\n\\n/// @title AgToken\\n/// @author Angle Labs, Inc.\\n/// @notice Base contract for Angle agTokens on Ethereum and on other chains\\n/// @dev By default, agTokens are ERC-20 tokens with 18 decimals\\ncontract AgToken is IAgToken, ERC20PermitUpgradeable {\\n // =========================== PARAMETERS / VARIABLES ==========================\\n\\n /// @inheritdoc IAgToken\\n mapping(address => bool) public isMinter;\\n /// @notice Reference to the treasury contract which can grant minting rights\\n address public treasury;\\n\\n // =================================== EVENTS ==================================\\n\\n event TreasuryUpdated(address indexed _treasury);\\n event MinterToggled(address indexed minter);\\n\\n // =================================== ERRORS ==================================\\n\\n error BurnAmountExceedsAllowance();\\n error InvalidSender();\\n error InvalidTreasury();\\n error NotMinter();\\n error NotTreasury();\\n\\n // ================================ CONSTRUCTOR ================================\\n\\n /// @custom:oz-upgrades-unsafe-allow constructor\\n constructor() initializer {}\\n\\n /// @notice Initializes the `AgToken` contract\\n function initialize(string memory name_, string memory symbol_, address _treasury) external {\\n _initialize(name_, symbol_, _treasury);\\n }\\n\\n /// @notice Initializes the contract\\n function _initialize(string memory name_, string memory symbol_, address _treasury) internal virtual initializer {\\n if (address(ITreasury(_treasury).stablecoin()) != address(this)) revert InvalidTreasury();\\n __ERC20Permit_init(name_);\\n __ERC20_init(name_, symbol_);\\n treasury = _treasury;\\n emit TreasuryUpdated(_treasury);\\n }\\n\\n // ================================= MODIFIERS =================================\\n\\n /// @notice Checks to see if it is the `Treasury` calling this contract\\n modifier onlyTreasury() {\\n if (msg.sender != treasury) revert NotTreasury();\\n _;\\n }\\n\\n /// @notice Checks whether the sender has the minting right\\n modifier onlyMinter() {\\n if (!isMinter[msg.sender]) revert NotMinter();\\n _;\\n }\\n\\n // ============================= EXTERNAL FUNCTION =============================\\n\\n /// @notice Allows anyone to burn stablecoins\\n /// @param amount Amount of stablecoins to burn\\n /// @dev This function can typically be called if there is a settlement mechanism to burn stablecoins\\n function burnStablecoin(uint256 amount) external {\\n _burn(msg.sender, amount);\\n }\\n\\n // ========================= MINTER ROLE ONLY FUNCTIONS ========================\\n\\n /// @inheritdoc IAgToken\\n function burnSelf(uint256 amount, address burner) external onlyMinter {\\n _burn(burner, amount);\\n }\\n\\n /// @inheritdoc IAgToken\\n function burnFrom(uint256 amount, address burner, address sender) external onlyMinter {\\n if (burner != sender) {\\n uint256 currentAllowance = allowance(burner, sender);\\n if (currentAllowance < amount) revert BurnAmountExceedsAllowance();\\n _approve(burner, sender, currentAllowance - amount);\\n }\\n _burn(burner, amount);\\n }\\n\\n /// @inheritdoc IAgToken\\n function mint(address account, uint256 amount) external onlyMinter {\\n _mint(account, amount);\\n }\\n\\n // ========================== GOVERNANCE ONLY FUNCTIONS ==========================\\n\\n /// @inheritdoc IAgToken\\n function addMinter(address minter) external onlyTreasury {\\n isMinter[minter] = true;\\n emit MinterToggled(minter);\\n }\\n\\n /// @inheritdoc IAgToken\\n function removeMinter(address minter) external {\\n if (msg.sender != address(treasury) && msg.sender != minter) revert InvalidSender();\\n isMinter[minter] = false;\\n emit MinterToggled(minter);\\n }\\n\\n /// @inheritdoc IAgToken\\n function setTreasury(address _treasury) external virtual onlyTreasury {\\n treasury = _treasury;\\n emit TreasuryUpdated(_treasury);\\n }\\n}\\n\",\"keccak256\":\"0x671d54d7840179050e859cf09662fe0e2c34cfaf5ec3782148d6c29e77c54d17\",\"license\":\"GPL-3.0\"},\"contracts/agToken/AgTokenSideChainMultiBridge.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-3.0\\n\\npragma solidity ^0.8.12;\\n\\nimport \\\"./AgToken.sol\\\";\\nimport \\\"@openzeppelin/contracts/token/ERC20/IERC20.sol\\\";\\nimport \\\"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\\\";\\n\\n/// @title AgTokenSideChainMultiBridge\\n/// @author Angle Labs, Inc.\\n/// @notice Contract for Angle agTokens on other chains than Ethereum mainnet\\n/// @dev This contract supports bridge tokens having a minting right on the stablecoin (also referred to as the canonical\\n/// or the native token)\\ncontract AgTokenSideChainMultiBridge is AgToken {\\n using SafeERC20 for IERC20;\\n\\n /// @notice Base used for fee computation\\n uint256 public constant BASE_PARAMS = 1e9;\\n\\n // =============================== BRIDGING DATA ===============================\\n\\n /// @notice Struct with some data about a specific bridge token\\n struct BridgeDetails {\\n // Limit on the balance of bridge token held by the contract: it is designed\\n // to reduce the exposure of the system to hacks\\n uint256 limit;\\n // Limit on the hourly volume of token minted through this bridge\\n // Technically the limit over a rolling hour is hourlyLimit x2 as hourly limit\\n // is enforced only between x:00 and x+1:00\\n uint256 hourlyLimit;\\n // Fee taken for swapping in and out the token\\n uint64 fee;\\n // Whether the associated token is allowed or not\\n bool allowed;\\n // Whether swapping in and out from the associated token is paused or not\\n bool paused;\\n }\\n\\n /// @notice Maps a bridge token to data\\n mapping(address => BridgeDetails) public bridges;\\n /// @notice List of all bridge tokens\\n address[] public bridgeTokensList;\\n /// @notice Maps a bridge token to the associated hourly volume\\n mapping(address => mapping(uint256 => uint256)) public usage;\\n /// @notice Maps an address to whether it is exempt of fees for when it comes to swapping in and out\\n mapping(address => uint256) public isFeeExempt;\\n /// @notice Limit to the amount of tokens that can be sent from that chain to another chain\\n uint256 public chainTotalHourlyLimit;\\n /// @notice Usage per hour on that chain. Maps an hourly timestamp to the total volume swapped out on the chain\\n mapping(uint256 => uint256) public chainTotalUsage;\\n\\n // =================================== EVENTS ==================================\\n\\n event BridgeTokenAdded(address indexed bridgeToken, uint256 limit, uint256 hourlyLimit, uint64 fee, bool paused);\\n event BridgeTokenToggled(address indexed bridgeToken, bool toggleStatus);\\n event BridgeTokenRemoved(address indexed bridgeToken);\\n event BridgeTokenFeeUpdated(address indexed bridgeToken, uint64 fee);\\n event BridgeTokenLimitUpdated(address indexed bridgeToken, uint256 limit);\\n event BridgeTokenHourlyLimitUpdated(address indexed bridgeToken, uint256 hourlyLimit);\\n event HourlyLimitUpdated(uint256 hourlyLimit);\\n event Recovered(address indexed token, address indexed to, uint256 amount);\\n event FeeToggled(address indexed theAddress, uint256 toggleStatus);\\n\\n // =================================== ERRORS ==================================\\n\\n error AssetStillControlledInReserves();\\n error HourlyLimitExceeded();\\n error InvalidToken();\\n error NotGovernor();\\n error NotGovernorOrGuardian();\\n error TooBigAmount();\\n error TooHighParameterValue();\\n error ZeroAddress();\\n\\n // ================================= MODIFIERS =================================\\n\\n /// @notice Checks whether the `msg.sender` has the governor role or not\\n modifier onlyGovernor() {\\n if (!ITreasury(treasury).isGovernor(msg.sender)) revert NotGovernor();\\n _;\\n }\\n\\n /// @notice Checks whether the `msg.sender` has the governor role or the guardian role\\n modifier onlyGovernorOrGuardian() {\\n if (!ITreasury(treasury).isGovernorOrGuardian(msg.sender)) revert NotGovernorOrGuardian();\\n _;\\n }\\n\\n // ===================== EXTERNAL PERMISSIONLESS FUNCTIONS =====================\\n\\n /// @notice Returns the list of all supported bridge tokens\\n /// @dev Helpful for UIs\\n function allBridgeTokens() external view returns (address[] memory) {\\n return bridgeTokensList;\\n }\\n\\n /// @notice Returns the current volume for a bridge, for the current hour\\n /// @param bridgeToken Bridge used to mint\\n /// @dev Helpful for UIs\\n function currentUsage(address bridgeToken) external view returns (uint256) {\\n return usage[bridgeToken][block.timestamp / 3600];\\n }\\n\\n /// @notice Returns the current total volume on the chain for the current hour\\n /// @dev Helpful for UIs\\n function currentTotalUsage() external view returns (uint256) {\\n return chainTotalUsage[block.timestamp / 3600];\\n }\\n\\n /// @notice Mints the canonical token from a supported bridge token\\n /// @param bridgeToken Bridge token to use to mint\\n /// @param amount Amount of bridge tokens to send\\n /// @param to Address to which the stablecoin should be sent\\n /// @return Amount of the canonical stablecoin actually minted\\n /// @dev Some fees may be taken by the protocol depending on the token used and on the address calling\\n function swapIn(address bridgeToken, uint256 amount, address to) external returns (uint256) {\\n BridgeDetails memory bridgeDetails = bridges[bridgeToken];\\n if (!bridgeDetails.allowed || bridgeDetails.paused) revert InvalidToken();\\n uint256 balance = IERC20(bridgeToken).balanceOf(address(this));\\n if (balance + amount > bridgeDetails.limit) {\\n // In case someone maliciously sends tokens to this contract\\n // Or the limit changes\\n if (bridgeDetails.limit > balance) amount = bridgeDetails.limit - balance;\\n else {\\n amount = 0;\\n }\\n }\\n\\n // Checking requirement on the hourly volume\\n uint256 hour = block.timestamp / 3600;\\n uint256 hourlyUsage = usage[bridgeToken][hour];\\n if (hourlyUsage + amount > bridgeDetails.hourlyLimit) {\\n // Edge case when the hourly limit changes\\n amount = bridgeDetails.hourlyLimit > hourlyUsage ? bridgeDetails.hourlyLimit - hourlyUsage : 0;\\n }\\n usage[bridgeToken][hour] = hourlyUsage + amount;\\n\\n IERC20(bridgeToken).safeTransferFrom(msg.sender, address(this), amount);\\n uint256 canonicalOut = amount;\\n // Computing fees\\n if (isFeeExempt[msg.sender] == 0) {\\n canonicalOut -= (canonicalOut * bridgeDetails.fee) / BASE_PARAMS;\\n }\\n _mint(to, canonicalOut);\\n return canonicalOut;\\n }\\n\\n /// @notice Burns the canonical token in exchange for a bridge token\\n /// @param bridgeToken Bridge token required\\n /// @param amount Amount of canonical tokens to burn\\n /// @param to Address to which the bridge token should be sent\\n /// @return Amount of bridge tokens actually sent back\\n /// @dev Some fees may be taken by the protocol depending on the token used and on the address calling\\n function swapOut(address bridgeToken, uint256 amount, address to) external returns (uint256) {\\n BridgeDetails memory bridgeDetails = bridges[bridgeToken];\\n if (!bridgeDetails.allowed || bridgeDetails.paused) revert InvalidToken();\\n\\n uint256 hour = block.timestamp / 3600;\\n uint256 hourlyUsage = chainTotalUsage[hour] + amount;\\n // If the amount being swapped out exceeds the limit, we revert\\n // We don't want to change the amount being swapped out.\\n // The user can decide to send another tx with the correct amount to reach the limit\\n if (hourlyUsage > chainTotalHourlyLimit) revert HourlyLimitExceeded();\\n chainTotalUsage[hour] = hourlyUsage;\\n\\n _burn(msg.sender, amount);\\n uint256 bridgeOut = amount;\\n if (isFeeExempt[msg.sender] == 0) {\\n bridgeOut -= (bridgeOut * bridgeDetails.fee) / BASE_PARAMS;\\n }\\n IERC20(bridgeToken).safeTransfer(to, bridgeOut);\\n return bridgeOut;\\n }\\n\\n // ============================ GOVERNANCE FUNCTIONS ===========================\\n\\n /// @notice Adds support for a bridge token\\n /// @param bridgeToken Bridge token to add: it should be a version of the stablecoin from another bridge\\n /// @param limit Limit on the balance of bridge token this contract could hold\\n /// @param hourlyLimit Limit on the hourly volume for this bridge\\n /// @param paused Whether swapping for this token should be paused or not\\n /// @param fee Fee taken upon swapping for or against this token\\n function addBridgeToken(\\n address bridgeToken,\\n uint256 limit,\\n uint256 hourlyLimit,\\n uint64 fee,\\n bool paused\\n ) external onlyGovernor {\\n if (bridges[bridgeToken].allowed || bridgeToken == address(0)) revert InvalidToken();\\n if (fee > BASE_PARAMS) revert TooHighParameterValue();\\n BridgeDetails memory _bridge;\\n _bridge.limit = limit;\\n _bridge.hourlyLimit = hourlyLimit;\\n _bridge.paused = paused;\\n _bridge.fee = fee;\\n _bridge.allowed = true;\\n bridges[bridgeToken] = _bridge;\\n bridgeTokensList.push(bridgeToken);\\n emit BridgeTokenAdded(bridgeToken, limit, hourlyLimit, fee, paused);\\n }\\n\\n /// @notice Removes support for a token\\n /// @param bridgeToken Address of the bridge token to remove support for\\n function removeBridgeToken(address bridgeToken) external onlyGovernor {\\n if (IERC20(bridgeToken).balanceOf(address(this)) != 0) revert AssetStillControlledInReserves();\\n delete bridges[bridgeToken];\\n // Deletion from `bridgeTokensList` loop\\n uint256 bridgeTokensListLength = bridgeTokensList.length;\\n for (uint256 i; i < bridgeTokensListLength - 1; ++i) {\\n if (bridgeTokensList[i] == bridgeToken) {\\n // Replace the `bridgeToken` to remove with the last of the list\\n bridgeTokensList[i] = bridgeTokensList[bridgeTokensListLength - 1];\\n break;\\n }\\n }\\n // Remove last element in array\\n bridgeTokensList.pop();\\n emit BridgeTokenRemoved(bridgeToken);\\n }\\n\\n /// @notice Recovers any ERC20 token\\n /// @dev Can be used to withdraw bridge tokens for them to be de-bridged on mainnet\\n function recoverERC20(address tokenAddress, address to, uint256 amountToRecover) external onlyGovernor {\\n IERC20(tokenAddress).safeTransfer(to, amountToRecover);\\n emit Recovered(tokenAddress, to, amountToRecover);\\n }\\n\\n /// @notice Updates the `limit` amount for `bridgeToken`\\n function setLimit(address bridgeToken, uint256 limit) external onlyGovernorOrGuardian {\\n if (!bridges[bridgeToken].allowed) revert InvalidToken();\\n bridges[bridgeToken].limit = limit;\\n emit BridgeTokenLimitUpdated(bridgeToken, limit);\\n }\\n\\n /// @notice Updates the `hourlyLimit` amount for `bridgeToken`\\n function setHourlyLimit(address bridgeToken, uint256 hourlyLimit) external onlyGovernorOrGuardian {\\n if (!bridges[bridgeToken].allowed) revert InvalidToken();\\n bridges[bridgeToken].hourlyLimit = hourlyLimit;\\n emit BridgeTokenHourlyLimitUpdated(bridgeToken, hourlyLimit);\\n }\\n\\n /// @notice Updates the `chainTotalHourlyLimit` amount\\n function setChainTotalHourlyLimit(uint256 hourlyLimit) external onlyGovernorOrGuardian {\\n chainTotalHourlyLimit = hourlyLimit;\\n emit HourlyLimitUpdated(hourlyLimit);\\n }\\n\\n /// @notice Updates the `fee` value for `bridgeToken`\\n function setSwapFee(address bridgeToken, uint64 fee) external onlyGovernorOrGuardian {\\n if (!bridges[bridgeToken].allowed) revert InvalidToken();\\n if (fee > BASE_PARAMS) revert TooHighParameterValue();\\n bridges[bridgeToken].fee = fee;\\n emit BridgeTokenFeeUpdated(bridgeToken, fee);\\n }\\n\\n /// @notice Pauses or unpauses swapping in and out for a token\\n function toggleBridge(address bridgeToken) external onlyGovernorOrGuardian {\\n if (!bridges[bridgeToken].allowed) revert InvalidToken();\\n bool pausedStatus = bridges[bridgeToken].paused;\\n bridges[bridgeToken].paused = !pausedStatus;\\n emit BridgeTokenToggled(bridgeToken, !pausedStatus);\\n }\\n\\n /// @notice Toggles fees for the address `theAddress`\\n function toggleFeesForAddress(address theAddress) external onlyGovernorOrGuardian {\\n uint256 feeExemptStatus = 1 - isFeeExempt[theAddress];\\n isFeeExempt[theAddress] = feeExemptStatus;\\n emit FeeToggled(theAddress, feeExemptStatus);\\n }\\n}\\n\",\"keccak256\":\"0x9782497e84a1dc4bc468778ede4aceb35cebf74e4159e2af8f469f49312c3841\",\"license\":\"GPL-3.0\"},\"contracts/interfaces/IAgToken.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-3.0\\n\\npragma solidity ^0.8.12;\\n\\nimport \\\"@openzeppelin/contracts-upgradeable/token/ERC20/IERC20Upgradeable.sol\\\";\\n\\n/// @title IAgToken\\n/// @author Angle Labs, Inc.\\n/// @notice Interface for the stablecoins `AgToken` contracts\\n/// @dev This interface only contains functions of the `AgToken` contract which are called by other contracts\\n/// of this module or of the first module of the Angle Protocol\\ninterface IAgToken is IERC20Upgradeable {\\n // ======================= Minter Role Only Functions ===========================\\n\\n /// @notice Lets the `StableMaster` contract or another whitelisted contract mint agTokens\\n /// @param account Address to mint to\\n /// @param amount Amount to mint\\n /// @dev The contracts allowed to issue agTokens are the `StableMaster` contract, `VaultManager` contracts\\n /// associated to this stablecoin as well as the flash loan module (if activated) and potentially contracts\\n /// whitelisted by governance\\n function mint(address account, uint256 amount) external;\\n\\n /// @notice Burns `amount` tokens from a `burner` address after being asked to by `sender`\\n /// @param amount Amount of tokens to burn\\n /// @param burner Address to burn from\\n /// @param sender Address which requested the burn from `burner`\\n /// @dev This method is to be called by a contract with the minter right after being requested\\n /// to do so by a `sender` address willing to burn tokens from another `burner` address\\n /// @dev The method checks the allowance between the `sender` and the `burner`\\n function burnFrom(uint256 amount, address burner, address sender) external;\\n\\n /// @notice Burns `amount` tokens from a `burner` address\\n /// @param amount Amount of tokens to burn\\n /// @param burner Address to burn from\\n /// @dev This method is to be called by a contract with a minter right on the AgToken after being\\n /// requested to do so by an address willing to burn tokens from its address\\n function burnSelf(uint256 amount, address burner) external;\\n\\n // ========================= Treasury Only Functions ===========================\\n\\n /// @notice Adds a minter in the contract\\n /// @param minter Minter address to add\\n /// @dev Zero address checks are performed directly in the `Treasury` contract\\n function addMinter(address minter) external;\\n\\n /// @notice Removes a minter from the contract\\n /// @param minter Minter address to remove\\n /// @dev This function can also be called by a minter wishing to revoke itself\\n function removeMinter(address minter) external;\\n\\n /// @notice Sets a new treasury contract\\n /// @param _treasury New treasury address\\n function setTreasury(address _treasury) external;\\n\\n // ========================= External functions ================================\\n\\n /// @notice Checks whether an address has the right to mint agTokens\\n /// @param minter Address for which the minting right should be checked\\n /// @return Whether the address has the right to mint agTokens or not\\n function isMinter(address minter) external view returns (bool);\\n\\n /// @notice Get the associated treasury\\n function treasury() external view returns (address);\\n}\\n\",\"keccak256\":\"0x0c83efcfc1fb9ae9ba830f7b89e3dab9abf6ad7a6205a31aa35fbccaa837dcdc\",\"license\":\"GPL-3.0\"},\"contracts/interfaces/ICoreBorrow.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-3.0\\n\\npragma solidity ^0.8.12;\\n\\n/// @title ICoreBorrow\\n/// @author Angle Labs, Inc.\\n/// @notice Interface for the `CoreBorrow` contract\\n/// @dev This interface only contains functions of the `CoreBorrow` contract which are called by other contracts\\n/// of this module\\ninterface ICoreBorrow {\\n /// @notice Checks if an address corresponds to a treasury of a stablecoin with a flash loan\\n /// module initialized on it\\n /// @param treasury Address to check\\n /// @return Whether the address has the `FLASHLOANER_TREASURY_ROLE` or not\\n function isFlashLoanerTreasury(address treasury) external view returns (bool);\\n\\n /// @notice Checks whether an address is governor of the Angle Protocol or not\\n /// @param admin Address to check\\n /// @return Whether the address has the `GOVERNOR_ROLE` or not\\n function isGovernor(address admin) external view returns (bool);\\n\\n /// @notice Checks whether an address is governor or a guardian of the Angle Protocol or not\\n /// @param admin Address to check\\n /// @return Whether the address has the `GUARDIAN_ROLE` or not\\n /// @dev Governance should make sure when adding a governor to also give this governor the guardian\\n /// role by calling the `addGovernor` function\\n function isGovernorOrGuardian(address admin) external view returns (bool);\\n}\\n\",\"keccak256\":\"0x10249210cbf522775f040baf981d7d037472168ce2746d87473ac7c29a34e62e\",\"license\":\"GPL-3.0\"},\"contracts/interfaces/IFlashAngle.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-3.0\\n\\npragma solidity ^0.8.12;\\n\\nimport \\\"./IAgToken.sol\\\";\\nimport \\\"./ICoreBorrow.sol\\\";\\n\\n/// @title IFlashAngle\\n/// @author Angle Labs, Inc.\\n/// @notice Interface for the `FlashAngle` contract\\n/// @dev This interface only contains functions of the contract which are called by other contracts\\n/// of this module\\ninterface IFlashAngle {\\n /// @notice Reference to the `CoreBorrow` contract managing the FlashLoan module\\n function core() external view returns (ICoreBorrow);\\n\\n /// @notice Sends the fees taken from flash loans to the treasury contract associated to the stablecoin\\n /// @param stablecoin Stablecoin from which profits should be sent\\n /// @return balance Amount of profits sent\\n /// @dev This function can only be called by the treasury contract\\n function accrueInterestToTreasury(IAgToken stablecoin) external returns (uint256 balance);\\n\\n /// @notice Adds support for a stablecoin\\n /// @param _treasury Treasury associated to the stablecoin to add support for\\n /// @dev This function can only be called by the `CoreBorrow` contract\\n function addStablecoinSupport(address _treasury) external;\\n\\n /// @notice Removes support for a stablecoin\\n /// @param _treasury Treasury associated to the stablecoin to remove support for\\n /// @dev This function can only be called by the `CoreBorrow` contract\\n function removeStablecoinSupport(address _treasury) external;\\n\\n /// @notice Sets a new core contract\\n /// @param _core Core contract address to set\\n /// @dev This function can only be called by the `CoreBorrow` contract\\n function setCore(address _core) external;\\n}\\n\",\"keccak256\":\"0x39b0097f695b9e934bccdc72676c91513f1077cc5d0fd151908fd25a7c5cfbe4\",\"license\":\"GPL-3.0\"},\"contracts/interfaces/ITreasury.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-3.0\\n\\npragma solidity ^0.8.12;\\n\\nimport \\\"./IAgToken.sol\\\";\\nimport \\\"./ICoreBorrow.sol\\\";\\nimport \\\"./IFlashAngle.sol\\\";\\n\\n/// @title ITreasury\\n/// @author Angle Labs, Inc.\\n/// @notice Interface for the `Treasury` contract\\n/// @dev This interface only contains functions of the `Treasury` which are called by other contracts\\n/// of this module\\ninterface ITreasury {\\n /// @notice Stablecoin handled by this `treasury` contract\\n function stablecoin() external view returns (IAgToken);\\n\\n /// @notice Checks whether a given address has the governor role\\n /// @param admin Address to check\\n /// @return Whether the address has the governor role\\n /// @dev Access control is only kept in the `CoreBorrow` contract\\n function isGovernor(address admin) external view returns (bool);\\n\\n /// @notice Checks whether a given address has the guardian or the governor role\\n /// @param admin Address to check\\n /// @return Whether the address has the guardian or the governor role\\n /// @dev Access control is only kept in the `CoreBorrow` contract which means that this function\\n /// queries the `CoreBorrow` contract\\n function isGovernorOrGuardian(address admin) external view returns (bool);\\n\\n /// @notice Checks whether a given address has well been initialized in this contract\\n /// as a `VaultManager`\\n /// @param _vaultManager Address to check\\n /// @return Whether the address has been initialized or not\\n function isVaultManager(address _vaultManager) external view returns (bool);\\n\\n /// @notice Sets a new flash loan module for this stablecoin\\n /// @param _flashLoanModule Reference to the new flash loan module\\n /// @dev This function removes the minting right to the old flash loan module and grants\\n /// it to the new module\\n function setFlashLoanModule(address _flashLoanModule) external;\\n\\n /// @notice Gets the vault manager list\\n function vaultManagerList(uint256 i) external returns (address);\\n}\\n\",\"keccak256\":\"0x06c2f781c08732ce1b5845c083af5742716245baa6c519bd737f32b230a884c1\",\"license\":\"GPL-3.0\"}},\"version\":1}", + "bytecode": "0x60806040523480156200001157600080fd5b50600054610100900460ff1615808015620000335750600054600160ff909116105b8062000063575062000050306200013d60201b6200273a1760201c565b15801562000063575060005460ff166001145b620000cb5760405162461bcd60e51b815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201526d191e481a5b9a5d1a585b1a5e995960921b606482015260840160405180910390fd5b6000805460ff191660011790558015620000ef576000805461ff0019166101001790555b801562000136576000805461ff0019169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15b506200014c565b6001600160a01b03163b151590565b6146d0806200015c6000396000f3fe608060405234801561001057600080fd5b50600436106102ff5760003560e01c806361d027b31161019c5780639f48118f116100ee578063ced67f0c11610097578063dd62ed3e11610071578063dd62ed3e14610724578063e3e286551461076a578063f0f442601461077d57600080fd5b8063ced67f0c1461066b578063d44ad63f146106fe578063d505accf1461071157600080fd5b8063aa271e1a116100c8578063aa271e1a14610620578063ba330bd714610643578063cd4839ca1461065657600080fd5b80639f48118f146105ef578063a457c2d7146105fa578063a9059cbb1461060d57600080fd5b80637ecebe001161015057806395d89b411161012a57806395d89b41146105c1578063983b2d56146105c95780639e4e0dae146105dc57600080fd5b80637ecebe00146105705780638933fb791461058357806390218cff146105ae57600080fd5b80637334d020116101815780637334d020146105425780637d4c9c2d146105555780637d74e25f1461056857600080fd5b806361d027b3146104c757806370a082311461050c57600080fd5b80633092afd511610255578063395093511161020957806340c10f19116101e357806340c10f19146104815780634dc32fcc146104945780635bfbec96146104a757600080fd5b8063395093511461043b5780633a55f89d1461044e5780633f4218e01461046157600080fd5b8063350ebe041161023a578063350ebe041461040d5780633644e5151461042057806336db43b51461042857600080fd5b80633092afd5146103eb578063313ce567146103fe57600080fd5b8063151dd755116102b757806323b872dd1161029157806323b872dd146103b25780632b471d8e146103c55780632e403e14146103d857600080fd5b8063151dd7551461038057806318160ddd146103a15780632342fb0e146103a957600080fd5b80630919a951116102e85780630919a95114610337578063095ea7b31461034a5780631171bda91461036d57600080fd5b806306fdde0314610304578063077f224a14610322575b600080fd5b61030c610790565b6040516103199190613e48565b60405180910390f35b610335610330366004613f95565b610822565b005b61033561034536600461400d565b610832565b61035d61035836600461402a565b610995565b6040519015158152602001610319565b61033561037b366004614056565b6109af565b61039361038e366004614097565b610b04565b604051908152602001610319565b603554610393565b61039360d25481565b61035d6103c0366004614056565b610dbe565b6103356103d33660046140ce565b610de2565b6103356103e636600461400d565b610e39565b6103356103f936600461400d565b6111e8565b60405160128152602001610319565b61033561041b3660046140fe565b6112d1565b6103936113da565b61033561043636600461402a565b6113e9565b61035d61044936600461402a565b611579565b61033561045c366004614135565b6115c0565b61039361046f36600461400d565b60d16020526000908152604090205481565b61033561048f36600461402a565b6116c3565b6103936104a236600461400d565b611716565b6103936104b5366004614135565b60d36020526000908152604090205481565b60cd546104e79073ffffffffffffffffffffffffffffffffffffffff1681565b60405173ffffffffffffffffffffffffffffffffffffffff9091168152602001610319565b61039361051a36600461400d565b73ffffffffffffffffffffffffffffffffffffffff1660009081526033602052604090205490565b61033561055036600461402a565b61175e565b610335610563366004614179565b6118f1565b610393611c59565b61039361057e36600461400d565b611c7e565b61039361059136600461402a565b60d060209081526000928352604080842090915290825290205481565b6103356105bc366004614135565b611ca9565b61030c611cb6565b6103356105d736600461400d565b611cc5565b6103356105ea3660046141d6565b611d8d565b610393633b9aca0081565b61035d61060836600461402a565b611f99565b61035d61061b36600461402a565b61206f565b61035d61062e36600461400d565b60cc6020526000908152604090205460ff1681565b6104e7610651366004614135565b61207d565b61065e6120b4565b604051610319919061420b565b6106c561067936600461400d565b60ce6020526000908152604090208054600182015460029092015490919067ffffffffffffffff81169060ff680100000000000000008204811691690100000000000000000090041685565b60408051958652602086019490945267ffffffffffffffff9092169284019290925290151560608301521515608082015260a001610319565b61039361070c366004614097565b612122565b61033561071f366004614265565b6122e7565b6103936107323660046142dc565b73ffffffffffffffffffffffffffffffffffffffff918216600090815260346020908152604080832093909416825291909152205490565b61033561077836600461400d565b6124a6565b61033561078b36600461400d565b61267a565b60606036805461079f9061430a565b80601f01602080910402602001604051908101604052809291908181526020018280546107cb9061430a565b80156108185780601f106107ed57610100808354040283529160200191610818565b820191906000526020600020905b8154815290600101906020018083116107fb57829003601f168201915b5050505050905090565b61082d838383612756565b505050565b60cd546040517f521d4de900000000000000000000000000000000000000000000000000000000815233600482015273ffffffffffffffffffffffffffffffffffffffff9091169063521d4de990602401602060405180830381865afa1580156108a0573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906108c49190614357565b6108fa576040517f99e120bc00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff8116600090815260d1602052604081205461092b9060016143a3565b73ffffffffffffffffffffffffffffffffffffffff8316600081815260d160205260409081902083905551919250907f979ef83e7e7a87cb48064e296dd7e997870d50f43acf8d7ad221313526c8ca0f906109899084815260200190565b60405180910390a25050565b6000336109a3818585612a35565b60019150505b92915050565b60cd546040517fe43581b800000000000000000000000000000000000000000000000000000000815233600482015273ffffffffffffffffffffffffffffffffffffffff9091169063e43581b890602401602060405180830381865afa158015610a1d573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610a419190614357565b610a77576040517fee3675d400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b610a9873ffffffffffffffffffffffffffffffffffffffff84168383612be0565b8173ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff167ffff3b3844276f57024e0b42afec1a37f75db36511e43819a4f2a63ab7862b64883604051610af791815260200190565b60405180910390a3505050565b73ffffffffffffffffffffffffffffffffffffffff8316600090815260ce60209081526040808320815160a081018352815481526001820154938101939093526002015467ffffffffffffffff81169183019190915260ff680100000000000000008204811615801560608501526901000000000000000000909204161515608083015280610b94575080608001515b15610bcb576040517fc1ab6dc100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015260009073ffffffffffffffffffffffffffffffffffffffff8716906370a0823190602401602060405180830381865afa158015610c38573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610c5c91906143b6565b8251909150610c6b86836143cf565b1115610c93578151811015610c8e578151610c879082906143a3565b9450610c93565b600094505b6000610ca1610e10426143e2565b73ffffffffffffffffffffffffffffffffffffffff8816600090815260d0602090815260408083208484528252909120549085015191925090610ce488836143cf565b1115610d0f5780846020015111610cfc576000610d0c565b808460200151610d0c91906143a3565b96505b610d1987826143cf565b73ffffffffffffffffffffffffffffffffffffffff8916600081815260d060209081526040808320878452909152902091909155610d599033308a612cb4565b33600090815260d16020526040812054889103610da657633b9aca00856040015167ffffffffffffffff1682610d8f919061441d565b610d9991906143e2565b610da390826143a3565b90505b610db08782612d12565b9450505050505b9392505050565b600033610dcc858285612e32565b610dd7858585612f03565b506001949350505050565b33600090815260cc602052604090205460ff16610e2b576040517ff8d2906c00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b610e3581836131b6565b5050565b60cd546040517fe43581b800000000000000000000000000000000000000000000000000000000815233600482015273ffffffffffffffffffffffffffffffffffffffff9091169063e43581b890602401602060405180830381865afa158015610ea7573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610ecb9190614357565b610f01576040517fee3675d400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015273ffffffffffffffffffffffffffffffffffffffff8216906370a0823190602401602060405180830381865afa158015610f6b573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610f8f91906143b6565b15610fc6576040517f2ef630ec00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff8116600090815260ce602052604081208181556001810182905560020180547fffffffffffffffffffffffffffffffffffffffffffff0000000000000000000016905560cf54905b61102e6001836143a3565b811015611139578273ffffffffffffffffffffffffffffffffffffffff1660cf828154811061105f5761105f614434565b60009182526020909120015473ffffffffffffffffffffffffffffffffffffffff16036111295760cf6110936001846143a3565b815481106110a3576110a3614434565b60009182526020909120015460cf805473ffffffffffffffffffffffffffffffffffffffff90921691839081106110dc576110dc614434565b9060005260206000200160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550611139565b61113281614463565b9050611023565b5060cf80548061114b5761114b61449b565b60008281526020812082017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff90810180547fffffffffffffffffffffffff000000000000000000000000000000000000000016905590910190915560405173ffffffffffffffffffffffffffffffffffffffff8416917f5c95b49c4d59d97a2f044167723f29c74b30f99702e3fd406c3830160aa9ccb891a25050565b60cd5473ffffffffffffffffffffffffffffffffffffffff16331480159061122657503373ffffffffffffffffffffffffffffffffffffffff821614155b1561125d576040517fddb5de5e00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff8116600081815260cc602052604080822080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00169055517f98c15241d6c02bc5ee0b780e11b3ea737a2defd9d04877edbe9f9497065bd02f9190a250565b33600090815260cc602052604090205460ff1661131a576040517ff8d2906c00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff16146113d05773ffffffffffffffffffffffffffffffffffffffff828116600090815260346020908152604080832093851683529290522054838110156113ba576040517f715ec26c00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6113ce83836113c987856143a3565b612a35565b505b61082d82846131b6565b60006113e46133a3565b905090565b60cd546040517f521d4de900000000000000000000000000000000000000000000000000000000815233600482015273ffffffffffffffffffffffffffffffffffffffff9091169063521d4de990602401602060405180830381865afa158015611457573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061147b9190614357565b6114b1576040517f99e120bc00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff8216600090815260ce602052604090206002015468010000000000000000900460ff1661151f576040517fc1ab6dc100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff8216600081815260ce602052604090819020839055517fe7b113fba37131b6396680a0c55790a697ec975e198ff8cfd89dac90a6379e61906109899084815260200190565b33600081815260346020908152604080832073ffffffffffffffffffffffffffffffffffffffff871684529091528120549091906109a390829086906113c99087906143cf565b60cd546040517f521d4de900000000000000000000000000000000000000000000000000000000815233600482015273ffffffffffffffffffffffffffffffffffffffff9091169063521d4de990602401602060405180830381865afa15801561162e573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906116529190614357565b611688576040517f99e120bc00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60d28190556040518181527fc3b69829afe2345596a02c8b587d41f796ba0094481d899e1b2e07b7532a1e219060200160405180910390a150565b33600090815260cc602052604090205460ff1661170c576040517ff8d2906c00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b610e358282612d12565b73ffffffffffffffffffffffffffffffffffffffff8116600090815260d06020526040812081611748610e10426143e2565b8152602001908152602001600020549050919050565b60cd546040517f521d4de900000000000000000000000000000000000000000000000000000000815233600482015273ffffffffffffffffffffffffffffffffffffffff9091169063521d4de990602401602060405180830381865afa1580156117cc573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906117f09190614357565b611826576040517f99e120bc00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff8216600090815260ce602052604090206002015468010000000000000000900460ff16611894576040517fc1ab6dc100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff8216600081815260ce602052604090819020600101839055517fe13ac9338b2ee623233f83c1b3ceab16490fa3e3737fac7f0970d0830a9f4871906109899084815260200190565b60cd546040517fe43581b800000000000000000000000000000000000000000000000000000000815233600482015273ffffffffffffffffffffffffffffffffffffffff9091169063e43581b890602401602060405180830381865afa15801561195f573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906119839190614357565b6119b9576040517fee3675d400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff8516600090815260ce602052604090206002015468010000000000000000900460ff1680611a10575073ffffffffffffffffffffffffffffffffffffffff8516155b15611a47576040517fc1ab6dc100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b633b9aca008267ffffffffffffffff161115611a8f576040517feca1d2c600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040805160a08101825260008082526020820181905291810182905260608101829052608081019190915284815260208082018581528315156080840190815267ffffffffffffffff808716604080870191825260016060880181815273ffffffffffffffffffffffffffffffffffffffff8e16600081815260ce9099528389208a5181559751888401559351600290970180549151965115156901000000000000000000027fffffffffffffffffffffffffffffffffffffffffffff00ffffffffffffffffff97151568010000000000000000027fffffffffffffffffffffffffffffffffffffffffffffff000000000000000000909316989096169790971717949094169290921790935560cf805492830181559093527facb8d954e2cfef495862221e91bd7523613cf8808827cb33edfe4904cc51bf290180547fffffffffffffffffffffffff0000000000000000000000000000000000000000168217905590517f53087ff85d80a7671594bd2e86b92af22e0b3c2c441c8033bba7399b7b5cbe2390611c49908890889088908890938452602084019290925267ffffffffffffffff1660408301521515606082015260800190565b60405180910390a2505050505050565b600060d381611c6a610e10426143e2565b815260200190815260200160002054905090565b73ffffffffffffffffffffffffffffffffffffffff81166000908152609960205260408120546109a9565b611cb333826131b6565b50565b60606037805461079f9061430a565b60cd5473ffffffffffffffffffffffffffffffffffffffff163314611d16576040517fb90cdbb100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff8116600081815260cc602052604080822080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00166001179055517f98c15241d6c02bc5ee0b780e11b3ea737a2defd9d04877edbe9f9497065bd02f9190a250565b60cd546040517f521d4de900000000000000000000000000000000000000000000000000000000815233600482015273ffffffffffffffffffffffffffffffffffffffff9091169063521d4de990602401602060405180830381865afa158015611dfb573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611e1f9190614357565b611e55576040517f99e120bc00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff8216600090815260ce602052604090206002015468010000000000000000900460ff16611ec3576040517fc1ab6dc100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b633b9aca008167ffffffffffffffff161115611f0b576040517feca1d2c600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff8216600081815260ce602090815260409182902060020180547fffffffffffffffffffffffffffffffffffffffffffffffff00000000000000001667ffffffffffffffff861690811790915591519182527f901f9de19b475adc8da4110434b8df940dce085afd05e2281c86807f3a899d299101610989565b33600081815260346020908152604080832073ffffffffffffffffffffffffffffffffffffffff8716845290915281205490919083811015612062576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602560248201527f45524332303a2064656372656173656420616c6c6f77616e63652062656c6f7760448201527f207a65726f00000000000000000000000000000000000000000000000000000060648201526084015b60405180910390fd5b610dd78286868403612a35565b6000336109a3818585612f03565b60cf818154811061208d57600080fd5b60009182526020909120015473ffffffffffffffffffffffffffffffffffffffff16905081565b606060cf80548060200260200160405190810160405280929190818152602001828054801561081857602002820191906000526020600020905b815473ffffffffffffffffffffffffffffffffffffffff1681526001909101906020018083116120ee575050505050905090565b73ffffffffffffffffffffffffffffffffffffffff8316600090815260ce60209081526040808320815160a081018352815481526001820154938101939093526002015467ffffffffffffffff81169183019190915260ff6801000000000000000082048116158015606085015269010000000000000000009092041615156080830152806121b2575080608001515b156121e9576040517fc1ab6dc100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60006121f7610e10426143e2565b600081815260d36020526040812054919250906122159087906143cf565b905060d254811115612253576040517f6d43d1ac00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600082815260d36020526040902081905561226e33876131b6565b33600090815260d160205260408120548791036122bb57633b9aca00846040015167ffffffffffffffff16826122a4919061441d565b6122ae91906143e2565b6122b890826143a3565b90505b6122dc73ffffffffffffffffffffffffffffffffffffffff89168783612be0565b979650505050505050565b83421115612351576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f45524332305065726d69743a206578706972656420646561646c696e650000006044820152606401612059565b60007f6e71edae12b1b97f4d1f60370fef10105fa2faae0126114a169c64845d6126c98888886123808c61341e565b60408051602081019690965273ffffffffffffffffffffffffffffffffffffffff94851690860152929091166060840152608083015260a082015260c0810186905260e00160405160208183030381529060405280519060200120905060006123e882613453565b905060006123f8828787876134bc565b90508973ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff161461248f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601e60248201527f45524332305065726d69743a20696e76616c6964207369676e617475726500006044820152606401612059565b61249a8a8a8a612a35565b50505050505050505050565b60cd546040517f521d4de900000000000000000000000000000000000000000000000000000000815233600482015273ffffffffffffffffffffffffffffffffffffffff9091169063521d4de990602401602060405180830381865afa158015612514573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906125389190614357565b61256e576040517f99e120bc00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff8116600090815260ce602052604090206002015468010000000000000000900460ff166125dc576040517fc1ab6dc100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff8116600081815260ce602090815260409182902060020180547fffffffffffffffffffffffffffffffffffffffffffff00ffffffffffffffffff811669010000000000000000009182900460ff16801592830291909117909255925192835292917ff7c93079dcbf699749d66345a351afab7d24219bb1d915c9f4fc4cf03f00d3979101610989565b60cd5473ffffffffffffffffffffffffffffffffffffffff1633146126cb576040517fb90cdbb100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60cd80547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83169081179091556040517f7dae230f18360d76a040c81f050aa14eb9d6dc7901b20fc5d855e2a20fe814d190600090a250565b73ffffffffffffffffffffffffffffffffffffffff163b151590565b600054610100900460ff16158080156127765750600054600160ff909116105b806127905750303b158015612790575060005460ff166001145b61281c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201527f647920696e697469616c697a65640000000000000000000000000000000000006064820152608401612059565b600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00166001179055801561287a57600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff166101001790555b3073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1663e9cbd8226040518163ffffffff1660e01b8152600401602060405180830381865afa1580156128dc573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061290091906144ca565b73ffffffffffffffffffffffffffffffffffffffff161461294d576040517f14bcf5c800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b612956846134e4565b61296084846135ba565b60cd80547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff84169081179091556040517f7dae230f18360d76a040c81f050aa14eb9d6dc7901b20fc5d855e2a20fe814d190600090a28015612a2f57600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15b50505050565b73ffffffffffffffffffffffffffffffffffffffff8316612ad7576040517f08c379a0000000000000000000000000000000000000000000000000000000008152602060048201526024808201527f45524332303a20617070726f76652066726f6d20746865207a65726f2061646460448201527f72657373000000000000000000000000000000000000000000000000000000006064820152608401612059565b73ffffffffffffffffffffffffffffffffffffffff8216612b7a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602260248201527f45524332303a20617070726f766520746f20746865207a65726f20616464726560448201527f73730000000000000000000000000000000000000000000000000000000000006064820152608401612059565b73ffffffffffffffffffffffffffffffffffffffff83811660008181526034602090815260408083209487168084529482529182902085905590518481527f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b9259101610af7565b60405173ffffffffffffffffffffffffffffffffffffffff831660248201526044810182905261082d9084907fa9059cbb00000000000000000000000000000000000000000000000000000000906064015b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff000000000000000000000000000000000000000000000000000000009093169290921790915261365b565b60405173ffffffffffffffffffffffffffffffffffffffff80851660248301528316604482015260648101829052612a2f9085907f23b872dd0000000000000000000000000000000000000000000000000000000090608401612c32565b73ffffffffffffffffffffffffffffffffffffffff8216612d8f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601f60248201527f45524332303a206d696e7420746f20746865207a65726f2061646472657373006044820152606401612059565b8060356000828254612da191906143cf565b909155505073ffffffffffffffffffffffffffffffffffffffff821660009081526033602052604081208054839290612ddb9084906143cf565b909155505060405181815273ffffffffffffffffffffffffffffffffffffffff8316906000907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef9060200160405180910390a35050565b73ffffffffffffffffffffffffffffffffffffffff8381166000908152603460209081526040808320938616835292905220547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8114612a2f5781811015612ef6576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f45524332303a20696e73756666696369656e7420616c6c6f77616e63650000006044820152606401612059565b612a2f8484848403612a35565b73ffffffffffffffffffffffffffffffffffffffff8316612fa6576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602560248201527f45524332303a207472616e736665722066726f6d20746865207a65726f20616460448201527f64726573730000000000000000000000000000000000000000000000000000006064820152608401612059565b73ffffffffffffffffffffffffffffffffffffffff8216613049576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602360248201527f45524332303a207472616e7366657220746f20746865207a65726f206164647260448201527f65737300000000000000000000000000000000000000000000000000000000006064820152608401612059565b73ffffffffffffffffffffffffffffffffffffffff8316600090815260336020526040902054818110156130ff576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f45524332303a207472616e7366657220616d6f756e742065786365656473206260448201527f616c616e636500000000000000000000000000000000000000000000000000006064820152608401612059565b73ffffffffffffffffffffffffffffffffffffffff8085166000908152603360205260408082208585039055918516815290812080548492906131439084906143cf565b925050819055508273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef846040516131a991815260200190565b60405180910390a3612a2f565b73ffffffffffffffffffffffffffffffffffffffff8216613259576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602160248201527f45524332303a206275726e2066726f6d20746865207a65726f2061646472657360448201527f73000000000000000000000000000000000000000000000000000000000000006064820152608401612059565b73ffffffffffffffffffffffffffffffffffffffff82166000908152603360205260409020548181101561330f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602260248201527f45524332303a206275726e20616d6f756e7420657863656564732062616c616e60448201527f63650000000000000000000000000000000000000000000000000000000000006064820152608401612059565b73ffffffffffffffffffffffffffffffffffffffff8316600090815260336020526040812083830390556035805484929061334b9084906143a3565b909155505060405182815260009073ffffffffffffffffffffffffffffffffffffffff8516907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef9060200160405180910390a3505050565b60006113e47f8b73c3c69bb8fe3d512ecc4cf759cc79239f7b179b0ffacaa9a75d522b39400f6133d260655490565b6066546040805160208101859052908101839052606081018290524660808201523060a082015260009060c0016040516020818303038152906040528051906020012090509392505050565b73ffffffffffffffffffffffffffffffffffffffff811660009081526099602052604090208054600181018255905b50919050565b60006109a96134606133a3565b836040517f19010000000000000000000000000000000000000000000000000000000000006020820152602281018390526042810182905260009060620160405160208183030381529060405280519060200120905092915050565b60008060006134cd87878787613767565b915091506134da8161387f565b5095945050505050565b600054610100900460ff1661357b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201527f6e697469616c697a696e670000000000000000000000000000000000000000006064820152608401612059565b611cb3816040518060400160405280600181526020017f3100000000000000000000000000000000000000000000000000000000000000815250613ad3565b600054610100900460ff16613651576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201527f6e697469616c697a696e670000000000000000000000000000000000000000006064820152608401612059565b610e358282613b84565b60006136bd826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c65648152508573ffffffffffffffffffffffffffffffffffffffff16613c349092919063ffffffff16565b80519091501561082d57808060200190518101906136db9190614357565b61082d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e60448201527f6f742073756363656564000000000000000000000000000000000000000000006064820152608401612059565b6000807f7fffffffffffffffffffffffffffffff5d576e7357a4501ddfe92f46681b20a083111561379e5750600090506003613876565b8460ff16601b141580156137b657508460ff16601c14155b156137c75750600090506004613876565b6040805160008082526020820180845289905260ff881692820192909252606081018690526080810185905260019060a0016020604051602081039080840390855afa15801561381b573d6000803e3d6000fd5b50506040517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0015191505073ffffffffffffffffffffffffffffffffffffffff811661386f57600060019250925050613876565b9150600090505b94509492505050565b6000816004811115613893576138936144e7565b0361389b5750565b60018160048111156138af576138af6144e7565b03613916576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601860248201527f45434453413a20696e76616c6964207369676e617475726500000000000000006044820152606401612059565b600281600481111561392a5761392a6144e7565b03613991576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601f60248201527f45434453413a20696e76616c6964207369676e6174757265206c656e677468006044820152606401612059565b60038160048111156139a5576139a56144e7565b03613a32576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602260248201527f45434453413a20696e76616c6964207369676e6174757265202773272076616c60448201527f75650000000000000000000000000000000000000000000000000000000000006064820152608401612059565b6004816004811115613a4657613a466144e7565b03611cb3576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602260248201527f45434453413a20696e76616c6964207369676e6174757265202776272076616c60448201527f75650000000000000000000000000000000000000000000000000000000000006064820152608401612059565b600054610100900460ff16613b6a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201527f6e697469616c697a696e670000000000000000000000000000000000000000006064820152608401612059565b815160209283012081519190920120606591909155606655565b600054610100900460ff16613c1b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201527f6e697469616c697a696e670000000000000000000000000000000000000000006064820152608401612059565b6036613c278382614564565b50603761082d8282614564565b6060613c438484600085613c4b565b949350505050565b606082471015613cdd576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f60448201527f722063616c6c00000000000000000000000000000000000000000000000000006064820152608401612059565b73ffffffffffffffffffffffffffffffffffffffff85163b613d5b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006044820152606401612059565b6000808673ffffffffffffffffffffffffffffffffffffffff168587604051613d84919061467e565b60006040518083038185875af1925050503d8060008114613dc1576040519150601f19603f3d011682016040523d82523d6000602084013e613dc6565b606091505b50915091506122dc82828660608315613de0575081610db7565b825115613df05782518084602001fd5b816040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016120599190613e48565b60005b83811015613e3f578181015183820152602001613e27565b50506000910152565b6020815260008251806020840152613e67816040850160208701613e24565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169190910160400192915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b600082601f830112613ed957600080fd5b813567ffffffffffffffff80821115613ef457613ef4613e99565b604051601f83017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0908116603f01168101908282118183101715613f3a57613f3a613e99565b81604052838152866020858801011115613f5357600080fd5b836020870160208301376000602085830101528094505050505092915050565b73ffffffffffffffffffffffffffffffffffffffff81168114611cb357600080fd5b600080600060608486031215613faa57600080fd5b833567ffffffffffffffff80821115613fc257600080fd5b613fce87838801613ec8565b94506020860135915080821115613fe457600080fd5b50613ff186828701613ec8565b925050604084013561400281613f73565b809150509250925092565b60006020828403121561401f57600080fd5b8135610db781613f73565b6000806040838503121561403d57600080fd5b823561404881613f73565b946020939093013593505050565b60008060006060848603121561406b57600080fd5b833561407681613f73565b9250602084013561408681613f73565b929592945050506040919091013590565b6000806000606084860312156140ac57600080fd5b83356140b781613f73565b925060208401359150604084013561400281613f73565b600080604083850312156140e157600080fd5b8235915060208301356140f381613f73565b809150509250929050565b60008060006060848603121561411357600080fd5b83359250602084013561412581613f73565b9150604084013561400281613f73565b60006020828403121561414757600080fd5b5035919050565b803567ffffffffffffffff8116811461416657600080fd5b919050565b8015158114611cb357600080fd5b600080600080600060a0868803121561419157600080fd5b853561419c81613f73565b945060208601359350604086013592506141b86060870161414e565b915060808601356141c88161416b565b809150509295509295909350565b600080604083850312156141e957600080fd5b82356141f481613f73565b91506142026020840161414e565b90509250929050565b6020808252825182820181905260009190848201906040850190845b8181101561425957835173ffffffffffffffffffffffffffffffffffffffff1683529284019291840191600101614227565b50909695505050505050565b600080600080600080600060e0888a03121561428057600080fd5b873561428b81613f73565b9650602088013561429b81613f73565b95506040880135945060608801359350608088013560ff811681146142bf57600080fd5b9699959850939692959460a0840135945060c09093013592915050565b600080604083850312156142ef57600080fd5b82356142fa81613f73565b915060208301356140f381613f73565b600181811c9082168061431e57607f821691505b60208210810361344d577f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b60006020828403121561436957600080fd5b8151610db78161416b565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b818103818111156109a9576109a9614374565b6000602082840312156143c857600080fd5b5051919050565b808201808211156109a9576109a9614374565b600082614418577f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b500490565b80820281158282048414176109a9576109a9614374565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff820361449457614494614374565b5060010190565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603160045260246000fd5b6000602082840312156144dc57600080fd5b8151610db781613f73565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b601f82111561082d57600081815260208120601f850160051c8101602086101561453d5750805b601f850160051c820191505b8181101561455c57828155600101614549565b505050505050565b815167ffffffffffffffff81111561457e5761457e613e99565b6145928161458c845461430a565b84614516565b602080601f8311600181146145e557600084156145af5750858301515b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600386901b1c1916600185901b17855561455c565b6000858152602081207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08616915b8281101561463257888601518255948401946001909101908401614613565b508582101561466e57878501517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600388901b60f8161c191681555b5050505050600190811b01905550565b60008251614690818460208701613e24565b919091019291505056fea2646970667358221220f2eb02bac1667a72be85ab617a5b5aa3d8f7a9b09b4d1fde9756b7a5636daf2164736f6c63430008110033", + "deployedBytecode": "0x608060405234801561001057600080fd5b50600436106102ff5760003560e01c806361d027b31161019c5780639f48118f116100ee578063ced67f0c11610097578063dd62ed3e11610071578063dd62ed3e14610724578063e3e286551461076a578063f0f442601461077d57600080fd5b8063ced67f0c1461066b578063d44ad63f146106fe578063d505accf1461071157600080fd5b8063aa271e1a116100c8578063aa271e1a14610620578063ba330bd714610643578063cd4839ca1461065657600080fd5b80639f48118f146105ef578063a457c2d7146105fa578063a9059cbb1461060d57600080fd5b80637ecebe001161015057806395d89b411161012a57806395d89b41146105c1578063983b2d56146105c95780639e4e0dae146105dc57600080fd5b80637ecebe00146105705780638933fb791461058357806390218cff146105ae57600080fd5b80637334d020116101815780637334d020146105425780637d4c9c2d146105555780637d74e25f1461056857600080fd5b806361d027b3146104c757806370a082311461050c57600080fd5b80633092afd511610255578063395093511161020957806340c10f19116101e357806340c10f19146104815780634dc32fcc146104945780635bfbec96146104a757600080fd5b8063395093511461043b5780633a55f89d1461044e5780633f4218e01461046157600080fd5b8063350ebe041161023a578063350ebe041461040d5780633644e5151461042057806336db43b51461042857600080fd5b80633092afd5146103eb578063313ce567146103fe57600080fd5b8063151dd755116102b757806323b872dd1161029157806323b872dd146103b25780632b471d8e146103c55780632e403e14146103d857600080fd5b8063151dd7551461038057806318160ddd146103a15780632342fb0e146103a957600080fd5b80630919a951116102e85780630919a95114610337578063095ea7b31461034a5780631171bda91461036d57600080fd5b806306fdde0314610304578063077f224a14610322575b600080fd5b61030c610790565b6040516103199190613e48565b60405180910390f35b610335610330366004613f95565b610822565b005b61033561034536600461400d565b610832565b61035d61035836600461402a565b610995565b6040519015158152602001610319565b61033561037b366004614056565b6109af565b61039361038e366004614097565b610b04565b604051908152602001610319565b603554610393565b61039360d25481565b61035d6103c0366004614056565b610dbe565b6103356103d33660046140ce565b610de2565b6103356103e636600461400d565b610e39565b6103356103f936600461400d565b6111e8565b60405160128152602001610319565b61033561041b3660046140fe565b6112d1565b6103936113da565b61033561043636600461402a565b6113e9565b61035d61044936600461402a565b611579565b61033561045c366004614135565b6115c0565b61039361046f36600461400d565b60d16020526000908152604090205481565b61033561048f36600461402a565b6116c3565b6103936104a236600461400d565b611716565b6103936104b5366004614135565b60d36020526000908152604090205481565b60cd546104e79073ffffffffffffffffffffffffffffffffffffffff1681565b60405173ffffffffffffffffffffffffffffffffffffffff9091168152602001610319565b61039361051a36600461400d565b73ffffffffffffffffffffffffffffffffffffffff1660009081526033602052604090205490565b61033561055036600461402a565b61175e565b610335610563366004614179565b6118f1565b610393611c59565b61039361057e36600461400d565b611c7e565b61039361059136600461402a565b60d060209081526000928352604080842090915290825290205481565b6103356105bc366004614135565b611ca9565b61030c611cb6565b6103356105d736600461400d565b611cc5565b6103356105ea3660046141d6565b611d8d565b610393633b9aca0081565b61035d61060836600461402a565b611f99565b61035d61061b36600461402a565b61206f565b61035d61062e36600461400d565b60cc6020526000908152604090205460ff1681565b6104e7610651366004614135565b61207d565b61065e6120b4565b604051610319919061420b565b6106c561067936600461400d565b60ce6020526000908152604090208054600182015460029092015490919067ffffffffffffffff81169060ff680100000000000000008204811691690100000000000000000090041685565b60408051958652602086019490945267ffffffffffffffff9092169284019290925290151560608301521515608082015260a001610319565b61039361070c366004614097565b612122565b61033561071f366004614265565b6122e7565b6103936107323660046142dc565b73ffffffffffffffffffffffffffffffffffffffff918216600090815260346020908152604080832093909416825291909152205490565b61033561077836600461400d565b6124a6565b61033561078b36600461400d565b61267a565b60606036805461079f9061430a565b80601f01602080910402602001604051908101604052809291908181526020018280546107cb9061430a565b80156108185780601f106107ed57610100808354040283529160200191610818565b820191906000526020600020905b8154815290600101906020018083116107fb57829003601f168201915b5050505050905090565b61082d838383612756565b505050565b60cd546040517f521d4de900000000000000000000000000000000000000000000000000000000815233600482015273ffffffffffffffffffffffffffffffffffffffff9091169063521d4de990602401602060405180830381865afa1580156108a0573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906108c49190614357565b6108fa576040517f99e120bc00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff8116600090815260d1602052604081205461092b9060016143a3565b73ffffffffffffffffffffffffffffffffffffffff8316600081815260d160205260409081902083905551919250907f979ef83e7e7a87cb48064e296dd7e997870d50f43acf8d7ad221313526c8ca0f906109899084815260200190565b60405180910390a25050565b6000336109a3818585612a35565b60019150505b92915050565b60cd546040517fe43581b800000000000000000000000000000000000000000000000000000000815233600482015273ffffffffffffffffffffffffffffffffffffffff9091169063e43581b890602401602060405180830381865afa158015610a1d573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610a419190614357565b610a77576040517fee3675d400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b610a9873ffffffffffffffffffffffffffffffffffffffff84168383612be0565b8173ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff167ffff3b3844276f57024e0b42afec1a37f75db36511e43819a4f2a63ab7862b64883604051610af791815260200190565b60405180910390a3505050565b73ffffffffffffffffffffffffffffffffffffffff8316600090815260ce60209081526040808320815160a081018352815481526001820154938101939093526002015467ffffffffffffffff81169183019190915260ff680100000000000000008204811615801560608501526901000000000000000000909204161515608083015280610b94575080608001515b15610bcb576040517fc1ab6dc100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015260009073ffffffffffffffffffffffffffffffffffffffff8716906370a0823190602401602060405180830381865afa158015610c38573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610c5c91906143b6565b8251909150610c6b86836143cf565b1115610c93578151811015610c8e578151610c879082906143a3565b9450610c93565b600094505b6000610ca1610e10426143e2565b73ffffffffffffffffffffffffffffffffffffffff8816600090815260d0602090815260408083208484528252909120549085015191925090610ce488836143cf565b1115610d0f5780846020015111610cfc576000610d0c565b808460200151610d0c91906143a3565b96505b610d1987826143cf565b73ffffffffffffffffffffffffffffffffffffffff8916600081815260d060209081526040808320878452909152902091909155610d599033308a612cb4565b33600090815260d16020526040812054889103610da657633b9aca00856040015167ffffffffffffffff1682610d8f919061441d565b610d9991906143e2565b610da390826143a3565b90505b610db08782612d12565b9450505050505b9392505050565b600033610dcc858285612e32565b610dd7858585612f03565b506001949350505050565b33600090815260cc602052604090205460ff16610e2b576040517ff8d2906c00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b610e3581836131b6565b5050565b60cd546040517fe43581b800000000000000000000000000000000000000000000000000000000815233600482015273ffffffffffffffffffffffffffffffffffffffff9091169063e43581b890602401602060405180830381865afa158015610ea7573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610ecb9190614357565b610f01576040517fee3675d400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015273ffffffffffffffffffffffffffffffffffffffff8216906370a0823190602401602060405180830381865afa158015610f6b573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610f8f91906143b6565b15610fc6576040517f2ef630ec00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff8116600090815260ce602052604081208181556001810182905560020180547fffffffffffffffffffffffffffffffffffffffffffff0000000000000000000016905560cf54905b61102e6001836143a3565b811015611139578273ffffffffffffffffffffffffffffffffffffffff1660cf828154811061105f5761105f614434565b60009182526020909120015473ffffffffffffffffffffffffffffffffffffffff16036111295760cf6110936001846143a3565b815481106110a3576110a3614434565b60009182526020909120015460cf805473ffffffffffffffffffffffffffffffffffffffff90921691839081106110dc576110dc614434565b9060005260206000200160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550611139565b61113281614463565b9050611023565b5060cf80548061114b5761114b61449b565b60008281526020812082017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff90810180547fffffffffffffffffffffffff000000000000000000000000000000000000000016905590910190915560405173ffffffffffffffffffffffffffffffffffffffff8416917f5c95b49c4d59d97a2f044167723f29c74b30f99702e3fd406c3830160aa9ccb891a25050565b60cd5473ffffffffffffffffffffffffffffffffffffffff16331480159061122657503373ffffffffffffffffffffffffffffffffffffffff821614155b1561125d576040517fddb5de5e00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff8116600081815260cc602052604080822080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00169055517f98c15241d6c02bc5ee0b780e11b3ea737a2defd9d04877edbe9f9497065bd02f9190a250565b33600090815260cc602052604090205460ff1661131a576040517ff8d2906c00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff16146113d05773ffffffffffffffffffffffffffffffffffffffff828116600090815260346020908152604080832093851683529290522054838110156113ba576040517f715ec26c00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6113ce83836113c987856143a3565b612a35565b505b61082d82846131b6565b60006113e46133a3565b905090565b60cd546040517f521d4de900000000000000000000000000000000000000000000000000000000815233600482015273ffffffffffffffffffffffffffffffffffffffff9091169063521d4de990602401602060405180830381865afa158015611457573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061147b9190614357565b6114b1576040517f99e120bc00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff8216600090815260ce602052604090206002015468010000000000000000900460ff1661151f576040517fc1ab6dc100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff8216600081815260ce602052604090819020839055517fe7b113fba37131b6396680a0c55790a697ec975e198ff8cfd89dac90a6379e61906109899084815260200190565b33600081815260346020908152604080832073ffffffffffffffffffffffffffffffffffffffff871684529091528120549091906109a390829086906113c99087906143cf565b60cd546040517f521d4de900000000000000000000000000000000000000000000000000000000815233600482015273ffffffffffffffffffffffffffffffffffffffff9091169063521d4de990602401602060405180830381865afa15801561162e573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906116529190614357565b611688576040517f99e120bc00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60d28190556040518181527fc3b69829afe2345596a02c8b587d41f796ba0094481d899e1b2e07b7532a1e219060200160405180910390a150565b33600090815260cc602052604090205460ff1661170c576040517ff8d2906c00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b610e358282612d12565b73ffffffffffffffffffffffffffffffffffffffff8116600090815260d06020526040812081611748610e10426143e2565b8152602001908152602001600020549050919050565b60cd546040517f521d4de900000000000000000000000000000000000000000000000000000000815233600482015273ffffffffffffffffffffffffffffffffffffffff9091169063521d4de990602401602060405180830381865afa1580156117cc573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906117f09190614357565b611826576040517f99e120bc00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff8216600090815260ce602052604090206002015468010000000000000000900460ff16611894576040517fc1ab6dc100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff8216600081815260ce602052604090819020600101839055517fe13ac9338b2ee623233f83c1b3ceab16490fa3e3737fac7f0970d0830a9f4871906109899084815260200190565b60cd546040517fe43581b800000000000000000000000000000000000000000000000000000000815233600482015273ffffffffffffffffffffffffffffffffffffffff9091169063e43581b890602401602060405180830381865afa15801561195f573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906119839190614357565b6119b9576040517fee3675d400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff8516600090815260ce602052604090206002015468010000000000000000900460ff1680611a10575073ffffffffffffffffffffffffffffffffffffffff8516155b15611a47576040517fc1ab6dc100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b633b9aca008267ffffffffffffffff161115611a8f576040517feca1d2c600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040805160a08101825260008082526020820181905291810182905260608101829052608081019190915284815260208082018581528315156080840190815267ffffffffffffffff808716604080870191825260016060880181815273ffffffffffffffffffffffffffffffffffffffff8e16600081815260ce9099528389208a5181559751888401559351600290970180549151965115156901000000000000000000027fffffffffffffffffffffffffffffffffffffffffffff00ffffffffffffffffff97151568010000000000000000027fffffffffffffffffffffffffffffffffffffffffffffff000000000000000000909316989096169790971717949094169290921790935560cf805492830181559093527facb8d954e2cfef495862221e91bd7523613cf8808827cb33edfe4904cc51bf290180547fffffffffffffffffffffffff0000000000000000000000000000000000000000168217905590517f53087ff85d80a7671594bd2e86b92af22e0b3c2c441c8033bba7399b7b5cbe2390611c49908890889088908890938452602084019290925267ffffffffffffffff1660408301521515606082015260800190565b60405180910390a2505050505050565b600060d381611c6a610e10426143e2565b815260200190815260200160002054905090565b73ffffffffffffffffffffffffffffffffffffffff81166000908152609960205260408120546109a9565b611cb333826131b6565b50565b60606037805461079f9061430a565b60cd5473ffffffffffffffffffffffffffffffffffffffff163314611d16576040517fb90cdbb100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff8116600081815260cc602052604080822080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00166001179055517f98c15241d6c02bc5ee0b780e11b3ea737a2defd9d04877edbe9f9497065bd02f9190a250565b60cd546040517f521d4de900000000000000000000000000000000000000000000000000000000815233600482015273ffffffffffffffffffffffffffffffffffffffff9091169063521d4de990602401602060405180830381865afa158015611dfb573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611e1f9190614357565b611e55576040517f99e120bc00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff8216600090815260ce602052604090206002015468010000000000000000900460ff16611ec3576040517fc1ab6dc100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b633b9aca008167ffffffffffffffff161115611f0b576040517feca1d2c600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff8216600081815260ce602090815260409182902060020180547fffffffffffffffffffffffffffffffffffffffffffffffff00000000000000001667ffffffffffffffff861690811790915591519182527f901f9de19b475adc8da4110434b8df940dce085afd05e2281c86807f3a899d299101610989565b33600081815260346020908152604080832073ffffffffffffffffffffffffffffffffffffffff8716845290915281205490919083811015612062576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602560248201527f45524332303a2064656372656173656420616c6c6f77616e63652062656c6f7760448201527f207a65726f00000000000000000000000000000000000000000000000000000060648201526084015b60405180910390fd5b610dd78286868403612a35565b6000336109a3818585612f03565b60cf818154811061208d57600080fd5b60009182526020909120015473ffffffffffffffffffffffffffffffffffffffff16905081565b606060cf80548060200260200160405190810160405280929190818152602001828054801561081857602002820191906000526020600020905b815473ffffffffffffffffffffffffffffffffffffffff1681526001909101906020018083116120ee575050505050905090565b73ffffffffffffffffffffffffffffffffffffffff8316600090815260ce60209081526040808320815160a081018352815481526001820154938101939093526002015467ffffffffffffffff81169183019190915260ff6801000000000000000082048116158015606085015269010000000000000000009092041615156080830152806121b2575080608001515b156121e9576040517fc1ab6dc100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60006121f7610e10426143e2565b600081815260d36020526040812054919250906122159087906143cf565b905060d254811115612253576040517f6d43d1ac00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600082815260d36020526040902081905561226e33876131b6565b33600090815260d160205260408120548791036122bb57633b9aca00846040015167ffffffffffffffff16826122a4919061441d565b6122ae91906143e2565b6122b890826143a3565b90505b6122dc73ffffffffffffffffffffffffffffffffffffffff89168783612be0565b979650505050505050565b83421115612351576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f45524332305065726d69743a206578706972656420646561646c696e650000006044820152606401612059565b60007f6e71edae12b1b97f4d1f60370fef10105fa2faae0126114a169c64845d6126c98888886123808c61341e565b60408051602081019690965273ffffffffffffffffffffffffffffffffffffffff94851690860152929091166060840152608083015260a082015260c0810186905260e00160405160208183030381529060405280519060200120905060006123e882613453565b905060006123f8828787876134bc565b90508973ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff161461248f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601e60248201527f45524332305065726d69743a20696e76616c6964207369676e617475726500006044820152606401612059565b61249a8a8a8a612a35565b50505050505050505050565b60cd546040517f521d4de900000000000000000000000000000000000000000000000000000000815233600482015273ffffffffffffffffffffffffffffffffffffffff9091169063521d4de990602401602060405180830381865afa158015612514573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906125389190614357565b61256e576040517f99e120bc00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff8116600090815260ce602052604090206002015468010000000000000000900460ff166125dc576040517fc1ab6dc100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff8116600081815260ce602090815260409182902060020180547fffffffffffffffffffffffffffffffffffffffffffff00ffffffffffffffffff811669010000000000000000009182900460ff16801592830291909117909255925192835292917ff7c93079dcbf699749d66345a351afab7d24219bb1d915c9f4fc4cf03f00d3979101610989565b60cd5473ffffffffffffffffffffffffffffffffffffffff1633146126cb576040517fb90cdbb100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60cd80547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83169081179091556040517f7dae230f18360d76a040c81f050aa14eb9d6dc7901b20fc5d855e2a20fe814d190600090a250565b73ffffffffffffffffffffffffffffffffffffffff163b151590565b600054610100900460ff16158080156127765750600054600160ff909116105b806127905750303b158015612790575060005460ff166001145b61281c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201527f647920696e697469616c697a65640000000000000000000000000000000000006064820152608401612059565b600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00166001179055801561287a57600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff166101001790555b3073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1663e9cbd8226040518163ffffffff1660e01b8152600401602060405180830381865afa1580156128dc573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061290091906144ca565b73ffffffffffffffffffffffffffffffffffffffff161461294d576040517f14bcf5c800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b612956846134e4565b61296084846135ba565b60cd80547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff84169081179091556040517f7dae230f18360d76a040c81f050aa14eb9d6dc7901b20fc5d855e2a20fe814d190600090a28015612a2f57600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15b50505050565b73ffffffffffffffffffffffffffffffffffffffff8316612ad7576040517f08c379a0000000000000000000000000000000000000000000000000000000008152602060048201526024808201527f45524332303a20617070726f76652066726f6d20746865207a65726f2061646460448201527f72657373000000000000000000000000000000000000000000000000000000006064820152608401612059565b73ffffffffffffffffffffffffffffffffffffffff8216612b7a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602260248201527f45524332303a20617070726f766520746f20746865207a65726f20616464726560448201527f73730000000000000000000000000000000000000000000000000000000000006064820152608401612059565b73ffffffffffffffffffffffffffffffffffffffff83811660008181526034602090815260408083209487168084529482529182902085905590518481527f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b9259101610af7565b60405173ffffffffffffffffffffffffffffffffffffffff831660248201526044810182905261082d9084907fa9059cbb00000000000000000000000000000000000000000000000000000000906064015b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff000000000000000000000000000000000000000000000000000000009093169290921790915261365b565b60405173ffffffffffffffffffffffffffffffffffffffff80851660248301528316604482015260648101829052612a2f9085907f23b872dd0000000000000000000000000000000000000000000000000000000090608401612c32565b73ffffffffffffffffffffffffffffffffffffffff8216612d8f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601f60248201527f45524332303a206d696e7420746f20746865207a65726f2061646472657373006044820152606401612059565b8060356000828254612da191906143cf565b909155505073ffffffffffffffffffffffffffffffffffffffff821660009081526033602052604081208054839290612ddb9084906143cf565b909155505060405181815273ffffffffffffffffffffffffffffffffffffffff8316906000907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef9060200160405180910390a35050565b73ffffffffffffffffffffffffffffffffffffffff8381166000908152603460209081526040808320938616835292905220547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8114612a2f5781811015612ef6576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f45524332303a20696e73756666696369656e7420616c6c6f77616e63650000006044820152606401612059565b612a2f8484848403612a35565b73ffffffffffffffffffffffffffffffffffffffff8316612fa6576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602560248201527f45524332303a207472616e736665722066726f6d20746865207a65726f20616460448201527f64726573730000000000000000000000000000000000000000000000000000006064820152608401612059565b73ffffffffffffffffffffffffffffffffffffffff8216613049576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602360248201527f45524332303a207472616e7366657220746f20746865207a65726f206164647260448201527f65737300000000000000000000000000000000000000000000000000000000006064820152608401612059565b73ffffffffffffffffffffffffffffffffffffffff8316600090815260336020526040902054818110156130ff576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f45524332303a207472616e7366657220616d6f756e742065786365656473206260448201527f616c616e636500000000000000000000000000000000000000000000000000006064820152608401612059565b73ffffffffffffffffffffffffffffffffffffffff8085166000908152603360205260408082208585039055918516815290812080548492906131439084906143cf565b925050819055508273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef846040516131a991815260200190565b60405180910390a3612a2f565b73ffffffffffffffffffffffffffffffffffffffff8216613259576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602160248201527f45524332303a206275726e2066726f6d20746865207a65726f2061646472657360448201527f73000000000000000000000000000000000000000000000000000000000000006064820152608401612059565b73ffffffffffffffffffffffffffffffffffffffff82166000908152603360205260409020548181101561330f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602260248201527f45524332303a206275726e20616d6f756e7420657863656564732062616c616e60448201527f63650000000000000000000000000000000000000000000000000000000000006064820152608401612059565b73ffffffffffffffffffffffffffffffffffffffff8316600090815260336020526040812083830390556035805484929061334b9084906143a3565b909155505060405182815260009073ffffffffffffffffffffffffffffffffffffffff8516907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef9060200160405180910390a3505050565b60006113e47f8b73c3c69bb8fe3d512ecc4cf759cc79239f7b179b0ffacaa9a75d522b39400f6133d260655490565b6066546040805160208101859052908101839052606081018290524660808201523060a082015260009060c0016040516020818303038152906040528051906020012090509392505050565b73ffffffffffffffffffffffffffffffffffffffff811660009081526099602052604090208054600181018255905b50919050565b60006109a96134606133a3565b836040517f19010000000000000000000000000000000000000000000000000000000000006020820152602281018390526042810182905260009060620160405160208183030381529060405280519060200120905092915050565b60008060006134cd87878787613767565b915091506134da8161387f565b5095945050505050565b600054610100900460ff1661357b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201527f6e697469616c697a696e670000000000000000000000000000000000000000006064820152608401612059565b611cb3816040518060400160405280600181526020017f3100000000000000000000000000000000000000000000000000000000000000815250613ad3565b600054610100900460ff16613651576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201527f6e697469616c697a696e670000000000000000000000000000000000000000006064820152608401612059565b610e358282613b84565b60006136bd826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c65648152508573ffffffffffffffffffffffffffffffffffffffff16613c349092919063ffffffff16565b80519091501561082d57808060200190518101906136db9190614357565b61082d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e60448201527f6f742073756363656564000000000000000000000000000000000000000000006064820152608401612059565b6000807f7fffffffffffffffffffffffffffffff5d576e7357a4501ddfe92f46681b20a083111561379e5750600090506003613876565b8460ff16601b141580156137b657508460ff16601c14155b156137c75750600090506004613876565b6040805160008082526020820180845289905260ff881692820192909252606081018690526080810185905260019060a0016020604051602081039080840390855afa15801561381b573d6000803e3d6000fd5b50506040517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0015191505073ffffffffffffffffffffffffffffffffffffffff811661386f57600060019250925050613876565b9150600090505b94509492505050565b6000816004811115613893576138936144e7565b0361389b5750565b60018160048111156138af576138af6144e7565b03613916576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601860248201527f45434453413a20696e76616c6964207369676e617475726500000000000000006044820152606401612059565b600281600481111561392a5761392a6144e7565b03613991576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601f60248201527f45434453413a20696e76616c6964207369676e6174757265206c656e677468006044820152606401612059565b60038160048111156139a5576139a56144e7565b03613a32576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602260248201527f45434453413a20696e76616c6964207369676e6174757265202773272076616c60448201527f75650000000000000000000000000000000000000000000000000000000000006064820152608401612059565b6004816004811115613a4657613a466144e7565b03611cb3576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602260248201527f45434453413a20696e76616c6964207369676e6174757265202776272076616c60448201527f75650000000000000000000000000000000000000000000000000000000000006064820152608401612059565b600054610100900460ff16613b6a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201527f6e697469616c697a696e670000000000000000000000000000000000000000006064820152608401612059565b815160209283012081519190920120606591909155606655565b600054610100900460ff16613c1b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201527f6e697469616c697a696e670000000000000000000000000000000000000000006064820152608401612059565b6036613c278382614564565b50603761082d8282614564565b6060613c438484600085613c4b565b949350505050565b606082471015613cdd576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f60448201527f722063616c6c00000000000000000000000000000000000000000000000000006064820152608401612059565b73ffffffffffffffffffffffffffffffffffffffff85163b613d5b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006044820152606401612059565b6000808673ffffffffffffffffffffffffffffffffffffffff168587604051613d84919061467e565b60006040518083038185875af1925050503d8060008114613dc1576040519150601f19603f3d011682016040523d82523d6000602084013e613dc6565b606091505b50915091506122dc82828660608315613de0575081610db7565b825115613df05782518084602001fd5b816040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016120599190613e48565b60005b83811015613e3f578181015183820152602001613e27565b50506000910152565b6020815260008251806020840152613e67816040850160208701613e24565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169190910160400192915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b600082601f830112613ed957600080fd5b813567ffffffffffffffff80821115613ef457613ef4613e99565b604051601f83017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0908116603f01168101908282118183101715613f3a57613f3a613e99565b81604052838152866020858801011115613f5357600080fd5b836020870160208301376000602085830101528094505050505092915050565b73ffffffffffffffffffffffffffffffffffffffff81168114611cb357600080fd5b600080600060608486031215613faa57600080fd5b833567ffffffffffffffff80821115613fc257600080fd5b613fce87838801613ec8565b94506020860135915080821115613fe457600080fd5b50613ff186828701613ec8565b925050604084013561400281613f73565b809150509250925092565b60006020828403121561401f57600080fd5b8135610db781613f73565b6000806040838503121561403d57600080fd5b823561404881613f73565b946020939093013593505050565b60008060006060848603121561406b57600080fd5b833561407681613f73565b9250602084013561408681613f73565b929592945050506040919091013590565b6000806000606084860312156140ac57600080fd5b83356140b781613f73565b925060208401359150604084013561400281613f73565b600080604083850312156140e157600080fd5b8235915060208301356140f381613f73565b809150509250929050565b60008060006060848603121561411357600080fd5b83359250602084013561412581613f73565b9150604084013561400281613f73565b60006020828403121561414757600080fd5b5035919050565b803567ffffffffffffffff8116811461416657600080fd5b919050565b8015158114611cb357600080fd5b600080600080600060a0868803121561419157600080fd5b853561419c81613f73565b945060208601359350604086013592506141b86060870161414e565b915060808601356141c88161416b565b809150509295509295909350565b600080604083850312156141e957600080fd5b82356141f481613f73565b91506142026020840161414e565b90509250929050565b6020808252825182820181905260009190848201906040850190845b8181101561425957835173ffffffffffffffffffffffffffffffffffffffff1683529284019291840191600101614227565b50909695505050505050565b600080600080600080600060e0888a03121561428057600080fd5b873561428b81613f73565b9650602088013561429b81613f73565b95506040880135945060608801359350608088013560ff811681146142bf57600080fd5b9699959850939692959460a0840135945060c09093013592915050565b600080604083850312156142ef57600080fd5b82356142fa81613f73565b915060208301356140f381613f73565b600181811c9082168061431e57607f821691505b60208210810361344d577f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b60006020828403121561436957600080fd5b8151610db78161416b565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b818103818111156109a9576109a9614374565b6000602082840312156143c857600080fd5b5051919050565b808201808211156109a9576109a9614374565b600082614418577f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b500490565b80820281158282048414176109a9576109a9614374565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff820361449457614494614374565b5060010190565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603160045260246000fd5b6000602082840312156144dc57600080fd5b8151610db781613f73565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b601f82111561082d57600081815260208120601f850160051c8101602086101561453d5750805b601f850160051c820191505b8181101561455c57828155600101614549565b505050505050565b815167ffffffffffffffff81111561457e5761457e613e99565b6145928161458c845461430a565b84614516565b602080601f8311600181146145e557600084156145af5750858301515b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600386901b1c1916600185901b17855561455c565b6000858152602081207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08616915b8281101561463257888601518255948401946001909101908401614613565b508582101561466e57878501517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600388901b60f8161c191681555b5050505050600190811b01905550565b60008251614690818460208701613e24565b919091019291505056fea2646970667358221220f2eb02bac1667a72be85ab617a5b5aa3d8f7a9b09b4d1fde9756b7a5636daf2164736f6c63430008110033", "devdoc": { - "author": "Angle Core Team", - "details": "This contract supports bridge tokens having a minting right on the stablecoin (also referred to as the canonical or the native token)References: - FRAX implementation: https://polygonscan.com/address/0x45c32fA6DF82ead1e2EF74d17b76547EDdFaFF89#code - QiDAO implementation: https://snowtrace.io/address/0x5c49b268c9841AFF1Cc3B0a418ff5c3442eE3F3b#code", + "author": "Angle Labs, Inc.", + "details": "This contract supports bridge tokens having a minting right on the stablecoin (also referred to as the canonical or the native token)", "kind": "dev", "methods": { "DOMAIN_SEPARATOR()": { @@ -1249,7 +1276,7 @@ "details": "See {IERC20-allowance}." }, "approve(address,uint256)": { - "details": "See {IERC20-approve}. Requirements: - `spender` cannot be the zero address." + "details": "See {IERC20-approve}. NOTE: If `amount` is the maximum `uint256`, the allowance is not updated on `transferFrom`. This is semantically equivalent to an infinite approval. Requirements: - `spender` cannot be the zero address." }, "balanceOf(address)": { "details": "See {IERC20-balanceOf}." @@ -1293,14 +1320,6 @@ "increaseAllowance(address,uint256)": { "details": "Atomically increases the allowance granted to `spender` by the caller. This is an alternative to {approve} that can be used as a mitigation for problems described in {IERC20-approve}. Emits an {Approval} event indicating the updated allowance. Requirements: - `spender` cannot be the zero address." }, - "initialize(string,string,address)": { - "details": "By default, agTokens are ERC-20 tokens with 18 decimals", - "params": { - "_treasury": "Reference to the `Treasury` contract associated to this agToken", - "name_": "Name of the token", - "symbol_": "Symbol of the token" - } - }, "mint(address,uint256)": { "details": "The contracts allowed to issue agTokens are the `StableMaster` contract, `VaultManager` contracts associated to this stablecoin as well as the flash loan module (if activated) and potentially contracts whitelisted by governance", "params": { @@ -1365,10 +1384,10 @@ "details": "See {IERC20-totalSupply}." }, "transfer(address,uint256)": { - "details": "See {IERC20-transfer}. Requirements: - `recipient` cannot be the zero address. - the caller must have a balance of at least `amount`." + "details": "See {IERC20-transfer}. Requirements: - `to` cannot be the zero address. - the caller must have a balance of at least `amount`." }, "transferFrom(address,address,uint256)": { - "details": "See {IERC20-transferFrom}. Emits an {Approval} event indicating the updated allowance. This is not required by the EIP. See the note at the beginning of {ERC20}. Requirements: - `sender` and `recipient` cannot be the zero address. - `sender` must have a balance of at least `amount`. - the caller must have allowance for ``sender``'s tokens of at least `amount`." + "details": "See {IERC20-transferFrom}. Emits an {Approval} event indicating the updated allowance. This is not required by the EIP. See the note at the beginning of {ERC20}. NOTE: Does not update the allowance if the current allowance is the maximum `uint256`. Requirements: - `from` and `to` cannot be the zero address. - `from` must have a balance of at least `amount`. - the caller must have allowance for ``from``'s tokens of at least `amount`." } }, "title": "AgTokenSideChainMultiBridge", @@ -1402,7 +1421,7 @@ "notice": "Burns `amount` tokens from a `burner` address" }, "burnStablecoin(uint256)": { - "notice": "Allows anyone to burn agToken without redeeming collateral back" + "notice": "Allows anyone to burn stablecoins" }, "chainTotalHourlyLimit()": { "notice": "Limit to the amount of tokens that can be sent from that chain to another chain" @@ -1477,15 +1496,15 @@ "storageLayout": { "storage": [ { - "astId": 772, + "astId": 770, "contract": "contracts/agToken/AgTokenSideChainMultiBridge.sol:AgTokenSideChainMultiBridge", "label": "_initialized", "offset": 0, "slot": "0", - "type": "t_bool" + "type": "t_uint8" }, { - "astId": 775, + "astId": 773, "contract": "contracts/agToken/AgTokenSideChainMultiBridge.sol:AgTokenSideChainMultiBridge", "label": "_initializing", "offset": 1, @@ -1493,7 +1512,7 @@ "type": "t_bool" }, { - "astId": 2592, + "astId": 2486, "contract": "contracts/agToken/AgTokenSideChainMultiBridge.sol:AgTokenSideChainMultiBridge", "label": "__gap", "offset": 0, @@ -1501,7 +1520,7 @@ "type": "t_array(t_uint256)50_storage" }, { - "astId": 1029, + "astId": 1119, "contract": "contracts/agToken/AgTokenSideChainMultiBridge.sol:AgTokenSideChainMultiBridge", "label": "_balances", "offset": 0, @@ -1509,7 +1528,7 @@ "type": "t_mapping(t_address,t_uint256)" }, { - "astId": 1035, + "astId": 1125, "contract": "contracts/agToken/AgTokenSideChainMultiBridge.sol:AgTokenSideChainMultiBridge", "label": "_allowances", "offset": 0, @@ -1517,7 +1536,7 @@ "type": "t_mapping(t_address,t_mapping(t_address,t_uint256))" }, { - "astId": 1037, + "astId": 1127, "contract": "contracts/agToken/AgTokenSideChainMultiBridge.sol:AgTokenSideChainMultiBridge", "label": "_totalSupply", "offset": 0, @@ -1525,7 +1544,7 @@ "type": "t_uint256" }, { - "astId": 1039, + "astId": 1129, "contract": "contracts/agToken/AgTokenSideChainMultiBridge.sol:AgTokenSideChainMultiBridge", "label": "_name", "offset": 0, @@ -1533,7 +1552,7 @@ "type": "t_string_storage" }, { - "astId": 1041, + "astId": 1131, "contract": "contracts/agToken/AgTokenSideChainMultiBridge.sol:AgTokenSideChainMultiBridge", "label": "_symbol", "offset": 0, @@ -1541,7 +1560,7 @@ "type": "t_string_storage" }, { - "astId": 1582, + "astId": 1710, "contract": "contracts/agToken/AgTokenSideChainMultiBridge.sol:AgTokenSideChainMultiBridge", "label": "__gap", "offset": 0, @@ -1549,7 +1568,7 @@ "type": "t_array(t_uint256)45_storage" }, { - "astId": 3269, + "astId": 3203, "contract": "contracts/agToken/AgTokenSideChainMultiBridge.sol:AgTokenSideChainMultiBridge", "label": "_HASHED_NAME", "offset": 0, @@ -1557,7 +1576,7 @@ "type": "t_bytes32" }, { - "astId": 3271, + "astId": 3205, "contract": "contracts/agToken/AgTokenSideChainMultiBridge.sol:AgTokenSideChainMultiBridge", "label": "_HASHED_VERSION", "offset": 0, @@ -1565,7 +1584,7 @@ "type": "t_bytes32" }, { - "astId": 3408, + "astId": 3343, "contract": "contracts/agToken/AgTokenSideChainMultiBridge.sol:AgTokenSideChainMultiBridge", "label": "__gap", "offset": 0, @@ -1573,23 +1592,23 @@ "type": "t_array(t_uint256)50_storage" }, { - "astId": 1712, + "astId": 1840, "contract": "contracts/agToken/AgTokenSideChainMultiBridge.sol:AgTokenSideChainMultiBridge", "label": "_nonces", "offset": 0, "slot": "153", - "type": "t_mapping(t_address,t_struct(Counter)2599_storage)" + "type": "t_mapping(t_address,t_struct(Counter)2493_storage)" }, { - "astId": 1714, + "astId": 1848, "contract": "contracts/agToken/AgTokenSideChainMultiBridge.sol:AgTokenSideChainMultiBridge", - "label": "_PERMIT_TYPEHASH", + "label": "_PERMIT_TYPEHASH_DEPRECATED_SLOT", "offset": 0, "slot": "154", "type": "t_bytes32" }, { - "astId": 1882, + "astId": 2004, "contract": "contracts/agToken/AgTokenSideChainMultiBridge.sol:AgTokenSideChainMultiBridge", "label": "__gap", "offset": 0, @@ -1597,7 +1616,7 @@ "type": "t_array(t_uint256)49_storage" }, { - "astId": 8835, + "astId": 7427, "contract": "contracts/agToken/AgTokenSideChainMultiBridge.sol:AgTokenSideChainMultiBridge", "label": "isMinter", "offset": 0, @@ -1605,7 +1624,7 @@ "type": "t_mapping(t_address,t_bool)" }, { - "astId": 8838, + "astId": 7430, "contract": "contracts/agToken/AgTokenSideChainMultiBridge.sol:AgTokenSideChainMultiBridge", "label": "treasury", "offset": 0, @@ -1613,15 +1632,15 @@ "type": "t_address" }, { - "astId": 7979, + "astId": 7739, "contract": "contracts/agToken/AgTokenSideChainMultiBridge.sol:AgTokenSideChainMultiBridge", "label": "bridges", "offset": 0, "slot": "206", - "type": "t_mapping(t_address,t_struct(BridgeDetails)7973_storage)" + "type": "t_mapping(t_address,t_struct(BridgeDetails)7733_storage)" }, { - "astId": 7983, + "astId": 7743, "contract": "contracts/agToken/AgTokenSideChainMultiBridge.sol:AgTokenSideChainMultiBridge", "label": "bridgeTokensList", "offset": 0, @@ -1629,7 +1648,7 @@ "type": "t_array(t_address)dyn_storage" }, { - "astId": 7990, + "astId": 7750, "contract": "contracts/agToken/AgTokenSideChainMultiBridge.sol:AgTokenSideChainMultiBridge", "label": "usage", "offset": 0, @@ -1637,7 +1656,7 @@ "type": "t_mapping(t_address,t_mapping(t_uint256,t_uint256))" }, { - "astId": 7995, + "astId": 7755, "contract": "contracts/agToken/AgTokenSideChainMultiBridge.sol:AgTokenSideChainMultiBridge", "label": "isFeeExempt", "offset": 0, @@ -1645,7 +1664,7 @@ "type": "t_mapping(t_address,t_uint256)" }, { - "astId": 7998, + "astId": 7758, "contract": "contracts/agToken/AgTokenSideChainMultiBridge.sol:AgTokenSideChainMultiBridge", "label": "chainTotalHourlyLimit", "offset": 0, @@ -1653,7 +1672,7 @@ "type": "t_uint256" }, { - "astId": 8003, + "astId": 7763, "contract": "contracts/agToken/AgTokenSideChainMultiBridge.sol:AgTokenSideChainMultiBridge", "label": "chainTotalUsage", "offset": 0, @@ -1722,19 +1741,19 @@ "numberOfBytes": "32", "value": "t_mapping(t_uint256,t_uint256)" }, - "t_mapping(t_address,t_struct(BridgeDetails)7973_storage)": { + "t_mapping(t_address,t_struct(BridgeDetails)7733_storage)": { "encoding": "mapping", "key": "t_address", "label": "mapping(address => struct AgTokenSideChainMultiBridge.BridgeDetails)", "numberOfBytes": "32", - "value": "t_struct(BridgeDetails)7973_storage" + "value": "t_struct(BridgeDetails)7733_storage" }, - "t_mapping(t_address,t_struct(Counter)2599_storage)": { + "t_mapping(t_address,t_struct(Counter)2493_storage)": { "encoding": "mapping", "key": "t_address", "label": "mapping(address => struct CountersUpgradeable.Counter)", "numberOfBytes": "32", - "value": "t_struct(Counter)2599_storage" + "value": "t_struct(Counter)2493_storage" }, "t_mapping(t_address,t_uint256)": { "encoding": "mapping", @@ -1755,12 +1774,12 @@ "label": "string", "numberOfBytes": "32" }, - "t_struct(BridgeDetails)7973_storage": { + "t_struct(BridgeDetails)7733_storage": { "encoding": "inplace", "label": "struct AgTokenSideChainMultiBridge.BridgeDetails", "members": [ { - "astId": 7964, + "astId": 7724, "contract": "contracts/agToken/AgTokenSideChainMultiBridge.sol:AgTokenSideChainMultiBridge", "label": "limit", "offset": 0, @@ -1768,7 +1787,7 @@ "type": "t_uint256" }, { - "astId": 7966, + "astId": 7726, "contract": "contracts/agToken/AgTokenSideChainMultiBridge.sol:AgTokenSideChainMultiBridge", "label": "hourlyLimit", "offset": 0, @@ -1776,7 +1795,7 @@ "type": "t_uint256" }, { - "astId": 7968, + "astId": 7728, "contract": "contracts/agToken/AgTokenSideChainMultiBridge.sol:AgTokenSideChainMultiBridge", "label": "fee", "offset": 0, @@ -1784,7 +1803,7 @@ "type": "t_uint64" }, { - "astId": 7970, + "astId": 7730, "contract": "contracts/agToken/AgTokenSideChainMultiBridge.sol:AgTokenSideChainMultiBridge", "label": "allowed", "offset": 8, @@ -1792,7 +1811,7 @@ "type": "t_bool" }, { - "astId": 7972, + "astId": 7732, "contract": "contracts/agToken/AgTokenSideChainMultiBridge.sol:AgTokenSideChainMultiBridge", "label": "paused", "offset": 9, @@ -1802,12 +1821,12 @@ ], "numberOfBytes": "96" }, - "t_struct(Counter)2599_storage": { + "t_struct(Counter)2493_storage": { "encoding": "inplace", "label": "struct CountersUpgradeable.Counter", "members": [ { - "astId": 2598, + "astId": 2492, "contract": "contracts/agToken/AgTokenSideChainMultiBridge.sol:AgTokenSideChainMultiBridge", "label": "_value", "offset": 0, @@ -1826,6 +1845,11 @@ "encoding": "inplace", "label": "uint64", "numberOfBytes": "8" + }, + "t_uint8": { + "encoding": "inplace", + "label": "uint8", + "numberOfBytes": "1" } } } diff --git a/deployments/optimism/CoreBorrowTest.json b/deployments/optimism/CoreBorrowTest.json new file mode 100644 index 00000000..eb2bb688 --- /dev/null +++ b/deployments/optimism/CoreBorrowTest.json @@ -0,0 +1,325 @@ +{ + "address": "0xe324d92516be618afd776c8c87386196e76d50ac", + "abi": [ + { + "inputs": [ + { + "internalType": "address", + "name": "_logic", + "type": "address" + }, + { + "internalType": "address", + "name": "admin_", + "type": "address" + }, + { + "internalType": "bytes", + "name": "_data", + "type": "bytes" + } + ], + "stateMutability": "payable", + "type": "constructor" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "previousAdmin", + "type": "address" + }, + { + "indexed": false, + "internalType": "address", + "name": "newAdmin", + "type": "address" + } + ], + "name": "AdminChanged", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "beacon", + "type": "address" + } + ], + "name": "BeaconUpgraded", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "implementation", + "type": "address" + } + ], + "name": "Upgraded", + "type": "event" + }, + { + "stateMutability": "payable", + "type": "fallback" + }, + { + "inputs": [], + "name": "admin", + "outputs": [ + { + "internalType": "address", + "name": "admin_", + "type": "address" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "newAdmin", + "type": "address" + } + ], + "name": "changeAdmin", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "implementation", + "outputs": [ + { + "internalType": "address", + "name": "implementation_", + "type": "address" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "newImplementation", + "type": "address" + } + ], + "name": "upgradeTo", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "newImplementation", + "type": "address" + }, + { + "internalType": "bytes", + "name": "data", + "type": "bytes" + } + ], + "name": "upgradeToAndCall", + "outputs": [], + "stateMutability": "payable", + "type": "function" + }, + { + "stateMutability": "payable", + "type": "receive" + } + ], + "transactionHash": "0x2033f9a14b9b424066275adee1d4cbcf3dbb7638dccdf37cfd453154302e4ed3", + "receipt": { + "to": null, + "from": "0xfdA462548Ce04282f4B6D6619823a7C64Fdc0185", + "contractAddress": "0xe324d92516be618afd776c8c87386196e76d50ac", + "transactionIndex": 7, + "gasUsed": "1037362", + "logsBloom": "0x00001004000040000800000400000000480000000000000000000000200000000000000000000000002000000000000000000000000000000000000000000000000000000020000000000000000002000009000000000000000000000000000000000000020000400200000000000800000000800000000000000000000000000000000000000000000000000000000000000003000000400000000000804000000000000000000000000000000000000000000000000040001000000000001000000020020000000000008000000000000800000400000100000000000020000000800000000000000000000000000400000000000000000000000000040000", + "blockHash": "0xb5298c118ea4fb0a4f479fd26567371ed464d4e7845eff61590bf69302977df4", + "transactionHash": "0x2033f9a14b9b424066275adee1d4cbcf3dbb7638dccdf37cfd453154302e4ed3", + "logs": [ + { + "transactionIndex": 7, + "blockNumber": 114643674, + "transactionHash": "0x2033f9a14b9b424066275adee1d4cbcf3dbb7638dccdf37cfd453154302e4ed3", + "address": "0xe324d92516be618afd776c8c87386196e76d50ac", + "topics": [ + "0xbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b", + "0x000000000000000000000000a61beb4a3d02decb01039e378237032b351125b4" + ], + "data": "0x", + "logIndex": 4, + "blockHash": "0xb5298c118ea4fb0a4f479fd26567371ed464d4e7845eff61590bf69302977df4" + }, + { + "transactionIndex": 7, + "blockNumber": 114643674, + "transactionHash": "0x2033f9a14b9b424066275adee1d4cbcf3dbb7638dccdf37cfd453154302e4ed3", + "address": "0xe324d92516be618afd776c8c87386196e76d50ac", + "topics": [ + "0x2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d", + "0x7935bd0ae54bc31f548c14dba4d37c5c64b3f8ca900cb468fb8abd54d5894f55", + "0x000000000000000000000000fda462548ce04282f4b6d6619823a7c64fdc0185", + "0x000000000000000000000000fda462548ce04282f4b6d6619823a7c64fdc0185" + ], + "data": "0x", + "logIndex": 5, + "blockHash": "0xb5298c118ea4fb0a4f479fd26567371ed464d4e7845eff61590bf69302977df4" + }, + { + "transactionIndex": 7, + "blockNumber": 114643674, + "transactionHash": "0x2033f9a14b9b424066275adee1d4cbcf3dbb7638dccdf37cfd453154302e4ed3", + "address": "0xe324d92516be618afd776c8c87386196e76d50ac", + "topics": [ + "0x2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d", + "0x55435dd261a4b9b3364963f7738a7a662ad9c84396d64be3365284bb7f0a5041", + "0x000000000000000000000000d245678e417aee2d91763f6f4efe570ff52fd080", + "0x000000000000000000000000fda462548ce04282f4b6d6619823a7c64fdc0185" + ], + "data": "0x", + "logIndex": 6, + "blockHash": "0xb5298c118ea4fb0a4f479fd26567371ed464d4e7845eff61590bf69302977df4" + }, + { + "transactionIndex": 7, + "blockNumber": 114643674, + "transactionHash": "0x2033f9a14b9b424066275adee1d4cbcf3dbb7638dccdf37cfd453154302e4ed3", + "address": "0xe324d92516be618afd776c8c87386196e76d50ac", + "topics": [ + "0x2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d", + "0x55435dd261a4b9b3364963f7738a7a662ad9c84396d64be3365284bb7f0a5041", + "0x000000000000000000000000fda462548ce04282f4b6d6619823a7c64fdc0185", + "0x000000000000000000000000fda462548ce04282f4b6d6619823a7c64fdc0185" + ], + "data": "0x", + "logIndex": 7, + "blockHash": "0xb5298c118ea4fb0a4f479fd26567371ed464d4e7845eff61590bf69302977df4" + }, + { + "transactionIndex": 7, + "blockNumber": 114643674, + "transactionHash": "0x2033f9a14b9b424066275adee1d4cbcf3dbb7638dccdf37cfd453154302e4ed3", + "address": "0xe324d92516be618afd776c8c87386196e76d50ac", + "topics": [ + "0xbd79b86ffe0ab8e8776151514217cd7cacd52c909f66475c3af44e129f0b00ff", + "0x55435dd261a4b9b3364963f7738a7a662ad9c84396d64be3365284bb7f0a5041", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x7935bd0ae54bc31f548c14dba4d37c5c64b3f8ca900cb468fb8abd54d5894f55" + ], + "data": "0x", + "logIndex": 8, + "blockHash": "0xb5298c118ea4fb0a4f479fd26567371ed464d4e7845eff61590bf69302977df4" + }, + { + "transactionIndex": 7, + "blockNumber": 114643674, + "transactionHash": "0x2033f9a14b9b424066275adee1d4cbcf3dbb7638dccdf37cfd453154302e4ed3", + "address": "0xe324d92516be618afd776c8c87386196e76d50ac", + "topics": [ + "0xbd79b86ffe0ab8e8776151514217cd7cacd52c909f66475c3af44e129f0b00ff", + "0x7935bd0ae54bc31f548c14dba4d37c5c64b3f8ca900cb468fb8abd54d5894f55", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x7935bd0ae54bc31f548c14dba4d37c5c64b3f8ca900cb468fb8abd54d5894f55" + ], + "data": "0x", + "logIndex": 9, + "blockHash": "0xb5298c118ea4fb0a4f479fd26567371ed464d4e7845eff61590bf69302977df4" + }, + { + "transactionIndex": 7, + "blockNumber": 114643674, + "transactionHash": "0x2033f9a14b9b424066275adee1d4cbcf3dbb7638dccdf37cfd453154302e4ed3", + "address": "0xe324d92516be618afd776c8c87386196e76d50ac", + "topics": [ + "0xbd79b86ffe0ab8e8776151514217cd7cacd52c909f66475c3af44e129f0b00ff", + "0x0ae0130c6b34f32239dfe5e419a3fbd7546b44e99783257f2d93526d5a936d46", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x7935bd0ae54bc31f548c14dba4d37c5c64b3f8ca900cb468fb8abd54d5894f55" + ], + "data": "0x", + "logIndex": 10, + "blockHash": "0xb5298c118ea4fb0a4f479fd26567371ed464d4e7845eff61590bf69302977df4" + }, + { + "transactionIndex": 7, + "blockNumber": 114643674, + "transactionHash": "0x2033f9a14b9b424066275adee1d4cbcf3dbb7638dccdf37cfd453154302e4ed3", + "address": "0xe324d92516be618afd776c8c87386196e76d50ac", + "topics": [ + "0x7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f" + ], + "data": "0x0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000c16b81af351ba9e64c1a069e3ab18c244a1e3049", + "logIndex": 11, + "blockHash": "0xb5298c118ea4fb0a4f479fd26567371ed464d4e7845eff61590bf69302977df4" + } + ], + "blockNumber": 114643674, + "cumulativeGasUsed": "1324276", + "status": 1, + "byzantium": true + }, + "args": [ + "0xA61BeB4A3d02decb01039e378237032B351125B4", + "0xC16B81Af351BA9e64C1a069E3Ab18c244A1E3049", + "0x485cc955000000000000000000000000fda462548ce04282f4b6d6619823a7c64fdc0185000000000000000000000000d245678e417aee2d91763f6f4efe570ff52fd080" + ], + "numDeployments": 1, + "solcInputHash": "871924e0c138825a2736b76def8fef8d", + "metadata": "{\"compiler\":{\"version\":\"0.8.17+commit.8df45f5f\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_logic\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"admin_\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"_data\",\"type\":\"bytes\"}],\"stateMutability\":\"payable\",\"type\":\"constructor\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"previousAdmin\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"newAdmin\",\"type\":\"address\"}],\"name\":\"AdminChanged\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"beacon\",\"type\":\"address\"}],\"name\":\"BeaconUpgraded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"implementation\",\"type\":\"address\"}],\"name\":\"Upgraded\",\"type\":\"event\"},{\"stateMutability\":\"payable\",\"type\":\"fallback\"},{\"inputs\":[],\"name\":\"admin\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"admin_\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newAdmin\",\"type\":\"address\"}],\"name\":\"changeAdmin\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"implementation\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"implementation_\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newImplementation\",\"type\":\"address\"}],\"name\":\"upgradeTo\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newImplementation\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"}],\"name\":\"upgradeToAndCall\",\"outputs\":[],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"stateMutability\":\"payable\",\"type\":\"receive\"}],\"devdoc\":{\"details\":\"This contract implements a proxy that is upgradeable by an admin. It is fully forked from OpenZeppelin `TransparentUpgradeableProxy` To avoid https://medium.com/nomic-labs-blog/malicious-backdoors-in-ethereum-proxies-62629adf3357[proxy selector clashing], which can potentially be used in an attack, this contract uses the https://blog.openzeppelin.com/the-transparent-proxy-pattern/[transparent proxy pattern]. This pattern implies two things that go hand in hand: 1. If any account other than the admin calls the proxy, the call will be forwarded to the implementation, even if that call matches one of the admin functions exposed by the proxy itself. 2. If the admin calls the proxy, it can access the admin functions, but its calls will never be forwarded to the implementation. If the admin tries to call a function on the implementation it will fail with an error that says \\\"admin cannot fallback to proxy target\\\". These properties mean that the admin account can only be used for admin actions like upgrading the proxy or changing the admin, so it's best if it's a dedicated account that is not used for anything else. This will avoid headaches due to sudden errors when trying to call a function from the proxy implementation. Our recommendation is for the dedicated account to be an instance of the {ProxyAdmin} contract. If set up this way, you should think of the `ProxyAdmin` instance as the real administrative interface of your proxy.\",\"kind\":\"dev\",\"methods\":{\"admin()\":{\"details\":\"Returns the current admin. NOTE: Only the admin can call this function. See {ProxyAdmin-getProxyAdmin}. TIP: To get this value clients can read directly from the storage slot shown below (specified by EIP1967) using the https://eth.wiki/json-rpc/API#eth_getstorageat[`eth_getStorageAt`] RPC call. `0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103`\"},\"changeAdmin(address)\":{\"details\":\"Changes the admin of the proxy. Emits an {AdminChanged} event. NOTE: Only the admin can call this function. See {ProxyAdmin-changeProxyAdmin}.\"},\"constructor\":{\"details\":\"Initializes an upgradeable proxy managed by `_admin`, backed by the implementation at `_logic`, and optionally initialized with `_data` as explained in {ERC1967Proxy-constructor}.\"},\"implementation()\":{\"details\":\"Returns the current implementation. NOTE: Only the admin can call this function. See {ProxyAdmin-getProxyImplementation}. TIP: To get this value clients can read directly from the storage slot shown below (specified by EIP1967) using the https://eth.wiki/json-rpc/API#eth_getstorageat[`eth_getStorageAt`] RPC call. `0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc`\"},\"upgradeTo(address)\":{\"details\":\"Upgrade the implementation of the proxy. NOTE: Only the admin can call this function. See {ProxyAdmin-upgrade}.\"},\"upgradeToAndCall(address,bytes)\":{\"details\":\"Upgrade the implementation of the proxy, and then call a function from the new implementation as specified by `data`, which should be an encoded function call. This is useful to initialize new storage variables in the proxied contract. NOTE: Only the admin can call this function. See {ProxyAdmin-upgradeAndCall}.\"}},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/external/TransparentUpgradeableProxy.sol\":\"TransparentUpgradeableProxy\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":1000000},\"remappings\":[]},\"sources\":{\"@openzeppelin/contracts/interfaces/draft-IERC1822.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.5.0) (interfaces/draft-IERC1822.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev ERC1822: Universal Upgradeable Proxy Standard (UUPS) documents a method for upgradeability through a simplified\\n * proxy whose upgrades are fully controlled by the current implementation.\\n */\\ninterface IERC1822Proxiable {\\n /**\\n * @dev Returns the storage slot that the proxiable contract assumes is being used to store the implementation\\n * address.\\n *\\n * IMPORTANT: A proxy pointing at a proxiable contract should not be considered proxiable itself, because this risks\\n * bricking a proxy that upgrades to it, by delegating to itself until out of gas. Thus it is critical that this\\n * function revert if invoked through a proxy.\\n */\\n function proxiableUUID() external view returns (bytes32);\\n}\\n\",\"keccak256\":\"0x1d4afe6cb24200cc4545eed814ecf5847277dfe5d613a1707aad5fceecebcfff\",\"license\":\"MIT\"},\"@openzeppelin/contracts/proxy/ERC1967/ERC1967Proxy.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.7.0) (proxy/ERC1967/ERC1967Proxy.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../Proxy.sol\\\";\\nimport \\\"./ERC1967Upgrade.sol\\\";\\n\\n/**\\n * @dev This contract implements an upgradeable proxy. It is upgradeable because calls are delegated to an\\n * implementation address that can be changed. This address is stored in storage in the location specified by\\n * https://eips.ethereum.org/EIPS/eip-1967[EIP1967], so that it doesn't conflict with the storage layout of the\\n * implementation behind the proxy.\\n */\\ncontract ERC1967Proxy is Proxy, ERC1967Upgrade {\\n /**\\n * @dev Initializes the upgradeable proxy with an initial implementation specified by `_logic`.\\n *\\n * If `_data` is nonempty, it's used as data in a delegate call to `_logic`. This will typically be an encoded\\n * function call, and allows initializing the storage of the proxy like a Solidity constructor.\\n */\\n constructor(address _logic, bytes memory _data) payable {\\n _upgradeToAndCall(_logic, _data, false);\\n }\\n\\n /**\\n * @dev Returns the current implementation address.\\n */\\n function _implementation() internal view virtual override returns (address impl) {\\n return ERC1967Upgrade._getImplementation();\\n }\\n}\\n\",\"keccak256\":\"0xa2b22da3032e50b55f95ec1d13336102d675f341167aa76db571ef7f8bb7975d\",\"license\":\"MIT\"},\"@openzeppelin/contracts/proxy/ERC1967/ERC1967Upgrade.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.5.0) (proxy/ERC1967/ERC1967Upgrade.sol)\\n\\npragma solidity ^0.8.2;\\n\\nimport \\\"../beacon/IBeacon.sol\\\";\\nimport \\\"../../interfaces/draft-IERC1822.sol\\\";\\nimport \\\"../../utils/Address.sol\\\";\\nimport \\\"../../utils/StorageSlot.sol\\\";\\n\\n/**\\n * @dev This abstract contract provides getters and event emitting update functions for\\n * https://eips.ethereum.org/EIPS/eip-1967[EIP1967] slots.\\n *\\n * _Available since v4.1._\\n *\\n * @custom:oz-upgrades-unsafe-allow delegatecall\\n */\\nabstract contract ERC1967Upgrade {\\n // This is the keccak-256 hash of \\\"eip1967.proxy.rollback\\\" subtracted by 1\\n bytes32 private constant _ROLLBACK_SLOT = 0x4910fdfa16fed3260ed0e7147f7cc6da11a60208b5b9406d12a635614ffd9143;\\n\\n /**\\n * @dev Storage slot with the address of the current implementation.\\n * This is the keccak-256 hash of \\\"eip1967.proxy.implementation\\\" subtracted by 1, and is\\n * validated in the constructor.\\n */\\n bytes32 internal constant _IMPLEMENTATION_SLOT = 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc;\\n\\n /**\\n * @dev Emitted when the implementation is upgraded.\\n */\\n event Upgraded(address indexed implementation);\\n\\n /**\\n * @dev Returns the current implementation address.\\n */\\n function _getImplementation() internal view returns (address) {\\n return StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value;\\n }\\n\\n /**\\n * @dev Stores a new address in the EIP1967 implementation slot.\\n */\\n function _setImplementation(address newImplementation) private {\\n require(Address.isContract(newImplementation), \\\"ERC1967: new implementation is not a contract\\\");\\n StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value = newImplementation;\\n }\\n\\n /**\\n * @dev Perform implementation upgrade\\n *\\n * Emits an {Upgraded} event.\\n */\\n function _upgradeTo(address newImplementation) internal {\\n _setImplementation(newImplementation);\\n emit Upgraded(newImplementation);\\n }\\n\\n /**\\n * @dev Perform implementation upgrade with additional setup call.\\n *\\n * Emits an {Upgraded} event.\\n */\\n function _upgradeToAndCall(\\n address newImplementation,\\n bytes memory data,\\n bool forceCall\\n ) internal {\\n _upgradeTo(newImplementation);\\n if (data.length > 0 || forceCall) {\\n Address.functionDelegateCall(newImplementation, data);\\n }\\n }\\n\\n /**\\n * @dev Perform implementation upgrade with security checks for UUPS proxies, and additional setup call.\\n *\\n * Emits an {Upgraded} event.\\n */\\n function _upgradeToAndCallUUPS(\\n address newImplementation,\\n bytes memory data,\\n bool forceCall\\n ) internal {\\n // Upgrades from old implementations will perform a rollback test. This test requires the new\\n // implementation to upgrade back to the old, non-ERC1822 compliant, implementation. Removing\\n // this special case will break upgrade paths from old UUPS implementation to new ones.\\n if (StorageSlot.getBooleanSlot(_ROLLBACK_SLOT).value) {\\n _setImplementation(newImplementation);\\n } else {\\n try IERC1822Proxiable(newImplementation).proxiableUUID() returns (bytes32 slot) {\\n require(slot == _IMPLEMENTATION_SLOT, \\\"ERC1967Upgrade: unsupported proxiableUUID\\\");\\n } catch {\\n revert(\\\"ERC1967Upgrade: new implementation is not UUPS\\\");\\n }\\n _upgradeToAndCall(newImplementation, data, forceCall);\\n }\\n }\\n\\n /**\\n * @dev Storage slot with the admin of the contract.\\n * This is the keccak-256 hash of \\\"eip1967.proxy.admin\\\" subtracted by 1, and is\\n * validated in the constructor.\\n */\\n bytes32 internal constant _ADMIN_SLOT = 0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103;\\n\\n /**\\n * @dev Emitted when the admin account has changed.\\n */\\n event AdminChanged(address previousAdmin, address newAdmin);\\n\\n /**\\n * @dev Returns the current admin.\\n */\\n function _getAdmin() internal view returns (address) {\\n return StorageSlot.getAddressSlot(_ADMIN_SLOT).value;\\n }\\n\\n /**\\n * @dev Stores a new address in the EIP1967 admin slot.\\n */\\n function _setAdmin(address newAdmin) private {\\n require(newAdmin != address(0), \\\"ERC1967: new admin is the zero address\\\");\\n StorageSlot.getAddressSlot(_ADMIN_SLOT).value = newAdmin;\\n }\\n\\n /**\\n * @dev Changes the admin of the proxy.\\n *\\n * Emits an {AdminChanged} event.\\n */\\n function _changeAdmin(address newAdmin) internal {\\n emit AdminChanged(_getAdmin(), newAdmin);\\n _setAdmin(newAdmin);\\n }\\n\\n /**\\n * @dev The storage slot of the UpgradeableBeacon contract which defines the implementation for this proxy.\\n * This is bytes32(uint256(keccak256('eip1967.proxy.beacon')) - 1)) and is validated in the constructor.\\n */\\n bytes32 internal constant _BEACON_SLOT = 0xa3f0ad74e5423aebfd80d3ef4346578335a9a72aeaee59ff6cb3582b35133d50;\\n\\n /**\\n * @dev Emitted when the beacon is upgraded.\\n */\\n event BeaconUpgraded(address indexed beacon);\\n\\n /**\\n * @dev Returns the current beacon.\\n */\\n function _getBeacon() internal view returns (address) {\\n return StorageSlot.getAddressSlot(_BEACON_SLOT).value;\\n }\\n\\n /**\\n * @dev Stores a new beacon in the EIP1967 beacon slot.\\n */\\n function _setBeacon(address newBeacon) private {\\n require(Address.isContract(newBeacon), \\\"ERC1967: new beacon is not a contract\\\");\\n require(\\n Address.isContract(IBeacon(newBeacon).implementation()),\\n \\\"ERC1967: beacon implementation is not a contract\\\"\\n );\\n StorageSlot.getAddressSlot(_BEACON_SLOT).value = newBeacon;\\n }\\n\\n /**\\n * @dev Perform beacon upgrade with additional setup call. Note: This upgrades the address of the beacon, it does\\n * not upgrade the implementation contained in the beacon (see {UpgradeableBeacon-_setImplementation} for that).\\n *\\n * Emits a {BeaconUpgraded} event.\\n */\\n function _upgradeBeaconToAndCall(\\n address newBeacon,\\n bytes memory data,\\n bool forceCall\\n ) internal {\\n _setBeacon(newBeacon);\\n emit BeaconUpgraded(newBeacon);\\n if (data.length > 0 || forceCall) {\\n Address.functionDelegateCall(IBeacon(newBeacon).implementation(), data);\\n }\\n }\\n}\\n\",\"keccak256\":\"0xabf3f59bc0e5423eae45e459dbe92e7052c6983628d39008590edc852a62f94a\",\"license\":\"MIT\"},\"@openzeppelin/contracts/proxy/Proxy.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.6.0) (proxy/Proxy.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev This abstract contract provides a fallback function that delegates all calls to another contract using the EVM\\n * instruction `delegatecall`. We refer to the second contract as the _implementation_ behind the proxy, and it has to\\n * be specified by overriding the virtual {_implementation} function.\\n *\\n * Additionally, delegation to the implementation can be triggered manually through the {_fallback} function, or to a\\n * different contract through the {_delegate} function.\\n *\\n * The success and return data of the delegated call will be returned back to the caller of the proxy.\\n */\\nabstract contract Proxy {\\n /**\\n * @dev Delegates the current call to `implementation`.\\n *\\n * This function does not return to its internal call site, it will return directly to the external caller.\\n */\\n function _delegate(address implementation) internal virtual {\\n assembly {\\n // Copy msg.data. We take full control of memory in this inline assembly\\n // block because it will not return to Solidity code. We overwrite the\\n // Solidity scratch pad at memory position 0.\\n calldatacopy(0, 0, calldatasize())\\n\\n // Call the implementation.\\n // out and outsize are 0 because we don't know the size yet.\\n let result := delegatecall(gas(), implementation, 0, calldatasize(), 0, 0)\\n\\n // Copy the returned data.\\n returndatacopy(0, 0, returndatasize())\\n\\n switch result\\n // delegatecall returns 0 on error.\\n case 0 {\\n revert(0, returndatasize())\\n }\\n default {\\n return(0, returndatasize())\\n }\\n }\\n }\\n\\n /**\\n * @dev This is a virtual function that should be overridden so it returns the address to which the fallback function\\n * and {_fallback} should delegate.\\n */\\n function _implementation() internal view virtual returns (address);\\n\\n /**\\n * @dev Delegates the current call to the address returned by `_implementation()`.\\n *\\n * This function does not return to its internal call site, it will return directly to the external caller.\\n */\\n function _fallback() internal virtual {\\n _beforeFallback();\\n _delegate(_implementation());\\n }\\n\\n /**\\n * @dev Fallback function that delegates calls to the address returned by `_implementation()`. Will run if no other\\n * function in the contract matches the call data.\\n */\\n fallback() external payable virtual {\\n _fallback();\\n }\\n\\n /**\\n * @dev Fallback function that delegates calls to the address returned by `_implementation()`. Will run if call data\\n * is empty.\\n */\\n receive() external payable virtual {\\n _fallback();\\n }\\n\\n /**\\n * @dev Hook that is called before falling back to the implementation. Can happen as part of a manual `_fallback`\\n * call, or as part of the Solidity `fallback` or `receive` functions.\\n *\\n * If overridden should call `super._beforeFallback()`.\\n */\\n function _beforeFallback() internal virtual {}\\n}\\n\",\"keccak256\":\"0xc130fe33f1b2132158531a87734153293f6d07bc263ff4ac90e85da9c82c0e27\",\"license\":\"MIT\"},\"@openzeppelin/contracts/proxy/beacon/IBeacon.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (proxy/beacon/IBeacon.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev This is the interface that {BeaconProxy} expects of its beacon.\\n */\\ninterface IBeacon {\\n /**\\n * @dev Must return an address that can be used as a delegate call target.\\n *\\n * {BeaconProxy} will check that this address is a contract.\\n */\\n function implementation() external view returns (address);\\n}\\n\",\"keccak256\":\"0xd50a3421ac379ccb1be435fa646d66a65c986b4924f0849839f08692f39dde61\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/Address.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.7.0) (utils/Address.sol)\\n\\npragma solidity ^0.8.1;\\n\\n/**\\n * @dev Collection of functions related to the address type\\n */\\nlibrary Address {\\n /**\\n * @dev Returns true if `account` is a contract.\\n *\\n * [IMPORTANT]\\n * ====\\n * It is unsafe to assume that an address for which this function returns\\n * false is an externally-owned account (EOA) and not a contract.\\n *\\n * Among others, `isContract` will return false for the following\\n * types of addresses:\\n *\\n * - an externally-owned account\\n * - a contract in construction\\n * - an address where a contract will be created\\n * - an address where a contract lived, but was destroyed\\n * ====\\n *\\n * [IMPORTANT]\\n * ====\\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\\n *\\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\\n * constructor.\\n * ====\\n */\\n function isContract(address account) internal view returns (bool) {\\n // This method relies on extcodesize/address.code.length, which returns 0\\n // for contracts in construction, since the code is only stored at the end\\n // of the constructor execution.\\n\\n return account.code.length > 0;\\n }\\n\\n /**\\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\\n * `recipient`, forwarding all available gas and reverting on errors.\\n *\\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\\n * imposed by `transfer`, making them unable to receive funds via\\n * `transfer`. {sendValue} removes this limitation.\\n *\\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\\n *\\n * IMPORTANT: because control is transferred to `recipient`, care must be\\n * taken to not create reentrancy vulnerabilities. Consider using\\n * {ReentrancyGuard} or the\\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\\n */\\n function sendValue(address payable recipient, uint256 amount) internal {\\n require(address(this).balance >= amount, \\\"Address: insufficient balance\\\");\\n\\n (bool success, ) = recipient.call{value: amount}(\\\"\\\");\\n require(success, \\\"Address: unable to send value, recipient may have reverted\\\");\\n }\\n\\n /**\\n * @dev Performs a Solidity function call using a low level `call`. A\\n * plain `call` is an unsafe replacement for a function call: use this\\n * function instead.\\n *\\n * If `target` reverts with a revert reason, it is bubbled up by this\\n * function (like regular Solidity function calls).\\n *\\n * Returns the raw returned data. To convert to the expected return value,\\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\\n *\\n * Requirements:\\n *\\n * - `target` must be a contract.\\n * - calling `target` with `data` must not revert.\\n *\\n * _Available since v3.1._\\n */\\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\\n return functionCall(target, data, \\\"Address: low-level call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\\n * `errorMessage` as a fallback revert reason when `target` reverts.\\n *\\n * _Available since v3.1._\\n */\\n function functionCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n return functionCallWithValue(target, data, 0, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but also transferring `value` wei to `target`.\\n *\\n * Requirements:\\n *\\n * - the calling contract must have an ETH balance of at least `value`.\\n * - the called Solidity function must be `payable`.\\n *\\n * _Available since v3.1._\\n */\\n function functionCallWithValue(\\n address target,\\n bytes memory data,\\n uint256 value\\n ) internal returns (bytes memory) {\\n return functionCallWithValue(target, data, value, \\\"Address: low-level call with value failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\\n * with `errorMessage` as a fallback revert reason when `target` reverts.\\n *\\n * _Available since v3.1._\\n */\\n function functionCallWithValue(\\n address target,\\n bytes memory data,\\n uint256 value,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n require(address(this).balance >= value, \\\"Address: insufficient balance for call\\\");\\n require(isContract(target), \\\"Address: call to non-contract\\\");\\n\\n (bool success, bytes memory returndata) = target.call{value: value}(data);\\n return verifyCallResult(success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but performing a static call.\\n *\\n * _Available since v3.3._\\n */\\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\\n return functionStaticCall(target, data, \\\"Address: low-level static call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\\n * but performing a static call.\\n *\\n * _Available since v3.3._\\n */\\n function functionStaticCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal view returns (bytes memory) {\\n require(isContract(target), \\\"Address: static call to non-contract\\\");\\n\\n (bool success, bytes memory returndata) = target.staticcall(data);\\n return verifyCallResult(success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but performing a delegate call.\\n *\\n * _Available since v3.4._\\n */\\n function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {\\n return functionDelegateCall(target, data, \\\"Address: low-level delegate call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\\n * but performing a delegate call.\\n *\\n * _Available since v3.4._\\n */\\n function functionDelegateCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n require(isContract(target), \\\"Address: delegate call to non-contract\\\");\\n\\n (bool success, bytes memory returndata) = target.delegatecall(data);\\n return verifyCallResult(success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the\\n * revert reason using the provided one.\\n *\\n * _Available since v4.3._\\n */\\n function verifyCallResult(\\n bool success,\\n bytes memory returndata,\\n string memory errorMessage\\n ) internal pure returns (bytes memory) {\\n if (success) {\\n return returndata;\\n } else {\\n // Look for revert reason and bubble it up if present\\n if (returndata.length > 0) {\\n // The easiest way to bubble the revert reason is using memory via assembly\\n /// @solidity memory-safe-assembly\\n assembly {\\n let returndata_size := mload(returndata)\\n revert(add(32, returndata), returndata_size)\\n }\\n } else {\\n revert(errorMessage);\\n }\\n }\\n }\\n}\\n\",\"keccak256\":\"0xd6153ce99bcdcce22b124f755e72553295be6abcd63804cfdffceb188b8bef10\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/StorageSlot.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.7.0) (utils/StorageSlot.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Library for reading and writing primitive types to specific storage slots.\\n *\\n * Storage slots are often used to avoid storage conflict when dealing with upgradeable contracts.\\n * This library helps with reading and writing to such slots without the need for inline assembly.\\n *\\n * The functions in this library return Slot structs that contain a `value` member that can be used to read or write.\\n *\\n * Example usage to set ERC1967 implementation slot:\\n * ```\\n * contract ERC1967 {\\n * bytes32 internal constant _IMPLEMENTATION_SLOT = 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc;\\n *\\n * function _getImplementation() internal view returns (address) {\\n * return StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value;\\n * }\\n *\\n * function _setImplementation(address newImplementation) internal {\\n * require(Address.isContract(newImplementation), \\\"ERC1967: new implementation is not a contract\\\");\\n * StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value = newImplementation;\\n * }\\n * }\\n * ```\\n *\\n * _Available since v4.1 for `address`, `bool`, `bytes32`, and `uint256`._\\n */\\nlibrary StorageSlot {\\n struct AddressSlot {\\n address value;\\n }\\n\\n struct BooleanSlot {\\n bool value;\\n }\\n\\n struct Bytes32Slot {\\n bytes32 value;\\n }\\n\\n struct Uint256Slot {\\n uint256 value;\\n }\\n\\n /**\\n * @dev Returns an `AddressSlot` with member `value` located at `slot`.\\n */\\n function getAddressSlot(bytes32 slot) internal pure returns (AddressSlot storage r) {\\n /// @solidity memory-safe-assembly\\n assembly {\\n r.slot := slot\\n }\\n }\\n\\n /**\\n * @dev Returns an `BooleanSlot` with member `value` located at `slot`.\\n */\\n function getBooleanSlot(bytes32 slot) internal pure returns (BooleanSlot storage r) {\\n /// @solidity memory-safe-assembly\\n assembly {\\n r.slot := slot\\n }\\n }\\n\\n /**\\n * @dev Returns an `Bytes32Slot` with member `value` located at `slot`.\\n */\\n function getBytes32Slot(bytes32 slot) internal pure returns (Bytes32Slot storage r) {\\n /// @solidity memory-safe-assembly\\n assembly {\\n r.slot := slot\\n }\\n }\\n\\n /**\\n * @dev Returns an `Uint256Slot` with member `value` located at `slot`.\\n */\\n function getUint256Slot(bytes32 slot) internal pure returns (Uint256Slot storage r) {\\n /// @solidity memory-safe-assembly\\n assembly {\\n r.slot := slot\\n }\\n }\\n}\\n\",\"keccak256\":\"0xd5c50c54bf02740ebd122ff06832546cb5fa84486d52695a9ccfd11666e0c81d\",\"license\":\"MIT\"},\"contracts/external/TransparentUpgradeableProxy.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-3.0\\n\\npragma solidity ^0.8.12;\\n\\nimport \\\"@openzeppelin/contracts/proxy/ERC1967/ERC1967Proxy.sol\\\";\\n\\n/**\\n * @dev This contract implements a proxy that is upgradeable by an admin. It is fully forked from OpenZeppelin\\n * `TransparentUpgradeableProxy`\\n *\\n * To avoid https://medium.com/nomic-labs-blog/malicious-backdoors-in-ethereum-proxies-62629adf3357[proxy selector\\n * clashing], which can potentially be used in an attack, this contract uses the\\n * https://blog.openzeppelin.com/the-transparent-proxy-pattern/[transparent proxy pattern]. This pattern implies two\\n * things that go hand in hand:\\n *\\n * 1. If any account other than the admin calls the proxy, the call will be forwarded to the implementation, even if\\n * that call matches one of the admin functions exposed by the proxy itself.\\n * 2. If the admin calls the proxy, it can access the admin functions, but its calls will never be forwarded to the\\n * implementation. If the admin tries to call a function on the implementation it will fail with an error that says\\n * \\\"admin cannot fallback to proxy target\\\".\\n *\\n * These properties mean that the admin account can only be used for admin actions like upgrading the proxy or changing\\n * the admin, so it's best if it's a dedicated account that is not used for anything else. This will avoid headaches due\\n * to sudden errors when trying to call a function from the proxy implementation.\\n *\\n * Our recommendation is for the dedicated account to be an instance of the {ProxyAdmin} contract. If set up this way,\\n * you should think of the `ProxyAdmin` instance as the real administrative interface of your proxy.\\n */\\ncontract TransparentUpgradeableProxy is ERC1967Proxy {\\n /**\\n * @dev Initializes an upgradeable proxy managed by `_admin`, backed by the implementation at `_logic`, and\\n * optionally initialized with `_data` as explained in {ERC1967Proxy-constructor}.\\n */\\n constructor(address _logic, address admin_, bytes memory _data) payable ERC1967Proxy(_logic, _data) {\\n assert(_ADMIN_SLOT == bytes32(uint256(keccak256(\\\"eip1967.proxy.admin\\\")) - 1));\\n _changeAdmin(admin_);\\n }\\n\\n /**\\n * @dev Modifier used internally that will delegate the call to the implementation unless the sender is the admin.\\n */\\n modifier ifAdmin() {\\n if (msg.sender == _getAdmin()) {\\n _;\\n } else {\\n _fallback();\\n }\\n }\\n\\n /**\\n * @dev Returns the current admin.\\n *\\n * NOTE: Only the admin can call this function. See {ProxyAdmin-getProxyAdmin}.\\n *\\n * TIP: To get this value clients can read directly from the storage slot shown below (specified by EIP1967) using the\\n * https://eth.wiki/json-rpc/API#eth_getstorageat[`eth_getStorageAt`] RPC call.\\n * `0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103`\\n */\\n function admin() external ifAdmin returns (address admin_) {\\n admin_ = _getAdmin();\\n }\\n\\n /**\\n * @dev Returns the current implementation.\\n *\\n * NOTE: Only the admin can call this function. See {ProxyAdmin-getProxyImplementation}.\\n *\\n * TIP: To get this value clients can read directly from the storage slot shown below (specified by EIP1967) using the\\n * https://eth.wiki/json-rpc/API#eth_getstorageat[`eth_getStorageAt`] RPC call.\\n * `0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc`\\n */\\n function implementation() external ifAdmin returns (address implementation_) {\\n implementation_ = _implementation();\\n }\\n\\n /**\\n * @dev Changes the admin of the proxy.\\n *\\n * Emits an {AdminChanged} event.\\n *\\n * NOTE: Only the admin can call this function. See {ProxyAdmin-changeProxyAdmin}.\\n */\\n function changeAdmin(address newAdmin) external virtual ifAdmin {\\n _changeAdmin(newAdmin);\\n }\\n\\n /**\\n * @dev Upgrade the implementation of the proxy.\\n *\\n * NOTE: Only the admin can call this function. See {ProxyAdmin-upgrade}.\\n */\\n function upgradeTo(address newImplementation) external ifAdmin {\\n _upgradeToAndCall(newImplementation, bytes(\\\"\\\"), false);\\n }\\n\\n /**\\n * @dev Upgrade the implementation of the proxy, and then call a function from the new implementation as specified\\n * by `data`, which should be an encoded function call. This is useful to initialize new storage variables in the\\n * proxied contract.\\n *\\n * NOTE: Only the admin can call this function. See {ProxyAdmin-upgradeAndCall}.\\n */\\n function upgradeToAndCall(address newImplementation, bytes calldata data) external payable ifAdmin {\\n _upgradeToAndCall(newImplementation, data, true);\\n }\\n\\n /**\\n * @dev Returns the current admin.\\n */\\n function _admin() internal view virtual returns (address) {\\n return _getAdmin();\\n }\\n\\n /**\\n * @dev Makes sure the admin cannot access the fallback function. See {Proxy-_beforeFallback}.\\n */\\n function _beforeFallback() internal virtual override {\\n require(msg.sender != _getAdmin(), \\\"TransparentUpgradeableProxy: admin cannot fallback to proxy target\\\");\\n super._beforeFallback();\\n }\\n}\\n\",\"keccak256\":\"0x93a67a0f612ea3ff2a76315e138a6a88267270a1379d3cc7be52845fbbe611e2\",\"license\":\"GPL-3.0\"}},\"version\":1}", + "bytecode": "0x6080604052604051620010bb380380620010bb8339810160408190526200002691620004d8565b828162000036828260006200009a565b5062000066905060017fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6104620005b8565b6000805160206200107483398151915214620000865762000086620005da565b6200009182620000d7565b50505062000643565b620000a58362000132565b600082511180620000b35750805b15620000d257620000d083836200017460201b6200028c1760201c565b505b505050565b7f7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f62000102620001a5565b604080516001600160a01b03928316815291841660208301520160405180910390a16200012f81620001de565b50565b6200013d8162000293565b6040516001600160a01b038216907fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b90600090a250565b60606200019c8383604051806060016040528060278152602001620010946027913962000347565b90505b92915050565b6000620001cf6000805160206200107483398151915260001b6200042f60201b6200022e1760201c565b546001600160a01b0316919050565b6001600160a01b038116620002495760405162461bcd60e51b815260206004820152602660248201527f455243313936373a206e65772061646d696e20697320746865207a65726f206160448201526564647265737360d01b60648201526084015b60405180910390fd5b80620002726000805160206200107483398151915260001b6200042f60201b6200022e1760201c565b80546001600160a01b0319166001600160a01b039290921691909117905550565b620002a9816200043260201b620002b81760201c565b6200030d5760405162461bcd60e51b815260206004820152602d60248201527f455243313936373a206e657720696d706c656d656e746174696f6e206973206e60448201526c1bdd08184818dbdb9d1c9858dd609a1b606482015260840162000240565b80620002727f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc60001b6200042f60201b6200022e1760201c565b60606001600160a01b0384163b620003b15760405162461bcd60e51b815260206004820152602660248201527f416464726573733a2064656c65676174652063616c6c20746f206e6f6e2d636f6044820152651b9d1c9858dd60d21b606482015260840162000240565b600080856001600160a01b031685604051620003ce9190620005f0565b600060405180830381855af49150503d80600081146200040b576040519150601f19603f3d011682016040523d82523d6000602084013e62000410565b606091505b5090925090506200042382828662000441565b925050505b9392505050565b90565b6001600160a01b03163b151590565b606083156200045257508162000428565b825115620004635782518084602001fd5b8160405162461bcd60e51b81526004016200024091906200060e565b80516001600160a01b03811681146200049757600080fd5b919050565b634e487b7160e01b600052604160045260246000fd5b60005b83811015620004cf578181015183820152602001620004b5565b50506000910152565b600080600060608486031215620004ee57600080fd5b620004f9846200047f565b925062000509602085016200047f565b60408501519092506001600160401b03808211156200052757600080fd5b818601915086601f8301126200053c57600080fd5b8151818111156200055157620005516200049c565b604051601f8201601f19908116603f011681019083821181831017156200057c576200057c6200049c565b816040528281528960208487010111156200059657600080fd5b620005a9836020830160208801620004b2565b80955050505050509250925092565b818103818111156200019f57634e487b7160e01b600052601160045260246000fd5b634e487b7160e01b600052600160045260246000fd5b6000825162000604818460208701620004b2565b9190910192915050565b60208152600082518060208401526200062f816040850160208701620004b2565b601f01601f19169190910160400192915050565b610a2180620006536000396000f3fe60806040526004361061005e5760003560e01c80635c60da1b116100435780635c60da1b146100a85780638f283970146100e6578063f851a440146101065761006d565b80633659cfe6146100755780634f1ef286146100955761006d565b3661006d5761006b61011b565b005b61006b61011b565b34801561008157600080fd5b5061006b610090366004610895565b610135565b61006b6100a33660046108b0565b61017f565b3480156100b457600080fd5b506100bd6101f3565b60405173ffffffffffffffffffffffffffffffffffffffff909116815260200160405180910390f35b3480156100f257600080fd5b5061006b610101366004610895565b610231565b34801561011257600080fd5b506100bd61025e565b6101236102d4565b61013361012e6103ab565b6103b5565b565b61013d6103d9565b73ffffffffffffffffffffffffffffffffffffffff1633036101775761017481604051806020016040528060008152506000610419565b50565b61017461011b565b6101876103d9565b73ffffffffffffffffffffffffffffffffffffffff1633036101eb576101e68383838080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525060019250610419915050565b505050565b6101e661011b565b60006101fd6103d9565b73ffffffffffffffffffffffffffffffffffffffff163303610226576102216103ab565b905090565b61022e61011b565b90565b6102396103d9565b73ffffffffffffffffffffffffffffffffffffffff1633036101775761017481610444565b60006102686103d9565b73ffffffffffffffffffffffffffffffffffffffff163303610226576102216103d9565b60606102b183836040518060600160405280602781526020016109c5602791396104a5565b9392505050565b73ffffffffffffffffffffffffffffffffffffffff163b151590565b6102dc6103d9565b73ffffffffffffffffffffffffffffffffffffffff163303610133576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604260248201527f5472616e73706172656e745570677261646561626c6550726f78793a2061646d60448201527f696e2063616e6e6f742066616c6c6261636b20746f2070726f7879207461726760648201527f6574000000000000000000000000000000000000000000000000000000000000608482015260a4015b60405180910390fd5b60006102216105cd565b3660008037600080366000845af43d6000803e8080156103d4573d6000f35b3d6000fd5b60007fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035b5473ffffffffffffffffffffffffffffffffffffffff16919050565b610422836105f5565b60008251118061042f5750805b156101e65761043e838361028c565b50505050565b7f7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f61046d6103d9565b6040805173ffffffffffffffffffffffffffffffffffffffff928316815291841660208301520160405180910390a161017481610642565b606073ffffffffffffffffffffffffffffffffffffffff84163b61054b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f416464726573733a2064656c65676174652063616c6c20746f206e6f6e2d636f60448201527f6e7472616374000000000000000000000000000000000000000000000000000060648201526084016103a2565b6000808573ffffffffffffffffffffffffffffffffffffffff16856040516105739190610957565b600060405180830381855af49150503d80600081146105ae576040519150601f19603f3d011682016040523d82523d6000602084013e6105b3565b606091505b50915091506105c382828661074e565b9695505050505050565b60007f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc6103fd565b6105fe816107a1565b60405173ffffffffffffffffffffffffffffffffffffffff8216907fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b90600090a250565b73ffffffffffffffffffffffffffffffffffffffff81166106e5576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f455243313936373a206e65772061646d696e20697320746865207a65726f206160448201527f646472657373000000000000000000000000000000000000000000000000000060648201526084016103a2565b807fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035b80547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff9290921691909117905550565b6060831561075d5750816102b1565b82511561076d5782518084602001fd5b816040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016103a29190610973565b73ffffffffffffffffffffffffffffffffffffffff81163b610845576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602d60248201527f455243313936373a206e657720696d706c656d656e746174696f6e206973206e60448201527f6f74206120636f6e74726163740000000000000000000000000000000000000060648201526084016103a2565b807f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc610708565b803573ffffffffffffffffffffffffffffffffffffffff8116811461089057600080fd5b919050565b6000602082840312156108a757600080fd5b6102b18261086c565b6000806000604084860312156108c557600080fd5b6108ce8461086c565b9250602084013567ffffffffffffffff808211156108eb57600080fd5b818601915086601f8301126108ff57600080fd5b81358181111561090e57600080fd5b87602082850101111561092057600080fd5b6020830194508093505050509250925092565b60005b8381101561094e578181015183820152602001610936565b50506000910152565b60008251610969818460208701610933565b9190910192915050565b6020815260008251806020840152610992816040850160208701610933565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016919091016040019291505056fe416464726573733a206c6f772d6c6576656c2064656c65676174652063616c6c206661696c6564a2646970667358221220e96638b07fb1675d93a95c49e417bc8111448b23a59918698cdcd8fd488dd7cf64736f6c63430008110033b53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103416464726573733a206c6f772d6c6576656c2064656c65676174652063616c6c206661696c6564", + "deployedBytecode": "0x60806040526004361061005e5760003560e01c80635c60da1b116100435780635c60da1b146100a85780638f283970146100e6578063f851a440146101065761006d565b80633659cfe6146100755780634f1ef286146100955761006d565b3661006d5761006b61011b565b005b61006b61011b565b34801561008157600080fd5b5061006b610090366004610895565b610135565b61006b6100a33660046108b0565b61017f565b3480156100b457600080fd5b506100bd6101f3565b60405173ffffffffffffffffffffffffffffffffffffffff909116815260200160405180910390f35b3480156100f257600080fd5b5061006b610101366004610895565b610231565b34801561011257600080fd5b506100bd61025e565b6101236102d4565b61013361012e6103ab565b6103b5565b565b61013d6103d9565b73ffffffffffffffffffffffffffffffffffffffff1633036101775761017481604051806020016040528060008152506000610419565b50565b61017461011b565b6101876103d9565b73ffffffffffffffffffffffffffffffffffffffff1633036101eb576101e68383838080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525060019250610419915050565b505050565b6101e661011b565b60006101fd6103d9565b73ffffffffffffffffffffffffffffffffffffffff163303610226576102216103ab565b905090565b61022e61011b565b90565b6102396103d9565b73ffffffffffffffffffffffffffffffffffffffff1633036101775761017481610444565b60006102686103d9565b73ffffffffffffffffffffffffffffffffffffffff163303610226576102216103d9565b60606102b183836040518060600160405280602781526020016109c5602791396104a5565b9392505050565b73ffffffffffffffffffffffffffffffffffffffff163b151590565b6102dc6103d9565b73ffffffffffffffffffffffffffffffffffffffff163303610133576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604260248201527f5472616e73706172656e745570677261646561626c6550726f78793a2061646d60448201527f696e2063616e6e6f742066616c6c6261636b20746f2070726f7879207461726760648201527f6574000000000000000000000000000000000000000000000000000000000000608482015260a4015b60405180910390fd5b60006102216105cd565b3660008037600080366000845af43d6000803e8080156103d4573d6000f35b3d6000fd5b60007fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035b5473ffffffffffffffffffffffffffffffffffffffff16919050565b610422836105f5565b60008251118061042f5750805b156101e65761043e838361028c565b50505050565b7f7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f61046d6103d9565b6040805173ffffffffffffffffffffffffffffffffffffffff928316815291841660208301520160405180910390a161017481610642565b606073ffffffffffffffffffffffffffffffffffffffff84163b61054b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f416464726573733a2064656c65676174652063616c6c20746f206e6f6e2d636f60448201527f6e7472616374000000000000000000000000000000000000000000000000000060648201526084016103a2565b6000808573ffffffffffffffffffffffffffffffffffffffff16856040516105739190610957565b600060405180830381855af49150503d80600081146105ae576040519150601f19603f3d011682016040523d82523d6000602084013e6105b3565b606091505b50915091506105c382828661074e565b9695505050505050565b60007f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc6103fd565b6105fe816107a1565b60405173ffffffffffffffffffffffffffffffffffffffff8216907fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b90600090a250565b73ffffffffffffffffffffffffffffffffffffffff81166106e5576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f455243313936373a206e65772061646d696e20697320746865207a65726f206160448201527f646472657373000000000000000000000000000000000000000000000000000060648201526084016103a2565b807fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035b80547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff9290921691909117905550565b6060831561075d5750816102b1565b82511561076d5782518084602001fd5b816040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016103a29190610973565b73ffffffffffffffffffffffffffffffffffffffff81163b610845576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602d60248201527f455243313936373a206e657720696d706c656d656e746174696f6e206973206e60448201527f6f74206120636f6e74726163740000000000000000000000000000000000000060648201526084016103a2565b807f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc610708565b803573ffffffffffffffffffffffffffffffffffffffff8116811461089057600080fd5b919050565b6000602082840312156108a757600080fd5b6102b18261086c565b6000806000604084860312156108c557600080fd5b6108ce8461086c565b9250602084013567ffffffffffffffff808211156108eb57600080fd5b818601915086601f8301126108ff57600080fd5b81358181111561090e57600080fd5b87602082850101111561092057600080fd5b6020830194508093505050509250925092565b60005b8381101561094e578181015183820152602001610936565b50506000910152565b60008251610969818460208701610933565b9190910192915050565b6020815260008251806020840152610992816040850160208701610933565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016919091016040019291505056fe416464726573733a206c6f772d6c6576656c2064656c65676174652063616c6c206661696c6564a2646970667358221220e96638b07fb1675d93a95c49e417bc8111448b23a59918698cdcd8fd488dd7cf64736f6c63430008110033", + "devdoc": { + "details": "This contract implements a proxy that is upgradeable by an admin. It is fully forked from OpenZeppelin `TransparentUpgradeableProxy` To avoid https://medium.com/nomic-labs-blog/malicious-backdoors-in-ethereum-proxies-62629adf3357[proxy selector clashing], which can potentially be used in an attack, this contract uses the https://blog.openzeppelin.com/the-transparent-proxy-pattern/[transparent proxy pattern]. This pattern implies two things that go hand in hand: 1. If any account other than the admin calls the proxy, the call will be forwarded to the implementation, even if that call matches one of the admin functions exposed by the proxy itself. 2. If the admin calls the proxy, it can access the admin functions, but its calls will never be forwarded to the implementation. If the admin tries to call a function on the implementation it will fail with an error that says \"admin cannot fallback to proxy target\". These properties mean that the admin account can only be used for admin actions like upgrading the proxy or changing the admin, so it's best if it's a dedicated account that is not used for anything else. This will avoid headaches due to sudden errors when trying to call a function from the proxy implementation. Our recommendation is for the dedicated account to be an instance of the {ProxyAdmin} contract. If set up this way, you should think of the `ProxyAdmin` instance as the real administrative interface of your proxy.", + "kind": "dev", + "methods": { + "admin()": { + "details": "Returns the current admin. NOTE: Only the admin can call this function. See {ProxyAdmin-getProxyAdmin}. TIP: To get this value clients can read directly from the storage slot shown below (specified by EIP1967) using the https://eth.wiki/json-rpc/API#eth_getstorageat[`eth_getStorageAt`] RPC call. `0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103`" + }, + "changeAdmin(address)": { + "details": "Changes the admin of the proxy. Emits an {AdminChanged} event. NOTE: Only the admin can call this function. See {ProxyAdmin-changeProxyAdmin}." + }, + "constructor": { + "details": "Initializes an upgradeable proxy managed by `_admin`, backed by the implementation at `_logic`, and optionally initialized with `_data` as explained in {ERC1967Proxy-constructor}." + }, + "implementation()": { + "details": "Returns the current implementation. NOTE: Only the admin can call this function. See {ProxyAdmin-getProxyImplementation}. TIP: To get this value clients can read directly from the storage slot shown below (specified by EIP1967) using the https://eth.wiki/json-rpc/API#eth_getstorageat[`eth_getStorageAt`] RPC call. `0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc`" + }, + "upgradeTo(address)": { + "details": "Upgrade the implementation of the proxy. NOTE: Only the admin can call this function. See {ProxyAdmin-upgrade}." + }, + "upgradeToAndCall(address,bytes)": { + "details": "Upgrade the implementation of the proxy, and then call a function from the new implementation as specified by `data`, which should be an encoded function call. This is useful to initialize new storage variables in the proxied contract. NOTE: Only the admin can call this function. See {ProxyAdmin-upgradeAndCall}." + } + }, + "version": 1 + }, + "userdoc": { + "kind": "user", + "methods": {}, + "version": 1 + }, + "storageLayout": { + "storage": [], + "types": null + } +} \ No newline at end of file diff --git a/deployments/optimism/LayerZeroBridge_USD.json b/deployments/optimism/LayerZeroBridge_USD.json new file mode 100644 index 00000000..08820385 --- /dev/null +++ b/deployments/optimism/LayerZeroBridge_USD.json @@ -0,0 +1,275 @@ +{ + "address": "0xc69e66109943fAF5Cbda22F360b7eB7c27Bb5C88", + "abi": [ + { + "inputs": [ + { + "internalType": "address", + "name": "_logic", + "type": "address" + }, + { + "internalType": "address", + "name": "admin_", + "type": "address" + }, + { + "internalType": "bytes", + "name": "_data", + "type": "bytes" + } + ], + "stateMutability": "payable", + "type": "constructor" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "previousAdmin", + "type": "address" + }, + { + "indexed": false, + "internalType": "address", + "name": "newAdmin", + "type": "address" + } + ], + "name": "AdminChanged", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "beacon", + "type": "address" + } + ], + "name": "BeaconUpgraded", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "implementation", + "type": "address" + } + ], + "name": "Upgraded", + "type": "event" + }, + { + "stateMutability": "payable", + "type": "fallback" + }, + { + "inputs": [], + "name": "admin", + "outputs": [ + { + "internalType": "address", + "name": "admin_", + "type": "address" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "newAdmin", + "type": "address" + } + ], + "name": "changeAdmin", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "implementation", + "outputs": [ + { + "internalType": "address", + "name": "implementation_", + "type": "address" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "newImplementation", + "type": "address" + } + ], + "name": "upgradeTo", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "newImplementation", + "type": "address" + }, + { + "internalType": "bytes", + "name": "data", + "type": "bytes" + } + ], + "name": "upgradeToAndCall", + "outputs": [], + "stateMutability": "payable", + "type": "function" + }, + { + "stateMutability": "payable", + "type": "receive" + } + ], + "transactionHash": "0x7e5d5f8ac08abc2659824cb7eff89f3ede53c10e33277d1aaf8a9dfe927a9320", + "receipt": { + "to": null, + "from": "0xfdA462548Ce04282f4B6D6619823a7C64Fdc0185", + "contractAddress": "0xc69e66109943fAF5Cbda22F360b7eB7c27Bb5C88", + "transactionIndex": 5, + "gasUsed": "849932", + "logsBloom": "0x0000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000000000000000000000000400000020000000000400000000000000000c000022000000000000000000000000000500000000000000020000000000000000000800000000800000000000000010000000000000000000000100000000000000000000000000000080000000800000800000020000000000000000000000000400000000004000000080000000000000000000004022000000000000000000040000000000000400000000000000000020000010000000000000000000000000000000000000000000000020000000000000", + "blockHash": "0x451b5c83f00d5df075c99792382be8f463e7ac5514e5808282d32ccbba1b2e98", + "transactionHash": "0x7e5d5f8ac08abc2659824cb7eff89f3ede53c10e33277d1aaf8a9dfe927a9320", + "logs": [ + { + "transactionIndex": 5, + "blockNumber": 114646752, + "transactionHash": "0x7e5d5f8ac08abc2659824cb7eff89f3ede53c10e33277d1aaf8a9dfe927a9320", + "address": "0xc69e66109943fAF5Cbda22F360b7eB7c27Bb5C88", + "topics": [ + "0xbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b", + "0x000000000000000000000000288320624972877cd64a1cb98d1342e7e1785024" + ], + "data": "0x", + "logIndex": 2, + "blockHash": "0x451b5c83f00d5df075c99792382be8f463e7ac5514e5808282d32ccbba1b2e98" + }, + { + "transactionIndex": 5, + "blockNumber": 114646752, + "transactionHash": "0x7e5d5f8ac08abc2659824cb7eff89f3ede53c10e33277d1aaf8a9dfe927a9320", + "address": "0xc69e66109943fAF5Cbda22F360b7eB7c27Bb5C88", + "topics": [ + "0x8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925", + "0x000000000000000000000000c69e66109943faf5cbda22f360b7eb7c27bb5c88", + "0x0000000000000000000000000000206329b97db379d5e1bf586bbdb969c63274" + ], + "data": "0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", + "logIndex": 3, + "blockHash": "0x451b5c83f00d5df075c99792382be8f463e7ac5514e5808282d32ccbba1b2e98" + }, + { + "transactionIndex": 5, + "blockNumber": 114646752, + "transactionHash": "0x7e5d5f8ac08abc2659824cb7eff89f3ede53c10e33277d1aaf8a9dfe927a9320", + "address": "0xc69e66109943fAF5Cbda22F360b7eB7c27Bb5C88", + "topics": [ + "0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000206329b97db379d5e1bf586bbdb969c63274" + ], + "data": "0x0000000000000000000000000000000000000000000000000000000000000000", + "logIndex": 4, + "blockHash": "0x451b5c83f00d5df075c99792382be8f463e7ac5514e5808282d32ccbba1b2e98" + }, + { + "transactionIndex": 5, + "blockNumber": 114646752, + "transactionHash": "0x7e5d5f8ac08abc2659824cb7eff89f3ede53c10e33277d1aaf8a9dfe927a9320", + "address": "0xc69e66109943fAF5Cbda22F360b7eB7c27Bb5C88", + "topics": [ + "0x7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb3847402498" + ], + "data": "0x0000000000000000000000000000000000000000000000000000000000000001", + "logIndex": 5, + "blockHash": "0x451b5c83f00d5df075c99792382be8f463e7ac5514e5808282d32ccbba1b2e98" + }, + { + "transactionIndex": 5, + "blockNumber": 114646752, + "transactionHash": "0x7e5d5f8ac08abc2659824cb7eff89f3ede53c10e33277d1aaf8a9dfe927a9320", + "address": "0xc69e66109943fAF5Cbda22F360b7eB7c27Bb5C88", + "topics": [ + "0x7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f" + ], + "data": "0x0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000c16b81af351ba9e64c1a069e3ab18c244a1e3049", + "logIndex": 6, + "blockHash": "0x451b5c83f00d5df075c99792382be8f463e7ac5514e5808282d32ccbba1b2e98" + } + ], + "blockNumber": 114646752, + "cumulativeGasUsed": "1041861", + "status": 1, + "byzantium": true + }, + "args": [ + "0x288320624972877Cd64A1CB98D1342E7e1785024", + "0xC16B81Af351BA9e64C1a069E3Ab18c244A1E3049", + "0xc9aba0aa00000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000000e00000000000000000000000003c2269811836af69497e5f486a85d7316753cf62000000000000000000000000770f7cdfae5ecaa3a0538da7cb1d6c8f22252fe0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000164c617965725a65726f204272696467652061675553440000000000000000000000000000000000000000000000000000000000000000000000000000000000084c5a2d6167555344000000000000000000000000000000000000000000000000" + ], + "numDeployments": 1, + "solcInputHash": "871924e0c138825a2736b76def8fef8d", + "metadata": "{\"compiler\":{\"version\":\"0.8.17+commit.8df45f5f\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_logic\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"admin_\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"_data\",\"type\":\"bytes\"}],\"stateMutability\":\"payable\",\"type\":\"constructor\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"previousAdmin\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"newAdmin\",\"type\":\"address\"}],\"name\":\"AdminChanged\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"beacon\",\"type\":\"address\"}],\"name\":\"BeaconUpgraded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"implementation\",\"type\":\"address\"}],\"name\":\"Upgraded\",\"type\":\"event\"},{\"stateMutability\":\"payable\",\"type\":\"fallback\"},{\"inputs\":[],\"name\":\"admin\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"admin_\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newAdmin\",\"type\":\"address\"}],\"name\":\"changeAdmin\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"implementation\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"implementation_\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newImplementation\",\"type\":\"address\"}],\"name\":\"upgradeTo\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newImplementation\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"}],\"name\":\"upgradeToAndCall\",\"outputs\":[],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"stateMutability\":\"payable\",\"type\":\"receive\"}],\"devdoc\":{\"details\":\"This contract implements a proxy that is upgradeable by an admin. It is fully forked from OpenZeppelin `TransparentUpgradeableProxy` To avoid https://medium.com/nomic-labs-blog/malicious-backdoors-in-ethereum-proxies-62629adf3357[proxy selector clashing], which can potentially be used in an attack, this contract uses the https://blog.openzeppelin.com/the-transparent-proxy-pattern/[transparent proxy pattern]. This pattern implies two things that go hand in hand: 1. If any account other than the admin calls the proxy, the call will be forwarded to the implementation, even if that call matches one of the admin functions exposed by the proxy itself. 2. If the admin calls the proxy, it can access the admin functions, but its calls will never be forwarded to the implementation. If the admin tries to call a function on the implementation it will fail with an error that says \\\"admin cannot fallback to proxy target\\\". These properties mean that the admin account can only be used for admin actions like upgrading the proxy or changing the admin, so it's best if it's a dedicated account that is not used for anything else. This will avoid headaches due to sudden errors when trying to call a function from the proxy implementation. Our recommendation is for the dedicated account to be an instance of the {ProxyAdmin} contract. If set up this way, you should think of the `ProxyAdmin` instance as the real administrative interface of your proxy.\",\"kind\":\"dev\",\"methods\":{\"admin()\":{\"details\":\"Returns the current admin. NOTE: Only the admin can call this function. See {ProxyAdmin-getProxyAdmin}. TIP: To get this value clients can read directly from the storage slot shown below (specified by EIP1967) using the https://eth.wiki/json-rpc/API#eth_getstorageat[`eth_getStorageAt`] RPC call. `0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103`\"},\"changeAdmin(address)\":{\"details\":\"Changes the admin of the proxy. Emits an {AdminChanged} event. NOTE: Only the admin can call this function. See {ProxyAdmin-changeProxyAdmin}.\"},\"constructor\":{\"details\":\"Initializes an upgradeable proxy managed by `_admin`, backed by the implementation at `_logic`, and optionally initialized with `_data` as explained in {ERC1967Proxy-constructor}.\"},\"implementation()\":{\"details\":\"Returns the current implementation. NOTE: Only the admin can call this function. See {ProxyAdmin-getProxyImplementation}. TIP: To get this value clients can read directly from the storage slot shown below (specified by EIP1967) using the https://eth.wiki/json-rpc/API#eth_getstorageat[`eth_getStorageAt`] RPC call. `0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc`\"},\"upgradeTo(address)\":{\"details\":\"Upgrade the implementation of the proxy. NOTE: Only the admin can call this function. See {ProxyAdmin-upgrade}.\"},\"upgradeToAndCall(address,bytes)\":{\"details\":\"Upgrade the implementation of the proxy, and then call a function from the new implementation as specified by `data`, which should be an encoded function call. This is useful to initialize new storage variables in the proxied contract. NOTE: Only the admin can call this function. See {ProxyAdmin-upgradeAndCall}.\"}},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/external/TransparentUpgradeableProxy.sol\":\"TransparentUpgradeableProxy\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":1000000},\"remappings\":[]},\"sources\":{\"@openzeppelin/contracts/interfaces/draft-IERC1822.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.5.0) (interfaces/draft-IERC1822.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev ERC1822: Universal Upgradeable Proxy Standard (UUPS) documents a method for upgradeability through a simplified\\n * proxy whose upgrades are fully controlled by the current implementation.\\n */\\ninterface IERC1822Proxiable {\\n /**\\n * @dev Returns the storage slot that the proxiable contract assumes is being used to store the implementation\\n * address.\\n *\\n * IMPORTANT: A proxy pointing at a proxiable contract should not be considered proxiable itself, because this risks\\n * bricking a proxy that upgrades to it, by delegating to itself until out of gas. Thus it is critical that this\\n * function revert if invoked through a proxy.\\n */\\n function proxiableUUID() external view returns (bytes32);\\n}\\n\",\"keccak256\":\"0x1d4afe6cb24200cc4545eed814ecf5847277dfe5d613a1707aad5fceecebcfff\",\"license\":\"MIT\"},\"@openzeppelin/contracts/proxy/ERC1967/ERC1967Proxy.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.7.0) (proxy/ERC1967/ERC1967Proxy.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../Proxy.sol\\\";\\nimport \\\"./ERC1967Upgrade.sol\\\";\\n\\n/**\\n * @dev This contract implements an upgradeable proxy. It is upgradeable because calls are delegated to an\\n * implementation address that can be changed. This address is stored in storage in the location specified by\\n * https://eips.ethereum.org/EIPS/eip-1967[EIP1967], so that it doesn't conflict with the storage layout of the\\n * implementation behind the proxy.\\n */\\ncontract ERC1967Proxy is Proxy, ERC1967Upgrade {\\n /**\\n * @dev Initializes the upgradeable proxy with an initial implementation specified by `_logic`.\\n *\\n * If `_data` is nonempty, it's used as data in a delegate call to `_logic`. This will typically be an encoded\\n * function call, and allows initializing the storage of the proxy like a Solidity constructor.\\n */\\n constructor(address _logic, bytes memory _data) payable {\\n _upgradeToAndCall(_logic, _data, false);\\n }\\n\\n /**\\n * @dev Returns the current implementation address.\\n */\\n function _implementation() internal view virtual override returns (address impl) {\\n return ERC1967Upgrade._getImplementation();\\n }\\n}\\n\",\"keccak256\":\"0xa2b22da3032e50b55f95ec1d13336102d675f341167aa76db571ef7f8bb7975d\",\"license\":\"MIT\"},\"@openzeppelin/contracts/proxy/ERC1967/ERC1967Upgrade.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.5.0) (proxy/ERC1967/ERC1967Upgrade.sol)\\n\\npragma solidity ^0.8.2;\\n\\nimport \\\"../beacon/IBeacon.sol\\\";\\nimport \\\"../../interfaces/draft-IERC1822.sol\\\";\\nimport \\\"../../utils/Address.sol\\\";\\nimport \\\"../../utils/StorageSlot.sol\\\";\\n\\n/**\\n * @dev This abstract contract provides getters and event emitting update functions for\\n * https://eips.ethereum.org/EIPS/eip-1967[EIP1967] slots.\\n *\\n * _Available since v4.1._\\n *\\n * @custom:oz-upgrades-unsafe-allow delegatecall\\n */\\nabstract contract ERC1967Upgrade {\\n // This is the keccak-256 hash of \\\"eip1967.proxy.rollback\\\" subtracted by 1\\n bytes32 private constant _ROLLBACK_SLOT = 0x4910fdfa16fed3260ed0e7147f7cc6da11a60208b5b9406d12a635614ffd9143;\\n\\n /**\\n * @dev Storage slot with the address of the current implementation.\\n * This is the keccak-256 hash of \\\"eip1967.proxy.implementation\\\" subtracted by 1, and is\\n * validated in the constructor.\\n */\\n bytes32 internal constant _IMPLEMENTATION_SLOT = 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc;\\n\\n /**\\n * @dev Emitted when the implementation is upgraded.\\n */\\n event Upgraded(address indexed implementation);\\n\\n /**\\n * @dev Returns the current implementation address.\\n */\\n function _getImplementation() internal view returns (address) {\\n return StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value;\\n }\\n\\n /**\\n * @dev Stores a new address in the EIP1967 implementation slot.\\n */\\n function _setImplementation(address newImplementation) private {\\n require(Address.isContract(newImplementation), \\\"ERC1967: new implementation is not a contract\\\");\\n StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value = newImplementation;\\n }\\n\\n /**\\n * @dev Perform implementation upgrade\\n *\\n * Emits an {Upgraded} event.\\n */\\n function _upgradeTo(address newImplementation) internal {\\n _setImplementation(newImplementation);\\n emit Upgraded(newImplementation);\\n }\\n\\n /**\\n * @dev Perform implementation upgrade with additional setup call.\\n *\\n * Emits an {Upgraded} event.\\n */\\n function _upgradeToAndCall(\\n address newImplementation,\\n bytes memory data,\\n bool forceCall\\n ) internal {\\n _upgradeTo(newImplementation);\\n if (data.length > 0 || forceCall) {\\n Address.functionDelegateCall(newImplementation, data);\\n }\\n }\\n\\n /**\\n * @dev Perform implementation upgrade with security checks for UUPS proxies, and additional setup call.\\n *\\n * Emits an {Upgraded} event.\\n */\\n function _upgradeToAndCallUUPS(\\n address newImplementation,\\n bytes memory data,\\n bool forceCall\\n ) internal {\\n // Upgrades from old implementations will perform a rollback test. This test requires the new\\n // implementation to upgrade back to the old, non-ERC1822 compliant, implementation. Removing\\n // this special case will break upgrade paths from old UUPS implementation to new ones.\\n if (StorageSlot.getBooleanSlot(_ROLLBACK_SLOT).value) {\\n _setImplementation(newImplementation);\\n } else {\\n try IERC1822Proxiable(newImplementation).proxiableUUID() returns (bytes32 slot) {\\n require(slot == _IMPLEMENTATION_SLOT, \\\"ERC1967Upgrade: unsupported proxiableUUID\\\");\\n } catch {\\n revert(\\\"ERC1967Upgrade: new implementation is not UUPS\\\");\\n }\\n _upgradeToAndCall(newImplementation, data, forceCall);\\n }\\n }\\n\\n /**\\n * @dev Storage slot with the admin of the contract.\\n * This is the keccak-256 hash of \\\"eip1967.proxy.admin\\\" subtracted by 1, and is\\n * validated in the constructor.\\n */\\n bytes32 internal constant _ADMIN_SLOT = 0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103;\\n\\n /**\\n * @dev Emitted when the admin account has changed.\\n */\\n event AdminChanged(address previousAdmin, address newAdmin);\\n\\n /**\\n * @dev Returns the current admin.\\n */\\n function _getAdmin() internal view returns (address) {\\n return StorageSlot.getAddressSlot(_ADMIN_SLOT).value;\\n }\\n\\n /**\\n * @dev Stores a new address in the EIP1967 admin slot.\\n */\\n function _setAdmin(address newAdmin) private {\\n require(newAdmin != address(0), \\\"ERC1967: new admin is the zero address\\\");\\n StorageSlot.getAddressSlot(_ADMIN_SLOT).value = newAdmin;\\n }\\n\\n /**\\n * @dev Changes the admin of the proxy.\\n *\\n * Emits an {AdminChanged} event.\\n */\\n function _changeAdmin(address newAdmin) internal {\\n emit AdminChanged(_getAdmin(), newAdmin);\\n _setAdmin(newAdmin);\\n }\\n\\n /**\\n * @dev The storage slot of the UpgradeableBeacon contract which defines the implementation for this proxy.\\n * This is bytes32(uint256(keccak256('eip1967.proxy.beacon')) - 1)) and is validated in the constructor.\\n */\\n bytes32 internal constant _BEACON_SLOT = 0xa3f0ad74e5423aebfd80d3ef4346578335a9a72aeaee59ff6cb3582b35133d50;\\n\\n /**\\n * @dev Emitted when the beacon is upgraded.\\n */\\n event BeaconUpgraded(address indexed beacon);\\n\\n /**\\n * @dev Returns the current beacon.\\n */\\n function _getBeacon() internal view returns (address) {\\n return StorageSlot.getAddressSlot(_BEACON_SLOT).value;\\n }\\n\\n /**\\n * @dev Stores a new beacon in the EIP1967 beacon slot.\\n */\\n function _setBeacon(address newBeacon) private {\\n require(Address.isContract(newBeacon), \\\"ERC1967: new beacon is not a contract\\\");\\n require(\\n Address.isContract(IBeacon(newBeacon).implementation()),\\n \\\"ERC1967: beacon implementation is not a contract\\\"\\n );\\n StorageSlot.getAddressSlot(_BEACON_SLOT).value = newBeacon;\\n }\\n\\n /**\\n * @dev Perform beacon upgrade with additional setup call. Note: This upgrades the address of the beacon, it does\\n * not upgrade the implementation contained in the beacon (see {UpgradeableBeacon-_setImplementation} for that).\\n *\\n * Emits a {BeaconUpgraded} event.\\n */\\n function _upgradeBeaconToAndCall(\\n address newBeacon,\\n bytes memory data,\\n bool forceCall\\n ) internal {\\n _setBeacon(newBeacon);\\n emit BeaconUpgraded(newBeacon);\\n if (data.length > 0 || forceCall) {\\n Address.functionDelegateCall(IBeacon(newBeacon).implementation(), data);\\n }\\n }\\n}\\n\",\"keccak256\":\"0xabf3f59bc0e5423eae45e459dbe92e7052c6983628d39008590edc852a62f94a\",\"license\":\"MIT\"},\"@openzeppelin/contracts/proxy/Proxy.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.6.0) (proxy/Proxy.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev This abstract contract provides a fallback function that delegates all calls to another contract using the EVM\\n * instruction `delegatecall`. We refer to the second contract as the _implementation_ behind the proxy, and it has to\\n * be specified by overriding the virtual {_implementation} function.\\n *\\n * Additionally, delegation to the implementation can be triggered manually through the {_fallback} function, or to a\\n * different contract through the {_delegate} function.\\n *\\n * The success and return data of the delegated call will be returned back to the caller of the proxy.\\n */\\nabstract contract Proxy {\\n /**\\n * @dev Delegates the current call to `implementation`.\\n *\\n * This function does not return to its internal call site, it will return directly to the external caller.\\n */\\n function _delegate(address implementation) internal virtual {\\n assembly {\\n // Copy msg.data. We take full control of memory in this inline assembly\\n // block because it will not return to Solidity code. We overwrite the\\n // Solidity scratch pad at memory position 0.\\n calldatacopy(0, 0, calldatasize())\\n\\n // Call the implementation.\\n // out and outsize are 0 because we don't know the size yet.\\n let result := delegatecall(gas(), implementation, 0, calldatasize(), 0, 0)\\n\\n // Copy the returned data.\\n returndatacopy(0, 0, returndatasize())\\n\\n switch result\\n // delegatecall returns 0 on error.\\n case 0 {\\n revert(0, returndatasize())\\n }\\n default {\\n return(0, returndatasize())\\n }\\n }\\n }\\n\\n /**\\n * @dev This is a virtual function that should be overridden so it returns the address to which the fallback function\\n * and {_fallback} should delegate.\\n */\\n function _implementation() internal view virtual returns (address);\\n\\n /**\\n * @dev Delegates the current call to the address returned by `_implementation()`.\\n *\\n * This function does not return to its internal call site, it will return directly to the external caller.\\n */\\n function _fallback() internal virtual {\\n _beforeFallback();\\n _delegate(_implementation());\\n }\\n\\n /**\\n * @dev Fallback function that delegates calls to the address returned by `_implementation()`. Will run if no other\\n * function in the contract matches the call data.\\n */\\n fallback() external payable virtual {\\n _fallback();\\n }\\n\\n /**\\n * @dev Fallback function that delegates calls to the address returned by `_implementation()`. Will run if call data\\n * is empty.\\n */\\n receive() external payable virtual {\\n _fallback();\\n }\\n\\n /**\\n * @dev Hook that is called before falling back to the implementation. Can happen as part of a manual `_fallback`\\n * call, or as part of the Solidity `fallback` or `receive` functions.\\n *\\n * If overridden should call `super._beforeFallback()`.\\n */\\n function _beforeFallback() internal virtual {}\\n}\\n\",\"keccak256\":\"0xc130fe33f1b2132158531a87734153293f6d07bc263ff4ac90e85da9c82c0e27\",\"license\":\"MIT\"},\"@openzeppelin/contracts/proxy/beacon/IBeacon.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (proxy/beacon/IBeacon.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev This is the interface that {BeaconProxy} expects of its beacon.\\n */\\ninterface IBeacon {\\n /**\\n * @dev Must return an address that can be used as a delegate call target.\\n *\\n * {BeaconProxy} will check that this address is a contract.\\n */\\n function implementation() external view returns (address);\\n}\\n\",\"keccak256\":\"0xd50a3421ac379ccb1be435fa646d66a65c986b4924f0849839f08692f39dde61\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/Address.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.7.0) (utils/Address.sol)\\n\\npragma solidity ^0.8.1;\\n\\n/**\\n * @dev Collection of functions related to the address type\\n */\\nlibrary Address {\\n /**\\n * @dev Returns true if `account` is a contract.\\n *\\n * [IMPORTANT]\\n * ====\\n * It is unsafe to assume that an address for which this function returns\\n * false is an externally-owned account (EOA) and not a contract.\\n *\\n * Among others, `isContract` will return false for the following\\n * types of addresses:\\n *\\n * - an externally-owned account\\n * - a contract in construction\\n * - an address where a contract will be created\\n * - an address where a contract lived, but was destroyed\\n * ====\\n *\\n * [IMPORTANT]\\n * ====\\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\\n *\\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\\n * constructor.\\n * ====\\n */\\n function isContract(address account) internal view returns (bool) {\\n // This method relies on extcodesize/address.code.length, which returns 0\\n // for contracts in construction, since the code is only stored at the end\\n // of the constructor execution.\\n\\n return account.code.length > 0;\\n }\\n\\n /**\\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\\n * `recipient`, forwarding all available gas and reverting on errors.\\n *\\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\\n * imposed by `transfer`, making them unable to receive funds via\\n * `transfer`. {sendValue} removes this limitation.\\n *\\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\\n *\\n * IMPORTANT: because control is transferred to `recipient`, care must be\\n * taken to not create reentrancy vulnerabilities. Consider using\\n * {ReentrancyGuard} or the\\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\\n */\\n function sendValue(address payable recipient, uint256 amount) internal {\\n require(address(this).balance >= amount, \\\"Address: insufficient balance\\\");\\n\\n (bool success, ) = recipient.call{value: amount}(\\\"\\\");\\n require(success, \\\"Address: unable to send value, recipient may have reverted\\\");\\n }\\n\\n /**\\n * @dev Performs a Solidity function call using a low level `call`. A\\n * plain `call` is an unsafe replacement for a function call: use this\\n * function instead.\\n *\\n * If `target` reverts with a revert reason, it is bubbled up by this\\n * function (like regular Solidity function calls).\\n *\\n * Returns the raw returned data. To convert to the expected return value,\\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\\n *\\n * Requirements:\\n *\\n * - `target` must be a contract.\\n * - calling `target` with `data` must not revert.\\n *\\n * _Available since v3.1._\\n */\\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\\n return functionCall(target, data, \\\"Address: low-level call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\\n * `errorMessage` as a fallback revert reason when `target` reverts.\\n *\\n * _Available since v3.1._\\n */\\n function functionCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n return functionCallWithValue(target, data, 0, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but also transferring `value` wei to `target`.\\n *\\n * Requirements:\\n *\\n * - the calling contract must have an ETH balance of at least `value`.\\n * - the called Solidity function must be `payable`.\\n *\\n * _Available since v3.1._\\n */\\n function functionCallWithValue(\\n address target,\\n bytes memory data,\\n uint256 value\\n ) internal returns (bytes memory) {\\n return functionCallWithValue(target, data, value, \\\"Address: low-level call with value failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\\n * with `errorMessage` as a fallback revert reason when `target` reverts.\\n *\\n * _Available since v3.1._\\n */\\n function functionCallWithValue(\\n address target,\\n bytes memory data,\\n uint256 value,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n require(address(this).balance >= value, \\\"Address: insufficient balance for call\\\");\\n require(isContract(target), \\\"Address: call to non-contract\\\");\\n\\n (bool success, bytes memory returndata) = target.call{value: value}(data);\\n return verifyCallResult(success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but performing a static call.\\n *\\n * _Available since v3.3._\\n */\\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\\n return functionStaticCall(target, data, \\\"Address: low-level static call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\\n * but performing a static call.\\n *\\n * _Available since v3.3._\\n */\\n function functionStaticCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal view returns (bytes memory) {\\n require(isContract(target), \\\"Address: static call to non-contract\\\");\\n\\n (bool success, bytes memory returndata) = target.staticcall(data);\\n return verifyCallResult(success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but performing a delegate call.\\n *\\n * _Available since v3.4._\\n */\\n function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {\\n return functionDelegateCall(target, data, \\\"Address: low-level delegate call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\\n * but performing a delegate call.\\n *\\n * _Available since v3.4._\\n */\\n function functionDelegateCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n require(isContract(target), \\\"Address: delegate call to non-contract\\\");\\n\\n (bool success, bytes memory returndata) = target.delegatecall(data);\\n return verifyCallResult(success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the\\n * revert reason using the provided one.\\n *\\n * _Available since v4.3._\\n */\\n function verifyCallResult(\\n bool success,\\n bytes memory returndata,\\n string memory errorMessage\\n ) internal pure returns (bytes memory) {\\n if (success) {\\n return returndata;\\n } else {\\n // Look for revert reason and bubble it up if present\\n if (returndata.length > 0) {\\n // The easiest way to bubble the revert reason is using memory via assembly\\n /// @solidity memory-safe-assembly\\n assembly {\\n let returndata_size := mload(returndata)\\n revert(add(32, returndata), returndata_size)\\n }\\n } else {\\n revert(errorMessage);\\n }\\n }\\n }\\n}\\n\",\"keccak256\":\"0xd6153ce99bcdcce22b124f755e72553295be6abcd63804cfdffceb188b8bef10\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/StorageSlot.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.7.0) (utils/StorageSlot.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Library for reading and writing primitive types to specific storage slots.\\n *\\n * Storage slots are often used to avoid storage conflict when dealing with upgradeable contracts.\\n * This library helps with reading and writing to such slots without the need for inline assembly.\\n *\\n * The functions in this library return Slot structs that contain a `value` member that can be used to read or write.\\n *\\n * Example usage to set ERC1967 implementation slot:\\n * ```\\n * contract ERC1967 {\\n * bytes32 internal constant _IMPLEMENTATION_SLOT = 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc;\\n *\\n * function _getImplementation() internal view returns (address) {\\n * return StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value;\\n * }\\n *\\n * function _setImplementation(address newImplementation) internal {\\n * require(Address.isContract(newImplementation), \\\"ERC1967: new implementation is not a contract\\\");\\n * StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value = newImplementation;\\n * }\\n * }\\n * ```\\n *\\n * _Available since v4.1 for `address`, `bool`, `bytes32`, and `uint256`._\\n */\\nlibrary StorageSlot {\\n struct AddressSlot {\\n address value;\\n }\\n\\n struct BooleanSlot {\\n bool value;\\n }\\n\\n struct Bytes32Slot {\\n bytes32 value;\\n }\\n\\n struct Uint256Slot {\\n uint256 value;\\n }\\n\\n /**\\n * @dev Returns an `AddressSlot` with member `value` located at `slot`.\\n */\\n function getAddressSlot(bytes32 slot) internal pure returns (AddressSlot storage r) {\\n /// @solidity memory-safe-assembly\\n assembly {\\n r.slot := slot\\n }\\n }\\n\\n /**\\n * @dev Returns an `BooleanSlot` with member `value` located at `slot`.\\n */\\n function getBooleanSlot(bytes32 slot) internal pure returns (BooleanSlot storage r) {\\n /// @solidity memory-safe-assembly\\n assembly {\\n r.slot := slot\\n }\\n }\\n\\n /**\\n * @dev Returns an `Bytes32Slot` with member `value` located at `slot`.\\n */\\n function getBytes32Slot(bytes32 slot) internal pure returns (Bytes32Slot storage r) {\\n /// @solidity memory-safe-assembly\\n assembly {\\n r.slot := slot\\n }\\n }\\n\\n /**\\n * @dev Returns an `Uint256Slot` with member `value` located at `slot`.\\n */\\n function getUint256Slot(bytes32 slot) internal pure returns (Uint256Slot storage r) {\\n /// @solidity memory-safe-assembly\\n assembly {\\n r.slot := slot\\n }\\n }\\n}\\n\",\"keccak256\":\"0xd5c50c54bf02740ebd122ff06832546cb5fa84486d52695a9ccfd11666e0c81d\",\"license\":\"MIT\"},\"contracts/external/TransparentUpgradeableProxy.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-3.0\\n\\npragma solidity ^0.8.12;\\n\\nimport \\\"@openzeppelin/contracts/proxy/ERC1967/ERC1967Proxy.sol\\\";\\n\\n/**\\n * @dev This contract implements a proxy that is upgradeable by an admin. It is fully forked from OpenZeppelin\\n * `TransparentUpgradeableProxy`\\n *\\n * To avoid https://medium.com/nomic-labs-blog/malicious-backdoors-in-ethereum-proxies-62629adf3357[proxy selector\\n * clashing], which can potentially be used in an attack, this contract uses the\\n * https://blog.openzeppelin.com/the-transparent-proxy-pattern/[transparent proxy pattern]. This pattern implies two\\n * things that go hand in hand:\\n *\\n * 1. If any account other than the admin calls the proxy, the call will be forwarded to the implementation, even if\\n * that call matches one of the admin functions exposed by the proxy itself.\\n * 2. If the admin calls the proxy, it can access the admin functions, but its calls will never be forwarded to the\\n * implementation. If the admin tries to call a function on the implementation it will fail with an error that says\\n * \\\"admin cannot fallback to proxy target\\\".\\n *\\n * These properties mean that the admin account can only be used for admin actions like upgrading the proxy or changing\\n * the admin, so it's best if it's a dedicated account that is not used for anything else. This will avoid headaches due\\n * to sudden errors when trying to call a function from the proxy implementation.\\n *\\n * Our recommendation is for the dedicated account to be an instance of the {ProxyAdmin} contract. If set up this way,\\n * you should think of the `ProxyAdmin` instance as the real administrative interface of your proxy.\\n */\\ncontract TransparentUpgradeableProxy is ERC1967Proxy {\\n /**\\n * @dev Initializes an upgradeable proxy managed by `_admin`, backed by the implementation at `_logic`, and\\n * optionally initialized with `_data` as explained in {ERC1967Proxy-constructor}.\\n */\\n constructor(address _logic, address admin_, bytes memory _data) payable ERC1967Proxy(_logic, _data) {\\n assert(_ADMIN_SLOT == bytes32(uint256(keccak256(\\\"eip1967.proxy.admin\\\")) - 1));\\n _changeAdmin(admin_);\\n }\\n\\n /**\\n * @dev Modifier used internally that will delegate the call to the implementation unless the sender is the admin.\\n */\\n modifier ifAdmin() {\\n if (msg.sender == _getAdmin()) {\\n _;\\n } else {\\n _fallback();\\n }\\n }\\n\\n /**\\n * @dev Returns the current admin.\\n *\\n * NOTE: Only the admin can call this function. See {ProxyAdmin-getProxyAdmin}.\\n *\\n * TIP: To get this value clients can read directly from the storage slot shown below (specified by EIP1967) using the\\n * https://eth.wiki/json-rpc/API#eth_getstorageat[`eth_getStorageAt`] RPC call.\\n * `0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103`\\n */\\n function admin() external ifAdmin returns (address admin_) {\\n admin_ = _getAdmin();\\n }\\n\\n /**\\n * @dev Returns the current implementation.\\n *\\n * NOTE: Only the admin can call this function. See {ProxyAdmin-getProxyImplementation}.\\n *\\n * TIP: To get this value clients can read directly from the storage slot shown below (specified by EIP1967) using the\\n * https://eth.wiki/json-rpc/API#eth_getstorageat[`eth_getStorageAt`] RPC call.\\n * `0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc`\\n */\\n function implementation() external ifAdmin returns (address implementation_) {\\n implementation_ = _implementation();\\n }\\n\\n /**\\n * @dev Changes the admin of the proxy.\\n *\\n * Emits an {AdminChanged} event.\\n *\\n * NOTE: Only the admin can call this function. See {ProxyAdmin-changeProxyAdmin}.\\n */\\n function changeAdmin(address newAdmin) external virtual ifAdmin {\\n _changeAdmin(newAdmin);\\n }\\n\\n /**\\n * @dev Upgrade the implementation of the proxy.\\n *\\n * NOTE: Only the admin can call this function. See {ProxyAdmin-upgrade}.\\n */\\n function upgradeTo(address newImplementation) external ifAdmin {\\n _upgradeToAndCall(newImplementation, bytes(\\\"\\\"), false);\\n }\\n\\n /**\\n * @dev Upgrade the implementation of the proxy, and then call a function from the new implementation as specified\\n * by `data`, which should be an encoded function call. This is useful to initialize new storage variables in the\\n * proxied contract.\\n *\\n * NOTE: Only the admin can call this function. See {ProxyAdmin-upgradeAndCall}.\\n */\\n function upgradeToAndCall(address newImplementation, bytes calldata data) external payable ifAdmin {\\n _upgradeToAndCall(newImplementation, data, true);\\n }\\n\\n /**\\n * @dev Returns the current admin.\\n */\\n function _admin() internal view virtual returns (address) {\\n return _getAdmin();\\n }\\n\\n /**\\n * @dev Makes sure the admin cannot access the fallback function. See {Proxy-_beforeFallback}.\\n */\\n function _beforeFallback() internal virtual override {\\n require(msg.sender != _getAdmin(), \\\"TransparentUpgradeableProxy: admin cannot fallback to proxy target\\\");\\n super._beforeFallback();\\n }\\n}\\n\",\"keccak256\":\"0x93a67a0f612ea3ff2a76315e138a6a88267270a1379d3cc7be52845fbbe611e2\",\"license\":\"GPL-3.0\"}},\"version\":1}", + "bytecode": "0x6080604052604051620010bb380380620010bb8339810160408190526200002691620004d8565b828162000036828260006200009a565b5062000066905060017fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6104620005b8565b6000805160206200107483398151915214620000865762000086620005da565b6200009182620000d7565b50505062000643565b620000a58362000132565b600082511180620000b35750805b15620000d257620000d083836200017460201b6200028c1760201c565b505b505050565b7f7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f62000102620001a5565b604080516001600160a01b03928316815291841660208301520160405180910390a16200012f81620001de565b50565b6200013d8162000293565b6040516001600160a01b038216907fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b90600090a250565b60606200019c8383604051806060016040528060278152602001620010946027913962000347565b90505b92915050565b6000620001cf6000805160206200107483398151915260001b6200042f60201b6200022e1760201c565b546001600160a01b0316919050565b6001600160a01b038116620002495760405162461bcd60e51b815260206004820152602660248201527f455243313936373a206e65772061646d696e20697320746865207a65726f206160448201526564647265737360d01b60648201526084015b60405180910390fd5b80620002726000805160206200107483398151915260001b6200042f60201b6200022e1760201c565b80546001600160a01b0319166001600160a01b039290921691909117905550565b620002a9816200043260201b620002b81760201c565b6200030d5760405162461bcd60e51b815260206004820152602d60248201527f455243313936373a206e657720696d706c656d656e746174696f6e206973206e60448201526c1bdd08184818dbdb9d1c9858dd609a1b606482015260840162000240565b80620002727f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc60001b6200042f60201b6200022e1760201c565b60606001600160a01b0384163b620003b15760405162461bcd60e51b815260206004820152602660248201527f416464726573733a2064656c65676174652063616c6c20746f206e6f6e2d636f6044820152651b9d1c9858dd60d21b606482015260840162000240565b600080856001600160a01b031685604051620003ce9190620005f0565b600060405180830381855af49150503d80600081146200040b576040519150601f19603f3d011682016040523d82523d6000602084013e62000410565b606091505b5090925090506200042382828662000441565b925050505b9392505050565b90565b6001600160a01b03163b151590565b606083156200045257508162000428565b825115620004635782518084602001fd5b8160405162461bcd60e51b81526004016200024091906200060e565b80516001600160a01b03811681146200049757600080fd5b919050565b634e487b7160e01b600052604160045260246000fd5b60005b83811015620004cf578181015183820152602001620004b5565b50506000910152565b600080600060608486031215620004ee57600080fd5b620004f9846200047f565b925062000509602085016200047f565b60408501519092506001600160401b03808211156200052757600080fd5b818601915086601f8301126200053c57600080fd5b8151818111156200055157620005516200049c565b604051601f8201601f19908116603f011681019083821181831017156200057c576200057c6200049c565b816040528281528960208487010111156200059657600080fd5b620005a9836020830160208801620004b2565b80955050505050509250925092565b818103818111156200019f57634e487b7160e01b600052601160045260246000fd5b634e487b7160e01b600052600160045260246000fd5b6000825162000604818460208701620004b2565b9190910192915050565b60208152600082518060208401526200062f816040850160208701620004b2565b601f01601f19169190910160400192915050565b610a2180620006536000396000f3fe60806040526004361061005e5760003560e01c80635c60da1b116100435780635c60da1b146100a85780638f283970146100e6578063f851a440146101065761006d565b80633659cfe6146100755780634f1ef286146100955761006d565b3661006d5761006b61011b565b005b61006b61011b565b34801561008157600080fd5b5061006b610090366004610895565b610135565b61006b6100a33660046108b0565b61017f565b3480156100b457600080fd5b506100bd6101f3565b60405173ffffffffffffffffffffffffffffffffffffffff909116815260200160405180910390f35b3480156100f257600080fd5b5061006b610101366004610895565b610231565b34801561011257600080fd5b506100bd61025e565b6101236102d4565b61013361012e6103ab565b6103b5565b565b61013d6103d9565b73ffffffffffffffffffffffffffffffffffffffff1633036101775761017481604051806020016040528060008152506000610419565b50565b61017461011b565b6101876103d9565b73ffffffffffffffffffffffffffffffffffffffff1633036101eb576101e68383838080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525060019250610419915050565b505050565b6101e661011b565b60006101fd6103d9565b73ffffffffffffffffffffffffffffffffffffffff163303610226576102216103ab565b905090565b61022e61011b565b90565b6102396103d9565b73ffffffffffffffffffffffffffffffffffffffff1633036101775761017481610444565b60006102686103d9565b73ffffffffffffffffffffffffffffffffffffffff163303610226576102216103d9565b60606102b183836040518060600160405280602781526020016109c5602791396104a5565b9392505050565b73ffffffffffffffffffffffffffffffffffffffff163b151590565b6102dc6103d9565b73ffffffffffffffffffffffffffffffffffffffff163303610133576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604260248201527f5472616e73706172656e745570677261646561626c6550726f78793a2061646d60448201527f696e2063616e6e6f742066616c6c6261636b20746f2070726f7879207461726760648201527f6574000000000000000000000000000000000000000000000000000000000000608482015260a4015b60405180910390fd5b60006102216105cd565b3660008037600080366000845af43d6000803e8080156103d4573d6000f35b3d6000fd5b60007fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035b5473ffffffffffffffffffffffffffffffffffffffff16919050565b610422836105f5565b60008251118061042f5750805b156101e65761043e838361028c565b50505050565b7f7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f61046d6103d9565b6040805173ffffffffffffffffffffffffffffffffffffffff928316815291841660208301520160405180910390a161017481610642565b606073ffffffffffffffffffffffffffffffffffffffff84163b61054b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f416464726573733a2064656c65676174652063616c6c20746f206e6f6e2d636f60448201527f6e7472616374000000000000000000000000000000000000000000000000000060648201526084016103a2565b6000808573ffffffffffffffffffffffffffffffffffffffff16856040516105739190610957565b600060405180830381855af49150503d80600081146105ae576040519150601f19603f3d011682016040523d82523d6000602084013e6105b3565b606091505b50915091506105c382828661074e565b9695505050505050565b60007f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc6103fd565b6105fe816107a1565b60405173ffffffffffffffffffffffffffffffffffffffff8216907fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b90600090a250565b73ffffffffffffffffffffffffffffffffffffffff81166106e5576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f455243313936373a206e65772061646d696e20697320746865207a65726f206160448201527f646472657373000000000000000000000000000000000000000000000000000060648201526084016103a2565b807fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035b80547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff9290921691909117905550565b6060831561075d5750816102b1565b82511561076d5782518084602001fd5b816040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016103a29190610973565b73ffffffffffffffffffffffffffffffffffffffff81163b610845576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602d60248201527f455243313936373a206e657720696d706c656d656e746174696f6e206973206e60448201527f6f74206120636f6e74726163740000000000000000000000000000000000000060648201526084016103a2565b807f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc610708565b803573ffffffffffffffffffffffffffffffffffffffff8116811461089057600080fd5b919050565b6000602082840312156108a757600080fd5b6102b18261086c565b6000806000604084860312156108c557600080fd5b6108ce8461086c565b9250602084013567ffffffffffffffff808211156108eb57600080fd5b818601915086601f8301126108ff57600080fd5b81358181111561090e57600080fd5b87602082850101111561092057600080fd5b6020830194508093505050509250925092565b60005b8381101561094e578181015183820152602001610936565b50506000910152565b60008251610969818460208701610933565b9190910192915050565b6020815260008251806020840152610992816040850160208701610933565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016919091016040019291505056fe416464726573733a206c6f772d6c6576656c2064656c65676174652063616c6c206661696c6564a2646970667358221220e96638b07fb1675d93a95c49e417bc8111448b23a59918698cdcd8fd488dd7cf64736f6c63430008110033b53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103416464726573733a206c6f772d6c6576656c2064656c65676174652063616c6c206661696c6564", + "deployedBytecode": "0x60806040526004361061005e5760003560e01c80635c60da1b116100435780635c60da1b146100a85780638f283970146100e6578063f851a440146101065761006d565b80633659cfe6146100755780634f1ef286146100955761006d565b3661006d5761006b61011b565b005b61006b61011b565b34801561008157600080fd5b5061006b610090366004610895565b610135565b61006b6100a33660046108b0565b61017f565b3480156100b457600080fd5b506100bd6101f3565b60405173ffffffffffffffffffffffffffffffffffffffff909116815260200160405180910390f35b3480156100f257600080fd5b5061006b610101366004610895565b610231565b34801561011257600080fd5b506100bd61025e565b6101236102d4565b61013361012e6103ab565b6103b5565b565b61013d6103d9565b73ffffffffffffffffffffffffffffffffffffffff1633036101775761017481604051806020016040528060008152506000610419565b50565b61017461011b565b6101876103d9565b73ffffffffffffffffffffffffffffffffffffffff1633036101eb576101e68383838080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525060019250610419915050565b505050565b6101e661011b565b60006101fd6103d9565b73ffffffffffffffffffffffffffffffffffffffff163303610226576102216103ab565b905090565b61022e61011b565b90565b6102396103d9565b73ffffffffffffffffffffffffffffffffffffffff1633036101775761017481610444565b60006102686103d9565b73ffffffffffffffffffffffffffffffffffffffff163303610226576102216103d9565b60606102b183836040518060600160405280602781526020016109c5602791396104a5565b9392505050565b73ffffffffffffffffffffffffffffffffffffffff163b151590565b6102dc6103d9565b73ffffffffffffffffffffffffffffffffffffffff163303610133576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604260248201527f5472616e73706172656e745570677261646561626c6550726f78793a2061646d60448201527f696e2063616e6e6f742066616c6c6261636b20746f2070726f7879207461726760648201527f6574000000000000000000000000000000000000000000000000000000000000608482015260a4015b60405180910390fd5b60006102216105cd565b3660008037600080366000845af43d6000803e8080156103d4573d6000f35b3d6000fd5b60007fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035b5473ffffffffffffffffffffffffffffffffffffffff16919050565b610422836105f5565b60008251118061042f5750805b156101e65761043e838361028c565b50505050565b7f7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f61046d6103d9565b6040805173ffffffffffffffffffffffffffffffffffffffff928316815291841660208301520160405180910390a161017481610642565b606073ffffffffffffffffffffffffffffffffffffffff84163b61054b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f416464726573733a2064656c65676174652063616c6c20746f206e6f6e2d636f60448201527f6e7472616374000000000000000000000000000000000000000000000000000060648201526084016103a2565b6000808573ffffffffffffffffffffffffffffffffffffffff16856040516105739190610957565b600060405180830381855af49150503d80600081146105ae576040519150601f19603f3d011682016040523d82523d6000602084013e6105b3565b606091505b50915091506105c382828661074e565b9695505050505050565b60007f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc6103fd565b6105fe816107a1565b60405173ffffffffffffffffffffffffffffffffffffffff8216907fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b90600090a250565b73ffffffffffffffffffffffffffffffffffffffff81166106e5576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f455243313936373a206e65772061646d696e20697320746865207a65726f206160448201527f646472657373000000000000000000000000000000000000000000000000000060648201526084016103a2565b807fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035b80547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff9290921691909117905550565b6060831561075d5750816102b1565b82511561076d5782518084602001fd5b816040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016103a29190610973565b73ffffffffffffffffffffffffffffffffffffffff81163b610845576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602d60248201527f455243313936373a206e657720696d706c656d656e746174696f6e206973206e60448201527f6f74206120636f6e74726163740000000000000000000000000000000000000060648201526084016103a2565b807f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc610708565b803573ffffffffffffffffffffffffffffffffffffffff8116811461089057600080fd5b919050565b6000602082840312156108a757600080fd5b6102b18261086c565b6000806000604084860312156108c557600080fd5b6108ce8461086c565b9250602084013567ffffffffffffffff808211156108eb57600080fd5b818601915086601f8301126108ff57600080fd5b81358181111561090e57600080fd5b87602082850101111561092057600080fd5b6020830194508093505050509250925092565b60005b8381101561094e578181015183820152602001610936565b50506000910152565b60008251610969818460208701610933565b9190910192915050565b6020815260008251806020840152610992816040850160208701610933565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016919091016040019291505056fe416464726573733a206c6f772d6c6576656c2064656c65676174652063616c6c206661696c6564a2646970667358221220e96638b07fb1675d93a95c49e417bc8111448b23a59918698cdcd8fd488dd7cf64736f6c63430008110033", + "devdoc": { + "details": "This contract implements a proxy that is upgradeable by an admin. It is fully forked from OpenZeppelin `TransparentUpgradeableProxy` To avoid https://medium.com/nomic-labs-blog/malicious-backdoors-in-ethereum-proxies-62629adf3357[proxy selector clashing], which can potentially be used in an attack, this contract uses the https://blog.openzeppelin.com/the-transparent-proxy-pattern/[transparent proxy pattern]. This pattern implies two things that go hand in hand: 1. If any account other than the admin calls the proxy, the call will be forwarded to the implementation, even if that call matches one of the admin functions exposed by the proxy itself. 2. If the admin calls the proxy, it can access the admin functions, but its calls will never be forwarded to the implementation. If the admin tries to call a function on the implementation it will fail with an error that says \"admin cannot fallback to proxy target\". These properties mean that the admin account can only be used for admin actions like upgrading the proxy or changing the admin, so it's best if it's a dedicated account that is not used for anything else. This will avoid headaches due to sudden errors when trying to call a function from the proxy implementation. Our recommendation is for the dedicated account to be an instance of the {ProxyAdmin} contract. If set up this way, you should think of the `ProxyAdmin` instance as the real administrative interface of your proxy.", + "kind": "dev", + "methods": { + "admin()": { + "details": "Returns the current admin. NOTE: Only the admin can call this function. See {ProxyAdmin-getProxyAdmin}. TIP: To get this value clients can read directly from the storage slot shown below (specified by EIP1967) using the https://eth.wiki/json-rpc/API#eth_getstorageat[`eth_getStorageAt`] RPC call. `0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103`" + }, + "changeAdmin(address)": { + "details": "Changes the admin of the proxy. Emits an {AdminChanged} event. NOTE: Only the admin can call this function. See {ProxyAdmin-changeProxyAdmin}." + }, + "constructor": { + "details": "Initializes an upgradeable proxy managed by `_admin`, backed by the implementation at `_logic`, and optionally initialized with `_data` as explained in {ERC1967Proxy-constructor}." + }, + "implementation()": { + "details": "Returns the current implementation. NOTE: Only the admin can call this function. See {ProxyAdmin-getProxyImplementation}. TIP: To get this value clients can read directly from the storage slot shown below (specified by EIP1967) using the https://eth.wiki/json-rpc/API#eth_getstorageat[`eth_getStorageAt`] RPC call. `0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc`" + }, + "upgradeTo(address)": { + "details": "Upgrade the implementation of the proxy. NOTE: Only the admin can call this function. See {ProxyAdmin-upgrade}." + }, + "upgradeToAndCall(address,bytes)": { + "details": "Upgrade the implementation of the proxy, and then call a function from the new implementation as specified by `data`, which should be an encoded function call. This is useful to initialize new storage variables in the proxied contract. NOTE: Only the admin can call this function. See {ProxyAdmin-upgradeAndCall}." + } + }, + "version": 1 + }, + "userdoc": { + "kind": "user", + "methods": {}, + "version": 1 + }, + "storageLayout": { + "storage": [], + "types": null + } +} \ No newline at end of file diff --git a/deployments/optimism/LayerZeroBridge_USD_Old.json b/deployments/optimism/LayerZeroBridge_USD_Old.json new file mode 100644 index 00000000..e55bc99b --- /dev/null +++ b/deployments/optimism/LayerZeroBridge_USD_Old.json @@ -0,0 +1,275 @@ +{ + "address": "0xcF6cF33e5Cbd20548e8fC4F2c75bB0d9f336b45B", + "abi": [ + { + "inputs": [ + { + "internalType": "address", + "name": "_logic", + "type": "address" + }, + { + "internalType": "address", + "name": "admin_", + "type": "address" + }, + { + "internalType": "bytes", + "name": "_data", + "type": "bytes" + } + ], + "stateMutability": "payable", + "type": "constructor" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "previousAdmin", + "type": "address" + }, + { + "indexed": false, + "internalType": "address", + "name": "newAdmin", + "type": "address" + } + ], + "name": "AdminChanged", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "beacon", + "type": "address" + } + ], + "name": "BeaconUpgraded", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "implementation", + "type": "address" + } + ], + "name": "Upgraded", + "type": "event" + }, + { + "stateMutability": "payable", + "type": "fallback" + }, + { + "inputs": [], + "name": "admin", + "outputs": [ + { + "internalType": "address", + "name": "admin_", + "type": "address" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "newAdmin", + "type": "address" + } + ], + "name": "changeAdmin", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "implementation", + "outputs": [ + { + "internalType": "address", + "name": "implementation_", + "type": "address" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "newImplementation", + "type": "address" + } + ], + "name": "upgradeTo", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "newImplementation", + "type": "address" + }, + { + "internalType": "bytes", + "name": "data", + "type": "bytes" + } + ], + "name": "upgradeToAndCall", + "outputs": [], + "stateMutability": "payable", + "type": "function" + }, + { + "stateMutability": "payable", + "type": "receive" + } + ], + "transactionHash": "0x61b4219c6d55122553546bf000f428afedb2af558ae816ba3320bfde224047eb", + "receipt": { + "to": null, + "from": "0xfdA462548Ce04282f4B6D6619823a7C64Fdc0185", + "contractAddress": "0xcF6cF33e5Cbd20548e8fC4F2c75bB0d9f336b45B", + "transactionIndex": 4, + "gasUsed": "849932", + "logsBloom": "0x00000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000000000000800000000004000000200000000004000000000400000008000022000000000000000200000000000500000000000000020000000000000000000800000000800000000000000010000000000000040000000000000000000000040000000000000080000000000000800000020000000000000000000000000400000000000000000000000000000000000000004022000000000000000000040000000000000400000000000000400020000010000000000000000000000000000000000000000000000000000000000000", + "blockHash": "0x20f999e751cad96ed597d028f659120097770a99ebcea2cc7391e4082b58108c", + "transactionHash": "0x61b4219c6d55122553546bf000f428afedb2af558ae816ba3320bfde224047eb", + "logs": [ + { + "transactionIndex": 4, + "blockNumber": 114643696, + "transactionHash": "0x61b4219c6d55122553546bf000f428afedb2af558ae816ba3320bfde224047eb", + "address": "0xcF6cF33e5Cbd20548e8fC4F2c75bB0d9f336b45B", + "topics": [ + "0xbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b", + "0x000000000000000000000000288320624972877cd64a1cb98d1342e7e1785024" + ], + "data": "0x", + "logIndex": 0, + "blockHash": "0x20f999e751cad96ed597d028f659120097770a99ebcea2cc7391e4082b58108c" + }, + { + "transactionIndex": 4, + "blockNumber": 114643696, + "transactionHash": "0x61b4219c6d55122553546bf000f428afedb2af558ae816ba3320bfde224047eb", + "address": "0xcF6cF33e5Cbd20548e8fC4F2c75bB0d9f336b45B", + "topics": [ + "0x8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925", + "0x000000000000000000000000cf6cf33e5cbd20548e8fc4f2c75bb0d9f336b45b", + "0x0000000000000000000000000000206329b97db379d5e1bf586bbdb969c63274" + ], + "data": "0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", + "logIndex": 1, + "blockHash": "0x20f999e751cad96ed597d028f659120097770a99ebcea2cc7391e4082b58108c" + }, + { + "transactionIndex": 4, + "blockNumber": 114643696, + "transactionHash": "0x61b4219c6d55122553546bf000f428afedb2af558ae816ba3320bfde224047eb", + "address": "0xcF6cF33e5Cbd20548e8fC4F2c75bB0d9f336b45B", + "topics": [ + "0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000206329b97db379d5e1bf586bbdb969c63274" + ], + "data": "0x0000000000000000000000000000000000000000000000000000000000000000", + "logIndex": 2, + "blockHash": "0x20f999e751cad96ed597d028f659120097770a99ebcea2cc7391e4082b58108c" + }, + { + "transactionIndex": 4, + "blockNumber": 114643696, + "transactionHash": "0x61b4219c6d55122553546bf000f428afedb2af558ae816ba3320bfde224047eb", + "address": "0xcF6cF33e5Cbd20548e8fC4F2c75bB0d9f336b45B", + "topics": [ + "0x7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb3847402498" + ], + "data": "0x0000000000000000000000000000000000000000000000000000000000000001", + "logIndex": 3, + "blockHash": "0x20f999e751cad96ed597d028f659120097770a99ebcea2cc7391e4082b58108c" + }, + { + "transactionIndex": 4, + "blockNumber": 114643696, + "transactionHash": "0x61b4219c6d55122553546bf000f428afedb2af558ae816ba3320bfde224047eb", + "address": "0xcF6cF33e5Cbd20548e8fC4F2c75bB0d9f336b45B", + "topics": [ + "0x7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f" + ], + "data": "0x0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000c16b81af351ba9e64c1a069e3ab18c244a1e3049", + "logIndex": 4, + "blockHash": "0x20f999e751cad96ed597d028f659120097770a99ebcea2cc7391e4082b58108c" + } + ], + "blockNumber": 114643696, + "cumulativeGasUsed": "966409", + "status": 1, + "byzantium": true + }, + "args": [ + "0x288320624972877Cd64A1CB98D1342E7e1785024", + "0xC16B81Af351BA9e64C1a069E3Ab18c244A1E3049", + "0xc9aba0aa00000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000000e000000000000000000000000066a71dcef29a0ffbdbe3c6a460a3b5bc225cd675000000000000000000000000770f7cdfae5ecaa3a0538da7cb1d6c8f22252fe0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000164c617965725a65726f204272696467652061675553440000000000000000000000000000000000000000000000000000000000000000000000000000000000084c5a2d6167555344000000000000000000000000000000000000000000000000" + ], + "numDeployments": 1, + "solcInputHash": "871924e0c138825a2736b76def8fef8d", + "metadata": "{\"compiler\":{\"version\":\"0.8.17+commit.8df45f5f\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_logic\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"admin_\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"_data\",\"type\":\"bytes\"}],\"stateMutability\":\"payable\",\"type\":\"constructor\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"previousAdmin\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"newAdmin\",\"type\":\"address\"}],\"name\":\"AdminChanged\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"beacon\",\"type\":\"address\"}],\"name\":\"BeaconUpgraded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"implementation\",\"type\":\"address\"}],\"name\":\"Upgraded\",\"type\":\"event\"},{\"stateMutability\":\"payable\",\"type\":\"fallback\"},{\"inputs\":[],\"name\":\"admin\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"admin_\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newAdmin\",\"type\":\"address\"}],\"name\":\"changeAdmin\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"implementation\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"implementation_\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newImplementation\",\"type\":\"address\"}],\"name\":\"upgradeTo\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newImplementation\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"}],\"name\":\"upgradeToAndCall\",\"outputs\":[],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"stateMutability\":\"payable\",\"type\":\"receive\"}],\"devdoc\":{\"details\":\"This contract implements a proxy that is upgradeable by an admin. It is fully forked from OpenZeppelin `TransparentUpgradeableProxy` To avoid https://medium.com/nomic-labs-blog/malicious-backdoors-in-ethereum-proxies-62629adf3357[proxy selector clashing], which can potentially be used in an attack, this contract uses the https://blog.openzeppelin.com/the-transparent-proxy-pattern/[transparent proxy pattern]. This pattern implies two things that go hand in hand: 1. If any account other than the admin calls the proxy, the call will be forwarded to the implementation, even if that call matches one of the admin functions exposed by the proxy itself. 2. If the admin calls the proxy, it can access the admin functions, but its calls will never be forwarded to the implementation. If the admin tries to call a function on the implementation it will fail with an error that says \\\"admin cannot fallback to proxy target\\\". These properties mean that the admin account can only be used for admin actions like upgrading the proxy or changing the admin, so it's best if it's a dedicated account that is not used for anything else. This will avoid headaches due to sudden errors when trying to call a function from the proxy implementation. Our recommendation is for the dedicated account to be an instance of the {ProxyAdmin} contract. If set up this way, you should think of the `ProxyAdmin` instance as the real administrative interface of your proxy.\",\"kind\":\"dev\",\"methods\":{\"admin()\":{\"details\":\"Returns the current admin. NOTE: Only the admin can call this function. See {ProxyAdmin-getProxyAdmin}. TIP: To get this value clients can read directly from the storage slot shown below (specified by EIP1967) using the https://eth.wiki/json-rpc/API#eth_getstorageat[`eth_getStorageAt`] RPC call. `0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103`\"},\"changeAdmin(address)\":{\"details\":\"Changes the admin of the proxy. Emits an {AdminChanged} event. NOTE: Only the admin can call this function. See {ProxyAdmin-changeProxyAdmin}.\"},\"constructor\":{\"details\":\"Initializes an upgradeable proxy managed by `_admin`, backed by the implementation at `_logic`, and optionally initialized with `_data` as explained in {ERC1967Proxy-constructor}.\"},\"implementation()\":{\"details\":\"Returns the current implementation. NOTE: Only the admin can call this function. See {ProxyAdmin-getProxyImplementation}. TIP: To get this value clients can read directly from the storage slot shown below (specified by EIP1967) using the https://eth.wiki/json-rpc/API#eth_getstorageat[`eth_getStorageAt`] RPC call. `0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc`\"},\"upgradeTo(address)\":{\"details\":\"Upgrade the implementation of the proxy. NOTE: Only the admin can call this function. See {ProxyAdmin-upgrade}.\"},\"upgradeToAndCall(address,bytes)\":{\"details\":\"Upgrade the implementation of the proxy, and then call a function from the new implementation as specified by `data`, which should be an encoded function call. This is useful to initialize new storage variables in the proxied contract. NOTE: Only the admin can call this function. See {ProxyAdmin-upgradeAndCall}.\"}},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/external/TransparentUpgradeableProxy.sol\":\"TransparentUpgradeableProxy\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":1000000},\"remappings\":[]},\"sources\":{\"@openzeppelin/contracts/interfaces/draft-IERC1822.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.5.0) (interfaces/draft-IERC1822.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev ERC1822: Universal Upgradeable Proxy Standard (UUPS) documents a method for upgradeability through a simplified\\n * proxy whose upgrades are fully controlled by the current implementation.\\n */\\ninterface IERC1822Proxiable {\\n /**\\n * @dev Returns the storage slot that the proxiable contract assumes is being used to store the implementation\\n * address.\\n *\\n * IMPORTANT: A proxy pointing at a proxiable contract should not be considered proxiable itself, because this risks\\n * bricking a proxy that upgrades to it, by delegating to itself until out of gas. Thus it is critical that this\\n * function revert if invoked through a proxy.\\n */\\n function proxiableUUID() external view returns (bytes32);\\n}\\n\",\"keccak256\":\"0x1d4afe6cb24200cc4545eed814ecf5847277dfe5d613a1707aad5fceecebcfff\",\"license\":\"MIT\"},\"@openzeppelin/contracts/proxy/ERC1967/ERC1967Proxy.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.7.0) (proxy/ERC1967/ERC1967Proxy.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../Proxy.sol\\\";\\nimport \\\"./ERC1967Upgrade.sol\\\";\\n\\n/**\\n * @dev This contract implements an upgradeable proxy. It is upgradeable because calls are delegated to an\\n * implementation address that can be changed. This address is stored in storage in the location specified by\\n * https://eips.ethereum.org/EIPS/eip-1967[EIP1967], so that it doesn't conflict with the storage layout of the\\n * implementation behind the proxy.\\n */\\ncontract ERC1967Proxy is Proxy, ERC1967Upgrade {\\n /**\\n * @dev Initializes the upgradeable proxy with an initial implementation specified by `_logic`.\\n *\\n * If `_data` is nonempty, it's used as data in a delegate call to `_logic`. This will typically be an encoded\\n * function call, and allows initializing the storage of the proxy like a Solidity constructor.\\n */\\n constructor(address _logic, bytes memory _data) payable {\\n _upgradeToAndCall(_logic, _data, false);\\n }\\n\\n /**\\n * @dev Returns the current implementation address.\\n */\\n function _implementation() internal view virtual override returns (address impl) {\\n return ERC1967Upgrade._getImplementation();\\n }\\n}\\n\",\"keccak256\":\"0xa2b22da3032e50b55f95ec1d13336102d675f341167aa76db571ef7f8bb7975d\",\"license\":\"MIT\"},\"@openzeppelin/contracts/proxy/ERC1967/ERC1967Upgrade.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.5.0) (proxy/ERC1967/ERC1967Upgrade.sol)\\n\\npragma solidity ^0.8.2;\\n\\nimport \\\"../beacon/IBeacon.sol\\\";\\nimport \\\"../../interfaces/draft-IERC1822.sol\\\";\\nimport \\\"../../utils/Address.sol\\\";\\nimport \\\"../../utils/StorageSlot.sol\\\";\\n\\n/**\\n * @dev This abstract contract provides getters and event emitting update functions for\\n * https://eips.ethereum.org/EIPS/eip-1967[EIP1967] slots.\\n *\\n * _Available since v4.1._\\n *\\n * @custom:oz-upgrades-unsafe-allow delegatecall\\n */\\nabstract contract ERC1967Upgrade {\\n // This is the keccak-256 hash of \\\"eip1967.proxy.rollback\\\" subtracted by 1\\n bytes32 private constant _ROLLBACK_SLOT = 0x4910fdfa16fed3260ed0e7147f7cc6da11a60208b5b9406d12a635614ffd9143;\\n\\n /**\\n * @dev Storage slot with the address of the current implementation.\\n * This is the keccak-256 hash of \\\"eip1967.proxy.implementation\\\" subtracted by 1, and is\\n * validated in the constructor.\\n */\\n bytes32 internal constant _IMPLEMENTATION_SLOT = 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc;\\n\\n /**\\n * @dev Emitted when the implementation is upgraded.\\n */\\n event Upgraded(address indexed implementation);\\n\\n /**\\n * @dev Returns the current implementation address.\\n */\\n function _getImplementation() internal view returns (address) {\\n return StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value;\\n }\\n\\n /**\\n * @dev Stores a new address in the EIP1967 implementation slot.\\n */\\n function _setImplementation(address newImplementation) private {\\n require(Address.isContract(newImplementation), \\\"ERC1967: new implementation is not a contract\\\");\\n StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value = newImplementation;\\n }\\n\\n /**\\n * @dev Perform implementation upgrade\\n *\\n * Emits an {Upgraded} event.\\n */\\n function _upgradeTo(address newImplementation) internal {\\n _setImplementation(newImplementation);\\n emit Upgraded(newImplementation);\\n }\\n\\n /**\\n * @dev Perform implementation upgrade with additional setup call.\\n *\\n * Emits an {Upgraded} event.\\n */\\n function _upgradeToAndCall(\\n address newImplementation,\\n bytes memory data,\\n bool forceCall\\n ) internal {\\n _upgradeTo(newImplementation);\\n if (data.length > 0 || forceCall) {\\n Address.functionDelegateCall(newImplementation, data);\\n }\\n }\\n\\n /**\\n * @dev Perform implementation upgrade with security checks for UUPS proxies, and additional setup call.\\n *\\n * Emits an {Upgraded} event.\\n */\\n function _upgradeToAndCallUUPS(\\n address newImplementation,\\n bytes memory data,\\n bool forceCall\\n ) internal {\\n // Upgrades from old implementations will perform a rollback test. This test requires the new\\n // implementation to upgrade back to the old, non-ERC1822 compliant, implementation. Removing\\n // this special case will break upgrade paths from old UUPS implementation to new ones.\\n if (StorageSlot.getBooleanSlot(_ROLLBACK_SLOT).value) {\\n _setImplementation(newImplementation);\\n } else {\\n try IERC1822Proxiable(newImplementation).proxiableUUID() returns (bytes32 slot) {\\n require(slot == _IMPLEMENTATION_SLOT, \\\"ERC1967Upgrade: unsupported proxiableUUID\\\");\\n } catch {\\n revert(\\\"ERC1967Upgrade: new implementation is not UUPS\\\");\\n }\\n _upgradeToAndCall(newImplementation, data, forceCall);\\n }\\n }\\n\\n /**\\n * @dev Storage slot with the admin of the contract.\\n * This is the keccak-256 hash of \\\"eip1967.proxy.admin\\\" subtracted by 1, and is\\n * validated in the constructor.\\n */\\n bytes32 internal constant _ADMIN_SLOT = 0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103;\\n\\n /**\\n * @dev Emitted when the admin account has changed.\\n */\\n event AdminChanged(address previousAdmin, address newAdmin);\\n\\n /**\\n * @dev Returns the current admin.\\n */\\n function _getAdmin() internal view returns (address) {\\n return StorageSlot.getAddressSlot(_ADMIN_SLOT).value;\\n }\\n\\n /**\\n * @dev Stores a new address in the EIP1967 admin slot.\\n */\\n function _setAdmin(address newAdmin) private {\\n require(newAdmin != address(0), \\\"ERC1967: new admin is the zero address\\\");\\n StorageSlot.getAddressSlot(_ADMIN_SLOT).value = newAdmin;\\n }\\n\\n /**\\n * @dev Changes the admin of the proxy.\\n *\\n * Emits an {AdminChanged} event.\\n */\\n function _changeAdmin(address newAdmin) internal {\\n emit AdminChanged(_getAdmin(), newAdmin);\\n _setAdmin(newAdmin);\\n }\\n\\n /**\\n * @dev The storage slot of the UpgradeableBeacon contract which defines the implementation for this proxy.\\n * This is bytes32(uint256(keccak256('eip1967.proxy.beacon')) - 1)) and is validated in the constructor.\\n */\\n bytes32 internal constant _BEACON_SLOT = 0xa3f0ad74e5423aebfd80d3ef4346578335a9a72aeaee59ff6cb3582b35133d50;\\n\\n /**\\n * @dev Emitted when the beacon is upgraded.\\n */\\n event BeaconUpgraded(address indexed beacon);\\n\\n /**\\n * @dev Returns the current beacon.\\n */\\n function _getBeacon() internal view returns (address) {\\n return StorageSlot.getAddressSlot(_BEACON_SLOT).value;\\n }\\n\\n /**\\n * @dev Stores a new beacon in the EIP1967 beacon slot.\\n */\\n function _setBeacon(address newBeacon) private {\\n require(Address.isContract(newBeacon), \\\"ERC1967: new beacon is not a contract\\\");\\n require(\\n Address.isContract(IBeacon(newBeacon).implementation()),\\n \\\"ERC1967: beacon implementation is not a contract\\\"\\n );\\n StorageSlot.getAddressSlot(_BEACON_SLOT).value = newBeacon;\\n }\\n\\n /**\\n * @dev Perform beacon upgrade with additional setup call. Note: This upgrades the address of the beacon, it does\\n * not upgrade the implementation contained in the beacon (see {UpgradeableBeacon-_setImplementation} for that).\\n *\\n * Emits a {BeaconUpgraded} event.\\n */\\n function _upgradeBeaconToAndCall(\\n address newBeacon,\\n bytes memory data,\\n bool forceCall\\n ) internal {\\n _setBeacon(newBeacon);\\n emit BeaconUpgraded(newBeacon);\\n if (data.length > 0 || forceCall) {\\n Address.functionDelegateCall(IBeacon(newBeacon).implementation(), data);\\n }\\n }\\n}\\n\",\"keccak256\":\"0xabf3f59bc0e5423eae45e459dbe92e7052c6983628d39008590edc852a62f94a\",\"license\":\"MIT\"},\"@openzeppelin/contracts/proxy/Proxy.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.6.0) (proxy/Proxy.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev This abstract contract provides a fallback function that delegates all calls to another contract using the EVM\\n * instruction `delegatecall`. We refer to the second contract as the _implementation_ behind the proxy, and it has to\\n * be specified by overriding the virtual {_implementation} function.\\n *\\n * Additionally, delegation to the implementation can be triggered manually through the {_fallback} function, or to a\\n * different contract through the {_delegate} function.\\n *\\n * The success and return data of the delegated call will be returned back to the caller of the proxy.\\n */\\nabstract contract Proxy {\\n /**\\n * @dev Delegates the current call to `implementation`.\\n *\\n * This function does not return to its internal call site, it will return directly to the external caller.\\n */\\n function _delegate(address implementation) internal virtual {\\n assembly {\\n // Copy msg.data. We take full control of memory in this inline assembly\\n // block because it will not return to Solidity code. We overwrite the\\n // Solidity scratch pad at memory position 0.\\n calldatacopy(0, 0, calldatasize())\\n\\n // Call the implementation.\\n // out and outsize are 0 because we don't know the size yet.\\n let result := delegatecall(gas(), implementation, 0, calldatasize(), 0, 0)\\n\\n // Copy the returned data.\\n returndatacopy(0, 0, returndatasize())\\n\\n switch result\\n // delegatecall returns 0 on error.\\n case 0 {\\n revert(0, returndatasize())\\n }\\n default {\\n return(0, returndatasize())\\n }\\n }\\n }\\n\\n /**\\n * @dev This is a virtual function that should be overridden so it returns the address to which the fallback function\\n * and {_fallback} should delegate.\\n */\\n function _implementation() internal view virtual returns (address);\\n\\n /**\\n * @dev Delegates the current call to the address returned by `_implementation()`.\\n *\\n * This function does not return to its internal call site, it will return directly to the external caller.\\n */\\n function _fallback() internal virtual {\\n _beforeFallback();\\n _delegate(_implementation());\\n }\\n\\n /**\\n * @dev Fallback function that delegates calls to the address returned by `_implementation()`. Will run if no other\\n * function in the contract matches the call data.\\n */\\n fallback() external payable virtual {\\n _fallback();\\n }\\n\\n /**\\n * @dev Fallback function that delegates calls to the address returned by `_implementation()`. Will run if call data\\n * is empty.\\n */\\n receive() external payable virtual {\\n _fallback();\\n }\\n\\n /**\\n * @dev Hook that is called before falling back to the implementation. Can happen as part of a manual `_fallback`\\n * call, or as part of the Solidity `fallback` or `receive` functions.\\n *\\n * If overridden should call `super._beforeFallback()`.\\n */\\n function _beforeFallback() internal virtual {}\\n}\\n\",\"keccak256\":\"0xc130fe33f1b2132158531a87734153293f6d07bc263ff4ac90e85da9c82c0e27\",\"license\":\"MIT\"},\"@openzeppelin/contracts/proxy/beacon/IBeacon.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (proxy/beacon/IBeacon.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev This is the interface that {BeaconProxy} expects of its beacon.\\n */\\ninterface IBeacon {\\n /**\\n * @dev Must return an address that can be used as a delegate call target.\\n *\\n * {BeaconProxy} will check that this address is a contract.\\n */\\n function implementation() external view returns (address);\\n}\\n\",\"keccak256\":\"0xd50a3421ac379ccb1be435fa646d66a65c986b4924f0849839f08692f39dde61\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/Address.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.7.0) (utils/Address.sol)\\n\\npragma solidity ^0.8.1;\\n\\n/**\\n * @dev Collection of functions related to the address type\\n */\\nlibrary Address {\\n /**\\n * @dev Returns true if `account` is a contract.\\n *\\n * [IMPORTANT]\\n * ====\\n * It is unsafe to assume that an address for which this function returns\\n * false is an externally-owned account (EOA) and not a contract.\\n *\\n * Among others, `isContract` will return false for the following\\n * types of addresses:\\n *\\n * - an externally-owned account\\n * - a contract in construction\\n * - an address where a contract will be created\\n * - an address where a contract lived, but was destroyed\\n * ====\\n *\\n * [IMPORTANT]\\n * ====\\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\\n *\\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\\n * constructor.\\n * ====\\n */\\n function isContract(address account) internal view returns (bool) {\\n // This method relies on extcodesize/address.code.length, which returns 0\\n // for contracts in construction, since the code is only stored at the end\\n // of the constructor execution.\\n\\n return account.code.length > 0;\\n }\\n\\n /**\\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\\n * `recipient`, forwarding all available gas and reverting on errors.\\n *\\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\\n * imposed by `transfer`, making them unable to receive funds via\\n * `transfer`. {sendValue} removes this limitation.\\n *\\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\\n *\\n * IMPORTANT: because control is transferred to `recipient`, care must be\\n * taken to not create reentrancy vulnerabilities. Consider using\\n * {ReentrancyGuard} or the\\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\\n */\\n function sendValue(address payable recipient, uint256 amount) internal {\\n require(address(this).balance >= amount, \\\"Address: insufficient balance\\\");\\n\\n (bool success, ) = recipient.call{value: amount}(\\\"\\\");\\n require(success, \\\"Address: unable to send value, recipient may have reverted\\\");\\n }\\n\\n /**\\n * @dev Performs a Solidity function call using a low level `call`. A\\n * plain `call` is an unsafe replacement for a function call: use this\\n * function instead.\\n *\\n * If `target` reverts with a revert reason, it is bubbled up by this\\n * function (like regular Solidity function calls).\\n *\\n * Returns the raw returned data. To convert to the expected return value,\\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\\n *\\n * Requirements:\\n *\\n * - `target` must be a contract.\\n * - calling `target` with `data` must not revert.\\n *\\n * _Available since v3.1._\\n */\\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\\n return functionCall(target, data, \\\"Address: low-level call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\\n * `errorMessage` as a fallback revert reason when `target` reverts.\\n *\\n * _Available since v3.1._\\n */\\n function functionCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n return functionCallWithValue(target, data, 0, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but also transferring `value` wei to `target`.\\n *\\n * Requirements:\\n *\\n * - the calling contract must have an ETH balance of at least `value`.\\n * - the called Solidity function must be `payable`.\\n *\\n * _Available since v3.1._\\n */\\n function functionCallWithValue(\\n address target,\\n bytes memory data,\\n uint256 value\\n ) internal returns (bytes memory) {\\n return functionCallWithValue(target, data, value, \\\"Address: low-level call with value failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\\n * with `errorMessage` as a fallback revert reason when `target` reverts.\\n *\\n * _Available since v3.1._\\n */\\n function functionCallWithValue(\\n address target,\\n bytes memory data,\\n uint256 value,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n require(address(this).balance >= value, \\\"Address: insufficient balance for call\\\");\\n require(isContract(target), \\\"Address: call to non-contract\\\");\\n\\n (bool success, bytes memory returndata) = target.call{value: value}(data);\\n return verifyCallResult(success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but performing a static call.\\n *\\n * _Available since v3.3._\\n */\\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\\n return functionStaticCall(target, data, \\\"Address: low-level static call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\\n * but performing a static call.\\n *\\n * _Available since v3.3._\\n */\\n function functionStaticCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal view returns (bytes memory) {\\n require(isContract(target), \\\"Address: static call to non-contract\\\");\\n\\n (bool success, bytes memory returndata) = target.staticcall(data);\\n return verifyCallResult(success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but performing a delegate call.\\n *\\n * _Available since v3.4._\\n */\\n function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {\\n return functionDelegateCall(target, data, \\\"Address: low-level delegate call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\\n * but performing a delegate call.\\n *\\n * _Available since v3.4._\\n */\\n function functionDelegateCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n require(isContract(target), \\\"Address: delegate call to non-contract\\\");\\n\\n (bool success, bytes memory returndata) = target.delegatecall(data);\\n return verifyCallResult(success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the\\n * revert reason using the provided one.\\n *\\n * _Available since v4.3._\\n */\\n function verifyCallResult(\\n bool success,\\n bytes memory returndata,\\n string memory errorMessage\\n ) internal pure returns (bytes memory) {\\n if (success) {\\n return returndata;\\n } else {\\n // Look for revert reason and bubble it up if present\\n if (returndata.length > 0) {\\n // The easiest way to bubble the revert reason is using memory via assembly\\n /// @solidity memory-safe-assembly\\n assembly {\\n let returndata_size := mload(returndata)\\n revert(add(32, returndata), returndata_size)\\n }\\n } else {\\n revert(errorMessage);\\n }\\n }\\n }\\n}\\n\",\"keccak256\":\"0xd6153ce99bcdcce22b124f755e72553295be6abcd63804cfdffceb188b8bef10\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/StorageSlot.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.7.0) (utils/StorageSlot.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Library for reading and writing primitive types to specific storage slots.\\n *\\n * Storage slots are often used to avoid storage conflict when dealing with upgradeable contracts.\\n * This library helps with reading and writing to such slots without the need for inline assembly.\\n *\\n * The functions in this library return Slot structs that contain a `value` member that can be used to read or write.\\n *\\n * Example usage to set ERC1967 implementation slot:\\n * ```\\n * contract ERC1967 {\\n * bytes32 internal constant _IMPLEMENTATION_SLOT = 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc;\\n *\\n * function _getImplementation() internal view returns (address) {\\n * return StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value;\\n * }\\n *\\n * function _setImplementation(address newImplementation) internal {\\n * require(Address.isContract(newImplementation), \\\"ERC1967: new implementation is not a contract\\\");\\n * StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value = newImplementation;\\n * }\\n * }\\n * ```\\n *\\n * _Available since v4.1 for `address`, `bool`, `bytes32`, and `uint256`._\\n */\\nlibrary StorageSlot {\\n struct AddressSlot {\\n address value;\\n }\\n\\n struct BooleanSlot {\\n bool value;\\n }\\n\\n struct Bytes32Slot {\\n bytes32 value;\\n }\\n\\n struct Uint256Slot {\\n uint256 value;\\n }\\n\\n /**\\n * @dev Returns an `AddressSlot` with member `value` located at `slot`.\\n */\\n function getAddressSlot(bytes32 slot) internal pure returns (AddressSlot storage r) {\\n /// @solidity memory-safe-assembly\\n assembly {\\n r.slot := slot\\n }\\n }\\n\\n /**\\n * @dev Returns an `BooleanSlot` with member `value` located at `slot`.\\n */\\n function getBooleanSlot(bytes32 slot) internal pure returns (BooleanSlot storage r) {\\n /// @solidity memory-safe-assembly\\n assembly {\\n r.slot := slot\\n }\\n }\\n\\n /**\\n * @dev Returns an `Bytes32Slot` with member `value` located at `slot`.\\n */\\n function getBytes32Slot(bytes32 slot) internal pure returns (Bytes32Slot storage r) {\\n /// @solidity memory-safe-assembly\\n assembly {\\n r.slot := slot\\n }\\n }\\n\\n /**\\n * @dev Returns an `Uint256Slot` with member `value` located at `slot`.\\n */\\n function getUint256Slot(bytes32 slot) internal pure returns (Uint256Slot storage r) {\\n /// @solidity memory-safe-assembly\\n assembly {\\n r.slot := slot\\n }\\n }\\n}\\n\",\"keccak256\":\"0xd5c50c54bf02740ebd122ff06832546cb5fa84486d52695a9ccfd11666e0c81d\",\"license\":\"MIT\"},\"contracts/external/TransparentUpgradeableProxy.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-3.0\\n\\npragma solidity ^0.8.12;\\n\\nimport \\\"@openzeppelin/contracts/proxy/ERC1967/ERC1967Proxy.sol\\\";\\n\\n/**\\n * @dev This contract implements a proxy that is upgradeable by an admin. It is fully forked from OpenZeppelin\\n * `TransparentUpgradeableProxy`\\n *\\n * To avoid https://medium.com/nomic-labs-blog/malicious-backdoors-in-ethereum-proxies-62629adf3357[proxy selector\\n * clashing], which can potentially be used in an attack, this contract uses the\\n * https://blog.openzeppelin.com/the-transparent-proxy-pattern/[transparent proxy pattern]. This pattern implies two\\n * things that go hand in hand:\\n *\\n * 1. If any account other than the admin calls the proxy, the call will be forwarded to the implementation, even if\\n * that call matches one of the admin functions exposed by the proxy itself.\\n * 2. If the admin calls the proxy, it can access the admin functions, but its calls will never be forwarded to the\\n * implementation. If the admin tries to call a function on the implementation it will fail with an error that says\\n * \\\"admin cannot fallback to proxy target\\\".\\n *\\n * These properties mean that the admin account can only be used for admin actions like upgrading the proxy or changing\\n * the admin, so it's best if it's a dedicated account that is not used for anything else. This will avoid headaches due\\n * to sudden errors when trying to call a function from the proxy implementation.\\n *\\n * Our recommendation is for the dedicated account to be an instance of the {ProxyAdmin} contract. If set up this way,\\n * you should think of the `ProxyAdmin` instance as the real administrative interface of your proxy.\\n */\\ncontract TransparentUpgradeableProxy is ERC1967Proxy {\\n /**\\n * @dev Initializes an upgradeable proxy managed by `_admin`, backed by the implementation at `_logic`, and\\n * optionally initialized with `_data` as explained in {ERC1967Proxy-constructor}.\\n */\\n constructor(address _logic, address admin_, bytes memory _data) payable ERC1967Proxy(_logic, _data) {\\n assert(_ADMIN_SLOT == bytes32(uint256(keccak256(\\\"eip1967.proxy.admin\\\")) - 1));\\n _changeAdmin(admin_);\\n }\\n\\n /**\\n * @dev Modifier used internally that will delegate the call to the implementation unless the sender is the admin.\\n */\\n modifier ifAdmin() {\\n if (msg.sender == _getAdmin()) {\\n _;\\n } else {\\n _fallback();\\n }\\n }\\n\\n /**\\n * @dev Returns the current admin.\\n *\\n * NOTE: Only the admin can call this function. See {ProxyAdmin-getProxyAdmin}.\\n *\\n * TIP: To get this value clients can read directly from the storage slot shown below (specified by EIP1967) using the\\n * https://eth.wiki/json-rpc/API#eth_getstorageat[`eth_getStorageAt`] RPC call.\\n * `0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103`\\n */\\n function admin() external ifAdmin returns (address admin_) {\\n admin_ = _getAdmin();\\n }\\n\\n /**\\n * @dev Returns the current implementation.\\n *\\n * NOTE: Only the admin can call this function. See {ProxyAdmin-getProxyImplementation}.\\n *\\n * TIP: To get this value clients can read directly from the storage slot shown below (specified by EIP1967) using the\\n * https://eth.wiki/json-rpc/API#eth_getstorageat[`eth_getStorageAt`] RPC call.\\n * `0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc`\\n */\\n function implementation() external ifAdmin returns (address implementation_) {\\n implementation_ = _implementation();\\n }\\n\\n /**\\n * @dev Changes the admin of the proxy.\\n *\\n * Emits an {AdminChanged} event.\\n *\\n * NOTE: Only the admin can call this function. See {ProxyAdmin-changeProxyAdmin}.\\n */\\n function changeAdmin(address newAdmin) external virtual ifAdmin {\\n _changeAdmin(newAdmin);\\n }\\n\\n /**\\n * @dev Upgrade the implementation of the proxy.\\n *\\n * NOTE: Only the admin can call this function. See {ProxyAdmin-upgrade}.\\n */\\n function upgradeTo(address newImplementation) external ifAdmin {\\n _upgradeToAndCall(newImplementation, bytes(\\\"\\\"), false);\\n }\\n\\n /**\\n * @dev Upgrade the implementation of the proxy, and then call a function from the new implementation as specified\\n * by `data`, which should be an encoded function call. This is useful to initialize new storage variables in the\\n * proxied contract.\\n *\\n * NOTE: Only the admin can call this function. See {ProxyAdmin-upgradeAndCall}.\\n */\\n function upgradeToAndCall(address newImplementation, bytes calldata data) external payable ifAdmin {\\n _upgradeToAndCall(newImplementation, data, true);\\n }\\n\\n /**\\n * @dev Returns the current admin.\\n */\\n function _admin() internal view virtual returns (address) {\\n return _getAdmin();\\n }\\n\\n /**\\n * @dev Makes sure the admin cannot access the fallback function. See {Proxy-_beforeFallback}.\\n */\\n function _beforeFallback() internal virtual override {\\n require(msg.sender != _getAdmin(), \\\"TransparentUpgradeableProxy: admin cannot fallback to proxy target\\\");\\n super._beforeFallback();\\n }\\n}\\n\",\"keccak256\":\"0x93a67a0f612ea3ff2a76315e138a6a88267270a1379d3cc7be52845fbbe611e2\",\"license\":\"GPL-3.0\"}},\"version\":1}", + "bytecode": "0x6080604052604051620010bb380380620010bb8339810160408190526200002691620004d8565b828162000036828260006200009a565b5062000066905060017fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6104620005b8565b6000805160206200107483398151915214620000865762000086620005da565b6200009182620000d7565b50505062000643565b620000a58362000132565b600082511180620000b35750805b15620000d257620000d083836200017460201b6200028c1760201c565b505b505050565b7f7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f62000102620001a5565b604080516001600160a01b03928316815291841660208301520160405180910390a16200012f81620001de565b50565b6200013d8162000293565b6040516001600160a01b038216907fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b90600090a250565b60606200019c8383604051806060016040528060278152602001620010946027913962000347565b90505b92915050565b6000620001cf6000805160206200107483398151915260001b6200042f60201b6200022e1760201c565b546001600160a01b0316919050565b6001600160a01b038116620002495760405162461bcd60e51b815260206004820152602660248201527f455243313936373a206e65772061646d696e20697320746865207a65726f206160448201526564647265737360d01b60648201526084015b60405180910390fd5b80620002726000805160206200107483398151915260001b6200042f60201b6200022e1760201c565b80546001600160a01b0319166001600160a01b039290921691909117905550565b620002a9816200043260201b620002b81760201c565b6200030d5760405162461bcd60e51b815260206004820152602d60248201527f455243313936373a206e657720696d706c656d656e746174696f6e206973206e60448201526c1bdd08184818dbdb9d1c9858dd609a1b606482015260840162000240565b80620002727f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc60001b6200042f60201b6200022e1760201c565b60606001600160a01b0384163b620003b15760405162461bcd60e51b815260206004820152602660248201527f416464726573733a2064656c65676174652063616c6c20746f206e6f6e2d636f6044820152651b9d1c9858dd60d21b606482015260840162000240565b600080856001600160a01b031685604051620003ce9190620005f0565b600060405180830381855af49150503d80600081146200040b576040519150601f19603f3d011682016040523d82523d6000602084013e62000410565b606091505b5090925090506200042382828662000441565b925050505b9392505050565b90565b6001600160a01b03163b151590565b606083156200045257508162000428565b825115620004635782518084602001fd5b8160405162461bcd60e51b81526004016200024091906200060e565b80516001600160a01b03811681146200049757600080fd5b919050565b634e487b7160e01b600052604160045260246000fd5b60005b83811015620004cf578181015183820152602001620004b5565b50506000910152565b600080600060608486031215620004ee57600080fd5b620004f9846200047f565b925062000509602085016200047f565b60408501519092506001600160401b03808211156200052757600080fd5b818601915086601f8301126200053c57600080fd5b8151818111156200055157620005516200049c565b604051601f8201601f19908116603f011681019083821181831017156200057c576200057c6200049c565b816040528281528960208487010111156200059657600080fd5b620005a9836020830160208801620004b2565b80955050505050509250925092565b818103818111156200019f57634e487b7160e01b600052601160045260246000fd5b634e487b7160e01b600052600160045260246000fd5b6000825162000604818460208701620004b2565b9190910192915050565b60208152600082518060208401526200062f816040850160208701620004b2565b601f01601f19169190910160400192915050565b610a2180620006536000396000f3fe60806040526004361061005e5760003560e01c80635c60da1b116100435780635c60da1b146100a85780638f283970146100e6578063f851a440146101065761006d565b80633659cfe6146100755780634f1ef286146100955761006d565b3661006d5761006b61011b565b005b61006b61011b565b34801561008157600080fd5b5061006b610090366004610895565b610135565b61006b6100a33660046108b0565b61017f565b3480156100b457600080fd5b506100bd6101f3565b60405173ffffffffffffffffffffffffffffffffffffffff909116815260200160405180910390f35b3480156100f257600080fd5b5061006b610101366004610895565b610231565b34801561011257600080fd5b506100bd61025e565b6101236102d4565b61013361012e6103ab565b6103b5565b565b61013d6103d9565b73ffffffffffffffffffffffffffffffffffffffff1633036101775761017481604051806020016040528060008152506000610419565b50565b61017461011b565b6101876103d9565b73ffffffffffffffffffffffffffffffffffffffff1633036101eb576101e68383838080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525060019250610419915050565b505050565b6101e661011b565b60006101fd6103d9565b73ffffffffffffffffffffffffffffffffffffffff163303610226576102216103ab565b905090565b61022e61011b565b90565b6102396103d9565b73ffffffffffffffffffffffffffffffffffffffff1633036101775761017481610444565b60006102686103d9565b73ffffffffffffffffffffffffffffffffffffffff163303610226576102216103d9565b60606102b183836040518060600160405280602781526020016109c5602791396104a5565b9392505050565b73ffffffffffffffffffffffffffffffffffffffff163b151590565b6102dc6103d9565b73ffffffffffffffffffffffffffffffffffffffff163303610133576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604260248201527f5472616e73706172656e745570677261646561626c6550726f78793a2061646d60448201527f696e2063616e6e6f742066616c6c6261636b20746f2070726f7879207461726760648201527f6574000000000000000000000000000000000000000000000000000000000000608482015260a4015b60405180910390fd5b60006102216105cd565b3660008037600080366000845af43d6000803e8080156103d4573d6000f35b3d6000fd5b60007fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035b5473ffffffffffffffffffffffffffffffffffffffff16919050565b610422836105f5565b60008251118061042f5750805b156101e65761043e838361028c565b50505050565b7f7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f61046d6103d9565b6040805173ffffffffffffffffffffffffffffffffffffffff928316815291841660208301520160405180910390a161017481610642565b606073ffffffffffffffffffffffffffffffffffffffff84163b61054b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f416464726573733a2064656c65676174652063616c6c20746f206e6f6e2d636f60448201527f6e7472616374000000000000000000000000000000000000000000000000000060648201526084016103a2565b6000808573ffffffffffffffffffffffffffffffffffffffff16856040516105739190610957565b600060405180830381855af49150503d80600081146105ae576040519150601f19603f3d011682016040523d82523d6000602084013e6105b3565b606091505b50915091506105c382828661074e565b9695505050505050565b60007f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc6103fd565b6105fe816107a1565b60405173ffffffffffffffffffffffffffffffffffffffff8216907fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b90600090a250565b73ffffffffffffffffffffffffffffffffffffffff81166106e5576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f455243313936373a206e65772061646d696e20697320746865207a65726f206160448201527f646472657373000000000000000000000000000000000000000000000000000060648201526084016103a2565b807fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035b80547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff9290921691909117905550565b6060831561075d5750816102b1565b82511561076d5782518084602001fd5b816040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016103a29190610973565b73ffffffffffffffffffffffffffffffffffffffff81163b610845576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602d60248201527f455243313936373a206e657720696d706c656d656e746174696f6e206973206e60448201527f6f74206120636f6e74726163740000000000000000000000000000000000000060648201526084016103a2565b807f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc610708565b803573ffffffffffffffffffffffffffffffffffffffff8116811461089057600080fd5b919050565b6000602082840312156108a757600080fd5b6102b18261086c565b6000806000604084860312156108c557600080fd5b6108ce8461086c565b9250602084013567ffffffffffffffff808211156108eb57600080fd5b818601915086601f8301126108ff57600080fd5b81358181111561090e57600080fd5b87602082850101111561092057600080fd5b6020830194508093505050509250925092565b60005b8381101561094e578181015183820152602001610936565b50506000910152565b60008251610969818460208701610933565b9190910192915050565b6020815260008251806020840152610992816040850160208701610933565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016919091016040019291505056fe416464726573733a206c6f772d6c6576656c2064656c65676174652063616c6c206661696c6564a2646970667358221220e96638b07fb1675d93a95c49e417bc8111448b23a59918698cdcd8fd488dd7cf64736f6c63430008110033b53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103416464726573733a206c6f772d6c6576656c2064656c65676174652063616c6c206661696c6564", + "deployedBytecode": "0x60806040526004361061005e5760003560e01c80635c60da1b116100435780635c60da1b146100a85780638f283970146100e6578063f851a440146101065761006d565b80633659cfe6146100755780634f1ef286146100955761006d565b3661006d5761006b61011b565b005b61006b61011b565b34801561008157600080fd5b5061006b610090366004610895565b610135565b61006b6100a33660046108b0565b61017f565b3480156100b457600080fd5b506100bd6101f3565b60405173ffffffffffffffffffffffffffffffffffffffff909116815260200160405180910390f35b3480156100f257600080fd5b5061006b610101366004610895565b610231565b34801561011257600080fd5b506100bd61025e565b6101236102d4565b61013361012e6103ab565b6103b5565b565b61013d6103d9565b73ffffffffffffffffffffffffffffffffffffffff1633036101775761017481604051806020016040528060008152506000610419565b50565b61017461011b565b6101876103d9565b73ffffffffffffffffffffffffffffffffffffffff1633036101eb576101e68383838080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525060019250610419915050565b505050565b6101e661011b565b60006101fd6103d9565b73ffffffffffffffffffffffffffffffffffffffff163303610226576102216103ab565b905090565b61022e61011b565b90565b6102396103d9565b73ffffffffffffffffffffffffffffffffffffffff1633036101775761017481610444565b60006102686103d9565b73ffffffffffffffffffffffffffffffffffffffff163303610226576102216103d9565b60606102b183836040518060600160405280602781526020016109c5602791396104a5565b9392505050565b73ffffffffffffffffffffffffffffffffffffffff163b151590565b6102dc6103d9565b73ffffffffffffffffffffffffffffffffffffffff163303610133576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604260248201527f5472616e73706172656e745570677261646561626c6550726f78793a2061646d60448201527f696e2063616e6e6f742066616c6c6261636b20746f2070726f7879207461726760648201527f6574000000000000000000000000000000000000000000000000000000000000608482015260a4015b60405180910390fd5b60006102216105cd565b3660008037600080366000845af43d6000803e8080156103d4573d6000f35b3d6000fd5b60007fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035b5473ffffffffffffffffffffffffffffffffffffffff16919050565b610422836105f5565b60008251118061042f5750805b156101e65761043e838361028c565b50505050565b7f7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f61046d6103d9565b6040805173ffffffffffffffffffffffffffffffffffffffff928316815291841660208301520160405180910390a161017481610642565b606073ffffffffffffffffffffffffffffffffffffffff84163b61054b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f416464726573733a2064656c65676174652063616c6c20746f206e6f6e2d636f60448201527f6e7472616374000000000000000000000000000000000000000000000000000060648201526084016103a2565b6000808573ffffffffffffffffffffffffffffffffffffffff16856040516105739190610957565b600060405180830381855af49150503d80600081146105ae576040519150601f19603f3d011682016040523d82523d6000602084013e6105b3565b606091505b50915091506105c382828661074e565b9695505050505050565b60007f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc6103fd565b6105fe816107a1565b60405173ffffffffffffffffffffffffffffffffffffffff8216907fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b90600090a250565b73ffffffffffffffffffffffffffffffffffffffff81166106e5576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f455243313936373a206e65772061646d696e20697320746865207a65726f206160448201527f646472657373000000000000000000000000000000000000000000000000000060648201526084016103a2565b807fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035b80547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff9290921691909117905550565b6060831561075d5750816102b1565b82511561076d5782518084602001fd5b816040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016103a29190610973565b73ffffffffffffffffffffffffffffffffffffffff81163b610845576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602d60248201527f455243313936373a206e657720696d706c656d656e746174696f6e206973206e60448201527f6f74206120636f6e74726163740000000000000000000000000000000000000060648201526084016103a2565b807f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc610708565b803573ffffffffffffffffffffffffffffffffffffffff8116811461089057600080fd5b919050565b6000602082840312156108a757600080fd5b6102b18261086c565b6000806000604084860312156108c557600080fd5b6108ce8461086c565b9250602084013567ffffffffffffffff808211156108eb57600080fd5b818601915086601f8301126108ff57600080fd5b81358181111561090e57600080fd5b87602082850101111561092057600080fd5b6020830194508093505050509250925092565b60005b8381101561094e578181015183820152602001610936565b50506000910152565b60008251610969818460208701610933565b9190910192915050565b6020815260008251806020840152610992816040850160208701610933565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016919091016040019291505056fe416464726573733a206c6f772d6c6576656c2064656c65676174652063616c6c206661696c6564a2646970667358221220e96638b07fb1675d93a95c49e417bc8111448b23a59918698cdcd8fd488dd7cf64736f6c63430008110033", + "devdoc": { + "details": "This contract implements a proxy that is upgradeable by an admin. It is fully forked from OpenZeppelin `TransparentUpgradeableProxy` To avoid https://medium.com/nomic-labs-blog/malicious-backdoors-in-ethereum-proxies-62629adf3357[proxy selector clashing], which can potentially be used in an attack, this contract uses the https://blog.openzeppelin.com/the-transparent-proxy-pattern/[transparent proxy pattern]. This pattern implies two things that go hand in hand: 1. If any account other than the admin calls the proxy, the call will be forwarded to the implementation, even if that call matches one of the admin functions exposed by the proxy itself. 2. If the admin calls the proxy, it can access the admin functions, but its calls will never be forwarded to the implementation. If the admin tries to call a function on the implementation it will fail with an error that says \"admin cannot fallback to proxy target\". These properties mean that the admin account can only be used for admin actions like upgrading the proxy or changing the admin, so it's best if it's a dedicated account that is not used for anything else. This will avoid headaches due to sudden errors when trying to call a function from the proxy implementation. Our recommendation is for the dedicated account to be an instance of the {ProxyAdmin} contract. If set up this way, you should think of the `ProxyAdmin` instance as the real administrative interface of your proxy.", + "kind": "dev", + "methods": { + "admin()": { + "details": "Returns the current admin. NOTE: Only the admin can call this function. See {ProxyAdmin-getProxyAdmin}. TIP: To get this value clients can read directly from the storage slot shown below (specified by EIP1967) using the https://eth.wiki/json-rpc/API#eth_getstorageat[`eth_getStorageAt`] RPC call. `0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103`" + }, + "changeAdmin(address)": { + "details": "Changes the admin of the proxy. Emits an {AdminChanged} event. NOTE: Only the admin can call this function. See {ProxyAdmin-changeProxyAdmin}." + }, + "constructor": { + "details": "Initializes an upgradeable proxy managed by `_admin`, backed by the implementation at `_logic`, and optionally initialized with `_data` as explained in {ERC1967Proxy-constructor}." + }, + "implementation()": { + "details": "Returns the current implementation. NOTE: Only the admin can call this function. See {ProxyAdmin-getProxyImplementation}. TIP: To get this value clients can read directly from the storage slot shown below (specified by EIP1967) using the https://eth.wiki/json-rpc/API#eth_getstorageat[`eth_getStorageAt`] RPC call. `0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc`" + }, + "upgradeTo(address)": { + "details": "Upgrade the implementation of the proxy. NOTE: Only the admin can call this function. See {ProxyAdmin-upgrade}." + }, + "upgradeToAndCall(address,bytes)": { + "details": "Upgrade the implementation of the proxy, and then call a function from the new implementation as specified by `data`, which should be an encoded function call. This is useful to initialize new storage variables in the proxied contract. NOTE: Only the admin can call this function. See {ProxyAdmin-upgradeAndCall}." + } + }, + "version": 1 + }, + "userdoc": { + "kind": "user", + "methods": {}, + "version": 1 + }, + "storageLayout": { + "storage": [], + "types": null + } +} \ No newline at end of file diff --git a/deployments/optimism/Treasury_USD.json b/deployments/optimism/Treasury_USD.json new file mode 100644 index 00000000..491ef468 --- /dev/null +++ b/deployments/optimism/Treasury_USD.json @@ -0,0 +1,235 @@ +{ + "address": "0x770F7CDFAe5ecaA3A0538DA7Cb1D6c8F22252fe0", + "abi": [ + { + "inputs": [ + { + "internalType": "address", + "name": "_logic", + "type": "address" + }, + { + "internalType": "address", + "name": "admin_", + "type": "address" + }, + { + "internalType": "bytes", + "name": "_data", + "type": "bytes" + } + ], + "stateMutability": "payable", + "type": "constructor" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "previousAdmin", + "type": "address" + }, + { + "indexed": false, + "internalType": "address", + "name": "newAdmin", + "type": "address" + } + ], + "name": "AdminChanged", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "beacon", + "type": "address" + } + ], + "name": "BeaconUpgraded", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "implementation", + "type": "address" + } + ], + "name": "Upgraded", + "type": "event" + }, + { + "stateMutability": "payable", + "type": "fallback" + }, + { + "inputs": [], + "name": "admin", + "outputs": [ + { + "internalType": "address", + "name": "admin_", + "type": "address" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "newAdmin", + "type": "address" + } + ], + "name": "changeAdmin", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "implementation", + "outputs": [ + { + "internalType": "address", + "name": "implementation_", + "type": "address" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "newImplementation", + "type": "address" + } + ], + "name": "upgradeTo", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "newImplementation", + "type": "address" + }, + { + "internalType": "bytes", + "name": "data", + "type": "bytes" + } + ], + "name": "upgradeToAndCall", + "outputs": [], + "stateMutability": "payable", + "type": "function" + }, + { + "stateMutability": "payable", + "type": "receive" + } + ], + "transactionHash": "0x8a9b55125c293edee755fe3570117beae399afe86d632ac374f4c8f8fce57a3e", + "receipt": { + "to": null, + "from": "0xfdA462548Ce04282f4B6D6619823a7C64Fdc0185", + "contractAddress": "0x770F7CDFAe5ecaA3A0538DA7Cb1D6c8F22252fe0", + "transactionIndex": 7, + "gasUsed": "734966", + "logsBloom": "0x00000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000008000000000000800000000000000000000000000000000000020000000000000000200000000000000000000000000000800000000000000000000000000000000000000000000000000000001000000000000000000020000000000000000000000000000000000400000000000000000000000000000000400000000000000000040000000000000000000000000000000000", + "blockHash": "0x53a7c5c8270d7b978f0a31a7316a6e32c9ef1450bab3fa36eaa88149835fea61", + "transactionHash": "0x8a9b55125c293edee755fe3570117beae399afe86d632ac374f4c8f8fce57a3e", + "logs": [ + { + "transactionIndex": 7, + "blockNumber": 114643689, + "transactionHash": "0x8a9b55125c293edee755fe3570117beae399afe86d632ac374f4c8f8fce57a3e", + "address": "0x770F7CDFAe5ecaA3A0538DA7Cb1D6c8F22252fe0", + "topics": [ + "0xbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b", + "0x0000000000000000000000001033dd8415a282db52f14902e91de6e91868ac6d" + ], + "data": "0x", + "logIndex": 5, + "blockHash": "0x53a7c5c8270d7b978f0a31a7316a6e32c9ef1450bab3fa36eaa88149835fea61" + }, + { + "transactionIndex": 7, + "blockNumber": 114643689, + "transactionHash": "0x8a9b55125c293edee755fe3570117beae399afe86d632ac374f4c8f8fce57a3e", + "address": "0x770F7CDFAe5ecaA3A0538DA7Cb1D6c8F22252fe0", + "topics": [ + "0x7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f" + ], + "data": "0x0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000c16b81af351ba9e64c1a069e3ab18c244a1e3049", + "logIndex": 6, + "blockHash": "0x53a7c5c8270d7b978f0a31a7316a6e32c9ef1450bab3fa36eaa88149835fea61" + } + ], + "blockNumber": 114643689, + "cumulativeGasUsed": "1033354", + "status": 1, + "byzantium": true + }, + "args": [ + "0x1033dD8415A282Db52f14902E91DE6e91868aC6D", + "0xC16B81Af351BA9e64C1a069E3Ab18c244A1E3049", + "0x485cc955000000000000000000000000e324d92516be618afd776c8c87386196e76d50ac0000000000000000000000000000206329b97db379d5e1bf586bbdb969c63274" + ], + "numDeployments": 1, + "solcInputHash": "871924e0c138825a2736b76def8fef8d", + "metadata": "{\"compiler\":{\"version\":\"0.8.17+commit.8df45f5f\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_logic\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"admin_\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"_data\",\"type\":\"bytes\"}],\"stateMutability\":\"payable\",\"type\":\"constructor\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"previousAdmin\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"newAdmin\",\"type\":\"address\"}],\"name\":\"AdminChanged\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"beacon\",\"type\":\"address\"}],\"name\":\"BeaconUpgraded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"implementation\",\"type\":\"address\"}],\"name\":\"Upgraded\",\"type\":\"event\"},{\"stateMutability\":\"payable\",\"type\":\"fallback\"},{\"inputs\":[],\"name\":\"admin\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"admin_\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newAdmin\",\"type\":\"address\"}],\"name\":\"changeAdmin\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"implementation\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"implementation_\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newImplementation\",\"type\":\"address\"}],\"name\":\"upgradeTo\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newImplementation\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"}],\"name\":\"upgradeToAndCall\",\"outputs\":[],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"stateMutability\":\"payable\",\"type\":\"receive\"}],\"devdoc\":{\"details\":\"This contract implements a proxy that is upgradeable by an admin. It is fully forked from OpenZeppelin `TransparentUpgradeableProxy` To avoid https://medium.com/nomic-labs-blog/malicious-backdoors-in-ethereum-proxies-62629adf3357[proxy selector clashing], which can potentially be used in an attack, this contract uses the https://blog.openzeppelin.com/the-transparent-proxy-pattern/[transparent proxy pattern]. This pattern implies two things that go hand in hand: 1. If any account other than the admin calls the proxy, the call will be forwarded to the implementation, even if that call matches one of the admin functions exposed by the proxy itself. 2. If the admin calls the proxy, it can access the admin functions, but its calls will never be forwarded to the implementation. If the admin tries to call a function on the implementation it will fail with an error that says \\\"admin cannot fallback to proxy target\\\". These properties mean that the admin account can only be used for admin actions like upgrading the proxy or changing the admin, so it's best if it's a dedicated account that is not used for anything else. This will avoid headaches due to sudden errors when trying to call a function from the proxy implementation. Our recommendation is for the dedicated account to be an instance of the {ProxyAdmin} contract. If set up this way, you should think of the `ProxyAdmin` instance as the real administrative interface of your proxy.\",\"kind\":\"dev\",\"methods\":{\"admin()\":{\"details\":\"Returns the current admin. NOTE: Only the admin can call this function. See {ProxyAdmin-getProxyAdmin}. TIP: To get this value clients can read directly from the storage slot shown below (specified by EIP1967) using the https://eth.wiki/json-rpc/API#eth_getstorageat[`eth_getStorageAt`] RPC call. `0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103`\"},\"changeAdmin(address)\":{\"details\":\"Changes the admin of the proxy. Emits an {AdminChanged} event. NOTE: Only the admin can call this function. See {ProxyAdmin-changeProxyAdmin}.\"},\"constructor\":{\"details\":\"Initializes an upgradeable proxy managed by `_admin`, backed by the implementation at `_logic`, and optionally initialized with `_data` as explained in {ERC1967Proxy-constructor}.\"},\"implementation()\":{\"details\":\"Returns the current implementation. NOTE: Only the admin can call this function. See {ProxyAdmin-getProxyImplementation}. TIP: To get this value clients can read directly from the storage slot shown below (specified by EIP1967) using the https://eth.wiki/json-rpc/API#eth_getstorageat[`eth_getStorageAt`] RPC call. `0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc`\"},\"upgradeTo(address)\":{\"details\":\"Upgrade the implementation of the proxy. NOTE: Only the admin can call this function. See {ProxyAdmin-upgrade}.\"},\"upgradeToAndCall(address,bytes)\":{\"details\":\"Upgrade the implementation of the proxy, and then call a function from the new implementation as specified by `data`, which should be an encoded function call. This is useful to initialize new storage variables in the proxied contract. NOTE: Only the admin can call this function. See {ProxyAdmin-upgradeAndCall}.\"}},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/external/TransparentUpgradeableProxy.sol\":\"TransparentUpgradeableProxy\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":1000000},\"remappings\":[]},\"sources\":{\"@openzeppelin/contracts/interfaces/draft-IERC1822.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.5.0) (interfaces/draft-IERC1822.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev ERC1822: Universal Upgradeable Proxy Standard (UUPS) documents a method for upgradeability through a simplified\\n * proxy whose upgrades are fully controlled by the current implementation.\\n */\\ninterface IERC1822Proxiable {\\n /**\\n * @dev Returns the storage slot that the proxiable contract assumes is being used to store the implementation\\n * address.\\n *\\n * IMPORTANT: A proxy pointing at a proxiable contract should not be considered proxiable itself, because this risks\\n * bricking a proxy that upgrades to it, by delegating to itself until out of gas. Thus it is critical that this\\n * function revert if invoked through a proxy.\\n */\\n function proxiableUUID() external view returns (bytes32);\\n}\\n\",\"keccak256\":\"0x1d4afe6cb24200cc4545eed814ecf5847277dfe5d613a1707aad5fceecebcfff\",\"license\":\"MIT\"},\"@openzeppelin/contracts/proxy/ERC1967/ERC1967Proxy.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.7.0) (proxy/ERC1967/ERC1967Proxy.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../Proxy.sol\\\";\\nimport \\\"./ERC1967Upgrade.sol\\\";\\n\\n/**\\n * @dev This contract implements an upgradeable proxy. It is upgradeable because calls are delegated to an\\n * implementation address that can be changed. This address is stored in storage in the location specified by\\n * https://eips.ethereum.org/EIPS/eip-1967[EIP1967], so that it doesn't conflict with the storage layout of the\\n * implementation behind the proxy.\\n */\\ncontract ERC1967Proxy is Proxy, ERC1967Upgrade {\\n /**\\n * @dev Initializes the upgradeable proxy with an initial implementation specified by `_logic`.\\n *\\n * If `_data` is nonempty, it's used as data in a delegate call to `_logic`. This will typically be an encoded\\n * function call, and allows initializing the storage of the proxy like a Solidity constructor.\\n */\\n constructor(address _logic, bytes memory _data) payable {\\n _upgradeToAndCall(_logic, _data, false);\\n }\\n\\n /**\\n * @dev Returns the current implementation address.\\n */\\n function _implementation() internal view virtual override returns (address impl) {\\n return ERC1967Upgrade._getImplementation();\\n }\\n}\\n\",\"keccak256\":\"0xa2b22da3032e50b55f95ec1d13336102d675f341167aa76db571ef7f8bb7975d\",\"license\":\"MIT\"},\"@openzeppelin/contracts/proxy/ERC1967/ERC1967Upgrade.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.5.0) (proxy/ERC1967/ERC1967Upgrade.sol)\\n\\npragma solidity ^0.8.2;\\n\\nimport \\\"../beacon/IBeacon.sol\\\";\\nimport \\\"../../interfaces/draft-IERC1822.sol\\\";\\nimport \\\"../../utils/Address.sol\\\";\\nimport \\\"../../utils/StorageSlot.sol\\\";\\n\\n/**\\n * @dev This abstract contract provides getters and event emitting update functions for\\n * https://eips.ethereum.org/EIPS/eip-1967[EIP1967] slots.\\n *\\n * _Available since v4.1._\\n *\\n * @custom:oz-upgrades-unsafe-allow delegatecall\\n */\\nabstract contract ERC1967Upgrade {\\n // This is the keccak-256 hash of \\\"eip1967.proxy.rollback\\\" subtracted by 1\\n bytes32 private constant _ROLLBACK_SLOT = 0x4910fdfa16fed3260ed0e7147f7cc6da11a60208b5b9406d12a635614ffd9143;\\n\\n /**\\n * @dev Storage slot with the address of the current implementation.\\n * This is the keccak-256 hash of \\\"eip1967.proxy.implementation\\\" subtracted by 1, and is\\n * validated in the constructor.\\n */\\n bytes32 internal constant _IMPLEMENTATION_SLOT = 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc;\\n\\n /**\\n * @dev Emitted when the implementation is upgraded.\\n */\\n event Upgraded(address indexed implementation);\\n\\n /**\\n * @dev Returns the current implementation address.\\n */\\n function _getImplementation() internal view returns (address) {\\n return StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value;\\n }\\n\\n /**\\n * @dev Stores a new address in the EIP1967 implementation slot.\\n */\\n function _setImplementation(address newImplementation) private {\\n require(Address.isContract(newImplementation), \\\"ERC1967: new implementation is not a contract\\\");\\n StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value = newImplementation;\\n }\\n\\n /**\\n * @dev Perform implementation upgrade\\n *\\n * Emits an {Upgraded} event.\\n */\\n function _upgradeTo(address newImplementation) internal {\\n _setImplementation(newImplementation);\\n emit Upgraded(newImplementation);\\n }\\n\\n /**\\n * @dev Perform implementation upgrade with additional setup call.\\n *\\n * Emits an {Upgraded} event.\\n */\\n function _upgradeToAndCall(\\n address newImplementation,\\n bytes memory data,\\n bool forceCall\\n ) internal {\\n _upgradeTo(newImplementation);\\n if (data.length > 0 || forceCall) {\\n Address.functionDelegateCall(newImplementation, data);\\n }\\n }\\n\\n /**\\n * @dev Perform implementation upgrade with security checks for UUPS proxies, and additional setup call.\\n *\\n * Emits an {Upgraded} event.\\n */\\n function _upgradeToAndCallUUPS(\\n address newImplementation,\\n bytes memory data,\\n bool forceCall\\n ) internal {\\n // Upgrades from old implementations will perform a rollback test. This test requires the new\\n // implementation to upgrade back to the old, non-ERC1822 compliant, implementation. Removing\\n // this special case will break upgrade paths from old UUPS implementation to new ones.\\n if (StorageSlot.getBooleanSlot(_ROLLBACK_SLOT).value) {\\n _setImplementation(newImplementation);\\n } else {\\n try IERC1822Proxiable(newImplementation).proxiableUUID() returns (bytes32 slot) {\\n require(slot == _IMPLEMENTATION_SLOT, \\\"ERC1967Upgrade: unsupported proxiableUUID\\\");\\n } catch {\\n revert(\\\"ERC1967Upgrade: new implementation is not UUPS\\\");\\n }\\n _upgradeToAndCall(newImplementation, data, forceCall);\\n }\\n }\\n\\n /**\\n * @dev Storage slot with the admin of the contract.\\n * This is the keccak-256 hash of \\\"eip1967.proxy.admin\\\" subtracted by 1, and is\\n * validated in the constructor.\\n */\\n bytes32 internal constant _ADMIN_SLOT = 0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103;\\n\\n /**\\n * @dev Emitted when the admin account has changed.\\n */\\n event AdminChanged(address previousAdmin, address newAdmin);\\n\\n /**\\n * @dev Returns the current admin.\\n */\\n function _getAdmin() internal view returns (address) {\\n return StorageSlot.getAddressSlot(_ADMIN_SLOT).value;\\n }\\n\\n /**\\n * @dev Stores a new address in the EIP1967 admin slot.\\n */\\n function _setAdmin(address newAdmin) private {\\n require(newAdmin != address(0), \\\"ERC1967: new admin is the zero address\\\");\\n StorageSlot.getAddressSlot(_ADMIN_SLOT).value = newAdmin;\\n }\\n\\n /**\\n * @dev Changes the admin of the proxy.\\n *\\n * Emits an {AdminChanged} event.\\n */\\n function _changeAdmin(address newAdmin) internal {\\n emit AdminChanged(_getAdmin(), newAdmin);\\n _setAdmin(newAdmin);\\n }\\n\\n /**\\n * @dev The storage slot of the UpgradeableBeacon contract which defines the implementation for this proxy.\\n * This is bytes32(uint256(keccak256('eip1967.proxy.beacon')) - 1)) and is validated in the constructor.\\n */\\n bytes32 internal constant _BEACON_SLOT = 0xa3f0ad74e5423aebfd80d3ef4346578335a9a72aeaee59ff6cb3582b35133d50;\\n\\n /**\\n * @dev Emitted when the beacon is upgraded.\\n */\\n event BeaconUpgraded(address indexed beacon);\\n\\n /**\\n * @dev Returns the current beacon.\\n */\\n function _getBeacon() internal view returns (address) {\\n return StorageSlot.getAddressSlot(_BEACON_SLOT).value;\\n }\\n\\n /**\\n * @dev Stores a new beacon in the EIP1967 beacon slot.\\n */\\n function _setBeacon(address newBeacon) private {\\n require(Address.isContract(newBeacon), \\\"ERC1967: new beacon is not a contract\\\");\\n require(\\n Address.isContract(IBeacon(newBeacon).implementation()),\\n \\\"ERC1967: beacon implementation is not a contract\\\"\\n );\\n StorageSlot.getAddressSlot(_BEACON_SLOT).value = newBeacon;\\n }\\n\\n /**\\n * @dev Perform beacon upgrade with additional setup call. Note: This upgrades the address of the beacon, it does\\n * not upgrade the implementation contained in the beacon (see {UpgradeableBeacon-_setImplementation} for that).\\n *\\n * Emits a {BeaconUpgraded} event.\\n */\\n function _upgradeBeaconToAndCall(\\n address newBeacon,\\n bytes memory data,\\n bool forceCall\\n ) internal {\\n _setBeacon(newBeacon);\\n emit BeaconUpgraded(newBeacon);\\n if (data.length > 0 || forceCall) {\\n Address.functionDelegateCall(IBeacon(newBeacon).implementation(), data);\\n }\\n }\\n}\\n\",\"keccak256\":\"0xabf3f59bc0e5423eae45e459dbe92e7052c6983628d39008590edc852a62f94a\",\"license\":\"MIT\"},\"@openzeppelin/contracts/proxy/Proxy.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.6.0) (proxy/Proxy.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev This abstract contract provides a fallback function that delegates all calls to another contract using the EVM\\n * instruction `delegatecall`. We refer to the second contract as the _implementation_ behind the proxy, and it has to\\n * be specified by overriding the virtual {_implementation} function.\\n *\\n * Additionally, delegation to the implementation can be triggered manually through the {_fallback} function, or to a\\n * different contract through the {_delegate} function.\\n *\\n * The success and return data of the delegated call will be returned back to the caller of the proxy.\\n */\\nabstract contract Proxy {\\n /**\\n * @dev Delegates the current call to `implementation`.\\n *\\n * This function does not return to its internal call site, it will return directly to the external caller.\\n */\\n function _delegate(address implementation) internal virtual {\\n assembly {\\n // Copy msg.data. We take full control of memory in this inline assembly\\n // block because it will not return to Solidity code. We overwrite the\\n // Solidity scratch pad at memory position 0.\\n calldatacopy(0, 0, calldatasize())\\n\\n // Call the implementation.\\n // out and outsize are 0 because we don't know the size yet.\\n let result := delegatecall(gas(), implementation, 0, calldatasize(), 0, 0)\\n\\n // Copy the returned data.\\n returndatacopy(0, 0, returndatasize())\\n\\n switch result\\n // delegatecall returns 0 on error.\\n case 0 {\\n revert(0, returndatasize())\\n }\\n default {\\n return(0, returndatasize())\\n }\\n }\\n }\\n\\n /**\\n * @dev This is a virtual function that should be overridden so it returns the address to which the fallback function\\n * and {_fallback} should delegate.\\n */\\n function _implementation() internal view virtual returns (address);\\n\\n /**\\n * @dev Delegates the current call to the address returned by `_implementation()`.\\n *\\n * This function does not return to its internal call site, it will return directly to the external caller.\\n */\\n function _fallback() internal virtual {\\n _beforeFallback();\\n _delegate(_implementation());\\n }\\n\\n /**\\n * @dev Fallback function that delegates calls to the address returned by `_implementation()`. Will run if no other\\n * function in the contract matches the call data.\\n */\\n fallback() external payable virtual {\\n _fallback();\\n }\\n\\n /**\\n * @dev Fallback function that delegates calls to the address returned by `_implementation()`. Will run if call data\\n * is empty.\\n */\\n receive() external payable virtual {\\n _fallback();\\n }\\n\\n /**\\n * @dev Hook that is called before falling back to the implementation. Can happen as part of a manual `_fallback`\\n * call, or as part of the Solidity `fallback` or `receive` functions.\\n *\\n * If overridden should call `super._beforeFallback()`.\\n */\\n function _beforeFallback() internal virtual {}\\n}\\n\",\"keccak256\":\"0xc130fe33f1b2132158531a87734153293f6d07bc263ff4ac90e85da9c82c0e27\",\"license\":\"MIT\"},\"@openzeppelin/contracts/proxy/beacon/IBeacon.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (proxy/beacon/IBeacon.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev This is the interface that {BeaconProxy} expects of its beacon.\\n */\\ninterface IBeacon {\\n /**\\n * @dev Must return an address that can be used as a delegate call target.\\n *\\n * {BeaconProxy} will check that this address is a contract.\\n */\\n function implementation() external view returns (address);\\n}\\n\",\"keccak256\":\"0xd50a3421ac379ccb1be435fa646d66a65c986b4924f0849839f08692f39dde61\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/Address.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.7.0) (utils/Address.sol)\\n\\npragma solidity ^0.8.1;\\n\\n/**\\n * @dev Collection of functions related to the address type\\n */\\nlibrary Address {\\n /**\\n * @dev Returns true if `account` is a contract.\\n *\\n * [IMPORTANT]\\n * ====\\n * It is unsafe to assume that an address for which this function returns\\n * false is an externally-owned account (EOA) and not a contract.\\n *\\n * Among others, `isContract` will return false for the following\\n * types of addresses:\\n *\\n * - an externally-owned account\\n * - a contract in construction\\n * - an address where a contract will be created\\n * - an address where a contract lived, but was destroyed\\n * ====\\n *\\n * [IMPORTANT]\\n * ====\\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\\n *\\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\\n * constructor.\\n * ====\\n */\\n function isContract(address account) internal view returns (bool) {\\n // This method relies on extcodesize/address.code.length, which returns 0\\n // for contracts in construction, since the code is only stored at the end\\n // of the constructor execution.\\n\\n return account.code.length > 0;\\n }\\n\\n /**\\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\\n * `recipient`, forwarding all available gas and reverting on errors.\\n *\\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\\n * imposed by `transfer`, making them unable to receive funds via\\n * `transfer`. {sendValue} removes this limitation.\\n *\\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\\n *\\n * IMPORTANT: because control is transferred to `recipient`, care must be\\n * taken to not create reentrancy vulnerabilities. Consider using\\n * {ReentrancyGuard} or the\\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\\n */\\n function sendValue(address payable recipient, uint256 amount) internal {\\n require(address(this).balance >= amount, \\\"Address: insufficient balance\\\");\\n\\n (bool success, ) = recipient.call{value: amount}(\\\"\\\");\\n require(success, \\\"Address: unable to send value, recipient may have reverted\\\");\\n }\\n\\n /**\\n * @dev Performs a Solidity function call using a low level `call`. A\\n * plain `call` is an unsafe replacement for a function call: use this\\n * function instead.\\n *\\n * If `target` reverts with a revert reason, it is bubbled up by this\\n * function (like regular Solidity function calls).\\n *\\n * Returns the raw returned data. To convert to the expected return value,\\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\\n *\\n * Requirements:\\n *\\n * - `target` must be a contract.\\n * - calling `target` with `data` must not revert.\\n *\\n * _Available since v3.1._\\n */\\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\\n return functionCall(target, data, \\\"Address: low-level call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\\n * `errorMessage` as a fallback revert reason when `target` reverts.\\n *\\n * _Available since v3.1._\\n */\\n function functionCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n return functionCallWithValue(target, data, 0, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but also transferring `value` wei to `target`.\\n *\\n * Requirements:\\n *\\n * - the calling contract must have an ETH balance of at least `value`.\\n * - the called Solidity function must be `payable`.\\n *\\n * _Available since v3.1._\\n */\\n function functionCallWithValue(\\n address target,\\n bytes memory data,\\n uint256 value\\n ) internal returns (bytes memory) {\\n return functionCallWithValue(target, data, value, \\\"Address: low-level call with value failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\\n * with `errorMessage` as a fallback revert reason when `target` reverts.\\n *\\n * _Available since v3.1._\\n */\\n function functionCallWithValue(\\n address target,\\n bytes memory data,\\n uint256 value,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n require(address(this).balance >= value, \\\"Address: insufficient balance for call\\\");\\n require(isContract(target), \\\"Address: call to non-contract\\\");\\n\\n (bool success, bytes memory returndata) = target.call{value: value}(data);\\n return verifyCallResult(success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but performing a static call.\\n *\\n * _Available since v3.3._\\n */\\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\\n return functionStaticCall(target, data, \\\"Address: low-level static call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\\n * but performing a static call.\\n *\\n * _Available since v3.3._\\n */\\n function functionStaticCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal view returns (bytes memory) {\\n require(isContract(target), \\\"Address: static call to non-contract\\\");\\n\\n (bool success, bytes memory returndata) = target.staticcall(data);\\n return verifyCallResult(success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but performing a delegate call.\\n *\\n * _Available since v3.4._\\n */\\n function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {\\n return functionDelegateCall(target, data, \\\"Address: low-level delegate call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\\n * but performing a delegate call.\\n *\\n * _Available since v3.4._\\n */\\n function functionDelegateCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n require(isContract(target), \\\"Address: delegate call to non-contract\\\");\\n\\n (bool success, bytes memory returndata) = target.delegatecall(data);\\n return verifyCallResult(success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the\\n * revert reason using the provided one.\\n *\\n * _Available since v4.3._\\n */\\n function verifyCallResult(\\n bool success,\\n bytes memory returndata,\\n string memory errorMessage\\n ) internal pure returns (bytes memory) {\\n if (success) {\\n return returndata;\\n } else {\\n // Look for revert reason and bubble it up if present\\n if (returndata.length > 0) {\\n // The easiest way to bubble the revert reason is using memory via assembly\\n /// @solidity memory-safe-assembly\\n assembly {\\n let returndata_size := mload(returndata)\\n revert(add(32, returndata), returndata_size)\\n }\\n } else {\\n revert(errorMessage);\\n }\\n }\\n }\\n}\\n\",\"keccak256\":\"0xd6153ce99bcdcce22b124f755e72553295be6abcd63804cfdffceb188b8bef10\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/StorageSlot.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.7.0) (utils/StorageSlot.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Library for reading and writing primitive types to specific storage slots.\\n *\\n * Storage slots are often used to avoid storage conflict when dealing with upgradeable contracts.\\n * This library helps with reading and writing to such slots without the need for inline assembly.\\n *\\n * The functions in this library return Slot structs that contain a `value` member that can be used to read or write.\\n *\\n * Example usage to set ERC1967 implementation slot:\\n * ```\\n * contract ERC1967 {\\n * bytes32 internal constant _IMPLEMENTATION_SLOT = 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc;\\n *\\n * function _getImplementation() internal view returns (address) {\\n * return StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value;\\n * }\\n *\\n * function _setImplementation(address newImplementation) internal {\\n * require(Address.isContract(newImplementation), \\\"ERC1967: new implementation is not a contract\\\");\\n * StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value = newImplementation;\\n * }\\n * }\\n * ```\\n *\\n * _Available since v4.1 for `address`, `bool`, `bytes32`, and `uint256`._\\n */\\nlibrary StorageSlot {\\n struct AddressSlot {\\n address value;\\n }\\n\\n struct BooleanSlot {\\n bool value;\\n }\\n\\n struct Bytes32Slot {\\n bytes32 value;\\n }\\n\\n struct Uint256Slot {\\n uint256 value;\\n }\\n\\n /**\\n * @dev Returns an `AddressSlot` with member `value` located at `slot`.\\n */\\n function getAddressSlot(bytes32 slot) internal pure returns (AddressSlot storage r) {\\n /// @solidity memory-safe-assembly\\n assembly {\\n r.slot := slot\\n }\\n }\\n\\n /**\\n * @dev Returns an `BooleanSlot` with member `value` located at `slot`.\\n */\\n function getBooleanSlot(bytes32 slot) internal pure returns (BooleanSlot storage r) {\\n /// @solidity memory-safe-assembly\\n assembly {\\n r.slot := slot\\n }\\n }\\n\\n /**\\n * @dev Returns an `Bytes32Slot` with member `value` located at `slot`.\\n */\\n function getBytes32Slot(bytes32 slot) internal pure returns (Bytes32Slot storage r) {\\n /// @solidity memory-safe-assembly\\n assembly {\\n r.slot := slot\\n }\\n }\\n\\n /**\\n * @dev Returns an `Uint256Slot` with member `value` located at `slot`.\\n */\\n function getUint256Slot(bytes32 slot) internal pure returns (Uint256Slot storage r) {\\n /// @solidity memory-safe-assembly\\n assembly {\\n r.slot := slot\\n }\\n }\\n}\\n\",\"keccak256\":\"0xd5c50c54bf02740ebd122ff06832546cb5fa84486d52695a9ccfd11666e0c81d\",\"license\":\"MIT\"},\"contracts/external/TransparentUpgradeableProxy.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-3.0\\n\\npragma solidity ^0.8.12;\\n\\nimport \\\"@openzeppelin/contracts/proxy/ERC1967/ERC1967Proxy.sol\\\";\\n\\n/**\\n * @dev This contract implements a proxy that is upgradeable by an admin. It is fully forked from OpenZeppelin\\n * `TransparentUpgradeableProxy`\\n *\\n * To avoid https://medium.com/nomic-labs-blog/malicious-backdoors-in-ethereum-proxies-62629adf3357[proxy selector\\n * clashing], which can potentially be used in an attack, this contract uses the\\n * https://blog.openzeppelin.com/the-transparent-proxy-pattern/[transparent proxy pattern]. This pattern implies two\\n * things that go hand in hand:\\n *\\n * 1. If any account other than the admin calls the proxy, the call will be forwarded to the implementation, even if\\n * that call matches one of the admin functions exposed by the proxy itself.\\n * 2. If the admin calls the proxy, it can access the admin functions, but its calls will never be forwarded to the\\n * implementation. If the admin tries to call a function on the implementation it will fail with an error that says\\n * \\\"admin cannot fallback to proxy target\\\".\\n *\\n * These properties mean that the admin account can only be used for admin actions like upgrading the proxy or changing\\n * the admin, so it's best if it's a dedicated account that is not used for anything else. This will avoid headaches due\\n * to sudden errors when trying to call a function from the proxy implementation.\\n *\\n * Our recommendation is for the dedicated account to be an instance of the {ProxyAdmin} contract. If set up this way,\\n * you should think of the `ProxyAdmin` instance as the real administrative interface of your proxy.\\n */\\ncontract TransparentUpgradeableProxy is ERC1967Proxy {\\n /**\\n * @dev Initializes an upgradeable proxy managed by `_admin`, backed by the implementation at `_logic`, and\\n * optionally initialized with `_data` as explained in {ERC1967Proxy-constructor}.\\n */\\n constructor(address _logic, address admin_, bytes memory _data) payable ERC1967Proxy(_logic, _data) {\\n assert(_ADMIN_SLOT == bytes32(uint256(keccak256(\\\"eip1967.proxy.admin\\\")) - 1));\\n _changeAdmin(admin_);\\n }\\n\\n /**\\n * @dev Modifier used internally that will delegate the call to the implementation unless the sender is the admin.\\n */\\n modifier ifAdmin() {\\n if (msg.sender == _getAdmin()) {\\n _;\\n } else {\\n _fallback();\\n }\\n }\\n\\n /**\\n * @dev Returns the current admin.\\n *\\n * NOTE: Only the admin can call this function. See {ProxyAdmin-getProxyAdmin}.\\n *\\n * TIP: To get this value clients can read directly from the storage slot shown below (specified by EIP1967) using the\\n * https://eth.wiki/json-rpc/API#eth_getstorageat[`eth_getStorageAt`] RPC call.\\n * `0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103`\\n */\\n function admin() external ifAdmin returns (address admin_) {\\n admin_ = _getAdmin();\\n }\\n\\n /**\\n * @dev Returns the current implementation.\\n *\\n * NOTE: Only the admin can call this function. See {ProxyAdmin-getProxyImplementation}.\\n *\\n * TIP: To get this value clients can read directly from the storage slot shown below (specified by EIP1967) using the\\n * https://eth.wiki/json-rpc/API#eth_getstorageat[`eth_getStorageAt`] RPC call.\\n * `0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc`\\n */\\n function implementation() external ifAdmin returns (address implementation_) {\\n implementation_ = _implementation();\\n }\\n\\n /**\\n * @dev Changes the admin of the proxy.\\n *\\n * Emits an {AdminChanged} event.\\n *\\n * NOTE: Only the admin can call this function. See {ProxyAdmin-changeProxyAdmin}.\\n */\\n function changeAdmin(address newAdmin) external virtual ifAdmin {\\n _changeAdmin(newAdmin);\\n }\\n\\n /**\\n * @dev Upgrade the implementation of the proxy.\\n *\\n * NOTE: Only the admin can call this function. See {ProxyAdmin-upgrade}.\\n */\\n function upgradeTo(address newImplementation) external ifAdmin {\\n _upgradeToAndCall(newImplementation, bytes(\\\"\\\"), false);\\n }\\n\\n /**\\n * @dev Upgrade the implementation of the proxy, and then call a function from the new implementation as specified\\n * by `data`, which should be an encoded function call. This is useful to initialize new storage variables in the\\n * proxied contract.\\n *\\n * NOTE: Only the admin can call this function. See {ProxyAdmin-upgradeAndCall}.\\n */\\n function upgradeToAndCall(address newImplementation, bytes calldata data) external payable ifAdmin {\\n _upgradeToAndCall(newImplementation, data, true);\\n }\\n\\n /**\\n * @dev Returns the current admin.\\n */\\n function _admin() internal view virtual returns (address) {\\n return _getAdmin();\\n }\\n\\n /**\\n * @dev Makes sure the admin cannot access the fallback function. See {Proxy-_beforeFallback}.\\n */\\n function _beforeFallback() internal virtual override {\\n require(msg.sender != _getAdmin(), \\\"TransparentUpgradeableProxy: admin cannot fallback to proxy target\\\");\\n super._beforeFallback();\\n }\\n}\\n\",\"keccak256\":\"0x93a67a0f612ea3ff2a76315e138a6a88267270a1379d3cc7be52845fbbe611e2\",\"license\":\"GPL-3.0\"}},\"version\":1}", + "bytecode": "0x6080604052604051620010bb380380620010bb8339810160408190526200002691620004d8565b828162000036828260006200009a565b5062000066905060017fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6104620005b8565b6000805160206200107483398151915214620000865762000086620005da565b6200009182620000d7565b50505062000643565b620000a58362000132565b600082511180620000b35750805b15620000d257620000d083836200017460201b6200028c1760201c565b505b505050565b7f7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f62000102620001a5565b604080516001600160a01b03928316815291841660208301520160405180910390a16200012f81620001de565b50565b6200013d8162000293565b6040516001600160a01b038216907fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b90600090a250565b60606200019c8383604051806060016040528060278152602001620010946027913962000347565b90505b92915050565b6000620001cf6000805160206200107483398151915260001b6200042f60201b6200022e1760201c565b546001600160a01b0316919050565b6001600160a01b038116620002495760405162461bcd60e51b815260206004820152602660248201527f455243313936373a206e65772061646d696e20697320746865207a65726f206160448201526564647265737360d01b60648201526084015b60405180910390fd5b80620002726000805160206200107483398151915260001b6200042f60201b6200022e1760201c565b80546001600160a01b0319166001600160a01b039290921691909117905550565b620002a9816200043260201b620002b81760201c565b6200030d5760405162461bcd60e51b815260206004820152602d60248201527f455243313936373a206e657720696d706c656d656e746174696f6e206973206e60448201526c1bdd08184818dbdb9d1c9858dd609a1b606482015260840162000240565b80620002727f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc60001b6200042f60201b6200022e1760201c565b60606001600160a01b0384163b620003b15760405162461bcd60e51b815260206004820152602660248201527f416464726573733a2064656c65676174652063616c6c20746f206e6f6e2d636f6044820152651b9d1c9858dd60d21b606482015260840162000240565b600080856001600160a01b031685604051620003ce9190620005f0565b600060405180830381855af49150503d80600081146200040b576040519150601f19603f3d011682016040523d82523d6000602084013e62000410565b606091505b5090925090506200042382828662000441565b925050505b9392505050565b90565b6001600160a01b03163b151590565b606083156200045257508162000428565b825115620004635782518084602001fd5b8160405162461bcd60e51b81526004016200024091906200060e565b80516001600160a01b03811681146200049757600080fd5b919050565b634e487b7160e01b600052604160045260246000fd5b60005b83811015620004cf578181015183820152602001620004b5565b50506000910152565b600080600060608486031215620004ee57600080fd5b620004f9846200047f565b925062000509602085016200047f565b60408501519092506001600160401b03808211156200052757600080fd5b818601915086601f8301126200053c57600080fd5b8151818111156200055157620005516200049c565b604051601f8201601f19908116603f011681019083821181831017156200057c576200057c6200049c565b816040528281528960208487010111156200059657600080fd5b620005a9836020830160208801620004b2565b80955050505050509250925092565b818103818111156200019f57634e487b7160e01b600052601160045260246000fd5b634e487b7160e01b600052600160045260246000fd5b6000825162000604818460208701620004b2565b9190910192915050565b60208152600082518060208401526200062f816040850160208701620004b2565b601f01601f19169190910160400192915050565b610a2180620006536000396000f3fe60806040526004361061005e5760003560e01c80635c60da1b116100435780635c60da1b146100a85780638f283970146100e6578063f851a440146101065761006d565b80633659cfe6146100755780634f1ef286146100955761006d565b3661006d5761006b61011b565b005b61006b61011b565b34801561008157600080fd5b5061006b610090366004610895565b610135565b61006b6100a33660046108b0565b61017f565b3480156100b457600080fd5b506100bd6101f3565b60405173ffffffffffffffffffffffffffffffffffffffff909116815260200160405180910390f35b3480156100f257600080fd5b5061006b610101366004610895565b610231565b34801561011257600080fd5b506100bd61025e565b6101236102d4565b61013361012e6103ab565b6103b5565b565b61013d6103d9565b73ffffffffffffffffffffffffffffffffffffffff1633036101775761017481604051806020016040528060008152506000610419565b50565b61017461011b565b6101876103d9565b73ffffffffffffffffffffffffffffffffffffffff1633036101eb576101e68383838080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525060019250610419915050565b505050565b6101e661011b565b60006101fd6103d9565b73ffffffffffffffffffffffffffffffffffffffff163303610226576102216103ab565b905090565b61022e61011b565b90565b6102396103d9565b73ffffffffffffffffffffffffffffffffffffffff1633036101775761017481610444565b60006102686103d9565b73ffffffffffffffffffffffffffffffffffffffff163303610226576102216103d9565b60606102b183836040518060600160405280602781526020016109c5602791396104a5565b9392505050565b73ffffffffffffffffffffffffffffffffffffffff163b151590565b6102dc6103d9565b73ffffffffffffffffffffffffffffffffffffffff163303610133576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604260248201527f5472616e73706172656e745570677261646561626c6550726f78793a2061646d60448201527f696e2063616e6e6f742066616c6c6261636b20746f2070726f7879207461726760648201527f6574000000000000000000000000000000000000000000000000000000000000608482015260a4015b60405180910390fd5b60006102216105cd565b3660008037600080366000845af43d6000803e8080156103d4573d6000f35b3d6000fd5b60007fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035b5473ffffffffffffffffffffffffffffffffffffffff16919050565b610422836105f5565b60008251118061042f5750805b156101e65761043e838361028c565b50505050565b7f7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f61046d6103d9565b6040805173ffffffffffffffffffffffffffffffffffffffff928316815291841660208301520160405180910390a161017481610642565b606073ffffffffffffffffffffffffffffffffffffffff84163b61054b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f416464726573733a2064656c65676174652063616c6c20746f206e6f6e2d636f60448201527f6e7472616374000000000000000000000000000000000000000000000000000060648201526084016103a2565b6000808573ffffffffffffffffffffffffffffffffffffffff16856040516105739190610957565b600060405180830381855af49150503d80600081146105ae576040519150601f19603f3d011682016040523d82523d6000602084013e6105b3565b606091505b50915091506105c382828661074e565b9695505050505050565b60007f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc6103fd565b6105fe816107a1565b60405173ffffffffffffffffffffffffffffffffffffffff8216907fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b90600090a250565b73ffffffffffffffffffffffffffffffffffffffff81166106e5576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f455243313936373a206e65772061646d696e20697320746865207a65726f206160448201527f646472657373000000000000000000000000000000000000000000000000000060648201526084016103a2565b807fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035b80547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff9290921691909117905550565b6060831561075d5750816102b1565b82511561076d5782518084602001fd5b816040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016103a29190610973565b73ffffffffffffffffffffffffffffffffffffffff81163b610845576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602d60248201527f455243313936373a206e657720696d706c656d656e746174696f6e206973206e60448201527f6f74206120636f6e74726163740000000000000000000000000000000000000060648201526084016103a2565b807f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc610708565b803573ffffffffffffffffffffffffffffffffffffffff8116811461089057600080fd5b919050565b6000602082840312156108a757600080fd5b6102b18261086c565b6000806000604084860312156108c557600080fd5b6108ce8461086c565b9250602084013567ffffffffffffffff808211156108eb57600080fd5b818601915086601f8301126108ff57600080fd5b81358181111561090e57600080fd5b87602082850101111561092057600080fd5b6020830194508093505050509250925092565b60005b8381101561094e578181015183820152602001610936565b50506000910152565b60008251610969818460208701610933565b9190910192915050565b6020815260008251806020840152610992816040850160208701610933565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016919091016040019291505056fe416464726573733a206c6f772d6c6576656c2064656c65676174652063616c6c206661696c6564a2646970667358221220e96638b07fb1675d93a95c49e417bc8111448b23a59918698cdcd8fd488dd7cf64736f6c63430008110033b53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103416464726573733a206c6f772d6c6576656c2064656c65676174652063616c6c206661696c6564", + "deployedBytecode": "0x60806040526004361061005e5760003560e01c80635c60da1b116100435780635c60da1b146100a85780638f283970146100e6578063f851a440146101065761006d565b80633659cfe6146100755780634f1ef286146100955761006d565b3661006d5761006b61011b565b005b61006b61011b565b34801561008157600080fd5b5061006b610090366004610895565b610135565b61006b6100a33660046108b0565b61017f565b3480156100b457600080fd5b506100bd6101f3565b60405173ffffffffffffffffffffffffffffffffffffffff909116815260200160405180910390f35b3480156100f257600080fd5b5061006b610101366004610895565b610231565b34801561011257600080fd5b506100bd61025e565b6101236102d4565b61013361012e6103ab565b6103b5565b565b61013d6103d9565b73ffffffffffffffffffffffffffffffffffffffff1633036101775761017481604051806020016040528060008152506000610419565b50565b61017461011b565b6101876103d9565b73ffffffffffffffffffffffffffffffffffffffff1633036101eb576101e68383838080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525060019250610419915050565b505050565b6101e661011b565b60006101fd6103d9565b73ffffffffffffffffffffffffffffffffffffffff163303610226576102216103ab565b905090565b61022e61011b565b90565b6102396103d9565b73ffffffffffffffffffffffffffffffffffffffff1633036101775761017481610444565b60006102686103d9565b73ffffffffffffffffffffffffffffffffffffffff163303610226576102216103d9565b60606102b183836040518060600160405280602781526020016109c5602791396104a5565b9392505050565b73ffffffffffffffffffffffffffffffffffffffff163b151590565b6102dc6103d9565b73ffffffffffffffffffffffffffffffffffffffff163303610133576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604260248201527f5472616e73706172656e745570677261646561626c6550726f78793a2061646d60448201527f696e2063616e6e6f742066616c6c6261636b20746f2070726f7879207461726760648201527f6574000000000000000000000000000000000000000000000000000000000000608482015260a4015b60405180910390fd5b60006102216105cd565b3660008037600080366000845af43d6000803e8080156103d4573d6000f35b3d6000fd5b60007fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035b5473ffffffffffffffffffffffffffffffffffffffff16919050565b610422836105f5565b60008251118061042f5750805b156101e65761043e838361028c565b50505050565b7f7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f61046d6103d9565b6040805173ffffffffffffffffffffffffffffffffffffffff928316815291841660208301520160405180910390a161017481610642565b606073ffffffffffffffffffffffffffffffffffffffff84163b61054b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f416464726573733a2064656c65676174652063616c6c20746f206e6f6e2d636f60448201527f6e7472616374000000000000000000000000000000000000000000000000000060648201526084016103a2565b6000808573ffffffffffffffffffffffffffffffffffffffff16856040516105739190610957565b600060405180830381855af49150503d80600081146105ae576040519150601f19603f3d011682016040523d82523d6000602084013e6105b3565b606091505b50915091506105c382828661074e565b9695505050505050565b60007f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc6103fd565b6105fe816107a1565b60405173ffffffffffffffffffffffffffffffffffffffff8216907fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b90600090a250565b73ffffffffffffffffffffffffffffffffffffffff81166106e5576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f455243313936373a206e65772061646d696e20697320746865207a65726f206160448201527f646472657373000000000000000000000000000000000000000000000000000060648201526084016103a2565b807fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035b80547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff9290921691909117905550565b6060831561075d5750816102b1565b82511561076d5782518084602001fd5b816040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016103a29190610973565b73ffffffffffffffffffffffffffffffffffffffff81163b610845576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602d60248201527f455243313936373a206e657720696d706c656d656e746174696f6e206973206e60448201527f6f74206120636f6e74726163740000000000000000000000000000000000000060648201526084016103a2565b807f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc610708565b803573ffffffffffffffffffffffffffffffffffffffff8116811461089057600080fd5b919050565b6000602082840312156108a757600080fd5b6102b18261086c565b6000806000604084860312156108c557600080fd5b6108ce8461086c565b9250602084013567ffffffffffffffff808211156108eb57600080fd5b818601915086601f8301126108ff57600080fd5b81358181111561090e57600080fd5b87602082850101111561092057600080fd5b6020830194508093505050509250925092565b60005b8381101561094e578181015183820152602001610936565b50506000910152565b60008251610969818460208701610933565b9190910192915050565b6020815260008251806020840152610992816040850160208701610933565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016919091016040019291505056fe416464726573733a206c6f772d6c6576656c2064656c65676174652063616c6c206661696c6564a2646970667358221220e96638b07fb1675d93a95c49e417bc8111448b23a59918698cdcd8fd488dd7cf64736f6c63430008110033", + "devdoc": { + "details": "This contract implements a proxy that is upgradeable by an admin. It is fully forked from OpenZeppelin `TransparentUpgradeableProxy` To avoid https://medium.com/nomic-labs-blog/malicious-backdoors-in-ethereum-proxies-62629adf3357[proxy selector clashing], which can potentially be used in an attack, this contract uses the https://blog.openzeppelin.com/the-transparent-proxy-pattern/[transparent proxy pattern]. This pattern implies two things that go hand in hand: 1. If any account other than the admin calls the proxy, the call will be forwarded to the implementation, even if that call matches one of the admin functions exposed by the proxy itself. 2. If the admin calls the proxy, it can access the admin functions, but its calls will never be forwarded to the implementation. If the admin tries to call a function on the implementation it will fail with an error that says \"admin cannot fallback to proxy target\". These properties mean that the admin account can only be used for admin actions like upgrading the proxy or changing the admin, so it's best if it's a dedicated account that is not used for anything else. This will avoid headaches due to sudden errors when trying to call a function from the proxy implementation. Our recommendation is for the dedicated account to be an instance of the {ProxyAdmin} contract. If set up this way, you should think of the `ProxyAdmin` instance as the real administrative interface of your proxy.", + "kind": "dev", + "methods": { + "admin()": { + "details": "Returns the current admin. NOTE: Only the admin can call this function. See {ProxyAdmin-getProxyAdmin}. TIP: To get this value clients can read directly from the storage slot shown below (specified by EIP1967) using the https://eth.wiki/json-rpc/API#eth_getstorageat[`eth_getStorageAt`] RPC call. `0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103`" + }, + "changeAdmin(address)": { + "details": "Changes the admin of the proxy. Emits an {AdminChanged} event. NOTE: Only the admin can call this function. See {ProxyAdmin-changeProxyAdmin}." + }, + "constructor": { + "details": "Initializes an upgradeable proxy managed by `_admin`, backed by the implementation at `_logic`, and optionally initialized with `_data` as explained in {ERC1967Proxy-constructor}." + }, + "implementation()": { + "details": "Returns the current implementation. NOTE: Only the admin can call this function. See {ProxyAdmin-getProxyImplementation}. TIP: To get this value clients can read directly from the storage slot shown below (specified by EIP1967) using the https://eth.wiki/json-rpc/API#eth_getstorageat[`eth_getStorageAt`] RPC call. `0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc`" + }, + "upgradeTo(address)": { + "details": "Upgrade the implementation of the proxy. NOTE: Only the admin can call this function. See {ProxyAdmin-upgrade}." + }, + "upgradeToAndCall(address,bytes)": { + "details": "Upgrade the implementation of the proxy, and then call a function from the new implementation as specified by `data`, which should be an encoded function call. This is useful to initialize new storage variables in the proxied contract. NOTE: Only the admin can call this function. See {ProxyAdmin-upgradeAndCall}." + } + }, + "version": 1 + }, + "userdoc": { + "kind": "user", + "methods": {}, + "version": 1 + }, + "storageLayout": { + "storage": [], + "types": null + } +} \ No newline at end of file diff --git a/deployments/optimism/solcInputs/871924e0c138825a2736b76def8fef8d.json b/deployments/optimism/solcInputs/871924e0c138825a2736b76def8fef8d.json new file mode 100644 index 00000000..57454028 --- /dev/null +++ b/deployments/optimism/solcInputs/871924e0c138825a2736b76def8fef8d.json @@ -0,0 +1,562 @@ +{ + "language": "Solidity", + "sources": { + "@chainlink/contracts/src/v0.8/interfaces/AggregatorV3Interface.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.0;\n\ninterface AggregatorV3Interface {\n\n function decimals()\n external\n view\n returns (\n uint8\n );\n\n function description()\n external\n view\n returns (\n string memory\n );\n\n function version()\n external\n view\n returns (\n uint256\n );\n\n // getRoundData and latestRoundData should both raise \"No data present\"\n // if they do not have data to report, instead of returning unset values\n // which could be misinterpreted as actual reported values.\n function getRoundData(\n uint80 _roundId\n )\n external\n view\n returns (\n uint80 roundId,\n int256 answer,\n uint256 startedAt,\n uint256 updatedAt,\n uint80 answeredInRound\n );\n\n function latestRoundData()\n external\n view\n returns (\n uint80 roundId,\n int256 answer,\n uint256 startedAt,\n uint256 updatedAt,\n uint80 answeredInRound\n );\n\n}\n" + }, + "@openzeppelin/contracts-upgradeable/access/AccessControlEnumerableUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.5.0) (access/AccessControlEnumerable.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./IAccessControlEnumerableUpgradeable.sol\";\nimport \"./AccessControlUpgradeable.sol\";\nimport \"../utils/structs/EnumerableSetUpgradeable.sol\";\nimport \"../proxy/utils/Initializable.sol\";\n\n/**\n * @dev Extension of {AccessControl} that allows enumerating the members of each role.\n */\nabstract contract AccessControlEnumerableUpgradeable is Initializable, IAccessControlEnumerableUpgradeable, AccessControlUpgradeable {\n function __AccessControlEnumerable_init() internal onlyInitializing {\n }\n\n function __AccessControlEnumerable_init_unchained() internal onlyInitializing {\n }\n using EnumerableSetUpgradeable for EnumerableSetUpgradeable.AddressSet;\n\n mapping(bytes32 => EnumerableSetUpgradeable.AddressSet) private _roleMembers;\n\n /**\n * @dev See {IERC165-supportsInterface}.\n */\n function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {\n return interfaceId == type(IAccessControlEnumerableUpgradeable).interfaceId || super.supportsInterface(interfaceId);\n }\n\n /**\n * @dev Returns one of the accounts that have `role`. `index` must be a\n * value between 0 and {getRoleMemberCount}, non-inclusive.\n *\n * Role bearers are not sorted in any particular way, and their ordering may\n * change at any point.\n *\n * WARNING: When using {getRoleMember} and {getRoleMemberCount}, make sure\n * you perform all queries on the same block. See the following\n * https://forum.openzeppelin.com/t/iterating-over-elements-on-enumerableset-in-openzeppelin-contracts/2296[forum post]\n * for more information.\n */\n function getRoleMember(bytes32 role, uint256 index) public view virtual override returns (address) {\n return _roleMembers[role].at(index);\n }\n\n /**\n * @dev Returns the number of accounts that have `role`. Can be used\n * together with {getRoleMember} to enumerate all bearers of a role.\n */\n function getRoleMemberCount(bytes32 role) public view virtual override returns (uint256) {\n return _roleMembers[role].length();\n }\n\n /**\n * @dev Overload {_grantRole} to track enumerable memberships\n */\n function _grantRole(bytes32 role, address account) internal virtual override {\n super._grantRole(role, account);\n _roleMembers[role].add(account);\n }\n\n /**\n * @dev Overload {_revokeRole} to track enumerable memberships\n */\n function _revokeRole(bytes32 role, address account) internal virtual override {\n super._revokeRole(role, account);\n _roleMembers[role].remove(account);\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[49] private __gap;\n}\n" + }, + "@openzeppelin/contracts-upgradeable/access/AccessControlUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (access/AccessControl.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./IAccessControlUpgradeable.sol\";\nimport \"../utils/ContextUpgradeable.sol\";\nimport \"../utils/StringsUpgradeable.sol\";\nimport \"../utils/introspection/ERC165Upgradeable.sol\";\nimport \"../proxy/utils/Initializable.sol\";\n\n/**\n * @dev Contract module that allows children to implement role-based access\n * control mechanisms. This is a lightweight version that doesn't allow enumerating role\n * members except through off-chain means by accessing the contract event logs. Some\n * applications may benefit from on-chain enumerability, for those cases see\n * {AccessControlEnumerable}.\n *\n * Roles are referred to by their `bytes32` identifier. These should be exposed\n * in the external API and be unique. The best way to achieve this is by\n * using `public constant` hash digests:\n *\n * ```\n * bytes32 public constant MY_ROLE = keccak256(\"MY_ROLE\");\n * ```\n *\n * Roles can be used to represent a set of permissions. To restrict access to a\n * function call, use {hasRole}:\n *\n * ```\n * function foo() public {\n * require(hasRole(MY_ROLE, msg.sender));\n * ...\n * }\n * ```\n *\n * Roles can be granted and revoked dynamically via the {grantRole} and\n * {revokeRole} functions. Each role has an associated admin role, and only\n * accounts that have a role's admin role can call {grantRole} and {revokeRole}.\n *\n * By default, the admin role for all roles is `DEFAULT_ADMIN_ROLE`, which means\n * that only accounts with this role will be able to grant or revoke other\n * roles. More complex role relationships can be created by using\n * {_setRoleAdmin}.\n *\n * WARNING: The `DEFAULT_ADMIN_ROLE` is also its own admin: it has permission to\n * grant and revoke this role. Extra precautions should be taken to secure\n * accounts that have been granted it.\n */\nabstract contract AccessControlUpgradeable is Initializable, ContextUpgradeable, IAccessControlUpgradeable, ERC165Upgradeable {\n function __AccessControl_init() internal onlyInitializing {\n }\n\n function __AccessControl_init_unchained() internal onlyInitializing {\n }\n struct RoleData {\n mapping(address => bool) members;\n bytes32 adminRole;\n }\n\n mapping(bytes32 => RoleData) private _roles;\n\n bytes32 public constant DEFAULT_ADMIN_ROLE = 0x00;\n\n /**\n * @dev Modifier that checks that an account has a specific role. Reverts\n * with a standardized message including the required role.\n *\n * The format of the revert reason is given by the following regular expression:\n *\n * /^AccessControl: account (0x[0-9a-f]{40}) is missing role (0x[0-9a-f]{64})$/\n *\n * _Available since v4.1._\n */\n modifier onlyRole(bytes32 role) {\n _checkRole(role);\n _;\n }\n\n /**\n * @dev See {IERC165-supportsInterface}.\n */\n function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {\n return interfaceId == type(IAccessControlUpgradeable).interfaceId || super.supportsInterface(interfaceId);\n }\n\n /**\n * @dev Returns `true` if `account` has been granted `role`.\n */\n function hasRole(bytes32 role, address account) public view virtual override returns (bool) {\n return _roles[role].members[account];\n }\n\n /**\n * @dev Revert with a standard message if `_msgSender()` is missing `role`.\n * Overriding this function changes the behavior of the {onlyRole} modifier.\n *\n * Format of the revert message is described in {_checkRole}.\n *\n * _Available since v4.6._\n */\n function _checkRole(bytes32 role) internal view virtual {\n _checkRole(role, _msgSender());\n }\n\n /**\n * @dev Revert with a standard message if `account` is missing `role`.\n *\n * The format of the revert reason is given by the following regular expression:\n *\n * /^AccessControl: account (0x[0-9a-f]{40}) is missing role (0x[0-9a-f]{64})$/\n */\n function _checkRole(bytes32 role, address account) internal view virtual {\n if (!hasRole(role, account)) {\n revert(\n string(\n abi.encodePacked(\n \"AccessControl: account \",\n StringsUpgradeable.toHexString(uint160(account), 20),\n \" is missing role \",\n StringsUpgradeable.toHexString(uint256(role), 32)\n )\n )\n );\n }\n }\n\n /**\n * @dev Returns the admin role that controls `role`. See {grantRole} and\n * {revokeRole}.\n *\n * To change a role's admin, use {_setRoleAdmin}.\n */\n function getRoleAdmin(bytes32 role) public view virtual override returns (bytes32) {\n return _roles[role].adminRole;\n }\n\n /**\n * @dev Grants `role` to `account`.\n *\n * If `account` had not been already granted `role`, emits a {RoleGranted}\n * event.\n *\n * Requirements:\n *\n * - the caller must have ``role``'s admin role.\n *\n * May emit a {RoleGranted} event.\n */\n function grantRole(bytes32 role, address account) public virtual override onlyRole(getRoleAdmin(role)) {\n _grantRole(role, account);\n }\n\n /**\n * @dev Revokes `role` from `account`.\n *\n * If `account` had been granted `role`, emits a {RoleRevoked} event.\n *\n * Requirements:\n *\n * - the caller must have ``role``'s admin role.\n *\n * May emit a {RoleRevoked} event.\n */\n function revokeRole(bytes32 role, address account) public virtual override onlyRole(getRoleAdmin(role)) {\n _revokeRole(role, account);\n }\n\n /**\n * @dev Revokes `role` from the calling account.\n *\n * Roles are often managed via {grantRole} and {revokeRole}: this function's\n * purpose is to provide a mechanism for accounts to lose their privileges\n * if they are compromised (such as when a trusted device is misplaced).\n *\n * If the calling account had been revoked `role`, emits a {RoleRevoked}\n * event.\n *\n * Requirements:\n *\n * - the caller must be `account`.\n *\n * May emit a {RoleRevoked} event.\n */\n function renounceRole(bytes32 role, address account) public virtual override {\n require(account == _msgSender(), \"AccessControl: can only renounce roles for self\");\n\n _revokeRole(role, account);\n }\n\n /**\n * @dev Grants `role` to `account`.\n *\n * If `account` had not been already granted `role`, emits a {RoleGranted}\n * event. Note that unlike {grantRole}, this function doesn't perform any\n * checks on the calling account.\n *\n * May emit a {RoleGranted} event.\n *\n * [WARNING]\n * ====\n * This function should only be called from the constructor when setting\n * up the initial roles for the system.\n *\n * Using this function in any other way is effectively circumventing the admin\n * system imposed by {AccessControl}.\n * ====\n *\n * NOTE: This function is deprecated in favor of {_grantRole}.\n */\n function _setupRole(bytes32 role, address account) internal virtual {\n _grantRole(role, account);\n }\n\n /**\n * @dev Sets `adminRole` as ``role``'s admin role.\n *\n * Emits a {RoleAdminChanged} event.\n */\n function _setRoleAdmin(bytes32 role, bytes32 adminRole) internal virtual {\n bytes32 previousAdminRole = getRoleAdmin(role);\n _roles[role].adminRole = adminRole;\n emit RoleAdminChanged(role, previousAdminRole, adminRole);\n }\n\n /**\n * @dev Grants `role` to `account`.\n *\n * Internal function without access restriction.\n *\n * May emit a {RoleGranted} event.\n */\n function _grantRole(bytes32 role, address account) internal virtual {\n if (!hasRole(role, account)) {\n _roles[role].members[account] = true;\n emit RoleGranted(role, account, _msgSender());\n }\n }\n\n /**\n * @dev Revokes `role` from `account`.\n *\n * Internal function without access restriction.\n *\n * May emit a {RoleRevoked} event.\n */\n function _revokeRole(bytes32 role, address account) internal virtual {\n if (hasRole(role, account)) {\n _roles[role].members[account] = false;\n emit RoleRevoked(role, account, _msgSender());\n }\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[49] private __gap;\n}\n" + }, + "@openzeppelin/contracts-upgradeable/access/IAccessControlEnumerableUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (access/IAccessControlEnumerable.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./IAccessControlUpgradeable.sol\";\n\n/**\n * @dev External interface of AccessControlEnumerable declared to support ERC165 detection.\n */\ninterface IAccessControlEnumerableUpgradeable is IAccessControlUpgradeable {\n /**\n * @dev Returns one of the accounts that have `role`. `index` must be a\n * value between 0 and {getRoleMemberCount}, non-inclusive.\n *\n * Role bearers are not sorted in any particular way, and their ordering may\n * change at any point.\n *\n * WARNING: When using {getRoleMember} and {getRoleMemberCount}, make sure\n * you perform all queries on the same block. See the following\n * https://forum.openzeppelin.com/t/iterating-over-elements-on-enumerableset-in-openzeppelin-contracts/2296[forum post]\n * for more information.\n */\n function getRoleMember(bytes32 role, uint256 index) external view returns (address);\n\n /**\n * @dev Returns the number of accounts that have `role`. Can be used\n * together with {getRoleMember} to enumerate all bearers of a role.\n */\n function getRoleMemberCount(bytes32 role) external view returns (uint256);\n}\n" + }, + "@openzeppelin/contracts-upgradeable/access/IAccessControlUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (access/IAccessControl.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev External interface of AccessControl declared to support ERC165 detection.\n */\ninterface IAccessControlUpgradeable {\n /**\n * @dev Emitted when `newAdminRole` is set as ``role``'s admin role, replacing `previousAdminRole`\n *\n * `DEFAULT_ADMIN_ROLE` is the starting admin for all roles, despite\n * {RoleAdminChanged} not being emitted signaling this.\n *\n * _Available since v3.1._\n */\n event RoleAdminChanged(bytes32 indexed role, bytes32 indexed previousAdminRole, bytes32 indexed newAdminRole);\n\n /**\n * @dev Emitted when `account` is granted `role`.\n *\n * `sender` is the account that originated the contract call, an admin role\n * bearer except when using {AccessControl-_setupRole}.\n */\n event RoleGranted(bytes32 indexed role, address indexed account, address indexed sender);\n\n /**\n * @dev Emitted when `account` is revoked `role`.\n *\n * `sender` is the account that originated the contract call:\n * - if using `revokeRole`, it is the admin role bearer\n * - if using `renounceRole`, it is the role bearer (i.e. `account`)\n */\n event RoleRevoked(bytes32 indexed role, address indexed account, address indexed sender);\n\n /**\n * @dev Returns `true` if `account` has been granted `role`.\n */\n function hasRole(bytes32 role, address account) external view returns (bool);\n\n /**\n * @dev Returns the admin role that controls `role`. See {grantRole} and\n * {revokeRole}.\n *\n * To change a role's admin, use {AccessControl-_setRoleAdmin}.\n */\n function getRoleAdmin(bytes32 role) external view returns (bytes32);\n\n /**\n * @dev Grants `role` to `account`.\n *\n * If `account` had not been already granted `role`, emits a {RoleGranted}\n * event.\n *\n * Requirements:\n *\n * - the caller must have ``role``'s admin role.\n */\n function grantRole(bytes32 role, address account) external;\n\n /**\n * @dev Revokes `role` from `account`.\n *\n * If `account` had been granted `role`, emits a {RoleRevoked} event.\n *\n * Requirements:\n *\n * - the caller must have ``role``'s admin role.\n */\n function revokeRole(bytes32 role, address account) external;\n\n /**\n * @dev Revokes `role` from the calling account.\n *\n * Roles are often managed via {grantRole} and {revokeRole}: this function's\n * purpose is to provide a mechanism for accounts to lose their privileges\n * if they are compromised (such as when a trusted device is misplaced).\n *\n * If the calling account had been granted `role`, emits a {RoleRevoked}\n * event.\n *\n * Requirements:\n *\n * - the caller must be `account`.\n */\n function renounceRole(bytes32 role, address account) external;\n}\n" + }, + "@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (access/Ownable.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../utils/ContextUpgradeable.sol\";\nimport \"../proxy/utils/Initializable.sol\";\n\n/**\n * @dev Contract module which provides a basic access control mechanism, where\n * there is an account (an owner) that can be granted exclusive access to\n * specific functions.\n *\n * By default, the owner account will be the one that deploys the contract. This\n * can later be changed with {transferOwnership}.\n *\n * This module is used through inheritance. It will make available the modifier\n * `onlyOwner`, which can be applied to your functions to restrict their use to\n * the owner.\n */\nabstract contract OwnableUpgradeable is Initializable, ContextUpgradeable {\n address private _owner;\n\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\n\n /**\n * @dev Initializes the contract setting the deployer as the initial owner.\n */\n function __Ownable_init() internal onlyInitializing {\n __Ownable_init_unchained();\n }\n\n function __Ownable_init_unchained() internal onlyInitializing {\n _transferOwnership(_msgSender());\n }\n\n /**\n * @dev Throws if called by any account other than the owner.\n */\n modifier onlyOwner() {\n _checkOwner();\n _;\n }\n\n /**\n * @dev Returns the address of the current owner.\n */\n function owner() public view virtual returns (address) {\n return _owner;\n }\n\n /**\n * @dev Throws if the sender is not the owner.\n */\n function _checkOwner() internal view virtual {\n require(owner() == _msgSender(), \"Ownable: caller is not the owner\");\n }\n\n /**\n * @dev Leaves the contract without owner. It will not be possible to call\n * `onlyOwner` functions anymore. Can only be called by the current owner.\n *\n * NOTE: Renouncing ownership will leave the contract without an owner,\n * thereby removing any functionality that is only available to the owner.\n */\n function renounceOwnership() public virtual onlyOwner {\n _transferOwnership(address(0));\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Can only be called by the current owner.\n */\n function transferOwnership(address newOwner) public virtual onlyOwner {\n require(newOwner != address(0), \"Ownable: new owner is the zero address\");\n _transferOwnership(newOwner);\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Internal function without access restriction.\n */\n function _transferOwnership(address newOwner) internal virtual {\n address oldOwner = _owner;\n _owner = newOwner;\n emit OwnershipTransferred(oldOwner, newOwner);\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[49] private __gap;\n}\n" + }, + "@openzeppelin/contracts-upgradeable/interfaces/IERC721MetadataUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (interfaces/IERC721Metadata.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../token/ERC721/extensions/IERC721MetadataUpgradeable.sol\";\n" + }, + "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (proxy/utils/Initializable.sol)\n\npragma solidity ^0.8.2;\n\nimport \"../../utils/AddressUpgradeable.sol\";\n\n/**\n * @dev This is a base contract to aid in writing upgradeable contracts, or any kind of contract that will be deployed\n * behind a proxy. Since proxied contracts do not make use of a constructor, it's common to move constructor logic to an\n * external initializer function, usually called `initialize`. It then becomes necessary to protect this initializer\n * function so it can only be called once. The {initializer} modifier provided by this contract will have this effect.\n *\n * The initialization functions use a version number. Once a version number is used, it is consumed and cannot be\n * reused. This mechanism prevents re-execution of each \"step\" but allows the creation of new initialization steps in\n * case an upgrade adds a module that needs to be initialized.\n *\n * For example:\n *\n * [.hljs-theme-light.nopadding]\n * ```\n * contract MyToken is ERC20Upgradeable {\n * function initialize() initializer public {\n * __ERC20_init(\"MyToken\", \"MTK\");\n * }\n * }\n * contract MyTokenV2 is MyToken, ERC20PermitUpgradeable {\n * function initializeV2() reinitializer(2) public {\n * __ERC20Permit_init(\"MyToken\");\n * }\n * }\n * ```\n *\n * TIP: To avoid leaving the proxy in an uninitialized state, the initializer function should be called as early as\n * possible by providing the encoded function call as the `_data` argument to {ERC1967Proxy-constructor}.\n *\n * CAUTION: When used with inheritance, manual care must be taken to not invoke a parent initializer twice, or to ensure\n * that all initializers are idempotent. This is not verified automatically as constructors are by Solidity.\n *\n * [CAUTION]\n * ====\n * Avoid leaving a contract uninitialized.\n *\n * An uninitialized contract can be taken over by an attacker. This applies to both a proxy and its implementation\n * contract, which may impact the proxy. To prevent the implementation contract from being used, you should invoke\n * the {_disableInitializers} function in the constructor to automatically lock it when it is deployed:\n *\n * [.hljs-theme-light.nopadding]\n * ```\n * /// @custom:oz-upgrades-unsafe-allow constructor\n * constructor() {\n * _disableInitializers();\n * }\n * ```\n * ====\n */\nabstract contract Initializable {\n /**\n * @dev Indicates that the contract has been initialized.\n * @custom:oz-retyped-from bool\n */\n uint8 private _initialized;\n\n /**\n * @dev Indicates that the contract is in the process of being initialized.\n */\n bool private _initializing;\n\n /**\n * @dev Triggered when the contract has been initialized or reinitialized.\n */\n event Initialized(uint8 version);\n\n /**\n * @dev A modifier that defines a protected initializer function that can be invoked at most once. In its scope,\n * `onlyInitializing` functions can be used to initialize parent contracts. Equivalent to `reinitializer(1)`.\n */\n modifier initializer() {\n bool isTopLevelCall = !_initializing;\n require(\n (isTopLevelCall && _initialized < 1) || (!AddressUpgradeable.isContract(address(this)) && _initialized == 1),\n \"Initializable: contract is already initialized\"\n );\n _initialized = 1;\n if (isTopLevelCall) {\n _initializing = true;\n }\n _;\n if (isTopLevelCall) {\n _initializing = false;\n emit Initialized(1);\n }\n }\n\n /**\n * @dev A modifier that defines a protected reinitializer function that can be invoked at most once, and only if the\n * contract hasn't been initialized to a greater version before. In its scope, `onlyInitializing` functions can be\n * used to initialize parent contracts.\n *\n * `initializer` is equivalent to `reinitializer(1)`, so a reinitializer may be used after the original\n * initialization step. This is essential to configure modules that are added through upgrades and that require\n * initialization.\n *\n * Note that versions can jump in increments greater than 1; this implies that if multiple reinitializers coexist in\n * a contract, executing them in the right order is up to the developer or operator.\n */\n modifier reinitializer(uint8 version) {\n require(!_initializing && _initialized < version, \"Initializable: contract is already initialized\");\n _initialized = version;\n _initializing = true;\n _;\n _initializing = false;\n emit Initialized(version);\n }\n\n /**\n * @dev Modifier to protect an initialization function so that it can only be invoked by functions with the\n * {initializer} and {reinitializer} modifiers, directly or indirectly.\n */\n modifier onlyInitializing() {\n require(_initializing, \"Initializable: contract is not initializing\");\n _;\n }\n\n /**\n * @dev Locks the contract, preventing any future reinitialization. This cannot be part of an initializer call.\n * Calling this in the constructor of a contract will prevent that contract from being initialized or reinitialized\n * to any version. It is recommended to use this to lock implementation contracts that are designed to be called\n * through proxies.\n */\n function _disableInitializers() internal virtual {\n require(!_initializing, \"Initializable: contract is initializing\");\n if (_initialized < type(uint8).max) {\n _initialized = type(uint8).max;\n emit Initialized(type(uint8).max);\n }\n }\n}\n" + }, + "@openzeppelin/contracts-upgradeable/security/PausableUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (security/Pausable.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../utils/ContextUpgradeable.sol\";\nimport \"../proxy/utils/Initializable.sol\";\n\n/**\n * @dev Contract module which allows children to implement an emergency stop\n * mechanism that can be triggered by an authorized account.\n *\n * This module is used through inheritance. It will make available the\n * modifiers `whenNotPaused` and `whenPaused`, which can be applied to\n * the functions of your contract. Note that they will not be pausable by\n * simply including this module, only once the modifiers are put in place.\n */\nabstract contract PausableUpgradeable is Initializable, ContextUpgradeable {\n /**\n * @dev Emitted when the pause is triggered by `account`.\n */\n event Paused(address account);\n\n /**\n * @dev Emitted when the pause is lifted by `account`.\n */\n event Unpaused(address account);\n\n bool private _paused;\n\n /**\n * @dev Initializes the contract in unpaused state.\n */\n function __Pausable_init() internal onlyInitializing {\n __Pausable_init_unchained();\n }\n\n function __Pausable_init_unchained() internal onlyInitializing {\n _paused = false;\n }\n\n /**\n * @dev Modifier to make a function callable only when the contract is not paused.\n *\n * Requirements:\n *\n * - The contract must not be paused.\n */\n modifier whenNotPaused() {\n _requireNotPaused();\n _;\n }\n\n /**\n * @dev Modifier to make a function callable only when the contract is paused.\n *\n * Requirements:\n *\n * - The contract must be paused.\n */\n modifier whenPaused() {\n _requirePaused();\n _;\n }\n\n /**\n * @dev Returns true if the contract is paused, and false otherwise.\n */\n function paused() public view virtual returns (bool) {\n return _paused;\n }\n\n /**\n * @dev Throws if the contract is paused.\n */\n function _requireNotPaused() internal view virtual {\n require(!paused(), \"Pausable: paused\");\n }\n\n /**\n * @dev Throws if the contract is not paused.\n */\n function _requirePaused() internal view virtual {\n require(paused(), \"Pausable: not paused\");\n }\n\n /**\n * @dev Triggers stopped state.\n *\n * Requirements:\n *\n * - The contract must not be paused.\n */\n function _pause() internal virtual whenNotPaused {\n _paused = true;\n emit Paused(_msgSender());\n }\n\n /**\n * @dev Returns to normal state.\n *\n * Requirements:\n *\n * - The contract must be paused.\n */\n function _unpause() internal virtual whenPaused {\n _paused = false;\n emit Unpaused(_msgSender());\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[49] private __gap;\n}\n" + }, + "@openzeppelin/contracts-upgradeable/security/ReentrancyGuardUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (security/ReentrancyGuard.sol)\n\npragma solidity ^0.8.0;\nimport \"../proxy/utils/Initializable.sol\";\n\n/**\n * @dev Contract module that helps prevent reentrant calls to a function.\n *\n * Inheriting from `ReentrancyGuard` will make the {nonReentrant} modifier\n * available, which can be applied to functions to make sure there are no nested\n * (reentrant) calls to them.\n *\n * Note that because there is a single `nonReentrant` guard, functions marked as\n * `nonReentrant` may not call one another. This can be worked around by making\n * those functions `private`, and then adding `external` `nonReentrant` entry\n * points to them.\n *\n * TIP: If you would like to learn more about reentrancy and alternative ways\n * to protect against it, check out our blog post\n * https://blog.openzeppelin.com/reentrancy-after-istanbul/[Reentrancy After Istanbul].\n */\nabstract contract ReentrancyGuardUpgradeable is Initializable {\n // Booleans are more expensive than uint256 or any type that takes up a full\n // word because each write operation emits an extra SLOAD to first read the\n // slot's contents, replace the bits taken up by the boolean, and then write\n // back. This is the compiler's defense against contract upgrades and\n // pointer aliasing, and it cannot be disabled.\n\n // The values being non-zero value makes deployment a bit more expensive,\n // but in exchange the refund on every call to nonReentrant will be lower in\n // amount. Since refunds are capped to a percentage of the total\n // transaction's gas, it is best to keep them low in cases like this one, to\n // increase the likelihood of the full refund coming into effect.\n uint256 private constant _NOT_ENTERED = 1;\n uint256 private constant _ENTERED = 2;\n\n uint256 private _status;\n\n function __ReentrancyGuard_init() internal onlyInitializing {\n __ReentrancyGuard_init_unchained();\n }\n\n function __ReentrancyGuard_init_unchained() internal onlyInitializing {\n _status = _NOT_ENTERED;\n }\n\n /**\n * @dev Prevents a contract from calling itself, directly or indirectly.\n * Calling a `nonReentrant` function from another `nonReentrant`\n * function is not supported. It is possible to prevent this from happening\n * by making the `nonReentrant` function external, and making it call a\n * `private` function that does the actual work.\n */\n modifier nonReentrant() {\n // On the first call to nonReentrant, _notEntered will be true\n require(_status != _ENTERED, \"ReentrancyGuard: reentrant call\");\n\n // Any calls to nonReentrant after this point will fail\n _status = _ENTERED;\n\n _;\n\n // By storing the original value once again, a refund is triggered (see\n // https://eips.ethereum.org/EIPS/eip-2200)\n _status = _NOT_ENTERED;\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[49] private __gap;\n}\n" + }, + "@openzeppelin/contracts-upgradeable/token/ERC20/ERC20Upgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (token/ERC20/ERC20.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./IERC20Upgradeable.sol\";\nimport \"./extensions/IERC20MetadataUpgradeable.sol\";\nimport \"../../utils/ContextUpgradeable.sol\";\nimport \"../../proxy/utils/Initializable.sol\";\n\n/**\n * @dev Implementation of the {IERC20} interface.\n *\n * This implementation is agnostic to the way tokens are created. This means\n * that a supply mechanism has to be added in a derived contract using {_mint}.\n * For a generic mechanism see {ERC20PresetMinterPauser}.\n *\n * TIP: For a detailed writeup see our guide\n * https://forum.zeppelin.solutions/t/how-to-implement-erc20-supply-mechanisms/226[How\n * to implement supply mechanisms].\n *\n * We have followed general OpenZeppelin Contracts guidelines: functions revert\n * instead returning `false` on failure. This behavior is nonetheless\n * conventional and does not conflict with the expectations of ERC20\n * applications.\n *\n * Additionally, an {Approval} event is emitted on calls to {transferFrom}.\n * This allows applications to reconstruct the allowance for all accounts just\n * by listening to said events. Other implementations of the EIP may not emit\n * these events, as it isn't required by the specification.\n *\n * Finally, the non-standard {decreaseAllowance} and {increaseAllowance}\n * functions have been added to mitigate the well-known issues around setting\n * allowances. See {IERC20-approve}.\n */\ncontract ERC20Upgradeable is Initializable, ContextUpgradeable, IERC20Upgradeable, IERC20MetadataUpgradeable {\n mapping(address => uint256) private _balances;\n\n mapping(address => mapping(address => uint256)) private _allowances;\n\n uint256 private _totalSupply;\n\n string private _name;\n string private _symbol;\n\n /**\n * @dev Sets the values for {name} and {symbol}.\n *\n * The default value of {decimals} is 18. To select a different value for\n * {decimals} you should overload it.\n *\n * All two of these values are immutable: they can only be set once during\n * construction.\n */\n function __ERC20_init(string memory name_, string memory symbol_) internal onlyInitializing {\n __ERC20_init_unchained(name_, symbol_);\n }\n\n function __ERC20_init_unchained(string memory name_, string memory symbol_) internal onlyInitializing {\n _name = name_;\n _symbol = symbol_;\n }\n\n /**\n * @dev Returns the name of the token.\n */\n function name() public view virtual override returns (string memory) {\n return _name;\n }\n\n /**\n * @dev Returns the symbol of the token, usually a shorter version of the\n * name.\n */\n function symbol() public view virtual override returns (string memory) {\n return _symbol;\n }\n\n /**\n * @dev Returns the number of decimals used to get its user representation.\n * For example, if `decimals` equals `2`, a balance of `505` tokens should\n * be displayed to a user as `5.05` (`505 / 10 ** 2`).\n *\n * Tokens usually opt for a value of 18, imitating the relationship between\n * Ether and Wei. This is the value {ERC20} uses, unless this function is\n * overridden;\n *\n * NOTE: This information is only used for _display_ purposes: it in\n * no way affects any of the arithmetic of the contract, including\n * {IERC20-balanceOf} and {IERC20-transfer}.\n */\n function decimals() public view virtual override returns (uint8) {\n return 18;\n }\n\n /**\n * @dev See {IERC20-totalSupply}.\n */\n function totalSupply() public view virtual override returns (uint256) {\n return _totalSupply;\n }\n\n /**\n * @dev See {IERC20-balanceOf}.\n */\n function balanceOf(address account) public view virtual override returns (uint256) {\n return _balances[account];\n }\n\n /**\n * @dev See {IERC20-transfer}.\n *\n * Requirements:\n *\n * - `to` cannot be the zero address.\n * - the caller must have a balance of at least `amount`.\n */\n function transfer(address to, uint256 amount) public virtual override returns (bool) {\n address owner = _msgSender();\n _transfer(owner, to, amount);\n return true;\n }\n\n /**\n * @dev See {IERC20-allowance}.\n */\n function allowance(address owner, address spender) public view virtual override returns (uint256) {\n return _allowances[owner][spender];\n }\n\n /**\n * @dev See {IERC20-approve}.\n *\n * NOTE: If `amount` is the maximum `uint256`, the allowance is not updated on\n * `transferFrom`. This is semantically equivalent to an infinite approval.\n *\n * Requirements:\n *\n * - `spender` cannot be the zero address.\n */\n function approve(address spender, uint256 amount) public virtual override returns (bool) {\n address owner = _msgSender();\n _approve(owner, spender, amount);\n return true;\n }\n\n /**\n * @dev See {IERC20-transferFrom}.\n *\n * Emits an {Approval} event indicating the updated allowance. This is not\n * required by the EIP. See the note at the beginning of {ERC20}.\n *\n * NOTE: Does not update the allowance if the current allowance\n * is the maximum `uint256`.\n *\n * Requirements:\n *\n * - `from` and `to` cannot be the zero address.\n * - `from` must have a balance of at least `amount`.\n * - the caller must have allowance for ``from``'s tokens of at least\n * `amount`.\n */\n function transferFrom(\n address from,\n address to,\n uint256 amount\n ) public virtual override returns (bool) {\n address spender = _msgSender();\n _spendAllowance(from, spender, amount);\n _transfer(from, to, amount);\n return true;\n }\n\n /**\n * @dev Atomically increases the allowance granted to `spender` by the caller.\n *\n * This is an alternative to {approve} that can be used as a mitigation for\n * problems described in {IERC20-approve}.\n *\n * Emits an {Approval} event indicating the updated allowance.\n *\n * Requirements:\n *\n * - `spender` cannot be the zero address.\n */\n function increaseAllowance(address spender, uint256 addedValue) public virtual returns (bool) {\n address owner = _msgSender();\n _approve(owner, spender, allowance(owner, spender) + addedValue);\n return true;\n }\n\n /**\n * @dev Atomically decreases the allowance granted to `spender` by the caller.\n *\n * This is an alternative to {approve} that can be used as a mitigation for\n * problems described in {IERC20-approve}.\n *\n * Emits an {Approval} event indicating the updated allowance.\n *\n * Requirements:\n *\n * - `spender` cannot be the zero address.\n * - `spender` must have allowance for the caller of at least\n * `subtractedValue`.\n */\n function decreaseAllowance(address spender, uint256 subtractedValue) public virtual returns (bool) {\n address owner = _msgSender();\n uint256 currentAllowance = allowance(owner, spender);\n require(currentAllowance >= subtractedValue, \"ERC20: decreased allowance below zero\");\n unchecked {\n _approve(owner, spender, currentAllowance - subtractedValue);\n }\n\n return true;\n }\n\n /**\n * @dev Moves `amount` of tokens from `from` to `to`.\n *\n * This internal function is equivalent to {transfer}, and can be used to\n * e.g. implement automatic token fees, slashing mechanisms, etc.\n *\n * Emits a {Transfer} event.\n *\n * Requirements:\n *\n * - `from` cannot be the zero address.\n * - `to` cannot be the zero address.\n * - `from` must have a balance of at least `amount`.\n */\n function _transfer(\n address from,\n address to,\n uint256 amount\n ) internal virtual {\n require(from != address(0), \"ERC20: transfer from the zero address\");\n require(to != address(0), \"ERC20: transfer to the zero address\");\n\n _beforeTokenTransfer(from, to, amount);\n\n uint256 fromBalance = _balances[from];\n require(fromBalance >= amount, \"ERC20: transfer amount exceeds balance\");\n unchecked {\n _balances[from] = fromBalance - amount;\n }\n _balances[to] += amount;\n\n emit Transfer(from, to, amount);\n\n _afterTokenTransfer(from, to, amount);\n }\n\n /** @dev Creates `amount` tokens and assigns them to `account`, increasing\n * the total supply.\n *\n * Emits a {Transfer} event with `from` set to the zero address.\n *\n * Requirements:\n *\n * - `account` cannot be the zero address.\n */\n function _mint(address account, uint256 amount) internal virtual {\n require(account != address(0), \"ERC20: mint to the zero address\");\n\n _beforeTokenTransfer(address(0), account, amount);\n\n _totalSupply += amount;\n _balances[account] += amount;\n emit Transfer(address(0), account, amount);\n\n _afterTokenTransfer(address(0), account, amount);\n }\n\n /**\n * @dev Destroys `amount` tokens from `account`, reducing the\n * total supply.\n *\n * Emits a {Transfer} event with `to` set to the zero address.\n *\n * Requirements:\n *\n * - `account` cannot be the zero address.\n * - `account` must have at least `amount` tokens.\n */\n function _burn(address account, uint256 amount) internal virtual {\n require(account != address(0), \"ERC20: burn from the zero address\");\n\n _beforeTokenTransfer(account, address(0), amount);\n\n uint256 accountBalance = _balances[account];\n require(accountBalance >= amount, \"ERC20: burn amount exceeds balance\");\n unchecked {\n _balances[account] = accountBalance - amount;\n }\n _totalSupply -= amount;\n\n emit Transfer(account, address(0), amount);\n\n _afterTokenTransfer(account, address(0), amount);\n }\n\n /**\n * @dev Sets `amount` as the allowance of `spender` over the `owner` s tokens.\n *\n * This internal function is equivalent to `approve`, and can be used to\n * e.g. set automatic allowances for certain subsystems, etc.\n *\n * Emits an {Approval} event.\n *\n * Requirements:\n *\n * - `owner` cannot be the zero address.\n * - `spender` cannot be the zero address.\n */\n function _approve(\n address owner,\n address spender,\n uint256 amount\n ) internal virtual {\n require(owner != address(0), \"ERC20: approve from the zero address\");\n require(spender != address(0), \"ERC20: approve to the zero address\");\n\n _allowances[owner][spender] = amount;\n emit Approval(owner, spender, amount);\n }\n\n /**\n * @dev Updates `owner` s allowance for `spender` based on spent `amount`.\n *\n * Does not update the allowance amount in case of infinite allowance.\n * Revert if not enough allowance is available.\n *\n * Might emit an {Approval} event.\n */\n function _spendAllowance(\n address owner,\n address spender,\n uint256 amount\n ) internal virtual {\n uint256 currentAllowance = allowance(owner, spender);\n if (currentAllowance != type(uint256).max) {\n require(currentAllowance >= amount, \"ERC20: insufficient allowance\");\n unchecked {\n _approve(owner, spender, currentAllowance - amount);\n }\n }\n }\n\n /**\n * @dev Hook that is called before any transfer of tokens. This includes\n * minting and burning.\n *\n * Calling conditions:\n *\n * - when `from` and `to` are both non-zero, `amount` of ``from``'s tokens\n * will be transferred to `to`.\n * - when `from` is zero, `amount` tokens will be minted for `to`.\n * - when `to` is zero, `amount` of ``from``'s tokens will be burned.\n * - `from` and `to` are never both zero.\n *\n * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].\n */\n function _beforeTokenTransfer(\n address from,\n address to,\n uint256 amount\n ) internal virtual {}\n\n /**\n * @dev Hook that is called after any transfer of tokens. This includes\n * minting and burning.\n *\n * Calling conditions:\n *\n * - when `from` and `to` are both non-zero, `amount` of ``from``'s tokens\n * has been transferred to `to`.\n * - when `from` is zero, `amount` tokens have been minted for `to`.\n * - when `to` is zero, `amount` of ``from``'s tokens have been burned.\n * - `from` and `to` are never both zero.\n *\n * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].\n */\n function _afterTokenTransfer(\n address from,\n address to,\n uint256 amount\n ) internal virtual {}\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[45] private __gap;\n}\n" + }, + "@openzeppelin/contracts-upgradeable/token/ERC20/extensions/draft-ERC20PermitUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.6.0) (token/ERC20/extensions/draft-ERC20Permit.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./draft-IERC20PermitUpgradeable.sol\";\nimport \"../ERC20Upgradeable.sol\";\nimport \"../../../utils/cryptography/draft-EIP712Upgradeable.sol\";\nimport \"../../../utils/cryptography/ECDSAUpgradeable.sol\";\nimport \"../../../utils/CountersUpgradeable.sol\";\nimport \"../../../proxy/utils/Initializable.sol\";\n\n/**\n * @dev Implementation of the ERC20 Permit extension allowing approvals to be made via signatures, as defined in\n * https://eips.ethereum.org/EIPS/eip-2612[EIP-2612].\n *\n * Adds the {permit} method, which can be used to change an account's ERC20 allowance (see {IERC20-allowance}) by\n * presenting a message signed by the account. By not relying on `{IERC20-approve}`, the token holder account doesn't\n * need to send a transaction, and thus is not required to hold Ether at all.\n *\n * _Available since v3.4._\n *\n * @custom:storage-size 51\n */\nabstract contract ERC20PermitUpgradeable is Initializable, ERC20Upgradeable, IERC20PermitUpgradeable, EIP712Upgradeable {\n using CountersUpgradeable for CountersUpgradeable.Counter;\n\n mapping(address => CountersUpgradeable.Counter) private _nonces;\n\n // solhint-disable-next-line var-name-mixedcase\n bytes32 private constant _PERMIT_TYPEHASH =\n keccak256(\"Permit(address owner,address spender,uint256 value,uint256 nonce,uint256 deadline)\");\n /**\n * @dev In previous versions `_PERMIT_TYPEHASH` was declared as `immutable`.\n * However, to ensure consistency with the upgradeable transpiler, we will continue\n * to reserve a slot.\n * @custom:oz-renamed-from _PERMIT_TYPEHASH\n */\n // solhint-disable-next-line var-name-mixedcase\n bytes32 private _PERMIT_TYPEHASH_DEPRECATED_SLOT;\n\n /**\n * @dev Initializes the {EIP712} domain separator using the `name` parameter, and setting `version` to `\"1\"`.\n *\n * It's a good idea to use the same `name` that is defined as the ERC20 token name.\n */\n function __ERC20Permit_init(string memory name) internal onlyInitializing {\n __EIP712_init_unchained(name, \"1\");\n }\n\n function __ERC20Permit_init_unchained(string memory) internal onlyInitializing {}\n\n /**\n * @dev See {IERC20Permit-permit}.\n */\n function permit(\n address owner,\n address spender,\n uint256 value,\n uint256 deadline,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) public virtual override {\n require(block.timestamp <= deadline, \"ERC20Permit: expired deadline\");\n\n bytes32 structHash = keccak256(abi.encode(_PERMIT_TYPEHASH, owner, spender, value, _useNonce(owner), deadline));\n\n bytes32 hash = _hashTypedDataV4(structHash);\n\n address signer = ECDSAUpgradeable.recover(hash, v, r, s);\n require(signer == owner, \"ERC20Permit: invalid signature\");\n\n _approve(owner, spender, value);\n }\n\n /**\n * @dev See {IERC20Permit-nonces}.\n */\n function nonces(address owner) public view virtual override returns (uint256) {\n return _nonces[owner].current();\n }\n\n /**\n * @dev See {IERC20Permit-DOMAIN_SEPARATOR}.\n */\n // solhint-disable-next-line func-name-mixedcase\n function DOMAIN_SEPARATOR() external view override returns (bytes32) {\n return _domainSeparatorV4();\n }\n\n /**\n * @dev \"Consume a nonce\": return the current value and increment.\n *\n * _Available since v4.1._\n */\n function _useNonce(address owner) internal virtual returns (uint256 current) {\n CountersUpgradeable.Counter storage nonce = _nonces[owner];\n current = nonce.current();\n nonce.increment();\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[49] private __gap;\n}\n" + }, + "@openzeppelin/contracts-upgradeable/token/ERC20/extensions/draft-IERC20PermitUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (token/ERC20/extensions/draft-IERC20Permit.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Interface of the ERC20 Permit extension allowing approvals to be made via signatures, as defined in\n * https://eips.ethereum.org/EIPS/eip-2612[EIP-2612].\n *\n * Adds the {permit} method, which can be used to change an account's ERC20 allowance (see {IERC20-allowance}) by\n * presenting a message signed by the account. By not relying on {IERC20-approve}, the token holder account doesn't\n * need to send a transaction, and thus is not required to hold Ether at all.\n */\ninterface IERC20PermitUpgradeable {\n /**\n * @dev Sets `value` as the allowance of `spender` over ``owner``'s tokens,\n * given ``owner``'s signed approval.\n *\n * IMPORTANT: The same issues {IERC20-approve} has related to transaction\n * ordering also apply here.\n *\n * Emits an {Approval} event.\n *\n * Requirements:\n *\n * - `spender` cannot be the zero address.\n * - `deadline` must be a timestamp in the future.\n * - `v`, `r` and `s` must be a valid `secp256k1` signature from `owner`\n * over the EIP712-formatted function arguments.\n * - the signature must use ``owner``'s current nonce (see {nonces}).\n *\n * For more information on the signature format, see the\n * https://eips.ethereum.org/EIPS/eip-2612#specification[relevant EIP\n * section].\n */\n function permit(\n address owner,\n address spender,\n uint256 value,\n uint256 deadline,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) external;\n\n /**\n * @dev Returns the current nonce for `owner`. This value must be\n * included whenever a signature is generated for {permit}.\n *\n * Every successful call to {permit} increases ``owner``'s nonce by one. This\n * prevents a signature from being used multiple times.\n */\n function nonces(address owner) external view returns (uint256);\n\n /**\n * @dev Returns the domain separator used in the encoding of the signature for {permit}, as defined by {EIP712}.\n */\n // solhint-disable-next-line func-name-mixedcase\n function DOMAIN_SEPARATOR() external view returns (bytes32);\n}\n" + }, + "@openzeppelin/contracts-upgradeable/token/ERC20/extensions/IERC20MetadataUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (token/ERC20/extensions/IERC20Metadata.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../IERC20Upgradeable.sol\";\n\n/**\n * @dev Interface for the optional metadata functions from the ERC20 standard.\n *\n * _Available since v4.1._\n */\ninterface IERC20MetadataUpgradeable is IERC20Upgradeable {\n /**\n * @dev Returns the name of the token.\n */\n function name() external view returns (string memory);\n\n /**\n * @dev Returns the symbol of the token.\n */\n function symbol() external view returns (string memory);\n\n /**\n * @dev Returns the decimals places of the token.\n */\n function decimals() external view returns (uint8);\n}\n" + }, + "@openzeppelin/contracts-upgradeable/token/ERC20/IERC20Upgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.6.0) (token/ERC20/IERC20.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Interface of the ERC20 standard as defined in the EIP.\n */\ninterface IERC20Upgradeable {\n /**\n * @dev Emitted when `value` tokens are moved from one account (`from`) to\n * another (`to`).\n *\n * Note that `value` may be zero.\n */\n event Transfer(address indexed from, address indexed to, uint256 value);\n\n /**\n * @dev Emitted when the allowance of a `spender` for an `owner` is set by\n * a call to {approve}. `value` is the new allowance.\n */\n event Approval(address indexed owner, address indexed spender, uint256 value);\n\n /**\n * @dev Returns the amount of tokens in existence.\n */\n function totalSupply() external view returns (uint256);\n\n /**\n * @dev Returns the amount of tokens owned by `account`.\n */\n function balanceOf(address account) external view returns (uint256);\n\n /**\n * @dev Moves `amount` tokens from the caller's account to `to`.\n *\n * Returns a boolean value indicating whether the operation succeeded.\n *\n * Emits a {Transfer} event.\n */\n function transfer(address to, uint256 amount) external returns (bool);\n\n /**\n * @dev Returns the remaining number of tokens that `spender` will be\n * allowed to spend on behalf of `owner` through {transferFrom}. This is\n * zero by default.\n *\n * This value changes when {approve} or {transferFrom} are called.\n */\n function allowance(address owner, address spender) external view returns (uint256);\n\n /**\n * @dev Sets `amount` as the allowance of `spender` over the caller's tokens.\n *\n * Returns a boolean value indicating whether the operation succeeded.\n *\n * IMPORTANT: Beware that changing an allowance with this method brings the risk\n * that someone may use both the old and the new allowance by unfortunate\n * transaction ordering. One possible solution to mitigate this race\n * condition is to first reduce the spender's allowance to 0 and set the\n * desired value afterwards:\n * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729\n *\n * Emits an {Approval} event.\n */\n function approve(address spender, uint256 amount) external returns (bool);\n\n /**\n * @dev Moves `amount` tokens from `from` to `to` using the\n * allowance mechanism. `amount` is then deducted from the caller's\n * allowance.\n *\n * Returns a boolean value indicating whether the operation succeeded.\n *\n * Emits a {Transfer} event.\n */\n function transferFrom(\n address from,\n address to,\n uint256 amount\n ) external returns (bool);\n}\n" + }, + "@openzeppelin/contracts-upgradeable/token/ERC721/extensions/IERC721MetadataUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (token/ERC721/extensions/IERC721Metadata.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../IERC721Upgradeable.sol\";\n\n/**\n * @title ERC-721 Non-Fungible Token Standard, optional metadata extension\n * @dev See https://eips.ethereum.org/EIPS/eip-721\n */\ninterface IERC721MetadataUpgradeable is IERC721Upgradeable {\n /**\n * @dev Returns the token collection name.\n */\n function name() external view returns (string memory);\n\n /**\n * @dev Returns the token collection symbol.\n */\n function symbol() external view returns (string memory);\n\n /**\n * @dev Returns the Uniform Resource Identifier (URI) for `tokenId` token.\n */\n function tokenURI(uint256 tokenId) external view returns (string memory);\n}\n" + }, + "@openzeppelin/contracts-upgradeable/token/ERC721/IERC721ReceiverUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.6.0) (token/ERC721/IERC721Receiver.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @title ERC721 token receiver interface\n * @dev Interface for any contract that wants to support safeTransfers\n * from ERC721 asset contracts.\n */\ninterface IERC721ReceiverUpgradeable {\n /**\n * @dev Whenever an {IERC721} `tokenId` token is transferred to this contract via {IERC721-safeTransferFrom}\n * by `operator` from `from`, this function is called.\n *\n * It must return its Solidity selector to confirm the token transfer.\n * If any other value is returned or the interface is not implemented by the recipient, the transfer will be reverted.\n *\n * The selector can be obtained in Solidity with `IERC721Receiver.onERC721Received.selector`.\n */\n function onERC721Received(\n address operator,\n address from,\n uint256 tokenId,\n bytes calldata data\n ) external returns (bytes4);\n}\n" + }, + "@openzeppelin/contracts-upgradeable/token/ERC721/IERC721Upgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (token/ERC721/IERC721.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../../utils/introspection/IERC165Upgradeable.sol\";\n\n/**\n * @dev Required interface of an ERC721 compliant contract.\n */\ninterface IERC721Upgradeable is IERC165Upgradeable {\n /**\n * @dev Emitted when `tokenId` token is transferred from `from` to `to`.\n */\n event Transfer(address indexed from, address indexed to, uint256 indexed tokenId);\n\n /**\n * @dev Emitted when `owner` enables `approved` to manage the `tokenId` token.\n */\n event Approval(address indexed owner, address indexed approved, uint256 indexed tokenId);\n\n /**\n * @dev Emitted when `owner` enables or disables (`approved`) `operator` to manage all of its assets.\n */\n event ApprovalForAll(address indexed owner, address indexed operator, bool approved);\n\n /**\n * @dev Returns the number of tokens in ``owner``'s account.\n */\n function balanceOf(address owner) external view returns (uint256 balance);\n\n /**\n * @dev Returns the owner of the `tokenId` token.\n *\n * Requirements:\n *\n * - `tokenId` must exist.\n */\n function ownerOf(uint256 tokenId) external view returns (address owner);\n\n /**\n * @dev Safely transfers `tokenId` token from `from` to `to`.\n *\n * Requirements:\n *\n * - `from` cannot be the zero address.\n * - `to` cannot be the zero address.\n * - `tokenId` token must exist and be owned by `from`.\n * - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}.\n * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.\n *\n * Emits a {Transfer} event.\n */\n function safeTransferFrom(\n address from,\n address to,\n uint256 tokenId,\n bytes calldata data\n ) external;\n\n /**\n * @dev Safely transfers `tokenId` token from `from` to `to`, checking first that contract recipients\n * are aware of the ERC721 protocol to prevent tokens from being forever locked.\n *\n * Requirements:\n *\n * - `from` cannot be the zero address.\n * - `to` cannot be the zero address.\n * - `tokenId` token must exist and be owned by `from`.\n * - If the caller is not `from`, it must have been allowed to move this token by either {approve} or {setApprovalForAll}.\n * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.\n *\n * Emits a {Transfer} event.\n */\n function safeTransferFrom(\n address from,\n address to,\n uint256 tokenId\n ) external;\n\n /**\n * @dev Transfers `tokenId` token from `from` to `to`.\n *\n * WARNING: Usage of this method is discouraged, use {safeTransferFrom} whenever possible.\n *\n * Requirements:\n *\n * - `from` cannot be the zero address.\n * - `to` cannot be the zero address.\n * - `tokenId` token must be owned by `from`.\n * - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}.\n *\n * Emits a {Transfer} event.\n */\n function transferFrom(\n address from,\n address to,\n uint256 tokenId\n ) external;\n\n /**\n * @dev Gives permission to `to` to transfer `tokenId` token to another account.\n * The approval is cleared when the token is transferred.\n *\n * Only a single account can be approved at a time, so approving the zero address clears previous approvals.\n *\n * Requirements:\n *\n * - The caller must own the token or be an approved operator.\n * - `tokenId` must exist.\n *\n * Emits an {Approval} event.\n */\n function approve(address to, uint256 tokenId) external;\n\n /**\n * @dev Approve or remove `operator` as an operator for the caller.\n * Operators can call {transferFrom} or {safeTransferFrom} for any token owned by the caller.\n *\n * Requirements:\n *\n * - The `operator` cannot be the caller.\n *\n * Emits an {ApprovalForAll} event.\n */\n function setApprovalForAll(address operator, bool _approved) external;\n\n /**\n * @dev Returns the account approved for `tokenId` token.\n *\n * Requirements:\n *\n * - `tokenId` must exist.\n */\n function getApproved(uint256 tokenId) external view returns (address operator);\n\n /**\n * @dev Returns if the `operator` is allowed to manage all of the assets of `owner`.\n *\n * See {setApprovalForAll}\n */\n function isApprovedForAll(address owner, address operator) external view returns (bool);\n}\n" + }, + "@openzeppelin/contracts-upgradeable/utils/AddressUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (utils/Address.sol)\n\npragma solidity ^0.8.1;\n\n/**\n * @dev Collection of functions related to the address type\n */\nlibrary AddressUpgradeable {\n /**\n * @dev Returns true if `account` is a contract.\n *\n * [IMPORTANT]\n * ====\n * It is unsafe to assume that an address for which this function returns\n * false is an externally-owned account (EOA) and not a contract.\n *\n * Among others, `isContract` will return false for the following\n * types of addresses:\n *\n * - an externally-owned account\n * - a contract in construction\n * - an address where a contract will be created\n * - an address where a contract lived, but was destroyed\n * ====\n *\n * [IMPORTANT]\n * ====\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\n *\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\n * constructor.\n * ====\n */\n function isContract(address account) internal view returns (bool) {\n // This method relies on extcodesize/address.code.length, which returns 0\n // for contracts in construction, since the code is only stored at the end\n // of the constructor execution.\n\n return account.code.length > 0;\n }\n\n /**\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\n * `recipient`, forwarding all available gas and reverting on errors.\n *\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\n * imposed by `transfer`, making them unable to receive funds via\n * `transfer`. {sendValue} removes this limitation.\n *\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\n *\n * IMPORTANT: because control is transferred to `recipient`, care must be\n * taken to not create reentrancy vulnerabilities. Consider using\n * {ReentrancyGuard} or the\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\n */\n function sendValue(address payable recipient, uint256 amount) internal {\n require(address(this).balance >= amount, \"Address: insufficient balance\");\n\n (bool success, ) = recipient.call{value: amount}(\"\");\n require(success, \"Address: unable to send value, recipient may have reverted\");\n }\n\n /**\n * @dev Performs a Solidity function call using a low level `call`. A\n * plain `call` is an unsafe replacement for a function call: use this\n * function instead.\n *\n * If `target` reverts with a revert reason, it is bubbled up by this\n * function (like regular Solidity function calls).\n *\n * Returns the raw returned data. To convert to the expected return value,\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\n *\n * Requirements:\n *\n * - `target` must be a contract.\n * - calling `target` with `data` must not revert.\n *\n * _Available since v3.1._\n */\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionCall(target, data, \"Address: low-level call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\n * `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, 0, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but also transferring `value` wei to `target`.\n *\n * Requirements:\n *\n * - the calling contract must have an ETH balance of at least `value`.\n * - the called Solidity function must be `payable`.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, value, \"Address: low-level call with value failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\n * with `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(address(this).balance >= value, \"Address: insufficient balance for call\");\n require(isContract(target), \"Address: call to non-contract\");\n\n (bool success, bytes memory returndata) = target.call{value: value}(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\n return functionStaticCall(target, data, \"Address: low-level static call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal view returns (bytes memory) {\n require(isContract(target), \"Address: static call to non-contract\");\n\n (bool success, bytes memory returndata) = target.staticcall(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the\n * revert reason using the provided one.\n *\n * _Available since v4.3._\n */\n function verifyCallResult(\n bool success,\n bytes memory returndata,\n string memory errorMessage\n ) internal pure returns (bytes memory) {\n if (success) {\n return returndata;\n } else {\n // Look for revert reason and bubble it up if present\n if (returndata.length > 0) {\n // The easiest way to bubble the revert reason is using memory via assembly\n /// @solidity memory-safe-assembly\n assembly {\n let returndata_size := mload(returndata)\n revert(add(32, returndata), returndata_size)\n }\n } else {\n revert(errorMessage);\n }\n }\n }\n}\n" + }, + "@openzeppelin/contracts-upgradeable/utils/ContextUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)\n\npragma solidity ^0.8.0;\nimport \"../proxy/utils/Initializable.sol\";\n\n/**\n * @dev Provides information about the current execution context, including the\n * sender of the transaction and its data. While these are generally available\n * via msg.sender and msg.data, they should not be accessed in such a direct\n * manner, since when dealing with meta-transactions the account sending and\n * paying for execution may not be the actual sender (as far as an application\n * is concerned).\n *\n * This contract is only required for intermediate, library-like contracts.\n */\nabstract contract ContextUpgradeable is Initializable {\n function __Context_init() internal onlyInitializing {\n }\n\n function __Context_init_unchained() internal onlyInitializing {\n }\n function _msgSender() internal view virtual returns (address) {\n return msg.sender;\n }\n\n function _msgData() internal view virtual returns (bytes calldata) {\n return msg.data;\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[50] private __gap;\n}\n" + }, + "@openzeppelin/contracts-upgradeable/utils/CountersUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (utils/Counters.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @title Counters\n * @author Matt Condon (@shrugs)\n * @dev Provides counters that can only be incremented, decremented or reset. This can be used e.g. to track the number\n * of elements in a mapping, issuing ERC721 ids, or counting request ids.\n *\n * Include with `using Counters for Counters.Counter;`\n */\nlibrary CountersUpgradeable {\n struct Counter {\n // This variable should never be directly accessed by users of the library: interactions must be restricted to\n // the library's function. As of Solidity v0.5.2, this cannot be enforced, though there is a proposal to add\n // this feature: see https://github.com/ethereum/solidity/issues/4637\n uint256 _value; // default: 0\n }\n\n function current(Counter storage counter) internal view returns (uint256) {\n return counter._value;\n }\n\n function increment(Counter storage counter) internal {\n unchecked {\n counter._value += 1;\n }\n }\n\n function decrement(Counter storage counter) internal {\n uint256 value = counter._value;\n require(value > 0, \"Counter: decrement overflow\");\n unchecked {\n counter._value = value - 1;\n }\n }\n\n function reset(Counter storage counter) internal {\n counter._value = 0;\n }\n}\n" + }, + "@openzeppelin/contracts-upgradeable/utils/cryptography/draft-EIP712Upgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (utils/cryptography/draft-EIP712.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./ECDSAUpgradeable.sol\";\nimport \"../../proxy/utils/Initializable.sol\";\n\n/**\n * @dev https://eips.ethereum.org/EIPS/eip-712[EIP 712] is a standard for hashing and signing of typed structured data.\n *\n * The encoding specified in the EIP is very generic, and such a generic implementation in Solidity is not feasible,\n * thus this contract does not implement the encoding itself. Protocols need to implement the type-specific encoding\n * they need in their contracts using a combination of `abi.encode` and `keccak256`.\n *\n * This contract implements the EIP 712 domain separator ({_domainSeparatorV4}) that is used as part of the encoding\n * scheme, and the final step of the encoding to obtain the message digest that is then signed via ECDSA\n * ({_hashTypedDataV4}).\n *\n * The implementation of the domain separator was designed to be as efficient as possible while still properly updating\n * the chain id to protect against replay attacks on an eventual fork of the chain.\n *\n * NOTE: This contract implements the version of the encoding known as \"v4\", as implemented by the JSON RPC method\n * https://docs.metamask.io/guide/signing-data.html[`eth_signTypedDataV4` in MetaMask].\n *\n * _Available since v3.4._\n *\n * @custom:storage-size 52\n */\nabstract contract EIP712Upgradeable is Initializable {\n /* solhint-disable var-name-mixedcase */\n bytes32 private _HASHED_NAME;\n bytes32 private _HASHED_VERSION;\n bytes32 private constant _TYPE_HASH = keccak256(\"EIP712Domain(string name,string version,uint256 chainId,address verifyingContract)\");\n\n /* solhint-enable var-name-mixedcase */\n\n /**\n * @dev Initializes the domain separator and parameter caches.\n *\n * The meaning of `name` and `version` is specified in\n * https://eips.ethereum.org/EIPS/eip-712#definition-of-domainseparator[EIP 712]:\n *\n * - `name`: the user readable name of the signing domain, i.e. the name of the DApp or the protocol.\n * - `version`: the current major version of the signing domain.\n *\n * NOTE: These parameters cannot be changed except through a xref:learn::upgrading-smart-contracts.adoc[smart\n * contract upgrade].\n */\n function __EIP712_init(string memory name, string memory version) internal onlyInitializing {\n __EIP712_init_unchained(name, version);\n }\n\n function __EIP712_init_unchained(string memory name, string memory version) internal onlyInitializing {\n bytes32 hashedName = keccak256(bytes(name));\n bytes32 hashedVersion = keccak256(bytes(version));\n _HASHED_NAME = hashedName;\n _HASHED_VERSION = hashedVersion;\n }\n\n /**\n * @dev Returns the domain separator for the current chain.\n */\n function _domainSeparatorV4() internal view returns (bytes32) {\n return _buildDomainSeparator(_TYPE_HASH, _EIP712NameHash(), _EIP712VersionHash());\n }\n\n function _buildDomainSeparator(\n bytes32 typeHash,\n bytes32 nameHash,\n bytes32 versionHash\n ) private view returns (bytes32) {\n return keccak256(abi.encode(typeHash, nameHash, versionHash, block.chainid, address(this)));\n }\n\n /**\n * @dev Given an already https://eips.ethereum.org/EIPS/eip-712#definition-of-hashstruct[hashed struct], this\n * function returns the hash of the fully encoded EIP712 message for this domain.\n *\n * This hash can be used together with {ECDSA-recover} to obtain the signer of a message. For example:\n *\n * ```solidity\n * bytes32 digest = _hashTypedDataV4(keccak256(abi.encode(\n * keccak256(\"Mail(address to,string contents)\"),\n * mailTo,\n * keccak256(bytes(mailContents))\n * )));\n * address signer = ECDSA.recover(digest, signature);\n * ```\n */\n function _hashTypedDataV4(bytes32 structHash) internal view virtual returns (bytes32) {\n return ECDSAUpgradeable.toTypedDataHash(_domainSeparatorV4(), structHash);\n }\n\n /**\n * @dev The hash of the name parameter for the EIP712 domain.\n *\n * NOTE: This function reads from storage by default, but can be redefined to return a constant value if gas costs\n * are a concern.\n */\n function _EIP712NameHash() internal virtual view returns (bytes32) {\n return _HASHED_NAME;\n }\n\n /**\n * @dev The hash of the version parameter for the EIP712 domain.\n *\n * NOTE: This function reads from storage by default, but can be redefined to return a constant value if gas costs\n * are a concern.\n */\n function _EIP712VersionHash() internal virtual view returns (bytes32) {\n return _HASHED_VERSION;\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[50] private __gap;\n}\n" + }, + "@openzeppelin/contracts-upgradeable/utils/cryptography/ECDSAUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (utils/cryptography/ECDSA.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../StringsUpgradeable.sol\";\n\n/**\n * @dev Elliptic Curve Digital Signature Algorithm (ECDSA) operations.\n *\n * These functions can be used to verify that a message was signed by the holder\n * of the private keys of a given address.\n */\nlibrary ECDSAUpgradeable {\n enum RecoverError {\n NoError,\n InvalidSignature,\n InvalidSignatureLength,\n InvalidSignatureS,\n InvalidSignatureV\n }\n\n function _throwError(RecoverError error) private pure {\n if (error == RecoverError.NoError) {\n return; // no error: do nothing\n } else if (error == RecoverError.InvalidSignature) {\n revert(\"ECDSA: invalid signature\");\n } else if (error == RecoverError.InvalidSignatureLength) {\n revert(\"ECDSA: invalid signature length\");\n } else if (error == RecoverError.InvalidSignatureS) {\n revert(\"ECDSA: invalid signature 's' value\");\n } else if (error == RecoverError.InvalidSignatureV) {\n revert(\"ECDSA: invalid signature 'v' value\");\n }\n }\n\n /**\n * @dev Returns the address that signed a hashed message (`hash`) with\n * `signature` or error string. This address can then be used for verification purposes.\n *\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\n * this function rejects them by requiring the `s` value to be in the lower\n * half order, and the `v` value to be either 27 or 28.\n *\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\n * verification to be secure: it is possible to craft signatures that\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\n * this is by receiving a hash of the original message (which may otherwise\n * be too long), and then calling {toEthSignedMessageHash} on it.\n *\n * Documentation for signature generation:\n * - with https://web3js.readthedocs.io/en/v1.3.4/web3-eth-accounts.html#sign[Web3.js]\n * - with https://docs.ethers.io/v5/api/signer/#Signer-signMessage[ethers]\n *\n * _Available since v4.3._\n */\n function tryRecover(bytes32 hash, bytes memory signature) internal pure returns (address, RecoverError) {\n // Check the signature length\n // - case 65: r,s,v signature (standard)\n // - case 64: r,vs signature (cf https://eips.ethereum.org/EIPS/eip-2098) _Available since v4.1._\n if (signature.length == 65) {\n bytes32 r;\n bytes32 s;\n uint8 v;\n // ecrecover takes the signature parameters, and the only way to get them\n // currently is to use assembly.\n /// @solidity memory-safe-assembly\n assembly {\n r := mload(add(signature, 0x20))\n s := mload(add(signature, 0x40))\n v := byte(0, mload(add(signature, 0x60)))\n }\n return tryRecover(hash, v, r, s);\n } else if (signature.length == 64) {\n bytes32 r;\n bytes32 vs;\n // ecrecover takes the signature parameters, and the only way to get them\n // currently is to use assembly.\n /// @solidity memory-safe-assembly\n assembly {\n r := mload(add(signature, 0x20))\n vs := mload(add(signature, 0x40))\n }\n return tryRecover(hash, r, vs);\n } else {\n return (address(0), RecoverError.InvalidSignatureLength);\n }\n }\n\n /**\n * @dev Returns the address that signed a hashed message (`hash`) with\n * `signature`. This address can then be used for verification purposes.\n *\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\n * this function rejects them by requiring the `s` value to be in the lower\n * half order, and the `v` value to be either 27 or 28.\n *\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\n * verification to be secure: it is possible to craft signatures that\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\n * this is by receiving a hash of the original message (which may otherwise\n * be too long), and then calling {toEthSignedMessageHash} on it.\n */\n function recover(bytes32 hash, bytes memory signature) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, signature);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Overload of {ECDSA-tryRecover} that receives the `r` and `vs` short-signature fields separately.\n *\n * See https://eips.ethereum.org/EIPS/eip-2098[EIP-2098 short signatures]\n *\n * _Available since v4.3._\n */\n function tryRecover(\n bytes32 hash,\n bytes32 r,\n bytes32 vs\n ) internal pure returns (address, RecoverError) {\n bytes32 s = vs & bytes32(0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff);\n uint8 v = uint8((uint256(vs) >> 255) + 27);\n return tryRecover(hash, v, r, s);\n }\n\n /**\n * @dev Overload of {ECDSA-recover} that receives the `r and `vs` short-signature fields separately.\n *\n * _Available since v4.2._\n */\n function recover(\n bytes32 hash,\n bytes32 r,\n bytes32 vs\n ) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, r, vs);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Overload of {ECDSA-tryRecover} that receives the `v`,\n * `r` and `s` signature fields separately.\n *\n * _Available since v4.3._\n */\n function tryRecover(\n bytes32 hash,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) internal pure returns (address, RecoverError) {\n // EIP-2 still allows signature malleability for ecrecover(). Remove this possibility and make the signature\n // unique. Appendix F in the Ethereum Yellow paper (https://ethereum.github.io/yellowpaper/paper.pdf), defines\n // the valid range for s in (301): 0 < s < secp256k1n ÷ 2 + 1, and for v in (302): v ∈ {27, 28}. Most\n // signatures from current libraries generate a unique signature with an s-value in the lower half order.\n //\n // If your library generates malleable signatures, such as s-values in the upper range, calculate a new s-value\n // with 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141 - s1 and flip v from 27 to 28 or\n // vice versa. If your library also generates signatures with 0/1 for v instead 27/28, add 27 to v to accept\n // these malleable signatures as well.\n if (uint256(s) > 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D576E7357A4501DDFE92F46681B20A0) {\n return (address(0), RecoverError.InvalidSignatureS);\n }\n if (v != 27 && v != 28) {\n return (address(0), RecoverError.InvalidSignatureV);\n }\n\n // If the signature is valid (and not malleable), return the signer address\n address signer = ecrecover(hash, v, r, s);\n if (signer == address(0)) {\n return (address(0), RecoverError.InvalidSignature);\n }\n\n return (signer, RecoverError.NoError);\n }\n\n /**\n * @dev Overload of {ECDSA-recover} that receives the `v`,\n * `r` and `s` signature fields separately.\n */\n function recover(\n bytes32 hash,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, v, r, s);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Returns an Ethereum Signed Message, created from a `hash`. This\n * produces hash corresponding to the one signed with the\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\n * JSON-RPC method as part of EIP-191.\n *\n * See {recover}.\n */\n function toEthSignedMessageHash(bytes32 hash) internal pure returns (bytes32) {\n // 32 is the length in bytes of hash,\n // enforced by the type signature above\n return keccak256(abi.encodePacked(\"\\x19Ethereum Signed Message:\\n32\", hash));\n }\n\n /**\n * @dev Returns an Ethereum Signed Message, created from `s`. This\n * produces hash corresponding to the one signed with the\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\n * JSON-RPC method as part of EIP-191.\n *\n * See {recover}.\n */\n function toEthSignedMessageHash(bytes memory s) internal pure returns (bytes32) {\n return keccak256(abi.encodePacked(\"\\x19Ethereum Signed Message:\\n\", StringsUpgradeable.toString(s.length), s));\n }\n\n /**\n * @dev Returns an Ethereum Signed Typed Data, created from a\n * `domainSeparator` and a `structHash`. This produces hash corresponding\n * to the one signed with the\n * https://eips.ethereum.org/EIPS/eip-712[`eth_signTypedData`]\n * JSON-RPC method as part of EIP-712.\n *\n * See {recover}.\n */\n function toTypedDataHash(bytes32 domainSeparator, bytes32 structHash) internal pure returns (bytes32) {\n return keccak256(abi.encodePacked(\"\\x19\\x01\", domainSeparator, structHash));\n }\n}\n" + }, + "@openzeppelin/contracts-upgradeable/utils/introspection/ERC165Upgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (utils/introspection/ERC165.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./IERC165Upgradeable.sol\";\nimport \"../../proxy/utils/Initializable.sol\";\n\n/**\n * @dev Implementation of the {IERC165} interface.\n *\n * Contracts that want to implement ERC165 should inherit from this contract and override {supportsInterface} to check\n * for the additional interface id that will be supported. For example:\n *\n * ```solidity\n * function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {\n * return interfaceId == type(MyInterface).interfaceId || super.supportsInterface(interfaceId);\n * }\n * ```\n *\n * Alternatively, {ERC165Storage} provides an easier to use but more expensive implementation.\n */\nabstract contract ERC165Upgradeable is Initializable, IERC165Upgradeable {\n function __ERC165_init() internal onlyInitializing {\n }\n\n function __ERC165_init_unchained() internal onlyInitializing {\n }\n /**\n * @dev See {IERC165-supportsInterface}.\n */\n function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {\n return interfaceId == type(IERC165Upgradeable).interfaceId;\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[50] private __gap;\n}\n" + }, + "@openzeppelin/contracts-upgradeable/utils/introspection/IERC165Upgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (utils/introspection/IERC165.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Interface of the ERC165 standard, as defined in the\n * https://eips.ethereum.org/EIPS/eip-165[EIP].\n *\n * Implementers can declare support of contract interfaces, which can then be\n * queried by others ({ERC165Checker}).\n *\n * For an implementation, see {ERC165}.\n */\ninterface IERC165Upgradeable {\n /**\n * @dev Returns true if this contract implements the interface defined by\n * `interfaceId`. See the corresponding\n * https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified[EIP section]\n * to learn more about how these ids are created.\n *\n * This function call must use less than 30 000 gas.\n */\n function supportsInterface(bytes4 interfaceId) external view returns (bool);\n}\n" + }, + "@openzeppelin/contracts-upgradeable/utils/StringsUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (utils/Strings.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev String operations.\n */\nlibrary StringsUpgradeable {\n bytes16 private constant _HEX_SYMBOLS = \"0123456789abcdef\";\n uint8 private constant _ADDRESS_LENGTH = 20;\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` decimal representation.\n */\n function toString(uint256 value) internal pure returns (string memory) {\n // Inspired by OraclizeAPI's implementation - MIT licence\n // https://github.com/oraclize/ethereum-api/blob/b42146b063c7d6ee1358846c198246239e9360e8/oraclizeAPI_0.4.25.sol\n\n if (value == 0) {\n return \"0\";\n }\n uint256 temp = value;\n uint256 digits;\n while (temp != 0) {\n digits++;\n temp /= 10;\n }\n bytes memory buffer = new bytes(digits);\n while (value != 0) {\n digits -= 1;\n buffer[digits] = bytes1(uint8(48 + uint256(value % 10)));\n value /= 10;\n }\n return string(buffer);\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation.\n */\n function toHexString(uint256 value) internal pure returns (string memory) {\n if (value == 0) {\n return \"0x00\";\n }\n uint256 temp = value;\n uint256 length = 0;\n while (temp != 0) {\n length++;\n temp >>= 8;\n }\n return toHexString(value, length);\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length.\n */\n function toHexString(uint256 value, uint256 length) internal pure returns (string memory) {\n bytes memory buffer = new bytes(2 * length + 2);\n buffer[0] = \"0\";\n buffer[1] = \"x\";\n for (uint256 i = 2 * length + 1; i > 1; --i) {\n buffer[i] = _HEX_SYMBOLS[value & 0xf];\n value >>= 4;\n }\n require(value == 0, \"Strings: hex length insufficient\");\n return string(buffer);\n }\n\n /**\n * @dev Converts an `address` with fixed length of 20 bytes to its not checksummed ASCII `string` hexadecimal representation.\n */\n function toHexString(address addr) internal pure returns (string memory) {\n return toHexString(uint256(uint160(addr)), _ADDRESS_LENGTH);\n }\n}\n" + }, + "@openzeppelin/contracts-upgradeable/utils/structs/EnumerableSetUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (utils/structs/EnumerableSet.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Library for managing\n * https://en.wikipedia.org/wiki/Set_(abstract_data_type)[sets] of primitive\n * types.\n *\n * Sets have the following properties:\n *\n * - Elements are added, removed, and checked for existence in constant time\n * (O(1)).\n * - Elements are enumerated in O(n). No guarantees are made on the ordering.\n *\n * ```\n * contract Example {\n * // Add the library methods\n * using EnumerableSet for EnumerableSet.AddressSet;\n *\n * // Declare a set state variable\n * EnumerableSet.AddressSet private mySet;\n * }\n * ```\n *\n * As of v3.3.0, sets of type `bytes32` (`Bytes32Set`), `address` (`AddressSet`)\n * and `uint256` (`UintSet`) are supported.\n *\n * [WARNING]\n * ====\n * Trying to delete such a structure from storage will likely result in data corruption, rendering the structure unusable.\n * See https://github.com/ethereum/solidity/pull/11843[ethereum/solidity#11843] for more info.\n *\n * In order to clean an EnumerableSet, you can either remove all elements one by one or create a fresh instance using an array of EnumerableSet.\n * ====\n */\nlibrary EnumerableSetUpgradeable {\n // To implement this library for multiple types with as little code\n // repetition as possible, we write it in terms of a generic Set type with\n // bytes32 values.\n // The Set implementation uses private functions, and user-facing\n // implementations (such as AddressSet) are just wrappers around the\n // underlying Set.\n // This means that we can only create new EnumerableSets for types that fit\n // in bytes32.\n\n struct Set {\n // Storage of set values\n bytes32[] _values;\n // Position of the value in the `values` array, plus 1 because index 0\n // means a value is not in the set.\n mapping(bytes32 => uint256) _indexes;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function _add(Set storage set, bytes32 value) private returns (bool) {\n if (!_contains(set, value)) {\n set._values.push(value);\n // The value is stored at length-1, but we add 1 to all indexes\n // and use 0 as a sentinel value\n set._indexes[value] = set._values.length;\n return true;\n } else {\n return false;\n }\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function _remove(Set storage set, bytes32 value) private returns (bool) {\n // We read and store the value's index to prevent multiple reads from the same storage slot\n uint256 valueIndex = set._indexes[value];\n\n if (valueIndex != 0) {\n // Equivalent to contains(set, value)\n // To delete an element from the _values array in O(1), we swap the element to delete with the last one in\n // the array, and then remove the last element (sometimes called as 'swap and pop').\n // This modifies the order of the array, as noted in {at}.\n\n uint256 toDeleteIndex = valueIndex - 1;\n uint256 lastIndex = set._values.length - 1;\n\n if (lastIndex != toDeleteIndex) {\n bytes32 lastValue = set._values[lastIndex];\n\n // Move the last value to the index where the value to delete is\n set._values[toDeleteIndex] = lastValue;\n // Update the index for the moved value\n set._indexes[lastValue] = valueIndex; // Replace lastValue's index to valueIndex\n }\n\n // Delete the slot where the moved value was stored\n set._values.pop();\n\n // Delete the index for the deleted slot\n delete set._indexes[value];\n\n return true;\n } else {\n return false;\n }\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function _contains(Set storage set, bytes32 value) private view returns (bool) {\n return set._indexes[value] != 0;\n }\n\n /**\n * @dev Returns the number of values on the set. O(1).\n */\n function _length(Set storage set) private view returns (uint256) {\n return set._values.length;\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function _at(Set storage set, uint256 index) private view returns (bytes32) {\n return set._values[index];\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function _values(Set storage set) private view returns (bytes32[] memory) {\n return set._values;\n }\n\n // Bytes32Set\n\n struct Bytes32Set {\n Set _inner;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function add(Bytes32Set storage set, bytes32 value) internal returns (bool) {\n return _add(set._inner, value);\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function remove(Bytes32Set storage set, bytes32 value) internal returns (bool) {\n return _remove(set._inner, value);\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function contains(Bytes32Set storage set, bytes32 value) internal view returns (bool) {\n return _contains(set._inner, value);\n }\n\n /**\n * @dev Returns the number of values in the set. O(1).\n */\n function length(Bytes32Set storage set) internal view returns (uint256) {\n return _length(set._inner);\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function at(Bytes32Set storage set, uint256 index) internal view returns (bytes32) {\n return _at(set._inner, index);\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function values(Bytes32Set storage set) internal view returns (bytes32[] memory) {\n return _values(set._inner);\n }\n\n // AddressSet\n\n struct AddressSet {\n Set _inner;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function add(AddressSet storage set, address value) internal returns (bool) {\n return _add(set._inner, bytes32(uint256(uint160(value))));\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function remove(AddressSet storage set, address value) internal returns (bool) {\n return _remove(set._inner, bytes32(uint256(uint160(value))));\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function contains(AddressSet storage set, address value) internal view returns (bool) {\n return _contains(set._inner, bytes32(uint256(uint160(value))));\n }\n\n /**\n * @dev Returns the number of values in the set. O(1).\n */\n function length(AddressSet storage set) internal view returns (uint256) {\n return _length(set._inner);\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function at(AddressSet storage set, uint256 index) internal view returns (address) {\n return address(uint160(uint256(_at(set._inner, index))));\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function values(AddressSet storage set) internal view returns (address[] memory) {\n bytes32[] memory store = _values(set._inner);\n address[] memory result;\n\n /// @solidity memory-safe-assembly\n assembly {\n result := store\n }\n\n return result;\n }\n\n // UintSet\n\n struct UintSet {\n Set _inner;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function add(UintSet storage set, uint256 value) internal returns (bool) {\n return _add(set._inner, bytes32(value));\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function remove(UintSet storage set, uint256 value) internal returns (bool) {\n return _remove(set._inner, bytes32(value));\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function contains(UintSet storage set, uint256 value) internal view returns (bool) {\n return _contains(set._inner, bytes32(value));\n }\n\n /**\n * @dev Returns the number of values on the set. O(1).\n */\n function length(UintSet storage set) internal view returns (uint256) {\n return _length(set._inner);\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function at(UintSet storage set, uint256 index) internal view returns (uint256) {\n return uint256(_at(set._inner, index));\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function values(UintSet storage set) internal view returns (uint256[] memory) {\n bytes32[] memory store = _values(set._inner);\n uint256[] memory result;\n\n /// @solidity memory-safe-assembly\n assembly {\n result := store\n }\n\n return result;\n }\n}\n" + }, + "@openzeppelin/contracts/access/Ownable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (access/Ownable.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../utils/Context.sol\";\n\n/**\n * @dev Contract module which provides a basic access control mechanism, where\n * there is an account (an owner) that can be granted exclusive access to\n * specific functions.\n *\n * By default, the owner account will be the one that deploys the contract. This\n * can later be changed with {transferOwnership}.\n *\n * This module is used through inheritance. It will make available the modifier\n * `onlyOwner`, which can be applied to your functions to restrict their use to\n * the owner.\n */\nabstract contract Ownable is Context {\n address private _owner;\n\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\n\n /**\n * @dev Initializes the contract setting the deployer as the initial owner.\n */\n constructor() {\n _transferOwnership(_msgSender());\n }\n\n /**\n * @dev Throws if called by any account other than the owner.\n */\n modifier onlyOwner() {\n _checkOwner();\n _;\n }\n\n /**\n * @dev Returns the address of the current owner.\n */\n function owner() public view virtual returns (address) {\n return _owner;\n }\n\n /**\n * @dev Throws if the sender is not the owner.\n */\n function _checkOwner() internal view virtual {\n require(owner() == _msgSender(), \"Ownable: caller is not the owner\");\n }\n\n /**\n * @dev Leaves the contract without owner. It will not be possible to call\n * `onlyOwner` functions anymore. Can only be called by the current owner.\n *\n * NOTE: Renouncing ownership will leave the contract without an owner,\n * thereby removing any functionality that is only available to the owner.\n */\n function renounceOwnership() public virtual onlyOwner {\n _transferOwnership(address(0));\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Can only be called by the current owner.\n */\n function transferOwnership(address newOwner) public virtual onlyOwner {\n require(newOwner != address(0), \"Ownable: new owner is the zero address\");\n _transferOwnership(newOwner);\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Internal function without access restriction.\n */\n function _transferOwnership(address newOwner) internal virtual {\n address oldOwner = _owner;\n _owner = newOwner;\n emit OwnershipTransferred(oldOwner, newOwner);\n }\n}\n" + }, + "@openzeppelin/contracts/interfaces/draft-IERC1822.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.5.0) (interfaces/draft-IERC1822.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev ERC1822: Universal Upgradeable Proxy Standard (UUPS) documents a method for upgradeability through a simplified\n * proxy whose upgrades are fully controlled by the current implementation.\n */\ninterface IERC1822Proxiable {\n /**\n * @dev Returns the storage slot that the proxiable contract assumes is being used to store the implementation\n * address.\n *\n * IMPORTANT: A proxy pointing at a proxiable contract should not be considered proxiable itself, because this risks\n * bricking a proxy that upgrades to it, by delegating to itself until out of gas. Thus it is critical that this\n * function revert if invoked through a proxy.\n */\n function proxiableUUID() external view returns (bytes32);\n}\n" + }, + "@openzeppelin/contracts/interfaces/IERC3156FlashBorrower.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (interfaces/IERC3156FlashBorrower.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Interface of the ERC3156 FlashBorrower, as defined in\n * https://eips.ethereum.org/EIPS/eip-3156[ERC-3156].\n *\n * _Available since v4.1._\n */\ninterface IERC3156FlashBorrower {\n /**\n * @dev Receive a flash loan.\n * @param initiator The initiator of the loan.\n * @param token The loan currency.\n * @param amount The amount of tokens lent.\n * @param fee The additional amount of tokens to repay.\n * @param data Arbitrary data structure, intended to contain user-defined parameters.\n * @return The keccak256 hash of \"IERC3156FlashBorrower.onFlashLoan\"\n */\n function onFlashLoan(\n address initiator,\n address token,\n uint256 amount,\n uint256 fee,\n bytes calldata data\n ) external returns (bytes32);\n}\n" + }, + "@openzeppelin/contracts/interfaces/IERC3156FlashLender.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (interfaces/IERC3156FlashLender.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./IERC3156FlashBorrower.sol\";\n\n/**\n * @dev Interface of the ERC3156 FlashLender, as defined in\n * https://eips.ethereum.org/EIPS/eip-3156[ERC-3156].\n *\n * _Available since v4.1._\n */\ninterface IERC3156FlashLender {\n /**\n * @dev The amount of currency available to be lended.\n * @param token The loan currency.\n * @return The amount of `token` that can be borrowed.\n */\n function maxFlashLoan(address token) external view returns (uint256);\n\n /**\n * @dev The fee to be charged for a given loan.\n * @param token The loan currency.\n * @param amount The amount of tokens lent.\n * @return The amount of `token` to be charged for the loan, on top of the returned principal.\n */\n function flashFee(address token, uint256 amount) external view returns (uint256);\n\n /**\n * @dev Initiate a flash loan.\n * @param receiver The receiver of the tokens in the loan, and the receiver of the callback.\n * @param token The loan currency.\n * @param amount The amount of tokens lent.\n * @param data Arbitrary data structure, intended to contain user-defined parameters.\n */\n function flashLoan(\n IERC3156FlashBorrower receiver,\n address token,\n uint256 amount,\n bytes calldata data\n ) external returns (bool);\n}\n" + }, + "@openzeppelin/contracts/interfaces/IERC721Metadata.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (interfaces/IERC721Metadata.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../token/ERC721/extensions/IERC721Metadata.sol\";\n" + }, + "@openzeppelin/contracts/proxy/beacon/IBeacon.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (proxy/beacon/IBeacon.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev This is the interface that {BeaconProxy} expects of its beacon.\n */\ninterface IBeacon {\n /**\n * @dev Must return an address that can be used as a delegate call target.\n *\n * {BeaconProxy} will check that this address is a contract.\n */\n function implementation() external view returns (address);\n}\n" + }, + "@openzeppelin/contracts/proxy/ERC1967/ERC1967Proxy.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (proxy/ERC1967/ERC1967Proxy.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../Proxy.sol\";\nimport \"./ERC1967Upgrade.sol\";\n\n/**\n * @dev This contract implements an upgradeable proxy. It is upgradeable because calls are delegated to an\n * implementation address that can be changed. This address is stored in storage in the location specified by\n * https://eips.ethereum.org/EIPS/eip-1967[EIP1967], so that it doesn't conflict with the storage layout of the\n * implementation behind the proxy.\n */\ncontract ERC1967Proxy is Proxy, ERC1967Upgrade {\n /**\n * @dev Initializes the upgradeable proxy with an initial implementation specified by `_logic`.\n *\n * If `_data` is nonempty, it's used as data in a delegate call to `_logic`. This will typically be an encoded\n * function call, and allows initializing the storage of the proxy like a Solidity constructor.\n */\n constructor(address _logic, bytes memory _data) payable {\n _upgradeToAndCall(_logic, _data, false);\n }\n\n /**\n * @dev Returns the current implementation address.\n */\n function _implementation() internal view virtual override returns (address impl) {\n return ERC1967Upgrade._getImplementation();\n }\n}\n" + }, + "@openzeppelin/contracts/proxy/ERC1967/ERC1967Upgrade.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.5.0) (proxy/ERC1967/ERC1967Upgrade.sol)\n\npragma solidity ^0.8.2;\n\nimport \"../beacon/IBeacon.sol\";\nimport \"../../interfaces/draft-IERC1822.sol\";\nimport \"../../utils/Address.sol\";\nimport \"../../utils/StorageSlot.sol\";\n\n/**\n * @dev This abstract contract provides getters and event emitting update functions for\n * https://eips.ethereum.org/EIPS/eip-1967[EIP1967] slots.\n *\n * _Available since v4.1._\n *\n * @custom:oz-upgrades-unsafe-allow delegatecall\n */\nabstract contract ERC1967Upgrade {\n // This is the keccak-256 hash of \"eip1967.proxy.rollback\" subtracted by 1\n bytes32 private constant _ROLLBACK_SLOT = 0x4910fdfa16fed3260ed0e7147f7cc6da11a60208b5b9406d12a635614ffd9143;\n\n /**\n * @dev Storage slot with the address of the current implementation.\n * This is the keccak-256 hash of \"eip1967.proxy.implementation\" subtracted by 1, and is\n * validated in the constructor.\n */\n bytes32 internal constant _IMPLEMENTATION_SLOT = 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc;\n\n /**\n * @dev Emitted when the implementation is upgraded.\n */\n event Upgraded(address indexed implementation);\n\n /**\n * @dev Returns the current implementation address.\n */\n function _getImplementation() internal view returns (address) {\n return StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value;\n }\n\n /**\n * @dev Stores a new address in the EIP1967 implementation slot.\n */\n function _setImplementation(address newImplementation) private {\n require(Address.isContract(newImplementation), \"ERC1967: new implementation is not a contract\");\n StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value = newImplementation;\n }\n\n /**\n * @dev Perform implementation upgrade\n *\n * Emits an {Upgraded} event.\n */\n function _upgradeTo(address newImplementation) internal {\n _setImplementation(newImplementation);\n emit Upgraded(newImplementation);\n }\n\n /**\n * @dev Perform implementation upgrade with additional setup call.\n *\n * Emits an {Upgraded} event.\n */\n function _upgradeToAndCall(\n address newImplementation,\n bytes memory data,\n bool forceCall\n ) internal {\n _upgradeTo(newImplementation);\n if (data.length > 0 || forceCall) {\n Address.functionDelegateCall(newImplementation, data);\n }\n }\n\n /**\n * @dev Perform implementation upgrade with security checks for UUPS proxies, and additional setup call.\n *\n * Emits an {Upgraded} event.\n */\n function _upgradeToAndCallUUPS(\n address newImplementation,\n bytes memory data,\n bool forceCall\n ) internal {\n // Upgrades from old implementations will perform a rollback test. This test requires the new\n // implementation to upgrade back to the old, non-ERC1822 compliant, implementation. Removing\n // this special case will break upgrade paths from old UUPS implementation to new ones.\n if (StorageSlot.getBooleanSlot(_ROLLBACK_SLOT).value) {\n _setImplementation(newImplementation);\n } else {\n try IERC1822Proxiable(newImplementation).proxiableUUID() returns (bytes32 slot) {\n require(slot == _IMPLEMENTATION_SLOT, \"ERC1967Upgrade: unsupported proxiableUUID\");\n } catch {\n revert(\"ERC1967Upgrade: new implementation is not UUPS\");\n }\n _upgradeToAndCall(newImplementation, data, forceCall);\n }\n }\n\n /**\n * @dev Storage slot with the admin of the contract.\n * This is the keccak-256 hash of \"eip1967.proxy.admin\" subtracted by 1, and is\n * validated in the constructor.\n */\n bytes32 internal constant _ADMIN_SLOT = 0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103;\n\n /**\n * @dev Emitted when the admin account has changed.\n */\n event AdminChanged(address previousAdmin, address newAdmin);\n\n /**\n * @dev Returns the current admin.\n */\n function _getAdmin() internal view returns (address) {\n return StorageSlot.getAddressSlot(_ADMIN_SLOT).value;\n }\n\n /**\n * @dev Stores a new address in the EIP1967 admin slot.\n */\n function _setAdmin(address newAdmin) private {\n require(newAdmin != address(0), \"ERC1967: new admin is the zero address\");\n StorageSlot.getAddressSlot(_ADMIN_SLOT).value = newAdmin;\n }\n\n /**\n * @dev Changes the admin of the proxy.\n *\n * Emits an {AdminChanged} event.\n */\n function _changeAdmin(address newAdmin) internal {\n emit AdminChanged(_getAdmin(), newAdmin);\n _setAdmin(newAdmin);\n }\n\n /**\n * @dev The storage slot of the UpgradeableBeacon contract which defines the implementation for this proxy.\n * This is bytes32(uint256(keccak256('eip1967.proxy.beacon')) - 1)) and is validated in the constructor.\n */\n bytes32 internal constant _BEACON_SLOT = 0xa3f0ad74e5423aebfd80d3ef4346578335a9a72aeaee59ff6cb3582b35133d50;\n\n /**\n * @dev Emitted when the beacon is upgraded.\n */\n event BeaconUpgraded(address indexed beacon);\n\n /**\n * @dev Returns the current beacon.\n */\n function _getBeacon() internal view returns (address) {\n return StorageSlot.getAddressSlot(_BEACON_SLOT).value;\n }\n\n /**\n * @dev Stores a new beacon in the EIP1967 beacon slot.\n */\n function _setBeacon(address newBeacon) private {\n require(Address.isContract(newBeacon), \"ERC1967: new beacon is not a contract\");\n require(\n Address.isContract(IBeacon(newBeacon).implementation()),\n \"ERC1967: beacon implementation is not a contract\"\n );\n StorageSlot.getAddressSlot(_BEACON_SLOT).value = newBeacon;\n }\n\n /**\n * @dev Perform beacon upgrade with additional setup call. Note: This upgrades the address of the beacon, it does\n * not upgrade the implementation contained in the beacon (see {UpgradeableBeacon-_setImplementation} for that).\n *\n * Emits a {BeaconUpgraded} event.\n */\n function _upgradeBeaconToAndCall(\n address newBeacon,\n bytes memory data,\n bool forceCall\n ) internal {\n _setBeacon(newBeacon);\n emit BeaconUpgraded(newBeacon);\n if (data.length > 0 || forceCall) {\n Address.functionDelegateCall(IBeacon(newBeacon).implementation(), data);\n }\n }\n}\n" + }, + "@openzeppelin/contracts/proxy/Proxy.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.6.0) (proxy/Proxy.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev This abstract contract provides a fallback function that delegates all calls to another contract using the EVM\n * instruction `delegatecall`. We refer to the second contract as the _implementation_ behind the proxy, and it has to\n * be specified by overriding the virtual {_implementation} function.\n *\n * Additionally, delegation to the implementation can be triggered manually through the {_fallback} function, or to a\n * different contract through the {_delegate} function.\n *\n * The success and return data of the delegated call will be returned back to the caller of the proxy.\n */\nabstract contract Proxy {\n /**\n * @dev Delegates the current call to `implementation`.\n *\n * This function does not return to its internal call site, it will return directly to the external caller.\n */\n function _delegate(address implementation) internal virtual {\n assembly {\n // Copy msg.data. We take full control of memory in this inline assembly\n // block because it will not return to Solidity code. We overwrite the\n // Solidity scratch pad at memory position 0.\n calldatacopy(0, 0, calldatasize())\n\n // Call the implementation.\n // out and outsize are 0 because we don't know the size yet.\n let result := delegatecall(gas(), implementation, 0, calldatasize(), 0, 0)\n\n // Copy the returned data.\n returndatacopy(0, 0, returndatasize())\n\n switch result\n // delegatecall returns 0 on error.\n case 0 {\n revert(0, returndatasize())\n }\n default {\n return(0, returndatasize())\n }\n }\n }\n\n /**\n * @dev This is a virtual function that should be overridden so it returns the address to which the fallback function\n * and {_fallback} should delegate.\n */\n function _implementation() internal view virtual returns (address);\n\n /**\n * @dev Delegates the current call to the address returned by `_implementation()`.\n *\n * This function does not return to its internal call site, it will return directly to the external caller.\n */\n function _fallback() internal virtual {\n _beforeFallback();\n _delegate(_implementation());\n }\n\n /**\n * @dev Fallback function that delegates calls to the address returned by `_implementation()`. Will run if no other\n * function in the contract matches the call data.\n */\n fallback() external payable virtual {\n _fallback();\n }\n\n /**\n * @dev Fallback function that delegates calls to the address returned by `_implementation()`. Will run if call data\n * is empty.\n */\n receive() external payable virtual {\n _fallback();\n }\n\n /**\n * @dev Hook that is called before falling back to the implementation. Can happen as part of a manual `_fallback`\n * call, or as part of the Solidity `fallback` or `receive` functions.\n *\n * If overridden should call `super._beforeFallback()`.\n */\n function _beforeFallback() internal virtual {}\n}\n" + }, + "@openzeppelin/contracts/token/ERC20/ERC20.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (token/ERC20/ERC20.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./IERC20.sol\";\nimport \"./extensions/IERC20Metadata.sol\";\nimport \"../../utils/Context.sol\";\n\n/**\n * @dev Implementation of the {IERC20} interface.\n *\n * This implementation is agnostic to the way tokens are created. This means\n * that a supply mechanism has to be added in a derived contract using {_mint}.\n * For a generic mechanism see {ERC20PresetMinterPauser}.\n *\n * TIP: For a detailed writeup see our guide\n * https://forum.zeppelin.solutions/t/how-to-implement-erc20-supply-mechanisms/226[How\n * to implement supply mechanisms].\n *\n * We have followed general OpenZeppelin Contracts guidelines: functions revert\n * instead returning `false` on failure. This behavior is nonetheless\n * conventional and does not conflict with the expectations of ERC20\n * applications.\n *\n * Additionally, an {Approval} event is emitted on calls to {transferFrom}.\n * This allows applications to reconstruct the allowance for all accounts just\n * by listening to said events. Other implementations of the EIP may not emit\n * these events, as it isn't required by the specification.\n *\n * Finally, the non-standard {decreaseAllowance} and {increaseAllowance}\n * functions have been added to mitigate the well-known issues around setting\n * allowances. See {IERC20-approve}.\n */\ncontract ERC20 is Context, IERC20, IERC20Metadata {\n mapping(address => uint256) private _balances;\n\n mapping(address => mapping(address => uint256)) private _allowances;\n\n uint256 private _totalSupply;\n\n string private _name;\n string private _symbol;\n\n /**\n * @dev Sets the values for {name} and {symbol}.\n *\n * The default value of {decimals} is 18. To select a different value for\n * {decimals} you should overload it.\n *\n * All two of these values are immutable: they can only be set once during\n * construction.\n */\n constructor(string memory name_, string memory symbol_) {\n _name = name_;\n _symbol = symbol_;\n }\n\n /**\n * @dev Returns the name of the token.\n */\n function name() public view virtual override returns (string memory) {\n return _name;\n }\n\n /**\n * @dev Returns the symbol of the token, usually a shorter version of the\n * name.\n */\n function symbol() public view virtual override returns (string memory) {\n return _symbol;\n }\n\n /**\n * @dev Returns the number of decimals used to get its user representation.\n * For example, if `decimals` equals `2`, a balance of `505` tokens should\n * be displayed to a user as `5.05` (`505 / 10 ** 2`).\n *\n * Tokens usually opt for a value of 18, imitating the relationship between\n * Ether and Wei. This is the value {ERC20} uses, unless this function is\n * overridden;\n *\n * NOTE: This information is only used for _display_ purposes: it in\n * no way affects any of the arithmetic of the contract, including\n * {IERC20-balanceOf} and {IERC20-transfer}.\n */\n function decimals() public view virtual override returns (uint8) {\n return 18;\n }\n\n /**\n * @dev See {IERC20-totalSupply}.\n */\n function totalSupply() public view virtual override returns (uint256) {\n return _totalSupply;\n }\n\n /**\n * @dev See {IERC20-balanceOf}.\n */\n function balanceOf(address account) public view virtual override returns (uint256) {\n return _balances[account];\n }\n\n /**\n * @dev See {IERC20-transfer}.\n *\n * Requirements:\n *\n * - `to` cannot be the zero address.\n * - the caller must have a balance of at least `amount`.\n */\n function transfer(address to, uint256 amount) public virtual override returns (bool) {\n address owner = _msgSender();\n _transfer(owner, to, amount);\n return true;\n }\n\n /**\n * @dev See {IERC20-allowance}.\n */\n function allowance(address owner, address spender) public view virtual override returns (uint256) {\n return _allowances[owner][spender];\n }\n\n /**\n * @dev See {IERC20-approve}.\n *\n * NOTE: If `amount` is the maximum `uint256`, the allowance is not updated on\n * `transferFrom`. This is semantically equivalent to an infinite approval.\n *\n * Requirements:\n *\n * - `spender` cannot be the zero address.\n */\n function approve(address spender, uint256 amount) public virtual override returns (bool) {\n address owner = _msgSender();\n _approve(owner, spender, amount);\n return true;\n }\n\n /**\n * @dev See {IERC20-transferFrom}.\n *\n * Emits an {Approval} event indicating the updated allowance. This is not\n * required by the EIP. See the note at the beginning of {ERC20}.\n *\n * NOTE: Does not update the allowance if the current allowance\n * is the maximum `uint256`.\n *\n * Requirements:\n *\n * - `from` and `to` cannot be the zero address.\n * - `from` must have a balance of at least `amount`.\n * - the caller must have allowance for ``from``'s tokens of at least\n * `amount`.\n */\n function transferFrom(\n address from,\n address to,\n uint256 amount\n ) public virtual override returns (bool) {\n address spender = _msgSender();\n _spendAllowance(from, spender, amount);\n _transfer(from, to, amount);\n return true;\n }\n\n /**\n * @dev Atomically increases the allowance granted to `spender` by the caller.\n *\n * This is an alternative to {approve} that can be used as a mitigation for\n * problems described in {IERC20-approve}.\n *\n * Emits an {Approval} event indicating the updated allowance.\n *\n * Requirements:\n *\n * - `spender` cannot be the zero address.\n */\n function increaseAllowance(address spender, uint256 addedValue) public virtual returns (bool) {\n address owner = _msgSender();\n _approve(owner, spender, allowance(owner, spender) + addedValue);\n return true;\n }\n\n /**\n * @dev Atomically decreases the allowance granted to `spender` by the caller.\n *\n * This is an alternative to {approve} that can be used as a mitigation for\n * problems described in {IERC20-approve}.\n *\n * Emits an {Approval} event indicating the updated allowance.\n *\n * Requirements:\n *\n * - `spender` cannot be the zero address.\n * - `spender` must have allowance for the caller of at least\n * `subtractedValue`.\n */\n function decreaseAllowance(address spender, uint256 subtractedValue) public virtual returns (bool) {\n address owner = _msgSender();\n uint256 currentAllowance = allowance(owner, spender);\n require(currentAllowance >= subtractedValue, \"ERC20: decreased allowance below zero\");\n unchecked {\n _approve(owner, spender, currentAllowance - subtractedValue);\n }\n\n return true;\n }\n\n /**\n * @dev Moves `amount` of tokens from `from` to `to`.\n *\n * This internal function is equivalent to {transfer}, and can be used to\n * e.g. implement automatic token fees, slashing mechanisms, etc.\n *\n * Emits a {Transfer} event.\n *\n * Requirements:\n *\n * - `from` cannot be the zero address.\n * - `to` cannot be the zero address.\n * - `from` must have a balance of at least `amount`.\n */\n function _transfer(\n address from,\n address to,\n uint256 amount\n ) internal virtual {\n require(from != address(0), \"ERC20: transfer from the zero address\");\n require(to != address(0), \"ERC20: transfer to the zero address\");\n\n _beforeTokenTransfer(from, to, amount);\n\n uint256 fromBalance = _balances[from];\n require(fromBalance >= amount, \"ERC20: transfer amount exceeds balance\");\n unchecked {\n _balances[from] = fromBalance - amount;\n }\n _balances[to] += amount;\n\n emit Transfer(from, to, amount);\n\n _afterTokenTransfer(from, to, amount);\n }\n\n /** @dev Creates `amount` tokens and assigns them to `account`, increasing\n * the total supply.\n *\n * Emits a {Transfer} event with `from` set to the zero address.\n *\n * Requirements:\n *\n * - `account` cannot be the zero address.\n */\n function _mint(address account, uint256 amount) internal virtual {\n require(account != address(0), \"ERC20: mint to the zero address\");\n\n _beforeTokenTransfer(address(0), account, amount);\n\n _totalSupply += amount;\n _balances[account] += amount;\n emit Transfer(address(0), account, amount);\n\n _afterTokenTransfer(address(0), account, amount);\n }\n\n /**\n * @dev Destroys `amount` tokens from `account`, reducing the\n * total supply.\n *\n * Emits a {Transfer} event with `to` set to the zero address.\n *\n * Requirements:\n *\n * - `account` cannot be the zero address.\n * - `account` must have at least `amount` tokens.\n */\n function _burn(address account, uint256 amount) internal virtual {\n require(account != address(0), \"ERC20: burn from the zero address\");\n\n _beforeTokenTransfer(account, address(0), amount);\n\n uint256 accountBalance = _balances[account];\n require(accountBalance >= amount, \"ERC20: burn amount exceeds balance\");\n unchecked {\n _balances[account] = accountBalance - amount;\n }\n _totalSupply -= amount;\n\n emit Transfer(account, address(0), amount);\n\n _afterTokenTransfer(account, address(0), amount);\n }\n\n /**\n * @dev Sets `amount` as the allowance of `spender` over the `owner` s tokens.\n *\n * This internal function is equivalent to `approve`, and can be used to\n * e.g. set automatic allowances for certain subsystems, etc.\n *\n * Emits an {Approval} event.\n *\n * Requirements:\n *\n * - `owner` cannot be the zero address.\n * - `spender` cannot be the zero address.\n */\n function _approve(\n address owner,\n address spender,\n uint256 amount\n ) internal virtual {\n require(owner != address(0), \"ERC20: approve from the zero address\");\n require(spender != address(0), \"ERC20: approve to the zero address\");\n\n _allowances[owner][spender] = amount;\n emit Approval(owner, spender, amount);\n }\n\n /**\n * @dev Updates `owner` s allowance for `spender` based on spent `amount`.\n *\n * Does not update the allowance amount in case of infinite allowance.\n * Revert if not enough allowance is available.\n *\n * Might emit an {Approval} event.\n */\n function _spendAllowance(\n address owner,\n address spender,\n uint256 amount\n ) internal virtual {\n uint256 currentAllowance = allowance(owner, spender);\n if (currentAllowance != type(uint256).max) {\n require(currentAllowance >= amount, \"ERC20: insufficient allowance\");\n unchecked {\n _approve(owner, spender, currentAllowance - amount);\n }\n }\n }\n\n /**\n * @dev Hook that is called before any transfer of tokens. This includes\n * minting and burning.\n *\n * Calling conditions:\n *\n * - when `from` and `to` are both non-zero, `amount` of ``from``'s tokens\n * will be transferred to `to`.\n * - when `from` is zero, `amount` tokens will be minted for `to`.\n * - when `to` is zero, `amount` of ``from``'s tokens will be burned.\n * - `from` and `to` are never both zero.\n *\n * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].\n */\n function _beforeTokenTransfer(\n address from,\n address to,\n uint256 amount\n ) internal virtual {}\n\n /**\n * @dev Hook that is called after any transfer of tokens. This includes\n * minting and burning.\n *\n * Calling conditions:\n *\n * - when `from` and `to` are both non-zero, `amount` of ``from``'s tokens\n * has been transferred to `to`.\n * - when `from` is zero, `amount` tokens have been minted for `to`.\n * - when `to` is zero, `amount` of ``from``'s tokens have been burned.\n * - `from` and `to` are never both zero.\n *\n * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].\n */\n function _afterTokenTransfer(\n address from,\n address to,\n uint256 amount\n ) internal virtual {}\n}\n" + }, + "@openzeppelin/contracts/token/ERC20/extensions/draft-ERC20Permit.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.6.0) (token/ERC20/extensions/draft-ERC20Permit.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./draft-IERC20Permit.sol\";\nimport \"../ERC20.sol\";\nimport \"../../../utils/cryptography/draft-EIP712.sol\";\nimport \"../../../utils/cryptography/ECDSA.sol\";\nimport \"../../../utils/Counters.sol\";\n\n/**\n * @dev Implementation of the ERC20 Permit extension allowing approvals to be made via signatures, as defined in\n * https://eips.ethereum.org/EIPS/eip-2612[EIP-2612].\n *\n * Adds the {permit} method, which can be used to change an account's ERC20 allowance (see {IERC20-allowance}) by\n * presenting a message signed by the account. By not relying on `{IERC20-approve}`, the token holder account doesn't\n * need to send a transaction, and thus is not required to hold Ether at all.\n *\n * _Available since v3.4._\n */\nabstract contract ERC20Permit is ERC20, IERC20Permit, EIP712 {\n using Counters for Counters.Counter;\n\n mapping(address => Counters.Counter) private _nonces;\n\n // solhint-disable-next-line var-name-mixedcase\n bytes32 private constant _PERMIT_TYPEHASH =\n keccak256(\"Permit(address owner,address spender,uint256 value,uint256 nonce,uint256 deadline)\");\n /**\n * @dev In previous versions `_PERMIT_TYPEHASH` was declared as `immutable`.\n * However, to ensure consistency with the upgradeable transpiler, we will continue\n * to reserve a slot.\n * @custom:oz-renamed-from _PERMIT_TYPEHASH\n */\n // solhint-disable-next-line var-name-mixedcase\n bytes32 private _PERMIT_TYPEHASH_DEPRECATED_SLOT;\n\n /**\n * @dev Initializes the {EIP712} domain separator using the `name` parameter, and setting `version` to `\"1\"`.\n *\n * It's a good idea to use the same `name` that is defined as the ERC20 token name.\n */\n constructor(string memory name) EIP712(name, \"1\") {}\n\n /**\n * @dev See {IERC20Permit-permit}.\n */\n function permit(\n address owner,\n address spender,\n uint256 value,\n uint256 deadline,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) public virtual override {\n require(block.timestamp <= deadline, \"ERC20Permit: expired deadline\");\n\n bytes32 structHash = keccak256(abi.encode(_PERMIT_TYPEHASH, owner, spender, value, _useNonce(owner), deadline));\n\n bytes32 hash = _hashTypedDataV4(structHash);\n\n address signer = ECDSA.recover(hash, v, r, s);\n require(signer == owner, \"ERC20Permit: invalid signature\");\n\n _approve(owner, spender, value);\n }\n\n /**\n * @dev See {IERC20Permit-nonces}.\n */\n function nonces(address owner) public view virtual override returns (uint256) {\n return _nonces[owner].current();\n }\n\n /**\n * @dev See {IERC20Permit-DOMAIN_SEPARATOR}.\n */\n // solhint-disable-next-line func-name-mixedcase\n function DOMAIN_SEPARATOR() external view override returns (bytes32) {\n return _domainSeparatorV4();\n }\n\n /**\n * @dev \"Consume a nonce\": return the current value and increment.\n *\n * _Available since v4.1._\n */\n function _useNonce(address owner) internal virtual returns (uint256 current) {\n Counters.Counter storage nonce = _nonces[owner];\n current = nonce.current();\n nonce.increment();\n }\n}\n" + }, + "@openzeppelin/contracts/token/ERC20/extensions/draft-IERC20Permit.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (token/ERC20/extensions/draft-IERC20Permit.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Interface of the ERC20 Permit extension allowing approvals to be made via signatures, as defined in\n * https://eips.ethereum.org/EIPS/eip-2612[EIP-2612].\n *\n * Adds the {permit} method, which can be used to change an account's ERC20 allowance (see {IERC20-allowance}) by\n * presenting a message signed by the account. By not relying on {IERC20-approve}, the token holder account doesn't\n * need to send a transaction, and thus is not required to hold Ether at all.\n */\ninterface IERC20Permit {\n /**\n * @dev Sets `value` as the allowance of `spender` over ``owner``'s tokens,\n * given ``owner``'s signed approval.\n *\n * IMPORTANT: The same issues {IERC20-approve} has related to transaction\n * ordering also apply here.\n *\n * Emits an {Approval} event.\n *\n * Requirements:\n *\n * - `spender` cannot be the zero address.\n * - `deadline` must be a timestamp in the future.\n * - `v`, `r` and `s` must be a valid `secp256k1` signature from `owner`\n * over the EIP712-formatted function arguments.\n * - the signature must use ``owner``'s current nonce (see {nonces}).\n *\n * For more information on the signature format, see the\n * https://eips.ethereum.org/EIPS/eip-2612#specification[relevant EIP\n * section].\n */\n function permit(\n address owner,\n address spender,\n uint256 value,\n uint256 deadline,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) external;\n\n /**\n * @dev Returns the current nonce for `owner`. This value must be\n * included whenever a signature is generated for {permit}.\n *\n * Every successful call to {permit} increases ``owner``'s nonce by one. This\n * prevents a signature from being used multiple times.\n */\n function nonces(address owner) external view returns (uint256);\n\n /**\n * @dev Returns the domain separator used in the encoding of the signature for {permit}, as defined by {EIP712}.\n */\n // solhint-disable-next-line func-name-mixedcase\n function DOMAIN_SEPARATOR() external view returns (bytes32);\n}\n" + }, + "@openzeppelin/contracts/token/ERC20/extensions/IERC20Metadata.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (token/ERC20/extensions/IERC20Metadata.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../IERC20.sol\";\n\n/**\n * @dev Interface for the optional metadata functions from the ERC20 standard.\n *\n * _Available since v4.1._\n */\ninterface IERC20Metadata is IERC20 {\n /**\n * @dev Returns the name of the token.\n */\n function name() external view returns (string memory);\n\n /**\n * @dev Returns the symbol of the token.\n */\n function symbol() external view returns (string memory);\n\n /**\n * @dev Returns the decimals places of the token.\n */\n function decimals() external view returns (uint8);\n}\n" + }, + "@openzeppelin/contracts/token/ERC20/IERC20.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.6.0) (token/ERC20/IERC20.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Interface of the ERC20 standard as defined in the EIP.\n */\ninterface IERC20 {\n /**\n * @dev Emitted when `value` tokens are moved from one account (`from`) to\n * another (`to`).\n *\n * Note that `value` may be zero.\n */\n event Transfer(address indexed from, address indexed to, uint256 value);\n\n /**\n * @dev Emitted when the allowance of a `spender` for an `owner` is set by\n * a call to {approve}. `value` is the new allowance.\n */\n event Approval(address indexed owner, address indexed spender, uint256 value);\n\n /**\n * @dev Returns the amount of tokens in existence.\n */\n function totalSupply() external view returns (uint256);\n\n /**\n * @dev Returns the amount of tokens owned by `account`.\n */\n function balanceOf(address account) external view returns (uint256);\n\n /**\n * @dev Moves `amount` tokens from the caller's account to `to`.\n *\n * Returns a boolean value indicating whether the operation succeeded.\n *\n * Emits a {Transfer} event.\n */\n function transfer(address to, uint256 amount) external returns (bool);\n\n /**\n * @dev Returns the remaining number of tokens that `spender` will be\n * allowed to spend on behalf of `owner` through {transferFrom}. This is\n * zero by default.\n *\n * This value changes when {approve} or {transferFrom} are called.\n */\n function allowance(address owner, address spender) external view returns (uint256);\n\n /**\n * @dev Sets `amount` as the allowance of `spender` over the caller's tokens.\n *\n * Returns a boolean value indicating whether the operation succeeded.\n *\n * IMPORTANT: Beware that changing an allowance with this method brings the risk\n * that someone may use both the old and the new allowance by unfortunate\n * transaction ordering. One possible solution to mitigate this race\n * condition is to first reduce the spender's allowance to 0 and set the\n * desired value afterwards:\n * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729\n *\n * Emits an {Approval} event.\n */\n function approve(address spender, uint256 amount) external returns (bool);\n\n /**\n * @dev Moves `amount` tokens from `from` to `to` using the\n * allowance mechanism. `amount` is then deducted from the caller's\n * allowance.\n *\n * Returns a boolean value indicating whether the operation succeeded.\n *\n * Emits a {Transfer} event.\n */\n function transferFrom(\n address from,\n address to,\n uint256 amount\n ) external returns (bool);\n}\n" + }, + "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (token/ERC20/utils/SafeERC20.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../IERC20.sol\";\nimport \"../extensions/draft-IERC20Permit.sol\";\nimport \"../../../utils/Address.sol\";\n\n/**\n * @title SafeERC20\n * @dev Wrappers around ERC20 operations that throw on failure (when the token\n * contract returns false). Tokens that return no value (and instead revert or\n * throw on failure) are also supported, non-reverting calls are assumed to be\n * successful.\n * To use this library you can add a `using SafeERC20 for IERC20;` statement to your contract,\n * which allows you to call the safe operations as `token.safeTransfer(...)`, etc.\n */\nlibrary SafeERC20 {\n using Address for address;\n\n function safeTransfer(\n IERC20 token,\n address to,\n uint256 value\n ) internal {\n _callOptionalReturn(token, abi.encodeWithSelector(token.transfer.selector, to, value));\n }\n\n function safeTransferFrom(\n IERC20 token,\n address from,\n address to,\n uint256 value\n ) internal {\n _callOptionalReturn(token, abi.encodeWithSelector(token.transferFrom.selector, from, to, value));\n }\n\n /**\n * @dev Deprecated. This function has issues similar to the ones found in\n * {IERC20-approve}, and its usage is discouraged.\n *\n * Whenever possible, use {safeIncreaseAllowance} and\n * {safeDecreaseAllowance} instead.\n */\n function safeApprove(\n IERC20 token,\n address spender,\n uint256 value\n ) internal {\n // safeApprove should only be called when setting an initial allowance,\n // or when resetting it to zero. To increase and decrease it, use\n // 'safeIncreaseAllowance' and 'safeDecreaseAllowance'\n require(\n (value == 0) || (token.allowance(address(this), spender) == 0),\n \"SafeERC20: approve from non-zero to non-zero allowance\"\n );\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, value));\n }\n\n function safeIncreaseAllowance(\n IERC20 token,\n address spender,\n uint256 value\n ) internal {\n uint256 newAllowance = token.allowance(address(this), spender) + value;\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));\n }\n\n function safeDecreaseAllowance(\n IERC20 token,\n address spender,\n uint256 value\n ) internal {\n unchecked {\n uint256 oldAllowance = token.allowance(address(this), spender);\n require(oldAllowance >= value, \"SafeERC20: decreased allowance below zero\");\n uint256 newAllowance = oldAllowance - value;\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));\n }\n }\n\n function safePermit(\n IERC20Permit token,\n address owner,\n address spender,\n uint256 value,\n uint256 deadline,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) internal {\n uint256 nonceBefore = token.nonces(owner);\n token.permit(owner, spender, value, deadline, v, r, s);\n uint256 nonceAfter = token.nonces(owner);\n require(nonceAfter == nonceBefore + 1, \"SafeERC20: permit did not succeed\");\n }\n\n /**\n * @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement\n * on the return value: the return value is optional (but if data is returned, it must not be false).\n * @param token The token targeted by the call.\n * @param data The call data (encoded using abi.encode or one of its variants).\n */\n function _callOptionalReturn(IERC20 token, bytes memory data) private {\n // We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since\n // we're implementing it ourselves. We use {Address.functionCall} to perform this call, which verifies that\n // the target address contains contract code and also asserts for success in the low-level call.\n\n bytes memory returndata = address(token).functionCall(data, \"SafeERC20: low-level call failed\");\n if (returndata.length > 0) {\n // Return data is optional\n require(abi.decode(returndata, (bool)), \"SafeERC20: ERC20 operation did not succeed\");\n }\n }\n}\n" + }, + "@openzeppelin/contracts/token/ERC721/extensions/IERC721Metadata.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (token/ERC721/extensions/IERC721Metadata.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../IERC721.sol\";\n\n/**\n * @title ERC-721 Non-Fungible Token Standard, optional metadata extension\n * @dev See https://eips.ethereum.org/EIPS/eip-721\n */\ninterface IERC721Metadata is IERC721 {\n /**\n * @dev Returns the token collection name.\n */\n function name() external view returns (string memory);\n\n /**\n * @dev Returns the token collection symbol.\n */\n function symbol() external view returns (string memory);\n\n /**\n * @dev Returns the Uniform Resource Identifier (URI) for `tokenId` token.\n */\n function tokenURI(uint256 tokenId) external view returns (string memory);\n}\n" + }, + "@openzeppelin/contracts/token/ERC721/IERC721.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (token/ERC721/IERC721.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../../utils/introspection/IERC165.sol\";\n\n/**\n * @dev Required interface of an ERC721 compliant contract.\n */\ninterface IERC721 is IERC165 {\n /**\n * @dev Emitted when `tokenId` token is transferred from `from` to `to`.\n */\n event Transfer(address indexed from, address indexed to, uint256 indexed tokenId);\n\n /**\n * @dev Emitted when `owner` enables `approved` to manage the `tokenId` token.\n */\n event Approval(address indexed owner, address indexed approved, uint256 indexed tokenId);\n\n /**\n * @dev Emitted when `owner` enables or disables (`approved`) `operator` to manage all of its assets.\n */\n event ApprovalForAll(address indexed owner, address indexed operator, bool approved);\n\n /**\n * @dev Returns the number of tokens in ``owner``'s account.\n */\n function balanceOf(address owner) external view returns (uint256 balance);\n\n /**\n * @dev Returns the owner of the `tokenId` token.\n *\n * Requirements:\n *\n * - `tokenId` must exist.\n */\n function ownerOf(uint256 tokenId) external view returns (address owner);\n\n /**\n * @dev Safely transfers `tokenId` token from `from` to `to`.\n *\n * Requirements:\n *\n * - `from` cannot be the zero address.\n * - `to` cannot be the zero address.\n * - `tokenId` token must exist and be owned by `from`.\n * - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}.\n * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.\n *\n * Emits a {Transfer} event.\n */\n function safeTransferFrom(\n address from,\n address to,\n uint256 tokenId,\n bytes calldata data\n ) external;\n\n /**\n * @dev Safely transfers `tokenId` token from `from` to `to`, checking first that contract recipients\n * are aware of the ERC721 protocol to prevent tokens from being forever locked.\n *\n * Requirements:\n *\n * - `from` cannot be the zero address.\n * - `to` cannot be the zero address.\n * - `tokenId` token must exist and be owned by `from`.\n * - If the caller is not `from`, it must have been allowed to move this token by either {approve} or {setApprovalForAll}.\n * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.\n *\n * Emits a {Transfer} event.\n */\n function safeTransferFrom(\n address from,\n address to,\n uint256 tokenId\n ) external;\n\n /**\n * @dev Transfers `tokenId` token from `from` to `to`.\n *\n * WARNING: Usage of this method is discouraged, use {safeTransferFrom} whenever possible.\n *\n * Requirements:\n *\n * - `from` cannot be the zero address.\n * - `to` cannot be the zero address.\n * - `tokenId` token must be owned by `from`.\n * - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}.\n *\n * Emits a {Transfer} event.\n */\n function transferFrom(\n address from,\n address to,\n uint256 tokenId\n ) external;\n\n /**\n * @dev Gives permission to `to` to transfer `tokenId` token to another account.\n * The approval is cleared when the token is transferred.\n *\n * Only a single account can be approved at a time, so approving the zero address clears previous approvals.\n *\n * Requirements:\n *\n * - The caller must own the token or be an approved operator.\n * - `tokenId` must exist.\n *\n * Emits an {Approval} event.\n */\n function approve(address to, uint256 tokenId) external;\n\n /**\n * @dev Approve or remove `operator` as an operator for the caller.\n * Operators can call {transferFrom} or {safeTransferFrom} for any token owned by the caller.\n *\n * Requirements:\n *\n * - The `operator` cannot be the caller.\n *\n * Emits an {ApprovalForAll} event.\n */\n function setApprovalForAll(address operator, bool _approved) external;\n\n /**\n * @dev Returns the account approved for `tokenId` token.\n *\n * Requirements:\n *\n * - `tokenId` must exist.\n */\n function getApproved(uint256 tokenId) external view returns (address operator);\n\n /**\n * @dev Returns if the `operator` is allowed to manage all of the assets of `owner`.\n *\n * See {setApprovalForAll}\n */\n function isApprovedForAll(address owner, address operator) external view returns (bool);\n}\n" + }, + "@openzeppelin/contracts/utils/Address.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (utils/Address.sol)\n\npragma solidity ^0.8.1;\n\n/**\n * @dev Collection of functions related to the address type\n */\nlibrary Address {\n /**\n * @dev Returns true if `account` is a contract.\n *\n * [IMPORTANT]\n * ====\n * It is unsafe to assume that an address for which this function returns\n * false is an externally-owned account (EOA) and not a contract.\n *\n * Among others, `isContract` will return false for the following\n * types of addresses:\n *\n * - an externally-owned account\n * - a contract in construction\n * - an address where a contract will be created\n * - an address where a contract lived, but was destroyed\n * ====\n *\n * [IMPORTANT]\n * ====\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\n *\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\n * constructor.\n * ====\n */\n function isContract(address account) internal view returns (bool) {\n // This method relies on extcodesize/address.code.length, which returns 0\n // for contracts in construction, since the code is only stored at the end\n // of the constructor execution.\n\n return account.code.length > 0;\n }\n\n /**\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\n * `recipient`, forwarding all available gas and reverting on errors.\n *\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\n * imposed by `transfer`, making them unable to receive funds via\n * `transfer`. {sendValue} removes this limitation.\n *\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\n *\n * IMPORTANT: because control is transferred to `recipient`, care must be\n * taken to not create reentrancy vulnerabilities. Consider using\n * {ReentrancyGuard} or the\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\n */\n function sendValue(address payable recipient, uint256 amount) internal {\n require(address(this).balance >= amount, \"Address: insufficient balance\");\n\n (bool success, ) = recipient.call{value: amount}(\"\");\n require(success, \"Address: unable to send value, recipient may have reverted\");\n }\n\n /**\n * @dev Performs a Solidity function call using a low level `call`. A\n * plain `call` is an unsafe replacement for a function call: use this\n * function instead.\n *\n * If `target` reverts with a revert reason, it is bubbled up by this\n * function (like regular Solidity function calls).\n *\n * Returns the raw returned data. To convert to the expected return value,\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\n *\n * Requirements:\n *\n * - `target` must be a contract.\n * - calling `target` with `data` must not revert.\n *\n * _Available since v3.1._\n */\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionCall(target, data, \"Address: low-level call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\n * `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, 0, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but also transferring `value` wei to `target`.\n *\n * Requirements:\n *\n * - the calling contract must have an ETH balance of at least `value`.\n * - the called Solidity function must be `payable`.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, value, \"Address: low-level call with value failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\n * with `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(address(this).balance >= value, \"Address: insufficient balance for call\");\n require(isContract(target), \"Address: call to non-contract\");\n\n (bool success, bytes memory returndata) = target.call{value: value}(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\n return functionStaticCall(target, data, \"Address: low-level static call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal view returns (bytes memory) {\n require(isContract(target), \"Address: static call to non-contract\");\n\n (bool success, bytes memory returndata) = target.staticcall(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a delegate call.\n *\n * _Available since v3.4._\n */\n function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionDelegateCall(target, data, \"Address: low-level delegate call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a delegate call.\n *\n * _Available since v3.4._\n */\n function functionDelegateCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(isContract(target), \"Address: delegate call to non-contract\");\n\n (bool success, bytes memory returndata) = target.delegatecall(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the\n * revert reason using the provided one.\n *\n * _Available since v4.3._\n */\n function verifyCallResult(\n bool success,\n bytes memory returndata,\n string memory errorMessage\n ) internal pure returns (bytes memory) {\n if (success) {\n return returndata;\n } else {\n // Look for revert reason and bubble it up if present\n if (returndata.length > 0) {\n // The easiest way to bubble the revert reason is using memory via assembly\n /// @solidity memory-safe-assembly\n assembly {\n let returndata_size := mload(returndata)\n revert(add(32, returndata), returndata_size)\n }\n } else {\n revert(errorMessage);\n }\n }\n }\n}\n" + }, + "@openzeppelin/contracts/utils/Context.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Provides information about the current execution context, including the\n * sender of the transaction and its data. While these are generally available\n * via msg.sender and msg.data, they should not be accessed in such a direct\n * manner, since when dealing with meta-transactions the account sending and\n * paying for execution may not be the actual sender (as far as an application\n * is concerned).\n *\n * This contract is only required for intermediate, library-like contracts.\n */\nabstract contract Context {\n function _msgSender() internal view virtual returns (address) {\n return msg.sender;\n }\n\n function _msgData() internal view virtual returns (bytes calldata) {\n return msg.data;\n }\n}\n" + }, + "@openzeppelin/contracts/utils/Counters.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (utils/Counters.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @title Counters\n * @author Matt Condon (@shrugs)\n * @dev Provides counters that can only be incremented, decremented or reset. This can be used e.g. to track the number\n * of elements in a mapping, issuing ERC721 ids, or counting request ids.\n *\n * Include with `using Counters for Counters.Counter;`\n */\nlibrary Counters {\n struct Counter {\n // This variable should never be directly accessed by users of the library: interactions must be restricted to\n // the library's function. As of Solidity v0.5.2, this cannot be enforced, though there is a proposal to add\n // this feature: see https://github.com/ethereum/solidity/issues/4637\n uint256 _value; // default: 0\n }\n\n function current(Counter storage counter) internal view returns (uint256) {\n return counter._value;\n }\n\n function increment(Counter storage counter) internal {\n unchecked {\n counter._value += 1;\n }\n }\n\n function decrement(Counter storage counter) internal {\n uint256 value = counter._value;\n require(value > 0, \"Counter: decrement overflow\");\n unchecked {\n counter._value = value - 1;\n }\n }\n\n function reset(Counter storage counter) internal {\n counter._value = 0;\n }\n}\n" + }, + "@openzeppelin/contracts/utils/cryptography/draft-EIP712.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (utils/cryptography/draft-EIP712.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./ECDSA.sol\";\n\n/**\n * @dev https://eips.ethereum.org/EIPS/eip-712[EIP 712] is a standard for hashing and signing of typed structured data.\n *\n * The encoding specified in the EIP is very generic, and such a generic implementation in Solidity is not feasible,\n * thus this contract does not implement the encoding itself. Protocols need to implement the type-specific encoding\n * they need in their contracts using a combination of `abi.encode` and `keccak256`.\n *\n * This contract implements the EIP 712 domain separator ({_domainSeparatorV4}) that is used as part of the encoding\n * scheme, and the final step of the encoding to obtain the message digest that is then signed via ECDSA\n * ({_hashTypedDataV4}).\n *\n * The implementation of the domain separator was designed to be as efficient as possible while still properly updating\n * the chain id to protect against replay attacks on an eventual fork of the chain.\n *\n * NOTE: This contract implements the version of the encoding known as \"v4\", as implemented by the JSON RPC method\n * https://docs.metamask.io/guide/signing-data.html[`eth_signTypedDataV4` in MetaMask].\n *\n * _Available since v3.4._\n */\nabstract contract EIP712 {\n /* solhint-disable var-name-mixedcase */\n // Cache the domain separator as an immutable value, but also store the chain id that it corresponds to, in order to\n // invalidate the cached domain separator if the chain id changes.\n bytes32 private immutable _CACHED_DOMAIN_SEPARATOR;\n uint256 private immutable _CACHED_CHAIN_ID;\n address private immutable _CACHED_THIS;\n\n bytes32 private immutable _HASHED_NAME;\n bytes32 private immutable _HASHED_VERSION;\n bytes32 private immutable _TYPE_HASH;\n\n /* solhint-enable var-name-mixedcase */\n\n /**\n * @dev Initializes the domain separator and parameter caches.\n *\n * The meaning of `name` and `version` is specified in\n * https://eips.ethereum.org/EIPS/eip-712#definition-of-domainseparator[EIP 712]:\n *\n * - `name`: the user readable name of the signing domain, i.e. the name of the DApp or the protocol.\n * - `version`: the current major version of the signing domain.\n *\n * NOTE: These parameters cannot be changed except through a xref:learn::upgrading-smart-contracts.adoc[smart\n * contract upgrade].\n */\n constructor(string memory name, string memory version) {\n bytes32 hashedName = keccak256(bytes(name));\n bytes32 hashedVersion = keccak256(bytes(version));\n bytes32 typeHash = keccak256(\n \"EIP712Domain(string name,string version,uint256 chainId,address verifyingContract)\"\n );\n _HASHED_NAME = hashedName;\n _HASHED_VERSION = hashedVersion;\n _CACHED_CHAIN_ID = block.chainid;\n _CACHED_DOMAIN_SEPARATOR = _buildDomainSeparator(typeHash, hashedName, hashedVersion);\n _CACHED_THIS = address(this);\n _TYPE_HASH = typeHash;\n }\n\n /**\n * @dev Returns the domain separator for the current chain.\n */\n function _domainSeparatorV4() internal view returns (bytes32) {\n if (address(this) == _CACHED_THIS && block.chainid == _CACHED_CHAIN_ID) {\n return _CACHED_DOMAIN_SEPARATOR;\n } else {\n return _buildDomainSeparator(_TYPE_HASH, _HASHED_NAME, _HASHED_VERSION);\n }\n }\n\n function _buildDomainSeparator(\n bytes32 typeHash,\n bytes32 nameHash,\n bytes32 versionHash\n ) private view returns (bytes32) {\n return keccak256(abi.encode(typeHash, nameHash, versionHash, block.chainid, address(this)));\n }\n\n /**\n * @dev Given an already https://eips.ethereum.org/EIPS/eip-712#definition-of-hashstruct[hashed struct], this\n * function returns the hash of the fully encoded EIP712 message for this domain.\n *\n * This hash can be used together with {ECDSA-recover} to obtain the signer of a message. For example:\n *\n * ```solidity\n * bytes32 digest = _hashTypedDataV4(keccak256(abi.encode(\n * keccak256(\"Mail(address to,string contents)\"),\n * mailTo,\n * keccak256(bytes(mailContents))\n * )));\n * address signer = ECDSA.recover(digest, signature);\n * ```\n */\n function _hashTypedDataV4(bytes32 structHash) internal view virtual returns (bytes32) {\n return ECDSA.toTypedDataHash(_domainSeparatorV4(), structHash);\n }\n}\n" + }, + "@openzeppelin/contracts/utils/cryptography/ECDSA.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (utils/cryptography/ECDSA.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../Strings.sol\";\n\n/**\n * @dev Elliptic Curve Digital Signature Algorithm (ECDSA) operations.\n *\n * These functions can be used to verify that a message was signed by the holder\n * of the private keys of a given address.\n */\nlibrary ECDSA {\n enum RecoverError {\n NoError,\n InvalidSignature,\n InvalidSignatureLength,\n InvalidSignatureS,\n InvalidSignatureV\n }\n\n function _throwError(RecoverError error) private pure {\n if (error == RecoverError.NoError) {\n return; // no error: do nothing\n } else if (error == RecoverError.InvalidSignature) {\n revert(\"ECDSA: invalid signature\");\n } else if (error == RecoverError.InvalidSignatureLength) {\n revert(\"ECDSA: invalid signature length\");\n } else if (error == RecoverError.InvalidSignatureS) {\n revert(\"ECDSA: invalid signature 's' value\");\n } else if (error == RecoverError.InvalidSignatureV) {\n revert(\"ECDSA: invalid signature 'v' value\");\n }\n }\n\n /**\n * @dev Returns the address that signed a hashed message (`hash`) with\n * `signature` or error string. This address can then be used for verification purposes.\n *\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\n * this function rejects them by requiring the `s` value to be in the lower\n * half order, and the `v` value to be either 27 or 28.\n *\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\n * verification to be secure: it is possible to craft signatures that\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\n * this is by receiving a hash of the original message (which may otherwise\n * be too long), and then calling {toEthSignedMessageHash} on it.\n *\n * Documentation for signature generation:\n * - with https://web3js.readthedocs.io/en/v1.3.4/web3-eth-accounts.html#sign[Web3.js]\n * - with https://docs.ethers.io/v5/api/signer/#Signer-signMessage[ethers]\n *\n * _Available since v4.3._\n */\n function tryRecover(bytes32 hash, bytes memory signature) internal pure returns (address, RecoverError) {\n // Check the signature length\n // - case 65: r,s,v signature (standard)\n // - case 64: r,vs signature (cf https://eips.ethereum.org/EIPS/eip-2098) _Available since v4.1._\n if (signature.length == 65) {\n bytes32 r;\n bytes32 s;\n uint8 v;\n // ecrecover takes the signature parameters, and the only way to get them\n // currently is to use assembly.\n /// @solidity memory-safe-assembly\n assembly {\n r := mload(add(signature, 0x20))\n s := mload(add(signature, 0x40))\n v := byte(0, mload(add(signature, 0x60)))\n }\n return tryRecover(hash, v, r, s);\n } else if (signature.length == 64) {\n bytes32 r;\n bytes32 vs;\n // ecrecover takes the signature parameters, and the only way to get them\n // currently is to use assembly.\n /// @solidity memory-safe-assembly\n assembly {\n r := mload(add(signature, 0x20))\n vs := mload(add(signature, 0x40))\n }\n return tryRecover(hash, r, vs);\n } else {\n return (address(0), RecoverError.InvalidSignatureLength);\n }\n }\n\n /**\n * @dev Returns the address that signed a hashed message (`hash`) with\n * `signature`. This address can then be used for verification purposes.\n *\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\n * this function rejects them by requiring the `s` value to be in the lower\n * half order, and the `v` value to be either 27 or 28.\n *\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\n * verification to be secure: it is possible to craft signatures that\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\n * this is by receiving a hash of the original message (which may otherwise\n * be too long), and then calling {toEthSignedMessageHash} on it.\n */\n function recover(bytes32 hash, bytes memory signature) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, signature);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Overload of {ECDSA-tryRecover} that receives the `r` and `vs` short-signature fields separately.\n *\n * See https://eips.ethereum.org/EIPS/eip-2098[EIP-2098 short signatures]\n *\n * _Available since v4.3._\n */\n function tryRecover(\n bytes32 hash,\n bytes32 r,\n bytes32 vs\n ) internal pure returns (address, RecoverError) {\n bytes32 s = vs & bytes32(0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff);\n uint8 v = uint8((uint256(vs) >> 255) + 27);\n return tryRecover(hash, v, r, s);\n }\n\n /**\n * @dev Overload of {ECDSA-recover} that receives the `r and `vs` short-signature fields separately.\n *\n * _Available since v4.2._\n */\n function recover(\n bytes32 hash,\n bytes32 r,\n bytes32 vs\n ) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, r, vs);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Overload of {ECDSA-tryRecover} that receives the `v`,\n * `r` and `s` signature fields separately.\n *\n * _Available since v4.3._\n */\n function tryRecover(\n bytes32 hash,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) internal pure returns (address, RecoverError) {\n // EIP-2 still allows signature malleability for ecrecover(). Remove this possibility and make the signature\n // unique. Appendix F in the Ethereum Yellow paper (https://ethereum.github.io/yellowpaper/paper.pdf), defines\n // the valid range for s in (301): 0 < s < secp256k1n ÷ 2 + 1, and for v in (302): v ∈ {27, 28}. Most\n // signatures from current libraries generate a unique signature with an s-value in the lower half order.\n //\n // If your library generates malleable signatures, such as s-values in the upper range, calculate a new s-value\n // with 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141 - s1 and flip v from 27 to 28 or\n // vice versa. If your library also generates signatures with 0/1 for v instead 27/28, add 27 to v to accept\n // these malleable signatures as well.\n if (uint256(s) > 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D576E7357A4501DDFE92F46681B20A0) {\n return (address(0), RecoverError.InvalidSignatureS);\n }\n if (v != 27 && v != 28) {\n return (address(0), RecoverError.InvalidSignatureV);\n }\n\n // If the signature is valid (and not malleable), return the signer address\n address signer = ecrecover(hash, v, r, s);\n if (signer == address(0)) {\n return (address(0), RecoverError.InvalidSignature);\n }\n\n return (signer, RecoverError.NoError);\n }\n\n /**\n * @dev Overload of {ECDSA-recover} that receives the `v`,\n * `r` and `s` signature fields separately.\n */\n function recover(\n bytes32 hash,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, v, r, s);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Returns an Ethereum Signed Message, created from a `hash`. This\n * produces hash corresponding to the one signed with the\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\n * JSON-RPC method as part of EIP-191.\n *\n * See {recover}.\n */\n function toEthSignedMessageHash(bytes32 hash) internal pure returns (bytes32) {\n // 32 is the length in bytes of hash,\n // enforced by the type signature above\n return keccak256(abi.encodePacked(\"\\x19Ethereum Signed Message:\\n32\", hash));\n }\n\n /**\n * @dev Returns an Ethereum Signed Message, created from `s`. This\n * produces hash corresponding to the one signed with the\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\n * JSON-RPC method as part of EIP-191.\n *\n * See {recover}.\n */\n function toEthSignedMessageHash(bytes memory s) internal pure returns (bytes32) {\n return keccak256(abi.encodePacked(\"\\x19Ethereum Signed Message:\\n\", Strings.toString(s.length), s));\n }\n\n /**\n * @dev Returns an Ethereum Signed Typed Data, created from a\n * `domainSeparator` and a `structHash`. This produces hash corresponding\n * to the one signed with the\n * https://eips.ethereum.org/EIPS/eip-712[`eth_signTypedData`]\n * JSON-RPC method as part of EIP-712.\n *\n * See {recover}.\n */\n function toTypedDataHash(bytes32 domainSeparator, bytes32 structHash) internal pure returns (bytes32) {\n return keccak256(abi.encodePacked(\"\\x19\\x01\", domainSeparator, structHash));\n }\n}\n" + }, + "@openzeppelin/contracts/utils/introspection/IERC165.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (utils/introspection/IERC165.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Interface of the ERC165 standard, as defined in the\n * https://eips.ethereum.org/EIPS/eip-165[EIP].\n *\n * Implementers can declare support of contract interfaces, which can then be\n * queried by others ({ERC165Checker}).\n *\n * For an implementation, see {ERC165}.\n */\ninterface IERC165 {\n /**\n * @dev Returns true if this contract implements the interface defined by\n * `interfaceId`. See the corresponding\n * https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified[EIP section]\n * to learn more about how these ids are created.\n *\n * This function call must use less than 30 000 gas.\n */\n function supportsInterface(bytes4 interfaceId) external view returns (bool);\n}\n" + }, + "@openzeppelin/contracts/utils/StorageSlot.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (utils/StorageSlot.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Library for reading and writing primitive types to specific storage slots.\n *\n * Storage slots are often used to avoid storage conflict when dealing with upgradeable contracts.\n * This library helps with reading and writing to such slots without the need for inline assembly.\n *\n * The functions in this library return Slot structs that contain a `value` member that can be used to read or write.\n *\n * Example usage to set ERC1967 implementation slot:\n * ```\n * contract ERC1967 {\n * bytes32 internal constant _IMPLEMENTATION_SLOT = 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc;\n *\n * function _getImplementation() internal view returns (address) {\n * return StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value;\n * }\n *\n * function _setImplementation(address newImplementation) internal {\n * require(Address.isContract(newImplementation), \"ERC1967: new implementation is not a contract\");\n * StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value = newImplementation;\n * }\n * }\n * ```\n *\n * _Available since v4.1 for `address`, `bool`, `bytes32`, and `uint256`._\n */\nlibrary StorageSlot {\n struct AddressSlot {\n address value;\n }\n\n struct BooleanSlot {\n bool value;\n }\n\n struct Bytes32Slot {\n bytes32 value;\n }\n\n struct Uint256Slot {\n uint256 value;\n }\n\n /**\n * @dev Returns an `AddressSlot` with member `value` located at `slot`.\n */\n function getAddressSlot(bytes32 slot) internal pure returns (AddressSlot storage r) {\n /// @solidity memory-safe-assembly\n assembly {\n r.slot := slot\n }\n }\n\n /**\n * @dev Returns an `BooleanSlot` with member `value` located at `slot`.\n */\n function getBooleanSlot(bytes32 slot) internal pure returns (BooleanSlot storage r) {\n /// @solidity memory-safe-assembly\n assembly {\n r.slot := slot\n }\n }\n\n /**\n * @dev Returns an `Bytes32Slot` with member `value` located at `slot`.\n */\n function getBytes32Slot(bytes32 slot) internal pure returns (Bytes32Slot storage r) {\n /// @solidity memory-safe-assembly\n assembly {\n r.slot := slot\n }\n }\n\n /**\n * @dev Returns an `Uint256Slot` with member `value` located at `slot`.\n */\n function getUint256Slot(bytes32 slot) internal pure returns (Uint256Slot storage r) {\n /// @solidity memory-safe-assembly\n assembly {\n r.slot := slot\n }\n }\n}\n" + }, + "@openzeppelin/contracts/utils/Strings.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (utils/Strings.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev String operations.\n */\nlibrary Strings {\n bytes16 private constant _HEX_SYMBOLS = \"0123456789abcdef\";\n uint8 private constant _ADDRESS_LENGTH = 20;\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` decimal representation.\n */\n function toString(uint256 value) internal pure returns (string memory) {\n // Inspired by OraclizeAPI's implementation - MIT licence\n // https://github.com/oraclize/ethereum-api/blob/b42146b063c7d6ee1358846c198246239e9360e8/oraclizeAPI_0.4.25.sol\n\n if (value == 0) {\n return \"0\";\n }\n uint256 temp = value;\n uint256 digits;\n while (temp != 0) {\n digits++;\n temp /= 10;\n }\n bytes memory buffer = new bytes(digits);\n while (value != 0) {\n digits -= 1;\n buffer[digits] = bytes1(uint8(48 + uint256(value % 10)));\n value /= 10;\n }\n return string(buffer);\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation.\n */\n function toHexString(uint256 value) internal pure returns (string memory) {\n if (value == 0) {\n return \"0x00\";\n }\n uint256 temp = value;\n uint256 length = 0;\n while (temp != 0) {\n length++;\n temp >>= 8;\n }\n return toHexString(value, length);\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length.\n */\n function toHexString(uint256 value, uint256 length) internal pure returns (string memory) {\n bytes memory buffer = new bytes(2 * length + 2);\n buffer[0] = \"0\";\n buffer[1] = \"x\";\n for (uint256 i = 2 * length + 1; i > 1; --i) {\n buffer[i] = _HEX_SYMBOLS[value & 0xf];\n value >>= 4;\n }\n require(value == 0, \"Strings: hex length insufficient\");\n return string(buffer);\n }\n\n /**\n * @dev Converts an `address` with fixed length of 20 bytes to its not checksummed ASCII `string` hexadecimal representation.\n */\n function toHexString(address addr) internal pure returns (string memory) {\n return toHexString(uint256(uint160(addr)), _ADDRESS_LENGTH);\n }\n}\n" + }, + "contracts/agToken/AgEUR.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\nimport \"../interfaces/IAgToken.sol\";\nimport \"../interfaces/coreModule/IStableMaster.sol\";\nimport \"../interfaces/ITreasury.sol\";\nimport \"@openzeppelin/contracts-upgradeable/token/ERC20/extensions/draft-ERC20PermitUpgradeable.sol\";\n\n/// @title AgEUR\n/// @author Angle Labs, Inc.\n/// @notice Base contract for agEUR, Angle's Euro stablecoin\n/// @dev This contract is an upgraded version of the agEUR contract that was first deployed on Ethereum mainnet\ncontract AgEUR is IAgToken, ERC20PermitUpgradeable {\n // ================================= REFERENCES ================================\n\n /// @notice Reference to the `StableMaster` contract associated to agEUR\n address public stableMaster;\n\n /// @custom:oz-upgrades-unsafe-allow constructor\n constructor() initializer {}\n\n // ============================== ADDED PARAMETERS =============================\n\n /// @inheritdoc IAgToken\n mapping(address => bool) public isMinter;\n /// @notice Reference to the treasury contract which can grant minting rights\n address public treasury;\n /// @notice Boolean used to check whether the contract had been reinitialized after an upgrade\n bool public treasuryInitialized;\n\n // =================================== EVENTS ==================================\n\n event TreasuryUpdated(address indexed _treasury);\n event MinterToggled(address indexed minter);\n\n // =================================== ERRORS ==================================\n\n error BurnAmountExceedsAllowance();\n error InvalidSender();\n error InvalidTreasury();\n error NotGovernor();\n error NotMinter();\n error NotTreasury();\n error TreasuryAlreadyInitialized();\n\n // ================================= MODIFIERS =================================\n\n /// @notice Checks to see if it is the `Treasury` calling this contract\n modifier onlyTreasury() {\n if (msg.sender != treasury) revert NotTreasury();\n _;\n }\n\n /// @notice Checks whether the sender has the minting right\n modifier onlyMinter() {\n if (!isMinter[msg.sender]) revert NotMinter();\n _;\n }\n\n // ============================= EXTERNAL FUNCTION =============================\n\n /// @notice Allows anyone to burn stablecoins\n /// @param amount Amount of stablecoins to burn\n /// @dev This function can typically be called if there is a settlement mechanism to burn stablecoins\n function burnStablecoin(uint256 amount) external {\n _burn(msg.sender, amount);\n }\n\n // ========================= MINTER ROLE ONLY FUNCTIONS ========================\n\n /// @inheritdoc IAgToken\n function burnSelf(uint256 amount, address burner) external onlyMinter {\n _burn(burner, amount);\n }\n\n /// @inheritdoc IAgToken\n function burnFrom(uint256 amount, address burner, address sender) external onlyMinter {\n if (burner != sender) {\n uint256 currentAllowance = allowance(burner, sender);\n if (currentAllowance < amount) revert BurnAmountExceedsAllowance();\n _approve(burner, sender, currentAllowance - amount);\n }\n _burn(burner, amount);\n }\n\n /// @inheritdoc IAgToken\n function mint(address account, uint256 amount) external onlyMinter {\n _mint(account, amount);\n }\n\n // ========================== TREASURY ONLY FUNCTIONS ==========================\n\n /// @inheritdoc IAgToken\n function addMinter(address minter) external onlyTreasury {\n isMinter[minter] = true;\n emit MinterToggled(minter);\n }\n\n /// @inheritdoc IAgToken\n function removeMinter(address minter) external {\n if (msg.sender != minter && msg.sender != address(treasury)) revert InvalidSender();\n isMinter[minter] = false;\n emit MinterToggled(minter);\n }\n\n /// @inheritdoc IAgToken\n function setTreasury(address _treasury) external onlyTreasury {\n treasury = _treasury;\n emit TreasuryUpdated(_treasury);\n }\n}\n" + }, + "contracts/agToken/AgToken.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\n/*\n * █ \n ***** ▓▓▓ \n * ▓▓▓▓▓▓▓ \n * ///. ▓▓▓▓▓▓▓▓▓▓▓▓▓ \n ***** //////// ▓▓▓▓▓▓▓ \n * ///////////// ▓▓▓ \n ▓▓ ////////////////// █ ▓▓ \n ▓▓ ▓▓ /////////////////////// ▓▓ ▓▓ \n ▓▓ ▓▓ //////////////////////////// ▓▓ ▓▓ \n ▓▓ ▓▓ /////////▓▓▓///////▓▓▓///////// ▓▓ ▓▓ \n ▓▓ ,////////////////////////////////////// ▓▓ ▓▓ \n ▓▓ ////////////////////////////////////////// ▓▓ \n ▓▓ //////////////////////▓▓▓▓///////////////////// \n ,//////////////////////////////////////////////////// \n .////////////////////////////////////////////////////////// \n .//////////////////////////██.,//////////////////////////█ \n .//////////////////////████..,./////////////////////██ \n ...////////////////███████.....,.////////////////███ \n ,.,////////////████████ ........,///////////████ \n .,.,//////█████████ ,.......///////████ \n ,..//████████ ........./████ \n ..,██████ .....,███ \n .██ ,.,█ \n \n \n \n ▓▓ ▓▓▓▓▓▓▓▓▓▓ ▓▓▓▓▓▓▓▓▓▓ ▓▓ ▓▓▓▓▓▓▓▓▓▓ \n ▓▓▓▓▓▓ ▓▓▓ ▓▓▓ ▓▓▓ ▓▓ ▓▓ ▓▓▓▓ \n ▓▓▓ ▓▓▓ ▓▓▓ ▓▓▓ ▓▓▓ ▓▓▓ ▓▓ ▓▓▓▓▓ \n ▓▓▓ ▓▓ ▓▓▓ ▓▓▓ ▓▓▓▓▓▓▓▓▓▓ ▓▓▓▓▓▓▓▓▓▓ ▓▓▓▓▓▓▓▓▓▓ \n*/\n\nimport \"../interfaces/IAgToken.sol\";\nimport \"../interfaces/ITreasury.sol\";\nimport \"@openzeppelin/contracts-upgradeable/token/ERC20/extensions/draft-ERC20PermitUpgradeable.sol\";\n\n/// @title AgToken\n/// @author Angle Labs, Inc.\n/// @notice Base contract for Angle agTokens on Ethereum and on other chains\n/// @dev By default, agTokens are ERC-20 tokens with 18 decimals\ncontract AgToken is IAgToken, ERC20PermitUpgradeable {\n // =========================== PARAMETERS / VARIABLES ==========================\n\n /// @inheritdoc IAgToken\n mapping(address => bool) public isMinter;\n /// @notice Reference to the treasury contract which can grant minting rights\n address public treasury;\n\n // =================================== EVENTS ==================================\n\n event TreasuryUpdated(address indexed _treasury);\n event MinterToggled(address indexed minter);\n\n // =================================== ERRORS ==================================\n\n error BurnAmountExceedsAllowance();\n error InvalidSender();\n error InvalidTreasury();\n error NotMinter();\n error NotTreasury();\n\n // ================================ CONSTRUCTOR ================================\n\n /// @custom:oz-upgrades-unsafe-allow constructor\n constructor() initializer {}\n\n /// @notice Initializes the `AgToken` contract\n function initialize(string memory name_, string memory symbol_, address _treasury) external {\n _initialize(name_, symbol_, _treasury);\n }\n\n /// @notice Initializes the contract\n function _initialize(string memory name_, string memory symbol_, address _treasury) internal virtual initializer {\n if (address(ITreasury(_treasury).stablecoin()) != address(this)) revert InvalidTreasury();\n __ERC20Permit_init(name_);\n __ERC20_init(name_, symbol_);\n treasury = _treasury;\n emit TreasuryUpdated(_treasury);\n }\n\n // ================================= MODIFIERS =================================\n\n /// @notice Checks to see if it is the `Treasury` calling this contract\n modifier onlyTreasury() {\n if (msg.sender != treasury) revert NotTreasury();\n _;\n }\n\n /// @notice Checks whether the sender has the minting right\n modifier onlyMinter() {\n if (!isMinter[msg.sender]) revert NotMinter();\n _;\n }\n\n // ============================= EXTERNAL FUNCTION =============================\n\n /// @notice Allows anyone to burn stablecoins\n /// @param amount Amount of stablecoins to burn\n /// @dev This function can typically be called if there is a settlement mechanism to burn stablecoins\n function burnStablecoin(uint256 amount) external {\n _burn(msg.sender, amount);\n }\n\n // ========================= MINTER ROLE ONLY FUNCTIONS ========================\n\n /// @inheritdoc IAgToken\n function burnSelf(uint256 amount, address burner) external onlyMinter {\n _burn(burner, amount);\n }\n\n /// @inheritdoc IAgToken\n function burnFrom(uint256 amount, address burner, address sender) external onlyMinter {\n if (burner != sender) {\n uint256 currentAllowance = allowance(burner, sender);\n if (currentAllowance < amount) revert BurnAmountExceedsAllowance();\n _approve(burner, sender, currentAllowance - amount);\n }\n _burn(burner, amount);\n }\n\n /// @inheritdoc IAgToken\n function mint(address account, uint256 amount) external onlyMinter {\n _mint(account, amount);\n }\n\n // ========================== GOVERNANCE ONLY FUNCTIONS ==========================\n\n /// @inheritdoc IAgToken\n function addMinter(address minter) external onlyTreasury {\n isMinter[minter] = true;\n emit MinterToggled(minter);\n }\n\n /// @inheritdoc IAgToken\n function removeMinter(address minter) external {\n if (msg.sender != address(treasury) && msg.sender != minter) revert InvalidSender();\n isMinter[minter] = false;\n emit MinterToggled(minter);\n }\n\n /// @inheritdoc IAgToken\n function setTreasury(address _treasury) external virtual onlyTreasury {\n treasury = _treasury;\n emit TreasuryUpdated(_treasury);\n }\n}\n" + }, + "contracts/agToken/AgTokenSideChainMultiBridge.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\nimport \"./AgToken.sol\";\nimport \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\nimport \"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\";\n\n/// @title AgTokenSideChainMultiBridge\n/// @author Angle Labs, Inc.\n/// @notice Contract for Angle agTokens on other chains than Ethereum mainnet\n/// @dev This contract supports bridge tokens having a minting right on the stablecoin (also referred to as the canonical\n/// or the native token)\ncontract AgTokenSideChainMultiBridge is AgToken {\n using SafeERC20 for IERC20;\n\n /// @notice Base used for fee computation\n uint256 public constant BASE_PARAMS = 1e9;\n\n // =============================== BRIDGING DATA ===============================\n\n /// @notice Struct with some data about a specific bridge token\n struct BridgeDetails {\n // Limit on the balance of bridge token held by the contract: it is designed\n // to reduce the exposure of the system to hacks\n uint256 limit;\n // Limit on the hourly volume of token minted through this bridge\n // Technically the limit over a rolling hour is hourlyLimit x2 as hourly limit\n // is enforced only between x:00 and x+1:00\n uint256 hourlyLimit;\n // Fee taken for swapping in and out the token\n uint64 fee;\n // Whether the associated token is allowed or not\n bool allowed;\n // Whether swapping in and out from the associated token is paused or not\n bool paused;\n }\n\n /// @notice Maps a bridge token to data\n mapping(address => BridgeDetails) public bridges;\n /// @notice List of all bridge tokens\n address[] public bridgeTokensList;\n /// @notice Maps a bridge token to the associated hourly volume\n mapping(address => mapping(uint256 => uint256)) public usage;\n /// @notice Maps an address to whether it is exempt of fees for when it comes to swapping in and out\n mapping(address => uint256) public isFeeExempt;\n /// @notice Limit to the amount of tokens that can be sent from that chain to another chain\n uint256 public chainTotalHourlyLimit;\n /// @notice Usage per hour on that chain. Maps an hourly timestamp to the total volume swapped out on the chain\n mapping(uint256 => uint256) public chainTotalUsage;\n\n // =================================== EVENTS ==================================\n\n event BridgeTokenAdded(address indexed bridgeToken, uint256 limit, uint256 hourlyLimit, uint64 fee, bool paused);\n event BridgeTokenToggled(address indexed bridgeToken, bool toggleStatus);\n event BridgeTokenRemoved(address indexed bridgeToken);\n event BridgeTokenFeeUpdated(address indexed bridgeToken, uint64 fee);\n event BridgeTokenLimitUpdated(address indexed bridgeToken, uint256 limit);\n event BridgeTokenHourlyLimitUpdated(address indexed bridgeToken, uint256 hourlyLimit);\n event HourlyLimitUpdated(uint256 hourlyLimit);\n event Recovered(address indexed token, address indexed to, uint256 amount);\n event FeeToggled(address indexed theAddress, uint256 toggleStatus);\n\n // =================================== ERRORS ==================================\n\n error AssetStillControlledInReserves();\n error HourlyLimitExceeded();\n error InvalidToken();\n error NotGovernor();\n error NotGovernorOrGuardian();\n error TooBigAmount();\n error TooHighParameterValue();\n error ZeroAddress();\n\n // ================================= MODIFIERS =================================\n\n /// @notice Checks whether the `msg.sender` has the governor role or not\n modifier onlyGovernor() {\n if (!ITreasury(treasury).isGovernor(msg.sender)) revert NotGovernor();\n _;\n }\n\n /// @notice Checks whether the `msg.sender` has the governor role or the guardian role\n modifier onlyGovernorOrGuardian() {\n if (!ITreasury(treasury).isGovernorOrGuardian(msg.sender)) revert NotGovernorOrGuardian();\n _;\n }\n\n // ===================== EXTERNAL PERMISSIONLESS FUNCTIONS =====================\n\n /// @notice Returns the list of all supported bridge tokens\n /// @dev Helpful for UIs\n function allBridgeTokens() external view returns (address[] memory) {\n return bridgeTokensList;\n }\n\n /// @notice Returns the current volume for a bridge, for the current hour\n /// @param bridgeToken Bridge used to mint\n /// @dev Helpful for UIs\n function currentUsage(address bridgeToken) external view returns (uint256) {\n return usage[bridgeToken][block.timestamp / 3600];\n }\n\n /// @notice Returns the current total volume on the chain for the current hour\n /// @dev Helpful for UIs\n function currentTotalUsage() external view returns (uint256) {\n return chainTotalUsage[block.timestamp / 3600];\n }\n\n /// @notice Mints the canonical token from a supported bridge token\n /// @param bridgeToken Bridge token to use to mint\n /// @param amount Amount of bridge tokens to send\n /// @param to Address to which the stablecoin should be sent\n /// @return Amount of the canonical stablecoin actually minted\n /// @dev Some fees may be taken by the protocol depending on the token used and on the address calling\n function swapIn(address bridgeToken, uint256 amount, address to) external returns (uint256) {\n BridgeDetails memory bridgeDetails = bridges[bridgeToken];\n if (!bridgeDetails.allowed || bridgeDetails.paused) revert InvalidToken();\n uint256 balance = IERC20(bridgeToken).balanceOf(address(this));\n if (balance + amount > bridgeDetails.limit) {\n // In case someone maliciously sends tokens to this contract\n // Or the limit changes\n if (bridgeDetails.limit > balance) amount = bridgeDetails.limit - balance;\n else {\n amount = 0;\n }\n }\n\n // Checking requirement on the hourly volume\n uint256 hour = block.timestamp / 3600;\n uint256 hourlyUsage = usage[bridgeToken][hour];\n if (hourlyUsage + amount > bridgeDetails.hourlyLimit) {\n // Edge case when the hourly limit changes\n amount = bridgeDetails.hourlyLimit > hourlyUsage ? bridgeDetails.hourlyLimit - hourlyUsage : 0;\n }\n usage[bridgeToken][hour] = hourlyUsage + amount;\n\n IERC20(bridgeToken).safeTransferFrom(msg.sender, address(this), amount);\n uint256 canonicalOut = amount;\n // Computing fees\n if (isFeeExempt[msg.sender] == 0) {\n canonicalOut -= (canonicalOut * bridgeDetails.fee) / BASE_PARAMS;\n }\n _mint(to, canonicalOut);\n return canonicalOut;\n }\n\n /// @notice Burns the canonical token in exchange for a bridge token\n /// @param bridgeToken Bridge token required\n /// @param amount Amount of canonical tokens to burn\n /// @param to Address to which the bridge token should be sent\n /// @return Amount of bridge tokens actually sent back\n /// @dev Some fees may be taken by the protocol depending on the token used and on the address calling\n function swapOut(address bridgeToken, uint256 amount, address to) external returns (uint256) {\n BridgeDetails memory bridgeDetails = bridges[bridgeToken];\n if (!bridgeDetails.allowed || bridgeDetails.paused) revert InvalidToken();\n\n uint256 hour = block.timestamp / 3600;\n uint256 hourlyUsage = chainTotalUsage[hour] + amount;\n // If the amount being swapped out exceeds the limit, we revert\n // We don't want to change the amount being swapped out.\n // The user can decide to send another tx with the correct amount to reach the limit\n if (hourlyUsage > chainTotalHourlyLimit) revert HourlyLimitExceeded();\n chainTotalUsage[hour] = hourlyUsage;\n\n _burn(msg.sender, amount);\n uint256 bridgeOut = amount;\n if (isFeeExempt[msg.sender] == 0) {\n bridgeOut -= (bridgeOut * bridgeDetails.fee) / BASE_PARAMS;\n }\n IERC20(bridgeToken).safeTransfer(to, bridgeOut);\n return bridgeOut;\n }\n\n // ============================ GOVERNANCE FUNCTIONS ===========================\n\n /// @notice Adds support for a bridge token\n /// @param bridgeToken Bridge token to add: it should be a version of the stablecoin from another bridge\n /// @param limit Limit on the balance of bridge token this contract could hold\n /// @param hourlyLimit Limit on the hourly volume for this bridge\n /// @param paused Whether swapping for this token should be paused or not\n /// @param fee Fee taken upon swapping for or against this token\n function addBridgeToken(\n address bridgeToken,\n uint256 limit,\n uint256 hourlyLimit,\n uint64 fee,\n bool paused\n ) external onlyGovernor {\n if (bridges[bridgeToken].allowed || bridgeToken == address(0)) revert InvalidToken();\n if (fee > BASE_PARAMS) revert TooHighParameterValue();\n BridgeDetails memory _bridge;\n _bridge.limit = limit;\n _bridge.hourlyLimit = hourlyLimit;\n _bridge.paused = paused;\n _bridge.fee = fee;\n _bridge.allowed = true;\n bridges[bridgeToken] = _bridge;\n bridgeTokensList.push(bridgeToken);\n emit BridgeTokenAdded(bridgeToken, limit, hourlyLimit, fee, paused);\n }\n\n /// @notice Removes support for a token\n /// @param bridgeToken Address of the bridge token to remove support for\n function removeBridgeToken(address bridgeToken) external onlyGovernor {\n if (IERC20(bridgeToken).balanceOf(address(this)) != 0) revert AssetStillControlledInReserves();\n delete bridges[bridgeToken];\n // Deletion from `bridgeTokensList` loop\n uint256 bridgeTokensListLength = bridgeTokensList.length;\n for (uint256 i; i < bridgeTokensListLength - 1; ++i) {\n if (bridgeTokensList[i] == bridgeToken) {\n // Replace the `bridgeToken` to remove with the last of the list\n bridgeTokensList[i] = bridgeTokensList[bridgeTokensListLength - 1];\n break;\n }\n }\n // Remove last element in array\n bridgeTokensList.pop();\n emit BridgeTokenRemoved(bridgeToken);\n }\n\n /// @notice Recovers any ERC20 token\n /// @dev Can be used to withdraw bridge tokens for them to be de-bridged on mainnet\n function recoverERC20(address tokenAddress, address to, uint256 amountToRecover) external onlyGovernor {\n IERC20(tokenAddress).safeTransfer(to, amountToRecover);\n emit Recovered(tokenAddress, to, amountToRecover);\n }\n\n /// @notice Updates the `limit` amount for `bridgeToken`\n function setLimit(address bridgeToken, uint256 limit) external onlyGovernorOrGuardian {\n if (!bridges[bridgeToken].allowed) revert InvalidToken();\n bridges[bridgeToken].limit = limit;\n emit BridgeTokenLimitUpdated(bridgeToken, limit);\n }\n\n /// @notice Updates the `hourlyLimit` amount for `bridgeToken`\n function setHourlyLimit(address bridgeToken, uint256 hourlyLimit) external onlyGovernorOrGuardian {\n if (!bridges[bridgeToken].allowed) revert InvalidToken();\n bridges[bridgeToken].hourlyLimit = hourlyLimit;\n emit BridgeTokenHourlyLimitUpdated(bridgeToken, hourlyLimit);\n }\n\n /// @notice Updates the `chainTotalHourlyLimit` amount\n function setChainTotalHourlyLimit(uint256 hourlyLimit) external onlyGovernorOrGuardian {\n chainTotalHourlyLimit = hourlyLimit;\n emit HourlyLimitUpdated(hourlyLimit);\n }\n\n /// @notice Updates the `fee` value for `bridgeToken`\n function setSwapFee(address bridgeToken, uint64 fee) external onlyGovernorOrGuardian {\n if (!bridges[bridgeToken].allowed) revert InvalidToken();\n if (fee > BASE_PARAMS) revert TooHighParameterValue();\n bridges[bridgeToken].fee = fee;\n emit BridgeTokenFeeUpdated(bridgeToken, fee);\n }\n\n /// @notice Pauses or unpauses swapping in and out for a token\n function toggleBridge(address bridgeToken) external onlyGovernorOrGuardian {\n if (!bridges[bridgeToken].allowed) revert InvalidToken();\n bool pausedStatus = bridges[bridgeToken].paused;\n bridges[bridgeToken].paused = !pausedStatus;\n emit BridgeTokenToggled(bridgeToken, !pausedStatus);\n }\n\n /// @notice Toggles fees for the address `theAddress`\n function toggleFeesForAddress(address theAddress) external onlyGovernorOrGuardian {\n uint256 feeExemptStatus = 1 - isFeeExempt[theAddress];\n isFeeExempt[theAddress] = feeExemptStatus;\n emit FeeToggled(theAddress, feeExemptStatus);\n }\n}\n" + }, + "contracts/agToken/layerZero/LayerZeroBridge.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.12;\n\nimport \"./utils/OFTCore.sol\";\nimport \"@openzeppelin/contracts-upgradeable/security/PausableUpgradeable.sol\";\nimport \"@openzeppelin/contracts/token/ERC20/extensions/draft-IERC20Permit.sol\";\n\n/// @title LayerZeroBridge\n/// @author Angle Labs, Inc., forked from https://github.com/LayerZero-Labs/solidity-examples/blob/main/contracts/token/oft/OFT.sol\n/// @notice Contract to be deployed on Ethereum for bridging an AgToken using a bridge intermediate token and LayerZero\ncontract LayerZeroBridge is OFTCore, PausableUpgradeable {\n /// @notice Name of the contract for indexing purposes\n string public name;\n\n /// @notice Address of the bridgeable token\n /// @dev Immutable\n IERC20 public canonicalToken;\n\n /// @notice Maps an address to the amount of token bridged but not received\n mapping(address => uint256) public balanceOf;\n\n // ================================ CONSTRUCTOR ================================\n /// @notice Initializes the contract\n /// @param _name Name of the token corresponding to this contract\n /// @param _lzEndpoint Layer zero endpoint to pass messages\n /// @param _treasury Address of the treasury contract used for access control\n function initialize(string memory _name, address _lzEndpoint, address _treasury) external initializer {\n __LzAppUpgradeable_init(_lzEndpoint, _treasury);\n name = _name;\n canonicalToken = IERC20(address(ITreasury(_treasury).stablecoin()));\n }\n\n /// @custom:oz-upgrades-unsafe-allow constructor\n constructor() initializer {}\n\n // ===================== EXTERNAL PERMISSIONLESS FUNCTIONS =====================\n\n /// @inheritdoc OFTCore\n function sendWithPermit(\n uint16 _dstChainId,\n bytes memory _toAddress,\n uint256 _amount,\n address payable _refundAddress,\n address _zroPaymentAddress,\n bytes memory _adapterParams,\n uint256 deadline,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) public payable override {\n IERC20Permit(address(canonicalToken)).permit(msg.sender, address(this), _amount, deadline, v, r, s);\n send(_dstChainId, _toAddress, _amount, _refundAddress, _zroPaymentAddress, _adapterParams);\n }\n\n /// @inheritdoc OFTCore\n function withdraw(uint256 amount, address recipient) external override returns (uint256) {\n return _withdraw(amount, msg.sender, recipient);\n }\n\n /// @notice Withdraws amount of `token` from the contract and sends it to the recipient\n /// @param amount Amount to withdraw\n /// @param recipient Address to withdraw for\n /// @return The amount of canonical token sent\n function withdrawFor(uint256 amount, address recipient) external returns (uint256) {\n return _withdraw(amount, recipient, recipient);\n }\n\n // ============================= INTERNAL FUNCTIONS ============================\n\n /// @notice Withdraws `amount` from the balance of the `from` address and sends these tokens to the `to` address\n /// @dev It's important to make sure that `from` is either the `msg.sender` or that `from` and `to` are the same\n /// addresses\n function _withdraw(uint256 amount, address from, address to) internal whenNotPaused returns (uint256) {\n balanceOf[from] -= amount; // Will overflow if the amount is too big\n canonicalToken.transfer(to, amount);\n return amount;\n }\n\n /// @inheritdoc OFTCore\n function _debitFrom(uint16, bytes memory, uint256 _amount) internal override whenNotPaused returns (uint256) {\n // No need to use safeTransferFrom as we know this implementation reverts on failure\n canonicalToken.transferFrom(msg.sender, address(this), _amount);\n return _amount;\n }\n\n /// @inheritdoc OFTCore\n function _debitCreditFrom(uint16, bytes memory, uint256 _amount) internal override whenNotPaused returns (uint256) {\n balanceOf[msg.sender] -= _amount;\n return _amount;\n }\n\n /// @inheritdoc OFTCore\n function _creditTo(uint16, address _toAddress, uint256 _amount) internal override whenNotPaused returns (uint256) {\n // Should never revert as all the LayerZero bridge tokens come from\n // this contract\n uint256 balance = canonicalToken.balanceOf(address(this));\n if (balance < _amount) {\n balanceOf[_toAddress] = _amount - balance;\n if (balance != 0) canonicalToken.transfer(_toAddress, balance);\n } else {\n canonicalToken.transfer(_toAddress, _amount);\n }\n return _amount;\n }\n\n // =============================== VIEW FUNCTIONS ==============================\n\n /// @inheritdoc ERC165Upgradeable\n function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {\n return interfaceId == type(IOFTCore).interfaceId || super.supportsInterface(interfaceId);\n }\n\n // ============================ GOVERNANCE FUNCTIONS ===========================\n\n /// @notice Pauses bridging through the contract\n /// @param pause Future pause status\n function pauseSendTokens(bool pause) external onlyGovernorOrGuardian {\n pause ? _pause() : _unpause();\n }\n\n /// @notice Decreases the balance of an address\n /// @param amount Amount to withdraw from balance\n /// @param recipient Address to withdraw from\n function sweep(uint256 amount, address recipient) external onlyGovernorOrGuardian {\n balanceOf[recipient] -= amount; // Will overflow if the amount is too big\n }\n\n uint256[47] private __gap;\n}\n" + }, + "contracts/agToken/layerZero/LayerZeroBridgeToken.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.12;\n\nimport \"./utils/OFTCore.sol\";\nimport \"../../interfaces/IAgTokenSideChainMultiBridge.sol\";\nimport \"@openzeppelin/contracts-upgradeable/security/PausableUpgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/token/ERC20/ERC20Upgradeable.sol\";\n\n/// @title LayerZeroBridgeToken\n/// @author Angle Labs, Inc., forked from https://github.com/LayerZero-Labs/solidity-examples/blob/main/contracts/token/oft/OFT.sol\n/// @notice Contract to be deployed on a L2/sidechain for bridging an AgToken using a bridge intermediate token and LayerZero\ncontract LayerZeroBridgeToken is OFTCore, ERC20Upgradeable, PausableUpgradeable {\n /// @notice Address of the bridgeable token\n /// @dev Immutable\n IAgTokenSideChainMultiBridge public canonicalToken;\n\n // =================================== ERROR ===================================\n\n error InvalidAllowance();\n\n // ================================ CONSTRUCTOR ================================\n\n /// @notice Initializes the contract\n /// @param _name Name of the token corresponding to this contract\n /// @param _symbol Symbol of the token corresponding to this contract\n /// @param _lzEndpoint Layer zero endpoint to pass messages\n /// @param _treasury Address of the treasury contract used for access control\n /// @param initialSupply Initial supply to mint to the canonical token address\n /// @dev The initial supply corresponds to the initial amount that could be bridged using this OFT\n function initialize(\n string memory _name,\n string memory _symbol,\n address _lzEndpoint,\n address _treasury,\n uint256 initialSupply\n ) external initializer {\n __ERC20_init_unchained(_name, _symbol);\n __LzAppUpgradeable_init(_lzEndpoint, _treasury);\n\n canonicalToken = IAgTokenSideChainMultiBridge(address(ITreasury(_treasury).stablecoin()));\n _approve(address(this), address(canonicalToken), type(uint256).max);\n _mint(address(canonicalToken), initialSupply);\n }\n\n /// @custom:oz-upgrades-unsafe-allow constructor\n constructor() initializer {}\n\n // ===================== EXTERNAL PERMISSIONLESS FUNCTIONS =====================\n\n /// @inheritdoc OFTCore\n function sendWithPermit(\n uint16 _dstChainId,\n bytes memory _toAddress,\n uint256 _amount,\n address payable _refundAddress,\n address _zroPaymentAddress,\n bytes memory _adapterParams,\n uint256 deadline,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) public payable override {\n canonicalToken.permit(msg.sender, address(this), _amount, deadline, v, r, s);\n send(_dstChainId, _toAddress, _amount, _refundAddress, _zroPaymentAddress, _adapterParams);\n }\n\n /// @inheritdoc OFTCore\n function withdraw(uint256 amount, address recipient) external override returns (uint256 amountMinted) {\n // Does not check allowances as transfers from `msg.sender`\n _transfer(msg.sender, address(this), amount);\n amountMinted = canonicalToken.swapIn(address(this), amount, recipient);\n uint256 leftover = balanceOf(address(this));\n if (leftover != 0) {\n _transfer(address(this), msg.sender, leftover);\n }\n }\n\n // ============================= INTERNAL FUNCTIONS ============================\n\n /// @inheritdoc OFTCore\n function _debitFrom(\n uint16,\n bytes memory,\n uint256 _amount\n ) internal override whenNotPaused returns (uint256 amountSwapped) {\n // No need to use safeTransferFrom as we know this implementation reverts on failure\n canonicalToken.transferFrom(msg.sender, address(this), _amount);\n\n // Swap canonical for this bridge token. There may be some fees\n amountSwapped = canonicalToken.swapOut(address(this), _amount, address(this));\n _burn(address(this), amountSwapped);\n }\n\n /// @inheritdoc OFTCore\n function _debitCreditFrom(uint16, bytes memory, uint256 _amount) internal override whenNotPaused returns (uint256) {\n _burn(msg.sender, _amount);\n return _amount;\n }\n\n /// @inheritdoc OFTCore\n function _creditTo(\n uint16,\n address _toAddress,\n uint256 _amount\n ) internal override whenNotPaused returns (uint256 amountMinted) {\n _mint(address(this), _amount);\n amountMinted = canonicalToken.swapIn(address(this), _amount, _toAddress);\n uint256 leftover = balanceOf(address(this));\n if (leftover != 0) {\n _transfer(address(this), _toAddress, leftover);\n }\n }\n\n // =============================== VIEW FUNCTIONS ==============================\n\n /// @inheritdoc ERC165Upgradeable\n function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {\n return\n interfaceId == type(IOFT).interfaceId ||\n interfaceId == type(IERC20).interfaceId ||\n super.supportsInterface(interfaceId);\n }\n\n // ============================ GOVERNANCE FUNCTIONS ===========================\n\n /// @notice Mints the intermediate contract to the `canonicalToken`\n /// @dev Used to increase the bridging capacity\n function mint(uint256 amount) external onlyGovernorOrGuardian {\n _mint(address(canonicalToken), amount);\n }\n\n /// @notice Burns the intermediate contract from the `canonicalToken`\n /// @dev Used to decrease the bridging capacity\n function burn(uint256 amount) external onlyGovernorOrGuardian {\n _burn(address(canonicalToken), amount);\n }\n\n /// @notice Increases allowance of the `canonicalToken`\n function setupAllowance() public onlyGovernorOrGuardian {\n _approve(address(this), address(canonicalToken), type(uint256).max);\n }\n\n /// @notice Pauses bridging through the contract\n /// @param pause Future pause status\n function pauseSendTokens(bool pause) external onlyGovernorOrGuardian {\n pause ? _pause() : _unpause();\n }\n\n uint256[49] private __gap;\n}\n" + }, + "contracts/agToken/layerZero/utils/IOFTCore.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.12;\n\nimport \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\nimport \"@openzeppelin/contracts/utils/introspection/IERC165.sol\";\n\n/**\n * @dev Interface of the IOFT core standard\n * @dev Forked from https://github.com/LayerZero-Labs/solidity-examples/blob/main/contracts/token/oft/IOFTCore.sol\n */\ninterface IOFTCore is IERC165 {\n /// @notice Estimates send token `_tokenId` to (`_dstChainId`, `_toAddress`)\n /// @param _dstChainId L0 defined chain id to send tokens too\n /// @param _toAddress dynamic bytes array which contains the address to whom you are sending tokens to on the dstChain\n /// @param _amount amount of the tokens to transfer\n /// @param _useZro indicates to use zro to pay L0 fees\n /// @param _adapterParams flexible bytes array to indicate messaging adapter services in L0\n function estimateSendFee(\n uint16 _dstChainId,\n bytes calldata _toAddress,\n uint256 _amount,\n bool _useZro,\n bytes calldata _adapterParams\n ) external view returns (uint256 nativeFee, uint256 zroFee);\n\n /// @notice Sends `_amount` amount of token to (`_dstChainId`, `_toAddress`)\n /// @param _dstChainId the destination chain identifier\n /// @param _toAddress can be any size depending on the `dstChainId`.\n /// @param _amount the quantity of tokens in wei\n /// @param _refundAddress the address LayerZero refunds if too much message fee is sent\n /// @param _zroPaymentAddress set to address(0x0) if not paying in ZRO (LayerZero Token)\n /// @param _adapterParams is a flexible bytes array to indicate messaging adapter services\n function send(\n uint16 _dstChainId,\n bytes calldata _toAddress,\n uint256 _amount,\n address payable _refundAddress,\n address _zroPaymentAddress,\n bytes calldata _adapterParams\n ) external payable;\n\n /// @notice Sends `_amount` amount of credit to (`_dstChainId`, `_toAddress`)\n /// @param _dstChainId the destination chain identifier\n /// @param _toAddress can be any size depending on the `dstChainId`.\n /// @param _amount the quantity of credit to send in wei\n /// @param _refundAddress the address LayerZero refunds if too much message fee is sent\n /// @param _zroPaymentAddress set to address(0x0) if not paying in ZRO (LayerZero Token)\n /// @param _adapterParams is a flexible bytes array to indicate messaging adapter services\n function sendCredit(\n uint16 _dstChainId,\n bytes calldata _toAddress,\n uint256 _amount,\n address payable _refundAddress,\n address _zroPaymentAddress,\n bytes calldata _adapterParams\n ) external payable;\n\n /// @notice Sends `_amount` amount of token to (`_dstChainId`, `_toAddress`)\n /// @param _dstChainId The destination chain identifier\n /// @param _toAddress Can be any size depending on the `dstChainId`.\n /// @param _amount Quantity of tokens in wei\n /// @param _refundAddress Address LayerZero refunds if too much message fee is sent\n /// @param _zroPaymentAddress Set to address(0x0) if not paying in ZRO (LayerZero Token)\n /// @param _adapterParams Flexible bytes array to indicate messaging adapter services\n /// @param deadline Deadline parameter for the signature to be valid\n /// @dev The `v`, `r`, and `s` parameters are used as signature data\n function sendWithPermit(\n uint16 _dstChainId,\n bytes memory _toAddress,\n uint256 _amount,\n address payable _refundAddress,\n address _zroPaymentAddress,\n bytes memory _adapterParams,\n uint256 deadline,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) external payable;\n\n /// @notice Withdraws amount of canonical token from the `msg.sender` balance and sends it to the recipient\n /// @param amount Amount to withdraw\n /// @param recipient Address to send the canonical token to\n /// @return The amount of canonical token sent\n function withdraw(uint256 amount, address recipient) external returns (uint256);\n\n /// @dev Emitted when `_amount` tokens are moved from the `_sender` to (`_dstChainId`, `_toAddress`)\n /// `_nonce` is the outbound nonce\n event SendToChain(\n address indexed _sender,\n uint16 indexed _dstChainId,\n bytes indexed _toAddress,\n uint256 _amount,\n uint64 _nonce\n );\n\n /// @dev Emitted when `_amount` tokens are received from `_srcChainId` into the `_toAddress` on the local chain.\n /// `_nonce` is the inbound nonce.\n event ReceiveFromChain(\n uint16 indexed _srcChainId,\n bytes indexed _srcAddress,\n address indexed _toAddress,\n uint256 _amount,\n uint64 _nonce\n );\n}\n\n/// @dev Interface of the OFT standard\ninterface IOFT is IOFTCore, IERC20 {\n\n}\n" + }, + "contracts/agToken/layerZero/utils/NonblockingLzApp.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.12;\n\nimport \"@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol\";\nimport \"../../../interfaces/external/layerZero/ILayerZeroReceiver.sol\";\nimport \"../../../interfaces/external/layerZero/ILayerZeroUserApplicationConfig.sol\";\nimport \"../../../interfaces/external/layerZero/ILayerZeroEndpoint.sol\";\nimport \"../../../interfaces/ITreasury.sol\";\n\n/// @title NonblockingLzApp\n/// @author Angle Labs, Inc., forked from https://github.com/LayerZero-Labs/solidity-examples/\n/// @notice Base contract for bridging using LayerZero\nabstract contract NonblockingLzApp is Initializable, ILayerZeroReceiver, ILayerZeroUserApplicationConfig {\n /// @notice Layer Zero endpoint\n ILayerZeroEndpoint public lzEndpoint;\n\n /// @notice Maps chainIds to failed messages to retry them\n mapping(uint16 => mapping(bytes => mapping(uint64 => bytes32))) public failedMessages;\n\n /// @notice Maps chainIds to their OFT address\n mapping(uint16 => bytes) public trustedRemoteLookup;\n\n /// @notice Reference to the treasury contract to fetch access control\n address public treasury;\n\n /// @notice Maps pairs of (`to` chain, `packetType`) to the minimum amount of gas needed on the destination chain\n mapping(uint16 => mapping(uint16 => uint256)) public minDstGasLookup;\n\n /// @notice For future LayerZero compatibility\n address public precrime;\n\n // ================================== Events ===================================\n\n event SetTrustedRemote(uint16 _srcChainId, bytes _srcAddress);\n event MessageFailed(uint16 _srcChainId, bytes _srcAddress, uint64 _nonce, bytes _payload);\n\n // =============================== Errors ================================\n\n error NotGovernor();\n error NotGovernorOrGuardian();\n error InsufficientGas();\n error InvalidEndpoint();\n error InvalidSource();\n error InvalidCaller();\n error InvalidParams();\n error InvalidPayload();\n error ZeroAddress();\n\n // ============================= Constructor ===================================\n\n //solhint-disable-next-line\n function __LzAppUpgradeable_init(address _endpoint, address _treasury) internal {\n if (_endpoint == address(0) || _treasury == address(0)) revert ZeroAddress();\n lzEndpoint = ILayerZeroEndpoint(_endpoint);\n treasury = _treasury;\n }\n\n // =============================== Modifiers ===================================\n\n /// @notice Checks whether the `msg.sender` has the governor role or the guardian role\n modifier onlyGovernorOrGuardian() {\n if (!ITreasury(treasury).isGovernorOrGuardian(msg.sender)) revert NotGovernorOrGuardian();\n _;\n }\n\n // ==================== External Permissionless Functions ======================\n\n /// @notice Receives a message from the LZ endpoint and process it\n /// @param _srcChainId ChainId of the source chain - LayerZero standard\n /// @param _srcAddress Sender of the source chain\n /// @param _nonce Nounce of the message\n /// @param _payload Data: recipient address and amount\n function lzReceive(\n uint16 _srcChainId,\n bytes memory _srcAddress,\n uint64 _nonce,\n bytes memory _payload\n ) public virtual override {\n // lzReceive must be called by the endpoint for security\n if (msg.sender != address(lzEndpoint)) revert InvalidEndpoint();\n\n bytes memory trustedRemote = trustedRemoteLookup[_srcChainId];\n // if will still block the message pathway from (srcChainId, srcAddress). should not receive message from untrusted remote.\n if (_srcAddress.length != trustedRemote.length || keccak256(_srcAddress) != keccak256(trustedRemote))\n revert InvalidSource();\n\n _blockingLzReceive(_srcChainId, _srcAddress, _nonce, _payload);\n }\n\n /// @notice Retries a message that previously failed and was stored\n /// @param _srcChainId ChainId of the source chain - LayerZero standard\n /// @param _srcAddress Sender of the source chain\n /// @param _nonce Nounce of the message\n /// @param _payload Data: recipient address and amount\n function retryMessage(\n uint16 _srcChainId,\n bytes memory _srcAddress,\n uint64 _nonce,\n bytes memory _payload\n ) public payable virtual {\n // assert there is message to retry\n bytes32 payloadHash = failedMessages[_srcChainId][_srcAddress][_nonce];\n if (payloadHash == bytes32(0) || keccak256(_payload) != payloadHash) revert InvalidPayload();\n // clear the stored message\n failedMessages[_srcChainId][_srcAddress][_nonce] = bytes32(0);\n // execute the message. revert if it fails again\n _nonblockingLzReceive(_srcChainId, _srcAddress, _nonce, _payload);\n }\n\n // ============================= Internal Functions ===================================\n\n /// @notice Handles message receptions in a non blocking way\n /// @param _srcChainId ChainId of the source chain - LayerZero standard\n /// @param _srcAddress Sender of the source chain\n /// @param _nonce Nounce of the message\n /// @param _payload Data: recipient address and amount\n /// @dev public for the needs of try / catch but effectively internal\n function nonblockingLzReceive(\n uint16 _srcChainId,\n bytes memory _srcAddress,\n uint64 _nonce,\n bytes memory _payload\n ) public virtual {\n // only internal transaction\n if (msg.sender != address(this)) revert InvalidCaller();\n _nonblockingLzReceive(_srcChainId, _srcAddress, _nonce, _payload);\n }\n\n /// @notice Handles message receptions in a non blocking way\n /// @param _srcChainId ChainId of the source chain - LayerZero standard\n /// @param _srcAddress Sender of the source chain\n /// @param _nonce Nounce of the message\n /// @param _payload Data: recipient address and amount\n function _nonblockingLzReceive(\n uint16 _srcChainId,\n bytes memory _srcAddress,\n uint64 _nonce,\n bytes memory _payload\n ) internal virtual;\n\n /// @notice Handles message receptions in a blocking way\n /// @param _srcChainId ChainId of the source chain - LayerZero standard\n /// @param _srcAddress Sender of the source chain\n /// @param _nonce Nounce of the message\n /// @param _payload Data: recipient address and amount\n function _blockingLzReceive(\n uint16 _srcChainId,\n bytes memory _srcAddress,\n uint64 _nonce,\n bytes memory _payload\n ) internal {\n // try-catch all errors/exceptions\n try this.nonblockingLzReceive(_srcChainId, _srcAddress, _nonce, _payload) {\n // do nothing\n } catch {\n // error / exception\n failedMessages[_srcChainId][_srcAddress][_nonce] = keccak256(_payload);\n emit MessageFailed(_srcChainId, _srcAddress, _nonce, _payload);\n }\n }\n\n /// @notice Sends a message to the LZ endpoint and process it\n /// @param _dstChainId L0 defined chain id to send tokens too\n /// @param _payload Data: recipient address and amount\n /// @param _refundAddress Address LayerZero refunds if too much message fee is sent\n /// @param _zroPaymentAddress Set to address(0x0) if not paying in ZRO (LayerZero Token)\n /// @param _adapterParams Flexible bytes array to indicate messaging adapter services in L0\n function _lzSend(\n uint16 _dstChainId,\n bytes memory _payload,\n address payable _refundAddress,\n address _zroPaymentAddress,\n bytes memory _adapterParams\n ) internal virtual {\n bytes memory trustedRemote = trustedRemoteLookup[_dstChainId];\n if (trustedRemote.length == 0) revert InvalidSource();\n //solhint-disable-next-line\n lzEndpoint.send{ value: msg.value }(\n _dstChainId,\n trustedRemote,\n _payload,\n _refundAddress,\n _zroPaymentAddress,\n _adapterParams\n );\n }\n\n /// @notice Checks the gas limit of a given transaction\n function _checkGasLimit(\n uint16 _dstChainId,\n uint16 _type,\n bytes memory _adapterParams,\n uint256 _extraGas\n ) internal view virtual {\n uint256 minGasLimit = minDstGasLookup[_dstChainId][_type] + _extraGas;\n if (minGasLimit == 0 || minGasLimit > _getGasLimit(_adapterParams)) revert InsufficientGas();\n }\n\n /// @notice Gets the gas limit from the `_adapterParams` parameter\n function _getGasLimit(bytes memory _adapterParams) internal pure virtual returns (uint256 gasLimit) {\n if (_adapterParams.length < 34) revert InvalidParams();\n // solhint-disable-next-line\n assembly {\n gasLimit := mload(add(_adapterParams, 34))\n }\n }\n\n // ======================= Governance Functions ================================\n\n /// @notice Sets the corresponding address on an other chain.\n /// @param _srcChainId ChainId of the source chain - LayerZero standard\n /// @param _srcAddress Address on the source chain\n /// @dev Used for both receiving and sending message\n /// @dev There can only be one trusted source per chain\n /// @dev Allows owner to set it multiple times.\n function setTrustedRemote(uint16 _srcChainId, bytes calldata _srcAddress) external onlyGovernorOrGuardian {\n trustedRemoteLookup[_srcChainId] = _srcAddress;\n emit SetTrustedRemote(_srcChainId, _srcAddress);\n }\n\n /// @notice Fetches the default LZ config\n function getConfig(\n uint16 _version,\n uint16 _chainId,\n address,\n uint256 _configType\n ) external view returns (bytes memory) {\n return lzEndpoint.getConfig(_version, _chainId, address(this), _configType);\n }\n\n /// @notice Overrides the default LZ config\n function setConfig(\n uint16 _version,\n uint16 _chainId,\n uint256 _configType,\n bytes calldata _config\n ) external override onlyGovernorOrGuardian {\n lzEndpoint.setConfig(_version, _chainId, _configType, _config);\n }\n\n /// @notice Overrides the default LZ config\n function setSendVersion(uint16 _version) external override onlyGovernorOrGuardian {\n lzEndpoint.setSendVersion(_version);\n }\n\n /// @notice Overrides the default LZ config\n function setReceiveVersion(uint16 _version) external override onlyGovernorOrGuardian {\n lzEndpoint.setReceiveVersion(_version);\n }\n\n /// @notice Unpauses the receive functionalities\n function forceResumeReceive(\n uint16 _srcChainId,\n bytes calldata _srcAddress\n ) external override onlyGovernorOrGuardian {\n lzEndpoint.forceResumeReceive(_srcChainId, _srcAddress);\n }\n\n /// @notice Sets the minimum gas parameter for a packet type on a given chain\n function setMinDstGas(uint16 _dstChainId, uint16 _packetType, uint256 _minGas) external onlyGovernorOrGuardian {\n if (_minGas == 0) revert InvalidParams();\n minDstGasLookup[_dstChainId][_packetType] = _minGas;\n }\n\n /// @notice Sets the precrime variable\n function setPrecrime(address _precrime) external onlyGovernorOrGuardian {\n precrime = _precrime;\n }\n\n // ======================= View Functions ================================\n\n /// @notice Checks if the `_srcAddress` corresponds to the trusted source\n function isTrustedRemote(uint16 _srcChainId, bytes calldata _srcAddress) external view returns (bool) {\n bytes memory trustedSource = trustedRemoteLookup[_srcChainId];\n return keccak256(trustedSource) == keccak256(_srcAddress);\n }\n\n uint256[44] private __gap;\n}\n" + }, + "contracts/agToken/layerZero/utils/OFTCore.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.12;\n\nimport \"./NonblockingLzApp.sol\";\nimport \"./IOFTCore.sol\";\nimport \"@openzeppelin/contracts-upgradeable/utils/introspection/ERC165Upgradeable.sol\";\n\n/// @title OFTCore\n/// @author Forked from https://github.com/LayerZero-Labs/solidity-examples/blob/main/contracts/token/oft/OFTCore.sol\n/// but with slight modifications from the Angle Labs, Inc. which added return values to the `_creditTo` and `_debitFrom` functions\n/// @notice Base contract for bridging using LayerZero\nabstract contract OFTCore is NonblockingLzApp, ERC165Upgradeable, IOFTCore {\n /// @notice Amount of additional gas specified\n uint256 public constant EXTRA_GAS = 200000;\n /// @notice Packet type for token transfer\n uint16 public constant PT_SEND = 0;\n\n /// @notice Whether to use custom parameters in transactions\n uint8 public useCustomAdapterParams;\n\n // ==================== External Permissionless Functions ======================\n\n /// @inheritdoc IOFTCore\n function sendWithPermit(\n uint16 _dstChainId,\n bytes memory _toAddress,\n uint256 _amount,\n address payable _refundAddress,\n address _zroPaymentAddress,\n bytes memory _adapterParams,\n uint256 deadline,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) public payable virtual;\n\n /// @inheritdoc IOFTCore\n function send(\n uint16 _dstChainId,\n bytes memory _toAddress,\n uint256 _amount,\n address payable _refundAddress,\n address _zroPaymentAddress,\n bytes memory _adapterParams\n ) public payable virtual {\n _checkAdapterParams(_dstChainId, PT_SEND, _adapterParams, EXTRA_GAS);\n _amount = _debitFrom(_dstChainId, _toAddress, _amount);\n\n bytes memory payload = abi.encode(_toAddress, _amount);\n _lzSend(_dstChainId, payload, _refundAddress, _zroPaymentAddress, _adapterParams);\n\n uint64 nonce = lzEndpoint.getOutboundNonce(_dstChainId, address(this));\n emit SendToChain(msg.sender, _dstChainId, _toAddress, _amount, nonce);\n }\n\n /// @inheritdoc IOFTCore\n function sendCredit(\n uint16 _dstChainId,\n bytes memory _toAddress,\n uint256 _amount,\n address payable _refundAddress,\n address _zroPaymentAddress,\n bytes memory _adapterParams\n ) public payable virtual {\n _checkAdapterParams(_dstChainId, PT_SEND, _adapterParams, EXTRA_GAS);\n _amount = _debitCreditFrom(_dstChainId, _toAddress, _amount);\n\n _send(_dstChainId, _toAddress, _amount, _refundAddress, _zroPaymentAddress, _adapterParams);\n }\n\n /// @inheritdoc IOFTCore\n function withdraw(uint256 amount, address recipient) external virtual returns (uint256);\n\n /// @notice Sets whether custom adapter parameters can be used or not\n function setUseCustomAdapterParams(uint8 _useCustomAdapterParams) public virtual onlyGovernorOrGuardian {\n useCustomAdapterParams = _useCustomAdapterParams;\n }\n\n // =========================== Internal Functions ==============================\n\n /// @notice Internal function to send `_amount` amount of token to (`_dstChainId`, `_toAddress`)\n /// @param _dstChainId the destination chain identifier\n /// @param _toAddress can be any size depending on the `dstChainId`.\n /// @param _amount the quantity of tokens in wei\n /// @param _refundAddress the address LayerZero refunds if too much message fee is sent\n /// @param _zroPaymentAddress set to address(0x0) if not paying in ZRO (LayerZero Token)\n /// @param _adapterParams is a flexible bytes array to indicate messaging adapter services\n /// @dev Accounting and checks should be performed beforehand\n function _send(\n uint16 _dstChainId,\n bytes memory _toAddress,\n uint256 _amount,\n address payable _refundAddress,\n address _zroPaymentAddress,\n bytes memory _adapterParams\n ) internal {\n bytes memory payload = abi.encode(_toAddress, _amount);\n _lzSend(_dstChainId, payload, _refundAddress, _zroPaymentAddress, _adapterParams);\n\n uint64 nonce = lzEndpoint.getOutboundNonce(_dstChainId, address(this));\n emit SendToChain(msg.sender, _dstChainId, _toAddress, _amount, nonce);\n }\n\n /// @inheritdoc NonblockingLzApp\n function _nonblockingLzReceive(\n uint16 _srcChainId,\n bytes memory _srcAddress,\n uint64 _nonce,\n bytes memory _payload\n ) internal virtual override {\n // decode and load the toAddress\n (bytes memory toAddressBytes, uint256 amount) = abi.decode(_payload, (bytes, uint256));\n address toAddress;\n //solhint-disable-next-line\n assembly {\n toAddress := mload(add(toAddressBytes, 20))\n }\n amount = _creditTo(_srcChainId, toAddress, amount);\n\n emit ReceiveFromChain(_srcChainId, _srcAddress, toAddress, amount, _nonce);\n }\n\n /// @notice Checks the adapter parameters given during the smart contract call\n function _checkAdapterParams(\n uint16 _dstChainId,\n uint16 _pkType,\n bytes memory _adapterParams,\n uint256 _extraGas\n ) internal virtual {\n if (useCustomAdapterParams > 0) _checkGasLimit(_dstChainId, _pkType, _adapterParams, _extraGas);\n else if (_adapterParams.length != 0) revert InvalidParams();\n }\n\n /// @notice Makes accountability when bridging from this contract using canonical token\n /// @param _dstChainId ChainId of the destination chain - LayerZero standard\n /// @param _toAddress Recipient on the destination chain\n /// @param _amount Amount to bridge\n function _debitFrom(\n uint16 _dstChainId,\n bytes memory _toAddress,\n uint256 _amount\n ) internal virtual returns (uint256);\n\n /// @notice Makes accountability when bridging from this contract's credit\n /// @param _dstChainId ChainId of the destination chain - LayerZero standard\n /// @param _toAddress Recipient on the destination chain\n /// @param _amount Amount to bridge\n function _debitCreditFrom(\n uint16 _dstChainId,\n bytes memory _toAddress,\n uint256 _amount\n ) internal virtual returns (uint256);\n\n /// @notice Makes accountability when bridging to this contract\n /// @param _srcChainId ChainId of the source chain - LayerZero standard\n /// @param _toAddress Recipient on this chain\n /// @param _amount Amount to bridge\n function _creditTo(uint16 _srcChainId, address _toAddress, uint256 _amount) internal virtual returns (uint256);\n\n // ========================== View Functions ===================================\n\n /// @inheritdoc ERC165Upgradeable\n function supportsInterface(\n bytes4 interfaceId\n ) public view virtual override(ERC165Upgradeable, IERC165) returns (bool) {\n return interfaceId == type(IOFTCore).interfaceId || super.supportsInterface(interfaceId);\n }\n\n /// @inheritdoc IOFTCore\n function estimateSendFee(\n uint16 _dstChainId,\n bytes memory _toAddress,\n uint256 _amount,\n bool _useZro,\n bytes memory _adapterParams\n ) public view virtual override returns (uint256 nativeFee, uint256 zroFee) {\n // mock the payload for send()\n bytes memory payload = abi.encode(_toAddress, _amount);\n return lzEndpoint.estimateFees(_dstChainId, address(this), payload, _useZro, _adapterParams);\n }\n\n uint256[49] private __gap;\n}\n" + }, + "contracts/agToken/polygon/TokenPolygonUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.12;\n\nimport \"./utils/ERC20UpgradeableCustom.sol\";\nimport \"@openzeppelin/contracts-upgradeable/access/AccessControlUpgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/utils/cryptography/draft-EIP712Upgradeable.sol\";\nimport \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\nimport \"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\";\n\nimport \"../../interfaces/IAgToken.sol\";\nimport \"../../interfaces/ITreasury.sol\";\n\ninterface IChildToken {\n function deposit(address user, bytes calldata depositData) external;\n\n function withdraw(uint256 amount) external;\n}\n\ncontract TokenPolygonUpgradeable is\n Initializable,\n ERC20UpgradeableCustom,\n AccessControlUpgradeable,\n EIP712Upgradeable,\n IChildToken\n{\n bytes32 public constant DEPOSITOR_ROLE = keccak256(\"DEPOSITOR_ROLE\");\n\n /// @dev Emitted when the child chain manager changes\n event ChildChainManagerAdded(address newAddress);\n event ChildChainManagerRevoked(address oldAddress);\n\n constructor() initializer {}\n\n function initialize(\n string memory _name,\n string memory _symbol,\n address childChainManager,\n address guardian\n ) public initializer {\n __ERC20_init(_name, _symbol);\n __AccessControl_init();\n _setupRole(DEFAULT_ADMIN_ROLE, guardian);\n _setupRole(DEPOSITOR_ROLE, childChainManager);\n __EIP712_init(_name, \"1\");\n }\n\n /**\n * @notice Called when the bridge has tokens to mint\n * @param user Address to mint the token to\n * @param depositData Encoded amount to mint\n */\n function deposit(address user, bytes calldata depositData) external override {\n require(hasRole(DEPOSITOR_ROLE, msg.sender));\n uint256 amount = abi.decode(depositData, (uint256));\n _mint(user, amount);\n }\n\n /**\n * @notice Called when user wants to withdraw tokens back to root chain\n * @dev Should burn user's tokens. This transaction will be verified when exiting on root chain\n * @param amount Amount of tokens to withdraw\n */\n function withdraw(uint256 amount) external override {\n _burn(_msgSender(), amount);\n }\n\n // =============================================================================\n // ======================= New data added for the upgrade ======================\n // =============================================================================\n\n mapping(address => bool) public isMinter;\n /// @notice Reference to the treasury contract which can grant minting rights\n address public treasury;\n /// @notice Boolean to check whether the contract has been reinitialized after its upgrade\n bool public treasuryInitialized;\n\n using SafeERC20 for IERC20;\n\n /// @notice Base used for fee computation\n uint256 public constant BASE_PARAMS = 10 ** 9;\n\n // =============================== Bridging Data ===============================\n\n /// @notice Struct with some data about a specific bridge token\n struct BridgeDetails {\n // Limit on the balance of bridge token held by the contract: it is designed\n // to reduce the exposure of the system to hacks\n uint256 limit;\n // Limit on the hourly volume of token minted through this bridge\n // Technically the limit over a rolling hour is hourlyLimit x2 as hourly limit\n // is enforced only between x:00 and x+1:00\n uint256 hourlyLimit;\n // Fee taken for swapping in and out the token\n uint64 fee;\n // Whether the associated token is allowed or not\n bool allowed;\n // Whether swapping in and out from the associated token is paused or not\n bool paused;\n }\n\n /// @notice Maps a bridge token to data\n mapping(address => BridgeDetails) public bridges;\n /// @notice List of all bridge tokens\n address[] public bridgeTokensList;\n /// @notice Maps a bridge token to the associated hourly volume\n mapping(address => mapping(uint256 => uint256)) public usage;\n /// @notice Maps an address to whether it is exempt of fees for when it comes to swapping in and out\n mapping(address => uint256) public isFeeExempt;\n /// @notice Limit to the amount of tokens that can be sent from that chain to another chain\n uint256 public chainTotalHourlyLimit;\n /// @notice Usage per hour on that chain. Maps an hourly timestamp to the total volume swapped out on the chain\n mapping(uint256 => uint256) public chainTotalUsage;\n\n uint256[42] private __gap;\n\n // ================================== Events ===================================\n\n event BridgeTokenAdded(address indexed bridgeToken, uint256 limit, uint256 hourlyLimit, uint64 fee, bool paused);\n event BridgeTokenToggled(address indexed bridgeToken, bool toggleStatus);\n event BridgeTokenRemoved(address indexed bridgeToken);\n event BridgeTokenFeeUpdated(address indexed bridgeToken, uint64 fee);\n event BridgeTokenLimitUpdated(address indexed bridgeToken, uint256 limit);\n event BridgeTokenHourlyLimitUpdated(address indexed bridgeToken, uint256 hourlyLimit);\n event HourlyLimitUpdated(uint256 hourlyLimit);\n event FeeToggled(address indexed theAddress, uint256 toggleStatus);\n event KeeperToggled(address indexed keeper, bool toggleStatus);\n event MinterToggled(address indexed minter);\n event Recovered(address indexed token, address indexed to, uint256 amount);\n event TreasuryUpdated(address indexed _treasury);\n\n // ================================== Errors ===================================\n\n error AssetStillControlledInReserves();\n error BurnAmountExceedsAllowance();\n error HourlyLimitExceeded();\n error InvalidSender();\n error InvalidToken();\n error InvalidTreasury();\n error NotGovernor();\n error NotGovernorOrGuardian();\n error NotMinter();\n error NotTreasury();\n error TooBigAmount();\n error TooHighParameterValue();\n error TreasuryAlreadyInitialized();\n error ZeroAddress();\n\n /// @notice Checks to see if it is the `Treasury` calling this contract\n /// @dev There is no Access Control here, because it can be handled cheaply through this modifier\n modifier onlyTreasury() {\n if (msg.sender != treasury) revert NotTreasury();\n _;\n }\n\n /// @notice Checks whether the sender has the minting right\n modifier onlyMinter() {\n if (!isMinter[msg.sender]) revert NotMinter();\n _;\n }\n\n /// @notice Checks whether the `msg.sender` has the governor role or not\n modifier onlyGovernor() {\n if (!ITreasury(treasury).isGovernor(msg.sender)) revert NotGovernor();\n _;\n }\n\n /// @notice Checks whether the `msg.sender` has the governor role or the guardian role\n modifier onlyGovernorOrGuardian() {\n if (!ITreasury(treasury).isGovernorOrGuardian(msg.sender)) revert NotGovernorOrGuardian();\n _;\n }\n\n /// @notice Sets up the treasury contract on Polygon after the upgrade\n /// @param _treasury Address of the treasury contract\n function setUpTreasury(address _treasury) external {\n // Only governor on Polygon\n if (msg.sender != 0xdA2D2f638D6fcbE306236583845e5822554c02EA) revert NotGovernor();\n if (address(ITreasury(_treasury).stablecoin()) != address(this)) revert InvalidTreasury();\n if (treasuryInitialized) revert TreasuryAlreadyInitialized();\n treasury = _treasury;\n treasuryInitialized = true;\n emit TreasuryUpdated(_treasury);\n }\n\n // =========================== External Function ===============================\n\n /// @notice Allows anyone to burn agToken without redeeming collateral back\n /// @param amount Amount of stablecoins to burn\n /// @dev This function can typically be called if there is a settlement mechanism to burn stablecoins\n function burnStablecoin(uint256 amount) external {\n _burnCustom(msg.sender, amount);\n }\n\n // ======================= Minter Role Only Functions ==========================\n\n function burnSelf(uint256 amount, address burner) external onlyMinter {\n _burnCustom(burner, amount);\n }\n\n function burnFrom(uint256 amount, address burner, address sender) external onlyMinter {\n _burnFromNoRedeem(amount, burner, sender);\n }\n\n function mint(address account, uint256 amount) external onlyMinter {\n _mint(account, amount);\n }\n\n // ======================= Treasury Only Functions =============================\n\n function addMinter(address minter) external onlyTreasury {\n isMinter[minter] = true;\n emit MinterToggled(minter);\n }\n\n function removeMinter(address minter) external {\n if (msg.sender != address(treasury) && msg.sender != minter) revert InvalidSender();\n isMinter[minter] = false;\n emit MinterToggled(minter);\n }\n\n function setTreasury(address _treasury) external onlyTreasury {\n treasury = _treasury;\n emit TreasuryUpdated(_treasury);\n }\n\n // ============================ Internal Function ==============================\n\n /// @notice Internal version of the function `burnFromNoRedeem`\n /// @param amount Amount to burn\n /// @dev It is at the level of this function that allowance checks are performed\n function _burnFromNoRedeem(uint256 amount, address burner, address sender) internal {\n if (burner != sender) {\n uint256 currentAllowance = allowance(burner, sender);\n if (currentAllowance < amount) revert BurnAmountExceedsAllowance();\n _approve(burner, sender, currentAllowance - amount);\n }\n _burnCustom(burner, amount);\n }\n\n // ==================== External Permissionless Functions ======================\n\n /// @notice Returns the list of all supported bridge tokens\n /// @dev Helpful for UIs\n function allBridgeTokens() external view returns (address[] memory) {\n return bridgeTokensList;\n }\n\n /// @notice Returns the current volume for a bridge, for the current hour\n /// @dev Helpful for UIs\n function currentUsage(address bridge) external view returns (uint256) {\n return usage[bridge][block.timestamp / 3600];\n }\n\n /// @notice Returns the current total volume on the chain for the current hour\n /// @dev Helpful for UIs\n function currentTotalUsage() external view returns (uint256) {\n return chainTotalUsage[block.timestamp / 3600];\n }\n\n /// @notice Mints the canonical token from a supported bridge token\n /// @param bridgeToken Bridge token to use to mint\n /// @param amount Amount of bridge tokens to send\n /// @param to Address to which the stablecoin should be sent\n /// @dev Some fees may be taken by the protocol depending on the token used and on the address calling\n function swapIn(address bridgeToken, uint256 amount, address to) external returns (uint256) {\n BridgeDetails memory bridgeDetails = bridges[bridgeToken];\n if (!bridgeDetails.allowed || bridgeDetails.paused) revert InvalidToken();\n uint256 balance = IERC20(bridgeToken).balanceOf(address(this));\n if (balance + amount > bridgeDetails.limit) {\n // In case someone maliciously sends tokens to this contract\n // Or the limit changes\n if (bridgeDetails.limit > balance) amount = bridgeDetails.limit - balance;\n else {\n amount = 0;\n }\n }\n\n // Checking requirement on the hourly volume\n uint256 hour = block.timestamp / 3600;\n uint256 hourlyUsage = usage[bridgeToken][hour] + amount;\n if (hourlyUsage > bridgeDetails.hourlyLimit) {\n // Edge case when the hourly limit changes\n if (bridgeDetails.hourlyLimit > usage[bridgeToken][hour])\n amount = bridgeDetails.hourlyLimit - usage[bridgeToken][hour];\n else {\n amount = 0;\n }\n }\n usage[bridgeToken][hour] += amount;\n\n IERC20(bridgeToken).safeTransferFrom(msg.sender, address(this), amount);\n uint256 canonicalOut = amount;\n // Computing fees\n if (isFeeExempt[msg.sender] == 0) {\n canonicalOut -= (canonicalOut * bridgeDetails.fee) / BASE_PARAMS;\n }\n _mint(to, canonicalOut);\n return canonicalOut;\n }\n\n /// @notice Burns the canonical token in exchange for a bridge token\n /// @param bridgeToken Bridge token required\n /// @param amount Amount of canonical tokens to burn\n /// @param to Address to which the bridge token should be sent\n /// @dev Some fees may be taken by the protocol depending on the token used and on the address calling\n function swapOut(address bridgeToken, uint256 amount, address to) external returns (uint256) {\n BridgeDetails memory bridgeDetails = bridges[bridgeToken];\n if (!bridgeDetails.allowed || bridgeDetails.paused) revert InvalidToken();\n\n uint256 hour = block.timestamp / 3600;\n uint256 hourlyUsage = chainTotalUsage[hour] + amount;\n // If the amount being swapped out exceeds the limit, we revert\n // We don't want to change the amount being swapped out.\n // The user can decide to send another tx with the correct amount to reach the limit\n if (hourlyUsage > chainTotalHourlyLimit) revert HourlyLimitExceeded();\n chainTotalUsage[hour] = hourlyUsage;\n\n _burnCustom(msg.sender, amount);\n uint256 bridgeOut = amount;\n if (isFeeExempt[msg.sender] == 0) {\n bridgeOut -= (bridgeOut * bridgeDetails.fee) / BASE_PARAMS;\n }\n IERC20(bridgeToken).safeTransfer(to, bridgeOut);\n return bridgeOut;\n }\n\n // ======================= Governance Functions ================================\n\n /// @notice Adds support for a bridge token\n /// @param bridgeToken Bridge token to add: it should be a version of the stablecoin from another bridge\n /// @param limit Limit on the balance of bridge token this contract could hold\n /// @param hourlyLimit Limit on the hourly volume for this bridge\n /// @param paused Whether swapping for this token should be paused or not\n /// @param fee Fee taken upon swapping for or against this token\n function addBridgeToken(\n address bridgeToken,\n uint256 limit,\n uint256 hourlyLimit,\n uint64 fee,\n bool paused\n ) external onlyGovernor {\n if (bridges[bridgeToken].allowed || bridgeToken == address(0)) revert InvalidToken();\n if (fee > BASE_PARAMS) revert TooHighParameterValue();\n BridgeDetails memory _bridge;\n _bridge.limit = limit;\n _bridge.hourlyLimit = hourlyLimit;\n _bridge.paused = paused;\n _bridge.fee = fee;\n _bridge.allowed = true;\n bridges[bridgeToken] = _bridge;\n bridgeTokensList.push(bridgeToken);\n emit BridgeTokenAdded(bridgeToken, limit, hourlyLimit, fee, paused);\n }\n\n /// @notice Removes support for a token\n /// @param bridgeToken Address of the bridge token to remove support for\n function removeBridgeToken(address bridgeToken) external onlyGovernor {\n if (IERC20(bridgeToken).balanceOf(address(this)) != 0) revert AssetStillControlledInReserves();\n delete bridges[bridgeToken];\n // Deletion from `bridgeTokensList` loop\n uint256 bridgeTokensListLength = bridgeTokensList.length;\n for (uint256 i; i < bridgeTokensListLength - 1; ++i) {\n if (bridgeTokensList[i] == bridgeToken) {\n // Replace the `bridgeToken` to remove with the last of the list\n bridgeTokensList[i] = bridgeTokensList[bridgeTokensListLength - 1];\n break;\n }\n }\n // Remove last element in array\n bridgeTokensList.pop();\n emit BridgeTokenRemoved(bridgeToken);\n }\n\n /// @notice Recovers any ERC20 token\n /// @dev Can be used to withdraw bridge tokens for them to be de-bridged on mainnet\n function recoverERC20(address tokenAddress, address to, uint256 amountToRecover) external onlyGovernor {\n IERC20(tokenAddress).safeTransfer(to, amountToRecover);\n emit Recovered(tokenAddress, to, amountToRecover);\n }\n\n /// @notice Updates the `limit` amount for `bridgeToken`\n function setLimit(address bridgeToken, uint256 limit) external onlyGovernorOrGuardian {\n if (!bridges[bridgeToken].allowed) revert InvalidToken();\n bridges[bridgeToken].limit = limit;\n emit BridgeTokenLimitUpdated(bridgeToken, limit);\n }\n\n /// @notice Updates the `hourlyLimit` amount for `bridgeToken`\n function setHourlyLimit(address bridgeToken, uint256 hourlyLimit) external onlyGovernorOrGuardian {\n if (!bridges[bridgeToken].allowed) revert InvalidToken();\n bridges[bridgeToken].hourlyLimit = hourlyLimit;\n emit BridgeTokenHourlyLimitUpdated(bridgeToken, hourlyLimit);\n }\n\n /// @notice Updates the `chainTotalHourlyLimit` amount\n function setChainTotalHourlyLimit(uint256 hourlyLimit) external onlyGovernorOrGuardian {\n chainTotalHourlyLimit = hourlyLimit;\n emit HourlyLimitUpdated(hourlyLimit);\n }\n\n /// @notice Updates the `fee` value for `bridgeToken`\n function setSwapFee(address bridgeToken, uint64 fee) external onlyGovernorOrGuardian {\n if (!bridges[bridgeToken].allowed) revert InvalidToken();\n if (fee > BASE_PARAMS) revert TooHighParameterValue();\n bridges[bridgeToken].fee = fee;\n emit BridgeTokenFeeUpdated(bridgeToken, fee);\n }\n\n /// @notice Pauses or unpauses swapping in and out for a token\n function toggleBridge(address bridgeToken) external onlyGovernorOrGuardian {\n if (!bridges[bridgeToken].allowed) revert InvalidToken();\n bool pausedStatus = bridges[bridgeToken].paused;\n bridges[bridgeToken].paused = !pausedStatus;\n emit BridgeTokenToggled(bridgeToken, !pausedStatus);\n }\n\n /// @notice Toggles fees for the address `theAddress`\n function toggleFeesForAddress(address theAddress) external onlyGovernorOrGuardian {\n uint256 feeExemptStatus = 1 - isFeeExempt[theAddress];\n isFeeExempt[theAddress] = feeExemptStatus;\n emit FeeToggled(theAddress, feeExemptStatus);\n }\n}\n" + }, + "contracts/agToken/polygon/utils/ERC20UpgradeableCustom.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (token/ERC20/ERC20.sol)\n\npragma solidity ^0.8.0;\n\nimport \"@openzeppelin/contracts-upgradeable/token/ERC20/IERC20Upgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/token/ERC20/extensions/IERC20MetadataUpgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/utils/ContextUpgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol\";\n\n/**\n * @dev Implementation of the {IERC20} interface modified by Angle Labs, Inc.\n *\n * This implementation has a custom burn function to avoid having a {Transfer} event to the zero address\n * in some specific burn cases to avoid having Polygon PoS bridge catching this event\n *\n * TIP: For a detailed writeup see our guide\n * https://forum.zeppelin.solutions/t/how-to-implement-erc20-supply-mechanisms/226[How\n * to implement supply mechanisms].\n *\n * We have followed general OpenZeppelin Contracts guidelines: functions revert\n * instead returning `false` on failure. This behavior is nonetheless\n * conventional and does not conflict with the expectations of ERC20\n * applications.\n *\n * Additionally, an {Approval} event is emitted on calls to {transferFrom}.\n * This allows applications to reconstruct the allowance for all accounts just\n * by listening to said events. Other implementations of the EIP may not emit\n * these events, as it isn't required by the specification.\n *\n * Finally, the non-standard {decreaseAllowance} and {increaseAllowance}\n * functions have been added to mitigate the well-known issues around setting\n * allowances. See {IERC20-approve}.\n */\ncontract ERC20UpgradeableCustom is Initializable, ContextUpgradeable, IERC20Upgradeable, IERC20MetadataUpgradeable {\n mapping(address => uint256) private _balances;\n\n mapping(address => mapping(address => uint256)) private _allowances;\n\n uint256 private _totalSupply;\n\n string private _name;\n string private _symbol;\n\n /**\n * @dev Sets the values for {name} and {symbol}.\n *\n * The default value of {decimals} is 18. To select a different value for\n * {decimals} you should overload it.\n *\n * All two of these values are immutable: they can only be set once during\n * construction.\n */\n //solhint-disable-next-line\n function __ERC20_init(string memory name_, string memory symbol_) internal onlyInitializing {\n __Context_init_unchained();\n __ERC20_init_unchained(name_, symbol_);\n }\n\n //solhint-disable-next-line\n function __ERC20_init_unchained(string memory name_, string memory symbol_) internal onlyInitializing {\n _name = name_;\n _symbol = symbol_;\n }\n\n /**\n * @dev Returns the name of the token.\n */\n function name() public view virtual override returns (string memory) {\n return _name;\n }\n\n /**\n * @dev Returns the symbol of the token, usually a shorter version of the\n * name.\n */\n function symbol() public view virtual override returns (string memory) {\n return _symbol;\n }\n\n /**\n * @dev Returns the number of decimals used to get its user representation.\n * For example, if `decimals` equals `2`, a balance of `505` tokens should\n * be displayed to a user as `5.05` (`505 / 10 ** 2`).\n *\n * Tokens usually opt for a value of 18, imitating the relationship between\n * Ether and Wei. This is the value {ERC20} uses, unless this function is\n * overridden;\n *\n * NOTE: This information is only used for _display_ purposes: it in\n * no way affects any of the arithmetic of the contract, including\n * {IERC20-balanceOf} and {IERC20-transfer}.\n */\n function decimals() public view virtual override returns (uint8) {\n return 18;\n }\n\n /**\n * @dev See {IERC20-totalSupply}.\n */\n function totalSupply() public view virtual override returns (uint256) {\n return _totalSupply;\n }\n\n /**\n * @dev See {IERC20-balanceOf}.\n */\n function balanceOf(address account) public view virtual override returns (uint256) {\n return _balances[account];\n }\n\n /**\n * @dev See {IERC20-transfer}.\n *\n * Requirements:\n *\n * - `recipient` cannot be the zero address.\n * - the caller must have a balance of at least `amount`.\n */\n function transfer(address recipient, uint256 amount) public virtual override returns (bool) {\n _transfer(_msgSender(), recipient, amount);\n return true;\n }\n\n /**\n * @dev See {IERC20-allowance}.\n */\n function allowance(address owner, address spender) public view virtual override returns (uint256) {\n return _allowances[owner][spender];\n }\n\n /**\n * @dev See {IERC20-approve}.\n *\n * Requirements:\n *\n * - `spender` cannot be the zero address.\n */\n function approve(address spender, uint256 amount) public virtual override returns (bool) {\n _approve(_msgSender(), spender, amount);\n return true;\n }\n\n /**\n * @dev See {IERC20-transferFrom}.\n *\n * Emits an {Approval} event indicating the updated allowance. This is not\n * required by the EIP. See the note at the beginning of {ERC20}.\n *\n * Requirements:\n *\n * - `sender` and `recipient` cannot be the zero address.\n * - `sender` must have a balance of at least `amount`.\n * - the caller must have allowance for `sender`'s tokens of at least\n * `amount`.\n */\n function transferFrom(address sender, address recipient, uint256 amount) public virtual override returns (bool) {\n _transfer(sender, recipient, amount);\n\n uint256 currentAllowance = _allowances[sender][_msgSender()];\n require(currentAllowance >= amount, \"ERC20: transfer amount exceeds allowance\");\n unchecked {\n _approve(sender, _msgSender(), currentAllowance - amount);\n }\n\n return true;\n }\n\n /**\n * @dev Atomically increases the allowance granted to `spender` by the caller.\n *\n * This is an alternative to {approve} that can be used as a mitigation for\n * problems described in {IERC20-approve}.\n *\n * Emits an {Approval} event indicating the updated allowance.\n *\n * Requirements:\n *\n * - `spender` cannot be the zero address.\n */\n function increaseAllowance(address spender, uint256 addedValue) public virtual returns (bool) {\n _approve(_msgSender(), spender, _allowances[_msgSender()][spender] + addedValue);\n return true;\n }\n\n /**\n * @dev Atomically decreases the allowance granted to `spender` by the caller.\n *\n * This is an alternative to {approve} that can be used as a mitigation for\n * problems described in {IERC20-approve}.\n *\n * Emits an {Approval} event indicating the updated allowance.\n *\n * Requirements:\n *\n * - `spender` cannot be the zero address.\n * - `spender` must have allowance for the caller of at least\n * `subtractedValue`.\n */\n function decreaseAllowance(address spender, uint256 subtractedValue) public virtual returns (bool) {\n uint256 currentAllowance = _allowances[_msgSender()][spender];\n require(currentAllowance >= subtractedValue, \"ERC20: decreased allowance below zero\");\n unchecked {\n _approve(_msgSender(), spender, currentAllowance - subtractedValue);\n }\n\n return true;\n }\n\n /**\n * @dev Moves `amount` of tokens from `sender` to `recipient`.\n *\n * This internal function is equivalent to {transfer}, and can be used to\n * e.g. implement automatic token fees, slashing mechanisms, etc.\n *\n * Emits a {Transfer} event.\n *\n * Requirements:\n *\n * - `sender` cannot be the zero address.\n * - `recipient` cannot be the zero address.\n * - `sender` must have a balance of at least `amount`.\n */\n function _transfer(address sender, address recipient, uint256 amount) internal virtual {\n require(sender != address(0), \"ERC20: transfer from the zero address\");\n require(recipient != address(0), \"ERC20: transfer to the zero address\");\n\n _beforeTokenTransfer(sender, recipient, amount);\n\n uint256 senderBalance = _balances[sender];\n require(senderBalance >= amount, \"ERC20: transfer amount exceeds balance\");\n unchecked {\n _balances[sender] = senderBalance - amount;\n }\n _balances[recipient] += amount;\n\n emit Transfer(sender, recipient, amount);\n\n _afterTokenTransfer(sender, recipient, amount);\n }\n\n /** @dev Creates `amount` tokens and assigns them to `account`, increasing\n * the total supply.\n *\n * Emits a {Transfer} event with `from` set to the zero address.\n *\n * Requirements:\n *\n * - `account` cannot be the zero address.\n */\n function _mint(address account, uint256 amount) internal virtual {\n require(account != address(0), \"ERC20: mint to the zero address\");\n\n _beforeTokenTransfer(address(0), account, amount);\n\n _totalSupply += amount;\n _balances[account] += amount;\n emit Transfer(address(0), account, amount);\n\n _afterTokenTransfer(address(0), account, amount);\n }\n\n /**\n * @dev Destroys `amount` tokens from `account`, reducing the\n * total supply.\n *\n * Emits a {Transfer} event with `to` set to the zero address.\n *\n * Requirements:\n *\n * - `account` cannot be the zero address.\n * - `account` must have at least `amount` tokens.\n */\n function _burn(address account, uint256 amount) internal virtual {\n require(account != address(0), \"ERC20: burn from the zero address\");\n\n _beforeTokenTransfer(account, address(0), amount);\n\n uint256 accountBalance = _balances[account];\n require(accountBalance >= amount, \"ERC20: burn amount exceeds balance\");\n unchecked {\n _balances[account] = accountBalance - amount;\n }\n _totalSupply -= amount;\n\n emit Transfer(account, address(0), amount);\n\n _afterTokenTransfer(account, address(0), amount);\n }\n\n /**\n * @dev Destroys `amount` tokens from `account`, reducing the\n * total supply.\n *\n * Contrary to the other `burn` function, the {Transfer} event is not to the zero address\n * but rather to this address: the reason is that not all burn events should be caught up\n * by the PoS bridge\n *\n * Requirements:\n *\n * - `account` cannot be the zero address.\n * - `account` must have at least `amount` tokens.\n */\n function _burnCustom(address account, uint256 amount) internal virtual {\n require(account != address(0), \"ERC20: burn from the zero address\");\n\n _beforeTokenTransfer(account, address(0), amount);\n\n uint256 accountBalance = _balances[account];\n require(accountBalance >= amount, \"ERC20: burn amount exceeds balance\");\n unchecked {\n _balances[account] = accountBalance - amount;\n }\n _totalSupply -= amount;\n\n emit Transfer(account, address(this), amount);\n\n _afterTokenTransfer(account, address(0), amount);\n }\n\n /**\n * @dev Sets `amount` as the allowance of `spender` over the `owner` s tokens.\n *\n * This internal function is equivalent to `approve`, and can be used to\n * e.g. set automatic allowances for certain subsystems, etc.\n *\n * Emits an {Approval} event.\n *\n * Requirements:\n *\n * - `owner` cannot be the zero address.\n * - `spender` cannot be the zero address.\n */\n function _approve(address owner, address spender, uint256 amount) internal virtual {\n require(owner != address(0), \"ERC20: approve from the zero address\");\n require(spender != address(0), \"ERC20: approve to the zero address\");\n\n _allowances[owner][spender] = amount;\n emit Approval(owner, spender, amount);\n }\n\n /**\n * @dev Hook that is called before any transfer of tokens. This includes\n * minting and burning.\n *\n * Calling conditions:\n *\n * - when `from` and `to` are both non-zero, `amount` of `from`'s tokens\n * will be transferred to `to`.\n * - when `from` is zero, `amount` tokens will be minted for `to`.\n * - when `to` is zero, `amount` of `from`'s tokens will be burned.\n * - `from` and `to` are never both zero.\n *\n * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].\n */\n function _beforeTokenTransfer(address from, address to, uint256 amount) internal virtual {}\n\n /**\n * @dev Hook that is called after any transfer of tokens. This includes\n * minting and burning.\n *\n * Calling conditions:\n *\n * - when `from` and `to` are both non-zero, `amount` of `from`'s tokens\n * has been transferred to `to`.\n * - when `from` is zero, `amount` tokens have been minted for `to`.\n * - when `to` is zero, `amount` of `from`'s tokens have been burned.\n * - `from` and `to` are never both zero.\n *\n * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].\n */\n function _afterTokenTransfer(address from, address to, uint256 amount) internal virtual {}\n\n uint256[45] private __gap;\n}\n" + }, + "contracts/coreBorrow/CoreBorrow.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\n/*\n * █ \n ***** ▓▓▓ \n * ▓▓▓▓▓▓▓ \n * ///. ▓▓▓▓▓▓▓▓▓▓▓▓▓ \n ***** //////// ▓▓▓▓▓▓▓ \n * ///////////// ▓▓▓ \n ▓▓ ////////////////// █ ▓▓ \n ▓▓ ▓▓ /////////////////////// ▓▓ ▓▓ \n ▓▓ ▓▓ //////////////////////////// ▓▓ ▓▓ \n ▓▓ ▓▓ /////////▓▓▓///////▓▓▓///////// ▓▓ ▓▓ \n ▓▓ ,////////////////////////////////////// ▓▓ ▓▓ \n ▓▓ ////////////////////////////////////////// ▓▓ \n ▓▓ //////////////////////▓▓▓▓///////////////////// \n ,//////////////////////////////////////////////////// \n .////////////////////////////////////////////////////////// \n .//////////////////////////██.,//////////////////////////█ \n .//////////////////////████..,./////////////////////██ \n ...////////////////███████.....,.////////////////███ \n ,.,////////////████████ ........,///////////████ \n .,.,//////█████████ ,.......///////████ \n ,..//████████ ........./████ \n ..,██████ .....,███ \n .██ ,.,█ \n \n \n \n ▓▓ ▓▓▓▓▓▓▓▓▓▓ ▓▓▓▓▓▓▓▓▓▓ ▓▓ ▓▓▓▓▓▓▓▓▓▓ \n ▓▓▓▓▓▓ ▓▓▓ ▓▓▓ ▓▓▓ ▓▓ ▓▓ ▓▓▓▓ \n ▓▓▓ ▓▓▓ ▓▓▓ ▓▓▓ ▓▓▓ ▓▓▓ ▓▓ ▓▓▓▓▓ \n ▓▓▓ ▓▓ ▓▓▓ ▓▓▓ ▓▓▓▓▓▓▓▓▓▓ ▓▓▓▓▓▓▓▓▓▓ ▓▓▓▓▓▓▓▓▓▓ \n*/\n\npragma solidity ^0.8.12;\n\nimport \"@openzeppelin/contracts-upgradeable/access/AccessControlEnumerableUpgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol\";\n\nimport \"../interfaces/ICoreBorrow.sol\";\nimport \"../interfaces/IFlashAngle.sol\";\nimport \"../interfaces/ITreasury.sol\";\n\n/// @title CoreBorrow\n/// @author Angle Labs, Inc.\n/// @notice Core contract of the borrowing module. This contract handles the access control across all contracts\n/// (it is read by all treasury contracts), and manages the `flashLoanModule`. It has no minting rights over the\n/// stablecoin contracts\ncontract CoreBorrow is ICoreBorrow, Initializable, AccessControlEnumerableUpgradeable {\n /// @notice Role for guardians\n bytes32 public constant GUARDIAN_ROLE = keccak256(\"GUARDIAN_ROLE\");\n /// @notice Role for governors\n bytes32 public constant GOVERNOR_ROLE = keccak256(\"GOVERNOR_ROLE\");\n /// @notice Role for treasury contract\n bytes32 public constant FLASHLOANER_TREASURY_ROLE = keccak256(\"FLASHLOANER_TREASURY_ROLE\");\n\n // ============================= Reference =====================================\n\n /// @notice Reference to the `flashLoanModule` with minting rights over the different stablecoins of the protocol\n address public flashLoanModule;\n\n // =============================== Events ======================================\n\n event FlashLoanModuleUpdated(address indexed _flashloanModule);\n event CoreUpdated(address indexed _core);\n\n // =============================== Errors ======================================\n\n error InvalidCore();\n error IncompatibleGovernorAndGuardian();\n error NotEnoughGovernorsLeft();\n error ZeroAddress();\n\n /// @notice Initializes the `CoreBorrow` contract and the access control of the borrowing module\n /// @param governor Address of the governor of the Angle Protocol\n /// @param guardian Guardian address of the protocol\n function initialize(address governor, address guardian) public initializer {\n if (governor == address(0) || guardian == address(0)) revert ZeroAddress();\n if (governor == guardian) revert IncompatibleGovernorAndGuardian();\n _setupRole(GOVERNOR_ROLE, governor);\n _setupRole(GUARDIAN_ROLE, guardian);\n _setupRole(GUARDIAN_ROLE, governor);\n _setRoleAdmin(GUARDIAN_ROLE, GOVERNOR_ROLE);\n _setRoleAdmin(GOVERNOR_ROLE, GOVERNOR_ROLE);\n _setRoleAdmin(FLASHLOANER_TREASURY_ROLE, GOVERNOR_ROLE);\n }\n\n /// @custom:oz-upgrades-unsafe-allow constructor\n constructor() initializer {}\n\n // =========================== View Functions ==================================\n\n /// @inheritdoc ICoreBorrow\n function isFlashLoanerTreasury(address treasury) external view returns (bool) {\n return hasRole(FLASHLOANER_TREASURY_ROLE, treasury);\n }\n\n /// @inheritdoc ICoreBorrow\n function isGovernor(address admin) external view returns (bool) {\n return hasRole(GOVERNOR_ROLE, admin);\n }\n\n /// @inheritdoc ICoreBorrow\n function isGovernorOrGuardian(address admin) external view returns (bool) {\n return hasRole(GUARDIAN_ROLE, admin);\n }\n\n // =========================== Governor Functions ==============================\n\n /// @notice Grants the `FLASHLOANER_TREASURY_ROLE` to a `treasury` contract\n /// @param treasury Contract to grant the role to\n /// @dev This function can be used to allow flash loans on a stablecoin of the protocol\n function addFlashLoanerTreasuryRole(address treasury) external {\n grantRole(FLASHLOANER_TREASURY_ROLE, treasury);\n address _flashLoanModule = flashLoanModule;\n if (_flashLoanModule != address(0)) {\n // This call will revert if `treasury` is the zero address or if it is not linked\n // to this `CoreBorrow` contract\n ITreasury(treasury).setFlashLoanModule(_flashLoanModule);\n IFlashAngle(_flashLoanModule).addStablecoinSupport(treasury);\n }\n }\n\n /// @notice Adds a governor in the protocol\n /// @param governor Address to grant the role to\n /// @dev It is necessary to call this function to grant a governor role to make sure\n /// all governors also have the guardian role\n function addGovernor(address governor) external {\n grantRole(GOVERNOR_ROLE, governor);\n grantRole(GUARDIAN_ROLE, governor);\n }\n\n /// @notice Revokes the flash loan ability for a stablecoin\n /// @param treasury Treasury address associated with the stablecoin for which flash loans\n /// should no longer be available\n function removeFlashLoanerTreasuryRole(address treasury) external {\n revokeRole(FLASHLOANER_TREASURY_ROLE, treasury);\n ITreasury(treasury).setFlashLoanModule(address(0));\n address _flashLoanModule = flashLoanModule;\n if (_flashLoanModule != address(0)) {\n IFlashAngle(flashLoanModule).removeStablecoinSupport(treasury);\n }\n }\n\n /// @notice Revokes a governor from the protocol\n /// @param governor Address to remove the role to\n /// @dev It is necessary to call this function to remove a governor role to make sure\n /// the address also loses its guardian role\n function removeGovernor(address governor) external {\n if (getRoleMemberCount(GOVERNOR_ROLE) <= 1) revert NotEnoughGovernorsLeft();\n revokeRole(GUARDIAN_ROLE, governor);\n revokeRole(GOVERNOR_ROLE, governor);\n }\n\n /// @notice Changes the `flashLoanModule` of the protocol\n /// @param _flashLoanModule Address of the new flash loan module\n function setFlashLoanModule(address _flashLoanModule) external onlyRole(GOVERNOR_ROLE) {\n if (_flashLoanModule != address(0)) {\n if (address(IFlashAngle(_flashLoanModule).core()) != address(this)) revert InvalidCore();\n }\n uint256 count = getRoleMemberCount(FLASHLOANER_TREASURY_ROLE);\n for (uint256 i; i < count; ++i) {\n ITreasury(getRoleMember(FLASHLOANER_TREASURY_ROLE, i)).setFlashLoanModule(_flashLoanModule);\n }\n flashLoanModule = _flashLoanModule;\n emit FlashLoanModuleUpdated(_flashLoanModule);\n }\n\n /// @notice Changes the core contract of the protocol\n /// @param _core New core contract\n /// @dev This function verifies that all governors of the current core contract are also governors\n /// of the new core contract. It also notifies the `flashLoanModule` of the change.\n /// @dev Governance wishing to change the core contract should also make sure to call `setCore`\n /// in the different treasury contracts\n function setCore(ICoreBorrow _core) external onlyRole(GOVERNOR_ROLE) {\n uint256 count = getRoleMemberCount(GOVERNOR_ROLE);\n bool success;\n for (uint256 i; i < count; ++i) {\n success = _core.isGovernor(getRoleMember(GOVERNOR_ROLE, i));\n if (!success) break;\n }\n if (!success) revert InvalidCore();\n address _flashLoanModule = flashLoanModule;\n if (_flashLoanModule != address(0)) IFlashAngle(_flashLoanModule).setCore(address(_core));\n emit CoreUpdated(address(_core));\n }\n}\n" + }, + "contracts/deprecated/AgTokenIntermediateUpgrade.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\nimport \"../interfaces/IAgToken.sol\";\nimport \"../interfaces/coreModule/IStableMaster.sol\";\n// OpenZeppelin may update its version of the ERC20PermitUpgradeable token\nimport \"@openzeppelin/contracts-upgradeable/token/ERC20/extensions/draft-ERC20PermitUpgradeable.sol\";\n\n/// @title AgTokenIntermediateUpgrade\n/// @author Angle Labs, Inc.\n/// @notice Base contract for agToken, that is to say Angle's stablecoins\n/// @dev This contract is used to create and handle the stablecoins of Angle protocol\n/// @dev It is still possible for any address to burn its agTokens without redeeming collateral in exchange\n/// @dev This contract is the upgraded version of the AgToken that was first deployed on Ethereum mainnet and is used to\n/// add other minters as needed by AMOs\ncontract AgTokenIntermediateUpgrade is ERC20PermitUpgradeable {\n // ========================= References to other contracts =====================\n\n /// @notice Reference to the `StableMaster` contract associated to this `AgToken`\n address public stableMaster;\n\n // ============================= Constructor ===================================\n\n /// @notice Initializes the `AgToken` contract\n /// @param name_ Name of the token\n /// @param symbol_ Symbol of the token\n /// @param stableMaster_ Reference to the `StableMaster` contract associated to this agToken\n /// @dev By default, agTokens are ERC-20 tokens with 18 decimals\n function initialize(string memory name_, string memory symbol_, address stableMaster_) external initializer {\n __ERC20Permit_init(name_);\n __ERC20_init(name_, symbol_);\n require(stableMaster_ != address(0), \"0\");\n stableMaster = stableMaster_;\n }\n\n /// @custom:oz-upgrades-unsafe-allow constructor\n constructor() initializer {}\n\n // ======= Added Parameters and Variables from the first implementation ========\n\n /// @notice Checks whether an address has the right to mint agTokens\n mapping(address => bool) public isMinter;\n\n // =============================== Added Events ================================\n\n event MinterToggled(address indexed minter);\n\n // =============================== Setup Function ==============================\n\n /// @notice Sets up the minter role and gives it to the governor\n /// @dev This function just has to be called once\n function setUpMinter() external {\n address governor = 0xdC4e6DFe07EFCa50a197DF15D9200883eF4Eb1c8;\n require(msg.sender == governor);\n isMinter[governor] = true;\n emit MinterToggled(governor);\n }\n\n // =============================== Modifiers ===================================\n\n /// @notice Checks whether the sender has the minting right\n modifier onlyMinter() {\n require(isMinter[msg.sender] || msg.sender == stableMaster, \"35\");\n _;\n }\n\n // ========================= External Functions ================================\n // The following functions allow anyone to burn stablecoins without redeeming collateral\n // in exchange for that\n\n /// @notice Destroys `amount` token from the caller without giving collateral back\n /// @param amount Amount to burn\n /// @param poolManager Reference to the `PoolManager` contract for which the `stocksUsers` will\n /// need to be updated\n /// @dev When calling this function, people should specify the `poolManager` for which they want to decrease\n /// the `stocksUsers`: this is a way for the protocol to maintain healthy accounting variables\n function burnNoRedeem(uint256 amount, address poolManager) external {\n _burn(msg.sender, amount);\n IStableMaster(stableMaster).updateStocksUsers(amount, poolManager);\n }\n\n /// @notice Burns `amount` of agToken on behalf of another account without redeeming collateral back\n /// @param account Account to burn on behalf of\n /// @param amount Amount to burn\n /// @param poolManager Reference to the `PoolManager` contract for which the `stocksUsers` will need to be updated\n function burnFromNoRedeem(address account, uint256 amount, address poolManager) external {\n _burnFromNoRedeem(amount, account, msg.sender);\n IStableMaster(stableMaster).updateStocksUsers(amount, poolManager);\n }\n\n // ======================= Minter Role Only Functions ==========================\n\n /// @notice Burns `amount` tokens from a `burner` address\n /// @param amount Amount of tokens to burn\n /// @param burner Address to burn from\n /// @dev This method is to be called by a contract with a minter right on the AgToken after being\n /// requested to do so by an address willing to burn tokens from its address\n function burnSelf(uint256 amount, address burner) external onlyMinter {\n _burn(burner, amount);\n }\n\n /// @notice Burns `amount` tokens from a `burner` address after being asked to by `sender`\n /// @param amount Amount of tokens to burn\n /// @param burner Address to burn from\n /// @param sender Address which requested the burn from `burner`\n /// @dev This method is to be called by a contract with the minter right after being requested\n /// to do so by a `sender` address willing to burn tokens from another `burner` address\n /// @dev The method checks the allowance between the `sender` and the `burner`\n function burnFrom(uint256 amount, address burner, address sender) external onlyMinter {\n _burnFromNoRedeem(amount, burner, sender);\n }\n\n /// @notice Lets the `StableMaster` contract or another whitelisted contract mint agTokens\n /// @param account Address to mint to\n /// @param amount Amount to mint\n /// @dev The contracts allowed to issue agTokens are the `StableMaster` contract, `VaultManager` contracts\n /// associated to this stablecoin as well as the flash loan module (if activated) and potentially contracts\n /// whitelisted by governance\n function mint(address account, uint256 amount) external onlyMinter {\n _mint(account, amount);\n }\n\n // ======================= Minter Only Functions ===============================\n\n /// @notice Adds a minter in the contract\n /// @param minter Minter address to add\n function addMinter(address minter) external onlyMinter {\n isMinter[minter] = true;\n emit MinterToggled(minter);\n }\n\n /// @notice Removes a minter from the contract\n /// @param minter Minter address to remove\n /// @dev This function can at the moment only be called by a minter wishing to revoke itself\n function removeMinter(address minter) external {\n require(msg.sender == minter && isMinter[msg.sender], \"36\");\n isMinter[minter] = false;\n emit MinterToggled(minter);\n }\n\n // ============================ Internal Function ==============================\n\n /// @notice Internal version of the function `burnFromNoRedeem`\n /// @param amount Amount to burn\n /// @dev It is at the level of this function that allowance checks are performed\n function _burnFromNoRedeem(uint256 amount, address burner, address sender) internal {\n if (burner != sender) {\n uint256 currentAllowance = allowance(burner, sender);\n require(currentAllowance >= amount, \"23\");\n _approve(burner, sender, currentAllowance - amount);\n }\n _burn(burner, amount);\n }\n}\n" + }, + "contracts/deprecated/layerZero/OldLayerZeroBridgeToken.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.12;\n\nimport \"./OldOFTCore.sol\";\nimport \"../../interfaces/IAgTokenSideChainMultiBridge.sol\";\nimport \"@openzeppelin/contracts-upgradeable/security/PausableUpgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/token/ERC20/ERC20Upgradeable.sol\";\n\n/// @title LayerZeroBridgeToken\n/// @author Angle Labs, Inc., forked from https://github.com/LayerZero-Labs/solidity-examples/blob/main/contracts/token/oft/OFT.sol\n/// @notice Contract to be deployed on a L2/sidechain for bridging an AgToken using a bridge intermediate token and LayerZero\ncontract OldLayerZeroBridgeToken is OldOFTCore, ERC20Upgradeable, PausableUpgradeable {\n /// @notice Address of the bridgeable token\n /// @dev Immutable\n IAgTokenSideChainMultiBridge public canonicalToken;\n\n // =============================== Errors ================================\n\n error InvalidAllowance();\n\n // ============================= Constructor ===================================\n\n /// @notice Initializes the contract\n /// @param _name Name of the token corresponding to this contract\n /// @param _symbol Symbol of the token corresponding to this contract\n /// @param _lzEndpoint Layer zero endpoint to pass messages\n /// @param _treasury Address of the treasury contract used for access control\n /// @param initialSupply Initial supply to mint to the canonical token address\n /// @dev The initial supply corresponds to the initial amount that could be bridged using this OFT\n function initialize(\n string memory _name,\n string memory _symbol,\n address _lzEndpoint,\n address _treasury,\n uint256 initialSupply\n ) external initializer {\n __ERC20_init_unchained(_name, _symbol);\n __LzAppUpgradeable_init(_lzEndpoint, _treasury);\n\n canonicalToken = IAgTokenSideChainMultiBridge(address(ITreasury(_treasury).stablecoin()));\n _approve(address(this), address(canonicalToken), type(uint256).max);\n _mint(address(canonicalToken), initialSupply);\n }\n\n /// @custom:oz-upgrades-unsafe-allow constructor\n constructor() initializer {}\n\n // ==================== External Permissionless Functions ======================\n\n function sendWithPermit(\n uint16 _dstChainId,\n bytes memory _toAddress,\n uint256 _amount,\n address payable _refundAddress,\n address _zroPaymentAddress,\n bytes memory _adapterParams,\n uint256 deadline,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) public payable override {\n canonicalToken.permit(msg.sender, address(this), _amount, deadline, v, r, s);\n send(_dstChainId, _toAddress, _amount, _refundAddress, _zroPaymentAddress, _adapterParams);\n }\n\n function withdraw(uint256 amount, address recipient) external override returns (uint256 amountMinted) {\n // Does not check allowances as transfers from `msg.sender`\n _transfer(msg.sender, address(this), amount);\n amountMinted = canonicalToken.swapIn(address(this), amount, recipient);\n uint256 leftover = balanceOf(address(this));\n if (leftover != 0) {\n _transfer(address(this), msg.sender, leftover);\n }\n }\n\n // ============================= Internal Functions ===================================\n\n function _debitFrom(\n uint16,\n bytes memory,\n uint256 _amount\n ) internal override whenNotPaused returns (uint256 amountSwapped) {\n // No need to use safeTransferFrom as we know this implementation reverts on failure\n canonicalToken.transferFrom(msg.sender, address(this), _amount);\n\n // Swap canonical for this bridge token. There may be some fees\n amountSwapped = canonicalToken.swapOut(address(this), _amount, address(this));\n _burn(address(this), amountSwapped);\n }\n\n function _debitCreditFrom(uint16, bytes memory, uint256 _amount) internal override whenNotPaused returns (uint256) {\n _burn(msg.sender, _amount);\n return _amount;\n }\n\n function _creditTo(\n uint16,\n address _toAddress,\n uint256 _amount\n ) internal override whenNotPaused returns (uint256 amountMinted) {\n _mint(address(this), _amount);\n amountMinted = canonicalToken.swapIn(address(this), _amount, _toAddress);\n uint256 leftover = balanceOf(address(this));\n if (leftover != 0) {\n _transfer(address(this), _toAddress, leftover);\n }\n }\n\n // ======================= View Functions ================================\n\n /// @inheritdoc ERC165Upgradeable\n function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {\n return\n interfaceId == type(IOFT).interfaceId ||\n interfaceId == type(IERC20).interfaceId ||\n super.supportsInterface(interfaceId);\n }\n\n // ======================= Governance Functions ================================\n\n /// @notice Mints the intermediate contract to the `canonicalToken`\n /// @dev Used to increase the bridging capacity\n function mint(uint256 amount) external onlyGovernorOrGuardian {\n _mint(address(canonicalToken), amount);\n }\n\n /// @notice Burns the intermediate contract from the `canonicalToken`\n /// @dev Used to decrease the bridging capacity\n function burn(uint256 amount) external onlyGovernorOrGuardian {\n _burn(address(canonicalToken), amount);\n }\n\n /// @notice Increases allowance of the `canonicalToken`\n function setupAllowance() public onlyGovernorOrGuardian {\n _approve(address(this), address(canonicalToken), type(uint256).max);\n }\n\n /// @notice Pauses bridging through the contract\n /// @param pause Future pause status\n function pauseSendTokens(bool pause) external onlyGovernorOrGuardian {\n pause ? _pause() : _unpause();\n }\n\n uint256[49] private __gap;\n}\n" + }, + "contracts/deprecated/layerZero/OldNonblockingLzApp.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.12;\n\nimport \"@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol\";\nimport \"../../interfaces/external/layerZero/ILayerZeroReceiver.sol\";\nimport \"../../interfaces/external/layerZero/ILayerZeroUserApplicationConfig.sol\";\nimport \"../../interfaces/external/layerZero/ILayerZeroEndpoint.sol\";\nimport \"../../interfaces/ITreasury.sol\";\n\n/// @title OldNonblockingLzApp\n/// @author Angle Labs, Inc., forked from https://github.com/LayerZero-Labs/solidity-examples/\n/// @notice Base contract for bridging using LayerZero\nabstract contract OldNonblockingLzApp is Initializable, ILayerZeroReceiver, ILayerZeroUserApplicationConfig {\n /// @notice Layer Zero endpoint\n ILayerZeroEndpoint public lzEndpoint;\n\n /// @notice Maps chainIds to failed messages to retry them\n mapping(uint16 => mapping(bytes => mapping(uint64 => bytes32))) public failedMessages;\n\n /// @notice Maps chainIds to their OFT address\n mapping(uint16 => bytes) public trustedRemoteLookup;\n\n /// @notice Reference to the treasury contract to fetch access control\n address public treasury;\n\n // ================================== Events ===================================\n\n event SetTrustedRemote(uint16 _srcChainId, bytes _srcAddress);\n event MessageFailed(uint16 _srcChainId, bytes _srcAddress, uint64 _nonce, bytes _payload);\n\n // =============================== Errors ================================\n\n error NotGovernor();\n error NotGovernorOrGuardian();\n error InsufficientGas();\n error InvalidEndpoint();\n error InvalidSource();\n error InvalidCaller();\n error InvalidParams();\n error InvalidPayload();\n error ZeroAddress();\n\n // ============================= Constructor ===================================\n\n //solhint-disable-next-line\n function __LzAppUpgradeable_init(address _endpoint, address _treasury) internal {\n if (_endpoint == address(0) || _treasury == address(0)) revert ZeroAddress();\n lzEndpoint = ILayerZeroEndpoint(_endpoint);\n treasury = _treasury;\n }\n\n // =============================== Modifiers ===================================\n\n /// @notice Checks whether the `msg.sender` has the governor role or the guardian role\n modifier onlyGovernorOrGuardian() {\n if (!ITreasury(treasury).isGovernorOrGuardian(msg.sender)) revert NotGovernorOrGuardian();\n _;\n }\n\n // ==================== External Permissionless Functions ======================\n\n /// @notice Receives a message from the LZ endpoint and process it\n /// @param _srcChainId ChainId of the source chain - LayerZero standard\n /// @param _srcAddress Sender of the source chain\n /// @param _nonce Nounce of the message\n /// @param _payload Data: recipient address and amount\n function lzReceive(\n uint16 _srcChainId,\n bytes memory _srcAddress,\n uint64 _nonce,\n bytes memory _payload\n ) public virtual override {\n // lzReceive must be called by the endpoint for security\n if (msg.sender != address(lzEndpoint)) revert InvalidEndpoint();\n\n bytes memory trustedRemote = trustedRemoteLookup[_srcChainId];\n // if will still block the message pathway from (srcChainId, srcAddress). should not receive message from untrusted remote.\n if (_srcAddress.length != trustedRemote.length || keccak256(_srcAddress) != keccak256(trustedRemote))\n revert InvalidSource();\n\n _blockingLzReceive(_srcChainId, _srcAddress, _nonce, _payload);\n }\n\n /// @notice Retries a message that previously failed and was stored\n /// @param _srcChainId ChainId of the source chain - LayerZero standard\n /// @param _srcAddress Sender of the source chain\n /// @param _nonce Nounce of the message\n /// @param _payload Data: recipient address and amount\n function retryMessage(\n uint16 _srcChainId,\n bytes memory _srcAddress,\n uint64 _nonce,\n bytes memory _payload\n ) public payable virtual {\n // assert there is message to retry\n bytes32 payloadHash = failedMessages[_srcChainId][_srcAddress][_nonce];\n if (payloadHash == bytes32(0) || keccak256(_payload) != payloadHash) revert InvalidPayload();\n // clear the stored message\n failedMessages[_srcChainId][_srcAddress][_nonce] = bytes32(0);\n // execute the message. revert if it fails again\n _nonblockingLzReceive(_srcChainId, _srcAddress, _nonce, _payload);\n }\n\n // ============================= Internal Functions ===================================\n\n /// @notice Handles message receptions in a non blocking way\n /// @param _srcChainId ChainId of the source chain - LayerZero standard\n /// @param _srcAddress Sender of the source chain\n /// @param _nonce Nounce of the message\n /// @param _payload Data: recipient address and amount\n /// @dev public for the needs of try / catch but effectively internal\n function nonblockingLzReceive(\n uint16 _srcChainId,\n bytes memory _srcAddress,\n uint64 _nonce,\n bytes memory _payload\n ) public virtual {\n // only internal transaction\n if (msg.sender != address(this)) revert InvalidCaller();\n _nonblockingLzReceive(_srcChainId, _srcAddress, _nonce, _payload);\n }\n\n /// @notice Handles message receptions in a non blocking way\n /// @param _srcChainId ChainId of the source chain - LayerZero standard\n /// @param _srcAddress Sender of the source chain\n /// @param _nonce Nounce of the message\n /// @param _payload Data: recipient address and amount\n function _nonblockingLzReceive(\n uint16 _srcChainId,\n bytes memory _srcAddress,\n uint64 _nonce,\n bytes memory _payload\n ) internal virtual;\n\n /// @notice Handles message receptions in a blocking way\n /// @param _srcChainId ChainId of the source chain - LayerZero standard\n /// @param _srcAddress Sender of the source chain\n /// @param _nonce Nounce of the message\n /// @param _payload Data: recipient address and amount\n function _blockingLzReceive(\n uint16 _srcChainId,\n bytes memory _srcAddress,\n uint64 _nonce,\n bytes memory _payload\n ) internal {\n // try-catch all errors/exceptions\n try this.nonblockingLzReceive(_srcChainId, _srcAddress, _nonce, _payload) {\n // do nothing\n } catch {\n // error / exception\n failedMessages[_srcChainId][_srcAddress][_nonce] = keccak256(_payload);\n emit MessageFailed(_srcChainId, _srcAddress, _nonce, _payload);\n }\n }\n\n /// @notice Sends a message to the LZ endpoint and process it\n /// @param _dstChainId L0 defined chain id to send tokens too\n /// @param _payload Data: recipient address and amount\n /// @param _refundAddress Address LayerZero refunds if too much message fee is sent\n /// @param _zroPaymentAddress Set to address(0x0) if not paying in ZRO (LayerZero Token)\n /// @param _adapterParams Flexible bytes array to indicate messaging adapter services in L0\n function _lzSend(\n uint16 _dstChainId,\n bytes memory _payload,\n address payable _refundAddress,\n address _zroPaymentAddress,\n bytes memory _adapterParams\n ) internal virtual {\n bytes memory trustedRemote = trustedRemoteLookup[_dstChainId];\n if (trustedRemote.length == 0) revert InvalidSource();\n //solhint-disable-next-line\n lzEndpoint.send{ value: msg.value }(\n _dstChainId,\n trustedRemote,\n _payload,\n _refundAddress,\n _zroPaymentAddress,\n _adapterParams\n );\n }\n\n // ======================= Governance Functions ================================\n\n /// @notice Sets the corresponding address on an other chain.\n /// @param _srcChainId ChainId of the source chain - LayerZero standard\n /// @param _srcAddress Address on the source chain\n /// @dev Used for both receiving and sending message\n /// @dev There can only be one trusted source per chain\n /// @dev Allows owner to set it multiple times.\n function setTrustedRemote(uint16 _srcChainId, bytes calldata _srcAddress) external onlyGovernorOrGuardian {\n trustedRemoteLookup[_srcChainId] = _srcAddress;\n emit SetTrustedRemote(_srcChainId, _srcAddress);\n }\n\n /// @notice Fetches the default LZ config\n function getConfig(\n uint16 _version,\n uint16 _chainId,\n address,\n uint256 _configType\n ) external view returns (bytes memory) {\n return lzEndpoint.getConfig(_version, _chainId, address(this), _configType);\n }\n\n /// @notice Overrides the default LZ config\n function setConfig(\n uint16 _version,\n uint16 _chainId,\n uint256 _configType,\n bytes calldata _config\n ) external override onlyGovernorOrGuardian {\n lzEndpoint.setConfig(_version, _chainId, _configType, _config);\n }\n\n /// @notice Overrides the default LZ config\n function setSendVersion(uint16 _version) external override onlyGovernorOrGuardian {\n lzEndpoint.setSendVersion(_version);\n }\n\n /// @notice Overrides the default LZ config\n function setReceiveVersion(uint16 _version) external override onlyGovernorOrGuardian {\n lzEndpoint.setReceiveVersion(_version);\n }\n\n /// @notice Unpauses the receive functionalities\n function forceResumeReceive(\n uint16 _srcChainId,\n bytes calldata _srcAddress\n ) external override onlyGovernorOrGuardian {\n lzEndpoint.forceResumeReceive(_srcChainId, _srcAddress);\n }\n\n // ======================= View Functions ================================\n\n /// @notice Checks if the `_srcAddress` corresponds to the trusted source\n function isTrustedRemote(uint16 _srcChainId, bytes calldata _srcAddress) external view returns (bool) {\n bytes memory trustedSource = trustedRemoteLookup[_srcChainId];\n return keccak256(trustedSource) == keccak256(_srcAddress);\n }\n\n uint256[46] private __gap;\n}\n" + }, + "contracts/deprecated/layerZero/OldOFTCore.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.12;\n\nimport \"./OldNonblockingLzApp.sol\";\nimport \"../../agToken/layerZero/utils/IOFTCore.sol\";\nimport \"@openzeppelin/contracts-upgradeable/utils/introspection/ERC165Upgradeable.sol\";\n\n/// @title OFTCore\n/// @author Forked from https://github.com/LayerZero-Labs/solidity-examples/blob/main/contracts/token/oft/OFTCore.sol\n/// but with slight modifications from the Angle Labs, Inc. which added return values to the `_creditTo` and `_debitFrom` functions\n/// @notice Base contract for bridging using LayerZero\nabstract contract OldOFTCore is OldNonblockingLzApp, ERC165Upgradeable, IOFTCore {\n // ==================== External Permissionless Functions ======================\n\n /// @inheritdoc IOFTCore\n function sendWithPermit(\n uint16 _dstChainId,\n bytes memory _toAddress,\n uint256 _amount,\n address payable _refundAddress,\n address _zroPaymentAddress,\n bytes memory _adapterParams,\n uint256 deadline,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) public payable virtual;\n\n /// @inheritdoc IOFTCore\n function send(\n uint16 _dstChainId,\n bytes memory _toAddress,\n uint256 _amount,\n address payable _refundAddress,\n address _zroPaymentAddress,\n bytes memory _adapterParams\n ) public payable virtual {\n _amount = _debitFrom(_dstChainId, _toAddress, _amount);\n\n bytes memory payload = abi.encode(_toAddress, _amount);\n _lzSend(_dstChainId, payload, _refundAddress, _zroPaymentAddress, _adapterParams);\n\n uint64 nonce = lzEndpoint.getOutboundNonce(_dstChainId, address(this));\n emit SendToChain(msg.sender, _dstChainId, _toAddress, _amount, nonce);\n }\n\n /// @inheritdoc IOFTCore\n function sendCredit(\n uint16 _dstChainId,\n bytes memory _toAddress,\n uint256 _amount,\n address payable _refundAddress,\n address _zroPaymentAddress,\n bytes memory _adapterParams\n ) public payable virtual {\n _amount = _debitCreditFrom(_dstChainId, _toAddress, _amount);\n\n _send(_dstChainId, _toAddress, _amount, _refundAddress, _zroPaymentAddress, _adapterParams);\n }\n\n /// @inheritdoc IOFTCore\n function withdraw(uint256 amount, address recipient) external virtual returns (uint256);\n\n // =========================== Internal Functions ==============================\n\n /// @notice Internal function to send `_amount` amount of token to (`_dstChainId`, `_toAddress`)\n /// @param _dstChainId the destination chain identifier\n /// @param _toAddress can be any size depending on the `dstChainId`.\n /// @param _amount the quantity of tokens in wei\n /// @param _refundAddress the address LayerZero refunds if too much message fee is sent\n /// @param _zroPaymentAddress set to address(0x0) if not paying in ZRO (LayerZero Token)\n /// @param _adapterParams is a flexible bytes array to indicate messaging adapter services\n /// @dev Accounting and checks should be performed beforehand\n function _send(\n uint16 _dstChainId,\n bytes memory _toAddress,\n uint256 _amount,\n address payable _refundAddress,\n address _zroPaymentAddress,\n bytes memory _adapterParams\n ) internal {\n bytes memory payload = abi.encode(_toAddress, _amount);\n _lzSend(_dstChainId, payload, _refundAddress, _zroPaymentAddress, _adapterParams);\n\n uint64 nonce = lzEndpoint.getOutboundNonce(_dstChainId, address(this));\n emit SendToChain(msg.sender, _dstChainId, _toAddress, _amount, nonce);\n }\n\n function _nonblockingLzReceive(\n uint16 _srcChainId,\n bytes memory _srcAddress,\n uint64 _nonce,\n bytes memory _payload\n ) internal virtual override {\n // decode and load the toAddress\n (bytes memory toAddressBytes, uint256 amount) = abi.decode(_payload, (bytes, uint256));\n address toAddress;\n //solhint-disable-next-line\n assembly {\n toAddress := mload(add(toAddressBytes, 20))\n }\n amount = _creditTo(_srcChainId, toAddress, amount);\n\n emit ReceiveFromChain(_srcChainId, _srcAddress, toAddress, amount, _nonce);\n }\n\n /// @notice Makes accountability when bridging from this contract using canonical token\n /// @param _dstChainId ChainId of the destination chain - LayerZero standard\n /// @param _toAddress Recipient on the destination chain\n /// @param _amount Amount to bridge\n function _debitFrom(\n uint16 _dstChainId,\n bytes memory _toAddress,\n uint256 _amount\n ) internal virtual returns (uint256);\n\n /// @notice Makes accountability when bridging from this contract's credit\n /// @param _dstChainId ChainId of the destination chain - LayerZero standard\n /// @param _toAddress Recipient on the destination chain\n /// @param _amount Amount to bridge\n function _debitCreditFrom(\n uint16 _dstChainId,\n bytes memory _toAddress,\n uint256 _amount\n ) internal virtual returns (uint256);\n\n /// @notice Makes accountability when bridging to this contract\n /// @param _srcChainId ChainId of the source chain - LayerZero standard\n /// @param _toAddress Recipient on this chain\n /// @param _amount Amount to bridge\n function _creditTo(uint16 _srcChainId, address _toAddress, uint256 _amount) internal virtual returns (uint256);\n\n // ========================== View Functions ===================================\n\n /// @inheritdoc ERC165Upgradeable\n function supportsInterface(\n bytes4 interfaceId\n ) public view virtual override(ERC165Upgradeable, IERC165) returns (bool) {\n return interfaceId == type(IOFTCore).interfaceId || super.supportsInterface(interfaceId);\n }\n\n /// @inheritdoc IOFTCore\n function estimateSendFee(\n uint16 _dstChainId,\n bytes memory _toAddress,\n uint256 _amount,\n bool _useZro,\n bytes memory _adapterParams\n ) public view virtual override returns (uint256 nativeFee, uint256 zroFee) {\n // mock the payload for send()\n bytes memory payload = abi.encode(_toAddress, _amount);\n return lzEndpoint.estimateFees(_dstChainId, address(this), payload, _useZro, _adapterParams);\n }\n\n uint256[50] private __gap;\n}\n" + }, + "contracts/deprecated/OldAgEUR.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\nimport \"../interfaces/IAgToken.sol\";\nimport \"../interfaces/coreModule/IStableMaster.sol\";\nimport \"../interfaces/ITreasury.sol\";\n// OpenZeppelin may update its version of the ERC20PermitUpgradeable token\nimport \"@openzeppelin/contracts-upgradeable/token/ERC20/extensions/draft-ERC20PermitUpgradeable.sol\";\n\n/// @title AgToken\n/// @author Angle Labs, Inc.\n/// @notice Base contract for agToken, that is to say Angle's stablecoins\n/// @dev This contract is used to create and handle the stablecoins of Angle protocol\n/// @dev It is still possible for any address to burn its agTokens without redeeming collateral in exchange\n/// @dev This contract is the upgraded version of the AgToken that was first deployed on Ethereum mainnet\ncontract OldAgEUR is IAgToken, ERC20PermitUpgradeable {\n // ========================= References to other contracts =====================\n\n /// @notice Reference to the `StableMaster` contract associated to this `AgToken`\n address public stableMaster;\n\n // ============================= Constructor ===================================\n\n /// @notice Initializes the `AgToken` contract\n /// @param name_ Name of the token\n /// @param symbol_ Symbol of the token\n /// @param stableMaster_ Reference to the `StableMaster` contract associated to this agToken\n /// @dev By default, agTokens are ERC-20 tokens with 18 decimals\n function initialize(string memory name_, string memory symbol_, address stableMaster_) external initializer {\n __ERC20Permit_init(name_);\n __ERC20_init(name_, symbol_);\n require(stableMaster_ != address(0), \"0\");\n stableMaster = stableMaster_;\n }\n\n /// @custom:oz-upgrades-unsafe-allow constructor\n constructor() initializer {}\n\n // ======= Added Parameters and Variables from the first implementation ========\n\n /// @inheritdoc IAgToken\n mapping(address => bool) public isMinter;\n /// @notice Reference to the treasury contract which can grant minting rights\n address public treasury;\n /// @notice Boolean to check whether the contract has been reinitialized after its upgrade\n bool public treasuryInitialized;\n\n // =============================== Added Events ================================\n\n event TreasuryUpdated(address indexed _treasury);\n event MinterToggled(address indexed minter);\n\n // =============================== Added Errors ================================\n\n error BurnAmountExceedsAllowance();\n error InvalidSender();\n error InvalidTreasury();\n error NotGovernor();\n error NotMinter();\n error NotTreasury();\n error TreasuryAlreadyInitialized();\n\n // =============================== Setup Function ==============================\n\n /// @notice Sets up the treasury contract in this AgToken contract\n /// @param _treasury Treasury contract to add\n /// @dev The address calling this function has to be hard-coded in the contract\n /// @dev Can be called only once\n function setUpTreasury(address _treasury) external {\n // Only governor\n if (msg.sender != 0xdC4e6DFe07EFCa50a197DF15D9200883eF4Eb1c8) revert NotGovernor();\n if (address(ITreasury(_treasury).stablecoin()) != address(this)) revert InvalidTreasury();\n if (treasuryInitialized) revert TreasuryAlreadyInitialized();\n treasury = _treasury;\n treasuryInitialized = true;\n isMinter[stableMaster] = true;\n emit TreasuryUpdated(_treasury);\n }\n\n // =============================== Modifiers ===================================\n\n /// @notice Checks to see if it is the `Treasury` calling this contract\n /// @dev There is no Access Control here, because it can be handled cheaply through this modifier\n modifier onlyTreasury() {\n if (msg.sender != treasury) revert NotTreasury();\n _;\n }\n\n /// @notice Checks whether the sender has the minting right\n modifier onlyMinter() {\n if (!isMinter[msg.sender]) revert NotMinter();\n _;\n }\n\n // ========================= External Functions ================================\n // The following functions allow anyone to burn stablecoins without redeeming collateral\n // in exchange for that\n\n /// @notice Destroys `amount` token from the caller without giving collateral back\n /// @param amount Amount to burn\n /// @param poolManager Reference to the `PoolManager` contract for which the `stocksUsers` will\n /// need to be updated\n /// @dev When calling this function, people should specify the `poolManager` for which they want to decrease\n /// the `stocksUsers`: this is a way for the protocol to maintain healthy accounting variables\n function burnNoRedeem(uint256 amount, address poolManager) external {\n _burn(msg.sender, amount);\n IStableMaster(stableMaster).updateStocksUsers(amount, poolManager);\n }\n\n /// @notice Burns `amount` of agToken on behalf of another account without redeeming collateral back\n /// @param account Account to burn on behalf of\n /// @param amount Amount to burn\n /// @param poolManager Reference to the `PoolManager` contract for which the `stocksUsers` will need to be updated\n function burnFromNoRedeem(address account, uint256 amount, address poolManager) external {\n _burnFromNoRedeem(amount, account, msg.sender);\n IStableMaster(stableMaster).updateStocksUsers(amount, poolManager);\n }\n\n /// @notice Allows anyone to burn agToken without redeeming collateral back\n /// @param amount Amount of stablecoins to burn\n /// @dev This function can typically be called if there is a settlement mechanism to burn stablecoins\n function burnStablecoin(uint256 amount) external {\n _burn(msg.sender, amount);\n }\n\n // ======================= Minter Role Only Functions ==========================\n\n /// @inheritdoc IAgToken\n function burnSelf(uint256 amount, address burner) external onlyMinter {\n _burn(burner, amount);\n }\n\n /// @inheritdoc IAgToken\n function burnFrom(uint256 amount, address burner, address sender) external onlyMinter {\n _burnFromNoRedeem(amount, burner, sender);\n }\n\n /// @inheritdoc IAgToken\n function mint(address account, uint256 amount) external onlyMinter {\n _mint(account, amount);\n }\n\n // ======================= Treasury Only Functions =============================\n\n /// @inheritdoc IAgToken\n function addMinter(address minter) external onlyTreasury {\n isMinter[minter] = true;\n emit MinterToggled(minter);\n }\n\n /// @inheritdoc IAgToken\n function removeMinter(address minter) external {\n // The `treasury` contract cannot remove the `stableMaster`\n if (msg.sender != minter && (msg.sender != address(treasury) || minter == stableMaster)) revert InvalidSender();\n isMinter[minter] = false;\n emit MinterToggled(minter);\n }\n\n /// @inheritdoc IAgToken\n function setTreasury(address _treasury) external onlyTreasury {\n treasury = _treasury;\n emit TreasuryUpdated(_treasury);\n }\n\n // ============================ Internal Function ==============================\n\n /// @notice Internal version of the function `burnFromNoRedeem`\n /// @param amount Amount to burn\n /// @dev It is at the level of this function that allowance checks are performed\n function _burnFromNoRedeem(uint256 amount, address burner, address sender) internal {\n if (burner != sender) {\n uint256 currentAllowance = allowance(burner, sender);\n if (currentAllowance < amount) revert BurnAmountExceedsAllowance();\n _approve(burner, sender, currentAllowance - amount);\n }\n _burn(burner, amount);\n }\n}\n" + }, + "contracts/deprecated/OldAngleHelpers.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\nimport \"../interfaces/IAngleRouter.sol\";\nimport \"../interfaces/coreModule/IAgTokenMainnet.sol\";\nimport \"../interfaces/coreModule/ICore.sol\";\nimport \"../interfaces/coreModule/IOracleCore.sol\";\nimport \"../interfaces/coreModule/IPerpetualManager.sol\";\nimport \"../interfaces/coreModule/IPoolManager.sol\";\nimport \"../interfaces/coreModule/IStableMaster.sol\";\nimport \"@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol\";\nimport \"../interfaces/IVaultManager.sol\";\n\npragma solidity ^0.8.12;\n\nstruct Parameters {\n SLPData slpData;\n MintBurnData feeData;\n PerpetualManagerFeeData perpFeeData;\n PerpetualManagerParamData perpParam;\n}\n\nstruct PerpetualManagerFeeData {\n uint64[] xHAFeesDeposit;\n uint64[] yHAFeesDeposit;\n uint64[] xHAFeesWithdraw;\n uint64[] yHAFeesWithdraw;\n uint64 haBonusMalusDeposit;\n uint64 haBonusMalusWithdraw;\n}\n\nstruct PerpetualManagerParamData {\n uint64 maintenanceMargin;\n uint64 maxLeverage;\n uint64 targetHAHedge;\n uint64 limitHAHedge;\n uint64 lockTime;\n}\n\nstruct CollateralAddresses {\n address stableMaster;\n address poolManager;\n address perpetualManager;\n address sanToken;\n address oracle;\n address gauge;\n address feeManager;\n address[] strategies;\n}\n\n/// @title AngleHelpers\n/// @author Angle Labs, Inc.\n/// @notice Contract with view functions designed to facilitate integrations on the Core module of the Angle Protocol\n/// @dev This contract only contains view functions to be queried off-chain. It was thus not optimized for gas consumption\ncontract OldAngleHelpers is Initializable {\n // ======================== Helper View Functions ==============================\n\n /// @notice Gives the amount of `agToken` you'd be getting if you were executing in the same block a mint transaction\n /// with `amount` of `collateral` in the Core module of the Angle protocol as well as the value of the fees\n /// (in `BASE_PARAMS`) that would be applied during the mint\n /// @return Amount of `agToken` that would be obtained with a mint transaction in the same block\n /// @return Percentage of fees that would be taken during a mint transaction in the same block\n /// @dev This function reverts if the mint transaction was to revert in the same conditions (without taking into account\n /// potential approval problems to the `StableMaster` contract)\n function previewMintAndFees(\n uint256 amount,\n address agToken,\n address collateral\n ) external view returns (uint256, uint256) {\n return _previewMintAndFees(amount, agToken, collateral);\n }\n\n /// @notice Gives the amount of `collateral` you'd be getting if you were executing in the same block a burn transaction\n /// with `amount` of `agToken` in the Core module of the Angle protocol as well as the value of the fees\n /// (in `BASE_PARAMS`) that would be applied during the burn\n /// @return Amount of `collateral` that would be obtained with a burn transaction in the same block\n /// @return Percentage of fees that would be taken during a burn transaction in the same block\n /// @dev This function reverts if the burn transaction was to revert in the same conditions (without taking into account\n /// potential approval problems to the `StableMaster` contract or agToken balance prior to the call)\n function previewBurnAndFees(\n uint256 amount,\n address agToken,\n address collateral\n ) external view returns (uint256, uint256) {\n return _previewBurnAndFees(amount, agToken, collateral);\n }\n\n /// @notice Returns all the addresses associated to the (`agToken`,`collateral`) pair given\n /// @return addresses A struct with all the addresses associated in the Core module\n function getCollateralAddresses(\n address agToken,\n address collateral\n ) external view returns (CollateralAddresses memory addresses) {\n address stableMaster = IAgTokenMainnet(agToken).stableMaster();\n (address poolManager, address perpetualManager, address sanToken, address gauge) = ROUTER.mapPoolManagers(\n stableMaster,\n collateral\n );\n (, , , IOracleCore oracle, , , , , ) = IStableMaster(stableMaster).collateralMap(poolManager);\n addresses.stableMaster = stableMaster;\n addresses.poolManager = poolManager;\n addresses.perpetualManager = perpetualManager;\n addresses.sanToken = sanToken;\n addresses.gauge = gauge;\n addresses.oracle = address(oracle);\n addresses.feeManager = IPoolManager(poolManager).feeManager();\n\n uint256 length = 0;\n while (true) {\n try IPoolManager(poolManager).strategyList(length) returns (address) {\n length += 1;\n } catch {\n break;\n }\n }\n address[] memory strategies = new address[](length);\n for (uint256 i; i < length; ++i) {\n strategies[i] = IPoolManager(poolManager).strategyList(i);\n }\n addresses.strategies = strategies;\n }\n\n /// @notice Gets the addresses of all the `StableMaster` contracts and their associated `AgToken` addresses\n /// @return List of the `StableMaster` addresses of the Angle protocol\n /// @return List of the `AgToken` addresses of the protocol\n /// @dev The place of an agToken address in the list is the same as the corresponding `StableMaster` address\n function getStablecoinAddresses() external view returns (address[] memory, address[] memory) {\n address[] memory stableMasterAddresses = CORE.stablecoinList();\n address[] memory agTokenAddresses = new address[](stableMasterAddresses.length);\n for (uint256 i; i < stableMasterAddresses.length; ++i) {\n agTokenAddresses[i] = IStableMaster(stableMasterAddresses[i]).agToken();\n }\n return (stableMasterAddresses, agTokenAddresses);\n }\n\n /// @notice Returns most of the governance parameters associated to the (`agToken`,`collateral`) pair given\n /// @return params Struct with most of the parameters in the `StableMaster` and `PerpetualManager` contracts\n /// @dev Check out the struct `Parameters` for the meaning of the return values\n function getCollateralParameters(\n address agToken,\n address collateral\n ) external view returns (Parameters memory params) {\n (address stableMaster, address poolManager) = _getStableMasterAndPoolManager(agToken, collateral);\n (\n ,\n ,\n IPerpetualManager perpetualManager,\n ,\n ,\n ,\n ,\n SLPData memory slpData,\n MintBurnData memory feeData\n ) = IStableMaster(stableMaster).collateralMap(poolManager);\n\n params.slpData = slpData;\n params.feeData = feeData;\n params.perpParam.maintenanceMargin = perpetualManager.maintenanceMargin();\n params.perpParam.maxLeverage = perpetualManager.maxLeverage();\n params.perpParam.targetHAHedge = perpetualManager.targetHAHedge();\n params.perpParam.limitHAHedge = perpetualManager.limitHAHedge();\n params.perpParam.lockTime = perpetualManager.lockTime();\n\n params.perpFeeData.haBonusMalusDeposit = perpetualManager.haBonusMalusDeposit();\n params.perpFeeData.haBonusMalusWithdraw = perpetualManager.haBonusMalusWithdraw();\n\n uint256 length = 0;\n while (true) {\n try perpetualManager.xHAFeesDeposit(length) returns (uint64) {\n length += 1;\n } catch {\n break;\n }\n }\n uint64[] memory data = new uint64[](length);\n uint64[] memory data2 = new uint64[](length);\n for (uint256 i; i < length; ++i) {\n data[i] = perpetualManager.xHAFeesDeposit(i);\n data2[i] = perpetualManager.yHAFeesDeposit(i);\n }\n params.perpFeeData.xHAFeesDeposit = data;\n params.perpFeeData.yHAFeesDeposit = data2;\n\n length = 0;\n while (true) {\n try perpetualManager.xHAFeesWithdraw(length) returns (uint64) {\n length += 1;\n } catch {\n break;\n }\n }\n data = new uint64[](length);\n data2 = new uint64[](length);\n for (uint256 i; i < length; ++i) {\n data[i] = perpetualManager.xHAFeesWithdraw(i);\n data2[i] = perpetualManager.yHAFeesWithdraw(i);\n }\n params.perpFeeData.xHAFeesWithdraw = data;\n params.perpFeeData.yHAFeesWithdraw = data2;\n }\n\n /// @notice Returns the address of the poolManager associated to an (`agToken`, `collateral`) pair\n /// in the Core module of the protocol\n function getPoolManager(address agToken, address collateral) public view returns (address poolManager) {\n (, poolManager) = _getStableMasterAndPoolManager(agToken, collateral);\n }\n\n // ======================== Replica Functions ==================================\n // These replicate what is done in the other contracts of the protocol\n\n function _previewBurnAndFees(\n uint256 amount,\n address agToken,\n address collateral\n ) internal view returns (uint256 amountForUserInCollat, uint256 feePercent) {\n (address stableMaster, address poolManager) = _getStableMasterAndPoolManager(agToken, collateral);\n (\n address token,\n ,\n IPerpetualManager perpetualManager,\n IOracleCore oracle,\n uint256 stocksUsers,\n ,\n uint256 collatBase,\n ,\n MintBurnData memory feeData\n ) = IStableMaster(stableMaster).collateralMap(poolManager);\n if (token == address(0) || IStableMaster(stableMaster).paused(keccak256(abi.encodePacked(STABLE, poolManager))))\n revert NotInitialized();\n if (amount > stocksUsers) revert InvalidAmount();\n\n if (feeData.xFeeBurn.length == 1) {\n feePercent = feeData.yFeeBurn[0];\n } else {\n bytes memory data = abi.encode(address(perpetualManager), feeData.targetHAHedge);\n uint64 hedgeRatio = _computeHedgeRatio(stocksUsers - amount, data);\n feePercent = _piecewiseLinear(hedgeRatio, feeData.xFeeBurn, feeData.yFeeBurn);\n }\n feePercent = (feePercent * feeData.bonusMalusBurn) / BASE_PARAMS;\n\n amountForUserInCollat = (amount * (BASE_PARAMS - feePercent) * collatBase) / (oracle.readUpper() * BASE_PARAMS);\n }\n\n function _previewMintAndFees(\n uint256 amount,\n address agToken,\n address collateral\n ) internal view returns (uint256 amountForUserInStable, uint256 feePercent) {\n (address stableMaster, address poolManager) = _getStableMasterAndPoolManager(agToken, collateral);\n (\n address token,\n ,\n IPerpetualManager perpetualManager,\n IOracleCore oracle,\n uint256 stocksUsers,\n ,\n ,\n ,\n MintBurnData memory feeData\n ) = IStableMaster(stableMaster).collateralMap(poolManager);\n if (token == address(0) || IStableMaster(stableMaster).paused(keccak256(abi.encodePacked(STABLE, poolManager))))\n revert NotInitialized();\n\n amountForUserInStable = oracle.readQuoteLower(amount);\n\n if (feeData.xFeeMint.length == 1) feePercent = feeData.yFeeMint[0];\n else {\n bytes memory data = abi.encode(address(perpetualManager), feeData.targetHAHedge);\n uint64 hedgeRatio = _computeHedgeRatio(amountForUserInStable + stocksUsers, data);\n feePercent = _piecewiseLinear(hedgeRatio, feeData.xFeeMint, feeData.yFeeMint);\n }\n feePercent = (feePercent * feeData.bonusMalusMint) / BASE_PARAMS;\n\n amountForUserInStable = (amountForUserInStable * (BASE_PARAMS - feePercent)) / BASE_PARAMS;\n if (stocksUsers + amountForUserInStable > feeData.capOnStableMinted) revert InvalidAmount();\n }\n\n // ======================== Utility Functions ==================================\n // These utility functions are taken from other contracts of the protocol\n\n function _computeHedgeRatio(uint256 newStocksUsers, bytes memory data) internal view returns (uint64 ratio) {\n (address perpetualManager, uint64 targetHAHedge) = abi.decode(data, (address, uint64));\n uint256 totalHedgeAmount = IPerpetualManager(perpetualManager).totalHedgeAmount();\n newStocksUsers = (targetHAHedge * newStocksUsers) / BASE_PARAMS;\n if (newStocksUsers > totalHedgeAmount) ratio = uint64((totalHedgeAmount * BASE_PARAMS) / newStocksUsers);\n else ratio = uint64(BASE_PARAMS);\n }\n\n function _piecewiseLinear(uint64 x, uint64[] memory xArray, uint64[] memory yArray) internal pure returns (uint64) {\n if (x >= xArray[xArray.length - 1]) {\n return yArray[xArray.length - 1];\n } else if (x <= xArray[0]) {\n return yArray[0];\n } else {\n uint256 lower;\n uint256 upper = xArray.length - 1;\n uint256 mid;\n while (upper - lower > 1) {\n mid = lower + (upper - lower) / 2;\n if (xArray[mid] <= x) {\n lower = mid;\n } else {\n upper = mid;\n }\n }\n if (yArray[upper] > yArray[lower]) {\n return\n yArray[lower] +\n ((yArray[upper] - yArray[lower]) * (x - xArray[lower])) /\n (xArray[upper] - xArray[lower]);\n } else {\n return\n yArray[lower] -\n ((yArray[lower] - yArray[upper]) * (x - xArray[lower])) /\n (xArray[upper] - xArray[lower]);\n }\n }\n }\n\n function _getStableMasterAndPoolManager(\n address agToken,\n address collateral\n ) internal view returns (address stableMaster, address poolManager) {\n stableMaster = IAgTokenMainnet(agToken).stableMaster();\n (poolManager, , , ) = ROUTER.mapPoolManagers(stableMaster, collateral);\n }\n\n // ====================== Constants and Initializers ===========================\n\n IAngleRouter public constant ROUTER = IAngleRouter(0xBB755240596530be0c1DE5DFD77ec6398471561d);\n ICore public constant CORE = ICore(0x61ed74de9Ca5796cF2F8fD60D54160D47E30B7c3);\n\n bytes32 public constant STABLE = keccak256(\"STABLE\");\n uint256 public constant BASE_PARAMS = 10 ** 9;\n\n error NotInitialized();\n error InvalidAmount();\n\n /// @custom:oz-upgrades-unsafe-allow constructor\n constructor() initializer {}\n}\n" + }, + "contracts/deprecated/vaultManager/OldVaultManagerERC721.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\nimport \"./OldVaultManagerStorage.sol\";\n\n/// @title VaultManagerERC721\n/// @author Angle Labs, Inc.\n/// @dev Base ERC721 Implementation of VaultManager\nabstract contract OldVaultManagerERC721 is IERC721MetadataUpgradeable, OldVaultManagerStorage {\n using SafeERC20 for IERC20;\n using Address for address;\n\n /// @inheritdoc IERC721MetadataUpgradeable\n string public name;\n /// @inheritdoc IERC721MetadataUpgradeable\n string public symbol;\n\n // ================================= MODIFIERS =================================\n\n /// @notice Checks if the person interacting with the vault with `vaultID` is approved\n /// @param caller Address of the person seeking to interact with the vault\n /// @param vaultID ID of the concerned vault\n modifier onlyApprovedOrOwner(address caller, uint256 vaultID) {\n if (!_isApprovedOrOwner(caller, vaultID)) revert NotApproved();\n _;\n }\n\n // ================================ ERC721 LOGIC ===============================\n\n /// @notice Checks whether a given address is approved for a vault or owns this vault\n /// @param spender Address for which vault ownership should be checked\n /// @param vaultID ID of the vault to check\n /// @return Whether the `spender` address owns or is approved for `vaultID`\n function isApprovedOrOwner(address spender, uint256 vaultID) external view returns (bool) {\n return _isApprovedOrOwner(spender, vaultID);\n }\n\n /// @inheritdoc IERC721MetadataUpgradeable\n function tokenURI(uint256 vaultID) external view returns (string memory) {\n if (!_exists(vaultID)) revert NonexistentVault();\n // There is no vault with `vaultID` equal to 0, so the following variable is\n // always greater than zero\n uint256 temp = vaultID;\n uint256 digits;\n while (temp != 0) {\n digits++;\n temp /= 10;\n }\n bytes memory buffer = new bytes(digits);\n while (vaultID != 0) {\n digits -= 1;\n buffer[digits] = bytes1(uint8(48 + uint256(vaultID % 10)));\n vaultID /= 10;\n }\n return bytes(_baseURI).length > 0 ? string(abi.encodePacked(_baseURI, string(buffer))) : \"\";\n }\n\n /// @inheritdoc IERC721Upgradeable\n function balanceOf(address owner) external view returns (uint256) {\n if (owner == address(0)) revert ZeroAddress();\n return _balances[owner];\n }\n\n /// @inheritdoc IERC721Upgradeable\n function ownerOf(uint256 vaultID) external view returns (address) {\n return _ownerOf(vaultID);\n }\n\n /// @inheritdoc IERC721Upgradeable\n function approve(address to, uint256 vaultID) external {\n address owner = _ownerOf(vaultID);\n if (to == owner) revert ApprovalToOwner();\n if (msg.sender != owner && !isApprovedForAll(owner, msg.sender)) revert NotApproved();\n\n _approve(to, vaultID);\n }\n\n /// @inheritdoc IERC721Upgradeable\n function getApproved(uint256 vaultID) external view returns (address) {\n if (!_exists(vaultID)) revert NonexistentVault();\n return _getApproved(vaultID);\n }\n\n /// @inheritdoc IERC721Upgradeable\n function setApprovalForAll(address operator, bool approved) external {\n _setApprovalForAll(msg.sender, operator, approved);\n }\n\n /// @inheritdoc IERC721Upgradeable\n function isApprovedForAll(address owner, address operator) public view returns (bool) {\n return _operatorApprovals[owner][operator] == 1;\n }\n\n /// @inheritdoc IERC721Upgradeable\n function transferFrom(address from, address to, uint256 vaultID) external onlyApprovedOrOwner(msg.sender, vaultID) {\n _transfer(from, to, vaultID);\n }\n\n /// @inheritdoc IERC721Upgradeable\n function safeTransferFrom(address from, address to, uint256 vaultID) external {\n safeTransferFrom(from, to, vaultID, \"\");\n }\n\n /// @inheritdoc IERC721Upgradeable\n function safeTransferFrom(\n address from,\n address to,\n uint256 vaultID,\n bytes memory _data\n ) public onlyApprovedOrOwner(msg.sender, vaultID) {\n _safeTransfer(from, to, vaultID, _data);\n }\n\n // ================================ ERC165 LOGIC ===============================\n\n /// @inheritdoc IERC165Upgradeable\n function supportsInterface(bytes4 interfaceId) external pure returns (bool) {\n return\n interfaceId == type(IERC721MetadataUpgradeable).interfaceId ||\n interfaceId == type(IERC721Upgradeable).interfaceId ||\n interfaceId == type(IVaultManager).interfaceId ||\n interfaceId == type(IERC165Upgradeable).interfaceId;\n }\n\n // ================== INTERNAL FUNCTIONS FOR THE ERC721 LOGIC ==================\n\n /// @notice Internal version of the `ownerOf` function\n function _ownerOf(uint256 vaultID) internal view returns (address owner) {\n owner = _owners[vaultID];\n if (owner == address(0)) revert NonexistentVault();\n }\n\n /// @notice Internal version of the `getApproved` function\n function _getApproved(uint256 vaultID) internal view returns (address) {\n return _vaultApprovals[vaultID];\n }\n\n /// @notice Internal version of the `safeTransferFrom` function (with the data parameter)\n function _safeTransfer(address from, address to, uint256 vaultID, bytes memory _data) internal {\n _transfer(from, to, vaultID);\n if (!_checkOnERC721Received(from, to, vaultID, _data)) revert NonERC721Receiver();\n }\n\n /// @notice Checks whether a vault exists\n /// @param vaultID ID of the vault to check\n /// @return Whether `vaultID` has been created\n function _exists(uint256 vaultID) internal view returns (bool) {\n return _owners[vaultID] != address(0);\n }\n\n /// @notice Internal version of the `isApprovedOrOwner` function\n function _isApprovedOrOwner(address spender, uint256 vaultID) internal view returns (bool) {\n // The following checks if the vault exists\n address owner = _ownerOf(vaultID);\n return (spender == owner || _getApproved(vaultID) == spender || _operatorApprovals[owner][spender] == 1);\n }\n\n /// @notice Internal version of the `createVault` function\n /// Mints `vaultID` and transfers it to `to`\n /// @dev This method is equivalent to the `_safeMint` method used in OpenZeppelin ERC721 contract\n /// @dev Emits a {Transfer} event\n function _mint(address to) internal returns (uint256 vaultID) {\n if (whitelistingActivated && (isWhitelisted[to] != 1 || isWhitelisted[msg.sender] != 1))\n revert NotWhitelisted();\n if (to == address(0)) revert ZeroAddress();\n\n unchecked {\n vaultIDCount += 1;\n }\n\n vaultID = vaultIDCount;\n _beforeTokenTransfer(address(0), to, vaultID);\n\n unchecked {\n _balances[to] += 1;\n }\n\n _owners[vaultID] = to;\n emit Transfer(address(0), to, vaultID);\n if (!_checkOnERC721Received(address(0), to, vaultID, \"\")) revert NonERC721Receiver();\n }\n\n /// @notice Destroys `vaultID`\n /// @dev `vaultID` must exist\n /// @dev Emits a {Transfer} event\n function _burn(uint256 vaultID) internal {\n address owner = _ownerOf(vaultID);\n\n _beforeTokenTransfer(owner, address(0), vaultID);\n // Clear approvals\n _approve(address(0), vaultID);\n // The following line cannot underflow as the owner's balance is necessarily\n // greater than 1\n unchecked {\n _balances[owner] -= 1;\n }\n delete _owners[vaultID];\n delete vaultData[vaultID];\n\n emit Transfer(owner, address(0), vaultID);\n }\n\n /// @notice Transfers `vaultID` from `from` to `to` as opposed to {transferFrom},\n /// this imposes no restrictions on msg.sender\n /// @dev `to` cannot be the zero address and `perpetualID` must be owned by `from`\n /// @dev Emits a {Transfer} event\n /// @dev A whitelist check is performed if necessary on the `to` address\n function _transfer(address from, address to, uint256 vaultID) internal {\n if (_ownerOf(vaultID) != from) revert NotApproved();\n if (to == address(0)) revert ZeroAddress();\n if (whitelistingActivated && isWhitelisted[to] != 1) revert NotWhitelisted();\n\n _beforeTokenTransfer(from, to, vaultID);\n\n // Clear approvals from the previous owner\n _approve(address(0), vaultID);\n unchecked {\n _balances[from] -= 1;\n _balances[to] += 1;\n }\n _owners[vaultID] = to;\n\n emit Transfer(from, to, vaultID);\n }\n\n /// @notice Approves `to` to operate on `vaultID`\n function _approve(address to, uint256 vaultID) internal {\n _vaultApprovals[vaultID] = to;\n emit Approval(_ownerOf(vaultID), to, vaultID);\n }\n\n /// @notice Internal version of the `setApprovalForAll` function\n /// @dev It contains an `approver` field to be used in case someone signs a permit for a particular\n /// address, and this signature is given to the contract by another address (like a router)\n function _setApprovalForAll(address approver, address operator, bool approved) internal {\n if (operator == approver) revert ApprovalToCaller();\n uint256 approval = approved ? 1 : 0;\n _operatorApprovals[approver][operator] = approval;\n emit ApprovalForAll(approver, operator, approved);\n }\n\n /// @notice Internal function to invoke {IERC721Receiver-onERC721Received} on a target address\n /// The call is not executed if the target address is not a contract\n /// @param from Address representing the previous owner of the given token ID\n /// @param to Target address that will receive the tokens\n /// @param vaultID ID of the token to be transferred\n /// @param _data Bytes optional data to send along with the call\n /// @return Bool whether the call correctly returned the expected value\n function _checkOnERC721Received(\n address from,\n address to,\n uint256 vaultID,\n bytes memory _data\n ) private returns (bool) {\n if (to.isContract()) {\n try IERC721ReceiverUpgradeable(to).onERC721Received(msg.sender, from, vaultID, _data) returns (\n bytes4 retval\n ) {\n return retval == IERC721ReceiverUpgradeable.onERC721Received.selector;\n } catch (bytes memory reason) {\n if (reason.length == 0) {\n revert NonERC721Receiver();\n } else {\n // solhint-disable-next-line no-inline-assembly\n assembly {\n revert(add(32, reason), mload(reason))\n }\n }\n }\n } else {\n return true;\n }\n }\n\n /// @notice Hook that is called before any token transfer. This includes minting and burning.\n /// Calling conditions:\n ///\n /// - When `from` and `to` are both non-zero, `from`'s `vaultID` will be\n /// transferred to `to`.\n /// - When `from` is zero, `vaultID` will be minted for `to`.\n /// - When `to` is zero, `from`'s `vaultID` will be burned.\n /// - `from` and `to` are never both zero.\n function _beforeTokenTransfer(address from, address to, uint256 vaultID) internal virtual {}\n}\n" + }, + "contracts/deprecated/vaultManager/OldVaultManagerPermit.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\nimport \"./OldVaultManagerERC721.sol\";\nimport \"../../interfaces/external/IERC1271.sol\";\n\n/// @title VaultManagerPermit\n/// @author Angle Labs, Inc.\n/// @dev Base Implementation of permit functions for the `VaultManager` contract\nabstract contract OldVaultManagerPermit is Initializable, OldVaultManagerERC721 {\n using Address for address;\n\n mapping(address => uint256) private _nonces;\n /* solhint-disable var-name-mixedcase */\n bytes32 private _HASHED_NAME;\n bytes32 private _HASHED_VERSION;\n bytes32 private _PERMIT_TYPEHASH;\n /* solhint-enable var-name-mixedcase */\n\n error ExpiredDeadline();\n error InvalidSignature();\n\n //solhint-disable-next-line\n function __ERC721Permit_init(string memory _name) internal onlyInitializing {\n _PERMIT_TYPEHASH = keccak256(\n \"Permit(address owner,address spender,bool approved,uint256 nonce,uint256 deadline)\"\n );\n _HASHED_NAME = keccak256(bytes(_name));\n _HASHED_VERSION = keccak256(bytes(\"1\"));\n }\n\n /// @notice Allows an address to give or revoke approval for all its vaults to another address\n /// @param owner Address signing the permit and giving (or revoking) its approval for all the controlled vaults\n /// @param spender Address to give approval to\n /// @param approved Whether to give or revoke the approval\n /// @param deadline Deadline parameter for the signature to be valid\n /// @dev The `v`, `r`, and `s` parameters are used as signature data\n function permit(\n address owner,\n address spender,\n bool approved,\n uint256 deadline,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) external {\n if (block.timestamp > deadline) revert ExpiredDeadline();\n // Additional signature checks performed in the `ECDSAUpgradeable.recover` function\n if (uint256(s) > 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D576E7357A4501DDFE92F46681B20A0 || (v != 27 && v != 28))\n revert InvalidSignature();\n\n bytes32 digest = keccak256(\n abi.encodePacked(\n \"\\x19\\x01\",\n _domainSeparatorV4(),\n keccak256(\n abi.encode(\n _PERMIT_TYPEHASH,\n // 0x3f43a9c6bafb5c7aab4e0cfe239dc5d4c15caf0381c6104188191f78a6640bd8,\n owner,\n spender,\n approved,\n _useNonce(owner),\n deadline\n )\n )\n )\n );\n if (owner.isContract()) {\n if (IERC1271(owner).isValidSignature(digest, abi.encodePacked(r, s, v)) != 0x1626ba7e)\n revert InvalidSignature();\n } else {\n address signer = ecrecover(digest, v, r, s);\n if (signer != owner || signer == address(0)) revert InvalidSignature();\n }\n\n _setApprovalForAll(owner, spender, approved);\n }\n\n /// @notice Returns the current nonce for an `owner` address\n function nonces(address owner) public view returns (uint256) {\n return _nonces[owner];\n }\n\n /// @notice Returns the domain separator for the current chain.\n // solhint-disable-next-line func-name-mixedcase\n function DOMAIN_SEPARATOR() external view returns (bytes32) {\n return _domainSeparatorV4();\n }\n\n /// @notice Internal version of the `DOMAIN_SEPARATOR` function\n function _domainSeparatorV4() internal view returns (bytes32) {\n return\n keccak256(\n abi.encode(\n // keccak256('EIP712Domain(string name,string version,uint256 chainId,address verifyingContract)')\n 0x8b73c3c69bb8fe3d512ecc4cf759cc79239f7b179b0ffacaa9a75d522b39400f,\n _HASHED_NAME,\n _HASHED_VERSION,\n block.chainid,\n address(this)\n )\n );\n }\n\n /// @notice Consumes a nonce for an address: returns the current value and increments it\n function _useNonce(address owner) internal returns (uint256 current) {\n current = _nonces[owner];\n _nonces[owner] = current + 1;\n }\n\n uint256[49] private __gap;\n}\n" + }, + "contracts/deprecated/vaultManager/OldVaultManagerStorage.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\nimport \"@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/token/ERC20/extensions/draft-IERC20PermitUpgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/token/ERC721/IERC721ReceiverUpgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/interfaces/IERC721MetadataUpgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/utils/introspection/IERC165Upgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/utils/AddressUpgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/security/ReentrancyGuardUpgradeable.sol\";\nimport \"@openzeppelin/contracts/token/ERC20/extensions/IERC20Metadata.sol\";\nimport \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\nimport \"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\";\n\nimport \"../../interfaces/IAgToken.sol\";\nimport \"../../interfaces/IOracle.sol\";\nimport \"../../interfaces/ISwapper.sol\";\nimport \"../../interfaces/ITreasury.sol\";\nimport \"../../interfaces/IVaultManager.sol\";\nimport \"../../interfaces/governance/IVeBoostProxy.sol\";\n\n/// @title VaultManagerStorage\n/// @author Angle Labs, Inc.\n/// @dev Variables, references, parameters and events needed in the `VaultManager` contract\n// solhint-disable-next-line max-states-count\ncontract OldVaultManagerStorage is IVaultManagerStorage, Initializable, ReentrancyGuardUpgradeable {\n /// @notice Base used for parameter computation: almost all the parameters of this contract are set in `BASE_PARAMS`\n uint256 public constant BASE_PARAMS = 10 ** 9;\n /// @notice Base used for interest rate computation\n uint256 public constant BASE_INTEREST = 10 ** 27;\n /// @notice Used for interest rate computation\n uint256 public constant HALF_BASE_INTEREST = 10 ** 27 / 2;\n\n // ================================= REFERENCES ================================\n\n /// @inheritdoc IVaultManagerStorage\n ITreasury public treasury;\n /// @inheritdoc IVaultManagerStorage\n IERC20 public collateral;\n /// @inheritdoc IVaultManagerStorage\n IAgToken public stablecoin;\n /// @inheritdoc IVaultManagerStorage\n IOracle public oracle;\n /// @notice Reference to the contract which computes adjusted veANGLE balances for liquidators boosts\n IVeBoostProxy public veBoostProxy;\n /// @notice Base of the collateral\n uint256 internal _collatBase;\n\n // ================================= PARAMETERS ================================\n // Unless specified otherwise, parameters of this contract are expressed in `BASE_PARAMS`\n\n /// @notice Maximum amount of stablecoins that can be issued with this contract (in `BASE_TOKENS`). This parameter should\n /// not be bigger than `type(uint256).max / BASE_INTEREST` otherwise there may be some overflows in the `increaseDebt` function\n uint256 public debtCeiling;\n /// @notice Threshold veANGLE balance values for the computation of the boost for liquidators: the length of this array\n /// should normally be 2. The base of the x-values in this array should be `BASE_TOKENS`\n uint256[] public xLiquidationBoost;\n /// @notice Values of the liquidation boost at the threshold values of x\n uint256[] public yLiquidationBoost;\n /// @inheritdoc IVaultManagerStorage\n uint64 public collateralFactor;\n /// @notice Maximum Health factor at which a vault can end up after a liquidation (unless it's fully liquidated)\n uint64 public targetHealthFactor;\n /// @notice Upfront fee taken when borrowing stablecoins: this fee is optional and should in practice not be used\n uint64 public borrowFee;\n /// @notice Upfront fee taken when repaying stablecoins: this fee is optional as well. It should be smaller\n /// than the liquidation surcharge (cf below) to avoid exploits where people voluntarily get liquidated at a 0\n /// discount to pay smaller repaying fees\n uint64 public repayFee;\n /// @notice Per second interest taken to borrowers taking agToken loans. Contrarily to other parameters, it is set in `BASE_INTEREST`\n /// that is to say in base 10**27\n uint64 public interestRate;\n /// @notice Fee taken by the protocol during a liquidation. Technically, this value is not the fee per se, it's 1 - fee.\n /// For instance for a 2% fee, `liquidationSurcharge` should be 98%\n uint64 public liquidationSurcharge;\n /// @notice Maximum discount given to liquidators\n uint64 public maxLiquidationDiscount;\n /// @notice Whether whitelisting is required to own a vault or not\n bool public whitelistingActivated;\n /// @notice Whether the contract is paused or not\n bool public paused;\n\n // ================================= VARIABLES =================================\n\n /// @notice Timestamp at which the `interestAccumulator` was updated\n uint256 public lastInterestAccumulatorUpdated;\n /// @inheritdoc IVaultManagerStorage\n uint256 public interestAccumulator;\n /// @inheritdoc IVaultManagerStorage\n uint256 public totalNormalizedDebt;\n /// @notice Surplus accumulated by the contract: surplus is always in stablecoins, and is then reset\n /// when the value is communicated to the treasury contract\n uint256 public surplus;\n /// @notice Bad debt made from liquidated vaults which ended up having no collateral and a positive amount\n /// of stablecoins\n uint256 public badDebt;\n\n // ================================== MAPPINGS =================================\n\n /// @inheritdoc IVaultManagerStorage\n mapping(uint256 => Vault) public vaultData;\n /// @notice Maps an address to 1 if it's whitelisted and can open or own a vault\n mapping(address => uint256) public isWhitelisted;\n\n // ================================ ERC721 DATA ================================\n\n /// @inheritdoc IVaultManagerStorage\n uint256 public vaultIDCount;\n\n /// @notice URI\n string internal _baseURI;\n\n // Mapping from `vaultID` to owner address\n mapping(uint256 => address) internal _owners;\n\n // Mapping from owner address to vault owned count\n mapping(address => uint256) internal _balances;\n\n // Mapping from `vaultID` to approved address\n mapping(uint256 => address) internal _vaultApprovals;\n\n // Mapping from owner to operator approvals\n mapping(address => mapping(address => uint256)) internal _operatorApprovals;\n\n uint256[50] private __gap;\n\n // =================================== EVENTS ==================================\n\n event AccruedToTreasury(uint256 surplusEndValue, uint256 badDebtEndValue);\n event CollateralAmountUpdated(uint256 vaultID, uint256 collateralAmount, uint8 isIncrease);\n event InterestAccumulatorUpdated(uint256 value, uint256 timestamp);\n event InternalDebtUpdated(uint256 vaultID, uint256 internalAmount, uint8 isIncrease);\n event FiledUint64(uint64 param, bytes32 what);\n event DebtCeilingUpdated(uint256 debtCeiling);\n event LiquidationBoostParametersUpdated(address indexed _veBoostProxy, uint256[] xBoost, uint256[] yBoost);\n event LiquidatedVaults(uint256[] vaultIDs);\n event DebtTransferred(uint256 srcVaultID, uint256 dstVaultID, address dstVaultManager, uint256 amount);\n\n // =================================== ERRORS ==================================\n\n error ApprovalToOwner();\n error ApprovalToCaller();\n error DustyLeftoverAmount();\n error DebtCeilingExceeded();\n error HealthyVault();\n error IncompatibleLengths();\n error InsolventVault();\n error InvalidParameterValue();\n error InvalidParameterType();\n error InvalidSetOfParameters();\n error InvalidTreasury();\n error NonERC721Receiver();\n error NonexistentVault();\n error NotApproved();\n error NotGovernor();\n error NotGovernorOrGuardian();\n error NotTreasury();\n error NotWhitelisted();\n error NotVaultManager();\n error Paused();\n error TooHighParameterValue();\n error TooSmallParameterValue();\n error ZeroAddress();\n\n /// @custom:oz-upgrades-unsafe-allow constructor\n constructor() initializer {}\n}\n" + }, + "contracts/external/ProxyAdmin.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\nimport \"./TransparentUpgradeableProxy.sol\";\nimport \"@openzeppelin/contracts/access/Ownable.sol\";\n\n/**\n * @dev This is an auxiliary contract meant to be assigned as the admin of a {TransparentUpgradeableProxy}. For an\n * explanation of why you would want to use this see the documentation for {TransparentUpgradeableProxy}.\n * This contract was fully forked from OpenZeppelin `ProxyAdmin`\n */\ncontract ProxyAdmin is Ownable {\n /**\n * @dev Returns the current implementation of `proxy`.\n *\n * Requirements:\n *\n * - This contract must be the admin of `proxy`.\n */\n function getProxyImplementation(TransparentUpgradeableProxy proxy) public view virtual returns (address) {\n // We need to manually run the static call since the getter cannot be flagged as view\n // bytes4(keccak256(\"implementation()\")) == 0x5c60da1b\n (bool success, bytes memory returndata) = address(proxy).staticcall(hex\"5c60da1b\");\n require(success);\n return abi.decode(returndata, (address));\n }\n\n /**\n * @dev Returns the current admin of `proxy`.\n *\n * Requirements:\n *\n * - This contract must be the admin of `proxy`.\n */\n function getProxyAdmin(TransparentUpgradeableProxy proxy) public view virtual returns (address) {\n // We need to manually run the static call since the getter cannot be flagged as view\n // bytes4(keccak256(\"admin()\")) == 0xf851a440\n (bool success, bytes memory returndata) = address(proxy).staticcall(hex\"f851a440\");\n require(success);\n return abi.decode(returndata, (address));\n }\n\n /**\n * @dev Changes the admin of `proxy` to `newAdmin`.\n *\n * Requirements:\n *\n * - This contract must be the current admin of `proxy`.\n */\n function changeProxyAdmin(TransparentUpgradeableProxy proxy, address newAdmin) public virtual onlyOwner {\n proxy.changeAdmin(newAdmin);\n }\n\n /**\n * @dev Upgrades `proxy` to `implementation`. See {TransparentUpgradeableProxy-upgradeTo}.\n *\n * Requirements:\n *\n * - This contract must be the admin of `proxy`.\n */\n function upgrade(TransparentUpgradeableProxy proxy, address implementation) public virtual onlyOwner {\n proxy.upgradeTo(implementation);\n }\n\n /**\n * @dev Upgrades `proxy` to `implementation` and calls a function on the new implementation. See\n * {TransparentUpgradeableProxy-upgradeToAndCall}.\n *\n * Requirements:\n *\n * - This contract must be the admin of `proxy`.\n */\n function upgradeAndCall(\n TransparentUpgradeableProxy proxy,\n address implementation,\n bytes memory data\n ) public payable virtual onlyOwner {\n proxy.upgradeToAndCall{ value: msg.value }(implementation, data);\n }\n}\n" + }, + "contracts/external/TransparentUpgradeableProxy.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\nimport \"@openzeppelin/contracts/proxy/ERC1967/ERC1967Proxy.sol\";\n\n/**\n * @dev This contract implements a proxy that is upgradeable by an admin. It is fully forked from OpenZeppelin\n * `TransparentUpgradeableProxy`\n *\n * To avoid https://medium.com/nomic-labs-blog/malicious-backdoors-in-ethereum-proxies-62629adf3357[proxy selector\n * clashing], which can potentially be used in an attack, this contract uses the\n * https://blog.openzeppelin.com/the-transparent-proxy-pattern/[transparent proxy pattern]. This pattern implies two\n * things that go hand in hand:\n *\n * 1. If any account other than the admin calls the proxy, the call will be forwarded to the implementation, even if\n * that call matches one of the admin functions exposed by the proxy itself.\n * 2. If the admin calls the proxy, it can access the admin functions, but its calls will never be forwarded to the\n * implementation. If the admin tries to call a function on the implementation it will fail with an error that says\n * \"admin cannot fallback to proxy target\".\n *\n * These properties mean that the admin account can only be used for admin actions like upgrading the proxy or changing\n * the admin, so it's best if it's a dedicated account that is not used for anything else. This will avoid headaches due\n * to sudden errors when trying to call a function from the proxy implementation.\n *\n * Our recommendation is for the dedicated account to be an instance of the {ProxyAdmin} contract. If set up this way,\n * you should think of the `ProxyAdmin` instance as the real administrative interface of your proxy.\n */\ncontract TransparentUpgradeableProxy is ERC1967Proxy {\n /**\n * @dev Initializes an upgradeable proxy managed by `_admin`, backed by the implementation at `_logic`, and\n * optionally initialized with `_data` as explained in {ERC1967Proxy-constructor}.\n */\n constructor(address _logic, address admin_, bytes memory _data) payable ERC1967Proxy(_logic, _data) {\n assert(_ADMIN_SLOT == bytes32(uint256(keccak256(\"eip1967.proxy.admin\")) - 1));\n _changeAdmin(admin_);\n }\n\n /**\n * @dev Modifier used internally that will delegate the call to the implementation unless the sender is the admin.\n */\n modifier ifAdmin() {\n if (msg.sender == _getAdmin()) {\n _;\n } else {\n _fallback();\n }\n }\n\n /**\n * @dev Returns the current admin.\n *\n * NOTE: Only the admin can call this function. See {ProxyAdmin-getProxyAdmin}.\n *\n * TIP: To get this value clients can read directly from the storage slot shown below (specified by EIP1967) using the\n * https://eth.wiki/json-rpc/API#eth_getstorageat[`eth_getStorageAt`] RPC call.\n * `0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103`\n */\n function admin() external ifAdmin returns (address admin_) {\n admin_ = _getAdmin();\n }\n\n /**\n * @dev Returns the current implementation.\n *\n * NOTE: Only the admin can call this function. See {ProxyAdmin-getProxyImplementation}.\n *\n * TIP: To get this value clients can read directly from the storage slot shown below (specified by EIP1967) using the\n * https://eth.wiki/json-rpc/API#eth_getstorageat[`eth_getStorageAt`] RPC call.\n * `0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc`\n */\n function implementation() external ifAdmin returns (address implementation_) {\n implementation_ = _implementation();\n }\n\n /**\n * @dev Changes the admin of the proxy.\n *\n * Emits an {AdminChanged} event.\n *\n * NOTE: Only the admin can call this function. See {ProxyAdmin-changeProxyAdmin}.\n */\n function changeAdmin(address newAdmin) external virtual ifAdmin {\n _changeAdmin(newAdmin);\n }\n\n /**\n * @dev Upgrade the implementation of the proxy.\n *\n * NOTE: Only the admin can call this function. See {ProxyAdmin-upgrade}.\n */\n function upgradeTo(address newImplementation) external ifAdmin {\n _upgradeToAndCall(newImplementation, bytes(\"\"), false);\n }\n\n /**\n * @dev Upgrade the implementation of the proxy, and then call a function from the new implementation as specified\n * by `data`, which should be an encoded function call. This is useful to initialize new storage variables in the\n * proxied contract.\n *\n * NOTE: Only the admin can call this function. See {ProxyAdmin-upgradeAndCall}.\n */\n function upgradeToAndCall(address newImplementation, bytes calldata data) external payable ifAdmin {\n _upgradeToAndCall(newImplementation, data, true);\n }\n\n /**\n * @dev Returns the current admin.\n */\n function _admin() internal view virtual returns (address) {\n return _getAdmin();\n }\n\n /**\n * @dev Makes sure the admin cannot access the fallback function. See {Proxy-_beforeFallback}.\n */\n function _beforeFallback() internal virtual override {\n require(msg.sender != _getAdmin(), \"TransparentUpgradeableProxy: admin cannot fallback to proxy target\");\n super._beforeFallback();\n }\n}\n" + }, + "contracts/flashloan/FlashAngle.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\nimport \"@openzeppelin/contracts-upgradeable/security/ReentrancyGuardUpgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol\";\nimport \"@openzeppelin/contracts/interfaces/IERC3156FlashBorrower.sol\";\nimport \"@openzeppelin/contracts/interfaces/IERC3156FlashLender.sol\";\nimport \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\nimport \"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\";\n\nimport \"../interfaces/IAgToken.sol\";\nimport \"../interfaces/ICoreBorrow.sol\";\nimport \"../interfaces/IFlashAngle.sol\";\nimport \"../interfaces/ITreasury.sol\";\n\n/// @title FlashAngle\n/// @author Angle Labs, Inc.\n/// @notice Contract to take flash loans on top of several AgToken contracts\ncontract FlashAngle is IERC3156FlashLender, IFlashAngle, Initializable, ReentrancyGuardUpgradeable {\n using SafeERC20 for IERC20;\n /// @notice Base used for parameter computation\n uint256 public constant BASE_PARAMS = 10 ** 9;\n /// @notice Success message received when calling a `FlashBorrower` contract\n bytes32 public constant CALLBACK_SUCCESS = keccak256(\"ERC3156FlashBorrower.onFlashLoan\");\n\n /// @notice Struct encoding for a given stablecoin the parameters\n struct StablecoinData {\n // Maximum amount borrowable for this stablecoin\n uint256 maxBorrowable;\n // Flash loan fee taken by the protocol for a flash loan on this stablecoin\n uint64 flashLoanFee;\n // Treasury address responsible of the stablecoin\n address treasury;\n }\n\n // ======================= Parameters and References ===========================\n\n /// @notice Maps a stablecoin to the data and parameters for flash loans\n mapping(IAgToken => StablecoinData) public stablecoinMap;\n /// @inheritdoc IFlashAngle\n ICoreBorrow public core;\n\n // =============================== Event =======================================\n\n event FlashLoan(address indexed stablecoin, uint256 amount, IERC3156FlashBorrower indexed receiver);\n event FlashLoanParametersUpdated(IAgToken indexed stablecoin, uint64 _flashLoanFee, uint256 _maxBorrowable);\n\n // =============================== Errors ======================================\n\n error InvalidReturnMessage();\n error NotCore();\n error NotGovernorOrGuardian();\n error NotTreasury();\n error TooBigAmount();\n error TooHighParameterValue();\n error UnsupportedStablecoin();\n error ZeroAddress();\n\n /// @notice Initializes the contract\n /// @param _core Core address handling this module\n function initialize(ICoreBorrow _core) public initializer {\n if (address(_core) == address(0)) revert ZeroAddress();\n core = _core;\n }\n\n /// @custom:oz-upgrades-unsafe-allow constructor\n constructor() initializer {}\n\n // =================================== Modifiers ===============================\n\n /// @notice Checks whether the sender is the core contract\n modifier onlyCore() {\n if (msg.sender != address(core)) revert NotCore();\n _;\n }\n\n /// @notice Checks whether a given stablecoin has been initialized in this contract\n /// @param stablecoin Stablecoin to check\n /// @dev To check whether a stablecoin has been initialized, we just need to check whether its associated\n /// `treasury` address is not null in the `stablecoinMap`. This is what's checked in the `CoreBorrow` contract\n /// when adding support for a stablecoin\n modifier onlyExistingStablecoin(IAgToken stablecoin) {\n if (stablecoinMap[stablecoin].treasury == address(0)) revert UnsupportedStablecoin();\n _;\n }\n\n // ================================ ERC3156 Spec ===============================\n\n /// @inheritdoc IERC3156FlashLender\n function flashFee(address token, uint256 amount) external view returns (uint256) {\n return _flashFee(token, amount);\n }\n\n /// @inheritdoc IERC3156FlashLender\n function maxFlashLoan(address token) external view returns (uint256) {\n // It will be 0 anyway if the token was not added\n return stablecoinMap[IAgToken(token)].maxBorrowable;\n }\n\n /// @inheritdoc IERC3156FlashLender\n function flashLoan(\n IERC3156FlashBorrower receiver,\n address token,\n uint256 amount,\n bytes calldata data\n ) external nonReentrant returns (bool) {\n uint256 fee = _flashFee(token, amount);\n if (amount > stablecoinMap[IAgToken(token)].maxBorrowable) revert TooBigAmount();\n IAgToken(token).mint(address(receiver), amount);\n if (receiver.onFlashLoan(msg.sender, token, amount, fee, data) != CALLBACK_SUCCESS)\n revert InvalidReturnMessage();\n // Token must be an agToken here so normally no need to use `safeTransferFrom`, but out of safety\n // and in case governance whitelists an agToken which does not have a correct implementation, we prefer\n // to use `safeTransferFrom` here\n IERC20(token).safeTransferFrom(address(receiver), address(this), amount + fee);\n IAgToken(token).burnSelf(amount, address(this));\n emit FlashLoan(token, amount, receiver);\n return true;\n }\n\n /// @notice Internal function to compute the fee induced for taking a flash loan of `amount` of `token`\n /// @param token The loan currency\n /// @param amount The amount of tokens lent\n /// @dev This function will revert if the `token` requested is not whitelisted here\n function _flashFee(\n address token,\n uint256 amount\n ) internal view onlyExistingStablecoin(IAgToken(token)) returns (uint256) {\n return (amount * stablecoinMap[IAgToken(token)].flashLoanFee) / BASE_PARAMS;\n }\n\n // ============================ Treasury Only Function =========================\n\n /// @inheritdoc IFlashAngle\n function accrueInterestToTreasury(IAgToken stablecoin) external returns (uint256 balance) {\n address treasury = stablecoinMap[stablecoin].treasury;\n if (msg.sender != treasury) revert NotTreasury();\n balance = stablecoin.balanceOf(address(this));\n IERC20(address(stablecoin)).safeTransfer(treasury, balance);\n }\n\n // =========================== Governance Only Function ========================\n\n /// @notice Sets the parameters for a given stablecoin\n /// @param stablecoin Stablecoin to change the parameters for\n /// @param _flashLoanFee New flash loan fee for this stablecoin\n /// @param _maxBorrowable Maximum amount that can be borrowed in a single flash loan\n /// @dev Setting a `maxBorrowable` parameter equal to 0 is a way to pause the functionality\n /// @dev Parameters can only be modified for whitelisted stablecoins\n function setFlashLoanParameters(\n IAgToken stablecoin,\n uint64 _flashLoanFee,\n uint256 _maxBorrowable\n ) external onlyExistingStablecoin(stablecoin) {\n if (!core.isGovernorOrGuardian(msg.sender)) revert NotGovernorOrGuardian();\n if (_flashLoanFee > BASE_PARAMS) revert TooHighParameterValue();\n stablecoinMap[stablecoin].flashLoanFee = _flashLoanFee;\n stablecoinMap[stablecoin].maxBorrowable = _maxBorrowable;\n emit FlashLoanParametersUpdated(stablecoin, _flashLoanFee, _maxBorrowable);\n }\n\n // =========================== CoreBorrow Only Functions =======================\n\n /// @inheritdoc IFlashAngle\n function addStablecoinSupport(address _treasury) external onlyCore {\n stablecoinMap[IAgToken(ITreasury(_treasury).stablecoin())].treasury = _treasury;\n }\n\n /// @inheritdoc IFlashAngle\n function removeStablecoinSupport(address _treasury) external onlyCore {\n delete stablecoinMap[IAgToken(ITreasury(_treasury).stablecoin())];\n }\n\n /// @inheritdoc IFlashAngle\n function setCore(address _core) external onlyCore {\n core = ICoreBorrow(_core);\n }\n}\n" + }, + "contracts/interfaces/coreModule/IAgTokenMainnet.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\n/// @title IAgTokenMainnet\n/// @author Angle Labs, Inc.\ninterface IAgTokenMainnet {\n function stableMaster() external view returns (address);\n}\n" + }, + "contracts/interfaces/coreModule/ICore.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\n/// @title ICore\n/// @author Angle Labs, Inc.\ninterface ICore {\n function stablecoinList() external view returns (address[] memory);\n}\n" + }, + "contracts/interfaces/coreModule/ILiquidityGauge.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\ninterface ILiquidityGauge {\n function deposit(\n uint256 _value,\n address _addr,\n // solhint-disable-next-line\n bool _claim_rewards\n ) external;\n\n function withdraw(\n uint256 _value,\n // solhint-disable-next-line\n bool _claim_rewards\n ) external;\n\n // solhint-disable-next-line\n function claim_rewards(address _addr, address _receiver) external;\n\n // solhint-disable-next-line\n function claimable_reward(address _addr, address _reward_token) external view returns (uint256 amount);\n}\n" + }, + "contracts/interfaces/coreModule/IOracleCore.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\n/// @title IOracleCore\n/// @author Angle Labs, Inc.\ninterface IOracleCore {\n function readUpper() external view returns (uint256);\n\n function readQuoteLower(uint256 baseAmount) external view returns (uint256);\n}\n" + }, + "contracts/interfaces/coreModule/IPerpetualManager.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\n/// @title IPerpetualManager\n/// @author Angle Labs, Inc.\ninterface IPerpetualManager {\n function totalHedgeAmount() external view returns (uint256);\n\n function maintenanceMargin() external view returns (uint64);\n\n function maxLeverage() external view returns (uint64);\n\n function targetHAHedge() external view returns (uint64);\n\n function limitHAHedge() external view returns (uint64);\n\n function lockTime() external view returns (uint64);\n\n function haBonusMalusDeposit() external view returns (uint64);\n\n function haBonusMalusWithdraw() external view returns (uint64);\n\n function xHAFeesDeposit(uint256) external view returns (uint64);\n\n function yHAFeesDeposit(uint256) external view returns (uint64);\n\n function xHAFeesWithdraw(uint256) external view returns (uint64);\n\n function yHAFeesWithdraw(uint256) external view returns (uint64);\n}\n" + }, + "contracts/interfaces/coreModule/IPoolManager.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\n/// @title IPoolManager\n/// @author Angle Labs, Inc.\ninterface IPoolManager {\n function feeManager() external view returns (address);\n\n function strategyList(uint256) external view returns (address);\n}\n" + }, + "contracts/interfaces/coreModule/IStableMaster.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\nimport \"./IPerpetualManager.sol\";\nimport \"./IOracleCore.sol\";\n\n// Struct to handle all the parameters to manage the fees\n// related to a given collateral pool (associated to the stablecoin)\nstruct MintBurnData {\n // Values of the thresholds to compute the minting fees\n // depending on HA hedge (scaled by `BASE_PARAMS`)\n uint64[] xFeeMint;\n // Values of the fees at thresholds (scaled by `BASE_PARAMS`)\n uint64[] yFeeMint;\n // Values of the thresholds to compute the burning fees\n // depending on HA hedge (scaled by `BASE_PARAMS`)\n uint64[] xFeeBurn;\n // Values of the fees at thresholds (scaled by `BASE_PARAMS`)\n uint64[] yFeeBurn;\n // Max proportion of collateral from users that can be covered by HAs\n // It is exactly the same as the parameter of the same name in `PerpetualManager`, whenever one is updated\n // the other changes accordingly\n uint64 targetHAHedge;\n // Minting fees correction set by the `FeeManager` contract: they are going to be multiplied\n // to the value of the fees computed using the hedge curve\n // Scaled by `BASE_PARAMS`\n uint64 bonusMalusMint;\n // Burning fees correction set by the `FeeManager` contract: they are going to be multiplied\n // to the value of the fees computed using the hedge curve\n // Scaled by `BASE_PARAMS`\n uint64 bonusMalusBurn;\n // Parameter used to limit the number of stablecoins that can be issued using the concerned collateral\n uint256 capOnStableMinted;\n}\n\n// Struct to handle all the variables and parameters to handle SLPs in the protocol\n// including the fraction of interests they receive or the fees to be distributed to\n// them\nstruct SLPData {\n // Last timestamp at which the `sanRate` has been updated for SLPs\n uint256 lastBlockUpdated;\n // Fees accumulated from previous blocks and to be distributed to SLPs\n uint256 lockedInterests;\n // Max interests used to update the `sanRate` in a single block\n // Should be in collateral token base\n uint256 maxInterestsDistributed;\n // Amount of fees left aside for SLPs and that will be distributed\n // when the protocol is collateralized back again\n uint256 feesAside;\n // Part of the fees normally going to SLPs that is left aside\n // before the protocol is collateralized back again (depends on collateral ratio)\n // Updated by keepers and scaled by `BASE_PARAMS`\n uint64 slippageFee;\n // Portion of the fees from users minting and burning\n // that goes to SLPs (the rest goes to surplus)\n uint64 feesForSLPs;\n // Slippage factor that's applied to SLPs exiting (depends on collateral ratio)\n // If `slippage = BASE_PARAMS`, SLPs can get nothing, if `slippage = 0` they get their full claim\n // Updated by keepers and scaled by `BASE_PARAMS`\n uint64 slippage;\n // Portion of the interests from lending\n // that goes to SLPs (the rest goes to surplus)\n uint64 interestsForSLPs;\n}\n\n/// @title IStableMaster\n/// @author Angle Labs, Inc.\ninterface IStableMaster {\n function agToken() external view returns (address);\n\n function updateStocksUsers(uint256 amount, address poolManager) external;\n\n function collateralMap(\n address poolManager\n )\n external\n view\n returns (\n address token,\n address sanToken,\n IPerpetualManager perpetualManager,\n IOracleCore oracle,\n uint256 stocksUsers,\n uint256 sanRate,\n uint256 collatBase,\n SLPData memory slpData,\n MintBurnData memory feeData\n );\n\n function paused(bytes32) external view returns (bool);\n\n function deposit(uint256 amount, address user, address poolManager) external;\n\n function withdraw(uint256 amount, address burner, address dest, address poolManager) external;\n}\n" + }, + "contracts/interfaces/external/create2/ImmutableCreate2Factory.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\ninterface ImmutableCreate2Factory {\n function safeCreate2(bytes32 salt, bytes memory initCode) external payable returns (address deploymentAddress);\n\n function findCreate2Address(\n bytes32 salt,\n bytes calldata initCode\n ) external view returns (address deploymentAddress);\n\n function findCreate2AddressViaHash(\n bytes32 salt,\n bytes32 initCodeHash\n ) external view returns (address deploymentAddress);\n}\n" + }, + "contracts/interfaces/external/IERC1271.sol": { + "content": "// SPDX-License-Identifier: GPL-2.0-or-later\npragma solidity ^0.8.12;\n\n/// @title Interface for verifying contract-based account signatures\n/// @notice Interface that verifies provided signature for the data\n/// @dev Interface defined by EIP-1271\ninterface IERC1271 {\n /// @notice Returns whether the provided signature is valid for the provided data\n /// @dev MUST return the bytes4 magic value 0x1626ba7e when function passes.\n /// MUST NOT modify state (using STATICCALL for solc < 0.5, view modifier for solc > 0.5).\n /// MUST allow external calls.\n /// @param hash Hash of the data to be signed\n /// @param signature Signature byte array associated with _data\n /// @return magicValue The bytes4 magic value 0x1626ba7e\n function isValidSignature(bytes32 hash, bytes memory signature) external view returns (bytes4 magicValue);\n}\n" + }, + "contracts/interfaces/external/IERC4626.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\npragma solidity >=0.8.0;\n\nimport \"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\";\nimport \"@openzeppelin/contracts/token/ERC20/ERC20.sol\";\n\n/// @notice Minimal IERC4646 tokenized Vault interface.\n/// @author Forked from Solmate (https://github.com/Rari-Capital/solmate/blob/main/src/mixins/ERC4626.sol)\n/// @dev Do not use in production! ERC-4626 is still in the review stage and is subject to change.\ninterface IERC4626 {\n event Deposit(address indexed from, address indexed to, uint256 amount, uint256 shares);\n event Withdraw(address indexed from, address indexed to, uint256 amount, uint256 shares);\n\n /// @notice Transfers a given amount of asset to the reactor and mint shares accordingly\n /// @param amount Given amount of asset\n /// @param to Address to mint shares to\n /// @return shares Amount of shares minted to `to`\n function deposit(uint256 amount, address to) external returns (uint256 shares);\n\n /// @notice Mints a given amount of shares to the reactor and transfer assets accordingly\n /// @param shares Given amount of shares\n /// @param to Address to mint shares to\n /// @return amount Amount of `asset` taken to the `msg.sender` to mint `shares`\n function mint(uint256 shares, address to) external returns (uint256 amount);\n\n /// @notice Transfers a given amount of asset from the reactor and burn shares accordingly\n /// @param amount Given amount of asset\n /// @param to Address to transfer assets to\n /// @param from Address to burn shares from\n /// @return shares Amount of shares burnt in the operation\n function withdraw(uint256 amount, address to, address from) external returns (uint256 shares);\n\n /// @notice Burns a given amount of shares to the reactor and transfer assets accordingly\n /// @param shares Given amount of shares\n /// @param to Address to transfer assets to\n /// @param from Address to burn shares from\n /// @return amount Amount of assets redeemed in the operation\n function redeem(uint256 shares, address to, address from) external returns (uint256 amount);\n\n /// @notice Returns the total assets managed by this reactor\n function totalAssets() external view returns (uint256);\n\n /// @notice Converts an amount of assets to the corresponding amount of reactor shares\n /// @param assets Amount of asset to convert\n /// @return Shares corresponding to the amount of assets obtained\n function convertToShares(uint256 assets) external view returns (uint256);\n\n /// @notice Converts an amount of shares to its current value in asset\n /// @param shares Amount of shares to convert\n /// @return Amount of assets corresponding to the amount of assets given\n function convertToAssets(uint256 shares) external view returns (uint256);\n\n /// @notice Computes how many shares one would get by depositing `assets`\n /// @param assets Amount of asset to convert\n function previewDeposit(uint256 assets) external view returns (uint256);\n\n /// @notice Computes how many assets one would need to mint `shares`\n /// @param shares Amount of shares required\n function previewMint(uint256 shares) external view returns (uint256);\n\n /// @notice Computes how many shares one would need to withdraw assets\n /// @param assets Amount of asset to withdraw\n function previewWithdraw(uint256 assets) external view returns (uint256);\n\n /// @notice Computes how many assets one would get by burning shares\n /// @param shares Amount of shares to burn\n function previewRedeem(uint256 shares) external view returns (uint256);\n\n /// @notice Max deposit allowed for a user\n /// @param user Address of the user to check\n function maxDeposit(address user) external returns (uint256);\n\n /// @notice Max mint allowed for a user\n /// @param user Address of the user to check\n function maxMint(address user) external returns (uint256);\n\n /// @notice Max withdraw allowed for a user\n /// @param user Address of the user to check\n function maxWithdraw(address user) external returns (uint256);\n\n /// @notice Max redeem allowed for a user\n /// @param user Address of the user to check\n function maxRedeem(address user) external returns (uint256);\n}\n" + }, + "contracts/interfaces/external/IWETH9.sol": { + "content": "// SPDX-License-Identifier: GPL-2.0-or-later\npragma solidity ^0.8.12;\n\nimport \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\n\n/// @title Interface for WETH9\ninterface IWETH9 is IERC20 {\n /// @notice Deposit ether to get wrapped ether\n function deposit() external payable;\n\n /// @notice Withdraw wrapped ether to get ether\n function withdraw(uint256) external;\n}\n" + }, + "contracts/interfaces/external/layerZero/ILayerZeroEndpoint.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity >=0.5.0;\n\nimport \"./ILayerZeroUserApplicationConfig.sol\";\n\ninterface ILayerZeroEndpoint is ILayerZeroUserApplicationConfig {\n // @notice send a LayerZero message to the specified address at a LayerZero endpoint.\n // @param _dstChainId - the destination chain identifier\n // @param _destination - the address on destination chain (in bytes). address length/format may vary by chains\n // @param _payload - a custom bytes payload to send to the destination contract\n // @param _refundAddress - if the source transaction is cheaper than the amount of value passed, refund the additional amount to this address\n // @param _zroPaymentAddress - the address of the ZRO token holder who would pay for the transaction\n // @param _adapterParams - parameters for custom functionality. e.g. receive airdropped native gas from the relayer on destination\n function send(\n uint16 _dstChainId,\n bytes calldata _destination,\n bytes calldata _payload,\n address payable _refundAddress,\n address _zroPaymentAddress,\n bytes calldata _adapterParams\n ) external payable;\n\n // @notice used by the messaging library to publish verified payload\n // @param _srcChainId - the source chain identifier\n // @param _srcAddress - the source contract (as bytes) at the source chain\n // @param _dstAddress - the address on destination chain\n // @param _nonce - the unbound message ordering nonce\n // @param _gasLimit - the gas limit for external contract execution\n // @param _payload - verified payload to send to the destination contract\n function receivePayload(\n uint16 _srcChainId,\n bytes calldata _srcAddress,\n address _dstAddress,\n uint64 _nonce,\n uint256 _gasLimit,\n bytes calldata _payload\n ) external;\n\n // @notice get the inboundNonce of a lzApp from a source chain which could be EVM or non-EVM chain\n // @param _srcChainId - the source chain identifier\n // @param _srcAddress - the source chain contract address\n function getInboundNonce(uint16 _srcChainId, bytes calldata _srcAddress) external view returns (uint64);\n\n // @notice get the outboundNonce from this source chain which, consequently, is always an EVM\n // @param _srcAddress - the source chain contract address\n function getOutboundNonce(uint16 _dstChainId, address _srcAddress) external view returns (uint64);\n\n // @notice gets a quote in source native gas, for the amount that send() requires to pay for message delivery\n // @param _dstChainId - the destination chain identifier\n // @param _userApplication - the user app address on this EVM chain\n // @param _payload - the custom message to send over LayerZero\n // @param _payInZRO - if false, user app pays the protocol fee in native token\n // @param _adapterParam - parameters for the adapter service, e.g. send some dust native token to dstChain\n function estimateFees(\n uint16 _dstChainId,\n address _userApplication,\n bytes calldata _payload,\n bool _payInZRO,\n bytes calldata _adapterParam\n ) external view returns (uint256 nativeFee, uint256 zroFee);\n\n // @notice get this Endpoint's immutable source identifier\n function getChainId() external view returns (uint16);\n\n // @notice the interface to retry failed message on this Endpoint destination\n // @param _srcChainId - the source chain identifier\n // @param _srcAddress - the source chain contract address\n // @param _payload - the payload to be retried\n function retryPayload(uint16 _srcChainId, bytes calldata _srcAddress, bytes calldata _payload) external;\n\n // @notice query if any STORED payload (message blocking) at the endpoint.\n // @param _srcChainId - the source chain identifier\n // @param _srcAddress - the source chain contract address\n function hasStoredPayload(uint16 _srcChainId, bytes calldata _srcAddress) external view returns (bool);\n\n // @notice query if the _libraryAddress is valid for sending msgs.\n // @param _userApplication - the user app address on this EVM chain\n function getSendLibraryAddress(address _userApplication) external view returns (address);\n\n // @notice query if the _libraryAddress is valid for receiving msgs.\n // @param _userApplication - the user app address on this EVM chain\n function getReceiveLibraryAddress(address _userApplication) external view returns (address);\n\n // @notice query if the non-reentrancy guard for send() is on\n // @return true if the guard is on. false otherwise\n function isSendingPayload() external view returns (bool);\n\n // @notice query if the non-reentrancy guard for receive() is on\n // @return true if the guard is on. false otherwise\n function isReceivingPayload() external view returns (bool);\n\n // @notice get the configuration of the LayerZero messaging library of the specified version\n // @param _version - messaging library version\n // @param _chainId - the chainId for the pending config change\n // @param _userApplication - the contract address of the user application\n // @param _configType - type of configuration. every messaging library has its own convention.\n function getConfig(\n uint16 _version,\n uint16 _chainId,\n address _userApplication,\n uint256 _configType\n ) external view returns (bytes memory);\n\n // @notice get the send() LayerZero messaging library version\n // @param _userApplication - the contract address of the user application\n function getSendVersion(address _userApplication) external view returns (uint16);\n\n // @notice get the lzReceive() LayerZero messaging library version\n // @param _userApplication - the contract address of the user application\n function getReceiveVersion(address _userApplication) external view returns (uint16);\n}\n" + }, + "contracts/interfaces/external/layerZero/ILayerZeroReceiver.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity >=0.5.0;\n\ninterface ILayerZeroReceiver {\n // @notice LayerZero endpoint will invoke this function to deliver the message on the destination\n // @param _srcChainId - the source endpoint identifier\n // @param _srcAddress - the source sending contract address from the source chain\n // @param _nonce - the ordered message nonce\n // @param _payload - the signed payload is the UA bytes has encoded to be sent\n function lzReceive(uint16 _srcChainId, bytes calldata _srcAddress, uint64 _nonce, bytes calldata _payload) external;\n}\n" + }, + "contracts/interfaces/external/layerZero/ILayerZeroUserApplicationConfig.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity >=0.5.0;\n\ninterface ILayerZeroUserApplicationConfig {\n // @notice set the configuration of the LayerZero messaging library of the specified version\n // @param _version - messaging library version\n // @param _chainId - the chainId for the pending config change\n // @param _configType - type of configuration. every messaging library has its own convention.\n // @param _config - configuration in the bytes. can encode arbitrary content.\n function setConfig(uint16 _version, uint16 _chainId, uint256 _configType, bytes calldata _config) external;\n\n // @notice set the send() LayerZero messaging library version to _version\n // @param _version - new messaging library version\n function setSendVersion(uint16 _version) external;\n\n // @notice set the lzReceive() LayerZero messaging library version to _version\n // @param _version - new messaging library version\n function setReceiveVersion(uint16 _version) external;\n\n // @notice Only when the UA needs to resume the message flow in blocking mode and clear the stored payload\n // @param _srcChainId - the chainId of the source chain\n // @param _srcAddress - the contract address of the source contract at the source chain\n function forceResumeReceive(uint16 _srcChainId, bytes calldata _srcAddress) external;\n}\n" + }, + "contracts/interfaces/external/lido/IStETH.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\n/// @title IStETH\n/// @author Angle Labs, Inc.\n/// @notice Interface for the `StETH` contract\n/// @dev This interface only contains functions of the `StETH` which are called by other contracts\n/// of this module\ninterface IStETH {\n function getPooledEthByShares(uint256 _sharesAmount) external view returns (uint256);\n\n event Submitted(address sender, uint256 amount, address referral);\n\n function submit(address) external payable returns (uint256);\n\n function getSharesByPooledEth(uint256 _ethAmount) external view returns (uint256);\n}\n" + }, + "contracts/interfaces/external/lido/IWStETH.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\n/// @title IWStETH\n/// @author Angle Labs, Inc.\n/// @notice Interface for the `WStETH` contract\n/// @dev This interface only contains functions of the `WStETH` which are called by other contracts\n/// of this module\ninterface IWStETH {\n function wrap(uint256 _stETHAmount) external returns (uint256);\n\n function stETH() external view returns (address);\n}\n" + }, + "contracts/interfaces/external/uniswap/IUniswapRouter.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\nstruct ExactInputParams {\n bytes path;\n address recipient;\n uint256 deadline;\n uint256 amountIn;\n uint256 amountOutMinimum;\n}\n\n/// @title Router token swapping functionality\n/// @notice Functions for swapping tokens via Uniswap V3\ninterface IUniswapV3Router {\n /// @notice Swaps `amountIn` of one token for as much as possible of another along the specified path\n /// @param params The parameters necessary for the multi-hop swap, encoded as `ExactInputParams` in calldata\n /// @return amountOut The amount of the received token\n function exactInput(ExactInputParams calldata params) external payable returns (uint256 amountOut);\n}\n\n/// @title Router for price estimation functionality\n/// @notice Functions for getting the price of one token with respect to another using Uniswap V2\n/// @dev This interface is only used for non critical elements of the protocol\ninterface IUniswapV2Router {\n /// @notice Given an input asset amount, returns the maximum output amount of the\n /// other asset (accounting for fees) given reserves.\n /// @param path Addresses of the pools used to get prices\n function getAmountsOut(uint256 amountIn, address[] calldata path) external view returns (uint256[] memory amounts);\n\n function swapExactTokensForTokens(\n uint256 swapAmount,\n uint256 minExpected,\n address[] calldata path,\n address receiver,\n uint256 swapDeadline\n ) external;\n}\n" + }, + "contracts/interfaces/external/uniswap/IUniswapV3Pool.sol": { + "content": "// SPDX-License-Identifier: GPL-2.0-or-later\npragma solidity >=0.5.0;\n\n/// @title Pool state that never changes\n/// @notice These parameters are fixed for a pool forever, i.e., the methods will always return the same values\ninterface IUniswapV3Pool {\n /// @notice The first of the two tokens of the pool, sorted by address\n /// @return The token contract address\n function token0() external view returns (address);\n\n /// @notice The second of the two tokens of the pool, sorted by address\n /// @return The token contract address\n function token1() external view returns (address);\n}\n" + }, + "contracts/interfaces/governance/IVeBoostProxy.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\n/// @title IVeBoostProxy\n/// @author Angle Labs, Inc.\n/// @notice Interface for the `VeBoostProxy` contract\n/// @dev This interface only contains functions of the contract which are called by other contracts\n/// of this module\n/// @dev The `veBoostProxy` contract used by Angle is a full fork of Curve Finance implementation\ninterface IVeBoostProxy {\n /// @notice Reads the adjusted veANGLE balance of an address (adjusted by delegation)\n //solhint-disable-next-line\n function adjusted_balance_of(address) external view returns (uint256);\n}\n" + }, + "contracts/interfaces/IAgToken.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\nimport \"@openzeppelin/contracts-upgradeable/token/ERC20/IERC20Upgradeable.sol\";\n\n/// @title IAgToken\n/// @author Angle Labs, Inc.\n/// @notice Interface for the stablecoins `AgToken` contracts\n/// @dev This interface only contains functions of the `AgToken` contract which are called by other contracts\n/// of this module or of the first module of the Angle Protocol\ninterface IAgToken is IERC20Upgradeable {\n // ======================= Minter Role Only Functions ===========================\n\n /// @notice Lets the `StableMaster` contract or another whitelisted contract mint agTokens\n /// @param account Address to mint to\n /// @param amount Amount to mint\n /// @dev The contracts allowed to issue agTokens are the `StableMaster` contract, `VaultManager` contracts\n /// associated to this stablecoin as well as the flash loan module (if activated) and potentially contracts\n /// whitelisted by governance\n function mint(address account, uint256 amount) external;\n\n /// @notice Burns `amount` tokens from a `burner` address after being asked to by `sender`\n /// @param amount Amount of tokens to burn\n /// @param burner Address to burn from\n /// @param sender Address which requested the burn from `burner`\n /// @dev This method is to be called by a contract with the minter right after being requested\n /// to do so by a `sender` address willing to burn tokens from another `burner` address\n /// @dev The method checks the allowance between the `sender` and the `burner`\n function burnFrom(uint256 amount, address burner, address sender) external;\n\n /// @notice Burns `amount` tokens from a `burner` address\n /// @param amount Amount of tokens to burn\n /// @param burner Address to burn from\n /// @dev This method is to be called by a contract with a minter right on the AgToken after being\n /// requested to do so by an address willing to burn tokens from its address\n function burnSelf(uint256 amount, address burner) external;\n\n // ========================= Treasury Only Functions ===========================\n\n /// @notice Adds a minter in the contract\n /// @param minter Minter address to add\n /// @dev Zero address checks are performed directly in the `Treasury` contract\n function addMinter(address minter) external;\n\n /// @notice Removes a minter from the contract\n /// @param minter Minter address to remove\n /// @dev This function can also be called by a minter wishing to revoke itself\n function removeMinter(address minter) external;\n\n /// @notice Sets a new treasury contract\n /// @param _treasury New treasury address\n function setTreasury(address _treasury) external;\n\n // ========================= External functions ================================\n\n /// @notice Checks whether an address has the right to mint agTokens\n /// @param minter Address for which the minting right should be checked\n /// @return Whether the address has the right to mint agTokens or not\n function isMinter(address minter) external view returns (bool);\n\n /// @notice Get the associated treasury\n function treasury() external view returns (address);\n}\n" + }, + "contracts/interfaces/IAgTokenSideChainMultiBridge.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\nimport \"@openzeppelin/contracts-upgradeable/token/ERC20/extensions/draft-IERC20PermitUpgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/token/ERC20/IERC20Upgradeable.sol\";\n\n/// @title IAgTokenSideChainMultiBridge\n/// @author Angle Labs, Inc.\n/// @notice Interface for the canonical `AgToken` contracts\n/// @dev This interface only contains functions useful for bridge tokens to interact with the canonical token\ninterface IAgTokenSideChainMultiBridge is IERC20PermitUpgradeable, IERC20Upgradeable {\n /// @notice Mints the canonical token from a supported bridge token\n /// @param bridgeToken Bridge token to use to mint\n /// @param amount Amount of bridge tokens to send\n /// @param to Address to which the stablecoin should be sent\n /// @return Amount of the canonical stablecoin actually minted\n /// @dev Some fees may be taken by the protocol depending on the token used and on the address calling\n function swapIn(address bridgeToken, uint256 amount, address to) external returns (uint256);\n\n /// @notice Burns the canonical token in exchange for a bridge token\n /// @param bridgeToken Bridge token required\n /// @param amount Amount of canonical tokens to burn\n /// @param to Address to which the bridge token should be sent\n /// @return Amount of bridge tokens actually sent back\n /// @dev Some fees may be taken by the protocol depending on the token used and on the address calling\n function swapOut(address bridgeToken, uint256 amount, address to) external returns (uint256);\n}\n" + }, + "contracts/interfaces/IAngleRouter.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\n/// @title IAngleRouter\n/// @author Angle Labs, Inc.\n/// @notice Interface for the `AngleRouter` contract\n/// @dev This interface only contains functions of the `AngleRouter01` contract which are called by other contracts\n/// of this module\ninterface IAngleRouter {\n function mint(\n address user,\n uint256 amount,\n uint256 minStableAmount,\n address stablecoin,\n address collateral\n ) external;\n\n function burn(address user, uint256 amount, uint256 minAmountOut, address stablecoin, address collateral) external;\n\n function mapPoolManagers(\n address stableMaster,\n address collateral\n ) external view returns (address poolManager, address perpetualManager, address sanToken, address gauge);\n}\n" + }, + "contracts/interfaces/IAngleRouterSidechain.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\n/// @notice Action types\nenum ActionType {\n transfer,\n wrap,\n wrapNative,\n sweep,\n sweepNative,\n unwrap,\n unwrapNative,\n swapIn,\n swapOut,\n uniswapV3,\n oneInch,\n claimRewards,\n gaugeDeposit,\n borrower\n}\n\n/// @notice Data needed to get permits\nstruct PermitType {\n address token;\n address owner;\n uint256 value;\n uint256 deadline;\n uint8 v;\n bytes32 r;\n bytes32 s;\n}\n\n/// @title IAngleRouterSidechain\n/// @author Angle Labs, Inc.\n/// @notice Interface for the `AngleRouter` contract on other chains\ninterface IAngleRouterSidechain {\n function mixer(PermitType[] memory paramsPermit, ActionType[] memory actions, bytes[] calldata data) external;\n}\n" + }, + "contracts/interfaces/ICoreBorrow.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\n/// @title ICoreBorrow\n/// @author Angle Labs, Inc.\n/// @notice Interface for the `CoreBorrow` contract\n/// @dev This interface only contains functions of the `CoreBorrow` contract which are called by other contracts\n/// of this module\ninterface ICoreBorrow {\n /// @notice Checks if an address corresponds to a treasury of a stablecoin with a flash loan\n /// module initialized on it\n /// @param treasury Address to check\n /// @return Whether the address has the `FLASHLOANER_TREASURY_ROLE` or not\n function isFlashLoanerTreasury(address treasury) external view returns (bool);\n\n /// @notice Checks whether an address is governor of the Angle Protocol or not\n /// @param admin Address to check\n /// @return Whether the address has the `GOVERNOR_ROLE` or not\n function isGovernor(address admin) external view returns (bool);\n\n /// @notice Checks whether an address is governor or a guardian of the Angle Protocol or not\n /// @param admin Address to check\n /// @return Whether the address has the `GUARDIAN_ROLE` or not\n /// @dev Governance should make sure when adding a governor to also give this governor the guardian\n /// role by calling the `addGovernor` function\n function isGovernorOrGuardian(address admin) external view returns (bool);\n}\n" + }, + "contracts/interfaces/IFlashAngle.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\nimport \"./IAgToken.sol\";\nimport \"./ICoreBorrow.sol\";\n\n/// @title IFlashAngle\n/// @author Angle Labs, Inc.\n/// @notice Interface for the `FlashAngle` contract\n/// @dev This interface only contains functions of the contract which are called by other contracts\n/// of this module\ninterface IFlashAngle {\n /// @notice Reference to the `CoreBorrow` contract managing the FlashLoan module\n function core() external view returns (ICoreBorrow);\n\n /// @notice Sends the fees taken from flash loans to the treasury contract associated to the stablecoin\n /// @param stablecoin Stablecoin from which profits should be sent\n /// @return balance Amount of profits sent\n /// @dev This function can only be called by the treasury contract\n function accrueInterestToTreasury(IAgToken stablecoin) external returns (uint256 balance);\n\n /// @notice Adds support for a stablecoin\n /// @param _treasury Treasury associated to the stablecoin to add support for\n /// @dev This function can only be called by the `CoreBorrow` contract\n function addStablecoinSupport(address _treasury) external;\n\n /// @notice Removes support for a stablecoin\n /// @param _treasury Treasury associated to the stablecoin to remove support for\n /// @dev This function can only be called by the `CoreBorrow` contract\n function removeStablecoinSupport(address _treasury) external;\n\n /// @notice Sets a new core contract\n /// @param _core Core contract address to set\n /// @dev This function can only be called by the `CoreBorrow` contract\n function setCore(address _core) external;\n}\n" + }, + "contracts/interfaces/IKeeperRegistry.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\nimport \"@openzeppelin/contracts-upgradeable/token/ERC20/IERC20Upgradeable.sol\";\n\n/// @title IKeeperRegistry\n/// @author Angle Labs, Inc.\ninterface IKeeperRegistry {\n /// @notice Checks whether an address is whitelisted during oracle updates\n /// @param caller Address for which the whitelist should be checked\n /// @return Whether the address is trusted or not\n function isTrusted(address caller) external view returns (bool);\n}\n" + }, + "contracts/interfaces/ILiquidityGauge.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.7;\n\ninterface ILiquidityGauge {\n function deposit(\n uint256 _value,\n address _addr,\n // solhint-disable-next-line\n bool _claim_rewards\n ) external;\n\n function withdraw(\n uint256 _value,\n // solhint-disable-next-line\n bool _claim_rewards\n ) external;\n\n // solhint-disable-next-line\n function claim_rewards(address _addr, address _receiver) external;\n\n // solhint-disable-next-line\n function claimable_reward(address _addr, address _reward_token) external view returns (uint256 amount);\n\n /// @dev Only for testing purposes\n // solhint-disable-next-line\n function deposit_reward_token(address _rewardToken, uint256 _amount) external;\n}\n" + }, + "contracts/interfaces/IOracle.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\nimport \"./ITreasury.sol\";\nimport \"@chainlink/contracts/src/v0.8/interfaces/AggregatorV3Interface.sol\";\n\n/// @title IOracle\n/// @author Angle Labs, Inc.\n/// @notice Interface for the `Oracle` contract\n/// @dev This interface only contains functions of the contract which are called by other contracts\n/// of this module\ninterface IOracle {\n /// @notice Reads the rate from the Chainlink circuit and other data provided\n /// @return quoteAmount The current rate between the in-currency and out-currency in the base\n /// of the out currency\n /// @dev For instance if the out currency is EUR (and hence agEUR), then the base of the returned\n /// value is 10**18\n function read() external view returns (uint256);\n\n /// @notice Changes the treasury contract\n /// @param _treasury Address of the new treasury contract\n /// @dev This function can be called by an approved `VaultManager` contract which can call\n /// this function after being requested to do so by a `treasury` contract\n /// @dev In some situations (like reactor contracts), the `VaultManager` may not directly be linked\n /// to the `oracle` contract and as such we may need governors to be able to call this function as well\n function setTreasury(address _treasury) external;\n\n /// @notice Reference to the `treasury` contract handling this `VaultManager`\n function treasury() external view returns (ITreasury treasury);\n\n /// @notice Array with the list of Chainlink feeds in the order in which they are read\n function circuitChainlink() external view returns (AggregatorV3Interface[] memory);\n}\n" + }, + "contracts/interfaces/ISwapper.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\nimport \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\n\n/// @title ISwapper\n/// @author Angle Labs, Inc.\n/// @notice Interface for Swapper contracts\n/// @dev This interface defines the key functions `Swapper` contracts should have when interacting with\n/// Angle\ninterface ISwapper {\n /// @notice Notifies a contract that an address should be given `outToken` from `inToken`\n /// @param inToken Address of the token received\n /// @param outToken Address of the token to obtain\n /// @param outTokenRecipient Address to which the outToken should be sent\n /// @param outTokenOwed Minimum amount of outToken the `outTokenRecipient` address should have at the end of the call\n /// @param inTokenObtained Amount of collateral obtained by a related address prior\n /// to the call to this function\n /// @param data Extra data needed (to encode Uniswap swaps for instance)\n function swap(\n IERC20 inToken,\n IERC20 outToken,\n address outTokenRecipient,\n uint256 outTokenOwed,\n uint256 inTokenObtained,\n bytes calldata data\n ) external;\n}\n" + }, + "contracts/interfaces/ITreasury.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\nimport \"./IAgToken.sol\";\nimport \"./ICoreBorrow.sol\";\nimport \"./IFlashAngle.sol\";\n\n/// @title ITreasury\n/// @author Angle Labs, Inc.\n/// @notice Interface for the `Treasury` contract\n/// @dev This interface only contains functions of the `Treasury` which are called by other contracts\n/// of this module\ninterface ITreasury {\n /// @notice Stablecoin handled by this `treasury` contract\n function stablecoin() external view returns (IAgToken);\n\n /// @notice Checks whether a given address has the governor role\n /// @param admin Address to check\n /// @return Whether the address has the governor role\n /// @dev Access control is only kept in the `CoreBorrow` contract\n function isGovernor(address admin) external view returns (bool);\n\n /// @notice Checks whether a given address has the guardian or the governor role\n /// @param admin Address to check\n /// @return Whether the address has the guardian or the governor role\n /// @dev Access control is only kept in the `CoreBorrow` contract which means that this function\n /// queries the `CoreBorrow` contract\n function isGovernorOrGuardian(address admin) external view returns (bool);\n\n /// @notice Checks whether a given address has well been initialized in this contract\n /// as a `VaultManager`\n /// @param _vaultManager Address to check\n /// @return Whether the address has been initialized or not\n function isVaultManager(address _vaultManager) external view returns (bool);\n\n /// @notice Sets a new flash loan module for this stablecoin\n /// @param _flashLoanModule Reference to the new flash loan module\n /// @dev This function removes the minting right to the old flash loan module and grants\n /// it to the new module\n function setFlashLoanModule(address _flashLoanModule) external;\n\n /// @notice Gets the vault manager list\n function vaultManagerList(uint256 i) external returns (address);\n}\n" + }, + "contracts/interfaces/IVaultManager.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\nimport \"@openzeppelin/contracts/interfaces/IERC721Metadata.sol\";\nimport \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\nimport \"./ITreasury.sol\";\nimport \"./IOracle.sol\";\n\n// ========================= Key Structs and Enums =============================\n\n/// @notice Parameters associated to a given `VaultManager` contract: these all correspond\n/// to parameters which signification is detailed in the `VaultManagerStorage` file\nstruct VaultParameters {\n uint256 debtCeiling;\n uint64 collateralFactor;\n uint64 targetHealthFactor;\n uint64 interestRate;\n uint64 liquidationSurcharge;\n uint64 maxLiquidationDiscount;\n bool whitelistingActivated;\n uint256 baseBoost;\n}\n\n/// @notice Data stored to track someone's loan (or equivalently called position)\nstruct Vault {\n // Amount of collateral deposited in the vault, in collateral decimals. For example, if the collateral\n // is USDC with 6 decimals, then `collateralAmount` will be in base 10**6\n uint256 collateralAmount;\n // Normalized value of the debt (that is to say of the stablecoins borrowed). It is expressed\n // in the base of Angle stablecoins (i.e. `BASE_TOKENS = 10**18`)\n uint256 normalizedDebt;\n}\n\n/// @notice For a given `vaultID`, this encodes a liquidation opportunity that is to say details about the maximum\n/// amount that could be repaid by liquidating the position\n/// @dev All the values are null in the case of a vault which cannot be liquidated under these conditions\nstruct LiquidationOpportunity {\n // Maximum stablecoin amount that can be repaid upon liquidating the vault\n uint256 maxStablecoinAmountToRepay;\n // Collateral amount given to the person in the case where the maximum amount to repay is given\n uint256 maxCollateralAmountGiven;\n // Threshold value of stablecoin amount to repay: it is ok for a liquidator to repay below threshold,\n // but if this threshold is non null and the liquidator wants to repay more than threshold, it should repay\n // the max stablecoin amount given in this vault\n uint256 thresholdRepayAmount;\n // Discount proposed to the liquidator on the collateral\n uint256 discount;\n // Amount of debt in the vault\n uint256 currentDebt;\n}\n\n/// @notice Data stored during a liquidation process to keep in memory what's due to a liquidator and some\n/// essential data for vaults being liquidated\nstruct LiquidatorData {\n // Current amount of stablecoins the liquidator should give to the contract\n uint256 stablecoinAmountToReceive;\n // Current amount of collateral the contract should give to the liquidator\n uint256 collateralAmountToGive;\n // Bad debt accrued across the liquidation process\n uint256 badDebtFromLiquidation;\n // Oracle value (in stablecoin base) at the time of the liquidation\n uint256 oracleValue;\n // Value of the `interestAccumulator` at the time of the call\n uint256 newInterestAccumulator;\n}\n\n/// @notice Data to track during a series of action the amount to give or receive in stablecoins and collateral\n/// to the caller or associated addresses\nstruct PaymentData {\n // Stablecoin amount the contract should give\n uint256 stablecoinAmountToGive;\n // Stablecoin amount owed to the contract\n uint256 stablecoinAmountToReceive;\n // Collateral amount the contract should give\n uint256 collateralAmountToGive;\n // Collateral amount owed to the contract\n uint256 collateralAmountToReceive;\n}\n\n/// @notice Actions possible when composing calls to the different entry functions proposed\nenum ActionType {\n createVault,\n closeVault,\n addCollateral,\n removeCollateral,\n repayDebt,\n borrow,\n getDebtIn,\n permit\n}\n\n// ========================= Interfaces =============================\n\n/// @title IVaultManagerFunctions\n/// @author Angle Labs, Inc.\n/// @notice Interface for the `VaultManager` contract\n/// @dev This interface only contains functions of the contract which are called by other contracts\n/// of this module (without getters)\ninterface IVaultManagerFunctions {\n /// @notice Accrues interest accumulated across all vaults to the surplus and sends the surplus to the treasury\n /// @return surplusValue Value of the surplus communicated to the `Treasury`\n /// @return badDebtValue Value of the bad debt communicated to the `Treasury`\n /// @dev `surplus` and `badDebt` should be reset to 0 once their current value have been given to the `treasury` contract\n function accrueInterestToTreasury() external returns (uint256 surplusValue, uint256 badDebtValue);\n\n /// @notice Removes debt from a vault after being requested to do so by another `VaultManager` contract\n /// @param vaultID ID of the vault to remove debt from\n /// @param amountStablecoins Amount of stablecoins to remove from the debt: this amount is to be converted to an\n /// internal debt amount\n /// @param senderBorrowFee Borrowing fees from the contract which requested this: this is to make sure that people are not\n /// arbitraging difference in minting fees\n /// @param senderRepayFee Repay fees from the contract which requested this: this is to make sure that people are not arbitraging\n /// differences in repay fees\n /// @dev This function can only be called from a vaultManager registered in the same Treasury\n function getDebtOut(\n uint256 vaultID,\n uint256 amountStablecoins,\n uint256 senderBorrowFee,\n uint256 senderRepayFee\n ) external;\n\n /// @notice Gets the current debt of a vault\n /// @param vaultID ID of the vault to check\n /// @return Debt of the vault\n function getVaultDebt(uint256 vaultID) external view returns (uint256);\n\n /// @notice Gets the total debt across all vaults\n /// @return Total debt across all vaults, taking into account the interest accumulated\n /// over time\n function getTotalDebt() external view returns (uint256);\n\n /// @notice Sets the treasury contract\n /// @param _treasury New treasury contract\n /// @dev All required checks when setting up a treasury contract are performed in the contract\n /// calling this function\n function setTreasury(address _treasury) external;\n\n /// @notice Creates a vault\n /// @param toVault Address for which the va\n /// @return vaultID ID of the vault created\n /// @dev This function just creates the vault without doing any collateral or\n function createVault(address toVault) external returns (uint256);\n\n /// @notice Allows composability between calls to the different entry points of this module. Any user calling\n /// this function can perform any of the allowed actions in the order of their choice\n /// @param actions Set of actions to perform\n /// @param datas Data to be decoded for each action: it can include like the `vaultID` or the `stablecoinAmount` to borrow\n /// @param from Address from which stablecoins will be taken if one action includes burning stablecoins. This address\n /// should either be the `msg.sender` or be approved by the latter\n /// @param to Address to which stablecoins and/or collateral will be sent in case of\n /// @param who Address of the contract to handle in case of repayment of stablecoins from received collateral\n /// @param repayData Data to pass to the repayment contract in case of\n /// @return paymentData Struct containing the accounting changes from the protocol's perspective (like how much of collateral\n /// or how much has been received). Note that the values in the struct are not aggregated and you could have in the output\n /// a positive amount of stablecoins to receive as well as a positive amount of stablecoins to give\n /// @dev This function is optimized to reduce gas cost due to payment from or to the user and that expensive calls\n /// or computations (like `oracleValue`) are done only once\n /// @dev When specifying `vaultID` in `data`, it is important to know that if you specify `vaultID = 0`, it will simply\n /// use the latest `vaultID`. This is the default behavior, and unless you're engaging into some complex protocol actions\n /// it is encouraged to use `vaultID = 0` only when the first action of the batch is `createVault`\n function angle(\n ActionType[] memory actions,\n bytes[] memory datas,\n address from,\n address to,\n address who,\n bytes memory repayData\n ) external returns (PaymentData memory paymentData);\n\n /// @notice This function is a wrapper built on top of the function above. It enables users to interact with the contract\n /// without having to provide `who` and `repayData` parameters\n function angle(\n ActionType[] memory actions,\n bytes[] memory datas,\n address from,\n address to\n ) external returns (PaymentData memory paymentData);\n\n /// @notice Initializes the `VaultManager` contract\n /// @param _treasury Treasury address handling the contract\n /// @param _collateral Collateral supported by this contract\n /// @param _oracle Oracle contract used\n /// @param _symbol Symbol used to define the `VaultManager` name and symbol\n /// @dev The parameters and the oracle are the only elements which could be modified once the\n /// contract has been initialized\n /// @dev For the contract to be fully initialized, governance needs to set the parameters for the liquidation\n /// boost\n function initialize(\n ITreasury _treasury,\n IERC20 _collateral,\n IOracle _oracle,\n VaultParameters calldata params,\n string memory _symbol\n ) external;\n\n /// @notice Minimum amount of debt a vault can have, expressed in `BASE_TOKENS` that is to say the base of the agTokens\n function dust() external view returns (uint256);\n\n /// @notice Pauses external permissionless functions of the contract\n function togglePause() external;\n}\n\n/// @title IVaultManagerStorage\n/// @author Angle Labs, Inc.\n/// @notice Interface for the `VaultManager` contract\n/// @dev This interface contains getters of the contract's public variables used by other contracts\n/// of this module\ninterface IVaultManagerStorage {\n /// @notice Encodes the maximum ratio stablecoin/collateral a vault can have before being liquidated. It's what\n /// determines the minimum collateral ratio of a position\n function collateralFactor() external view returns (uint64);\n\n /// @notice Stablecoin handled by this contract. Another `VaultManager` contract could have\n /// the same rights as this `VaultManager` on the stablecoin contract\n function stablecoin() external view returns (IAgToken);\n\n /// @notice Reference to the `treasury` contract handling this `VaultManager`\n function treasury() external view returns (ITreasury);\n\n /// @notice Oracle contract to get access to the price of the collateral with respect to the stablecoin\n function oracle() external view returns (IOracle);\n\n /// @notice The `interestAccumulator` variable keeps track of the interest that should accrue to the protocol.\n /// The stored value is not necessarily the true value: this one is recomputed every time an action takes place\n /// within the protocol. It is in base `BASE_INTEREST`\n function interestAccumulator() external view returns (uint256);\n\n /// @notice Reference to the collateral handled by this `VaultManager`\n function collateral() external view returns (IERC20);\n\n /// @notice Total normalized amount of stablecoins borrowed, not taking into account the potential bad debt accumulated\n /// This value is expressed in the base of Angle stablecoins (`BASE_TOKENS = 10**18`)\n function totalNormalizedDebt() external view returns (uint256);\n\n /// @notice Maximum amount of stablecoins that can be issued with this contract. It is expressed in `BASE_TOKENS`\n function debtCeiling() external view returns (uint256);\n\n /// @notice Maps a `vaultID` to its data (namely collateral amount and normalized debt)\n function vaultData(uint256 vaultID) external view returns (uint256 collateralAmount, uint256 normalizedDebt);\n\n /// @notice ID of the last vault created. The `vaultIDCount` variables serves as a counter to generate a unique\n /// `vaultID` for each vault: it is like `tokenID` in basic ERC721 contracts\n function vaultIDCount() external view returns (uint256);\n}\n\n/// @title IVaultManager\n/// @author Angle Labs, Inc.\n/// @notice Interface for the `VaultManager` contract\ninterface IVaultManager is IVaultManagerFunctions, IVaultManagerStorage, IERC721Metadata {\n function isApprovedOrOwner(address spender, uint256 vaultID) external view returns (bool);\n}\n\n/// @title IVaultManagerListing\n/// @author Angle Labs, Inc.\n/// @notice Interface for the `VaultManagerListing` contract\ninterface IVaultManagerListing is IVaultManager {\n /// @notice Get the collateral owned by `user` in the contract\n /// @dev This function effectively sums the collateral amounts of all the vaults owned by `user`\n function getUserCollateral(address user) external view returns (uint256);\n}\n" + }, + "contracts/keeperMulticall/KeeperMulticall.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\nimport \"@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/access/AccessControlUpgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol\";\nimport \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\nimport \"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\";\nimport \"./RevertReasonParser.sol\";\n\n/// @title KeeperMulticall\n/// @notice Allows an authorized caller (keeper) to execute multiple actions in a single tx.\n/// @author Angle Labs, Inc.\n/// @dev Special features:\n/// - ability to pay the miner (for private Flashbots transactions)\n/// - swap tokens through 1inch\n/// @dev Tx need to be encoded as an array of Action. The flag `isDelegateCall` is used for calling functions within this same contract\ncontract KeeperMulticall is Initializable, AccessControlUpgradeable {\n using SafeERC20 for IERC20;\n\n bytes32 public constant KEEPER_ROLE = keccak256(\"KEEPER_ROLE\");\n\n //solhint-disable-next-line\n address private constant _oneInch = 0x1111111254fb6c44bAC0beD2854e76F90643097d;\n\n struct Action {\n address target;\n bytes data;\n bool isDelegateCall;\n }\n\n event LogAction(address indexed target, bytes data);\n event SentToMiner(uint256 indexed value);\n event Recovered(address indexed tokenAddress, address indexed to, uint256 amount);\n\n error AmountOutTooLow(uint256 amount, uint256 min);\n error BalanceTooLow();\n error FlashbotsErrorPayingMiner(uint256 value);\n error IncompatibleLengths();\n error RevertBytes();\n error WrongAmount();\n error ZeroAddress();\n\n constructor() initializer {}\n\n function initialize(address keeper) external initializer {\n __AccessControl_init();\n\n _setupRole(KEEPER_ROLE, keeper);\n _setRoleAdmin(KEEPER_ROLE, KEEPER_ROLE);\n }\n\n /// @notice Allows an authorized keeper to execute multiple actions in a single step\n /// @param actions Actions to be executed\n /// @param percentageToMiner Percentage to pay to miner expressed in bps (10000)\n /// @dev This is the main entry point for actions to be executed. The `isDelegateCall` flag is used for calling function inside this `KeeperMulticall` contract,\n /// if we call other contracts, the flag should be false\n function executeActions(\n Action[] memory actions,\n uint256 percentageToMiner\n ) external payable onlyRole(KEEPER_ROLE) returns (bytes[] memory) {\n uint256 numberOfActions = actions.length;\n if (numberOfActions == 0) revert IncompatibleLengths();\n\n bytes[] memory returnValues = new bytes[](numberOfActions + 1);\n\n uint256 balanceBefore = address(this).balance;\n\n for (uint256 i; i < numberOfActions; ++i) {\n returnValues[i] = _executeAction(actions[i]);\n }\n\n if (percentageToMiner != 0) {\n if (percentageToMiner >= 10000) revert WrongAmount();\n uint256 balanceAfter = address(this).balance;\n if (balanceAfter > balanceBefore) {\n uint256 amountToMiner = ((balanceAfter - balanceBefore) * percentageToMiner) / 10000;\n returnValues[numberOfActions] = payFlashbots(amountToMiner);\n }\n }\n\n return returnValues;\n }\n\n /// @notice Gets the action address and data and executes it\n /// @param action Action to be executed\n function _executeAction(Action memory action) internal returns (bytes memory) {\n bool success;\n bytes memory response;\n\n if (action.isDelegateCall) {\n //solhint-disable-next-line\n (success, response) = action.target.delegatecall(action.data);\n } else {\n //solhint-disable-next-line\n (success, response) = action.target.call(action.data);\n }\n\n require(success, RevertReasonParser.parse(response, \"action reverted: \"));\n emit LogAction(action.target, action.data);\n return response;\n }\n\n /// @notice Ability to pay miner directly. Used for Flashbots to execute private transactions\n /// @param value Value to be sent\n function payFlashbots(uint256 value) public payable onlyRole(KEEPER_ROLE) returns (bytes memory) {\n //solhint-disable-next-line\n (bool success, bytes memory response) = block.coinbase.call{ value: value }(\"\");\n if (!success) revert FlashbotsErrorPayingMiner(value);\n emit SentToMiner(value);\n return response;\n }\n\n /// @notice Used to check the balances the token holds for each token. If we don't have enough of a token, we revert the tx\n /// @param tokens Array of tokens to check\n /// @param minBalances Array of balances for each token\n function finalBalanceCheck(IERC20[] memory tokens, uint256[] memory minBalances) external view returns (bool) {\n uint256 tokensLength = tokens.length;\n if (tokensLength == 0 || tokensLength != minBalances.length) revert IncompatibleLengths();\n\n for (uint256 i; i < tokensLength; ++i) {\n if (address(tokens[i]) == 0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE) {\n if (address(this).balance < minBalances[i]) revert BalanceTooLow();\n } else {\n if (tokens[i].balanceOf(address(this)) < minBalances[i]) revert BalanceTooLow();\n }\n }\n\n return true;\n }\n\n /// @notice Swap token to another through 1Inch\n /// @param minAmountOut Minimum amount of `out` token to receive for the swap to happen\n /// @param payload Bytes needed for 1Inch API\n function swapToken(uint256 minAmountOut, bytes memory payload) external onlyRole(KEEPER_ROLE) {\n //solhint-disable-next-line\n (bool success, bytes memory result) = _oneInch.call(payload);\n if (!success) _revertBytes(result);\n\n uint256 amountOut = abi.decode(result, (uint256));\n if (amountOut < minAmountOut) revert AmountOutTooLow(amountOut, minAmountOut);\n }\n\n /// @notice Copied from 1Inch contract, used to revert if there is an error\n function _revertBytes(bytes memory errMsg) internal pure {\n if (errMsg.length != 0) {\n //solhint-disable-next-line\n assembly {\n revert(add(32, errMsg), mload(errMsg))\n }\n }\n revert RevertBytes();\n }\n\n /// @notice Approve a `spender` for `token`\n /// @param token Address of the token to approve\n /// @param spender Address of the spender to approve\n /// @param amount Amount to approve\n function approve(IERC20 token, address spender, uint256 amount) external onlyRole(KEEPER_ROLE) {\n uint256 currentAllowance = token.allowance(address(this), spender);\n if (currentAllowance < amount) {\n token.safeIncreaseAllowance(spender, amount - currentAllowance);\n } else if (currentAllowance > amount) {\n token.safeDecreaseAllowance(spender, currentAllowance - amount);\n }\n }\n\n receive() external payable {}\n\n /// @notice Withdraw stuck funds\n /// @param token Address of the token to recover\n /// @param receiver Address where to send the tokens\n /// @param amount Amount to recover\n function withdrawStuckFunds(address token, address receiver, uint256 amount) external onlyRole(KEEPER_ROLE) {\n if (receiver == address(0)) revert ZeroAddress();\n if (token == 0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE) {\n payable(receiver).transfer(amount);\n } else {\n IERC20(token).safeTransfer(receiver, amount);\n }\n\n emit Recovered(token, receiver, amount);\n }\n}\n" + }, + "contracts/keeperMulticall/MulticallWithFailure.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.12;\n\n/// @title MultiCallWithFailure\n/// @author Angle Labs, Inc.\n/// @notice Multicall contract allowing subcalls to fail without reverting the entire call\ncontract MultiCallWithFailure {\n error SubcallFailed();\n\n struct Call {\n address target;\n bytes data;\n bool canFail;\n }\n\n function multiCall(Call[] memory calls) external view returns (bytes[] memory) {\n bytes[] memory results = new bytes[](calls.length);\n\n for (uint256 i; i < calls.length; ++i) {\n (bool success, bytes memory result) = calls[i].target.staticcall(calls[i].data);\n if (!calls[i].canFail) {\n if (!success) {\n revert SubcallFailed();\n }\n }\n results[i] = result;\n }\n\n return results;\n }\n}\n" + }, + "contracts/keeperMulticall/RevertReasonParser.sol": { + "content": "// SPDX-License-Identifier: GNU-3\n\npragma solidity ^0.8.12;\n\n/// @title RevertReasonParser\n/// @author 1Inch team, taken from:\n/// - https://docs.1inch.io/docs/limit-order-protocol/smart-contract/libraries/RevertReasonParser/\n/// - https://etherscan.io/address/0x1111111254fb6c44bAC0beD2854e76F90643097d#code\nlibrary RevertReasonParser {\n bytes4 private constant _PANIC_SELECTOR = bytes4(keccak256(\"Panic(uint256)\"));\n bytes4 private constant _ERROR_SELECTOR = bytes4(keccak256(\"Error(string)\"));\n\n function parse(bytes memory data, string memory prefix) internal pure returns (string memory) {\n if (data.length >= 4) {\n bytes4 selector;\n //solhint-disable-next-line\n assembly {\n selector := mload(add(data, 0x20))\n }\n\n // 68 = 4-byte selector + 32 bytes offset + 32 bytes length\n if (selector == _ERROR_SELECTOR && data.length >= 68) {\n uint256 offset;\n bytes memory reason;\n // solhint-disable no-inline-assembly\n assembly {\n // 36 = 32 bytes data length + 4-byte selector\n offset := mload(add(data, 36))\n reason := add(data, add(36, offset))\n }\n /*\n revert reason is padded up to 32 bytes with ABI encoder: Error(string)\n also sometimes there is extra 32 bytes of zeros padded in the end:\n https://github.com/ethereum/solidity/issues/10170\n because of that we can't check for equality and instead check\n that offset + string length + extra 36 bytes is less than overall data length\n */\n require(data.length >= 36 + offset + reason.length, \"Invalid revert reason\");\n return string(abi.encodePacked(prefix, \"Error(\", reason, \")\"));\n }\n // 36 = 4-byte selector + 32 bytes integer\n else if (selector == _PANIC_SELECTOR && data.length == 36) {\n uint256 code;\n // solhint-disable no-inline-assembly\n assembly {\n // 36 = 32 bytes data length + 4-byte selector\n code := mload(add(data, 36))\n }\n return string(abi.encodePacked(prefix, \"Panic(\", _toHex(code), \")\"));\n }\n }\n\n return string(abi.encodePacked(prefix, \"Unknown(\", _toHex(data), \")\"));\n }\n\n function _toHex(uint256 value) private pure returns (string memory) {\n return _toHex(abi.encodePacked(value));\n }\n\n function _toHex(bytes memory data) private pure returns (string memory) {\n bytes16 alphabet = 0x30313233343536373839616263646566;\n bytes memory str = new bytes(2 + data.length * 2);\n str[0] = \"0\";\n str[1] = \"x\";\n for (uint256 i; i < data.length; ++i) {\n str[2 * i + 2] = alphabet[uint8(data[i] >> 4)];\n str[2 * i + 3] = alphabet[uint8(data[i] & 0x0f)];\n }\n return string(str);\n }\n}\n" + }, + "contracts/mock/Mock1Inch.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.12;\n\nimport \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\nimport \"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\";\n\ncontract Mock1Inch {\n using SafeERC20 for IERC20;\n\n function swap(address tokenIn, uint256 amountIn, address to, address tokenOut, uint256 amountOut) external {\n IERC20(tokenIn).safeTransferFrom(msg.sender, to, amountIn);\n if (tokenOut == 0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE) {\n //solhint-disable-next-line\n (bool sent, bytes memory data) = msg.sender.call{ value: amountOut }(\"\");\n data;\n require(sent, \"Failed to send Ether\");\n } else {\n IERC20(tokenOut).safeTransferFrom(to, msg.sender, amountOut);\n }\n }\n\n receive() external payable {}\n}\n" + }, + "contracts/mock/MockAnything.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.12;\n\ncontract MockAnything {\n uint256 public stateVar = 1;\n\n error CustomError();\n error CustomErrorWithValue(uint256);\n\n function fail(uint256 value) external view returns (uint256) {\n stateVar;\n if (value < 10) {\n revert CustomError();\n }\n if (value < 20) {\n revert CustomErrorWithValue(value);\n }\n return value + 1;\n }\n\n function modifyState(uint256 value) external {\n stateVar = value;\n }\n}\n" + }, + "contracts/mock/MockChainlinkOracle.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.7;\n\ninterface MockAggregatorV3Interface {\n function decimals() external view returns (uint8);\n\n function description() external view returns (string memory);\n\n function version() external view returns (uint256);\n\n function getRoundData(\n uint80 _roundId\n )\n external\n view\n returns (uint80 roundId, int256 answer, uint256 startedAt, uint256 updatedAt, uint80 answeredInRound);\n\n function latestRoundData()\n external\n view\n returns (uint80 roundId, int256 answer, uint256 startedAt, uint256 updatedAt, uint80 answeredInRound);\n}\n\ncontract MockChainlinkOracle is MockAggregatorV3Interface {\n uint80 public roundId = 0;\n uint8 public keyDecimals = 0;\n\n struct Entry {\n uint80 roundId;\n int256 answer;\n uint256 startedAt;\n uint256 updatedAt;\n uint80 answeredInRound;\n }\n\n mapping(uint256 => Entry) public entries;\n\n bool public latestRoundDataShouldRevert;\n\n string public desc;\n\n constructor() {}\n\n // Mock setup function\n function setLatestAnswer(int256 answer, uint256 timestamp) external {\n roundId++;\n entries[roundId] = Entry({\n roundId: roundId,\n answer: answer,\n startedAt: timestamp,\n updatedAt: timestamp,\n answeredInRound: roundId\n });\n }\n\n function setLatestAnswerWithRound(int256 answer, uint256 timestamp, uint80 _roundId) external {\n roundId = _roundId;\n entries[roundId] = Entry({\n roundId: roundId,\n answer: answer,\n startedAt: timestamp,\n updatedAt: timestamp,\n answeredInRound: roundId\n });\n }\n\n function setLatestAnswerRevert(int256 answer, uint256 timestamp) external {\n roundId++;\n entries[roundId] = Entry({\n roundId: roundId,\n answer: answer,\n startedAt: timestamp,\n updatedAt: timestamp,\n answeredInRound: roundId - 1\n });\n }\n\n function setLatestRoundDataShouldRevert(bool _shouldRevert) external {\n latestRoundDataShouldRevert = _shouldRevert;\n }\n\n function setDecimals(uint8 _decimals) external {\n keyDecimals = _decimals;\n }\n\n function setDescritpion(string memory _desc) external {\n desc = _desc;\n }\n\n function description() external view override returns (string memory) {\n return desc;\n }\n\n function version() external view override returns (uint256) {\n roundId;\n return 0;\n }\n\n function latestRoundData() external view override returns (uint80, int256, uint256, uint256, uint80) {\n if (latestRoundDataShouldRevert) {\n revert(\"latestRoundData reverted\");\n }\n return getRoundData(uint80(roundId));\n }\n\n function decimals() external view override returns (uint8) {\n return keyDecimals;\n }\n\n function getRoundData(uint80 _roundId) public view override returns (uint80, int256, uint256, uint256, uint80) {\n Entry memory entry = entries[_roundId];\n // Emulate a Chainlink aggregator\n require(entry.updatedAt > 0, \"No data present\");\n return (entry.roundId, entry.answer, entry.startedAt, entry.updatedAt, entry.answeredInRound);\n }\n}\n" + }, + "contracts/mock/MockCoreBorrow.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\nimport \"../interfaces/ICoreBorrow.sol\";\nimport \"../interfaces/IFlashAngle.sol\";\nimport \"../interfaces/ITreasury.sol\";\n\ncontract MockCoreBorrow is ICoreBorrow {\n mapping(address => bool) public flashLoaners;\n mapping(address => bool) public governors;\n mapping(address => bool) public guardians;\n\n function isFlashLoanerTreasury(address treasury) external view override returns (bool) {\n return flashLoaners[treasury];\n }\n\n function isGovernor(address admin) external view override returns (bool) {\n return governors[admin];\n }\n\n function isGovernorOrGuardian(address admin) external view override returns (bool) {\n return governors[admin] || guardians[admin];\n }\n\n function toggleGovernor(address admin) external {\n governors[admin] = !governors[admin];\n }\n\n function toggleGuardian(address admin) external {\n guardians[admin] = !guardians[admin];\n }\n\n function toggleFlashLoaners(address admin) external {\n flashLoaners[admin] = !flashLoaners[admin];\n }\n\n function addStablecoinSupport(IFlashAngle flashAngle, address _treasury) external {\n flashAngle.addStablecoinSupport(_treasury);\n }\n\n function removeStablecoinSupport(IFlashAngle flashAngle, address _treasury) external {\n flashAngle.removeStablecoinSupport(_treasury);\n }\n\n function setCore(IFlashAngle flashAngle, address _core) external {\n flashAngle.setCore(_core);\n }\n\n function setFlashLoanModule(ITreasury _treasury, address _flashLoanModule) external {\n _treasury.setFlashLoanModule(_flashLoanModule);\n }\n}\n" + }, + "contracts/mock/MockERC1271.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.12;\n\nimport \"../interfaces/external/IERC1271.sol\";\n\ncontract MockERC1271 is IERC1271 {\n uint256 public mode = 0;\n\n function setMode(uint256 _mode) public {\n mode = _mode;\n }\n\n /// @notice Returns whether the provided signature is valid for the provided data\n /// @dev MUST return the bytes4 magic value 0x1626ba7e when function passes.\n /// MUST NOT modify state (using STATICCALL for solc < 0.5, view modifier for solc > 0.5).\n /// MUST allow external calls.\n /// @return magicValue The bytes4 magic value 0x1626ba7e\n function isValidSignature(bytes32, bytes memory) external view returns (bytes4 magicValue) {\n if (mode == 1) magicValue = 0x1626ba7e;\n }\n}\n" + }, + "contracts/mock/MockERC721Receiver.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (token/ERC721/utils/ERC721Holder.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Implementation of the {IERC721Receiver} interface.\n *\n * Accepts all token transfers.\n * Make sure the contract is able to use its token with {IERC721-safeTransferFrom}, {IERC721-approve} or {IERC721-setApprovalForAll}.\n */\ncontract MockERC721Receiver {\n uint256 public mode = 0;\n\n function setMode(uint256 _mode) public {\n mode = _mode;\n }\n\n function onERC721Received(address, address, uint256, bytes memory) public view returns (bytes4) {\n require(mode != 1, \"0x1111111\");\n if (mode == 2) return this.setMode.selector;\n return this.onERC721Received.selector;\n }\n}\n" + }, + "contracts/mock/MockEulerPool.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\nimport \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\n\ncontract MockEulerPool {\n IERC20 public collateral;\n uint256 public poolSize;\n //solhint-disable-next-line\n uint256 public MAX_SANE_AMOUNT;\n\n mapping(address => uint256) public users;\n uint256 public interestRateAccumulator;\n\n constructor(IERC20 collateral_, uint256 poolSize_) {\n collateral = collateral_;\n poolSize = poolSize_;\n interestRateAccumulator = 10 ** 18;\n MAX_SANE_AMOUNT = type(uint112).max;\n }\n\n function setPoolSize(uint256 poolSize_) external {\n uint256 balance = collateral.balanceOf(address(this));\n poolSize = poolSize_;\n if (balance > poolSize_) collateral.transfer(msg.sender, balance - poolSize_);\n if (balance < poolSize_) collateral.transferFrom(msg.sender, address(this), poolSize_ - balance);\n }\n\n function setInterestRateAccumulator(uint256 interestRateAccumulator_) external {\n interestRateAccumulator = interestRateAccumulator_;\n }\n\n //solhint-disable-next-line\n function setMAXSANEAMOUNT(uint256 MAX_SANE_AMOUNT_) external {\n MAX_SANE_AMOUNT = MAX_SANE_AMOUNT_;\n }\n\n function balanceOfUnderlying(address account) external view returns (uint256) {\n return (users[account] * interestRateAccumulator) / 10 ** 18;\n }\n\n function deposit(uint256, uint256 amount) external {\n users[msg.sender] += (amount * 10 ** 18) / interestRateAccumulator;\n poolSize += amount;\n collateral.transferFrom(msg.sender, address(this), amount);\n }\n\n function withdraw(uint256, uint256 amount) external {\n if (amount == type(uint256).max) amount = (users[msg.sender] * interestRateAccumulator) / 10 ** 18;\n\n require(amount <= poolSize, \"4\");\n users[msg.sender] -= (amount * 10 ** 18) / interestRateAccumulator;\n collateral.transfer(msg.sender, amount);\n }\n}\n" + }, + "contracts/mock/MockFlashLoanModule.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\nimport \"../interfaces/IFlashAngle.sol\";\nimport \"../interfaces/ICoreBorrow.sol\";\n\ncontract MockFlashLoanModule is IFlashAngle {\n ICoreBorrow public override core;\n mapping(address => bool) public stablecoinsSupported;\n mapping(IAgToken => uint256) public interestAccrued;\n uint256 public surplusValue;\n\n constructor(ICoreBorrow _core) {\n core = _core;\n }\n\n function accrueInterestToTreasury(IAgToken stablecoin) external override returns (uint256 balance) {\n balance = surplusValue;\n interestAccrued[stablecoin] += balance;\n }\n\n function addStablecoinSupport(address _treasury) external override {\n stablecoinsSupported[_treasury] = true;\n }\n\n function removeStablecoinSupport(address _treasury) external override {\n stablecoinsSupported[_treasury] = false;\n }\n\n function setCore(address _core) external override {\n core = ICoreBorrow(_core);\n }\n\n function setSurplusValue(uint256 _surplusValue) external {\n surplusValue = _surplusValue;\n }\n}\n" + }, + "contracts/mock/MockFlashLoanReceiver.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.7;\n\nimport \"@openzeppelin/contracts/token/ERC20/ERC20.sol\";\n\nimport \"@openzeppelin/contracts/interfaces/IERC3156FlashBorrower.sol\";\n\nimport \"@openzeppelin/contracts/interfaces/IERC3156FlashLender.sol\";\n\ncontract MockFlashLoanReceiver is IERC3156FlashBorrower {\n bytes32 public constant CALLBACK_SUCCESS = keccak256(\"ERC3156FlashBorrower.onFlashLoan\");\n\n constructor() {}\n\n function onFlashLoan(\n address,\n address token,\n uint256 amount,\n uint256 fee,\n bytes calldata data\n ) external override returns (bytes32) {\n IERC20(token).approve(msg.sender, amount + fee);\n if (amount >= 10 ** 21) return keccak256(\"error\");\n if (amount == 2 * 10 ** 18) {\n IERC3156FlashLender(msg.sender).flashLoan(IERC3156FlashBorrower(address(this)), token, amount, data);\n return keccak256(\"reentrant\");\n } else return CALLBACK_SUCCESS;\n }\n}\n" + }, + "contracts/mock/MockInterestRateComputer.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\ncontract MockInterestRateComputer {\n uint256 public interestRate;\n uint256 public interestAccumulator;\n uint256 public immutable baseInterest;\n uint256 public immutable halfBase;\n\n uint256 public constant WEEK = 7 * 86400;\n\n constructor(uint256 _baseInterest, uint256 _interestRate) {\n interestAccumulator = _baseInterest;\n baseInterest = _baseInterest;\n halfBase = _baseInterest / 2;\n interestRate = _interestRate;\n }\n\n function _calculateAngle(uint256 exp, uint256 _interestAccumulator) internal view returns (uint256) {\n uint256 ratePerSecond = interestRate;\n if (exp == 0 || ratePerSecond == 0) return _interestAccumulator;\n uint256 expMinusOne = exp - 1;\n uint256 expMinusTwo = exp > 2 ? exp - 2 : 0;\n uint256 basePowerTwo = (ratePerSecond * ratePerSecond) / baseInterest;\n uint256 basePowerThree = (basePowerTwo * ratePerSecond) / baseInterest;\n uint256 secondTerm = (exp * expMinusOne * basePowerTwo) / 2;\n uint256 thirdTerm = (exp * expMinusOne * expMinusTwo * basePowerThree) / 6;\n return (_interestAccumulator * (baseInterest + ratePerSecond * exp + secondTerm + thirdTerm)) / baseInterest;\n }\n\n function _calculateAave(uint256 exp, uint256 _interestAccumulator) internal view returns (uint256) {\n uint256 ratePerSecond = interestRate;\n if (exp == 0 || ratePerSecond == 0) return _interestAccumulator;\n uint256 expMinusOne = exp - 1;\n uint256 expMinusTwo = exp > 2 ? exp - 2 : 0;\n uint256 basePowerTwo = (ratePerSecond * ratePerSecond + halfBase) / baseInterest;\n uint256 basePowerThree = (basePowerTwo * ratePerSecond + halfBase) / baseInterest;\n uint256 secondTerm = (exp * expMinusOne * basePowerTwo) / 2;\n uint256 thirdTerm = (exp * expMinusOne * expMinusTwo * basePowerThree) / 6;\n return (_interestAccumulator * (baseInterest + ratePerSecond * exp + secondTerm + thirdTerm)) / baseInterest;\n }\n\n function _calculateCompound(uint256 exp, uint256 _interestAccumulator) internal view returns (uint256) {\n return _interestAccumulator * (baseInterest + interestRate * exp);\n }\n\n function _rpow(uint256 x, uint256 n, uint256 base) internal pure returns (uint256 z) {\n //solhint-disable-next-line\n assembly {\n switch x\n case 0 {\n switch n\n case 0 {\n z := base\n }\n default {\n z := 0\n }\n }\n default {\n switch mod(n, 2)\n case 0 {\n z := base\n }\n default {\n z := x\n }\n let half := div(base, 2) // for rounding.\n for {\n n := div(n, 2)\n } n {\n n := div(n, 2)\n } {\n let xx := mul(x, x)\n if iszero(eq(div(xx, x), x)) {\n revert(0, 0)\n }\n let xxRound := add(xx, half)\n if lt(xxRound, xx) {\n revert(0, 0)\n }\n x := div(xxRound, base)\n if mod(n, 2) {\n let zx := mul(z, x)\n if and(iszero(iszero(x)), iszero(eq(div(zx, x), z))) {\n revert(0, 0)\n }\n let zxRound := add(zx, half)\n if lt(zxRound, zx) {\n revert(0, 0)\n }\n z := div(zxRound, base)\n }\n }\n }\n }\n }\n\n function _calculateMaker(uint256 delta, uint256 _interestAccumulator) internal view returns (uint256) {\n return (_rpow(baseInterest + interestRate, delta, baseInterest) * _interestAccumulator) / baseInterest;\n }\n\n function calculateAngle(uint256 delta) external view returns (uint256) {\n return _calculateAngle(delta, interestAccumulator);\n }\n\n function calculateAave(uint256 delta) external view returns (uint256) {\n return _calculateAave(delta, interestAccumulator);\n }\n\n function calculateMaker(uint256 delta) external view returns (uint256) {\n return _calculateMaker(delta, interestAccumulator);\n }\n\n function calculateAngle1Year() external view returns (uint256) {\n uint256 _interestAccumulator = interestAccumulator;\n for (uint256 i; i < 52; ++i) {\n _interestAccumulator = _calculateAngle(WEEK, _interestAccumulator);\n }\n return _interestAccumulator;\n }\n\n function calculateAave1Year() external view returns (uint256) {\n uint256 _interestAccumulator = interestAccumulator;\n for (uint256 i; i < 52; ++i) {\n _interestAccumulator = _calculateAave(WEEK, _interestAccumulator);\n }\n return _interestAccumulator;\n }\n\n function calculateMaker1Year() external view returns (uint256) {\n uint256 _interestAccumulator = interestAccumulator;\n for (uint256 i; i < 52; ++i) {\n _interestAccumulator = _calculateMaker(WEEK, _interestAccumulator);\n }\n return _interestAccumulator;\n }\n\n function calculateAngle1YearDirect() external view returns (uint256) {\n uint256 _interestAccumulator = interestAccumulator;\n _interestAccumulator = _calculateAngle(52 * WEEK, _interestAccumulator);\n\n return _interestAccumulator;\n }\n\n function calculateAave1YearDirect() external view returns (uint256) {\n uint256 _interestAccumulator = interestAccumulator;\n _interestAccumulator = _calculateAave(52 * WEEK, _interestAccumulator);\n\n return _interestAccumulator;\n }\n\n function calculateMaker1YearDirect() external view returns (uint256) {\n uint256 _interestAccumulator = interestAccumulator;\n _interestAccumulator = _calculateMaker(52 * WEEK, _interestAccumulator);\n\n return _interestAccumulator;\n }\n\n function calculateCompound1YearDirect() external view returns (uint256) {\n uint256 _interestAccumulator = interestAccumulator;\n _interestAccumulator = _calculateCompound(52 * WEEK, _interestAccumulator);\n\n return _interestAccumulator;\n }\n}\n" + }, + "contracts/mock/MockKeeperMulticall.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.12;\n\nimport \"@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/access/AccessControlUpgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol\";\nimport \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\nimport \"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\";\n\ncontract MockKeeperMulticall is Initializable, AccessControlUpgradeable {\n using SafeERC20 for IERC20;\n\n bytes32 public constant KEEPER_ROLE = keccak256(\"KEEPER_ROLE\");\n\n //solhint-disable-next-line\n address private constant _oneInch = 0x1111111254fb6c44bAC0beD2854e76F90643097d;\n\n struct Action {\n address target;\n bytes data;\n bool isDelegateCall;\n }\n\n event LogAction(address indexed target, bytes data);\n event SentToMiner(uint256 indexed value);\n event Recovered(address indexed tokenAddress, address indexed to, uint256 amount);\n\n error AmountOutTooLow(uint256 amount, uint256 min);\n error BalanceTooLow();\n error FlashbotsErrorPayingMiner(uint256 value);\n error IncompatibleLengths();\n error RevertBytes();\n error ZeroAddress();\n\n constructor() initializer {}\n\n function initialize(address keeper) public initializer {\n __AccessControl_init();\n\n _setupRole(KEEPER_ROLE, keeper);\n _setRoleAdmin(KEEPER_ROLE, KEEPER_ROLE);\n }\n}\n\ncontract MockKeeperMulticall2 {\n uint256 public varTest = 1;\n\n bytes32 public constant KEEPER_ROLE = keccak256(\"KEEPER_ROLE\");\n\n //solhint-disable-next-line\n address private constant _oneInch = 0x1111111254fb6c44bAC0beD2854e76F90643097d;\n\n struct Action {\n address target;\n bytes data;\n bool isDelegateCall;\n }\n\n event LogAction(address indexed target, bytes data);\n event SentToMiner(uint256 indexed value);\n event Recovered(address indexed tokenAddress, address indexed to, uint256 amount);\n\n error AmountOutTooLow(uint256 amount, uint256 min);\n error BalanceTooLow();\n error FlashbotsErrorPayingMiner(uint256 value);\n error IncompatibleLengths();\n error RevertBytes();\n error ZeroAddress();\n\n function functionTest() external pure returns (bool) {\n return true;\n }\n}\n" + }, + "contracts/mock/MockLayerZero.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\ninterface ILzApp {\n function lzReceive(uint16 _srcChainId, bytes memory _srcAddress, uint64 _nonce, bytes memory _payload) external;\n}\n\ncontract MockLayerZero {\n mapping(uint16 => uint256) public counters;\n uint256 public config;\n mapping(uint16 => uint64) public outboundNonce;\n uint256 public resumeReceived;\n uint256 public sendVersion;\n uint256 public receiveVersion;\n\n /// @notice Initiate with a fixe change rate\n constructor() {}\n\n function send(\n uint16 _dstChainId,\n bytes calldata,\n bytes calldata,\n address,\n address,\n bytes calldata\n ) external payable {\n counters[_dstChainId] += 1;\n }\n\n function getOutboundNonce(uint16 _dstChainId, address) external view returns (uint64) {\n return outboundNonce[_dstChainId];\n }\n\n function setOutBoundNonce(uint16 _from, uint64 value) external {\n outboundNonce[_from] = value;\n }\n\n function lzReceive(\n address lzApp,\n uint16 _srcChainId,\n bytes memory _srcAddress,\n uint64 _nonce,\n bytes memory _payload\n ) public {\n ILzApp(lzApp).lzReceive(_srcChainId, _srcAddress, _nonce, _payload);\n }\n\n function estimateFees(\n uint16,\n address,\n bytes calldata,\n bool,\n bytes calldata\n ) external pure returns (uint256 nativeFee, uint256 zroFee) {\n return (123, 456);\n }\n\n function setConfig(uint16, uint16, uint256 _configType, bytes calldata) external {\n config = _configType;\n }\n\n function getConfig(uint16, uint16, address, uint256) external view returns (bytes memory) {\n return abi.encodePacked(config);\n }\n\n function setSendVersion(uint16 _version) external {\n sendVersion = _version;\n }\n\n function setReceiveVersion(uint16 _version) external {\n receiveVersion = _version;\n }\n\n function forceResumeReceive(uint16, bytes calldata) external {\n resumeReceived = 1 - resumeReceived;\n }\n}\n" + }, + "contracts/mock/MockLiquidityGauge.sol": { + "content": "// SPDX-License-Identifier: UNLICENSED\npragma solidity ^0.8.12;\n\nimport { ILiquidityGauge } from \"../interfaces/coreModule/ILiquidityGauge.sol\";\nimport \"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\";\nimport \"@openzeppelin/contracts/token/ERC20/ERC20.sol\";\n\ncontract MockLiquidityGauge is ILiquidityGauge, ERC20 {\n using SafeERC20 for IERC20;\n\n IERC20 internal _ANGLE = IERC20(0x31429d1856aD1377A8A0079410B297e1a9e214c2);\n IERC20 internal _token;\n mapping(address => uint256) public rewards;\n\n constructor(string memory name_, string memory symbol_, address token_) ERC20(name_, symbol_) {\n _token = IERC20(token_);\n }\n\n function deposit(\n uint256 _value,\n address _addr,\n // solhint-disable-next-line\n bool\n ) external {\n _token.safeTransferFrom(msg.sender, address(this), _value);\n _mint(_addr, _value);\n }\n\n function withdraw(\n uint256 _value,\n // solhint-disable-next-line\n bool\n ) external {\n _burn(msg.sender, _value);\n _token.safeTransfer(msg.sender, _value);\n }\n\n // solhint-disable-next-line\n function claim_rewards(address _addr, address _receiver) external {\n if (_receiver == address(0)) _receiver = _addr;\n _ANGLE.safeTransfer(_receiver, rewards[_addr]);\n rewards[_addr] = 0;\n }\n\n // solhint-disable-next-line\n function claimable_reward(address _addr, address) external view returns (uint256 amount) {\n return rewards[_addr];\n }\n\n function setReward(address receiver_, uint256 amount) external {\n rewards[receiver_] = amount;\n }\n}\n" + }, + "contracts/mock/MockOracle.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.7;\n\nimport \"../interfaces/IOracle.sol\";\n\ncontract MockOracle is IOracle {\n event Update(uint256 _peg);\n\n ITreasury public treasury;\n\n uint256 public base = 1 ether;\n uint256 public precision = 1 ether;\n uint256 public rate;\n bool public outdated;\n\n /// @notice Initiate with a fixe change rate\n constructor(uint256 rate_, ITreasury _treasury) {\n rate = rate_;\n treasury = _treasury;\n }\n\n /// @notice Mock read\n function read() external view override returns (uint256) {\n return rate;\n }\n\n /// @notice change oracle rate\n function update(uint256 newRate) external {\n rate = newRate;\n }\n\n function setTreasury(address _treasury) external override {\n treasury = ITreasury(_treasury);\n }\n\n function circuitChainlink() external pure override returns (AggregatorV3Interface[] memory) {}\n}\n" + }, + "contracts/mock/MockPolygonAgEUR.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.12;\n\nimport \"../agToken/polygon/utils/ERC20UpgradeableCustom.sol\";\nimport \"@openzeppelin/contracts-upgradeable/access/AccessControlUpgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/utils/cryptography/draft-EIP712Upgradeable.sol\";\nimport \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\nimport \"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\";\n\nimport \"../interfaces/IAgToken.sol\";\nimport \"../interfaces/ITreasury.sol\";\n\ninterface IChildToken {\n function deposit(address user, bytes calldata depositData) external;\n\n function withdraw(uint256 amount) external;\n}\n\ncontract MockPolygonAgEUR is\n Initializable,\n ERC20UpgradeableCustom,\n AccessControlUpgradeable,\n EIP712Upgradeable,\n IChildToken\n{\n bytes32 public constant DEPOSITOR_ROLE = keccak256(\"DEPOSITOR_ROLE\");\n\n /// @dev Emitted when the child chain manager changes\n event ChildChainManagerAdded(address newAddress);\n event ChildChainManagerRevoked(address oldAddress);\n\n constructor() initializer {}\n\n function initialize(\n string memory _name,\n string memory _symbol,\n address childChainManager,\n address guardian\n ) public initializer {\n __ERC20_init(_name, _symbol);\n __AccessControl_init();\n _setupRole(DEFAULT_ADMIN_ROLE, guardian);\n _setupRole(DEPOSITOR_ROLE, childChainManager);\n __EIP712_init(_name, \"1\");\n }\n\n /**\n * @notice Called when the bridge has tokens to mint\n * @param user Address to mint the token to\n * @param depositData Encoded amount to mint\n */\n function deposit(address user, bytes calldata depositData) external override {\n require(hasRole(DEPOSITOR_ROLE, msg.sender));\n uint256 amount = abi.decode(depositData, (uint256));\n _mint(user, amount);\n }\n\n /**\n * @notice Called when user wants to withdraw tokens back to root chain\n * @dev Should burn user's tokens. This transaction will be verified when exiting on root chain\n * @param amount Amount of tokens to withdraw\n */\n function withdraw(uint256 amount) external override {\n _burn(_msgSender(), amount);\n }\n\n // =============================================================================\n // ======================= New data added for the upgrade ======================\n // =============================================================================\n\n mapping(address => bool) public isMinter;\n /// @notice Reference to the treasury contract which can grant minting rights\n address public treasury;\n /// @notice Boolean to check whether the contract has been reinitialized after its upgrade\n bool public treasuryInitialized;\n\n using SafeERC20 for IERC20;\n\n /// @notice Base used for fee computation\n uint256 public constant BASE_PARAMS = 10 ** 9;\n\n // =============================== Bridging Data ===============================\n\n /// @notice Struct with some data about a specific bridge token\n struct BridgeDetails {\n // Limit on the balance of bridge token held by the contract: it is designed\n // to reduce the exposure of the system to hacks\n uint256 limit;\n // Limit on the hourly volume of token minted through this bridge\n // Technically the limit over a rolling hour is hourlyLimit x2 as hourly limit\n // is enforced only between x:00 and x+1:00\n uint256 hourlyLimit;\n // Fee taken for swapping in and out the token\n uint64 fee;\n // Whether the associated token is allowed or not\n bool allowed;\n // Whether swapping in and out from the associated token is paused or not\n bool paused;\n }\n\n /// @notice Maps a bridge token to data\n mapping(address => BridgeDetails) public bridges;\n /// @notice List of all bridge tokens\n address[] public bridgeTokensList;\n /// @notice Maps a bridge token to the associated hourly volume\n mapping(address => mapping(uint256 => uint256)) public usage;\n /// @notice Maps an address to whether it is exempt of fees for when it comes to swapping in and out\n mapping(address => uint256) public isFeeExempt;\n\n uint256[44] private __gap;\n\n // ================================== Events ===================================\n\n event BridgeTokenAdded(address indexed bridgeToken, uint256 limit, uint256 hourlyLimit, uint64 fee, bool paused);\n event BridgeTokenToggled(address indexed bridgeToken, bool toggleStatus);\n event BridgeTokenRemoved(address indexed bridgeToken);\n event BridgeTokenFeeUpdated(address indexed bridgeToken, uint64 fee);\n event BridgeTokenLimitUpdated(address indexed bridgeToken, uint256 limit);\n event BridgeTokenHourlyLimitUpdated(address indexed bridgeToken, uint256 hourlyLimit);\n event HourlyLimitUpdated(uint256 hourlyLimit);\n event FeeToggled(address indexed theAddress, uint256 toggleStatus);\n event KeeperToggled(address indexed keeper, bool toggleStatus);\n event MinterToggled(address indexed minter);\n event Recovered(address indexed token, address indexed to, uint256 amount);\n event TreasuryUpdated(address indexed _treasury);\n\n // ================================== Errors ===================================\n\n error AssetStillControlledInReserves();\n error BurnAmountExceedsAllowance();\n error HourlyLimitExceeded();\n error InvalidSender();\n error InvalidToken();\n error InvalidTreasury();\n error NotGovernor();\n error NotGovernorOrGuardian();\n error NotMinter();\n error NotTreasury();\n error TooBigAmount();\n error TooHighParameterValue();\n error TreasuryAlreadyInitialized();\n error ZeroAddress();\n\n /// @notice Checks to see if it is the `Treasury` calling this contract\n /// @dev There is no Access Control here, because it can be handled cheaply through this modifier\n modifier onlyTreasury() {\n if (msg.sender != treasury) revert NotTreasury();\n _;\n }\n\n /// @notice Checks whether the sender has the minting right\n modifier onlyMinter() {\n if (!isMinter[msg.sender]) revert NotMinter();\n _;\n }\n\n /// @notice Checks whether the `msg.sender` has the governor role or not\n modifier onlyGovernor() {\n if (!ITreasury(treasury).isGovernor(msg.sender)) revert NotGovernor();\n _;\n }\n\n /// @notice Checks whether the `msg.sender` has the governor role or the guardian role\n modifier onlyGovernorOrGuardian() {\n if (!ITreasury(treasury).isGovernorOrGuardian(msg.sender)) revert NotGovernorOrGuardian();\n _;\n }\n\n /// @notice Sets up the treasury contract on Polygon after the upgrade\n /// @param _treasury Address of the treasury contract\n function setUpTreasury(address _treasury) external {\n // Only governor on Polygon\n if (msg.sender != 0xdA2D2f638D6fcbE306236583845e5822554c02EA) revert NotGovernor();\n if (address(ITreasury(_treasury).stablecoin()) != address(this)) revert InvalidTreasury();\n if (treasuryInitialized) revert TreasuryAlreadyInitialized();\n treasury = _treasury;\n treasuryInitialized = true;\n emit TreasuryUpdated(_treasury);\n }\n\n // =========================== External Function ===============================\n\n /// @notice Allows anyone to burn agToken without redeeming collateral back\n /// @param amount Amount of stablecoins to burn\n /// @dev This function can typically be called if there is a settlement mechanism to burn stablecoins\n function burnStablecoin(uint256 amount) external {\n _burnCustom(msg.sender, amount);\n }\n\n // ======================= Minter Role Only Functions ==========================\n\n function burnSelf(uint256 amount, address burner) external onlyMinter {\n _burnCustom(burner, amount);\n }\n\n function burnFrom(uint256 amount, address burner, address sender) external onlyMinter {\n _burnFromNoRedeem(amount, burner, sender);\n }\n\n function mint(address account, uint256 amount) external onlyMinter {\n _mint(account, amount);\n }\n\n // ======================= Treasury Only Functions =============================\n\n function addMinter(address minter) external onlyTreasury {\n isMinter[minter] = true;\n emit MinterToggled(minter);\n }\n\n function removeMinter(address minter) external {\n if (msg.sender != address(treasury) && msg.sender != minter) revert InvalidSender();\n isMinter[minter] = false;\n emit MinterToggled(minter);\n }\n\n function setTreasury(address _treasury) external onlyTreasury {\n treasury = _treasury;\n emit TreasuryUpdated(_treasury);\n }\n\n // ============================ Internal Function ==============================\n\n /// @notice Internal version of the function `burnFromNoRedeem`\n /// @param amount Amount to burn\n /// @dev It is at the level of this function that allowance checks are performed\n function _burnFromNoRedeem(uint256 amount, address burner, address sender) internal {\n if (burner != sender) {\n uint256 currentAllowance = allowance(burner, sender);\n if (currentAllowance < amount) revert BurnAmountExceedsAllowance();\n _approve(burner, sender, currentAllowance - amount);\n }\n _burnCustom(burner, amount);\n }\n\n // ==================== External Permissionless Functions ======================\n\n /// @notice Returns the list of all supported bridge tokens\n /// @dev Helpful for UIs\n function allBridgeTokens() external view returns (address[] memory) {\n return bridgeTokensList;\n }\n\n /// @notice Returns the current volume for a bridge, for the current hour\n /// @dev Helpful for UIs\n function currentUsage(address bridge) external view returns (uint256) {\n return usage[bridge][block.timestamp / 3600];\n }\n\n /// @notice Mints the canonical token from a supported bridge token\n /// @param bridgeToken Bridge token to use to mint\n /// @param amount Amount of bridge tokens to send\n /// @param to Address to which the stablecoin should be sent\n /// @dev Some fees may be taken by the protocol depending on the token used and on the address calling\n function swapIn(address bridgeToken, uint256 amount, address to) external returns (uint256) {\n BridgeDetails memory bridgeDetails = bridges[bridgeToken];\n if (!bridgeDetails.allowed || bridgeDetails.paused) revert InvalidToken();\n uint256 balance = IERC20(bridgeToken).balanceOf(address(this));\n if (balance + amount > bridgeDetails.limit) {\n // In case someone maliciously sends tokens to this contract\n // Or the limit changes\n if (bridgeDetails.limit > balance) amount = bridgeDetails.limit - balance;\n else {\n amount = 0;\n }\n }\n\n // Checking requirement on the hourly volume\n uint256 hour = block.timestamp / 3600;\n uint256 hourlyUsage = usage[bridgeToken][hour] + amount;\n if (hourlyUsage > bridgeDetails.hourlyLimit) {\n // Edge case when the hourly limit changes\n if (bridgeDetails.hourlyLimit > usage[bridgeToken][hour])\n amount = bridgeDetails.hourlyLimit - usage[bridgeToken][hour];\n else {\n amount = 0;\n }\n }\n usage[bridgeToken][hour] = usage[bridgeToken][hour] + amount;\n\n IERC20(bridgeToken).safeTransferFrom(msg.sender, address(this), amount);\n uint256 canonicalOut = amount;\n // Computing fees\n if (isFeeExempt[msg.sender] == 0) {\n canonicalOut -= (canonicalOut * bridgeDetails.fee) / BASE_PARAMS;\n }\n _mint(to, canonicalOut);\n return canonicalOut;\n }\n\n /// @notice Burns the canonical token in exchange for a bridge token\n /// @param bridgeToken Bridge token required\n /// @param amount Amount of canonical tokens to burn\n /// @param to Address to which the bridge token should be sent\n /// @dev Some fees may be taken by the protocol depending on the token used and on the address calling\n function swapOut(address bridgeToken, uint256 amount, address to) external returns (uint256) {\n BridgeDetails memory bridgeDetails = bridges[bridgeToken];\n if (!bridgeDetails.allowed || bridgeDetails.paused) revert InvalidToken();\n\n _burnCustom(msg.sender, amount);\n uint256 bridgeOut = amount;\n if (isFeeExempt[msg.sender] == 0) {\n bridgeOut -= (bridgeOut * bridgeDetails.fee) / BASE_PARAMS;\n }\n IERC20(bridgeToken).safeTransfer(to, bridgeOut);\n return bridgeOut;\n }\n\n // ======================= Governance Functions ================================\n\n /// @notice Adds support for a bridge token\n /// @param bridgeToken Bridge token to add: it should be a version of the stablecoin from another bridge\n /// @param limit Limit on the balance of bridge token this contract could hold\n /// @param hourlyLimit Limit on the hourly volume for this bridge\n /// @param paused Whether swapping for this token should be paused or not\n /// @param fee Fee taken upon swapping for or against this token\n function addBridgeToken(\n address bridgeToken,\n uint256 limit,\n uint256 hourlyLimit,\n uint64 fee,\n bool paused\n ) external onlyGovernor {\n if (bridges[bridgeToken].allowed || bridgeToken == address(0)) revert InvalidToken();\n if (fee > BASE_PARAMS) revert TooHighParameterValue();\n BridgeDetails memory _bridge;\n _bridge.limit = limit;\n _bridge.hourlyLimit = hourlyLimit;\n _bridge.paused = paused;\n _bridge.fee = fee;\n _bridge.allowed = true;\n bridges[bridgeToken] = _bridge;\n bridgeTokensList.push(bridgeToken);\n emit BridgeTokenAdded(bridgeToken, limit, hourlyLimit, fee, paused);\n }\n\n /// @notice Removes support for a token\n /// @param bridgeToken Address of the bridge token to remove support for\n function removeBridgeToken(address bridgeToken) external onlyGovernor {\n if (IERC20(bridgeToken).balanceOf(address(this)) != 0) revert AssetStillControlledInReserves();\n delete bridges[bridgeToken];\n // Deletion from `bridgeTokensList` loop\n uint256 bridgeTokensListLength = bridgeTokensList.length;\n for (uint256 i; i < bridgeTokensListLength - 1; ++i) {\n if (bridgeTokensList[i] == bridgeToken) {\n // Replace the `bridgeToken` to remove with the last of the list\n bridgeTokensList[i] = bridgeTokensList[bridgeTokensListLength - 1];\n break;\n }\n }\n // Remove last element in array\n bridgeTokensList.pop();\n emit BridgeTokenRemoved(bridgeToken);\n }\n\n /// @notice Recovers any ERC20 token\n /// @dev Can be used to withdraw bridge tokens for them to be de-bridged on mainnet\n function recoverERC20(address tokenAddress, address to, uint256 amountToRecover) external onlyGovernor {\n IERC20(tokenAddress).safeTransfer(to, amountToRecover);\n emit Recovered(tokenAddress, to, amountToRecover);\n }\n\n /// @notice Updates the `limit` amount for `bridgeToken`\n function setLimit(address bridgeToken, uint256 limit) external onlyGovernorOrGuardian {\n if (!bridges[bridgeToken].allowed) revert InvalidToken();\n bridges[bridgeToken].limit = limit;\n emit BridgeTokenLimitUpdated(bridgeToken, limit);\n }\n\n /// @notice Updates the `hourlyLimit` amount for `bridgeToken`\n function setHourlyLimit(address bridgeToken, uint256 hourlyLimit) external onlyGovernorOrGuardian {\n if (!bridges[bridgeToken].allowed) revert InvalidToken();\n bridges[bridgeToken].hourlyLimit = hourlyLimit;\n emit BridgeTokenHourlyLimitUpdated(bridgeToken, hourlyLimit);\n }\n\n /// @notice Updates the `fee` value for `bridgeToken`\n function setSwapFee(address bridgeToken, uint64 fee) external onlyGovernorOrGuardian {\n if (!bridges[bridgeToken].allowed) revert InvalidToken();\n if (fee > BASE_PARAMS) revert TooHighParameterValue();\n bridges[bridgeToken].fee = fee;\n emit BridgeTokenFeeUpdated(bridgeToken, fee);\n }\n\n /// @notice Pauses or unpauses swapping in and out for a token\n function toggleBridge(address bridgeToken) external onlyGovernorOrGuardian {\n if (!bridges[bridgeToken].allowed) revert InvalidToken();\n bool pausedStatus = bridges[bridgeToken].paused;\n bridges[bridgeToken].paused = !pausedStatus;\n emit BridgeTokenToggled(bridgeToken, !pausedStatus);\n }\n\n /// @notice Toggles fees for the address `theAddress`\n function toggleFeesForAddress(address theAddress) external onlyGovernorOrGuardian {\n uint256 feeExemptStatus = 1 - isFeeExempt[theAddress];\n isFeeExempt[theAddress] = feeExemptStatus;\n emit FeeToggled(theAddress, feeExemptStatus);\n }\n}\n" + }, + "contracts/mock/MockRouter.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\nimport \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\nimport \"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\";\n\nimport \"../interfaces/IAngleRouter.sol\";\nimport \"../interfaces/external/uniswap/IUniswapRouter.sol\";\nimport \"../interfaces/external/lido/IWStETH.sol\";\n\ncontract MockRouter is IUniswapV3Router, IWStETH {\n using SafeERC20 for IERC20;\n\n uint256 public counterAngleMint;\n uint256 public counterAngleBurn;\n uint256 public counter1Inch;\n uint256 public counterUni;\n uint256 public counterWrap;\n uint256 public counterMixer;\n uint256 public amountOutUni;\n uint256 public multiplierMintBurn;\n uint256 public stETHMultiplier;\n address public inToken;\n address public outToken;\n\n address public stETH;\n\n /// @notice Action types\n enum ActionType {\n transfer,\n wrap,\n wrapNative,\n sweep,\n sweepNative,\n unwrap,\n unwrapNative,\n swapIn,\n swapOut,\n uniswapV3,\n oneInch,\n claimRewards,\n gaugeDeposit,\n borrower\n }\n\n /// @notice Data needed to get permits\n struct PermitType {\n address token;\n address owner;\n uint256 value;\n uint256 deadline;\n uint8 v;\n bytes32 r;\n bytes32 s;\n }\n\n constructor() {}\n\n function mint(address user, uint256 amount, uint256, address stablecoin, address collateral) external {\n counterAngleMint += 1;\n IERC20(collateral).safeTransferFrom(msg.sender, address(this), amount);\n IERC20(stablecoin).safeTransfer(user, (amount * 10 ** 9) / multiplierMintBurn);\n }\n\n function setStETH(address _stETH) external {\n stETH = _stETH;\n }\n\n function burn(address user, uint256 amount, uint256, address stablecoin, address collateral) external {\n counterAngleBurn += 1;\n IERC20(stablecoin).safeTransferFrom(msg.sender, address(this), amount);\n IERC20(collateral).safeTransfer(user, (amount * multiplierMintBurn) / 10 ** 9);\n }\n\n function mixer(\n PermitType[] memory paramsPermit,\n ActionType[] memory actions,\n bytes[] calldata data\n ) public payable virtual {\n paramsPermit;\n counterMixer += 1;\n for (uint256 i; i < actions.length; ++i) {\n if (actions[i] == ActionType.transfer) {\n (address transferToken, uint256 amount) = abi.decode(data[i], (address, uint256));\n IERC20(transferToken).safeTransferFrom(msg.sender, address(this), amount);\n }\n }\n }\n\n function wrap(uint256 amount) external returns (uint256 amountOut) {\n amountOut = (amount * stETHMultiplier) / 10 ** 9;\n counterWrap += 1;\n IERC20(stETH).safeTransferFrom(msg.sender, address(this), amount);\n IERC20(outToken).safeTransfer(msg.sender, amountOut);\n }\n\n function oneInch(uint256 amountIn) external returns (uint256 amountOut) {\n counter1Inch += 1;\n amountOut = (amountOutUni * amountIn) / 10 ** 9;\n IERC20(inToken).safeTransferFrom(msg.sender, address(this), amountIn);\n IERC20(outToken).safeTransfer(msg.sender, amountOut);\n }\n\n function oneInchReverts() external {\n counter1Inch += 1;\n revert(\"wrong swap\");\n }\n\n function oneInchRevertsWithoutMessage() external {\n counter1Inch += 1;\n require(false);\n }\n\n function exactInput(ExactInputParams calldata params) external payable returns (uint256 amountOut) {\n counterUni += 1;\n amountOut = (params.amountIn * amountOutUni) / 10 ** 9;\n IERC20(inToken).safeTransferFrom(msg.sender, address(this), params.amountIn);\n IERC20(outToken).safeTransfer(params.recipient, amountOut);\n require(amountOut >= params.amountOutMinimum);\n }\n\n function setMultipliers(uint256 a, uint256 b) external {\n amountOutUni = a;\n multiplierMintBurn = b;\n }\n\n function setStETHMultiplier(uint256 value) external {\n stETHMultiplier = value;\n }\n\n function setInOut(address _collateral, address _stablecoin) external {\n inToken = _collateral;\n outToken = _stablecoin;\n }\n}\n" + }, + "contracts/mock/MockSidechainAgEUR.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\nimport \"../agToken/AgToken.sol\";\nimport \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\nimport \"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\";\n\n/// @title AgTokenSideChainMultiBridge\n/// @author Angle Labs, Inc.\n/// @notice Contract for Angle agTokens on other chains than Ethereum mainnet\n/// @dev This contract supports bridge tokens having a minting right on the stablecoin (also referred to as the canonical\n/// or the native token)\n/// @dev References:\n/// - FRAX implementation: https://polygonscan.com/address/0x45c32fA6DF82ead1e2EF74d17b76547EDdFaFF89#code\n/// - QiDAO implementation: https://snowtrace.io/address/0x5c49b268c9841AFF1Cc3B0a418ff5c3442eE3F3b#code\ncontract MockSidechainAgEUR is AgToken {\n using SafeERC20 for IERC20;\n\n /// @notice Base used for fee computation\n uint256 public constant BASE_PARAMS = 10 ** 9;\n\n // =============================== Bridging Data ===============================\n\n /// @notice Struct with some data about a specific bridge token\n struct BridgeDetails {\n // Limit on the balance of bridge token held by the contract: it is designed\n // to reduce the exposure of the system to hacks\n uint256 limit;\n // Limit on the hourly volume of token minted through this bridge\n // Technically the limit over a rolling hour is hourlyLimit x2 as hourly limit\n // is enforced only between x:00 and x+1:00\n uint256 hourlyLimit;\n // Fee taken for swapping in and out the token\n uint64 fee;\n // Whether the associated token is allowed or not\n bool allowed;\n // Whether swapping in and out from the associated token is paused or not\n bool paused;\n }\n\n /// @notice Maps a bridge token to data\n mapping(address => BridgeDetails) public bridges;\n /// @notice List of all bridge tokens\n address[] public bridgeTokensList;\n /// @notice Maps a bridge token to the associated hourly volume\n mapping(address => mapping(uint256 => uint256)) public usage;\n /// @notice Maps an address to whether it is exempt of fees for when it comes to swapping in and out\n mapping(address => uint256) public isFeeExempt;\n\n // ================================== Events ===================================\n\n event BridgeTokenAdded(address indexed bridgeToken, uint256 limit, uint256 hourlyLimit, uint64 fee, bool paused);\n event BridgeTokenToggled(address indexed bridgeToken, bool toggleStatus);\n event BridgeTokenRemoved(address indexed bridgeToken);\n event BridgeTokenFeeUpdated(address indexed bridgeToken, uint64 fee);\n event BridgeTokenLimitUpdated(address indexed bridgeToken, uint256 limit);\n event BridgeTokenHourlyLimitUpdated(address indexed bridgeToken, uint256 hourlyLimit);\n event HourlyLimitUpdated(uint256 hourlyLimit);\n event Recovered(address indexed token, address indexed to, uint256 amount);\n event FeeToggled(address indexed theAddress, uint256 toggleStatus);\n\n // =============================== Errors ================================\n\n error AssetStillControlledInReserves();\n error HourlyLimitExceeded();\n error InvalidToken();\n error NotGovernor();\n error NotGovernorOrGuardian();\n error TooBigAmount();\n error TooHighParameterValue();\n error ZeroAddress();\n\n // ============================= Constructor ===================================\n\n /// @notice Checks whether the `msg.sender` has the governor role or not\n modifier onlyGovernor() {\n if (!ITreasury(treasury).isGovernor(msg.sender)) revert NotGovernor();\n _;\n }\n\n /// @notice Checks whether the `msg.sender` has the governor role or the guardian role\n modifier onlyGovernorOrGuardian() {\n if (!ITreasury(treasury).isGovernorOrGuardian(msg.sender)) revert NotGovernorOrGuardian();\n _;\n }\n\n // ==================== External Permissionless Functions ======================\n\n /// @notice Returns the list of all supported bridge tokens\n /// @dev Helpful for UIs\n function allBridgeTokens() external view returns (address[] memory) {\n return bridgeTokensList;\n }\n\n /// @notice Returns the current volume for a bridge, for the current hour\n /// @param bridgeToken Bridge used to mint\n /// @dev Helpful for UIs\n function currentUsage(address bridgeToken) external view returns (uint256) {\n return usage[bridgeToken][block.timestamp / 3600];\n }\n\n /// @notice Mints the canonical token from a supported bridge token\n /// @param bridgeToken Bridge token to use to mint\n /// @param amount Amount of bridge tokens to send\n /// @param to Address to which the stablecoin should be sent\n /// @return Amount of the canonical stablecoin actually minted\n /// @dev Some fees may be taken by the protocol depending on the token used and on the address calling\n function swapIn(address bridgeToken, uint256 amount, address to) external returns (uint256) {\n BridgeDetails memory bridgeDetails = bridges[bridgeToken];\n if (!bridgeDetails.allowed || bridgeDetails.paused) revert InvalidToken();\n uint256 balance = IERC20(bridgeToken).balanceOf(address(this));\n if (balance + amount > bridgeDetails.limit) {\n // In case someone maliciously sends tokens to this contract\n // Or the limit changes\n if (bridgeDetails.limit > balance) amount = bridgeDetails.limit - balance;\n else {\n amount = 0;\n }\n }\n\n // Checking requirement on the hourly volume\n uint256 hour = block.timestamp / 3600;\n uint256 hourlyUsage = usage[bridgeToken][hour] + amount;\n if (hourlyUsage > bridgeDetails.hourlyLimit) {\n // Edge case when the hourly limit changes\n if (bridgeDetails.hourlyLimit > usage[bridgeToken][hour])\n amount = bridgeDetails.hourlyLimit - usage[bridgeToken][hour];\n else {\n amount = 0;\n }\n }\n usage[bridgeToken][hour] = usage[bridgeToken][hour] + amount;\n\n IERC20(bridgeToken).safeTransferFrom(msg.sender, address(this), amount);\n uint256 canonicalOut = amount;\n // Computing fees\n if (isFeeExempt[msg.sender] == 0) {\n canonicalOut -= (canonicalOut * bridgeDetails.fee) / BASE_PARAMS;\n }\n _mint(to, canonicalOut);\n return canonicalOut;\n }\n\n /// @notice Burns the canonical token in exchange for a bridge token\n /// @param bridgeToken Bridge token required\n /// @param amount Amount of canonical tokens to burn\n /// @param to Address to which the bridge token should be sent\n /// @return Amount of bridge tokens actually sent back\n /// @dev Some fees may be taken by the protocol depending on the token used and on the address calling\n function swapOut(address bridgeToken, uint256 amount, address to) external returns (uint256) {\n BridgeDetails memory bridgeDetails = bridges[bridgeToken];\n if (!bridgeDetails.allowed || bridgeDetails.paused) revert InvalidToken();\n\n _burn(msg.sender, amount);\n uint256 bridgeOut = amount;\n if (isFeeExempt[msg.sender] == 0) {\n bridgeOut -= (bridgeOut * bridgeDetails.fee) / BASE_PARAMS;\n }\n IERC20(bridgeToken).safeTransfer(to, bridgeOut);\n return bridgeOut;\n }\n\n // ======================= Governance Functions ================================\n\n /// @notice Adds support for a bridge token\n /// @param bridgeToken Bridge token to add: it should be a version of the stablecoin from another bridge\n /// @param limit Limit on the balance of bridge token this contract could hold\n /// @param hourlyLimit Limit on the hourly volume for this bridge\n /// @param paused Whether swapping for this token should be paused or not\n /// @param fee Fee taken upon swapping for or against this token\n function addBridgeToken(\n address bridgeToken,\n uint256 limit,\n uint256 hourlyLimit,\n uint64 fee,\n bool paused\n ) external onlyGovernor {\n if (bridges[bridgeToken].allowed || bridgeToken == address(0)) revert InvalidToken();\n if (fee > BASE_PARAMS) revert TooHighParameterValue();\n BridgeDetails memory _bridge;\n _bridge.limit = limit;\n _bridge.hourlyLimit = hourlyLimit;\n _bridge.paused = paused;\n _bridge.fee = fee;\n _bridge.allowed = true;\n bridges[bridgeToken] = _bridge;\n bridgeTokensList.push(bridgeToken);\n emit BridgeTokenAdded(bridgeToken, limit, hourlyLimit, fee, paused);\n }\n\n /// @notice Removes support for a token\n /// @param bridgeToken Address of the bridge token to remove support for\n function removeBridgeToken(address bridgeToken) external onlyGovernor {\n if (IERC20(bridgeToken).balanceOf(address(this)) != 0) revert AssetStillControlledInReserves();\n delete bridges[bridgeToken];\n // Deletion from `bridgeTokensList` loop\n uint256 bridgeTokensListLength = bridgeTokensList.length;\n for (uint256 i; i < bridgeTokensListLength - 1; ++i) {\n if (bridgeTokensList[i] == bridgeToken) {\n // Replace the `bridgeToken` to remove with the last of the list\n bridgeTokensList[i] = bridgeTokensList[bridgeTokensListLength - 1];\n break;\n }\n }\n // Remove last element in array\n bridgeTokensList.pop();\n emit BridgeTokenRemoved(bridgeToken);\n }\n\n /// @notice Recovers any ERC20 token\n /// @dev Can be used to withdraw bridge tokens for them to be de-bridged on mainnet\n function recoverERC20(address tokenAddress, address to, uint256 amountToRecover) external onlyGovernor {\n IERC20(tokenAddress).safeTransfer(to, amountToRecover);\n emit Recovered(tokenAddress, to, amountToRecover);\n }\n\n /// @notice Updates the `limit` amount for `bridgeToken`\n function setLimit(address bridgeToken, uint256 limit) external onlyGovernorOrGuardian {\n if (!bridges[bridgeToken].allowed) revert InvalidToken();\n bridges[bridgeToken].limit = limit;\n emit BridgeTokenLimitUpdated(bridgeToken, limit);\n }\n\n /// @notice Updates the `hourlyLimit` amount for `bridgeToken`\n function setHourlyLimit(address bridgeToken, uint256 hourlyLimit) external onlyGovernorOrGuardian {\n if (!bridges[bridgeToken].allowed) revert InvalidToken();\n bridges[bridgeToken].hourlyLimit = hourlyLimit;\n emit BridgeTokenHourlyLimitUpdated(bridgeToken, hourlyLimit);\n }\n\n /// @notice Updates the `fee` value for `bridgeToken`\n function setSwapFee(address bridgeToken, uint64 fee) external onlyGovernorOrGuardian {\n if (!bridges[bridgeToken].allowed) revert InvalidToken();\n if (fee > BASE_PARAMS) revert TooHighParameterValue();\n bridges[bridgeToken].fee = fee;\n emit BridgeTokenFeeUpdated(bridgeToken, fee);\n }\n\n /// @notice Pauses or unpauses swapping in and out for a token\n function toggleBridge(address bridgeToken) external onlyGovernorOrGuardian {\n if (!bridges[bridgeToken].allowed) revert InvalidToken();\n bool pausedStatus = bridges[bridgeToken].paused;\n bridges[bridgeToken].paused = !pausedStatus;\n emit BridgeTokenToggled(bridgeToken, !pausedStatus);\n }\n\n /// @notice Toggles fees for the address `theAddress`\n function toggleFeesForAddress(address theAddress) external onlyGovernorOrGuardian {\n uint256 feeExemptStatus = 1 - isFeeExempt[theAddress];\n isFeeExempt[theAddress] = feeExemptStatus;\n emit FeeToggled(theAddress, feeExemptStatus);\n }\n}\n" + }, + "contracts/mock/MockStableMaster.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\nimport \"../interfaces/IAgToken.sol\";\nimport \"./MockToken.sol\";\nimport \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\nimport \"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\";\nimport { SLPData, MintBurnData } from \"../interfaces/coreModule/IStableMaster.sol\";\n\n// All the details about a collateral that are going to be stored in `StableMaster`\nstruct Collateral {\n // Interface for the token accepted by the underlying `PoolManager` contract\n IERC20 token;\n // Reference to the `SanToken` for the pool\n MockToken sanToken;\n // Reference to the `PerpetualManager` for the pool\n address perpetualManager;\n // Adress of the oracle for the change rate between\n // collateral and the corresponding stablecoin\n address oracle;\n // Amount of collateral in the reserves that comes from users\n // converted in stablecoin value. Updated at minting and burning.\n // A `stocksUsers` of 10 for a collateral type means that overall the balance of the collateral from users\n // that minted/burnt stablecoins using this collateral is worth 10 of stablecoins\n uint256 stocksUsers;\n // Exchange rate between sanToken and collateral\n uint256 sanRate;\n // Base used in the collateral implementation (ERC20 decimal)\n uint256 collatBase;\n // Parameters for SLPs and update of the `sanRate`\n SLPData slpData;\n // All the fees parameters\n MintBurnData feeData;\n}\n\ncontract MockStableMaster {\n mapping(address => uint256) public poolManagerMap;\n\n constructor() {}\n\n function updateStocksUsers(uint256 amount, address poolManager) external {\n poolManagerMap[poolManager] += amount;\n }\n\n function burnSelf(IAgToken agToken, uint256 amount, address burner) external {\n agToken.burnSelf(amount, burner);\n }\n\n function burnFrom(IAgToken agToken, uint256 amount, address burner, address sender) external {\n agToken.burnFrom(amount, burner, sender);\n }\n\n function mint(IAgToken agToken, address account, uint256 amount) external {\n agToken.mint(account, amount);\n }\n}\n\ncontract MockStableMasterSanWrapper is MockStableMaster {\n using SafeERC20 for IERC20;\n\n /// @notice Maps a `PoolManager` contract handling a collateral for this stablecoin to the properties of the struct above\n mapping(address => Collateral) public collateralMap;\n\n constructor() MockStableMaster() {}\n\n uint256 internal constant _BASE_TOKENS = 10 ** 18;\n uint256 internal constant _BASE_PARAMS = 10 ** 9;\n IERC20 public token;\n\n function deposit(uint256 assets, address receiver, address poolManager) external {\n token.safeTransferFrom(msg.sender, address(this), assets);\n Collateral storage col = collateralMap[poolManager];\n _updateSanRate(col);\n uint256 amount = (assets * _BASE_TOKENS) / col.sanRate;\n col.sanToken.mint(receiver, amount);\n }\n\n function withdraw(uint256 assets, address sender, address receiver, address poolManager) external {\n Collateral storage col = collateralMap[poolManager];\n _updateSanRate(col);\n col.sanToken.burn(sender, assets);\n // Computing the amount of collateral to give back to the SLP depending on slippage and on the `sanRate`\n uint256 redeemInC = (assets * (_BASE_PARAMS - col.slpData.slippage) * col.sanRate) /\n (_BASE_TOKENS * _BASE_PARAMS);\n token.safeTransfer(receiver, redeemInC);\n }\n\n function setPoolManagerToken(address, address token_) external {\n token = MockToken(token_);\n }\n\n function setPoolManagerSanToken(address poolManager, address sanToken_) external {\n Collateral storage col = collateralMap[poolManager];\n col.sanToken = MockToken(sanToken_);\n }\n\n function setSanRate(address poolManager, uint256 sanRate_) external {\n Collateral storage col = collateralMap[poolManager];\n col.sanRate = sanRate_;\n }\n\n function _updateSanRate(Collateral storage col) internal {\n uint256 _lockedInterests = col.slpData.lockedInterests;\n // Checking if the `sanRate` has been updated in the current block using past block fees\n // This is a way to prevent flash loans attacks when an important amount of fees are going to be distributed\n // in a block: fees are stored but will just be distributed to SLPs who will be here during next blocks\n if (block.timestamp != col.slpData.lastBlockUpdated && _lockedInterests > 0) {\n uint256 sanMint = col.sanToken.totalSupply();\n if (sanMint != 0) {\n // Checking if the update is too important and should be made in multiple blocks\n if (_lockedInterests > col.slpData.maxInterestsDistributed) {\n // `sanRate` is expressed in `BASE_TOKENS`\n col.sanRate += (col.slpData.maxInterestsDistributed * 10 ** 18) / sanMint;\n _lockedInterests -= col.slpData.maxInterestsDistributed;\n } else {\n col.sanRate += (_lockedInterests * 10 ** 18) / sanMint;\n _lockedInterests = 0;\n }\n } else {\n _lockedInterests = 0;\n }\n }\n col.slpData.lockedInterests = _lockedInterests;\n col.slpData.lastBlockUpdated = block.timestamp;\n }\n\n // copy paste from the deployed contract\n function estimateSanRate(address poolManager) external view returns (uint256 sanRate, uint64 slippage) {\n Collateral memory col = collateralMap[poolManager];\n uint256 _lockedInterests = col.slpData.lockedInterests;\n // Checking if the `sanRate` has been updated in the current block using past block fees\n // This is a way to prevent flash loans attacks when an important amount of fees are going to be distributed\n // in a block: fees are stored but will just be distributed to SLPs who will be here during next blocks\n if (block.timestamp != col.slpData.lastBlockUpdated && _lockedInterests > 0) {\n uint256 sanMint = col.sanToken.totalSupply();\n if (sanMint != 0) {\n // Checking if the update is too important and should be made in multiple blocks\n if (_lockedInterests > col.slpData.maxInterestsDistributed) {\n // `sanRate` is expressed in `BASE_TOKENS`\n col.sanRate += (col.slpData.maxInterestsDistributed * 10 ** 18) / sanMint;\n _lockedInterests -= col.slpData.maxInterestsDistributed;\n } else {\n col.sanRate += (_lockedInterests * 10 ** 18) / sanMint;\n _lockedInterests = 0;\n }\n } else {\n _lockedInterests = 0;\n }\n }\n return (col.sanRate, col.slpData.slippage);\n }\n\n function setSLPData(\n address poolManager,\n uint256 lockedInterests,\n uint256 maxInterestsDistributed,\n uint64 slippage\n ) external {\n Collateral storage col = collateralMap[poolManager];\n col.slpData.lockedInterests = lockedInterests;\n col.slpData.maxInterestsDistributed = maxInterestsDistributed;\n col.slpData.slippage = slippage;\n }\n}\n" + }, + "contracts/mock/MockSwapper.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\nimport \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\nimport \"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\";\n\nimport \"../interfaces/ISwapper.sol\";\n\ncontract MockSwapper is ISwapper {\n bytes32 public constant CALLBACK_SUCCESS = keccak256(\"ERC3156FlashBorrower.onFlashLoan\");\n\n uint256 public counter;\n\n constructor() {}\n\n function swap(IERC20, IERC20, address, uint256, uint256, bytes calldata data) external {\n counter += 1;\n data;\n }\n}\n\ncontract MockSwapperWithSwap is ISwapper {\n using SafeERC20 for IERC20;\n bytes32 public constant CALLBACK_SUCCESS = keccak256(\"ERC3156FlashBorrower.onFlashLoan\");\n\n uint256 public counter;\n\n constructor() {}\n\n function swap(\n IERC20,\n IERC20 outToken,\n address outTokenRecipient,\n uint256 outTokenOwed,\n uint256,\n bytes calldata data\n ) external {\n counter += 1;\n outToken.safeTransfer(outTokenRecipient, outTokenOwed);\n\n data;\n }\n}\n" + }, + "contracts/mock/MockSwapperSidechain.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\nimport \"../swapper/Swapper.sol\";\n\n/// @title MockSwapperSidechain\n/// @author Angle Labs, Inc.\ncontract MockSwapperSidechain is Swapper {\n error NotImplemented();\n\n /// @notice Constructor of the contract\n /// @param _core Core address\n /// @param _uniV3Router UniswapV3 Router address\n /// @param _oneInch 1Inch Router address\n /// @param _angleRouter AngleRouter contract address\n constructor(\n ICoreBorrow _core,\n IUniswapV3Router _uniV3Router,\n address _oneInch,\n IAngleRouterSidechain _angleRouter\n ) Swapper(_core, _uniV3Router, _oneInch, _angleRouter) {}\n\n function _swapLeverage(bytes memory) internal pure override returns (uint256) {\n revert NotImplemented();\n }\n}\n" + }, + "contracts/mock/MockToken.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.7;\n\nimport \"@openzeppelin/contracts/token/ERC20/ERC20.sol\";\n\ncontract MockToken is ERC20 {\n event Minting(address indexed _to, address indexed _minter, uint256 _amount);\n\n event Burning(address indexed _from, address indexed _burner, uint256 _amount);\n\n uint8 internal _decimal;\n mapping(address => bool) public minters;\n address public treasury;\n\n constructor(string memory name_, string memory symbol_, uint8 decimal_) ERC20(name_, symbol_) {\n _decimal = decimal_;\n }\n\n function decimals() public view override returns (uint8) {\n return _decimal;\n }\n\n function mint(address account, uint256 amount) external {\n _mint(account, amount);\n emit Minting(account, msg.sender, amount);\n }\n\n function burn(address account, uint256 amount) public {\n _burn(account, amount);\n emit Burning(account, msg.sender, amount);\n }\n\n function setAllowance(address from, address to) public {\n _approve(from, to, type(uint256).max);\n }\n\n function burnSelf(uint256 amount, address account) public {\n _burn(account, amount);\n emit Burning(account, msg.sender, amount);\n }\n\n function addMinter(address minter) public {\n minters[minter] = true;\n }\n\n function removeMinter(address minter) public {\n minters[minter] = false;\n }\n\n function setTreasury(address _treasury) public {\n treasury = _treasury;\n }\n}\n" + }, + "contracts/mock/MockTokenPermit.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.7;\n\nimport \"@openzeppelin/contracts/token/ERC20/extensions/draft-ERC20Permit.sol\";\nimport \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\nimport \"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\";\n\ncontract MockTokenPermit is ERC20Permit {\n using SafeERC20 for IERC20;\n event Minting(address indexed _to, address indexed _minter, uint256 _amount);\n\n event Burning(address indexed _from, address indexed _burner, uint256 _amount);\n\n uint8 internal _decimal;\n mapping(address => bool) public minters;\n address public treasury;\n uint256 public fees;\n\n bool public reverts;\n\n constructor(string memory name_, string memory symbol_, uint8 decimal_) ERC20Permit(name_) ERC20(name_, symbol_) {\n _decimal = decimal_;\n }\n\n function decimals() public view override returns (uint8) {\n return _decimal;\n }\n\n function mint(address account, uint256 amount) external {\n _mint(account, amount);\n emit Minting(account, msg.sender, amount);\n }\n\n function burn(address account, uint256 amount) public {\n _burn(account, amount);\n emit Burning(account, msg.sender, amount);\n }\n\n function setAllowance(address from, address to) public {\n _approve(from, to, type(uint256).max);\n }\n\n function burnSelf(uint256 amount, address account) public {\n _burn(account, amount);\n emit Burning(account, msg.sender, amount);\n }\n\n function addMinter(address minter) public {\n minters[minter] = true;\n }\n\n function removeMinter(address minter) public {\n minters[minter] = false;\n }\n\n function setTreasury(address _treasury) public {\n treasury = _treasury;\n }\n\n function setFees(uint256 _fees) public {\n fees = _fees;\n }\n\n function recoverERC20(IERC20 token, address to, uint256 amount) external {\n token.safeTransfer(to, amount);\n }\n\n function swapIn(address bridgeToken, uint256 amount, address to) external returns (uint256) {\n require(!reverts);\n\n IERC20(bridgeToken).safeTransferFrom(msg.sender, address(this), amount);\n uint256 canonicalOut = amount;\n canonicalOut -= (canonicalOut * fees) / 10 ** 9;\n _mint(to, canonicalOut);\n return canonicalOut;\n }\n\n function swapOut(address bridgeToken, uint256 amount, address to) external returns (uint256) {\n require(!reverts);\n _burn(msg.sender, amount);\n uint256 bridgeOut = amount;\n bridgeOut -= (bridgeOut * fees) / 10 ** 9;\n IERC20(bridgeToken).safeTransfer(to, bridgeOut);\n return bridgeOut;\n }\n}\n" + }, + "contracts/mock/MockTreasury.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\nimport \"../interfaces/ITreasury.sol\";\nimport \"../interfaces/IFlashAngle.sol\";\nimport \"../interfaces/IVaultManager.sol\";\n\ncontract MockTreasury is ITreasury {\n IAgToken public override stablecoin;\n address public governor;\n address public guardian;\n address public vaultManager1;\n address public vaultManager2;\n address public flashLoanModule;\n address[] public vaultManagerList;\n\n constructor(\n IAgToken _stablecoin,\n address _governor,\n address _guardian,\n address _vaultManager1,\n address _vaultManager2,\n address _flashLoanModule\n ) {\n stablecoin = _stablecoin;\n governor = _governor;\n guardian = _guardian;\n vaultManager1 = _vaultManager1;\n vaultManager2 = _vaultManager2;\n flashLoanModule = _flashLoanModule;\n }\n\n function isGovernor(address admin) external view override returns (bool) {\n return (admin == governor);\n }\n\n function isGovernorOrGuardian(address admin) external view override returns (bool) {\n return (admin == governor || admin == guardian);\n }\n\n function isVaultManager(address _vaultManager) external view override returns (bool) {\n return (_vaultManager == vaultManager1 || _vaultManager == vaultManager2);\n }\n\n function setStablecoin(IAgToken _stablecoin) external {\n stablecoin = _stablecoin;\n }\n\n function setFlashLoanModule(address _flashLoanModule) external override {\n flashLoanModule = _flashLoanModule;\n }\n\n function setGovernor(address _governor) external {\n governor = _governor;\n }\n\n function setVaultManager(address _vaultManager) external {\n vaultManager1 = _vaultManager;\n }\n\n function setVaultManager2(address _vaultManager) external {\n vaultManager2 = _vaultManager;\n }\n\n function setTreasury(address _agTokenOrVaultManager, address _treasury) external {\n IAgToken(_agTokenOrVaultManager).setTreasury(_treasury);\n }\n\n function addMinter(IAgToken _agToken, address _minter) external {\n _agToken.addMinter(_minter);\n }\n\n function removeMinter(IAgToken _agToken, address _minter) external {\n _agToken.removeMinter(_minter);\n }\n\n function accrueInterestToTreasury(IFlashAngle flashAngle) external returns (uint256 balance) {\n balance = flashAngle.accrueInterestToTreasury(stablecoin);\n }\n\n function accrueInterestToTreasuryVaultManager(IVaultManager _vaultManager) external returns (uint256, uint256) {\n return _vaultManager.accrueInterestToTreasury();\n }\n}\n" + }, + "contracts/mock/MockUniswapV3Pool.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.7;\n\ncontract MockUniswapV3Pool {\n address public token0;\n address public token1;\n uint32 public constant EPOCH_DURATION = 24 * 3600 * 7;\n\n function setToken(address token, uint256 who) external {\n if (who == 0) token0 = token;\n else token1 = token;\n }\n\n function round(uint256 amount) external pure returns (uint256) {\n return (amount / EPOCH_DURATION) * EPOCH_DURATION;\n }\n}\n" + }, + "contracts/mock/MockVaultManager.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\nimport \"../interfaces/IVaultManager.sol\";\nimport \"../interfaces/ITreasury.sol\";\nimport \"@openzeppelin/contracts/token/ERC20/ERC20.sol\";\n\ncontract MockVaultManager {\n ITreasury public treasury;\n mapping(uint256 => Vault) public vaultData;\n mapping(uint256 => address) public ownerOf;\n uint256 public surplus;\n uint256 public badDebt;\n IAgToken public token;\n address public oracle = address(this);\n\n address public governor;\n address public collateral;\n address public stablecoin;\n uint256 public oracleValue;\n uint256 public interestAccumulator;\n uint256 public collateralFactor;\n uint256 public totalNormalizedDebt;\n\n constructor(address _treasury) {\n treasury = ITreasury(_treasury);\n }\n\n function accrueInterestToTreasury() external returns (uint256, uint256) {\n // Avoid the function to be view\n if (surplus >= badDebt) {\n token.mint(msg.sender, surplus - badDebt);\n }\n return (surplus, badDebt);\n }\n\n function read() external view returns (uint256) {\n return oracleValue;\n }\n\n function setParams(\n address _governor,\n address _collateral,\n address _stablecoin,\n uint256 _oracleValue,\n uint256 _interestAccumulator,\n uint256 _collateralFactor,\n uint256 _totalNormalizedDebt\n ) external {\n governor = _governor;\n collateral = _collateral;\n stablecoin = _stablecoin;\n interestAccumulator = _interestAccumulator;\n collateralFactor = _collateralFactor;\n totalNormalizedDebt = _totalNormalizedDebt;\n oracleValue = _oracleValue;\n }\n\n function setOwner(uint256 vaultID, address owner) external virtual {\n ownerOf[vaultID] = owner;\n }\n\n function setVaultData(uint256 normalizedDebt, uint256 collateralAmount, uint256 vaultID) external {\n vaultData[vaultID].normalizedDebt = normalizedDebt;\n vaultData[vaultID].collateralAmount = collateralAmount;\n }\n\n function isGovernor(address admin) external view returns (bool) {\n return admin == governor;\n }\n\n function setSurplusBadDebt(uint256 _surplus, uint256 _badDebt, IAgToken _token) external {\n surplus = _surplus;\n badDebt = _badDebt;\n token = _token;\n }\n\n function getDebtOut(uint256 vaultID, uint256 amountStablecoins, uint256 senderBorrowFee) external {}\n\n function setTreasury(address _treasury) external {\n treasury = ITreasury(_treasury);\n }\n\n function getVaultDebt(uint256 vaultID) external view returns (uint256) {\n vaultID;\n token;\n return 0;\n }\n\n function createVault(address toVault) external view returns (uint256) {\n toVault;\n token;\n return 0;\n }\n}\n\ncontract MockVaultManagerListing is MockVaultManager {\n // @notice Mapping from owner address to all his vaults\n mapping(address => uint256[]) internal _ownerListVaults;\n\n constructor(address _treasury) MockVaultManager(_treasury) {}\n\n function getUserVaults(address owner) public view returns (uint256[] memory) {\n return _ownerListVaults[owner];\n }\n\n function getUserCollateral(address owner) public view returns (uint256 totalCollateral) {\n uint256[] memory vaultList = _ownerListVaults[owner];\n uint256 vaultListLength = vaultList.length;\n for (uint256 k; k < vaultListLength; ++k) {\n totalCollateral += vaultData[vaultList[k]].collateralAmount;\n }\n return totalCollateral;\n }\n\n function setOwner(uint256 vaultID, address owner) external override {\n if (ownerOf[vaultID] != address(0)) _removeVaultFromList(ownerOf[vaultID], vaultID);\n _ownerListVaults[owner].push(vaultID);\n ownerOf[vaultID] = owner;\n }\n\n /// @notice Remove `vaultID` from `user` stroed vault list\n /// @param user Address to look out for the vault list\n /// @param vaultID VaultId to remove from the list\n /// @dev The vault is necessarily in the list\n function _removeVaultFromList(address user, uint256 vaultID) internal {\n uint256[] storage vaultList = _ownerListVaults[user];\n uint256 vaultListLength = vaultList.length;\n for (uint256 i; i < vaultListLength - 1; ++i) {\n if (vaultList[i] == vaultID) {\n vaultList[i] = vaultList[vaultListLength - 1];\n break;\n }\n }\n vaultList.pop();\n }\n}\n" + }, + "contracts/mock/MockVeBoostProxy.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\nimport \"../interfaces/governance/IVeBoostProxy.sol\";\n\ncontract MockVeBoostProxy is IVeBoostProxy {\n //solhint-disable-next-line\n mapping(address => uint256) public adjusted_balance_of;\n\n constructor() {}\n\n function setBalance(address concerned, uint256 balance) external {\n adjusted_balance_of[concerned] = balance;\n }\n}\n" + }, + "contracts/oracle/BaseOracleChainlinkMulti.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\n/*\n * █ \n ***** ▓▓▓ \n * ▓▓▓▓▓▓▓ \n * ///. ▓▓▓▓▓▓▓▓▓▓▓▓▓ \n ***** //////// ▓▓▓▓▓▓▓ \n * ///////////// ▓▓▓ \n ▓▓ ////////////////// █ ▓▓ \n ▓▓ ▓▓ /////////////////////// ▓▓ ▓▓ \n ▓▓ ▓▓ //////////////////////////// ▓▓ ▓▓ \n ▓▓ ▓▓ /////////▓▓▓///////▓▓▓///////// ▓▓ ▓▓ \n ▓▓ ,////////////////////////////////////// ▓▓ ▓▓ \n ▓▓ ////////////////////////////////////////// ▓▓ \n ▓▓ //////////////////////▓▓▓▓///////////////////// \n ,//////////////////////////////////////////////////// \n .////////////////////////////////////////////////////////// \n .//////////////////////////██.,//////////////////////////█ \n .//////////////////////████..,./////////////////////██ \n ...////////////////███████.....,.////////////////███ \n ,.,////////////████████ ........,///////////████ \n .,.,//////█████████ ,.......///////████ \n ,..//████████ ........./████ \n ..,██████ .....,███ \n .██ ,.,█ \n \n \n \n ▓▓ ▓▓▓▓▓▓▓▓▓▓ ▓▓▓▓▓▓▓▓▓▓ ▓▓ ▓▓▓▓▓▓▓▓▓▓ \n ▓▓▓▓▓▓ ▓▓▓ ▓▓▓ ▓▓▓ ▓▓ ▓▓ ▓▓▓▓ \n ▓▓▓ ▓▓▓ ▓▓▓ ▓▓▓ ▓▓▓ ▓▓▓ ▓▓ ▓▓▓▓▓ \n ▓▓▓ ▓▓ ▓▓▓ ▓▓▓ ▓▓▓▓▓▓▓▓▓▓ ▓▓▓▓▓▓▓▓▓▓ ▓▓▓▓▓▓▓▓▓▓ \n*/\n\npragma solidity ^0.8.12;\n\nimport \"@chainlink/contracts/src/v0.8/interfaces/AggregatorV3Interface.sol\";\n\nimport \"../interfaces/IOracle.sol\";\nimport \"../interfaces/ITreasury.sol\";\n\n/// @title BaseOracleChainlinkMulti\n/// @author Angle Labs, Inc.\n/// @notice Base Contract to be overriden by all contracts of the protocol\n/// @dev This base contract concerns an oracle that uses Chainlink with multiple pools to read from\n/// @dev All gas-efficient implementation of the `OracleChainlinkMulti` contract should inherit from this\nabstract contract BaseOracleChainlinkMulti is IOracle {\n // ========================= Parameters and References =========================\n\n /// @inheritdoc IOracle\n ITreasury public override treasury;\n /// @notice Represent the maximum amount of time (in seconds) between each Chainlink update\n /// before the price feed is considered stale\n uint32 public stalePeriod;\n\n // =================================== Event ===================================\n\n event StalePeriodUpdated(uint32 _stalePeriod);\n\n // =================================== Errors ===================================\n\n error InvalidChainlinkRate();\n error NotGovernorOrGuardian();\n error NotVaultManagerOrGovernor();\n\n /// @notice Constructor for an oracle using Chainlink with multiple pools to read from\n /// @param _stalePeriod Minimum feed update frequency for the oracle to not revert\n /// @param _treasury Treasury associated to the VaultManager which reads from this feed\n constructor(uint32 _stalePeriod, address _treasury) {\n stalePeriod = _stalePeriod;\n treasury = ITreasury(_treasury);\n }\n\n // ============================= Reading Oracles ===============================\n\n /// @inheritdoc IOracle\n function read() external view virtual override returns (uint256 quoteAmount);\n\n /// @inheritdoc IOracle\n function circuitChainlink() public view virtual returns (AggregatorV3Interface[] memory);\n\n /// @notice Reads a Chainlink feed using a quote amount and converts the quote amount to\n /// the out-currency\n /// @param quoteAmount The amount for which to compute the price expressed with base decimal\n /// @param feed Chainlink feed to query\n /// @param multiplied Whether the ratio outputted by Chainlink should be multiplied or divided\n /// to the `quoteAmount`\n /// @param decimals Number of decimals of the corresponding Chainlink pair\n /// @return The `quoteAmount` converted in out-currency\n function _readChainlinkFeed(\n uint256 quoteAmount,\n AggregatorV3Interface feed,\n uint8 multiplied,\n uint256 decimals\n ) internal view returns (uint256) {\n (uint80 roundId, int256 ratio, , uint256 updatedAt, uint80 answeredInRound) = feed.latestRoundData();\n if (ratio <= 0 || roundId > answeredInRound || block.timestamp - updatedAt > stalePeriod)\n revert InvalidChainlinkRate();\n uint256 castedRatio = uint256(ratio);\n // Checking whether we should multiply or divide by the ratio computed\n if (multiplied == 1) return (quoteAmount * castedRatio) / (10 ** decimals);\n else return (quoteAmount * (10 ** decimals)) / castedRatio;\n }\n\n // ======================= Governance Related Functions ========================\n\n /// @notice Changes the stale period\n /// @param _stalePeriod New stale period (in seconds)\n function changeStalePeriod(uint32 _stalePeriod) external {\n if (!treasury.isGovernorOrGuardian(msg.sender)) revert NotGovernorOrGuardian();\n stalePeriod = _stalePeriod;\n emit StalePeriodUpdated(_stalePeriod);\n }\n\n /// @inheritdoc IOracle\n function setTreasury(address _treasury) external override {\n if (!treasury.isVaultManager(msg.sender) && !treasury.isGovernor(msg.sender))\n revert NotVaultManagerOrGovernor();\n treasury = ITreasury(_treasury);\n }\n}\n" + }, + "contracts/oracle/BaseOracleChainlinkMultiTwoFeeds.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\nimport \"@chainlink/contracts/src/v0.8/interfaces/AggregatorV3Interface.sol\";\n\nimport \"./BaseOracleChainlinkMulti.sol\";\n\n/// @title BaseOracleChainlinkMultiTwoFeeds\n/// @author Angle Labs, Inc.\n/// @notice Base contract for an oracle that reads into two Chainlink feeds (including an EUR/USD feed) which both have\n/// 8 decimals\nabstract contract BaseOracleChainlinkMultiTwoFeeds is BaseOracleChainlinkMulti {\n constructor(uint32 _stalePeriod, address _treasury) BaseOracleChainlinkMulti(_stalePeriod, _treasury) {}\n\n /// @notice Returns the quote amount of the oracle contract\n function _getQuoteAmount() internal view virtual returns (uint256) {\n return 10 ** 18;\n }\n\n /// @inheritdoc IOracle\n function read() external view virtual override returns (uint256 quoteAmount) {\n quoteAmount = _getQuoteAmount();\n AggregatorV3Interface[] memory _circuitChainlink = circuitChainlink();\n uint8[2] memory circuitChainIsMultiplied = [1, 0];\n uint8[2] memory chainlinkDecimals = [8, 8];\n uint256 circuitLength = _circuitChainlink.length;\n for (uint256 i; i < circuitLength; ++i) {\n quoteAmount = _readChainlinkFeed(\n quoteAmount,\n _circuitChainlink[i],\n circuitChainIsMultiplied[i],\n chainlinkDecimals[i]\n );\n }\n }\n}\n" + }, + "contracts/oracle/BaseOracleChainlinkOneFeed.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\nimport \"@chainlink/contracts/src/v0.8/interfaces/AggregatorV3Interface.sol\";\n\nimport \"./BaseOracleChainlinkMulti.sol\";\n\n/// @title BaseOracleChainlinkOneFeed\n/// @author Angle Labs, Inc.\n/// @notice Base contract for an oracle that reads into one Chainlink feeds with 8 decimals\nabstract contract BaseOracleChainlinkOneFeed is BaseOracleChainlinkMulti {\n constructor(uint32 _stalePeriod, address _treasury) BaseOracleChainlinkMulti(_stalePeriod, _treasury) {}\n\n /// @notice Returns the quote amount of the oracle contract\n function _getQuoteAmount() internal view virtual returns (uint256) {\n return 10 ** 18;\n }\n\n /// @inheritdoc IOracle\n function read() external view virtual override returns (uint256 quoteAmount) {\n AggregatorV3Interface[] memory _circuitChainlink = circuitChainlink();\n quoteAmount = _readChainlinkFeed(_getQuoteAmount(), _circuitChainlink[0], 1, 8);\n }\n}\n" + }, + "contracts/oracle/implementations/arbitrum/EUR/OracleBTCEURChainlinkArbitrum.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\nimport \"@chainlink/contracts/src/v0.8/interfaces/AggregatorV3Interface.sol\";\n\nimport \"../../../BaseOracleChainlinkMultiTwoFeeds.sol\";\n\n/// @title OracleBTCEURChainlinkArbitrum\n/// @author Angle Labs, Inc.\n/// @notice Gives the price of BTC in Euro in base 18\n/// @dev This contract is built to be deployed on Arbitrum\ncontract OracleBTCEURChainlinkArbitrum is BaseOracleChainlinkMultiTwoFeeds {\n string public constant DESCRIPTION = \"BTC/EUR Oracle\";\n\n constructor(uint32 _stalePeriod, address _treasury) BaseOracleChainlinkMultiTwoFeeds(_stalePeriod, _treasury) {}\n\n /// @inheritdoc IOracle\n function circuitChainlink() public pure override returns (AggregatorV3Interface[] memory) {\n AggregatorV3Interface[] memory _circuitChainlink = new AggregatorV3Interface[](2);\n // Oracle BTC/USD\n _circuitChainlink[0] = AggregatorV3Interface(0x6ce185860a4963106506C203335A2910413708e9);\n // Oracle EUR/USD\n _circuitChainlink[1] = AggregatorV3Interface(0xA14d53bC1F1c0F31B4aA3BD109344E5009051a84);\n return _circuitChainlink;\n }\n}\n" + }, + "contracts/oracle/implementations/arbitrum/EUR/OracleETHEURChainlinkArbitrum.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\nimport \"@chainlink/contracts/src/v0.8/interfaces/AggregatorV3Interface.sol\";\n\nimport \"../../../BaseOracleChainlinkMultiTwoFeeds.sol\";\n\n/// @title OracleETHEURChainlinkArbitrum\n/// @author Angle Labs, Inc.\n/// @notice Gives the price of ETH in Euro in base 18\n/// @dev This contract is built to be deployed on Arbitrum\ncontract OracleETHEURChainlinkArbitrum is BaseOracleChainlinkMultiTwoFeeds {\n string public constant DESCRIPTION = \"ETH/EUR Oracle\";\n\n constructor(uint32 _stalePeriod, address _treasury) BaseOracleChainlinkMultiTwoFeeds(_stalePeriod, _treasury) {}\n\n /// @inheritdoc IOracle\n function circuitChainlink() public pure override returns (AggregatorV3Interface[] memory) {\n AggregatorV3Interface[] memory _circuitChainlink = new AggregatorV3Interface[](2);\n // Oracle ETH/USD\n _circuitChainlink[0] = AggregatorV3Interface(0x639Fe6ab55C921f74e7fac1ee960C0B6293ba612);\n // Oracle EUR/USD\n _circuitChainlink[1] = AggregatorV3Interface(0xA14d53bC1F1c0F31B4aA3BD109344E5009051a84);\n return _circuitChainlink;\n }\n}\n" + }, + "contracts/oracle/implementations/arbitrum/EUR/OracleUSDCEURChainlinkArbitrum.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\nimport \"@chainlink/contracts/src/v0.8/interfaces/AggregatorV3Interface.sol\";\n\nimport \"../../../BaseOracleChainlinkMultiTwoFeeds.sol\";\n\n/// @title OracleUSDCEURChainlinkArbitrum\n/// @author Angle Labs, Inc.\n/// @notice Gives the price of USDC in Euro in base 18\n/// @dev This contract is built to be deployed on Arbitrum\ncontract OracleUSDCEURChainlinkArbitrum is BaseOracleChainlinkMultiTwoFeeds {\n string public constant DESCRIPTION = \"USDC/EUR Oracle\";\n\n constructor(uint32 _stalePeriod, address _treasury) BaseOracleChainlinkMultiTwoFeeds(_stalePeriod, _treasury) {}\n\n /// @inheritdoc IOracle\n function circuitChainlink() public pure override returns (AggregatorV3Interface[] memory) {\n AggregatorV3Interface[] memory _circuitChainlink = new AggregatorV3Interface[](2);\n // Oracle ETH/USD\n _circuitChainlink[0] = AggregatorV3Interface(0x50834F3163758fcC1Df9973b6e91f0F0F0434aD3);\n // Oracle EUR/USD\n _circuitChainlink[1] = AggregatorV3Interface(0xA14d53bC1F1c0F31B4aA3BD109344E5009051a84);\n return _circuitChainlink;\n }\n}\n" + }, + "contracts/oracle/implementations/avalanche/EUR/OracleAVAXEURChainlinkAvalanche.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\nimport \"@chainlink/contracts/src/v0.8/interfaces/AggregatorV3Interface.sol\";\n\nimport \"../../../BaseOracleChainlinkMultiTwoFeeds.sol\";\n\n/// @title OracleAVAXEURChainlinkAvalanche\n/// @author Angle Labs, Inc.\n/// @notice Gives the price of AVAX in Euro in base 18\n/// @dev This contract is built to be deployed on Avalanche\ncontract OracleAVAXEURChainlinkAvalanche is BaseOracleChainlinkMultiTwoFeeds {\n string public constant DESCRIPTION = \"AVAX/EUR Oracle\";\n\n constructor(uint32 _stalePeriod, address _treasury) BaseOracleChainlinkMultiTwoFeeds(_stalePeriod, _treasury) {}\n\n /// @inheritdoc IOracle\n function circuitChainlink() public pure override returns (AggregatorV3Interface[] memory) {\n AggregatorV3Interface[] memory _circuitChainlink = new AggregatorV3Interface[](2);\n // Oracle AVAX/USD\n _circuitChainlink[0] = AggregatorV3Interface(0x0A77230d17318075983913bC2145DB16C7366156);\n // Oracle EUR/USD\n _circuitChainlink[1] = AggregatorV3Interface(0x192f2DBA961Bb0277520C082d6bfa87D5961333E);\n return _circuitChainlink;\n }\n}\n" + }, + "contracts/oracle/implementations/avalanche/EUR/OracleUSDCEURChainlinkAvalanche.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\nimport \"@chainlink/contracts/src/v0.8/interfaces/AggregatorV3Interface.sol\";\n\nimport \"../../../BaseOracleChainlinkMultiTwoFeeds.sol\";\n\n/// @title OracleUSDCEURChainlinkAvalanche\n/// @author Angle Labs, Inc.\n/// @notice Gives the price of USDC in Euro in base 18\n/// @dev This contract is built to be deployed on Avalanche\ncontract OracleUSDCEURChainlinkAvalanche is BaseOracleChainlinkMultiTwoFeeds {\n string public constant DESCRIPTION = \"USDC/EUR Oracle\";\n\n constructor(uint32 _stalePeriod, address _treasury) BaseOracleChainlinkMultiTwoFeeds(_stalePeriod, _treasury) {}\n\n /// @inheritdoc IOracle\n function circuitChainlink() public pure override returns (AggregatorV3Interface[] memory) {\n AggregatorV3Interface[] memory _circuitChainlink = new AggregatorV3Interface[](2);\n // Oracle USDC/USD\n _circuitChainlink[0] = AggregatorV3Interface(0xF096872672F44d6EBA71458D74fe67F9a77a23B9);\n // Oracle EUR/USD\n _circuitChainlink[1] = AggregatorV3Interface(0x192f2DBA961Bb0277520C082d6bfa87D5961333E);\n return _circuitChainlink;\n }\n}\n" + }, + "contracts/oracle/implementations/mainnet/EUR/OracleBTCEURChainlink.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\nimport \"@chainlink/contracts/src/v0.8/interfaces/AggregatorV3Interface.sol\";\n\nimport \"../../../BaseOracleChainlinkMultiTwoFeeds.sol\";\n\n/// @title OracleBTCEURChainlink\n/// @author Angle Labs, Inc.\n/// @notice Gives the price of BTC in Euro in base 18\ncontract OracleBTCEURChainlink is BaseOracleChainlinkMultiTwoFeeds {\n string public constant DESCRIPTION = \"BTC/EUR Oracle\";\n\n constructor(uint32 _stalePeriod, address _treasury) BaseOracleChainlinkMultiTwoFeeds(_stalePeriod, _treasury) {}\n\n /// @inheritdoc IOracle\n function circuitChainlink() public pure override returns (AggregatorV3Interface[] memory) {\n AggregatorV3Interface[] memory _circuitChainlink = new AggregatorV3Interface[](2);\n // Oracle BTC/USD\n _circuitChainlink[0] = AggregatorV3Interface(0xF4030086522a5bEEa4988F8cA5B36dbC97BeE88c);\n // Oracle EUR/USD\n _circuitChainlink[1] = AggregatorV3Interface(0xb49f677943BC038e9857d61E7d053CaA2C1734C1);\n return _circuitChainlink;\n }\n}\n" + }, + "contracts/oracle/implementations/mainnet/EUR/OracleCBETHEURChainlink.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\nimport \"@chainlink/contracts/src/v0.8/interfaces/AggregatorV3Interface.sol\";\n\nimport \"../../../BaseOracleChainlinkMultiTwoFeeds.sol\";\n\n/// @title OracleCBETHEURChainlink\n/// @author Angle Labs, Inc.\n/// @notice Gives the price of cbETH in Euro in base 18\ncontract OracleCBETHEURChainlink is BaseOracleChainlinkMultiTwoFeeds {\n string public constant DESCRIPTION = \"cbETH/EUR Oracle\";\n\n constructor(uint32 _stalePeriod, address _treasury) BaseOracleChainlinkMultiTwoFeeds(_stalePeriod, _treasury) {}\n\n /// @inheritdoc IOracle\n function circuitChainlink() public pure override returns (AggregatorV3Interface[] memory) {\n AggregatorV3Interface[] memory _circuitChainlink = new AggregatorV3Interface[](3);\n // Oracle cbETH/ETH\n _circuitChainlink[0] = AggregatorV3Interface(0xF017fcB346A1885194689bA23Eff2fE6fA5C483b);\n // Oracle ETH/USD\n _circuitChainlink[1] = AggregatorV3Interface(0x5f4eC3Df9cbd43714FE2740f5E3616155c5b8419);\n // Oracle EUR/USD\n _circuitChainlink[2] = AggregatorV3Interface(0xb49f677943BC038e9857d61E7d053CaA2C1734C1);\n return _circuitChainlink;\n }\n\n /// @inheritdoc BaseOracleChainlinkMultiTwoFeeds\n function read() external view virtual override returns (uint256 quoteAmount) {\n quoteAmount = _getQuoteAmount();\n AggregatorV3Interface[] memory _circuitChainlink = circuitChainlink();\n uint8[3] memory circuitChainIsMultiplied = [1, 1, 0];\n uint8[3] memory chainlinkDecimals = [18, 8, 8];\n uint256 circuitLength = _circuitChainlink.length;\n for (uint256 i; i < circuitLength; ++i) {\n quoteAmount = _readChainlinkFeed(\n quoteAmount,\n _circuitChainlink[i],\n circuitChainIsMultiplied[i],\n chainlinkDecimals[i]\n );\n }\n }\n}\n" + }, + "contracts/oracle/implementations/mainnet/EUR/OracleETHEURChainlink.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\nimport \"@chainlink/contracts/src/v0.8/interfaces/AggregatorV3Interface.sol\";\n\nimport \"../../../BaseOracleChainlinkMultiTwoFeeds.sol\";\n\n/// @title OracleETHEURChainlink\n/// @author Angle Labs, Inc.\n/// @notice Gives the price of ETH in Euro in base 18\ncontract OracleETHEURChainlink is BaseOracleChainlinkMultiTwoFeeds {\n string public constant DESCRIPTION = \"ETH/EUR Oracle\";\n\n constructor(uint32 _stalePeriod, address _treasury) BaseOracleChainlinkMultiTwoFeeds(_stalePeriod, _treasury) {}\n\n /// @inheritdoc IOracle\n function circuitChainlink() public pure override returns (AggregatorV3Interface[] memory) {\n AggregatorV3Interface[] memory _circuitChainlink = new AggregatorV3Interface[](2);\n // Oracle ETH/USD\n _circuitChainlink[0] = AggregatorV3Interface(0x5f4eC3Df9cbd43714FE2740f5E3616155c5b8419);\n // Oracle EUR/USD\n _circuitChainlink[1] = AggregatorV3Interface(0xb49f677943BC038e9857d61E7d053CaA2C1734C1);\n return _circuitChainlink;\n }\n}\n" + }, + "contracts/oracle/implementations/mainnet/EUR/OracleHIGHEURChainlink.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\nimport \"@chainlink/contracts/src/v0.8/interfaces/AggregatorV3Interface.sol\";\n\nimport \"../../../BaseOracleChainlinkMultiTwoFeeds.sol\";\n\n/// @title OracleHIGHEURChainlink\n/// @author Angle Labs, Inc.\n/// @notice Gives the price of HIGH in Euro in base 18\ncontract OracleHIGHEURChainlink is BaseOracleChainlinkMultiTwoFeeds {\n string public constant DESCRIPTION = \"HIGH/EUR Oracle\";\n\n constructor(uint32 _stalePeriod, address _treasury) BaseOracleChainlinkMultiTwoFeeds(_stalePeriod, _treasury) {}\n\n /// @inheritdoc IOracle\n function circuitChainlink() public pure override returns (AggregatorV3Interface[] memory) {\n AggregatorV3Interface[] memory _circuitChainlink = new AggregatorV3Interface[](1);\n // Oracle HIGH/EUR\n _circuitChainlink[0] = AggregatorV3Interface(0x9E8E794ad6Ecdb6d5c7eaBE059D30E907F58859b);\n return _circuitChainlink;\n }\n\n /// @inheritdoc BaseOracleChainlinkMultiTwoFeeds\n function read() external view override returns (uint256 quoteAmount) {\n quoteAmount = _readChainlinkFeed(_getQuoteAmount(), circuitChainlink()[0], 1, 8);\n }\n}\n" + }, + "contracts/oracle/implementations/mainnet/EUR/OracleIB01EURChainlink.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\nimport \"@chainlink/contracts/src/v0.8/interfaces/AggregatorV3Interface.sol\";\n\nimport \"../../../BaseOracleChainlinkMultiTwoFeeds.sol\";\n\n/// @title OracleIB01EURChainlink\n/// @author Angle Labs, Inc.\n/// @notice Gives the price of IB01 in Euro in base 18\ncontract OracleIB01EURChainlink is BaseOracleChainlinkMultiTwoFeeds {\n string public constant DESCRIPTION = \"IB01/EUR Oracle\";\n\n constructor(uint32 _stalePeriod, address _treasury) BaseOracleChainlinkMultiTwoFeeds(_stalePeriod, _treasury) {}\n\n /// @inheritdoc IOracle\n function circuitChainlink() public pure override returns (AggregatorV3Interface[] memory) {\n AggregatorV3Interface[] memory _circuitChainlink = new AggregatorV3Interface[](2);\n // Oracle IB01/USD\n _circuitChainlink[0] = AggregatorV3Interface(0x32d1463EB53b73C095625719Afa544D5426354cB);\n // Oracle EUR/USD\n _circuitChainlink[1] = AggregatorV3Interface(0xb49f677943BC038e9857d61E7d053CaA2C1734C1);\n return _circuitChainlink;\n }\n}\n" + }, + "contracts/oracle/implementations/mainnet/EUR/OracleLUSDEURChainlink.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\nimport \"@chainlink/contracts/src/v0.8/interfaces/AggregatorV3Interface.sol\";\n\nimport \"../../../BaseOracleChainlinkMultiTwoFeeds.sol\";\n\n/// @title OracleLUSDEURChainlink\n/// @author Angle Labs, Inc.\n/// @notice Gives the price of LUSD in Euro in base 18\ncontract OracleLUSDEURChainlink is BaseOracleChainlinkMultiTwoFeeds {\n string public constant DESCRIPTION = \"LUSD/EUR Oracle\";\n\n constructor(uint32 _stalePeriod, address _treasury) BaseOracleChainlinkMultiTwoFeeds(_stalePeriod, _treasury) {}\n\n /// @inheritdoc IOracle\n function circuitChainlink() public pure override returns (AggregatorV3Interface[] memory) {\n AggregatorV3Interface[] memory _circuitChainlink = new AggregatorV3Interface[](2);\n // Oracle LUSD/USD\n _circuitChainlink[0] = AggregatorV3Interface(0x3D7aE7E594f2f2091Ad8798313450130d0Aba3a0);\n // Oracle EUR/USD\n _circuitChainlink[1] = AggregatorV3Interface(0xb49f677943BC038e9857d61E7d053CaA2C1734C1);\n return _circuitChainlink;\n }\n}\n" + }, + "contracts/oracle/implementations/mainnet/EUR/OracleUSDCEURChainlink.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\nimport \"@chainlink/contracts/src/v0.8/interfaces/AggregatorV3Interface.sol\";\n\nimport \"../../../BaseOracleChainlinkMultiTwoFeeds.sol\";\n\n/// @title OracleUSDCEURChainlink\n/// @author Angle Labs, Inc.\n/// @notice Gives the price of USDC in Euro in base 18\ncontract OracleUSDCEURChainlink is BaseOracleChainlinkMultiTwoFeeds {\n string public constant DESCRIPTION = \"USDC/EUR Oracle\";\n\n constructor(uint32 _stalePeriod, address _treasury) BaseOracleChainlinkMultiTwoFeeds(_stalePeriod, _treasury) {}\n\n /// @inheritdoc IOracle\n function circuitChainlink() public pure override returns (AggregatorV3Interface[] memory) {\n AggregatorV3Interface[] memory _circuitChainlink = new AggregatorV3Interface[](2);\n // Oracle USDC/USD\n _circuitChainlink[0] = AggregatorV3Interface(0x8fFfFfd4AfB6115b954Bd326cbe7B4BA576818f6);\n // Oracle EUR/USD\n _circuitChainlink[1] = AggregatorV3Interface(0xb49f677943BC038e9857d61E7d053CaA2C1734C1);\n return _circuitChainlink;\n }\n}\n" + }, + "contracts/oracle/implementations/mainnet/EUR/OracleWSTETHEURChainlink.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\nimport \"@chainlink/contracts/src/v0.8/interfaces/AggregatorV3Interface.sol\";\n\nimport \"../../../BaseOracleChainlinkMultiTwoFeeds.sol\";\nimport \"../../../../interfaces/external/lido/IStETH.sol\";\n\n/// @title OracleWSTETHEURChainlink\n/// @author Angle Labs, Inc.\n/// @notice Gives the price of wSTETH in Euro in base 18\ncontract OracleWSTETHEURChainlink is BaseOracleChainlinkMultiTwoFeeds {\n string public constant DESCRIPTION = \"wSTETH/EUR Oracle\";\n IStETH public constant STETH = IStETH(0xae7ab96520DE3A18E5e111B5EaAb095312D7fE84);\n\n constructor(uint32 _stalePeriod, address _treasury) BaseOracleChainlinkMultiTwoFeeds(_stalePeriod, _treasury) {}\n\n /// @inheritdoc IOracle\n function circuitChainlink() public pure override returns (AggregatorV3Interface[] memory) {\n AggregatorV3Interface[] memory _circuitChainlink = new AggregatorV3Interface[](2);\n // Oracle stETH/USD\n _circuitChainlink[0] = AggregatorV3Interface(0xCfE54B5cD566aB89272946F602D76Ea879CAb4a8);\n // Oracle EUR/USD\n _circuitChainlink[1] = AggregatorV3Interface(0xb49f677943BC038e9857d61E7d053CaA2C1734C1);\n return _circuitChainlink;\n }\n\n /// @inheritdoc BaseOracleChainlinkMultiTwoFeeds\n function _getQuoteAmount() internal view override returns (uint256) {\n return STETH.getPooledEthByShares(1 ether);\n }\n}\n" + }, + "contracts/oracle/implementations/mainnet/USD/OracleWSTETHUSDChainlink.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\nimport \"@chainlink/contracts/src/v0.8/interfaces/AggregatorV3Interface.sol\";\n\nimport \"../../../BaseOracleChainlinkOneFeed.sol\";\nimport \"../../../../interfaces/external/lido/IStETH.sol\";\n\n/// @title OracleWSTETHUSDChainlink\n/// @author Angle Labs, Inc.\n/// @notice Gives the price of wSTETH in USD in base 18\ncontract OracleWSTETHUSDChainlink is BaseOracleChainlinkOneFeed {\n string public constant DESCRIPTION = \"wSTETH/USD Oracle\";\n IStETH public constant STETH = IStETH(0xae7ab96520DE3A18E5e111B5EaAb095312D7fE84);\n\n constructor(uint32 _stalePeriod, address _treasury) BaseOracleChainlinkOneFeed(_stalePeriod, _treasury) {}\n\n /// @inheritdoc IOracle\n function circuitChainlink() public pure override returns (AggregatorV3Interface[] memory) {\n AggregatorV3Interface[] memory _circuitChainlink = new AggregatorV3Interface[](1);\n // Oracle stETH/USD\n _circuitChainlink[0] = AggregatorV3Interface(0xCfE54B5cD566aB89272946F602D76Ea879CAb4a8);\n return _circuitChainlink;\n }\n\n /// @inheritdoc BaseOracleChainlinkOneFeed\n function _getQuoteAmount() internal view override returns (uint256) {\n return STETH.getPooledEthByShares(1 ether);\n }\n}\n" + }, + "contracts/oracle/implementations/mainnet/XAU/OracleETHXAUChainlink.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\nimport \"@chainlink/contracts/src/v0.8/interfaces/AggregatorV3Interface.sol\";\n\nimport \"../../../BaseOracleChainlinkMultiTwoFeeds.sol\";\n\n/// @title OracleETHXAUChainlink\n/// @author Angle Labs, Inc.\n/// @notice Gives the price of ETH in XAU in base 18\ncontract OracleETHXAUChainlink is BaseOracleChainlinkMultiTwoFeeds {\n string public constant DESCRIPTION = \"ETH/GOLD Oracle\";\n\n constructor(uint32 _stalePeriod, address _treasury) BaseOracleChainlinkMultiTwoFeeds(_stalePeriod, _treasury) {}\n\n /// @inheritdoc IOracle\n function circuitChainlink() public pure override returns (AggregatorV3Interface[] memory) {\n AggregatorV3Interface[] memory _circuitChainlink = new AggregatorV3Interface[](2);\n // Oracle ETH/USD\n _circuitChainlink[0] = AggregatorV3Interface(0x5f4eC3Df9cbd43714FE2740f5E3616155c5b8419);\n // Oracle XAU/USD\n _circuitChainlink[1] = AggregatorV3Interface(0x214eD9Da11D2fbe465a6fc601a91E62EbEc1a0D6);\n return _circuitChainlink;\n }\n}\n" + }, + "contracts/oracle/implementations/mainnet/XAU/OracleLUSDXAUChainlink.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\nimport \"@chainlink/contracts/src/v0.8/interfaces/AggregatorV3Interface.sol\";\n\nimport \"../../../BaseOracleChainlinkMultiTwoFeeds.sol\";\n\n/// @title OracleLUSDXAUChainlink\n/// @author Angle Labs, Inc.\n/// @notice Gives the price of LUSD in XAU in base 18\ncontract OracleLUSDXAUChainlink is BaseOracleChainlinkMultiTwoFeeds {\n string public constant DESCRIPTION = \"LUSD/GOLD Oracle\";\n\n constructor(uint32 _stalePeriod, address _treasury) BaseOracleChainlinkMultiTwoFeeds(_stalePeriod, _treasury) {}\n\n /// @inheritdoc IOracle\n function circuitChainlink() public pure override returns (AggregatorV3Interface[] memory) {\n AggregatorV3Interface[] memory _circuitChainlink = new AggregatorV3Interface[](2);\n // Oracle LUSD/USD\n _circuitChainlink[0] = AggregatorV3Interface(0x3D7aE7E594f2f2091Ad8798313450130d0Aba3a0);\n // Oracle XAU/USD\n _circuitChainlink[1] = AggregatorV3Interface(0x214eD9Da11D2fbe465a6fc601a91E62EbEc1a0D6);\n return _circuitChainlink;\n }\n}\n" + }, + "contracts/oracle/implementations/mainnet/XAU/OracleUSDCXAUChainlink.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\nimport \"@chainlink/contracts/src/v0.8/interfaces/AggregatorV3Interface.sol\";\n\nimport \"../../../BaseOracleChainlinkMultiTwoFeeds.sol\";\n\n/// @title OracleUSDCXAUChainlink\n/// @author Angle Labs, Inc.\n/// @notice Gives the price of USDC in XAU in base 18\ncontract OracleUSDCXAUChainlink is BaseOracleChainlinkMultiTwoFeeds {\n string public constant DESCRIPTION = \"USDC/GOLD Oracle\";\n\n constructor(uint32 _stalePeriod, address _treasury) BaseOracleChainlinkMultiTwoFeeds(_stalePeriod, _treasury) {}\n\n /// @inheritdoc IOracle\n function circuitChainlink() public pure override returns (AggregatorV3Interface[] memory) {\n AggregatorV3Interface[] memory _circuitChainlink = new AggregatorV3Interface[](2);\n // Oracle USDC/USD\n _circuitChainlink[0] = AggregatorV3Interface(0x8fFfFfd4AfB6115b954Bd326cbe7B4BA576818f6);\n // Oracle XAU/USD\n _circuitChainlink[1] = AggregatorV3Interface(0x214eD9Da11D2fbe465a6fc601a91E62EbEc1a0D6);\n return _circuitChainlink;\n }\n}\n" + }, + "contracts/oracle/implementations/mainnet/XAU/OracleWSTETHXAUChainlink.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\nimport \"@chainlink/contracts/src/v0.8/interfaces/AggregatorV3Interface.sol\";\n\nimport \"../../../BaseOracleChainlinkMultiTwoFeeds.sol\";\nimport \"../../../../interfaces/external/lido/IStETH.sol\";\n\n/// @title OracleWSTETHXAUChainlink\n/// @author Angle Labs, Inc.\n/// @notice Gives the price of wSTETH in XAU in base 18\ncontract OracleWSTETHXAUChainlink is BaseOracleChainlinkMultiTwoFeeds {\n string public constant DESCRIPTION = \"wSTETH/XAU Oracle\";\n IStETH public constant STETH = IStETH(0xae7ab96520DE3A18E5e111B5EaAb095312D7fE84);\n\n constructor(uint32 _stalePeriod, address _treasury) BaseOracleChainlinkMultiTwoFeeds(_stalePeriod, _treasury) {}\n\n /// @inheritdoc IOracle\n function circuitChainlink() public pure override returns (AggregatorV3Interface[] memory) {\n AggregatorV3Interface[] memory _circuitChainlink = new AggregatorV3Interface[](2);\n // Oracle stETH/USD\n _circuitChainlink[0] = AggregatorV3Interface(0xCfE54B5cD566aB89272946F602D76Ea879CAb4a8);\n // Oracle XAU/USD\n _circuitChainlink[1] = AggregatorV3Interface(0x214eD9Da11D2fbe465a6fc601a91E62EbEc1a0D6);\n return _circuitChainlink;\n }\n\n /// @inheritdoc BaseOracleChainlinkMultiTwoFeeds\n function _getQuoteAmount() internal view override returns (uint256) {\n return STETH.getPooledEthByShares(1 ether);\n }\n}\n" + }, + "contracts/oracle/implementations/optimism/EUR/OracleETHEURChainlinkOptimism.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\nimport \"@chainlink/contracts/src/v0.8/interfaces/AggregatorV3Interface.sol\";\n\nimport \"../../../BaseOracleChainlinkMultiTwoFeeds.sol\";\n\n/// @title OracleETHEURChainlinkOptimism\n/// @author Angle Labs, Inc.\n/// @notice Gives the price of ETH in Euro in base 18\n/// @dev This contract is built to be deployed on Optimism\ncontract OracleETHEURChainlinkOptimism is BaseOracleChainlinkMultiTwoFeeds {\n string public constant DESCRIPTION = \"ETH/EUR Oracle\";\n\n constructor(uint32 _stalePeriod, address _treasury) BaseOracleChainlinkMultiTwoFeeds(_stalePeriod, _treasury) {}\n\n /// @inheritdoc IOracle\n function circuitChainlink() public pure override returns (AggregatorV3Interface[] memory) {\n AggregatorV3Interface[] memory _circuitChainlink = new AggregatorV3Interface[](2);\n // Oracle ETH/USD\n _circuitChainlink[0] = AggregatorV3Interface(0x13e3Ee699D1909E989722E753853AE30b17e08c5);\n // Oracle EUR/USD\n _circuitChainlink[1] = AggregatorV3Interface(0x3626369857A10CcC6cc3A6e4f5C2f5984a519F20);\n return _circuitChainlink;\n }\n}\n" + }, + "contracts/oracle/implementations/optimism/EUR/OracleOPEURChainlinkOptimism.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\nimport \"@chainlink/contracts/src/v0.8/interfaces/AggregatorV3Interface.sol\";\n\nimport \"../../../BaseOracleChainlinkMultiTwoFeeds.sol\";\n\n/// @title OracleOPEURChainlinkOptimism\n/// @author Angle Labs, Inc.\n/// @notice Gives the price of OP in Euro in base 18\n/// @dev This contract is built to be deployed on Optimism\ncontract OracleOPEURChainlinkOptimism is BaseOracleChainlinkMultiTwoFeeds {\n string public constant DESCRIPTION = \"OP/EUR Oracle\";\n\n constructor(uint32 _stalePeriod, address _treasury) BaseOracleChainlinkMultiTwoFeeds(_stalePeriod, _treasury) {}\n\n /// @inheritdoc IOracle\n function circuitChainlink() public pure override returns (AggregatorV3Interface[] memory) {\n AggregatorV3Interface[] memory _circuitChainlink = new AggregatorV3Interface[](2);\n // Oracle OP/USD\n _circuitChainlink[0] = AggregatorV3Interface(0x0D276FC14719f9292D5C1eA2198673d1f4269246);\n // Oracle EUR/USD\n _circuitChainlink[1] = AggregatorV3Interface(0x3626369857A10CcC6cc3A6e4f5C2f5984a519F20);\n return _circuitChainlink;\n }\n}\n" + }, + "contracts/oracle/implementations/optimism/EUR/OracleUSDCEURChainlinkOptimism.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\nimport \"@chainlink/contracts/src/v0.8/interfaces/AggregatorV3Interface.sol\";\n\nimport \"../../../BaseOracleChainlinkMultiTwoFeeds.sol\";\n\n/// @title OracleUSDCEURChainlinkOptimism\n/// @author Angle Labs, Inc.\n/// @notice Gives the price of USDC in Euro in base 18\n/// @dev This contract is built to be deployed on Optimism\ncontract OracleUSDCEURChainlinkOptimism is BaseOracleChainlinkMultiTwoFeeds {\n string public constant DESCRIPTION = \"USDC/EUR Oracle\";\n\n constructor(uint32 _stalePeriod, address _treasury) BaseOracleChainlinkMultiTwoFeeds(_stalePeriod, _treasury) {}\n\n /// @inheritdoc IOracle\n function circuitChainlink() public pure override returns (AggregatorV3Interface[] memory) {\n AggregatorV3Interface[] memory _circuitChainlink = new AggregatorV3Interface[](2);\n // Oracle USDC/USD\n _circuitChainlink[0] = AggregatorV3Interface(0x16a9FA2FDa030272Ce99B29CF780dFA30361E0f3);\n // Oracle EUR/USD\n _circuitChainlink[1] = AggregatorV3Interface(0x3626369857A10CcC6cc3A6e4f5C2f5984a519F20);\n return _circuitChainlink;\n }\n}\n" + }, + "contracts/oracle/implementations/polygon/EUR/OracleBTCEURChainlinkPolygon.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\nimport \"@chainlink/contracts/src/v0.8/interfaces/AggregatorV3Interface.sol\";\n\nimport \"../../../BaseOracleChainlinkMultiTwoFeeds.sol\";\n\n/// @title OracleBTCEURChainlinkPolygon\n/// @author Angle Labs, Inc.\n/// @notice Gives the price of BTC in Euro in base 18\n/// @dev This contract is built to be deployed on Polygon\ncontract OracleBTCEURChainlinkPolygon is BaseOracleChainlinkMultiTwoFeeds {\n string public constant DESCRIPTION = \"BTC/EUR Oracle\";\n\n constructor(uint32 _stalePeriod, address _treasury) BaseOracleChainlinkMultiTwoFeeds(_stalePeriod, _treasury) {}\n\n /// @inheritdoc IOracle\n function circuitChainlink() public pure override returns (AggregatorV3Interface[] memory) {\n AggregatorV3Interface[] memory _circuitChainlink = new AggregatorV3Interface[](2);\n // Oracle BTC/USD\n _circuitChainlink[0] = AggregatorV3Interface(0xc907E116054Ad103354f2D350FD2514433D57F6f);\n // Oracle EUR/USD\n _circuitChainlink[1] = AggregatorV3Interface(0x73366Fe0AA0Ded304479862808e02506FE556a98);\n return _circuitChainlink;\n }\n}\n" + }, + "contracts/oracle/implementations/polygon/EUR/OracleETHEURChainlinkPolygon.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\nimport \"@chainlink/contracts/src/v0.8/interfaces/AggregatorV3Interface.sol\";\n\nimport \"../../../BaseOracleChainlinkMultiTwoFeeds.sol\";\n\n/// @title OracleETHEURChainlinkPolygon\n/// @author Angle Labs, Inc.\n/// @notice Gives the price of ETH in Euro in base 18\n/// @dev This contract is built to be deployed on Polygon\ncontract OracleETHEURChainlinkPolygon is BaseOracleChainlinkMultiTwoFeeds {\n string public constant DESCRIPTION = \"ETH/EUR Oracle\";\n\n constructor(uint32 _stalePeriod, address _treasury) BaseOracleChainlinkMultiTwoFeeds(_stalePeriod, _treasury) {}\n\n /// @inheritdoc IOracle\n function circuitChainlink() public pure override returns (AggregatorV3Interface[] memory) {\n AggregatorV3Interface[] memory _circuitChainlink = new AggregatorV3Interface[](2);\n // Oracle ETH/USD\n _circuitChainlink[0] = AggregatorV3Interface(0xF9680D99D6C9589e2a93a78A04A279e509205945);\n // Oracle EUR/USD\n _circuitChainlink[1] = AggregatorV3Interface(0x73366Fe0AA0Ded304479862808e02506FE556a98);\n return _circuitChainlink;\n }\n}\n" + }, + "contracts/oracle/implementations/polygon/EUR/OracleMAIEURChainlinkPolygon.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\nimport \"@chainlink/contracts/src/v0.8/interfaces/AggregatorV3Interface.sol\";\n\nimport \"../../../BaseOracleChainlinkMultiTwoFeeds.sol\";\n\n/// @title OracleMAIEURChainlinkPolygon\n/// @author Angle Labs, Inc.\n/// @notice Gives the price of MAI in Euro in base 18\n/// @dev This contract is built to be deployed on Polygon\ncontract OracleMAIEURChainlinkPolygon is BaseOracleChainlinkMultiTwoFeeds {\n string public constant DESCRIPTION = \"MAI/EUR Oracle\";\n\n constructor(uint32 _stalePeriod, address _treasury) BaseOracleChainlinkMultiTwoFeeds(_stalePeriod, _treasury) {}\n\n /// @inheritdoc IOracle\n function circuitChainlink() public pure override returns (AggregatorV3Interface[] memory) {\n AggregatorV3Interface[] memory _circuitChainlink = new AggregatorV3Interface[](2);\n // Oracle MAI/USD\n _circuitChainlink[0] = AggregatorV3Interface(0xd8d483d813547CfB624b8Dc33a00F2fcbCd2D428);\n // Oracle EUR/USD\n _circuitChainlink[1] = AggregatorV3Interface(0x73366Fe0AA0Ded304479862808e02506FE556a98);\n return _circuitChainlink;\n }\n}\n" + }, + "contracts/oracle/implementations/polygon/EUR/OracleMATICEURChainlinkPolygon.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\nimport \"@chainlink/contracts/src/v0.8/interfaces/AggregatorV3Interface.sol\";\n\nimport \"../../../BaseOracleChainlinkMultiTwoFeeds.sol\";\n\n/// @title OracleMATICEURChainlinkPolygon\n/// @author Angle Labs, Inc.\n/// @notice Gives the price of MATIC in Euro in base 18\n/// @dev This contract is built to be deployed on Polygon\ncontract OracleMATICEURChainlinkPolygon is BaseOracleChainlinkMultiTwoFeeds {\n string public constant DESCRIPTION = \"MATIC/EUR Oracle\";\n\n constructor(uint32 _stalePeriod, address _treasury) BaseOracleChainlinkMultiTwoFeeds(_stalePeriod, _treasury) {}\n\n /// @inheritdoc IOracle\n function circuitChainlink() public pure override returns (AggregatorV3Interface[] memory) {\n AggregatorV3Interface[] memory _circuitChainlink = new AggregatorV3Interface[](2);\n // Oracle MATIC/USD\n _circuitChainlink[0] = AggregatorV3Interface(0xAB594600376Ec9fD91F8e885dADF0CE036862dE0);\n // Oracle EUR/USD\n _circuitChainlink[1] = AggregatorV3Interface(0x73366Fe0AA0Ded304479862808e02506FE556a98);\n return _circuitChainlink;\n }\n}\n" + }, + "contracts/oracle/implementations/polygon/EUR/OracleUSDCEURChainlinkPolygon.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\nimport \"../../../BaseOracleChainlinkMultiTwoFeeds.sol\";\n\n/// @title OracleUSDCEURChainlinkPolygon\n/// @author Angle Labs, Inc.\n/// @notice Gives the price of USDC in Euro in base 18\n/// @dev This contract is built to be deployed on Polygon\ncontract OracleUSDCEURChainlinkPolygon is BaseOracleChainlinkMultiTwoFeeds {\n string public constant DESCRIPTION = \"USDC/EUR Oracle\";\n\n constructor(uint32 _stalePeriod, address _treasury) BaseOracleChainlinkMultiTwoFeeds(_stalePeriod, _treasury) {}\n\n /// @inheritdoc IOracle\n function circuitChainlink() public pure override returns (AggregatorV3Interface[] memory) {\n AggregatorV3Interface[] memory _circuitChainlink = new AggregatorV3Interface[](2);\n // Oracle USDC/USD\n _circuitChainlink[0] = AggregatorV3Interface(0xfE4A8cc5b5B2366C1B58Bea3858e81843581b2F7);\n // Oracle EUR/USD\n _circuitChainlink[1] = AggregatorV3Interface(0x73366Fe0AA0Ded304479862808e02506FE556a98);\n return _circuitChainlink;\n }\n}\n" + }, + "contracts/oracle/implementations/polygon/XAU/OracleETHXAUChainlinkPolygon.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\nimport \"@chainlink/contracts/src/v0.8/interfaces/AggregatorV3Interface.sol\";\n\nimport \"../../../BaseOracleChainlinkMultiTwoFeeds.sol\";\n\n/// @title OracleETHXAUChainlinkPolygon\n/// @author Angle Labs, Inc.\n/// @notice Gives the price of ETH in XAU in base 18\n/// @dev This contract is built to be deployed on Polygon\ncontract OracleETHXAUChainlinkPolygon is BaseOracleChainlinkMultiTwoFeeds {\n string public constant DESCRIPTION = \"ETH/GOLD Oracle\";\n\n constructor(uint32 _stalePeriod, address _treasury) BaseOracleChainlinkMultiTwoFeeds(_stalePeriod, _treasury) {}\n\n /// @inheritdoc IOracle\n function circuitChainlink() public pure override returns (AggregatorV3Interface[] memory) {\n AggregatorV3Interface[] memory _circuitChainlink = new AggregatorV3Interface[](2);\n // Oracle ETH/USD\n _circuitChainlink[0] = AggregatorV3Interface(0xF9680D99D6C9589e2a93a78A04A279e509205945);\n // Oracle XAU/USD\n _circuitChainlink[1] = AggregatorV3Interface(0x0C466540B2ee1a31b441671eac0ca886e051E410);\n return _circuitChainlink;\n }\n}\n" + }, + "contracts/oracle/KeeperRegistry.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\nimport \"@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol\";\nimport \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\nimport \"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\";\n\nimport \"../interfaces/ICoreBorrow.sol\";\nimport \"../interfaces/IKeeperRegistry.sol\";\n\n/// @title KeeperRegistry\n/// @notice Maintains a mapping of keepers authorized to use the core module just after oracle updates\n/// @author Angle Labs, Inc.\ncontract KeeperRegistry is Initializable, IKeeperRegistry {\n using SafeERC20 for IERC20;\n\n /// @notice Contract handling access control\n ICoreBorrow public coreBorrow;\n\n /// @notice Trusted EOAs - needs to be tx.origin\n mapping(address => uint256) public trusted;\n\n uint256[48] private __gap;\n\n // =================================== EVENTS ==================================\n\n event TrustedToggled(address indexed wallet, bool trust);\n\n // =================================== ERRORS ==================================\n\n error NotGovernorOrGuardian();\n error NotTrusted();\n error ZeroAddress();\n\n // ================================= MODIFIERS =================================\n\n /// @notice Checks whether the `msg.sender` has the governor role or the guardian role\n modifier onlyGovernorOrGuardian() {\n if (!coreBorrow.isGovernorOrGuardian(msg.sender)) revert NotGovernorOrGuardian();\n _;\n }\n\n // ================================ CONSTRUCTOR ================================\n\n constructor() initializer {}\n\n function initialize(ICoreBorrow _coreBorrow) public initializer {\n if (address(_coreBorrow) == address(0)) revert ZeroAddress();\n coreBorrow = _coreBorrow;\n }\n\n // =============================== MAIN FUNCTIONS ==============================\n\n /// @notice Adds or removes a trusted keeper bot\n function toggleTrusted(address eoa) external onlyGovernorOrGuardian {\n uint256 trustedStatus = 1 - trusted[eoa];\n trusted[eoa] = trustedStatus;\n emit TrustedToggled(eoa, trustedStatus == 1);\n }\n\n /// @inheritdoc IKeeperRegistry\n function isTrusted(address caller) external view returns (bool) {\n return trusted[caller] == 1;\n }\n}\n" + }, + "contracts/oracle/OracleChainlinkMulti.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\nimport \"@chainlink/contracts/src/v0.8/interfaces/AggregatorV3Interface.sol\";\n\nimport \"./BaseOracleChainlinkMulti.sol\";\n\n/// @title OracleChainlinkMulti\n/// @author Angle Labs, Inc.\n/// @notice Oracle contract, one contract is deployed per collateral/stablecoin pair\n/// @dev This contract concerns an oracle that uses Chainlink with multiple pools to read from\n/// @dev Typically we expect to use this contract to read like the ETH/USD and then USD/EUR feed\ncontract OracleChainlinkMulti is BaseOracleChainlinkMulti {\n // ========================= Parameters and References =========================\n\n /// @notice Chainlink pools, the order of the pools has to be the order in which they are read for the computation\n /// of the price\n AggregatorV3Interface[] internal _circuitChainlink;\n /// @notice Whether each rate for the pairs in `circuitChainlink` should be multiplied or divided\n uint8[] public circuitChainIsMultiplied;\n /// @notice Decimals for each Chainlink pairs\n uint8[] public chainlinkDecimals;\n /// @notice Unit of the stablecoin\n uint256 public immutable outBase;\n /// @notice Description of the assets concerned by the oracle and the price outputted\n string public description;\n\n // ===================================== Error =================================\n\n error IncompatibleLengths();\n\n /// @notice Constructor for an oracle using Chainlink with multiple pools to read from\n /// @param circuitChainlink_ Chainlink pool addresses (in order)\n /// @param _circuitChainIsMultiplied Whether we should multiply or divide by this rate\n /// @param _outBase Unit of the stablecoin (or the out asset) associated to the oracle\n /// @param _stalePeriod Minimum feed update frequency for the oracle to not revert\n /// @param _treasury Treasury associated to the VaultManager which reads from this feed\n /// @param _description Description of the assets concerned by the oracle\n /// @dev For instance, if this oracle is supposed to give the price of ETH in EUR, and if the agEUR\n /// stablecoin associated to EUR has 18 decimals, then `outBase` should be 10**18\n constructor(\n address[] memory circuitChainlink_,\n uint8[] memory _circuitChainIsMultiplied,\n uint256 _outBase,\n uint32 _stalePeriod,\n address _treasury,\n string memory _description\n ) BaseOracleChainlinkMulti(_stalePeriod, _treasury) {\n outBase = _outBase;\n description = _description;\n uint256 circuitLength = circuitChainlink_.length;\n if (circuitLength == 0 || circuitLength != _circuitChainIsMultiplied.length) revert IncompatibleLengths();\n for (uint256 i; i < circuitLength; ++i) {\n AggregatorV3Interface _pool = AggregatorV3Interface(circuitChainlink_[i]);\n _circuitChainlink.push(_pool);\n chainlinkDecimals.push(_pool.decimals());\n }\n circuitChainIsMultiplied = _circuitChainIsMultiplied;\n }\n\n // ============================= Reading Oracles ===============================\n\n /// @inheritdoc IOracle\n function circuitChainlink() public view override returns (AggregatorV3Interface[] memory) {\n return _circuitChainlink;\n }\n\n /// @inheritdoc IOracle\n function read() external view override returns (uint256 quoteAmount) {\n quoteAmount = outBase;\n uint256 circuitLength = _circuitChainlink.length;\n for (uint256 i; i < circuitLength; ++i) {\n quoteAmount = _readChainlinkFeed(\n quoteAmount,\n _circuitChainlink[i],\n circuitChainIsMultiplied[i],\n chainlinkDecimals[i]\n );\n }\n }\n}\n" + }, + "contracts/settlement/Settlement.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\nimport \"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\";\nimport \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\nimport \"@openzeppelin/contracts/token/ERC20/extensions/IERC20Metadata.sol\";\n\nimport \"../interfaces/IAgToken.sol\";\nimport \"../interfaces/ISwapper.sol\";\nimport \"../interfaces/IVaultManager.sol\";\n\n/// @title Settlement\n/// @author Angle Labs, Inc.\n/// @notice Settlement Contract for a VaultManager\n/// @dev This settlement contract should be activated by a careful governance which needs to have performed\n/// some key operations before activating this contract\n/// @dev In case of global settlement, there should be one settlement contract per `VaultManager`\ncontract Settlement {\n using SafeERC20 for IERC20;\n\n /// @notice Base used for parameter computation\n uint256 public constant BASE_PARAMS = 10 ** 9;\n /// @notice Base used for interest computation\n uint256 public constant BASE_INTEREST = 10 ** 27;\n /// @notice Base used for exchange rate computation. It is assumed\n /// that stablecoins have this base\n uint256 public constant BASE_STABLECOIN = 10 ** 18;\n /// @notice Duration of the claim period for over-collateralized vaults\n uint256 public constant OVER_COLLATERALIZED_CLAIM_DURATION = 3 * 24 * 3600;\n\n // =============== Immutable references set in the constructor =================\n\n /// @notice `VaultManager` of this settlement contract\n IVaultManager public immutable vaultManager;\n /// @notice Reference to the stablecoin supported by the `VaultManager` contract\n IAgToken public immutable stablecoin;\n /// @notice Reference to the collateral supported by the `VaultManager`\n IERC20 public immutable collateral;\n /// @notice Base of the collateral\n uint256 internal immutable _collatBase;\n\n // ================ Variables frozen at settlement activation ==================\n\n /// @notice Value of the oracle for the collateral/stablecoin pair\n uint256 public oracleValue;\n /// @notice Value of the interest accumulator at settlement activation\n uint256 public interestAccumulator;\n /// @notice Timestamp at which settlement was activated\n uint256 public activationTimestamp;\n /// @notice Collateral factor of the `VaultManager`\n uint64 public collateralFactor;\n\n // =================== Variables updated during the process ====================\n\n /// @notice How much collateral you can get from stablecoins\n uint256 public collateralStablecoinExchangeRate;\n /// @notice Amount of collateral that will be left over at the end of the process\n uint256 public leftOverCollateral;\n /// @notice Whether the `collateralStablecoinExchangeRate` has been computed\n bool public exchangeRateComputed;\n /// @notice Maps a vault to 1 if it was claimed by its owner\n mapping(uint256 => uint256) public vaultCheck;\n\n // ================================ Events =====================================\n\n event GlobalClaimPeriodActivated(uint256 _collateralStablecoinExchangeRate);\n event Recovered(address indexed tokenAddress, address indexed to, uint256 amount);\n event SettlementActivated(uint256 startTimestamp);\n event VaultClaimed(uint256 vaultID, uint256 stablecoinAmount, uint256 collateralAmount);\n\n // ================================ Errors =====================================\n\n error GlobalClaimPeriodNotStarted();\n error InsolventVault();\n error NotGovernor();\n error NotOwner();\n error RestrictedClaimPeriodNotEnded();\n error SettlementNotInitialized();\n error VaultAlreadyClaimed();\n\n /// @notice Constructor of the contract\n /// @param _vaultManager Address of the `VaultManager` associated to this `Settlement` contract\n /// @dev Out of safety, this constructor reads values from the `VaultManager` contract directly\n constructor(IVaultManager _vaultManager) {\n vaultManager = _vaultManager;\n stablecoin = _vaultManager.stablecoin();\n collateral = _vaultManager.collateral();\n _collatBase = 10 ** (IERC20Metadata(address(collateral)).decimals());\n }\n\n /// @notice Checks whether the `msg.sender` has the governor role or not\n modifier onlyGovernor() {\n if (!(vaultManager.treasury().isGovernor(msg.sender))) revert NotGovernor();\n _;\n }\n\n /// @notice Activates the settlement contract\n /// @dev When calling this function governance should make sure to have:\n /// 1. Accrued the interest rate on the contract\n /// 2. Paused the contract\n /// 3. Recovered all the collateral available in the `VaultManager` contract either\n /// by doing a contract upgrade or by calling a `recoverERC20` method if supported\n function activateSettlement() external onlyGovernor {\n oracleValue = (vaultManager.oracle()).read();\n interestAccumulator = vaultManager.interestAccumulator();\n activationTimestamp = block.timestamp;\n collateralFactor = vaultManager.collateralFactor();\n emit SettlementActivated(block.timestamp);\n }\n\n /// @notice Allows the owner of an over-collateralized vault to claim its collateral upon bringing back all owed stablecoins\n /// @param vaultID ID of the vault to claim\n /// @param to Address to which collateral should be sent\n /// @param who Address which should be notified if needed of the transfer of stablecoins and collateral\n /// @param data Data to pass to the `who` contract for it to successfully give the correct amount of stablecoins\n /// to the `msg.sender` address\n /// @return Amount of collateral sent to the `to` address\n /// @return Amount of stablecoins sent to the contract\n /// @dev Claiming can only happen short after settlement activation\n /// @dev A vault cannot be claimed twice and only the owner of the vault can claim it (regardless of the approval logic)\n /// @dev Only over-collateralized vaults can be claimed from this medium\n function claimOverCollateralizedVault(\n uint256 vaultID,\n address to,\n address who,\n bytes memory data\n ) external returns (uint256, uint256) {\n if (activationTimestamp == 0 || block.timestamp > activationTimestamp + OVER_COLLATERALIZED_CLAIM_DURATION)\n revert SettlementNotInitialized();\n if (vaultCheck[vaultID] == 1) revert VaultAlreadyClaimed();\n if (vaultManager.ownerOf(vaultID) != msg.sender) revert NotOwner();\n (uint256 collateralAmount, uint256 normalizedDebt) = vaultManager.vaultData(vaultID);\n uint256 vaultDebt = (normalizedDebt * interestAccumulator) / BASE_INTEREST;\n if (collateralAmount * oracleValue * collateralFactor < vaultDebt * BASE_PARAMS * _collatBase)\n revert InsolventVault();\n vaultCheck[vaultID] = 1;\n emit VaultClaimed(vaultID, vaultDebt, collateralAmount);\n return _handleRepay(collateralAmount, vaultDebt, to, who, data);\n }\n\n /// @notice Activates the global claim period by setting the `collateralStablecoinExchangeRate` which is going to\n /// dictate how much of collateral will be recoverable for each stablecoin\n /// @dev This function can only be called by the governor in order to allow it in case multiple settlements happen across\n /// different `VaultManager` to rebalance the amount of stablecoins on each to make sure that across all settlement contracts\n /// a similar value of collateral can be obtained against a similar value of stablecoins\n function activateGlobalClaimPeriod() external onlyGovernor {\n if (activationTimestamp == 0 || block.timestamp <= activationTimestamp + OVER_COLLATERALIZED_CLAIM_DURATION)\n revert RestrictedClaimPeriodNotEnded();\n uint256 collateralBalance = collateral.balanceOf(address(this));\n uint256 leftOverDebt = (vaultManager.totalNormalizedDebt() * interestAccumulator) / BASE_INTEREST;\n uint256 stablecoinBalance = stablecoin.balanceOf(address(this));\n // How much 1 of stablecoin will give you in collateral\n uint256 _collateralStablecoinExchangeRate;\n\n if (stablecoinBalance < leftOverDebt) {\n // The left over debt is the total debt minus the stablecoins which have already been accumulated\n // in the first phase\n leftOverDebt -= stablecoinBalance;\n // If you control all the debt, then you are entitled to get all the collateral left in the protocol\n _collateralStablecoinExchangeRate = (collateralBalance * BASE_STABLECOIN) / leftOverDebt;\n // But at the same time, you cannot get more collateral than the value of the stablecoins you brought\n uint256 maxExchangeRate = (BASE_STABLECOIN * _collatBase) / oracleValue;\n if (_collateralStablecoinExchangeRate >= maxExchangeRate) {\n // In this situation, we're sure that `leftOverCollateral` will be positive: governance should be wary\n // to call `recoverERC20` short after though as there's nothing that is going to prevent people to redeem\n // more stablecoins than the `leftOverDebt`\n leftOverCollateral = collateralBalance - (leftOverDebt * _collatBase) / oracleValue;\n _collateralStablecoinExchangeRate = maxExchangeRate;\n }\n }\n exchangeRateComputed = true;\n // In the else case where there is no debt left, you cannot get anything from your stablecoins\n // and so the `collateralStablecoinExchangeRate` is null\n collateralStablecoinExchangeRate = _collateralStablecoinExchangeRate;\n emit GlobalClaimPeriodActivated(_collateralStablecoinExchangeRate);\n }\n\n /// @notice Allows to claim collateral from stablecoins\n /// @param to Address to which collateral should be sent\n /// @param who Address which should be notified if needed of the transfer of stablecoins and collateral\n /// @param data Data to pass to the `who` contract for it to successfully give the correct amount of stablecoins\n /// to the `msg.sender` address\n /// @return Amount of collateral sent to the `to` address\n /// @return Amount of stablecoins sent to the contract\n /// @dev This function reverts if the `collateralStablecoinExchangeRate` is null and hence if the global claim period has\n /// not been activated\n function claimCollateralFromStablecoins(\n uint256 stablecoinAmount,\n address to,\n address who,\n bytes memory data\n ) external returns (uint256, uint256) {\n if (!exchangeRateComputed) revert GlobalClaimPeriodNotStarted();\n return\n _handleRepay(\n (stablecoinAmount * collateralStablecoinExchangeRate) / BASE_STABLECOIN,\n stablecoinAmount,\n to,\n who,\n data\n );\n }\n\n /// @notice Handles the simultaneous repayment of stablecoins with a transfer of collateral\n /// @param collateralAmountToGive Amount of collateral the contract should give\n /// @param stableAmountToRepay Amount of stablecoins the contract should burn from the call\n /// @param to Address to which stablecoins should be sent\n /// @param who Address which should be notified if needed of the transfer\n /// @param data Data to pass to the `who` contract for it to successfully give the correct amount of stablecoins\n /// to the `msg.sender` address\n /// @dev This function allows for capital-efficient claims of collateral from stablecoins\n function _handleRepay(\n uint256 collateralAmountToGive,\n uint256 stableAmountToRepay,\n address to,\n address who,\n bytes memory data\n ) internal returns (uint256, uint256) {\n collateral.safeTransfer(to, collateralAmountToGive);\n if (data.length != 0) {\n ISwapper(who).swap(\n collateral,\n IERC20(address(stablecoin)),\n msg.sender,\n stableAmountToRepay,\n collateralAmountToGive,\n data\n );\n }\n stablecoin.transferFrom(msg.sender, address(this), stableAmountToRepay);\n return (collateralAmountToGive, stableAmountToRepay);\n }\n\n /// @notice Recovers leftover tokens from the contract or tokens that were mistakenly sent to the contract\n /// @param tokenAddress Address of the token to recover\n /// @param to Address to send the remaining tokens to\n /// @param amountToRecover Amount to recover from the contract\n /// @dev Governors cannot recover more collateral than what would be leftover from the contract\n /// @dev This function can be used to rebalance stablecoin balances across different settlement contracts\n /// to make sure every stablecoin can be redeemed for the same value of collateral\n /// @dev It can also be used to recover tokens that are mistakenly sent to this contract\n function recoverERC20(address tokenAddress, address to, uint256 amountToRecover) external onlyGovernor {\n if (tokenAddress == address(collateral)) {\n if (!exchangeRateComputed) revert GlobalClaimPeriodNotStarted();\n leftOverCollateral -= amountToRecover;\n collateral.safeTransfer(to, amountToRecover);\n } else {\n IERC20(tokenAddress).safeTransfer(to, amountToRecover);\n }\n emit Recovered(tokenAddress, to, amountToRecover);\n }\n}\n" + }, + "contracts/swapper/Swapper.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\n/*\n * █ \n ***** ▓▓▓ \n * ▓▓▓▓▓▓▓ \n * ///. ▓▓▓▓▓▓▓▓▓▓▓▓▓ \n ***** //////// ▓▓▓▓▓▓▓ \n * ///////////// ▓▓▓ \n ▓▓ ////////////////// █ ▓▓ \n ▓▓ ▓▓ /////////////////////// ▓▓ ▓▓ \n ▓▓ ▓▓ //////////////////////////// ▓▓ ▓▓ \n ▓▓ ▓▓ /////////▓▓▓///////▓▓▓///////// ▓▓ ▓▓ \n ▓▓ ,////////////////////////////////////// ▓▓ ▓▓ \n ▓▓ ////////////////////////////////////////// ▓▓ \n ▓▓ //////////////////////▓▓▓▓///////////////////// \n ,//////////////////////////////////////////////////// \n .////////////////////////////////////////////////////////// \n .//////////////////////////██.,//////////////////////////█ \n .//////////////////////████..,./////////////////////██ \n ...////////////////███████.....,.////////////////███ \n ,.,////////////████████ ........,///////////████ \n .,.,//////█████████ ,.......///////████ \n ,..//████████ ........./████ \n ..,██████ .....,███ \n .██ ,.,█ \n \n \n \n ▓▓ ▓▓▓▓▓▓▓▓▓▓ ▓▓▓▓▓▓▓▓▓▓ ▓▓ ▓▓▓▓▓▓▓▓▓▓ \n ▓▓▓▓▓▓ ▓▓▓ ▓▓▓ ▓▓▓ ▓▓ ▓▓ ▓▓▓▓ \n ▓▓▓ ▓▓▓ ▓▓▓ ▓▓▓ ▓▓▓ ▓▓▓ ▓▓ ▓▓▓▓▓ \n ▓▓▓ ▓▓ ▓▓▓ ▓▓▓ ▓▓▓▓▓▓▓▓▓▓ ▓▓▓▓▓▓▓▓▓▓ ▓▓▓▓▓▓▓▓▓▓ \n*/\n\npragma solidity ^0.8.12;\n\nimport \"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\";\nimport \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\n\nimport \"../interfaces/IAngleRouterSidechain.sol\";\nimport \"../interfaces/ICoreBorrow.sol\";\nimport \"../interfaces/ISwapper.sol\";\nimport \"../interfaces/external/lido/IWStETH.sol\";\nimport \"../interfaces/external/uniswap/IUniswapRouter.sol\";\n\n// ==================================== ENUM ===================================\n\n/// @notice All possible swaps\nenum SwapType {\n UniswapV3,\n oneInch,\n AngleRouter,\n Leverage,\n None\n}\n\n/// @title Swapper\n/// @author Angle Labs, Inc.\n/// @notice Swapper contract facilitating interactions with Angle VaultManager contracts, notably\n/// liquidation and leverage transactions\ncontract Swapper is ISwapper {\n using SafeERC20 for IERC20;\n\n // ===================== CONSTANTS AND IMMUTABLE VARIABLES =====================\n\n /// @notice Reference to the `CoreBorrow` contract of the module which handles all AccessControl logic\n ICoreBorrow public immutable core;\n /// @notice Uniswap Router contract\n IUniswapV3Router public immutable uniV3Router;\n /// @notice 1inch Router\n address public immutable oneInch;\n /// @notice AngleRouter\n IAngleRouterSidechain public immutable angleRouter;\n\n // =================================== ERRORS ==================================\n\n error EmptyReturnMessage();\n error IncompatibleLengths();\n error NotGovernorOrGuardian();\n error TooSmallAmountOut();\n error ZeroAddress();\n\n /// @notice Constructor of the contract\n /// @param _core Core address\n /// @param _uniV3Router UniswapV3 Router address\n /// @param _oneInch 1inch Router address\n /// @param _angleRouter AngleRouter contract address\n constructor(\n ICoreBorrow _core,\n IUniswapV3Router _uniV3Router,\n address _oneInch,\n IAngleRouterSidechain _angleRouter\n ) {\n if (address(_core) == address(0) || _oneInch == address(0) || address(_angleRouter) == address(0))\n revert ZeroAddress();\n core = _core;\n uniV3Router = _uniV3Router;\n oneInch = _oneInch;\n angleRouter = _angleRouter;\n }\n\n // ========================= EXTERNAL ACCESS FUNCTIONS =========================\n\n /// @inheritdoc ISwapper\n /// @dev This function swaps the `inToken` to the `outToken` by doing a UniV3 swap, a 1inch swap or by interacting\n /// with the `AngleRouter` contract\n /// @dev One slippage check is performed at the end of the call\n /// @dev In this implementation, the function tries to make sure that the `outTokenRecipient` address has at the end\n /// of the call `outTokenOwed`, leftover tokens are sent to a `to` address which by default is the `outTokenRecipient`\n function swap(\n IERC20 inToken,\n IERC20 outToken,\n address outTokenRecipient,\n uint256 outTokenOwed,\n uint256 inTokenObtained,\n bytes memory data\n ) external {\n // Address to receive the surplus amount of token at the end of the call\n address to;\n // For slippage protection, it is checked at the end of the call\n uint256 minAmountOut;\n // Type of the swap to execute: if `swapType == 4`, then it is optional to swap\n uint256 swapType;\n // We're reusing the `data` variable (it can be `path` on UniswapV3, a payload for 1inch or like encoded actions\n // for a router call)\n (to, minAmountOut, swapType, data) = abi.decode(data, (address, uint256, uint256, bytes));\n\n to = (to == address(0)) ? outTokenRecipient : to;\n\n _swap(inToken, inTokenObtained, SwapType(swapType), data);\n\n // A final slippage check is performed after the swaps\n uint256 outTokenBalance = outToken.balanceOf(address(this));\n if (outTokenBalance < minAmountOut) revert TooSmallAmountOut();\n\n // The `outTokenRecipient` may already have enough in balance, in which case there's no need to transfer\n // to this address the token and everything can be given to the `to` address\n uint256 outTokenBalanceRecipient = outToken.balanceOf(outTokenRecipient);\n if (outTokenBalanceRecipient >= outTokenOwed || to == outTokenRecipient)\n outToken.safeTransfer(to, outTokenBalance);\n else {\n // The `outTokenRecipient` should receive the delta to make sure its end balance is equal to `outTokenOwed`\n // Any leftover in this case is sent to the `to` address\n // The function reverts if it did not obtain more than `outTokenOwed - outTokenBalanceRecipient` from the swap\n outToken.safeTransfer(outTokenRecipient, outTokenOwed - outTokenBalanceRecipient);\n outToken.safeTransfer(to, outTokenBalanceRecipient + outTokenBalance - outTokenOwed);\n }\n // Reusing the `inTokenObtained` variable for the `inToken` balance\n // Sending back the remaining amount of inTokens to the `to` address: it is possible that not the full `inTokenObtained`\n // is swapped to `outToken` if we're using the `1inch` payload\n inTokenObtained = inToken.balanceOf(address(this));\n if (inTokenObtained != 0) inToken.safeTransfer(to, inTokenObtained);\n }\n\n // ============================ GOVERNANCE FUNCTION ============================\n\n /// @notice Changes allowances of this contract for different tokens\n /// @param tokens Addresses of the tokens to allow\n /// @param spenders Addresses to allow transfer\n /// @param amounts Amounts to allow\n function changeAllowance(\n IERC20[] calldata tokens,\n address[] calldata spenders,\n uint256[] calldata amounts\n ) external {\n if (!core.isGovernorOrGuardian(msg.sender)) revert NotGovernorOrGuardian();\n uint256 tokensLength = tokens.length;\n if (tokensLength != spenders.length || tokensLength != amounts.length) revert IncompatibleLengths();\n for (uint256 i; i < tokensLength; ++i) {\n _changeAllowance(tokens[i], spenders[i], amounts[i]);\n }\n }\n\n // ========================= INTERNAL UTILITY FUNCTIONS ========================\n\n /// @notice Internal version of the `_changeAllowance` function\n function _changeAllowance(IERC20 token, address spender, uint256 amount) internal {\n uint256 currentAllowance = token.allowance(address(this), spender);\n // In case `currentAllowance < type(uint256).max / 2` and we want to increase it:\n // Do nothing (to handle tokens that need reapprovals to 0 and save gas)\n if (currentAllowance < amount && currentAllowance < type(uint256).max / 2) {\n token.safeIncreaseAllowance(spender, amount - currentAllowance);\n } else if (currentAllowance > amount) {\n token.safeDecreaseAllowance(spender, currentAllowance - amount);\n }\n }\n\n /// @notice Checks the allowance for a contract and updates it to the max if it is not big enough\n /// @param token Token for which allowance should be checked\n /// @param spender Address to grant allowance to\n /// @param amount Minimum amount of tokens needed for the allowance\n function _checkAllowance(IERC20 token, address spender, uint256 amount) internal {\n uint256 currentAllowance = token.allowance(address(this), spender);\n if (currentAllowance < amount) token.safeIncreaseAllowance(spender, type(uint256).max - currentAllowance);\n }\n\n /// @notice Performs a swap using either Uniswap, 1inch. This function can also stake stETH to wstETH\n /// @param inToken Token to swap\n /// @param amount Amount of tokens to swap\n /// @param swapType Type of the swap to perform\n /// @param args Extra args for the swap: in the case of Uniswap it should be a path, for 1inch it should be\n /// a payload\n /// @dev This function does nothing if `swapType` is None and it simply passes on the `amount` it received\n /// @dev No slippage is specified in the actions given here as a final slippage check is performed\n /// after the call to this function\n function _swap(IERC20 inToken, uint256 amount, SwapType swapType, bytes memory args) internal {\n if (swapType == SwapType.UniswapV3) _swapOnUniswapV3(inToken, amount, args);\n else if (swapType == SwapType.oneInch) _swapOn1inch(inToken, args);\n else if (swapType == SwapType.AngleRouter) _angleRouterActions(inToken, args);\n else if (swapType == SwapType.Leverage) _swapLeverage(args);\n }\n\n /// @notice Performs a UniswapV3 swap\n /// @param inToken Token to swap\n /// @param amount Amount of tokens to swap\n /// @param path Path for the UniswapV3 swap: this encodes the out token that is going to be obtained\n /// @dev This function does not check the out token obtained here: if it is wrongly specified, either\n /// the `swap` function could fail or these tokens could stay on the contract\n function _swapOnUniswapV3(IERC20 inToken, uint256 amount, bytes memory path) internal returns (uint256 amountOut) {\n // We need more than `amount` of allowance to the contract\n _checkAllowance(inToken, address(uniV3Router), amount);\n amountOut = uniV3Router.exactInput(ExactInputParams(path, address(this), block.timestamp, amount, 0));\n }\n\n /// @notice Allows to swap any token to an accepted collateral via 1inch API\n /// @param inToken Token received for the 1inch swap\n /// @param payload Bytes needed for 1inch API\n function _swapOn1inch(IERC20 inToken, bytes memory payload) internal returns (uint256 amountOut) {\n _changeAllowance(inToken, oneInch, type(uint256).max);\n //solhint-disable-next-line\n (bool success, bytes memory result) = oneInch.call(payload);\n if (!success) _revertBytes(result);\n amountOut = abi.decode(result, (uint256));\n }\n\n /// @notice Performs actions with the router contract of the protocol on the corresponding chain\n /// @param inToken Token concerned by the action and for which\n function _angleRouterActions(IERC20 inToken, bytes memory args) internal {\n (ActionType[] memory actions, bytes[] memory actionData) = abi.decode(args, (ActionType[], bytes[]));\n _changeAllowance(inToken, address(angleRouter), type(uint256).max);\n PermitType[] memory permits;\n angleRouter.mixer(permits, actions, actionData);\n }\n\n /// @notice Allows to take leverage or deleverage via a specific contract\n /// @param payload Bytes needed for 1inch API\n /// @dev This function is to be implemented if the swapper concerns a token that requires some actions\n /// not supported by 1inch or UniV3\n function _swapLeverage(bytes memory payload) internal virtual returns (uint256 amountOut) {}\n\n /// @notice Internal function used for error handling\n /// @param errMsg Error message received\n function _revertBytes(bytes memory errMsg) internal pure {\n if (errMsg.length != 0) {\n //solhint-disable-next-line\n assembly {\n revert(add(32, errMsg), mload(errMsg))\n }\n }\n revert EmptyReturnMessage();\n }\n}\n" + }, + "contracts/treasury/Treasury.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\n/*\n * █ \n ***** ▓▓▓ \n * ▓▓▓▓▓▓▓ \n * ///. ▓▓▓▓▓▓▓▓▓▓▓▓▓ \n ***** //////// ▓▓▓▓▓▓▓ \n * ///////////// ▓▓▓ \n ▓▓ ////////////////// █ ▓▓ \n ▓▓ ▓▓ /////////////////////// ▓▓ ▓▓ \n ▓▓ ▓▓ //////////////////////////// ▓▓ ▓▓ \n ▓▓ ▓▓ /////////▓▓▓///////▓▓▓///////// ▓▓ ▓▓ \n ▓▓ ,////////////////////////////////////// ▓▓ ▓▓ \n ▓▓ ////////////////////////////////////////// ▓▓ \n ▓▓ //////////////////////▓▓▓▓///////////////////// \n ,//////////////////////////////////////////////////// \n .////////////////////////////////////////////////////////// \n .//////////////////////////██.,//////////////////////////█ \n .//////////////////////████..,./////////////////////██ \n ...////////////////███████.....,.////////////////███ \n ,.,////////////████████ ........,///////////████ \n .,.,//////█████████ ,.......///////████ \n ,..//████████ ........./████ \n ..,██████ .....,███ \n .██ ,.,█ \n \n \n \n ▓▓ ▓▓▓▓▓▓▓▓▓▓ ▓▓▓▓▓▓▓▓▓▓ ▓▓ ▓▓▓▓▓▓▓▓▓▓ \n ▓▓▓▓▓▓ ▓▓▓ ▓▓▓ ▓▓▓ ▓▓ ▓▓ ▓▓▓▓ \n ▓▓▓ ▓▓▓ ▓▓▓ ▓▓▓ ▓▓▓ ▓▓▓ ▓▓ ▓▓▓▓▓ \n ▓▓▓ ▓▓ ▓▓▓ ▓▓▓ ▓▓▓▓▓▓▓▓▓▓ ▓▓▓▓▓▓▓▓▓▓ ▓▓▓▓▓▓▓▓▓▓ \n*/\n\npragma solidity ^0.8.12;\n\nimport \"@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol\";\nimport \"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\";\nimport \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\n\nimport \"../interfaces/IAgToken.sol\";\nimport \"../interfaces/ICoreBorrow.sol\";\nimport \"../interfaces/IFlashAngle.sol\";\nimport \"../interfaces/ITreasury.sol\";\nimport \"../interfaces/IVaultManager.sol\";\n\n/// @title Treasury\n/// @author Angle Labs, Inc.\n/// @notice Treasury of Angle Borrowing Module doing the accounting across all VaultManagers for\n/// a given stablecoin\ncontract Treasury is ITreasury, Initializable {\n using SafeERC20 for IERC20;\n\n /// @notice Base used for parameter computation\n uint256 public constant BASE_9 = 1e9;\n\n // ================================= REFERENCES ================================\n\n /// @notice Reference to the `CoreBorrow` contract of the module which handles all AccessControl logic\n ICoreBorrow public core;\n /// @notice Flash Loan Module with a minter right on the stablecoin\n IFlashAngle public flashLoanModule;\n /// @inheritdoc ITreasury\n IAgToken public stablecoin;\n /// @notice Address responsible for handling the surplus made by the treasury\n address public surplusManager;\n /// @notice List of the accepted `VaultManager` of the protocol\n address[] public vaultManagerList;\n /// @notice Maps an address to 1 if it was initialized as a `VaultManager` contract\n mapping(address => uint256) public vaultManagerMap;\n\n // ================================= VARIABLES =================================\n\n /// @notice Amount of bad debt (unbacked stablecoin) accumulated across all `VaultManager` contracts\n /// linked to this stablecoin\n uint256 public badDebt;\n /// @notice Surplus amount accumulated by the contract waiting to be distributed to governance. Technically\n /// only a share of this `surplusBuffer` will go to governance. Once a share of the surplus buffer has been\n /// given to governance, then this surplus is reset\n uint256 public surplusBuffer;\n\n // ================================= PARAMETER =================================\n\n /// @notice Share of the `surplusBuffer` distributed to governance (in `BASE_9`)\n uint64 public surplusForGovernance;\n\n // =================================== EVENTS ==================================\n\n event BadDebtUpdated(uint256 badDebtValue);\n event CoreUpdated(address indexed _core);\n event NewTreasurySet(address indexed _treasury);\n event Recovered(address indexed token, address indexed to, uint256 amount);\n event SurplusBufferUpdated(uint256 surplusBufferValue);\n event SurplusForGovernanceUpdated(uint64 _surplusForGovernance);\n event SurplusManagerUpdated(address indexed _surplusManager);\n event VaultManagerToggled(address indexed vaultManager);\n\n // =================================== ERRORS ==================================\n\n error AlreadyVaultManager();\n error InvalidAddress();\n error InvalidTreasury();\n error NotCore();\n error NotGovernor();\n error NotVaultManager();\n error RightsNotRemoved();\n error TooBigAmount();\n error TooHighParameterValue();\n error ZeroAddress();\n\n // ================================== MODIFIER =================================\n\n /// @notice Checks whether the `msg.sender` has the governor role or not\n modifier onlyGovernor() {\n if (!core.isGovernor(msg.sender)) revert NotGovernor();\n _;\n }\n\n /// @notice Initializes the treasury contract\n /// @param _core Address of the `CoreBorrow` contract of the module\n /// @param _stablecoin Address of the stablecoin\n function initialize(ICoreBorrow _core, IAgToken _stablecoin) public virtual initializer {\n if (address(_stablecoin) == address(0) || address(_core) == address(0)) revert ZeroAddress();\n core = _core;\n stablecoin = _stablecoin;\n }\n\n /// @custom:oz-upgrades-unsafe-allow constructor\n constructor() initializer {}\n\n // =============================== VIEW FUNCTIONS ==============================\n\n /// @inheritdoc ITreasury\n function isGovernor(address admin) external view returns (bool) {\n return core.isGovernor(admin);\n }\n\n /// @inheritdoc ITreasury\n function isGovernorOrGuardian(address admin) external view returns (bool) {\n return core.isGovernorOrGuardian(admin);\n }\n\n /// @inheritdoc ITreasury\n function isVaultManager(address _vaultManager) external view returns (bool) {\n return vaultManagerMap[_vaultManager] == 1;\n }\n\n // ===================== EXTERNAL PERMISSIONLESS FUNCTIONS =====================\n\n /// @notice Fetches the surplus accrued across all the `VaultManager` contracts controlled by this\n /// `Treasury` contract as well as from the fees of the `FlashLoan` module\n /// @return Surplus buffer value at the end of the call\n /// @return Bad debt value at the end of the call\n /// @dev This function pools surplus and bad debt across all contracts and then updates the `surplusBuffer`\n /// (or the `badDebt` if more losses were made than profits)\n function fetchSurplusFromAll() external returns (uint256, uint256) {\n return _fetchSurplusFromAll();\n }\n\n /// @notice Fetches the surplus accrued in the flash loan module and updates the `surplusBuffer`\n /// @return Surplus buffer value at the end of the call\n /// @return Bad debt value at the end of the call\n /// @dev This function fails if the `flashLoanModule` has not been initialized yet\n function fetchSurplusFromFlashLoan() external returns (uint256, uint256) {\n uint256 surplusBufferValue = surplusBuffer + flashLoanModule.accrueInterestToTreasury(stablecoin);\n return _updateSurplusAndBadDebt(surplusBufferValue, badDebt);\n }\n\n /// @notice Pushes the surplus buffer to the `surplusManager` contract\n /// @return governanceAllocation Amount transferred to governance\n /// @dev It makes sure to fetch the surplus from all the contracts handled by this treasury to avoid\n /// the situation where rewards are still distributed to governance even though a `VaultManager` has made\n /// a big loss\n /// @dev Typically this function is to be called once every week by a keeper to distribute rewards to veANGLE\n /// holders\n /// @dev `stablecoin` must be an AgToken and hence `transfer` reverts if the call is not successful\n function pushSurplus() external returns (uint256 governanceAllocation) {\n address _surplusManager = surplusManager;\n if (_surplusManager == address(0)) {\n revert ZeroAddress();\n }\n (uint256 surplusBufferValue, ) = _fetchSurplusFromAll();\n surplusBuffer = 0;\n emit SurplusBufferUpdated(0);\n governanceAllocation = (surplusForGovernance * surplusBufferValue) / BASE_9;\n stablecoin.transfer(_surplusManager, governanceAllocation);\n }\n\n /// @notice Updates the bad debt of the protocol in case where the protocol has accumulated some revenue\n /// from an external source\n /// @param amount Amount to reduce the bad debt of\n /// @return badDebtValue Value of the bad debt at the end of the call\n /// @dev If the protocol has made a loss and managed to make some profits to recover for this loss (through\n /// a program like Olympus Pro), then this function needs to be called\n /// @dev `badDebt` is simply reduced here by burning stablecoins\n /// @dev It is impossible to burn more than the `badDebt` otherwise this function could be used to manipulate\n /// the `surplusBuffer` and hence the amount going to governance\n function updateBadDebt(uint256 amount) external returns (uint256 badDebtValue) {\n stablecoin.burnSelf(amount, address(this));\n badDebtValue = badDebt - amount;\n badDebt = badDebtValue;\n emit BadDebtUpdated(badDebtValue);\n }\n\n // ========================= INTERNAL UTILITY FUNCTIONS ========================\n\n /// @notice Internal version of the `fetchSurplusFromAll` function\n function _fetchSurplusFromAll() internal returns (uint256 surplusBufferValue, uint256 badDebtValue) {\n (surplusBufferValue, badDebtValue) = _fetchSurplusFromList(vaultManagerList);\n // It will fail anyway if the `flashLoanModule` is the zero address\n if (address(flashLoanModule) != address(0))\n surplusBufferValue += flashLoanModule.accrueInterestToTreasury(stablecoin);\n (surplusBufferValue, badDebtValue) = _updateSurplusAndBadDebt(surplusBufferValue, badDebtValue);\n }\n\n /// @notice Fetches the surplus from a list of `VaultManager` addresses without modifying the\n /// `surplusBuffer` and `badDebtValue`\n /// @return surplusBufferValue Value the `surplusBuffer` should have after the call if it was updated\n /// @return badDebtValue Value the `badDebt` should have after the call if it was updated\n /// @dev This internal function is never to be called alone, and should always be called in conjunction\n /// with the `_updateSurplusAndBadDebt` function\n function _fetchSurplusFromList(\n address[] memory vaultManagers\n ) internal returns (uint256 surplusBufferValue, uint256 badDebtValue) {\n badDebtValue = badDebt;\n surplusBufferValue = surplusBuffer;\n uint256 newSurplus;\n uint256 newBadDebt;\n uint256 vaultManagersLength = vaultManagers.length;\n for (uint256 i; i < vaultManagersLength; ++i) {\n (newSurplus, newBadDebt) = IVaultManager(vaultManagers[i]).accrueInterestToTreasury();\n surplusBufferValue += newSurplus;\n badDebtValue += newBadDebt;\n }\n }\n\n /// @notice Updates the `surplusBuffer` and the `badDebt` from updated values after calling the flash loan module\n /// and/or a list of `VaultManager` contracts\n /// @param surplusBufferValue Value of the surplus buffer after the calls to the different modules\n /// @param badDebtValue Value of the bad debt after the calls to the different modules\n /// @return Value of the `surplusBuffer` corrected from the `badDebt`\n /// @return Value of the `badDebt` corrected from the `surplusBuffer` and from the surplus the treasury had accumulated\n /// previously\n /// @dev When calling this function, it is possible that there is a positive `surplusBufferValue` and `badDebtValue`,\n /// this function tries to reconcile both values and makes sure that we either have surplus or bad debt but not both\n /// at the same time\n function _updateSurplusAndBadDebt(\n uint256 surplusBufferValue,\n uint256 badDebtValue\n ) internal returns (uint256, uint256) {\n if (badDebtValue != 0) {\n // If we have bad debt we need to burn stablecoins that accrued to the protocol\n // We still need to make sure that we're not burning too much or as much as we can if the debt is big\n uint256 balance = stablecoin.balanceOf(address(this));\n // We are going to burn `min(balance, badDebtValue)`\n uint256 toBurn = balance <= badDebtValue ? balance : badDebtValue;\n stablecoin.burnSelf(toBurn, address(this));\n // If we burned more than `surplusBuffer`, we set surplus to 0. It means we had to tap into Treasury reserve\n surplusBufferValue = toBurn >= surplusBufferValue ? 0 : surplusBufferValue - toBurn;\n badDebtValue -= toBurn;\n // Note here that the stablecoin balance is necessarily greater than the surplus buffer, and so if\n // `surplusBuffer >= toBurn`, then `badDebtValue = toBurn`\n }\n surplusBuffer = surplusBufferValue;\n badDebt = badDebtValue;\n emit SurplusBufferUpdated(surplusBufferValue);\n emit BadDebtUpdated(badDebtValue);\n return (surplusBufferValue, badDebtValue);\n }\n\n /// @notice Adds a new `VaultManager`\n /// @param vaultManager `VaultManager` contract to add\n /// @dev This contract should have already been initialized with a correct treasury address\n /// @dev It's this function that gives the minter right to the `VaultManager`\n function _addVaultManager(address vaultManager) internal virtual {\n if (vaultManagerMap[vaultManager] == 1) revert AlreadyVaultManager();\n if (address(IVaultManager(vaultManager).treasury()) != address(this)) revert InvalidTreasury();\n vaultManagerMap[vaultManager] = 1;\n vaultManagerList.push(vaultManager);\n emit VaultManagerToggled(vaultManager);\n stablecoin.addMinter(vaultManager);\n }\n\n // ============================= GOVERNOR FUNCTIONS ============================\n\n /// @notice Adds a new minter for the stablecoin\n /// @param minter Minter address to add\n function addMinter(address minter) external virtual onlyGovernor {\n if (minter == address(0)) revert ZeroAddress();\n stablecoin.addMinter(minter);\n }\n\n /// @notice External wrapper for `_addVaultManager`\n function addVaultManager(address vaultManager) external virtual onlyGovernor {\n _addVaultManager(vaultManager);\n }\n\n /// @notice Removes a minter from the stablecoin contract\n /// @param minter Minter address to remove\n function removeMinter(address minter) external virtual onlyGovernor {\n // To remove the minter role to a `VaultManager` you have to go through the `removeVaultManager` function\n if (vaultManagerMap[minter] == 1) revert InvalidAddress();\n stablecoin.removeMinter(minter);\n }\n\n /// @notice Removes a `VaultManager`\n /// @param vaultManager `VaultManager` contract to remove\n /// @dev A removed `VaultManager` loses its minter right on the stablecoin\n function removeVaultManager(address vaultManager) external onlyGovernor {\n if (vaultManagerMap[vaultManager] != 1) revert NotVaultManager();\n delete vaultManagerMap[vaultManager];\n // deletion from `vaultManagerList` loop\n uint256 vaultManagerListLength = vaultManagerList.length;\n for (uint256 i; i < vaultManagerListLength - 1; ++i) {\n if (vaultManagerList[i] == vaultManager) {\n // replace the `VaultManager` to remove with the last of the list\n vaultManagerList[i] = vaultManagerList[vaultManagerListLength - 1];\n break;\n }\n }\n // remove last element in array\n vaultManagerList.pop();\n emit VaultManagerToggled(vaultManager);\n stablecoin.removeMinter(vaultManager);\n }\n\n /// @notice Allows to recover any ERC20 token, including the stablecoin handled by this contract, and to send it\n /// to a contract\n /// @param tokenAddress Address of the token to recover\n /// @param to Address of the contract to send collateral to\n /// @param amountToRecover Amount of collateral to transfer\n /// @dev It is impossible to recover the stablecoin of the protocol if there is some bad debt for it\n /// @dev In this case, the function makes sure to fetch the surplus/bad debt from all the `VaultManager` contracts\n /// and from the flash loan module\n /// @dev If the token to recover is the stablecoin, tokens recovered are fetched\n /// from the surplus and not from the `surplusBuffer`\n function recoverERC20(address tokenAddress, address to, uint256 amountToRecover) external onlyGovernor {\n // Cannot recover stablecoin if badDebt or tap into the surplus buffer\n if (tokenAddress == address(stablecoin)) {\n _fetchSurplusFromAll();\n // If balance is non zero then this means, after the call to `fetchSurplusFromAll` that\n // bad debt is necessarily null\n uint256 balance = stablecoin.balanceOf(address(this));\n if (amountToRecover + surplusBuffer > balance) revert TooBigAmount();\n stablecoin.transfer(to, amountToRecover);\n } else {\n IERC20(tokenAddress).safeTransfer(to, amountToRecover);\n }\n emit Recovered(tokenAddress, to, amountToRecover);\n }\n\n /// @notice Changes the treasury contract and communicates this change to all `VaultManager` contract\n /// @param _treasury New treasury address for this stablecoin\n /// @dev This function is basically a way to remove rights to this contract and grant them to a new one\n /// @dev It could be used to set a new core contract\n function setTreasury(address _treasury) external virtual onlyGovernor {\n if (ITreasury(_treasury).stablecoin() != stablecoin) revert InvalidTreasury();\n // Flash loan role should be removed before calling this function\n if (core.isFlashLoanerTreasury(address(this))) revert RightsNotRemoved();\n emit NewTreasurySet(_treasury);\n uint256 vaultManagerListLength = vaultManagerList.length;\n for (uint256 i; i < vaultManagerListLength; ++i) {\n IVaultManager(vaultManagerList[i]).setTreasury(_treasury);\n }\n // A `TreasuryUpdated` event is triggered in the stablecoin\n stablecoin.setTreasury(_treasury);\n }\n\n /// @notice Sets the `surplusForGovernance` parameter\n /// @param _surplusForGovernance New value of the parameter\n /// @dev To pause surplus distribution, governance needs to set a zero value for `surplusForGovernance`\n /// which means\n function setSurplusForGovernance(uint64 _surplusForGovernance) external onlyGovernor {\n if (_surplusForGovernance > BASE_9) revert TooHighParameterValue();\n surplusForGovernance = _surplusForGovernance;\n emit SurplusForGovernanceUpdated(_surplusForGovernance);\n }\n\n /// @notice Sets the `surplusManager` contract responsible for handling the surplus of the\n /// protocol\n /// @param _surplusManager New address responsible for handling the surplus\n function setSurplusManager(address _surplusManager) external onlyGovernor {\n if (_surplusManager == address(0)) revert ZeroAddress();\n surplusManager = _surplusManager;\n emit SurplusManagerUpdated(_surplusManager);\n }\n\n /// @notice Sets a new `core` contract\n /// @dev This function should typically be called on all treasury contracts after the `setCore`\n /// function has been called on the `CoreBorrow` contract\n /// @dev One sanity check that can be performed here is to verify whether at least the governor\n /// calling the contract is still a governor in the new core\n function setCore(ICoreBorrow _core) external onlyGovernor {\n if (!_core.isGovernor(msg.sender)) revert NotGovernor();\n core = ICoreBorrow(_core);\n emit CoreUpdated(address(_core));\n }\n\n /// @inheritdoc ITreasury\n function setFlashLoanModule(address _flashLoanModule) external {\n if (msg.sender != address(core)) revert NotCore();\n address oldFlashLoanModule = address(flashLoanModule);\n flashLoanModule = IFlashAngle(_flashLoanModule);\n if (oldFlashLoanModule != address(0)) {\n stablecoin.removeMinter(oldFlashLoanModule);\n }\n // We may want to cancel the module\n if (_flashLoanModule != address(0)) {\n stablecoin.addMinter(_flashLoanModule);\n }\n }\n}\n" + }, + "contracts/ui-helpers/AngleBorrowHelpers.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\n/*\n * █ \n ***** ▓▓▓ \n * ▓▓▓▓▓▓▓ \n * ///. ▓▓▓▓▓▓▓▓▓▓▓▓▓ \n ***** //////// ▓▓▓▓▓▓▓ \n * ///////////// ▓▓▓ \n ▓▓ ////////////////// █ ▓▓ \n ▓▓ ▓▓ /////////////////////// ▓▓ ▓▓ \n ▓▓ ▓▓ //////////////////////////// ▓▓ ▓▓ \n ▓▓ ▓▓ /////////▓▓▓///////▓▓▓///////// ▓▓ ▓▓ \n ▓▓ ,////////////////////////////////////// ▓▓ ▓▓ \n ▓▓ ////////////////////////////////////////// ▓▓ \n ▓▓ //////////////////////▓▓▓▓///////////////////// \n ,//////////////////////////////////////////////////// \n .////////////////////////////////////////////////////////// \n .//////////////////////////██.,//////////////////////////█ \n .//////////////////////████..,./////////////////////██ \n ...////////////////███████.....,.////////////////███ \n ,.,////////////████████ ........,///////////████ \n .,.,//////█████████ ,.......///////████ \n ,..//████████ ........./████ \n ..,██████ .....,███ \n .██ ,.,█ \n \n \n \n ▓▓ ▓▓▓▓▓▓▓▓▓▓ ▓▓▓▓▓▓▓▓▓▓ ▓▓ ▓▓▓▓▓▓▓▓▓▓ \n ▓▓▓▓▓▓ ▓▓▓ ▓▓▓ ▓▓▓ ▓▓ ▓▓ ▓▓▓▓ \n ▓▓▓ ▓▓▓ ▓▓▓ ▓▓▓ ▓▓▓ ▓▓▓ ▓▓ ▓▓▓▓▓ \n ▓▓▓ ▓▓ ▓▓▓ ▓▓▓ ▓▓▓▓▓▓▓▓▓▓ ▓▓▓▓▓▓▓▓▓▓ ▓▓▓▓▓▓▓▓▓▓ \n*/\n\nimport \"@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol\";\nimport \"../interfaces/IVaultManager.sol\";\n\npragma solidity ^0.8.12;\n\n/// @title AngleBorrowHelpers\n/// @author Angle Labs, Inc.\n/// @notice Contract with view functions designed to facilitate integrations on the Borrow module of the Angle Protocol\n/// @dev This contract only contains view functions to be queried off-chain. It was thus not optimized for gas consumption\ncontract AngleBorrowHelpers is Initializable {\n /// @notice Returns all the vaults owned or controlled (under the form of approval) by an address\n /// @param vaultManager VaultManager address to query vaultIDs on\n /// @param spender Address for which vault ownerships should be checked\n /// @return List of `vaultID` controlled by this address\n /// @return Count of vaults owned by the address\n /// @dev This function is never to be called on-chain since it iterates over all vaultIDs. It is here\n /// to reduce dependency on an external graph to link an ID to its owner\n function getControlledVaults(\n IVaultManager vaultManager,\n address spender\n ) external view returns (uint256[] memory, uint256) {\n uint256 arraySize = vaultManager.vaultIDCount();\n uint256[] memory vaultsControlled = new uint256[](arraySize);\n uint256 count;\n for (uint256 i = 1; i <= arraySize; ++i) {\n try vaultManager.isApprovedOrOwner(spender, i) returns (bool _isApprovedOrOwner) {\n if (_isApprovedOrOwner) {\n vaultsControlled[count] = i;\n count += 1;\n }\n } catch {\n continue;\n } // This happens if nobody owns the vaultID=i (if there has been a burn)\n }\n return (vaultsControlled, count);\n }\n\n /// @custom:oz-upgrades-unsafe-allow constructor\n constructor() initializer {}\n}\n" + }, + "contracts/ui-helpers/AngleHelpers.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\nimport \"../interfaces/IAngleRouter.sol\";\nimport \"../interfaces/coreModule/IAgTokenMainnet.sol\";\nimport \"../interfaces/coreModule/ICore.sol\";\nimport \"../interfaces/coreModule/IOracleCore.sol\";\nimport \"../interfaces/coreModule/IPerpetualManager.sol\";\nimport \"../interfaces/coreModule/IPoolManager.sol\";\nimport \"../interfaces/coreModule/IStableMaster.sol\";\nimport \"./AngleBorrowHelpers.sol\";\n\npragma solidity ^0.8.12;\n\nstruct Parameters {\n SLPData slpData;\n MintBurnData feeData;\n PerpetualManagerFeeData perpFeeData;\n PerpetualManagerParamData perpParam;\n}\n\nstruct PerpetualManagerFeeData {\n uint64[] xHAFeesDeposit;\n uint64[] yHAFeesDeposit;\n uint64[] xHAFeesWithdraw;\n uint64[] yHAFeesWithdraw;\n uint64 haBonusMalusDeposit;\n uint64 haBonusMalusWithdraw;\n}\n\nstruct PerpetualManagerParamData {\n uint64 maintenanceMargin;\n uint64 maxLeverage;\n uint64 targetHAHedge;\n uint64 limitHAHedge;\n uint64 lockTime;\n}\n\nstruct CollateralAddresses {\n address stableMaster;\n address poolManager;\n address perpetualManager;\n address sanToken;\n address oracle;\n address gauge;\n address feeManager;\n address[] strategies;\n}\n\n/// @title AngleHelpers\n/// @author Angle Labs, Inc.\n/// @notice Contract with view functions designed to facilitate integrations on the Core and Borrow module of the Angle Protocol\n/// @dev This contract only contains view functions to be queried off-chain. It was thus not optimized for gas consumption\ncontract AngleHelpers is AngleBorrowHelpers {\n // =========================== HELPER VIEW FUNCTIONS ===========================\n\n /// @notice Gives the amount of `agToken` you'd be getting if you were executing in the same block a mint transaction\n /// with `amount` of `collateral` in the Core module of the Angle protocol as well as the value of the fees\n /// (in `BASE_PARAMS`) that would be applied during the mint\n /// @return Amount of `agToken` that would be obtained with a mint transaction in the same block\n /// @return Percentage of fees that would be taken during a mint transaction in the same block\n /// @dev This function reverts if the mint transaction was to revert in the same conditions (without taking into account\n /// potential approval problems to the `StableMaster` contract)\n function previewMintAndFees(\n uint256 amount,\n address agToken,\n address collateral\n ) external view returns (uint256, uint256) {\n return _previewMintAndFees(amount, agToken, collateral);\n }\n\n /// @notice Gives the amount of `collateral` you'd be getting if you were executing in the same block a burn transaction\n /// with `amount` of `agToken` in the Core module of the Angle protocol as well as the value of the fees\n /// (in `BASE_PARAMS`) that would be applied during the burn\n /// @return Amount of `collateral` that would be obtained with a burn transaction in the same block\n /// @return Percentage of fees that would be taken during a burn transaction in the same block\n /// @dev This function reverts if the burn transaction was to revert in the same conditions (without taking into account\n /// potential approval problems to the `StableMaster` contract or agToken balance prior to the call)\n function previewBurnAndFees(\n uint256 amount,\n address agToken,\n address collateral\n ) external view returns (uint256, uint256) {\n return _previewBurnAndFees(amount, agToken, collateral);\n }\n\n /// @notice Returns all the addresses associated to the (`agToken`,`collateral`) pair given\n /// @return addresses A struct with all the addresses associated in the Core module\n function getCollateralAddresses(\n address agToken,\n address collateral\n ) external view returns (CollateralAddresses memory addresses) {\n address stableMaster = IAgTokenMainnet(agToken).stableMaster();\n (address poolManager, address perpetualManager, address sanToken, address gauge) = ROUTER.mapPoolManagers(\n stableMaster,\n collateral\n );\n (, , , IOracleCore oracle, , , , , ) = IStableMaster(stableMaster).collateralMap(poolManager);\n addresses.stableMaster = stableMaster;\n addresses.poolManager = poolManager;\n addresses.perpetualManager = perpetualManager;\n addresses.sanToken = sanToken;\n addresses.gauge = gauge;\n addresses.oracle = address(oracle);\n addresses.feeManager = IPoolManager(poolManager).feeManager();\n\n uint256 length;\n while (true) {\n try IPoolManager(poolManager).strategyList(length) returns (address) {\n length += 1;\n } catch {\n break;\n }\n }\n address[] memory strategies = new address[](length);\n for (uint256 i; i < length; ++i) {\n strategies[i] = IPoolManager(poolManager).strategyList(i);\n }\n addresses.strategies = strategies;\n }\n\n /// @notice Gets the addresses of all the `StableMaster` contracts and their associated `AgToken` addresses\n /// @return List of the `StableMaster` addresses of the Angle protocol\n /// @return List of the `AgToken` addresses of the protocol\n /// @dev The place of an agToken address in the list is the same as the corresponding `StableMaster` address\n function getStablecoinAddresses() external view returns (address[] memory, address[] memory) {\n address[] memory stableMasterAddresses = CORE.stablecoinList();\n address[] memory agTokenAddresses = new address[](stableMasterAddresses.length);\n for (uint256 i; i < stableMasterAddresses.length; ++i) {\n agTokenAddresses[i] = IStableMaster(stableMasterAddresses[i]).agToken();\n }\n return (stableMasterAddresses, agTokenAddresses);\n }\n\n /// @notice Returns most of the governance parameters associated to the (`agToken`,`collateral`) pair given\n /// @return params Struct with most of the parameters in the `StableMaster` and `PerpetualManager` contracts\n /// @dev Check out the struct `Parameters` for the meaning of the return values\n function getCollateralParameters(\n address agToken,\n address collateral\n ) external view returns (Parameters memory params) {\n (address stableMaster, address poolManager) = _getStableMasterAndPoolManager(agToken, collateral);\n (\n ,\n ,\n IPerpetualManager perpetualManager,\n ,\n ,\n ,\n ,\n SLPData memory slpData,\n MintBurnData memory feeData\n ) = IStableMaster(stableMaster).collateralMap(poolManager);\n\n params.slpData = slpData;\n params.feeData = feeData;\n params.perpParam.maintenanceMargin = perpetualManager.maintenanceMargin();\n params.perpParam.maxLeverage = perpetualManager.maxLeverage();\n params.perpParam.targetHAHedge = perpetualManager.targetHAHedge();\n params.perpParam.limitHAHedge = perpetualManager.limitHAHedge();\n params.perpParam.lockTime = perpetualManager.lockTime();\n\n params.perpFeeData.haBonusMalusDeposit = perpetualManager.haBonusMalusDeposit();\n params.perpFeeData.haBonusMalusWithdraw = perpetualManager.haBonusMalusWithdraw();\n\n uint256 length;\n while (true) {\n try perpetualManager.xHAFeesDeposit(length) returns (uint64) {\n length += 1;\n } catch {\n break;\n }\n }\n uint64[] memory data = new uint64[](length);\n uint64[] memory data2 = new uint64[](length);\n for (uint256 i; i < length; ++i) {\n data[i] = perpetualManager.xHAFeesDeposit(i);\n data2[i] = perpetualManager.yHAFeesDeposit(i);\n }\n params.perpFeeData.xHAFeesDeposit = data;\n params.perpFeeData.yHAFeesDeposit = data2;\n\n length = 0;\n while (true) {\n try perpetualManager.xHAFeesWithdraw(length) returns (uint64) {\n length += 1;\n } catch {\n break;\n }\n }\n data = new uint64[](length);\n data2 = new uint64[](length);\n for (uint256 i; i < length; ++i) {\n data[i] = perpetualManager.xHAFeesWithdraw(i);\n data2[i] = perpetualManager.yHAFeesWithdraw(i);\n }\n params.perpFeeData.xHAFeesWithdraw = data;\n params.perpFeeData.yHAFeesWithdraw = data2;\n }\n\n /// @notice Returns the address of the poolManager associated to an (`agToken`, `collateral`) pair\n /// in the Core module of the protocol\n function getPoolManager(address agToken, address collateral) public view returns (address poolManager) {\n (, poolManager) = _getStableMasterAndPoolManager(agToken, collateral);\n }\n\n // ============================= REPLICA FUNCTIONS =============================\n // These replicate what is done in the other contracts of the protocol\n\n function _previewBurnAndFees(\n uint256 amount,\n address agToken,\n address collateral\n ) internal view returns (uint256 amountForUserInCollat, uint256 feePercent) {\n (address stableMaster, address poolManager) = _getStableMasterAndPoolManager(agToken, collateral);\n (\n address token,\n ,\n IPerpetualManager perpetualManager,\n IOracleCore oracle,\n uint256 stocksUsers,\n ,\n uint256 collatBase,\n ,\n MintBurnData memory feeData\n ) = IStableMaster(stableMaster).collateralMap(poolManager);\n if (token == address(0) || IStableMaster(stableMaster).paused(keccak256(abi.encodePacked(STABLE, poolManager))))\n revert NotInitialized();\n if (amount > stocksUsers) revert InvalidAmount();\n\n if (feeData.xFeeBurn.length == 1) {\n feePercent = feeData.yFeeBurn[0];\n } else {\n bytes memory data = abi.encode(address(perpetualManager), feeData.targetHAHedge);\n uint64 hedgeRatio = _computeHedgeRatio(stocksUsers - amount, data);\n feePercent = _piecewiseLinear(hedgeRatio, feeData.xFeeBurn, feeData.yFeeBurn);\n }\n feePercent = (feePercent * feeData.bonusMalusBurn) / BASE_PARAMS;\n\n amountForUserInCollat = (amount * (BASE_PARAMS - feePercent) * collatBase) / (oracle.readUpper() * BASE_PARAMS);\n }\n\n function _previewMintAndFees(\n uint256 amount,\n address agToken,\n address collateral\n ) internal view returns (uint256 amountForUserInStable, uint256 feePercent) {\n (address stableMaster, address poolManager) = _getStableMasterAndPoolManager(agToken, collateral);\n (\n address token,\n ,\n IPerpetualManager perpetualManager,\n IOracleCore oracle,\n uint256 stocksUsers,\n ,\n ,\n ,\n MintBurnData memory feeData\n ) = IStableMaster(stableMaster).collateralMap(poolManager);\n if (token == address(0) || IStableMaster(stableMaster).paused(keccak256(abi.encodePacked(STABLE, poolManager))))\n revert NotInitialized();\n\n amountForUserInStable = oracle.readQuoteLower(amount);\n\n if (feeData.xFeeMint.length == 1) feePercent = feeData.yFeeMint[0];\n else {\n bytes memory data = abi.encode(address(perpetualManager), feeData.targetHAHedge);\n uint64 hedgeRatio = _computeHedgeRatio(amountForUserInStable + stocksUsers, data);\n feePercent = _piecewiseLinear(hedgeRatio, feeData.xFeeMint, feeData.yFeeMint);\n }\n feePercent = (feePercent * feeData.bonusMalusMint) / BASE_PARAMS;\n\n amountForUserInStable = (amountForUserInStable * (BASE_PARAMS - feePercent)) / BASE_PARAMS;\n if (stocksUsers + amountForUserInStable > feeData.capOnStableMinted) revert InvalidAmount();\n }\n\n // ============================= UTILITY FUNCTIONS =============================\n // These utility functions are taken from other contracts of the protocol\n\n function _computeHedgeRatio(uint256 newStocksUsers, bytes memory data) internal view returns (uint64 ratio) {\n (address perpetualManager, uint64 targetHAHedge) = abi.decode(data, (address, uint64));\n uint256 totalHedgeAmount = IPerpetualManager(perpetualManager).totalHedgeAmount();\n newStocksUsers = (targetHAHedge * newStocksUsers) / BASE_PARAMS;\n if (newStocksUsers > totalHedgeAmount) ratio = uint64((totalHedgeAmount * BASE_PARAMS) / newStocksUsers);\n else ratio = uint64(BASE_PARAMS);\n }\n\n function _piecewiseLinear(uint64 x, uint64[] memory xArray, uint64[] memory yArray) internal pure returns (uint64) {\n if (x >= xArray[xArray.length - 1]) {\n return yArray[xArray.length - 1];\n } else if (x <= xArray[0]) {\n return yArray[0];\n } else {\n uint256 lower;\n uint256 upper = xArray.length - 1;\n uint256 mid;\n while (upper - lower > 1) {\n mid = lower + (upper - lower) / 2;\n if (xArray[mid] <= x) {\n lower = mid;\n } else {\n upper = mid;\n }\n }\n if (yArray[upper] > yArray[lower]) {\n return\n yArray[lower] +\n ((yArray[upper] - yArray[lower]) * (x - xArray[lower])) /\n (xArray[upper] - xArray[lower]);\n } else {\n return\n yArray[lower] -\n ((yArray[lower] - yArray[upper]) * (x - xArray[lower])) /\n (xArray[upper] - xArray[lower]);\n }\n }\n }\n\n function _getStableMasterAndPoolManager(\n address agToken,\n address collateral\n ) internal view returns (address stableMaster, address poolManager) {\n stableMaster = IAgTokenMainnet(agToken).stableMaster();\n (poolManager, , , ) = ROUTER.mapPoolManagers(stableMaster, collateral);\n }\n\n // ========================= CONSTANTS AND INITIALIZERS ========================\n\n IAngleRouter public constant ROUTER = IAngleRouter(0xBB755240596530be0c1DE5DFD77ec6398471561d);\n ICore public constant CORE = ICore(0x61ed74de9Ca5796cF2F8fD60D54160D47E30B7c3);\n\n bytes32 public constant STABLE = keccak256(\"STABLE\");\n uint256 public constant BASE_PARAMS = 10 ** 9;\n\n error NotInitialized();\n error InvalidAmount();\n}\n" + }, + "contracts/utils/Constants.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\nerror InsufficientAssets();\n\n/// @title Constants\n/// @author Angle Labs, Inc.\n/// @notice Constants and errors for Angle Protocol contracts\ncontract Constants {\n uint256 internal constant _BASE_9 = 1e9;\n uint256 internal constant _BASE_18 = 1e18;\n uint256 internal constant _BASE_27 = 1e27;\n uint256 internal constant _BASE_36 = 1e36;\n}\n" + }, + "contracts/vaultManager/VaultManagerERC721.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\nimport \"./VaultManagerStorage.sol\";\n\n/// @title VaultManagerERC721\n/// @author Angle Labs, Inc.\n/// @dev Base ERC721 Implementation of VaultManager\nabstract contract VaultManagerERC721 is IERC721MetadataUpgradeable, VaultManagerStorage {\n using SafeERC20 for IERC20;\n using Address for address;\n\n /// @inheritdoc IERC721MetadataUpgradeable\n string public name;\n /// @inheritdoc IERC721MetadataUpgradeable\n string public symbol;\n\n // ================================= MODIFIERS =================================\n\n /// @notice Checks if the person interacting with the vault with `vaultID` is approved\n /// @param caller Address of the person seeking to interact with the vault\n /// @param vaultID ID of the concerned vault\n modifier onlyApprovedOrOwner(address caller, uint256 vaultID) {\n if (!_isApprovedOrOwner(caller, vaultID)) revert NotApproved();\n _;\n }\n\n // ================================ ERC721 LOGIC ===============================\n\n /// @notice Checks whether a given address is approved for a vault or owns this vault\n /// @param spender Address for which vault ownership should be checked\n /// @param vaultID ID of the vault to check\n /// @return Whether the `spender` address owns or is approved for `vaultID`\n function isApprovedOrOwner(address spender, uint256 vaultID) external view returns (bool) {\n return _isApprovedOrOwner(spender, vaultID);\n }\n\n /// @inheritdoc IERC721MetadataUpgradeable\n function tokenURI(uint256 vaultID) external view returns (string memory) {\n if (!_exists(vaultID)) revert NonexistentVault();\n // There is no vault with `vaultID` equal to 0, so the following variable is\n // always greater than zero\n uint256 temp = vaultID;\n uint256 digits;\n while (temp != 0) {\n ++digits;\n temp /= 10;\n }\n bytes memory buffer = new bytes(digits);\n while (vaultID != 0) {\n digits -= 1;\n buffer[digits] = bytes1(uint8(48 + uint256(vaultID % 10)));\n vaultID /= 10;\n }\n return bytes(_baseURI).length != 0 ? string(abi.encodePacked(_baseURI, string(buffer))) : \"\";\n }\n\n /// @inheritdoc IERC721Upgradeable\n function balanceOf(address owner) external view returns (uint256) {\n if (owner == address(0)) revert ZeroAddress();\n return _balances[owner];\n }\n\n /// @inheritdoc IERC721Upgradeable\n function ownerOf(uint256 vaultID) external view returns (address) {\n return _ownerOf(vaultID);\n }\n\n /// @inheritdoc IERC721Upgradeable\n function approve(address to, uint256 vaultID) external {\n address owner = _ownerOf(vaultID);\n if (to == owner) revert ApprovalToOwner();\n if (msg.sender != owner && !isApprovedForAll(owner, msg.sender)) revert NotApproved();\n\n _approve(to, vaultID);\n }\n\n /// @inheritdoc IERC721Upgradeable\n function getApproved(uint256 vaultID) external view returns (address) {\n if (!_exists(vaultID)) revert NonexistentVault();\n return _getApproved(vaultID);\n }\n\n /// @inheritdoc IERC721Upgradeable\n function setApprovalForAll(address operator, bool approved) external {\n _setApprovalForAll(msg.sender, operator, approved);\n }\n\n /// @inheritdoc IERC721Upgradeable\n function isApprovedForAll(address owner, address operator) public view returns (bool) {\n return _operatorApprovals[owner][operator] == 1;\n }\n\n /// @inheritdoc IERC721Upgradeable\n function transferFrom(address from, address to, uint256 vaultID) external onlyApprovedOrOwner(msg.sender, vaultID) {\n _transfer(from, to, vaultID);\n }\n\n /// @inheritdoc IERC721Upgradeable\n function safeTransferFrom(address from, address to, uint256 vaultID) external {\n safeTransferFrom(from, to, vaultID, \"\");\n }\n\n /// @inheritdoc IERC721Upgradeable\n function safeTransferFrom(\n address from,\n address to,\n uint256 vaultID,\n bytes memory _data\n ) public onlyApprovedOrOwner(msg.sender, vaultID) {\n _safeTransfer(from, to, vaultID, _data);\n }\n\n // ================================ ERC165 LOGIC ===============================\n\n /// @inheritdoc IERC165Upgradeable\n function supportsInterface(bytes4 interfaceId) external pure returns (bool) {\n return\n interfaceId == type(IERC721MetadataUpgradeable).interfaceId ||\n interfaceId == type(IERC721Upgradeable).interfaceId ||\n interfaceId == type(IVaultManager).interfaceId ||\n interfaceId == type(IERC165Upgradeable).interfaceId;\n }\n\n // ================== INTERNAL FUNCTIONS FOR THE ERC721 LOGIC ==================\n\n /// @notice Internal version of the `ownerOf` function\n function _ownerOf(uint256 vaultID) internal view returns (address owner) {\n owner = _owners[vaultID];\n if (owner == address(0)) revert NonexistentVault();\n }\n\n /// @notice Internal version of the `getApproved` function\n function _getApproved(uint256 vaultID) internal view returns (address) {\n return _vaultApprovals[vaultID];\n }\n\n /// @notice Internal version of the `safeTransferFrom` function (with the data parameter)\n function _safeTransfer(address from, address to, uint256 vaultID, bytes memory _data) internal {\n _transfer(from, to, vaultID);\n if (!_checkOnERC721Received(from, to, vaultID, _data)) revert NonERC721Receiver();\n }\n\n /// @notice Checks whether a vault exists\n /// @param vaultID ID of the vault to check\n /// @return Whether `vaultID` has been created\n function _exists(uint256 vaultID) internal view returns (bool) {\n return _owners[vaultID] != address(0);\n }\n\n /// @notice Internal version of the `isApprovedOrOwner` function\n function _isApprovedOrOwner(address spender, uint256 vaultID) internal view returns (bool) {\n // The following checks if the vault exists\n address owner = _ownerOf(vaultID);\n return (spender == owner || _getApproved(vaultID) == spender || _operatorApprovals[owner][spender] == 1);\n }\n\n /// @notice Internal version of the `createVault` function\n /// Mints `vaultID` and transfers it to `to`\n /// @dev This method is equivalent to the `_safeMint` method used in OpenZeppelin ERC721 contract\n /// @dev Emits a {Transfer} event\n function _mint(address to) internal returns (uint256 vaultID) {\n if (to == address(0)) revert ZeroAddress();\n\n unchecked {\n vaultIDCount += 1;\n }\n\n vaultID = vaultIDCount;\n _beforeTokenTransfer(address(0), to, vaultID);\n\n unchecked {\n _balances[to] += 1;\n }\n\n _owners[vaultID] = to;\n emit Transfer(address(0), to, vaultID);\n if (!_checkOnERC721Received(address(0), to, vaultID, \"\")) revert NonERC721Receiver();\n }\n\n /// @notice Destroys `vaultID`\n /// @dev `vaultID` must exist\n /// @dev Emits a {Transfer} event\n function _burn(uint256 vaultID) internal {\n address owner = _ownerOf(vaultID);\n\n _beforeTokenTransfer(owner, address(0), vaultID);\n // Clear approvals\n _approve(address(0), vaultID);\n // The following line cannot underflow as the owner's balance is necessarily\n // greater than 1\n unchecked {\n _balances[owner] -= 1;\n }\n delete _owners[vaultID];\n delete vaultData[vaultID];\n\n emit Transfer(owner, address(0), vaultID);\n }\n\n /// @notice Transfers `vaultID` from `from` to `to` as opposed to {transferFrom},\n /// this imposes no restrictions on msg.sender\n /// @dev `to` cannot be the zero address and `perpetualID` must be owned by `from`\n /// @dev Emits a {Transfer} event\n function _transfer(address from, address to, uint256 vaultID) internal {\n if (_ownerOf(vaultID) != from) revert NotApproved();\n if (to == address(0)) revert ZeroAddress();\n\n _beforeTokenTransfer(from, to, vaultID);\n\n // Clear approvals from the previous owner\n _approve(address(0), vaultID);\n unchecked {\n _balances[from] -= 1;\n _balances[to] += 1;\n }\n _owners[vaultID] = to;\n\n emit Transfer(from, to, vaultID);\n }\n\n /// @notice Approves `to` to operate on `vaultID`\n function _approve(address to, uint256 vaultID) internal {\n _vaultApprovals[vaultID] = to;\n emit Approval(_ownerOf(vaultID), to, vaultID);\n }\n\n /// @notice Internal version of the `setApprovalForAll` function\n /// @dev It contains an `approver` field to be used in case someone signs a permit for a particular\n /// address, and this signature is given to the contract by another address (like a router)\n function _setApprovalForAll(address approver, address operator, bool approved) internal {\n if (operator == approver) revert ApprovalToCaller();\n uint256 approval = approved ? 1 : 0;\n _operatorApprovals[approver][operator] = approval;\n emit ApprovalForAll(approver, operator, approved);\n }\n\n /// @notice Internal function to invoke {IERC721Receiver-onERC721Received} on a target address\n /// The call is not executed if the target address is not a contract\n /// @param from Address representing the previous owner of the given token ID\n /// @param to Target address that will receive the tokens\n /// @param vaultID ID of the token to be transferred\n /// @param _data Bytes optional data to send along with the call\n /// @return Bool whether the call correctly returned the expected value\n function _checkOnERC721Received(\n address from,\n address to,\n uint256 vaultID,\n bytes memory _data\n ) private returns (bool) {\n if (to.isContract()) {\n try IERC721ReceiverUpgradeable(to).onERC721Received(msg.sender, from, vaultID, _data) returns (\n bytes4 retval\n ) {\n return retval == IERC721ReceiverUpgradeable.onERC721Received.selector;\n } catch (bytes memory reason) {\n if (reason.length == 0) {\n revert NonERC721Receiver();\n } else {\n // solhint-disable-next-line no-inline-assembly\n assembly {\n revert(add(32, reason), mload(reason))\n }\n }\n }\n } else {\n return true;\n }\n }\n\n /// @notice Hook that is called before any token transfer. This includes minting and burning.\n /// Calling conditions:\n ///\n /// - When `from` and `to` are both non-zero, `from`'s `vaultID` will be\n /// transferred to `to`.\n /// - When `from` is zero, `vaultID` will be minted for `to`.\n /// - When `to` is zero, `from`'s `vaultID` will be burned.\n /// - `from` and `to` are never both zero.\n function _beforeTokenTransfer(address from, address to, uint256 vaultID) internal virtual {}\n\n /// @notice Get `whitelistingActivated` in storage only if needed\n function _whitelistingActivated() internal view virtual returns (bool) {\n return whitelistingActivated;\n }\n}\n" + }, + "contracts/vaultManager/VaultManagerPermit.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\nimport \"./VaultManagerERC721.sol\";\nimport \"../interfaces/external/IERC1271.sol\";\n\n/// @title VaultManagerPermit\n/// @author Angle Labs, Inc.\n/// @dev Base Implementation of permit functions for the `VaultManager` contract\nabstract contract VaultManagerPermit is Initializable, VaultManagerERC721 {\n using Address for address;\n\n mapping(address => uint256) private _nonces;\n /* solhint-disable var-name-mixedcase */\n bytes32 private _HASHED_NAME;\n bytes32 private _HASHED_VERSION;\n bytes32 private _PERMIT_TYPEHASH;\n /* solhint-enable var-name-mixedcase */\n\n error ExpiredDeadline();\n error InvalidSignature();\n\n //solhint-disable-next-line\n function __ERC721Permit_init(string memory _name) internal onlyInitializing {\n _PERMIT_TYPEHASH = keccak256(\n \"Permit(address owner,address spender,bool approved,uint256 nonce,uint256 deadline)\"\n );\n _HASHED_NAME = keccak256(bytes(_name));\n _HASHED_VERSION = keccak256(bytes(\"1\"));\n }\n\n /// @notice Allows an address to give or revoke approval for all its vaults to another address\n /// @param owner Address signing the permit and giving (or revoking) its approval for all the controlled vaults\n /// @param spender Address to give approval to\n /// @param approved Whether to give or revoke the approval\n /// @param deadline Deadline parameter for the signature to be valid\n /// @dev The `v`, `r`, and `s` parameters are used as signature data\n function permit(\n address owner,\n address spender,\n bool approved,\n uint256 deadline,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) external {\n if (block.timestamp > deadline) revert ExpiredDeadline();\n // Additional signature checks performed in the `ECDSAUpgradeable.recover` function\n if (uint256(s) > 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D576E7357A4501DDFE92F46681B20A0 || (v != 27 && v != 28))\n revert InvalidSignature();\n\n bytes32 digest = keccak256(\n abi.encodePacked(\n \"\\x19\\x01\",\n _domainSeparatorV4(),\n keccak256(\n abi.encode(\n _PERMIT_TYPEHASH,\n // 0x3f43a9c6bafb5c7aab4e0cfe239dc5d4c15caf0381c6104188191f78a6640bd8,\n owner,\n spender,\n approved,\n _useNonce(owner),\n deadline\n )\n )\n )\n );\n if (owner.isContract()) {\n if (IERC1271(owner).isValidSignature(digest, abi.encodePacked(r, s, v)) != 0x1626ba7e)\n revert InvalidSignature();\n } else {\n address signer = ecrecover(digest, v, r, s);\n if (signer != owner || signer == address(0)) revert InvalidSignature();\n }\n\n _setApprovalForAll(owner, spender, approved);\n }\n\n /// @notice Returns the current nonce for an `owner` address\n function nonces(address owner) public view returns (uint256) {\n return _nonces[owner];\n }\n\n /// @notice Returns the domain separator for the current chain.\n // solhint-disable-next-line func-name-mixedcase\n function DOMAIN_SEPARATOR() external view returns (bytes32) {\n return _domainSeparatorV4();\n }\n\n /// @notice Internal version of the `DOMAIN_SEPARATOR` function\n function _domainSeparatorV4() internal view returns (bytes32) {\n return\n keccak256(\n abi.encode(\n // keccak256('EIP712Domain(string name,string version,uint256 chainId,address verifyingContract)')\n 0x8b73c3c69bb8fe3d512ecc4cf759cc79239f7b179b0ffacaa9a75d522b39400f,\n _HASHED_NAME,\n _HASHED_VERSION,\n block.chainid,\n address(this)\n )\n );\n }\n\n /// @notice Consumes a nonce for an address: returns the current value and increments it\n function _useNonce(address owner) internal returns (uint256 current) {\n current = _nonces[owner];\n _nonces[owner] = current + 1;\n }\n\n uint256[49] private __gap;\n}\n" + }, + "contracts/vaultManager/VaultManagerStorage.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\nimport \"@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/token/ERC20/extensions/draft-IERC20PermitUpgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/token/ERC721/IERC721ReceiverUpgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/interfaces/IERC721MetadataUpgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/utils/introspection/IERC165Upgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/utils/AddressUpgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/security/ReentrancyGuardUpgradeable.sol\";\nimport \"@openzeppelin/contracts/token/ERC20/extensions/IERC20Metadata.sol\";\nimport \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\nimport \"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\";\n\nimport \"../interfaces/IAgToken.sol\";\nimport \"../interfaces/IOracle.sol\";\nimport \"../interfaces/ISwapper.sol\";\nimport \"../interfaces/ITreasury.sol\";\nimport \"../interfaces/IVaultManager.sol\";\nimport \"../interfaces/governance/IVeBoostProxy.sol\";\n\n/// @title VaultManagerStorage\n/// @author Angle Labs, Inc.\n/// @dev Variables, references, parameters and events needed in the `VaultManager` contract\n// solhint-disable-next-line max-states-count\ncontract VaultManagerStorage is IVaultManagerStorage, Initializable, ReentrancyGuardUpgradeable {\n /// @notice Base used for parameter computation: almost all the parameters of this contract are set in `BASE_PARAMS`\n uint256 public constant BASE_PARAMS = 10 ** 9;\n /// @notice Base used for interest rate computation\n uint256 public constant BASE_INTEREST = 10 ** 27;\n /// @notice Used for interest rate computation\n uint256 public constant HALF_BASE_INTEREST = 10 ** 27 / 2;\n\n // ================================= REFERENCES ================================\n\n /// @inheritdoc IVaultManagerStorage\n ITreasury public treasury;\n /// @inheritdoc IVaultManagerStorage\n IERC20 public collateral;\n /// @inheritdoc IVaultManagerStorage\n IAgToken public stablecoin;\n /// @inheritdoc IVaultManagerStorage\n IOracle public oracle;\n /// @notice Reference to the contract which computes adjusted veANGLE balances for liquidators boosts\n IVeBoostProxy public veBoostProxy;\n /// @notice Base of the collateral\n uint256 internal _collatBase;\n\n // ================================= PARAMETERS ================================\n // Unless specified otherwise, parameters of this contract are expressed in `BASE_PARAMS`\n\n /// @notice Maximum amount of stablecoins that can be issued with this contract (in `BASE_TOKENS`). This parameter should\n /// not be bigger than `type(uint256).max / BASE_INTEREST` otherwise there may be some overflows in the `increaseDebt` function\n uint256 public debtCeiling;\n /// @notice Threshold veANGLE balance values for the computation of the boost for liquidators: the length of this array\n /// should normally be 2. The base of the x-values in this array should be `BASE_TOKENS`\n uint256[] public xLiquidationBoost;\n /// @notice Values of the liquidation boost at the threshold values of x\n uint256[] public yLiquidationBoost;\n /// @inheritdoc IVaultManagerStorage\n uint64 public collateralFactor;\n /// @notice Maximum Health factor at which a vault can end up after a liquidation (unless it's fully liquidated)\n uint64 public targetHealthFactor;\n /// @notice Upfront fee taken when borrowing stablecoins: this fee is optional and should in practice not be used\n uint64 public borrowFee;\n /// @notice Upfront fee taken when repaying stablecoins: this fee is optional as well. It should be smaller\n /// than the liquidation surcharge (cf below) to avoid exploits where people voluntarily get liquidated at a 0\n /// discount to pay smaller repaying fees\n uint64 public repayFee;\n /// @notice Per second interest taken to borrowers taking agToken loans. Contrarily to other parameters, it is set in `BASE_INTEREST`\n /// that is to say in base 10**27\n uint64 public interestRate;\n /// @notice Fee taken by the protocol during a liquidation. Technically, this value is not the fee per se, it's 1 - fee.\n /// For instance for a 2% fee, `liquidationSurcharge` should be 98%\n uint64 public liquidationSurcharge;\n /// @notice Maximum discount given to liquidators\n uint64 public maxLiquidationDiscount;\n /// @notice Whether whitelisting is required to own a vault or not\n bool public whitelistingActivated;\n /// @notice Whether the contract is paused or not\n bool public paused;\n\n // ================================= VARIABLES =================================\n\n /// @notice Timestamp at which the `interestAccumulator` was updated\n uint256 public lastInterestAccumulatorUpdated;\n /// @inheritdoc IVaultManagerStorage\n uint256 public interestAccumulator;\n /// @inheritdoc IVaultManagerStorage\n uint256 public totalNormalizedDebt;\n /// @notice Surplus accumulated by the contract: surplus is always in stablecoins, and is then reset\n /// when the value is communicated to the treasury contract\n uint256 public surplus;\n /// @notice Bad debt made from liquidated vaults which ended up having no collateral and a positive amount\n /// of stablecoins\n uint256 public badDebt;\n\n // ================================== MAPPINGS =================================\n\n /// @inheritdoc IVaultManagerStorage\n mapping(uint256 => Vault) public vaultData;\n /// @notice Maps an address to 1 if it's whitelisted and can open or own a vault\n mapping(address => uint256) public isWhitelisted;\n\n // ================================ ERC721 DATA ================================\n\n /// @inheritdoc IVaultManagerStorage\n uint256 public vaultIDCount;\n\n /// @notice URI\n string internal _baseURI;\n\n // Mapping from `vaultID` to owner address\n mapping(uint256 => address) internal _owners;\n\n // Mapping from owner address to vault owned count\n mapping(address => uint256) internal _balances;\n\n // Mapping from `vaultID` to approved address\n mapping(uint256 => address) internal _vaultApprovals;\n\n // Mapping from owner to operator approvals\n mapping(address => mapping(address => uint256)) internal _operatorApprovals;\n\n uint256[50] private __gap;\n\n // =================================== EVENTS ==================================\n\n event AccruedToTreasury(uint256 surplusEndValue, uint256 badDebtEndValue);\n event CollateralAmountUpdated(uint256 vaultID, uint256 collateralAmount, uint8 isIncrease);\n event InterestAccumulatorUpdated(uint256 value, uint256 timestamp);\n event InternalDebtUpdated(uint256 vaultID, uint256 internalAmount, uint8 isIncrease);\n event FiledUint64(uint64 param, bytes32 what);\n event DebtCeilingUpdated(uint256 debtCeiling);\n event LiquidationBoostParametersUpdated(address indexed _veBoostProxy, uint256[] xBoost, uint256[] yBoost);\n event LiquidatedVaults(uint256[] vaultIDs);\n event DebtTransferred(uint256 srcVaultID, uint256 dstVaultID, address dstVaultManager, uint256 amount);\n\n // =================================== ERRORS ==================================\n\n error ApprovalToOwner();\n error ApprovalToCaller();\n error DustyLeftoverAmount();\n error DebtCeilingExceeded();\n error HealthyVault();\n error IncompatibleLengths();\n error InsolventVault();\n error InvalidParameterValue();\n error InvalidParameterType();\n error InvalidSetOfParameters();\n error InvalidTreasury();\n error NonERC721Receiver();\n error NonexistentVault();\n error NotApproved();\n error NotGovernor();\n error NotGovernorOrGuardian();\n error NotTreasury();\n error NotWhitelisted();\n error NotVaultManager();\n error Paused();\n error TooHighParameterValue();\n error TooSmallParameterValue();\n error ZeroAddress();\n\n /// @custom:oz-upgrades-unsafe-allow constructor\n constructor() initializer {}\n}\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 1000000 + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers", + "metadata", + "devdoc", + "userdoc", + "storageLayout", + "evm.gasEstimates", + "devdoc", + "userdoc" + ], + "": [ + "ast" + ] + } + }, + "metadata": { + "useLiteralContent": true + } + } +} \ No newline at end of file diff --git a/deployments/polygon/AgTokenSideChainMultiBridge_Implementation.json b/deployments/polygon/AgTokenSideChainMultiBridge_Implementation.json new file mode 100644 index 00000000..0f90e293 --- /dev/null +++ b/deployments/polygon/AgTokenSideChainMultiBridge_Implementation.json @@ -0,0 +1,1871 @@ +{ + "address": "0x4924E9740d317c58Edce2f02b4EF747Bc9046ed5", + "abi": [ + { + "inputs": [], + "name": "AssetStillControlledInReserves", + "type": "error" + }, + { + "inputs": [], + "name": "BurnAmountExceedsAllowance", + "type": "error" + }, + { + "inputs": [], + "name": "HourlyLimitExceeded", + "type": "error" + }, + { + "inputs": [], + "name": "InvalidSender", + "type": "error" + }, + { + "inputs": [], + "name": "InvalidToken", + "type": "error" + }, + { + "inputs": [], + "name": "InvalidTreasury", + "type": "error" + }, + { + "inputs": [], + "name": "NotGovernor", + "type": "error" + }, + { + "inputs": [], + "name": "NotGovernorOrGuardian", + "type": "error" + }, + { + "inputs": [], + "name": "NotMinter", + "type": "error" + }, + { + "inputs": [], + "name": "NotTreasury", + "type": "error" + }, + { + "inputs": [], + "name": "TooBigAmount", + "type": "error" + }, + { + "inputs": [], + "name": "TooHighParameterValue", + "type": "error" + }, + { + "inputs": [], + "name": "ZeroAddress", + "type": "error" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "owner", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "spender", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "value", + "type": "uint256" + } + ], + "name": "Approval", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "bridgeToken", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "limit", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "hourlyLimit", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint64", + "name": "fee", + "type": "uint64" + }, + { + "indexed": false, + "internalType": "bool", + "name": "paused", + "type": "bool" + } + ], + "name": "BridgeTokenAdded", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "bridgeToken", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint64", + "name": "fee", + "type": "uint64" + } + ], + "name": "BridgeTokenFeeUpdated", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "bridgeToken", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "hourlyLimit", + "type": "uint256" + } + ], + "name": "BridgeTokenHourlyLimitUpdated", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "bridgeToken", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "limit", + "type": "uint256" + } + ], + "name": "BridgeTokenLimitUpdated", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "bridgeToken", + "type": "address" + } + ], + "name": "BridgeTokenRemoved", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "bridgeToken", + "type": "address" + }, + { + "indexed": false, + "internalType": "bool", + "name": "toggleStatus", + "type": "bool" + } + ], + "name": "BridgeTokenToggled", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "theAddress", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "toggleStatus", + "type": "uint256" + } + ], + "name": "FeeToggled", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint256", + "name": "hourlyLimit", + "type": "uint256" + } + ], + "name": "HourlyLimitUpdated", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint8", + "name": "version", + "type": "uint8" + } + ], + "name": "Initialized", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "minter", + "type": "address" + } + ], + "name": "MinterToggled", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "token", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "Recovered", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "from", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "value", + "type": "uint256" + } + ], + "name": "Transfer", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "_treasury", + "type": "address" + } + ], + "name": "TreasuryUpdated", + "type": "event" + }, + { + "inputs": [], + "name": "BASE_PARAMS", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "DOMAIN_SEPARATOR", + "outputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "bridgeToken", + "type": "address" + }, + { + "internalType": "uint256", + "name": "limit", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "hourlyLimit", + "type": "uint256" + }, + { + "internalType": "uint64", + "name": "fee", + "type": "uint64" + }, + { + "internalType": "bool", + "name": "paused", + "type": "bool" + } + ], + "name": "addBridgeToken", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "minter", + "type": "address" + } + ], + "name": "addMinter", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "allBridgeTokens", + "outputs": [ + { + "internalType": "address[]", + "name": "", + "type": "address[]" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "owner", + "type": "address" + }, + { + "internalType": "address", + "name": "spender", + "type": "address" + } + ], + "name": "allowance", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "spender", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "approve", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "balanceOf", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "name": "bridgeTokensList", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "bridges", + "outputs": [ + { + "internalType": "uint256", + "name": "limit", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "hourlyLimit", + "type": "uint256" + }, + { + "internalType": "uint64", + "name": "fee", + "type": "uint64" + }, + { + "internalType": "bool", + "name": "allowed", + "type": "bool" + }, + { + "internalType": "bool", + "name": "paused", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + }, + { + "internalType": "address", + "name": "burner", + "type": "address" + }, + { + "internalType": "address", + "name": "sender", + "type": "address" + } + ], + "name": "burnFrom", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + }, + { + "internalType": "address", + "name": "burner", + "type": "address" + } + ], + "name": "burnSelf", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "burnStablecoin", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "chainTotalHourlyLimit", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "name": "chainTotalUsage", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "currentTotalUsage", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "bridgeToken", + "type": "address" + } + ], + "name": "currentUsage", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "decimals", + "outputs": [ + { + "internalType": "uint8", + "name": "", + "type": "uint8" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "spender", + "type": "address" + }, + { + "internalType": "uint256", + "name": "subtractedValue", + "type": "uint256" + } + ], + "name": "decreaseAllowance", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "spender", + "type": "address" + }, + { + "internalType": "uint256", + "name": "addedValue", + "type": "uint256" + } + ], + "name": "increaseAllowance", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "string", + "name": "name_", + "type": "string" + }, + { + "internalType": "string", + "name": "symbol_", + "type": "string" + }, + { + "internalType": "address", + "name": "_treasury", + "type": "address" + } + ], + "name": "initialize", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "isFeeExempt", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "isMinter", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "account", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "mint", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "name", + "outputs": [ + { + "internalType": "string", + "name": "", + "type": "string" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "owner", + "type": "address" + } + ], + "name": "nonces", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "owner", + "type": "address" + }, + { + "internalType": "address", + "name": "spender", + "type": "address" + }, + { + "internalType": "uint256", + "name": "value", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "deadline", + "type": "uint256" + }, + { + "internalType": "uint8", + "name": "v", + "type": "uint8" + }, + { + "internalType": "bytes32", + "name": "r", + "type": "bytes32" + }, + { + "internalType": "bytes32", + "name": "s", + "type": "bytes32" + } + ], + "name": "permit", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "tokenAddress", + "type": "address" + }, + { + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amountToRecover", + "type": "uint256" + } + ], + "name": "recoverERC20", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "bridgeToken", + "type": "address" + } + ], + "name": "removeBridgeToken", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "minter", + "type": "address" + } + ], + "name": "removeMinter", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "hourlyLimit", + "type": "uint256" + } + ], + "name": "setChainTotalHourlyLimit", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "bridgeToken", + "type": "address" + }, + { + "internalType": "uint256", + "name": "hourlyLimit", + "type": "uint256" + } + ], + "name": "setHourlyLimit", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "bridgeToken", + "type": "address" + }, + { + "internalType": "uint256", + "name": "limit", + "type": "uint256" + } + ], + "name": "setLimit", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "bridgeToken", + "type": "address" + }, + { + "internalType": "uint64", + "name": "fee", + "type": "uint64" + } + ], + "name": "setSwapFee", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_treasury", + "type": "address" + } + ], + "name": "setTreasury", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "bridgeToken", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + }, + { + "internalType": "address", + "name": "to", + "type": "address" + } + ], + "name": "swapIn", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "bridgeToken", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + }, + { + "internalType": "address", + "name": "to", + "type": "address" + } + ], + "name": "swapOut", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "symbol", + "outputs": [ + { + "internalType": "string", + "name": "", + "type": "string" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "bridgeToken", + "type": "address" + } + ], + "name": "toggleBridge", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "theAddress", + "type": "address" + } + ], + "name": "toggleFeesForAddress", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "totalSupply", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "transfer", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "from", + "type": "address" + }, + { + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "transferFrom", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "treasury", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + }, + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "name": "usage", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + } + ], + "transactionHash": "0x8666c37e68a26f2b3ee110baf962cb2f288cc23ca66e295bf4ffb47f96a10a20", + "receipt": { + "to": null, + "from": "0xfdA462548Ce04282f4B6D6619823a7C64Fdc0185", + "contractAddress": "0x4924E9740d317c58Edce2f02b4EF747Bc9046ed5", + "transactionIndex": 36, + "gasUsed": "3966151", + "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000008000000000000000000000000040000000000000000000000000000000800000000000000000000100000000000000000000000000000000000000000000000000000000000080000000000100000000000000000000000000000000000000000002000080000000000000000000200000000000000000000000000400000000000000000000000000000000005000000000000000000001000000040000000800000000000000100000000000000000000000000000100000000000000000000000000000200000002000100000", + "blockHash": "0xbe9887547659e263718d8fe01e911af93732b42b53f6d31d9716566ea0bda805", + "transactionHash": "0x8666c37e68a26f2b3ee110baf962cb2f288cc23ca66e295bf4ffb47f96a10a20", + "logs": [ + { + "transactionIndex": 36, + "blockNumber": 52158243, + "transactionHash": "0x8666c37e68a26f2b3ee110baf962cb2f288cc23ca66e295bf4ffb47f96a10a20", + "address": "0x4924E9740d317c58Edce2f02b4EF747Bc9046ed5", + "topics": [ + "0x7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb3847402498" + ], + "data": "0x0000000000000000000000000000000000000000000000000000000000000001", + "logIndex": 173, + "blockHash": "0xbe9887547659e263718d8fe01e911af93732b42b53f6d31d9716566ea0bda805" + }, + { + "transactionIndex": 36, + "blockNumber": 52158243, + "transactionHash": "0x8666c37e68a26f2b3ee110baf962cb2f288cc23ca66e295bf4ffb47f96a10a20", + "address": "0x0000000000000000000000000000000000001010", + "topics": [ + "0x4dfe1bbbcf077ddc3e01291eea2d5c70c2b422b415d95645b9adcfd678cb1d63", + "0x0000000000000000000000000000000000000000000000000000000000001010", + "0x000000000000000000000000fda462548ce04282f4b6d6619823a7c64fdc0185", + "0x000000000000000000000000b9ede6f94d192073d8eaf85f8db677133d483249" + ], + "data": "0x000000000000000000000000000000000000000000000000022a7729cb1ad9d900000000000000000000000000000000000000000000000403df25979a0ddd360000000000000000000000000000000000000000000003dac7ae55cb91e81bbc00000000000000000000000000000000000000000000000401b4ae6dcef3035d0000000000000000000000000000000000000000000003dac9d8ccf55d02f595", + "logIndex": 174, + "blockHash": "0xbe9887547659e263718d8fe01e911af93732b42b53f6d31d9716566ea0bda805" + } + ], + "blockNumber": 52158243, + "cumulativeGasUsed": "9888193", + "status": 1, + "byzantium": true + }, + "args": [], + "numDeployments": 1, + "solcInputHash": "871924e0c138825a2736b76def8fef8d", + "metadata": "{\"compiler\":{\"version\":\"0.8.17+commit.8df45f5f\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[],\"name\":\"AssetStillControlledInReserves\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"BurnAmountExceedsAllowance\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"HourlyLimitExceeded\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidSender\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidToken\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidTreasury\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"NotGovernor\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"NotGovernorOrGuardian\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"NotMinter\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"NotTreasury\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"TooBigAmount\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"TooHighParameterValue\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ZeroAddress\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"spender\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"}],\"name\":\"Approval\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"bridgeToken\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"limit\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"hourlyLimit\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"fee\",\"type\":\"uint64\"},{\"indexed\":false,\"internalType\":\"bool\",\"name\":\"paused\",\"type\":\"bool\"}],\"name\":\"BridgeTokenAdded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"bridgeToken\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"fee\",\"type\":\"uint64\"}],\"name\":\"BridgeTokenFeeUpdated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"bridgeToken\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"hourlyLimit\",\"type\":\"uint256\"}],\"name\":\"BridgeTokenHourlyLimitUpdated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"bridgeToken\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"limit\",\"type\":\"uint256\"}],\"name\":\"BridgeTokenLimitUpdated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"bridgeToken\",\"type\":\"address\"}],\"name\":\"BridgeTokenRemoved\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"bridgeToken\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"bool\",\"name\":\"toggleStatus\",\"type\":\"bool\"}],\"name\":\"BridgeTokenToggled\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"theAddress\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"toggleStatus\",\"type\":\"uint256\"}],\"name\":\"FeeToggled\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"hourlyLimit\",\"type\":\"uint256\"}],\"name\":\"HourlyLimitUpdated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint8\",\"name\":\"version\",\"type\":\"uint8\"}],\"name\":\"Initialized\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"minter\",\"type\":\"address\"}],\"name\":\"MinterToggled\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"Recovered\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"}],\"name\":\"Transfer\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"_treasury\",\"type\":\"address\"}],\"name\":\"TreasuryUpdated\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"BASE_PARAMS\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"DOMAIN_SEPARATOR\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"bridgeToken\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"limit\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"hourlyLimit\",\"type\":\"uint256\"},{\"internalType\":\"uint64\",\"name\":\"fee\",\"type\":\"uint64\"},{\"internalType\":\"bool\",\"name\":\"paused\",\"type\":\"bool\"}],\"name\":\"addBridgeToken\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"minter\",\"type\":\"address\"}],\"name\":\"addMinter\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"allBridgeTokens\",\"outputs\":[{\"internalType\":\"address[]\",\"name\":\"\",\"type\":\"address[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"spender\",\"type\":\"address\"}],\"name\":\"allowance\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"spender\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"approve\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"}],\"name\":\"balanceOf\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"name\":\"bridgeTokensList\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"bridges\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"limit\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"hourlyLimit\",\"type\":\"uint256\"},{\"internalType\":\"uint64\",\"name\":\"fee\",\"type\":\"uint64\"},{\"internalType\":\"bool\",\"name\":\"allowed\",\"type\":\"bool\"},{\"internalType\":\"bool\",\"name\":\"paused\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"burner\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"}],\"name\":\"burnFrom\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"burner\",\"type\":\"address\"}],\"name\":\"burnSelf\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"burnStablecoin\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"chainTotalHourlyLimit\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"name\":\"chainTotalUsage\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"currentTotalUsage\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"bridgeToken\",\"type\":\"address\"}],\"name\":\"currentUsage\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"decimals\",\"outputs\":[{\"internalType\":\"uint8\",\"name\":\"\",\"type\":\"uint8\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"spender\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"subtractedValue\",\"type\":\"uint256\"}],\"name\":\"decreaseAllowance\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"spender\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"addedValue\",\"type\":\"uint256\"}],\"name\":\"increaseAllowance\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"string\",\"name\":\"name_\",\"type\":\"string\"},{\"internalType\":\"string\",\"name\":\"symbol_\",\"type\":\"string\"},{\"internalType\":\"address\",\"name\":\"_treasury\",\"type\":\"address\"}],\"name\":\"initialize\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"isFeeExempt\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"isMinter\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"mint\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"name\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"}],\"name\":\"nonces\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"spender\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"deadline\",\"type\":\"uint256\"},{\"internalType\":\"uint8\",\"name\":\"v\",\"type\":\"uint8\"},{\"internalType\":\"bytes32\",\"name\":\"r\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32\",\"name\":\"s\",\"type\":\"bytes32\"}],\"name\":\"permit\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"tokenAddress\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amountToRecover\",\"type\":\"uint256\"}],\"name\":\"recoverERC20\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"bridgeToken\",\"type\":\"address\"}],\"name\":\"removeBridgeToken\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"minter\",\"type\":\"address\"}],\"name\":\"removeMinter\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"hourlyLimit\",\"type\":\"uint256\"}],\"name\":\"setChainTotalHourlyLimit\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"bridgeToken\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"hourlyLimit\",\"type\":\"uint256\"}],\"name\":\"setHourlyLimit\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"bridgeToken\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"limit\",\"type\":\"uint256\"}],\"name\":\"setLimit\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"bridgeToken\",\"type\":\"address\"},{\"internalType\":\"uint64\",\"name\":\"fee\",\"type\":\"uint64\"}],\"name\":\"setSwapFee\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_treasury\",\"type\":\"address\"}],\"name\":\"setTreasury\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"bridgeToken\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"swapIn\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"bridgeToken\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"swapOut\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"symbol\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"bridgeToken\",\"type\":\"address\"}],\"name\":\"toggleBridge\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"theAddress\",\"type\":\"address\"}],\"name\":\"toggleFeesForAddress\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"totalSupply\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"transfer\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"transferFrom\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"treasury\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"name\":\"usage\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"}],\"devdoc\":{\"author\":\"Angle Labs, Inc.\",\"details\":\"This contract supports bridge tokens having a minting right on the stablecoin (also referred to as the canonical or the native token)\",\"kind\":\"dev\",\"methods\":{\"DOMAIN_SEPARATOR()\":{\"details\":\"See {IERC20Permit-DOMAIN_SEPARATOR}.\"},\"addBridgeToken(address,uint256,uint256,uint64,bool)\":{\"params\":{\"bridgeToken\":\"Bridge token to add: it should be a version of the stablecoin from another bridge\",\"fee\":\"Fee taken upon swapping for or against this token\",\"hourlyLimit\":\"Limit on the hourly volume for this bridge\",\"limit\":\"Limit on the balance of bridge token this contract could hold\",\"paused\":\"Whether swapping for this token should be paused or not\"}},\"addMinter(address)\":{\"details\":\"Zero address checks are performed directly in the `Treasury` contract\",\"params\":{\"minter\":\"Minter address to add\"}},\"allBridgeTokens()\":{\"details\":\"Helpful for UIs\"},\"allowance(address,address)\":{\"details\":\"See {IERC20-allowance}.\"},\"approve(address,uint256)\":{\"details\":\"See {IERC20-approve}. NOTE: If `amount` is the maximum `uint256`, the allowance is not updated on `transferFrom`. This is semantically equivalent to an infinite approval. Requirements: - `spender` cannot be the zero address.\"},\"balanceOf(address)\":{\"details\":\"See {IERC20-balanceOf}.\"},\"burnFrom(uint256,address,address)\":{\"details\":\"This method is to be called by a contract with the minter right after being requested to do so by a `sender` address willing to burn tokens from another `burner` addressThe method checks the allowance between the `sender` and the `burner`\",\"params\":{\"amount\":\"Amount of tokens to burn\",\"burner\":\"Address to burn from\",\"sender\":\"Address which requested the burn from `burner`\"}},\"burnSelf(uint256,address)\":{\"details\":\"This method is to be called by a contract with a minter right on the AgToken after being requested to do so by an address willing to burn tokens from its address\",\"params\":{\"amount\":\"Amount of tokens to burn\",\"burner\":\"Address to burn from\"}},\"burnStablecoin(uint256)\":{\"details\":\"This function can typically be called if there is a settlement mechanism to burn stablecoins\",\"params\":{\"amount\":\"Amount of stablecoins to burn\"}},\"currentTotalUsage()\":{\"details\":\"Helpful for UIs\"},\"currentUsage(address)\":{\"details\":\"Helpful for UIs\",\"params\":{\"bridgeToken\":\"Bridge used to mint\"}},\"decimals()\":{\"details\":\"Returns the number of decimals used to get its user representation. For example, if `decimals` equals `2`, a balance of `505` tokens should be displayed to a user as `5.05` (`505 / 10 ** 2`). Tokens usually opt for a value of 18, imitating the relationship between Ether and Wei. This is the value {ERC20} uses, unless this function is overridden; NOTE: This information is only used for _display_ purposes: it in no way affects any of the arithmetic of the contract, including {IERC20-balanceOf} and {IERC20-transfer}.\"},\"decreaseAllowance(address,uint256)\":{\"details\":\"Atomically decreases the allowance granted to `spender` by the caller. This is an alternative to {approve} that can be used as a mitigation for problems described in {IERC20-approve}. Emits an {Approval} event indicating the updated allowance. Requirements: - `spender` cannot be the zero address. - `spender` must have allowance for the caller of at least `subtractedValue`.\"},\"increaseAllowance(address,uint256)\":{\"details\":\"Atomically increases the allowance granted to `spender` by the caller. This is an alternative to {approve} that can be used as a mitigation for problems described in {IERC20-approve}. Emits an {Approval} event indicating the updated allowance. Requirements: - `spender` cannot be the zero address.\"},\"mint(address,uint256)\":{\"details\":\"The contracts allowed to issue agTokens are the `StableMaster` contract, `VaultManager` contracts associated to this stablecoin as well as the flash loan module (if activated) and potentially contracts whitelisted by governance\",\"params\":{\"account\":\"Address to mint to\",\"amount\":\"Amount to mint\"}},\"name()\":{\"details\":\"Returns the name of the token.\"},\"nonces(address)\":{\"details\":\"See {IERC20Permit-nonces}.\"},\"permit(address,address,uint256,uint256,uint8,bytes32,bytes32)\":{\"details\":\"See {IERC20Permit-permit}.\"},\"recoverERC20(address,address,uint256)\":{\"details\":\"Can be used to withdraw bridge tokens for them to be de-bridged on mainnet\"},\"removeBridgeToken(address)\":{\"params\":{\"bridgeToken\":\"Address of the bridge token to remove support for\"}},\"removeMinter(address)\":{\"details\":\"This function can also be called by a minter wishing to revoke itself\",\"params\":{\"minter\":\"Minter address to remove\"}},\"setTreasury(address)\":{\"params\":{\"_treasury\":\"New treasury address\"}},\"swapIn(address,uint256,address)\":{\"details\":\"Some fees may be taken by the protocol depending on the token used and on the address calling\",\"params\":{\"amount\":\"Amount of bridge tokens to send\",\"bridgeToken\":\"Bridge token to use to mint\",\"to\":\"Address to which the stablecoin should be sent\"},\"returns\":{\"_0\":\"Amount of the canonical stablecoin actually minted\"}},\"swapOut(address,uint256,address)\":{\"details\":\"Some fees may be taken by the protocol depending on the token used and on the address calling\",\"params\":{\"amount\":\"Amount of canonical tokens to burn\",\"bridgeToken\":\"Bridge token required\",\"to\":\"Address to which the bridge token should be sent\"},\"returns\":{\"_0\":\"Amount of bridge tokens actually sent back\"}},\"symbol()\":{\"details\":\"Returns the symbol of the token, usually a shorter version of the name.\"},\"totalSupply()\":{\"details\":\"See {IERC20-totalSupply}.\"},\"transfer(address,uint256)\":{\"details\":\"See {IERC20-transfer}. Requirements: - `to` cannot be the zero address. - the caller must have a balance of at least `amount`.\"},\"transferFrom(address,address,uint256)\":{\"details\":\"See {IERC20-transferFrom}. Emits an {Approval} event indicating the updated allowance. This is not required by the EIP. See the note at the beginning of {ERC20}. NOTE: Does not update the allowance if the current allowance is the maximum `uint256`. Requirements: - `from` and `to` cannot be the zero address. - `from` must have a balance of at least `amount`. - the caller must have allowance for ``from``'s tokens of at least `amount`.\"}},\"title\":\"AgTokenSideChainMultiBridge\",\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{\"BASE_PARAMS()\":{\"notice\":\"Base used for fee computation\"},\"addBridgeToken(address,uint256,uint256,uint64,bool)\":{\"notice\":\"Adds support for a bridge token\"},\"addMinter(address)\":{\"notice\":\"Adds a minter in the contract\"},\"allBridgeTokens()\":{\"notice\":\"Returns the list of all supported bridge tokens\"},\"bridgeTokensList(uint256)\":{\"notice\":\"List of all bridge tokens\"},\"bridges(address)\":{\"notice\":\"Maps a bridge token to data\"},\"burnFrom(uint256,address,address)\":{\"notice\":\"Burns `amount` tokens from a `burner` address after being asked to by `sender`\"},\"burnSelf(uint256,address)\":{\"notice\":\"Burns `amount` tokens from a `burner` address\"},\"burnStablecoin(uint256)\":{\"notice\":\"Allows anyone to burn stablecoins\"},\"chainTotalHourlyLimit()\":{\"notice\":\"Limit to the amount of tokens that can be sent from that chain to another chain\"},\"chainTotalUsage(uint256)\":{\"notice\":\"Usage per hour on that chain. Maps an hourly timestamp to the total volume swapped out on the chain\"},\"currentTotalUsage()\":{\"notice\":\"Returns the current total volume on the chain for the current hour\"},\"currentUsage(address)\":{\"notice\":\"Returns the current volume for a bridge, for the current hour\"},\"initialize(string,string,address)\":{\"notice\":\"Initializes the `AgToken` contract\"},\"isFeeExempt(address)\":{\"notice\":\"Maps an address to whether it is exempt of fees for when it comes to swapping in and out\"},\"isMinter(address)\":{\"notice\":\"Checks whether an address has the right to mint agTokens\"},\"mint(address,uint256)\":{\"notice\":\"Lets the `StableMaster` contract or another whitelisted contract mint agTokens\"},\"recoverERC20(address,address,uint256)\":{\"notice\":\"Recovers any ERC20 token\"},\"removeBridgeToken(address)\":{\"notice\":\"Removes support for a token\"},\"removeMinter(address)\":{\"notice\":\"Removes a minter from the contract\"},\"setChainTotalHourlyLimit(uint256)\":{\"notice\":\"Updates the `chainTotalHourlyLimit` amount\"},\"setHourlyLimit(address,uint256)\":{\"notice\":\"Updates the `hourlyLimit` amount for `bridgeToken`\"},\"setLimit(address,uint256)\":{\"notice\":\"Updates the `limit` amount for `bridgeToken`\"},\"setSwapFee(address,uint64)\":{\"notice\":\"Updates the `fee` value for `bridgeToken`\"},\"setTreasury(address)\":{\"notice\":\"Sets a new treasury contract\"},\"swapIn(address,uint256,address)\":{\"notice\":\"Mints the canonical token from a supported bridge token\"},\"swapOut(address,uint256,address)\":{\"notice\":\"Burns the canonical token in exchange for a bridge token\"},\"toggleBridge(address)\":{\"notice\":\"Pauses or unpauses swapping in and out for a token\"},\"toggleFeesForAddress(address)\":{\"notice\":\"Toggles fees for the address `theAddress`\"},\"treasury()\":{\"notice\":\"Reference to the treasury contract which can grant minting rights\"},\"usage(address,uint256)\":{\"notice\":\"Maps a bridge token to the associated hourly volume\"}},\"notice\":\"Contract for Angle agTokens on other chains than Ethereum mainnet\",\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/agToken/AgTokenSideChainMultiBridge.sol\":\"AgTokenSideChainMultiBridge\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":1000000},\"remappings\":[]},\"sources\":{\"@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.7.0) (proxy/utils/Initializable.sol)\\n\\npragma solidity ^0.8.2;\\n\\nimport \\\"../../utils/AddressUpgradeable.sol\\\";\\n\\n/**\\n * @dev This is a base contract to aid in writing upgradeable contracts, or any kind of contract that will be deployed\\n * behind a proxy. Since proxied contracts do not make use of a constructor, it's common to move constructor logic to an\\n * external initializer function, usually called `initialize`. It then becomes necessary to protect this initializer\\n * function so it can only be called once. The {initializer} modifier provided by this contract will have this effect.\\n *\\n * The initialization functions use a version number. Once a version number is used, it is consumed and cannot be\\n * reused. This mechanism prevents re-execution of each \\\"step\\\" but allows the creation of new initialization steps in\\n * case an upgrade adds a module that needs to be initialized.\\n *\\n * For example:\\n *\\n * [.hljs-theme-light.nopadding]\\n * ```\\n * contract MyToken is ERC20Upgradeable {\\n * function initialize() initializer public {\\n * __ERC20_init(\\\"MyToken\\\", \\\"MTK\\\");\\n * }\\n * }\\n * contract MyTokenV2 is MyToken, ERC20PermitUpgradeable {\\n * function initializeV2() reinitializer(2) public {\\n * __ERC20Permit_init(\\\"MyToken\\\");\\n * }\\n * }\\n * ```\\n *\\n * TIP: To avoid leaving the proxy in an uninitialized state, the initializer function should be called as early as\\n * possible by providing the encoded function call as the `_data` argument to {ERC1967Proxy-constructor}.\\n *\\n * CAUTION: When used with inheritance, manual care must be taken to not invoke a parent initializer twice, or to ensure\\n * that all initializers are idempotent. This is not verified automatically as constructors are by Solidity.\\n *\\n * [CAUTION]\\n * ====\\n * Avoid leaving a contract uninitialized.\\n *\\n * An uninitialized contract can be taken over by an attacker. This applies to both a proxy and its implementation\\n * contract, which may impact the proxy. To prevent the implementation contract from being used, you should invoke\\n * the {_disableInitializers} function in the constructor to automatically lock it when it is deployed:\\n *\\n * [.hljs-theme-light.nopadding]\\n * ```\\n * /// @custom:oz-upgrades-unsafe-allow constructor\\n * constructor() {\\n * _disableInitializers();\\n * }\\n * ```\\n * ====\\n */\\nabstract contract Initializable {\\n /**\\n * @dev Indicates that the contract has been initialized.\\n * @custom:oz-retyped-from bool\\n */\\n uint8 private _initialized;\\n\\n /**\\n * @dev Indicates that the contract is in the process of being initialized.\\n */\\n bool private _initializing;\\n\\n /**\\n * @dev Triggered when the contract has been initialized or reinitialized.\\n */\\n event Initialized(uint8 version);\\n\\n /**\\n * @dev A modifier that defines a protected initializer function that can be invoked at most once. In its scope,\\n * `onlyInitializing` functions can be used to initialize parent contracts. Equivalent to `reinitializer(1)`.\\n */\\n modifier initializer() {\\n bool isTopLevelCall = !_initializing;\\n require(\\n (isTopLevelCall && _initialized < 1) || (!AddressUpgradeable.isContract(address(this)) && _initialized == 1),\\n \\\"Initializable: contract is already initialized\\\"\\n );\\n _initialized = 1;\\n if (isTopLevelCall) {\\n _initializing = true;\\n }\\n _;\\n if (isTopLevelCall) {\\n _initializing = false;\\n emit Initialized(1);\\n }\\n }\\n\\n /**\\n * @dev A modifier that defines a protected reinitializer function that can be invoked at most once, and only if the\\n * contract hasn't been initialized to a greater version before. In its scope, `onlyInitializing` functions can be\\n * used to initialize parent contracts.\\n *\\n * `initializer` is equivalent to `reinitializer(1)`, so a reinitializer may be used after the original\\n * initialization step. This is essential to configure modules that are added through upgrades and that require\\n * initialization.\\n *\\n * Note that versions can jump in increments greater than 1; this implies that if multiple reinitializers coexist in\\n * a contract, executing them in the right order is up to the developer or operator.\\n */\\n modifier reinitializer(uint8 version) {\\n require(!_initializing && _initialized < version, \\\"Initializable: contract is already initialized\\\");\\n _initialized = version;\\n _initializing = true;\\n _;\\n _initializing = false;\\n emit Initialized(version);\\n }\\n\\n /**\\n * @dev Modifier to protect an initialization function so that it can only be invoked by functions with the\\n * {initializer} and {reinitializer} modifiers, directly or indirectly.\\n */\\n modifier onlyInitializing() {\\n require(_initializing, \\\"Initializable: contract is not initializing\\\");\\n _;\\n }\\n\\n /**\\n * @dev Locks the contract, preventing any future reinitialization. This cannot be part of an initializer call.\\n * Calling this in the constructor of a contract will prevent that contract from being initialized or reinitialized\\n * to any version. It is recommended to use this to lock implementation contracts that are designed to be called\\n * through proxies.\\n */\\n function _disableInitializers() internal virtual {\\n require(!_initializing, \\\"Initializable: contract is initializing\\\");\\n if (_initialized < type(uint8).max) {\\n _initialized = type(uint8).max;\\n emit Initialized(type(uint8).max);\\n }\\n }\\n}\\n\",\"keccak256\":\"0x0203dcadc5737d9ef2c211d6fa15d18ebc3b30dfa51903b64870b01a062b0b4e\",\"license\":\"MIT\"},\"@openzeppelin/contracts-upgradeable/token/ERC20/ERC20Upgradeable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.7.0) (token/ERC20/ERC20.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"./IERC20Upgradeable.sol\\\";\\nimport \\\"./extensions/IERC20MetadataUpgradeable.sol\\\";\\nimport \\\"../../utils/ContextUpgradeable.sol\\\";\\nimport \\\"../../proxy/utils/Initializable.sol\\\";\\n\\n/**\\n * @dev Implementation of the {IERC20} interface.\\n *\\n * This implementation is agnostic to the way tokens are created. This means\\n * that a supply mechanism has to be added in a derived contract using {_mint}.\\n * For a generic mechanism see {ERC20PresetMinterPauser}.\\n *\\n * TIP: For a detailed writeup see our guide\\n * https://forum.zeppelin.solutions/t/how-to-implement-erc20-supply-mechanisms/226[How\\n * to implement supply mechanisms].\\n *\\n * We have followed general OpenZeppelin Contracts guidelines: functions revert\\n * instead returning `false` on failure. This behavior is nonetheless\\n * conventional and does not conflict with the expectations of ERC20\\n * applications.\\n *\\n * Additionally, an {Approval} event is emitted on calls to {transferFrom}.\\n * This allows applications to reconstruct the allowance for all accounts just\\n * by listening to said events. Other implementations of the EIP may not emit\\n * these events, as it isn't required by the specification.\\n *\\n * Finally, the non-standard {decreaseAllowance} and {increaseAllowance}\\n * functions have been added to mitigate the well-known issues around setting\\n * allowances. See {IERC20-approve}.\\n */\\ncontract ERC20Upgradeable is Initializable, ContextUpgradeable, IERC20Upgradeable, IERC20MetadataUpgradeable {\\n mapping(address => uint256) private _balances;\\n\\n mapping(address => mapping(address => uint256)) private _allowances;\\n\\n uint256 private _totalSupply;\\n\\n string private _name;\\n string private _symbol;\\n\\n /**\\n * @dev Sets the values for {name} and {symbol}.\\n *\\n * The default value of {decimals} is 18. To select a different value for\\n * {decimals} you should overload it.\\n *\\n * All two of these values are immutable: they can only be set once during\\n * construction.\\n */\\n function __ERC20_init(string memory name_, string memory symbol_) internal onlyInitializing {\\n __ERC20_init_unchained(name_, symbol_);\\n }\\n\\n function __ERC20_init_unchained(string memory name_, string memory symbol_) internal onlyInitializing {\\n _name = name_;\\n _symbol = symbol_;\\n }\\n\\n /**\\n * @dev Returns the name of the token.\\n */\\n function name() public view virtual override returns (string memory) {\\n return _name;\\n }\\n\\n /**\\n * @dev Returns the symbol of the token, usually a shorter version of the\\n * name.\\n */\\n function symbol() public view virtual override returns (string memory) {\\n return _symbol;\\n }\\n\\n /**\\n * @dev Returns the number of decimals used to get its user representation.\\n * For example, if `decimals` equals `2`, a balance of `505` tokens should\\n * be displayed to a user as `5.05` (`505 / 10 ** 2`).\\n *\\n * Tokens usually opt for a value of 18, imitating the relationship between\\n * Ether and Wei. This is the value {ERC20} uses, unless this function is\\n * overridden;\\n *\\n * NOTE: This information is only used for _display_ purposes: it in\\n * no way affects any of the arithmetic of the contract, including\\n * {IERC20-balanceOf} and {IERC20-transfer}.\\n */\\n function decimals() public view virtual override returns (uint8) {\\n return 18;\\n }\\n\\n /**\\n * @dev See {IERC20-totalSupply}.\\n */\\n function totalSupply() public view virtual override returns (uint256) {\\n return _totalSupply;\\n }\\n\\n /**\\n * @dev See {IERC20-balanceOf}.\\n */\\n function balanceOf(address account) public view virtual override returns (uint256) {\\n return _balances[account];\\n }\\n\\n /**\\n * @dev See {IERC20-transfer}.\\n *\\n * Requirements:\\n *\\n * - `to` cannot be the zero address.\\n * - the caller must have a balance of at least `amount`.\\n */\\n function transfer(address to, uint256 amount) public virtual override returns (bool) {\\n address owner = _msgSender();\\n _transfer(owner, to, amount);\\n return true;\\n }\\n\\n /**\\n * @dev See {IERC20-allowance}.\\n */\\n function allowance(address owner, address spender) public view virtual override returns (uint256) {\\n return _allowances[owner][spender];\\n }\\n\\n /**\\n * @dev See {IERC20-approve}.\\n *\\n * NOTE: If `amount` is the maximum `uint256`, the allowance is not updated on\\n * `transferFrom`. This is semantically equivalent to an infinite approval.\\n *\\n * Requirements:\\n *\\n * - `spender` cannot be the zero address.\\n */\\n function approve(address spender, uint256 amount) public virtual override returns (bool) {\\n address owner = _msgSender();\\n _approve(owner, spender, amount);\\n return true;\\n }\\n\\n /**\\n * @dev See {IERC20-transferFrom}.\\n *\\n * Emits an {Approval} event indicating the updated allowance. This is not\\n * required by the EIP. See the note at the beginning of {ERC20}.\\n *\\n * NOTE: Does not update the allowance if the current allowance\\n * is the maximum `uint256`.\\n *\\n * Requirements:\\n *\\n * - `from` and `to` cannot be the zero address.\\n * - `from` must have a balance of at least `amount`.\\n * - the caller must have allowance for ``from``'s tokens of at least\\n * `amount`.\\n */\\n function transferFrom(\\n address from,\\n address to,\\n uint256 amount\\n ) public virtual override returns (bool) {\\n address spender = _msgSender();\\n _spendAllowance(from, spender, amount);\\n _transfer(from, to, amount);\\n return true;\\n }\\n\\n /**\\n * @dev Atomically increases the allowance granted to `spender` by the caller.\\n *\\n * This is an alternative to {approve} that can be used as a mitigation for\\n * problems described in {IERC20-approve}.\\n *\\n * Emits an {Approval} event indicating the updated allowance.\\n *\\n * Requirements:\\n *\\n * - `spender` cannot be the zero address.\\n */\\n function increaseAllowance(address spender, uint256 addedValue) public virtual returns (bool) {\\n address owner = _msgSender();\\n _approve(owner, spender, allowance(owner, spender) + addedValue);\\n return true;\\n }\\n\\n /**\\n * @dev Atomically decreases the allowance granted to `spender` by the caller.\\n *\\n * This is an alternative to {approve} that can be used as a mitigation for\\n * problems described in {IERC20-approve}.\\n *\\n * Emits an {Approval} event indicating the updated allowance.\\n *\\n * Requirements:\\n *\\n * - `spender` cannot be the zero address.\\n * - `spender` must have allowance for the caller of at least\\n * `subtractedValue`.\\n */\\n function decreaseAllowance(address spender, uint256 subtractedValue) public virtual returns (bool) {\\n address owner = _msgSender();\\n uint256 currentAllowance = allowance(owner, spender);\\n require(currentAllowance >= subtractedValue, \\\"ERC20: decreased allowance below zero\\\");\\n unchecked {\\n _approve(owner, spender, currentAllowance - subtractedValue);\\n }\\n\\n return true;\\n }\\n\\n /**\\n * @dev Moves `amount` of tokens from `from` to `to`.\\n *\\n * This internal function is equivalent to {transfer}, and can be used to\\n * e.g. implement automatic token fees, slashing mechanisms, etc.\\n *\\n * Emits a {Transfer} event.\\n *\\n * Requirements:\\n *\\n * - `from` cannot be the zero address.\\n * - `to` cannot be the zero address.\\n * - `from` must have a balance of at least `amount`.\\n */\\n function _transfer(\\n address from,\\n address to,\\n uint256 amount\\n ) internal virtual {\\n require(from != address(0), \\\"ERC20: transfer from the zero address\\\");\\n require(to != address(0), \\\"ERC20: transfer to the zero address\\\");\\n\\n _beforeTokenTransfer(from, to, amount);\\n\\n uint256 fromBalance = _balances[from];\\n require(fromBalance >= amount, \\\"ERC20: transfer amount exceeds balance\\\");\\n unchecked {\\n _balances[from] = fromBalance - amount;\\n }\\n _balances[to] += amount;\\n\\n emit Transfer(from, to, amount);\\n\\n _afterTokenTransfer(from, to, amount);\\n }\\n\\n /** @dev Creates `amount` tokens and assigns them to `account`, increasing\\n * the total supply.\\n *\\n * Emits a {Transfer} event with `from` set to the zero address.\\n *\\n * Requirements:\\n *\\n * - `account` cannot be the zero address.\\n */\\n function _mint(address account, uint256 amount) internal virtual {\\n require(account != address(0), \\\"ERC20: mint to the zero address\\\");\\n\\n _beforeTokenTransfer(address(0), account, amount);\\n\\n _totalSupply += amount;\\n _balances[account] += amount;\\n emit Transfer(address(0), account, amount);\\n\\n _afterTokenTransfer(address(0), account, amount);\\n }\\n\\n /**\\n * @dev Destroys `amount` tokens from `account`, reducing the\\n * total supply.\\n *\\n * Emits a {Transfer} event with `to` set to the zero address.\\n *\\n * Requirements:\\n *\\n * - `account` cannot be the zero address.\\n * - `account` must have at least `amount` tokens.\\n */\\n function _burn(address account, uint256 amount) internal virtual {\\n require(account != address(0), \\\"ERC20: burn from the zero address\\\");\\n\\n _beforeTokenTransfer(account, address(0), amount);\\n\\n uint256 accountBalance = _balances[account];\\n require(accountBalance >= amount, \\\"ERC20: burn amount exceeds balance\\\");\\n unchecked {\\n _balances[account] = accountBalance - amount;\\n }\\n _totalSupply -= amount;\\n\\n emit Transfer(account, address(0), amount);\\n\\n _afterTokenTransfer(account, address(0), amount);\\n }\\n\\n /**\\n * @dev Sets `amount` as the allowance of `spender` over the `owner` s tokens.\\n *\\n * This internal function is equivalent to `approve`, and can be used to\\n * e.g. set automatic allowances for certain subsystems, etc.\\n *\\n * Emits an {Approval} event.\\n *\\n * Requirements:\\n *\\n * - `owner` cannot be the zero address.\\n * - `spender` cannot be the zero address.\\n */\\n function _approve(\\n address owner,\\n address spender,\\n uint256 amount\\n ) internal virtual {\\n require(owner != address(0), \\\"ERC20: approve from the zero address\\\");\\n require(spender != address(0), \\\"ERC20: approve to the zero address\\\");\\n\\n _allowances[owner][spender] = amount;\\n emit Approval(owner, spender, amount);\\n }\\n\\n /**\\n * @dev Updates `owner` s allowance for `spender` based on spent `amount`.\\n *\\n * Does not update the allowance amount in case of infinite allowance.\\n * Revert if not enough allowance is available.\\n *\\n * Might emit an {Approval} event.\\n */\\n function _spendAllowance(\\n address owner,\\n address spender,\\n uint256 amount\\n ) internal virtual {\\n uint256 currentAllowance = allowance(owner, spender);\\n if (currentAllowance != type(uint256).max) {\\n require(currentAllowance >= amount, \\\"ERC20: insufficient allowance\\\");\\n unchecked {\\n _approve(owner, spender, currentAllowance - amount);\\n }\\n }\\n }\\n\\n /**\\n * @dev Hook that is called before any transfer of tokens. This includes\\n * minting and burning.\\n *\\n * Calling conditions:\\n *\\n * - when `from` and `to` are both non-zero, `amount` of ``from``'s tokens\\n * will be transferred to `to`.\\n * - when `from` is zero, `amount` tokens will be minted for `to`.\\n * - when `to` is zero, `amount` of ``from``'s tokens will be burned.\\n * - `from` and `to` are never both zero.\\n *\\n * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].\\n */\\n function _beforeTokenTransfer(\\n address from,\\n address to,\\n uint256 amount\\n ) internal virtual {}\\n\\n /**\\n * @dev Hook that is called after any transfer of tokens. This includes\\n * minting and burning.\\n *\\n * Calling conditions:\\n *\\n * - when `from` and `to` are both non-zero, `amount` of ``from``'s tokens\\n * has been transferred to `to`.\\n * - when `from` is zero, `amount` tokens have been minted for `to`.\\n * - when `to` is zero, `amount` of ``from``'s tokens have been burned.\\n * - `from` and `to` are never both zero.\\n *\\n * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].\\n */\\n function _afterTokenTransfer(\\n address from,\\n address to,\\n uint256 amount\\n ) internal virtual {}\\n\\n /**\\n * @dev This empty reserved space is put in place to allow future versions to add new\\n * variables without shifting down storage in the inheritance chain.\\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\\n */\\n uint256[45] private __gap;\\n}\\n\",\"keccak256\":\"0x7c7ac0bc6c340a7f320524b9a4b4b079ee9da3c51258080d4bab237f329a427c\",\"license\":\"MIT\"},\"@openzeppelin/contracts-upgradeable/token/ERC20/IERC20Upgradeable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.6.0) (token/ERC20/IERC20.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Interface of the ERC20 standard as defined in the EIP.\\n */\\ninterface IERC20Upgradeable {\\n /**\\n * @dev Emitted when `value` tokens are moved from one account (`from`) to\\n * another (`to`).\\n *\\n * Note that `value` may be zero.\\n */\\n event Transfer(address indexed from, address indexed to, uint256 value);\\n\\n /**\\n * @dev Emitted when the allowance of a `spender` for an `owner` is set by\\n * a call to {approve}. `value` is the new allowance.\\n */\\n event Approval(address indexed owner, address indexed spender, uint256 value);\\n\\n /**\\n * @dev Returns the amount of tokens in existence.\\n */\\n function totalSupply() external view returns (uint256);\\n\\n /**\\n * @dev Returns the amount of tokens owned by `account`.\\n */\\n function balanceOf(address account) external view returns (uint256);\\n\\n /**\\n * @dev Moves `amount` tokens from the caller's account to `to`.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * Emits a {Transfer} event.\\n */\\n function transfer(address to, uint256 amount) external returns (bool);\\n\\n /**\\n * @dev Returns the remaining number of tokens that `spender` will be\\n * allowed to spend on behalf of `owner` through {transferFrom}. This is\\n * zero by default.\\n *\\n * This value changes when {approve} or {transferFrom} are called.\\n */\\n function allowance(address owner, address spender) external view returns (uint256);\\n\\n /**\\n * @dev Sets `amount` as the allowance of `spender` over the caller's tokens.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * IMPORTANT: Beware that changing an allowance with this method brings the risk\\n * that someone may use both the old and the new allowance by unfortunate\\n * transaction ordering. One possible solution to mitigate this race\\n * condition is to first reduce the spender's allowance to 0 and set the\\n * desired value afterwards:\\n * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729\\n *\\n * Emits an {Approval} event.\\n */\\n function approve(address spender, uint256 amount) external returns (bool);\\n\\n /**\\n * @dev Moves `amount` tokens from `from` to `to` using the\\n * allowance mechanism. `amount` is then deducted from the caller's\\n * allowance.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * Emits a {Transfer} event.\\n */\\n function transferFrom(\\n address from,\\n address to,\\n uint256 amount\\n ) external returns (bool);\\n}\\n\",\"keccak256\":\"0x4e733d3164f73f461eaf9d8087a7ad1ea180bdc8ba0d3d61b0e1ae16d8e63dff\",\"license\":\"MIT\"},\"@openzeppelin/contracts-upgradeable/token/ERC20/extensions/IERC20MetadataUpgradeable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (token/ERC20/extensions/IERC20Metadata.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../IERC20Upgradeable.sol\\\";\\n\\n/**\\n * @dev Interface for the optional metadata functions from the ERC20 standard.\\n *\\n * _Available since v4.1._\\n */\\ninterface IERC20MetadataUpgradeable is IERC20Upgradeable {\\n /**\\n * @dev Returns the name of the token.\\n */\\n function name() external view returns (string memory);\\n\\n /**\\n * @dev Returns the symbol of the token.\\n */\\n function symbol() external view returns (string memory);\\n\\n /**\\n * @dev Returns the decimals places of the token.\\n */\\n function decimals() external view returns (uint8);\\n}\\n\",\"keccak256\":\"0x605434219ebbe4653f703640f06969faa5a1d78f0bfef878e5ddbb1ca369ceeb\",\"license\":\"MIT\"},\"@openzeppelin/contracts-upgradeable/token/ERC20/extensions/draft-ERC20PermitUpgradeable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.6.0) (token/ERC20/extensions/draft-ERC20Permit.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"./draft-IERC20PermitUpgradeable.sol\\\";\\nimport \\\"../ERC20Upgradeable.sol\\\";\\nimport \\\"../../../utils/cryptography/draft-EIP712Upgradeable.sol\\\";\\nimport \\\"../../../utils/cryptography/ECDSAUpgradeable.sol\\\";\\nimport \\\"../../../utils/CountersUpgradeable.sol\\\";\\nimport \\\"../../../proxy/utils/Initializable.sol\\\";\\n\\n/**\\n * @dev Implementation of the ERC20 Permit extension allowing approvals to be made via signatures, as defined in\\n * https://eips.ethereum.org/EIPS/eip-2612[EIP-2612].\\n *\\n * Adds the {permit} method, which can be used to change an account's ERC20 allowance (see {IERC20-allowance}) by\\n * presenting a message signed by the account. By not relying on `{IERC20-approve}`, the token holder account doesn't\\n * need to send a transaction, and thus is not required to hold Ether at all.\\n *\\n * _Available since v3.4._\\n *\\n * @custom:storage-size 51\\n */\\nabstract contract ERC20PermitUpgradeable is Initializable, ERC20Upgradeable, IERC20PermitUpgradeable, EIP712Upgradeable {\\n using CountersUpgradeable for CountersUpgradeable.Counter;\\n\\n mapping(address => CountersUpgradeable.Counter) private _nonces;\\n\\n // solhint-disable-next-line var-name-mixedcase\\n bytes32 private constant _PERMIT_TYPEHASH =\\n keccak256(\\\"Permit(address owner,address spender,uint256 value,uint256 nonce,uint256 deadline)\\\");\\n /**\\n * @dev In previous versions `_PERMIT_TYPEHASH` was declared as `immutable`.\\n * However, to ensure consistency with the upgradeable transpiler, we will continue\\n * to reserve a slot.\\n * @custom:oz-renamed-from _PERMIT_TYPEHASH\\n */\\n // solhint-disable-next-line var-name-mixedcase\\n bytes32 private _PERMIT_TYPEHASH_DEPRECATED_SLOT;\\n\\n /**\\n * @dev Initializes the {EIP712} domain separator using the `name` parameter, and setting `version` to `\\\"1\\\"`.\\n *\\n * It's a good idea to use the same `name` that is defined as the ERC20 token name.\\n */\\n function __ERC20Permit_init(string memory name) internal onlyInitializing {\\n __EIP712_init_unchained(name, \\\"1\\\");\\n }\\n\\n function __ERC20Permit_init_unchained(string memory) internal onlyInitializing {}\\n\\n /**\\n * @dev See {IERC20Permit-permit}.\\n */\\n function permit(\\n address owner,\\n address spender,\\n uint256 value,\\n uint256 deadline,\\n uint8 v,\\n bytes32 r,\\n bytes32 s\\n ) public virtual override {\\n require(block.timestamp <= deadline, \\\"ERC20Permit: expired deadline\\\");\\n\\n bytes32 structHash = keccak256(abi.encode(_PERMIT_TYPEHASH, owner, spender, value, _useNonce(owner), deadline));\\n\\n bytes32 hash = _hashTypedDataV4(structHash);\\n\\n address signer = ECDSAUpgradeable.recover(hash, v, r, s);\\n require(signer == owner, \\\"ERC20Permit: invalid signature\\\");\\n\\n _approve(owner, spender, value);\\n }\\n\\n /**\\n * @dev See {IERC20Permit-nonces}.\\n */\\n function nonces(address owner) public view virtual override returns (uint256) {\\n return _nonces[owner].current();\\n }\\n\\n /**\\n * @dev See {IERC20Permit-DOMAIN_SEPARATOR}.\\n */\\n // solhint-disable-next-line func-name-mixedcase\\n function DOMAIN_SEPARATOR() external view override returns (bytes32) {\\n return _domainSeparatorV4();\\n }\\n\\n /**\\n * @dev \\\"Consume a nonce\\\": return the current value and increment.\\n *\\n * _Available since v4.1._\\n */\\n function _useNonce(address owner) internal virtual returns (uint256 current) {\\n CountersUpgradeable.Counter storage nonce = _nonces[owner];\\n current = nonce.current();\\n nonce.increment();\\n }\\n\\n /**\\n * @dev This empty reserved space is put in place to allow future versions to add new\\n * variables without shifting down storage in the inheritance chain.\\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\\n */\\n uint256[49] private __gap;\\n}\\n\",\"keccak256\":\"0x564385ebed633694decce3e13d687f3ac7e8eaef64f7a504bfb3f03ad210601f\",\"license\":\"MIT\"},\"@openzeppelin/contracts-upgradeable/token/ERC20/extensions/draft-IERC20PermitUpgradeable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (token/ERC20/extensions/draft-IERC20Permit.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Interface of the ERC20 Permit extension allowing approvals to be made via signatures, as defined in\\n * https://eips.ethereum.org/EIPS/eip-2612[EIP-2612].\\n *\\n * Adds the {permit} method, which can be used to change an account's ERC20 allowance (see {IERC20-allowance}) by\\n * presenting a message signed by the account. By not relying on {IERC20-approve}, the token holder account doesn't\\n * need to send a transaction, and thus is not required to hold Ether at all.\\n */\\ninterface IERC20PermitUpgradeable {\\n /**\\n * @dev Sets `value` as the allowance of `spender` over ``owner``'s tokens,\\n * given ``owner``'s signed approval.\\n *\\n * IMPORTANT: The same issues {IERC20-approve} has related to transaction\\n * ordering also apply here.\\n *\\n * Emits an {Approval} event.\\n *\\n * Requirements:\\n *\\n * - `spender` cannot be the zero address.\\n * - `deadline` must be a timestamp in the future.\\n * - `v`, `r` and `s` must be a valid `secp256k1` signature from `owner`\\n * over the EIP712-formatted function arguments.\\n * - the signature must use ``owner``'s current nonce (see {nonces}).\\n *\\n * For more information on the signature format, see the\\n * https://eips.ethereum.org/EIPS/eip-2612#specification[relevant EIP\\n * section].\\n */\\n function permit(\\n address owner,\\n address spender,\\n uint256 value,\\n uint256 deadline,\\n uint8 v,\\n bytes32 r,\\n bytes32 s\\n ) external;\\n\\n /**\\n * @dev Returns the current nonce for `owner`. This value must be\\n * included whenever a signature is generated for {permit}.\\n *\\n * Every successful call to {permit} increases ``owner``'s nonce by one. This\\n * prevents a signature from being used multiple times.\\n */\\n function nonces(address owner) external view returns (uint256);\\n\\n /**\\n * @dev Returns the domain separator used in the encoding of the signature for {permit}, as defined by {EIP712}.\\n */\\n // solhint-disable-next-line func-name-mixedcase\\n function DOMAIN_SEPARATOR() external view returns (bytes32);\\n}\\n\",\"keccak256\":\"0xcc70d8e2281fb3ff69e8ab242500f10142cd0a7fa8dd9e45882be270d4d09024\",\"license\":\"MIT\"},\"@openzeppelin/contracts-upgradeable/utils/AddressUpgradeable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.7.0) (utils/Address.sol)\\n\\npragma solidity ^0.8.1;\\n\\n/**\\n * @dev Collection of functions related to the address type\\n */\\nlibrary AddressUpgradeable {\\n /**\\n * @dev Returns true if `account` is a contract.\\n *\\n * [IMPORTANT]\\n * ====\\n * It is unsafe to assume that an address for which this function returns\\n * false is an externally-owned account (EOA) and not a contract.\\n *\\n * Among others, `isContract` will return false for the following\\n * types of addresses:\\n *\\n * - an externally-owned account\\n * - a contract in construction\\n * - an address where a contract will be created\\n * - an address where a contract lived, but was destroyed\\n * ====\\n *\\n * [IMPORTANT]\\n * ====\\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\\n *\\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\\n * constructor.\\n * ====\\n */\\n function isContract(address account) internal view returns (bool) {\\n // This method relies on extcodesize/address.code.length, which returns 0\\n // for contracts in construction, since the code is only stored at the end\\n // of the constructor execution.\\n\\n return account.code.length > 0;\\n }\\n\\n /**\\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\\n * `recipient`, forwarding all available gas and reverting on errors.\\n *\\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\\n * imposed by `transfer`, making them unable to receive funds via\\n * `transfer`. {sendValue} removes this limitation.\\n *\\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\\n *\\n * IMPORTANT: because control is transferred to `recipient`, care must be\\n * taken to not create reentrancy vulnerabilities. Consider using\\n * {ReentrancyGuard} or the\\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\\n */\\n function sendValue(address payable recipient, uint256 amount) internal {\\n require(address(this).balance >= amount, \\\"Address: insufficient balance\\\");\\n\\n (bool success, ) = recipient.call{value: amount}(\\\"\\\");\\n require(success, \\\"Address: unable to send value, recipient may have reverted\\\");\\n }\\n\\n /**\\n * @dev Performs a Solidity function call using a low level `call`. A\\n * plain `call` is an unsafe replacement for a function call: use this\\n * function instead.\\n *\\n * If `target` reverts with a revert reason, it is bubbled up by this\\n * function (like regular Solidity function calls).\\n *\\n * Returns the raw returned data. To convert to the expected return value,\\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\\n *\\n * Requirements:\\n *\\n * - `target` must be a contract.\\n * - calling `target` with `data` must not revert.\\n *\\n * _Available since v3.1._\\n */\\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\\n return functionCall(target, data, \\\"Address: low-level call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\\n * `errorMessage` as a fallback revert reason when `target` reverts.\\n *\\n * _Available since v3.1._\\n */\\n function functionCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n return functionCallWithValue(target, data, 0, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but also transferring `value` wei to `target`.\\n *\\n * Requirements:\\n *\\n * - the calling contract must have an ETH balance of at least `value`.\\n * - the called Solidity function must be `payable`.\\n *\\n * _Available since v3.1._\\n */\\n function functionCallWithValue(\\n address target,\\n bytes memory data,\\n uint256 value\\n ) internal returns (bytes memory) {\\n return functionCallWithValue(target, data, value, \\\"Address: low-level call with value failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\\n * with `errorMessage` as a fallback revert reason when `target` reverts.\\n *\\n * _Available since v3.1._\\n */\\n function functionCallWithValue(\\n address target,\\n bytes memory data,\\n uint256 value,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n require(address(this).balance >= value, \\\"Address: insufficient balance for call\\\");\\n require(isContract(target), \\\"Address: call to non-contract\\\");\\n\\n (bool success, bytes memory returndata) = target.call{value: value}(data);\\n return verifyCallResult(success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but performing a static call.\\n *\\n * _Available since v3.3._\\n */\\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\\n return functionStaticCall(target, data, \\\"Address: low-level static call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\\n * but performing a static call.\\n *\\n * _Available since v3.3._\\n */\\n function functionStaticCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal view returns (bytes memory) {\\n require(isContract(target), \\\"Address: static call to non-contract\\\");\\n\\n (bool success, bytes memory returndata) = target.staticcall(data);\\n return verifyCallResult(success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the\\n * revert reason using the provided one.\\n *\\n * _Available since v4.3._\\n */\\n function verifyCallResult(\\n bool success,\\n bytes memory returndata,\\n string memory errorMessage\\n ) internal pure returns (bytes memory) {\\n if (success) {\\n return returndata;\\n } else {\\n // Look for revert reason and bubble it up if present\\n if (returndata.length > 0) {\\n // The easiest way to bubble the revert reason is using memory via assembly\\n /// @solidity memory-safe-assembly\\n assembly {\\n let returndata_size := mload(returndata)\\n revert(add(32, returndata), returndata_size)\\n }\\n } else {\\n revert(errorMessage);\\n }\\n }\\n }\\n}\\n\",\"keccak256\":\"0x611aa3f23e59cfdd1863c536776407b3e33d695152a266fa7cfb34440a29a8a3\",\"license\":\"MIT\"},\"@openzeppelin/contracts-upgradeable/utils/ContextUpgradeable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)\\n\\npragma solidity ^0.8.0;\\nimport \\\"../proxy/utils/Initializable.sol\\\";\\n\\n/**\\n * @dev Provides information about the current execution context, including the\\n * sender of the transaction and its data. While these are generally available\\n * via msg.sender and msg.data, they should not be accessed in such a direct\\n * manner, since when dealing with meta-transactions the account sending and\\n * paying for execution may not be the actual sender (as far as an application\\n * is concerned).\\n *\\n * This contract is only required for intermediate, library-like contracts.\\n */\\nabstract contract ContextUpgradeable is Initializable {\\n function __Context_init() internal onlyInitializing {\\n }\\n\\n function __Context_init_unchained() internal onlyInitializing {\\n }\\n function _msgSender() internal view virtual returns (address) {\\n return msg.sender;\\n }\\n\\n function _msgData() internal view virtual returns (bytes calldata) {\\n return msg.data;\\n }\\n\\n /**\\n * @dev This empty reserved space is put in place to allow future versions to add new\\n * variables without shifting down storage in the inheritance chain.\\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\\n */\\n uint256[50] private __gap;\\n}\\n\",\"keccak256\":\"0x963ea7f0b48b032eef72fe3a7582edf78408d6f834115b9feadd673a4d5bd149\",\"license\":\"MIT\"},\"@openzeppelin/contracts-upgradeable/utils/CountersUpgradeable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (utils/Counters.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @title Counters\\n * @author Matt Condon (@shrugs)\\n * @dev Provides counters that can only be incremented, decremented or reset. This can be used e.g. to track the number\\n * of elements in a mapping, issuing ERC721 ids, or counting request ids.\\n *\\n * Include with `using Counters for Counters.Counter;`\\n */\\nlibrary CountersUpgradeable {\\n struct Counter {\\n // This variable should never be directly accessed by users of the library: interactions must be restricted to\\n // the library's function. As of Solidity v0.5.2, this cannot be enforced, though there is a proposal to add\\n // this feature: see https://github.com/ethereum/solidity/issues/4637\\n uint256 _value; // default: 0\\n }\\n\\n function current(Counter storage counter) internal view returns (uint256) {\\n return counter._value;\\n }\\n\\n function increment(Counter storage counter) internal {\\n unchecked {\\n counter._value += 1;\\n }\\n }\\n\\n function decrement(Counter storage counter) internal {\\n uint256 value = counter._value;\\n require(value > 0, \\\"Counter: decrement overflow\\\");\\n unchecked {\\n counter._value = value - 1;\\n }\\n }\\n\\n function reset(Counter storage counter) internal {\\n counter._value = 0;\\n }\\n}\\n\",\"keccak256\":\"0x798741e231b22b81e2dd2eddaaf8832dee4baf5cd8e2dbaa5c1dd12a1c053c4d\",\"license\":\"MIT\"},\"@openzeppelin/contracts-upgradeable/utils/StringsUpgradeable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.7.0) (utils/Strings.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev String operations.\\n */\\nlibrary StringsUpgradeable {\\n bytes16 private constant _HEX_SYMBOLS = \\\"0123456789abcdef\\\";\\n uint8 private constant _ADDRESS_LENGTH = 20;\\n\\n /**\\n * @dev Converts a `uint256` to its ASCII `string` decimal representation.\\n */\\n function toString(uint256 value) internal pure returns (string memory) {\\n // Inspired by OraclizeAPI's implementation - MIT licence\\n // https://github.com/oraclize/ethereum-api/blob/b42146b063c7d6ee1358846c198246239e9360e8/oraclizeAPI_0.4.25.sol\\n\\n if (value == 0) {\\n return \\\"0\\\";\\n }\\n uint256 temp = value;\\n uint256 digits;\\n while (temp != 0) {\\n digits++;\\n temp /= 10;\\n }\\n bytes memory buffer = new bytes(digits);\\n while (value != 0) {\\n digits -= 1;\\n buffer[digits] = bytes1(uint8(48 + uint256(value % 10)));\\n value /= 10;\\n }\\n return string(buffer);\\n }\\n\\n /**\\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation.\\n */\\n function toHexString(uint256 value) internal pure returns (string memory) {\\n if (value == 0) {\\n return \\\"0x00\\\";\\n }\\n uint256 temp = value;\\n uint256 length = 0;\\n while (temp != 0) {\\n length++;\\n temp >>= 8;\\n }\\n return toHexString(value, length);\\n }\\n\\n /**\\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length.\\n */\\n function toHexString(uint256 value, uint256 length) internal pure returns (string memory) {\\n bytes memory buffer = new bytes(2 * length + 2);\\n buffer[0] = \\\"0\\\";\\n buffer[1] = \\\"x\\\";\\n for (uint256 i = 2 * length + 1; i > 1; --i) {\\n buffer[i] = _HEX_SYMBOLS[value & 0xf];\\n value >>= 4;\\n }\\n require(value == 0, \\\"Strings: hex length insufficient\\\");\\n return string(buffer);\\n }\\n\\n /**\\n * @dev Converts an `address` with fixed length of 20 bytes to its not checksummed ASCII `string` hexadecimal representation.\\n */\\n function toHexString(address addr) internal pure returns (string memory) {\\n return toHexString(uint256(uint160(addr)), _ADDRESS_LENGTH);\\n }\\n}\\n\",\"keccak256\":\"0xea5339a7fff0ed42b45be56a88efdd0b2ddde9fa480dc99fef9a6a4c5b776863\",\"license\":\"MIT\"},\"@openzeppelin/contracts-upgradeable/utils/cryptography/ECDSAUpgradeable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.7.0) (utils/cryptography/ECDSA.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../StringsUpgradeable.sol\\\";\\n\\n/**\\n * @dev Elliptic Curve Digital Signature Algorithm (ECDSA) operations.\\n *\\n * These functions can be used to verify that a message was signed by the holder\\n * of the private keys of a given address.\\n */\\nlibrary ECDSAUpgradeable {\\n enum RecoverError {\\n NoError,\\n InvalidSignature,\\n InvalidSignatureLength,\\n InvalidSignatureS,\\n InvalidSignatureV\\n }\\n\\n function _throwError(RecoverError error) private pure {\\n if (error == RecoverError.NoError) {\\n return; // no error: do nothing\\n } else if (error == RecoverError.InvalidSignature) {\\n revert(\\\"ECDSA: invalid signature\\\");\\n } else if (error == RecoverError.InvalidSignatureLength) {\\n revert(\\\"ECDSA: invalid signature length\\\");\\n } else if (error == RecoverError.InvalidSignatureS) {\\n revert(\\\"ECDSA: invalid signature 's' value\\\");\\n } else if (error == RecoverError.InvalidSignatureV) {\\n revert(\\\"ECDSA: invalid signature 'v' value\\\");\\n }\\n }\\n\\n /**\\n * @dev Returns the address that signed a hashed message (`hash`) with\\n * `signature` or error string. This address can then be used for verification purposes.\\n *\\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\\n * this function rejects them by requiring the `s` value to be in the lower\\n * half order, and the `v` value to be either 27 or 28.\\n *\\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\\n * verification to be secure: it is possible to craft signatures that\\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\\n * this is by receiving a hash of the original message (which may otherwise\\n * be too long), and then calling {toEthSignedMessageHash} on it.\\n *\\n * Documentation for signature generation:\\n * - with https://web3js.readthedocs.io/en/v1.3.4/web3-eth-accounts.html#sign[Web3.js]\\n * - with https://docs.ethers.io/v5/api/signer/#Signer-signMessage[ethers]\\n *\\n * _Available since v4.3._\\n */\\n function tryRecover(bytes32 hash, bytes memory signature) internal pure returns (address, RecoverError) {\\n // Check the signature length\\n // - case 65: r,s,v signature (standard)\\n // - case 64: r,vs signature (cf https://eips.ethereum.org/EIPS/eip-2098) _Available since v4.1._\\n if (signature.length == 65) {\\n bytes32 r;\\n bytes32 s;\\n uint8 v;\\n // ecrecover takes the signature parameters, and the only way to get them\\n // currently is to use assembly.\\n /// @solidity memory-safe-assembly\\n assembly {\\n r := mload(add(signature, 0x20))\\n s := mload(add(signature, 0x40))\\n v := byte(0, mload(add(signature, 0x60)))\\n }\\n return tryRecover(hash, v, r, s);\\n } else if (signature.length == 64) {\\n bytes32 r;\\n bytes32 vs;\\n // ecrecover takes the signature parameters, and the only way to get them\\n // currently is to use assembly.\\n /// @solidity memory-safe-assembly\\n assembly {\\n r := mload(add(signature, 0x20))\\n vs := mload(add(signature, 0x40))\\n }\\n return tryRecover(hash, r, vs);\\n } else {\\n return (address(0), RecoverError.InvalidSignatureLength);\\n }\\n }\\n\\n /**\\n * @dev Returns the address that signed a hashed message (`hash`) with\\n * `signature`. This address can then be used for verification purposes.\\n *\\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\\n * this function rejects them by requiring the `s` value to be in the lower\\n * half order, and the `v` value to be either 27 or 28.\\n *\\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\\n * verification to be secure: it is possible to craft signatures that\\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\\n * this is by receiving a hash of the original message (which may otherwise\\n * be too long), and then calling {toEthSignedMessageHash} on it.\\n */\\n function recover(bytes32 hash, bytes memory signature) internal pure returns (address) {\\n (address recovered, RecoverError error) = tryRecover(hash, signature);\\n _throwError(error);\\n return recovered;\\n }\\n\\n /**\\n * @dev Overload of {ECDSA-tryRecover} that receives the `r` and `vs` short-signature fields separately.\\n *\\n * See https://eips.ethereum.org/EIPS/eip-2098[EIP-2098 short signatures]\\n *\\n * _Available since v4.3._\\n */\\n function tryRecover(\\n bytes32 hash,\\n bytes32 r,\\n bytes32 vs\\n ) internal pure returns (address, RecoverError) {\\n bytes32 s = vs & bytes32(0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff);\\n uint8 v = uint8((uint256(vs) >> 255) + 27);\\n return tryRecover(hash, v, r, s);\\n }\\n\\n /**\\n * @dev Overload of {ECDSA-recover} that receives the `r and `vs` short-signature fields separately.\\n *\\n * _Available since v4.2._\\n */\\n function recover(\\n bytes32 hash,\\n bytes32 r,\\n bytes32 vs\\n ) internal pure returns (address) {\\n (address recovered, RecoverError error) = tryRecover(hash, r, vs);\\n _throwError(error);\\n return recovered;\\n }\\n\\n /**\\n * @dev Overload of {ECDSA-tryRecover} that receives the `v`,\\n * `r` and `s` signature fields separately.\\n *\\n * _Available since v4.3._\\n */\\n function tryRecover(\\n bytes32 hash,\\n uint8 v,\\n bytes32 r,\\n bytes32 s\\n ) internal pure returns (address, RecoverError) {\\n // EIP-2 still allows signature malleability for ecrecover(). Remove this possibility and make the signature\\n // unique. Appendix F in the Ethereum Yellow paper (https://ethereum.github.io/yellowpaper/paper.pdf), defines\\n // the valid range for s in (301): 0 < s < secp256k1n \\u00f7 2 + 1, and for v in (302): v \\u2208 {27, 28}. Most\\n // signatures from current libraries generate a unique signature with an s-value in the lower half order.\\n //\\n // If your library generates malleable signatures, such as s-values in the upper range, calculate a new s-value\\n // with 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141 - s1 and flip v from 27 to 28 or\\n // vice versa. If your library also generates signatures with 0/1 for v instead 27/28, add 27 to v to accept\\n // these malleable signatures as well.\\n if (uint256(s) > 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D576E7357A4501DDFE92F46681B20A0) {\\n return (address(0), RecoverError.InvalidSignatureS);\\n }\\n if (v != 27 && v != 28) {\\n return (address(0), RecoverError.InvalidSignatureV);\\n }\\n\\n // If the signature is valid (and not malleable), return the signer address\\n address signer = ecrecover(hash, v, r, s);\\n if (signer == address(0)) {\\n return (address(0), RecoverError.InvalidSignature);\\n }\\n\\n return (signer, RecoverError.NoError);\\n }\\n\\n /**\\n * @dev Overload of {ECDSA-recover} that receives the `v`,\\n * `r` and `s` signature fields separately.\\n */\\n function recover(\\n bytes32 hash,\\n uint8 v,\\n bytes32 r,\\n bytes32 s\\n ) internal pure returns (address) {\\n (address recovered, RecoverError error) = tryRecover(hash, v, r, s);\\n _throwError(error);\\n return recovered;\\n }\\n\\n /**\\n * @dev Returns an Ethereum Signed Message, created from a `hash`. This\\n * produces hash corresponding to the one signed with the\\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\\n * JSON-RPC method as part of EIP-191.\\n *\\n * See {recover}.\\n */\\n function toEthSignedMessageHash(bytes32 hash) internal pure returns (bytes32) {\\n // 32 is the length in bytes of hash,\\n // enforced by the type signature above\\n return keccak256(abi.encodePacked(\\\"\\\\x19Ethereum Signed Message:\\\\n32\\\", hash));\\n }\\n\\n /**\\n * @dev Returns an Ethereum Signed Message, created from `s`. This\\n * produces hash corresponding to the one signed with the\\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\\n * JSON-RPC method as part of EIP-191.\\n *\\n * See {recover}.\\n */\\n function toEthSignedMessageHash(bytes memory s) internal pure returns (bytes32) {\\n return keccak256(abi.encodePacked(\\\"\\\\x19Ethereum Signed Message:\\\\n\\\", StringsUpgradeable.toString(s.length), s));\\n }\\n\\n /**\\n * @dev Returns an Ethereum Signed Typed Data, created from a\\n * `domainSeparator` and a `structHash`. This produces hash corresponding\\n * to the one signed with the\\n * https://eips.ethereum.org/EIPS/eip-712[`eth_signTypedData`]\\n * JSON-RPC method as part of EIP-712.\\n *\\n * See {recover}.\\n */\\n function toTypedDataHash(bytes32 domainSeparator, bytes32 structHash) internal pure returns (bytes32) {\\n return keccak256(abi.encodePacked(\\\"\\\\x19\\\\x01\\\", domainSeparator, structHash));\\n }\\n}\\n\",\"keccak256\":\"0xe8c62ca00ed2d0a4d9b7e3c4bf7d62c821618b2cdb3c844da91a1193986851bf\",\"license\":\"MIT\"},\"@openzeppelin/contracts-upgradeable/utils/cryptography/draft-EIP712Upgradeable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (utils/cryptography/draft-EIP712.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"./ECDSAUpgradeable.sol\\\";\\nimport \\\"../../proxy/utils/Initializable.sol\\\";\\n\\n/**\\n * @dev https://eips.ethereum.org/EIPS/eip-712[EIP 712] is a standard for hashing and signing of typed structured data.\\n *\\n * The encoding specified in the EIP is very generic, and such a generic implementation in Solidity is not feasible,\\n * thus this contract does not implement the encoding itself. Protocols need to implement the type-specific encoding\\n * they need in their contracts using a combination of `abi.encode` and `keccak256`.\\n *\\n * This contract implements the EIP 712 domain separator ({_domainSeparatorV4}) that is used as part of the encoding\\n * scheme, and the final step of the encoding to obtain the message digest that is then signed via ECDSA\\n * ({_hashTypedDataV4}).\\n *\\n * The implementation of the domain separator was designed to be as efficient as possible while still properly updating\\n * the chain id to protect against replay attacks on an eventual fork of the chain.\\n *\\n * NOTE: This contract implements the version of the encoding known as \\\"v4\\\", as implemented by the JSON RPC method\\n * https://docs.metamask.io/guide/signing-data.html[`eth_signTypedDataV4` in MetaMask].\\n *\\n * _Available since v3.4._\\n *\\n * @custom:storage-size 52\\n */\\nabstract contract EIP712Upgradeable is Initializable {\\n /* solhint-disable var-name-mixedcase */\\n bytes32 private _HASHED_NAME;\\n bytes32 private _HASHED_VERSION;\\n bytes32 private constant _TYPE_HASH = keccak256(\\\"EIP712Domain(string name,string version,uint256 chainId,address verifyingContract)\\\");\\n\\n /* solhint-enable var-name-mixedcase */\\n\\n /**\\n * @dev Initializes the domain separator and parameter caches.\\n *\\n * The meaning of `name` and `version` is specified in\\n * https://eips.ethereum.org/EIPS/eip-712#definition-of-domainseparator[EIP 712]:\\n *\\n * - `name`: the user readable name of the signing domain, i.e. the name of the DApp or the protocol.\\n * - `version`: the current major version of the signing domain.\\n *\\n * NOTE: These parameters cannot be changed except through a xref:learn::upgrading-smart-contracts.adoc[smart\\n * contract upgrade].\\n */\\n function __EIP712_init(string memory name, string memory version) internal onlyInitializing {\\n __EIP712_init_unchained(name, version);\\n }\\n\\n function __EIP712_init_unchained(string memory name, string memory version) internal onlyInitializing {\\n bytes32 hashedName = keccak256(bytes(name));\\n bytes32 hashedVersion = keccak256(bytes(version));\\n _HASHED_NAME = hashedName;\\n _HASHED_VERSION = hashedVersion;\\n }\\n\\n /**\\n * @dev Returns the domain separator for the current chain.\\n */\\n function _domainSeparatorV4() internal view returns (bytes32) {\\n return _buildDomainSeparator(_TYPE_HASH, _EIP712NameHash(), _EIP712VersionHash());\\n }\\n\\n function _buildDomainSeparator(\\n bytes32 typeHash,\\n bytes32 nameHash,\\n bytes32 versionHash\\n ) private view returns (bytes32) {\\n return keccak256(abi.encode(typeHash, nameHash, versionHash, block.chainid, address(this)));\\n }\\n\\n /**\\n * @dev Given an already https://eips.ethereum.org/EIPS/eip-712#definition-of-hashstruct[hashed struct], this\\n * function returns the hash of the fully encoded EIP712 message for this domain.\\n *\\n * This hash can be used together with {ECDSA-recover} to obtain the signer of a message. For example:\\n *\\n * ```solidity\\n * bytes32 digest = _hashTypedDataV4(keccak256(abi.encode(\\n * keccak256(\\\"Mail(address to,string contents)\\\"),\\n * mailTo,\\n * keccak256(bytes(mailContents))\\n * )));\\n * address signer = ECDSA.recover(digest, signature);\\n * ```\\n */\\n function _hashTypedDataV4(bytes32 structHash) internal view virtual returns (bytes32) {\\n return ECDSAUpgradeable.toTypedDataHash(_domainSeparatorV4(), structHash);\\n }\\n\\n /**\\n * @dev The hash of the name parameter for the EIP712 domain.\\n *\\n * NOTE: This function reads from storage by default, but can be redefined to return a constant value if gas costs\\n * are a concern.\\n */\\n function _EIP712NameHash() internal virtual view returns (bytes32) {\\n return _HASHED_NAME;\\n }\\n\\n /**\\n * @dev The hash of the version parameter for the EIP712 domain.\\n *\\n * NOTE: This function reads from storage by default, but can be redefined to return a constant value if gas costs\\n * are a concern.\\n */\\n function _EIP712VersionHash() internal virtual view returns (bytes32) {\\n return _HASHED_VERSION;\\n }\\n\\n /**\\n * @dev This empty reserved space is put in place to allow future versions to add new\\n * variables without shifting down storage in the inheritance chain.\\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\\n */\\n uint256[50] private __gap;\\n}\\n\",\"keccak256\":\"0xaf5a96100f421d61693605349511e43221d3c2e47d4b3efa87af2b936e2567fc\",\"license\":\"MIT\"},\"@openzeppelin/contracts/token/ERC20/IERC20.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.6.0) (token/ERC20/IERC20.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Interface of the ERC20 standard as defined in the EIP.\\n */\\ninterface IERC20 {\\n /**\\n * @dev Emitted when `value` tokens are moved from one account (`from`) to\\n * another (`to`).\\n *\\n * Note that `value` may be zero.\\n */\\n event Transfer(address indexed from, address indexed to, uint256 value);\\n\\n /**\\n * @dev Emitted when the allowance of a `spender` for an `owner` is set by\\n * a call to {approve}. `value` is the new allowance.\\n */\\n event Approval(address indexed owner, address indexed spender, uint256 value);\\n\\n /**\\n * @dev Returns the amount of tokens in existence.\\n */\\n function totalSupply() external view returns (uint256);\\n\\n /**\\n * @dev Returns the amount of tokens owned by `account`.\\n */\\n function balanceOf(address account) external view returns (uint256);\\n\\n /**\\n * @dev Moves `amount` tokens from the caller's account to `to`.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * Emits a {Transfer} event.\\n */\\n function transfer(address to, uint256 amount) external returns (bool);\\n\\n /**\\n * @dev Returns the remaining number of tokens that `spender` will be\\n * allowed to spend on behalf of `owner` through {transferFrom}. This is\\n * zero by default.\\n *\\n * This value changes when {approve} or {transferFrom} are called.\\n */\\n function allowance(address owner, address spender) external view returns (uint256);\\n\\n /**\\n * @dev Sets `amount` as the allowance of `spender` over the caller's tokens.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * IMPORTANT: Beware that changing an allowance with this method brings the risk\\n * that someone may use both the old and the new allowance by unfortunate\\n * transaction ordering. One possible solution to mitigate this race\\n * condition is to first reduce the spender's allowance to 0 and set the\\n * desired value afterwards:\\n * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729\\n *\\n * Emits an {Approval} event.\\n */\\n function approve(address spender, uint256 amount) external returns (bool);\\n\\n /**\\n * @dev Moves `amount` tokens from `from` to `to` using the\\n * allowance mechanism. `amount` is then deducted from the caller's\\n * allowance.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * Emits a {Transfer} event.\\n */\\n function transferFrom(\\n address from,\\n address to,\\n uint256 amount\\n ) external returns (bool);\\n}\\n\",\"keccak256\":\"0x9750c6b834f7b43000631af5cc30001c5f547b3ceb3635488f140f60e897ea6b\",\"license\":\"MIT\"},\"@openzeppelin/contracts/token/ERC20/extensions/draft-IERC20Permit.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (token/ERC20/extensions/draft-IERC20Permit.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Interface of the ERC20 Permit extension allowing approvals to be made via signatures, as defined in\\n * https://eips.ethereum.org/EIPS/eip-2612[EIP-2612].\\n *\\n * Adds the {permit} method, which can be used to change an account's ERC20 allowance (see {IERC20-allowance}) by\\n * presenting a message signed by the account. By not relying on {IERC20-approve}, the token holder account doesn't\\n * need to send a transaction, and thus is not required to hold Ether at all.\\n */\\ninterface IERC20Permit {\\n /**\\n * @dev Sets `value` as the allowance of `spender` over ``owner``'s tokens,\\n * given ``owner``'s signed approval.\\n *\\n * IMPORTANT: The same issues {IERC20-approve} has related to transaction\\n * ordering also apply here.\\n *\\n * Emits an {Approval} event.\\n *\\n * Requirements:\\n *\\n * - `spender` cannot be the zero address.\\n * - `deadline` must be a timestamp in the future.\\n * - `v`, `r` and `s` must be a valid `secp256k1` signature from `owner`\\n * over the EIP712-formatted function arguments.\\n * - the signature must use ``owner``'s current nonce (see {nonces}).\\n *\\n * For more information on the signature format, see the\\n * https://eips.ethereum.org/EIPS/eip-2612#specification[relevant EIP\\n * section].\\n */\\n function permit(\\n address owner,\\n address spender,\\n uint256 value,\\n uint256 deadline,\\n uint8 v,\\n bytes32 r,\\n bytes32 s\\n ) external;\\n\\n /**\\n * @dev Returns the current nonce for `owner`. This value must be\\n * included whenever a signature is generated for {permit}.\\n *\\n * Every successful call to {permit} increases ``owner``'s nonce by one. This\\n * prevents a signature from being used multiple times.\\n */\\n function nonces(address owner) external view returns (uint256);\\n\\n /**\\n * @dev Returns the domain separator used in the encoding of the signature for {permit}, as defined by {EIP712}.\\n */\\n // solhint-disable-next-line func-name-mixedcase\\n function DOMAIN_SEPARATOR() external view returns (bytes32);\\n}\\n\",\"keccak256\":\"0xf41ca991f30855bf80ffd11e9347856a517b977f0a6c2d52e6421a99b7840329\",\"license\":\"MIT\"},\"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.7.0) (token/ERC20/utils/SafeERC20.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../IERC20.sol\\\";\\nimport \\\"../extensions/draft-IERC20Permit.sol\\\";\\nimport \\\"../../../utils/Address.sol\\\";\\n\\n/**\\n * @title SafeERC20\\n * @dev Wrappers around ERC20 operations that throw on failure (when the token\\n * contract returns false). Tokens that return no value (and instead revert or\\n * throw on failure) are also supported, non-reverting calls are assumed to be\\n * successful.\\n * To use this library you can add a `using SafeERC20 for IERC20;` statement to your contract,\\n * which allows you to call the safe operations as `token.safeTransfer(...)`, etc.\\n */\\nlibrary SafeERC20 {\\n using Address for address;\\n\\n function safeTransfer(\\n IERC20 token,\\n address to,\\n uint256 value\\n ) internal {\\n _callOptionalReturn(token, abi.encodeWithSelector(token.transfer.selector, to, value));\\n }\\n\\n function safeTransferFrom(\\n IERC20 token,\\n address from,\\n address to,\\n uint256 value\\n ) internal {\\n _callOptionalReturn(token, abi.encodeWithSelector(token.transferFrom.selector, from, to, value));\\n }\\n\\n /**\\n * @dev Deprecated. This function has issues similar to the ones found in\\n * {IERC20-approve}, and its usage is discouraged.\\n *\\n * Whenever possible, use {safeIncreaseAllowance} and\\n * {safeDecreaseAllowance} instead.\\n */\\n function safeApprove(\\n IERC20 token,\\n address spender,\\n uint256 value\\n ) internal {\\n // safeApprove should only be called when setting an initial allowance,\\n // or when resetting it to zero. To increase and decrease it, use\\n // 'safeIncreaseAllowance' and 'safeDecreaseAllowance'\\n require(\\n (value == 0) || (token.allowance(address(this), spender) == 0),\\n \\\"SafeERC20: approve from non-zero to non-zero allowance\\\"\\n );\\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, value));\\n }\\n\\n function safeIncreaseAllowance(\\n IERC20 token,\\n address spender,\\n uint256 value\\n ) internal {\\n uint256 newAllowance = token.allowance(address(this), spender) + value;\\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));\\n }\\n\\n function safeDecreaseAllowance(\\n IERC20 token,\\n address spender,\\n uint256 value\\n ) internal {\\n unchecked {\\n uint256 oldAllowance = token.allowance(address(this), spender);\\n require(oldAllowance >= value, \\\"SafeERC20: decreased allowance below zero\\\");\\n uint256 newAllowance = oldAllowance - value;\\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));\\n }\\n }\\n\\n function safePermit(\\n IERC20Permit token,\\n address owner,\\n address spender,\\n uint256 value,\\n uint256 deadline,\\n uint8 v,\\n bytes32 r,\\n bytes32 s\\n ) internal {\\n uint256 nonceBefore = token.nonces(owner);\\n token.permit(owner, spender, value, deadline, v, r, s);\\n uint256 nonceAfter = token.nonces(owner);\\n require(nonceAfter == nonceBefore + 1, \\\"SafeERC20: permit did not succeed\\\");\\n }\\n\\n /**\\n * @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement\\n * on the return value: the return value is optional (but if data is returned, it must not be false).\\n * @param token The token targeted by the call.\\n * @param data The call data (encoded using abi.encode or one of its variants).\\n */\\n function _callOptionalReturn(IERC20 token, bytes memory data) private {\\n // We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since\\n // we're implementing it ourselves. We use {Address.functionCall} to perform this call, which verifies that\\n // the target address contains contract code and also asserts for success in the low-level call.\\n\\n bytes memory returndata = address(token).functionCall(data, \\\"SafeERC20: low-level call failed\\\");\\n if (returndata.length > 0) {\\n // Return data is optional\\n require(abi.decode(returndata, (bool)), \\\"SafeERC20: ERC20 operation did not succeed\\\");\\n }\\n }\\n}\\n\",\"keccak256\":\"0x032807210d1d7d218963d7355d62e021a84bf1b3339f4f50be2f63b53cccaf29\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/Address.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.7.0) (utils/Address.sol)\\n\\npragma solidity ^0.8.1;\\n\\n/**\\n * @dev Collection of functions related to the address type\\n */\\nlibrary Address {\\n /**\\n * @dev Returns true if `account` is a contract.\\n *\\n * [IMPORTANT]\\n * ====\\n * It is unsafe to assume that an address for which this function returns\\n * false is an externally-owned account (EOA) and not a contract.\\n *\\n * Among others, `isContract` will return false for the following\\n * types of addresses:\\n *\\n * - an externally-owned account\\n * - a contract in construction\\n * - an address where a contract will be created\\n * - an address where a contract lived, but was destroyed\\n * ====\\n *\\n * [IMPORTANT]\\n * ====\\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\\n *\\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\\n * constructor.\\n * ====\\n */\\n function isContract(address account) internal view returns (bool) {\\n // This method relies on extcodesize/address.code.length, which returns 0\\n // for contracts in construction, since the code is only stored at the end\\n // of the constructor execution.\\n\\n return account.code.length > 0;\\n }\\n\\n /**\\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\\n * `recipient`, forwarding all available gas and reverting on errors.\\n *\\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\\n * imposed by `transfer`, making them unable to receive funds via\\n * `transfer`. {sendValue} removes this limitation.\\n *\\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\\n *\\n * IMPORTANT: because control is transferred to `recipient`, care must be\\n * taken to not create reentrancy vulnerabilities. Consider using\\n * {ReentrancyGuard} or the\\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\\n */\\n function sendValue(address payable recipient, uint256 amount) internal {\\n require(address(this).balance >= amount, \\\"Address: insufficient balance\\\");\\n\\n (bool success, ) = recipient.call{value: amount}(\\\"\\\");\\n require(success, \\\"Address: unable to send value, recipient may have reverted\\\");\\n }\\n\\n /**\\n * @dev Performs a Solidity function call using a low level `call`. A\\n * plain `call` is an unsafe replacement for a function call: use this\\n * function instead.\\n *\\n * If `target` reverts with a revert reason, it is bubbled up by this\\n * function (like regular Solidity function calls).\\n *\\n * Returns the raw returned data. To convert to the expected return value,\\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\\n *\\n * Requirements:\\n *\\n * - `target` must be a contract.\\n * - calling `target` with `data` must not revert.\\n *\\n * _Available since v3.1._\\n */\\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\\n return functionCall(target, data, \\\"Address: low-level call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\\n * `errorMessage` as a fallback revert reason when `target` reverts.\\n *\\n * _Available since v3.1._\\n */\\n function functionCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n return functionCallWithValue(target, data, 0, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but also transferring `value` wei to `target`.\\n *\\n * Requirements:\\n *\\n * - the calling contract must have an ETH balance of at least `value`.\\n * - the called Solidity function must be `payable`.\\n *\\n * _Available since v3.1._\\n */\\n function functionCallWithValue(\\n address target,\\n bytes memory data,\\n uint256 value\\n ) internal returns (bytes memory) {\\n return functionCallWithValue(target, data, value, \\\"Address: low-level call with value failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\\n * with `errorMessage` as a fallback revert reason when `target` reverts.\\n *\\n * _Available since v3.1._\\n */\\n function functionCallWithValue(\\n address target,\\n bytes memory data,\\n uint256 value,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n require(address(this).balance >= value, \\\"Address: insufficient balance for call\\\");\\n require(isContract(target), \\\"Address: call to non-contract\\\");\\n\\n (bool success, bytes memory returndata) = target.call{value: value}(data);\\n return verifyCallResult(success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but performing a static call.\\n *\\n * _Available since v3.3._\\n */\\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\\n return functionStaticCall(target, data, \\\"Address: low-level static call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\\n * but performing a static call.\\n *\\n * _Available since v3.3._\\n */\\n function functionStaticCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal view returns (bytes memory) {\\n require(isContract(target), \\\"Address: static call to non-contract\\\");\\n\\n (bool success, bytes memory returndata) = target.staticcall(data);\\n return verifyCallResult(success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but performing a delegate call.\\n *\\n * _Available since v3.4._\\n */\\n function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {\\n return functionDelegateCall(target, data, \\\"Address: low-level delegate call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\\n * but performing a delegate call.\\n *\\n * _Available since v3.4._\\n */\\n function functionDelegateCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n require(isContract(target), \\\"Address: delegate call to non-contract\\\");\\n\\n (bool success, bytes memory returndata) = target.delegatecall(data);\\n return verifyCallResult(success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the\\n * revert reason using the provided one.\\n *\\n * _Available since v4.3._\\n */\\n function verifyCallResult(\\n bool success,\\n bytes memory returndata,\\n string memory errorMessage\\n ) internal pure returns (bytes memory) {\\n if (success) {\\n return returndata;\\n } else {\\n // Look for revert reason and bubble it up if present\\n if (returndata.length > 0) {\\n // The easiest way to bubble the revert reason is using memory via assembly\\n /// @solidity memory-safe-assembly\\n assembly {\\n let returndata_size := mload(returndata)\\n revert(add(32, returndata), returndata_size)\\n }\\n } else {\\n revert(errorMessage);\\n }\\n }\\n }\\n}\\n\",\"keccak256\":\"0xd6153ce99bcdcce22b124f755e72553295be6abcd63804cfdffceb188b8bef10\",\"license\":\"MIT\"},\"contracts/agToken/AgToken.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-3.0\\n\\npragma solidity ^0.8.12;\\n\\n/*\\n * \\u2588 \\n ***** \\u2593\\u2593\\u2593 \\n * \\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593 \\n * ///. \\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593 \\n ***** //////// \\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593 \\n * ///////////// \\u2593\\u2593\\u2593 \\n \\u2593\\u2593 ////////////////// \\u2588 \\u2593\\u2593 \\n \\u2593\\u2593 \\u2593\\u2593 /////////////////////// \\u2593\\u2593 \\u2593\\u2593 \\n \\u2593\\u2593 \\u2593\\u2593 //////////////////////////// \\u2593\\u2593 \\u2593\\u2593 \\n \\u2593\\u2593 \\u2593\\u2593 /////////\\u2593\\u2593\\u2593///////\\u2593\\u2593\\u2593///////// \\u2593\\u2593 \\u2593\\u2593 \\n \\u2593\\u2593 ,////////////////////////////////////// \\u2593\\u2593 \\u2593\\u2593 \\n \\u2593\\u2593 ////////////////////////////////////////// \\u2593\\u2593 \\n \\u2593\\u2593 //////////////////////\\u2593\\u2593\\u2593\\u2593///////////////////// \\n ,//////////////////////////////////////////////////// \\n .////////////////////////////////////////////////////////// \\n .//////////////////////////\\u2588\\u2588.,//////////////////////////\\u2588 \\n .//////////////////////\\u2588\\u2588\\u2588\\u2588..,./////////////////////\\u2588\\u2588 \\n ...////////////////\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588.....,.////////////////\\u2588\\u2588\\u2588 \\n ,.,////////////\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588 ........,///////////\\u2588\\u2588\\u2588\\u2588 \\n .,.,//////\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588 ,.......///////\\u2588\\u2588\\u2588\\u2588 \\n ,..//\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588 ........./\\u2588\\u2588\\u2588\\u2588 \\n ..,\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588 .....,\\u2588\\u2588\\u2588 \\n .\\u2588\\u2588 ,.,\\u2588 \\n \\n \\n \\n \\u2593\\u2593 \\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593 \\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593 \\u2593\\u2593 \\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593 \\n \\u2593\\u2593\\u2593\\u2593\\u2593\\u2593 \\u2593\\u2593\\u2593 \\u2593\\u2593\\u2593 \\u2593\\u2593\\u2593 \\u2593\\u2593 \\u2593\\u2593 \\u2593\\u2593\\u2593\\u2593 \\n \\u2593\\u2593\\u2593 \\u2593\\u2593\\u2593 \\u2593\\u2593\\u2593 \\u2593\\u2593\\u2593 \\u2593\\u2593\\u2593 \\u2593\\u2593\\u2593 \\u2593\\u2593 \\u2593\\u2593\\u2593\\u2593\\u2593 \\n \\u2593\\u2593\\u2593 \\u2593\\u2593 \\u2593\\u2593\\u2593 \\u2593\\u2593\\u2593 \\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593 \\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593 \\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593 \\n*/\\n\\nimport \\\"../interfaces/IAgToken.sol\\\";\\nimport \\\"../interfaces/ITreasury.sol\\\";\\nimport \\\"@openzeppelin/contracts-upgradeable/token/ERC20/extensions/draft-ERC20PermitUpgradeable.sol\\\";\\n\\n/// @title AgToken\\n/// @author Angle Labs, Inc.\\n/// @notice Base contract for Angle agTokens on Ethereum and on other chains\\n/// @dev By default, agTokens are ERC-20 tokens with 18 decimals\\ncontract AgToken is IAgToken, ERC20PermitUpgradeable {\\n // =========================== PARAMETERS / VARIABLES ==========================\\n\\n /// @inheritdoc IAgToken\\n mapping(address => bool) public isMinter;\\n /// @notice Reference to the treasury contract which can grant minting rights\\n address public treasury;\\n\\n // =================================== EVENTS ==================================\\n\\n event TreasuryUpdated(address indexed _treasury);\\n event MinterToggled(address indexed minter);\\n\\n // =================================== ERRORS ==================================\\n\\n error BurnAmountExceedsAllowance();\\n error InvalidSender();\\n error InvalidTreasury();\\n error NotMinter();\\n error NotTreasury();\\n\\n // ================================ CONSTRUCTOR ================================\\n\\n /// @custom:oz-upgrades-unsafe-allow constructor\\n constructor() initializer {}\\n\\n /// @notice Initializes the `AgToken` contract\\n function initialize(string memory name_, string memory symbol_, address _treasury) external {\\n _initialize(name_, symbol_, _treasury);\\n }\\n\\n /// @notice Initializes the contract\\n function _initialize(string memory name_, string memory symbol_, address _treasury) internal virtual initializer {\\n if (address(ITreasury(_treasury).stablecoin()) != address(this)) revert InvalidTreasury();\\n __ERC20Permit_init(name_);\\n __ERC20_init(name_, symbol_);\\n treasury = _treasury;\\n emit TreasuryUpdated(_treasury);\\n }\\n\\n // ================================= MODIFIERS =================================\\n\\n /// @notice Checks to see if it is the `Treasury` calling this contract\\n modifier onlyTreasury() {\\n if (msg.sender != treasury) revert NotTreasury();\\n _;\\n }\\n\\n /// @notice Checks whether the sender has the minting right\\n modifier onlyMinter() {\\n if (!isMinter[msg.sender]) revert NotMinter();\\n _;\\n }\\n\\n // ============================= EXTERNAL FUNCTION =============================\\n\\n /// @notice Allows anyone to burn stablecoins\\n /// @param amount Amount of stablecoins to burn\\n /// @dev This function can typically be called if there is a settlement mechanism to burn stablecoins\\n function burnStablecoin(uint256 amount) external {\\n _burn(msg.sender, amount);\\n }\\n\\n // ========================= MINTER ROLE ONLY FUNCTIONS ========================\\n\\n /// @inheritdoc IAgToken\\n function burnSelf(uint256 amount, address burner) external onlyMinter {\\n _burn(burner, amount);\\n }\\n\\n /// @inheritdoc IAgToken\\n function burnFrom(uint256 amount, address burner, address sender) external onlyMinter {\\n if (burner != sender) {\\n uint256 currentAllowance = allowance(burner, sender);\\n if (currentAllowance < amount) revert BurnAmountExceedsAllowance();\\n _approve(burner, sender, currentAllowance - amount);\\n }\\n _burn(burner, amount);\\n }\\n\\n /// @inheritdoc IAgToken\\n function mint(address account, uint256 amount) external onlyMinter {\\n _mint(account, amount);\\n }\\n\\n // ========================== GOVERNANCE ONLY FUNCTIONS ==========================\\n\\n /// @inheritdoc IAgToken\\n function addMinter(address minter) external onlyTreasury {\\n isMinter[minter] = true;\\n emit MinterToggled(minter);\\n }\\n\\n /// @inheritdoc IAgToken\\n function removeMinter(address minter) external {\\n if (msg.sender != address(treasury) && msg.sender != minter) revert InvalidSender();\\n isMinter[minter] = false;\\n emit MinterToggled(minter);\\n }\\n\\n /// @inheritdoc IAgToken\\n function setTreasury(address _treasury) external virtual onlyTreasury {\\n treasury = _treasury;\\n emit TreasuryUpdated(_treasury);\\n }\\n}\\n\",\"keccak256\":\"0x671d54d7840179050e859cf09662fe0e2c34cfaf5ec3782148d6c29e77c54d17\",\"license\":\"GPL-3.0\"},\"contracts/agToken/AgTokenSideChainMultiBridge.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-3.0\\n\\npragma solidity ^0.8.12;\\n\\nimport \\\"./AgToken.sol\\\";\\nimport \\\"@openzeppelin/contracts/token/ERC20/IERC20.sol\\\";\\nimport \\\"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\\\";\\n\\n/// @title AgTokenSideChainMultiBridge\\n/// @author Angle Labs, Inc.\\n/// @notice Contract for Angle agTokens on other chains than Ethereum mainnet\\n/// @dev This contract supports bridge tokens having a minting right on the stablecoin (also referred to as the canonical\\n/// or the native token)\\ncontract AgTokenSideChainMultiBridge is AgToken {\\n using SafeERC20 for IERC20;\\n\\n /// @notice Base used for fee computation\\n uint256 public constant BASE_PARAMS = 1e9;\\n\\n // =============================== BRIDGING DATA ===============================\\n\\n /// @notice Struct with some data about a specific bridge token\\n struct BridgeDetails {\\n // Limit on the balance of bridge token held by the contract: it is designed\\n // to reduce the exposure of the system to hacks\\n uint256 limit;\\n // Limit on the hourly volume of token minted through this bridge\\n // Technically the limit over a rolling hour is hourlyLimit x2 as hourly limit\\n // is enforced only between x:00 and x+1:00\\n uint256 hourlyLimit;\\n // Fee taken for swapping in and out the token\\n uint64 fee;\\n // Whether the associated token is allowed or not\\n bool allowed;\\n // Whether swapping in and out from the associated token is paused or not\\n bool paused;\\n }\\n\\n /// @notice Maps a bridge token to data\\n mapping(address => BridgeDetails) public bridges;\\n /// @notice List of all bridge tokens\\n address[] public bridgeTokensList;\\n /// @notice Maps a bridge token to the associated hourly volume\\n mapping(address => mapping(uint256 => uint256)) public usage;\\n /// @notice Maps an address to whether it is exempt of fees for when it comes to swapping in and out\\n mapping(address => uint256) public isFeeExempt;\\n /// @notice Limit to the amount of tokens that can be sent from that chain to another chain\\n uint256 public chainTotalHourlyLimit;\\n /// @notice Usage per hour on that chain. Maps an hourly timestamp to the total volume swapped out on the chain\\n mapping(uint256 => uint256) public chainTotalUsage;\\n\\n // =================================== EVENTS ==================================\\n\\n event BridgeTokenAdded(address indexed bridgeToken, uint256 limit, uint256 hourlyLimit, uint64 fee, bool paused);\\n event BridgeTokenToggled(address indexed bridgeToken, bool toggleStatus);\\n event BridgeTokenRemoved(address indexed bridgeToken);\\n event BridgeTokenFeeUpdated(address indexed bridgeToken, uint64 fee);\\n event BridgeTokenLimitUpdated(address indexed bridgeToken, uint256 limit);\\n event BridgeTokenHourlyLimitUpdated(address indexed bridgeToken, uint256 hourlyLimit);\\n event HourlyLimitUpdated(uint256 hourlyLimit);\\n event Recovered(address indexed token, address indexed to, uint256 amount);\\n event FeeToggled(address indexed theAddress, uint256 toggleStatus);\\n\\n // =================================== ERRORS ==================================\\n\\n error AssetStillControlledInReserves();\\n error HourlyLimitExceeded();\\n error InvalidToken();\\n error NotGovernor();\\n error NotGovernorOrGuardian();\\n error TooBigAmount();\\n error TooHighParameterValue();\\n error ZeroAddress();\\n\\n // ================================= MODIFIERS =================================\\n\\n /// @notice Checks whether the `msg.sender` has the governor role or not\\n modifier onlyGovernor() {\\n if (!ITreasury(treasury).isGovernor(msg.sender)) revert NotGovernor();\\n _;\\n }\\n\\n /// @notice Checks whether the `msg.sender` has the governor role or the guardian role\\n modifier onlyGovernorOrGuardian() {\\n if (!ITreasury(treasury).isGovernorOrGuardian(msg.sender)) revert NotGovernorOrGuardian();\\n _;\\n }\\n\\n // ===================== EXTERNAL PERMISSIONLESS FUNCTIONS =====================\\n\\n /// @notice Returns the list of all supported bridge tokens\\n /// @dev Helpful for UIs\\n function allBridgeTokens() external view returns (address[] memory) {\\n return bridgeTokensList;\\n }\\n\\n /// @notice Returns the current volume for a bridge, for the current hour\\n /// @param bridgeToken Bridge used to mint\\n /// @dev Helpful for UIs\\n function currentUsage(address bridgeToken) external view returns (uint256) {\\n return usage[bridgeToken][block.timestamp / 3600];\\n }\\n\\n /// @notice Returns the current total volume on the chain for the current hour\\n /// @dev Helpful for UIs\\n function currentTotalUsage() external view returns (uint256) {\\n return chainTotalUsage[block.timestamp / 3600];\\n }\\n\\n /// @notice Mints the canonical token from a supported bridge token\\n /// @param bridgeToken Bridge token to use to mint\\n /// @param amount Amount of bridge tokens to send\\n /// @param to Address to which the stablecoin should be sent\\n /// @return Amount of the canonical stablecoin actually minted\\n /// @dev Some fees may be taken by the protocol depending on the token used and on the address calling\\n function swapIn(address bridgeToken, uint256 amount, address to) external returns (uint256) {\\n BridgeDetails memory bridgeDetails = bridges[bridgeToken];\\n if (!bridgeDetails.allowed || bridgeDetails.paused) revert InvalidToken();\\n uint256 balance = IERC20(bridgeToken).balanceOf(address(this));\\n if (balance + amount > bridgeDetails.limit) {\\n // In case someone maliciously sends tokens to this contract\\n // Or the limit changes\\n if (bridgeDetails.limit > balance) amount = bridgeDetails.limit - balance;\\n else {\\n amount = 0;\\n }\\n }\\n\\n // Checking requirement on the hourly volume\\n uint256 hour = block.timestamp / 3600;\\n uint256 hourlyUsage = usage[bridgeToken][hour];\\n if (hourlyUsage + amount > bridgeDetails.hourlyLimit) {\\n // Edge case when the hourly limit changes\\n amount = bridgeDetails.hourlyLimit > hourlyUsage ? bridgeDetails.hourlyLimit - hourlyUsage : 0;\\n }\\n usage[bridgeToken][hour] = hourlyUsage + amount;\\n\\n IERC20(bridgeToken).safeTransferFrom(msg.sender, address(this), amount);\\n uint256 canonicalOut = amount;\\n // Computing fees\\n if (isFeeExempt[msg.sender] == 0) {\\n canonicalOut -= (canonicalOut * bridgeDetails.fee) / BASE_PARAMS;\\n }\\n _mint(to, canonicalOut);\\n return canonicalOut;\\n }\\n\\n /// @notice Burns the canonical token in exchange for a bridge token\\n /// @param bridgeToken Bridge token required\\n /// @param amount Amount of canonical tokens to burn\\n /// @param to Address to which the bridge token should be sent\\n /// @return Amount of bridge tokens actually sent back\\n /// @dev Some fees may be taken by the protocol depending on the token used and on the address calling\\n function swapOut(address bridgeToken, uint256 amount, address to) external returns (uint256) {\\n BridgeDetails memory bridgeDetails = bridges[bridgeToken];\\n if (!bridgeDetails.allowed || bridgeDetails.paused) revert InvalidToken();\\n\\n uint256 hour = block.timestamp / 3600;\\n uint256 hourlyUsage = chainTotalUsage[hour] + amount;\\n // If the amount being swapped out exceeds the limit, we revert\\n // We don't want to change the amount being swapped out.\\n // The user can decide to send another tx with the correct amount to reach the limit\\n if (hourlyUsage > chainTotalHourlyLimit) revert HourlyLimitExceeded();\\n chainTotalUsage[hour] = hourlyUsage;\\n\\n _burn(msg.sender, amount);\\n uint256 bridgeOut = amount;\\n if (isFeeExempt[msg.sender] == 0) {\\n bridgeOut -= (bridgeOut * bridgeDetails.fee) / BASE_PARAMS;\\n }\\n IERC20(bridgeToken).safeTransfer(to, bridgeOut);\\n return bridgeOut;\\n }\\n\\n // ============================ GOVERNANCE FUNCTIONS ===========================\\n\\n /// @notice Adds support for a bridge token\\n /// @param bridgeToken Bridge token to add: it should be a version of the stablecoin from another bridge\\n /// @param limit Limit on the balance of bridge token this contract could hold\\n /// @param hourlyLimit Limit on the hourly volume for this bridge\\n /// @param paused Whether swapping for this token should be paused or not\\n /// @param fee Fee taken upon swapping for or against this token\\n function addBridgeToken(\\n address bridgeToken,\\n uint256 limit,\\n uint256 hourlyLimit,\\n uint64 fee,\\n bool paused\\n ) external onlyGovernor {\\n if (bridges[bridgeToken].allowed || bridgeToken == address(0)) revert InvalidToken();\\n if (fee > BASE_PARAMS) revert TooHighParameterValue();\\n BridgeDetails memory _bridge;\\n _bridge.limit = limit;\\n _bridge.hourlyLimit = hourlyLimit;\\n _bridge.paused = paused;\\n _bridge.fee = fee;\\n _bridge.allowed = true;\\n bridges[bridgeToken] = _bridge;\\n bridgeTokensList.push(bridgeToken);\\n emit BridgeTokenAdded(bridgeToken, limit, hourlyLimit, fee, paused);\\n }\\n\\n /// @notice Removes support for a token\\n /// @param bridgeToken Address of the bridge token to remove support for\\n function removeBridgeToken(address bridgeToken) external onlyGovernor {\\n if (IERC20(bridgeToken).balanceOf(address(this)) != 0) revert AssetStillControlledInReserves();\\n delete bridges[bridgeToken];\\n // Deletion from `bridgeTokensList` loop\\n uint256 bridgeTokensListLength = bridgeTokensList.length;\\n for (uint256 i; i < bridgeTokensListLength - 1; ++i) {\\n if (bridgeTokensList[i] == bridgeToken) {\\n // Replace the `bridgeToken` to remove with the last of the list\\n bridgeTokensList[i] = bridgeTokensList[bridgeTokensListLength - 1];\\n break;\\n }\\n }\\n // Remove last element in array\\n bridgeTokensList.pop();\\n emit BridgeTokenRemoved(bridgeToken);\\n }\\n\\n /// @notice Recovers any ERC20 token\\n /// @dev Can be used to withdraw bridge tokens for them to be de-bridged on mainnet\\n function recoverERC20(address tokenAddress, address to, uint256 amountToRecover) external onlyGovernor {\\n IERC20(tokenAddress).safeTransfer(to, amountToRecover);\\n emit Recovered(tokenAddress, to, amountToRecover);\\n }\\n\\n /// @notice Updates the `limit` amount for `bridgeToken`\\n function setLimit(address bridgeToken, uint256 limit) external onlyGovernorOrGuardian {\\n if (!bridges[bridgeToken].allowed) revert InvalidToken();\\n bridges[bridgeToken].limit = limit;\\n emit BridgeTokenLimitUpdated(bridgeToken, limit);\\n }\\n\\n /// @notice Updates the `hourlyLimit` amount for `bridgeToken`\\n function setHourlyLimit(address bridgeToken, uint256 hourlyLimit) external onlyGovernorOrGuardian {\\n if (!bridges[bridgeToken].allowed) revert InvalidToken();\\n bridges[bridgeToken].hourlyLimit = hourlyLimit;\\n emit BridgeTokenHourlyLimitUpdated(bridgeToken, hourlyLimit);\\n }\\n\\n /// @notice Updates the `chainTotalHourlyLimit` amount\\n function setChainTotalHourlyLimit(uint256 hourlyLimit) external onlyGovernorOrGuardian {\\n chainTotalHourlyLimit = hourlyLimit;\\n emit HourlyLimitUpdated(hourlyLimit);\\n }\\n\\n /// @notice Updates the `fee` value for `bridgeToken`\\n function setSwapFee(address bridgeToken, uint64 fee) external onlyGovernorOrGuardian {\\n if (!bridges[bridgeToken].allowed) revert InvalidToken();\\n if (fee > BASE_PARAMS) revert TooHighParameterValue();\\n bridges[bridgeToken].fee = fee;\\n emit BridgeTokenFeeUpdated(bridgeToken, fee);\\n }\\n\\n /// @notice Pauses or unpauses swapping in and out for a token\\n function toggleBridge(address bridgeToken) external onlyGovernorOrGuardian {\\n if (!bridges[bridgeToken].allowed) revert InvalidToken();\\n bool pausedStatus = bridges[bridgeToken].paused;\\n bridges[bridgeToken].paused = !pausedStatus;\\n emit BridgeTokenToggled(bridgeToken, !pausedStatus);\\n }\\n\\n /// @notice Toggles fees for the address `theAddress`\\n function toggleFeesForAddress(address theAddress) external onlyGovernorOrGuardian {\\n uint256 feeExemptStatus = 1 - isFeeExempt[theAddress];\\n isFeeExempt[theAddress] = feeExemptStatus;\\n emit FeeToggled(theAddress, feeExemptStatus);\\n }\\n}\\n\",\"keccak256\":\"0x9782497e84a1dc4bc468778ede4aceb35cebf74e4159e2af8f469f49312c3841\",\"license\":\"GPL-3.0\"},\"contracts/interfaces/IAgToken.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-3.0\\n\\npragma solidity ^0.8.12;\\n\\nimport \\\"@openzeppelin/contracts-upgradeable/token/ERC20/IERC20Upgradeable.sol\\\";\\n\\n/// @title IAgToken\\n/// @author Angle Labs, Inc.\\n/// @notice Interface for the stablecoins `AgToken` contracts\\n/// @dev This interface only contains functions of the `AgToken` contract which are called by other contracts\\n/// of this module or of the first module of the Angle Protocol\\ninterface IAgToken is IERC20Upgradeable {\\n // ======================= Minter Role Only Functions ===========================\\n\\n /// @notice Lets the `StableMaster` contract or another whitelisted contract mint agTokens\\n /// @param account Address to mint to\\n /// @param amount Amount to mint\\n /// @dev The contracts allowed to issue agTokens are the `StableMaster` contract, `VaultManager` contracts\\n /// associated to this stablecoin as well as the flash loan module (if activated) and potentially contracts\\n /// whitelisted by governance\\n function mint(address account, uint256 amount) external;\\n\\n /// @notice Burns `amount` tokens from a `burner` address after being asked to by `sender`\\n /// @param amount Amount of tokens to burn\\n /// @param burner Address to burn from\\n /// @param sender Address which requested the burn from `burner`\\n /// @dev This method is to be called by a contract with the minter right after being requested\\n /// to do so by a `sender` address willing to burn tokens from another `burner` address\\n /// @dev The method checks the allowance between the `sender` and the `burner`\\n function burnFrom(uint256 amount, address burner, address sender) external;\\n\\n /// @notice Burns `amount` tokens from a `burner` address\\n /// @param amount Amount of tokens to burn\\n /// @param burner Address to burn from\\n /// @dev This method is to be called by a contract with a minter right on the AgToken after being\\n /// requested to do so by an address willing to burn tokens from its address\\n function burnSelf(uint256 amount, address burner) external;\\n\\n // ========================= Treasury Only Functions ===========================\\n\\n /// @notice Adds a minter in the contract\\n /// @param minter Minter address to add\\n /// @dev Zero address checks are performed directly in the `Treasury` contract\\n function addMinter(address minter) external;\\n\\n /// @notice Removes a minter from the contract\\n /// @param minter Minter address to remove\\n /// @dev This function can also be called by a minter wishing to revoke itself\\n function removeMinter(address minter) external;\\n\\n /// @notice Sets a new treasury contract\\n /// @param _treasury New treasury address\\n function setTreasury(address _treasury) external;\\n\\n // ========================= External functions ================================\\n\\n /// @notice Checks whether an address has the right to mint agTokens\\n /// @param minter Address for which the minting right should be checked\\n /// @return Whether the address has the right to mint agTokens or not\\n function isMinter(address minter) external view returns (bool);\\n\\n /// @notice Get the associated treasury\\n function treasury() external view returns (address);\\n}\\n\",\"keccak256\":\"0x0c83efcfc1fb9ae9ba830f7b89e3dab9abf6ad7a6205a31aa35fbccaa837dcdc\",\"license\":\"GPL-3.0\"},\"contracts/interfaces/ICoreBorrow.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-3.0\\n\\npragma solidity ^0.8.12;\\n\\n/// @title ICoreBorrow\\n/// @author Angle Labs, Inc.\\n/// @notice Interface for the `CoreBorrow` contract\\n/// @dev This interface only contains functions of the `CoreBorrow` contract which are called by other contracts\\n/// of this module\\ninterface ICoreBorrow {\\n /// @notice Checks if an address corresponds to a treasury of a stablecoin with a flash loan\\n /// module initialized on it\\n /// @param treasury Address to check\\n /// @return Whether the address has the `FLASHLOANER_TREASURY_ROLE` or not\\n function isFlashLoanerTreasury(address treasury) external view returns (bool);\\n\\n /// @notice Checks whether an address is governor of the Angle Protocol or not\\n /// @param admin Address to check\\n /// @return Whether the address has the `GOVERNOR_ROLE` or not\\n function isGovernor(address admin) external view returns (bool);\\n\\n /// @notice Checks whether an address is governor or a guardian of the Angle Protocol or not\\n /// @param admin Address to check\\n /// @return Whether the address has the `GUARDIAN_ROLE` or not\\n /// @dev Governance should make sure when adding a governor to also give this governor the guardian\\n /// role by calling the `addGovernor` function\\n function isGovernorOrGuardian(address admin) external view returns (bool);\\n}\\n\",\"keccak256\":\"0x10249210cbf522775f040baf981d7d037472168ce2746d87473ac7c29a34e62e\",\"license\":\"GPL-3.0\"},\"contracts/interfaces/IFlashAngle.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-3.0\\n\\npragma solidity ^0.8.12;\\n\\nimport \\\"./IAgToken.sol\\\";\\nimport \\\"./ICoreBorrow.sol\\\";\\n\\n/// @title IFlashAngle\\n/// @author Angle Labs, Inc.\\n/// @notice Interface for the `FlashAngle` contract\\n/// @dev This interface only contains functions of the contract which are called by other contracts\\n/// of this module\\ninterface IFlashAngle {\\n /// @notice Reference to the `CoreBorrow` contract managing the FlashLoan module\\n function core() external view returns (ICoreBorrow);\\n\\n /// @notice Sends the fees taken from flash loans to the treasury contract associated to the stablecoin\\n /// @param stablecoin Stablecoin from which profits should be sent\\n /// @return balance Amount of profits sent\\n /// @dev This function can only be called by the treasury contract\\n function accrueInterestToTreasury(IAgToken stablecoin) external returns (uint256 balance);\\n\\n /// @notice Adds support for a stablecoin\\n /// @param _treasury Treasury associated to the stablecoin to add support for\\n /// @dev This function can only be called by the `CoreBorrow` contract\\n function addStablecoinSupport(address _treasury) external;\\n\\n /// @notice Removes support for a stablecoin\\n /// @param _treasury Treasury associated to the stablecoin to remove support for\\n /// @dev This function can only be called by the `CoreBorrow` contract\\n function removeStablecoinSupport(address _treasury) external;\\n\\n /// @notice Sets a new core contract\\n /// @param _core Core contract address to set\\n /// @dev This function can only be called by the `CoreBorrow` contract\\n function setCore(address _core) external;\\n}\\n\",\"keccak256\":\"0x39b0097f695b9e934bccdc72676c91513f1077cc5d0fd151908fd25a7c5cfbe4\",\"license\":\"GPL-3.0\"},\"contracts/interfaces/ITreasury.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-3.0\\n\\npragma solidity ^0.8.12;\\n\\nimport \\\"./IAgToken.sol\\\";\\nimport \\\"./ICoreBorrow.sol\\\";\\nimport \\\"./IFlashAngle.sol\\\";\\n\\n/// @title ITreasury\\n/// @author Angle Labs, Inc.\\n/// @notice Interface for the `Treasury` contract\\n/// @dev This interface only contains functions of the `Treasury` which are called by other contracts\\n/// of this module\\ninterface ITreasury {\\n /// @notice Stablecoin handled by this `treasury` contract\\n function stablecoin() external view returns (IAgToken);\\n\\n /// @notice Checks whether a given address has the governor role\\n /// @param admin Address to check\\n /// @return Whether the address has the governor role\\n /// @dev Access control is only kept in the `CoreBorrow` contract\\n function isGovernor(address admin) external view returns (bool);\\n\\n /// @notice Checks whether a given address has the guardian or the governor role\\n /// @param admin Address to check\\n /// @return Whether the address has the guardian or the governor role\\n /// @dev Access control is only kept in the `CoreBorrow` contract which means that this function\\n /// queries the `CoreBorrow` contract\\n function isGovernorOrGuardian(address admin) external view returns (bool);\\n\\n /// @notice Checks whether a given address has well been initialized in this contract\\n /// as a `VaultManager`\\n /// @param _vaultManager Address to check\\n /// @return Whether the address has been initialized or not\\n function isVaultManager(address _vaultManager) external view returns (bool);\\n\\n /// @notice Sets a new flash loan module for this stablecoin\\n /// @param _flashLoanModule Reference to the new flash loan module\\n /// @dev This function removes the minting right to the old flash loan module and grants\\n /// it to the new module\\n function setFlashLoanModule(address _flashLoanModule) external;\\n\\n /// @notice Gets the vault manager list\\n function vaultManagerList(uint256 i) external returns (address);\\n}\\n\",\"keccak256\":\"0x06c2f781c08732ce1b5845c083af5742716245baa6c519bd737f32b230a884c1\",\"license\":\"GPL-3.0\"}},\"version\":1}", + "bytecode": "0x60806040523480156200001157600080fd5b50600054610100900460ff1615808015620000335750600054600160ff909116105b8062000063575062000050306200013d60201b6200273a1760201c565b15801562000063575060005460ff166001145b620000cb5760405162461bcd60e51b815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201526d191e481a5b9a5d1a585b1a5e995960921b606482015260840160405180910390fd5b6000805460ff191660011790558015620000ef576000805461ff0019166101001790555b801562000136576000805461ff0019169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15b506200014c565b6001600160a01b03163b151590565b6146d0806200015c6000396000f3fe608060405234801561001057600080fd5b50600436106102ff5760003560e01c806361d027b31161019c5780639f48118f116100ee578063ced67f0c11610097578063dd62ed3e11610071578063dd62ed3e14610724578063e3e286551461076a578063f0f442601461077d57600080fd5b8063ced67f0c1461066b578063d44ad63f146106fe578063d505accf1461071157600080fd5b8063aa271e1a116100c8578063aa271e1a14610620578063ba330bd714610643578063cd4839ca1461065657600080fd5b80639f48118f146105ef578063a457c2d7146105fa578063a9059cbb1461060d57600080fd5b80637ecebe001161015057806395d89b411161012a57806395d89b41146105c1578063983b2d56146105c95780639e4e0dae146105dc57600080fd5b80637ecebe00146105705780638933fb791461058357806390218cff146105ae57600080fd5b80637334d020116101815780637334d020146105425780637d4c9c2d146105555780637d74e25f1461056857600080fd5b806361d027b3146104c757806370a082311461050c57600080fd5b80633092afd511610255578063395093511161020957806340c10f19116101e357806340c10f19146104815780634dc32fcc146104945780635bfbec96146104a757600080fd5b8063395093511461043b5780633a55f89d1461044e5780633f4218e01461046157600080fd5b8063350ebe041161023a578063350ebe041461040d5780633644e5151461042057806336db43b51461042857600080fd5b80633092afd5146103eb578063313ce567146103fe57600080fd5b8063151dd755116102b757806323b872dd1161029157806323b872dd146103b25780632b471d8e146103c55780632e403e14146103d857600080fd5b8063151dd7551461038057806318160ddd146103a15780632342fb0e146103a957600080fd5b80630919a951116102e85780630919a95114610337578063095ea7b31461034a5780631171bda91461036d57600080fd5b806306fdde0314610304578063077f224a14610322575b600080fd5b61030c610790565b6040516103199190613e48565b60405180910390f35b610335610330366004613f95565b610822565b005b61033561034536600461400d565b610832565b61035d61035836600461402a565b610995565b6040519015158152602001610319565b61033561037b366004614056565b6109af565b61039361038e366004614097565b610b04565b604051908152602001610319565b603554610393565b61039360d25481565b61035d6103c0366004614056565b610dbe565b6103356103d33660046140ce565b610de2565b6103356103e636600461400d565b610e39565b6103356103f936600461400d565b6111e8565b60405160128152602001610319565b61033561041b3660046140fe565b6112d1565b6103936113da565b61033561043636600461402a565b6113e9565b61035d61044936600461402a565b611579565b61033561045c366004614135565b6115c0565b61039361046f36600461400d565b60d16020526000908152604090205481565b61033561048f36600461402a565b6116c3565b6103936104a236600461400d565b611716565b6103936104b5366004614135565b60d36020526000908152604090205481565b60cd546104e79073ffffffffffffffffffffffffffffffffffffffff1681565b60405173ffffffffffffffffffffffffffffffffffffffff9091168152602001610319565b61039361051a36600461400d565b73ffffffffffffffffffffffffffffffffffffffff1660009081526033602052604090205490565b61033561055036600461402a565b61175e565b610335610563366004614179565b6118f1565b610393611c59565b61039361057e36600461400d565b611c7e565b61039361059136600461402a565b60d060209081526000928352604080842090915290825290205481565b6103356105bc366004614135565b611ca9565b61030c611cb6565b6103356105d736600461400d565b611cc5565b6103356105ea3660046141d6565b611d8d565b610393633b9aca0081565b61035d61060836600461402a565b611f99565b61035d61061b36600461402a565b61206f565b61035d61062e36600461400d565b60cc6020526000908152604090205460ff1681565b6104e7610651366004614135565b61207d565b61065e6120b4565b604051610319919061420b565b6106c561067936600461400d565b60ce6020526000908152604090208054600182015460029092015490919067ffffffffffffffff81169060ff680100000000000000008204811691690100000000000000000090041685565b60408051958652602086019490945267ffffffffffffffff9092169284019290925290151560608301521515608082015260a001610319565b61039361070c366004614097565b612122565b61033561071f366004614265565b6122e7565b6103936107323660046142dc565b73ffffffffffffffffffffffffffffffffffffffff918216600090815260346020908152604080832093909416825291909152205490565b61033561077836600461400d565b6124a6565b61033561078b36600461400d565b61267a565b60606036805461079f9061430a565b80601f01602080910402602001604051908101604052809291908181526020018280546107cb9061430a565b80156108185780601f106107ed57610100808354040283529160200191610818565b820191906000526020600020905b8154815290600101906020018083116107fb57829003601f168201915b5050505050905090565b61082d838383612756565b505050565b60cd546040517f521d4de900000000000000000000000000000000000000000000000000000000815233600482015273ffffffffffffffffffffffffffffffffffffffff9091169063521d4de990602401602060405180830381865afa1580156108a0573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906108c49190614357565b6108fa576040517f99e120bc00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff8116600090815260d1602052604081205461092b9060016143a3565b73ffffffffffffffffffffffffffffffffffffffff8316600081815260d160205260409081902083905551919250907f979ef83e7e7a87cb48064e296dd7e997870d50f43acf8d7ad221313526c8ca0f906109899084815260200190565b60405180910390a25050565b6000336109a3818585612a35565b60019150505b92915050565b60cd546040517fe43581b800000000000000000000000000000000000000000000000000000000815233600482015273ffffffffffffffffffffffffffffffffffffffff9091169063e43581b890602401602060405180830381865afa158015610a1d573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610a419190614357565b610a77576040517fee3675d400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b610a9873ffffffffffffffffffffffffffffffffffffffff84168383612be0565b8173ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff167ffff3b3844276f57024e0b42afec1a37f75db36511e43819a4f2a63ab7862b64883604051610af791815260200190565b60405180910390a3505050565b73ffffffffffffffffffffffffffffffffffffffff8316600090815260ce60209081526040808320815160a081018352815481526001820154938101939093526002015467ffffffffffffffff81169183019190915260ff680100000000000000008204811615801560608501526901000000000000000000909204161515608083015280610b94575080608001515b15610bcb576040517fc1ab6dc100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015260009073ffffffffffffffffffffffffffffffffffffffff8716906370a0823190602401602060405180830381865afa158015610c38573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610c5c91906143b6565b8251909150610c6b86836143cf565b1115610c93578151811015610c8e578151610c879082906143a3565b9450610c93565b600094505b6000610ca1610e10426143e2565b73ffffffffffffffffffffffffffffffffffffffff8816600090815260d0602090815260408083208484528252909120549085015191925090610ce488836143cf565b1115610d0f5780846020015111610cfc576000610d0c565b808460200151610d0c91906143a3565b96505b610d1987826143cf565b73ffffffffffffffffffffffffffffffffffffffff8916600081815260d060209081526040808320878452909152902091909155610d599033308a612cb4565b33600090815260d16020526040812054889103610da657633b9aca00856040015167ffffffffffffffff1682610d8f919061441d565b610d9991906143e2565b610da390826143a3565b90505b610db08782612d12565b9450505050505b9392505050565b600033610dcc858285612e32565b610dd7858585612f03565b506001949350505050565b33600090815260cc602052604090205460ff16610e2b576040517ff8d2906c00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b610e3581836131b6565b5050565b60cd546040517fe43581b800000000000000000000000000000000000000000000000000000000815233600482015273ffffffffffffffffffffffffffffffffffffffff9091169063e43581b890602401602060405180830381865afa158015610ea7573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610ecb9190614357565b610f01576040517fee3675d400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015273ffffffffffffffffffffffffffffffffffffffff8216906370a0823190602401602060405180830381865afa158015610f6b573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610f8f91906143b6565b15610fc6576040517f2ef630ec00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff8116600090815260ce602052604081208181556001810182905560020180547fffffffffffffffffffffffffffffffffffffffffffff0000000000000000000016905560cf54905b61102e6001836143a3565b811015611139578273ffffffffffffffffffffffffffffffffffffffff1660cf828154811061105f5761105f614434565b60009182526020909120015473ffffffffffffffffffffffffffffffffffffffff16036111295760cf6110936001846143a3565b815481106110a3576110a3614434565b60009182526020909120015460cf805473ffffffffffffffffffffffffffffffffffffffff90921691839081106110dc576110dc614434565b9060005260206000200160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550611139565b61113281614463565b9050611023565b5060cf80548061114b5761114b61449b565b60008281526020812082017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff90810180547fffffffffffffffffffffffff000000000000000000000000000000000000000016905590910190915560405173ffffffffffffffffffffffffffffffffffffffff8416917f5c95b49c4d59d97a2f044167723f29c74b30f99702e3fd406c3830160aa9ccb891a25050565b60cd5473ffffffffffffffffffffffffffffffffffffffff16331480159061122657503373ffffffffffffffffffffffffffffffffffffffff821614155b1561125d576040517fddb5de5e00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff8116600081815260cc602052604080822080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00169055517f98c15241d6c02bc5ee0b780e11b3ea737a2defd9d04877edbe9f9497065bd02f9190a250565b33600090815260cc602052604090205460ff1661131a576040517ff8d2906c00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff16146113d05773ffffffffffffffffffffffffffffffffffffffff828116600090815260346020908152604080832093851683529290522054838110156113ba576040517f715ec26c00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6113ce83836113c987856143a3565b612a35565b505b61082d82846131b6565b60006113e46133a3565b905090565b60cd546040517f521d4de900000000000000000000000000000000000000000000000000000000815233600482015273ffffffffffffffffffffffffffffffffffffffff9091169063521d4de990602401602060405180830381865afa158015611457573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061147b9190614357565b6114b1576040517f99e120bc00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff8216600090815260ce602052604090206002015468010000000000000000900460ff1661151f576040517fc1ab6dc100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff8216600081815260ce602052604090819020839055517fe7b113fba37131b6396680a0c55790a697ec975e198ff8cfd89dac90a6379e61906109899084815260200190565b33600081815260346020908152604080832073ffffffffffffffffffffffffffffffffffffffff871684529091528120549091906109a390829086906113c99087906143cf565b60cd546040517f521d4de900000000000000000000000000000000000000000000000000000000815233600482015273ffffffffffffffffffffffffffffffffffffffff9091169063521d4de990602401602060405180830381865afa15801561162e573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906116529190614357565b611688576040517f99e120bc00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60d28190556040518181527fc3b69829afe2345596a02c8b587d41f796ba0094481d899e1b2e07b7532a1e219060200160405180910390a150565b33600090815260cc602052604090205460ff1661170c576040517ff8d2906c00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b610e358282612d12565b73ffffffffffffffffffffffffffffffffffffffff8116600090815260d06020526040812081611748610e10426143e2565b8152602001908152602001600020549050919050565b60cd546040517f521d4de900000000000000000000000000000000000000000000000000000000815233600482015273ffffffffffffffffffffffffffffffffffffffff9091169063521d4de990602401602060405180830381865afa1580156117cc573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906117f09190614357565b611826576040517f99e120bc00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff8216600090815260ce602052604090206002015468010000000000000000900460ff16611894576040517fc1ab6dc100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff8216600081815260ce602052604090819020600101839055517fe13ac9338b2ee623233f83c1b3ceab16490fa3e3737fac7f0970d0830a9f4871906109899084815260200190565b60cd546040517fe43581b800000000000000000000000000000000000000000000000000000000815233600482015273ffffffffffffffffffffffffffffffffffffffff9091169063e43581b890602401602060405180830381865afa15801561195f573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906119839190614357565b6119b9576040517fee3675d400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff8516600090815260ce602052604090206002015468010000000000000000900460ff1680611a10575073ffffffffffffffffffffffffffffffffffffffff8516155b15611a47576040517fc1ab6dc100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b633b9aca008267ffffffffffffffff161115611a8f576040517feca1d2c600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040805160a08101825260008082526020820181905291810182905260608101829052608081019190915284815260208082018581528315156080840190815267ffffffffffffffff808716604080870191825260016060880181815273ffffffffffffffffffffffffffffffffffffffff8e16600081815260ce9099528389208a5181559751888401559351600290970180549151965115156901000000000000000000027fffffffffffffffffffffffffffffffffffffffffffff00ffffffffffffffffff97151568010000000000000000027fffffffffffffffffffffffffffffffffffffffffffffff000000000000000000909316989096169790971717949094169290921790935560cf805492830181559093527facb8d954e2cfef495862221e91bd7523613cf8808827cb33edfe4904cc51bf290180547fffffffffffffffffffffffff0000000000000000000000000000000000000000168217905590517f53087ff85d80a7671594bd2e86b92af22e0b3c2c441c8033bba7399b7b5cbe2390611c49908890889088908890938452602084019290925267ffffffffffffffff1660408301521515606082015260800190565b60405180910390a2505050505050565b600060d381611c6a610e10426143e2565b815260200190815260200160002054905090565b73ffffffffffffffffffffffffffffffffffffffff81166000908152609960205260408120546109a9565b611cb333826131b6565b50565b60606037805461079f9061430a565b60cd5473ffffffffffffffffffffffffffffffffffffffff163314611d16576040517fb90cdbb100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff8116600081815260cc602052604080822080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00166001179055517f98c15241d6c02bc5ee0b780e11b3ea737a2defd9d04877edbe9f9497065bd02f9190a250565b60cd546040517f521d4de900000000000000000000000000000000000000000000000000000000815233600482015273ffffffffffffffffffffffffffffffffffffffff9091169063521d4de990602401602060405180830381865afa158015611dfb573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611e1f9190614357565b611e55576040517f99e120bc00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff8216600090815260ce602052604090206002015468010000000000000000900460ff16611ec3576040517fc1ab6dc100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b633b9aca008167ffffffffffffffff161115611f0b576040517feca1d2c600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff8216600081815260ce602090815260409182902060020180547fffffffffffffffffffffffffffffffffffffffffffffffff00000000000000001667ffffffffffffffff861690811790915591519182527f901f9de19b475adc8da4110434b8df940dce085afd05e2281c86807f3a899d299101610989565b33600081815260346020908152604080832073ffffffffffffffffffffffffffffffffffffffff8716845290915281205490919083811015612062576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602560248201527f45524332303a2064656372656173656420616c6c6f77616e63652062656c6f7760448201527f207a65726f00000000000000000000000000000000000000000000000000000060648201526084015b60405180910390fd5b610dd78286868403612a35565b6000336109a3818585612f03565b60cf818154811061208d57600080fd5b60009182526020909120015473ffffffffffffffffffffffffffffffffffffffff16905081565b606060cf80548060200260200160405190810160405280929190818152602001828054801561081857602002820191906000526020600020905b815473ffffffffffffffffffffffffffffffffffffffff1681526001909101906020018083116120ee575050505050905090565b73ffffffffffffffffffffffffffffffffffffffff8316600090815260ce60209081526040808320815160a081018352815481526001820154938101939093526002015467ffffffffffffffff81169183019190915260ff6801000000000000000082048116158015606085015269010000000000000000009092041615156080830152806121b2575080608001515b156121e9576040517fc1ab6dc100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60006121f7610e10426143e2565b600081815260d36020526040812054919250906122159087906143cf565b905060d254811115612253576040517f6d43d1ac00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600082815260d36020526040902081905561226e33876131b6565b33600090815260d160205260408120548791036122bb57633b9aca00846040015167ffffffffffffffff16826122a4919061441d565b6122ae91906143e2565b6122b890826143a3565b90505b6122dc73ffffffffffffffffffffffffffffffffffffffff89168783612be0565b979650505050505050565b83421115612351576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f45524332305065726d69743a206578706972656420646561646c696e650000006044820152606401612059565b60007f6e71edae12b1b97f4d1f60370fef10105fa2faae0126114a169c64845d6126c98888886123808c61341e565b60408051602081019690965273ffffffffffffffffffffffffffffffffffffffff94851690860152929091166060840152608083015260a082015260c0810186905260e00160405160208183030381529060405280519060200120905060006123e882613453565b905060006123f8828787876134bc565b90508973ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff161461248f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601e60248201527f45524332305065726d69743a20696e76616c6964207369676e617475726500006044820152606401612059565b61249a8a8a8a612a35565b50505050505050505050565b60cd546040517f521d4de900000000000000000000000000000000000000000000000000000000815233600482015273ffffffffffffffffffffffffffffffffffffffff9091169063521d4de990602401602060405180830381865afa158015612514573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906125389190614357565b61256e576040517f99e120bc00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff8116600090815260ce602052604090206002015468010000000000000000900460ff166125dc576040517fc1ab6dc100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff8116600081815260ce602090815260409182902060020180547fffffffffffffffffffffffffffffffffffffffffffff00ffffffffffffffffff811669010000000000000000009182900460ff16801592830291909117909255925192835292917ff7c93079dcbf699749d66345a351afab7d24219bb1d915c9f4fc4cf03f00d3979101610989565b60cd5473ffffffffffffffffffffffffffffffffffffffff1633146126cb576040517fb90cdbb100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60cd80547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83169081179091556040517f7dae230f18360d76a040c81f050aa14eb9d6dc7901b20fc5d855e2a20fe814d190600090a250565b73ffffffffffffffffffffffffffffffffffffffff163b151590565b600054610100900460ff16158080156127765750600054600160ff909116105b806127905750303b158015612790575060005460ff166001145b61281c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201527f647920696e697469616c697a65640000000000000000000000000000000000006064820152608401612059565b600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00166001179055801561287a57600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff166101001790555b3073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1663e9cbd8226040518163ffffffff1660e01b8152600401602060405180830381865afa1580156128dc573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061290091906144ca565b73ffffffffffffffffffffffffffffffffffffffff161461294d576040517f14bcf5c800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b612956846134e4565b61296084846135ba565b60cd80547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff84169081179091556040517f7dae230f18360d76a040c81f050aa14eb9d6dc7901b20fc5d855e2a20fe814d190600090a28015612a2f57600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15b50505050565b73ffffffffffffffffffffffffffffffffffffffff8316612ad7576040517f08c379a0000000000000000000000000000000000000000000000000000000008152602060048201526024808201527f45524332303a20617070726f76652066726f6d20746865207a65726f2061646460448201527f72657373000000000000000000000000000000000000000000000000000000006064820152608401612059565b73ffffffffffffffffffffffffffffffffffffffff8216612b7a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602260248201527f45524332303a20617070726f766520746f20746865207a65726f20616464726560448201527f73730000000000000000000000000000000000000000000000000000000000006064820152608401612059565b73ffffffffffffffffffffffffffffffffffffffff83811660008181526034602090815260408083209487168084529482529182902085905590518481527f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b9259101610af7565b60405173ffffffffffffffffffffffffffffffffffffffff831660248201526044810182905261082d9084907fa9059cbb00000000000000000000000000000000000000000000000000000000906064015b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff000000000000000000000000000000000000000000000000000000009093169290921790915261365b565b60405173ffffffffffffffffffffffffffffffffffffffff80851660248301528316604482015260648101829052612a2f9085907f23b872dd0000000000000000000000000000000000000000000000000000000090608401612c32565b73ffffffffffffffffffffffffffffffffffffffff8216612d8f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601f60248201527f45524332303a206d696e7420746f20746865207a65726f2061646472657373006044820152606401612059565b8060356000828254612da191906143cf565b909155505073ffffffffffffffffffffffffffffffffffffffff821660009081526033602052604081208054839290612ddb9084906143cf565b909155505060405181815273ffffffffffffffffffffffffffffffffffffffff8316906000907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef9060200160405180910390a35050565b73ffffffffffffffffffffffffffffffffffffffff8381166000908152603460209081526040808320938616835292905220547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8114612a2f5781811015612ef6576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f45524332303a20696e73756666696369656e7420616c6c6f77616e63650000006044820152606401612059565b612a2f8484848403612a35565b73ffffffffffffffffffffffffffffffffffffffff8316612fa6576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602560248201527f45524332303a207472616e736665722066726f6d20746865207a65726f20616460448201527f64726573730000000000000000000000000000000000000000000000000000006064820152608401612059565b73ffffffffffffffffffffffffffffffffffffffff8216613049576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602360248201527f45524332303a207472616e7366657220746f20746865207a65726f206164647260448201527f65737300000000000000000000000000000000000000000000000000000000006064820152608401612059565b73ffffffffffffffffffffffffffffffffffffffff8316600090815260336020526040902054818110156130ff576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f45524332303a207472616e7366657220616d6f756e742065786365656473206260448201527f616c616e636500000000000000000000000000000000000000000000000000006064820152608401612059565b73ffffffffffffffffffffffffffffffffffffffff8085166000908152603360205260408082208585039055918516815290812080548492906131439084906143cf565b925050819055508273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef846040516131a991815260200190565b60405180910390a3612a2f565b73ffffffffffffffffffffffffffffffffffffffff8216613259576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602160248201527f45524332303a206275726e2066726f6d20746865207a65726f2061646472657360448201527f73000000000000000000000000000000000000000000000000000000000000006064820152608401612059565b73ffffffffffffffffffffffffffffffffffffffff82166000908152603360205260409020548181101561330f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602260248201527f45524332303a206275726e20616d6f756e7420657863656564732062616c616e60448201527f63650000000000000000000000000000000000000000000000000000000000006064820152608401612059565b73ffffffffffffffffffffffffffffffffffffffff8316600090815260336020526040812083830390556035805484929061334b9084906143a3565b909155505060405182815260009073ffffffffffffffffffffffffffffffffffffffff8516907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef9060200160405180910390a3505050565b60006113e47f8b73c3c69bb8fe3d512ecc4cf759cc79239f7b179b0ffacaa9a75d522b39400f6133d260655490565b6066546040805160208101859052908101839052606081018290524660808201523060a082015260009060c0016040516020818303038152906040528051906020012090509392505050565b73ffffffffffffffffffffffffffffffffffffffff811660009081526099602052604090208054600181018255905b50919050565b60006109a96134606133a3565b836040517f19010000000000000000000000000000000000000000000000000000000000006020820152602281018390526042810182905260009060620160405160208183030381529060405280519060200120905092915050565b60008060006134cd87878787613767565b915091506134da8161387f565b5095945050505050565b600054610100900460ff1661357b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201527f6e697469616c697a696e670000000000000000000000000000000000000000006064820152608401612059565b611cb3816040518060400160405280600181526020017f3100000000000000000000000000000000000000000000000000000000000000815250613ad3565b600054610100900460ff16613651576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201527f6e697469616c697a696e670000000000000000000000000000000000000000006064820152608401612059565b610e358282613b84565b60006136bd826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c65648152508573ffffffffffffffffffffffffffffffffffffffff16613c349092919063ffffffff16565b80519091501561082d57808060200190518101906136db9190614357565b61082d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e60448201527f6f742073756363656564000000000000000000000000000000000000000000006064820152608401612059565b6000807f7fffffffffffffffffffffffffffffff5d576e7357a4501ddfe92f46681b20a083111561379e5750600090506003613876565b8460ff16601b141580156137b657508460ff16601c14155b156137c75750600090506004613876565b6040805160008082526020820180845289905260ff881692820192909252606081018690526080810185905260019060a0016020604051602081039080840390855afa15801561381b573d6000803e3d6000fd5b50506040517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0015191505073ffffffffffffffffffffffffffffffffffffffff811661386f57600060019250925050613876565b9150600090505b94509492505050565b6000816004811115613893576138936144e7565b0361389b5750565b60018160048111156138af576138af6144e7565b03613916576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601860248201527f45434453413a20696e76616c6964207369676e617475726500000000000000006044820152606401612059565b600281600481111561392a5761392a6144e7565b03613991576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601f60248201527f45434453413a20696e76616c6964207369676e6174757265206c656e677468006044820152606401612059565b60038160048111156139a5576139a56144e7565b03613a32576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602260248201527f45434453413a20696e76616c6964207369676e6174757265202773272076616c60448201527f75650000000000000000000000000000000000000000000000000000000000006064820152608401612059565b6004816004811115613a4657613a466144e7565b03611cb3576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602260248201527f45434453413a20696e76616c6964207369676e6174757265202776272076616c60448201527f75650000000000000000000000000000000000000000000000000000000000006064820152608401612059565b600054610100900460ff16613b6a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201527f6e697469616c697a696e670000000000000000000000000000000000000000006064820152608401612059565b815160209283012081519190920120606591909155606655565b600054610100900460ff16613c1b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201527f6e697469616c697a696e670000000000000000000000000000000000000000006064820152608401612059565b6036613c278382614564565b50603761082d8282614564565b6060613c438484600085613c4b565b949350505050565b606082471015613cdd576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f60448201527f722063616c6c00000000000000000000000000000000000000000000000000006064820152608401612059565b73ffffffffffffffffffffffffffffffffffffffff85163b613d5b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006044820152606401612059565b6000808673ffffffffffffffffffffffffffffffffffffffff168587604051613d84919061467e565b60006040518083038185875af1925050503d8060008114613dc1576040519150601f19603f3d011682016040523d82523d6000602084013e613dc6565b606091505b50915091506122dc82828660608315613de0575081610db7565b825115613df05782518084602001fd5b816040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016120599190613e48565b60005b83811015613e3f578181015183820152602001613e27565b50506000910152565b6020815260008251806020840152613e67816040850160208701613e24565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169190910160400192915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b600082601f830112613ed957600080fd5b813567ffffffffffffffff80821115613ef457613ef4613e99565b604051601f83017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0908116603f01168101908282118183101715613f3a57613f3a613e99565b81604052838152866020858801011115613f5357600080fd5b836020870160208301376000602085830101528094505050505092915050565b73ffffffffffffffffffffffffffffffffffffffff81168114611cb357600080fd5b600080600060608486031215613faa57600080fd5b833567ffffffffffffffff80821115613fc257600080fd5b613fce87838801613ec8565b94506020860135915080821115613fe457600080fd5b50613ff186828701613ec8565b925050604084013561400281613f73565b809150509250925092565b60006020828403121561401f57600080fd5b8135610db781613f73565b6000806040838503121561403d57600080fd5b823561404881613f73565b946020939093013593505050565b60008060006060848603121561406b57600080fd5b833561407681613f73565b9250602084013561408681613f73565b929592945050506040919091013590565b6000806000606084860312156140ac57600080fd5b83356140b781613f73565b925060208401359150604084013561400281613f73565b600080604083850312156140e157600080fd5b8235915060208301356140f381613f73565b809150509250929050565b60008060006060848603121561411357600080fd5b83359250602084013561412581613f73565b9150604084013561400281613f73565b60006020828403121561414757600080fd5b5035919050565b803567ffffffffffffffff8116811461416657600080fd5b919050565b8015158114611cb357600080fd5b600080600080600060a0868803121561419157600080fd5b853561419c81613f73565b945060208601359350604086013592506141b86060870161414e565b915060808601356141c88161416b565b809150509295509295909350565b600080604083850312156141e957600080fd5b82356141f481613f73565b91506142026020840161414e565b90509250929050565b6020808252825182820181905260009190848201906040850190845b8181101561425957835173ffffffffffffffffffffffffffffffffffffffff1683529284019291840191600101614227565b50909695505050505050565b600080600080600080600060e0888a03121561428057600080fd5b873561428b81613f73565b9650602088013561429b81613f73565b95506040880135945060608801359350608088013560ff811681146142bf57600080fd5b9699959850939692959460a0840135945060c09093013592915050565b600080604083850312156142ef57600080fd5b82356142fa81613f73565b915060208301356140f381613f73565b600181811c9082168061431e57607f821691505b60208210810361344d577f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b60006020828403121561436957600080fd5b8151610db78161416b565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b818103818111156109a9576109a9614374565b6000602082840312156143c857600080fd5b5051919050565b808201808211156109a9576109a9614374565b600082614418577f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b500490565b80820281158282048414176109a9576109a9614374565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff820361449457614494614374565b5060010190565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603160045260246000fd5b6000602082840312156144dc57600080fd5b8151610db781613f73565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b601f82111561082d57600081815260208120601f850160051c8101602086101561453d5750805b601f850160051c820191505b8181101561455c57828155600101614549565b505050505050565b815167ffffffffffffffff81111561457e5761457e613e99565b6145928161458c845461430a565b84614516565b602080601f8311600181146145e557600084156145af5750858301515b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600386901b1c1916600185901b17855561455c565b6000858152602081207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08616915b8281101561463257888601518255948401946001909101908401614613565b508582101561466e57878501517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600388901b60f8161c191681555b5050505050600190811b01905550565b60008251614690818460208701613e24565b919091019291505056fea2646970667358221220f2eb02bac1667a72be85ab617a5b5aa3d8f7a9b09b4d1fde9756b7a5636daf2164736f6c63430008110033", + "deployedBytecode": "0x608060405234801561001057600080fd5b50600436106102ff5760003560e01c806361d027b31161019c5780639f48118f116100ee578063ced67f0c11610097578063dd62ed3e11610071578063dd62ed3e14610724578063e3e286551461076a578063f0f442601461077d57600080fd5b8063ced67f0c1461066b578063d44ad63f146106fe578063d505accf1461071157600080fd5b8063aa271e1a116100c8578063aa271e1a14610620578063ba330bd714610643578063cd4839ca1461065657600080fd5b80639f48118f146105ef578063a457c2d7146105fa578063a9059cbb1461060d57600080fd5b80637ecebe001161015057806395d89b411161012a57806395d89b41146105c1578063983b2d56146105c95780639e4e0dae146105dc57600080fd5b80637ecebe00146105705780638933fb791461058357806390218cff146105ae57600080fd5b80637334d020116101815780637334d020146105425780637d4c9c2d146105555780637d74e25f1461056857600080fd5b806361d027b3146104c757806370a082311461050c57600080fd5b80633092afd511610255578063395093511161020957806340c10f19116101e357806340c10f19146104815780634dc32fcc146104945780635bfbec96146104a757600080fd5b8063395093511461043b5780633a55f89d1461044e5780633f4218e01461046157600080fd5b8063350ebe041161023a578063350ebe041461040d5780633644e5151461042057806336db43b51461042857600080fd5b80633092afd5146103eb578063313ce567146103fe57600080fd5b8063151dd755116102b757806323b872dd1161029157806323b872dd146103b25780632b471d8e146103c55780632e403e14146103d857600080fd5b8063151dd7551461038057806318160ddd146103a15780632342fb0e146103a957600080fd5b80630919a951116102e85780630919a95114610337578063095ea7b31461034a5780631171bda91461036d57600080fd5b806306fdde0314610304578063077f224a14610322575b600080fd5b61030c610790565b6040516103199190613e48565b60405180910390f35b610335610330366004613f95565b610822565b005b61033561034536600461400d565b610832565b61035d61035836600461402a565b610995565b6040519015158152602001610319565b61033561037b366004614056565b6109af565b61039361038e366004614097565b610b04565b604051908152602001610319565b603554610393565b61039360d25481565b61035d6103c0366004614056565b610dbe565b6103356103d33660046140ce565b610de2565b6103356103e636600461400d565b610e39565b6103356103f936600461400d565b6111e8565b60405160128152602001610319565b61033561041b3660046140fe565b6112d1565b6103936113da565b61033561043636600461402a565b6113e9565b61035d61044936600461402a565b611579565b61033561045c366004614135565b6115c0565b61039361046f36600461400d565b60d16020526000908152604090205481565b61033561048f36600461402a565b6116c3565b6103936104a236600461400d565b611716565b6103936104b5366004614135565b60d36020526000908152604090205481565b60cd546104e79073ffffffffffffffffffffffffffffffffffffffff1681565b60405173ffffffffffffffffffffffffffffffffffffffff9091168152602001610319565b61039361051a36600461400d565b73ffffffffffffffffffffffffffffffffffffffff1660009081526033602052604090205490565b61033561055036600461402a565b61175e565b610335610563366004614179565b6118f1565b610393611c59565b61039361057e36600461400d565b611c7e565b61039361059136600461402a565b60d060209081526000928352604080842090915290825290205481565b6103356105bc366004614135565b611ca9565b61030c611cb6565b6103356105d736600461400d565b611cc5565b6103356105ea3660046141d6565b611d8d565b610393633b9aca0081565b61035d61060836600461402a565b611f99565b61035d61061b36600461402a565b61206f565b61035d61062e36600461400d565b60cc6020526000908152604090205460ff1681565b6104e7610651366004614135565b61207d565b61065e6120b4565b604051610319919061420b565b6106c561067936600461400d565b60ce6020526000908152604090208054600182015460029092015490919067ffffffffffffffff81169060ff680100000000000000008204811691690100000000000000000090041685565b60408051958652602086019490945267ffffffffffffffff9092169284019290925290151560608301521515608082015260a001610319565b61039361070c366004614097565b612122565b61033561071f366004614265565b6122e7565b6103936107323660046142dc565b73ffffffffffffffffffffffffffffffffffffffff918216600090815260346020908152604080832093909416825291909152205490565b61033561077836600461400d565b6124a6565b61033561078b36600461400d565b61267a565b60606036805461079f9061430a565b80601f01602080910402602001604051908101604052809291908181526020018280546107cb9061430a565b80156108185780601f106107ed57610100808354040283529160200191610818565b820191906000526020600020905b8154815290600101906020018083116107fb57829003601f168201915b5050505050905090565b61082d838383612756565b505050565b60cd546040517f521d4de900000000000000000000000000000000000000000000000000000000815233600482015273ffffffffffffffffffffffffffffffffffffffff9091169063521d4de990602401602060405180830381865afa1580156108a0573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906108c49190614357565b6108fa576040517f99e120bc00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff8116600090815260d1602052604081205461092b9060016143a3565b73ffffffffffffffffffffffffffffffffffffffff8316600081815260d160205260409081902083905551919250907f979ef83e7e7a87cb48064e296dd7e997870d50f43acf8d7ad221313526c8ca0f906109899084815260200190565b60405180910390a25050565b6000336109a3818585612a35565b60019150505b92915050565b60cd546040517fe43581b800000000000000000000000000000000000000000000000000000000815233600482015273ffffffffffffffffffffffffffffffffffffffff9091169063e43581b890602401602060405180830381865afa158015610a1d573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610a419190614357565b610a77576040517fee3675d400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b610a9873ffffffffffffffffffffffffffffffffffffffff84168383612be0565b8173ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff167ffff3b3844276f57024e0b42afec1a37f75db36511e43819a4f2a63ab7862b64883604051610af791815260200190565b60405180910390a3505050565b73ffffffffffffffffffffffffffffffffffffffff8316600090815260ce60209081526040808320815160a081018352815481526001820154938101939093526002015467ffffffffffffffff81169183019190915260ff680100000000000000008204811615801560608501526901000000000000000000909204161515608083015280610b94575080608001515b15610bcb576040517fc1ab6dc100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015260009073ffffffffffffffffffffffffffffffffffffffff8716906370a0823190602401602060405180830381865afa158015610c38573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610c5c91906143b6565b8251909150610c6b86836143cf565b1115610c93578151811015610c8e578151610c879082906143a3565b9450610c93565b600094505b6000610ca1610e10426143e2565b73ffffffffffffffffffffffffffffffffffffffff8816600090815260d0602090815260408083208484528252909120549085015191925090610ce488836143cf565b1115610d0f5780846020015111610cfc576000610d0c565b808460200151610d0c91906143a3565b96505b610d1987826143cf565b73ffffffffffffffffffffffffffffffffffffffff8916600081815260d060209081526040808320878452909152902091909155610d599033308a612cb4565b33600090815260d16020526040812054889103610da657633b9aca00856040015167ffffffffffffffff1682610d8f919061441d565b610d9991906143e2565b610da390826143a3565b90505b610db08782612d12565b9450505050505b9392505050565b600033610dcc858285612e32565b610dd7858585612f03565b506001949350505050565b33600090815260cc602052604090205460ff16610e2b576040517ff8d2906c00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b610e3581836131b6565b5050565b60cd546040517fe43581b800000000000000000000000000000000000000000000000000000000815233600482015273ffffffffffffffffffffffffffffffffffffffff9091169063e43581b890602401602060405180830381865afa158015610ea7573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610ecb9190614357565b610f01576040517fee3675d400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015273ffffffffffffffffffffffffffffffffffffffff8216906370a0823190602401602060405180830381865afa158015610f6b573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610f8f91906143b6565b15610fc6576040517f2ef630ec00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff8116600090815260ce602052604081208181556001810182905560020180547fffffffffffffffffffffffffffffffffffffffffffff0000000000000000000016905560cf54905b61102e6001836143a3565b811015611139578273ffffffffffffffffffffffffffffffffffffffff1660cf828154811061105f5761105f614434565b60009182526020909120015473ffffffffffffffffffffffffffffffffffffffff16036111295760cf6110936001846143a3565b815481106110a3576110a3614434565b60009182526020909120015460cf805473ffffffffffffffffffffffffffffffffffffffff90921691839081106110dc576110dc614434565b9060005260206000200160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550611139565b61113281614463565b9050611023565b5060cf80548061114b5761114b61449b565b60008281526020812082017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff90810180547fffffffffffffffffffffffff000000000000000000000000000000000000000016905590910190915560405173ffffffffffffffffffffffffffffffffffffffff8416917f5c95b49c4d59d97a2f044167723f29c74b30f99702e3fd406c3830160aa9ccb891a25050565b60cd5473ffffffffffffffffffffffffffffffffffffffff16331480159061122657503373ffffffffffffffffffffffffffffffffffffffff821614155b1561125d576040517fddb5de5e00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff8116600081815260cc602052604080822080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00169055517f98c15241d6c02bc5ee0b780e11b3ea737a2defd9d04877edbe9f9497065bd02f9190a250565b33600090815260cc602052604090205460ff1661131a576040517ff8d2906c00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff16146113d05773ffffffffffffffffffffffffffffffffffffffff828116600090815260346020908152604080832093851683529290522054838110156113ba576040517f715ec26c00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6113ce83836113c987856143a3565b612a35565b505b61082d82846131b6565b60006113e46133a3565b905090565b60cd546040517f521d4de900000000000000000000000000000000000000000000000000000000815233600482015273ffffffffffffffffffffffffffffffffffffffff9091169063521d4de990602401602060405180830381865afa158015611457573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061147b9190614357565b6114b1576040517f99e120bc00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff8216600090815260ce602052604090206002015468010000000000000000900460ff1661151f576040517fc1ab6dc100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff8216600081815260ce602052604090819020839055517fe7b113fba37131b6396680a0c55790a697ec975e198ff8cfd89dac90a6379e61906109899084815260200190565b33600081815260346020908152604080832073ffffffffffffffffffffffffffffffffffffffff871684529091528120549091906109a390829086906113c99087906143cf565b60cd546040517f521d4de900000000000000000000000000000000000000000000000000000000815233600482015273ffffffffffffffffffffffffffffffffffffffff9091169063521d4de990602401602060405180830381865afa15801561162e573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906116529190614357565b611688576040517f99e120bc00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60d28190556040518181527fc3b69829afe2345596a02c8b587d41f796ba0094481d899e1b2e07b7532a1e219060200160405180910390a150565b33600090815260cc602052604090205460ff1661170c576040517ff8d2906c00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b610e358282612d12565b73ffffffffffffffffffffffffffffffffffffffff8116600090815260d06020526040812081611748610e10426143e2565b8152602001908152602001600020549050919050565b60cd546040517f521d4de900000000000000000000000000000000000000000000000000000000815233600482015273ffffffffffffffffffffffffffffffffffffffff9091169063521d4de990602401602060405180830381865afa1580156117cc573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906117f09190614357565b611826576040517f99e120bc00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff8216600090815260ce602052604090206002015468010000000000000000900460ff16611894576040517fc1ab6dc100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff8216600081815260ce602052604090819020600101839055517fe13ac9338b2ee623233f83c1b3ceab16490fa3e3737fac7f0970d0830a9f4871906109899084815260200190565b60cd546040517fe43581b800000000000000000000000000000000000000000000000000000000815233600482015273ffffffffffffffffffffffffffffffffffffffff9091169063e43581b890602401602060405180830381865afa15801561195f573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906119839190614357565b6119b9576040517fee3675d400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff8516600090815260ce602052604090206002015468010000000000000000900460ff1680611a10575073ffffffffffffffffffffffffffffffffffffffff8516155b15611a47576040517fc1ab6dc100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b633b9aca008267ffffffffffffffff161115611a8f576040517feca1d2c600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040805160a08101825260008082526020820181905291810182905260608101829052608081019190915284815260208082018581528315156080840190815267ffffffffffffffff808716604080870191825260016060880181815273ffffffffffffffffffffffffffffffffffffffff8e16600081815260ce9099528389208a5181559751888401559351600290970180549151965115156901000000000000000000027fffffffffffffffffffffffffffffffffffffffffffff00ffffffffffffffffff97151568010000000000000000027fffffffffffffffffffffffffffffffffffffffffffffff000000000000000000909316989096169790971717949094169290921790935560cf805492830181559093527facb8d954e2cfef495862221e91bd7523613cf8808827cb33edfe4904cc51bf290180547fffffffffffffffffffffffff0000000000000000000000000000000000000000168217905590517f53087ff85d80a7671594bd2e86b92af22e0b3c2c441c8033bba7399b7b5cbe2390611c49908890889088908890938452602084019290925267ffffffffffffffff1660408301521515606082015260800190565b60405180910390a2505050505050565b600060d381611c6a610e10426143e2565b815260200190815260200160002054905090565b73ffffffffffffffffffffffffffffffffffffffff81166000908152609960205260408120546109a9565b611cb333826131b6565b50565b60606037805461079f9061430a565b60cd5473ffffffffffffffffffffffffffffffffffffffff163314611d16576040517fb90cdbb100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff8116600081815260cc602052604080822080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00166001179055517f98c15241d6c02bc5ee0b780e11b3ea737a2defd9d04877edbe9f9497065bd02f9190a250565b60cd546040517f521d4de900000000000000000000000000000000000000000000000000000000815233600482015273ffffffffffffffffffffffffffffffffffffffff9091169063521d4de990602401602060405180830381865afa158015611dfb573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611e1f9190614357565b611e55576040517f99e120bc00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff8216600090815260ce602052604090206002015468010000000000000000900460ff16611ec3576040517fc1ab6dc100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b633b9aca008167ffffffffffffffff161115611f0b576040517feca1d2c600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff8216600081815260ce602090815260409182902060020180547fffffffffffffffffffffffffffffffffffffffffffffffff00000000000000001667ffffffffffffffff861690811790915591519182527f901f9de19b475adc8da4110434b8df940dce085afd05e2281c86807f3a899d299101610989565b33600081815260346020908152604080832073ffffffffffffffffffffffffffffffffffffffff8716845290915281205490919083811015612062576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602560248201527f45524332303a2064656372656173656420616c6c6f77616e63652062656c6f7760448201527f207a65726f00000000000000000000000000000000000000000000000000000060648201526084015b60405180910390fd5b610dd78286868403612a35565b6000336109a3818585612f03565b60cf818154811061208d57600080fd5b60009182526020909120015473ffffffffffffffffffffffffffffffffffffffff16905081565b606060cf80548060200260200160405190810160405280929190818152602001828054801561081857602002820191906000526020600020905b815473ffffffffffffffffffffffffffffffffffffffff1681526001909101906020018083116120ee575050505050905090565b73ffffffffffffffffffffffffffffffffffffffff8316600090815260ce60209081526040808320815160a081018352815481526001820154938101939093526002015467ffffffffffffffff81169183019190915260ff6801000000000000000082048116158015606085015269010000000000000000009092041615156080830152806121b2575080608001515b156121e9576040517fc1ab6dc100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60006121f7610e10426143e2565b600081815260d36020526040812054919250906122159087906143cf565b905060d254811115612253576040517f6d43d1ac00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600082815260d36020526040902081905561226e33876131b6565b33600090815260d160205260408120548791036122bb57633b9aca00846040015167ffffffffffffffff16826122a4919061441d565b6122ae91906143e2565b6122b890826143a3565b90505b6122dc73ffffffffffffffffffffffffffffffffffffffff89168783612be0565b979650505050505050565b83421115612351576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f45524332305065726d69743a206578706972656420646561646c696e650000006044820152606401612059565b60007f6e71edae12b1b97f4d1f60370fef10105fa2faae0126114a169c64845d6126c98888886123808c61341e565b60408051602081019690965273ffffffffffffffffffffffffffffffffffffffff94851690860152929091166060840152608083015260a082015260c0810186905260e00160405160208183030381529060405280519060200120905060006123e882613453565b905060006123f8828787876134bc565b90508973ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff161461248f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601e60248201527f45524332305065726d69743a20696e76616c6964207369676e617475726500006044820152606401612059565b61249a8a8a8a612a35565b50505050505050505050565b60cd546040517f521d4de900000000000000000000000000000000000000000000000000000000815233600482015273ffffffffffffffffffffffffffffffffffffffff9091169063521d4de990602401602060405180830381865afa158015612514573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906125389190614357565b61256e576040517f99e120bc00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff8116600090815260ce602052604090206002015468010000000000000000900460ff166125dc576040517fc1ab6dc100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff8116600081815260ce602090815260409182902060020180547fffffffffffffffffffffffffffffffffffffffffffff00ffffffffffffffffff811669010000000000000000009182900460ff16801592830291909117909255925192835292917ff7c93079dcbf699749d66345a351afab7d24219bb1d915c9f4fc4cf03f00d3979101610989565b60cd5473ffffffffffffffffffffffffffffffffffffffff1633146126cb576040517fb90cdbb100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60cd80547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83169081179091556040517f7dae230f18360d76a040c81f050aa14eb9d6dc7901b20fc5d855e2a20fe814d190600090a250565b73ffffffffffffffffffffffffffffffffffffffff163b151590565b600054610100900460ff16158080156127765750600054600160ff909116105b806127905750303b158015612790575060005460ff166001145b61281c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201527f647920696e697469616c697a65640000000000000000000000000000000000006064820152608401612059565b600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00166001179055801561287a57600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff166101001790555b3073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1663e9cbd8226040518163ffffffff1660e01b8152600401602060405180830381865afa1580156128dc573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061290091906144ca565b73ffffffffffffffffffffffffffffffffffffffff161461294d576040517f14bcf5c800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b612956846134e4565b61296084846135ba565b60cd80547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff84169081179091556040517f7dae230f18360d76a040c81f050aa14eb9d6dc7901b20fc5d855e2a20fe814d190600090a28015612a2f57600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15b50505050565b73ffffffffffffffffffffffffffffffffffffffff8316612ad7576040517f08c379a0000000000000000000000000000000000000000000000000000000008152602060048201526024808201527f45524332303a20617070726f76652066726f6d20746865207a65726f2061646460448201527f72657373000000000000000000000000000000000000000000000000000000006064820152608401612059565b73ffffffffffffffffffffffffffffffffffffffff8216612b7a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602260248201527f45524332303a20617070726f766520746f20746865207a65726f20616464726560448201527f73730000000000000000000000000000000000000000000000000000000000006064820152608401612059565b73ffffffffffffffffffffffffffffffffffffffff83811660008181526034602090815260408083209487168084529482529182902085905590518481527f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b9259101610af7565b60405173ffffffffffffffffffffffffffffffffffffffff831660248201526044810182905261082d9084907fa9059cbb00000000000000000000000000000000000000000000000000000000906064015b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff000000000000000000000000000000000000000000000000000000009093169290921790915261365b565b60405173ffffffffffffffffffffffffffffffffffffffff80851660248301528316604482015260648101829052612a2f9085907f23b872dd0000000000000000000000000000000000000000000000000000000090608401612c32565b73ffffffffffffffffffffffffffffffffffffffff8216612d8f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601f60248201527f45524332303a206d696e7420746f20746865207a65726f2061646472657373006044820152606401612059565b8060356000828254612da191906143cf565b909155505073ffffffffffffffffffffffffffffffffffffffff821660009081526033602052604081208054839290612ddb9084906143cf565b909155505060405181815273ffffffffffffffffffffffffffffffffffffffff8316906000907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef9060200160405180910390a35050565b73ffffffffffffffffffffffffffffffffffffffff8381166000908152603460209081526040808320938616835292905220547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8114612a2f5781811015612ef6576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f45524332303a20696e73756666696369656e7420616c6c6f77616e63650000006044820152606401612059565b612a2f8484848403612a35565b73ffffffffffffffffffffffffffffffffffffffff8316612fa6576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602560248201527f45524332303a207472616e736665722066726f6d20746865207a65726f20616460448201527f64726573730000000000000000000000000000000000000000000000000000006064820152608401612059565b73ffffffffffffffffffffffffffffffffffffffff8216613049576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602360248201527f45524332303a207472616e7366657220746f20746865207a65726f206164647260448201527f65737300000000000000000000000000000000000000000000000000000000006064820152608401612059565b73ffffffffffffffffffffffffffffffffffffffff8316600090815260336020526040902054818110156130ff576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f45524332303a207472616e7366657220616d6f756e742065786365656473206260448201527f616c616e636500000000000000000000000000000000000000000000000000006064820152608401612059565b73ffffffffffffffffffffffffffffffffffffffff8085166000908152603360205260408082208585039055918516815290812080548492906131439084906143cf565b925050819055508273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef846040516131a991815260200190565b60405180910390a3612a2f565b73ffffffffffffffffffffffffffffffffffffffff8216613259576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602160248201527f45524332303a206275726e2066726f6d20746865207a65726f2061646472657360448201527f73000000000000000000000000000000000000000000000000000000000000006064820152608401612059565b73ffffffffffffffffffffffffffffffffffffffff82166000908152603360205260409020548181101561330f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602260248201527f45524332303a206275726e20616d6f756e7420657863656564732062616c616e60448201527f63650000000000000000000000000000000000000000000000000000000000006064820152608401612059565b73ffffffffffffffffffffffffffffffffffffffff8316600090815260336020526040812083830390556035805484929061334b9084906143a3565b909155505060405182815260009073ffffffffffffffffffffffffffffffffffffffff8516907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef9060200160405180910390a3505050565b60006113e47f8b73c3c69bb8fe3d512ecc4cf759cc79239f7b179b0ffacaa9a75d522b39400f6133d260655490565b6066546040805160208101859052908101839052606081018290524660808201523060a082015260009060c0016040516020818303038152906040528051906020012090509392505050565b73ffffffffffffffffffffffffffffffffffffffff811660009081526099602052604090208054600181018255905b50919050565b60006109a96134606133a3565b836040517f19010000000000000000000000000000000000000000000000000000000000006020820152602281018390526042810182905260009060620160405160208183030381529060405280519060200120905092915050565b60008060006134cd87878787613767565b915091506134da8161387f565b5095945050505050565b600054610100900460ff1661357b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201527f6e697469616c697a696e670000000000000000000000000000000000000000006064820152608401612059565b611cb3816040518060400160405280600181526020017f3100000000000000000000000000000000000000000000000000000000000000815250613ad3565b600054610100900460ff16613651576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201527f6e697469616c697a696e670000000000000000000000000000000000000000006064820152608401612059565b610e358282613b84565b60006136bd826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c65648152508573ffffffffffffffffffffffffffffffffffffffff16613c349092919063ffffffff16565b80519091501561082d57808060200190518101906136db9190614357565b61082d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e60448201527f6f742073756363656564000000000000000000000000000000000000000000006064820152608401612059565b6000807f7fffffffffffffffffffffffffffffff5d576e7357a4501ddfe92f46681b20a083111561379e5750600090506003613876565b8460ff16601b141580156137b657508460ff16601c14155b156137c75750600090506004613876565b6040805160008082526020820180845289905260ff881692820192909252606081018690526080810185905260019060a0016020604051602081039080840390855afa15801561381b573d6000803e3d6000fd5b50506040517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0015191505073ffffffffffffffffffffffffffffffffffffffff811661386f57600060019250925050613876565b9150600090505b94509492505050565b6000816004811115613893576138936144e7565b0361389b5750565b60018160048111156138af576138af6144e7565b03613916576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601860248201527f45434453413a20696e76616c6964207369676e617475726500000000000000006044820152606401612059565b600281600481111561392a5761392a6144e7565b03613991576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601f60248201527f45434453413a20696e76616c6964207369676e6174757265206c656e677468006044820152606401612059565b60038160048111156139a5576139a56144e7565b03613a32576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602260248201527f45434453413a20696e76616c6964207369676e6174757265202773272076616c60448201527f75650000000000000000000000000000000000000000000000000000000000006064820152608401612059565b6004816004811115613a4657613a466144e7565b03611cb3576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602260248201527f45434453413a20696e76616c6964207369676e6174757265202776272076616c60448201527f75650000000000000000000000000000000000000000000000000000000000006064820152608401612059565b600054610100900460ff16613b6a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201527f6e697469616c697a696e670000000000000000000000000000000000000000006064820152608401612059565b815160209283012081519190920120606591909155606655565b600054610100900460ff16613c1b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201527f6e697469616c697a696e670000000000000000000000000000000000000000006064820152608401612059565b6036613c278382614564565b50603761082d8282614564565b6060613c438484600085613c4b565b949350505050565b606082471015613cdd576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f60448201527f722063616c6c00000000000000000000000000000000000000000000000000006064820152608401612059565b73ffffffffffffffffffffffffffffffffffffffff85163b613d5b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006044820152606401612059565b6000808673ffffffffffffffffffffffffffffffffffffffff168587604051613d84919061467e565b60006040518083038185875af1925050503d8060008114613dc1576040519150601f19603f3d011682016040523d82523d6000602084013e613dc6565b606091505b50915091506122dc82828660608315613de0575081610db7565b825115613df05782518084602001fd5b816040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016120599190613e48565b60005b83811015613e3f578181015183820152602001613e27565b50506000910152565b6020815260008251806020840152613e67816040850160208701613e24565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169190910160400192915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b600082601f830112613ed957600080fd5b813567ffffffffffffffff80821115613ef457613ef4613e99565b604051601f83017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0908116603f01168101908282118183101715613f3a57613f3a613e99565b81604052838152866020858801011115613f5357600080fd5b836020870160208301376000602085830101528094505050505092915050565b73ffffffffffffffffffffffffffffffffffffffff81168114611cb357600080fd5b600080600060608486031215613faa57600080fd5b833567ffffffffffffffff80821115613fc257600080fd5b613fce87838801613ec8565b94506020860135915080821115613fe457600080fd5b50613ff186828701613ec8565b925050604084013561400281613f73565b809150509250925092565b60006020828403121561401f57600080fd5b8135610db781613f73565b6000806040838503121561403d57600080fd5b823561404881613f73565b946020939093013593505050565b60008060006060848603121561406b57600080fd5b833561407681613f73565b9250602084013561408681613f73565b929592945050506040919091013590565b6000806000606084860312156140ac57600080fd5b83356140b781613f73565b925060208401359150604084013561400281613f73565b600080604083850312156140e157600080fd5b8235915060208301356140f381613f73565b809150509250929050565b60008060006060848603121561411357600080fd5b83359250602084013561412581613f73565b9150604084013561400281613f73565b60006020828403121561414757600080fd5b5035919050565b803567ffffffffffffffff8116811461416657600080fd5b919050565b8015158114611cb357600080fd5b600080600080600060a0868803121561419157600080fd5b853561419c81613f73565b945060208601359350604086013592506141b86060870161414e565b915060808601356141c88161416b565b809150509295509295909350565b600080604083850312156141e957600080fd5b82356141f481613f73565b91506142026020840161414e565b90509250929050565b6020808252825182820181905260009190848201906040850190845b8181101561425957835173ffffffffffffffffffffffffffffffffffffffff1683529284019291840191600101614227565b50909695505050505050565b600080600080600080600060e0888a03121561428057600080fd5b873561428b81613f73565b9650602088013561429b81613f73565b95506040880135945060608801359350608088013560ff811681146142bf57600080fd5b9699959850939692959460a0840135945060c09093013592915050565b600080604083850312156142ef57600080fd5b82356142fa81613f73565b915060208301356140f381613f73565b600181811c9082168061431e57607f821691505b60208210810361344d577f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b60006020828403121561436957600080fd5b8151610db78161416b565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b818103818111156109a9576109a9614374565b6000602082840312156143c857600080fd5b5051919050565b808201808211156109a9576109a9614374565b600082614418577f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b500490565b80820281158282048414176109a9576109a9614374565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff820361449457614494614374565b5060010190565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603160045260246000fd5b6000602082840312156144dc57600080fd5b8151610db781613f73565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b601f82111561082d57600081815260208120601f850160051c8101602086101561453d5750805b601f850160051c820191505b8181101561455c57828155600101614549565b505050505050565b815167ffffffffffffffff81111561457e5761457e613e99565b6145928161458c845461430a565b84614516565b602080601f8311600181146145e557600084156145af5750858301515b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600386901b1c1916600185901b17855561455c565b6000858152602081207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08616915b8281101561463257888601518255948401946001909101908401614613565b508582101561466e57878501517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600388901b60f8161c191681555b5050505050600190811b01905550565b60008251614690818460208701613e24565b919091019291505056fea2646970667358221220f2eb02bac1667a72be85ab617a5b5aa3d8f7a9b09b4d1fde9756b7a5636daf2164736f6c63430008110033", + "devdoc": { + "author": "Angle Labs, Inc.", + "details": "This contract supports bridge tokens having a minting right on the stablecoin (also referred to as the canonical or the native token)", + "kind": "dev", + "methods": { + "DOMAIN_SEPARATOR()": { + "details": "See {IERC20Permit-DOMAIN_SEPARATOR}." + }, + "addBridgeToken(address,uint256,uint256,uint64,bool)": { + "params": { + "bridgeToken": "Bridge token to add: it should be a version of the stablecoin from another bridge", + "fee": "Fee taken upon swapping for or against this token", + "hourlyLimit": "Limit on the hourly volume for this bridge", + "limit": "Limit on the balance of bridge token this contract could hold", + "paused": "Whether swapping for this token should be paused or not" + } + }, + "addMinter(address)": { + "details": "Zero address checks are performed directly in the `Treasury` contract", + "params": { + "minter": "Minter address to add" + } + }, + "allBridgeTokens()": { + "details": "Helpful for UIs" + }, + "allowance(address,address)": { + "details": "See {IERC20-allowance}." + }, + "approve(address,uint256)": { + "details": "See {IERC20-approve}. NOTE: If `amount` is the maximum `uint256`, the allowance is not updated on `transferFrom`. This is semantically equivalent to an infinite approval. Requirements: - `spender` cannot be the zero address." + }, + "balanceOf(address)": { + "details": "See {IERC20-balanceOf}." + }, + "burnFrom(uint256,address,address)": { + "details": "This method is to be called by a contract with the minter right after being requested to do so by a `sender` address willing to burn tokens from another `burner` addressThe method checks the allowance between the `sender` and the `burner`", + "params": { + "amount": "Amount of tokens to burn", + "burner": "Address to burn from", + "sender": "Address which requested the burn from `burner`" + } + }, + "burnSelf(uint256,address)": { + "details": "This method is to be called by a contract with a minter right on the AgToken after being requested to do so by an address willing to burn tokens from its address", + "params": { + "amount": "Amount of tokens to burn", + "burner": "Address to burn from" + } + }, + "burnStablecoin(uint256)": { + "details": "This function can typically be called if there is a settlement mechanism to burn stablecoins", + "params": { + "amount": "Amount of stablecoins to burn" + } + }, + "currentTotalUsage()": { + "details": "Helpful for UIs" + }, + "currentUsage(address)": { + "details": "Helpful for UIs", + "params": { + "bridgeToken": "Bridge used to mint" + } + }, + "decimals()": { + "details": "Returns the number of decimals used to get its user representation. For example, if `decimals` equals `2`, a balance of `505` tokens should be displayed to a user as `5.05` (`505 / 10 ** 2`). Tokens usually opt for a value of 18, imitating the relationship between Ether and Wei. This is the value {ERC20} uses, unless this function is overridden; NOTE: This information is only used for _display_ purposes: it in no way affects any of the arithmetic of the contract, including {IERC20-balanceOf} and {IERC20-transfer}." + }, + "decreaseAllowance(address,uint256)": { + "details": "Atomically decreases the allowance granted to `spender` by the caller. This is an alternative to {approve} that can be used as a mitigation for problems described in {IERC20-approve}. Emits an {Approval} event indicating the updated allowance. Requirements: - `spender` cannot be the zero address. - `spender` must have allowance for the caller of at least `subtractedValue`." + }, + "increaseAllowance(address,uint256)": { + "details": "Atomically increases the allowance granted to `spender` by the caller. This is an alternative to {approve} that can be used as a mitigation for problems described in {IERC20-approve}. Emits an {Approval} event indicating the updated allowance. Requirements: - `spender` cannot be the zero address." + }, + "mint(address,uint256)": { + "details": "The contracts allowed to issue agTokens are the `StableMaster` contract, `VaultManager` contracts associated to this stablecoin as well as the flash loan module (if activated) and potentially contracts whitelisted by governance", + "params": { + "account": "Address to mint to", + "amount": "Amount to mint" + } + }, + "name()": { + "details": "Returns the name of the token." + }, + "nonces(address)": { + "details": "See {IERC20Permit-nonces}." + }, + "permit(address,address,uint256,uint256,uint8,bytes32,bytes32)": { + "details": "See {IERC20Permit-permit}." + }, + "recoverERC20(address,address,uint256)": { + "details": "Can be used to withdraw bridge tokens for them to be de-bridged on mainnet" + }, + "removeBridgeToken(address)": { + "params": { + "bridgeToken": "Address of the bridge token to remove support for" + } + }, + "removeMinter(address)": { + "details": "This function can also be called by a minter wishing to revoke itself", + "params": { + "minter": "Minter address to remove" + } + }, + "setTreasury(address)": { + "params": { + "_treasury": "New treasury address" + } + }, + "swapIn(address,uint256,address)": { + "details": "Some fees may be taken by the protocol depending on the token used and on the address calling", + "params": { + "amount": "Amount of bridge tokens to send", + "bridgeToken": "Bridge token to use to mint", + "to": "Address to which the stablecoin should be sent" + }, + "returns": { + "_0": "Amount of the canonical stablecoin actually minted" + } + }, + "swapOut(address,uint256,address)": { + "details": "Some fees may be taken by the protocol depending on the token used and on the address calling", + "params": { + "amount": "Amount of canonical tokens to burn", + "bridgeToken": "Bridge token required", + "to": "Address to which the bridge token should be sent" + }, + "returns": { + "_0": "Amount of bridge tokens actually sent back" + } + }, + "symbol()": { + "details": "Returns the symbol of the token, usually a shorter version of the name." + }, + "totalSupply()": { + "details": "See {IERC20-totalSupply}." + }, + "transfer(address,uint256)": { + "details": "See {IERC20-transfer}. Requirements: - `to` cannot be the zero address. - the caller must have a balance of at least `amount`." + }, + "transferFrom(address,address,uint256)": { + "details": "See {IERC20-transferFrom}. Emits an {Approval} event indicating the updated allowance. This is not required by the EIP. See the note at the beginning of {ERC20}. NOTE: Does not update the allowance if the current allowance is the maximum `uint256`. Requirements: - `from` and `to` cannot be the zero address. - `from` must have a balance of at least `amount`. - the caller must have allowance for ``from``'s tokens of at least `amount`." + } + }, + "title": "AgTokenSideChainMultiBridge", + "version": 1 + }, + "userdoc": { + "kind": "user", + "methods": { + "BASE_PARAMS()": { + "notice": "Base used for fee computation" + }, + "addBridgeToken(address,uint256,uint256,uint64,bool)": { + "notice": "Adds support for a bridge token" + }, + "addMinter(address)": { + "notice": "Adds a minter in the contract" + }, + "allBridgeTokens()": { + "notice": "Returns the list of all supported bridge tokens" + }, + "bridgeTokensList(uint256)": { + "notice": "List of all bridge tokens" + }, + "bridges(address)": { + "notice": "Maps a bridge token to data" + }, + "burnFrom(uint256,address,address)": { + "notice": "Burns `amount` tokens from a `burner` address after being asked to by `sender`" + }, + "burnSelf(uint256,address)": { + "notice": "Burns `amount` tokens from a `burner` address" + }, + "burnStablecoin(uint256)": { + "notice": "Allows anyone to burn stablecoins" + }, + "chainTotalHourlyLimit()": { + "notice": "Limit to the amount of tokens that can be sent from that chain to another chain" + }, + "chainTotalUsage(uint256)": { + "notice": "Usage per hour on that chain. Maps an hourly timestamp to the total volume swapped out on the chain" + }, + "currentTotalUsage()": { + "notice": "Returns the current total volume on the chain for the current hour" + }, + "currentUsage(address)": { + "notice": "Returns the current volume for a bridge, for the current hour" + }, + "initialize(string,string,address)": { + "notice": "Initializes the `AgToken` contract" + }, + "isFeeExempt(address)": { + "notice": "Maps an address to whether it is exempt of fees for when it comes to swapping in and out" + }, + "isMinter(address)": { + "notice": "Checks whether an address has the right to mint agTokens" + }, + "mint(address,uint256)": { + "notice": "Lets the `StableMaster` contract or another whitelisted contract mint agTokens" + }, + "recoverERC20(address,address,uint256)": { + "notice": "Recovers any ERC20 token" + }, + "removeBridgeToken(address)": { + "notice": "Removes support for a token" + }, + "removeMinter(address)": { + "notice": "Removes a minter from the contract" + }, + "setChainTotalHourlyLimit(uint256)": { + "notice": "Updates the `chainTotalHourlyLimit` amount" + }, + "setHourlyLimit(address,uint256)": { + "notice": "Updates the `hourlyLimit` amount for `bridgeToken`" + }, + "setLimit(address,uint256)": { + "notice": "Updates the `limit` amount for `bridgeToken`" + }, + "setSwapFee(address,uint64)": { + "notice": "Updates the `fee` value for `bridgeToken`" + }, + "setTreasury(address)": { + "notice": "Sets a new treasury contract" + }, + "swapIn(address,uint256,address)": { + "notice": "Mints the canonical token from a supported bridge token" + }, + "swapOut(address,uint256,address)": { + "notice": "Burns the canonical token in exchange for a bridge token" + }, + "toggleBridge(address)": { + "notice": "Pauses or unpauses swapping in and out for a token" + }, + "toggleFeesForAddress(address)": { + "notice": "Toggles fees for the address `theAddress`" + }, + "treasury()": { + "notice": "Reference to the treasury contract which can grant minting rights" + }, + "usage(address,uint256)": { + "notice": "Maps a bridge token to the associated hourly volume" + } + }, + "notice": "Contract for Angle agTokens on other chains than Ethereum mainnet", + "version": 1 + }, + "storageLayout": { + "storage": [ + { + "astId": 770, + "contract": "contracts/agToken/AgTokenSideChainMultiBridge.sol:AgTokenSideChainMultiBridge", + "label": "_initialized", + "offset": 0, + "slot": "0", + "type": "t_uint8" + }, + { + "astId": 773, + "contract": "contracts/agToken/AgTokenSideChainMultiBridge.sol:AgTokenSideChainMultiBridge", + "label": "_initializing", + "offset": 1, + "slot": "0", + "type": "t_bool" + }, + { + "astId": 2486, + "contract": "contracts/agToken/AgTokenSideChainMultiBridge.sol:AgTokenSideChainMultiBridge", + "label": "__gap", + "offset": 0, + "slot": "1", + "type": "t_array(t_uint256)50_storage" + }, + { + "astId": 1119, + "contract": "contracts/agToken/AgTokenSideChainMultiBridge.sol:AgTokenSideChainMultiBridge", + "label": "_balances", + "offset": 0, + "slot": "51", + "type": "t_mapping(t_address,t_uint256)" + }, + { + "astId": 1125, + "contract": "contracts/agToken/AgTokenSideChainMultiBridge.sol:AgTokenSideChainMultiBridge", + "label": "_allowances", + "offset": 0, + "slot": "52", + "type": "t_mapping(t_address,t_mapping(t_address,t_uint256))" + }, + { + "astId": 1127, + "contract": "contracts/agToken/AgTokenSideChainMultiBridge.sol:AgTokenSideChainMultiBridge", + "label": "_totalSupply", + "offset": 0, + "slot": "53", + "type": "t_uint256" + }, + { + "astId": 1129, + "contract": "contracts/agToken/AgTokenSideChainMultiBridge.sol:AgTokenSideChainMultiBridge", + "label": "_name", + "offset": 0, + "slot": "54", + "type": "t_string_storage" + }, + { + "astId": 1131, + "contract": "contracts/agToken/AgTokenSideChainMultiBridge.sol:AgTokenSideChainMultiBridge", + "label": "_symbol", + "offset": 0, + "slot": "55", + "type": "t_string_storage" + }, + { + "astId": 1710, + "contract": "contracts/agToken/AgTokenSideChainMultiBridge.sol:AgTokenSideChainMultiBridge", + "label": "__gap", + "offset": 0, + "slot": "56", + "type": "t_array(t_uint256)45_storage" + }, + { + "astId": 3203, + "contract": "contracts/agToken/AgTokenSideChainMultiBridge.sol:AgTokenSideChainMultiBridge", + "label": "_HASHED_NAME", + "offset": 0, + "slot": "101", + "type": "t_bytes32" + }, + { + "astId": 3205, + "contract": "contracts/agToken/AgTokenSideChainMultiBridge.sol:AgTokenSideChainMultiBridge", + "label": "_HASHED_VERSION", + "offset": 0, + "slot": "102", + "type": "t_bytes32" + }, + { + "astId": 3343, + "contract": "contracts/agToken/AgTokenSideChainMultiBridge.sol:AgTokenSideChainMultiBridge", + "label": "__gap", + "offset": 0, + "slot": "103", + "type": "t_array(t_uint256)50_storage" + }, + { + "astId": 1840, + "contract": "contracts/agToken/AgTokenSideChainMultiBridge.sol:AgTokenSideChainMultiBridge", + "label": "_nonces", + "offset": 0, + "slot": "153", + "type": "t_mapping(t_address,t_struct(Counter)2493_storage)" + }, + { + "astId": 1848, + "contract": "contracts/agToken/AgTokenSideChainMultiBridge.sol:AgTokenSideChainMultiBridge", + "label": "_PERMIT_TYPEHASH_DEPRECATED_SLOT", + "offset": 0, + "slot": "154", + "type": "t_bytes32" + }, + { + "astId": 2004, + "contract": "contracts/agToken/AgTokenSideChainMultiBridge.sol:AgTokenSideChainMultiBridge", + "label": "__gap", + "offset": 0, + "slot": "155", + "type": "t_array(t_uint256)49_storage" + }, + { + "astId": 7427, + "contract": "contracts/agToken/AgTokenSideChainMultiBridge.sol:AgTokenSideChainMultiBridge", + "label": "isMinter", + "offset": 0, + "slot": "204", + "type": "t_mapping(t_address,t_bool)" + }, + { + "astId": 7430, + "contract": "contracts/agToken/AgTokenSideChainMultiBridge.sol:AgTokenSideChainMultiBridge", + "label": "treasury", + "offset": 0, + "slot": "205", + "type": "t_address" + }, + { + "astId": 7739, + "contract": "contracts/agToken/AgTokenSideChainMultiBridge.sol:AgTokenSideChainMultiBridge", + "label": "bridges", + "offset": 0, + "slot": "206", + "type": "t_mapping(t_address,t_struct(BridgeDetails)7733_storage)" + }, + { + "astId": 7743, + "contract": "contracts/agToken/AgTokenSideChainMultiBridge.sol:AgTokenSideChainMultiBridge", + "label": "bridgeTokensList", + "offset": 0, + "slot": "207", + "type": "t_array(t_address)dyn_storage" + }, + { + "astId": 7750, + "contract": "contracts/agToken/AgTokenSideChainMultiBridge.sol:AgTokenSideChainMultiBridge", + "label": "usage", + "offset": 0, + "slot": "208", + "type": "t_mapping(t_address,t_mapping(t_uint256,t_uint256))" + }, + { + "astId": 7755, + "contract": "contracts/agToken/AgTokenSideChainMultiBridge.sol:AgTokenSideChainMultiBridge", + "label": "isFeeExempt", + "offset": 0, + "slot": "209", + "type": "t_mapping(t_address,t_uint256)" + }, + { + "astId": 7758, + "contract": "contracts/agToken/AgTokenSideChainMultiBridge.sol:AgTokenSideChainMultiBridge", + "label": "chainTotalHourlyLimit", + "offset": 0, + "slot": "210", + "type": "t_uint256" + }, + { + "astId": 7763, + "contract": "contracts/agToken/AgTokenSideChainMultiBridge.sol:AgTokenSideChainMultiBridge", + "label": "chainTotalUsage", + "offset": 0, + "slot": "211", + "type": "t_mapping(t_uint256,t_uint256)" + } + ], + "types": { + "t_address": { + "encoding": "inplace", + "label": "address", + "numberOfBytes": "20" + }, + "t_array(t_address)dyn_storage": { + "base": "t_address", + "encoding": "dynamic_array", + "label": "address[]", + "numberOfBytes": "32" + }, + "t_array(t_uint256)45_storage": { + "base": "t_uint256", + "encoding": "inplace", + "label": "uint256[45]", + "numberOfBytes": "1440" + }, + "t_array(t_uint256)49_storage": { + "base": "t_uint256", + "encoding": "inplace", + "label": "uint256[49]", + "numberOfBytes": "1568" + }, + "t_array(t_uint256)50_storage": { + "base": "t_uint256", + "encoding": "inplace", + "label": "uint256[50]", + "numberOfBytes": "1600" + }, + "t_bool": { + "encoding": "inplace", + "label": "bool", + "numberOfBytes": "1" + }, + "t_bytes32": { + "encoding": "inplace", + "label": "bytes32", + "numberOfBytes": "32" + }, + "t_mapping(t_address,t_bool)": { + "encoding": "mapping", + "key": "t_address", + "label": "mapping(address => bool)", + "numberOfBytes": "32", + "value": "t_bool" + }, + "t_mapping(t_address,t_mapping(t_address,t_uint256))": { + "encoding": "mapping", + "key": "t_address", + "label": "mapping(address => mapping(address => uint256))", + "numberOfBytes": "32", + "value": "t_mapping(t_address,t_uint256)" + }, + "t_mapping(t_address,t_mapping(t_uint256,t_uint256))": { + "encoding": "mapping", + "key": "t_address", + "label": "mapping(address => mapping(uint256 => uint256))", + "numberOfBytes": "32", + "value": "t_mapping(t_uint256,t_uint256)" + }, + "t_mapping(t_address,t_struct(BridgeDetails)7733_storage)": { + "encoding": "mapping", + "key": "t_address", + "label": "mapping(address => struct AgTokenSideChainMultiBridge.BridgeDetails)", + "numberOfBytes": "32", + "value": "t_struct(BridgeDetails)7733_storage" + }, + "t_mapping(t_address,t_struct(Counter)2493_storage)": { + "encoding": "mapping", + "key": "t_address", + "label": "mapping(address => struct CountersUpgradeable.Counter)", + "numberOfBytes": "32", + "value": "t_struct(Counter)2493_storage" + }, + "t_mapping(t_address,t_uint256)": { + "encoding": "mapping", + "key": "t_address", + "label": "mapping(address => uint256)", + "numberOfBytes": "32", + "value": "t_uint256" + }, + "t_mapping(t_uint256,t_uint256)": { + "encoding": "mapping", + "key": "t_uint256", + "label": "mapping(uint256 => uint256)", + "numberOfBytes": "32", + "value": "t_uint256" + }, + "t_string_storage": { + "encoding": "bytes", + "label": "string", + "numberOfBytes": "32" + }, + "t_struct(BridgeDetails)7733_storage": { + "encoding": "inplace", + "label": "struct AgTokenSideChainMultiBridge.BridgeDetails", + "members": [ + { + "astId": 7724, + "contract": "contracts/agToken/AgTokenSideChainMultiBridge.sol:AgTokenSideChainMultiBridge", + "label": "limit", + "offset": 0, + "slot": "0", + "type": "t_uint256" + }, + { + "astId": 7726, + "contract": "contracts/agToken/AgTokenSideChainMultiBridge.sol:AgTokenSideChainMultiBridge", + "label": "hourlyLimit", + "offset": 0, + "slot": "1", + "type": "t_uint256" + }, + { + "astId": 7728, + "contract": "contracts/agToken/AgTokenSideChainMultiBridge.sol:AgTokenSideChainMultiBridge", + "label": "fee", + "offset": 0, + "slot": "2", + "type": "t_uint64" + }, + { + "astId": 7730, + "contract": "contracts/agToken/AgTokenSideChainMultiBridge.sol:AgTokenSideChainMultiBridge", + "label": "allowed", + "offset": 8, + "slot": "2", + "type": "t_bool" + }, + { + "astId": 7732, + "contract": "contracts/agToken/AgTokenSideChainMultiBridge.sol:AgTokenSideChainMultiBridge", + "label": "paused", + "offset": 9, + "slot": "2", + "type": "t_bool" + } + ], + "numberOfBytes": "96" + }, + "t_struct(Counter)2493_storage": { + "encoding": "inplace", + "label": "struct CountersUpgradeable.Counter", + "members": [ + { + "astId": 2492, + "contract": "contracts/agToken/AgTokenSideChainMultiBridge.sol:AgTokenSideChainMultiBridge", + "label": "_value", + "offset": 0, + "slot": "0", + "type": "t_uint256" + } + ], + "numberOfBytes": "32" + }, + "t_uint256": { + "encoding": "inplace", + "label": "uint256", + "numberOfBytes": "32" + }, + "t_uint64": { + "encoding": "inplace", + "label": "uint64", + "numberOfBytes": "8" + }, + "t_uint8": { + "encoding": "inplace", + "label": "uint8", + "numberOfBytes": "1" + } + } + } +} \ No newline at end of file diff --git a/deployments/polygon/CoreBorrowTest.json b/deployments/polygon/CoreBorrowTest.json new file mode 100644 index 00000000..a014ce13 --- /dev/null +++ b/deployments/polygon/CoreBorrowTest.json @@ -0,0 +1,340 @@ +{ + "address": "0x57EF4E590a0EBa16A5893443C5b1F6Fb9ED7e341", + "abi": [ + { + "inputs": [ + { + "internalType": "address", + "name": "_logic", + "type": "address" + }, + { + "internalType": "address", + "name": "admin_", + "type": "address" + }, + { + "internalType": "bytes", + "name": "_data", + "type": "bytes" + } + ], + "stateMutability": "payable", + "type": "constructor" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "previousAdmin", + "type": "address" + }, + { + "indexed": false, + "internalType": "address", + "name": "newAdmin", + "type": "address" + } + ], + "name": "AdminChanged", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "beacon", + "type": "address" + } + ], + "name": "BeaconUpgraded", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "implementation", + "type": "address" + } + ], + "name": "Upgraded", + "type": "event" + }, + { + "stateMutability": "payable", + "type": "fallback" + }, + { + "inputs": [], + "name": "admin", + "outputs": [ + { + "internalType": "address", + "name": "admin_", + "type": "address" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "newAdmin", + "type": "address" + } + ], + "name": "changeAdmin", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "implementation", + "outputs": [ + { + "internalType": "address", + "name": "implementation_", + "type": "address" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "newImplementation", + "type": "address" + } + ], + "name": "upgradeTo", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "newImplementation", + "type": "address" + }, + { + "internalType": "bytes", + "name": "data", + "type": "bytes" + } + ], + "name": "upgradeToAndCall", + "outputs": [], + "stateMutability": "payable", + "type": "function" + }, + { + "stateMutability": "payable", + "type": "receive" + } + ], + "transactionHash": "0xbfd571c0876af93fb127c52da9fb57dc01093685b64dd864ab65ea7cb1556778", + "receipt": { + "to": null, + "from": "0xfdA462548Ce04282f4B6D6619823a7C64Fdc0185", + "contractAddress": "0x57EF4E590a0EBa16A5893443C5b1F6Fb9ED7e341", + "transactionIndex": 79, + "gasUsed": "1037644", + "logsBloom": "0x00000004000000000800000400000000480000000000000000000000200000000000000000000000000800000000000000008000000000000000000000000000000000000000000000000000000002800000000000000000000100000000000000000000020000400000000000000800000000810000000080000000000100000000000000000000000000800000000000000003000000040000000000804000200000000000000000000000000000000000000000000000001000000002205000002020020000000001008000800000000800000400000100100000000020000000800000000000100000000000000400000000000200200000000000140000", + "blockHash": "0x19639f6430a50a3084990bfea0692894dcd5e4b9e850937be5343f36493b3b86", + "transactionHash": "0xbfd571c0876af93fb127c52da9fb57dc01093685b64dd864ab65ea7cb1556778", + "logs": [ + { + "transactionIndex": 79, + "blockNumber": 52158240, + "transactionHash": "0xbfd571c0876af93fb127c52da9fb57dc01093685b64dd864ab65ea7cb1556778", + "address": "0x57EF4E590a0EBa16A5893443C5b1F6Fb9ED7e341", + "topics": [ + "0xbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b", + "0x000000000000000000000000a2875bc2e4d1567190fa7a045427041d51b7c2b1" + ], + "data": "0x", + "logIndex": 878, + "blockHash": "0x19639f6430a50a3084990bfea0692894dcd5e4b9e850937be5343f36493b3b86" + }, + { + "transactionIndex": 79, + "blockNumber": 52158240, + "transactionHash": "0xbfd571c0876af93fb127c52da9fb57dc01093685b64dd864ab65ea7cb1556778", + "address": "0x57EF4E590a0EBa16A5893443C5b1F6Fb9ED7e341", + "topics": [ + "0x2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d", + "0x7935bd0ae54bc31f548c14dba4d37c5c64b3f8ca900cb468fb8abd54d5894f55", + "0x000000000000000000000000fda462548ce04282f4b6d6619823a7c64fdc0185", + "0x000000000000000000000000fda462548ce04282f4b6d6619823a7c64fdc0185" + ], + "data": "0x", + "logIndex": 879, + "blockHash": "0x19639f6430a50a3084990bfea0692894dcd5e4b9e850937be5343f36493b3b86" + }, + { + "transactionIndex": 79, + "blockNumber": 52158240, + "transactionHash": "0xbfd571c0876af93fb127c52da9fb57dc01093685b64dd864ab65ea7cb1556778", + "address": "0x57EF4E590a0EBa16A5893443C5b1F6Fb9ED7e341", + "topics": [ + "0x2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d", + "0x55435dd261a4b9b3364963f7738a7a662ad9c84396d64be3365284bb7f0a5041", + "0x0000000000000000000000003b9d32d0822a6351f415beab05251c1457ff6f8d", + "0x000000000000000000000000fda462548ce04282f4b6d6619823a7c64fdc0185" + ], + "data": "0x", + "logIndex": 880, + "blockHash": "0x19639f6430a50a3084990bfea0692894dcd5e4b9e850937be5343f36493b3b86" + }, + { + "transactionIndex": 79, + "blockNumber": 52158240, + "transactionHash": "0xbfd571c0876af93fb127c52da9fb57dc01093685b64dd864ab65ea7cb1556778", + "address": "0x57EF4E590a0EBa16A5893443C5b1F6Fb9ED7e341", + "topics": [ + "0x2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d", + "0x55435dd261a4b9b3364963f7738a7a662ad9c84396d64be3365284bb7f0a5041", + "0x000000000000000000000000fda462548ce04282f4b6d6619823a7c64fdc0185", + "0x000000000000000000000000fda462548ce04282f4b6d6619823a7c64fdc0185" + ], + "data": "0x", + "logIndex": 881, + "blockHash": "0x19639f6430a50a3084990bfea0692894dcd5e4b9e850937be5343f36493b3b86" + }, + { + "transactionIndex": 79, + "blockNumber": 52158240, + "transactionHash": "0xbfd571c0876af93fb127c52da9fb57dc01093685b64dd864ab65ea7cb1556778", + "address": "0x57EF4E590a0EBa16A5893443C5b1F6Fb9ED7e341", + "topics": [ + "0xbd79b86ffe0ab8e8776151514217cd7cacd52c909f66475c3af44e129f0b00ff", + "0x55435dd261a4b9b3364963f7738a7a662ad9c84396d64be3365284bb7f0a5041", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x7935bd0ae54bc31f548c14dba4d37c5c64b3f8ca900cb468fb8abd54d5894f55" + ], + "data": "0x", + "logIndex": 882, + "blockHash": "0x19639f6430a50a3084990bfea0692894dcd5e4b9e850937be5343f36493b3b86" + }, + { + "transactionIndex": 79, + "blockNumber": 52158240, + "transactionHash": "0xbfd571c0876af93fb127c52da9fb57dc01093685b64dd864ab65ea7cb1556778", + "address": "0x57EF4E590a0EBa16A5893443C5b1F6Fb9ED7e341", + "topics": [ + "0xbd79b86ffe0ab8e8776151514217cd7cacd52c909f66475c3af44e129f0b00ff", + "0x7935bd0ae54bc31f548c14dba4d37c5c64b3f8ca900cb468fb8abd54d5894f55", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x7935bd0ae54bc31f548c14dba4d37c5c64b3f8ca900cb468fb8abd54d5894f55" + ], + "data": "0x", + "logIndex": 883, + "blockHash": "0x19639f6430a50a3084990bfea0692894dcd5e4b9e850937be5343f36493b3b86" + }, + { + "transactionIndex": 79, + "blockNumber": 52158240, + "transactionHash": "0xbfd571c0876af93fb127c52da9fb57dc01093685b64dd864ab65ea7cb1556778", + "address": "0x57EF4E590a0EBa16A5893443C5b1F6Fb9ED7e341", + "topics": [ + "0xbd79b86ffe0ab8e8776151514217cd7cacd52c909f66475c3af44e129f0b00ff", + "0x0ae0130c6b34f32239dfe5e419a3fbd7546b44e99783257f2d93526d5a936d46", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x7935bd0ae54bc31f548c14dba4d37c5c64b3f8ca900cb468fb8abd54d5894f55" + ], + "data": "0x", + "logIndex": 884, + "blockHash": "0x19639f6430a50a3084990bfea0692894dcd5e4b9e850937be5343f36493b3b86" + }, + { + "transactionIndex": 79, + "blockNumber": 52158240, + "transactionHash": "0xbfd571c0876af93fb127c52da9fb57dc01093685b64dd864ab65ea7cb1556778", + "address": "0x57EF4E590a0EBa16A5893443C5b1F6Fb9ED7e341", + "topics": [ + "0x7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f" + ], + "data": "0x0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000bfca293e17e067e8abdca30a5d35addd0cbae6d6", + "logIndex": 885, + "blockHash": "0x19639f6430a50a3084990bfea0692894dcd5e4b9e850937be5343f36493b3b86" + }, + { + "transactionIndex": 79, + "blockNumber": 52158240, + "transactionHash": "0xbfd571c0876af93fb127c52da9fb57dc01093685b64dd864ab65ea7cb1556778", + "address": "0x0000000000000000000000000000000000001010", + "topics": [ + "0x4dfe1bbbcf077ddc3e01291eea2d5c70c2b422b415d95645b9adcfd678cb1d63", + "0x0000000000000000000000000000000000000000000000000000000000001010", + "0x000000000000000000000000fda462548ce04282f4b6d6619823a7c64fdc0185", + "0x000000000000000000000000b9ede6f94d192073d8eaf85f8db677133d483249" + ], + "data": "0x0000000000000000000000000000000000000000000000000082895de6031c7800000000000000000000000000000000000000000000000404745a28dd87f50e0000000000000000000000000000000000000000000003daab7004d5a3f0dfe400000000000000000000000000000000000000000000000403f1d0caf784d8960000000000000000000000000000000000000000000003daabf28e3389f3fc5c", + "logIndex": 886, + "blockHash": "0x19639f6430a50a3084990bfea0692894dcd5e4b9e850937be5343f36493b3b86" + } + ], + "blockNumber": 52158240, + "cumulativeGasUsed": "14713074", + "status": 1, + "byzantium": true + }, + "args": [ + "0xA2875bC2e4D1567190FA7A045427041D51B7C2B1", + "0xBFca293e17e067e8aBdca30A5D35ADDd0cBaE6D6", + "0x485cc955000000000000000000000000fda462548ce04282f4b6d6619823a7c64fdc01850000000000000000000000003b9d32d0822a6351f415beab05251c1457ff6f8d" + ], + "numDeployments": 1, + "solcInputHash": "871924e0c138825a2736b76def8fef8d", + "metadata": "{\"compiler\":{\"version\":\"0.8.17+commit.8df45f5f\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_logic\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"admin_\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"_data\",\"type\":\"bytes\"}],\"stateMutability\":\"payable\",\"type\":\"constructor\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"previousAdmin\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"newAdmin\",\"type\":\"address\"}],\"name\":\"AdminChanged\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"beacon\",\"type\":\"address\"}],\"name\":\"BeaconUpgraded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"implementation\",\"type\":\"address\"}],\"name\":\"Upgraded\",\"type\":\"event\"},{\"stateMutability\":\"payable\",\"type\":\"fallback\"},{\"inputs\":[],\"name\":\"admin\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"admin_\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newAdmin\",\"type\":\"address\"}],\"name\":\"changeAdmin\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"implementation\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"implementation_\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newImplementation\",\"type\":\"address\"}],\"name\":\"upgradeTo\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newImplementation\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"}],\"name\":\"upgradeToAndCall\",\"outputs\":[],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"stateMutability\":\"payable\",\"type\":\"receive\"}],\"devdoc\":{\"details\":\"This contract implements a proxy that is upgradeable by an admin. It is fully forked from OpenZeppelin `TransparentUpgradeableProxy` To avoid https://medium.com/nomic-labs-blog/malicious-backdoors-in-ethereum-proxies-62629adf3357[proxy selector clashing], which can potentially be used in an attack, this contract uses the https://blog.openzeppelin.com/the-transparent-proxy-pattern/[transparent proxy pattern]. This pattern implies two things that go hand in hand: 1. If any account other than the admin calls the proxy, the call will be forwarded to the implementation, even if that call matches one of the admin functions exposed by the proxy itself. 2. If the admin calls the proxy, it can access the admin functions, but its calls will never be forwarded to the implementation. If the admin tries to call a function on the implementation it will fail with an error that says \\\"admin cannot fallback to proxy target\\\". These properties mean that the admin account can only be used for admin actions like upgrading the proxy or changing the admin, so it's best if it's a dedicated account that is not used for anything else. This will avoid headaches due to sudden errors when trying to call a function from the proxy implementation. Our recommendation is for the dedicated account to be an instance of the {ProxyAdmin} contract. If set up this way, you should think of the `ProxyAdmin` instance as the real administrative interface of your proxy.\",\"kind\":\"dev\",\"methods\":{\"admin()\":{\"details\":\"Returns the current admin. NOTE: Only the admin can call this function. See {ProxyAdmin-getProxyAdmin}. TIP: To get this value clients can read directly from the storage slot shown below (specified by EIP1967) using the https://eth.wiki/json-rpc/API#eth_getstorageat[`eth_getStorageAt`] RPC call. `0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103`\"},\"changeAdmin(address)\":{\"details\":\"Changes the admin of the proxy. Emits an {AdminChanged} event. NOTE: Only the admin can call this function. See {ProxyAdmin-changeProxyAdmin}.\"},\"constructor\":{\"details\":\"Initializes an upgradeable proxy managed by `_admin`, backed by the implementation at `_logic`, and optionally initialized with `_data` as explained in {ERC1967Proxy-constructor}.\"},\"implementation()\":{\"details\":\"Returns the current implementation. NOTE: Only the admin can call this function. See {ProxyAdmin-getProxyImplementation}. TIP: To get this value clients can read directly from the storage slot shown below (specified by EIP1967) using the https://eth.wiki/json-rpc/API#eth_getstorageat[`eth_getStorageAt`] RPC call. `0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc`\"},\"upgradeTo(address)\":{\"details\":\"Upgrade the implementation of the proxy. NOTE: Only the admin can call this function. See {ProxyAdmin-upgrade}.\"},\"upgradeToAndCall(address,bytes)\":{\"details\":\"Upgrade the implementation of the proxy, and then call a function from the new implementation as specified by `data`, which should be an encoded function call. This is useful to initialize new storage variables in the proxied contract. NOTE: Only the admin can call this function. See {ProxyAdmin-upgradeAndCall}.\"}},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/external/TransparentUpgradeableProxy.sol\":\"TransparentUpgradeableProxy\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":1000000},\"remappings\":[]},\"sources\":{\"@openzeppelin/contracts/interfaces/draft-IERC1822.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.5.0) (interfaces/draft-IERC1822.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev ERC1822: Universal Upgradeable Proxy Standard (UUPS) documents a method for upgradeability through a simplified\\n * proxy whose upgrades are fully controlled by the current implementation.\\n */\\ninterface IERC1822Proxiable {\\n /**\\n * @dev Returns the storage slot that the proxiable contract assumes is being used to store the implementation\\n * address.\\n *\\n * IMPORTANT: A proxy pointing at a proxiable contract should not be considered proxiable itself, because this risks\\n * bricking a proxy that upgrades to it, by delegating to itself until out of gas. Thus it is critical that this\\n * function revert if invoked through a proxy.\\n */\\n function proxiableUUID() external view returns (bytes32);\\n}\\n\",\"keccak256\":\"0x1d4afe6cb24200cc4545eed814ecf5847277dfe5d613a1707aad5fceecebcfff\",\"license\":\"MIT\"},\"@openzeppelin/contracts/proxy/ERC1967/ERC1967Proxy.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.7.0) (proxy/ERC1967/ERC1967Proxy.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../Proxy.sol\\\";\\nimport \\\"./ERC1967Upgrade.sol\\\";\\n\\n/**\\n * @dev This contract implements an upgradeable proxy. It is upgradeable because calls are delegated to an\\n * implementation address that can be changed. This address is stored in storage in the location specified by\\n * https://eips.ethereum.org/EIPS/eip-1967[EIP1967], so that it doesn't conflict with the storage layout of the\\n * implementation behind the proxy.\\n */\\ncontract ERC1967Proxy is Proxy, ERC1967Upgrade {\\n /**\\n * @dev Initializes the upgradeable proxy with an initial implementation specified by `_logic`.\\n *\\n * If `_data` is nonempty, it's used as data in a delegate call to `_logic`. This will typically be an encoded\\n * function call, and allows initializing the storage of the proxy like a Solidity constructor.\\n */\\n constructor(address _logic, bytes memory _data) payable {\\n _upgradeToAndCall(_logic, _data, false);\\n }\\n\\n /**\\n * @dev Returns the current implementation address.\\n */\\n function _implementation() internal view virtual override returns (address impl) {\\n return ERC1967Upgrade._getImplementation();\\n }\\n}\\n\",\"keccak256\":\"0xa2b22da3032e50b55f95ec1d13336102d675f341167aa76db571ef7f8bb7975d\",\"license\":\"MIT\"},\"@openzeppelin/contracts/proxy/ERC1967/ERC1967Upgrade.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.5.0) (proxy/ERC1967/ERC1967Upgrade.sol)\\n\\npragma solidity ^0.8.2;\\n\\nimport \\\"../beacon/IBeacon.sol\\\";\\nimport \\\"../../interfaces/draft-IERC1822.sol\\\";\\nimport \\\"../../utils/Address.sol\\\";\\nimport \\\"../../utils/StorageSlot.sol\\\";\\n\\n/**\\n * @dev This abstract contract provides getters and event emitting update functions for\\n * https://eips.ethereum.org/EIPS/eip-1967[EIP1967] slots.\\n *\\n * _Available since v4.1._\\n *\\n * @custom:oz-upgrades-unsafe-allow delegatecall\\n */\\nabstract contract ERC1967Upgrade {\\n // This is the keccak-256 hash of \\\"eip1967.proxy.rollback\\\" subtracted by 1\\n bytes32 private constant _ROLLBACK_SLOT = 0x4910fdfa16fed3260ed0e7147f7cc6da11a60208b5b9406d12a635614ffd9143;\\n\\n /**\\n * @dev Storage slot with the address of the current implementation.\\n * This is the keccak-256 hash of \\\"eip1967.proxy.implementation\\\" subtracted by 1, and is\\n * validated in the constructor.\\n */\\n bytes32 internal constant _IMPLEMENTATION_SLOT = 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc;\\n\\n /**\\n * @dev Emitted when the implementation is upgraded.\\n */\\n event Upgraded(address indexed implementation);\\n\\n /**\\n * @dev Returns the current implementation address.\\n */\\n function _getImplementation() internal view returns (address) {\\n return StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value;\\n }\\n\\n /**\\n * @dev Stores a new address in the EIP1967 implementation slot.\\n */\\n function _setImplementation(address newImplementation) private {\\n require(Address.isContract(newImplementation), \\\"ERC1967: new implementation is not a contract\\\");\\n StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value = newImplementation;\\n }\\n\\n /**\\n * @dev Perform implementation upgrade\\n *\\n * Emits an {Upgraded} event.\\n */\\n function _upgradeTo(address newImplementation) internal {\\n _setImplementation(newImplementation);\\n emit Upgraded(newImplementation);\\n }\\n\\n /**\\n * @dev Perform implementation upgrade with additional setup call.\\n *\\n * Emits an {Upgraded} event.\\n */\\n function _upgradeToAndCall(\\n address newImplementation,\\n bytes memory data,\\n bool forceCall\\n ) internal {\\n _upgradeTo(newImplementation);\\n if (data.length > 0 || forceCall) {\\n Address.functionDelegateCall(newImplementation, data);\\n }\\n }\\n\\n /**\\n * @dev Perform implementation upgrade with security checks for UUPS proxies, and additional setup call.\\n *\\n * Emits an {Upgraded} event.\\n */\\n function _upgradeToAndCallUUPS(\\n address newImplementation,\\n bytes memory data,\\n bool forceCall\\n ) internal {\\n // Upgrades from old implementations will perform a rollback test. This test requires the new\\n // implementation to upgrade back to the old, non-ERC1822 compliant, implementation. Removing\\n // this special case will break upgrade paths from old UUPS implementation to new ones.\\n if (StorageSlot.getBooleanSlot(_ROLLBACK_SLOT).value) {\\n _setImplementation(newImplementation);\\n } else {\\n try IERC1822Proxiable(newImplementation).proxiableUUID() returns (bytes32 slot) {\\n require(slot == _IMPLEMENTATION_SLOT, \\\"ERC1967Upgrade: unsupported proxiableUUID\\\");\\n } catch {\\n revert(\\\"ERC1967Upgrade: new implementation is not UUPS\\\");\\n }\\n _upgradeToAndCall(newImplementation, data, forceCall);\\n }\\n }\\n\\n /**\\n * @dev Storage slot with the admin of the contract.\\n * This is the keccak-256 hash of \\\"eip1967.proxy.admin\\\" subtracted by 1, and is\\n * validated in the constructor.\\n */\\n bytes32 internal constant _ADMIN_SLOT = 0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103;\\n\\n /**\\n * @dev Emitted when the admin account has changed.\\n */\\n event AdminChanged(address previousAdmin, address newAdmin);\\n\\n /**\\n * @dev Returns the current admin.\\n */\\n function _getAdmin() internal view returns (address) {\\n return StorageSlot.getAddressSlot(_ADMIN_SLOT).value;\\n }\\n\\n /**\\n * @dev Stores a new address in the EIP1967 admin slot.\\n */\\n function _setAdmin(address newAdmin) private {\\n require(newAdmin != address(0), \\\"ERC1967: new admin is the zero address\\\");\\n StorageSlot.getAddressSlot(_ADMIN_SLOT).value = newAdmin;\\n }\\n\\n /**\\n * @dev Changes the admin of the proxy.\\n *\\n * Emits an {AdminChanged} event.\\n */\\n function _changeAdmin(address newAdmin) internal {\\n emit AdminChanged(_getAdmin(), newAdmin);\\n _setAdmin(newAdmin);\\n }\\n\\n /**\\n * @dev The storage slot of the UpgradeableBeacon contract which defines the implementation for this proxy.\\n * This is bytes32(uint256(keccak256('eip1967.proxy.beacon')) - 1)) and is validated in the constructor.\\n */\\n bytes32 internal constant _BEACON_SLOT = 0xa3f0ad74e5423aebfd80d3ef4346578335a9a72aeaee59ff6cb3582b35133d50;\\n\\n /**\\n * @dev Emitted when the beacon is upgraded.\\n */\\n event BeaconUpgraded(address indexed beacon);\\n\\n /**\\n * @dev Returns the current beacon.\\n */\\n function _getBeacon() internal view returns (address) {\\n return StorageSlot.getAddressSlot(_BEACON_SLOT).value;\\n }\\n\\n /**\\n * @dev Stores a new beacon in the EIP1967 beacon slot.\\n */\\n function _setBeacon(address newBeacon) private {\\n require(Address.isContract(newBeacon), \\\"ERC1967: new beacon is not a contract\\\");\\n require(\\n Address.isContract(IBeacon(newBeacon).implementation()),\\n \\\"ERC1967: beacon implementation is not a contract\\\"\\n );\\n StorageSlot.getAddressSlot(_BEACON_SLOT).value = newBeacon;\\n }\\n\\n /**\\n * @dev Perform beacon upgrade with additional setup call. Note: This upgrades the address of the beacon, it does\\n * not upgrade the implementation contained in the beacon (see {UpgradeableBeacon-_setImplementation} for that).\\n *\\n * Emits a {BeaconUpgraded} event.\\n */\\n function _upgradeBeaconToAndCall(\\n address newBeacon,\\n bytes memory data,\\n bool forceCall\\n ) internal {\\n _setBeacon(newBeacon);\\n emit BeaconUpgraded(newBeacon);\\n if (data.length > 0 || forceCall) {\\n Address.functionDelegateCall(IBeacon(newBeacon).implementation(), data);\\n }\\n }\\n}\\n\",\"keccak256\":\"0xabf3f59bc0e5423eae45e459dbe92e7052c6983628d39008590edc852a62f94a\",\"license\":\"MIT\"},\"@openzeppelin/contracts/proxy/Proxy.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.6.0) (proxy/Proxy.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev This abstract contract provides a fallback function that delegates all calls to another contract using the EVM\\n * instruction `delegatecall`. We refer to the second contract as the _implementation_ behind the proxy, and it has to\\n * be specified by overriding the virtual {_implementation} function.\\n *\\n * Additionally, delegation to the implementation can be triggered manually through the {_fallback} function, or to a\\n * different contract through the {_delegate} function.\\n *\\n * The success and return data of the delegated call will be returned back to the caller of the proxy.\\n */\\nabstract contract Proxy {\\n /**\\n * @dev Delegates the current call to `implementation`.\\n *\\n * This function does not return to its internal call site, it will return directly to the external caller.\\n */\\n function _delegate(address implementation) internal virtual {\\n assembly {\\n // Copy msg.data. We take full control of memory in this inline assembly\\n // block because it will not return to Solidity code. We overwrite the\\n // Solidity scratch pad at memory position 0.\\n calldatacopy(0, 0, calldatasize())\\n\\n // Call the implementation.\\n // out and outsize are 0 because we don't know the size yet.\\n let result := delegatecall(gas(), implementation, 0, calldatasize(), 0, 0)\\n\\n // Copy the returned data.\\n returndatacopy(0, 0, returndatasize())\\n\\n switch result\\n // delegatecall returns 0 on error.\\n case 0 {\\n revert(0, returndatasize())\\n }\\n default {\\n return(0, returndatasize())\\n }\\n }\\n }\\n\\n /**\\n * @dev This is a virtual function that should be overridden so it returns the address to which the fallback function\\n * and {_fallback} should delegate.\\n */\\n function _implementation() internal view virtual returns (address);\\n\\n /**\\n * @dev Delegates the current call to the address returned by `_implementation()`.\\n *\\n * This function does not return to its internal call site, it will return directly to the external caller.\\n */\\n function _fallback() internal virtual {\\n _beforeFallback();\\n _delegate(_implementation());\\n }\\n\\n /**\\n * @dev Fallback function that delegates calls to the address returned by `_implementation()`. Will run if no other\\n * function in the contract matches the call data.\\n */\\n fallback() external payable virtual {\\n _fallback();\\n }\\n\\n /**\\n * @dev Fallback function that delegates calls to the address returned by `_implementation()`. Will run if call data\\n * is empty.\\n */\\n receive() external payable virtual {\\n _fallback();\\n }\\n\\n /**\\n * @dev Hook that is called before falling back to the implementation. Can happen as part of a manual `_fallback`\\n * call, or as part of the Solidity `fallback` or `receive` functions.\\n *\\n * If overridden should call `super._beforeFallback()`.\\n */\\n function _beforeFallback() internal virtual {}\\n}\\n\",\"keccak256\":\"0xc130fe33f1b2132158531a87734153293f6d07bc263ff4ac90e85da9c82c0e27\",\"license\":\"MIT\"},\"@openzeppelin/contracts/proxy/beacon/IBeacon.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (proxy/beacon/IBeacon.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev This is the interface that {BeaconProxy} expects of its beacon.\\n */\\ninterface IBeacon {\\n /**\\n * @dev Must return an address that can be used as a delegate call target.\\n *\\n * {BeaconProxy} will check that this address is a contract.\\n */\\n function implementation() external view returns (address);\\n}\\n\",\"keccak256\":\"0xd50a3421ac379ccb1be435fa646d66a65c986b4924f0849839f08692f39dde61\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/Address.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.7.0) (utils/Address.sol)\\n\\npragma solidity ^0.8.1;\\n\\n/**\\n * @dev Collection of functions related to the address type\\n */\\nlibrary Address {\\n /**\\n * @dev Returns true if `account` is a contract.\\n *\\n * [IMPORTANT]\\n * ====\\n * It is unsafe to assume that an address for which this function returns\\n * false is an externally-owned account (EOA) and not a contract.\\n *\\n * Among others, `isContract` will return false for the following\\n * types of addresses:\\n *\\n * - an externally-owned account\\n * - a contract in construction\\n * - an address where a contract will be created\\n * - an address where a contract lived, but was destroyed\\n * ====\\n *\\n * [IMPORTANT]\\n * ====\\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\\n *\\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\\n * constructor.\\n * ====\\n */\\n function isContract(address account) internal view returns (bool) {\\n // This method relies on extcodesize/address.code.length, which returns 0\\n // for contracts in construction, since the code is only stored at the end\\n // of the constructor execution.\\n\\n return account.code.length > 0;\\n }\\n\\n /**\\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\\n * `recipient`, forwarding all available gas and reverting on errors.\\n *\\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\\n * imposed by `transfer`, making them unable to receive funds via\\n * `transfer`. {sendValue} removes this limitation.\\n *\\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\\n *\\n * IMPORTANT: because control is transferred to `recipient`, care must be\\n * taken to not create reentrancy vulnerabilities. Consider using\\n * {ReentrancyGuard} or the\\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\\n */\\n function sendValue(address payable recipient, uint256 amount) internal {\\n require(address(this).balance >= amount, \\\"Address: insufficient balance\\\");\\n\\n (bool success, ) = recipient.call{value: amount}(\\\"\\\");\\n require(success, \\\"Address: unable to send value, recipient may have reverted\\\");\\n }\\n\\n /**\\n * @dev Performs a Solidity function call using a low level `call`. A\\n * plain `call` is an unsafe replacement for a function call: use this\\n * function instead.\\n *\\n * If `target` reverts with a revert reason, it is bubbled up by this\\n * function (like regular Solidity function calls).\\n *\\n * Returns the raw returned data. To convert to the expected return value,\\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\\n *\\n * Requirements:\\n *\\n * - `target` must be a contract.\\n * - calling `target` with `data` must not revert.\\n *\\n * _Available since v3.1._\\n */\\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\\n return functionCall(target, data, \\\"Address: low-level call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\\n * `errorMessage` as a fallback revert reason when `target` reverts.\\n *\\n * _Available since v3.1._\\n */\\n function functionCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n return functionCallWithValue(target, data, 0, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but also transferring `value` wei to `target`.\\n *\\n * Requirements:\\n *\\n * - the calling contract must have an ETH balance of at least `value`.\\n * - the called Solidity function must be `payable`.\\n *\\n * _Available since v3.1._\\n */\\n function functionCallWithValue(\\n address target,\\n bytes memory data,\\n uint256 value\\n ) internal returns (bytes memory) {\\n return functionCallWithValue(target, data, value, \\\"Address: low-level call with value failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\\n * with `errorMessage` as a fallback revert reason when `target` reverts.\\n *\\n * _Available since v3.1._\\n */\\n function functionCallWithValue(\\n address target,\\n bytes memory data,\\n uint256 value,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n require(address(this).balance >= value, \\\"Address: insufficient balance for call\\\");\\n require(isContract(target), \\\"Address: call to non-contract\\\");\\n\\n (bool success, bytes memory returndata) = target.call{value: value}(data);\\n return verifyCallResult(success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but performing a static call.\\n *\\n * _Available since v3.3._\\n */\\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\\n return functionStaticCall(target, data, \\\"Address: low-level static call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\\n * but performing a static call.\\n *\\n * _Available since v3.3._\\n */\\n function functionStaticCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal view returns (bytes memory) {\\n require(isContract(target), \\\"Address: static call to non-contract\\\");\\n\\n (bool success, bytes memory returndata) = target.staticcall(data);\\n return verifyCallResult(success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but performing a delegate call.\\n *\\n * _Available since v3.4._\\n */\\n function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {\\n return functionDelegateCall(target, data, \\\"Address: low-level delegate call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\\n * but performing a delegate call.\\n *\\n * _Available since v3.4._\\n */\\n function functionDelegateCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n require(isContract(target), \\\"Address: delegate call to non-contract\\\");\\n\\n (bool success, bytes memory returndata) = target.delegatecall(data);\\n return verifyCallResult(success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the\\n * revert reason using the provided one.\\n *\\n * _Available since v4.3._\\n */\\n function verifyCallResult(\\n bool success,\\n bytes memory returndata,\\n string memory errorMessage\\n ) internal pure returns (bytes memory) {\\n if (success) {\\n return returndata;\\n } else {\\n // Look for revert reason and bubble it up if present\\n if (returndata.length > 0) {\\n // The easiest way to bubble the revert reason is using memory via assembly\\n /// @solidity memory-safe-assembly\\n assembly {\\n let returndata_size := mload(returndata)\\n revert(add(32, returndata), returndata_size)\\n }\\n } else {\\n revert(errorMessage);\\n }\\n }\\n }\\n}\\n\",\"keccak256\":\"0xd6153ce99bcdcce22b124f755e72553295be6abcd63804cfdffceb188b8bef10\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/StorageSlot.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.7.0) (utils/StorageSlot.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Library for reading and writing primitive types to specific storage slots.\\n *\\n * Storage slots are often used to avoid storage conflict when dealing with upgradeable contracts.\\n * This library helps with reading and writing to such slots without the need for inline assembly.\\n *\\n * The functions in this library return Slot structs that contain a `value` member that can be used to read or write.\\n *\\n * Example usage to set ERC1967 implementation slot:\\n * ```\\n * contract ERC1967 {\\n * bytes32 internal constant _IMPLEMENTATION_SLOT = 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc;\\n *\\n * function _getImplementation() internal view returns (address) {\\n * return StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value;\\n * }\\n *\\n * function _setImplementation(address newImplementation) internal {\\n * require(Address.isContract(newImplementation), \\\"ERC1967: new implementation is not a contract\\\");\\n * StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value = newImplementation;\\n * }\\n * }\\n * ```\\n *\\n * _Available since v4.1 for `address`, `bool`, `bytes32`, and `uint256`._\\n */\\nlibrary StorageSlot {\\n struct AddressSlot {\\n address value;\\n }\\n\\n struct BooleanSlot {\\n bool value;\\n }\\n\\n struct Bytes32Slot {\\n bytes32 value;\\n }\\n\\n struct Uint256Slot {\\n uint256 value;\\n }\\n\\n /**\\n * @dev Returns an `AddressSlot` with member `value` located at `slot`.\\n */\\n function getAddressSlot(bytes32 slot) internal pure returns (AddressSlot storage r) {\\n /// @solidity memory-safe-assembly\\n assembly {\\n r.slot := slot\\n }\\n }\\n\\n /**\\n * @dev Returns an `BooleanSlot` with member `value` located at `slot`.\\n */\\n function getBooleanSlot(bytes32 slot) internal pure returns (BooleanSlot storage r) {\\n /// @solidity memory-safe-assembly\\n assembly {\\n r.slot := slot\\n }\\n }\\n\\n /**\\n * @dev Returns an `Bytes32Slot` with member `value` located at `slot`.\\n */\\n function getBytes32Slot(bytes32 slot) internal pure returns (Bytes32Slot storage r) {\\n /// @solidity memory-safe-assembly\\n assembly {\\n r.slot := slot\\n }\\n }\\n\\n /**\\n * @dev Returns an `Uint256Slot` with member `value` located at `slot`.\\n */\\n function getUint256Slot(bytes32 slot) internal pure returns (Uint256Slot storage r) {\\n /// @solidity memory-safe-assembly\\n assembly {\\n r.slot := slot\\n }\\n }\\n}\\n\",\"keccak256\":\"0xd5c50c54bf02740ebd122ff06832546cb5fa84486d52695a9ccfd11666e0c81d\",\"license\":\"MIT\"},\"contracts/external/TransparentUpgradeableProxy.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-3.0\\n\\npragma solidity ^0.8.12;\\n\\nimport \\\"@openzeppelin/contracts/proxy/ERC1967/ERC1967Proxy.sol\\\";\\n\\n/**\\n * @dev This contract implements a proxy that is upgradeable by an admin. It is fully forked from OpenZeppelin\\n * `TransparentUpgradeableProxy`\\n *\\n * To avoid https://medium.com/nomic-labs-blog/malicious-backdoors-in-ethereum-proxies-62629adf3357[proxy selector\\n * clashing], which can potentially be used in an attack, this contract uses the\\n * https://blog.openzeppelin.com/the-transparent-proxy-pattern/[transparent proxy pattern]. This pattern implies two\\n * things that go hand in hand:\\n *\\n * 1. If any account other than the admin calls the proxy, the call will be forwarded to the implementation, even if\\n * that call matches one of the admin functions exposed by the proxy itself.\\n * 2. If the admin calls the proxy, it can access the admin functions, but its calls will never be forwarded to the\\n * implementation. If the admin tries to call a function on the implementation it will fail with an error that says\\n * \\\"admin cannot fallback to proxy target\\\".\\n *\\n * These properties mean that the admin account can only be used for admin actions like upgrading the proxy or changing\\n * the admin, so it's best if it's a dedicated account that is not used for anything else. This will avoid headaches due\\n * to sudden errors when trying to call a function from the proxy implementation.\\n *\\n * Our recommendation is for the dedicated account to be an instance of the {ProxyAdmin} contract. If set up this way,\\n * you should think of the `ProxyAdmin` instance as the real administrative interface of your proxy.\\n */\\ncontract TransparentUpgradeableProxy is ERC1967Proxy {\\n /**\\n * @dev Initializes an upgradeable proxy managed by `_admin`, backed by the implementation at `_logic`, and\\n * optionally initialized with `_data` as explained in {ERC1967Proxy-constructor}.\\n */\\n constructor(address _logic, address admin_, bytes memory _data) payable ERC1967Proxy(_logic, _data) {\\n assert(_ADMIN_SLOT == bytes32(uint256(keccak256(\\\"eip1967.proxy.admin\\\")) - 1));\\n _changeAdmin(admin_);\\n }\\n\\n /**\\n * @dev Modifier used internally that will delegate the call to the implementation unless the sender is the admin.\\n */\\n modifier ifAdmin() {\\n if (msg.sender == _getAdmin()) {\\n _;\\n } else {\\n _fallback();\\n }\\n }\\n\\n /**\\n * @dev Returns the current admin.\\n *\\n * NOTE: Only the admin can call this function. See {ProxyAdmin-getProxyAdmin}.\\n *\\n * TIP: To get this value clients can read directly from the storage slot shown below (specified by EIP1967) using the\\n * https://eth.wiki/json-rpc/API#eth_getstorageat[`eth_getStorageAt`] RPC call.\\n * `0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103`\\n */\\n function admin() external ifAdmin returns (address admin_) {\\n admin_ = _getAdmin();\\n }\\n\\n /**\\n * @dev Returns the current implementation.\\n *\\n * NOTE: Only the admin can call this function. See {ProxyAdmin-getProxyImplementation}.\\n *\\n * TIP: To get this value clients can read directly from the storage slot shown below (specified by EIP1967) using the\\n * https://eth.wiki/json-rpc/API#eth_getstorageat[`eth_getStorageAt`] RPC call.\\n * `0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc`\\n */\\n function implementation() external ifAdmin returns (address implementation_) {\\n implementation_ = _implementation();\\n }\\n\\n /**\\n * @dev Changes the admin of the proxy.\\n *\\n * Emits an {AdminChanged} event.\\n *\\n * NOTE: Only the admin can call this function. See {ProxyAdmin-changeProxyAdmin}.\\n */\\n function changeAdmin(address newAdmin) external virtual ifAdmin {\\n _changeAdmin(newAdmin);\\n }\\n\\n /**\\n * @dev Upgrade the implementation of the proxy.\\n *\\n * NOTE: Only the admin can call this function. See {ProxyAdmin-upgrade}.\\n */\\n function upgradeTo(address newImplementation) external ifAdmin {\\n _upgradeToAndCall(newImplementation, bytes(\\\"\\\"), false);\\n }\\n\\n /**\\n * @dev Upgrade the implementation of the proxy, and then call a function from the new implementation as specified\\n * by `data`, which should be an encoded function call. This is useful to initialize new storage variables in the\\n * proxied contract.\\n *\\n * NOTE: Only the admin can call this function. See {ProxyAdmin-upgradeAndCall}.\\n */\\n function upgradeToAndCall(address newImplementation, bytes calldata data) external payable ifAdmin {\\n _upgradeToAndCall(newImplementation, data, true);\\n }\\n\\n /**\\n * @dev Returns the current admin.\\n */\\n function _admin() internal view virtual returns (address) {\\n return _getAdmin();\\n }\\n\\n /**\\n * @dev Makes sure the admin cannot access the fallback function. See {Proxy-_beforeFallback}.\\n */\\n function _beforeFallback() internal virtual override {\\n require(msg.sender != _getAdmin(), \\\"TransparentUpgradeableProxy: admin cannot fallback to proxy target\\\");\\n super._beforeFallback();\\n }\\n}\\n\",\"keccak256\":\"0x93a67a0f612ea3ff2a76315e138a6a88267270a1379d3cc7be52845fbbe611e2\",\"license\":\"GPL-3.0\"}},\"version\":1}", + "bytecode": "0x6080604052604051620010bb380380620010bb8339810160408190526200002691620004d8565b828162000036828260006200009a565b5062000066905060017fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6104620005b8565b6000805160206200107483398151915214620000865762000086620005da565b6200009182620000d7565b50505062000643565b620000a58362000132565b600082511180620000b35750805b15620000d257620000d083836200017460201b6200028c1760201c565b505b505050565b7f7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f62000102620001a5565b604080516001600160a01b03928316815291841660208301520160405180910390a16200012f81620001de565b50565b6200013d8162000293565b6040516001600160a01b038216907fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b90600090a250565b60606200019c8383604051806060016040528060278152602001620010946027913962000347565b90505b92915050565b6000620001cf6000805160206200107483398151915260001b6200042f60201b6200022e1760201c565b546001600160a01b0316919050565b6001600160a01b038116620002495760405162461bcd60e51b815260206004820152602660248201527f455243313936373a206e65772061646d696e20697320746865207a65726f206160448201526564647265737360d01b60648201526084015b60405180910390fd5b80620002726000805160206200107483398151915260001b6200042f60201b6200022e1760201c565b80546001600160a01b0319166001600160a01b039290921691909117905550565b620002a9816200043260201b620002b81760201c565b6200030d5760405162461bcd60e51b815260206004820152602d60248201527f455243313936373a206e657720696d706c656d656e746174696f6e206973206e60448201526c1bdd08184818dbdb9d1c9858dd609a1b606482015260840162000240565b80620002727f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc60001b6200042f60201b6200022e1760201c565b60606001600160a01b0384163b620003b15760405162461bcd60e51b815260206004820152602660248201527f416464726573733a2064656c65676174652063616c6c20746f206e6f6e2d636f6044820152651b9d1c9858dd60d21b606482015260840162000240565b600080856001600160a01b031685604051620003ce9190620005f0565b600060405180830381855af49150503d80600081146200040b576040519150601f19603f3d011682016040523d82523d6000602084013e62000410565b606091505b5090925090506200042382828662000441565b925050505b9392505050565b90565b6001600160a01b03163b151590565b606083156200045257508162000428565b825115620004635782518084602001fd5b8160405162461bcd60e51b81526004016200024091906200060e565b80516001600160a01b03811681146200049757600080fd5b919050565b634e487b7160e01b600052604160045260246000fd5b60005b83811015620004cf578181015183820152602001620004b5565b50506000910152565b600080600060608486031215620004ee57600080fd5b620004f9846200047f565b925062000509602085016200047f565b60408501519092506001600160401b03808211156200052757600080fd5b818601915086601f8301126200053c57600080fd5b8151818111156200055157620005516200049c565b604051601f8201601f19908116603f011681019083821181831017156200057c576200057c6200049c565b816040528281528960208487010111156200059657600080fd5b620005a9836020830160208801620004b2565b80955050505050509250925092565b818103818111156200019f57634e487b7160e01b600052601160045260246000fd5b634e487b7160e01b600052600160045260246000fd5b6000825162000604818460208701620004b2565b9190910192915050565b60208152600082518060208401526200062f816040850160208701620004b2565b601f01601f19169190910160400192915050565b610a2180620006536000396000f3fe60806040526004361061005e5760003560e01c80635c60da1b116100435780635c60da1b146100a85780638f283970146100e6578063f851a440146101065761006d565b80633659cfe6146100755780634f1ef286146100955761006d565b3661006d5761006b61011b565b005b61006b61011b565b34801561008157600080fd5b5061006b610090366004610895565b610135565b61006b6100a33660046108b0565b61017f565b3480156100b457600080fd5b506100bd6101f3565b60405173ffffffffffffffffffffffffffffffffffffffff909116815260200160405180910390f35b3480156100f257600080fd5b5061006b610101366004610895565b610231565b34801561011257600080fd5b506100bd61025e565b6101236102d4565b61013361012e6103ab565b6103b5565b565b61013d6103d9565b73ffffffffffffffffffffffffffffffffffffffff1633036101775761017481604051806020016040528060008152506000610419565b50565b61017461011b565b6101876103d9565b73ffffffffffffffffffffffffffffffffffffffff1633036101eb576101e68383838080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525060019250610419915050565b505050565b6101e661011b565b60006101fd6103d9565b73ffffffffffffffffffffffffffffffffffffffff163303610226576102216103ab565b905090565b61022e61011b565b90565b6102396103d9565b73ffffffffffffffffffffffffffffffffffffffff1633036101775761017481610444565b60006102686103d9565b73ffffffffffffffffffffffffffffffffffffffff163303610226576102216103d9565b60606102b183836040518060600160405280602781526020016109c5602791396104a5565b9392505050565b73ffffffffffffffffffffffffffffffffffffffff163b151590565b6102dc6103d9565b73ffffffffffffffffffffffffffffffffffffffff163303610133576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604260248201527f5472616e73706172656e745570677261646561626c6550726f78793a2061646d60448201527f696e2063616e6e6f742066616c6c6261636b20746f2070726f7879207461726760648201527f6574000000000000000000000000000000000000000000000000000000000000608482015260a4015b60405180910390fd5b60006102216105cd565b3660008037600080366000845af43d6000803e8080156103d4573d6000f35b3d6000fd5b60007fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035b5473ffffffffffffffffffffffffffffffffffffffff16919050565b610422836105f5565b60008251118061042f5750805b156101e65761043e838361028c565b50505050565b7f7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f61046d6103d9565b6040805173ffffffffffffffffffffffffffffffffffffffff928316815291841660208301520160405180910390a161017481610642565b606073ffffffffffffffffffffffffffffffffffffffff84163b61054b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f416464726573733a2064656c65676174652063616c6c20746f206e6f6e2d636f60448201527f6e7472616374000000000000000000000000000000000000000000000000000060648201526084016103a2565b6000808573ffffffffffffffffffffffffffffffffffffffff16856040516105739190610957565b600060405180830381855af49150503d80600081146105ae576040519150601f19603f3d011682016040523d82523d6000602084013e6105b3565b606091505b50915091506105c382828661074e565b9695505050505050565b60007f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc6103fd565b6105fe816107a1565b60405173ffffffffffffffffffffffffffffffffffffffff8216907fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b90600090a250565b73ffffffffffffffffffffffffffffffffffffffff81166106e5576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f455243313936373a206e65772061646d696e20697320746865207a65726f206160448201527f646472657373000000000000000000000000000000000000000000000000000060648201526084016103a2565b807fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035b80547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff9290921691909117905550565b6060831561075d5750816102b1565b82511561076d5782518084602001fd5b816040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016103a29190610973565b73ffffffffffffffffffffffffffffffffffffffff81163b610845576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602d60248201527f455243313936373a206e657720696d706c656d656e746174696f6e206973206e60448201527f6f74206120636f6e74726163740000000000000000000000000000000000000060648201526084016103a2565b807f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc610708565b803573ffffffffffffffffffffffffffffffffffffffff8116811461089057600080fd5b919050565b6000602082840312156108a757600080fd5b6102b18261086c565b6000806000604084860312156108c557600080fd5b6108ce8461086c565b9250602084013567ffffffffffffffff808211156108eb57600080fd5b818601915086601f8301126108ff57600080fd5b81358181111561090e57600080fd5b87602082850101111561092057600080fd5b6020830194508093505050509250925092565b60005b8381101561094e578181015183820152602001610936565b50506000910152565b60008251610969818460208701610933565b9190910192915050565b6020815260008251806020840152610992816040850160208701610933565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016919091016040019291505056fe416464726573733a206c6f772d6c6576656c2064656c65676174652063616c6c206661696c6564a2646970667358221220e96638b07fb1675d93a95c49e417bc8111448b23a59918698cdcd8fd488dd7cf64736f6c63430008110033b53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103416464726573733a206c6f772d6c6576656c2064656c65676174652063616c6c206661696c6564", + "deployedBytecode": "0x60806040526004361061005e5760003560e01c80635c60da1b116100435780635c60da1b146100a85780638f283970146100e6578063f851a440146101065761006d565b80633659cfe6146100755780634f1ef286146100955761006d565b3661006d5761006b61011b565b005b61006b61011b565b34801561008157600080fd5b5061006b610090366004610895565b610135565b61006b6100a33660046108b0565b61017f565b3480156100b457600080fd5b506100bd6101f3565b60405173ffffffffffffffffffffffffffffffffffffffff909116815260200160405180910390f35b3480156100f257600080fd5b5061006b610101366004610895565b610231565b34801561011257600080fd5b506100bd61025e565b6101236102d4565b61013361012e6103ab565b6103b5565b565b61013d6103d9565b73ffffffffffffffffffffffffffffffffffffffff1633036101775761017481604051806020016040528060008152506000610419565b50565b61017461011b565b6101876103d9565b73ffffffffffffffffffffffffffffffffffffffff1633036101eb576101e68383838080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525060019250610419915050565b505050565b6101e661011b565b60006101fd6103d9565b73ffffffffffffffffffffffffffffffffffffffff163303610226576102216103ab565b905090565b61022e61011b565b90565b6102396103d9565b73ffffffffffffffffffffffffffffffffffffffff1633036101775761017481610444565b60006102686103d9565b73ffffffffffffffffffffffffffffffffffffffff163303610226576102216103d9565b60606102b183836040518060600160405280602781526020016109c5602791396104a5565b9392505050565b73ffffffffffffffffffffffffffffffffffffffff163b151590565b6102dc6103d9565b73ffffffffffffffffffffffffffffffffffffffff163303610133576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604260248201527f5472616e73706172656e745570677261646561626c6550726f78793a2061646d60448201527f696e2063616e6e6f742066616c6c6261636b20746f2070726f7879207461726760648201527f6574000000000000000000000000000000000000000000000000000000000000608482015260a4015b60405180910390fd5b60006102216105cd565b3660008037600080366000845af43d6000803e8080156103d4573d6000f35b3d6000fd5b60007fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035b5473ffffffffffffffffffffffffffffffffffffffff16919050565b610422836105f5565b60008251118061042f5750805b156101e65761043e838361028c565b50505050565b7f7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f61046d6103d9565b6040805173ffffffffffffffffffffffffffffffffffffffff928316815291841660208301520160405180910390a161017481610642565b606073ffffffffffffffffffffffffffffffffffffffff84163b61054b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f416464726573733a2064656c65676174652063616c6c20746f206e6f6e2d636f60448201527f6e7472616374000000000000000000000000000000000000000000000000000060648201526084016103a2565b6000808573ffffffffffffffffffffffffffffffffffffffff16856040516105739190610957565b600060405180830381855af49150503d80600081146105ae576040519150601f19603f3d011682016040523d82523d6000602084013e6105b3565b606091505b50915091506105c382828661074e565b9695505050505050565b60007f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc6103fd565b6105fe816107a1565b60405173ffffffffffffffffffffffffffffffffffffffff8216907fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b90600090a250565b73ffffffffffffffffffffffffffffffffffffffff81166106e5576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f455243313936373a206e65772061646d696e20697320746865207a65726f206160448201527f646472657373000000000000000000000000000000000000000000000000000060648201526084016103a2565b807fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035b80547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff9290921691909117905550565b6060831561075d5750816102b1565b82511561076d5782518084602001fd5b816040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016103a29190610973565b73ffffffffffffffffffffffffffffffffffffffff81163b610845576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602d60248201527f455243313936373a206e657720696d706c656d656e746174696f6e206973206e60448201527f6f74206120636f6e74726163740000000000000000000000000000000000000060648201526084016103a2565b807f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc610708565b803573ffffffffffffffffffffffffffffffffffffffff8116811461089057600080fd5b919050565b6000602082840312156108a757600080fd5b6102b18261086c565b6000806000604084860312156108c557600080fd5b6108ce8461086c565b9250602084013567ffffffffffffffff808211156108eb57600080fd5b818601915086601f8301126108ff57600080fd5b81358181111561090e57600080fd5b87602082850101111561092057600080fd5b6020830194508093505050509250925092565b60005b8381101561094e578181015183820152602001610936565b50506000910152565b60008251610969818460208701610933565b9190910192915050565b6020815260008251806020840152610992816040850160208701610933565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016919091016040019291505056fe416464726573733a206c6f772d6c6576656c2064656c65676174652063616c6c206661696c6564a2646970667358221220e96638b07fb1675d93a95c49e417bc8111448b23a59918698cdcd8fd488dd7cf64736f6c63430008110033", + "devdoc": { + "details": "This contract implements a proxy that is upgradeable by an admin. It is fully forked from OpenZeppelin `TransparentUpgradeableProxy` To avoid https://medium.com/nomic-labs-blog/malicious-backdoors-in-ethereum-proxies-62629adf3357[proxy selector clashing], which can potentially be used in an attack, this contract uses the https://blog.openzeppelin.com/the-transparent-proxy-pattern/[transparent proxy pattern]. This pattern implies two things that go hand in hand: 1. If any account other than the admin calls the proxy, the call will be forwarded to the implementation, even if that call matches one of the admin functions exposed by the proxy itself. 2. If the admin calls the proxy, it can access the admin functions, but its calls will never be forwarded to the implementation. If the admin tries to call a function on the implementation it will fail with an error that says \"admin cannot fallback to proxy target\". These properties mean that the admin account can only be used for admin actions like upgrading the proxy or changing the admin, so it's best if it's a dedicated account that is not used for anything else. This will avoid headaches due to sudden errors when trying to call a function from the proxy implementation. Our recommendation is for the dedicated account to be an instance of the {ProxyAdmin} contract. If set up this way, you should think of the `ProxyAdmin` instance as the real administrative interface of your proxy.", + "kind": "dev", + "methods": { + "admin()": { + "details": "Returns the current admin. NOTE: Only the admin can call this function. See {ProxyAdmin-getProxyAdmin}. TIP: To get this value clients can read directly from the storage slot shown below (specified by EIP1967) using the https://eth.wiki/json-rpc/API#eth_getstorageat[`eth_getStorageAt`] RPC call. `0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103`" + }, + "changeAdmin(address)": { + "details": "Changes the admin of the proxy. Emits an {AdminChanged} event. NOTE: Only the admin can call this function. See {ProxyAdmin-changeProxyAdmin}." + }, + "constructor": { + "details": "Initializes an upgradeable proxy managed by `_admin`, backed by the implementation at `_logic`, and optionally initialized with `_data` as explained in {ERC1967Proxy-constructor}." + }, + "implementation()": { + "details": "Returns the current implementation. NOTE: Only the admin can call this function. See {ProxyAdmin-getProxyImplementation}. TIP: To get this value clients can read directly from the storage slot shown below (specified by EIP1967) using the https://eth.wiki/json-rpc/API#eth_getstorageat[`eth_getStorageAt`] RPC call. `0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc`" + }, + "upgradeTo(address)": { + "details": "Upgrade the implementation of the proxy. NOTE: Only the admin can call this function. See {ProxyAdmin-upgrade}." + }, + "upgradeToAndCall(address,bytes)": { + "details": "Upgrade the implementation of the proxy, and then call a function from the new implementation as specified by `data`, which should be an encoded function call. This is useful to initialize new storage variables in the proxied contract. NOTE: Only the admin can call this function. See {ProxyAdmin-upgradeAndCall}." + } + }, + "version": 1 + }, + "userdoc": { + "kind": "user", + "methods": {}, + "version": 1 + }, + "storageLayout": { + "storage": [], + "types": null + } +} \ No newline at end of file diff --git a/deployments/polygon/LayerZeroBridge_USD.json b/deployments/polygon/LayerZeroBridge_USD.json new file mode 100644 index 00000000..a4e32e41 --- /dev/null +++ b/deployments/polygon/LayerZeroBridge_USD.json @@ -0,0 +1,290 @@ +{ + "address": "0xe70575daaB2B1b3fa9658fa76cC506fcB0007169", + "abi": [ + { + "inputs": [ + { + "internalType": "address", + "name": "_logic", + "type": "address" + }, + { + "internalType": "address", + "name": "admin_", + "type": "address" + }, + { + "internalType": "bytes", + "name": "_data", + "type": "bytes" + } + ], + "stateMutability": "payable", + "type": "constructor" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "previousAdmin", + "type": "address" + }, + { + "indexed": false, + "internalType": "address", + "name": "newAdmin", + "type": "address" + } + ], + "name": "AdminChanged", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "beacon", + "type": "address" + } + ], + "name": "BeaconUpgraded", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "implementation", + "type": "address" + } + ], + "name": "Upgraded", + "type": "event" + }, + { + "stateMutability": "payable", + "type": "fallback" + }, + { + "inputs": [], + "name": "admin", + "outputs": [ + { + "internalType": "address", + "name": "admin_", + "type": "address" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "newAdmin", + "type": "address" + } + ], + "name": "changeAdmin", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "implementation", + "outputs": [ + { + "internalType": "address", + "name": "implementation_", + "type": "address" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "newImplementation", + "type": "address" + } + ], + "name": "upgradeTo", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "newImplementation", + "type": "address" + }, + { + "internalType": "bytes", + "name": "data", + "type": "bytes" + } + ], + "name": "upgradeToAndCall", + "outputs": [], + "stateMutability": "payable", + "type": "function" + }, + { + "stateMutability": "payable", + "type": "receive" + } + ], + "transactionHash": "0xed65135fff52523cb55815996372367f762f0cce3d6247f91e8d3ec09feb255c", + "receipt": { + "to": null, + "from": "0xfdA462548Ce04282f4B6D6619823a7C64Fdc0185", + "contractAddress": "0xe70575daaB2B1b3fa9658fa76cC506fcB0007169", + "transactionIndex": 39, + "gasUsed": "850228", + "logsBloom": "0x08000000000000000000000000000000400000000000000000000000000000400000000000000000000000000000000000008000000000000000000000200000000004000000000000000008000002800000000000400000000100000500040000000000020000020000000000000800000000800080000080000010000000000000000000000000000000008000000000000002000080000000000000800000220000000000000000001000000400000000000000000000000400000000005000000022000000000001000001040000000800000400200000100000000020000010000000000000000000000000000000000000000000000000000000100000", + "blockHash": "0x589b7a35ee2abd0c1cdeed32a567b5e4c10b38ae33fdc12d8221e8b6f6e1c010", + "transactionHash": "0xed65135fff52523cb55815996372367f762f0cce3d6247f91e8d3ec09feb255c", + "logs": [ + { + "transactionIndex": 39, + "blockNumber": 52158260, + "transactionHash": "0xed65135fff52523cb55815996372367f762f0cce3d6247f91e8d3ec09feb255c", + "address": "0xe70575daaB2B1b3fa9658fa76cC506fcB0007169", + "topics": [ + "0xbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b", + "0x000000000000000000000000e59d2c2cfe8459c53917d908177aa25fea5b919b" + ], + "data": "0x", + "logIndex": 154, + "blockHash": "0x589b7a35ee2abd0c1cdeed32a567b5e4c10b38ae33fdc12d8221e8b6f6e1c010" + }, + { + "transactionIndex": 39, + "blockNumber": 52158260, + "transactionHash": "0xed65135fff52523cb55815996372367f762f0cce3d6247f91e8d3ec09feb255c", + "address": "0xe70575daaB2B1b3fa9658fa76cC506fcB0007169", + "topics": [ + "0x8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925", + "0x000000000000000000000000e70575daab2b1b3fa9658fa76cc506fcb0007169", + "0x0000000000000000000000000000206329b97db379d5e1bf586bbdb969c63274" + ], + "data": "0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", + "logIndex": 155, + "blockHash": "0x589b7a35ee2abd0c1cdeed32a567b5e4c10b38ae33fdc12d8221e8b6f6e1c010" + }, + { + "transactionIndex": 39, + "blockNumber": 52158260, + "transactionHash": "0xed65135fff52523cb55815996372367f762f0cce3d6247f91e8d3ec09feb255c", + "address": "0xe70575daaB2B1b3fa9658fa76cC506fcB0007169", + "topics": [ + "0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000206329b97db379d5e1bf586bbdb969c63274" + ], + "data": "0x0000000000000000000000000000000000000000000000000000000000000000", + "logIndex": 156, + "blockHash": "0x589b7a35ee2abd0c1cdeed32a567b5e4c10b38ae33fdc12d8221e8b6f6e1c010" + }, + { + "transactionIndex": 39, + "blockNumber": 52158260, + "transactionHash": "0xed65135fff52523cb55815996372367f762f0cce3d6247f91e8d3ec09feb255c", + "address": "0xe70575daaB2B1b3fa9658fa76cC506fcB0007169", + "topics": [ + "0x7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb3847402498" + ], + "data": "0x0000000000000000000000000000000000000000000000000000000000000001", + "logIndex": 157, + "blockHash": "0x589b7a35ee2abd0c1cdeed32a567b5e4c10b38ae33fdc12d8221e8b6f6e1c010" + }, + { + "transactionIndex": 39, + "blockNumber": 52158260, + "transactionHash": "0xed65135fff52523cb55815996372367f762f0cce3d6247f91e8d3ec09feb255c", + "address": "0xe70575daaB2B1b3fa9658fa76cC506fcB0007169", + "topics": [ + "0x7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f" + ], + "data": "0x0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000bfca293e17e067e8abdca30a5d35addd0cbae6d6", + "logIndex": 158, + "blockHash": "0x589b7a35ee2abd0c1cdeed32a567b5e4c10b38ae33fdc12d8221e8b6f6e1c010" + }, + { + "transactionIndex": 39, + "blockNumber": 52158260, + "transactionHash": "0xed65135fff52523cb55815996372367f762f0cce3d6247f91e8d3ec09feb255c", + "address": "0x0000000000000000000000000000000000001010", + "topics": [ + "0x4dfe1bbbcf077ddc3e01291eea2d5c70c2b422b415d95645b9adcfd678cb1d63", + "0x0000000000000000000000000000000000000000000000000000000000001010", + "0x000000000000000000000000fda462548ce04282f4b6d6619823a7c64fdc0185", + "0x0000000000000000000000007c7379531b2aee82e4ca06d4175d13b9cbeafd49" + ], + "data": "0x0000000000000000000000000000000000000000000000000061afce58456400000000000000000000000000000000000000000000000004005c2f85826e8f5700000000000000000000000000000000000000000002b082339801b49b5bed9f000000000000000000000000000000000000000000000003fffa7fb72a292b5700000000000000000000000000000000000000000002b08233f9b182f3a1519f", + "logIndex": 159, + "blockHash": "0x589b7a35ee2abd0c1cdeed32a567b5e4c10b38ae33fdc12d8221e8b6f6e1c010" + } + ], + "blockNumber": 52158260, + "cumulativeGasUsed": "5948211", + "status": 1, + "byzantium": true + }, + "args": [ + "0xe59D2c2CfE8459c53917D908177aa25fea5B919b", + "0xBFca293e17e067e8aBdca30A5D35ADDd0cBaE6D6", + "0xc9aba0aa00000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000000e00000000000000000000000003c2269811836af69497e5f486a85d7316753cf6200000000000000000000000037ad97c08e3ce8184ad30911bfb0bcee443d5120000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000164c617965725a65726f204272696467652061675553440000000000000000000000000000000000000000000000000000000000000000000000000000000000084c5a2d6167555344000000000000000000000000000000000000000000000000" + ], + "numDeployments": 1, + "solcInputHash": "871924e0c138825a2736b76def8fef8d", + "metadata": "{\"compiler\":{\"version\":\"0.8.17+commit.8df45f5f\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_logic\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"admin_\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"_data\",\"type\":\"bytes\"}],\"stateMutability\":\"payable\",\"type\":\"constructor\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"previousAdmin\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"newAdmin\",\"type\":\"address\"}],\"name\":\"AdminChanged\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"beacon\",\"type\":\"address\"}],\"name\":\"BeaconUpgraded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"implementation\",\"type\":\"address\"}],\"name\":\"Upgraded\",\"type\":\"event\"},{\"stateMutability\":\"payable\",\"type\":\"fallback\"},{\"inputs\":[],\"name\":\"admin\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"admin_\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newAdmin\",\"type\":\"address\"}],\"name\":\"changeAdmin\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"implementation\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"implementation_\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newImplementation\",\"type\":\"address\"}],\"name\":\"upgradeTo\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newImplementation\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"}],\"name\":\"upgradeToAndCall\",\"outputs\":[],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"stateMutability\":\"payable\",\"type\":\"receive\"}],\"devdoc\":{\"details\":\"This contract implements a proxy that is upgradeable by an admin. It is fully forked from OpenZeppelin `TransparentUpgradeableProxy` To avoid https://medium.com/nomic-labs-blog/malicious-backdoors-in-ethereum-proxies-62629adf3357[proxy selector clashing], which can potentially be used in an attack, this contract uses the https://blog.openzeppelin.com/the-transparent-proxy-pattern/[transparent proxy pattern]. This pattern implies two things that go hand in hand: 1. If any account other than the admin calls the proxy, the call will be forwarded to the implementation, even if that call matches one of the admin functions exposed by the proxy itself. 2. If the admin calls the proxy, it can access the admin functions, but its calls will never be forwarded to the implementation. If the admin tries to call a function on the implementation it will fail with an error that says \\\"admin cannot fallback to proxy target\\\". These properties mean that the admin account can only be used for admin actions like upgrading the proxy or changing the admin, so it's best if it's a dedicated account that is not used for anything else. This will avoid headaches due to sudden errors when trying to call a function from the proxy implementation. Our recommendation is for the dedicated account to be an instance of the {ProxyAdmin} contract. If set up this way, you should think of the `ProxyAdmin` instance as the real administrative interface of your proxy.\",\"kind\":\"dev\",\"methods\":{\"admin()\":{\"details\":\"Returns the current admin. NOTE: Only the admin can call this function. See {ProxyAdmin-getProxyAdmin}. TIP: To get this value clients can read directly from the storage slot shown below (specified by EIP1967) using the https://eth.wiki/json-rpc/API#eth_getstorageat[`eth_getStorageAt`] RPC call. `0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103`\"},\"changeAdmin(address)\":{\"details\":\"Changes the admin of the proxy. Emits an {AdminChanged} event. NOTE: Only the admin can call this function. See {ProxyAdmin-changeProxyAdmin}.\"},\"constructor\":{\"details\":\"Initializes an upgradeable proxy managed by `_admin`, backed by the implementation at `_logic`, and optionally initialized with `_data` as explained in {ERC1967Proxy-constructor}.\"},\"implementation()\":{\"details\":\"Returns the current implementation. NOTE: Only the admin can call this function. See {ProxyAdmin-getProxyImplementation}. TIP: To get this value clients can read directly from the storage slot shown below (specified by EIP1967) using the https://eth.wiki/json-rpc/API#eth_getstorageat[`eth_getStorageAt`] RPC call. `0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc`\"},\"upgradeTo(address)\":{\"details\":\"Upgrade the implementation of the proxy. NOTE: Only the admin can call this function. See {ProxyAdmin-upgrade}.\"},\"upgradeToAndCall(address,bytes)\":{\"details\":\"Upgrade the implementation of the proxy, and then call a function from the new implementation as specified by `data`, which should be an encoded function call. This is useful to initialize new storage variables in the proxied contract. NOTE: Only the admin can call this function. See {ProxyAdmin-upgradeAndCall}.\"}},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/external/TransparentUpgradeableProxy.sol\":\"TransparentUpgradeableProxy\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":1000000},\"remappings\":[]},\"sources\":{\"@openzeppelin/contracts/interfaces/draft-IERC1822.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.5.0) (interfaces/draft-IERC1822.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev ERC1822: Universal Upgradeable Proxy Standard (UUPS) documents a method for upgradeability through a simplified\\n * proxy whose upgrades are fully controlled by the current implementation.\\n */\\ninterface IERC1822Proxiable {\\n /**\\n * @dev Returns the storage slot that the proxiable contract assumes is being used to store the implementation\\n * address.\\n *\\n * IMPORTANT: A proxy pointing at a proxiable contract should not be considered proxiable itself, because this risks\\n * bricking a proxy that upgrades to it, by delegating to itself until out of gas. Thus it is critical that this\\n * function revert if invoked through a proxy.\\n */\\n function proxiableUUID() external view returns (bytes32);\\n}\\n\",\"keccak256\":\"0x1d4afe6cb24200cc4545eed814ecf5847277dfe5d613a1707aad5fceecebcfff\",\"license\":\"MIT\"},\"@openzeppelin/contracts/proxy/ERC1967/ERC1967Proxy.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.7.0) (proxy/ERC1967/ERC1967Proxy.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../Proxy.sol\\\";\\nimport \\\"./ERC1967Upgrade.sol\\\";\\n\\n/**\\n * @dev This contract implements an upgradeable proxy. It is upgradeable because calls are delegated to an\\n * implementation address that can be changed. This address is stored in storage in the location specified by\\n * https://eips.ethereum.org/EIPS/eip-1967[EIP1967], so that it doesn't conflict with the storage layout of the\\n * implementation behind the proxy.\\n */\\ncontract ERC1967Proxy is Proxy, ERC1967Upgrade {\\n /**\\n * @dev Initializes the upgradeable proxy with an initial implementation specified by `_logic`.\\n *\\n * If `_data` is nonempty, it's used as data in a delegate call to `_logic`. This will typically be an encoded\\n * function call, and allows initializing the storage of the proxy like a Solidity constructor.\\n */\\n constructor(address _logic, bytes memory _data) payable {\\n _upgradeToAndCall(_logic, _data, false);\\n }\\n\\n /**\\n * @dev Returns the current implementation address.\\n */\\n function _implementation() internal view virtual override returns (address impl) {\\n return ERC1967Upgrade._getImplementation();\\n }\\n}\\n\",\"keccak256\":\"0xa2b22da3032e50b55f95ec1d13336102d675f341167aa76db571ef7f8bb7975d\",\"license\":\"MIT\"},\"@openzeppelin/contracts/proxy/ERC1967/ERC1967Upgrade.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.5.0) (proxy/ERC1967/ERC1967Upgrade.sol)\\n\\npragma solidity ^0.8.2;\\n\\nimport \\\"../beacon/IBeacon.sol\\\";\\nimport \\\"../../interfaces/draft-IERC1822.sol\\\";\\nimport \\\"../../utils/Address.sol\\\";\\nimport \\\"../../utils/StorageSlot.sol\\\";\\n\\n/**\\n * @dev This abstract contract provides getters and event emitting update functions for\\n * https://eips.ethereum.org/EIPS/eip-1967[EIP1967] slots.\\n *\\n * _Available since v4.1._\\n *\\n * @custom:oz-upgrades-unsafe-allow delegatecall\\n */\\nabstract contract ERC1967Upgrade {\\n // This is the keccak-256 hash of \\\"eip1967.proxy.rollback\\\" subtracted by 1\\n bytes32 private constant _ROLLBACK_SLOT = 0x4910fdfa16fed3260ed0e7147f7cc6da11a60208b5b9406d12a635614ffd9143;\\n\\n /**\\n * @dev Storage slot with the address of the current implementation.\\n * This is the keccak-256 hash of \\\"eip1967.proxy.implementation\\\" subtracted by 1, and is\\n * validated in the constructor.\\n */\\n bytes32 internal constant _IMPLEMENTATION_SLOT = 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc;\\n\\n /**\\n * @dev Emitted when the implementation is upgraded.\\n */\\n event Upgraded(address indexed implementation);\\n\\n /**\\n * @dev Returns the current implementation address.\\n */\\n function _getImplementation() internal view returns (address) {\\n return StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value;\\n }\\n\\n /**\\n * @dev Stores a new address in the EIP1967 implementation slot.\\n */\\n function _setImplementation(address newImplementation) private {\\n require(Address.isContract(newImplementation), \\\"ERC1967: new implementation is not a contract\\\");\\n StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value = newImplementation;\\n }\\n\\n /**\\n * @dev Perform implementation upgrade\\n *\\n * Emits an {Upgraded} event.\\n */\\n function _upgradeTo(address newImplementation) internal {\\n _setImplementation(newImplementation);\\n emit Upgraded(newImplementation);\\n }\\n\\n /**\\n * @dev Perform implementation upgrade with additional setup call.\\n *\\n * Emits an {Upgraded} event.\\n */\\n function _upgradeToAndCall(\\n address newImplementation,\\n bytes memory data,\\n bool forceCall\\n ) internal {\\n _upgradeTo(newImplementation);\\n if (data.length > 0 || forceCall) {\\n Address.functionDelegateCall(newImplementation, data);\\n }\\n }\\n\\n /**\\n * @dev Perform implementation upgrade with security checks for UUPS proxies, and additional setup call.\\n *\\n * Emits an {Upgraded} event.\\n */\\n function _upgradeToAndCallUUPS(\\n address newImplementation,\\n bytes memory data,\\n bool forceCall\\n ) internal {\\n // Upgrades from old implementations will perform a rollback test. This test requires the new\\n // implementation to upgrade back to the old, non-ERC1822 compliant, implementation. Removing\\n // this special case will break upgrade paths from old UUPS implementation to new ones.\\n if (StorageSlot.getBooleanSlot(_ROLLBACK_SLOT).value) {\\n _setImplementation(newImplementation);\\n } else {\\n try IERC1822Proxiable(newImplementation).proxiableUUID() returns (bytes32 slot) {\\n require(slot == _IMPLEMENTATION_SLOT, \\\"ERC1967Upgrade: unsupported proxiableUUID\\\");\\n } catch {\\n revert(\\\"ERC1967Upgrade: new implementation is not UUPS\\\");\\n }\\n _upgradeToAndCall(newImplementation, data, forceCall);\\n }\\n }\\n\\n /**\\n * @dev Storage slot with the admin of the contract.\\n * This is the keccak-256 hash of \\\"eip1967.proxy.admin\\\" subtracted by 1, and is\\n * validated in the constructor.\\n */\\n bytes32 internal constant _ADMIN_SLOT = 0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103;\\n\\n /**\\n * @dev Emitted when the admin account has changed.\\n */\\n event AdminChanged(address previousAdmin, address newAdmin);\\n\\n /**\\n * @dev Returns the current admin.\\n */\\n function _getAdmin() internal view returns (address) {\\n return StorageSlot.getAddressSlot(_ADMIN_SLOT).value;\\n }\\n\\n /**\\n * @dev Stores a new address in the EIP1967 admin slot.\\n */\\n function _setAdmin(address newAdmin) private {\\n require(newAdmin != address(0), \\\"ERC1967: new admin is the zero address\\\");\\n StorageSlot.getAddressSlot(_ADMIN_SLOT).value = newAdmin;\\n }\\n\\n /**\\n * @dev Changes the admin of the proxy.\\n *\\n * Emits an {AdminChanged} event.\\n */\\n function _changeAdmin(address newAdmin) internal {\\n emit AdminChanged(_getAdmin(), newAdmin);\\n _setAdmin(newAdmin);\\n }\\n\\n /**\\n * @dev The storage slot of the UpgradeableBeacon contract which defines the implementation for this proxy.\\n * This is bytes32(uint256(keccak256('eip1967.proxy.beacon')) - 1)) and is validated in the constructor.\\n */\\n bytes32 internal constant _BEACON_SLOT = 0xa3f0ad74e5423aebfd80d3ef4346578335a9a72aeaee59ff6cb3582b35133d50;\\n\\n /**\\n * @dev Emitted when the beacon is upgraded.\\n */\\n event BeaconUpgraded(address indexed beacon);\\n\\n /**\\n * @dev Returns the current beacon.\\n */\\n function _getBeacon() internal view returns (address) {\\n return StorageSlot.getAddressSlot(_BEACON_SLOT).value;\\n }\\n\\n /**\\n * @dev Stores a new beacon in the EIP1967 beacon slot.\\n */\\n function _setBeacon(address newBeacon) private {\\n require(Address.isContract(newBeacon), \\\"ERC1967: new beacon is not a contract\\\");\\n require(\\n Address.isContract(IBeacon(newBeacon).implementation()),\\n \\\"ERC1967: beacon implementation is not a contract\\\"\\n );\\n StorageSlot.getAddressSlot(_BEACON_SLOT).value = newBeacon;\\n }\\n\\n /**\\n * @dev Perform beacon upgrade with additional setup call. Note: This upgrades the address of the beacon, it does\\n * not upgrade the implementation contained in the beacon (see {UpgradeableBeacon-_setImplementation} for that).\\n *\\n * Emits a {BeaconUpgraded} event.\\n */\\n function _upgradeBeaconToAndCall(\\n address newBeacon,\\n bytes memory data,\\n bool forceCall\\n ) internal {\\n _setBeacon(newBeacon);\\n emit BeaconUpgraded(newBeacon);\\n if (data.length > 0 || forceCall) {\\n Address.functionDelegateCall(IBeacon(newBeacon).implementation(), data);\\n }\\n }\\n}\\n\",\"keccak256\":\"0xabf3f59bc0e5423eae45e459dbe92e7052c6983628d39008590edc852a62f94a\",\"license\":\"MIT\"},\"@openzeppelin/contracts/proxy/Proxy.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.6.0) (proxy/Proxy.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev This abstract contract provides a fallback function that delegates all calls to another contract using the EVM\\n * instruction `delegatecall`. We refer to the second contract as the _implementation_ behind the proxy, and it has to\\n * be specified by overriding the virtual {_implementation} function.\\n *\\n * Additionally, delegation to the implementation can be triggered manually through the {_fallback} function, or to a\\n * different contract through the {_delegate} function.\\n *\\n * The success and return data of the delegated call will be returned back to the caller of the proxy.\\n */\\nabstract contract Proxy {\\n /**\\n * @dev Delegates the current call to `implementation`.\\n *\\n * This function does not return to its internal call site, it will return directly to the external caller.\\n */\\n function _delegate(address implementation) internal virtual {\\n assembly {\\n // Copy msg.data. We take full control of memory in this inline assembly\\n // block because it will not return to Solidity code. We overwrite the\\n // Solidity scratch pad at memory position 0.\\n calldatacopy(0, 0, calldatasize())\\n\\n // Call the implementation.\\n // out and outsize are 0 because we don't know the size yet.\\n let result := delegatecall(gas(), implementation, 0, calldatasize(), 0, 0)\\n\\n // Copy the returned data.\\n returndatacopy(0, 0, returndatasize())\\n\\n switch result\\n // delegatecall returns 0 on error.\\n case 0 {\\n revert(0, returndatasize())\\n }\\n default {\\n return(0, returndatasize())\\n }\\n }\\n }\\n\\n /**\\n * @dev This is a virtual function that should be overridden so it returns the address to which the fallback function\\n * and {_fallback} should delegate.\\n */\\n function _implementation() internal view virtual returns (address);\\n\\n /**\\n * @dev Delegates the current call to the address returned by `_implementation()`.\\n *\\n * This function does not return to its internal call site, it will return directly to the external caller.\\n */\\n function _fallback() internal virtual {\\n _beforeFallback();\\n _delegate(_implementation());\\n }\\n\\n /**\\n * @dev Fallback function that delegates calls to the address returned by `_implementation()`. Will run if no other\\n * function in the contract matches the call data.\\n */\\n fallback() external payable virtual {\\n _fallback();\\n }\\n\\n /**\\n * @dev Fallback function that delegates calls to the address returned by `_implementation()`. Will run if call data\\n * is empty.\\n */\\n receive() external payable virtual {\\n _fallback();\\n }\\n\\n /**\\n * @dev Hook that is called before falling back to the implementation. Can happen as part of a manual `_fallback`\\n * call, or as part of the Solidity `fallback` or `receive` functions.\\n *\\n * If overridden should call `super._beforeFallback()`.\\n */\\n function _beforeFallback() internal virtual {}\\n}\\n\",\"keccak256\":\"0xc130fe33f1b2132158531a87734153293f6d07bc263ff4ac90e85da9c82c0e27\",\"license\":\"MIT\"},\"@openzeppelin/contracts/proxy/beacon/IBeacon.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (proxy/beacon/IBeacon.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev This is the interface that {BeaconProxy} expects of its beacon.\\n */\\ninterface IBeacon {\\n /**\\n * @dev Must return an address that can be used as a delegate call target.\\n *\\n * {BeaconProxy} will check that this address is a contract.\\n */\\n function implementation() external view returns (address);\\n}\\n\",\"keccak256\":\"0xd50a3421ac379ccb1be435fa646d66a65c986b4924f0849839f08692f39dde61\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/Address.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.7.0) (utils/Address.sol)\\n\\npragma solidity ^0.8.1;\\n\\n/**\\n * @dev Collection of functions related to the address type\\n */\\nlibrary Address {\\n /**\\n * @dev Returns true if `account` is a contract.\\n *\\n * [IMPORTANT]\\n * ====\\n * It is unsafe to assume that an address for which this function returns\\n * false is an externally-owned account (EOA) and not a contract.\\n *\\n * Among others, `isContract` will return false for the following\\n * types of addresses:\\n *\\n * - an externally-owned account\\n * - a contract in construction\\n * - an address where a contract will be created\\n * - an address where a contract lived, but was destroyed\\n * ====\\n *\\n * [IMPORTANT]\\n * ====\\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\\n *\\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\\n * constructor.\\n * ====\\n */\\n function isContract(address account) internal view returns (bool) {\\n // This method relies on extcodesize/address.code.length, which returns 0\\n // for contracts in construction, since the code is only stored at the end\\n // of the constructor execution.\\n\\n return account.code.length > 0;\\n }\\n\\n /**\\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\\n * `recipient`, forwarding all available gas and reverting on errors.\\n *\\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\\n * imposed by `transfer`, making them unable to receive funds via\\n * `transfer`. {sendValue} removes this limitation.\\n *\\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\\n *\\n * IMPORTANT: because control is transferred to `recipient`, care must be\\n * taken to not create reentrancy vulnerabilities. Consider using\\n * {ReentrancyGuard} or the\\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\\n */\\n function sendValue(address payable recipient, uint256 amount) internal {\\n require(address(this).balance >= amount, \\\"Address: insufficient balance\\\");\\n\\n (bool success, ) = recipient.call{value: amount}(\\\"\\\");\\n require(success, \\\"Address: unable to send value, recipient may have reverted\\\");\\n }\\n\\n /**\\n * @dev Performs a Solidity function call using a low level `call`. A\\n * plain `call` is an unsafe replacement for a function call: use this\\n * function instead.\\n *\\n * If `target` reverts with a revert reason, it is bubbled up by this\\n * function (like regular Solidity function calls).\\n *\\n * Returns the raw returned data. To convert to the expected return value,\\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\\n *\\n * Requirements:\\n *\\n * - `target` must be a contract.\\n * - calling `target` with `data` must not revert.\\n *\\n * _Available since v3.1._\\n */\\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\\n return functionCall(target, data, \\\"Address: low-level call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\\n * `errorMessage` as a fallback revert reason when `target` reverts.\\n *\\n * _Available since v3.1._\\n */\\n function functionCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n return functionCallWithValue(target, data, 0, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but also transferring `value` wei to `target`.\\n *\\n * Requirements:\\n *\\n * - the calling contract must have an ETH balance of at least `value`.\\n * - the called Solidity function must be `payable`.\\n *\\n * _Available since v3.1._\\n */\\n function functionCallWithValue(\\n address target,\\n bytes memory data,\\n uint256 value\\n ) internal returns (bytes memory) {\\n return functionCallWithValue(target, data, value, \\\"Address: low-level call with value failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\\n * with `errorMessage` as a fallback revert reason when `target` reverts.\\n *\\n * _Available since v3.1._\\n */\\n function functionCallWithValue(\\n address target,\\n bytes memory data,\\n uint256 value,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n require(address(this).balance >= value, \\\"Address: insufficient balance for call\\\");\\n require(isContract(target), \\\"Address: call to non-contract\\\");\\n\\n (bool success, bytes memory returndata) = target.call{value: value}(data);\\n return verifyCallResult(success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but performing a static call.\\n *\\n * _Available since v3.3._\\n */\\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\\n return functionStaticCall(target, data, \\\"Address: low-level static call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\\n * but performing a static call.\\n *\\n * _Available since v3.3._\\n */\\n function functionStaticCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal view returns (bytes memory) {\\n require(isContract(target), \\\"Address: static call to non-contract\\\");\\n\\n (bool success, bytes memory returndata) = target.staticcall(data);\\n return verifyCallResult(success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but performing a delegate call.\\n *\\n * _Available since v3.4._\\n */\\n function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {\\n return functionDelegateCall(target, data, \\\"Address: low-level delegate call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\\n * but performing a delegate call.\\n *\\n * _Available since v3.4._\\n */\\n function functionDelegateCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n require(isContract(target), \\\"Address: delegate call to non-contract\\\");\\n\\n (bool success, bytes memory returndata) = target.delegatecall(data);\\n return verifyCallResult(success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the\\n * revert reason using the provided one.\\n *\\n * _Available since v4.3._\\n */\\n function verifyCallResult(\\n bool success,\\n bytes memory returndata,\\n string memory errorMessage\\n ) internal pure returns (bytes memory) {\\n if (success) {\\n return returndata;\\n } else {\\n // Look for revert reason and bubble it up if present\\n if (returndata.length > 0) {\\n // The easiest way to bubble the revert reason is using memory via assembly\\n /// @solidity memory-safe-assembly\\n assembly {\\n let returndata_size := mload(returndata)\\n revert(add(32, returndata), returndata_size)\\n }\\n } else {\\n revert(errorMessage);\\n }\\n }\\n }\\n}\\n\",\"keccak256\":\"0xd6153ce99bcdcce22b124f755e72553295be6abcd63804cfdffceb188b8bef10\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/StorageSlot.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.7.0) (utils/StorageSlot.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Library for reading and writing primitive types to specific storage slots.\\n *\\n * Storage slots are often used to avoid storage conflict when dealing with upgradeable contracts.\\n * This library helps with reading and writing to such slots without the need for inline assembly.\\n *\\n * The functions in this library return Slot structs that contain a `value` member that can be used to read or write.\\n *\\n * Example usage to set ERC1967 implementation slot:\\n * ```\\n * contract ERC1967 {\\n * bytes32 internal constant _IMPLEMENTATION_SLOT = 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc;\\n *\\n * function _getImplementation() internal view returns (address) {\\n * return StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value;\\n * }\\n *\\n * function _setImplementation(address newImplementation) internal {\\n * require(Address.isContract(newImplementation), \\\"ERC1967: new implementation is not a contract\\\");\\n * StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value = newImplementation;\\n * }\\n * }\\n * ```\\n *\\n * _Available since v4.1 for `address`, `bool`, `bytes32`, and `uint256`._\\n */\\nlibrary StorageSlot {\\n struct AddressSlot {\\n address value;\\n }\\n\\n struct BooleanSlot {\\n bool value;\\n }\\n\\n struct Bytes32Slot {\\n bytes32 value;\\n }\\n\\n struct Uint256Slot {\\n uint256 value;\\n }\\n\\n /**\\n * @dev Returns an `AddressSlot` with member `value` located at `slot`.\\n */\\n function getAddressSlot(bytes32 slot) internal pure returns (AddressSlot storage r) {\\n /// @solidity memory-safe-assembly\\n assembly {\\n r.slot := slot\\n }\\n }\\n\\n /**\\n * @dev Returns an `BooleanSlot` with member `value` located at `slot`.\\n */\\n function getBooleanSlot(bytes32 slot) internal pure returns (BooleanSlot storage r) {\\n /// @solidity memory-safe-assembly\\n assembly {\\n r.slot := slot\\n }\\n }\\n\\n /**\\n * @dev Returns an `Bytes32Slot` with member `value` located at `slot`.\\n */\\n function getBytes32Slot(bytes32 slot) internal pure returns (Bytes32Slot storage r) {\\n /// @solidity memory-safe-assembly\\n assembly {\\n r.slot := slot\\n }\\n }\\n\\n /**\\n * @dev Returns an `Uint256Slot` with member `value` located at `slot`.\\n */\\n function getUint256Slot(bytes32 slot) internal pure returns (Uint256Slot storage r) {\\n /// @solidity memory-safe-assembly\\n assembly {\\n r.slot := slot\\n }\\n }\\n}\\n\",\"keccak256\":\"0xd5c50c54bf02740ebd122ff06832546cb5fa84486d52695a9ccfd11666e0c81d\",\"license\":\"MIT\"},\"contracts/external/TransparentUpgradeableProxy.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-3.0\\n\\npragma solidity ^0.8.12;\\n\\nimport \\\"@openzeppelin/contracts/proxy/ERC1967/ERC1967Proxy.sol\\\";\\n\\n/**\\n * @dev This contract implements a proxy that is upgradeable by an admin. It is fully forked from OpenZeppelin\\n * `TransparentUpgradeableProxy`\\n *\\n * To avoid https://medium.com/nomic-labs-blog/malicious-backdoors-in-ethereum-proxies-62629adf3357[proxy selector\\n * clashing], which can potentially be used in an attack, this contract uses the\\n * https://blog.openzeppelin.com/the-transparent-proxy-pattern/[transparent proxy pattern]. This pattern implies two\\n * things that go hand in hand:\\n *\\n * 1. If any account other than the admin calls the proxy, the call will be forwarded to the implementation, even if\\n * that call matches one of the admin functions exposed by the proxy itself.\\n * 2. If the admin calls the proxy, it can access the admin functions, but its calls will never be forwarded to the\\n * implementation. If the admin tries to call a function on the implementation it will fail with an error that says\\n * \\\"admin cannot fallback to proxy target\\\".\\n *\\n * These properties mean that the admin account can only be used for admin actions like upgrading the proxy or changing\\n * the admin, so it's best if it's a dedicated account that is not used for anything else. This will avoid headaches due\\n * to sudden errors when trying to call a function from the proxy implementation.\\n *\\n * Our recommendation is for the dedicated account to be an instance of the {ProxyAdmin} contract. If set up this way,\\n * you should think of the `ProxyAdmin` instance as the real administrative interface of your proxy.\\n */\\ncontract TransparentUpgradeableProxy is ERC1967Proxy {\\n /**\\n * @dev Initializes an upgradeable proxy managed by `_admin`, backed by the implementation at `_logic`, and\\n * optionally initialized with `_data` as explained in {ERC1967Proxy-constructor}.\\n */\\n constructor(address _logic, address admin_, bytes memory _data) payable ERC1967Proxy(_logic, _data) {\\n assert(_ADMIN_SLOT == bytes32(uint256(keccak256(\\\"eip1967.proxy.admin\\\")) - 1));\\n _changeAdmin(admin_);\\n }\\n\\n /**\\n * @dev Modifier used internally that will delegate the call to the implementation unless the sender is the admin.\\n */\\n modifier ifAdmin() {\\n if (msg.sender == _getAdmin()) {\\n _;\\n } else {\\n _fallback();\\n }\\n }\\n\\n /**\\n * @dev Returns the current admin.\\n *\\n * NOTE: Only the admin can call this function. See {ProxyAdmin-getProxyAdmin}.\\n *\\n * TIP: To get this value clients can read directly from the storage slot shown below (specified by EIP1967) using the\\n * https://eth.wiki/json-rpc/API#eth_getstorageat[`eth_getStorageAt`] RPC call.\\n * `0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103`\\n */\\n function admin() external ifAdmin returns (address admin_) {\\n admin_ = _getAdmin();\\n }\\n\\n /**\\n * @dev Returns the current implementation.\\n *\\n * NOTE: Only the admin can call this function. See {ProxyAdmin-getProxyImplementation}.\\n *\\n * TIP: To get this value clients can read directly from the storage slot shown below (specified by EIP1967) using the\\n * https://eth.wiki/json-rpc/API#eth_getstorageat[`eth_getStorageAt`] RPC call.\\n * `0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc`\\n */\\n function implementation() external ifAdmin returns (address implementation_) {\\n implementation_ = _implementation();\\n }\\n\\n /**\\n * @dev Changes the admin of the proxy.\\n *\\n * Emits an {AdminChanged} event.\\n *\\n * NOTE: Only the admin can call this function. See {ProxyAdmin-changeProxyAdmin}.\\n */\\n function changeAdmin(address newAdmin) external virtual ifAdmin {\\n _changeAdmin(newAdmin);\\n }\\n\\n /**\\n * @dev Upgrade the implementation of the proxy.\\n *\\n * NOTE: Only the admin can call this function. See {ProxyAdmin-upgrade}.\\n */\\n function upgradeTo(address newImplementation) external ifAdmin {\\n _upgradeToAndCall(newImplementation, bytes(\\\"\\\"), false);\\n }\\n\\n /**\\n * @dev Upgrade the implementation of the proxy, and then call a function from the new implementation as specified\\n * by `data`, which should be an encoded function call. This is useful to initialize new storage variables in the\\n * proxied contract.\\n *\\n * NOTE: Only the admin can call this function. See {ProxyAdmin-upgradeAndCall}.\\n */\\n function upgradeToAndCall(address newImplementation, bytes calldata data) external payable ifAdmin {\\n _upgradeToAndCall(newImplementation, data, true);\\n }\\n\\n /**\\n * @dev Returns the current admin.\\n */\\n function _admin() internal view virtual returns (address) {\\n return _getAdmin();\\n }\\n\\n /**\\n * @dev Makes sure the admin cannot access the fallback function. See {Proxy-_beforeFallback}.\\n */\\n function _beforeFallback() internal virtual override {\\n require(msg.sender != _getAdmin(), \\\"TransparentUpgradeableProxy: admin cannot fallback to proxy target\\\");\\n super._beforeFallback();\\n }\\n}\\n\",\"keccak256\":\"0x93a67a0f612ea3ff2a76315e138a6a88267270a1379d3cc7be52845fbbe611e2\",\"license\":\"GPL-3.0\"}},\"version\":1}", + "bytecode": "0x6080604052604051620010bb380380620010bb8339810160408190526200002691620004d8565b828162000036828260006200009a565b5062000066905060017fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6104620005b8565b6000805160206200107483398151915214620000865762000086620005da565b6200009182620000d7565b50505062000643565b620000a58362000132565b600082511180620000b35750805b15620000d257620000d083836200017460201b6200028c1760201c565b505b505050565b7f7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f62000102620001a5565b604080516001600160a01b03928316815291841660208301520160405180910390a16200012f81620001de565b50565b6200013d8162000293565b6040516001600160a01b038216907fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b90600090a250565b60606200019c8383604051806060016040528060278152602001620010946027913962000347565b90505b92915050565b6000620001cf6000805160206200107483398151915260001b6200042f60201b6200022e1760201c565b546001600160a01b0316919050565b6001600160a01b038116620002495760405162461bcd60e51b815260206004820152602660248201527f455243313936373a206e65772061646d696e20697320746865207a65726f206160448201526564647265737360d01b60648201526084015b60405180910390fd5b80620002726000805160206200107483398151915260001b6200042f60201b6200022e1760201c565b80546001600160a01b0319166001600160a01b039290921691909117905550565b620002a9816200043260201b620002b81760201c565b6200030d5760405162461bcd60e51b815260206004820152602d60248201527f455243313936373a206e657720696d706c656d656e746174696f6e206973206e60448201526c1bdd08184818dbdb9d1c9858dd609a1b606482015260840162000240565b80620002727f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc60001b6200042f60201b6200022e1760201c565b60606001600160a01b0384163b620003b15760405162461bcd60e51b815260206004820152602660248201527f416464726573733a2064656c65676174652063616c6c20746f206e6f6e2d636f6044820152651b9d1c9858dd60d21b606482015260840162000240565b600080856001600160a01b031685604051620003ce9190620005f0565b600060405180830381855af49150503d80600081146200040b576040519150601f19603f3d011682016040523d82523d6000602084013e62000410565b606091505b5090925090506200042382828662000441565b925050505b9392505050565b90565b6001600160a01b03163b151590565b606083156200045257508162000428565b825115620004635782518084602001fd5b8160405162461bcd60e51b81526004016200024091906200060e565b80516001600160a01b03811681146200049757600080fd5b919050565b634e487b7160e01b600052604160045260246000fd5b60005b83811015620004cf578181015183820152602001620004b5565b50506000910152565b600080600060608486031215620004ee57600080fd5b620004f9846200047f565b925062000509602085016200047f565b60408501519092506001600160401b03808211156200052757600080fd5b818601915086601f8301126200053c57600080fd5b8151818111156200055157620005516200049c565b604051601f8201601f19908116603f011681019083821181831017156200057c576200057c6200049c565b816040528281528960208487010111156200059657600080fd5b620005a9836020830160208801620004b2565b80955050505050509250925092565b818103818111156200019f57634e487b7160e01b600052601160045260246000fd5b634e487b7160e01b600052600160045260246000fd5b6000825162000604818460208701620004b2565b9190910192915050565b60208152600082518060208401526200062f816040850160208701620004b2565b601f01601f19169190910160400192915050565b610a2180620006536000396000f3fe60806040526004361061005e5760003560e01c80635c60da1b116100435780635c60da1b146100a85780638f283970146100e6578063f851a440146101065761006d565b80633659cfe6146100755780634f1ef286146100955761006d565b3661006d5761006b61011b565b005b61006b61011b565b34801561008157600080fd5b5061006b610090366004610895565b610135565b61006b6100a33660046108b0565b61017f565b3480156100b457600080fd5b506100bd6101f3565b60405173ffffffffffffffffffffffffffffffffffffffff909116815260200160405180910390f35b3480156100f257600080fd5b5061006b610101366004610895565b610231565b34801561011257600080fd5b506100bd61025e565b6101236102d4565b61013361012e6103ab565b6103b5565b565b61013d6103d9565b73ffffffffffffffffffffffffffffffffffffffff1633036101775761017481604051806020016040528060008152506000610419565b50565b61017461011b565b6101876103d9565b73ffffffffffffffffffffffffffffffffffffffff1633036101eb576101e68383838080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525060019250610419915050565b505050565b6101e661011b565b60006101fd6103d9565b73ffffffffffffffffffffffffffffffffffffffff163303610226576102216103ab565b905090565b61022e61011b565b90565b6102396103d9565b73ffffffffffffffffffffffffffffffffffffffff1633036101775761017481610444565b60006102686103d9565b73ffffffffffffffffffffffffffffffffffffffff163303610226576102216103d9565b60606102b183836040518060600160405280602781526020016109c5602791396104a5565b9392505050565b73ffffffffffffffffffffffffffffffffffffffff163b151590565b6102dc6103d9565b73ffffffffffffffffffffffffffffffffffffffff163303610133576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604260248201527f5472616e73706172656e745570677261646561626c6550726f78793a2061646d60448201527f696e2063616e6e6f742066616c6c6261636b20746f2070726f7879207461726760648201527f6574000000000000000000000000000000000000000000000000000000000000608482015260a4015b60405180910390fd5b60006102216105cd565b3660008037600080366000845af43d6000803e8080156103d4573d6000f35b3d6000fd5b60007fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035b5473ffffffffffffffffffffffffffffffffffffffff16919050565b610422836105f5565b60008251118061042f5750805b156101e65761043e838361028c565b50505050565b7f7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f61046d6103d9565b6040805173ffffffffffffffffffffffffffffffffffffffff928316815291841660208301520160405180910390a161017481610642565b606073ffffffffffffffffffffffffffffffffffffffff84163b61054b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f416464726573733a2064656c65676174652063616c6c20746f206e6f6e2d636f60448201527f6e7472616374000000000000000000000000000000000000000000000000000060648201526084016103a2565b6000808573ffffffffffffffffffffffffffffffffffffffff16856040516105739190610957565b600060405180830381855af49150503d80600081146105ae576040519150601f19603f3d011682016040523d82523d6000602084013e6105b3565b606091505b50915091506105c382828661074e565b9695505050505050565b60007f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc6103fd565b6105fe816107a1565b60405173ffffffffffffffffffffffffffffffffffffffff8216907fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b90600090a250565b73ffffffffffffffffffffffffffffffffffffffff81166106e5576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f455243313936373a206e65772061646d696e20697320746865207a65726f206160448201527f646472657373000000000000000000000000000000000000000000000000000060648201526084016103a2565b807fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035b80547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff9290921691909117905550565b6060831561075d5750816102b1565b82511561076d5782518084602001fd5b816040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016103a29190610973565b73ffffffffffffffffffffffffffffffffffffffff81163b610845576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602d60248201527f455243313936373a206e657720696d706c656d656e746174696f6e206973206e60448201527f6f74206120636f6e74726163740000000000000000000000000000000000000060648201526084016103a2565b807f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc610708565b803573ffffffffffffffffffffffffffffffffffffffff8116811461089057600080fd5b919050565b6000602082840312156108a757600080fd5b6102b18261086c565b6000806000604084860312156108c557600080fd5b6108ce8461086c565b9250602084013567ffffffffffffffff808211156108eb57600080fd5b818601915086601f8301126108ff57600080fd5b81358181111561090e57600080fd5b87602082850101111561092057600080fd5b6020830194508093505050509250925092565b60005b8381101561094e578181015183820152602001610936565b50506000910152565b60008251610969818460208701610933565b9190910192915050565b6020815260008251806020840152610992816040850160208701610933565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016919091016040019291505056fe416464726573733a206c6f772d6c6576656c2064656c65676174652063616c6c206661696c6564a2646970667358221220e96638b07fb1675d93a95c49e417bc8111448b23a59918698cdcd8fd488dd7cf64736f6c63430008110033b53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103416464726573733a206c6f772d6c6576656c2064656c65676174652063616c6c206661696c6564", + "deployedBytecode": "0x60806040526004361061005e5760003560e01c80635c60da1b116100435780635c60da1b146100a85780638f283970146100e6578063f851a440146101065761006d565b80633659cfe6146100755780634f1ef286146100955761006d565b3661006d5761006b61011b565b005b61006b61011b565b34801561008157600080fd5b5061006b610090366004610895565b610135565b61006b6100a33660046108b0565b61017f565b3480156100b457600080fd5b506100bd6101f3565b60405173ffffffffffffffffffffffffffffffffffffffff909116815260200160405180910390f35b3480156100f257600080fd5b5061006b610101366004610895565b610231565b34801561011257600080fd5b506100bd61025e565b6101236102d4565b61013361012e6103ab565b6103b5565b565b61013d6103d9565b73ffffffffffffffffffffffffffffffffffffffff1633036101775761017481604051806020016040528060008152506000610419565b50565b61017461011b565b6101876103d9565b73ffffffffffffffffffffffffffffffffffffffff1633036101eb576101e68383838080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525060019250610419915050565b505050565b6101e661011b565b60006101fd6103d9565b73ffffffffffffffffffffffffffffffffffffffff163303610226576102216103ab565b905090565b61022e61011b565b90565b6102396103d9565b73ffffffffffffffffffffffffffffffffffffffff1633036101775761017481610444565b60006102686103d9565b73ffffffffffffffffffffffffffffffffffffffff163303610226576102216103d9565b60606102b183836040518060600160405280602781526020016109c5602791396104a5565b9392505050565b73ffffffffffffffffffffffffffffffffffffffff163b151590565b6102dc6103d9565b73ffffffffffffffffffffffffffffffffffffffff163303610133576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604260248201527f5472616e73706172656e745570677261646561626c6550726f78793a2061646d60448201527f696e2063616e6e6f742066616c6c6261636b20746f2070726f7879207461726760648201527f6574000000000000000000000000000000000000000000000000000000000000608482015260a4015b60405180910390fd5b60006102216105cd565b3660008037600080366000845af43d6000803e8080156103d4573d6000f35b3d6000fd5b60007fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035b5473ffffffffffffffffffffffffffffffffffffffff16919050565b610422836105f5565b60008251118061042f5750805b156101e65761043e838361028c565b50505050565b7f7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f61046d6103d9565b6040805173ffffffffffffffffffffffffffffffffffffffff928316815291841660208301520160405180910390a161017481610642565b606073ffffffffffffffffffffffffffffffffffffffff84163b61054b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f416464726573733a2064656c65676174652063616c6c20746f206e6f6e2d636f60448201527f6e7472616374000000000000000000000000000000000000000000000000000060648201526084016103a2565b6000808573ffffffffffffffffffffffffffffffffffffffff16856040516105739190610957565b600060405180830381855af49150503d80600081146105ae576040519150601f19603f3d011682016040523d82523d6000602084013e6105b3565b606091505b50915091506105c382828661074e565b9695505050505050565b60007f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc6103fd565b6105fe816107a1565b60405173ffffffffffffffffffffffffffffffffffffffff8216907fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b90600090a250565b73ffffffffffffffffffffffffffffffffffffffff81166106e5576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f455243313936373a206e65772061646d696e20697320746865207a65726f206160448201527f646472657373000000000000000000000000000000000000000000000000000060648201526084016103a2565b807fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035b80547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff9290921691909117905550565b6060831561075d5750816102b1565b82511561076d5782518084602001fd5b816040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016103a29190610973565b73ffffffffffffffffffffffffffffffffffffffff81163b610845576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602d60248201527f455243313936373a206e657720696d706c656d656e746174696f6e206973206e60448201527f6f74206120636f6e74726163740000000000000000000000000000000000000060648201526084016103a2565b807f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc610708565b803573ffffffffffffffffffffffffffffffffffffffff8116811461089057600080fd5b919050565b6000602082840312156108a757600080fd5b6102b18261086c565b6000806000604084860312156108c557600080fd5b6108ce8461086c565b9250602084013567ffffffffffffffff808211156108eb57600080fd5b818601915086601f8301126108ff57600080fd5b81358181111561090e57600080fd5b87602082850101111561092057600080fd5b6020830194508093505050509250925092565b60005b8381101561094e578181015183820152602001610936565b50506000910152565b60008251610969818460208701610933565b9190910192915050565b6020815260008251806020840152610992816040850160208701610933565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016919091016040019291505056fe416464726573733a206c6f772d6c6576656c2064656c65676174652063616c6c206661696c6564a2646970667358221220e96638b07fb1675d93a95c49e417bc8111448b23a59918698cdcd8fd488dd7cf64736f6c63430008110033", + "devdoc": { + "details": "This contract implements a proxy that is upgradeable by an admin. It is fully forked from OpenZeppelin `TransparentUpgradeableProxy` To avoid https://medium.com/nomic-labs-blog/malicious-backdoors-in-ethereum-proxies-62629adf3357[proxy selector clashing], which can potentially be used in an attack, this contract uses the https://blog.openzeppelin.com/the-transparent-proxy-pattern/[transparent proxy pattern]. This pattern implies two things that go hand in hand: 1. If any account other than the admin calls the proxy, the call will be forwarded to the implementation, even if that call matches one of the admin functions exposed by the proxy itself. 2. If the admin calls the proxy, it can access the admin functions, but its calls will never be forwarded to the implementation. If the admin tries to call a function on the implementation it will fail with an error that says \"admin cannot fallback to proxy target\". These properties mean that the admin account can only be used for admin actions like upgrading the proxy or changing the admin, so it's best if it's a dedicated account that is not used for anything else. This will avoid headaches due to sudden errors when trying to call a function from the proxy implementation. Our recommendation is for the dedicated account to be an instance of the {ProxyAdmin} contract. If set up this way, you should think of the `ProxyAdmin` instance as the real administrative interface of your proxy.", + "kind": "dev", + "methods": { + "admin()": { + "details": "Returns the current admin. NOTE: Only the admin can call this function. See {ProxyAdmin-getProxyAdmin}. TIP: To get this value clients can read directly from the storage slot shown below (specified by EIP1967) using the https://eth.wiki/json-rpc/API#eth_getstorageat[`eth_getStorageAt`] RPC call. `0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103`" + }, + "changeAdmin(address)": { + "details": "Changes the admin of the proxy. Emits an {AdminChanged} event. NOTE: Only the admin can call this function. See {ProxyAdmin-changeProxyAdmin}." + }, + "constructor": { + "details": "Initializes an upgradeable proxy managed by `_admin`, backed by the implementation at `_logic`, and optionally initialized with `_data` as explained in {ERC1967Proxy-constructor}." + }, + "implementation()": { + "details": "Returns the current implementation. NOTE: Only the admin can call this function. See {ProxyAdmin-getProxyImplementation}. TIP: To get this value clients can read directly from the storage slot shown below (specified by EIP1967) using the https://eth.wiki/json-rpc/API#eth_getstorageat[`eth_getStorageAt`] RPC call. `0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc`" + }, + "upgradeTo(address)": { + "details": "Upgrade the implementation of the proxy. NOTE: Only the admin can call this function. See {ProxyAdmin-upgrade}." + }, + "upgradeToAndCall(address,bytes)": { + "details": "Upgrade the implementation of the proxy, and then call a function from the new implementation as specified by `data`, which should be an encoded function call. This is useful to initialize new storage variables in the proxied contract. NOTE: Only the admin can call this function. See {ProxyAdmin-upgradeAndCall}." + } + }, + "version": 1 + }, + "userdoc": { + "kind": "user", + "methods": {}, + "version": 1 + }, + "storageLayout": { + "storage": [], + "types": null + } +} \ No newline at end of file diff --git a/deployments/polygon/Treasury_USD.json b/deployments/polygon/Treasury_USD.json new file mode 100644 index 00000000..268eb20b --- /dev/null +++ b/deployments/polygon/Treasury_USD.json @@ -0,0 +1,250 @@ +{ + "address": "0x37ad97C08E3Ce8184aD30911bfb0BcEe443d5120", + "abi": [ + { + "inputs": [ + { + "internalType": "address", + "name": "_logic", + "type": "address" + }, + { + "internalType": "address", + "name": "admin_", + "type": "address" + }, + { + "internalType": "bytes", + "name": "_data", + "type": "bytes" + } + ], + "stateMutability": "payable", + "type": "constructor" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "previousAdmin", + "type": "address" + }, + { + "indexed": false, + "internalType": "address", + "name": "newAdmin", + "type": "address" + } + ], + "name": "AdminChanged", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "beacon", + "type": "address" + } + ], + "name": "BeaconUpgraded", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "implementation", + "type": "address" + } + ], + "name": "Upgraded", + "type": "event" + }, + { + "stateMutability": "payable", + "type": "fallback" + }, + { + "inputs": [], + "name": "admin", + "outputs": [ + { + "internalType": "address", + "name": "admin_", + "type": "address" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "newAdmin", + "type": "address" + } + ], + "name": "changeAdmin", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "implementation", + "outputs": [ + { + "internalType": "address", + "name": "implementation_", + "type": "address" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "newImplementation", + "type": "address" + } + ], + "name": "upgradeTo", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "newImplementation", + "type": "address" + }, + { + "internalType": "bytes", + "name": "data", + "type": "bytes" + } + ], + "name": "upgradeToAndCall", + "outputs": [], + "stateMutability": "payable", + "type": "function" + }, + { + "stateMutability": "payable", + "type": "receive" + } + ], + "transactionHash": "0x3800c89647d96e50991f3e9cf7c02d7b79bbc28b016b45fa62898200af1e357d", + "receipt": { + "to": null, + "from": "0xfdA462548Ce04282f4B6D6619823a7C64Fdc0185", + "contractAddress": "0x37ad97C08E3Ce8184aD30911bfb0BcEe443d5120", + "transactionIndex": 67, + "gasUsed": "735236", + "logsBloom": "0x00000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000002800000000000000000000100000000000000000100000000200000000000000000000000800000000080000000000100000000000000000000000000000000000000000002000000000000000000800000200000000000000000001000000000000000000000000000000000000000005000000020000000000001000000000000000800000400000000100000000000000000000101000000100000000000100000000000000000200000000000100000", + "blockHash": "0xe55653a5a25fbac907df22846a9ca9e2973a22b445efc36b1d483a901fd4c788", + "transactionHash": "0x3800c89647d96e50991f3e9cf7c02d7b79bbc28b016b45fa62898200af1e357d", + "logs": [ + { + "transactionIndex": 67, + "blockNumber": 52158255, + "transactionHash": "0x3800c89647d96e50991f3e9cf7c02d7b79bbc28b016b45fa62898200af1e357d", + "address": "0x37ad97C08E3Ce8184aD30911bfb0BcEe443d5120", + "topics": [ + "0xbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b", + "0x00000000000000000000000026c67a7493ae48722aef0bb96e00c0580cf29320" + ], + "data": "0x", + "logIndex": 273, + "blockHash": "0xe55653a5a25fbac907df22846a9ca9e2973a22b445efc36b1d483a901fd4c788" + }, + { + "transactionIndex": 67, + "blockNumber": 52158255, + "transactionHash": "0x3800c89647d96e50991f3e9cf7c02d7b79bbc28b016b45fa62898200af1e357d", + "address": "0x37ad97C08E3Ce8184aD30911bfb0BcEe443d5120", + "topics": [ + "0x7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f" + ], + "data": "0x0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000bfca293e17e067e8abdca30a5d35addd0cbae6d6", + "logIndex": 274, + "blockHash": "0xe55653a5a25fbac907df22846a9ca9e2973a22b445efc36b1d483a901fd4c788" + }, + { + "transactionIndex": 67, + "blockNumber": 52158255, + "transactionHash": "0x3800c89647d96e50991f3e9cf7c02d7b79bbc28b016b45fa62898200af1e357d", + "address": "0x0000000000000000000000000000000000001010", + "topics": [ + "0x4dfe1bbbcf077ddc3e01291eea2d5c70c2b422b415d95645b9adcfd678cb1d63", + "0x0000000000000000000000000000000000000000000000000000000000001010", + "0x000000000000000000000000fda462548ce04282f4b6d6619823a7c64fdc0185", + "0x000000000000000000000000b9ede6f94d192073d8eaf85f8db677133d483249" + ], + "data": "0x00000000000000000000000000000000000000000000000000501d601e4a1d7400000000000000000000000000000000000000000000000400d331d20085e6390000000000000000000000000000000000000000000003db714b15c42afafe6300000000000000000000000000000000000000000000000400831471e23bc8c50000000000000000000000000000000000000000000003db719b332449451bd7", + "logIndex": 275, + "blockHash": "0xe55653a5a25fbac907df22846a9ca9e2973a22b445efc36b1d483a901fd4c788" + } + ], + "blockNumber": 52158255, + "cumulativeGasUsed": "9241613", + "status": 1, + "byzantium": true + }, + "args": [ + "0x26c67a7493Ae48722AEf0bB96e00C0580cf29320", + "0xBFca293e17e067e8aBdca30A5D35ADDd0cBaE6D6", + "0x485cc95500000000000000000000000057ef4e590a0eba16a5893443c5b1f6fb9ed7e3410000000000000000000000000000206329b97db379d5e1bf586bbdb969c63274" + ], + "numDeployments": 1, + "solcInputHash": "871924e0c138825a2736b76def8fef8d", + "metadata": "{\"compiler\":{\"version\":\"0.8.17+commit.8df45f5f\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_logic\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"admin_\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"_data\",\"type\":\"bytes\"}],\"stateMutability\":\"payable\",\"type\":\"constructor\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"previousAdmin\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"newAdmin\",\"type\":\"address\"}],\"name\":\"AdminChanged\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"beacon\",\"type\":\"address\"}],\"name\":\"BeaconUpgraded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"implementation\",\"type\":\"address\"}],\"name\":\"Upgraded\",\"type\":\"event\"},{\"stateMutability\":\"payable\",\"type\":\"fallback\"},{\"inputs\":[],\"name\":\"admin\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"admin_\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newAdmin\",\"type\":\"address\"}],\"name\":\"changeAdmin\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"implementation\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"implementation_\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newImplementation\",\"type\":\"address\"}],\"name\":\"upgradeTo\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newImplementation\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"}],\"name\":\"upgradeToAndCall\",\"outputs\":[],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"stateMutability\":\"payable\",\"type\":\"receive\"}],\"devdoc\":{\"details\":\"This contract implements a proxy that is upgradeable by an admin. It is fully forked from OpenZeppelin `TransparentUpgradeableProxy` To avoid https://medium.com/nomic-labs-blog/malicious-backdoors-in-ethereum-proxies-62629adf3357[proxy selector clashing], which can potentially be used in an attack, this contract uses the https://blog.openzeppelin.com/the-transparent-proxy-pattern/[transparent proxy pattern]. This pattern implies two things that go hand in hand: 1. If any account other than the admin calls the proxy, the call will be forwarded to the implementation, even if that call matches one of the admin functions exposed by the proxy itself. 2. If the admin calls the proxy, it can access the admin functions, but its calls will never be forwarded to the implementation. If the admin tries to call a function on the implementation it will fail with an error that says \\\"admin cannot fallback to proxy target\\\". These properties mean that the admin account can only be used for admin actions like upgrading the proxy or changing the admin, so it's best if it's a dedicated account that is not used for anything else. This will avoid headaches due to sudden errors when trying to call a function from the proxy implementation. Our recommendation is for the dedicated account to be an instance of the {ProxyAdmin} contract. If set up this way, you should think of the `ProxyAdmin` instance as the real administrative interface of your proxy.\",\"kind\":\"dev\",\"methods\":{\"admin()\":{\"details\":\"Returns the current admin. NOTE: Only the admin can call this function. See {ProxyAdmin-getProxyAdmin}. TIP: To get this value clients can read directly from the storage slot shown below (specified by EIP1967) using the https://eth.wiki/json-rpc/API#eth_getstorageat[`eth_getStorageAt`] RPC call. `0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103`\"},\"changeAdmin(address)\":{\"details\":\"Changes the admin of the proxy. Emits an {AdminChanged} event. NOTE: Only the admin can call this function. See {ProxyAdmin-changeProxyAdmin}.\"},\"constructor\":{\"details\":\"Initializes an upgradeable proxy managed by `_admin`, backed by the implementation at `_logic`, and optionally initialized with `_data` as explained in {ERC1967Proxy-constructor}.\"},\"implementation()\":{\"details\":\"Returns the current implementation. NOTE: Only the admin can call this function. See {ProxyAdmin-getProxyImplementation}. TIP: To get this value clients can read directly from the storage slot shown below (specified by EIP1967) using the https://eth.wiki/json-rpc/API#eth_getstorageat[`eth_getStorageAt`] RPC call. `0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc`\"},\"upgradeTo(address)\":{\"details\":\"Upgrade the implementation of the proxy. NOTE: Only the admin can call this function. See {ProxyAdmin-upgrade}.\"},\"upgradeToAndCall(address,bytes)\":{\"details\":\"Upgrade the implementation of the proxy, and then call a function from the new implementation as specified by `data`, which should be an encoded function call. This is useful to initialize new storage variables in the proxied contract. NOTE: Only the admin can call this function. See {ProxyAdmin-upgradeAndCall}.\"}},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/external/TransparentUpgradeableProxy.sol\":\"TransparentUpgradeableProxy\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":1000000},\"remappings\":[]},\"sources\":{\"@openzeppelin/contracts/interfaces/draft-IERC1822.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.5.0) (interfaces/draft-IERC1822.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev ERC1822: Universal Upgradeable Proxy Standard (UUPS) documents a method for upgradeability through a simplified\\n * proxy whose upgrades are fully controlled by the current implementation.\\n */\\ninterface IERC1822Proxiable {\\n /**\\n * @dev Returns the storage slot that the proxiable contract assumes is being used to store the implementation\\n * address.\\n *\\n * IMPORTANT: A proxy pointing at a proxiable contract should not be considered proxiable itself, because this risks\\n * bricking a proxy that upgrades to it, by delegating to itself until out of gas. Thus it is critical that this\\n * function revert if invoked through a proxy.\\n */\\n function proxiableUUID() external view returns (bytes32);\\n}\\n\",\"keccak256\":\"0x1d4afe6cb24200cc4545eed814ecf5847277dfe5d613a1707aad5fceecebcfff\",\"license\":\"MIT\"},\"@openzeppelin/contracts/proxy/ERC1967/ERC1967Proxy.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.7.0) (proxy/ERC1967/ERC1967Proxy.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../Proxy.sol\\\";\\nimport \\\"./ERC1967Upgrade.sol\\\";\\n\\n/**\\n * @dev This contract implements an upgradeable proxy. It is upgradeable because calls are delegated to an\\n * implementation address that can be changed. This address is stored in storage in the location specified by\\n * https://eips.ethereum.org/EIPS/eip-1967[EIP1967], so that it doesn't conflict with the storage layout of the\\n * implementation behind the proxy.\\n */\\ncontract ERC1967Proxy is Proxy, ERC1967Upgrade {\\n /**\\n * @dev Initializes the upgradeable proxy with an initial implementation specified by `_logic`.\\n *\\n * If `_data` is nonempty, it's used as data in a delegate call to `_logic`. This will typically be an encoded\\n * function call, and allows initializing the storage of the proxy like a Solidity constructor.\\n */\\n constructor(address _logic, bytes memory _data) payable {\\n _upgradeToAndCall(_logic, _data, false);\\n }\\n\\n /**\\n * @dev Returns the current implementation address.\\n */\\n function _implementation() internal view virtual override returns (address impl) {\\n return ERC1967Upgrade._getImplementation();\\n }\\n}\\n\",\"keccak256\":\"0xa2b22da3032e50b55f95ec1d13336102d675f341167aa76db571ef7f8bb7975d\",\"license\":\"MIT\"},\"@openzeppelin/contracts/proxy/ERC1967/ERC1967Upgrade.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.5.0) (proxy/ERC1967/ERC1967Upgrade.sol)\\n\\npragma solidity ^0.8.2;\\n\\nimport \\\"../beacon/IBeacon.sol\\\";\\nimport \\\"../../interfaces/draft-IERC1822.sol\\\";\\nimport \\\"../../utils/Address.sol\\\";\\nimport \\\"../../utils/StorageSlot.sol\\\";\\n\\n/**\\n * @dev This abstract contract provides getters and event emitting update functions for\\n * https://eips.ethereum.org/EIPS/eip-1967[EIP1967] slots.\\n *\\n * _Available since v4.1._\\n *\\n * @custom:oz-upgrades-unsafe-allow delegatecall\\n */\\nabstract contract ERC1967Upgrade {\\n // This is the keccak-256 hash of \\\"eip1967.proxy.rollback\\\" subtracted by 1\\n bytes32 private constant _ROLLBACK_SLOT = 0x4910fdfa16fed3260ed0e7147f7cc6da11a60208b5b9406d12a635614ffd9143;\\n\\n /**\\n * @dev Storage slot with the address of the current implementation.\\n * This is the keccak-256 hash of \\\"eip1967.proxy.implementation\\\" subtracted by 1, and is\\n * validated in the constructor.\\n */\\n bytes32 internal constant _IMPLEMENTATION_SLOT = 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc;\\n\\n /**\\n * @dev Emitted when the implementation is upgraded.\\n */\\n event Upgraded(address indexed implementation);\\n\\n /**\\n * @dev Returns the current implementation address.\\n */\\n function _getImplementation() internal view returns (address) {\\n return StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value;\\n }\\n\\n /**\\n * @dev Stores a new address in the EIP1967 implementation slot.\\n */\\n function _setImplementation(address newImplementation) private {\\n require(Address.isContract(newImplementation), \\\"ERC1967: new implementation is not a contract\\\");\\n StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value = newImplementation;\\n }\\n\\n /**\\n * @dev Perform implementation upgrade\\n *\\n * Emits an {Upgraded} event.\\n */\\n function _upgradeTo(address newImplementation) internal {\\n _setImplementation(newImplementation);\\n emit Upgraded(newImplementation);\\n }\\n\\n /**\\n * @dev Perform implementation upgrade with additional setup call.\\n *\\n * Emits an {Upgraded} event.\\n */\\n function _upgradeToAndCall(\\n address newImplementation,\\n bytes memory data,\\n bool forceCall\\n ) internal {\\n _upgradeTo(newImplementation);\\n if (data.length > 0 || forceCall) {\\n Address.functionDelegateCall(newImplementation, data);\\n }\\n }\\n\\n /**\\n * @dev Perform implementation upgrade with security checks for UUPS proxies, and additional setup call.\\n *\\n * Emits an {Upgraded} event.\\n */\\n function _upgradeToAndCallUUPS(\\n address newImplementation,\\n bytes memory data,\\n bool forceCall\\n ) internal {\\n // Upgrades from old implementations will perform a rollback test. This test requires the new\\n // implementation to upgrade back to the old, non-ERC1822 compliant, implementation. Removing\\n // this special case will break upgrade paths from old UUPS implementation to new ones.\\n if (StorageSlot.getBooleanSlot(_ROLLBACK_SLOT).value) {\\n _setImplementation(newImplementation);\\n } else {\\n try IERC1822Proxiable(newImplementation).proxiableUUID() returns (bytes32 slot) {\\n require(slot == _IMPLEMENTATION_SLOT, \\\"ERC1967Upgrade: unsupported proxiableUUID\\\");\\n } catch {\\n revert(\\\"ERC1967Upgrade: new implementation is not UUPS\\\");\\n }\\n _upgradeToAndCall(newImplementation, data, forceCall);\\n }\\n }\\n\\n /**\\n * @dev Storage slot with the admin of the contract.\\n * This is the keccak-256 hash of \\\"eip1967.proxy.admin\\\" subtracted by 1, and is\\n * validated in the constructor.\\n */\\n bytes32 internal constant _ADMIN_SLOT = 0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103;\\n\\n /**\\n * @dev Emitted when the admin account has changed.\\n */\\n event AdminChanged(address previousAdmin, address newAdmin);\\n\\n /**\\n * @dev Returns the current admin.\\n */\\n function _getAdmin() internal view returns (address) {\\n return StorageSlot.getAddressSlot(_ADMIN_SLOT).value;\\n }\\n\\n /**\\n * @dev Stores a new address in the EIP1967 admin slot.\\n */\\n function _setAdmin(address newAdmin) private {\\n require(newAdmin != address(0), \\\"ERC1967: new admin is the zero address\\\");\\n StorageSlot.getAddressSlot(_ADMIN_SLOT).value = newAdmin;\\n }\\n\\n /**\\n * @dev Changes the admin of the proxy.\\n *\\n * Emits an {AdminChanged} event.\\n */\\n function _changeAdmin(address newAdmin) internal {\\n emit AdminChanged(_getAdmin(), newAdmin);\\n _setAdmin(newAdmin);\\n }\\n\\n /**\\n * @dev The storage slot of the UpgradeableBeacon contract which defines the implementation for this proxy.\\n * This is bytes32(uint256(keccak256('eip1967.proxy.beacon')) - 1)) and is validated in the constructor.\\n */\\n bytes32 internal constant _BEACON_SLOT = 0xa3f0ad74e5423aebfd80d3ef4346578335a9a72aeaee59ff6cb3582b35133d50;\\n\\n /**\\n * @dev Emitted when the beacon is upgraded.\\n */\\n event BeaconUpgraded(address indexed beacon);\\n\\n /**\\n * @dev Returns the current beacon.\\n */\\n function _getBeacon() internal view returns (address) {\\n return StorageSlot.getAddressSlot(_BEACON_SLOT).value;\\n }\\n\\n /**\\n * @dev Stores a new beacon in the EIP1967 beacon slot.\\n */\\n function _setBeacon(address newBeacon) private {\\n require(Address.isContract(newBeacon), \\\"ERC1967: new beacon is not a contract\\\");\\n require(\\n Address.isContract(IBeacon(newBeacon).implementation()),\\n \\\"ERC1967: beacon implementation is not a contract\\\"\\n );\\n StorageSlot.getAddressSlot(_BEACON_SLOT).value = newBeacon;\\n }\\n\\n /**\\n * @dev Perform beacon upgrade with additional setup call. Note: This upgrades the address of the beacon, it does\\n * not upgrade the implementation contained in the beacon (see {UpgradeableBeacon-_setImplementation} for that).\\n *\\n * Emits a {BeaconUpgraded} event.\\n */\\n function _upgradeBeaconToAndCall(\\n address newBeacon,\\n bytes memory data,\\n bool forceCall\\n ) internal {\\n _setBeacon(newBeacon);\\n emit BeaconUpgraded(newBeacon);\\n if (data.length > 0 || forceCall) {\\n Address.functionDelegateCall(IBeacon(newBeacon).implementation(), data);\\n }\\n }\\n}\\n\",\"keccak256\":\"0xabf3f59bc0e5423eae45e459dbe92e7052c6983628d39008590edc852a62f94a\",\"license\":\"MIT\"},\"@openzeppelin/contracts/proxy/Proxy.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.6.0) (proxy/Proxy.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev This abstract contract provides a fallback function that delegates all calls to another contract using the EVM\\n * instruction `delegatecall`. We refer to the second contract as the _implementation_ behind the proxy, and it has to\\n * be specified by overriding the virtual {_implementation} function.\\n *\\n * Additionally, delegation to the implementation can be triggered manually through the {_fallback} function, or to a\\n * different contract through the {_delegate} function.\\n *\\n * The success and return data of the delegated call will be returned back to the caller of the proxy.\\n */\\nabstract contract Proxy {\\n /**\\n * @dev Delegates the current call to `implementation`.\\n *\\n * This function does not return to its internal call site, it will return directly to the external caller.\\n */\\n function _delegate(address implementation) internal virtual {\\n assembly {\\n // Copy msg.data. We take full control of memory in this inline assembly\\n // block because it will not return to Solidity code. We overwrite the\\n // Solidity scratch pad at memory position 0.\\n calldatacopy(0, 0, calldatasize())\\n\\n // Call the implementation.\\n // out and outsize are 0 because we don't know the size yet.\\n let result := delegatecall(gas(), implementation, 0, calldatasize(), 0, 0)\\n\\n // Copy the returned data.\\n returndatacopy(0, 0, returndatasize())\\n\\n switch result\\n // delegatecall returns 0 on error.\\n case 0 {\\n revert(0, returndatasize())\\n }\\n default {\\n return(0, returndatasize())\\n }\\n }\\n }\\n\\n /**\\n * @dev This is a virtual function that should be overridden so it returns the address to which the fallback function\\n * and {_fallback} should delegate.\\n */\\n function _implementation() internal view virtual returns (address);\\n\\n /**\\n * @dev Delegates the current call to the address returned by `_implementation()`.\\n *\\n * This function does not return to its internal call site, it will return directly to the external caller.\\n */\\n function _fallback() internal virtual {\\n _beforeFallback();\\n _delegate(_implementation());\\n }\\n\\n /**\\n * @dev Fallback function that delegates calls to the address returned by `_implementation()`. Will run if no other\\n * function in the contract matches the call data.\\n */\\n fallback() external payable virtual {\\n _fallback();\\n }\\n\\n /**\\n * @dev Fallback function that delegates calls to the address returned by `_implementation()`. Will run if call data\\n * is empty.\\n */\\n receive() external payable virtual {\\n _fallback();\\n }\\n\\n /**\\n * @dev Hook that is called before falling back to the implementation. Can happen as part of a manual `_fallback`\\n * call, or as part of the Solidity `fallback` or `receive` functions.\\n *\\n * If overridden should call `super._beforeFallback()`.\\n */\\n function _beforeFallback() internal virtual {}\\n}\\n\",\"keccak256\":\"0xc130fe33f1b2132158531a87734153293f6d07bc263ff4ac90e85da9c82c0e27\",\"license\":\"MIT\"},\"@openzeppelin/contracts/proxy/beacon/IBeacon.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (proxy/beacon/IBeacon.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev This is the interface that {BeaconProxy} expects of its beacon.\\n */\\ninterface IBeacon {\\n /**\\n * @dev Must return an address that can be used as a delegate call target.\\n *\\n * {BeaconProxy} will check that this address is a contract.\\n */\\n function implementation() external view returns (address);\\n}\\n\",\"keccak256\":\"0xd50a3421ac379ccb1be435fa646d66a65c986b4924f0849839f08692f39dde61\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/Address.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.7.0) (utils/Address.sol)\\n\\npragma solidity ^0.8.1;\\n\\n/**\\n * @dev Collection of functions related to the address type\\n */\\nlibrary Address {\\n /**\\n * @dev Returns true if `account` is a contract.\\n *\\n * [IMPORTANT]\\n * ====\\n * It is unsafe to assume that an address for which this function returns\\n * false is an externally-owned account (EOA) and not a contract.\\n *\\n * Among others, `isContract` will return false for the following\\n * types of addresses:\\n *\\n * - an externally-owned account\\n * - a contract in construction\\n * - an address where a contract will be created\\n * - an address where a contract lived, but was destroyed\\n * ====\\n *\\n * [IMPORTANT]\\n * ====\\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\\n *\\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\\n * constructor.\\n * ====\\n */\\n function isContract(address account) internal view returns (bool) {\\n // This method relies on extcodesize/address.code.length, which returns 0\\n // for contracts in construction, since the code is only stored at the end\\n // of the constructor execution.\\n\\n return account.code.length > 0;\\n }\\n\\n /**\\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\\n * `recipient`, forwarding all available gas and reverting on errors.\\n *\\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\\n * imposed by `transfer`, making them unable to receive funds via\\n * `transfer`. {sendValue} removes this limitation.\\n *\\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\\n *\\n * IMPORTANT: because control is transferred to `recipient`, care must be\\n * taken to not create reentrancy vulnerabilities. Consider using\\n * {ReentrancyGuard} or the\\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\\n */\\n function sendValue(address payable recipient, uint256 amount) internal {\\n require(address(this).balance >= amount, \\\"Address: insufficient balance\\\");\\n\\n (bool success, ) = recipient.call{value: amount}(\\\"\\\");\\n require(success, \\\"Address: unable to send value, recipient may have reverted\\\");\\n }\\n\\n /**\\n * @dev Performs a Solidity function call using a low level `call`. A\\n * plain `call` is an unsafe replacement for a function call: use this\\n * function instead.\\n *\\n * If `target` reverts with a revert reason, it is bubbled up by this\\n * function (like regular Solidity function calls).\\n *\\n * Returns the raw returned data. To convert to the expected return value,\\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\\n *\\n * Requirements:\\n *\\n * - `target` must be a contract.\\n * - calling `target` with `data` must not revert.\\n *\\n * _Available since v3.1._\\n */\\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\\n return functionCall(target, data, \\\"Address: low-level call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\\n * `errorMessage` as a fallback revert reason when `target` reverts.\\n *\\n * _Available since v3.1._\\n */\\n function functionCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n return functionCallWithValue(target, data, 0, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but also transferring `value` wei to `target`.\\n *\\n * Requirements:\\n *\\n * - the calling contract must have an ETH balance of at least `value`.\\n * - the called Solidity function must be `payable`.\\n *\\n * _Available since v3.1._\\n */\\n function functionCallWithValue(\\n address target,\\n bytes memory data,\\n uint256 value\\n ) internal returns (bytes memory) {\\n return functionCallWithValue(target, data, value, \\\"Address: low-level call with value failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\\n * with `errorMessage` as a fallback revert reason when `target` reverts.\\n *\\n * _Available since v3.1._\\n */\\n function functionCallWithValue(\\n address target,\\n bytes memory data,\\n uint256 value,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n require(address(this).balance >= value, \\\"Address: insufficient balance for call\\\");\\n require(isContract(target), \\\"Address: call to non-contract\\\");\\n\\n (bool success, bytes memory returndata) = target.call{value: value}(data);\\n return verifyCallResult(success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but performing a static call.\\n *\\n * _Available since v3.3._\\n */\\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\\n return functionStaticCall(target, data, \\\"Address: low-level static call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\\n * but performing a static call.\\n *\\n * _Available since v3.3._\\n */\\n function functionStaticCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal view returns (bytes memory) {\\n require(isContract(target), \\\"Address: static call to non-contract\\\");\\n\\n (bool success, bytes memory returndata) = target.staticcall(data);\\n return verifyCallResult(success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but performing a delegate call.\\n *\\n * _Available since v3.4._\\n */\\n function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {\\n return functionDelegateCall(target, data, \\\"Address: low-level delegate call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\\n * but performing a delegate call.\\n *\\n * _Available since v3.4._\\n */\\n function functionDelegateCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n require(isContract(target), \\\"Address: delegate call to non-contract\\\");\\n\\n (bool success, bytes memory returndata) = target.delegatecall(data);\\n return verifyCallResult(success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the\\n * revert reason using the provided one.\\n *\\n * _Available since v4.3._\\n */\\n function verifyCallResult(\\n bool success,\\n bytes memory returndata,\\n string memory errorMessage\\n ) internal pure returns (bytes memory) {\\n if (success) {\\n return returndata;\\n } else {\\n // Look for revert reason and bubble it up if present\\n if (returndata.length > 0) {\\n // The easiest way to bubble the revert reason is using memory via assembly\\n /// @solidity memory-safe-assembly\\n assembly {\\n let returndata_size := mload(returndata)\\n revert(add(32, returndata), returndata_size)\\n }\\n } else {\\n revert(errorMessage);\\n }\\n }\\n }\\n}\\n\",\"keccak256\":\"0xd6153ce99bcdcce22b124f755e72553295be6abcd63804cfdffceb188b8bef10\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/StorageSlot.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.7.0) (utils/StorageSlot.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Library for reading and writing primitive types to specific storage slots.\\n *\\n * Storage slots are often used to avoid storage conflict when dealing with upgradeable contracts.\\n * This library helps with reading and writing to such slots without the need for inline assembly.\\n *\\n * The functions in this library return Slot structs that contain a `value` member that can be used to read or write.\\n *\\n * Example usage to set ERC1967 implementation slot:\\n * ```\\n * contract ERC1967 {\\n * bytes32 internal constant _IMPLEMENTATION_SLOT = 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc;\\n *\\n * function _getImplementation() internal view returns (address) {\\n * return StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value;\\n * }\\n *\\n * function _setImplementation(address newImplementation) internal {\\n * require(Address.isContract(newImplementation), \\\"ERC1967: new implementation is not a contract\\\");\\n * StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value = newImplementation;\\n * }\\n * }\\n * ```\\n *\\n * _Available since v4.1 for `address`, `bool`, `bytes32`, and `uint256`._\\n */\\nlibrary StorageSlot {\\n struct AddressSlot {\\n address value;\\n }\\n\\n struct BooleanSlot {\\n bool value;\\n }\\n\\n struct Bytes32Slot {\\n bytes32 value;\\n }\\n\\n struct Uint256Slot {\\n uint256 value;\\n }\\n\\n /**\\n * @dev Returns an `AddressSlot` with member `value` located at `slot`.\\n */\\n function getAddressSlot(bytes32 slot) internal pure returns (AddressSlot storage r) {\\n /// @solidity memory-safe-assembly\\n assembly {\\n r.slot := slot\\n }\\n }\\n\\n /**\\n * @dev Returns an `BooleanSlot` with member `value` located at `slot`.\\n */\\n function getBooleanSlot(bytes32 slot) internal pure returns (BooleanSlot storage r) {\\n /// @solidity memory-safe-assembly\\n assembly {\\n r.slot := slot\\n }\\n }\\n\\n /**\\n * @dev Returns an `Bytes32Slot` with member `value` located at `slot`.\\n */\\n function getBytes32Slot(bytes32 slot) internal pure returns (Bytes32Slot storage r) {\\n /// @solidity memory-safe-assembly\\n assembly {\\n r.slot := slot\\n }\\n }\\n\\n /**\\n * @dev Returns an `Uint256Slot` with member `value` located at `slot`.\\n */\\n function getUint256Slot(bytes32 slot) internal pure returns (Uint256Slot storage r) {\\n /// @solidity memory-safe-assembly\\n assembly {\\n r.slot := slot\\n }\\n }\\n}\\n\",\"keccak256\":\"0xd5c50c54bf02740ebd122ff06832546cb5fa84486d52695a9ccfd11666e0c81d\",\"license\":\"MIT\"},\"contracts/external/TransparentUpgradeableProxy.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-3.0\\n\\npragma solidity ^0.8.12;\\n\\nimport \\\"@openzeppelin/contracts/proxy/ERC1967/ERC1967Proxy.sol\\\";\\n\\n/**\\n * @dev This contract implements a proxy that is upgradeable by an admin. It is fully forked from OpenZeppelin\\n * `TransparentUpgradeableProxy`\\n *\\n * To avoid https://medium.com/nomic-labs-blog/malicious-backdoors-in-ethereum-proxies-62629adf3357[proxy selector\\n * clashing], which can potentially be used in an attack, this contract uses the\\n * https://blog.openzeppelin.com/the-transparent-proxy-pattern/[transparent proxy pattern]. This pattern implies two\\n * things that go hand in hand:\\n *\\n * 1. If any account other than the admin calls the proxy, the call will be forwarded to the implementation, even if\\n * that call matches one of the admin functions exposed by the proxy itself.\\n * 2. If the admin calls the proxy, it can access the admin functions, but its calls will never be forwarded to the\\n * implementation. If the admin tries to call a function on the implementation it will fail with an error that says\\n * \\\"admin cannot fallback to proxy target\\\".\\n *\\n * These properties mean that the admin account can only be used for admin actions like upgrading the proxy or changing\\n * the admin, so it's best if it's a dedicated account that is not used for anything else. This will avoid headaches due\\n * to sudden errors when trying to call a function from the proxy implementation.\\n *\\n * Our recommendation is for the dedicated account to be an instance of the {ProxyAdmin} contract. If set up this way,\\n * you should think of the `ProxyAdmin` instance as the real administrative interface of your proxy.\\n */\\ncontract TransparentUpgradeableProxy is ERC1967Proxy {\\n /**\\n * @dev Initializes an upgradeable proxy managed by `_admin`, backed by the implementation at `_logic`, and\\n * optionally initialized with `_data` as explained in {ERC1967Proxy-constructor}.\\n */\\n constructor(address _logic, address admin_, bytes memory _data) payable ERC1967Proxy(_logic, _data) {\\n assert(_ADMIN_SLOT == bytes32(uint256(keccak256(\\\"eip1967.proxy.admin\\\")) - 1));\\n _changeAdmin(admin_);\\n }\\n\\n /**\\n * @dev Modifier used internally that will delegate the call to the implementation unless the sender is the admin.\\n */\\n modifier ifAdmin() {\\n if (msg.sender == _getAdmin()) {\\n _;\\n } else {\\n _fallback();\\n }\\n }\\n\\n /**\\n * @dev Returns the current admin.\\n *\\n * NOTE: Only the admin can call this function. See {ProxyAdmin-getProxyAdmin}.\\n *\\n * TIP: To get this value clients can read directly from the storage slot shown below (specified by EIP1967) using the\\n * https://eth.wiki/json-rpc/API#eth_getstorageat[`eth_getStorageAt`] RPC call.\\n * `0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103`\\n */\\n function admin() external ifAdmin returns (address admin_) {\\n admin_ = _getAdmin();\\n }\\n\\n /**\\n * @dev Returns the current implementation.\\n *\\n * NOTE: Only the admin can call this function. See {ProxyAdmin-getProxyImplementation}.\\n *\\n * TIP: To get this value clients can read directly from the storage slot shown below (specified by EIP1967) using the\\n * https://eth.wiki/json-rpc/API#eth_getstorageat[`eth_getStorageAt`] RPC call.\\n * `0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc`\\n */\\n function implementation() external ifAdmin returns (address implementation_) {\\n implementation_ = _implementation();\\n }\\n\\n /**\\n * @dev Changes the admin of the proxy.\\n *\\n * Emits an {AdminChanged} event.\\n *\\n * NOTE: Only the admin can call this function. See {ProxyAdmin-changeProxyAdmin}.\\n */\\n function changeAdmin(address newAdmin) external virtual ifAdmin {\\n _changeAdmin(newAdmin);\\n }\\n\\n /**\\n * @dev Upgrade the implementation of the proxy.\\n *\\n * NOTE: Only the admin can call this function. See {ProxyAdmin-upgrade}.\\n */\\n function upgradeTo(address newImplementation) external ifAdmin {\\n _upgradeToAndCall(newImplementation, bytes(\\\"\\\"), false);\\n }\\n\\n /**\\n * @dev Upgrade the implementation of the proxy, and then call a function from the new implementation as specified\\n * by `data`, which should be an encoded function call. This is useful to initialize new storage variables in the\\n * proxied contract.\\n *\\n * NOTE: Only the admin can call this function. See {ProxyAdmin-upgradeAndCall}.\\n */\\n function upgradeToAndCall(address newImplementation, bytes calldata data) external payable ifAdmin {\\n _upgradeToAndCall(newImplementation, data, true);\\n }\\n\\n /**\\n * @dev Returns the current admin.\\n */\\n function _admin() internal view virtual returns (address) {\\n return _getAdmin();\\n }\\n\\n /**\\n * @dev Makes sure the admin cannot access the fallback function. See {Proxy-_beforeFallback}.\\n */\\n function _beforeFallback() internal virtual override {\\n require(msg.sender != _getAdmin(), \\\"TransparentUpgradeableProxy: admin cannot fallback to proxy target\\\");\\n super._beforeFallback();\\n }\\n}\\n\",\"keccak256\":\"0x93a67a0f612ea3ff2a76315e138a6a88267270a1379d3cc7be52845fbbe611e2\",\"license\":\"GPL-3.0\"}},\"version\":1}", + "bytecode": "0x6080604052604051620010bb380380620010bb8339810160408190526200002691620004d8565b828162000036828260006200009a565b5062000066905060017fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6104620005b8565b6000805160206200107483398151915214620000865762000086620005da565b6200009182620000d7565b50505062000643565b620000a58362000132565b600082511180620000b35750805b15620000d257620000d083836200017460201b6200028c1760201c565b505b505050565b7f7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f62000102620001a5565b604080516001600160a01b03928316815291841660208301520160405180910390a16200012f81620001de565b50565b6200013d8162000293565b6040516001600160a01b038216907fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b90600090a250565b60606200019c8383604051806060016040528060278152602001620010946027913962000347565b90505b92915050565b6000620001cf6000805160206200107483398151915260001b6200042f60201b6200022e1760201c565b546001600160a01b0316919050565b6001600160a01b038116620002495760405162461bcd60e51b815260206004820152602660248201527f455243313936373a206e65772061646d696e20697320746865207a65726f206160448201526564647265737360d01b60648201526084015b60405180910390fd5b80620002726000805160206200107483398151915260001b6200042f60201b6200022e1760201c565b80546001600160a01b0319166001600160a01b039290921691909117905550565b620002a9816200043260201b620002b81760201c565b6200030d5760405162461bcd60e51b815260206004820152602d60248201527f455243313936373a206e657720696d706c656d656e746174696f6e206973206e60448201526c1bdd08184818dbdb9d1c9858dd609a1b606482015260840162000240565b80620002727f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc60001b6200042f60201b6200022e1760201c565b60606001600160a01b0384163b620003b15760405162461bcd60e51b815260206004820152602660248201527f416464726573733a2064656c65676174652063616c6c20746f206e6f6e2d636f6044820152651b9d1c9858dd60d21b606482015260840162000240565b600080856001600160a01b031685604051620003ce9190620005f0565b600060405180830381855af49150503d80600081146200040b576040519150601f19603f3d011682016040523d82523d6000602084013e62000410565b606091505b5090925090506200042382828662000441565b925050505b9392505050565b90565b6001600160a01b03163b151590565b606083156200045257508162000428565b825115620004635782518084602001fd5b8160405162461bcd60e51b81526004016200024091906200060e565b80516001600160a01b03811681146200049757600080fd5b919050565b634e487b7160e01b600052604160045260246000fd5b60005b83811015620004cf578181015183820152602001620004b5565b50506000910152565b600080600060608486031215620004ee57600080fd5b620004f9846200047f565b925062000509602085016200047f565b60408501519092506001600160401b03808211156200052757600080fd5b818601915086601f8301126200053c57600080fd5b8151818111156200055157620005516200049c565b604051601f8201601f19908116603f011681019083821181831017156200057c576200057c6200049c565b816040528281528960208487010111156200059657600080fd5b620005a9836020830160208801620004b2565b80955050505050509250925092565b818103818111156200019f57634e487b7160e01b600052601160045260246000fd5b634e487b7160e01b600052600160045260246000fd5b6000825162000604818460208701620004b2565b9190910192915050565b60208152600082518060208401526200062f816040850160208701620004b2565b601f01601f19169190910160400192915050565b610a2180620006536000396000f3fe60806040526004361061005e5760003560e01c80635c60da1b116100435780635c60da1b146100a85780638f283970146100e6578063f851a440146101065761006d565b80633659cfe6146100755780634f1ef286146100955761006d565b3661006d5761006b61011b565b005b61006b61011b565b34801561008157600080fd5b5061006b610090366004610895565b610135565b61006b6100a33660046108b0565b61017f565b3480156100b457600080fd5b506100bd6101f3565b60405173ffffffffffffffffffffffffffffffffffffffff909116815260200160405180910390f35b3480156100f257600080fd5b5061006b610101366004610895565b610231565b34801561011257600080fd5b506100bd61025e565b6101236102d4565b61013361012e6103ab565b6103b5565b565b61013d6103d9565b73ffffffffffffffffffffffffffffffffffffffff1633036101775761017481604051806020016040528060008152506000610419565b50565b61017461011b565b6101876103d9565b73ffffffffffffffffffffffffffffffffffffffff1633036101eb576101e68383838080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525060019250610419915050565b505050565b6101e661011b565b60006101fd6103d9565b73ffffffffffffffffffffffffffffffffffffffff163303610226576102216103ab565b905090565b61022e61011b565b90565b6102396103d9565b73ffffffffffffffffffffffffffffffffffffffff1633036101775761017481610444565b60006102686103d9565b73ffffffffffffffffffffffffffffffffffffffff163303610226576102216103d9565b60606102b183836040518060600160405280602781526020016109c5602791396104a5565b9392505050565b73ffffffffffffffffffffffffffffffffffffffff163b151590565b6102dc6103d9565b73ffffffffffffffffffffffffffffffffffffffff163303610133576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604260248201527f5472616e73706172656e745570677261646561626c6550726f78793a2061646d60448201527f696e2063616e6e6f742066616c6c6261636b20746f2070726f7879207461726760648201527f6574000000000000000000000000000000000000000000000000000000000000608482015260a4015b60405180910390fd5b60006102216105cd565b3660008037600080366000845af43d6000803e8080156103d4573d6000f35b3d6000fd5b60007fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035b5473ffffffffffffffffffffffffffffffffffffffff16919050565b610422836105f5565b60008251118061042f5750805b156101e65761043e838361028c565b50505050565b7f7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f61046d6103d9565b6040805173ffffffffffffffffffffffffffffffffffffffff928316815291841660208301520160405180910390a161017481610642565b606073ffffffffffffffffffffffffffffffffffffffff84163b61054b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f416464726573733a2064656c65676174652063616c6c20746f206e6f6e2d636f60448201527f6e7472616374000000000000000000000000000000000000000000000000000060648201526084016103a2565b6000808573ffffffffffffffffffffffffffffffffffffffff16856040516105739190610957565b600060405180830381855af49150503d80600081146105ae576040519150601f19603f3d011682016040523d82523d6000602084013e6105b3565b606091505b50915091506105c382828661074e565b9695505050505050565b60007f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc6103fd565b6105fe816107a1565b60405173ffffffffffffffffffffffffffffffffffffffff8216907fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b90600090a250565b73ffffffffffffffffffffffffffffffffffffffff81166106e5576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f455243313936373a206e65772061646d696e20697320746865207a65726f206160448201527f646472657373000000000000000000000000000000000000000000000000000060648201526084016103a2565b807fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035b80547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff9290921691909117905550565b6060831561075d5750816102b1565b82511561076d5782518084602001fd5b816040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016103a29190610973565b73ffffffffffffffffffffffffffffffffffffffff81163b610845576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602d60248201527f455243313936373a206e657720696d706c656d656e746174696f6e206973206e60448201527f6f74206120636f6e74726163740000000000000000000000000000000000000060648201526084016103a2565b807f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc610708565b803573ffffffffffffffffffffffffffffffffffffffff8116811461089057600080fd5b919050565b6000602082840312156108a757600080fd5b6102b18261086c565b6000806000604084860312156108c557600080fd5b6108ce8461086c565b9250602084013567ffffffffffffffff808211156108eb57600080fd5b818601915086601f8301126108ff57600080fd5b81358181111561090e57600080fd5b87602082850101111561092057600080fd5b6020830194508093505050509250925092565b60005b8381101561094e578181015183820152602001610936565b50506000910152565b60008251610969818460208701610933565b9190910192915050565b6020815260008251806020840152610992816040850160208701610933565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016919091016040019291505056fe416464726573733a206c6f772d6c6576656c2064656c65676174652063616c6c206661696c6564a2646970667358221220e96638b07fb1675d93a95c49e417bc8111448b23a59918698cdcd8fd488dd7cf64736f6c63430008110033b53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103416464726573733a206c6f772d6c6576656c2064656c65676174652063616c6c206661696c6564", + "deployedBytecode": "0x60806040526004361061005e5760003560e01c80635c60da1b116100435780635c60da1b146100a85780638f283970146100e6578063f851a440146101065761006d565b80633659cfe6146100755780634f1ef286146100955761006d565b3661006d5761006b61011b565b005b61006b61011b565b34801561008157600080fd5b5061006b610090366004610895565b610135565b61006b6100a33660046108b0565b61017f565b3480156100b457600080fd5b506100bd6101f3565b60405173ffffffffffffffffffffffffffffffffffffffff909116815260200160405180910390f35b3480156100f257600080fd5b5061006b610101366004610895565b610231565b34801561011257600080fd5b506100bd61025e565b6101236102d4565b61013361012e6103ab565b6103b5565b565b61013d6103d9565b73ffffffffffffffffffffffffffffffffffffffff1633036101775761017481604051806020016040528060008152506000610419565b50565b61017461011b565b6101876103d9565b73ffffffffffffffffffffffffffffffffffffffff1633036101eb576101e68383838080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525060019250610419915050565b505050565b6101e661011b565b60006101fd6103d9565b73ffffffffffffffffffffffffffffffffffffffff163303610226576102216103ab565b905090565b61022e61011b565b90565b6102396103d9565b73ffffffffffffffffffffffffffffffffffffffff1633036101775761017481610444565b60006102686103d9565b73ffffffffffffffffffffffffffffffffffffffff163303610226576102216103d9565b60606102b183836040518060600160405280602781526020016109c5602791396104a5565b9392505050565b73ffffffffffffffffffffffffffffffffffffffff163b151590565b6102dc6103d9565b73ffffffffffffffffffffffffffffffffffffffff163303610133576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604260248201527f5472616e73706172656e745570677261646561626c6550726f78793a2061646d60448201527f696e2063616e6e6f742066616c6c6261636b20746f2070726f7879207461726760648201527f6574000000000000000000000000000000000000000000000000000000000000608482015260a4015b60405180910390fd5b60006102216105cd565b3660008037600080366000845af43d6000803e8080156103d4573d6000f35b3d6000fd5b60007fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035b5473ffffffffffffffffffffffffffffffffffffffff16919050565b610422836105f5565b60008251118061042f5750805b156101e65761043e838361028c565b50505050565b7f7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f61046d6103d9565b6040805173ffffffffffffffffffffffffffffffffffffffff928316815291841660208301520160405180910390a161017481610642565b606073ffffffffffffffffffffffffffffffffffffffff84163b61054b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f416464726573733a2064656c65676174652063616c6c20746f206e6f6e2d636f60448201527f6e7472616374000000000000000000000000000000000000000000000000000060648201526084016103a2565b6000808573ffffffffffffffffffffffffffffffffffffffff16856040516105739190610957565b600060405180830381855af49150503d80600081146105ae576040519150601f19603f3d011682016040523d82523d6000602084013e6105b3565b606091505b50915091506105c382828661074e565b9695505050505050565b60007f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc6103fd565b6105fe816107a1565b60405173ffffffffffffffffffffffffffffffffffffffff8216907fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b90600090a250565b73ffffffffffffffffffffffffffffffffffffffff81166106e5576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f455243313936373a206e65772061646d696e20697320746865207a65726f206160448201527f646472657373000000000000000000000000000000000000000000000000000060648201526084016103a2565b807fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035b80547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff9290921691909117905550565b6060831561075d5750816102b1565b82511561076d5782518084602001fd5b816040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016103a29190610973565b73ffffffffffffffffffffffffffffffffffffffff81163b610845576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602d60248201527f455243313936373a206e657720696d706c656d656e746174696f6e206973206e60448201527f6f74206120636f6e74726163740000000000000000000000000000000000000060648201526084016103a2565b807f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc610708565b803573ffffffffffffffffffffffffffffffffffffffff8116811461089057600080fd5b919050565b6000602082840312156108a757600080fd5b6102b18261086c565b6000806000604084860312156108c557600080fd5b6108ce8461086c565b9250602084013567ffffffffffffffff808211156108eb57600080fd5b818601915086601f8301126108ff57600080fd5b81358181111561090e57600080fd5b87602082850101111561092057600080fd5b6020830194508093505050509250925092565b60005b8381101561094e578181015183820152602001610936565b50506000910152565b60008251610969818460208701610933565b9190910192915050565b6020815260008251806020840152610992816040850160208701610933565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016919091016040019291505056fe416464726573733a206c6f772d6c6576656c2064656c65676174652063616c6c206661696c6564a2646970667358221220e96638b07fb1675d93a95c49e417bc8111448b23a59918698cdcd8fd488dd7cf64736f6c63430008110033", + "devdoc": { + "details": "This contract implements a proxy that is upgradeable by an admin. It is fully forked from OpenZeppelin `TransparentUpgradeableProxy` To avoid https://medium.com/nomic-labs-blog/malicious-backdoors-in-ethereum-proxies-62629adf3357[proxy selector clashing], which can potentially be used in an attack, this contract uses the https://blog.openzeppelin.com/the-transparent-proxy-pattern/[transparent proxy pattern]. This pattern implies two things that go hand in hand: 1. If any account other than the admin calls the proxy, the call will be forwarded to the implementation, even if that call matches one of the admin functions exposed by the proxy itself. 2. If the admin calls the proxy, it can access the admin functions, but its calls will never be forwarded to the implementation. If the admin tries to call a function on the implementation it will fail with an error that says \"admin cannot fallback to proxy target\". These properties mean that the admin account can only be used for admin actions like upgrading the proxy or changing the admin, so it's best if it's a dedicated account that is not used for anything else. This will avoid headaches due to sudden errors when trying to call a function from the proxy implementation. Our recommendation is for the dedicated account to be an instance of the {ProxyAdmin} contract. If set up this way, you should think of the `ProxyAdmin` instance as the real administrative interface of your proxy.", + "kind": "dev", + "methods": { + "admin()": { + "details": "Returns the current admin. NOTE: Only the admin can call this function. See {ProxyAdmin-getProxyAdmin}. TIP: To get this value clients can read directly from the storage slot shown below (specified by EIP1967) using the https://eth.wiki/json-rpc/API#eth_getstorageat[`eth_getStorageAt`] RPC call. `0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103`" + }, + "changeAdmin(address)": { + "details": "Changes the admin of the proxy. Emits an {AdminChanged} event. NOTE: Only the admin can call this function. See {ProxyAdmin-changeProxyAdmin}." + }, + "constructor": { + "details": "Initializes an upgradeable proxy managed by `_admin`, backed by the implementation at `_logic`, and optionally initialized with `_data` as explained in {ERC1967Proxy-constructor}." + }, + "implementation()": { + "details": "Returns the current implementation. NOTE: Only the admin can call this function. See {ProxyAdmin-getProxyImplementation}. TIP: To get this value clients can read directly from the storage slot shown below (specified by EIP1967) using the https://eth.wiki/json-rpc/API#eth_getstorageat[`eth_getStorageAt`] RPC call. `0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc`" + }, + "upgradeTo(address)": { + "details": "Upgrade the implementation of the proxy. NOTE: Only the admin can call this function. See {ProxyAdmin-upgrade}." + }, + "upgradeToAndCall(address,bytes)": { + "details": "Upgrade the implementation of the proxy, and then call a function from the new implementation as specified by `data`, which should be an encoded function call. This is useful to initialize new storage variables in the proxied contract. NOTE: Only the admin can call this function. See {ProxyAdmin-upgradeAndCall}." + } + }, + "version": 1 + }, + "userdoc": { + "kind": "user", + "methods": {}, + "version": 1 + }, + "storageLayout": { + "storage": [], + "types": null + } +} \ No newline at end of file diff --git a/deployments/polygon/solcInputs/871924e0c138825a2736b76def8fef8d.json b/deployments/polygon/solcInputs/871924e0c138825a2736b76def8fef8d.json new file mode 100644 index 00000000..57454028 --- /dev/null +++ b/deployments/polygon/solcInputs/871924e0c138825a2736b76def8fef8d.json @@ -0,0 +1,562 @@ +{ + "language": "Solidity", + "sources": { + "@chainlink/contracts/src/v0.8/interfaces/AggregatorV3Interface.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.0;\n\ninterface AggregatorV3Interface {\n\n function decimals()\n external\n view\n returns (\n uint8\n );\n\n function description()\n external\n view\n returns (\n string memory\n );\n\n function version()\n external\n view\n returns (\n uint256\n );\n\n // getRoundData and latestRoundData should both raise \"No data present\"\n // if they do not have data to report, instead of returning unset values\n // which could be misinterpreted as actual reported values.\n function getRoundData(\n uint80 _roundId\n )\n external\n view\n returns (\n uint80 roundId,\n int256 answer,\n uint256 startedAt,\n uint256 updatedAt,\n uint80 answeredInRound\n );\n\n function latestRoundData()\n external\n view\n returns (\n uint80 roundId,\n int256 answer,\n uint256 startedAt,\n uint256 updatedAt,\n uint80 answeredInRound\n );\n\n}\n" + }, + "@openzeppelin/contracts-upgradeable/access/AccessControlEnumerableUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.5.0) (access/AccessControlEnumerable.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./IAccessControlEnumerableUpgradeable.sol\";\nimport \"./AccessControlUpgradeable.sol\";\nimport \"../utils/structs/EnumerableSetUpgradeable.sol\";\nimport \"../proxy/utils/Initializable.sol\";\n\n/**\n * @dev Extension of {AccessControl} that allows enumerating the members of each role.\n */\nabstract contract AccessControlEnumerableUpgradeable is Initializable, IAccessControlEnumerableUpgradeable, AccessControlUpgradeable {\n function __AccessControlEnumerable_init() internal onlyInitializing {\n }\n\n function __AccessControlEnumerable_init_unchained() internal onlyInitializing {\n }\n using EnumerableSetUpgradeable for EnumerableSetUpgradeable.AddressSet;\n\n mapping(bytes32 => EnumerableSetUpgradeable.AddressSet) private _roleMembers;\n\n /**\n * @dev See {IERC165-supportsInterface}.\n */\n function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {\n return interfaceId == type(IAccessControlEnumerableUpgradeable).interfaceId || super.supportsInterface(interfaceId);\n }\n\n /**\n * @dev Returns one of the accounts that have `role`. `index` must be a\n * value between 0 and {getRoleMemberCount}, non-inclusive.\n *\n * Role bearers are not sorted in any particular way, and their ordering may\n * change at any point.\n *\n * WARNING: When using {getRoleMember} and {getRoleMemberCount}, make sure\n * you perform all queries on the same block. See the following\n * https://forum.openzeppelin.com/t/iterating-over-elements-on-enumerableset-in-openzeppelin-contracts/2296[forum post]\n * for more information.\n */\n function getRoleMember(bytes32 role, uint256 index) public view virtual override returns (address) {\n return _roleMembers[role].at(index);\n }\n\n /**\n * @dev Returns the number of accounts that have `role`. Can be used\n * together with {getRoleMember} to enumerate all bearers of a role.\n */\n function getRoleMemberCount(bytes32 role) public view virtual override returns (uint256) {\n return _roleMembers[role].length();\n }\n\n /**\n * @dev Overload {_grantRole} to track enumerable memberships\n */\n function _grantRole(bytes32 role, address account) internal virtual override {\n super._grantRole(role, account);\n _roleMembers[role].add(account);\n }\n\n /**\n * @dev Overload {_revokeRole} to track enumerable memberships\n */\n function _revokeRole(bytes32 role, address account) internal virtual override {\n super._revokeRole(role, account);\n _roleMembers[role].remove(account);\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[49] private __gap;\n}\n" + }, + "@openzeppelin/contracts-upgradeable/access/AccessControlUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (access/AccessControl.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./IAccessControlUpgradeable.sol\";\nimport \"../utils/ContextUpgradeable.sol\";\nimport \"../utils/StringsUpgradeable.sol\";\nimport \"../utils/introspection/ERC165Upgradeable.sol\";\nimport \"../proxy/utils/Initializable.sol\";\n\n/**\n * @dev Contract module that allows children to implement role-based access\n * control mechanisms. This is a lightweight version that doesn't allow enumerating role\n * members except through off-chain means by accessing the contract event logs. Some\n * applications may benefit from on-chain enumerability, for those cases see\n * {AccessControlEnumerable}.\n *\n * Roles are referred to by their `bytes32` identifier. These should be exposed\n * in the external API and be unique. The best way to achieve this is by\n * using `public constant` hash digests:\n *\n * ```\n * bytes32 public constant MY_ROLE = keccak256(\"MY_ROLE\");\n * ```\n *\n * Roles can be used to represent a set of permissions. To restrict access to a\n * function call, use {hasRole}:\n *\n * ```\n * function foo() public {\n * require(hasRole(MY_ROLE, msg.sender));\n * ...\n * }\n * ```\n *\n * Roles can be granted and revoked dynamically via the {grantRole} and\n * {revokeRole} functions. Each role has an associated admin role, and only\n * accounts that have a role's admin role can call {grantRole} and {revokeRole}.\n *\n * By default, the admin role for all roles is `DEFAULT_ADMIN_ROLE`, which means\n * that only accounts with this role will be able to grant or revoke other\n * roles. More complex role relationships can be created by using\n * {_setRoleAdmin}.\n *\n * WARNING: The `DEFAULT_ADMIN_ROLE` is also its own admin: it has permission to\n * grant and revoke this role. Extra precautions should be taken to secure\n * accounts that have been granted it.\n */\nabstract contract AccessControlUpgradeable is Initializable, ContextUpgradeable, IAccessControlUpgradeable, ERC165Upgradeable {\n function __AccessControl_init() internal onlyInitializing {\n }\n\n function __AccessControl_init_unchained() internal onlyInitializing {\n }\n struct RoleData {\n mapping(address => bool) members;\n bytes32 adminRole;\n }\n\n mapping(bytes32 => RoleData) private _roles;\n\n bytes32 public constant DEFAULT_ADMIN_ROLE = 0x00;\n\n /**\n * @dev Modifier that checks that an account has a specific role. Reverts\n * with a standardized message including the required role.\n *\n * The format of the revert reason is given by the following regular expression:\n *\n * /^AccessControl: account (0x[0-9a-f]{40}) is missing role (0x[0-9a-f]{64})$/\n *\n * _Available since v4.1._\n */\n modifier onlyRole(bytes32 role) {\n _checkRole(role);\n _;\n }\n\n /**\n * @dev See {IERC165-supportsInterface}.\n */\n function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {\n return interfaceId == type(IAccessControlUpgradeable).interfaceId || super.supportsInterface(interfaceId);\n }\n\n /**\n * @dev Returns `true` if `account` has been granted `role`.\n */\n function hasRole(bytes32 role, address account) public view virtual override returns (bool) {\n return _roles[role].members[account];\n }\n\n /**\n * @dev Revert with a standard message if `_msgSender()` is missing `role`.\n * Overriding this function changes the behavior of the {onlyRole} modifier.\n *\n * Format of the revert message is described in {_checkRole}.\n *\n * _Available since v4.6._\n */\n function _checkRole(bytes32 role) internal view virtual {\n _checkRole(role, _msgSender());\n }\n\n /**\n * @dev Revert with a standard message if `account` is missing `role`.\n *\n * The format of the revert reason is given by the following regular expression:\n *\n * /^AccessControl: account (0x[0-9a-f]{40}) is missing role (0x[0-9a-f]{64})$/\n */\n function _checkRole(bytes32 role, address account) internal view virtual {\n if (!hasRole(role, account)) {\n revert(\n string(\n abi.encodePacked(\n \"AccessControl: account \",\n StringsUpgradeable.toHexString(uint160(account), 20),\n \" is missing role \",\n StringsUpgradeable.toHexString(uint256(role), 32)\n )\n )\n );\n }\n }\n\n /**\n * @dev Returns the admin role that controls `role`. See {grantRole} and\n * {revokeRole}.\n *\n * To change a role's admin, use {_setRoleAdmin}.\n */\n function getRoleAdmin(bytes32 role) public view virtual override returns (bytes32) {\n return _roles[role].adminRole;\n }\n\n /**\n * @dev Grants `role` to `account`.\n *\n * If `account` had not been already granted `role`, emits a {RoleGranted}\n * event.\n *\n * Requirements:\n *\n * - the caller must have ``role``'s admin role.\n *\n * May emit a {RoleGranted} event.\n */\n function grantRole(bytes32 role, address account) public virtual override onlyRole(getRoleAdmin(role)) {\n _grantRole(role, account);\n }\n\n /**\n * @dev Revokes `role` from `account`.\n *\n * If `account` had been granted `role`, emits a {RoleRevoked} event.\n *\n * Requirements:\n *\n * - the caller must have ``role``'s admin role.\n *\n * May emit a {RoleRevoked} event.\n */\n function revokeRole(bytes32 role, address account) public virtual override onlyRole(getRoleAdmin(role)) {\n _revokeRole(role, account);\n }\n\n /**\n * @dev Revokes `role` from the calling account.\n *\n * Roles are often managed via {grantRole} and {revokeRole}: this function's\n * purpose is to provide a mechanism for accounts to lose their privileges\n * if they are compromised (such as when a trusted device is misplaced).\n *\n * If the calling account had been revoked `role`, emits a {RoleRevoked}\n * event.\n *\n * Requirements:\n *\n * - the caller must be `account`.\n *\n * May emit a {RoleRevoked} event.\n */\n function renounceRole(bytes32 role, address account) public virtual override {\n require(account == _msgSender(), \"AccessControl: can only renounce roles for self\");\n\n _revokeRole(role, account);\n }\n\n /**\n * @dev Grants `role` to `account`.\n *\n * If `account` had not been already granted `role`, emits a {RoleGranted}\n * event. Note that unlike {grantRole}, this function doesn't perform any\n * checks on the calling account.\n *\n * May emit a {RoleGranted} event.\n *\n * [WARNING]\n * ====\n * This function should only be called from the constructor when setting\n * up the initial roles for the system.\n *\n * Using this function in any other way is effectively circumventing the admin\n * system imposed by {AccessControl}.\n * ====\n *\n * NOTE: This function is deprecated in favor of {_grantRole}.\n */\n function _setupRole(bytes32 role, address account) internal virtual {\n _grantRole(role, account);\n }\n\n /**\n * @dev Sets `adminRole` as ``role``'s admin role.\n *\n * Emits a {RoleAdminChanged} event.\n */\n function _setRoleAdmin(bytes32 role, bytes32 adminRole) internal virtual {\n bytes32 previousAdminRole = getRoleAdmin(role);\n _roles[role].adminRole = adminRole;\n emit RoleAdminChanged(role, previousAdminRole, adminRole);\n }\n\n /**\n * @dev Grants `role` to `account`.\n *\n * Internal function without access restriction.\n *\n * May emit a {RoleGranted} event.\n */\n function _grantRole(bytes32 role, address account) internal virtual {\n if (!hasRole(role, account)) {\n _roles[role].members[account] = true;\n emit RoleGranted(role, account, _msgSender());\n }\n }\n\n /**\n * @dev Revokes `role` from `account`.\n *\n * Internal function without access restriction.\n *\n * May emit a {RoleRevoked} event.\n */\n function _revokeRole(bytes32 role, address account) internal virtual {\n if (hasRole(role, account)) {\n _roles[role].members[account] = false;\n emit RoleRevoked(role, account, _msgSender());\n }\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[49] private __gap;\n}\n" + }, + "@openzeppelin/contracts-upgradeable/access/IAccessControlEnumerableUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (access/IAccessControlEnumerable.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./IAccessControlUpgradeable.sol\";\n\n/**\n * @dev External interface of AccessControlEnumerable declared to support ERC165 detection.\n */\ninterface IAccessControlEnumerableUpgradeable is IAccessControlUpgradeable {\n /**\n * @dev Returns one of the accounts that have `role`. `index` must be a\n * value between 0 and {getRoleMemberCount}, non-inclusive.\n *\n * Role bearers are not sorted in any particular way, and their ordering may\n * change at any point.\n *\n * WARNING: When using {getRoleMember} and {getRoleMemberCount}, make sure\n * you perform all queries on the same block. See the following\n * https://forum.openzeppelin.com/t/iterating-over-elements-on-enumerableset-in-openzeppelin-contracts/2296[forum post]\n * for more information.\n */\n function getRoleMember(bytes32 role, uint256 index) external view returns (address);\n\n /**\n * @dev Returns the number of accounts that have `role`. Can be used\n * together with {getRoleMember} to enumerate all bearers of a role.\n */\n function getRoleMemberCount(bytes32 role) external view returns (uint256);\n}\n" + }, + "@openzeppelin/contracts-upgradeable/access/IAccessControlUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (access/IAccessControl.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev External interface of AccessControl declared to support ERC165 detection.\n */\ninterface IAccessControlUpgradeable {\n /**\n * @dev Emitted when `newAdminRole` is set as ``role``'s admin role, replacing `previousAdminRole`\n *\n * `DEFAULT_ADMIN_ROLE` is the starting admin for all roles, despite\n * {RoleAdminChanged} not being emitted signaling this.\n *\n * _Available since v3.1._\n */\n event RoleAdminChanged(bytes32 indexed role, bytes32 indexed previousAdminRole, bytes32 indexed newAdminRole);\n\n /**\n * @dev Emitted when `account` is granted `role`.\n *\n * `sender` is the account that originated the contract call, an admin role\n * bearer except when using {AccessControl-_setupRole}.\n */\n event RoleGranted(bytes32 indexed role, address indexed account, address indexed sender);\n\n /**\n * @dev Emitted when `account` is revoked `role`.\n *\n * `sender` is the account that originated the contract call:\n * - if using `revokeRole`, it is the admin role bearer\n * - if using `renounceRole`, it is the role bearer (i.e. `account`)\n */\n event RoleRevoked(bytes32 indexed role, address indexed account, address indexed sender);\n\n /**\n * @dev Returns `true` if `account` has been granted `role`.\n */\n function hasRole(bytes32 role, address account) external view returns (bool);\n\n /**\n * @dev Returns the admin role that controls `role`. See {grantRole} and\n * {revokeRole}.\n *\n * To change a role's admin, use {AccessControl-_setRoleAdmin}.\n */\n function getRoleAdmin(bytes32 role) external view returns (bytes32);\n\n /**\n * @dev Grants `role` to `account`.\n *\n * If `account` had not been already granted `role`, emits a {RoleGranted}\n * event.\n *\n * Requirements:\n *\n * - the caller must have ``role``'s admin role.\n */\n function grantRole(bytes32 role, address account) external;\n\n /**\n * @dev Revokes `role` from `account`.\n *\n * If `account` had been granted `role`, emits a {RoleRevoked} event.\n *\n * Requirements:\n *\n * - the caller must have ``role``'s admin role.\n */\n function revokeRole(bytes32 role, address account) external;\n\n /**\n * @dev Revokes `role` from the calling account.\n *\n * Roles are often managed via {grantRole} and {revokeRole}: this function's\n * purpose is to provide a mechanism for accounts to lose their privileges\n * if they are compromised (such as when a trusted device is misplaced).\n *\n * If the calling account had been granted `role`, emits a {RoleRevoked}\n * event.\n *\n * Requirements:\n *\n * - the caller must be `account`.\n */\n function renounceRole(bytes32 role, address account) external;\n}\n" + }, + "@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (access/Ownable.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../utils/ContextUpgradeable.sol\";\nimport \"../proxy/utils/Initializable.sol\";\n\n/**\n * @dev Contract module which provides a basic access control mechanism, where\n * there is an account (an owner) that can be granted exclusive access to\n * specific functions.\n *\n * By default, the owner account will be the one that deploys the contract. This\n * can later be changed with {transferOwnership}.\n *\n * This module is used through inheritance. It will make available the modifier\n * `onlyOwner`, which can be applied to your functions to restrict their use to\n * the owner.\n */\nabstract contract OwnableUpgradeable is Initializable, ContextUpgradeable {\n address private _owner;\n\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\n\n /**\n * @dev Initializes the contract setting the deployer as the initial owner.\n */\n function __Ownable_init() internal onlyInitializing {\n __Ownable_init_unchained();\n }\n\n function __Ownable_init_unchained() internal onlyInitializing {\n _transferOwnership(_msgSender());\n }\n\n /**\n * @dev Throws if called by any account other than the owner.\n */\n modifier onlyOwner() {\n _checkOwner();\n _;\n }\n\n /**\n * @dev Returns the address of the current owner.\n */\n function owner() public view virtual returns (address) {\n return _owner;\n }\n\n /**\n * @dev Throws if the sender is not the owner.\n */\n function _checkOwner() internal view virtual {\n require(owner() == _msgSender(), \"Ownable: caller is not the owner\");\n }\n\n /**\n * @dev Leaves the contract without owner. It will not be possible to call\n * `onlyOwner` functions anymore. Can only be called by the current owner.\n *\n * NOTE: Renouncing ownership will leave the contract without an owner,\n * thereby removing any functionality that is only available to the owner.\n */\n function renounceOwnership() public virtual onlyOwner {\n _transferOwnership(address(0));\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Can only be called by the current owner.\n */\n function transferOwnership(address newOwner) public virtual onlyOwner {\n require(newOwner != address(0), \"Ownable: new owner is the zero address\");\n _transferOwnership(newOwner);\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Internal function without access restriction.\n */\n function _transferOwnership(address newOwner) internal virtual {\n address oldOwner = _owner;\n _owner = newOwner;\n emit OwnershipTransferred(oldOwner, newOwner);\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[49] private __gap;\n}\n" + }, + "@openzeppelin/contracts-upgradeable/interfaces/IERC721MetadataUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (interfaces/IERC721Metadata.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../token/ERC721/extensions/IERC721MetadataUpgradeable.sol\";\n" + }, + "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (proxy/utils/Initializable.sol)\n\npragma solidity ^0.8.2;\n\nimport \"../../utils/AddressUpgradeable.sol\";\n\n/**\n * @dev This is a base contract to aid in writing upgradeable contracts, or any kind of contract that will be deployed\n * behind a proxy. Since proxied contracts do not make use of a constructor, it's common to move constructor logic to an\n * external initializer function, usually called `initialize`. It then becomes necessary to protect this initializer\n * function so it can only be called once. The {initializer} modifier provided by this contract will have this effect.\n *\n * The initialization functions use a version number. Once a version number is used, it is consumed and cannot be\n * reused. This mechanism prevents re-execution of each \"step\" but allows the creation of new initialization steps in\n * case an upgrade adds a module that needs to be initialized.\n *\n * For example:\n *\n * [.hljs-theme-light.nopadding]\n * ```\n * contract MyToken is ERC20Upgradeable {\n * function initialize() initializer public {\n * __ERC20_init(\"MyToken\", \"MTK\");\n * }\n * }\n * contract MyTokenV2 is MyToken, ERC20PermitUpgradeable {\n * function initializeV2() reinitializer(2) public {\n * __ERC20Permit_init(\"MyToken\");\n * }\n * }\n * ```\n *\n * TIP: To avoid leaving the proxy in an uninitialized state, the initializer function should be called as early as\n * possible by providing the encoded function call as the `_data` argument to {ERC1967Proxy-constructor}.\n *\n * CAUTION: When used with inheritance, manual care must be taken to not invoke a parent initializer twice, or to ensure\n * that all initializers are idempotent. This is not verified automatically as constructors are by Solidity.\n *\n * [CAUTION]\n * ====\n * Avoid leaving a contract uninitialized.\n *\n * An uninitialized contract can be taken over by an attacker. This applies to both a proxy and its implementation\n * contract, which may impact the proxy. To prevent the implementation contract from being used, you should invoke\n * the {_disableInitializers} function in the constructor to automatically lock it when it is deployed:\n *\n * [.hljs-theme-light.nopadding]\n * ```\n * /// @custom:oz-upgrades-unsafe-allow constructor\n * constructor() {\n * _disableInitializers();\n * }\n * ```\n * ====\n */\nabstract contract Initializable {\n /**\n * @dev Indicates that the contract has been initialized.\n * @custom:oz-retyped-from bool\n */\n uint8 private _initialized;\n\n /**\n * @dev Indicates that the contract is in the process of being initialized.\n */\n bool private _initializing;\n\n /**\n * @dev Triggered when the contract has been initialized or reinitialized.\n */\n event Initialized(uint8 version);\n\n /**\n * @dev A modifier that defines a protected initializer function that can be invoked at most once. In its scope,\n * `onlyInitializing` functions can be used to initialize parent contracts. Equivalent to `reinitializer(1)`.\n */\n modifier initializer() {\n bool isTopLevelCall = !_initializing;\n require(\n (isTopLevelCall && _initialized < 1) || (!AddressUpgradeable.isContract(address(this)) && _initialized == 1),\n \"Initializable: contract is already initialized\"\n );\n _initialized = 1;\n if (isTopLevelCall) {\n _initializing = true;\n }\n _;\n if (isTopLevelCall) {\n _initializing = false;\n emit Initialized(1);\n }\n }\n\n /**\n * @dev A modifier that defines a protected reinitializer function that can be invoked at most once, and only if the\n * contract hasn't been initialized to a greater version before. In its scope, `onlyInitializing` functions can be\n * used to initialize parent contracts.\n *\n * `initializer` is equivalent to `reinitializer(1)`, so a reinitializer may be used after the original\n * initialization step. This is essential to configure modules that are added through upgrades and that require\n * initialization.\n *\n * Note that versions can jump in increments greater than 1; this implies that if multiple reinitializers coexist in\n * a contract, executing them in the right order is up to the developer or operator.\n */\n modifier reinitializer(uint8 version) {\n require(!_initializing && _initialized < version, \"Initializable: contract is already initialized\");\n _initialized = version;\n _initializing = true;\n _;\n _initializing = false;\n emit Initialized(version);\n }\n\n /**\n * @dev Modifier to protect an initialization function so that it can only be invoked by functions with the\n * {initializer} and {reinitializer} modifiers, directly or indirectly.\n */\n modifier onlyInitializing() {\n require(_initializing, \"Initializable: contract is not initializing\");\n _;\n }\n\n /**\n * @dev Locks the contract, preventing any future reinitialization. This cannot be part of an initializer call.\n * Calling this in the constructor of a contract will prevent that contract from being initialized or reinitialized\n * to any version. It is recommended to use this to lock implementation contracts that are designed to be called\n * through proxies.\n */\n function _disableInitializers() internal virtual {\n require(!_initializing, \"Initializable: contract is initializing\");\n if (_initialized < type(uint8).max) {\n _initialized = type(uint8).max;\n emit Initialized(type(uint8).max);\n }\n }\n}\n" + }, + "@openzeppelin/contracts-upgradeable/security/PausableUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (security/Pausable.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../utils/ContextUpgradeable.sol\";\nimport \"../proxy/utils/Initializable.sol\";\n\n/**\n * @dev Contract module which allows children to implement an emergency stop\n * mechanism that can be triggered by an authorized account.\n *\n * This module is used through inheritance. It will make available the\n * modifiers `whenNotPaused` and `whenPaused`, which can be applied to\n * the functions of your contract. Note that they will not be pausable by\n * simply including this module, only once the modifiers are put in place.\n */\nabstract contract PausableUpgradeable is Initializable, ContextUpgradeable {\n /**\n * @dev Emitted when the pause is triggered by `account`.\n */\n event Paused(address account);\n\n /**\n * @dev Emitted when the pause is lifted by `account`.\n */\n event Unpaused(address account);\n\n bool private _paused;\n\n /**\n * @dev Initializes the contract in unpaused state.\n */\n function __Pausable_init() internal onlyInitializing {\n __Pausable_init_unchained();\n }\n\n function __Pausable_init_unchained() internal onlyInitializing {\n _paused = false;\n }\n\n /**\n * @dev Modifier to make a function callable only when the contract is not paused.\n *\n * Requirements:\n *\n * - The contract must not be paused.\n */\n modifier whenNotPaused() {\n _requireNotPaused();\n _;\n }\n\n /**\n * @dev Modifier to make a function callable only when the contract is paused.\n *\n * Requirements:\n *\n * - The contract must be paused.\n */\n modifier whenPaused() {\n _requirePaused();\n _;\n }\n\n /**\n * @dev Returns true if the contract is paused, and false otherwise.\n */\n function paused() public view virtual returns (bool) {\n return _paused;\n }\n\n /**\n * @dev Throws if the contract is paused.\n */\n function _requireNotPaused() internal view virtual {\n require(!paused(), \"Pausable: paused\");\n }\n\n /**\n * @dev Throws if the contract is not paused.\n */\n function _requirePaused() internal view virtual {\n require(paused(), \"Pausable: not paused\");\n }\n\n /**\n * @dev Triggers stopped state.\n *\n * Requirements:\n *\n * - The contract must not be paused.\n */\n function _pause() internal virtual whenNotPaused {\n _paused = true;\n emit Paused(_msgSender());\n }\n\n /**\n * @dev Returns to normal state.\n *\n * Requirements:\n *\n * - The contract must be paused.\n */\n function _unpause() internal virtual whenPaused {\n _paused = false;\n emit Unpaused(_msgSender());\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[49] private __gap;\n}\n" + }, + "@openzeppelin/contracts-upgradeable/security/ReentrancyGuardUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (security/ReentrancyGuard.sol)\n\npragma solidity ^0.8.0;\nimport \"../proxy/utils/Initializable.sol\";\n\n/**\n * @dev Contract module that helps prevent reentrant calls to a function.\n *\n * Inheriting from `ReentrancyGuard` will make the {nonReentrant} modifier\n * available, which can be applied to functions to make sure there are no nested\n * (reentrant) calls to them.\n *\n * Note that because there is a single `nonReentrant` guard, functions marked as\n * `nonReentrant` may not call one another. This can be worked around by making\n * those functions `private`, and then adding `external` `nonReentrant` entry\n * points to them.\n *\n * TIP: If you would like to learn more about reentrancy and alternative ways\n * to protect against it, check out our blog post\n * https://blog.openzeppelin.com/reentrancy-after-istanbul/[Reentrancy After Istanbul].\n */\nabstract contract ReentrancyGuardUpgradeable is Initializable {\n // Booleans are more expensive than uint256 or any type that takes up a full\n // word because each write operation emits an extra SLOAD to first read the\n // slot's contents, replace the bits taken up by the boolean, and then write\n // back. This is the compiler's defense against contract upgrades and\n // pointer aliasing, and it cannot be disabled.\n\n // The values being non-zero value makes deployment a bit more expensive,\n // but in exchange the refund on every call to nonReentrant will be lower in\n // amount. Since refunds are capped to a percentage of the total\n // transaction's gas, it is best to keep them low in cases like this one, to\n // increase the likelihood of the full refund coming into effect.\n uint256 private constant _NOT_ENTERED = 1;\n uint256 private constant _ENTERED = 2;\n\n uint256 private _status;\n\n function __ReentrancyGuard_init() internal onlyInitializing {\n __ReentrancyGuard_init_unchained();\n }\n\n function __ReentrancyGuard_init_unchained() internal onlyInitializing {\n _status = _NOT_ENTERED;\n }\n\n /**\n * @dev Prevents a contract from calling itself, directly or indirectly.\n * Calling a `nonReentrant` function from another `nonReentrant`\n * function is not supported. It is possible to prevent this from happening\n * by making the `nonReentrant` function external, and making it call a\n * `private` function that does the actual work.\n */\n modifier nonReentrant() {\n // On the first call to nonReentrant, _notEntered will be true\n require(_status != _ENTERED, \"ReentrancyGuard: reentrant call\");\n\n // Any calls to nonReentrant after this point will fail\n _status = _ENTERED;\n\n _;\n\n // By storing the original value once again, a refund is triggered (see\n // https://eips.ethereum.org/EIPS/eip-2200)\n _status = _NOT_ENTERED;\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[49] private __gap;\n}\n" + }, + "@openzeppelin/contracts-upgradeable/token/ERC20/ERC20Upgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (token/ERC20/ERC20.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./IERC20Upgradeable.sol\";\nimport \"./extensions/IERC20MetadataUpgradeable.sol\";\nimport \"../../utils/ContextUpgradeable.sol\";\nimport \"../../proxy/utils/Initializable.sol\";\n\n/**\n * @dev Implementation of the {IERC20} interface.\n *\n * This implementation is agnostic to the way tokens are created. This means\n * that a supply mechanism has to be added in a derived contract using {_mint}.\n * For a generic mechanism see {ERC20PresetMinterPauser}.\n *\n * TIP: For a detailed writeup see our guide\n * https://forum.zeppelin.solutions/t/how-to-implement-erc20-supply-mechanisms/226[How\n * to implement supply mechanisms].\n *\n * We have followed general OpenZeppelin Contracts guidelines: functions revert\n * instead returning `false` on failure. This behavior is nonetheless\n * conventional and does not conflict with the expectations of ERC20\n * applications.\n *\n * Additionally, an {Approval} event is emitted on calls to {transferFrom}.\n * This allows applications to reconstruct the allowance for all accounts just\n * by listening to said events. Other implementations of the EIP may not emit\n * these events, as it isn't required by the specification.\n *\n * Finally, the non-standard {decreaseAllowance} and {increaseAllowance}\n * functions have been added to mitigate the well-known issues around setting\n * allowances. See {IERC20-approve}.\n */\ncontract ERC20Upgradeable is Initializable, ContextUpgradeable, IERC20Upgradeable, IERC20MetadataUpgradeable {\n mapping(address => uint256) private _balances;\n\n mapping(address => mapping(address => uint256)) private _allowances;\n\n uint256 private _totalSupply;\n\n string private _name;\n string private _symbol;\n\n /**\n * @dev Sets the values for {name} and {symbol}.\n *\n * The default value of {decimals} is 18. To select a different value for\n * {decimals} you should overload it.\n *\n * All two of these values are immutable: they can only be set once during\n * construction.\n */\n function __ERC20_init(string memory name_, string memory symbol_) internal onlyInitializing {\n __ERC20_init_unchained(name_, symbol_);\n }\n\n function __ERC20_init_unchained(string memory name_, string memory symbol_) internal onlyInitializing {\n _name = name_;\n _symbol = symbol_;\n }\n\n /**\n * @dev Returns the name of the token.\n */\n function name() public view virtual override returns (string memory) {\n return _name;\n }\n\n /**\n * @dev Returns the symbol of the token, usually a shorter version of the\n * name.\n */\n function symbol() public view virtual override returns (string memory) {\n return _symbol;\n }\n\n /**\n * @dev Returns the number of decimals used to get its user representation.\n * For example, if `decimals` equals `2`, a balance of `505` tokens should\n * be displayed to a user as `5.05` (`505 / 10 ** 2`).\n *\n * Tokens usually opt for a value of 18, imitating the relationship between\n * Ether and Wei. This is the value {ERC20} uses, unless this function is\n * overridden;\n *\n * NOTE: This information is only used for _display_ purposes: it in\n * no way affects any of the arithmetic of the contract, including\n * {IERC20-balanceOf} and {IERC20-transfer}.\n */\n function decimals() public view virtual override returns (uint8) {\n return 18;\n }\n\n /**\n * @dev See {IERC20-totalSupply}.\n */\n function totalSupply() public view virtual override returns (uint256) {\n return _totalSupply;\n }\n\n /**\n * @dev See {IERC20-balanceOf}.\n */\n function balanceOf(address account) public view virtual override returns (uint256) {\n return _balances[account];\n }\n\n /**\n * @dev See {IERC20-transfer}.\n *\n * Requirements:\n *\n * - `to` cannot be the zero address.\n * - the caller must have a balance of at least `amount`.\n */\n function transfer(address to, uint256 amount) public virtual override returns (bool) {\n address owner = _msgSender();\n _transfer(owner, to, amount);\n return true;\n }\n\n /**\n * @dev See {IERC20-allowance}.\n */\n function allowance(address owner, address spender) public view virtual override returns (uint256) {\n return _allowances[owner][spender];\n }\n\n /**\n * @dev See {IERC20-approve}.\n *\n * NOTE: If `amount` is the maximum `uint256`, the allowance is not updated on\n * `transferFrom`. This is semantically equivalent to an infinite approval.\n *\n * Requirements:\n *\n * - `spender` cannot be the zero address.\n */\n function approve(address spender, uint256 amount) public virtual override returns (bool) {\n address owner = _msgSender();\n _approve(owner, spender, amount);\n return true;\n }\n\n /**\n * @dev See {IERC20-transferFrom}.\n *\n * Emits an {Approval} event indicating the updated allowance. This is not\n * required by the EIP. See the note at the beginning of {ERC20}.\n *\n * NOTE: Does not update the allowance if the current allowance\n * is the maximum `uint256`.\n *\n * Requirements:\n *\n * - `from` and `to` cannot be the zero address.\n * - `from` must have a balance of at least `amount`.\n * - the caller must have allowance for ``from``'s tokens of at least\n * `amount`.\n */\n function transferFrom(\n address from,\n address to,\n uint256 amount\n ) public virtual override returns (bool) {\n address spender = _msgSender();\n _spendAllowance(from, spender, amount);\n _transfer(from, to, amount);\n return true;\n }\n\n /**\n * @dev Atomically increases the allowance granted to `spender` by the caller.\n *\n * This is an alternative to {approve} that can be used as a mitigation for\n * problems described in {IERC20-approve}.\n *\n * Emits an {Approval} event indicating the updated allowance.\n *\n * Requirements:\n *\n * - `spender` cannot be the zero address.\n */\n function increaseAllowance(address spender, uint256 addedValue) public virtual returns (bool) {\n address owner = _msgSender();\n _approve(owner, spender, allowance(owner, spender) + addedValue);\n return true;\n }\n\n /**\n * @dev Atomically decreases the allowance granted to `spender` by the caller.\n *\n * This is an alternative to {approve} that can be used as a mitigation for\n * problems described in {IERC20-approve}.\n *\n * Emits an {Approval} event indicating the updated allowance.\n *\n * Requirements:\n *\n * - `spender` cannot be the zero address.\n * - `spender` must have allowance for the caller of at least\n * `subtractedValue`.\n */\n function decreaseAllowance(address spender, uint256 subtractedValue) public virtual returns (bool) {\n address owner = _msgSender();\n uint256 currentAllowance = allowance(owner, spender);\n require(currentAllowance >= subtractedValue, \"ERC20: decreased allowance below zero\");\n unchecked {\n _approve(owner, spender, currentAllowance - subtractedValue);\n }\n\n return true;\n }\n\n /**\n * @dev Moves `amount` of tokens from `from` to `to`.\n *\n * This internal function is equivalent to {transfer}, and can be used to\n * e.g. implement automatic token fees, slashing mechanisms, etc.\n *\n * Emits a {Transfer} event.\n *\n * Requirements:\n *\n * - `from` cannot be the zero address.\n * - `to` cannot be the zero address.\n * - `from` must have a balance of at least `amount`.\n */\n function _transfer(\n address from,\n address to,\n uint256 amount\n ) internal virtual {\n require(from != address(0), \"ERC20: transfer from the zero address\");\n require(to != address(0), \"ERC20: transfer to the zero address\");\n\n _beforeTokenTransfer(from, to, amount);\n\n uint256 fromBalance = _balances[from];\n require(fromBalance >= amount, \"ERC20: transfer amount exceeds balance\");\n unchecked {\n _balances[from] = fromBalance - amount;\n }\n _balances[to] += amount;\n\n emit Transfer(from, to, amount);\n\n _afterTokenTransfer(from, to, amount);\n }\n\n /** @dev Creates `amount` tokens and assigns them to `account`, increasing\n * the total supply.\n *\n * Emits a {Transfer} event with `from` set to the zero address.\n *\n * Requirements:\n *\n * - `account` cannot be the zero address.\n */\n function _mint(address account, uint256 amount) internal virtual {\n require(account != address(0), \"ERC20: mint to the zero address\");\n\n _beforeTokenTransfer(address(0), account, amount);\n\n _totalSupply += amount;\n _balances[account] += amount;\n emit Transfer(address(0), account, amount);\n\n _afterTokenTransfer(address(0), account, amount);\n }\n\n /**\n * @dev Destroys `amount` tokens from `account`, reducing the\n * total supply.\n *\n * Emits a {Transfer} event with `to` set to the zero address.\n *\n * Requirements:\n *\n * - `account` cannot be the zero address.\n * - `account` must have at least `amount` tokens.\n */\n function _burn(address account, uint256 amount) internal virtual {\n require(account != address(0), \"ERC20: burn from the zero address\");\n\n _beforeTokenTransfer(account, address(0), amount);\n\n uint256 accountBalance = _balances[account];\n require(accountBalance >= amount, \"ERC20: burn amount exceeds balance\");\n unchecked {\n _balances[account] = accountBalance - amount;\n }\n _totalSupply -= amount;\n\n emit Transfer(account, address(0), amount);\n\n _afterTokenTransfer(account, address(0), amount);\n }\n\n /**\n * @dev Sets `amount` as the allowance of `spender` over the `owner` s tokens.\n *\n * This internal function is equivalent to `approve`, and can be used to\n * e.g. set automatic allowances for certain subsystems, etc.\n *\n * Emits an {Approval} event.\n *\n * Requirements:\n *\n * - `owner` cannot be the zero address.\n * - `spender` cannot be the zero address.\n */\n function _approve(\n address owner,\n address spender,\n uint256 amount\n ) internal virtual {\n require(owner != address(0), \"ERC20: approve from the zero address\");\n require(spender != address(0), \"ERC20: approve to the zero address\");\n\n _allowances[owner][spender] = amount;\n emit Approval(owner, spender, amount);\n }\n\n /**\n * @dev Updates `owner` s allowance for `spender` based on spent `amount`.\n *\n * Does not update the allowance amount in case of infinite allowance.\n * Revert if not enough allowance is available.\n *\n * Might emit an {Approval} event.\n */\n function _spendAllowance(\n address owner,\n address spender,\n uint256 amount\n ) internal virtual {\n uint256 currentAllowance = allowance(owner, spender);\n if (currentAllowance != type(uint256).max) {\n require(currentAllowance >= amount, \"ERC20: insufficient allowance\");\n unchecked {\n _approve(owner, spender, currentAllowance - amount);\n }\n }\n }\n\n /**\n * @dev Hook that is called before any transfer of tokens. This includes\n * minting and burning.\n *\n * Calling conditions:\n *\n * - when `from` and `to` are both non-zero, `amount` of ``from``'s tokens\n * will be transferred to `to`.\n * - when `from` is zero, `amount` tokens will be minted for `to`.\n * - when `to` is zero, `amount` of ``from``'s tokens will be burned.\n * - `from` and `to` are never both zero.\n *\n * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].\n */\n function _beforeTokenTransfer(\n address from,\n address to,\n uint256 amount\n ) internal virtual {}\n\n /**\n * @dev Hook that is called after any transfer of tokens. This includes\n * minting and burning.\n *\n * Calling conditions:\n *\n * - when `from` and `to` are both non-zero, `amount` of ``from``'s tokens\n * has been transferred to `to`.\n * - when `from` is zero, `amount` tokens have been minted for `to`.\n * - when `to` is zero, `amount` of ``from``'s tokens have been burned.\n * - `from` and `to` are never both zero.\n *\n * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].\n */\n function _afterTokenTransfer(\n address from,\n address to,\n uint256 amount\n ) internal virtual {}\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[45] private __gap;\n}\n" + }, + "@openzeppelin/contracts-upgradeable/token/ERC20/extensions/draft-ERC20PermitUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.6.0) (token/ERC20/extensions/draft-ERC20Permit.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./draft-IERC20PermitUpgradeable.sol\";\nimport \"../ERC20Upgradeable.sol\";\nimport \"../../../utils/cryptography/draft-EIP712Upgradeable.sol\";\nimport \"../../../utils/cryptography/ECDSAUpgradeable.sol\";\nimport \"../../../utils/CountersUpgradeable.sol\";\nimport \"../../../proxy/utils/Initializable.sol\";\n\n/**\n * @dev Implementation of the ERC20 Permit extension allowing approvals to be made via signatures, as defined in\n * https://eips.ethereum.org/EIPS/eip-2612[EIP-2612].\n *\n * Adds the {permit} method, which can be used to change an account's ERC20 allowance (see {IERC20-allowance}) by\n * presenting a message signed by the account. By not relying on `{IERC20-approve}`, the token holder account doesn't\n * need to send a transaction, and thus is not required to hold Ether at all.\n *\n * _Available since v3.4._\n *\n * @custom:storage-size 51\n */\nabstract contract ERC20PermitUpgradeable is Initializable, ERC20Upgradeable, IERC20PermitUpgradeable, EIP712Upgradeable {\n using CountersUpgradeable for CountersUpgradeable.Counter;\n\n mapping(address => CountersUpgradeable.Counter) private _nonces;\n\n // solhint-disable-next-line var-name-mixedcase\n bytes32 private constant _PERMIT_TYPEHASH =\n keccak256(\"Permit(address owner,address spender,uint256 value,uint256 nonce,uint256 deadline)\");\n /**\n * @dev In previous versions `_PERMIT_TYPEHASH` was declared as `immutable`.\n * However, to ensure consistency with the upgradeable transpiler, we will continue\n * to reserve a slot.\n * @custom:oz-renamed-from _PERMIT_TYPEHASH\n */\n // solhint-disable-next-line var-name-mixedcase\n bytes32 private _PERMIT_TYPEHASH_DEPRECATED_SLOT;\n\n /**\n * @dev Initializes the {EIP712} domain separator using the `name` parameter, and setting `version` to `\"1\"`.\n *\n * It's a good idea to use the same `name` that is defined as the ERC20 token name.\n */\n function __ERC20Permit_init(string memory name) internal onlyInitializing {\n __EIP712_init_unchained(name, \"1\");\n }\n\n function __ERC20Permit_init_unchained(string memory) internal onlyInitializing {}\n\n /**\n * @dev See {IERC20Permit-permit}.\n */\n function permit(\n address owner,\n address spender,\n uint256 value,\n uint256 deadline,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) public virtual override {\n require(block.timestamp <= deadline, \"ERC20Permit: expired deadline\");\n\n bytes32 structHash = keccak256(abi.encode(_PERMIT_TYPEHASH, owner, spender, value, _useNonce(owner), deadline));\n\n bytes32 hash = _hashTypedDataV4(structHash);\n\n address signer = ECDSAUpgradeable.recover(hash, v, r, s);\n require(signer == owner, \"ERC20Permit: invalid signature\");\n\n _approve(owner, spender, value);\n }\n\n /**\n * @dev See {IERC20Permit-nonces}.\n */\n function nonces(address owner) public view virtual override returns (uint256) {\n return _nonces[owner].current();\n }\n\n /**\n * @dev See {IERC20Permit-DOMAIN_SEPARATOR}.\n */\n // solhint-disable-next-line func-name-mixedcase\n function DOMAIN_SEPARATOR() external view override returns (bytes32) {\n return _domainSeparatorV4();\n }\n\n /**\n * @dev \"Consume a nonce\": return the current value and increment.\n *\n * _Available since v4.1._\n */\n function _useNonce(address owner) internal virtual returns (uint256 current) {\n CountersUpgradeable.Counter storage nonce = _nonces[owner];\n current = nonce.current();\n nonce.increment();\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[49] private __gap;\n}\n" + }, + "@openzeppelin/contracts-upgradeable/token/ERC20/extensions/draft-IERC20PermitUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (token/ERC20/extensions/draft-IERC20Permit.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Interface of the ERC20 Permit extension allowing approvals to be made via signatures, as defined in\n * https://eips.ethereum.org/EIPS/eip-2612[EIP-2612].\n *\n * Adds the {permit} method, which can be used to change an account's ERC20 allowance (see {IERC20-allowance}) by\n * presenting a message signed by the account. By not relying on {IERC20-approve}, the token holder account doesn't\n * need to send a transaction, and thus is not required to hold Ether at all.\n */\ninterface IERC20PermitUpgradeable {\n /**\n * @dev Sets `value` as the allowance of `spender` over ``owner``'s tokens,\n * given ``owner``'s signed approval.\n *\n * IMPORTANT: The same issues {IERC20-approve} has related to transaction\n * ordering also apply here.\n *\n * Emits an {Approval} event.\n *\n * Requirements:\n *\n * - `spender` cannot be the zero address.\n * - `deadline` must be a timestamp in the future.\n * - `v`, `r` and `s` must be a valid `secp256k1` signature from `owner`\n * over the EIP712-formatted function arguments.\n * - the signature must use ``owner``'s current nonce (see {nonces}).\n *\n * For more information on the signature format, see the\n * https://eips.ethereum.org/EIPS/eip-2612#specification[relevant EIP\n * section].\n */\n function permit(\n address owner,\n address spender,\n uint256 value,\n uint256 deadline,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) external;\n\n /**\n * @dev Returns the current nonce for `owner`. This value must be\n * included whenever a signature is generated for {permit}.\n *\n * Every successful call to {permit} increases ``owner``'s nonce by one. This\n * prevents a signature from being used multiple times.\n */\n function nonces(address owner) external view returns (uint256);\n\n /**\n * @dev Returns the domain separator used in the encoding of the signature for {permit}, as defined by {EIP712}.\n */\n // solhint-disable-next-line func-name-mixedcase\n function DOMAIN_SEPARATOR() external view returns (bytes32);\n}\n" + }, + "@openzeppelin/contracts-upgradeable/token/ERC20/extensions/IERC20MetadataUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (token/ERC20/extensions/IERC20Metadata.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../IERC20Upgradeable.sol\";\n\n/**\n * @dev Interface for the optional metadata functions from the ERC20 standard.\n *\n * _Available since v4.1._\n */\ninterface IERC20MetadataUpgradeable is IERC20Upgradeable {\n /**\n * @dev Returns the name of the token.\n */\n function name() external view returns (string memory);\n\n /**\n * @dev Returns the symbol of the token.\n */\n function symbol() external view returns (string memory);\n\n /**\n * @dev Returns the decimals places of the token.\n */\n function decimals() external view returns (uint8);\n}\n" + }, + "@openzeppelin/contracts-upgradeable/token/ERC20/IERC20Upgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.6.0) (token/ERC20/IERC20.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Interface of the ERC20 standard as defined in the EIP.\n */\ninterface IERC20Upgradeable {\n /**\n * @dev Emitted when `value` tokens are moved from one account (`from`) to\n * another (`to`).\n *\n * Note that `value` may be zero.\n */\n event Transfer(address indexed from, address indexed to, uint256 value);\n\n /**\n * @dev Emitted when the allowance of a `spender` for an `owner` is set by\n * a call to {approve}. `value` is the new allowance.\n */\n event Approval(address indexed owner, address indexed spender, uint256 value);\n\n /**\n * @dev Returns the amount of tokens in existence.\n */\n function totalSupply() external view returns (uint256);\n\n /**\n * @dev Returns the amount of tokens owned by `account`.\n */\n function balanceOf(address account) external view returns (uint256);\n\n /**\n * @dev Moves `amount` tokens from the caller's account to `to`.\n *\n * Returns a boolean value indicating whether the operation succeeded.\n *\n * Emits a {Transfer} event.\n */\n function transfer(address to, uint256 amount) external returns (bool);\n\n /**\n * @dev Returns the remaining number of tokens that `spender` will be\n * allowed to spend on behalf of `owner` through {transferFrom}. This is\n * zero by default.\n *\n * This value changes when {approve} or {transferFrom} are called.\n */\n function allowance(address owner, address spender) external view returns (uint256);\n\n /**\n * @dev Sets `amount` as the allowance of `spender` over the caller's tokens.\n *\n * Returns a boolean value indicating whether the operation succeeded.\n *\n * IMPORTANT: Beware that changing an allowance with this method brings the risk\n * that someone may use both the old and the new allowance by unfortunate\n * transaction ordering. One possible solution to mitigate this race\n * condition is to first reduce the spender's allowance to 0 and set the\n * desired value afterwards:\n * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729\n *\n * Emits an {Approval} event.\n */\n function approve(address spender, uint256 amount) external returns (bool);\n\n /**\n * @dev Moves `amount` tokens from `from` to `to` using the\n * allowance mechanism. `amount` is then deducted from the caller's\n * allowance.\n *\n * Returns a boolean value indicating whether the operation succeeded.\n *\n * Emits a {Transfer} event.\n */\n function transferFrom(\n address from,\n address to,\n uint256 amount\n ) external returns (bool);\n}\n" + }, + "@openzeppelin/contracts-upgradeable/token/ERC721/extensions/IERC721MetadataUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (token/ERC721/extensions/IERC721Metadata.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../IERC721Upgradeable.sol\";\n\n/**\n * @title ERC-721 Non-Fungible Token Standard, optional metadata extension\n * @dev See https://eips.ethereum.org/EIPS/eip-721\n */\ninterface IERC721MetadataUpgradeable is IERC721Upgradeable {\n /**\n * @dev Returns the token collection name.\n */\n function name() external view returns (string memory);\n\n /**\n * @dev Returns the token collection symbol.\n */\n function symbol() external view returns (string memory);\n\n /**\n * @dev Returns the Uniform Resource Identifier (URI) for `tokenId` token.\n */\n function tokenURI(uint256 tokenId) external view returns (string memory);\n}\n" + }, + "@openzeppelin/contracts-upgradeable/token/ERC721/IERC721ReceiverUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.6.0) (token/ERC721/IERC721Receiver.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @title ERC721 token receiver interface\n * @dev Interface for any contract that wants to support safeTransfers\n * from ERC721 asset contracts.\n */\ninterface IERC721ReceiverUpgradeable {\n /**\n * @dev Whenever an {IERC721} `tokenId` token is transferred to this contract via {IERC721-safeTransferFrom}\n * by `operator` from `from`, this function is called.\n *\n * It must return its Solidity selector to confirm the token transfer.\n * If any other value is returned or the interface is not implemented by the recipient, the transfer will be reverted.\n *\n * The selector can be obtained in Solidity with `IERC721Receiver.onERC721Received.selector`.\n */\n function onERC721Received(\n address operator,\n address from,\n uint256 tokenId,\n bytes calldata data\n ) external returns (bytes4);\n}\n" + }, + "@openzeppelin/contracts-upgradeable/token/ERC721/IERC721Upgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (token/ERC721/IERC721.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../../utils/introspection/IERC165Upgradeable.sol\";\n\n/**\n * @dev Required interface of an ERC721 compliant contract.\n */\ninterface IERC721Upgradeable is IERC165Upgradeable {\n /**\n * @dev Emitted when `tokenId` token is transferred from `from` to `to`.\n */\n event Transfer(address indexed from, address indexed to, uint256 indexed tokenId);\n\n /**\n * @dev Emitted when `owner` enables `approved` to manage the `tokenId` token.\n */\n event Approval(address indexed owner, address indexed approved, uint256 indexed tokenId);\n\n /**\n * @dev Emitted when `owner` enables or disables (`approved`) `operator` to manage all of its assets.\n */\n event ApprovalForAll(address indexed owner, address indexed operator, bool approved);\n\n /**\n * @dev Returns the number of tokens in ``owner``'s account.\n */\n function balanceOf(address owner) external view returns (uint256 balance);\n\n /**\n * @dev Returns the owner of the `tokenId` token.\n *\n * Requirements:\n *\n * - `tokenId` must exist.\n */\n function ownerOf(uint256 tokenId) external view returns (address owner);\n\n /**\n * @dev Safely transfers `tokenId` token from `from` to `to`.\n *\n * Requirements:\n *\n * - `from` cannot be the zero address.\n * - `to` cannot be the zero address.\n * - `tokenId` token must exist and be owned by `from`.\n * - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}.\n * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.\n *\n * Emits a {Transfer} event.\n */\n function safeTransferFrom(\n address from,\n address to,\n uint256 tokenId,\n bytes calldata data\n ) external;\n\n /**\n * @dev Safely transfers `tokenId` token from `from` to `to`, checking first that contract recipients\n * are aware of the ERC721 protocol to prevent tokens from being forever locked.\n *\n * Requirements:\n *\n * - `from` cannot be the zero address.\n * - `to` cannot be the zero address.\n * - `tokenId` token must exist and be owned by `from`.\n * - If the caller is not `from`, it must have been allowed to move this token by either {approve} or {setApprovalForAll}.\n * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.\n *\n * Emits a {Transfer} event.\n */\n function safeTransferFrom(\n address from,\n address to,\n uint256 tokenId\n ) external;\n\n /**\n * @dev Transfers `tokenId` token from `from` to `to`.\n *\n * WARNING: Usage of this method is discouraged, use {safeTransferFrom} whenever possible.\n *\n * Requirements:\n *\n * - `from` cannot be the zero address.\n * - `to` cannot be the zero address.\n * - `tokenId` token must be owned by `from`.\n * - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}.\n *\n * Emits a {Transfer} event.\n */\n function transferFrom(\n address from,\n address to,\n uint256 tokenId\n ) external;\n\n /**\n * @dev Gives permission to `to` to transfer `tokenId` token to another account.\n * The approval is cleared when the token is transferred.\n *\n * Only a single account can be approved at a time, so approving the zero address clears previous approvals.\n *\n * Requirements:\n *\n * - The caller must own the token or be an approved operator.\n * - `tokenId` must exist.\n *\n * Emits an {Approval} event.\n */\n function approve(address to, uint256 tokenId) external;\n\n /**\n * @dev Approve or remove `operator` as an operator for the caller.\n * Operators can call {transferFrom} or {safeTransferFrom} for any token owned by the caller.\n *\n * Requirements:\n *\n * - The `operator` cannot be the caller.\n *\n * Emits an {ApprovalForAll} event.\n */\n function setApprovalForAll(address operator, bool _approved) external;\n\n /**\n * @dev Returns the account approved for `tokenId` token.\n *\n * Requirements:\n *\n * - `tokenId` must exist.\n */\n function getApproved(uint256 tokenId) external view returns (address operator);\n\n /**\n * @dev Returns if the `operator` is allowed to manage all of the assets of `owner`.\n *\n * See {setApprovalForAll}\n */\n function isApprovedForAll(address owner, address operator) external view returns (bool);\n}\n" + }, + "@openzeppelin/contracts-upgradeable/utils/AddressUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (utils/Address.sol)\n\npragma solidity ^0.8.1;\n\n/**\n * @dev Collection of functions related to the address type\n */\nlibrary AddressUpgradeable {\n /**\n * @dev Returns true if `account` is a contract.\n *\n * [IMPORTANT]\n * ====\n * It is unsafe to assume that an address for which this function returns\n * false is an externally-owned account (EOA) and not a contract.\n *\n * Among others, `isContract` will return false for the following\n * types of addresses:\n *\n * - an externally-owned account\n * - a contract in construction\n * - an address where a contract will be created\n * - an address where a contract lived, but was destroyed\n * ====\n *\n * [IMPORTANT]\n * ====\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\n *\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\n * constructor.\n * ====\n */\n function isContract(address account) internal view returns (bool) {\n // This method relies on extcodesize/address.code.length, which returns 0\n // for contracts in construction, since the code is only stored at the end\n // of the constructor execution.\n\n return account.code.length > 0;\n }\n\n /**\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\n * `recipient`, forwarding all available gas and reverting on errors.\n *\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\n * imposed by `transfer`, making them unable to receive funds via\n * `transfer`. {sendValue} removes this limitation.\n *\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\n *\n * IMPORTANT: because control is transferred to `recipient`, care must be\n * taken to not create reentrancy vulnerabilities. Consider using\n * {ReentrancyGuard} or the\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\n */\n function sendValue(address payable recipient, uint256 amount) internal {\n require(address(this).balance >= amount, \"Address: insufficient balance\");\n\n (bool success, ) = recipient.call{value: amount}(\"\");\n require(success, \"Address: unable to send value, recipient may have reverted\");\n }\n\n /**\n * @dev Performs a Solidity function call using a low level `call`. A\n * plain `call` is an unsafe replacement for a function call: use this\n * function instead.\n *\n * If `target` reverts with a revert reason, it is bubbled up by this\n * function (like regular Solidity function calls).\n *\n * Returns the raw returned data. To convert to the expected return value,\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\n *\n * Requirements:\n *\n * - `target` must be a contract.\n * - calling `target` with `data` must not revert.\n *\n * _Available since v3.1._\n */\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionCall(target, data, \"Address: low-level call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\n * `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, 0, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but also transferring `value` wei to `target`.\n *\n * Requirements:\n *\n * - the calling contract must have an ETH balance of at least `value`.\n * - the called Solidity function must be `payable`.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, value, \"Address: low-level call with value failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\n * with `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(address(this).balance >= value, \"Address: insufficient balance for call\");\n require(isContract(target), \"Address: call to non-contract\");\n\n (bool success, bytes memory returndata) = target.call{value: value}(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\n return functionStaticCall(target, data, \"Address: low-level static call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal view returns (bytes memory) {\n require(isContract(target), \"Address: static call to non-contract\");\n\n (bool success, bytes memory returndata) = target.staticcall(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the\n * revert reason using the provided one.\n *\n * _Available since v4.3._\n */\n function verifyCallResult(\n bool success,\n bytes memory returndata,\n string memory errorMessage\n ) internal pure returns (bytes memory) {\n if (success) {\n return returndata;\n } else {\n // Look for revert reason and bubble it up if present\n if (returndata.length > 0) {\n // The easiest way to bubble the revert reason is using memory via assembly\n /// @solidity memory-safe-assembly\n assembly {\n let returndata_size := mload(returndata)\n revert(add(32, returndata), returndata_size)\n }\n } else {\n revert(errorMessage);\n }\n }\n }\n}\n" + }, + "@openzeppelin/contracts-upgradeable/utils/ContextUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)\n\npragma solidity ^0.8.0;\nimport \"../proxy/utils/Initializable.sol\";\n\n/**\n * @dev Provides information about the current execution context, including the\n * sender of the transaction and its data. While these are generally available\n * via msg.sender and msg.data, they should not be accessed in such a direct\n * manner, since when dealing with meta-transactions the account sending and\n * paying for execution may not be the actual sender (as far as an application\n * is concerned).\n *\n * This contract is only required for intermediate, library-like contracts.\n */\nabstract contract ContextUpgradeable is Initializable {\n function __Context_init() internal onlyInitializing {\n }\n\n function __Context_init_unchained() internal onlyInitializing {\n }\n function _msgSender() internal view virtual returns (address) {\n return msg.sender;\n }\n\n function _msgData() internal view virtual returns (bytes calldata) {\n return msg.data;\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[50] private __gap;\n}\n" + }, + "@openzeppelin/contracts-upgradeable/utils/CountersUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (utils/Counters.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @title Counters\n * @author Matt Condon (@shrugs)\n * @dev Provides counters that can only be incremented, decremented or reset. This can be used e.g. to track the number\n * of elements in a mapping, issuing ERC721 ids, or counting request ids.\n *\n * Include with `using Counters for Counters.Counter;`\n */\nlibrary CountersUpgradeable {\n struct Counter {\n // This variable should never be directly accessed by users of the library: interactions must be restricted to\n // the library's function. As of Solidity v0.5.2, this cannot be enforced, though there is a proposal to add\n // this feature: see https://github.com/ethereum/solidity/issues/4637\n uint256 _value; // default: 0\n }\n\n function current(Counter storage counter) internal view returns (uint256) {\n return counter._value;\n }\n\n function increment(Counter storage counter) internal {\n unchecked {\n counter._value += 1;\n }\n }\n\n function decrement(Counter storage counter) internal {\n uint256 value = counter._value;\n require(value > 0, \"Counter: decrement overflow\");\n unchecked {\n counter._value = value - 1;\n }\n }\n\n function reset(Counter storage counter) internal {\n counter._value = 0;\n }\n}\n" + }, + "@openzeppelin/contracts-upgradeable/utils/cryptography/draft-EIP712Upgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (utils/cryptography/draft-EIP712.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./ECDSAUpgradeable.sol\";\nimport \"../../proxy/utils/Initializable.sol\";\n\n/**\n * @dev https://eips.ethereum.org/EIPS/eip-712[EIP 712] is a standard for hashing and signing of typed structured data.\n *\n * The encoding specified in the EIP is very generic, and such a generic implementation in Solidity is not feasible,\n * thus this contract does not implement the encoding itself. Protocols need to implement the type-specific encoding\n * they need in their contracts using a combination of `abi.encode` and `keccak256`.\n *\n * This contract implements the EIP 712 domain separator ({_domainSeparatorV4}) that is used as part of the encoding\n * scheme, and the final step of the encoding to obtain the message digest that is then signed via ECDSA\n * ({_hashTypedDataV4}).\n *\n * The implementation of the domain separator was designed to be as efficient as possible while still properly updating\n * the chain id to protect against replay attacks on an eventual fork of the chain.\n *\n * NOTE: This contract implements the version of the encoding known as \"v4\", as implemented by the JSON RPC method\n * https://docs.metamask.io/guide/signing-data.html[`eth_signTypedDataV4` in MetaMask].\n *\n * _Available since v3.4._\n *\n * @custom:storage-size 52\n */\nabstract contract EIP712Upgradeable is Initializable {\n /* solhint-disable var-name-mixedcase */\n bytes32 private _HASHED_NAME;\n bytes32 private _HASHED_VERSION;\n bytes32 private constant _TYPE_HASH = keccak256(\"EIP712Domain(string name,string version,uint256 chainId,address verifyingContract)\");\n\n /* solhint-enable var-name-mixedcase */\n\n /**\n * @dev Initializes the domain separator and parameter caches.\n *\n * The meaning of `name` and `version` is specified in\n * https://eips.ethereum.org/EIPS/eip-712#definition-of-domainseparator[EIP 712]:\n *\n * - `name`: the user readable name of the signing domain, i.e. the name of the DApp or the protocol.\n * - `version`: the current major version of the signing domain.\n *\n * NOTE: These parameters cannot be changed except through a xref:learn::upgrading-smart-contracts.adoc[smart\n * contract upgrade].\n */\n function __EIP712_init(string memory name, string memory version) internal onlyInitializing {\n __EIP712_init_unchained(name, version);\n }\n\n function __EIP712_init_unchained(string memory name, string memory version) internal onlyInitializing {\n bytes32 hashedName = keccak256(bytes(name));\n bytes32 hashedVersion = keccak256(bytes(version));\n _HASHED_NAME = hashedName;\n _HASHED_VERSION = hashedVersion;\n }\n\n /**\n * @dev Returns the domain separator for the current chain.\n */\n function _domainSeparatorV4() internal view returns (bytes32) {\n return _buildDomainSeparator(_TYPE_HASH, _EIP712NameHash(), _EIP712VersionHash());\n }\n\n function _buildDomainSeparator(\n bytes32 typeHash,\n bytes32 nameHash,\n bytes32 versionHash\n ) private view returns (bytes32) {\n return keccak256(abi.encode(typeHash, nameHash, versionHash, block.chainid, address(this)));\n }\n\n /**\n * @dev Given an already https://eips.ethereum.org/EIPS/eip-712#definition-of-hashstruct[hashed struct], this\n * function returns the hash of the fully encoded EIP712 message for this domain.\n *\n * This hash can be used together with {ECDSA-recover} to obtain the signer of a message. For example:\n *\n * ```solidity\n * bytes32 digest = _hashTypedDataV4(keccak256(abi.encode(\n * keccak256(\"Mail(address to,string contents)\"),\n * mailTo,\n * keccak256(bytes(mailContents))\n * )));\n * address signer = ECDSA.recover(digest, signature);\n * ```\n */\n function _hashTypedDataV4(bytes32 structHash) internal view virtual returns (bytes32) {\n return ECDSAUpgradeable.toTypedDataHash(_domainSeparatorV4(), structHash);\n }\n\n /**\n * @dev The hash of the name parameter for the EIP712 domain.\n *\n * NOTE: This function reads from storage by default, but can be redefined to return a constant value if gas costs\n * are a concern.\n */\n function _EIP712NameHash() internal virtual view returns (bytes32) {\n return _HASHED_NAME;\n }\n\n /**\n * @dev The hash of the version parameter for the EIP712 domain.\n *\n * NOTE: This function reads from storage by default, but can be redefined to return a constant value if gas costs\n * are a concern.\n */\n function _EIP712VersionHash() internal virtual view returns (bytes32) {\n return _HASHED_VERSION;\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[50] private __gap;\n}\n" + }, + "@openzeppelin/contracts-upgradeable/utils/cryptography/ECDSAUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (utils/cryptography/ECDSA.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../StringsUpgradeable.sol\";\n\n/**\n * @dev Elliptic Curve Digital Signature Algorithm (ECDSA) operations.\n *\n * These functions can be used to verify that a message was signed by the holder\n * of the private keys of a given address.\n */\nlibrary ECDSAUpgradeable {\n enum RecoverError {\n NoError,\n InvalidSignature,\n InvalidSignatureLength,\n InvalidSignatureS,\n InvalidSignatureV\n }\n\n function _throwError(RecoverError error) private pure {\n if (error == RecoverError.NoError) {\n return; // no error: do nothing\n } else if (error == RecoverError.InvalidSignature) {\n revert(\"ECDSA: invalid signature\");\n } else if (error == RecoverError.InvalidSignatureLength) {\n revert(\"ECDSA: invalid signature length\");\n } else if (error == RecoverError.InvalidSignatureS) {\n revert(\"ECDSA: invalid signature 's' value\");\n } else if (error == RecoverError.InvalidSignatureV) {\n revert(\"ECDSA: invalid signature 'v' value\");\n }\n }\n\n /**\n * @dev Returns the address that signed a hashed message (`hash`) with\n * `signature` or error string. This address can then be used for verification purposes.\n *\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\n * this function rejects them by requiring the `s` value to be in the lower\n * half order, and the `v` value to be either 27 or 28.\n *\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\n * verification to be secure: it is possible to craft signatures that\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\n * this is by receiving a hash of the original message (which may otherwise\n * be too long), and then calling {toEthSignedMessageHash} on it.\n *\n * Documentation for signature generation:\n * - with https://web3js.readthedocs.io/en/v1.3.4/web3-eth-accounts.html#sign[Web3.js]\n * - with https://docs.ethers.io/v5/api/signer/#Signer-signMessage[ethers]\n *\n * _Available since v4.3._\n */\n function tryRecover(bytes32 hash, bytes memory signature) internal pure returns (address, RecoverError) {\n // Check the signature length\n // - case 65: r,s,v signature (standard)\n // - case 64: r,vs signature (cf https://eips.ethereum.org/EIPS/eip-2098) _Available since v4.1._\n if (signature.length == 65) {\n bytes32 r;\n bytes32 s;\n uint8 v;\n // ecrecover takes the signature parameters, and the only way to get them\n // currently is to use assembly.\n /// @solidity memory-safe-assembly\n assembly {\n r := mload(add(signature, 0x20))\n s := mload(add(signature, 0x40))\n v := byte(0, mload(add(signature, 0x60)))\n }\n return tryRecover(hash, v, r, s);\n } else if (signature.length == 64) {\n bytes32 r;\n bytes32 vs;\n // ecrecover takes the signature parameters, and the only way to get them\n // currently is to use assembly.\n /// @solidity memory-safe-assembly\n assembly {\n r := mload(add(signature, 0x20))\n vs := mload(add(signature, 0x40))\n }\n return tryRecover(hash, r, vs);\n } else {\n return (address(0), RecoverError.InvalidSignatureLength);\n }\n }\n\n /**\n * @dev Returns the address that signed a hashed message (`hash`) with\n * `signature`. This address can then be used for verification purposes.\n *\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\n * this function rejects them by requiring the `s` value to be in the lower\n * half order, and the `v` value to be either 27 or 28.\n *\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\n * verification to be secure: it is possible to craft signatures that\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\n * this is by receiving a hash of the original message (which may otherwise\n * be too long), and then calling {toEthSignedMessageHash} on it.\n */\n function recover(bytes32 hash, bytes memory signature) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, signature);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Overload of {ECDSA-tryRecover} that receives the `r` and `vs` short-signature fields separately.\n *\n * See https://eips.ethereum.org/EIPS/eip-2098[EIP-2098 short signatures]\n *\n * _Available since v4.3._\n */\n function tryRecover(\n bytes32 hash,\n bytes32 r,\n bytes32 vs\n ) internal pure returns (address, RecoverError) {\n bytes32 s = vs & bytes32(0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff);\n uint8 v = uint8((uint256(vs) >> 255) + 27);\n return tryRecover(hash, v, r, s);\n }\n\n /**\n * @dev Overload of {ECDSA-recover} that receives the `r and `vs` short-signature fields separately.\n *\n * _Available since v4.2._\n */\n function recover(\n bytes32 hash,\n bytes32 r,\n bytes32 vs\n ) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, r, vs);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Overload of {ECDSA-tryRecover} that receives the `v`,\n * `r` and `s` signature fields separately.\n *\n * _Available since v4.3._\n */\n function tryRecover(\n bytes32 hash,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) internal pure returns (address, RecoverError) {\n // EIP-2 still allows signature malleability for ecrecover(). Remove this possibility and make the signature\n // unique. Appendix F in the Ethereum Yellow paper (https://ethereum.github.io/yellowpaper/paper.pdf), defines\n // the valid range for s in (301): 0 < s < secp256k1n ÷ 2 + 1, and for v in (302): v ∈ {27, 28}. Most\n // signatures from current libraries generate a unique signature with an s-value in the lower half order.\n //\n // If your library generates malleable signatures, such as s-values in the upper range, calculate a new s-value\n // with 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141 - s1 and flip v from 27 to 28 or\n // vice versa. If your library also generates signatures with 0/1 for v instead 27/28, add 27 to v to accept\n // these malleable signatures as well.\n if (uint256(s) > 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D576E7357A4501DDFE92F46681B20A0) {\n return (address(0), RecoverError.InvalidSignatureS);\n }\n if (v != 27 && v != 28) {\n return (address(0), RecoverError.InvalidSignatureV);\n }\n\n // If the signature is valid (and not malleable), return the signer address\n address signer = ecrecover(hash, v, r, s);\n if (signer == address(0)) {\n return (address(0), RecoverError.InvalidSignature);\n }\n\n return (signer, RecoverError.NoError);\n }\n\n /**\n * @dev Overload of {ECDSA-recover} that receives the `v`,\n * `r` and `s` signature fields separately.\n */\n function recover(\n bytes32 hash,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, v, r, s);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Returns an Ethereum Signed Message, created from a `hash`. This\n * produces hash corresponding to the one signed with the\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\n * JSON-RPC method as part of EIP-191.\n *\n * See {recover}.\n */\n function toEthSignedMessageHash(bytes32 hash) internal pure returns (bytes32) {\n // 32 is the length in bytes of hash,\n // enforced by the type signature above\n return keccak256(abi.encodePacked(\"\\x19Ethereum Signed Message:\\n32\", hash));\n }\n\n /**\n * @dev Returns an Ethereum Signed Message, created from `s`. This\n * produces hash corresponding to the one signed with the\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\n * JSON-RPC method as part of EIP-191.\n *\n * See {recover}.\n */\n function toEthSignedMessageHash(bytes memory s) internal pure returns (bytes32) {\n return keccak256(abi.encodePacked(\"\\x19Ethereum Signed Message:\\n\", StringsUpgradeable.toString(s.length), s));\n }\n\n /**\n * @dev Returns an Ethereum Signed Typed Data, created from a\n * `domainSeparator` and a `structHash`. This produces hash corresponding\n * to the one signed with the\n * https://eips.ethereum.org/EIPS/eip-712[`eth_signTypedData`]\n * JSON-RPC method as part of EIP-712.\n *\n * See {recover}.\n */\n function toTypedDataHash(bytes32 domainSeparator, bytes32 structHash) internal pure returns (bytes32) {\n return keccak256(abi.encodePacked(\"\\x19\\x01\", domainSeparator, structHash));\n }\n}\n" + }, + "@openzeppelin/contracts-upgradeable/utils/introspection/ERC165Upgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (utils/introspection/ERC165.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./IERC165Upgradeable.sol\";\nimport \"../../proxy/utils/Initializable.sol\";\n\n/**\n * @dev Implementation of the {IERC165} interface.\n *\n * Contracts that want to implement ERC165 should inherit from this contract and override {supportsInterface} to check\n * for the additional interface id that will be supported. For example:\n *\n * ```solidity\n * function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {\n * return interfaceId == type(MyInterface).interfaceId || super.supportsInterface(interfaceId);\n * }\n * ```\n *\n * Alternatively, {ERC165Storage} provides an easier to use but more expensive implementation.\n */\nabstract contract ERC165Upgradeable is Initializable, IERC165Upgradeable {\n function __ERC165_init() internal onlyInitializing {\n }\n\n function __ERC165_init_unchained() internal onlyInitializing {\n }\n /**\n * @dev See {IERC165-supportsInterface}.\n */\n function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {\n return interfaceId == type(IERC165Upgradeable).interfaceId;\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[50] private __gap;\n}\n" + }, + "@openzeppelin/contracts-upgradeable/utils/introspection/IERC165Upgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (utils/introspection/IERC165.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Interface of the ERC165 standard, as defined in the\n * https://eips.ethereum.org/EIPS/eip-165[EIP].\n *\n * Implementers can declare support of contract interfaces, which can then be\n * queried by others ({ERC165Checker}).\n *\n * For an implementation, see {ERC165}.\n */\ninterface IERC165Upgradeable {\n /**\n * @dev Returns true if this contract implements the interface defined by\n * `interfaceId`. See the corresponding\n * https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified[EIP section]\n * to learn more about how these ids are created.\n *\n * This function call must use less than 30 000 gas.\n */\n function supportsInterface(bytes4 interfaceId) external view returns (bool);\n}\n" + }, + "@openzeppelin/contracts-upgradeable/utils/StringsUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (utils/Strings.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev String operations.\n */\nlibrary StringsUpgradeable {\n bytes16 private constant _HEX_SYMBOLS = \"0123456789abcdef\";\n uint8 private constant _ADDRESS_LENGTH = 20;\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` decimal representation.\n */\n function toString(uint256 value) internal pure returns (string memory) {\n // Inspired by OraclizeAPI's implementation - MIT licence\n // https://github.com/oraclize/ethereum-api/blob/b42146b063c7d6ee1358846c198246239e9360e8/oraclizeAPI_0.4.25.sol\n\n if (value == 0) {\n return \"0\";\n }\n uint256 temp = value;\n uint256 digits;\n while (temp != 0) {\n digits++;\n temp /= 10;\n }\n bytes memory buffer = new bytes(digits);\n while (value != 0) {\n digits -= 1;\n buffer[digits] = bytes1(uint8(48 + uint256(value % 10)));\n value /= 10;\n }\n return string(buffer);\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation.\n */\n function toHexString(uint256 value) internal pure returns (string memory) {\n if (value == 0) {\n return \"0x00\";\n }\n uint256 temp = value;\n uint256 length = 0;\n while (temp != 0) {\n length++;\n temp >>= 8;\n }\n return toHexString(value, length);\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length.\n */\n function toHexString(uint256 value, uint256 length) internal pure returns (string memory) {\n bytes memory buffer = new bytes(2 * length + 2);\n buffer[0] = \"0\";\n buffer[1] = \"x\";\n for (uint256 i = 2 * length + 1; i > 1; --i) {\n buffer[i] = _HEX_SYMBOLS[value & 0xf];\n value >>= 4;\n }\n require(value == 0, \"Strings: hex length insufficient\");\n return string(buffer);\n }\n\n /**\n * @dev Converts an `address` with fixed length of 20 bytes to its not checksummed ASCII `string` hexadecimal representation.\n */\n function toHexString(address addr) internal pure returns (string memory) {\n return toHexString(uint256(uint160(addr)), _ADDRESS_LENGTH);\n }\n}\n" + }, + "@openzeppelin/contracts-upgradeable/utils/structs/EnumerableSetUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (utils/structs/EnumerableSet.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Library for managing\n * https://en.wikipedia.org/wiki/Set_(abstract_data_type)[sets] of primitive\n * types.\n *\n * Sets have the following properties:\n *\n * - Elements are added, removed, and checked for existence in constant time\n * (O(1)).\n * - Elements are enumerated in O(n). No guarantees are made on the ordering.\n *\n * ```\n * contract Example {\n * // Add the library methods\n * using EnumerableSet for EnumerableSet.AddressSet;\n *\n * // Declare a set state variable\n * EnumerableSet.AddressSet private mySet;\n * }\n * ```\n *\n * As of v3.3.0, sets of type `bytes32` (`Bytes32Set`), `address` (`AddressSet`)\n * and `uint256` (`UintSet`) are supported.\n *\n * [WARNING]\n * ====\n * Trying to delete such a structure from storage will likely result in data corruption, rendering the structure unusable.\n * See https://github.com/ethereum/solidity/pull/11843[ethereum/solidity#11843] for more info.\n *\n * In order to clean an EnumerableSet, you can either remove all elements one by one or create a fresh instance using an array of EnumerableSet.\n * ====\n */\nlibrary EnumerableSetUpgradeable {\n // To implement this library for multiple types with as little code\n // repetition as possible, we write it in terms of a generic Set type with\n // bytes32 values.\n // The Set implementation uses private functions, and user-facing\n // implementations (such as AddressSet) are just wrappers around the\n // underlying Set.\n // This means that we can only create new EnumerableSets for types that fit\n // in bytes32.\n\n struct Set {\n // Storage of set values\n bytes32[] _values;\n // Position of the value in the `values` array, plus 1 because index 0\n // means a value is not in the set.\n mapping(bytes32 => uint256) _indexes;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function _add(Set storage set, bytes32 value) private returns (bool) {\n if (!_contains(set, value)) {\n set._values.push(value);\n // The value is stored at length-1, but we add 1 to all indexes\n // and use 0 as a sentinel value\n set._indexes[value] = set._values.length;\n return true;\n } else {\n return false;\n }\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function _remove(Set storage set, bytes32 value) private returns (bool) {\n // We read and store the value's index to prevent multiple reads from the same storage slot\n uint256 valueIndex = set._indexes[value];\n\n if (valueIndex != 0) {\n // Equivalent to contains(set, value)\n // To delete an element from the _values array in O(1), we swap the element to delete with the last one in\n // the array, and then remove the last element (sometimes called as 'swap and pop').\n // This modifies the order of the array, as noted in {at}.\n\n uint256 toDeleteIndex = valueIndex - 1;\n uint256 lastIndex = set._values.length - 1;\n\n if (lastIndex != toDeleteIndex) {\n bytes32 lastValue = set._values[lastIndex];\n\n // Move the last value to the index where the value to delete is\n set._values[toDeleteIndex] = lastValue;\n // Update the index for the moved value\n set._indexes[lastValue] = valueIndex; // Replace lastValue's index to valueIndex\n }\n\n // Delete the slot where the moved value was stored\n set._values.pop();\n\n // Delete the index for the deleted slot\n delete set._indexes[value];\n\n return true;\n } else {\n return false;\n }\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function _contains(Set storage set, bytes32 value) private view returns (bool) {\n return set._indexes[value] != 0;\n }\n\n /**\n * @dev Returns the number of values on the set. O(1).\n */\n function _length(Set storage set) private view returns (uint256) {\n return set._values.length;\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function _at(Set storage set, uint256 index) private view returns (bytes32) {\n return set._values[index];\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function _values(Set storage set) private view returns (bytes32[] memory) {\n return set._values;\n }\n\n // Bytes32Set\n\n struct Bytes32Set {\n Set _inner;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function add(Bytes32Set storage set, bytes32 value) internal returns (bool) {\n return _add(set._inner, value);\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function remove(Bytes32Set storage set, bytes32 value) internal returns (bool) {\n return _remove(set._inner, value);\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function contains(Bytes32Set storage set, bytes32 value) internal view returns (bool) {\n return _contains(set._inner, value);\n }\n\n /**\n * @dev Returns the number of values in the set. O(1).\n */\n function length(Bytes32Set storage set) internal view returns (uint256) {\n return _length(set._inner);\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function at(Bytes32Set storage set, uint256 index) internal view returns (bytes32) {\n return _at(set._inner, index);\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function values(Bytes32Set storage set) internal view returns (bytes32[] memory) {\n return _values(set._inner);\n }\n\n // AddressSet\n\n struct AddressSet {\n Set _inner;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function add(AddressSet storage set, address value) internal returns (bool) {\n return _add(set._inner, bytes32(uint256(uint160(value))));\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function remove(AddressSet storage set, address value) internal returns (bool) {\n return _remove(set._inner, bytes32(uint256(uint160(value))));\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function contains(AddressSet storage set, address value) internal view returns (bool) {\n return _contains(set._inner, bytes32(uint256(uint160(value))));\n }\n\n /**\n * @dev Returns the number of values in the set. O(1).\n */\n function length(AddressSet storage set) internal view returns (uint256) {\n return _length(set._inner);\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function at(AddressSet storage set, uint256 index) internal view returns (address) {\n return address(uint160(uint256(_at(set._inner, index))));\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function values(AddressSet storage set) internal view returns (address[] memory) {\n bytes32[] memory store = _values(set._inner);\n address[] memory result;\n\n /// @solidity memory-safe-assembly\n assembly {\n result := store\n }\n\n return result;\n }\n\n // UintSet\n\n struct UintSet {\n Set _inner;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function add(UintSet storage set, uint256 value) internal returns (bool) {\n return _add(set._inner, bytes32(value));\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function remove(UintSet storage set, uint256 value) internal returns (bool) {\n return _remove(set._inner, bytes32(value));\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function contains(UintSet storage set, uint256 value) internal view returns (bool) {\n return _contains(set._inner, bytes32(value));\n }\n\n /**\n * @dev Returns the number of values on the set. O(1).\n */\n function length(UintSet storage set) internal view returns (uint256) {\n return _length(set._inner);\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function at(UintSet storage set, uint256 index) internal view returns (uint256) {\n return uint256(_at(set._inner, index));\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function values(UintSet storage set) internal view returns (uint256[] memory) {\n bytes32[] memory store = _values(set._inner);\n uint256[] memory result;\n\n /// @solidity memory-safe-assembly\n assembly {\n result := store\n }\n\n return result;\n }\n}\n" + }, + "@openzeppelin/contracts/access/Ownable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (access/Ownable.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../utils/Context.sol\";\n\n/**\n * @dev Contract module which provides a basic access control mechanism, where\n * there is an account (an owner) that can be granted exclusive access to\n * specific functions.\n *\n * By default, the owner account will be the one that deploys the contract. This\n * can later be changed with {transferOwnership}.\n *\n * This module is used through inheritance. It will make available the modifier\n * `onlyOwner`, which can be applied to your functions to restrict their use to\n * the owner.\n */\nabstract contract Ownable is Context {\n address private _owner;\n\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\n\n /**\n * @dev Initializes the contract setting the deployer as the initial owner.\n */\n constructor() {\n _transferOwnership(_msgSender());\n }\n\n /**\n * @dev Throws if called by any account other than the owner.\n */\n modifier onlyOwner() {\n _checkOwner();\n _;\n }\n\n /**\n * @dev Returns the address of the current owner.\n */\n function owner() public view virtual returns (address) {\n return _owner;\n }\n\n /**\n * @dev Throws if the sender is not the owner.\n */\n function _checkOwner() internal view virtual {\n require(owner() == _msgSender(), \"Ownable: caller is not the owner\");\n }\n\n /**\n * @dev Leaves the contract without owner. It will not be possible to call\n * `onlyOwner` functions anymore. Can only be called by the current owner.\n *\n * NOTE: Renouncing ownership will leave the contract without an owner,\n * thereby removing any functionality that is only available to the owner.\n */\n function renounceOwnership() public virtual onlyOwner {\n _transferOwnership(address(0));\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Can only be called by the current owner.\n */\n function transferOwnership(address newOwner) public virtual onlyOwner {\n require(newOwner != address(0), \"Ownable: new owner is the zero address\");\n _transferOwnership(newOwner);\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Internal function without access restriction.\n */\n function _transferOwnership(address newOwner) internal virtual {\n address oldOwner = _owner;\n _owner = newOwner;\n emit OwnershipTransferred(oldOwner, newOwner);\n }\n}\n" + }, + "@openzeppelin/contracts/interfaces/draft-IERC1822.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.5.0) (interfaces/draft-IERC1822.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev ERC1822: Universal Upgradeable Proxy Standard (UUPS) documents a method for upgradeability through a simplified\n * proxy whose upgrades are fully controlled by the current implementation.\n */\ninterface IERC1822Proxiable {\n /**\n * @dev Returns the storage slot that the proxiable contract assumes is being used to store the implementation\n * address.\n *\n * IMPORTANT: A proxy pointing at a proxiable contract should not be considered proxiable itself, because this risks\n * bricking a proxy that upgrades to it, by delegating to itself until out of gas. Thus it is critical that this\n * function revert if invoked through a proxy.\n */\n function proxiableUUID() external view returns (bytes32);\n}\n" + }, + "@openzeppelin/contracts/interfaces/IERC3156FlashBorrower.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (interfaces/IERC3156FlashBorrower.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Interface of the ERC3156 FlashBorrower, as defined in\n * https://eips.ethereum.org/EIPS/eip-3156[ERC-3156].\n *\n * _Available since v4.1._\n */\ninterface IERC3156FlashBorrower {\n /**\n * @dev Receive a flash loan.\n * @param initiator The initiator of the loan.\n * @param token The loan currency.\n * @param amount The amount of tokens lent.\n * @param fee The additional amount of tokens to repay.\n * @param data Arbitrary data structure, intended to contain user-defined parameters.\n * @return The keccak256 hash of \"IERC3156FlashBorrower.onFlashLoan\"\n */\n function onFlashLoan(\n address initiator,\n address token,\n uint256 amount,\n uint256 fee,\n bytes calldata data\n ) external returns (bytes32);\n}\n" + }, + "@openzeppelin/contracts/interfaces/IERC3156FlashLender.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (interfaces/IERC3156FlashLender.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./IERC3156FlashBorrower.sol\";\n\n/**\n * @dev Interface of the ERC3156 FlashLender, as defined in\n * https://eips.ethereum.org/EIPS/eip-3156[ERC-3156].\n *\n * _Available since v4.1._\n */\ninterface IERC3156FlashLender {\n /**\n * @dev The amount of currency available to be lended.\n * @param token The loan currency.\n * @return The amount of `token` that can be borrowed.\n */\n function maxFlashLoan(address token) external view returns (uint256);\n\n /**\n * @dev The fee to be charged for a given loan.\n * @param token The loan currency.\n * @param amount The amount of tokens lent.\n * @return The amount of `token` to be charged for the loan, on top of the returned principal.\n */\n function flashFee(address token, uint256 amount) external view returns (uint256);\n\n /**\n * @dev Initiate a flash loan.\n * @param receiver The receiver of the tokens in the loan, and the receiver of the callback.\n * @param token The loan currency.\n * @param amount The amount of tokens lent.\n * @param data Arbitrary data structure, intended to contain user-defined parameters.\n */\n function flashLoan(\n IERC3156FlashBorrower receiver,\n address token,\n uint256 amount,\n bytes calldata data\n ) external returns (bool);\n}\n" + }, + "@openzeppelin/contracts/interfaces/IERC721Metadata.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (interfaces/IERC721Metadata.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../token/ERC721/extensions/IERC721Metadata.sol\";\n" + }, + "@openzeppelin/contracts/proxy/beacon/IBeacon.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (proxy/beacon/IBeacon.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev This is the interface that {BeaconProxy} expects of its beacon.\n */\ninterface IBeacon {\n /**\n * @dev Must return an address that can be used as a delegate call target.\n *\n * {BeaconProxy} will check that this address is a contract.\n */\n function implementation() external view returns (address);\n}\n" + }, + "@openzeppelin/contracts/proxy/ERC1967/ERC1967Proxy.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (proxy/ERC1967/ERC1967Proxy.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../Proxy.sol\";\nimport \"./ERC1967Upgrade.sol\";\n\n/**\n * @dev This contract implements an upgradeable proxy. It is upgradeable because calls are delegated to an\n * implementation address that can be changed. This address is stored in storage in the location specified by\n * https://eips.ethereum.org/EIPS/eip-1967[EIP1967], so that it doesn't conflict with the storage layout of the\n * implementation behind the proxy.\n */\ncontract ERC1967Proxy is Proxy, ERC1967Upgrade {\n /**\n * @dev Initializes the upgradeable proxy with an initial implementation specified by `_logic`.\n *\n * If `_data` is nonempty, it's used as data in a delegate call to `_logic`. This will typically be an encoded\n * function call, and allows initializing the storage of the proxy like a Solidity constructor.\n */\n constructor(address _logic, bytes memory _data) payable {\n _upgradeToAndCall(_logic, _data, false);\n }\n\n /**\n * @dev Returns the current implementation address.\n */\n function _implementation() internal view virtual override returns (address impl) {\n return ERC1967Upgrade._getImplementation();\n }\n}\n" + }, + "@openzeppelin/contracts/proxy/ERC1967/ERC1967Upgrade.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.5.0) (proxy/ERC1967/ERC1967Upgrade.sol)\n\npragma solidity ^0.8.2;\n\nimport \"../beacon/IBeacon.sol\";\nimport \"../../interfaces/draft-IERC1822.sol\";\nimport \"../../utils/Address.sol\";\nimport \"../../utils/StorageSlot.sol\";\n\n/**\n * @dev This abstract contract provides getters and event emitting update functions for\n * https://eips.ethereum.org/EIPS/eip-1967[EIP1967] slots.\n *\n * _Available since v4.1._\n *\n * @custom:oz-upgrades-unsafe-allow delegatecall\n */\nabstract contract ERC1967Upgrade {\n // This is the keccak-256 hash of \"eip1967.proxy.rollback\" subtracted by 1\n bytes32 private constant _ROLLBACK_SLOT = 0x4910fdfa16fed3260ed0e7147f7cc6da11a60208b5b9406d12a635614ffd9143;\n\n /**\n * @dev Storage slot with the address of the current implementation.\n * This is the keccak-256 hash of \"eip1967.proxy.implementation\" subtracted by 1, and is\n * validated in the constructor.\n */\n bytes32 internal constant _IMPLEMENTATION_SLOT = 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc;\n\n /**\n * @dev Emitted when the implementation is upgraded.\n */\n event Upgraded(address indexed implementation);\n\n /**\n * @dev Returns the current implementation address.\n */\n function _getImplementation() internal view returns (address) {\n return StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value;\n }\n\n /**\n * @dev Stores a new address in the EIP1967 implementation slot.\n */\n function _setImplementation(address newImplementation) private {\n require(Address.isContract(newImplementation), \"ERC1967: new implementation is not a contract\");\n StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value = newImplementation;\n }\n\n /**\n * @dev Perform implementation upgrade\n *\n * Emits an {Upgraded} event.\n */\n function _upgradeTo(address newImplementation) internal {\n _setImplementation(newImplementation);\n emit Upgraded(newImplementation);\n }\n\n /**\n * @dev Perform implementation upgrade with additional setup call.\n *\n * Emits an {Upgraded} event.\n */\n function _upgradeToAndCall(\n address newImplementation,\n bytes memory data,\n bool forceCall\n ) internal {\n _upgradeTo(newImplementation);\n if (data.length > 0 || forceCall) {\n Address.functionDelegateCall(newImplementation, data);\n }\n }\n\n /**\n * @dev Perform implementation upgrade with security checks for UUPS proxies, and additional setup call.\n *\n * Emits an {Upgraded} event.\n */\n function _upgradeToAndCallUUPS(\n address newImplementation,\n bytes memory data,\n bool forceCall\n ) internal {\n // Upgrades from old implementations will perform a rollback test. This test requires the new\n // implementation to upgrade back to the old, non-ERC1822 compliant, implementation. Removing\n // this special case will break upgrade paths from old UUPS implementation to new ones.\n if (StorageSlot.getBooleanSlot(_ROLLBACK_SLOT).value) {\n _setImplementation(newImplementation);\n } else {\n try IERC1822Proxiable(newImplementation).proxiableUUID() returns (bytes32 slot) {\n require(slot == _IMPLEMENTATION_SLOT, \"ERC1967Upgrade: unsupported proxiableUUID\");\n } catch {\n revert(\"ERC1967Upgrade: new implementation is not UUPS\");\n }\n _upgradeToAndCall(newImplementation, data, forceCall);\n }\n }\n\n /**\n * @dev Storage slot with the admin of the contract.\n * This is the keccak-256 hash of \"eip1967.proxy.admin\" subtracted by 1, and is\n * validated in the constructor.\n */\n bytes32 internal constant _ADMIN_SLOT = 0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103;\n\n /**\n * @dev Emitted when the admin account has changed.\n */\n event AdminChanged(address previousAdmin, address newAdmin);\n\n /**\n * @dev Returns the current admin.\n */\n function _getAdmin() internal view returns (address) {\n return StorageSlot.getAddressSlot(_ADMIN_SLOT).value;\n }\n\n /**\n * @dev Stores a new address in the EIP1967 admin slot.\n */\n function _setAdmin(address newAdmin) private {\n require(newAdmin != address(0), \"ERC1967: new admin is the zero address\");\n StorageSlot.getAddressSlot(_ADMIN_SLOT).value = newAdmin;\n }\n\n /**\n * @dev Changes the admin of the proxy.\n *\n * Emits an {AdminChanged} event.\n */\n function _changeAdmin(address newAdmin) internal {\n emit AdminChanged(_getAdmin(), newAdmin);\n _setAdmin(newAdmin);\n }\n\n /**\n * @dev The storage slot of the UpgradeableBeacon contract which defines the implementation for this proxy.\n * This is bytes32(uint256(keccak256('eip1967.proxy.beacon')) - 1)) and is validated in the constructor.\n */\n bytes32 internal constant _BEACON_SLOT = 0xa3f0ad74e5423aebfd80d3ef4346578335a9a72aeaee59ff6cb3582b35133d50;\n\n /**\n * @dev Emitted when the beacon is upgraded.\n */\n event BeaconUpgraded(address indexed beacon);\n\n /**\n * @dev Returns the current beacon.\n */\n function _getBeacon() internal view returns (address) {\n return StorageSlot.getAddressSlot(_BEACON_SLOT).value;\n }\n\n /**\n * @dev Stores a new beacon in the EIP1967 beacon slot.\n */\n function _setBeacon(address newBeacon) private {\n require(Address.isContract(newBeacon), \"ERC1967: new beacon is not a contract\");\n require(\n Address.isContract(IBeacon(newBeacon).implementation()),\n \"ERC1967: beacon implementation is not a contract\"\n );\n StorageSlot.getAddressSlot(_BEACON_SLOT).value = newBeacon;\n }\n\n /**\n * @dev Perform beacon upgrade with additional setup call. Note: This upgrades the address of the beacon, it does\n * not upgrade the implementation contained in the beacon (see {UpgradeableBeacon-_setImplementation} for that).\n *\n * Emits a {BeaconUpgraded} event.\n */\n function _upgradeBeaconToAndCall(\n address newBeacon,\n bytes memory data,\n bool forceCall\n ) internal {\n _setBeacon(newBeacon);\n emit BeaconUpgraded(newBeacon);\n if (data.length > 0 || forceCall) {\n Address.functionDelegateCall(IBeacon(newBeacon).implementation(), data);\n }\n }\n}\n" + }, + "@openzeppelin/contracts/proxy/Proxy.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.6.0) (proxy/Proxy.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev This abstract contract provides a fallback function that delegates all calls to another contract using the EVM\n * instruction `delegatecall`. We refer to the second contract as the _implementation_ behind the proxy, and it has to\n * be specified by overriding the virtual {_implementation} function.\n *\n * Additionally, delegation to the implementation can be triggered manually through the {_fallback} function, or to a\n * different contract through the {_delegate} function.\n *\n * The success and return data of the delegated call will be returned back to the caller of the proxy.\n */\nabstract contract Proxy {\n /**\n * @dev Delegates the current call to `implementation`.\n *\n * This function does not return to its internal call site, it will return directly to the external caller.\n */\n function _delegate(address implementation) internal virtual {\n assembly {\n // Copy msg.data. We take full control of memory in this inline assembly\n // block because it will not return to Solidity code. We overwrite the\n // Solidity scratch pad at memory position 0.\n calldatacopy(0, 0, calldatasize())\n\n // Call the implementation.\n // out and outsize are 0 because we don't know the size yet.\n let result := delegatecall(gas(), implementation, 0, calldatasize(), 0, 0)\n\n // Copy the returned data.\n returndatacopy(0, 0, returndatasize())\n\n switch result\n // delegatecall returns 0 on error.\n case 0 {\n revert(0, returndatasize())\n }\n default {\n return(0, returndatasize())\n }\n }\n }\n\n /**\n * @dev This is a virtual function that should be overridden so it returns the address to which the fallback function\n * and {_fallback} should delegate.\n */\n function _implementation() internal view virtual returns (address);\n\n /**\n * @dev Delegates the current call to the address returned by `_implementation()`.\n *\n * This function does not return to its internal call site, it will return directly to the external caller.\n */\n function _fallback() internal virtual {\n _beforeFallback();\n _delegate(_implementation());\n }\n\n /**\n * @dev Fallback function that delegates calls to the address returned by `_implementation()`. Will run if no other\n * function in the contract matches the call data.\n */\n fallback() external payable virtual {\n _fallback();\n }\n\n /**\n * @dev Fallback function that delegates calls to the address returned by `_implementation()`. Will run if call data\n * is empty.\n */\n receive() external payable virtual {\n _fallback();\n }\n\n /**\n * @dev Hook that is called before falling back to the implementation. Can happen as part of a manual `_fallback`\n * call, or as part of the Solidity `fallback` or `receive` functions.\n *\n * If overridden should call `super._beforeFallback()`.\n */\n function _beforeFallback() internal virtual {}\n}\n" + }, + "@openzeppelin/contracts/token/ERC20/ERC20.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (token/ERC20/ERC20.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./IERC20.sol\";\nimport \"./extensions/IERC20Metadata.sol\";\nimport \"../../utils/Context.sol\";\n\n/**\n * @dev Implementation of the {IERC20} interface.\n *\n * This implementation is agnostic to the way tokens are created. This means\n * that a supply mechanism has to be added in a derived contract using {_mint}.\n * For a generic mechanism see {ERC20PresetMinterPauser}.\n *\n * TIP: For a detailed writeup see our guide\n * https://forum.zeppelin.solutions/t/how-to-implement-erc20-supply-mechanisms/226[How\n * to implement supply mechanisms].\n *\n * We have followed general OpenZeppelin Contracts guidelines: functions revert\n * instead returning `false` on failure. This behavior is nonetheless\n * conventional and does not conflict with the expectations of ERC20\n * applications.\n *\n * Additionally, an {Approval} event is emitted on calls to {transferFrom}.\n * This allows applications to reconstruct the allowance for all accounts just\n * by listening to said events. Other implementations of the EIP may not emit\n * these events, as it isn't required by the specification.\n *\n * Finally, the non-standard {decreaseAllowance} and {increaseAllowance}\n * functions have been added to mitigate the well-known issues around setting\n * allowances. See {IERC20-approve}.\n */\ncontract ERC20 is Context, IERC20, IERC20Metadata {\n mapping(address => uint256) private _balances;\n\n mapping(address => mapping(address => uint256)) private _allowances;\n\n uint256 private _totalSupply;\n\n string private _name;\n string private _symbol;\n\n /**\n * @dev Sets the values for {name} and {symbol}.\n *\n * The default value of {decimals} is 18. To select a different value for\n * {decimals} you should overload it.\n *\n * All two of these values are immutable: they can only be set once during\n * construction.\n */\n constructor(string memory name_, string memory symbol_) {\n _name = name_;\n _symbol = symbol_;\n }\n\n /**\n * @dev Returns the name of the token.\n */\n function name() public view virtual override returns (string memory) {\n return _name;\n }\n\n /**\n * @dev Returns the symbol of the token, usually a shorter version of the\n * name.\n */\n function symbol() public view virtual override returns (string memory) {\n return _symbol;\n }\n\n /**\n * @dev Returns the number of decimals used to get its user representation.\n * For example, if `decimals` equals `2`, a balance of `505` tokens should\n * be displayed to a user as `5.05` (`505 / 10 ** 2`).\n *\n * Tokens usually opt for a value of 18, imitating the relationship between\n * Ether and Wei. This is the value {ERC20} uses, unless this function is\n * overridden;\n *\n * NOTE: This information is only used for _display_ purposes: it in\n * no way affects any of the arithmetic of the contract, including\n * {IERC20-balanceOf} and {IERC20-transfer}.\n */\n function decimals() public view virtual override returns (uint8) {\n return 18;\n }\n\n /**\n * @dev See {IERC20-totalSupply}.\n */\n function totalSupply() public view virtual override returns (uint256) {\n return _totalSupply;\n }\n\n /**\n * @dev See {IERC20-balanceOf}.\n */\n function balanceOf(address account) public view virtual override returns (uint256) {\n return _balances[account];\n }\n\n /**\n * @dev See {IERC20-transfer}.\n *\n * Requirements:\n *\n * - `to` cannot be the zero address.\n * - the caller must have a balance of at least `amount`.\n */\n function transfer(address to, uint256 amount) public virtual override returns (bool) {\n address owner = _msgSender();\n _transfer(owner, to, amount);\n return true;\n }\n\n /**\n * @dev See {IERC20-allowance}.\n */\n function allowance(address owner, address spender) public view virtual override returns (uint256) {\n return _allowances[owner][spender];\n }\n\n /**\n * @dev See {IERC20-approve}.\n *\n * NOTE: If `amount` is the maximum `uint256`, the allowance is not updated on\n * `transferFrom`. This is semantically equivalent to an infinite approval.\n *\n * Requirements:\n *\n * - `spender` cannot be the zero address.\n */\n function approve(address spender, uint256 amount) public virtual override returns (bool) {\n address owner = _msgSender();\n _approve(owner, spender, amount);\n return true;\n }\n\n /**\n * @dev See {IERC20-transferFrom}.\n *\n * Emits an {Approval} event indicating the updated allowance. This is not\n * required by the EIP. See the note at the beginning of {ERC20}.\n *\n * NOTE: Does not update the allowance if the current allowance\n * is the maximum `uint256`.\n *\n * Requirements:\n *\n * - `from` and `to` cannot be the zero address.\n * - `from` must have a balance of at least `amount`.\n * - the caller must have allowance for ``from``'s tokens of at least\n * `amount`.\n */\n function transferFrom(\n address from,\n address to,\n uint256 amount\n ) public virtual override returns (bool) {\n address spender = _msgSender();\n _spendAllowance(from, spender, amount);\n _transfer(from, to, amount);\n return true;\n }\n\n /**\n * @dev Atomically increases the allowance granted to `spender` by the caller.\n *\n * This is an alternative to {approve} that can be used as a mitigation for\n * problems described in {IERC20-approve}.\n *\n * Emits an {Approval} event indicating the updated allowance.\n *\n * Requirements:\n *\n * - `spender` cannot be the zero address.\n */\n function increaseAllowance(address spender, uint256 addedValue) public virtual returns (bool) {\n address owner = _msgSender();\n _approve(owner, spender, allowance(owner, spender) + addedValue);\n return true;\n }\n\n /**\n * @dev Atomically decreases the allowance granted to `spender` by the caller.\n *\n * This is an alternative to {approve} that can be used as a mitigation for\n * problems described in {IERC20-approve}.\n *\n * Emits an {Approval} event indicating the updated allowance.\n *\n * Requirements:\n *\n * - `spender` cannot be the zero address.\n * - `spender` must have allowance for the caller of at least\n * `subtractedValue`.\n */\n function decreaseAllowance(address spender, uint256 subtractedValue) public virtual returns (bool) {\n address owner = _msgSender();\n uint256 currentAllowance = allowance(owner, spender);\n require(currentAllowance >= subtractedValue, \"ERC20: decreased allowance below zero\");\n unchecked {\n _approve(owner, spender, currentAllowance - subtractedValue);\n }\n\n return true;\n }\n\n /**\n * @dev Moves `amount` of tokens from `from` to `to`.\n *\n * This internal function is equivalent to {transfer}, and can be used to\n * e.g. implement automatic token fees, slashing mechanisms, etc.\n *\n * Emits a {Transfer} event.\n *\n * Requirements:\n *\n * - `from` cannot be the zero address.\n * - `to` cannot be the zero address.\n * - `from` must have a balance of at least `amount`.\n */\n function _transfer(\n address from,\n address to,\n uint256 amount\n ) internal virtual {\n require(from != address(0), \"ERC20: transfer from the zero address\");\n require(to != address(0), \"ERC20: transfer to the zero address\");\n\n _beforeTokenTransfer(from, to, amount);\n\n uint256 fromBalance = _balances[from];\n require(fromBalance >= amount, \"ERC20: transfer amount exceeds balance\");\n unchecked {\n _balances[from] = fromBalance - amount;\n }\n _balances[to] += amount;\n\n emit Transfer(from, to, amount);\n\n _afterTokenTransfer(from, to, amount);\n }\n\n /** @dev Creates `amount` tokens and assigns them to `account`, increasing\n * the total supply.\n *\n * Emits a {Transfer} event with `from` set to the zero address.\n *\n * Requirements:\n *\n * - `account` cannot be the zero address.\n */\n function _mint(address account, uint256 amount) internal virtual {\n require(account != address(0), \"ERC20: mint to the zero address\");\n\n _beforeTokenTransfer(address(0), account, amount);\n\n _totalSupply += amount;\n _balances[account] += amount;\n emit Transfer(address(0), account, amount);\n\n _afterTokenTransfer(address(0), account, amount);\n }\n\n /**\n * @dev Destroys `amount` tokens from `account`, reducing the\n * total supply.\n *\n * Emits a {Transfer} event with `to` set to the zero address.\n *\n * Requirements:\n *\n * - `account` cannot be the zero address.\n * - `account` must have at least `amount` tokens.\n */\n function _burn(address account, uint256 amount) internal virtual {\n require(account != address(0), \"ERC20: burn from the zero address\");\n\n _beforeTokenTransfer(account, address(0), amount);\n\n uint256 accountBalance = _balances[account];\n require(accountBalance >= amount, \"ERC20: burn amount exceeds balance\");\n unchecked {\n _balances[account] = accountBalance - amount;\n }\n _totalSupply -= amount;\n\n emit Transfer(account, address(0), amount);\n\n _afterTokenTransfer(account, address(0), amount);\n }\n\n /**\n * @dev Sets `amount` as the allowance of `spender` over the `owner` s tokens.\n *\n * This internal function is equivalent to `approve`, and can be used to\n * e.g. set automatic allowances for certain subsystems, etc.\n *\n * Emits an {Approval} event.\n *\n * Requirements:\n *\n * - `owner` cannot be the zero address.\n * - `spender` cannot be the zero address.\n */\n function _approve(\n address owner,\n address spender,\n uint256 amount\n ) internal virtual {\n require(owner != address(0), \"ERC20: approve from the zero address\");\n require(spender != address(0), \"ERC20: approve to the zero address\");\n\n _allowances[owner][spender] = amount;\n emit Approval(owner, spender, amount);\n }\n\n /**\n * @dev Updates `owner` s allowance for `spender` based on spent `amount`.\n *\n * Does not update the allowance amount in case of infinite allowance.\n * Revert if not enough allowance is available.\n *\n * Might emit an {Approval} event.\n */\n function _spendAllowance(\n address owner,\n address spender,\n uint256 amount\n ) internal virtual {\n uint256 currentAllowance = allowance(owner, spender);\n if (currentAllowance != type(uint256).max) {\n require(currentAllowance >= amount, \"ERC20: insufficient allowance\");\n unchecked {\n _approve(owner, spender, currentAllowance - amount);\n }\n }\n }\n\n /**\n * @dev Hook that is called before any transfer of tokens. This includes\n * minting and burning.\n *\n * Calling conditions:\n *\n * - when `from` and `to` are both non-zero, `amount` of ``from``'s tokens\n * will be transferred to `to`.\n * - when `from` is zero, `amount` tokens will be minted for `to`.\n * - when `to` is zero, `amount` of ``from``'s tokens will be burned.\n * - `from` and `to` are never both zero.\n *\n * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].\n */\n function _beforeTokenTransfer(\n address from,\n address to,\n uint256 amount\n ) internal virtual {}\n\n /**\n * @dev Hook that is called after any transfer of tokens. This includes\n * minting and burning.\n *\n * Calling conditions:\n *\n * - when `from` and `to` are both non-zero, `amount` of ``from``'s tokens\n * has been transferred to `to`.\n * - when `from` is zero, `amount` tokens have been minted for `to`.\n * - when `to` is zero, `amount` of ``from``'s tokens have been burned.\n * - `from` and `to` are never both zero.\n *\n * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].\n */\n function _afterTokenTransfer(\n address from,\n address to,\n uint256 amount\n ) internal virtual {}\n}\n" + }, + "@openzeppelin/contracts/token/ERC20/extensions/draft-ERC20Permit.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.6.0) (token/ERC20/extensions/draft-ERC20Permit.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./draft-IERC20Permit.sol\";\nimport \"../ERC20.sol\";\nimport \"../../../utils/cryptography/draft-EIP712.sol\";\nimport \"../../../utils/cryptography/ECDSA.sol\";\nimport \"../../../utils/Counters.sol\";\n\n/**\n * @dev Implementation of the ERC20 Permit extension allowing approvals to be made via signatures, as defined in\n * https://eips.ethereum.org/EIPS/eip-2612[EIP-2612].\n *\n * Adds the {permit} method, which can be used to change an account's ERC20 allowance (see {IERC20-allowance}) by\n * presenting a message signed by the account. By not relying on `{IERC20-approve}`, the token holder account doesn't\n * need to send a transaction, and thus is not required to hold Ether at all.\n *\n * _Available since v3.4._\n */\nabstract contract ERC20Permit is ERC20, IERC20Permit, EIP712 {\n using Counters for Counters.Counter;\n\n mapping(address => Counters.Counter) private _nonces;\n\n // solhint-disable-next-line var-name-mixedcase\n bytes32 private constant _PERMIT_TYPEHASH =\n keccak256(\"Permit(address owner,address spender,uint256 value,uint256 nonce,uint256 deadline)\");\n /**\n * @dev In previous versions `_PERMIT_TYPEHASH` was declared as `immutable`.\n * However, to ensure consistency with the upgradeable transpiler, we will continue\n * to reserve a slot.\n * @custom:oz-renamed-from _PERMIT_TYPEHASH\n */\n // solhint-disable-next-line var-name-mixedcase\n bytes32 private _PERMIT_TYPEHASH_DEPRECATED_SLOT;\n\n /**\n * @dev Initializes the {EIP712} domain separator using the `name` parameter, and setting `version` to `\"1\"`.\n *\n * It's a good idea to use the same `name` that is defined as the ERC20 token name.\n */\n constructor(string memory name) EIP712(name, \"1\") {}\n\n /**\n * @dev See {IERC20Permit-permit}.\n */\n function permit(\n address owner,\n address spender,\n uint256 value,\n uint256 deadline,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) public virtual override {\n require(block.timestamp <= deadline, \"ERC20Permit: expired deadline\");\n\n bytes32 structHash = keccak256(abi.encode(_PERMIT_TYPEHASH, owner, spender, value, _useNonce(owner), deadline));\n\n bytes32 hash = _hashTypedDataV4(structHash);\n\n address signer = ECDSA.recover(hash, v, r, s);\n require(signer == owner, \"ERC20Permit: invalid signature\");\n\n _approve(owner, spender, value);\n }\n\n /**\n * @dev See {IERC20Permit-nonces}.\n */\n function nonces(address owner) public view virtual override returns (uint256) {\n return _nonces[owner].current();\n }\n\n /**\n * @dev See {IERC20Permit-DOMAIN_SEPARATOR}.\n */\n // solhint-disable-next-line func-name-mixedcase\n function DOMAIN_SEPARATOR() external view override returns (bytes32) {\n return _domainSeparatorV4();\n }\n\n /**\n * @dev \"Consume a nonce\": return the current value and increment.\n *\n * _Available since v4.1._\n */\n function _useNonce(address owner) internal virtual returns (uint256 current) {\n Counters.Counter storage nonce = _nonces[owner];\n current = nonce.current();\n nonce.increment();\n }\n}\n" + }, + "@openzeppelin/contracts/token/ERC20/extensions/draft-IERC20Permit.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (token/ERC20/extensions/draft-IERC20Permit.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Interface of the ERC20 Permit extension allowing approvals to be made via signatures, as defined in\n * https://eips.ethereum.org/EIPS/eip-2612[EIP-2612].\n *\n * Adds the {permit} method, which can be used to change an account's ERC20 allowance (see {IERC20-allowance}) by\n * presenting a message signed by the account. By not relying on {IERC20-approve}, the token holder account doesn't\n * need to send a transaction, and thus is not required to hold Ether at all.\n */\ninterface IERC20Permit {\n /**\n * @dev Sets `value` as the allowance of `spender` over ``owner``'s tokens,\n * given ``owner``'s signed approval.\n *\n * IMPORTANT: The same issues {IERC20-approve} has related to transaction\n * ordering also apply here.\n *\n * Emits an {Approval} event.\n *\n * Requirements:\n *\n * - `spender` cannot be the zero address.\n * - `deadline` must be a timestamp in the future.\n * - `v`, `r` and `s` must be a valid `secp256k1` signature from `owner`\n * over the EIP712-formatted function arguments.\n * - the signature must use ``owner``'s current nonce (see {nonces}).\n *\n * For more information on the signature format, see the\n * https://eips.ethereum.org/EIPS/eip-2612#specification[relevant EIP\n * section].\n */\n function permit(\n address owner,\n address spender,\n uint256 value,\n uint256 deadline,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) external;\n\n /**\n * @dev Returns the current nonce for `owner`. This value must be\n * included whenever a signature is generated for {permit}.\n *\n * Every successful call to {permit} increases ``owner``'s nonce by one. This\n * prevents a signature from being used multiple times.\n */\n function nonces(address owner) external view returns (uint256);\n\n /**\n * @dev Returns the domain separator used in the encoding of the signature for {permit}, as defined by {EIP712}.\n */\n // solhint-disable-next-line func-name-mixedcase\n function DOMAIN_SEPARATOR() external view returns (bytes32);\n}\n" + }, + "@openzeppelin/contracts/token/ERC20/extensions/IERC20Metadata.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (token/ERC20/extensions/IERC20Metadata.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../IERC20.sol\";\n\n/**\n * @dev Interface for the optional metadata functions from the ERC20 standard.\n *\n * _Available since v4.1._\n */\ninterface IERC20Metadata is IERC20 {\n /**\n * @dev Returns the name of the token.\n */\n function name() external view returns (string memory);\n\n /**\n * @dev Returns the symbol of the token.\n */\n function symbol() external view returns (string memory);\n\n /**\n * @dev Returns the decimals places of the token.\n */\n function decimals() external view returns (uint8);\n}\n" + }, + "@openzeppelin/contracts/token/ERC20/IERC20.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.6.0) (token/ERC20/IERC20.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Interface of the ERC20 standard as defined in the EIP.\n */\ninterface IERC20 {\n /**\n * @dev Emitted when `value` tokens are moved from one account (`from`) to\n * another (`to`).\n *\n * Note that `value` may be zero.\n */\n event Transfer(address indexed from, address indexed to, uint256 value);\n\n /**\n * @dev Emitted when the allowance of a `spender` for an `owner` is set by\n * a call to {approve}. `value` is the new allowance.\n */\n event Approval(address indexed owner, address indexed spender, uint256 value);\n\n /**\n * @dev Returns the amount of tokens in existence.\n */\n function totalSupply() external view returns (uint256);\n\n /**\n * @dev Returns the amount of tokens owned by `account`.\n */\n function balanceOf(address account) external view returns (uint256);\n\n /**\n * @dev Moves `amount` tokens from the caller's account to `to`.\n *\n * Returns a boolean value indicating whether the operation succeeded.\n *\n * Emits a {Transfer} event.\n */\n function transfer(address to, uint256 amount) external returns (bool);\n\n /**\n * @dev Returns the remaining number of tokens that `spender` will be\n * allowed to spend on behalf of `owner` through {transferFrom}. This is\n * zero by default.\n *\n * This value changes when {approve} or {transferFrom} are called.\n */\n function allowance(address owner, address spender) external view returns (uint256);\n\n /**\n * @dev Sets `amount` as the allowance of `spender` over the caller's tokens.\n *\n * Returns a boolean value indicating whether the operation succeeded.\n *\n * IMPORTANT: Beware that changing an allowance with this method brings the risk\n * that someone may use both the old and the new allowance by unfortunate\n * transaction ordering. One possible solution to mitigate this race\n * condition is to first reduce the spender's allowance to 0 and set the\n * desired value afterwards:\n * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729\n *\n * Emits an {Approval} event.\n */\n function approve(address spender, uint256 amount) external returns (bool);\n\n /**\n * @dev Moves `amount` tokens from `from` to `to` using the\n * allowance mechanism. `amount` is then deducted from the caller's\n * allowance.\n *\n * Returns a boolean value indicating whether the operation succeeded.\n *\n * Emits a {Transfer} event.\n */\n function transferFrom(\n address from,\n address to,\n uint256 amount\n ) external returns (bool);\n}\n" + }, + "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (token/ERC20/utils/SafeERC20.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../IERC20.sol\";\nimport \"../extensions/draft-IERC20Permit.sol\";\nimport \"../../../utils/Address.sol\";\n\n/**\n * @title SafeERC20\n * @dev Wrappers around ERC20 operations that throw on failure (when the token\n * contract returns false). Tokens that return no value (and instead revert or\n * throw on failure) are also supported, non-reverting calls are assumed to be\n * successful.\n * To use this library you can add a `using SafeERC20 for IERC20;` statement to your contract,\n * which allows you to call the safe operations as `token.safeTransfer(...)`, etc.\n */\nlibrary SafeERC20 {\n using Address for address;\n\n function safeTransfer(\n IERC20 token,\n address to,\n uint256 value\n ) internal {\n _callOptionalReturn(token, abi.encodeWithSelector(token.transfer.selector, to, value));\n }\n\n function safeTransferFrom(\n IERC20 token,\n address from,\n address to,\n uint256 value\n ) internal {\n _callOptionalReturn(token, abi.encodeWithSelector(token.transferFrom.selector, from, to, value));\n }\n\n /**\n * @dev Deprecated. This function has issues similar to the ones found in\n * {IERC20-approve}, and its usage is discouraged.\n *\n * Whenever possible, use {safeIncreaseAllowance} and\n * {safeDecreaseAllowance} instead.\n */\n function safeApprove(\n IERC20 token,\n address spender,\n uint256 value\n ) internal {\n // safeApprove should only be called when setting an initial allowance,\n // or when resetting it to zero. To increase and decrease it, use\n // 'safeIncreaseAllowance' and 'safeDecreaseAllowance'\n require(\n (value == 0) || (token.allowance(address(this), spender) == 0),\n \"SafeERC20: approve from non-zero to non-zero allowance\"\n );\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, value));\n }\n\n function safeIncreaseAllowance(\n IERC20 token,\n address spender,\n uint256 value\n ) internal {\n uint256 newAllowance = token.allowance(address(this), spender) + value;\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));\n }\n\n function safeDecreaseAllowance(\n IERC20 token,\n address spender,\n uint256 value\n ) internal {\n unchecked {\n uint256 oldAllowance = token.allowance(address(this), spender);\n require(oldAllowance >= value, \"SafeERC20: decreased allowance below zero\");\n uint256 newAllowance = oldAllowance - value;\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));\n }\n }\n\n function safePermit(\n IERC20Permit token,\n address owner,\n address spender,\n uint256 value,\n uint256 deadline,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) internal {\n uint256 nonceBefore = token.nonces(owner);\n token.permit(owner, spender, value, deadline, v, r, s);\n uint256 nonceAfter = token.nonces(owner);\n require(nonceAfter == nonceBefore + 1, \"SafeERC20: permit did not succeed\");\n }\n\n /**\n * @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement\n * on the return value: the return value is optional (but if data is returned, it must not be false).\n * @param token The token targeted by the call.\n * @param data The call data (encoded using abi.encode or one of its variants).\n */\n function _callOptionalReturn(IERC20 token, bytes memory data) private {\n // We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since\n // we're implementing it ourselves. We use {Address.functionCall} to perform this call, which verifies that\n // the target address contains contract code and also asserts for success in the low-level call.\n\n bytes memory returndata = address(token).functionCall(data, \"SafeERC20: low-level call failed\");\n if (returndata.length > 0) {\n // Return data is optional\n require(abi.decode(returndata, (bool)), \"SafeERC20: ERC20 operation did not succeed\");\n }\n }\n}\n" + }, + "@openzeppelin/contracts/token/ERC721/extensions/IERC721Metadata.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (token/ERC721/extensions/IERC721Metadata.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../IERC721.sol\";\n\n/**\n * @title ERC-721 Non-Fungible Token Standard, optional metadata extension\n * @dev See https://eips.ethereum.org/EIPS/eip-721\n */\ninterface IERC721Metadata is IERC721 {\n /**\n * @dev Returns the token collection name.\n */\n function name() external view returns (string memory);\n\n /**\n * @dev Returns the token collection symbol.\n */\n function symbol() external view returns (string memory);\n\n /**\n * @dev Returns the Uniform Resource Identifier (URI) for `tokenId` token.\n */\n function tokenURI(uint256 tokenId) external view returns (string memory);\n}\n" + }, + "@openzeppelin/contracts/token/ERC721/IERC721.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (token/ERC721/IERC721.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../../utils/introspection/IERC165.sol\";\n\n/**\n * @dev Required interface of an ERC721 compliant contract.\n */\ninterface IERC721 is IERC165 {\n /**\n * @dev Emitted when `tokenId` token is transferred from `from` to `to`.\n */\n event Transfer(address indexed from, address indexed to, uint256 indexed tokenId);\n\n /**\n * @dev Emitted when `owner` enables `approved` to manage the `tokenId` token.\n */\n event Approval(address indexed owner, address indexed approved, uint256 indexed tokenId);\n\n /**\n * @dev Emitted when `owner` enables or disables (`approved`) `operator` to manage all of its assets.\n */\n event ApprovalForAll(address indexed owner, address indexed operator, bool approved);\n\n /**\n * @dev Returns the number of tokens in ``owner``'s account.\n */\n function balanceOf(address owner) external view returns (uint256 balance);\n\n /**\n * @dev Returns the owner of the `tokenId` token.\n *\n * Requirements:\n *\n * - `tokenId` must exist.\n */\n function ownerOf(uint256 tokenId) external view returns (address owner);\n\n /**\n * @dev Safely transfers `tokenId` token from `from` to `to`.\n *\n * Requirements:\n *\n * - `from` cannot be the zero address.\n * - `to` cannot be the zero address.\n * - `tokenId` token must exist and be owned by `from`.\n * - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}.\n * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.\n *\n * Emits a {Transfer} event.\n */\n function safeTransferFrom(\n address from,\n address to,\n uint256 tokenId,\n bytes calldata data\n ) external;\n\n /**\n * @dev Safely transfers `tokenId` token from `from` to `to`, checking first that contract recipients\n * are aware of the ERC721 protocol to prevent tokens from being forever locked.\n *\n * Requirements:\n *\n * - `from` cannot be the zero address.\n * - `to` cannot be the zero address.\n * - `tokenId` token must exist and be owned by `from`.\n * - If the caller is not `from`, it must have been allowed to move this token by either {approve} or {setApprovalForAll}.\n * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.\n *\n * Emits a {Transfer} event.\n */\n function safeTransferFrom(\n address from,\n address to,\n uint256 tokenId\n ) external;\n\n /**\n * @dev Transfers `tokenId` token from `from` to `to`.\n *\n * WARNING: Usage of this method is discouraged, use {safeTransferFrom} whenever possible.\n *\n * Requirements:\n *\n * - `from` cannot be the zero address.\n * - `to` cannot be the zero address.\n * - `tokenId` token must be owned by `from`.\n * - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}.\n *\n * Emits a {Transfer} event.\n */\n function transferFrom(\n address from,\n address to,\n uint256 tokenId\n ) external;\n\n /**\n * @dev Gives permission to `to` to transfer `tokenId` token to another account.\n * The approval is cleared when the token is transferred.\n *\n * Only a single account can be approved at a time, so approving the zero address clears previous approvals.\n *\n * Requirements:\n *\n * - The caller must own the token or be an approved operator.\n * - `tokenId` must exist.\n *\n * Emits an {Approval} event.\n */\n function approve(address to, uint256 tokenId) external;\n\n /**\n * @dev Approve or remove `operator` as an operator for the caller.\n * Operators can call {transferFrom} or {safeTransferFrom} for any token owned by the caller.\n *\n * Requirements:\n *\n * - The `operator` cannot be the caller.\n *\n * Emits an {ApprovalForAll} event.\n */\n function setApprovalForAll(address operator, bool _approved) external;\n\n /**\n * @dev Returns the account approved for `tokenId` token.\n *\n * Requirements:\n *\n * - `tokenId` must exist.\n */\n function getApproved(uint256 tokenId) external view returns (address operator);\n\n /**\n * @dev Returns if the `operator` is allowed to manage all of the assets of `owner`.\n *\n * See {setApprovalForAll}\n */\n function isApprovedForAll(address owner, address operator) external view returns (bool);\n}\n" + }, + "@openzeppelin/contracts/utils/Address.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (utils/Address.sol)\n\npragma solidity ^0.8.1;\n\n/**\n * @dev Collection of functions related to the address type\n */\nlibrary Address {\n /**\n * @dev Returns true if `account` is a contract.\n *\n * [IMPORTANT]\n * ====\n * It is unsafe to assume that an address for which this function returns\n * false is an externally-owned account (EOA) and not a contract.\n *\n * Among others, `isContract` will return false for the following\n * types of addresses:\n *\n * - an externally-owned account\n * - a contract in construction\n * - an address where a contract will be created\n * - an address where a contract lived, but was destroyed\n * ====\n *\n * [IMPORTANT]\n * ====\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\n *\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\n * constructor.\n * ====\n */\n function isContract(address account) internal view returns (bool) {\n // This method relies on extcodesize/address.code.length, which returns 0\n // for contracts in construction, since the code is only stored at the end\n // of the constructor execution.\n\n return account.code.length > 0;\n }\n\n /**\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\n * `recipient`, forwarding all available gas and reverting on errors.\n *\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\n * imposed by `transfer`, making them unable to receive funds via\n * `transfer`. {sendValue} removes this limitation.\n *\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\n *\n * IMPORTANT: because control is transferred to `recipient`, care must be\n * taken to not create reentrancy vulnerabilities. Consider using\n * {ReentrancyGuard} or the\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\n */\n function sendValue(address payable recipient, uint256 amount) internal {\n require(address(this).balance >= amount, \"Address: insufficient balance\");\n\n (bool success, ) = recipient.call{value: amount}(\"\");\n require(success, \"Address: unable to send value, recipient may have reverted\");\n }\n\n /**\n * @dev Performs a Solidity function call using a low level `call`. A\n * plain `call` is an unsafe replacement for a function call: use this\n * function instead.\n *\n * If `target` reverts with a revert reason, it is bubbled up by this\n * function (like regular Solidity function calls).\n *\n * Returns the raw returned data. To convert to the expected return value,\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\n *\n * Requirements:\n *\n * - `target` must be a contract.\n * - calling `target` with `data` must not revert.\n *\n * _Available since v3.1._\n */\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionCall(target, data, \"Address: low-level call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\n * `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, 0, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but also transferring `value` wei to `target`.\n *\n * Requirements:\n *\n * - the calling contract must have an ETH balance of at least `value`.\n * - the called Solidity function must be `payable`.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, value, \"Address: low-level call with value failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\n * with `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(address(this).balance >= value, \"Address: insufficient balance for call\");\n require(isContract(target), \"Address: call to non-contract\");\n\n (bool success, bytes memory returndata) = target.call{value: value}(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\n return functionStaticCall(target, data, \"Address: low-level static call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal view returns (bytes memory) {\n require(isContract(target), \"Address: static call to non-contract\");\n\n (bool success, bytes memory returndata) = target.staticcall(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a delegate call.\n *\n * _Available since v3.4._\n */\n function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionDelegateCall(target, data, \"Address: low-level delegate call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a delegate call.\n *\n * _Available since v3.4._\n */\n function functionDelegateCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(isContract(target), \"Address: delegate call to non-contract\");\n\n (bool success, bytes memory returndata) = target.delegatecall(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the\n * revert reason using the provided one.\n *\n * _Available since v4.3._\n */\n function verifyCallResult(\n bool success,\n bytes memory returndata,\n string memory errorMessage\n ) internal pure returns (bytes memory) {\n if (success) {\n return returndata;\n } else {\n // Look for revert reason and bubble it up if present\n if (returndata.length > 0) {\n // The easiest way to bubble the revert reason is using memory via assembly\n /// @solidity memory-safe-assembly\n assembly {\n let returndata_size := mload(returndata)\n revert(add(32, returndata), returndata_size)\n }\n } else {\n revert(errorMessage);\n }\n }\n }\n}\n" + }, + "@openzeppelin/contracts/utils/Context.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Provides information about the current execution context, including the\n * sender of the transaction and its data. While these are generally available\n * via msg.sender and msg.data, they should not be accessed in such a direct\n * manner, since when dealing with meta-transactions the account sending and\n * paying for execution may not be the actual sender (as far as an application\n * is concerned).\n *\n * This contract is only required for intermediate, library-like contracts.\n */\nabstract contract Context {\n function _msgSender() internal view virtual returns (address) {\n return msg.sender;\n }\n\n function _msgData() internal view virtual returns (bytes calldata) {\n return msg.data;\n }\n}\n" + }, + "@openzeppelin/contracts/utils/Counters.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (utils/Counters.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @title Counters\n * @author Matt Condon (@shrugs)\n * @dev Provides counters that can only be incremented, decremented or reset. This can be used e.g. to track the number\n * of elements in a mapping, issuing ERC721 ids, or counting request ids.\n *\n * Include with `using Counters for Counters.Counter;`\n */\nlibrary Counters {\n struct Counter {\n // This variable should never be directly accessed by users of the library: interactions must be restricted to\n // the library's function. As of Solidity v0.5.2, this cannot be enforced, though there is a proposal to add\n // this feature: see https://github.com/ethereum/solidity/issues/4637\n uint256 _value; // default: 0\n }\n\n function current(Counter storage counter) internal view returns (uint256) {\n return counter._value;\n }\n\n function increment(Counter storage counter) internal {\n unchecked {\n counter._value += 1;\n }\n }\n\n function decrement(Counter storage counter) internal {\n uint256 value = counter._value;\n require(value > 0, \"Counter: decrement overflow\");\n unchecked {\n counter._value = value - 1;\n }\n }\n\n function reset(Counter storage counter) internal {\n counter._value = 0;\n }\n}\n" + }, + "@openzeppelin/contracts/utils/cryptography/draft-EIP712.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (utils/cryptography/draft-EIP712.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./ECDSA.sol\";\n\n/**\n * @dev https://eips.ethereum.org/EIPS/eip-712[EIP 712] is a standard for hashing and signing of typed structured data.\n *\n * The encoding specified in the EIP is very generic, and such a generic implementation in Solidity is not feasible,\n * thus this contract does not implement the encoding itself. Protocols need to implement the type-specific encoding\n * they need in their contracts using a combination of `abi.encode` and `keccak256`.\n *\n * This contract implements the EIP 712 domain separator ({_domainSeparatorV4}) that is used as part of the encoding\n * scheme, and the final step of the encoding to obtain the message digest that is then signed via ECDSA\n * ({_hashTypedDataV4}).\n *\n * The implementation of the domain separator was designed to be as efficient as possible while still properly updating\n * the chain id to protect against replay attacks on an eventual fork of the chain.\n *\n * NOTE: This contract implements the version of the encoding known as \"v4\", as implemented by the JSON RPC method\n * https://docs.metamask.io/guide/signing-data.html[`eth_signTypedDataV4` in MetaMask].\n *\n * _Available since v3.4._\n */\nabstract contract EIP712 {\n /* solhint-disable var-name-mixedcase */\n // Cache the domain separator as an immutable value, but also store the chain id that it corresponds to, in order to\n // invalidate the cached domain separator if the chain id changes.\n bytes32 private immutable _CACHED_DOMAIN_SEPARATOR;\n uint256 private immutable _CACHED_CHAIN_ID;\n address private immutable _CACHED_THIS;\n\n bytes32 private immutable _HASHED_NAME;\n bytes32 private immutable _HASHED_VERSION;\n bytes32 private immutable _TYPE_HASH;\n\n /* solhint-enable var-name-mixedcase */\n\n /**\n * @dev Initializes the domain separator and parameter caches.\n *\n * The meaning of `name` and `version` is specified in\n * https://eips.ethereum.org/EIPS/eip-712#definition-of-domainseparator[EIP 712]:\n *\n * - `name`: the user readable name of the signing domain, i.e. the name of the DApp or the protocol.\n * - `version`: the current major version of the signing domain.\n *\n * NOTE: These parameters cannot be changed except through a xref:learn::upgrading-smart-contracts.adoc[smart\n * contract upgrade].\n */\n constructor(string memory name, string memory version) {\n bytes32 hashedName = keccak256(bytes(name));\n bytes32 hashedVersion = keccak256(bytes(version));\n bytes32 typeHash = keccak256(\n \"EIP712Domain(string name,string version,uint256 chainId,address verifyingContract)\"\n );\n _HASHED_NAME = hashedName;\n _HASHED_VERSION = hashedVersion;\n _CACHED_CHAIN_ID = block.chainid;\n _CACHED_DOMAIN_SEPARATOR = _buildDomainSeparator(typeHash, hashedName, hashedVersion);\n _CACHED_THIS = address(this);\n _TYPE_HASH = typeHash;\n }\n\n /**\n * @dev Returns the domain separator for the current chain.\n */\n function _domainSeparatorV4() internal view returns (bytes32) {\n if (address(this) == _CACHED_THIS && block.chainid == _CACHED_CHAIN_ID) {\n return _CACHED_DOMAIN_SEPARATOR;\n } else {\n return _buildDomainSeparator(_TYPE_HASH, _HASHED_NAME, _HASHED_VERSION);\n }\n }\n\n function _buildDomainSeparator(\n bytes32 typeHash,\n bytes32 nameHash,\n bytes32 versionHash\n ) private view returns (bytes32) {\n return keccak256(abi.encode(typeHash, nameHash, versionHash, block.chainid, address(this)));\n }\n\n /**\n * @dev Given an already https://eips.ethereum.org/EIPS/eip-712#definition-of-hashstruct[hashed struct], this\n * function returns the hash of the fully encoded EIP712 message for this domain.\n *\n * This hash can be used together with {ECDSA-recover} to obtain the signer of a message. For example:\n *\n * ```solidity\n * bytes32 digest = _hashTypedDataV4(keccak256(abi.encode(\n * keccak256(\"Mail(address to,string contents)\"),\n * mailTo,\n * keccak256(bytes(mailContents))\n * )));\n * address signer = ECDSA.recover(digest, signature);\n * ```\n */\n function _hashTypedDataV4(bytes32 structHash) internal view virtual returns (bytes32) {\n return ECDSA.toTypedDataHash(_domainSeparatorV4(), structHash);\n }\n}\n" + }, + "@openzeppelin/contracts/utils/cryptography/ECDSA.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (utils/cryptography/ECDSA.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../Strings.sol\";\n\n/**\n * @dev Elliptic Curve Digital Signature Algorithm (ECDSA) operations.\n *\n * These functions can be used to verify that a message was signed by the holder\n * of the private keys of a given address.\n */\nlibrary ECDSA {\n enum RecoverError {\n NoError,\n InvalidSignature,\n InvalidSignatureLength,\n InvalidSignatureS,\n InvalidSignatureV\n }\n\n function _throwError(RecoverError error) private pure {\n if (error == RecoverError.NoError) {\n return; // no error: do nothing\n } else if (error == RecoverError.InvalidSignature) {\n revert(\"ECDSA: invalid signature\");\n } else if (error == RecoverError.InvalidSignatureLength) {\n revert(\"ECDSA: invalid signature length\");\n } else if (error == RecoverError.InvalidSignatureS) {\n revert(\"ECDSA: invalid signature 's' value\");\n } else if (error == RecoverError.InvalidSignatureV) {\n revert(\"ECDSA: invalid signature 'v' value\");\n }\n }\n\n /**\n * @dev Returns the address that signed a hashed message (`hash`) with\n * `signature` or error string. This address can then be used for verification purposes.\n *\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\n * this function rejects them by requiring the `s` value to be in the lower\n * half order, and the `v` value to be either 27 or 28.\n *\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\n * verification to be secure: it is possible to craft signatures that\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\n * this is by receiving a hash of the original message (which may otherwise\n * be too long), and then calling {toEthSignedMessageHash} on it.\n *\n * Documentation for signature generation:\n * - with https://web3js.readthedocs.io/en/v1.3.4/web3-eth-accounts.html#sign[Web3.js]\n * - with https://docs.ethers.io/v5/api/signer/#Signer-signMessage[ethers]\n *\n * _Available since v4.3._\n */\n function tryRecover(bytes32 hash, bytes memory signature) internal pure returns (address, RecoverError) {\n // Check the signature length\n // - case 65: r,s,v signature (standard)\n // - case 64: r,vs signature (cf https://eips.ethereum.org/EIPS/eip-2098) _Available since v4.1._\n if (signature.length == 65) {\n bytes32 r;\n bytes32 s;\n uint8 v;\n // ecrecover takes the signature parameters, and the only way to get them\n // currently is to use assembly.\n /// @solidity memory-safe-assembly\n assembly {\n r := mload(add(signature, 0x20))\n s := mload(add(signature, 0x40))\n v := byte(0, mload(add(signature, 0x60)))\n }\n return tryRecover(hash, v, r, s);\n } else if (signature.length == 64) {\n bytes32 r;\n bytes32 vs;\n // ecrecover takes the signature parameters, and the only way to get them\n // currently is to use assembly.\n /// @solidity memory-safe-assembly\n assembly {\n r := mload(add(signature, 0x20))\n vs := mload(add(signature, 0x40))\n }\n return tryRecover(hash, r, vs);\n } else {\n return (address(0), RecoverError.InvalidSignatureLength);\n }\n }\n\n /**\n * @dev Returns the address that signed a hashed message (`hash`) with\n * `signature`. This address can then be used for verification purposes.\n *\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\n * this function rejects them by requiring the `s` value to be in the lower\n * half order, and the `v` value to be either 27 or 28.\n *\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\n * verification to be secure: it is possible to craft signatures that\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\n * this is by receiving a hash of the original message (which may otherwise\n * be too long), and then calling {toEthSignedMessageHash} on it.\n */\n function recover(bytes32 hash, bytes memory signature) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, signature);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Overload of {ECDSA-tryRecover} that receives the `r` and `vs` short-signature fields separately.\n *\n * See https://eips.ethereum.org/EIPS/eip-2098[EIP-2098 short signatures]\n *\n * _Available since v4.3._\n */\n function tryRecover(\n bytes32 hash,\n bytes32 r,\n bytes32 vs\n ) internal pure returns (address, RecoverError) {\n bytes32 s = vs & bytes32(0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff);\n uint8 v = uint8((uint256(vs) >> 255) + 27);\n return tryRecover(hash, v, r, s);\n }\n\n /**\n * @dev Overload of {ECDSA-recover} that receives the `r and `vs` short-signature fields separately.\n *\n * _Available since v4.2._\n */\n function recover(\n bytes32 hash,\n bytes32 r,\n bytes32 vs\n ) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, r, vs);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Overload of {ECDSA-tryRecover} that receives the `v`,\n * `r` and `s` signature fields separately.\n *\n * _Available since v4.3._\n */\n function tryRecover(\n bytes32 hash,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) internal pure returns (address, RecoverError) {\n // EIP-2 still allows signature malleability for ecrecover(). Remove this possibility and make the signature\n // unique. Appendix F in the Ethereum Yellow paper (https://ethereum.github.io/yellowpaper/paper.pdf), defines\n // the valid range for s in (301): 0 < s < secp256k1n ÷ 2 + 1, and for v in (302): v ∈ {27, 28}. Most\n // signatures from current libraries generate a unique signature with an s-value in the lower half order.\n //\n // If your library generates malleable signatures, such as s-values in the upper range, calculate a new s-value\n // with 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141 - s1 and flip v from 27 to 28 or\n // vice versa. If your library also generates signatures with 0/1 for v instead 27/28, add 27 to v to accept\n // these malleable signatures as well.\n if (uint256(s) > 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D576E7357A4501DDFE92F46681B20A0) {\n return (address(0), RecoverError.InvalidSignatureS);\n }\n if (v != 27 && v != 28) {\n return (address(0), RecoverError.InvalidSignatureV);\n }\n\n // If the signature is valid (and not malleable), return the signer address\n address signer = ecrecover(hash, v, r, s);\n if (signer == address(0)) {\n return (address(0), RecoverError.InvalidSignature);\n }\n\n return (signer, RecoverError.NoError);\n }\n\n /**\n * @dev Overload of {ECDSA-recover} that receives the `v`,\n * `r` and `s` signature fields separately.\n */\n function recover(\n bytes32 hash,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, v, r, s);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Returns an Ethereum Signed Message, created from a `hash`. This\n * produces hash corresponding to the one signed with the\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\n * JSON-RPC method as part of EIP-191.\n *\n * See {recover}.\n */\n function toEthSignedMessageHash(bytes32 hash) internal pure returns (bytes32) {\n // 32 is the length in bytes of hash,\n // enforced by the type signature above\n return keccak256(abi.encodePacked(\"\\x19Ethereum Signed Message:\\n32\", hash));\n }\n\n /**\n * @dev Returns an Ethereum Signed Message, created from `s`. This\n * produces hash corresponding to the one signed with the\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\n * JSON-RPC method as part of EIP-191.\n *\n * See {recover}.\n */\n function toEthSignedMessageHash(bytes memory s) internal pure returns (bytes32) {\n return keccak256(abi.encodePacked(\"\\x19Ethereum Signed Message:\\n\", Strings.toString(s.length), s));\n }\n\n /**\n * @dev Returns an Ethereum Signed Typed Data, created from a\n * `domainSeparator` and a `structHash`. This produces hash corresponding\n * to the one signed with the\n * https://eips.ethereum.org/EIPS/eip-712[`eth_signTypedData`]\n * JSON-RPC method as part of EIP-712.\n *\n * See {recover}.\n */\n function toTypedDataHash(bytes32 domainSeparator, bytes32 structHash) internal pure returns (bytes32) {\n return keccak256(abi.encodePacked(\"\\x19\\x01\", domainSeparator, structHash));\n }\n}\n" + }, + "@openzeppelin/contracts/utils/introspection/IERC165.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (utils/introspection/IERC165.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Interface of the ERC165 standard, as defined in the\n * https://eips.ethereum.org/EIPS/eip-165[EIP].\n *\n * Implementers can declare support of contract interfaces, which can then be\n * queried by others ({ERC165Checker}).\n *\n * For an implementation, see {ERC165}.\n */\ninterface IERC165 {\n /**\n * @dev Returns true if this contract implements the interface defined by\n * `interfaceId`. See the corresponding\n * https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified[EIP section]\n * to learn more about how these ids are created.\n *\n * This function call must use less than 30 000 gas.\n */\n function supportsInterface(bytes4 interfaceId) external view returns (bool);\n}\n" + }, + "@openzeppelin/contracts/utils/StorageSlot.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (utils/StorageSlot.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Library for reading and writing primitive types to specific storage slots.\n *\n * Storage slots are often used to avoid storage conflict when dealing with upgradeable contracts.\n * This library helps with reading and writing to such slots without the need for inline assembly.\n *\n * The functions in this library return Slot structs that contain a `value` member that can be used to read or write.\n *\n * Example usage to set ERC1967 implementation slot:\n * ```\n * contract ERC1967 {\n * bytes32 internal constant _IMPLEMENTATION_SLOT = 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc;\n *\n * function _getImplementation() internal view returns (address) {\n * return StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value;\n * }\n *\n * function _setImplementation(address newImplementation) internal {\n * require(Address.isContract(newImplementation), \"ERC1967: new implementation is not a contract\");\n * StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value = newImplementation;\n * }\n * }\n * ```\n *\n * _Available since v4.1 for `address`, `bool`, `bytes32`, and `uint256`._\n */\nlibrary StorageSlot {\n struct AddressSlot {\n address value;\n }\n\n struct BooleanSlot {\n bool value;\n }\n\n struct Bytes32Slot {\n bytes32 value;\n }\n\n struct Uint256Slot {\n uint256 value;\n }\n\n /**\n * @dev Returns an `AddressSlot` with member `value` located at `slot`.\n */\n function getAddressSlot(bytes32 slot) internal pure returns (AddressSlot storage r) {\n /// @solidity memory-safe-assembly\n assembly {\n r.slot := slot\n }\n }\n\n /**\n * @dev Returns an `BooleanSlot` with member `value` located at `slot`.\n */\n function getBooleanSlot(bytes32 slot) internal pure returns (BooleanSlot storage r) {\n /// @solidity memory-safe-assembly\n assembly {\n r.slot := slot\n }\n }\n\n /**\n * @dev Returns an `Bytes32Slot` with member `value` located at `slot`.\n */\n function getBytes32Slot(bytes32 slot) internal pure returns (Bytes32Slot storage r) {\n /// @solidity memory-safe-assembly\n assembly {\n r.slot := slot\n }\n }\n\n /**\n * @dev Returns an `Uint256Slot` with member `value` located at `slot`.\n */\n function getUint256Slot(bytes32 slot) internal pure returns (Uint256Slot storage r) {\n /// @solidity memory-safe-assembly\n assembly {\n r.slot := slot\n }\n }\n}\n" + }, + "@openzeppelin/contracts/utils/Strings.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (utils/Strings.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev String operations.\n */\nlibrary Strings {\n bytes16 private constant _HEX_SYMBOLS = \"0123456789abcdef\";\n uint8 private constant _ADDRESS_LENGTH = 20;\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` decimal representation.\n */\n function toString(uint256 value) internal pure returns (string memory) {\n // Inspired by OraclizeAPI's implementation - MIT licence\n // https://github.com/oraclize/ethereum-api/blob/b42146b063c7d6ee1358846c198246239e9360e8/oraclizeAPI_0.4.25.sol\n\n if (value == 0) {\n return \"0\";\n }\n uint256 temp = value;\n uint256 digits;\n while (temp != 0) {\n digits++;\n temp /= 10;\n }\n bytes memory buffer = new bytes(digits);\n while (value != 0) {\n digits -= 1;\n buffer[digits] = bytes1(uint8(48 + uint256(value % 10)));\n value /= 10;\n }\n return string(buffer);\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation.\n */\n function toHexString(uint256 value) internal pure returns (string memory) {\n if (value == 0) {\n return \"0x00\";\n }\n uint256 temp = value;\n uint256 length = 0;\n while (temp != 0) {\n length++;\n temp >>= 8;\n }\n return toHexString(value, length);\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length.\n */\n function toHexString(uint256 value, uint256 length) internal pure returns (string memory) {\n bytes memory buffer = new bytes(2 * length + 2);\n buffer[0] = \"0\";\n buffer[1] = \"x\";\n for (uint256 i = 2 * length + 1; i > 1; --i) {\n buffer[i] = _HEX_SYMBOLS[value & 0xf];\n value >>= 4;\n }\n require(value == 0, \"Strings: hex length insufficient\");\n return string(buffer);\n }\n\n /**\n * @dev Converts an `address` with fixed length of 20 bytes to its not checksummed ASCII `string` hexadecimal representation.\n */\n function toHexString(address addr) internal pure returns (string memory) {\n return toHexString(uint256(uint160(addr)), _ADDRESS_LENGTH);\n }\n}\n" + }, + "contracts/agToken/AgEUR.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\nimport \"../interfaces/IAgToken.sol\";\nimport \"../interfaces/coreModule/IStableMaster.sol\";\nimport \"../interfaces/ITreasury.sol\";\nimport \"@openzeppelin/contracts-upgradeable/token/ERC20/extensions/draft-ERC20PermitUpgradeable.sol\";\n\n/// @title AgEUR\n/// @author Angle Labs, Inc.\n/// @notice Base contract for agEUR, Angle's Euro stablecoin\n/// @dev This contract is an upgraded version of the agEUR contract that was first deployed on Ethereum mainnet\ncontract AgEUR is IAgToken, ERC20PermitUpgradeable {\n // ================================= REFERENCES ================================\n\n /// @notice Reference to the `StableMaster` contract associated to agEUR\n address public stableMaster;\n\n /// @custom:oz-upgrades-unsafe-allow constructor\n constructor() initializer {}\n\n // ============================== ADDED PARAMETERS =============================\n\n /// @inheritdoc IAgToken\n mapping(address => bool) public isMinter;\n /// @notice Reference to the treasury contract which can grant minting rights\n address public treasury;\n /// @notice Boolean used to check whether the contract had been reinitialized after an upgrade\n bool public treasuryInitialized;\n\n // =================================== EVENTS ==================================\n\n event TreasuryUpdated(address indexed _treasury);\n event MinterToggled(address indexed minter);\n\n // =================================== ERRORS ==================================\n\n error BurnAmountExceedsAllowance();\n error InvalidSender();\n error InvalidTreasury();\n error NotGovernor();\n error NotMinter();\n error NotTreasury();\n error TreasuryAlreadyInitialized();\n\n // ================================= MODIFIERS =================================\n\n /// @notice Checks to see if it is the `Treasury` calling this contract\n modifier onlyTreasury() {\n if (msg.sender != treasury) revert NotTreasury();\n _;\n }\n\n /// @notice Checks whether the sender has the minting right\n modifier onlyMinter() {\n if (!isMinter[msg.sender]) revert NotMinter();\n _;\n }\n\n // ============================= EXTERNAL FUNCTION =============================\n\n /// @notice Allows anyone to burn stablecoins\n /// @param amount Amount of stablecoins to burn\n /// @dev This function can typically be called if there is a settlement mechanism to burn stablecoins\n function burnStablecoin(uint256 amount) external {\n _burn(msg.sender, amount);\n }\n\n // ========================= MINTER ROLE ONLY FUNCTIONS ========================\n\n /// @inheritdoc IAgToken\n function burnSelf(uint256 amount, address burner) external onlyMinter {\n _burn(burner, amount);\n }\n\n /// @inheritdoc IAgToken\n function burnFrom(uint256 amount, address burner, address sender) external onlyMinter {\n if (burner != sender) {\n uint256 currentAllowance = allowance(burner, sender);\n if (currentAllowance < amount) revert BurnAmountExceedsAllowance();\n _approve(burner, sender, currentAllowance - amount);\n }\n _burn(burner, amount);\n }\n\n /// @inheritdoc IAgToken\n function mint(address account, uint256 amount) external onlyMinter {\n _mint(account, amount);\n }\n\n // ========================== TREASURY ONLY FUNCTIONS ==========================\n\n /// @inheritdoc IAgToken\n function addMinter(address minter) external onlyTreasury {\n isMinter[minter] = true;\n emit MinterToggled(minter);\n }\n\n /// @inheritdoc IAgToken\n function removeMinter(address minter) external {\n if (msg.sender != minter && msg.sender != address(treasury)) revert InvalidSender();\n isMinter[minter] = false;\n emit MinterToggled(minter);\n }\n\n /// @inheritdoc IAgToken\n function setTreasury(address _treasury) external onlyTreasury {\n treasury = _treasury;\n emit TreasuryUpdated(_treasury);\n }\n}\n" + }, + "contracts/agToken/AgToken.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\n/*\n * █ \n ***** ▓▓▓ \n * ▓▓▓▓▓▓▓ \n * ///. ▓▓▓▓▓▓▓▓▓▓▓▓▓ \n ***** //////// ▓▓▓▓▓▓▓ \n * ///////////// ▓▓▓ \n ▓▓ ////////////////// █ ▓▓ \n ▓▓ ▓▓ /////////////////////// ▓▓ ▓▓ \n ▓▓ ▓▓ //////////////////////////// ▓▓ ▓▓ \n ▓▓ ▓▓ /////////▓▓▓///////▓▓▓///////// ▓▓ ▓▓ \n ▓▓ ,////////////////////////////////////// ▓▓ ▓▓ \n ▓▓ ////////////////////////////////////////// ▓▓ \n ▓▓ //////////////////////▓▓▓▓///////////////////// \n ,//////////////////////////////////////////////////// \n .////////////////////////////////////////////////////////// \n .//////////////////////////██.,//////////////////////////█ \n .//////////////////////████..,./////////////////////██ \n ...////////////////███████.....,.////////////////███ \n ,.,////////////████████ ........,///////////████ \n .,.,//////█████████ ,.......///////████ \n ,..//████████ ........./████ \n ..,██████ .....,███ \n .██ ,.,█ \n \n \n \n ▓▓ ▓▓▓▓▓▓▓▓▓▓ ▓▓▓▓▓▓▓▓▓▓ ▓▓ ▓▓▓▓▓▓▓▓▓▓ \n ▓▓▓▓▓▓ ▓▓▓ ▓▓▓ ▓▓▓ ▓▓ ▓▓ ▓▓▓▓ \n ▓▓▓ ▓▓▓ ▓▓▓ ▓▓▓ ▓▓▓ ▓▓▓ ▓▓ ▓▓▓▓▓ \n ▓▓▓ ▓▓ ▓▓▓ ▓▓▓ ▓▓▓▓▓▓▓▓▓▓ ▓▓▓▓▓▓▓▓▓▓ ▓▓▓▓▓▓▓▓▓▓ \n*/\n\nimport \"../interfaces/IAgToken.sol\";\nimport \"../interfaces/ITreasury.sol\";\nimport \"@openzeppelin/contracts-upgradeable/token/ERC20/extensions/draft-ERC20PermitUpgradeable.sol\";\n\n/// @title AgToken\n/// @author Angle Labs, Inc.\n/// @notice Base contract for Angle agTokens on Ethereum and on other chains\n/// @dev By default, agTokens are ERC-20 tokens with 18 decimals\ncontract AgToken is IAgToken, ERC20PermitUpgradeable {\n // =========================== PARAMETERS / VARIABLES ==========================\n\n /// @inheritdoc IAgToken\n mapping(address => bool) public isMinter;\n /// @notice Reference to the treasury contract which can grant minting rights\n address public treasury;\n\n // =================================== EVENTS ==================================\n\n event TreasuryUpdated(address indexed _treasury);\n event MinterToggled(address indexed minter);\n\n // =================================== ERRORS ==================================\n\n error BurnAmountExceedsAllowance();\n error InvalidSender();\n error InvalidTreasury();\n error NotMinter();\n error NotTreasury();\n\n // ================================ CONSTRUCTOR ================================\n\n /// @custom:oz-upgrades-unsafe-allow constructor\n constructor() initializer {}\n\n /// @notice Initializes the `AgToken` contract\n function initialize(string memory name_, string memory symbol_, address _treasury) external {\n _initialize(name_, symbol_, _treasury);\n }\n\n /// @notice Initializes the contract\n function _initialize(string memory name_, string memory symbol_, address _treasury) internal virtual initializer {\n if (address(ITreasury(_treasury).stablecoin()) != address(this)) revert InvalidTreasury();\n __ERC20Permit_init(name_);\n __ERC20_init(name_, symbol_);\n treasury = _treasury;\n emit TreasuryUpdated(_treasury);\n }\n\n // ================================= MODIFIERS =================================\n\n /// @notice Checks to see if it is the `Treasury` calling this contract\n modifier onlyTreasury() {\n if (msg.sender != treasury) revert NotTreasury();\n _;\n }\n\n /// @notice Checks whether the sender has the minting right\n modifier onlyMinter() {\n if (!isMinter[msg.sender]) revert NotMinter();\n _;\n }\n\n // ============================= EXTERNAL FUNCTION =============================\n\n /// @notice Allows anyone to burn stablecoins\n /// @param amount Amount of stablecoins to burn\n /// @dev This function can typically be called if there is a settlement mechanism to burn stablecoins\n function burnStablecoin(uint256 amount) external {\n _burn(msg.sender, amount);\n }\n\n // ========================= MINTER ROLE ONLY FUNCTIONS ========================\n\n /// @inheritdoc IAgToken\n function burnSelf(uint256 amount, address burner) external onlyMinter {\n _burn(burner, amount);\n }\n\n /// @inheritdoc IAgToken\n function burnFrom(uint256 amount, address burner, address sender) external onlyMinter {\n if (burner != sender) {\n uint256 currentAllowance = allowance(burner, sender);\n if (currentAllowance < amount) revert BurnAmountExceedsAllowance();\n _approve(burner, sender, currentAllowance - amount);\n }\n _burn(burner, amount);\n }\n\n /// @inheritdoc IAgToken\n function mint(address account, uint256 amount) external onlyMinter {\n _mint(account, amount);\n }\n\n // ========================== GOVERNANCE ONLY FUNCTIONS ==========================\n\n /// @inheritdoc IAgToken\n function addMinter(address minter) external onlyTreasury {\n isMinter[minter] = true;\n emit MinterToggled(minter);\n }\n\n /// @inheritdoc IAgToken\n function removeMinter(address minter) external {\n if (msg.sender != address(treasury) && msg.sender != minter) revert InvalidSender();\n isMinter[minter] = false;\n emit MinterToggled(minter);\n }\n\n /// @inheritdoc IAgToken\n function setTreasury(address _treasury) external virtual onlyTreasury {\n treasury = _treasury;\n emit TreasuryUpdated(_treasury);\n }\n}\n" + }, + "contracts/agToken/AgTokenSideChainMultiBridge.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\nimport \"./AgToken.sol\";\nimport \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\nimport \"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\";\n\n/// @title AgTokenSideChainMultiBridge\n/// @author Angle Labs, Inc.\n/// @notice Contract for Angle agTokens on other chains than Ethereum mainnet\n/// @dev This contract supports bridge tokens having a minting right on the stablecoin (also referred to as the canonical\n/// or the native token)\ncontract AgTokenSideChainMultiBridge is AgToken {\n using SafeERC20 for IERC20;\n\n /// @notice Base used for fee computation\n uint256 public constant BASE_PARAMS = 1e9;\n\n // =============================== BRIDGING DATA ===============================\n\n /// @notice Struct with some data about a specific bridge token\n struct BridgeDetails {\n // Limit on the balance of bridge token held by the contract: it is designed\n // to reduce the exposure of the system to hacks\n uint256 limit;\n // Limit on the hourly volume of token minted through this bridge\n // Technically the limit over a rolling hour is hourlyLimit x2 as hourly limit\n // is enforced only between x:00 and x+1:00\n uint256 hourlyLimit;\n // Fee taken for swapping in and out the token\n uint64 fee;\n // Whether the associated token is allowed or not\n bool allowed;\n // Whether swapping in and out from the associated token is paused or not\n bool paused;\n }\n\n /// @notice Maps a bridge token to data\n mapping(address => BridgeDetails) public bridges;\n /// @notice List of all bridge tokens\n address[] public bridgeTokensList;\n /// @notice Maps a bridge token to the associated hourly volume\n mapping(address => mapping(uint256 => uint256)) public usage;\n /// @notice Maps an address to whether it is exempt of fees for when it comes to swapping in and out\n mapping(address => uint256) public isFeeExempt;\n /// @notice Limit to the amount of tokens that can be sent from that chain to another chain\n uint256 public chainTotalHourlyLimit;\n /// @notice Usage per hour on that chain. Maps an hourly timestamp to the total volume swapped out on the chain\n mapping(uint256 => uint256) public chainTotalUsage;\n\n // =================================== EVENTS ==================================\n\n event BridgeTokenAdded(address indexed bridgeToken, uint256 limit, uint256 hourlyLimit, uint64 fee, bool paused);\n event BridgeTokenToggled(address indexed bridgeToken, bool toggleStatus);\n event BridgeTokenRemoved(address indexed bridgeToken);\n event BridgeTokenFeeUpdated(address indexed bridgeToken, uint64 fee);\n event BridgeTokenLimitUpdated(address indexed bridgeToken, uint256 limit);\n event BridgeTokenHourlyLimitUpdated(address indexed bridgeToken, uint256 hourlyLimit);\n event HourlyLimitUpdated(uint256 hourlyLimit);\n event Recovered(address indexed token, address indexed to, uint256 amount);\n event FeeToggled(address indexed theAddress, uint256 toggleStatus);\n\n // =================================== ERRORS ==================================\n\n error AssetStillControlledInReserves();\n error HourlyLimitExceeded();\n error InvalidToken();\n error NotGovernor();\n error NotGovernorOrGuardian();\n error TooBigAmount();\n error TooHighParameterValue();\n error ZeroAddress();\n\n // ================================= MODIFIERS =================================\n\n /// @notice Checks whether the `msg.sender` has the governor role or not\n modifier onlyGovernor() {\n if (!ITreasury(treasury).isGovernor(msg.sender)) revert NotGovernor();\n _;\n }\n\n /// @notice Checks whether the `msg.sender` has the governor role or the guardian role\n modifier onlyGovernorOrGuardian() {\n if (!ITreasury(treasury).isGovernorOrGuardian(msg.sender)) revert NotGovernorOrGuardian();\n _;\n }\n\n // ===================== EXTERNAL PERMISSIONLESS FUNCTIONS =====================\n\n /// @notice Returns the list of all supported bridge tokens\n /// @dev Helpful for UIs\n function allBridgeTokens() external view returns (address[] memory) {\n return bridgeTokensList;\n }\n\n /// @notice Returns the current volume for a bridge, for the current hour\n /// @param bridgeToken Bridge used to mint\n /// @dev Helpful for UIs\n function currentUsage(address bridgeToken) external view returns (uint256) {\n return usage[bridgeToken][block.timestamp / 3600];\n }\n\n /// @notice Returns the current total volume on the chain for the current hour\n /// @dev Helpful for UIs\n function currentTotalUsage() external view returns (uint256) {\n return chainTotalUsage[block.timestamp / 3600];\n }\n\n /// @notice Mints the canonical token from a supported bridge token\n /// @param bridgeToken Bridge token to use to mint\n /// @param amount Amount of bridge tokens to send\n /// @param to Address to which the stablecoin should be sent\n /// @return Amount of the canonical stablecoin actually minted\n /// @dev Some fees may be taken by the protocol depending on the token used and on the address calling\n function swapIn(address bridgeToken, uint256 amount, address to) external returns (uint256) {\n BridgeDetails memory bridgeDetails = bridges[bridgeToken];\n if (!bridgeDetails.allowed || bridgeDetails.paused) revert InvalidToken();\n uint256 balance = IERC20(bridgeToken).balanceOf(address(this));\n if (balance + amount > bridgeDetails.limit) {\n // In case someone maliciously sends tokens to this contract\n // Or the limit changes\n if (bridgeDetails.limit > balance) amount = bridgeDetails.limit - balance;\n else {\n amount = 0;\n }\n }\n\n // Checking requirement on the hourly volume\n uint256 hour = block.timestamp / 3600;\n uint256 hourlyUsage = usage[bridgeToken][hour];\n if (hourlyUsage + amount > bridgeDetails.hourlyLimit) {\n // Edge case when the hourly limit changes\n amount = bridgeDetails.hourlyLimit > hourlyUsage ? bridgeDetails.hourlyLimit - hourlyUsage : 0;\n }\n usage[bridgeToken][hour] = hourlyUsage + amount;\n\n IERC20(bridgeToken).safeTransferFrom(msg.sender, address(this), amount);\n uint256 canonicalOut = amount;\n // Computing fees\n if (isFeeExempt[msg.sender] == 0) {\n canonicalOut -= (canonicalOut * bridgeDetails.fee) / BASE_PARAMS;\n }\n _mint(to, canonicalOut);\n return canonicalOut;\n }\n\n /// @notice Burns the canonical token in exchange for a bridge token\n /// @param bridgeToken Bridge token required\n /// @param amount Amount of canonical tokens to burn\n /// @param to Address to which the bridge token should be sent\n /// @return Amount of bridge tokens actually sent back\n /// @dev Some fees may be taken by the protocol depending on the token used and on the address calling\n function swapOut(address bridgeToken, uint256 amount, address to) external returns (uint256) {\n BridgeDetails memory bridgeDetails = bridges[bridgeToken];\n if (!bridgeDetails.allowed || bridgeDetails.paused) revert InvalidToken();\n\n uint256 hour = block.timestamp / 3600;\n uint256 hourlyUsage = chainTotalUsage[hour] + amount;\n // If the amount being swapped out exceeds the limit, we revert\n // We don't want to change the amount being swapped out.\n // The user can decide to send another tx with the correct amount to reach the limit\n if (hourlyUsage > chainTotalHourlyLimit) revert HourlyLimitExceeded();\n chainTotalUsage[hour] = hourlyUsage;\n\n _burn(msg.sender, amount);\n uint256 bridgeOut = amount;\n if (isFeeExempt[msg.sender] == 0) {\n bridgeOut -= (bridgeOut * bridgeDetails.fee) / BASE_PARAMS;\n }\n IERC20(bridgeToken).safeTransfer(to, bridgeOut);\n return bridgeOut;\n }\n\n // ============================ GOVERNANCE FUNCTIONS ===========================\n\n /// @notice Adds support for a bridge token\n /// @param bridgeToken Bridge token to add: it should be a version of the stablecoin from another bridge\n /// @param limit Limit on the balance of bridge token this contract could hold\n /// @param hourlyLimit Limit on the hourly volume for this bridge\n /// @param paused Whether swapping for this token should be paused or not\n /// @param fee Fee taken upon swapping for or against this token\n function addBridgeToken(\n address bridgeToken,\n uint256 limit,\n uint256 hourlyLimit,\n uint64 fee,\n bool paused\n ) external onlyGovernor {\n if (bridges[bridgeToken].allowed || bridgeToken == address(0)) revert InvalidToken();\n if (fee > BASE_PARAMS) revert TooHighParameterValue();\n BridgeDetails memory _bridge;\n _bridge.limit = limit;\n _bridge.hourlyLimit = hourlyLimit;\n _bridge.paused = paused;\n _bridge.fee = fee;\n _bridge.allowed = true;\n bridges[bridgeToken] = _bridge;\n bridgeTokensList.push(bridgeToken);\n emit BridgeTokenAdded(bridgeToken, limit, hourlyLimit, fee, paused);\n }\n\n /// @notice Removes support for a token\n /// @param bridgeToken Address of the bridge token to remove support for\n function removeBridgeToken(address bridgeToken) external onlyGovernor {\n if (IERC20(bridgeToken).balanceOf(address(this)) != 0) revert AssetStillControlledInReserves();\n delete bridges[bridgeToken];\n // Deletion from `bridgeTokensList` loop\n uint256 bridgeTokensListLength = bridgeTokensList.length;\n for (uint256 i; i < bridgeTokensListLength - 1; ++i) {\n if (bridgeTokensList[i] == bridgeToken) {\n // Replace the `bridgeToken` to remove with the last of the list\n bridgeTokensList[i] = bridgeTokensList[bridgeTokensListLength - 1];\n break;\n }\n }\n // Remove last element in array\n bridgeTokensList.pop();\n emit BridgeTokenRemoved(bridgeToken);\n }\n\n /// @notice Recovers any ERC20 token\n /// @dev Can be used to withdraw bridge tokens for them to be de-bridged on mainnet\n function recoverERC20(address tokenAddress, address to, uint256 amountToRecover) external onlyGovernor {\n IERC20(tokenAddress).safeTransfer(to, amountToRecover);\n emit Recovered(tokenAddress, to, amountToRecover);\n }\n\n /// @notice Updates the `limit` amount for `bridgeToken`\n function setLimit(address bridgeToken, uint256 limit) external onlyGovernorOrGuardian {\n if (!bridges[bridgeToken].allowed) revert InvalidToken();\n bridges[bridgeToken].limit = limit;\n emit BridgeTokenLimitUpdated(bridgeToken, limit);\n }\n\n /// @notice Updates the `hourlyLimit` amount for `bridgeToken`\n function setHourlyLimit(address bridgeToken, uint256 hourlyLimit) external onlyGovernorOrGuardian {\n if (!bridges[bridgeToken].allowed) revert InvalidToken();\n bridges[bridgeToken].hourlyLimit = hourlyLimit;\n emit BridgeTokenHourlyLimitUpdated(bridgeToken, hourlyLimit);\n }\n\n /// @notice Updates the `chainTotalHourlyLimit` amount\n function setChainTotalHourlyLimit(uint256 hourlyLimit) external onlyGovernorOrGuardian {\n chainTotalHourlyLimit = hourlyLimit;\n emit HourlyLimitUpdated(hourlyLimit);\n }\n\n /// @notice Updates the `fee` value for `bridgeToken`\n function setSwapFee(address bridgeToken, uint64 fee) external onlyGovernorOrGuardian {\n if (!bridges[bridgeToken].allowed) revert InvalidToken();\n if (fee > BASE_PARAMS) revert TooHighParameterValue();\n bridges[bridgeToken].fee = fee;\n emit BridgeTokenFeeUpdated(bridgeToken, fee);\n }\n\n /// @notice Pauses or unpauses swapping in and out for a token\n function toggleBridge(address bridgeToken) external onlyGovernorOrGuardian {\n if (!bridges[bridgeToken].allowed) revert InvalidToken();\n bool pausedStatus = bridges[bridgeToken].paused;\n bridges[bridgeToken].paused = !pausedStatus;\n emit BridgeTokenToggled(bridgeToken, !pausedStatus);\n }\n\n /// @notice Toggles fees for the address `theAddress`\n function toggleFeesForAddress(address theAddress) external onlyGovernorOrGuardian {\n uint256 feeExemptStatus = 1 - isFeeExempt[theAddress];\n isFeeExempt[theAddress] = feeExemptStatus;\n emit FeeToggled(theAddress, feeExemptStatus);\n }\n}\n" + }, + "contracts/agToken/layerZero/LayerZeroBridge.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.12;\n\nimport \"./utils/OFTCore.sol\";\nimport \"@openzeppelin/contracts-upgradeable/security/PausableUpgradeable.sol\";\nimport \"@openzeppelin/contracts/token/ERC20/extensions/draft-IERC20Permit.sol\";\n\n/// @title LayerZeroBridge\n/// @author Angle Labs, Inc., forked from https://github.com/LayerZero-Labs/solidity-examples/blob/main/contracts/token/oft/OFT.sol\n/// @notice Contract to be deployed on Ethereum for bridging an AgToken using a bridge intermediate token and LayerZero\ncontract LayerZeroBridge is OFTCore, PausableUpgradeable {\n /// @notice Name of the contract for indexing purposes\n string public name;\n\n /// @notice Address of the bridgeable token\n /// @dev Immutable\n IERC20 public canonicalToken;\n\n /// @notice Maps an address to the amount of token bridged but not received\n mapping(address => uint256) public balanceOf;\n\n // ================================ CONSTRUCTOR ================================\n /// @notice Initializes the contract\n /// @param _name Name of the token corresponding to this contract\n /// @param _lzEndpoint Layer zero endpoint to pass messages\n /// @param _treasury Address of the treasury contract used for access control\n function initialize(string memory _name, address _lzEndpoint, address _treasury) external initializer {\n __LzAppUpgradeable_init(_lzEndpoint, _treasury);\n name = _name;\n canonicalToken = IERC20(address(ITreasury(_treasury).stablecoin()));\n }\n\n /// @custom:oz-upgrades-unsafe-allow constructor\n constructor() initializer {}\n\n // ===================== EXTERNAL PERMISSIONLESS FUNCTIONS =====================\n\n /// @inheritdoc OFTCore\n function sendWithPermit(\n uint16 _dstChainId,\n bytes memory _toAddress,\n uint256 _amount,\n address payable _refundAddress,\n address _zroPaymentAddress,\n bytes memory _adapterParams,\n uint256 deadline,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) public payable override {\n IERC20Permit(address(canonicalToken)).permit(msg.sender, address(this), _amount, deadline, v, r, s);\n send(_dstChainId, _toAddress, _amount, _refundAddress, _zroPaymentAddress, _adapterParams);\n }\n\n /// @inheritdoc OFTCore\n function withdraw(uint256 amount, address recipient) external override returns (uint256) {\n return _withdraw(amount, msg.sender, recipient);\n }\n\n /// @notice Withdraws amount of `token` from the contract and sends it to the recipient\n /// @param amount Amount to withdraw\n /// @param recipient Address to withdraw for\n /// @return The amount of canonical token sent\n function withdrawFor(uint256 amount, address recipient) external returns (uint256) {\n return _withdraw(amount, recipient, recipient);\n }\n\n // ============================= INTERNAL FUNCTIONS ============================\n\n /// @notice Withdraws `amount` from the balance of the `from` address and sends these tokens to the `to` address\n /// @dev It's important to make sure that `from` is either the `msg.sender` or that `from` and `to` are the same\n /// addresses\n function _withdraw(uint256 amount, address from, address to) internal whenNotPaused returns (uint256) {\n balanceOf[from] -= amount; // Will overflow if the amount is too big\n canonicalToken.transfer(to, amount);\n return amount;\n }\n\n /// @inheritdoc OFTCore\n function _debitFrom(uint16, bytes memory, uint256 _amount) internal override whenNotPaused returns (uint256) {\n // No need to use safeTransferFrom as we know this implementation reverts on failure\n canonicalToken.transferFrom(msg.sender, address(this), _amount);\n return _amount;\n }\n\n /// @inheritdoc OFTCore\n function _debitCreditFrom(uint16, bytes memory, uint256 _amount) internal override whenNotPaused returns (uint256) {\n balanceOf[msg.sender] -= _amount;\n return _amount;\n }\n\n /// @inheritdoc OFTCore\n function _creditTo(uint16, address _toAddress, uint256 _amount) internal override whenNotPaused returns (uint256) {\n // Should never revert as all the LayerZero bridge tokens come from\n // this contract\n uint256 balance = canonicalToken.balanceOf(address(this));\n if (balance < _amount) {\n balanceOf[_toAddress] = _amount - balance;\n if (balance != 0) canonicalToken.transfer(_toAddress, balance);\n } else {\n canonicalToken.transfer(_toAddress, _amount);\n }\n return _amount;\n }\n\n // =============================== VIEW FUNCTIONS ==============================\n\n /// @inheritdoc ERC165Upgradeable\n function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {\n return interfaceId == type(IOFTCore).interfaceId || super.supportsInterface(interfaceId);\n }\n\n // ============================ GOVERNANCE FUNCTIONS ===========================\n\n /// @notice Pauses bridging through the contract\n /// @param pause Future pause status\n function pauseSendTokens(bool pause) external onlyGovernorOrGuardian {\n pause ? _pause() : _unpause();\n }\n\n /// @notice Decreases the balance of an address\n /// @param amount Amount to withdraw from balance\n /// @param recipient Address to withdraw from\n function sweep(uint256 amount, address recipient) external onlyGovernorOrGuardian {\n balanceOf[recipient] -= amount; // Will overflow if the amount is too big\n }\n\n uint256[47] private __gap;\n}\n" + }, + "contracts/agToken/layerZero/LayerZeroBridgeToken.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.12;\n\nimport \"./utils/OFTCore.sol\";\nimport \"../../interfaces/IAgTokenSideChainMultiBridge.sol\";\nimport \"@openzeppelin/contracts-upgradeable/security/PausableUpgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/token/ERC20/ERC20Upgradeable.sol\";\n\n/// @title LayerZeroBridgeToken\n/// @author Angle Labs, Inc., forked from https://github.com/LayerZero-Labs/solidity-examples/blob/main/contracts/token/oft/OFT.sol\n/// @notice Contract to be deployed on a L2/sidechain for bridging an AgToken using a bridge intermediate token and LayerZero\ncontract LayerZeroBridgeToken is OFTCore, ERC20Upgradeable, PausableUpgradeable {\n /// @notice Address of the bridgeable token\n /// @dev Immutable\n IAgTokenSideChainMultiBridge public canonicalToken;\n\n // =================================== ERROR ===================================\n\n error InvalidAllowance();\n\n // ================================ CONSTRUCTOR ================================\n\n /// @notice Initializes the contract\n /// @param _name Name of the token corresponding to this contract\n /// @param _symbol Symbol of the token corresponding to this contract\n /// @param _lzEndpoint Layer zero endpoint to pass messages\n /// @param _treasury Address of the treasury contract used for access control\n /// @param initialSupply Initial supply to mint to the canonical token address\n /// @dev The initial supply corresponds to the initial amount that could be bridged using this OFT\n function initialize(\n string memory _name,\n string memory _symbol,\n address _lzEndpoint,\n address _treasury,\n uint256 initialSupply\n ) external initializer {\n __ERC20_init_unchained(_name, _symbol);\n __LzAppUpgradeable_init(_lzEndpoint, _treasury);\n\n canonicalToken = IAgTokenSideChainMultiBridge(address(ITreasury(_treasury).stablecoin()));\n _approve(address(this), address(canonicalToken), type(uint256).max);\n _mint(address(canonicalToken), initialSupply);\n }\n\n /// @custom:oz-upgrades-unsafe-allow constructor\n constructor() initializer {}\n\n // ===================== EXTERNAL PERMISSIONLESS FUNCTIONS =====================\n\n /// @inheritdoc OFTCore\n function sendWithPermit(\n uint16 _dstChainId,\n bytes memory _toAddress,\n uint256 _amount,\n address payable _refundAddress,\n address _zroPaymentAddress,\n bytes memory _adapterParams,\n uint256 deadline,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) public payable override {\n canonicalToken.permit(msg.sender, address(this), _amount, deadline, v, r, s);\n send(_dstChainId, _toAddress, _amount, _refundAddress, _zroPaymentAddress, _adapterParams);\n }\n\n /// @inheritdoc OFTCore\n function withdraw(uint256 amount, address recipient) external override returns (uint256 amountMinted) {\n // Does not check allowances as transfers from `msg.sender`\n _transfer(msg.sender, address(this), amount);\n amountMinted = canonicalToken.swapIn(address(this), amount, recipient);\n uint256 leftover = balanceOf(address(this));\n if (leftover != 0) {\n _transfer(address(this), msg.sender, leftover);\n }\n }\n\n // ============================= INTERNAL FUNCTIONS ============================\n\n /// @inheritdoc OFTCore\n function _debitFrom(\n uint16,\n bytes memory,\n uint256 _amount\n ) internal override whenNotPaused returns (uint256 amountSwapped) {\n // No need to use safeTransferFrom as we know this implementation reverts on failure\n canonicalToken.transferFrom(msg.sender, address(this), _amount);\n\n // Swap canonical for this bridge token. There may be some fees\n amountSwapped = canonicalToken.swapOut(address(this), _amount, address(this));\n _burn(address(this), amountSwapped);\n }\n\n /// @inheritdoc OFTCore\n function _debitCreditFrom(uint16, bytes memory, uint256 _amount) internal override whenNotPaused returns (uint256) {\n _burn(msg.sender, _amount);\n return _amount;\n }\n\n /// @inheritdoc OFTCore\n function _creditTo(\n uint16,\n address _toAddress,\n uint256 _amount\n ) internal override whenNotPaused returns (uint256 amountMinted) {\n _mint(address(this), _amount);\n amountMinted = canonicalToken.swapIn(address(this), _amount, _toAddress);\n uint256 leftover = balanceOf(address(this));\n if (leftover != 0) {\n _transfer(address(this), _toAddress, leftover);\n }\n }\n\n // =============================== VIEW FUNCTIONS ==============================\n\n /// @inheritdoc ERC165Upgradeable\n function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {\n return\n interfaceId == type(IOFT).interfaceId ||\n interfaceId == type(IERC20).interfaceId ||\n super.supportsInterface(interfaceId);\n }\n\n // ============================ GOVERNANCE FUNCTIONS ===========================\n\n /// @notice Mints the intermediate contract to the `canonicalToken`\n /// @dev Used to increase the bridging capacity\n function mint(uint256 amount) external onlyGovernorOrGuardian {\n _mint(address(canonicalToken), amount);\n }\n\n /// @notice Burns the intermediate contract from the `canonicalToken`\n /// @dev Used to decrease the bridging capacity\n function burn(uint256 amount) external onlyGovernorOrGuardian {\n _burn(address(canonicalToken), amount);\n }\n\n /// @notice Increases allowance of the `canonicalToken`\n function setupAllowance() public onlyGovernorOrGuardian {\n _approve(address(this), address(canonicalToken), type(uint256).max);\n }\n\n /// @notice Pauses bridging through the contract\n /// @param pause Future pause status\n function pauseSendTokens(bool pause) external onlyGovernorOrGuardian {\n pause ? _pause() : _unpause();\n }\n\n uint256[49] private __gap;\n}\n" + }, + "contracts/agToken/layerZero/utils/IOFTCore.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.12;\n\nimport \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\nimport \"@openzeppelin/contracts/utils/introspection/IERC165.sol\";\n\n/**\n * @dev Interface of the IOFT core standard\n * @dev Forked from https://github.com/LayerZero-Labs/solidity-examples/blob/main/contracts/token/oft/IOFTCore.sol\n */\ninterface IOFTCore is IERC165 {\n /// @notice Estimates send token `_tokenId` to (`_dstChainId`, `_toAddress`)\n /// @param _dstChainId L0 defined chain id to send tokens too\n /// @param _toAddress dynamic bytes array which contains the address to whom you are sending tokens to on the dstChain\n /// @param _amount amount of the tokens to transfer\n /// @param _useZro indicates to use zro to pay L0 fees\n /// @param _adapterParams flexible bytes array to indicate messaging adapter services in L0\n function estimateSendFee(\n uint16 _dstChainId,\n bytes calldata _toAddress,\n uint256 _amount,\n bool _useZro,\n bytes calldata _adapterParams\n ) external view returns (uint256 nativeFee, uint256 zroFee);\n\n /// @notice Sends `_amount` amount of token to (`_dstChainId`, `_toAddress`)\n /// @param _dstChainId the destination chain identifier\n /// @param _toAddress can be any size depending on the `dstChainId`.\n /// @param _amount the quantity of tokens in wei\n /// @param _refundAddress the address LayerZero refunds if too much message fee is sent\n /// @param _zroPaymentAddress set to address(0x0) if not paying in ZRO (LayerZero Token)\n /// @param _adapterParams is a flexible bytes array to indicate messaging adapter services\n function send(\n uint16 _dstChainId,\n bytes calldata _toAddress,\n uint256 _amount,\n address payable _refundAddress,\n address _zroPaymentAddress,\n bytes calldata _adapterParams\n ) external payable;\n\n /// @notice Sends `_amount` amount of credit to (`_dstChainId`, `_toAddress`)\n /// @param _dstChainId the destination chain identifier\n /// @param _toAddress can be any size depending on the `dstChainId`.\n /// @param _amount the quantity of credit to send in wei\n /// @param _refundAddress the address LayerZero refunds if too much message fee is sent\n /// @param _zroPaymentAddress set to address(0x0) if not paying in ZRO (LayerZero Token)\n /// @param _adapterParams is a flexible bytes array to indicate messaging adapter services\n function sendCredit(\n uint16 _dstChainId,\n bytes calldata _toAddress,\n uint256 _amount,\n address payable _refundAddress,\n address _zroPaymentAddress,\n bytes calldata _adapterParams\n ) external payable;\n\n /// @notice Sends `_amount` amount of token to (`_dstChainId`, `_toAddress`)\n /// @param _dstChainId The destination chain identifier\n /// @param _toAddress Can be any size depending on the `dstChainId`.\n /// @param _amount Quantity of tokens in wei\n /// @param _refundAddress Address LayerZero refunds if too much message fee is sent\n /// @param _zroPaymentAddress Set to address(0x0) if not paying in ZRO (LayerZero Token)\n /// @param _adapterParams Flexible bytes array to indicate messaging adapter services\n /// @param deadline Deadline parameter for the signature to be valid\n /// @dev The `v`, `r`, and `s` parameters are used as signature data\n function sendWithPermit(\n uint16 _dstChainId,\n bytes memory _toAddress,\n uint256 _amount,\n address payable _refundAddress,\n address _zroPaymentAddress,\n bytes memory _adapterParams,\n uint256 deadline,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) external payable;\n\n /// @notice Withdraws amount of canonical token from the `msg.sender` balance and sends it to the recipient\n /// @param amount Amount to withdraw\n /// @param recipient Address to send the canonical token to\n /// @return The amount of canonical token sent\n function withdraw(uint256 amount, address recipient) external returns (uint256);\n\n /// @dev Emitted when `_amount` tokens are moved from the `_sender` to (`_dstChainId`, `_toAddress`)\n /// `_nonce` is the outbound nonce\n event SendToChain(\n address indexed _sender,\n uint16 indexed _dstChainId,\n bytes indexed _toAddress,\n uint256 _amount,\n uint64 _nonce\n );\n\n /// @dev Emitted when `_amount` tokens are received from `_srcChainId` into the `_toAddress` on the local chain.\n /// `_nonce` is the inbound nonce.\n event ReceiveFromChain(\n uint16 indexed _srcChainId,\n bytes indexed _srcAddress,\n address indexed _toAddress,\n uint256 _amount,\n uint64 _nonce\n );\n}\n\n/// @dev Interface of the OFT standard\ninterface IOFT is IOFTCore, IERC20 {\n\n}\n" + }, + "contracts/agToken/layerZero/utils/NonblockingLzApp.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.12;\n\nimport \"@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol\";\nimport \"../../../interfaces/external/layerZero/ILayerZeroReceiver.sol\";\nimport \"../../../interfaces/external/layerZero/ILayerZeroUserApplicationConfig.sol\";\nimport \"../../../interfaces/external/layerZero/ILayerZeroEndpoint.sol\";\nimport \"../../../interfaces/ITreasury.sol\";\n\n/// @title NonblockingLzApp\n/// @author Angle Labs, Inc., forked from https://github.com/LayerZero-Labs/solidity-examples/\n/// @notice Base contract for bridging using LayerZero\nabstract contract NonblockingLzApp is Initializable, ILayerZeroReceiver, ILayerZeroUserApplicationConfig {\n /// @notice Layer Zero endpoint\n ILayerZeroEndpoint public lzEndpoint;\n\n /// @notice Maps chainIds to failed messages to retry them\n mapping(uint16 => mapping(bytes => mapping(uint64 => bytes32))) public failedMessages;\n\n /// @notice Maps chainIds to their OFT address\n mapping(uint16 => bytes) public trustedRemoteLookup;\n\n /// @notice Reference to the treasury contract to fetch access control\n address public treasury;\n\n /// @notice Maps pairs of (`to` chain, `packetType`) to the minimum amount of gas needed on the destination chain\n mapping(uint16 => mapping(uint16 => uint256)) public minDstGasLookup;\n\n /// @notice For future LayerZero compatibility\n address public precrime;\n\n // ================================== Events ===================================\n\n event SetTrustedRemote(uint16 _srcChainId, bytes _srcAddress);\n event MessageFailed(uint16 _srcChainId, bytes _srcAddress, uint64 _nonce, bytes _payload);\n\n // =============================== Errors ================================\n\n error NotGovernor();\n error NotGovernorOrGuardian();\n error InsufficientGas();\n error InvalidEndpoint();\n error InvalidSource();\n error InvalidCaller();\n error InvalidParams();\n error InvalidPayload();\n error ZeroAddress();\n\n // ============================= Constructor ===================================\n\n //solhint-disable-next-line\n function __LzAppUpgradeable_init(address _endpoint, address _treasury) internal {\n if (_endpoint == address(0) || _treasury == address(0)) revert ZeroAddress();\n lzEndpoint = ILayerZeroEndpoint(_endpoint);\n treasury = _treasury;\n }\n\n // =============================== Modifiers ===================================\n\n /// @notice Checks whether the `msg.sender` has the governor role or the guardian role\n modifier onlyGovernorOrGuardian() {\n if (!ITreasury(treasury).isGovernorOrGuardian(msg.sender)) revert NotGovernorOrGuardian();\n _;\n }\n\n // ==================== External Permissionless Functions ======================\n\n /// @notice Receives a message from the LZ endpoint and process it\n /// @param _srcChainId ChainId of the source chain - LayerZero standard\n /// @param _srcAddress Sender of the source chain\n /// @param _nonce Nounce of the message\n /// @param _payload Data: recipient address and amount\n function lzReceive(\n uint16 _srcChainId,\n bytes memory _srcAddress,\n uint64 _nonce,\n bytes memory _payload\n ) public virtual override {\n // lzReceive must be called by the endpoint for security\n if (msg.sender != address(lzEndpoint)) revert InvalidEndpoint();\n\n bytes memory trustedRemote = trustedRemoteLookup[_srcChainId];\n // if will still block the message pathway from (srcChainId, srcAddress). should not receive message from untrusted remote.\n if (_srcAddress.length != trustedRemote.length || keccak256(_srcAddress) != keccak256(trustedRemote))\n revert InvalidSource();\n\n _blockingLzReceive(_srcChainId, _srcAddress, _nonce, _payload);\n }\n\n /// @notice Retries a message that previously failed and was stored\n /// @param _srcChainId ChainId of the source chain - LayerZero standard\n /// @param _srcAddress Sender of the source chain\n /// @param _nonce Nounce of the message\n /// @param _payload Data: recipient address and amount\n function retryMessage(\n uint16 _srcChainId,\n bytes memory _srcAddress,\n uint64 _nonce,\n bytes memory _payload\n ) public payable virtual {\n // assert there is message to retry\n bytes32 payloadHash = failedMessages[_srcChainId][_srcAddress][_nonce];\n if (payloadHash == bytes32(0) || keccak256(_payload) != payloadHash) revert InvalidPayload();\n // clear the stored message\n failedMessages[_srcChainId][_srcAddress][_nonce] = bytes32(0);\n // execute the message. revert if it fails again\n _nonblockingLzReceive(_srcChainId, _srcAddress, _nonce, _payload);\n }\n\n // ============================= Internal Functions ===================================\n\n /// @notice Handles message receptions in a non blocking way\n /// @param _srcChainId ChainId of the source chain - LayerZero standard\n /// @param _srcAddress Sender of the source chain\n /// @param _nonce Nounce of the message\n /// @param _payload Data: recipient address and amount\n /// @dev public for the needs of try / catch but effectively internal\n function nonblockingLzReceive(\n uint16 _srcChainId,\n bytes memory _srcAddress,\n uint64 _nonce,\n bytes memory _payload\n ) public virtual {\n // only internal transaction\n if (msg.sender != address(this)) revert InvalidCaller();\n _nonblockingLzReceive(_srcChainId, _srcAddress, _nonce, _payload);\n }\n\n /// @notice Handles message receptions in a non blocking way\n /// @param _srcChainId ChainId of the source chain - LayerZero standard\n /// @param _srcAddress Sender of the source chain\n /// @param _nonce Nounce of the message\n /// @param _payload Data: recipient address and amount\n function _nonblockingLzReceive(\n uint16 _srcChainId,\n bytes memory _srcAddress,\n uint64 _nonce,\n bytes memory _payload\n ) internal virtual;\n\n /// @notice Handles message receptions in a blocking way\n /// @param _srcChainId ChainId of the source chain - LayerZero standard\n /// @param _srcAddress Sender of the source chain\n /// @param _nonce Nounce of the message\n /// @param _payload Data: recipient address and amount\n function _blockingLzReceive(\n uint16 _srcChainId,\n bytes memory _srcAddress,\n uint64 _nonce,\n bytes memory _payload\n ) internal {\n // try-catch all errors/exceptions\n try this.nonblockingLzReceive(_srcChainId, _srcAddress, _nonce, _payload) {\n // do nothing\n } catch {\n // error / exception\n failedMessages[_srcChainId][_srcAddress][_nonce] = keccak256(_payload);\n emit MessageFailed(_srcChainId, _srcAddress, _nonce, _payload);\n }\n }\n\n /// @notice Sends a message to the LZ endpoint and process it\n /// @param _dstChainId L0 defined chain id to send tokens too\n /// @param _payload Data: recipient address and amount\n /// @param _refundAddress Address LayerZero refunds if too much message fee is sent\n /// @param _zroPaymentAddress Set to address(0x0) if not paying in ZRO (LayerZero Token)\n /// @param _adapterParams Flexible bytes array to indicate messaging adapter services in L0\n function _lzSend(\n uint16 _dstChainId,\n bytes memory _payload,\n address payable _refundAddress,\n address _zroPaymentAddress,\n bytes memory _adapterParams\n ) internal virtual {\n bytes memory trustedRemote = trustedRemoteLookup[_dstChainId];\n if (trustedRemote.length == 0) revert InvalidSource();\n //solhint-disable-next-line\n lzEndpoint.send{ value: msg.value }(\n _dstChainId,\n trustedRemote,\n _payload,\n _refundAddress,\n _zroPaymentAddress,\n _adapterParams\n );\n }\n\n /// @notice Checks the gas limit of a given transaction\n function _checkGasLimit(\n uint16 _dstChainId,\n uint16 _type,\n bytes memory _adapterParams,\n uint256 _extraGas\n ) internal view virtual {\n uint256 minGasLimit = minDstGasLookup[_dstChainId][_type] + _extraGas;\n if (minGasLimit == 0 || minGasLimit > _getGasLimit(_adapterParams)) revert InsufficientGas();\n }\n\n /// @notice Gets the gas limit from the `_adapterParams` parameter\n function _getGasLimit(bytes memory _adapterParams) internal pure virtual returns (uint256 gasLimit) {\n if (_adapterParams.length < 34) revert InvalidParams();\n // solhint-disable-next-line\n assembly {\n gasLimit := mload(add(_adapterParams, 34))\n }\n }\n\n // ======================= Governance Functions ================================\n\n /// @notice Sets the corresponding address on an other chain.\n /// @param _srcChainId ChainId of the source chain - LayerZero standard\n /// @param _srcAddress Address on the source chain\n /// @dev Used for both receiving and sending message\n /// @dev There can only be one trusted source per chain\n /// @dev Allows owner to set it multiple times.\n function setTrustedRemote(uint16 _srcChainId, bytes calldata _srcAddress) external onlyGovernorOrGuardian {\n trustedRemoteLookup[_srcChainId] = _srcAddress;\n emit SetTrustedRemote(_srcChainId, _srcAddress);\n }\n\n /// @notice Fetches the default LZ config\n function getConfig(\n uint16 _version,\n uint16 _chainId,\n address,\n uint256 _configType\n ) external view returns (bytes memory) {\n return lzEndpoint.getConfig(_version, _chainId, address(this), _configType);\n }\n\n /// @notice Overrides the default LZ config\n function setConfig(\n uint16 _version,\n uint16 _chainId,\n uint256 _configType,\n bytes calldata _config\n ) external override onlyGovernorOrGuardian {\n lzEndpoint.setConfig(_version, _chainId, _configType, _config);\n }\n\n /// @notice Overrides the default LZ config\n function setSendVersion(uint16 _version) external override onlyGovernorOrGuardian {\n lzEndpoint.setSendVersion(_version);\n }\n\n /// @notice Overrides the default LZ config\n function setReceiveVersion(uint16 _version) external override onlyGovernorOrGuardian {\n lzEndpoint.setReceiveVersion(_version);\n }\n\n /// @notice Unpauses the receive functionalities\n function forceResumeReceive(\n uint16 _srcChainId,\n bytes calldata _srcAddress\n ) external override onlyGovernorOrGuardian {\n lzEndpoint.forceResumeReceive(_srcChainId, _srcAddress);\n }\n\n /// @notice Sets the minimum gas parameter for a packet type on a given chain\n function setMinDstGas(uint16 _dstChainId, uint16 _packetType, uint256 _minGas) external onlyGovernorOrGuardian {\n if (_minGas == 0) revert InvalidParams();\n minDstGasLookup[_dstChainId][_packetType] = _minGas;\n }\n\n /// @notice Sets the precrime variable\n function setPrecrime(address _precrime) external onlyGovernorOrGuardian {\n precrime = _precrime;\n }\n\n // ======================= View Functions ================================\n\n /// @notice Checks if the `_srcAddress` corresponds to the trusted source\n function isTrustedRemote(uint16 _srcChainId, bytes calldata _srcAddress) external view returns (bool) {\n bytes memory trustedSource = trustedRemoteLookup[_srcChainId];\n return keccak256(trustedSource) == keccak256(_srcAddress);\n }\n\n uint256[44] private __gap;\n}\n" + }, + "contracts/agToken/layerZero/utils/OFTCore.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.12;\n\nimport \"./NonblockingLzApp.sol\";\nimport \"./IOFTCore.sol\";\nimport \"@openzeppelin/contracts-upgradeable/utils/introspection/ERC165Upgradeable.sol\";\n\n/// @title OFTCore\n/// @author Forked from https://github.com/LayerZero-Labs/solidity-examples/blob/main/contracts/token/oft/OFTCore.sol\n/// but with slight modifications from the Angle Labs, Inc. which added return values to the `_creditTo` and `_debitFrom` functions\n/// @notice Base contract for bridging using LayerZero\nabstract contract OFTCore is NonblockingLzApp, ERC165Upgradeable, IOFTCore {\n /// @notice Amount of additional gas specified\n uint256 public constant EXTRA_GAS = 200000;\n /// @notice Packet type for token transfer\n uint16 public constant PT_SEND = 0;\n\n /// @notice Whether to use custom parameters in transactions\n uint8 public useCustomAdapterParams;\n\n // ==================== External Permissionless Functions ======================\n\n /// @inheritdoc IOFTCore\n function sendWithPermit(\n uint16 _dstChainId,\n bytes memory _toAddress,\n uint256 _amount,\n address payable _refundAddress,\n address _zroPaymentAddress,\n bytes memory _adapterParams,\n uint256 deadline,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) public payable virtual;\n\n /// @inheritdoc IOFTCore\n function send(\n uint16 _dstChainId,\n bytes memory _toAddress,\n uint256 _amount,\n address payable _refundAddress,\n address _zroPaymentAddress,\n bytes memory _adapterParams\n ) public payable virtual {\n _checkAdapterParams(_dstChainId, PT_SEND, _adapterParams, EXTRA_GAS);\n _amount = _debitFrom(_dstChainId, _toAddress, _amount);\n\n bytes memory payload = abi.encode(_toAddress, _amount);\n _lzSend(_dstChainId, payload, _refundAddress, _zroPaymentAddress, _adapterParams);\n\n uint64 nonce = lzEndpoint.getOutboundNonce(_dstChainId, address(this));\n emit SendToChain(msg.sender, _dstChainId, _toAddress, _amount, nonce);\n }\n\n /// @inheritdoc IOFTCore\n function sendCredit(\n uint16 _dstChainId,\n bytes memory _toAddress,\n uint256 _amount,\n address payable _refundAddress,\n address _zroPaymentAddress,\n bytes memory _adapterParams\n ) public payable virtual {\n _checkAdapterParams(_dstChainId, PT_SEND, _adapterParams, EXTRA_GAS);\n _amount = _debitCreditFrom(_dstChainId, _toAddress, _amount);\n\n _send(_dstChainId, _toAddress, _amount, _refundAddress, _zroPaymentAddress, _adapterParams);\n }\n\n /// @inheritdoc IOFTCore\n function withdraw(uint256 amount, address recipient) external virtual returns (uint256);\n\n /// @notice Sets whether custom adapter parameters can be used or not\n function setUseCustomAdapterParams(uint8 _useCustomAdapterParams) public virtual onlyGovernorOrGuardian {\n useCustomAdapterParams = _useCustomAdapterParams;\n }\n\n // =========================== Internal Functions ==============================\n\n /// @notice Internal function to send `_amount` amount of token to (`_dstChainId`, `_toAddress`)\n /// @param _dstChainId the destination chain identifier\n /// @param _toAddress can be any size depending on the `dstChainId`.\n /// @param _amount the quantity of tokens in wei\n /// @param _refundAddress the address LayerZero refunds if too much message fee is sent\n /// @param _zroPaymentAddress set to address(0x0) if not paying in ZRO (LayerZero Token)\n /// @param _adapterParams is a flexible bytes array to indicate messaging adapter services\n /// @dev Accounting and checks should be performed beforehand\n function _send(\n uint16 _dstChainId,\n bytes memory _toAddress,\n uint256 _amount,\n address payable _refundAddress,\n address _zroPaymentAddress,\n bytes memory _adapterParams\n ) internal {\n bytes memory payload = abi.encode(_toAddress, _amount);\n _lzSend(_dstChainId, payload, _refundAddress, _zroPaymentAddress, _adapterParams);\n\n uint64 nonce = lzEndpoint.getOutboundNonce(_dstChainId, address(this));\n emit SendToChain(msg.sender, _dstChainId, _toAddress, _amount, nonce);\n }\n\n /// @inheritdoc NonblockingLzApp\n function _nonblockingLzReceive(\n uint16 _srcChainId,\n bytes memory _srcAddress,\n uint64 _nonce,\n bytes memory _payload\n ) internal virtual override {\n // decode and load the toAddress\n (bytes memory toAddressBytes, uint256 amount) = abi.decode(_payload, (bytes, uint256));\n address toAddress;\n //solhint-disable-next-line\n assembly {\n toAddress := mload(add(toAddressBytes, 20))\n }\n amount = _creditTo(_srcChainId, toAddress, amount);\n\n emit ReceiveFromChain(_srcChainId, _srcAddress, toAddress, amount, _nonce);\n }\n\n /// @notice Checks the adapter parameters given during the smart contract call\n function _checkAdapterParams(\n uint16 _dstChainId,\n uint16 _pkType,\n bytes memory _adapterParams,\n uint256 _extraGas\n ) internal virtual {\n if (useCustomAdapterParams > 0) _checkGasLimit(_dstChainId, _pkType, _adapterParams, _extraGas);\n else if (_adapterParams.length != 0) revert InvalidParams();\n }\n\n /// @notice Makes accountability when bridging from this contract using canonical token\n /// @param _dstChainId ChainId of the destination chain - LayerZero standard\n /// @param _toAddress Recipient on the destination chain\n /// @param _amount Amount to bridge\n function _debitFrom(\n uint16 _dstChainId,\n bytes memory _toAddress,\n uint256 _amount\n ) internal virtual returns (uint256);\n\n /// @notice Makes accountability when bridging from this contract's credit\n /// @param _dstChainId ChainId of the destination chain - LayerZero standard\n /// @param _toAddress Recipient on the destination chain\n /// @param _amount Amount to bridge\n function _debitCreditFrom(\n uint16 _dstChainId,\n bytes memory _toAddress,\n uint256 _amount\n ) internal virtual returns (uint256);\n\n /// @notice Makes accountability when bridging to this contract\n /// @param _srcChainId ChainId of the source chain - LayerZero standard\n /// @param _toAddress Recipient on this chain\n /// @param _amount Amount to bridge\n function _creditTo(uint16 _srcChainId, address _toAddress, uint256 _amount) internal virtual returns (uint256);\n\n // ========================== View Functions ===================================\n\n /// @inheritdoc ERC165Upgradeable\n function supportsInterface(\n bytes4 interfaceId\n ) public view virtual override(ERC165Upgradeable, IERC165) returns (bool) {\n return interfaceId == type(IOFTCore).interfaceId || super.supportsInterface(interfaceId);\n }\n\n /// @inheritdoc IOFTCore\n function estimateSendFee(\n uint16 _dstChainId,\n bytes memory _toAddress,\n uint256 _amount,\n bool _useZro,\n bytes memory _adapterParams\n ) public view virtual override returns (uint256 nativeFee, uint256 zroFee) {\n // mock the payload for send()\n bytes memory payload = abi.encode(_toAddress, _amount);\n return lzEndpoint.estimateFees(_dstChainId, address(this), payload, _useZro, _adapterParams);\n }\n\n uint256[49] private __gap;\n}\n" + }, + "contracts/agToken/polygon/TokenPolygonUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.12;\n\nimport \"./utils/ERC20UpgradeableCustom.sol\";\nimport \"@openzeppelin/contracts-upgradeable/access/AccessControlUpgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/utils/cryptography/draft-EIP712Upgradeable.sol\";\nimport \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\nimport \"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\";\n\nimport \"../../interfaces/IAgToken.sol\";\nimport \"../../interfaces/ITreasury.sol\";\n\ninterface IChildToken {\n function deposit(address user, bytes calldata depositData) external;\n\n function withdraw(uint256 amount) external;\n}\n\ncontract TokenPolygonUpgradeable is\n Initializable,\n ERC20UpgradeableCustom,\n AccessControlUpgradeable,\n EIP712Upgradeable,\n IChildToken\n{\n bytes32 public constant DEPOSITOR_ROLE = keccak256(\"DEPOSITOR_ROLE\");\n\n /// @dev Emitted when the child chain manager changes\n event ChildChainManagerAdded(address newAddress);\n event ChildChainManagerRevoked(address oldAddress);\n\n constructor() initializer {}\n\n function initialize(\n string memory _name,\n string memory _symbol,\n address childChainManager,\n address guardian\n ) public initializer {\n __ERC20_init(_name, _symbol);\n __AccessControl_init();\n _setupRole(DEFAULT_ADMIN_ROLE, guardian);\n _setupRole(DEPOSITOR_ROLE, childChainManager);\n __EIP712_init(_name, \"1\");\n }\n\n /**\n * @notice Called when the bridge has tokens to mint\n * @param user Address to mint the token to\n * @param depositData Encoded amount to mint\n */\n function deposit(address user, bytes calldata depositData) external override {\n require(hasRole(DEPOSITOR_ROLE, msg.sender));\n uint256 amount = abi.decode(depositData, (uint256));\n _mint(user, amount);\n }\n\n /**\n * @notice Called when user wants to withdraw tokens back to root chain\n * @dev Should burn user's tokens. This transaction will be verified when exiting on root chain\n * @param amount Amount of tokens to withdraw\n */\n function withdraw(uint256 amount) external override {\n _burn(_msgSender(), amount);\n }\n\n // =============================================================================\n // ======================= New data added for the upgrade ======================\n // =============================================================================\n\n mapping(address => bool) public isMinter;\n /// @notice Reference to the treasury contract which can grant minting rights\n address public treasury;\n /// @notice Boolean to check whether the contract has been reinitialized after its upgrade\n bool public treasuryInitialized;\n\n using SafeERC20 for IERC20;\n\n /// @notice Base used for fee computation\n uint256 public constant BASE_PARAMS = 10 ** 9;\n\n // =============================== Bridging Data ===============================\n\n /// @notice Struct with some data about a specific bridge token\n struct BridgeDetails {\n // Limit on the balance of bridge token held by the contract: it is designed\n // to reduce the exposure of the system to hacks\n uint256 limit;\n // Limit on the hourly volume of token minted through this bridge\n // Technically the limit over a rolling hour is hourlyLimit x2 as hourly limit\n // is enforced only between x:00 and x+1:00\n uint256 hourlyLimit;\n // Fee taken for swapping in and out the token\n uint64 fee;\n // Whether the associated token is allowed or not\n bool allowed;\n // Whether swapping in and out from the associated token is paused or not\n bool paused;\n }\n\n /// @notice Maps a bridge token to data\n mapping(address => BridgeDetails) public bridges;\n /// @notice List of all bridge tokens\n address[] public bridgeTokensList;\n /// @notice Maps a bridge token to the associated hourly volume\n mapping(address => mapping(uint256 => uint256)) public usage;\n /// @notice Maps an address to whether it is exempt of fees for when it comes to swapping in and out\n mapping(address => uint256) public isFeeExempt;\n /// @notice Limit to the amount of tokens that can be sent from that chain to another chain\n uint256 public chainTotalHourlyLimit;\n /// @notice Usage per hour on that chain. Maps an hourly timestamp to the total volume swapped out on the chain\n mapping(uint256 => uint256) public chainTotalUsage;\n\n uint256[42] private __gap;\n\n // ================================== Events ===================================\n\n event BridgeTokenAdded(address indexed bridgeToken, uint256 limit, uint256 hourlyLimit, uint64 fee, bool paused);\n event BridgeTokenToggled(address indexed bridgeToken, bool toggleStatus);\n event BridgeTokenRemoved(address indexed bridgeToken);\n event BridgeTokenFeeUpdated(address indexed bridgeToken, uint64 fee);\n event BridgeTokenLimitUpdated(address indexed bridgeToken, uint256 limit);\n event BridgeTokenHourlyLimitUpdated(address indexed bridgeToken, uint256 hourlyLimit);\n event HourlyLimitUpdated(uint256 hourlyLimit);\n event FeeToggled(address indexed theAddress, uint256 toggleStatus);\n event KeeperToggled(address indexed keeper, bool toggleStatus);\n event MinterToggled(address indexed minter);\n event Recovered(address indexed token, address indexed to, uint256 amount);\n event TreasuryUpdated(address indexed _treasury);\n\n // ================================== Errors ===================================\n\n error AssetStillControlledInReserves();\n error BurnAmountExceedsAllowance();\n error HourlyLimitExceeded();\n error InvalidSender();\n error InvalidToken();\n error InvalidTreasury();\n error NotGovernor();\n error NotGovernorOrGuardian();\n error NotMinter();\n error NotTreasury();\n error TooBigAmount();\n error TooHighParameterValue();\n error TreasuryAlreadyInitialized();\n error ZeroAddress();\n\n /// @notice Checks to see if it is the `Treasury` calling this contract\n /// @dev There is no Access Control here, because it can be handled cheaply through this modifier\n modifier onlyTreasury() {\n if (msg.sender != treasury) revert NotTreasury();\n _;\n }\n\n /// @notice Checks whether the sender has the minting right\n modifier onlyMinter() {\n if (!isMinter[msg.sender]) revert NotMinter();\n _;\n }\n\n /// @notice Checks whether the `msg.sender` has the governor role or not\n modifier onlyGovernor() {\n if (!ITreasury(treasury).isGovernor(msg.sender)) revert NotGovernor();\n _;\n }\n\n /// @notice Checks whether the `msg.sender` has the governor role or the guardian role\n modifier onlyGovernorOrGuardian() {\n if (!ITreasury(treasury).isGovernorOrGuardian(msg.sender)) revert NotGovernorOrGuardian();\n _;\n }\n\n /// @notice Sets up the treasury contract on Polygon after the upgrade\n /// @param _treasury Address of the treasury contract\n function setUpTreasury(address _treasury) external {\n // Only governor on Polygon\n if (msg.sender != 0xdA2D2f638D6fcbE306236583845e5822554c02EA) revert NotGovernor();\n if (address(ITreasury(_treasury).stablecoin()) != address(this)) revert InvalidTreasury();\n if (treasuryInitialized) revert TreasuryAlreadyInitialized();\n treasury = _treasury;\n treasuryInitialized = true;\n emit TreasuryUpdated(_treasury);\n }\n\n // =========================== External Function ===============================\n\n /// @notice Allows anyone to burn agToken without redeeming collateral back\n /// @param amount Amount of stablecoins to burn\n /// @dev This function can typically be called if there is a settlement mechanism to burn stablecoins\n function burnStablecoin(uint256 amount) external {\n _burnCustom(msg.sender, amount);\n }\n\n // ======================= Minter Role Only Functions ==========================\n\n function burnSelf(uint256 amount, address burner) external onlyMinter {\n _burnCustom(burner, amount);\n }\n\n function burnFrom(uint256 amount, address burner, address sender) external onlyMinter {\n _burnFromNoRedeem(amount, burner, sender);\n }\n\n function mint(address account, uint256 amount) external onlyMinter {\n _mint(account, amount);\n }\n\n // ======================= Treasury Only Functions =============================\n\n function addMinter(address minter) external onlyTreasury {\n isMinter[minter] = true;\n emit MinterToggled(minter);\n }\n\n function removeMinter(address minter) external {\n if (msg.sender != address(treasury) && msg.sender != minter) revert InvalidSender();\n isMinter[minter] = false;\n emit MinterToggled(minter);\n }\n\n function setTreasury(address _treasury) external onlyTreasury {\n treasury = _treasury;\n emit TreasuryUpdated(_treasury);\n }\n\n // ============================ Internal Function ==============================\n\n /// @notice Internal version of the function `burnFromNoRedeem`\n /// @param amount Amount to burn\n /// @dev It is at the level of this function that allowance checks are performed\n function _burnFromNoRedeem(uint256 amount, address burner, address sender) internal {\n if (burner != sender) {\n uint256 currentAllowance = allowance(burner, sender);\n if (currentAllowance < amount) revert BurnAmountExceedsAllowance();\n _approve(burner, sender, currentAllowance - amount);\n }\n _burnCustom(burner, amount);\n }\n\n // ==================== External Permissionless Functions ======================\n\n /// @notice Returns the list of all supported bridge tokens\n /// @dev Helpful for UIs\n function allBridgeTokens() external view returns (address[] memory) {\n return bridgeTokensList;\n }\n\n /// @notice Returns the current volume for a bridge, for the current hour\n /// @dev Helpful for UIs\n function currentUsage(address bridge) external view returns (uint256) {\n return usage[bridge][block.timestamp / 3600];\n }\n\n /// @notice Returns the current total volume on the chain for the current hour\n /// @dev Helpful for UIs\n function currentTotalUsage() external view returns (uint256) {\n return chainTotalUsage[block.timestamp / 3600];\n }\n\n /// @notice Mints the canonical token from a supported bridge token\n /// @param bridgeToken Bridge token to use to mint\n /// @param amount Amount of bridge tokens to send\n /// @param to Address to which the stablecoin should be sent\n /// @dev Some fees may be taken by the protocol depending on the token used and on the address calling\n function swapIn(address bridgeToken, uint256 amount, address to) external returns (uint256) {\n BridgeDetails memory bridgeDetails = bridges[bridgeToken];\n if (!bridgeDetails.allowed || bridgeDetails.paused) revert InvalidToken();\n uint256 balance = IERC20(bridgeToken).balanceOf(address(this));\n if (balance + amount > bridgeDetails.limit) {\n // In case someone maliciously sends tokens to this contract\n // Or the limit changes\n if (bridgeDetails.limit > balance) amount = bridgeDetails.limit - balance;\n else {\n amount = 0;\n }\n }\n\n // Checking requirement on the hourly volume\n uint256 hour = block.timestamp / 3600;\n uint256 hourlyUsage = usage[bridgeToken][hour] + amount;\n if (hourlyUsage > bridgeDetails.hourlyLimit) {\n // Edge case when the hourly limit changes\n if (bridgeDetails.hourlyLimit > usage[bridgeToken][hour])\n amount = bridgeDetails.hourlyLimit - usage[bridgeToken][hour];\n else {\n amount = 0;\n }\n }\n usage[bridgeToken][hour] += amount;\n\n IERC20(bridgeToken).safeTransferFrom(msg.sender, address(this), amount);\n uint256 canonicalOut = amount;\n // Computing fees\n if (isFeeExempt[msg.sender] == 0) {\n canonicalOut -= (canonicalOut * bridgeDetails.fee) / BASE_PARAMS;\n }\n _mint(to, canonicalOut);\n return canonicalOut;\n }\n\n /// @notice Burns the canonical token in exchange for a bridge token\n /// @param bridgeToken Bridge token required\n /// @param amount Amount of canonical tokens to burn\n /// @param to Address to which the bridge token should be sent\n /// @dev Some fees may be taken by the protocol depending on the token used and on the address calling\n function swapOut(address bridgeToken, uint256 amount, address to) external returns (uint256) {\n BridgeDetails memory bridgeDetails = bridges[bridgeToken];\n if (!bridgeDetails.allowed || bridgeDetails.paused) revert InvalidToken();\n\n uint256 hour = block.timestamp / 3600;\n uint256 hourlyUsage = chainTotalUsage[hour] + amount;\n // If the amount being swapped out exceeds the limit, we revert\n // We don't want to change the amount being swapped out.\n // The user can decide to send another tx with the correct amount to reach the limit\n if (hourlyUsage > chainTotalHourlyLimit) revert HourlyLimitExceeded();\n chainTotalUsage[hour] = hourlyUsage;\n\n _burnCustom(msg.sender, amount);\n uint256 bridgeOut = amount;\n if (isFeeExempt[msg.sender] == 0) {\n bridgeOut -= (bridgeOut * bridgeDetails.fee) / BASE_PARAMS;\n }\n IERC20(bridgeToken).safeTransfer(to, bridgeOut);\n return bridgeOut;\n }\n\n // ======================= Governance Functions ================================\n\n /// @notice Adds support for a bridge token\n /// @param bridgeToken Bridge token to add: it should be a version of the stablecoin from another bridge\n /// @param limit Limit on the balance of bridge token this contract could hold\n /// @param hourlyLimit Limit on the hourly volume for this bridge\n /// @param paused Whether swapping for this token should be paused or not\n /// @param fee Fee taken upon swapping for or against this token\n function addBridgeToken(\n address bridgeToken,\n uint256 limit,\n uint256 hourlyLimit,\n uint64 fee,\n bool paused\n ) external onlyGovernor {\n if (bridges[bridgeToken].allowed || bridgeToken == address(0)) revert InvalidToken();\n if (fee > BASE_PARAMS) revert TooHighParameterValue();\n BridgeDetails memory _bridge;\n _bridge.limit = limit;\n _bridge.hourlyLimit = hourlyLimit;\n _bridge.paused = paused;\n _bridge.fee = fee;\n _bridge.allowed = true;\n bridges[bridgeToken] = _bridge;\n bridgeTokensList.push(bridgeToken);\n emit BridgeTokenAdded(bridgeToken, limit, hourlyLimit, fee, paused);\n }\n\n /// @notice Removes support for a token\n /// @param bridgeToken Address of the bridge token to remove support for\n function removeBridgeToken(address bridgeToken) external onlyGovernor {\n if (IERC20(bridgeToken).balanceOf(address(this)) != 0) revert AssetStillControlledInReserves();\n delete bridges[bridgeToken];\n // Deletion from `bridgeTokensList` loop\n uint256 bridgeTokensListLength = bridgeTokensList.length;\n for (uint256 i; i < bridgeTokensListLength - 1; ++i) {\n if (bridgeTokensList[i] == bridgeToken) {\n // Replace the `bridgeToken` to remove with the last of the list\n bridgeTokensList[i] = bridgeTokensList[bridgeTokensListLength - 1];\n break;\n }\n }\n // Remove last element in array\n bridgeTokensList.pop();\n emit BridgeTokenRemoved(bridgeToken);\n }\n\n /// @notice Recovers any ERC20 token\n /// @dev Can be used to withdraw bridge tokens for them to be de-bridged on mainnet\n function recoverERC20(address tokenAddress, address to, uint256 amountToRecover) external onlyGovernor {\n IERC20(tokenAddress).safeTransfer(to, amountToRecover);\n emit Recovered(tokenAddress, to, amountToRecover);\n }\n\n /// @notice Updates the `limit` amount for `bridgeToken`\n function setLimit(address bridgeToken, uint256 limit) external onlyGovernorOrGuardian {\n if (!bridges[bridgeToken].allowed) revert InvalidToken();\n bridges[bridgeToken].limit = limit;\n emit BridgeTokenLimitUpdated(bridgeToken, limit);\n }\n\n /// @notice Updates the `hourlyLimit` amount for `bridgeToken`\n function setHourlyLimit(address bridgeToken, uint256 hourlyLimit) external onlyGovernorOrGuardian {\n if (!bridges[bridgeToken].allowed) revert InvalidToken();\n bridges[bridgeToken].hourlyLimit = hourlyLimit;\n emit BridgeTokenHourlyLimitUpdated(bridgeToken, hourlyLimit);\n }\n\n /// @notice Updates the `chainTotalHourlyLimit` amount\n function setChainTotalHourlyLimit(uint256 hourlyLimit) external onlyGovernorOrGuardian {\n chainTotalHourlyLimit = hourlyLimit;\n emit HourlyLimitUpdated(hourlyLimit);\n }\n\n /// @notice Updates the `fee` value for `bridgeToken`\n function setSwapFee(address bridgeToken, uint64 fee) external onlyGovernorOrGuardian {\n if (!bridges[bridgeToken].allowed) revert InvalidToken();\n if (fee > BASE_PARAMS) revert TooHighParameterValue();\n bridges[bridgeToken].fee = fee;\n emit BridgeTokenFeeUpdated(bridgeToken, fee);\n }\n\n /// @notice Pauses or unpauses swapping in and out for a token\n function toggleBridge(address bridgeToken) external onlyGovernorOrGuardian {\n if (!bridges[bridgeToken].allowed) revert InvalidToken();\n bool pausedStatus = bridges[bridgeToken].paused;\n bridges[bridgeToken].paused = !pausedStatus;\n emit BridgeTokenToggled(bridgeToken, !pausedStatus);\n }\n\n /// @notice Toggles fees for the address `theAddress`\n function toggleFeesForAddress(address theAddress) external onlyGovernorOrGuardian {\n uint256 feeExemptStatus = 1 - isFeeExempt[theAddress];\n isFeeExempt[theAddress] = feeExemptStatus;\n emit FeeToggled(theAddress, feeExemptStatus);\n }\n}\n" + }, + "contracts/agToken/polygon/utils/ERC20UpgradeableCustom.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (token/ERC20/ERC20.sol)\n\npragma solidity ^0.8.0;\n\nimport \"@openzeppelin/contracts-upgradeable/token/ERC20/IERC20Upgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/token/ERC20/extensions/IERC20MetadataUpgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/utils/ContextUpgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol\";\n\n/**\n * @dev Implementation of the {IERC20} interface modified by Angle Labs, Inc.\n *\n * This implementation has a custom burn function to avoid having a {Transfer} event to the zero address\n * in some specific burn cases to avoid having Polygon PoS bridge catching this event\n *\n * TIP: For a detailed writeup see our guide\n * https://forum.zeppelin.solutions/t/how-to-implement-erc20-supply-mechanisms/226[How\n * to implement supply mechanisms].\n *\n * We have followed general OpenZeppelin Contracts guidelines: functions revert\n * instead returning `false` on failure. This behavior is nonetheless\n * conventional and does not conflict with the expectations of ERC20\n * applications.\n *\n * Additionally, an {Approval} event is emitted on calls to {transferFrom}.\n * This allows applications to reconstruct the allowance for all accounts just\n * by listening to said events. Other implementations of the EIP may not emit\n * these events, as it isn't required by the specification.\n *\n * Finally, the non-standard {decreaseAllowance} and {increaseAllowance}\n * functions have been added to mitigate the well-known issues around setting\n * allowances. See {IERC20-approve}.\n */\ncontract ERC20UpgradeableCustom is Initializable, ContextUpgradeable, IERC20Upgradeable, IERC20MetadataUpgradeable {\n mapping(address => uint256) private _balances;\n\n mapping(address => mapping(address => uint256)) private _allowances;\n\n uint256 private _totalSupply;\n\n string private _name;\n string private _symbol;\n\n /**\n * @dev Sets the values for {name} and {symbol}.\n *\n * The default value of {decimals} is 18. To select a different value for\n * {decimals} you should overload it.\n *\n * All two of these values are immutable: they can only be set once during\n * construction.\n */\n //solhint-disable-next-line\n function __ERC20_init(string memory name_, string memory symbol_) internal onlyInitializing {\n __Context_init_unchained();\n __ERC20_init_unchained(name_, symbol_);\n }\n\n //solhint-disable-next-line\n function __ERC20_init_unchained(string memory name_, string memory symbol_) internal onlyInitializing {\n _name = name_;\n _symbol = symbol_;\n }\n\n /**\n * @dev Returns the name of the token.\n */\n function name() public view virtual override returns (string memory) {\n return _name;\n }\n\n /**\n * @dev Returns the symbol of the token, usually a shorter version of the\n * name.\n */\n function symbol() public view virtual override returns (string memory) {\n return _symbol;\n }\n\n /**\n * @dev Returns the number of decimals used to get its user representation.\n * For example, if `decimals` equals `2`, a balance of `505` tokens should\n * be displayed to a user as `5.05` (`505 / 10 ** 2`).\n *\n * Tokens usually opt for a value of 18, imitating the relationship between\n * Ether and Wei. This is the value {ERC20} uses, unless this function is\n * overridden;\n *\n * NOTE: This information is only used for _display_ purposes: it in\n * no way affects any of the arithmetic of the contract, including\n * {IERC20-balanceOf} and {IERC20-transfer}.\n */\n function decimals() public view virtual override returns (uint8) {\n return 18;\n }\n\n /**\n * @dev See {IERC20-totalSupply}.\n */\n function totalSupply() public view virtual override returns (uint256) {\n return _totalSupply;\n }\n\n /**\n * @dev See {IERC20-balanceOf}.\n */\n function balanceOf(address account) public view virtual override returns (uint256) {\n return _balances[account];\n }\n\n /**\n * @dev See {IERC20-transfer}.\n *\n * Requirements:\n *\n * - `recipient` cannot be the zero address.\n * - the caller must have a balance of at least `amount`.\n */\n function transfer(address recipient, uint256 amount) public virtual override returns (bool) {\n _transfer(_msgSender(), recipient, amount);\n return true;\n }\n\n /**\n * @dev See {IERC20-allowance}.\n */\n function allowance(address owner, address spender) public view virtual override returns (uint256) {\n return _allowances[owner][spender];\n }\n\n /**\n * @dev See {IERC20-approve}.\n *\n * Requirements:\n *\n * - `spender` cannot be the zero address.\n */\n function approve(address spender, uint256 amount) public virtual override returns (bool) {\n _approve(_msgSender(), spender, amount);\n return true;\n }\n\n /**\n * @dev See {IERC20-transferFrom}.\n *\n * Emits an {Approval} event indicating the updated allowance. This is not\n * required by the EIP. See the note at the beginning of {ERC20}.\n *\n * Requirements:\n *\n * - `sender` and `recipient` cannot be the zero address.\n * - `sender` must have a balance of at least `amount`.\n * - the caller must have allowance for `sender`'s tokens of at least\n * `amount`.\n */\n function transferFrom(address sender, address recipient, uint256 amount) public virtual override returns (bool) {\n _transfer(sender, recipient, amount);\n\n uint256 currentAllowance = _allowances[sender][_msgSender()];\n require(currentAllowance >= amount, \"ERC20: transfer amount exceeds allowance\");\n unchecked {\n _approve(sender, _msgSender(), currentAllowance - amount);\n }\n\n return true;\n }\n\n /**\n * @dev Atomically increases the allowance granted to `spender` by the caller.\n *\n * This is an alternative to {approve} that can be used as a mitigation for\n * problems described in {IERC20-approve}.\n *\n * Emits an {Approval} event indicating the updated allowance.\n *\n * Requirements:\n *\n * - `spender` cannot be the zero address.\n */\n function increaseAllowance(address spender, uint256 addedValue) public virtual returns (bool) {\n _approve(_msgSender(), spender, _allowances[_msgSender()][spender] + addedValue);\n return true;\n }\n\n /**\n * @dev Atomically decreases the allowance granted to `spender` by the caller.\n *\n * This is an alternative to {approve} that can be used as a mitigation for\n * problems described in {IERC20-approve}.\n *\n * Emits an {Approval} event indicating the updated allowance.\n *\n * Requirements:\n *\n * - `spender` cannot be the zero address.\n * - `spender` must have allowance for the caller of at least\n * `subtractedValue`.\n */\n function decreaseAllowance(address spender, uint256 subtractedValue) public virtual returns (bool) {\n uint256 currentAllowance = _allowances[_msgSender()][spender];\n require(currentAllowance >= subtractedValue, \"ERC20: decreased allowance below zero\");\n unchecked {\n _approve(_msgSender(), spender, currentAllowance - subtractedValue);\n }\n\n return true;\n }\n\n /**\n * @dev Moves `amount` of tokens from `sender` to `recipient`.\n *\n * This internal function is equivalent to {transfer}, and can be used to\n * e.g. implement automatic token fees, slashing mechanisms, etc.\n *\n * Emits a {Transfer} event.\n *\n * Requirements:\n *\n * - `sender` cannot be the zero address.\n * - `recipient` cannot be the zero address.\n * - `sender` must have a balance of at least `amount`.\n */\n function _transfer(address sender, address recipient, uint256 amount) internal virtual {\n require(sender != address(0), \"ERC20: transfer from the zero address\");\n require(recipient != address(0), \"ERC20: transfer to the zero address\");\n\n _beforeTokenTransfer(sender, recipient, amount);\n\n uint256 senderBalance = _balances[sender];\n require(senderBalance >= amount, \"ERC20: transfer amount exceeds balance\");\n unchecked {\n _balances[sender] = senderBalance - amount;\n }\n _balances[recipient] += amount;\n\n emit Transfer(sender, recipient, amount);\n\n _afterTokenTransfer(sender, recipient, amount);\n }\n\n /** @dev Creates `amount` tokens and assigns them to `account`, increasing\n * the total supply.\n *\n * Emits a {Transfer} event with `from` set to the zero address.\n *\n * Requirements:\n *\n * - `account` cannot be the zero address.\n */\n function _mint(address account, uint256 amount) internal virtual {\n require(account != address(0), \"ERC20: mint to the zero address\");\n\n _beforeTokenTransfer(address(0), account, amount);\n\n _totalSupply += amount;\n _balances[account] += amount;\n emit Transfer(address(0), account, amount);\n\n _afterTokenTransfer(address(0), account, amount);\n }\n\n /**\n * @dev Destroys `amount` tokens from `account`, reducing the\n * total supply.\n *\n * Emits a {Transfer} event with `to` set to the zero address.\n *\n * Requirements:\n *\n * - `account` cannot be the zero address.\n * - `account` must have at least `amount` tokens.\n */\n function _burn(address account, uint256 amount) internal virtual {\n require(account != address(0), \"ERC20: burn from the zero address\");\n\n _beforeTokenTransfer(account, address(0), amount);\n\n uint256 accountBalance = _balances[account];\n require(accountBalance >= amount, \"ERC20: burn amount exceeds balance\");\n unchecked {\n _balances[account] = accountBalance - amount;\n }\n _totalSupply -= amount;\n\n emit Transfer(account, address(0), amount);\n\n _afterTokenTransfer(account, address(0), amount);\n }\n\n /**\n * @dev Destroys `amount` tokens from `account`, reducing the\n * total supply.\n *\n * Contrary to the other `burn` function, the {Transfer} event is not to the zero address\n * but rather to this address: the reason is that not all burn events should be caught up\n * by the PoS bridge\n *\n * Requirements:\n *\n * - `account` cannot be the zero address.\n * - `account` must have at least `amount` tokens.\n */\n function _burnCustom(address account, uint256 amount) internal virtual {\n require(account != address(0), \"ERC20: burn from the zero address\");\n\n _beforeTokenTransfer(account, address(0), amount);\n\n uint256 accountBalance = _balances[account];\n require(accountBalance >= amount, \"ERC20: burn amount exceeds balance\");\n unchecked {\n _balances[account] = accountBalance - amount;\n }\n _totalSupply -= amount;\n\n emit Transfer(account, address(this), amount);\n\n _afterTokenTransfer(account, address(0), amount);\n }\n\n /**\n * @dev Sets `amount` as the allowance of `spender` over the `owner` s tokens.\n *\n * This internal function is equivalent to `approve`, and can be used to\n * e.g. set automatic allowances for certain subsystems, etc.\n *\n * Emits an {Approval} event.\n *\n * Requirements:\n *\n * - `owner` cannot be the zero address.\n * - `spender` cannot be the zero address.\n */\n function _approve(address owner, address spender, uint256 amount) internal virtual {\n require(owner != address(0), \"ERC20: approve from the zero address\");\n require(spender != address(0), \"ERC20: approve to the zero address\");\n\n _allowances[owner][spender] = amount;\n emit Approval(owner, spender, amount);\n }\n\n /**\n * @dev Hook that is called before any transfer of tokens. This includes\n * minting and burning.\n *\n * Calling conditions:\n *\n * - when `from` and `to` are both non-zero, `amount` of `from`'s tokens\n * will be transferred to `to`.\n * - when `from` is zero, `amount` tokens will be minted for `to`.\n * - when `to` is zero, `amount` of `from`'s tokens will be burned.\n * - `from` and `to` are never both zero.\n *\n * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].\n */\n function _beforeTokenTransfer(address from, address to, uint256 amount) internal virtual {}\n\n /**\n * @dev Hook that is called after any transfer of tokens. This includes\n * minting and burning.\n *\n * Calling conditions:\n *\n * - when `from` and `to` are both non-zero, `amount` of `from`'s tokens\n * has been transferred to `to`.\n * - when `from` is zero, `amount` tokens have been minted for `to`.\n * - when `to` is zero, `amount` of `from`'s tokens have been burned.\n * - `from` and `to` are never both zero.\n *\n * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].\n */\n function _afterTokenTransfer(address from, address to, uint256 amount) internal virtual {}\n\n uint256[45] private __gap;\n}\n" + }, + "contracts/coreBorrow/CoreBorrow.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\n/*\n * █ \n ***** ▓▓▓ \n * ▓▓▓▓▓▓▓ \n * ///. ▓▓▓▓▓▓▓▓▓▓▓▓▓ \n ***** //////// ▓▓▓▓▓▓▓ \n * ///////////// ▓▓▓ \n ▓▓ ////////////////// █ ▓▓ \n ▓▓ ▓▓ /////////////////////// ▓▓ ▓▓ \n ▓▓ ▓▓ //////////////////////////// ▓▓ ▓▓ \n ▓▓ ▓▓ /////////▓▓▓///////▓▓▓///////// ▓▓ ▓▓ \n ▓▓ ,////////////////////////////////////// ▓▓ ▓▓ \n ▓▓ ////////////////////////////////////////// ▓▓ \n ▓▓ //////////////////////▓▓▓▓///////////////////// \n ,//////////////////////////////////////////////////// \n .////////////////////////////////////////////////////////// \n .//////////////////////////██.,//////////////////////////█ \n .//////////////////////████..,./////////////////////██ \n ...////////////////███████.....,.////////////////███ \n ,.,////////////████████ ........,///////////████ \n .,.,//////█████████ ,.......///////████ \n ,..//████████ ........./████ \n ..,██████ .....,███ \n .██ ,.,█ \n \n \n \n ▓▓ ▓▓▓▓▓▓▓▓▓▓ ▓▓▓▓▓▓▓▓▓▓ ▓▓ ▓▓▓▓▓▓▓▓▓▓ \n ▓▓▓▓▓▓ ▓▓▓ ▓▓▓ ▓▓▓ ▓▓ ▓▓ ▓▓▓▓ \n ▓▓▓ ▓▓▓ ▓▓▓ ▓▓▓ ▓▓▓ ▓▓▓ ▓▓ ▓▓▓▓▓ \n ▓▓▓ ▓▓ ▓▓▓ ▓▓▓ ▓▓▓▓▓▓▓▓▓▓ ▓▓▓▓▓▓▓▓▓▓ ▓▓▓▓▓▓▓▓▓▓ \n*/\n\npragma solidity ^0.8.12;\n\nimport \"@openzeppelin/contracts-upgradeable/access/AccessControlEnumerableUpgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol\";\n\nimport \"../interfaces/ICoreBorrow.sol\";\nimport \"../interfaces/IFlashAngle.sol\";\nimport \"../interfaces/ITreasury.sol\";\n\n/// @title CoreBorrow\n/// @author Angle Labs, Inc.\n/// @notice Core contract of the borrowing module. This contract handles the access control across all contracts\n/// (it is read by all treasury contracts), and manages the `flashLoanModule`. It has no minting rights over the\n/// stablecoin contracts\ncontract CoreBorrow is ICoreBorrow, Initializable, AccessControlEnumerableUpgradeable {\n /// @notice Role for guardians\n bytes32 public constant GUARDIAN_ROLE = keccak256(\"GUARDIAN_ROLE\");\n /// @notice Role for governors\n bytes32 public constant GOVERNOR_ROLE = keccak256(\"GOVERNOR_ROLE\");\n /// @notice Role for treasury contract\n bytes32 public constant FLASHLOANER_TREASURY_ROLE = keccak256(\"FLASHLOANER_TREASURY_ROLE\");\n\n // ============================= Reference =====================================\n\n /// @notice Reference to the `flashLoanModule` with minting rights over the different stablecoins of the protocol\n address public flashLoanModule;\n\n // =============================== Events ======================================\n\n event FlashLoanModuleUpdated(address indexed _flashloanModule);\n event CoreUpdated(address indexed _core);\n\n // =============================== Errors ======================================\n\n error InvalidCore();\n error IncompatibleGovernorAndGuardian();\n error NotEnoughGovernorsLeft();\n error ZeroAddress();\n\n /// @notice Initializes the `CoreBorrow` contract and the access control of the borrowing module\n /// @param governor Address of the governor of the Angle Protocol\n /// @param guardian Guardian address of the protocol\n function initialize(address governor, address guardian) public initializer {\n if (governor == address(0) || guardian == address(0)) revert ZeroAddress();\n if (governor == guardian) revert IncompatibleGovernorAndGuardian();\n _setupRole(GOVERNOR_ROLE, governor);\n _setupRole(GUARDIAN_ROLE, guardian);\n _setupRole(GUARDIAN_ROLE, governor);\n _setRoleAdmin(GUARDIAN_ROLE, GOVERNOR_ROLE);\n _setRoleAdmin(GOVERNOR_ROLE, GOVERNOR_ROLE);\n _setRoleAdmin(FLASHLOANER_TREASURY_ROLE, GOVERNOR_ROLE);\n }\n\n /// @custom:oz-upgrades-unsafe-allow constructor\n constructor() initializer {}\n\n // =========================== View Functions ==================================\n\n /// @inheritdoc ICoreBorrow\n function isFlashLoanerTreasury(address treasury) external view returns (bool) {\n return hasRole(FLASHLOANER_TREASURY_ROLE, treasury);\n }\n\n /// @inheritdoc ICoreBorrow\n function isGovernor(address admin) external view returns (bool) {\n return hasRole(GOVERNOR_ROLE, admin);\n }\n\n /// @inheritdoc ICoreBorrow\n function isGovernorOrGuardian(address admin) external view returns (bool) {\n return hasRole(GUARDIAN_ROLE, admin);\n }\n\n // =========================== Governor Functions ==============================\n\n /// @notice Grants the `FLASHLOANER_TREASURY_ROLE` to a `treasury` contract\n /// @param treasury Contract to grant the role to\n /// @dev This function can be used to allow flash loans on a stablecoin of the protocol\n function addFlashLoanerTreasuryRole(address treasury) external {\n grantRole(FLASHLOANER_TREASURY_ROLE, treasury);\n address _flashLoanModule = flashLoanModule;\n if (_flashLoanModule != address(0)) {\n // This call will revert if `treasury` is the zero address or if it is not linked\n // to this `CoreBorrow` contract\n ITreasury(treasury).setFlashLoanModule(_flashLoanModule);\n IFlashAngle(_flashLoanModule).addStablecoinSupport(treasury);\n }\n }\n\n /// @notice Adds a governor in the protocol\n /// @param governor Address to grant the role to\n /// @dev It is necessary to call this function to grant a governor role to make sure\n /// all governors also have the guardian role\n function addGovernor(address governor) external {\n grantRole(GOVERNOR_ROLE, governor);\n grantRole(GUARDIAN_ROLE, governor);\n }\n\n /// @notice Revokes the flash loan ability for a stablecoin\n /// @param treasury Treasury address associated with the stablecoin for which flash loans\n /// should no longer be available\n function removeFlashLoanerTreasuryRole(address treasury) external {\n revokeRole(FLASHLOANER_TREASURY_ROLE, treasury);\n ITreasury(treasury).setFlashLoanModule(address(0));\n address _flashLoanModule = flashLoanModule;\n if (_flashLoanModule != address(0)) {\n IFlashAngle(flashLoanModule).removeStablecoinSupport(treasury);\n }\n }\n\n /// @notice Revokes a governor from the protocol\n /// @param governor Address to remove the role to\n /// @dev It is necessary to call this function to remove a governor role to make sure\n /// the address also loses its guardian role\n function removeGovernor(address governor) external {\n if (getRoleMemberCount(GOVERNOR_ROLE) <= 1) revert NotEnoughGovernorsLeft();\n revokeRole(GUARDIAN_ROLE, governor);\n revokeRole(GOVERNOR_ROLE, governor);\n }\n\n /// @notice Changes the `flashLoanModule` of the protocol\n /// @param _flashLoanModule Address of the new flash loan module\n function setFlashLoanModule(address _flashLoanModule) external onlyRole(GOVERNOR_ROLE) {\n if (_flashLoanModule != address(0)) {\n if (address(IFlashAngle(_flashLoanModule).core()) != address(this)) revert InvalidCore();\n }\n uint256 count = getRoleMemberCount(FLASHLOANER_TREASURY_ROLE);\n for (uint256 i; i < count; ++i) {\n ITreasury(getRoleMember(FLASHLOANER_TREASURY_ROLE, i)).setFlashLoanModule(_flashLoanModule);\n }\n flashLoanModule = _flashLoanModule;\n emit FlashLoanModuleUpdated(_flashLoanModule);\n }\n\n /// @notice Changes the core contract of the protocol\n /// @param _core New core contract\n /// @dev This function verifies that all governors of the current core contract are also governors\n /// of the new core contract. It also notifies the `flashLoanModule` of the change.\n /// @dev Governance wishing to change the core contract should also make sure to call `setCore`\n /// in the different treasury contracts\n function setCore(ICoreBorrow _core) external onlyRole(GOVERNOR_ROLE) {\n uint256 count = getRoleMemberCount(GOVERNOR_ROLE);\n bool success;\n for (uint256 i; i < count; ++i) {\n success = _core.isGovernor(getRoleMember(GOVERNOR_ROLE, i));\n if (!success) break;\n }\n if (!success) revert InvalidCore();\n address _flashLoanModule = flashLoanModule;\n if (_flashLoanModule != address(0)) IFlashAngle(_flashLoanModule).setCore(address(_core));\n emit CoreUpdated(address(_core));\n }\n}\n" + }, + "contracts/deprecated/AgTokenIntermediateUpgrade.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\nimport \"../interfaces/IAgToken.sol\";\nimport \"../interfaces/coreModule/IStableMaster.sol\";\n// OpenZeppelin may update its version of the ERC20PermitUpgradeable token\nimport \"@openzeppelin/contracts-upgradeable/token/ERC20/extensions/draft-ERC20PermitUpgradeable.sol\";\n\n/// @title AgTokenIntermediateUpgrade\n/// @author Angle Labs, Inc.\n/// @notice Base contract for agToken, that is to say Angle's stablecoins\n/// @dev This contract is used to create and handle the stablecoins of Angle protocol\n/// @dev It is still possible for any address to burn its agTokens without redeeming collateral in exchange\n/// @dev This contract is the upgraded version of the AgToken that was first deployed on Ethereum mainnet and is used to\n/// add other minters as needed by AMOs\ncontract AgTokenIntermediateUpgrade is ERC20PermitUpgradeable {\n // ========================= References to other contracts =====================\n\n /// @notice Reference to the `StableMaster` contract associated to this `AgToken`\n address public stableMaster;\n\n // ============================= Constructor ===================================\n\n /// @notice Initializes the `AgToken` contract\n /// @param name_ Name of the token\n /// @param symbol_ Symbol of the token\n /// @param stableMaster_ Reference to the `StableMaster` contract associated to this agToken\n /// @dev By default, agTokens are ERC-20 tokens with 18 decimals\n function initialize(string memory name_, string memory symbol_, address stableMaster_) external initializer {\n __ERC20Permit_init(name_);\n __ERC20_init(name_, symbol_);\n require(stableMaster_ != address(0), \"0\");\n stableMaster = stableMaster_;\n }\n\n /// @custom:oz-upgrades-unsafe-allow constructor\n constructor() initializer {}\n\n // ======= Added Parameters and Variables from the first implementation ========\n\n /// @notice Checks whether an address has the right to mint agTokens\n mapping(address => bool) public isMinter;\n\n // =============================== Added Events ================================\n\n event MinterToggled(address indexed minter);\n\n // =============================== Setup Function ==============================\n\n /// @notice Sets up the minter role and gives it to the governor\n /// @dev This function just has to be called once\n function setUpMinter() external {\n address governor = 0xdC4e6DFe07EFCa50a197DF15D9200883eF4Eb1c8;\n require(msg.sender == governor);\n isMinter[governor] = true;\n emit MinterToggled(governor);\n }\n\n // =============================== Modifiers ===================================\n\n /// @notice Checks whether the sender has the minting right\n modifier onlyMinter() {\n require(isMinter[msg.sender] || msg.sender == stableMaster, \"35\");\n _;\n }\n\n // ========================= External Functions ================================\n // The following functions allow anyone to burn stablecoins without redeeming collateral\n // in exchange for that\n\n /// @notice Destroys `amount` token from the caller without giving collateral back\n /// @param amount Amount to burn\n /// @param poolManager Reference to the `PoolManager` contract for which the `stocksUsers` will\n /// need to be updated\n /// @dev When calling this function, people should specify the `poolManager` for which they want to decrease\n /// the `stocksUsers`: this is a way for the protocol to maintain healthy accounting variables\n function burnNoRedeem(uint256 amount, address poolManager) external {\n _burn(msg.sender, amount);\n IStableMaster(stableMaster).updateStocksUsers(amount, poolManager);\n }\n\n /// @notice Burns `amount` of agToken on behalf of another account without redeeming collateral back\n /// @param account Account to burn on behalf of\n /// @param amount Amount to burn\n /// @param poolManager Reference to the `PoolManager` contract for which the `stocksUsers` will need to be updated\n function burnFromNoRedeem(address account, uint256 amount, address poolManager) external {\n _burnFromNoRedeem(amount, account, msg.sender);\n IStableMaster(stableMaster).updateStocksUsers(amount, poolManager);\n }\n\n // ======================= Minter Role Only Functions ==========================\n\n /// @notice Burns `amount` tokens from a `burner` address\n /// @param amount Amount of tokens to burn\n /// @param burner Address to burn from\n /// @dev This method is to be called by a contract with a minter right on the AgToken after being\n /// requested to do so by an address willing to burn tokens from its address\n function burnSelf(uint256 amount, address burner) external onlyMinter {\n _burn(burner, amount);\n }\n\n /// @notice Burns `amount` tokens from a `burner` address after being asked to by `sender`\n /// @param amount Amount of tokens to burn\n /// @param burner Address to burn from\n /// @param sender Address which requested the burn from `burner`\n /// @dev This method is to be called by a contract with the minter right after being requested\n /// to do so by a `sender` address willing to burn tokens from another `burner` address\n /// @dev The method checks the allowance between the `sender` and the `burner`\n function burnFrom(uint256 amount, address burner, address sender) external onlyMinter {\n _burnFromNoRedeem(amount, burner, sender);\n }\n\n /// @notice Lets the `StableMaster` contract or another whitelisted contract mint agTokens\n /// @param account Address to mint to\n /// @param amount Amount to mint\n /// @dev The contracts allowed to issue agTokens are the `StableMaster` contract, `VaultManager` contracts\n /// associated to this stablecoin as well as the flash loan module (if activated) and potentially contracts\n /// whitelisted by governance\n function mint(address account, uint256 amount) external onlyMinter {\n _mint(account, amount);\n }\n\n // ======================= Minter Only Functions ===============================\n\n /// @notice Adds a minter in the contract\n /// @param minter Minter address to add\n function addMinter(address minter) external onlyMinter {\n isMinter[minter] = true;\n emit MinterToggled(minter);\n }\n\n /// @notice Removes a minter from the contract\n /// @param minter Minter address to remove\n /// @dev This function can at the moment only be called by a minter wishing to revoke itself\n function removeMinter(address minter) external {\n require(msg.sender == minter && isMinter[msg.sender], \"36\");\n isMinter[minter] = false;\n emit MinterToggled(minter);\n }\n\n // ============================ Internal Function ==============================\n\n /// @notice Internal version of the function `burnFromNoRedeem`\n /// @param amount Amount to burn\n /// @dev It is at the level of this function that allowance checks are performed\n function _burnFromNoRedeem(uint256 amount, address burner, address sender) internal {\n if (burner != sender) {\n uint256 currentAllowance = allowance(burner, sender);\n require(currentAllowance >= amount, \"23\");\n _approve(burner, sender, currentAllowance - amount);\n }\n _burn(burner, amount);\n }\n}\n" + }, + "contracts/deprecated/layerZero/OldLayerZeroBridgeToken.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.12;\n\nimport \"./OldOFTCore.sol\";\nimport \"../../interfaces/IAgTokenSideChainMultiBridge.sol\";\nimport \"@openzeppelin/contracts-upgradeable/security/PausableUpgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/token/ERC20/ERC20Upgradeable.sol\";\n\n/// @title LayerZeroBridgeToken\n/// @author Angle Labs, Inc., forked from https://github.com/LayerZero-Labs/solidity-examples/blob/main/contracts/token/oft/OFT.sol\n/// @notice Contract to be deployed on a L2/sidechain for bridging an AgToken using a bridge intermediate token and LayerZero\ncontract OldLayerZeroBridgeToken is OldOFTCore, ERC20Upgradeable, PausableUpgradeable {\n /// @notice Address of the bridgeable token\n /// @dev Immutable\n IAgTokenSideChainMultiBridge public canonicalToken;\n\n // =============================== Errors ================================\n\n error InvalidAllowance();\n\n // ============================= Constructor ===================================\n\n /// @notice Initializes the contract\n /// @param _name Name of the token corresponding to this contract\n /// @param _symbol Symbol of the token corresponding to this contract\n /// @param _lzEndpoint Layer zero endpoint to pass messages\n /// @param _treasury Address of the treasury contract used for access control\n /// @param initialSupply Initial supply to mint to the canonical token address\n /// @dev The initial supply corresponds to the initial amount that could be bridged using this OFT\n function initialize(\n string memory _name,\n string memory _symbol,\n address _lzEndpoint,\n address _treasury,\n uint256 initialSupply\n ) external initializer {\n __ERC20_init_unchained(_name, _symbol);\n __LzAppUpgradeable_init(_lzEndpoint, _treasury);\n\n canonicalToken = IAgTokenSideChainMultiBridge(address(ITreasury(_treasury).stablecoin()));\n _approve(address(this), address(canonicalToken), type(uint256).max);\n _mint(address(canonicalToken), initialSupply);\n }\n\n /// @custom:oz-upgrades-unsafe-allow constructor\n constructor() initializer {}\n\n // ==================== External Permissionless Functions ======================\n\n function sendWithPermit(\n uint16 _dstChainId,\n bytes memory _toAddress,\n uint256 _amount,\n address payable _refundAddress,\n address _zroPaymentAddress,\n bytes memory _adapterParams,\n uint256 deadline,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) public payable override {\n canonicalToken.permit(msg.sender, address(this), _amount, deadline, v, r, s);\n send(_dstChainId, _toAddress, _amount, _refundAddress, _zroPaymentAddress, _adapterParams);\n }\n\n function withdraw(uint256 amount, address recipient) external override returns (uint256 amountMinted) {\n // Does not check allowances as transfers from `msg.sender`\n _transfer(msg.sender, address(this), amount);\n amountMinted = canonicalToken.swapIn(address(this), amount, recipient);\n uint256 leftover = balanceOf(address(this));\n if (leftover != 0) {\n _transfer(address(this), msg.sender, leftover);\n }\n }\n\n // ============================= Internal Functions ===================================\n\n function _debitFrom(\n uint16,\n bytes memory,\n uint256 _amount\n ) internal override whenNotPaused returns (uint256 amountSwapped) {\n // No need to use safeTransferFrom as we know this implementation reverts on failure\n canonicalToken.transferFrom(msg.sender, address(this), _amount);\n\n // Swap canonical for this bridge token. There may be some fees\n amountSwapped = canonicalToken.swapOut(address(this), _amount, address(this));\n _burn(address(this), amountSwapped);\n }\n\n function _debitCreditFrom(uint16, bytes memory, uint256 _amount) internal override whenNotPaused returns (uint256) {\n _burn(msg.sender, _amount);\n return _amount;\n }\n\n function _creditTo(\n uint16,\n address _toAddress,\n uint256 _amount\n ) internal override whenNotPaused returns (uint256 amountMinted) {\n _mint(address(this), _amount);\n amountMinted = canonicalToken.swapIn(address(this), _amount, _toAddress);\n uint256 leftover = balanceOf(address(this));\n if (leftover != 0) {\n _transfer(address(this), _toAddress, leftover);\n }\n }\n\n // ======================= View Functions ================================\n\n /// @inheritdoc ERC165Upgradeable\n function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {\n return\n interfaceId == type(IOFT).interfaceId ||\n interfaceId == type(IERC20).interfaceId ||\n super.supportsInterface(interfaceId);\n }\n\n // ======================= Governance Functions ================================\n\n /// @notice Mints the intermediate contract to the `canonicalToken`\n /// @dev Used to increase the bridging capacity\n function mint(uint256 amount) external onlyGovernorOrGuardian {\n _mint(address(canonicalToken), amount);\n }\n\n /// @notice Burns the intermediate contract from the `canonicalToken`\n /// @dev Used to decrease the bridging capacity\n function burn(uint256 amount) external onlyGovernorOrGuardian {\n _burn(address(canonicalToken), amount);\n }\n\n /// @notice Increases allowance of the `canonicalToken`\n function setupAllowance() public onlyGovernorOrGuardian {\n _approve(address(this), address(canonicalToken), type(uint256).max);\n }\n\n /// @notice Pauses bridging through the contract\n /// @param pause Future pause status\n function pauseSendTokens(bool pause) external onlyGovernorOrGuardian {\n pause ? _pause() : _unpause();\n }\n\n uint256[49] private __gap;\n}\n" + }, + "contracts/deprecated/layerZero/OldNonblockingLzApp.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.12;\n\nimport \"@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol\";\nimport \"../../interfaces/external/layerZero/ILayerZeroReceiver.sol\";\nimport \"../../interfaces/external/layerZero/ILayerZeroUserApplicationConfig.sol\";\nimport \"../../interfaces/external/layerZero/ILayerZeroEndpoint.sol\";\nimport \"../../interfaces/ITreasury.sol\";\n\n/// @title OldNonblockingLzApp\n/// @author Angle Labs, Inc., forked from https://github.com/LayerZero-Labs/solidity-examples/\n/// @notice Base contract for bridging using LayerZero\nabstract contract OldNonblockingLzApp is Initializable, ILayerZeroReceiver, ILayerZeroUserApplicationConfig {\n /// @notice Layer Zero endpoint\n ILayerZeroEndpoint public lzEndpoint;\n\n /// @notice Maps chainIds to failed messages to retry them\n mapping(uint16 => mapping(bytes => mapping(uint64 => bytes32))) public failedMessages;\n\n /// @notice Maps chainIds to their OFT address\n mapping(uint16 => bytes) public trustedRemoteLookup;\n\n /// @notice Reference to the treasury contract to fetch access control\n address public treasury;\n\n // ================================== Events ===================================\n\n event SetTrustedRemote(uint16 _srcChainId, bytes _srcAddress);\n event MessageFailed(uint16 _srcChainId, bytes _srcAddress, uint64 _nonce, bytes _payload);\n\n // =============================== Errors ================================\n\n error NotGovernor();\n error NotGovernorOrGuardian();\n error InsufficientGas();\n error InvalidEndpoint();\n error InvalidSource();\n error InvalidCaller();\n error InvalidParams();\n error InvalidPayload();\n error ZeroAddress();\n\n // ============================= Constructor ===================================\n\n //solhint-disable-next-line\n function __LzAppUpgradeable_init(address _endpoint, address _treasury) internal {\n if (_endpoint == address(0) || _treasury == address(0)) revert ZeroAddress();\n lzEndpoint = ILayerZeroEndpoint(_endpoint);\n treasury = _treasury;\n }\n\n // =============================== Modifiers ===================================\n\n /// @notice Checks whether the `msg.sender` has the governor role or the guardian role\n modifier onlyGovernorOrGuardian() {\n if (!ITreasury(treasury).isGovernorOrGuardian(msg.sender)) revert NotGovernorOrGuardian();\n _;\n }\n\n // ==================== External Permissionless Functions ======================\n\n /// @notice Receives a message from the LZ endpoint and process it\n /// @param _srcChainId ChainId of the source chain - LayerZero standard\n /// @param _srcAddress Sender of the source chain\n /// @param _nonce Nounce of the message\n /// @param _payload Data: recipient address and amount\n function lzReceive(\n uint16 _srcChainId,\n bytes memory _srcAddress,\n uint64 _nonce,\n bytes memory _payload\n ) public virtual override {\n // lzReceive must be called by the endpoint for security\n if (msg.sender != address(lzEndpoint)) revert InvalidEndpoint();\n\n bytes memory trustedRemote = trustedRemoteLookup[_srcChainId];\n // if will still block the message pathway from (srcChainId, srcAddress). should not receive message from untrusted remote.\n if (_srcAddress.length != trustedRemote.length || keccak256(_srcAddress) != keccak256(trustedRemote))\n revert InvalidSource();\n\n _blockingLzReceive(_srcChainId, _srcAddress, _nonce, _payload);\n }\n\n /// @notice Retries a message that previously failed and was stored\n /// @param _srcChainId ChainId of the source chain - LayerZero standard\n /// @param _srcAddress Sender of the source chain\n /// @param _nonce Nounce of the message\n /// @param _payload Data: recipient address and amount\n function retryMessage(\n uint16 _srcChainId,\n bytes memory _srcAddress,\n uint64 _nonce,\n bytes memory _payload\n ) public payable virtual {\n // assert there is message to retry\n bytes32 payloadHash = failedMessages[_srcChainId][_srcAddress][_nonce];\n if (payloadHash == bytes32(0) || keccak256(_payload) != payloadHash) revert InvalidPayload();\n // clear the stored message\n failedMessages[_srcChainId][_srcAddress][_nonce] = bytes32(0);\n // execute the message. revert if it fails again\n _nonblockingLzReceive(_srcChainId, _srcAddress, _nonce, _payload);\n }\n\n // ============================= Internal Functions ===================================\n\n /// @notice Handles message receptions in a non blocking way\n /// @param _srcChainId ChainId of the source chain - LayerZero standard\n /// @param _srcAddress Sender of the source chain\n /// @param _nonce Nounce of the message\n /// @param _payload Data: recipient address and amount\n /// @dev public for the needs of try / catch but effectively internal\n function nonblockingLzReceive(\n uint16 _srcChainId,\n bytes memory _srcAddress,\n uint64 _nonce,\n bytes memory _payload\n ) public virtual {\n // only internal transaction\n if (msg.sender != address(this)) revert InvalidCaller();\n _nonblockingLzReceive(_srcChainId, _srcAddress, _nonce, _payload);\n }\n\n /// @notice Handles message receptions in a non blocking way\n /// @param _srcChainId ChainId of the source chain - LayerZero standard\n /// @param _srcAddress Sender of the source chain\n /// @param _nonce Nounce of the message\n /// @param _payload Data: recipient address and amount\n function _nonblockingLzReceive(\n uint16 _srcChainId,\n bytes memory _srcAddress,\n uint64 _nonce,\n bytes memory _payload\n ) internal virtual;\n\n /// @notice Handles message receptions in a blocking way\n /// @param _srcChainId ChainId of the source chain - LayerZero standard\n /// @param _srcAddress Sender of the source chain\n /// @param _nonce Nounce of the message\n /// @param _payload Data: recipient address and amount\n function _blockingLzReceive(\n uint16 _srcChainId,\n bytes memory _srcAddress,\n uint64 _nonce,\n bytes memory _payload\n ) internal {\n // try-catch all errors/exceptions\n try this.nonblockingLzReceive(_srcChainId, _srcAddress, _nonce, _payload) {\n // do nothing\n } catch {\n // error / exception\n failedMessages[_srcChainId][_srcAddress][_nonce] = keccak256(_payload);\n emit MessageFailed(_srcChainId, _srcAddress, _nonce, _payload);\n }\n }\n\n /// @notice Sends a message to the LZ endpoint and process it\n /// @param _dstChainId L0 defined chain id to send tokens too\n /// @param _payload Data: recipient address and amount\n /// @param _refundAddress Address LayerZero refunds if too much message fee is sent\n /// @param _zroPaymentAddress Set to address(0x0) if not paying in ZRO (LayerZero Token)\n /// @param _adapterParams Flexible bytes array to indicate messaging adapter services in L0\n function _lzSend(\n uint16 _dstChainId,\n bytes memory _payload,\n address payable _refundAddress,\n address _zroPaymentAddress,\n bytes memory _adapterParams\n ) internal virtual {\n bytes memory trustedRemote = trustedRemoteLookup[_dstChainId];\n if (trustedRemote.length == 0) revert InvalidSource();\n //solhint-disable-next-line\n lzEndpoint.send{ value: msg.value }(\n _dstChainId,\n trustedRemote,\n _payload,\n _refundAddress,\n _zroPaymentAddress,\n _adapterParams\n );\n }\n\n // ======================= Governance Functions ================================\n\n /// @notice Sets the corresponding address on an other chain.\n /// @param _srcChainId ChainId of the source chain - LayerZero standard\n /// @param _srcAddress Address on the source chain\n /// @dev Used for both receiving and sending message\n /// @dev There can only be one trusted source per chain\n /// @dev Allows owner to set it multiple times.\n function setTrustedRemote(uint16 _srcChainId, bytes calldata _srcAddress) external onlyGovernorOrGuardian {\n trustedRemoteLookup[_srcChainId] = _srcAddress;\n emit SetTrustedRemote(_srcChainId, _srcAddress);\n }\n\n /// @notice Fetches the default LZ config\n function getConfig(\n uint16 _version,\n uint16 _chainId,\n address,\n uint256 _configType\n ) external view returns (bytes memory) {\n return lzEndpoint.getConfig(_version, _chainId, address(this), _configType);\n }\n\n /// @notice Overrides the default LZ config\n function setConfig(\n uint16 _version,\n uint16 _chainId,\n uint256 _configType,\n bytes calldata _config\n ) external override onlyGovernorOrGuardian {\n lzEndpoint.setConfig(_version, _chainId, _configType, _config);\n }\n\n /// @notice Overrides the default LZ config\n function setSendVersion(uint16 _version) external override onlyGovernorOrGuardian {\n lzEndpoint.setSendVersion(_version);\n }\n\n /// @notice Overrides the default LZ config\n function setReceiveVersion(uint16 _version) external override onlyGovernorOrGuardian {\n lzEndpoint.setReceiveVersion(_version);\n }\n\n /// @notice Unpauses the receive functionalities\n function forceResumeReceive(\n uint16 _srcChainId,\n bytes calldata _srcAddress\n ) external override onlyGovernorOrGuardian {\n lzEndpoint.forceResumeReceive(_srcChainId, _srcAddress);\n }\n\n // ======================= View Functions ================================\n\n /// @notice Checks if the `_srcAddress` corresponds to the trusted source\n function isTrustedRemote(uint16 _srcChainId, bytes calldata _srcAddress) external view returns (bool) {\n bytes memory trustedSource = trustedRemoteLookup[_srcChainId];\n return keccak256(trustedSource) == keccak256(_srcAddress);\n }\n\n uint256[46] private __gap;\n}\n" + }, + "contracts/deprecated/layerZero/OldOFTCore.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.12;\n\nimport \"./OldNonblockingLzApp.sol\";\nimport \"../../agToken/layerZero/utils/IOFTCore.sol\";\nimport \"@openzeppelin/contracts-upgradeable/utils/introspection/ERC165Upgradeable.sol\";\n\n/// @title OFTCore\n/// @author Forked from https://github.com/LayerZero-Labs/solidity-examples/blob/main/contracts/token/oft/OFTCore.sol\n/// but with slight modifications from the Angle Labs, Inc. which added return values to the `_creditTo` and `_debitFrom` functions\n/// @notice Base contract for bridging using LayerZero\nabstract contract OldOFTCore is OldNonblockingLzApp, ERC165Upgradeable, IOFTCore {\n // ==================== External Permissionless Functions ======================\n\n /// @inheritdoc IOFTCore\n function sendWithPermit(\n uint16 _dstChainId,\n bytes memory _toAddress,\n uint256 _amount,\n address payable _refundAddress,\n address _zroPaymentAddress,\n bytes memory _adapterParams,\n uint256 deadline,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) public payable virtual;\n\n /// @inheritdoc IOFTCore\n function send(\n uint16 _dstChainId,\n bytes memory _toAddress,\n uint256 _amount,\n address payable _refundAddress,\n address _zroPaymentAddress,\n bytes memory _adapterParams\n ) public payable virtual {\n _amount = _debitFrom(_dstChainId, _toAddress, _amount);\n\n bytes memory payload = abi.encode(_toAddress, _amount);\n _lzSend(_dstChainId, payload, _refundAddress, _zroPaymentAddress, _adapterParams);\n\n uint64 nonce = lzEndpoint.getOutboundNonce(_dstChainId, address(this));\n emit SendToChain(msg.sender, _dstChainId, _toAddress, _amount, nonce);\n }\n\n /// @inheritdoc IOFTCore\n function sendCredit(\n uint16 _dstChainId,\n bytes memory _toAddress,\n uint256 _amount,\n address payable _refundAddress,\n address _zroPaymentAddress,\n bytes memory _adapterParams\n ) public payable virtual {\n _amount = _debitCreditFrom(_dstChainId, _toAddress, _amount);\n\n _send(_dstChainId, _toAddress, _amount, _refundAddress, _zroPaymentAddress, _adapterParams);\n }\n\n /// @inheritdoc IOFTCore\n function withdraw(uint256 amount, address recipient) external virtual returns (uint256);\n\n // =========================== Internal Functions ==============================\n\n /// @notice Internal function to send `_amount` amount of token to (`_dstChainId`, `_toAddress`)\n /// @param _dstChainId the destination chain identifier\n /// @param _toAddress can be any size depending on the `dstChainId`.\n /// @param _amount the quantity of tokens in wei\n /// @param _refundAddress the address LayerZero refunds if too much message fee is sent\n /// @param _zroPaymentAddress set to address(0x0) if not paying in ZRO (LayerZero Token)\n /// @param _adapterParams is a flexible bytes array to indicate messaging adapter services\n /// @dev Accounting and checks should be performed beforehand\n function _send(\n uint16 _dstChainId,\n bytes memory _toAddress,\n uint256 _amount,\n address payable _refundAddress,\n address _zroPaymentAddress,\n bytes memory _adapterParams\n ) internal {\n bytes memory payload = abi.encode(_toAddress, _amount);\n _lzSend(_dstChainId, payload, _refundAddress, _zroPaymentAddress, _adapterParams);\n\n uint64 nonce = lzEndpoint.getOutboundNonce(_dstChainId, address(this));\n emit SendToChain(msg.sender, _dstChainId, _toAddress, _amount, nonce);\n }\n\n function _nonblockingLzReceive(\n uint16 _srcChainId,\n bytes memory _srcAddress,\n uint64 _nonce,\n bytes memory _payload\n ) internal virtual override {\n // decode and load the toAddress\n (bytes memory toAddressBytes, uint256 amount) = abi.decode(_payload, (bytes, uint256));\n address toAddress;\n //solhint-disable-next-line\n assembly {\n toAddress := mload(add(toAddressBytes, 20))\n }\n amount = _creditTo(_srcChainId, toAddress, amount);\n\n emit ReceiveFromChain(_srcChainId, _srcAddress, toAddress, amount, _nonce);\n }\n\n /// @notice Makes accountability when bridging from this contract using canonical token\n /// @param _dstChainId ChainId of the destination chain - LayerZero standard\n /// @param _toAddress Recipient on the destination chain\n /// @param _amount Amount to bridge\n function _debitFrom(\n uint16 _dstChainId,\n bytes memory _toAddress,\n uint256 _amount\n ) internal virtual returns (uint256);\n\n /// @notice Makes accountability when bridging from this contract's credit\n /// @param _dstChainId ChainId of the destination chain - LayerZero standard\n /// @param _toAddress Recipient on the destination chain\n /// @param _amount Amount to bridge\n function _debitCreditFrom(\n uint16 _dstChainId,\n bytes memory _toAddress,\n uint256 _amount\n ) internal virtual returns (uint256);\n\n /// @notice Makes accountability when bridging to this contract\n /// @param _srcChainId ChainId of the source chain - LayerZero standard\n /// @param _toAddress Recipient on this chain\n /// @param _amount Amount to bridge\n function _creditTo(uint16 _srcChainId, address _toAddress, uint256 _amount) internal virtual returns (uint256);\n\n // ========================== View Functions ===================================\n\n /// @inheritdoc ERC165Upgradeable\n function supportsInterface(\n bytes4 interfaceId\n ) public view virtual override(ERC165Upgradeable, IERC165) returns (bool) {\n return interfaceId == type(IOFTCore).interfaceId || super.supportsInterface(interfaceId);\n }\n\n /// @inheritdoc IOFTCore\n function estimateSendFee(\n uint16 _dstChainId,\n bytes memory _toAddress,\n uint256 _amount,\n bool _useZro,\n bytes memory _adapterParams\n ) public view virtual override returns (uint256 nativeFee, uint256 zroFee) {\n // mock the payload for send()\n bytes memory payload = abi.encode(_toAddress, _amount);\n return lzEndpoint.estimateFees(_dstChainId, address(this), payload, _useZro, _adapterParams);\n }\n\n uint256[50] private __gap;\n}\n" + }, + "contracts/deprecated/OldAgEUR.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\nimport \"../interfaces/IAgToken.sol\";\nimport \"../interfaces/coreModule/IStableMaster.sol\";\nimport \"../interfaces/ITreasury.sol\";\n// OpenZeppelin may update its version of the ERC20PermitUpgradeable token\nimport \"@openzeppelin/contracts-upgradeable/token/ERC20/extensions/draft-ERC20PermitUpgradeable.sol\";\n\n/// @title AgToken\n/// @author Angle Labs, Inc.\n/// @notice Base contract for agToken, that is to say Angle's stablecoins\n/// @dev This contract is used to create and handle the stablecoins of Angle protocol\n/// @dev It is still possible for any address to burn its agTokens without redeeming collateral in exchange\n/// @dev This contract is the upgraded version of the AgToken that was first deployed on Ethereum mainnet\ncontract OldAgEUR is IAgToken, ERC20PermitUpgradeable {\n // ========================= References to other contracts =====================\n\n /// @notice Reference to the `StableMaster` contract associated to this `AgToken`\n address public stableMaster;\n\n // ============================= Constructor ===================================\n\n /// @notice Initializes the `AgToken` contract\n /// @param name_ Name of the token\n /// @param symbol_ Symbol of the token\n /// @param stableMaster_ Reference to the `StableMaster` contract associated to this agToken\n /// @dev By default, agTokens are ERC-20 tokens with 18 decimals\n function initialize(string memory name_, string memory symbol_, address stableMaster_) external initializer {\n __ERC20Permit_init(name_);\n __ERC20_init(name_, symbol_);\n require(stableMaster_ != address(0), \"0\");\n stableMaster = stableMaster_;\n }\n\n /// @custom:oz-upgrades-unsafe-allow constructor\n constructor() initializer {}\n\n // ======= Added Parameters and Variables from the first implementation ========\n\n /// @inheritdoc IAgToken\n mapping(address => bool) public isMinter;\n /// @notice Reference to the treasury contract which can grant minting rights\n address public treasury;\n /// @notice Boolean to check whether the contract has been reinitialized after its upgrade\n bool public treasuryInitialized;\n\n // =============================== Added Events ================================\n\n event TreasuryUpdated(address indexed _treasury);\n event MinterToggled(address indexed minter);\n\n // =============================== Added Errors ================================\n\n error BurnAmountExceedsAllowance();\n error InvalidSender();\n error InvalidTreasury();\n error NotGovernor();\n error NotMinter();\n error NotTreasury();\n error TreasuryAlreadyInitialized();\n\n // =============================== Setup Function ==============================\n\n /// @notice Sets up the treasury contract in this AgToken contract\n /// @param _treasury Treasury contract to add\n /// @dev The address calling this function has to be hard-coded in the contract\n /// @dev Can be called only once\n function setUpTreasury(address _treasury) external {\n // Only governor\n if (msg.sender != 0xdC4e6DFe07EFCa50a197DF15D9200883eF4Eb1c8) revert NotGovernor();\n if (address(ITreasury(_treasury).stablecoin()) != address(this)) revert InvalidTreasury();\n if (treasuryInitialized) revert TreasuryAlreadyInitialized();\n treasury = _treasury;\n treasuryInitialized = true;\n isMinter[stableMaster] = true;\n emit TreasuryUpdated(_treasury);\n }\n\n // =============================== Modifiers ===================================\n\n /// @notice Checks to see if it is the `Treasury` calling this contract\n /// @dev There is no Access Control here, because it can be handled cheaply through this modifier\n modifier onlyTreasury() {\n if (msg.sender != treasury) revert NotTreasury();\n _;\n }\n\n /// @notice Checks whether the sender has the minting right\n modifier onlyMinter() {\n if (!isMinter[msg.sender]) revert NotMinter();\n _;\n }\n\n // ========================= External Functions ================================\n // The following functions allow anyone to burn stablecoins without redeeming collateral\n // in exchange for that\n\n /// @notice Destroys `amount` token from the caller without giving collateral back\n /// @param amount Amount to burn\n /// @param poolManager Reference to the `PoolManager` contract for which the `stocksUsers` will\n /// need to be updated\n /// @dev When calling this function, people should specify the `poolManager` for which they want to decrease\n /// the `stocksUsers`: this is a way for the protocol to maintain healthy accounting variables\n function burnNoRedeem(uint256 amount, address poolManager) external {\n _burn(msg.sender, amount);\n IStableMaster(stableMaster).updateStocksUsers(amount, poolManager);\n }\n\n /// @notice Burns `amount` of agToken on behalf of another account without redeeming collateral back\n /// @param account Account to burn on behalf of\n /// @param amount Amount to burn\n /// @param poolManager Reference to the `PoolManager` contract for which the `stocksUsers` will need to be updated\n function burnFromNoRedeem(address account, uint256 amount, address poolManager) external {\n _burnFromNoRedeem(amount, account, msg.sender);\n IStableMaster(stableMaster).updateStocksUsers(amount, poolManager);\n }\n\n /// @notice Allows anyone to burn agToken without redeeming collateral back\n /// @param amount Amount of stablecoins to burn\n /// @dev This function can typically be called if there is a settlement mechanism to burn stablecoins\n function burnStablecoin(uint256 amount) external {\n _burn(msg.sender, amount);\n }\n\n // ======================= Minter Role Only Functions ==========================\n\n /// @inheritdoc IAgToken\n function burnSelf(uint256 amount, address burner) external onlyMinter {\n _burn(burner, amount);\n }\n\n /// @inheritdoc IAgToken\n function burnFrom(uint256 amount, address burner, address sender) external onlyMinter {\n _burnFromNoRedeem(amount, burner, sender);\n }\n\n /// @inheritdoc IAgToken\n function mint(address account, uint256 amount) external onlyMinter {\n _mint(account, amount);\n }\n\n // ======================= Treasury Only Functions =============================\n\n /// @inheritdoc IAgToken\n function addMinter(address minter) external onlyTreasury {\n isMinter[minter] = true;\n emit MinterToggled(minter);\n }\n\n /// @inheritdoc IAgToken\n function removeMinter(address minter) external {\n // The `treasury` contract cannot remove the `stableMaster`\n if (msg.sender != minter && (msg.sender != address(treasury) || minter == stableMaster)) revert InvalidSender();\n isMinter[minter] = false;\n emit MinterToggled(minter);\n }\n\n /// @inheritdoc IAgToken\n function setTreasury(address _treasury) external onlyTreasury {\n treasury = _treasury;\n emit TreasuryUpdated(_treasury);\n }\n\n // ============================ Internal Function ==============================\n\n /// @notice Internal version of the function `burnFromNoRedeem`\n /// @param amount Amount to burn\n /// @dev It is at the level of this function that allowance checks are performed\n function _burnFromNoRedeem(uint256 amount, address burner, address sender) internal {\n if (burner != sender) {\n uint256 currentAllowance = allowance(burner, sender);\n if (currentAllowance < amount) revert BurnAmountExceedsAllowance();\n _approve(burner, sender, currentAllowance - amount);\n }\n _burn(burner, amount);\n }\n}\n" + }, + "contracts/deprecated/OldAngleHelpers.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\nimport \"../interfaces/IAngleRouter.sol\";\nimport \"../interfaces/coreModule/IAgTokenMainnet.sol\";\nimport \"../interfaces/coreModule/ICore.sol\";\nimport \"../interfaces/coreModule/IOracleCore.sol\";\nimport \"../interfaces/coreModule/IPerpetualManager.sol\";\nimport \"../interfaces/coreModule/IPoolManager.sol\";\nimport \"../interfaces/coreModule/IStableMaster.sol\";\nimport \"@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol\";\nimport \"../interfaces/IVaultManager.sol\";\n\npragma solidity ^0.8.12;\n\nstruct Parameters {\n SLPData slpData;\n MintBurnData feeData;\n PerpetualManagerFeeData perpFeeData;\n PerpetualManagerParamData perpParam;\n}\n\nstruct PerpetualManagerFeeData {\n uint64[] xHAFeesDeposit;\n uint64[] yHAFeesDeposit;\n uint64[] xHAFeesWithdraw;\n uint64[] yHAFeesWithdraw;\n uint64 haBonusMalusDeposit;\n uint64 haBonusMalusWithdraw;\n}\n\nstruct PerpetualManagerParamData {\n uint64 maintenanceMargin;\n uint64 maxLeverage;\n uint64 targetHAHedge;\n uint64 limitHAHedge;\n uint64 lockTime;\n}\n\nstruct CollateralAddresses {\n address stableMaster;\n address poolManager;\n address perpetualManager;\n address sanToken;\n address oracle;\n address gauge;\n address feeManager;\n address[] strategies;\n}\n\n/// @title AngleHelpers\n/// @author Angle Labs, Inc.\n/// @notice Contract with view functions designed to facilitate integrations on the Core module of the Angle Protocol\n/// @dev This contract only contains view functions to be queried off-chain. It was thus not optimized for gas consumption\ncontract OldAngleHelpers is Initializable {\n // ======================== Helper View Functions ==============================\n\n /// @notice Gives the amount of `agToken` you'd be getting if you were executing in the same block a mint transaction\n /// with `amount` of `collateral` in the Core module of the Angle protocol as well as the value of the fees\n /// (in `BASE_PARAMS`) that would be applied during the mint\n /// @return Amount of `agToken` that would be obtained with a mint transaction in the same block\n /// @return Percentage of fees that would be taken during a mint transaction in the same block\n /// @dev This function reverts if the mint transaction was to revert in the same conditions (without taking into account\n /// potential approval problems to the `StableMaster` contract)\n function previewMintAndFees(\n uint256 amount,\n address agToken,\n address collateral\n ) external view returns (uint256, uint256) {\n return _previewMintAndFees(amount, agToken, collateral);\n }\n\n /// @notice Gives the amount of `collateral` you'd be getting if you were executing in the same block a burn transaction\n /// with `amount` of `agToken` in the Core module of the Angle protocol as well as the value of the fees\n /// (in `BASE_PARAMS`) that would be applied during the burn\n /// @return Amount of `collateral` that would be obtained with a burn transaction in the same block\n /// @return Percentage of fees that would be taken during a burn transaction in the same block\n /// @dev This function reverts if the burn transaction was to revert in the same conditions (without taking into account\n /// potential approval problems to the `StableMaster` contract or agToken balance prior to the call)\n function previewBurnAndFees(\n uint256 amount,\n address agToken,\n address collateral\n ) external view returns (uint256, uint256) {\n return _previewBurnAndFees(amount, agToken, collateral);\n }\n\n /// @notice Returns all the addresses associated to the (`agToken`,`collateral`) pair given\n /// @return addresses A struct with all the addresses associated in the Core module\n function getCollateralAddresses(\n address agToken,\n address collateral\n ) external view returns (CollateralAddresses memory addresses) {\n address stableMaster = IAgTokenMainnet(agToken).stableMaster();\n (address poolManager, address perpetualManager, address sanToken, address gauge) = ROUTER.mapPoolManagers(\n stableMaster,\n collateral\n );\n (, , , IOracleCore oracle, , , , , ) = IStableMaster(stableMaster).collateralMap(poolManager);\n addresses.stableMaster = stableMaster;\n addresses.poolManager = poolManager;\n addresses.perpetualManager = perpetualManager;\n addresses.sanToken = sanToken;\n addresses.gauge = gauge;\n addresses.oracle = address(oracle);\n addresses.feeManager = IPoolManager(poolManager).feeManager();\n\n uint256 length = 0;\n while (true) {\n try IPoolManager(poolManager).strategyList(length) returns (address) {\n length += 1;\n } catch {\n break;\n }\n }\n address[] memory strategies = new address[](length);\n for (uint256 i; i < length; ++i) {\n strategies[i] = IPoolManager(poolManager).strategyList(i);\n }\n addresses.strategies = strategies;\n }\n\n /// @notice Gets the addresses of all the `StableMaster` contracts and their associated `AgToken` addresses\n /// @return List of the `StableMaster` addresses of the Angle protocol\n /// @return List of the `AgToken` addresses of the protocol\n /// @dev The place of an agToken address in the list is the same as the corresponding `StableMaster` address\n function getStablecoinAddresses() external view returns (address[] memory, address[] memory) {\n address[] memory stableMasterAddresses = CORE.stablecoinList();\n address[] memory agTokenAddresses = new address[](stableMasterAddresses.length);\n for (uint256 i; i < stableMasterAddresses.length; ++i) {\n agTokenAddresses[i] = IStableMaster(stableMasterAddresses[i]).agToken();\n }\n return (stableMasterAddresses, agTokenAddresses);\n }\n\n /// @notice Returns most of the governance parameters associated to the (`agToken`,`collateral`) pair given\n /// @return params Struct with most of the parameters in the `StableMaster` and `PerpetualManager` contracts\n /// @dev Check out the struct `Parameters` for the meaning of the return values\n function getCollateralParameters(\n address agToken,\n address collateral\n ) external view returns (Parameters memory params) {\n (address stableMaster, address poolManager) = _getStableMasterAndPoolManager(agToken, collateral);\n (\n ,\n ,\n IPerpetualManager perpetualManager,\n ,\n ,\n ,\n ,\n SLPData memory slpData,\n MintBurnData memory feeData\n ) = IStableMaster(stableMaster).collateralMap(poolManager);\n\n params.slpData = slpData;\n params.feeData = feeData;\n params.perpParam.maintenanceMargin = perpetualManager.maintenanceMargin();\n params.perpParam.maxLeverage = perpetualManager.maxLeverage();\n params.perpParam.targetHAHedge = perpetualManager.targetHAHedge();\n params.perpParam.limitHAHedge = perpetualManager.limitHAHedge();\n params.perpParam.lockTime = perpetualManager.lockTime();\n\n params.perpFeeData.haBonusMalusDeposit = perpetualManager.haBonusMalusDeposit();\n params.perpFeeData.haBonusMalusWithdraw = perpetualManager.haBonusMalusWithdraw();\n\n uint256 length = 0;\n while (true) {\n try perpetualManager.xHAFeesDeposit(length) returns (uint64) {\n length += 1;\n } catch {\n break;\n }\n }\n uint64[] memory data = new uint64[](length);\n uint64[] memory data2 = new uint64[](length);\n for (uint256 i; i < length; ++i) {\n data[i] = perpetualManager.xHAFeesDeposit(i);\n data2[i] = perpetualManager.yHAFeesDeposit(i);\n }\n params.perpFeeData.xHAFeesDeposit = data;\n params.perpFeeData.yHAFeesDeposit = data2;\n\n length = 0;\n while (true) {\n try perpetualManager.xHAFeesWithdraw(length) returns (uint64) {\n length += 1;\n } catch {\n break;\n }\n }\n data = new uint64[](length);\n data2 = new uint64[](length);\n for (uint256 i; i < length; ++i) {\n data[i] = perpetualManager.xHAFeesWithdraw(i);\n data2[i] = perpetualManager.yHAFeesWithdraw(i);\n }\n params.perpFeeData.xHAFeesWithdraw = data;\n params.perpFeeData.yHAFeesWithdraw = data2;\n }\n\n /// @notice Returns the address of the poolManager associated to an (`agToken`, `collateral`) pair\n /// in the Core module of the protocol\n function getPoolManager(address agToken, address collateral) public view returns (address poolManager) {\n (, poolManager) = _getStableMasterAndPoolManager(agToken, collateral);\n }\n\n // ======================== Replica Functions ==================================\n // These replicate what is done in the other contracts of the protocol\n\n function _previewBurnAndFees(\n uint256 amount,\n address agToken,\n address collateral\n ) internal view returns (uint256 amountForUserInCollat, uint256 feePercent) {\n (address stableMaster, address poolManager) = _getStableMasterAndPoolManager(agToken, collateral);\n (\n address token,\n ,\n IPerpetualManager perpetualManager,\n IOracleCore oracle,\n uint256 stocksUsers,\n ,\n uint256 collatBase,\n ,\n MintBurnData memory feeData\n ) = IStableMaster(stableMaster).collateralMap(poolManager);\n if (token == address(0) || IStableMaster(stableMaster).paused(keccak256(abi.encodePacked(STABLE, poolManager))))\n revert NotInitialized();\n if (amount > stocksUsers) revert InvalidAmount();\n\n if (feeData.xFeeBurn.length == 1) {\n feePercent = feeData.yFeeBurn[0];\n } else {\n bytes memory data = abi.encode(address(perpetualManager), feeData.targetHAHedge);\n uint64 hedgeRatio = _computeHedgeRatio(stocksUsers - amount, data);\n feePercent = _piecewiseLinear(hedgeRatio, feeData.xFeeBurn, feeData.yFeeBurn);\n }\n feePercent = (feePercent * feeData.bonusMalusBurn) / BASE_PARAMS;\n\n amountForUserInCollat = (amount * (BASE_PARAMS - feePercent) * collatBase) / (oracle.readUpper() * BASE_PARAMS);\n }\n\n function _previewMintAndFees(\n uint256 amount,\n address agToken,\n address collateral\n ) internal view returns (uint256 amountForUserInStable, uint256 feePercent) {\n (address stableMaster, address poolManager) = _getStableMasterAndPoolManager(agToken, collateral);\n (\n address token,\n ,\n IPerpetualManager perpetualManager,\n IOracleCore oracle,\n uint256 stocksUsers,\n ,\n ,\n ,\n MintBurnData memory feeData\n ) = IStableMaster(stableMaster).collateralMap(poolManager);\n if (token == address(0) || IStableMaster(stableMaster).paused(keccak256(abi.encodePacked(STABLE, poolManager))))\n revert NotInitialized();\n\n amountForUserInStable = oracle.readQuoteLower(amount);\n\n if (feeData.xFeeMint.length == 1) feePercent = feeData.yFeeMint[0];\n else {\n bytes memory data = abi.encode(address(perpetualManager), feeData.targetHAHedge);\n uint64 hedgeRatio = _computeHedgeRatio(amountForUserInStable + stocksUsers, data);\n feePercent = _piecewiseLinear(hedgeRatio, feeData.xFeeMint, feeData.yFeeMint);\n }\n feePercent = (feePercent * feeData.bonusMalusMint) / BASE_PARAMS;\n\n amountForUserInStable = (amountForUserInStable * (BASE_PARAMS - feePercent)) / BASE_PARAMS;\n if (stocksUsers + amountForUserInStable > feeData.capOnStableMinted) revert InvalidAmount();\n }\n\n // ======================== Utility Functions ==================================\n // These utility functions are taken from other contracts of the protocol\n\n function _computeHedgeRatio(uint256 newStocksUsers, bytes memory data) internal view returns (uint64 ratio) {\n (address perpetualManager, uint64 targetHAHedge) = abi.decode(data, (address, uint64));\n uint256 totalHedgeAmount = IPerpetualManager(perpetualManager).totalHedgeAmount();\n newStocksUsers = (targetHAHedge * newStocksUsers) / BASE_PARAMS;\n if (newStocksUsers > totalHedgeAmount) ratio = uint64((totalHedgeAmount * BASE_PARAMS) / newStocksUsers);\n else ratio = uint64(BASE_PARAMS);\n }\n\n function _piecewiseLinear(uint64 x, uint64[] memory xArray, uint64[] memory yArray) internal pure returns (uint64) {\n if (x >= xArray[xArray.length - 1]) {\n return yArray[xArray.length - 1];\n } else if (x <= xArray[0]) {\n return yArray[0];\n } else {\n uint256 lower;\n uint256 upper = xArray.length - 1;\n uint256 mid;\n while (upper - lower > 1) {\n mid = lower + (upper - lower) / 2;\n if (xArray[mid] <= x) {\n lower = mid;\n } else {\n upper = mid;\n }\n }\n if (yArray[upper] > yArray[lower]) {\n return\n yArray[lower] +\n ((yArray[upper] - yArray[lower]) * (x - xArray[lower])) /\n (xArray[upper] - xArray[lower]);\n } else {\n return\n yArray[lower] -\n ((yArray[lower] - yArray[upper]) * (x - xArray[lower])) /\n (xArray[upper] - xArray[lower]);\n }\n }\n }\n\n function _getStableMasterAndPoolManager(\n address agToken,\n address collateral\n ) internal view returns (address stableMaster, address poolManager) {\n stableMaster = IAgTokenMainnet(agToken).stableMaster();\n (poolManager, , , ) = ROUTER.mapPoolManagers(stableMaster, collateral);\n }\n\n // ====================== Constants and Initializers ===========================\n\n IAngleRouter public constant ROUTER = IAngleRouter(0xBB755240596530be0c1DE5DFD77ec6398471561d);\n ICore public constant CORE = ICore(0x61ed74de9Ca5796cF2F8fD60D54160D47E30B7c3);\n\n bytes32 public constant STABLE = keccak256(\"STABLE\");\n uint256 public constant BASE_PARAMS = 10 ** 9;\n\n error NotInitialized();\n error InvalidAmount();\n\n /// @custom:oz-upgrades-unsafe-allow constructor\n constructor() initializer {}\n}\n" + }, + "contracts/deprecated/vaultManager/OldVaultManagerERC721.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\nimport \"./OldVaultManagerStorage.sol\";\n\n/// @title VaultManagerERC721\n/// @author Angle Labs, Inc.\n/// @dev Base ERC721 Implementation of VaultManager\nabstract contract OldVaultManagerERC721 is IERC721MetadataUpgradeable, OldVaultManagerStorage {\n using SafeERC20 for IERC20;\n using Address for address;\n\n /// @inheritdoc IERC721MetadataUpgradeable\n string public name;\n /// @inheritdoc IERC721MetadataUpgradeable\n string public symbol;\n\n // ================================= MODIFIERS =================================\n\n /// @notice Checks if the person interacting with the vault with `vaultID` is approved\n /// @param caller Address of the person seeking to interact with the vault\n /// @param vaultID ID of the concerned vault\n modifier onlyApprovedOrOwner(address caller, uint256 vaultID) {\n if (!_isApprovedOrOwner(caller, vaultID)) revert NotApproved();\n _;\n }\n\n // ================================ ERC721 LOGIC ===============================\n\n /// @notice Checks whether a given address is approved for a vault or owns this vault\n /// @param spender Address for which vault ownership should be checked\n /// @param vaultID ID of the vault to check\n /// @return Whether the `spender` address owns or is approved for `vaultID`\n function isApprovedOrOwner(address spender, uint256 vaultID) external view returns (bool) {\n return _isApprovedOrOwner(spender, vaultID);\n }\n\n /// @inheritdoc IERC721MetadataUpgradeable\n function tokenURI(uint256 vaultID) external view returns (string memory) {\n if (!_exists(vaultID)) revert NonexistentVault();\n // There is no vault with `vaultID` equal to 0, so the following variable is\n // always greater than zero\n uint256 temp = vaultID;\n uint256 digits;\n while (temp != 0) {\n digits++;\n temp /= 10;\n }\n bytes memory buffer = new bytes(digits);\n while (vaultID != 0) {\n digits -= 1;\n buffer[digits] = bytes1(uint8(48 + uint256(vaultID % 10)));\n vaultID /= 10;\n }\n return bytes(_baseURI).length > 0 ? string(abi.encodePacked(_baseURI, string(buffer))) : \"\";\n }\n\n /// @inheritdoc IERC721Upgradeable\n function balanceOf(address owner) external view returns (uint256) {\n if (owner == address(0)) revert ZeroAddress();\n return _balances[owner];\n }\n\n /// @inheritdoc IERC721Upgradeable\n function ownerOf(uint256 vaultID) external view returns (address) {\n return _ownerOf(vaultID);\n }\n\n /// @inheritdoc IERC721Upgradeable\n function approve(address to, uint256 vaultID) external {\n address owner = _ownerOf(vaultID);\n if (to == owner) revert ApprovalToOwner();\n if (msg.sender != owner && !isApprovedForAll(owner, msg.sender)) revert NotApproved();\n\n _approve(to, vaultID);\n }\n\n /// @inheritdoc IERC721Upgradeable\n function getApproved(uint256 vaultID) external view returns (address) {\n if (!_exists(vaultID)) revert NonexistentVault();\n return _getApproved(vaultID);\n }\n\n /// @inheritdoc IERC721Upgradeable\n function setApprovalForAll(address operator, bool approved) external {\n _setApprovalForAll(msg.sender, operator, approved);\n }\n\n /// @inheritdoc IERC721Upgradeable\n function isApprovedForAll(address owner, address operator) public view returns (bool) {\n return _operatorApprovals[owner][operator] == 1;\n }\n\n /// @inheritdoc IERC721Upgradeable\n function transferFrom(address from, address to, uint256 vaultID) external onlyApprovedOrOwner(msg.sender, vaultID) {\n _transfer(from, to, vaultID);\n }\n\n /// @inheritdoc IERC721Upgradeable\n function safeTransferFrom(address from, address to, uint256 vaultID) external {\n safeTransferFrom(from, to, vaultID, \"\");\n }\n\n /// @inheritdoc IERC721Upgradeable\n function safeTransferFrom(\n address from,\n address to,\n uint256 vaultID,\n bytes memory _data\n ) public onlyApprovedOrOwner(msg.sender, vaultID) {\n _safeTransfer(from, to, vaultID, _data);\n }\n\n // ================================ ERC165 LOGIC ===============================\n\n /// @inheritdoc IERC165Upgradeable\n function supportsInterface(bytes4 interfaceId) external pure returns (bool) {\n return\n interfaceId == type(IERC721MetadataUpgradeable).interfaceId ||\n interfaceId == type(IERC721Upgradeable).interfaceId ||\n interfaceId == type(IVaultManager).interfaceId ||\n interfaceId == type(IERC165Upgradeable).interfaceId;\n }\n\n // ================== INTERNAL FUNCTIONS FOR THE ERC721 LOGIC ==================\n\n /// @notice Internal version of the `ownerOf` function\n function _ownerOf(uint256 vaultID) internal view returns (address owner) {\n owner = _owners[vaultID];\n if (owner == address(0)) revert NonexistentVault();\n }\n\n /// @notice Internal version of the `getApproved` function\n function _getApproved(uint256 vaultID) internal view returns (address) {\n return _vaultApprovals[vaultID];\n }\n\n /// @notice Internal version of the `safeTransferFrom` function (with the data parameter)\n function _safeTransfer(address from, address to, uint256 vaultID, bytes memory _data) internal {\n _transfer(from, to, vaultID);\n if (!_checkOnERC721Received(from, to, vaultID, _data)) revert NonERC721Receiver();\n }\n\n /// @notice Checks whether a vault exists\n /// @param vaultID ID of the vault to check\n /// @return Whether `vaultID` has been created\n function _exists(uint256 vaultID) internal view returns (bool) {\n return _owners[vaultID] != address(0);\n }\n\n /// @notice Internal version of the `isApprovedOrOwner` function\n function _isApprovedOrOwner(address spender, uint256 vaultID) internal view returns (bool) {\n // The following checks if the vault exists\n address owner = _ownerOf(vaultID);\n return (spender == owner || _getApproved(vaultID) == spender || _operatorApprovals[owner][spender] == 1);\n }\n\n /// @notice Internal version of the `createVault` function\n /// Mints `vaultID` and transfers it to `to`\n /// @dev This method is equivalent to the `_safeMint` method used in OpenZeppelin ERC721 contract\n /// @dev Emits a {Transfer} event\n function _mint(address to) internal returns (uint256 vaultID) {\n if (whitelistingActivated && (isWhitelisted[to] != 1 || isWhitelisted[msg.sender] != 1))\n revert NotWhitelisted();\n if (to == address(0)) revert ZeroAddress();\n\n unchecked {\n vaultIDCount += 1;\n }\n\n vaultID = vaultIDCount;\n _beforeTokenTransfer(address(0), to, vaultID);\n\n unchecked {\n _balances[to] += 1;\n }\n\n _owners[vaultID] = to;\n emit Transfer(address(0), to, vaultID);\n if (!_checkOnERC721Received(address(0), to, vaultID, \"\")) revert NonERC721Receiver();\n }\n\n /// @notice Destroys `vaultID`\n /// @dev `vaultID` must exist\n /// @dev Emits a {Transfer} event\n function _burn(uint256 vaultID) internal {\n address owner = _ownerOf(vaultID);\n\n _beforeTokenTransfer(owner, address(0), vaultID);\n // Clear approvals\n _approve(address(0), vaultID);\n // The following line cannot underflow as the owner's balance is necessarily\n // greater than 1\n unchecked {\n _balances[owner] -= 1;\n }\n delete _owners[vaultID];\n delete vaultData[vaultID];\n\n emit Transfer(owner, address(0), vaultID);\n }\n\n /// @notice Transfers `vaultID` from `from` to `to` as opposed to {transferFrom},\n /// this imposes no restrictions on msg.sender\n /// @dev `to` cannot be the zero address and `perpetualID` must be owned by `from`\n /// @dev Emits a {Transfer} event\n /// @dev A whitelist check is performed if necessary on the `to` address\n function _transfer(address from, address to, uint256 vaultID) internal {\n if (_ownerOf(vaultID) != from) revert NotApproved();\n if (to == address(0)) revert ZeroAddress();\n if (whitelistingActivated && isWhitelisted[to] != 1) revert NotWhitelisted();\n\n _beforeTokenTransfer(from, to, vaultID);\n\n // Clear approvals from the previous owner\n _approve(address(0), vaultID);\n unchecked {\n _balances[from] -= 1;\n _balances[to] += 1;\n }\n _owners[vaultID] = to;\n\n emit Transfer(from, to, vaultID);\n }\n\n /// @notice Approves `to` to operate on `vaultID`\n function _approve(address to, uint256 vaultID) internal {\n _vaultApprovals[vaultID] = to;\n emit Approval(_ownerOf(vaultID), to, vaultID);\n }\n\n /// @notice Internal version of the `setApprovalForAll` function\n /// @dev It contains an `approver` field to be used in case someone signs a permit for a particular\n /// address, and this signature is given to the contract by another address (like a router)\n function _setApprovalForAll(address approver, address operator, bool approved) internal {\n if (operator == approver) revert ApprovalToCaller();\n uint256 approval = approved ? 1 : 0;\n _operatorApprovals[approver][operator] = approval;\n emit ApprovalForAll(approver, operator, approved);\n }\n\n /// @notice Internal function to invoke {IERC721Receiver-onERC721Received} on a target address\n /// The call is not executed if the target address is not a contract\n /// @param from Address representing the previous owner of the given token ID\n /// @param to Target address that will receive the tokens\n /// @param vaultID ID of the token to be transferred\n /// @param _data Bytes optional data to send along with the call\n /// @return Bool whether the call correctly returned the expected value\n function _checkOnERC721Received(\n address from,\n address to,\n uint256 vaultID,\n bytes memory _data\n ) private returns (bool) {\n if (to.isContract()) {\n try IERC721ReceiverUpgradeable(to).onERC721Received(msg.sender, from, vaultID, _data) returns (\n bytes4 retval\n ) {\n return retval == IERC721ReceiverUpgradeable.onERC721Received.selector;\n } catch (bytes memory reason) {\n if (reason.length == 0) {\n revert NonERC721Receiver();\n } else {\n // solhint-disable-next-line no-inline-assembly\n assembly {\n revert(add(32, reason), mload(reason))\n }\n }\n }\n } else {\n return true;\n }\n }\n\n /// @notice Hook that is called before any token transfer. This includes minting and burning.\n /// Calling conditions:\n ///\n /// - When `from` and `to` are both non-zero, `from`'s `vaultID` will be\n /// transferred to `to`.\n /// - When `from` is zero, `vaultID` will be minted for `to`.\n /// - When `to` is zero, `from`'s `vaultID` will be burned.\n /// - `from` and `to` are never both zero.\n function _beforeTokenTransfer(address from, address to, uint256 vaultID) internal virtual {}\n}\n" + }, + "contracts/deprecated/vaultManager/OldVaultManagerPermit.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\nimport \"./OldVaultManagerERC721.sol\";\nimport \"../../interfaces/external/IERC1271.sol\";\n\n/// @title VaultManagerPermit\n/// @author Angle Labs, Inc.\n/// @dev Base Implementation of permit functions for the `VaultManager` contract\nabstract contract OldVaultManagerPermit is Initializable, OldVaultManagerERC721 {\n using Address for address;\n\n mapping(address => uint256) private _nonces;\n /* solhint-disable var-name-mixedcase */\n bytes32 private _HASHED_NAME;\n bytes32 private _HASHED_VERSION;\n bytes32 private _PERMIT_TYPEHASH;\n /* solhint-enable var-name-mixedcase */\n\n error ExpiredDeadline();\n error InvalidSignature();\n\n //solhint-disable-next-line\n function __ERC721Permit_init(string memory _name) internal onlyInitializing {\n _PERMIT_TYPEHASH = keccak256(\n \"Permit(address owner,address spender,bool approved,uint256 nonce,uint256 deadline)\"\n );\n _HASHED_NAME = keccak256(bytes(_name));\n _HASHED_VERSION = keccak256(bytes(\"1\"));\n }\n\n /// @notice Allows an address to give or revoke approval for all its vaults to another address\n /// @param owner Address signing the permit and giving (or revoking) its approval for all the controlled vaults\n /// @param spender Address to give approval to\n /// @param approved Whether to give or revoke the approval\n /// @param deadline Deadline parameter for the signature to be valid\n /// @dev The `v`, `r`, and `s` parameters are used as signature data\n function permit(\n address owner,\n address spender,\n bool approved,\n uint256 deadline,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) external {\n if (block.timestamp > deadline) revert ExpiredDeadline();\n // Additional signature checks performed in the `ECDSAUpgradeable.recover` function\n if (uint256(s) > 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D576E7357A4501DDFE92F46681B20A0 || (v != 27 && v != 28))\n revert InvalidSignature();\n\n bytes32 digest = keccak256(\n abi.encodePacked(\n \"\\x19\\x01\",\n _domainSeparatorV4(),\n keccak256(\n abi.encode(\n _PERMIT_TYPEHASH,\n // 0x3f43a9c6bafb5c7aab4e0cfe239dc5d4c15caf0381c6104188191f78a6640bd8,\n owner,\n spender,\n approved,\n _useNonce(owner),\n deadline\n )\n )\n )\n );\n if (owner.isContract()) {\n if (IERC1271(owner).isValidSignature(digest, abi.encodePacked(r, s, v)) != 0x1626ba7e)\n revert InvalidSignature();\n } else {\n address signer = ecrecover(digest, v, r, s);\n if (signer != owner || signer == address(0)) revert InvalidSignature();\n }\n\n _setApprovalForAll(owner, spender, approved);\n }\n\n /// @notice Returns the current nonce for an `owner` address\n function nonces(address owner) public view returns (uint256) {\n return _nonces[owner];\n }\n\n /// @notice Returns the domain separator for the current chain.\n // solhint-disable-next-line func-name-mixedcase\n function DOMAIN_SEPARATOR() external view returns (bytes32) {\n return _domainSeparatorV4();\n }\n\n /// @notice Internal version of the `DOMAIN_SEPARATOR` function\n function _domainSeparatorV4() internal view returns (bytes32) {\n return\n keccak256(\n abi.encode(\n // keccak256('EIP712Domain(string name,string version,uint256 chainId,address verifyingContract)')\n 0x8b73c3c69bb8fe3d512ecc4cf759cc79239f7b179b0ffacaa9a75d522b39400f,\n _HASHED_NAME,\n _HASHED_VERSION,\n block.chainid,\n address(this)\n )\n );\n }\n\n /// @notice Consumes a nonce for an address: returns the current value and increments it\n function _useNonce(address owner) internal returns (uint256 current) {\n current = _nonces[owner];\n _nonces[owner] = current + 1;\n }\n\n uint256[49] private __gap;\n}\n" + }, + "contracts/deprecated/vaultManager/OldVaultManagerStorage.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\nimport \"@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/token/ERC20/extensions/draft-IERC20PermitUpgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/token/ERC721/IERC721ReceiverUpgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/interfaces/IERC721MetadataUpgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/utils/introspection/IERC165Upgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/utils/AddressUpgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/security/ReentrancyGuardUpgradeable.sol\";\nimport \"@openzeppelin/contracts/token/ERC20/extensions/IERC20Metadata.sol\";\nimport \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\nimport \"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\";\n\nimport \"../../interfaces/IAgToken.sol\";\nimport \"../../interfaces/IOracle.sol\";\nimport \"../../interfaces/ISwapper.sol\";\nimport \"../../interfaces/ITreasury.sol\";\nimport \"../../interfaces/IVaultManager.sol\";\nimport \"../../interfaces/governance/IVeBoostProxy.sol\";\n\n/// @title VaultManagerStorage\n/// @author Angle Labs, Inc.\n/// @dev Variables, references, parameters and events needed in the `VaultManager` contract\n// solhint-disable-next-line max-states-count\ncontract OldVaultManagerStorage is IVaultManagerStorage, Initializable, ReentrancyGuardUpgradeable {\n /// @notice Base used for parameter computation: almost all the parameters of this contract are set in `BASE_PARAMS`\n uint256 public constant BASE_PARAMS = 10 ** 9;\n /// @notice Base used for interest rate computation\n uint256 public constant BASE_INTEREST = 10 ** 27;\n /// @notice Used for interest rate computation\n uint256 public constant HALF_BASE_INTEREST = 10 ** 27 / 2;\n\n // ================================= REFERENCES ================================\n\n /// @inheritdoc IVaultManagerStorage\n ITreasury public treasury;\n /// @inheritdoc IVaultManagerStorage\n IERC20 public collateral;\n /// @inheritdoc IVaultManagerStorage\n IAgToken public stablecoin;\n /// @inheritdoc IVaultManagerStorage\n IOracle public oracle;\n /// @notice Reference to the contract which computes adjusted veANGLE balances for liquidators boosts\n IVeBoostProxy public veBoostProxy;\n /// @notice Base of the collateral\n uint256 internal _collatBase;\n\n // ================================= PARAMETERS ================================\n // Unless specified otherwise, parameters of this contract are expressed in `BASE_PARAMS`\n\n /// @notice Maximum amount of stablecoins that can be issued with this contract (in `BASE_TOKENS`). This parameter should\n /// not be bigger than `type(uint256).max / BASE_INTEREST` otherwise there may be some overflows in the `increaseDebt` function\n uint256 public debtCeiling;\n /// @notice Threshold veANGLE balance values for the computation of the boost for liquidators: the length of this array\n /// should normally be 2. The base of the x-values in this array should be `BASE_TOKENS`\n uint256[] public xLiquidationBoost;\n /// @notice Values of the liquidation boost at the threshold values of x\n uint256[] public yLiquidationBoost;\n /// @inheritdoc IVaultManagerStorage\n uint64 public collateralFactor;\n /// @notice Maximum Health factor at which a vault can end up after a liquidation (unless it's fully liquidated)\n uint64 public targetHealthFactor;\n /// @notice Upfront fee taken when borrowing stablecoins: this fee is optional and should in practice not be used\n uint64 public borrowFee;\n /// @notice Upfront fee taken when repaying stablecoins: this fee is optional as well. It should be smaller\n /// than the liquidation surcharge (cf below) to avoid exploits where people voluntarily get liquidated at a 0\n /// discount to pay smaller repaying fees\n uint64 public repayFee;\n /// @notice Per second interest taken to borrowers taking agToken loans. Contrarily to other parameters, it is set in `BASE_INTEREST`\n /// that is to say in base 10**27\n uint64 public interestRate;\n /// @notice Fee taken by the protocol during a liquidation. Technically, this value is not the fee per se, it's 1 - fee.\n /// For instance for a 2% fee, `liquidationSurcharge` should be 98%\n uint64 public liquidationSurcharge;\n /// @notice Maximum discount given to liquidators\n uint64 public maxLiquidationDiscount;\n /// @notice Whether whitelisting is required to own a vault or not\n bool public whitelistingActivated;\n /// @notice Whether the contract is paused or not\n bool public paused;\n\n // ================================= VARIABLES =================================\n\n /// @notice Timestamp at which the `interestAccumulator` was updated\n uint256 public lastInterestAccumulatorUpdated;\n /// @inheritdoc IVaultManagerStorage\n uint256 public interestAccumulator;\n /// @inheritdoc IVaultManagerStorage\n uint256 public totalNormalizedDebt;\n /// @notice Surplus accumulated by the contract: surplus is always in stablecoins, and is then reset\n /// when the value is communicated to the treasury contract\n uint256 public surplus;\n /// @notice Bad debt made from liquidated vaults which ended up having no collateral and a positive amount\n /// of stablecoins\n uint256 public badDebt;\n\n // ================================== MAPPINGS =================================\n\n /// @inheritdoc IVaultManagerStorage\n mapping(uint256 => Vault) public vaultData;\n /// @notice Maps an address to 1 if it's whitelisted and can open or own a vault\n mapping(address => uint256) public isWhitelisted;\n\n // ================================ ERC721 DATA ================================\n\n /// @inheritdoc IVaultManagerStorage\n uint256 public vaultIDCount;\n\n /// @notice URI\n string internal _baseURI;\n\n // Mapping from `vaultID` to owner address\n mapping(uint256 => address) internal _owners;\n\n // Mapping from owner address to vault owned count\n mapping(address => uint256) internal _balances;\n\n // Mapping from `vaultID` to approved address\n mapping(uint256 => address) internal _vaultApprovals;\n\n // Mapping from owner to operator approvals\n mapping(address => mapping(address => uint256)) internal _operatorApprovals;\n\n uint256[50] private __gap;\n\n // =================================== EVENTS ==================================\n\n event AccruedToTreasury(uint256 surplusEndValue, uint256 badDebtEndValue);\n event CollateralAmountUpdated(uint256 vaultID, uint256 collateralAmount, uint8 isIncrease);\n event InterestAccumulatorUpdated(uint256 value, uint256 timestamp);\n event InternalDebtUpdated(uint256 vaultID, uint256 internalAmount, uint8 isIncrease);\n event FiledUint64(uint64 param, bytes32 what);\n event DebtCeilingUpdated(uint256 debtCeiling);\n event LiquidationBoostParametersUpdated(address indexed _veBoostProxy, uint256[] xBoost, uint256[] yBoost);\n event LiquidatedVaults(uint256[] vaultIDs);\n event DebtTransferred(uint256 srcVaultID, uint256 dstVaultID, address dstVaultManager, uint256 amount);\n\n // =================================== ERRORS ==================================\n\n error ApprovalToOwner();\n error ApprovalToCaller();\n error DustyLeftoverAmount();\n error DebtCeilingExceeded();\n error HealthyVault();\n error IncompatibleLengths();\n error InsolventVault();\n error InvalidParameterValue();\n error InvalidParameterType();\n error InvalidSetOfParameters();\n error InvalidTreasury();\n error NonERC721Receiver();\n error NonexistentVault();\n error NotApproved();\n error NotGovernor();\n error NotGovernorOrGuardian();\n error NotTreasury();\n error NotWhitelisted();\n error NotVaultManager();\n error Paused();\n error TooHighParameterValue();\n error TooSmallParameterValue();\n error ZeroAddress();\n\n /// @custom:oz-upgrades-unsafe-allow constructor\n constructor() initializer {}\n}\n" + }, + "contracts/external/ProxyAdmin.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\nimport \"./TransparentUpgradeableProxy.sol\";\nimport \"@openzeppelin/contracts/access/Ownable.sol\";\n\n/**\n * @dev This is an auxiliary contract meant to be assigned as the admin of a {TransparentUpgradeableProxy}. For an\n * explanation of why you would want to use this see the documentation for {TransparentUpgradeableProxy}.\n * This contract was fully forked from OpenZeppelin `ProxyAdmin`\n */\ncontract ProxyAdmin is Ownable {\n /**\n * @dev Returns the current implementation of `proxy`.\n *\n * Requirements:\n *\n * - This contract must be the admin of `proxy`.\n */\n function getProxyImplementation(TransparentUpgradeableProxy proxy) public view virtual returns (address) {\n // We need to manually run the static call since the getter cannot be flagged as view\n // bytes4(keccak256(\"implementation()\")) == 0x5c60da1b\n (bool success, bytes memory returndata) = address(proxy).staticcall(hex\"5c60da1b\");\n require(success);\n return abi.decode(returndata, (address));\n }\n\n /**\n * @dev Returns the current admin of `proxy`.\n *\n * Requirements:\n *\n * - This contract must be the admin of `proxy`.\n */\n function getProxyAdmin(TransparentUpgradeableProxy proxy) public view virtual returns (address) {\n // We need to manually run the static call since the getter cannot be flagged as view\n // bytes4(keccak256(\"admin()\")) == 0xf851a440\n (bool success, bytes memory returndata) = address(proxy).staticcall(hex\"f851a440\");\n require(success);\n return abi.decode(returndata, (address));\n }\n\n /**\n * @dev Changes the admin of `proxy` to `newAdmin`.\n *\n * Requirements:\n *\n * - This contract must be the current admin of `proxy`.\n */\n function changeProxyAdmin(TransparentUpgradeableProxy proxy, address newAdmin) public virtual onlyOwner {\n proxy.changeAdmin(newAdmin);\n }\n\n /**\n * @dev Upgrades `proxy` to `implementation`. See {TransparentUpgradeableProxy-upgradeTo}.\n *\n * Requirements:\n *\n * - This contract must be the admin of `proxy`.\n */\n function upgrade(TransparentUpgradeableProxy proxy, address implementation) public virtual onlyOwner {\n proxy.upgradeTo(implementation);\n }\n\n /**\n * @dev Upgrades `proxy` to `implementation` and calls a function on the new implementation. See\n * {TransparentUpgradeableProxy-upgradeToAndCall}.\n *\n * Requirements:\n *\n * - This contract must be the admin of `proxy`.\n */\n function upgradeAndCall(\n TransparentUpgradeableProxy proxy,\n address implementation,\n bytes memory data\n ) public payable virtual onlyOwner {\n proxy.upgradeToAndCall{ value: msg.value }(implementation, data);\n }\n}\n" + }, + "contracts/external/TransparentUpgradeableProxy.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\nimport \"@openzeppelin/contracts/proxy/ERC1967/ERC1967Proxy.sol\";\n\n/**\n * @dev This contract implements a proxy that is upgradeable by an admin. It is fully forked from OpenZeppelin\n * `TransparentUpgradeableProxy`\n *\n * To avoid https://medium.com/nomic-labs-blog/malicious-backdoors-in-ethereum-proxies-62629adf3357[proxy selector\n * clashing], which can potentially be used in an attack, this contract uses the\n * https://blog.openzeppelin.com/the-transparent-proxy-pattern/[transparent proxy pattern]. This pattern implies two\n * things that go hand in hand:\n *\n * 1. If any account other than the admin calls the proxy, the call will be forwarded to the implementation, even if\n * that call matches one of the admin functions exposed by the proxy itself.\n * 2. If the admin calls the proxy, it can access the admin functions, but its calls will never be forwarded to the\n * implementation. If the admin tries to call a function on the implementation it will fail with an error that says\n * \"admin cannot fallback to proxy target\".\n *\n * These properties mean that the admin account can only be used for admin actions like upgrading the proxy or changing\n * the admin, so it's best if it's a dedicated account that is not used for anything else. This will avoid headaches due\n * to sudden errors when trying to call a function from the proxy implementation.\n *\n * Our recommendation is for the dedicated account to be an instance of the {ProxyAdmin} contract. If set up this way,\n * you should think of the `ProxyAdmin` instance as the real administrative interface of your proxy.\n */\ncontract TransparentUpgradeableProxy is ERC1967Proxy {\n /**\n * @dev Initializes an upgradeable proxy managed by `_admin`, backed by the implementation at `_logic`, and\n * optionally initialized with `_data` as explained in {ERC1967Proxy-constructor}.\n */\n constructor(address _logic, address admin_, bytes memory _data) payable ERC1967Proxy(_logic, _data) {\n assert(_ADMIN_SLOT == bytes32(uint256(keccak256(\"eip1967.proxy.admin\")) - 1));\n _changeAdmin(admin_);\n }\n\n /**\n * @dev Modifier used internally that will delegate the call to the implementation unless the sender is the admin.\n */\n modifier ifAdmin() {\n if (msg.sender == _getAdmin()) {\n _;\n } else {\n _fallback();\n }\n }\n\n /**\n * @dev Returns the current admin.\n *\n * NOTE: Only the admin can call this function. See {ProxyAdmin-getProxyAdmin}.\n *\n * TIP: To get this value clients can read directly from the storage slot shown below (specified by EIP1967) using the\n * https://eth.wiki/json-rpc/API#eth_getstorageat[`eth_getStorageAt`] RPC call.\n * `0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103`\n */\n function admin() external ifAdmin returns (address admin_) {\n admin_ = _getAdmin();\n }\n\n /**\n * @dev Returns the current implementation.\n *\n * NOTE: Only the admin can call this function. See {ProxyAdmin-getProxyImplementation}.\n *\n * TIP: To get this value clients can read directly from the storage slot shown below (specified by EIP1967) using the\n * https://eth.wiki/json-rpc/API#eth_getstorageat[`eth_getStorageAt`] RPC call.\n * `0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc`\n */\n function implementation() external ifAdmin returns (address implementation_) {\n implementation_ = _implementation();\n }\n\n /**\n * @dev Changes the admin of the proxy.\n *\n * Emits an {AdminChanged} event.\n *\n * NOTE: Only the admin can call this function. See {ProxyAdmin-changeProxyAdmin}.\n */\n function changeAdmin(address newAdmin) external virtual ifAdmin {\n _changeAdmin(newAdmin);\n }\n\n /**\n * @dev Upgrade the implementation of the proxy.\n *\n * NOTE: Only the admin can call this function. See {ProxyAdmin-upgrade}.\n */\n function upgradeTo(address newImplementation) external ifAdmin {\n _upgradeToAndCall(newImplementation, bytes(\"\"), false);\n }\n\n /**\n * @dev Upgrade the implementation of the proxy, and then call a function from the new implementation as specified\n * by `data`, which should be an encoded function call. This is useful to initialize new storage variables in the\n * proxied contract.\n *\n * NOTE: Only the admin can call this function. See {ProxyAdmin-upgradeAndCall}.\n */\n function upgradeToAndCall(address newImplementation, bytes calldata data) external payable ifAdmin {\n _upgradeToAndCall(newImplementation, data, true);\n }\n\n /**\n * @dev Returns the current admin.\n */\n function _admin() internal view virtual returns (address) {\n return _getAdmin();\n }\n\n /**\n * @dev Makes sure the admin cannot access the fallback function. See {Proxy-_beforeFallback}.\n */\n function _beforeFallback() internal virtual override {\n require(msg.sender != _getAdmin(), \"TransparentUpgradeableProxy: admin cannot fallback to proxy target\");\n super._beforeFallback();\n }\n}\n" + }, + "contracts/flashloan/FlashAngle.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\nimport \"@openzeppelin/contracts-upgradeable/security/ReentrancyGuardUpgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol\";\nimport \"@openzeppelin/contracts/interfaces/IERC3156FlashBorrower.sol\";\nimport \"@openzeppelin/contracts/interfaces/IERC3156FlashLender.sol\";\nimport \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\nimport \"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\";\n\nimport \"../interfaces/IAgToken.sol\";\nimport \"../interfaces/ICoreBorrow.sol\";\nimport \"../interfaces/IFlashAngle.sol\";\nimport \"../interfaces/ITreasury.sol\";\n\n/// @title FlashAngle\n/// @author Angle Labs, Inc.\n/// @notice Contract to take flash loans on top of several AgToken contracts\ncontract FlashAngle is IERC3156FlashLender, IFlashAngle, Initializable, ReentrancyGuardUpgradeable {\n using SafeERC20 for IERC20;\n /// @notice Base used for parameter computation\n uint256 public constant BASE_PARAMS = 10 ** 9;\n /// @notice Success message received when calling a `FlashBorrower` contract\n bytes32 public constant CALLBACK_SUCCESS = keccak256(\"ERC3156FlashBorrower.onFlashLoan\");\n\n /// @notice Struct encoding for a given stablecoin the parameters\n struct StablecoinData {\n // Maximum amount borrowable for this stablecoin\n uint256 maxBorrowable;\n // Flash loan fee taken by the protocol for a flash loan on this stablecoin\n uint64 flashLoanFee;\n // Treasury address responsible of the stablecoin\n address treasury;\n }\n\n // ======================= Parameters and References ===========================\n\n /// @notice Maps a stablecoin to the data and parameters for flash loans\n mapping(IAgToken => StablecoinData) public stablecoinMap;\n /// @inheritdoc IFlashAngle\n ICoreBorrow public core;\n\n // =============================== Event =======================================\n\n event FlashLoan(address indexed stablecoin, uint256 amount, IERC3156FlashBorrower indexed receiver);\n event FlashLoanParametersUpdated(IAgToken indexed stablecoin, uint64 _flashLoanFee, uint256 _maxBorrowable);\n\n // =============================== Errors ======================================\n\n error InvalidReturnMessage();\n error NotCore();\n error NotGovernorOrGuardian();\n error NotTreasury();\n error TooBigAmount();\n error TooHighParameterValue();\n error UnsupportedStablecoin();\n error ZeroAddress();\n\n /// @notice Initializes the contract\n /// @param _core Core address handling this module\n function initialize(ICoreBorrow _core) public initializer {\n if (address(_core) == address(0)) revert ZeroAddress();\n core = _core;\n }\n\n /// @custom:oz-upgrades-unsafe-allow constructor\n constructor() initializer {}\n\n // =================================== Modifiers ===============================\n\n /// @notice Checks whether the sender is the core contract\n modifier onlyCore() {\n if (msg.sender != address(core)) revert NotCore();\n _;\n }\n\n /// @notice Checks whether a given stablecoin has been initialized in this contract\n /// @param stablecoin Stablecoin to check\n /// @dev To check whether a stablecoin has been initialized, we just need to check whether its associated\n /// `treasury` address is not null in the `stablecoinMap`. This is what's checked in the `CoreBorrow` contract\n /// when adding support for a stablecoin\n modifier onlyExistingStablecoin(IAgToken stablecoin) {\n if (stablecoinMap[stablecoin].treasury == address(0)) revert UnsupportedStablecoin();\n _;\n }\n\n // ================================ ERC3156 Spec ===============================\n\n /// @inheritdoc IERC3156FlashLender\n function flashFee(address token, uint256 amount) external view returns (uint256) {\n return _flashFee(token, amount);\n }\n\n /// @inheritdoc IERC3156FlashLender\n function maxFlashLoan(address token) external view returns (uint256) {\n // It will be 0 anyway if the token was not added\n return stablecoinMap[IAgToken(token)].maxBorrowable;\n }\n\n /// @inheritdoc IERC3156FlashLender\n function flashLoan(\n IERC3156FlashBorrower receiver,\n address token,\n uint256 amount,\n bytes calldata data\n ) external nonReentrant returns (bool) {\n uint256 fee = _flashFee(token, amount);\n if (amount > stablecoinMap[IAgToken(token)].maxBorrowable) revert TooBigAmount();\n IAgToken(token).mint(address(receiver), amount);\n if (receiver.onFlashLoan(msg.sender, token, amount, fee, data) != CALLBACK_SUCCESS)\n revert InvalidReturnMessage();\n // Token must be an agToken here so normally no need to use `safeTransferFrom`, but out of safety\n // and in case governance whitelists an agToken which does not have a correct implementation, we prefer\n // to use `safeTransferFrom` here\n IERC20(token).safeTransferFrom(address(receiver), address(this), amount + fee);\n IAgToken(token).burnSelf(amount, address(this));\n emit FlashLoan(token, amount, receiver);\n return true;\n }\n\n /// @notice Internal function to compute the fee induced for taking a flash loan of `amount` of `token`\n /// @param token The loan currency\n /// @param amount The amount of tokens lent\n /// @dev This function will revert if the `token` requested is not whitelisted here\n function _flashFee(\n address token,\n uint256 amount\n ) internal view onlyExistingStablecoin(IAgToken(token)) returns (uint256) {\n return (amount * stablecoinMap[IAgToken(token)].flashLoanFee) / BASE_PARAMS;\n }\n\n // ============================ Treasury Only Function =========================\n\n /// @inheritdoc IFlashAngle\n function accrueInterestToTreasury(IAgToken stablecoin) external returns (uint256 balance) {\n address treasury = stablecoinMap[stablecoin].treasury;\n if (msg.sender != treasury) revert NotTreasury();\n balance = stablecoin.balanceOf(address(this));\n IERC20(address(stablecoin)).safeTransfer(treasury, balance);\n }\n\n // =========================== Governance Only Function ========================\n\n /// @notice Sets the parameters for a given stablecoin\n /// @param stablecoin Stablecoin to change the parameters for\n /// @param _flashLoanFee New flash loan fee for this stablecoin\n /// @param _maxBorrowable Maximum amount that can be borrowed in a single flash loan\n /// @dev Setting a `maxBorrowable` parameter equal to 0 is a way to pause the functionality\n /// @dev Parameters can only be modified for whitelisted stablecoins\n function setFlashLoanParameters(\n IAgToken stablecoin,\n uint64 _flashLoanFee,\n uint256 _maxBorrowable\n ) external onlyExistingStablecoin(stablecoin) {\n if (!core.isGovernorOrGuardian(msg.sender)) revert NotGovernorOrGuardian();\n if (_flashLoanFee > BASE_PARAMS) revert TooHighParameterValue();\n stablecoinMap[stablecoin].flashLoanFee = _flashLoanFee;\n stablecoinMap[stablecoin].maxBorrowable = _maxBorrowable;\n emit FlashLoanParametersUpdated(stablecoin, _flashLoanFee, _maxBorrowable);\n }\n\n // =========================== CoreBorrow Only Functions =======================\n\n /// @inheritdoc IFlashAngle\n function addStablecoinSupport(address _treasury) external onlyCore {\n stablecoinMap[IAgToken(ITreasury(_treasury).stablecoin())].treasury = _treasury;\n }\n\n /// @inheritdoc IFlashAngle\n function removeStablecoinSupport(address _treasury) external onlyCore {\n delete stablecoinMap[IAgToken(ITreasury(_treasury).stablecoin())];\n }\n\n /// @inheritdoc IFlashAngle\n function setCore(address _core) external onlyCore {\n core = ICoreBorrow(_core);\n }\n}\n" + }, + "contracts/interfaces/coreModule/IAgTokenMainnet.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\n/// @title IAgTokenMainnet\n/// @author Angle Labs, Inc.\ninterface IAgTokenMainnet {\n function stableMaster() external view returns (address);\n}\n" + }, + "contracts/interfaces/coreModule/ICore.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\n/// @title ICore\n/// @author Angle Labs, Inc.\ninterface ICore {\n function stablecoinList() external view returns (address[] memory);\n}\n" + }, + "contracts/interfaces/coreModule/ILiquidityGauge.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\ninterface ILiquidityGauge {\n function deposit(\n uint256 _value,\n address _addr,\n // solhint-disable-next-line\n bool _claim_rewards\n ) external;\n\n function withdraw(\n uint256 _value,\n // solhint-disable-next-line\n bool _claim_rewards\n ) external;\n\n // solhint-disable-next-line\n function claim_rewards(address _addr, address _receiver) external;\n\n // solhint-disable-next-line\n function claimable_reward(address _addr, address _reward_token) external view returns (uint256 amount);\n}\n" + }, + "contracts/interfaces/coreModule/IOracleCore.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\n/// @title IOracleCore\n/// @author Angle Labs, Inc.\ninterface IOracleCore {\n function readUpper() external view returns (uint256);\n\n function readQuoteLower(uint256 baseAmount) external view returns (uint256);\n}\n" + }, + "contracts/interfaces/coreModule/IPerpetualManager.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\n/// @title IPerpetualManager\n/// @author Angle Labs, Inc.\ninterface IPerpetualManager {\n function totalHedgeAmount() external view returns (uint256);\n\n function maintenanceMargin() external view returns (uint64);\n\n function maxLeverage() external view returns (uint64);\n\n function targetHAHedge() external view returns (uint64);\n\n function limitHAHedge() external view returns (uint64);\n\n function lockTime() external view returns (uint64);\n\n function haBonusMalusDeposit() external view returns (uint64);\n\n function haBonusMalusWithdraw() external view returns (uint64);\n\n function xHAFeesDeposit(uint256) external view returns (uint64);\n\n function yHAFeesDeposit(uint256) external view returns (uint64);\n\n function xHAFeesWithdraw(uint256) external view returns (uint64);\n\n function yHAFeesWithdraw(uint256) external view returns (uint64);\n}\n" + }, + "contracts/interfaces/coreModule/IPoolManager.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\n/// @title IPoolManager\n/// @author Angle Labs, Inc.\ninterface IPoolManager {\n function feeManager() external view returns (address);\n\n function strategyList(uint256) external view returns (address);\n}\n" + }, + "contracts/interfaces/coreModule/IStableMaster.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\nimport \"./IPerpetualManager.sol\";\nimport \"./IOracleCore.sol\";\n\n// Struct to handle all the parameters to manage the fees\n// related to a given collateral pool (associated to the stablecoin)\nstruct MintBurnData {\n // Values of the thresholds to compute the minting fees\n // depending on HA hedge (scaled by `BASE_PARAMS`)\n uint64[] xFeeMint;\n // Values of the fees at thresholds (scaled by `BASE_PARAMS`)\n uint64[] yFeeMint;\n // Values of the thresholds to compute the burning fees\n // depending on HA hedge (scaled by `BASE_PARAMS`)\n uint64[] xFeeBurn;\n // Values of the fees at thresholds (scaled by `BASE_PARAMS`)\n uint64[] yFeeBurn;\n // Max proportion of collateral from users that can be covered by HAs\n // It is exactly the same as the parameter of the same name in `PerpetualManager`, whenever one is updated\n // the other changes accordingly\n uint64 targetHAHedge;\n // Minting fees correction set by the `FeeManager` contract: they are going to be multiplied\n // to the value of the fees computed using the hedge curve\n // Scaled by `BASE_PARAMS`\n uint64 bonusMalusMint;\n // Burning fees correction set by the `FeeManager` contract: they are going to be multiplied\n // to the value of the fees computed using the hedge curve\n // Scaled by `BASE_PARAMS`\n uint64 bonusMalusBurn;\n // Parameter used to limit the number of stablecoins that can be issued using the concerned collateral\n uint256 capOnStableMinted;\n}\n\n// Struct to handle all the variables and parameters to handle SLPs in the protocol\n// including the fraction of interests they receive or the fees to be distributed to\n// them\nstruct SLPData {\n // Last timestamp at which the `sanRate` has been updated for SLPs\n uint256 lastBlockUpdated;\n // Fees accumulated from previous blocks and to be distributed to SLPs\n uint256 lockedInterests;\n // Max interests used to update the `sanRate` in a single block\n // Should be in collateral token base\n uint256 maxInterestsDistributed;\n // Amount of fees left aside for SLPs and that will be distributed\n // when the protocol is collateralized back again\n uint256 feesAside;\n // Part of the fees normally going to SLPs that is left aside\n // before the protocol is collateralized back again (depends on collateral ratio)\n // Updated by keepers and scaled by `BASE_PARAMS`\n uint64 slippageFee;\n // Portion of the fees from users minting and burning\n // that goes to SLPs (the rest goes to surplus)\n uint64 feesForSLPs;\n // Slippage factor that's applied to SLPs exiting (depends on collateral ratio)\n // If `slippage = BASE_PARAMS`, SLPs can get nothing, if `slippage = 0` they get their full claim\n // Updated by keepers and scaled by `BASE_PARAMS`\n uint64 slippage;\n // Portion of the interests from lending\n // that goes to SLPs (the rest goes to surplus)\n uint64 interestsForSLPs;\n}\n\n/// @title IStableMaster\n/// @author Angle Labs, Inc.\ninterface IStableMaster {\n function agToken() external view returns (address);\n\n function updateStocksUsers(uint256 amount, address poolManager) external;\n\n function collateralMap(\n address poolManager\n )\n external\n view\n returns (\n address token,\n address sanToken,\n IPerpetualManager perpetualManager,\n IOracleCore oracle,\n uint256 stocksUsers,\n uint256 sanRate,\n uint256 collatBase,\n SLPData memory slpData,\n MintBurnData memory feeData\n );\n\n function paused(bytes32) external view returns (bool);\n\n function deposit(uint256 amount, address user, address poolManager) external;\n\n function withdraw(uint256 amount, address burner, address dest, address poolManager) external;\n}\n" + }, + "contracts/interfaces/external/create2/ImmutableCreate2Factory.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\ninterface ImmutableCreate2Factory {\n function safeCreate2(bytes32 salt, bytes memory initCode) external payable returns (address deploymentAddress);\n\n function findCreate2Address(\n bytes32 salt,\n bytes calldata initCode\n ) external view returns (address deploymentAddress);\n\n function findCreate2AddressViaHash(\n bytes32 salt,\n bytes32 initCodeHash\n ) external view returns (address deploymentAddress);\n}\n" + }, + "contracts/interfaces/external/IERC1271.sol": { + "content": "// SPDX-License-Identifier: GPL-2.0-or-later\npragma solidity ^0.8.12;\n\n/// @title Interface for verifying contract-based account signatures\n/// @notice Interface that verifies provided signature for the data\n/// @dev Interface defined by EIP-1271\ninterface IERC1271 {\n /// @notice Returns whether the provided signature is valid for the provided data\n /// @dev MUST return the bytes4 magic value 0x1626ba7e when function passes.\n /// MUST NOT modify state (using STATICCALL for solc < 0.5, view modifier for solc > 0.5).\n /// MUST allow external calls.\n /// @param hash Hash of the data to be signed\n /// @param signature Signature byte array associated with _data\n /// @return magicValue The bytes4 magic value 0x1626ba7e\n function isValidSignature(bytes32 hash, bytes memory signature) external view returns (bytes4 magicValue);\n}\n" + }, + "contracts/interfaces/external/IERC4626.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\npragma solidity >=0.8.0;\n\nimport \"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\";\nimport \"@openzeppelin/contracts/token/ERC20/ERC20.sol\";\n\n/// @notice Minimal IERC4646 tokenized Vault interface.\n/// @author Forked from Solmate (https://github.com/Rari-Capital/solmate/blob/main/src/mixins/ERC4626.sol)\n/// @dev Do not use in production! ERC-4626 is still in the review stage and is subject to change.\ninterface IERC4626 {\n event Deposit(address indexed from, address indexed to, uint256 amount, uint256 shares);\n event Withdraw(address indexed from, address indexed to, uint256 amount, uint256 shares);\n\n /// @notice Transfers a given amount of asset to the reactor and mint shares accordingly\n /// @param amount Given amount of asset\n /// @param to Address to mint shares to\n /// @return shares Amount of shares minted to `to`\n function deposit(uint256 amount, address to) external returns (uint256 shares);\n\n /// @notice Mints a given amount of shares to the reactor and transfer assets accordingly\n /// @param shares Given amount of shares\n /// @param to Address to mint shares to\n /// @return amount Amount of `asset` taken to the `msg.sender` to mint `shares`\n function mint(uint256 shares, address to) external returns (uint256 amount);\n\n /// @notice Transfers a given amount of asset from the reactor and burn shares accordingly\n /// @param amount Given amount of asset\n /// @param to Address to transfer assets to\n /// @param from Address to burn shares from\n /// @return shares Amount of shares burnt in the operation\n function withdraw(uint256 amount, address to, address from) external returns (uint256 shares);\n\n /// @notice Burns a given amount of shares to the reactor and transfer assets accordingly\n /// @param shares Given amount of shares\n /// @param to Address to transfer assets to\n /// @param from Address to burn shares from\n /// @return amount Amount of assets redeemed in the operation\n function redeem(uint256 shares, address to, address from) external returns (uint256 amount);\n\n /// @notice Returns the total assets managed by this reactor\n function totalAssets() external view returns (uint256);\n\n /// @notice Converts an amount of assets to the corresponding amount of reactor shares\n /// @param assets Amount of asset to convert\n /// @return Shares corresponding to the amount of assets obtained\n function convertToShares(uint256 assets) external view returns (uint256);\n\n /// @notice Converts an amount of shares to its current value in asset\n /// @param shares Amount of shares to convert\n /// @return Amount of assets corresponding to the amount of assets given\n function convertToAssets(uint256 shares) external view returns (uint256);\n\n /// @notice Computes how many shares one would get by depositing `assets`\n /// @param assets Amount of asset to convert\n function previewDeposit(uint256 assets) external view returns (uint256);\n\n /// @notice Computes how many assets one would need to mint `shares`\n /// @param shares Amount of shares required\n function previewMint(uint256 shares) external view returns (uint256);\n\n /// @notice Computes how many shares one would need to withdraw assets\n /// @param assets Amount of asset to withdraw\n function previewWithdraw(uint256 assets) external view returns (uint256);\n\n /// @notice Computes how many assets one would get by burning shares\n /// @param shares Amount of shares to burn\n function previewRedeem(uint256 shares) external view returns (uint256);\n\n /// @notice Max deposit allowed for a user\n /// @param user Address of the user to check\n function maxDeposit(address user) external returns (uint256);\n\n /// @notice Max mint allowed for a user\n /// @param user Address of the user to check\n function maxMint(address user) external returns (uint256);\n\n /// @notice Max withdraw allowed for a user\n /// @param user Address of the user to check\n function maxWithdraw(address user) external returns (uint256);\n\n /// @notice Max redeem allowed for a user\n /// @param user Address of the user to check\n function maxRedeem(address user) external returns (uint256);\n}\n" + }, + "contracts/interfaces/external/IWETH9.sol": { + "content": "// SPDX-License-Identifier: GPL-2.0-or-later\npragma solidity ^0.8.12;\n\nimport \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\n\n/// @title Interface for WETH9\ninterface IWETH9 is IERC20 {\n /// @notice Deposit ether to get wrapped ether\n function deposit() external payable;\n\n /// @notice Withdraw wrapped ether to get ether\n function withdraw(uint256) external;\n}\n" + }, + "contracts/interfaces/external/layerZero/ILayerZeroEndpoint.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity >=0.5.0;\n\nimport \"./ILayerZeroUserApplicationConfig.sol\";\n\ninterface ILayerZeroEndpoint is ILayerZeroUserApplicationConfig {\n // @notice send a LayerZero message to the specified address at a LayerZero endpoint.\n // @param _dstChainId - the destination chain identifier\n // @param _destination - the address on destination chain (in bytes). address length/format may vary by chains\n // @param _payload - a custom bytes payload to send to the destination contract\n // @param _refundAddress - if the source transaction is cheaper than the amount of value passed, refund the additional amount to this address\n // @param _zroPaymentAddress - the address of the ZRO token holder who would pay for the transaction\n // @param _adapterParams - parameters for custom functionality. e.g. receive airdropped native gas from the relayer on destination\n function send(\n uint16 _dstChainId,\n bytes calldata _destination,\n bytes calldata _payload,\n address payable _refundAddress,\n address _zroPaymentAddress,\n bytes calldata _adapterParams\n ) external payable;\n\n // @notice used by the messaging library to publish verified payload\n // @param _srcChainId - the source chain identifier\n // @param _srcAddress - the source contract (as bytes) at the source chain\n // @param _dstAddress - the address on destination chain\n // @param _nonce - the unbound message ordering nonce\n // @param _gasLimit - the gas limit for external contract execution\n // @param _payload - verified payload to send to the destination contract\n function receivePayload(\n uint16 _srcChainId,\n bytes calldata _srcAddress,\n address _dstAddress,\n uint64 _nonce,\n uint256 _gasLimit,\n bytes calldata _payload\n ) external;\n\n // @notice get the inboundNonce of a lzApp from a source chain which could be EVM or non-EVM chain\n // @param _srcChainId - the source chain identifier\n // @param _srcAddress - the source chain contract address\n function getInboundNonce(uint16 _srcChainId, bytes calldata _srcAddress) external view returns (uint64);\n\n // @notice get the outboundNonce from this source chain which, consequently, is always an EVM\n // @param _srcAddress - the source chain contract address\n function getOutboundNonce(uint16 _dstChainId, address _srcAddress) external view returns (uint64);\n\n // @notice gets a quote in source native gas, for the amount that send() requires to pay for message delivery\n // @param _dstChainId - the destination chain identifier\n // @param _userApplication - the user app address on this EVM chain\n // @param _payload - the custom message to send over LayerZero\n // @param _payInZRO - if false, user app pays the protocol fee in native token\n // @param _adapterParam - parameters for the adapter service, e.g. send some dust native token to dstChain\n function estimateFees(\n uint16 _dstChainId,\n address _userApplication,\n bytes calldata _payload,\n bool _payInZRO,\n bytes calldata _adapterParam\n ) external view returns (uint256 nativeFee, uint256 zroFee);\n\n // @notice get this Endpoint's immutable source identifier\n function getChainId() external view returns (uint16);\n\n // @notice the interface to retry failed message on this Endpoint destination\n // @param _srcChainId - the source chain identifier\n // @param _srcAddress - the source chain contract address\n // @param _payload - the payload to be retried\n function retryPayload(uint16 _srcChainId, bytes calldata _srcAddress, bytes calldata _payload) external;\n\n // @notice query if any STORED payload (message blocking) at the endpoint.\n // @param _srcChainId - the source chain identifier\n // @param _srcAddress - the source chain contract address\n function hasStoredPayload(uint16 _srcChainId, bytes calldata _srcAddress) external view returns (bool);\n\n // @notice query if the _libraryAddress is valid for sending msgs.\n // @param _userApplication - the user app address on this EVM chain\n function getSendLibraryAddress(address _userApplication) external view returns (address);\n\n // @notice query if the _libraryAddress is valid for receiving msgs.\n // @param _userApplication - the user app address on this EVM chain\n function getReceiveLibraryAddress(address _userApplication) external view returns (address);\n\n // @notice query if the non-reentrancy guard for send() is on\n // @return true if the guard is on. false otherwise\n function isSendingPayload() external view returns (bool);\n\n // @notice query if the non-reentrancy guard for receive() is on\n // @return true if the guard is on. false otherwise\n function isReceivingPayload() external view returns (bool);\n\n // @notice get the configuration of the LayerZero messaging library of the specified version\n // @param _version - messaging library version\n // @param _chainId - the chainId for the pending config change\n // @param _userApplication - the contract address of the user application\n // @param _configType - type of configuration. every messaging library has its own convention.\n function getConfig(\n uint16 _version,\n uint16 _chainId,\n address _userApplication,\n uint256 _configType\n ) external view returns (bytes memory);\n\n // @notice get the send() LayerZero messaging library version\n // @param _userApplication - the contract address of the user application\n function getSendVersion(address _userApplication) external view returns (uint16);\n\n // @notice get the lzReceive() LayerZero messaging library version\n // @param _userApplication - the contract address of the user application\n function getReceiveVersion(address _userApplication) external view returns (uint16);\n}\n" + }, + "contracts/interfaces/external/layerZero/ILayerZeroReceiver.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity >=0.5.0;\n\ninterface ILayerZeroReceiver {\n // @notice LayerZero endpoint will invoke this function to deliver the message on the destination\n // @param _srcChainId - the source endpoint identifier\n // @param _srcAddress - the source sending contract address from the source chain\n // @param _nonce - the ordered message nonce\n // @param _payload - the signed payload is the UA bytes has encoded to be sent\n function lzReceive(uint16 _srcChainId, bytes calldata _srcAddress, uint64 _nonce, bytes calldata _payload) external;\n}\n" + }, + "contracts/interfaces/external/layerZero/ILayerZeroUserApplicationConfig.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity >=0.5.0;\n\ninterface ILayerZeroUserApplicationConfig {\n // @notice set the configuration of the LayerZero messaging library of the specified version\n // @param _version - messaging library version\n // @param _chainId - the chainId for the pending config change\n // @param _configType - type of configuration. every messaging library has its own convention.\n // @param _config - configuration in the bytes. can encode arbitrary content.\n function setConfig(uint16 _version, uint16 _chainId, uint256 _configType, bytes calldata _config) external;\n\n // @notice set the send() LayerZero messaging library version to _version\n // @param _version - new messaging library version\n function setSendVersion(uint16 _version) external;\n\n // @notice set the lzReceive() LayerZero messaging library version to _version\n // @param _version - new messaging library version\n function setReceiveVersion(uint16 _version) external;\n\n // @notice Only when the UA needs to resume the message flow in blocking mode and clear the stored payload\n // @param _srcChainId - the chainId of the source chain\n // @param _srcAddress - the contract address of the source contract at the source chain\n function forceResumeReceive(uint16 _srcChainId, bytes calldata _srcAddress) external;\n}\n" + }, + "contracts/interfaces/external/lido/IStETH.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\n/// @title IStETH\n/// @author Angle Labs, Inc.\n/// @notice Interface for the `StETH` contract\n/// @dev This interface only contains functions of the `StETH` which are called by other contracts\n/// of this module\ninterface IStETH {\n function getPooledEthByShares(uint256 _sharesAmount) external view returns (uint256);\n\n event Submitted(address sender, uint256 amount, address referral);\n\n function submit(address) external payable returns (uint256);\n\n function getSharesByPooledEth(uint256 _ethAmount) external view returns (uint256);\n}\n" + }, + "contracts/interfaces/external/lido/IWStETH.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\n/// @title IWStETH\n/// @author Angle Labs, Inc.\n/// @notice Interface for the `WStETH` contract\n/// @dev This interface only contains functions of the `WStETH` which are called by other contracts\n/// of this module\ninterface IWStETH {\n function wrap(uint256 _stETHAmount) external returns (uint256);\n\n function stETH() external view returns (address);\n}\n" + }, + "contracts/interfaces/external/uniswap/IUniswapRouter.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\nstruct ExactInputParams {\n bytes path;\n address recipient;\n uint256 deadline;\n uint256 amountIn;\n uint256 amountOutMinimum;\n}\n\n/// @title Router token swapping functionality\n/// @notice Functions for swapping tokens via Uniswap V3\ninterface IUniswapV3Router {\n /// @notice Swaps `amountIn` of one token for as much as possible of another along the specified path\n /// @param params The parameters necessary for the multi-hop swap, encoded as `ExactInputParams` in calldata\n /// @return amountOut The amount of the received token\n function exactInput(ExactInputParams calldata params) external payable returns (uint256 amountOut);\n}\n\n/// @title Router for price estimation functionality\n/// @notice Functions for getting the price of one token with respect to another using Uniswap V2\n/// @dev This interface is only used for non critical elements of the protocol\ninterface IUniswapV2Router {\n /// @notice Given an input asset amount, returns the maximum output amount of the\n /// other asset (accounting for fees) given reserves.\n /// @param path Addresses of the pools used to get prices\n function getAmountsOut(uint256 amountIn, address[] calldata path) external view returns (uint256[] memory amounts);\n\n function swapExactTokensForTokens(\n uint256 swapAmount,\n uint256 minExpected,\n address[] calldata path,\n address receiver,\n uint256 swapDeadline\n ) external;\n}\n" + }, + "contracts/interfaces/external/uniswap/IUniswapV3Pool.sol": { + "content": "// SPDX-License-Identifier: GPL-2.0-or-later\npragma solidity >=0.5.0;\n\n/// @title Pool state that never changes\n/// @notice These parameters are fixed for a pool forever, i.e., the methods will always return the same values\ninterface IUniswapV3Pool {\n /// @notice The first of the two tokens of the pool, sorted by address\n /// @return The token contract address\n function token0() external view returns (address);\n\n /// @notice The second of the two tokens of the pool, sorted by address\n /// @return The token contract address\n function token1() external view returns (address);\n}\n" + }, + "contracts/interfaces/governance/IVeBoostProxy.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\n/// @title IVeBoostProxy\n/// @author Angle Labs, Inc.\n/// @notice Interface for the `VeBoostProxy` contract\n/// @dev This interface only contains functions of the contract which are called by other contracts\n/// of this module\n/// @dev The `veBoostProxy` contract used by Angle is a full fork of Curve Finance implementation\ninterface IVeBoostProxy {\n /// @notice Reads the adjusted veANGLE balance of an address (adjusted by delegation)\n //solhint-disable-next-line\n function adjusted_balance_of(address) external view returns (uint256);\n}\n" + }, + "contracts/interfaces/IAgToken.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\nimport \"@openzeppelin/contracts-upgradeable/token/ERC20/IERC20Upgradeable.sol\";\n\n/// @title IAgToken\n/// @author Angle Labs, Inc.\n/// @notice Interface for the stablecoins `AgToken` contracts\n/// @dev This interface only contains functions of the `AgToken` contract which are called by other contracts\n/// of this module or of the first module of the Angle Protocol\ninterface IAgToken is IERC20Upgradeable {\n // ======================= Minter Role Only Functions ===========================\n\n /// @notice Lets the `StableMaster` contract or another whitelisted contract mint agTokens\n /// @param account Address to mint to\n /// @param amount Amount to mint\n /// @dev The contracts allowed to issue agTokens are the `StableMaster` contract, `VaultManager` contracts\n /// associated to this stablecoin as well as the flash loan module (if activated) and potentially contracts\n /// whitelisted by governance\n function mint(address account, uint256 amount) external;\n\n /// @notice Burns `amount` tokens from a `burner` address after being asked to by `sender`\n /// @param amount Amount of tokens to burn\n /// @param burner Address to burn from\n /// @param sender Address which requested the burn from `burner`\n /// @dev This method is to be called by a contract with the minter right after being requested\n /// to do so by a `sender` address willing to burn tokens from another `burner` address\n /// @dev The method checks the allowance between the `sender` and the `burner`\n function burnFrom(uint256 amount, address burner, address sender) external;\n\n /// @notice Burns `amount` tokens from a `burner` address\n /// @param amount Amount of tokens to burn\n /// @param burner Address to burn from\n /// @dev This method is to be called by a contract with a minter right on the AgToken after being\n /// requested to do so by an address willing to burn tokens from its address\n function burnSelf(uint256 amount, address burner) external;\n\n // ========================= Treasury Only Functions ===========================\n\n /// @notice Adds a minter in the contract\n /// @param minter Minter address to add\n /// @dev Zero address checks are performed directly in the `Treasury` contract\n function addMinter(address minter) external;\n\n /// @notice Removes a minter from the contract\n /// @param minter Minter address to remove\n /// @dev This function can also be called by a minter wishing to revoke itself\n function removeMinter(address minter) external;\n\n /// @notice Sets a new treasury contract\n /// @param _treasury New treasury address\n function setTreasury(address _treasury) external;\n\n // ========================= External functions ================================\n\n /// @notice Checks whether an address has the right to mint agTokens\n /// @param minter Address for which the minting right should be checked\n /// @return Whether the address has the right to mint agTokens or not\n function isMinter(address minter) external view returns (bool);\n\n /// @notice Get the associated treasury\n function treasury() external view returns (address);\n}\n" + }, + "contracts/interfaces/IAgTokenSideChainMultiBridge.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\nimport \"@openzeppelin/contracts-upgradeable/token/ERC20/extensions/draft-IERC20PermitUpgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/token/ERC20/IERC20Upgradeable.sol\";\n\n/// @title IAgTokenSideChainMultiBridge\n/// @author Angle Labs, Inc.\n/// @notice Interface for the canonical `AgToken` contracts\n/// @dev This interface only contains functions useful for bridge tokens to interact with the canonical token\ninterface IAgTokenSideChainMultiBridge is IERC20PermitUpgradeable, IERC20Upgradeable {\n /// @notice Mints the canonical token from a supported bridge token\n /// @param bridgeToken Bridge token to use to mint\n /// @param amount Amount of bridge tokens to send\n /// @param to Address to which the stablecoin should be sent\n /// @return Amount of the canonical stablecoin actually minted\n /// @dev Some fees may be taken by the protocol depending on the token used and on the address calling\n function swapIn(address bridgeToken, uint256 amount, address to) external returns (uint256);\n\n /// @notice Burns the canonical token in exchange for a bridge token\n /// @param bridgeToken Bridge token required\n /// @param amount Amount of canonical tokens to burn\n /// @param to Address to which the bridge token should be sent\n /// @return Amount of bridge tokens actually sent back\n /// @dev Some fees may be taken by the protocol depending on the token used and on the address calling\n function swapOut(address bridgeToken, uint256 amount, address to) external returns (uint256);\n}\n" + }, + "contracts/interfaces/IAngleRouter.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\n/// @title IAngleRouter\n/// @author Angle Labs, Inc.\n/// @notice Interface for the `AngleRouter` contract\n/// @dev This interface only contains functions of the `AngleRouter01` contract which are called by other contracts\n/// of this module\ninterface IAngleRouter {\n function mint(\n address user,\n uint256 amount,\n uint256 minStableAmount,\n address stablecoin,\n address collateral\n ) external;\n\n function burn(address user, uint256 amount, uint256 minAmountOut, address stablecoin, address collateral) external;\n\n function mapPoolManagers(\n address stableMaster,\n address collateral\n ) external view returns (address poolManager, address perpetualManager, address sanToken, address gauge);\n}\n" + }, + "contracts/interfaces/IAngleRouterSidechain.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\n/// @notice Action types\nenum ActionType {\n transfer,\n wrap,\n wrapNative,\n sweep,\n sweepNative,\n unwrap,\n unwrapNative,\n swapIn,\n swapOut,\n uniswapV3,\n oneInch,\n claimRewards,\n gaugeDeposit,\n borrower\n}\n\n/// @notice Data needed to get permits\nstruct PermitType {\n address token;\n address owner;\n uint256 value;\n uint256 deadline;\n uint8 v;\n bytes32 r;\n bytes32 s;\n}\n\n/// @title IAngleRouterSidechain\n/// @author Angle Labs, Inc.\n/// @notice Interface for the `AngleRouter` contract on other chains\ninterface IAngleRouterSidechain {\n function mixer(PermitType[] memory paramsPermit, ActionType[] memory actions, bytes[] calldata data) external;\n}\n" + }, + "contracts/interfaces/ICoreBorrow.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\n/// @title ICoreBorrow\n/// @author Angle Labs, Inc.\n/// @notice Interface for the `CoreBorrow` contract\n/// @dev This interface only contains functions of the `CoreBorrow` contract which are called by other contracts\n/// of this module\ninterface ICoreBorrow {\n /// @notice Checks if an address corresponds to a treasury of a stablecoin with a flash loan\n /// module initialized on it\n /// @param treasury Address to check\n /// @return Whether the address has the `FLASHLOANER_TREASURY_ROLE` or not\n function isFlashLoanerTreasury(address treasury) external view returns (bool);\n\n /// @notice Checks whether an address is governor of the Angle Protocol or not\n /// @param admin Address to check\n /// @return Whether the address has the `GOVERNOR_ROLE` or not\n function isGovernor(address admin) external view returns (bool);\n\n /// @notice Checks whether an address is governor or a guardian of the Angle Protocol or not\n /// @param admin Address to check\n /// @return Whether the address has the `GUARDIAN_ROLE` or not\n /// @dev Governance should make sure when adding a governor to also give this governor the guardian\n /// role by calling the `addGovernor` function\n function isGovernorOrGuardian(address admin) external view returns (bool);\n}\n" + }, + "contracts/interfaces/IFlashAngle.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\nimport \"./IAgToken.sol\";\nimport \"./ICoreBorrow.sol\";\n\n/// @title IFlashAngle\n/// @author Angle Labs, Inc.\n/// @notice Interface for the `FlashAngle` contract\n/// @dev This interface only contains functions of the contract which are called by other contracts\n/// of this module\ninterface IFlashAngle {\n /// @notice Reference to the `CoreBorrow` contract managing the FlashLoan module\n function core() external view returns (ICoreBorrow);\n\n /// @notice Sends the fees taken from flash loans to the treasury contract associated to the stablecoin\n /// @param stablecoin Stablecoin from which profits should be sent\n /// @return balance Amount of profits sent\n /// @dev This function can only be called by the treasury contract\n function accrueInterestToTreasury(IAgToken stablecoin) external returns (uint256 balance);\n\n /// @notice Adds support for a stablecoin\n /// @param _treasury Treasury associated to the stablecoin to add support for\n /// @dev This function can only be called by the `CoreBorrow` contract\n function addStablecoinSupport(address _treasury) external;\n\n /// @notice Removes support for a stablecoin\n /// @param _treasury Treasury associated to the stablecoin to remove support for\n /// @dev This function can only be called by the `CoreBorrow` contract\n function removeStablecoinSupport(address _treasury) external;\n\n /// @notice Sets a new core contract\n /// @param _core Core contract address to set\n /// @dev This function can only be called by the `CoreBorrow` contract\n function setCore(address _core) external;\n}\n" + }, + "contracts/interfaces/IKeeperRegistry.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\nimport \"@openzeppelin/contracts-upgradeable/token/ERC20/IERC20Upgradeable.sol\";\n\n/// @title IKeeperRegistry\n/// @author Angle Labs, Inc.\ninterface IKeeperRegistry {\n /// @notice Checks whether an address is whitelisted during oracle updates\n /// @param caller Address for which the whitelist should be checked\n /// @return Whether the address is trusted or not\n function isTrusted(address caller) external view returns (bool);\n}\n" + }, + "contracts/interfaces/ILiquidityGauge.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.7;\n\ninterface ILiquidityGauge {\n function deposit(\n uint256 _value,\n address _addr,\n // solhint-disable-next-line\n bool _claim_rewards\n ) external;\n\n function withdraw(\n uint256 _value,\n // solhint-disable-next-line\n bool _claim_rewards\n ) external;\n\n // solhint-disable-next-line\n function claim_rewards(address _addr, address _receiver) external;\n\n // solhint-disable-next-line\n function claimable_reward(address _addr, address _reward_token) external view returns (uint256 amount);\n\n /// @dev Only for testing purposes\n // solhint-disable-next-line\n function deposit_reward_token(address _rewardToken, uint256 _amount) external;\n}\n" + }, + "contracts/interfaces/IOracle.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\nimport \"./ITreasury.sol\";\nimport \"@chainlink/contracts/src/v0.8/interfaces/AggregatorV3Interface.sol\";\n\n/// @title IOracle\n/// @author Angle Labs, Inc.\n/// @notice Interface for the `Oracle` contract\n/// @dev This interface only contains functions of the contract which are called by other contracts\n/// of this module\ninterface IOracle {\n /// @notice Reads the rate from the Chainlink circuit and other data provided\n /// @return quoteAmount The current rate between the in-currency and out-currency in the base\n /// of the out currency\n /// @dev For instance if the out currency is EUR (and hence agEUR), then the base of the returned\n /// value is 10**18\n function read() external view returns (uint256);\n\n /// @notice Changes the treasury contract\n /// @param _treasury Address of the new treasury contract\n /// @dev This function can be called by an approved `VaultManager` contract which can call\n /// this function after being requested to do so by a `treasury` contract\n /// @dev In some situations (like reactor contracts), the `VaultManager` may not directly be linked\n /// to the `oracle` contract and as such we may need governors to be able to call this function as well\n function setTreasury(address _treasury) external;\n\n /// @notice Reference to the `treasury` contract handling this `VaultManager`\n function treasury() external view returns (ITreasury treasury);\n\n /// @notice Array with the list of Chainlink feeds in the order in which they are read\n function circuitChainlink() external view returns (AggregatorV3Interface[] memory);\n}\n" + }, + "contracts/interfaces/ISwapper.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\nimport \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\n\n/// @title ISwapper\n/// @author Angle Labs, Inc.\n/// @notice Interface for Swapper contracts\n/// @dev This interface defines the key functions `Swapper` contracts should have when interacting with\n/// Angle\ninterface ISwapper {\n /// @notice Notifies a contract that an address should be given `outToken` from `inToken`\n /// @param inToken Address of the token received\n /// @param outToken Address of the token to obtain\n /// @param outTokenRecipient Address to which the outToken should be sent\n /// @param outTokenOwed Minimum amount of outToken the `outTokenRecipient` address should have at the end of the call\n /// @param inTokenObtained Amount of collateral obtained by a related address prior\n /// to the call to this function\n /// @param data Extra data needed (to encode Uniswap swaps for instance)\n function swap(\n IERC20 inToken,\n IERC20 outToken,\n address outTokenRecipient,\n uint256 outTokenOwed,\n uint256 inTokenObtained,\n bytes calldata data\n ) external;\n}\n" + }, + "contracts/interfaces/ITreasury.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\nimport \"./IAgToken.sol\";\nimport \"./ICoreBorrow.sol\";\nimport \"./IFlashAngle.sol\";\n\n/// @title ITreasury\n/// @author Angle Labs, Inc.\n/// @notice Interface for the `Treasury` contract\n/// @dev This interface only contains functions of the `Treasury` which are called by other contracts\n/// of this module\ninterface ITreasury {\n /// @notice Stablecoin handled by this `treasury` contract\n function stablecoin() external view returns (IAgToken);\n\n /// @notice Checks whether a given address has the governor role\n /// @param admin Address to check\n /// @return Whether the address has the governor role\n /// @dev Access control is only kept in the `CoreBorrow` contract\n function isGovernor(address admin) external view returns (bool);\n\n /// @notice Checks whether a given address has the guardian or the governor role\n /// @param admin Address to check\n /// @return Whether the address has the guardian or the governor role\n /// @dev Access control is only kept in the `CoreBorrow` contract which means that this function\n /// queries the `CoreBorrow` contract\n function isGovernorOrGuardian(address admin) external view returns (bool);\n\n /// @notice Checks whether a given address has well been initialized in this contract\n /// as a `VaultManager`\n /// @param _vaultManager Address to check\n /// @return Whether the address has been initialized or not\n function isVaultManager(address _vaultManager) external view returns (bool);\n\n /// @notice Sets a new flash loan module for this stablecoin\n /// @param _flashLoanModule Reference to the new flash loan module\n /// @dev This function removes the minting right to the old flash loan module and grants\n /// it to the new module\n function setFlashLoanModule(address _flashLoanModule) external;\n\n /// @notice Gets the vault manager list\n function vaultManagerList(uint256 i) external returns (address);\n}\n" + }, + "contracts/interfaces/IVaultManager.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\nimport \"@openzeppelin/contracts/interfaces/IERC721Metadata.sol\";\nimport \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\nimport \"./ITreasury.sol\";\nimport \"./IOracle.sol\";\n\n// ========================= Key Structs and Enums =============================\n\n/// @notice Parameters associated to a given `VaultManager` contract: these all correspond\n/// to parameters which signification is detailed in the `VaultManagerStorage` file\nstruct VaultParameters {\n uint256 debtCeiling;\n uint64 collateralFactor;\n uint64 targetHealthFactor;\n uint64 interestRate;\n uint64 liquidationSurcharge;\n uint64 maxLiquidationDiscount;\n bool whitelistingActivated;\n uint256 baseBoost;\n}\n\n/// @notice Data stored to track someone's loan (or equivalently called position)\nstruct Vault {\n // Amount of collateral deposited in the vault, in collateral decimals. For example, if the collateral\n // is USDC with 6 decimals, then `collateralAmount` will be in base 10**6\n uint256 collateralAmount;\n // Normalized value of the debt (that is to say of the stablecoins borrowed). It is expressed\n // in the base of Angle stablecoins (i.e. `BASE_TOKENS = 10**18`)\n uint256 normalizedDebt;\n}\n\n/// @notice For a given `vaultID`, this encodes a liquidation opportunity that is to say details about the maximum\n/// amount that could be repaid by liquidating the position\n/// @dev All the values are null in the case of a vault which cannot be liquidated under these conditions\nstruct LiquidationOpportunity {\n // Maximum stablecoin amount that can be repaid upon liquidating the vault\n uint256 maxStablecoinAmountToRepay;\n // Collateral amount given to the person in the case where the maximum amount to repay is given\n uint256 maxCollateralAmountGiven;\n // Threshold value of stablecoin amount to repay: it is ok for a liquidator to repay below threshold,\n // but if this threshold is non null and the liquidator wants to repay more than threshold, it should repay\n // the max stablecoin amount given in this vault\n uint256 thresholdRepayAmount;\n // Discount proposed to the liquidator on the collateral\n uint256 discount;\n // Amount of debt in the vault\n uint256 currentDebt;\n}\n\n/// @notice Data stored during a liquidation process to keep in memory what's due to a liquidator and some\n/// essential data for vaults being liquidated\nstruct LiquidatorData {\n // Current amount of stablecoins the liquidator should give to the contract\n uint256 stablecoinAmountToReceive;\n // Current amount of collateral the contract should give to the liquidator\n uint256 collateralAmountToGive;\n // Bad debt accrued across the liquidation process\n uint256 badDebtFromLiquidation;\n // Oracle value (in stablecoin base) at the time of the liquidation\n uint256 oracleValue;\n // Value of the `interestAccumulator` at the time of the call\n uint256 newInterestAccumulator;\n}\n\n/// @notice Data to track during a series of action the amount to give or receive in stablecoins and collateral\n/// to the caller or associated addresses\nstruct PaymentData {\n // Stablecoin amount the contract should give\n uint256 stablecoinAmountToGive;\n // Stablecoin amount owed to the contract\n uint256 stablecoinAmountToReceive;\n // Collateral amount the contract should give\n uint256 collateralAmountToGive;\n // Collateral amount owed to the contract\n uint256 collateralAmountToReceive;\n}\n\n/// @notice Actions possible when composing calls to the different entry functions proposed\nenum ActionType {\n createVault,\n closeVault,\n addCollateral,\n removeCollateral,\n repayDebt,\n borrow,\n getDebtIn,\n permit\n}\n\n// ========================= Interfaces =============================\n\n/// @title IVaultManagerFunctions\n/// @author Angle Labs, Inc.\n/// @notice Interface for the `VaultManager` contract\n/// @dev This interface only contains functions of the contract which are called by other contracts\n/// of this module (without getters)\ninterface IVaultManagerFunctions {\n /// @notice Accrues interest accumulated across all vaults to the surplus and sends the surplus to the treasury\n /// @return surplusValue Value of the surplus communicated to the `Treasury`\n /// @return badDebtValue Value of the bad debt communicated to the `Treasury`\n /// @dev `surplus` and `badDebt` should be reset to 0 once their current value have been given to the `treasury` contract\n function accrueInterestToTreasury() external returns (uint256 surplusValue, uint256 badDebtValue);\n\n /// @notice Removes debt from a vault after being requested to do so by another `VaultManager` contract\n /// @param vaultID ID of the vault to remove debt from\n /// @param amountStablecoins Amount of stablecoins to remove from the debt: this amount is to be converted to an\n /// internal debt amount\n /// @param senderBorrowFee Borrowing fees from the contract which requested this: this is to make sure that people are not\n /// arbitraging difference in minting fees\n /// @param senderRepayFee Repay fees from the contract which requested this: this is to make sure that people are not arbitraging\n /// differences in repay fees\n /// @dev This function can only be called from a vaultManager registered in the same Treasury\n function getDebtOut(\n uint256 vaultID,\n uint256 amountStablecoins,\n uint256 senderBorrowFee,\n uint256 senderRepayFee\n ) external;\n\n /// @notice Gets the current debt of a vault\n /// @param vaultID ID of the vault to check\n /// @return Debt of the vault\n function getVaultDebt(uint256 vaultID) external view returns (uint256);\n\n /// @notice Gets the total debt across all vaults\n /// @return Total debt across all vaults, taking into account the interest accumulated\n /// over time\n function getTotalDebt() external view returns (uint256);\n\n /// @notice Sets the treasury contract\n /// @param _treasury New treasury contract\n /// @dev All required checks when setting up a treasury contract are performed in the contract\n /// calling this function\n function setTreasury(address _treasury) external;\n\n /// @notice Creates a vault\n /// @param toVault Address for which the va\n /// @return vaultID ID of the vault created\n /// @dev This function just creates the vault without doing any collateral or\n function createVault(address toVault) external returns (uint256);\n\n /// @notice Allows composability between calls to the different entry points of this module. Any user calling\n /// this function can perform any of the allowed actions in the order of their choice\n /// @param actions Set of actions to perform\n /// @param datas Data to be decoded for each action: it can include like the `vaultID` or the `stablecoinAmount` to borrow\n /// @param from Address from which stablecoins will be taken if one action includes burning stablecoins. This address\n /// should either be the `msg.sender` or be approved by the latter\n /// @param to Address to which stablecoins and/or collateral will be sent in case of\n /// @param who Address of the contract to handle in case of repayment of stablecoins from received collateral\n /// @param repayData Data to pass to the repayment contract in case of\n /// @return paymentData Struct containing the accounting changes from the protocol's perspective (like how much of collateral\n /// or how much has been received). Note that the values in the struct are not aggregated and you could have in the output\n /// a positive amount of stablecoins to receive as well as a positive amount of stablecoins to give\n /// @dev This function is optimized to reduce gas cost due to payment from or to the user and that expensive calls\n /// or computations (like `oracleValue`) are done only once\n /// @dev When specifying `vaultID` in `data`, it is important to know that if you specify `vaultID = 0`, it will simply\n /// use the latest `vaultID`. This is the default behavior, and unless you're engaging into some complex protocol actions\n /// it is encouraged to use `vaultID = 0` only when the first action of the batch is `createVault`\n function angle(\n ActionType[] memory actions,\n bytes[] memory datas,\n address from,\n address to,\n address who,\n bytes memory repayData\n ) external returns (PaymentData memory paymentData);\n\n /// @notice This function is a wrapper built on top of the function above. It enables users to interact with the contract\n /// without having to provide `who` and `repayData` parameters\n function angle(\n ActionType[] memory actions,\n bytes[] memory datas,\n address from,\n address to\n ) external returns (PaymentData memory paymentData);\n\n /// @notice Initializes the `VaultManager` contract\n /// @param _treasury Treasury address handling the contract\n /// @param _collateral Collateral supported by this contract\n /// @param _oracle Oracle contract used\n /// @param _symbol Symbol used to define the `VaultManager` name and symbol\n /// @dev The parameters and the oracle are the only elements which could be modified once the\n /// contract has been initialized\n /// @dev For the contract to be fully initialized, governance needs to set the parameters for the liquidation\n /// boost\n function initialize(\n ITreasury _treasury,\n IERC20 _collateral,\n IOracle _oracle,\n VaultParameters calldata params,\n string memory _symbol\n ) external;\n\n /// @notice Minimum amount of debt a vault can have, expressed in `BASE_TOKENS` that is to say the base of the agTokens\n function dust() external view returns (uint256);\n\n /// @notice Pauses external permissionless functions of the contract\n function togglePause() external;\n}\n\n/// @title IVaultManagerStorage\n/// @author Angle Labs, Inc.\n/// @notice Interface for the `VaultManager` contract\n/// @dev This interface contains getters of the contract's public variables used by other contracts\n/// of this module\ninterface IVaultManagerStorage {\n /// @notice Encodes the maximum ratio stablecoin/collateral a vault can have before being liquidated. It's what\n /// determines the minimum collateral ratio of a position\n function collateralFactor() external view returns (uint64);\n\n /// @notice Stablecoin handled by this contract. Another `VaultManager` contract could have\n /// the same rights as this `VaultManager` on the stablecoin contract\n function stablecoin() external view returns (IAgToken);\n\n /// @notice Reference to the `treasury` contract handling this `VaultManager`\n function treasury() external view returns (ITreasury);\n\n /// @notice Oracle contract to get access to the price of the collateral with respect to the stablecoin\n function oracle() external view returns (IOracle);\n\n /// @notice The `interestAccumulator` variable keeps track of the interest that should accrue to the protocol.\n /// The stored value is not necessarily the true value: this one is recomputed every time an action takes place\n /// within the protocol. It is in base `BASE_INTEREST`\n function interestAccumulator() external view returns (uint256);\n\n /// @notice Reference to the collateral handled by this `VaultManager`\n function collateral() external view returns (IERC20);\n\n /// @notice Total normalized amount of stablecoins borrowed, not taking into account the potential bad debt accumulated\n /// This value is expressed in the base of Angle stablecoins (`BASE_TOKENS = 10**18`)\n function totalNormalizedDebt() external view returns (uint256);\n\n /// @notice Maximum amount of stablecoins that can be issued with this contract. It is expressed in `BASE_TOKENS`\n function debtCeiling() external view returns (uint256);\n\n /// @notice Maps a `vaultID` to its data (namely collateral amount and normalized debt)\n function vaultData(uint256 vaultID) external view returns (uint256 collateralAmount, uint256 normalizedDebt);\n\n /// @notice ID of the last vault created. The `vaultIDCount` variables serves as a counter to generate a unique\n /// `vaultID` for each vault: it is like `tokenID` in basic ERC721 contracts\n function vaultIDCount() external view returns (uint256);\n}\n\n/// @title IVaultManager\n/// @author Angle Labs, Inc.\n/// @notice Interface for the `VaultManager` contract\ninterface IVaultManager is IVaultManagerFunctions, IVaultManagerStorage, IERC721Metadata {\n function isApprovedOrOwner(address spender, uint256 vaultID) external view returns (bool);\n}\n\n/// @title IVaultManagerListing\n/// @author Angle Labs, Inc.\n/// @notice Interface for the `VaultManagerListing` contract\ninterface IVaultManagerListing is IVaultManager {\n /// @notice Get the collateral owned by `user` in the contract\n /// @dev This function effectively sums the collateral amounts of all the vaults owned by `user`\n function getUserCollateral(address user) external view returns (uint256);\n}\n" + }, + "contracts/keeperMulticall/KeeperMulticall.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\nimport \"@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/access/AccessControlUpgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol\";\nimport \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\nimport \"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\";\nimport \"./RevertReasonParser.sol\";\n\n/// @title KeeperMulticall\n/// @notice Allows an authorized caller (keeper) to execute multiple actions in a single tx.\n/// @author Angle Labs, Inc.\n/// @dev Special features:\n/// - ability to pay the miner (for private Flashbots transactions)\n/// - swap tokens through 1inch\n/// @dev Tx need to be encoded as an array of Action. The flag `isDelegateCall` is used for calling functions within this same contract\ncontract KeeperMulticall is Initializable, AccessControlUpgradeable {\n using SafeERC20 for IERC20;\n\n bytes32 public constant KEEPER_ROLE = keccak256(\"KEEPER_ROLE\");\n\n //solhint-disable-next-line\n address private constant _oneInch = 0x1111111254fb6c44bAC0beD2854e76F90643097d;\n\n struct Action {\n address target;\n bytes data;\n bool isDelegateCall;\n }\n\n event LogAction(address indexed target, bytes data);\n event SentToMiner(uint256 indexed value);\n event Recovered(address indexed tokenAddress, address indexed to, uint256 amount);\n\n error AmountOutTooLow(uint256 amount, uint256 min);\n error BalanceTooLow();\n error FlashbotsErrorPayingMiner(uint256 value);\n error IncompatibleLengths();\n error RevertBytes();\n error WrongAmount();\n error ZeroAddress();\n\n constructor() initializer {}\n\n function initialize(address keeper) external initializer {\n __AccessControl_init();\n\n _setupRole(KEEPER_ROLE, keeper);\n _setRoleAdmin(KEEPER_ROLE, KEEPER_ROLE);\n }\n\n /// @notice Allows an authorized keeper to execute multiple actions in a single step\n /// @param actions Actions to be executed\n /// @param percentageToMiner Percentage to pay to miner expressed in bps (10000)\n /// @dev This is the main entry point for actions to be executed. The `isDelegateCall` flag is used for calling function inside this `KeeperMulticall` contract,\n /// if we call other contracts, the flag should be false\n function executeActions(\n Action[] memory actions,\n uint256 percentageToMiner\n ) external payable onlyRole(KEEPER_ROLE) returns (bytes[] memory) {\n uint256 numberOfActions = actions.length;\n if (numberOfActions == 0) revert IncompatibleLengths();\n\n bytes[] memory returnValues = new bytes[](numberOfActions + 1);\n\n uint256 balanceBefore = address(this).balance;\n\n for (uint256 i; i < numberOfActions; ++i) {\n returnValues[i] = _executeAction(actions[i]);\n }\n\n if (percentageToMiner != 0) {\n if (percentageToMiner >= 10000) revert WrongAmount();\n uint256 balanceAfter = address(this).balance;\n if (balanceAfter > balanceBefore) {\n uint256 amountToMiner = ((balanceAfter - balanceBefore) * percentageToMiner) / 10000;\n returnValues[numberOfActions] = payFlashbots(amountToMiner);\n }\n }\n\n return returnValues;\n }\n\n /// @notice Gets the action address and data and executes it\n /// @param action Action to be executed\n function _executeAction(Action memory action) internal returns (bytes memory) {\n bool success;\n bytes memory response;\n\n if (action.isDelegateCall) {\n //solhint-disable-next-line\n (success, response) = action.target.delegatecall(action.data);\n } else {\n //solhint-disable-next-line\n (success, response) = action.target.call(action.data);\n }\n\n require(success, RevertReasonParser.parse(response, \"action reverted: \"));\n emit LogAction(action.target, action.data);\n return response;\n }\n\n /// @notice Ability to pay miner directly. Used for Flashbots to execute private transactions\n /// @param value Value to be sent\n function payFlashbots(uint256 value) public payable onlyRole(KEEPER_ROLE) returns (bytes memory) {\n //solhint-disable-next-line\n (bool success, bytes memory response) = block.coinbase.call{ value: value }(\"\");\n if (!success) revert FlashbotsErrorPayingMiner(value);\n emit SentToMiner(value);\n return response;\n }\n\n /// @notice Used to check the balances the token holds for each token. If we don't have enough of a token, we revert the tx\n /// @param tokens Array of tokens to check\n /// @param minBalances Array of balances for each token\n function finalBalanceCheck(IERC20[] memory tokens, uint256[] memory minBalances) external view returns (bool) {\n uint256 tokensLength = tokens.length;\n if (tokensLength == 0 || tokensLength != minBalances.length) revert IncompatibleLengths();\n\n for (uint256 i; i < tokensLength; ++i) {\n if (address(tokens[i]) == 0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE) {\n if (address(this).balance < minBalances[i]) revert BalanceTooLow();\n } else {\n if (tokens[i].balanceOf(address(this)) < minBalances[i]) revert BalanceTooLow();\n }\n }\n\n return true;\n }\n\n /// @notice Swap token to another through 1Inch\n /// @param minAmountOut Minimum amount of `out` token to receive for the swap to happen\n /// @param payload Bytes needed for 1Inch API\n function swapToken(uint256 minAmountOut, bytes memory payload) external onlyRole(KEEPER_ROLE) {\n //solhint-disable-next-line\n (bool success, bytes memory result) = _oneInch.call(payload);\n if (!success) _revertBytes(result);\n\n uint256 amountOut = abi.decode(result, (uint256));\n if (amountOut < minAmountOut) revert AmountOutTooLow(amountOut, minAmountOut);\n }\n\n /// @notice Copied from 1Inch contract, used to revert if there is an error\n function _revertBytes(bytes memory errMsg) internal pure {\n if (errMsg.length != 0) {\n //solhint-disable-next-line\n assembly {\n revert(add(32, errMsg), mload(errMsg))\n }\n }\n revert RevertBytes();\n }\n\n /// @notice Approve a `spender` for `token`\n /// @param token Address of the token to approve\n /// @param spender Address of the spender to approve\n /// @param amount Amount to approve\n function approve(IERC20 token, address spender, uint256 amount) external onlyRole(KEEPER_ROLE) {\n uint256 currentAllowance = token.allowance(address(this), spender);\n if (currentAllowance < amount) {\n token.safeIncreaseAllowance(spender, amount - currentAllowance);\n } else if (currentAllowance > amount) {\n token.safeDecreaseAllowance(spender, currentAllowance - amount);\n }\n }\n\n receive() external payable {}\n\n /// @notice Withdraw stuck funds\n /// @param token Address of the token to recover\n /// @param receiver Address where to send the tokens\n /// @param amount Amount to recover\n function withdrawStuckFunds(address token, address receiver, uint256 amount) external onlyRole(KEEPER_ROLE) {\n if (receiver == address(0)) revert ZeroAddress();\n if (token == 0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE) {\n payable(receiver).transfer(amount);\n } else {\n IERC20(token).safeTransfer(receiver, amount);\n }\n\n emit Recovered(token, receiver, amount);\n }\n}\n" + }, + "contracts/keeperMulticall/MulticallWithFailure.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.12;\n\n/// @title MultiCallWithFailure\n/// @author Angle Labs, Inc.\n/// @notice Multicall contract allowing subcalls to fail without reverting the entire call\ncontract MultiCallWithFailure {\n error SubcallFailed();\n\n struct Call {\n address target;\n bytes data;\n bool canFail;\n }\n\n function multiCall(Call[] memory calls) external view returns (bytes[] memory) {\n bytes[] memory results = new bytes[](calls.length);\n\n for (uint256 i; i < calls.length; ++i) {\n (bool success, bytes memory result) = calls[i].target.staticcall(calls[i].data);\n if (!calls[i].canFail) {\n if (!success) {\n revert SubcallFailed();\n }\n }\n results[i] = result;\n }\n\n return results;\n }\n}\n" + }, + "contracts/keeperMulticall/RevertReasonParser.sol": { + "content": "// SPDX-License-Identifier: GNU-3\n\npragma solidity ^0.8.12;\n\n/// @title RevertReasonParser\n/// @author 1Inch team, taken from:\n/// - https://docs.1inch.io/docs/limit-order-protocol/smart-contract/libraries/RevertReasonParser/\n/// - https://etherscan.io/address/0x1111111254fb6c44bAC0beD2854e76F90643097d#code\nlibrary RevertReasonParser {\n bytes4 private constant _PANIC_SELECTOR = bytes4(keccak256(\"Panic(uint256)\"));\n bytes4 private constant _ERROR_SELECTOR = bytes4(keccak256(\"Error(string)\"));\n\n function parse(bytes memory data, string memory prefix) internal pure returns (string memory) {\n if (data.length >= 4) {\n bytes4 selector;\n //solhint-disable-next-line\n assembly {\n selector := mload(add(data, 0x20))\n }\n\n // 68 = 4-byte selector + 32 bytes offset + 32 bytes length\n if (selector == _ERROR_SELECTOR && data.length >= 68) {\n uint256 offset;\n bytes memory reason;\n // solhint-disable no-inline-assembly\n assembly {\n // 36 = 32 bytes data length + 4-byte selector\n offset := mload(add(data, 36))\n reason := add(data, add(36, offset))\n }\n /*\n revert reason is padded up to 32 bytes with ABI encoder: Error(string)\n also sometimes there is extra 32 bytes of zeros padded in the end:\n https://github.com/ethereum/solidity/issues/10170\n because of that we can't check for equality and instead check\n that offset + string length + extra 36 bytes is less than overall data length\n */\n require(data.length >= 36 + offset + reason.length, \"Invalid revert reason\");\n return string(abi.encodePacked(prefix, \"Error(\", reason, \")\"));\n }\n // 36 = 4-byte selector + 32 bytes integer\n else if (selector == _PANIC_SELECTOR && data.length == 36) {\n uint256 code;\n // solhint-disable no-inline-assembly\n assembly {\n // 36 = 32 bytes data length + 4-byte selector\n code := mload(add(data, 36))\n }\n return string(abi.encodePacked(prefix, \"Panic(\", _toHex(code), \")\"));\n }\n }\n\n return string(abi.encodePacked(prefix, \"Unknown(\", _toHex(data), \")\"));\n }\n\n function _toHex(uint256 value) private pure returns (string memory) {\n return _toHex(abi.encodePacked(value));\n }\n\n function _toHex(bytes memory data) private pure returns (string memory) {\n bytes16 alphabet = 0x30313233343536373839616263646566;\n bytes memory str = new bytes(2 + data.length * 2);\n str[0] = \"0\";\n str[1] = \"x\";\n for (uint256 i; i < data.length; ++i) {\n str[2 * i + 2] = alphabet[uint8(data[i] >> 4)];\n str[2 * i + 3] = alphabet[uint8(data[i] & 0x0f)];\n }\n return string(str);\n }\n}\n" + }, + "contracts/mock/Mock1Inch.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.12;\n\nimport \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\nimport \"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\";\n\ncontract Mock1Inch {\n using SafeERC20 for IERC20;\n\n function swap(address tokenIn, uint256 amountIn, address to, address tokenOut, uint256 amountOut) external {\n IERC20(tokenIn).safeTransferFrom(msg.sender, to, amountIn);\n if (tokenOut == 0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE) {\n //solhint-disable-next-line\n (bool sent, bytes memory data) = msg.sender.call{ value: amountOut }(\"\");\n data;\n require(sent, \"Failed to send Ether\");\n } else {\n IERC20(tokenOut).safeTransferFrom(to, msg.sender, amountOut);\n }\n }\n\n receive() external payable {}\n}\n" + }, + "contracts/mock/MockAnything.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.12;\n\ncontract MockAnything {\n uint256 public stateVar = 1;\n\n error CustomError();\n error CustomErrorWithValue(uint256);\n\n function fail(uint256 value) external view returns (uint256) {\n stateVar;\n if (value < 10) {\n revert CustomError();\n }\n if (value < 20) {\n revert CustomErrorWithValue(value);\n }\n return value + 1;\n }\n\n function modifyState(uint256 value) external {\n stateVar = value;\n }\n}\n" + }, + "contracts/mock/MockChainlinkOracle.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.7;\n\ninterface MockAggregatorV3Interface {\n function decimals() external view returns (uint8);\n\n function description() external view returns (string memory);\n\n function version() external view returns (uint256);\n\n function getRoundData(\n uint80 _roundId\n )\n external\n view\n returns (uint80 roundId, int256 answer, uint256 startedAt, uint256 updatedAt, uint80 answeredInRound);\n\n function latestRoundData()\n external\n view\n returns (uint80 roundId, int256 answer, uint256 startedAt, uint256 updatedAt, uint80 answeredInRound);\n}\n\ncontract MockChainlinkOracle is MockAggregatorV3Interface {\n uint80 public roundId = 0;\n uint8 public keyDecimals = 0;\n\n struct Entry {\n uint80 roundId;\n int256 answer;\n uint256 startedAt;\n uint256 updatedAt;\n uint80 answeredInRound;\n }\n\n mapping(uint256 => Entry) public entries;\n\n bool public latestRoundDataShouldRevert;\n\n string public desc;\n\n constructor() {}\n\n // Mock setup function\n function setLatestAnswer(int256 answer, uint256 timestamp) external {\n roundId++;\n entries[roundId] = Entry({\n roundId: roundId,\n answer: answer,\n startedAt: timestamp,\n updatedAt: timestamp,\n answeredInRound: roundId\n });\n }\n\n function setLatestAnswerWithRound(int256 answer, uint256 timestamp, uint80 _roundId) external {\n roundId = _roundId;\n entries[roundId] = Entry({\n roundId: roundId,\n answer: answer,\n startedAt: timestamp,\n updatedAt: timestamp,\n answeredInRound: roundId\n });\n }\n\n function setLatestAnswerRevert(int256 answer, uint256 timestamp) external {\n roundId++;\n entries[roundId] = Entry({\n roundId: roundId,\n answer: answer,\n startedAt: timestamp,\n updatedAt: timestamp,\n answeredInRound: roundId - 1\n });\n }\n\n function setLatestRoundDataShouldRevert(bool _shouldRevert) external {\n latestRoundDataShouldRevert = _shouldRevert;\n }\n\n function setDecimals(uint8 _decimals) external {\n keyDecimals = _decimals;\n }\n\n function setDescritpion(string memory _desc) external {\n desc = _desc;\n }\n\n function description() external view override returns (string memory) {\n return desc;\n }\n\n function version() external view override returns (uint256) {\n roundId;\n return 0;\n }\n\n function latestRoundData() external view override returns (uint80, int256, uint256, uint256, uint80) {\n if (latestRoundDataShouldRevert) {\n revert(\"latestRoundData reverted\");\n }\n return getRoundData(uint80(roundId));\n }\n\n function decimals() external view override returns (uint8) {\n return keyDecimals;\n }\n\n function getRoundData(uint80 _roundId) public view override returns (uint80, int256, uint256, uint256, uint80) {\n Entry memory entry = entries[_roundId];\n // Emulate a Chainlink aggregator\n require(entry.updatedAt > 0, \"No data present\");\n return (entry.roundId, entry.answer, entry.startedAt, entry.updatedAt, entry.answeredInRound);\n }\n}\n" + }, + "contracts/mock/MockCoreBorrow.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\nimport \"../interfaces/ICoreBorrow.sol\";\nimport \"../interfaces/IFlashAngle.sol\";\nimport \"../interfaces/ITreasury.sol\";\n\ncontract MockCoreBorrow is ICoreBorrow {\n mapping(address => bool) public flashLoaners;\n mapping(address => bool) public governors;\n mapping(address => bool) public guardians;\n\n function isFlashLoanerTreasury(address treasury) external view override returns (bool) {\n return flashLoaners[treasury];\n }\n\n function isGovernor(address admin) external view override returns (bool) {\n return governors[admin];\n }\n\n function isGovernorOrGuardian(address admin) external view override returns (bool) {\n return governors[admin] || guardians[admin];\n }\n\n function toggleGovernor(address admin) external {\n governors[admin] = !governors[admin];\n }\n\n function toggleGuardian(address admin) external {\n guardians[admin] = !guardians[admin];\n }\n\n function toggleFlashLoaners(address admin) external {\n flashLoaners[admin] = !flashLoaners[admin];\n }\n\n function addStablecoinSupport(IFlashAngle flashAngle, address _treasury) external {\n flashAngle.addStablecoinSupport(_treasury);\n }\n\n function removeStablecoinSupport(IFlashAngle flashAngle, address _treasury) external {\n flashAngle.removeStablecoinSupport(_treasury);\n }\n\n function setCore(IFlashAngle flashAngle, address _core) external {\n flashAngle.setCore(_core);\n }\n\n function setFlashLoanModule(ITreasury _treasury, address _flashLoanModule) external {\n _treasury.setFlashLoanModule(_flashLoanModule);\n }\n}\n" + }, + "contracts/mock/MockERC1271.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.12;\n\nimport \"../interfaces/external/IERC1271.sol\";\n\ncontract MockERC1271 is IERC1271 {\n uint256 public mode = 0;\n\n function setMode(uint256 _mode) public {\n mode = _mode;\n }\n\n /// @notice Returns whether the provided signature is valid for the provided data\n /// @dev MUST return the bytes4 magic value 0x1626ba7e when function passes.\n /// MUST NOT modify state (using STATICCALL for solc < 0.5, view modifier for solc > 0.5).\n /// MUST allow external calls.\n /// @return magicValue The bytes4 magic value 0x1626ba7e\n function isValidSignature(bytes32, bytes memory) external view returns (bytes4 magicValue) {\n if (mode == 1) magicValue = 0x1626ba7e;\n }\n}\n" + }, + "contracts/mock/MockERC721Receiver.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (token/ERC721/utils/ERC721Holder.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Implementation of the {IERC721Receiver} interface.\n *\n * Accepts all token transfers.\n * Make sure the contract is able to use its token with {IERC721-safeTransferFrom}, {IERC721-approve} or {IERC721-setApprovalForAll}.\n */\ncontract MockERC721Receiver {\n uint256 public mode = 0;\n\n function setMode(uint256 _mode) public {\n mode = _mode;\n }\n\n function onERC721Received(address, address, uint256, bytes memory) public view returns (bytes4) {\n require(mode != 1, \"0x1111111\");\n if (mode == 2) return this.setMode.selector;\n return this.onERC721Received.selector;\n }\n}\n" + }, + "contracts/mock/MockEulerPool.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\nimport \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\n\ncontract MockEulerPool {\n IERC20 public collateral;\n uint256 public poolSize;\n //solhint-disable-next-line\n uint256 public MAX_SANE_AMOUNT;\n\n mapping(address => uint256) public users;\n uint256 public interestRateAccumulator;\n\n constructor(IERC20 collateral_, uint256 poolSize_) {\n collateral = collateral_;\n poolSize = poolSize_;\n interestRateAccumulator = 10 ** 18;\n MAX_SANE_AMOUNT = type(uint112).max;\n }\n\n function setPoolSize(uint256 poolSize_) external {\n uint256 balance = collateral.balanceOf(address(this));\n poolSize = poolSize_;\n if (balance > poolSize_) collateral.transfer(msg.sender, balance - poolSize_);\n if (balance < poolSize_) collateral.transferFrom(msg.sender, address(this), poolSize_ - balance);\n }\n\n function setInterestRateAccumulator(uint256 interestRateAccumulator_) external {\n interestRateAccumulator = interestRateAccumulator_;\n }\n\n //solhint-disable-next-line\n function setMAXSANEAMOUNT(uint256 MAX_SANE_AMOUNT_) external {\n MAX_SANE_AMOUNT = MAX_SANE_AMOUNT_;\n }\n\n function balanceOfUnderlying(address account) external view returns (uint256) {\n return (users[account] * interestRateAccumulator) / 10 ** 18;\n }\n\n function deposit(uint256, uint256 amount) external {\n users[msg.sender] += (amount * 10 ** 18) / interestRateAccumulator;\n poolSize += amount;\n collateral.transferFrom(msg.sender, address(this), amount);\n }\n\n function withdraw(uint256, uint256 amount) external {\n if (amount == type(uint256).max) amount = (users[msg.sender] * interestRateAccumulator) / 10 ** 18;\n\n require(amount <= poolSize, \"4\");\n users[msg.sender] -= (amount * 10 ** 18) / interestRateAccumulator;\n collateral.transfer(msg.sender, amount);\n }\n}\n" + }, + "contracts/mock/MockFlashLoanModule.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\nimport \"../interfaces/IFlashAngle.sol\";\nimport \"../interfaces/ICoreBorrow.sol\";\n\ncontract MockFlashLoanModule is IFlashAngle {\n ICoreBorrow public override core;\n mapping(address => bool) public stablecoinsSupported;\n mapping(IAgToken => uint256) public interestAccrued;\n uint256 public surplusValue;\n\n constructor(ICoreBorrow _core) {\n core = _core;\n }\n\n function accrueInterestToTreasury(IAgToken stablecoin) external override returns (uint256 balance) {\n balance = surplusValue;\n interestAccrued[stablecoin] += balance;\n }\n\n function addStablecoinSupport(address _treasury) external override {\n stablecoinsSupported[_treasury] = true;\n }\n\n function removeStablecoinSupport(address _treasury) external override {\n stablecoinsSupported[_treasury] = false;\n }\n\n function setCore(address _core) external override {\n core = ICoreBorrow(_core);\n }\n\n function setSurplusValue(uint256 _surplusValue) external {\n surplusValue = _surplusValue;\n }\n}\n" + }, + "contracts/mock/MockFlashLoanReceiver.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.7;\n\nimport \"@openzeppelin/contracts/token/ERC20/ERC20.sol\";\n\nimport \"@openzeppelin/contracts/interfaces/IERC3156FlashBorrower.sol\";\n\nimport \"@openzeppelin/contracts/interfaces/IERC3156FlashLender.sol\";\n\ncontract MockFlashLoanReceiver is IERC3156FlashBorrower {\n bytes32 public constant CALLBACK_SUCCESS = keccak256(\"ERC3156FlashBorrower.onFlashLoan\");\n\n constructor() {}\n\n function onFlashLoan(\n address,\n address token,\n uint256 amount,\n uint256 fee,\n bytes calldata data\n ) external override returns (bytes32) {\n IERC20(token).approve(msg.sender, amount + fee);\n if (amount >= 10 ** 21) return keccak256(\"error\");\n if (amount == 2 * 10 ** 18) {\n IERC3156FlashLender(msg.sender).flashLoan(IERC3156FlashBorrower(address(this)), token, amount, data);\n return keccak256(\"reentrant\");\n } else return CALLBACK_SUCCESS;\n }\n}\n" + }, + "contracts/mock/MockInterestRateComputer.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\ncontract MockInterestRateComputer {\n uint256 public interestRate;\n uint256 public interestAccumulator;\n uint256 public immutable baseInterest;\n uint256 public immutable halfBase;\n\n uint256 public constant WEEK = 7 * 86400;\n\n constructor(uint256 _baseInterest, uint256 _interestRate) {\n interestAccumulator = _baseInterest;\n baseInterest = _baseInterest;\n halfBase = _baseInterest / 2;\n interestRate = _interestRate;\n }\n\n function _calculateAngle(uint256 exp, uint256 _interestAccumulator) internal view returns (uint256) {\n uint256 ratePerSecond = interestRate;\n if (exp == 0 || ratePerSecond == 0) return _interestAccumulator;\n uint256 expMinusOne = exp - 1;\n uint256 expMinusTwo = exp > 2 ? exp - 2 : 0;\n uint256 basePowerTwo = (ratePerSecond * ratePerSecond) / baseInterest;\n uint256 basePowerThree = (basePowerTwo * ratePerSecond) / baseInterest;\n uint256 secondTerm = (exp * expMinusOne * basePowerTwo) / 2;\n uint256 thirdTerm = (exp * expMinusOne * expMinusTwo * basePowerThree) / 6;\n return (_interestAccumulator * (baseInterest + ratePerSecond * exp + secondTerm + thirdTerm)) / baseInterest;\n }\n\n function _calculateAave(uint256 exp, uint256 _interestAccumulator) internal view returns (uint256) {\n uint256 ratePerSecond = interestRate;\n if (exp == 0 || ratePerSecond == 0) return _interestAccumulator;\n uint256 expMinusOne = exp - 1;\n uint256 expMinusTwo = exp > 2 ? exp - 2 : 0;\n uint256 basePowerTwo = (ratePerSecond * ratePerSecond + halfBase) / baseInterest;\n uint256 basePowerThree = (basePowerTwo * ratePerSecond + halfBase) / baseInterest;\n uint256 secondTerm = (exp * expMinusOne * basePowerTwo) / 2;\n uint256 thirdTerm = (exp * expMinusOne * expMinusTwo * basePowerThree) / 6;\n return (_interestAccumulator * (baseInterest + ratePerSecond * exp + secondTerm + thirdTerm)) / baseInterest;\n }\n\n function _calculateCompound(uint256 exp, uint256 _interestAccumulator) internal view returns (uint256) {\n return _interestAccumulator * (baseInterest + interestRate * exp);\n }\n\n function _rpow(uint256 x, uint256 n, uint256 base) internal pure returns (uint256 z) {\n //solhint-disable-next-line\n assembly {\n switch x\n case 0 {\n switch n\n case 0 {\n z := base\n }\n default {\n z := 0\n }\n }\n default {\n switch mod(n, 2)\n case 0 {\n z := base\n }\n default {\n z := x\n }\n let half := div(base, 2) // for rounding.\n for {\n n := div(n, 2)\n } n {\n n := div(n, 2)\n } {\n let xx := mul(x, x)\n if iszero(eq(div(xx, x), x)) {\n revert(0, 0)\n }\n let xxRound := add(xx, half)\n if lt(xxRound, xx) {\n revert(0, 0)\n }\n x := div(xxRound, base)\n if mod(n, 2) {\n let zx := mul(z, x)\n if and(iszero(iszero(x)), iszero(eq(div(zx, x), z))) {\n revert(0, 0)\n }\n let zxRound := add(zx, half)\n if lt(zxRound, zx) {\n revert(0, 0)\n }\n z := div(zxRound, base)\n }\n }\n }\n }\n }\n\n function _calculateMaker(uint256 delta, uint256 _interestAccumulator) internal view returns (uint256) {\n return (_rpow(baseInterest + interestRate, delta, baseInterest) * _interestAccumulator) / baseInterest;\n }\n\n function calculateAngle(uint256 delta) external view returns (uint256) {\n return _calculateAngle(delta, interestAccumulator);\n }\n\n function calculateAave(uint256 delta) external view returns (uint256) {\n return _calculateAave(delta, interestAccumulator);\n }\n\n function calculateMaker(uint256 delta) external view returns (uint256) {\n return _calculateMaker(delta, interestAccumulator);\n }\n\n function calculateAngle1Year() external view returns (uint256) {\n uint256 _interestAccumulator = interestAccumulator;\n for (uint256 i; i < 52; ++i) {\n _interestAccumulator = _calculateAngle(WEEK, _interestAccumulator);\n }\n return _interestAccumulator;\n }\n\n function calculateAave1Year() external view returns (uint256) {\n uint256 _interestAccumulator = interestAccumulator;\n for (uint256 i; i < 52; ++i) {\n _interestAccumulator = _calculateAave(WEEK, _interestAccumulator);\n }\n return _interestAccumulator;\n }\n\n function calculateMaker1Year() external view returns (uint256) {\n uint256 _interestAccumulator = interestAccumulator;\n for (uint256 i; i < 52; ++i) {\n _interestAccumulator = _calculateMaker(WEEK, _interestAccumulator);\n }\n return _interestAccumulator;\n }\n\n function calculateAngle1YearDirect() external view returns (uint256) {\n uint256 _interestAccumulator = interestAccumulator;\n _interestAccumulator = _calculateAngle(52 * WEEK, _interestAccumulator);\n\n return _interestAccumulator;\n }\n\n function calculateAave1YearDirect() external view returns (uint256) {\n uint256 _interestAccumulator = interestAccumulator;\n _interestAccumulator = _calculateAave(52 * WEEK, _interestAccumulator);\n\n return _interestAccumulator;\n }\n\n function calculateMaker1YearDirect() external view returns (uint256) {\n uint256 _interestAccumulator = interestAccumulator;\n _interestAccumulator = _calculateMaker(52 * WEEK, _interestAccumulator);\n\n return _interestAccumulator;\n }\n\n function calculateCompound1YearDirect() external view returns (uint256) {\n uint256 _interestAccumulator = interestAccumulator;\n _interestAccumulator = _calculateCompound(52 * WEEK, _interestAccumulator);\n\n return _interestAccumulator;\n }\n}\n" + }, + "contracts/mock/MockKeeperMulticall.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.12;\n\nimport \"@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/access/AccessControlUpgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol\";\nimport \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\nimport \"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\";\n\ncontract MockKeeperMulticall is Initializable, AccessControlUpgradeable {\n using SafeERC20 for IERC20;\n\n bytes32 public constant KEEPER_ROLE = keccak256(\"KEEPER_ROLE\");\n\n //solhint-disable-next-line\n address private constant _oneInch = 0x1111111254fb6c44bAC0beD2854e76F90643097d;\n\n struct Action {\n address target;\n bytes data;\n bool isDelegateCall;\n }\n\n event LogAction(address indexed target, bytes data);\n event SentToMiner(uint256 indexed value);\n event Recovered(address indexed tokenAddress, address indexed to, uint256 amount);\n\n error AmountOutTooLow(uint256 amount, uint256 min);\n error BalanceTooLow();\n error FlashbotsErrorPayingMiner(uint256 value);\n error IncompatibleLengths();\n error RevertBytes();\n error ZeroAddress();\n\n constructor() initializer {}\n\n function initialize(address keeper) public initializer {\n __AccessControl_init();\n\n _setupRole(KEEPER_ROLE, keeper);\n _setRoleAdmin(KEEPER_ROLE, KEEPER_ROLE);\n }\n}\n\ncontract MockKeeperMulticall2 {\n uint256 public varTest = 1;\n\n bytes32 public constant KEEPER_ROLE = keccak256(\"KEEPER_ROLE\");\n\n //solhint-disable-next-line\n address private constant _oneInch = 0x1111111254fb6c44bAC0beD2854e76F90643097d;\n\n struct Action {\n address target;\n bytes data;\n bool isDelegateCall;\n }\n\n event LogAction(address indexed target, bytes data);\n event SentToMiner(uint256 indexed value);\n event Recovered(address indexed tokenAddress, address indexed to, uint256 amount);\n\n error AmountOutTooLow(uint256 amount, uint256 min);\n error BalanceTooLow();\n error FlashbotsErrorPayingMiner(uint256 value);\n error IncompatibleLengths();\n error RevertBytes();\n error ZeroAddress();\n\n function functionTest() external pure returns (bool) {\n return true;\n }\n}\n" + }, + "contracts/mock/MockLayerZero.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\ninterface ILzApp {\n function lzReceive(uint16 _srcChainId, bytes memory _srcAddress, uint64 _nonce, bytes memory _payload) external;\n}\n\ncontract MockLayerZero {\n mapping(uint16 => uint256) public counters;\n uint256 public config;\n mapping(uint16 => uint64) public outboundNonce;\n uint256 public resumeReceived;\n uint256 public sendVersion;\n uint256 public receiveVersion;\n\n /// @notice Initiate with a fixe change rate\n constructor() {}\n\n function send(\n uint16 _dstChainId,\n bytes calldata,\n bytes calldata,\n address,\n address,\n bytes calldata\n ) external payable {\n counters[_dstChainId] += 1;\n }\n\n function getOutboundNonce(uint16 _dstChainId, address) external view returns (uint64) {\n return outboundNonce[_dstChainId];\n }\n\n function setOutBoundNonce(uint16 _from, uint64 value) external {\n outboundNonce[_from] = value;\n }\n\n function lzReceive(\n address lzApp,\n uint16 _srcChainId,\n bytes memory _srcAddress,\n uint64 _nonce,\n bytes memory _payload\n ) public {\n ILzApp(lzApp).lzReceive(_srcChainId, _srcAddress, _nonce, _payload);\n }\n\n function estimateFees(\n uint16,\n address,\n bytes calldata,\n bool,\n bytes calldata\n ) external pure returns (uint256 nativeFee, uint256 zroFee) {\n return (123, 456);\n }\n\n function setConfig(uint16, uint16, uint256 _configType, bytes calldata) external {\n config = _configType;\n }\n\n function getConfig(uint16, uint16, address, uint256) external view returns (bytes memory) {\n return abi.encodePacked(config);\n }\n\n function setSendVersion(uint16 _version) external {\n sendVersion = _version;\n }\n\n function setReceiveVersion(uint16 _version) external {\n receiveVersion = _version;\n }\n\n function forceResumeReceive(uint16, bytes calldata) external {\n resumeReceived = 1 - resumeReceived;\n }\n}\n" + }, + "contracts/mock/MockLiquidityGauge.sol": { + "content": "// SPDX-License-Identifier: UNLICENSED\npragma solidity ^0.8.12;\n\nimport { ILiquidityGauge } from \"../interfaces/coreModule/ILiquidityGauge.sol\";\nimport \"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\";\nimport \"@openzeppelin/contracts/token/ERC20/ERC20.sol\";\n\ncontract MockLiquidityGauge is ILiquidityGauge, ERC20 {\n using SafeERC20 for IERC20;\n\n IERC20 internal _ANGLE = IERC20(0x31429d1856aD1377A8A0079410B297e1a9e214c2);\n IERC20 internal _token;\n mapping(address => uint256) public rewards;\n\n constructor(string memory name_, string memory symbol_, address token_) ERC20(name_, symbol_) {\n _token = IERC20(token_);\n }\n\n function deposit(\n uint256 _value,\n address _addr,\n // solhint-disable-next-line\n bool\n ) external {\n _token.safeTransferFrom(msg.sender, address(this), _value);\n _mint(_addr, _value);\n }\n\n function withdraw(\n uint256 _value,\n // solhint-disable-next-line\n bool\n ) external {\n _burn(msg.sender, _value);\n _token.safeTransfer(msg.sender, _value);\n }\n\n // solhint-disable-next-line\n function claim_rewards(address _addr, address _receiver) external {\n if (_receiver == address(0)) _receiver = _addr;\n _ANGLE.safeTransfer(_receiver, rewards[_addr]);\n rewards[_addr] = 0;\n }\n\n // solhint-disable-next-line\n function claimable_reward(address _addr, address) external view returns (uint256 amount) {\n return rewards[_addr];\n }\n\n function setReward(address receiver_, uint256 amount) external {\n rewards[receiver_] = amount;\n }\n}\n" + }, + "contracts/mock/MockOracle.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.7;\n\nimport \"../interfaces/IOracle.sol\";\n\ncontract MockOracle is IOracle {\n event Update(uint256 _peg);\n\n ITreasury public treasury;\n\n uint256 public base = 1 ether;\n uint256 public precision = 1 ether;\n uint256 public rate;\n bool public outdated;\n\n /// @notice Initiate with a fixe change rate\n constructor(uint256 rate_, ITreasury _treasury) {\n rate = rate_;\n treasury = _treasury;\n }\n\n /// @notice Mock read\n function read() external view override returns (uint256) {\n return rate;\n }\n\n /// @notice change oracle rate\n function update(uint256 newRate) external {\n rate = newRate;\n }\n\n function setTreasury(address _treasury) external override {\n treasury = ITreasury(_treasury);\n }\n\n function circuitChainlink() external pure override returns (AggregatorV3Interface[] memory) {}\n}\n" + }, + "contracts/mock/MockPolygonAgEUR.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.12;\n\nimport \"../agToken/polygon/utils/ERC20UpgradeableCustom.sol\";\nimport \"@openzeppelin/contracts-upgradeable/access/AccessControlUpgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/utils/cryptography/draft-EIP712Upgradeable.sol\";\nimport \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\nimport \"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\";\n\nimport \"../interfaces/IAgToken.sol\";\nimport \"../interfaces/ITreasury.sol\";\n\ninterface IChildToken {\n function deposit(address user, bytes calldata depositData) external;\n\n function withdraw(uint256 amount) external;\n}\n\ncontract MockPolygonAgEUR is\n Initializable,\n ERC20UpgradeableCustom,\n AccessControlUpgradeable,\n EIP712Upgradeable,\n IChildToken\n{\n bytes32 public constant DEPOSITOR_ROLE = keccak256(\"DEPOSITOR_ROLE\");\n\n /// @dev Emitted when the child chain manager changes\n event ChildChainManagerAdded(address newAddress);\n event ChildChainManagerRevoked(address oldAddress);\n\n constructor() initializer {}\n\n function initialize(\n string memory _name,\n string memory _symbol,\n address childChainManager,\n address guardian\n ) public initializer {\n __ERC20_init(_name, _symbol);\n __AccessControl_init();\n _setupRole(DEFAULT_ADMIN_ROLE, guardian);\n _setupRole(DEPOSITOR_ROLE, childChainManager);\n __EIP712_init(_name, \"1\");\n }\n\n /**\n * @notice Called when the bridge has tokens to mint\n * @param user Address to mint the token to\n * @param depositData Encoded amount to mint\n */\n function deposit(address user, bytes calldata depositData) external override {\n require(hasRole(DEPOSITOR_ROLE, msg.sender));\n uint256 amount = abi.decode(depositData, (uint256));\n _mint(user, amount);\n }\n\n /**\n * @notice Called when user wants to withdraw tokens back to root chain\n * @dev Should burn user's tokens. This transaction will be verified when exiting on root chain\n * @param amount Amount of tokens to withdraw\n */\n function withdraw(uint256 amount) external override {\n _burn(_msgSender(), amount);\n }\n\n // =============================================================================\n // ======================= New data added for the upgrade ======================\n // =============================================================================\n\n mapping(address => bool) public isMinter;\n /// @notice Reference to the treasury contract which can grant minting rights\n address public treasury;\n /// @notice Boolean to check whether the contract has been reinitialized after its upgrade\n bool public treasuryInitialized;\n\n using SafeERC20 for IERC20;\n\n /// @notice Base used for fee computation\n uint256 public constant BASE_PARAMS = 10 ** 9;\n\n // =============================== Bridging Data ===============================\n\n /// @notice Struct with some data about a specific bridge token\n struct BridgeDetails {\n // Limit on the balance of bridge token held by the contract: it is designed\n // to reduce the exposure of the system to hacks\n uint256 limit;\n // Limit on the hourly volume of token minted through this bridge\n // Technically the limit over a rolling hour is hourlyLimit x2 as hourly limit\n // is enforced only between x:00 and x+1:00\n uint256 hourlyLimit;\n // Fee taken for swapping in and out the token\n uint64 fee;\n // Whether the associated token is allowed or not\n bool allowed;\n // Whether swapping in and out from the associated token is paused or not\n bool paused;\n }\n\n /// @notice Maps a bridge token to data\n mapping(address => BridgeDetails) public bridges;\n /// @notice List of all bridge tokens\n address[] public bridgeTokensList;\n /// @notice Maps a bridge token to the associated hourly volume\n mapping(address => mapping(uint256 => uint256)) public usage;\n /// @notice Maps an address to whether it is exempt of fees for when it comes to swapping in and out\n mapping(address => uint256) public isFeeExempt;\n\n uint256[44] private __gap;\n\n // ================================== Events ===================================\n\n event BridgeTokenAdded(address indexed bridgeToken, uint256 limit, uint256 hourlyLimit, uint64 fee, bool paused);\n event BridgeTokenToggled(address indexed bridgeToken, bool toggleStatus);\n event BridgeTokenRemoved(address indexed bridgeToken);\n event BridgeTokenFeeUpdated(address indexed bridgeToken, uint64 fee);\n event BridgeTokenLimitUpdated(address indexed bridgeToken, uint256 limit);\n event BridgeTokenHourlyLimitUpdated(address indexed bridgeToken, uint256 hourlyLimit);\n event HourlyLimitUpdated(uint256 hourlyLimit);\n event FeeToggled(address indexed theAddress, uint256 toggleStatus);\n event KeeperToggled(address indexed keeper, bool toggleStatus);\n event MinterToggled(address indexed minter);\n event Recovered(address indexed token, address indexed to, uint256 amount);\n event TreasuryUpdated(address indexed _treasury);\n\n // ================================== Errors ===================================\n\n error AssetStillControlledInReserves();\n error BurnAmountExceedsAllowance();\n error HourlyLimitExceeded();\n error InvalidSender();\n error InvalidToken();\n error InvalidTreasury();\n error NotGovernor();\n error NotGovernorOrGuardian();\n error NotMinter();\n error NotTreasury();\n error TooBigAmount();\n error TooHighParameterValue();\n error TreasuryAlreadyInitialized();\n error ZeroAddress();\n\n /// @notice Checks to see if it is the `Treasury` calling this contract\n /// @dev There is no Access Control here, because it can be handled cheaply through this modifier\n modifier onlyTreasury() {\n if (msg.sender != treasury) revert NotTreasury();\n _;\n }\n\n /// @notice Checks whether the sender has the minting right\n modifier onlyMinter() {\n if (!isMinter[msg.sender]) revert NotMinter();\n _;\n }\n\n /// @notice Checks whether the `msg.sender` has the governor role or not\n modifier onlyGovernor() {\n if (!ITreasury(treasury).isGovernor(msg.sender)) revert NotGovernor();\n _;\n }\n\n /// @notice Checks whether the `msg.sender` has the governor role or the guardian role\n modifier onlyGovernorOrGuardian() {\n if (!ITreasury(treasury).isGovernorOrGuardian(msg.sender)) revert NotGovernorOrGuardian();\n _;\n }\n\n /// @notice Sets up the treasury contract on Polygon after the upgrade\n /// @param _treasury Address of the treasury contract\n function setUpTreasury(address _treasury) external {\n // Only governor on Polygon\n if (msg.sender != 0xdA2D2f638D6fcbE306236583845e5822554c02EA) revert NotGovernor();\n if (address(ITreasury(_treasury).stablecoin()) != address(this)) revert InvalidTreasury();\n if (treasuryInitialized) revert TreasuryAlreadyInitialized();\n treasury = _treasury;\n treasuryInitialized = true;\n emit TreasuryUpdated(_treasury);\n }\n\n // =========================== External Function ===============================\n\n /// @notice Allows anyone to burn agToken without redeeming collateral back\n /// @param amount Amount of stablecoins to burn\n /// @dev This function can typically be called if there is a settlement mechanism to burn stablecoins\n function burnStablecoin(uint256 amount) external {\n _burnCustom(msg.sender, amount);\n }\n\n // ======================= Minter Role Only Functions ==========================\n\n function burnSelf(uint256 amount, address burner) external onlyMinter {\n _burnCustom(burner, amount);\n }\n\n function burnFrom(uint256 amount, address burner, address sender) external onlyMinter {\n _burnFromNoRedeem(amount, burner, sender);\n }\n\n function mint(address account, uint256 amount) external onlyMinter {\n _mint(account, amount);\n }\n\n // ======================= Treasury Only Functions =============================\n\n function addMinter(address minter) external onlyTreasury {\n isMinter[minter] = true;\n emit MinterToggled(minter);\n }\n\n function removeMinter(address minter) external {\n if (msg.sender != address(treasury) && msg.sender != minter) revert InvalidSender();\n isMinter[minter] = false;\n emit MinterToggled(minter);\n }\n\n function setTreasury(address _treasury) external onlyTreasury {\n treasury = _treasury;\n emit TreasuryUpdated(_treasury);\n }\n\n // ============================ Internal Function ==============================\n\n /// @notice Internal version of the function `burnFromNoRedeem`\n /// @param amount Amount to burn\n /// @dev It is at the level of this function that allowance checks are performed\n function _burnFromNoRedeem(uint256 amount, address burner, address sender) internal {\n if (burner != sender) {\n uint256 currentAllowance = allowance(burner, sender);\n if (currentAllowance < amount) revert BurnAmountExceedsAllowance();\n _approve(burner, sender, currentAllowance - amount);\n }\n _burnCustom(burner, amount);\n }\n\n // ==================== External Permissionless Functions ======================\n\n /// @notice Returns the list of all supported bridge tokens\n /// @dev Helpful for UIs\n function allBridgeTokens() external view returns (address[] memory) {\n return bridgeTokensList;\n }\n\n /// @notice Returns the current volume for a bridge, for the current hour\n /// @dev Helpful for UIs\n function currentUsage(address bridge) external view returns (uint256) {\n return usage[bridge][block.timestamp / 3600];\n }\n\n /// @notice Mints the canonical token from a supported bridge token\n /// @param bridgeToken Bridge token to use to mint\n /// @param amount Amount of bridge tokens to send\n /// @param to Address to which the stablecoin should be sent\n /// @dev Some fees may be taken by the protocol depending on the token used and on the address calling\n function swapIn(address bridgeToken, uint256 amount, address to) external returns (uint256) {\n BridgeDetails memory bridgeDetails = bridges[bridgeToken];\n if (!bridgeDetails.allowed || bridgeDetails.paused) revert InvalidToken();\n uint256 balance = IERC20(bridgeToken).balanceOf(address(this));\n if (balance + amount > bridgeDetails.limit) {\n // In case someone maliciously sends tokens to this contract\n // Or the limit changes\n if (bridgeDetails.limit > balance) amount = bridgeDetails.limit - balance;\n else {\n amount = 0;\n }\n }\n\n // Checking requirement on the hourly volume\n uint256 hour = block.timestamp / 3600;\n uint256 hourlyUsage = usage[bridgeToken][hour] + amount;\n if (hourlyUsage > bridgeDetails.hourlyLimit) {\n // Edge case when the hourly limit changes\n if (bridgeDetails.hourlyLimit > usage[bridgeToken][hour])\n amount = bridgeDetails.hourlyLimit - usage[bridgeToken][hour];\n else {\n amount = 0;\n }\n }\n usage[bridgeToken][hour] = usage[bridgeToken][hour] + amount;\n\n IERC20(bridgeToken).safeTransferFrom(msg.sender, address(this), amount);\n uint256 canonicalOut = amount;\n // Computing fees\n if (isFeeExempt[msg.sender] == 0) {\n canonicalOut -= (canonicalOut * bridgeDetails.fee) / BASE_PARAMS;\n }\n _mint(to, canonicalOut);\n return canonicalOut;\n }\n\n /// @notice Burns the canonical token in exchange for a bridge token\n /// @param bridgeToken Bridge token required\n /// @param amount Amount of canonical tokens to burn\n /// @param to Address to which the bridge token should be sent\n /// @dev Some fees may be taken by the protocol depending on the token used and on the address calling\n function swapOut(address bridgeToken, uint256 amount, address to) external returns (uint256) {\n BridgeDetails memory bridgeDetails = bridges[bridgeToken];\n if (!bridgeDetails.allowed || bridgeDetails.paused) revert InvalidToken();\n\n _burnCustom(msg.sender, amount);\n uint256 bridgeOut = amount;\n if (isFeeExempt[msg.sender] == 0) {\n bridgeOut -= (bridgeOut * bridgeDetails.fee) / BASE_PARAMS;\n }\n IERC20(bridgeToken).safeTransfer(to, bridgeOut);\n return bridgeOut;\n }\n\n // ======================= Governance Functions ================================\n\n /// @notice Adds support for a bridge token\n /// @param bridgeToken Bridge token to add: it should be a version of the stablecoin from another bridge\n /// @param limit Limit on the balance of bridge token this contract could hold\n /// @param hourlyLimit Limit on the hourly volume for this bridge\n /// @param paused Whether swapping for this token should be paused or not\n /// @param fee Fee taken upon swapping for or against this token\n function addBridgeToken(\n address bridgeToken,\n uint256 limit,\n uint256 hourlyLimit,\n uint64 fee,\n bool paused\n ) external onlyGovernor {\n if (bridges[bridgeToken].allowed || bridgeToken == address(0)) revert InvalidToken();\n if (fee > BASE_PARAMS) revert TooHighParameterValue();\n BridgeDetails memory _bridge;\n _bridge.limit = limit;\n _bridge.hourlyLimit = hourlyLimit;\n _bridge.paused = paused;\n _bridge.fee = fee;\n _bridge.allowed = true;\n bridges[bridgeToken] = _bridge;\n bridgeTokensList.push(bridgeToken);\n emit BridgeTokenAdded(bridgeToken, limit, hourlyLimit, fee, paused);\n }\n\n /// @notice Removes support for a token\n /// @param bridgeToken Address of the bridge token to remove support for\n function removeBridgeToken(address bridgeToken) external onlyGovernor {\n if (IERC20(bridgeToken).balanceOf(address(this)) != 0) revert AssetStillControlledInReserves();\n delete bridges[bridgeToken];\n // Deletion from `bridgeTokensList` loop\n uint256 bridgeTokensListLength = bridgeTokensList.length;\n for (uint256 i; i < bridgeTokensListLength - 1; ++i) {\n if (bridgeTokensList[i] == bridgeToken) {\n // Replace the `bridgeToken` to remove with the last of the list\n bridgeTokensList[i] = bridgeTokensList[bridgeTokensListLength - 1];\n break;\n }\n }\n // Remove last element in array\n bridgeTokensList.pop();\n emit BridgeTokenRemoved(bridgeToken);\n }\n\n /// @notice Recovers any ERC20 token\n /// @dev Can be used to withdraw bridge tokens for them to be de-bridged on mainnet\n function recoverERC20(address tokenAddress, address to, uint256 amountToRecover) external onlyGovernor {\n IERC20(tokenAddress).safeTransfer(to, amountToRecover);\n emit Recovered(tokenAddress, to, amountToRecover);\n }\n\n /// @notice Updates the `limit` amount for `bridgeToken`\n function setLimit(address bridgeToken, uint256 limit) external onlyGovernorOrGuardian {\n if (!bridges[bridgeToken].allowed) revert InvalidToken();\n bridges[bridgeToken].limit = limit;\n emit BridgeTokenLimitUpdated(bridgeToken, limit);\n }\n\n /// @notice Updates the `hourlyLimit` amount for `bridgeToken`\n function setHourlyLimit(address bridgeToken, uint256 hourlyLimit) external onlyGovernorOrGuardian {\n if (!bridges[bridgeToken].allowed) revert InvalidToken();\n bridges[bridgeToken].hourlyLimit = hourlyLimit;\n emit BridgeTokenHourlyLimitUpdated(bridgeToken, hourlyLimit);\n }\n\n /// @notice Updates the `fee` value for `bridgeToken`\n function setSwapFee(address bridgeToken, uint64 fee) external onlyGovernorOrGuardian {\n if (!bridges[bridgeToken].allowed) revert InvalidToken();\n if (fee > BASE_PARAMS) revert TooHighParameterValue();\n bridges[bridgeToken].fee = fee;\n emit BridgeTokenFeeUpdated(bridgeToken, fee);\n }\n\n /// @notice Pauses or unpauses swapping in and out for a token\n function toggleBridge(address bridgeToken) external onlyGovernorOrGuardian {\n if (!bridges[bridgeToken].allowed) revert InvalidToken();\n bool pausedStatus = bridges[bridgeToken].paused;\n bridges[bridgeToken].paused = !pausedStatus;\n emit BridgeTokenToggled(bridgeToken, !pausedStatus);\n }\n\n /// @notice Toggles fees for the address `theAddress`\n function toggleFeesForAddress(address theAddress) external onlyGovernorOrGuardian {\n uint256 feeExemptStatus = 1 - isFeeExempt[theAddress];\n isFeeExempt[theAddress] = feeExemptStatus;\n emit FeeToggled(theAddress, feeExemptStatus);\n }\n}\n" + }, + "contracts/mock/MockRouter.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\nimport \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\nimport \"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\";\n\nimport \"../interfaces/IAngleRouter.sol\";\nimport \"../interfaces/external/uniswap/IUniswapRouter.sol\";\nimport \"../interfaces/external/lido/IWStETH.sol\";\n\ncontract MockRouter is IUniswapV3Router, IWStETH {\n using SafeERC20 for IERC20;\n\n uint256 public counterAngleMint;\n uint256 public counterAngleBurn;\n uint256 public counter1Inch;\n uint256 public counterUni;\n uint256 public counterWrap;\n uint256 public counterMixer;\n uint256 public amountOutUni;\n uint256 public multiplierMintBurn;\n uint256 public stETHMultiplier;\n address public inToken;\n address public outToken;\n\n address public stETH;\n\n /// @notice Action types\n enum ActionType {\n transfer,\n wrap,\n wrapNative,\n sweep,\n sweepNative,\n unwrap,\n unwrapNative,\n swapIn,\n swapOut,\n uniswapV3,\n oneInch,\n claimRewards,\n gaugeDeposit,\n borrower\n }\n\n /// @notice Data needed to get permits\n struct PermitType {\n address token;\n address owner;\n uint256 value;\n uint256 deadline;\n uint8 v;\n bytes32 r;\n bytes32 s;\n }\n\n constructor() {}\n\n function mint(address user, uint256 amount, uint256, address stablecoin, address collateral) external {\n counterAngleMint += 1;\n IERC20(collateral).safeTransferFrom(msg.sender, address(this), amount);\n IERC20(stablecoin).safeTransfer(user, (amount * 10 ** 9) / multiplierMintBurn);\n }\n\n function setStETH(address _stETH) external {\n stETH = _stETH;\n }\n\n function burn(address user, uint256 amount, uint256, address stablecoin, address collateral) external {\n counterAngleBurn += 1;\n IERC20(stablecoin).safeTransferFrom(msg.sender, address(this), amount);\n IERC20(collateral).safeTransfer(user, (amount * multiplierMintBurn) / 10 ** 9);\n }\n\n function mixer(\n PermitType[] memory paramsPermit,\n ActionType[] memory actions,\n bytes[] calldata data\n ) public payable virtual {\n paramsPermit;\n counterMixer += 1;\n for (uint256 i; i < actions.length; ++i) {\n if (actions[i] == ActionType.transfer) {\n (address transferToken, uint256 amount) = abi.decode(data[i], (address, uint256));\n IERC20(transferToken).safeTransferFrom(msg.sender, address(this), amount);\n }\n }\n }\n\n function wrap(uint256 amount) external returns (uint256 amountOut) {\n amountOut = (amount * stETHMultiplier) / 10 ** 9;\n counterWrap += 1;\n IERC20(stETH).safeTransferFrom(msg.sender, address(this), amount);\n IERC20(outToken).safeTransfer(msg.sender, amountOut);\n }\n\n function oneInch(uint256 amountIn) external returns (uint256 amountOut) {\n counter1Inch += 1;\n amountOut = (amountOutUni * amountIn) / 10 ** 9;\n IERC20(inToken).safeTransferFrom(msg.sender, address(this), amountIn);\n IERC20(outToken).safeTransfer(msg.sender, amountOut);\n }\n\n function oneInchReverts() external {\n counter1Inch += 1;\n revert(\"wrong swap\");\n }\n\n function oneInchRevertsWithoutMessage() external {\n counter1Inch += 1;\n require(false);\n }\n\n function exactInput(ExactInputParams calldata params) external payable returns (uint256 amountOut) {\n counterUni += 1;\n amountOut = (params.amountIn * amountOutUni) / 10 ** 9;\n IERC20(inToken).safeTransferFrom(msg.sender, address(this), params.amountIn);\n IERC20(outToken).safeTransfer(params.recipient, amountOut);\n require(amountOut >= params.amountOutMinimum);\n }\n\n function setMultipliers(uint256 a, uint256 b) external {\n amountOutUni = a;\n multiplierMintBurn = b;\n }\n\n function setStETHMultiplier(uint256 value) external {\n stETHMultiplier = value;\n }\n\n function setInOut(address _collateral, address _stablecoin) external {\n inToken = _collateral;\n outToken = _stablecoin;\n }\n}\n" + }, + "contracts/mock/MockSidechainAgEUR.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\nimport \"../agToken/AgToken.sol\";\nimport \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\nimport \"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\";\n\n/// @title AgTokenSideChainMultiBridge\n/// @author Angle Labs, Inc.\n/// @notice Contract for Angle agTokens on other chains than Ethereum mainnet\n/// @dev This contract supports bridge tokens having a minting right on the stablecoin (also referred to as the canonical\n/// or the native token)\n/// @dev References:\n/// - FRAX implementation: https://polygonscan.com/address/0x45c32fA6DF82ead1e2EF74d17b76547EDdFaFF89#code\n/// - QiDAO implementation: https://snowtrace.io/address/0x5c49b268c9841AFF1Cc3B0a418ff5c3442eE3F3b#code\ncontract MockSidechainAgEUR is AgToken {\n using SafeERC20 for IERC20;\n\n /// @notice Base used for fee computation\n uint256 public constant BASE_PARAMS = 10 ** 9;\n\n // =============================== Bridging Data ===============================\n\n /// @notice Struct with some data about a specific bridge token\n struct BridgeDetails {\n // Limit on the balance of bridge token held by the contract: it is designed\n // to reduce the exposure of the system to hacks\n uint256 limit;\n // Limit on the hourly volume of token minted through this bridge\n // Technically the limit over a rolling hour is hourlyLimit x2 as hourly limit\n // is enforced only between x:00 and x+1:00\n uint256 hourlyLimit;\n // Fee taken for swapping in and out the token\n uint64 fee;\n // Whether the associated token is allowed or not\n bool allowed;\n // Whether swapping in and out from the associated token is paused or not\n bool paused;\n }\n\n /// @notice Maps a bridge token to data\n mapping(address => BridgeDetails) public bridges;\n /// @notice List of all bridge tokens\n address[] public bridgeTokensList;\n /// @notice Maps a bridge token to the associated hourly volume\n mapping(address => mapping(uint256 => uint256)) public usage;\n /// @notice Maps an address to whether it is exempt of fees for when it comes to swapping in and out\n mapping(address => uint256) public isFeeExempt;\n\n // ================================== Events ===================================\n\n event BridgeTokenAdded(address indexed bridgeToken, uint256 limit, uint256 hourlyLimit, uint64 fee, bool paused);\n event BridgeTokenToggled(address indexed bridgeToken, bool toggleStatus);\n event BridgeTokenRemoved(address indexed bridgeToken);\n event BridgeTokenFeeUpdated(address indexed bridgeToken, uint64 fee);\n event BridgeTokenLimitUpdated(address indexed bridgeToken, uint256 limit);\n event BridgeTokenHourlyLimitUpdated(address indexed bridgeToken, uint256 hourlyLimit);\n event HourlyLimitUpdated(uint256 hourlyLimit);\n event Recovered(address indexed token, address indexed to, uint256 amount);\n event FeeToggled(address indexed theAddress, uint256 toggleStatus);\n\n // =============================== Errors ================================\n\n error AssetStillControlledInReserves();\n error HourlyLimitExceeded();\n error InvalidToken();\n error NotGovernor();\n error NotGovernorOrGuardian();\n error TooBigAmount();\n error TooHighParameterValue();\n error ZeroAddress();\n\n // ============================= Constructor ===================================\n\n /// @notice Checks whether the `msg.sender` has the governor role or not\n modifier onlyGovernor() {\n if (!ITreasury(treasury).isGovernor(msg.sender)) revert NotGovernor();\n _;\n }\n\n /// @notice Checks whether the `msg.sender` has the governor role or the guardian role\n modifier onlyGovernorOrGuardian() {\n if (!ITreasury(treasury).isGovernorOrGuardian(msg.sender)) revert NotGovernorOrGuardian();\n _;\n }\n\n // ==================== External Permissionless Functions ======================\n\n /// @notice Returns the list of all supported bridge tokens\n /// @dev Helpful for UIs\n function allBridgeTokens() external view returns (address[] memory) {\n return bridgeTokensList;\n }\n\n /// @notice Returns the current volume for a bridge, for the current hour\n /// @param bridgeToken Bridge used to mint\n /// @dev Helpful for UIs\n function currentUsage(address bridgeToken) external view returns (uint256) {\n return usage[bridgeToken][block.timestamp / 3600];\n }\n\n /// @notice Mints the canonical token from a supported bridge token\n /// @param bridgeToken Bridge token to use to mint\n /// @param amount Amount of bridge tokens to send\n /// @param to Address to which the stablecoin should be sent\n /// @return Amount of the canonical stablecoin actually minted\n /// @dev Some fees may be taken by the protocol depending on the token used and on the address calling\n function swapIn(address bridgeToken, uint256 amount, address to) external returns (uint256) {\n BridgeDetails memory bridgeDetails = bridges[bridgeToken];\n if (!bridgeDetails.allowed || bridgeDetails.paused) revert InvalidToken();\n uint256 balance = IERC20(bridgeToken).balanceOf(address(this));\n if (balance + amount > bridgeDetails.limit) {\n // In case someone maliciously sends tokens to this contract\n // Or the limit changes\n if (bridgeDetails.limit > balance) amount = bridgeDetails.limit - balance;\n else {\n amount = 0;\n }\n }\n\n // Checking requirement on the hourly volume\n uint256 hour = block.timestamp / 3600;\n uint256 hourlyUsage = usage[bridgeToken][hour] + amount;\n if (hourlyUsage > bridgeDetails.hourlyLimit) {\n // Edge case when the hourly limit changes\n if (bridgeDetails.hourlyLimit > usage[bridgeToken][hour])\n amount = bridgeDetails.hourlyLimit - usage[bridgeToken][hour];\n else {\n amount = 0;\n }\n }\n usage[bridgeToken][hour] = usage[bridgeToken][hour] + amount;\n\n IERC20(bridgeToken).safeTransferFrom(msg.sender, address(this), amount);\n uint256 canonicalOut = amount;\n // Computing fees\n if (isFeeExempt[msg.sender] == 0) {\n canonicalOut -= (canonicalOut * bridgeDetails.fee) / BASE_PARAMS;\n }\n _mint(to, canonicalOut);\n return canonicalOut;\n }\n\n /// @notice Burns the canonical token in exchange for a bridge token\n /// @param bridgeToken Bridge token required\n /// @param amount Amount of canonical tokens to burn\n /// @param to Address to which the bridge token should be sent\n /// @return Amount of bridge tokens actually sent back\n /// @dev Some fees may be taken by the protocol depending on the token used and on the address calling\n function swapOut(address bridgeToken, uint256 amount, address to) external returns (uint256) {\n BridgeDetails memory bridgeDetails = bridges[bridgeToken];\n if (!bridgeDetails.allowed || bridgeDetails.paused) revert InvalidToken();\n\n _burn(msg.sender, amount);\n uint256 bridgeOut = amount;\n if (isFeeExempt[msg.sender] == 0) {\n bridgeOut -= (bridgeOut * bridgeDetails.fee) / BASE_PARAMS;\n }\n IERC20(bridgeToken).safeTransfer(to, bridgeOut);\n return bridgeOut;\n }\n\n // ======================= Governance Functions ================================\n\n /// @notice Adds support for a bridge token\n /// @param bridgeToken Bridge token to add: it should be a version of the stablecoin from another bridge\n /// @param limit Limit on the balance of bridge token this contract could hold\n /// @param hourlyLimit Limit on the hourly volume for this bridge\n /// @param paused Whether swapping for this token should be paused or not\n /// @param fee Fee taken upon swapping for or against this token\n function addBridgeToken(\n address bridgeToken,\n uint256 limit,\n uint256 hourlyLimit,\n uint64 fee,\n bool paused\n ) external onlyGovernor {\n if (bridges[bridgeToken].allowed || bridgeToken == address(0)) revert InvalidToken();\n if (fee > BASE_PARAMS) revert TooHighParameterValue();\n BridgeDetails memory _bridge;\n _bridge.limit = limit;\n _bridge.hourlyLimit = hourlyLimit;\n _bridge.paused = paused;\n _bridge.fee = fee;\n _bridge.allowed = true;\n bridges[bridgeToken] = _bridge;\n bridgeTokensList.push(bridgeToken);\n emit BridgeTokenAdded(bridgeToken, limit, hourlyLimit, fee, paused);\n }\n\n /// @notice Removes support for a token\n /// @param bridgeToken Address of the bridge token to remove support for\n function removeBridgeToken(address bridgeToken) external onlyGovernor {\n if (IERC20(bridgeToken).balanceOf(address(this)) != 0) revert AssetStillControlledInReserves();\n delete bridges[bridgeToken];\n // Deletion from `bridgeTokensList` loop\n uint256 bridgeTokensListLength = bridgeTokensList.length;\n for (uint256 i; i < bridgeTokensListLength - 1; ++i) {\n if (bridgeTokensList[i] == bridgeToken) {\n // Replace the `bridgeToken` to remove with the last of the list\n bridgeTokensList[i] = bridgeTokensList[bridgeTokensListLength - 1];\n break;\n }\n }\n // Remove last element in array\n bridgeTokensList.pop();\n emit BridgeTokenRemoved(bridgeToken);\n }\n\n /// @notice Recovers any ERC20 token\n /// @dev Can be used to withdraw bridge tokens for them to be de-bridged on mainnet\n function recoverERC20(address tokenAddress, address to, uint256 amountToRecover) external onlyGovernor {\n IERC20(tokenAddress).safeTransfer(to, amountToRecover);\n emit Recovered(tokenAddress, to, amountToRecover);\n }\n\n /// @notice Updates the `limit` amount for `bridgeToken`\n function setLimit(address bridgeToken, uint256 limit) external onlyGovernorOrGuardian {\n if (!bridges[bridgeToken].allowed) revert InvalidToken();\n bridges[bridgeToken].limit = limit;\n emit BridgeTokenLimitUpdated(bridgeToken, limit);\n }\n\n /// @notice Updates the `hourlyLimit` amount for `bridgeToken`\n function setHourlyLimit(address bridgeToken, uint256 hourlyLimit) external onlyGovernorOrGuardian {\n if (!bridges[bridgeToken].allowed) revert InvalidToken();\n bridges[bridgeToken].hourlyLimit = hourlyLimit;\n emit BridgeTokenHourlyLimitUpdated(bridgeToken, hourlyLimit);\n }\n\n /// @notice Updates the `fee` value for `bridgeToken`\n function setSwapFee(address bridgeToken, uint64 fee) external onlyGovernorOrGuardian {\n if (!bridges[bridgeToken].allowed) revert InvalidToken();\n if (fee > BASE_PARAMS) revert TooHighParameterValue();\n bridges[bridgeToken].fee = fee;\n emit BridgeTokenFeeUpdated(bridgeToken, fee);\n }\n\n /// @notice Pauses or unpauses swapping in and out for a token\n function toggleBridge(address bridgeToken) external onlyGovernorOrGuardian {\n if (!bridges[bridgeToken].allowed) revert InvalidToken();\n bool pausedStatus = bridges[bridgeToken].paused;\n bridges[bridgeToken].paused = !pausedStatus;\n emit BridgeTokenToggled(bridgeToken, !pausedStatus);\n }\n\n /// @notice Toggles fees for the address `theAddress`\n function toggleFeesForAddress(address theAddress) external onlyGovernorOrGuardian {\n uint256 feeExemptStatus = 1 - isFeeExempt[theAddress];\n isFeeExempt[theAddress] = feeExemptStatus;\n emit FeeToggled(theAddress, feeExemptStatus);\n }\n}\n" + }, + "contracts/mock/MockStableMaster.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\nimport \"../interfaces/IAgToken.sol\";\nimport \"./MockToken.sol\";\nimport \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\nimport \"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\";\nimport { SLPData, MintBurnData } from \"../interfaces/coreModule/IStableMaster.sol\";\n\n// All the details about a collateral that are going to be stored in `StableMaster`\nstruct Collateral {\n // Interface for the token accepted by the underlying `PoolManager` contract\n IERC20 token;\n // Reference to the `SanToken` for the pool\n MockToken sanToken;\n // Reference to the `PerpetualManager` for the pool\n address perpetualManager;\n // Adress of the oracle for the change rate between\n // collateral and the corresponding stablecoin\n address oracle;\n // Amount of collateral in the reserves that comes from users\n // converted in stablecoin value. Updated at minting and burning.\n // A `stocksUsers` of 10 for a collateral type means that overall the balance of the collateral from users\n // that minted/burnt stablecoins using this collateral is worth 10 of stablecoins\n uint256 stocksUsers;\n // Exchange rate between sanToken and collateral\n uint256 sanRate;\n // Base used in the collateral implementation (ERC20 decimal)\n uint256 collatBase;\n // Parameters for SLPs and update of the `sanRate`\n SLPData slpData;\n // All the fees parameters\n MintBurnData feeData;\n}\n\ncontract MockStableMaster {\n mapping(address => uint256) public poolManagerMap;\n\n constructor() {}\n\n function updateStocksUsers(uint256 amount, address poolManager) external {\n poolManagerMap[poolManager] += amount;\n }\n\n function burnSelf(IAgToken agToken, uint256 amount, address burner) external {\n agToken.burnSelf(amount, burner);\n }\n\n function burnFrom(IAgToken agToken, uint256 amount, address burner, address sender) external {\n agToken.burnFrom(amount, burner, sender);\n }\n\n function mint(IAgToken agToken, address account, uint256 amount) external {\n agToken.mint(account, amount);\n }\n}\n\ncontract MockStableMasterSanWrapper is MockStableMaster {\n using SafeERC20 for IERC20;\n\n /// @notice Maps a `PoolManager` contract handling a collateral for this stablecoin to the properties of the struct above\n mapping(address => Collateral) public collateralMap;\n\n constructor() MockStableMaster() {}\n\n uint256 internal constant _BASE_TOKENS = 10 ** 18;\n uint256 internal constant _BASE_PARAMS = 10 ** 9;\n IERC20 public token;\n\n function deposit(uint256 assets, address receiver, address poolManager) external {\n token.safeTransferFrom(msg.sender, address(this), assets);\n Collateral storage col = collateralMap[poolManager];\n _updateSanRate(col);\n uint256 amount = (assets * _BASE_TOKENS) / col.sanRate;\n col.sanToken.mint(receiver, amount);\n }\n\n function withdraw(uint256 assets, address sender, address receiver, address poolManager) external {\n Collateral storage col = collateralMap[poolManager];\n _updateSanRate(col);\n col.sanToken.burn(sender, assets);\n // Computing the amount of collateral to give back to the SLP depending on slippage and on the `sanRate`\n uint256 redeemInC = (assets * (_BASE_PARAMS - col.slpData.slippage) * col.sanRate) /\n (_BASE_TOKENS * _BASE_PARAMS);\n token.safeTransfer(receiver, redeemInC);\n }\n\n function setPoolManagerToken(address, address token_) external {\n token = MockToken(token_);\n }\n\n function setPoolManagerSanToken(address poolManager, address sanToken_) external {\n Collateral storage col = collateralMap[poolManager];\n col.sanToken = MockToken(sanToken_);\n }\n\n function setSanRate(address poolManager, uint256 sanRate_) external {\n Collateral storage col = collateralMap[poolManager];\n col.sanRate = sanRate_;\n }\n\n function _updateSanRate(Collateral storage col) internal {\n uint256 _lockedInterests = col.slpData.lockedInterests;\n // Checking if the `sanRate` has been updated in the current block using past block fees\n // This is a way to prevent flash loans attacks when an important amount of fees are going to be distributed\n // in a block: fees are stored but will just be distributed to SLPs who will be here during next blocks\n if (block.timestamp != col.slpData.lastBlockUpdated && _lockedInterests > 0) {\n uint256 sanMint = col.sanToken.totalSupply();\n if (sanMint != 0) {\n // Checking if the update is too important and should be made in multiple blocks\n if (_lockedInterests > col.slpData.maxInterestsDistributed) {\n // `sanRate` is expressed in `BASE_TOKENS`\n col.sanRate += (col.slpData.maxInterestsDistributed * 10 ** 18) / sanMint;\n _lockedInterests -= col.slpData.maxInterestsDistributed;\n } else {\n col.sanRate += (_lockedInterests * 10 ** 18) / sanMint;\n _lockedInterests = 0;\n }\n } else {\n _lockedInterests = 0;\n }\n }\n col.slpData.lockedInterests = _lockedInterests;\n col.slpData.lastBlockUpdated = block.timestamp;\n }\n\n // copy paste from the deployed contract\n function estimateSanRate(address poolManager) external view returns (uint256 sanRate, uint64 slippage) {\n Collateral memory col = collateralMap[poolManager];\n uint256 _lockedInterests = col.slpData.lockedInterests;\n // Checking if the `sanRate` has been updated in the current block using past block fees\n // This is a way to prevent flash loans attacks when an important amount of fees are going to be distributed\n // in a block: fees are stored but will just be distributed to SLPs who will be here during next blocks\n if (block.timestamp != col.slpData.lastBlockUpdated && _lockedInterests > 0) {\n uint256 sanMint = col.sanToken.totalSupply();\n if (sanMint != 0) {\n // Checking if the update is too important and should be made in multiple blocks\n if (_lockedInterests > col.slpData.maxInterestsDistributed) {\n // `sanRate` is expressed in `BASE_TOKENS`\n col.sanRate += (col.slpData.maxInterestsDistributed * 10 ** 18) / sanMint;\n _lockedInterests -= col.slpData.maxInterestsDistributed;\n } else {\n col.sanRate += (_lockedInterests * 10 ** 18) / sanMint;\n _lockedInterests = 0;\n }\n } else {\n _lockedInterests = 0;\n }\n }\n return (col.sanRate, col.slpData.slippage);\n }\n\n function setSLPData(\n address poolManager,\n uint256 lockedInterests,\n uint256 maxInterestsDistributed,\n uint64 slippage\n ) external {\n Collateral storage col = collateralMap[poolManager];\n col.slpData.lockedInterests = lockedInterests;\n col.slpData.maxInterestsDistributed = maxInterestsDistributed;\n col.slpData.slippage = slippage;\n }\n}\n" + }, + "contracts/mock/MockSwapper.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\nimport \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\nimport \"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\";\n\nimport \"../interfaces/ISwapper.sol\";\n\ncontract MockSwapper is ISwapper {\n bytes32 public constant CALLBACK_SUCCESS = keccak256(\"ERC3156FlashBorrower.onFlashLoan\");\n\n uint256 public counter;\n\n constructor() {}\n\n function swap(IERC20, IERC20, address, uint256, uint256, bytes calldata data) external {\n counter += 1;\n data;\n }\n}\n\ncontract MockSwapperWithSwap is ISwapper {\n using SafeERC20 for IERC20;\n bytes32 public constant CALLBACK_SUCCESS = keccak256(\"ERC3156FlashBorrower.onFlashLoan\");\n\n uint256 public counter;\n\n constructor() {}\n\n function swap(\n IERC20,\n IERC20 outToken,\n address outTokenRecipient,\n uint256 outTokenOwed,\n uint256,\n bytes calldata data\n ) external {\n counter += 1;\n outToken.safeTransfer(outTokenRecipient, outTokenOwed);\n\n data;\n }\n}\n" + }, + "contracts/mock/MockSwapperSidechain.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\nimport \"../swapper/Swapper.sol\";\n\n/// @title MockSwapperSidechain\n/// @author Angle Labs, Inc.\ncontract MockSwapperSidechain is Swapper {\n error NotImplemented();\n\n /// @notice Constructor of the contract\n /// @param _core Core address\n /// @param _uniV3Router UniswapV3 Router address\n /// @param _oneInch 1Inch Router address\n /// @param _angleRouter AngleRouter contract address\n constructor(\n ICoreBorrow _core,\n IUniswapV3Router _uniV3Router,\n address _oneInch,\n IAngleRouterSidechain _angleRouter\n ) Swapper(_core, _uniV3Router, _oneInch, _angleRouter) {}\n\n function _swapLeverage(bytes memory) internal pure override returns (uint256) {\n revert NotImplemented();\n }\n}\n" + }, + "contracts/mock/MockToken.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.7;\n\nimport \"@openzeppelin/contracts/token/ERC20/ERC20.sol\";\n\ncontract MockToken is ERC20 {\n event Minting(address indexed _to, address indexed _minter, uint256 _amount);\n\n event Burning(address indexed _from, address indexed _burner, uint256 _amount);\n\n uint8 internal _decimal;\n mapping(address => bool) public minters;\n address public treasury;\n\n constructor(string memory name_, string memory symbol_, uint8 decimal_) ERC20(name_, symbol_) {\n _decimal = decimal_;\n }\n\n function decimals() public view override returns (uint8) {\n return _decimal;\n }\n\n function mint(address account, uint256 amount) external {\n _mint(account, amount);\n emit Minting(account, msg.sender, amount);\n }\n\n function burn(address account, uint256 amount) public {\n _burn(account, amount);\n emit Burning(account, msg.sender, amount);\n }\n\n function setAllowance(address from, address to) public {\n _approve(from, to, type(uint256).max);\n }\n\n function burnSelf(uint256 amount, address account) public {\n _burn(account, amount);\n emit Burning(account, msg.sender, amount);\n }\n\n function addMinter(address minter) public {\n minters[minter] = true;\n }\n\n function removeMinter(address minter) public {\n minters[minter] = false;\n }\n\n function setTreasury(address _treasury) public {\n treasury = _treasury;\n }\n}\n" + }, + "contracts/mock/MockTokenPermit.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.7;\n\nimport \"@openzeppelin/contracts/token/ERC20/extensions/draft-ERC20Permit.sol\";\nimport \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\nimport \"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\";\n\ncontract MockTokenPermit is ERC20Permit {\n using SafeERC20 for IERC20;\n event Minting(address indexed _to, address indexed _minter, uint256 _amount);\n\n event Burning(address indexed _from, address indexed _burner, uint256 _amount);\n\n uint8 internal _decimal;\n mapping(address => bool) public minters;\n address public treasury;\n uint256 public fees;\n\n bool public reverts;\n\n constructor(string memory name_, string memory symbol_, uint8 decimal_) ERC20Permit(name_) ERC20(name_, symbol_) {\n _decimal = decimal_;\n }\n\n function decimals() public view override returns (uint8) {\n return _decimal;\n }\n\n function mint(address account, uint256 amount) external {\n _mint(account, amount);\n emit Minting(account, msg.sender, amount);\n }\n\n function burn(address account, uint256 amount) public {\n _burn(account, amount);\n emit Burning(account, msg.sender, amount);\n }\n\n function setAllowance(address from, address to) public {\n _approve(from, to, type(uint256).max);\n }\n\n function burnSelf(uint256 amount, address account) public {\n _burn(account, amount);\n emit Burning(account, msg.sender, amount);\n }\n\n function addMinter(address minter) public {\n minters[minter] = true;\n }\n\n function removeMinter(address minter) public {\n minters[minter] = false;\n }\n\n function setTreasury(address _treasury) public {\n treasury = _treasury;\n }\n\n function setFees(uint256 _fees) public {\n fees = _fees;\n }\n\n function recoverERC20(IERC20 token, address to, uint256 amount) external {\n token.safeTransfer(to, amount);\n }\n\n function swapIn(address bridgeToken, uint256 amount, address to) external returns (uint256) {\n require(!reverts);\n\n IERC20(bridgeToken).safeTransferFrom(msg.sender, address(this), amount);\n uint256 canonicalOut = amount;\n canonicalOut -= (canonicalOut * fees) / 10 ** 9;\n _mint(to, canonicalOut);\n return canonicalOut;\n }\n\n function swapOut(address bridgeToken, uint256 amount, address to) external returns (uint256) {\n require(!reverts);\n _burn(msg.sender, amount);\n uint256 bridgeOut = amount;\n bridgeOut -= (bridgeOut * fees) / 10 ** 9;\n IERC20(bridgeToken).safeTransfer(to, bridgeOut);\n return bridgeOut;\n }\n}\n" + }, + "contracts/mock/MockTreasury.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\nimport \"../interfaces/ITreasury.sol\";\nimport \"../interfaces/IFlashAngle.sol\";\nimport \"../interfaces/IVaultManager.sol\";\n\ncontract MockTreasury is ITreasury {\n IAgToken public override stablecoin;\n address public governor;\n address public guardian;\n address public vaultManager1;\n address public vaultManager2;\n address public flashLoanModule;\n address[] public vaultManagerList;\n\n constructor(\n IAgToken _stablecoin,\n address _governor,\n address _guardian,\n address _vaultManager1,\n address _vaultManager2,\n address _flashLoanModule\n ) {\n stablecoin = _stablecoin;\n governor = _governor;\n guardian = _guardian;\n vaultManager1 = _vaultManager1;\n vaultManager2 = _vaultManager2;\n flashLoanModule = _flashLoanModule;\n }\n\n function isGovernor(address admin) external view override returns (bool) {\n return (admin == governor);\n }\n\n function isGovernorOrGuardian(address admin) external view override returns (bool) {\n return (admin == governor || admin == guardian);\n }\n\n function isVaultManager(address _vaultManager) external view override returns (bool) {\n return (_vaultManager == vaultManager1 || _vaultManager == vaultManager2);\n }\n\n function setStablecoin(IAgToken _stablecoin) external {\n stablecoin = _stablecoin;\n }\n\n function setFlashLoanModule(address _flashLoanModule) external override {\n flashLoanModule = _flashLoanModule;\n }\n\n function setGovernor(address _governor) external {\n governor = _governor;\n }\n\n function setVaultManager(address _vaultManager) external {\n vaultManager1 = _vaultManager;\n }\n\n function setVaultManager2(address _vaultManager) external {\n vaultManager2 = _vaultManager;\n }\n\n function setTreasury(address _agTokenOrVaultManager, address _treasury) external {\n IAgToken(_agTokenOrVaultManager).setTreasury(_treasury);\n }\n\n function addMinter(IAgToken _agToken, address _minter) external {\n _agToken.addMinter(_minter);\n }\n\n function removeMinter(IAgToken _agToken, address _minter) external {\n _agToken.removeMinter(_minter);\n }\n\n function accrueInterestToTreasury(IFlashAngle flashAngle) external returns (uint256 balance) {\n balance = flashAngle.accrueInterestToTreasury(stablecoin);\n }\n\n function accrueInterestToTreasuryVaultManager(IVaultManager _vaultManager) external returns (uint256, uint256) {\n return _vaultManager.accrueInterestToTreasury();\n }\n}\n" + }, + "contracts/mock/MockUniswapV3Pool.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.7;\n\ncontract MockUniswapV3Pool {\n address public token0;\n address public token1;\n uint32 public constant EPOCH_DURATION = 24 * 3600 * 7;\n\n function setToken(address token, uint256 who) external {\n if (who == 0) token0 = token;\n else token1 = token;\n }\n\n function round(uint256 amount) external pure returns (uint256) {\n return (amount / EPOCH_DURATION) * EPOCH_DURATION;\n }\n}\n" + }, + "contracts/mock/MockVaultManager.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\nimport \"../interfaces/IVaultManager.sol\";\nimport \"../interfaces/ITreasury.sol\";\nimport \"@openzeppelin/contracts/token/ERC20/ERC20.sol\";\n\ncontract MockVaultManager {\n ITreasury public treasury;\n mapping(uint256 => Vault) public vaultData;\n mapping(uint256 => address) public ownerOf;\n uint256 public surplus;\n uint256 public badDebt;\n IAgToken public token;\n address public oracle = address(this);\n\n address public governor;\n address public collateral;\n address public stablecoin;\n uint256 public oracleValue;\n uint256 public interestAccumulator;\n uint256 public collateralFactor;\n uint256 public totalNormalizedDebt;\n\n constructor(address _treasury) {\n treasury = ITreasury(_treasury);\n }\n\n function accrueInterestToTreasury() external returns (uint256, uint256) {\n // Avoid the function to be view\n if (surplus >= badDebt) {\n token.mint(msg.sender, surplus - badDebt);\n }\n return (surplus, badDebt);\n }\n\n function read() external view returns (uint256) {\n return oracleValue;\n }\n\n function setParams(\n address _governor,\n address _collateral,\n address _stablecoin,\n uint256 _oracleValue,\n uint256 _interestAccumulator,\n uint256 _collateralFactor,\n uint256 _totalNormalizedDebt\n ) external {\n governor = _governor;\n collateral = _collateral;\n stablecoin = _stablecoin;\n interestAccumulator = _interestAccumulator;\n collateralFactor = _collateralFactor;\n totalNormalizedDebt = _totalNormalizedDebt;\n oracleValue = _oracleValue;\n }\n\n function setOwner(uint256 vaultID, address owner) external virtual {\n ownerOf[vaultID] = owner;\n }\n\n function setVaultData(uint256 normalizedDebt, uint256 collateralAmount, uint256 vaultID) external {\n vaultData[vaultID].normalizedDebt = normalizedDebt;\n vaultData[vaultID].collateralAmount = collateralAmount;\n }\n\n function isGovernor(address admin) external view returns (bool) {\n return admin == governor;\n }\n\n function setSurplusBadDebt(uint256 _surplus, uint256 _badDebt, IAgToken _token) external {\n surplus = _surplus;\n badDebt = _badDebt;\n token = _token;\n }\n\n function getDebtOut(uint256 vaultID, uint256 amountStablecoins, uint256 senderBorrowFee) external {}\n\n function setTreasury(address _treasury) external {\n treasury = ITreasury(_treasury);\n }\n\n function getVaultDebt(uint256 vaultID) external view returns (uint256) {\n vaultID;\n token;\n return 0;\n }\n\n function createVault(address toVault) external view returns (uint256) {\n toVault;\n token;\n return 0;\n }\n}\n\ncontract MockVaultManagerListing is MockVaultManager {\n // @notice Mapping from owner address to all his vaults\n mapping(address => uint256[]) internal _ownerListVaults;\n\n constructor(address _treasury) MockVaultManager(_treasury) {}\n\n function getUserVaults(address owner) public view returns (uint256[] memory) {\n return _ownerListVaults[owner];\n }\n\n function getUserCollateral(address owner) public view returns (uint256 totalCollateral) {\n uint256[] memory vaultList = _ownerListVaults[owner];\n uint256 vaultListLength = vaultList.length;\n for (uint256 k; k < vaultListLength; ++k) {\n totalCollateral += vaultData[vaultList[k]].collateralAmount;\n }\n return totalCollateral;\n }\n\n function setOwner(uint256 vaultID, address owner) external override {\n if (ownerOf[vaultID] != address(0)) _removeVaultFromList(ownerOf[vaultID], vaultID);\n _ownerListVaults[owner].push(vaultID);\n ownerOf[vaultID] = owner;\n }\n\n /// @notice Remove `vaultID` from `user` stroed vault list\n /// @param user Address to look out for the vault list\n /// @param vaultID VaultId to remove from the list\n /// @dev The vault is necessarily in the list\n function _removeVaultFromList(address user, uint256 vaultID) internal {\n uint256[] storage vaultList = _ownerListVaults[user];\n uint256 vaultListLength = vaultList.length;\n for (uint256 i; i < vaultListLength - 1; ++i) {\n if (vaultList[i] == vaultID) {\n vaultList[i] = vaultList[vaultListLength - 1];\n break;\n }\n }\n vaultList.pop();\n }\n}\n" + }, + "contracts/mock/MockVeBoostProxy.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\nimport \"../interfaces/governance/IVeBoostProxy.sol\";\n\ncontract MockVeBoostProxy is IVeBoostProxy {\n //solhint-disable-next-line\n mapping(address => uint256) public adjusted_balance_of;\n\n constructor() {}\n\n function setBalance(address concerned, uint256 balance) external {\n adjusted_balance_of[concerned] = balance;\n }\n}\n" + }, + "contracts/oracle/BaseOracleChainlinkMulti.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\n/*\n * █ \n ***** ▓▓▓ \n * ▓▓▓▓▓▓▓ \n * ///. ▓▓▓▓▓▓▓▓▓▓▓▓▓ \n ***** //////// ▓▓▓▓▓▓▓ \n * ///////////// ▓▓▓ \n ▓▓ ////////////////// █ ▓▓ \n ▓▓ ▓▓ /////////////////////// ▓▓ ▓▓ \n ▓▓ ▓▓ //////////////////////////// ▓▓ ▓▓ \n ▓▓ ▓▓ /////////▓▓▓///////▓▓▓///////// ▓▓ ▓▓ \n ▓▓ ,////////////////////////////////////// ▓▓ ▓▓ \n ▓▓ ////////////////////////////////////////// ▓▓ \n ▓▓ //////////////////////▓▓▓▓///////////////////// \n ,//////////////////////////////////////////////////// \n .////////////////////////////////////////////////////////// \n .//////////////////////////██.,//////////////////////////█ \n .//////////////////////████..,./////////////////////██ \n ...////////////////███████.....,.////////////////███ \n ,.,////////////████████ ........,///////////████ \n .,.,//////█████████ ,.......///////████ \n ,..//████████ ........./████ \n ..,██████ .....,███ \n .██ ,.,█ \n \n \n \n ▓▓ ▓▓▓▓▓▓▓▓▓▓ ▓▓▓▓▓▓▓▓▓▓ ▓▓ ▓▓▓▓▓▓▓▓▓▓ \n ▓▓▓▓▓▓ ▓▓▓ ▓▓▓ ▓▓▓ ▓▓ ▓▓ ▓▓▓▓ \n ▓▓▓ ▓▓▓ ▓▓▓ ▓▓▓ ▓▓▓ ▓▓▓ ▓▓ ▓▓▓▓▓ \n ▓▓▓ ▓▓ ▓▓▓ ▓▓▓ ▓▓▓▓▓▓▓▓▓▓ ▓▓▓▓▓▓▓▓▓▓ ▓▓▓▓▓▓▓▓▓▓ \n*/\n\npragma solidity ^0.8.12;\n\nimport \"@chainlink/contracts/src/v0.8/interfaces/AggregatorV3Interface.sol\";\n\nimport \"../interfaces/IOracle.sol\";\nimport \"../interfaces/ITreasury.sol\";\n\n/// @title BaseOracleChainlinkMulti\n/// @author Angle Labs, Inc.\n/// @notice Base Contract to be overriden by all contracts of the protocol\n/// @dev This base contract concerns an oracle that uses Chainlink with multiple pools to read from\n/// @dev All gas-efficient implementation of the `OracleChainlinkMulti` contract should inherit from this\nabstract contract BaseOracleChainlinkMulti is IOracle {\n // ========================= Parameters and References =========================\n\n /// @inheritdoc IOracle\n ITreasury public override treasury;\n /// @notice Represent the maximum amount of time (in seconds) between each Chainlink update\n /// before the price feed is considered stale\n uint32 public stalePeriod;\n\n // =================================== Event ===================================\n\n event StalePeriodUpdated(uint32 _stalePeriod);\n\n // =================================== Errors ===================================\n\n error InvalidChainlinkRate();\n error NotGovernorOrGuardian();\n error NotVaultManagerOrGovernor();\n\n /// @notice Constructor for an oracle using Chainlink with multiple pools to read from\n /// @param _stalePeriod Minimum feed update frequency for the oracle to not revert\n /// @param _treasury Treasury associated to the VaultManager which reads from this feed\n constructor(uint32 _stalePeriod, address _treasury) {\n stalePeriod = _stalePeriod;\n treasury = ITreasury(_treasury);\n }\n\n // ============================= Reading Oracles ===============================\n\n /// @inheritdoc IOracle\n function read() external view virtual override returns (uint256 quoteAmount);\n\n /// @inheritdoc IOracle\n function circuitChainlink() public view virtual returns (AggregatorV3Interface[] memory);\n\n /// @notice Reads a Chainlink feed using a quote amount and converts the quote amount to\n /// the out-currency\n /// @param quoteAmount The amount for which to compute the price expressed with base decimal\n /// @param feed Chainlink feed to query\n /// @param multiplied Whether the ratio outputted by Chainlink should be multiplied or divided\n /// to the `quoteAmount`\n /// @param decimals Number of decimals of the corresponding Chainlink pair\n /// @return The `quoteAmount` converted in out-currency\n function _readChainlinkFeed(\n uint256 quoteAmount,\n AggregatorV3Interface feed,\n uint8 multiplied,\n uint256 decimals\n ) internal view returns (uint256) {\n (uint80 roundId, int256 ratio, , uint256 updatedAt, uint80 answeredInRound) = feed.latestRoundData();\n if (ratio <= 0 || roundId > answeredInRound || block.timestamp - updatedAt > stalePeriod)\n revert InvalidChainlinkRate();\n uint256 castedRatio = uint256(ratio);\n // Checking whether we should multiply or divide by the ratio computed\n if (multiplied == 1) return (quoteAmount * castedRatio) / (10 ** decimals);\n else return (quoteAmount * (10 ** decimals)) / castedRatio;\n }\n\n // ======================= Governance Related Functions ========================\n\n /// @notice Changes the stale period\n /// @param _stalePeriod New stale period (in seconds)\n function changeStalePeriod(uint32 _stalePeriod) external {\n if (!treasury.isGovernorOrGuardian(msg.sender)) revert NotGovernorOrGuardian();\n stalePeriod = _stalePeriod;\n emit StalePeriodUpdated(_stalePeriod);\n }\n\n /// @inheritdoc IOracle\n function setTreasury(address _treasury) external override {\n if (!treasury.isVaultManager(msg.sender) && !treasury.isGovernor(msg.sender))\n revert NotVaultManagerOrGovernor();\n treasury = ITreasury(_treasury);\n }\n}\n" + }, + "contracts/oracle/BaseOracleChainlinkMultiTwoFeeds.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\nimport \"@chainlink/contracts/src/v0.8/interfaces/AggregatorV3Interface.sol\";\n\nimport \"./BaseOracleChainlinkMulti.sol\";\n\n/// @title BaseOracleChainlinkMultiTwoFeeds\n/// @author Angle Labs, Inc.\n/// @notice Base contract for an oracle that reads into two Chainlink feeds (including an EUR/USD feed) which both have\n/// 8 decimals\nabstract contract BaseOracleChainlinkMultiTwoFeeds is BaseOracleChainlinkMulti {\n constructor(uint32 _stalePeriod, address _treasury) BaseOracleChainlinkMulti(_stalePeriod, _treasury) {}\n\n /// @notice Returns the quote amount of the oracle contract\n function _getQuoteAmount() internal view virtual returns (uint256) {\n return 10 ** 18;\n }\n\n /// @inheritdoc IOracle\n function read() external view virtual override returns (uint256 quoteAmount) {\n quoteAmount = _getQuoteAmount();\n AggregatorV3Interface[] memory _circuitChainlink = circuitChainlink();\n uint8[2] memory circuitChainIsMultiplied = [1, 0];\n uint8[2] memory chainlinkDecimals = [8, 8];\n uint256 circuitLength = _circuitChainlink.length;\n for (uint256 i; i < circuitLength; ++i) {\n quoteAmount = _readChainlinkFeed(\n quoteAmount,\n _circuitChainlink[i],\n circuitChainIsMultiplied[i],\n chainlinkDecimals[i]\n );\n }\n }\n}\n" + }, + "contracts/oracle/BaseOracleChainlinkOneFeed.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\nimport \"@chainlink/contracts/src/v0.8/interfaces/AggregatorV3Interface.sol\";\n\nimport \"./BaseOracleChainlinkMulti.sol\";\n\n/// @title BaseOracleChainlinkOneFeed\n/// @author Angle Labs, Inc.\n/// @notice Base contract for an oracle that reads into one Chainlink feeds with 8 decimals\nabstract contract BaseOracleChainlinkOneFeed is BaseOracleChainlinkMulti {\n constructor(uint32 _stalePeriod, address _treasury) BaseOracleChainlinkMulti(_stalePeriod, _treasury) {}\n\n /// @notice Returns the quote amount of the oracle contract\n function _getQuoteAmount() internal view virtual returns (uint256) {\n return 10 ** 18;\n }\n\n /// @inheritdoc IOracle\n function read() external view virtual override returns (uint256 quoteAmount) {\n AggregatorV3Interface[] memory _circuitChainlink = circuitChainlink();\n quoteAmount = _readChainlinkFeed(_getQuoteAmount(), _circuitChainlink[0], 1, 8);\n }\n}\n" + }, + "contracts/oracle/implementations/arbitrum/EUR/OracleBTCEURChainlinkArbitrum.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\nimport \"@chainlink/contracts/src/v0.8/interfaces/AggregatorV3Interface.sol\";\n\nimport \"../../../BaseOracleChainlinkMultiTwoFeeds.sol\";\n\n/// @title OracleBTCEURChainlinkArbitrum\n/// @author Angle Labs, Inc.\n/// @notice Gives the price of BTC in Euro in base 18\n/// @dev This contract is built to be deployed on Arbitrum\ncontract OracleBTCEURChainlinkArbitrum is BaseOracleChainlinkMultiTwoFeeds {\n string public constant DESCRIPTION = \"BTC/EUR Oracle\";\n\n constructor(uint32 _stalePeriod, address _treasury) BaseOracleChainlinkMultiTwoFeeds(_stalePeriod, _treasury) {}\n\n /// @inheritdoc IOracle\n function circuitChainlink() public pure override returns (AggregatorV3Interface[] memory) {\n AggregatorV3Interface[] memory _circuitChainlink = new AggregatorV3Interface[](2);\n // Oracle BTC/USD\n _circuitChainlink[0] = AggregatorV3Interface(0x6ce185860a4963106506C203335A2910413708e9);\n // Oracle EUR/USD\n _circuitChainlink[1] = AggregatorV3Interface(0xA14d53bC1F1c0F31B4aA3BD109344E5009051a84);\n return _circuitChainlink;\n }\n}\n" + }, + "contracts/oracle/implementations/arbitrum/EUR/OracleETHEURChainlinkArbitrum.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\nimport \"@chainlink/contracts/src/v0.8/interfaces/AggregatorV3Interface.sol\";\n\nimport \"../../../BaseOracleChainlinkMultiTwoFeeds.sol\";\n\n/// @title OracleETHEURChainlinkArbitrum\n/// @author Angle Labs, Inc.\n/// @notice Gives the price of ETH in Euro in base 18\n/// @dev This contract is built to be deployed on Arbitrum\ncontract OracleETHEURChainlinkArbitrum is BaseOracleChainlinkMultiTwoFeeds {\n string public constant DESCRIPTION = \"ETH/EUR Oracle\";\n\n constructor(uint32 _stalePeriod, address _treasury) BaseOracleChainlinkMultiTwoFeeds(_stalePeriod, _treasury) {}\n\n /// @inheritdoc IOracle\n function circuitChainlink() public pure override returns (AggregatorV3Interface[] memory) {\n AggregatorV3Interface[] memory _circuitChainlink = new AggregatorV3Interface[](2);\n // Oracle ETH/USD\n _circuitChainlink[0] = AggregatorV3Interface(0x639Fe6ab55C921f74e7fac1ee960C0B6293ba612);\n // Oracle EUR/USD\n _circuitChainlink[1] = AggregatorV3Interface(0xA14d53bC1F1c0F31B4aA3BD109344E5009051a84);\n return _circuitChainlink;\n }\n}\n" + }, + "contracts/oracle/implementations/arbitrum/EUR/OracleUSDCEURChainlinkArbitrum.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\nimport \"@chainlink/contracts/src/v0.8/interfaces/AggregatorV3Interface.sol\";\n\nimport \"../../../BaseOracleChainlinkMultiTwoFeeds.sol\";\n\n/// @title OracleUSDCEURChainlinkArbitrum\n/// @author Angle Labs, Inc.\n/// @notice Gives the price of USDC in Euro in base 18\n/// @dev This contract is built to be deployed on Arbitrum\ncontract OracleUSDCEURChainlinkArbitrum is BaseOracleChainlinkMultiTwoFeeds {\n string public constant DESCRIPTION = \"USDC/EUR Oracle\";\n\n constructor(uint32 _stalePeriod, address _treasury) BaseOracleChainlinkMultiTwoFeeds(_stalePeriod, _treasury) {}\n\n /// @inheritdoc IOracle\n function circuitChainlink() public pure override returns (AggregatorV3Interface[] memory) {\n AggregatorV3Interface[] memory _circuitChainlink = new AggregatorV3Interface[](2);\n // Oracle ETH/USD\n _circuitChainlink[0] = AggregatorV3Interface(0x50834F3163758fcC1Df9973b6e91f0F0F0434aD3);\n // Oracle EUR/USD\n _circuitChainlink[1] = AggregatorV3Interface(0xA14d53bC1F1c0F31B4aA3BD109344E5009051a84);\n return _circuitChainlink;\n }\n}\n" + }, + "contracts/oracle/implementations/avalanche/EUR/OracleAVAXEURChainlinkAvalanche.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\nimport \"@chainlink/contracts/src/v0.8/interfaces/AggregatorV3Interface.sol\";\n\nimport \"../../../BaseOracleChainlinkMultiTwoFeeds.sol\";\n\n/// @title OracleAVAXEURChainlinkAvalanche\n/// @author Angle Labs, Inc.\n/// @notice Gives the price of AVAX in Euro in base 18\n/// @dev This contract is built to be deployed on Avalanche\ncontract OracleAVAXEURChainlinkAvalanche is BaseOracleChainlinkMultiTwoFeeds {\n string public constant DESCRIPTION = \"AVAX/EUR Oracle\";\n\n constructor(uint32 _stalePeriod, address _treasury) BaseOracleChainlinkMultiTwoFeeds(_stalePeriod, _treasury) {}\n\n /// @inheritdoc IOracle\n function circuitChainlink() public pure override returns (AggregatorV3Interface[] memory) {\n AggregatorV3Interface[] memory _circuitChainlink = new AggregatorV3Interface[](2);\n // Oracle AVAX/USD\n _circuitChainlink[0] = AggregatorV3Interface(0x0A77230d17318075983913bC2145DB16C7366156);\n // Oracle EUR/USD\n _circuitChainlink[1] = AggregatorV3Interface(0x192f2DBA961Bb0277520C082d6bfa87D5961333E);\n return _circuitChainlink;\n }\n}\n" + }, + "contracts/oracle/implementations/avalanche/EUR/OracleUSDCEURChainlinkAvalanche.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\nimport \"@chainlink/contracts/src/v0.8/interfaces/AggregatorV3Interface.sol\";\n\nimport \"../../../BaseOracleChainlinkMultiTwoFeeds.sol\";\n\n/// @title OracleUSDCEURChainlinkAvalanche\n/// @author Angle Labs, Inc.\n/// @notice Gives the price of USDC in Euro in base 18\n/// @dev This contract is built to be deployed on Avalanche\ncontract OracleUSDCEURChainlinkAvalanche is BaseOracleChainlinkMultiTwoFeeds {\n string public constant DESCRIPTION = \"USDC/EUR Oracle\";\n\n constructor(uint32 _stalePeriod, address _treasury) BaseOracleChainlinkMultiTwoFeeds(_stalePeriod, _treasury) {}\n\n /// @inheritdoc IOracle\n function circuitChainlink() public pure override returns (AggregatorV3Interface[] memory) {\n AggregatorV3Interface[] memory _circuitChainlink = new AggregatorV3Interface[](2);\n // Oracle USDC/USD\n _circuitChainlink[0] = AggregatorV3Interface(0xF096872672F44d6EBA71458D74fe67F9a77a23B9);\n // Oracle EUR/USD\n _circuitChainlink[1] = AggregatorV3Interface(0x192f2DBA961Bb0277520C082d6bfa87D5961333E);\n return _circuitChainlink;\n }\n}\n" + }, + "contracts/oracle/implementations/mainnet/EUR/OracleBTCEURChainlink.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\nimport \"@chainlink/contracts/src/v0.8/interfaces/AggregatorV3Interface.sol\";\n\nimport \"../../../BaseOracleChainlinkMultiTwoFeeds.sol\";\n\n/// @title OracleBTCEURChainlink\n/// @author Angle Labs, Inc.\n/// @notice Gives the price of BTC in Euro in base 18\ncontract OracleBTCEURChainlink is BaseOracleChainlinkMultiTwoFeeds {\n string public constant DESCRIPTION = \"BTC/EUR Oracle\";\n\n constructor(uint32 _stalePeriod, address _treasury) BaseOracleChainlinkMultiTwoFeeds(_stalePeriod, _treasury) {}\n\n /// @inheritdoc IOracle\n function circuitChainlink() public pure override returns (AggregatorV3Interface[] memory) {\n AggregatorV3Interface[] memory _circuitChainlink = new AggregatorV3Interface[](2);\n // Oracle BTC/USD\n _circuitChainlink[0] = AggregatorV3Interface(0xF4030086522a5bEEa4988F8cA5B36dbC97BeE88c);\n // Oracle EUR/USD\n _circuitChainlink[1] = AggregatorV3Interface(0xb49f677943BC038e9857d61E7d053CaA2C1734C1);\n return _circuitChainlink;\n }\n}\n" + }, + "contracts/oracle/implementations/mainnet/EUR/OracleCBETHEURChainlink.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\nimport \"@chainlink/contracts/src/v0.8/interfaces/AggregatorV3Interface.sol\";\n\nimport \"../../../BaseOracleChainlinkMultiTwoFeeds.sol\";\n\n/// @title OracleCBETHEURChainlink\n/// @author Angle Labs, Inc.\n/// @notice Gives the price of cbETH in Euro in base 18\ncontract OracleCBETHEURChainlink is BaseOracleChainlinkMultiTwoFeeds {\n string public constant DESCRIPTION = \"cbETH/EUR Oracle\";\n\n constructor(uint32 _stalePeriod, address _treasury) BaseOracleChainlinkMultiTwoFeeds(_stalePeriod, _treasury) {}\n\n /// @inheritdoc IOracle\n function circuitChainlink() public pure override returns (AggregatorV3Interface[] memory) {\n AggregatorV3Interface[] memory _circuitChainlink = new AggregatorV3Interface[](3);\n // Oracle cbETH/ETH\n _circuitChainlink[0] = AggregatorV3Interface(0xF017fcB346A1885194689bA23Eff2fE6fA5C483b);\n // Oracle ETH/USD\n _circuitChainlink[1] = AggregatorV3Interface(0x5f4eC3Df9cbd43714FE2740f5E3616155c5b8419);\n // Oracle EUR/USD\n _circuitChainlink[2] = AggregatorV3Interface(0xb49f677943BC038e9857d61E7d053CaA2C1734C1);\n return _circuitChainlink;\n }\n\n /// @inheritdoc BaseOracleChainlinkMultiTwoFeeds\n function read() external view virtual override returns (uint256 quoteAmount) {\n quoteAmount = _getQuoteAmount();\n AggregatorV3Interface[] memory _circuitChainlink = circuitChainlink();\n uint8[3] memory circuitChainIsMultiplied = [1, 1, 0];\n uint8[3] memory chainlinkDecimals = [18, 8, 8];\n uint256 circuitLength = _circuitChainlink.length;\n for (uint256 i; i < circuitLength; ++i) {\n quoteAmount = _readChainlinkFeed(\n quoteAmount,\n _circuitChainlink[i],\n circuitChainIsMultiplied[i],\n chainlinkDecimals[i]\n );\n }\n }\n}\n" + }, + "contracts/oracle/implementations/mainnet/EUR/OracleETHEURChainlink.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\nimport \"@chainlink/contracts/src/v0.8/interfaces/AggregatorV3Interface.sol\";\n\nimport \"../../../BaseOracleChainlinkMultiTwoFeeds.sol\";\n\n/// @title OracleETHEURChainlink\n/// @author Angle Labs, Inc.\n/// @notice Gives the price of ETH in Euro in base 18\ncontract OracleETHEURChainlink is BaseOracleChainlinkMultiTwoFeeds {\n string public constant DESCRIPTION = \"ETH/EUR Oracle\";\n\n constructor(uint32 _stalePeriod, address _treasury) BaseOracleChainlinkMultiTwoFeeds(_stalePeriod, _treasury) {}\n\n /// @inheritdoc IOracle\n function circuitChainlink() public pure override returns (AggregatorV3Interface[] memory) {\n AggregatorV3Interface[] memory _circuitChainlink = new AggregatorV3Interface[](2);\n // Oracle ETH/USD\n _circuitChainlink[0] = AggregatorV3Interface(0x5f4eC3Df9cbd43714FE2740f5E3616155c5b8419);\n // Oracle EUR/USD\n _circuitChainlink[1] = AggregatorV3Interface(0xb49f677943BC038e9857d61E7d053CaA2C1734C1);\n return _circuitChainlink;\n }\n}\n" + }, + "contracts/oracle/implementations/mainnet/EUR/OracleHIGHEURChainlink.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\nimport \"@chainlink/contracts/src/v0.8/interfaces/AggregatorV3Interface.sol\";\n\nimport \"../../../BaseOracleChainlinkMultiTwoFeeds.sol\";\n\n/// @title OracleHIGHEURChainlink\n/// @author Angle Labs, Inc.\n/// @notice Gives the price of HIGH in Euro in base 18\ncontract OracleHIGHEURChainlink is BaseOracleChainlinkMultiTwoFeeds {\n string public constant DESCRIPTION = \"HIGH/EUR Oracle\";\n\n constructor(uint32 _stalePeriod, address _treasury) BaseOracleChainlinkMultiTwoFeeds(_stalePeriod, _treasury) {}\n\n /// @inheritdoc IOracle\n function circuitChainlink() public pure override returns (AggregatorV3Interface[] memory) {\n AggregatorV3Interface[] memory _circuitChainlink = new AggregatorV3Interface[](1);\n // Oracle HIGH/EUR\n _circuitChainlink[0] = AggregatorV3Interface(0x9E8E794ad6Ecdb6d5c7eaBE059D30E907F58859b);\n return _circuitChainlink;\n }\n\n /// @inheritdoc BaseOracleChainlinkMultiTwoFeeds\n function read() external view override returns (uint256 quoteAmount) {\n quoteAmount = _readChainlinkFeed(_getQuoteAmount(), circuitChainlink()[0], 1, 8);\n }\n}\n" + }, + "contracts/oracle/implementations/mainnet/EUR/OracleIB01EURChainlink.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\nimport \"@chainlink/contracts/src/v0.8/interfaces/AggregatorV3Interface.sol\";\n\nimport \"../../../BaseOracleChainlinkMultiTwoFeeds.sol\";\n\n/// @title OracleIB01EURChainlink\n/// @author Angle Labs, Inc.\n/// @notice Gives the price of IB01 in Euro in base 18\ncontract OracleIB01EURChainlink is BaseOracleChainlinkMultiTwoFeeds {\n string public constant DESCRIPTION = \"IB01/EUR Oracle\";\n\n constructor(uint32 _stalePeriod, address _treasury) BaseOracleChainlinkMultiTwoFeeds(_stalePeriod, _treasury) {}\n\n /// @inheritdoc IOracle\n function circuitChainlink() public pure override returns (AggregatorV3Interface[] memory) {\n AggregatorV3Interface[] memory _circuitChainlink = new AggregatorV3Interface[](2);\n // Oracle IB01/USD\n _circuitChainlink[0] = AggregatorV3Interface(0x32d1463EB53b73C095625719Afa544D5426354cB);\n // Oracle EUR/USD\n _circuitChainlink[1] = AggregatorV3Interface(0xb49f677943BC038e9857d61E7d053CaA2C1734C1);\n return _circuitChainlink;\n }\n}\n" + }, + "contracts/oracle/implementations/mainnet/EUR/OracleLUSDEURChainlink.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\nimport \"@chainlink/contracts/src/v0.8/interfaces/AggregatorV3Interface.sol\";\n\nimport \"../../../BaseOracleChainlinkMultiTwoFeeds.sol\";\n\n/// @title OracleLUSDEURChainlink\n/// @author Angle Labs, Inc.\n/// @notice Gives the price of LUSD in Euro in base 18\ncontract OracleLUSDEURChainlink is BaseOracleChainlinkMultiTwoFeeds {\n string public constant DESCRIPTION = \"LUSD/EUR Oracle\";\n\n constructor(uint32 _stalePeriod, address _treasury) BaseOracleChainlinkMultiTwoFeeds(_stalePeriod, _treasury) {}\n\n /// @inheritdoc IOracle\n function circuitChainlink() public pure override returns (AggregatorV3Interface[] memory) {\n AggregatorV3Interface[] memory _circuitChainlink = new AggregatorV3Interface[](2);\n // Oracle LUSD/USD\n _circuitChainlink[0] = AggregatorV3Interface(0x3D7aE7E594f2f2091Ad8798313450130d0Aba3a0);\n // Oracle EUR/USD\n _circuitChainlink[1] = AggregatorV3Interface(0xb49f677943BC038e9857d61E7d053CaA2C1734C1);\n return _circuitChainlink;\n }\n}\n" + }, + "contracts/oracle/implementations/mainnet/EUR/OracleUSDCEURChainlink.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\nimport \"@chainlink/contracts/src/v0.8/interfaces/AggregatorV3Interface.sol\";\n\nimport \"../../../BaseOracleChainlinkMultiTwoFeeds.sol\";\n\n/// @title OracleUSDCEURChainlink\n/// @author Angle Labs, Inc.\n/// @notice Gives the price of USDC in Euro in base 18\ncontract OracleUSDCEURChainlink is BaseOracleChainlinkMultiTwoFeeds {\n string public constant DESCRIPTION = \"USDC/EUR Oracle\";\n\n constructor(uint32 _stalePeriod, address _treasury) BaseOracleChainlinkMultiTwoFeeds(_stalePeriod, _treasury) {}\n\n /// @inheritdoc IOracle\n function circuitChainlink() public pure override returns (AggregatorV3Interface[] memory) {\n AggregatorV3Interface[] memory _circuitChainlink = new AggregatorV3Interface[](2);\n // Oracle USDC/USD\n _circuitChainlink[0] = AggregatorV3Interface(0x8fFfFfd4AfB6115b954Bd326cbe7B4BA576818f6);\n // Oracle EUR/USD\n _circuitChainlink[1] = AggregatorV3Interface(0xb49f677943BC038e9857d61E7d053CaA2C1734C1);\n return _circuitChainlink;\n }\n}\n" + }, + "contracts/oracle/implementations/mainnet/EUR/OracleWSTETHEURChainlink.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\nimport \"@chainlink/contracts/src/v0.8/interfaces/AggregatorV3Interface.sol\";\n\nimport \"../../../BaseOracleChainlinkMultiTwoFeeds.sol\";\nimport \"../../../../interfaces/external/lido/IStETH.sol\";\n\n/// @title OracleWSTETHEURChainlink\n/// @author Angle Labs, Inc.\n/// @notice Gives the price of wSTETH in Euro in base 18\ncontract OracleWSTETHEURChainlink is BaseOracleChainlinkMultiTwoFeeds {\n string public constant DESCRIPTION = \"wSTETH/EUR Oracle\";\n IStETH public constant STETH = IStETH(0xae7ab96520DE3A18E5e111B5EaAb095312D7fE84);\n\n constructor(uint32 _stalePeriod, address _treasury) BaseOracleChainlinkMultiTwoFeeds(_stalePeriod, _treasury) {}\n\n /// @inheritdoc IOracle\n function circuitChainlink() public pure override returns (AggregatorV3Interface[] memory) {\n AggregatorV3Interface[] memory _circuitChainlink = new AggregatorV3Interface[](2);\n // Oracle stETH/USD\n _circuitChainlink[0] = AggregatorV3Interface(0xCfE54B5cD566aB89272946F602D76Ea879CAb4a8);\n // Oracle EUR/USD\n _circuitChainlink[1] = AggregatorV3Interface(0xb49f677943BC038e9857d61E7d053CaA2C1734C1);\n return _circuitChainlink;\n }\n\n /// @inheritdoc BaseOracleChainlinkMultiTwoFeeds\n function _getQuoteAmount() internal view override returns (uint256) {\n return STETH.getPooledEthByShares(1 ether);\n }\n}\n" + }, + "contracts/oracle/implementations/mainnet/USD/OracleWSTETHUSDChainlink.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\nimport \"@chainlink/contracts/src/v0.8/interfaces/AggregatorV3Interface.sol\";\n\nimport \"../../../BaseOracleChainlinkOneFeed.sol\";\nimport \"../../../../interfaces/external/lido/IStETH.sol\";\n\n/// @title OracleWSTETHUSDChainlink\n/// @author Angle Labs, Inc.\n/// @notice Gives the price of wSTETH in USD in base 18\ncontract OracleWSTETHUSDChainlink is BaseOracleChainlinkOneFeed {\n string public constant DESCRIPTION = \"wSTETH/USD Oracle\";\n IStETH public constant STETH = IStETH(0xae7ab96520DE3A18E5e111B5EaAb095312D7fE84);\n\n constructor(uint32 _stalePeriod, address _treasury) BaseOracleChainlinkOneFeed(_stalePeriod, _treasury) {}\n\n /// @inheritdoc IOracle\n function circuitChainlink() public pure override returns (AggregatorV3Interface[] memory) {\n AggregatorV3Interface[] memory _circuitChainlink = new AggregatorV3Interface[](1);\n // Oracle stETH/USD\n _circuitChainlink[0] = AggregatorV3Interface(0xCfE54B5cD566aB89272946F602D76Ea879CAb4a8);\n return _circuitChainlink;\n }\n\n /// @inheritdoc BaseOracleChainlinkOneFeed\n function _getQuoteAmount() internal view override returns (uint256) {\n return STETH.getPooledEthByShares(1 ether);\n }\n}\n" + }, + "contracts/oracle/implementations/mainnet/XAU/OracleETHXAUChainlink.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\nimport \"@chainlink/contracts/src/v0.8/interfaces/AggregatorV3Interface.sol\";\n\nimport \"../../../BaseOracleChainlinkMultiTwoFeeds.sol\";\n\n/// @title OracleETHXAUChainlink\n/// @author Angle Labs, Inc.\n/// @notice Gives the price of ETH in XAU in base 18\ncontract OracleETHXAUChainlink is BaseOracleChainlinkMultiTwoFeeds {\n string public constant DESCRIPTION = \"ETH/GOLD Oracle\";\n\n constructor(uint32 _stalePeriod, address _treasury) BaseOracleChainlinkMultiTwoFeeds(_stalePeriod, _treasury) {}\n\n /// @inheritdoc IOracle\n function circuitChainlink() public pure override returns (AggregatorV3Interface[] memory) {\n AggregatorV3Interface[] memory _circuitChainlink = new AggregatorV3Interface[](2);\n // Oracle ETH/USD\n _circuitChainlink[0] = AggregatorV3Interface(0x5f4eC3Df9cbd43714FE2740f5E3616155c5b8419);\n // Oracle XAU/USD\n _circuitChainlink[1] = AggregatorV3Interface(0x214eD9Da11D2fbe465a6fc601a91E62EbEc1a0D6);\n return _circuitChainlink;\n }\n}\n" + }, + "contracts/oracle/implementations/mainnet/XAU/OracleLUSDXAUChainlink.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\nimport \"@chainlink/contracts/src/v0.8/interfaces/AggregatorV3Interface.sol\";\n\nimport \"../../../BaseOracleChainlinkMultiTwoFeeds.sol\";\n\n/// @title OracleLUSDXAUChainlink\n/// @author Angle Labs, Inc.\n/// @notice Gives the price of LUSD in XAU in base 18\ncontract OracleLUSDXAUChainlink is BaseOracleChainlinkMultiTwoFeeds {\n string public constant DESCRIPTION = \"LUSD/GOLD Oracle\";\n\n constructor(uint32 _stalePeriod, address _treasury) BaseOracleChainlinkMultiTwoFeeds(_stalePeriod, _treasury) {}\n\n /// @inheritdoc IOracle\n function circuitChainlink() public pure override returns (AggregatorV3Interface[] memory) {\n AggregatorV3Interface[] memory _circuitChainlink = new AggregatorV3Interface[](2);\n // Oracle LUSD/USD\n _circuitChainlink[0] = AggregatorV3Interface(0x3D7aE7E594f2f2091Ad8798313450130d0Aba3a0);\n // Oracle XAU/USD\n _circuitChainlink[1] = AggregatorV3Interface(0x214eD9Da11D2fbe465a6fc601a91E62EbEc1a0D6);\n return _circuitChainlink;\n }\n}\n" + }, + "contracts/oracle/implementations/mainnet/XAU/OracleUSDCXAUChainlink.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\nimport \"@chainlink/contracts/src/v0.8/interfaces/AggregatorV3Interface.sol\";\n\nimport \"../../../BaseOracleChainlinkMultiTwoFeeds.sol\";\n\n/// @title OracleUSDCXAUChainlink\n/// @author Angle Labs, Inc.\n/// @notice Gives the price of USDC in XAU in base 18\ncontract OracleUSDCXAUChainlink is BaseOracleChainlinkMultiTwoFeeds {\n string public constant DESCRIPTION = \"USDC/GOLD Oracle\";\n\n constructor(uint32 _stalePeriod, address _treasury) BaseOracleChainlinkMultiTwoFeeds(_stalePeriod, _treasury) {}\n\n /// @inheritdoc IOracle\n function circuitChainlink() public pure override returns (AggregatorV3Interface[] memory) {\n AggregatorV3Interface[] memory _circuitChainlink = new AggregatorV3Interface[](2);\n // Oracle USDC/USD\n _circuitChainlink[0] = AggregatorV3Interface(0x8fFfFfd4AfB6115b954Bd326cbe7B4BA576818f6);\n // Oracle XAU/USD\n _circuitChainlink[1] = AggregatorV3Interface(0x214eD9Da11D2fbe465a6fc601a91E62EbEc1a0D6);\n return _circuitChainlink;\n }\n}\n" + }, + "contracts/oracle/implementations/mainnet/XAU/OracleWSTETHXAUChainlink.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\nimport \"@chainlink/contracts/src/v0.8/interfaces/AggregatorV3Interface.sol\";\n\nimport \"../../../BaseOracleChainlinkMultiTwoFeeds.sol\";\nimport \"../../../../interfaces/external/lido/IStETH.sol\";\n\n/// @title OracleWSTETHXAUChainlink\n/// @author Angle Labs, Inc.\n/// @notice Gives the price of wSTETH in XAU in base 18\ncontract OracleWSTETHXAUChainlink is BaseOracleChainlinkMultiTwoFeeds {\n string public constant DESCRIPTION = \"wSTETH/XAU Oracle\";\n IStETH public constant STETH = IStETH(0xae7ab96520DE3A18E5e111B5EaAb095312D7fE84);\n\n constructor(uint32 _stalePeriod, address _treasury) BaseOracleChainlinkMultiTwoFeeds(_stalePeriod, _treasury) {}\n\n /// @inheritdoc IOracle\n function circuitChainlink() public pure override returns (AggregatorV3Interface[] memory) {\n AggregatorV3Interface[] memory _circuitChainlink = new AggregatorV3Interface[](2);\n // Oracle stETH/USD\n _circuitChainlink[0] = AggregatorV3Interface(0xCfE54B5cD566aB89272946F602D76Ea879CAb4a8);\n // Oracle XAU/USD\n _circuitChainlink[1] = AggregatorV3Interface(0x214eD9Da11D2fbe465a6fc601a91E62EbEc1a0D6);\n return _circuitChainlink;\n }\n\n /// @inheritdoc BaseOracleChainlinkMultiTwoFeeds\n function _getQuoteAmount() internal view override returns (uint256) {\n return STETH.getPooledEthByShares(1 ether);\n }\n}\n" + }, + "contracts/oracle/implementations/optimism/EUR/OracleETHEURChainlinkOptimism.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\nimport \"@chainlink/contracts/src/v0.8/interfaces/AggregatorV3Interface.sol\";\n\nimport \"../../../BaseOracleChainlinkMultiTwoFeeds.sol\";\n\n/// @title OracleETHEURChainlinkOptimism\n/// @author Angle Labs, Inc.\n/// @notice Gives the price of ETH in Euro in base 18\n/// @dev This contract is built to be deployed on Optimism\ncontract OracleETHEURChainlinkOptimism is BaseOracleChainlinkMultiTwoFeeds {\n string public constant DESCRIPTION = \"ETH/EUR Oracle\";\n\n constructor(uint32 _stalePeriod, address _treasury) BaseOracleChainlinkMultiTwoFeeds(_stalePeriod, _treasury) {}\n\n /// @inheritdoc IOracle\n function circuitChainlink() public pure override returns (AggregatorV3Interface[] memory) {\n AggregatorV3Interface[] memory _circuitChainlink = new AggregatorV3Interface[](2);\n // Oracle ETH/USD\n _circuitChainlink[0] = AggregatorV3Interface(0x13e3Ee699D1909E989722E753853AE30b17e08c5);\n // Oracle EUR/USD\n _circuitChainlink[1] = AggregatorV3Interface(0x3626369857A10CcC6cc3A6e4f5C2f5984a519F20);\n return _circuitChainlink;\n }\n}\n" + }, + "contracts/oracle/implementations/optimism/EUR/OracleOPEURChainlinkOptimism.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\nimport \"@chainlink/contracts/src/v0.8/interfaces/AggregatorV3Interface.sol\";\n\nimport \"../../../BaseOracleChainlinkMultiTwoFeeds.sol\";\n\n/// @title OracleOPEURChainlinkOptimism\n/// @author Angle Labs, Inc.\n/// @notice Gives the price of OP in Euro in base 18\n/// @dev This contract is built to be deployed on Optimism\ncontract OracleOPEURChainlinkOptimism is BaseOracleChainlinkMultiTwoFeeds {\n string public constant DESCRIPTION = \"OP/EUR Oracle\";\n\n constructor(uint32 _stalePeriod, address _treasury) BaseOracleChainlinkMultiTwoFeeds(_stalePeriod, _treasury) {}\n\n /// @inheritdoc IOracle\n function circuitChainlink() public pure override returns (AggregatorV3Interface[] memory) {\n AggregatorV3Interface[] memory _circuitChainlink = new AggregatorV3Interface[](2);\n // Oracle OP/USD\n _circuitChainlink[0] = AggregatorV3Interface(0x0D276FC14719f9292D5C1eA2198673d1f4269246);\n // Oracle EUR/USD\n _circuitChainlink[1] = AggregatorV3Interface(0x3626369857A10CcC6cc3A6e4f5C2f5984a519F20);\n return _circuitChainlink;\n }\n}\n" + }, + "contracts/oracle/implementations/optimism/EUR/OracleUSDCEURChainlinkOptimism.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\nimport \"@chainlink/contracts/src/v0.8/interfaces/AggregatorV3Interface.sol\";\n\nimport \"../../../BaseOracleChainlinkMultiTwoFeeds.sol\";\n\n/// @title OracleUSDCEURChainlinkOptimism\n/// @author Angle Labs, Inc.\n/// @notice Gives the price of USDC in Euro in base 18\n/// @dev This contract is built to be deployed on Optimism\ncontract OracleUSDCEURChainlinkOptimism is BaseOracleChainlinkMultiTwoFeeds {\n string public constant DESCRIPTION = \"USDC/EUR Oracle\";\n\n constructor(uint32 _stalePeriod, address _treasury) BaseOracleChainlinkMultiTwoFeeds(_stalePeriod, _treasury) {}\n\n /// @inheritdoc IOracle\n function circuitChainlink() public pure override returns (AggregatorV3Interface[] memory) {\n AggregatorV3Interface[] memory _circuitChainlink = new AggregatorV3Interface[](2);\n // Oracle USDC/USD\n _circuitChainlink[0] = AggregatorV3Interface(0x16a9FA2FDa030272Ce99B29CF780dFA30361E0f3);\n // Oracle EUR/USD\n _circuitChainlink[1] = AggregatorV3Interface(0x3626369857A10CcC6cc3A6e4f5C2f5984a519F20);\n return _circuitChainlink;\n }\n}\n" + }, + "contracts/oracle/implementations/polygon/EUR/OracleBTCEURChainlinkPolygon.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\nimport \"@chainlink/contracts/src/v0.8/interfaces/AggregatorV3Interface.sol\";\n\nimport \"../../../BaseOracleChainlinkMultiTwoFeeds.sol\";\n\n/// @title OracleBTCEURChainlinkPolygon\n/// @author Angle Labs, Inc.\n/// @notice Gives the price of BTC in Euro in base 18\n/// @dev This contract is built to be deployed on Polygon\ncontract OracleBTCEURChainlinkPolygon is BaseOracleChainlinkMultiTwoFeeds {\n string public constant DESCRIPTION = \"BTC/EUR Oracle\";\n\n constructor(uint32 _stalePeriod, address _treasury) BaseOracleChainlinkMultiTwoFeeds(_stalePeriod, _treasury) {}\n\n /// @inheritdoc IOracle\n function circuitChainlink() public pure override returns (AggregatorV3Interface[] memory) {\n AggregatorV3Interface[] memory _circuitChainlink = new AggregatorV3Interface[](2);\n // Oracle BTC/USD\n _circuitChainlink[0] = AggregatorV3Interface(0xc907E116054Ad103354f2D350FD2514433D57F6f);\n // Oracle EUR/USD\n _circuitChainlink[1] = AggregatorV3Interface(0x73366Fe0AA0Ded304479862808e02506FE556a98);\n return _circuitChainlink;\n }\n}\n" + }, + "contracts/oracle/implementations/polygon/EUR/OracleETHEURChainlinkPolygon.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\nimport \"@chainlink/contracts/src/v0.8/interfaces/AggregatorV3Interface.sol\";\n\nimport \"../../../BaseOracleChainlinkMultiTwoFeeds.sol\";\n\n/// @title OracleETHEURChainlinkPolygon\n/// @author Angle Labs, Inc.\n/// @notice Gives the price of ETH in Euro in base 18\n/// @dev This contract is built to be deployed on Polygon\ncontract OracleETHEURChainlinkPolygon is BaseOracleChainlinkMultiTwoFeeds {\n string public constant DESCRIPTION = \"ETH/EUR Oracle\";\n\n constructor(uint32 _stalePeriod, address _treasury) BaseOracleChainlinkMultiTwoFeeds(_stalePeriod, _treasury) {}\n\n /// @inheritdoc IOracle\n function circuitChainlink() public pure override returns (AggregatorV3Interface[] memory) {\n AggregatorV3Interface[] memory _circuitChainlink = new AggregatorV3Interface[](2);\n // Oracle ETH/USD\n _circuitChainlink[0] = AggregatorV3Interface(0xF9680D99D6C9589e2a93a78A04A279e509205945);\n // Oracle EUR/USD\n _circuitChainlink[1] = AggregatorV3Interface(0x73366Fe0AA0Ded304479862808e02506FE556a98);\n return _circuitChainlink;\n }\n}\n" + }, + "contracts/oracle/implementations/polygon/EUR/OracleMAIEURChainlinkPolygon.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\nimport \"@chainlink/contracts/src/v0.8/interfaces/AggregatorV3Interface.sol\";\n\nimport \"../../../BaseOracleChainlinkMultiTwoFeeds.sol\";\n\n/// @title OracleMAIEURChainlinkPolygon\n/// @author Angle Labs, Inc.\n/// @notice Gives the price of MAI in Euro in base 18\n/// @dev This contract is built to be deployed on Polygon\ncontract OracleMAIEURChainlinkPolygon is BaseOracleChainlinkMultiTwoFeeds {\n string public constant DESCRIPTION = \"MAI/EUR Oracle\";\n\n constructor(uint32 _stalePeriod, address _treasury) BaseOracleChainlinkMultiTwoFeeds(_stalePeriod, _treasury) {}\n\n /// @inheritdoc IOracle\n function circuitChainlink() public pure override returns (AggregatorV3Interface[] memory) {\n AggregatorV3Interface[] memory _circuitChainlink = new AggregatorV3Interface[](2);\n // Oracle MAI/USD\n _circuitChainlink[0] = AggregatorV3Interface(0xd8d483d813547CfB624b8Dc33a00F2fcbCd2D428);\n // Oracle EUR/USD\n _circuitChainlink[1] = AggregatorV3Interface(0x73366Fe0AA0Ded304479862808e02506FE556a98);\n return _circuitChainlink;\n }\n}\n" + }, + "contracts/oracle/implementations/polygon/EUR/OracleMATICEURChainlinkPolygon.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\nimport \"@chainlink/contracts/src/v0.8/interfaces/AggregatorV3Interface.sol\";\n\nimport \"../../../BaseOracleChainlinkMultiTwoFeeds.sol\";\n\n/// @title OracleMATICEURChainlinkPolygon\n/// @author Angle Labs, Inc.\n/// @notice Gives the price of MATIC in Euro in base 18\n/// @dev This contract is built to be deployed on Polygon\ncontract OracleMATICEURChainlinkPolygon is BaseOracleChainlinkMultiTwoFeeds {\n string public constant DESCRIPTION = \"MATIC/EUR Oracle\";\n\n constructor(uint32 _stalePeriod, address _treasury) BaseOracleChainlinkMultiTwoFeeds(_stalePeriod, _treasury) {}\n\n /// @inheritdoc IOracle\n function circuitChainlink() public pure override returns (AggregatorV3Interface[] memory) {\n AggregatorV3Interface[] memory _circuitChainlink = new AggregatorV3Interface[](2);\n // Oracle MATIC/USD\n _circuitChainlink[0] = AggregatorV3Interface(0xAB594600376Ec9fD91F8e885dADF0CE036862dE0);\n // Oracle EUR/USD\n _circuitChainlink[1] = AggregatorV3Interface(0x73366Fe0AA0Ded304479862808e02506FE556a98);\n return _circuitChainlink;\n }\n}\n" + }, + "contracts/oracle/implementations/polygon/EUR/OracleUSDCEURChainlinkPolygon.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\nimport \"../../../BaseOracleChainlinkMultiTwoFeeds.sol\";\n\n/// @title OracleUSDCEURChainlinkPolygon\n/// @author Angle Labs, Inc.\n/// @notice Gives the price of USDC in Euro in base 18\n/// @dev This contract is built to be deployed on Polygon\ncontract OracleUSDCEURChainlinkPolygon is BaseOracleChainlinkMultiTwoFeeds {\n string public constant DESCRIPTION = \"USDC/EUR Oracle\";\n\n constructor(uint32 _stalePeriod, address _treasury) BaseOracleChainlinkMultiTwoFeeds(_stalePeriod, _treasury) {}\n\n /// @inheritdoc IOracle\n function circuitChainlink() public pure override returns (AggregatorV3Interface[] memory) {\n AggregatorV3Interface[] memory _circuitChainlink = new AggregatorV3Interface[](2);\n // Oracle USDC/USD\n _circuitChainlink[0] = AggregatorV3Interface(0xfE4A8cc5b5B2366C1B58Bea3858e81843581b2F7);\n // Oracle EUR/USD\n _circuitChainlink[1] = AggregatorV3Interface(0x73366Fe0AA0Ded304479862808e02506FE556a98);\n return _circuitChainlink;\n }\n}\n" + }, + "contracts/oracle/implementations/polygon/XAU/OracleETHXAUChainlinkPolygon.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\nimport \"@chainlink/contracts/src/v0.8/interfaces/AggregatorV3Interface.sol\";\n\nimport \"../../../BaseOracleChainlinkMultiTwoFeeds.sol\";\n\n/// @title OracleETHXAUChainlinkPolygon\n/// @author Angle Labs, Inc.\n/// @notice Gives the price of ETH in XAU in base 18\n/// @dev This contract is built to be deployed on Polygon\ncontract OracleETHXAUChainlinkPolygon is BaseOracleChainlinkMultiTwoFeeds {\n string public constant DESCRIPTION = \"ETH/GOLD Oracle\";\n\n constructor(uint32 _stalePeriod, address _treasury) BaseOracleChainlinkMultiTwoFeeds(_stalePeriod, _treasury) {}\n\n /// @inheritdoc IOracle\n function circuitChainlink() public pure override returns (AggregatorV3Interface[] memory) {\n AggregatorV3Interface[] memory _circuitChainlink = new AggregatorV3Interface[](2);\n // Oracle ETH/USD\n _circuitChainlink[0] = AggregatorV3Interface(0xF9680D99D6C9589e2a93a78A04A279e509205945);\n // Oracle XAU/USD\n _circuitChainlink[1] = AggregatorV3Interface(0x0C466540B2ee1a31b441671eac0ca886e051E410);\n return _circuitChainlink;\n }\n}\n" + }, + "contracts/oracle/KeeperRegistry.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\nimport \"@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol\";\nimport \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\nimport \"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\";\n\nimport \"../interfaces/ICoreBorrow.sol\";\nimport \"../interfaces/IKeeperRegistry.sol\";\n\n/// @title KeeperRegistry\n/// @notice Maintains a mapping of keepers authorized to use the core module just after oracle updates\n/// @author Angle Labs, Inc.\ncontract KeeperRegistry is Initializable, IKeeperRegistry {\n using SafeERC20 for IERC20;\n\n /// @notice Contract handling access control\n ICoreBorrow public coreBorrow;\n\n /// @notice Trusted EOAs - needs to be tx.origin\n mapping(address => uint256) public trusted;\n\n uint256[48] private __gap;\n\n // =================================== EVENTS ==================================\n\n event TrustedToggled(address indexed wallet, bool trust);\n\n // =================================== ERRORS ==================================\n\n error NotGovernorOrGuardian();\n error NotTrusted();\n error ZeroAddress();\n\n // ================================= MODIFIERS =================================\n\n /// @notice Checks whether the `msg.sender` has the governor role or the guardian role\n modifier onlyGovernorOrGuardian() {\n if (!coreBorrow.isGovernorOrGuardian(msg.sender)) revert NotGovernorOrGuardian();\n _;\n }\n\n // ================================ CONSTRUCTOR ================================\n\n constructor() initializer {}\n\n function initialize(ICoreBorrow _coreBorrow) public initializer {\n if (address(_coreBorrow) == address(0)) revert ZeroAddress();\n coreBorrow = _coreBorrow;\n }\n\n // =============================== MAIN FUNCTIONS ==============================\n\n /// @notice Adds or removes a trusted keeper bot\n function toggleTrusted(address eoa) external onlyGovernorOrGuardian {\n uint256 trustedStatus = 1 - trusted[eoa];\n trusted[eoa] = trustedStatus;\n emit TrustedToggled(eoa, trustedStatus == 1);\n }\n\n /// @inheritdoc IKeeperRegistry\n function isTrusted(address caller) external view returns (bool) {\n return trusted[caller] == 1;\n }\n}\n" + }, + "contracts/oracle/OracleChainlinkMulti.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\nimport \"@chainlink/contracts/src/v0.8/interfaces/AggregatorV3Interface.sol\";\n\nimport \"./BaseOracleChainlinkMulti.sol\";\n\n/// @title OracleChainlinkMulti\n/// @author Angle Labs, Inc.\n/// @notice Oracle contract, one contract is deployed per collateral/stablecoin pair\n/// @dev This contract concerns an oracle that uses Chainlink with multiple pools to read from\n/// @dev Typically we expect to use this contract to read like the ETH/USD and then USD/EUR feed\ncontract OracleChainlinkMulti is BaseOracleChainlinkMulti {\n // ========================= Parameters and References =========================\n\n /// @notice Chainlink pools, the order of the pools has to be the order in which they are read for the computation\n /// of the price\n AggregatorV3Interface[] internal _circuitChainlink;\n /// @notice Whether each rate for the pairs in `circuitChainlink` should be multiplied or divided\n uint8[] public circuitChainIsMultiplied;\n /// @notice Decimals for each Chainlink pairs\n uint8[] public chainlinkDecimals;\n /// @notice Unit of the stablecoin\n uint256 public immutable outBase;\n /// @notice Description of the assets concerned by the oracle and the price outputted\n string public description;\n\n // ===================================== Error =================================\n\n error IncompatibleLengths();\n\n /// @notice Constructor for an oracle using Chainlink with multiple pools to read from\n /// @param circuitChainlink_ Chainlink pool addresses (in order)\n /// @param _circuitChainIsMultiplied Whether we should multiply or divide by this rate\n /// @param _outBase Unit of the stablecoin (or the out asset) associated to the oracle\n /// @param _stalePeriod Minimum feed update frequency for the oracle to not revert\n /// @param _treasury Treasury associated to the VaultManager which reads from this feed\n /// @param _description Description of the assets concerned by the oracle\n /// @dev For instance, if this oracle is supposed to give the price of ETH in EUR, and if the agEUR\n /// stablecoin associated to EUR has 18 decimals, then `outBase` should be 10**18\n constructor(\n address[] memory circuitChainlink_,\n uint8[] memory _circuitChainIsMultiplied,\n uint256 _outBase,\n uint32 _stalePeriod,\n address _treasury,\n string memory _description\n ) BaseOracleChainlinkMulti(_stalePeriod, _treasury) {\n outBase = _outBase;\n description = _description;\n uint256 circuitLength = circuitChainlink_.length;\n if (circuitLength == 0 || circuitLength != _circuitChainIsMultiplied.length) revert IncompatibleLengths();\n for (uint256 i; i < circuitLength; ++i) {\n AggregatorV3Interface _pool = AggregatorV3Interface(circuitChainlink_[i]);\n _circuitChainlink.push(_pool);\n chainlinkDecimals.push(_pool.decimals());\n }\n circuitChainIsMultiplied = _circuitChainIsMultiplied;\n }\n\n // ============================= Reading Oracles ===============================\n\n /// @inheritdoc IOracle\n function circuitChainlink() public view override returns (AggregatorV3Interface[] memory) {\n return _circuitChainlink;\n }\n\n /// @inheritdoc IOracle\n function read() external view override returns (uint256 quoteAmount) {\n quoteAmount = outBase;\n uint256 circuitLength = _circuitChainlink.length;\n for (uint256 i; i < circuitLength; ++i) {\n quoteAmount = _readChainlinkFeed(\n quoteAmount,\n _circuitChainlink[i],\n circuitChainIsMultiplied[i],\n chainlinkDecimals[i]\n );\n }\n }\n}\n" + }, + "contracts/settlement/Settlement.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\nimport \"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\";\nimport \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\nimport \"@openzeppelin/contracts/token/ERC20/extensions/IERC20Metadata.sol\";\n\nimport \"../interfaces/IAgToken.sol\";\nimport \"../interfaces/ISwapper.sol\";\nimport \"../interfaces/IVaultManager.sol\";\n\n/// @title Settlement\n/// @author Angle Labs, Inc.\n/// @notice Settlement Contract for a VaultManager\n/// @dev This settlement contract should be activated by a careful governance which needs to have performed\n/// some key operations before activating this contract\n/// @dev In case of global settlement, there should be one settlement contract per `VaultManager`\ncontract Settlement {\n using SafeERC20 for IERC20;\n\n /// @notice Base used for parameter computation\n uint256 public constant BASE_PARAMS = 10 ** 9;\n /// @notice Base used for interest computation\n uint256 public constant BASE_INTEREST = 10 ** 27;\n /// @notice Base used for exchange rate computation. It is assumed\n /// that stablecoins have this base\n uint256 public constant BASE_STABLECOIN = 10 ** 18;\n /// @notice Duration of the claim period for over-collateralized vaults\n uint256 public constant OVER_COLLATERALIZED_CLAIM_DURATION = 3 * 24 * 3600;\n\n // =============== Immutable references set in the constructor =================\n\n /// @notice `VaultManager` of this settlement contract\n IVaultManager public immutable vaultManager;\n /// @notice Reference to the stablecoin supported by the `VaultManager` contract\n IAgToken public immutable stablecoin;\n /// @notice Reference to the collateral supported by the `VaultManager`\n IERC20 public immutable collateral;\n /// @notice Base of the collateral\n uint256 internal immutable _collatBase;\n\n // ================ Variables frozen at settlement activation ==================\n\n /// @notice Value of the oracle for the collateral/stablecoin pair\n uint256 public oracleValue;\n /// @notice Value of the interest accumulator at settlement activation\n uint256 public interestAccumulator;\n /// @notice Timestamp at which settlement was activated\n uint256 public activationTimestamp;\n /// @notice Collateral factor of the `VaultManager`\n uint64 public collateralFactor;\n\n // =================== Variables updated during the process ====================\n\n /// @notice How much collateral you can get from stablecoins\n uint256 public collateralStablecoinExchangeRate;\n /// @notice Amount of collateral that will be left over at the end of the process\n uint256 public leftOverCollateral;\n /// @notice Whether the `collateralStablecoinExchangeRate` has been computed\n bool public exchangeRateComputed;\n /// @notice Maps a vault to 1 if it was claimed by its owner\n mapping(uint256 => uint256) public vaultCheck;\n\n // ================================ Events =====================================\n\n event GlobalClaimPeriodActivated(uint256 _collateralStablecoinExchangeRate);\n event Recovered(address indexed tokenAddress, address indexed to, uint256 amount);\n event SettlementActivated(uint256 startTimestamp);\n event VaultClaimed(uint256 vaultID, uint256 stablecoinAmount, uint256 collateralAmount);\n\n // ================================ Errors =====================================\n\n error GlobalClaimPeriodNotStarted();\n error InsolventVault();\n error NotGovernor();\n error NotOwner();\n error RestrictedClaimPeriodNotEnded();\n error SettlementNotInitialized();\n error VaultAlreadyClaimed();\n\n /// @notice Constructor of the contract\n /// @param _vaultManager Address of the `VaultManager` associated to this `Settlement` contract\n /// @dev Out of safety, this constructor reads values from the `VaultManager` contract directly\n constructor(IVaultManager _vaultManager) {\n vaultManager = _vaultManager;\n stablecoin = _vaultManager.stablecoin();\n collateral = _vaultManager.collateral();\n _collatBase = 10 ** (IERC20Metadata(address(collateral)).decimals());\n }\n\n /// @notice Checks whether the `msg.sender` has the governor role or not\n modifier onlyGovernor() {\n if (!(vaultManager.treasury().isGovernor(msg.sender))) revert NotGovernor();\n _;\n }\n\n /// @notice Activates the settlement contract\n /// @dev When calling this function governance should make sure to have:\n /// 1. Accrued the interest rate on the contract\n /// 2. Paused the contract\n /// 3. Recovered all the collateral available in the `VaultManager` contract either\n /// by doing a contract upgrade or by calling a `recoverERC20` method if supported\n function activateSettlement() external onlyGovernor {\n oracleValue = (vaultManager.oracle()).read();\n interestAccumulator = vaultManager.interestAccumulator();\n activationTimestamp = block.timestamp;\n collateralFactor = vaultManager.collateralFactor();\n emit SettlementActivated(block.timestamp);\n }\n\n /// @notice Allows the owner of an over-collateralized vault to claim its collateral upon bringing back all owed stablecoins\n /// @param vaultID ID of the vault to claim\n /// @param to Address to which collateral should be sent\n /// @param who Address which should be notified if needed of the transfer of stablecoins and collateral\n /// @param data Data to pass to the `who` contract for it to successfully give the correct amount of stablecoins\n /// to the `msg.sender` address\n /// @return Amount of collateral sent to the `to` address\n /// @return Amount of stablecoins sent to the contract\n /// @dev Claiming can only happen short after settlement activation\n /// @dev A vault cannot be claimed twice and only the owner of the vault can claim it (regardless of the approval logic)\n /// @dev Only over-collateralized vaults can be claimed from this medium\n function claimOverCollateralizedVault(\n uint256 vaultID,\n address to,\n address who,\n bytes memory data\n ) external returns (uint256, uint256) {\n if (activationTimestamp == 0 || block.timestamp > activationTimestamp + OVER_COLLATERALIZED_CLAIM_DURATION)\n revert SettlementNotInitialized();\n if (vaultCheck[vaultID] == 1) revert VaultAlreadyClaimed();\n if (vaultManager.ownerOf(vaultID) != msg.sender) revert NotOwner();\n (uint256 collateralAmount, uint256 normalizedDebt) = vaultManager.vaultData(vaultID);\n uint256 vaultDebt = (normalizedDebt * interestAccumulator) / BASE_INTEREST;\n if (collateralAmount * oracleValue * collateralFactor < vaultDebt * BASE_PARAMS * _collatBase)\n revert InsolventVault();\n vaultCheck[vaultID] = 1;\n emit VaultClaimed(vaultID, vaultDebt, collateralAmount);\n return _handleRepay(collateralAmount, vaultDebt, to, who, data);\n }\n\n /// @notice Activates the global claim period by setting the `collateralStablecoinExchangeRate` which is going to\n /// dictate how much of collateral will be recoverable for each stablecoin\n /// @dev This function can only be called by the governor in order to allow it in case multiple settlements happen across\n /// different `VaultManager` to rebalance the amount of stablecoins on each to make sure that across all settlement contracts\n /// a similar value of collateral can be obtained against a similar value of stablecoins\n function activateGlobalClaimPeriod() external onlyGovernor {\n if (activationTimestamp == 0 || block.timestamp <= activationTimestamp + OVER_COLLATERALIZED_CLAIM_DURATION)\n revert RestrictedClaimPeriodNotEnded();\n uint256 collateralBalance = collateral.balanceOf(address(this));\n uint256 leftOverDebt = (vaultManager.totalNormalizedDebt() * interestAccumulator) / BASE_INTEREST;\n uint256 stablecoinBalance = stablecoin.balanceOf(address(this));\n // How much 1 of stablecoin will give you in collateral\n uint256 _collateralStablecoinExchangeRate;\n\n if (stablecoinBalance < leftOverDebt) {\n // The left over debt is the total debt minus the stablecoins which have already been accumulated\n // in the first phase\n leftOverDebt -= stablecoinBalance;\n // If you control all the debt, then you are entitled to get all the collateral left in the protocol\n _collateralStablecoinExchangeRate = (collateralBalance * BASE_STABLECOIN) / leftOverDebt;\n // But at the same time, you cannot get more collateral than the value of the stablecoins you brought\n uint256 maxExchangeRate = (BASE_STABLECOIN * _collatBase) / oracleValue;\n if (_collateralStablecoinExchangeRate >= maxExchangeRate) {\n // In this situation, we're sure that `leftOverCollateral` will be positive: governance should be wary\n // to call `recoverERC20` short after though as there's nothing that is going to prevent people to redeem\n // more stablecoins than the `leftOverDebt`\n leftOverCollateral = collateralBalance - (leftOverDebt * _collatBase) / oracleValue;\n _collateralStablecoinExchangeRate = maxExchangeRate;\n }\n }\n exchangeRateComputed = true;\n // In the else case where there is no debt left, you cannot get anything from your stablecoins\n // and so the `collateralStablecoinExchangeRate` is null\n collateralStablecoinExchangeRate = _collateralStablecoinExchangeRate;\n emit GlobalClaimPeriodActivated(_collateralStablecoinExchangeRate);\n }\n\n /// @notice Allows to claim collateral from stablecoins\n /// @param to Address to which collateral should be sent\n /// @param who Address which should be notified if needed of the transfer of stablecoins and collateral\n /// @param data Data to pass to the `who` contract for it to successfully give the correct amount of stablecoins\n /// to the `msg.sender` address\n /// @return Amount of collateral sent to the `to` address\n /// @return Amount of stablecoins sent to the contract\n /// @dev This function reverts if the `collateralStablecoinExchangeRate` is null and hence if the global claim period has\n /// not been activated\n function claimCollateralFromStablecoins(\n uint256 stablecoinAmount,\n address to,\n address who,\n bytes memory data\n ) external returns (uint256, uint256) {\n if (!exchangeRateComputed) revert GlobalClaimPeriodNotStarted();\n return\n _handleRepay(\n (stablecoinAmount * collateralStablecoinExchangeRate) / BASE_STABLECOIN,\n stablecoinAmount,\n to,\n who,\n data\n );\n }\n\n /// @notice Handles the simultaneous repayment of stablecoins with a transfer of collateral\n /// @param collateralAmountToGive Amount of collateral the contract should give\n /// @param stableAmountToRepay Amount of stablecoins the contract should burn from the call\n /// @param to Address to which stablecoins should be sent\n /// @param who Address which should be notified if needed of the transfer\n /// @param data Data to pass to the `who` contract for it to successfully give the correct amount of stablecoins\n /// to the `msg.sender` address\n /// @dev This function allows for capital-efficient claims of collateral from stablecoins\n function _handleRepay(\n uint256 collateralAmountToGive,\n uint256 stableAmountToRepay,\n address to,\n address who,\n bytes memory data\n ) internal returns (uint256, uint256) {\n collateral.safeTransfer(to, collateralAmountToGive);\n if (data.length != 0) {\n ISwapper(who).swap(\n collateral,\n IERC20(address(stablecoin)),\n msg.sender,\n stableAmountToRepay,\n collateralAmountToGive,\n data\n );\n }\n stablecoin.transferFrom(msg.sender, address(this), stableAmountToRepay);\n return (collateralAmountToGive, stableAmountToRepay);\n }\n\n /// @notice Recovers leftover tokens from the contract or tokens that were mistakenly sent to the contract\n /// @param tokenAddress Address of the token to recover\n /// @param to Address to send the remaining tokens to\n /// @param amountToRecover Amount to recover from the contract\n /// @dev Governors cannot recover more collateral than what would be leftover from the contract\n /// @dev This function can be used to rebalance stablecoin balances across different settlement contracts\n /// to make sure every stablecoin can be redeemed for the same value of collateral\n /// @dev It can also be used to recover tokens that are mistakenly sent to this contract\n function recoverERC20(address tokenAddress, address to, uint256 amountToRecover) external onlyGovernor {\n if (tokenAddress == address(collateral)) {\n if (!exchangeRateComputed) revert GlobalClaimPeriodNotStarted();\n leftOverCollateral -= amountToRecover;\n collateral.safeTransfer(to, amountToRecover);\n } else {\n IERC20(tokenAddress).safeTransfer(to, amountToRecover);\n }\n emit Recovered(tokenAddress, to, amountToRecover);\n }\n}\n" + }, + "contracts/swapper/Swapper.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\n/*\n * █ \n ***** ▓▓▓ \n * ▓▓▓▓▓▓▓ \n * ///. ▓▓▓▓▓▓▓▓▓▓▓▓▓ \n ***** //////// ▓▓▓▓▓▓▓ \n * ///////////// ▓▓▓ \n ▓▓ ////////////////// █ ▓▓ \n ▓▓ ▓▓ /////////////////////// ▓▓ ▓▓ \n ▓▓ ▓▓ //////////////////////////// ▓▓ ▓▓ \n ▓▓ ▓▓ /////////▓▓▓///////▓▓▓///////// ▓▓ ▓▓ \n ▓▓ ,////////////////////////////////////// ▓▓ ▓▓ \n ▓▓ ////////////////////////////////////////// ▓▓ \n ▓▓ //////////////////////▓▓▓▓///////////////////// \n ,//////////////////////////////////////////////////// \n .////////////////////////////////////////////////////////// \n .//////////////////////////██.,//////////////////////////█ \n .//////////////////////████..,./////////////////////██ \n ...////////////////███████.....,.////////////////███ \n ,.,////////////████████ ........,///////////████ \n .,.,//////█████████ ,.......///////████ \n ,..//████████ ........./████ \n ..,██████ .....,███ \n .██ ,.,█ \n \n \n \n ▓▓ ▓▓▓▓▓▓▓▓▓▓ ▓▓▓▓▓▓▓▓▓▓ ▓▓ ▓▓▓▓▓▓▓▓▓▓ \n ▓▓▓▓▓▓ ▓▓▓ ▓▓▓ ▓▓▓ ▓▓ ▓▓ ▓▓▓▓ \n ▓▓▓ ▓▓▓ ▓▓▓ ▓▓▓ ▓▓▓ ▓▓▓ ▓▓ ▓▓▓▓▓ \n ▓▓▓ ▓▓ ▓▓▓ ▓▓▓ ▓▓▓▓▓▓▓▓▓▓ ▓▓▓▓▓▓▓▓▓▓ ▓▓▓▓▓▓▓▓▓▓ \n*/\n\npragma solidity ^0.8.12;\n\nimport \"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\";\nimport \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\n\nimport \"../interfaces/IAngleRouterSidechain.sol\";\nimport \"../interfaces/ICoreBorrow.sol\";\nimport \"../interfaces/ISwapper.sol\";\nimport \"../interfaces/external/lido/IWStETH.sol\";\nimport \"../interfaces/external/uniswap/IUniswapRouter.sol\";\n\n// ==================================== ENUM ===================================\n\n/// @notice All possible swaps\nenum SwapType {\n UniswapV3,\n oneInch,\n AngleRouter,\n Leverage,\n None\n}\n\n/// @title Swapper\n/// @author Angle Labs, Inc.\n/// @notice Swapper contract facilitating interactions with Angle VaultManager contracts, notably\n/// liquidation and leverage transactions\ncontract Swapper is ISwapper {\n using SafeERC20 for IERC20;\n\n // ===================== CONSTANTS AND IMMUTABLE VARIABLES =====================\n\n /// @notice Reference to the `CoreBorrow` contract of the module which handles all AccessControl logic\n ICoreBorrow public immutable core;\n /// @notice Uniswap Router contract\n IUniswapV3Router public immutable uniV3Router;\n /// @notice 1inch Router\n address public immutable oneInch;\n /// @notice AngleRouter\n IAngleRouterSidechain public immutable angleRouter;\n\n // =================================== ERRORS ==================================\n\n error EmptyReturnMessage();\n error IncompatibleLengths();\n error NotGovernorOrGuardian();\n error TooSmallAmountOut();\n error ZeroAddress();\n\n /// @notice Constructor of the contract\n /// @param _core Core address\n /// @param _uniV3Router UniswapV3 Router address\n /// @param _oneInch 1inch Router address\n /// @param _angleRouter AngleRouter contract address\n constructor(\n ICoreBorrow _core,\n IUniswapV3Router _uniV3Router,\n address _oneInch,\n IAngleRouterSidechain _angleRouter\n ) {\n if (address(_core) == address(0) || _oneInch == address(0) || address(_angleRouter) == address(0))\n revert ZeroAddress();\n core = _core;\n uniV3Router = _uniV3Router;\n oneInch = _oneInch;\n angleRouter = _angleRouter;\n }\n\n // ========================= EXTERNAL ACCESS FUNCTIONS =========================\n\n /// @inheritdoc ISwapper\n /// @dev This function swaps the `inToken` to the `outToken` by doing a UniV3 swap, a 1inch swap or by interacting\n /// with the `AngleRouter` contract\n /// @dev One slippage check is performed at the end of the call\n /// @dev In this implementation, the function tries to make sure that the `outTokenRecipient` address has at the end\n /// of the call `outTokenOwed`, leftover tokens are sent to a `to` address which by default is the `outTokenRecipient`\n function swap(\n IERC20 inToken,\n IERC20 outToken,\n address outTokenRecipient,\n uint256 outTokenOwed,\n uint256 inTokenObtained,\n bytes memory data\n ) external {\n // Address to receive the surplus amount of token at the end of the call\n address to;\n // For slippage protection, it is checked at the end of the call\n uint256 minAmountOut;\n // Type of the swap to execute: if `swapType == 4`, then it is optional to swap\n uint256 swapType;\n // We're reusing the `data` variable (it can be `path` on UniswapV3, a payload for 1inch or like encoded actions\n // for a router call)\n (to, minAmountOut, swapType, data) = abi.decode(data, (address, uint256, uint256, bytes));\n\n to = (to == address(0)) ? outTokenRecipient : to;\n\n _swap(inToken, inTokenObtained, SwapType(swapType), data);\n\n // A final slippage check is performed after the swaps\n uint256 outTokenBalance = outToken.balanceOf(address(this));\n if (outTokenBalance < minAmountOut) revert TooSmallAmountOut();\n\n // The `outTokenRecipient` may already have enough in balance, in which case there's no need to transfer\n // to this address the token and everything can be given to the `to` address\n uint256 outTokenBalanceRecipient = outToken.balanceOf(outTokenRecipient);\n if (outTokenBalanceRecipient >= outTokenOwed || to == outTokenRecipient)\n outToken.safeTransfer(to, outTokenBalance);\n else {\n // The `outTokenRecipient` should receive the delta to make sure its end balance is equal to `outTokenOwed`\n // Any leftover in this case is sent to the `to` address\n // The function reverts if it did not obtain more than `outTokenOwed - outTokenBalanceRecipient` from the swap\n outToken.safeTransfer(outTokenRecipient, outTokenOwed - outTokenBalanceRecipient);\n outToken.safeTransfer(to, outTokenBalanceRecipient + outTokenBalance - outTokenOwed);\n }\n // Reusing the `inTokenObtained` variable for the `inToken` balance\n // Sending back the remaining amount of inTokens to the `to` address: it is possible that not the full `inTokenObtained`\n // is swapped to `outToken` if we're using the `1inch` payload\n inTokenObtained = inToken.balanceOf(address(this));\n if (inTokenObtained != 0) inToken.safeTransfer(to, inTokenObtained);\n }\n\n // ============================ GOVERNANCE FUNCTION ============================\n\n /// @notice Changes allowances of this contract for different tokens\n /// @param tokens Addresses of the tokens to allow\n /// @param spenders Addresses to allow transfer\n /// @param amounts Amounts to allow\n function changeAllowance(\n IERC20[] calldata tokens,\n address[] calldata spenders,\n uint256[] calldata amounts\n ) external {\n if (!core.isGovernorOrGuardian(msg.sender)) revert NotGovernorOrGuardian();\n uint256 tokensLength = tokens.length;\n if (tokensLength != spenders.length || tokensLength != amounts.length) revert IncompatibleLengths();\n for (uint256 i; i < tokensLength; ++i) {\n _changeAllowance(tokens[i], spenders[i], amounts[i]);\n }\n }\n\n // ========================= INTERNAL UTILITY FUNCTIONS ========================\n\n /// @notice Internal version of the `_changeAllowance` function\n function _changeAllowance(IERC20 token, address spender, uint256 amount) internal {\n uint256 currentAllowance = token.allowance(address(this), spender);\n // In case `currentAllowance < type(uint256).max / 2` and we want to increase it:\n // Do nothing (to handle tokens that need reapprovals to 0 and save gas)\n if (currentAllowance < amount && currentAllowance < type(uint256).max / 2) {\n token.safeIncreaseAllowance(spender, amount - currentAllowance);\n } else if (currentAllowance > amount) {\n token.safeDecreaseAllowance(spender, currentAllowance - amount);\n }\n }\n\n /// @notice Checks the allowance for a contract and updates it to the max if it is not big enough\n /// @param token Token for which allowance should be checked\n /// @param spender Address to grant allowance to\n /// @param amount Minimum amount of tokens needed for the allowance\n function _checkAllowance(IERC20 token, address spender, uint256 amount) internal {\n uint256 currentAllowance = token.allowance(address(this), spender);\n if (currentAllowance < amount) token.safeIncreaseAllowance(spender, type(uint256).max - currentAllowance);\n }\n\n /// @notice Performs a swap using either Uniswap, 1inch. This function can also stake stETH to wstETH\n /// @param inToken Token to swap\n /// @param amount Amount of tokens to swap\n /// @param swapType Type of the swap to perform\n /// @param args Extra args for the swap: in the case of Uniswap it should be a path, for 1inch it should be\n /// a payload\n /// @dev This function does nothing if `swapType` is None and it simply passes on the `amount` it received\n /// @dev No slippage is specified in the actions given here as a final slippage check is performed\n /// after the call to this function\n function _swap(IERC20 inToken, uint256 amount, SwapType swapType, bytes memory args) internal {\n if (swapType == SwapType.UniswapV3) _swapOnUniswapV3(inToken, amount, args);\n else if (swapType == SwapType.oneInch) _swapOn1inch(inToken, args);\n else if (swapType == SwapType.AngleRouter) _angleRouterActions(inToken, args);\n else if (swapType == SwapType.Leverage) _swapLeverage(args);\n }\n\n /// @notice Performs a UniswapV3 swap\n /// @param inToken Token to swap\n /// @param amount Amount of tokens to swap\n /// @param path Path for the UniswapV3 swap: this encodes the out token that is going to be obtained\n /// @dev This function does not check the out token obtained here: if it is wrongly specified, either\n /// the `swap` function could fail or these tokens could stay on the contract\n function _swapOnUniswapV3(IERC20 inToken, uint256 amount, bytes memory path) internal returns (uint256 amountOut) {\n // We need more than `amount` of allowance to the contract\n _checkAllowance(inToken, address(uniV3Router), amount);\n amountOut = uniV3Router.exactInput(ExactInputParams(path, address(this), block.timestamp, amount, 0));\n }\n\n /// @notice Allows to swap any token to an accepted collateral via 1inch API\n /// @param inToken Token received for the 1inch swap\n /// @param payload Bytes needed for 1inch API\n function _swapOn1inch(IERC20 inToken, bytes memory payload) internal returns (uint256 amountOut) {\n _changeAllowance(inToken, oneInch, type(uint256).max);\n //solhint-disable-next-line\n (bool success, bytes memory result) = oneInch.call(payload);\n if (!success) _revertBytes(result);\n amountOut = abi.decode(result, (uint256));\n }\n\n /// @notice Performs actions with the router contract of the protocol on the corresponding chain\n /// @param inToken Token concerned by the action and for which\n function _angleRouterActions(IERC20 inToken, bytes memory args) internal {\n (ActionType[] memory actions, bytes[] memory actionData) = abi.decode(args, (ActionType[], bytes[]));\n _changeAllowance(inToken, address(angleRouter), type(uint256).max);\n PermitType[] memory permits;\n angleRouter.mixer(permits, actions, actionData);\n }\n\n /// @notice Allows to take leverage or deleverage via a specific contract\n /// @param payload Bytes needed for 1inch API\n /// @dev This function is to be implemented if the swapper concerns a token that requires some actions\n /// not supported by 1inch or UniV3\n function _swapLeverage(bytes memory payload) internal virtual returns (uint256 amountOut) {}\n\n /// @notice Internal function used for error handling\n /// @param errMsg Error message received\n function _revertBytes(bytes memory errMsg) internal pure {\n if (errMsg.length != 0) {\n //solhint-disable-next-line\n assembly {\n revert(add(32, errMsg), mload(errMsg))\n }\n }\n revert EmptyReturnMessage();\n }\n}\n" + }, + "contracts/treasury/Treasury.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\n/*\n * █ \n ***** ▓▓▓ \n * ▓▓▓▓▓▓▓ \n * ///. ▓▓▓▓▓▓▓▓▓▓▓▓▓ \n ***** //////// ▓▓▓▓▓▓▓ \n * ///////////// ▓▓▓ \n ▓▓ ////////////////// █ ▓▓ \n ▓▓ ▓▓ /////////////////////// ▓▓ ▓▓ \n ▓▓ ▓▓ //////////////////////////// ▓▓ ▓▓ \n ▓▓ ▓▓ /////////▓▓▓///////▓▓▓///////// ▓▓ ▓▓ \n ▓▓ ,////////////////////////////////////// ▓▓ ▓▓ \n ▓▓ ////////////////////////////////////////// ▓▓ \n ▓▓ //////////////////////▓▓▓▓///////////////////// \n ,//////////////////////////////////////////////////// \n .////////////////////////////////////////////////////////// \n .//////////////////////////██.,//////////////////////////█ \n .//////////////////////████..,./////////////////////██ \n ...////////////////███████.....,.////////////////███ \n ,.,////////////████████ ........,///////////████ \n .,.,//////█████████ ,.......///////████ \n ,..//████████ ........./████ \n ..,██████ .....,███ \n .██ ,.,█ \n \n \n \n ▓▓ ▓▓▓▓▓▓▓▓▓▓ ▓▓▓▓▓▓▓▓▓▓ ▓▓ ▓▓▓▓▓▓▓▓▓▓ \n ▓▓▓▓▓▓ ▓▓▓ ▓▓▓ ▓▓▓ ▓▓ ▓▓ ▓▓▓▓ \n ▓▓▓ ▓▓▓ ▓▓▓ ▓▓▓ ▓▓▓ ▓▓▓ ▓▓ ▓▓▓▓▓ \n ▓▓▓ ▓▓ ▓▓▓ ▓▓▓ ▓▓▓▓▓▓▓▓▓▓ ▓▓▓▓▓▓▓▓▓▓ ▓▓▓▓▓▓▓▓▓▓ \n*/\n\npragma solidity ^0.8.12;\n\nimport \"@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol\";\nimport \"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\";\nimport \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\n\nimport \"../interfaces/IAgToken.sol\";\nimport \"../interfaces/ICoreBorrow.sol\";\nimport \"../interfaces/IFlashAngle.sol\";\nimport \"../interfaces/ITreasury.sol\";\nimport \"../interfaces/IVaultManager.sol\";\n\n/// @title Treasury\n/// @author Angle Labs, Inc.\n/// @notice Treasury of Angle Borrowing Module doing the accounting across all VaultManagers for\n/// a given stablecoin\ncontract Treasury is ITreasury, Initializable {\n using SafeERC20 for IERC20;\n\n /// @notice Base used for parameter computation\n uint256 public constant BASE_9 = 1e9;\n\n // ================================= REFERENCES ================================\n\n /// @notice Reference to the `CoreBorrow` contract of the module which handles all AccessControl logic\n ICoreBorrow public core;\n /// @notice Flash Loan Module with a minter right on the stablecoin\n IFlashAngle public flashLoanModule;\n /// @inheritdoc ITreasury\n IAgToken public stablecoin;\n /// @notice Address responsible for handling the surplus made by the treasury\n address public surplusManager;\n /// @notice List of the accepted `VaultManager` of the protocol\n address[] public vaultManagerList;\n /// @notice Maps an address to 1 if it was initialized as a `VaultManager` contract\n mapping(address => uint256) public vaultManagerMap;\n\n // ================================= VARIABLES =================================\n\n /// @notice Amount of bad debt (unbacked stablecoin) accumulated across all `VaultManager` contracts\n /// linked to this stablecoin\n uint256 public badDebt;\n /// @notice Surplus amount accumulated by the contract waiting to be distributed to governance. Technically\n /// only a share of this `surplusBuffer` will go to governance. Once a share of the surplus buffer has been\n /// given to governance, then this surplus is reset\n uint256 public surplusBuffer;\n\n // ================================= PARAMETER =================================\n\n /// @notice Share of the `surplusBuffer` distributed to governance (in `BASE_9`)\n uint64 public surplusForGovernance;\n\n // =================================== EVENTS ==================================\n\n event BadDebtUpdated(uint256 badDebtValue);\n event CoreUpdated(address indexed _core);\n event NewTreasurySet(address indexed _treasury);\n event Recovered(address indexed token, address indexed to, uint256 amount);\n event SurplusBufferUpdated(uint256 surplusBufferValue);\n event SurplusForGovernanceUpdated(uint64 _surplusForGovernance);\n event SurplusManagerUpdated(address indexed _surplusManager);\n event VaultManagerToggled(address indexed vaultManager);\n\n // =================================== ERRORS ==================================\n\n error AlreadyVaultManager();\n error InvalidAddress();\n error InvalidTreasury();\n error NotCore();\n error NotGovernor();\n error NotVaultManager();\n error RightsNotRemoved();\n error TooBigAmount();\n error TooHighParameterValue();\n error ZeroAddress();\n\n // ================================== MODIFIER =================================\n\n /// @notice Checks whether the `msg.sender` has the governor role or not\n modifier onlyGovernor() {\n if (!core.isGovernor(msg.sender)) revert NotGovernor();\n _;\n }\n\n /// @notice Initializes the treasury contract\n /// @param _core Address of the `CoreBorrow` contract of the module\n /// @param _stablecoin Address of the stablecoin\n function initialize(ICoreBorrow _core, IAgToken _stablecoin) public virtual initializer {\n if (address(_stablecoin) == address(0) || address(_core) == address(0)) revert ZeroAddress();\n core = _core;\n stablecoin = _stablecoin;\n }\n\n /// @custom:oz-upgrades-unsafe-allow constructor\n constructor() initializer {}\n\n // =============================== VIEW FUNCTIONS ==============================\n\n /// @inheritdoc ITreasury\n function isGovernor(address admin) external view returns (bool) {\n return core.isGovernor(admin);\n }\n\n /// @inheritdoc ITreasury\n function isGovernorOrGuardian(address admin) external view returns (bool) {\n return core.isGovernorOrGuardian(admin);\n }\n\n /// @inheritdoc ITreasury\n function isVaultManager(address _vaultManager) external view returns (bool) {\n return vaultManagerMap[_vaultManager] == 1;\n }\n\n // ===================== EXTERNAL PERMISSIONLESS FUNCTIONS =====================\n\n /// @notice Fetches the surplus accrued across all the `VaultManager` contracts controlled by this\n /// `Treasury` contract as well as from the fees of the `FlashLoan` module\n /// @return Surplus buffer value at the end of the call\n /// @return Bad debt value at the end of the call\n /// @dev This function pools surplus and bad debt across all contracts and then updates the `surplusBuffer`\n /// (or the `badDebt` if more losses were made than profits)\n function fetchSurplusFromAll() external returns (uint256, uint256) {\n return _fetchSurplusFromAll();\n }\n\n /// @notice Fetches the surplus accrued in the flash loan module and updates the `surplusBuffer`\n /// @return Surplus buffer value at the end of the call\n /// @return Bad debt value at the end of the call\n /// @dev This function fails if the `flashLoanModule` has not been initialized yet\n function fetchSurplusFromFlashLoan() external returns (uint256, uint256) {\n uint256 surplusBufferValue = surplusBuffer + flashLoanModule.accrueInterestToTreasury(stablecoin);\n return _updateSurplusAndBadDebt(surplusBufferValue, badDebt);\n }\n\n /// @notice Pushes the surplus buffer to the `surplusManager` contract\n /// @return governanceAllocation Amount transferred to governance\n /// @dev It makes sure to fetch the surplus from all the contracts handled by this treasury to avoid\n /// the situation where rewards are still distributed to governance even though a `VaultManager` has made\n /// a big loss\n /// @dev Typically this function is to be called once every week by a keeper to distribute rewards to veANGLE\n /// holders\n /// @dev `stablecoin` must be an AgToken and hence `transfer` reverts if the call is not successful\n function pushSurplus() external returns (uint256 governanceAllocation) {\n address _surplusManager = surplusManager;\n if (_surplusManager == address(0)) {\n revert ZeroAddress();\n }\n (uint256 surplusBufferValue, ) = _fetchSurplusFromAll();\n surplusBuffer = 0;\n emit SurplusBufferUpdated(0);\n governanceAllocation = (surplusForGovernance * surplusBufferValue) / BASE_9;\n stablecoin.transfer(_surplusManager, governanceAllocation);\n }\n\n /// @notice Updates the bad debt of the protocol in case where the protocol has accumulated some revenue\n /// from an external source\n /// @param amount Amount to reduce the bad debt of\n /// @return badDebtValue Value of the bad debt at the end of the call\n /// @dev If the protocol has made a loss and managed to make some profits to recover for this loss (through\n /// a program like Olympus Pro), then this function needs to be called\n /// @dev `badDebt` is simply reduced here by burning stablecoins\n /// @dev It is impossible to burn more than the `badDebt` otherwise this function could be used to manipulate\n /// the `surplusBuffer` and hence the amount going to governance\n function updateBadDebt(uint256 amount) external returns (uint256 badDebtValue) {\n stablecoin.burnSelf(amount, address(this));\n badDebtValue = badDebt - amount;\n badDebt = badDebtValue;\n emit BadDebtUpdated(badDebtValue);\n }\n\n // ========================= INTERNAL UTILITY FUNCTIONS ========================\n\n /// @notice Internal version of the `fetchSurplusFromAll` function\n function _fetchSurplusFromAll() internal returns (uint256 surplusBufferValue, uint256 badDebtValue) {\n (surplusBufferValue, badDebtValue) = _fetchSurplusFromList(vaultManagerList);\n // It will fail anyway if the `flashLoanModule` is the zero address\n if (address(flashLoanModule) != address(0))\n surplusBufferValue += flashLoanModule.accrueInterestToTreasury(stablecoin);\n (surplusBufferValue, badDebtValue) = _updateSurplusAndBadDebt(surplusBufferValue, badDebtValue);\n }\n\n /// @notice Fetches the surplus from a list of `VaultManager` addresses without modifying the\n /// `surplusBuffer` and `badDebtValue`\n /// @return surplusBufferValue Value the `surplusBuffer` should have after the call if it was updated\n /// @return badDebtValue Value the `badDebt` should have after the call if it was updated\n /// @dev This internal function is never to be called alone, and should always be called in conjunction\n /// with the `_updateSurplusAndBadDebt` function\n function _fetchSurplusFromList(\n address[] memory vaultManagers\n ) internal returns (uint256 surplusBufferValue, uint256 badDebtValue) {\n badDebtValue = badDebt;\n surplusBufferValue = surplusBuffer;\n uint256 newSurplus;\n uint256 newBadDebt;\n uint256 vaultManagersLength = vaultManagers.length;\n for (uint256 i; i < vaultManagersLength; ++i) {\n (newSurplus, newBadDebt) = IVaultManager(vaultManagers[i]).accrueInterestToTreasury();\n surplusBufferValue += newSurplus;\n badDebtValue += newBadDebt;\n }\n }\n\n /// @notice Updates the `surplusBuffer` and the `badDebt` from updated values after calling the flash loan module\n /// and/or a list of `VaultManager` contracts\n /// @param surplusBufferValue Value of the surplus buffer after the calls to the different modules\n /// @param badDebtValue Value of the bad debt after the calls to the different modules\n /// @return Value of the `surplusBuffer` corrected from the `badDebt`\n /// @return Value of the `badDebt` corrected from the `surplusBuffer` and from the surplus the treasury had accumulated\n /// previously\n /// @dev When calling this function, it is possible that there is a positive `surplusBufferValue` and `badDebtValue`,\n /// this function tries to reconcile both values and makes sure that we either have surplus or bad debt but not both\n /// at the same time\n function _updateSurplusAndBadDebt(\n uint256 surplusBufferValue,\n uint256 badDebtValue\n ) internal returns (uint256, uint256) {\n if (badDebtValue != 0) {\n // If we have bad debt we need to burn stablecoins that accrued to the protocol\n // We still need to make sure that we're not burning too much or as much as we can if the debt is big\n uint256 balance = stablecoin.balanceOf(address(this));\n // We are going to burn `min(balance, badDebtValue)`\n uint256 toBurn = balance <= badDebtValue ? balance : badDebtValue;\n stablecoin.burnSelf(toBurn, address(this));\n // If we burned more than `surplusBuffer`, we set surplus to 0. It means we had to tap into Treasury reserve\n surplusBufferValue = toBurn >= surplusBufferValue ? 0 : surplusBufferValue - toBurn;\n badDebtValue -= toBurn;\n // Note here that the stablecoin balance is necessarily greater than the surplus buffer, and so if\n // `surplusBuffer >= toBurn`, then `badDebtValue = toBurn`\n }\n surplusBuffer = surplusBufferValue;\n badDebt = badDebtValue;\n emit SurplusBufferUpdated(surplusBufferValue);\n emit BadDebtUpdated(badDebtValue);\n return (surplusBufferValue, badDebtValue);\n }\n\n /// @notice Adds a new `VaultManager`\n /// @param vaultManager `VaultManager` contract to add\n /// @dev This contract should have already been initialized with a correct treasury address\n /// @dev It's this function that gives the minter right to the `VaultManager`\n function _addVaultManager(address vaultManager) internal virtual {\n if (vaultManagerMap[vaultManager] == 1) revert AlreadyVaultManager();\n if (address(IVaultManager(vaultManager).treasury()) != address(this)) revert InvalidTreasury();\n vaultManagerMap[vaultManager] = 1;\n vaultManagerList.push(vaultManager);\n emit VaultManagerToggled(vaultManager);\n stablecoin.addMinter(vaultManager);\n }\n\n // ============================= GOVERNOR FUNCTIONS ============================\n\n /// @notice Adds a new minter for the stablecoin\n /// @param minter Minter address to add\n function addMinter(address minter) external virtual onlyGovernor {\n if (minter == address(0)) revert ZeroAddress();\n stablecoin.addMinter(minter);\n }\n\n /// @notice External wrapper for `_addVaultManager`\n function addVaultManager(address vaultManager) external virtual onlyGovernor {\n _addVaultManager(vaultManager);\n }\n\n /// @notice Removes a minter from the stablecoin contract\n /// @param minter Minter address to remove\n function removeMinter(address minter) external virtual onlyGovernor {\n // To remove the minter role to a `VaultManager` you have to go through the `removeVaultManager` function\n if (vaultManagerMap[minter] == 1) revert InvalidAddress();\n stablecoin.removeMinter(minter);\n }\n\n /// @notice Removes a `VaultManager`\n /// @param vaultManager `VaultManager` contract to remove\n /// @dev A removed `VaultManager` loses its minter right on the stablecoin\n function removeVaultManager(address vaultManager) external onlyGovernor {\n if (vaultManagerMap[vaultManager] != 1) revert NotVaultManager();\n delete vaultManagerMap[vaultManager];\n // deletion from `vaultManagerList` loop\n uint256 vaultManagerListLength = vaultManagerList.length;\n for (uint256 i; i < vaultManagerListLength - 1; ++i) {\n if (vaultManagerList[i] == vaultManager) {\n // replace the `VaultManager` to remove with the last of the list\n vaultManagerList[i] = vaultManagerList[vaultManagerListLength - 1];\n break;\n }\n }\n // remove last element in array\n vaultManagerList.pop();\n emit VaultManagerToggled(vaultManager);\n stablecoin.removeMinter(vaultManager);\n }\n\n /// @notice Allows to recover any ERC20 token, including the stablecoin handled by this contract, and to send it\n /// to a contract\n /// @param tokenAddress Address of the token to recover\n /// @param to Address of the contract to send collateral to\n /// @param amountToRecover Amount of collateral to transfer\n /// @dev It is impossible to recover the stablecoin of the protocol if there is some bad debt for it\n /// @dev In this case, the function makes sure to fetch the surplus/bad debt from all the `VaultManager` contracts\n /// and from the flash loan module\n /// @dev If the token to recover is the stablecoin, tokens recovered are fetched\n /// from the surplus and not from the `surplusBuffer`\n function recoverERC20(address tokenAddress, address to, uint256 amountToRecover) external onlyGovernor {\n // Cannot recover stablecoin if badDebt or tap into the surplus buffer\n if (tokenAddress == address(stablecoin)) {\n _fetchSurplusFromAll();\n // If balance is non zero then this means, after the call to `fetchSurplusFromAll` that\n // bad debt is necessarily null\n uint256 balance = stablecoin.balanceOf(address(this));\n if (amountToRecover + surplusBuffer > balance) revert TooBigAmount();\n stablecoin.transfer(to, amountToRecover);\n } else {\n IERC20(tokenAddress).safeTransfer(to, amountToRecover);\n }\n emit Recovered(tokenAddress, to, amountToRecover);\n }\n\n /// @notice Changes the treasury contract and communicates this change to all `VaultManager` contract\n /// @param _treasury New treasury address for this stablecoin\n /// @dev This function is basically a way to remove rights to this contract and grant them to a new one\n /// @dev It could be used to set a new core contract\n function setTreasury(address _treasury) external virtual onlyGovernor {\n if (ITreasury(_treasury).stablecoin() != stablecoin) revert InvalidTreasury();\n // Flash loan role should be removed before calling this function\n if (core.isFlashLoanerTreasury(address(this))) revert RightsNotRemoved();\n emit NewTreasurySet(_treasury);\n uint256 vaultManagerListLength = vaultManagerList.length;\n for (uint256 i; i < vaultManagerListLength; ++i) {\n IVaultManager(vaultManagerList[i]).setTreasury(_treasury);\n }\n // A `TreasuryUpdated` event is triggered in the stablecoin\n stablecoin.setTreasury(_treasury);\n }\n\n /// @notice Sets the `surplusForGovernance` parameter\n /// @param _surplusForGovernance New value of the parameter\n /// @dev To pause surplus distribution, governance needs to set a zero value for `surplusForGovernance`\n /// which means\n function setSurplusForGovernance(uint64 _surplusForGovernance) external onlyGovernor {\n if (_surplusForGovernance > BASE_9) revert TooHighParameterValue();\n surplusForGovernance = _surplusForGovernance;\n emit SurplusForGovernanceUpdated(_surplusForGovernance);\n }\n\n /// @notice Sets the `surplusManager` contract responsible for handling the surplus of the\n /// protocol\n /// @param _surplusManager New address responsible for handling the surplus\n function setSurplusManager(address _surplusManager) external onlyGovernor {\n if (_surplusManager == address(0)) revert ZeroAddress();\n surplusManager = _surplusManager;\n emit SurplusManagerUpdated(_surplusManager);\n }\n\n /// @notice Sets a new `core` contract\n /// @dev This function should typically be called on all treasury contracts after the `setCore`\n /// function has been called on the `CoreBorrow` contract\n /// @dev One sanity check that can be performed here is to verify whether at least the governor\n /// calling the contract is still a governor in the new core\n function setCore(ICoreBorrow _core) external onlyGovernor {\n if (!_core.isGovernor(msg.sender)) revert NotGovernor();\n core = ICoreBorrow(_core);\n emit CoreUpdated(address(_core));\n }\n\n /// @inheritdoc ITreasury\n function setFlashLoanModule(address _flashLoanModule) external {\n if (msg.sender != address(core)) revert NotCore();\n address oldFlashLoanModule = address(flashLoanModule);\n flashLoanModule = IFlashAngle(_flashLoanModule);\n if (oldFlashLoanModule != address(0)) {\n stablecoin.removeMinter(oldFlashLoanModule);\n }\n // We may want to cancel the module\n if (_flashLoanModule != address(0)) {\n stablecoin.addMinter(_flashLoanModule);\n }\n }\n}\n" + }, + "contracts/ui-helpers/AngleBorrowHelpers.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\n/*\n * █ \n ***** ▓▓▓ \n * ▓▓▓▓▓▓▓ \n * ///. ▓▓▓▓▓▓▓▓▓▓▓▓▓ \n ***** //////// ▓▓▓▓▓▓▓ \n * ///////////// ▓▓▓ \n ▓▓ ////////////////// █ ▓▓ \n ▓▓ ▓▓ /////////////////////// ▓▓ ▓▓ \n ▓▓ ▓▓ //////////////////////////// ▓▓ ▓▓ \n ▓▓ ▓▓ /////////▓▓▓///////▓▓▓///////// ▓▓ ▓▓ \n ▓▓ ,////////////////////////////////////// ▓▓ ▓▓ \n ▓▓ ////////////////////////////////////////// ▓▓ \n ▓▓ //////////////////////▓▓▓▓///////////////////// \n ,//////////////////////////////////////////////////// \n .////////////////////////////////////////////////////////// \n .//////////////////////////██.,//////////////////////////█ \n .//////////////////////████..,./////////////////////██ \n ...////////////////███████.....,.////////////////███ \n ,.,////////////████████ ........,///////////████ \n .,.,//////█████████ ,.......///////████ \n ,..//████████ ........./████ \n ..,██████ .....,███ \n .██ ,.,█ \n \n \n \n ▓▓ ▓▓▓▓▓▓▓▓▓▓ ▓▓▓▓▓▓▓▓▓▓ ▓▓ ▓▓▓▓▓▓▓▓▓▓ \n ▓▓▓▓▓▓ ▓▓▓ ▓▓▓ ▓▓▓ ▓▓ ▓▓ ▓▓▓▓ \n ▓▓▓ ▓▓▓ ▓▓▓ ▓▓▓ ▓▓▓ ▓▓▓ ▓▓ ▓▓▓▓▓ \n ▓▓▓ ▓▓ ▓▓▓ ▓▓▓ ▓▓▓▓▓▓▓▓▓▓ ▓▓▓▓▓▓▓▓▓▓ ▓▓▓▓▓▓▓▓▓▓ \n*/\n\nimport \"@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol\";\nimport \"../interfaces/IVaultManager.sol\";\n\npragma solidity ^0.8.12;\n\n/// @title AngleBorrowHelpers\n/// @author Angle Labs, Inc.\n/// @notice Contract with view functions designed to facilitate integrations on the Borrow module of the Angle Protocol\n/// @dev This contract only contains view functions to be queried off-chain. It was thus not optimized for gas consumption\ncontract AngleBorrowHelpers is Initializable {\n /// @notice Returns all the vaults owned or controlled (under the form of approval) by an address\n /// @param vaultManager VaultManager address to query vaultIDs on\n /// @param spender Address for which vault ownerships should be checked\n /// @return List of `vaultID` controlled by this address\n /// @return Count of vaults owned by the address\n /// @dev This function is never to be called on-chain since it iterates over all vaultIDs. It is here\n /// to reduce dependency on an external graph to link an ID to its owner\n function getControlledVaults(\n IVaultManager vaultManager,\n address spender\n ) external view returns (uint256[] memory, uint256) {\n uint256 arraySize = vaultManager.vaultIDCount();\n uint256[] memory vaultsControlled = new uint256[](arraySize);\n uint256 count;\n for (uint256 i = 1; i <= arraySize; ++i) {\n try vaultManager.isApprovedOrOwner(spender, i) returns (bool _isApprovedOrOwner) {\n if (_isApprovedOrOwner) {\n vaultsControlled[count] = i;\n count += 1;\n }\n } catch {\n continue;\n } // This happens if nobody owns the vaultID=i (if there has been a burn)\n }\n return (vaultsControlled, count);\n }\n\n /// @custom:oz-upgrades-unsafe-allow constructor\n constructor() initializer {}\n}\n" + }, + "contracts/ui-helpers/AngleHelpers.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\nimport \"../interfaces/IAngleRouter.sol\";\nimport \"../interfaces/coreModule/IAgTokenMainnet.sol\";\nimport \"../interfaces/coreModule/ICore.sol\";\nimport \"../interfaces/coreModule/IOracleCore.sol\";\nimport \"../interfaces/coreModule/IPerpetualManager.sol\";\nimport \"../interfaces/coreModule/IPoolManager.sol\";\nimport \"../interfaces/coreModule/IStableMaster.sol\";\nimport \"./AngleBorrowHelpers.sol\";\n\npragma solidity ^0.8.12;\n\nstruct Parameters {\n SLPData slpData;\n MintBurnData feeData;\n PerpetualManagerFeeData perpFeeData;\n PerpetualManagerParamData perpParam;\n}\n\nstruct PerpetualManagerFeeData {\n uint64[] xHAFeesDeposit;\n uint64[] yHAFeesDeposit;\n uint64[] xHAFeesWithdraw;\n uint64[] yHAFeesWithdraw;\n uint64 haBonusMalusDeposit;\n uint64 haBonusMalusWithdraw;\n}\n\nstruct PerpetualManagerParamData {\n uint64 maintenanceMargin;\n uint64 maxLeverage;\n uint64 targetHAHedge;\n uint64 limitHAHedge;\n uint64 lockTime;\n}\n\nstruct CollateralAddresses {\n address stableMaster;\n address poolManager;\n address perpetualManager;\n address sanToken;\n address oracle;\n address gauge;\n address feeManager;\n address[] strategies;\n}\n\n/// @title AngleHelpers\n/// @author Angle Labs, Inc.\n/// @notice Contract with view functions designed to facilitate integrations on the Core and Borrow module of the Angle Protocol\n/// @dev This contract only contains view functions to be queried off-chain. It was thus not optimized for gas consumption\ncontract AngleHelpers is AngleBorrowHelpers {\n // =========================== HELPER VIEW FUNCTIONS ===========================\n\n /// @notice Gives the amount of `agToken` you'd be getting if you were executing in the same block a mint transaction\n /// with `amount` of `collateral` in the Core module of the Angle protocol as well as the value of the fees\n /// (in `BASE_PARAMS`) that would be applied during the mint\n /// @return Amount of `agToken` that would be obtained with a mint transaction in the same block\n /// @return Percentage of fees that would be taken during a mint transaction in the same block\n /// @dev This function reverts if the mint transaction was to revert in the same conditions (without taking into account\n /// potential approval problems to the `StableMaster` contract)\n function previewMintAndFees(\n uint256 amount,\n address agToken,\n address collateral\n ) external view returns (uint256, uint256) {\n return _previewMintAndFees(amount, agToken, collateral);\n }\n\n /// @notice Gives the amount of `collateral` you'd be getting if you were executing in the same block a burn transaction\n /// with `amount` of `agToken` in the Core module of the Angle protocol as well as the value of the fees\n /// (in `BASE_PARAMS`) that would be applied during the burn\n /// @return Amount of `collateral` that would be obtained with a burn transaction in the same block\n /// @return Percentage of fees that would be taken during a burn transaction in the same block\n /// @dev This function reverts if the burn transaction was to revert in the same conditions (without taking into account\n /// potential approval problems to the `StableMaster` contract or agToken balance prior to the call)\n function previewBurnAndFees(\n uint256 amount,\n address agToken,\n address collateral\n ) external view returns (uint256, uint256) {\n return _previewBurnAndFees(amount, agToken, collateral);\n }\n\n /// @notice Returns all the addresses associated to the (`agToken`,`collateral`) pair given\n /// @return addresses A struct with all the addresses associated in the Core module\n function getCollateralAddresses(\n address agToken,\n address collateral\n ) external view returns (CollateralAddresses memory addresses) {\n address stableMaster = IAgTokenMainnet(agToken).stableMaster();\n (address poolManager, address perpetualManager, address sanToken, address gauge) = ROUTER.mapPoolManagers(\n stableMaster,\n collateral\n );\n (, , , IOracleCore oracle, , , , , ) = IStableMaster(stableMaster).collateralMap(poolManager);\n addresses.stableMaster = stableMaster;\n addresses.poolManager = poolManager;\n addresses.perpetualManager = perpetualManager;\n addresses.sanToken = sanToken;\n addresses.gauge = gauge;\n addresses.oracle = address(oracle);\n addresses.feeManager = IPoolManager(poolManager).feeManager();\n\n uint256 length;\n while (true) {\n try IPoolManager(poolManager).strategyList(length) returns (address) {\n length += 1;\n } catch {\n break;\n }\n }\n address[] memory strategies = new address[](length);\n for (uint256 i; i < length; ++i) {\n strategies[i] = IPoolManager(poolManager).strategyList(i);\n }\n addresses.strategies = strategies;\n }\n\n /// @notice Gets the addresses of all the `StableMaster` contracts and their associated `AgToken` addresses\n /// @return List of the `StableMaster` addresses of the Angle protocol\n /// @return List of the `AgToken` addresses of the protocol\n /// @dev The place of an agToken address in the list is the same as the corresponding `StableMaster` address\n function getStablecoinAddresses() external view returns (address[] memory, address[] memory) {\n address[] memory stableMasterAddresses = CORE.stablecoinList();\n address[] memory agTokenAddresses = new address[](stableMasterAddresses.length);\n for (uint256 i; i < stableMasterAddresses.length; ++i) {\n agTokenAddresses[i] = IStableMaster(stableMasterAddresses[i]).agToken();\n }\n return (stableMasterAddresses, agTokenAddresses);\n }\n\n /// @notice Returns most of the governance parameters associated to the (`agToken`,`collateral`) pair given\n /// @return params Struct with most of the parameters in the `StableMaster` and `PerpetualManager` contracts\n /// @dev Check out the struct `Parameters` for the meaning of the return values\n function getCollateralParameters(\n address agToken,\n address collateral\n ) external view returns (Parameters memory params) {\n (address stableMaster, address poolManager) = _getStableMasterAndPoolManager(agToken, collateral);\n (\n ,\n ,\n IPerpetualManager perpetualManager,\n ,\n ,\n ,\n ,\n SLPData memory slpData,\n MintBurnData memory feeData\n ) = IStableMaster(stableMaster).collateralMap(poolManager);\n\n params.slpData = slpData;\n params.feeData = feeData;\n params.perpParam.maintenanceMargin = perpetualManager.maintenanceMargin();\n params.perpParam.maxLeverage = perpetualManager.maxLeverage();\n params.perpParam.targetHAHedge = perpetualManager.targetHAHedge();\n params.perpParam.limitHAHedge = perpetualManager.limitHAHedge();\n params.perpParam.lockTime = perpetualManager.lockTime();\n\n params.perpFeeData.haBonusMalusDeposit = perpetualManager.haBonusMalusDeposit();\n params.perpFeeData.haBonusMalusWithdraw = perpetualManager.haBonusMalusWithdraw();\n\n uint256 length;\n while (true) {\n try perpetualManager.xHAFeesDeposit(length) returns (uint64) {\n length += 1;\n } catch {\n break;\n }\n }\n uint64[] memory data = new uint64[](length);\n uint64[] memory data2 = new uint64[](length);\n for (uint256 i; i < length; ++i) {\n data[i] = perpetualManager.xHAFeesDeposit(i);\n data2[i] = perpetualManager.yHAFeesDeposit(i);\n }\n params.perpFeeData.xHAFeesDeposit = data;\n params.perpFeeData.yHAFeesDeposit = data2;\n\n length = 0;\n while (true) {\n try perpetualManager.xHAFeesWithdraw(length) returns (uint64) {\n length += 1;\n } catch {\n break;\n }\n }\n data = new uint64[](length);\n data2 = new uint64[](length);\n for (uint256 i; i < length; ++i) {\n data[i] = perpetualManager.xHAFeesWithdraw(i);\n data2[i] = perpetualManager.yHAFeesWithdraw(i);\n }\n params.perpFeeData.xHAFeesWithdraw = data;\n params.perpFeeData.yHAFeesWithdraw = data2;\n }\n\n /// @notice Returns the address of the poolManager associated to an (`agToken`, `collateral`) pair\n /// in the Core module of the protocol\n function getPoolManager(address agToken, address collateral) public view returns (address poolManager) {\n (, poolManager) = _getStableMasterAndPoolManager(agToken, collateral);\n }\n\n // ============================= REPLICA FUNCTIONS =============================\n // These replicate what is done in the other contracts of the protocol\n\n function _previewBurnAndFees(\n uint256 amount,\n address agToken,\n address collateral\n ) internal view returns (uint256 amountForUserInCollat, uint256 feePercent) {\n (address stableMaster, address poolManager) = _getStableMasterAndPoolManager(agToken, collateral);\n (\n address token,\n ,\n IPerpetualManager perpetualManager,\n IOracleCore oracle,\n uint256 stocksUsers,\n ,\n uint256 collatBase,\n ,\n MintBurnData memory feeData\n ) = IStableMaster(stableMaster).collateralMap(poolManager);\n if (token == address(0) || IStableMaster(stableMaster).paused(keccak256(abi.encodePacked(STABLE, poolManager))))\n revert NotInitialized();\n if (amount > stocksUsers) revert InvalidAmount();\n\n if (feeData.xFeeBurn.length == 1) {\n feePercent = feeData.yFeeBurn[0];\n } else {\n bytes memory data = abi.encode(address(perpetualManager), feeData.targetHAHedge);\n uint64 hedgeRatio = _computeHedgeRatio(stocksUsers - amount, data);\n feePercent = _piecewiseLinear(hedgeRatio, feeData.xFeeBurn, feeData.yFeeBurn);\n }\n feePercent = (feePercent * feeData.bonusMalusBurn) / BASE_PARAMS;\n\n amountForUserInCollat = (amount * (BASE_PARAMS - feePercent) * collatBase) / (oracle.readUpper() * BASE_PARAMS);\n }\n\n function _previewMintAndFees(\n uint256 amount,\n address agToken,\n address collateral\n ) internal view returns (uint256 amountForUserInStable, uint256 feePercent) {\n (address stableMaster, address poolManager) = _getStableMasterAndPoolManager(agToken, collateral);\n (\n address token,\n ,\n IPerpetualManager perpetualManager,\n IOracleCore oracle,\n uint256 stocksUsers,\n ,\n ,\n ,\n MintBurnData memory feeData\n ) = IStableMaster(stableMaster).collateralMap(poolManager);\n if (token == address(0) || IStableMaster(stableMaster).paused(keccak256(abi.encodePacked(STABLE, poolManager))))\n revert NotInitialized();\n\n amountForUserInStable = oracle.readQuoteLower(amount);\n\n if (feeData.xFeeMint.length == 1) feePercent = feeData.yFeeMint[0];\n else {\n bytes memory data = abi.encode(address(perpetualManager), feeData.targetHAHedge);\n uint64 hedgeRatio = _computeHedgeRatio(amountForUserInStable + stocksUsers, data);\n feePercent = _piecewiseLinear(hedgeRatio, feeData.xFeeMint, feeData.yFeeMint);\n }\n feePercent = (feePercent * feeData.bonusMalusMint) / BASE_PARAMS;\n\n amountForUserInStable = (amountForUserInStable * (BASE_PARAMS - feePercent)) / BASE_PARAMS;\n if (stocksUsers + amountForUserInStable > feeData.capOnStableMinted) revert InvalidAmount();\n }\n\n // ============================= UTILITY FUNCTIONS =============================\n // These utility functions are taken from other contracts of the protocol\n\n function _computeHedgeRatio(uint256 newStocksUsers, bytes memory data) internal view returns (uint64 ratio) {\n (address perpetualManager, uint64 targetHAHedge) = abi.decode(data, (address, uint64));\n uint256 totalHedgeAmount = IPerpetualManager(perpetualManager).totalHedgeAmount();\n newStocksUsers = (targetHAHedge * newStocksUsers) / BASE_PARAMS;\n if (newStocksUsers > totalHedgeAmount) ratio = uint64((totalHedgeAmount * BASE_PARAMS) / newStocksUsers);\n else ratio = uint64(BASE_PARAMS);\n }\n\n function _piecewiseLinear(uint64 x, uint64[] memory xArray, uint64[] memory yArray) internal pure returns (uint64) {\n if (x >= xArray[xArray.length - 1]) {\n return yArray[xArray.length - 1];\n } else if (x <= xArray[0]) {\n return yArray[0];\n } else {\n uint256 lower;\n uint256 upper = xArray.length - 1;\n uint256 mid;\n while (upper - lower > 1) {\n mid = lower + (upper - lower) / 2;\n if (xArray[mid] <= x) {\n lower = mid;\n } else {\n upper = mid;\n }\n }\n if (yArray[upper] > yArray[lower]) {\n return\n yArray[lower] +\n ((yArray[upper] - yArray[lower]) * (x - xArray[lower])) /\n (xArray[upper] - xArray[lower]);\n } else {\n return\n yArray[lower] -\n ((yArray[lower] - yArray[upper]) * (x - xArray[lower])) /\n (xArray[upper] - xArray[lower]);\n }\n }\n }\n\n function _getStableMasterAndPoolManager(\n address agToken,\n address collateral\n ) internal view returns (address stableMaster, address poolManager) {\n stableMaster = IAgTokenMainnet(agToken).stableMaster();\n (poolManager, , , ) = ROUTER.mapPoolManagers(stableMaster, collateral);\n }\n\n // ========================= CONSTANTS AND INITIALIZERS ========================\n\n IAngleRouter public constant ROUTER = IAngleRouter(0xBB755240596530be0c1DE5DFD77ec6398471561d);\n ICore public constant CORE = ICore(0x61ed74de9Ca5796cF2F8fD60D54160D47E30B7c3);\n\n bytes32 public constant STABLE = keccak256(\"STABLE\");\n uint256 public constant BASE_PARAMS = 10 ** 9;\n\n error NotInitialized();\n error InvalidAmount();\n}\n" + }, + "contracts/utils/Constants.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\nerror InsufficientAssets();\n\n/// @title Constants\n/// @author Angle Labs, Inc.\n/// @notice Constants and errors for Angle Protocol contracts\ncontract Constants {\n uint256 internal constant _BASE_9 = 1e9;\n uint256 internal constant _BASE_18 = 1e18;\n uint256 internal constant _BASE_27 = 1e27;\n uint256 internal constant _BASE_36 = 1e36;\n}\n" + }, + "contracts/vaultManager/VaultManagerERC721.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\nimport \"./VaultManagerStorage.sol\";\n\n/// @title VaultManagerERC721\n/// @author Angle Labs, Inc.\n/// @dev Base ERC721 Implementation of VaultManager\nabstract contract VaultManagerERC721 is IERC721MetadataUpgradeable, VaultManagerStorage {\n using SafeERC20 for IERC20;\n using Address for address;\n\n /// @inheritdoc IERC721MetadataUpgradeable\n string public name;\n /// @inheritdoc IERC721MetadataUpgradeable\n string public symbol;\n\n // ================================= MODIFIERS =================================\n\n /// @notice Checks if the person interacting with the vault with `vaultID` is approved\n /// @param caller Address of the person seeking to interact with the vault\n /// @param vaultID ID of the concerned vault\n modifier onlyApprovedOrOwner(address caller, uint256 vaultID) {\n if (!_isApprovedOrOwner(caller, vaultID)) revert NotApproved();\n _;\n }\n\n // ================================ ERC721 LOGIC ===============================\n\n /// @notice Checks whether a given address is approved for a vault or owns this vault\n /// @param spender Address for which vault ownership should be checked\n /// @param vaultID ID of the vault to check\n /// @return Whether the `spender` address owns or is approved for `vaultID`\n function isApprovedOrOwner(address spender, uint256 vaultID) external view returns (bool) {\n return _isApprovedOrOwner(spender, vaultID);\n }\n\n /// @inheritdoc IERC721MetadataUpgradeable\n function tokenURI(uint256 vaultID) external view returns (string memory) {\n if (!_exists(vaultID)) revert NonexistentVault();\n // There is no vault with `vaultID` equal to 0, so the following variable is\n // always greater than zero\n uint256 temp = vaultID;\n uint256 digits;\n while (temp != 0) {\n ++digits;\n temp /= 10;\n }\n bytes memory buffer = new bytes(digits);\n while (vaultID != 0) {\n digits -= 1;\n buffer[digits] = bytes1(uint8(48 + uint256(vaultID % 10)));\n vaultID /= 10;\n }\n return bytes(_baseURI).length != 0 ? string(abi.encodePacked(_baseURI, string(buffer))) : \"\";\n }\n\n /// @inheritdoc IERC721Upgradeable\n function balanceOf(address owner) external view returns (uint256) {\n if (owner == address(0)) revert ZeroAddress();\n return _balances[owner];\n }\n\n /// @inheritdoc IERC721Upgradeable\n function ownerOf(uint256 vaultID) external view returns (address) {\n return _ownerOf(vaultID);\n }\n\n /// @inheritdoc IERC721Upgradeable\n function approve(address to, uint256 vaultID) external {\n address owner = _ownerOf(vaultID);\n if (to == owner) revert ApprovalToOwner();\n if (msg.sender != owner && !isApprovedForAll(owner, msg.sender)) revert NotApproved();\n\n _approve(to, vaultID);\n }\n\n /// @inheritdoc IERC721Upgradeable\n function getApproved(uint256 vaultID) external view returns (address) {\n if (!_exists(vaultID)) revert NonexistentVault();\n return _getApproved(vaultID);\n }\n\n /// @inheritdoc IERC721Upgradeable\n function setApprovalForAll(address operator, bool approved) external {\n _setApprovalForAll(msg.sender, operator, approved);\n }\n\n /// @inheritdoc IERC721Upgradeable\n function isApprovedForAll(address owner, address operator) public view returns (bool) {\n return _operatorApprovals[owner][operator] == 1;\n }\n\n /// @inheritdoc IERC721Upgradeable\n function transferFrom(address from, address to, uint256 vaultID) external onlyApprovedOrOwner(msg.sender, vaultID) {\n _transfer(from, to, vaultID);\n }\n\n /// @inheritdoc IERC721Upgradeable\n function safeTransferFrom(address from, address to, uint256 vaultID) external {\n safeTransferFrom(from, to, vaultID, \"\");\n }\n\n /// @inheritdoc IERC721Upgradeable\n function safeTransferFrom(\n address from,\n address to,\n uint256 vaultID,\n bytes memory _data\n ) public onlyApprovedOrOwner(msg.sender, vaultID) {\n _safeTransfer(from, to, vaultID, _data);\n }\n\n // ================================ ERC165 LOGIC ===============================\n\n /// @inheritdoc IERC165Upgradeable\n function supportsInterface(bytes4 interfaceId) external pure returns (bool) {\n return\n interfaceId == type(IERC721MetadataUpgradeable).interfaceId ||\n interfaceId == type(IERC721Upgradeable).interfaceId ||\n interfaceId == type(IVaultManager).interfaceId ||\n interfaceId == type(IERC165Upgradeable).interfaceId;\n }\n\n // ================== INTERNAL FUNCTIONS FOR THE ERC721 LOGIC ==================\n\n /// @notice Internal version of the `ownerOf` function\n function _ownerOf(uint256 vaultID) internal view returns (address owner) {\n owner = _owners[vaultID];\n if (owner == address(0)) revert NonexistentVault();\n }\n\n /// @notice Internal version of the `getApproved` function\n function _getApproved(uint256 vaultID) internal view returns (address) {\n return _vaultApprovals[vaultID];\n }\n\n /// @notice Internal version of the `safeTransferFrom` function (with the data parameter)\n function _safeTransfer(address from, address to, uint256 vaultID, bytes memory _data) internal {\n _transfer(from, to, vaultID);\n if (!_checkOnERC721Received(from, to, vaultID, _data)) revert NonERC721Receiver();\n }\n\n /// @notice Checks whether a vault exists\n /// @param vaultID ID of the vault to check\n /// @return Whether `vaultID` has been created\n function _exists(uint256 vaultID) internal view returns (bool) {\n return _owners[vaultID] != address(0);\n }\n\n /// @notice Internal version of the `isApprovedOrOwner` function\n function _isApprovedOrOwner(address spender, uint256 vaultID) internal view returns (bool) {\n // The following checks if the vault exists\n address owner = _ownerOf(vaultID);\n return (spender == owner || _getApproved(vaultID) == spender || _operatorApprovals[owner][spender] == 1);\n }\n\n /// @notice Internal version of the `createVault` function\n /// Mints `vaultID` and transfers it to `to`\n /// @dev This method is equivalent to the `_safeMint` method used in OpenZeppelin ERC721 contract\n /// @dev Emits a {Transfer} event\n function _mint(address to) internal returns (uint256 vaultID) {\n if (to == address(0)) revert ZeroAddress();\n\n unchecked {\n vaultIDCount += 1;\n }\n\n vaultID = vaultIDCount;\n _beforeTokenTransfer(address(0), to, vaultID);\n\n unchecked {\n _balances[to] += 1;\n }\n\n _owners[vaultID] = to;\n emit Transfer(address(0), to, vaultID);\n if (!_checkOnERC721Received(address(0), to, vaultID, \"\")) revert NonERC721Receiver();\n }\n\n /// @notice Destroys `vaultID`\n /// @dev `vaultID` must exist\n /// @dev Emits a {Transfer} event\n function _burn(uint256 vaultID) internal {\n address owner = _ownerOf(vaultID);\n\n _beforeTokenTransfer(owner, address(0), vaultID);\n // Clear approvals\n _approve(address(0), vaultID);\n // The following line cannot underflow as the owner's balance is necessarily\n // greater than 1\n unchecked {\n _balances[owner] -= 1;\n }\n delete _owners[vaultID];\n delete vaultData[vaultID];\n\n emit Transfer(owner, address(0), vaultID);\n }\n\n /// @notice Transfers `vaultID` from `from` to `to` as opposed to {transferFrom},\n /// this imposes no restrictions on msg.sender\n /// @dev `to` cannot be the zero address and `perpetualID` must be owned by `from`\n /// @dev Emits a {Transfer} event\n function _transfer(address from, address to, uint256 vaultID) internal {\n if (_ownerOf(vaultID) != from) revert NotApproved();\n if (to == address(0)) revert ZeroAddress();\n\n _beforeTokenTransfer(from, to, vaultID);\n\n // Clear approvals from the previous owner\n _approve(address(0), vaultID);\n unchecked {\n _balances[from] -= 1;\n _balances[to] += 1;\n }\n _owners[vaultID] = to;\n\n emit Transfer(from, to, vaultID);\n }\n\n /// @notice Approves `to` to operate on `vaultID`\n function _approve(address to, uint256 vaultID) internal {\n _vaultApprovals[vaultID] = to;\n emit Approval(_ownerOf(vaultID), to, vaultID);\n }\n\n /// @notice Internal version of the `setApprovalForAll` function\n /// @dev It contains an `approver` field to be used in case someone signs a permit for a particular\n /// address, and this signature is given to the contract by another address (like a router)\n function _setApprovalForAll(address approver, address operator, bool approved) internal {\n if (operator == approver) revert ApprovalToCaller();\n uint256 approval = approved ? 1 : 0;\n _operatorApprovals[approver][operator] = approval;\n emit ApprovalForAll(approver, operator, approved);\n }\n\n /// @notice Internal function to invoke {IERC721Receiver-onERC721Received} on a target address\n /// The call is not executed if the target address is not a contract\n /// @param from Address representing the previous owner of the given token ID\n /// @param to Target address that will receive the tokens\n /// @param vaultID ID of the token to be transferred\n /// @param _data Bytes optional data to send along with the call\n /// @return Bool whether the call correctly returned the expected value\n function _checkOnERC721Received(\n address from,\n address to,\n uint256 vaultID,\n bytes memory _data\n ) private returns (bool) {\n if (to.isContract()) {\n try IERC721ReceiverUpgradeable(to).onERC721Received(msg.sender, from, vaultID, _data) returns (\n bytes4 retval\n ) {\n return retval == IERC721ReceiverUpgradeable.onERC721Received.selector;\n } catch (bytes memory reason) {\n if (reason.length == 0) {\n revert NonERC721Receiver();\n } else {\n // solhint-disable-next-line no-inline-assembly\n assembly {\n revert(add(32, reason), mload(reason))\n }\n }\n }\n } else {\n return true;\n }\n }\n\n /// @notice Hook that is called before any token transfer. This includes minting and burning.\n /// Calling conditions:\n ///\n /// - When `from` and `to` are both non-zero, `from`'s `vaultID` will be\n /// transferred to `to`.\n /// - When `from` is zero, `vaultID` will be minted for `to`.\n /// - When `to` is zero, `from`'s `vaultID` will be burned.\n /// - `from` and `to` are never both zero.\n function _beforeTokenTransfer(address from, address to, uint256 vaultID) internal virtual {}\n\n /// @notice Get `whitelistingActivated` in storage only if needed\n function _whitelistingActivated() internal view virtual returns (bool) {\n return whitelistingActivated;\n }\n}\n" + }, + "contracts/vaultManager/VaultManagerPermit.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\nimport \"./VaultManagerERC721.sol\";\nimport \"../interfaces/external/IERC1271.sol\";\n\n/// @title VaultManagerPermit\n/// @author Angle Labs, Inc.\n/// @dev Base Implementation of permit functions for the `VaultManager` contract\nabstract contract VaultManagerPermit is Initializable, VaultManagerERC721 {\n using Address for address;\n\n mapping(address => uint256) private _nonces;\n /* solhint-disable var-name-mixedcase */\n bytes32 private _HASHED_NAME;\n bytes32 private _HASHED_VERSION;\n bytes32 private _PERMIT_TYPEHASH;\n /* solhint-enable var-name-mixedcase */\n\n error ExpiredDeadline();\n error InvalidSignature();\n\n //solhint-disable-next-line\n function __ERC721Permit_init(string memory _name) internal onlyInitializing {\n _PERMIT_TYPEHASH = keccak256(\n \"Permit(address owner,address spender,bool approved,uint256 nonce,uint256 deadline)\"\n );\n _HASHED_NAME = keccak256(bytes(_name));\n _HASHED_VERSION = keccak256(bytes(\"1\"));\n }\n\n /// @notice Allows an address to give or revoke approval for all its vaults to another address\n /// @param owner Address signing the permit and giving (or revoking) its approval for all the controlled vaults\n /// @param spender Address to give approval to\n /// @param approved Whether to give or revoke the approval\n /// @param deadline Deadline parameter for the signature to be valid\n /// @dev The `v`, `r`, and `s` parameters are used as signature data\n function permit(\n address owner,\n address spender,\n bool approved,\n uint256 deadline,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) external {\n if (block.timestamp > deadline) revert ExpiredDeadline();\n // Additional signature checks performed in the `ECDSAUpgradeable.recover` function\n if (uint256(s) > 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D576E7357A4501DDFE92F46681B20A0 || (v != 27 && v != 28))\n revert InvalidSignature();\n\n bytes32 digest = keccak256(\n abi.encodePacked(\n \"\\x19\\x01\",\n _domainSeparatorV4(),\n keccak256(\n abi.encode(\n _PERMIT_TYPEHASH,\n // 0x3f43a9c6bafb5c7aab4e0cfe239dc5d4c15caf0381c6104188191f78a6640bd8,\n owner,\n spender,\n approved,\n _useNonce(owner),\n deadline\n )\n )\n )\n );\n if (owner.isContract()) {\n if (IERC1271(owner).isValidSignature(digest, abi.encodePacked(r, s, v)) != 0x1626ba7e)\n revert InvalidSignature();\n } else {\n address signer = ecrecover(digest, v, r, s);\n if (signer != owner || signer == address(0)) revert InvalidSignature();\n }\n\n _setApprovalForAll(owner, spender, approved);\n }\n\n /// @notice Returns the current nonce for an `owner` address\n function nonces(address owner) public view returns (uint256) {\n return _nonces[owner];\n }\n\n /// @notice Returns the domain separator for the current chain.\n // solhint-disable-next-line func-name-mixedcase\n function DOMAIN_SEPARATOR() external view returns (bytes32) {\n return _domainSeparatorV4();\n }\n\n /// @notice Internal version of the `DOMAIN_SEPARATOR` function\n function _domainSeparatorV4() internal view returns (bytes32) {\n return\n keccak256(\n abi.encode(\n // keccak256('EIP712Domain(string name,string version,uint256 chainId,address verifyingContract)')\n 0x8b73c3c69bb8fe3d512ecc4cf759cc79239f7b179b0ffacaa9a75d522b39400f,\n _HASHED_NAME,\n _HASHED_VERSION,\n block.chainid,\n address(this)\n )\n );\n }\n\n /// @notice Consumes a nonce for an address: returns the current value and increments it\n function _useNonce(address owner) internal returns (uint256 current) {\n current = _nonces[owner];\n _nonces[owner] = current + 1;\n }\n\n uint256[49] private __gap;\n}\n" + }, + "contracts/vaultManager/VaultManagerStorage.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\nimport \"@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/token/ERC20/extensions/draft-IERC20PermitUpgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/token/ERC721/IERC721ReceiverUpgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/interfaces/IERC721MetadataUpgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/utils/introspection/IERC165Upgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/utils/AddressUpgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/security/ReentrancyGuardUpgradeable.sol\";\nimport \"@openzeppelin/contracts/token/ERC20/extensions/IERC20Metadata.sol\";\nimport \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\nimport \"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\";\n\nimport \"../interfaces/IAgToken.sol\";\nimport \"../interfaces/IOracle.sol\";\nimport \"../interfaces/ISwapper.sol\";\nimport \"../interfaces/ITreasury.sol\";\nimport \"../interfaces/IVaultManager.sol\";\nimport \"../interfaces/governance/IVeBoostProxy.sol\";\n\n/// @title VaultManagerStorage\n/// @author Angle Labs, Inc.\n/// @dev Variables, references, parameters and events needed in the `VaultManager` contract\n// solhint-disable-next-line max-states-count\ncontract VaultManagerStorage is IVaultManagerStorage, Initializable, ReentrancyGuardUpgradeable {\n /// @notice Base used for parameter computation: almost all the parameters of this contract are set in `BASE_PARAMS`\n uint256 public constant BASE_PARAMS = 10 ** 9;\n /// @notice Base used for interest rate computation\n uint256 public constant BASE_INTEREST = 10 ** 27;\n /// @notice Used for interest rate computation\n uint256 public constant HALF_BASE_INTEREST = 10 ** 27 / 2;\n\n // ================================= REFERENCES ================================\n\n /// @inheritdoc IVaultManagerStorage\n ITreasury public treasury;\n /// @inheritdoc IVaultManagerStorage\n IERC20 public collateral;\n /// @inheritdoc IVaultManagerStorage\n IAgToken public stablecoin;\n /// @inheritdoc IVaultManagerStorage\n IOracle public oracle;\n /// @notice Reference to the contract which computes adjusted veANGLE balances for liquidators boosts\n IVeBoostProxy public veBoostProxy;\n /// @notice Base of the collateral\n uint256 internal _collatBase;\n\n // ================================= PARAMETERS ================================\n // Unless specified otherwise, parameters of this contract are expressed in `BASE_PARAMS`\n\n /// @notice Maximum amount of stablecoins that can be issued with this contract (in `BASE_TOKENS`). This parameter should\n /// not be bigger than `type(uint256).max / BASE_INTEREST` otherwise there may be some overflows in the `increaseDebt` function\n uint256 public debtCeiling;\n /// @notice Threshold veANGLE balance values for the computation of the boost for liquidators: the length of this array\n /// should normally be 2. The base of the x-values in this array should be `BASE_TOKENS`\n uint256[] public xLiquidationBoost;\n /// @notice Values of the liquidation boost at the threshold values of x\n uint256[] public yLiquidationBoost;\n /// @inheritdoc IVaultManagerStorage\n uint64 public collateralFactor;\n /// @notice Maximum Health factor at which a vault can end up after a liquidation (unless it's fully liquidated)\n uint64 public targetHealthFactor;\n /// @notice Upfront fee taken when borrowing stablecoins: this fee is optional and should in practice not be used\n uint64 public borrowFee;\n /// @notice Upfront fee taken when repaying stablecoins: this fee is optional as well. It should be smaller\n /// than the liquidation surcharge (cf below) to avoid exploits where people voluntarily get liquidated at a 0\n /// discount to pay smaller repaying fees\n uint64 public repayFee;\n /// @notice Per second interest taken to borrowers taking agToken loans. Contrarily to other parameters, it is set in `BASE_INTEREST`\n /// that is to say in base 10**27\n uint64 public interestRate;\n /// @notice Fee taken by the protocol during a liquidation. Technically, this value is not the fee per se, it's 1 - fee.\n /// For instance for a 2% fee, `liquidationSurcharge` should be 98%\n uint64 public liquidationSurcharge;\n /// @notice Maximum discount given to liquidators\n uint64 public maxLiquidationDiscount;\n /// @notice Whether whitelisting is required to own a vault or not\n bool public whitelistingActivated;\n /// @notice Whether the contract is paused or not\n bool public paused;\n\n // ================================= VARIABLES =================================\n\n /// @notice Timestamp at which the `interestAccumulator` was updated\n uint256 public lastInterestAccumulatorUpdated;\n /// @inheritdoc IVaultManagerStorage\n uint256 public interestAccumulator;\n /// @inheritdoc IVaultManagerStorage\n uint256 public totalNormalizedDebt;\n /// @notice Surplus accumulated by the contract: surplus is always in stablecoins, and is then reset\n /// when the value is communicated to the treasury contract\n uint256 public surplus;\n /// @notice Bad debt made from liquidated vaults which ended up having no collateral and a positive amount\n /// of stablecoins\n uint256 public badDebt;\n\n // ================================== MAPPINGS =================================\n\n /// @inheritdoc IVaultManagerStorage\n mapping(uint256 => Vault) public vaultData;\n /// @notice Maps an address to 1 if it's whitelisted and can open or own a vault\n mapping(address => uint256) public isWhitelisted;\n\n // ================================ ERC721 DATA ================================\n\n /// @inheritdoc IVaultManagerStorage\n uint256 public vaultIDCount;\n\n /// @notice URI\n string internal _baseURI;\n\n // Mapping from `vaultID` to owner address\n mapping(uint256 => address) internal _owners;\n\n // Mapping from owner address to vault owned count\n mapping(address => uint256) internal _balances;\n\n // Mapping from `vaultID` to approved address\n mapping(uint256 => address) internal _vaultApprovals;\n\n // Mapping from owner to operator approvals\n mapping(address => mapping(address => uint256)) internal _operatorApprovals;\n\n uint256[50] private __gap;\n\n // =================================== EVENTS ==================================\n\n event AccruedToTreasury(uint256 surplusEndValue, uint256 badDebtEndValue);\n event CollateralAmountUpdated(uint256 vaultID, uint256 collateralAmount, uint8 isIncrease);\n event InterestAccumulatorUpdated(uint256 value, uint256 timestamp);\n event InternalDebtUpdated(uint256 vaultID, uint256 internalAmount, uint8 isIncrease);\n event FiledUint64(uint64 param, bytes32 what);\n event DebtCeilingUpdated(uint256 debtCeiling);\n event LiquidationBoostParametersUpdated(address indexed _veBoostProxy, uint256[] xBoost, uint256[] yBoost);\n event LiquidatedVaults(uint256[] vaultIDs);\n event DebtTransferred(uint256 srcVaultID, uint256 dstVaultID, address dstVaultManager, uint256 amount);\n\n // =================================== ERRORS ==================================\n\n error ApprovalToOwner();\n error ApprovalToCaller();\n error DustyLeftoverAmount();\n error DebtCeilingExceeded();\n error HealthyVault();\n error IncompatibleLengths();\n error InsolventVault();\n error InvalidParameterValue();\n error InvalidParameterType();\n error InvalidSetOfParameters();\n error InvalidTreasury();\n error NonERC721Receiver();\n error NonexistentVault();\n error NotApproved();\n error NotGovernor();\n error NotGovernorOrGuardian();\n error NotTreasury();\n error NotWhitelisted();\n error NotVaultManager();\n error Paused();\n error TooHighParameterValue();\n error TooSmallParameterValue();\n error ZeroAddress();\n\n /// @custom:oz-upgrades-unsafe-allow constructor\n constructor() initializer {}\n}\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 1000000 + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers", + "metadata", + "devdoc", + "userdoc", + "storageLayout", + "evm.gasEstimates", + "devdoc", + "userdoc" + ], + "": [ + "ast" + ] + } + }, + "metadata": { + "useLiteralContent": true + } + } +} \ No newline at end of file diff --git a/deployments/polygonzkevm/AgTokenSideChainMultiBridge_Implementation.json b/deployments/polygonzkevm/AgTokenSideChainMultiBridge_Implementation.json index 8e7afd61..6a51dda4 100644 --- a/deployments/polygonzkevm/AgTokenSideChainMultiBridge_Implementation.json +++ b/deployments/polygonzkevm/AgTokenSideChainMultiBridge_Implementation.json @@ -1,5 +1,5 @@ { - "address": "0x5adDc89785D75C86aB939E9e15bfBBb7Fc086A87", + "address": "0xe1e6D7370Fb8eA42CC9169d18571579C67141eeA", "abi": [ { "inputs": [], @@ -1211,44 +1211,44 @@ "type": "function" } ], - "transactionHash": "0x0a4b000ae00e8e2ff8bf206aaf328812eb410bca7dfe1d2011a6b73c45f12983", + "transactionHash": "0x985620d0857d4b8f4c8d6615107db60a56559d4107bf984fe2c4ad5d152c0c10", "receipt": { "to": null, "from": "0xfdA462548Ce04282f4B6D6619823a7C64Fdc0185", - "contractAddress": "0x5adDc89785D75C86aB939E9e15bfBBb7Fc086A87", + "contractAddress": "0xe1e6D7370Fb8eA42CC9169d18571579C67141eeA", "transactionIndex": 0, - "gasUsed": "3970824", - "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000080000000000000000000000000000000000000000000000000000000000000000000000000080000000000000000000000000000000000000000000000400000008000000000000000000000000000000000000000000000000010000040000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", - "blockHash": "0xe4a2d18825c51cdafe4b2b1f61afc40d112b6423a9501c185008dd4728621fd0", - "transactionHash": "0x0a4b000ae00e8e2ff8bf206aaf328812eb410bca7dfe1d2011a6b73c45f12983", + "gasUsed": "3964995", + "logsBloom": "0x00000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000080000000000000000004000000000000000000001000000400000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "blockHash": "0xa55008ed9e0687f593ddfbd492c411c772c52fb9cf9e05533f7d2c522b182e1d", + "transactionHash": "0x985620d0857d4b8f4c8d6615107db60a56559d4107bf984fe2c4ad5d152c0c10", "logs": [ { "transactionIndex": 0, - "blockNumber": 1412728, - "transactionHash": "0x0a4b000ae00e8e2ff8bf206aaf328812eb410bca7dfe1d2011a6b73c45f12983", - "address": "0x5adDc89785D75C86aB939E9e15bfBBb7Fc086A87", + "blockNumber": 9134284, + "transactionHash": "0x985620d0857d4b8f4c8d6615107db60a56559d4107bf984fe2c4ad5d152c0c10", + "address": "0xe1e6D7370Fb8eA42CC9169d18571579C67141eeA", "topics": [ "0x7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb3847402498" ], "data": "0x0000000000000000000000000000000000000000000000000000000000000001", "logIndex": 0, - "blockHash": "0xe4a2d18825c51cdafe4b2b1f61afc40d112b6423a9501c185008dd4728621fd0" + "blockHash": "0xa55008ed9e0687f593ddfbd492c411c772c52fb9cf9e05533f7d2c522b182e1d" } ], - "blockNumber": 1412728, - "cumulativeGasUsed": "3970824", + "blockNumber": 9134284, + "cumulativeGasUsed": "3964995", "status": 1, "byzantium": true }, "args": [], - "numDeployments": 1, - "solcInputHash": "24b1610c184975567a57199ee00015c7", - "metadata": "{\"compiler\":{\"version\":\"0.8.17+commit.8df45f5f\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[],\"name\":\"AssetStillControlledInReserves\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"BurnAmountExceedsAllowance\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"HourlyLimitExceeded\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidSender\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidToken\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidTreasury\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"NotGovernor\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"NotGovernorOrGuardian\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"NotMinter\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"NotTreasury\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"TooBigAmount\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"TooHighParameterValue\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ZeroAddress\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"spender\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"}],\"name\":\"Approval\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"bridgeToken\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"limit\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"hourlyLimit\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"fee\",\"type\":\"uint64\"},{\"indexed\":false,\"internalType\":\"bool\",\"name\":\"paused\",\"type\":\"bool\"}],\"name\":\"BridgeTokenAdded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"bridgeToken\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"fee\",\"type\":\"uint64\"}],\"name\":\"BridgeTokenFeeUpdated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"bridgeToken\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"hourlyLimit\",\"type\":\"uint256\"}],\"name\":\"BridgeTokenHourlyLimitUpdated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"bridgeToken\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"limit\",\"type\":\"uint256\"}],\"name\":\"BridgeTokenLimitUpdated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"bridgeToken\",\"type\":\"address\"}],\"name\":\"BridgeTokenRemoved\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"bridgeToken\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"bool\",\"name\":\"toggleStatus\",\"type\":\"bool\"}],\"name\":\"BridgeTokenToggled\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"theAddress\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"toggleStatus\",\"type\":\"uint256\"}],\"name\":\"FeeToggled\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"hourlyLimit\",\"type\":\"uint256\"}],\"name\":\"HourlyLimitUpdated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint8\",\"name\":\"version\",\"type\":\"uint8\"}],\"name\":\"Initialized\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"minter\",\"type\":\"address\"}],\"name\":\"MinterToggled\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"Recovered\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"}],\"name\":\"Transfer\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"_treasury\",\"type\":\"address\"}],\"name\":\"TreasuryUpdated\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"BASE_PARAMS\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"DOMAIN_SEPARATOR\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"bridgeToken\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"limit\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"hourlyLimit\",\"type\":\"uint256\"},{\"internalType\":\"uint64\",\"name\":\"fee\",\"type\":\"uint64\"},{\"internalType\":\"bool\",\"name\":\"paused\",\"type\":\"bool\"}],\"name\":\"addBridgeToken\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"minter\",\"type\":\"address\"}],\"name\":\"addMinter\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"allBridgeTokens\",\"outputs\":[{\"internalType\":\"address[]\",\"name\":\"\",\"type\":\"address[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"spender\",\"type\":\"address\"}],\"name\":\"allowance\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"spender\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"approve\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"}],\"name\":\"balanceOf\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"name\":\"bridgeTokensList\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"bridges\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"limit\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"hourlyLimit\",\"type\":\"uint256\"},{\"internalType\":\"uint64\",\"name\":\"fee\",\"type\":\"uint64\"},{\"internalType\":\"bool\",\"name\":\"allowed\",\"type\":\"bool\"},{\"internalType\":\"bool\",\"name\":\"paused\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"burner\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"}],\"name\":\"burnFrom\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"burner\",\"type\":\"address\"}],\"name\":\"burnSelf\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"burnStablecoin\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"chainTotalHourlyLimit\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"name\":\"chainTotalUsage\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"currentTotalUsage\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"bridgeToken\",\"type\":\"address\"}],\"name\":\"currentUsage\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"decimals\",\"outputs\":[{\"internalType\":\"uint8\",\"name\":\"\",\"type\":\"uint8\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"spender\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"subtractedValue\",\"type\":\"uint256\"}],\"name\":\"decreaseAllowance\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"spender\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"addedValue\",\"type\":\"uint256\"}],\"name\":\"increaseAllowance\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"string\",\"name\":\"name_\",\"type\":\"string\"},{\"internalType\":\"string\",\"name\":\"symbol_\",\"type\":\"string\"},{\"internalType\":\"address\",\"name\":\"_treasury\",\"type\":\"address\"}],\"name\":\"initialize\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"isFeeExempt\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"isMinter\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"mint\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"name\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"}],\"name\":\"nonces\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"spender\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"deadline\",\"type\":\"uint256\"},{\"internalType\":\"uint8\",\"name\":\"v\",\"type\":\"uint8\"},{\"internalType\":\"bytes32\",\"name\":\"r\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32\",\"name\":\"s\",\"type\":\"bytes32\"}],\"name\":\"permit\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"tokenAddress\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amountToRecover\",\"type\":\"uint256\"}],\"name\":\"recoverERC20\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"bridgeToken\",\"type\":\"address\"}],\"name\":\"removeBridgeToken\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"minter\",\"type\":\"address\"}],\"name\":\"removeMinter\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"hourlyLimit\",\"type\":\"uint256\"}],\"name\":\"setChainTotalHourlyLimit\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"bridgeToken\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"hourlyLimit\",\"type\":\"uint256\"}],\"name\":\"setHourlyLimit\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"bridgeToken\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"limit\",\"type\":\"uint256\"}],\"name\":\"setLimit\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"bridgeToken\",\"type\":\"address\"},{\"internalType\":\"uint64\",\"name\":\"fee\",\"type\":\"uint64\"}],\"name\":\"setSwapFee\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_treasury\",\"type\":\"address\"}],\"name\":\"setTreasury\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"bridgeToken\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"swapIn\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"bridgeToken\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"swapOut\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"symbol\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"bridgeToken\",\"type\":\"address\"}],\"name\":\"toggleBridge\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"theAddress\",\"type\":\"address\"}],\"name\":\"toggleFeesForAddress\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"totalSupply\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"transfer\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"transferFrom\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"treasury\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"name\":\"usage\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"}],\"devdoc\":{\"author\":\"Angle Labs, Inc.\",\"details\":\"This contract supports bridge tokens having a minting right on the stablecoin (also referred to as the canonical or the native token)References: - FRAX implementation: https://polygonscan.com/address/0x45c32fA6DF82ead1e2EF74d17b76547EDdFaFF89#code - QiDAO implementation: https://snowtrace.io/address/0x5c49b268c9841AFF1Cc3B0a418ff5c3442eE3F3b#code\",\"kind\":\"dev\",\"methods\":{\"DOMAIN_SEPARATOR()\":{\"details\":\"See {IERC20Permit-DOMAIN_SEPARATOR}.\"},\"addBridgeToken(address,uint256,uint256,uint64,bool)\":{\"params\":{\"bridgeToken\":\"Bridge token to add: it should be a version of the stablecoin from another bridge\",\"fee\":\"Fee taken upon swapping for or against this token\",\"hourlyLimit\":\"Limit on the hourly volume for this bridge\",\"limit\":\"Limit on the balance of bridge token this contract could hold\",\"paused\":\"Whether swapping for this token should be paused or not\"}},\"addMinter(address)\":{\"details\":\"Zero address checks are performed directly in the `Treasury` contract\",\"params\":{\"minter\":\"Minter address to add\"}},\"allBridgeTokens()\":{\"details\":\"Helpful for UIs\"},\"allowance(address,address)\":{\"details\":\"See {IERC20-allowance}.\"},\"approve(address,uint256)\":{\"details\":\"See {IERC20-approve}. NOTE: If `amount` is the maximum `uint256`, the allowance is not updated on `transferFrom`. This is semantically equivalent to an infinite approval. Requirements: - `spender` cannot be the zero address.\"},\"balanceOf(address)\":{\"details\":\"See {IERC20-balanceOf}.\"},\"burnFrom(uint256,address,address)\":{\"details\":\"This method is to be called by a contract with the minter right after being requested to do so by a `sender` address willing to burn tokens from another `burner` addressThe method checks the allowance between the `sender` and the `burner`\",\"params\":{\"amount\":\"Amount of tokens to burn\",\"burner\":\"Address to burn from\",\"sender\":\"Address which requested the burn from `burner`\"}},\"burnSelf(uint256,address)\":{\"details\":\"This method is to be called by a contract with a minter right on the AgToken after being requested to do so by an address willing to burn tokens from its address\",\"params\":{\"amount\":\"Amount of tokens to burn\",\"burner\":\"Address to burn from\"}},\"burnStablecoin(uint256)\":{\"details\":\"This function can typically be called if there is a settlement mechanism to burn stablecoins\",\"params\":{\"amount\":\"Amount of stablecoins to burn\"}},\"currentTotalUsage()\":{\"details\":\"Helpful for UIs\"},\"currentUsage(address)\":{\"details\":\"Helpful for UIs\",\"params\":{\"bridgeToken\":\"Bridge used to mint\"}},\"decimals()\":{\"details\":\"Returns the number of decimals used to get its user representation. For example, if `decimals` equals `2`, a balance of `505` tokens should be displayed to a user as `5.05` (`505 / 10 ** 2`). Tokens usually opt for a value of 18, imitating the relationship between Ether and Wei. This is the value {ERC20} uses, unless this function is overridden; NOTE: This information is only used for _display_ purposes: it in no way affects any of the arithmetic of the contract, including {IERC20-balanceOf} and {IERC20-transfer}.\"},\"decreaseAllowance(address,uint256)\":{\"details\":\"Atomically decreases the allowance granted to `spender` by the caller. This is an alternative to {approve} that can be used as a mitigation for problems described in {IERC20-approve}. Emits an {Approval} event indicating the updated allowance. Requirements: - `spender` cannot be the zero address. - `spender` must have allowance for the caller of at least `subtractedValue`.\"},\"increaseAllowance(address,uint256)\":{\"details\":\"Atomically increases the allowance granted to `spender` by the caller. This is an alternative to {approve} that can be used as a mitigation for problems described in {IERC20-approve}. Emits an {Approval} event indicating the updated allowance. Requirements: - `spender` cannot be the zero address.\"},\"initialize(string,string,address)\":{\"details\":\"By default, agTokens are ERC-20 tokens with 18 decimals\",\"params\":{\"_treasury\":\"Reference to the `Treasury` contract associated to this agToken\",\"name_\":\"Name of the token\",\"symbol_\":\"Symbol of the token\"}},\"mint(address,uint256)\":{\"details\":\"The contracts allowed to issue agTokens are the `StableMaster` contract, `VaultManager` contracts associated to this stablecoin as well as the flash loan module (if activated) and potentially contracts whitelisted by governance\",\"params\":{\"account\":\"Address to mint to\",\"amount\":\"Amount to mint\"}},\"name()\":{\"details\":\"Returns the name of the token.\"},\"nonces(address)\":{\"details\":\"See {IERC20Permit-nonces}.\"},\"permit(address,address,uint256,uint256,uint8,bytes32,bytes32)\":{\"details\":\"See {IERC20Permit-permit}.\"},\"recoverERC20(address,address,uint256)\":{\"details\":\"Can be used to withdraw bridge tokens for them to be de-bridged on mainnet\"},\"removeBridgeToken(address)\":{\"params\":{\"bridgeToken\":\"Address of the bridge token to remove support for\"}},\"removeMinter(address)\":{\"details\":\"This function can also be called by a minter wishing to revoke itself\",\"params\":{\"minter\":\"Minter address to remove\"}},\"setTreasury(address)\":{\"params\":{\"_treasury\":\"New treasury address\"}},\"swapIn(address,uint256,address)\":{\"details\":\"Some fees may be taken by the protocol depending on the token used and on the address calling\",\"params\":{\"amount\":\"Amount of bridge tokens to send\",\"bridgeToken\":\"Bridge token to use to mint\",\"to\":\"Address to which the stablecoin should be sent\"},\"returns\":{\"_0\":\"Amount of the canonical stablecoin actually minted\"}},\"swapOut(address,uint256,address)\":{\"details\":\"Some fees may be taken by the protocol depending on the token used and on the address calling\",\"params\":{\"amount\":\"Amount of canonical tokens to burn\",\"bridgeToken\":\"Bridge token required\",\"to\":\"Address to which the bridge token should be sent\"},\"returns\":{\"_0\":\"Amount of bridge tokens actually sent back\"}},\"symbol()\":{\"details\":\"Returns the symbol of the token, usually a shorter version of the name.\"},\"totalSupply()\":{\"details\":\"See {IERC20-totalSupply}.\"},\"transfer(address,uint256)\":{\"details\":\"See {IERC20-transfer}. Requirements: - `to` cannot be the zero address. - the caller must have a balance of at least `amount`.\"},\"transferFrom(address,address,uint256)\":{\"details\":\"See {IERC20-transferFrom}. Emits an {Approval} event indicating the updated allowance. This is not required by the EIP. See the note at the beginning of {ERC20}. NOTE: Does not update the allowance if the current allowance is the maximum `uint256`. Requirements: - `from` and `to` cannot be the zero address. - `from` must have a balance of at least `amount`. - the caller must have allowance for ``from``'s tokens of at least `amount`.\"}},\"title\":\"AgTokenSideChainMultiBridge\",\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{\"BASE_PARAMS()\":{\"notice\":\"Base used for fee computation\"},\"addBridgeToken(address,uint256,uint256,uint64,bool)\":{\"notice\":\"Adds support for a bridge token\"},\"addMinter(address)\":{\"notice\":\"Adds a minter in the contract\"},\"allBridgeTokens()\":{\"notice\":\"Returns the list of all supported bridge tokens\"},\"bridgeTokensList(uint256)\":{\"notice\":\"List of all bridge tokens\"},\"bridges(address)\":{\"notice\":\"Maps a bridge token to data\"},\"burnFrom(uint256,address,address)\":{\"notice\":\"Burns `amount` tokens from a `burner` address after being asked to by `sender`\"},\"burnSelf(uint256,address)\":{\"notice\":\"Burns `amount` tokens from a `burner` address\"},\"burnStablecoin(uint256)\":{\"notice\":\"Allows anyone to burn agToken without redeeming collateral back\"},\"chainTotalHourlyLimit()\":{\"notice\":\"Limit to the amount of tokens that can be sent from that chain to another chain\"},\"chainTotalUsage(uint256)\":{\"notice\":\"Usage per hour on that chain. Maps an hourly timestamp to the total volume swapped out on the chain\"},\"currentTotalUsage()\":{\"notice\":\"Returns the current total volume on the chain for the current hour\"},\"currentUsage(address)\":{\"notice\":\"Returns the current volume for a bridge, for the current hour\"},\"initialize(string,string,address)\":{\"notice\":\"Initializes the `AgToken` contract\"},\"isFeeExempt(address)\":{\"notice\":\"Maps an address to whether it is exempt of fees for when it comes to swapping in and out\"},\"isMinter(address)\":{\"notice\":\"Checks whether an address has the right to mint agTokens\"},\"mint(address,uint256)\":{\"notice\":\"Lets the `StableMaster` contract or another whitelisted contract mint agTokens\"},\"recoverERC20(address,address,uint256)\":{\"notice\":\"Recovers any ERC20 token\"},\"removeBridgeToken(address)\":{\"notice\":\"Removes support for a token\"},\"removeMinter(address)\":{\"notice\":\"Removes a minter from the contract\"},\"setChainTotalHourlyLimit(uint256)\":{\"notice\":\"Updates the `chainTotalHourlyLimit` amount\"},\"setHourlyLimit(address,uint256)\":{\"notice\":\"Updates the `hourlyLimit` amount for `bridgeToken`\"},\"setLimit(address,uint256)\":{\"notice\":\"Updates the `limit` amount for `bridgeToken`\"},\"setSwapFee(address,uint64)\":{\"notice\":\"Updates the `fee` value for `bridgeToken`\"},\"setTreasury(address)\":{\"notice\":\"Sets a new treasury contract\"},\"swapIn(address,uint256,address)\":{\"notice\":\"Mints the canonical token from a supported bridge token\"},\"swapOut(address,uint256,address)\":{\"notice\":\"Burns the canonical token in exchange for a bridge token\"},\"toggleBridge(address)\":{\"notice\":\"Pauses or unpauses swapping in and out for a token\"},\"toggleFeesForAddress(address)\":{\"notice\":\"Toggles fees for the address `theAddress`\"},\"treasury()\":{\"notice\":\"Reference to the treasury contract which can grant minting rights\"},\"usage(address,uint256)\":{\"notice\":\"Maps a bridge token to the associated hourly volume\"}},\"notice\":\"Contract for Angle agTokens on other chains than Ethereum mainnet\",\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/agToken/AgTokenSideChainMultiBridge.sol\":\"AgTokenSideChainMultiBridge\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":1000000},\"remappings\":[]},\"sources\":{\"@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.7.0) (proxy/utils/Initializable.sol)\\n\\npragma solidity ^0.8.2;\\n\\nimport \\\"../../utils/AddressUpgradeable.sol\\\";\\n\\n/**\\n * @dev This is a base contract to aid in writing upgradeable contracts, or any kind of contract that will be deployed\\n * behind a proxy. Since proxied contracts do not make use of a constructor, it's common to move constructor logic to an\\n * external initializer function, usually called `initialize`. It then becomes necessary to protect this initializer\\n * function so it can only be called once. The {initializer} modifier provided by this contract will have this effect.\\n *\\n * The initialization functions use a version number. Once a version number is used, it is consumed and cannot be\\n * reused. This mechanism prevents re-execution of each \\\"step\\\" but allows the creation of new initialization steps in\\n * case an upgrade adds a module that needs to be initialized.\\n *\\n * For example:\\n *\\n * [.hljs-theme-light.nopadding]\\n * ```\\n * contract MyToken is ERC20Upgradeable {\\n * function initialize() initializer public {\\n * __ERC20_init(\\\"MyToken\\\", \\\"MTK\\\");\\n * }\\n * }\\n * contract MyTokenV2 is MyToken, ERC20PermitUpgradeable {\\n * function initializeV2() reinitializer(2) public {\\n * __ERC20Permit_init(\\\"MyToken\\\");\\n * }\\n * }\\n * ```\\n *\\n * TIP: To avoid leaving the proxy in an uninitialized state, the initializer function should be called as early as\\n * possible by providing the encoded function call as the `_data` argument to {ERC1967Proxy-constructor}.\\n *\\n * CAUTION: When used with inheritance, manual care must be taken to not invoke a parent initializer twice, or to ensure\\n * that all initializers are idempotent. This is not verified automatically as constructors are by Solidity.\\n *\\n * [CAUTION]\\n * ====\\n * Avoid leaving a contract uninitialized.\\n *\\n * An uninitialized contract can be taken over by an attacker. This applies to both a proxy and its implementation\\n * contract, which may impact the proxy. To prevent the implementation contract from being used, you should invoke\\n * the {_disableInitializers} function in the constructor to automatically lock it when it is deployed:\\n *\\n * [.hljs-theme-light.nopadding]\\n * ```\\n * /// @custom:oz-upgrades-unsafe-allow constructor\\n * constructor() {\\n * _disableInitializers();\\n * }\\n * ```\\n * ====\\n */\\nabstract contract Initializable {\\n /**\\n * @dev Indicates that the contract has been initialized.\\n * @custom:oz-retyped-from bool\\n */\\n uint8 private _initialized;\\n\\n /**\\n * @dev Indicates that the contract is in the process of being initialized.\\n */\\n bool private _initializing;\\n\\n /**\\n * @dev Triggered when the contract has been initialized or reinitialized.\\n */\\n event Initialized(uint8 version);\\n\\n /**\\n * @dev A modifier that defines a protected initializer function that can be invoked at most once. In its scope,\\n * `onlyInitializing` functions can be used to initialize parent contracts. Equivalent to `reinitializer(1)`.\\n */\\n modifier initializer() {\\n bool isTopLevelCall = !_initializing;\\n require(\\n (isTopLevelCall && _initialized < 1) || (!AddressUpgradeable.isContract(address(this)) && _initialized == 1),\\n \\\"Initializable: contract is already initialized\\\"\\n );\\n _initialized = 1;\\n if (isTopLevelCall) {\\n _initializing = true;\\n }\\n _;\\n if (isTopLevelCall) {\\n _initializing = false;\\n emit Initialized(1);\\n }\\n }\\n\\n /**\\n * @dev A modifier that defines a protected reinitializer function that can be invoked at most once, and only if the\\n * contract hasn't been initialized to a greater version before. In its scope, `onlyInitializing` functions can be\\n * used to initialize parent contracts.\\n *\\n * `initializer` is equivalent to `reinitializer(1)`, so a reinitializer may be used after the original\\n * initialization step. This is essential to configure modules that are added through upgrades and that require\\n * initialization.\\n *\\n * Note that versions can jump in increments greater than 1; this implies that if multiple reinitializers coexist in\\n * a contract, executing them in the right order is up to the developer or operator.\\n */\\n modifier reinitializer(uint8 version) {\\n require(!_initializing && _initialized < version, \\\"Initializable: contract is already initialized\\\");\\n _initialized = version;\\n _initializing = true;\\n _;\\n _initializing = false;\\n emit Initialized(version);\\n }\\n\\n /**\\n * @dev Modifier to protect an initialization function so that it can only be invoked by functions with the\\n * {initializer} and {reinitializer} modifiers, directly or indirectly.\\n */\\n modifier onlyInitializing() {\\n require(_initializing, \\\"Initializable: contract is not initializing\\\");\\n _;\\n }\\n\\n /**\\n * @dev Locks the contract, preventing any future reinitialization. This cannot be part of an initializer call.\\n * Calling this in the constructor of a contract will prevent that contract from being initialized or reinitialized\\n * to any version. It is recommended to use this to lock implementation contracts that are designed to be called\\n * through proxies.\\n */\\n function _disableInitializers() internal virtual {\\n require(!_initializing, \\\"Initializable: contract is initializing\\\");\\n if (_initialized < type(uint8).max) {\\n _initialized = type(uint8).max;\\n emit Initialized(type(uint8).max);\\n }\\n }\\n}\\n\",\"keccak256\":\"0x0203dcadc5737d9ef2c211d6fa15d18ebc3b30dfa51903b64870b01a062b0b4e\",\"license\":\"MIT\"},\"@openzeppelin/contracts-upgradeable/token/ERC20/ERC20Upgradeable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.7.0) (token/ERC20/ERC20.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"./IERC20Upgradeable.sol\\\";\\nimport \\\"./extensions/IERC20MetadataUpgradeable.sol\\\";\\nimport \\\"../../utils/ContextUpgradeable.sol\\\";\\nimport \\\"../../proxy/utils/Initializable.sol\\\";\\n\\n/**\\n * @dev Implementation of the {IERC20} interface.\\n *\\n * This implementation is agnostic to the way tokens are created. This means\\n * that a supply mechanism has to be added in a derived contract using {_mint}.\\n * For a generic mechanism see {ERC20PresetMinterPauser}.\\n *\\n * TIP: For a detailed writeup see our guide\\n * https://forum.zeppelin.solutions/t/how-to-implement-erc20-supply-mechanisms/226[How\\n * to implement supply mechanisms].\\n *\\n * We have followed general OpenZeppelin Contracts guidelines: functions revert\\n * instead returning `false` on failure. This behavior is nonetheless\\n * conventional and does not conflict with the expectations of ERC20\\n * applications.\\n *\\n * Additionally, an {Approval} event is emitted on calls to {transferFrom}.\\n * This allows applications to reconstruct the allowance for all accounts just\\n * by listening to said events. Other implementations of the EIP may not emit\\n * these events, as it isn't required by the specification.\\n *\\n * Finally, the non-standard {decreaseAllowance} and {increaseAllowance}\\n * functions have been added to mitigate the well-known issues around setting\\n * allowances. See {IERC20-approve}.\\n */\\ncontract ERC20Upgradeable is Initializable, ContextUpgradeable, IERC20Upgradeable, IERC20MetadataUpgradeable {\\n mapping(address => uint256) private _balances;\\n\\n mapping(address => mapping(address => uint256)) private _allowances;\\n\\n uint256 private _totalSupply;\\n\\n string private _name;\\n string private _symbol;\\n\\n /**\\n * @dev Sets the values for {name} and {symbol}.\\n *\\n * The default value of {decimals} is 18. To select a different value for\\n * {decimals} you should overload it.\\n *\\n * All two of these values are immutable: they can only be set once during\\n * construction.\\n */\\n function __ERC20_init(string memory name_, string memory symbol_) internal onlyInitializing {\\n __ERC20_init_unchained(name_, symbol_);\\n }\\n\\n function __ERC20_init_unchained(string memory name_, string memory symbol_) internal onlyInitializing {\\n _name = name_;\\n _symbol = symbol_;\\n }\\n\\n /**\\n * @dev Returns the name of the token.\\n */\\n function name() public view virtual override returns (string memory) {\\n return _name;\\n }\\n\\n /**\\n * @dev Returns the symbol of the token, usually a shorter version of the\\n * name.\\n */\\n function symbol() public view virtual override returns (string memory) {\\n return _symbol;\\n }\\n\\n /**\\n * @dev Returns the number of decimals used to get its user representation.\\n * For example, if `decimals` equals `2`, a balance of `505` tokens should\\n * be displayed to a user as `5.05` (`505 / 10 ** 2`).\\n *\\n * Tokens usually opt for a value of 18, imitating the relationship between\\n * Ether and Wei. This is the value {ERC20} uses, unless this function is\\n * overridden;\\n *\\n * NOTE: This information is only used for _display_ purposes: it in\\n * no way affects any of the arithmetic of the contract, including\\n * {IERC20-balanceOf} and {IERC20-transfer}.\\n */\\n function decimals() public view virtual override returns (uint8) {\\n return 18;\\n }\\n\\n /**\\n * @dev See {IERC20-totalSupply}.\\n */\\n function totalSupply() public view virtual override returns (uint256) {\\n return _totalSupply;\\n }\\n\\n /**\\n * @dev See {IERC20-balanceOf}.\\n */\\n function balanceOf(address account) public view virtual override returns (uint256) {\\n return _balances[account];\\n }\\n\\n /**\\n * @dev See {IERC20-transfer}.\\n *\\n * Requirements:\\n *\\n * - `to` cannot be the zero address.\\n * - the caller must have a balance of at least `amount`.\\n */\\n function transfer(address to, uint256 amount) public virtual override returns (bool) {\\n address owner = _msgSender();\\n _transfer(owner, to, amount);\\n return true;\\n }\\n\\n /**\\n * @dev See {IERC20-allowance}.\\n */\\n function allowance(address owner, address spender) public view virtual override returns (uint256) {\\n return _allowances[owner][spender];\\n }\\n\\n /**\\n * @dev See {IERC20-approve}.\\n *\\n * NOTE: If `amount` is the maximum `uint256`, the allowance is not updated on\\n * `transferFrom`. This is semantically equivalent to an infinite approval.\\n *\\n * Requirements:\\n *\\n * - `spender` cannot be the zero address.\\n */\\n function approve(address spender, uint256 amount) public virtual override returns (bool) {\\n address owner = _msgSender();\\n _approve(owner, spender, amount);\\n return true;\\n }\\n\\n /**\\n * @dev See {IERC20-transferFrom}.\\n *\\n * Emits an {Approval} event indicating the updated allowance. This is not\\n * required by the EIP. See the note at the beginning of {ERC20}.\\n *\\n * NOTE: Does not update the allowance if the current allowance\\n * is the maximum `uint256`.\\n *\\n * Requirements:\\n *\\n * - `from` and `to` cannot be the zero address.\\n * - `from` must have a balance of at least `amount`.\\n * - the caller must have allowance for ``from``'s tokens of at least\\n * `amount`.\\n */\\n function transferFrom(\\n address from,\\n address to,\\n uint256 amount\\n ) public virtual override returns (bool) {\\n address spender = _msgSender();\\n _spendAllowance(from, spender, amount);\\n _transfer(from, to, amount);\\n return true;\\n }\\n\\n /**\\n * @dev Atomically increases the allowance granted to `spender` by the caller.\\n *\\n * This is an alternative to {approve} that can be used as a mitigation for\\n * problems described in {IERC20-approve}.\\n *\\n * Emits an {Approval} event indicating the updated allowance.\\n *\\n * Requirements:\\n *\\n * - `spender` cannot be the zero address.\\n */\\n function increaseAllowance(address spender, uint256 addedValue) public virtual returns (bool) {\\n address owner = _msgSender();\\n _approve(owner, spender, allowance(owner, spender) + addedValue);\\n return true;\\n }\\n\\n /**\\n * @dev Atomically decreases the allowance granted to `spender` by the caller.\\n *\\n * This is an alternative to {approve} that can be used as a mitigation for\\n * problems described in {IERC20-approve}.\\n *\\n * Emits an {Approval} event indicating the updated allowance.\\n *\\n * Requirements:\\n *\\n * - `spender` cannot be the zero address.\\n * - `spender` must have allowance for the caller of at least\\n * `subtractedValue`.\\n */\\n function decreaseAllowance(address spender, uint256 subtractedValue) public virtual returns (bool) {\\n address owner = _msgSender();\\n uint256 currentAllowance = allowance(owner, spender);\\n require(currentAllowance >= subtractedValue, \\\"ERC20: decreased allowance below zero\\\");\\n unchecked {\\n _approve(owner, spender, currentAllowance - subtractedValue);\\n }\\n\\n return true;\\n }\\n\\n /**\\n * @dev Moves `amount` of tokens from `from` to `to`.\\n *\\n * This internal function is equivalent to {transfer}, and can be used to\\n * e.g. implement automatic token fees, slashing mechanisms, etc.\\n *\\n * Emits a {Transfer} event.\\n *\\n * Requirements:\\n *\\n * - `from` cannot be the zero address.\\n * - `to` cannot be the zero address.\\n * - `from` must have a balance of at least `amount`.\\n */\\n function _transfer(\\n address from,\\n address to,\\n uint256 amount\\n ) internal virtual {\\n require(from != address(0), \\\"ERC20: transfer from the zero address\\\");\\n require(to != address(0), \\\"ERC20: transfer to the zero address\\\");\\n\\n _beforeTokenTransfer(from, to, amount);\\n\\n uint256 fromBalance = _balances[from];\\n require(fromBalance >= amount, \\\"ERC20: transfer amount exceeds balance\\\");\\n unchecked {\\n _balances[from] = fromBalance - amount;\\n }\\n _balances[to] += amount;\\n\\n emit Transfer(from, to, amount);\\n\\n _afterTokenTransfer(from, to, amount);\\n }\\n\\n /** @dev Creates `amount` tokens and assigns them to `account`, increasing\\n * the total supply.\\n *\\n * Emits a {Transfer} event with `from` set to the zero address.\\n *\\n * Requirements:\\n *\\n * - `account` cannot be the zero address.\\n */\\n function _mint(address account, uint256 amount) internal virtual {\\n require(account != address(0), \\\"ERC20: mint to the zero address\\\");\\n\\n _beforeTokenTransfer(address(0), account, amount);\\n\\n _totalSupply += amount;\\n _balances[account] += amount;\\n emit Transfer(address(0), account, amount);\\n\\n _afterTokenTransfer(address(0), account, amount);\\n }\\n\\n /**\\n * @dev Destroys `amount` tokens from `account`, reducing the\\n * total supply.\\n *\\n * Emits a {Transfer} event with `to` set to the zero address.\\n *\\n * Requirements:\\n *\\n * - `account` cannot be the zero address.\\n * - `account` must have at least `amount` tokens.\\n */\\n function _burn(address account, uint256 amount) internal virtual {\\n require(account != address(0), \\\"ERC20: burn from the zero address\\\");\\n\\n _beforeTokenTransfer(account, address(0), amount);\\n\\n uint256 accountBalance = _balances[account];\\n require(accountBalance >= amount, \\\"ERC20: burn amount exceeds balance\\\");\\n unchecked {\\n _balances[account] = accountBalance - amount;\\n }\\n _totalSupply -= amount;\\n\\n emit Transfer(account, address(0), amount);\\n\\n _afterTokenTransfer(account, address(0), amount);\\n }\\n\\n /**\\n * @dev Sets `amount` as the allowance of `spender` over the `owner` s tokens.\\n *\\n * This internal function is equivalent to `approve`, and can be used to\\n * e.g. set automatic allowances for certain subsystems, etc.\\n *\\n * Emits an {Approval} event.\\n *\\n * Requirements:\\n *\\n * - `owner` cannot be the zero address.\\n * - `spender` cannot be the zero address.\\n */\\n function _approve(\\n address owner,\\n address spender,\\n uint256 amount\\n ) internal virtual {\\n require(owner != address(0), \\\"ERC20: approve from the zero address\\\");\\n require(spender != address(0), \\\"ERC20: approve to the zero address\\\");\\n\\n _allowances[owner][spender] = amount;\\n emit Approval(owner, spender, amount);\\n }\\n\\n /**\\n * @dev Updates `owner` s allowance for `spender` based on spent `amount`.\\n *\\n * Does not update the allowance amount in case of infinite allowance.\\n * Revert if not enough allowance is available.\\n *\\n * Might emit an {Approval} event.\\n */\\n function _spendAllowance(\\n address owner,\\n address spender,\\n uint256 amount\\n ) internal virtual {\\n uint256 currentAllowance = allowance(owner, spender);\\n if (currentAllowance != type(uint256).max) {\\n require(currentAllowance >= amount, \\\"ERC20: insufficient allowance\\\");\\n unchecked {\\n _approve(owner, spender, currentAllowance - amount);\\n }\\n }\\n }\\n\\n /**\\n * @dev Hook that is called before any transfer of tokens. This includes\\n * minting and burning.\\n *\\n * Calling conditions:\\n *\\n * - when `from` and `to` are both non-zero, `amount` of ``from``'s tokens\\n * will be transferred to `to`.\\n * - when `from` is zero, `amount` tokens will be minted for `to`.\\n * - when `to` is zero, `amount` of ``from``'s tokens will be burned.\\n * - `from` and `to` are never both zero.\\n *\\n * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].\\n */\\n function _beforeTokenTransfer(\\n address from,\\n address to,\\n uint256 amount\\n ) internal virtual {}\\n\\n /**\\n * @dev Hook that is called after any transfer of tokens. This includes\\n * minting and burning.\\n *\\n * Calling conditions:\\n *\\n * - when `from` and `to` are both non-zero, `amount` of ``from``'s tokens\\n * has been transferred to `to`.\\n * - when `from` is zero, `amount` tokens have been minted for `to`.\\n * - when `to` is zero, `amount` of ``from``'s tokens have been burned.\\n * - `from` and `to` are never both zero.\\n *\\n * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].\\n */\\n function _afterTokenTransfer(\\n address from,\\n address to,\\n uint256 amount\\n ) internal virtual {}\\n\\n /**\\n * @dev This empty reserved space is put in place to allow future versions to add new\\n * variables without shifting down storage in the inheritance chain.\\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\\n */\\n uint256[45] private __gap;\\n}\\n\",\"keccak256\":\"0x7c7ac0bc6c340a7f320524b9a4b4b079ee9da3c51258080d4bab237f329a427c\",\"license\":\"MIT\"},\"@openzeppelin/contracts-upgradeable/token/ERC20/IERC20Upgradeable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.6.0) (token/ERC20/IERC20.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Interface of the ERC20 standard as defined in the EIP.\\n */\\ninterface IERC20Upgradeable {\\n /**\\n * @dev Emitted when `value` tokens are moved from one account (`from`) to\\n * another (`to`).\\n *\\n * Note that `value` may be zero.\\n */\\n event Transfer(address indexed from, address indexed to, uint256 value);\\n\\n /**\\n * @dev Emitted when the allowance of a `spender` for an `owner` is set by\\n * a call to {approve}. `value` is the new allowance.\\n */\\n event Approval(address indexed owner, address indexed spender, uint256 value);\\n\\n /**\\n * @dev Returns the amount of tokens in existence.\\n */\\n function totalSupply() external view returns (uint256);\\n\\n /**\\n * @dev Returns the amount of tokens owned by `account`.\\n */\\n function balanceOf(address account) external view returns (uint256);\\n\\n /**\\n * @dev Moves `amount` tokens from the caller's account to `to`.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * Emits a {Transfer} event.\\n */\\n function transfer(address to, uint256 amount) external returns (bool);\\n\\n /**\\n * @dev Returns the remaining number of tokens that `spender` will be\\n * allowed to spend on behalf of `owner` through {transferFrom}. This is\\n * zero by default.\\n *\\n * This value changes when {approve} or {transferFrom} are called.\\n */\\n function allowance(address owner, address spender) external view returns (uint256);\\n\\n /**\\n * @dev Sets `amount` as the allowance of `spender` over the caller's tokens.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * IMPORTANT: Beware that changing an allowance with this method brings the risk\\n * that someone may use both the old and the new allowance by unfortunate\\n * transaction ordering. One possible solution to mitigate this race\\n * condition is to first reduce the spender's allowance to 0 and set the\\n * desired value afterwards:\\n * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729\\n *\\n * Emits an {Approval} event.\\n */\\n function approve(address spender, uint256 amount) external returns (bool);\\n\\n /**\\n * @dev Moves `amount` tokens from `from` to `to` using the\\n * allowance mechanism. `amount` is then deducted from the caller's\\n * allowance.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * Emits a {Transfer} event.\\n */\\n function transferFrom(\\n address from,\\n address to,\\n uint256 amount\\n ) external returns (bool);\\n}\\n\",\"keccak256\":\"0x4e733d3164f73f461eaf9d8087a7ad1ea180bdc8ba0d3d61b0e1ae16d8e63dff\",\"license\":\"MIT\"},\"@openzeppelin/contracts-upgradeable/token/ERC20/extensions/IERC20MetadataUpgradeable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (token/ERC20/extensions/IERC20Metadata.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../IERC20Upgradeable.sol\\\";\\n\\n/**\\n * @dev Interface for the optional metadata functions from the ERC20 standard.\\n *\\n * _Available since v4.1._\\n */\\ninterface IERC20MetadataUpgradeable is IERC20Upgradeable {\\n /**\\n * @dev Returns the name of the token.\\n */\\n function name() external view returns (string memory);\\n\\n /**\\n * @dev Returns the symbol of the token.\\n */\\n function symbol() external view returns (string memory);\\n\\n /**\\n * @dev Returns the decimals places of the token.\\n */\\n function decimals() external view returns (uint8);\\n}\\n\",\"keccak256\":\"0x605434219ebbe4653f703640f06969faa5a1d78f0bfef878e5ddbb1ca369ceeb\",\"license\":\"MIT\"},\"@openzeppelin/contracts-upgradeable/token/ERC20/extensions/draft-ERC20PermitUpgradeable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.6.0) (token/ERC20/extensions/draft-ERC20Permit.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"./draft-IERC20PermitUpgradeable.sol\\\";\\nimport \\\"../ERC20Upgradeable.sol\\\";\\nimport \\\"../../../utils/cryptography/draft-EIP712Upgradeable.sol\\\";\\nimport \\\"../../../utils/cryptography/ECDSAUpgradeable.sol\\\";\\nimport \\\"../../../utils/CountersUpgradeable.sol\\\";\\nimport \\\"../../../proxy/utils/Initializable.sol\\\";\\n\\n/**\\n * @dev Implementation of the ERC20 Permit extension allowing approvals to be made via signatures, as defined in\\n * https://eips.ethereum.org/EIPS/eip-2612[EIP-2612].\\n *\\n * Adds the {permit} method, which can be used to change an account's ERC20 allowance (see {IERC20-allowance}) by\\n * presenting a message signed by the account. By not relying on `{IERC20-approve}`, the token holder account doesn't\\n * need to send a transaction, and thus is not required to hold Ether at all.\\n *\\n * _Available since v3.4._\\n *\\n * @custom:storage-size 51\\n */\\nabstract contract ERC20PermitUpgradeable is Initializable, ERC20Upgradeable, IERC20PermitUpgradeable, EIP712Upgradeable {\\n using CountersUpgradeable for CountersUpgradeable.Counter;\\n\\n mapping(address => CountersUpgradeable.Counter) private _nonces;\\n\\n // solhint-disable-next-line var-name-mixedcase\\n bytes32 private constant _PERMIT_TYPEHASH =\\n keccak256(\\\"Permit(address owner,address spender,uint256 value,uint256 nonce,uint256 deadline)\\\");\\n /**\\n * @dev In previous versions `_PERMIT_TYPEHASH` was declared as `immutable`.\\n * However, to ensure consistency with the upgradeable transpiler, we will continue\\n * to reserve a slot.\\n * @custom:oz-renamed-from _PERMIT_TYPEHASH\\n */\\n // solhint-disable-next-line var-name-mixedcase\\n bytes32 private _PERMIT_TYPEHASH_DEPRECATED_SLOT;\\n\\n /**\\n * @dev Initializes the {EIP712} domain separator using the `name` parameter, and setting `version` to `\\\"1\\\"`.\\n *\\n * It's a good idea to use the same `name` that is defined as the ERC20 token name.\\n */\\n function __ERC20Permit_init(string memory name) internal onlyInitializing {\\n __EIP712_init_unchained(name, \\\"1\\\");\\n }\\n\\n function __ERC20Permit_init_unchained(string memory) internal onlyInitializing {}\\n\\n /**\\n * @dev See {IERC20Permit-permit}.\\n */\\n function permit(\\n address owner,\\n address spender,\\n uint256 value,\\n uint256 deadline,\\n uint8 v,\\n bytes32 r,\\n bytes32 s\\n ) public virtual override {\\n require(block.timestamp <= deadline, \\\"ERC20Permit: expired deadline\\\");\\n\\n bytes32 structHash = keccak256(abi.encode(_PERMIT_TYPEHASH, owner, spender, value, _useNonce(owner), deadline));\\n\\n bytes32 hash = _hashTypedDataV4(structHash);\\n\\n address signer = ECDSAUpgradeable.recover(hash, v, r, s);\\n require(signer == owner, \\\"ERC20Permit: invalid signature\\\");\\n\\n _approve(owner, spender, value);\\n }\\n\\n /**\\n * @dev See {IERC20Permit-nonces}.\\n */\\n function nonces(address owner) public view virtual override returns (uint256) {\\n return _nonces[owner].current();\\n }\\n\\n /**\\n * @dev See {IERC20Permit-DOMAIN_SEPARATOR}.\\n */\\n // solhint-disable-next-line func-name-mixedcase\\n function DOMAIN_SEPARATOR() external view override returns (bytes32) {\\n return _domainSeparatorV4();\\n }\\n\\n /**\\n * @dev \\\"Consume a nonce\\\": return the current value and increment.\\n *\\n * _Available since v4.1._\\n */\\n function _useNonce(address owner) internal virtual returns (uint256 current) {\\n CountersUpgradeable.Counter storage nonce = _nonces[owner];\\n current = nonce.current();\\n nonce.increment();\\n }\\n\\n /**\\n * @dev This empty reserved space is put in place to allow future versions to add new\\n * variables without shifting down storage in the inheritance chain.\\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\\n */\\n uint256[49] private __gap;\\n}\\n\",\"keccak256\":\"0x564385ebed633694decce3e13d687f3ac7e8eaef64f7a504bfb3f03ad210601f\",\"license\":\"MIT\"},\"@openzeppelin/contracts-upgradeable/token/ERC20/extensions/draft-IERC20PermitUpgradeable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (token/ERC20/extensions/draft-IERC20Permit.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Interface of the ERC20 Permit extension allowing approvals to be made via signatures, as defined in\\n * https://eips.ethereum.org/EIPS/eip-2612[EIP-2612].\\n *\\n * Adds the {permit} method, which can be used to change an account's ERC20 allowance (see {IERC20-allowance}) by\\n * presenting a message signed by the account. By not relying on {IERC20-approve}, the token holder account doesn't\\n * need to send a transaction, and thus is not required to hold Ether at all.\\n */\\ninterface IERC20PermitUpgradeable {\\n /**\\n * @dev Sets `value` as the allowance of `spender` over ``owner``'s tokens,\\n * given ``owner``'s signed approval.\\n *\\n * IMPORTANT: The same issues {IERC20-approve} has related to transaction\\n * ordering also apply here.\\n *\\n * Emits an {Approval} event.\\n *\\n * Requirements:\\n *\\n * - `spender` cannot be the zero address.\\n * - `deadline` must be a timestamp in the future.\\n * - `v`, `r` and `s` must be a valid `secp256k1` signature from `owner`\\n * over the EIP712-formatted function arguments.\\n * - the signature must use ``owner``'s current nonce (see {nonces}).\\n *\\n * For more information on the signature format, see the\\n * https://eips.ethereum.org/EIPS/eip-2612#specification[relevant EIP\\n * section].\\n */\\n function permit(\\n address owner,\\n address spender,\\n uint256 value,\\n uint256 deadline,\\n uint8 v,\\n bytes32 r,\\n bytes32 s\\n ) external;\\n\\n /**\\n * @dev Returns the current nonce for `owner`. This value must be\\n * included whenever a signature is generated for {permit}.\\n *\\n * Every successful call to {permit} increases ``owner``'s nonce by one. This\\n * prevents a signature from being used multiple times.\\n */\\n function nonces(address owner) external view returns (uint256);\\n\\n /**\\n * @dev Returns the domain separator used in the encoding of the signature for {permit}, as defined by {EIP712}.\\n */\\n // solhint-disable-next-line func-name-mixedcase\\n function DOMAIN_SEPARATOR() external view returns (bytes32);\\n}\\n\",\"keccak256\":\"0xcc70d8e2281fb3ff69e8ab242500f10142cd0a7fa8dd9e45882be270d4d09024\",\"license\":\"MIT\"},\"@openzeppelin/contracts-upgradeable/utils/AddressUpgradeable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.7.0) (utils/Address.sol)\\n\\npragma solidity ^0.8.1;\\n\\n/**\\n * @dev Collection of functions related to the address type\\n */\\nlibrary AddressUpgradeable {\\n /**\\n * @dev Returns true if `account` is a contract.\\n *\\n * [IMPORTANT]\\n * ====\\n * It is unsafe to assume that an address for which this function returns\\n * false is an externally-owned account (EOA) and not a contract.\\n *\\n * Among others, `isContract` will return false for the following\\n * types of addresses:\\n *\\n * - an externally-owned account\\n * - a contract in construction\\n * - an address where a contract will be created\\n * - an address where a contract lived, but was destroyed\\n * ====\\n *\\n * [IMPORTANT]\\n * ====\\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\\n *\\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\\n * constructor.\\n * ====\\n */\\n function isContract(address account) internal view returns (bool) {\\n // This method relies on extcodesize/address.code.length, which returns 0\\n // for contracts in construction, since the code is only stored at the end\\n // of the constructor execution.\\n\\n return account.code.length > 0;\\n }\\n\\n /**\\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\\n * `recipient`, forwarding all available gas and reverting on errors.\\n *\\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\\n * imposed by `transfer`, making them unable to receive funds via\\n * `transfer`. {sendValue} removes this limitation.\\n *\\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\\n *\\n * IMPORTANT: because control is transferred to `recipient`, care must be\\n * taken to not create reentrancy vulnerabilities. Consider using\\n * {ReentrancyGuard} or the\\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\\n */\\n function sendValue(address payable recipient, uint256 amount) internal {\\n require(address(this).balance >= amount, \\\"Address: insufficient balance\\\");\\n\\n (bool success, ) = recipient.call{value: amount}(\\\"\\\");\\n require(success, \\\"Address: unable to send value, recipient may have reverted\\\");\\n }\\n\\n /**\\n * @dev Performs a Solidity function call using a low level `call`. A\\n * plain `call` is an unsafe replacement for a function call: use this\\n * function instead.\\n *\\n * If `target` reverts with a revert reason, it is bubbled up by this\\n * function (like regular Solidity function calls).\\n *\\n * Returns the raw returned data. To convert to the expected return value,\\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\\n *\\n * Requirements:\\n *\\n * - `target` must be a contract.\\n * - calling `target` with `data` must not revert.\\n *\\n * _Available since v3.1._\\n */\\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\\n return functionCall(target, data, \\\"Address: low-level call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\\n * `errorMessage` as a fallback revert reason when `target` reverts.\\n *\\n * _Available since v3.1._\\n */\\n function functionCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n return functionCallWithValue(target, data, 0, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but also transferring `value` wei to `target`.\\n *\\n * Requirements:\\n *\\n * - the calling contract must have an ETH balance of at least `value`.\\n * - the called Solidity function must be `payable`.\\n *\\n * _Available since v3.1._\\n */\\n function functionCallWithValue(\\n address target,\\n bytes memory data,\\n uint256 value\\n ) internal returns (bytes memory) {\\n return functionCallWithValue(target, data, value, \\\"Address: low-level call with value failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\\n * with `errorMessage` as a fallback revert reason when `target` reverts.\\n *\\n * _Available since v3.1._\\n */\\n function functionCallWithValue(\\n address target,\\n bytes memory data,\\n uint256 value,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n require(address(this).balance >= value, \\\"Address: insufficient balance for call\\\");\\n require(isContract(target), \\\"Address: call to non-contract\\\");\\n\\n (bool success, bytes memory returndata) = target.call{value: value}(data);\\n return verifyCallResult(success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but performing a static call.\\n *\\n * _Available since v3.3._\\n */\\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\\n return functionStaticCall(target, data, \\\"Address: low-level static call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\\n * but performing a static call.\\n *\\n * _Available since v3.3._\\n */\\n function functionStaticCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal view returns (bytes memory) {\\n require(isContract(target), \\\"Address: static call to non-contract\\\");\\n\\n (bool success, bytes memory returndata) = target.staticcall(data);\\n return verifyCallResult(success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the\\n * revert reason using the provided one.\\n *\\n * _Available since v4.3._\\n */\\n function verifyCallResult(\\n bool success,\\n bytes memory returndata,\\n string memory errorMessage\\n ) internal pure returns (bytes memory) {\\n if (success) {\\n return returndata;\\n } else {\\n // Look for revert reason and bubble it up if present\\n if (returndata.length > 0) {\\n // The easiest way to bubble the revert reason is using memory via assembly\\n /// @solidity memory-safe-assembly\\n assembly {\\n let returndata_size := mload(returndata)\\n revert(add(32, returndata), returndata_size)\\n }\\n } else {\\n revert(errorMessage);\\n }\\n }\\n }\\n}\\n\",\"keccak256\":\"0x611aa3f23e59cfdd1863c536776407b3e33d695152a266fa7cfb34440a29a8a3\",\"license\":\"MIT\"},\"@openzeppelin/contracts-upgradeable/utils/ContextUpgradeable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)\\n\\npragma solidity ^0.8.0;\\nimport \\\"../proxy/utils/Initializable.sol\\\";\\n\\n/**\\n * @dev Provides information about the current execution context, including the\\n * sender of the transaction and its data. While these are generally available\\n * via msg.sender and msg.data, they should not be accessed in such a direct\\n * manner, since when dealing with meta-transactions the account sending and\\n * paying for execution may not be the actual sender (as far as an application\\n * is concerned).\\n *\\n * This contract is only required for intermediate, library-like contracts.\\n */\\nabstract contract ContextUpgradeable is Initializable {\\n function __Context_init() internal onlyInitializing {\\n }\\n\\n function __Context_init_unchained() internal onlyInitializing {\\n }\\n function _msgSender() internal view virtual returns (address) {\\n return msg.sender;\\n }\\n\\n function _msgData() internal view virtual returns (bytes calldata) {\\n return msg.data;\\n }\\n\\n /**\\n * @dev This empty reserved space is put in place to allow future versions to add new\\n * variables without shifting down storage in the inheritance chain.\\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\\n */\\n uint256[50] private __gap;\\n}\\n\",\"keccak256\":\"0x963ea7f0b48b032eef72fe3a7582edf78408d6f834115b9feadd673a4d5bd149\",\"license\":\"MIT\"},\"@openzeppelin/contracts-upgradeable/utils/CountersUpgradeable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (utils/Counters.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @title Counters\\n * @author Matt Condon (@shrugs)\\n * @dev Provides counters that can only be incremented, decremented or reset. This can be used e.g. to track the number\\n * of elements in a mapping, issuing ERC721 ids, or counting request ids.\\n *\\n * Include with `using Counters for Counters.Counter;`\\n */\\nlibrary CountersUpgradeable {\\n struct Counter {\\n // This variable should never be directly accessed by users of the library: interactions must be restricted to\\n // the library's function. As of Solidity v0.5.2, this cannot be enforced, though there is a proposal to add\\n // this feature: see https://github.com/ethereum/solidity/issues/4637\\n uint256 _value; // default: 0\\n }\\n\\n function current(Counter storage counter) internal view returns (uint256) {\\n return counter._value;\\n }\\n\\n function increment(Counter storage counter) internal {\\n unchecked {\\n counter._value += 1;\\n }\\n }\\n\\n function decrement(Counter storage counter) internal {\\n uint256 value = counter._value;\\n require(value > 0, \\\"Counter: decrement overflow\\\");\\n unchecked {\\n counter._value = value - 1;\\n }\\n }\\n\\n function reset(Counter storage counter) internal {\\n counter._value = 0;\\n }\\n}\\n\",\"keccak256\":\"0x798741e231b22b81e2dd2eddaaf8832dee4baf5cd8e2dbaa5c1dd12a1c053c4d\",\"license\":\"MIT\"},\"@openzeppelin/contracts-upgradeable/utils/StringsUpgradeable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.7.0) (utils/Strings.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev String operations.\\n */\\nlibrary StringsUpgradeable {\\n bytes16 private constant _HEX_SYMBOLS = \\\"0123456789abcdef\\\";\\n uint8 private constant _ADDRESS_LENGTH = 20;\\n\\n /**\\n * @dev Converts a `uint256` to its ASCII `string` decimal representation.\\n */\\n function toString(uint256 value) internal pure returns (string memory) {\\n // Inspired by OraclizeAPI's implementation - MIT licence\\n // https://github.com/oraclize/ethereum-api/blob/b42146b063c7d6ee1358846c198246239e9360e8/oraclizeAPI_0.4.25.sol\\n\\n if (value == 0) {\\n return \\\"0\\\";\\n }\\n uint256 temp = value;\\n uint256 digits;\\n while (temp != 0) {\\n digits++;\\n temp /= 10;\\n }\\n bytes memory buffer = new bytes(digits);\\n while (value != 0) {\\n digits -= 1;\\n buffer[digits] = bytes1(uint8(48 + uint256(value % 10)));\\n value /= 10;\\n }\\n return string(buffer);\\n }\\n\\n /**\\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation.\\n */\\n function toHexString(uint256 value) internal pure returns (string memory) {\\n if (value == 0) {\\n return \\\"0x00\\\";\\n }\\n uint256 temp = value;\\n uint256 length = 0;\\n while (temp != 0) {\\n length++;\\n temp >>= 8;\\n }\\n return toHexString(value, length);\\n }\\n\\n /**\\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length.\\n */\\n function toHexString(uint256 value, uint256 length) internal pure returns (string memory) {\\n bytes memory buffer = new bytes(2 * length + 2);\\n buffer[0] = \\\"0\\\";\\n buffer[1] = \\\"x\\\";\\n for (uint256 i = 2 * length + 1; i > 1; --i) {\\n buffer[i] = _HEX_SYMBOLS[value & 0xf];\\n value >>= 4;\\n }\\n require(value == 0, \\\"Strings: hex length insufficient\\\");\\n return string(buffer);\\n }\\n\\n /**\\n * @dev Converts an `address` with fixed length of 20 bytes to its not checksummed ASCII `string` hexadecimal representation.\\n */\\n function toHexString(address addr) internal pure returns (string memory) {\\n return toHexString(uint256(uint160(addr)), _ADDRESS_LENGTH);\\n }\\n}\\n\",\"keccak256\":\"0xea5339a7fff0ed42b45be56a88efdd0b2ddde9fa480dc99fef9a6a4c5b776863\",\"license\":\"MIT\"},\"@openzeppelin/contracts-upgradeable/utils/cryptography/ECDSAUpgradeable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.7.0) (utils/cryptography/ECDSA.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../StringsUpgradeable.sol\\\";\\n\\n/**\\n * @dev Elliptic Curve Digital Signature Algorithm (ECDSA) operations.\\n *\\n * These functions can be used to verify that a message was signed by the holder\\n * of the private keys of a given address.\\n */\\nlibrary ECDSAUpgradeable {\\n enum RecoverError {\\n NoError,\\n InvalidSignature,\\n InvalidSignatureLength,\\n InvalidSignatureS,\\n InvalidSignatureV\\n }\\n\\n function _throwError(RecoverError error) private pure {\\n if (error == RecoverError.NoError) {\\n return; // no error: do nothing\\n } else if (error == RecoverError.InvalidSignature) {\\n revert(\\\"ECDSA: invalid signature\\\");\\n } else if (error == RecoverError.InvalidSignatureLength) {\\n revert(\\\"ECDSA: invalid signature length\\\");\\n } else if (error == RecoverError.InvalidSignatureS) {\\n revert(\\\"ECDSA: invalid signature 's' value\\\");\\n } else if (error == RecoverError.InvalidSignatureV) {\\n revert(\\\"ECDSA: invalid signature 'v' value\\\");\\n }\\n }\\n\\n /**\\n * @dev Returns the address that signed a hashed message (`hash`) with\\n * `signature` or error string. This address can then be used for verification purposes.\\n *\\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\\n * this function rejects them by requiring the `s` value to be in the lower\\n * half order, and the `v` value to be either 27 or 28.\\n *\\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\\n * verification to be secure: it is possible to craft signatures that\\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\\n * this is by receiving a hash of the original message (which may otherwise\\n * be too long), and then calling {toEthSignedMessageHash} on it.\\n *\\n * Documentation for signature generation:\\n * - with https://web3js.readthedocs.io/en/v1.3.4/web3-eth-accounts.html#sign[Web3.js]\\n * - with https://docs.ethers.io/v5/api/signer/#Signer-signMessage[ethers]\\n *\\n * _Available since v4.3._\\n */\\n function tryRecover(bytes32 hash, bytes memory signature) internal pure returns (address, RecoverError) {\\n // Check the signature length\\n // - case 65: r,s,v signature (standard)\\n // - case 64: r,vs signature (cf https://eips.ethereum.org/EIPS/eip-2098) _Available since v4.1._\\n if (signature.length == 65) {\\n bytes32 r;\\n bytes32 s;\\n uint8 v;\\n // ecrecover takes the signature parameters, and the only way to get them\\n // currently is to use assembly.\\n /// @solidity memory-safe-assembly\\n assembly {\\n r := mload(add(signature, 0x20))\\n s := mload(add(signature, 0x40))\\n v := byte(0, mload(add(signature, 0x60)))\\n }\\n return tryRecover(hash, v, r, s);\\n } else if (signature.length == 64) {\\n bytes32 r;\\n bytes32 vs;\\n // ecrecover takes the signature parameters, and the only way to get them\\n // currently is to use assembly.\\n /// @solidity memory-safe-assembly\\n assembly {\\n r := mload(add(signature, 0x20))\\n vs := mload(add(signature, 0x40))\\n }\\n return tryRecover(hash, r, vs);\\n } else {\\n return (address(0), RecoverError.InvalidSignatureLength);\\n }\\n }\\n\\n /**\\n * @dev Returns the address that signed a hashed message (`hash`) with\\n * `signature`. This address can then be used for verification purposes.\\n *\\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\\n * this function rejects them by requiring the `s` value to be in the lower\\n * half order, and the `v` value to be either 27 or 28.\\n *\\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\\n * verification to be secure: it is possible to craft signatures that\\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\\n * this is by receiving a hash of the original message (which may otherwise\\n * be too long), and then calling {toEthSignedMessageHash} on it.\\n */\\n function recover(bytes32 hash, bytes memory signature) internal pure returns (address) {\\n (address recovered, RecoverError error) = tryRecover(hash, signature);\\n _throwError(error);\\n return recovered;\\n }\\n\\n /**\\n * @dev Overload of {ECDSA-tryRecover} that receives the `r` and `vs` short-signature fields separately.\\n *\\n * See https://eips.ethereum.org/EIPS/eip-2098[EIP-2098 short signatures]\\n *\\n * _Available since v4.3._\\n */\\n function tryRecover(\\n bytes32 hash,\\n bytes32 r,\\n bytes32 vs\\n ) internal pure returns (address, RecoverError) {\\n bytes32 s = vs & bytes32(0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff);\\n uint8 v = uint8((uint256(vs) >> 255) + 27);\\n return tryRecover(hash, v, r, s);\\n }\\n\\n /**\\n * @dev Overload of {ECDSA-recover} that receives the `r and `vs` short-signature fields separately.\\n *\\n * _Available since v4.2._\\n */\\n function recover(\\n bytes32 hash,\\n bytes32 r,\\n bytes32 vs\\n ) internal pure returns (address) {\\n (address recovered, RecoverError error) = tryRecover(hash, r, vs);\\n _throwError(error);\\n return recovered;\\n }\\n\\n /**\\n * @dev Overload of {ECDSA-tryRecover} that receives the `v`,\\n * `r` and `s` signature fields separately.\\n *\\n * _Available since v4.3._\\n */\\n function tryRecover(\\n bytes32 hash,\\n uint8 v,\\n bytes32 r,\\n bytes32 s\\n ) internal pure returns (address, RecoverError) {\\n // EIP-2 still allows signature malleability for ecrecover(). Remove this possibility and make the signature\\n // unique. Appendix F in the Ethereum Yellow paper (https://ethereum.github.io/yellowpaper/paper.pdf), defines\\n // the valid range for s in (301): 0 < s < secp256k1n \\u00f7 2 + 1, and for v in (302): v \\u2208 {27, 28}. Most\\n // signatures from current libraries generate a unique signature with an s-value in the lower half order.\\n //\\n // If your library generates malleable signatures, such as s-values in the upper range, calculate a new s-value\\n // with 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141 - s1 and flip v from 27 to 28 or\\n // vice versa. If your library also generates signatures with 0/1 for v instead 27/28, add 27 to v to accept\\n // these malleable signatures as well.\\n if (uint256(s) > 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D576E7357A4501DDFE92F46681B20A0) {\\n return (address(0), RecoverError.InvalidSignatureS);\\n }\\n if (v != 27 && v != 28) {\\n return (address(0), RecoverError.InvalidSignatureV);\\n }\\n\\n // If the signature is valid (and not malleable), return the signer address\\n address signer = ecrecover(hash, v, r, s);\\n if (signer == address(0)) {\\n return (address(0), RecoverError.InvalidSignature);\\n }\\n\\n return (signer, RecoverError.NoError);\\n }\\n\\n /**\\n * @dev Overload of {ECDSA-recover} that receives the `v`,\\n * `r` and `s` signature fields separately.\\n */\\n function recover(\\n bytes32 hash,\\n uint8 v,\\n bytes32 r,\\n bytes32 s\\n ) internal pure returns (address) {\\n (address recovered, RecoverError error) = tryRecover(hash, v, r, s);\\n _throwError(error);\\n return recovered;\\n }\\n\\n /**\\n * @dev Returns an Ethereum Signed Message, created from a `hash`. This\\n * produces hash corresponding to the one signed with the\\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\\n * JSON-RPC method as part of EIP-191.\\n *\\n * See {recover}.\\n */\\n function toEthSignedMessageHash(bytes32 hash) internal pure returns (bytes32) {\\n // 32 is the length in bytes of hash,\\n // enforced by the type signature above\\n return keccak256(abi.encodePacked(\\\"\\\\x19Ethereum Signed Message:\\\\n32\\\", hash));\\n }\\n\\n /**\\n * @dev Returns an Ethereum Signed Message, created from `s`. This\\n * produces hash corresponding to the one signed with the\\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\\n * JSON-RPC method as part of EIP-191.\\n *\\n * See {recover}.\\n */\\n function toEthSignedMessageHash(bytes memory s) internal pure returns (bytes32) {\\n return keccak256(abi.encodePacked(\\\"\\\\x19Ethereum Signed Message:\\\\n\\\", StringsUpgradeable.toString(s.length), s));\\n }\\n\\n /**\\n * @dev Returns an Ethereum Signed Typed Data, created from a\\n * `domainSeparator` and a `structHash`. This produces hash corresponding\\n * to the one signed with the\\n * https://eips.ethereum.org/EIPS/eip-712[`eth_signTypedData`]\\n * JSON-RPC method as part of EIP-712.\\n *\\n * See {recover}.\\n */\\n function toTypedDataHash(bytes32 domainSeparator, bytes32 structHash) internal pure returns (bytes32) {\\n return keccak256(abi.encodePacked(\\\"\\\\x19\\\\x01\\\", domainSeparator, structHash));\\n }\\n}\\n\",\"keccak256\":\"0xe8c62ca00ed2d0a4d9b7e3c4bf7d62c821618b2cdb3c844da91a1193986851bf\",\"license\":\"MIT\"},\"@openzeppelin/contracts-upgradeable/utils/cryptography/draft-EIP712Upgradeable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (utils/cryptography/draft-EIP712.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"./ECDSAUpgradeable.sol\\\";\\nimport \\\"../../proxy/utils/Initializable.sol\\\";\\n\\n/**\\n * @dev https://eips.ethereum.org/EIPS/eip-712[EIP 712] is a standard for hashing and signing of typed structured data.\\n *\\n * The encoding specified in the EIP is very generic, and such a generic implementation in Solidity is not feasible,\\n * thus this contract does not implement the encoding itself. Protocols need to implement the type-specific encoding\\n * they need in their contracts using a combination of `abi.encode` and `keccak256`.\\n *\\n * This contract implements the EIP 712 domain separator ({_domainSeparatorV4}) that is used as part of the encoding\\n * scheme, and the final step of the encoding to obtain the message digest that is then signed via ECDSA\\n * ({_hashTypedDataV4}).\\n *\\n * The implementation of the domain separator was designed to be as efficient as possible while still properly updating\\n * the chain id to protect against replay attacks on an eventual fork of the chain.\\n *\\n * NOTE: This contract implements the version of the encoding known as \\\"v4\\\", as implemented by the JSON RPC method\\n * https://docs.metamask.io/guide/signing-data.html[`eth_signTypedDataV4` in MetaMask].\\n *\\n * _Available since v3.4._\\n *\\n * @custom:storage-size 52\\n */\\nabstract contract EIP712Upgradeable is Initializable {\\n /* solhint-disable var-name-mixedcase */\\n bytes32 private _HASHED_NAME;\\n bytes32 private _HASHED_VERSION;\\n bytes32 private constant _TYPE_HASH = keccak256(\\\"EIP712Domain(string name,string version,uint256 chainId,address verifyingContract)\\\");\\n\\n /* solhint-enable var-name-mixedcase */\\n\\n /**\\n * @dev Initializes the domain separator and parameter caches.\\n *\\n * The meaning of `name` and `version` is specified in\\n * https://eips.ethereum.org/EIPS/eip-712#definition-of-domainseparator[EIP 712]:\\n *\\n * - `name`: the user readable name of the signing domain, i.e. the name of the DApp or the protocol.\\n * - `version`: the current major version of the signing domain.\\n *\\n * NOTE: These parameters cannot be changed except through a xref:learn::upgrading-smart-contracts.adoc[smart\\n * contract upgrade].\\n */\\n function __EIP712_init(string memory name, string memory version) internal onlyInitializing {\\n __EIP712_init_unchained(name, version);\\n }\\n\\n function __EIP712_init_unchained(string memory name, string memory version) internal onlyInitializing {\\n bytes32 hashedName = keccak256(bytes(name));\\n bytes32 hashedVersion = keccak256(bytes(version));\\n _HASHED_NAME = hashedName;\\n _HASHED_VERSION = hashedVersion;\\n }\\n\\n /**\\n * @dev Returns the domain separator for the current chain.\\n */\\n function _domainSeparatorV4() internal view returns (bytes32) {\\n return _buildDomainSeparator(_TYPE_HASH, _EIP712NameHash(), _EIP712VersionHash());\\n }\\n\\n function _buildDomainSeparator(\\n bytes32 typeHash,\\n bytes32 nameHash,\\n bytes32 versionHash\\n ) private view returns (bytes32) {\\n return keccak256(abi.encode(typeHash, nameHash, versionHash, block.chainid, address(this)));\\n }\\n\\n /**\\n * @dev Given an already https://eips.ethereum.org/EIPS/eip-712#definition-of-hashstruct[hashed struct], this\\n * function returns the hash of the fully encoded EIP712 message for this domain.\\n *\\n * This hash can be used together with {ECDSA-recover} to obtain the signer of a message. For example:\\n *\\n * ```solidity\\n * bytes32 digest = _hashTypedDataV4(keccak256(abi.encode(\\n * keccak256(\\\"Mail(address to,string contents)\\\"),\\n * mailTo,\\n * keccak256(bytes(mailContents))\\n * )));\\n * address signer = ECDSA.recover(digest, signature);\\n * ```\\n */\\n function _hashTypedDataV4(bytes32 structHash) internal view virtual returns (bytes32) {\\n return ECDSAUpgradeable.toTypedDataHash(_domainSeparatorV4(), structHash);\\n }\\n\\n /**\\n * @dev The hash of the name parameter for the EIP712 domain.\\n *\\n * NOTE: This function reads from storage by default, but can be redefined to return a constant value if gas costs\\n * are a concern.\\n */\\n function _EIP712NameHash() internal virtual view returns (bytes32) {\\n return _HASHED_NAME;\\n }\\n\\n /**\\n * @dev The hash of the version parameter for the EIP712 domain.\\n *\\n * NOTE: This function reads from storage by default, but can be redefined to return a constant value if gas costs\\n * are a concern.\\n */\\n function _EIP712VersionHash() internal virtual view returns (bytes32) {\\n return _HASHED_VERSION;\\n }\\n\\n /**\\n * @dev This empty reserved space is put in place to allow future versions to add new\\n * variables without shifting down storage in the inheritance chain.\\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\\n */\\n uint256[50] private __gap;\\n}\\n\",\"keccak256\":\"0xaf5a96100f421d61693605349511e43221d3c2e47d4b3efa87af2b936e2567fc\",\"license\":\"MIT\"},\"@openzeppelin/contracts/token/ERC20/IERC20.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.6.0) (token/ERC20/IERC20.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Interface of the ERC20 standard as defined in the EIP.\\n */\\ninterface IERC20 {\\n /**\\n * @dev Emitted when `value` tokens are moved from one account (`from`) to\\n * another (`to`).\\n *\\n * Note that `value` may be zero.\\n */\\n event Transfer(address indexed from, address indexed to, uint256 value);\\n\\n /**\\n * @dev Emitted when the allowance of a `spender` for an `owner` is set by\\n * a call to {approve}. `value` is the new allowance.\\n */\\n event Approval(address indexed owner, address indexed spender, uint256 value);\\n\\n /**\\n * @dev Returns the amount of tokens in existence.\\n */\\n function totalSupply() external view returns (uint256);\\n\\n /**\\n * @dev Returns the amount of tokens owned by `account`.\\n */\\n function balanceOf(address account) external view returns (uint256);\\n\\n /**\\n * @dev Moves `amount` tokens from the caller's account to `to`.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * Emits a {Transfer} event.\\n */\\n function transfer(address to, uint256 amount) external returns (bool);\\n\\n /**\\n * @dev Returns the remaining number of tokens that `spender` will be\\n * allowed to spend on behalf of `owner` through {transferFrom}. This is\\n * zero by default.\\n *\\n * This value changes when {approve} or {transferFrom} are called.\\n */\\n function allowance(address owner, address spender) external view returns (uint256);\\n\\n /**\\n * @dev Sets `amount` as the allowance of `spender` over the caller's tokens.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * IMPORTANT: Beware that changing an allowance with this method brings the risk\\n * that someone may use both the old and the new allowance by unfortunate\\n * transaction ordering. One possible solution to mitigate this race\\n * condition is to first reduce the spender's allowance to 0 and set the\\n * desired value afterwards:\\n * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729\\n *\\n * Emits an {Approval} event.\\n */\\n function approve(address spender, uint256 amount) external returns (bool);\\n\\n /**\\n * @dev Moves `amount` tokens from `from` to `to` using the\\n * allowance mechanism. `amount` is then deducted from the caller's\\n * allowance.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * Emits a {Transfer} event.\\n */\\n function transferFrom(\\n address from,\\n address to,\\n uint256 amount\\n ) external returns (bool);\\n}\\n\",\"keccak256\":\"0x9750c6b834f7b43000631af5cc30001c5f547b3ceb3635488f140f60e897ea6b\",\"license\":\"MIT\"},\"@openzeppelin/contracts/token/ERC20/extensions/draft-IERC20Permit.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (token/ERC20/extensions/draft-IERC20Permit.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Interface of the ERC20 Permit extension allowing approvals to be made via signatures, as defined in\\n * https://eips.ethereum.org/EIPS/eip-2612[EIP-2612].\\n *\\n * Adds the {permit} method, which can be used to change an account's ERC20 allowance (see {IERC20-allowance}) by\\n * presenting a message signed by the account. By not relying on {IERC20-approve}, the token holder account doesn't\\n * need to send a transaction, and thus is not required to hold Ether at all.\\n */\\ninterface IERC20Permit {\\n /**\\n * @dev Sets `value` as the allowance of `spender` over ``owner``'s tokens,\\n * given ``owner``'s signed approval.\\n *\\n * IMPORTANT: The same issues {IERC20-approve} has related to transaction\\n * ordering also apply here.\\n *\\n * Emits an {Approval} event.\\n *\\n * Requirements:\\n *\\n * - `spender` cannot be the zero address.\\n * - `deadline` must be a timestamp in the future.\\n * - `v`, `r` and `s` must be a valid `secp256k1` signature from `owner`\\n * over the EIP712-formatted function arguments.\\n * - the signature must use ``owner``'s current nonce (see {nonces}).\\n *\\n * For more information on the signature format, see the\\n * https://eips.ethereum.org/EIPS/eip-2612#specification[relevant EIP\\n * section].\\n */\\n function permit(\\n address owner,\\n address spender,\\n uint256 value,\\n uint256 deadline,\\n uint8 v,\\n bytes32 r,\\n bytes32 s\\n ) external;\\n\\n /**\\n * @dev Returns the current nonce for `owner`. This value must be\\n * included whenever a signature is generated for {permit}.\\n *\\n * Every successful call to {permit} increases ``owner``'s nonce by one. This\\n * prevents a signature from being used multiple times.\\n */\\n function nonces(address owner) external view returns (uint256);\\n\\n /**\\n * @dev Returns the domain separator used in the encoding of the signature for {permit}, as defined by {EIP712}.\\n */\\n // solhint-disable-next-line func-name-mixedcase\\n function DOMAIN_SEPARATOR() external view returns (bytes32);\\n}\\n\",\"keccak256\":\"0xf41ca991f30855bf80ffd11e9347856a517b977f0a6c2d52e6421a99b7840329\",\"license\":\"MIT\"},\"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.7.0) (token/ERC20/utils/SafeERC20.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../IERC20.sol\\\";\\nimport \\\"../extensions/draft-IERC20Permit.sol\\\";\\nimport \\\"../../../utils/Address.sol\\\";\\n\\n/**\\n * @title SafeERC20\\n * @dev Wrappers around ERC20 operations that throw on failure (when the token\\n * contract returns false). Tokens that return no value (and instead revert or\\n * throw on failure) are also supported, non-reverting calls are assumed to be\\n * successful.\\n * To use this library you can add a `using SafeERC20 for IERC20;` statement to your contract,\\n * which allows you to call the safe operations as `token.safeTransfer(...)`, etc.\\n */\\nlibrary SafeERC20 {\\n using Address for address;\\n\\n function safeTransfer(\\n IERC20 token,\\n address to,\\n uint256 value\\n ) internal {\\n _callOptionalReturn(token, abi.encodeWithSelector(token.transfer.selector, to, value));\\n }\\n\\n function safeTransferFrom(\\n IERC20 token,\\n address from,\\n address to,\\n uint256 value\\n ) internal {\\n _callOptionalReturn(token, abi.encodeWithSelector(token.transferFrom.selector, from, to, value));\\n }\\n\\n /**\\n * @dev Deprecated. This function has issues similar to the ones found in\\n * {IERC20-approve}, and its usage is discouraged.\\n *\\n * Whenever possible, use {safeIncreaseAllowance} and\\n * {safeDecreaseAllowance} instead.\\n */\\n function safeApprove(\\n IERC20 token,\\n address spender,\\n uint256 value\\n ) internal {\\n // safeApprove should only be called when setting an initial allowance,\\n // or when resetting it to zero. To increase and decrease it, use\\n // 'safeIncreaseAllowance' and 'safeDecreaseAllowance'\\n require(\\n (value == 0) || (token.allowance(address(this), spender) == 0),\\n \\\"SafeERC20: approve from non-zero to non-zero allowance\\\"\\n );\\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, value));\\n }\\n\\n function safeIncreaseAllowance(\\n IERC20 token,\\n address spender,\\n uint256 value\\n ) internal {\\n uint256 newAllowance = token.allowance(address(this), spender) + value;\\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));\\n }\\n\\n function safeDecreaseAllowance(\\n IERC20 token,\\n address spender,\\n uint256 value\\n ) internal {\\n unchecked {\\n uint256 oldAllowance = token.allowance(address(this), spender);\\n require(oldAllowance >= value, \\\"SafeERC20: decreased allowance below zero\\\");\\n uint256 newAllowance = oldAllowance - value;\\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));\\n }\\n }\\n\\n function safePermit(\\n IERC20Permit token,\\n address owner,\\n address spender,\\n uint256 value,\\n uint256 deadline,\\n uint8 v,\\n bytes32 r,\\n bytes32 s\\n ) internal {\\n uint256 nonceBefore = token.nonces(owner);\\n token.permit(owner, spender, value, deadline, v, r, s);\\n uint256 nonceAfter = token.nonces(owner);\\n require(nonceAfter == nonceBefore + 1, \\\"SafeERC20: permit did not succeed\\\");\\n }\\n\\n /**\\n * @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement\\n * on the return value: the return value is optional (but if data is returned, it must not be false).\\n * @param token The token targeted by the call.\\n * @param data The call data (encoded using abi.encode or one of its variants).\\n */\\n function _callOptionalReturn(IERC20 token, bytes memory data) private {\\n // We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since\\n // we're implementing it ourselves. We use {Address.functionCall} to perform this call, which verifies that\\n // the target address contains contract code and also asserts for success in the low-level call.\\n\\n bytes memory returndata = address(token).functionCall(data, \\\"SafeERC20: low-level call failed\\\");\\n if (returndata.length > 0) {\\n // Return data is optional\\n require(abi.decode(returndata, (bool)), \\\"SafeERC20: ERC20 operation did not succeed\\\");\\n }\\n }\\n}\\n\",\"keccak256\":\"0x032807210d1d7d218963d7355d62e021a84bf1b3339f4f50be2f63b53cccaf29\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/Address.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.7.0) (utils/Address.sol)\\n\\npragma solidity ^0.8.1;\\n\\n/**\\n * @dev Collection of functions related to the address type\\n */\\nlibrary Address {\\n /**\\n * @dev Returns true if `account` is a contract.\\n *\\n * [IMPORTANT]\\n * ====\\n * It is unsafe to assume that an address for which this function returns\\n * false is an externally-owned account (EOA) and not a contract.\\n *\\n * Among others, `isContract` will return false for the following\\n * types of addresses:\\n *\\n * - an externally-owned account\\n * - a contract in construction\\n * - an address where a contract will be created\\n * - an address where a contract lived, but was destroyed\\n * ====\\n *\\n * [IMPORTANT]\\n * ====\\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\\n *\\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\\n * constructor.\\n * ====\\n */\\n function isContract(address account) internal view returns (bool) {\\n // This method relies on extcodesize/address.code.length, which returns 0\\n // for contracts in construction, since the code is only stored at the end\\n // of the constructor execution.\\n\\n return account.code.length > 0;\\n }\\n\\n /**\\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\\n * `recipient`, forwarding all available gas and reverting on errors.\\n *\\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\\n * imposed by `transfer`, making them unable to receive funds via\\n * `transfer`. {sendValue} removes this limitation.\\n *\\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\\n *\\n * IMPORTANT: because control is transferred to `recipient`, care must be\\n * taken to not create reentrancy vulnerabilities. Consider using\\n * {ReentrancyGuard} or the\\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\\n */\\n function sendValue(address payable recipient, uint256 amount) internal {\\n require(address(this).balance >= amount, \\\"Address: insufficient balance\\\");\\n\\n (bool success, ) = recipient.call{value: amount}(\\\"\\\");\\n require(success, \\\"Address: unable to send value, recipient may have reverted\\\");\\n }\\n\\n /**\\n * @dev Performs a Solidity function call using a low level `call`. A\\n * plain `call` is an unsafe replacement for a function call: use this\\n * function instead.\\n *\\n * If `target` reverts with a revert reason, it is bubbled up by this\\n * function (like regular Solidity function calls).\\n *\\n * Returns the raw returned data. To convert to the expected return value,\\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\\n *\\n * Requirements:\\n *\\n * - `target` must be a contract.\\n * - calling `target` with `data` must not revert.\\n *\\n * _Available since v3.1._\\n */\\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\\n return functionCall(target, data, \\\"Address: low-level call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\\n * `errorMessage` as a fallback revert reason when `target` reverts.\\n *\\n * _Available since v3.1._\\n */\\n function functionCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n return functionCallWithValue(target, data, 0, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but also transferring `value` wei to `target`.\\n *\\n * Requirements:\\n *\\n * - the calling contract must have an ETH balance of at least `value`.\\n * - the called Solidity function must be `payable`.\\n *\\n * _Available since v3.1._\\n */\\n function functionCallWithValue(\\n address target,\\n bytes memory data,\\n uint256 value\\n ) internal returns (bytes memory) {\\n return functionCallWithValue(target, data, value, \\\"Address: low-level call with value failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\\n * with `errorMessage` as a fallback revert reason when `target` reverts.\\n *\\n * _Available since v3.1._\\n */\\n function functionCallWithValue(\\n address target,\\n bytes memory data,\\n uint256 value,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n require(address(this).balance >= value, \\\"Address: insufficient balance for call\\\");\\n require(isContract(target), \\\"Address: call to non-contract\\\");\\n\\n (bool success, bytes memory returndata) = target.call{value: value}(data);\\n return verifyCallResult(success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but performing a static call.\\n *\\n * _Available since v3.3._\\n */\\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\\n return functionStaticCall(target, data, \\\"Address: low-level static call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\\n * but performing a static call.\\n *\\n * _Available since v3.3._\\n */\\n function functionStaticCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal view returns (bytes memory) {\\n require(isContract(target), \\\"Address: static call to non-contract\\\");\\n\\n (bool success, bytes memory returndata) = target.staticcall(data);\\n return verifyCallResult(success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but performing a delegate call.\\n *\\n * _Available since v3.4._\\n */\\n function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {\\n return functionDelegateCall(target, data, \\\"Address: low-level delegate call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\\n * but performing a delegate call.\\n *\\n * _Available since v3.4._\\n */\\n function functionDelegateCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n require(isContract(target), \\\"Address: delegate call to non-contract\\\");\\n\\n (bool success, bytes memory returndata) = target.delegatecall(data);\\n return verifyCallResult(success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the\\n * revert reason using the provided one.\\n *\\n * _Available since v4.3._\\n */\\n function verifyCallResult(\\n bool success,\\n bytes memory returndata,\\n string memory errorMessage\\n ) internal pure returns (bytes memory) {\\n if (success) {\\n return returndata;\\n } else {\\n // Look for revert reason and bubble it up if present\\n if (returndata.length > 0) {\\n // The easiest way to bubble the revert reason is using memory via assembly\\n /// @solidity memory-safe-assembly\\n assembly {\\n let returndata_size := mload(returndata)\\n revert(add(32, returndata), returndata_size)\\n }\\n } else {\\n revert(errorMessage);\\n }\\n }\\n }\\n}\\n\",\"keccak256\":\"0xd6153ce99bcdcce22b124f755e72553295be6abcd63804cfdffceb188b8bef10\",\"license\":\"MIT\"},\"contracts/agToken/AgTokenSideChainMultiBridge.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-3.0\\n\\npragma solidity ^0.8.12;\\n\\nimport \\\"./BaseAgTokenSideChain.sol\\\";\\nimport \\\"@openzeppelin/contracts/token/ERC20/IERC20.sol\\\";\\nimport \\\"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\\\";\\n\\n/// @title AgTokenSideChainMultiBridge\\n/// @author Angle Labs, Inc.\\n/// @notice Contract for Angle agTokens on other chains than Ethereum mainnet\\n/// @dev This contract supports bridge tokens having a minting right on the stablecoin (also referred to as the canonical\\n/// or the native token)\\n/// @dev References:\\n/// - FRAX implementation: https://polygonscan.com/address/0x45c32fA6DF82ead1e2EF74d17b76547EDdFaFF89#code\\n/// - QiDAO implementation: https://snowtrace.io/address/0x5c49b268c9841AFF1Cc3B0a418ff5c3442eE3F3b#code\\ncontract AgTokenSideChainMultiBridge is BaseAgTokenSideChain {\\n using SafeERC20 for IERC20;\\n\\n /// @notice Base used for fee computation\\n uint256 public constant BASE_PARAMS = 10**9;\\n\\n // =============================== Bridging Data ===============================\\n\\n /// @notice Struct with some data about a specific bridge token\\n struct BridgeDetails {\\n // Limit on the balance of bridge token held by the contract: it is designed\\n // to reduce the exposure of the system to hacks\\n uint256 limit;\\n // Limit on the hourly volume of token minted through this bridge\\n // Technically the limit over a rolling hour is hourlyLimit x2 as hourly limit\\n // is enforced only between x:00 and x+1:00\\n uint256 hourlyLimit;\\n // Fee taken for swapping in and out the token\\n uint64 fee;\\n // Whether the associated token is allowed or not\\n bool allowed;\\n // Whether swapping in and out from the associated token is paused or not\\n bool paused;\\n }\\n\\n /// @notice Maps a bridge token to data\\n mapping(address => BridgeDetails) public bridges;\\n /// @notice List of all bridge tokens\\n address[] public bridgeTokensList;\\n /// @notice Maps a bridge token to the associated hourly volume\\n mapping(address => mapping(uint256 => uint256)) public usage;\\n /// @notice Maps an address to whether it is exempt of fees for when it comes to swapping in and out\\n mapping(address => uint256) public isFeeExempt;\\n /// @notice Limit to the amount of tokens that can be sent from that chain to another chain\\n uint256 public chainTotalHourlyLimit;\\n /// @notice Usage per hour on that chain. Maps an hourly timestamp to the total volume swapped out on the chain\\n mapping(uint256 => uint256) public chainTotalUsage;\\n\\n // ================================== Events ===================================\\n\\n event BridgeTokenAdded(address indexed bridgeToken, uint256 limit, uint256 hourlyLimit, uint64 fee, bool paused);\\n event BridgeTokenToggled(address indexed bridgeToken, bool toggleStatus);\\n event BridgeTokenRemoved(address indexed bridgeToken);\\n event BridgeTokenFeeUpdated(address indexed bridgeToken, uint64 fee);\\n event BridgeTokenLimitUpdated(address indexed bridgeToken, uint256 limit);\\n event BridgeTokenHourlyLimitUpdated(address indexed bridgeToken, uint256 hourlyLimit);\\n event HourlyLimitUpdated(uint256 hourlyLimit);\\n event Recovered(address indexed token, address indexed to, uint256 amount);\\n event FeeToggled(address indexed theAddress, uint256 toggleStatus);\\n\\n // =============================== Errors ================================\\n\\n error AssetStillControlledInReserves();\\n error HourlyLimitExceeded();\\n error InvalidToken();\\n error NotGovernor();\\n error NotGovernorOrGuardian();\\n error TooBigAmount();\\n error TooHighParameterValue();\\n error ZeroAddress();\\n\\n // ============================= Constructor ===================================\\n\\n /// @notice Initializes the `AgToken` contract\\n /// @param name_ Name of the token\\n /// @param symbol_ Symbol of the token\\n /// @param _treasury Reference to the `Treasury` contract associated to this agToken\\n /// @dev By default, agTokens are ERC-20 tokens with 18 decimals\\n function initialize(\\n string memory name_,\\n string memory symbol_,\\n address _treasury\\n ) external {\\n _initialize(name_, symbol_, _treasury);\\n }\\n\\n // =============================== Modifiers ===================================\\n\\n /// @notice Checks whether the `msg.sender` has the governor role or not\\n modifier onlyGovernor() {\\n if (!ITreasury(treasury).isGovernor(msg.sender)) revert NotGovernor();\\n _;\\n }\\n\\n /// @notice Checks whether the `msg.sender` has the governor role or the guardian role\\n modifier onlyGovernorOrGuardian() {\\n if (!ITreasury(treasury).isGovernorOrGuardian(msg.sender)) revert NotGovernorOrGuardian();\\n _;\\n }\\n\\n // ==================== External Permissionless Functions ======================\\n\\n /// @notice Returns the list of all supported bridge tokens\\n /// @dev Helpful for UIs\\n function allBridgeTokens() external view returns (address[] memory) {\\n return bridgeTokensList;\\n }\\n\\n /// @notice Returns the current volume for a bridge, for the current hour\\n /// @param bridgeToken Bridge used to mint\\n /// @dev Helpful for UIs\\n function currentUsage(address bridgeToken) external view returns (uint256) {\\n return usage[bridgeToken][block.timestamp / 3600];\\n }\\n\\n /// @notice Returns the current total volume on the chain for the current hour\\n /// @dev Helpful for UIs\\n function currentTotalUsage() external view returns (uint256) {\\n return chainTotalUsage[block.timestamp / 3600];\\n }\\n\\n /// @notice Mints the canonical token from a supported bridge token\\n /// @param bridgeToken Bridge token to use to mint\\n /// @param amount Amount of bridge tokens to send\\n /// @param to Address to which the stablecoin should be sent\\n /// @return Amount of the canonical stablecoin actually minted\\n /// @dev Some fees may be taken by the protocol depending on the token used and on the address calling\\n function swapIn(\\n address bridgeToken,\\n uint256 amount,\\n address to\\n ) external returns (uint256) {\\n BridgeDetails memory bridgeDetails = bridges[bridgeToken];\\n if (!bridgeDetails.allowed || bridgeDetails.paused) revert InvalidToken();\\n uint256 balance = IERC20(bridgeToken).balanceOf(address(this));\\n if (balance + amount > bridgeDetails.limit) {\\n // In case someone maliciously sends tokens to this contract\\n // Or the limit changes\\n if (bridgeDetails.limit > balance) amount = bridgeDetails.limit - balance;\\n else {\\n amount = 0;\\n }\\n }\\n\\n // Checking requirement on the hourly volume\\n uint256 hour = block.timestamp / 3600;\\n uint256 hourlyUsage = usage[bridgeToken][hour];\\n if (hourlyUsage + amount > bridgeDetails.hourlyLimit) {\\n // Edge case when the hourly limit changes\\n amount = bridgeDetails.hourlyLimit > hourlyUsage ? bridgeDetails.hourlyLimit - hourlyUsage : 0;\\n }\\n usage[bridgeToken][hour] = hourlyUsage + amount;\\n\\n IERC20(bridgeToken).safeTransferFrom(msg.sender, address(this), amount);\\n uint256 canonicalOut = amount;\\n // Computing fees\\n if (isFeeExempt[msg.sender] == 0) {\\n canonicalOut -= (canonicalOut * bridgeDetails.fee) / BASE_PARAMS;\\n }\\n _mint(to, canonicalOut);\\n return canonicalOut;\\n }\\n\\n /// @notice Burns the canonical token in exchange for a bridge token\\n /// @param bridgeToken Bridge token required\\n /// @param amount Amount of canonical tokens to burn\\n /// @param to Address to which the bridge token should be sent\\n /// @return Amount of bridge tokens actually sent back\\n /// @dev Some fees may be taken by the protocol depending on the token used and on the address calling\\n function swapOut(\\n address bridgeToken,\\n uint256 amount,\\n address to\\n ) external returns (uint256) {\\n BridgeDetails memory bridgeDetails = bridges[bridgeToken];\\n if (!bridgeDetails.allowed || bridgeDetails.paused) revert InvalidToken();\\n\\n uint256 hour = block.timestamp / 3600;\\n uint256 hourlyUsage = chainTotalUsage[hour] + amount;\\n // If the amount being swapped out exceeds the limit, we revert\\n // We don't want to change the amount being swapped out.\\n // The user can decide to send another tx with the correct amount to reach the limit\\n if (hourlyUsage > chainTotalHourlyLimit) revert HourlyLimitExceeded();\\n chainTotalUsage[hour] = hourlyUsage;\\n\\n _burn(msg.sender, amount);\\n uint256 bridgeOut = amount;\\n if (isFeeExempt[msg.sender] == 0) {\\n bridgeOut -= (bridgeOut * bridgeDetails.fee) / BASE_PARAMS;\\n }\\n IERC20(bridgeToken).safeTransfer(to, bridgeOut);\\n return bridgeOut;\\n }\\n\\n // ======================= Governance Functions ================================\\n\\n /// @notice Adds support for a bridge token\\n /// @param bridgeToken Bridge token to add: it should be a version of the stablecoin from another bridge\\n /// @param limit Limit on the balance of bridge token this contract could hold\\n /// @param hourlyLimit Limit on the hourly volume for this bridge\\n /// @param paused Whether swapping for this token should be paused or not\\n /// @param fee Fee taken upon swapping for or against this token\\n function addBridgeToken(\\n address bridgeToken,\\n uint256 limit,\\n uint256 hourlyLimit,\\n uint64 fee,\\n bool paused\\n ) external onlyGovernor {\\n if (bridges[bridgeToken].allowed || bridgeToken == address(0)) revert InvalidToken();\\n if (fee > BASE_PARAMS) revert TooHighParameterValue();\\n BridgeDetails memory _bridge;\\n _bridge.limit = limit;\\n _bridge.hourlyLimit = hourlyLimit;\\n _bridge.paused = paused;\\n _bridge.fee = fee;\\n _bridge.allowed = true;\\n bridges[bridgeToken] = _bridge;\\n bridgeTokensList.push(bridgeToken);\\n emit BridgeTokenAdded(bridgeToken, limit, hourlyLimit, fee, paused);\\n }\\n\\n /// @notice Removes support for a token\\n /// @param bridgeToken Address of the bridge token to remove support for\\n function removeBridgeToken(address bridgeToken) external onlyGovernor {\\n if (IERC20(bridgeToken).balanceOf(address(this)) != 0) revert AssetStillControlledInReserves();\\n delete bridges[bridgeToken];\\n // Deletion from `bridgeTokensList` loop\\n uint256 bridgeTokensListLength = bridgeTokensList.length;\\n for (uint256 i; i < bridgeTokensListLength - 1; ++i) {\\n if (bridgeTokensList[i] == bridgeToken) {\\n // Replace the `bridgeToken` to remove with the last of the list\\n bridgeTokensList[i] = bridgeTokensList[bridgeTokensListLength - 1];\\n break;\\n }\\n }\\n // Remove last element in array\\n bridgeTokensList.pop();\\n emit BridgeTokenRemoved(bridgeToken);\\n }\\n\\n /// @notice Recovers any ERC20 token\\n /// @dev Can be used to withdraw bridge tokens for them to be de-bridged on mainnet\\n function recoverERC20(\\n address tokenAddress,\\n address to,\\n uint256 amountToRecover\\n ) external onlyGovernor {\\n IERC20(tokenAddress).safeTransfer(to, amountToRecover);\\n emit Recovered(tokenAddress, to, amountToRecover);\\n }\\n\\n /// @notice Updates the `limit` amount for `bridgeToken`\\n function setLimit(address bridgeToken, uint256 limit) external onlyGovernorOrGuardian {\\n if (!bridges[bridgeToken].allowed) revert InvalidToken();\\n bridges[bridgeToken].limit = limit;\\n emit BridgeTokenLimitUpdated(bridgeToken, limit);\\n }\\n\\n /// @notice Updates the `hourlyLimit` amount for `bridgeToken`\\n function setHourlyLimit(address bridgeToken, uint256 hourlyLimit) external onlyGovernorOrGuardian {\\n if (!bridges[bridgeToken].allowed) revert InvalidToken();\\n bridges[bridgeToken].hourlyLimit = hourlyLimit;\\n emit BridgeTokenHourlyLimitUpdated(bridgeToken, hourlyLimit);\\n }\\n\\n /// @notice Updates the `chainTotalHourlyLimit` amount\\n function setChainTotalHourlyLimit(uint256 hourlyLimit) external onlyGovernorOrGuardian {\\n chainTotalHourlyLimit = hourlyLimit;\\n emit HourlyLimitUpdated(hourlyLimit);\\n }\\n\\n /// @notice Updates the `fee` value for `bridgeToken`\\n function setSwapFee(address bridgeToken, uint64 fee) external onlyGovernorOrGuardian {\\n if (!bridges[bridgeToken].allowed) revert InvalidToken();\\n if (fee > BASE_PARAMS) revert TooHighParameterValue();\\n bridges[bridgeToken].fee = fee;\\n emit BridgeTokenFeeUpdated(bridgeToken, fee);\\n }\\n\\n /// @notice Pauses or unpauses swapping in and out for a token\\n function toggleBridge(address bridgeToken) external onlyGovernorOrGuardian {\\n if (!bridges[bridgeToken].allowed) revert InvalidToken();\\n bool pausedStatus = bridges[bridgeToken].paused;\\n bridges[bridgeToken].paused = !pausedStatus;\\n emit BridgeTokenToggled(bridgeToken, !pausedStatus);\\n }\\n\\n /// @notice Toggles fees for the address `theAddress`\\n function toggleFeesForAddress(address theAddress) external onlyGovernorOrGuardian {\\n uint256 feeExemptStatus = 1 - isFeeExempt[theAddress];\\n isFeeExempt[theAddress] = feeExemptStatus;\\n emit FeeToggled(theAddress, feeExemptStatus);\\n }\\n}\\n\",\"keccak256\":\"0x03d7733482f57983ff12e1ea50ad9f7ba089f747e566c11d27ee199c59ff229c\",\"license\":\"GPL-3.0\"},\"contracts/agToken/BaseAgTokenSideChain.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-3.0\\n\\npragma solidity ^0.8.12;\\n\\n/*\\n * \\u2588 \\n ***** \\u2593\\u2593\\u2593 \\n * \\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593 \\n * ///. \\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593 \\n ***** //////// \\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593 \\n * ///////////// \\u2593\\u2593\\u2593 \\n \\u2593\\u2593 ////////////////// \\u2588 \\u2593\\u2593 \\n \\u2593\\u2593 \\u2593\\u2593 /////////////////////// \\u2593\\u2593 \\u2593\\u2593 \\n \\u2593\\u2593 \\u2593\\u2593 //////////////////////////// \\u2593\\u2593 \\u2593\\u2593 \\n \\u2593\\u2593 \\u2593\\u2593 /////////\\u2593\\u2593\\u2593///////\\u2593\\u2593\\u2593///////// \\u2593\\u2593 \\u2593\\u2593 \\n \\u2593\\u2593 ,////////////////////////////////////// \\u2593\\u2593 \\u2593\\u2593 \\n \\u2593\\u2593 ////////////////////////////////////////// \\u2593\\u2593 \\n \\u2593\\u2593 //////////////////////\\u2593\\u2593\\u2593\\u2593///////////////////// \\n ,//////////////////////////////////////////////////// \\n .////////////////////////////////////////////////////////// \\n .//////////////////////////\\u2588\\u2588.,//////////////////////////\\u2588 \\n .//////////////////////\\u2588\\u2588\\u2588\\u2588..,./////////////////////\\u2588\\u2588 \\n ...////////////////\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588.....,.////////////////\\u2588\\u2588\\u2588 \\n ,.,////////////\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588 ........,///////////\\u2588\\u2588\\u2588\\u2588 \\n .,.,//////\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588 ,.......///////\\u2588\\u2588\\u2588\\u2588 \\n ,..//\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588 ........./\\u2588\\u2588\\u2588\\u2588 \\n ..,\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588 .....,\\u2588\\u2588\\u2588 \\n .\\u2588\\u2588 ,.,\\u2588 \\n \\n \\n \\n \\u2593\\u2593 \\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593 \\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593 \\u2593\\u2593 \\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593 \\n \\u2593\\u2593\\u2593\\u2593\\u2593\\u2593 \\u2593\\u2593\\u2593 \\u2593\\u2593\\u2593 \\u2593\\u2593\\u2593 \\u2593\\u2593 \\u2593\\u2593 \\u2593\\u2593\\u2593\\u2593 \\n \\u2593\\u2593\\u2593 \\u2593\\u2593\\u2593 \\u2593\\u2593\\u2593 \\u2593\\u2593\\u2593 \\u2593\\u2593\\u2593 \\u2593\\u2593\\u2593 \\u2593\\u2593 \\u2593\\u2593\\u2593\\u2593\\u2593 \\n \\u2593\\u2593\\u2593 \\u2593\\u2593 \\u2593\\u2593\\u2593 \\u2593\\u2593\\u2593 \\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593 \\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593 \\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593 \\n*/\\n\\nimport \\\"../interfaces/IAgToken.sol\\\";\\nimport \\\"../interfaces/ITreasury.sol\\\";\\nimport \\\"@openzeppelin/contracts-upgradeable/token/ERC20/extensions/draft-ERC20PermitUpgradeable.sol\\\";\\n\\n/// @title BaseAgTokenSideChain\\n/// @author Angle Labs, Inc.\\n/// @notice Base contract for Angle agTokens on Ethereum and on other chains\\n/// @dev By default, agTokens are ERC-20 tokens with 18 decimals\\ncontract BaseAgTokenSideChain is IAgToken, ERC20PermitUpgradeable {\\n // =========================== PARAMETERS / VARIABLES ==========================\\n\\n /// @inheritdoc IAgToken\\n mapping(address => bool) public isMinter;\\n /// @notice Reference to the treasury contract which can grant minting rights\\n address public treasury;\\n\\n // =================================== EVENTS ==================================\\n\\n event TreasuryUpdated(address indexed _treasury);\\n event MinterToggled(address indexed minter);\\n\\n // =================================== ERRORS ==================================\\n\\n error BurnAmountExceedsAllowance();\\n error InvalidSender();\\n error InvalidTreasury();\\n error NotMinter();\\n error NotTreasury();\\n\\n // ================================ CONSTRUCTOR ================================\\n\\n /// @notice Wraps `_initializeBase` for `BaseAgTokenSideChain` and makes a safety check\\n /// on `_treasury`\\n function _initialize(string memory name_, string memory symbol_, address _treasury) internal virtual initializer {\\n if (address(ITreasury(_treasury).stablecoin()) != address(this)) revert InvalidTreasury();\\n _initializeBase(name_, symbol_, _treasury);\\n }\\n\\n /// @custom:oz-upgrades-unsafe-allow constructor\\n constructor() initializer {}\\n\\n /// @notice Initializes the contract\\n /// @param name_ Name of the token\\n /// @param symbol_ Symbol of the token\\n /// @param _treasury Reference to the `Treasury` contract associated to this agToken implementation\\n function _initializeBase(string memory name_, string memory symbol_, address _treasury) internal virtual {\\n __ERC20Permit_init(name_);\\n __ERC20_init(name_, symbol_);\\n treasury = _treasury;\\n emit TreasuryUpdated(address(_treasury));\\n }\\n\\n // ================================= MODIFIERS =================================\\n\\n /// @notice Checks to see if it is the `Treasury` calling this contract\\n /// @dev There is no Access Control here, because it can be handled cheaply through this modifier\\n modifier onlyTreasury() {\\n if (msg.sender != address(treasury)) revert NotTreasury();\\n _;\\n }\\n\\n /// @notice Checks whether the sender has the minting right\\n modifier onlyMinter() {\\n if (!isMinter[msg.sender]) revert NotMinter();\\n _;\\n }\\n\\n // ============================= EXTERNAL FUNCTION =============================\\n\\n /// @notice Allows anyone to burn agToken without redeeming collateral back\\n /// @param amount Amount of stablecoins to burn\\n /// @dev This function can typically be called if there is a settlement mechanism to burn stablecoins\\n function burnStablecoin(uint256 amount) external {\\n _burn(msg.sender, amount);\\n }\\n\\n // ========================= MINTER ROLE ONLY FUNCTIONS ========================\\n\\n /// @inheritdoc IAgToken\\n function burnSelf(uint256 amount, address burner) external onlyMinter {\\n _burn(burner, amount);\\n }\\n\\n /// @inheritdoc IAgToken\\n function burnFrom(uint256 amount, address burner, address sender) external onlyMinter {\\n _burnFromNoRedeem(amount, burner, sender);\\n }\\n\\n /// @inheritdoc IAgToken\\n function mint(address account, uint256 amount) external onlyMinter {\\n _mint(account, amount);\\n }\\n\\n // ========================== TREASURY ONLY FUNCTIONS ==========================\\n\\n /// @inheritdoc IAgToken\\n function addMinter(address minter) external onlyTreasury {\\n isMinter[minter] = true;\\n emit MinterToggled(minter);\\n }\\n\\n /// @inheritdoc IAgToken\\n function removeMinter(address minter) external {\\n if (msg.sender != address(treasury) && msg.sender != minter) revert InvalidSender();\\n isMinter[minter] = false;\\n emit MinterToggled(minter);\\n }\\n\\n /// @inheritdoc IAgToken\\n function setTreasury(address _treasury) external virtual onlyTreasury {\\n treasury = _treasury;\\n emit TreasuryUpdated(_treasury);\\n }\\n\\n // ============================= INTERNAL FUNCTION =============================\\n\\n /// @notice Internal version of the function `burnFromNoRedeem`\\n /// @param amount Amount to burn\\n /// @dev It is at the level of this function that allowance checks are performed\\n function _burnFromNoRedeem(uint256 amount, address burner, address sender) internal {\\n if (burner != sender) {\\n uint256 currentAllowance = allowance(burner, sender);\\n if (currentAllowance < amount) revert BurnAmountExceedsAllowance();\\n _approve(burner, sender, currentAllowance - amount);\\n }\\n _burn(burner, amount);\\n }\\n}\\n\",\"keccak256\":\"0x3a120df43d66baf21914de14312a36c51fb22d7d10b7ef704ff0ec847c128943\",\"license\":\"GPL-3.0\"},\"contracts/interfaces/IAgToken.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-3.0\\n\\npragma solidity ^0.8.12;\\n\\nimport \\\"@openzeppelin/contracts-upgradeable/token/ERC20/IERC20Upgradeable.sol\\\";\\n\\n/// @title IAgToken\\n/// @author Angle Labs, Inc.\\n/// @notice Interface for the stablecoins `AgToken` contracts\\n/// @dev This interface only contains functions of the `AgToken` contract which are called by other contracts\\n/// of this module or of the first module of the Angle Protocol\\ninterface IAgToken is IERC20Upgradeable {\\n // ======================= Minter Role Only Functions ===========================\\n\\n /// @notice Lets the `StableMaster` contract or another whitelisted contract mint agTokens\\n /// @param account Address to mint to\\n /// @param amount Amount to mint\\n /// @dev The contracts allowed to issue agTokens are the `StableMaster` contract, `VaultManager` contracts\\n /// associated to this stablecoin as well as the flash loan module (if activated) and potentially contracts\\n /// whitelisted by governance\\n function mint(address account, uint256 amount) external;\\n\\n /// @notice Burns `amount` tokens from a `burner` address after being asked to by `sender`\\n /// @param amount Amount of tokens to burn\\n /// @param burner Address to burn from\\n /// @param sender Address which requested the burn from `burner`\\n /// @dev This method is to be called by a contract with the minter right after being requested\\n /// to do so by a `sender` address willing to burn tokens from another `burner` address\\n /// @dev The method checks the allowance between the `sender` and the `burner`\\n function burnFrom(\\n uint256 amount,\\n address burner,\\n address sender\\n ) external;\\n\\n /// @notice Burns `amount` tokens from a `burner` address\\n /// @param amount Amount of tokens to burn\\n /// @param burner Address to burn from\\n /// @dev This method is to be called by a contract with a minter right on the AgToken after being\\n /// requested to do so by an address willing to burn tokens from its address\\n function burnSelf(uint256 amount, address burner) external;\\n\\n // ========================= Treasury Only Functions ===========================\\n\\n /// @notice Adds a minter in the contract\\n /// @param minter Minter address to add\\n /// @dev Zero address checks are performed directly in the `Treasury` contract\\n function addMinter(address minter) external;\\n\\n /// @notice Removes a minter from the contract\\n /// @param minter Minter address to remove\\n /// @dev This function can also be called by a minter wishing to revoke itself\\n function removeMinter(address minter) external;\\n\\n /// @notice Sets a new treasury contract\\n /// @param _treasury New treasury address\\n function setTreasury(address _treasury) external;\\n\\n // ========================= External functions ================================\\n\\n /// @notice Checks whether an address has the right to mint agTokens\\n /// @param minter Address for which the minting right should be checked\\n /// @return Whether the address has the right to mint agTokens or not\\n function isMinter(address minter) external view returns (bool);\\n\\n /// @notice Get the associated treasury\\n function treasury() external view returns (address);\\n}\\n\",\"keccak256\":\"0xd671dbd00b28a86b839fd455ada4d1ef9203694d06142be76853e00a91f80b5f\",\"license\":\"GPL-3.0\"},\"contracts/interfaces/ICoreBorrow.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-3.0\\n\\npragma solidity ^0.8.12;\\n\\n/// @title ICoreBorrow\\n/// @author Angle Labs, Inc.\\n/// @notice Interface for the `CoreBorrow` contract\\n/// @dev This interface only contains functions of the `CoreBorrow` contract which are called by other contracts\\n/// of this module\\ninterface ICoreBorrow {\\n /// @notice Checks if an address corresponds to a treasury of a stablecoin with a flash loan\\n /// module initialized on it\\n /// @param treasury Address to check\\n /// @return Whether the address has the `FLASHLOANER_TREASURY_ROLE` or not\\n function isFlashLoanerTreasury(address treasury) external view returns (bool);\\n\\n /// @notice Checks whether an address is governor of the Angle Protocol or not\\n /// @param admin Address to check\\n /// @return Whether the address has the `GOVERNOR_ROLE` or not\\n function isGovernor(address admin) external view returns (bool);\\n\\n /// @notice Checks whether an address is governor or a guardian of the Angle Protocol or not\\n /// @param admin Address to check\\n /// @return Whether the address has the `GUARDIAN_ROLE` or not\\n /// @dev Governance should make sure when adding a governor to also give this governor the guardian\\n /// role by calling the `addGovernor` function\\n function isGovernorOrGuardian(address admin) external view returns (bool);\\n}\\n\",\"keccak256\":\"0x10249210cbf522775f040baf981d7d037472168ce2746d87473ac7c29a34e62e\",\"license\":\"GPL-3.0\"},\"contracts/interfaces/IFlashAngle.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-3.0\\n\\npragma solidity ^0.8.12;\\n\\nimport \\\"./IAgToken.sol\\\";\\nimport \\\"./ICoreBorrow.sol\\\";\\n\\n/// @title IFlashAngle\\n/// @author Angle Labs, Inc.\\n/// @notice Interface for the `FlashAngle` contract\\n/// @dev This interface only contains functions of the contract which are called by other contracts\\n/// of this module\\ninterface IFlashAngle {\\n /// @notice Reference to the `CoreBorrow` contract managing the FlashLoan module\\n function core() external view returns (ICoreBorrow);\\n\\n /// @notice Sends the fees taken from flash loans to the treasury contract associated to the stablecoin\\n /// @param stablecoin Stablecoin from which profits should be sent\\n /// @return balance Amount of profits sent\\n /// @dev This function can only be called by the treasury contract\\n function accrueInterestToTreasury(IAgToken stablecoin) external returns (uint256 balance);\\n\\n /// @notice Adds support for a stablecoin\\n /// @param _treasury Treasury associated to the stablecoin to add support for\\n /// @dev This function can only be called by the `CoreBorrow` contract\\n function addStablecoinSupport(address _treasury) external;\\n\\n /// @notice Removes support for a stablecoin\\n /// @param _treasury Treasury associated to the stablecoin to remove support for\\n /// @dev This function can only be called by the `CoreBorrow` contract\\n function removeStablecoinSupport(address _treasury) external;\\n\\n /// @notice Sets a new core contract\\n /// @param _core Core contract address to set\\n /// @dev This function can only be called by the `CoreBorrow` contract\\n function setCore(address _core) external;\\n}\\n\",\"keccak256\":\"0x39b0097f695b9e934bccdc72676c91513f1077cc5d0fd151908fd25a7c5cfbe4\",\"license\":\"GPL-3.0\"},\"contracts/interfaces/ITreasury.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-3.0\\n\\npragma solidity ^0.8.12;\\n\\nimport \\\"./IAgToken.sol\\\";\\nimport \\\"./ICoreBorrow.sol\\\";\\nimport \\\"./IFlashAngle.sol\\\";\\n\\n/// @title ITreasury\\n/// @author Angle Labs, Inc.\\n/// @notice Interface for the `Treasury` contract\\n/// @dev This interface only contains functions of the `Treasury` which are called by other contracts\\n/// of this module\\ninterface ITreasury {\\n /// @notice Stablecoin handled by this `treasury` contract\\n function stablecoin() external view returns (IAgToken);\\n\\n /// @notice Checks whether a given address has the governor role\\n /// @param admin Address to check\\n /// @return Whether the address has the governor role\\n /// @dev Access control is only kept in the `CoreBorrow` contract\\n function isGovernor(address admin) external view returns (bool);\\n\\n /// @notice Checks whether a given address has the guardian or the governor role\\n /// @param admin Address to check\\n /// @return Whether the address has the guardian or the governor role\\n /// @dev Access control is only kept in the `CoreBorrow` contract which means that this function\\n /// queries the `CoreBorrow` contract\\n function isGovernorOrGuardian(address admin) external view returns (bool);\\n\\n /// @notice Checks whether a given address has well been initialized in this contract\\n /// as a `VaultManager`\\n /// @param _vaultManager Address to check\\n /// @return Whether the address has been initialized or not\\n function isVaultManager(address _vaultManager) external view returns (bool);\\n\\n /// @notice Sets a new flash loan module for this stablecoin\\n /// @param _flashLoanModule Reference to the new flash loan module\\n /// @dev This function removes the minting right to the old flash loan module and grants\\n /// it to the new module\\n function setFlashLoanModule(address _flashLoanModule) external;\\n}\\n\",\"keccak256\":\"0x624733dae1bfb98721ba994573aed10997f7448c893b791ed985300531c361fd\",\"license\":\"GPL-3.0\"}},\"version\":1}", - "bytecode": "0x60806040523480156200001157600080fd5b50600054610100900460ff1615808015620000335750600054600160ff909116105b8062000063575062000050306200013d60201b6200268a1760201c565b15801562000063575060005460ff166001145b620000cb5760405162461bcd60e51b815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201526d191e481a5b9a5d1a585b1a5e995960921b606482015260840160405180910390fd5b6000805460ff191660011790558015620000ef576000805461ff0019166101001790555b801562000136576000805461ff0019169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15b506200014c565b6001600160a01b03163b151590565b6146eb806200015c6000396000f3fe608060405234801561001057600080fd5b50600436106102ff5760003560e01c806361d027b31161019c5780639f48118f116100ee578063ced67f0c11610097578063dd62ed3e11610071578063dd62ed3e14610724578063e3e286551461076a578063f0f442601461077d57600080fd5b8063ced67f0c1461066b578063d44ad63f146106fe578063d505accf1461071157600080fd5b8063aa271e1a116100c8578063aa271e1a14610620578063ba330bd714610643578063cd4839ca1461065657600080fd5b80639f48118f146105ef578063a457c2d7146105fa578063a9059cbb1461060d57600080fd5b80637ecebe001161015057806395d89b411161012a57806395d89b41146105c1578063983b2d56146105c95780639e4e0dae146105dc57600080fd5b80637ecebe00146105705780638933fb791461058357806390218cff146105ae57600080fd5b80637334d020116101815780637334d020146105425780637d4c9c2d146105555780637d74e25f1461056857600080fd5b806361d027b3146104c757806370a082311461050c57600080fd5b80633092afd511610255578063395093511161020957806340c10f19116101e357806340c10f19146104815780634dc32fcc146104945780635bfbec96146104a757600080fd5b8063395093511461043b5780633a55f89d1461044e5780633f4218e01461046157600080fd5b8063350ebe041161023a578063350ebe041461040d5780633644e5151461042057806336db43b51461042857600080fd5b80633092afd5146103eb578063313ce567146103fe57600080fd5b8063151dd755116102b757806323b872dd1161029157806323b872dd146103b25780632b471d8e146103c55780632e403e14146103d857600080fd5b8063151dd7551461038057806318160ddd146103a15780632342fb0e146103a957600080fd5b80630919a951116102e85780630919a95114610337578063095ea7b31461034a5780631171bda91461036d57600080fd5b806306fdde0314610304578063077f224a14610322575b600080fd5b61030c610790565b6040516103199190613e63565b60405180910390f35b610335610330366004613fb0565b610822565b005b610335610345366004614028565b610832565b61035d610358366004614045565b610995565b6040519015158152602001610319565b61033561037b366004614071565b6109af565b61039361038e3660046140b2565b610b04565b604051908152602001610319565b603554610393565b61039360d25481565b61035d6103c0366004614071565b610dbe565b6103356103d33660046140e9565b610de2565b6103356103e6366004614028565b610e39565b6103356103f9366004614028565b6111e8565b60405160128152602001610319565b61033561041b366004614119565b6112d1565b610393611325565b610335610436366004614045565b611334565b61035d610449366004614045565b6114c4565b61033561045c366004614150565b611510565b61039361046f366004614028565b60d16020526000908152604090205481565b61033561048f366004614045565b611613565b6103936104a2366004614028565b611666565b6103936104b5366004614150565b60d36020526000908152604090205481565b60cd546104e79073ffffffffffffffffffffffffffffffffffffffff1681565b60405173ffffffffffffffffffffffffffffffffffffffff9091168152602001610319565b61039361051a366004614028565b73ffffffffffffffffffffffffffffffffffffffff1660009081526033602052604090205490565b610335610550366004614045565b6116ae565b610335610563366004614194565b611841565b610393611ba9565b61039361057e366004614028565b611bce565b610393610591366004614045565b60d060209081526000928352604080842090915290825290205481565b6103356105bc366004614150565b611bf9565b61030c611c06565b6103356105d7366004614028565b611c15565b6103356105ea3660046141f1565b611cdd565b610393633b9aca0081565b61035d610608366004614045565b611ee9565b61035d61061b366004614045565b611fbf565b61035d61062e366004614028565b60cc6020526000908152604090205460ff1681565b6104e7610651366004614150565b611fcd565b61065e612004565b6040516103199190614226565b6106c5610679366004614028565b60ce6020526000908152604090208054600182015460029092015490919067ffffffffffffffff81169060ff680100000000000000008204811691690100000000000000000090041685565b60408051958652602086019490945267ffffffffffffffff9092169284019290925290151560608301521515608082015260a001610319565b61039361070c3660046140b2565b612072565b61033561071f366004614280565b612237565b6103936107323660046142f7565b73ffffffffffffffffffffffffffffffffffffffff918216600090815260346020908152604080832093909416825291909152205490565b610335610778366004614028565b6123f6565b61033561078b366004614028565b6125ca565b60606036805461079f90614325565b80601f01602080910402602001604051908101604052809291908181526020018280546107cb90614325565b80156108185780601f106107ed57610100808354040283529160200191610818565b820191906000526020600020905b8154815290600101906020018083116107fb57829003601f168201915b5050505050905090565b61082d8383836126a6565b505050565b60cd546040517f521d4de900000000000000000000000000000000000000000000000000000000815233600482015273ffffffffffffffffffffffffffffffffffffffff9091169063521d4de990602401602060405180830381865afa1580156108a0573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906108c49190614372565b6108fa576040517f99e120bc00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff8116600090815260d1602052604081205461092b9060016143be565b73ffffffffffffffffffffffffffffffffffffffff8316600081815260d160205260409081902083905551919250907f979ef83e7e7a87cb48064e296dd7e997870d50f43acf8d7ad221313526c8ca0f906109899084815260200190565b60405180910390a25050565b6000336109a3818585612911565b60019150505b92915050565b60cd546040517fe43581b800000000000000000000000000000000000000000000000000000000815233600482015273ffffffffffffffffffffffffffffffffffffffff9091169063e43581b890602401602060405180830381865afa158015610a1d573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610a419190614372565b610a77576040517fee3675d400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b610a9873ffffffffffffffffffffffffffffffffffffffff84168383612abc565b8173ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff167ffff3b3844276f57024e0b42afec1a37f75db36511e43819a4f2a63ab7862b64883604051610af791815260200190565b60405180910390a3505050565b73ffffffffffffffffffffffffffffffffffffffff8316600090815260ce60209081526040808320815160a081018352815481526001820154938101939093526002015467ffffffffffffffff81169183019190915260ff680100000000000000008204811615801560608501526901000000000000000000909204161515608083015280610b94575080608001515b15610bcb576040517fc1ab6dc100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015260009073ffffffffffffffffffffffffffffffffffffffff8716906370a0823190602401602060405180830381865afa158015610c38573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610c5c91906143d1565b8251909150610c6b86836143ea565b1115610c93578151811015610c8e578151610c879082906143be565b9450610c93565b600094505b6000610ca1610e10426143fd565b73ffffffffffffffffffffffffffffffffffffffff8816600090815260d0602090815260408083208484528252909120549085015191925090610ce488836143ea565b1115610d0f5780846020015111610cfc576000610d0c565b808460200151610d0c91906143be565b96505b610d1987826143ea565b73ffffffffffffffffffffffffffffffffffffffff8916600081815260d060209081526040808320878452909152902091909155610d599033308a612b90565b33600090815260d16020526040812054889103610da657633b9aca00856040015167ffffffffffffffff1682610d8f9190614438565b610d9991906143fd565b610da390826143be565b90505b610db08782612bee565b9450505050505b9392505050565b600033610dcc858285612d0e565b610dd7858585612ddf565b506001949350505050565b33600090815260cc602052604090205460ff16610e2b576040517ff8d2906c00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b610e358183613092565b5050565b60cd546040517fe43581b800000000000000000000000000000000000000000000000000000000815233600482015273ffffffffffffffffffffffffffffffffffffffff9091169063e43581b890602401602060405180830381865afa158015610ea7573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610ecb9190614372565b610f01576040517fee3675d400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015273ffffffffffffffffffffffffffffffffffffffff8216906370a0823190602401602060405180830381865afa158015610f6b573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610f8f91906143d1565b15610fc6576040517f2ef630ec00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff8116600090815260ce602052604081208181556001810182905560020180547fffffffffffffffffffffffffffffffffffffffffffff0000000000000000000016905560cf54905b61102e6001836143be565b811015611139578273ffffffffffffffffffffffffffffffffffffffff1660cf828154811061105f5761105f61444f565b60009182526020909120015473ffffffffffffffffffffffffffffffffffffffff16036111295760cf6110936001846143be565b815481106110a3576110a361444f565b60009182526020909120015460cf805473ffffffffffffffffffffffffffffffffffffffff90921691839081106110dc576110dc61444f565b9060005260206000200160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550611139565b6111328161447e565b9050611023565b5060cf80548061114b5761114b6144b6565b60008281526020812082017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff90810180547fffffffffffffffffffffffff000000000000000000000000000000000000000016905590910190915560405173ffffffffffffffffffffffffffffffffffffffff8416917f5c95b49c4d59d97a2f044167723f29c74b30f99702e3fd406c3830160aa9ccb891a25050565b60cd5473ffffffffffffffffffffffffffffffffffffffff16331480159061122657503373ffffffffffffffffffffffffffffffffffffffff821614155b1561125d576040517fddb5de5e00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff8116600081815260cc602052604080822080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00169055517f98c15241d6c02bc5ee0b780e11b3ea737a2defd9d04877edbe9f9497065bd02f9190a250565b33600090815260cc602052604090205460ff1661131a576040517ff8d2906c00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b61082d83838361327f565b600061132f61333a565b905090565b60cd546040517f521d4de900000000000000000000000000000000000000000000000000000000815233600482015273ffffffffffffffffffffffffffffffffffffffff9091169063521d4de990602401602060405180830381865afa1580156113a2573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906113c69190614372565b6113fc576040517f99e120bc00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff8216600090815260ce602052604090206002015468010000000000000000900460ff1661146a576040517fc1ab6dc100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff8216600081815260ce602052604090819020839055517fe7b113fba37131b6396680a0c55790a697ec975e198ff8cfd89dac90a6379e61906109899084815260200190565b33600081815260346020908152604080832073ffffffffffffffffffffffffffffffffffffffff871684529091528120549091906109a3908290869061150b9087906143ea565b612911565b60cd546040517f521d4de900000000000000000000000000000000000000000000000000000000815233600482015273ffffffffffffffffffffffffffffffffffffffff9091169063521d4de990602401602060405180830381865afa15801561157e573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906115a29190614372565b6115d8576040517f99e120bc00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60d28190556040518181527fc3b69829afe2345596a02c8b587d41f796ba0094481d899e1b2e07b7532a1e219060200160405180910390a150565b33600090815260cc602052604090205460ff1661165c576040517ff8d2906c00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b610e358282612bee565b73ffffffffffffffffffffffffffffffffffffffff8116600090815260d06020526040812081611698610e10426143fd565b8152602001908152602001600020549050919050565b60cd546040517f521d4de900000000000000000000000000000000000000000000000000000000815233600482015273ffffffffffffffffffffffffffffffffffffffff9091169063521d4de990602401602060405180830381865afa15801561171c573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906117409190614372565b611776576040517f99e120bc00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff8216600090815260ce602052604090206002015468010000000000000000900460ff166117e4576040517fc1ab6dc100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff8216600081815260ce602052604090819020600101839055517fe13ac9338b2ee623233f83c1b3ceab16490fa3e3737fac7f0970d0830a9f4871906109899084815260200190565b60cd546040517fe43581b800000000000000000000000000000000000000000000000000000000815233600482015273ffffffffffffffffffffffffffffffffffffffff9091169063e43581b890602401602060405180830381865afa1580156118af573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906118d39190614372565b611909576040517fee3675d400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff8516600090815260ce602052604090206002015468010000000000000000900460ff1680611960575073ffffffffffffffffffffffffffffffffffffffff8516155b15611997576040517fc1ab6dc100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b633b9aca008267ffffffffffffffff1611156119df576040517feca1d2c600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040805160a08101825260008082526020820181905291810182905260608101829052608081019190915284815260208082018581528315156080840190815267ffffffffffffffff808716604080870191825260016060880181815273ffffffffffffffffffffffffffffffffffffffff8e16600081815260ce9099528389208a5181559751888401559351600290970180549151965115156901000000000000000000027fffffffffffffffffffffffffffffffffffffffffffff00ffffffffffffffffff97151568010000000000000000027fffffffffffffffffffffffffffffffffffffffffffffff000000000000000000909316989096169790971717949094169290921790935560cf805492830181559093527facb8d954e2cfef495862221e91bd7523613cf8808827cb33edfe4904cc51bf290180547fffffffffffffffffffffffff0000000000000000000000000000000000000000168217905590517f53087ff85d80a7671594bd2e86b92af22e0b3c2c441c8033bba7399b7b5cbe2390611b99908890889088908890938452602084019290925267ffffffffffffffff1660408301521515606082015260800190565b60405180910390a2505050505050565b600060d381611bba610e10426143fd565b815260200190815260200160002054905090565b73ffffffffffffffffffffffffffffffffffffffff81166000908152609960205260408120546109a9565b611c033382613092565b50565b60606037805461079f90614325565b60cd5473ffffffffffffffffffffffffffffffffffffffff163314611c66576040517fb90cdbb100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff8116600081815260cc602052604080822080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00166001179055517f98c15241d6c02bc5ee0b780e11b3ea737a2defd9d04877edbe9f9497065bd02f9190a250565b60cd546040517f521d4de900000000000000000000000000000000000000000000000000000000815233600482015273ffffffffffffffffffffffffffffffffffffffff9091169063521d4de990602401602060405180830381865afa158015611d4b573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611d6f9190614372565b611da5576040517f99e120bc00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff8216600090815260ce602052604090206002015468010000000000000000900460ff16611e13576040517fc1ab6dc100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b633b9aca008167ffffffffffffffff161115611e5b576040517feca1d2c600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff8216600081815260ce602090815260409182902060020180547fffffffffffffffffffffffffffffffffffffffffffffffff00000000000000001667ffffffffffffffff861690811790915591519182527f901f9de19b475adc8da4110434b8df940dce085afd05e2281c86807f3a899d299101610989565b33600081815260346020908152604080832073ffffffffffffffffffffffffffffffffffffffff8716845290915281205490919083811015611fb2576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602560248201527f45524332303a2064656372656173656420616c6c6f77616e63652062656c6f7760448201527f207a65726f00000000000000000000000000000000000000000000000000000060648201526084015b60405180910390fd5b610dd78286868403612911565b6000336109a3818585612ddf565b60cf8181548110611fdd57600080fd5b60009182526020909120015473ffffffffffffffffffffffffffffffffffffffff16905081565b606060cf80548060200260200160405190810160405280929190818152602001828054801561081857602002820191906000526020600020905b815473ffffffffffffffffffffffffffffffffffffffff16815260019091019060200180831161203e575050505050905090565b73ffffffffffffffffffffffffffffffffffffffff8316600090815260ce60209081526040808320815160a081018352815481526001820154938101939093526002015467ffffffffffffffff81169183019190915260ff680100000000000000008204811615801560608501526901000000000000000000909204161515608083015280612102575080608001515b15612139576040517fc1ab6dc100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000612147610e10426143fd565b600081815260d36020526040812054919250906121659087906143ea565b905060d2548111156121a3576040517f6d43d1ac00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600082815260d3602052604090208190556121be3387613092565b33600090815260d1602052604081205487910361220b57633b9aca00846040015167ffffffffffffffff16826121f49190614438565b6121fe91906143fd565b61220890826143be565b90505b61222c73ffffffffffffffffffffffffffffffffffffffff89168783612abc565b979650505050505050565b834211156122a1576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f45524332305065726d69743a206578706972656420646561646c696e650000006044820152606401611fa9565b60007f6e71edae12b1b97f4d1f60370fef10105fa2faae0126114a169c64845d6126c98888886122d08c6133b5565b60408051602081019690965273ffffffffffffffffffffffffffffffffffffffff94851690860152929091166060840152608083015260a082015260c0810186905260e0016040516020818303038152906040528051906020012090506000612338826133ea565b9050600061234882878787613453565b90508973ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16146123df576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601e60248201527f45524332305065726d69743a20696e76616c6964207369676e617475726500006044820152606401611fa9565b6123ea8a8a8a612911565b50505050505050505050565b60cd546040517f521d4de900000000000000000000000000000000000000000000000000000000815233600482015273ffffffffffffffffffffffffffffffffffffffff9091169063521d4de990602401602060405180830381865afa158015612464573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906124889190614372565b6124be576040517f99e120bc00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff8116600090815260ce602052604090206002015468010000000000000000900460ff1661252c576040517fc1ab6dc100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff8116600081815260ce602090815260409182902060020180547fffffffffffffffffffffffffffffffffffffffffffff00ffffffffffffffffff811669010000000000000000009182900460ff16801592830291909117909255925192835292917ff7c93079dcbf699749d66345a351afab7d24219bb1d915c9f4fc4cf03f00d3979101610989565b60cd5473ffffffffffffffffffffffffffffffffffffffff16331461261b576040517fb90cdbb100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60cd80547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83169081179091556040517f7dae230f18360d76a040c81f050aa14eb9d6dc7901b20fc5d855e2a20fe814d190600090a250565b73ffffffffffffffffffffffffffffffffffffffff163b151590565b600054610100900460ff16158080156126c65750600054600160ff909116105b806126e05750303b1580156126e0575060005460ff166001145b61276c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201527f647920696e697469616c697a65640000000000000000000000000000000000006064820152608401611fa9565b600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0016600117905580156127ca57600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff166101001790555b3073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1663e9cbd8226040518163ffffffff1660e01b8152600401602060405180830381865afa15801561282c573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061285091906144e5565b73ffffffffffffffffffffffffffffffffffffffff161461289d576040517f14bcf5c800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6128a884848461347b565b801561290b57600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15b50505050565b73ffffffffffffffffffffffffffffffffffffffff83166129b3576040517f08c379a0000000000000000000000000000000000000000000000000000000008152602060048201526024808201527f45524332303a20617070726f76652066726f6d20746865207a65726f2061646460448201527f72657373000000000000000000000000000000000000000000000000000000006064820152608401611fa9565b73ffffffffffffffffffffffffffffffffffffffff8216612a56576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602260248201527f45524332303a20617070726f766520746f20746865207a65726f20616464726560448201527f73730000000000000000000000000000000000000000000000000000000000006064820152608401611fa9565b73ffffffffffffffffffffffffffffffffffffffff83811660008181526034602090815260408083209487168084529482529182902085905590518481527f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b9259101610af7565b60405173ffffffffffffffffffffffffffffffffffffffff831660248201526044810182905261082d9084907fa9059cbb00000000000000000000000000000000000000000000000000000000906064015b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff00000000000000000000000000000000000000000000000000000000909316929092179091526134ff565b60405173ffffffffffffffffffffffffffffffffffffffff8085166024830152831660448201526064810182905261290b9085907f23b872dd0000000000000000000000000000000000000000000000000000000090608401612b0e565b73ffffffffffffffffffffffffffffffffffffffff8216612c6b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601f60248201527f45524332303a206d696e7420746f20746865207a65726f2061646472657373006044820152606401611fa9565b8060356000828254612c7d91906143ea565b909155505073ffffffffffffffffffffffffffffffffffffffff821660009081526033602052604081208054839290612cb79084906143ea565b909155505060405181815273ffffffffffffffffffffffffffffffffffffffff8316906000907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef9060200160405180910390a35050565b73ffffffffffffffffffffffffffffffffffffffff8381166000908152603460209081526040808320938616835292905220547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff811461290b5781811015612dd2576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f45524332303a20696e73756666696369656e7420616c6c6f77616e63650000006044820152606401611fa9565b61290b8484848403612911565b73ffffffffffffffffffffffffffffffffffffffff8316612e82576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602560248201527f45524332303a207472616e736665722066726f6d20746865207a65726f20616460448201527f64726573730000000000000000000000000000000000000000000000000000006064820152608401611fa9565b73ffffffffffffffffffffffffffffffffffffffff8216612f25576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602360248201527f45524332303a207472616e7366657220746f20746865207a65726f206164647260448201527f65737300000000000000000000000000000000000000000000000000000000006064820152608401611fa9565b73ffffffffffffffffffffffffffffffffffffffff831660009081526033602052604090205481811015612fdb576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f45524332303a207472616e7366657220616d6f756e742065786365656473206260448201527f616c616e636500000000000000000000000000000000000000000000000000006064820152608401611fa9565b73ffffffffffffffffffffffffffffffffffffffff80851660009081526033602052604080822085850390559185168152908120805484929061301f9084906143ea565b925050819055508273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef8460405161308591815260200190565b60405180910390a361290b565b73ffffffffffffffffffffffffffffffffffffffff8216613135576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602160248201527f45524332303a206275726e2066726f6d20746865207a65726f2061646472657360448201527f73000000000000000000000000000000000000000000000000000000000000006064820152608401611fa9565b73ffffffffffffffffffffffffffffffffffffffff8216600090815260336020526040902054818110156131eb576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602260248201527f45524332303a206275726e20616d6f756e7420657863656564732062616c616e60448201527f63650000000000000000000000000000000000000000000000000000000000006064820152608401611fa9565b73ffffffffffffffffffffffffffffffffffffffff831660009081526033602052604081208383039055603580548492906132279084906143be565b909155505060405182815260009073ffffffffffffffffffffffffffffffffffffffff8516907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef9060200160405180910390a3505050565b8073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff16146133305773ffffffffffffffffffffffffffffffffffffffff8281166000908152603460209081526040808320938516835292905220548381101561331f576040517f715ec26c00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b61332e838361150b87856143be565b505b61082d8284613092565b600061132f7f8b73c3c69bb8fe3d512ecc4cf759cc79239f7b179b0ffacaa9a75d522b39400f61336960655490565b6066546040805160208101859052908101839052606081018290524660808201523060a082015260009060c0016040516020818303038152906040528051906020012090509392505050565b73ffffffffffffffffffffffffffffffffffffffff811660009081526099602052604090208054600181018255905b50919050565b60006109a96133f761333a565b836040517f19010000000000000000000000000000000000000000000000000000000000006020820152602281018390526042810182905260009060620160405160208183030381529060405280519060200120905092915050565b60008060006134648787878761360b565b9150915061347181613723565b5095945050505050565b61348483613977565b61348e8383613a4d565b60cd80547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83169081179091556040517f7dae230f18360d76a040c81f050aa14eb9d6dc7901b20fc5d855e2a20fe814d190600090a2505050565b6000613561826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c65648152508573ffffffffffffffffffffffffffffffffffffffff16613aee9092919063ffffffff16565b80519091501561082d578080602001905181019061357f9190614372565b61082d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e60448201527f6f742073756363656564000000000000000000000000000000000000000000006064820152608401611fa9565b6000807f7fffffffffffffffffffffffffffffff5d576e7357a4501ddfe92f46681b20a0831115613642575060009050600361371a565b8460ff16601b1415801561365a57508460ff16601c14155b1561366b575060009050600461371a565b6040805160008082526020820180845289905260ff881692820192909252606081018690526080810185905260019060a0016020604051602081039080840390855afa1580156136bf573d6000803e3d6000fd5b50506040517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0015191505073ffffffffffffffffffffffffffffffffffffffff81166137135760006001925092505061371a565b9150600090505b94509492505050565b600081600481111561373757613737614502565b0361373f5750565b600181600481111561375357613753614502565b036137ba576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601860248201527f45434453413a20696e76616c6964207369676e617475726500000000000000006044820152606401611fa9565b60028160048111156137ce576137ce614502565b03613835576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601f60248201527f45434453413a20696e76616c6964207369676e6174757265206c656e677468006044820152606401611fa9565b600381600481111561384957613849614502565b036138d6576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602260248201527f45434453413a20696e76616c6964207369676e6174757265202773272076616c60448201527f75650000000000000000000000000000000000000000000000000000000000006064820152608401611fa9565b60048160048111156138ea576138ea614502565b03611c03576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602260248201527f45434453413a20696e76616c6964207369676e6174757265202776272076616c60448201527f75650000000000000000000000000000000000000000000000000000000000006064820152608401611fa9565b600054610100900460ff16613a0e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201527f6e697469616c697a696e670000000000000000000000000000000000000000006064820152608401611fa9565b611c03816040518060400160405280600181526020017f3100000000000000000000000000000000000000000000000000000000000000815250613b05565b600054610100900460ff16613ae4576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201527f6e697469616c697a696e670000000000000000000000000000000000000000006064820152608401611fa9565b610e358282613bb6565b6060613afd8484600085613c66565b949350505050565b600054610100900460ff16613b9c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201527f6e697469616c697a696e670000000000000000000000000000000000000000006064820152608401611fa9565b815160209283012081519190920120606591909155606655565b600054610100900460ff16613c4d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201527f6e697469616c697a696e670000000000000000000000000000000000000000006064820152608401611fa9565b6036613c59838261457f565b50603761082d828261457f565b606082471015613cf8576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f60448201527f722063616c6c00000000000000000000000000000000000000000000000000006064820152608401611fa9565b73ffffffffffffffffffffffffffffffffffffffff85163b613d76576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006044820152606401611fa9565b6000808673ffffffffffffffffffffffffffffffffffffffff168587604051613d9f9190614699565b60006040518083038185875af1925050503d8060008114613ddc576040519150601f19603f3d011682016040523d82523d6000602084013e613de1565b606091505b509150915061222c82828660608315613dfb575081610db7565b825115613e0b5782518084602001fd5b816040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611fa99190613e63565b60005b83811015613e5a578181015183820152602001613e42565b50506000910152565b6020815260008251806020840152613e82816040850160208701613e3f565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169190910160400192915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b600082601f830112613ef457600080fd5b813567ffffffffffffffff80821115613f0f57613f0f613eb4565b604051601f83017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0908116603f01168101908282118183101715613f5557613f55613eb4565b81604052838152866020858801011115613f6e57600080fd5b836020870160208301376000602085830101528094505050505092915050565b73ffffffffffffffffffffffffffffffffffffffff81168114611c0357600080fd5b600080600060608486031215613fc557600080fd5b833567ffffffffffffffff80821115613fdd57600080fd5b613fe987838801613ee3565b94506020860135915080821115613fff57600080fd5b5061400c86828701613ee3565b925050604084013561401d81613f8e565b809150509250925092565b60006020828403121561403a57600080fd5b8135610db781613f8e565b6000806040838503121561405857600080fd5b823561406381613f8e565b946020939093013593505050565b60008060006060848603121561408657600080fd5b833561409181613f8e565b925060208401356140a181613f8e565b929592945050506040919091013590565b6000806000606084860312156140c757600080fd5b83356140d281613f8e565b925060208401359150604084013561401d81613f8e565b600080604083850312156140fc57600080fd5b82359150602083013561410e81613f8e565b809150509250929050565b60008060006060848603121561412e57600080fd5b83359250602084013561414081613f8e565b9150604084013561401d81613f8e565b60006020828403121561416257600080fd5b5035919050565b803567ffffffffffffffff8116811461418157600080fd5b919050565b8015158114611c0357600080fd5b600080600080600060a086880312156141ac57600080fd5b85356141b781613f8e565b945060208601359350604086013592506141d360608701614169565b915060808601356141e381614186565b809150509295509295909350565b6000806040838503121561420457600080fd5b823561420f81613f8e565b915061421d60208401614169565b90509250929050565b6020808252825182820181905260009190848201906040850190845b8181101561427457835173ffffffffffffffffffffffffffffffffffffffff1683529284019291840191600101614242565b50909695505050505050565b600080600080600080600060e0888a03121561429b57600080fd5b87356142a681613f8e565b965060208801356142b681613f8e565b95506040880135945060608801359350608088013560ff811681146142da57600080fd5b9699959850939692959460a0840135945060c09093013592915050565b6000806040838503121561430a57600080fd5b823561431581613f8e565b9150602083013561410e81613f8e565b600181811c9082168061433957607f821691505b6020821081036133e4577f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b60006020828403121561438457600080fd5b8151610db781614186565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b818103818111156109a9576109a961438f565b6000602082840312156143e357600080fd5b5051919050565b808201808211156109a9576109a961438f565b600082614433577f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b500490565b80820281158282048414176109a9576109a961438f565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82036144af576144af61438f565b5060010190565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603160045260246000fd5b6000602082840312156144f757600080fd5b8151610db781613f8e565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b601f82111561082d57600081815260208120601f850160051c810160208610156145585750805b601f850160051c820191505b8181101561457757828155600101614564565b505050505050565b815167ffffffffffffffff81111561459957614599613eb4565b6145ad816145a78454614325565b84614531565b602080601f83116001811461460057600084156145ca5750858301515b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600386901b1c1916600185901b178555614577565b6000858152602081207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08616915b8281101561464d5788860151825594840194600190910190840161462e565b508582101561468957878501517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600388901b60f8161c191681555b5050505050600190811b01905550565b600082516146ab818460208701613e3f565b919091019291505056fea26469706673582212204ab762f428941cadd300d875bf277cb0f7dff52a487fb7282a657f3da537ca0564736f6c63430008110033", - "deployedBytecode": "0x608060405234801561001057600080fd5b50600436106102ff5760003560e01c806361d027b31161019c5780639f48118f116100ee578063ced67f0c11610097578063dd62ed3e11610071578063dd62ed3e14610724578063e3e286551461076a578063f0f442601461077d57600080fd5b8063ced67f0c1461066b578063d44ad63f146106fe578063d505accf1461071157600080fd5b8063aa271e1a116100c8578063aa271e1a14610620578063ba330bd714610643578063cd4839ca1461065657600080fd5b80639f48118f146105ef578063a457c2d7146105fa578063a9059cbb1461060d57600080fd5b80637ecebe001161015057806395d89b411161012a57806395d89b41146105c1578063983b2d56146105c95780639e4e0dae146105dc57600080fd5b80637ecebe00146105705780638933fb791461058357806390218cff146105ae57600080fd5b80637334d020116101815780637334d020146105425780637d4c9c2d146105555780637d74e25f1461056857600080fd5b806361d027b3146104c757806370a082311461050c57600080fd5b80633092afd511610255578063395093511161020957806340c10f19116101e357806340c10f19146104815780634dc32fcc146104945780635bfbec96146104a757600080fd5b8063395093511461043b5780633a55f89d1461044e5780633f4218e01461046157600080fd5b8063350ebe041161023a578063350ebe041461040d5780633644e5151461042057806336db43b51461042857600080fd5b80633092afd5146103eb578063313ce567146103fe57600080fd5b8063151dd755116102b757806323b872dd1161029157806323b872dd146103b25780632b471d8e146103c55780632e403e14146103d857600080fd5b8063151dd7551461038057806318160ddd146103a15780632342fb0e146103a957600080fd5b80630919a951116102e85780630919a95114610337578063095ea7b31461034a5780631171bda91461036d57600080fd5b806306fdde0314610304578063077f224a14610322575b600080fd5b61030c610790565b6040516103199190613e63565b60405180910390f35b610335610330366004613fb0565b610822565b005b610335610345366004614028565b610832565b61035d610358366004614045565b610995565b6040519015158152602001610319565b61033561037b366004614071565b6109af565b61039361038e3660046140b2565b610b04565b604051908152602001610319565b603554610393565b61039360d25481565b61035d6103c0366004614071565b610dbe565b6103356103d33660046140e9565b610de2565b6103356103e6366004614028565b610e39565b6103356103f9366004614028565b6111e8565b60405160128152602001610319565b61033561041b366004614119565b6112d1565b610393611325565b610335610436366004614045565b611334565b61035d610449366004614045565b6114c4565b61033561045c366004614150565b611510565b61039361046f366004614028565b60d16020526000908152604090205481565b61033561048f366004614045565b611613565b6103936104a2366004614028565b611666565b6103936104b5366004614150565b60d36020526000908152604090205481565b60cd546104e79073ffffffffffffffffffffffffffffffffffffffff1681565b60405173ffffffffffffffffffffffffffffffffffffffff9091168152602001610319565b61039361051a366004614028565b73ffffffffffffffffffffffffffffffffffffffff1660009081526033602052604090205490565b610335610550366004614045565b6116ae565b610335610563366004614194565b611841565b610393611ba9565b61039361057e366004614028565b611bce565b610393610591366004614045565b60d060209081526000928352604080842090915290825290205481565b6103356105bc366004614150565b611bf9565b61030c611c06565b6103356105d7366004614028565b611c15565b6103356105ea3660046141f1565b611cdd565b610393633b9aca0081565b61035d610608366004614045565b611ee9565b61035d61061b366004614045565b611fbf565b61035d61062e366004614028565b60cc6020526000908152604090205460ff1681565b6104e7610651366004614150565b611fcd565b61065e612004565b6040516103199190614226565b6106c5610679366004614028565b60ce6020526000908152604090208054600182015460029092015490919067ffffffffffffffff81169060ff680100000000000000008204811691690100000000000000000090041685565b60408051958652602086019490945267ffffffffffffffff9092169284019290925290151560608301521515608082015260a001610319565b61039361070c3660046140b2565b612072565b61033561071f366004614280565b612237565b6103936107323660046142f7565b73ffffffffffffffffffffffffffffffffffffffff918216600090815260346020908152604080832093909416825291909152205490565b610335610778366004614028565b6123f6565b61033561078b366004614028565b6125ca565b60606036805461079f90614325565b80601f01602080910402602001604051908101604052809291908181526020018280546107cb90614325565b80156108185780601f106107ed57610100808354040283529160200191610818565b820191906000526020600020905b8154815290600101906020018083116107fb57829003601f168201915b5050505050905090565b61082d8383836126a6565b505050565b60cd546040517f521d4de900000000000000000000000000000000000000000000000000000000815233600482015273ffffffffffffffffffffffffffffffffffffffff9091169063521d4de990602401602060405180830381865afa1580156108a0573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906108c49190614372565b6108fa576040517f99e120bc00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff8116600090815260d1602052604081205461092b9060016143be565b73ffffffffffffffffffffffffffffffffffffffff8316600081815260d160205260409081902083905551919250907f979ef83e7e7a87cb48064e296dd7e997870d50f43acf8d7ad221313526c8ca0f906109899084815260200190565b60405180910390a25050565b6000336109a3818585612911565b60019150505b92915050565b60cd546040517fe43581b800000000000000000000000000000000000000000000000000000000815233600482015273ffffffffffffffffffffffffffffffffffffffff9091169063e43581b890602401602060405180830381865afa158015610a1d573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610a419190614372565b610a77576040517fee3675d400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b610a9873ffffffffffffffffffffffffffffffffffffffff84168383612abc565b8173ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff167ffff3b3844276f57024e0b42afec1a37f75db36511e43819a4f2a63ab7862b64883604051610af791815260200190565b60405180910390a3505050565b73ffffffffffffffffffffffffffffffffffffffff8316600090815260ce60209081526040808320815160a081018352815481526001820154938101939093526002015467ffffffffffffffff81169183019190915260ff680100000000000000008204811615801560608501526901000000000000000000909204161515608083015280610b94575080608001515b15610bcb576040517fc1ab6dc100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015260009073ffffffffffffffffffffffffffffffffffffffff8716906370a0823190602401602060405180830381865afa158015610c38573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610c5c91906143d1565b8251909150610c6b86836143ea565b1115610c93578151811015610c8e578151610c879082906143be565b9450610c93565b600094505b6000610ca1610e10426143fd565b73ffffffffffffffffffffffffffffffffffffffff8816600090815260d0602090815260408083208484528252909120549085015191925090610ce488836143ea565b1115610d0f5780846020015111610cfc576000610d0c565b808460200151610d0c91906143be565b96505b610d1987826143ea565b73ffffffffffffffffffffffffffffffffffffffff8916600081815260d060209081526040808320878452909152902091909155610d599033308a612b90565b33600090815260d16020526040812054889103610da657633b9aca00856040015167ffffffffffffffff1682610d8f9190614438565b610d9991906143fd565b610da390826143be565b90505b610db08782612bee565b9450505050505b9392505050565b600033610dcc858285612d0e565b610dd7858585612ddf565b506001949350505050565b33600090815260cc602052604090205460ff16610e2b576040517ff8d2906c00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b610e358183613092565b5050565b60cd546040517fe43581b800000000000000000000000000000000000000000000000000000000815233600482015273ffffffffffffffffffffffffffffffffffffffff9091169063e43581b890602401602060405180830381865afa158015610ea7573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610ecb9190614372565b610f01576040517fee3675d400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015273ffffffffffffffffffffffffffffffffffffffff8216906370a0823190602401602060405180830381865afa158015610f6b573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610f8f91906143d1565b15610fc6576040517f2ef630ec00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff8116600090815260ce602052604081208181556001810182905560020180547fffffffffffffffffffffffffffffffffffffffffffff0000000000000000000016905560cf54905b61102e6001836143be565b811015611139578273ffffffffffffffffffffffffffffffffffffffff1660cf828154811061105f5761105f61444f565b60009182526020909120015473ffffffffffffffffffffffffffffffffffffffff16036111295760cf6110936001846143be565b815481106110a3576110a361444f565b60009182526020909120015460cf805473ffffffffffffffffffffffffffffffffffffffff90921691839081106110dc576110dc61444f565b9060005260206000200160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550611139565b6111328161447e565b9050611023565b5060cf80548061114b5761114b6144b6565b60008281526020812082017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff90810180547fffffffffffffffffffffffff000000000000000000000000000000000000000016905590910190915560405173ffffffffffffffffffffffffffffffffffffffff8416917f5c95b49c4d59d97a2f044167723f29c74b30f99702e3fd406c3830160aa9ccb891a25050565b60cd5473ffffffffffffffffffffffffffffffffffffffff16331480159061122657503373ffffffffffffffffffffffffffffffffffffffff821614155b1561125d576040517fddb5de5e00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff8116600081815260cc602052604080822080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00169055517f98c15241d6c02bc5ee0b780e11b3ea737a2defd9d04877edbe9f9497065bd02f9190a250565b33600090815260cc602052604090205460ff1661131a576040517ff8d2906c00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b61082d83838361327f565b600061132f61333a565b905090565b60cd546040517f521d4de900000000000000000000000000000000000000000000000000000000815233600482015273ffffffffffffffffffffffffffffffffffffffff9091169063521d4de990602401602060405180830381865afa1580156113a2573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906113c69190614372565b6113fc576040517f99e120bc00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff8216600090815260ce602052604090206002015468010000000000000000900460ff1661146a576040517fc1ab6dc100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff8216600081815260ce602052604090819020839055517fe7b113fba37131b6396680a0c55790a697ec975e198ff8cfd89dac90a6379e61906109899084815260200190565b33600081815260346020908152604080832073ffffffffffffffffffffffffffffffffffffffff871684529091528120549091906109a3908290869061150b9087906143ea565b612911565b60cd546040517f521d4de900000000000000000000000000000000000000000000000000000000815233600482015273ffffffffffffffffffffffffffffffffffffffff9091169063521d4de990602401602060405180830381865afa15801561157e573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906115a29190614372565b6115d8576040517f99e120bc00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60d28190556040518181527fc3b69829afe2345596a02c8b587d41f796ba0094481d899e1b2e07b7532a1e219060200160405180910390a150565b33600090815260cc602052604090205460ff1661165c576040517ff8d2906c00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b610e358282612bee565b73ffffffffffffffffffffffffffffffffffffffff8116600090815260d06020526040812081611698610e10426143fd565b8152602001908152602001600020549050919050565b60cd546040517f521d4de900000000000000000000000000000000000000000000000000000000815233600482015273ffffffffffffffffffffffffffffffffffffffff9091169063521d4de990602401602060405180830381865afa15801561171c573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906117409190614372565b611776576040517f99e120bc00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff8216600090815260ce602052604090206002015468010000000000000000900460ff166117e4576040517fc1ab6dc100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff8216600081815260ce602052604090819020600101839055517fe13ac9338b2ee623233f83c1b3ceab16490fa3e3737fac7f0970d0830a9f4871906109899084815260200190565b60cd546040517fe43581b800000000000000000000000000000000000000000000000000000000815233600482015273ffffffffffffffffffffffffffffffffffffffff9091169063e43581b890602401602060405180830381865afa1580156118af573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906118d39190614372565b611909576040517fee3675d400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff8516600090815260ce602052604090206002015468010000000000000000900460ff1680611960575073ffffffffffffffffffffffffffffffffffffffff8516155b15611997576040517fc1ab6dc100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b633b9aca008267ffffffffffffffff1611156119df576040517feca1d2c600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040805160a08101825260008082526020820181905291810182905260608101829052608081019190915284815260208082018581528315156080840190815267ffffffffffffffff808716604080870191825260016060880181815273ffffffffffffffffffffffffffffffffffffffff8e16600081815260ce9099528389208a5181559751888401559351600290970180549151965115156901000000000000000000027fffffffffffffffffffffffffffffffffffffffffffff00ffffffffffffffffff97151568010000000000000000027fffffffffffffffffffffffffffffffffffffffffffffff000000000000000000909316989096169790971717949094169290921790935560cf805492830181559093527facb8d954e2cfef495862221e91bd7523613cf8808827cb33edfe4904cc51bf290180547fffffffffffffffffffffffff0000000000000000000000000000000000000000168217905590517f53087ff85d80a7671594bd2e86b92af22e0b3c2c441c8033bba7399b7b5cbe2390611b99908890889088908890938452602084019290925267ffffffffffffffff1660408301521515606082015260800190565b60405180910390a2505050505050565b600060d381611bba610e10426143fd565b815260200190815260200160002054905090565b73ffffffffffffffffffffffffffffffffffffffff81166000908152609960205260408120546109a9565b611c033382613092565b50565b60606037805461079f90614325565b60cd5473ffffffffffffffffffffffffffffffffffffffff163314611c66576040517fb90cdbb100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff8116600081815260cc602052604080822080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00166001179055517f98c15241d6c02bc5ee0b780e11b3ea737a2defd9d04877edbe9f9497065bd02f9190a250565b60cd546040517f521d4de900000000000000000000000000000000000000000000000000000000815233600482015273ffffffffffffffffffffffffffffffffffffffff9091169063521d4de990602401602060405180830381865afa158015611d4b573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611d6f9190614372565b611da5576040517f99e120bc00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff8216600090815260ce602052604090206002015468010000000000000000900460ff16611e13576040517fc1ab6dc100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b633b9aca008167ffffffffffffffff161115611e5b576040517feca1d2c600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff8216600081815260ce602090815260409182902060020180547fffffffffffffffffffffffffffffffffffffffffffffffff00000000000000001667ffffffffffffffff861690811790915591519182527f901f9de19b475adc8da4110434b8df940dce085afd05e2281c86807f3a899d299101610989565b33600081815260346020908152604080832073ffffffffffffffffffffffffffffffffffffffff8716845290915281205490919083811015611fb2576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602560248201527f45524332303a2064656372656173656420616c6c6f77616e63652062656c6f7760448201527f207a65726f00000000000000000000000000000000000000000000000000000060648201526084015b60405180910390fd5b610dd78286868403612911565b6000336109a3818585612ddf565b60cf8181548110611fdd57600080fd5b60009182526020909120015473ffffffffffffffffffffffffffffffffffffffff16905081565b606060cf80548060200260200160405190810160405280929190818152602001828054801561081857602002820191906000526020600020905b815473ffffffffffffffffffffffffffffffffffffffff16815260019091019060200180831161203e575050505050905090565b73ffffffffffffffffffffffffffffffffffffffff8316600090815260ce60209081526040808320815160a081018352815481526001820154938101939093526002015467ffffffffffffffff81169183019190915260ff680100000000000000008204811615801560608501526901000000000000000000909204161515608083015280612102575080608001515b15612139576040517fc1ab6dc100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000612147610e10426143fd565b600081815260d36020526040812054919250906121659087906143ea565b905060d2548111156121a3576040517f6d43d1ac00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600082815260d3602052604090208190556121be3387613092565b33600090815260d1602052604081205487910361220b57633b9aca00846040015167ffffffffffffffff16826121f49190614438565b6121fe91906143fd565b61220890826143be565b90505b61222c73ffffffffffffffffffffffffffffffffffffffff89168783612abc565b979650505050505050565b834211156122a1576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f45524332305065726d69743a206578706972656420646561646c696e650000006044820152606401611fa9565b60007f6e71edae12b1b97f4d1f60370fef10105fa2faae0126114a169c64845d6126c98888886122d08c6133b5565b60408051602081019690965273ffffffffffffffffffffffffffffffffffffffff94851690860152929091166060840152608083015260a082015260c0810186905260e0016040516020818303038152906040528051906020012090506000612338826133ea565b9050600061234882878787613453565b90508973ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16146123df576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601e60248201527f45524332305065726d69743a20696e76616c6964207369676e617475726500006044820152606401611fa9565b6123ea8a8a8a612911565b50505050505050505050565b60cd546040517f521d4de900000000000000000000000000000000000000000000000000000000815233600482015273ffffffffffffffffffffffffffffffffffffffff9091169063521d4de990602401602060405180830381865afa158015612464573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906124889190614372565b6124be576040517f99e120bc00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff8116600090815260ce602052604090206002015468010000000000000000900460ff1661252c576040517fc1ab6dc100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff8116600081815260ce602090815260409182902060020180547fffffffffffffffffffffffffffffffffffffffffffff00ffffffffffffffffff811669010000000000000000009182900460ff16801592830291909117909255925192835292917ff7c93079dcbf699749d66345a351afab7d24219bb1d915c9f4fc4cf03f00d3979101610989565b60cd5473ffffffffffffffffffffffffffffffffffffffff16331461261b576040517fb90cdbb100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60cd80547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83169081179091556040517f7dae230f18360d76a040c81f050aa14eb9d6dc7901b20fc5d855e2a20fe814d190600090a250565b73ffffffffffffffffffffffffffffffffffffffff163b151590565b600054610100900460ff16158080156126c65750600054600160ff909116105b806126e05750303b1580156126e0575060005460ff166001145b61276c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201527f647920696e697469616c697a65640000000000000000000000000000000000006064820152608401611fa9565b600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0016600117905580156127ca57600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff166101001790555b3073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1663e9cbd8226040518163ffffffff1660e01b8152600401602060405180830381865afa15801561282c573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061285091906144e5565b73ffffffffffffffffffffffffffffffffffffffff161461289d576040517f14bcf5c800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6128a884848461347b565b801561290b57600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15b50505050565b73ffffffffffffffffffffffffffffffffffffffff83166129b3576040517f08c379a0000000000000000000000000000000000000000000000000000000008152602060048201526024808201527f45524332303a20617070726f76652066726f6d20746865207a65726f2061646460448201527f72657373000000000000000000000000000000000000000000000000000000006064820152608401611fa9565b73ffffffffffffffffffffffffffffffffffffffff8216612a56576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602260248201527f45524332303a20617070726f766520746f20746865207a65726f20616464726560448201527f73730000000000000000000000000000000000000000000000000000000000006064820152608401611fa9565b73ffffffffffffffffffffffffffffffffffffffff83811660008181526034602090815260408083209487168084529482529182902085905590518481527f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b9259101610af7565b60405173ffffffffffffffffffffffffffffffffffffffff831660248201526044810182905261082d9084907fa9059cbb00000000000000000000000000000000000000000000000000000000906064015b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff00000000000000000000000000000000000000000000000000000000909316929092179091526134ff565b60405173ffffffffffffffffffffffffffffffffffffffff8085166024830152831660448201526064810182905261290b9085907f23b872dd0000000000000000000000000000000000000000000000000000000090608401612b0e565b73ffffffffffffffffffffffffffffffffffffffff8216612c6b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601f60248201527f45524332303a206d696e7420746f20746865207a65726f2061646472657373006044820152606401611fa9565b8060356000828254612c7d91906143ea565b909155505073ffffffffffffffffffffffffffffffffffffffff821660009081526033602052604081208054839290612cb79084906143ea565b909155505060405181815273ffffffffffffffffffffffffffffffffffffffff8316906000907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef9060200160405180910390a35050565b73ffffffffffffffffffffffffffffffffffffffff8381166000908152603460209081526040808320938616835292905220547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff811461290b5781811015612dd2576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f45524332303a20696e73756666696369656e7420616c6c6f77616e63650000006044820152606401611fa9565b61290b8484848403612911565b73ffffffffffffffffffffffffffffffffffffffff8316612e82576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602560248201527f45524332303a207472616e736665722066726f6d20746865207a65726f20616460448201527f64726573730000000000000000000000000000000000000000000000000000006064820152608401611fa9565b73ffffffffffffffffffffffffffffffffffffffff8216612f25576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602360248201527f45524332303a207472616e7366657220746f20746865207a65726f206164647260448201527f65737300000000000000000000000000000000000000000000000000000000006064820152608401611fa9565b73ffffffffffffffffffffffffffffffffffffffff831660009081526033602052604090205481811015612fdb576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f45524332303a207472616e7366657220616d6f756e742065786365656473206260448201527f616c616e636500000000000000000000000000000000000000000000000000006064820152608401611fa9565b73ffffffffffffffffffffffffffffffffffffffff80851660009081526033602052604080822085850390559185168152908120805484929061301f9084906143ea565b925050819055508273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef8460405161308591815260200190565b60405180910390a361290b565b73ffffffffffffffffffffffffffffffffffffffff8216613135576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602160248201527f45524332303a206275726e2066726f6d20746865207a65726f2061646472657360448201527f73000000000000000000000000000000000000000000000000000000000000006064820152608401611fa9565b73ffffffffffffffffffffffffffffffffffffffff8216600090815260336020526040902054818110156131eb576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602260248201527f45524332303a206275726e20616d6f756e7420657863656564732062616c616e60448201527f63650000000000000000000000000000000000000000000000000000000000006064820152608401611fa9565b73ffffffffffffffffffffffffffffffffffffffff831660009081526033602052604081208383039055603580548492906132279084906143be565b909155505060405182815260009073ffffffffffffffffffffffffffffffffffffffff8516907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef9060200160405180910390a3505050565b8073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff16146133305773ffffffffffffffffffffffffffffffffffffffff8281166000908152603460209081526040808320938516835292905220548381101561331f576040517f715ec26c00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b61332e838361150b87856143be565b505b61082d8284613092565b600061132f7f8b73c3c69bb8fe3d512ecc4cf759cc79239f7b179b0ffacaa9a75d522b39400f61336960655490565b6066546040805160208101859052908101839052606081018290524660808201523060a082015260009060c0016040516020818303038152906040528051906020012090509392505050565b73ffffffffffffffffffffffffffffffffffffffff811660009081526099602052604090208054600181018255905b50919050565b60006109a96133f761333a565b836040517f19010000000000000000000000000000000000000000000000000000000000006020820152602281018390526042810182905260009060620160405160208183030381529060405280519060200120905092915050565b60008060006134648787878761360b565b9150915061347181613723565b5095945050505050565b61348483613977565b61348e8383613a4d565b60cd80547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83169081179091556040517f7dae230f18360d76a040c81f050aa14eb9d6dc7901b20fc5d855e2a20fe814d190600090a2505050565b6000613561826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c65648152508573ffffffffffffffffffffffffffffffffffffffff16613aee9092919063ffffffff16565b80519091501561082d578080602001905181019061357f9190614372565b61082d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e60448201527f6f742073756363656564000000000000000000000000000000000000000000006064820152608401611fa9565b6000807f7fffffffffffffffffffffffffffffff5d576e7357a4501ddfe92f46681b20a0831115613642575060009050600361371a565b8460ff16601b1415801561365a57508460ff16601c14155b1561366b575060009050600461371a565b6040805160008082526020820180845289905260ff881692820192909252606081018690526080810185905260019060a0016020604051602081039080840390855afa1580156136bf573d6000803e3d6000fd5b50506040517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0015191505073ffffffffffffffffffffffffffffffffffffffff81166137135760006001925092505061371a565b9150600090505b94509492505050565b600081600481111561373757613737614502565b0361373f5750565b600181600481111561375357613753614502565b036137ba576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601860248201527f45434453413a20696e76616c6964207369676e617475726500000000000000006044820152606401611fa9565b60028160048111156137ce576137ce614502565b03613835576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601f60248201527f45434453413a20696e76616c6964207369676e6174757265206c656e677468006044820152606401611fa9565b600381600481111561384957613849614502565b036138d6576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602260248201527f45434453413a20696e76616c6964207369676e6174757265202773272076616c60448201527f75650000000000000000000000000000000000000000000000000000000000006064820152608401611fa9565b60048160048111156138ea576138ea614502565b03611c03576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602260248201527f45434453413a20696e76616c6964207369676e6174757265202776272076616c60448201527f75650000000000000000000000000000000000000000000000000000000000006064820152608401611fa9565b600054610100900460ff16613a0e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201527f6e697469616c697a696e670000000000000000000000000000000000000000006064820152608401611fa9565b611c03816040518060400160405280600181526020017f3100000000000000000000000000000000000000000000000000000000000000815250613b05565b600054610100900460ff16613ae4576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201527f6e697469616c697a696e670000000000000000000000000000000000000000006064820152608401611fa9565b610e358282613bb6565b6060613afd8484600085613c66565b949350505050565b600054610100900460ff16613b9c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201527f6e697469616c697a696e670000000000000000000000000000000000000000006064820152608401611fa9565b815160209283012081519190920120606591909155606655565b600054610100900460ff16613c4d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201527f6e697469616c697a696e670000000000000000000000000000000000000000006064820152608401611fa9565b6036613c59838261457f565b50603761082d828261457f565b606082471015613cf8576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f60448201527f722063616c6c00000000000000000000000000000000000000000000000000006064820152608401611fa9565b73ffffffffffffffffffffffffffffffffffffffff85163b613d76576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006044820152606401611fa9565b6000808673ffffffffffffffffffffffffffffffffffffffff168587604051613d9f9190614699565b60006040518083038185875af1925050503d8060008114613ddc576040519150601f19603f3d011682016040523d82523d6000602084013e613de1565b606091505b509150915061222c82828660608315613dfb575081610db7565b825115613e0b5782518084602001fd5b816040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611fa99190613e63565b60005b83811015613e5a578181015183820152602001613e42565b50506000910152565b6020815260008251806020840152613e82816040850160208701613e3f565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169190910160400192915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b600082601f830112613ef457600080fd5b813567ffffffffffffffff80821115613f0f57613f0f613eb4565b604051601f83017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0908116603f01168101908282118183101715613f5557613f55613eb4565b81604052838152866020858801011115613f6e57600080fd5b836020870160208301376000602085830101528094505050505092915050565b73ffffffffffffffffffffffffffffffffffffffff81168114611c0357600080fd5b600080600060608486031215613fc557600080fd5b833567ffffffffffffffff80821115613fdd57600080fd5b613fe987838801613ee3565b94506020860135915080821115613fff57600080fd5b5061400c86828701613ee3565b925050604084013561401d81613f8e565b809150509250925092565b60006020828403121561403a57600080fd5b8135610db781613f8e565b6000806040838503121561405857600080fd5b823561406381613f8e565b946020939093013593505050565b60008060006060848603121561408657600080fd5b833561409181613f8e565b925060208401356140a181613f8e565b929592945050506040919091013590565b6000806000606084860312156140c757600080fd5b83356140d281613f8e565b925060208401359150604084013561401d81613f8e565b600080604083850312156140fc57600080fd5b82359150602083013561410e81613f8e565b809150509250929050565b60008060006060848603121561412e57600080fd5b83359250602084013561414081613f8e565b9150604084013561401d81613f8e565b60006020828403121561416257600080fd5b5035919050565b803567ffffffffffffffff8116811461418157600080fd5b919050565b8015158114611c0357600080fd5b600080600080600060a086880312156141ac57600080fd5b85356141b781613f8e565b945060208601359350604086013592506141d360608701614169565b915060808601356141e381614186565b809150509295509295909350565b6000806040838503121561420457600080fd5b823561420f81613f8e565b915061421d60208401614169565b90509250929050565b6020808252825182820181905260009190848201906040850190845b8181101561427457835173ffffffffffffffffffffffffffffffffffffffff1683529284019291840191600101614242565b50909695505050505050565b600080600080600080600060e0888a03121561429b57600080fd5b87356142a681613f8e565b965060208801356142b681613f8e565b95506040880135945060608801359350608088013560ff811681146142da57600080fd5b9699959850939692959460a0840135945060c09093013592915050565b6000806040838503121561430a57600080fd5b823561431581613f8e565b9150602083013561410e81613f8e565b600181811c9082168061433957607f821691505b6020821081036133e4577f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b60006020828403121561438457600080fd5b8151610db781614186565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b818103818111156109a9576109a961438f565b6000602082840312156143e357600080fd5b5051919050565b808201808211156109a9576109a961438f565b600082614433577f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b500490565b80820281158282048414176109a9576109a961438f565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82036144af576144af61438f565b5060010190565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603160045260246000fd5b6000602082840312156144f757600080fd5b8151610db781613f8e565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b601f82111561082d57600081815260208120601f850160051c810160208610156145585750805b601f850160051c820191505b8181101561457757828155600101614564565b505050505050565b815167ffffffffffffffff81111561459957614599613eb4565b6145ad816145a78454614325565b84614531565b602080601f83116001811461460057600084156145ca5750858301515b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600386901b1c1916600185901b178555614577565b6000858152602081207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08616915b8281101561464d5788860151825594840194600190910190840161462e565b508582101561468957878501517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600388901b60f8161c191681555b5050505050600190811b01905550565b600082516146ab818460208701613e3f565b919091019291505056fea26469706673582212204ab762f428941cadd300d875bf277cb0f7dff52a487fb7282a657f3da537ca0564736f6c63430008110033", + "numDeployments": 2, + "solcInputHash": "871924e0c138825a2736b76def8fef8d", + "metadata": "{\"compiler\":{\"version\":\"0.8.17+commit.8df45f5f\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[],\"name\":\"AssetStillControlledInReserves\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"BurnAmountExceedsAllowance\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"HourlyLimitExceeded\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidSender\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidToken\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidTreasury\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"NotGovernor\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"NotGovernorOrGuardian\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"NotMinter\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"NotTreasury\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"TooBigAmount\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"TooHighParameterValue\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ZeroAddress\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"spender\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"}],\"name\":\"Approval\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"bridgeToken\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"limit\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"hourlyLimit\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"fee\",\"type\":\"uint64\"},{\"indexed\":false,\"internalType\":\"bool\",\"name\":\"paused\",\"type\":\"bool\"}],\"name\":\"BridgeTokenAdded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"bridgeToken\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"fee\",\"type\":\"uint64\"}],\"name\":\"BridgeTokenFeeUpdated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"bridgeToken\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"hourlyLimit\",\"type\":\"uint256\"}],\"name\":\"BridgeTokenHourlyLimitUpdated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"bridgeToken\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"limit\",\"type\":\"uint256\"}],\"name\":\"BridgeTokenLimitUpdated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"bridgeToken\",\"type\":\"address\"}],\"name\":\"BridgeTokenRemoved\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"bridgeToken\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"bool\",\"name\":\"toggleStatus\",\"type\":\"bool\"}],\"name\":\"BridgeTokenToggled\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"theAddress\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"toggleStatus\",\"type\":\"uint256\"}],\"name\":\"FeeToggled\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"hourlyLimit\",\"type\":\"uint256\"}],\"name\":\"HourlyLimitUpdated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint8\",\"name\":\"version\",\"type\":\"uint8\"}],\"name\":\"Initialized\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"minter\",\"type\":\"address\"}],\"name\":\"MinterToggled\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"Recovered\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"}],\"name\":\"Transfer\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"_treasury\",\"type\":\"address\"}],\"name\":\"TreasuryUpdated\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"BASE_PARAMS\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"DOMAIN_SEPARATOR\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"bridgeToken\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"limit\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"hourlyLimit\",\"type\":\"uint256\"},{\"internalType\":\"uint64\",\"name\":\"fee\",\"type\":\"uint64\"},{\"internalType\":\"bool\",\"name\":\"paused\",\"type\":\"bool\"}],\"name\":\"addBridgeToken\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"minter\",\"type\":\"address\"}],\"name\":\"addMinter\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"allBridgeTokens\",\"outputs\":[{\"internalType\":\"address[]\",\"name\":\"\",\"type\":\"address[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"spender\",\"type\":\"address\"}],\"name\":\"allowance\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"spender\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"approve\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"}],\"name\":\"balanceOf\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"name\":\"bridgeTokensList\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"bridges\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"limit\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"hourlyLimit\",\"type\":\"uint256\"},{\"internalType\":\"uint64\",\"name\":\"fee\",\"type\":\"uint64\"},{\"internalType\":\"bool\",\"name\":\"allowed\",\"type\":\"bool\"},{\"internalType\":\"bool\",\"name\":\"paused\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"burner\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"}],\"name\":\"burnFrom\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"burner\",\"type\":\"address\"}],\"name\":\"burnSelf\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"burnStablecoin\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"chainTotalHourlyLimit\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"name\":\"chainTotalUsage\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"currentTotalUsage\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"bridgeToken\",\"type\":\"address\"}],\"name\":\"currentUsage\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"decimals\",\"outputs\":[{\"internalType\":\"uint8\",\"name\":\"\",\"type\":\"uint8\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"spender\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"subtractedValue\",\"type\":\"uint256\"}],\"name\":\"decreaseAllowance\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"spender\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"addedValue\",\"type\":\"uint256\"}],\"name\":\"increaseAllowance\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"string\",\"name\":\"name_\",\"type\":\"string\"},{\"internalType\":\"string\",\"name\":\"symbol_\",\"type\":\"string\"},{\"internalType\":\"address\",\"name\":\"_treasury\",\"type\":\"address\"}],\"name\":\"initialize\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"isFeeExempt\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"isMinter\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"mint\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"name\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"}],\"name\":\"nonces\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"spender\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"deadline\",\"type\":\"uint256\"},{\"internalType\":\"uint8\",\"name\":\"v\",\"type\":\"uint8\"},{\"internalType\":\"bytes32\",\"name\":\"r\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32\",\"name\":\"s\",\"type\":\"bytes32\"}],\"name\":\"permit\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"tokenAddress\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amountToRecover\",\"type\":\"uint256\"}],\"name\":\"recoverERC20\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"bridgeToken\",\"type\":\"address\"}],\"name\":\"removeBridgeToken\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"minter\",\"type\":\"address\"}],\"name\":\"removeMinter\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"hourlyLimit\",\"type\":\"uint256\"}],\"name\":\"setChainTotalHourlyLimit\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"bridgeToken\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"hourlyLimit\",\"type\":\"uint256\"}],\"name\":\"setHourlyLimit\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"bridgeToken\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"limit\",\"type\":\"uint256\"}],\"name\":\"setLimit\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"bridgeToken\",\"type\":\"address\"},{\"internalType\":\"uint64\",\"name\":\"fee\",\"type\":\"uint64\"}],\"name\":\"setSwapFee\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_treasury\",\"type\":\"address\"}],\"name\":\"setTreasury\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"bridgeToken\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"swapIn\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"bridgeToken\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"swapOut\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"symbol\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"bridgeToken\",\"type\":\"address\"}],\"name\":\"toggleBridge\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"theAddress\",\"type\":\"address\"}],\"name\":\"toggleFeesForAddress\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"totalSupply\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"transfer\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"transferFrom\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"treasury\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"name\":\"usage\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"}],\"devdoc\":{\"author\":\"Angle Labs, Inc.\",\"details\":\"This contract supports bridge tokens having a minting right on the stablecoin (also referred to as the canonical or the native token)\",\"kind\":\"dev\",\"methods\":{\"DOMAIN_SEPARATOR()\":{\"details\":\"See {IERC20Permit-DOMAIN_SEPARATOR}.\"},\"addBridgeToken(address,uint256,uint256,uint64,bool)\":{\"params\":{\"bridgeToken\":\"Bridge token to add: it should be a version of the stablecoin from another bridge\",\"fee\":\"Fee taken upon swapping for or against this token\",\"hourlyLimit\":\"Limit on the hourly volume for this bridge\",\"limit\":\"Limit on the balance of bridge token this contract could hold\",\"paused\":\"Whether swapping for this token should be paused or not\"}},\"addMinter(address)\":{\"details\":\"Zero address checks are performed directly in the `Treasury` contract\",\"params\":{\"minter\":\"Minter address to add\"}},\"allBridgeTokens()\":{\"details\":\"Helpful for UIs\"},\"allowance(address,address)\":{\"details\":\"See {IERC20-allowance}.\"},\"approve(address,uint256)\":{\"details\":\"See {IERC20-approve}. NOTE: If `amount` is the maximum `uint256`, the allowance is not updated on `transferFrom`. This is semantically equivalent to an infinite approval. Requirements: - `spender` cannot be the zero address.\"},\"balanceOf(address)\":{\"details\":\"See {IERC20-balanceOf}.\"},\"burnFrom(uint256,address,address)\":{\"details\":\"This method is to be called by a contract with the minter right after being requested to do so by a `sender` address willing to burn tokens from another `burner` addressThe method checks the allowance between the `sender` and the `burner`\",\"params\":{\"amount\":\"Amount of tokens to burn\",\"burner\":\"Address to burn from\",\"sender\":\"Address which requested the burn from `burner`\"}},\"burnSelf(uint256,address)\":{\"details\":\"This method is to be called by a contract with a minter right on the AgToken after being requested to do so by an address willing to burn tokens from its address\",\"params\":{\"amount\":\"Amount of tokens to burn\",\"burner\":\"Address to burn from\"}},\"burnStablecoin(uint256)\":{\"details\":\"This function can typically be called if there is a settlement mechanism to burn stablecoins\",\"params\":{\"amount\":\"Amount of stablecoins to burn\"}},\"currentTotalUsage()\":{\"details\":\"Helpful for UIs\"},\"currentUsage(address)\":{\"details\":\"Helpful for UIs\",\"params\":{\"bridgeToken\":\"Bridge used to mint\"}},\"decimals()\":{\"details\":\"Returns the number of decimals used to get its user representation. For example, if `decimals` equals `2`, a balance of `505` tokens should be displayed to a user as `5.05` (`505 / 10 ** 2`). Tokens usually opt for a value of 18, imitating the relationship between Ether and Wei. This is the value {ERC20} uses, unless this function is overridden; NOTE: This information is only used for _display_ purposes: it in no way affects any of the arithmetic of the contract, including {IERC20-balanceOf} and {IERC20-transfer}.\"},\"decreaseAllowance(address,uint256)\":{\"details\":\"Atomically decreases the allowance granted to `spender` by the caller. This is an alternative to {approve} that can be used as a mitigation for problems described in {IERC20-approve}. Emits an {Approval} event indicating the updated allowance. Requirements: - `spender` cannot be the zero address. - `spender` must have allowance for the caller of at least `subtractedValue`.\"},\"increaseAllowance(address,uint256)\":{\"details\":\"Atomically increases the allowance granted to `spender` by the caller. This is an alternative to {approve} that can be used as a mitigation for problems described in {IERC20-approve}. Emits an {Approval} event indicating the updated allowance. Requirements: - `spender` cannot be the zero address.\"},\"mint(address,uint256)\":{\"details\":\"The contracts allowed to issue agTokens are the `StableMaster` contract, `VaultManager` contracts associated to this stablecoin as well as the flash loan module (if activated) and potentially contracts whitelisted by governance\",\"params\":{\"account\":\"Address to mint to\",\"amount\":\"Amount to mint\"}},\"name()\":{\"details\":\"Returns the name of the token.\"},\"nonces(address)\":{\"details\":\"See {IERC20Permit-nonces}.\"},\"permit(address,address,uint256,uint256,uint8,bytes32,bytes32)\":{\"details\":\"See {IERC20Permit-permit}.\"},\"recoverERC20(address,address,uint256)\":{\"details\":\"Can be used to withdraw bridge tokens for them to be de-bridged on mainnet\"},\"removeBridgeToken(address)\":{\"params\":{\"bridgeToken\":\"Address of the bridge token to remove support for\"}},\"removeMinter(address)\":{\"details\":\"This function can also be called by a minter wishing to revoke itself\",\"params\":{\"minter\":\"Minter address to remove\"}},\"setTreasury(address)\":{\"params\":{\"_treasury\":\"New treasury address\"}},\"swapIn(address,uint256,address)\":{\"details\":\"Some fees may be taken by the protocol depending on the token used and on the address calling\",\"params\":{\"amount\":\"Amount of bridge tokens to send\",\"bridgeToken\":\"Bridge token to use to mint\",\"to\":\"Address to which the stablecoin should be sent\"},\"returns\":{\"_0\":\"Amount of the canonical stablecoin actually minted\"}},\"swapOut(address,uint256,address)\":{\"details\":\"Some fees may be taken by the protocol depending on the token used and on the address calling\",\"params\":{\"amount\":\"Amount of canonical tokens to burn\",\"bridgeToken\":\"Bridge token required\",\"to\":\"Address to which the bridge token should be sent\"},\"returns\":{\"_0\":\"Amount of bridge tokens actually sent back\"}},\"symbol()\":{\"details\":\"Returns the symbol of the token, usually a shorter version of the name.\"},\"totalSupply()\":{\"details\":\"See {IERC20-totalSupply}.\"},\"transfer(address,uint256)\":{\"details\":\"See {IERC20-transfer}. Requirements: - `to` cannot be the zero address. - the caller must have a balance of at least `amount`.\"},\"transferFrom(address,address,uint256)\":{\"details\":\"See {IERC20-transferFrom}. Emits an {Approval} event indicating the updated allowance. This is not required by the EIP. See the note at the beginning of {ERC20}. NOTE: Does not update the allowance if the current allowance is the maximum `uint256`. Requirements: - `from` and `to` cannot be the zero address. - `from` must have a balance of at least `amount`. - the caller must have allowance for ``from``'s tokens of at least `amount`.\"}},\"title\":\"AgTokenSideChainMultiBridge\",\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{\"BASE_PARAMS()\":{\"notice\":\"Base used for fee computation\"},\"addBridgeToken(address,uint256,uint256,uint64,bool)\":{\"notice\":\"Adds support for a bridge token\"},\"addMinter(address)\":{\"notice\":\"Adds a minter in the contract\"},\"allBridgeTokens()\":{\"notice\":\"Returns the list of all supported bridge tokens\"},\"bridgeTokensList(uint256)\":{\"notice\":\"List of all bridge tokens\"},\"bridges(address)\":{\"notice\":\"Maps a bridge token to data\"},\"burnFrom(uint256,address,address)\":{\"notice\":\"Burns `amount` tokens from a `burner` address after being asked to by `sender`\"},\"burnSelf(uint256,address)\":{\"notice\":\"Burns `amount` tokens from a `burner` address\"},\"burnStablecoin(uint256)\":{\"notice\":\"Allows anyone to burn stablecoins\"},\"chainTotalHourlyLimit()\":{\"notice\":\"Limit to the amount of tokens that can be sent from that chain to another chain\"},\"chainTotalUsage(uint256)\":{\"notice\":\"Usage per hour on that chain. Maps an hourly timestamp to the total volume swapped out on the chain\"},\"currentTotalUsage()\":{\"notice\":\"Returns the current total volume on the chain for the current hour\"},\"currentUsage(address)\":{\"notice\":\"Returns the current volume for a bridge, for the current hour\"},\"initialize(string,string,address)\":{\"notice\":\"Initializes the `AgToken` contract\"},\"isFeeExempt(address)\":{\"notice\":\"Maps an address to whether it is exempt of fees for when it comes to swapping in and out\"},\"isMinter(address)\":{\"notice\":\"Checks whether an address has the right to mint agTokens\"},\"mint(address,uint256)\":{\"notice\":\"Lets the `StableMaster` contract or another whitelisted contract mint agTokens\"},\"recoverERC20(address,address,uint256)\":{\"notice\":\"Recovers any ERC20 token\"},\"removeBridgeToken(address)\":{\"notice\":\"Removes support for a token\"},\"removeMinter(address)\":{\"notice\":\"Removes a minter from the contract\"},\"setChainTotalHourlyLimit(uint256)\":{\"notice\":\"Updates the `chainTotalHourlyLimit` amount\"},\"setHourlyLimit(address,uint256)\":{\"notice\":\"Updates the `hourlyLimit` amount for `bridgeToken`\"},\"setLimit(address,uint256)\":{\"notice\":\"Updates the `limit` amount for `bridgeToken`\"},\"setSwapFee(address,uint64)\":{\"notice\":\"Updates the `fee` value for `bridgeToken`\"},\"setTreasury(address)\":{\"notice\":\"Sets a new treasury contract\"},\"swapIn(address,uint256,address)\":{\"notice\":\"Mints the canonical token from a supported bridge token\"},\"swapOut(address,uint256,address)\":{\"notice\":\"Burns the canonical token in exchange for a bridge token\"},\"toggleBridge(address)\":{\"notice\":\"Pauses or unpauses swapping in and out for a token\"},\"toggleFeesForAddress(address)\":{\"notice\":\"Toggles fees for the address `theAddress`\"},\"treasury()\":{\"notice\":\"Reference to the treasury contract which can grant minting rights\"},\"usage(address,uint256)\":{\"notice\":\"Maps a bridge token to the associated hourly volume\"}},\"notice\":\"Contract for Angle agTokens on other chains than Ethereum mainnet\",\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/agToken/AgTokenSideChainMultiBridge.sol\":\"AgTokenSideChainMultiBridge\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":1000000},\"remappings\":[]},\"sources\":{\"@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.7.0) (proxy/utils/Initializable.sol)\\n\\npragma solidity ^0.8.2;\\n\\nimport \\\"../../utils/AddressUpgradeable.sol\\\";\\n\\n/**\\n * @dev This is a base contract to aid in writing upgradeable contracts, or any kind of contract that will be deployed\\n * behind a proxy. Since proxied contracts do not make use of a constructor, it's common to move constructor logic to an\\n * external initializer function, usually called `initialize`. It then becomes necessary to protect this initializer\\n * function so it can only be called once. The {initializer} modifier provided by this contract will have this effect.\\n *\\n * The initialization functions use a version number. Once a version number is used, it is consumed and cannot be\\n * reused. This mechanism prevents re-execution of each \\\"step\\\" but allows the creation of new initialization steps in\\n * case an upgrade adds a module that needs to be initialized.\\n *\\n * For example:\\n *\\n * [.hljs-theme-light.nopadding]\\n * ```\\n * contract MyToken is ERC20Upgradeable {\\n * function initialize() initializer public {\\n * __ERC20_init(\\\"MyToken\\\", \\\"MTK\\\");\\n * }\\n * }\\n * contract MyTokenV2 is MyToken, ERC20PermitUpgradeable {\\n * function initializeV2() reinitializer(2) public {\\n * __ERC20Permit_init(\\\"MyToken\\\");\\n * }\\n * }\\n * ```\\n *\\n * TIP: To avoid leaving the proxy in an uninitialized state, the initializer function should be called as early as\\n * possible by providing the encoded function call as the `_data` argument to {ERC1967Proxy-constructor}.\\n *\\n * CAUTION: When used with inheritance, manual care must be taken to not invoke a parent initializer twice, or to ensure\\n * that all initializers are idempotent. This is not verified automatically as constructors are by Solidity.\\n *\\n * [CAUTION]\\n * ====\\n * Avoid leaving a contract uninitialized.\\n *\\n * An uninitialized contract can be taken over by an attacker. This applies to both a proxy and its implementation\\n * contract, which may impact the proxy. To prevent the implementation contract from being used, you should invoke\\n * the {_disableInitializers} function in the constructor to automatically lock it when it is deployed:\\n *\\n * [.hljs-theme-light.nopadding]\\n * ```\\n * /// @custom:oz-upgrades-unsafe-allow constructor\\n * constructor() {\\n * _disableInitializers();\\n * }\\n * ```\\n * ====\\n */\\nabstract contract Initializable {\\n /**\\n * @dev Indicates that the contract has been initialized.\\n * @custom:oz-retyped-from bool\\n */\\n uint8 private _initialized;\\n\\n /**\\n * @dev Indicates that the contract is in the process of being initialized.\\n */\\n bool private _initializing;\\n\\n /**\\n * @dev Triggered when the contract has been initialized or reinitialized.\\n */\\n event Initialized(uint8 version);\\n\\n /**\\n * @dev A modifier that defines a protected initializer function that can be invoked at most once. In its scope,\\n * `onlyInitializing` functions can be used to initialize parent contracts. Equivalent to `reinitializer(1)`.\\n */\\n modifier initializer() {\\n bool isTopLevelCall = !_initializing;\\n require(\\n (isTopLevelCall && _initialized < 1) || (!AddressUpgradeable.isContract(address(this)) && _initialized == 1),\\n \\\"Initializable: contract is already initialized\\\"\\n );\\n _initialized = 1;\\n if (isTopLevelCall) {\\n _initializing = true;\\n }\\n _;\\n if (isTopLevelCall) {\\n _initializing = false;\\n emit Initialized(1);\\n }\\n }\\n\\n /**\\n * @dev A modifier that defines a protected reinitializer function that can be invoked at most once, and only if the\\n * contract hasn't been initialized to a greater version before. In its scope, `onlyInitializing` functions can be\\n * used to initialize parent contracts.\\n *\\n * `initializer` is equivalent to `reinitializer(1)`, so a reinitializer may be used after the original\\n * initialization step. This is essential to configure modules that are added through upgrades and that require\\n * initialization.\\n *\\n * Note that versions can jump in increments greater than 1; this implies that if multiple reinitializers coexist in\\n * a contract, executing them in the right order is up to the developer or operator.\\n */\\n modifier reinitializer(uint8 version) {\\n require(!_initializing && _initialized < version, \\\"Initializable: contract is already initialized\\\");\\n _initialized = version;\\n _initializing = true;\\n _;\\n _initializing = false;\\n emit Initialized(version);\\n }\\n\\n /**\\n * @dev Modifier to protect an initialization function so that it can only be invoked by functions with the\\n * {initializer} and {reinitializer} modifiers, directly or indirectly.\\n */\\n modifier onlyInitializing() {\\n require(_initializing, \\\"Initializable: contract is not initializing\\\");\\n _;\\n }\\n\\n /**\\n * @dev Locks the contract, preventing any future reinitialization. This cannot be part of an initializer call.\\n * Calling this in the constructor of a contract will prevent that contract from being initialized or reinitialized\\n * to any version. It is recommended to use this to lock implementation contracts that are designed to be called\\n * through proxies.\\n */\\n function _disableInitializers() internal virtual {\\n require(!_initializing, \\\"Initializable: contract is initializing\\\");\\n if (_initialized < type(uint8).max) {\\n _initialized = type(uint8).max;\\n emit Initialized(type(uint8).max);\\n }\\n }\\n}\\n\",\"keccak256\":\"0x0203dcadc5737d9ef2c211d6fa15d18ebc3b30dfa51903b64870b01a062b0b4e\",\"license\":\"MIT\"},\"@openzeppelin/contracts-upgradeable/token/ERC20/ERC20Upgradeable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.7.0) (token/ERC20/ERC20.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"./IERC20Upgradeable.sol\\\";\\nimport \\\"./extensions/IERC20MetadataUpgradeable.sol\\\";\\nimport \\\"../../utils/ContextUpgradeable.sol\\\";\\nimport \\\"../../proxy/utils/Initializable.sol\\\";\\n\\n/**\\n * @dev Implementation of the {IERC20} interface.\\n *\\n * This implementation is agnostic to the way tokens are created. This means\\n * that a supply mechanism has to be added in a derived contract using {_mint}.\\n * For a generic mechanism see {ERC20PresetMinterPauser}.\\n *\\n * TIP: For a detailed writeup see our guide\\n * https://forum.zeppelin.solutions/t/how-to-implement-erc20-supply-mechanisms/226[How\\n * to implement supply mechanisms].\\n *\\n * We have followed general OpenZeppelin Contracts guidelines: functions revert\\n * instead returning `false` on failure. This behavior is nonetheless\\n * conventional and does not conflict with the expectations of ERC20\\n * applications.\\n *\\n * Additionally, an {Approval} event is emitted on calls to {transferFrom}.\\n * This allows applications to reconstruct the allowance for all accounts just\\n * by listening to said events. Other implementations of the EIP may not emit\\n * these events, as it isn't required by the specification.\\n *\\n * Finally, the non-standard {decreaseAllowance} and {increaseAllowance}\\n * functions have been added to mitigate the well-known issues around setting\\n * allowances. See {IERC20-approve}.\\n */\\ncontract ERC20Upgradeable is Initializable, ContextUpgradeable, IERC20Upgradeable, IERC20MetadataUpgradeable {\\n mapping(address => uint256) private _balances;\\n\\n mapping(address => mapping(address => uint256)) private _allowances;\\n\\n uint256 private _totalSupply;\\n\\n string private _name;\\n string private _symbol;\\n\\n /**\\n * @dev Sets the values for {name} and {symbol}.\\n *\\n * The default value of {decimals} is 18. To select a different value for\\n * {decimals} you should overload it.\\n *\\n * All two of these values are immutable: they can only be set once during\\n * construction.\\n */\\n function __ERC20_init(string memory name_, string memory symbol_) internal onlyInitializing {\\n __ERC20_init_unchained(name_, symbol_);\\n }\\n\\n function __ERC20_init_unchained(string memory name_, string memory symbol_) internal onlyInitializing {\\n _name = name_;\\n _symbol = symbol_;\\n }\\n\\n /**\\n * @dev Returns the name of the token.\\n */\\n function name() public view virtual override returns (string memory) {\\n return _name;\\n }\\n\\n /**\\n * @dev Returns the symbol of the token, usually a shorter version of the\\n * name.\\n */\\n function symbol() public view virtual override returns (string memory) {\\n return _symbol;\\n }\\n\\n /**\\n * @dev Returns the number of decimals used to get its user representation.\\n * For example, if `decimals` equals `2`, a balance of `505` tokens should\\n * be displayed to a user as `5.05` (`505 / 10 ** 2`).\\n *\\n * Tokens usually opt for a value of 18, imitating the relationship between\\n * Ether and Wei. This is the value {ERC20} uses, unless this function is\\n * overridden;\\n *\\n * NOTE: This information is only used for _display_ purposes: it in\\n * no way affects any of the arithmetic of the contract, including\\n * {IERC20-balanceOf} and {IERC20-transfer}.\\n */\\n function decimals() public view virtual override returns (uint8) {\\n return 18;\\n }\\n\\n /**\\n * @dev See {IERC20-totalSupply}.\\n */\\n function totalSupply() public view virtual override returns (uint256) {\\n return _totalSupply;\\n }\\n\\n /**\\n * @dev See {IERC20-balanceOf}.\\n */\\n function balanceOf(address account) public view virtual override returns (uint256) {\\n return _balances[account];\\n }\\n\\n /**\\n * @dev See {IERC20-transfer}.\\n *\\n * Requirements:\\n *\\n * - `to` cannot be the zero address.\\n * - the caller must have a balance of at least `amount`.\\n */\\n function transfer(address to, uint256 amount) public virtual override returns (bool) {\\n address owner = _msgSender();\\n _transfer(owner, to, amount);\\n return true;\\n }\\n\\n /**\\n * @dev See {IERC20-allowance}.\\n */\\n function allowance(address owner, address spender) public view virtual override returns (uint256) {\\n return _allowances[owner][spender];\\n }\\n\\n /**\\n * @dev See {IERC20-approve}.\\n *\\n * NOTE: If `amount` is the maximum `uint256`, the allowance is not updated on\\n * `transferFrom`. This is semantically equivalent to an infinite approval.\\n *\\n * Requirements:\\n *\\n * - `spender` cannot be the zero address.\\n */\\n function approve(address spender, uint256 amount) public virtual override returns (bool) {\\n address owner = _msgSender();\\n _approve(owner, spender, amount);\\n return true;\\n }\\n\\n /**\\n * @dev See {IERC20-transferFrom}.\\n *\\n * Emits an {Approval} event indicating the updated allowance. This is not\\n * required by the EIP. See the note at the beginning of {ERC20}.\\n *\\n * NOTE: Does not update the allowance if the current allowance\\n * is the maximum `uint256`.\\n *\\n * Requirements:\\n *\\n * - `from` and `to` cannot be the zero address.\\n * - `from` must have a balance of at least `amount`.\\n * - the caller must have allowance for ``from``'s tokens of at least\\n * `amount`.\\n */\\n function transferFrom(\\n address from,\\n address to,\\n uint256 amount\\n ) public virtual override returns (bool) {\\n address spender = _msgSender();\\n _spendAllowance(from, spender, amount);\\n _transfer(from, to, amount);\\n return true;\\n }\\n\\n /**\\n * @dev Atomically increases the allowance granted to `spender` by the caller.\\n *\\n * This is an alternative to {approve} that can be used as a mitigation for\\n * problems described in {IERC20-approve}.\\n *\\n * Emits an {Approval} event indicating the updated allowance.\\n *\\n * Requirements:\\n *\\n * - `spender` cannot be the zero address.\\n */\\n function increaseAllowance(address spender, uint256 addedValue) public virtual returns (bool) {\\n address owner = _msgSender();\\n _approve(owner, spender, allowance(owner, spender) + addedValue);\\n return true;\\n }\\n\\n /**\\n * @dev Atomically decreases the allowance granted to `spender` by the caller.\\n *\\n * This is an alternative to {approve} that can be used as a mitigation for\\n * problems described in {IERC20-approve}.\\n *\\n * Emits an {Approval} event indicating the updated allowance.\\n *\\n * Requirements:\\n *\\n * - `spender` cannot be the zero address.\\n * - `spender` must have allowance for the caller of at least\\n * `subtractedValue`.\\n */\\n function decreaseAllowance(address spender, uint256 subtractedValue) public virtual returns (bool) {\\n address owner = _msgSender();\\n uint256 currentAllowance = allowance(owner, spender);\\n require(currentAllowance >= subtractedValue, \\\"ERC20: decreased allowance below zero\\\");\\n unchecked {\\n _approve(owner, spender, currentAllowance - subtractedValue);\\n }\\n\\n return true;\\n }\\n\\n /**\\n * @dev Moves `amount` of tokens from `from` to `to`.\\n *\\n * This internal function is equivalent to {transfer}, and can be used to\\n * e.g. implement automatic token fees, slashing mechanisms, etc.\\n *\\n * Emits a {Transfer} event.\\n *\\n * Requirements:\\n *\\n * - `from` cannot be the zero address.\\n * - `to` cannot be the zero address.\\n * - `from` must have a balance of at least `amount`.\\n */\\n function _transfer(\\n address from,\\n address to,\\n uint256 amount\\n ) internal virtual {\\n require(from != address(0), \\\"ERC20: transfer from the zero address\\\");\\n require(to != address(0), \\\"ERC20: transfer to the zero address\\\");\\n\\n _beforeTokenTransfer(from, to, amount);\\n\\n uint256 fromBalance = _balances[from];\\n require(fromBalance >= amount, \\\"ERC20: transfer amount exceeds balance\\\");\\n unchecked {\\n _balances[from] = fromBalance - amount;\\n }\\n _balances[to] += amount;\\n\\n emit Transfer(from, to, amount);\\n\\n _afterTokenTransfer(from, to, amount);\\n }\\n\\n /** @dev Creates `amount` tokens and assigns them to `account`, increasing\\n * the total supply.\\n *\\n * Emits a {Transfer} event with `from` set to the zero address.\\n *\\n * Requirements:\\n *\\n * - `account` cannot be the zero address.\\n */\\n function _mint(address account, uint256 amount) internal virtual {\\n require(account != address(0), \\\"ERC20: mint to the zero address\\\");\\n\\n _beforeTokenTransfer(address(0), account, amount);\\n\\n _totalSupply += amount;\\n _balances[account] += amount;\\n emit Transfer(address(0), account, amount);\\n\\n _afterTokenTransfer(address(0), account, amount);\\n }\\n\\n /**\\n * @dev Destroys `amount` tokens from `account`, reducing the\\n * total supply.\\n *\\n * Emits a {Transfer} event with `to` set to the zero address.\\n *\\n * Requirements:\\n *\\n * - `account` cannot be the zero address.\\n * - `account` must have at least `amount` tokens.\\n */\\n function _burn(address account, uint256 amount) internal virtual {\\n require(account != address(0), \\\"ERC20: burn from the zero address\\\");\\n\\n _beforeTokenTransfer(account, address(0), amount);\\n\\n uint256 accountBalance = _balances[account];\\n require(accountBalance >= amount, \\\"ERC20: burn amount exceeds balance\\\");\\n unchecked {\\n _balances[account] = accountBalance - amount;\\n }\\n _totalSupply -= amount;\\n\\n emit Transfer(account, address(0), amount);\\n\\n _afterTokenTransfer(account, address(0), amount);\\n }\\n\\n /**\\n * @dev Sets `amount` as the allowance of `spender` over the `owner` s tokens.\\n *\\n * This internal function is equivalent to `approve`, and can be used to\\n * e.g. set automatic allowances for certain subsystems, etc.\\n *\\n * Emits an {Approval} event.\\n *\\n * Requirements:\\n *\\n * - `owner` cannot be the zero address.\\n * - `spender` cannot be the zero address.\\n */\\n function _approve(\\n address owner,\\n address spender,\\n uint256 amount\\n ) internal virtual {\\n require(owner != address(0), \\\"ERC20: approve from the zero address\\\");\\n require(spender != address(0), \\\"ERC20: approve to the zero address\\\");\\n\\n _allowances[owner][spender] = amount;\\n emit Approval(owner, spender, amount);\\n }\\n\\n /**\\n * @dev Updates `owner` s allowance for `spender` based on spent `amount`.\\n *\\n * Does not update the allowance amount in case of infinite allowance.\\n * Revert if not enough allowance is available.\\n *\\n * Might emit an {Approval} event.\\n */\\n function _spendAllowance(\\n address owner,\\n address spender,\\n uint256 amount\\n ) internal virtual {\\n uint256 currentAllowance = allowance(owner, spender);\\n if (currentAllowance != type(uint256).max) {\\n require(currentAllowance >= amount, \\\"ERC20: insufficient allowance\\\");\\n unchecked {\\n _approve(owner, spender, currentAllowance - amount);\\n }\\n }\\n }\\n\\n /**\\n * @dev Hook that is called before any transfer of tokens. This includes\\n * minting and burning.\\n *\\n * Calling conditions:\\n *\\n * - when `from` and `to` are both non-zero, `amount` of ``from``'s tokens\\n * will be transferred to `to`.\\n * - when `from` is zero, `amount` tokens will be minted for `to`.\\n * - when `to` is zero, `amount` of ``from``'s tokens will be burned.\\n * - `from` and `to` are never both zero.\\n *\\n * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].\\n */\\n function _beforeTokenTransfer(\\n address from,\\n address to,\\n uint256 amount\\n ) internal virtual {}\\n\\n /**\\n * @dev Hook that is called after any transfer of tokens. This includes\\n * minting and burning.\\n *\\n * Calling conditions:\\n *\\n * - when `from` and `to` are both non-zero, `amount` of ``from``'s tokens\\n * has been transferred to `to`.\\n * - when `from` is zero, `amount` tokens have been minted for `to`.\\n * - when `to` is zero, `amount` of ``from``'s tokens have been burned.\\n * - `from` and `to` are never both zero.\\n *\\n * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].\\n */\\n function _afterTokenTransfer(\\n address from,\\n address to,\\n uint256 amount\\n ) internal virtual {}\\n\\n /**\\n * @dev This empty reserved space is put in place to allow future versions to add new\\n * variables without shifting down storage in the inheritance chain.\\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\\n */\\n uint256[45] private __gap;\\n}\\n\",\"keccak256\":\"0x7c7ac0bc6c340a7f320524b9a4b4b079ee9da3c51258080d4bab237f329a427c\",\"license\":\"MIT\"},\"@openzeppelin/contracts-upgradeable/token/ERC20/IERC20Upgradeable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.6.0) (token/ERC20/IERC20.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Interface of the ERC20 standard as defined in the EIP.\\n */\\ninterface IERC20Upgradeable {\\n /**\\n * @dev Emitted when `value` tokens are moved from one account (`from`) to\\n * another (`to`).\\n *\\n * Note that `value` may be zero.\\n */\\n event Transfer(address indexed from, address indexed to, uint256 value);\\n\\n /**\\n * @dev Emitted when the allowance of a `spender` for an `owner` is set by\\n * a call to {approve}. `value` is the new allowance.\\n */\\n event Approval(address indexed owner, address indexed spender, uint256 value);\\n\\n /**\\n * @dev Returns the amount of tokens in existence.\\n */\\n function totalSupply() external view returns (uint256);\\n\\n /**\\n * @dev Returns the amount of tokens owned by `account`.\\n */\\n function balanceOf(address account) external view returns (uint256);\\n\\n /**\\n * @dev Moves `amount` tokens from the caller's account to `to`.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * Emits a {Transfer} event.\\n */\\n function transfer(address to, uint256 amount) external returns (bool);\\n\\n /**\\n * @dev Returns the remaining number of tokens that `spender` will be\\n * allowed to spend on behalf of `owner` through {transferFrom}. This is\\n * zero by default.\\n *\\n * This value changes when {approve} or {transferFrom} are called.\\n */\\n function allowance(address owner, address spender) external view returns (uint256);\\n\\n /**\\n * @dev Sets `amount` as the allowance of `spender` over the caller's tokens.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * IMPORTANT: Beware that changing an allowance with this method brings the risk\\n * that someone may use both the old and the new allowance by unfortunate\\n * transaction ordering. One possible solution to mitigate this race\\n * condition is to first reduce the spender's allowance to 0 and set the\\n * desired value afterwards:\\n * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729\\n *\\n * Emits an {Approval} event.\\n */\\n function approve(address spender, uint256 amount) external returns (bool);\\n\\n /**\\n * @dev Moves `amount` tokens from `from` to `to` using the\\n * allowance mechanism. `amount` is then deducted from the caller's\\n * allowance.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * Emits a {Transfer} event.\\n */\\n function transferFrom(\\n address from,\\n address to,\\n uint256 amount\\n ) external returns (bool);\\n}\\n\",\"keccak256\":\"0x4e733d3164f73f461eaf9d8087a7ad1ea180bdc8ba0d3d61b0e1ae16d8e63dff\",\"license\":\"MIT\"},\"@openzeppelin/contracts-upgradeable/token/ERC20/extensions/IERC20MetadataUpgradeable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (token/ERC20/extensions/IERC20Metadata.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../IERC20Upgradeable.sol\\\";\\n\\n/**\\n * @dev Interface for the optional metadata functions from the ERC20 standard.\\n *\\n * _Available since v4.1._\\n */\\ninterface IERC20MetadataUpgradeable is IERC20Upgradeable {\\n /**\\n * @dev Returns the name of the token.\\n */\\n function name() external view returns (string memory);\\n\\n /**\\n * @dev Returns the symbol of the token.\\n */\\n function symbol() external view returns (string memory);\\n\\n /**\\n * @dev Returns the decimals places of the token.\\n */\\n function decimals() external view returns (uint8);\\n}\\n\",\"keccak256\":\"0x605434219ebbe4653f703640f06969faa5a1d78f0bfef878e5ddbb1ca369ceeb\",\"license\":\"MIT\"},\"@openzeppelin/contracts-upgradeable/token/ERC20/extensions/draft-ERC20PermitUpgradeable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.6.0) (token/ERC20/extensions/draft-ERC20Permit.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"./draft-IERC20PermitUpgradeable.sol\\\";\\nimport \\\"../ERC20Upgradeable.sol\\\";\\nimport \\\"../../../utils/cryptography/draft-EIP712Upgradeable.sol\\\";\\nimport \\\"../../../utils/cryptography/ECDSAUpgradeable.sol\\\";\\nimport \\\"../../../utils/CountersUpgradeable.sol\\\";\\nimport \\\"../../../proxy/utils/Initializable.sol\\\";\\n\\n/**\\n * @dev Implementation of the ERC20 Permit extension allowing approvals to be made via signatures, as defined in\\n * https://eips.ethereum.org/EIPS/eip-2612[EIP-2612].\\n *\\n * Adds the {permit} method, which can be used to change an account's ERC20 allowance (see {IERC20-allowance}) by\\n * presenting a message signed by the account. By not relying on `{IERC20-approve}`, the token holder account doesn't\\n * need to send a transaction, and thus is not required to hold Ether at all.\\n *\\n * _Available since v3.4._\\n *\\n * @custom:storage-size 51\\n */\\nabstract contract ERC20PermitUpgradeable is Initializable, ERC20Upgradeable, IERC20PermitUpgradeable, EIP712Upgradeable {\\n using CountersUpgradeable for CountersUpgradeable.Counter;\\n\\n mapping(address => CountersUpgradeable.Counter) private _nonces;\\n\\n // solhint-disable-next-line var-name-mixedcase\\n bytes32 private constant _PERMIT_TYPEHASH =\\n keccak256(\\\"Permit(address owner,address spender,uint256 value,uint256 nonce,uint256 deadline)\\\");\\n /**\\n * @dev In previous versions `_PERMIT_TYPEHASH` was declared as `immutable`.\\n * However, to ensure consistency with the upgradeable transpiler, we will continue\\n * to reserve a slot.\\n * @custom:oz-renamed-from _PERMIT_TYPEHASH\\n */\\n // solhint-disable-next-line var-name-mixedcase\\n bytes32 private _PERMIT_TYPEHASH_DEPRECATED_SLOT;\\n\\n /**\\n * @dev Initializes the {EIP712} domain separator using the `name` parameter, and setting `version` to `\\\"1\\\"`.\\n *\\n * It's a good idea to use the same `name` that is defined as the ERC20 token name.\\n */\\n function __ERC20Permit_init(string memory name) internal onlyInitializing {\\n __EIP712_init_unchained(name, \\\"1\\\");\\n }\\n\\n function __ERC20Permit_init_unchained(string memory) internal onlyInitializing {}\\n\\n /**\\n * @dev See {IERC20Permit-permit}.\\n */\\n function permit(\\n address owner,\\n address spender,\\n uint256 value,\\n uint256 deadline,\\n uint8 v,\\n bytes32 r,\\n bytes32 s\\n ) public virtual override {\\n require(block.timestamp <= deadline, \\\"ERC20Permit: expired deadline\\\");\\n\\n bytes32 structHash = keccak256(abi.encode(_PERMIT_TYPEHASH, owner, spender, value, _useNonce(owner), deadline));\\n\\n bytes32 hash = _hashTypedDataV4(structHash);\\n\\n address signer = ECDSAUpgradeable.recover(hash, v, r, s);\\n require(signer == owner, \\\"ERC20Permit: invalid signature\\\");\\n\\n _approve(owner, spender, value);\\n }\\n\\n /**\\n * @dev See {IERC20Permit-nonces}.\\n */\\n function nonces(address owner) public view virtual override returns (uint256) {\\n return _nonces[owner].current();\\n }\\n\\n /**\\n * @dev See {IERC20Permit-DOMAIN_SEPARATOR}.\\n */\\n // solhint-disable-next-line func-name-mixedcase\\n function DOMAIN_SEPARATOR() external view override returns (bytes32) {\\n return _domainSeparatorV4();\\n }\\n\\n /**\\n * @dev \\\"Consume a nonce\\\": return the current value and increment.\\n *\\n * _Available since v4.1._\\n */\\n function _useNonce(address owner) internal virtual returns (uint256 current) {\\n CountersUpgradeable.Counter storage nonce = _nonces[owner];\\n current = nonce.current();\\n nonce.increment();\\n }\\n\\n /**\\n * @dev This empty reserved space is put in place to allow future versions to add new\\n * variables without shifting down storage in the inheritance chain.\\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\\n */\\n uint256[49] private __gap;\\n}\\n\",\"keccak256\":\"0x564385ebed633694decce3e13d687f3ac7e8eaef64f7a504bfb3f03ad210601f\",\"license\":\"MIT\"},\"@openzeppelin/contracts-upgradeable/token/ERC20/extensions/draft-IERC20PermitUpgradeable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (token/ERC20/extensions/draft-IERC20Permit.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Interface of the ERC20 Permit extension allowing approvals to be made via signatures, as defined in\\n * https://eips.ethereum.org/EIPS/eip-2612[EIP-2612].\\n *\\n * Adds the {permit} method, which can be used to change an account's ERC20 allowance (see {IERC20-allowance}) by\\n * presenting a message signed by the account. By not relying on {IERC20-approve}, the token holder account doesn't\\n * need to send a transaction, and thus is not required to hold Ether at all.\\n */\\ninterface IERC20PermitUpgradeable {\\n /**\\n * @dev Sets `value` as the allowance of `spender` over ``owner``'s tokens,\\n * given ``owner``'s signed approval.\\n *\\n * IMPORTANT: The same issues {IERC20-approve} has related to transaction\\n * ordering also apply here.\\n *\\n * Emits an {Approval} event.\\n *\\n * Requirements:\\n *\\n * - `spender` cannot be the zero address.\\n * - `deadline` must be a timestamp in the future.\\n * - `v`, `r` and `s` must be a valid `secp256k1` signature from `owner`\\n * over the EIP712-formatted function arguments.\\n * - the signature must use ``owner``'s current nonce (see {nonces}).\\n *\\n * For more information on the signature format, see the\\n * https://eips.ethereum.org/EIPS/eip-2612#specification[relevant EIP\\n * section].\\n */\\n function permit(\\n address owner,\\n address spender,\\n uint256 value,\\n uint256 deadline,\\n uint8 v,\\n bytes32 r,\\n bytes32 s\\n ) external;\\n\\n /**\\n * @dev Returns the current nonce for `owner`. This value must be\\n * included whenever a signature is generated for {permit}.\\n *\\n * Every successful call to {permit} increases ``owner``'s nonce by one. This\\n * prevents a signature from being used multiple times.\\n */\\n function nonces(address owner) external view returns (uint256);\\n\\n /**\\n * @dev Returns the domain separator used in the encoding of the signature for {permit}, as defined by {EIP712}.\\n */\\n // solhint-disable-next-line func-name-mixedcase\\n function DOMAIN_SEPARATOR() external view returns (bytes32);\\n}\\n\",\"keccak256\":\"0xcc70d8e2281fb3ff69e8ab242500f10142cd0a7fa8dd9e45882be270d4d09024\",\"license\":\"MIT\"},\"@openzeppelin/contracts-upgradeable/utils/AddressUpgradeable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.7.0) (utils/Address.sol)\\n\\npragma solidity ^0.8.1;\\n\\n/**\\n * @dev Collection of functions related to the address type\\n */\\nlibrary AddressUpgradeable {\\n /**\\n * @dev Returns true if `account` is a contract.\\n *\\n * [IMPORTANT]\\n * ====\\n * It is unsafe to assume that an address for which this function returns\\n * false is an externally-owned account (EOA) and not a contract.\\n *\\n * Among others, `isContract` will return false for the following\\n * types of addresses:\\n *\\n * - an externally-owned account\\n * - a contract in construction\\n * - an address where a contract will be created\\n * - an address where a contract lived, but was destroyed\\n * ====\\n *\\n * [IMPORTANT]\\n * ====\\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\\n *\\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\\n * constructor.\\n * ====\\n */\\n function isContract(address account) internal view returns (bool) {\\n // This method relies on extcodesize/address.code.length, which returns 0\\n // for contracts in construction, since the code is only stored at the end\\n // of the constructor execution.\\n\\n return account.code.length > 0;\\n }\\n\\n /**\\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\\n * `recipient`, forwarding all available gas and reverting on errors.\\n *\\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\\n * imposed by `transfer`, making them unable to receive funds via\\n * `transfer`. {sendValue} removes this limitation.\\n *\\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\\n *\\n * IMPORTANT: because control is transferred to `recipient`, care must be\\n * taken to not create reentrancy vulnerabilities. Consider using\\n * {ReentrancyGuard} or the\\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\\n */\\n function sendValue(address payable recipient, uint256 amount) internal {\\n require(address(this).balance >= amount, \\\"Address: insufficient balance\\\");\\n\\n (bool success, ) = recipient.call{value: amount}(\\\"\\\");\\n require(success, \\\"Address: unable to send value, recipient may have reverted\\\");\\n }\\n\\n /**\\n * @dev Performs a Solidity function call using a low level `call`. A\\n * plain `call` is an unsafe replacement for a function call: use this\\n * function instead.\\n *\\n * If `target` reverts with a revert reason, it is bubbled up by this\\n * function (like regular Solidity function calls).\\n *\\n * Returns the raw returned data. To convert to the expected return value,\\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\\n *\\n * Requirements:\\n *\\n * - `target` must be a contract.\\n * - calling `target` with `data` must not revert.\\n *\\n * _Available since v3.1._\\n */\\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\\n return functionCall(target, data, \\\"Address: low-level call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\\n * `errorMessage` as a fallback revert reason when `target` reverts.\\n *\\n * _Available since v3.1._\\n */\\n function functionCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n return functionCallWithValue(target, data, 0, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but also transferring `value` wei to `target`.\\n *\\n * Requirements:\\n *\\n * - the calling contract must have an ETH balance of at least `value`.\\n * - the called Solidity function must be `payable`.\\n *\\n * _Available since v3.1._\\n */\\n function functionCallWithValue(\\n address target,\\n bytes memory data,\\n uint256 value\\n ) internal returns (bytes memory) {\\n return functionCallWithValue(target, data, value, \\\"Address: low-level call with value failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\\n * with `errorMessage` as a fallback revert reason when `target` reverts.\\n *\\n * _Available since v3.1._\\n */\\n function functionCallWithValue(\\n address target,\\n bytes memory data,\\n uint256 value,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n require(address(this).balance >= value, \\\"Address: insufficient balance for call\\\");\\n require(isContract(target), \\\"Address: call to non-contract\\\");\\n\\n (bool success, bytes memory returndata) = target.call{value: value}(data);\\n return verifyCallResult(success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but performing a static call.\\n *\\n * _Available since v3.3._\\n */\\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\\n return functionStaticCall(target, data, \\\"Address: low-level static call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\\n * but performing a static call.\\n *\\n * _Available since v3.3._\\n */\\n function functionStaticCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal view returns (bytes memory) {\\n require(isContract(target), \\\"Address: static call to non-contract\\\");\\n\\n (bool success, bytes memory returndata) = target.staticcall(data);\\n return verifyCallResult(success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the\\n * revert reason using the provided one.\\n *\\n * _Available since v4.3._\\n */\\n function verifyCallResult(\\n bool success,\\n bytes memory returndata,\\n string memory errorMessage\\n ) internal pure returns (bytes memory) {\\n if (success) {\\n return returndata;\\n } else {\\n // Look for revert reason and bubble it up if present\\n if (returndata.length > 0) {\\n // The easiest way to bubble the revert reason is using memory via assembly\\n /// @solidity memory-safe-assembly\\n assembly {\\n let returndata_size := mload(returndata)\\n revert(add(32, returndata), returndata_size)\\n }\\n } else {\\n revert(errorMessage);\\n }\\n }\\n }\\n}\\n\",\"keccak256\":\"0x611aa3f23e59cfdd1863c536776407b3e33d695152a266fa7cfb34440a29a8a3\",\"license\":\"MIT\"},\"@openzeppelin/contracts-upgradeable/utils/ContextUpgradeable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)\\n\\npragma solidity ^0.8.0;\\nimport \\\"../proxy/utils/Initializable.sol\\\";\\n\\n/**\\n * @dev Provides information about the current execution context, including the\\n * sender of the transaction and its data. While these are generally available\\n * via msg.sender and msg.data, they should not be accessed in such a direct\\n * manner, since when dealing with meta-transactions the account sending and\\n * paying for execution may not be the actual sender (as far as an application\\n * is concerned).\\n *\\n * This contract is only required for intermediate, library-like contracts.\\n */\\nabstract contract ContextUpgradeable is Initializable {\\n function __Context_init() internal onlyInitializing {\\n }\\n\\n function __Context_init_unchained() internal onlyInitializing {\\n }\\n function _msgSender() internal view virtual returns (address) {\\n return msg.sender;\\n }\\n\\n function _msgData() internal view virtual returns (bytes calldata) {\\n return msg.data;\\n }\\n\\n /**\\n * @dev This empty reserved space is put in place to allow future versions to add new\\n * variables without shifting down storage in the inheritance chain.\\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\\n */\\n uint256[50] private __gap;\\n}\\n\",\"keccak256\":\"0x963ea7f0b48b032eef72fe3a7582edf78408d6f834115b9feadd673a4d5bd149\",\"license\":\"MIT\"},\"@openzeppelin/contracts-upgradeable/utils/CountersUpgradeable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (utils/Counters.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @title Counters\\n * @author Matt Condon (@shrugs)\\n * @dev Provides counters that can only be incremented, decremented or reset. This can be used e.g. to track the number\\n * of elements in a mapping, issuing ERC721 ids, or counting request ids.\\n *\\n * Include with `using Counters for Counters.Counter;`\\n */\\nlibrary CountersUpgradeable {\\n struct Counter {\\n // This variable should never be directly accessed by users of the library: interactions must be restricted to\\n // the library's function. As of Solidity v0.5.2, this cannot be enforced, though there is a proposal to add\\n // this feature: see https://github.com/ethereum/solidity/issues/4637\\n uint256 _value; // default: 0\\n }\\n\\n function current(Counter storage counter) internal view returns (uint256) {\\n return counter._value;\\n }\\n\\n function increment(Counter storage counter) internal {\\n unchecked {\\n counter._value += 1;\\n }\\n }\\n\\n function decrement(Counter storage counter) internal {\\n uint256 value = counter._value;\\n require(value > 0, \\\"Counter: decrement overflow\\\");\\n unchecked {\\n counter._value = value - 1;\\n }\\n }\\n\\n function reset(Counter storage counter) internal {\\n counter._value = 0;\\n }\\n}\\n\",\"keccak256\":\"0x798741e231b22b81e2dd2eddaaf8832dee4baf5cd8e2dbaa5c1dd12a1c053c4d\",\"license\":\"MIT\"},\"@openzeppelin/contracts-upgradeable/utils/StringsUpgradeable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.7.0) (utils/Strings.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev String operations.\\n */\\nlibrary StringsUpgradeable {\\n bytes16 private constant _HEX_SYMBOLS = \\\"0123456789abcdef\\\";\\n uint8 private constant _ADDRESS_LENGTH = 20;\\n\\n /**\\n * @dev Converts a `uint256` to its ASCII `string` decimal representation.\\n */\\n function toString(uint256 value) internal pure returns (string memory) {\\n // Inspired by OraclizeAPI's implementation - MIT licence\\n // https://github.com/oraclize/ethereum-api/blob/b42146b063c7d6ee1358846c198246239e9360e8/oraclizeAPI_0.4.25.sol\\n\\n if (value == 0) {\\n return \\\"0\\\";\\n }\\n uint256 temp = value;\\n uint256 digits;\\n while (temp != 0) {\\n digits++;\\n temp /= 10;\\n }\\n bytes memory buffer = new bytes(digits);\\n while (value != 0) {\\n digits -= 1;\\n buffer[digits] = bytes1(uint8(48 + uint256(value % 10)));\\n value /= 10;\\n }\\n return string(buffer);\\n }\\n\\n /**\\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation.\\n */\\n function toHexString(uint256 value) internal pure returns (string memory) {\\n if (value == 0) {\\n return \\\"0x00\\\";\\n }\\n uint256 temp = value;\\n uint256 length = 0;\\n while (temp != 0) {\\n length++;\\n temp >>= 8;\\n }\\n return toHexString(value, length);\\n }\\n\\n /**\\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length.\\n */\\n function toHexString(uint256 value, uint256 length) internal pure returns (string memory) {\\n bytes memory buffer = new bytes(2 * length + 2);\\n buffer[0] = \\\"0\\\";\\n buffer[1] = \\\"x\\\";\\n for (uint256 i = 2 * length + 1; i > 1; --i) {\\n buffer[i] = _HEX_SYMBOLS[value & 0xf];\\n value >>= 4;\\n }\\n require(value == 0, \\\"Strings: hex length insufficient\\\");\\n return string(buffer);\\n }\\n\\n /**\\n * @dev Converts an `address` with fixed length of 20 bytes to its not checksummed ASCII `string` hexadecimal representation.\\n */\\n function toHexString(address addr) internal pure returns (string memory) {\\n return toHexString(uint256(uint160(addr)), _ADDRESS_LENGTH);\\n }\\n}\\n\",\"keccak256\":\"0xea5339a7fff0ed42b45be56a88efdd0b2ddde9fa480dc99fef9a6a4c5b776863\",\"license\":\"MIT\"},\"@openzeppelin/contracts-upgradeable/utils/cryptography/ECDSAUpgradeable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.7.0) (utils/cryptography/ECDSA.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../StringsUpgradeable.sol\\\";\\n\\n/**\\n * @dev Elliptic Curve Digital Signature Algorithm (ECDSA) operations.\\n *\\n * These functions can be used to verify that a message was signed by the holder\\n * of the private keys of a given address.\\n */\\nlibrary ECDSAUpgradeable {\\n enum RecoverError {\\n NoError,\\n InvalidSignature,\\n InvalidSignatureLength,\\n InvalidSignatureS,\\n InvalidSignatureV\\n }\\n\\n function _throwError(RecoverError error) private pure {\\n if (error == RecoverError.NoError) {\\n return; // no error: do nothing\\n } else if (error == RecoverError.InvalidSignature) {\\n revert(\\\"ECDSA: invalid signature\\\");\\n } else if (error == RecoverError.InvalidSignatureLength) {\\n revert(\\\"ECDSA: invalid signature length\\\");\\n } else if (error == RecoverError.InvalidSignatureS) {\\n revert(\\\"ECDSA: invalid signature 's' value\\\");\\n } else if (error == RecoverError.InvalidSignatureV) {\\n revert(\\\"ECDSA: invalid signature 'v' value\\\");\\n }\\n }\\n\\n /**\\n * @dev Returns the address that signed a hashed message (`hash`) with\\n * `signature` or error string. This address can then be used for verification purposes.\\n *\\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\\n * this function rejects them by requiring the `s` value to be in the lower\\n * half order, and the `v` value to be either 27 or 28.\\n *\\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\\n * verification to be secure: it is possible to craft signatures that\\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\\n * this is by receiving a hash of the original message (which may otherwise\\n * be too long), and then calling {toEthSignedMessageHash} on it.\\n *\\n * Documentation for signature generation:\\n * - with https://web3js.readthedocs.io/en/v1.3.4/web3-eth-accounts.html#sign[Web3.js]\\n * - with https://docs.ethers.io/v5/api/signer/#Signer-signMessage[ethers]\\n *\\n * _Available since v4.3._\\n */\\n function tryRecover(bytes32 hash, bytes memory signature) internal pure returns (address, RecoverError) {\\n // Check the signature length\\n // - case 65: r,s,v signature (standard)\\n // - case 64: r,vs signature (cf https://eips.ethereum.org/EIPS/eip-2098) _Available since v4.1._\\n if (signature.length == 65) {\\n bytes32 r;\\n bytes32 s;\\n uint8 v;\\n // ecrecover takes the signature parameters, and the only way to get them\\n // currently is to use assembly.\\n /// @solidity memory-safe-assembly\\n assembly {\\n r := mload(add(signature, 0x20))\\n s := mload(add(signature, 0x40))\\n v := byte(0, mload(add(signature, 0x60)))\\n }\\n return tryRecover(hash, v, r, s);\\n } else if (signature.length == 64) {\\n bytes32 r;\\n bytes32 vs;\\n // ecrecover takes the signature parameters, and the only way to get them\\n // currently is to use assembly.\\n /// @solidity memory-safe-assembly\\n assembly {\\n r := mload(add(signature, 0x20))\\n vs := mload(add(signature, 0x40))\\n }\\n return tryRecover(hash, r, vs);\\n } else {\\n return (address(0), RecoverError.InvalidSignatureLength);\\n }\\n }\\n\\n /**\\n * @dev Returns the address that signed a hashed message (`hash`) with\\n * `signature`. This address can then be used for verification purposes.\\n *\\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\\n * this function rejects them by requiring the `s` value to be in the lower\\n * half order, and the `v` value to be either 27 or 28.\\n *\\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\\n * verification to be secure: it is possible to craft signatures that\\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\\n * this is by receiving a hash of the original message (which may otherwise\\n * be too long), and then calling {toEthSignedMessageHash} on it.\\n */\\n function recover(bytes32 hash, bytes memory signature) internal pure returns (address) {\\n (address recovered, RecoverError error) = tryRecover(hash, signature);\\n _throwError(error);\\n return recovered;\\n }\\n\\n /**\\n * @dev Overload of {ECDSA-tryRecover} that receives the `r` and `vs` short-signature fields separately.\\n *\\n * See https://eips.ethereum.org/EIPS/eip-2098[EIP-2098 short signatures]\\n *\\n * _Available since v4.3._\\n */\\n function tryRecover(\\n bytes32 hash,\\n bytes32 r,\\n bytes32 vs\\n ) internal pure returns (address, RecoverError) {\\n bytes32 s = vs & bytes32(0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff);\\n uint8 v = uint8((uint256(vs) >> 255) + 27);\\n return tryRecover(hash, v, r, s);\\n }\\n\\n /**\\n * @dev Overload of {ECDSA-recover} that receives the `r and `vs` short-signature fields separately.\\n *\\n * _Available since v4.2._\\n */\\n function recover(\\n bytes32 hash,\\n bytes32 r,\\n bytes32 vs\\n ) internal pure returns (address) {\\n (address recovered, RecoverError error) = tryRecover(hash, r, vs);\\n _throwError(error);\\n return recovered;\\n }\\n\\n /**\\n * @dev Overload of {ECDSA-tryRecover} that receives the `v`,\\n * `r` and `s` signature fields separately.\\n *\\n * _Available since v4.3._\\n */\\n function tryRecover(\\n bytes32 hash,\\n uint8 v,\\n bytes32 r,\\n bytes32 s\\n ) internal pure returns (address, RecoverError) {\\n // EIP-2 still allows signature malleability for ecrecover(). Remove this possibility and make the signature\\n // unique. Appendix F in the Ethereum Yellow paper (https://ethereum.github.io/yellowpaper/paper.pdf), defines\\n // the valid range for s in (301): 0 < s < secp256k1n \\u00f7 2 + 1, and for v in (302): v \\u2208 {27, 28}. Most\\n // signatures from current libraries generate a unique signature with an s-value in the lower half order.\\n //\\n // If your library generates malleable signatures, such as s-values in the upper range, calculate a new s-value\\n // with 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141 - s1 and flip v from 27 to 28 or\\n // vice versa. If your library also generates signatures with 0/1 for v instead 27/28, add 27 to v to accept\\n // these malleable signatures as well.\\n if (uint256(s) > 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D576E7357A4501DDFE92F46681B20A0) {\\n return (address(0), RecoverError.InvalidSignatureS);\\n }\\n if (v != 27 && v != 28) {\\n return (address(0), RecoverError.InvalidSignatureV);\\n }\\n\\n // If the signature is valid (and not malleable), return the signer address\\n address signer = ecrecover(hash, v, r, s);\\n if (signer == address(0)) {\\n return (address(0), RecoverError.InvalidSignature);\\n }\\n\\n return (signer, RecoverError.NoError);\\n }\\n\\n /**\\n * @dev Overload of {ECDSA-recover} that receives the `v`,\\n * `r` and `s` signature fields separately.\\n */\\n function recover(\\n bytes32 hash,\\n uint8 v,\\n bytes32 r,\\n bytes32 s\\n ) internal pure returns (address) {\\n (address recovered, RecoverError error) = tryRecover(hash, v, r, s);\\n _throwError(error);\\n return recovered;\\n }\\n\\n /**\\n * @dev Returns an Ethereum Signed Message, created from a `hash`. This\\n * produces hash corresponding to the one signed with the\\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\\n * JSON-RPC method as part of EIP-191.\\n *\\n * See {recover}.\\n */\\n function toEthSignedMessageHash(bytes32 hash) internal pure returns (bytes32) {\\n // 32 is the length in bytes of hash,\\n // enforced by the type signature above\\n return keccak256(abi.encodePacked(\\\"\\\\x19Ethereum Signed Message:\\\\n32\\\", hash));\\n }\\n\\n /**\\n * @dev Returns an Ethereum Signed Message, created from `s`. This\\n * produces hash corresponding to the one signed with the\\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\\n * JSON-RPC method as part of EIP-191.\\n *\\n * See {recover}.\\n */\\n function toEthSignedMessageHash(bytes memory s) internal pure returns (bytes32) {\\n return keccak256(abi.encodePacked(\\\"\\\\x19Ethereum Signed Message:\\\\n\\\", StringsUpgradeable.toString(s.length), s));\\n }\\n\\n /**\\n * @dev Returns an Ethereum Signed Typed Data, created from a\\n * `domainSeparator` and a `structHash`. This produces hash corresponding\\n * to the one signed with the\\n * https://eips.ethereum.org/EIPS/eip-712[`eth_signTypedData`]\\n * JSON-RPC method as part of EIP-712.\\n *\\n * See {recover}.\\n */\\n function toTypedDataHash(bytes32 domainSeparator, bytes32 structHash) internal pure returns (bytes32) {\\n return keccak256(abi.encodePacked(\\\"\\\\x19\\\\x01\\\", domainSeparator, structHash));\\n }\\n}\\n\",\"keccak256\":\"0xe8c62ca00ed2d0a4d9b7e3c4bf7d62c821618b2cdb3c844da91a1193986851bf\",\"license\":\"MIT\"},\"@openzeppelin/contracts-upgradeable/utils/cryptography/draft-EIP712Upgradeable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (utils/cryptography/draft-EIP712.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"./ECDSAUpgradeable.sol\\\";\\nimport \\\"../../proxy/utils/Initializable.sol\\\";\\n\\n/**\\n * @dev https://eips.ethereum.org/EIPS/eip-712[EIP 712] is a standard for hashing and signing of typed structured data.\\n *\\n * The encoding specified in the EIP is very generic, and such a generic implementation in Solidity is not feasible,\\n * thus this contract does not implement the encoding itself. Protocols need to implement the type-specific encoding\\n * they need in their contracts using a combination of `abi.encode` and `keccak256`.\\n *\\n * This contract implements the EIP 712 domain separator ({_domainSeparatorV4}) that is used as part of the encoding\\n * scheme, and the final step of the encoding to obtain the message digest that is then signed via ECDSA\\n * ({_hashTypedDataV4}).\\n *\\n * The implementation of the domain separator was designed to be as efficient as possible while still properly updating\\n * the chain id to protect against replay attacks on an eventual fork of the chain.\\n *\\n * NOTE: This contract implements the version of the encoding known as \\\"v4\\\", as implemented by the JSON RPC method\\n * https://docs.metamask.io/guide/signing-data.html[`eth_signTypedDataV4` in MetaMask].\\n *\\n * _Available since v3.4._\\n *\\n * @custom:storage-size 52\\n */\\nabstract contract EIP712Upgradeable is Initializable {\\n /* solhint-disable var-name-mixedcase */\\n bytes32 private _HASHED_NAME;\\n bytes32 private _HASHED_VERSION;\\n bytes32 private constant _TYPE_HASH = keccak256(\\\"EIP712Domain(string name,string version,uint256 chainId,address verifyingContract)\\\");\\n\\n /* solhint-enable var-name-mixedcase */\\n\\n /**\\n * @dev Initializes the domain separator and parameter caches.\\n *\\n * The meaning of `name` and `version` is specified in\\n * https://eips.ethereum.org/EIPS/eip-712#definition-of-domainseparator[EIP 712]:\\n *\\n * - `name`: the user readable name of the signing domain, i.e. the name of the DApp or the protocol.\\n * - `version`: the current major version of the signing domain.\\n *\\n * NOTE: These parameters cannot be changed except through a xref:learn::upgrading-smart-contracts.adoc[smart\\n * contract upgrade].\\n */\\n function __EIP712_init(string memory name, string memory version) internal onlyInitializing {\\n __EIP712_init_unchained(name, version);\\n }\\n\\n function __EIP712_init_unchained(string memory name, string memory version) internal onlyInitializing {\\n bytes32 hashedName = keccak256(bytes(name));\\n bytes32 hashedVersion = keccak256(bytes(version));\\n _HASHED_NAME = hashedName;\\n _HASHED_VERSION = hashedVersion;\\n }\\n\\n /**\\n * @dev Returns the domain separator for the current chain.\\n */\\n function _domainSeparatorV4() internal view returns (bytes32) {\\n return _buildDomainSeparator(_TYPE_HASH, _EIP712NameHash(), _EIP712VersionHash());\\n }\\n\\n function _buildDomainSeparator(\\n bytes32 typeHash,\\n bytes32 nameHash,\\n bytes32 versionHash\\n ) private view returns (bytes32) {\\n return keccak256(abi.encode(typeHash, nameHash, versionHash, block.chainid, address(this)));\\n }\\n\\n /**\\n * @dev Given an already https://eips.ethereum.org/EIPS/eip-712#definition-of-hashstruct[hashed struct], this\\n * function returns the hash of the fully encoded EIP712 message for this domain.\\n *\\n * This hash can be used together with {ECDSA-recover} to obtain the signer of a message. For example:\\n *\\n * ```solidity\\n * bytes32 digest = _hashTypedDataV4(keccak256(abi.encode(\\n * keccak256(\\\"Mail(address to,string contents)\\\"),\\n * mailTo,\\n * keccak256(bytes(mailContents))\\n * )));\\n * address signer = ECDSA.recover(digest, signature);\\n * ```\\n */\\n function _hashTypedDataV4(bytes32 structHash) internal view virtual returns (bytes32) {\\n return ECDSAUpgradeable.toTypedDataHash(_domainSeparatorV4(), structHash);\\n }\\n\\n /**\\n * @dev The hash of the name parameter for the EIP712 domain.\\n *\\n * NOTE: This function reads from storage by default, but can be redefined to return a constant value if gas costs\\n * are a concern.\\n */\\n function _EIP712NameHash() internal virtual view returns (bytes32) {\\n return _HASHED_NAME;\\n }\\n\\n /**\\n * @dev The hash of the version parameter for the EIP712 domain.\\n *\\n * NOTE: This function reads from storage by default, but can be redefined to return a constant value if gas costs\\n * are a concern.\\n */\\n function _EIP712VersionHash() internal virtual view returns (bytes32) {\\n return _HASHED_VERSION;\\n }\\n\\n /**\\n * @dev This empty reserved space is put in place to allow future versions to add new\\n * variables without shifting down storage in the inheritance chain.\\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\\n */\\n uint256[50] private __gap;\\n}\\n\",\"keccak256\":\"0xaf5a96100f421d61693605349511e43221d3c2e47d4b3efa87af2b936e2567fc\",\"license\":\"MIT\"},\"@openzeppelin/contracts/token/ERC20/IERC20.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.6.0) (token/ERC20/IERC20.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Interface of the ERC20 standard as defined in the EIP.\\n */\\ninterface IERC20 {\\n /**\\n * @dev Emitted when `value` tokens are moved from one account (`from`) to\\n * another (`to`).\\n *\\n * Note that `value` may be zero.\\n */\\n event Transfer(address indexed from, address indexed to, uint256 value);\\n\\n /**\\n * @dev Emitted when the allowance of a `spender` for an `owner` is set by\\n * a call to {approve}. `value` is the new allowance.\\n */\\n event Approval(address indexed owner, address indexed spender, uint256 value);\\n\\n /**\\n * @dev Returns the amount of tokens in existence.\\n */\\n function totalSupply() external view returns (uint256);\\n\\n /**\\n * @dev Returns the amount of tokens owned by `account`.\\n */\\n function balanceOf(address account) external view returns (uint256);\\n\\n /**\\n * @dev Moves `amount` tokens from the caller's account to `to`.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * Emits a {Transfer} event.\\n */\\n function transfer(address to, uint256 amount) external returns (bool);\\n\\n /**\\n * @dev Returns the remaining number of tokens that `spender` will be\\n * allowed to spend on behalf of `owner` through {transferFrom}. This is\\n * zero by default.\\n *\\n * This value changes when {approve} or {transferFrom} are called.\\n */\\n function allowance(address owner, address spender) external view returns (uint256);\\n\\n /**\\n * @dev Sets `amount` as the allowance of `spender` over the caller's tokens.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * IMPORTANT: Beware that changing an allowance with this method brings the risk\\n * that someone may use both the old and the new allowance by unfortunate\\n * transaction ordering. One possible solution to mitigate this race\\n * condition is to first reduce the spender's allowance to 0 and set the\\n * desired value afterwards:\\n * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729\\n *\\n * Emits an {Approval} event.\\n */\\n function approve(address spender, uint256 amount) external returns (bool);\\n\\n /**\\n * @dev Moves `amount` tokens from `from` to `to` using the\\n * allowance mechanism. `amount` is then deducted from the caller's\\n * allowance.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * Emits a {Transfer} event.\\n */\\n function transferFrom(\\n address from,\\n address to,\\n uint256 amount\\n ) external returns (bool);\\n}\\n\",\"keccak256\":\"0x9750c6b834f7b43000631af5cc30001c5f547b3ceb3635488f140f60e897ea6b\",\"license\":\"MIT\"},\"@openzeppelin/contracts/token/ERC20/extensions/draft-IERC20Permit.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (token/ERC20/extensions/draft-IERC20Permit.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Interface of the ERC20 Permit extension allowing approvals to be made via signatures, as defined in\\n * https://eips.ethereum.org/EIPS/eip-2612[EIP-2612].\\n *\\n * Adds the {permit} method, which can be used to change an account's ERC20 allowance (see {IERC20-allowance}) by\\n * presenting a message signed by the account. By not relying on {IERC20-approve}, the token holder account doesn't\\n * need to send a transaction, and thus is not required to hold Ether at all.\\n */\\ninterface IERC20Permit {\\n /**\\n * @dev Sets `value` as the allowance of `spender` over ``owner``'s tokens,\\n * given ``owner``'s signed approval.\\n *\\n * IMPORTANT: The same issues {IERC20-approve} has related to transaction\\n * ordering also apply here.\\n *\\n * Emits an {Approval} event.\\n *\\n * Requirements:\\n *\\n * - `spender` cannot be the zero address.\\n * - `deadline` must be a timestamp in the future.\\n * - `v`, `r` and `s` must be a valid `secp256k1` signature from `owner`\\n * over the EIP712-formatted function arguments.\\n * - the signature must use ``owner``'s current nonce (see {nonces}).\\n *\\n * For more information on the signature format, see the\\n * https://eips.ethereum.org/EIPS/eip-2612#specification[relevant EIP\\n * section].\\n */\\n function permit(\\n address owner,\\n address spender,\\n uint256 value,\\n uint256 deadline,\\n uint8 v,\\n bytes32 r,\\n bytes32 s\\n ) external;\\n\\n /**\\n * @dev Returns the current nonce for `owner`. This value must be\\n * included whenever a signature is generated for {permit}.\\n *\\n * Every successful call to {permit} increases ``owner``'s nonce by one. This\\n * prevents a signature from being used multiple times.\\n */\\n function nonces(address owner) external view returns (uint256);\\n\\n /**\\n * @dev Returns the domain separator used in the encoding of the signature for {permit}, as defined by {EIP712}.\\n */\\n // solhint-disable-next-line func-name-mixedcase\\n function DOMAIN_SEPARATOR() external view returns (bytes32);\\n}\\n\",\"keccak256\":\"0xf41ca991f30855bf80ffd11e9347856a517b977f0a6c2d52e6421a99b7840329\",\"license\":\"MIT\"},\"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.7.0) (token/ERC20/utils/SafeERC20.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../IERC20.sol\\\";\\nimport \\\"../extensions/draft-IERC20Permit.sol\\\";\\nimport \\\"../../../utils/Address.sol\\\";\\n\\n/**\\n * @title SafeERC20\\n * @dev Wrappers around ERC20 operations that throw on failure (when the token\\n * contract returns false). Tokens that return no value (and instead revert or\\n * throw on failure) are also supported, non-reverting calls are assumed to be\\n * successful.\\n * To use this library you can add a `using SafeERC20 for IERC20;` statement to your contract,\\n * which allows you to call the safe operations as `token.safeTransfer(...)`, etc.\\n */\\nlibrary SafeERC20 {\\n using Address for address;\\n\\n function safeTransfer(\\n IERC20 token,\\n address to,\\n uint256 value\\n ) internal {\\n _callOptionalReturn(token, abi.encodeWithSelector(token.transfer.selector, to, value));\\n }\\n\\n function safeTransferFrom(\\n IERC20 token,\\n address from,\\n address to,\\n uint256 value\\n ) internal {\\n _callOptionalReturn(token, abi.encodeWithSelector(token.transferFrom.selector, from, to, value));\\n }\\n\\n /**\\n * @dev Deprecated. This function has issues similar to the ones found in\\n * {IERC20-approve}, and its usage is discouraged.\\n *\\n * Whenever possible, use {safeIncreaseAllowance} and\\n * {safeDecreaseAllowance} instead.\\n */\\n function safeApprove(\\n IERC20 token,\\n address spender,\\n uint256 value\\n ) internal {\\n // safeApprove should only be called when setting an initial allowance,\\n // or when resetting it to zero. To increase and decrease it, use\\n // 'safeIncreaseAllowance' and 'safeDecreaseAllowance'\\n require(\\n (value == 0) || (token.allowance(address(this), spender) == 0),\\n \\\"SafeERC20: approve from non-zero to non-zero allowance\\\"\\n );\\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, value));\\n }\\n\\n function safeIncreaseAllowance(\\n IERC20 token,\\n address spender,\\n uint256 value\\n ) internal {\\n uint256 newAllowance = token.allowance(address(this), spender) + value;\\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));\\n }\\n\\n function safeDecreaseAllowance(\\n IERC20 token,\\n address spender,\\n uint256 value\\n ) internal {\\n unchecked {\\n uint256 oldAllowance = token.allowance(address(this), spender);\\n require(oldAllowance >= value, \\\"SafeERC20: decreased allowance below zero\\\");\\n uint256 newAllowance = oldAllowance - value;\\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));\\n }\\n }\\n\\n function safePermit(\\n IERC20Permit token,\\n address owner,\\n address spender,\\n uint256 value,\\n uint256 deadline,\\n uint8 v,\\n bytes32 r,\\n bytes32 s\\n ) internal {\\n uint256 nonceBefore = token.nonces(owner);\\n token.permit(owner, spender, value, deadline, v, r, s);\\n uint256 nonceAfter = token.nonces(owner);\\n require(nonceAfter == nonceBefore + 1, \\\"SafeERC20: permit did not succeed\\\");\\n }\\n\\n /**\\n * @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement\\n * on the return value: the return value is optional (but if data is returned, it must not be false).\\n * @param token The token targeted by the call.\\n * @param data The call data (encoded using abi.encode or one of its variants).\\n */\\n function _callOptionalReturn(IERC20 token, bytes memory data) private {\\n // We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since\\n // we're implementing it ourselves. We use {Address.functionCall} to perform this call, which verifies that\\n // the target address contains contract code and also asserts for success in the low-level call.\\n\\n bytes memory returndata = address(token).functionCall(data, \\\"SafeERC20: low-level call failed\\\");\\n if (returndata.length > 0) {\\n // Return data is optional\\n require(abi.decode(returndata, (bool)), \\\"SafeERC20: ERC20 operation did not succeed\\\");\\n }\\n }\\n}\\n\",\"keccak256\":\"0x032807210d1d7d218963d7355d62e021a84bf1b3339f4f50be2f63b53cccaf29\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/Address.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.7.0) (utils/Address.sol)\\n\\npragma solidity ^0.8.1;\\n\\n/**\\n * @dev Collection of functions related to the address type\\n */\\nlibrary Address {\\n /**\\n * @dev Returns true if `account` is a contract.\\n *\\n * [IMPORTANT]\\n * ====\\n * It is unsafe to assume that an address for which this function returns\\n * false is an externally-owned account (EOA) and not a contract.\\n *\\n * Among others, `isContract` will return false for the following\\n * types of addresses:\\n *\\n * - an externally-owned account\\n * - a contract in construction\\n * - an address where a contract will be created\\n * - an address where a contract lived, but was destroyed\\n * ====\\n *\\n * [IMPORTANT]\\n * ====\\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\\n *\\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\\n * constructor.\\n * ====\\n */\\n function isContract(address account) internal view returns (bool) {\\n // This method relies on extcodesize/address.code.length, which returns 0\\n // for contracts in construction, since the code is only stored at the end\\n // of the constructor execution.\\n\\n return account.code.length > 0;\\n }\\n\\n /**\\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\\n * `recipient`, forwarding all available gas and reverting on errors.\\n *\\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\\n * imposed by `transfer`, making them unable to receive funds via\\n * `transfer`. {sendValue} removes this limitation.\\n *\\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\\n *\\n * IMPORTANT: because control is transferred to `recipient`, care must be\\n * taken to not create reentrancy vulnerabilities. Consider using\\n * {ReentrancyGuard} or the\\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\\n */\\n function sendValue(address payable recipient, uint256 amount) internal {\\n require(address(this).balance >= amount, \\\"Address: insufficient balance\\\");\\n\\n (bool success, ) = recipient.call{value: amount}(\\\"\\\");\\n require(success, \\\"Address: unable to send value, recipient may have reverted\\\");\\n }\\n\\n /**\\n * @dev Performs a Solidity function call using a low level `call`. A\\n * plain `call` is an unsafe replacement for a function call: use this\\n * function instead.\\n *\\n * If `target` reverts with a revert reason, it is bubbled up by this\\n * function (like regular Solidity function calls).\\n *\\n * Returns the raw returned data. To convert to the expected return value,\\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\\n *\\n * Requirements:\\n *\\n * - `target` must be a contract.\\n * - calling `target` with `data` must not revert.\\n *\\n * _Available since v3.1._\\n */\\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\\n return functionCall(target, data, \\\"Address: low-level call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\\n * `errorMessage` as a fallback revert reason when `target` reverts.\\n *\\n * _Available since v3.1._\\n */\\n function functionCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n return functionCallWithValue(target, data, 0, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but also transferring `value` wei to `target`.\\n *\\n * Requirements:\\n *\\n * - the calling contract must have an ETH balance of at least `value`.\\n * - the called Solidity function must be `payable`.\\n *\\n * _Available since v3.1._\\n */\\n function functionCallWithValue(\\n address target,\\n bytes memory data,\\n uint256 value\\n ) internal returns (bytes memory) {\\n return functionCallWithValue(target, data, value, \\\"Address: low-level call with value failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\\n * with `errorMessage` as a fallback revert reason when `target` reverts.\\n *\\n * _Available since v3.1._\\n */\\n function functionCallWithValue(\\n address target,\\n bytes memory data,\\n uint256 value,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n require(address(this).balance >= value, \\\"Address: insufficient balance for call\\\");\\n require(isContract(target), \\\"Address: call to non-contract\\\");\\n\\n (bool success, bytes memory returndata) = target.call{value: value}(data);\\n return verifyCallResult(success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but performing a static call.\\n *\\n * _Available since v3.3._\\n */\\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\\n return functionStaticCall(target, data, \\\"Address: low-level static call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\\n * but performing a static call.\\n *\\n * _Available since v3.3._\\n */\\n function functionStaticCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal view returns (bytes memory) {\\n require(isContract(target), \\\"Address: static call to non-contract\\\");\\n\\n (bool success, bytes memory returndata) = target.staticcall(data);\\n return verifyCallResult(success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but performing a delegate call.\\n *\\n * _Available since v3.4._\\n */\\n function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {\\n return functionDelegateCall(target, data, \\\"Address: low-level delegate call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\\n * but performing a delegate call.\\n *\\n * _Available since v3.4._\\n */\\n function functionDelegateCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n require(isContract(target), \\\"Address: delegate call to non-contract\\\");\\n\\n (bool success, bytes memory returndata) = target.delegatecall(data);\\n return verifyCallResult(success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the\\n * revert reason using the provided one.\\n *\\n * _Available since v4.3._\\n */\\n function verifyCallResult(\\n bool success,\\n bytes memory returndata,\\n string memory errorMessage\\n ) internal pure returns (bytes memory) {\\n if (success) {\\n return returndata;\\n } else {\\n // Look for revert reason and bubble it up if present\\n if (returndata.length > 0) {\\n // The easiest way to bubble the revert reason is using memory via assembly\\n /// @solidity memory-safe-assembly\\n assembly {\\n let returndata_size := mload(returndata)\\n revert(add(32, returndata), returndata_size)\\n }\\n } else {\\n revert(errorMessage);\\n }\\n }\\n }\\n}\\n\",\"keccak256\":\"0xd6153ce99bcdcce22b124f755e72553295be6abcd63804cfdffceb188b8bef10\",\"license\":\"MIT\"},\"contracts/agToken/AgToken.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-3.0\\n\\npragma solidity ^0.8.12;\\n\\n/*\\n * \\u2588 \\n ***** \\u2593\\u2593\\u2593 \\n * \\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593 \\n * ///. \\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593 \\n ***** //////// \\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593 \\n * ///////////// \\u2593\\u2593\\u2593 \\n \\u2593\\u2593 ////////////////// \\u2588 \\u2593\\u2593 \\n \\u2593\\u2593 \\u2593\\u2593 /////////////////////// \\u2593\\u2593 \\u2593\\u2593 \\n \\u2593\\u2593 \\u2593\\u2593 //////////////////////////// \\u2593\\u2593 \\u2593\\u2593 \\n \\u2593\\u2593 \\u2593\\u2593 /////////\\u2593\\u2593\\u2593///////\\u2593\\u2593\\u2593///////// \\u2593\\u2593 \\u2593\\u2593 \\n \\u2593\\u2593 ,////////////////////////////////////// \\u2593\\u2593 \\u2593\\u2593 \\n \\u2593\\u2593 ////////////////////////////////////////// \\u2593\\u2593 \\n \\u2593\\u2593 //////////////////////\\u2593\\u2593\\u2593\\u2593///////////////////// \\n ,//////////////////////////////////////////////////// \\n .////////////////////////////////////////////////////////// \\n .//////////////////////////\\u2588\\u2588.,//////////////////////////\\u2588 \\n .//////////////////////\\u2588\\u2588\\u2588\\u2588..,./////////////////////\\u2588\\u2588 \\n ...////////////////\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588.....,.////////////////\\u2588\\u2588\\u2588 \\n ,.,////////////\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588 ........,///////////\\u2588\\u2588\\u2588\\u2588 \\n .,.,//////\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588 ,.......///////\\u2588\\u2588\\u2588\\u2588 \\n ,..//\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588 ........./\\u2588\\u2588\\u2588\\u2588 \\n ..,\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588 .....,\\u2588\\u2588\\u2588 \\n .\\u2588\\u2588 ,.,\\u2588 \\n \\n \\n \\n \\u2593\\u2593 \\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593 \\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593 \\u2593\\u2593 \\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593 \\n \\u2593\\u2593\\u2593\\u2593\\u2593\\u2593 \\u2593\\u2593\\u2593 \\u2593\\u2593\\u2593 \\u2593\\u2593\\u2593 \\u2593\\u2593 \\u2593\\u2593 \\u2593\\u2593\\u2593\\u2593 \\n \\u2593\\u2593\\u2593 \\u2593\\u2593\\u2593 \\u2593\\u2593\\u2593 \\u2593\\u2593\\u2593 \\u2593\\u2593\\u2593 \\u2593\\u2593\\u2593 \\u2593\\u2593 \\u2593\\u2593\\u2593\\u2593\\u2593 \\n \\u2593\\u2593\\u2593 \\u2593\\u2593 \\u2593\\u2593\\u2593 \\u2593\\u2593\\u2593 \\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593 \\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593 \\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593\\u2593 \\n*/\\n\\nimport \\\"../interfaces/IAgToken.sol\\\";\\nimport \\\"../interfaces/ITreasury.sol\\\";\\nimport \\\"@openzeppelin/contracts-upgradeable/token/ERC20/extensions/draft-ERC20PermitUpgradeable.sol\\\";\\n\\n/// @title AgToken\\n/// @author Angle Labs, Inc.\\n/// @notice Base contract for Angle agTokens on Ethereum and on other chains\\n/// @dev By default, agTokens are ERC-20 tokens with 18 decimals\\ncontract AgToken is IAgToken, ERC20PermitUpgradeable {\\n // =========================== PARAMETERS / VARIABLES ==========================\\n\\n /// @inheritdoc IAgToken\\n mapping(address => bool) public isMinter;\\n /// @notice Reference to the treasury contract which can grant minting rights\\n address public treasury;\\n\\n // =================================== EVENTS ==================================\\n\\n event TreasuryUpdated(address indexed _treasury);\\n event MinterToggled(address indexed minter);\\n\\n // =================================== ERRORS ==================================\\n\\n error BurnAmountExceedsAllowance();\\n error InvalidSender();\\n error InvalidTreasury();\\n error NotMinter();\\n error NotTreasury();\\n\\n // ================================ CONSTRUCTOR ================================\\n\\n /// @custom:oz-upgrades-unsafe-allow constructor\\n constructor() initializer {}\\n\\n /// @notice Initializes the `AgToken` contract\\n function initialize(string memory name_, string memory symbol_, address _treasury) external {\\n _initialize(name_, symbol_, _treasury);\\n }\\n\\n /// @notice Initializes the contract\\n function _initialize(string memory name_, string memory symbol_, address _treasury) internal virtual initializer {\\n if (address(ITreasury(_treasury).stablecoin()) != address(this)) revert InvalidTreasury();\\n __ERC20Permit_init(name_);\\n __ERC20_init(name_, symbol_);\\n treasury = _treasury;\\n emit TreasuryUpdated(_treasury);\\n }\\n\\n // ================================= MODIFIERS =================================\\n\\n /// @notice Checks to see if it is the `Treasury` calling this contract\\n modifier onlyTreasury() {\\n if (msg.sender != treasury) revert NotTreasury();\\n _;\\n }\\n\\n /// @notice Checks whether the sender has the minting right\\n modifier onlyMinter() {\\n if (!isMinter[msg.sender]) revert NotMinter();\\n _;\\n }\\n\\n // ============================= EXTERNAL FUNCTION =============================\\n\\n /// @notice Allows anyone to burn stablecoins\\n /// @param amount Amount of stablecoins to burn\\n /// @dev This function can typically be called if there is a settlement mechanism to burn stablecoins\\n function burnStablecoin(uint256 amount) external {\\n _burn(msg.sender, amount);\\n }\\n\\n // ========================= MINTER ROLE ONLY FUNCTIONS ========================\\n\\n /// @inheritdoc IAgToken\\n function burnSelf(uint256 amount, address burner) external onlyMinter {\\n _burn(burner, amount);\\n }\\n\\n /// @inheritdoc IAgToken\\n function burnFrom(uint256 amount, address burner, address sender) external onlyMinter {\\n if (burner != sender) {\\n uint256 currentAllowance = allowance(burner, sender);\\n if (currentAllowance < amount) revert BurnAmountExceedsAllowance();\\n _approve(burner, sender, currentAllowance - amount);\\n }\\n _burn(burner, amount);\\n }\\n\\n /// @inheritdoc IAgToken\\n function mint(address account, uint256 amount) external onlyMinter {\\n _mint(account, amount);\\n }\\n\\n // ========================== GOVERNANCE ONLY FUNCTIONS ==========================\\n\\n /// @inheritdoc IAgToken\\n function addMinter(address minter) external onlyTreasury {\\n isMinter[minter] = true;\\n emit MinterToggled(minter);\\n }\\n\\n /// @inheritdoc IAgToken\\n function removeMinter(address minter) external {\\n if (msg.sender != address(treasury) && msg.sender != minter) revert InvalidSender();\\n isMinter[minter] = false;\\n emit MinterToggled(minter);\\n }\\n\\n /// @inheritdoc IAgToken\\n function setTreasury(address _treasury) external virtual onlyTreasury {\\n treasury = _treasury;\\n emit TreasuryUpdated(_treasury);\\n }\\n}\\n\",\"keccak256\":\"0x671d54d7840179050e859cf09662fe0e2c34cfaf5ec3782148d6c29e77c54d17\",\"license\":\"GPL-3.0\"},\"contracts/agToken/AgTokenSideChainMultiBridge.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-3.0\\n\\npragma solidity ^0.8.12;\\n\\nimport \\\"./AgToken.sol\\\";\\nimport \\\"@openzeppelin/contracts/token/ERC20/IERC20.sol\\\";\\nimport \\\"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\\\";\\n\\n/// @title AgTokenSideChainMultiBridge\\n/// @author Angle Labs, Inc.\\n/// @notice Contract for Angle agTokens on other chains than Ethereum mainnet\\n/// @dev This contract supports bridge tokens having a minting right on the stablecoin (also referred to as the canonical\\n/// or the native token)\\ncontract AgTokenSideChainMultiBridge is AgToken {\\n using SafeERC20 for IERC20;\\n\\n /// @notice Base used for fee computation\\n uint256 public constant BASE_PARAMS = 1e9;\\n\\n // =============================== BRIDGING DATA ===============================\\n\\n /// @notice Struct with some data about a specific bridge token\\n struct BridgeDetails {\\n // Limit on the balance of bridge token held by the contract: it is designed\\n // to reduce the exposure of the system to hacks\\n uint256 limit;\\n // Limit on the hourly volume of token minted through this bridge\\n // Technically the limit over a rolling hour is hourlyLimit x2 as hourly limit\\n // is enforced only between x:00 and x+1:00\\n uint256 hourlyLimit;\\n // Fee taken for swapping in and out the token\\n uint64 fee;\\n // Whether the associated token is allowed or not\\n bool allowed;\\n // Whether swapping in and out from the associated token is paused or not\\n bool paused;\\n }\\n\\n /// @notice Maps a bridge token to data\\n mapping(address => BridgeDetails) public bridges;\\n /// @notice List of all bridge tokens\\n address[] public bridgeTokensList;\\n /// @notice Maps a bridge token to the associated hourly volume\\n mapping(address => mapping(uint256 => uint256)) public usage;\\n /// @notice Maps an address to whether it is exempt of fees for when it comes to swapping in and out\\n mapping(address => uint256) public isFeeExempt;\\n /// @notice Limit to the amount of tokens that can be sent from that chain to another chain\\n uint256 public chainTotalHourlyLimit;\\n /// @notice Usage per hour on that chain. Maps an hourly timestamp to the total volume swapped out on the chain\\n mapping(uint256 => uint256) public chainTotalUsage;\\n\\n // =================================== EVENTS ==================================\\n\\n event BridgeTokenAdded(address indexed bridgeToken, uint256 limit, uint256 hourlyLimit, uint64 fee, bool paused);\\n event BridgeTokenToggled(address indexed bridgeToken, bool toggleStatus);\\n event BridgeTokenRemoved(address indexed bridgeToken);\\n event BridgeTokenFeeUpdated(address indexed bridgeToken, uint64 fee);\\n event BridgeTokenLimitUpdated(address indexed bridgeToken, uint256 limit);\\n event BridgeTokenHourlyLimitUpdated(address indexed bridgeToken, uint256 hourlyLimit);\\n event HourlyLimitUpdated(uint256 hourlyLimit);\\n event Recovered(address indexed token, address indexed to, uint256 amount);\\n event FeeToggled(address indexed theAddress, uint256 toggleStatus);\\n\\n // =================================== ERRORS ==================================\\n\\n error AssetStillControlledInReserves();\\n error HourlyLimitExceeded();\\n error InvalidToken();\\n error NotGovernor();\\n error NotGovernorOrGuardian();\\n error TooBigAmount();\\n error TooHighParameterValue();\\n error ZeroAddress();\\n\\n // ================================= MODIFIERS =================================\\n\\n /// @notice Checks whether the `msg.sender` has the governor role or not\\n modifier onlyGovernor() {\\n if (!ITreasury(treasury).isGovernor(msg.sender)) revert NotGovernor();\\n _;\\n }\\n\\n /// @notice Checks whether the `msg.sender` has the governor role or the guardian role\\n modifier onlyGovernorOrGuardian() {\\n if (!ITreasury(treasury).isGovernorOrGuardian(msg.sender)) revert NotGovernorOrGuardian();\\n _;\\n }\\n\\n // ===================== EXTERNAL PERMISSIONLESS FUNCTIONS =====================\\n\\n /// @notice Returns the list of all supported bridge tokens\\n /// @dev Helpful for UIs\\n function allBridgeTokens() external view returns (address[] memory) {\\n return bridgeTokensList;\\n }\\n\\n /// @notice Returns the current volume for a bridge, for the current hour\\n /// @param bridgeToken Bridge used to mint\\n /// @dev Helpful for UIs\\n function currentUsage(address bridgeToken) external view returns (uint256) {\\n return usage[bridgeToken][block.timestamp / 3600];\\n }\\n\\n /// @notice Returns the current total volume on the chain for the current hour\\n /// @dev Helpful for UIs\\n function currentTotalUsage() external view returns (uint256) {\\n return chainTotalUsage[block.timestamp / 3600];\\n }\\n\\n /// @notice Mints the canonical token from a supported bridge token\\n /// @param bridgeToken Bridge token to use to mint\\n /// @param amount Amount of bridge tokens to send\\n /// @param to Address to which the stablecoin should be sent\\n /// @return Amount of the canonical stablecoin actually minted\\n /// @dev Some fees may be taken by the protocol depending on the token used and on the address calling\\n function swapIn(address bridgeToken, uint256 amount, address to) external returns (uint256) {\\n BridgeDetails memory bridgeDetails = bridges[bridgeToken];\\n if (!bridgeDetails.allowed || bridgeDetails.paused) revert InvalidToken();\\n uint256 balance = IERC20(bridgeToken).balanceOf(address(this));\\n if (balance + amount > bridgeDetails.limit) {\\n // In case someone maliciously sends tokens to this contract\\n // Or the limit changes\\n if (bridgeDetails.limit > balance) amount = bridgeDetails.limit - balance;\\n else {\\n amount = 0;\\n }\\n }\\n\\n // Checking requirement on the hourly volume\\n uint256 hour = block.timestamp / 3600;\\n uint256 hourlyUsage = usage[bridgeToken][hour];\\n if (hourlyUsage + amount > bridgeDetails.hourlyLimit) {\\n // Edge case when the hourly limit changes\\n amount = bridgeDetails.hourlyLimit > hourlyUsage ? bridgeDetails.hourlyLimit - hourlyUsage : 0;\\n }\\n usage[bridgeToken][hour] = hourlyUsage + amount;\\n\\n IERC20(bridgeToken).safeTransferFrom(msg.sender, address(this), amount);\\n uint256 canonicalOut = amount;\\n // Computing fees\\n if (isFeeExempt[msg.sender] == 0) {\\n canonicalOut -= (canonicalOut * bridgeDetails.fee) / BASE_PARAMS;\\n }\\n _mint(to, canonicalOut);\\n return canonicalOut;\\n }\\n\\n /// @notice Burns the canonical token in exchange for a bridge token\\n /// @param bridgeToken Bridge token required\\n /// @param amount Amount of canonical tokens to burn\\n /// @param to Address to which the bridge token should be sent\\n /// @return Amount of bridge tokens actually sent back\\n /// @dev Some fees may be taken by the protocol depending on the token used and on the address calling\\n function swapOut(address bridgeToken, uint256 amount, address to) external returns (uint256) {\\n BridgeDetails memory bridgeDetails = bridges[bridgeToken];\\n if (!bridgeDetails.allowed || bridgeDetails.paused) revert InvalidToken();\\n\\n uint256 hour = block.timestamp / 3600;\\n uint256 hourlyUsage = chainTotalUsage[hour] + amount;\\n // If the amount being swapped out exceeds the limit, we revert\\n // We don't want to change the amount being swapped out.\\n // The user can decide to send another tx with the correct amount to reach the limit\\n if (hourlyUsage > chainTotalHourlyLimit) revert HourlyLimitExceeded();\\n chainTotalUsage[hour] = hourlyUsage;\\n\\n _burn(msg.sender, amount);\\n uint256 bridgeOut = amount;\\n if (isFeeExempt[msg.sender] == 0) {\\n bridgeOut -= (bridgeOut * bridgeDetails.fee) / BASE_PARAMS;\\n }\\n IERC20(bridgeToken).safeTransfer(to, bridgeOut);\\n return bridgeOut;\\n }\\n\\n // ============================ GOVERNANCE FUNCTIONS ===========================\\n\\n /// @notice Adds support for a bridge token\\n /// @param bridgeToken Bridge token to add: it should be a version of the stablecoin from another bridge\\n /// @param limit Limit on the balance of bridge token this contract could hold\\n /// @param hourlyLimit Limit on the hourly volume for this bridge\\n /// @param paused Whether swapping for this token should be paused or not\\n /// @param fee Fee taken upon swapping for or against this token\\n function addBridgeToken(\\n address bridgeToken,\\n uint256 limit,\\n uint256 hourlyLimit,\\n uint64 fee,\\n bool paused\\n ) external onlyGovernor {\\n if (bridges[bridgeToken].allowed || bridgeToken == address(0)) revert InvalidToken();\\n if (fee > BASE_PARAMS) revert TooHighParameterValue();\\n BridgeDetails memory _bridge;\\n _bridge.limit = limit;\\n _bridge.hourlyLimit = hourlyLimit;\\n _bridge.paused = paused;\\n _bridge.fee = fee;\\n _bridge.allowed = true;\\n bridges[bridgeToken] = _bridge;\\n bridgeTokensList.push(bridgeToken);\\n emit BridgeTokenAdded(bridgeToken, limit, hourlyLimit, fee, paused);\\n }\\n\\n /// @notice Removes support for a token\\n /// @param bridgeToken Address of the bridge token to remove support for\\n function removeBridgeToken(address bridgeToken) external onlyGovernor {\\n if (IERC20(bridgeToken).balanceOf(address(this)) != 0) revert AssetStillControlledInReserves();\\n delete bridges[bridgeToken];\\n // Deletion from `bridgeTokensList` loop\\n uint256 bridgeTokensListLength = bridgeTokensList.length;\\n for (uint256 i; i < bridgeTokensListLength - 1; ++i) {\\n if (bridgeTokensList[i] == bridgeToken) {\\n // Replace the `bridgeToken` to remove with the last of the list\\n bridgeTokensList[i] = bridgeTokensList[bridgeTokensListLength - 1];\\n break;\\n }\\n }\\n // Remove last element in array\\n bridgeTokensList.pop();\\n emit BridgeTokenRemoved(bridgeToken);\\n }\\n\\n /// @notice Recovers any ERC20 token\\n /// @dev Can be used to withdraw bridge tokens for them to be de-bridged on mainnet\\n function recoverERC20(address tokenAddress, address to, uint256 amountToRecover) external onlyGovernor {\\n IERC20(tokenAddress).safeTransfer(to, amountToRecover);\\n emit Recovered(tokenAddress, to, amountToRecover);\\n }\\n\\n /// @notice Updates the `limit` amount for `bridgeToken`\\n function setLimit(address bridgeToken, uint256 limit) external onlyGovernorOrGuardian {\\n if (!bridges[bridgeToken].allowed) revert InvalidToken();\\n bridges[bridgeToken].limit = limit;\\n emit BridgeTokenLimitUpdated(bridgeToken, limit);\\n }\\n\\n /// @notice Updates the `hourlyLimit` amount for `bridgeToken`\\n function setHourlyLimit(address bridgeToken, uint256 hourlyLimit) external onlyGovernorOrGuardian {\\n if (!bridges[bridgeToken].allowed) revert InvalidToken();\\n bridges[bridgeToken].hourlyLimit = hourlyLimit;\\n emit BridgeTokenHourlyLimitUpdated(bridgeToken, hourlyLimit);\\n }\\n\\n /// @notice Updates the `chainTotalHourlyLimit` amount\\n function setChainTotalHourlyLimit(uint256 hourlyLimit) external onlyGovernorOrGuardian {\\n chainTotalHourlyLimit = hourlyLimit;\\n emit HourlyLimitUpdated(hourlyLimit);\\n }\\n\\n /// @notice Updates the `fee` value for `bridgeToken`\\n function setSwapFee(address bridgeToken, uint64 fee) external onlyGovernorOrGuardian {\\n if (!bridges[bridgeToken].allowed) revert InvalidToken();\\n if (fee > BASE_PARAMS) revert TooHighParameterValue();\\n bridges[bridgeToken].fee = fee;\\n emit BridgeTokenFeeUpdated(bridgeToken, fee);\\n }\\n\\n /// @notice Pauses or unpauses swapping in and out for a token\\n function toggleBridge(address bridgeToken) external onlyGovernorOrGuardian {\\n if (!bridges[bridgeToken].allowed) revert InvalidToken();\\n bool pausedStatus = bridges[bridgeToken].paused;\\n bridges[bridgeToken].paused = !pausedStatus;\\n emit BridgeTokenToggled(bridgeToken, !pausedStatus);\\n }\\n\\n /// @notice Toggles fees for the address `theAddress`\\n function toggleFeesForAddress(address theAddress) external onlyGovernorOrGuardian {\\n uint256 feeExemptStatus = 1 - isFeeExempt[theAddress];\\n isFeeExempt[theAddress] = feeExemptStatus;\\n emit FeeToggled(theAddress, feeExemptStatus);\\n }\\n}\\n\",\"keccak256\":\"0x9782497e84a1dc4bc468778ede4aceb35cebf74e4159e2af8f469f49312c3841\",\"license\":\"GPL-3.0\"},\"contracts/interfaces/IAgToken.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-3.0\\n\\npragma solidity ^0.8.12;\\n\\nimport \\\"@openzeppelin/contracts-upgradeable/token/ERC20/IERC20Upgradeable.sol\\\";\\n\\n/// @title IAgToken\\n/// @author Angle Labs, Inc.\\n/// @notice Interface for the stablecoins `AgToken` contracts\\n/// @dev This interface only contains functions of the `AgToken` contract which are called by other contracts\\n/// of this module or of the first module of the Angle Protocol\\ninterface IAgToken is IERC20Upgradeable {\\n // ======================= Minter Role Only Functions ===========================\\n\\n /// @notice Lets the `StableMaster` contract or another whitelisted contract mint agTokens\\n /// @param account Address to mint to\\n /// @param amount Amount to mint\\n /// @dev The contracts allowed to issue agTokens are the `StableMaster` contract, `VaultManager` contracts\\n /// associated to this stablecoin as well as the flash loan module (if activated) and potentially contracts\\n /// whitelisted by governance\\n function mint(address account, uint256 amount) external;\\n\\n /// @notice Burns `amount` tokens from a `burner` address after being asked to by `sender`\\n /// @param amount Amount of tokens to burn\\n /// @param burner Address to burn from\\n /// @param sender Address which requested the burn from `burner`\\n /// @dev This method is to be called by a contract with the minter right after being requested\\n /// to do so by a `sender` address willing to burn tokens from another `burner` address\\n /// @dev The method checks the allowance between the `sender` and the `burner`\\n function burnFrom(uint256 amount, address burner, address sender) external;\\n\\n /// @notice Burns `amount` tokens from a `burner` address\\n /// @param amount Amount of tokens to burn\\n /// @param burner Address to burn from\\n /// @dev This method is to be called by a contract with a minter right on the AgToken after being\\n /// requested to do so by an address willing to burn tokens from its address\\n function burnSelf(uint256 amount, address burner) external;\\n\\n // ========================= Treasury Only Functions ===========================\\n\\n /// @notice Adds a minter in the contract\\n /// @param minter Minter address to add\\n /// @dev Zero address checks are performed directly in the `Treasury` contract\\n function addMinter(address minter) external;\\n\\n /// @notice Removes a minter from the contract\\n /// @param minter Minter address to remove\\n /// @dev This function can also be called by a minter wishing to revoke itself\\n function removeMinter(address minter) external;\\n\\n /// @notice Sets a new treasury contract\\n /// @param _treasury New treasury address\\n function setTreasury(address _treasury) external;\\n\\n // ========================= External functions ================================\\n\\n /// @notice Checks whether an address has the right to mint agTokens\\n /// @param minter Address for which the minting right should be checked\\n /// @return Whether the address has the right to mint agTokens or not\\n function isMinter(address minter) external view returns (bool);\\n\\n /// @notice Get the associated treasury\\n function treasury() external view returns (address);\\n}\\n\",\"keccak256\":\"0x0c83efcfc1fb9ae9ba830f7b89e3dab9abf6ad7a6205a31aa35fbccaa837dcdc\",\"license\":\"GPL-3.0\"},\"contracts/interfaces/ICoreBorrow.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-3.0\\n\\npragma solidity ^0.8.12;\\n\\n/// @title ICoreBorrow\\n/// @author Angle Labs, Inc.\\n/// @notice Interface for the `CoreBorrow` contract\\n/// @dev This interface only contains functions of the `CoreBorrow` contract which are called by other contracts\\n/// of this module\\ninterface ICoreBorrow {\\n /// @notice Checks if an address corresponds to a treasury of a stablecoin with a flash loan\\n /// module initialized on it\\n /// @param treasury Address to check\\n /// @return Whether the address has the `FLASHLOANER_TREASURY_ROLE` or not\\n function isFlashLoanerTreasury(address treasury) external view returns (bool);\\n\\n /// @notice Checks whether an address is governor of the Angle Protocol or not\\n /// @param admin Address to check\\n /// @return Whether the address has the `GOVERNOR_ROLE` or not\\n function isGovernor(address admin) external view returns (bool);\\n\\n /// @notice Checks whether an address is governor or a guardian of the Angle Protocol or not\\n /// @param admin Address to check\\n /// @return Whether the address has the `GUARDIAN_ROLE` or not\\n /// @dev Governance should make sure when adding a governor to also give this governor the guardian\\n /// role by calling the `addGovernor` function\\n function isGovernorOrGuardian(address admin) external view returns (bool);\\n}\\n\",\"keccak256\":\"0x10249210cbf522775f040baf981d7d037472168ce2746d87473ac7c29a34e62e\",\"license\":\"GPL-3.0\"},\"contracts/interfaces/IFlashAngle.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-3.0\\n\\npragma solidity ^0.8.12;\\n\\nimport \\\"./IAgToken.sol\\\";\\nimport \\\"./ICoreBorrow.sol\\\";\\n\\n/// @title IFlashAngle\\n/// @author Angle Labs, Inc.\\n/// @notice Interface for the `FlashAngle` contract\\n/// @dev This interface only contains functions of the contract which are called by other contracts\\n/// of this module\\ninterface IFlashAngle {\\n /// @notice Reference to the `CoreBorrow` contract managing the FlashLoan module\\n function core() external view returns (ICoreBorrow);\\n\\n /// @notice Sends the fees taken from flash loans to the treasury contract associated to the stablecoin\\n /// @param stablecoin Stablecoin from which profits should be sent\\n /// @return balance Amount of profits sent\\n /// @dev This function can only be called by the treasury contract\\n function accrueInterestToTreasury(IAgToken stablecoin) external returns (uint256 balance);\\n\\n /// @notice Adds support for a stablecoin\\n /// @param _treasury Treasury associated to the stablecoin to add support for\\n /// @dev This function can only be called by the `CoreBorrow` contract\\n function addStablecoinSupport(address _treasury) external;\\n\\n /// @notice Removes support for a stablecoin\\n /// @param _treasury Treasury associated to the stablecoin to remove support for\\n /// @dev This function can only be called by the `CoreBorrow` contract\\n function removeStablecoinSupport(address _treasury) external;\\n\\n /// @notice Sets a new core contract\\n /// @param _core Core contract address to set\\n /// @dev This function can only be called by the `CoreBorrow` contract\\n function setCore(address _core) external;\\n}\\n\",\"keccak256\":\"0x39b0097f695b9e934bccdc72676c91513f1077cc5d0fd151908fd25a7c5cfbe4\",\"license\":\"GPL-3.0\"},\"contracts/interfaces/ITreasury.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-3.0\\n\\npragma solidity ^0.8.12;\\n\\nimport \\\"./IAgToken.sol\\\";\\nimport \\\"./ICoreBorrow.sol\\\";\\nimport \\\"./IFlashAngle.sol\\\";\\n\\n/// @title ITreasury\\n/// @author Angle Labs, Inc.\\n/// @notice Interface for the `Treasury` contract\\n/// @dev This interface only contains functions of the `Treasury` which are called by other contracts\\n/// of this module\\ninterface ITreasury {\\n /// @notice Stablecoin handled by this `treasury` contract\\n function stablecoin() external view returns (IAgToken);\\n\\n /// @notice Checks whether a given address has the governor role\\n /// @param admin Address to check\\n /// @return Whether the address has the governor role\\n /// @dev Access control is only kept in the `CoreBorrow` contract\\n function isGovernor(address admin) external view returns (bool);\\n\\n /// @notice Checks whether a given address has the guardian or the governor role\\n /// @param admin Address to check\\n /// @return Whether the address has the guardian or the governor role\\n /// @dev Access control is only kept in the `CoreBorrow` contract which means that this function\\n /// queries the `CoreBorrow` contract\\n function isGovernorOrGuardian(address admin) external view returns (bool);\\n\\n /// @notice Checks whether a given address has well been initialized in this contract\\n /// as a `VaultManager`\\n /// @param _vaultManager Address to check\\n /// @return Whether the address has been initialized or not\\n function isVaultManager(address _vaultManager) external view returns (bool);\\n\\n /// @notice Sets a new flash loan module for this stablecoin\\n /// @param _flashLoanModule Reference to the new flash loan module\\n /// @dev This function removes the minting right to the old flash loan module and grants\\n /// it to the new module\\n function setFlashLoanModule(address _flashLoanModule) external;\\n\\n /// @notice Gets the vault manager list\\n function vaultManagerList(uint256 i) external returns (address);\\n}\\n\",\"keccak256\":\"0x06c2f781c08732ce1b5845c083af5742716245baa6c519bd737f32b230a884c1\",\"license\":\"GPL-3.0\"}},\"version\":1}", + "bytecode": "0x60806040523480156200001157600080fd5b50600054610100900460ff1615808015620000335750600054600160ff909116105b8062000063575062000050306200013d60201b6200273a1760201c565b15801562000063575060005460ff166001145b620000cb5760405162461bcd60e51b815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201526d191e481a5b9a5d1a585b1a5e995960921b606482015260840160405180910390fd5b6000805460ff191660011790558015620000ef576000805461ff0019166101001790555b801562000136576000805461ff0019169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15b506200014c565b6001600160a01b03163b151590565b6146d0806200015c6000396000f3fe608060405234801561001057600080fd5b50600436106102ff5760003560e01c806361d027b31161019c5780639f48118f116100ee578063ced67f0c11610097578063dd62ed3e11610071578063dd62ed3e14610724578063e3e286551461076a578063f0f442601461077d57600080fd5b8063ced67f0c1461066b578063d44ad63f146106fe578063d505accf1461071157600080fd5b8063aa271e1a116100c8578063aa271e1a14610620578063ba330bd714610643578063cd4839ca1461065657600080fd5b80639f48118f146105ef578063a457c2d7146105fa578063a9059cbb1461060d57600080fd5b80637ecebe001161015057806395d89b411161012a57806395d89b41146105c1578063983b2d56146105c95780639e4e0dae146105dc57600080fd5b80637ecebe00146105705780638933fb791461058357806390218cff146105ae57600080fd5b80637334d020116101815780637334d020146105425780637d4c9c2d146105555780637d74e25f1461056857600080fd5b806361d027b3146104c757806370a082311461050c57600080fd5b80633092afd511610255578063395093511161020957806340c10f19116101e357806340c10f19146104815780634dc32fcc146104945780635bfbec96146104a757600080fd5b8063395093511461043b5780633a55f89d1461044e5780633f4218e01461046157600080fd5b8063350ebe041161023a578063350ebe041461040d5780633644e5151461042057806336db43b51461042857600080fd5b80633092afd5146103eb578063313ce567146103fe57600080fd5b8063151dd755116102b757806323b872dd1161029157806323b872dd146103b25780632b471d8e146103c55780632e403e14146103d857600080fd5b8063151dd7551461038057806318160ddd146103a15780632342fb0e146103a957600080fd5b80630919a951116102e85780630919a95114610337578063095ea7b31461034a5780631171bda91461036d57600080fd5b806306fdde0314610304578063077f224a14610322575b600080fd5b61030c610790565b6040516103199190613e48565b60405180910390f35b610335610330366004613f95565b610822565b005b61033561034536600461400d565b610832565b61035d61035836600461402a565b610995565b6040519015158152602001610319565b61033561037b366004614056565b6109af565b61039361038e366004614097565b610b04565b604051908152602001610319565b603554610393565b61039360d25481565b61035d6103c0366004614056565b610dbe565b6103356103d33660046140ce565b610de2565b6103356103e636600461400d565b610e39565b6103356103f936600461400d565b6111e8565b60405160128152602001610319565b61033561041b3660046140fe565b6112d1565b6103936113da565b61033561043636600461402a565b6113e9565b61035d61044936600461402a565b611579565b61033561045c366004614135565b6115c0565b61039361046f36600461400d565b60d16020526000908152604090205481565b61033561048f36600461402a565b6116c3565b6103936104a236600461400d565b611716565b6103936104b5366004614135565b60d36020526000908152604090205481565b60cd546104e79073ffffffffffffffffffffffffffffffffffffffff1681565b60405173ffffffffffffffffffffffffffffffffffffffff9091168152602001610319565b61039361051a36600461400d565b73ffffffffffffffffffffffffffffffffffffffff1660009081526033602052604090205490565b61033561055036600461402a565b61175e565b610335610563366004614179565b6118f1565b610393611c59565b61039361057e36600461400d565b611c7e565b61039361059136600461402a565b60d060209081526000928352604080842090915290825290205481565b6103356105bc366004614135565b611ca9565b61030c611cb6565b6103356105d736600461400d565b611cc5565b6103356105ea3660046141d6565b611d8d565b610393633b9aca0081565b61035d61060836600461402a565b611f99565b61035d61061b36600461402a565b61206f565b61035d61062e36600461400d565b60cc6020526000908152604090205460ff1681565b6104e7610651366004614135565b61207d565b61065e6120b4565b604051610319919061420b565b6106c561067936600461400d565b60ce6020526000908152604090208054600182015460029092015490919067ffffffffffffffff81169060ff680100000000000000008204811691690100000000000000000090041685565b60408051958652602086019490945267ffffffffffffffff9092169284019290925290151560608301521515608082015260a001610319565b61039361070c366004614097565b612122565b61033561071f366004614265565b6122e7565b6103936107323660046142dc565b73ffffffffffffffffffffffffffffffffffffffff918216600090815260346020908152604080832093909416825291909152205490565b61033561077836600461400d565b6124a6565b61033561078b36600461400d565b61267a565b60606036805461079f9061430a565b80601f01602080910402602001604051908101604052809291908181526020018280546107cb9061430a565b80156108185780601f106107ed57610100808354040283529160200191610818565b820191906000526020600020905b8154815290600101906020018083116107fb57829003601f168201915b5050505050905090565b61082d838383612756565b505050565b60cd546040517f521d4de900000000000000000000000000000000000000000000000000000000815233600482015273ffffffffffffffffffffffffffffffffffffffff9091169063521d4de990602401602060405180830381865afa1580156108a0573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906108c49190614357565b6108fa576040517f99e120bc00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff8116600090815260d1602052604081205461092b9060016143a3565b73ffffffffffffffffffffffffffffffffffffffff8316600081815260d160205260409081902083905551919250907f979ef83e7e7a87cb48064e296dd7e997870d50f43acf8d7ad221313526c8ca0f906109899084815260200190565b60405180910390a25050565b6000336109a3818585612a35565b60019150505b92915050565b60cd546040517fe43581b800000000000000000000000000000000000000000000000000000000815233600482015273ffffffffffffffffffffffffffffffffffffffff9091169063e43581b890602401602060405180830381865afa158015610a1d573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610a419190614357565b610a77576040517fee3675d400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b610a9873ffffffffffffffffffffffffffffffffffffffff84168383612be0565b8173ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff167ffff3b3844276f57024e0b42afec1a37f75db36511e43819a4f2a63ab7862b64883604051610af791815260200190565b60405180910390a3505050565b73ffffffffffffffffffffffffffffffffffffffff8316600090815260ce60209081526040808320815160a081018352815481526001820154938101939093526002015467ffffffffffffffff81169183019190915260ff680100000000000000008204811615801560608501526901000000000000000000909204161515608083015280610b94575080608001515b15610bcb576040517fc1ab6dc100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015260009073ffffffffffffffffffffffffffffffffffffffff8716906370a0823190602401602060405180830381865afa158015610c38573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610c5c91906143b6565b8251909150610c6b86836143cf565b1115610c93578151811015610c8e578151610c879082906143a3565b9450610c93565b600094505b6000610ca1610e10426143e2565b73ffffffffffffffffffffffffffffffffffffffff8816600090815260d0602090815260408083208484528252909120549085015191925090610ce488836143cf565b1115610d0f5780846020015111610cfc576000610d0c565b808460200151610d0c91906143a3565b96505b610d1987826143cf565b73ffffffffffffffffffffffffffffffffffffffff8916600081815260d060209081526040808320878452909152902091909155610d599033308a612cb4565b33600090815260d16020526040812054889103610da657633b9aca00856040015167ffffffffffffffff1682610d8f919061441d565b610d9991906143e2565b610da390826143a3565b90505b610db08782612d12565b9450505050505b9392505050565b600033610dcc858285612e32565b610dd7858585612f03565b506001949350505050565b33600090815260cc602052604090205460ff16610e2b576040517ff8d2906c00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b610e3581836131b6565b5050565b60cd546040517fe43581b800000000000000000000000000000000000000000000000000000000815233600482015273ffffffffffffffffffffffffffffffffffffffff9091169063e43581b890602401602060405180830381865afa158015610ea7573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610ecb9190614357565b610f01576040517fee3675d400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015273ffffffffffffffffffffffffffffffffffffffff8216906370a0823190602401602060405180830381865afa158015610f6b573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610f8f91906143b6565b15610fc6576040517f2ef630ec00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff8116600090815260ce602052604081208181556001810182905560020180547fffffffffffffffffffffffffffffffffffffffffffff0000000000000000000016905560cf54905b61102e6001836143a3565b811015611139578273ffffffffffffffffffffffffffffffffffffffff1660cf828154811061105f5761105f614434565b60009182526020909120015473ffffffffffffffffffffffffffffffffffffffff16036111295760cf6110936001846143a3565b815481106110a3576110a3614434565b60009182526020909120015460cf805473ffffffffffffffffffffffffffffffffffffffff90921691839081106110dc576110dc614434565b9060005260206000200160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550611139565b61113281614463565b9050611023565b5060cf80548061114b5761114b61449b565b60008281526020812082017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff90810180547fffffffffffffffffffffffff000000000000000000000000000000000000000016905590910190915560405173ffffffffffffffffffffffffffffffffffffffff8416917f5c95b49c4d59d97a2f044167723f29c74b30f99702e3fd406c3830160aa9ccb891a25050565b60cd5473ffffffffffffffffffffffffffffffffffffffff16331480159061122657503373ffffffffffffffffffffffffffffffffffffffff821614155b1561125d576040517fddb5de5e00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff8116600081815260cc602052604080822080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00169055517f98c15241d6c02bc5ee0b780e11b3ea737a2defd9d04877edbe9f9497065bd02f9190a250565b33600090815260cc602052604090205460ff1661131a576040517ff8d2906c00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff16146113d05773ffffffffffffffffffffffffffffffffffffffff828116600090815260346020908152604080832093851683529290522054838110156113ba576040517f715ec26c00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6113ce83836113c987856143a3565b612a35565b505b61082d82846131b6565b60006113e46133a3565b905090565b60cd546040517f521d4de900000000000000000000000000000000000000000000000000000000815233600482015273ffffffffffffffffffffffffffffffffffffffff9091169063521d4de990602401602060405180830381865afa158015611457573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061147b9190614357565b6114b1576040517f99e120bc00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff8216600090815260ce602052604090206002015468010000000000000000900460ff1661151f576040517fc1ab6dc100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff8216600081815260ce602052604090819020839055517fe7b113fba37131b6396680a0c55790a697ec975e198ff8cfd89dac90a6379e61906109899084815260200190565b33600081815260346020908152604080832073ffffffffffffffffffffffffffffffffffffffff871684529091528120549091906109a390829086906113c99087906143cf565b60cd546040517f521d4de900000000000000000000000000000000000000000000000000000000815233600482015273ffffffffffffffffffffffffffffffffffffffff9091169063521d4de990602401602060405180830381865afa15801561162e573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906116529190614357565b611688576040517f99e120bc00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60d28190556040518181527fc3b69829afe2345596a02c8b587d41f796ba0094481d899e1b2e07b7532a1e219060200160405180910390a150565b33600090815260cc602052604090205460ff1661170c576040517ff8d2906c00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b610e358282612d12565b73ffffffffffffffffffffffffffffffffffffffff8116600090815260d06020526040812081611748610e10426143e2565b8152602001908152602001600020549050919050565b60cd546040517f521d4de900000000000000000000000000000000000000000000000000000000815233600482015273ffffffffffffffffffffffffffffffffffffffff9091169063521d4de990602401602060405180830381865afa1580156117cc573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906117f09190614357565b611826576040517f99e120bc00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff8216600090815260ce602052604090206002015468010000000000000000900460ff16611894576040517fc1ab6dc100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff8216600081815260ce602052604090819020600101839055517fe13ac9338b2ee623233f83c1b3ceab16490fa3e3737fac7f0970d0830a9f4871906109899084815260200190565b60cd546040517fe43581b800000000000000000000000000000000000000000000000000000000815233600482015273ffffffffffffffffffffffffffffffffffffffff9091169063e43581b890602401602060405180830381865afa15801561195f573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906119839190614357565b6119b9576040517fee3675d400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff8516600090815260ce602052604090206002015468010000000000000000900460ff1680611a10575073ffffffffffffffffffffffffffffffffffffffff8516155b15611a47576040517fc1ab6dc100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b633b9aca008267ffffffffffffffff161115611a8f576040517feca1d2c600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040805160a08101825260008082526020820181905291810182905260608101829052608081019190915284815260208082018581528315156080840190815267ffffffffffffffff808716604080870191825260016060880181815273ffffffffffffffffffffffffffffffffffffffff8e16600081815260ce9099528389208a5181559751888401559351600290970180549151965115156901000000000000000000027fffffffffffffffffffffffffffffffffffffffffffff00ffffffffffffffffff97151568010000000000000000027fffffffffffffffffffffffffffffffffffffffffffffff000000000000000000909316989096169790971717949094169290921790935560cf805492830181559093527facb8d954e2cfef495862221e91bd7523613cf8808827cb33edfe4904cc51bf290180547fffffffffffffffffffffffff0000000000000000000000000000000000000000168217905590517f53087ff85d80a7671594bd2e86b92af22e0b3c2c441c8033bba7399b7b5cbe2390611c49908890889088908890938452602084019290925267ffffffffffffffff1660408301521515606082015260800190565b60405180910390a2505050505050565b600060d381611c6a610e10426143e2565b815260200190815260200160002054905090565b73ffffffffffffffffffffffffffffffffffffffff81166000908152609960205260408120546109a9565b611cb333826131b6565b50565b60606037805461079f9061430a565b60cd5473ffffffffffffffffffffffffffffffffffffffff163314611d16576040517fb90cdbb100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff8116600081815260cc602052604080822080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00166001179055517f98c15241d6c02bc5ee0b780e11b3ea737a2defd9d04877edbe9f9497065bd02f9190a250565b60cd546040517f521d4de900000000000000000000000000000000000000000000000000000000815233600482015273ffffffffffffffffffffffffffffffffffffffff9091169063521d4de990602401602060405180830381865afa158015611dfb573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611e1f9190614357565b611e55576040517f99e120bc00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff8216600090815260ce602052604090206002015468010000000000000000900460ff16611ec3576040517fc1ab6dc100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b633b9aca008167ffffffffffffffff161115611f0b576040517feca1d2c600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff8216600081815260ce602090815260409182902060020180547fffffffffffffffffffffffffffffffffffffffffffffffff00000000000000001667ffffffffffffffff861690811790915591519182527f901f9de19b475adc8da4110434b8df940dce085afd05e2281c86807f3a899d299101610989565b33600081815260346020908152604080832073ffffffffffffffffffffffffffffffffffffffff8716845290915281205490919083811015612062576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602560248201527f45524332303a2064656372656173656420616c6c6f77616e63652062656c6f7760448201527f207a65726f00000000000000000000000000000000000000000000000000000060648201526084015b60405180910390fd5b610dd78286868403612a35565b6000336109a3818585612f03565b60cf818154811061208d57600080fd5b60009182526020909120015473ffffffffffffffffffffffffffffffffffffffff16905081565b606060cf80548060200260200160405190810160405280929190818152602001828054801561081857602002820191906000526020600020905b815473ffffffffffffffffffffffffffffffffffffffff1681526001909101906020018083116120ee575050505050905090565b73ffffffffffffffffffffffffffffffffffffffff8316600090815260ce60209081526040808320815160a081018352815481526001820154938101939093526002015467ffffffffffffffff81169183019190915260ff6801000000000000000082048116158015606085015269010000000000000000009092041615156080830152806121b2575080608001515b156121e9576040517fc1ab6dc100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60006121f7610e10426143e2565b600081815260d36020526040812054919250906122159087906143cf565b905060d254811115612253576040517f6d43d1ac00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600082815260d36020526040902081905561226e33876131b6565b33600090815260d160205260408120548791036122bb57633b9aca00846040015167ffffffffffffffff16826122a4919061441d565b6122ae91906143e2565b6122b890826143a3565b90505b6122dc73ffffffffffffffffffffffffffffffffffffffff89168783612be0565b979650505050505050565b83421115612351576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f45524332305065726d69743a206578706972656420646561646c696e650000006044820152606401612059565b60007f6e71edae12b1b97f4d1f60370fef10105fa2faae0126114a169c64845d6126c98888886123808c61341e565b60408051602081019690965273ffffffffffffffffffffffffffffffffffffffff94851690860152929091166060840152608083015260a082015260c0810186905260e00160405160208183030381529060405280519060200120905060006123e882613453565b905060006123f8828787876134bc565b90508973ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff161461248f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601e60248201527f45524332305065726d69743a20696e76616c6964207369676e617475726500006044820152606401612059565b61249a8a8a8a612a35565b50505050505050505050565b60cd546040517f521d4de900000000000000000000000000000000000000000000000000000000815233600482015273ffffffffffffffffffffffffffffffffffffffff9091169063521d4de990602401602060405180830381865afa158015612514573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906125389190614357565b61256e576040517f99e120bc00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff8116600090815260ce602052604090206002015468010000000000000000900460ff166125dc576040517fc1ab6dc100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff8116600081815260ce602090815260409182902060020180547fffffffffffffffffffffffffffffffffffffffffffff00ffffffffffffffffff811669010000000000000000009182900460ff16801592830291909117909255925192835292917ff7c93079dcbf699749d66345a351afab7d24219bb1d915c9f4fc4cf03f00d3979101610989565b60cd5473ffffffffffffffffffffffffffffffffffffffff1633146126cb576040517fb90cdbb100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60cd80547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83169081179091556040517f7dae230f18360d76a040c81f050aa14eb9d6dc7901b20fc5d855e2a20fe814d190600090a250565b73ffffffffffffffffffffffffffffffffffffffff163b151590565b600054610100900460ff16158080156127765750600054600160ff909116105b806127905750303b158015612790575060005460ff166001145b61281c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201527f647920696e697469616c697a65640000000000000000000000000000000000006064820152608401612059565b600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00166001179055801561287a57600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff166101001790555b3073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1663e9cbd8226040518163ffffffff1660e01b8152600401602060405180830381865afa1580156128dc573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061290091906144ca565b73ffffffffffffffffffffffffffffffffffffffff161461294d576040517f14bcf5c800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b612956846134e4565b61296084846135ba565b60cd80547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff84169081179091556040517f7dae230f18360d76a040c81f050aa14eb9d6dc7901b20fc5d855e2a20fe814d190600090a28015612a2f57600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15b50505050565b73ffffffffffffffffffffffffffffffffffffffff8316612ad7576040517f08c379a0000000000000000000000000000000000000000000000000000000008152602060048201526024808201527f45524332303a20617070726f76652066726f6d20746865207a65726f2061646460448201527f72657373000000000000000000000000000000000000000000000000000000006064820152608401612059565b73ffffffffffffffffffffffffffffffffffffffff8216612b7a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602260248201527f45524332303a20617070726f766520746f20746865207a65726f20616464726560448201527f73730000000000000000000000000000000000000000000000000000000000006064820152608401612059565b73ffffffffffffffffffffffffffffffffffffffff83811660008181526034602090815260408083209487168084529482529182902085905590518481527f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b9259101610af7565b60405173ffffffffffffffffffffffffffffffffffffffff831660248201526044810182905261082d9084907fa9059cbb00000000000000000000000000000000000000000000000000000000906064015b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff000000000000000000000000000000000000000000000000000000009093169290921790915261365b565b60405173ffffffffffffffffffffffffffffffffffffffff80851660248301528316604482015260648101829052612a2f9085907f23b872dd0000000000000000000000000000000000000000000000000000000090608401612c32565b73ffffffffffffffffffffffffffffffffffffffff8216612d8f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601f60248201527f45524332303a206d696e7420746f20746865207a65726f2061646472657373006044820152606401612059565b8060356000828254612da191906143cf565b909155505073ffffffffffffffffffffffffffffffffffffffff821660009081526033602052604081208054839290612ddb9084906143cf565b909155505060405181815273ffffffffffffffffffffffffffffffffffffffff8316906000907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef9060200160405180910390a35050565b73ffffffffffffffffffffffffffffffffffffffff8381166000908152603460209081526040808320938616835292905220547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8114612a2f5781811015612ef6576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f45524332303a20696e73756666696369656e7420616c6c6f77616e63650000006044820152606401612059565b612a2f8484848403612a35565b73ffffffffffffffffffffffffffffffffffffffff8316612fa6576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602560248201527f45524332303a207472616e736665722066726f6d20746865207a65726f20616460448201527f64726573730000000000000000000000000000000000000000000000000000006064820152608401612059565b73ffffffffffffffffffffffffffffffffffffffff8216613049576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602360248201527f45524332303a207472616e7366657220746f20746865207a65726f206164647260448201527f65737300000000000000000000000000000000000000000000000000000000006064820152608401612059565b73ffffffffffffffffffffffffffffffffffffffff8316600090815260336020526040902054818110156130ff576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f45524332303a207472616e7366657220616d6f756e742065786365656473206260448201527f616c616e636500000000000000000000000000000000000000000000000000006064820152608401612059565b73ffffffffffffffffffffffffffffffffffffffff8085166000908152603360205260408082208585039055918516815290812080548492906131439084906143cf565b925050819055508273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef846040516131a991815260200190565b60405180910390a3612a2f565b73ffffffffffffffffffffffffffffffffffffffff8216613259576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602160248201527f45524332303a206275726e2066726f6d20746865207a65726f2061646472657360448201527f73000000000000000000000000000000000000000000000000000000000000006064820152608401612059565b73ffffffffffffffffffffffffffffffffffffffff82166000908152603360205260409020548181101561330f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602260248201527f45524332303a206275726e20616d6f756e7420657863656564732062616c616e60448201527f63650000000000000000000000000000000000000000000000000000000000006064820152608401612059565b73ffffffffffffffffffffffffffffffffffffffff8316600090815260336020526040812083830390556035805484929061334b9084906143a3565b909155505060405182815260009073ffffffffffffffffffffffffffffffffffffffff8516907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef9060200160405180910390a3505050565b60006113e47f8b73c3c69bb8fe3d512ecc4cf759cc79239f7b179b0ffacaa9a75d522b39400f6133d260655490565b6066546040805160208101859052908101839052606081018290524660808201523060a082015260009060c0016040516020818303038152906040528051906020012090509392505050565b73ffffffffffffffffffffffffffffffffffffffff811660009081526099602052604090208054600181018255905b50919050565b60006109a96134606133a3565b836040517f19010000000000000000000000000000000000000000000000000000000000006020820152602281018390526042810182905260009060620160405160208183030381529060405280519060200120905092915050565b60008060006134cd87878787613767565b915091506134da8161387f565b5095945050505050565b600054610100900460ff1661357b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201527f6e697469616c697a696e670000000000000000000000000000000000000000006064820152608401612059565b611cb3816040518060400160405280600181526020017f3100000000000000000000000000000000000000000000000000000000000000815250613ad3565b600054610100900460ff16613651576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201527f6e697469616c697a696e670000000000000000000000000000000000000000006064820152608401612059565b610e358282613b84565b60006136bd826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c65648152508573ffffffffffffffffffffffffffffffffffffffff16613c349092919063ffffffff16565b80519091501561082d57808060200190518101906136db9190614357565b61082d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e60448201527f6f742073756363656564000000000000000000000000000000000000000000006064820152608401612059565b6000807f7fffffffffffffffffffffffffffffff5d576e7357a4501ddfe92f46681b20a083111561379e5750600090506003613876565b8460ff16601b141580156137b657508460ff16601c14155b156137c75750600090506004613876565b6040805160008082526020820180845289905260ff881692820192909252606081018690526080810185905260019060a0016020604051602081039080840390855afa15801561381b573d6000803e3d6000fd5b50506040517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0015191505073ffffffffffffffffffffffffffffffffffffffff811661386f57600060019250925050613876565b9150600090505b94509492505050565b6000816004811115613893576138936144e7565b0361389b5750565b60018160048111156138af576138af6144e7565b03613916576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601860248201527f45434453413a20696e76616c6964207369676e617475726500000000000000006044820152606401612059565b600281600481111561392a5761392a6144e7565b03613991576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601f60248201527f45434453413a20696e76616c6964207369676e6174757265206c656e677468006044820152606401612059565b60038160048111156139a5576139a56144e7565b03613a32576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602260248201527f45434453413a20696e76616c6964207369676e6174757265202773272076616c60448201527f75650000000000000000000000000000000000000000000000000000000000006064820152608401612059565b6004816004811115613a4657613a466144e7565b03611cb3576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602260248201527f45434453413a20696e76616c6964207369676e6174757265202776272076616c60448201527f75650000000000000000000000000000000000000000000000000000000000006064820152608401612059565b600054610100900460ff16613b6a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201527f6e697469616c697a696e670000000000000000000000000000000000000000006064820152608401612059565b815160209283012081519190920120606591909155606655565b600054610100900460ff16613c1b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201527f6e697469616c697a696e670000000000000000000000000000000000000000006064820152608401612059565b6036613c278382614564565b50603761082d8282614564565b6060613c438484600085613c4b565b949350505050565b606082471015613cdd576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f60448201527f722063616c6c00000000000000000000000000000000000000000000000000006064820152608401612059565b73ffffffffffffffffffffffffffffffffffffffff85163b613d5b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006044820152606401612059565b6000808673ffffffffffffffffffffffffffffffffffffffff168587604051613d84919061467e565b60006040518083038185875af1925050503d8060008114613dc1576040519150601f19603f3d011682016040523d82523d6000602084013e613dc6565b606091505b50915091506122dc82828660608315613de0575081610db7565b825115613df05782518084602001fd5b816040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016120599190613e48565b60005b83811015613e3f578181015183820152602001613e27565b50506000910152565b6020815260008251806020840152613e67816040850160208701613e24565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169190910160400192915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b600082601f830112613ed957600080fd5b813567ffffffffffffffff80821115613ef457613ef4613e99565b604051601f83017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0908116603f01168101908282118183101715613f3a57613f3a613e99565b81604052838152866020858801011115613f5357600080fd5b836020870160208301376000602085830101528094505050505092915050565b73ffffffffffffffffffffffffffffffffffffffff81168114611cb357600080fd5b600080600060608486031215613faa57600080fd5b833567ffffffffffffffff80821115613fc257600080fd5b613fce87838801613ec8565b94506020860135915080821115613fe457600080fd5b50613ff186828701613ec8565b925050604084013561400281613f73565b809150509250925092565b60006020828403121561401f57600080fd5b8135610db781613f73565b6000806040838503121561403d57600080fd5b823561404881613f73565b946020939093013593505050565b60008060006060848603121561406b57600080fd5b833561407681613f73565b9250602084013561408681613f73565b929592945050506040919091013590565b6000806000606084860312156140ac57600080fd5b83356140b781613f73565b925060208401359150604084013561400281613f73565b600080604083850312156140e157600080fd5b8235915060208301356140f381613f73565b809150509250929050565b60008060006060848603121561411357600080fd5b83359250602084013561412581613f73565b9150604084013561400281613f73565b60006020828403121561414757600080fd5b5035919050565b803567ffffffffffffffff8116811461416657600080fd5b919050565b8015158114611cb357600080fd5b600080600080600060a0868803121561419157600080fd5b853561419c81613f73565b945060208601359350604086013592506141b86060870161414e565b915060808601356141c88161416b565b809150509295509295909350565b600080604083850312156141e957600080fd5b82356141f481613f73565b91506142026020840161414e565b90509250929050565b6020808252825182820181905260009190848201906040850190845b8181101561425957835173ffffffffffffffffffffffffffffffffffffffff1683529284019291840191600101614227565b50909695505050505050565b600080600080600080600060e0888a03121561428057600080fd5b873561428b81613f73565b9650602088013561429b81613f73565b95506040880135945060608801359350608088013560ff811681146142bf57600080fd5b9699959850939692959460a0840135945060c09093013592915050565b600080604083850312156142ef57600080fd5b82356142fa81613f73565b915060208301356140f381613f73565b600181811c9082168061431e57607f821691505b60208210810361344d577f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b60006020828403121561436957600080fd5b8151610db78161416b565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b818103818111156109a9576109a9614374565b6000602082840312156143c857600080fd5b5051919050565b808201808211156109a9576109a9614374565b600082614418577f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b500490565b80820281158282048414176109a9576109a9614374565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff820361449457614494614374565b5060010190565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603160045260246000fd5b6000602082840312156144dc57600080fd5b8151610db781613f73565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b601f82111561082d57600081815260208120601f850160051c8101602086101561453d5750805b601f850160051c820191505b8181101561455c57828155600101614549565b505050505050565b815167ffffffffffffffff81111561457e5761457e613e99565b6145928161458c845461430a565b84614516565b602080601f8311600181146145e557600084156145af5750858301515b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600386901b1c1916600185901b17855561455c565b6000858152602081207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08616915b8281101561463257888601518255948401946001909101908401614613565b508582101561466e57878501517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600388901b60f8161c191681555b5050505050600190811b01905550565b60008251614690818460208701613e24565b919091019291505056fea2646970667358221220f2eb02bac1667a72be85ab617a5b5aa3d8f7a9b09b4d1fde9756b7a5636daf2164736f6c63430008110033", + "deployedBytecode": "0x608060405234801561001057600080fd5b50600436106102ff5760003560e01c806361d027b31161019c5780639f48118f116100ee578063ced67f0c11610097578063dd62ed3e11610071578063dd62ed3e14610724578063e3e286551461076a578063f0f442601461077d57600080fd5b8063ced67f0c1461066b578063d44ad63f146106fe578063d505accf1461071157600080fd5b8063aa271e1a116100c8578063aa271e1a14610620578063ba330bd714610643578063cd4839ca1461065657600080fd5b80639f48118f146105ef578063a457c2d7146105fa578063a9059cbb1461060d57600080fd5b80637ecebe001161015057806395d89b411161012a57806395d89b41146105c1578063983b2d56146105c95780639e4e0dae146105dc57600080fd5b80637ecebe00146105705780638933fb791461058357806390218cff146105ae57600080fd5b80637334d020116101815780637334d020146105425780637d4c9c2d146105555780637d74e25f1461056857600080fd5b806361d027b3146104c757806370a082311461050c57600080fd5b80633092afd511610255578063395093511161020957806340c10f19116101e357806340c10f19146104815780634dc32fcc146104945780635bfbec96146104a757600080fd5b8063395093511461043b5780633a55f89d1461044e5780633f4218e01461046157600080fd5b8063350ebe041161023a578063350ebe041461040d5780633644e5151461042057806336db43b51461042857600080fd5b80633092afd5146103eb578063313ce567146103fe57600080fd5b8063151dd755116102b757806323b872dd1161029157806323b872dd146103b25780632b471d8e146103c55780632e403e14146103d857600080fd5b8063151dd7551461038057806318160ddd146103a15780632342fb0e146103a957600080fd5b80630919a951116102e85780630919a95114610337578063095ea7b31461034a5780631171bda91461036d57600080fd5b806306fdde0314610304578063077f224a14610322575b600080fd5b61030c610790565b6040516103199190613e48565b60405180910390f35b610335610330366004613f95565b610822565b005b61033561034536600461400d565b610832565b61035d61035836600461402a565b610995565b6040519015158152602001610319565b61033561037b366004614056565b6109af565b61039361038e366004614097565b610b04565b604051908152602001610319565b603554610393565b61039360d25481565b61035d6103c0366004614056565b610dbe565b6103356103d33660046140ce565b610de2565b6103356103e636600461400d565b610e39565b6103356103f936600461400d565b6111e8565b60405160128152602001610319565b61033561041b3660046140fe565b6112d1565b6103936113da565b61033561043636600461402a565b6113e9565b61035d61044936600461402a565b611579565b61033561045c366004614135565b6115c0565b61039361046f36600461400d565b60d16020526000908152604090205481565b61033561048f36600461402a565b6116c3565b6103936104a236600461400d565b611716565b6103936104b5366004614135565b60d36020526000908152604090205481565b60cd546104e79073ffffffffffffffffffffffffffffffffffffffff1681565b60405173ffffffffffffffffffffffffffffffffffffffff9091168152602001610319565b61039361051a36600461400d565b73ffffffffffffffffffffffffffffffffffffffff1660009081526033602052604090205490565b61033561055036600461402a565b61175e565b610335610563366004614179565b6118f1565b610393611c59565b61039361057e36600461400d565b611c7e565b61039361059136600461402a565b60d060209081526000928352604080842090915290825290205481565b6103356105bc366004614135565b611ca9565b61030c611cb6565b6103356105d736600461400d565b611cc5565b6103356105ea3660046141d6565b611d8d565b610393633b9aca0081565b61035d61060836600461402a565b611f99565b61035d61061b36600461402a565b61206f565b61035d61062e36600461400d565b60cc6020526000908152604090205460ff1681565b6104e7610651366004614135565b61207d565b61065e6120b4565b604051610319919061420b565b6106c561067936600461400d565b60ce6020526000908152604090208054600182015460029092015490919067ffffffffffffffff81169060ff680100000000000000008204811691690100000000000000000090041685565b60408051958652602086019490945267ffffffffffffffff9092169284019290925290151560608301521515608082015260a001610319565b61039361070c366004614097565b612122565b61033561071f366004614265565b6122e7565b6103936107323660046142dc565b73ffffffffffffffffffffffffffffffffffffffff918216600090815260346020908152604080832093909416825291909152205490565b61033561077836600461400d565b6124a6565b61033561078b36600461400d565b61267a565b60606036805461079f9061430a565b80601f01602080910402602001604051908101604052809291908181526020018280546107cb9061430a565b80156108185780601f106107ed57610100808354040283529160200191610818565b820191906000526020600020905b8154815290600101906020018083116107fb57829003601f168201915b5050505050905090565b61082d838383612756565b505050565b60cd546040517f521d4de900000000000000000000000000000000000000000000000000000000815233600482015273ffffffffffffffffffffffffffffffffffffffff9091169063521d4de990602401602060405180830381865afa1580156108a0573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906108c49190614357565b6108fa576040517f99e120bc00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff8116600090815260d1602052604081205461092b9060016143a3565b73ffffffffffffffffffffffffffffffffffffffff8316600081815260d160205260409081902083905551919250907f979ef83e7e7a87cb48064e296dd7e997870d50f43acf8d7ad221313526c8ca0f906109899084815260200190565b60405180910390a25050565b6000336109a3818585612a35565b60019150505b92915050565b60cd546040517fe43581b800000000000000000000000000000000000000000000000000000000815233600482015273ffffffffffffffffffffffffffffffffffffffff9091169063e43581b890602401602060405180830381865afa158015610a1d573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610a419190614357565b610a77576040517fee3675d400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b610a9873ffffffffffffffffffffffffffffffffffffffff84168383612be0565b8173ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff167ffff3b3844276f57024e0b42afec1a37f75db36511e43819a4f2a63ab7862b64883604051610af791815260200190565b60405180910390a3505050565b73ffffffffffffffffffffffffffffffffffffffff8316600090815260ce60209081526040808320815160a081018352815481526001820154938101939093526002015467ffffffffffffffff81169183019190915260ff680100000000000000008204811615801560608501526901000000000000000000909204161515608083015280610b94575080608001515b15610bcb576040517fc1ab6dc100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015260009073ffffffffffffffffffffffffffffffffffffffff8716906370a0823190602401602060405180830381865afa158015610c38573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610c5c91906143b6565b8251909150610c6b86836143cf565b1115610c93578151811015610c8e578151610c879082906143a3565b9450610c93565b600094505b6000610ca1610e10426143e2565b73ffffffffffffffffffffffffffffffffffffffff8816600090815260d0602090815260408083208484528252909120549085015191925090610ce488836143cf565b1115610d0f5780846020015111610cfc576000610d0c565b808460200151610d0c91906143a3565b96505b610d1987826143cf565b73ffffffffffffffffffffffffffffffffffffffff8916600081815260d060209081526040808320878452909152902091909155610d599033308a612cb4565b33600090815260d16020526040812054889103610da657633b9aca00856040015167ffffffffffffffff1682610d8f919061441d565b610d9991906143e2565b610da390826143a3565b90505b610db08782612d12565b9450505050505b9392505050565b600033610dcc858285612e32565b610dd7858585612f03565b506001949350505050565b33600090815260cc602052604090205460ff16610e2b576040517ff8d2906c00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b610e3581836131b6565b5050565b60cd546040517fe43581b800000000000000000000000000000000000000000000000000000000815233600482015273ffffffffffffffffffffffffffffffffffffffff9091169063e43581b890602401602060405180830381865afa158015610ea7573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610ecb9190614357565b610f01576040517fee3675d400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015273ffffffffffffffffffffffffffffffffffffffff8216906370a0823190602401602060405180830381865afa158015610f6b573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610f8f91906143b6565b15610fc6576040517f2ef630ec00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff8116600090815260ce602052604081208181556001810182905560020180547fffffffffffffffffffffffffffffffffffffffffffff0000000000000000000016905560cf54905b61102e6001836143a3565b811015611139578273ffffffffffffffffffffffffffffffffffffffff1660cf828154811061105f5761105f614434565b60009182526020909120015473ffffffffffffffffffffffffffffffffffffffff16036111295760cf6110936001846143a3565b815481106110a3576110a3614434565b60009182526020909120015460cf805473ffffffffffffffffffffffffffffffffffffffff90921691839081106110dc576110dc614434565b9060005260206000200160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550611139565b61113281614463565b9050611023565b5060cf80548061114b5761114b61449b565b60008281526020812082017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff90810180547fffffffffffffffffffffffff000000000000000000000000000000000000000016905590910190915560405173ffffffffffffffffffffffffffffffffffffffff8416917f5c95b49c4d59d97a2f044167723f29c74b30f99702e3fd406c3830160aa9ccb891a25050565b60cd5473ffffffffffffffffffffffffffffffffffffffff16331480159061122657503373ffffffffffffffffffffffffffffffffffffffff821614155b1561125d576040517fddb5de5e00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff8116600081815260cc602052604080822080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00169055517f98c15241d6c02bc5ee0b780e11b3ea737a2defd9d04877edbe9f9497065bd02f9190a250565b33600090815260cc602052604090205460ff1661131a576040517ff8d2906c00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff16146113d05773ffffffffffffffffffffffffffffffffffffffff828116600090815260346020908152604080832093851683529290522054838110156113ba576040517f715ec26c00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6113ce83836113c987856143a3565b612a35565b505b61082d82846131b6565b60006113e46133a3565b905090565b60cd546040517f521d4de900000000000000000000000000000000000000000000000000000000815233600482015273ffffffffffffffffffffffffffffffffffffffff9091169063521d4de990602401602060405180830381865afa158015611457573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061147b9190614357565b6114b1576040517f99e120bc00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff8216600090815260ce602052604090206002015468010000000000000000900460ff1661151f576040517fc1ab6dc100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff8216600081815260ce602052604090819020839055517fe7b113fba37131b6396680a0c55790a697ec975e198ff8cfd89dac90a6379e61906109899084815260200190565b33600081815260346020908152604080832073ffffffffffffffffffffffffffffffffffffffff871684529091528120549091906109a390829086906113c99087906143cf565b60cd546040517f521d4de900000000000000000000000000000000000000000000000000000000815233600482015273ffffffffffffffffffffffffffffffffffffffff9091169063521d4de990602401602060405180830381865afa15801561162e573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906116529190614357565b611688576040517f99e120bc00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60d28190556040518181527fc3b69829afe2345596a02c8b587d41f796ba0094481d899e1b2e07b7532a1e219060200160405180910390a150565b33600090815260cc602052604090205460ff1661170c576040517ff8d2906c00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b610e358282612d12565b73ffffffffffffffffffffffffffffffffffffffff8116600090815260d06020526040812081611748610e10426143e2565b8152602001908152602001600020549050919050565b60cd546040517f521d4de900000000000000000000000000000000000000000000000000000000815233600482015273ffffffffffffffffffffffffffffffffffffffff9091169063521d4de990602401602060405180830381865afa1580156117cc573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906117f09190614357565b611826576040517f99e120bc00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff8216600090815260ce602052604090206002015468010000000000000000900460ff16611894576040517fc1ab6dc100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff8216600081815260ce602052604090819020600101839055517fe13ac9338b2ee623233f83c1b3ceab16490fa3e3737fac7f0970d0830a9f4871906109899084815260200190565b60cd546040517fe43581b800000000000000000000000000000000000000000000000000000000815233600482015273ffffffffffffffffffffffffffffffffffffffff9091169063e43581b890602401602060405180830381865afa15801561195f573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906119839190614357565b6119b9576040517fee3675d400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff8516600090815260ce602052604090206002015468010000000000000000900460ff1680611a10575073ffffffffffffffffffffffffffffffffffffffff8516155b15611a47576040517fc1ab6dc100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b633b9aca008267ffffffffffffffff161115611a8f576040517feca1d2c600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040805160a08101825260008082526020820181905291810182905260608101829052608081019190915284815260208082018581528315156080840190815267ffffffffffffffff808716604080870191825260016060880181815273ffffffffffffffffffffffffffffffffffffffff8e16600081815260ce9099528389208a5181559751888401559351600290970180549151965115156901000000000000000000027fffffffffffffffffffffffffffffffffffffffffffff00ffffffffffffffffff97151568010000000000000000027fffffffffffffffffffffffffffffffffffffffffffffff000000000000000000909316989096169790971717949094169290921790935560cf805492830181559093527facb8d954e2cfef495862221e91bd7523613cf8808827cb33edfe4904cc51bf290180547fffffffffffffffffffffffff0000000000000000000000000000000000000000168217905590517f53087ff85d80a7671594bd2e86b92af22e0b3c2c441c8033bba7399b7b5cbe2390611c49908890889088908890938452602084019290925267ffffffffffffffff1660408301521515606082015260800190565b60405180910390a2505050505050565b600060d381611c6a610e10426143e2565b815260200190815260200160002054905090565b73ffffffffffffffffffffffffffffffffffffffff81166000908152609960205260408120546109a9565b611cb333826131b6565b50565b60606037805461079f9061430a565b60cd5473ffffffffffffffffffffffffffffffffffffffff163314611d16576040517fb90cdbb100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff8116600081815260cc602052604080822080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00166001179055517f98c15241d6c02bc5ee0b780e11b3ea737a2defd9d04877edbe9f9497065bd02f9190a250565b60cd546040517f521d4de900000000000000000000000000000000000000000000000000000000815233600482015273ffffffffffffffffffffffffffffffffffffffff9091169063521d4de990602401602060405180830381865afa158015611dfb573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611e1f9190614357565b611e55576040517f99e120bc00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff8216600090815260ce602052604090206002015468010000000000000000900460ff16611ec3576040517fc1ab6dc100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b633b9aca008167ffffffffffffffff161115611f0b576040517feca1d2c600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff8216600081815260ce602090815260409182902060020180547fffffffffffffffffffffffffffffffffffffffffffffffff00000000000000001667ffffffffffffffff861690811790915591519182527f901f9de19b475adc8da4110434b8df940dce085afd05e2281c86807f3a899d299101610989565b33600081815260346020908152604080832073ffffffffffffffffffffffffffffffffffffffff8716845290915281205490919083811015612062576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602560248201527f45524332303a2064656372656173656420616c6c6f77616e63652062656c6f7760448201527f207a65726f00000000000000000000000000000000000000000000000000000060648201526084015b60405180910390fd5b610dd78286868403612a35565b6000336109a3818585612f03565b60cf818154811061208d57600080fd5b60009182526020909120015473ffffffffffffffffffffffffffffffffffffffff16905081565b606060cf80548060200260200160405190810160405280929190818152602001828054801561081857602002820191906000526020600020905b815473ffffffffffffffffffffffffffffffffffffffff1681526001909101906020018083116120ee575050505050905090565b73ffffffffffffffffffffffffffffffffffffffff8316600090815260ce60209081526040808320815160a081018352815481526001820154938101939093526002015467ffffffffffffffff81169183019190915260ff6801000000000000000082048116158015606085015269010000000000000000009092041615156080830152806121b2575080608001515b156121e9576040517fc1ab6dc100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60006121f7610e10426143e2565b600081815260d36020526040812054919250906122159087906143cf565b905060d254811115612253576040517f6d43d1ac00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600082815260d36020526040902081905561226e33876131b6565b33600090815260d160205260408120548791036122bb57633b9aca00846040015167ffffffffffffffff16826122a4919061441d565b6122ae91906143e2565b6122b890826143a3565b90505b6122dc73ffffffffffffffffffffffffffffffffffffffff89168783612be0565b979650505050505050565b83421115612351576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f45524332305065726d69743a206578706972656420646561646c696e650000006044820152606401612059565b60007f6e71edae12b1b97f4d1f60370fef10105fa2faae0126114a169c64845d6126c98888886123808c61341e565b60408051602081019690965273ffffffffffffffffffffffffffffffffffffffff94851690860152929091166060840152608083015260a082015260c0810186905260e00160405160208183030381529060405280519060200120905060006123e882613453565b905060006123f8828787876134bc565b90508973ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff161461248f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601e60248201527f45524332305065726d69743a20696e76616c6964207369676e617475726500006044820152606401612059565b61249a8a8a8a612a35565b50505050505050505050565b60cd546040517f521d4de900000000000000000000000000000000000000000000000000000000815233600482015273ffffffffffffffffffffffffffffffffffffffff9091169063521d4de990602401602060405180830381865afa158015612514573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906125389190614357565b61256e576040517f99e120bc00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff8116600090815260ce602052604090206002015468010000000000000000900460ff166125dc576040517fc1ab6dc100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff8116600081815260ce602090815260409182902060020180547fffffffffffffffffffffffffffffffffffffffffffff00ffffffffffffffffff811669010000000000000000009182900460ff16801592830291909117909255925192835292917ff7c93079dcbf699749d66345a351afab7d24219bb1d915c9f4fc4cf03f00d3979101610989565b60cd5473ffffffffffffffffffffffffffffffffffffffff1633146126cb576040517fb90cdbb100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60cd80547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83169081179091556040517f7dae230f18360d76a040c81f050aa14eb9d6dc7901b20fc5d855e2a20fe814d190600090a250565b73ffffffffffffffffffffffffffffffffffffffff163b151590565b600054610100900460ff16158080156127765750600054600160ff909116105b806127905750303b158015612790575060005460ff166001145b61281c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201527f647920696e697469616c697a65640000000000000000000000000000000000006064820152608401612059565b600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00166001179055801561287a57600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff166101001790555b3073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1663e9cbd8226040518163ffffffff1660e01b8152600401602060405180830381865afa1580156128dc573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061290091906144ca565b73ffffffffffffffffffffffffffffffffffffffff161461294d576040517f14bcf5c800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b612956846134e4565b61296084846135ba565b60cd80547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff84169081179091556040517f7dae230f18360d76a040c81f050aa14eb9d6dc7901b20fc5d855e2a20fe814d190600090a28015612a2f57600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15b50505050565b73ffffffffffffffffffffffffffffffffffffffff8316612ad7576040517f08c379a0000000000000000000000000000000000000000000000000000000008152602060048201526024808201527f45524332303a20617070726f76652066726f6d20746865207a65726f2061646460448201527f72657373000000000000000000000000000000000000000000000000000000006064820152608401612059565b73ffffffffffffffffffffffffffffffffffffffff8216612b7a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602260248201527f45524332303a20617070726f766520746f20746865207a65726f20616464726560448201527f73730000000000000000000000000000000000000000000000000000000000006064820152608401612059565b73ffffffffffffffffffffffffffffffffffffffff83811660008181526034602090815260408083209487168084529482529182902085905590518481527f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b9259101610af7565b60405173ffffffffffffffffffffffffffffffffffffffff831660248201526044810182905261082d9084907fa9059cbb00000000000000000000000000000000000000000000000000000000906064015b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff000000000000000000000000000000000000000000000000000000009093169290921790915261365b565b60405173ffffffffffffffffffffffffffffffffffffffff80851660248301528316604482015260648101829052612a2f9085907f23b872dd0000000000000000000000000000000000000000000000000000000090608401612c32565b73ffffffffffffffffffffffffffffffffffffffff8216612d8f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601f60248201527f45524332303a206d696e7420746f20746865207a65726f2061646472657373006044820152606401612059565b8060356000828254612da191906143cf565b909155505073ffffffffffffffffffffffffffffffffffffffff821660009081526033602052604081208054839290612ddb9084906143cf565b909155505060405181815273ffffffffffffffffffffffffffffffffffffffff8316906000907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef9060200160405180910390a35050565b73ffffffffffffffffffffffffffffffffffffffff8381166000908152603460209081526040808320938616835292905220547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8114612a2f5781811015612ef6576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f45524332303a20696e73756666696369656e7420616c6c6f77616e63650000006044820152606401612059565b612a2f8484848403612a35565b73ffffffffffffffffffffffffffffffffffffffff8316612fa6576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602560248201527f45524332303a207472616e736665722066726f6d20746865207a65726f20616460448201527f64726573730000000000000000000000000000000000000000000000000000006064820152608401612059565b73ffffffffffffffffffffffffffffffffffffffff8216613049576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602360248201527f45524332303a207472616e7366657220746f20746865207a65726f206164647260448201527f65737300000000000000000000000000000000000000000000000000000000006064820152608401612059565b73ffffffffffffffffffffffffffffffffffffffff8316600090815260336020526040902054818110156130ff576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f45524332303a207472616e7366657220616d6f756e742065786365656473206260448201527f616c616e636500000000000000000000000000000000000000000000000000006064820152608401612059565b73ffffffffffffffffffffffffffffffffffffffff8085166000908152603360205260408082208585039055918516815290812080548492906131439084906143cf565b925050819055508273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef846040516131a991815260200190565b60405180910390a3612a2f565b73ffffffffffffffffffffffffffffffffffffffff8216613259576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602160248201527f45524332303a206275726e2066726f6d20746865207a65726f2061646472657360448201527f73000000000000000000000000000000000000000000000000000000000000006064820152608401612059565b73ffffffffffffffffffffffffffffffffffffffff82166000908152603360205260409020548181101561330f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602260248201527f45524332303a206275726e20616d6f756e7420657863656564732062616c616e60448201527f63650000000000000000000000000000000000000000000000000000000000006064820152608401612059565b73ffffffffffffffffffffffffffffffffffffffff8316600090815260336020526040812083830390556035805484929061334b9084906143a3565b909155505060405182815260009073ffffffffffffffffffffffffffffffffffffffff8516907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef9060200160405180910390a3505050565b60006113e47f8b73c3c69bb8fe3d512ecc4cf759cc79239f7b179b0ffacaa9a75d522b39400f6133d260655490565b6066546040805160208101859052908101839052606081018290524660808201523060a082015260009060c0016040516020818303038152906040528051906020012090509392505050565b73ffffffffffffffffffffffffffffffffffffffff811660009081526099602052604090208054600181018255905b50919050565b60006109a96134606133a3565b836040517f19010000000000000000000000000000000000000000000000000000000000006020820152602281018390526042810182905260009060620160405160208183030381529060405280519060200120905092915050565b60008060006134cd87878787613767565b915091506134da8161387f565b5095945050505050565b600054610100900460ff1661357b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201527f6e697469616c697a696e670000000000000000000000000000000000000000006064820152608401612059565b611cb3816040518060400160405280600181526020017f3100000000000000000000000000000000000000000000000000000000000000815250613ad3565b600054610100900460ff16613651576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201527f6e697469616c697a696e670000000000000000000000000000000000000000006064820152608401612059565b610e358282613b84565b60006136bd826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c65648152508573ffffffffffffffffffffffffffffffffffffffff16613c349092919063ffffffff16565b80519091501561082d57808060200190518101906136db9190614357565b61082d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e60448201527f6f742073756363656564000000000000000000000000000000000000000000006064820152608401612059565b6000807f7fffffffffffffffffffffffffffffff5d576e7357a4501ddfe92f46681b20a083111561379e5750600090506003613876565b8460ff16601b141580156137b657508460ff16601c14155b156137c75750600090506004613876565b6040805160008082526020820180845289905260ff881692820192909252606081018690526080810185905260019060a0016020604051602081039080840390855afa15801561381b573d6000803e3d6000fd5b50506040517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0015191505073ffffffffffffffffffffffffffffffffffffffff811661386f57600060019250925050613876565b9150600090505b94509492505050565b6000816004811115613893576138936144e7565b0361389b5750565b60018160048111156138af576138af6144e7565b03613916576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601860248201527f45434453413a20696e76616c6964207369676e617475726500000000000000006044820152606401612059565b600281600481111561392a5761392a6144e7565b03613991576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601f60248201527f45434453413a20696e76616c6964207369676e6174757265206c656e677468006044820152606401612059565b60038160048111156139a5576139a56144e7565b03613a32576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602260248201527f45434453413a20696e76616c6964207369676e6174757265202773272076616c60448201527f75650000000000000000000000000000000000000000000000000000000000006064820152608401612059565b6004816004811115613a4657613a466144e7565b03611cb3576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602260248201527f45434453413a20696e76616c6964207369676e6174757265202776272076616c60448201527f75650000000000000000000000000000000000000000000000000000000000006064820152608401612059565b600054610100900460ff16613b6a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201527f6e697469616c697a696e670000000000000000000000000000000000000000006064820152608401612059565b815160209283012081519190920120606591909155606655565b600054610100900460ff16613c1b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201527f6e697469616c697a696e670000000000000000000000000000000000000000006064820152608401612059565b6036613c278382614564565b50603761082d8282614564565b6060613c438484600085613c4b565b949350505050565b606082471015613cdd576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f60448201527f722063616c6c00000000000000000000000000000000000000000000000000006064820152608401612059565b73ffffffffffffffffffffffffffffffffffffffff85163b613d5b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006044820152606401612059565b6000808673ffffffffffffffffffffffffffffffffffffffff168587604051613d84919061467e565b60006040518083038185875af1925050503d8060008114613dc1576040519150601f19603f3d011682016040523d82523d6000602084013e613dc6565b606091505b50915091506122dc82828660608315613de0575081610db7565b825115613df05782518084602001fd5b816040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016120599190613e48565b60005b83811015613e3f578181015183820152602001613e27565b50506000910152565b6020815260008251806020840152613e67816040850160208701613e24565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169190910160400192915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b600082601f830112613ed957600080fd5b813567ffffffffffffffff80821115613ef457613ef4613e99565b604051601f83017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0908116603f01168101908282118183101715613f3a57613f3a613e99565b81604052838152866020858801011115613f5357600080fd5b836020870160208301376000602085830101528094505050505092915050565b73ffffffffffffffffffffffffffffffffffffffff81168114611cb357600080fd5b600080600060608486031215613faa57600080fd5b833567ffffffffffffffff80821115613fc257600080fd5b613fce87838801613ec8565b94506020860135915080821115613fe457600080fd5b50613ff186828701613ec8565b925050604084013561400281613f73565b809150509250925092565b60006020828403121561401f57600080fd5b8135610db781613f73565b6000806040838503121561403d57600080fd5b823561404881613f73565b946020939093013593505050565b60008060006060848603121561406b57600080fd5b833561407681613f73565b9250602084013561408681613f73565b929592945050506040919091013590565b6000806000606084860312156140ac57600080fd5b83356140b781613f73565b925060208401359150604084013561400281613f73565b600080604083850312156140e157600080fd5b8235915060208301356140f381613f73565b809150509250929050565b60008060006060848603121561411357600080fd5b83359250602084013561412581613f73565b9150604084013561400281613f73565b60006020828403121561414757600080fd5b5035919050565b803567ffffffffffffffff8116811461416657600080fd5b919050565b8015158114611cb357600080fd5b600080600080600060a0868803121561419157600080fd5b853561419c81613f73565b945060208601359350604086013592506141b86060870161414e565b915060808601356141c88161416b565b809150509295509295909350565b600080604083850312156141e957600080fd5b82356141f481613f73565b91506142026020840161414e565b90509250929050565b6020808252825182820181905260009190848201906040850190845b8181101561425957835173ffffffffffffffffffffffffffffffffffffffff1683529284019291840191600101614227565b50909695505050505050565b600080600080600080600060e0888a03121561428057600080fd5b873561428b81613f73565b9650602088013561429b81613f73565b95506040880135945060608801359350608088013560ff811681146142bf57600080fd5b9699959850939692959460a0840135945060c09093013592915050565b600080604083850312156142ef57600080fd5b82356142fa81613f73565b915060208301356140f381613f73565b600181811c9082168061431e57607f821691505b60208210810361344d577f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b60006020828403121561436957600080fd5b8151610db78161416b565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b818103818111156109a9576109a9614374565b6000602082840312156143c857600080fd5b5051919050565b808201808211156109a9576109a9614374565b600082614418577f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b500490565b80820281158282048414176109a9576109a9614374565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff820361449457614494614374565b5060010190565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603160045260246000fd5b6000602082840312156144dc57600080fd5b8151610db781613f73565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b601f82111561082d57600081815260208120601f850160051c8101602086101561453d5750805b601f850160051c820191505b8181101561455c57828155600101614549565b505050505050565b815167ffffffffffffffff81111561457e5761457e613e99565b6145928161458c845461430a565b84614516565b602080601f8311600181146145e557600084156145af5750858301515b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600386901b1c1916600185901b17855561455c565b6000858152602081207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08616915b8281101561463257888601518255948401946001909101908401614613565b508582101561466e57878501517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600388901b60f8161c191681555b5050505050600190811b01905550565b60008251614690818460208701613e24565b919091019291505056fea2646970667358221220f2eb02bac1667a72be85ab617a5b5aa3d8f7a9b09b4d1fde9756b7a5636daf2164736f6c63430008110033", "devdoc": { "author": "Angle Labs, Inc.", - "details": "This contract supports bridge tokens having a minting right on the stablecoin (also referred to as the canonical or the native token)References: - FRAX implementation: https://polygonscan.com/address/0x45c32fA6DF82ead1e2EF74d17b76547EDdFaFF89#code - QiDAO implementation: https://snowtrace.io/address/0x5c49b268c9841AFF1Cc3B0a418ff5c3442eE3F3b#code", + "details": "This contract supports bridge tokens having a minting right on the stablecoin (also referred to as the canonical or the native token)", "kind": "dev", "methods": { "DOMAIN_SEPARATOR()": { @@ -1320,14 +1320,6 @@ "increaseAllowance(address,uint256)": { "details": "Atomically increases the allowance granted to `spender` by the caller. This is an alternative to {approve} that can be used as a mitigation for problems described in {IERC20-approve}. Emits an {Approval} event indicating the updated allowance. Requirements: - `spender` cannot be the zero address." }, - "initialize(string,string,address)": { - "details": "By default, agTokens are ERC-20 tokens with 18 decimals", - "params": { - "_treasury": "Reference to the `Treasury` contract associated to this agToken", - "name_": "Name of the token", - "symbol_": "Symbol of the token" - } - }, "mint(address,uint256)": { "details": "The contracts allowed to issue agTokens are the `StableMaster` contract, `VaultManager` contracts associated to this stablecoin as well as the flash loan module (if activated) and potentially contracts whitelisted by governance", "params": { @@ -1429,7 +1421,7 @@ "notice": "Burns `amount` tokens from a `burner` address" }, "burnStablecoin(uint256)": { - "notice": "Allows anyone to burn agToken without redeeming collateral back" + "notice": "Allows anyone to burn stablecoins" }, "chainTotalHourlyLimit()": { "notice": "Limit to the amount of tokens that can be sent from that chain to another chain" @@ -1624,7 +1616,7 @@ "type": "t_array(t_uint256)49_storage" }, { - "astId": 8510, + "astId": 7427, "contract": "contracts/agToken/AgTokenSideChainMultiBridge.sol:AgTokenSideChainMultiBridge", "label": "isMinter", "offset": 0, @@ -1632,7 +1624,7 @@ "type": "t_mapping(t_address,t_bool)" }, { - "astId": 8513, + "astId": 7430, "contract": "contracts/agToken/AgTokenSideChainMultiBridge.sol:AgTokenSideChainMultiBridge", "label": "treasury", "offset": 0, @@ -1640,15 +1632,15 @@ "type": "t_address" }, { - "astId": 7671, + "astId": 7739, "contract": "contracts/agToken/AgTokenSideChainMultiBridge.sol:AgTokenSideChainMultiBridge", "label": "bridges", "offset": 0, "slot": "206", - "type": "t_mapping(t_address,t_struct(BridgeDetails)7665_storage)" + "type": "t_mapping(t_address,t_struct(BridgeDetails)7733_storage)" }, { - "astId": 7675, + "astId": 7743, "contract": "contracts/agToken/AgTokenSideChainMultiBridge.sol:AgTokenSideChainMultiBridge", "label": "bridgeTokensList", "offset": 0, @@ -1656,7 +1648,7 @@ "type": "t_array(t_address)dyn_storage" }, { - "astId": 7682, + "astId": 7750, "contract": "contracts/agToken/AgTokenSideChainMultiBridge.sol:AgTokenSideChainMultiBridge", "label": "usage", "offset": 0, @@ -1664,7 +1656,7 @@ "type": "t_mapping(t_address,t_mapping(t_uint256,t_uint256))" }, { - "astId": 7687, + "astId": 7755, "contract": "contracts/agToken/AgTokenSideChainMultiBridge.sol:AgTokenSideChainMultiBridge", "label": "isFeeExempt", "offset": 0, @@ -1672,7 +1664,7 @@ "type": "t_mapping(t_address,t_uint256)" }, { - "astId": 7690, + "astId": 7758, "contract": "contracts/agToken/AgTokenSideChainMultiBridge.sol:AgTokenSideChainMultiBridge", "label": "chainTotalHourlyLimit", "offset": 0, @@ -1680,7 +1672,7 @@ "type": "t_uint256" }, { - "astId": 7695, + "astId": 7763, "contract": "contracts/agToken/AgTokenSideChainMultiBridge.sol:AgTokenSideChainMultiBridge", "label": "chainTotalUsage", "offset": 0, @@ -1749,12 +1741,12 @@ "numberOfBytes": "32", "value": "t_mapping(t_uint256,t_uint256)" }, - "t_mapping(t_address,t_struct(BridgeDetails)7665_storage)": { + "t_mapping(t_address,t_struct(BridgeDetails)7733_storage)": { "encoding": "mapping", "key": "t_address", "label": "mapping(address => struct AgTokenSideChainMultiBridge.BridgeDetails)", "numberOfBytes": "32", - "value": "t_struct(BridgeDetails)7665_storage" + "value": "t_struct(BridgeDetails)7733_storage" }, "t_mapping(t_address,t_struct(Counter)2493_storage)": { "encoding": "mapping", @@ -1782,12 +1774,12 @@ "label": "string", "numberOfBytes": "32" }, - "t_struct(BridgeDetails)7665_storage": { + "t_struct(BridgeDetails)7733_storage": { "encoding": "inplace", "label": "struct AgTokenSideChainMultiBridge.BridgeDetails", "members": [ { - "astId": 7656, + "astId": 7724, "contract": "contracts/agToken/AgTokenSideChainMultiBridge.sol:AgTokenSideChainMultiBridge", "label": "limit", "offset": 0, @@ -1795,7 +1787,7 @@ "type": "t_uint256" }, { - "astId": 7658, + "astId": 7726, "contract": "contracts/agToken/AgTokenSideChainMultiBridge.sol:AgTokenSideChainMultiBridge", "label": "hourlyLimit", "offset": 0, @@ -1803,7 +1795,7 @@ "type": "t_uint256" }, { - "astId": 7660, + "astId": 7728, "contract": "contracts/agToken/AgTokenSideChainMultiBridge.sol:AgTokenSideChainMultiBridge", "label": "fee", "offset": 0, @@ -1811,7 +1803,7 @@ "type": "t_uint64" }, { - "astId": 7662, + "astId": 7730, "contract": "contracts/agToken/AgTokenSideChainMultiBridge.sol:AgTokenSideChainMultiBridge", "label": "allowed", "offset": 8, @@ -1819,7 +1811,7 @@ "type": "t_bool" }, { - "astId": 7664, + "astId": 7732, "contract": "contracts/agToken/AgTokenSideChainMultiBridge.sol:AgTokenSideChainMultiBridge", "label": "paused", "offset": 9, diff --git a/deployments/polygonzkevm/CoreBorrowTest.json b/deployments/polygonzkevm/CoreBorrowTest.json new file mode 100644 index 00000000..8fe57130 --- /dev/null +++ b/deployments/polygonzkevm/CoreBorrowTest.json @@ -0,0 +1,337 @@ +{ + "address": "0xb1F2A25fFB2b095E99f430cAF507cC31F9A3EaAB", + "abi": [ + { + "inputs": [ + { + "internalType": "address", + "name": "_logic", + "type": "address" + }, + { + "internalType": "address", + "name": "admin_", + "type": "address" + }, + { + "internalType": "bytes", + "name": "_data", + "type": "bytes" + } + ], + "stateMutability": "payable", + "type": "constructor" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "previousAdmin", + "type": "address" + }, + { + "indexed": false, + "internalType": "address", + "name": "newAdmin", + "type": "address" + } + ], + "name": "AdminChanged", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "beacon", + "type": "address" + } + ], + "name": "BeaconUpgraded", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "implementation", + "type": "address" + } + ], + "name": "Upgraded", + "type": "event" + }, + { + "stateMutability": "payable", + "type": "fallback" + }, + { + "inputs": [], + "name": "admin", + "outputs": [ + { + "internalType": "address", + "name": "admin_", + "type": "address" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "newAdmin", + "type": "address" + } + ], + "name": "changeAdmin", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "implementation", + "outputs": [ + { + "internalType": "address", + "name": "implementation_", + "type": "address" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "newImplementation", + "type": "address" + } + ], + "name": "upgradeTo", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "newImplementation", + "type": "address" + }, + { + "internalType": "bytes", + "name": "data", + "type": "bytes" + } + ], + "name": "upgradeToAndCall", + "outputs": [], + "stateMutability": "payable", + "type": "function" + }, + { + "stateMutability": "payable", + "type": "receive" + } + ], + "transactionHash": "0x8b1bf46e68cc179583ccb00ba558c428e7925ecf6f2ddece9ce7f2385179f369", + "receipt": { + "to": null, + "from": "0xfdA462548Ce04282f4B6D6619823a7C64Fdc0185", + "contractAddress": "0xb1F2A25fFB2b095E99f430cAF507cC31F9A3EaAB", + "transactionIndex": 0, + "gasUsed": "1038543", + "logsBloom": "0x00000004000000000800000400000000480000000000000000000000200000000000000000080000000000000000000000000000000000000000000000000000000000000000000000000000000002000100000000000000000080000000000000000000420000400000000000000800000000800000000000000000000000000000000000000000004000000000000000000003800080000000000000804000000000000000000000000000000400000000000000000000001000000000001000000020020000000000008000041000000800000400000100000000010020000000800000000000000000000000000400000000100000000000000000040000", + "blockHash": "0xb43b4fffdb5b3c68f21414bcb5a62aaf415be7b0efb5dd8ff4d613caac39bd95", + "transactionHash": "0x8b1bf46e68cc179583ccb00ba558c428e7925ecf6f2ddece9ce7f2385179f369", + "logs": [ + { + "transactionIndex": 0, + "blockNumber": 9134280, + "transactionHash": "0x8b1bf46e68cc179583ccb00ba558c428e7925ecf6f2ddece9ce7f2385179f369", + "address": "0xb1F2A25fFB2b095E99f430cAF507cC31F9A3EaAB", + "topics": [ + "0xbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b", + "0x00000000000000000000000059153e939c5b4721543251ff3049ea04c755373b" + ], + "data": "0x", + "logIndex": 0, + "blockHash": "0xb43b4fffdb5b3c68f21414bcb5a62aaf415be7b0efb5dd8ff4d613caac39bd95" + }, + { + "transactionIndex": 0, + "blockNumber": 9134280, + "transactionHash": "0x8b1bf46e68cc179583ccb00ba558c428e7925ecf6f2ddece9ce7f2385179f369", + "address": "0xb1F2A25fFB2b095E99f430cAF507cC31F9A3EaAB", + "topics": [ + "0x2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d", + "0x7935bd0ae54bc31f548c14dba4d37c5c64b3f8ca900cb468fb8abd54d5894f55", + "0x000000000000000000000000fda462548ce04282f4b6d6619823a7c64fdc0185", + "0x000000000000000000000000fda462548ce04282f4b6d6619823a7c64fdc0185" + ], + "data": "0x", + "logIndex": 1, + "blockHash": "0xb43b4fffdb5b3c68f21414bcb5a62aaf415be7b0efb5dd8ff4d613caac39bd95" + }, + { + "transactionIndex": 0, + "blockNumber": 9134280, + "transactionHash": "0x8b1bf46e68cc179583ccb00ba558c428e7925ecf6f2ddece9ce7f2385179f369", + "address": "0xb1F2A25fFB2b095E99f430cAF507cC31F9A3EaAB", + "topics": [ + "0x2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d", + "0x55435dd261a4b9b3364963f7738a7a662ad9c84396d64be3365284bb7f0a5041", + "0x00000000000000000000000010def8a92c51c8082087356186a1485301078dcd", + "0x000000000000000000000000fda462548ce04282f4b6d6619823a7c64fdc0185" + ], + "data": "0x", + "logIndex": 2, + "blockHash": "0xb43b4fffdb5b3c68f21414bcb5a62aaf415be7b0efb5dd8ff4d613caac39bd95" + }, + { + "transactionIndex": 0, + "blockNumber": 9134280, + "transactionHash": "0x8b1bf46e68cc179583ccb00ba558c428e7925ecf6f2ddece9ce7f2385179f369", + "address": "0xb1F2A25fFB2b095E99f430cAF507cC31F9A3EaAB", + "topics": [ + "0x2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d", + "0x55435dd261a4b9b3364963f7738a7a662ad9c84396d64be3365284bb7f0a5041", + "0x000000000000000000000000fda462548ce04282f4b6d6619823a7c64fdc0185", + "0x000000000000000000000000fda462548ce04282f4b6d6619823a7c64fdc0185" + ], + "data": "0x", + "logIndex": 3, + "blockHash": "0xb43b4fffdb5b3c68f21414bcb5a62aaf415be7b0efb5dd8ff4d613caac39bd95" + }, + { + "transactionIndex": 0, + "blockNumber": 9134280, + "transactionHash": "0x8b1bf46e68cc179583ccb00ba558c428e7925ecf6f2ddece9ce7f2385179f369", + "address": "0xb1F2A25fFB2b095E99f430cAF507cC31F9A3EaAB", + "topics": [ + "0xbd79b86ffe0ab8e8776151514217cd7cacd52c909f66475c3af44e129f0b00ff", + "0x55435dd261a4b9b3364963f7738a7a662ad9c84396d64be3365284bb7f0a5041", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x7935bd0ae54bc31f548c14dba4d37c5c64b3f8ca900cb468fb8abd54d5894f55" + ], + "data": "0x", + "logIndex": 4, + "blockHash": "0xb43b4fffdb5b3c68f21414bcb5a62aaf415be7b0efb5dd8ff4d613caac39bd95" + }, + { + "transactionIndex": 0, + "blockNumber": 9134280, + "transactionHash": "0x8b1bf46e68cc179583ccb00ba558c428e7925ecf6f2ddece9ce7f2385179f369", + "address": "0xb1F2A25fFB2b095E99f430cAF507cC31F9A3EaAB", + "topics": [ + "0xbd79b86ffe0ab8e8776151514217cd7cacd52c909f66475c3af44e129f0b00ff", + "0x7935bd0ae54bc31f548c14dba4d37c5c64b3f8ca900cb468fb8abd54d5894f55", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x7935bd0ae54bc31f548c14dba4d37c5c64b3f8ca900cb468fb8abd54d5894f55" + ], + "data": "0x", + "logIndex": 5, + "blockHash": "0xb43b4fffdb5b3c68f21414bcb5a62aaf415be7b0efb5dd8ff4d613caac39bd95" + }, + { + "transactionIndex": 0, + "blockNumber": 9134280, + "transactionHash": "0x8b1bf46e68cc179583ccb00ba558c428e7925ecf6f2ddece9ce7f2385179f369", + "address": "0xb1F2A25fFB2b095E99f430cAF507cC31F9A3EaAB", + "topics": [ + "0xbd79b86ffe0ab8e8776151514217cd7cacd52c909f66475c3af44e129f0b00ff", + "0x0ae0130c6b34f32239dfe5e419a3fbd7546b44e99783257f2d93526d5a936d46", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x7935bd0ae54bc31f548c14dba4d37c5c64b3f8ca900cb468fb8abd54d5894f55" + ], + "data": "0x", + "logIndex": 6, + "blockHash": "0xb43b4fffdb5b3c68f21414bcb5a62aaf415be7b0efb5dd8ff4d613caac39bd95" + }, + { + "transactionIndex": 0, + "blockNumber": 9134280, + "transactionHash": "0x8b1bf46e68cc179583ccb00ba558c428e7925ecf6f2ddece9ce7f2385179f369", + "address": "0xb1F2A25fFB2b095E99f430cAF507cC31F9A3EaAB", + "topics": [ + "0x7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb3847402498" + ], + "data": "0x0000000000000000000000000000000000000000000000000000000000000001", + "logIndex": 7, + "blockHash": "0xb43b4fffdb5b3c68f21414bcb5a62aaf415be7b0efb5dd8ff4d613caac39bd95" + }, + { + "transactionIndex": 0, + "blockNumber": 9134280, + "transactionHash": "0x8b1bf46e68cc179583ccb00ba558c428e7925ecf6f2ddece9ce7f2385179f369", + "address": "0xb1F2A25fFB2b095E99f430cAF507cC31F9A3EaAB", + "topics": [ + "0x7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f" + ], + "data": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000001d941ef0d3bba4ad67dbfbcee5262f4cee53a32b", + "logIndex": 8, + "blockHash": "0xb43b4fffdb5b3c68f21414bcb5a62aaf415be7b0efb5dd8ff4d613caac39bd95" + } + ], + "blockNumber": 9134280, + "cumulativeGasUsed": "1038543", + "status": 1, + "byzantium": true + }, + "args": [ + "0x59153e939c5b4721543251ff3049Ea04c755373B", + "0x1D941EF0D3Bba4ad67DBfBCeE5262F4CEE53A32b", + "0x485cc955000000000000000000000000fda462548ce04282f4b6d6619823a7c64fdc018500000000000000000000000010def8a92c51c8082087356186a1485301078dcd" + ], + "numDeployments": 1, + "solcInputHash": "871924e0c138825a2736b76def8fef8d", + "metadata": "{\"compiler\":{\"version\":\"0.8.17+commit.8df45f5f\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_logic\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"admin_\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"_data\",\"type\":\"bytes\"}],\"stateMutability\":\"payable\",\"type\":\"constructor\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"previousAdmin\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"newAdmin\",\"type\":\"address\"}],\"name\":\"AdminChanged\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"beacon\",\"type\":\"address\"}],\"name\":\"BeaconUpgraded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"implementation\",\"type\":\"address\"}],\"name\":\"Upgraded\",\"type\":\"event\"},{\"stateMutability\":\"payable\",\"type\":\"fallback\"},{\"inputs\":[],\"name\":\"admin\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"admin_\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newAdmin\",\"type\":\"address\"}],\"name\":\"changeAdmin\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"implementation\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"implementation_\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newImplementation\",\"type\":\"address\"}],\"name\":\"upgradeTo\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newImplementation\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"}],\"name\":\"upgradeToAndCall\",\"outputs\":[],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"stateMutability\":\"payable\",\"type\":\"receive\"}],\"devdoc\":{\"details\":\"This contract implements a proxy that is upgradeable by an admin. It is fully forked from OpenZeppelin `TransparentUpgradeableProxy` To avoid https://medium.com/nomic-labs-blog/malicious-backdoors-in-ethereum-proxies-62629adf3357[proxy selector clashing], which can potentially be used in an attack, this contract uses the https://blog.openzeppelin.com/the-transparent-proxy-pattern/[transparent proxy pattern]. This pattern implies two things that go hand in hand: 1. If any account other than the admin calls the proxy, the call will be forwarded to the implementation, even if that call matches one of the admin functions exposed by the proxy itself. 2. If the admin calls the proxy, it can access the admin functions, but its calls will never be forwarded to the implementation. If the admin tries to call a function on the implementation it will fail with an error that says \\\"admin cannot fallback to proxy target\\\". These properties mean that the admin account can only be used for admin actions like upgrading the proxy or changing the admin, so it's best if it's a dedicated account that is not used for anything else. This will avoid headaches due to sudden errors when trying to call a function from the proxy implementation. Our recommendation is for the dedicated account to be an instance of the {ProxyAdmin} contract. If set up this way, you should think of the `ProxyAdmin` instance as the real administrative interface of your proxy.\",\"kind\":\"dev\",\"methods\":{\"admin()\":{\"details\":\"Returns the current admin. NOTE: Only the admin can call this function. See {ProxyAdmin-getProxyAdmin}. TIP: To get this value clients can read directly from the storage slot shown below (specified by EIP1967) using the https://eth.wiki/json-rpc/API#eth_getstorageat[`eth_getStorageAt`] RPC call. `0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103`\"},\"changeAdmin(address)\":{\"details\":\"Changes the admin of the proxy. Emits an {AdminChanged} event. NOTE: Only the admin can call this function. See {ProxyAdmin-changeProxyAdmin}.\"},\"constructor\":{\"details\":\"Initializes an upgradeable proxy managed by `_admin`, backed by the implementation at `_logic`, and optionally initialized with `_data` as explained in {ERC1967Proxy-constructor}.\"},\"implementation()\":{\"details\":\"Returns the current implementation. NOTE: Only the admin can call this function. See {ProxyAdmin-getProxyImplementation}. TIP: To get this value clients can read directly from the storage slot shown below (specified by EIP1967) using the https://eth.wiki/json-rpc/API#eth_getstorageat[`eth_getStorageAt`] RPC call. `0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc`\"},\"upgradeTo(address)\":{\"details\":\"Upgrade the implementation of the proxy. NOTE: Only the admin can call this function. See {ProxyAdmin-upgrade}.\"},\"upgradeToAndCall(address,bytes)\":{\"details\":\"Upgrade the implementation of the proxy, and then call a function from the new implementation as specified by `data`, which should be an encoded function call. This is useful to initialize new storage variables in the proxied contract. NOTE: Only the admin can call this function. See {ProxyAdmin-upgradeAndCall}.\"}},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/external/TransparentUpgradeableProxy.sol\":\"TransparentUpgradeableProxy\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":1000000},\"remappings\":[]},\"sources\":{\"@openzeppelin/contracts/interfaces/draft-IERC1822.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.5.0) (interfaces/draft-IERC1822.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev ERC1822: Universal Upgradeable Proxy Standard (UUPS) documents a method for upgradeability through a simplified\\n * proxy whose upgrades are fully controlled by the current implementation.\\n */\\ninterface IERC1822Proxiable {\\n /**\\n * @dev Returns the storage slot that the proxiable contract assumes is being used to store the implementation\\n * address.\\n *\\n * IMPORTANT: A proxy pointing at a proxiable contract should not be considered proxiable itself, because this risks\\n * bricking a proxy that upgrades to it, by delegating to itself until out of gas. Thus it is critical that this\\n * function revert if invoked through a proxy.\\n */\\n function proxiableUUID() external view returns (bytes32);\\n}\\n\",\"keccak256\":\"0x1d4afe6cb24200cc4545eed814ecf5847277dfe5d613a1707aad5fceecebcfff\",\"license\":\"MIT\"},\"@openzeppelin/contracts/proxy/ERC1967/ERC1967Proxy.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.7.0) (proxy/ERC1967/ERC1967Proxy.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../Proxy.sol\\\";\\nimport \\\"./ERC1967Upgrade.sol\\\";\\n\\n/**\\n * @dev This contract implements an upgradeable proxy. It is upgradeable because calls are delegated to an\\n * implementation address that can be changed. This address is stored in storage in the location specified by\\n * https://eips.ethereum.org/EIPS/eip-1967[EIP1967], so that it doesn't conflict with the storage layout of the\\n * implementation behind the proxy.\\n */\\ncontract ERC1967Proxy is Proxy, ERC1967Upgrade {\\n /**\\n * @dev Initializes the upgradeable proxy with an initial implementation specified by `_logic`.\\n *\\n * If `_data` is nonempty, it's used as data in a delegate call to `_logic`. This will typically be an encoded\\n * function call, and allows initializing the storage of the proxy like a Solidity constructor.\\n */\\n constructor(address _logic, bytes memory _data) payable {\\n _upgradeToAndCall(_logic, _data, false);\\n }\\n\\n /**\\n * @dev Returns the current implementation address.\\n */\\n function _implementation() internal view virtual override returns (address impl) {\\n return ERC1967Upgrade._getImplementation();\\n }\\n}\\n\",\"keccak256\":\"0xa2b22da3032e50b55f95ec1d13336102d675f341167aa76db571ef7f8bb7975d\",\"license\":\"MIT\"},\"@openzeppelin/contracts/proxy/ERC1967/ERC1967Upgrade.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.5.0) (proxy/ERC1967/ERC1967Upgrade.sol)\\n\\npragma solidity ^0.8.2;\\n\\nimport \\\"../beacon/IBeacon.sol\\\";\\nimport \\\"../../interfaces/draft-IERC1822.sol\\\";\\nimport \\\"../../utils/Address.sol\\\";\\nimport \\\"../../utils/StorageSlot.sol\\\";\\n\\n/**\\n * @dev This abstract contract provides getters and event emitting update functions for\\n * https://eips.ethereum.org/EIPS/eip-1967[EIP1967] slots.\\n *\\n * _Available since v4.1._\\n *\\n * @custom:oz-upgrades-unsafe-allow delegatecall\\n */\\nabstract contract ERC1967Upgrade {\\n // This is the keccak-256 hash of \\\"eip1967.proxy.rollback\\\" subtracted by 1\\n bytes32 private constant _ROLLBACK_SLOT = 0x4910fdfa16fed3260ed0e7147f7cc6da11a60208b5b9406d12a635614ffd9143;\\n\\n /**\\n * @dev Storage slot with the address of the current implementation.\\n * This is the keccak-256 hash of \\\"eip1967.proxy.implementation\\\" subtracted by 1, and is\\n * validated in the constructor.\\n */\\n bytes32 internal constant _IMPLEMENTATION_SLOT = 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc;\\n\\n /**\\n * @dev Emitted when the implementation is upgraded.\\n */\\n event Upgraded(address indexed implementation);\\n\\n /**\\n * @dev Returns the current implementation address.\\n */\\n function _getImplementation() internal view returns (address) {\\n return StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value;\\n }\\n\\n /**\\n * @dev Stores a new address in the EIP1967 implementation slot.\\n */\\n function _setImplementation(address newImplementation) private {\\n require(Address.isContract(newImplementation), \\\"ERC1967: new implementation is not a contract\\\");\\n StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value = newImplementation;\\n }\\n\\n /**\\n * @dev Perform implementation upgrade\\n *\\n * Emits an {Upgraded} event.\\n */\\n function _upgradeTo(address newImplementation) internal {\\n _setImplementation(newImplementation);\\n emit Upgraded(newImplementation);\\n }\\n\\n /**\\n * @dev Perform implementation upgrade with additional setup call.\\n *\\n * Emits an {Upgraded} event.\\n */\\n function _upgradeToAndCall(\\n address newImplementation,\\n bytes memory data,\\n bool forceCall\\n ) internal {\\n _upgradeTo(newImplementation);\\n if (data.length > 0 || forceCall) {\\n Address.functionDelegateCall(newImplementation, data);\\n }\\n }\\n\\n /**\\n * @dev Perform implementation upgrade with security checks for UUPS proxies, and additional setup call.\\n *\\n * Emits an {Upgraded} event.\\n */\\n function _upgradeToAndCallUUPS(\\n address newImplementation,\\n bytes memory data,\\n bool forceCall\\n ) internal {\\n // Upgrades from old implementations will perform a rollback test. This test requires the new\\n // implementation to upgrade back to the old, non-ERC1822 compliant, implementation. Removing\\n // this special case will break upgrade paths from old UUPS implementation to new ones.\\n if (StorageSlot.getBooleanSlot(_ROLLBACK_SLOT).value) {\\n _setImplementation(newImplementation);\\n } else {\\n try IERC1822Proxiable(newImplementation).proxiableUUID() returns (bytes32 slot) {\\n require(slot == _IMPLEMENTATION_SLOT, \\\"ERC1967Upgrade: unsupported proxiableUUID\\\");\\n } catch {\\n revert(\\\"ERC1967Upgrade: new implementation is not UUPS\\\");\\n }\\n _upgradeToAndCall(newImplementation, data, forceCall);\\n }\\n }\\n\\n /**\\n * @dev Storage slot with the admin of the contract.\\n * This is the keccak-256 hash of \\\"eip1967.proxy.admin\\\" subtracted by 1, and is\\n * validated in the constructor.\\n */\\n bytes32 internal constant _ADMIN_SLOT = 0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103;\\n\\n /**\\n * @dev Emitted when the admin account has changed.\\n */\\n event AdminChanged(address previousAdmin, address newAdmin);\\n\\n /**\\n * @dev Returns the current admin.\\n */\\n function _getAdmin() internal view returns (address) {\\n return StorageSlot.getAddressSlot(_ADMIN_SLOT).value;\\n }\\n\\n /**\\n * @dev Stores a new address in the EIP1967 admin slot.\\n */\\n function _setAdmin(address newAdmin) private {\\n require(newAdmin != address(0), \\\"ERC1967: new admin is the zero address\\\");\\n StorageSlot.getAddressSlot(_ADMIN_SLOT).value = newAdmin;\\n }\\n\\n /**\\n * @dev Changes the admin of the proxy.\\n *\\n * Emits an {AdminChanged} event.\\n */\\n function _changeAdmin(address newAdmin) internal {\\n emit AdminChanged(_getAdmin(), newAdmin);\\n _setAdmin(newAdmin);\\n }\\n\\n /**\\n * @dev The storage slot of the UpgradeableBeacon contract which defines the implementation for this proxy.\\n * This is bytes32(uint256(keccak256('eip1967.proxy.beacon')) - 1)) and is validated in the constructor.\\n */\\n bytes32 internal constant _BEACON_SLOT = 0xa3f0ad74e5423aebfd80d3ef4346578335a9a72aeaee59ff6cb3582b35133d50;\\n\\n /**\\n * @dev Emitted when the beacon is upgraded.\\n */\\n event BeaconUpgraded(address indexed beacon);\\n\\n /**\\n * @dev Returns the current beacon.\\n */\\n function _getBeacon() internal view returns (address) {\\n return StorageSlot.getAddressSlot(_BEACON_SLOT).value;\\n }\\n\\n /**\\n * @dev Stores a new beacon in the EIP1967 beacon slot.\\n */\\n function _setBeacon(address newBeacon) private {\\n require(Address.isContract(newBeacon), \\\"ERC1967: new beacon is not a contract\\\");\\n require(\\n Address.isContract(IBeacon(newBeacon).implementation()),\\n \\\"ERC1967: beacon implementation is not a contract\\\"\\n );\\n StorageSlot.getAddressSlot(_BEACON_SLOT).value = newBeacon;\\n }\\n\\n /**\\n * @dev Perform beacon upgrade with additional setup call. Note: This upgrades the address of the beacon, it does\\n * not upgrade the implementation contained in the beacon (see {UpgradeableBeacon-_setImplementation} for that).\\n *\\n * Emits a {BeaconUpgraded} event.\\n */\\n function _upgradeBeaconToAndCall(\\n address newBeacon,\\n bytes memory data,\\n bool forceCall\\n ) internal {\\n _setBeacon(newBeacon);\\n emit BeaconUpgraded(newBeacon);\\n if (data.length > 0 || forceCall) {\\n Address.functionDelegateCall(IBeacon(newBeacon).implementation(), data);\\n }\\n }\\n}\\n\",\"keccak256\":\"0xabf3f59bc0e5423eae45e459dbe92e7052c6983628d39008590edc852a62f94a\",\"license\":\"MIT\"},\"@openzeppelin/contracts/proxy/Proxy.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.6.0) (proxy/Proxy.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev This abstract contract provides a fallback function that delegates all calls to another contract using the EVM\\n * instruction `delegatecall`. We refer to the second contract as the _implementation_ behind the proxy, and it has to\\n * be specified by overriding the virtual {_implementation} function.\\n *\\n * Additionally, delegation to the implementation can be triggered manually through the {_fallback} function, or to a\\n * different contract through the {_delegate} function.\\n *\\n * The success and return data of the delegated call will be returned back to the caller of the proxy.\\n */\\nabstract contract Proxy {\\n /**\\n * @dev Delegates the current call to `implementation`.\\n *\\n * This function does not return to its internal call site, it will return directly to the external caller.\\n */\\n function _delegate(address implementation) internal virtual {\\n assembly {\\n // Copy msg.data. We take full control of memory in this inline assembly\\n // block because it will not return to Solidity code. We overwrite the\\n // Solidity scratch pad at memory position 0.\\n calldatacopy(0, 0, calldatasize())\\n\\n // Call the implementation.\\n // out and outsize are 0 because we don't know the size yet.\\n let result := delegatecall(gas(), implementation, 0, calldatasize(), 0, 0)\\n\\n // Copy the returned data.\\n returndatacopy(0, 0, returndatasize())\\n\\n switch result\\n // delegatecall returns 0 on error.\\n case 0 {\\n revert(0, returndatasize())\\n }\\n default {\\n return(0, returndatasize())\\n }\\n }\\n }\\n\\n /**\\n * @dev This is a virtual function that should be overridden so it returns the address to which the fallback function\\n * and {_fallback} should delegate.\\n */\\n function _implementation() internal view virtual returns (address);\\n\\n /**\\n * @dev Delegates the current call to the address returned by `_implementation()`.\\n *\\n * This function does not return to its internal call site, it will return directly to the external caller.\\n */\\n function _fallback() internal virtual {\\n _beforeFallback();\\n _delegate(_implementation());\\n }\\n\\n /**\\n * @dev Fallback function that delegates calls to the address returned by `_implementation()`. Will run if no other\\n * function in the contract matches the call data.\\n */\\n fallback() external payable virtual {\\n _fallback();\\n }\\n\\n /**\\n * @dev Fallback function that delegates calls to the address returned by `_implementation()`. Will run if call data\\n * is empty.\\n */\\n receive() external payable virtual {\\n _fallback();\\n }\\n\\n /**\\n * @dev Hook that is called before falling back to the implementation. Can happen as part of a manual `_fallback`\\n * call, or as part of the Solidity `fallback` or `receive` functions.\\n *\\n * If overridden should call `super._beforeFallback()`.\\n */\\n function _beforeFallback() internal virtual {}\\n}\\n\",\"keccak256\":\"0xc130fe33f1b2132158531a87734153293f6d07bc263ff4ac90e85da9c82c0e27\",\"license\":\"MIT\"},\"@openzeppelin/contracts/proxy/beacon/IBeacon.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (proxy/beacon/IBeacon.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev This is the interface that {BeaconProxy} expects of its beacon.\\n */\\ninterface IBeacon {\\n /**\\n * @dev Must return an address that can be used as a delegate call target.\\n *\\n * {BeaconProxy} will check that this address is a contract.\\n */\\n function implementation() external view returns (address);\\n}\\n\",\"keccak256\":\"0xd50a3421ac379ccb1be435fa646d66a65c986b4924f0849839f08692f39dde61\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/Address.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.7.0) (utils/Address.sol)\\n\\npragma solidity ^0.8.1;\\n\\n/**\\n * @dev Collection of functions related to the address type\\n */\\nlibrary Address {\\n /**\\n * @dev Returns true if `account` is a contract.\\n *\\n * [IMPORTANT]\\n * ====\\n * It is unsafe to assume that an address for which this function returns\\n * false is an externally-owned account (EOA) and not a contract.\\n *\\n * Among others, `isContract` will return false for the following\\n * types of addresses:\\n *\\n * - an externally-owned account\\n * - a contract in construction\\n * - an address where a contract will be created\\n * - an address where a contract lived, but was destroyed\\n * ====\\n *\\n * [IMPORTANT]\\n * ====\\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\\n *\\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\\n * constructor.\\n * ====\\n */\\n function isContract(address account) internal view returns (bool) {\\n // This method relies on extcodesize/address.code.length, which returns 0\\n // for contracts in construction, since the code is only stored at the end\\n // of the constructor execution.\\n\\n return account.code.length > 0;\\n }\\n\\n /**\\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\\n * `recipient`, forwarding all available gas and reverting on errors.\\n *\\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\\n * imposed by `transfer`, making them unable to receive funds via\\n * `transfer`. {sendValue} removes this limitation.\\n *\\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\\n *\\n * IMPORTANT: because control is transferred to `recipient`, care must be\\n * taken to not create reentrancy vulnerabilities. Consider using\\n * {ReentrancyGuard} or the\\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\\n */\\n function sendValue(address payable recipient, uint256 amount) internal {\\n require(address(this).balance >= amount, \\\"Address: insufficient balance\\\");\\n\\n (bool success, ) = recipient.call{value: amount}(\\\"\\\");\\n require(success, \\\"Address: unable to send value, recipient may have reverted\\\");\\n }\\n\\n /**\\n * @dev Performs a Solidity function call using a low level `call`. A\\n * plain `call` is an unsafe replacement for a function call: use this\\n * function instead.\\n *\\n * If `target` reverts with a revert reason, it is bubbled up by this\\n * function (like regular Solidity function calls).\\n *\\n * Returns the raw returned data. To convert to the expected return value,\\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\\n *\\n * Requirements:\\n *\\n * - `target` must be a contract.\\n * - calling `target` with `data` must not revert.\\n *\\n * _Available since v3.1._\\n */\\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\\n return functionCall(target, data, \\\"Address: low-level call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\\n * `errorMessage` as a fallback revert reason when `target` reverts.\\n *\\n * _Available since v3.1._\\n */\\n function functionCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n return functionCallWithValue(target, data, 0, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but also transferring `value` wei to `target`.\\n *\\n * Requirements:\\n *\\n * - the calling contract must have an ETH balance of at least `value`.\\n * - the called Solidity function must be `payable`.\\n *\\n * _Available since v3.1._\\n */\\n function functionCallWithValue(\\n address target,\\n bytes memory data,\\n uint256 value\\n ) internal returns (bytes memory) {\\n return functionCallWithValue(target, data, value, \\\"Address: low-level call with value failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\\n * with `errorMessage` as a fallback revert reason when `target` reverts.\\n *\\n * _Available since v3.1._\\n */\\n function functionCallWithValue(\\n address target,\\n bytes memory data,\\n uint256 value,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n require(address(this).balance >= value, \\\"Address: insufficient balance for call\\\");\\n require(isContract(target), \\\"Address: call to non-contract\\\");\\n\\n (bool success, bytes memory returndata) = target.call{value: value}(data);\\n return verifyCallResult(success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but performing a static call.\\n *\\n * _Available since v3.3._\\n */\\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\\n return functionStaticCall(target, data, \\\"Address: low-level static call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\\n * but performing a static call.\\n *\\n * _Available since v3.3._\\n */\\n function functionStaticCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal view returns (bytes memory) {\\n require(isContract(target), \\\"Address: static call to non-contract\\\");\\n\\n (bool success, bytes memory returndata) = target.staticcall(data);\\n return verifyCallResult(success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but performing a delegate call.\\n *\\n * _Available since v3.4._\\n */\\n function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {\\n return functionDelegateCall(target, data, \\\"Address: low-level delegate call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\\n * but performing a delegate call.\\n *\\n * _Available since v3.4._\\n */\\n function functionDelegateCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n require(isContract(target), \\\"Address: delegate call to non-contract\\\");\\n\\n (bool success, bytes memory returndata) = target.delegatecall(data);\\n return verifyCallResult(success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the\\n * revert reason using the provided one.\\n *\\n * _Available since v4.3._\\n */\\n function verifyCallResult(\\n bool success,\\n bytes memory returndata,\\n string memory errorMessage\\n ) internal pure returns (bytes memory) {\\n if (success) {\\n return returndata;\\n } else {\\n // Look for revert reason and bubble it up if present\\n if (returndata.length > 0) {\\n // The easiest way to bubble the revert reason is using memory via assembly\\n /// @solidity memory-safe-assembly\\n assembly {\\n let returndata_size := mload(returndata)\\n revert(add(32, returndata), returndata_size)\\n }\\n } else {\\n revert(errorMessage);\\n }\\n }\\n }\\n}\\n\",\"keccak256\":\"0xd6153ce99bcdcce22b124f755e72553295be6abcd63804cfdffceb188b8bef10\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/StorageSlot.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.7.0) (utils/StorageSlot.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Library for reading and writing primitive types to specific storage slots.\\n *\\n * Storage slots are often used to avoid storage conflict when dealing with upgradeable contracts.\\n * This library helps with reading and writing to such slots without the need for inline assembly.\\n *\\n * The functions in this library return Slot structs that contain a `value` member that can be used to read or write.\\n *\\n * Example usage to set ERC1967 implementation slot:\\n * ```\\n * contract ERC1967 {\\n * bytes32 internal constant _IMPLEMENTATION_SLOT = 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc;\\n *\\n * function _getImplementation() internal view returns (address) {\\n * return StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value;\\n * }\\n *\\n * function _setImplementation(address newImplementation) internal {\\n * require(Address.isContract(newImplementation), \\\"ERC1967: new implementation is not a contract\\\");\\n * StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value = newImplementation;\\n * }\\n * }\\n * ```\\n *\\n * _Available since v4.1 for `address`, `bool`, `bytes32`, and `uint256`._\\n */\\nlibrary StorageSlot {\\n struct AddressSlot {\\n address value;\\n }\\n\\n struct BooleanSlot {\\n bool value;\\n }\\n\\n struct Bytes32Slot {\\n bytes32 value;\\n }\\n\\n struct Uint256Slot {\\n uint256 value;\\n }\\n\\n /**\\n * @dev Returns an `AddressSlot` with member `value` located at `slot`.\\n */\\n function getAddressSlot(bytes32 slot) internal pure returns (AddressSlot storage r) {\\n /// @solidity memory-safe-assembly\\n assembly {\\n r.slot := slot\\n }\\n }\\n\\n /**\\n * @dev Returns an `BooleanSlot` with member `value` located at `slot`.\\n */\\n function getBooleanSlot(bytes32 slot) internal pure returns (BooleanSlot storage r) {\\n /// @solidity memory-safe-assembly\\n assembly {\\n r.slot := slot\\n }\\n }\\n\\n /**\\n * @dev Returns an `Bytes32Slot` with member `value` located at `slot`.\\n */\\n function getBytes32Slot(bytes32 slot) internal pure returns (Bytes32Slot storage r) {\\n /// @solidity memory-safe-assembly\\n assembly {\\n r.slot := slot\\n }\\n }\\n\\n /**\\n * @dev Returns an `Uint256Slot` with member `value` located at `slot`.\\n */\\n function getUint256Slot(bytes32 slot) internal pure returns (Uint256Slot storage r) {\\n /// @solidity memory-safe-assembly\\n assembly {\\n r.slot := slot\\n }\\n }\\n}\\n\",\"keccak256\":\"0xd5c50c54bf02740ebd122ff06832546cb5fa84486d52695a9ccfd11666e0c81d\",\"license\":\"MIT\"},\"contracts/external/TransparentUpgradeableProxy.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-3.0\\n\\npragma solidity ^0.8.12;\\n\\nimport \\\"@openzeppelin/contracts/proxy/ERC1967/ERC1967Proxy.sol\\\";\\n\\n/**\\n * @dev This contract implements a proxy that is upgradeable by an admin. It is fully forked from OpenZeppelin\\n * `TransparentUpgradeableProxy`\\n *\\n * To avoid https://medium.com/nomic-labs-blog/malicious-backdoors-in-ethereum-proxies-62629adf3357[proxy selector\\n * clashing], which can potentially be used in an attack, this contract uses the\\n * https://blog.openzeppelin.com/the-transparent-proxy-pattern/[transparent proxy pattern]. This pattern implies two\\n * things that go hand in hand:\\n *\\n * 1. If any account other than the admin calls the proxy, the call will be forwarded to the implementation, even if\\n * that call matches one of the admin functions exposed by the proxy itself.\\n * 2. If the admin calls the proxy, it can access the admin functions, but its calls will never be forwarded to the\\n * implementation. If the admin tries to call a function on the implementation it will fail with an error that says\\n * \\\"admin cannot fallback to proxy target\\\".\\n *\\n * These properties mean that the admin account can only be used for admin actions like upgrading the proxy or changing\\n * the admin, so it's best if it's a dedicated account that is not used for anything else. This will avoid headaches due\\n * to sudden errors when trying to call a function from the proxy implementation.\\n *\\n * Our recommendation is for the dedicated account to be an instance of the {ProxyAdmin} contract. If set up this way,\\n * you should think of the `ProxyAdmin` instance as the real administrative interface of your proxy.\\n */\\ncontract TransparentUpgradeableProxy is ERC1967Proxy {\\n /**\\n * @dev Initializes an upgradeable proxy managed by `_admin`, backed by the implementation at `_logic`, and\\n * optionally initialized with `_data` as explained in {ERC1967Proxy-constructor}.\\n */\\n constructor(address _logic, address admin_, bytes memory _data) payable ERC1967Proxy(_logic, _data) {\\n assert(_ADMIN_SLOT == bytes32(uint256(keccak256(\\\"eip1967.proxy.admin\\\")) - 1));\\n _changeAdmin(admin_);\\n }\\n\\n /**\\n * @dev Modifier used internally that will delegate the call to the implementation unless the sender is the admin.\\n */\\n modifier ifAdmin() {\\n if (msg.sender == _getAdmin()) {\\n _;\\n } else {\\n _fallback();\\n }\\n }\\n\\n /**\\n * @dev Returns the current admin.\\n *\\n * NOTE: Only the admin can call this function. See {ProxyAdmin-getProxyAdmin}.\\n *\\n * TIP: To get this value clients can read directly from the storage slot shown below (specified by EIP1967) using the\\n * https://eth.wiki/json-rpc/API#eth_getstorageat[`eth_getStorageAt`] RPC call.\\n * `0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103`\\n */\\n function admin() external ifAdmin returns (address admin_) {\\n admin_ = _getAdmin();\\n }\\n\\n /**\\n * @dev Returns the current implementation.\\n *\\n * NOTE: Only the admin can call this function. See {ProxyAdmin-getProxyImplementation}.\\n *\\n * TIP: To get this value clients can read directly from the storage slot shown below (specified by EIP1967) using the\\n * https://eth.wiki/json-rpc/API#eth_getstorageat[`eth_getStorageAt`] RPC call.\\n * `0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc`\\n */\\n function implementation() external ifAdmin returns (address implementation_) {\\n implementation_ = _implementation();\\n }\\n\\n /**\\n * @dev Changes the admin of the proxy.\\n *\\n * Emits an {AdminChanged} event.\\n *\\n * NOTE: Only the admin can call this function. See {ProxyAdmin-changeProxyAdmin}.\\n */\\n function changeAdmin(address newAdmin) external virtual ifAdmin {\\n _changeAdmin(newAdmin);\\n }\\n\\n /**\\n * @dev Upgrade the implementation of the proxy.\\n *\\n * NOTE: Only the admin can call this function. See {ProxyAdmin-upgrade}.\\n */\\n function upgradeTo(address newImplementation) external ifAdmin {\\n _upgradeToAndCall(newImplementation, bytes(\\\"\\\"), false);\\n }\\n\\n /**\\n * @dev Upgrade the implementation of the proxy, and then call a function from the new implementation as specified\\n * by `data`, which should be an encoded function call. This is useful to initialize new storage variables in the\\n * proxied contract.\\n *\\n * NOTE: Only the admin can call this function. See {ProxyAdmin-upgradeAndCall}.\\n */\\n function upgradeToAndCall(address newImplementation, bytes calldata data) external payable ifAdmin {\\n _upgradeToAndCall(newImplementation, data, true);\\n }\\n\\n /**\\n * @dev Returns the current admin.\\n */\\n function _admin() internal view virtual returns (address) {\\n return _getAdmin();\\n }\\n\\n /**\\n * @dev Makes sure the admin cannot access the fallback function. See {Proxy-_beforeFallback}.\\n */\\n function _beforeFallback() internal virtual override {\\n require(msg.sender != _getAdmin(), \\\"TransparentUpgradeableProxy: admin cannot fallback to proxy target\\\");\\n super._beforeFallback();\\n }\\n}\\n\",\"keccak256\":\"0x93a67a0f612ea3ff2a76315e138a6a88267270a1379d3cc7be52845fbbe611e2\",\"license\":\"GPL-3.0\"}},\"version\":1}", + "bytecode": "0x6080604052604051620010bb380380620010bb8339810160408190526200002691620004d8565b828162000036828260006200009a565b5062000066905060017fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6104620005b8565b6000805160206200107483398151915214620000865762000086620005da565b6200009182620000d7565b50505062000643565b620000a58362000132565b600082511180620000b35750805b15620000d257620000d083836200017460201b6200028c1760201c565b505b505050565b7f7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f62000102620001a5565b604080516001600160a01b03928316815291841660208301520160405180910390a16200012f81620001de565b50565b6200013d8162000293565b6040516001600160a01b038216907fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b90600090a250565b60606200019c8383604051806060016040528060278152602001620010946027913962000347565b90505b92915050565b6000620001cf6000805160206200107483398151915260001b6200042f60201b6200022e1760201c565b546001600160a01b0316919050565b6001600160a01b038116620002495760405162461bcd60e51b815260206004820152602660248201527f455243313936373a206e65772061646d696e20697320746865207a65726f206160448201526564647265737360d01b60648201526084015b60405180910390fd5b80620002726000805160206200107483398151915260001b6200042f60201b6200022e1760201c565b80546001600160a01b0319166001600160a01b039290921691909117905550565b620002a9816200043260201b620002b81760201c565b6200030d5760405162461bcd60e51b815260206004820152602d60248201527f455243313936373a206e657720696d706c656d656e746174696f6e206973206e60448201526c1bdd08184818dbdb9d1c9858dd609a1b606482015260840162000240565b80620002727f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc60001b6200042f60201b6200022e1760201c565b60606001600160a01b0384163b620003b15760405162461bcd60e51b815260206004820152602660248201527f416464726573733a2064656c65676174652063616c6c20746f206e6f6e2d636f6044820152651b9d1c9858dd60d21b606482015260840162000240565b600080856001600160a01b031685604051620003ce9190620005f0565b600060405180830381855af49150503d80600081146200040b576040519150601f19603f3d011682016040523d82523d6000602084013e62000410565b606091505b5090925090506200042382828662000441565b925050505b9392505050565b90565b6001600160a01b03163b151590565b606083156200045257508162000428565b825115620004635782518084602001fd5b8160405162461bcd60e51b81526004016200024091906200060e565b80516001600160a01b03811681146200049757600080fd5b919050565b634e487b7160e01b600052604160045260246000fd5b60005b83811015620004cf578181015183820152602001620004b5565b50506000910152565b600080600060608486031215620004ee57600080fd5b620004f9846200047f565b925062000509602085016200047f565b60408501519092506001600160401b03808211156200052757600080fd5b818601915086601f8301126200053c57600080fd5b8151818111156200055157620005516200049c565b604051601f8201601f19908116603f011681019083821181831017156200057c576200057c6200049c565b816040528281528960208487010111156200059657600080fd5b620005a9836020830160208801620004b2565b80955050505050509250925092565b818103818111156200019f57634e487b7160e01b600052601160045260246000fd5b634e487b7160e01b600052600160045260246000fd5b6000825162000604818460208701620004b2565b9190910192915050565b60208152600082518060208401526200062f816040850160208701620004b2565b601f01601f19169190910160400192915050565b610a2180620006536000396000f3fe60806040526004361061005e5760003560e01c80635c60da1b116100435780635c60da1b146100a85780638f283970146100e6578063f851a440146101065761006d565b80633659cfe6146100755780634f1ef286146100955761006d565b3661006d5761006b61011b565b005b61006b61011b565b34801561008157600080fd5b5061006b610090366004610895565b610135565b61006b6100a33660046108b0565b61017f565b3480156100b457600080fd5b506100bd6101f3565b60405173ffffffffffffffffffffffffffffffffffffffff909116815260200160405180910390f35b3480156100f257600080fd5b5061006b610101366004610895565b610231565b34801561011257600080fd5b506100bd61025e565b6101236102d4565b61013361012e6103ab565b6103b5565b565b61013d6103d9565b73ffffffffffffffffffffffffffffffffffffffff1633036101775761017481604051806020016040528060008152506000610419565b50565b61017461011b565b6101876103d9565b73ffffffffffffffffffffffffffffffffffffffff1633036101eb576101e68383838080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525060019250610419915050565b505050565b6101e661011b565b60006101fd6103d9565b73ffffffffffffffffffffffffffffffffffffffff163303610226576102216103ab565b905090565b61022e61011b565b90565b6102396103d9565b73ffffffffffffffffffffffffffffffffffffffff1633036101775761017481610444565b60006102686103d9565b73ffffffffffffffffffffffffffffffffffffffff163303610226576102216103d9565b60606102b183836040518060600160405280602781526020016109c5602791396104a5565b9392505050565b73ffffffffffffffffffffffffffffffffffffffff163b151590565b6102dc6103d9565b73ffffffffffffffffffffffffffffffffffffffff163303610133576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604260248201527f5472616e73706172656e745570677261646561626c6550726f78793a2061646d60448201527f696e2063616e6e6f742066616c6c6261636b20746f2070726f7879207461726760648201527f6574000000000000000000000000000000000000000000000000000000000000608482015260a4015b60405180910390fd5b60006102216105cd565b3660008037600080366000845af43d6000803e8080156103d4573d6000f35b3d6000fd5b60007fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035b5473ffffffffffffffffffffffffffffffffffffffff16919050565b610422836105f5565b60008251118061042f5750805b156101e65761043e838361028c565b50505050565b7f7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f61046d6103d9565b6040805173ffffffffffffffffffffffffffffffffffffffff928316815291841660208301520160405180910390a161017481610642565b606073ffffffffffffffffffffffffffffffffffffffff84163b61054b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f416464726573733a2064656c65676174652063616c6c20746f206e6f6e2d636f60448201527f6e7472616374000000000000000000000000000000000000000000000000000060648201526084016103a2565b6000808573ffffffffffffffffffffffffffffffffffffffff16856040516105739190610957565b600060405180830381855af49150503d80600081146105ae576040519150601f19603f3d011682016040523d82523d6000602084013e6105b3565b606091505b50915091506105c382828661074e565b9695505050505050565b60007f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc6103fd565b6105fe816107a1565b60405173ffffffffffffffffffffffffffffffffffffffff8216907fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b90600090a250565b73ffffffffffffffffffffffffffffffffffffffff81166106e5576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f455243313936373a206e65772061646d696e20697320746865207a65726f206160448201527f646472657373000000000000000000000000000000000000000000000000000060648201526084016103a2565b807fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035b80547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff9290921691909117905550565b6060831561075d5750816102b1565b82511561076d5782518084602001fd5b816040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016103a29190610973565b73ffffffffffffffffffffffffffffffffffffffff81163b610845576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602d60248201527f455243313936373a206e657720696d706c656d656e746174696f6e206973206e60448201527f6f74206120636f6e74726163740000000000000000000000000000000000000060648201526084016103a2565b807f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc610708565b803573ffffffffffffffffffffffffffffffffffffffff8116811461089057600080fd5b919050565b6000602082840312156108a757600080fd5b6102b18261086c565b6000806000604084860312156108c557600080fd5b6108ce8461086c565b9250602084013567ffffffffffffffff808211156108eb57600080fd5b818601915086601f8301126108ff57600080fd5b81358181111561090e57600080fd5b87602082850101111561092057600080fd5b6020830194508093505050509250925092565b60005b8381101561094e578181015183820152602001610936565b50506000910152565b60008251610969818460208701610933565b9190910192915050565b6020815260008251806020840152610992816040850160208701610933565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016919091016040019291505056fe416464726573733a206c6f772d6c6576656c2064656c65676174652063616c6c206661696c6564a2646970667358221220e96638b07fb1675d93a95c49e417bc8111448b23a59918698cdcd8fd488dd7cf64736f6c63430008110033b53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103416464726573733a206c6f772d6c6576656c2064656c65676174652063616c6c206661696c6564", + "deployedBytecode": "0x60806040526004361061005e5760003560e01c80635c60da1b116100435780635c60da1b146100a85780638f283970146100e6578063f851a440146101065761006d565b80633659cfe6146100755780634f1ef286146100955761006d565b3661006d5761006b61011b565b005b61006b61011b565b34801561008157600080fd5b5061006b610090366004610895565b610135565b61006b6100a33660046108b0565b61017f565b3480156100b457600080fd5b506100bd6101f3565b60405173ffffffffffffffffffffffffffffffffffffffff909116815260200160405180910390f35b3480156100f257600080fd5b5061006b610101366004610895565b610231565b34801561011257600080fd5b506100bd61025e565b6101236102d4565b61013361012e6103ab565b6103b5565b565b61013d6103d9565b73ffffffffffffffffffffffffffffffffffffffff1633036101775761017481604051806020016040528060008152506000610419565b50565b61017461011b565b6101876103d9565b73ffffffffffffffffffffffffffffffffffffffff1633036101eb576101e68383838080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525060019250610419915050565b505050565b6101e661011b565b60006101fd6103d9565b73ffffffffffffffffffffffffffffffffffffffff163303610226576102216103ab565b905090565b61022e61011b565b90565b6102396103d9565b73ffffffffffffffffffffffffffffffffffffffff1633036101775761017481610444565b60006102686103d9565b73ffffffffffffffffffffffffffffffffffffffff163303610226576102216103d9565b60606102b183836040518060600160405280602781526020016109c5602791396104a5565b9392505050565b73ffffffffffffffffffffffffffffffffffffffff163b151590565b6102dc6103d9565b73ffffffffffffffffffffffffffffffffffffffff163303610133576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604260248201527f5472616e73706172656e745570677261646561626c6550726f78793a2061646d60448201527f696e2063616e6e6f742066616c6c6261636b20746f2070726f7879207461726760648201527f6574000000000000000000000000000000000000000000000000000000000000608482015260a4015b60405180910390fd5b60006102216105cd565b3660008037600080366000845af43d6000803e8080156103d4573d6000f35b3d6000fd5b60007fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035b5473ffffffffffffffffffffffffffffffffffffffff16919050565b610422836105f5565b60008251118061042f5750805b156101e65761043e838361028c565b50505050565b7f7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f61046d6103d9565b6040805173ffffffffffffffffffffffffffffffffffffffff928316815291841660208301520160405180910390a161017481610642565b606073ffffffffffffffffffffffffffffffffffffffff84163b61054b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f416464726573733a2064656c65676174652063616c6c20746f206e6f6e2d636f60448201527f6e7472616374000000000000000000000000000000000000000000000000000060648201526084016103a2565b6000808573ffffffffffffffffffffffffffffffffffffffff16856040516105739190610957565b600060405180830381855af49150503d80600081146105ae576040519150601f19603f3d011682016040523d82523d6000602084013e6105b3565b606091505b50915091506105c382828661074e565b9695505050505050565b60007f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc6103fd565b6105fe816107a1565b60405173ffffffffffffffffffffffffffffffffffffffff8216907fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b90600090a250565b73ffffffffffffffffffffffffffffffffffffffff81166106e5576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f455243313936373a206e65772061646d696e20697320746865207a65726f206160448201527f646472657373000000000000000000000000000000000000000000000000000060648201526084016103a2565b807fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035b80547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff9290921691909117905550565b6060831561075d5750816102b1565b82511561076d5782518084602001fd5b816040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016103a29190610973565b73ffffffffffffffffffffffffffffffffffffffff81163b610845576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602d60248201527f455243313936373a206e657720696d706c656d656e746174696f6e206973206e60448201527f6f74206120636f6e74726163740000000000000000000000000000000000000060648201526084016103a2565b807f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc610708565b803573ffffffffffffffffffffffffffffffffffffffff8116811461089057600080fd5b919050565b6000602082840312156108a757600080fd5b6102b18261086c565b6000806000604084860312156108c557600080fd5b6108ce8461086c565b9250602084013567ffffffffffffffff808211156108eb57600080fd5b818601915086601f8301126108ff57600080fd5b81358181111561090e57600080fd5b87602082850101111561092057600080fd5b6020830194508093505050509250925092565b60005b8381101561094e578181015183820152602001610936565b50506000910152565b60008251610969818460208701610933565b9190910192915050565b6020815260008251806020840152610992816040850160208701610933565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016919091016040019291505056fe416464726573733a206c6f772d6c6576656c2064656c65676174652063616c6c206661696c6564a2646970667358221220e96638b07fb1675d93a95c49e417bc8111448b23a59918698cdcd8fd488dd7cf64736f6c63430008110033", + "devdoc": { + "details": "This contract implements a proxy that is upgradeable by an admin. It is fully forked from OpenZeppelin `TransparentUpgradeableProxy` To avoid https://medium.com/nomic-labs-blog/malicious-backdoors-in-ethereum-proxies-62629adf3357[proxy selector clashing], which can potentially be used in an attack, this contract uses the https://blog.openzeppelin.com/the-transparent-proxy-pattern/[transparent proxy pattern]. This pattern implies two things that go hand in hand: 1. If any account other than the admin calls the proxy, the call will be forwarded to the implementation, even if that call matches one of the admin functions exposed by the proxy itself. 2. If the admin calls the proxy, it can access the admin functions, but its calls will never be forwarded to the implementation. If the admin tries to call a function on the implementation it will fail with an error that says \"admin cannot fallback to proxy target\". These properties mean that the admin account can only be used for admin actions like upgrading the proxy or changing the admin, so it's best if it's a dedicated account that is not used for anything else. This will avoid headaches due to sudden errors when trying to call a function from the proxy implementation. Our recommendation is for the dedicated account to be an instance of the {ProxyAdmin} contract. If set up this way, you should think of the `ProxyAdmin` instance as the real administrative interface of your proxy.", + "kind": "dev", + "methods": { + "admin()": { + "details": "Returns the current admin. NOTE: Only the admin can call this function. See {ProxyAdmin-getProxyAdmin}. TIP: To get this value clients can read directly from the storage slot shown below (specified by EIP1967) using the https://eth.wiki/json-rpc/API#eth_getstorageat[`eth_getStorageAt`] RPC call. `0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103`" + }, + "changeAdmin(address)": { + "details": "Changes the admin of the proxy. Emits an {AdminChanged} event. NOTE: Only the admin can call this function. See {ProxyAdmin-changeProxyAdmin}." + }, + "constructor": { + "details": "Initializes an upgradeable proxy managed by `_admin`, backed by the implementation at `_logic`, and optionally initialized with `_data` as explained in {ERC1967Proxy-constructor}." + }, + "implementation()": { + "details": "Returns the current implementation. NOTE: Only the admin can call this function. See {ProxyAdmin-getProxyImplementation}. TIP: To get this value clients can read directly from the storage slot shown below (specified by EIP1967) using the https://eth.wiki/json-rpc/API#eth_getstorageat[`eth_getStorageAt`] RPC call. `0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc`" + }, + "upgradeTo(address)": { + "details": "Upgrade the implementation of the proxy. NOTE: Only the admin can call this function. See {ProxyAdmin-upgrade}." + }, + "upgradeToAndCall(address,bytes)": { + "details": "Upgrade the implementation of the proxy, and then call a function from the new implementation as specified by `data`, which should be an encoded function call. This is useful to initialize new storage variables in the proxied contract. NOTE: Only the admin can call this function. See {ProxyAdmin-upgradeAndCall}." + } + }, + "version": 1 + }, + "userdoc": { + "kind": "user", + "methods": {}, + "version": 1 + }, + "storageLayout": { + "storage": [], + "types": null + } +} \ No newline at end of file diff --git a/deployments/polygonzkevm/LayerZeroBridge_USD.json b/deployments/polygonzkevm/LayerZeroBridge_USD.json new file mode 100644 index 00000000..ba48c459 --- /dev/null +++ b/deployments/polygonzkevm/LayerZeroBridge_USD.json @@ -0,0 +1,275 @@ +{ + "address": "0x1E5B48c08D6b5efE0792d04f27602bD90026514a", + "abi": [ + { + "inputs": [ + { + "internalType": "address", + "name": "_logic", + "type": "address" + }, + { + "internalType": "address", + "name": "admin_", + "type": "address" + }, + { + "internalType": "bytes", + "name": "_data", + "type": "bytes" + } + ], + "stateMutability": "payable", + "type": "constructor" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "previousAdmin", + "type": "address" + }, + { + "indexed": false, + "internalType": "address", + "name": "newAdmin", + "type": "address" + } + ], + "name": "AdminChanged", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "beacon", + "type": "address" + } + ], + "name": "BeaconUpgraded", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "implementation", + "type": "address" + } + ], + "name": "Upgraded", + "type": "event" + }, + { + "stateMutability": "payable", + "type": "fallback" + }, + { + "inputs": [], + "name": "admin", + "outputs": [ + { + "internalType": "address", + "name": "admin_", + "type": "address" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "newAdmin", + "type": "address" + } + ], + "name": "changeAdmin", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "implementation", + "outputs": [ + { + "internalType": "address", + "name": "implementation_", + "type": "address" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "newImplementation", + "type": "address" + } + ], + "name": "upgradeTo", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "newImplementation", + "type": "address" + }, + { + "internalType": "bytes", + "name": "data", + "type": "bytes" + } + ], + "name": "upgradeToAndCall", + "outputs": [], + "stateMutability": "payable", + "type": "function" + }, + { + "stateMutability": "payable", + "type": "receive" + } + ], + "transactionHash": "0x6794dd0e8ad2d1a6dba59c0a5fc77a54cbdf15d3e8fad9e69da8c412069e475e", + "receipt": { + "to": null, + "from": "0xfdA462548Ce04282f4B6D6619823a7C64Fdc0185", + "contractAddress": "0x1E5B48c08D6b5efE0792d04f27602bD90026514a", + "transactionIndex": 0, + "gasUsed": "849920", + "logsBloom": "0x00000000000000000000000000000000400010000000000000000000000000000000000000000000000000000000000000000000000000000000100000200000000004000000000000000008000002000000000000000000000000000500000000000000020000000000000000000800000400800000010000020010000000000000000000000000000000000000000000000000000080000040000000800000020000000000000000000000000400000000000000004000000000000000000000000022000000000000020000040000000000000400000000000000000020000010000008000000000000000000000000000000000000000000000000000000", + "blockHash": "0x4bf11193843dfedfcfcc72b1238d70043aeb90ddb7cc1b1989f2053c8edf5a82", + "transactionHash": "0x6794dd0e8ad2d1a6dba59c0a5fc77a54cbdf15d3e8fad9e69da8c412069e475e", + "logs": [ + { + "transactionIndex": 0, + "blockNumber": 9134301, + "transactionHash": "0x6794dd0e8ad2d1a6dba59c0a5fc77a54cbdf15d3e8fad9e69da8c412069e475e", + "address": "0x1E5B48c08D6b5efE0792d04f27602bD90026514a", + "topics": [ + "0xbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b", + "0x0000000000000000000000000d710512e100c171139d2cf5708f22c680eccf52" + ], + "data": "0x", + "logIndex": 0, + "blockHash": "0x4bf11193843dfedfcfcc72b1238d70043aeb90ddb7cc1b1989f2053c8edf5a82" + }, + { + "transactionIndex": 0, + "blockNumber": 9134301, + "transactionHash": "0x6794dd0e8ad2d1a6dba59c0a5fc77a54cbdf15d3e8fad9e69da8c412069e475e", + "address": "0x1E5B48c08D6b5efE0792d04f27602bD90026514a", + "topics": [ + "0x8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925", + "0x0000000000000000000000001e5b48c08d6b5efe0792d04f27602bd90026514a", + "0x0000000000000000000000000000206329b97db379d5e1bf586bbdb969c63274" + ], + "data": "0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", + "logIndex": 1, + "blockHash": "0x4bf11193843dfedfcfcc72b1238d70043aeb90ddb7cc1b1989f2053c8edf5a82" + }, + { + "transactionIndex": 0, + "blockNumber": 9134301, + "transactionHash": "0x6794dd0e8ad2d1a6dba59c0a5fc77a54cbdf15d3e8fad9e69da8c412069e475e", + "address": "0x1E5B48c08D6b5efE0792d04f27602bD90026514a", + "topics": [ + "0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000206329b97db379d5e1bf586bbdb969c63274" + ], + "data": "0x0000000000000000000000000000000000000000000000000000000000000000", + "logIndex": 2, + "blockHash": "0x4bf11193843dfedfcfcc72b1238d70043aeb90ddb7cc1b1989f2053c8edf5a82" + }, + { + "transactionIndex": 0, + "blockNumber": 9134301, + "transactionHash": "0x6794dd0e8ad2d1a6dba59c0a5fc77a54cbdf15d3e8fad9e69da8c412069e475e", + "address": "0x1E5B48c08D6b5efE0792d04f27602bD90026514a", + "topics": [ + "0x7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb3847402498" + ], + "data": "0x0000000000000000000000000000000000000000000000000000000000000001", + "logIndex": 3, + "blockHash": "0x4bf11193843dfedfcfcc72b1238d70043aeb90ddb7cc1b1989f2053c8edf5a82" + }, + { + "transactionIndex": 0, + "blockNumber": 9134301, + "transactionHash": "0x6794dd0e8ad2d1a6dba59c0a5fc77a54cbdf15d3e8fad9e69da8c412069e475e", + "address": "0x1E5B48c08D6b5efE0792d04f27602bD90026514a", + "topics": [ + "0x7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f" + ], + "data": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000001d941ef0d3bba4ad67dbfbcee5262f4cee53a32b", + "logIndex": 4, + "blockHash": "0x4bf11193843dfedfcfcc72b1238d70043aeb90ddb7cc1b1989f2053c8edf5a82" + } + ], + "blockNumber": 9134301, + "cumulativeGasUsed": "849920", + "status": 1, + "byzantium": true + }, + "args": [ + "0x0D710512E100C171139D2Cf5708f22C680eccF52", + "0x1D941EF0D3Bba4ad67DBfBCeE5262F4CEE53A32b", + "0xc9aba0aa00000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000000e00000000000000000000000009740ff91f1985d8d2b71494ae1a2f723bb3ed9e4000000000000000000000000352742b8c16bf83b83107283e151f843e80fdd97000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000164c617965725a65726f204272696467652061675553440000000000000000000000000000000000000000000000000000000000000000000000000000000000084c5a2d6167555344000000000000000000000000000000000000000000000000" + ], + "numDeployments": 1, + "solcInputHash": "871924e0c138825a2736b76def8fef8d", + "metadata": "{\"compiler\":{\"version\":\"0.8.17+commit.8df45f5f\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_logic\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"admin_\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"_data\",\"type\":\"bytes\"}],\"stateMutability\":\"payable\",\"type\":\"constructor\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"previousAdmin\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"newAdmin\",\"type\":\"address\"}],\"name\":\"AdminChanged\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"beacon\",\"type\":\"address\"}],\"name\":\"BeaconUpgraded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"implementation\",\"type\":\"address\"}],\"name\":\"Upgraded\",\"type\":\"event\"},{\"stateMutability\":\"payable\",\"type\":\"fallback\"},{\"inputs\":[],\"name\":\"admin\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"admin_\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newAdmin\",\"type\":\"address\"}],\"name\":\"changeAdmin\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"implementation\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"implementation_\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newImplementation\",\"type\":\"address\"}],\"name\":\"upgradeTo\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newImplementation\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"}],\"name\":\"upgradeToAndCall\",\"outputs\":[],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"stateMutability\":\"payable\",\"type\":\"receive\"}],\"devdoc\":{\"details\":\"This contract implements a proxy that is upgradeable by an admin. It is fully forked from OpenZeppelin `TransparentUpgradeableProxy` To avoid https://medium.com/nomic-labs-blog/malicious-backdoors-in-ethereum-proxies-62629adf3357[proxy selector clashing], which can potentially be used in an attack, this contract uses the https://blog.openzeppelin.com/the-transparent-proxy-pattern/[transparent proxy pattern]. This pattern implies two things that go hand in hand: 1. If any account other than the admin calls the proxy, the call will be forwarded to the implementation, even if that call matches one of the admin functions exposed by the proxy itself. 2. If the admin calls the proxy, it can access the admin functions, but its calls will never be forwarded to the implementation. If the admin tries to call a function on the implementation it will fail with an error that says \\\"admin cannot fallback to proxy target\\\". These properties mean that the admin account can only be used for admin actions like upgrading the proxy or changing the admin, so it's best if it's a dedicated account that is not used for anything else. This will avoid headaches due to sudden errors when trying to call a function from the proxy implementation. Our recommendation is for the dedicated account to be an instance of the {ProxyAdmin} contract. If set up this way, you should think of the `ProxyAdmin` instance as the real administrative interface of your proxy.\",\"kind\":\"dev\",\"methods\":{\"admin()\":{\"details\":\"Returns the current admin. NOTE: Only the admin can call this function. See {ProxyAdmin-getProxyAdmin}. TIP: To get this value clients can read directly from the storage slot shown below (specified by EIP1967) using the https://eth.wiki/json-rpc/API#eth_getstorageat[`eth_getStorageAt`] RPC call. `0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103`\"},\"changeAdmin(address)\":{\"details\":\"Changes the admin of the proxy. Emits an {AdminChanged} event. NOTE: Only the admin can call this function. See {ProxyAdmin-changeProxyAdmin}.\"},\"constructor\":{\"details\":\"Initializes an upgradeable proxy managed by `_admin`, backed by the implementation at `_logic`, and optionally initialized with `_data` as explained in {ERC1967Proxy-constructor}.\"},\"implementation()\":{\"details\":\"Returns the current implementation. NOTE: Only the admin can call this function. See {ProxyAdmin-getProxyImplementation}. TIP: To get this value clients can read directly from the storage slot shown below (specified by EIP1967) using the https://eth.wiki/json-rpc/API#eth_getstorageat[`eth_getStorageAt`] RPC call. `0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc`\"},\"upgradeTo(address)\":{\"details\":\"Upgrade the implementation of the proxy. NOTE: Only the admin can call this function. See {ProxyAdmin-upgrade}.\"},\"upgradeToAndCall(address,bytes)\":{\"details\":\"Upgrade the implementation of the proxy, and then call a function from the new implementation as specified by `data`, which should be an encoded function call. This is useful to initialize new storage variables in the proxied contract. NOTE: Only the admin can call this function. See {ProxyAdmin-upgradeAndCall}.\"}},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/external/TransparentUpgradeableProxy.sol\":\"TransparentUpgradeableProxy\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":1000000},\"remappings\":[]},\"sources\":{\"@openzeppelin/contracts/interfaces/draft-IERC1822.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.5.0) (interfaces/draft-IERC1822.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev ERC1822: Universal Upgradeable Proxy Standard (UUPS) documents a method for upgradeability through a simplified\\n * proxy whose upgrades are fully controlled by the current implementation.\\n */\\ninterface IERC1822Proxiable {\\n /**\\n * @dev Returns the storage slot that the proxiable contract assumes is being used to store the implementation\\n * address.\\n *\\n * IMPORTANT: A proxy pointing at a proxiable contract should not be considered proxiable itself, because this risks\\n * bricking a proxy that upgrades to it, by delegating to itself until out of gas. Thus it is critical that this\\n * function revert if invoked through a proxy.\\n */\\n function proxiableUUID() external view returns (bytes32);\\n}\\n\",\"keccak256\":\"0x1d4afe6cb24200cc4545eed814ecf5847277dfe5d613a1707aad5fceecebcfff\",\"license\":\"MIT\"},\"@openzeppelin/contracts/proxy/ERC1967/ERC1967Proxy.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.7.0) (proxy/ERC1967/ERC1967Proxy.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../Proxy.sol\\\";\\nimport \\\"./ERC1967Upgrade.sol\\\";\\n\\n/**\\n * @dev This contract implements an upgradeable proxy. It is upgradeable because calls are delegated to an\\n * implementation address that can be changed. This address is stored in storage in the location specified by\\n * https://eips.ethereum.org/EIPS/eip-1967[EIP1967], so that it doesn't conflict with the storage layout of the\\n * implementation behind the proxy.\\n */\\ncontract ERC1967Proxy is Proxy, ERC1967Upgrade {\\n /**\\n * @dev Initializes the upgradeable proxy with an initial implementation specified by `_logic`.\\n *\\n * If `_data` is nonempty, it's used as data in a delegate call to `_logic`. This will typically be an encoded\\n * function call, and allows initializing the storage of the proxy like a Solidity constructor.\\n */\\n constructor(address _logic, bytes memory _data) payable {\\n _upgradeToAndCall(_logic, _data, false);\\n }\\n\\n /**\\n * @dev Returns the current implementation address.\\n */\\n function _implementation() internal view virtual override returns (address impl) {\\n return ERC1967Upgrade._getImplementation();\\n }\\n}\\n\",\"keccak256\":\"0xa2b22da3032e50b55f95ec1d13336102d675f341167aa76db571ef7f8bb7975d\",\"license\":\"MIT\"},\"@openzeppelin/contracts/proxy/ERC1967/ERC1967Upgrade.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.5.0) (proxy/ERC1967/ERC1967Upgrade.sol)\\n\\npragma solidity ^0.8.2;\\n\\nimport \\\"../beacon/IBeacon.sol\\\";\\nimport \\\"../../interfaces/draft-IERC1822.sol\\\";\\nimport \\\"../../utils/Address.sol\\\";\\nimport \\\"../../utils/StorageSlot.sol\\\";\\n\\n/**\\n * @dev This abstract contract provides getters and event emitting update functions for\\n * https://eips.ethereum.org/EIPS/eip-1967[EIP1967] slots.\\n *\\n * _Available since v4.1._\\n *\\n * @custom:oz-upgrades-unsafe-allow delegatecall\\n */\\nabstract contract ERC1967Upgrade {\\n // This is the keccak-256 hash of \\\"eip1967.proxy.rollback\\\" subtracted by 1\\n bytes32 private constant _ROLLBACK_SLOT = 0x4910fdfa16fed3260ed0e7147f7cc6da11a60208b5b9406d12a635614ffd9143;\\n\\n /**\\n * @dev Storage slot with the address of the current implementation.\\n * This is the keccak-256 hash of \\\"eip1967.proxy.implementation\\\" subtracted by 1, and is\\n * validated in the constructor.\\n */\\n bytes32 internal constant _IMPLEMENTATION_SLOT = 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc;\\n\\n /**\\n * @dev Emitted when the implementation is upgraded.\\n */\\n event Upgraded(address indexed implementation);\\n\\n /**\\n * @dev Returns the current implementation address.\\n */\\n function _getImplementation() internal view returns (address) {\\n return StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value;\\n }\\n\\n /**\\n * @dev Stores a new address in the EIP1967 implementation slot.\\n */\\n function _setImplementation(address newImplementation) private {\\n require(Address.isContract(newImplementation), \\\"ERC1967: new implementation is not a contract\\\");\\n StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value = newImplementation;\\n }\\n\\n /**\\n * @dev Perform implementation upgrade\\n *\\n * Emits an {Upgraded} event.\\n */\\n function _upgradeTo(address newImplementation) internal {\\n _setImplementation(newImplementation);\\n emit Upgraded(newImplementation);\\n }\\n\\n /**\\n * @dev Perform implementation upgrade with additional setup call.\\n *\\n * Emits an {Upgraded} event.\\n */\\n function _upgradeToAndCall(\\n address newImplementation,\\n bytes memory data,\\n bool forceCall\\n ) internal {\\n _upgradeTo(newImplementation);\\n if (data.length > 0 || forceCall) {\\n Address.functionDelegateCall(newImplementation, data);\\n }\\n }\\n\\n /**\\n * @dev Perform implementation upgrade with security checks for UUPS proxies, and additional setup call.\\n *\\n * Emits an {Upgraded} event.\\n */\\n function _upgradeToAndCallUUPS(\\n address newImplementation,\\n bytes memory data,\\n bool forceCall\\n ) internal {\\n // Upgrades from old implementations will perform a rollback test. This test requires the new\\n // implementation to upgrade back to the old, non-ERC1822 compliant, implementation. Removing\\n // this special case will break upgrade paths from old UUPS implementation to new ones.\\n if (StorageSlot.getBooleanSlot(_ROLLBACK_SLOT).value) {\\n _setImplementation(newImplementation);\\n } else {\\n try IERC1822Proxiable(newImplementation).proxiableUUID() returns (bytes32 slot) {\\n require(slot == _IMPLEMENTATION_SLOT, \\\"ERC1967Upgrade: unsupported proxiableUUID\\\");\\n } catch {\\n revert(\\\"ERC1967Upgrade: new implementation is not UUPS\\\");\\n }\\n _upgradeToAndCall(newImplementation, data, forceCall);\\n }\\n }\\n\\n /**\\n * @dev Storage slot with the admin of the contract.\\n * This is the keccak-256 hash of \\\"eip1967.proxy.admin\\\" subtracted by 1, and is\\n * validated in the constructor.\\n */\\n bytes32 internal constant _ADMIN_SLOT = 0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103;\\n\\n /**\\n * @dev Emitted when the admin account has changed.\\n */\\n event AdminChanged(address previousAdmin, address newAdmin);\\n\\n /**\\n * @dev Returns the current admin.\\n */\\n function _getAdmin() internal view returns (address) {\\n return StorageSlot.getAddressSlot(_ADMIN_SLOT).value;\\n }\\n\\n /**\\n * @dev Stores a new address in the EIP1967 admin slot.\\n */\\n function _setAdmin(address newAdmin) private {\\n require(newAdmin != address(0), \\\"ERC1967: new admin is the zero address\\\");\\n StorageSlot.getAddressSlot(_ADMIN_SLOT).value = newAdmin;\\n }\\n\\n /**\\n * @dev Changes the admin of the proxy.\\n *\\n * Emits an {AdminChanged} event.\\n */\\n function _changeAdmin(address newAdmin) internal {\\n emit AdminChanged(_getAdmin(), newAdmin);\\n _setAdmin(newAdmin);\\n }\\n\\n /**\\n * @dev The storage slot of the UpgradeableBeacon contract which defines the implementation for this proxy.\\n * This is bytes32(uint256(keccak256('eip1967.proxy.beacon')) - 1)) and is validated in the constructor.\\n */\\n bytes32 internal constant _BEACON_SLOT = 0xa3f0ad74e5423aebfd80d3ef4346578335a9a72aeaee59ff6cb3582b35133d50;\\n\\n /**\\n * @dev Emitted when the beacon is upgraded.\\n */\\n event BeaconUpgraded(address indexed beacon);\\n\\n /**\\n * @dev Returns the current beacon.\\n */\\n function _getBeacon() internal view returns (address) {\\n return StorageSlot.getAddressSlot(_BEACON_SLOT).value;\\n }\\n\\n /**\\n * @dev Stores a new beacon in the EIP1967 beacon slot.\\n */\\n function _setBeacon(address newBeacon) private {\\n require(Address.isContract(newBeacon), \\\"ERC1967: new beacon is not a contract\\\");\\n require(\\n Address.isContract(IBeacon(newBeacon).implementation()),\\n \\\"ERC1967: beacon implementation is not a contract\\\"\\n );\\n StorageSlot.getAddressSlot(_BEACON_SLOT).value = newBeacon;\\n }\\n\\n /**\\n * @dev Perform beacon upgrade with additional setup call. Note: This upgrades the address of the beacon, it does\\n * not upgrade the implementation contained in the beacon (see {UpgradeableBeacon-_setImplementation} for that).\\n *\\n * Emits a {BeaconUpgraded} event.\\n */\\n function _upgradeBeaconToAndCall(\\n address newBeacon,\\n bytes memory data,\\n bool forceCall\\n ) internal {\\n _setBeacon(newBeacon);\\n emit BeaconUpgraded(newBeacon);\\n if (data.length > 0 || forceCall) {\\n Address.functionDelegateCall(IBeacon(newBeacon).implementation(), data);\\n }\\n }\\n}\\n\",\"keccak256\":\"0xabf3f59bc0e5423eae45e459dbe92e7052c6983628d39008590edc852a62f94a\",\"license\":\"MIT\"},\"@openzeppelin/contracts/proxy/Proxy.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.6.0) (proxy/Proxy.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev This abstract contract provides a fallback function that delegates all calls to another contract using the EVM\\n * instruction `delegatecall`. We refer to the second contract as the _implementation_ behind the proxy, and it has to\\n * be specified by overriding the virtual {_implementation} function.\\n *\\n * Additionally, delegation to the implementation can be triggered manually through the {_fallback} function, or to a\\n * different contract through the {_delegate} function.\\n *\\n * The success and return data of the delegated call will be returned back to the caller of the proxy.\\n */\\nabstract contract Proxy {\\n /**\\n * @dev Delegates the current call to `implementation`.\\n *\\n * This function does not return to its internal call site, it will return directly to the external caller.\\n */\\n function _delegate(address implementation) internal virtual {\\n assembly {\\n // Copy msg.data. We take full control of memory in this inline assembly\\n // block because it will not return to Solidity code. We overwrite the\\n // Solidity scratch pad at memory position 0.\\n calldatacopy(0, 0, calldatasize())\\n\\n // Call the implementation.\\n // out and outsize are 0 because we don't know the size yet.\\n let result := delegatecall(gas(), implementation, 0, calldatasize(), 0, 0)\\n\\n // Copy the returned data.\\n returndatacopy(0, 0, returndatasize())\\n\\n switch result\\n // delegatecall returns 0 on error.\\n case 0 {\\n revert(0, returndatasize())\\n }\\n default {\\n return(0, returndatasize())\\n }\\n }\\n }\\n\\n /**\\n * @dev This is a virtual function that should be overridden so it returns the address to which the fallback function\\n * and {_fallback} should delegate.\\n */\\n function _implementation() internal view virtual returns (address);\\n\\n /**\\n * @dev Delegates the current call to the address returned by `_implementation()`.\\n *\\n * This function does not return to its internal call site, it will return directly to the external caller.\\n */\\n function _fallback() internal virtual {\\n _beforeFallback();\\n _delegate(_implementation());\\n }\\n\\n /**\\n * @dev Fallback function that delegates calls to the address returned by `_implementation()`. Will run if no other\\n * function in the contract matches the call data.\\n */\\n fallback() external payable virtual {\\n _fallback();\\n }\\n\\n /**\\n * @dev Fallback function that delegates calls to the address returned by `_implementation()`. Will run if call data\\n * is empty.\\n */\\n receive() external payable virtual {\\n _fallback();\\n }\\n\\n /**\\n * @dev Hook that is called before falling back to the implementation. Can happen as part of a manual `_fallback`\\n * call, or as part of the Solidity `fallback` or `receive` functions.\\n *\\n * If overridden should call `super._beforeFallback()`.\\n */\\n function _beforeFallback() internal virtual {}\\n}\\n\",\"keccak256\":\"0xc130fe33f1b2132158531a87734153293f6d07bc263ff4ac90e85da9c82c0e27\",\"license\":\"MIT\"},\"@openzeppelin/contracts/proxy/beacon/IBeacon.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (proxy/beacon/IBeacon.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev This is the interface that {BeaconProxy} expects of its beacon.\\n */\\ninterface IBeacon {\\n /**\\n * @dev Must return an address that can be used as a delegate call target.\\n *\\n * {BeaconProxy} will check that this address is a contract.\\n */\\n function implementation() external view returns (address);\\n}\\n\",\"keccak256\":\"0xd50a3421ac379ccb1be435fa646d66a65c986b4924f0849839f08692f39dde61\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/Address.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.7.0) (utils/Address.sol)\\n\\npragma solidity ^0.8.1;\\n\\n/**\\n * @dev Collection of functions related to the address type\\n */\\nlibrary Address {\\n /**\\n * @dev Returns true if `account` is a contract.\\n *\\n * [IMPORTANT]\\n * ====\\n * It is unsafe to assume that an address for which this function returns\\n * false is an externally-owned account (EOA) and not a contract.\\n *\\n * Among others, `isContract` will return false for the following\\n * types of addresses:\\n *\\n * - an externally-owned account\\n * - a contract in construction\\n * - an address where a contract will be created\\n * - an address where a contract lived, but was destroyed\\n * ====\\n *\\n * [IMPORTANT]\\n * ====\\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\\n *\\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\\n * constructor.\\n * ====\\n */\\n function isContract(address account) internal view returns (bool) {\\n // This method relies on extcodesize/address.code.length, which returns 0\\n // for contracts in construction, since the code is only stored at the end\\n // of the constructor execution.\\n\\n return account.code.length > 0;\\n }\\n\\n /**\\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\\n * `recipient`, forwarding all available gas and reverting on errors.\\n *\\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\\n * imposed by `transfer`, making them unable to receive funds via\\n * `transfer`. {sendValue} removes this limitation.\\n *\\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\\n *\\n * IMPORTANT: because control is transferred to `recipient`, care must be\\n * taken to not create reentrancy vulnerabilities. Consider using\\n * {ReentrancyGuard} or the\\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\\n */\\n function sendValue(address payable recipient, uint256 amount) internal {\\n require(address(this).balance >= amount, \\\"Address: insufficient balance\\\");\\n\\n (bool success, ) = recipient.call{value: amount}(\\\"\\\");\\n require(success, \\\"Address: unable to send value, recipient may have reverted\\\");\\n }\\n\\n /**\\n * @dev Performs a Solidity function call using a low level `call`. A\\n * plain `call` is an unsafe replacement for a function call: use this\\n * function instead.\\n *\\n * If `target` reverts with a revert reason, it is bubbled up by this\\n * function (like regular Solidity function calls).\\n *\\n * Returns the raw returned data. To convert to the expected return value,\\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\\n *\\n * Requirements:\\n *\\n * - `target` must be a contract.\\n * - calling `target` with `data` must not revert.\\n *\\n * _Available since v3.1._\\n */\\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\\n return functionCall(target, data, \\\"Address: low-level call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\\n * `errorMessage` as a fallback revert reason when `target` reverts.\\n *\\n * _Available since v3.1._\\n */\\n function functionCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n return functionCallWithValue(target, data, 0, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but also transferring `value` wei to `target`.\\n *\\n * Requirements:\\n *\\n * - the calling contract must have an ETH balance of at least `value`.\\n * - the called Solidity function must be `payable`.\\n *\\n * _Available since v3.1._\\n */\\n function functionCallWithValue(\\n address target,\\n bytes memory data,\\n uint256 value\\n ) internal returns (bytes memory) {\\n return functionCallWithValue(target, data, value, \\\"Address: low-level call with value failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\\n * with `errorMessage` as a fallback revert reason when `target` reverts.\\n *\\n * _Available since v3.1._\\n */\\n function functionCallWithValue(\\n address target,\\n bytes memory data,\\n uint256 value,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n require(address(this).balance >= value, \\\"Address: insufficient balance for call\\\");\\n require(isContract(target), \\\"Address: call to non-contract\\\");\\n\\n (bool success, bytes memory returndata) = target.call{value: value}(data);\\n return verifyCallResult(success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but performing a static call.\\n *\\n * _Available since v3.3._\\n */\\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\\n return functionStaticCall(target, data, \\\"Address: low-level static call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\\n * but performing a static call.\\n *\\n * _Available since v3.3._\\n */\\n function functionStaticCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal view returns (bytes memory) {\\n require(isContract(target), \\\"Address: static call to non-contract\\\");\\n\\n (bool success, bytes memory returndata) = target.staticcall(data);\\n return verifyCallResult(success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but performing a delegate call.\\n *\\n * _Available since v3.4._\\n */\\n function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {\\n return functionDelegateCall(target, data, \\\"Address: low-level delegate call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\\n * but performing a delegate call.\\n *\\n * _Available since v3.4._\\n */\\n function functionDelegateCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n require(isContract(target), \\\"Address: delegate call to non-contract\\\");\\n\\n (bool success, bytes memory returndata) = target.delegatecall(data);\\n return verifyCallResult(success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the\\n * revert reason using the provided one.\\n *\\n * _Available since v4.3._\\n */\\n function verifyCallResult(\\n bool success,\\n bytes memory returndata,\\n string memory errorMessage\\n ) internal pure returns (bytes memory) {\\n if (success) {\\n return returndata;\\n } else {\\n // Look for revert reason and bubble it up if present\\n if (returndata.length > 0) {\\n // The easiest way to bubble the revert reason is using memory via assembly\\n /// @solidity memory-safe-assembly\\n assembly {\\n let returndata_size := mload(returndata)\\n revert(add(32, returndata), returndata_size)\\n }\\n } else {\\n revert(errorMessage);\\n }\\n }\\n }\\n}\\n\",\"keccak256\":\"0xd6153ce99bcdcce22b124f755e72553295be6abcd63804cfdffceb188b8bef10\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/StorageSlot.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.7.0) (utils/StorageSlot.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Library for reading and writing primitive types to specific storage slots.\\n *\\n * Storage slots are often used to avoid storage conflict when dealing with upgradeable contracts.\\n * This library helps with reading and writing to such slots without the need for inline assembly.\\n *\\n * The functions in this library return Slot structs that contain a `value` member that can be used to read or write.\\n *\\n * Example usage to set ERC1967 implementation slot:\\n * ```\\n * contract ERC1967 {\\n * bytes32 internal constant _IMPLEMENTATION_SLOT = 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc;\\n *\\n * function _getImplementation() internal view returns (address) {\\n * return StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value;\\n * }\\n *\\n * function _setImplementation(address newImplementation) internal {\\n * require(Address.isContract(newImplementation), \\\"ERC1967: new implementation is not a contract\\\");\\n * StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value = newImplementation;\\n * }\\n * }\\n * ```\\n *\\n * _Available since v4.1 for `address`, `bool`, `bytes32`, and `uint256`._\\n */\\nlibrary StorageSlot {\\n struct AddressSlot {\\n address value;\\n }\\n\\n struct BooleanSlot {\\n bool value;\\n }\\n\\n struct Bytes32Slot {\\n bytes32 value;\\n }\\n\\n struct Uint256Slot {\\n uint256 value;\\n }\\n\\n /**\\n * @dev Returns an `AddressSlot` with member `value` located at `slot`.\\n */\\n function getAddressSlot(bytes32 slot) internal pure returns (AddressSlot storage r) {\\n /// @solidity memory-safe-assembly\\n assembly {\\n r.slot := slot\\n }\\n }\\n\\n /**\\n * @dev Returns an `BooleanSlot` with member `value` located at `slot`.\\n */\\n function getBooleanSlot(bytes32 slot) internal pure returns (BooleanSlot storage r) {\\n /// @solidity memory-safe-assembly\\n assembly {\\n r.slot := slot\\n }\\n }\\n\\n /**\\n * @dev Returns an `Bytes32Slot` with member `value` located at `slot`.\\n */\\n function getBytes32Slot(bytes32 slot) internal pure returns (Bytes32Slot storage r) {\\n /// @solidity memory-safe-assembly\\n assembly {\\n r.slot := slot\\n }\\n }\\n\\n /**\\n * @dev Returns an `Uint256Slot` with member `value` located at `slot`.\\n */\\n function getUint256Slot(bytes32 slot) internal pure returns (Uint256Slot storage r) {\\n /// @solidity memory-safe-assembly\\n assembly {\\n r.slot := slot\\n }\\n }\\n}\\n\",\"keccak256\":\"0xd5c50c54bf02740ebd122ff06832546cb5fa84486d52695a9ccfd11666e0c81d\",\"license\":\"MIT\"},\"contracts/external/TransparentUpgradeableProxy.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-3.0\\n\\npragma solidity ^0.8.12;\\n\\nimport \\\"@openzeppelin/contracts/proxy/ERC1967/ERC1967Proxy.sol\\\";\\n\\n/**\\n * @dev This contract implements a proxy that is upgradeable by an admin. It is fully forked from OpenZeppelin\\n * `TransparentUpgradeableProxy`\\n *\\n * To avoid https://medium.com/nomic-labs-blog/malicious-backdoors-in-ethereum-proxies-62629adf3357[proxy selector\\n * clashing], which can potentially be used in an attack, this contract uses the\\n * https://blog.openzeppelin.com/the-transparent-proxy-pattern/[transparent proxy pattern]. This pattern implies two\\n * things that go hand in hand:\\n *\\n * 1. If any account other than the admin calls the proxy, the call will be forwarded to the implementation, even if\\n * that call matches one of the admin functions exposed by the proxy itself.\\n * 2. If the admin calls the proxy, it can access the admin functions, but its calls will never be forwarded to the\\n * implementation. If the admin tries to call a function on the implementation it will fail with an error that says\\n * \\\"admin cannot fallback to proxy target\\\".\\n *\\n * These properties mean that the admin account can only be used for admin actions like upgrading the proxy or changing\\n * the admin, so it's best if it's a dedicated account that is not used for anything else. This will avoid headaches due\\n * to sudden errors when trying to call a function from the proxy implementation.\\n *\\n * Our recommendation is for the dedicated account to be an instance of the {ProxyAdmin} contract. If set up this way,\\n * you should think of the `ProxyAdmin` instance as the real administrative interface of your proxy.\\n */\\ncontract TransparentUpgradeableProxy is ERC1967Proxy {\\n /**\\n * @dev Initializes an upgradeable proxy managed by `_admin`, backed by the implementation at `_logic`, and\\n * optionally initialized with `_data` as explained in {ERC1967Proxy-constructor}.\\n */\\n constructor(address _logic, address admin_, bytes memory _data) payable ERC1967Proxy(_logic, _data) {\\n assert(_ADMIN_SLOT == bytes32(uint256(keccak256(\\\"eip1967.proxy.admin\\\")) - 1));\\n _changeAdmin(admin_);\\n }\\n\\n /**\\n * @dev Modifier used internally that will delegate the call to the implementation unless the sender is the admin.\\n */\\n modifier ifAdmin() {\\n if (msg.sender == _getAdmin()) {\\n _;\\n } else {\\n _fallback();\\n }\\n }\\n\\n /**\\n * @dev Returns the current admin.\\n *\\n * NOTE: Only the admin can call this function. See {ProxyAdmin-getProxyAdmin}.\\n *\\n * TIP: To get this value clients can read directly from the storage slot shown below (specified by EIP1967) using the\\n * https://eth.wiki/json-rpc/API#eth_getstorageat[`eth_getStorageAt`] RPC call.\\n * `0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103`\\n */\\n function admin() external ifAdmin returns (address admin_) {\\n admin_ = _getAdmin();\\n }\\n\\n /**\\n * @dev Returns the current implementation.\\n *\\n * NOTE: Only the admin can call this function. See {ProxyAdmin-getProxyImplementation}.\\n *\\n * TIP: To get this value clients can read directly from the storage slot shown below (specified by EIP1967) using the\\n * https://eth.wiki/json-rpc/API#eth_getstorageat[`eth_getStorageAt`] RPC call.\\n * `0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc`\\n */\\n function implementation() external ifAdmin returns (address implementation_) {\\n implementation_ = _implementation();\\n }\\n\\n /**\\n * @dev Changes the admin of the proxy.\\n *\\n * Emits an {AdminChanged} event.\\n *\\n * NOTE: Only the admin can call this function. See {ProxyAdmin-changeProxyAdmin}.\\n */\\n function changeAdmin(address newAdmin) external virtual ifAdmin {\\n _changeAdmin(newAdmin);\\n }\\n\\n /**\\n * @dev Upgrade the implementation of the proxy.\\n *\\n * NOTE: Only the admin can call this function. See {ProxyAdmin-upgrade}.\\n */\\n function upgradeTo(address newImplementation) external ifAdmin {\\n _upgradeToAndCall(newImplementation, bytes(\\\"\\\"), false);\\n }\\n\\n /**\\n * @dev Upgrade the implementation of the proxy, and then call a function from the new implementation as specified\\n * by `data`, which should be an encoded function call. This is useful to initialize new storage variables in the\\n * proxied contract.\\n *\\n * NOTE: Only the admin can call this function. See {ProxyAdmin-upgradeAndCall}.\\n */\\n function upgradeToAndCall(address newImplementation, bytes calldata data) external payable ifAdmin {\\n _upgradeToAndCall(newImplementation, data, true);\\n }\\n\\n /**\\n * @dev Returns the current admin.\\n */\\n function _admin() internal view virtual returns (address) {\\n return _getAdmin();\\n }\\n\\n /**\\n * @dev Makes sure the admin cannot access the fallback function. See {Proxy-_beforeFallback}.\\n */\\n function _beforeFallback() internal virtual override {\\n require(msg.sender != _getAdmin(), \\\"TransparentUpgradeableProxy: admin cannot fallback to proxy target\\\");\\n super._beforeFallback();\\n }\\n}\\n\",\"keccak256\":\"0x93a67a0f612ea3ff2a76315e138a6a88267270a1379d3cc7be52845fbbe611e2\",\"license\":\"GPL-3.0\"}},\"version\":1}", + "bytecode": "0x6080604052604051620010bb380380620010bb8339810160408190526200002691620004d8565b828162000036828260006200009a565b5062000066905060017fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6104620005b8565b6000805160206200107483398151915214620000865762000086620005da565b6200009182620000d7565b50505062000643565b620000a58362000132565b600082511180620000b35750805b15620000d257620000d083836200017460201b6200028c1760201c565b505b505050565b7f7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f62000102620001a5565b604080516001600160a01b03928316815291841660208301520160405180910390a16200012f81620001de565b50565b6200013d8162000293565b6040516001600160a01b038216907fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b90600090a250565b60606200019c8383604051806060016040528060278152602001620010946027913962000347565b90505b92915050565b6000620001cf6000805160206200107483398151915260001b6200042f60201b6200022e1760201c565b546001600160a01b0316919050565b6001600160a01b038116620002495760405162461bcd60e51b815260206004820152602660248201527f455243313936373a206e65772061646d696e20697320746865207a65726f206160448201526564647265737360d01b60648201526084015b60405180910390fd5b80620002726000805160206200107483398151915260001b6200042f60201b6200022e1760201c565b80546001600160a01b0319166001600160a01b039290921691909117905550565b620002a9816200043260201b620002b81760201c565b6200030d5760405162461bcd60e51b815260206004820152602d60248201527f455243313936373a206e657720696d706c656d656e746174696f6e206973206e60448201526c1bdd08184818dbdb9d1c9858dd609a1b606482015260840162000240565b80620002727f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc60001b6200042f60201b6200022e1760201c565b60606001600160a01b0384163b620003b15760405162461bcd60e51b815260206004820152602660248201527f416464726573733a2064656c65676174652063616c6c20746f206e6f6e2d636f6044820152651b9d1c9858dd60d21b606482015260840162000240565b600080856001600160a01b031685604051620003ce9190620005f0565b600060405180830381855af49150503d80600081146200040b576040519150601f19603f3d011682016040523d82523d6000602084013e62000410565b606091505b5090925090506200042382828662000441565b925050505b9392505050565b90565b6001600160a01b03163b151590565b606083156200045257508162000428565b825115620004635782518084602001fd5b8160405162461bcd60e51b81526004016200024091906200060e565b80516001600160a01b03811681146200049757600080fd5b919050565b634e487b7160e01b600052604160045260246000fd5b60005b83811015620004cf578181015183820152602001620004b5565b50506000910152565b600080600060608486031215620004ee57600080fd5b620004f9846200047f565b925062000509602085016200047f565b60408501519092506001600160401b03808211156200052757600080fd5b818601915086601f8301126200053c57600080fd5b8151818111156200055157620005516200049c565b604051601f8201601f19908116603f011681019083821181831017156200057c576200057c6200049c565b816040528281528960208487010111156200059657600080fd5b620005a9836020830160208801620004b2565b80955050505050509250925092565b818103818111156200019f57634e487b7160e01b600052601160045260246000fd5b634e487b7160e01b600052600160045260246000fd5b6000825162000604818460208701620004b2565b9190910192915050565b60208152600082518060208401526200062f816040850160208701620004b2565b601f01601f19169190910160400192915050565b610a2180620006536000396000f3fe60806040526004361061005e5760003560e01c80635c60da1b116100435780635c60da1b146100a85780638f283970146100e6578063f851a440146101065761006d565b80633659cfe6146100755780634f1ef286146100955761006d565b3661006d5761006b61011b565b005b61006b61011b565b34801561008157600080fd5b5061006b610090366004610895565b610135565b61006b6100a33660046108b0565b61017f565b3480156100b457600080fd5b506100bd6101f3565b60405173ffffffffffffffffffffffffffffffffffffffff909116815260200160405180910390f35b3480156100f257600080fd5b5061006b610101366004610895565b610231565b34801561011257600080fd5b506100bd61025e565b6101236102d4565b61013361012e6103ab565b6103b5565b565b61013d6103d9565b73ffffffffffffffffffffffffffffffffffffffff1633036101775761017481604051806020016040528060008152506000610419565b50565b61017461011b565b6101876103d9565b73ffffffffffffffffffffffffffffffffffffffff1633036101eb576101e68383838080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525060019250610419915050565b505050565b6101e661011b565b60006101fd6103d9565b73ffffffffffffffffffffffffffffffffffffffff163303610226576102216103ab565b905090565b61022e61011b565b90565b6102396103d9565b73ffffffffffffffffffffffffffffffffffffffff1633036101775761017481610444565b60006102686103d9565b73ffffffffffffffffffffffffffffffffffffffff163303610226576102216103d9565b60606102b183836040518060600160405280602781526020016109c5602791396104a5565b9392505050565b73ffffffffffffffffffffffffffffffffffffffff163b151590565b6102dc6103d9565b73ffffffffffffffffffffffffffffffffffffffff163303610133576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604260248201527f5472616e73706172656e745570677261646561626c6550726f78793a2061646d60448201527f696e2063616e6e6f742066616c6c6261636b20746f2070726f7879207461726760648201527f6574000000000000000000000000000000000000000000000000000000000000608482015260a4015b60405180910390fd5b60006102216105cd565b3660008037600080366000845af43d6000803e8080156103d4573d6000f35b3d6000fd5b60007fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035b5473ffffffffffffffffffffffffffffffffffffffff16919050565b610422836105f5565b60008251118061042f5750805b156101e65761043e838361028c565b50505050565b7f7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f61046d6103d9565b6040805173ffffffffffffffffffffffffffffffffffffffff928316815291841660208301520160405180910390a161017481610642565b606073ffffffffffffffffffffffffffffffffffffffff84163b61054b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f416464726573733a2064656c65676174652063616c6c20746f206e6f6e2d636f60448201527f6e7472616374000000000000000000000000000000000000000000000000000060648201526084016103a2565b6000808573ffffffffffffffffffffffffffffffffffffffff16856040516105739190610957565b600060405180830381855af49150503d80600081146105ae576040519150601f19603f3d011682016040523d82523d6000602084013e6105b3565b606091505b50915091506105c382828661074e565b9695505050505050565b60007f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc6103fd565b6105fe816107a1565b60405173ffffffffffffffffffffffffffffffffffffffff8216907fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b90600090a250565b73ffffffffffffffffffffffffffffffffffffffff81166106e5576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f455243313936373a206e65772061646d696e20697320746865207a65726f206160448201527f646472657373000000000000000000000000000000000000000000000000000060648201526084016103a2565b807fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035b80547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff9290921691909117905550565b6060831561075d5750816102b1565b82511561076d5782518084602001fd5b816040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016103a29190610973565b73ffffffffffffffffffffffffffffffffffffffff81163b610845576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602d60248201527f455243313936373a206e657720696d706c656d656e746174696f6e206973206e60448201527f6f74206120636f6e74726163740000000000000000000000000000000000000060648201526084016103a2565b807f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc610708565b803573ffffffffffffffffffffffffffffffffffffffff8116811461089057600080fd5b919050565b6000602082840312156108a757600080fd5b6102b18261086c565b6000806000604084860312156108c557600080fd5b6108ce8461086c565b9250602084013567ffffffffffffffff808211156108eb57600080fd5b818601915086601f8301126108ff57600080fd5b81358181111561090e57600080fd5b87602082850101111561092057600080fd5b6020830194508093505050509250925092565b60005b8381101561094e578181015183820152602001610936565b50506000910152565b60008251610969818460208701610933565b9190910192915050565b6020815260008251806020840152610992816040850160208701610933565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016919091016040019291505056fe416464726573733a206c6f772d6c6576656c2064656c65676174652063616c6c206661696c6564a2646970667358221220e96638b07fb1675d93a95c49e417bc8111448b23a59918698cdcd8fd488dd7cf64736f6c63430008110033b53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103416464726573733a206c6f772d6c6576656c2064656c65676174652063616c6c206661696c6564", + "deployedBytecode": "0x60806040526004361061005e5760003560e01c80635c60da1b116100435780635c60da1b146100a85780638f283970146100e6578063f851a440146101065761006d565b80633659cfe6146100755780634f1ef286146100955761006d565b3661006d5761006b61011b565b005b61006b61011b565b34801561008157600080fd5b5061006b610090366004610895565b610135565b61006b6100a33660046108b0565b61017f565b3480156100b457600080fd5b506100bd6101f3565b60405173ffffffffffffffffffffffffffffffffffffffff909116815260200160405180910390f35b3480156100f257600080fd5b5061006b610101366004610895565b610231565b34801561011257600080fd5b506100bd61025e565b6101236102d4565b61013361012e6103ab565b6103b5565b565b61013d6103d9565b73ffffffffffffffffffffffffffffffffffffffff1633036101775761017481604051806020016040528060008152506000610419565b50565b61017461011b565b6101876103d9565b73ffffffffffffffffffffffffffffffffffffffff1633036101eb576101e68383838080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525060019250610419915050565b505050565b6101e661011b565b60006101fd6103d9565b73ffffffffffffffffffffffffffffffffffffffff163303610226576102216103ab565b905090565b61022e61011b565b90565b6102396103d9565b73ffffffffffffffffffffffffffffffffffffffff1633036101775761017481610444565b60006102686103d9565b73ffffffffffffffffffffffffffffffffffffffff163303610226576102216103d9565b60606102b183836040518060600160405280602781526020016109c5602791396104a5565b9392505050565b73ffffffffffffffffffffffffffffffffffffffff163b151590565b6102dc6103d9565b73ffffffffffffffffffffffffffffffffffffffff163303610133576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604260248201527f5472616e73706172656e745570677261646561626c6550726f78793a2061646d60448201527f696e2063616e6e6f742066616c6c6261636b20746f2070726f7879207461726760648201527f6574000000000000000000000000000000000000000000000000000000000000608482015260a4015b60405180910390fd5b60006102216105cd565b3660008037600080366000845af43d6000803e8080156103d4573d6000f35b3d6000fd5b60007fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035b5473ffffffffffffffffffffffffffffffffffffffff16919050565b610422836105f5565b60008251118061042f5750805b156101e65761043e838361028c565b50505050565b7f7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f61046d6103d9565b6040805173ffffffffffffffffffffffffffffffffffffffff928316815291841660208301520160405180910390a161017481610642565b606073ffffffffffffffffffffffffffffffffffffffff84163b61054b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f416464726573733a2064656c65676174652063616c6c20746f206e6f6e2d636f60448201527f6e7472616374000000000000000000000000000000000000000000000000000060648201526084016103a2565b6000808573ffffffffffffffffffffffffffffffffffffffff16856040516105739190610957565b600060405180830381855af49150503d80600081146105ae576040519150601f19603f3d011682016040523d82523d6000602084013e6105b3565b606091505b50915091506105c382828661074e565b9695505050505050565b60007f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc6103fd565b6105fe816107a1565b60405173ffffffffffffffffffffffffffffffffffffffff8216907fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b90600090a250565b73ffffffffffffffffffffffffffffffffffffffff81166106e5576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f455243313936373a206e65772061646d696e20697320746865207a65726f206160448201527f646472657373000000000000000000000000000000000000000000000000000060648201526084016103a2565b807fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035b80547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff9290921691909117905550565b6060831561075d5750816102b1565b82511561076d5782518084602001fd5b816040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016103a29190610973565b73ffffffffffffffffffffffffffffffffffffffff81163b610845576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602d60248201527f455243313936373a206e657720696d706c656d656e746174696f6e206973206e60448201527f6f74206120636f6e74726163740000000000000000000000000000000000000060648201526084016103a2565b807f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc610708565b803573ffffffffffffffffffffffffffffffffffffffff8116811461089057600080fd5b919050565b6000602082840312156108a757600080fd5b6102b18261086c565b6000806000604084860312156108c557600080fd5b6108ce8461086c565b9250602084013567ffffffffffffffff808211156108eb57600080fd5b818601915086601f8301126108ff57600080fd5b81358181111561090e57600080fd5b87602082850101111561092057600080fd5b6020830194508093505050509250925092565b60005b8381101561094e578181015183820152602001610936565b50506000910152565b60008251610969818460208701610933565b9190910192915050565b6020815260008251806020840152610992816040850160208701610933565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016919091016040019291505056fe416464726573733a206c6f772d6c6576656c2064656c65676174652063616c6c206661696c6564a2646970667358221220e96638b07fb1675d93a95c49e417bc8111448b23a59918698cdcd8fd488dd7cf64736f6c63430008110033", + "devdoc": { + "details": "This contract implements a proxy that is upgradeable by an admin. It is fully forked from OpenZeppelin `TransparentUpgradeableProxy` To avoid https://medium.com/nomic-labs-blog/malicious-backdoors-in-ethereum-proxies-62629adf3357[proxy selector clashing], which can potentially be used in an attack, this contract uses the https://blog.openzeppelin.com/the-transparent-proxy-pattern/[transparent proxy pattern]. This pattern implies two things that go hand in hand: 1. If any account other than the admin calls the proxy, the call will be forwarded to the implementation, even if that call matches one of the admin functions exposed by the proxy itself. 2. If the admin calls the proxy, it can access the admin functions, but its calls will never be forwarded to the implementation. If the admin tries to call a function on the implementation it will fail with an error that says \"admin cannot fallback to proxy target\". These properties mean that the admin account can only be used for admin actions like upgrading the proxy or changing the admin, so it's best if it's a dedicated account that is not used for anything else. This will avoid headaches due to sudden errors when trying to call a function from the proxy implementation. Our recommendation is for the dedicated account to be an instance of the {ProxyAdmin} contract. If set up this way, you should think of the `ProxyAdmin` instance as the real administrative interface of your proxy.", + "kind": "dev", + "methods": { + "admin()": { + "details": "Returns the current admin. NOTE: Only the admin can call this function. See {ProxyAdmin-getProxyAdmin}. TIP: To get this value clients can read directly from the storage slot shown below (specified by EIP1967) using the https://eth.wiki/json-rpc/API#eth_getstorageat[`eth_getStorageAt`] RPC call. `0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103`" + }, + "changeAdmin(address)": { + "details": "Changes the admin of the proxy. Emits an {AdminChanged} event. NOTE: Only the admin can call this function. See {ProxyAdmin-changeProxyAdmin}." + }, + "constructor": { + "details": "Initializes an upgradeable proxy managed by `_admin`, backed by the implementation at `_logic`, and optionally initialized with `_data` as explained in {ERC1967Proxy-constructor}." + }, + "implementation()": { + "details": "Returns the current implementation. NOTE: Only the admin can call this function. See {ProxyAdmin-getProxyImplementation}. TIP: To get this value clients can read directly from the storage slot shown below (specified by EIP1967) using the https://eth.wiki/json-rpc/API#eth_getstorageat[`eth_getStorageAt`] RPC call. `0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc`" + }, + "upgradeTo(address)": { + "details": "Upgrade the implementation of the proxy. NOTE: Only the admin can call this function. See {ProxyAdmin-upgrade}." + }, + "upgradeToAndCall(address,bytes)": { + "details": "Upgrade the implementation of the proxy, and then call a function from the new implementation as specified by `data`, which should be an encoded function call. This is useful to initialize new storage variables in the proxied contract. NOTE: Only the admin can call this function. See {ProxyAdmin-upgradeAndCall}." + } + }, + "version": 1 + }, + "userdoc": { + "kind": "user", + "methods": {}, + "version": 1 + }, + "storageLayout": { + "storage": [], + "types": null + } +} \ No newline at end of file diff --git a/deployments/polygonzkevm/Treasury_USD.json b/deployments/polygonzkevm/Treasury_USD.json new file mode 100644 index 00000000..a1668f84 --- /dev/null +++ b/deployments/polygonzkevm/Treasury_USD.json @@ -0,0 +1,247 @@ +{ + "address": "0x352742b8c16bf83b83107283E151F843E80fdD97", + "abi": [ + { + "inputs": [ + { + "internalType": "address", + "name": "_logic", + "type": "address" + }, + { + "internalType": "address", + "name": "admin_", + "type": "address" + }, + { + "internalType": "bytes", + "name": "_data", + "type": "bytes" + } + ], + "stateMutability": "payable", + "type": "constructor" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "previousAdmin", + "type": "address" + }, + { + "indexed": false, + "internalType": "address", + "name": "newAdmin", + "type": "address" + } + ], + "name": "AdminChanged", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "beacon", + "type": "address" + } + ], + "name": "BeaconUpgraded", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "implementation", + "type": "address" + } + ], + "name": "Upgraded", + "type": "event" + }, + { + "stateMutability": "payable", + "type": "fallback" + }, + { + "inputs": [], + "name": "admin", + "outputs": [ + { + "internalType": "address", + "name": "admin_", + "type": "address" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "newAdmin", + "type": "address" + } + ], + "name": "changeAdmin", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "implementation", + "outputs": [ + { + "internalType": "address", + "name": "implementation_", + "type": "address" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "newImplementation", + "type": "address" + } + ], + "name": "upgradeTo", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "newImplementation", + "type": "address" + }, + { + "internalType": "bytes", + "name": "data", + "type": "bytes" + } + ], + "name": "upgradeToAndCall", + "outputs": [], + "stateMutability": "payable", + "type": "function" + }, + { + "stateMutability": "payable", + "type": "receive" + } + ], + "transactionHash": "0x1932b3b94468c662b9b29825f1a8863cf3354d4c918d997303825d009a19de23", + "receipt": { + "to": null, + "from": "0xfdA462548Ce04282f4B6D6619823a7C64Fdc0185", + "contractAddress": "0x352742b8c16bf83b83107283E151F843E80fdD97", + "transactionIndex": 0, + "gasUsed": "736150", + "logsBloom": "0x00000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000000000000000000020000000000000000000000000040000000000000000002000000000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000010000000000000000000000000000000080000000000000800000000000000000000000000000000400000000000000000000000000000000000000000020000000000011000000040000000000000400000000000000000000000000000000000000000000000000000000000000000000000002000000000000", + "blockHash": "0x77e1cf34bbb1834a4d780353fccc29492c5b1fae4792dda03b797e68ab23c46b", + "transactionHash": "0x1932b3b94468c662b9b29825f1a8863cf3354d4c918d997303825d009a19de23", + "logs": [ + { + "transactionIndex": 0, + "blockNumber": 9134295, + "transactionHash": "0x1932b3b94468c662b9b29825f1a8863cf3354d4c918d997303825d009a19de23", + "address": "0x352742b8c16bf83b83107283E151F843E80fdD97", + "topics": [ + "0xbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b", + "0x0000000000000000000000001a7e4e63778b4f12a199c062f3efdd288afcbce8" + ], + "data": "0x", + "logIndex": 0, + "blockHash": "0x77e1cf34bbb1834a4d780353fccc29492c5b1fae4792dda03b797e68ab23c46b" + }, + { + "transactionIndex": 0, + "blockNumber": 9134295, + "transactionHash": "0x1932b3b94468c662b9b29825f1a8863cf3354d4c918d997303825d009a19de23", + "address": "0x352742b8c16bf83b83107283E151F843E80fdD97", + "topics": [ + "0x7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb3847402498" + ], + "data": "0x0000000000000000000000000000000000000000000000000000000000000001", + "logIndex": 1, + "blockHash": "0x77e1cf34bbb1834a4d780353fccc29492c5b1fae4792dda03b797e68ab23c46b" + }, + { + "transactionIndex": 0, + "blockNumber": 9134295, + "transactionHash": "0x1932b3b94468c662b9b29825f1a8863cf3354d4c918d997303825d009a19de23", + "address": "0x352742b8c16bf83b83107283E151F843E80fdD97", + "topics": [ + "0x7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f" + ], + "data": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000001d941ef0d3bba4ad67dbfbcee5262f4cee53a32b", + "logIndex": 2, + "blockHash": "0x77e1cf34bbb1834a4d780353fccc29492c5b1fae4792dda03b797e68ab23c46b" + } + ], + "blockNumber": 9134295, + "cumulativeGasUsed": "736150", + "status": 1, + "byzantium": true + }, + "args": [ + "0x1a7e4e63778B4f12a199C062f3eFdD288afCBce8", + "0x1D941EF0D3Bba4ad67DBfBCeE5262F4CEE53A32b", + "0x485cc955000000000000000000000000b1f2a25ffb2b095e99f430caf507cc31f9a3eaab0000000000000000000000000000206329b97db379d5e1bf586bbdb969c63274" + ], + "numDeployments": 1, + "solcInputHash": "871924e0c138825a2736b76def8fef8d", + "metadata": "{\"compiler\":{\"version\":\"0.8.17+commit.8df45f5f\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_logic\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"admin_\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"_data\",\"type\":\"bytes\"}],\"stateMutability\":\"payable\",\"type\":\"constructor\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"previousAdmin\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"newAdmin\",\"type\":\"address\"}],\"name\":\"AdminChanged\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"beacon\",\"type\":\"address\"}],\"name\":\"BeaconUpgraded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"implementation\",\"type\":\"address\"}],\"name\":\"Upgraded\",\"type\":\"event\"},{\"stateMutability\":\"payable\",\"type\":\"fallback\"},{\"inputs\":[],\"name\":\"admin\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"admin_\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newAdmin\",\"type\":\"address\"}],\"name\":\"changeAdmin\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"implementation\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"implementation_\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newImplementation\",\"type\":\"address\"}],\"name\":\"upgradeTo\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newImplementation\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"}],\"name\":\"upgradeToAndCall\",\"outputs\":[],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"stateMutability\":\"payable\",\"type\":\"receive\"}],\"devdoc\":{\"details\":\"This contract implements a proxy that is upgradeable by an admin. It is fully forked from OpenZeppelin `TransparentUpgradeableProxy` To avoid https://medium.com/nomic-labs-blog/malicious-backdoors-in-ethereum-proxies-62629adf3357[proxy selector clashing], which can potentially be used in an attack, this contract uses the https://blog.openzeppelin.com/the-transparent-proxy-pattern/[transparent proxy pattern]. This pattern implies two things that go hand in hand: 1. If any account other than the admin calls the proxy, the call will be forwarded to the implementation, even if that call matches one of the admin functions exposed by the proxy itself. 2. If the admin calls the proxy, it can access the admin functions, but its calls will never be forwarded to the implementation. If the admin tries to call a function on the implementation it will fail with an error that says \\\"admin cannot fallback to proxy target\\\". These properties mean that the admin account can only be used for admin actions like upgrading the proxy or changing the admin, so it's best if it's a dedicated account that is not used for anything else. This will avoid headaches due to sudden errors when trying to call a function from the proxy implementation. Our recommendation is for the dedicated account to be an instance of the {ProxyAdmin} contract. If set up this way, you should think of the `ProxyAdmin` instance as the real administrative interface of your proxy.\",\"kind\":\"dev\",\"methods\":{\"admin()\":{\"details\":\"Returns the current admin. NOTE: Only the admin can call this function. See {ProxyAdmin-getProxyAdmin}. TIP: To get this value clients can read directly from the storage slot shown below (specified by EIP1967) using the https://eth.wiki/json-rpc/API#eth_getstorageat[`eth_getStorageAt`] RPC call. `0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103`\"},\"changeAdmin(address)\":{\"details\":\"Changes the admin of the proxy. Emits an {AdminChanged} event. NOTE: Only the admin can call this function. See {ProxyAdmin-changeProxyAdmin}.\"},\"constructor\":{\"details\":\"Initializes an upgradeable proxy managed by `_admin`, backed by the implementation at `_logic`, and optionally initialized with `_data` as explained in {ERC1967Proxy-constructor}.\"},\"implementation()\":{\"details\":\"Returns the current implementation. NOTE: Only the admin can call this function. See {ProxyAdmin-getProxyImplementation}. TIP: To get this value clients can read directly from the storage slot shown below (specified by EIP1967) using the https://eth.wiki/json-rpc/API#eth_getstorageat[`eth_getStorageAt`] RPC call. `0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc`\"},\"upgradeTo(address)\":{\"details\":\"Upgrade the implementation of the proxy. NOTE: Only the admin can call this function. See {ProxyAdmin-upgrade}.\"},\"upgradeToAndCall(address,bytes)\":{\"details\":\"Upgrade the implementation of the proxy, and then call a function from the new implementation as specified by `data`, which should be an encoded function call. This is useful to initialize new storage variables in the proxied contract. NOTE: Only the admin can call this function. See {ProxyAdmin-upgradeAndCall}.\"}},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/external/TransparentUpgradeableProxy.sol\":\"TransparentUpgradeableProxy\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":1000000},\"remappings\":[]},\"sources\":{\"@openzeppelin/contracts/interfaces/draft-IERC1822.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.5.0) (interfaces/draft-IERC1822.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev ERC1822: Universal Upgradeable Proxy Standard (UUPS) documents a method for upgradeability through a simplified\\n * proxy whose upgrades are fully controlled by the current implementation.\\n */\\ninterface IERC1822Proxiable {\\n /**\\n * @dev Returns the storage slot that the proxiable contract assumes is being used to store the implementation\\n * address.\\n *\\n * IMPORTANT: A proxy pointing at a proxiable contract should not be considered proxiable itself, because this risks\\n * bricking a proxy that upgrades to it, by delegating to itself until out of gas. Thus it is critical that this\\n * function revert if invoked through a proxy.\\n */\\n function proxiableUUID() external view returns (bytes32);\\n}\\n\",\"keccak256\":\"0x1d4afe6cb24200cc4545eed814ecf5847277dfe5d613a1707aad5fceecebcfff\",\"license\":\"MIT\"},\"@openzeppelin/contracts/proxy/ERC1967/ERC1967Proxy.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.7.0) (proxy/ERC1967/ERC1967Proxy.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../Proxy.sol\\\";\\nimport \\\"./ERC1967Upgrade.sol\\\";\\n\\n/**\\n * @dev This contract implements an upgradeable proxy. It is upgradeable because calls are delegated to an\\n * implementation address that can be changed. This address is stored in storage in the location specified by\\n * https://eips.ethereum.org/EIPS/eip-1967[EIP1967], so that it doesn't conflict with the storage layout of the\\n * implementation behind the proxy.\\n */\\ncontract ERC1967Proxy is Proxy, ERC1967Upgrade {\\n /**\\n * @dev Initializes the upgradeable proxy with an initial implementation specified by `_logic`.\\n *\\n * If `_data` is nonempty, it's used as data in a delegate call to `_logic`. This will typically be an encoded\\n * function call, and allows initializing the storage of the proxy like a Solidity constructor.\\n */\\n constructor(address _logic, bytes memory _data) payable {\\n _upgradeToAndCall(_logic, _data, false);\\n }\\n\\n /**\\n * @dev Returns the current implementation address.\\n */\\n function _implementation() internal view virtual override returns (address impl) {\\n return ERC1967Upgrade._getImplementation();\\n }\\n}\\n\",\"keccak256\":\"0xa2b22da3032e50b55f95ec1d13336102d675f341167aa76db571ef7f8bb7975d\",\"license\":\"MIT\"},\"@openzeppelin/contracts/proxy/ERC1967/ERC1967Upgrade.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.5.0) (proxy/ERC1967/ERC1967Upgrade.sol)\\n\\npragma solidity ^0.8.2;\\n\\nimport \\\"../beacon/IBeacon.sol\\\";\\nimport \\\"../../interfaces/draft-IERC1822.sol\\\";\\nimport \\\"../../utils/Address.sol\\\";\\nimport \\\"../../utils/StorageSlot.sol\\\";\\n\\n/**\\n * @dev This abstract contract provides getters and event emitting update functions for\\n * https://eips.ethereum.org/EIPS/eip-1967[EIP1967] slots.\\n *\\n * _Available since v4.1._\\n *\\n * @custom:oz-upgrades-unsafe-allow delegatecall\\n */\\nabstract contract ERC1967Upgrade {\\n // This is the keccak-256 hash of \\\"eip1967.proxy.rollback\\\" subtracted by 1\\n bytes32 private constant _ROLLBACK_SLOT = 0x4910fdfa16fed3260ed0e7147f7cc6da11a60208b5b9406d12a635614ffd9143;\\n\\n /**\\n * @dev Storage slot with the address of the current implementation.\\n * This is the keccak-256 hash of \\\"eip1967.proxy.implementation\\\" subtracted by 1, and is\\n * validated in the constructor.\\n */\\n bytes32 internal constant _IMPLEMENTATION_SLOT = 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc;\\n\\n /**\\n * @dev Emitted when the implementation is upgraded.\\n */\\n event Upgraded(address indexed implementation);\\n\\n /**\\n * @dev Returns the current implementation address.\\n */\\n function _getImplementation() internal view returns (address) {\\n return StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value;\\n }\\n\\n /**\\n * @dev Stores a new address in the EIP1967 implementation slot.\\n */\\n function _setImplementation(address newImplementation) private {\\n require(Address.isContract(newImplementation), \\\"ERC1967: new implementation is not a contract\\\");\\n StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value = newImplementation;\\n }\\n\\n /**\\n * @dev Perform implementation upgrade\\n *\\n * Emits an {Upgraded} event.\\n */\\n function _upgradeTo(address newImplementation) internal {\\n _setImplementation(newImplementation);\\n emit Upgraded(newImplementation);\\n }\\n\\n /**\\n * @dev Perform implementation upgrade with additional setup call.\\n *\\n * Emits an {Upgraded} event.\\n */\\n function _upgradeToAndCall(\\n address newImplementation,\\n bytes memory data,\\n bool forceCall\\n ) internal {\\n _upgradeTo(newImplementation);\\n if (data.length > 0 || forceCall) {\\n Address.functionDelegateCall(newImplementation, data);\\n }\\n }\\n\\n /**\\n * @dev Perform implementation upgrade with security checks for UUPS proxies, and additional setup call.\\n *\\n * Emits an {Upgraded} event.\\n */\\n function _upgradeToAndCallUUPS(\\n address newImplementation,\\n bytes memory data,\\n bool forceCall\\n ) internal {\\n // Upgrades from old implementations will perform a rollback test. This test requires the new\\n // implementation to upgrade back to the old, non-ERC1822 compliant, implementation. Removing\\n // this special case will break upgrade paths from old UUPS implementation to new ones.\\n if (StorageSlot.getBooleanSlot(_ROLLBACK_SLOT).value) {\\n _setImplementation(newImplementation);\\n } else {\\n try IERC1822Proxiable(newImplementation).proxiableUUID() returns (bytes32 slot) {\\n require(slot == _IMPLEMENTATION_SLOT, \\\"ERC1967Upgrade: unsupported proxiableUUID\\\");\\n } catch {\\n revert(\\\"ERC1967Upgrade: new implementation is not UUPS\\\");\\n }\\n _upgradeToAndCall(newImplementation, data, forceCall);\\n }\\n }\\n\\n /**\\n * @dev Storage slot with the admin of the contract.\\n * This is the keccak-256 hash of \\\"eip1967.proxy.admin\\\" subtracted by 1, and is\\n * validated in the constructor.\\n */\\n bytes32 internal constant _ADMIN_SLOT = 0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103;\\n\\n /**\\n * @dev Emitted when the admin account has changed.\\n */\\n event AdminChanged(address previousAdmin, address newAdmin);\\n\\n /**\\n * @dev Returns the current admin.\\n */\\n function _getAdmin() internal view returns (address) {\\n return StorageSlot.getAddressSlot(_ADMIN_SLOT).value;\\n }\\n\\n /**\\n * @dev Stores a new address in the EIP1967 admin slot.\\n */\\n function _setAdmin(address newAdmin) private {\\n require(newAdmin != address(0), \\\"ERC1967: new admin is the zero address\\\");\\n StorageSlot.getAddressSlot(_ADMIN_SLOT).value = newAdmin;\\n }\\n\\n /**\\n * @dev Changes the admin of the proxy.\\n *\\n * Emits an {AdminChanged} event.\\n */\\n function _changeAdmin(address newAdmin) internal {\\n emit AdminChanged(_getAdmin(), newAdmin);\\n _setAdmin(newAdmin);\\n }\\n\\n /**\\n * @dev The storage slot of the UpgradeableBeacon contract which defines the implementation for this proxy.\\n * This is bytes32(uint256(keccak256('eip1967.proxy.beacon')) - 1)) and is validated in the constructor.\\n */\\n bytes32 internal constant _BEACON_SLOT = 0xa3f0ad74e5423aebfd80d3ef4346578335a9a72aeaee59ff6cb3582b35133d50;\\n\\n /**\\n * @dev Emitted when the beacon is upgraded.\\n */\\n event BeaconUpgraded(address indexed beacon);\\n\\n /**\\n * @dev Returns the current beacon.\\n */\\n function _getBeacon() internal view returns (address) {\\n return StorageSlot.getAddressSlot(_BEACON_SLOT).value;\\n }\\n\\n /**\\n * @dev Stores a new beacon in the EIP1967 beacon slot.\\n */\\n function _setBeacon(address newBeacon) private {\\n require(Address.isContract(newBeacon), \\\"ERC1967: new beacon is not a contract\\\");\\n require(\\n Address.isContract(IBeacon(newBeacon).implementation()),\\n \\\"ERC1967: beacon implementation is not a contract\\\"\\n );\\n StorageSlot.getAddressSlot(_BEACON_SLOT).value = newBeacon;\\n }\\n\\n /**\\n * @dev Perform beacon upgrade with additional setup call. Note: This upgrades the address of the beacon, it does\\n * not upgrade the implementation contained in the beacon (see {UpgradeableBeacon-_setImplementation} for that).\\n *\\n * Emits a {BeaconUpgraded} event.\\n */\\n function _upgradeBeaconToAndCall(\\n address newBeacon,\\n bytes memory data,\\n bool forceCall\\n ) internal {\\n _setBeacon(newBeacon);\\n emit BeaconUpgraded(newBeacon);\\n if (data.length > 0 || forceCall) {\\n Address.functionDelegateCall(IBeacon(newBeacon).implementation(), data);\\n }\\n }\\n}\\n\",\"keccak256\":\"0xabf3f59bc0e5423eae45e459dbe92e7052c6983628d39008590edc852a62f94a\",\"license\":\"MIT\"},\"@openzeppelin/contracts/proxy/Proxy.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.6.0) (proxy/Proxy.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev This abstract contract provides a fallback function that delegates all calls to another contract using the EVM\\n * instruction `delegatecall`. We refer to the second contract as the _implementation_ behind the proxy, and it has to\\n * be specified by overriding the virtual {_implementation} function.\\n *\\n * Additionally, delegation to the implementation can be triggered manually through the {_fallback} function, or to a\\n * different contract through the {_delegate} function.\\n *\\n * The success and return data of the delegated call will be returned back to the caller of the proxy.\\n */\\nabstract contract Proxy {\\n /**\\n * @dev Delegates the current call to `implementation`.\\n *\\n * This function does not return to its internal call site, it will return directly to the external caller.\\n */\\n function _delegate(address implementation) internal virtual {\\n assembly {\\n // Copy msg.data. We take full control of memory in this inline assembly\\n // block because it will not return to Solidity code. We overwrite the\\n // Solidity scratch pad at memory position 0.\\n calldatacopy(0, 0, calldatasize())\\n\\n // Call the implementation.\\n // out and outsize are 0 because we don't know the size yet.\\n let result := delegatecall(gas(), implementation, 0, calldatasize(), 0, 0)\\n\\n // Copy the returned data.\\n returndatacopy(0, 0, returndatasize())\\n\\n switch result\\n // delegatecall returns 0 on error.\\n case 0 {\\n revert(0, returndatasize())\\n }\\n default {\\n return(0, returndatasize())\\n }\\n }\\n }\\n\\n /**\\n * @dev This is a virtual function that should be overridden so it returns the address to which the fallback function\\n * and {_fallback} should delegate.\\n */\\n function _implementation() internal view virtual returns (address);\\n\\n /**\\n * @dev Delegates the current call to the address returned by `_implementation()`.\\n *\\n * This function does not return to its internal call site, it will return directly to the external caller.\\n */\\n function _fallback() internal virtual {\\n _beforeFallback();\\n _delegate(_implementation());\\n }\\n\\n /**\\n * @dev Fallback function that delegates calls to the address returned by `_implementation()`. Will run if no other\\n * function in the contract matches the call data.\\n */\\n fallback() external payable virtual {\\n _fallback();\\n }\\n\\n /**\\n * @dev Fallback function that delegates calls to the address returned by `_implementation()`. Will run if call data\\n * is empty.\\n */\\n receive() external payable virtual {\\n _fallback();\\n }\\n\\n /**\\n * @dev Hook that is called before falling back to the implementation. Can happen as part of a manual `_fallback`\\n * call, or as part of the Solidity `fallback` or `receive` functions.\\n *\\n * If overridden should call `super._beforeFallback()`.\\n */\\n function _beforeFallback() internal virtual {}\\n}\\n\",\"keccak256\":\"0xc130fe33f1b2132158531a87734153293f6d07bc263ff4ac90e85da9c82c0e27\",\"license\":\"MIT\"},\"@openzeppelin/contracts/proxy/beacon/IBeacon.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (proxy/beacon/IBeacon.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev This is the interface that {BeaconProxy} expects of its beacon.\\n */\\ninterface IBeacon {\\n /**\\n * @dev Must return an address that can be used as a delegate call target.\\n *\\n * {BeaconProxy} will check that this address is a contract.\\n */\\n function implementation() external view returns (address);\\n}\\n\",\"keccak256\":\"0xd50a3421ac379ccb1be435fa646d66a65c986b4924f0849839f08692f39dde61\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/Address.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.7.0) (utils/Address.sol)\\n\\npragma solidity ^0.8.1;\\n\\n/**\\n * @dev Collection of functions related to the address type\\n */\\nlibrary Address {\\n /**\\n * @dev Returns true if `account` is a contract.\\n *\\n * [IMPORTANT]\\n * ====\\n * It is unsafe to assume that an address for which this function returns\\n * false is an externally-owned account (EOA) and not a contract.\\n *\\n * Among others, `isContract` will return false for the following\\n * types of addresses:\\n *\\n * - an externally-owned account\\n * - a contract in construction\\n * - an address where a contract will be created\\n * - an address where a contract lived, but was destroyed\\n * ====\\n *\\n * [IMPORTANT]\\n * ====\\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\\n *\\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\\n * constructor.\\n * ====\\n */\\n function isContract(address account) internal view returns (bool) {\\n // This method relies on extcodesize/address.code.length, which returns 0\\n // for contracts in construction, since the code is only stored at the end\\n // of the constructor execution.\\n\\n return account.code.length > 0;\\n }\\n\\n /**\\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\\n * `recipient`, forwarding all available gas and reverting on errors.\\n *\\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\\n * imposed by `transfer`, making them unable to receive funds via\\n * `transfer`. {sendValue} removes this limitation.\\n *\\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\\n *\\n * IMPORTANT: because control is transferred to `recipient`, care must be\\n * taken to not create reentrancy vulnerabilities. Consider using\\n * {ReentrancyGuard} or the\\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\\n */\\n function sendValue(address payable recipient, uint256 amount) internal {\\n require(address(this).balance >= amount, \\\"Address: insufficient balance\\\");\\n\\n (bool success, ) = recipient.call{value: amount}(\\\"\\\");\\n require(success, \\\"Address: unable to send value, recipient may have reverted\\\");\\n }\\n\\n /**\\n * @dev Performs a Solidity function call using a low level `call`. A\\n * plain `call` is an unsafe replacement for a function call: use this\\n * function instead.\\n *\\n * If `target` reverts with a revert reason, it is bubbled up by this\\n * function (like regular Solidity function calls).\\n *\\n * Returns the raw returned data. To convert to the expected return value,\\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\\n *\\n * Requirements:\\n *\\n * - `target` must be a contract.\\n * - calling `target` with `data` must not revert.\\n *\\n * _Available since v3.1._\\n */\\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\\n return functionCall(target, data, \\\"Address: low-level call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\\n * `errorMessage` as a fallback revert reason when `target` reverts.\\n *\\n * _Available since v3.1._\\n */\\n function functionCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n return functionCallWithValue(target, data, 0, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but also transferring `value` wei to `target`.\\n *\\n * Requirements:\\n *\\n * - the calling contract must have an ETH balance of at least `value`.\\n * - the called Solidity function must be `payable`.\\n *\\n * _Available since v3.1._\\n */\\n function functionCallWithValue(\\n address target,\\n bytes memory data,\\n uint256 value\\n ) internal returns (bytes memory) {\\n return functionCallWithValue(target, data, value, \\\"Address: low-level call with value failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\\n * with `errorMessage` as a fallback revert reason when `target` reverts.\\n *\\n * _Available since v3.1._\\n */\\n function functionCallWithValue(\\n address target,\\n bytes memory data,\\n uint256 value,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n require(address(this).balance >= value, \\\"Address: insufficient balance for call\\\");\\n require(isContract(target), \\\"Address: call to non-contract\\\");\\n\\n (bool success, bytes memory returndata) = target.call{value: value}(data);\\n return verifyCallResult(success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but performing a static call.\\n *\\n * _Available since v3.3._\\n */\\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\\n return functionStaticCall(target, data, \\\"Address: low-level static call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\\n * but performing a static call.\\n *\\n * _Available since v3.3._\\n */\\n function functionStaticCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal view returns (bytes memory) {\\n require(isContract(target), \\\"Address: static call to non-contract\\\");\\n\\n (bool success, bytes memory returndata) = target.staticcall(data);\\n return verifyCallResult(success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but performing a delegate call.\\n *\\n * _Available since v3.4._\\n */\\n function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {\\n return functionDelegateCall(target, data, \\\"Address: low-level delegate call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\\n * but performing a delegate call.\\n *\\n * _Available since v3.4._\\n */\\n function functionDelegateCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n require(isContract(target), \\\"Address: delegate call to non-contract\\\");\\n\\n (bool success, bytes memory returndata) = target.delegatecall(data);\\n return verifyCallResult(success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the\\n * revert reason using the provided one.\\n *\\n * _Available since v4.3._\\n */\\n function verifyCallResult(\\n bool success,\\n bytes memory returndata,\\n string memory errorMessage\\n ) internal pure returns (bytes memory) {\\n if (success) {\\n return returndata;\\n } else {\\n // Look for revert reason and bubble it up if present\\n if (returndata.length > 0) {\\n // The easiest way to bubble the revert reason is using memory via assembly\\n /// @solidity memory-safe-assembly\\n assembly {\\n let returndata_size := mload(returndata)\\n revert(add(32, returndata), returndata_size)\\n }\\n } else {\\n revert(errorMessage);\\n }\\n }\\n }\\n}\\n\",\"keccak256\":\"0xd6153ce99bcdcce22b124f755e72553295be6abcd63804cfdffceb188b8bef10\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/StorageSlot.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.7.0) (utils/StorageSlot.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Library for reading and writing primitive types to specific storage slots.\\n *\\n * Storage slots are often used to avoid storage conflict when dealing with upgradeable contracts.\\n * This library helps with reading and writing to such slots without the need for inline assembly.\\n *\\n * The functions in this library return Slot structs that contain a `value` member that can be used to read or write.\\n *\\n * Example usage to set ERC1967 implementation slot:\\n * ```\\n * contract ERC1967 {\\n * bytes32 internal constant _IMPLEMENTATION_SLOT = 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc;\\n *\\n * function _getImplementation() internal view returns (address) {\\n * return StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value;\\n * }\\n *\\n * function _setImplementation(address newImplementation) internal {\\n * require(Address.isContract(newImplementation), \\\"ERC1967: new implementation is not a contract\\\");\\n * StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value = newImplementation;\\n * }\\n * }\\n * ```\\n *\\n * _Available since v4.1 for `address`, `bool`, `bytes32`, and `uint256`._\\n */\\nlibrary StorageSlot {\\n struct AddressSlot {\\n address value;\\n }\\n\\n struct BooleanSlot {\\n bool value;\\n }\\n\\n struct Bytes32Slot {\\n bytes32 value;\\n }\\n\\n struct Uint256Slot {\\n uint256 value;\\n }\\n\\n /**\\n * @dev Returns an `AddressSlot` with member `value` located at `slot`.\\n */\\n function getAddressSlot(bytes32 slot) internal pure returns (AddressSlot storage r) {\\n /// @solidity memory-safe-assembly\\n assembly {\\n r.slot := slot\\n }\\n }\\n\\n /**\\n * @dev Returns an `BooleanSlot` with member `value` located at `slot`.\\n */\\n function getBooleanSlot(bytes32 slot) internal pure returns (BooleanSlot storage r) {\\n /// @solidity memory-safe-assembly\\n assembly {\\n r.slot := slot\\n }\\n }\\n\\n /**\\n * @dev Returns an `Bytes32Slot` with member `value` located at `slot`.\\n */\\n function getBytes32Slot(bytes32 slot) internal pure returns (Bytes32Slot storage r) {\\n /// @solidity memory-safe-assembly\\n assembly {\\n r.slot := slot\\n }\\n }\\n\\n /**\\n * @dev Returns an `Uint256Slot` with member `value` located at `slot`.\\n */\\n function getUint256Slot(bytes32 slot) internal pure returns (Uint256Slot storage r) {\\n /// @solidity memory-safe-assembly\\n assembly {\\n r.slot := slot\\n }\\n }\\n}\\n\",\"keccak256\":\"0xd5c50c54bf02740ebd122ff06832546cb5fa84486d52695a9ccfd11666e0c81d\",\"license\":\"MIT\"},\"contracts/external/TransparentUpgradeableProxy.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-3.0\\n\\npragma solidity ^0.8.12;\\n\\nimport \\\"@openzeppelin/contracts/proxy/ERC1967/ERC1967Proxy.sol\\\";\\n\\n/**\\n * @dev This contract implements a proxy that is upgradeable by an admin. It is fully forked from OpenZeppelin\\n * `TransparentUpgradeableProxy`\\n *\\n * To avoid https://medium.com/nomic-labs-blog/malicious-backdoors-in-ethereum-proxies-62629adf3357[proxy selector\\n * clashing], which can potentially be used in an attack, this contract uses the\\n * https://blog.openzeppelin.com/the-transparent-proxy-pattern/[transparent proxy pattern]. This pattern implies two\\n * things that go hand in hand:\\n *\\n * 1. If any account other than the admin calls the proxy, the call will be forwarded to the implementation, even if\\n * that call matches one of the admin functions exposed by the proxy itself.\\n * 2. If the admin calls the proxy, it can access the admin functions, but its calls will never be forwarded to the\\n * implementation. If the admin tries to call a function on the implementation it will fail with an error that says\\n * \\\"admin cannot fallback to proxy target\\\".\\n *\\n * These properties mean that the admin account can only be used for admin actions like upgrading the proxy or changing\\n * the admin, so it's best if it's a dedicated account that is not used for anything else. This will avoid headaches due\\n * to sudden errors when trying to call a function from the proxy implementation.\\n *\\n * Our recommendation is for the dedicated account to be an instance of the {ProxyAdmin} contract. If set up this way,\\n * you should think of the `ProxyAdmin` instance as the real administrative interface of your proxy.\\n */\\ncontract TransparentUpgradeableProxy is ERC1967Proxy {\\n /**\\n * @dev Initializes an upgradeable proxy managed by `_admin`, backed by the implementation at `_logic`, and\\n * optionally initialized with `_data` as explained in {ERC1967Proxy-constructor}.\\n */\\n constructor(address _logic, address admin_, bytes memory _data) payable ERC1967Proxy(_logic, _data) {\\n assert(_ADMIN_SLOT == bytes32(uint256(keccak256(\\\"eip1967.proxy.admin\\\")) - 1));\\n _changeAdmin(admin_);\\n }\\n\\n /**\\n * @dev Modifier used internally that will delegate the call to the implementation unless the sender is the admin.\\n */\\n modifier ifAdmin() {\\n if (msg.sender == _getAdmin()) {\\n _;\\n } else {\\n _fallback();\\n }\\n }\\n\\n /**\\n * @dev Returns the current admin.\\n *\\n * NOTE: Only the admin can call this function. See {ProxyAdmin-getProxyAdmin}.\\n *\\n * TIP: To get this value clients can read directly from the storage slot shown below (specified by EIP1967) using the\\n * https://eth.wiki/json-rpc/API#eth_getstorageat[`eth_getStorageAt`] RPC call.\\n * `0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103`\\n */\\n function admin() external ifAdmin returns (address admin_) {\\n admin_ = _getAdmin();\\n }\\n\\n /**\\n * @dev Returns the current implementation.\\n *\\n * NOTE: Only the admin can call this function. See {ProxyAdmin-getProxyImplementation}.\\n *\\n * TIP: To get this value clients can read directly from the storage slot shown below (specified by EIP1967) using the\\n * https://eth.wiki/json-rpc/API#eth_getstorageat[`eth_getStorageAt`] RPC call.\\n * `0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc`\\n */\\n function implementation() external ifAdmin returns (address implementation_) {\\n implementation_ = _implementation();\\n }\\n\\n /**\\n * @dev Changes the admin of the proxy.\\n *\\n * Emits an {AdminChanged} event.\\n *\\n * NOTE: Only the admin can call this function. See {ProxyAdmin-changeProxyAdmin}.\\n */\\n function changeAdmin(address newAdmin) external virtual ifAdmin {\\n _changeAdmin(newAdmin);\\n }\\n\\n /**\\n * @dev Upgrade the implementation of the proxy.\\n *\\n * NOTE: Only the admin can call this function. See {ProxyAdmin-upgrade}.\\n */\\n function upgradeTo(address newImplementation) external ifAdmin {\\n _upgradeToAndCall(newImplementation, bytes(\\\"\\\"), false);\\n }\\n\\n /**\\n * @dev Upgrade the implementation of the proxy, and then call a function from the new implementation as specified\\n * by `data`, which should be an encoded function call. This is useful to initialize new storage variables in the\\n * proxied contract.\\n *\\n * NOTE: Only the admin can call this function. See {ProxyAdmin-upgradeAndCall}.\\n */\\n function upgradeToAndCall(address newImplementation, bytes calldata data) external payable ifAdmin {\\n _upgradeToAndCall(newImplementation, data, true);\\n }\\n\\n /**\\n * @dev Returns the current admin.\\n */\\n function _admin() internal view virtual returns (address) {\\n return _getAdmin();\\n }\\n\\n /**\\n * @dev Makes sure the admin cannot access the fallback function. See {Proxy-_beforeFallback}.\\n */\\n function _beforeFallback() internal virtual override {\\n require(msg.sender != _getAdmin(), \\\"TransparentUpgradeableProxy: admin cannot fallback to proxy target\\\");\\n super._beforeFallback();\\n }\\n}\\n\",\"keccak256\":\"0x93a67a0f612ea3ff2a76315e138a6a88267270a1379d3cc7be52845fbbe611e2\",\"license\":\"GPL-3.0\"}},\"version\":1}", + "bytecode": "0x6080604052604051620010bb380380620010bb8339810160408190526200002691620004d8565b828162000036828260006200009a565b5062000066905060017fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6104620005b8565b6000805160206200107483398151915214620000865762000086620005da565b6200009182620000d7565b50505062000643565b620000a58362000132565b600082511180620000b35750805b15620000d257620000d083836200017460201b6200028c1760201c565b505b505050565b7f7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f62000102620001a5565b604080516001600160a01b03928316815291841660208301520160405180910390a16200012f81620001de565b50565b6200013d8162000293565b6040516001600160a01b038216907fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b90600090a250565b60606200019c8383604051806060016040528060278152602001620010946027913962000347565b90505b92915050565b6000620001cf6000805160206200107483398151915260001b6200042f60201b6200022e1760201c565b546001600160a01b0316919050565b6001600160a01b038116620002495760405162461bcd60e51b815260206004820152602660248201527f455243313936373a206e65772061646d696e20697320746865207a65726f206160448201526564647265737360d01b60648201526084015b60405180910390fd5b80620002726000805160206200107483398151915260001b6200042f60201b6200022e1760201c565b80546001600160a01b0319166001600160a01b039290921691909117905550565b620002a9816200043260201b620002b81760201c565b6200030d5760405162461bcd60e51b815260206004820152602d60248201527f455243313936373a206e657720696d706c656d656e746174696f6e206973206e60448201526c1bdd08184818dbdb9d1c9858dd609a1b606482015260840162000240565b80620002727f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc60001b6200042f60201b6200022e1760201c565b60606001600160a01b0384163b620003b15760405162461bcd60e51b815260206004820152602660248201527f416464726573733a2064656c65676174652063616c6c20746f206e6f6e2d636f6044820152651b9d1c9858dd60d21b606482015260840162000240565b600080856001600160a01b031685604051620003ce9190620005f0565b600060405180830381855af49150503d80600081146200040b576040519150601f19603f3d011682016040523d82523d6000602084013e62000410565b606091505b5090925090506200042382828662000441565b925050505b9392505050565b90565b6001600160a01b03163b151590565b606083156200045257508162000428565b825115620004635782518084602001fd5b8160405162461bcd60e51b81526004016200024091906200060e565b80516001600160a01b03811681146200049757600080fd5b919050565b634e487b7160e01b600052604160045260246000fd5b60005b83811015620004cf578181015183820152602001620004b5565b50506000910152565b600080600060608486031215620004ee57600080fd5b620004f9846200047f565b925062000509602085016200047f565b60408501519092506001600160401b03808211156200052757600080fd5b818601915086601f8301126200053c57600080fd5b8151818111156200055157620005516200049c565b604051601f8201601f19908116603f011681019083821181831017156200057c576200057c6200049c565b816040528281528960208487010111156200059657600080fd5b620005a9836020830160208801620004b2565b80955050505050509250925092565b818103818111156200019f57634e487b7160e01b600052601160045260246000fd5b634e487b7160e01b600052600160045260246000fd5b6000825162000604818460208701620004b2565b9190910192915050565b60208152600082518060208401526200062f816040850160208701620004b2565b601f01601f19169190910160400192915050565b610a2180620006536000396000f3fe60806040526004361061005e5760003560e01c80635c60da1b116100435780635c60da1b146100a85780638f283970146100e6578063f851a440146101065761006d565b80633659cfe6146100755780634f1ef286146100955761006d565b3661006d5761006b61011b565b005b61006b61011b565b34801561008157600080fd5b5061006b610090366004610895565b610135565b61006b6100a33660046108b0565b61017f565b3480156100b457600080fd5b506100bd6101f3565b60405173ffffffffffffffffffffffffffffffffffffffff909116815260200160405180910390f35b3480156100f257600080fd5b5061006b610101366004610895565b610231565b34801561011257600080fd5b506100bd61025e565b6101236102d4565b61013361012e6103ab565b6103b5565b565b61013d6103d9565b73ffffffffffffffffffffffffffffffffffffffff1633036101775761017481604051806020016040528060008152506000610419565b50565b61017461011b565b6101876103d9565b73ffffffffffffffffffffffffffffffffffffffff1633036101eb576101e68383838080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525060019250610419915050565b505050565b6101e661011b565b60006101fd6103d9565b73ffffffffffffffffffffffffffffffffffffffff163303610226576102216103ab565b905090565b61022e61011b565b90565b6102396103d9565b73ffffffffffffffffffffffffffffffffffffffff1633036101775761017481610444565b60006102686103d9565b73ffffffffffffffffffffffffffffffffffffffff163303610226576102216103d9565b60606102b183836040518060600160405280602781526020016109c5602791396104a5565b9392505050565b73ffffffffffffffffffffffffffffffffffffffff163b151590565b6102dc6103d9565b73ffffffffffffffffffffffffffffffffffffffff163303610133576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604260248201527f5472616e73706172656e745570677261646561626c6550726f78793a2061646d60448201527f696e2063616e6e6f742066616c6c6261636b20746f2070726f7879207461726760648201527f6574000000000000000000000000000000000000000000000000000000000000608482015260a4015b60405180910390fd5b60006102216105cd565b3660008037600080366000845af43d6000803e8080156103d4573d6000f35b3d6000fd5b60007fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035b5473ffffffffffffffffffffffffffffffffffffffff16919050565b610422836105f5565b60008251118061042f5750805b156101e65761043e838361028c565b50505050565b7f7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f61046d6103d9565b6040805173ffffffffffffffffffffffffffffffffffffffff928316815291841660208301520160405180910390a161017481610642565b606073ffffffffffffffffffffffffffffffffffffffff84163b61054b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f416464726573733a2064656c65676174652063616c6c20746f206e6f6e2d636f60448201527f6e7472616374000000000000000000000000000000000000000000000000000060648201526084016103a2565b6000808573ffffffffffffffffffffffffffffffffffffffff16856040516105739190610957565b600060405180830381855af49150503d80600081146105ae576040519150601f19603f3d011682016040523d82523d6000602084013e6105b3565b606091505b50915091506105c382828661074e565b9695505050505050565b60007f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc6103fd565b6105fe816107a1565b60405173ffffffffffffffffffffffffffffffffffffffff8216907fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b90600090a250565b73ffffffffffffffffffffffffffffffffffffffff81166106e5576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f455243313936373a206e65772061646d696e20697320746865207a65726f206160448201527f646472657373000000000000000000000000000000000000000000000000000060648201526084016103a2565b807fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035b80547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff9290921691909117905550565b6060831561075d5750816102b1565b82511561076d5782518084602001fd5b816040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016103a29190610973565b73ffffffffffffffffffffffffffffffffffffffff81163b610845576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602d60248201527f455243313936373a206e657720696d706c656d656e746174696f6e206973206e60448201527f6f74206120636f6e74726163740000000000000000000000000000000000000060648201526084016103a2565b807f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc610708565b803573ffffffffffffffffffffffffffffffffffffffff8116811461089057600080fd5b919050565b6000602082840312156108a757600080fd5b6102b18261086c565b6000806000604084860312156108c557600080fd5b6108ce8461086c565b9250602084013567ffffffffffffffff808211156108eb57600080fd5b818601915086601f8301126108ff57600080fd5b81358181111561090e57600080fd5b87602082850101111561092057600080fd5b6020830194508093505050509250925092565b60005b8381101561094e578181015183820152602001610936565b50506000910152565b60008251610969818460208701610933565b9190910192915050565b6020815260008251806020840152610992816040850160208701610933565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016919091016040019291505056fe416464726573733a206c6f772d6c6576656c2064656c65676174652063616c6c206661696c6564a2646970667358221220e96638b07fb1675d93a95c49e417bc8111448b23a59918698cdcd8fd488dd7cf64736f6c63430008110033b53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103416464726573733a206c6f772d6c6576656c2064656c65676174652063616c6c206661696c6564", + "deployedBytecode": "0x60806040526004361061005e5760003560e01c80635c60da1b116100435780635c60da1b146100a85780638f283970146100e6578063f851a440146101065761006d565b80633659cfe6146100755780634f1ef286146100955761006d565b3661006d5761006b61011b565b005b61006b61011b565b34801561008157600080fd5b5061006b610090366004610895565b610135565b61006b6100a33660046108b0565b61017f565b3480156100b457600080fd5b506100bd6101f3565b60405173ffffffffffffffffffffffffffffffffffffffff909116815260200160405180910390f35b3480156100f257600080fd5b5061006b610101366004610895565b610231565b34801561011257600080fd5b506100bd61025e565b6101236102d4565b61013361012e6103ab565b6103b5565b565b61013d6103d9565b73ffffffffffffffffffffffffffffffffffffffff1633036101775761017481604051806020016040528060008152506000610419565b50565b61017461011b565b6101876103d9565b73ffffffffffffffffffffffffffffffffffffffff1633036101eb576101e68383838080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525060019250610419915050565b505050565b6101e661011b565b60006101fd6103d9565b73ffffffffffffffffffffffffffffffffffffffff163303610226576102216103ab565b905090565b61022e61011b565b90565b6102396103d9565b73ffffffffffffffffffffffffffffffffffffffff1633036101775761017481610444565b60006102686103d9565b73ffffffffffffffffffffffffffffffffffffffff163303610226576102216103d9565b60606102b183836040518060600160405280602781526020016109c5602791396104a5565b9392505050565b73ffffffffffffffffffffffffffffffffffffffff163b151590565b6102dc6103d9565b73ffffffffffffffffffffffffffffffffffffffff163303610133576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604260248201527f5472616e73706172656e745570677261646561626c6550726f78793a2061646d60448201527f696e2063616e6e6f742066616c6c6261636b20746f2070726f7879207461726760648201527f6574000000000000000000000000000000000000000000000000000000000000608482015260a4015b60405180910390fd5b60006102216105cd565b3660008037600080366000845af43d6000803e8080156103d4573d6000f35b3d6000fd5b60007fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035b5473ffffffffffffffffffffffffffffffffffffffff16919050565b610422836105f5565b60008251118061042f5750805b156101e65761043e838361028c565b50505050565b7f7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f61046d6103d9565b6040805173ffffffffffffffffffffffffffffffffffffffff928316815291841660208301520160405180910390a161017481610642565b606073ffffffffffffffffffffffffffffffffffffffff84163b61054b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f416464726573733a2064656c65676174652063616c6c20746f206e6f6e2d636f60448201527f6e7472616374000000000000000000000000000000000000000000000000000060648201526084016103a2565b6000808573ffffffffffffffffffffffffffffffffffffffff16856040516105739190610957565b600060405180830381855af49150503d80600081146105ae576040519150601f19603f3d011682016040523d82523d6000602084013e6105b3565b606091505b50915091506105c382828661074e565b9695505050505050565b60007f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc6103fd565b6105fe816107a1565b60405173ffffffffffffffffffffffffffffffffffffffff8216907fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b90600090a250565b73ffffffffffffffffffffffffffffffffffffffff81166106e5576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f455243313936373a206e65772061646d696e20697320746865207a65726f206160448201527f646472657373000000000000000000000000000000000000000000000000000060648201526084016103a2565b807fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035b80547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff9290921691909117905550565b6060831561075d5750816102b1565b82511561076d5782518084602001fd5b816040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016103a29190610973565b73ffffffffffffffffffffffffffffffffffffffff81163b610845576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602d60248201527f455243313936373a206e657720696d706c656d656e746174696f6e206973206e60448201527f6f74206120636f6e74726163740000000000000000000000000000000000000060648201526084016103a2565b807f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc610708565b803573ffffffffffffffffffffffffffffffffffffffff8116811461089057600080fd5b919050565b6000602082840312156108a757600080fd5b6102b18261086c565b6000806000604084860312156108c557600080fd5b6108ce8461086c565b9250602084013567ffffffffffffffff808211156108eb57600080fd5b818601915086601f8301126108ff57600080fd5b81358181111561090e57600080fd5b87602082850101111561092057600080fd5b6020830194508093505050509250925092565b60005b8381101561094e578181015183820152602001610936565b50506000910152565b60008251610969818460208701610933565b9190910192915050565b6020815260008251806020840152610992816040850160208701610933565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016919091016040019291505056fe416464726573733a206c6f772d6c6576656c2064656c65676174652063616c6c206661696c6564a2646970667358221220e96638b07fb1675d93a95c49e417bc8111448b23a59918698cdcd8fd488dd7cf64736f6c63430008110033", + "devdoc": { + "details": "This contract implements a proxy that is upgradeable by an admin. It is fully forked from OpenZeppelin `TransparentUpgradeableProxy` To avoid https://medium.com/nomic-labs-blog/malicious-backdoors-in-ethereum-proxies-62629adf3357[proxy selector clashing], which can potentially be used in an attack, this contract uses the https://blog.openzeppelin.com/the-transparent-proxy-pattern/[transparent proxy pattern]. This pattern implies two things that go hand in hand: 1. If any account other than the admin calls the proxy, the call will be forwarded to the implementation, even if that call matches one of the admin functions exposed by the proxy itself. 2. If the admin calls the proxy, it can access the admin functions, but its calls will never be forwarded to the implementation. If the admin tries to call a function on the implementation it will fail with an error that says \"admin cannot fallback to proxy target\". These properties mean that the admin account can only be used for admin actions like upgrading the proxy or changing the admin, so it's best if it's a dedicated account that is not used for anything else. This will avoid headaches due to sudden errors when trying to call a function from the proxy implementation. Our recommendation is for the dedicated account to be an instance of the {ProxyAdmin} contract. If set up this way, you should think of the `ProxyAdmin` instance as the real administrative interface of your proxy.", + "kind": "dev", + "methods": { + "admin()": { + "details": "Returns the current admin. NOTE: Only the admin can call this function. See {ProxyAdmin-getProxyAdmin}. TIP: To get this value clients can read directly from the storage slot shown below (specified by EIP1967) using the https://eth.wiki/json-rpc/API#eth_getstorageat[`eth_getStorageAt`] RPC call. `0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103`" + }, + "changeAdmin(address)": { + "details": "Changes the admin of the proxy. Emits an {AdminChanged} event. NOTE: Only the admin can call this function. See {ProxyAdmin-changeProxyAdmin}." + }, + "constructor": { + "details": "Initializes an upgradeable proxy managed by `_admin`, backed by the implementation at `_logic`, and optionally initialized with `_data` as explained in {ERC1967Proxy-constructor}." + }, + "implementation()": { + "details": "Returns the current implementation. NOTE: Only the admin can call this function. See {ProxyAdmin-getProxyImplementation}. TIP: To get this value clients can read directly from the storage slot shown below (specified by EIP1967) using the https://eth.wiki/json-rpc/API#eth_getstorageat[`eth_getStorageAt`] RPC call. `0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc`" + }, + "upgradeTo(address)": { + "details": "Upgrade the implementation of the proxy. NOTE: Only the admin can call this function. See {ProxyAdmin-upgrade}." + }, + "upgradeToAndCall(address,bytes)": { + "details": "Upgrade the implementation of the proxy, and then call a function from the new implementation as specified by `data`, which should be an encoded function call. This is useful to initialize new storage variables in the proxied contract. NOTE: Only the admin can call this function. See {ProxyAdmin-upgradeAndCall}." + } + }, + "version": 1 + }, + "userdoc": { + "kind": "user", + "methods": {}, + "version": 1 + }, + "storageLayout": { + "storage": [], + "types": null + } +} \ No newline at end of file diff --git a/deployments/polygonzkevm/solcInputs/871924e0c138825a2736b76def8fef8d.json b/deployments/polygonzkevm/solcInputs/871924e0c138825a2736b76def8fef8d.json new file mode 100644 index 00000000..57454028 --- /dev/null +++ b/deployments/polygonzkevm/solcInputs/871924e0c138825a2736b76def8fef8d.json @@ -0,0 +1,562 @@ +{ + "language": "Solidity", + "sources": { + "@chainlink/contracts/src/v0.8/interfaces/AggregatorV3Interface.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.0;\n\ninterface AggregatorV3Interface {\n\n function decimals()\n external\n view\n returns (\n uint8\n );\n\n function description()\n external\n view\n returns (\n string memory\n );\n\n function version()\n external\n view\n returns (\n uint256\n );\n\n // getRoundData and latestRoundData should both raise \"No data present\"\n // if they do not have data to report, instead of returning unset values\n // which could be misinterpreted as actual reported values.\n function getRoundData(\n uint80 _roundId\n )\n external\n view\n returns (\n uint80 roundId,\n int256 answer,\n uint256 startedAt,\n uint256 updatedAt,\n uint80 answeredInRound\n );\n\n function latestRoundData()\n external\n view\n returns (\n uint80 roundId,\n int256 answer,\n uint256 startedAt,\n uint256 updatedAt,\n uint80 answeredInRound\n );\n\n}\n" + }, + "@openzeppelin/contracts-upgradeable/access/AccessControlEnumerableUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.5.0) (access/AccessControlEnumerable.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./IAccessControlEnumerableUpgradeable.sol\";\nimport \"./AccessControlUpgradeable.sol\";\nimport \"../utils/structs/EnumerableSetUpgradeable.sol\";\nimport \"../proxy/utils/Initializable.sol\";\n\n/**\n * @dev Extension of {AccessControl} that allows enumerating the members of each role.\n */\nabstract contract AccessControlEnumerableUpgradeable is Initializable, IAccessControlEnumerableUpgradeable, AccessControlUpgradeable {\n function __AccessControlEnumerable_init() internal onlyInitializing {\n }\n\n function __AccessControlEnumerable_init_unchained() internal onlyInitializing {\n }\n using EnumerableSetUpgradeable for EnumerableSetUpgradeable.AddressSet;\n\n mapping(bytes32 => EnumerableSetUpgradeable.AddressSet) private _roleMembers;\n\n /**\n * @dev See {IERC165-supportsInterface}.\n */\n function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {\n return interfaceId == type(IAccessControlEnumerableUpgradeable).interfaceId || super.supportsInterface(interfaceId);\n }\n\n /**\n * @dev Returns one of the accounts that have `role`. `index` must be a\n * value between 0 and {getRoleMemberCount}, non-inclusive.\n *\n * Role bearers are not sorted in any particular way, and their ordering may\n * change at any point.\n *\n * WARNING: When using {getRoleMember} and {getRoleMemberCount}, make sure\n * you perform all queries on the same block. See the following\n * https://forum.openzeppelin.com/t/iterating-over-elements-on-enumerableset-in-openzeppelin-contracts/2296[forum post]\n * for more information.\n */\n function getRoleMember(bytes32 role, uint256 index) public view virtual override returns (address) {\n return _roleMembers[role].at(index);\n }\n\n /**\n * @dev Returns the number of accounts that have `role`. Can be used\n * together with {getRoleMember} to enumerate all bearers of a role.\n */\n function getRoleMemberCount(bytes32 role) public view virtual override returns (uint256) {\n return _roleMembers[role].length();\n }\n\n /**\n * @dev Overload {_grantRole} to track enumerable memberships\n */\n function _grantRole(bytes32 role, address account) internal virtual override {\n super._grantRole(role, account);\n _roleMembers[role].add(account);\n }\n\n /**\n * @dev Overload {_revokeRole} to track enumerable memberships\n */\n function _revokeRole(bytes32 role, address account) internal virtual override {\n super._revokeRole(role, account);\n _roleMembers[role].remove(account);\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[49] private __gap;\n}\n" + }, + "@openzeppelin/contracts-upgradeable/access/AccessControlUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (access/AccessControl.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./IAccessControlUpgradeable.sol\";\nimport \"../utils/ContextUpgradeable.sol\";\nimport \"../utils/StringsUpgradeable.sol\";\nimport \"../utils/introspection/ERC165Upgradeable.sol\";\nimport \"../proxy/utils/Initializable.sol\";\n\n/**\n * @dev Contract module that allows children to implement role-based access\n * control mechanisms. This is a lightweight version that doesn't allow enumerating role\n * members except through off-chain means by accessing the contract event logs. Some\n * applications may benefit from on-chain enumerability, for those cases see\n * {AccessControlEnumerable}.\n *\n * Roles are referred to by their `bytes32` identifier. These should be exposed\n * in the external API and be unique. The best way to achieve this is by\n * using `public constant` hash digests:\n *\n * ```\n * bytes32 public constant MY_ROLE = keccak256(\"MY_ROLE\");\n * ```\n *\n * Roles can be used to represent a set of permissions. To restrict access to a\n * function call, use {hasRole}:\n *\n * ```\n * function foo() public {\n * require(hasRole(MY_ROLE, msg.sender));\n * ...\n * }\n * ```\n *\n * Roles can be granted and revoked dynamically via the {grantRole} and\n * {revokeRole} functions. Each role has an associated admin role, and only\n * accounts that have a role's admin role can call {grantRole} and {revokeRole}.\n *\n * By default, the admin role for all roles is `DEFAULT_ADMIN_ROLE`, which means\n * that only accounts with this role will be able to grant or revoke other\n * roles. More complex role relationships can be created by using\n * {_setRoleAdmin}.\n *\n * WARNING: The `DEFAULT_ADMIN_ROLE` is also its own admin: it has permission to\n * grant and revoke this role. Extra precautions should be taken to secure\n * accounts that have been granted it.\n */\nabstract contract AccessControlUpgradeable is Initializable, ContextUpgradeable, IAccessControlUpgradeable, ERC165Upgradeable {\n function __AccessControl_init() internal onlyInitializing {\n }\n\n function __AccessControl_init_unchained() internal onlyInitializing {\n }\n struct RoleData {\n mapping(address => bool) members;\n bytes32 adminRole;\n }\n\n mapping(bytes32 => RoleData) private _roles;\n\n bytes32 public constant DEFAULT_ADMIN_ROLE = 0x00;\n\n /**\n * @dev Modifier that checks that an account has a specific role. Reverts\n * with a standardized message including the required role.\n *\n * The format of the revert reason is given by the following regular expression:\n *\n * /^AccessControl: account (0x[0-9a-f]{40}) is missing role (0x[0-9a-f]{64})$/\n *\n * _Available since v4.1._\n */\n modifier onlyRole(bytes32 role) {\n _checkRole(role);\n _;\n }\n\n /**\n * @dev See {IERC165-supportsInterface}.\n */\n function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {\n return interfaceId == type(IAccessControlUpgradeable).interfaceId || super.supportsInterface(interfaceId);\n }\n\n /**\n * @dev Returns `true` if `account` has been granted `role`.\n */\n function hasRole(bytes32 role, address account) public view virtual override returns (bool) {\n return _roles[role].members[account];\n }\n\n /**\n * @dev Revert with a standard message if `_msgSender()` is missing `role`.\n * Overriding this function changes the behavior of the {onlyRole} modifier.\n *\n * Format of the revert message is described in {_checkRole}.\n *\n * _Available since v4.6._\n */\n function _checkRole(bytes32 role) internal view virtual {\n _checkRole(role, _msgSender());\n }\n\n /**\n * @dev Revert with a standard message if `account` is missing `role`.\n *\n * The format of the revert reason is given by the following regular expression:\n *\n * /^AccessControl: account (0x[0-9a-f]{40}) is missing role (0x[0-9a-f]{64})$/\n */\n function _checkRole(bytes32 role, address account) internal view virtual {\n if (!hasRole(role, account)) {\n revert(\n string(\n abi.encodePacked(\n \"AccessControl: account \",\n StringsUpgradeable.toHexString(uint160(account), 20),\n \" is missing role \",\n StringsUpgradeable.toHexString(uint256(role), 32)\n )\n )\n );\n }\n }\n\n /**\n * @dev Returns the admin role that controls `role`. See {grantRole} and\n * {revokeRole}.\n *\n * To change a role's admin, use {_setRoleAdmin}.\n */\n function getRoleAdmin(bytes32 role) public view virtual override returns (bytes32) {\n return _roles[role].adminRole;\n }\n\n /**\n * @dev Grants `role` to `account`.\n *\n * If `account` had not been already granted `role`, emits a {RoleGranted}\n * event.\n *\n * Requirements:\n *\n * - the caller must have ``role``'s admin role.\n *\n * May emit a {RoleGranted} event.\n */\n function grantRole(bytes32 role, address account) public virtual override onlyRole(getRoleAdmin(role)) {\n _grantRole(role, account);\n }\n\n /**\n * @dev Revokes `role` from `account`.\n *\n * If `account` had been granted `role`, emits a {RoleRevoked} event.\n *\n * Requirements:\n *\n * - the caller must have ``role``'s admin role.\n *\n * May emit a {RoleRevoked} event.\n */\n function revokeRole(bytes32 role, address account) public virtual override onlyRole(getRoleAdmin(role)) {\n _revokeRole(role, account);\n }\n\n /**\n * @dev Revokes `role` from the calling account.\n *\n * Roles are often managed via {grantRole} and {revokeRole}: this function's\n * purpose is to provide a mechanism for accounts to lose their privileges\n * if they are compromised (such as when a trusted device is misplaced).\n *\n * If the calling account had been revoked `role`, emits a {RoleRevoked}\n * event.\n *\n * Requirements:\n *\n * - the caller must be `account`.\n *\n * May emit a {RoleRevoked} event.\n */\n function renounceRole(bytes32 role, address account) public virtual override {\n require(account == _msgSender(), \"AccessControl: can only renounce roles for self\");\n\n _revokeRole(role, account);\n }\n\n /**\n * @dev Grants `role` to `account`.\n *\n * If `account` had not been already granted `role`, emits a {RoleGranted}\n * event. Note that unlike {grantRole}, this function doesn't perform any\n * checks on the calling account.\n *\n * May emit a {RoleGranted} event.\n *\n * [WARNING]\n * ====\n * This function should only be called from the constructor when setting\n * up the initial roles for the system.\n *\n * Using this function in any other way is effectively circumventing the admin\n * system imposed by {AccessControl}.\n * ====\n *\n * NOTE: This function is deprecated in favor of {_grantRole}.\n */\n function _setupRole(bytes32 role, address account) internal virtual {\n _grantRole(role, account);\n }\n\n /**\n * @dev Sets `adminRole` as ``role``'s admin role.\n *\n * Emits a {RoleAdminChanged} event.\n */\n function _setRoleAdmin(bytes32 role, bytes32 adminRole) internal virtual {\n bytes32 previousAdminRole = getRoleAdmin(role);\n _roles[role].adminRole = adminRole;\n emit RoleAdminChanged(role, previousAdminRole, adminRole);\n }\n\n /**\n * @dev Grants `role` to `account`.\n *\n * Internal function without access restriction.\n *\n * May emit a {RoleGranted} event.\n */\n function _grantRole(bytes32 role, address account) internal virtual {\n if (!hasRole(role, account)) {\n _roles[role].members[account] = true;\n emit RoleGranted(role, account, _msgSender());\n }\n }\n\n /**\n * @dev Revokes `role` from `account`.\n *\n * Internal function without access restriction.\n *\n * May emit a {RoleRevoked} event.\n */\n function _revokeRole(bytes32 role, address account) internal virtual {\n if (hasRole(role, account)) {\n _roles[role].members[account] = false;\n emit RoleRevoked(role, account, _msgSender());\n }\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[49] private __gap;\n}\n" + }, + "@openzeppelin/contracts-upgradeable/access/IAccessControlEnumerableUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (access/IAccessControlEnumerable.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./IAccessControlUpgradeable.sol\";\n\n/**\n * @dev External interface of AccessControlEnumerable declared to support ERC165 detection.\n */\ninterface IAccessControlEnumerableUpgradeable is IAccessControlUpgradeable {\n /**\n * @dev Returns one of the accounts that have `role`. `index` must be a\n * value between 0 and {getRoleMemberCount}, non-inclusive.\n *\n * Role bearers are not sorted in any particular way, and their ordering may\n * change at any point.\n *\n * WARNING: When using {getRoleMember} and {getRoleMemberCount}, make sure\n * you perform all queries on the same block. See the following\n * https://forum.openzeppelin.com/t/iterating-over-elements-on-enumerableset-in-openzeppelin-contracts/2296[forum post]\n * for more information.\n */\n function getRoleMember(bytes32 role, uint256 index) external view returns (address);\n\n /**\n * @dev Returns the number of accounts that have `role`. Can be used\n * together with {getRoleMember} to enumerate all bearers of a role.\n */\n function getRoleMemberCount(bytes32 role) external view returns (uint256);\n}\n" + }, + "@openzeppelin/contracts-upgradeable/access/IAccessControlUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (access/IAccessControl.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev External interface of AccessControl declared to support ERC165 detection.\n */\ninterface IAccessControlUpgradeable {\n /**\n * @dev Emitted when `newAdminRole` is set as ``role``'s admin role, replacing `previousAdminRole`\n *\n * `DEFAULT_ADMIN_ROLE` is the starting admin for all roles, despite\n * {RoleAdminChanged} not being emitted signaling this.\n *\n * _Available since v3.1._\n */\n event RoleAdminChanged(bytes32 indexed role, bytes32 indexed previousAdminRole, bytes32 indexed newAdminRole);\n\n /**\n * @dev Emitted when `account` is granted `role`.\n *\n * `sender` is the account that originated the contract call, an admin role\n * bearer except when using {AccessControl-_setupRole}.\n */\n event RoleGranted(bytes32 indexed role, address indexed account, address indexed sender);\n\n /**\n * @dev Emitted when `account` is revoked `role`.\n *\n * `sender` is the account that originated the contract call:\n * - if using `revokeRole`, it is the admin role bearer\n * - if using `renounceRole`, it is the role bearer (i.e. `account`)\n */\n event RoleRevoked(bytes32 indexed role, address indexed account, address indexed sender);\n\n /**\n * @dev Returns `true` if `account` has been granted `role`.\n */\n function hasRole(bytes32 role, address account) external view returns (bool);\n\n /**\n * @dev Returns the admin role that controls `role`. See {grantRole} and\n * {revokeRole}.\n *\n * To change a role's admin, use {AccessControl-_setRoleAdmin}.\n */\n function getRoleAdmin(bytes32 role) external view returns (bytes32);\n\n /**\n * @dev Grants `role` to `account`.\n *\n * If `account` had not been already granted `role`, emits a {RoleGranted}\n * event.\n *\n * Requirements:\n *\n * - the caller must have ``role``'s admin role.\n */\n function grantRole(bytes32 role, address account) external;\n\n /**\n * @dev Revokes `role` from `account`.\n *\n * If `account` had been granted `role`, emits a {RoleRevoked} event.\n *\n * Requirements:\n *\n * - the caller must have ``role``'s admin role.\n */\n function revokeRole(bytes32 role, address account) external;\n\n /**\n * @dev Revokes `role` from the calling account.\n *\n * Roles are often managed via {grantRole} and {revokeRole}: this function's\n * purpose is to provide a mechanism for accounts to lose their privileges\n * if they are compromised (such as when a trusted device is misplaced).\n *\n * If the calling account had been granted `role`, emits a {RoleRevoked}\n * event.\n *\n * Requirements:\n *\n * - the caller must be `account`.\n */\n function renounceRole(bytes32 role, address account) external;\n}\n" + }, + "@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (access/Ownable.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../utils/ContextUpgradeable.sol\";\nimport \"../proxy/utils/Initializable.sol\";\n\n/**\n * @dev Contract module which provides a basic access control mechanism, where\n * there is an account (an owner) that can be granted exclusive access to\n * specific functions.\n *\n * By default, the owner account will be the one that deploys the contract. This\n * can later be changed with {transferOwnership}.\n *\n * This module is used through inheritance. It will make available the modifier\n * `onlyOwner`, which can be applied to your functions to restrict their use to\n * the owner.\n */\nabstract contract OwnableUpgradeable is Initializable, ContextUpgradeable {\n address private _owner;\n\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\n\n /**\n * @dev Initializes the contract setting the deployer as the initial owner.\n */\n function __Ownable_init() internal onlyInitializing {\n __Ownable_init_unchained();\n }\n\n function __Ownable_init_unchained() internal onlyInitializing {\n _transferOwnership(_msgSender());\n }\n\n /**\n * @dev Throws if called by any account other than the owner.\n */\n modifier onlyOwner() {\n _checkOwner();\n _;\n }\n\n /**\n * @dev Returns the address of the current owner.\n */\n function owner() public view virtual returns (address) {\n return _owner;\n }\n\n /**\n * @dev Throws if the sender is not the owner.\n */\n function _checkOwner() internal view virtual {\n require(owner() == _msgSender(), \"Ownable: caller is not the owner\");\n }\n\n /**\n * @dev Leaves the contract without owner. It will not be possible to call\n * `onlyOwner` functions anymore. Can only be called by the current owner.\n *\n * NOTE: Renouncing ownership will leave the contract without an owner,\n * thereby removing any functionality that is only available to the owner.\n */\n function renounceOwnership() public virtual onlyOwner {\n _transferOwnership(address(0));\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Can only be called by the current owner.\n */\n function transferOwnership(address newOwner) public virtual onlyOwner {\n require(newOwner != address(0), \"Ownable: new owner is the zero address\");\n _transferOwnership(newOwner);\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Internal function without access restriction.\n */\n function _transferOwnership(address newOwner) internal virtual {\n address oldOwner = _owner;\n _owner = newOwner;\n emit OwnershipTransferred(oldOwner, newOwner);\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[49] private __gap;\n}\n" + }, + "@openzeppelin/contracts-upgradeable/interfaces/IERC721MetadataUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (interfaces/IERC721Metadata.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../token/ERC721/extensions/IERC721MetadataUpgradeable.sol\";\n" + }, + "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (proxy/utils/Initializable.sol)\n\npragma solidity ^0.8.2;\n\nimport \"../../utils/AddressUpgradeable.sol\";\n\n/**\n * @dev This is a base contract to aid in writing upgradeable contracts, or any kind of contract that will be deployed\n * behind a proxy. Since proxied contracts do not make use of a constructor, it's common to move constructor logic to an\n * external initializer function, usually called `initialize`. It then becomes necessary to protect this initializer\n * function so it can only be called once. The {initializer} modifier provided by this contract will have this effect.\n *\n * The initialization functions use a version number. Once a version number is used, it is consumed and cannot be\n * reused. This mechanism prevents re-execution of each \"step\" but allows the creation of new initialization steps in\n * case an upgrade adds a module that needs to be initialized.\n *\n * For example:\n *\n * [.hljs-theme-light.nopadding]\n * ```\n * contract MyToken is ERC20Upgradeable {\n * function initialize() initializer public {\n * __ERC20_init(\"MyToken\", \"MTK\");\n * }\n * }\n * contract MyTokenV2 is MyToken, ERC20PermitUpgradeable {\n * function initializeV2() reinitializer(2) public {\n * __ERC20Permit_init(\"MyToken\");\n * }\n * }\n * ```\n *\n * TIP: To avoid leaving the proxy in an uninitialized state, the initializer function should be called as early as\n * possible by providing the encoded function call as the `_data` argument to {ERC1967Proxy-constructor}.\n *\n * CAUTION: When used with inheritance, manual care must be taken to not invoke a parent initializer twice, or to ensure\n * that all initializers are idempotent. This is not verified automatically as constructors are by Solidity.\n *\n * [CAUTION]\n * ====\n * Avoid leaving a contract uninitialized.\n *\n * An uninitialized contract can be taken over by an attacker. This applies to both a proxy and its implementation\n * contract, which may impact the proxy. To prevent the implementation contract from being used, you should invoke\n * the {_disableInitializers} function in the constructor to automatically lock it when it is deployed:\n *\n * [.hljs-theme-light.nopadding]\n * ```\n * /// @custom:oz-upgrades-unsafe-allow constructor\n * constructor() {\n * _disableInitializers();\n * }\n * ```\n * ====\n */\nabstract contract Initializable {\n /**\n * @dev Indicates that the contract has been initialized.\n * @custom:oz-retyped-from bool\n */\n uint8 private _initialized;\n\n /**\n * @dev Indicates that the contract is in the process of being initialized.\n */\n bool private _initializing;\n\n /**\n * @dev Triggered when the contract has been initialized or reinitialized.\n */\n event Initialized(uint8 version);\n\n /**\n * @dev A modifier that defines a protected initializer function that can be invoked at most once. In its scope,\n * `onlyInitializing` functions can be used to initialize parent contracts. Equivalent to `reinitializer(1)`.\n */\n modifier initializer() {\n bool isTopLevelCall = !_initializing;\n require(\n (isTopLevelCall && _initialized < 1) || (!AddressUpgradeable.isContract(address(this)) && _initialized == 1),\n \"Initializable: contract is already initialized\"\n );\n _initialized = 1;\n if (isTopLevelCall) {\n _initializing = true;\n }\n _;\n if (isTopLevelCall) {\n _initializing = false;\n emit Initialized(1);\n }\n }\n\n /**\n * @dev A modifier that defines a protected reinitializer function that can be invoked at most once, and only if the\n * contract hasn't been initialized to a greater version before. In its scope, `onlyInitializing` functions can be\n * used to initialize parent contracts.\n *\n * `initializer` is equivalent to `reinitializer(1)`, so a reinitializer may be used after the original\n * initialization step. This is essential to configure modules that are added through upgrades and that require\n * initialization.\n *\n * Note that versions can jump in increments greater than 1; this implies that if multiple reinitializers coexist in\n * a contract, executing them in the right order is up to the developer or operator.\n */\n modifier reinitializer(uint8 version) {\n require(!_initializing && _initialized < version, \"Initializable: contract is already initialized\");\n _initialized = version;\n _initializing = true;\n _;\n _initializing = false;\n emit Initialized(version);\n }\n\n /**\n * @dev Modifier to protect an initialization function so that it can only be invoked by functions with the\n * {initializer} and {reinitializer} modifiers, directly or indirectly.\n */\n modifier onlyInitializing() {\n require(_initializing, \"Initializable: contract is not initializing\");\n _;\n }\n\n /**\n * @dev Locks the contract, preventing any future reinitialization. This cannot be part of an initializer call.\n * Calling this in the constructor of a contract will prevent that contract from being initialized or reinitialized\n * to any version. It is recommended to use this to lock implementation contracts that are designed to be called\n * through proxies.\n */\n function _disableInitializers() internal virtual {\n require(!_initializing, \"Initializable: contract is initializing\");\n if (_initialized < type(uint8).max) {\n _initialized = type(uint8).max;\n emit Initialized(type(uint8).max);\n }\n }\n}\n" + }, + "@openzeppelin/contracts-upgradeable/security/PausableUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (security/Pausable.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../utils/ContextUpgradeable.sol\";\nimport \"../proxy/utils/Initializable.sol\";\n\n/**\n * @dev Contract module which allows children to implement an emergency stop\n * mechanism that can be triggered by an authorized account.\n *\n * This module is used through inheritance. It will make available the\n * modifiers `whenNotPaused` and `whenPaused`, which can be applied to\n * the functions of your contract. Note that they will not be pausable by\n * simply including this module, only once the modifiers are put in place.\n */\nabstract contract PausableUpgradeable is Initializable, ContextUpgradeable {\n /**\n * @dev Emitted when the pause is triggered by `account`.\n */\n event Paused(address account);\n\n /**\n * @dev Emitted when the pause is lifted by `account`.\n */\n event Unpaused(address account);\n\n bool private _paused;\n\n /**\n * @dev Initializes the contract in unpaused state.\n */\n function __Pausable_init() internal onlyInitializing {\n __Pausable_init_unchained();\n }\n\n function __Pausable_init_unchained() internal onlyInitializing {\n _paused = false;\n }\n\n /**\n * @dev Modifier to make a function callable only when the contract is not paused.\n *\n * Requirements:\n *\n * - The contract must not be paused.\n */\n modifier whenNotPaused() {\n _requireNotPaused();\n _;\n }\n\n /**\n * @dev Modifier to make a function callable only when the contract is paused.\n *\n * Requirements:\n *\n * - The contract must be paused.\n */\n modifier whenPaused() {\n _requirePaused();\n _;\n }\n\n /**\n * @dev Returns true if the contract is paused, and false otherwise.\n */\n function paused() public view virtual returns (bool) {\n return _paused;\n }\n\n /**\n * @dev Throws if the contract is paused.\n */\n function _requireNotPaused() internal view virtual {\n require(!paused(), \"Pausable: paused\");\n }\n\n /**\n * @dev Throws if the contract is not paused.\n */\n function _requirePaused() internal view virtual {\n require(paused(), \"Pausable: not paused\");\n }\n\n /**\n * @dev Triggers stopped state.\n *\n * Requirements:\n *\n * - The contract must not be paused.\n */\n function _pause() internal virtual whenNotPaused {\n _paused = true;\n emit Paused(_msgSender());\n }\n\n /**\n * @dev Returns to normal state.\n *\n * Requirements:\n *\n * - The contract must be paused.\n */\n function _unpause() internal virtual whenPaused {\n _paused = false;\n emit Unpaused(_msgSender());\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[49] private __gap;\n}\n" + }, + "@openzeppelin/contracts-upgradeable/security/ReentrancyGuardUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (security/ReentrancyGuard.sol)\n\npragma solidity ^0.8.0;\nimport \"../proxy/utils/Initializable.sol\";\n\n/**\n * @dev Contract module that helps prevent reentrant calls to a function.\n *\n * Inheriting from `ReentrancyGuard` will make the {nonReentrant} modifier\n * available, which can be applied to functions to make sure there are no nested\n * (reentrant) calls to them.\n *\n * Note that because there is a single `nonReentrant` guard, functions marked as\n * `nonReentrant` may not call one another. This can be worked around by making\n * those functions `private`, and then adding `external` `nonReentrant` entry\n * points to them.\n *\n * TIP: If you would like to learn more about reentrancy and alternative ways\n * to protect against it, check out our blog post\n * https://blog.openzeppelin.com/reentrancy-after-istanbul/[Reentrancy After Istanbul].\n */\nabstract contract ReentrancyGuardUpgradeable is Initializable {\n // Booleans are more expensive than uint256 or any type that takes up a full\n // word because each write operation emits an extra SLOAD to first read the\n // slot's contents, replace the bits taken up by the boolean, and then write\n // back. This is the compiler's defense against contract upgrades and\n // pointer aliasing, and it cannot be disabled.\n\n // The values being non-zero value makes deployment a bit more expensive,\n // but in exchange the refund on every call to nonReentrant will be lower in\n // amount. Since refunds are capped to a percentage of the total\n // transaction's gas, it is best to keep them low in cases like this one, to\n // increase the likelihood of the full refund coming into effect.\n uint256 private constant _NOT_ENTERED = 1;\n uint256 private constant _ENTERED = 2;\n\n uint256 private _status;\n\n function __ReentrancyGuard_init() internal onlyInitializing {\n __ReentrancyGuard_init_unchained();\n }\n\n function __ReentrancyGuard_init_unchained() internal onlyInitializing {\n _status = _NOT_ENTERED;\n }\n\n /**\n * @dev Prevents a contract from calling itself, directly or indirectly.\n * Calling a `nonReentrant` function from another `nonReentrant`\n * function is not supported. It is possible to prevent this from happening\n * by making the `nonReentrant` function external, and making it call a\n * `private` function that does the actual work.\n */\n modifier nonReentrant() {\n // On the first call to nonReentrant, _notEntered will be true\n require(_status != _ENTERED, \"ReentrancyGuard: reentrant call\");\n\n // Any calls to nonReentrant after this point will fail\n _status = _ENTERED;\n\n _;\n\n // By storing the original value once again, a refund is triggered (see\n // https://eips.ethereum.org/EIPS/eip-2200)\n _status = _NOT_ENTERED;\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[49] private __gap;\n}\n" + }, + "@openzeppelin/contracts-upgradeable/token/ERC20/ERC20Upgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (token/ERC20/ERC20.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./IERC20Upgradeable.sol\";\nimport \"./extensions/IERC20MetadataUpgradeable.sol\";\nimport \"../../utils/ContextUpgradeable.sol\";\nimport \"../../proxy/utils/Initializable.sol\";\n\n/**\n * @dev Implementation of the {IERC20} interface.\n *\n * This implementation is agnostic to the way tokens are created. This means\n * that a supply mechanism has to be added in a derived contract using {_mint}.\n * For a generic mechanism see {ERC20PresetMinterPauser}.\n *\n * TIP: For a detailed writeup see our guide\n * https://forum.zeppelin.solutions/t/how-to-implement-erc20-supply-mechanisms/226[How\n * to implement supply mechanisms].\n *\n * We have followed general OpenZeppelin Contracts guidelines: functions revert\n * instead returning `false` on failure. This behavior is nonetheless\n * conventional and does not conflict with the expectations of ERC20\n * applications.\n *\n * Additionally, an {Approval} event is emitted on calls to {transferFrom}.\n * This allows applications to reconstruct the allowance for all accounts just\n * by listening to said events. Other implementations of the EIP may not emit\n * these events, as it isn't required by the specification.\n *\n * Finally, the non-standard {decreaseAllowance} and {increaseAllowance}\n * functions have been added to mitigate the well-known issues around setting\n * allowances. See {IERC20-approve}.\n */\ncontract ERC20Upgradeable is Initializable, ContextUpgradeable, IERC20Upgradeable, IERC20MetadataUpgradeable {\n mapping(address => uint256) private _balances;\n\n mapping(address => mapping(address => uint256)) private _allowances;\n\n uint256 private _totalSupply;\n\n string private _name;\n string private _symbol;\n\n /**\n * @dev Sets the values for {name} and {symbol}.\n *\n * The default value of {decimals} is 18. To select a different value for\n * {decimals} you should overload it.\n *\n * All two of these values are immutable: they can only be set once during\n * construction.\n */\n function __ERC20_init(string memory name_, string memory symbol_) internal onlyInitializing {\n __ERC20_init_unchained(name_, symbol_);\n }\n\n function __ERC20_init_unchained(string memory name_, string memory symbol_) internal onlyInitializing {\n _name = name_;\n _symbol = symbol_;\n }\n\n /**\n * @dev Returns the name of the token.\n */\n function name() public view virtual override returns (string memory) {\n return _name;\n }\n\n /**\n * @dev Returns the symbol of the token, usually a shorter version of the\n * name.\n */\n function symbol() public view virtual override returns (string memory) {\n return _symbol;\n }\n\n /**\n * @dev Returns the number of decimals used to get its user representation.\n * For example, if `decimals` equals `2`, a balance of `505` tokens should\n * be displayed to a user as `5.05` (`505 / 10 ** 2`).\n *\n * Tokens usually opt for a value of 18, imitating the relationship between\n * Ether and Wei. This is the value {ERC20} uses, unless this function is\n * overridden;\n *\n * NOTE: This information is only used for _display_ purposes: it in\n * no way affects any of the arithmetic of the contract, including\n * {IERC20-balanceOf} and {IERC20-transfer}.\n */\n function decimals() public view virtual override returns (uint8) {\n return 18;\n }\n\n /**\n * @dev See {IERC20-totalSupply}.\n */\n function totalSupply() public view virtual override returns (uint256) {\n return _totalSupply;\n }\n\n /**\n * @dev See {IERC20-balanceOf}.\n */\n function balanceOf(address account) public view virtual override returns (uint256) {\n return _balances[account];\n }\n\n /**\n * @dev See {IERC20-transfer}.\n *\n * Requirements:\n *\n * - `to` cannot be the zero address.\n * - the caller must have a balance of at least `amount`.\n */\n function transfer(address to, uint256 amount) public virtual override returns (bool) {\n address owner = _msgSender();\n _transfer(owner, to, amount);\n return true;\n }\n\n /**\n * @dev See {IERC20-allowance}.\n */\n function allowance(address owner, address spender) public view virtual override returns (uint256) {\n return _allowances[owner][spender];\n }\n\n /**\n * @dev See {IERC20-approve}.\n *\n * NOTE: If `amount` is the maximum `uint256`, the allowance is not updated on\n * `transferFrom`. This is semantically equivalent to an infinite approval.\n *\n * Requirements:\n *\n * - `spender` cannot be the zero address.\n */\n function approve(address spender, uint256 amount) public virtual override returns (bool) {\n address owner = _msgSender();\n _approve(owner, spender, amount);\n return true;\n }\n\n /**\n * @dev See {IERC20-transferFrom}.\n *\n * Emits an {Approval} event indicating the updated allowance. This is not\n * required by the EIP. See the note at the beginning of {ERC20}.\n *\n * NOTE: Does not update the allowance if the current allowance\n * is the maximum `uint256`.\n *\n * Requirements:\n *\n * - `from` and `to` cannot be the zero address.\n * - `from` must have a balance of at least `amount`.\n * - the caller must have allowance for ``from``'s tokens of at least\n * `amount`.\n */\n function transferFrom(\n address from,\n address to,\n uint256 amount\n ) public virtual override returns (bool) {\n address spender = _msgSender();\n _spendAllowance(from, spender, amount);\n _transfer(from, to, amount);\n return true;\n }\n\n /**\n * @dev Atomically increases the allowance granted to `spender` by the caller.\n *\n * This is an alternative to {approve} that can be used as a mitigation for\n * problems described in {IERC20-approve}.\n *\n * Emits an {Approval} event indicating the updated allowance.\n *\n * Requirements:\n *\n * - `spender` cannot be the zero address.\n */\n function increaseAllowance(address spender, uint256 addedValue) public virtual returns (bool) {\n address owner = _msgSender();\n _approve(owner, spender, allowance(owner, spender) + addedValue);\n return true;\n }\n\n /**\n * @dev Atomically decreases the allowance granted to `spender` by the caller.\n *\n * This is an alternative to {approve} that can be used as a mitigation for\n * problems described in {IERC20-approve}.\n *\n * Emits an {Approval} event indicating the updated allowance.\n *\n * Requirements:\n *\n * - `spender` cannot be the zero address.\n * - `spender` must have allowance for the caller of at least\n * `subtractedValue`.\n */\n function decreaseAllowance(address spender, uint256 subtractedValue) public virtual returns (bool) {\n address owner = _msgSender();\n uint256 currentAllowance = allowance(owner, spender);\n require(currentAllowance >= subtractedValue, \"ERC20: decreased allowance below zero\");\n unchecked {\n _approve(owner, spender, currentAllowance - subtractedValue);\n }\n\n return true;\n }\n\n /**\n * @dev Moves `amount` of tokens from `from` to `to`.\n *\n * This internal function is equivalent to {transfer}, and can be used to\n * e.g. implement automatic token fees, slashing mechanisms, etc.\n *\n * Emits a {Transfer} event.\n *\n * Requirements:\n *\n * - `from` cannot be the zero address.\n * - `to` cannot be the zero address.\n * - `from` must have a balance of at least `amount`.\n */\n function _transfer(\n address from,\n address to,\n uint256 amount\n ) internal virtual {\n require(from != address(0), \"ERC20: transfer from the zero address\");\n require(to != address(0), \"ERC20: transfer to the zero address\");\n\n _beforeTokenTransfer(from, to, amount);\n\n uint256 fromBalance = _balances[from];\n require(fromBalance >= amount, \"ERC20: transfer amount exceeds balance\");\n unchecked {\n _balances[from] = fromBalance - amount;\n }\n _balances[to] += amount;\n\n emit Transfer(from, to, amount);\n\n _afterTokenTransfer(from, to, amount);\n }\n\n /** @dev Creates `amount` tokens and assigns them to `account`, increasing\n * the total supply.\n *\n * Emits a {Transfer} event with `from` set to the zero address.\n *\n * Requirements:\n *\n * - `account` cannot be the zero address.\n */\n function _mint(address account, uint256 amount) internal virtual {\n require(account != address(0), \"ERC20: mint to the zero address\");\n\n _beforeTokenTransfer(address(0), account, amount);\n\n _totalSupply += amount;\n _balances[account] += amount;\n emit Transfer(address(0), account, amount);\n\n _afterTokenTransfer(address(0), account, amount);\n }\n\n /**\n * @dev Destroys `amount` tokens from `account`, reducing the\n * total supply.\n *\n * Emits a {Transfer} event with `to` set to the zero address.\n *\n * Requirements:\n *\n * - `account` cannot be the zero address.\n * - `account` must have at least `amount` tokens.\n */\n function _burn(address account, uint256 amount) internal virtual {\n require(account != address(0), \"ERC20: burn from the zero address\");\n\n _beforeTokenTransfer(account, address(0), amount);\n\n uint256 accountBalance = _balances[account];\n require(accountBalance >= amount, \"ERC20: burn amount exceeds balance\");\n unchecked {\n _balances[account] = accountBalance - amount;\n }\n _totalSupply -= amount;\n\n emit Transfer(account, address(0), amount);\n\n _afterTokenTransfer(account, address(0), amount);\n }\n\n /**\n * @dev Sets `amount` as the allowance of `spender` over the `owner` s tokens.\n *\n * This internal function is equivalent to `approve`, and can be used to\n * e.g. set automatic allowances for certain subsystems, etc.\n *\n * Emits an {Approval} event.\n *\n * Requirements:\n *\n * - `owner` cannot be the zero address.\n * - `spender` cannot be the zero address.\n */\n function _approve(\n address owner,\n address spender,\n uint256 amount\n ) internal virtual {\n require(owner != address(0), \"ERC20: approve from the zero address\");\n require(spender != address(0), \"ERC20: approve to the zero address\");\n\n _allowances[owner][spender] = amount;\n emit Approval(owner, spender, amount);\n }\n\n /**\n * @dev Updates `owner` s allowance for `spender` based on spent `amount`.\n *\n * Does not update the allowance amount in case of infinite allowance.\n * Revert if not enough allowance is available.\n *\n * Might emit an {Approval} event.\n */\n function _spendAllowance(\n address owner,\n address spender,\n uint256 amount\n ) internal virtual {\n uint256 currentAllowance = allowance(owner, spender);\n if (currentAllowance != type(uint256).max) {\n require(currentAllowance >= amount, \"ERC20: insufficient allowance\");\n unchecked {\n _approve(owner, spender, currentAllowance - amount);\n }\n }\n }\n\n /**\n * @dev Hook that is called before any transfer of tokens. This includes\n * minting and burning.\n *\n * Calling conditions:\n *\n * - when `from` and `to` are both non-zero, `amount` of ``from``'s tokens\n * will be transferred to `to`.\n * - when `from` is zero, `amount` tokens will be minted for `to`.\n * - when `to` is zero, `amount` of ``from``'s tokens will be burned.\n * - `from` and `to` are never both zero.\n *\n * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].\n */\n function _beforeTokenTransfer(\n address from,\n address to,\n uint256 amount\n ) internal virtual {}\n\n /**\n * @dev Hook that is called after any transfer of tokens. This includes\n * minting and burning.\n *\n * Calling conditions:\n *\n * - when `from` and `to` are both non-zero, `amount` of ``from``'s tokens\n * has been transferred to `to`.\n * - when `from` is zero, `amount` tokens have been minted for `to`.\n * - when `to` is zero, `amount` of ``from``'s tokens have been burned.\n * - `from` and `to` are never both zero.\n *\n * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].\n */\n function _afterTokenTransfer(\n address from,\n address to,\n uint256 amount\n ) internal virtual {}\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[45] private __gap;\n}\n" + }, + "@openzeppelin/contracts-upgradeable/token/ERC20/extensions/draft-ERC20PermitUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.6.0) (token/ERC20/extensions/draft-ERC20Permit.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./draft-IERC20PermitUpgradeable.sol\";\nimport \"../ERC20Upgradeable.sol\";\nimport \"../../../utils/cryptography/draft-EIP712Upgradeable.sol\";\nimport \"../../../utils/cryptography/ECDSAUpgradeable.sol\";\nimport \"../../../utils/CountersUpgradeable.sol\";\nimport \"../../../proxy/utils/Initializable.sol\";\n\n/**\n * @dev Implementation of the ERC20 Permit extension allowing approvals to be made via signatures, as defined in\n * https://eips.ethereum.org/EIPS/eip-2612[EIP-2612].\n *\n * Adds the {permit} method, which can be used to change an account's ERC20 allowance (see {IERC20-allowance}) by\n * presenting a message signed by the account. By not relying on `{IERC20-approve}`, the token holder account doesn't\n * need to send a transaction, and thus is not required to hold Ether at all.\n *\n * _Available since v3.4._\n *\n * @custom:storage-size 51\n */\nabstract contract ERC20PermitUpgradeable is Initializable, ERC20Upgradeable, IERC20PermitUpgradeable, EIP712Upgradeable {\n using CountersUpgradeable for CountersUpgradeable.Counter;\n\n mapping(address => CountersUpgradeable.Counter) private _nonces;\n\n // solhint-disable-next-line var-name-mixedcase\n bytes32 private constant _PERMIT_TYPEHASH =\n keccak256(\"Permit(address owner,address spender,uint256 value,uint256 nonce,uint256 deadline)\");\n /**\n * @dev In previous versions `_PERMIT_TYPEHASH` was declared as `immutable`.\n * However, to ensure consistency with the upgradeable transpiler, we will continue\n * to reserve a slot.\n * @custom:oz-renamed-from _PERMIT_TYPEHASH\n */\n // solhint-disable-next-line var-name-mixedcase\n bytes32 private _PERMIT_TYPEHASH_DEPRECATED_SLOT;\n\n /**\n * @dev Initializes the {EIP712} domain separator using the `name` parameter, and setting `version` to `\"1\"`.\n *\n * It's a good idea to use the same `name` that is defined as the ERC20 token name.\n */\n function __ERC20Permit_init(string memory name) internal onlyInitializing {\n __EIP712_init_unchained(name, \"1\");\n }\n\n function __ERC20Permit_init_unchained(string memory) internal onlyInitializing {}\n\n /**\n * @dev See {IERC20Permit-permit}.\n */\n function permit(\n address owner,\n address spender,\n uint256 value,\n uint256 deadline,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) public virtual override {\n require(block.timestamp <= deadline, \"ERC20Permit: expired deadline\");\n\n bytes32 structHash = keccak256(abi.encode(_PERMIT_TYPEHASH, owner, spender, value, _useNonce(owner), deadline));\n\n bytes32 hash = _hashTypedDataV4(structHash);\n\n address signer = ECDSAUpgradeable.recover(hash, v, r, s);\n require(signer == owner, \"ERC20Permit: invalid signature\");\n\n _approve(owner, spender, value);\n }\n\n /**\n * @dev See {IERC20Permit-nonces}.\n */\n function nonces(address owner) public view virtual override returns (uint256) {\n return _nonces[owner].current();\n }\n\n /**\n * @dev See {IERC20Permit-DOMAIN_SEPARATOR}.\n */\n // solhint-disable-next-line func-name-mixedcase\n function DOMAIN_SEPARATOR() external view override returns (bytes32) {\n return _domainSeparatorV4();\n }\n\n /**\n * @dev \"Consume a nonce\": return the current value and increment.\n *\n * _Available since v4.1._\n */\n function _useNonce(address owner) internal virtual returns (uint256 current) {\n CountersUpgradeable.Counter storage nonce = _nonces[owner];\n current = nonce.current();\n nonce.increment();\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[49] private __gap;\n}\n" + }, + "@openzeppelin/contracts-upgradeable/token/ERC20/extensions/draft-IERC20PermitUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (token/ERC20/extensions/draft-IERC20Permit.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Interface of the ERC20 Permit extension allowing approvals to be made via signatures, as defined in\n * https://eips.ethereum.org/EIPS/eip-2612[EIP-2612].\n *\n * Adds the {permit} method, which can be used to change an account's ERC20 allowance (see {IERC20-allowance}) by\n * presenting a message signed by the account. By not relying on {IERC20-approve}, the token holder account doesn't\n * need to send a transaction, and thus is not required to hold Ether at all.\n */\ninterface IERC20PermitUpgradeable {\n /**\n * @dev Sets `value` as the allowance of `spender` over ``owner``'s tokens,\n * given ``owner``'s signed approval.\n *\n * IMPORTANT: The same issues {IERC20-approve} has related to transaction\n * ordering also apply here.\n *\n * Emits an {Approval} event.\n *\n * Requirements:\n *\n * - `spender` cannot be the zero address.\n * - `deadline` must be a timestamp in the future.\n * - `v`, `r` and `s` must be a valid `secp256k1` signature from `owner`\n * over the EIP712-formatted function arguments.\n * - the signature must use ``owner``'s current nonce (see {nonces}).\n *\n * For more information on the signature format, see the\n * https://eips.ethereum.org/EIPS/eip-2612#specification[relevant EIP\n * section].\n */\n function permit(\n address owner,\n address spender,\n uint256 value,\n uint256 deadline,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) external;\n\n /**\n * @dev Returns the current nonce for `owner`. This value must be\n * included whenever a signature is generated for {permit}.\n *\n * Every successful call to {permit} increases ``owner``'s nonce by one. This\n * prevents a signature from being used multiple times.\n */\n function nonces(address owner) external view returns (uint256);\n\n /**\n * @dev Returns the domain separator used in the encoding of the signature for {permit}, as defined by {EIP712}.\n */\n // solhint-disable-next-line func-name-mixedcase\n function DOMAIN_SEPARATOR() external view returns (bytes32);\n}\n" + }, + "@openzeppelin/contracts-upgradeable/token/ERC20/extensions/IERC20MetadataUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (token/ERC20/extensions/IERC20Metadata.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../IERC20Upgradeable.sol\";\n\n/**\n * @dev Interface for the optional metadata functions from the ERC20 standard.\n *\n * _Available since v4.1._\n */\ninterface IERC20MetadataUpgradeable is IERC20Upgradeable {\n /**\n * @dev Returns the name of the token.\n */\n function name() external view returns (string memory);\n\n /**\n * @dev Returns the symbol of the token.\n */\n function symbol() external view returns (string memory);\n\n /**\n * @dev Returns the decimals places of the token.\n */\n function decimals() external view returns (uint8);\n}\n" + }, + "@openzeppelin/contracts-upgradeable/token/ERC20/IERC20Upgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.6.0) (token/ERC20/IERC20.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Interface of the ERC20 standard as defined in the EIP.\n */\ninterface IERC20Upgradeable {\n /**\n * @dev Emitted when `value` tokens are moved from one account (`from`) to\n * another (`to`).\n *\n * Note that `value` may be zero.\n */\n event Transfer(address indexed from, address indexed to, uint256 value);\n\n /**\n * @dev Emitted when the allowance of a `spender` for an `owner` is set by\n * a call to {approve}. `value` is the new allowance.\n */\n event Approval(address indexed owner, address indexed spender, uint256 value);\n\n /**\n * @dev Returns the amount of tokens in existence.\n */\n function totalSupply() external view returns (uint256);\n\n /**\n * @dev Returns the amount of tokens owned by `account`.\n */\n function balanceOf(address account) external view returns (uint256);\n\n /**\n * @dev Moves `amount` tokens from the caller's account to `to`.\n *\n * Returns a boolean value indicating whether the operation succeeded.\n *\n * Emits a {Transfer} event.\n */\n function transfer(address to, uint256 amount) external returns (bool);\n\n /**\n * @dev Returns the remaining number of tokens that `spender` will be\n * allowed to spend on behalf of `owner` through {transferFrom}. This is\n * zero by default.\n *\n * This value changes when {approve} or {transferFrom} are called.\n */\n function allowance(address owner, address spender) external view returns (uint256);\n\n /**\n * @dev Sets `amount` as the allowance of `spender` over the caller's tokens.\n *\n * Returns a boolean value indicating whether the operation succeeded.\n *\n * IMPORTANT: Beware that changing an allowance with this method brings the risk\n * that someone may use both the old and the new allowance by unfortunate\n * transaction ordering. One possible solution to mitigate this race\n * condition is to first reduce the spender's allowance to 0 and set the\n * desired value afterwards:\n * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729\n *\n * Emits an {Approval} event.\n */\n function approve(address spender, uint256 amount) external returns (bool);\n\n /**\n * @dev Moves `amount` tokens from `from` to `to` using the\n * allowance mechanism. `amount` is then deducted from the caller's\n * allowance.\n *\n * Returns a boolean value indicating whether the operation succeeded.\n *\n * Emits a {Transfer} event.\n */\n function transferFrom(\n address from,\n address to,\n uint256 amount\n ) external returns (bool);\n}\n" + }, + "@openzeppelin/contracts-upgradeable/token/ERC721/extensions/IERC721MetadataUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (token/ERC721/extensions/IERC721Metadata.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../IERC721Upgradeable.sol\";\n\n/**\n * @title ERC-721 Non-Fungible Token Standard, optional metadata extension\n * @dev See https://eips.ethereum.org/EIPS/eip-721\n */\ninterface IERC721MetadataUpgradeable is IERC721Upgradeable {\n /**\n * @dev Returns the token collection name.\n */\n function name() external view returns (string memory);\n\n /**\n * @dev Returns the token collection symbol.\n */\n function symbol() external view returns (string memory);\n\n /**\n * @dev Returns the Uniform Resource Identifier (URI) for `tokenId` token.\n */\n function tokenURI(uint256 tokenId) external view returns (string memory);\n}\n" + }, + "@openzeppelin/contracts-upgradeable/token/ERC721/IERC721ReceiverUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.6.0) (token/ERC721/IERC721Receiver.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @title ERC721 token receiver interface\n * @dev Interface for any contract that wants to support safeTransfers\n * from ERC721 asset contracts.\n */\ninterface IERC721ReceiverUpgradeable {\n /**\n * @dev Whenever an {IERC721} `tokenId` token is transferred to this contract via {IERC721-safeTransferFrom}\n * by `operator` from `from`, this function is called.\n *\n * It must return its Solidity selector to confirm the token transfer.\n * If any other value is returned or the interface is not implemented by the recipient, the transfer will be reverted.\n *\n * The selector can be obtained in Solidity with `IERC721Receiver.onERC721Received.selector`.\n */\n function onERC721Received(\n address operator,\n address from,\n uint256 tokenId,\n bytes calldata data\n ) external returns (bytes4);\n}\n" + }, + "@openzeppelin/contracts-upgradeable/token/ERC721/IERC721Upgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (token/ERC721/IERC721.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../../utils/introspection/IERC165Upgradeable.sol\";\n\n/**\n * @dev Required interface of an ERC721 compliant contract.\n */\ninterface IERC721Upgradeable is IERC165Upgradeable {\n /**\n * @dev Emitted when `tokenId` token is transferred from `from` to `to`.\n */\n event Transfer(address indexed from, address indexed to, uint256 indexed tokenId);\n\n /**\n * @dev Emitted when `owner` enables `approved` to manage the `tokenId` token.\n */\n event Approval(address indexed owner, address indexed approved, uint256 indexed tokenId);\n\n /**\n * @dev Emitted when `owner` enables or disables (`approved`) `operator` to manage all of its assets.\n */\n event ApprovalForAll(address indexed owner, address indexed operator, bool approved);\n\n /**\n * @dev Returns the number of tokens in ``owner``'s account.\n */\n function balanceOf(address owner) external view returns (uint256 balance);\n\n /**\n * @dev Returns the owner of the `tokenId` token.\n *\n * Requirements:\n *\n * - `tokenId` must exist.\n */\n function ownerOf(uint256 tokenId) external view returns (address owner);\n\n /**\n * @dev Safely transfers `tokenId` token from `from` to `to`.\n *\n * Requirements:\n *\n * - `from` cannot be the zero address.\n * - `to` cannot be the zero address.\n * - `tokenId` token must exist and be owned by `from`.\n * - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}.\n * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.\n *\n * Emits a {Transfer} event.\n */\n function safeTransferFrom(\n address from,\n address to,\n uint256 tokenId,\n bytes calldata data\n ) external;\n\n /**\n * @dev Safely transfers `tokenId` token from `from` to `to`, checking first that contract recipients\n * are aware of the ERC721 protocol to prevent tokens from being forever locked.\n *\n * Requirements:\n *\n * - `from` cannot be the zero address.\n * - `to` cannot be the zero address.\n * - `tokenId` token must exist and be owned by `from`.\n * - If the caller is not `from`, it must have been allowed to move this token by either {approve} or {setApprovalForAll}.\n * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.\n *\n * Emits a {Transfer} event.\n */\n function safeTransferFrom(\n address from,\n address to,\n uint256 tokenId\n ) external;\n\n /**\n * @dev Transfers `tokenId` token from `from` to `to`.\n *\n * WARNING: Usage of this method is discouraged, use {safeTransferFrom} whenever possible.\n *\n * Requirements:\n *\n * - `from` cannot be the zero address.\n * - `to` cannot be the zero address.\n * - `tokenId` token must be owned by `from`.\n * - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}.\n *\n * Emits a {Transfer} event.\n */\n function transferFrom(\n address from,\n address to,\n uint256 tokenId\n ) external;\n\n /**\n * @dev Gives permission to `to` to transfer `tokenId` token to another account.\n * The approval is cleared when the token is transferred.\n *\n * Only a single account can be approved at a time, so approving the zero address clears previous approvals.\n *\n * Requirements:\n *\n * - The caller must own the token or be an approved operator.\n * - `tokenId` must exist.\n *\n * Emits an {Approval} event.\n */\n function approve(address to, uint256 tokenId) external;\n\n /**\n * @dev Approve or remove `operator` as an operator for the caller.\n * Operators can call {transferFrom} or {safeTransferFrom} for any token owned by the caller.\n *\n * Requirements:\n *\n * - The `operator` cannot be the caller.\n *\n * Emits an {ApprovalForAll} event.\n */\n function setApprovalForAll(address operator, bool _approved) external;\n\n /**\n * @dev Returns the account approved for `tokenId` token.\n *\n * Requirements:\n *\n * - `tokenId` must exist.\n */\n function getApproved(uint256 tokenId) external view returns (address operator);\n\n /**\n * @dev Returns if the `operator` is allowed to manage all of the assets of `owner`.\n *\n * See {setApprovalForAll}\n */\n function isApprovedForAll(address owner, address operator) external view returns (bool);\n}\n" + }, + "@openzeppelin/contracts-upgradeable/utils/AddressUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (utils/Address.sol)\n\npragma solidity ^0.8.1;\n\n/**\n * @dev Collection of functions related to the address type\n */\nlibrary AddressUpgradeable {\n /**\n * @dev Returns true if `account` is a contract.\n *\n * [IMPORTANT]\n * ====\n * It is unsafe to assume that an address for which this function returns\n * false is an externally-owned account (EOA) and not a contract.\n *\n * Among others, `isContract` will return false for the following\n * types of addresses:\n *\n * - an externally-owned account\n * - a contract in construction\n * - an address where a contract will be created\n * - an address where a contract lived, but was destroyed\n * ====\n *\n * [IMPORTANT]\n * ====\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\n *\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\n * constructor.\n * ====\n */\n function isContract(address account) internal view returns (bool) {\n // This method relies on extcodesize/address.code.length, which returns 0\n // for contracts in construction, since the code is only stored at the end\n // of the constructor execution.\n\n return account.code.length > 0;\n }\n\n /**\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\n * `recipient`, forwarding all available gas and reverting on errors.\n *\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\n * imposed by `transfer`, making them unable to receive funds via\n * `transfer`. {sendValue} removes this limitation.\n *\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\n *\n * IMPORTANT: because control is transferred to `recipient`, care must be\n * taken to not create reentrancy vulnerabilities. Consider using\n * {ReentrancyGuard} or the\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\n */\n function sendValue(address payable recipient, uint256 amount) internal {\n require(address(this).balance >= amount, \"Address: insufficient balance\");\n\n (bool success, ) = recipient.call{value: amount}(\"\");\n require(success, \"Address: unable to send value, recipient may have reverted\");\n }\n\n /**\n * @dev Performs a Solidity function call using a low level `call`. A\n * plain `call` is an unsafe replacement for a function call: use this\n * function instead.\n *\n * If `target` reverts with a revert reason, it is bubbled up by this\n * function (like regular Solidity function calls).\n *\n * Returns the raw returned data. To convert to the expected return value,\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\n *\n * Requirements:\n *\n * - `target` must be a contract.\n * - calling `target` with `data` must not revert.\n *\n * _Available since v3.1._\n */\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionCall(target, data, \"Address: low-level call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\n * `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, 0, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but also transferring `value` wei to `target`.\n *\n * Requirements:\n *\n * - the calling contract must have an ETH balance of at least `value`.\n * - the called Solidity function must be `payable`.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, value, \"Address: low-level call with value failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\n * with `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(address(this).balance >= value, \"Address: insufficient balance for call\");\n require(isContract(target), \"Address: call to non-contract\");\n\n (bool success, bytes memory returndata) = target.call{value: value}(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\n return functionStaticCall(target, data, \"Address: low-level static call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal view returns (bytes memory) {\n require(isContract(target), \"Address: static call to non-contract\");\n\n (bool success, bytes memory returndata) = target.staticcall(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the\n * revert reason using the provided one.\n *\n * _Available since v4.3._\n */\n function verifyCallResult(\n bool success,\n bytes memory returndata,\n string memory errorMessage\n ) internal pure returns (bytes memory) {\n if (success) {\n return returndata;\n } else {\n // Look for revert reason and bubble it up if present\n if (returndata.length > 0) {\n // The easiest way to bubble the revert reason is using memory via assembly\n /// @solidity memory-safe-assembly\n assembly {\n let returndata_size := mload(returndata)\n revert(add(32, returndata), returndata_size)\n }\n } else {\n revert(errorMessage);\n }\n }\n }\n}\n" + }, + "@openzeppelin/contracts-upgradeable/utils/ContextUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)\n\npragma solidity ^0.8.0;\nimport \"../proxy/utils/Initializable.sol\";\n\n/**\n * @dev Provides information about the current execution context, including the\n * sender of the transaction and its data. While these are generally available\n * via msg.sender and msg.data, they should not be accessed in such a direct\n * manner, since when dealing with meta-transactions the account sending and\n * paying for execution may not be the actual sender (as far as an application\n * is concerned).\n *\n * This contract is only required for intermediate, library-like contracts.\n */\nabstract contract ContextUpgradeable is Initializable {\n function __Context_init() internal onlyInitializing {\n }\n\n function __Context_init_unchained() internal onlyInitializing {\n }\n function _msgSender() internal view virtual returns (address) {\n return msg.sender;\n }\n\n function _msgData() internal view virtual returns (bytes calldata) {\n return msg.data;\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[50] private __gap;\n}\n" + }, + "@openzeppelin/contracts-upgradeable/utils/CountersUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (utils/Counters.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @title Counters\n * @author Matt Condon (@shrugs)\n * @dev Provides counters that can only be incremented, decremented or reset. This can be used e.g. to track the number\n * of elements in a mapping, issuing ERC721 ids, or counting request ids.\n *\n * Include with `using Counters for Counters.Counter;`\n */\nlibrary CountersUpgradeable {\n struct Counter {\n // This variable should never be directly accessed by users of the library: interactions must be restricted to\n // the library's function. As of Solidity v0.5.2, this cannot be enforced, though there is a proposal to add\n // this feature: see https://github.com/ethereum/solidity/issues/4637\n uint256 _value; // default: 0\n }\n\n function current(Counter storage counter) internal view returns (uint256) {\n return counter._value;\n }\n\n function increment(Counter storage counter) internal {\n unchecked {\n counter._value += 1;\n }\n }\n\n function decrement(Counter storage counter) internal {\n uint256 value = counter._value;\n require(value > 0, \"Counter: decrement overflow\");\n unchecked {\n counter._value = value - 1;\n }\n }\n\n function reset(Counter storage counter) internal {\n counter._value = 0;\n }\n}\n" + }, + "@openzeppelin/contracts-upgradeable/utils/cryptography/draft-EIP712Upgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (utils/cryptography/draft-EIP712.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./ECDSAUpgradeable.sol\";\nimport \"../../proxy/utils/Initializable.sol\";\n\n/**\n * @dev https://eips.ethereum.org/EIPS/eip-712[EIP 712] is a standard for hashing and signing of typed structured data.\n *\n * The encoding specified in the EIP is very generic, and such a generic implementation in Solidity is not feasible,\n * thus this contract does not implement the encoding itself. Protocols need to implement the type-specific encoding\n * they need in their contracts using a combination of `abi.encode` and `keccak256`.\n *\n * This contract implements the EIP 712 domain separator ({_domainSeparatorV4}) that is used as part of the encoding\n * scheme, and the final step of the encoding to obtain the message digest that is then signed via ECDSA\n * ({_hashTypedDataV4}).\n *\n * The implementation of the domain separator was designed to be as efficient as possible while still properly updating\n * the chain id to protect against replay attacks on an eventual fork of the chain.\n *\n * NOTE: This contract implements the version of the encoding known as \"v4\", as implemented by the JSON RPC method\n * https://docs.metamask.io/guide/signing-data.html[`eth_signTypedDataV4` in MetaMask].\n *\n * _Available since v3.4._\n *\n * @custom:storage-size 52\n */\nabstract contract EIP712Upgradeable is Initializable {\n /* solhint-disable var-name-mixedcase */\n bytes32 private _HASHED_NAME;\n bytes32 private _HASHED_VERSION;\n bytes32 private constant _TYPE_HASH = keccak256(\"EIP712Domain(string name,string version,uint256 chainId,address verifyingContract)\");\n\n /* solhint-enable var-name-mixedcase */\n\n /**\n * @dev Initializes the domain separator and parameter caches.\n *\n * The meaning of `name` and `version` is specified in\n * https://eips.ethereum.org/EIPS/eip-712#definition-of-domainseparator[EIP 712]:\n *\n * - `name`: the user readable name of the signing domain, i.e. the name of the DApp or the protocol.\n * - `version`: the current major version of the signing domain.\n *\n * NOTE: These parameters cannot be changed except through a xref:learn::upgrading-smart-contracts.adoc[smart\n * contract upgrade].\n */\n function __EIP712_init(string memory name, string memory version) internal onlyInitializing {\n __EIP712_init_unchained(name, version);\n }\n\n function __EIP712_init_unchained(string memory name, string memory version) internal onlyInitializing {\n bytes32 hashedName = keccak256(bytes(name));\n bytes32 hashedVersion = keccak256(bytes(version));\n _HASHED_NAME = hashedName;\n _HASHED_VERSION = hashedVersion;\n }\n\n /**\n * @dev Returns the domain separator for the current chain.\n */\n function _domainSeparatorV4() internal view returns (bytes32) {\n return _buildDomainSeparator(_TYPE_HASH, _EIP712NameHash(), _EIP712VersionHash());\n }\n\n function _buildDomainSeparator(\n bytes32 typeHash,\n bytes32 nameHash,\n bytes32 versionHash\n ) private view returns (bytes32) {\n return keccak256(abi.encode(typeHash, nameHash, versionHash, block.chainid, address(this)));\n }\n\n /**\n * @dev Given an already https://eips.ethereum.org/EIPS/eip-712#definition-of-hashstruct[hashed struct], this\n * function returns the hash of the fully encoded EIP712 message for this domain.\n *\n * This hash can be used together with {ECDSA-recover} to obtain the signer of a message. For example:\n *\n * ```solidity\n * bytes32 digest = _hashTypedDataV4(keccak256(abi.encode(\n * keccak256(\"Mail(address to,string contents)\"),\n * mailTo,\n * keccak256(bytes(mailContents))\n * )));\n * address signer = ECDSA.recover(digest, signature);\n * ```\n */\n function _hashTypedDataV4(bytes32 structHash) internal view virtual returns (bytes32) {\n return ECDSAUpgradeable.toTypedDataHash(_domainSeparatorV4(), structHash);\n }\n\n /**\n * @dev The hash of the name parameter for the EIP712 domain.\n *\n * NOTE: This function reads from storage by default, but can be redefined to return a constant value if gas costs\n * are a concern.\n */\n function _EIP712NameHash() internal virtual view returns (bytes32) {\n return _HASHED_NAME;\n }\n\n /**\n * @dev The hash of the version parameter for the EIP712 domain.\n *\n * NOTE: This function reads from storage by default, but can be redefined to return a constant value if gas costs\n * are a concern.\n */\n function _EIP712VersionHash() internal virtual view returns (bytes32) {\n return _HASHED_VERSION;\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[50] private __gap;\n}\n" + }, + "@openzeppelin/contracts-upgradeable/utils/cryptography/ECDSAUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (utils/cryptography/ECDSA.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../StringsUpgradeable.sol\";\n\n/**\n * @dev Elliptic Curve Digital Signature Algorithm (ECDSA) operations.\n *\n * These functions can be used to verify that a message was signed by the holder\n * of the private keys of a given address.\n */\nlibrary ECDSAUpgradeable {\n enum RecoverError {\n NoError,\n InvalidSignature,\n InvalidSignatureLength,\n InvalidSignatureS,\n InvalidSignatureV\n }\n\n function _throwError(RecoverError error) private pure {\n if (error == RecoverError.NoError) {\n return; // no error: do nothing\n } else if (error == RecoverError.InvalidSignature) {\n revert(\"ECDSA: invalid signature\");\n } else if (error == RecoverError.InvalidSignatureLength) {\n revert(\"ECDSA: invalid signature length\");\n } else if (error == RecoverError.InvalidSignatureS) {\n revert(\"ECDSA: invalid signature 's' value\");\n } else if (error == RecoverError.InvalidSignatureV) {\n revert(\"ECDSA: invalid signature 'v' value\");\n }\n }\n\n /**\n * @dev Returns the address that signed a hashed message (`hash`) with\n * `signature` or error string. This address can then be used for verification purposes.\n *\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\n * this function rejects them by requiring the `s` value to be in the lower\n * half order, and the `v` value to be either 27 or 28.\n *\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\n * verification to be secure: it is possible to craft signatures that\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\n * this is by receiving a hash of the original message (which may otherwise\n * be too long), and then calling {toEthSignedMessageHash} on it.\n *\n * Documentation for signature generation:\n * - with https://web3js.readthedocs.io/en/v1.3.4/web3-eth-accounts.html#sign[Web3.js]\n * - with https://docs.ethers.io/v5/api/signer/#Signer-signMessage[ethers]\n *\n * _Available since v4.3._\n */\n function tryRecover(bytes32 hash, bytes memory signature) internal pure returns (address, RecoverError) {\n // Check the signature length\n // - case 65: r,s,v signature (standard)\n // - case 64: r,vs signature (cf https://eips.ethereum.org/EIPS/eip-2098) _Available since v4.1._\n if (signature.length == 65) {\n bytes32 r;\n bytes32 s;\n uint8 v;\n // ecrecover takes the signature parameters, and the only way to get them\n // currently is to use assembly.\n /// @solidity memory-safe-assembly\n assembly {\n r := mload(add(signature, 0x20))\n s := mload(add(signature, 0x40))\n v := byte(0, mload(add(signature, 0x60)))\n }\n return tryRecover(hash, v, r, s);\n } else if (signature.length == 64) {\n bytes32 r;\n bytes32 vs;\n // ecrecover takes the signature parameters, and the only way to get them\n // currently is to use assembly.\n /// @solidity memory-safe-assembly\n assembly {\n r := mload(add(signature, 0x20))\n vs := mload(add(signature, 0x40))\n }\n return tryRecover(hash, r, vs);\n } else {\n return (address(0), RecoverError.InvalidSignatureLength);\n }\n }\n\n /**\n * @dev Returns the address that signed a hashed message (`hash`) with\n * `signature`. This address can then be used for verification purposes.\n *\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\n * this function rejects them by requiring the `s` value to be in the lower\n * half order, and the `v` value to be either 27 or 28.\n *\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\n * verification to be secure: it is possible to craft signatures that\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\n * this is by receiving a hash of the original message (which may otherwise\n * be too long), and then calling {toEthSignedMessageHash} on it.\n */\n function recover(bytes32 hash, bytes memory signature) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, signature);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Overload of {ECDSA-tryRecover} that receives the `r` and `vs` short-signature fields separately.\n *\n * See https://eips.ethereum.org/EIPS/eip-2098[EIP-2098 short signatures]\n *\n * _Available since v4.3._\n */\n function tryRecover(\n bytes32 hash,\n bytes32 r,\n bytes32 vs\n ) internal pure returns (address, RecoverError) {\n bytes32 s = vs & bytes32(0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff);\n uint8 v = uint8((uint256(vs) >> 255) + 27);\n return tryRecover(hash, v, r, s);\n }\n\n /**\n * @dev Overload of {ECDSA-recover} that receives the `r and `vs` short-signature fields separately.\n *\n * _Available since v4.2._\n */\n function recover(\n bytes32 hash,\n bytes32 r,\n bytes32 vs\n ) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, r, vs);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Overload of {ECDSA-tryRecover} that receives the `v`,\n * `r` and `s` signature fields separately.\n *\n * _Available since v4.3._\n */\n function tryRecover(\n bytes32 hash,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) internal pure returns (address, RecoverError) {\n // EIP-2 still allows signature malleability for ecrecover(). Remove this possibility and make the signature\n // unique. Appendix F in the Ethereum Yellow paper (https://ethereum.github.io/yellowpaper/paper.pdf), defines\n // the valid range for s in (301): 0 < s < secp256k1n ÷ 2 + 1, and for v in (302): v ∈ {27, 28}. Most\n // signatures from current libraries generate a unique signature with an s-value in the lower half order.\n //\n // If your library generates malleable signatures, such as s-values in the upper range, calculate a new s-value\n // with 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141 - s1 and flip v from 27 to 28 or\n // vice versa. If your library also generates signatures with 0/1 for v instead 27/28, add 27 to v to accept\n // these malleable signatures as well.\n if (uint256(s) > 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D576E7357A4501DDFE92F46681B20A0) {\n return (address(0), RecoverError.InvalidSignatureS);\n }\n if (v != 27 && v != 28) {\n return (address(0), RecoverError.InvalidSignatureV);\n }\n\n // If the signature is valid (and not malleable), return the signer address\n address signer = ecrecover(hash, v, r, s);\n if (signer == address(0)) {\n return (address(0), RecoverError.InvalidSignature);\n }\n\n return (signer, RecoverError.NoError);\n }\n\n /**\n * @dev Overload of {ECDSA-recover} that receives the `v`,\n * `r` and `s` signature fields separately.\n */\n function recover(\n bytes32 hash,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, v, r, s);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Returns an Ethereum Signed Message, created from a `hash`. This\n * produces hash corresponding to the one signed with the\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\n * JSON-RPC method as part of EIP-191.\n *\n * See {recover}.\n */\n function toEthSignedMessageHash(bytes32 hash) internal pure returns (bytes32) {\n // 32 is the length in bytes of hash,\n // enforced by the type signature above\n return keccak256(abi.encodePacked(\"\\x19Ethereum Signed Message:\\n32\", hash));\n }\n\n /**\n * @dev Returns an Ethereum Signed Message, created from `s`. This\n * produces hash corresponding to the one signed with the\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\n * JSON-RPC method as part of EIP-191.\n *\n * See {recover}.\n */\n function toEthSignedMessageHash(bytes memory s) internal pure returns (bytes32) {\n return keccak256(abi.encodePacked(\"\\x19Ethereum Signed Message:\\n\", StringsUpgradeable.toString(s.length), s));\n }\n\n /**\n * @dev Returns an Ethereum Signed Typed Data, created from a\n * `domainSeparator` and a `structHash`. This produces hash corresponding\n * to the one signed with the\n * https://eips.ethereum.org/EIPS/eip-712[`eth_signTypedData`]\n * JSON-RPC method as part of EIP-712.\n *\n * See {recover}.\n */\n function toTypedDataHash(bytes32 domainSeparator, bytes32 structHash) internal pure returns (bytes32) {\n return keccak256(abi.encodePacked(\"\\x19\\x01\", domainSeparator, structHash));\n }\n}\n" + }, + "@openzeppelin/contracts-upgradeable/utils/introspection/ERC165Upgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (utils/introspection/ERC165.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./IERC165Upgradeable.sol\";\nimport \"../../proxy/utils/Initializable.sol\";\n\n/**\n * @dev Implementation of the {IERC165} interface.\n *\n * Contracts that want to implement ERC165 should inherit from this contract and override {supportsInterface} to check\n * for the additional interface id that will be supported. For example:\n *\n * ```solidity\n * function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {\n * return interfaceId == type(MyInterface).interfaceId || super.supportsInterface(interfaceId);\n * }\n * ```\n *\n * Alternatively, {ERC165Storage} provides an easier to use but more expensive implementation.\n */\nabstract contract ERC165Upgradeable is Initializable, IERC165Upgradeable {\n function __ERC165_init() internal onlyInitializing {\n }\n\n function __ERC165_init_unchained() internal onlyInitializing {\n }\n /**\n * @dev See {IERC165-supportsInterface}.\n */\n function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {\n return interfaceId == type(IERC165Upgradeable).interfaceId;\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[50] private __gap;\n}\n" + }, + "@openzeppelin/contracts-upgradeable/utils/introspection/IERC165Upgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (utils/introspection/IERC165.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Interface of the ERC165 standard, as defined in the\n * https://eips.ethereum.org/EIPS/eip-165[EIP].\n *\n * Implementers can declare support of contract interfaces, which can then be\n * queried by others ({ERC165Checker}).\n *\n * For an implementation, see {ERC165}.\n */\ninterface IERC165Upgradeable {\n /**\n * @dev Returns true if this contract implements the interface defined by\n * `interfaceId`. See the corresponding\n * https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified[EIP section]\n * to learn more about how these ids are created.\n *\n * This function call must use less than 30 000 gas.\n */\n function supportsInterface(bytes4 interfaceId) external view returns (bool);\n}\n" + }, + "@openzeppelin/contracts-upgradeable/utils/StringsUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (utils/Strings.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev String operations.\n */\nlibrary StringsUpgradeable {\n bytes16 private constant _HEX_SYMBOLS = \"0123456789abcdef\";\n uint8 private constant _ADDRESS_LENGTH = 20;\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` decimal representation.\n */\n function toString(uint256 value) internal pure returns (string memory) {\n // Inspired by OraclizeAPI's implementation - MIT licence\n // https://github.com/oraclize/ethereum-api/blob/b42146b063c7d6ee1358846c198246239e9360e8/oraclizeAPI_0.4.25.sol\n\n if (value == 0) {\n return \"0\";\n }\n uint256 temp = value;\n uint256 digits;\n while (temp != 0) {\n digits++;\n temp /= 10;\n }\n bytes memory buffer = new bytes(digits);\n while (value != 0) {\n digits -= 1;\n buffer[digits] = bytes1(uint8(48 + uint256(value % 10)));\n value /= 10;\n }\n return string(buffer);\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation.\n */\n function toHexString(uint256 value) internal pure returns (string memory) {\n if (value == 0) {\n return \"0x00\";\n }\n uint256 temp = value;\n uint256 length = 0;\n while (temp != 0) {\n length++;\n temp >>= 8;\n }\n return toHexString(value, length);\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length.\n */\n function toHexString(uint256 value, uint256 length) internal pure returns (string memory) {\n bytes memory buffer = new bytes(2 * length + 2);\n buffer[0] = \"0\";\n buffer[1] = \"x\";\n for (uint256 i = 2 * length + 1; i > 1; --i) {\n buffer[i] = _HEX_SYMBOLS[value & 0xf];\n value >>= 4;\n }\n require(value == 0, \"Strings: hex length insufficient\");\n return string(buffer);\n }\n\n /**\n * @dev Converts an `address` with fixed length of 20 bytes to its not checksummed ASCII `string` hexadecimal representation.\n */\n function toHexString(address addr) internal pure returns (string memory) {\n return toHexString(uint256(uint160(addr)), _ADDRESS_LENGTH);\n }\n}\n" + }, + "@openzeppelin/contracts-upgradeable/utils/structs/EnumerableSetUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (utils/structs/EnumerableSet.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Library for managing\n * https://en.wikipedia.org/wiki/Set_(abstract_data_type)[sets] of primitive\n * types.\n *\n * Sets have the following properties:\n *\n * - Elements are added, removed, and checked for existence in constant time\n * (O(1)).\n * - Elements are enumerated in O(n). No guarantees are made on the ordering.\n *\n * ```\n * contract Example {\n * // Add the library methods\n * using EnumerableSet for EnumerableSet.AddressSet;\n *\n * // Declare a set state variable\n * EnumerableSet.AddressSet private mySet;\n * }\n * ```\n *\n * As of v3.3.0, sets of type `bytes32` (`Bytes32Set`), `address` (`AddressSet`)\n * and `uint256` (`UintSet`) are supported.\n *\n * [WARNING]\n * ====\n * Trying to delete such a structure from storage will likely result in data corruption, rendering the structure unusable.\n * See https://github.com/ethereum/solidity/pull/11843[ethereum/solidity#11843] for more info.\n *\n * In order to clean an EnumerableSet, you can either remove all elements one by one or create a fresh instance using an array of EnumerableSet.\n * ====\n */\nlibrary EnumerableSetUpgradeable {\n // To implement this library for multiple types with as little code\n // repetition as possible, we write it in terms of a generic Set type with\n // bytes32 values.\n // The Set implementation uses private functions, and user-facing\n // implementations (such as AddressSet) are just wrappers around the\n // underlying Set.\n // This means that we can only create new EnumerableSets for types that fit\n // in bytes32.\n\n struct Set {\n // Storage of set values\n bytes32[] _values;\n // Position of the value in the `values` array, plus 1 because index 0\n // means a value is not in the set.\n mapping(bytes32 => uint256) _indexes;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function _add(Set storage set, bytes32 value) private returns (bool) {\n if (!_contains(set, value)) {\n set._values.push(value);\n // The value is stored at length-1, but we add 1 to all indexes\n // and use 0 as a sentinel value\n set._indexes[value] = set._values.length;\n return true;\n } else {\n return false;\n }\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function _remove(Set storage set, bytes32 value) private returns (bool) {\n // We read and store the value's index to prevent multiple reads from the same storage slot\n uint256 valueIndex = set._indexes[value];\n\n if (valueIndex != 0) {\n // Equivalent to contains(set, value)\n // To delete an element from the _values array in O(1), we swap the element to delete with the last one in\n // the array, and then remove the last element (sometimes called as 'swap and pop').\n // This modifies the order of the array, as noted in {at}.\n\n uint256 toDeleteIndex = valueIndex - 1;\n uint256 lastIndex = set._values.length - 1;\n\n if (lastIndex != toDeleteIndex) {\n bytes32 lastValue = set._values[lastIndex];\n\n // Move the last value to the index where the value to delete is\n set._values[toDeleteIndex] = lastValue;\n // Update the index for the moved value\n set._indexes[lastValue] = valueIndex; // Replace lastValue's index to valueIndex\n }\n\n // Delete the slot where the moved value was stored\n set._values.pop();\n\n // Delete the index for the deleted slot\n delete set._indexes[value];\n\n return true;\n } else {\n return false;\n }\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function _contains(Set storage set, bytes32 value) private view returns (bool) {\n return set._indexes[value] != 0;\n }\n\n /**\n * @dev Returns the number of values on the set. O(1).\n */\n function _length(Set storage set) private view returns (uint256) {\n return set._values.length;\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function _at(Set storage set, uint256 index) private view returns (bytes32) {\n return set._values[index];\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function _values(Set storage set) private view returns (bytes32[] memory) {\n return set._values;\n }\n\n // Bytes32Set\n\n struct Bytes32Set {\n Set _inner;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function add(Bytes32Set storage set, bytes32 value) internal returns (bool) {\n return _add(set._inner, value);\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function remove(Bytes32Set storage set, bytes32 value) internal returns (bool) {\n return _remove(set._inner, value);\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function contains(Bytes32Set storage set, bytes32 value) internal view returns (bool) {\n return _contains(set._inner, value);\n }\n\n /**\n * @dev Returns the number of values in the set. O(1).\n */\n function length(Bytes32Set storage set) internal view returns (uint256) {\n return _length(set._inner);\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function at(Bytes32Set storage set, uint256 index) internal view returns (bytes32) {\n return _at(set._inner, index);\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function values(Bytes32Set storage set) internal view returns (bytes32[] memory) {\n return _values(set._inner);\n }\n\n // AddressSet\n\n struct AddressSet {\n Set _inner;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function add(AddressSet storage set, address value) internal returns (bool) {\n return _add(set._inner, bytes32(uint256(uint160(value))));\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function remove(AddressSet storage set, address value) internal returns (bool) {\n return _remove(set._inner, bytes32(uint256(uint160(value))));\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function contains(AddressSet storage set, address value) internal view returns (bool) {\n return _contains(set._inner, bytes32(uint256(uint160(value))));\n }\n\n /**\n * @dev Returns the number of values in the set. O(1).\n */\n function length(AddressSet storage set) internal view returns (uint256) {\n return _length(set._inner);\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function at(AddressSet storage set, uint256 index) internal view returns (address) {\n return address(uint160(uint256(_at(set._inner, index))));\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function values(AddressSet storage set) internal view returns (address[] memory) {\n bytes32[] memory store = _values(set._inner);\n address[] memory result;\n\n /// @solidity memory-safe-assembly\n assembly {\n result := store\n }\n\n return result;\n }\n\n // UintSet\n\n struct UintSet {\n Set _inner;\n }\n\n /**\n * @dev Add a value to a set. O(1).\n *\n * Returns true if the value was added to the set, that is if it was not\n * already present.\n */\n function add(UintSet storage set, uint256 value) internal returns (bool) {\n return _add(set._inner, bytes32(value));\n }\n\n /**\n * @dev Removes a value from a set. O(1).\n *\n * Returns true if the value was removed from the set, that is if it was\n * present.\n */\n function remove(UintSet storage set, uint256 value) internal returns (bool) {\n return _remove(set._inner, bytes32(value));\n }\n\n /**\n * @dev Returns true if the value is in the set. O(1).\n */\n function contains(UintSet storage set, uint256 value) internal view returns (bool) {\n return _contains(set._inner, bytes32(value));\n }\n\n /**\n * @dev Returns the number of values on the set. O(1).\n */\n function length(UintSet storage set) internal view returns (uint256) {\n return _length(set._inner);\n }\n\n /**\n * @dev Returns the value stored at position `index` in the set. O(1).\n *\n * Note that there are no guarantees on the ordering of values inside the\n * array, and it may change when more values are added or removed.\n *\n * Requirements:\n *\n * - `index` must be strictly less than {length}.\n */\n function at(UintSet storage set, uint256 index) internal view returns (uint256) {\n return uint256(_at(set._inner, index));\n }\n\n /**\n * @dev Return the entire set in an array\n *\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n */\n function values(UintSet storage set) internal view returns (uint256[] memory) {\n bytes32[] memory store = _values(set._inner);\n uint256[] memory result;\n\n /// @solidity memory-safe-assembly\n assembly {\n result := store\n }\n\n return result;\n }\n}\n" + }, + "@openzeppelin/contracts/access/Ownable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (access/Ownable.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../utils/Context.sol\";\n\n/**\n * @dev Contract module which provides a basic access control mechanism, where\n * there is an account (an owner) that can be granted exclusive access to\n * specific functions.\n *\n * By default, the owner account will be the one that deploys the contract. This\n * can later be changed with {transferOwnership}.\n *\n * This module is used through inheritance. It will make available the modifier\n * `onlyOwner`, which can be applied to your functions to restrict their use to\n * the owner.\n */\nabstract contract Ownable is Context {\n address private _owner;\n\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\n\n /**\n * @dev Initializes the contract setting the deployer as the initial owner.\n */\n constructor() {\n _transferOwnership(_msgSender());\n }\n\n /**\n * @dev Throws if called by any account other than the owner.\n */\n modifier onlyOwner() {\n _checkOwner();\n _;\n }\n\n /**\n * @dev Returns the address of the current owner.\n */\n function owner() public view virtual returns (address) {\n return _owner;\n }\n\n /**\n * @dev Throws if the sender is not the owner.\n */\n function _checkOwner() internal view virtual {\n require(owner() == _msgSender(), \"Ownable: caller is not the owner\");\n }\n\n /**\n * @dev Leaves the contract without owner. It will not be possible to call\n * `onlyOwner` functions anymore. Can only be called by the current owner.\n *\n * NOTE: Renouncing ownership will leave the contract without an owner,\n * thereby removing any functionality that is only available to the owner.\n */\n function renounceOwnership() public virtual onlyOwner {\n _transferOwnership(address(0));\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Can only be called by the current owner.\n */\n function transferOwnership(address newOwner) public virtual onlyOwner {\n require(newOwner != address(0), \"Ownable: new owner is the zero address\");\n _transferOwnership(newOwner);\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Internal function without access restriction.\n */\n function _transferOwnership(address newOwner) internal virtual {\n address oldOwner = _owner;\n _owner = newOwner;\n emit OwnershipTransferred(oldOwner, newOwner);\n }\n}\n" + }, + "@openzeppelin/contracts/interfaces/draft-IERC1822.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.5.0) (interfaces/draft-IERC1822.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev ERC1822: Universal Upgradeable Proxy Standard (UUPS) documents a method for upgradeability through a simplified\n * proxy whose upgrades are fully controlled by the current implementation.\n */\ninterface IERC1822Proxiable {\n /**\n * @dev Returns the storage slot that the proxiable contract assumes is being used to store the implementation\n * address.\n *\n * IMPORTANT: A proxy pointing at a proxiable contract should not be considered proxiable itself, because this risks\n * bricking a proxy that upgrades to it, by delegating to itself until out of gas. Thus it is critical that this\n * function revert if invoked through a proxy.\n */\n function proxiableUUID() external view returns (bytes32);\n}\n" + }, + "@openzeppelin/contracts/interfaces/IERC3156FlashBorrower.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (interfaces/IERC3156FlashBorrower.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Interface of the ERC3156 FlashBorrower, as defined in\n * https://eips.ethereum.org/EIPS/eip-3156[ERC-3156].\n *\n * _Available since v4.1._\n */\ninterface IERC3156FlashBorrower {\n /**\n * @dev Receive a flash loan.\n * @param initiator The initiator of the loan.\n * @param token The loan currency.\n * @param amount The amount of tokens lent.\n * @param fee The additional amount of tokens to repay.\n * @param data Arbitrary data structure, intended to contain user-defined parameters.\n * @return The keccak256 hash of \"IERC3156FlashBorrower.onFlashLoan\"\n */\n function onFlashLoan(\n address initiator,\n address token,\n uint256 amount,\n uint256 fee,\n bytes calldata data\n ) external returns (bytes32);\n}\n" + }, + "@openzeppelin/contracts/interfaces/IERC3156FlashLender.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (interfaces/IERC3156FlashLender.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./IERC3156FlashBorrower.sol\";\n\n/**\n * @dev Interface of the ERC3156 FlashLender, as defined in\n * https://eips.ethereum.org/EIPS/eip-3156[ERC-3156].\n *\n * _Available since v4.1._\n */\ninterface IERC3156FlashLender {\n /**\n * @dev The amount of currency available to be lended.\n * @param token The loan currency.\n * @return The amount of `token` that can be borrowed.\n */\n function maxFlashLoan(address token) external view returns (uint256);\n\n /**\n * @dev The fee to be charged for a given loan.\n * @param token The loan currency.\n * @param amount The amount of tokens lent.\n * @return The amount of `token` to be charged for the loan, on top of the returned principal.\n */\n function flashFee(address token, uint256 amount) external view returns (uint256);\n\n /**\n * @dev Initiate a flash loan.\n * @param receiver The receiver of the tokens in the loan, and the receiver of the callback.\n * @param token The loan currency.\n * @param amount The amount of tokens lent.\n * @param data Arbitrary data structure, intended to contain user-defined parameters.\n */\n function flashLoan(\n IERC3156FlashBorrower receiver,\n address token,\n uint256 amount,\n bytes calldata data\n ) external returns (bool);\n}\n" + }, + "@openzeppelin/contracts/interfaces/IERC721Metadata.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (interfaces/IERC721Metadata.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../token/ERC721/extensions/IERC721Metadata.sol\";\n" + }, + "@openzeppelin/contracts/proxy/beacon/IBeacon.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (proxy/beacon/IBeacon.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev This is the interface that {BeaconProxy} expects of its beacon.\n */\ninterface IBeacon {\n /**\n * @dev Must return an address that can be used as a delegate call target.\n *\n * {BeaconProxy} will check that this address is a contract.\n */\n function implementation() external view returns (address);\n}\n" + }, + "@openzeppelin/contracts/proxy/ERC1967/ERC1967Proxy.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (proxy/ERC1967/ERC1967Proxy.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../Proxy.sol\";\nimport \"./ERC1967Upgrade.sol\";\n\n/**\n * @dev This contract implements an upgradeable proxy. It is upgradeable because calls are delegated to an\n * implementation address that can be changed. This address is stored in storage in the location specified by\n * https://eips.ethereum.org/EIPS/eip-1967[EIP1967], so that it doesn't conflict with the storage layout of the\n * implementation behind the proxy.\n */\ncontract ERC1967Proxy is Proxy, ERC1967Upgrade {\n /**\n * @dev Initializes the upgradeable proxy with an initial implementation specified by `_logic`.\n *\n * If `_data` is nonempty, it's used as data in a delegate call to `_logic`. This will typically be an encoded\n * function call, and allows initializing the storage of the proxy like a Solidity constructor.\n */\n constructor(address _logic, bytes memory _data) payable {\n _upgradeToAndCall(_logic, _data, false);\n }\n\n /**\n * @dev Returns the current implementation address.\n */\n function _implementation() internal view virtual override returns (address impl) {\n return ERC1967Upgrade._getImplementation();\n }\n}\n" + }, + "@openzeppelin/contracts/proxy/ERC1967/ERC1967Upgrade.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.5.0) (proxy/ERC1967/ERC1967Upgrade.sol)\n\npragma solidity ^0.8.2;\n\nimport \"../beacon/IBeacon.sol\";\nimport \"../../interfaces/draft-IERC1822.sol\";\nimport \"../../utils/Address.sol\";\nimport \"../../utils/StorageSlot.sol\";\n\n/**\n * @dev This abstract contract provides getters and event emitting update functions for\n * https://eips.ethereum.org/EIPS/eip-1967[EIP1967] slots.\n *\n * _Available since v4.1._\n *\n * @custom:oz-upgrades-unsafe-allow delegatecall\n */\nabstract contract ERC1967Upgrade {\n // This is the keccak-256 hash of \"eip1967.proxy.rollback\" subtracted by 1\n bytes32 private constant _ROLLBACK_SLOT = 0x4910fdfa16fed3260ed0e7147f7cc6da11a60208b5b9406d12a635614ffd9143;\n\n /**\n * @dev Storage slot with the address of the current implementation.\n * This is the keccak-256 hash of \"eip1967.proxy.implementation\" subtracted by 1, and is\n * validated in the constructor.\n */\n bytes32 internal constant _IMPLEMENTATION_SLOT = 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc;\n\n /**\n * @dev Emitted when the implementation is upgraded.\n */\n event Upgraded(address indexed implementation);\n\n /**\n * @dev Returns the current implementation address.\n */\n function _getImplementation() internal view returns (address) {\n return StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value;\n }\n\n /**\n * @dev Stores a new address in the EIP1967 implementation slot.\n */\n function _setImplementation(address newImplementation) private {\n require(Address.isContract(newImplementation), \"ERC1967: new implementation is not a contract\");\n StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value = newImplementation;\n }\n\n /**\n * @dev Perform implementation upgrade\n *\n * Emits an {Upgraded} event.\n */\n function _upgradeTo(address newImplementation) internal {\n _setImplementation(newImplementation);\n emit Upgraded(newImplementation);\n }\n\n /**\n * @dev Perform implementation upgrade with additional setup call.\n *\n * Emits an {Upgraded} event.\n */\n function _upgradeToAndCall(\n address newImplementation,\n bytes memory data,\n bool forceCall\n ) internal {\n _upgradeTo(newImplementation);\n if (data.length > 0 || forceCall) {\n Address.functionDelegateCall(newImplementation, data);\n }\n }\n\n /**\n * @dev Perform implementation upgrade with security checks for UUPS proxies, and additional setup call.\n *\n * Emits an {Upgraded} event.\n */\n function _upgradeToAndCallUUPS(\n address newImplementation,\n bytes memory data,\n bool forceCall\n ) internal {\n // Upgrades from old implementations will perform a rollback test. This test requires the new\n // implementation to upgrade back to the old, non-ERC1822 compliant, implementation. Removing\n // this special case will break upgrade paths from old UUPS implementation to new ones.\n if (StorageSlot.getBooleanSlot(_ROLLBACK_SLOT).value) {\n _setImplementation(newImplementation);\n } else {\n try IERC1822Proxiable(newImplementation).proxiableUUID() returns (bytes32 slot) {\n require(slot == _IMPLEMENTATION_SLOT, \"ERC1967Upgrade: unsupported proxiableUUID\");\n } catch {\n revert(\"ERC1967Upgrade: new implementation is not UUPS\");\n }\n _upgradeToAndCall(newImplementation, data, forceCall);\n }\n }\n\n /**\n * @dev Storage slot with the admin of the contract.\n * This is the keccak-256 hash of \"eip1967.proxy.admin\" subtracted by 1, and is\n * validated in the constructor.\n */\n bytes32 internal constant _ADMIN_SLOT = 0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103;\n\n /**\n * @dev Emitted when the admin account has changed.\n */\n event AdminChanged(address previousAdmin, address newAdmin);\n\n /**\n * @dev Returns the current admin.\n */\n function _getAdmin() internal view returns (address) {\n return StorageSlot.getAddressSlot(_ADMIN_SLOT).value;\n }\n\n /**\n * @dev Stores a new address in the EIP1967 admin slot.\n */\n function _setAdmin(address newAdmin) private {\n require(newAdmin != address(0), \"ERC1967: new admin is the zero address\");\n StorageSlot.getAddressSlot(_ADMIN_SLOT).value = newAdmin;\n }\n\n /**\n * @dev Changes the admin of the proxy.\n *\n * Emits an {AdminChanged} event.\n */\n function _changeAdmin(address newAdmin) internal {\n emit AdminChanged(_getAdmin(), newAdmin);\n _setAdmin(newAdmin);\n }\n\n /**\n * @dev The storage slot of the UpgradeableBeacon contract which defines the implementation for this proxy.\n * This is bytes32(uint256(keccak256('eip1967.proxy.beacon')) - 1)) and is validated in the constructor.\n */\n bytes32 internal constant _BEACON_SLOT = 0xa3f0ad74e5423aebfd80d3ef4346578335a9a72aeaee59ff6cb3582b35133d50;\n\n /**\n * @dev Emitted when the beacon is upgraded.\n */\n event BeaconUpgraded(address indexed beacon);\n\n /**\n * @dev Returns the current beacon.\n */\n function _getBeacon() internal view returns (address) {\n return StorageSlot.getAddressSlot(_BEACON_SLOT).value;\n }\n\n /**\n * @dev Stores a new beacon in the EIP1967 beacon slot.\n */\n function _setBeacon(address newBeacon) private {\n require(Address.isContract(newBeacon), \"ERC1967: new beacon is not a contract\");\n require(\n Address.isContract(IBeacon(newBeacon).implementation()),\n \"ERC1967: beacon implementation is not a contract\"\n );\n StorageSlot.getAddressSlot(_BEACON_SLOT).value = newBeacon;\n }\n\n /**\n * @dev Perform beacon upgrade with additional setup call. Note: This upgrades the address of the beacon, it does\n * not upgrade the implementation contained in the beacon (see {UpgradeableBeacon-_setImplementation} for that).\n *\n * Emits a {BeaconUpgraded} event.\n */\n function _upgradeBeaconToAndCall(\n address newBeacon,\n bytes memory data,\n bool forceCall\n ) internal {\n _setBeacon(newBeacon);\n emit BeaconUpgraded(newBeacon);\n if (data.length > 0 || forceCall) {\n Address.functionDelegateCall(IBeacon(newBeacon).implementation(), data);\n }\n }\n}\n" + }, + "@openzeppelin/contracts/proxy/Proxy.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.6.0) (proxy/Proxy.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev This abstract contract provides a fallback function that delegates all calls to another contract using the EVM\n * instruction `delegatecall`. We refer to the second contract as the _implementation_ behind the proxy, and it has to\n * be specified by overriding the virtual {_implementation} function.\n *\n * Additionally, delegation to the implementation can be triggered manually through the {_fallback} function, or to a\n * different contract through the {_delegate} function.\n *\n * The success and return data of the delegated call will be returned back to the caller of the proxy.\n */\nabstract contract Proxy {\n /**\n * @dev Delegates the current call to `implementation`.\n *\n * This function does not return to its internal call site, it will return directly to the external caller.\n */\n function _delegate(address implementation) internal virtual {\n assembly {\n // Copy msg.data. We take full control of memory in this inline assembly\n // block because it will not return to Solidity code. We overwrite the\n // Solidity scratch pad at memory position 0.\n calldatacopy(0, 0, calldatasize())\n\n // Call the implementation.\n // out and outsize are 0 because we don't know the size yet.\n let result := delegatecall(gas(), implementation, 0, calldatasize(), 0, 0)\n\n // Copy the returned data.\n returndatacopy(0, 0, returndatasize())\n\n switch result\n // delegatecall returns 0 on error.\n case 0 {\n revert(0, returndatasize())\n }\n default {\n return(0, returndatasize())\n }\n }\n }\n\n /**\n * @dev This is a virtual function that should be overridden so it returns the address to which the fallback function\n * and {_fallback} should delegate.\n */\n function _implementation() internal view virtual returns (address);\n\n /**\n * @dev Delegates the current call to the address returned by `_implementation()`.\n *\n * This function does not return to its internal call site, it will return directly to the external caller.\n */\n function _fallback() internal virtual {\n _beforeFallback();\n _delegate(_implementation());\n }\n\n /**\n * @dev Fallback function that delegates calls to the address returned by `_implementation()`. Will run if no other\n * function in the contract matches the call data.\n */\n fallback() external payable virtual {\n _fallback();\n }\n\n /**\n * @dev Fallback function that delegates calls to the address returned by `_implementation()`. Will run if call data\n * is empty.\n */\n receive() external payable virtual {\n _fallback();\n }\n\n /**\n * @dev Hook that is called before falling back to the implementation. Can happen as part of a manual `_fallback`\n * call, or as part of the Solidity `fallback` or `receive` functions.\n *\n * If overridden should call `super._beforeFallback()`.\n */\n function _beforeFallback() internal virtual {}\n}\n" + }, + "@openzeppelin/contracts/token/ERC20/ERC20.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (token/ERC20/ERC20.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./IERC20.sol\";\nimport \"./extensions/IERC20Metadata.sol\";\nimport \"../../utils/Context.sol\";\n\n/**\n * @dev Implementation of the {IERC20} interface.\n *\n * This implementation is agnostic to the way tokens are created. This means\n * that a supply mechanism has to be added in a derived contract using {_mint}.\n * For a generic mechanism see {ERC20PresetMinterPauser}.\n *\n * TIP: For a detailed writeup see our guide\n * https://forum.zeppelin.solutions/t/how-to-implement-erc20-supply-mechanisms/226[How\n * to implement supply mechanisms].\n *\n * We have followed general OpenZeppelin Contracts guidelines: functions revert\n * instead returning `false` on failure. This behavior is nonetheless\n * conventional and does not conflict with the expectations of ERC20\n * applications.\n *\n * Additionally, an {Approval} event is emitted on calls to {transferFrom}.\n * This allows applications to reconstruct the allowance for all accounts just\n * by listening to said events. Other implementations of the EIP may not emit\n * these events, as it isn't required by the specification.\n *\n * Finally, the non-standard {decreaseAllowance} and {increaseAllowance}\n * functions have been added to mitigate the well-known issues around setting\n * allowances. See {IERC20-approve}.\n */\ncontract ERC20 is Context, IERC20, IERC20Metadata {\n mapping(address => uint256) private _balances;\n\n mapping(address => mapping(address => uint256)) private _allowances;\n\n uint256 private _totalSupply;\n\n string private _name;\n string private _symbol;\n\n /**\n * @dev Sets the values for {name} and {symbol}.\n *\n * The default value of {decimals} is 18. To select a different value for\n * {decimals} you should overload it.\n *\n * All two of these values are immutable: they can only be set once during\n * construction.\n */\n constructor(string memory name_, string memory symbol_) {\n _name = name_;\n _symbol = symbol_;\n }\n\n /**\n * @dev Returns the name of the token.\n */\n function name() public view virtual override returns (string memory) {\n return _name;\n }\n\n /**\n * @dev Returns the symbol of the token, usually a shorter version of the\n * name.\n */\n function symbol() public view virtual override returns (string memory) {\n return _symbol;\n }\n\n /**\n * @dev Returns the number of decimals used to get its user representation.\n * For example, if `decimals` equals `2`, a balance of `505` tokens should\n * be displayed to a user as `5.05` (`505 / 10 ** 2`).\n *\n * Tokens usually opt for a value of 18, imitating the relationship between\n * Ether and Wei. This is the value {ERC20} uses, unless this function is\n * overridden;\n *\n * NOTE: This information is only used for _display_ purposes: it in\n * no way affects any of the arithmetic of the contract, including\n * {IERC20-balanceOf} and {IERC20-transfer}.\n */\n function decimals() public view virtual override returns (uint8) {\n return 18;\n }\n\n /**\n * @dev See {IERC20-totalSupply}.\n */\n function totalSupply() public view virtual override returns (uint256) {\n return _totalSupply;\n }\n\n /**\n * @dev See {IERC20-balanceOf}.\n */\n function balanceOf(address account) public view virtual override returns (uint256) {\n return _balances[account];\n }\n\n /**\n * @dev See {IERC20-transfer}.\n *\n * Requirements:\n *\n * - `to` cannot be the zero address.\n * - the caller must have a balance of at least `amount`.\n */\n function transfer(address to, uint256 amount) public virtual override returns (bool) {\n address owner = _msgSender();\n _transfer(owner, to, amount);\n return true;\n }\n\n /**\n * @dev See {IERC20-allowance}.\n */\n function allowance(address owner, address spender) public view virtual override returns (uint256) {\n return _allowances[owner][spender];\n }\n\n /**\n * @dev See {IERC20-approve}.\n *\n * NOTE: If `amount` is the maximum `uint256`, the allowance is not updated on\n * `transferFrom`. This is semantically equivalent to an infinite approval.\n *\n * Requirements:\n *\n * - `spender` cannot be the zero address.\n */\n function approve(address spender, uint256 amount) public virtual override returns (bool) {\n address owner = _msgSender();\n _approve(owner, spender, amount);\n return true;\n }\n\n /**\n * @dev See {IERC20-transferFrom}.\n *\n * Emits an {Approval} event indicating the updated allowance. This is not\n * required by the EIP. See the note at the beginning of {ERC20}.\n *\n * NOTE: Does not update the allowance if the current allowance\n * is the maximum `uint256`.\n *\n * Requirements:\n *\n * - `from` and `to` cannot be the zero address.\n * - `from` must have a balance of at least `amount`.\n * - the caller must have allowance for ``from``'s tokens of at least\n * `amount`.\n */\n function transferFrom(\n address from,\n address to,\n uint256 amount\n ) public virtual override returns (bool) {\n address spender = _msgSender();\n _spendAllowance(from, spender, amount);\n _transfer(from, to, amount);\n return true;\n }\n\n /**\n * @dev Atomically increases the allowance granted to `spender` by the caller.\n *\n * This is an alternative to {approve} that can be used as a mitigation for\n * problems described in {IERC20-approve}.\n *\n * Emits an {Approval} event indicating the updated allowance.\n *\n * Requirements:\n *\n * - `spender` cannot be the zero address.\n */\n function increaseAllowance(address spender, uint256 addedValue) public virtual returns (bool) {\n address owner = _msgSender();\n _approve(owner, spender, allowance(owner, spender) + addedValue);\n return true;\n }\n\n /**\n * @dev Atomically decreases the allowance granted to `spender` by the caller.\n *\n * This is an alternative to {approve} that can be used as a mitigation for\n * problems described in {IERC20-approve}.\n *\n * Emits an {Approval} event indicating the updated allowance.\n *\n * Requirements:\n *\n * - `spender` cannot be the zero address.\n * - `spender` must have allowance for the caller of at least\n * `subtractedValue`.\n */\n function decreaseAllowance(address spender, uint256 subtractedValue) public virtual returns (bool) {\n address owner = _msgSender();\n uint256 currentAllowance = allowance(owner, spender);\n require(currentAllowance >= subtractedValue, \"ERC20: decreased allowance below zero\");\n unchecked {\n _approve(owner, spender, currentAllowance - subtractedValue);\n }\n\n return true;\n }\n\n /**\n * @dev Moves `amount` of tokens from `from` to `to`.\n *\n * This internal function is equivalent to {transfer}, and can be used to\n * e.g. implement automatic token fees, slashing mechanisms, etc.\n *\n * Emits a {Transfer} event.\n *\n * Requirements:\n *\n * - `from` cannot be the zero address.\n * - `to` cannot be the zero address.\n * - `from` must have a balance of at least `amount`.\n */\n function _transfer(\n address from,\n address to,\n uint256 amount\n ) internal virtual {\n require(from != address(0), \"ERC20: transfer from the zero address\");\n require(to != address(0), \"ERC20: transfer to the zero address\");\n\n _beforeTokenTransfer(from, to, amount);\n\n uint256 fromBalance = _balances[from];\n require(fromBalance >= amount, \"ERC20: transfer amount exceeds balance\");\n unchecked {\n _balances[from] = fromBalance - amount;\n }\n _balances[to] += amount;\n\n emit Transfer(from, to, amount);\n\n _afterTokenTransfer(from, to, amount);\n }\n\n /** @dev Creates `amount` tokens and assigns them to `account`, increasing\n * the total supply.\n *\n * Emits a {Transfer} event with `from` set to the zero address.\n *\n * Requirements:\n *\n * - `account` cannot be the zero address.\n */\n function _mint(address account, uint256 amount) internal virtual {\n require(account != address(0), \"ERC20: mint to the zero address\");\n\n _beforeTokenTransfer(address(0), account, amount);\n\n _totalSupply += amount;\n _balances[account] += amount;\n emit Transfer(address(0), account, amount);\n\n _afterTokenTransfer(address(0), account, amount);\n }\n\n /**\n * @dev Destroys `amount` tokens from `account`, reducing the\n * total supply.\n *\n * Emits a {Transfer} event with `to` set to the zero address.\n *\n * Requirements:\n *\n * - `account` cannot be the zero address.\n * - `account` must have at least `amount` tokens.\n */\n function _burn(address account, uint256 amount) internal virtual {\n require(account != address(0), \"ERC20: burn from the zero address\");\n\n _beforeTokenTransfer(account, address(0), amount);\n\n uint256 accountBalance = _balances[account];\n require(accountBalance >= amount, \"ERC20: burn amount exceeds balance\");\n unchecked {\n _balances[account] = accountBalance - amount;\n }\n _totalSupply -= amount;\n\n emit Transfer(account, address(0), amount);\n\n _afterTokenTransfer(account, address(0), amount);\n }\n\n /**\n * @dev Sets `amount` as the allowance of `spender` over the `owner` s tokens.\n *\n * This internal function is equivalent to `approve`, and can be used to\n * e.g. set automatic allowances for certain subsystems, etc.\n *\n * Emits an {Approval} event.\n *\n * Requirements:\n *\n * - `owner` cannot be the zero address.\n * - `spender` cannot be the zero address.\n */\n function _approve(\n address owner,\n address spender,\n uint256 amount\n ) internal virtual {\n require(owner != address(0), \"ERC20: approve from the zero address\");\n require(spender != address(0), \"ERC20: approve to the zero address\");\n\n _allowances[owner][spender] = amount;\n emit Approval(owner, spender, amount);\n }\n\n /**\n * @dev Updates `owner` s allowance for `spender` based on spent `amount`.\n *\n * Does not update the allowance amount in case of infinite allowance.\n * Revert if not enough allowance is available.\n *\n * Might emit an {Approval} event.\n */\n function _spendAllowance(\n address owner,\n address spender,\n uint256 amount\n ) internal virtual {\n uint256 currentAllowance = allowance(owner, spender);\n if (currentAllowance != type(uint256).max) {\n require(currentAllowance >= amount, \"ERC20: insufficient allowance\");\n unchecked {\n _approve(owner, spender, currentAllowance - amount);\n }\n }\n }\n\n /**\n * @dev Hook that is called before any transfer of tokens. This includes\n * minting and burning.\n *\n * Calling conditions:\n *\n * - when `from` and `to` are both non-zero, `amount` of ``from``'s tokens\n * will be transferred to `to`.\n * - when `from` is zero, `amount` tokens will be minted for `to`.\n * - when `to` is zero, `amount` of ``from``'s tokens will be burned.\n * - `from` and `to` are never both zero.\n *\n * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].\n */\n function _beforeTokenTransfer(\n address from,\n address to,\n uint256 amount\n ) internal virtual {}\n\n /**\n * @dev Hook that is called after any transfer of tokens. This includes\n * minting and burning.\n *\n * Calling conditions:\n *\n * - when `from` and `to` are both non-zero, `amount` of ``from``'s tokens\n * has been transferred to `to`.\n * - when `from` is zero, `amount` tokens have been minted for `to`.\n * - when `to` is zero, `amount` of ``from``'s tokens have been burned.\n * - `from` and `to` are never both zero.\n *\n * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].\n */\n function _afterTokenTransfer(\n address from,\n address to,\n uint256 amount\n ) internal virtual {}\n}\n" + }, + "@openzeppelin/contracts/token/ERC20/extensions/draft-ERC20Permit.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.6.0) (token/ERC20/extensions/draft-ERC20Permit.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./draft-IERC20Permit.sol\";\nimport \"../ERC20.sol\";\nimport \"../../../utils/cryptography/draft-EIP712.sol\";\nimport \"../../../utils/cryptography/ECDSA.sol\";\nimport \"../../../utils/Counters.sol\";\n\n/**\n * @dev Implementation of the ERC20 Permit extension allowing approvals to be made via signatures, as defined in\n * https://eips.ethereum.org/EIPS/eip-2612[EIP-2612].\n *\n * Adds the {permit} method, which can be used to change an account's ERC20 allowance (see {IERC20-allowance}) by\n * presenting a message signed by the account. By not relying on `{IERC20-approve}`, the token holder account doesn't\n * need to send a transaction, and thus is not required to hold Ether at all.\n *\n * _Available since v3.4._\n */\nabstract contract ERC20Permit is ERC20, IERC20Permit, EIP712 {\n using Counters for Counters.Counter;\n\n mapping(address => Counters.Counter) private _nonces;\n\n // solhint-disable-next-line var-name-mixedcase\n bytes32 private constant _PERMIT_TYPEHASH =\n keccak256(\"Permit(address owner,address spender,uint256 value,uint256 nonce,uint256 deadline)\");\n /**\n * @dev In previous versions `_PERMIT_TYPEHASH` was declared as `immutable`.\n * However, to ensure consistency with the upgradeable transpiler, we will continue\n * to reserve a slot.\n * @custom:oz-renamed-from _PERMIT_TYPEHASH\n */\n // solhint-disable-next-line var-name-mixedcase\n bytes32 private _PERMIT_TYPEHASH_DEPRECATED_SLOT;\n\n /**\n * @dev Initializes the {EIP712} domain separator using the `name` parameter, and setting `version` to `\"1\"`.\n *\n * It's a good idea to use the same `name` that is defined as the ERC20 token name.\n */\n constructor(string memory name) EIP712(name, \"1\") {}\n\n /**\n * @dev See {IERC20Permit-permit}.\n */\n function permit(\n address owner,\n address spender,\n uint256 value,\n uint256 deadline,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) public virtual override {\n require(block.timestamp <= deadline, \"ERC20Permit: expired deadline\");\n\n bytes32 structHash = keccak256(abi.encode(_PERMIT_TYPEHASH, owner, spender, value, _useNonce(owner), deadline));\n\n bytes32 hash = _hashTypedDataV4(structHash);\n\n address signer = ECDSA.recover(hash, v, r, s);\n require(signer == owner, \"ERC20Permit: invalid signature\");\n\n _approve(owner, spender, value);\n }\n\n /**\n * @dev See {IERC20Permit-nonces}.\n */\n function nonces(address owner) public view virtual override returns (uint256) {\n return _nonces[owner].current();\n }\n\n /**\n * @dev See {IERC20Permit-DOMAIN_SEPARATOR}.\n */\n // solhint-disable-next-line func-name-mixedcase\n function DOMAIN_SEPARATOR() external view override returns (bytes32) {\n return _domainSeparatorV4();\n }\n\n /**\n * @dev \"Consume a nonce\": return the current value and increment.\n *\n * _Available since v4.1._\n */\n function _useNonce(address owner) internal virtual returns (uint256 current) {\n Counters.Counter storage nonce = _nonces[owner];\n current = nonce.current();\n nonce.increment();\n }\n}\n" + }, + "@openzeppelin/contracts/token/ERC20/extensions/draft-IERC20Permit.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (token/ERC20/extensions/draft-IERC20Permit.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Interface of the ERC20 Permit extension allowing approvals to be made via signatures, as defined in\n * https://eips.ethereum.org/EIPS/eip-2612[EIP-2612].\n *\n * Adds the {permit} method, which can be used to change an account's ERC20 allowance (see {IERC20-allowance}) by\n * presenting a message signed by the account. By not relying on {IERC20-approve}, the token holder account doesn't\n * need to send a transaction, and thus is not required to hold Ether at all.\n */\ninterface IERC20Permit {\n /**\n * @dev Sets `value` as the allowance of `spender` over ``owner``'s tokens,\n * given ``owner``'s signed approval.\n *\n * IMPORTANT: The same issues {IERC20-approve} has related to transaction\n * ordering also apply here.\n *\n * Emits an {Approval} event.\n *\n * Requirements:\n *\n * - `spender` cannot be the zero address.\n * - `deadline` must be a timestamp in the future.\n * - `v`, `r` and `s` must be a valid `secp256k1` signature from `owner`\n * over the EIP712-formatted function arguments.\n * - the signature must use ``owner``'s current nonce (see {nonces}).\n *\n * For more information on the signature format, see the\n * https://eips.ethereum.org/EIPS/eip-2612#specification[relevant EIP\n * section].\n */\n function permit(\n address owner,\n address spender,\n uint256 value,\n uint256 deadline,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) external;\n\n /**\n * @dev Returns the current nonce for `owner`. This value must be\n * included whenever a signature is generated for {permit}.\n *\n * Every successful call to {permit} increases ``owner``'s nonce by one. This\n * prevents a signature from being used multiple times.\n */\n function nonces(address owner) external view returns (uint256);\n\n /**\n * @dev Returns the domain separator used in the encoding of the signature for {permit}, as defined by {EIP712}.\n */\n // solhint-disable-next-line func-name-mixedcase\n function DOMAIN_SEPARATOR() external view returns (bytes32);\n}\n" + }, + "@openzeppelin/contracts/token/ERC20/extensions/IERC20Metadata.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (token/ERC20/extensions/IERC20Metadata.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../IERC20.sol\";\n\n/**\n * @dev Interface for the optional metadata functions from the ERC20 standard.\n *\n * _Available since v4.1._\n */\ninterface IERC20Metadata is IERC20 {\n /**\n * @dev Returns the name of the token.\n */\n function name() external view returns (string memory);\n\n /**\n * @dev Returns the symbol of the token.\n */\n function symbol() external view returns (string memory);\n\n /**\n * @dev Returns the decimals places of the token.\n */\n function decimals() external view returns (uint8);\n}\n" + }, + "@openzeppelin/contracts/token/ERC20/IERC20.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.6.0) (token/ERC20/IERC20.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Interface of the ERC20 standard as defined in the EIP.\n */\ninterface IERC20 {\n /**\n * @dev Emitted when `value` tokens are moved from one account (`from`) to\n * another (`to`).\n *\n * Note that `value` may be zero.\n */\n event Transfer(address indexed from, address indexed to, uint256 value);\n\n /**\n * @dev Emitted when the allowance of a `spender` for an `owner` is set by\n * a call to {approve}. `value` is the new allowance.\n */\n event Approval(address indexed owner, address indexed spender, uint256 value);\n\n /**\n * @dev Returns the amount of tokens in existence.\n */\n function totalSupply() external view returns (uint256);\n\n /**\n * @dev Returns the amount of tokens owned by `account`.\n */\n function balanceOf(address account) external view returns (uint256);\n\n /**\n * @dev Moves `amount` tokens from the caller's account to `to`.\n *\n * Returns a boolean value indicating whether the operation succeeded.\n *\n * Emits a {Transfer} event.\n */\n function transfer(address to, uint256 amount) external returns (bool);\n\n /**\n * @dev Returns the remaining number of tokens that `spender` will be\n * allowed to spend on behalf of `owner` through {transferFrom}. This is\n * zero by default.\n *\n * This value changes when {approve} or {transferFrom} are called.\n */\n function allowance(address owner, address spender) external view returns (uint256);\n\n /**\n * @dev Sets `amount` as the allowance of `spender` over the caller's tokens.\n *\n * Returns a boolean value indicating whether the operation succeeded.\n *\n * IMPORTANT: Beware that changing an allowance with this method brings the risk\n * that someone may use both the old and the new allowance by unfortunate\n * transaction ordering. One possible solution to mitigate this race\n * condition is to first reduce the spender's allowance to 0 and set the\n * desired value afterwards:\n * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729\n *\n * Emits an {Approval} event.\n */\n function approve(address spender, uint256 amount) external returns (bool);\n\n /**\n * @dev Moves `amount` tokens from `from` to `to` using the\n * allowance mechanism. `amount` is then deducted from the caller's\n * allowance.\n *\n * Returns a boolean value indicating whether the operation succeeded.\n *\n * Emits a {Transfer} event.\n */\n function transferFrom(\n address from,\n address to,\n uint256 amount\n ) external returns (bool);\n}\n" + }, + "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (token/ERC20/utils/SafeERC20.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../IERC20.sol\";\nimport \"../extensions/draft-IERC20Permit.sol\";\nimport \"../../../utils/Address.sol\";\n\n/**\n * @title SafeERC20\n * @dev Wrappers around ERC20 operations that throw on failure (when the token\n * contract returns false). Tokens that return no value (and instead revert or\n * throw on failure) are also supported, non-reverting calls are assumed to be\n * successful.\n * To use this library you can add a `using SafeERC20 for IERC20;` statement to your contract,\n * which allows you to call the safe operations as `token.safeTransfer(...)`, etc.\n */\nlibrary SafeERC20 {\n using Address for address;\n\n function safeTransfer(\n IERC20 token,\n address to,\n uint256 value\n ) internal {\n _callOptionalReturn(token, abi.encodeWithSelector(token.transfer.selector, to, value));\n }\n\n function safeTransferFrom(\n IERC20 token,\n address from,\n address to,\n uint256 value\n ) internal {\n _callOptionalReturn(token, abi.encodeWithSelector(token.transferFrom.selector, from, to, value));\n }\n\n /**\n * @dev Deprecated. This function has issues similar to the ones found in\n * {IERC20-approve}, and its usage is discouraged.\n *\n * Whenever possible, use {safeIncreaseAllowance} and\n * {safeDecreaseAllowance} instead.\n */\n function safeApprove(\n IERC20 token,\n address spender,\n uint256 value\n ) internal {\n // safeApprove should only be called when setting an initial allowance,\n // or when resetting it to zero. To increase and decrease it, use\n // 'safeIncreaseAllowance' and 'safeDecreaseAllowance'\n require(\n (value == 0) || (token.allowance(address(this), spender) == 0),\n \"SafeERC20: approve from non-zero to non-zero allowance\"\n );\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, value));\n }\n\n function safeIncreaseAllowance(\n IERC20 token,\n address spender,\n uint256 value\n ) internal {\n uint256 newAllowance = token.allowance(address(this), spender) + value;\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));\n }\n\n function safeDecreaseAllowance(\n IERC20 token,\n address spender,\n uint256 value\n ) internal {\n unchecked {\n uint256 oldAllowance = token.allowance(address(this), spender);\n require(oldAllowance >= value, \"SafeERC20: decreased allowance below zero\");\n uint256 newAllowance = oldAllowance - value;\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));\n }\n }\n\n function safePermit(\n IERC20Permit token,\n address owner,\n address spender,\n uint256 value,\n uint256 deadline,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) internal {\n uint256 nonceBefore = token.nonces(owner);\n token.permit(owner, spender, value, deadline, v, r, s);\n uint256 nonceAfter = token.nonces(owner);\n require(nonceAfter == nonceBefore + 1, \"SafeERC20: permit did not succeed\");\n }\n\n /**\n * @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement\n * on the return value: the return value is optional (but if data is returned, it must not be false).\n * @param token The token targeted by the call.\n * @param data The call data (encoded using abi.encode or one of its variants).\n */\n function _callOptionalReturn(IERC20 token, bytes memory data) private {\n // We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since\n // we're implementing it ourselves. We use {Address.functionCall} to perform this call, which verifies that\n // the target address contains contract code and also asserts for success in the low-level call.\n\n bytes memory returndata = address(token).functionCall(data, \"SafeERC20: low-level call failed\");\n if (returndata.length > 0) {\n // Return data is optional\n require(abi.decode(returndata, (bool)), \"SafeERC20: ERC20 operation did not succeed\");\n }\n }\n}\n" + }, + "@openzeppelin/contracts/token/ERC721/extensions/IERC721Metadata.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (token/ERC721/extensions/IERC721Metadata.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../IERC721.sol\";\n\n/**\n * @title ERC-721 Non-Fungible Token Standard, optional metadata extension\n * @dev See https://eips.ethereum.org/EIPS/eip-721\n */\ninterface IERC721Metadata is IERC721 {\n /**\n * @dev Returns the token collection name.\n */\n function name() external view returns (string memory);\n\n /**\n * @dev Returns the token collection symbol.\n */\n function symbol() external view returns (string memory);\n\n /**\n * @dev Returns the Uniform Resource Identifier (URI) for `tokenId` token.\n */\n function tokenURI(uint256 tokenId) external view returns (string memory);\n}\n" + }, + "@openzeppelin/contracts/token/ERC721/IERC721.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (token/ERC721/IERC721.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../../utils/introspection/IERC165.sol\";\n\n/**\n * @dev Required interface of an ERC721 compliant contract.\n */\ninterface IERC721 is IERC165 {\n /**\n * @dev Emitted when `tokenId` token is transferred from `from` to `to`.\n */\n event Transfer(address indexed from, address indexed to, uint256 indexed tokenId);\n\n /**\n * @dev Emitted when `owner` enables `approved` to manage the `tokenId` token.\n */\n event Approval(address indexed owner, address indexed approved, uint256 indexed tokenId);\n\n /**\n * @dev Emitted when `owner` enables or disables (`approved`) `operator` to manage all of its assets.\n */\n event ApprovalForAll(address indexed owner, address indexed operator, bool approved);\n\n /**\n * @dev Returns the number of tokens in ``owner``'s account.\n */\n function balanceOf(address owner) external view returns (uint256 balance);\n\n /**\n * @dev Returns the owner of the `tokenId` token.\n *\n * Requirements:\n *\n * - `tokenId` must exist.\n */\n function ownerOf(uint256 tokenId) external view returns (address owner);\n\n /**\n * @dev Safely transfers `tokenId` token from `from` to `to`.\n *\n * Requirements:\n *\n * - `from` cannot be the zero address.\n * - `to` cannot be the zero address.\n * - `tokenId` token must exist and be owned by `from`.\n * - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}.\n * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.\n *\n * Emits a {Transfer} event.\n */\n function safeTransferFrom(\n address from,\n address to,\n uint256 tokenId,\n bytes calldata data\n ) external;\n\n /**\n * @dev Safely transfers `tokenId` token from `from` to `to`, checking first that contract recipients\n * are aware of the ERC721 protocol to prevent tokens from being forever locked.\n *\n * Requirements:\n *\n * - `from` cannot be the zero address.\n * - `to` cannot be the zero address.\n * - `tokenId` token must exist and be owned by `from`.\n * - If the caller is not `from`, it must have been allowed to move this token by either {approve} or {setApprovalForAll}.\n * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.\n *\n * Emits a {Transfer} event.\n */\n function safeTransferFrom(\n address from,\n address to,\n uint256 tokenId\n ) external;\n\n /**\n * @dev Transfers `tokenId` token from `from` to `to`.\n *\n * WARNING: Usage of this method is discouraged, use {safeTransferFrom} whenever possible.\n *\n * Requirements:\n *\n * - `from` cannot be the zero address.\n * - `to` cannot be the zero address.\n * - `tokenId` token must be owned by `from`.\n * - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}.\n *\n * Emits a {Transfer} event.\n */\n function transferFrom(\n address from,\n address to,\n uint256 tokenId\n ) external;\n\n /**\n * @dev Gives permission to `to` to transfer `tokenId` token to another account.\n * The approval is cleared when the token is transferred.\n *\n * Only a single account can be approved at a time, so approving the zero address clears previous approvals.\n *\n * Requirements:\n *\n * - The caller must own the token or be an approved operator.\n * - `tokenId` must exist.\n *\n * Emits an {Approval} event.\n */\n function approve(address to, uint256 tokenId) external;\n\n /**\n * @dev Approve or remove `operator` as an operator for the caller.\n * Operators can call {transferFrom} or {safeTransferFrom} for any token owned by the caller.\n *\n * Requirements:\n *\n * - The `operator` cannot be the caller.\n *\n * Emits an {ApprovalForAll} event.\n */\n function setApprovalForAll(address operator, bool _approved) external;\n\n /**\n * @dev Returns the account approved for `tokenId` token.\n *\n * Requirements:\n *\n * - `tokenId` must exist.\n */\n function getApproved(uint256 tokenId) external view returns (address operator);\n\n /**\n * @dev Returns if the `operator` is allowed to manage all of the assets of `owner`.\n *\n * See {setApprovalForAll}\n */\n function isApprovedForAll(address owner, address operator) external view returns (bool);\n}\n" + }, + "@openzeppelin/contracts/utils/Address.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (utils/Address.sol)\n\npragma solidity ^0.8.1;\n\n/**\n * @dev Collection of functions related to the address type\n */\nlibrary Address {\n /**\n * @dev Returns true if `account` is a contract.\n *\n * [IMPORTANT]\n * ====\n * It is unsafe to assume that an address for which this function returns\n * false is an externally-owned account (EOA) and not a contract.\n *\n * Among others, `isContract` will return false for the following\n * types of addresses:\n *\n * - an externally-owned account\n * - a contract in construction\n * - an address where a contract will be created\n * - an address where a contract lived, but was destroyed\n * ====\n *\n * [IMPORTANT]\n * ====\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\n *\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\n * constructor.\n * ====\n */\n function isContract(address account) internal view returns (bool) {\n // This method relies on extcodesize/address.code.length, which returns 0\n // for contracts in construction, since the code is only stored at the end\n // of the constructor execution.\n\n return account.code.length > 0;\n }\n\n /**\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\n * `recipient`, forwarding all available gas and reverting on errors.\n *\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\n * imposed by `transfer`, making them unable to receive funds via\n * `transfer`. {sendValue} removes this limitation.\n *\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\n *\n * IMPORTANT: because control is transferred to `recipient`, care must be\n * taken to not create reentrancy vulnerabilities. Consider using\n * {ReentrancyGuard} or the\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\n */\n function sendValue(address payable recipient, uint256 amount) internal {\n require(address(this).balance >= amount, \"Address: insufficient balance\");\n\n (bool success, ) = recipient.call{value: amount}(\"\");\n require(success, \"Address: unable to send value, recipient may have reverted\");\n }\n\n /**\n * @dev Performs a Solidity function call using a low level `call`. A\n * plain `call` is an unsafe replacement for a function call: use this\n * function instead.\n *\n * If `target` reverts with a revert reason, it is bubbled up by this\n * function (like regular Solidity function calls).\n *\n * Returns the raw returned data. To convert to the expected return value,\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\n *\n * Requirements:\n *\n * - `target` must be a contract.\n * - calling `target` with `data` must not revert.\n *\n * _Available since v3.1._\n */\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionCall(target, data, \"Address: low-level call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\n * `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, 0, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but also transferring `value` wei to `target`.\n *\n * Requirements:\n *\n * - the calling contract must have an ETH balance of at least `value`.\n * - the called Solidity function must be `payable`.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, value, \"Address: low-level call with value failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\n * with `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(address(this).balance >= value, \"Address: insufficient balance for call\");\n require(isContract(target), \"Address: call to non-contract\");\n\n (bool success, bytes memory returndata) = target.call{value: value}(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\n return functionStaticCall(target, data, \"Address: low-level static call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal view returns (bytes memory) {\n require(isContract(target), \"Address: static call to non-contract\");\n\n (bool success, bytes memory returndata) = target.staticcall(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a delegate call.\n *\n * _Available since v3.4._\n */\n function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionDelegateCall(target, data, \"Address: low-level delegate call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a delegate call.\n *\n * _Available since v3.4._\n */\n function functionDelegateCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(isContract(target), \"Address: delegate call to non-contract\");\n\n (bool success, bytes memory returndata) = target.delegatecall(data);\n return verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the\n * revert reason using the provided one.\n *\n * _Available since v4.3._\n */\n function verifyCallResult(\n bool success,\n bytes memory returndata,\n string memory errorMessage\n ) internal pure returns (bytes memory) {\n if (success) {\n return returndata;\n } else {\n // Look for revert reason and bubble it up if present\n if (returndata.length > 0) {\n // The easiest way to bubble the revert reason is using memory via assembly\n /// @solidity memory-safe-assembly\n assembly {\n let returndata_size := mload(returndata)\n revert(add(32, returndata), returndata_size)\n }\n } else {\n revert(errorMessage);\n }\n }\n }\n}\n" + }, + "@openzeppelin/contracts/utils/Context.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Provides information about the current execution context, including the\n * sender of the transaction and its data. While these are generally available\n * via msg.sender and msg.data, they should not be accessed in such a direct\n * manner, since when dealing with meta-transactions the account sending and\n * paying for execution may not be the actual sender (as far as an application\n * is concerned).\n *\n * This contract is only required for intermediate, library-like contracts.\n */\nabstract contract Context {\n function _msgSender() internal view virtual returns (address) {\n return msg.sender;\n }\n\n function _msgData() internal view virtual returns (bytes calldata) {\n return msg.data;\n }\n}\n" + }, + "@openzeppelin/contracts/utils/Counters.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (utils/Counters.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @title Counters\n * @author Matt Condon (@shrugs)\n * @dev Provides counters that can only be incremented, decremented or reset. This can be used e.g. to track the number\n * of elements in a mapping, issuing ERC721 ids, or counting request ids.\n *\n * Include with `using Counters for Counters.Counter;`\n */\nlibrary Counters {\n struct Counter {\n // This variable should never be directly accessed by users of the library: interactions must be restricted to\n // the library's function. As of Solidity v0.5.2, this cannot be enforced, though there is a proposal to add\n // this feature: see https://github.com/ethereum/solidity/issues/4637\n uint256 _value; // default: 0\n }\n\n function current(Counter storage counter) internal view returns (uint256) {\n return counter._value;\n }\n\n function increment(Counter storage counter) internal {\n unchecked {\n counter._value += 1;\n }\n }\n\n function decrement(Counter storage counter) internal {\n uint256 value = counter._value;\n require(value > 0, \"Counter: decrement overflow\");\n unchecked {\n counter._value = value - 1;\n }\n }\n\n function reset(Counter storage counter) internal {\n counter._value = 0;\n }\n}\n" + }, + "@openzeppelin/contracts/utils/cryptography/draft-EIP712.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (utils/cryptography/draft-EIP712.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./ECDSA.sol\";\n\n/**\n * @dev https://eips.ethereum.org/EIPS/eip-712[EIP 712] is a standard for hashing and signing of typed structured data.\n *\n * The encoding specified in the EIP is very generic, and such a generic implementation in Solidity is not feasible,\n * thus this contract does not implement the encoding itself. Protocols need to implement the type-specific encoding\n * they need in their contracts using a combination of `abi.encode` and `keccak256`.\n *\n * This contract implements the EIP 712 domain separator ({_domainSeparatorV4}) that is used as part of the encoding\n * scheme, and the final step of the encoding to obtain the message digest that is then signed via ECDSA\n * ({_hashTypedDataV4}).\n *\n * The implementation of the domain separator was designed to be as efficient as possible while still properly updating\n * the chain id to protect against replay attacks on an eventual fork of the chain.\n *\n * NOTE: This contract implements the version of the encoding known as \"v4\", as implemented by the JSON RPC method\n * https://docs.metamask.io/guide/signing-data.html[`eth_signTypedDataV4` in MetaMask].\n *\n * _Available since v3.4._\n */\nabstract contract EIP712 {\n /* solhint-disable var-name-mixedcase */\n // Cache the domain separator as an immutable value, but also store the chain id that it corresponds to, in order to\n // invalidate the cached domain separator if the chain id changes.\n bytes32 private immutable _CACHED_DOMAIN_SEPARATOR;\n uint256 private immutable _CACHED_CHAIN_ID;\n address private immutable _CACHED_THIS;\n\n bytes32 private immutable _HASHED_NAME;\n bytes32 private immutable _HASHED_VERSION;\n bytes32 private immutable _TYPE_HASH;\n\n /* solhint-enable var-name-mixedcase */\n\n /**\n * @dev Initializes the domain separator and parameter caches.\n *\n * The meaning of `name` and `version` is specified in\n * https://eips.ethereum.org/EIPS/eip-712#definition-of-domainseparator[EIP 712]:\n *\n * - `name`: the user readable name of the signing domain, i.e. the name of the DApp or the protocol.\n * - `version`: the current major version of the signing domain.\n *\n * NOTE: These parameters cannot be changed except through a xref:learn::upgrading-smart-contracts.adoc[smart\n * contract upgrade].\n */\n constructor(string memory name, string memory version) {\n bytes32 hashedName = keccak256(bytes(name));\n bytes32 hashedVersion = keccak256(bytes(version));\n bytes32 typeHash = keccak256(\n \"EIP712Domain(string name,string version,uint256 chainId,address verifyingContract)\"\n );\n _HASHED_NAME = hashedName;\n _HASHED_VERSION = hashedVersion;\n _CACHED_CHAIN_ID = block.chainid;\n _CACHED_DOMAIN_SEPARATOR = _buildDomainSeparator(typeHash, hashedName, hashedVersion);\n _CACHED_THIS = address(this);\n _TYPE_HASH = typeHash;\n }\n\n /**\n * @dev Returns the domain separator for the current chain.\n */\n function _domainSeparatorV4() internal view returns (bytes32) {\n if (address(this) == _CACHED_THIS && block.chainid == _CACHED_CHAIN_ID) {\n return _CACHED_DOMAIN_SEPARATOR;\n } else {\n return _buildDomainSeparator(_TYPE_HASH, _HASHED_NAME, _HASHED_VERSION);\n }\n }\n\n function _buildDomainSeparator(\n bytes32 typeHash,\n bytes32 nameHash,\n bytes32 versionHash\n ) private view returns (bytes32) {\n return keccak256(abi.encode(typeHash, nameHash, versionHash, block.chainid, address(this)));\n }\n\n /**\n * @dev Given an already https://eips.ethereum.org/EIPS/eip-712#definition-of-hashstruct[hashed struct], this\n * function returns the hash of the fully encoded EIP712 message for this domain.\n *\n * This hash can be used together with {ECDSA-recover} to obtain the signer of a message. For example:\n *\n * ```solidity\n * bytes32 digest = _hashTypedDataV4(keccak256(abi.encode(\n * keccak256(\"Mail(address to,string contents)\"),\n * mailTo,\n * keccak256(bytes(mailContents))\n * )));\n * address signer = ECDSA.recover(digest, signature);\n * ```\n */\n function _hashTypedDataV4(bytes32 structHash) internal view virtual returns (bytes32) {\n return ECDSA.toTypedDataHash(_domainSeparatorV4(), structHash);\n }\n}\n" + }, + "@openzeppelin/contracts/utils/cryptography/ECDSA.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (utils/cryptography/ECDSA.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../Strings.sol\";\n\n/**\n * @dev Elliptic Curve Digital Signature Algorithm (ECDSA) operations.\n *\n * These functions can be used to verify that a message was signed by the holder\n * of the private keys of a given address.\n */\nlibrary ECDSA {\n enum RecoverError {\n NoError,\n InvalidSignature,\n InvalidSignatureLength,\n InvalidSignatureS,\n InvalidSignatureV\n }\n\n function _throwError(RecoverError error) private pure {\n if (error == RecoverError.NoError) {\n return; // no error: do nothing\n } else if (error == RecoverError.InvalidSignature) {\n revert(\"ECDSA: invalid signature\");\n } else if (error == RecoverError.InvalidSignatureLength) {\n revert(\"ECDSA: invalid signature length\");\n } else if (error == RecoverError.InvalidSignatureS) {\n revert(\"ECDSA: invalid signature 's' value\");\n } else if (error == RecoverError.InvalidSignatureV) {\n revert(\"ECDSA: invalid signature 'v' value\");\n }\n }\n\n /**\n * @dev Returns the address that signed a hashed message (`hash`) with\n * `signature` or error string. This address can then be used for verification purposes.\n *\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\n * this function rejects them by requiring the `s` value to be in the lower\n * half order, and the `v` value to be either 27 or 28.\n *\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\n * verification to be secure: it is possible to craft signatures that\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\n * this is by receiving a hash of the original message (which may otherwise\n * be too long), and then calling {toEthSignedMessageHash} on it.\n *\n * Documentation for signature generation:\n * - with https://web3js.readthedocs.io/en/v1.3.4/web3-eth-accounts.html#sign[Web3.js]\n * - with https://docs.ethers.io/v5/api/signer/#Signer-signMessage[ethers]\n *\n * _Available since v4.3._\n */\n function tryRecover(bytes32 hash, bytes memory signature) internal pure returns (address, RecoverError) {\n // Check the signature length\n // - case 65: r,s,v signature (standard)\n // - case 64: r,vs signature (cf https://eips.ethereum.org/EIPS/eip-2098) _Available since v4.1._\n if (signature.length == 65) {\n bytes32 r;\n bytes32 s;\n uint8 v;\n // ecrecover takes the signature parameters, and the only way to get them\n // currently is to use assembly.\n /// @solidity memory-safe-assembly\n assembly {\n r := mload(add(signature, 0x20))\n s := mload(add(signature, 0x40))\n v := byte(0, mload(add(signature, 0x60)))\n }\n return tryRecover(hash, v, r, s);\n } else if (signature.length == 64) {\n bytes32 r;\n bytes32 vs;\n // ecrecover takes the signature parameters, and the only way to get them\n // currently is to use assembly.\n /// @solidity memory-safe-assembly\n assembly {\n r := mload(add(signature, 0x20))\n vs := mload(add(signature, 0x40))\n }\n return tryRecover(hash, r, vs);\n } else {\n return (address(0), RecoverError.InvalidSignatureLength);\n }\n }\n\n /**\n * @dev Returns the address that signed a hashed message (`hash`) with\n * `signature`. This address can then be used for verification purposes.\n *\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\n * this function rejects them by requiring the `s` value to be in the lower\n * half order, and the `v` value to be either 27 or 28.\n *\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\n * verification to be secure: it is possible to craft signatures that\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\n * this is by receiving a hash of the original message (which may otherwise\n * be too long), and then calling {toEthSignedMessageHash} on it.\n */\n function recover(bytes32 hash, bytes memory signature) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, signature);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Overload of {ECDSA-tryRecover} that receives the `r` and `vs` short-signature fields separately.\n *\n * See https://eips.ethereum.org/EIPS/eip-2098[EIP-2098 short signatures]\n *\n * _Available since v4.3._\n */\n function tryRecover(\n bytes32 hash,\n bytes32 r,\n bytes32 vs\n ) internal pure returns (address, RecoverError) {\n bytes32 s = vs & bytes32(0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff);\n uint8 v = uint8((uint256(vs) >> 255) + 27);\n return tryRecover(hash, v, r, s);\n }\n\n /**\n * @dev Overload of {ECDSA-recover} that receives the `r and `vs` short-signature fields separately.\n *\n * _Available since v4.2._\n */\n function recover(\n bytes32 hash,\n bytes32 r,\n bytes32 vs\n ) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, r, vs);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Overload of {ECDSA-tryRecover} that receives the `v`,\n * `r` and `s` signature fields separately.\n *\n * _Available since v4.3._\n */\n function tryRecover(\n bytes32 hash,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) internal pure returns (address, RecoverError) {\n // EIP-2 still allows signature malleability for ecrecover(). Remove this possibility and make the signature\n // unique. Appendix F in the Ethereum Yellow paper (https://ethereum.github.io/yellowpaper/paper.pdf), defines\n // the valid range for s in (301): 0 < s < secp256k1n ÷ 2 + 1, and for v in (302): v ∈ {27, 28}. Most\n // signatures from current libraries generate a unique signature with an s-value in the lower half order.\n //\n // If your library generates malleable signatures, such as s-values in the upper range, calculate a new s-value\n // with 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141 - s1 and flip v from 27 to 28 or\n // vice versa. If your library also generates signatures with 0/1 for v instead 27/28, add 27 to v to accept\n // these malleable signatures as well.\n if (uint256(s) > 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D576E7357A4501DDFE92F46681B20A0) {\n return (address(0), RecoverError.InvalidSignatureS);\n }\n if (v != 27 && v != 28) {\n return (address(0), RecoverError.InvalidSignatureV);\n }\n\n // If the signature is valid (and not malleable), return the signer address\n address signer = ecrecover(hash, v, r, s);\n if (signer == address(0)) {\n return (address(0), RecoverError.InvalidSignature);\n }\n\n return (signer, RecoverError.NoError);\n }\n\n /**\n * @dev Overload of {ECDSA-recover} that receives the `v`,\n * `r` and `s` signature fields separately.\n */\n function recover(\n bytes32 hash,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, v, r, s);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Returns an Ethereum Signed Message, created from a `hash`. This\n * produces hash corresponding to the one signed with the\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\n * JSON-RPC method as part of EIP-191.\n *\n * See {recover}.\n */\n function toEthSignedMessageHash(bytes32 hash) internal pure returns (bytes32) {\n // 32 is the length in bytes of hash,\n // enforced by the type signature above\n return keccak256(abi.encodePacked(\"\\x19Ethereum Signed Message:\\n32\", hash));\n }\n\n /**\n * @dev Returns an Ethereum Signed Message, created from `s`. This\n * produces hash corresponding to the one signed with the\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\n * JSON-RPC method as part of EIP-191.\n *\n * See {recover}.\n */\n function toEthSignedMessageHash(bytes memory s) internal pure returns (bytes32) {\n return keccak256(abi.encodePacked(\"\\x19Ethereum Signed Message:\\n\", Strings.toString(s.length), s));\n }\n\n /**\n * @dev Returns an Ethereum Signed Typed Data, created from a\n * `domainSeparator` and a `structHash`. This produces hash corresponding\n * to the one signed with the\n * https://eips.ethereum.org/EIPS/eip-712[`eth_signTypedData`]\n * JSON-RPC method as part of EIP-712.\n *\n * See {recover}.\n */\n function toTypedDataHash(bytes32 domainSeparator, bytes32 structHash) internal pure returns (bytes32) {\n return keccak256(abi.encodePacked(\"\\x19\\x01\", domainSeparator, structHash));\n }\n}\n" + }, + "@openzeppelin/contracts/utils/introspection/IERC165.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (utils/introspection/IERC165.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Interface of the ERC165 standard, as defined in the\n * https://eips.ethereum.org/EIPS/eip-165[EIP].\n *\n * Implementers can declare support of contract interfaces, which can then be\n * queried by others ({ERC165Checker}).\n *\n * For an implementation, see {ERC165}.\n */\ninterface IERC165 {\n /**\n * @dev Returns true if this contract implements the interface defined by\n * `interfaceId`. See the corresponding\n * https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified[EIP section]\n * to learn more about how these ids are created.\n *\n * This function call must use less than 30 000 gas.\n */\n function supportsInterface(bytes4 interfaceId) external view returns (bool);\n}\n" + }, + "@openzeppelin/contracts/utils/StorageSlot.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (utils/StorageSlot.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Library for reading and writing primitive types to specific storage slots.\n *\n * Storage slots are often used to avoid storage conflict when dealing with upgradeable contracts.\n * This library helps with reading and writing to such slots without the need for inline assembly.\n *\n * The functions in this library return Slot structs that contain a `value` member that can be used to read or write.\n *\n * Example usage to set ERC1967 implementation slot:\n * ```\n * contract ERC1967 {\n * bytes32 internal constant _IMPLEMENTATION_SLOT = 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc;\n *\n * function _getImplementation() internal view returns (address) {\n * return StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value;\n * }\n *\n * function _setImplementation(address newImplementation) internal {\n * require(Address.isContract(newImplementation), \"ERC1967: new implementation is not a contract\");\n * StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value = newImplementation;\n * }\n * }\n * ```\n *\n * _Available since v4.1 for `address`, `bool`, `bytes32`, and `uint256`._\n */\nlibrary StorageSlot {\n struct AddressSlot {\n address value;\n }\n\n struct BooleanSlot {\n bool value;\n }\n\n struct Bytes32Slot {\n bytes32 value;\n }\n\n struct Uint256Slot {\n uint256 value;\n }\n\n /**\n * @dev Returns an `AddressSlot` with member `value` located at `slot`.\n */\n function getAddressSlot(bytes32 slot) internal pure returns (AddressSlot storage r) {\n /// @solidity memory-safe-assembly\n assembly {\n r.slot := slot\n }\n }\n\n /**\n * @dev Returns an `BooleanSlot` with member `value` located at `slot`.\n */\n function getBooleanSlot(bytes32 slot) internal pure returns (BooleanSlot storage r) {\n /// @solidity memory-safe-assembly\n assembly {\n r.slot := slot\n }\n }\n\n /**\n * @dev Returns an `Bytes32Slot` with member `value` located at `slot`.\n */\n function getBytes32Slot(bytes32 slot) internal pure returns (Bytes32Slot storage r) {\n /// @solidity memory-safe-assembly\n assembly {\n r.slot := slot\n }\n }\n\n /**\n * @dev Returns an `Uint256Slot` with member `value` located at `slot`.\n */\n function getUint256Slot(bytes32 slot) internal pure returns (Uint256Slot storage r) {\n /// @solidity memory-safe-assembly\n assembly {\n r.slot := slot\n }\n }\n}\n" + }, + "@openzeppelin/contracts/utils/Strings.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (utils/Strings.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev String operations.\n */\nlibrary Strings {\n bytes16 private constant _HEX_SYMBOLS = \"0123456789abcdef\";\n uint8 private constant _ADDRESS_LENGTH = 20;\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` decimal representation.\n */\n function toString(uint256 value) internal pure returns (string memory) {\n // Inspired by OraclizeAPI's implementation - MIT licence\n // https://github.com/oraclize/ethereum-api/blob/b42146b063c7d6ee1358846c198246239e9360e8/oraclizeAPI_0.4.25.sol\n\n if (value == 0) {\n return \"0\";\n }\n uint256 temp = value;\n uint256 digits;\n while (temp != 0) {\n digits++;\n temp /= 10;\n }\n bytes memory buffer = new bytes(digits);\n while (value != 0) {\n digits -= 1;\n buffer[digits] = bytes1(uint8(48 + uint256(value % 10)));\n value /= 10;\n }\n return string(buffer);\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation.\n */\n function toHexString(uint256 value) internal pure returns (string memory) {\n if (value == 0) {\n return \"0x00\";\n }\n uint256 temp = value;\n uint256 length = 0;\n while (temp != 0) {\n length++;\n temp >>= 8;\n }\n return toHexString(value, length);\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length.\n */\n function toHexString(uint256 value, uint256 length) internal pure returns (string memory) {\n bytes memory buffer = new bytes(2 * length + 2);\n buffer[0] = \"0\";\n buffer[1] = \"x\";\n for (uint256 i = 2 * length + 1; i > 1; --i) {\n buffer[i] = _HEX_SYMBOLS[value & 0xf];\n value >>= 4;\n }\n require(value == 0, \"Strings: hex length insufficient\");\n return string(buffer);\n }\n\n /**\n * @dev Converts an `address` with fixed length of 20 bytes to its not checksummed ASCII `string` hexadecimal representation.\n */\n function toHexString(address addr) internal pure returns (string memory) {\n return toHexString(uint256(uint160(addr)), _ADDRESS_LENGTH);\n }\n}\n" + }, + "contracts/agToken/AgEUR.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\nimport \"../interfaces/IAgToken.sol\";\nimport \"../interfaces/coreModule/IStableMaster.sol\";\nimport \"../interfaces/ITreasury.sol\";\nimport \"@openzeppelin/contracts-upgradeable/token/ERC20/extensions/draft-ERC20PermitUpgradeable.sol\";\n\n/// @title AgEUR\n/// @author Angle Labs, Inc.\n/// @notice Base contract for agEUR, Angle's Euro stablecoin\n/// @dev This contract is an upgraded version of the agEUR contract that was first deployed on Ethereum mainnet\ncontract AgEUR is IAgToken, ERC20PermitUpgradeable {\n // ================================= REFERENCES ================================\n\n /// @notice Reference to the `StableMaster` contract associated to agEUR\n address public stableMaster;\n\n /// @custom:oz-upgrades-unsafe-allow constructor\n constructor() initializer {}\n\n // ============================== ADDED PARAMETERS =============================\n\n /// @inheritdoc IAgToken\n mapping(address => bool) public isMinter;\n /// @notice Reference to the treasury contract which can grant minting rights\n address public treasury;\n /// @notice Boolean used to check whether the contract had been reinitialized after an upgrade\n bool public treasuryInitialized;\n\n // =================================== EVENTS ==================================\n\n event TreasuryUpdated(address indexed _treasury);\n event MinterToggled(address indexed minter);\n\n // =================================== ERRORS ==================================\n\n error BurnAmountExceedsAllowance();\n error InvalidSender();\n error InvalidTreasury();\n error NotGovernor();\n error NotMinter();\n error NotTreasury();\n error TreasuryAlreadyInitialized();\n\n // ================================= MODIFIERS =================================\n\n /// @notice Checks to see if it is the `Treasury` calling this contract\n modifier onlyTreasury() {\n if (msg.sender != treasury) revert NotTreasury();\n _;\n }\n\n /// @notice Checks whether the sender has the minting right\n modifier onlyMinter() {\n if (!isMinter[msg.sender]) revert NotMinter();\n _;\n }\n\n // ============================= EXTERNAL FUNCTION =============================\n\n /// @notice Allows anyone to burn stablecoins\n /// @param amount Amount of stablecoins to burn\n /// @dev This function can typically be called if there is a settlement mechanism to burn stablecoins\n function burnStablecoin(uint256 amount) external {\n _burn(msg.sender, amount);\n }\n\n // ========================= MINTER ROLE ONLY FUNCTIONS ========================\n\n /// @inheritdoc IAgToken\n function burnSelf(uint256 amount, address burner) external onlyMinter {\n _burn(burner, amount);\n }\n\n /// @inheritdoc IAgToken\n function burnFrom(uint256 amount, address burner, address sender) external onlyMinter {\n if (burner != sender) {\n uint256 currentAllowance = allowance(burner, sender);\n if (currentAllowance < amount) revert BurnAmountExceedsAllowance();\n _approve(burner, sender, currentAllowance - amount);\n }\n _burn(burner, amount);\n }\n\n /// @inheritdoc IAgToken\n function mint(address account, uint256 amount) external onlyMinter {\n _mint(account, amount);\n }\n\n // ========================== TREASURY ONLY FUNCTIONS ==========================\n\n /// @inheritdoc IAgToken\n function addMinter(address minter) external onlyTreasury {\n isMinter[minter] = true;\n emit MinterToggled(minter);\n }\n\n /// @inheritdoc IAgToken\n function removeMinter(address minter) external {\n if (msg.sender != minter && msg.sender != address(treasury)) revert InvalidSender();\n isMinter[minter] = false;\n emit MinterToggled(minter);\n }\n\n /// @inheritdoc IAgToken\n function setTreasury(address _treasury) external onlyTreasury {\n treasury = _treasury;\n emit TreasuryUpdated(_treasury);\n }\n}\n" + }, + "contracts/agToken/AgToken.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\n/*\n * █ \n ***** ▓▓▓ \n * ▓▓▓▓▓▓▓ \n * ///. ▓▓▓▓▓▓▓▓▓▓▓▓▓ \n ***** //////// ▓▓▓▓▓▓▓ \n * ///////////// ▓▓▓ \n ▓▓ ////////////////// █ ▓▓ \n ▓▓ ▓▓ /////////////////////// ▓▓ ▓▓ \n ▓▓ ▓▓ //////////////////////////// ▓▓ ▓▓ \n ▓▓ ▓▓ /////////▓▓▓///////▓▓▓///////// ▓▓ ▓▓ \n ▓▓ ,////////////////////////////////////// ▓▓ ▓▓ \n ▓▓ ////////////////////////////////////////// ▓▓ \n ▓▓ //////////////////////▓▓▓▓///////////////////// \n ,//////////////////////////////////////////////////// \n .////////////////////////////////////////////////////////// \n .//////////////////////////██.,//////////////////////////█ \n .//////////////////////████..,./////////////////////██ \n ...////////////////███████.....,.////////////////███ \n ,.,////////////████████ ........,///////////████ \n .,.,//////█████████ ,.......///////████ \n ,..//████████ ........./████ \n ..,██████ .....,███ \n .██ ,.,█ \n \n \n \n ▓▓ ▓▓▓▓▓▓▓▓▓▓ ▓▓▓▓▓▓▓▓▓▓ ▓▓ ▓▓▓▓▓▓▓▓▓▓ \n ▓▓▓▓▓▓ ▓▓▓ ▓▓▓ ▓▓▓ ▓▓ ▓▓ ▓▓▓▓ \n ▓▓▓ ▓▓▓ ▓▓▓ ▓▓▓ ▓▓▓ ▓▓▓ ▓▓ ▓▓▓▓▓ \n ▓▓▓ ▓▓ ▓▓▓ ▓▓▓ ▓▓▓▓▓▓▓▓▓▓ ▓▓▓▓▓▓▓▓▓▓ ▓▓▓▓▓▓▓▓▓▓ \n*/\n\nimport \"../interfaces/IAgToken.sol\";\nimport \"../interfaces/ITreasury.sol\";\nimport \"@openzeppelin/contracts-upgradeable/token/ERC20/extensions/draft-ERC20PermitUpgradeable.sol\";\n\n/// @title AgToken\n/// @author Angle Labs, Inc.\n/// @notice Base contract for Angle agTokens on Ethereum and on other chains\n/// @dev By default, agTokens are ERC-20 tokens with 18 decimals\ncontract AgToken is IAgToken, ERC20PermitUpgradeable {\n // =========================== PARAMETERS / VARIABLES ==========================\n\n /// @inheritdoc IAgToken\n mapping(address => bool) public isMinter;\n /// @notice Reference to the treasury contract which can grant minting rights\n address public treasury;\n\n // =================================== EVENTS ==================================\n\n event TreasuryUpdated(address indexed _treasury);\n event MinterToggled(address indexed minter);\n\n // =================================== ERRORS ==================================\n\n error BurnAmountExceedsAllowance();\n error InvalidSender();\n error InvalidTreasury();\n error NotMinter();\n error NotTreasury();\n\n // ================================ CONSTRUCTOR ================================\n\n /// @custom:oz-upgrades-unsafe-allow constructor\n constructor() initializer {}\n\n /// @notice Initializes the `AgToken` contract\n function initialize(string memory name_, string memory symbol_, address _treasury) external {\n _initialize(name_, symbol_, _treasury);\n }\n\n /// @notice Initializes the contract\n function _initialize(string memory name_, string memory symbol_, address _treasury) internal virtual initializer {\n if (address(ITreasury(_treasury).stablecoin()) != address(this)) revert InvalidTreasury();\n __ERC20Permit_init(name_);\n __ERC20_init(name_, symbol_);\n treasury = _treasury;\n emit TreasuryUpdated(_treasury);\n }\n\n // ================================= MODIFIERS =================================\n\n /// @notice Checks to see if it is the `Treasury` calling this contract\n modifier onlyTreasury() {\n if (msg.sender != treasury) revert NotTreasury();\n _;\n }\n\n /// @notice Checks whether the sender has the minting right\n modifier onlyMinter() {\n if (!isMinter[msg.sender]) revert NotMinter();\n _;\n }\n\n // ============================= EXTERNAL FUNCTION =============================\n\n /// @notice Allows anyone to burn stablecoins\n /// @param amount Amount of stablecoins to burn\n /// @dev This function can typically be called if there is a settlement mechanism to burn stablecoins\n function burnStablecoin(uint256 amount) external {\n _burn(msg.sender, amount);\n }\n\n // ========================= MINTER ROLE ONLY FUNCTIONS ========================\n\n /// @inheritdoc IAgToken\n function burnSelf(uint256 amount, address burner) external onlyMinter {\n _burn(burner, amount);\n }\n\n /// @inheritdoc IAgToken\n function burnFrom(uint256 amount, address burner, address sender) external onlyMinter {\n if (burner != sender) {\n uint256 currentAllowance = allowance(burner, sender);\n if (currentAllowance < amount) revert BurnAmountExceedsAllowance();\n _approve(burner, sender, currentAllowance - amount);\n }\n _burn(burner, amount);\n }\n\n /// @inheritdoc IAgToken\n function mint(address account, uint256 amount) external onlyMinter {\n _mint(account, amount);\n }\n\n // ========================== GOVERNANCE ONLY FUNCTIONS ==========================\n\n /// @inheritdoc IAgToken\n function addMinter(address minter) external onlyTreasury {\n isMinter[minter] = true;\n emit MinterToggled(minter);\n }\n\n /// @inheritdoc IAgToken\n function removeMinter(address minter) external {\n if (msg.sender != address(treasury) && msg.sender != minter) revert InvalidSender();\n isMinter[minter] = false;\n emit MinterToggled(minter);\n }\n\n /// @inheritdoc IAgToken\n function setTreasury(address _treasury) external virtual onlyTreasury {\n treasury = _treasury;\n emit TreasuryUpdated(_treasury);\n }\n}\n" + }, + "contracts/agToken/AgTokenSideChainMultiBridge.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\nimport \"./AgToken.sol\";\nimport \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\nimport \"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\";\n\n/// @title AgTokenSideChainMultiBridge\n/// @author Angle Labs, Inc.\n/// @notice Contract for Angle agTokens on other chains than Ethereum mainnet\n/// @dev This contract supports bridge tokens having a minting right on the stablecoin (also referred to as the canonical\n/// or the native token)\ncontract AgTokenSideChainMultiBridge is AgToken {\n using SafeERC20 for IERC20;\n\n /// @notice Base used for fee computation\n uint256 public constant BASE_PARAMS = 1e9;\n\n // =============================== BRIDGING DATA ===============================\n\n /// @notice Struct with some data about a specific bridge token\n struct BridgeDetails {\n // Limit on the balance of bridge token held by the contract: it is designed\n // to reduce the exposure of the system to hacks\n uint256 limit;\n // Limit on the hourly volume of token minted through this bridge\n // Technically the limit over a rolling hour is hourlyLimit x2 as hourly limit\n // is enforced only between x:00 and x+1:00\n uint256 hourlyLimit;\n // Fee taken for swapping in and out the token\n uint64 fee;\n // Whether the associated token is allowed or not\n bool allowed;\n // Whether swapping in and out from the associated token is paused or not\n bool paused;\n }\n\n /// @notice Maps a bridge token to data\n mapping(address => BridgeDetails) public bridges;\n /// @notice List of all bridge tokens\n address[] public bridgeTokensList;\n /// @notice Maps a bridge token to the associated hourly volume\n mapping(address => mapping(uint256 => uint256)) public usage;\n /// @notice Maps an address to whether it is exempt of fees for when it comes to swapping in and out\n mapping(address => uint256) public isFeeExempt;\n /// @notice Limit to the amount of tokens that can be sent from that chain to another chain\n uint256 public chainTotalHourlyLimit;\n /// @notice Usage per hour on that chain. Maps an hourly timestamp to the total volume swapped out on the chain\n mapping(uint256 => uint256) public chainTotalUsage;\n\n // =================================== EVENTS ==================================\n\n event BridgeTokenAdded(address indexed bridgeToken, uint256 limit, uint256 hourlyLimit, uint64 fee, bool paused);\n event BridgeTokenToggled(address indexed bridgeToken, bool toggleStatus);\n event BridgeTokenRemoved(address indexed bridgeToken);\n event BridgeTokenFeeUpdated(address indexed bridgeToken, uint64 fee);\n event BridgeTokenLimitUpdated(address indexed bridgeToken, uint256 limit);\n event BridgeTokenHourlyLimitUpdated(address indexed bridgeToken, uint256 hourlyLimit);\n event HourlyLimitUpdated(uint256 hourlyLimit);\n event Recovered(address indexed token, address indexed to, uint256 amount);\n event FeeToggled(address indexed theAddress, uint256 toggleStatus);\n\n // =================================== ERRORS ==================================\n\n error AssetStillControlledInReserves();\n error HourlyLimitExceeded();\n error InvalidToken();\n error NotGovernor();\n error NotGovernorOrGuardian();\n error TooBigAmount();\n error TooHighParameterValue();\n error ZeroAddress();\n\n // ================================= MODIFIERS =================================\n\n /// @notice Checks whether the `msg.sender` has the governor role or not\n modifier onlyGovernor() {\n if (!ITreasury(treasury).isGovernor(msg.sender)) revert NotGovernor();\n _;\n }\n\n /// @notice Checks whether the `msg.sender` has the governor role or the guardian role\n modifier onlyGovernorOrGuardian() {\n if (!ITreasury(treasury).isGovernorOrGuardian(msg.sender)) revert NotGovernorOrGuardian();\n _;\n }\n\n // ===================== EXTERNAL PERMISSIONLESS FUNCTIONS =====================\n\n /// @notice Returns the list of all supported bridge tokens\n /// @dev Helpful for UIs\n function allBridgeTokens() external view returns (address[] memory) {\n return bridgeTokensList;\n }\n\n /// @notice Returns the current volume for a bridge, for the current hour\n /// @param bridgeToken Bridge used to mint\n /// @dev Helpful for UIs\n function currentUsage(address bridgeToken) external view returns (uint256) {\n return usage[bridgeToken][block.timestamp / 3600];\n }\n\n /// @notice Returns the current total volume on the chain for the current hour\n /// @dev Helpful for UIs\n function currentTotalUsage() external view returns (uint256) {\n return chainTotalUsage[block.timestamp / 3600];\n }\n\n /// @notice Mints the canonical token from a supported bridge token\n /// @param bridgeToken Bridge token to use to mint\n /// @param amount Amount of bridge tokens to send\n /// @param to Address to which the stablecoin should be sent\n /// @return Amount of the canonical stablecoin actually minted\n /// @dev Some fees may be taken by the protocol depending on the token used and on the address calling\n function swapIn(address bridgeToken, uint256 amount, address to) external returns (uint256) {\n BridgeDetails memory bridgeDetails = bridges[bridgeToken];\n if (!bridgeDetails.allowed || bridgeDetails.paused) revert InvalidToken();\n uint256 balance = IERC20(bridgeToken).balanceOf(address(this));\n if (balance + amount > bridgeDetails.limit) {\n // In case someone maliciously sends tokens to this contract\n // Or the limit changes\n if (bridgeDetails.limit > balance) amount = bridgeDetails.limit - balance;\n else {\n amount = 0;\n }\n }\n\n // Checking requirement on the hourly volume\n uint256 hour = block.timestamp / 3600;\n uint256 hourlyUsage = usage[bridgeToken][hour];\n if (hourlyUsage + amount > bridgeDetails.hourlyLimit) {\n // Edge case when the hourly limit changes\n amount = bridgeDetails.hourlyLimit > hourlyUsage ? bridgeDetails.hourlyLimit - hourlyUsage : 0;\n }\n usage[bridgeToken][hour] = hourlyUsage + amount;\n\n IERC20(bridgeToken).safeTransferFrom(msg.sender, address(this), amount);\n uint256 canonicalOut = amount;\n // Computing fees\n if (isFeeExempt[msg.sender] == 0) {\n canonicalOut -= (canonicalOut * bridgeDetails.fee) / BASE_PARAMS;\n }\n _mint(to, canonicalOut);\n return canonicalOut;\n }\n\n /// @notice Burns the canonical token in exchange for a bridge token\n /// @param bridgeToken Bridge token required\n /// @param amount Amount of canonical tokens to burn\n /// @param to Address to which the bridge token should be sent\n /// @return Amount of bridge tokens actually sent back\n /// @dev Some fees may be taken by the protocol depending on the token used and on the address calling\n function swapOut(address bridgeToken, uint256 amount, address to) external returns (uint256) {\n BridgeDetails memory bridgeDetails = bridges[bridgeToken];\n if (!bridgeDetails.allowed || bridgeDetails.paused) revert InvalidToken();\n\n uint256 hour = block.timestamp / 3600;\n uint256 hourlyUsage = chainTotalUsage[hour] + amount;\n // If the amount being swapped out exceeds the limit, we revert\n // We don't want to change the amount being swapped out.\n // The user can decide to send another tx with the correct amount to reach the limit\n if (hourlyUsage > chainTotalHourlyLimit) revert HourlyLimitExceeded();\n chainTotalUsage[hour] = hourlyUsage;\n\n _burn(msg.sender, amount);\n uint256 bridgeOut = amount;\n if (isFeeExempt[msg.sender] == 0) {\n bridgeOut -= (bridgeOut * bridgeDetails.fee) / BASE_PARAMS;\n }\n IERC20(bridgeToken).safeTransfer(to, bridgeOut);\n return bridgeOut;\n }\n\n // ============================ GOVERNANCE FUNCTIONS ===========================\n\n /// @notice Adds support for a bridge token\n /// @param bridgeToken Bridge token to add: it should be a version of the stablecoin from another bridge\n /// @param limit Limit on the balance of bridge token this contract could hold\n /// @param hourlyLimit Limit on the hourly volume for this bridge\n /// @param paused Whether swapping for this token should be paused or not\n /// @param fee Fee taken upon swapping for or against this token\n function addBridgeToken(\n address bridgeToken,\n uint256 limit,\n uint256 hourlyLimit,\n uint64 fee,\n bool paused\n ) external onlyGovernor {\n if (bridges[bridgeToken].allowed || bridgeToken == address(0)) revert InvalidToken();\n if (fee > BASE_PARAMS) revert TooHighParameterValue();\n BridgeDetails memory _bridge;\n _bridge.limit = limit;\n _bridge.hourlyLimit = hourlyLimit;\n _bridge.paused = paused;\n _bridge.fee = fee;\n _bridge.allowed = true;\n bridges[bridgeToken] = _bridge;\n bridgeTokensList.push(bridgeToken);\n emit BridgeTokenAdded(bridgeToken, limit, hourlyLimit, fee, paused);\n }\n\n /// @notice Removes support for a token\n /// @param bridgeToken Address of the bridge token to remove support for\n function removeBridgeToken(address bridgeToken) external onlyGovernor {\n if (IERC20(bridgeToken).balanceOf(address(this)) != 0) revert AssetStillControlledInReserves();\n delete bridges[bridgeToken];\n // Deletion from `bridgeTokensList` loop\n uint256 bridgeTokensListLength = bridgeTokensList.length;\n for (uint256 i; i < bridgeTokensListLength - 1; ++i) {\n if (bridgeTokensList[i] == bridgeToken) {\n // Replace the `bridgeToken` to remove with the last of the list\n bridgeTokensList[i] = bridgeTokensList[bridgeTokensListLength - 1];\n break;\n }\n }\n // Remove last element in array\n bridgeTokensList.pop();\n emit BridgeTokenRemoved(bridgeToken);\n }\n\n /// @notice Recovers any ERC20 token\n /// @dev Can be used to withdraw bridge tokens for them to be de-bridged on mainnet\n function recoverERC20(address tokenAddress, address to, uint256 amountToRecover) external onlyGovernor {\n IERC20(tokenAddress).safeTransfer(to, amountToRecover);\n emit Recovered(tokenAddress, to, amountToRecover);\n }\n\n /// @notice Updates the `limit` amount for `bridgeToken`\n function setLimit(address bridgeToken, uint256 limit) external onlyGovernorOrGuardian {\n if (!bridges[bridgeToken].allowed) revert InvalidToken();\n bridges[bridgeToken].limit = limit;\n emit BridgeTokenLimitUpdated(bridgeToken, limit);\n }\n\n /// @notice Updates the `hourlyLimit` amount for `bridgeToken`\n function setHourlyLimit(address bridgeToken, uint256 hourlyLimit) external onlyGovernorOrGuardian {\n if (!bridges[bridgeToken].allowed) revert InvalidToken();\n bridges[bridgeToken].hourlyLimit = hourlyLimit;\n emit BridgeTokenHourlyLimitUpdated(bridgeToken, hourlyLimit);\n }\n\n /// @notice Updates the `chainTotalHourlyLimit` amount\n function setChainTotalHourlyLimit(uint256 hourlyLimit) external onlyGovernorOrGuardian {\n chainTotalHourlyLimit = hourlyLimit;\n emit HourlyLimitUpdated(hourlyLimit);\n }\n\n /// @notice Updates the `fee` value for `bridgeToken`\n function setSwapFee(address bridgeToken, uint64 fee) external onlyGovernorOrGuardian {\n if (!bridges[bridgeToken].allowed) revert InvalidToken();\n if (fee > BASE_PARAMS) revert TooHighParameterValue();\n bridges[bridgeToken].fee = fee;\n emit BridgeTokenFeeUpdated(bridgeToken, fee);\n }\n\n /// @notice Pauses or unpauses swapping in and out for a token\n function toggleBridge(address bridgeToken) external onlyGovernorOrGuardian {\n if (!bridges[bridgeToken].allowed) revert InvalidToken();\n bool pausedStatus = bridges[bridgeToken].paused;\n bridges[bridgeToken].paused = !pausedStatus;\n emit BridgeTokenToggled(bridgeToken, !pausedStatus);\n }\n\n /// @notice Toggles fees for the address `theAddress`\n function toggleFeesForAddress(address theAddress) external onlyGovernorOrGuardian {\n uint256 feeExemptStatus = 1 - isFeeExempt[theAddress];\n isFeeExempt[theAddress] = feeExemptStatus;\n emit FeeToggled(theAddress, feeExemptStatus);\n }\n}\n" + }, + "contracts/agToken/layerZero/LayerZeroBridge.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.12;\n\nimport \"./utils/OFTCore.sol\";\nimport \"@openzeppelin/contracts-upgradeable/security/PausableUpgradeable.sol\";\nimport \"@openzeppelin/contracts/token/ERC20/extensions/draft-IERC20Permit.sol\";\n\n/// @title LayerZeroBridge\n/// @author Angle Labs, Inc., forked from https://github.com/LayerZero-Labs/solidity-examples/blob/main/contracts/token/oft/OFT.sol\n/// @notice Contract to be deployed on Ethereum for bridging an AgToken using a bridge intermediate token and LayerZero\ncontract LayerZeroBridge is OFTCore, PausableUpgradeable {\n /// @notice Name of the contract for indexing purposes\n string public name;\n\n /// @notice Address of the bridgeable token\n /// @dev Immutable\n IERC20 public canonicalToken;\n\n /// @notice Maps an address to the amount of token bridged but not received\n mapping(address => uint256) public balanceOf;\n\n // ================================ CONSTRUCTOR ================================\n /// @notice Initializes the contract\n /// @param _name Name of the token corresponding to this contract\n /// @param _lzEndpoint Layer zero endpoint to pass messages\n /// @param _treasury Address of the treasury contract used for access control\n function initialize(string memory _name, address _lzEndpoint, address _treasury) external initializer {\n __LzAppUpgradeable_init(_lzEndpoint, _treasury);\n name = _name;\n canonicalToken = IERC20(address(ITreasury(_treasury).stablecoin()));\n }\n\n /// @custom:oz-upgrades-unsafe-allow constructor\n constructor() initializer {}\n\n // ===================== EXTERNAL PERMISSIONLESS FUNCTIONS =====================\n\n /// @inheritdoc OFTCore\n function sendWithPermit(\n uint16 _dstChainId,\n bytes memory _toAddress,\n uint256 _amount,\n address payable _refundAddress,\n address _zroPaymentAddress,\n bytes memory _adapterParams,\n uint256 deadline,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) public payable override {\n IERC20Permit(address(canonicalToken)).permit(msg.sender, address(this), _amount, deadline, v, r, s);\n send(_dstChainId, _toAddress, _amount, _refundAddress, _zroPaymentAddress, _adapterParams);\n }\n\n /// @inheritdoc OFTCore\n function withdraw(uint256 amount, address recipient) external override returns (uint256) {\n return _withdraw(amount, msg.sender, recipient);\n }\n\n /// @notice Withdraws amount of `token` from the contract and sends it to the recipient\n /// @param amount Amount to withdraw\n /// @param recipient Address to withdraw for\n /// @return The amount of canonical token sent\n function withdrawFor(uint256 amount, address recipient) external returns (uint256) {\n return _withdraw(amount, recipient, recipient);\n }\n\n // ============================= INTERNAL FUNCTIONS ============================\n\n /// @notice Withdraws `amount` from the balance of the `from` address and sends these tokens to the `to` address\n /// @dev It's important to make sure that `from` is either the `msg.sender` or that `from` and `to` are the same\n /// addresses\n function _withdraw(uint256 amount, address from, address to) internal whenNotPaused returns (uint256) {\n balanceOf[from] -= amount; // Will overflow if the amount is too big\n canonicalToken.transfer(to, amount);\n return amount;\n }\n\n /// @inheritdoc OFTCore\n function _debitFrom(uint16, bytes memory, uint256 _amount) internal override whenNotPaused returns (uint256) {\n // No need to use safeTransferFrom as we know this implementation reverts on failure\n canonicalToken.transferFrom(msg.sender, address(this), _amount);\n return _amount;\n }\n\n /// @inheritdoc OFTCore\n function _debitCreditFrom(uint16, bytes memory, uint256 _amount) internal override whenNotPaused returns (uint256) {\n balanceOf[msg.sender] -= _amount;\n return _amount;\n }\n\n /// @inheritdoc OFTCore\n function _creditTo(uint16, address _toAddress, uint256 _amount) internal override whenNotPaused returns (uint256) {\n // Should never revert as all the LayerZero bridge tokens come from\n // this contract\n uint256 balance = canonicalToken.balanceOf(address(this));\n if (balance < _amount) {\n balanceOf[_toAddress] = _amount - balance;\n if (balance != 0) canonicalToken.transfer(_toAddress, balance);\n } else {\n canonicalToken.transfer(_toAddress, _amount);\n }\n return _amount;\n }\n\n // =============================== VIEW FUNCTIONS ==============================\n\n /// @inheritdoc ERC165Upgradeable\n function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {\n return interfaceId == type(IOFTCore).interfaceId || super.supportsInterface(interfaceId);\n }\n\n // ============================ GOVERNANCE FUNCTIONS ===========================\n\n /// @notice Pauses bridging through the contract\n /// @param pause Future pause status\n function pauseSendTokens(bool pause) external onlyGovernorOrGuardian {\n pause ? _pause() : _unpause();\n }\n\n /// @notice Decreases the balance of an address\n /// @param amount Amount to withdraw from balance\n /// @param recipient Address to withdraw from\n function sweep(uint256 amount, address recipient) external onlyGovernorOrGuardian {\n balanceOf[recipient] -= amount; // Will overflow if the amount is too big\n }\n\n uint256[47] private __gap;\n}\n" + }, + "contracts/agToken/layerZero/LayerZeroBridgeToken.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.12;\n\nimport \"./utils/OFTCore.sol\";\nimport \"../../interfaces/IAgTokenSideChainMultiBridge.sol\";\nimport \"@openzeppelin/contracts-upgradeable/security/PausableUpgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/token/ERC20/ERC20Upgradeable.sol\";\n\n/// @title LayerZeroBridgeToken\n/// @author Angle Labs, Inc., forked from https://github.com/LayerZero-Labs/solidity-examples/blob/main/contracts/token/oft/OFT.sol\n/// @notice Contract to be deployed on a L2/sidechain for bridging an AgToken using a bridge intermediate token and LayerZero\ncontract LayerZeroBridgeToken is OFTCore, ERC20Upgradeable, PausableUpgradeable {\n /// @notice Address of the bridgeable token\n /// @dev Immutable\n IAgTokenSideChainMultiBridge public canonicalToken;\n\n // =================================== ERROR ===================================\n\n error InvalidAllowance();\n\n // ================================ CONSTRUCTOR ================================\n\n /// @notice Initializes the contract\n /// @param _name Name of the token corresponding to this contract\n /// @param _symbol Symbol of the token corresponding to this contract\n /// @param _lzEndpoint Layer zero endpoint to pass messages\n /// @param _treasury Address of the treasury contract used for access control\n /// @param initialSupply Initial supply to mint to the canonical token address\n /// @dev The initial supply corresponds to the initial amount that could be bridged using this OFT\n function initialize(\n string memory _name,\n string memory _symbol,\n address _lzEndpoint,\n address _treasury,\n uint256 initialSupply\n ) external initializer {\n __ERC20_init_unchained(_name, _symbol);\n __LzAppUpgradeable_init(_lzEndpoint, _treasury);\n\n canonicalToken = IAgTokenSideChainMultiBridge(address(ITreasury(_treasury).stablecoin()));\n _approve(address(this), address(canonicalToken), type(uint256).max);\n _mint(address(canonicalToken), initialSupply);\n }\n\n /// @custom:oz-upgrades-unsafe-allow constructor\n constructor() initializer {}\n\n // ===================== EXTERNAL PERMISSIONLESS FUNCTIONS =====================\n\n /// @inheritdoc OFTCore\n function sendWithPermit(\n uint16 _dstChainId,\n bytes memory _toAddress,\n uint256 _amount,\n address payable _refundAddress,\n address _zroPaymentAddress,\n bytes memory _adapterParams,\n uint256 deadline,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) public payable override {\n canonicalToken.permit(msg.sender, address(this), _amount, deadline, v, r, s);\n send(_dstChainId, _toAddress, _amount, _refundAddress, _zroPaymentAddress, _adapterParams);\n }\n\n /// @inheritdoc OFTCore\n function withdraw(uint256 amount, address recipient) external override returns (uint256 amountMinted) {\n // Does not check allowances as transfers from `msg.sender`\n _transfer(msg.sender, address(this), amount);\n amountMinted = canonicalToken.swapIn(address(this), amount, recipient);\n uint256 leftover = balanceOf(address(this));\n if (leftover != 0) {\n _transfer(address(this), msg.sender, leftover);\n }\n }\n\n // ============================= INTERNAL FUNCTIONS ============================\n\n /// @inheritdoc OFTCore\n function _debitFrom(\n uint16,\n bytes memory,\n uint256 _amount\n ) internal override whenNotPaused returns (uint256 amountSwapped) {\n // No need to use safeTransferFrom as we know this implementation reverts on failure\n canonicalToken.transferFrom(msg.sender, address(this), _amount);\n\n // Swap canonical for this bridge token. There may be some fees\n amountSwapped = canonicalToken.swapOut(address(this), _amount, address(this));\n _burn(address(this), amountSwapped);\n }\n\n /// @inheritdoc OFTCore\n function _debitCreditFrom(uint16, bytes memory, uint256 _amount) internal override whenNotPaused returns (uint256) {\n _burn(msg.sender, _amount);\n return _amount;\n }\n\n /// @inheritdoc OFTCore\n function _creditTo(\n uint16,\n address _toAddress,\n uint256 _amount\n ) internal override whenNotPaused returns (uint256 amountMinted) {\n _mint(address(this), _amount);\n amountMinted = canonicalToken.swapIn(address(this), _amount, _toAddress);\n uint256 leftover = balanceOf(address(this));\n if (leftover != 0) {\n _transfer(address(this), _toAddress, leftover);\n }\n }\n\n // =============================== VIEW FUNCTIONS ==============================\n\n /// @inheritdoc ERC165Upgradeable\n function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {\n return\n interfaceId == type(IOFT).interfaceId ||\n interfaceId == type(IERC20).interfaceId ||\n super.supportsInterface(interfaceId);\n }\n\n // ============================ GOVERNANCE FUNCTIONS ===========================\n\n /// @notice Mints the intermediate contract to the `canonicalToken`\n /// @dev Used to increase the bridging capacity\n function mint(uint256 amount) external onlyGovernorOrGuardian {\n _mint(address(canonicalToken), amount);\n }\n\n /// @notice Burns the intermediate contract from the `canonicalToken`\n /// @dev Used to decrease the bridging capacity\n function burn(uint256 amount) external onlyGovernorOrGuardian {\n _burn(address(canonicalToken), amount);\n }\n\n /// @notice Increases allowance of the `canonicalToken`\n function setupAllowance() public onlyGovernorOrGuardian {\n _approve(address(this), address(canonicalToken), type(uint256).max);\n }\n\n /// @notice Pauses bridging through the contract\n /// @param pause Future pause status\n function pauseSendTokens(bool pause) external onlyGovernorOrGuardian {\n pause ? _pause() : _unpause();\n }\n\n uint256[49] private __gap;\n}\n" + }, + "contracts/agToken/layerZero/utils/IOFTCore.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.12;\n\nimport \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\nimport \"@openzeppelin/contracts/utils/introspection/IERC165.sol\";\n\n/**\n * @dev Interface of the IOFT core standard\n * @dev Forked from https://github.com/LayerZero-Labs/solidity-examples/blob/main/contracts/token/oft/IOFTCore.sol\n */\ninterface IOFTCore is IERC165 {\n /// @notice Estimates send token `_tokenId` to (`_dstChainId`, `_toAddress`)\n /// @param _dstChainId L0 defined chain id to send tokens too\n /// @param _toAddress dynamic bytes array which contains the address to whom you are sending tokens to on the dstChain\n /// @param _amount amount of the tokens to transfer\n /// @param _useZro indicates to use zro to pay L0 fees\n /// @param _adapterParams flexible bytes array to indicate messaging adapter services in L0\n function estimateSendFee(\n uint16 _dstChainId,\n bytes calldata _toAddress,\n uint256 _amount,\n bool _useZro,\n bytes calldata _adapterParams\n ) external view returns (uint256 nativeFee, uint256 zroFee);\n\n /// @notice Sends `_amount` amount of token to (`_dstChainId`, `_toAddress`)\n /// @param _dstChainId the destination chain identifier\n /// @param _toAddress can be any size depending on the `dstChainId`.\n /// @param _amount the quantity of tokens in wei\n /// @param _refundAddress the address LayerZero refunds if too much message fee is sent\n /// @param _zroPaymentAddress set to address(0x0) if not paying in ZRO (LayerZero Token)\n /// @param _adapterParams is a flexible bytes array to indicate messaging adapter services\n function send(\n uint16 _dstChainId,\n bytes calldata _toAddress,\n uint256 _amount,\n address payable _refundAddress,\n address _zroPaymentAddress,\n bytes calldata _adapterParams\n ) external payable;\n\n /// @notice Sends `_amount` amount of credit to (`_dstChainId`, `_toAddress`)\n /// @param _dstChainId the destination chain identifier\n /// @param _toAddress can be any size depending on the `dstChainId`.\n /// @param _amount the quantity of credit to send in wei\n /// @param _refundAddress the address LayerZero refunds if too much message fee is sent\n /// @param _zroPaymentAddress set to address(0x0) if not paying in ZRO (LayerZero Token)\n /// @param _adapterParams is a flexible bytes array to indicate messaging adapter services\n function sendCredit(\n uint16 _dstChainId,\n bytes calldata _toAddress,\n uint256 _amount,\n address payable _refundAddress,\n address _zroPaymentAddress,\n bytes calldata _adapterParams\n ) external payable;\n\n /// @notice Sends `_amount` amount of token to (`_dstChainId`, `_toAddress`)\n /// @param _dstChainId The destination chain identifier\n /// @param _toAddress Can be any size depending on the `dstChainId`.\n /// @param _amount Quantity of tokens in wei\n /// @param _refundAddress Address LayerZero refunds if too much message fee is sent\n /// @param _zroPaymentAddress Set to address(0x0) if not paying in ZRO (LayerZero Token)\n /// @param _adapterParams Flexible bytes array to indicate messaging adapter services\n /// @param deadline Deadline parameter for the signature to be valid\n /// @dev The `v`, `r`, and `s` parameters are used as signature data\n function sendWithPermit(\n uint16 _dstChainId,\n bytes memory _toAddress,\n uint256 _amount,\n address payable _refundAddress,\n address _zroPaymentAddress,\n bytes memory _adapterParams,\n uint256 deadline,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) external payable;\n\n /// @notice Withdraws amount of canonical token from the `msg.sender` balance and sends it to the recipient\n /// @param amount Amount to withdraw\n /// @param recipient Address to send the canonical token to\n /// @return The amount of canonical token sent\n function withdraw(uint256 amount, address recipient) external returns (uint256);\n\n /// @dev Emitted when `_amount` tokens are moved from the `_sender` to (`_dstChainId`, `_toAddress`)\n /// `_nonce` is the outbound nonce\n event SendToChain(\n address indexed _sender,\n uint16 indexed _dstChainId,\n bytes indexed _toAddress,\n uint256 _amount,\n uint64 _nonce\n );\n\n /// @dev Emitted when `_amount` tokens are received from `_srcChainId` into the `_toAddress` on the local chain.\n /// `_nonce` is the inbound nonce.\n event ReceiveFromChain(\n uint16 indexed _srcChainId,\n bytes indexed _srcAddress,\n address indexed _toAddress,\n uint256 _amount,\n uint64 _nonce\n );\n}\n\n/// @dev Interface of the OFT standard\ninterface IOFT is IOFTCore, IERC20 {\n\n}\n" + }, + "contracts/agToken/layerZero/utils/NonblockingLzApp.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.12;\n\nimport \"@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol\";\nimport \"../../../interfaces/external/layerZero/ILayerZeroReceiver.sol\";\nimport \"../../../interfaces/external/layerZero/ILayerZeroUserApplicationConfig.sol\";\nimport \"../../../interfaces/external/layerZero/ILayerZeroEndpoint.sol\";\nimport \"../../../interfaces/ITreasury.sol\";\n\n/// @title NonblockingLzApp\n/// @author Angle Labs, Inc., forked from https://github.com/LayerZero-Labs/solidity-examples/\n/// @notice Base contract for bridging using LayerZero\nabstract contract NonblockingLzApp is Initializable, ILayerZeroReceiver, ILayerZeroUserApplicationConfig {\n /// @notice Layer Zero endpoint\n ILayerZeroEndpoint public lzEndpoint;\n\n /// @notice Maps chainIds to failed messages to retry them\n mapping(uint16 => mapping(bytes => mapping(uint64 => bytes32))) public failedMessages;\n\n /// @notice Maps chainIds to their OFT address\n mapping(uint16 => bytes) public trustedRemoteLookup;\n\n /// @notice Reference to the treasury contract to fetch access control\n address public treasury;\n\n /// @notice Maps pairs of (`to` chain, `packetType`) to the minimum amount of gas needed on the destination chain\n mapping(uint16 => mapping(uint16 => uint256)) public minDstGasLookup;\n\n /// @notice For future LayerZero compatibility\n address public precrime;\n\n // ================================== Events ===================================\n\n event SetTrustedRemote(uint16 _srcChainId, bytes _srcAddress);\n event MessageFailed(uint16 _srcChainId, bytes _srcAddress, uint64 _nonce, bytes _payload);\n\n // =============================== Errors ================================\n\n error NotGovernor();\n error NotGovernorOrGuardian();\n error InsufficientGas();\n error InvalidEndpoint();\n error InvalidSource();\n error InvalidCaller();\n error InvalidParams();\n error InvalidPayload();\n error ZeroAddress();\n\n // ============================= Constructor ===================================\n\n //solhint-disable-next-line\n function __LzAppUpgradeable_init(address _endpoint, address _treasury) internal {\n if (_endpoint == address(0) || _treasury == address(0)) revert ZeroAddress();\n lzEndpoint = ILayerZeroEndpoint(_endpoint);\n treasury = _treasury;\n }\n\n // =============================== Modifiers ===================================\n\n /// @notice Checks whether the `msg.sender` has the governor role or the guardian role\n modifier onlyGovernorOrGuardian() {\n if (!ITreasury(treasury).isGovernorOrGuardian(msg.sender)) revert NotGovernorOrGuardian();\n _;\n }\n\n // ==================== External Permissionless Functions ======================\n\n /// @notice Receives a message from the LZ endpoint and process it\n /// @param _srcChainId ChainId of the source chain - LayerZero standard\n /// @param _srcAddress Sender of the source chain\n /// @param _nonce Nounce of the message\n /// @param _payload Data: recipient address and amount\n function lzReceive(\n uint16 _srcChainId,\n bytes memory _srcAddress,\n uint64 _nonce,\n bytes memory _payload\n ) public virtual override {\n // lzReceive must be called by the endpoint for security\n if (msg.sender != address(lzEndpoint)) revert InvalidEndpoint();\n\n bytes memory trustedRemote = trustedRemoteLookup[_srcChainId];\n // if will still block the message pathway from (srcChainId, srcAddress). should not receive message from untrusted remote.\n if (_srcAddress.length != trustedRemote.length || keccak256(_srcAddress) != keccak256(trustedRemote))\n revert InvalidSource();\n\n _blockingLzReceive(_srcChainId, _srcAddress, _nonce, _payload);\n }\n\n /// @notice Retries a message that previously failed and was stored\n /// @param _srcChainId ChainId of the source chain - LayerZero standard\n /// @param _srcAddress Sender of the source chain\n /// @param _nonce Nounce of the message\n /// @param _payload Data: recipient address and amount\n function retryMessage(\n uint16 _srcChainId,\n bytes memory _srcAddress,\n uint64 _nonce,\n bytes memory _payload\n ) public payable virtual {\n // assert there is message to retry\n bytes32 payloadHash = failedMessages[_srcChainId][_srcAddress][_nonce];\n if (payloadHash == bytes32(0) || keccak256(_payload) != payloadHash) revert InvalidPayload();\n // clear the stored message\n failedMessages[_srcChainId][_srcAddress][_nonce] = bytes32(0);\n // execute the message. revert if it fails again\n _nonblockingLzReceive(_srcChainId, _srcAddress, _nonce, _payload);\n }\n\n // ============================= Internal Functions ===================================\n\n /// @notice Handles message receptions in a non blocking way\n /// @param _srcChainId ChainId of the source chain - LayerZero standard\n /// @param _srcAddress Sender of the source chain\n /// @param _nonce Nounce of the message\n /// @param _payload Data: recipient address and amount\n /// @dev public for the needs of try / catch but effectively internal\n function nonblockingLzReceive(\n uint16 _srcChainId,\n bytes memory _srcAddress,\n uint64 _nonce,\n bytes memory _payload\n ) public virtual {\n // only internal transaction\n if (msg.sender != address(this)) revert InvalidCaller();\n _nonblockingLzReceive(_srcChainId, _srcAddress, _nonce, _payload);\n }\n\n /// @notice Handles message receptions in a non blocking way\n /// @param _srcChainId ChainId of the source chain - LayerZero standard\n /// @param _srcAddress Sender of the source chain\n /// @param _nonce Nounce of the message\n /// @param _payload Data: recipient address and amount\n function _nonblockingLzReceive(\n uint16 _srcChainId,\n bytes memory _srcAddress,\n uint64 _nonce,\n bytes memory _payload\n ) internal virtual;\n\n /// @notice Handles message receptions in a blocking way\n /// @param _srcChainId ChainId of the source chain - LayerZero standard\n /// @param _srcAddress Sender of the source chain\n /// @param _nonce Nounce of the message\n /// @param _payload Data: recipient address and amount\n function _blockingLzReceive(\n uint16 _srcChainId,\n bytes memory _srcAddress,\n uint64 _nonce,\n bytes memory _payload\n ) internal {\n // try-catch all errors/exceptions\n try this.nonblockingLzReceive(_srcChainId, _srcAddress, _nonce, _payload) {\n // do nothing\n } catch {\n // error / exception\n failedMessages[_srcChainId][_srcAddress][_nonce] = keccak256(_payload);\n emit MessageFailed(_srcChainId, _srcAddress, _nonce, _payload);\n }\n }\n\n /// @notice Sends a message to the LZ endpoint and process it\n /// @param _dstChainId L0 defined chain id to send tokens too\n /// @param _payload Data: recipient address and amount\n /// @param _refundAddress Address LayerZero refunds if too much message fee is sent\n /// @param _zroPaymentAddress Set to address(0x0) if not paying in ZRO (LayerZero Token)\n /// @param _adapterParams Flexible bytes array to indicate messaging adapter services in L0\n function _lzSend(\n uint16 _dstChainId,\n bytes memory _payload,\n address payable _refundAddress,\n address _zroPaymentAddress,\n bytes memory _adapterParams\n ) internal virtual {\n bytes memory trustedRemote = trustedRemoteLookup[_dstChainId];\n if (trustedRemote.length == 0) revert InvalidSource();\n //solhint-disable-next-line\n lzEndpoint.send{ value: msg.value }(\n _dstChainId,\n trustedRemote,\n _payload,\n _refundAddress,\n _zroPaymentAddress,\n _adapterParams\n );\n }\n\n /// @notice Checks the gas limit of a given transaction\n function _checkGasLimit(\n uint16 _dstChainId,\n uint16 _type,\n bytes memory _adapterParams,\n uint256 _extraGas\n ) internal view virtual {\n uint256 minGasLimit = minDstGasLookup[_dstChainId][_type] + _extraGas;\n if (minGasLimit == 0 || minGasLimit > _getGasLimit(_adapterParams)) revert InsufficientGas();\n }\n\n /// @notice Gets the gas limit from the `_adapterParams` parameter\n function _getGasLimit(bytes memory _adapterParams) internal pure virtual returns (uint256 gasLimit) {\n if (_adapterParams.length < 34) revert InvalidParams();\n // solhint-disable-next-line\n assembly {\n gasLimit := mload(add(_adapterParams, 34))\n }\n }\n\n // ======================= Governance Functions ================================\n\n /// @notice Sets the corresponding address on an other chain.\n /// @param _srcChainId ChainId of the source chain - LayerZero standard\n /// @param _srcAddress Address on the source chain\n /// @dev Used for both receiving and sending message\n /// @dev There can only be one trusted source per chain\n /// @dev Allows owner to set it multiple times.\n function setTrustedRemote(uint16 _srcChainId, bytes calldata _srcAddress) external onlyGovernorOrGuardian {\n trustedRemoteLookup[_srcChainId] = _srcAddress;\n emit SetTrustedRemote(_srcChainId, _srcAddress);\n }\n\n /// @notice Fetches the default LZ config\n function getConfig(\n uint16 _version,\n uint16 _chainId,\n address,\n uint256 _configType\n ) external view returns (bytes memory) {\n return lzEndpoint.getConfig(_version, _chainId, address(this), _configType);\n }\n\n /// @notice Overrides the default LZ config\n function setConfig(\n uint16 _version,\n uint16 _chainId,\n uint256 _configType,\n bytes calldata _config\n ) external override onlyGovernorOrGuardian {\n lzEndpoint.setConfig(_version, _chainId, _configType, _config);\n }\n\n /// @notice Overrides the default LZ config\n function setSendVersion(uint16 _version) external override onlyGovernorOrGuardian {\n lzEndpoint.setSendVersion(_version);\n }\n\n /// @notice Overrides the default LZ config\n function setReceiveVersion(uint16 _version) external override onlyGovernorOrGuardian {\n lzEndpoint.setReceiveVersion(_version);\n }\n\n /// @notice Unpauses the receive functionalities\n function forceResumeReceive(\n uint16 _srcChainId,\n bytes calldata _srcAddress\n ) external override onlyGovernorOrGuardian {\n lzEndpoint.forceResumeReceive(_srcChainId, _srcAddress);\n }\n\n /// @notice Sets the minimum gas parameter for a packet type on a given chain\n function setMinDstGas(uint16 _dstChainId, uint16 _packetType, uint256 _minGas) external onlyGovernorOrGuardian {\n if (_minGas == 0) revert InvalidParams();\n minDstGasLookup[_dstChainId][_packetType] = _minGas;\n }\n\n /// @notice Sets the precrime variable\n function setPrecrime(address _precrime) external onlyGovernorOrGuardian {\n precrime = _precrime;\n }\n\n // ======================= View Functions ================================\n\n /// @notice Checks if the `_srcAddress` corresponds to the trusted source\n function isTrustedRemote(uint16 _srcChainId, bytes calldata _srcAddress) external view returns (bool) {\n bytes memory trustedSource = trustedRemoteLookup[_srcChainId];\n return keccak256(trustedSource) == keccak256(_srcAddress);\n }\n\n uint256[44] private __gap;\n}\n" + }, + "contracts/agToken/layerZero/utils/OFTCore.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.12;\n\nimport \"./NonblockingLzApp.sol\";\nimport \"./IOFTCore.sol\";\nimport \"@openzeppelin/contracts-upgradeable/utils/introspection/ERC165Upgradeable.sol\";\n\n/// @title OFTCore\n/// @author Forked from https://github.com/LayerZero-Labs/solidity-examples/blob/main/contracts/token/oft/OFTCore.sol\n/// but with slight modifications from the Angle Labs, Inc. which added return values to the `_creditTo` and `_debitFrom` functions\n/// @notice Base contract for bridging using LayerZero\nabstract contract OFTCore is NonblockingLzApp, ERC165Upgradeable, IOFTCore {\n /// @notice Amount of additional gas specified\n uint256 public constant EXTRA_GAS = 200000;\n /// @notice Packet type for token transfer\n uint16 public constant PT_SEND = 0;\n\n /// @notice Whether to use custom parameters in transactions\n uint8 public useCustomAdapterParams;\n\n // ==================== External Permissionless Functions ======================\n\n /// @inheritdoc IOFTCore\n function sendWithPermit(\n uint16 _dstChainId,\n bytes memory _toAddress,\n uint256 _amount,\n address payable _refundAddress,\n address _zroPaymentAddress,\n bytes memory _adapterParams,\n uint256 deadline,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) public payable virtual;\n\n /// @inheritdoc IOFTCore\n function send(\n uint16 _dstChainId,\n bytes memory _toAddress,\n uint256 _amount,\n address payable _refundAddress,\n address _zroPaymentAddress,\n bytes memory _adapterParams\n ) public payable virtual {\n _checkAdapterParams(_dstChainId, PT_SEND, _adapterParams, EXTRA_GAS);\n _amount = _debitFrom(_dstChainId, _toAddress, _amount);\n\n bytes memory payload = abi.encode(_toAddress, _amount);\n _lzSend(_dstChainId, payload, _refundAddress, _zroPaymentAddress, _adapterParams);\n\n uint64 nonce = lzEndpoint.getOutboundNonce(_dstChainId, address(this));\n emit SendToChain(msg.sender, _dstChainId, _toAddress, _amount, nonce);\n }\n\n /// @inheritdoc IOFTCore\n function sendCredit(\n uint16 _dstChainId,\n bytes memory _toAddress,\n uint256 _amount,\n address payable _refundAddress,\n address _zroPaymentAddress,\n bytes memory _adapterParams\n ) public payable virtual {\n _checkAdapterParams(_dstChainId, PT_SEND, _adapterParams, EXTRA_GAS);\n _amount = _debitCreditFrom(_dstChainId, _toAddress, _amount);\n\n _send(_dstChainId, _toAddress, _amount, _refundAddress, _zroPaymentAddress, _adapterParams);\n }\n\n /// @inheritdoc IOFTCore\n function withdraw(uint256 amount, address recipient) external virtual returns (uint256);\n\n /// @notice Sets whether custom adapter parameters can be used or not\n function setUseCustomAdapterParams(uint8 _useCustomAdapterParams) public virtual onlyGovernorOrGuardian {\n useCustomAdapterParams = _useCustomAdapterParams;\n }\n\n // =========================== Internal Functions ==============================\n\n /// @notice Internal function to send `_amount` amount of token to (`_dstChainId`, `_toAddress`)\n /// @param _dstChainId the destination chain identifier\n /// @param _toAddress can be any size depending on the `dstChainId`.\n /// @param _amount the quantity of tokens in wei\n /// @param _refundAddress the address LayerZero refunds if too much message fee is sent\n /// @param _zroPaymentAddress set to address(0x0) if not paying in ZRO (LayerZero Token)\n /// @param _adapterParams is a flexible bytes array to indicate messaging adapter services\n /// @dev Accounting and checks should be performed beforehand\n function _send(\n uint16 _dstChainId,\n bytes memory _toAddress,\n uint256 _amount,\n address payable _refundAddress,\n address _zroPaymentAddress,\n bytes memory _adapterParams\n ) internal {\n bytes memory payload = abi.encode(_toAddress, _amount);\n _lzSend(_dstChainId, payload, _refundAddress, _zroPaymentAddress, _adapterParams);\n\n uint64 nonce = lzEndpoint.getOutboundNonce(_dstChainId, address(this));\n emit SendToChain(msg.sender, _dstChainId, _toAddress, _amount, nonce);\n }\n\n /// @inheritdoc NonblockingLzApp\n function _nonblockingLzReceive(\n uint16 _srcChainId,\n bytes memory _srcAddress,\n uint64 _nonce,\n bytes memory _payload\n ) internal virtual override {\n // decode and load the toAddress\n (bytes memory toAddressBytes, uint256 amount) = abi.decode(_payload, (bytes, uint256));\n address toAddress;\n //solhint-disable-next-line\n assembly {\n toAddress := mload(add(toAddressBytes, 20))\n }\n amount = _creditTo(_srcChainId, toAddress, amount);\n\n emit ReceiveFromChain(_srcChainId, _srcAddress, toAddress, amount, _nonce);\n }\n\n /// @notice Checks the adapter parameters given during the smart contract call\n function _checkAdapterParams(\n uint16 _dstChainId,\n uint16 _pkType,\n bytes memory _adapterParams,\n uint256 _extraGas\n ) internal virtual {\n if (useCustomAdapterParams > 0) _checkGasLimit(_dstChainId, _pkType, _adapterParams, _extraGas);\n else if (_adapterParams.length != 0) revert InvalidParams();\n }\n\n /// @notice Makes accountability when bridging from this contract using canonical token\n /// @param _dstChainId ChainId of the destination chain - LayerZero standard\n /// @param _toAddress Recipient on the destination chain\n /// @param _amount Amount to bridge\n function _debitFrom(\n uint16 _dstChainId,\n bytes memory _toAddress,\n uint256 _amount\n ) internal virtual returns (uint256);\n\n /// @notice Makes accountability when bridging from this contract's credit\n /// @param _dstChainId ChainId of the destination chain - LayerZero standard\n /// @param _toAddress Recipient on the destination chain\n /// @param _amount Amount to bridge\n function _debitCreditFrom(\n uint16 _dstChainId,\n bytes memory _toAddress,\n uint256 _amount\n ) internal virtual returns (uint256);\n\n /// @notice Makes accountability when bridging to this contract\n /// @param _srcChainId ChainId of the source chain - LayerZero standard\n /// @param _toAddress Recipient on this chain\n /// @param _amount Amount to bridge\n function _creditTo(uint16 _srcChainId, address _toAddress, uint256 _amount) internal virtual returns (uint256);\n\n // ========================== View Functions ===================================\n\n /// @inheritdoc ERC165Upgradeable\n function supportsInterface(\n bytes4 interfaceId\n ) public view virtual override(ERC165Upgradeable, IERC165) returns (bool) {\n return interfaceId == type(IOFTCore).interfaceId || super.supportsInterface(interfaceId);\n }\n\n /// @inheritdoc IOFTCore\n function estimateSendFee(\n uint16 _dstChainId,\n bytes memory _toAddress,\n uint256 _amount,\n bool _useZro,\n bytes memory _adapterParams\n ) public view virtual override returns (uint256 nativeFee, uint256 zroFee) {\n // mock the payload for send()\n bytes memory payload = abi.encode(_toAddress, _amount);\n return lzEndpoint.estimateFees(_dstChainId, address(this), payload, _useZro, _adapterParams);\n }\n\n uint256[49] private __gap;\n}\n" + }, + "contracts/agToken/polygon/TokenPolygonUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.12;\n\nimport \"./utils/ERC20UpgradeableCustom.sol\";\nimport \"@openzeppelin/contracts-upgradeable/access/AccessControlUpgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/utils/cryptography/draft-EIP712Upgradeable.sol\";\nimport \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\nimport \"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\";\n\nimport \"../../interfaces/IAgToken.sol\";\nimport \"../../interfaces/ITreasury.sol\";\n\ninterface IChildToken {\n function deposit(address user, bytes calldata depositData) external;\n\n function withdraw(uint256 amount) external;\n}\n\ncontract TokenPolygonUpgradeable is\n Initializable,\n ERC20UpgradeableCustom,\n AccessControlUpgradeable,\n EIP712Upgradeable,\n IChildToken\n{\n bytes32 public constant DEPOSITOR_ROLE = keccak256(\"DEPOSITOR_ROLE\");\n\n /// @dev Emitted when the child chain manager changes\n event ChildChainManagerAdded(address newAddress);\n event ChildChainManagerRevoked(address oldAddress);\n\n constructor() initializer {}\n\n function initialize(\n string memory _name,\n string memory _symbol,\n address childChainManager,\n address guardian\n ) public initializer {\n __ERC20_init(_name, _symbol);\n __AccessControl_init();\n _setupRole(DEFAULT_ADMIN_ROLE, guardian);\n _setupRole(DEPOSITOR_ROLE, childChainManager);\n __EIP712_init(_name, \"1\");\n }\n\n /**\n * @notice Called when the bridge has tokens to mint\n * @param user Address to mint the token to\n * @param depositData Encoded amount to mint\n */\n function deposit(address user, bytes calldata depositData) external override {\n require(hasRole(DEPOSITOR_ROLE, msg.sender));\n uint256 amount = abi.decode(depositData, (uint256));\n _mint(user, amount);\n }\n\n /**\n * @notice Called when user wants to withdraw tokens back to root chain\n * @dev Should burn user's tokens. This transaction will be verified when exiting on root chain\n * @param amount Amount of tokens to withdraw\n */\n function withdraw(uint256 amount) external override {\n _burn(_msgSender(), amount);\n }\n\n // =============================================================================\n // ======================= New data added for the upgrade ======================\n // =============================================================================\n\n mapping(address => bool) public isMinter;\n /// @notice Reference to the treasury contract which can grant minting rights\n address public treasury;\n /// @notice Boolean to check whether the contract has been reinitialized after its upgrade\n bool public treasuryInitialized;\n\n using SafeERC20 for IERC20;\n\n /// @notice Base used for fee computation\n uint256 public constant BASE_PARAMS = 10 ** 9;\n\n // =============================== Bridging Data ===============================\n\n /// @notice Struct with some data about a specific bridge token\n struct BridgeDetails {\n // Limit on the balance of bridge token held by the contract: it is designed\n // to reduce the exposure of the system to hacks\n uint256 limit;\n // Limit on the hourly volume of token minted through this bridge\n // Technically the limit over a rolling hour is hourlyLimit x2 as hourly limit\n // is enforced only between x:00 and x+1:00\n uint256 hourlyLimit;\n // Fee taken for swapping in and out the token\n uint64 fee;\n // Whether the associated token is allowed or not\n bool allowed;\n // Whether swapping in and out from the associated token is paused or not\n bool paused;\n }\n\n /// @notice Maps a bridge token to data\n mapping(address => BridgeDetails) public bridges;\n /// @notice List of all bridge tokens\n address[] public bridgeTokensList;\n /// @notice Maps a bridge token to the associated hourly volume\n mapping(address => mapping(uint256 => uint256)) public usage;\n /// @notice Maps an address to whether it is exempt of fees for when it comes to swapping in and out\n mapping(address => uint256) public isFeeExempt;\n /// @notice Limit to the amount of tokens that can be sent from that chain to another chain\n uint256 public chainTotalHourlyLimit;\n /// @notice Usage per hour on that chain. Maps an hourly timestamp to the total volume swapped out on the chain\n mapping(uint256 => uint256) public chainTotalUsage;\n\n uint256[42] private __gap;\n\n // ================================== Events ===================================\n\n event BridgeTokenAdded(address indexed bridgeToken, uint256 limit, uint256 hourlyLimit, uint64 fee, bool paused);\n event BridgeTokenToggled(address indexed bridgeToken, bool toggleStatus);\n event BridgeTokenRemoved(address indexed bridgeToken);\n event BridgeTokenFeeUpdated(address indexed bridgeToken, uint64 fee);\n event BridgeTokenLimitUpdated(address indexed bridgeToken, uint256 limit);\n event BridgeTokenHourlyLimitUpdated(address indexed bridgeToken, uint256 hourlyLimit);\n event HourlyLimitUpdated(uint256 hourlyLimit);\n event FeeToggled(address indexed theAddress, uint256 toggleStatus);\n event KeeperToggled(address indexed keeper, bool toggleStatus);\n event MinterToggled(address indexed minter);\n event Recovered(address indexed token, address indexed to, uint256 amount);\n event TreasuryUpdated(address indexed _treasury);\n\n // ================================== Errors ===================================\n\n error AssetStillControlledInReserves();\n error BurnAmountExceedsAllowance();\n error HourlyLimitExceeded();\n error InvalidSender();\n error InvalidToken();\n error InvalidTreasury();\n error NotGovernor();\n error NotGovernorOrGuardian();\n error NotMinter();\n error NotTreasury();\n error TooBigAmount();\n error TooHighParameterValue();\n error TreasuryAlreadyInitialized();\n error ZeroAddress();\n\n /// @notice Checks to see if it is the `Treasury` calling this contract\n /// @dev There is no Access Control here, because it can be handled cheaply through this modifier\n modifier onlyTreasury() {\n if (msg.sender != treasury) revert NotTreasury();\n _;\n }\n\n /// @notice Checks whether the sender has the minting right\n modifier onlyMinter() {\n if (!isMinter[msg.sender]) revert NotMinter();\n _;\n }\n\n /// @notice Checks whether the `msg.sender` has the governor role or not\n modifier onlyGovernor() {\n if (!ITreasury(treasury).isGovernor(msg.sender)) revert NotGovernor();\n _;\n }\n\n /// @notice Checks whether the `msg.sender` has the governor role or the guardian role\n modifier onlyGovernorOrGuardian() {\n if (!ITreasury(treasury).isGovernorOrGuardian(msg.sender)) revert NotGovernorOrGuardian();\n _;\n }\n\n /// @notice Sets up the treasury contract on Polygon after the upgrade\n /// @param _treasury Address of the treasury contract\n function setUpTreasury(address _treasury) external {\n // Only governor on Polygon\n if (msg.sender != 0xdA2D2f638D6fcbE306236583845e5822554c02EA) revert NotGovernor();\n if (address(ITreasury(_treasury).stablecoin()) != address(this)) revert InvalidTreasury();\n if (treasuryInitialized) revert TreasuryAlreadyInitialized();\n treasury = _treasury;\n treasuryInitialized = true;\n emit TreasuryUpdated(_treasury);\n }\n\n // =========================== External Function ===============================\n\n /// @notice Allows anyone to burn agToken without redeeming collateral back\n /// @param amount Amount of stablecoins to burn\n /// @dev This function can typically be called if there is a settlement mechanism to burn stablecoins\n function burnStablecoin(uint256 amount) external {\n _burnCustom(msg.sender, amount);\n }\n\n // ======================= Minter Role Only Functions ==========================\n\n function burnSelf(uint256 amount, address burner) external onlyMinter {\n _burnCustom(burner, amount);\n }\n\n function burnFrom(uint256 amount, address burner, address sender) external onlyMinter {\n _burnFromNoRedeem(amount, burner, sender);\n }\n\n function mint(address account, uint256 amount) external onlyMinter {\n _mint(account, amount);\n }\n\n // ======================= Treasury Only Functions =============================\n\n function addMinter(address minter) external onlyTreasury {\n isMinter[minter] = true;\n emit MinterToggled(minter);\n }\n\n function removeMinter(address minter) external {\n if (msg.sender != address(treasury) && msg.sender != minter) revert InvalidSender();\n isMinter[minter] = false;\n emit MinterToggled(minter);\n }\n\n function setTreasury(address _treasury) external onlyTreasury {\n treasury = _treasury;\n emit TreasuryUpdated(_treasury);\n }\n\n // ============================ Internal Function ==============================\n\n /// @notice Internal version of the function `burnFromNoRedeem`\n /// @param amount Amount to burn\n /// @dev It is at the level of this function that allowance checks are performed\n function _burnFromNoRedeem(uint256 amount, address burner, address sender) internal {\n if (burner != sender) {\n uint256 currentAllowance = allowance(burner, sender);\n if (currentAllowance < amount) revert BurnAmountExceedsAllowance();\n _approve(burner, sender, currentAllowance - amount);\n }\n _burnCustom(burner, amount);\n }\n\n // ==================== External Permissionless Functions ======================\n\n /// @notice Returns the list of all supported bridge tokens\n /// @dev Helpful for UIs\n function allBridgeTokens() external view returns (address[] memory) {\n return bridgeTokensList;\n }\n\n /// @notice Returns the current volume for a bridge, for the current hour\n /// @dev Helpful for UIs\n function currentUsage(address bridge) external view returns (uint256) {\n return usage[bridge][block.timestamp / 3600];\n }\n\n /// @notice Returns the current total volume on the chain for the current hour\n /// @dev Helpful for UIs\n function currentTotalUsage() external view returns (uint256) {\n return chainTotalUsage[block.timestamp / 3600];\n }\n\n /// @notice Mints the canonical token from a supported bridge token\n /// @param bridgeToken Bridge token to use to mint\n /// @param amount Amount of bridge tokens to send\n /// @param to Address to which the stablecoin should be sent\n /// @dev Some fees may be taken by the protocol depending on the token used and on the address calling\n function swapIn(address bridgeToken, uint256 amount, address to) external returns (uint256) {\n BridgeDetails memory bridgeDetails = bridges[bridgeToken];\n if (!bridgeDetails.allowed || bridgeDetails.paused) revert InvalidToken();\n uint256 balance = IERC20(bridgeToken).balanceOf(address(this));\n if (balance + amount > bridgeDetails.limit) {\n // In case someone maliciously sends tokens to this contract\n // Or the limit changes\n if (bridgeDetails.limit > balance) amount = bridgeDetails.limit - balance;\n else {\n amount = 0;\n }\n }\n\n // Checking requirement on the hourly volume\n uint256 hour = block.timestamp / 3600;\n uint256 hourlyUsage = usage[bridgeToken][hour] + amount;\n if (hourlyUsage > bridgeDetails.hourlyLimit) {\n // Edge case when the hourly limit changes\n if (bridgeDetails.hourlyLimit > usage[bridgeToken][hour])\n amount = bridgeDetails.hourlyLimit - usage[bridgeToken][hour];\n else {\n amount = 0;\n }\n }\n usage[bridgeToken][hour] += amount;\n\n IERC20(bridgeToken).safeTransferFrom(msg.sender, address(this), amount);\n uint256 canonicalOut = amount;\n // Computing fees\n if (isFeeExempt[msg.sender] == 0) {\n canonicalOut -= (canonicalOut * bridgeDetails.fee) / BASE_PARAMS;\n }\n _mint(to, canonicalOut);\n return canonicalOut;\n }\n\n /// @notice Burns the canonical token in exchange for a bridge token\n /// @param bridgeToken Bridge token required\n /// @param amount Amount of canonical tokens to burn\n /// @param to Address to which the bridge token should be sent\n /// @dev Some fees may be taken by the protocol depending on the token used and on the address calling\n function swapOut(address bridgeToken, uint256 amount, address to) external returns (uint256) {\n BridgeDetails memory bridgeDetails = bridges[bridgeToken];\n if (!bridgeDetails.allowed || bridgeDetails.paused) revert InvalidToken();\n\n uint256 hour = block.timestamp / 3600;\n uint256 hourlyUsage = chainTotalUsage[hour] + amount;\n // If the amount being swapped out exceeds the limit, we revert\n // We don't want to change the amount being swapped out.\n // The user can decide to send another tx with the correct amount to reach the limit\n if (hourlyUsage > chainTotalHourlyLimit) revert HourlyLimitExceeded();\n chainTotalUsage[hour] = hourlyUsage;\n\n _burnCustom(msg.sender, amount);\n uint256 bridgeOut = amount;\n if (isFeeExempt[msg.sender] == 0) {\n bridgeOut -= (bridgeOut * bridgeDetails.fee) / BASE_PARAMS;\n }\n IERC20(bridgeToken).safeTransfer(to, bridgeOut);\n return bridgeOut;\n }\n\n // ======================= Governance Functions ================================\n\n /// @notice Adds support for a bridge token\n /// @param bridgeToken Bridge token to add: it should be a version of the stablecoin from another bridge\n /// @param limit Limit on the balance of bridge token this contract could hold\n /// @param hourlyLimit Limit on the hourly volume for this bridge\n /// @param paused Whether swapping for this token should be paused or not\n /// @param fee Fee taken upon swapping for or against this token\n function addBridgeToken(\n address bridgeToken,\n uint256 limit,\n uint256 hourlyLimit,\n uint64 fee,\n bool paused\n ) external onlyGovernor {\n if (bridges[bridgeToken].allowed || bridgeToken == address(0)) revert InvalidToken();\n if (fee > BASE_PARAMS) revert TooHighParameterValue();\n BridgeDetails memory _bridge;\n _bridge.limit = limit;\n _bridge.hourlyLimit = hourlyLimit;\n _bridge.paused = paused;\n _bridge.fee = fee;\n _bridge.allowed = true;\n bridges[bridgeToken] = _bridge;\n bridgeTokensList.push(bridgeToken);\n emit BridgeTokenAdded(bridgeToken, limit, hourlyLimit, fee, paused);\n }\n\n /// @notice Removes support for a token\n /// @param bridgeToken Address of the bridge token to remove support for\n function removeBridgeToken(address bridgeToken) external onlyGovernor {\n if (IERC20(bridgeToken).balanceOf(address(this)) != 0) revert AssetStillControlledInReserves();\n delete bridges[bridgeToken];\n // Deletion from `bridgeTokensList` loop\n uint256 bridgeTokensListLength = bridgeTokensList.length;\n for (uint256 i; i < bridgeTokensListLength - 1; ++i) {\n if (bridgeTokensList[i] == bridgeToken) {\n // Replace the `bridgeToken` to remove with the last of the list\n bridgeTokensList[i] = bridgeTokensList[bridgeTokensListLength - 1];\n break;\n }\n }\n // Remove last element in array\n bridgeTokensList.pop();\n emit BridgeTokenRemoved(bridgeToken);\n }\n\n /// @notice Recovers any ERC20 token\n /// @dev Can be used to withdraw bridge tokens for them to be de-bridged on mainnet\n function recoverERC20(address tokenAddress, address to, uint256 amountToRecover) external onlyGovernor {\n IERC20(tokenAddress).safeTransfer(to, amountToRecover);\n emit Recovered(tokenAddress, to, amountToRecover);\n }\n\n /// @notice Updates the `limit` amount for `bridgeToken`\n function setLimit(address bridgeToken, uint256 limit) external onlyGovernorOrGuardian {\n if (!bridges[bridgeToken].allowed) revert InvalidToken();\n bridges[bridgeToken].limit = limit;\n emit BridgeTokenLimitUpdated(bridgeToken, limit);\n }\n\n /// @notice Updates the `hourlyLimit` amount for `bridgeToken`\n function setHourlyLimit(address bridgeToken, uint256 hourlyLimit) external onlyGovernorOrGuardian {\n if (!bridges[bridgeToken].allowed) revert InvalidToken();\n bridges[bridgeToken].hourlyLimit = hourlyLimit;\n emit BridgeTokenHourlyLimitUpdated(bridgeToken, hourlyLimit);\n }\n\n /// @notice Updates the `chainTotalHourlyLimit` amount\n function setChainTotalHourlyLimit(uint256 hourlyLimit) external onlyGovernorOrGuardian {\n chainTotalHourlyLimit = hourlyLimit;\n emit HourlyLimitUpdated(hourlyLimit);\n }\n\n /// @notice Updates the `fee` value for `bridgeToken`\n function setSwapFee(address bridgeToken, uint64 fee) external onlyGovernorOrGuardian {\n if (!bridges[bridgeToken].allowed) revert InvalidToken();\n if (fee > BASE_PARAMS) revert TooHighParameterValue();\n bridges[bridgeToken].fee = fee;\n emit BridgeTokenFeeUpdated(bridgeToken, fee);\n }\n\n /// @notice Pauses or unpauses swapping in and out for a token\n function toggleBridge(address bridgeToken) external onlyGovernorOrGuardian {\n if (!bridges[bridgeToken].allowed) revert InvalidToken();\n bool pausedStatus = bridges[bridgeToken].paused;\n bridges[bridgeToken].paused = !pausedStatus;\n emit BridgeTokenToggled(bridgeToken, !pausedStatus);\n }\n\n /// @notice Toggles fees for the address `theAddress`\n function toggleFeesForAddress(address theAddress) external onlyGovernorOrGuardian {\n uint256 feeExemptStatus = 1 - isFeeExempt[theAddress];\n isFeeExempt[theAddress] = feeExemptStatus;\n emit FeeToggled(theAddress, feeExemptStatus);\n }\n}\n" + }, + "contracts/agToken/polygon/utils/ERC20UpgradeableCustom.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (token/ERC20/ERC20.sol)\n\npragma solidity ^0.8.0;\n\nimport \"@openzeppelin/contracts-upgradeable/token/ERC20/IERC20Upgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/token/ERC20/extensions/IERC20MetadataUpgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/utils/ContextUpgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol\";\n\n/**\n * @dev Implementation of the {IERC20} interface modified by Angle Labs, Inc.\n *\n * This implementation has a custom burn function to avoid having a {Transfer} event to the zero address\n * in some specific burn cases to avoid having Polygon PoS bridge catching this event\n *\n * TIP: For a detailed writeup see our guide\n * https://forum.zeppelin.solutions/t/how-to-implement-erc20-supply-mechanisms/226[How\n * to implement supply mechanisms].\n *\n * We have followed general OpenZeppelin Contracts guidelines: functions revert\n * instead returning `false` on failure. This behavior is nonetheless\n * conventional and does not conflict with the expectations of ERC20\n * applications.\n *\n * Additionally, an {Approval} event is emitted on calls to {transferFrom}.\n * This allows applications to reconstruct the allowance for all accounts just\n * by listening to said events. Other implementations of the EIP may not emit\n * these events, as it isn't required by the specification.\n *\n * Finally, the non-standard {decreaseAllowance} and {increaseAllowance}\n * functions have been added to mitigate the well-known issues around setting\n * allowances. See {IERC20-approve}.\n */\ncontract ERC20UpgradeableCustom is Initializable, ContextUpgradeable, IERC20Upgradeable, IERC20MetadataUpgradeable {\n mapping(address => uint256) private _balances;\n\n mapping(address => mapping(address => uint256)) private _allowances;\n\n uint256 private _totalSupply;\n\n string private _name;\n string private _symbol;\n\n /**\n * @dev Sets the values for {name} and {symbol}.\n *\n * The default value of {decimals} is 18. To select a different value for\n * {decimals} you should overload it.\n *\n * All two of these values are immutable: they can only be set once during\n * construction.\n */\n //solhint-disable-next-line\n function __ERC20_init(string memory name_, string memory symbol_) internal onlyInitializing {\n __Context_init_unchained();\n __ERC20_init_unchained(name_, symbol_);\n }\n\n //solhint-disable-next-line\n function __ERC20_init_unchained(string memory name_, string memory symbol_) internal onlyInitializing {\n _name = name_;\n _symbol = symbol_;\n }\n\n /**\n * @dev Returns the name of the token.\n */\n function name() public view virtual override returns (string memory) {\n return _name;\n }\n\n /**\n * @dev Returns the symbol of the token, usually a shorter version of the\n * name.\n */\n function symbol() public view virtual override returns (string memory) {\n return _symbol;\n }\n\n /**\n * @dev Returns the number of decimals used to get its user representation.\n * For example, if `decimals` equals `2`, a balance of `505` tokens should\n * be displayed to a user as `5.05` (`505 / 10 ** 2`).\n *\n * Tokens usually opt for a value of 18, imitating the relationship between\n * Ether and Wei. This is the value {ERC20} uses, unless this function is\n * overridden;\n *\n * NOTE: This information is only used for _display_ purposes: it in\n * no way affects any of the arithmetic of the contract, including\n * {IERC20-balanceOf} and {IERC20-transfer}.\n */\n function decimals() public view virtual override returns (uint8) {\n return 18;\n }\n\n /**\n * @dev See {IERC20-totalSupply}.\n */\n function totalSupply() public view virtual override returns (uint256) {\n return _totalSupply;\n }\n\n /**\n * @dev See {IERC20-balanceOf}.\n */\n function balanceOf(address account) public view virtual override returns (uint256) {\n return _balances[account];\n }\n\n /**\n * @dev See {IERC20-transfer}.\n *\n * Requirements:\n *\n * - `recipient` cannot be the zero address.\n * - the caller must have a balance of at least `amount`.\n */\n function transfer(address recipient, uint256 amount) public virtual override returns (bool) {\n _transfer(_msgSender(), recipient, amount);\n return true;\n }\n\n /**\n * @dev See {IERC20-allowance}.\n */\n function allowance(address owner, address spender) public view virtual override returns (uint256) {\n return _allowances[owner][spender];\n }\n\n /**\n * @dev See {IERC20-approve}.\n *\n * Requirements:\n *\n * - `spender` cannot be the zero address.\n */\n function approve(address spender, uint256 amount) public virtual override returns (bool) {\n _approve(_msgSender(), spender, amount);\n return true;\n }\n\n /**\n * @dev See {IERC20-transferFrom}.\n *\n * Emits an {Approval} event indicating the updated allowance. This is not\n * required by the EIP. See the note at the beginning of {ERC20}.\n *\n * Requirements:\n *\n * - `sender` and `recipient` cannot be the zero address.\n * - `sender` must have a balance of at least `amount`.\n * - the caller must have allowance for `sender`'s tokens of at least\n * `amount`.\n */\n function transferFrom(address sender, address recipient, uint256 amount) public virtual override returns (bool) {\n _transfer(sender, recipient, amount);\n\n uint256 currentAllowance = _allowances[sender][_msgSender()];\n require(currentAllowance >= amount, \"ERC20: transfer amount exceeds allowance\");\n unchecked {\n _approve(sender, _msgSender(), currentAllowance - amount);\n }\n\n return true;\n }\n\n /**\n * @dev Atomically increases the allowance granted to `spender` by the caller.\n *\n * This is an alternative to {approve} that can be used as a mitigation for\n * problems described in {IERC20-approve}.\n *\n * Emits an {Approval} event indicating the updated allowance.\n *\n * Requirements:\n *\n * - `spender` cannot be the zero address.\n */\n function increaseAllowance(address spender, uint256 addedValue) public virtual returns (bool) {\n _approve(_msgSender(), spender, _allowances[_msgSender()][spender] + addedValue);\n return true;\n }\n\n /**\n * @dev Atomically decreases the allowance granted to `spender` by the caller.\n *\n * This is an alternative to {approve} that can be used as a mitigation for\n * problems described in {IERC20-approve}.\n *\n * Emits an {Approval} event indicating the updated allowance.\n *\n * Requirements:\n *\n * - `spender` cannot be the zero address.\n * - `spender` must have allowance for the caller of at least\n * `subtractedValue`.\n */\n function decreaseAllowance(address spender, uint256 subtractedValue) public virtual returns (bool) {\n uint256 currentAllowance = _allowances[_msgSender()][spender];\n require(currentAllowance >= subtractedValue, \"ERC20: decreased allowance below zero\");\n unchecked {\n _approve(_msgSender(), spender, currentAllowance - subtractedValue);\n }\n\n return true;\n }\n\n /**\n * @dev Moves `amount` of tokens from `sender` to `recipient`.\n *\n * This internal function is equivalent to {transfer}, and can be used to\n * e.g. implement automatic token fees, slashing mechanisms, etc.\n *\n * Emits a {Transfer} event.\n *\n * Requirements:\n *\n * - `sender` cannot be the zero address.\n * - `recipient` cannot be the zero address.\n * - `sender` must have a balance of at least `amount`.\n */\n function _transfer(address sender, address recipient, uint256 amount) internal virtual {\n require(sender != address(0), \"ERC20: transfer from the zero address\");\n require(recipient != address(0), \"ERC20: transfer to the zero address\");\n\n _beforeTokenTransfer(sender, recipient, amount);\n\n uint256 senderBalance = _balances[sender];\n require(senderBalance >= amount, \"ERC20: transfer amount exceeds balance\");\n unchecked {\n _balances[sender] = senderBalance - amount;\n }\n _balances[recipient] += amount;\n\n emit Transfer(sender, recipient, amount);\n\n _afterTokenTransfer(sender, recipient, amount);\n }\n\n /** @dev Creates `amount` tokens and assigns them to `account`, increasing\n * the total supply.\n *\n * Emits a {Transfer} event with `from` set to the zero address.\n *\n * Requirements:\n *\n * - `account` cannot be the zero address.\n */\n function _mint(address account, uint256 amount) internal virtual {\n require(account != address(0), \"ERC20: mint to the zero address\");\n\n _beforeTokenTransfer(address(0), account, amount);\n\n _totalSupply += amount;\n _balances[account] += amount;\n emit Transfer(address(0), account, amount);\n\n _afterTokenTransfer(address(0), account, amount);\n }\n\n /**\n * @dev Destroys `amount` tokens from `account`, reducing the\n * total supply.\n *\n * Emits a {Transfer} event with `to` set to the zero address.\n *\n * Requirements:\n *\n * - `account` cannot be the zero address.\n * - `account` must have at least `amount` tokens.\n */\n function _burn(address account, uint256 amount) internal virtual {\n require(account != address(0), \"ERC20: burn from the zero address\");\n\n _beforeTokenTransfer(account, address(0), amount);\n\n uint256 accountBalance = _balances[account];\n require(accountBalance >= amount, \"ERC20: burn amount exceeds balance\");\n unchecked {\n _balances[account] = accountBalance - amount;\n }\n _totalSupply -= amount;\n\n emit Transfer(account, address(0), amount);\n\n _afterTokenTransfer(account, address(0), amount);\n }\n\n /**\n * @dev Destroys `amount` tokens from `account`, reducing the\n * total supply.\n *\n * Contrary to the other `burn` function, the {Transfer} event is not to the zero address\n * but rather to this address: the reason is that not all burn events should be caught up\n * by the PoS bridge\n *\n * Requirements:\n *\n * - `account` cannot be the zero address.\n * - `account` must have at least `amount` tokens.\n */\n function _burnCustom(address account, uint256 amount) internal virtual {\n require(account != address(0), \"ERC20: burn from the zero address\");\n\n _beforeTokenTransfer(account, address(0), amount);\n\n uint256 accountBalance = _balances[account];\n require(accountBalance >= amount, \"ERC20: burn amount exceeds balance\");\n unchecked {\n _balances[account] = accountBalance - amount;\n }\n _totalSupply -= amount;\n\n emit Transfer(account, address(this), amount);\n\n _afterTokenTransfer(account, address(0), amount);\n }\n\n /**\n * @dev Sets `amount` as the allowance of `spender` over the `owner` s tokens.\n *\n * This internal function is equivalent to `approve`, and can be used to\n * e.g. set automatic allowances for certain subsystems, etc.\n *\n * Emits an {Approval} event.\n *\n * Requirements:\n *\n * - `owner` cannot be the zero address.\n * - `spender` cannot be the zero address.\n */\n function _approve(address owner, address spender, uint256 amount) internal virtual {\n require(owner != address(0), \"ERC20: approve from the zero address\");\n require(spender != address(0), \"ERC20: approve to the zero address\");\n\n _allowances[owner][spender] = amount;\n emit Approval(owner, spender, amount);\n }\n\n /**\n * @dev Hook that is called before any transfer of tokens. This includes\n * minting and burning.\n *\n * Calling conditions:\n *\n * - when `from` and `to` are both non-zero, `amount` of `from`'s tokens\n * will be transferred to `to`.\n * - when `from` is zero, `amount` tokens will be minted for `to`.\n * - when `to` is zero, `amount` of `from`'s tokens will be burned.\n * - `from` and `to` are never both zero.\n *\n * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].\n */\n function _beforeTokenTransfer(address from, address to, uint256 amount) internal virtual {}\n\n /**\n * @dev Hook that is called after any transfer of tokens. This includes\n * minting and burning.\n *\n * Calling conditions:\n *\n * - when `from` and `to` are both non-zero, `amount` of `from`'s tokens\n * has been transferred to `to`.\n * - when `from` is zero, `amount` tokens have been minted for `to`.\n * - when `to` is zero, `amount` of `from`'s tokens have been burned.\n * - `from` and `to` are never both zero.\n *\n * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].\n */\n function _afterTokenTransfer(address from, address to, uint256 amount) internal virtual {}\n\n uint256[45] private __gap;\n}\n" + }, + "contracts/coreBorrow/CoreBorrow.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\n/*\n * █ \n ***** ▓▓▓ \n * ▓▓▓▓▓▓▓ \n * ///. ▓▓▓▓▓▓▓▓▓▓▓▓▓ \n ***** //////// ▓▓▓▓▓▓▓ \n * ///////////// ▓▓▓ \n ▓▓ ////////////////// █ ▓▓ \n ▓▓ ▓▓ /////////////////////// ▓▓ ▓▓ \n ▓▓ ▓▓ //////////////////////////// ▓▓ ▓▓ \n ▓▓ ▓▓ /////////▓▓▓///////▓▓▓///////// ▓▓ ▓▓ \n ▓▓ ,////////////////////////////////////// ▓▓ ▓▓ \n ▓▓ ////////////////////////////////////////// ▓▓ \n ▓▓ //////////////////////▓▓▓▓///////////////////// \n ,//////////////////////////////////////////////////// \n .////////////////////////////////////////////////////////// \n .//////////////////////////██.,//////////////////////////█ \n .//////////////////////████..,./////////////////////██ \n ...////////////////███████.....,.////////////////███ \n ,.,////////////████████ ........,///////////████ \n .,.,//////█████████ ,.......///////████ \n ,..//████████ ........./████ \n ..,██████ .....,███ \n .██ ,.,█ \n \n \n \n ▓▓ ▓▓▓▓▓▓▓▓▓▓ ▓▓▓▓▓▓▓▓▓▓ ▓▓ ▓▓▓▓▓▓▓▓▓▓ \n ▓▓▓▓▓▓ ▓▓▓ ▓▓▓ ▓▓▓ ▓▓ ▓▓ ▓▓▓▓ \n ▓▓▓ ▓▓▓ ▓▓▓ ▓▓▓ ▓▓▓ ▓▓▓ ▓▓ ▓▓▓▓▓ \n ▓▓▓ ▓▓ ▓▓▓ ▓▓▓ ▓▓▓▓▓▓▓▓▓▓ ▓▓▓▓▓▓▓▓▓▓ ▓▓▓▓▓▓▓▓▓▓ \n*/\n\npragma solidity ^0.8.12;\n\nimport \"@openzeppelin/contracts-upgradeable/access/AccessControlEnumerableUpgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol\";\n\nimport \"../interfaces/ICoreBorrow.sol\";\nimport \"../interfaces/IFlashAngle.sol\";\nimport \"../interfaces/ITreasury.sol\";\n\n/// @title CoreBorrow\n/// @author Angle Labs, Inc.\n/// @notice Core contract of the borrowing module. This contract handles the access control across all contracts\n/// (it is read by all treasury contracts), and manages the `flashLoanModule`. It has no minting rights over the\n/// stablecoin contracts\ncontract CoreBorrow is ICoreBorrow, Initializable, AccessControlEnumerableUpgradeable {\n /// @notice Role for guardians\n bytes32 public constant GUARDIAN_ROLE = keccak256(\"GUARDIAN_ROLE\");\n /// @notice Role for governors\n bytes32 public constant GOVERNOR_ROLE = keccak256(\"GOVERNOR_ROLE\");\n /// @notice Role for treasury contract\n bytes32 public constant FLASHLOANER_TREASURY_ROLE = keccak256(\"FLASHLOANER_TREASURY_ROLE\");\n\n // ============================= Reference =====================================\n\n /// @notice Reference to the `flashLoanModule` with minting rights over the different stablecoins of the protocol\n address public flashLoanModule;\n\n // =============================== Events ======================================\n\n event FlashLoanModuleUpdated(address indexed _flashloanModule);\n event CoreUpdated(address indexed _core);\n\n // =============================== Errors ======================================\n\n error InvalidCore();\n error IncompatibleGovernorAndGuardian();\n error NotEnoughGovernorsLeft();\n error ZeroAddress();\n\n /// @notice Initializes the `CoreBorrow` contract and the access control of the borrowing module\n /// @param governor Address of the governor of the Angle Protocol\n /// @param guardian Guardian address of the protocol\n function initialize(address governor, address guardian) public initializer {\n if (governor == address(0) || guardian == address(0)) revert ZeroAddress();\n if (governor == guardian) revert IncompatibleGovernorAndGuardian();\n _setupRole(GOVERNOR_ROLE, governor);\n _setupRole(GUARDIAN_ROLE, guardian);\n _setupRole(GUARDIAN_ROLE, governor);\n _setRoleAdmin(GUARDIAN_ROLE, GOVERNOR_ROLE);\n _setRoleAdmin(GOVERNOR_ROLE, GOVERNOR_ROLE);\n _setRoleAdmin(FLASHLOANER_TREASURY_ROLE, GOVERNOR_ROLE);\n }\n\n /// @custom:oz-upgrades-unsafe-allow constructor\n constructor() initializer {}\n\n // =========================== View Functions ==================================\n\n /// @inheritdoc ICoreBorrow\n function isFlashLoanerTreasury(address treasury) external view returns (bool) {\n return hasRole(FLASHLOANER_TREASURY_ROLE, treasury);\n }\n\n /// @inheritdoc ICoreBorrow\n function isGovernor(address admin) external view returns (bool) {\n return hasRole(GOVERNOR_ROLE, admin);\n }\n\n /// @inheritdoc ICoreBorrow\n function isGovernorOrGuardian(address admin) external view returns (bool) {\n return hasRole(GUARDIAN_ROLE, admin);\n }\n\n // =========================== Governor Functions ==============================\n\n /// @notice Grants the `FLASHLOANER_TREASURY_ROLE` to a `treasury` contract\n /// @param treasury Contract to grant the role to\n /// @dev This function can be used to allow flash loans on a stablecoin of the protocol\n function addFlashLoanerTreasuryRole(address treasury) external {\n grantRole(FLASHLOANER_TREASURY_ROLE, treasury);\n address _flashLoanModule = flashLoanModule;\n if (_flashLoanModule != address(0)) {\n // This call will revert if `treasury` is the zero address or if it is not linked\n // to this `CoreBorrow` contract\n ITreasury(treasury).setFlashLoanModule(_flashLoanModule);\n IFlashAngle(_flashLoanModule).addStablecoinSupport(treasury);\n }\n }\n\n /// @notice Adds a governor in the protocol\n /// @param governor Address to grant the role to\n /// @dev It is necessary to call this function to grant a governor role to make sure\n /// all governors also have the guardian role\n function addGovernor(address governor) external {\n grantRole(GOVERNOR_ROLE, governor);\n grantRole(GUARDIAN_ROLE, governor);\n }\n\n /// @notice Revokes the flash loan ability for a stablecoin\n /// @param treasury Treasury address associated with the stablecoin for which flash loans\n /// should no longer be available\n function removeFlashLoanerTreasuryRole(address treasury) external {\n revokeRole(FLASHLOANER_TREASURY_ROLE, treasury);\n ITreasury(treasury).setFlashLoanModule(address(0));\n address _flashLoanModule = flashLoanModule;\n if (_flashLoanModule != address(0)) {\n IFlashAngle(flashLoanModule).removeStablecoinSupport(treasury);\n }\n }\n\n /// @notice Revokes a governor from the protocol\n /// @param governor Address to remove the role to\n /// @dev It is necessary to call this function to remove a governor role to make sure\n /// the address also loses its guardian role\n function removeGovernor(address governor) external {\n if (getRoleMemberCount(GOVERNOR_ROLE) <= 1) revert NotEnoughGovernorsLeft();\n revokeRole(GUARDIAN_ROLE, governor);\n revokeRole(GOVERNOR_ROLE, governor);\n }\n\n /// @notice Changes the `flashLoanModule` of the protocol\n /// @param _flashLoanModule Address of the new flash loan module\n function setFlashLoanModule(address _flashLoanModule) external onlyRole(GOVERNOR_ROLE) {\n if (_flashLoanModule != address(0)) {\n if (address(IFlashAngle(_flashLoanModule).core()) != address(this)) revert InvalidCore();\n }\n uint256 count = getRoleMemberCount(FLASHLOANER_TREASURY_ROLE);\n for (uint256 i; i < count; ++i) {\n ITreasury(getRoleMember(FLASHLOANER_TREASURY_ROLE, i)).setFlashLoanModule(_flashLoanModule);\n }\n flashLoanModule = _flashLoanModule;\n emit FlashLoanModuleUpdated(_flashLoanModule);\n }\n\n /// @notice Changes the core contract of the protocol\n /// @param _core New core contract\n /// @dev This function verifies that all governors of the current core contract are also governors\n /// of the new core contract. It also notifies the `flashLoanModule` of the change.\n /// @dev Governance wishing to change the core contract should also make sure to call `setCore`\n /// in the different treasury contracts\n function setCore(ICoreBorrow _core) external onlyRole(GOVERNOR_ROLE) {\n uint256 count = getRoleMemberCount(GOVERNOR_ROLE);\n bool success;\n for (uint256 i; i < count; ++i) {\n success = _core.isGovernor(getRoleMember(GOVERNOR_ROLE, i));\n if (!success) break;\n }\n if (!success) revert InvalidCore();\n address _flashLoanModule = flashLoanModule;\n if (_flashLoanModule != address(0)) IFlashAngle(_flashLoanModule).setCore(address(_core));\n emit CoreUpdated(address(_core));\n }\n}\n" + }, + "contracts/deprecated/AgTokenIntermediateUpgrade.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\nimport \"../interfaces/IAgToken.sol\";\nimport \"../interfaces/coreModule/IStableMaster.sol\";\n// OpenZeppelin may update its version of the ERC20PermitUpgradeable token\nimport \"@openzeppelin/contracts-upgradeable/token/ERC20/extensions/draft-ERC20PermitUpgradeable.sol\";\n\n/// @title AgTokenIntermediateUpgrade\n/// @author Angle Labs, Inc.\n/// @notice Base contract for agToken, that is to say Angle's stablecoins\n/// @dev This contract is used to create and handle the stablecoins of Angle protocol\n/// @dev It is still possible for any address to burn its agTokens without redeeming collateral in exchange\n/// @dev This contract is the upgraded version of the AgToken that was first deployed on Ethereum mainnet and is used to\n/// add other minters as needed by AMOs\ncontract AgTokenIntermediateUpgrade is ERC20PermitUpgradeable {\n // ========================= References to other contracts =====================\n\n /// @notice Reference to the `StableMaster` contract associated to this `AgToken`\n address public stableMaster;\n\n // ============================= Constructor ===================================\n\n /// @notice Initializes the `AgToken` contract\n /// @param name_ Name of the token\n /// @param symbol_ Symbol of the token\n /// @param stableMaster_ Reference to the `StableMaster` contract associated to this agToken\n /// @dev By default, agTokens are ERC-20 tokens with 18 decimals\n function initialize(string memory name_, string memory symbol_, address stableMaster_) external initializer {\n __ERC20Permit_init(name_);\n __ERC20_init(name_, symbol_);\n require(stableMaster_ != address(0), \"0\");\n stableMaster = stableMaster_;\n }\n\n /// @custom:oz-upgrades-unsafe-allow constructor\n constructor() initializer {}\n\n // ======= Added Parameters and Variables from the first implementation ========\n\n /// @notice Checks whether an address has the right to mint agTokens\n mapping(address => bool) public isMinter;\n\n // =============================== Added Events ================================\n\n event MinterToggled(address indexed minter);\n\n // =============================== Setup Function ==============================\n\n /// @notice Sets up the minter role and gives it to the governor\n /// @dev This function just has to be called once\n function setUpMinter() external {\n address governor = 0xdC4e6DFe07EFCa50a197DF15D9200883eF4Eb1c8;\n require(msg.sender == governor);\n isMinter[governor] = true;\n emit MinterToggled(governor);\n }\n\n // =============================== Modifiers ===================================\n\n /// @notice Checks whether the sender has the minting right\n modifier onlyMinter() {\n require(isMinter[msg.sender] || msg.sender == stableMaster, \"35\");\n _;\n }\n\n // ========================= External Functions ================================\n // The following functions allow anyone to burn stablecoins without redeeming collateral\n // in exchange for that\n\n /// @notice Destroys `amount` token from the caller without giving collateral back\n /// @param amount Amount to burn\n /// @param poolManager Reference to the `PoolManager` contract for which the `stocksUsers` will\n /// need to be updated\n /// @dev When calling this function, people should specify the `poolManager` for which they want to decrease\n /// the `stocksUsers`: this is a way for the protocol to maintain healthy accounting variables\n function burnNoRedeem(uint256 amount, address poolManager) external {\n _burn(msg.sender, amount);\n IStableMaster(stableMaster).updateStocksUsers(amount, poolManager);\n }\n\n /// @notice Burns `amount` of agToken on behalf of another account without redeeming collateral back\n /// @param account Account to burn on behalf of\n /// @param amount Amount to burn\n /// @param poolManager Reference to the `PoolManager` contract for which the `stocksUsers` will need to be updated\n function burnFromNoRedeem(address account, uint256 amount, address poolManager) external {\n _burnFromNoRedeem(amount, account, msg.sender);\n IStableMaster(stableMaster).updateStocksUsers(amount, poolManager);\n }\n\n // ======================= Minter Role Only Functions ==========================\n\n /// @notice Burns `amount` tokens from a `burner` address\n /// @param amount Amount of tokens to burn\n /// @param burner Address to burn from\n /// @dev This method is to be called by a contract with a minter right on the AgToken after being\n /// requested to do so by an address willing to burn tokens from its address\n function burnSelf(uint256 amount, address burner) external onlyMinter {\n _burn(burner, amount);\n }\n\n /// @notice Burns `amount` tokens from a `burner` address after being asked to by `sender`\n /// @param amount Amount of tokens to burn\n /// @param burner Address to burn from\n /// @param sender Address which requested the burn from `burner`\n /// @dev This method is to be called by a contract with the minter right after being requested\n /// to do so by a `sender` address willing to burn tokens from another `burner` address\n /// @dev The method checks the allowance between the `sender` and the `burner`\n function burnFrom(uint256 amount, address burner, address sender) external onlyMinter {\n _burnFromNoRedeem(amount, burner, sender);\n }\n\n /// @notice Lets the `StableMaster` contract or another whitelisted contract mint agTokens\n /// @param account Address to mint to\n /// @param amount Amount to mint\n /// @dev The contracts allowed to issue agTokens are the `StableMaster` contract, `VaultManager` contracts\n /// associated to this stablecoin as well as the flash loan module (if activated) and potentially contracts\n /// whitelisted by governance\n function mint(address account, uint256 amount) external onlyMinter {\n _mint(account, amount);\n }\n\n // ======================= Minter Only Functions ===============================\n\n /// @notice Adds a minter in the contract\n /// @param minter Minter address to add\n function addMinter(address minter) external onlyMinter {\n isMinter[minter] = true;\n emit MinterToggled(minter);\n }\n\n /// @notice Removes a minter from the contract\n /// @param minter Minter address to remove\n /// @dev This function can at the moment only be called by a minter wishing to revoke itself\n function removeMinter(address minter) external {\n require(msg.sender == minter && isMinter[msg.sender], \"36\");\n isMinter[minter] = false;\n emit MinterToggled(minter);\n }\n\n // ============================ Internal Function ==============================\n\n /// @notice Internal version of the function `burnFromNoRedeem`\n /// @param amount Amount to burn\n /// @dev It is at the level of this function that allowance checks are performed\n function _burnFromNoRedeem(uint256 amount, address burner, address sender) internal {\n if (burner != sender) {\n uint256 currentAllowance = allowance(burner, sender);\n require(currentAllowance >= amount, \"23\");\n _approve(burner, sender, currentAllowance - amount);\n }\n _burn(burner, amount);\n }\n}\n" + }, + "contracts/deprecated/layerZero/OldLayerZeroBridgeToken.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.12;\n\nimport \"./OldOFTCore.sol\";\nimport \"../../interfaces/IAgTokenSideChainMultiBridge.sol\";\nimport \"@openzeppelin/contracts-upgradeable/security/PausableUpgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/token/ERC20/ERC20Upgradeable.sol\";\n\n/// @title LayerZeroBridgeToken\n/// @author Angle Labs, Inc., forked from https://github.com/LayerZero-Labs/solidity-examples/blob/main/contracts/token/oft/OFT.sol\n/// @notice Contract to be deployed on a L2/sidechain for bridging an AgToken using a bridge intermediate token and LayerZero\ncontract OldLayerZeroBridgeToken is OldOFTCore, ERC20Upgradeable, PausableUpgradeable {\n /// @notice Address of the bridgeable token\n /// @dev Immutable\n IAgTokenSideChainMultiBridge public canonicalToken;\n\n // =============================== Errors ================================\n\n error InvalidAllowance();\n\n // ============================= Constructor ===================================\n\n /// @notice Initializes the contract\n /// @param _name Name of the token corresponding to this contract\n /// @param _symbol Symbol of the token corresponding to this contract\n /// @param _lzEndpoint Layer zero endpoint to pass messages\n /// @param _treasury Address of the treasury contract used for access control\n /// @param initialSupply Initial supply to mint to the canonical token address\n /// @dev The initial supply corresponds to the initial amount that could be bridged using this OFT\n function initialize(\n string memory _name,\n string memory _symbol,\n address _lzEndpoint,\n address _treasury,\n uint256 initialSupply\n ) external initializer {\n __ERC20_init_unchained(_name, _symbol);\n __LzAppUpgradeable_init(_lzEndpoint, _treasury);\n\n canonicalToken = IAgTokenSideChainMultiBridge(address(ITreasury(_treasury).stablecoin()));\n _approve(address(this), address(canonicalToken), type(uint256).max);\n _mint(address(canonicalToken), initialSupply);\n }\n\n /// @custom:oz-upgrades-unsafe-allow constructor\n constructor() initializer {}\n\n // ==================== External Permissionless Functions ======================\n\n function sendWithPermit(\n uint16 _dstChainId,\n bytes memory _toAddress,\n uint256 _amount,\n address payable _refundAddress,\n address _zroPaymentAddress,\n bytes memory _adapterParams,\n uint256 deadline,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) public payable override {\n canonicalToken.permit(msg.sender, address(this), _amount, deadline, v, r, s);\n send(_dstChainId, _toAddress, _amount, _refundAddress, _zroPaymentAddress, _adapterParams);\n }\n\n function withdraw(uint256 amount, address recipient) external override returns (uint256 amountMinted) {\n // Does not check allowances as transfers from `msg.sender`\n _transfer(msg.sender, address(this), amount);\n amountMinted = canonicalToken.swapIn(address(this), amount, recipient);\n uint256 leftover = balanceOf(address(this));\n if (leftover != 0) {\n _transfer(address(this), msg.sender, leftover);\n }\n }\n\n // ============================= Internal Functions ===================================\n\n function _debitFrom(\n uint16,\n bytes memory,\n uint256 _amount\n ) internal override whenNotPaused returns (uint256 amountSwapped) {\n // No need to use safeTransferFrom as we know this implementation reverts on failure\n canonicalToken.transferFrom(msg.sender, address(this), _amount);\n\n // Swap canonical for this bridge token. There may be some fees\n amountSwapped = canonicalToken.swapOut(address(this), _amount, address(this));\n _burn(address(this), amountSwapped);\n }\n\n function _debitCreditFrom(uint16, bytes memory, uint256 _amount) internal override whenNotPaused returns (uint256) {\n _burn(msg.sender, _amount);\n return _amount;\n }\n\n function _creditTo(\n uint16,\n address _toAddress,\n uint256 _amount\n ) internal override whenNotPaused returns (uint256 amountMinted) {\n _mint(address(this), _amount);\n amountMinted = canonicalToken.swapIn(address(this), _amount, _toAddress);\n uint256 leftover = balanceOf(address(this));\n if (leftover != 0) {\n _transfer(address(this), _toAddress, leftover);\n }\n }\n\n // ======================= View Functions ================================\n\n /// @inheritdoc ERC165Upgradeable\n function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {\n return\n interfaceId == type(IOFT).interfaceId ||\n interfaceId == type(IERC20).interfaceId ||\n super.supportsInterface(interfaceId);\n }\n\n // ======================= Governance Functions ================================\n\n /// @notice Mints the intermediate contract to the `canonicalToken`\n /// @dev Used to increase the bridging capacity\n function mint(uint256 amount) external onlyGovernorOrGuardian {\n _mint(address(canonicalToken), amount);\n }\n\n /// @notice Burns the intermediate contract from the `canonicalToken`\n /// @dev Used to decrease the bridging capacity\n function burn(uint256 amount) external onlyGovernorOrGuardian {\n _burn(address(canonicalToken), amount);\n }\n\n /// @notice Increases allowance of the `canonicalToken`\n function setupAllowance() public onlyGovernorOrGuardian {\n _approve(address(this), address(canonicalToken), type(uint256).max);\n }\n\n /// @notice Pauses bridging through the contract\n /// @param pause Future pause status\n function pauseSendTokens(bool pause) external onlyGovernorOrGuardian {\n pause ? _pause() : _unpause();\n }\n\n uint256[49] private __gap;\n}\n" + }, + "contracts/deprecated/layerZero/OldNonblockingLzApp.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.12;\n\nimport \"@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol\";\nimport \"../../interfaces/external/layerZero/ILayerZeroReceiver.sol\";\nimport \"../../interfaces/external/layerZero/ILayerZeroUserApplicationConfig.sol\";\nimport \"../../interfaces/external/layerZero/ILayerZeroEndpoint.sol\";\nimport \"../../interfaces/ITreasury.sol\";\n\n/// @title OldNonblockingLzApp\n/// @author Angle Labs, Inc., forked from https://github.com/LayerZero-Labs/solidity-examples/\n/// @notice Base contract for bridging using LayerZero\nabstract contract OldNonblockingLzApp is Initializable, ILayerZeroReceiver, ILayerZeroUserApplicationConfig {\n /// @notice Layer Zero endpoint\n ILayerZeroEndpoint public lzEndpoint;\n\n /// @notice Maps chainIds to failed messages to retry them\n mapping(uint16 => mapping(bytes => mapping(uint64 => bytes32))) public failedMessages;\n\n /// @notice Maps chainIds to their OFT address\n mapping(uint16 => bytes) public trustedRemoteLookup;\n\n /// @notice Reference to the treasury contract to fetch access control\n address public treasury;\n\n // ================================== Events ===================================\n\n event SetTrustedRemote(uint16 _srcChainId, bytes _srcAddress);\n event MessageFailed(uint16 _srcChainId, bytes _srcAddress, uint64 _nonce, bytes _payload);\n\n // =============================== Errors ================================\n\n error NotGovernor();\n error NotGovernorOrGuardian();\n error InsufficientGas();\n error InvalidEndpoint();\n error InvalidSource();\n error InvalidCaller();\n error InvalidParams();\n error InvalidPayload();\n error ZeroAddress();\n\n // ============================= Constructor ===================================\n\n //solhint-disable-next-line\n function __LzAppUpgradeable_init(address _endpoint, address _treasury) internal {\n if (_endpoint == address(0) || _treasury == address(0)) revert ZeroAddress();\n lzEndpoint = ILayerZeroEndpoint(_endpoint);\n treasury = _treasury;\n }\n\n // =============================== Modifiers ===================================\n\n /// @notice Checks whether the `msg.sender` has the governor role or the guardian role\n modifier onlyGovernorOrGuardian() {\n if (!ITreasury(treasury).isGovernorOrGuardian(msg.sender)) revert NotGovernorOrGuardian();\n _;\n }\n\n // ==================== External Permissionless Functions ======================\n\n /// @notice Receives a message from the LZ endpoint and process it\n /// @param _srcChainId ChainId of the source chain - LayerZero standard\n /// @param _srcAddress Sender of the source chain\n /// @param _nonce Nounce of the message\n /// @param _payload Data: recipient address and amount\n function lzReceive(\n uint16 _srcChainId,\n bytes memory _srcAddress,\n uint64 _nonce,\n bytes memory _payload\n ) public virtual override {\n // lzReceive must be called by the endpoint for security\n if (msg.sender != address(lzEndpoint)) revert InvalidEndpoint();\n\n bytes memory trustedRemote = trustedRemoteLookup[_srcChainId];\n // if will still block the message pathway from (srcChainId, srcAddress). should not receive message from untrusted remote.\n if (_srcAddress.length != trustedRemote.length || keccak256(_srcAddress) != keccak256(trustedRemote))\n revert InvalidSource();\n\n _blockingLzReceive(_srcChainId, _srcAddress, _nonce, _payload);\n }\n\n /// @notice Retries a message that previously failed and was stored\n /// @param _srcChainId ChainId of the source chain - LayerZero standard\n /// @param _srcAddress Sender of the source chain\n /// @param _nonce Nounce of the message\n /// @param _payload Data: recipient address and amount\n function retryMessage(\n uint16 _srcChainId,\n bytes memory _srcAddress,\n uint64 _nonce,\n bytes memory _payload\n ) public payable virtual {\n // assert there is message to retry\n bytes32 payloadHash = failedMessages[_srcChainId][_srcAddress][_nonce];\n if (payloadHash == bytes32(0) || keccak256(_payload) != payloadHash) revert InvalidPayload();\n // clear the stored message\n failedMessages[_srcChainId][_srcAddress][_nonce] = bytes32(0);\n // execute the message. revert if it fails again\n _nonblockingLzReceive(_srcChainId, _srcAddress, _nonce, _payload);\n }\n\n // ============================= Internal Functions ===================================\n\n /// @notice Handles message receptions in a non blocking way\n /// @param _srcChainId ChainId of the source chain - LayerZero standard\n /// @param _srcAddress Sender of the source chain\n /// @param _nonce Nounce of the message\n /// @param _payload Data: recipient address and amount\n /// @dev public for the needs of try / catch but effectively internal\n function nonblockingLzReceive(\n uint16 _srcChainId,\n bytes memory _srcAddress,\n uint64 _nonce,\n bytes memory _payload\n ) public virtual {\n // only internal transaction\n if (msg.sender != address(this)) revert InvalidCaller();\n _nonblockingLzReceive(_srcChainId, _srcAddress, _nonce, _payload);\n }\n\n /// @notice Handles message receptions in a non blocking way\n /// @param _srcChainId ChainId of the source chain - LayerZero standard\n /// @param _srcAddress Sender of the source chain\n /// @param _nonce Nounce of the message\n /// @param _payload Data: recipient address and amount\n function _nonblockingLzReceive(\n uint16 _srcChainId,\n bytes memory _srcAddress,\n uint64 _nonce,\n bytes memory _payload\n ) internal virtual;\n\n /// @notice Handles message receptions in a blocking way\n /// @param _srcChainId ChainId of the source chain - LayerZero standard\n /// @param _srcAddress Sender of the source chain\n /// @param _nonce Nounce of the message\n /// @param _payload Data: recipient address and amount\n function _blockingLzReceive(\n uint16 _srcChainId,\n bytes memory _srcAddress,\n uint64 _nonce,\n bytes memory _payload\n ) internal {\n // try-catch all errors/exceptions\n try this.nonblockingLzReceive(_srcChainId, _srcAddress, _nonce, _payload) {\n // do nothing\n } catch {\n // error / exception\n failedMessages[_srcChainId][_srcAddress][_nonce] = keccak256(_payload);\n emit MessageFailed(_srcChainId, _srcAddress, _nonce, _payload);\n }\n }\n\n /// @notice Sends a message to the LZ endpoint and process it\n /// @param _dstChainId L0 defined chain id to send tokens too\n /// @param _payload Data: recipient address and amount\n /// @param _refundAddress Address LayerZero refunds if too much message fee is sent\n /// @param _zroPaymentAddress Set to address(0x0) if not paying in ZRO (LayerZero Token)\n /// @param _adapterParams Flexible bytes array to indicate messaging adapter services in L0\n function _lzSend(\n uint16 _dstChainId,\n bytes memory _payload,\n address payable _refundAddress,\n address _zroPaymentAddress,\n bytes memory _adapterParams\n ) internal virtual {\n bytes memory trustedRemote = trustedRemoteLookup[_dstChainId];\n if (trustedRemote.length == 0) revert InvalidSource();\n //solhint-disable-next-line\n lzEndpoint.send{ value: msg.value }(\n _dstChainId,\n trustedRemote,\n _payload,\n _refundAddress,\n _zroPaymentAddress,\n _adapterParams\n );\n }\n\n // ======================= Governance Functions ================================\n\n /// @notice Sets the corresponding address on an other chain.\n /// @param _srcChainId ChainId of the source chain - LayerZero standard\n /// @param _srcAddress Address on the source chain\n /// @dev Used for both receiving and sending message\n /// @dev There can only be one trusted source per chain\n /// @dev Allows owner to set it multiple times.\n function setTrustedRemote(uint16 _srcChainId, bytes calldata _srcAddress) external onlyGovernorOrGuardian {\n trustedRemoteLookup[_srcChainId] = _srcAddress;\n emit SetTrustedRemote(_srcChainId, _srcAddress);\n }\n\n /// @notice Fetches the default LZ config\n function getConfig(\n uint16 _version,\n uint16 _chainId,\n address,\n uint256 _configType\n ) external view returns (bytes memory) {\n return lzEndpoint.getConfig(_version, _chainId, address(this), _configType);\n }\n\n /// @notice Overrides the default LZ config\n function setConfig(\n uint16 _version,\n uint16 _chainId,\n uint256 _configType,\n bytes calldata _config\n ) external override onlyGovernorOrGuardian {\n lzEndpoint.setConfig(_version, _chainId, _configType, _config);\n }\n\n /// @notice Overrides the default LZ config\n function setSendVersion(uint16 _version) external override onlyGovernorOrGuardian {\n lzEndpoint.setSendVersion(_version);\n }\n\n /// @notice Overrides the default LZ config\n function setReceiveVersion(uint16 _version) external override onlyGovernorOrGuardian {\n lzEndpoint.setReceiveVersion(_version);\n }\n\n /// @notice Unpauses the receive functionalities\n function forceResumeReceive(\n uint16 _srcChainId,\n bytes calldata _srcAddress\n ) external override onlyGovernorOrGuardian {\n lzEndpoint.forceResumeReceive(_srcChainId, _srcAddress);\n }\n\n // ======================= View Functions ================================\n\n /// @notice Checks if the `_srcAddress` corresponds to the trusted source\n function isTrustedRemote(uint16 _srcChainId, bytes calldata _srcAddress) external view returns (bool) {\n bytes memory trustedSource = trustedRemoteLookup[_srcChainId];\n return keccak256(trustedSource) == keccak256(_srcAddress);\n }\n\n uint256[46] private __gap;\n}\n" + }, + "contracts/deprecated/layerZero/OldOFTCore.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.12;\n\nimport \"./OldNonblockingLzApp.sol\";\nimport \"../../agToken/layerZero/utils/IOFTCore.sol\";\nimport \"@openzeppelin/contracts-upgradeable/utils/introspection/ERC165Upgradeable.sol\";\n\n/// @title OFTCore\n/// @author Forked from https://github.com/LayerZero-Labs/solidity-examples/blob/main/contracts/token/oft/OFTCore.sol\n/// but with slight modifications from the Angle Labs, Inc. which added return values to the `_creditTo` and `_debitFrom` functions\n/// @notice Base contract for bridging using LayerZero\nabstract contract OldOFTCore is OldNonblockingLzApp, ERC165Upgradeable, IOFTCore {\n // ==================== External Permissionless Functions ======================\n\n /// @inheritdoc IOFTCore\n function sendWithPermit(\n uint16 _dstChainId,\n bytes memory _toAddress,\n uint256 _amount,\n address payable _refundAddress,\n address _zroPaymentAddress,\n bytes memory _adapterParams,\n uint256 deadline,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) public payable virtual;\n\n /// @inheritdoc IOFTCore\n function send(\n uint16 _dstChainId,\n bytes memory _toAddress,\n uint256 _amount,\n address payable _refundAddress,\n address _zroPaymentAddress,\n bytes memory _adapterParams\n ) public payable virtual {\n _amount = _debitFrom(_dstChainId, _toAddress, _amount);\n\n bytes memory payload = abi.encode(_toAddress, _amount);\n _lzSend(_dstChainId, payload, _refundAddress, _zroPaymentAddress, _adapterParams);\n\n uint64 nonce = lzEndpoint.getOutboundNonce(_dstChainId, address(this));\n emit SendToChain(msg.sender, _dstChainId, _toAddress, _amount, nonce);\n }\n\n /// @inheritdoc IOFTCore\n function sendCredit(\n uint16 _dstChainId,\n bytes memory _toAddress,\n uint256 _amount,\n address payable _refundAddress,\n address _zroPaymentAddress,\n bytes memory _adapterParams\n ) public payable virtual {\n _amount = _debitCreditFrom(_dstChainId, _toAddress, _amount);\n\n _send(_dstChainId, _toAddress, _amount, _refundAddress, _zroPaymentAddress, _adapterParams);\n }\n\n /// @inheritdoc IOFTCore\n function withdraw(uint256 amount, address recipient) external virtual returns (uint256);\n\n // =========================== Internal Functions ==============================\n\n /// @notice Internal function to send `_amount` amount of token to (`_dstChainId`, `_toAddress`)\n /// @param _dstChainId the destination chain identifier\n /// @param _toAddress can be any size depending on the `dstChainId`.\n /// @param _amount the quantity of tokens in wei\n /// @param _refundAddress the address LayerZero refunds if too much message fee is sent\n /// @param _zroPaymentAddress set to address(0x0) if not paying in ZRO (LayerZero Token)\n /// @param _adapterParams is a flexible bytes array to indicate messaging adapter services\n /// @dev Accounting and checks should be performed beforehand\n function _send(\n uint16 _dstChainId,\n bytes memory _toAddress,\n uint256 _amount,\n address payable _refundAddress,\n address _zroPaymentAddress,\n bytes memory _adapterParams\n ) internal {\n bytes memory payload = abi.encode(_toAddress, _amount);\n _lzSend(_dstChainId, payload, _refundAddress, _zroPaymentAddress, _adapterParams);\n\n uint64 nonce = lzEndpoint.getOutboundNonce(_dstChainId, address(this));\n emit SendToChain(msg.sender, _dstChainId, _toAddress, _amount, nonce);\n }\n\n function _nonblockingLzReceive(\n uint16 _srcChainId,\n bytes memory _srcAddress,\n uint64 _nonce,\n bytes memory _payload\n ) internal virtual override {\n // decode and load the toAddress\n (bytes memory toAddressBytes, uint256 amount) = abi.decode(_payload, (bytes, uint256));\n address toAddress;\n //solhint-disable-next-line\n assembly {\n toAddress := mload(add(toAddressBytes, 20))\n }\n amount = _creditTo(_srcChainId, toAddress, amount);\n\n emit ReceiveFromChain(_srcChainId, _srcAddress, toAddress, amount, _nonce);\n }\n\n /// @notice Makes accountability when bridging from this contract using canonical token\n /// @param _dstChainId ChainId of the destination chain - LayerZero standard\n /// @param _toAddress Recipient on the destination chain\n /// @param _amount Amount to bridge\n function _debitFrom(\n uint16 _dstChainId,\n bytes memory _toAddress,\n uint256 _amount\n ) internal virtual returns (uint256);\n\n /// @notice Makes accountability when bridging from this contract's credit\n /// @param _dstChainId ChainId of the destination chain - LayerZero standard\n /// @param _toAddress Recipient on the destination chain\n /// @param _amount Amount to bridge\n function _debitCreditFrom(\n uint16 _dstChainId,\n bytes memory _toAddress,\n uint256 _amount\n ) internal virtual returns (uint256);\n\n /// @notice Makes accountability when bridging to this contract\n /// @param _srcChainId ChainId of the source chain - LayerZero standard\n /// @param _toAddress Recipient on this chain\n /// @param _amount Amount to bridge\n function _creditTo(uint16 _srcChainId, address _toAddress, uint256 _amount) internal virtual returns (uint256);\n\n // ========================== View Functions ===================================\n\n /// @inheritdoc ERC165Upgradeable\n function supportsInterface(\n bytes4 interfaceId\n ) public view virtual override(ERC165Upgradeable, IERC165) returns (bool) {\n return interfaceId == type(IOFTCore).interfaceId || super.supportsInterface(interfaceId);\n }\n\n /// @inheritdoc IOFTCore\n function estimateSendFee(\n uint16 _dstChainId,\n bytes memory _toAddress,\n uint256 _amount,\n bool _useZro,\n bytes memory _adapterParams\n ) public view virtual override returns (uint256 nativeFee, uint256 zroFee) {\n // mock the payload for send()\n bytes memory payload = abi.encode(_toAddress, _amount);\n return lzEndpoint.estimateFees(_dstChainId, address(this), payload, _useZro, _adapterParams);\n }\n\n uint256[50] private __gap;\n}\n" + }, + "contracts/deprecated/OldAgEUR.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\nimport \"../interfaces/IAgToken.sol\";\nimport \"../interfaces/coreModule/IStableMaster.sol\";\nimport \"../interfaces/ITreasury.sol\";\n// OpenZeppelin may update its version of the ERC20PermitUpgradeable token\nimport \"@openzeppelin/contracts-upgradeable/token/ERC20/extensions/draft-ERC20PermitUpgradeable.sol\";\n\n/// @title AgToken\n/// @author Angle Labs, Inc.\n/// @notice Base contract for agToken, that is to say Angle's stablecoins\n/// @dev This contract is used to create and handle the stablecoins of Angle protocol\n/// @dev It is still possible for any address to burn its agTokens without redeeming collateral in exchange\n/// @dev This contract is the upgraded version of the AgToken that was first deployed on Ethereum mainnet\ncontract OldAgEUR is IAgToken, ERC20PermitUpgradeable {\n // ========================= References to other contracts =====================\n\n /// @notice Reference to the `StableMaster` contract associated to this `AgToken`\n address public stableMaster;\n\n // ============================= Constructor ===================================\n\n /// @notice Initializes the `AgToken` contract\n /// @param name_ Name of the token\n /// @param symbol_ Symbol of the token\n /// @param stableMaster_ Reference to the `StableMaster` contract associated to this agToken\n /// @dev By default, agTokens are ERC-20 tokens with 18 decimals\n function initialize(string memory name_, string memory symbol_, address stableMaster_) external initializer {\n __ERC20Permit_init(name_);\n __ERC20_init(name_, symbol_);\n require(stableMaster_ != address(0), \"0\");\n stableMaster = stableMaster_;\n }\n\n /// @custom:oz-upgrades-unsafe-allow constructor\n constructor() initializer {}\n\n // ======= Added Parameters and Variables from the first implementation ========\n\n /// @inheritdoc IAgToken\n mapping(address => bool) public isMinter;\n /// @notice Reference to the treasury contract which can grant minting rights\n address public treasury;\n /// @notice Boolean to check whether the contract has been reinitialized after its upgrade\n bool public treasuryInitialized;\n\n // =============================== Added Events ================================\n\n event TreasuryUpdated(address indexed _treasury);\n event MinterToggled(address indexed minter);\n\n // =============================== Added Errors ================================\n\n error BurnAmountExceedsAllowance();\n error InvalidSender();\n error InvalidTreasury();\n error NotGovernor();\n error NotMinter();\n error NotTreasury();\n error TreasuryAlreadyInitialized();\n\n // =============================== Setup Function ==============================\n\n /// @notice Sets up the treasury contract in this AgToken contract\n /// @param _treasury Treasury contract to add\n /// @dev The address calling this function has to be hard-coded in the contract\n /// @dev Can be called only once\n function setUpTreasury(address _treasury) external {\n // Only governor\n if (msg.sender != 0xdC4e6DFe07EFCa50a197DF15D9200883eF4Eb1c8) revert NotGovernor();\n if (address(ITreasury(_treasury).stablecoin()) != address(this)) revert InvalidTreasury();\n if (treasuryInitialized) revert TreasuryAlreadyInitialized();\n treasury = _treasury;\n treasuryInitialized = true;\n isMinter[stableMaster] = true;\n emit TreasuryUpdated(_treasury);\n }\n\n // =============================== Modifiers ===================================\n\n /// @notice Checks to see if it is the `Treasury` calling this contract\n /// @dev There is no Access Control here, because it can be handled cheaply through this modifier\n modifier onlyTreasury() {\n if (msg.sender != treasury) revert NotTreasury();\n _;\n }\n\n /// @notice Checks whether the sender has the minting right\n modifier onlyMinter() {\n if (!isMinter[msg.sender]) revert NotMinter();\n _;\n }\n\n // ========================= External Functions ================================\n // The following functions allow anyone to burn stablecoins without redeeming collateral\n // in exchange for that\n\n /// @notice Destroys `amount` token from the caller without giving collateral back\n /// @param amount Amount to burn\n /// @param poolManager Reference to the `PoolManager` contract for which the `stocksUsers` will\n /// need to be updated\n /// @dev When calling this function, people should specify the `poolManager` for which they want to decrease\n /// the `stocksUsers`: this is a way for the protocol to maintain healthy accounting variables\n function burnNoRedeem(uint256 amount, address poolManager) external {\n _burn(msg.sender, amount);\n IStableMaster(stableMaster).updateStocksUsers(amount, poolManager);\n }\n\n /// @notice Burns `amount` of agToken on behalf of another account without redeeming collateral back\n /// @param account Account to burn on behalf of\n /// @param amount Amount to burn\n /// @param poolManager Reference to the `PoolManager` contract for which the `stocksUsers` will need to be updated\n function burnFromNoRedeem(address account, uint256 amount, address poolManager) external {\n _burnFromNoRedeem(amount, account, msg.sender);\n IStableMaster(stableMaster).updateStocksUsers(amount, poolManager);\n }\n\n /// @notice Allows anyone to burn agToken without redeeming collateral back\n /// @param amount Amount of stablecoins to burn\n /// @dev This function can typically be called if there is a settlement mechanism to burn stablecoins\n function burnStablecoin(uint256 amount) external {\n _burn(msg.sender, amount);\n }\n\n // ======================= Minter Role Only Functions ==========================\n\n /// @inheritdoc IAgToken\n function burnSelf(uint256 amount, address burner) external onlyMinter {\n _burn(burner, amount);\n }\n\n /// @inheritdoc IAgToken\n function burnFrom(uint256 amount, address burner, address sender) external onlyMinter {\n _burnFromNoRedeem(amount, burner, sender);\n }\n\n /// @inheritdoc IAgToken\n function mint(address account, uint256 amount) external onlyMinter {\n _mint(account, amount);\n }\n\n // ======================= Treasury Only Functions =============================\n\n /// @inheritdoc IAgToken\n function addMinter(address minter) external onlyTreasury {\n isMinter[minter] = true;\n emit MinterToggled(minter);\n }\n\n /// @inheritdoc IAgToken\n function removeMinter(address minter) external {\n // The `treasury` contract cannot remove the `stableMaster`\n if (msg.sender != minter && (msg.sender != address(treasury) || minter == stableMaster)) revert InvalidSender();\n isMinter[minter] = false;\n emit MinterToggled(minter);\n }\n\n /// @inheritdoc IAgToken\n function setTreasury(address _treasury) external onlyTreasury {\n treasury = _treasury;\n emit TreasuryUpdated(_treasury);\n }\n\n // ============================ Internal Function ==============================\n\n /// @notice Internal version of the function `burnFromNoRedeem`\n /// @param amount Amount to burn\n /// @dev It is at the level of this function that allowance checks are performed\n function _burnFromNoRedeem(uint256 amount, address burner, address sender) internal {\n if (burner != sender) {\n uint256 currentAllowance = allowance(burner, sender);\n if (currentAllowance < amount) revert BurnAmountExceedsAllowance();\n _approve(burner, sender, currentAllowance - amount);\n }\n _burn(burner, amount);\n }\n}\n" + }, + "contracts/deprecated/OldAngleHelpers.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\nimport \"../interfaces/IAngleRouter.sol\";\nimport \"../interfaces/coreModule/IAgTokenMainnet.sol\";\nimport \"../interfaces/coreModule/ICore.sol\";\nimport \"../interfaces/coreModule/IOracleCore.sol\";\nimport \"../interfaces/coreModule/IPerpetualManager.sol\";\nimport \"../interfaces/coreModule/IPoolManager.sol\";\nimport \"../interfaces/coreModule/IStableMaster.sol\";\nimport \"@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol\";\nimport \"../interfaces/IVaultManager.sol\";\n\npragma solidity ^0.8.12;\n\nstruct Parameters {\n SLPData slpData;\n MintBurnData feeData;\n PerpetualManagerFeeData perpFeeData;\n PerpetualManagerParamData perpParam;\n}\n\nstruct PerpetualManagerFeeData {\n uint64[] xHAFeesDeposit;\n uint64[] yHAFeesDeposit;\n uint64[] xHAFeesWithdraw;\n uint64[] yHAFeesWithdraw;\n uint64 haBonusMalusDeposit;\n uint64 haBonusMalusWithdraw;\n}\n\nstruct PerpetualManagerParamData {\n uint64 maintenanceMargin;\n uint64 maxLeverage;\n uint64 targetHAHedge;\n uint64 limitHAHedge;\n uint64 lockTime;\n}\n\nstruct CollateralAddresses {\n address stableMaster;\n address poolManager;\n address perpetualManager;\n address sanToken;\n address oracle;\n address gauge;\n address feeManager;\n address[] strategies;\n}\n\n/// @title AngleHelpers\n/// @author Angle Labs, Inc.\n/// @notice Contract with view functions designed to facilitate integrations on the Core module of the Angle Protocol\n/// @dev This contract only contains view functions to be queried off-chain. It was thus not optimized for gas consumption\ncontract OldAngleHelpers is Initializable {\n // ======================== Helper View Functions ==============================\n\n /// @notice Gives the amount of `agToken` you'd be getting if you were executing in the same block a mint transaction\n /// with `amount` of `collateral` in the Core module of the Angle protocol as well as the value of the fees\n /// (in `BASE_PARAMS`) that would be applied during the mint\n /// @return Amount of `agToken` that would be obtained with a mint transaction in the same block\n /// @return Percentage of fees that would be taken during a mint transaction in the same block\n /// @dev This function reverts if the mint transaction was to revert in the same conditions (without taking into account\n /// potential approval problems to the `StableMaster` contract)\n function previewMintAndFees(\n uint256 amount,\n address agToken,\n address collateral\n ) external view returns (uint256, uint256) {\n return _previewMintAndFees(amount, agToken, collateral);\n }\n\n /// @notice Gives the amount of `collateral` you'd be getting if you were executing in the same block a burn transaction\n /// with `amount` of `agToken` in the Core module of the Angle protocol as well as the value of the fees\n /// (in `BASE_PARAMS`) that would be applied during the burn\n /// @return Amount of `collateral` that would be obtained with a burn transaction in the same block\n /// @return Percentage of fees that would be taken during a burn transaction in the same block\n /// @dev This function reverts if the burn transaction was to revert in the same conditions (without taking into account\n /// potential approval problems to the `StableMaster` contract or agToken balance prior to the call)\n function previewBurnAndFees(\n uint256 amount,\n address agToken,\n address collateral\n ) external view returns (uint256, uint256) {\n return _previewBurnAndFees(amount, agToken, collateral);\n }\n\n /// @notice Returns all the addresses associated to the (`agToken`,`collateral`) pair given\n /// @return addresses A struct with all the addresses associated in the Core module\n function getCollateralAddresses(\n address agToken,\n address collateral\n ) external view returns (CollateralAddresses memory addresses) {\n address stableMaster = IAgTokenMainnet(agToken).stableMaster();\n (address poolManager, address perpetualManager, address sanToken, address gauge) = ROUTER.mapPoolManagers(\n stableMaster,\n collateral\n );\n (, , , IOracleCore oracle, , , , , ) = IStableMaster(stableMaster).collateralMap(poolManager);\n addresses.stableMaster = stableMaster;\n addresses.poolManager = poolManager;\n addresses.perpetualManager = perpetualManager;\n addresses.sanToken = sanToken;\n addresses.gauge = gauge;\n addresses.oracle = address(oracle);\n addresses.feeManager = IPoolManager(poolManager).feeManager();\n\n uint256 length = 0;\n while (true) {\n try IPoolManager(poolManager).strategyList(length) returns (address) {\n length += 1;\n } catch {\n break;\n }\n }\n address[] memory strategies = new address[](length);\n for (uint256 i; i < length; ++i) {\n strategies[i] = IPoolManager(poolManager).strategyList(i);\n }\n addresses.strategies = strategies;\n }\n\n /// @notice Gets the addresses of all the `StableMaster` contracts and their associated `AgToken` addresses\n /// @return List of the `StableMaster` addresses of the Angle protocol\n /// @return List of the `AgToken` addresses of the protocol\n /// @dev The place of an agToken address in the list is the same as the corresponding `StableMaster` address\n function getStablecoinAddresses() external view returns (address[] memory, address[] memory) {\n address[] memory stableMasterAddresses = CORE.stablecoinList();\n address[] memory agTokenAddresses = new address[](stableMasterAddresses.length);\n for (uint256 i; i < stableMasterAddresses.length; ++i) {\n agTokenAddresses[i] = IStableMaster(stableMasterAddresses[i]).agToken();\n }\n return (stableMasterAddresses, agTokenAddresses);\n }\n\n /// @notice Returns most of the governance parameters associated to the (`agToken`,`collateral`) pair given\n /// @return params Struct with most of the parameters in the `StableMaster` and `PerpetualManager` contracts\n /// @dev Check out the struct `Parameters` for the meaning of the return values\n function getCollateralParameters(\n address agToken,\n address collateral\n ) external view returns (Parameters memory params) {\n (address stableMaster, address poolManager) = _getStableMasterAndPoolManager(agToken, collateral);\n (\n ,\n ,\n IPerpetualManager perpetualManager,\n ,\n ,\n ,\n ,\n SLPData memory slpData,\n MintBurnData memory feeData\n ) = IStableMaster(stableMaster).collateralMap(poolManager);\n\n params.slpData = slpData;\n params.feeData = feeData;\n params.perpParam.maintenanceMargin = perpetualManager.maintenanceMargin();\n params.perpParam.maxLeverage = perpetualManager.maxLeverage();\n params.perpParam.targetHAHedge = perpetualManager.targetHAHedge();\n params.perpParam.limitHAHedge = perpetualManager.limitHAHedge();\n params.perpParam.lockTime = perpetualManager.lockTime();\n\n params.perpFeeData.haBonusMalusDeposit = perpetualManager.haBonusMalusDeposit();\n params.perpFeeData.haBonusMalusWithdraw = perpetualManager.haBonusMalusWithdraw();\n\n uint256 length = 0;\n while (true) {\n try perpetualManager.xHAFeesDeposit(length) returns (uint64) {\n length += 1;\n } catch {\n break;\n }\n }\n uint64[] memory data = new uint64[](length);\n uint64[] memory data2 = new uint64[](length);\n for (uint256 i; i < length; ++i) {\n data[i] = perpetualManager.xHAFeesDeposit(i);\n data2[i] = perpetualManager.yHAFeesDeposit(i);\n }\n params.perpFeeData.xHAFeesDeposit = data;\n params.perpFeeData.yHAFeesDeposit = data2;\n\n length = 0;\n while (true) {\n try perpetualManager.xHAFeesWithdraw(length) returns (uint64) {\n length += 1;\n } catch {\n break;\n }\n }\n data = new uint64[](length);\n data2 = new uint64[](length);\n for (uint256 i; i < length; ++i) {\n data[i] = perpetualManager.xHAFeesWithdraw(i);\n data2[i] = perpetualManager.yHAFeesWithdraw(i);\n }\n params.perpFeeData.xHAFeesWithdraw = data;\n params.perpFeeData.yHAFeesWithdraw = data2;\n }\n\n /// @notice Returns the address of the poolManager associated to an (`agToken`, `collateral`) pair\n /// in the Core module of the protocol\n function getPoolManager(address agToken, address collateral) public view returns (address poolManager) {\n (, poolManager) = _getStableMasterAndPoolManager(agToken, collateral);\n }\n\n // ======================== Replica Functions ==================================\n // These replicate what is done in the other contracts of the protocol\n\n function _previewBurnAndFees(\n uint256 amount,\n address agToken,\n address collateral\n ) internal view returns (uint256 amountForUserInCollat, uint256 feePercent) {\n (address stableMaster, address poolManager) = _getStableMasterAndPoolManager(agToken, collateral);\n (\n address token,\n ,\n IPerpetualManager perpetualManager,\n IOracleCore oracle,\n uint256 stocksUsers,\n ,\n uint256 collatBase,\n ,\n MintBurnData memory feeData\n ) = IStableMaster(stableMaster).collateralMap(poolManager);\n if (token == address(0) || IStableMaster(stableMaster).paused(keccak256(abi.encodePacked(STABLE, poolManager))))\n revert NotInitialized();\n if (amount > stocksUsers) revert InvalidAmount();\n\n if (feeData.xFeeBurn.length == 1) {\n feePercent = feeData.yFeeBurn[0];\n } else {\n bytes memory data = abi.encode(address(perpetualManager), feeData.targetHAHedge);\n uint64 hedgeRatio = _computeHedgeRatio(stocksUsers - amount, data);\n feePercent = _piecewiseLinear(hedgeRatio, feeData.xFeeBurn, feeData.yFeeBurn);\n }\n feePercent = (feePercent * feeData.bonusMalusBurn) / BASE_PARAMS;\n\n amountForUserInCollat = (amount * (BASE_PARAMS - feePercent) * collatBase) / (oracle.readUpper() * BASE_PARAMS);\n }\n\n function _previewMintAndFees(\n uint256 amount,\n address agToken,\n address collateral\n ) internal view returns (uint256 amountForUserInStable, uint256 feePercent) {\n (address stableMaster, address poolManager) = _getStableMasterAndPoolManager(agToken, collateral);\n (\n address token,\n ,\n IPerpetualManager perpetualManager,\n IOracleCore oracle,\n uint256 stocksUsers,\n ,\n ,\n ,\n MintBurnData memory feeData\n ) = IStableMaster(stableMaster).collateralMap(poolManager);\n if (token == address(0) || IStableMaster(stableMaster).paused(keccak256(abi.encodePacked(STABLE, poolManager))))\n revert NotInitialized();\n\n amountForUserInStable = oracle.readQuoteLower(amount);\n\n if (feeData.xFeeMint.length == 1) feePercent = feeData.yFeeMint[0];\n else {\n bytes memory data = abi.encode(address(perpetualManager), feeData.targetHAHedge);\n uint64 hedgeRatio = _computeHedgeRatio(amountForUserInStable + stocksUsers, data);\n feePercent = _piecewiseLinear(hedgeRatio, feeData.xFeeMint, feeData.yFeeMint);\n }\n feePercent = (feePercent * feeData.bonusMalusMint) / BASE_PARAMS;\n\n amountForUserInStable = (amountForUserInStable * (BASE_PARAMS - feePercent)) / BASE_PARAMS;\n if (stocksUsers + amountForUserInStable > feeData.capOnStableMinted) revert InvalidAmount();\n }\n\n // ======================== Utility Functions ==================================\n // These utility functions are taken from other contracts of the protocol\n\n function _computeHedgeRatio(uint256 newStocksUsers, bytes memory data) internal view returns (uint64 ratio) {\n (address perpetualManager, uint64 targetHAHedge) = abi.decode(data, (address, uint64));\n uint256 totalHedgeAmount = IPerpetualManager(perpetualManager).totalHedgeAmount();\n newStocksUsers = (targetHAHedge * newStocksUsers) / BASE_PARAMS;\n if (newStocksUsers > totalHedgeAmount) ratio = uint64((totalHedgeAmount * BASE_PARAMS) / newStocksUsers);\n else ratio = uint64(BASE_PARAMS);\n }\n\n function _piecewiseLinear(uint64 x, uint64[] memory xArray, uint64[] memory yArray) internal pure returns (uint64) {\n if (x >= xArray[xArray.length - 1]) {\n return yArray[xArray.length - 1];\n } else if (x <= xArray[0]) {\n return yArray[0];\n } else {\n uint256 lower;\n uint256 upper = xArray.length - 1;\n uint256 mid;\n while (upper - lower > 1) {\n mid = lower + (upper - lower) / 2;\n if (xArray[mid] <= x) {\n lower = mid;\n } else {\n upper = mid;\n }\n }\n if (yArray[upper] > yArray[lower]) {\n return\n yArray[lower] +\n ((yArray[upper] - yArray[lower]) * (x - xArray[lower])) /\n (xArray[upper] - xArray[lower]);\n } else {\n return\n yArray[lower] -\n ((yArray[lower] - yArray[upper]) * (x - xArray[lower])) /\n (xArray[upper] - xArray[lower]);\n }\n }\n }\n\n function _getStableMasterAndPoolManager(\n address agToken,\n address collateral\n ) internal view returns (address stableMaster, address poolManager) {\n stableMaster = IAgTokenMainnet(agToken).stableMaster();\n (poolManager, , , ) = ROUTER.mapPoolManagers(stableMaster, collateral);\n }\n\n // ====================== Constants and Initializers ===========================\n\n IAngleRouter public constant ROUTER = IAngleRouter(0xBB755240596530be0c1DE5DFD77ec6398471561d);\n ICore public constant CORE = ICore(0x61ed74de9Ca5796cF2F8fD60D54160D47E30B7c3);\n\n bytes32 public constant STABLE = keccak256(\"STABLE\");\n uint256 public constant BASE_PARAMS = 10 ** 9;\n\n error NotInitialized();\n error InvalidAmount();\n\n /// @custom:oz-upgrades-unsafe-allow constructor\n constructor() initializer {}\n}\n" + }, + "contracts/deprecated/vaultManager/OldVaultManagerERC721.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\nimport \"./OldVaultManagerStorage.sol\";\n\n/// @title VaultManagerERC721\n/// @author Angle Labs, Inc.\n/// @dev Base ERC721 Implementation of VaultManager\nabstract contract OldVaultManagerERC721 is IERC721MetadataUpgradeable, OldVaultManagerStorage {\n using SafeERC20 for IERC20;\n using Address for address;\n\n /// @inheritdoc IERC721MetadataUpgradeable\n string public name;\n /// @inheritdoc IERC721MetadataUpgradeable\n string public symbol;\n\n // ================================= MODIFIERS =================================\n\n /// @notice Checks if the person interacting with the vault with `vaultID` is approved\n /// @param caller Address of the person seeking to interact with the vault\n /// @param vaultID ID of the concerned vault\n modifier onlyApprovedOrOwner(address caller, uint256 vaultID) {\n if (!_isApprovedOrOwner(caller, vaultID)) revert NotApproved();\n _;\n }\n\n // ================================ ERC721 LOGIC ===============================\n\n /// @notice Checks whether a given address is approved for a vault or owns this vault\n /// @param spender Address for which vault ownership should be checked\n /// @param vaultID ID of the vault to check\n /// @return Whether the `spender` address owns or is approved for `vaultID`\n function isApprovedOrOwner(address spender, uint256 vaultID) external view returns (bool) {\n return _isApprovedOrOwner(spender, vaultID);\n }\n\n /// @inheritdoc IERC721MetadataUpgradeable\n function tokenURI(uint256 vaultID) external view returns (string memory) {\n if (!_exists(vaultID)) revert NonexistentVault();\n // There is no vault with `vaultID` equal to 0, so the following variable is\n // always greater than zero\n uint256 temp = vaultID;\n uint256 digits;\n while (temp != 0) {\n digits++;\n temp /= 10;\n }\n bytes memory buffer = new bytes(digits);\n while (vaultID != 0) {\n digits -= 1;\n buffer[digits] = bytes1(uint8(48 + uint256(vaultID % 10)));\n vaultID /= 10;\n }\n return bytes(_baseURI).length > 0 ? string(abi.encodePacked(_baseURI, string(buffer))) : \"\";\n }\n\n /// @inheritdoc IERC721Upgradeable\n function balanceOf(address owner) external view returns (uint256) {\n if (owner == address(0)) revert ZeroAddress();\n return _balances[owner];\n }\n\n /// @inheritdoc IERC721Upgradeable\n function ownerOf(uint256 vaultID) external view returns (address) {\n return _ownerOf(vaultID);\n }\n\n /// @inheritdoc IERC721Upgradeable\n function approve(address to, uint256 vaultID) external {\n address owner = _ownerOf(vaultID);\n if (to == owner) revert ApprovalToOwner();\n if (msg.sender != owner && !isApprovedForAll(owner, msg.sender)) revert NotApproved();\n\n _approve(to, vaultID);\n }\n\n /// @inheritdoc IERC721Upgradeable\n function getApproved(uint256 vaultID) external view returns (address) {\n if (!_exists(vaultID)) revert NonexistentVault();\n return _getApproved(vaultID);\n }\n\n /// @inheritdoc IERC721Upgradeable\n function setApprovalForAll(address operator, bool approved) external {\n _setApprovalForAll(msg.sender, operator, approved);\n }\n\n /// @inheritdoc IERC721Upgradeable\n function isApprovedForAll(address owner, address operator) public view returns (bool) {\n return _operatorApprovals[owner][operator] == 1;\n }\n\n /// @inheritdoc IERC721Upgradeable\n function transferFrom(address from, address to, uint256 vaultID) external onlyApprovedOrOwner(msg.sender, vaultID) {\n _transfer(from, to, vaultID);\n }\n\n /// @inheritdoc IERC721Upgradeable\n function safeTransferFrom(address from, address to, uint256 vaultID) external {\n safeTransferFrom(from, to, vaultID, \"\");\n }\n\n /// @inheritdoc IERC721Upgradeable\n function safeTransferFrom(\n address from,\n address to,\n uint256 vaultID,\n bytes memory _data\n ) public onlyApprovedOrOwner(msg.sender, vaultID) {\n _safeTransfer(from, to, vaultID, _data);\n }\n\n // ================================ ERC165 LOGIC ===============================\n\n /// @inheritdoc IERC165Upgradeable\n function supportsInterface(bytes4 interfaceId) external pure returns (bool) {\n return\n interfaceId == type(IERC721MetadataUpgradeable).interfaceId ||\n interfaceId == type(IERC721Upgradeable).interfaceId ||\n interfaceId == type(IVaultManager).interfaceId ||\n interfaceId == type(IERC165Upgradeable).interfaceId;\n }\n\n // ================== INTERNAL FUNCTIONS FOR THE ERC721 LOGIC ==================\n\n /// @notice Internal version of the `ownerOf` function\n function _ownerOf(uint256 vaultID) internal view returns (address owner) {\n owner = _owners[vaultID];\n if (owner == address(0)) revert NonexistentVault();\n }\n\n /// @notice Internal version of the `getApproved` function\n function _getApproved(uint256 vaultID) internal view returns (address) {\n return _vaultApprovals[vaultID];\n }\n\n /// @notice Internal version of the `safeTransferFrom` function (with the data parameter)\n function _safeTransfer(address from, address to, uint256 vaultID, bytes memory _data) internal {\n _transfer(from, to, vaultID);\n if (!_checkOnERC721Received(from, to, vaultID, _data)) revert NonERC721Receiver();\n }\n\n /// @notice Checks whether a vault exists\n /// @param vaultID ID of the vault to check\n /// @return Whether `vaultID` has been created\n function _exists(uint256 vaultID) internal view returns (bool) {\n return _owners[vaultID] != address(0);\n }\n\n /// @notice Internal version of the `isApprovedOrOwner` function\n function _isApprovedOrOwner(address spender, uint256 vaultID) internal view returns (bool) {\n // The following checks if the vault exists\n address owner = _ownerOf(vaultID);\n return (spender == owner || _getApproved(vaultID) == spender || _operatorApprovals[owner][spender] == 1);\n }\n\n /// @notice Internal version of the `createVault` function\n /// Mints `vaultID` and transfers it to `to`\n /// @dev This method is equivalent to the `_safeMint` method used in OpenZeppelin ERC721 contract\n /// @dev Emits a {Transfer} event\n function _mint(address to) internal returns (uint256 vaultID) {\n if (whitelistingActivated && (isWhitelisted[to] != 1 || isWhitelisted[msg.sender] != 1))\n revert NotWhitelisted();\n if (to == address(0)) revert ZeroAddress();\n\n unchecked {\n vaultIDCount += 1;\n }\n\n vaultID = vaultIDCount;\n _beforeTokenTransfer(address(0), to, vaultID);\n\n unchecked {\n _balances[to] += 1;\n }\n\n _owners[vaultID] = to;\n emit Transfer(address(0), to, vaultID);\n if (!_checkOnERC721Received(address(0), to, vaultID, \"\")) revert NonERC721Receiver();\n }\n\n /// @notice Destroys `vaultID`\n /// @dev `vaultID` must exist\n /// @dev Emits a {Transfer} event\n function _burn(uint256 vaultID) internal {\n address owner = _ownerOf(vaultID);\n\n _beforeTokenTransfer(owner, address(0), vaultID);\n // Clear approvals\n _approve(address(0), vaultID);\n // The following line cannot underflow as the owner's balance is necessarily\n // greater than 1\n unchecked {\n _balances[owner] -= 1;\n }\n delete _owners[vaultID];\n delete vaultData[vaultID];\n\n emit Transfer(owner, address(0), vaultID);\n }\n\n /// @notice Transfers `vaultID` from `from` to `to` as opposed to {transferFrom},\n /// this imposes no restrictions on msg.sender\n /// @dev `to` cannot be the zero address and `perpetualID` must be owned by `from`\n /// @dev Emits a {Transfer} event\n /// @dev A whitelist check is performed if necessary on the `to` address\n function _transfer(address from, address to, uint256 vaultID) internal {\n if (_ownerOf(vaultID) != from) revert NotApproved();\n if (to == address(0)) revert ZeroAddress();\n if (whitelistingActivated && isWhitelisted[to] != 1) revert NotWhitelisted();\n\n _beforeTokenTransfer(from, to, vaultID);\n\n // Clear approvals from the previous owner\n _approve(address(0), vaultID);\n unchecked {\n _balances[from] -= 1;\n _balances[to] += 1;\n }\n _owners[vaultID] = to;\n\n emit Transfer(from, to, vaultID);\n }\n\n /// @notice Approves `to` to operate on `vaultID`\n function _approve(address to, uint256 vaultID) internal {\n _vaultApprovals[vaultID] = to;\n emit Approval(_ownerOf(vaultID), to, vaultID);\n }\n\n /// @notice Internal version of the `setApprovalForAll` function\n /// @dev It contains an `approver` field to be used in case someone signs a permit for a particular\n /// address, and this signature is given to the contract by another address (like a router)\n function _setApprovalForAll(address approver, address operator, bool approved) internal {\n if (operator == approver) revert ApprovalToCaller();\n uint256 approval = approved ? 1 : 0;\n _operatorApprovals[approver][operator] = approval;\n emit ApprovalForAll(approver, operator, approved);\n }\n\n /// @notice Internal function to invoke {IERC721Receiver-onERC721Received} on a target address\n /// The call is not executed if the target address is not a contract\n /// @param from Address representing the previous owner of the given token ID\n /// @param to Target address that will receive the tokens\n /// @param vaultID ID of the token to be transferred\n /// @param _data Bytes optional data to send along with the call\n /// @return Bool whether the call correctly returned the expected value\n function _checkOnERC721Received(\n address from,\n address to,\n uint256 vaultID,\n bytes memory _data\n ) private returns (bool) {\n if (to.isContract()) {\n try IERC721ReceiverUpgradeable(to).onERC721Received(msg.sender, from, vaultID, _data) returns (\n bytes4 retval\n ) {\n return retval == IERC721ReceiverUpgradeable.onERC721Received.selector;\n } catch (bytes memory reason) {\n if (reason.length == 0) {\n revert NonERC721Receiver();\n } else {\n // solhint-disable-next-line no-inline-assembly\n assembly {\n revert(add(32, reason), mload(reason))\n }\n }\n }\n } else {\n return true;\n }\n }\n\n /// @notice Hook that is called before any token transfer. This includes minting and burning.\n /// Calling conditions:\n ///\n /// - When `from` and `to` are both non-zero, `from`'s `vaultID` will be\n /// transferred to `to`.\n /// - When `from` is zero, `vaultID` will be minted for `to`.\n /// - When `to` is zero, `from`'s `vaultID` will be burned.\n /// - `from` and `to` are never both zero.\n function _beforeTokenTransfer(address from, address to, uint256 vaultID) internal virtual {}\n}\n" + }, + "contracts/deprecated/vaultManager/OldVaultManagerPermit.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\nimport \"./OldVaultManagerERC721.sol\";\nimport \"../../interfaces/external/IERC1271.sol\";\n\n/// @title VaultManagerPermit\n/// @author Angle Labs, Inc.\n/// @dev Base Implementation of permit functions for the `VaultManager` contract\nabstract contract OldVaultManagerPermit is Initializable, OldVaultManagerERC721 {\n using Address for address;\n\n mapping(address => uint256) private _nonces;\n /* solhint-disable var-name-mixedcase */\n bytes32 private _HASHED_NAME;\n bytes32 private _HASHED_VERSION;\n bytes32 private _PERMIT_TYPEHASH;\n /* solhint-enable var-name-mixedcase */\n\n error ExpiredDeadline();\n error InvalidSignature();\n\n //solhint-disable-next-line\n function __ERC721Permit_init(string memory _name) internal onlyInitializing {\n _PERMIT_TYPEHASH = keccak256(\n \"Permit(address owner,address spender,bool approved,uint256 nonce,uint256 deadline)\"\n );\n _HASHED_NAME = keccak256(bytes(_name));\n _HASHED_VERSION = keccak256(bytes(\"1\"));\n }\n\n /// @notice Allows an address to give or revoke approval for all its vaults to another address\n /// @param owner Address signing the permit and giving (or revoking) its approval for all the controlled vaults\n /// @param spender Address to give approval to\n /// @param approved Whether to give or revoke the approval\n /// @param deadline Deadline parameter for the signature to be valid\n /// @dev The `v`, `r`, and `s` parameters are used as signature data\n function permit(\n address owner,\n address spender,\n bool approved,\n uint256 deadline,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) external {\n if (block.timestamp > deadline) revert ExpiredDeadline();\n // Additional signature checks performed in the `ECDSAUpgradeable.recover` function\n if (uint256(s) > 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D576E7357A4501DDFE92F46681B20A0 || (v != 27 && v != 28))\n revert InvalidSignature();\n\n bytes32 digest = keccak256(\n abi.encodePacked(\n \"\\x19\\x01\",\n _domainSeparatorV4(),\n keccak256(\n abi.encode(\n _PERMIT_TYPEHASH,\n // 0x3f43a9c6bafb5c7aab4e0cfe239dc5d4c15caf0381c6104188191f78a6640bd8,\n owner,\n spender,\n approved,\n _useNonce(owner),\n deadline\n )\n )\n )\n );\n if (owner.isContract()) {\n if (IERC1271(owner).isValidSignature(digest, abi.encodePacked(r, s, v)) != 0x1626ba7e)\n revert InvalidSignature();\n } else {\n address signer = ecrecover(digest, v, r, s);\n if (signer != owner || signer == address(0)) revert InvalidSignature();\n }\n\n _setApprovalForAll(owner, spender, approved);\n }\n\n /// @notice Returns the current nonce for an `owner` address\n function nonces(address owner) public view returns (uint256) {\n return _nonces[owner];\n }\n\n /// @notice Returns the domain separator for the current chain.\n // solhint-disable-next-line func-name-mixedcase\n function DOMAIN_SEPARATOR() external view returns (bytes32) {\n return _domainSeparatorV4();\n }\n\n /// @notice Internal version of the `DOMAIN_SEPARATOR` function\n function _domainSeparatorV4() internal view returns (bytes32) {\n return\n keccak256(\n abi.encode(\n // keccak256('EIP712Domain(string name,string version,uint256 chainId,address verifyingContract)')\n 0x8b73c3c69bb8fe3d512ecc4cf759cc79239f7b179b0ffacaa9a75d522b39400f,\n _HASHED_NAME,\n _HASHED_VERSION,\n block.chainid,\n address(this)\n )\n );\n }\n\n /// @notice Consumes a nonce for an address: returns the current value and increments it\n function _useNonce(address owner) internal returns (uint256 current) {\n current = _nonces[owner];\n _nonces[owner] = current + 1;\n }\n\n uint256[49] private __gap;\n}\n" + }, + "contracts/deprecated/vaultManager/OldVaultManagerStorage.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\nimport \"@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/token/ERC20/extensions/draft-IERC20PermitUpgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/token/ERC721/IERC721ReceiverUpgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/interfaces/IERC721MetadataUpgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/utils/introspection/IERC165Upgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/utils/AddressUpgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/security/ReentrancyGuardUpgradeable.sol\";\nimport \"@openzeppelin/contracts/token/ERC20/extensions/IERC20Metadata.sol\";\nimport \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\nimport \"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\";\n\nimport \"../../interfaces/IAgToken.sol\";\nimport \"../../interfaces/IOracle.sol\";\nimport \"../../interfaces/ISwapper.sol\";\nimport \"../../interfaces/ITreasury.sol\";\nimport \"../../interfaces/IVaultManager.sol\";\nimport \"../../interfaces/governance/IVeBoostProxy.sol\";\n\n/// @title VaultManagerStorage\n/// @author Angle Labs, Inc.\n/// @dev Variables, references, parameters and events needed in the `VaultManager` contract\n// solhint-disable-next-line max-states-count\ncontract OldVaultManagerStorage is IVaultManagerStorage, Initializable, ReentrancyGuardUpgradeable {\n /// @notice Base used for parameter computation: almost all the parameters of this contract are set in `BASE_PARAMS`\n uint256 public constant BASE_PARAMS = 10 ** 9;\n /// @notice Base used for interest rate computation\n uint256 public constant BASE_INTEREST = 10 ** 27;\n /// @notice Used for interest rate computation\n uint256 public constant HALF_BASE_INTEREST = 10 ** 27 / 2;\n\n // ================================= REFERENCES ================================\n\n /// @inheritdoc IVaultManagerStorage\n ITreasury public treasury;\n /// @inheritdoc IVaultManagerStorage\n IERC20 public collateral;\n /// @inheritdoc IVaultManagerStorage\n IAgToken public stablecoin;\n /// @inheritdoc IVaultManagerStorage\n IOracle public oracle;\n /// @notice Reference to the contract which computes adjusted veANGLE balances for liquidators boosts\n IVeBoostProxy public veBoostProxy;\n /// @notice Base of the collateral\n uint256 internal _collatBase;\n\n // ================================= PARAMETERS ================================\n // Unless specified otherwise, parameters of this contract are expressed in `BASE_PARAMS`\n\n /// @notice Maximum amount of stablecoins that can be issued with this contract (in `BASE_TOKENS`). This parameter should\n /// not be bigger than `type(uint256).max / BASE_INTEREST` otherwise there may be some overflows in the `increaseDebt` function\n uint256 public debtCeiling;\n /// @notice Threshold veANGLE balance values for the computation of the boost for liquidators: the length of this array\n /// should normally be 2. The base of the x-values in this array should be `BASE_TOKENS`\n uint256[] public xLiquidationBoost;\n /// @notice Values of the liquidation boost at the threshold values of x\n uint256[] public yLiquidationBoost;\n /// @inheritdoc IVaultManagerStorage\n uint64 public collateralFactor;\n /// @notice Maximum Health factor at which a vault can end up after a liquidation (unless it's fully liquidated)\n uint64 public targetHealthFactor;\n /// @notice Upfront fee taken when borrowing stablecoins: this fee is optional and should in practice not be used\n uint64 public borrowFee;\n /// @notice Upfront fee taken when repaying stablecoins: this fee is optional as well. It should be smaller\n /// than the liquidation surcharge (cf below) to avoid exploits where people voluntarily get liquidated at a 0\n /// discount to pay smaller repaying fees\n uint64 public repayFee;\n /// @notice Per second interest taken to borrowers taking agToken loans. Contrarily to other parameters, it is set in `BASE_INTEREST`\n /// that is to say in base 10**27\n uint64 public interestRate;\n /// @notice Fee taken by the protocol during a liquidation. Technically, this value is not the fee per se, it's 1 - fee.\n /// For instance for a 2% fee, `liquidationSurcharge` should be 98%\n uint64 public liquidationSurcharge;\n /// @notice Maximum discount given to liquidators\n uint64 public maxLiquidationDiscount;\n /// @notice Whether whitelisting is required to own a vault or not\n bool public whitelistingActivated;\n /// @notice Whether the contract is paused or not\n bool public paused;\n\n // ================================= VARIABLES =================================\n\n /// @notice Timestamp at which the `interestAccumulator` was updated\n uint256 public lastInterestAccumulatorUpdated;\n /// @inheritdoc IVaultManagerStorage\n uint256 public interestAccumulator;\n /// @inheritdoc IVaultManagerStorage\n uint256 public totalNormalizedDebt;\n /// @notice Surplus accumulated by the contract: surplus is always in stablecoins, and is then reset\n /// when the value is communicated to the treasury contract\n uint256 public surplus;\n /// @notice Bad debt made from liquidated vaults which ended up having no collateral and a positive amount\n /// of stablecoins\n uint256 public badDebt;\n\n // ================================== MAPPINGS =================================\n\n /// @inheritdoc IVaultManagerStorage\n mapping(uint256 => Vault) public vaultData;\n /// @notice Maps an address to 1 if it's whitelisted and can open or own a vault\n mapping(address => uint256) public isWhitelisted;\n\n // ================================ ERC721 DATA ================================\n\n /// @inheritdoc IVaultManagerStorage\n uint256 public vaultIDCount;\n\n /// @notice URI\n string internal _baseURI;\n\n // Mapping from `vaultID` to owner address\n mapping(uint256 => address) internal _owners;\n\n // Mapping from owner address to vault owned count\n mapping(address => uint256) internal _balances;\n\n // Mapping from `vaultID` to approved address\n mapping(uint256 => address) internal _vaultApprovals;\n\n // Mapping from owner to operator approvals\n mapping(address => mapping(address => uint256)) internal _operatorApprovals;\n\n uint256[50] private __gap;\n\n // =================================== EVENTS ==================================\n\n event AccruedToTreasury(uint256 surplusEndValue, uint256 badDebtEndValue);\n event CollateralAmountUpdated(uint256 vaultID, uint256 collateralAmount, uint8 isIncrease);\n event InterestAccumulatorUpdated(uint256 value, uint256 timestamp);\n event InternalDebtUpdated(uint256 vaultID, uint256 internalAmount, uint8 isIncrease);\n event FiledUint64(uint64 param, bytes32 what);\n event DebtCeilingUpdated(uint256 debtCeiling);\n event LiquidationBoostParametersUpdated(address indexed _veBoostProxy, uint256[] xBoost, uint256[] yBoost);\n event LiquidatedVaults(uint256[] vaultIDs);\n event DebtTransferred(uint256 srcVaultID, uint256 dstVaultID, address dstVaultManager, uint256 amount);\n\n // =================================== ERRORS ==================================\n\n error ApprovalToOwner();\n error ApprovalToCaller();\n error DustyLeftoverAmount();\n error DebtCeilingExceeded();\n error HealthyVault();\n error IncompatibleLengths();\n error InsolventVault();\n error InvalidParameterValue();\n error InvalidParameterType();\n error InvalidSetOfParameters();\n error InvalidTreasury();\n error NonERC721Receiver();\n error NonexistentVault();\n error NotApproved();\n error NotGovernor();\n error NotGovernorOrGuardian();\n error NotTreasury();\n error NotWhitelisted();\n error NotVaultManager();\n error Paused();\n error TooHighParameterValue();\n error TooSmallParameterValue();\n error ZeroAddress();\n\n /// @custom:oz-upgrades-unsafe-allow constructor\n constructor() initializer {}\n}\n" + }, + "contracts/external/ProxyAdmin.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\nimport \"./TransparentUpgradeableProxy.sol\";\nimport \"@openzeppelin/contracts/access/Ownable.sol\";\n\n/**\n * @dev This is an auxiliary contract meant to be assigned as the admin of a {TransparentUpgradeableProxy}. For an\n * explanation of why you would want to use this see the documentation for {TransparentUpgradeableProxy}.\n * This contract was fully forked from OpenZeppelin `ProxyAdmin`\n */\ncontract ProxyAdmin is Ownable {\n /**\n * @dev Returns the current implementation of `proxy`.\n *\n * Requirements:\n *\n * - This contract must be the admin of `proxy`.\n */\n function getProxyImplementation(TransparentUpgradeableProxy proxy) public view virtual returns (address) {\n // We need to manually run the static call since the getter cannot be flagged as view\n // bytes4(keccak256(\"implementation()\")) == 0x5c60da1b\n (bool success, bytes memory returndata) = address(proxy).staticcall(hex\"5c60da1b\");\n require(success);\n return abi.decode(returndata, (address));\n }\n\n /**\n * @dev Returns the current admin of `proxy`.\n *\n * Requirements:\n *\n * - This contract must be the admin of `proxy`.\n */\n function getProxyAdmin(TransparentUpgradeableProxy proxy) public view virtual returns (address) {\n // We need to manually run the static call since the getter cannot be flagged as view\n // bytes4(keccak256(\"admin()\")) == 0xf851a440\n (bool success, bytes memory returndata) = address(proxy).staticcall(hex\"f851a440\");\n require(success);\n return abi.decode(returndata, (address));\n }\n\n /**\n * @dev Changes the admin of `proxy` to `newAdmin`.\n *\n * Requirements:\n *\n * - This contract must be the current admin of `proxy`.\n */\n function changeProxyAdmin(TransparentUpgradeableProxy proxy, address newAdmin) public virtual onlyOwner {\n proxy.changeAdmin(newAdmin);\n }\n\n /**\n * @dev Upgrades `proxy` to `implementation`. See {TransparentUpgradeableProxy-upgradeTo}.\n *\n * Requirements:\n *\n * - This contract must be the admin of `proxy`.\n */\n function upgrade(TransparentUpgradeableProxy proxy, address implementation) public virtual onlyOwner {\n proxy.upgradeTo(implementation);\n }\n\n /**\n * @dev Upgrades `proxy` to `implementation` and calls a function on the new implementation. See\n * {TransparentUpgradeableProxy-upgradeToAndCall}.\n *\n * Requirements:\n *\n * - This contract must be the admin of `proxy`.\n */\n function upgradeAndCall(\n TransparentUpgradeableProxy proxy,\n address implementation,\n bytes memory data\n ) public payable virtual onlyOwner {\n proxy.upgradeToAndCall{ value: msg.value }(implementation, data);\n }\n}\n" + }, + "contracts/external/TransparentUpgradeableProxy.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\nimport \"@openzeppelin/contracts/proxy/ERC1967/ERC1967Proxy.sol\";\n\n/**\n * @dev This contract implements a proxy that is upgradeable by an admin. It is fully forked from OpenZeppelin\n * `TransparentUpgradeableProxy`\n *\n * To avoid https://medium.com/nomic-labs-blog/malicious-backdoors-in-ethereum-proxies-62629adf3357[proxy selector\n * clashing], which can potentially be used in an attack, this contract uses the\n * https://blog.openzeppelin.com/the-transparent-proxy-pattern/[transparent proxy pattern]. This pattern implies two\n * things that go hand in hand:\n *\n * 1. If any account other than the admin calls the proxy, the call will be forwarded to the implementation, even if\n * that call matches one of the admin functions exposed by the proxy itself.\n * 2. If the admin calls the proxy, it can access the admin functions, but its calls will never be forwarded to the\n * implementation. If the admin tries to call a function on the implementation it will fail with an error that says\n * \"admin cannot fallback to proxy target\".\n *\n * These properties mean that the admin account can only be used for admin actions like upgrading the proxy or changing\n * the admin, so it's best if it's a dedicated account that is not used for anything else. This will avoid headaches due\n * to sudden errors when trying to call a function from the proxy implementation.\n *\n * Our recommendation is for the dedicated account to be an instance of the {ProxyAdmin} contract. If set up this way,\n * you should think of the `ProxyAdmin` instance as the real administrative interface of your proxy.\n */\ncontract TransparentUpgradeableProxy is ERC1967Proxy {\n /**\n * @dev Initializes an upgradeable proxy managed by `_admin`, backed by the implementation at `_logic`, and\n * optionally initialized with `_data` as explained in {ERC1967Proxy-constructor}.\n */\n constructor(address _logic, address admin_, bytes memory _data) payable ERC1967Proxy(_logic, _data) {\n assert(_ADMIN_SLOT == bytes32(uint256(keccak256(\"eip1967.proxy.admin\")) - 1));\n _changeAdmin(admin_);\n }\n\n /**\n * @dev Modifier used internally that will delegate the call to the implementation unless the sender is the admin.\n */\n modifier ifAdmin() {\n if (msg.sender == _getAdmin()) {\n _;\n } else {\n _fallback();\n }\n }\n\n /**\n * @dev Returns the current admin.\n *\n * NOTE: Only the admin can call this function. See {ProxyAdmin-getProxyAdmin}.\n *\n * TIP: To get this value clients can read directly from the storage slot shown below (specified by EIP1967) using the\n * https://eth.wiki/json-rpc/API#eth_getstorageat[`eth_getStorageAt`] RPC call.\n * `0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103`\n */\n function admin() external ifAdmin returns (address admin_) {\n admin_ = _getAdmin();\n }\n\n /**\n * @dev Returns the current implementation.\n *\n * NOTE: Only the admin can call this function. See {ProxyAdmin-getProxyImplementation}.\n *\n * TIP: To get this value clients can read directly from the storage slot shown below (specified by EIP1967) using the\n * https://eth.wiki/json-rpc/API#eth_getstorageat[`eth_getStorageAt`] RPC call.\n * `0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc`\n */\n function implementation() external ifAdmin returns (address implementation_) {\n implementation_ = _implementation();\n }\n\n /**\n * @dev Changes the admin of the proxy.\n *\n * Emits an {AdminChanged} event.\n *\n * NOTE: Only the admin can call this function. See {ProxyAdmin-changeProxyAdmin}.\n */\n function changeAdmin(address newAdmin) external virtual ifAdmin {\n _changeAdmin(newAdmin);\n }\n\n /**\n * @dev Upgrade the implementation of the proxy.\n *\n * NOTE: Only the admin can call this function. See {ProxyAdmin-upgrade}.\n */\n function upgradeTo(address newImplementation) external ifAdmin {\n _upgradeToAndCall(newImplementation, bytes(\"\"), false);\n }\n\n /**\n * @dev Upgrade the implementation of the proxy, and then call a function from the new implementation as specified\n * by `data`, which should be an encoded function call. This is useful to initialize new storage variables in the\n * proxied contract.\n *\n * NOTE: Only the admin can call this function. See {ProxyAdmin-upgradeAndCall}.\n */\n function upgradeToAndCall(address newImplementation, bytes calldata data) external payable ifAdmin {\n _upgradeToAndCall(newImplementation, data, true);\n }\n\n /**\n * @dev Returns the current admin.\n */\n function _admin() internal view virtual returns (address) {\n return _getAdmin();\n }\n\n /**\n * @dev Makes sure the admin cannot access the fallback function. See {Proxy-_beforeFallback}.\n */\n function _beforeFallback() internal virtual override {\n require(msg.sender != _getAdmin(), \"TransparentUpgradeableProxy: admin cannot fallback to proxy target\");\n super._beforeFallback();\n }\n}\n" + }, + "contracts/flashloan/FlashAngle.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\nimport \"@openzeppelin/contracts-upgradeable/security/ReentrancyGuardUpgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol\";\nimport \"@openzeppelin/contracts/interfaces/IERC3156FlashBorrower.sol\";\nimport \"@openzeppelin/contracts/interfaces/IERC3156FlashLender.sol\";\nimport \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\nimport \"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\";\n\nimport \"../interfaces/IAgToken.sol\";\nimport \"../interfaces/ICoreBorrow.sol\";\nimport \"../interfaces/IFlashAngle.sol\";\nimport \"../interfaces/ITreasury.sol\";\n\n/// @title FlashAngle\n/// @author Angle Labs, Inc.\n/// @notice Contract to take flash loans on top of several AgToken contracts\ncontract FlashAngle is IERC3156FlashLender, IFlashAngle, Initializable, ReentrancyGuardUpgradeable {\n using SafeERC20 for IERC20;\n /// @notice Base used for parameter computation\n uint256 public constant BASE_PARAMS = 10 ** 9;\n /// @notice Success message received when calling a `FlashBorrower` contract\n bytes32 public constant CALLBACK_SUCCESS = keccak256(\"ERC3156FlashBorrower.onFlashLoan\");\n\n /// @notice Struct encoding for a given stablecoin the parameters\n struct StablecoinData {\n // Maximum amount borrowable for this stablecoin\n uint256 maxBorrowable;\n // Flash loan fee taken by the protocol for a flash loan on this stablecoin\n uint64 flashLoanFee;\n // Treasury address responsible of the stablecoin\n address treasury;\n }\n\n // ======================= Parameters and References ===========================\n\n /// @notice Maps a stablecoin to the data and parameters for flash loans\n mapping(IAgToken => StablecoinData) public stablecoinMap;\n /// @inheritdoc IFlashAngle\n ICoreBorrow public core;\n\n // =============================== Event =======================================\n\n event FlashLoan(address indexed stablecoin, uint256 amount, IERC3156FlashBorrower indexed receiver);\n event FlashLoanParametersUpdated(IAgToken indexed stablecoin, uint64 _flashLoanFee, uint256 _maxBorrowable);\n\n // =============================== Errors ======================================\n\n error InvalidReturnMessage();\n error NotCore();\n error NotGovernorOrGuardian();\n error NotTreasury();\n error TooBigAmount();\n error TooHighParameterValue();\n error UnsupportedStablecoin();\n error ZeroAddress();\n\n /// @notice Initializes the contract\n /// @param _core Core address handling this module\n function initialize(ICoreBorrow _core) public initializer {\n if (address(_core) == address(0)) revert ZeroAddress();\n core = _core;\n }\n\n /// @custom:oz-upgrades-unsafe-allow constructor\n constructor() initializer {}\n\n // =================================== Modifiers ===============================\n\n /// @notice Checks whether the sender is the core contract\n modifier onlyCore() {\n if (msg.sender != address(core)) revert NotCore();\n _;\n }\n\n /// @notice Checks whether a given stablecoin has been initialized in this contract\n /// @param stablecoin Stablecoin to check\n /// @dev To check whether a stablecoin has been initialized, we just need to check whether its associated\n /// `treasury` address is not null in the `stablecoinMap`. This is what's checked in the `CoreBorrow` contract\n /// when adding support for a stablecoin\n modifier onlyExistingStablecoin(IAgToken stablecoin) {\n if (stablecoinMap[stablecoin].treasury == address(0)) revert UnsupportedStablecoin();\n _;\n }\n\n // ================================ ERC3156 Spec ===============================\n\n /// @inheritdoc IERC3156FlashLender\n function flashFee(address token, uint256 amount) external view returns (uint256) {\n return _flashFee(token, amount);\n }\n\n /// @inheritdoc IERC3156FlashLender\n function maxFlashLoan(address token) external view returns (uint256) {\n // It will be 0 anyway if the token was not added\n return stablecoinMap[IAgToken(token)].maxBorrowable;\n }\n\n /// @inheritdoc IERC3156FlashLender\n function flashLoan(\n IERC3156FlashBorrower receiver,\n address token,\n uint256 amount,\n bytes calldata data\n ) external nonReentrant returns (bool) {\n uint256 fee = _flashFee(token, amount);\n if (amount > stablecoinMap[IAgToken(token)].maxBorrowable) revert TooBigAmount();\n IAgToken(token).mint(address(receiver), amount);\n if (receiver.onFlashLoan(msg.sender, token, amount, fee, data) != CALLBACK_SUCCESS)\n revert InvalidReturnMessage();\n // Token must be an agToken here so normally no need to use `safeTransferFrom`, but out of safety\n // and in case governance whitelists an agToken which does not have a correct implementation, we prefer\n // to use `safeTransferFrom` here\n IERC20(token).safeTransferFrom(address(receiver), address(this), amount + fee);\n IAgToken(token).burnSelf(amount, address(this));\n emit FlashLoan(token, amount, receiver);\n return true;\n }\n\n /// @notice Internal function to compute the fee induced for taking a flash loan of `amount` of `token`\n /// @param token The loan currency\n /// @param amount The amount of tokens lent\n /// @dev This function will revert if the `token` requested is not whitelisted here\n function _flashFee(\n address token,\n uint256 amount\n ) internal view onlyExistingStablecoin(IAgToken(token)) returns (uint256) {\n return (amount * stablecoinMap[IAgToken(token)].flashLoanFee) / BASE_PARAMS;\n }\n\n // ============================ Treasury Only Function =========================\n\n /// @inheritdoc IFlashAngle\n function accrueInterestToTreasury(IAgToken stablecoin) external returns (uint256 balance) {\n address treasury = stablecoinMap[stablecoin].treasury;\n if (msg.sender != treasury) revert NotTreasury();\n balance = stablecoin.balanceOf(address(this));\n IERC20(address(stablecoin)).safeTransfer(treasury, balance);\n }\n\n // =========================== Governance Only Function ========================\n\n /// @notice Sets the parameters for a given stablecoin\n /// @param stablecoin Stablecoin to change the parameters for\n /// @param _flashLoanFee New flash loan fee for this stablecoin\n /// @param _maxBorrowable Maximum amount that can be borrowed in a single flash loan\n /// @dev Setting a `maxBorrowable` parameter equal to 0 is a way to pause the functionality\n /// @dev Parameters can only be modified for whitelisted stablecoins\n function setFlashLoanParameters(\n IAgToken stablecoin,\n uint64 _flashLoanFee,\n uint256 _maxBorrowable\n ) external onlyExistingStablecoin(stablecoin) {\n if (!core.isGovernorOrGuardian(msg.sender)) revert NotGovernorOrGuardian();\n if (_flashLoanFee > BASE_PARAMS) revert TooHighParameterValue();\n stablecoinMap[stablecoin].flashLoanFee = _flashLoanFee;\n stablecoinMap[stablecoin].maxBorrowable = _maxBorrowable;\n emit FlashLoanParametersUpdated(stablecoin, _flashLoanFee, _maxBorrowable);\n }\n\n // =========================== CoreBorrow Only Functions =======================\n\n /// @inheritdoc IFlashAngle\n function addStablecoinSupport(address _treasury) external onlyCore {\n stablecoinMap[IAgToken(ITreasury(_treasury).stablecoin())].treasury = _treasury;\n }\n\n /// @inheritdoc IFlashAngle\n function removeStablecoinSupport(address _treasury) external onlyCore {\n delete stablecoinMap[IAgToken(ITreasury(_treasury).stablecoin())];\n }\n\n /// @inheritdoc IFlashAngle\n function setCore(address _core) external onlyCore {\n core = ICoreBorrow(_core);\n }\n}\n" + }, + "contracts/interfaces/coreModule/IAgTokenMainnet.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\n/// @title IAgTokenMainnet\n/// @author Angle Labs, Inc.\ninterface IAgTokenMainnet {\n function stableMaster() external view returns (address);\n}\n" + }, + "contracts/interfaces/coreModule/ICore.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\n/// @title ICore\n/// @author Angle Labs, Inc.\ninterface ICore {\n function stablecoinList() external view returns (address[] memory);\n}\n" + }, + "contracts/interfaces/coreModule/ILiquidityGauge.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\ninterface ILiquidityGauge {\n function deposit(\n uint256 _value,\n address _addr,\n // solhint-disable-next-line\n bool _claim_rewards\n ) external;\n\n function withdraw(\n uint256 _value,\n // solhint-disable-next-line\n bool _claim_rewards\n ) external;\n\n // solhint-disable-next-line\n function claim_rewards(address _addr, address _receiver) external;\n\n // solhint-disable-next-line\n function claimable_reward(address _addr, address _reward_token) external view returns (uint256 amount);\n}\n" + }, + "contracts/interfaces/coreModule/IOracleCore.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\n/// @title IOracleCore\n/// @author Angle Labs, Inc.\ninterface IOracleCore {\n function readUpper() external view returns (uint256);\n\n function readQuoteLower(uint256 baseAmount) external view returns (uint256);\n}\n" + }, + "contracts/interfaces/coreModule/IPerpetualManager.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\n/// @title IPerpetualManager\n/// @author Angle Labs, Inc.\ninterface IPerpetualManager {\n function totalHedgeAmount() external view returns (uint256);\n\n function maintenanceMargin() external view returns (uint64);\n\n function maxLeverage() external view returns (uint64);\n\n function targetHAHedge() external view returns (uint64);\n\n function limitHAHedge() external view returns (uint64);\n\n function lockTime() external view returns (uint64);\n\n function haBonusMalusDeposit() external view returns (uint64);\n\n function haBonusMalusWithdraw() external view returns (uint64);\n\n function xHAFeesDeposit(uint256) external view returns (uint64);\n\n function yHAFeesDeposit(uint256) external view returns (uint64);\n\n function xHAFeesWithdraw(uint256) external view returns (uint64);\n\n function yHAFeesWithdraw(uint256) external view returns (uint64);\n}\n" + }, + "contracts/interfaces/coreModule/IPoolManager.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\n/// @title IPoolManager\n/// @author Angle Labs, Inc.\ninterface IPoolManager {\n function feeManager() external view returns (address);\n\n function strategyList(uint256) external view returns (address);\n}\n" + }, + "contracts/interfaces/coreModule/IStableMaster.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\nimport \"./IPerpetualManager.sol\";\nimport \"./IOracleCore.sol\";\n\n// Struct to handle all the parameters to manage the fees\n// related to a given collateral pool (associated to the stablecoin)\nstruct MintBurnData {\n // Values of the thresholds to compute the minting fees\n // depending on HA hedge (scaled by `BASE_PARAMS`)\n uint64[] xFeeMint;\n // Values of the fees at thresholds (scaled by `BASE_PARAMS`)\n uint64[] yFeeMint;\n // Values of the thresholds to compute the burning fees\n // depending on HA hedge (scaled by `BASE_PARAMS`)\n uint64[] xFeeBurn;\n // Values of the fees at thresholds (scaled by `BASE_PARAMS`)\n uint64[] yFeeBurn;\n // Max proportion of collateral from users that can be covered by HAs\n // It is exactly the same as the parameter of the same name in `PerpetualManager`, whenever one is updated\n // the other changes accordingly\n uint64 targetHAHedge;\n // Minting fees correction set by the `FeeManager` contract: they are going to be multiplied\n // to the value of the fees computed using the hedge curve\n // Scaled by `BASE_PARAMS`\n uint64 bonusMalusMint;\n // Burning fees correction set by the `FeeManager` contract: they are going to be multiplied\n // to the value of the fees computed using the hedge curve\n // Scaled by `BASE_PARAMS`\n uint64 bonusMalusBurn;\n // Parameter used to limit the number of stablecoins that can be issued using the concerned collateral\n uint256 capOnStableMinted;\n}\n\n// Struct to handle all the variables and parameters to handle SLPs in the protocol\n// including the fraction of interests they receive or the fees to be distributed to\n// them\nstruct SLPData {\n // Last timestamp at which the `sanRate` has been updated for SLPs\n uint256 lastBlockUpdated;\n // Fees accumulated from previous blocks and to be distributed to SLPs\n uint256 lockedInterests;\n // Max interests used to update the `sanRate` in a single block\n // Should be in collateral token base\n uint256 maxInterestsDistributed;\n // Amount of fees left aside for SLPs and that will be distributed\n // when the protocol is collateralized back again\n uint256 feesAside;\n // Part of the fees normally going to SLPs that is left aside\n // before the protocol is collateralized back again (depends on collateral ratio)\n // Updated by keepers and scaled by `BASE_PARAMS`\n uint64 slippageFee;\n // Portion of the fees from users minting and burning\n // that goes to SLPs (the rest goes to surplus)\n uint64 feesForSLPs;\n // Slippage factor that's applied to SLPs exiting (depends on collateral ratio)\n // If `slippage = BASE_PARAMS`, SLPs can get nothing, if `slippage = 0` they get their full claim\n // Updated by keepers and scaled by `BASE_PARAMS`\n uint64 slippage;\n // Portion of the interests from lending\n // that goes to SLPs (the rest goes to surplus)\n uint64 interestsForSLPs;\n}\n\n/// @title IStableMaster\n/// @author Angle Labs, Inc.\ninterface IStableMaster {\n function agToken() external view returns (address);\n\n function updateStocksUsers(uint256 amount, address poolManager) external;\n\n function collateralMap(\n address poolManager\n )\n external\n view\n returns (\n address token,\n address sanToken,\n IPerpetualManager perpetualManager,\n IOracleCore oracle,\n uint256 stocksUsers,\n uint256 sanRate,\n uint256 collatBase,\n SLPData memory slpData,\n MintBurnData memory feeData\n );\n\n function paused(bytes32) external view returns (bool);\n\n function deposit(uint256 amount, address user, address poolManager) external;\n\n function withdraw(uint256 amount, address burner, address dest, address poolManager) external;\n}\n" + }, + "contracts/interfaces/external/create2/ImmutableCreate2Factory.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\ninterface ImmutableCreate2Factory {\n function safeCreate2(bytes32 salt, bytes memory initCode) external payable returns (address deploymentAddress);\n\n function findCreate2Address(\n bytes32 salt,\n bytes calldata initCode\n ) external view returns (address deploymentAddress);\n\n function findCreate2AddressViaHash(\n bytes32 salt,\n bytes32 initCodeHash\n ) external view returns (address deploymentAddress);\n}\n" + }, + "contracts/interfaces/external/IERC1271.sol": { + "content": "// SPDX-License-Identifier: GPL-2.0-or-later\npragma solidity ^0.8.12;\n\n/// @title Interface for verifying contract-based account signatures\n/// @notice Interface that verifies provided signature for the data\n/// @dev Interface defined by EIP-1271\ninterface IERC1271 {\n /// @notice Returns whether the provided signature is valid for the provided data\n /// @dev MUST return the bytes4 magic value 0x1626ba7e when function passes.\n /// MUST NOT modify state (using STATICCALL for solc < 0.5, view modifier for solc > 0.5).\n /// MUST allow external calls.\n /// @param hash Hash of the data to be signed\n /// @param signature Signature byte array associated with _data\n /// @return magicValue The bytes4 magic value 0x1626ba7e\n function isValidSignature(bytes32 hash, bytes memory signature) external view returns (bytes4 magicValue);\n}\n" + }, + "contracts/interfaces/external/IERC4626.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0-only\npragma solidity >=0.8.0;\n\nimport \"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\";\nimport \"@openzeppelin/contracts/token/ERC20/ERC20.sol\";\n\n/// @notice Minimal IERC4646 tokenized Vault interface.\n/// @author Forked from Solmate (https://github.com/Rari-Capital/solmate/blob/main/src/mixins/ERC4626.sol)\n/// @dev Do not use in production! ERC-4626 is still in the review stage and is subject to change.\ninterface IERC4626 {\n event Deposit(address indexed from, address indexed to, uint256 amount, uint256 shares);\n event Withdraw(address indexed from, address indexed to, uint256 amount, uint256 shares);\n\n /// @notice Transfers a given amount of asset to the reactor and mint shares accordingly\n /// @param amount Given amount of asset\n /// @param to Address to mint shares to\n /// @return shares Amount of shares minted to `to`\n function deposit(uint256 amount, address to) external returns (uint256 shares);\n\n /// @notice Mints a given amount of shares to the reactor and transfer assets accordingly\n /// @param shares Given amount of shares\n /// @param to Address to mint shares to\n /// @return amount Amount of `asset` taken to the `msg.sender` to mint `shares`\n function mint(uint256 shares, address to) external returns (uint256 amount);\n\n /// @notice Transfers a given amount of asset from the reactor and burn shares accordingly\n /// @param amount Given amount of asset\n /// @param to Address to transfer assets to\n /// @param from Address to burn shares from\n /// @return shares Amount of shares burnt in the operation\n function withdraw(uint256 amount, address to, address from) external returns (uint256 shares);\n\n /// @notice Burns a given amount of shares to the reactor and transfer assets accordingly\n /// @param shares Given amount of shares\n /// @param to Address to transfer assets to\n /// @param from Address to burn shares from\n /// @return amount Amount of assets redeemed in the operation\n function redeem(uint256 shares, address to, address from) external returns (uint256 amount);\n\n /// @notice Returns the total assets managed by this reactor\n function totalAssets() external view returns (uint256);\n\n /// @notice Converts an amount of assets to the corresponding amount of reactor shares\n /// @param assets Amount of asset to convert\n /// @return Shares corresponding to the amount of assets obtained\n function convertToShares(uint256 assets) external view returns (uint256);\n\n /// @notice Converts an amount of shares to its current value in asset\n /// @param shares Amount of shares to convert\n /// @return Amount of assets corresponding to the amount of assets given\n function convertToAssets(uint256 shares) external view returns (uint256);\n\n /// @notice Computes how many shares one would get by depositing `assets`\n /// @param assets Amount of asset to convert\n function previewDeposit(uint256 assets) external view returns (uint256);\n\n /// @notice Computes how many assets one would need to mint `shares`\n /// @param shares Amount of shares required\n function previewMint(uint256 shares) external view returns (uint256);\n\n /// @notice Computes how many shares one would need to withdraw assets\n /// @param assets Amount of asset to withdraw\n function previewWithdraw(uint256 assets) external view returns (uint256);\n\n /// @notice Computes how many assets one would get by burning shares\n /// @param shares Amount of shares to burn\n function previewRedeem(uint256 shares) external view returns (uint256);\n\n /// @notice Max deposit allowed for a user\n /// @param user Address of the user to check\n function maxDeposit(address user) external returns (uint256);\n\n /// @notice Max mint allowed for a user\n /// @param user Address of the user to check\n function maxMint(address user) external returns (uint256);\n\n /// @notice Max withdraw allowed for a user\n /// @param user Address of the user to check\n function maxWithdraw(address user) external returns (uint256);\n\n /// @notice Max redeem allowed for a user\n /// @param user Address of the user to check\n function maxRedeem(address user) external returns (uint256);\n}\n" + }, + "contracts/interfaces/external/IWETH9.sol": { + "content": "// SPDX-License-Identifier: GPL-2.0-or-later\npragma solidity ^0.8.12;\n\nimport \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\n\n/// @title Interface for WETH9\ninterface IWETH9 is IERC20 {\n /// @notice Deposit ether to get wrapped ether\n function deposit() external payable;\n\n /// @notice Withdraw wrapped ether to get ether\n function withdraw(uint256) external;\n}\n" + }, + "contracts/interfaces/external/layerZero/ILayerZeroEndpoint.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity >=0.5.0;\n\nimport \"./ILayerZeroUserApplicationConfig.sol\";\n\ninterface ILayerZeroEndpoint is ILayerZeroUserApplicationConfig {\n // @notice send a LayerZero message to the specified address at a LayerZero endpoint.\n // @param _dstChainId - the destination chain identifier\n // @param _destination - the address on destination chain (in bytes). address length/format may vary by chains\n // @param _payload - a custom bytes payload to send to the destination contract\n // @param _refundAddress - if the source transaction is cheaper than the amount of value passed, refund the additional amount to this address\n // @param _zroPaymentAddress - the address of the ZRO token holder who would pay for the transaction\n // @param _adapterParams - parameters for custom functionality. e.g. receive airdropped native gas from the relayer on destination\n function send(\n uint16 _dstChainId,\n bytes calldata _destination,\n bytes calldata _payload,\n address payable _refundAddress,\n address _zroPaymentAddress,\n bytes calldata _adapterParams\n ) external payable;\n\n // @notice used by the messaging library to publish verified payload\n // @param _srcChainId - the source chain identifier\n // @param _srcAddress - the source contract (as bytes) at the source chain\n // @param _dstAddress - the address on destination chain\n // @param _nonce - the unbound message ordering nonce\n // @param _gasLimit - the gas limit for external contract execution\n // @param _payload - verified payload to send to the destination contract\n function receivePayload(\n uint16 _srcChainId,\n bytes calldata _srcAddress,\n address _dstAddress,\n uint64 _nonce,\n uint256 _gasLimit,\n bytes calldata _payload\n ) external;\n\n // @notice get the inboundNonce of a lzApp from a source chain which could be EVM or non-EVM chain\n // @param _srcChainId - the source chain identifier\n // @param _srcAddress - the source chain contract address\n function getInboundNonce(uint16 _srcChainId, bytes calldata _srcAddress) external view returns (uint64);\n\n // @notice get the outboundNonce from this source chain which, consequently, is always an EVM\n // @param _srcAddress - the source chain contract address\n function getOutboundNonce(uint16 _dstChainId, address _srcAddress) external view returns (uint64);\n\n // @notice gets a quote in source native gas, for the amount that send() requires to pay for message delivery\n // @param _dstChainId - the destination chain identifier\n // @param _userApplication - the user app address on this EVM chain\n // @param _payload - the custom message to send over LayerZero\n // @param _payInZRO - if false, user app pays the protocol fee in native token\n // @param _adapterParam - parameters for the adapter service, e.g. send some dust native token to dstChain\n function estimateFees(\n uint16 _dstChainId,\n address _userApplication,\n bytes calldata _payload,\n bool _payInZRO,\n bytes calldata _adapterParam\n ) external view returns (uint256 nativeFee, uint256 zroFee);\n\n // @notice get this Endpoint's immutable source identifier\n function getChainId() external view returns (uint16);\n\n // @notice the interface to retry failed message on this Endpoint destination\n // @param _srcChainId - the source chain identifier\n // @param _srcAddress - the source chain contract address\n // @param _payload - the payload to be retried\n function retryPayload(uint16 _srcChainId, bytes calldata _srcAddress, bytes calldata _payload) external;\n\n // @notice query if any STORED payload (message blocking) at the endpoint.\n // @param _srcChainId - the source chain identifier\n // @param _srcAddress - the source chain contract address\n function hasStoredPayload(uint16 _srcChainId, bytes calldata _srcAddress) external view returns (bool);\n\n // @notice query if the _libraryAddress is valid for sending msgs.\n // @param _userApplication - the user app address on this EVM chain\n function getSendLibraryAddress(address _userApplication) external view returns (address);\n\n // @notice query if the _libraryAddress is valid for receiving msgs.\n // @param _userApplication - the user app address on this EVM chain\n function getReceiveLibraryAddress(address _userApplication) external view returns (address);\n\n // @notice query if the non-reentrancy guard for send() is on\n // @return true if the guard is on. false otherwise\n function isSendingPayload() external view returns (bool);\n\n // @notice query if the non-reentrancy guard for receive() is on\n // @return true if the guard is on. false otherwise\n function isReceivingPayload() external view returns (bool);\n\n // @notice get the configuration of the LayerZero messaging library of the specified version\n // @param _version - messaging library version\n // @param _chainId - the chainId for the pending config change\n // @param _userApplication - the contract address of the user application\n // @param _configType - type of configuration. every messaging library has its own convention.\n function getConfig(\n uint16 _version,\n uint16 _chainId,\n address _userApplication,\n uint256 _configType\n ) external view returns (bytes memory);\n\n // @notice get the send() LayerZero messaging library version\n // @param _userApplication - the contract address of the user application\n function getSendVersion(address _userApplication) external view returns (uint16);\n\n // @notice get the lzReceive() LayerZero messaging library version\n // @param _userApplication - the contract address of the user application\n function getReceiveVersion(address _userApplication) external view returns (uint16);\n}\n" + }, + "contracts/interfaces/external/layerZero/ILayerZeroReceiver.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity >=0.5.0;\n\ninterface ILayerZeroReceiver {\n // @notice LayerZero endpoint will invoke this function to deliver the message on the destination\n // @param _srcChainId - the source endpoint identifier\n // @param _srcAddress - the source sending contract address from the source chain\n // @param _nonce - the ordered message nonce\n // @param _payload - the signed payload is the UA bytes has encoded to be sent\n function lzReceive(uint16 _srcChainId, bytes calldata _srcAddress, uint64 _nonce, bytes calldata _payload) external;\n}\n" + }, + "contracts/interfaces/external/layerZero/ILayerZeroUserApplicationConfig.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity >=0.5.0;\n\ninterface ILayerZeroUserApplicationConfig {\n // @notice set the configuration of the LayerZero messaging library of the specified version\n // @param _version - messaging library version\n // @param _chainId - the chainId for the pending config change\n // @param _configType - type of configuration. every messaging library has its own convention.\n // @param _config - configuration in the bytes. can encode arbitrary content.\n function setConfig(uint16 _version, uint16 _chainId, uint256 _configType, bytes calldata _config) external;\n\n // @notice set the send() LayerZero messaging library version to _version\n // @param _version - new messaging library version\n function setSendVersion(uint16 _version) external;\n\n // @notice set the lzReceive() LayerZero messaging library version to _version\n // @param _version - new messaging library version\n function setReceiveVersion(uint16 _version) external;\n\n // @notice Only when the UA needs to resume the message flow in blocking mode and clear the stored payload\n // @param _srcChainId - the chainId of the source chain\n // @param _srcAddress - the contract address of the source contract at the source chain\n function forceResumeReceive(uint16 _srcChainId, bytes calldata _srcAddress) external;\n}\n" + }, + "contracts/interfaces/external/lido/IStETH.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\n/// @title IStETH\n/// @author Angle Labs, Inc.\n/// @notice Interface for the `StETH` contract\n/// @dev This interface only contains functions of the `StETH` which are called by other contracts\n/// of this module\ninterface IStETH {\n function getPooledEthByShares(uint256 _sharesAmount) external view returns (uint256);\n\n event Submitted(address sender, uint256 amount, address referral);\n\n function submit(address) external payable returns (uint256);\n\n function getSharesByPooledEth(uint256 _ethAmount) external view returns (uint256);\n}\n" + }, + "contracts/interfaces/external/lido/IWStETH.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\n/// @title IWStETH\n/// @author Angle Labs, Inc.\n/// @notice Interface for the `WStETH` contract\n/// @dev This interface only contains functions of the `WStETH` which are called by other contracts\n/// of this module\ninterface IWStETH {\n function wrap(uint256 _stETHAmount) external returns (uint256);\n\n function stETH() external view returns (address);\n}\n" + }, + "contracts/interfaces/external/uniswap/IUniswapRouter.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\nstruct ExactInputParams {\n bytes path;\n address recipient;\n uint256 deadline;\n uint256 amountIn;\n uint256 amountOutMinimum;\n}\n\n/// @title Router token swapping functionality\n/// @notice Functions for swapping tokens via Uniswap V3\ninterface IUniswapV3Router {\n /// @notice Swaps `amountIn` of one token for as much as possible of another along the specified path\n /// @param params The parameters necessary for the multi-hop swap, encoded as `ExactInputParams` in calldata\n /// @return amountOut The amount of the received token\n function exactInput(ExactInputParams calldata params) external payable returns (uint256 amountOut);\n}\n\n/// @title Router for price estimation functionality\n/// @notice Functions for getting the price of one token with respect to another using Uniswap V2\n/// @dev This interface is only used for non critical elements of the protocol\ninterface IUniswapV2Router {\n /// @notice Given an input asset amount, returns the maximum output amount of the\n /// other asset (accounting for fees) given reserves.\n /// @param path Addresses of the pools used to get prices\n function getAmountsOut(uint256 amountIn, address[] calldata path) external view returns (uint256[] memory amounts);\n\n function swapExactTokensForTokens(\n uint256 swapAmount,\n uint256 minExpected,\n address[] calldata path,\n address receiver,\n uint256 swapDeadline\n ) external;\n}\n" + }, + "contracts/interfaces/external/uniswap/IUniswapV3Pool.sol": { + "content": "// SPDX-License-Identifier: GPL-2.0-or-later\npragma solidity >=0.5.0;\n\n/// @title Pool state that never changes\n/// @notice These parameters are fixed for a pool forever, i.e., the methods will always return the same values\ninterface IUniswapV3Pool {\n /// @notice The first of the two tokens of the pool, sorted by address\n /// @return The token contract address\n function token0() external view returns (address);\n\n /// @notice The second of the two tokens of the pool, sorted by address\n /// @return The token contract address\n function token1() external view returns (address);\n}\n" + }, + "contracts/interfaces/governance/IVeBoostProxy.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\n/// @title IVeBoostProxy\n/// @author Angle Labs, Inc.\n/// @notice Interface for the `VeBoostProxy` contract\n/// @dev This interface only contains functions of the contract which are called by other contracts\n/// of this module\n/// @dev The `veBoostProxy` contract used by Angle is a full fork of Curve Finance implementation\ninterface IVeBoostProxy {\n /// @notice Reads the adjusted veANGLE balance of an address (adjusted by delegation)\n //solhint-disable-next-line\n function adjusted_balance_of(address) external view returns (uint256);\n}\n" + }, + "contracts/interfaces/IAgToken.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\nimport \"@openzeppelin/contracts-upgradeable/token/ERC20/IERC20Upgradeable.sol\";\n\n/// @title IAgToken\n/// @author Angle Labs, Inc.\n/// @notice Interface for the stablecoins `AgToken` contracts\n/// @dev This interface only contains functions of the `AgToken` contract which are called by other contracts\n/// of this module or of the first module of the Angle Protocol\ninterface IAgToken is IERC20Upgradeable {\n // ======================= Minter Role Only Functions ===========================\n\n /// @notice Lets the `StableMaster` contract or another whitelisted contract mint agTokens\n /// @param account Address to mint to\n /// @param amount Amount to mint\n /// @dev The contracts allowed to issue agTokens are the `StableMaster` contract, `VaultManager` contracts\n /// associated to this stablecoin as well as the flash loan module (if activated) and potentially contracts\n /// whitelisted by governance\n function mint(address account, uint256 amount) external;\n\n /// @notice Burns `amount` tokens from a `burner` address after being asked to by `sender`\n /// @param amount Amount of tokens to burn\n /// @param burner Address to burn from\n /// @param sender Address which requested the burn from `burner`\n /// @dev This method is to be called by a contract with the minter right after being requested\n /// to do so by a `sender` address willing to burn tokens from another `burner` address\n /// @dev The method checks the allowance between the `sender` and the `burner`\n function burnFrom(uint256 amount, address burner, address sender) external;\n\n /// @notice Burns `amount` tokens from a `burner` address\n /// @param amount Amount of tokens to burn\n /// @param burner Address to burn from\n /// @dev This method is to be called by a contract with a minter right on the AgToken after being\n /// requested to do so by an address willing to burn tokens from its address\n function burnSelf(uint256 amount, address burner) external;\n\n // ========================= Treasury Only Functions ===========================\n\n /// @notice Adds a minter in the contract\n /// @param minter Minter address to add\n /// @dev Zero address checks are performed directly in the `Treasury` contract\n function addMinter(address minter) external;\n\n /// @notice Removes a minter from the contract\n /// @param minter Minter address to remove\n /// @dev This function can also be called by a minter wishing to revoke itself\n function removeMinter(address minter) external;\n\n /// @notice Sets a new treasury contract\n /// @param _treasury New treasury address\n function setTreasury(address _treasury) external;\n\n // ========================= External functions ================================\n\n /// @notice Checks whether an address has the right to mint agTokens\n /// @param minter Address for which the minting right should be checked\n /// @return Whether the address has the right to mint agTokens or not\n function isMinter(address minter) external view returns (bool);\n\n /// @notice Get the associated treasury\n function treasury() external view returns (address);\n}\n" + }, + "contracts/interfaces/IAgTokenSideChainMultiBridge.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\nimport \"@openzeppelin/contracts-upgradeable/token/ERC20/extensions/draft-IERC20PermitUpgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/token/ERC20/IERC20Upgradeable.sol\";\n\n/// @title IAgTokenSideChainMultiBridge\n/// @author Angle Labs, Inc.\n/// @notice Interface for the canonical `AgToken` contracts\n/// @dev This interface only contains functions useful for bridge tokens to interact with the canonical token\ninterface IAgTokenSideChainMultiBridge is IERC20PermitUpgradeable, IERC20Upgradeable {\n /// @notice Mints the canonical token from a supported bridge token\n /// @param bridgeToken Bridge token to use to mint\n /// @param amount Amount of bridge tokens to send\n /// @param to Address to which the stablecoin should be sent\n /// @return Amount of the canonical stablecoin actually minted\n /// @dev Some fees may be taken by the protocol depending on the token used and on the address calling\n function swapIn(address bridgeToken, uint256 amount, address to) external returns (uint256);\n\n /// @notice Burns the canonical token in exchange for a bridge token\n /// @param bridgeToken Bridge token required\n /// @param amount Amount of canonical tokens to burn\n /// @param to Address to which the bridge token should be sent\n /// @return Amount of bridge tokens actually sent back\n /// @dev Some fees may be taken by the protocol depending on the token used and on the address calling\n function swapOut(address bridgeToken, uint256 amount, address to) external returns (uint256);\n}\n" + }, + "contracts/interfaces/IAngleRouter.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\n/// @title IAngleRouter\n/// @author Angle Labs, Inc.\n/// @notice Interface for the `AngleRouter` contract\n/// @dev This interface only contains functions of the `AngleRouter01` contract which are called by other contracts\n/// of this module\ninterface IAngleRouter {\n function mint(\n address user,\n uint256 amount,\n uint256 minStableAmount,\n address stablecoin,\n address collateral\n ) external;\n\n function burn(address user, uint256 amount, uint256 minAmountOut, address stablecoin, address collateral) external;\n\n function mapPoolManagers(\n address stableMaster,\n address collateral\n ) external view returns (address poolManager, address perpetualManager, address sanToken, address gauge);\n}\n" + }, + "contracts/interfaces/IAngleRouterSidechain.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\n/// @notice Action types\nenum ActionType {\n transfer,\n wrap,\n wrapNative,\n sweep,\n sweepNative,\n unwrap,\n unwrapNative,\n swapIn,\n swapOut,\n uniswapV3,\n oneInch,\n claimRewards,\n gaugeDeposit,\n borrower\n}\n\n/// @notice Data needed to get permits\nstruct PermitType {\n address token;\n address owner;\n uint256 value;\n uint256 deadline;\n uint8 v;\n bytes32 r;\n bytes32 s;\n}\n\n/// @title IAngleRouterSidechain\n/// @author Angle Labs, Inc.\n/// @notice Interface for the `AngleRouter` contract on other chains\ninterface IAngleRouterSidechain {\n function mixer(PermitType[] memory paramsPermit, ActionType[] memory actions, bytes[] calldata data) external;\n}\n" + }, + "contracts/interfaces/ICoreBorrow.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\n/// @title ICoreBorrow\n/// @author Angle Labs, Inc.\n/// @notice Interface for the `CoreBorrow` contract\n/// @dev This interface only contains functions of the `CoreBorrow` contract which are called by other contracts\n/// of this module\ninterface ICoreBorrow {\n /// @notice Checks if an address corresponds to a treasury of a stablecoin with a flash loan\n /// module initialized on it\n /// @param treasury Address to check\n /// @return Whether the address has the `FLASHLOANER_TREASURY_ROLE` or not\n function isFlashLoanerTreasury(address treasury) external view returns (bool);\n\n /// @notice Checks whether an address is governor of the Angle Protocol or not\n /// @param admin Address to check\n /// @return Whether the address has the `GOVERNOR_ROLE` or not\n function isGovernor(address admin) external view returns (bool);\n\n /// @notice Checks whether an address is governor or a guardian of the Angle Protocol or not\n /// @param admin Address to check\n /// @return Whether the address has the `GUARDIAN_ROLE` or not\n /// @dev Governance should make sure when adding a governor to also give this governor the guardian\n /// role by calling the `addGovernor` function\n function isGovernorOrGuardian(address admin) external view returns (bool);\n}\n" + }, + "contracts/interfaces/IFlashAngle.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\nimport \"./IAgToken.sol\";\nimport \"./ICoreBorrow.sol\";\n\n/// @title IFlashAngle\n/// @author Angle Labs, Inc.\n/// @notice Interface for the `FlashAngle` contract\n/// @dev This interface only contains functions of the contract which are called by other contracts\n/// of this module\ninterface IFlashAngle {\n /// @notice Reference to the `CoreBorrow` contract managing the FlashLoan module\n function core() external view returns (ICoreBorrow);\n\n /// @notice Sends the fees taken from flash loans to the treasury contract associated to the stablecoin\n /// @param stablecoin Stablecoin from which profits should be sent\n /// @return balance Amount of profits sent\n /// @dev This function can only be called by the treasury contract\n function accrueInterestToTreasury(IAgToken stablecoin) external returns (uint256 balance);\n\n /// @notice Adds support for a stablecoin\n /// @param _treasury Treasury associated to the stablecoin to add support for\n /// @dev This function can only be called by the `CoreBorrow` contract\n function addStablecoinSupport(address _treasury) external;\n\n /// @notice Removes support for a stablecoin\n /// @param _treasury Treasury associated to the stablecoin to remove support for\n /// @dev This function can only be called by the `CoreBorrow` contract\n function removeStablecoinSupport(address _treasury) external;\n\n /// @notice Sets a new core contract\n /// @param _core Core contract address to set\n /// @dev This function can only be called by the `CoreBorrow` contract\n function setCore(address _core) external;\n}\n" + }, + "contracts/interfaces/IKeeperRegistry.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\nimport \"@openzeppelin/contracts-upgradeable/token/ERC20/IERC20Upgradeable.sol\";\n\n/// @title IKeeperRegistry\n/// @author Angle Labs, Inc.\ninterface IKeeperRegistry {\n /// @notice Checks whether an address is whitelisted during oracle updates\n /// @param caller Address for which the whitelist should be checked\n /// @return Whether the address is trusted or not\n function isTrusted(address caller) external view returns (bool);\n}\n" + }, + "contracts/interfaces/ILiquidityGauge.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.7;\n\ninterface ILiquidityGauge {\n function deposit(\n uint256 _value,\n address _addr,\n // solhint-disable-next-line\n bool _claim_rewards\n ) external;\n\n function withdraw(\n uint256 _value,\n // solhint-disable-next-line\n bool _claim_rewards\n ) external;\n\n // solhint-disable-next-line\n function claim_rewards(address _addr, address _receiver) external;\n\n // solhint-disable-next-line\n function claimable_reward(address _addr, address _reward_token) external view returns (uint256 amount);\n\n /// @dev Only for testing purposes\n // solhint-disable-next-line\n function deposit_reward_token(address _rewardToken, uint256 _amount) external;\n}\n" + }, + "contracts/interfaces/IOracle.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\nimport \"./ITreasury.sol\";\nimport \"@chainlink/contracts/src/v0.8/interfaces/AggregatorV3Interface.sol\";\n\n/// @title IOracle\n/// @author Angle Labs, Inc.\n/// @notice Interface for the `Oracle` contract\n/// @dev This interface only contains functions of the contract which are called by other contracts\n/// of this module\ninterface IOracle {\n /// @notice Reads the rate from the Chainlink circuit and other data provided\n /// @return quoteAmount The current rate between the in-currency and out-currency in the base\n /// of the out currency\n /// @dev For instance if the out currency is EUR (and hence agEUR), then the base of the returned\n /// value is 10**18\n function read() external view returns (uint256);\n\n /// @notice Changes the treasury contract\n /// @param _treasury Address of the new treasury contract\n /// @dev This function can be called by an approved `VaultManager` contract which can call\n /// this function after being requested to do so by a `treasury` contract\n /// @dev In some situations (like reactor contracts), the `VaultManager` may not directly be linked\n /// to the `oracle` contract and as such we may need governors to be able to call this function as well\n function setTreasury(address _treasury) external;\n\n /// @notice Reference to the `treasury` contract handling this `VaultManager`\n function treasury() external view returns (ITreasury treasury);\n\n /// @notice Array with the list of Chainlink feeds in the order in which they are read\n function circuitChainlink() external view returns (AggregatorV3Interface[] memory);\n}\n" + }, + "contracts/interfaces/ISwapper.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\nimport \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\n\n/// @title ISwapper\n/// @author Angle Labs, Inc.\n/// @notice Interface for Swapper contracts\n/// @dev This interface defines the key functions `Swapper` contracts should have when interacting with\n/// Angle\ninterface ISwapper {\n /// @notice Notifies a contract that an address should be given `outToken` from `inToken`\n /// @param inToken Address of the token received\n /// @param outToken Address of the token to obtain\n /// @param outTokenRecipient Address to which the outToken should be sent\n /// @param outTokenOwed Minimum amount of outToken the `outTokenRecipient` address should have at the end of the call\n /// @param inTokenObtained Amount of collateral obtained by a related address prior\n /// to the call to this function\n /// @param data Extra data needed (to encode Uniswap swaps for instance)\n function swap(\n IERC20 inToken,\n IERC20 outToken,\n address outTokenRecipient,\n uint256 outTokenOwed,\n uint256 inTokenObtained,\n bytes calldata data\n ) external;\n}\n" + }, + "contracts/interfaces/ITreasury.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\nimport \"./IAgToken.sol\";\nimport \"./ICoreBorrow.sol\";\nimport \"./IFlashAngle.sol\";\n\n/// @title ITreasury\n/// @author Angle Labs, Inc.\n/// @notice Interface for the `Treasury` contract\n/// @dev This interface only contains functions of the `Treasury` which are called by other contracts\n/// of this module\ninterface ITreasury {\n /// @notice Stablecoin handled by this `treasury` contract\n function stablecoin() external view returns (IAgToken);\n\n /// @notice Checks whether a given address has the governor role\n /// @param admin Address to check\n /// @return Whether the address has the governor role\n /// @dev Access control is only kept in the `CoreBorrow` contract\n function isGovernor(address admin) external view returns (bool);\n\n /// @notice Checks whether a given address has the guardian or the governor role\n /// @param admin Address to check\n /// @return Whether the address has the guardian or the governor role\n /// @dev Access control is only kept in the `CoreBorrow` contract which means that this function\n /// queries the `CoreBorrow` contract\n function isGovernorOrGuardian(address admin) external view returns (bool);\n\n /// @notice Checks whether a given address has well been initialized in this contract\n /// as a `VaultManager`\n /// @param _vaultManager Address to check\n /// @return Whether the address has been initialized or not\n function isVaultManager(address _vaultManager) external view returns (bool);\n\n /// @notice Sets a new flash loan module for this stablecoin\n /// @param _flashLoanModule Reference to the new flash loan module\n /// @dev This function removes the minting right to the old flash loan module and grants\n /// it to the new module\n function setFlashLoanModule(address _flashLoanModule) external;\n\n /// @notice Gets the vault manager list\n function vaultManagerList(uint256 i) external returns (address);\n}\n" + }, + "contracts/interfaces/IVaultManager.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\nimport \"@openzeppelin/contracts/interfaces/IERC721Metadata.sol\";\nimport \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\nimport \"./ITreasury.sol\";\nimport \"./IOracle.sol\";\n\n// ========================= Key Structs and Enums =============================\n\n/// @notice Parameters associated to a given `VaultManager` contract: these all correspond\n/// to parameters which signification is detailed in the `VaultManagerStorage` file\nstruct VaultParameters {\n uint256 debtCeiling;\n uint64 collateralFactor;\n uint64 targetHealthFactor;\n uint64 interestRate;\n uint64 liquidationSurcharge;\n uint64 maxLiquidationDiscount;\n bool whitelistingActivated;\n uint256 baseBoost;\n}\n\n/// @notice Data stored to track someone's loan (or equivalently called position)\nstruct Vault {\n // Amount of collateral deposited in the vault, in collateral decimals. For example, if the collateral\n // is USDC with 6 decimals, then `collateralAmount` will be in base 10**6\n uint256 collateralAmount;\n // Normalized value of the debt (that is to say of the stablecoins borrowed). It is expressed\n // in the base of Angle stablecoins (i.e. `BASE_TOKENS = 10**18`)\n uint256 normalizedDebt;\n}\n\n/// @notice For a given `vaultID`, this encodes a liquidation opportunity that is to say details about the maximum\n/// amount that could be repaid by liquidating the position\n/// @dev All the values are null in the case of a vault which cannot be liquidated under these conditions\nstruct LiquidationOpportunity {\n // Maximum stablecoin amount that can be repaid upon liquidating the vault\n uint256 maxStablecoinAmountToRepay;\n // Collateral amount given to the person in the case where the maximum amount to repay is given\n uint256 maxCollateralAmountGiven;\n // Threshold value of stablecoin amount to repay: it is ok for a liquidator to repay below threshold,\n // but if this threshold is non null and the liquidator wants to repay more than threshold, it should repay\n // the max stablecoin amount given in this vault\n uint256 thresholdRepayAmount;\n // Discount proposed to the liquidator on the collateral\n uint256 discount;\n // Amount of debt in the vault\n uint256 currentDebt;\n}\n\n/// @notice Data stored during a liquidation process to keep in memory what's due to a liquidator and some\n/// essential data for vaults being liquidated\nstruct LiquidatorData {\n // Current amount of stablecoins the liquidator should give to the contract\n uint256 stablecoinAmountToReceive;\n // Current amount of collateral the contract should give to the liquidator\n uint256 collateralAmountToGive;\n // Bad debt accrued across the liquidation process\n uint256 badDebtFromLiquidation;\n // Oracle value (in stablecoin base) at the time of the liquidation\n uint256 oracleValue;\n // Value of the `interestAccumulator` at the time of the call\n uint256 newInterestAccumulator;\n}\n\n/// @notice Data to track during a series of action the amount to give or receive in stablecoins and collateral\n/// to the caller or associated addresses\nstruct PaymentData {\n // Stablecoin amount the contract should give\n uint256 stablecoinAmountToGive;\n // Stablecoin amount owed to the contract\n uint256 stablecoinAmountToReceive;\n // Collateral amount the contract should give\n uint256 collateralAmountToGive;\n // Collateral amount owed to the contract\n uint256 collateralAmountToReceive;\n}\n\n/// @notice Actions possible when composing calls to the different entry functions proposed\nenum ActionType {\n createVault,\n closeVault,\n addCollateral,\n removeCollateral,\n repayDebt,\n borrow,\n getDebtIn,\n permit\n}\n\n// ========================= Interfaces =============================\n\n/// @title IVaultManagerFunctions\n/// @author Angle Labs, Inc.\n/// @notice Interface for the `VaultManager` contract\n/// @dev This interface only contains functions of the contract which are called by other contracts\n/// of this module (without getters)\ninterface IVaultManagerFunctions {\n /// @notice Accrues interest accumulated across all vaults to the surplus and sends the surplus to the treasury\n /// @return surplusValue Value of the surplus communicated to the `Treasury`\n /// @return badDebtValue Value of the bad debt communicated to the `Treasury`\n /// @dev `surplus` and `badDebt` should be reset to 0 once their current value have been given to the `treasury` contract\n function accrueInterestToTreasury() external returns (uint256 surplusValue, uint256 badDebtValue);\n\n /// @notice Removes debt from a vault after being requested to do so by another `VaultManager` contract\n /// @param vaultID ID of the vault to remove debt from\n /// @param amountStablecoins Amount of stablecoins to remove from the debt: this amount is to be converted to an\n /// internal debt amount\n /// @param senderBorrowFee Borrowing fees from the contract which requested this: this is to make sure that people are not\n /// arbitraging difference in minting fees\n /// @param senderRepayFee Repay fees from the contract which requested this: this is to make sure that people are not arbitraging\n /// differences in repay fees\n /// @dev This function can only be called from a vaultManager registered in the same Treasury\n function getDebtOut(\n uint256 vaultID,\n uint256 amountStablecoins,\n uint256 senderBorrowFee,\n uint256 senderRepayFee\n ) external;\n\n /// @notice Gets the current debt of a vault\n /// @param vaultID ID of the vault to check\n /// @return Debt of the vault\n function getVaultDebt(uint256 vaultID) external view returns (uint256);\n\n /// @notice Gets the total debt across all vaults\n /// @return Total debt across all vaults, taking into account the interest accumulated\n /// over time\n function getTotalDebt() external view returns (uint256);\n\n /// @notice Sets the treasury contract\n /// @param _treasury New treasury contract\n /// @dev All required checks when setting up a treasury contract are performed in the contract\n /// calling this function\n function setTreasury(address _treasury) external;\n\n /// @notice Creates a vault\n /// @param toVault Address for which the va\n /// @return vaultID ID of the vault created\n /// @dev This function just creates the vault without doing any collateral or\n function createVault(address toVault) external returns (uint256);\n\n /// @notice Allows composability between calls to the different entry points of this module. Any user calling\n /// this function can perform any of the allowed actions in the order of their choice\n /// @param actions Set of actions to perform\n /// @param datas Data to be decoded for each action: it can include like the `vaultID` or the `stablecoinAmount` to borrow\n /// @param from Address from which stablecoins will be taken if one action includes burning stablecoins. This address\n /// should either be the `msg.sender` or be approved by the latter\n /// @param to Address to which stablecoins and/or collateral will be sent in case of\n /// @param who Address of the contract to handle in case of repayment of stablecoins from received collateral\n /// @param repayData Data to pass to the repayment contract in case of\n /// @return paymentData Struct containing the accounting changes from the protocol's perspective (like how much of collateral\n /// or how much has been received). Note that the values in the struct are not aggregated and you could have in the output\n /// a positive amount of stablecoins to receive as well as a positive amount of stablecoins to give\n /// @dev This function is optimized to reduce gas cost due to payment from or to the user and that expensive calls\n /// or computations (like `oracleValue`) are done only once\n /// @dev When specifying `vaultID` in `data`, it is important to know that if you specify `vaultID = 0`, it will simply\n /// use the latest `vaultID`. This is the default behavior, and unless you're engaging into some complex protocol actions\n /// it is encouraged to use `vaultID = 0` only when the first action of the batch is `createVault`\n function angle(\n ActionType[] memory actions,\n bytes[] memory datas,\n address from,\n address to,\n address who,\n bytes memory repayData\n ) external returns (PaymentData memory paymentData);\n\n /// @notice This function is a wrapper built on top of the function above. It enables users to interact with the contract\n /// without having to provide `who` and `repayData` parameters\n function angle(\n ActionType[] memory actions,\n bytes[] memory datas,\n address from,\n address to\n ) external returns (PaymentData memory paymentData);\n\n /// @notice Initializes the `VaultManager` contract\n /// @param _treasury Treasury address handling the contract\n /// @param _collateral Collateral supported by this contract\n /// @param _oracle Oracle contract used\n /// @param _symbol Symbol used to define the `VaultManager` name and symbol\n /// @dev The parameters and the oracle are the only elements which could be modified once the\n /// contract has been initialized\n /// @dev For the contract to be fully initialized, governance needs to set the parameters for the liquidation\n /// boost\n function initialize(\n ITreasury _treasury,\n IERC20 _collateral,\n IOracle _oracle,\n VaultParameters calldata params,\n string memory _symbol\n ) external;\n\n /// @notice Minimum amount of debt a vault can have, expressed in `BASE_TOKENS` that is to say the base of the agTokens\n function dust() external view returns (uint256);\n\n /// @notice Pauses external permissionless functions of the contract\n function togglePause() external;\n}\n\n/// @title IVaultManagerStorage\n/// @author Angle Labs, Inc.\n/// @notice Interface for the `VaultManager` contract\n/// @dev This interface contains getters of the contract's public variables used by other contracts\n/// of this module\ninterface IVaultManagerStorage {\n /// @notice Encodes the maximum ratio stablecoin/collateral a vault can have before being liquidated. It's what\n /// determines the minimum collateral ratio of a position\n function collateralFactor() external view returns (uint64);\n\n /// @notice Stablecoin handled by this contract. Another `VaultManager` contract could have\n /// the same rights as this `VaultManager` on the stablecoin contract\n function stablecoin() external view returns (IAgToken);\n\n /// @notice Reference to the `treasury` contract handling this `VaultManager`\n function treasury() external view returns (ITreasury);\n\n /// @notice Oracle contract to get access to the price of the collateral with respect to the stablecoin\n function oracle() external view returns (IOracle);\n\n /// @notice The `interestAccumulator` variable keeps track of the interest that should accrue to the protocol.\n /// The stored value is not necessarily the true value: this one is recomputed every time an action takes place\n /// within the protocol. It is in base `BASE_INTEREST`\n function interestAccumulator() external view returns (uint256);\n\n /// @notice Reference to the collateral handled by this `VaultManager`\n function collateral() external view returns (IERC20);\n\n /// @notice Total normalized amount of stablecoins borrowed, not taking into account the potential bad debt accumulated\n /// This value is expressed in the base of Angle stablecoins (`BASE_TOKENS = 10**18`)\n function totalNormalizedDebt() external view returns (uint256);\n\n /// @notice Maximum amount of stablecoins that can be issued with this contract. It is expressed in `BASE_TOKENS`\n function debtCeiling() external view returns (uint256);\n\n /// @notice Maps a `vaultID` to its data (namely collateral amount and normalized debt)\n function vaultData(uint256 vaultID) external view returns (uint256 collateralAmount, uint256 normalizedDebt);\n\n /// @notice ID of the last vault created. The `vaultIDCount` variables serves as a counter to generate a unique\n /// `vaultID` for each vault: it is like `tokenID` in basic ERC721 contracts\n function vaultIDCount() external view returns (uint256);\n}\n\n/// @title IVaultManager\n/// @author Angle Labs, Inc.\n/// @notice Interface for the `VaultManager` contract\ninterface IVaultManager is IVaultManagerFunctions, IVaultManagerStorage, IERC721Metadata {\n function isApprovedOrOwner(address spender, uint256 vaultID) external view returns (bool);\n}\n\n/// @title IVaultManagerListing\n/// @author Angle Labs, Inc.\n/// @notice Interface for the `VaultManagerListing` contract\ninterface IVaultManagerListing is IVaultManager {\n /// @notice Get the collateral owned by `user` in the contract\n /// @dev This function effectively sums the collateral amounts of all the vaults owned by `user`\n function getUserCollateral(address user) external view returns (uint256);\n}\n" + }, + "contracts/keeperMulticall/KeeperMulticall.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\nimport \"@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/access/AccessControlUpgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol\";\nimport \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\nimport \"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\";\nimport \"./RevertReasonParser.sol\";\n\n/// @title KeeperMulticall\n/// @notice Allows an authorized caller (keeper) to execute multiple actions in a single tx.\n/// @author Angle Labs, Inc.\n/// @dev Special features:\n/// - ability to pay the miner (for private Flashbots transactions)\n/// - swap tokens through 1inch\n/// @dev Tx need to be encoded as an array of Action. The flag `isDelegateCall` is used for calling functions within this same contract\ncontract KeeperMulticall is Initializable, AccessControlUpgradeable {\n using SafeERC20 for IERC20;\n\n bytes32 public constant KEEPER_ROLE = keccak256(\"KEEPER_ROLE\");\n\n //solhint-disable-next-line\n address private constant _oneInch = 0x1111111254fb6c44bAC0beD2854e76F90643097d;\n\n struct Action {\n address target;\n bytes data;\n bool isDelegateCall;\n }\n\n event LogAction(address indexed target, bytes data);\n event SentToMiner(uint256 indexed value);\n event Recovered(address indexed tokenAddress, address indexed to, uint256 amount);\n\n error AmountOutTooLow(uint256 amount, uint256 min);\n error BalanceTooLow();\n error FlashbotsErrorPayingMiner(uint256 value);\n error IncompatibleLengths();\n error RevertBytes();\n error WrongAmount();\n error ZeroAddress();\n\n constructor() initializer {}\n\n function initialize(address keeper) external initializer {\n __AccessControl_init();\n\n _setupRole(KEEPER_ROLE, keeper);\n _setRoleAdmin(KEEPER_ROLE, KEEPER_ROLE);\n }\n\n /// @notice Allows an authorized keeper to execute multiple actions in a single step\n /// @param actions Actions to be executed\n /// @param percentageToMiner Percentage to pay to miner expressed in bps (10000)\n /// @dev This is the main entry point for actions to be executed. The `isDelegateCall` flag is used for calling function inside this `KeeperMulticall` contract,\n /// if we call other contracts, the flag should be false\n function executeActions(\n Action[] memory actions,\n uint256 percentageToMiner\n ) external payable onlyRole(KEEPER_ROLE) returns (bytes[] memory) {\n uint256 numberOfActions = actions.length;\n if (numberOfActions == 0) revert IncompatibleLengths();\n\n bytes[] memory returnValues = new bytes[](numberOfActions + 1);\n\n uint256 balanceBefore = address(this).balance;\n\n for (uint256 i; i < numberOfActions; ++i) {\n returnValues[i] = _executeAction(actions[i]);\n }\n\n if (percentageToMiner != 0) {\n if (percentageToMiner >= 10000) revert WrongAmount();\n uint256 balanceAfter = address(this).balance;\n if (balanceAfter > balanceBefore) {\n uint256 amountToMiner = ((balanceAfter - balanceBefore) * percentageToMiner) / 10000;\n returnValues[numberOfActions] = payFlashbots(amountToMiner);\n }\n }\n\n return returnValues;\n }\n\n /// @notice Gets the action address and data and executes it\n /// @param action Action to be executed\n function _executeAction(Action memory action) internal returns (bytes memory) {\n bool success;\n bytes memory response;\n\n if (action.isDelegateCall) {\n //solhint-disable-next-line\n (success, response) = action.target.delegatecall(action.data);\n } else {\n //solhint-disable-next-line\n (success, response) = action.target.call(action.data);\n }\n\n require(success, RevertReasonParser.parse(response, \"action reverted: \"));\n emit LogAction(action.target, action.data);\n return response;\n }\n\n /// @notice Ability to pay miner directly. Used for Flashbots to execute private transactions\n /// @param value Value to be sent\n function payFlashbots(uint256 value) public payable onlyRole(KEEPER_ROLE) returns (bytes memory) {\n //solhint-disable-next-line\n (bool success, bytes memory response) = block.coinbase.call{ value: value }(\"\");\n if (!success) revert FlashbotsErrorPayingMiner(value);\n emit SentToMiner(value);\n return response;\n }\n\n /// @notice Used to check the balances the token holds for each token. If we don't have enough of a token, we revert the tx\n /// @param tokens Array of tokens to check\n /// @param minBalances Array of balances for each token\n function finalBalanceCheck(IERC20[] memory tokens, uint256[] memory minBalances) external view returns (bool) {\n uint256 tokensLength = tokens.length;\n if (tokensLength == 0 || tokensLength != minBalances.length) revert IncompatibleLengths();\n\n for (uint256 i; i < tokensLength; ++i) {\n if (address(tokens[i]) == 0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE) {\n if (address(this).balance < minBalances[i]) revert BalanceTooLow();\n } else {\n if (tokens[i].balanceOf(address(this)) < minBalances[i]) revert BalanceTooLow();\n }\n }\n\n return true;\n }\n\n /// @notice Swap token to another through 1Inch\n /// @param minAmountOut Minimum amount of `out` token to receive for the swap to happen\n /// @param payload Bytes needed for 1Inch API\n function swapToken(uint256 minAmountOut, bytes memory payload) external onlyRole(KEEPER_ROLE) {\n //solhint-disable-next-line\n (bool success, bytes memory result) = _oneInch.call(payload);\n if (!success) _revertBytes(result);\n\n uint256 amountOut = abi.decode(result, (uint256));\n if (amountOut < minAmountOut) revert AmountOutTooLow(amountOut, minAmountOut);\n }\n\n /// @notice Copied from 1Inch contract, used to revert if there is an error\n function _revertBytes(bytes memory errMsg) internal pure {\n if (errMsg.length != 0) {\n //solhint-disable-next-line\n assembly {\n revert(add(32, errMsg), mload(errMsg))\n }\n }\n revert RevertBytes();\n }\n\n /// @notice Approve a `spender` for `token`\n /// @param token Address of the token to approve\n /// @param spender Address of the spender to approve\n /// @param amount Amount to approve\n function approve(IERC20 token, address spender, uint256 amount) external onlyRole(KEEPER_ROLE) {\n uint256 currentAllowance = token.allowance(address(this), spender);\n if (currentAllowance < amount) {\n token.safeIncreaseAllowance(spender, amount - currentAllowance);\n } else if (currentAllowance > amount) {\n token.safeDecreaseAllowance(spender, currentAllowance - amount);\n }\n }\n\n receive() external payable {}\n\n /// @notice Withdraw stuck funds\n /// @param token Address of the token to recover\n /// @param receiver Address where to send the tokens\n /// @param amount Amount to recover\n function withdrawStuckFunds(address token, address receiver, uint256 amount) external onlyRole(KEEPER_ROLE) {\n if (receiver == address(0)) revert ZeroAddress();\n if (token == 0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE) {\n payable(receiver).transfer(amount);\n } else {\n IERC20(token).safeTransfer(receiver, amount);\n }\n\n emit Recovered(token, receiver, amount);\n }\n}\n" + }, + "contracts/keeperMulticall/MulticallWithFailure.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.12;\n\n/// @title MultiCallWithFailure\n/// @author Angle Labs, Inc.\n/// @notice Multicall contract allowing subcalls to fail without reverting the entire call\ncontract MultiCallWithFailure {\n error SubcallFailed();\n\n struct Call {\n address target;\n bytes data;\n bool canFail;\n }\n\n function multiCall(Call[] memory calls) external view returns (bytes[] memory) {\n bytes[] memory results = new bytes[](calls.length);\n\n for (uint256 i; i < calls.length; ++i) {\n (bool success, bytes memory result) = calls[i].target.staticcall(calls[i].data);\n if (!calls[i].canFail) {\n if (!success) {\n revert SubcallFailed();\n }\n }\n results[i] = result;\n }\n\n return results;\n }\n}\n" + }, + "contracts/keeperMulticall/RevertReasonParser.sol": { + "content": "// SPDX-License-Identifier: GNU-3\n\npragma solidity ^0.8.12;\n\n/// @title RevertReasonParser\n/// @author 1Inch team, taken from:\n/// - https://docs.1inch.io/docs/limit-order-protocol/smart-contract/libraries/RevertReasonParser/\n/// - https://etherscan.io/address/0x1111111254fb6c44bAC0beD2854e76F90643097d#code\nlibrary RevertReasonParser {\n bytes4 private constant _PANIC_SELECTOR = bytes4(keccak256(\"Panic(uint256)\"));\n bytes4 private constant _ERROR_SELECTOR = bytes4(keccak256(\"Error(string)\"));\n\n function parse(bytes memory data, string memory prefix) internal pure returns (string memory) {\n if (data.length >= 4) {\n bytes4 selector;\n //solhint-disable-next-line\n assembly {\n selector := mload(add(data, 0x20))\n }\n\n // 68 = 4-byte selector + 32 bytes offset + 32 bytes length\n if (selector == _ERROR_SELECTOR && data.length >= 68) {\n uint256 offset;\n bytes memory reason;\n // solhint-disable no-inline-assembly\n assembly {\n // 36 = 32 bytes data length + 4-byte selector\n offset := mload(add(data, 36))\n reason := add(data, add(36, offset))\n }\n /*\n revert reason is padded up to 32 bytes with ABI encoder: Error(string)\n also sometimes there is extra 32 bytes of zeros padded in the end:\n https://github.com/ethereum/solidity/issues/10170\n because of that we can't check for equality and instead check\n that offset + string length + extra 36 bytes is less than overall data length\n */\n require(data.length >= 36 + offset + reason.length, \"Invalid revert reason\");\n return string(abi.encodePacked(prefix, \"Error(\", reason, \")\"));\n }\n // 36 = 4-byte selector + 32 bytes integer\n else if (selector == _PANIC_SELECTOR && data.length == 36) {\n uint256 code;\n // solhint-disable no-inline-assembly\n assembly {\n // 36 = 32 bytes data length + 4-byte selector\n code := mload(add(data, 36))\n }\n return string(abi.encodePacked(prefix, \"Panic(\", _toHex(code), \")\"));\n }\n }\n\n return string(abi.encodePacked(prefix, \"Unknown(\", _toHex(data), \")\"));\n }\n\n function _toHex(uint256 value) private pure returns (string memory) {\n return _toHex(abi.encodePacked(value));\n }\n\n function _toHex(bytes memory data) private pure returns (string memory) {\n bytes16 alphabet = 0x30313233343536373839616263646566;\n bytes memory str = new bytes(2 + data.length * 2);\n str[0] = \"0\";\n str[1] = \"x\";\n for (uint256 i; i < data.length; ++i) {\n str[2 * i + 2] = alphabet[uint8(data[i] >> 4)];\n str[2 * i + 3] = alphabet[uint8(data[i] & 0x0f)];\n }\n return string(str);\n }\n}\n" + }, + "contracts/mock/Mock1Inch.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.12;\n\nimport \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\nimport \"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\";\n\ncontract Mock1Inch {\n using SafeERC20 for IERC20;\n\n function swap(address tokenIn, uint256 amountIn, address to, address tokenOut, uint256 amountOut) external {\n IERC20(tokenIn).safeTransferFrom(msg.sender, to, amountIn);\n if (tokenOut == 0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE) {\n //solhint-disable-next-line\n (bool sent, bytes memory data) = msg.sender.call{ value: amountOut }(\"\");\n data;\n require(sent, \"Failed to send Ether\");\n } else {\n IERC20(tokenOut).safeTransferFrom(to, msg.sender, amountOut);\n }\n }\n\n receive() external payable {}\n}\n" + }, + "contracts/mock/MockAnything.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.12;\n\ncontract MockAnything {\n uint256 public stateVar = 1;\n\n error CustomError();\n error CustomErrorWithValue(uint256);\n\n function fail(uint256 value) external view returns (uint256) {\n stateVar;\n if (value < 10) {\n revert CustomError();\n }\n if (value < 20) {\n revert CustomErrorWithValue(value);\n }\n return value + 1;\n }\n\n function modifyState(uint256 value) external {\n stateVar = value;\n }\n}\n" + }, + "contracts/mock/MockChainlinkOracle.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.7;\n\ninterface MockAggregatorV3Interface {\n function decimals() external view returns (uint8);\n\n function description() external view returns (string memory);\n\n function version() external view returns (uint256);\n\n function getRoundData(\n uint80 _roundId\n )\n external\n view\n returns (uint80 roundId, int256 answer, uint256 startedAt, uint256 updatedAt, uint80 answeredInRound);\n\n function latestRoundData()\n external\n view\n returns (uint80 roundId, int256 answer, uint256 startedAt, uint256 updatedAt, uint80 answeredInRound);\n}\n\ncontract MockChainlinkOracle is MockAggregatorV3Interface {\n uint80 public roundId = 0;\n uint8 public keyDecimals = 0;\n\n struct Entry {\n uint80 roundId;\n int256 answer;\n uint256 startedAt;\n uint256 updatedAt;\n uint80 answeredInRound;\n }\n\n mapping(uint256 => Entry) public entries;\n\n bool public latestRoundDataShouldRevert;\n\n string public desc;\n\n constructor() {}\n\n // Mock setup function\n function setLatestAnswer(int256 answer, uint256 timestamp) external {\n roundId++;\n entries[roundId] = Entry({\n roundId: roundId,\n answer: answer,\n startedAt: timestamp,\n updatedAt: timestamp,\n answeredInRound: roundId\n });\n }\n\n function setLatestAnswerWithRound(int256 answer, uint256 timestamp, uint80 _roundId) external {\n roundId = _roundId;\n entries[roundId] = Entry({\n roundId: roundId,\n answer: answer,\n startedAt: timestamp,\n updatedAt: timestamp,\n answeredInRound: roundId\n });\n }\n\n function setLatestAnswerRevert(int256 answer, uint256 timestamp) external {\n roundId++;\n entries[roundId] = Entry({\n roundId: roundId,\n answer: answer,\n startedAt: timestamp,\n updatedAt: timestamp,\n answeredInRound: roundId - 1\n });\n }\n\n function setLatestRoundDataShouldRevert(bool _shouldRevert) external {\n latestRoundDataShouldRevert = _shouldRevert;\n }\n\n function setDecimals(uint8 _decimals) external {\n keyDecimals = _decimals;\n }\n\n function setDescritpion(string memory _desc) external {\n desc = _desc;\n }\n\n function description() external view override returns (string memory) {\n return desc;\n }\n\n function version() external view override returns (uint256) {\n roundId;\n return 0;\n }\n\n function latestRoundData() external view override returns (uint80, int256, uint256, uint256, uint80) {\n if (latestRoundDataShouldRevert) {\n revert(\"latestRoundData reverted\");\n }\n return getRoundData(uint80(roundId));\n }\n\n function decimals() external view override returns (uint8) {\n return keyDecimals;\n }\n\n function getRoundData(uint80 _roundId) public view override returns (uint80, int256, uint256, uint256, uint80) {\n Entry memory entry = entries[_roundId];\n // Emulate a Chainlink aggregator\n require(entry.updatedAt > 0, \"No data present\");\n return (entry.roundId, entry.answer, entry.startedAt, entry.updatedAt, entry.answeredInRound);\n }\n}\n" + }, + "contracts/mock/MockCoreBorrow.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\nimport \"../interfaces/ICoreBorrow.sol\";\nimport \"../interfaces/IFlashAngle.sol\";\nimport \"../interfaces/ITreasury.sol\";\n\ncontract MockCoreBorrow is ICoreBorrow {\n mapping(address => bool) public flashLoaners;\n mapping(address => bool) public governors;\n mapping(address => bool) public guardians;\n\n function isFlashLoanerTreasury(address treasury) external view override returns (bool) {\n return flashLoaners[treasury];\n }\n\n function isGovernor(address admin) external view override returns (bool) {\n return governors[admin];\n }\n\n function isGovernorOrGuardian(address admin) external view override returns (bool) {\n return governors[admin] || guardians[admin];\n }\n\n function toggleGovernor(address admin) external {\n governors[admin] = !governors[admin];\n }\n\n function toggleGuardian(address admin) external {\n guardians[admin] = !guardians[admin];\n }\n\n function toggleFlashLoaners(address admin) external {\n flashLoaners[admin] = !flashLoaners[admin];\n }\n\n function addStablecoinSupport(IFlashAngle flashAngle, address _treasury) external {\n flashAngle.addStablecoinSupport(_treasury);\n }\n\n function removeStablecoinSupport(IFlashAngle flashAngle, address _treasury) external {\n flashAngle.removeStablecoinSupport(_treasury);\n }\n\n function setCore(IFlashAngle flashAngle, address _core) external {\n flashAngle.setCore(_core);\n }\n\n function setFlashLoanModule(ITreasury _treasury, address _flashLoanModule) external {\n _treasury.setFlashLoanModule(_flashLoanModule);\n }\n}\n" + }, + "contracts/mock/MockERC1271.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.12;\n\nimport \"../interfaces/external/IERC1271.sol\";\n\ncontract MockERC1271 is IERC1271 {\n uint256 public mode = 0;\n\n function setMode(uint256 _mode) public {\n mode = _mode;\n }\n\n /// @notice Returns whether the provided signature is valid for the provided data\n /// @dev MUST return the bytes4 magic value 0x1626ba7e when function passes.\n /// MUST NOT modify state (using STATICCALL for solc < 0.5, view modifier for solc > 0.5).\n /// MUST allow external calls.\n /// @return magicValue The bytes4 magic value 0x1626ba7e\n function isValidSignature(bytes32, bytes memory) external view returns (bytes4 magicValue) {\n if (mode == 1) magicValue = 0x1626ba7e;\n }\n}\n" + }, + "contracts/mock/MockERC721Receiver.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (token/ERC721/utils/ERC721Holder.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Implementation of the {IERC721Receiver} interface.\n *\n * Accepts all token transfers.\n * Make sure the contract is able to use its token with {IERC721-safeTransferFrom}, {IERC721-approve} or {IERC721-setApprovalForAll}.\n */\ncontract MockERC721Receiver {\n uint256 public mode = 0;\n\n function setMode(uint256 _mode) public {\n mode = _mode;\n }\n\n function onERC721Received(address, address, uint256, bytes memory) public view returns (bytes4) {\n require(mode != 1, \"0x1111111\");\n if (mode == 2) return this.setMode.selector;\n return this.onERC721Received.selector;\n }\n}\n" + }, + "contracts/mock/MockEulerPool.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\nimport \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\n\ncontract MockEulerPool {\n IERC20 public collateral;\n uint256 public poolSize;\n //solhint-disable-next-line\n uint256 public MAX_SANE_AMOUNT;\n\n mapping(address => uint256) public users;\n uint256 public interestRateAccumulator;\n\n constructor(IERC20 collateral_, uint256 poolSize_) {\n collateral = collateral_;\n poolSize = poolSize_;\n interestRateAccumulator = 10 ** 18;\n MAX_SANE_AMOUNT = type(uint112).max;\n }\n\n function setPoolSize(uint256 poolSize_) external {\n uint256 balance = collateral.balanceOf(address(this));\n poolSize = poolSize_;\n if (balance > poolSize_) collateral.transfer(msg.sender, balance - poolSize_);\n if (balance < poolSize_) collateral.transferFrom(msg.sender, address(this), poolSize_ - balance);\n }\n\n function setInterestRateAccumulator(uint256 interestRateAccumulator_) external {\n interestRateAccumulator = interestRateAccumulator_;\n }\n\n //solhint-disable-next-line\n function setMAXSANEAMOUNT(uint256 MAX_SANE_AMOUNT_) external {\n MAX_SANE_AMOUNT = MAX_SANE_AMOUNT_;\n }\n\n function balanceOfUnderlying(address account) external view returns (uint256) {\n return (users[account] * interestRateAccumulator) / 10 ** 18;\n }\n\n function deposit(uint256, uint256 amount) external {\n users[msg.sender] += (amount * 10 ** 18) / interestRateAccumulator;\n poolSize += amount;\n collateral.transferFrom(msg.sender, address(this), amount);\n }\n\n function withdraw(uint256, uint256 amount) external {\n if (amount == type(uint256).max) amount = (users[msg.sender] * interestRateAccumulator) / 10 ** 18;\n\n require(amount <= poolSize, \"4\");\n users[msg.sender] -= (amount * 10 ** 18) / interestRateAccumulator;\n collateral.transfer(msg.sender, amount);\n }\n}\n" + }, + "contracts/mock/MockFlashLoanModule.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\nimport \"../interfaces/IFlashAngle.sol\";\nimport \"../interfaces/ICoreBorrow.sol\";\n\ncontract MockFlashLoanModule is IFlashAngle {\n ICoreBorrow public override core;\n mapping(address => bool) public stablecoinsSupported;\n mapping(IAgToken => uint256) public interestAccrued;\n uint256 public surplusValue;\n\n constructor(ICoreBorrow _core) {\n core = _core;\n }\n\n function accrueInterestToTreasury(IAgToken stablecoin) external override returns (uint256 balance) {\n balance = surplusValue;\n interestAccrued[stablecoin] += balance;\n }\n\n function addStablecoinSupport(address _treasury) external override {\n stablecoinsSupported[_treasury] = true;\n }\n\n function removeStablecoinSupport(address _treasury) external override {\n stablecoinsSupported[_treasury] = false;\n }\n\n function setCore(address _core) external override {\n core = ICoreBorrow(_core);\n }\n\n function setSurplusValue(uint256 _surplusValue) external {\n surplusValue = _surplusValue;\n }\n}\n" + }, + "contracts/mock/MockFlashLoanReceiver.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.7;\n\nimport \"@openzeppelin/contracts/token/ERC20/ERC20.sol\";\n\nimport \"@openzeppelin/contracts/interfaces/IERC3156FlashBorrower.sol\";\n\nimport \"@openzeppelin/contracts/interfaces/IERC3156FlashLender.sol\";\n\ncontract MockFlashLoanReceiver is IERC3156FlashBorrower {\n bytes32 public constant CALLBACK_SUCCESS = keccak256(\"ERC3156FlashBorrower.onFlashLoan\");\n\n constructor() {}\n\n function onFlashLoan(\n address,\n address token,\n uint256 amount,\n uint256 fee,\n bytes calldata data\n ) external override returns (bytes32) {\n IERC20(token).approve(msg.sender, amount + fee);\n if (amount >= 10 ** 21) return keccak256(\"error\");\n if (amount == 2 * 10 ** 18) {\n IERC3156FlashLender(msg.sender).flashLoan(IERC3156FlashBorrower(address(this)), token, amount, data);\n return keccak256(\"reentrant\");\n } else return CALLBACK_SUCCESS;\n }\n}\n" + }, + "contracts/mock/MockInterestRateComputer.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\ncontract MockInterestRateComputer {\n uint256 public interestRate;\n uint256 public interestAccumulator;\n uint256 public immutable baseInterest;\n uint256 public immutable halfBase;\n\n uint256 public constant WEEK = 7 * 86400;\n\n constructor(uint256 _baseInterest, uint256 _interestRate) {\n interestAccumulator = _baseInterest;\n baseInterest = _baseInterest;\n halfBase = _baseInterest / 2;\n interestRate = _interestRate;\n }\n\n function _calculateAngle(uint256 exp, uint256 _interestAccumulator) internal view returns (uint256) {\n uint256 ratePerSecond = interestRate;\n if (exp == 0 || ratePerSecond == 0) return _interestAccumulator;\n uint256 expMinusOne = exp - 1;\n uint256 expMinusTwo = exp > 2 ? exp - 2 : 0;\n uint256 basePowerTwo = (ratePerSecond * ratePerSecond) / baseInterest;\n uint256 basePowerThree = (basePowerTwo * ratePerSecond) / baseInterest;\n uint256 secondTerm = (exp * expMinusOne * basePowerTwo) / 2;\n uint256 thirdTerm = (exp * expMinusOne * expMinusTwo * basePowerThree) / 6;\n return (_interestAccumulator * (baseInterest + ratePerSecond * exp + secondTerm + thirdTerm)) / baseInterest;\n }\n\n function _calculateAave(uint256 exp, uint256 _interestAccumulator) internal view returns (uint256) {\n uint256 ratePerSecond = interestRate;\n if (exp == 0 || ratePerSecond == 0) return _interestAccumulator;\n uint256 expMinusOne = exp - 1;\n uint256 expMinusTwo = exp > 2 ? exp - 2 : 0;\n uint256 basePowerTwo = (ratePerSecond * ratePerSecond + halfBase) / baseInterest;\n uint256 basePowerThree = (basePowerTwo * ratePerSecond + halfBase) / baseInterest;\n uint256 secondTerm = (exp * expMinusOne * basePowerTwo) / 2;\n uint256 thirdTerm = (exp * expMinusOne * expMinusTwo * basePowerThree) / 6;\n return (_interestAccumulator * (baseInterest + ratePerSecond * exp + secondTerm + thirdTerm)) / baseInterest;\n }\n\n function _calculateCompound(uint256 exp, uint256 _interestAccumulator) internal view returns (uint256) {\n return _interestAccumulator * (baseInterest + interestRate * exp);\n }\n\n function _rpow(uint256 x, uint256 n, uint256 base) internal pure returns (uint256 z) {\n //solhint-disable-next-line\n assembly {\n switch x\n case 0 {\n switch n\n case 0 {\n z := base\n }\n default {\n z := 0\n }\n }\n default {\n switch mod(n, 2)\n case 0 {\n z := base\n }\n default {\n z := x\n }\n let half := div(base, 2) // for rounding.\n for {\n n := div(n, 2)\n } n {\n n := div(n, 2)\n } {\n let xx := mul(x, x)\n if iszero(eq(div(xx, x), x)) {\n revert(0, 0)\n }\n let xxRound := add(xx, half)\n if lt(xxRound, xx) {\n revert(0, 0)\n }\n x := div(xxRound, base)\n if mod(n, 2) {\n let zx := mul(z, x)\n if and(iszero(iszero(x)), iszero(eq(div(zx, x), z))) {\n revert(0, 0)\n }\n let zxRound := add(zx, half)\n if lt(zxRound, zx) {\n revert(0, 0)\n }\n z := div(zxRound, base)\n }\n }\n }\n }\n }\n\n function _calculateMaker(uint256 delta, uint256 _interestAccumulator) internal view returns (uint256) {\n return (_rpow(baseInterest + interestRate, delta, baseInterest) * _interestAccumulator) / baseInterest;\n }\n\n function calculateAngle(uint256 delta) external view returns (uint256) {\n return _calculateAngle(delta, interestAccumulator);\n }\n\n function calculateAave(uint256 delta) external view returns (uint256) {\n return _calculateAave(delta, interestAccumulator);\n }\n\n function calculateMaker(uint256 delta) external view returns (uint256) {\n return _calculateMaker(delta, interestAccumulator);\n }\n\n function calculateAngle1Year() external view returns (uint256) {\n uint256 _interestAccumulator = interestAccumulator;\n for (uint256 i; i < 52; ++i) {\n _interestAccumulator = _calculateAngle(WEEK, _interestAccumulator);\n }\n return _interestAccumulator;\n }\n\n function calculateAave1Year() external view returns (uint256) {\n uint256 _interestAccumulator = interestAccumulator;\n for (uint256 i; i < 52; ++i) {\n _interestAccumulator = _calculateAave(WEEK, _interestAccumulator);\n }\n return _interestAccumulator;\n }\n\n function calculateMaker1Year() external view returns (uint256) {\n uint256 _interestAccumulator = interestAccumulator;\n for (uint256 i; i < 52; ++i) {\n _interestAccumulator = _calculateMaker(WEEK, _interestAccumulator);\n }\n return _interestAccumulator;\n }\n\n function calculateAngle1YearDirect() external view returns (uint256) {\n uint256 _interestAccumulator = interestAccumulator;\n _interestAccumulator = _calculateAngle(52 * WEEK, _interestAccumulator);\n\n return _interestAccumulator;\n }\n\n function calculateAave1YearDirect() external view returns (uint256) {\n uint256 _interestAccumulator = interestAccumulator;\n _interestAccumulator = _calculateAave(52 * WEEK, _interestAccumulator);\n\n return _interestAccumulator;\n }\n\n function calculateMaker1YearDirect() external view returns (uint256) {\n uint256 _interestAccumulator = interestAccumulator;\n _interestAccumulator = _calculateMaker(52 * WEEK, _interestAccumulator);\n\n return _interestAccumulator;\n }\n\n function calculateCompound1YearDirect() external view returns (uint256) {\n uint256 _interestAccumulator = interestAccumulator;\n _interestAccumulator = _calculateCompound(52 * WEEK, _interestAccumulator);\n\n return _interestAccumulator;\n }\n}\n" + }, + "contracts/mock/MockKeeperMulticall.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.12;\n\nimport \"@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/access/AccessControlUpgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol\";\nimport \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\nimport \"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\";\n\ncontract MockKeeperMulticall is Initializable, AccessControlUpgradeable {\n using SafeERC20 for IERC20;\n\n bytes32 public constant KEEPER_ROLE = keccak256(\"KEEPER_ROLE\");\n\n //solhint-disable-next-line\n address private constant _oneInch = 0x1111111254fb6c44bAC0beD2854e76F90643097d;\n\n struct Action {\n address target;\n bytes data;\n bool isDelegateCall;\n }\n\n event LogAction(address indexed target, bytes data);\n event SentToMiner(uint256 indexed value);\n event Recovered(address indexed tokenAddress, address indexed to, uint256 amount);\n\n error AmountOutTooLow(uint256 amount, uint256 min);\n error BalanceTooLow();\n error FlashbotsErrorPayingMiner(uint256 value);\n error IncompatibleLengths();\n error RevertBytes();\n error ZeroAddress();\n\n constructor() initializer {}\n\n function initialize(address keeper) public initializer {\n __AccessControl_init();\n\n _setupRole(KEEPER_ROLE, keeper);\n _setRoleAdmin(KEEPER_ROLE, KEEPER_ROLE);\n }\n}\n\ncontract MockKeeperMulticall2 {\n uint256 public varTest = 1;\n\n bytes32 public constant KEEPER_ROLE = keccak256(\"KEEPER_ROLE\");\n\n //solhint-disable-next-line\n address private constant _oneInch = 0x1111111254fb6c44bAC0beD2854e76F90643097d;\n\n struct Action {\n address target;\n bytes data;\n bool isDelegateCall;\n }\n\n event LogAction(address indexed target, bytes data);\n event SentToMiner(uint256 indexed value);\n event Recovered(address indexed tokenAddress, address indexed to, uint256 amount);\n\n error AmountOutTooLow(uint256 amount, uint256 min);\n error BalanceTooLow();\n error FlashbotsErrorPayingMiner(uint256 value);\n error IncompatibleLengths();\n error RevertBytes();\n error ZeroAddress();\n\n function functionTest() external pure returns (bool) {\n return true;\n }\n}\n" + }, + "contracts/mock/MockLayerZero.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\ninterface ILzApp {\n function lzReceive(uint16 _srcChainId, bytes memory _srcAddress, uint64 _nonce, bytes memory _payload) external;\n}\n\ncontract MockLayerZero {\n mapping(uint16 => uint256) public counters;\n uint256 public config;\n mapping(uint16 => uint64) public outboundNonce;\n uint256 public resumeReceived;\n uint256 public sendVersion;\n uint256 public receiveVersion;\n\n /// @notice Initiate with a fixe change rate\n constructor() {}\n\n function send(\n uint16 _dstChainId,\n bytes calldata,\n bytes calldata,\n address,\n address,\n bytes calldata\n ) external payable {\n counters[_dstChainId] += 1;\n }\n\n function getOutboundNonce(uint16 _dstChainId, address) external view returns (uint64) {\n return outboundNonce[_dstChainId];\n }\n\n function setOutBoundNonce(uint16 _from, uint64 value) external {\n outboundNonce[_from] = value;\n }\n\n function lzReceive(\n address lzApp,\n uint16 _srcChainId,\n bytes memory _srcAddress,\n uint64 _nonce,\n bytes memory _payload\n ) public {\n ILzApp(lzApp).lzReceive(_srcChainId, _srcAddress, _nonce, _payload);\n }\n\n function estimateFees(\n uint16,\n address,\n bytes calldata,\n bool,\n bytes calldata\n ) external pure returns (uint256 nativeFee, uint256 zroFee) {\n return (123, 456);\n }\n\n function setConfig(uint16, uint16, uint256 _configType, bytes calldata) external {\n config = _configType;\n }\n\n function getConfig(uint16, uint16, address, uint256) external view returns (bytes memory) {\n return abi.encodePacked(config);\n }\n\n function setSendVersion(uint16 _version) external {\n sendVersion = _version;\n }\n\n function setReceiveVersion(uint16 _version) external {\n receiveVersion = _version;\n }\n\n function forceResumeReceive(uint16, bytes calldata) external {\n resumeReceived = 1 - resumeReceived;\n }\n}\n" + }, + "contracts/mock/MockLiquidityGauge.sol": { + "content": "// SPDX-License-Identifier: UNLICENSED\npragma solidity ^0.8.12;\n\nimport { ILiquidityGauge } from \"../interfaces/coreModule/ILiquidityGauge.sol\";\nimport \"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\";\nimport \"@openzeppelin/contracts/token/ERC20/ERC20.sol\";\n\ncontract MockLiquidityGauge is ILiquidityGauge, ERC20 {\n using SafeERC20 for IERC20;\n\n IERC20 internal _ANGLE = IERC20(0x31429d1856aD1377A8A0079410B297e1a9e214c2);\n IERC20 internal _token;\n mapping(address => uint256) public rewards;\n\n constructor(string memory name_, string memory symbol_, address token_) ERC20(name_, symbol_) {\n _token = IERC20(token_);\n }\n\n function deposit(\n uint256 _value,\n address _addr,\n // solhint-disable-next-line\n bool\n ) external {\n _token.safeTransferFrom(msg.sender, address(this), _value);\n _mint(_addr, _value);\n }\n\n function withdraw(\n uint256 _value,\n // solhint-disable-next-line\n bool\n ) external {\n _burn(msg.sender, _value);\n _token.safeTransfer(msg.sender, _value);\n }\n\n // solhint-disable-next-line\n function claim_rewards(address _addr, address _receiver) external {\n if (_receiver == address(0)) _receiver = _addr;\n _ANGLE.safeTransfer(_receiver, rewards[_addr]);\n rewards[_addr] = 0;\n }\n\n // solhint-disable-next-line\n function claimable_reward(address _addr, address) external view returns (uint256 amount) {\n return rewards[_addr];\n }\n\n function setReward(address receiver_, uint256 amount) external {\n rewards[receiver_] = amount;\n }\n}\n" + }, + "contracts/mock/MockOracle.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.7;\n\nimport \"../interfaces/IOracle.sol\";\n\ncontract MockOracle is IOracle {\n event Update(uint256 _peg);\n\n ITreasury public treasury;\n\n uint256 public base = 1 ether;\n uint256 public precision = 1 ether;\n uint256 public rate;\n bool public outdated;\n\n /// @notice Initiate with a fixe change rate\n constructor(uint256 rate_, ITreasury _treasury) {\n rate = rate_;\n treasury = _treasury;\n }\n\n /// @notice Mock read\n function read() external view override returns (uint256) {\n return rate;\n }\n\n /// @notice change oracle rate\n function update(uint256 newRate) external {\n rate = newRate;\n }\n\n function setTreasury(address _treasury) external override {\n treasury = ITreasury(_treasury);\n }\n\n function circuitChainlink() external pure override returns (AggregatorV3Interface[] memory) {}\n}\n" + }, + "contracts/mock/MockPolygonAgEUR.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.12;\n\nimport \"../agToken/polygon/utils/ERC20UpgradeableCustom.sol\";\nimport \"@openzeppelin/contracts-upgradeable/access/AccessControlUpgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/utils/cryptography/draft-EIP712Upgradeable.sol\";\nimport \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\nimport \"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\";\n\nimport \"../interfaces/IAgToken.sol\";\nimport \"../interfaces/ITreasury.sol\";\n\ninterface IChildToken {\n function deposit(address user, bytes calldata depositData) external;\n\n function withdraw(uint256 amount) external;\n}\n\ncontract MockPolygonAgEUR is\n Initializable,\n ERC20UpgradeableCustom,\n AccessControlUpgradeable,\n EIP712Upgradeable,\n IChildToken\n{\n bytes32 public constant DEPOSITOR_ROLE = keccak256(\"DEPOSITOR_ROLE\");\n\n /// @dev Emitted when the child chain manager changes\n event ChildChainManagerAdded(address newAddress);\n event ChildChainManagerRevoked(address oldAddress);\n\n constructor() initializer {}\n\n function initialize(\n string memory _name,\n string memory _symbol,\n address childChainManager,\n address guardian\n ) public initializer {\n __ERC20_init(_name, _symbol);\n __AccessControl_init();\n _setupRole(DEFAULT_ADMIN_ROLE, guardian);\n _setupRole(DEPOSITOR_ROLE, childChainManager);\n __EIP712_init(_name, \"1\");\n }\n\n /**\n * @notice Called when the bridge has tokens to mint\n * @param user Address to mint the token to\n * @param depositData Encoded amount to mint\n */\n function deposit(address user, bytes calldata depositData) external override {\n require(hasRole(DEPOSITOR_ROLE, msg.sender));\n uint256 amount = abi.decode(depositData, (uint256));\n _mint(user, amount);\n }\n\n /**\n * @notice Called when user wants to withdraw tokens back to root chain\n * @dev Should burn user's tokens. This transaction will be verified when exiting on root chain\n * @param amount Amount of tokens to withdraw\n */\n function withdraw(uint256 amount) external override {\n _burn(_msgSender(), amount);\n }\n\n // =============================================================================\n // ======================= New data added for the upgrade ======================\n // =============================================================================\n\n mapping(address => bool) public isMinter;\n /// @notice Reference to the treasury contract which can grant minting rights\n address public treasury;\n /// @notice Boolean to check whether the contract has been reinitialized after its upgrade\n bool public treasuryInitialized;\n\n using SafeERC20 for IERC20;\n\n /// @notice Base used for fee computation\n uint256 public constant BASE_PARAMS = 10 ** 9;\n\n // =============================== Bridging Data ===============================\n\n /// @notice Struct with some data about a specific bridge token\n struct BridgeDetails {\n // Limit on the balance of bridge token held by the contract: it is designed\n // to reduce the exposure of the system to hacks\n uint256 limit;\n // Limit on the hourly volume of token minted through this bridge\n // Technically the limit over a rolling hour is hourlyLimit x2 as hourly limit\n // is enforced only between x:00 and x+1:00\n uint256 hourlyLimit;\n // Fee taken for swapping in and out the token\n uint64 fee;\n // Whether the associated token is allowed or not\n bool allowed;\n // Whether swapping in and out from the associated token is paused or not\n bool paused;\n }\n\n /// @notice Maps a bridge token to data\n mapping(address => BridgeDetails) public bridges;\n /// @notice List of all bridge tokens\n address[] public bridgeTokensList;\n /// @notice Maps a bridge token to the associated hourly volume\n mapping(address => mapping(uint256 => uint256)) public usage;\n /// @notice Maps an address to whether it is exempt of fees for when it comes to swapping in and out\n mapping(address => uint256) public isFeeExempt;\n\n uint256[44] private __gap;\n\n // ================================== Events ===================================\n\n event BridgeTokenAdded(address indexed bridgeToken, uint256 limit, uint256 hourlyLimit, uint64 fee, bool paused);\n event BridgeTokenToggled(address indexed bridgeToken, bool toggleStatus);\n event BridgeTokenRemoved(address indexed bridgeToken);\n event BridgeTokenFeeUpdated(address indexed bridgeToken, uint64 fee);\n event BridgeTokenLimitUpdated(address indexed bridgeToken, uint256 limit);\n event BridgeTokenHourlyLimitUpdated(address indexed bridgeToken, uint256 hourlyLimit);\n event HourlyLimitUpdated(uint256 hourlyLimit);\n event FeeToggled(address indexed theAddress, uint256 toggleStatus);\n event KeeperToggled(address indexed keeper, bool toggleStatus);\n event MinterToggled(address indexed minter);\n event Recovered(address indexed token, address indexed to, uint256 amount);\n event TreasuryUpdated(address indexed _treasury);\n\n // ================================== Errors ===================================\n\n error AssetStillControlledInReserves();\n error BurnAmountExceedsAllowance();\n error HourlyLimitExceeded();\n error InvalidSender();\n error InvalidToken();\n error InvalidTreasury();\n error NotGovernor();\n error NotGovernorOrGuardian();\n error NotMinter();\n error NotTreasury();\n error TooBigAmount();\n error TooHighParameterValue();\n error TreasuryAlreadyInitialized();\n error ZeroAddress();\n\n /// @notice Checks to see if it is the `Treasury` calling this contract\n /// @dev There is no Access Control here, because it can be handled cheaply through this modifier\n modifier onlyTreasury() {\n if (msg.sender != treasury) revert NotTreasury();\n _;\n }\n\n /// @notice Checks whether the sender has the minting right\n modifier onlyMinter() {\n if (!isMinter[msg.sender]) revert NotMinter();\n _;\n }\n\n /// @notice Checks whether the `msg.sender` has the governor role or not\n modifier onlyGovernor() {\n if (!ITreasury(treasury).isGovernor(msg.sender)) revert NotGovernor();\n _;\n }\n\n /// @notice Checks whether the `msg.sender` has the governor role or the guardian role\n modifier onlyGovernorOrGuardian() {\n if (!ITreasury(treasury).isGovernorOrGuardian(msg.sender)) revert NotGovernorOrGuardian();\n _;\n }\n\n /// @notice Sets up the treasury contract on Polygon after the upgrade\n /// @param _treasury Address of the treasury contract\n function setUpTreasury(address _treasury) external {\n // Only governor on Polygon\n if (msg.sender != 0xdA2D2f638D6fcbE306236583845e5822554c02EA) revert NotGovernor();\n if (address(ITreasury(_treasury).stablecoin()) != address(this)) revert InvalidTreasury();\n if (treasuryInitialized) revert TreasuryAlreadyInitialized();\n treasury = _treasury;\n treasuryInitialized = true;\n emit TreasuryUpdated(_treasury);\n }\n\n // =========================== External Function ===============================\n\n /// @notice Allows anyone to burn agToken without redeeming collateral back\n /// @param amount Amount of stablecoins to burn\n /// @dev This function can typically be called if there is a settlement mechanism to burn stablecoins\n function burnStablecoin(uint256 amount) external {\n _burnCustom(msg.sender, amount);\n }\n\n // ======================= Minter Role Only Functions ==========================\n\n function burnSelf(uint256 amount, address burner) external onlyMinter {\n _burnCustom(burner, amount);\n }\n\n function burnFrom(uint256 amount, address burner, address sender) external onlyMinter {\n _burnFromNoRedeem(amount, burner, sender);\n }\n\n function mint(address account, uint256 amount) external onlyMinter {\n _mint(account, amount);\n }\n\n // ======================= Treasury Only Functions =============================\n\n function addMinter(address minter) external onlyTreasury {\n isMinter[minter] = true;\n emit MinterToggled(minter);\n }\n\n function removeMinter(address minter) external {\n if (msg.sender != address(treasury) && msg.sender != minter) revert InvalidSender();\n isMinter[minter] = false;\n emit MinterToggled(minter);\n }\n\n function setTreasury(address _treasury) external onlyTreasury {\n treasury = _treasury;\n emit TreasuryUpdated(_treasury);\n }\n\n // ============================ Internal Function ==============================\n\n /// @notice Internal version of the function `burnFromNoRedeem`\n /// @param amount Amount to burn\n /// @dev It is at the level of this function that allowance checks are performed\n function _burnFromNoRedeem(uint256 amount, address burner, address sender) internal {\n if (burner != sender) {\n uint256 currentAllowance = allowance(burner, sender);\n if (currentAllowance < amount) revert BurnAmountExceedsAllowance();\n _approve(burner, sender, currentAllowance - amount);\n }\n _burnCustom(burner, amount);\n }\n\n // ==================== External Permissionless Functions ======================\n\n /// @notice Returns the list of all supported bridge tokens\n /// @dev Helpful for UIs\n function allBridgeTokens() external view returns (address[] memory) {\n return bridgeTokensList;\n }\n\n /// @notice Returns the current volume for a bridge, for the current hour\n /// @dev Helpful for UIs\n function currentUsage(address bridge) external view returns (uint256) {\n return usage[bridge][block.timestamp / 3600];\n }\n\n /// @notice Mints the canonical token from a supported bridge token\n /// @param bridgeToken Bridge token to use to mint\n /// @param amount Amount of bridge tokens to send\n /// @param to Address to which the stablecoin should be sent\n /// @dev Some fees may be taken by the protocol depending on the token used and on the address calling\n function swapIn(address bridgeToken, uint256 amount, address to) external returns (uint256) {\n BridgeDetails memory bridgeDetails = bridges[bridgeToken];\n if (!bridgeDetails.allowed || bridgeDetails.paused) revert InvalidToken();\n uint256 balance = IERC20(bridgeToken).balanceOf(address(this));\n if (balance + amount > bridgeDetails.limit) {\n // In case someone maliciously sends tokens to this contract\n // Or the limit changes\n if (bridgeDetails.limit > balance) amount = bridgeDetails.limit - balance;\n else {\n amount = 0;\n }\n }\n\n // Checking requirement on the hourly volume\n uint256 hour = block.timestamp / 3600;\n uint256 hourlyUsage = usage[bridgeToken][hour] + amount;\n if (hourlyUsage > bridgeDetails.hourlyLimit) {\n // Edge case when the hourly limit changes\n if (bridgeDetails.hourlyLimit > usage[bridgeToken][hour])\n amount = bridgeDetails.hourlyLimit - usage[bridgeToken][hour];\n else {\n amount = 0;\n }\n }\n usage[bridgeToken][hour] = usage[bridgeToken][hour] + amount;\n\n IERC20(bridgeToken).safeTransferFrom(msg.sender, address(this), amount);\n uint256 canonicalOut = amount;\n // Computing fees\n if (isFeeExempt[msg.sender] == 0) {\n canonicalOut -= (canonicalOut * bridgeDetails.fee) / BASE_PARAMS;\n }\n _mint(to, canonicalOut);\n return canonicalOut;\n }\n\n /// @notice Burns the canonical token in exchange for a bridge token\n /// @param bridgeToken Bridge token required\n /// @param amount Amount of canonical tokens to burn\n /// @param to Address to which the bridge token should be sent\n /// @dev Some fees may be taken by the protocol depending on the token used and on the address calling\n function swapOut(address bridgeToken, uint256 amount, address to) external returns (uint256) {\n BridgeDetails memory bridgeDetails = bridges[bridgeToken];\n if (!bridgeDetails.allowed || bridgeDetails.paused) revert InvalidToken();\n\n _burnCustom(msg.sender, amount);\n uint256 bridgeOut = amount;\n if (isFeeExempt[msg.sender] == 0) {\n bridgeOut -= (bridgeOut * bridgeDetails.fee) / BASE_PARAMS;\n }\n IERC20(bridgeToken).safeTransfer(to, bridgeOut);\n return bridgeOut;\n }\n\n // ======================= Governance Functions ================================\n\n /// @notice Adds support for a bridge token\n /// @param bridgeToken Bridge token to add: it should be a version of the stablecoin from another bridge\n /// @param limit Limit on the balance of bridge token this contract could hold\n /// @param hourlyLimit Limit on the hourly volume for this bridge\n /// @param paused Whether swapping for this token should be paused or not\n /// @param fee Fee taken upon swapping for or against this token\n function addBridgeToken(\n address bridgeToken,\n uint256 limit,\n uint256 hourlyLimit,\n uint64 fee,\n bool paused\n ) external onlyGovernor {\n if (bridges[bridgeToken].allowed || bridgeToken == address(0)) revert InvalidToken();\n if (fee > BASE_PARAMS) revert TooHighParameterValue();\n BridgeDetails memory _bridge;\n _bridge.limit = limit;\n _bridge.hourlyLimit = hourlyLimit;\n _bridge.paused = paused;\n _bridge.fee = fee;\n _bridge.allowed = true;\n bridges[bridgeToken] = _bridge;\n bridgeTokensList.push(bridgeToken);\n emit BridgeTokenAdded(bridgeToken, limit, hourlyLimit, fee, paused);\n }\n\n /// @notice Removes support for a token\n /// @param bridgeToken Address of the bridge token to remove support for\n function removeBridgeToken(address bridgeToken) external onlyGovernor {\n if (IERC20(bridgeToken).balanceOf(address(this)) != 0) revert AssetStillControlledInReserves();\n delete bridges[bridgeToken];\n // Deletion from `bridgeTokensList` loop\n uint256 bridgeTokensListLength = bridgeTokensList.length;\n for (uint256 i; i < bridgeTokensListLength - 1; ++i) {\n if (bridgeTokensList[i] == bridgeToken) {\n // Replace the `bridgeToken` to remove with the last of the list\n bridgeTokensList[i] = bridgeTokensList[bridgeTokensListLength - 1];\n break;\n }\n }\n // Remove last element in array\n bridgeTokensList.pop();\n emit BridgeTokenRemoved(bridgeToken);\n }\n\n /// @notice Recovers any ERC20 token\n /// @dev Can be used to withdraw bridge tokens for them to be de-bridged on mainnet\n function recoverERC20(address tokenAddress, address to, uint256 amountToRecover) external onlyGovernor {\n IERC20(tokenAddress).safeTransfer(to, amountToRecover);\n emit Recovered(tokenAddress, to, amountToRecover);\n }\n\n /// @notice Updates the `limit` amount for `bridgeToken`\n function setLimit(address bridgeToken, uint256 limit) external onlyGovernorOrGuardian {\n if (!bridges[bridgeToken].allowed) revert InvalidToken();\n bridges[bridgeToken].limit = limit;\n emit BridgeTokenLimitUpdated(bridgeToken, limit);\n }\n\n /// @notice Updates the `hourlyLimit` amount for `bridgeToken`\n function setHourlyLimit(address bridgeToken, uint256 hourlyLimit) external onlyGovernorOrGuardian {\n if (!bridges[bridgeToken].allowed) revert InvalidToken();\n bridges[bridgeToken].hourlyLimit = hourlyLimit;\n emit BridgeTokenHourlyLimitUpdated(bridgeToken, hourlyLimit);\n }\n\n /// @notice Updates the `fee` value for `bridgeToken`\n function setSwapFee(address bridgeToken, uint64 fee) external onlyGovernorOrGuardian {\n if (!bridges[bridgeToken].allowed) revert InvalidToken();\n if (fee > BASE_PARAMS) revert TooHighParameterValue();\n bridges[bridgeToken].fee = fee;\n emit BridgeTokenFeeUpdated(bridgeToken, fee);\n }\n\n /// @notice Pauses or unpauses swapping in and out for a token\n function toggleBridge(address bridgeToken) external onlyGovernorOrGuardian {\n if (!bridges[bridgeToken].allowed) revert InvalidToken();\n bool pausedStatus = bridges[bridgeToken].paused;\n bridges[bridgeToken].paused = !pausedStatus;\n emit BridgeTokenToggled(bridgeToken, !pausedStatus);\n }\n\n /// @notice Toggles fees for the address `theAddress`\n function toggleFeesForAddress(address theAddress) external onlyGovernorOrGuardian {\n uint256 feeExemptStatus = 1 - isFeeExempt[theAddress];\n isFeeExempt[theAddress] = feeExemptStatus;\n emit FeeToggled(theAddress, feeExemptStatus);\n }\n}\n" + }, + "contracts/mock/MockRouter.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\nimport \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\nimport \"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\";\n\nimport \"../interfaces/IAngleRouter.sol\";\nimport \"../interfaces/external/uniswap/IUniswapRouter.sol\";\nimport \"../interfaces/external/lido/IWStETH.sol\";\n\ncontract MockRouter is IUniswapV3Router, IWStETH {\n using SafeERC20 for IERC20;\n\n uint256 public counterAngleMint;\n uint256 public counterAngleBurn;\n uint256 public counter1Inch;\n uint256 public counterUni;\n uint256 public counterWrap;\n uint256 public counterMixer;\n uint256 public amountOutUni;\n uint256 public multiplierMintBurn;\n uint256 public stETHMultiplier;\n address public inToken;\n address public outToken;\n\n address public stETH;\n\n /// @notice Action types\n enum ActionType {\n transfer,\n wrap,\n wrapNative,\n sweep,\n sweepNative,\n unwrap,\n unwrapNative,\n swapIn,\n swapOut,\n uniswapV3,\n oneInch,\n claimRewards,\n gaugeDeposit,\n borrower\n }\n\n /// @notice Data needed to get permits\n struct PermitType {\n address token;\n address owner;\n uint256 value;\n uint256 deadline;\n uint8 v;\n bytes32 r;\n bytes32 s;\n }\n\n constructor() {}\n\n function mint(address user, uint256 amount, uint256, address stablecoin, address collateral) external {\n counterAngleMint += 1;\n IERC20(collateral).safeTransferFrom(msg.sender, address(this), amount);\n IERC20(stablecoin).safeTransfer(user, (amount * 10 ** 9) / multiplierMintBurn);\n }\n\n function setStETH(address _stETH) external {\n stETH = _stETH;\n }\n\n function burn(address user, uint256 amount, uint256, address stablecoin, address collateral) external {\n counterAngleBurn += 1;\n IERC20(stablecoin).safeTransferFrom(msg.sender, address(this), amount);\n IERC20(collateral).safeTransfer(user, (amount * multiplierMintBurn) / 10 ** 9);\n }\n\n function mixer(\n PermitType[] memory paramsPermit,\n ActionType[] memory actions,\n bytes[] calldata data\n ) public payable virtual {\n paramsPermit;\n counterMixer += 1;\n for (uint256 i; i < actions.length; ++i) {\n if (actions[i] == ActionType.transfer) {\n (address transferToken, uint256 amount) = abi.decode(data[i], (address, uint256));\n IERC20(transferToken).safeTransferFrom(msg.sender, address(this), amount);\n }\n }\n }\n\n function wrap(uint256 amount) external returns (uint256 amountOut) {\n amountOut = (amount * stETHMultiplier) / 10 ** 9;\n counterWrap += 1;\n IERC20(stETH).safeTransferFrom(msg.sender, address(this), amount);\n IERC20(outToken).safeTransfer(msg.sender, amountOut);\n }\n\n function oneInch(uint256 amountIn) external returns (uint256 amountOut) {\n counter1Inch += 1;\n amountOut = (amountOutUni * amountIn) / 10 ** 9;\n IERC20(inToken).safeTransferFrom(msg.sender, address(this), amountIn);\n IERC20(outToken).safeTransfer(msg.sender, amountOut);\n }\n\n function oneInchReverts() external {\n counter1Inch += 1;\n revert(\"wrong swap\");\n }\n\n function oneInchRevertsWithoutMessage() external {\n counter1Inch += 1;\n require(false);\n }\n\n function exactInput(ExactInputParams calldata params) external payable returns (uint256 amountOut) {\n counterUni += 1;\n amountOut = (params.amountIn * amountOutUni) / 10 ** 9;\n IERC20(inToken).safeTransferFrom(msg.sender, address(this), params.amountIn);\n IERC20(outToken).safeTransfer(params.recipient, amountOut);\n require(amountOut >= params.amountOutMinimum);\n }\n\n function setMultipliers(uint256 a, uint256 b) external {\n amountOutUni = a;\n multiplierMintBurn = b;\n }\n\n function setStETHMultiplier(uint256 value) external {\n stETHMultiplier = value;\n }\n\n function setInOut(address _collateral, address _stablecoin) external {\n inToken = _collateral;\n outToken = _stablecoin;\n }\n}\n" + }, + "contracts/mock/MockSidechainAgEUR.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\nimport \"../agToken/AgToken.sol\";\nimport \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\nimport \"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\";\n\n/// @title AgTokenSideChainMultiBridge\n/// @author Angle Labs, Inc.\n/// @notice Contract for Angle agTokens on other chains than Ethereum mainnet\n/// @dev This contract supports bridge tokens having a minting right on the stablecoin (also referred to as the canonical\n/// or the native token)\n/// @dev References:\n/// - FRAX implementation: https://polygonscan.com/address/0x45c32fA6DF82ead1e2EF74d17b76547EDdFaFF89#code\n/// - QiDAO implementation: https://snowtrace.io/address/0x5c49b268c9841AFF1Cc3B0a418ff5c3442eE3F3b#code\ncontract MockSidechainAgEUR is AgToken {\n using SafeERC20 for IERC20;\n\n /// @notice Base used for fee computation\n uint256 public constant BASE_PARAMS = 10 ** 9;\n\n // =============================== Bridging Data ===============================\n\n /// @notice Struct with some data about a specific bridge token\n struct BridgeDetails {\n // Limit on the balance of bridge token held by the contract: it is designed\n // to reduce the exposure of the system to hacks\n uint256 limit;\n // Limit on the hourly volume of token minted through this bridge\n // Technically the limit over a rolling hour is hourlyLimit x2 as hourly limit\n // is enforced only between x:00 and x+1:00\n uint256 hourlyLimit;\n // Fee taken for swapping in and out the token\n uint64 fee;\n // Whether the associated token is allowed or not\n bool allowed;\n // Whether swapping in and out from the associated token is paused or not\n bool paused;\n }\n\n /// @notice Maps a bridge token to data\n mapping(address => BridgeDetails) public bridges;\n /// @notice List of all bridge tokens\n address[] public bridgeTokensList;\n /// @notice Maps a bridge token to the associated hourly volume\n mapping(address => mapping(uint256 => uint256)) public usage;\n /// @notice Maps an address to whether it is exempt of fees for when it comes to swapping in and out\n mapping(address => uint256) public isFeeExempt;\n\n // ================================== Events ===================================\n\n event BridgeTokenAdded(address indexed bridgeToken, uint256 limit, uint256 hourlyLimit, uint64 fee, bool paused);\n event BridgeTokenToggled(address indexed bridgeToken, bool toggleStatus);\n event BridgeTokenRemoved(address indexed bridgeToken);\n event BridgeTokenFeeUpdated(address indexed bridgeToken, uint64 fee);\n event BridgeTokenLimitUpdated(address indexed bridgeToken, uint256 limit);\n event BridgeTokenHourlyLimitUpdated(address indexed bridgeToken, uint256 hourlyLimit);\n event HourlyLimitUpdated(uint256 hourlyLimit);\n event Recovered(address indexed token, address indexed to, uint256 amount);\n event FeeToggled(address indexed theAddress, uint256 toggleStatus);\n\n // =============================== Errors ================================\n\n error AssetStillControlledInReserves();\n error HourlyLimitExceeded();\n error InvalidToken();\n error NotGovernor();\n error NotGovernorOrGuardian();\n error TooBigAmount();\n error TooHighParameterValue();\n error ZeroAddress();\n\n // ============================= Constructor ===================================\n\n /// @notice Checks whether the `msg.sender` has the governor role or not\n modifier onlyGovernor() {\n if (!ITreasury(treasury).isGovernor(msg.sender)) revert NotGovernor();\n _;\n }\n\n /// @notice Checks whether the `msg.sender` has the governor role or the guardian role\n modifier onlyGovernorOrGuardian() {\n if (!ITreasury(treasury).isGovernorOrGuardian(msg.sender)) revert NotGovernorOrGuardian();\n _;\n }\n\n // ==================== External Permissionless Functions ======================\n\n /// @notice Returns the list of all supported bridge tokens\n /// @dev Helpful for UIs\n function allBridgeTokens() external view returns (address[] memory) {\n return bridgeTokensList;\n }\n\n /// @notice Returns the current volume for a bridge, for the current hour\n /// @param bridgeToken Bridge used to mint\n /// @dev Helpful for UIs\n function currentUsage(address bridgeToken) external view returns (uint256) {\n return usage[bridgeToken][block.timestamp / 3600];\n }\n\n /// @notice Mints the canonical token from a supported bridge token\n /// @param bridgeToken Bridge token to use to mint\n /// @param amount Amount of bridge tokens to send\n /// @param to Address to which the stablecoin should be sent\n /// @return Amount of the canonical stablecoin actually minted\n /// @dev Some fees may be taken by the protocol depending on the token used and on the address calling\n function swapIn(address bridgeToken, uint256 amount, address to) external returns (uint256) {\n BridgeDetails memory bridgeDetails = bridges[bridgeToken];\n if (!bridgeDetails.allowed || bridgeDetails.paused) revert InvalidToken();\n uint256 balance = IERC20(bridgeToken).balanceOf(address(this));\n if (balance + amount > bridgeDetails.limit) {\n // In case someone maliciously sends tokens to this contract\n // Or the limit changes\n if (bridgeDetails.limit > balance) amount = bridgeDetails.limit - balance;\n else {\n amount = 0;\n }\n }\n\n // Checking requirement on the hourly volume\n uint256 hour = block.timestamp / 3600;\n uint256 hourlyUsage = usage[bridgeToken][hour] + amount;\n if (hourlyUsage > bridgeDetails.hourlyLimit) {\n // Edge case when the hourly limit changes\n if (bridgeDetails.hourlyLimit > usage[bridgeToken][hour])\n amount = bridgeDetails.hourlyLimit - usage[bridgeToken][hour];\n else {\n amount = 0;\n }\n }\n usage[bridgeToken][hour] = usage[bridgeToken][hour] + amount;\n\n IERC20(bridgeToken).safeTransferFrom(msg.sender, address(this), amount);\n uint256 canonicalOut = amount;\n // Computing fees\n if (isFeeExempt[msg.sender] == 0) {\n canonicalOut -= (canonicalOut * bridgeDetails.fee) / BASE_PARAMS;\n }\n _mint(to, canonicalOut);\n return canonicalOut;\n }\n\n /// @notice Burns the canonical token in exchange for a bridge token\n /// @param bridgeToken Bridge token required\n /// @param amount Amount of canonical tokens to burn\n /// @param to Address to which the bridge token should be sent\n /// @return Amount of bridge tokens actually sent back\n /// @dev Some fees may be taken by the protocol depending on the token used and on the address calling\n function swapOut(address bridgeToken, uint256 amount, address to) external returns (uint256) {\n BridgeDetails memory bridgeDetails = bridges[bridgeToken];\n if (!bridgeDetails.allowed || bridgeDetails.paused) revert InvalidToken();\n\n _burn(msg.sender, amount);\n uint256 bridgeOut = amount;\n if (isFeeExempt[msg.sender] == 0) {\n bridgeOut -= (bridgeOut * bridgeDetails.fee) / BASE_PARAMS;\n }\n IERC20(bridgeToken).safeTransfer(to, bridgeOut);\n return bridgeOut;\n }\n\n // ======================= Governance Functions ================================\n\n /// @notice Adds support for a bridge token\n /// @param bridgeToken Bridge token to add: it should be a version of the stablecoin from another bridge\n /// @param limit Limit on the balance of bridge token this contract could hold\n /// @param hourlyLimit Limit on the hourly volume for this bridge\n /// @param paused Whether swapping for this token should be paused or not\n /// @param fee Fee taken upon swapping for or against this token\n function addBridgeToken(\n address bridgeToken,\n uint256 limit,\n uint256 hourlyLimit,\n uint64 fee,\n bool paused\n ) external onlyGovernor {\n if (bridges[bridgeToken].allowed || bridgeToken == address(0)) revert InvalidToken();\n if (fee > BASE_PARAMS) revert TooHighParameterValue();\n BridgeDetails memory _bridge;\n _bridge.limit = limit;\n _bridge.hourlyLimit = hourlyLimit;\n _bridge.paused = paused;\n _bridge.fee = fee;\n _bridge.allowed = true;\n bridges[bridgeToken] = _bridge;\n bridgeTokensList.push(bridgeToken);\n emit BridgeTokenAdded(bridgeToken, limit, hourlyLimit, fee, paused);\n }\n\n /// @notice Removes support for a token\n /// @param bridgeToken Address of the bridge token to remove support for\n function removeBridgeToken(address bridgeToken) external onlyGovernor {\n if (IERC20(bridgeToken).balanceOf(address(this)) != 0) revert AssetStillControlledInReserves();\n delete bridges[bridgeToken];\n // Deletion from `bridgeTokensList` loop\n uint256 bridgeTokensListLength = bridgeTokensList.length;\n for (uint256 i; i < bridgeTokensListLength - 1; ++i) {\n if (bridgeTokensList[i] == bridgeToken) {\n // Replace the `bridgeToken` to remove with the last of the list\n bridgeTokensList[i] = bridgeTokensList[bridgeTokensListLength - 1];\n break;\n }\n }\n // Remove last element in array\n bridgeTokensList.pop();\n emit BridgeTokenRemoved(bridgeToken);\n }\n\n /// @notice Recovers any ERC20 token\n /// @dev Can be used to withdraw bridge tokens for them to be de-bridged on mainnet\n function recoverERC20(address tokenAddress, address to, uint256 amountToRecover) external onlyGovernor {\n IERC20(tokenAddress).safeTransfer(to, amountToRecover);\n emit Recovered(tokenAddress, to, amountToRecover);\n }\n\n /// @notice Updates the `limit` amount for `bridgeToken`\n function setLimit(address bridgeToken, uint256 limit) external onlyGovernorOrGuardian {\n if (!bridges[bridgeToken].allowed) revert InvalidToken();\n bridges[bridgeToken].limit = limit;\n emit BridgeTokenLimitUpdated(bridgeToken, limit);\n }\n\n /// @notice Updates the `hourlyLimit` amount for `bridgeToken`\n function setHourlyLimit(address bridgeToken, uint256 hourlyLimit) external onlyGovernorOrGuardian {\n if (!bridges[bridgeToken].allowed) revert InvalidToken();\n bridges[bridgeToken].hourlyLimit = hourlyLimit;\n emit BridgeTokenHourlyLimitUpdated(bridgeToken, hourlyLimit);\n }\n\n /// @notice Updates the `fee` value for `bridgeToken`\n function setSwapFee(address bridgeToken, uint64 fee) external onlyGovernorOrGuardian {\n if (!bridges[bridgeToken].allowed) revert InvalidToken();\n if (fee > BASE_PARAMS) revert TooHighParameterValue();\n bridges[bridgeToken].fee = fee;\n emit BridgeTokenFeeUpdated(bridgeToken, fee);\n }\n\n /// @notice Pauses or unpauses swapping in and out for a token\n function toggleBridge(address bridgeToken) external onlyGovernorOrGuardian {\n if (!bridges[bridgeToken].allowed) revert InvalidToken();\n bool pausedStatus = bridges[bridgeToken].paused;\n bridges[bridgeToken].paused = !pausedStatus;\n emit BridgeTokenToggled(bridgeToken, !pausedStatus);\n }\n\n /// @notice Toggles fees for the address `theAddress`\n function toggleFeesForAddress(address theAddress) external onlyGovernorOrGuardian {\n uint256 feeExemptStatus = 1 - isFeeExempt[theAddress];\n isFeeExempt[theAddress] = feeExemptStatus;\n emit FeeToggled(theAddress, feeExemptStatus);\n }\n}\n" + }, + "contracts/mock/MockStableMaster.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\nimport \"../interfaces/IAgToken.sol\";\nimport \"./MockToken.sol\";\nimport \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\nimport \"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\";\nimport { SLPData, MintBurnData } from \"../interfaces/coreModule/IStableMaster.sol\";\n\n// All the details about a collateral that are going to be stored in `StableMaster`\nstruct Collateral {\n // Interface for the token accepted by the underlying `PoolManager` contract\n IERC20 token;\n // Reference to the `SanToken` for the pool\n MockToken sanToken;\n // Reference to the `PerpetualManager` for the pool\n address perpetualManager;\n // Adress of the oracle for the change rate between\n // collateral and the corresponding stablecoin\n address oracle;\n // Amount of collateral in the reserves that comes from users\n // converted in stablecoin value. Updated at minting and burning.\n // A `stocksUsers` of 10 for a collateral type means that overall the balance of the collateral from users\n // that minted/burnt stablecoins using this collateral is worth 10 of stablecoins\n uint256 stocksUsers;\n // Exchange rate between sanToken and collateral\n uint256 sanRate;\n // Base used in the collateral implementation (ERC20 decimal)\n uint256 collatBase;\n // Parameters for SLPs and update of the `sanRate`\n SLPData slpData;\n // All the fees parameters\n MintBurnData feeData;\n}\n\ncontract MockStableMaster {\n mapping(address => uint256) public poolManagerMap;\n\n constructor() {}\n\n function updateStocksUsers(uint256 amount, address poolManager) external {\n poolManagerMap[poolManager] += amount;\n }\n\n function burnSelf(IAgToken agToken, uint256 amount, address burner) external {\n agToken.burnSelf(amount, burner);\n }\n\n function burnFrom(IAgToken agToken, uint256 amount, address burner, address sender) external {\n agToken.burnFrom(amount, burner, sender);\n }\n\n function mint(IAgToken agToken, address account, uint256 amount) external {\n agToken.mint(account, amount);\n }\n}\n\ncontract MockStableMasterSanWrapper is MockStableMaster {\n using SafeERC20 for IERC20;\n\n /// @notice Maps a `PoolManager` contract handling a collateral for this stablecoin to the properties of the struct above\n mapping(address => Collateral) public collateralMap;\n\n constructor() MockStableMaster() {}\n\n uint256 internal constant _BASE_TOKENS = 10 ** 18;\n uint256 internal constant _BASE_PARAMS = 10 ** 9;\n IERC20 public token;\n\n function deposit(uint256 assets, address receiver, address poolManager) external {\n token.safeTransferFrom(msg.sender, address(this), assets);\n Collateral storage col = collateralMap[poolManager];\n _updateSanRate(col);\n uint256 amount = (assets * _BASE_TOKENS) / col.sanRate;\n col.sanToken.mint(receiver, amount);\n }\n\n function withdraw(uint256 assets, address sender, address receiver, address poolManager) external {\n Collateral storage col = collateralMap[poolManager];\n _updateSanRate(col);\n col.sanToken.burn(sender, assets);\n // Computing the amount of collateral to give back to the SLP depending on slippage and on the `sanRate`\n uint256 redeemInC = (assets * (_BASE_PARAMS - col.slpData.slippage) * col.sanRate) /\n (_BASE_TOKENS * _BASE_PARAMS);\n token.safeTransfer(receiver, redeemInC);\n }\n\n function setPoolManagerToken(address, address token_) external {\n token = MockToken(token_);\n }\n\n function setPoolManagerSanToken(address poolManager, address sanToken_) external {\n Collateral storage col = collateralMap[poolManager];\n col.sanToken = MockToken(sanToken_);\n }\n\n function setSanRate(address poolManager, uint256 sanRate_) external {\n Collateral storage col = collateralMap[poolManager];\n col.sanRate = sanRate_;\n }\n\n function _updateSanRate(Collateral storage col) internal {\n uint256 _lockedInterests = col.slpData.lockedInterests;\n // Checking if the `sanRate` has been updated in the current block using past block fees\n // This is a way to prevent flash loans attacks when an important amount of fees are going to be distributed\n // in a block: fees are stored but will just be distributed to SLPs who will be here during next blocks\n if (block.timestamp != col.slpData.lastBlockUpdated && _lockedInterests > 0) {\n uint256 sanMint = col.sanToken.totalSupply();\n if (sanMint != 0) {\n // Checking if the update is too important and should be made in multiple blocks\n if (_lockedInterests > col.slpData.maxInterestsDistributed) {\n // `sanRate` is expressed in `BASE_TOKENS`\n col.sanRate += (col.slpData.maxInterestsDistributed * 10 ** 18) / sanMint;\n _lockedInterests -= col.slpData.maxInterestsDistributed;\n } else {\n col.sanRate += (_lockedInterests * 10 ** 18) / sanMint;\n _lockedInterests = 0;\n }\n } else {\n _lockedInterests = 0;\n }\n }\n col.slpData.lockedInterests = _lockedInterests;\n col.slpData.lastBlockUpdated = block.timestamp;\n }\n\n // copy paste from the deployed contract\n function estimateSanRate(address poolManager) external view returns (uint256 sanRate, uint64 slippage) {\n Collateral memory col = collateralMap[poolManager];\n uint256 _lockedInterests = col.slpData.lockedInterests;\n // Checking if the `sanRate` has been updated in the current block using past block fees\n // This is a way to prevent flash loans attacks when an important amount of fees are going to be distributed\n // in a block: fees are stored but will just be distributed to SLPs who will be here during next blocks\n if (block.timestamp != col.slpData.lastBlockUpdated && _lockedInterests > 0) {\n uint256 sanMint = col.sanToken.totalSupply();\n if (sanMint != 0) {\n // Checking if the update is too important and should be made in multiple blocks\n if (_lockedInterests > col.slpData.maxInterestsDistributed) {\n // `sanRate` is expressed in `BASE_TOKENS`\n col.sanRate += (col.slpData.maxInterestsDistributed * 10 ** 18) / sanMint;\n _lockedInterests -= col.slpData.maxInterestsDistributed;\n } else {\n col.sanRate += (_lockedInterests * 10 ** 18) / sanMint;\n _lockedInterests = 0;\n }\n } else {\n _lockedInterests = 0;\n }\n }\n return (col.sanRate, col.slpData.slippage);\n }\n\n function setSLPData(\n address poolManager,\n uint256 lockedInterests,\n uint256 maxInterestsDistributed,\n uint64 slippage\n ) external {\n Collateral storage col = collateralMap[poolManager];\n col.slpData.lockedInterests = lockedInterests;\n col.slpData.maxInterestsDistributed = maxInterestsDistributed;\n col.slpData.slippage = slippage;\n }\n}\n" + }, + "contracts/mock/MockSwapper.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\nimport \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\nimport \"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\";\n\nimport \"../interfaces/ISwapper.sol\";\n\ncontract MockSwapper is ISwapper {\n bytes32 public constant CALLBACK_SUCCESS = keccak256(\"ERC3156FlashBorrower.onFlashLoan\");\n\n uint256 public counter;\n\n constructor() {}\n\n function swap(IERC20, IERC20, address, uint256, uint256, bytes calldata data) external {\n counter += 1;\n data;\n }\n}\n\ncontract MockSwapperWithSwap is ISwapper {\n using SafeERC20 for IERC20;\n bytes32 public constant CALLBACK_SUCCESS = keccak256(\"ERC3156FlashBorrower.onFlashLoan\");\n\n uint256 public counter;\n\n constructor() {}\n\n function swap(\n IERC20,\n IERC20 outToken,\n address outTokenRecipient,\n uint256 outTokenOwed,\n uint256,\n bytes calldata data\n ) external {\n counter += 1;\n outToken.safeTransfer(outTokenRecipient, outTokenOwed);\n\n data;\n }\n}\n" + }, + "contracts/mock/MockSwapperSidechain.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\nimport \"../swapper/Swapper.sol\";\n\n/// @title MockSwapperSidechain\n/// @author Angle Labs, Inc.\ncontract MockSwapperSidechain is Swapper {\n error NotImplemented();\n\n /// @notice Constructor of the contract\n /// @param _core Core address\n /// @param _uniV3Router UniswapV3 Router address\n /// @param _oneInch 1Inch Router address\n /// @param _angleRouter AngleRouter contract address\n constructor(\n ICoreBorrow _core,\n IUniswapV3Router _uniV3Router,\n address _oneInch,\n IAngleRouterSidechain _angleRouter\n ) Swapper(_core, _uniV3Router, _oneInch, _angleRouter) {}\n\n function _swapLeverage(bytes memory) internal pure override returns (uint256) {\n revert NotImplemented();\n }\n}\n" + }, + "contracts/mock/MockToken.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.7;\n\nimport \"@openzeppelin/contracts/token/ERC20/ERC20.sol\";\n\ncontract MockToken is ERC20 {\n event Minting(address indexed _to, address indexed _minter, uint256 _amount);\n\n event Burning(address indexed _from, address indexed _burner, uint256 _amount);\n\n uint8 internal _decimal;\n mapping(address => bool) public minters;\n address public treasury;\n\n constructor(string memory name_, string memory symbol_, uint8 decimal_) ERC20(name_, symbol_) {\n _decimal = decimal_;\n }\n\n function decimals() public view override returns (uint8) {\n return _decimal;\n }\n\n function mint(address account, uint256 amount) external {\n _mint(account, amount);\n emit Minting(account, msg.sender, amount);\n }\n\n function burn(address account, uint256 amount) public {\n _burn(account, amount);\n emit Burning(account, msg.sender, amount);\n }\n\n function setAllowance(address from, address to) public {\n _approve(from, to, type(uint256).max);\n }\n\n function burnSelf(uint256 amount, address account) public {\n _burn(account, amount);\n emit Burning(account, msg.sender, amount);\n }\n\n function addMinter(address minter) public {\n minters[minter] = true;\n }\n\n function removeMinter(address minter) public {\n minters[minter] = false;\n }\n\n function setTreasury(address _treasury) public {\n treasury = _treasury;\n }\n}\n" + }, + "contracts/mock/MockTokenPermit.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.7;\n\nimport \"@openzeppelin/contracts/token/ERC20/extensions/draft-ERC20Permit.sol\";\nimport \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\nimport \"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\";\n\ncontract MockTokenPermit is ERC20Permit {\n using SafeERC20 for IERC20;\n event Minting(address indexed _to, address indexed _minter, uint256 _amount);\n\n event Burning(address indexed _from, address indexed _burner, uint256 _amount);\n\n uint8 internal _decimal;\n mapping(address => bool) public minters;\n address public treasury;\n uint256 public fees;\n\n bool public reverts;\n\n constructor(string memory name_, string memory symbol_, uint8 decimal_) ERC20Permit(name_) ERC20(name_, symbol_) {\n _decimal = decimal_;\n }\n\n function decimals() public view override returns (uint8) {\n return _decimal;\n }\n\n function mint(address account, uint256 amount) external {\n _mint(account, amount);\n emit Minting(account, msg.sender, amount);\n }\n\n function burn(address account, uint256 amount) public {\n _burn(account, amount);\n emit Burning(account, msg.sender, amount);\n }\n\n function setAllowance(address from, address to) public {\n _approve(from, to, type(uint256).max);\n }\n\n function burnSelf(uint256 amount, address account) public {\n _burn(account, amount);\n emit Burning(account, msg.sender, amount);\n }\n\n function addMinter(address minter) public {\n minters[minter] = true;\n }\n\n function removeMinter(address minter) public {\n minters[minter] = false;\n }\n\n function setTreasury(address _treasury) public {\n treasury = _treasury;\n }\n\n function setFees(uint256 _fees) public {\n fees = _fees;\n }\n\n function recoverERC20(IERC20 token, address to, uint256 amount) external {\n token.safeTransfer(to, amount);\n }\n\n function swapIn(address bridgeToken, uint256 amount, address to) external returns (uint256) {\n require(!reverts);\n\n IERC20(bridgeToken).safeTransferFrom(msg.sender, address(this), amount);\n uint256 canonicalOut = amount;\n canonicalOut -= (canonicalOut * fees) / 10 ** 9;\n _mint(to, canonicalOut);\n return canonicalOut;\n }\n\n function swapOut(address bridgeToken, uint256 amount, address to) external returns (uint256) {\n require(!reverts);\n _burn(msg.sender, amount);\n uint256 bridgeOut = amount;\n bridgeOut -= (bridgeOut * fees) / 10 ** 9;\n IERC20(bridgeToken).safeTransfer(to, bridgeOut);\n return bridgeOut;\n }\n}\n" + }, + "contracts/mock/MockTreasury.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\nimport \"../interfaces/ITreasury.sol\";\nimport \"../interfaces/IFlashAngle.sol\";\nimport \"../interfaces/IVaultManager.sol\";\n\ncontract MockTreasury is ITreasury {\n IAgToken public override stablecoin;\n address public governor;\n address public guardian;\n address public vaultManager1;\n address public vaultManager2;\n address public flashLoanModule;\n address[] public vaultManagerList;\n\n constructor(\n IAgToken _stablecoin,\n address _governor,\n address _guardian,\n address _vaultManager1,\n address _vaultManager2,\n address _flashLoanModule\n ) {\n stablecoin = _stablecoin;\n governor = _governor;\n guardian = _guardian;\n vaultManager1 = _vaultManager1;\n vaultManager2 = _vaultManager2;\n flashLoanModule = _flashLoanModule;\n }\n\n function isGovernor(address admin) external view override returns (bool) {\n return (admin == governor);\n }\n\n function isGovernorOrGuardian(address admin) external view override returns (bool) {\n return (admin == governor || admin == guardian);\n }\n\n function isVaultManager(address _vaultManager) external view override returns (bool) {\n return (_vaultManager == vaultManager1 || _vaultManager == vaultManager2);\n }\n\n function setStablecoin(IAgToken _stablecoin) external {\n stablecoin = _stablecoin;\n }\n\n function setFlashLoanModule(address _flashLoanModule) external override {\n flashLoanModule = _flashLoanModule;\n }\n\n function setGovernor(address _governor) external {\n governor = _governor;\n }\n\n function setVaultManager(address _vaultManager) external {\n vaultManager1 = _vaultManager;\n }\n\n function setVaultManager2(address _vaultManager) external {\n vaultManager2 = _vaultManager;\n }\n\n function setTreasury(address _agTokenOrVaultManager, address _treasury) external {\n IAgToken(_agTokenOrVaultManager).setTreasury(_treasury);\n }\n\n function addMinter(IAgToken _agToken, address _minter) external {\n _agToken.addMinter(_minter);\n }\n\n function removeMinter(IAgToken _agToken, address _minter) external {\n _agToken.removeMinter(_minter);\n }\n\n function accrueInterestToTreasury(IFlashAngle flashAngle) external returns (uint256 balance) {\n balance = flashAngle.accrueInterestToTreasury(stablecoin);\n }\n\n function accrueInterestToTreasuryVaultManager(IVaultManager _vaultManager) external returns (uint256, uint256) {\n return _vaultManager.accrueInterestToTreasury();\n }\n}\n" + }, + "contracts/mock/MockUniswapV3Pool.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.7;\n\ncontract MockUniswapV3Pool {\n address public token0;\n address public token1;\n uint32 public constant EPOCH_DURATION = 24 * 3600 * 7;\n\n function setToken(address token, uint256 who) external {\n if (who == 0) token0 = token;\n else token1 = token;\n }\n\n function round(uint256 amount) external pure returns (uint256) {\n return (amount / EPOCH_DURATION) * EPOCH_DURATION;\n }\n}\n" + }, + "contracts/mock/MockVaultManager.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\nimport \"../interfaces/IVaultManager.sol\";\nimport \"../interfaces/ITreasury.sol\";\nimport \"@openzeppelin/contracts/token/ERC20/ERC20.sol\";\n\ncontract MockVaultManager {\n ITreasury public treasury;\n mapping(uint256 => Vault) public vaultData;\n mapping(uint256 => address) public ownerOf;\n uint256 public surplus;\n uint256 public badDebt;\n IAgToken public token;\n address public oracle = address(this);\n\n address public governor;\n address public collateral;\n address public stablecoin;\n uint256 public oracleValue;\n uint256 public interestAccumulator;\n uint256 public collateralFactor;\n uint256 public totalNormalizedDebt;\n\n constructor(address _treasury) {\n treasury = ITreasury(_treasury);\n }\n\n function accrueInterestToTreasury() external returns (uint256, uint256) {\n // Avoid the function to be view\n if (surplus >= badDebt) {\n token.mint(msg.sender, surplus - badDebt);\n }\n return (surplus, badDebt);\n }\n\n function read() external view returns (uint256) {\n return oracleValue;\n }\n\n function setParams(\n address _governor,\n address _collateral,\n address _stablecoin,\n uint256 _oracleValue,\n uint256 _interestAccumulator,\n uint256 _collateralFactor,\n uint256 _totalNormalizedDebt\n ) external {\n governor = _governor;\n collateral = _collateral;\n stablecoin = _stablecoin;\n interestAccumulator = _interestAccumulator;\n collateralFactor = _collateralFactor;\n totalNormalizedDebt = _totalNormalizedDebt;\n oracleValue = _oracleValue;\n }\n\n function setOwner(uint256 vaultID, address owner) external virtual {\n ownerOf[vaultID] = owner;\n }\n\n function setVaultData(uint256 normalizedDebt, uint256 collateralAmount, uint256 vaultID) external {\n vaultData[vaultID].normalizedDebt = normalizedDebt;\n vaultData[vaultID].collateralAmount = collateralAmount;\n }\n\n function isGovernor(address admin) external view returns (bool) {\n return admin == governor;\n }\n\n function setSurplusBadDebt(uint256 _surplus, uint256 _badDebt, IAgToken _token) external {\n surplus = _surplus;\n badDebt = _badDebt;\n token = _token;\n }\n\n function getDebtOut(uint256 vaultID, uint256 amountStablecoins, uint256 senderBorrowFee) external {}\n\n function setTreasury(address _treasury) external {\n treasury = ITreasury(_treasury);\n }\n\n function getVaultDebt(uint256 vaultID) external view returns (uint256) {\n vaultID;\n token;\n return 0;\n }\n\n function createVault(address toVault) external view returns (uint256) {\n toVault;\n token;\n return 0;\n }\n}\n\ncontract MockVaultManagerListing is MockVaultManager {\n // @notice Mapping from owner address to all his vaults\n mapping(address => uint256[]) internal _ownerListVaults;\n\n constructor(address _treasury) MockVaultManager(_treasury) {}\n\n function getUserVaults(address owner) public view returns (uint256[] memory) {\n return _ownerListVaults[owner];\n }\n\n function getUserCollateral(address owner) public view returns (uint256 totalCollateral) {\n uint256[] memory vaultList = _ownerListVaults[owner];\n uint256 vaultListLength = vaultList.length;\n for (uint256 k; k < vaultListLength; ++k) {\n totalCollateral += vaultData[vaultList[k]].collateralAmount;\n }\n return totalCollateral;\n }\n\n function setOwner(uint256 vaultID, address owner) external override {\n if (ownerOf[vaultID] != address(0)) _removeVaultFromList(ownerOf[vaultID], vaultID);\n _ownerListVaults[owner].push(vaultID);\n ownerOf[vaultID] = owner;\n }\n\n /// @notice Remove `vaultID` from `user` stroed vault list\n /// @param user Address to look out for the vault list\n /// @param vaultID VaultId to remove from the list\n /// @dev The vault is necessarily in the list\n function _removeVaultFromList(address user, uint256 vaultID) internal {\n uint256[] storage vaultList = _ownerListVaults[user];\n uint256 vaultListLength = vaultList.length;\n for (uint256 i; i < vaultListLength - 1; ++i) {\n if (vaultList[i] == vaultID) {\n vaultList[i] = vaultList[vaultListLength - 1];\n break;\n }\n }\n vaultList.pop();\n }\n}\n" + }, + "contracts/mock/MockVeBoostProxy.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\nimport \"../interfaces/governance/IVeBoostProxy.sol\";\n\ncontract MockVeBoostProxy is IVeBoostProxy {\n //solhint-disable-next-line\n mapping(address => uint256) public adjusted_balance_of;\n\n constructor() {}\n\n function setBalance(address concerned, uint256 balance) external {\n adjusted_balance_of[concerned] = balance;\n }\n}\n" + }, + "contracts/oracle/BaseOracleChainlinkMulti.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\n/*\n * █ \n ***** ▓▓▓ \n * ▓▓▓▓▓▓▓ \n * ///. ▓▓▓▓▓▓▓▓▓▓▓▓▓ \n ***** //////// ▓▓▓▓▓▓▓ \n * ///////////// ▓▓▓ \n ▓▓ ////////////////// █ ▓▓ \n ▓▓ ▓▓ /////////////////////// ▓▓ ▓▓ \n ▓▓ ▓▓ //////////////////////////// ▓▓ ▓▓ \n ▓▓ ▓▓ /////////▓▓▓///////▓▓▓///////// ▓▓ ▓▓ \n ▓▓ ,////////////////////////////////////// ▓▓ ▓▓ \n ▓▓ ////////////////////////////////////////// ▓▓ \n ▓▓ //////////////////////▓▓▓▓///////////////////// \n ,//////////////////////////////////////////////////// \n .////////////////////////////////////////////////////////// \n .//////////////////////////██.,//////////////////////////█ \n .//////////////////////████..,./////////////////////██ \n ...////////////////███████.....,.////////////////███ \n ,.,////////////████████ ........,///////////████ \n .,.,//////█████████ ,.......///////████ \n ,..//████████ ........./████ \n ..,██████ .....,███ \n .██ ,.,█ \n \n \n \n ▓▓ ▓▓▓▓▓▓▓▓▓▓ ▓▓▓▓▓▓▓▓▓▓ ▓▓ ▓▓▓▓▓▓▓▓▓▓ \n ▓▓▓▓▓▓ ▓▓▓ ▓▓▓ ▓▓▓ ▓▓ ▓▓ ▓▓▓▓ \n ▓▓▓ ▓▓▓ ▓▓▓ ▓▓▓ ▓▓▓ ▓▓▓ ▓▓ ▓▓▓▓▓ \n ▓▓▓ ▓▓ ▓▓▓ ▓▓▓ ▓▓▓▓▓▓▓▓▓▓ ▓▓▓▓▓▓▓▓▓▓ ▓▓▓▓▓▓▓▓▓▓ \n*/\n\npragma solidity ^0.8.12;\n\nimport \"@chainlink/contracts/src/v0.8/interfaces/AggregatorV3Interface.sol\";\n\nimport \"../interfaces/IOracle.sol\";\nimport \"../interfaces/ITreasury.sol\";\n\n/// @title BaseOracleChainlinkMulti\n/// @author Angle Labs, Inc.\n/// @notice Base Contract to be overriden by all contracts of the protocol\n/// @dev This base contract concerns an oracle that uses Chainlink with multiple pools to read from\n/// @dev All gas-efficient implementation of the `OracleChainlinkMulti` contract should inherit from this\nabstract contract BaseOracleChainlinkMulti is IOracle {\n // ========================= Parameters and References =========================\n\n /// @inheritdoc IOracle\n ITreasury public override treasury;\n /// @notice Represent the maximum amount of time (in seconds) between each Chainlink update\n /// before the price feed is considered stale\n uint32 public stalePeriod;\n\n // =================================== Event ===================================\n\n event StalePeriodUpdated(uint32 _stalePeriod);\n\n // =================================== Errors ===================================\n\n error InvalidChainlinkRate();\n error NotGovernorOrGuardian();\n error NotVaultManagerOrGovernor();\n\n /// @notice Constructor for an oracle using Chainlink with multiple pools to read from\n /// @param _stalePeriod Minimum feed update frequency for the oracle to not revert\n /// @param _treasury Treasury associated to the VaultManager which reads from this feed\n constructor(uint32 _stalePeriod, address _treasury) {\n stalePeriod = _stalePeriod;\n treasury = ITreasury(_treasury);\n }\n\n // ============================= Reading Oracles ===============================\n\n /// @inheritdoc IOracle\n function read() external view virtual override returns (uint256 quoteAmount);\n\n /// @inheritdoc IOracle\n function circuitChainlink() public view virtual returns (AggregatorV3Interface[] memory);\n\n /// @notice Reads a Chainlink feed using a quote amount and converts the quote amount to\n /// the out-currency\n /// @param quoteAmount The amount for which to compute the price expressed with base decimal\n /// @param feed Chainlink feed to query\n /// @param multiplied Whether the ratio outputted by Chainlink should be multiplied or divided\n /// to the `quoteAmount`\n /// @param decimals Number of decimals of the corresponding Chainlink pair\n /// @return The `quoteAmount` converted in out-currency\n function _readChainlinkFeed(\n uint256 quoteAmount,\n AggregatorV3Interface feed,\n uint8 multiplied,\n uint256 decimals\n ) internal view returns (uint256) {\n (uint80 roundId, int256 ratio, , uint256 updatedAt, uint80 answeredInRound) = feed.latestRoundData();\n if (ratio <= 0 || roundId > answeredInRound || block.timestamp - updatedAt > stalePeriod)\n revert InvalidChainlinkRate();\n uint256 castedRatio = uint256(ratio);\n // Checking whether we should multiply or divide by the ratio computed\n if (multiplied == 1) return (quoteAmount * castedRatio) / (10 ** decimals);\n else return (quoteAmount * (10 ** decimals)) / castedRatio;\n }\n\n // ======================= Governance Related Functions ========================\n\n /// @notice Changes the stale period\n /// @param _stalePeriod New stale period (in seconds)\n function changeStalePeriod(uint32 _stalePeriod) external {\n if (!treasury.isGovernorOrGuardian(msg.sender)) revert NotGovernorOrGuardian();\n stalePeriod = _stalePeriod;\n emit StalePeriodUpdated(_stalePeriod);\n }\n\n /// @inheritdoc IOracle\n function setTreasury(address _treasury) external override {\n if (!treasury.isVaultManager(msg.sender) && !treasury.isGovernor(msg.sender))\n revert NotVaultManagerOrGovernor();\n treasury = ITreasury(_treasury);\n }\n}\n" + }, + "contracts/oracle/BaseOracleChainlinkMultiTwoFeeds.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\nimport \"@chainlink/contracts/src/v0.8/interfaces/AggregatorV3Interface.sol\";\n\nimport \"./BaseOracleChainlinkMulti.sol\";\n\n/// @title BaseOracleChainlinkMultiTwoFeeds\n/// @author Angle Labs, Inc.\n/// @notice Base contract for an oracle that reads into two Chainlink feeds (including an EUR/USD feed) which both have\n/// 8 decimals\nabstract contract BaseOracleChainlinkMultiTwoFeeds is BaseOracleChainlinkMulti {\n constructor(uint32 _stalePeriod, address _treasury) BaseOracleChainlinkMulti(_stalePeriod, _treasury) {}\n\n /// @notice Returns the quote amount of the oracle contract\n function _getQuoteAmount() internal view virtual returns (uint256) {\n return 10 ** 18;\n }\n\n /// @inheritdoc IOracle\n function read() external view virtual override returns (uint256 quoteAmount) {\n quoteAmount = _getQuoteAmount();\n AggregatorV3Interface[] memory _circuitChainlink = circuitChainlink();\n uint8[2] memory circuitChainIsMultiplied = [1, 0];\n uint8[2] memory chainlinkDecimals = [8, 8];\n uint256 circuitLength = _circuitChainlink.length;\n for (uint256 i; i < circuitLength; ++i) {\n quoteAmount = _readChainlinkFeed(\n quoteAmount,\n _circuitChainlink[i],\n circuitChainIsMultiplied[i],\n chainlinkDecimals[i]\n );\n }\n }\n}\n" + }, + "contracts/oracle/BaseOracleChainlinkOneFeed.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\nimport \"@chainlink/contracts/src/v0.8/interfaces/AggregatorV3Interface.sol\";\n\nimport \"./BaseOracleChainlinkMulti.sol\";\n\n/// @title BaseOracleChainlinkOneFeed\n/// @author Angle Labs, Inc.\n/// @notice Base contract for an oracle that reads into one Chainlink feeds with 8 decimals\nabstract contract BaseOracleChainlinkOneFeed is BaseOracleChainlinkMulti {\n constructor(uint32 _stalePeriod, address _treasury) BaseOracleChainlinkMulti(_stalePeriod, _treasury) {}\n\n /// @notice Returns the quote amount of the oracle contract\n function _getQuoteAmount() internal view virtual returns (uint256) {\n return 10 ** 18;\n }\n\n /// @inheritdoc IOracle\n function read() external view virtual override returns (uint256 quoteAmount) {\n AggregatorV3Interface[] memory _circuitChainlink = circuitChainlink();\n quoteAmount = _readChainlinkFeed(_getQuoteAmount(), _circuitChainlink[0], 1, 8);\n }\n}\n" + }, + "contracts/oracle/implementations/arbitrum/EUR/OracleBTCEURChainlinkArbitrum.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\nimport \"@chainlink/contracts/src/v0.8/interfaces/AggregatorV3Interface.sol\";\n\nimport \"../../../BaseOracleChainlinkMultiTwoFeeds.sol\";\n\n/// @title OracleBTCEURChainlinkArbitrum\n/// @author Angle Labs, Inc.\n/// @notice Gives the price of BTC in Euro in base 18\n/// @dev This contract is built to be deployed on Arbitrum\ncontract OracleBTCEURChainlinkArbitrum is BaseOracleChainlinkMultiTwoFeeds {\n string public constant DESCRIPTION = \"BTC/EUR Oracle\";\n\n constructor(uint32 _stalePeriod, address _treasury) BaseOracleChainlinkMultiTwoFeeds(_stalePeriod, _treasury) {}\n\n /// @inheritdoc IOracle\n function circuitChainlink() public pure override returns (AggregatorV3Interface[] memory) {\n AggregatorV3Interface[] memory _circuitChainlink = new AggregatorV3Interface[](2);\n // Oracle BTC/USD\n _circuitChainlink[0] = AggregatorV3Interface(0x6ce185860a4963106506C203335A2910413708e9);\n // Oracle EUR/USD\n _circuitChainlink[1] = AggregatorV3Interface(0xA14d53bC1F1c0F31B4aA3BD109344E5009051a84);\n return _circuitChainlink;\n }\n}\n" + }, + "contracts/oracle/implementations/arbitrum/EUR/OracleETHEURChainlinkArbitrum.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\nimport \"@chainlink/contracts/src/v0.8/interfaces/AggregatorV3Interface.sol\";\n\nimport \"../../../BaseOracleChainlinkMultiTwoFeeds.sol\";\n\n/// @title OracleETHEURChainlinkArbitrum\n/// @author Angle Labs, Inc.\n/// @notice Gives the price of ETH in Euro in base 18\n/// @dev This contract is built to be deployed on Arbitrum\ncontract OracleETHEURChainlinkArbitrum is BaseOracleChainlinkMultiTwoFeeds {\n string public constant DESCRIPTION = \"ETH/EUR Oracle\";\n\n constructor(uint32 _stalePeriod, address _treasury) BaseOracleChainlinkMultiTwoFeeds(_stalePeriod, _treasury) {}\n\n /// @inheritdoc IOracle\n function circuitChainlink() public pure override returns (AggregatorV3Interface[] memory) {\n AggregatorV3Interface[] memory _circuitChainlink = new AggregatorV3Interface[](2);\n // Oracle ETH/USD\n _circuitChainlink[0] = AggregatorV3Interface(0x639Fe6ab55C921f74e7fac1ee960C0B6293ba612);\n // Oracle EUR/USD\n _circuitChainlink[1] = AggregatorV3Interface(0xA14d53bC1F1c0F31B4aA3BD109344E5009051a84);\n return _circuitChainlink;\n }\n}\n" + }, + "contracts/oracle/implementations/arbitrum/EUR/OracleUSDCEURChainlinkArbitrum.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\nimport \"@chainlink/contracts/src/v0.8/interfaces/AggregatorV3Interface.sol\";\n\nimport \"../../../BaseOracleChainlinkMultiTwoFeeds.sol\";\n\n/// @title OracleUSDCEURChainlinkArbitrum\n/// @author Angle Labs, Inc.\n/// @notice Gives the price of USDC in Euro in base 18\n/// @dev This contract is built to be deployed on Arbitrum\ncontract OracleUSDCEURChainlinkArbitrum is BaseOracleChainlinkMultiTwoFeeds {\n string public constant DESCRIPTION = \"USDC/EUR Oracle\";\n\n constructor(uint32 _stalePeriod, address _treasury) BaseOracleChainlinkMultiTwoFeeds(_stalePeriod, _treasury) {}\n\n /// @inheritdoc IOracle\n function circuitChainlink() public pure override returns (AggregatorV3Interface[] memory) {\n AggregatorV3Interface[] memory _circuitChainlink = new AggregatorV3Interface[](2);\n // Oracle ETH/USD\n _circuitChainlink[0] = AggregatorV3Interface(0x50834F3163758fcC1Df9973b6e91f0F0F0434aD3);\n // Oracle EUR/USD\n _circuitChainlink[1] = AggregatorV3Interface(0xA14d53bC1F1c0F31B4aA3BD109344E5009051a84);\n return _circuitChainlink;\n }\n}\n" + }, + "contracts/oracle/implementations/avalanche/EUR/OracleAVAXEURChainlinkAvalanche.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\nimport \"@chainlink/contracts/src/v0.8/interfaces/AggregatorV3Interface.sol\";\n\nimport \"../../../BaseOracleChainlinkMultiTwoFeeds.sol\";\n\n/// @title OracleAVAXEURChainlinkAvalanche\n/// @author Angle Labs, Inc.\n/// @notice Gives the price of AVAX in Euro in base 18\n/// @dev This contract is built to be deployed on Avalanche\ncontract OracleAVAXEURChainlinkAvalanche is BaseOracleChainlinkMultiTwoFeeds {\n string public constant DESCRIPTION = \"AVAX/EUR Oracle\";\n\n constructor(uint32 _stalePeriod, address _treasury) BaseOracleChainlinkMultiTwoFeeds(_stalePeriod, _treasury) {}\n\n /// @inheritdoc IOracle\n function circuitChainlink() public pure override returns (AggregatorV3Interface[] memory) {\n AggregatorV3Interface[] memory _circuitChainlink = new AggregatorV3Interface[](2);\n // Oracle AVAX/USD\n _circuitChainlink[0] = AggregatorV3Interface(0x0A77230d17318075983913bC2145DB16C7366156);\n // Oracle EUR/USD\n _circuitChainlink[1] = AggregatorV3Interface(0x192f2DBA961Bb0277520C082d6bfa87D5961333E);\n return _circuitChainlink;\n }\n}\n" + }, + "contracts/oracle/implementations/avalanche/EUR/OracleUSDCEURChainlinkAvalanche.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\nimport \"@chainlink/contracts/src/v0.8/interfaces/AggregatorV3Interface.sol\";\n\nimport \"../../../BaseOracleChainlinkMultiTwoFeeds.sol\";\n\n/// @title OracleUSDCEURChainlinkAvalanche\n/// @author Angle Labs, Inc.\n/// @notice Gives the price of USDC in Euro in base 18\n/// @dev This contract is built to be deployed on Avalanche\ncontract OracleUSDCEURChainlinkAvalanche is BaseOracleChainlinkMultiTwoFeeds {\n string public constant DESCRIPTION = \"USDC/EUR Oracle\";\n\n constructor(uint32 _stalePeriod, address _treasury) BaseOracleChainlinkMultiTwoFeeds(_stalePeriod, _treasury) {}\n\n /// @inheritdoc IOracle\n function circuitChainlink() public pure override returns (AggregatorV3Interface[] memory) {\n AggregatorV3Interface[] memory _circuitChainlink = new AggregatorV3Interface[](2);\n // Oracle USDC/USD\n _circuitChainlink[0] = AggregatorV3Interface(0xF096872672F44d6EBA71458D74fe67F9a77a23B9);\n // Oracle EUR/USD\n _circuitChainlink[1] = AggregatorV3Interface(0x192f2DBA961Bb0277520C082d6bfa87D5961333E);\n return _circuitChainlink;\n }\n}\n" + }, + "contracts/oracle/implementations/mainnet/EUR/OracleBTCEURChainlink.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\nimport \"@chainlink/contracts/src/v0.8/interfaces/AggregatorV3Interface.sol\";\n\nimport \"../../../BaseOracleChainlinkMultiTwoFeeds.sol\";\n\n/// @title OracleBTCEURChainlink\n/// @author Angle Labs, Inc.\n/// @notice Gives the price of BTC in Euro in base 18\ncontract OracleBTCEURChainlink is BaseOracleChainlinkMultiTwoFeeds {\n string public constant DESCRIPTION = \"BTC/EUR Oracle\";\n\n constructor(uint32 _stalePeriod, address _treasury) BaseOracleChainlinkMultiTwoFeeds(_stalePeriod, _treasury) {}\n\n /// @inheritdoc IOracle\n function circuitChainlink() public pure override returns (AggregatorV3Interface[] memory) {\n AggregatorV3Interface[] memory _circuitChainlink = new AggregatorV3Interface[](2);\n // Oracle BTC/USD\n _circuitChainlink[0] = AggregatorV3Interface(0xF4030086522a5bEEa4988F8cA5B36dbC97BeE88c);\n // Oracle EUR/USD\n _circuitChainlink[1] = AggregatorV3Interface(0xb49f677943BC038e9857d61E7d053CaA2C1734C1);\n return _circuitChainlink;\n }\n}\n" + }, + "contracts/oracle/implementations/mainnet/EUR/OracleCBETHEURChainlink.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\nimport \"@chainlink/contracts/src/v0.8/interfaces/AggregatorV3Interface.sol\";\n\nimport \"../../../BaseOracleChainlinkMultiTwoFeeds.sol\";\n\n/// @title OracleCBETHEURChainlink\n/// @author Angle Labs, Inc.\n/// @notice Gives the price of cbETH in Euro in base 18\ncontract OracleCBETHEURChainlink is BaseOracleChainlinkMultiTwoFeeds {\n string public constant DESCRIPTION = \"cbETH/EUR Oracle\";\n\n constructor(uint32 _stalePeriod, address _treasury) BaseOracleChainlinkMultiTwoFeeds(_stalePeriod, _treasury) {}\n\n /// @inheritdoc IOracle\n function circuitChainlink() public pure override returns (AggregatorV3Interface[] memory) {\n AggregatorV3Interface[] memory _circuitChainlink = new AggregatorV3Interface[](3);\n // Oracle cbETH/ETH\n _circuitChainlink[0] = AggregatorV3Interface(0xF017fcB346A1885194689bA23Eff2fE6fA5C483b);\n // Oracle ETH/USD\n _circuitChainlink[1] = AggregatorV3Interface(0x5f4eC3Df9cbd43714FE2740f5E3616155c5b8419);\n // Oracle EUR/USD\n _circuitChainlink[2] = AggregatorV3Interface(0xb49f677943BC038e9857d61E7d053CaA2C1734C1);\n return _circuitChainlink;\n }\n\n /// @inheritdoc BaseOracleChainlinkMultiTwoFeeds\n function read() external view virtual override returns (uint256 quoteAmount) {\n quoteAmount = _getQuoteAmount();\n AggregatorV3Interface[] memory _circuitChainlink = circuitChainlink();\n uint8[3] memory circuitChainIsMultiplied = [1, 1, 0];\n uint8[3] memory chainlinkDecimals = [18, 8, 8];\n uint256 circuitLength = _circuitChainlink.length;\n for (uint256 i; i < circuitLength; ++i) {\n quoteAmount = _readChainlinkFeed(\n quoteAmount,\n _circuitChainlink[i],\n circuitChainIsMultiplied[i],\n chainlinkDecimals[i]\n );\n }\n }\n}\n" + }, + "contracts/oracle/implementations/mainnet/EUR/OracleETHEURChainlink.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\nimport \"@chainlink/contracts/src/v0.8/interfaces/AggregatorV3Interface.sol\";\n\nimport \"../../../BaseOracleChainlinkMultiTwoFeeds.sol\";\n\n/// @title OracleETHEURChainlink\n/// @author Angle Labs, Inc.\n/// @notice Gives the price of ETH in Euro in base 18\ncontract OracleETHEURChainlink is BaseOracleChainlinkMultiTwoFeeds {\n string public constant DESCRIPTION = \"ETH/EUR Oracle\";\n\n constructor(uint32 _stalePeriod, address _treasury) BaseOracleChainlinkMultiTwoFeeds(_stalePeriod, _treasury) {}\n\n /// @inheritdoc IOracle\n function circuitChainlink() public pure override returns (AggregatorV3Interface[] memory) {\n AggregatorV3Interface[] memory _circuitChainlink = new AggregatorV3Interface[](2);\n // Oracle ETH/USD\n _circuitChainlink[0] = AggregatorV3Interface(0x5f4eC3Df9cbd43714FE2740f5E3616155c5b8419);\n // Oracle EUR/USD\n _circuitChainlink[1] = AggregatorV3Interface(0xb49f677943BC038e9857d61E7d053CaA2C1734C1);\n return _circuitChainlink;\n }\n}\n" + }, + "contracts/oracle/implementations/mainnet/EUR/OracleHIGHEURChainlink.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\nimport \"@chainlink/contracts/src/v0.8/interfaces/AggregatorV3Interface.sol\";\n\nimport \"../../../BaseOracleChainlinkMultiTwoFeeds.sol\";\n\n/// @title OracleHIGHEURChainlink\n/// @author Angle Labs, Inc.\n/// @notice Gives the price of HIGH in Euro in base 18\ncontract OracleHIGHEURChainlink is BaseOracleChainlinkMultiTwoFeeds {\n string public constant DESCRIPTION = \"HIGH/EUR Oracle\";\n\n constructor(uint32 _stalePeriod, address _treasury) BaseOracleChainlinkMultiTwoFeeds(_stalePeriod, _treasury) {}\n\n /// @inheritdoc IOracle\n function circuitChainlink() public pure override returns (AggregatorV3Interface[] memory) {\n AggregatorV3Interface[] memory _circuitChainlink = new AggregatorV3Interface[](1);\n // Oracle HIGH/EUR\n _circuitChainlink[0] = AggregatorV3Interface(0x9E8E794ad6Ecdb6d5c7eaBE059D30E907F58859b);\n return _circuitChainlink;\n }\n\n /// @inheritdoc BaseOracleChainlinkMultiTwoFeeds\n function read() external view override returns (uint256 quoteAmount) {\n quoteAmount = _readChainlinkFeed(_getQuoteAmount(), circuitChainlink()[0], 1, 8);\n }\n}\n" + }, + "contracts/oracle/implementations/mainnet/EUR/OracleIB01EURChainlink.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\nimport \"@chainlink/contracts/src/v0.8/interfaces/AggregatorV3Interface.sol\";\n\nimport \"../../../BaseOracleChainlinkMultiTwoFeeds.sol\";\n\n/// @title OracleIB01EURChainlink\n/// @author Angle Labs, Inc.\n/// @notice Gives the price of IB01 in Euro in base 18\ncontract OracleIB01EURChainlink is BaseOracleChainlinkMultiTwoFeeds {\n string public constant DESCRIPTION = \"IB01/EUR Oracle\";\n\n constructor(uint32 _stalePeriod, address _treasury) BaseOracleChainlinkMultiTwoFeeds(_stalePeriod, _treasury) {}\n\n /// @inheritdoc IOracle\n function circuitChainlink() public pure override returns (AggregatorV3Interface[] memory) {\n AggregatorV3Interface[] memory _circuitChainlink = new AggregatorV3Interface[](2);\n // Oracle IB01/USD\n _circuitChainlink[0] = AggregatorV3Interface(0x32d1463EB53b73C095625719Afa544D5426354cB);\n // Oracle EUR/USD\n _circuitChainlink[1] = AggregatorV3Interface(0xb49f677943BC038e9857d61E7d053CaA2C1734C1);\n return _circuitChainlink;\n }\n}\n" + }, + "contracts/oracle/implementations/mainnet/EUR/OracleLUSDEURChainlink.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\nimport \"@chainlink/contracts/src/v0.8/interfaces/AggregatorV3Interface.sol\";\n\nimport \"../../../BaseOracleChainlinkMultiTwoFeeds.sol\";\n\n/// @title OracleLUSDEURChainlink\n/// @author Angle Labs, Inc.\n/// @notice Gives the price of LUSD in Euro in base 18\ncontract OracleLUSDEURChainlink is BaseOracleChainlinkMultiTwoFeeds {\n string public constant DESCRIPTION = \"LUSD/EUR Oracle\";\n\n constructor(uint32 _stalePeriod, address _treasury) BaseOracleChainlinkMultiTwoFeeds(_stalePeriod, _treasury) {}\n\n /// @inheritdoc IOracle\n function circuitChainlink() public pure override returns (AggregatorV3Interface[] memory) {\n AggregatorV3Interface[] memory _circuitChainlink = new AggregatorV3Interface[](2);\n // Oracle LUSD/USD\n _circuitChainlink[0] = AggregatorV3Interface(0x3D7aE7E594f2f2091Ad8798313450130d0Aba3a0);\n // Oracle EUR/USD\n _circuitChainlink[1] = AggregatorV3Interface(0xb49f677943BC038e9857d61E7d053CaA2C1734C1);\n return _circuitChainlink;\n }\n}\n" + }, + "contracts/oracle/implementations/mainnet/EUR/OracleUSDCEURChainlink.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\nimport \"@chainlink/contracts/src/v0.8/interfaces/AggregatorV3Interface.sol\";\n\nimport \"../../../BaseOracleChainlinkMultiTwoFeeds.sol\";\n\n/// @title OracleUSDCEURChainlink\n/// @author Angle Labs, Inc.\n/// @notice Gives the price of USDC in Euro in base 18\ncontract OracleUSDCEURChainlink is BaseOracleChainlinkMultiTwoFeeds {\n string public constant DESCRIPTION = \"USDC/EUR Oracle\";\n\n constructor(uint32 _stalePeriod, address _treasury) BaseOracleChainlinkMultiTwoFeeds(_stalePeriod, _treasury) {}\n\n /// @inheritdoc IOracle\n function circuitChainlink() public pure override returns (AggregatorV3Interface[] memory) {\n AggregatorV3Interface[] memory _circuitChainlink = new AggregatorV3Interface[](2);\n // Oracle USDC/USD\n _circuitChainlink[0] = AggregatorV3Interface(0x8fFfFfd4AfB6115b954Bd326cbe7B4BA576818f6);\n // Oracle EUR/USD\n _circuitChainlink[1] = AggregatorV3Interface(0xb49f677943BC038e9857d61E7d053CaA2C1734C1);\n return _circuitChainlink;\n }\n}\n" + }, + "contracts/oracle/implementations/mainnet/EUR/OracleWSTETHEURChainlink.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\nimport \"@chainlink/contracts/src/v0.8/interfaces/AggregatorV3Interface.sol\";\n\nimport \"../../../BaseOracleChainlinkMultiTwoFeeds.sol\";\nimport \"../../../../interfaces/external/lido/IStETH.sol\";\n\n/// @title OracleWSTETHEURChainlink\n/// @author Angle Labs, Inc.\n/// @notice Gives the price of wSTETH in Euro in base 18\ncontract OracleWSTETHEURChainlink is BaseOracleChainlinkMultiTwoFeeds {\n string public constant DESCRIPTION = \"wSTETH/EUR Oracle\";\n IStETH public constant STETH = IStETH(0xae7ab96520DE3A18E5e111B5EaAb095312D7fE84);\n\n constructor(uint32 _stalePeriod, address _treasury) BaseOracleChainlinkMultiTwoFeeds(_stalePeriod, _treasury) {}\n\n /// @inheritdoc IOracle\n function circuitChainlink() public pure override returns (AggregatorV3Interface[] memory) {\n AggregatorV3Interface[] memory _circuitChainlink = new AggregatorV3Interface[](2);\n // Oracle stETH/USD\n _circuitChainlink[0] = AggregatorV3Interface(0xCfE54B5cD566aB89272946F602D76Ea879CAb4a8);\n // Oracle EUR/USD\n _circuitChainlink[1] = AggregatorV3Interface(0xb49f677943BC038e9857d61E7d053CaA2C1734C1);\n return _circuitChainlink;\n }\n\n /// @inheritdoc BaseOracleChainlinkMultiTwoFeeds\n function _getQuoteAmount() internal view override returns (uint256) {\n return STETH.getPooledEthByShares(1 ether);\n }\n}\n" + }, + "contracts/oracle/implementations/mainnet/USD/OracleWSTETHUSDChainlink.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\nimport \"@chainlink/contracts/src/v0.8/interfaces/AggregatorV3Interface.sol\";\n\nimport \"../../../BaseOracleChainlinkOneFeed.sol\";\nimport \"../../../../interfaces/external/lido/IStETH.sol\";\n\n/// @title OracleWSTETHUSDChainlink\n/// @author Angle Labs, Inc.\n/// @notice Gives the price of wSTETH in USD in base 18\ncontract OracleWSTETHUSDChainlink is BaseOracleChainlinkOneFeed {\n string public constant DESCRIPTION = \"wSTETH/USD Oracle\";\n IStETH public constant STETH = IStETH(0xae7ab96520DE3A18E5e111B5EaAb095312D7fE84);\n\n constructor(uint32 _stalePeriod, address _treasury) BaseOracleChainlinkOneFeed(_stalePeriod, _treasury) {}\n\n /// @inheritdoc IOracle\n function circuitChainlink() public pure override returns (AggregatorV3Interface[] memory) {\n AggregatorV3Interface[] memory _circuitChainlink = new AggregatorV3Interface[](1);\n // Oracle stETH/USD\n _circuitChainlink[0] = AggregatorV3Interface(0xCfE54B5cD566aB89272946F602D76Ea879CAb4a8);\n return _circuitChainlink;\n }\n\n /// @inheritdoc BaseOracleChainlinkOneFeed\n function _getQuoteAmount() internal view override returns (uint256) {\n return STETH.getPooledEthByShares(1 ether);\n }\n}\n" + }, + "contracts/oracle/implementations/mainnet/XAU/OracleETHXAUChainlink.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\nimport \"@chainlink/contracts/src/v0.8/interfaces/AggregatorV3Interface.sol\";\n\nimport \"../../../BaseOracleChainlinkMultiTwoFeeds.sol\";\n\n/// @title OracleETHXAUChainlink\n/// @author Angle Labs, Inc.\n/// @notice Gives the price of ETH in XAU in base 18\ncontract OracleETHXAUChainlink is BaseOracleChainlinkMultiTwoFeeds {\n string public constant DESCRIPTION = \"ETH/GOLD Oracle\";\n\n constructor(uint32 _stalePeriod, address _treasury) BaseOracleChainlinkMultiTwoFeeds(_stalePeriod, _treasury) {}\n\n /// @inheritdoc IOracle\n function circuitChainlink() public pure override returns (AggregatorV3Interface[] memory) {\n AggregatorV3Interface[] memory _circuitChainlink = new AggregatorV3Interface[](2);\n // Oracle ETH/USD\n _circuitChainlink[0] = AggregatorV3Interface(0x5f4eC3Df9cbd43714FE2740f5E3616155c5b8419);\n // Oracle XAU/USD\n _circuitChainlink[1] = AggregatorV3Interface(0x214eD9Da11D2fbe465a6fc601a91E62EbEc1a0D6);\n return _circuitChainlink;\n }\n}\n" + }, + "contracts/oracle/implementations/mainnet/XAU/OracleLUSDXAUChainlink.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\nimport \"@chainlink/contracts/src/v0.8/interfaces/AggregatorV3Interface.sol\";\n\nimport \"../../../BaseOracleChainlinkMultiTwoFeeds.sol\";\n\n/// @title OracleLUSDXAUChainlink\n/// @author Angle Labs, Inc.\n/// @notice Gives the price of LUSD in XAU in base 18\ncontract OracleLUSDXAUChainlink is BaseOracleChainlinkMultiTwoFeeds {\n string public constant DESCRIPTION = \"LUSD/GOLD Oracle\";\n\n constructor(uint32 _stalePeriod, address _treasury) BaseOracleChainlinkMultiTwoFeeds(_stalePeriod, _treasury) {}\n\n /// @inheritdoc IOracle\n function circuitChainlink() public pure override returns (AggregatorV3Interface[] memory) {\n AggregatorV3Interface[] memory _circuitChainlink = new AggregatorV3Interface[](2);\n // Oracle LUSD/USD\n _circuitChainlink[0] = AggregatorV3Interface(0x3D7aE7E594f2f2091Ad8798313450130d0Aba3a0);\n // Oracle XAU/USD\n _circuitChainlink[1] = AggregatorV3Interface(0x214eD9Da11D2fbe465a6fc601a91E62EbEc1a0D6);\n return _circuitChainlink;\n }\n}\n" + }, + "contracts/oracle/implementations/mainnet/XAU/OracleUSDCXAUChainlink.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\nimport \"@chainlink/contracts/src/v0.8/interfaces/AggregatorV3Interface.sol\";\n\nimport \"../../../BaseOracleChainlinkMultiTwoFeeds.sol\";\n\n/// @title OracleUSDCXAUChainlink\n/// @author Angle Labs, Inc.\n/// @notice Gives the price of USDC in XAU in base 18\ncontract OracleUSDCXAUChainlink is BaseOracleChainlinkMultiTwoFeeds {\n string public constant DESCRIPTION = \"USDC/GOLD Oracle\";\n\n constructor(uint32 _stalePeriod, address _treasury) BaseOracleChainlinkMultiTwoFeeds(_stalePeriod, _treasury) {}\n\n /// @inheritdoc IOracle\n function circuitChainlink() public pure override returns (AggregatorV3Interface[] memory) {\n AggregatorV3Interface[] memory _circuitChainlink = new AggregatorV3Interface[](2);\n // Oracle USDC/USD\n _circuitChainlink[0] = AggregatorV3Interface(0x8fFfFfd4AfB6115b954Bd326cbe7B4BA576818f6);\n // Oracle XAU/USD\n _circuitChainlink[1] = AggregatorV3Interface(0x214eD9Da11D2fbe465a6fc601a91E62EbEc1a0D6);\n return _circuitChainlink;\n }\n}\n" + }, + "contracts/oracle/implementations/mainnet/XAU/OracleWSTETHXAUChainlink.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\nimport \"@chainlink/contracts/src/v0.8/interfaces/AggregatorV3Interface.sol\";\n\nimport \"../../../BaseOracleChainlinkMultiTwoFeeds.sol\";\nimport \"../../../../interfaces/external/lido/IStETH.sol\";\n\n/// @title OracleWSTETHXAUChainlink\n/// @author Angle Labs, Inc.\n/// @notice Gives the price of wSTETH in XAU in base 18\ncontract OracleWSTETHXAUChainlink is BaseOracleChainlinkMultiTwoFeeds {\n string public constant DESCRIPTION = \"wSTETH/XAU Oracle\";\n IStETH public constant STETH = IStETH(0xae7ab96520DE3A18E5e111B5EaAb095312D7fE84);\n\n constructor(uint32 _stalePeriod, address _treasury) BaseOracleChainlinkMultiTwoFeeds(_stalePeriod, _treasury) {}\n\n /// @inheritdoc IOracle\n function circuitChainlink() public pure override returns (AggregatorV3Interface[] memory) {\n AggregatorV3Interface[] memory _circuitChainlink = new AggregatorV3Interface[](2);\n // Oracle stETH/USD\n _circuitChainlink[0] = AggregatorV3Interface(0xCfE54B5cD566aB89272946F602D76Ea879CAb4a8);\n // Oracle XAU/USD\n _circuitChainlink[1] = AggregatorV3Interface(0x214eD9Da11D2fbe465a6fc601a91E62EbEc1a0D6);\n return _circuitChainlink;\n }\n\n /// @inheritdoc BaseOracleChainlinkMultiTwoFeeds\n function _getQuoteAmount() internal view override returns (uint256) {\n return STETH.getPooledEthByShares(1 ether);\n }\n}\n" + }, + "contracts/oracle/implementations/optimism/EUR/OracleETHEURChainlinkOptimism.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\nimport \"@chainlink/contracts/src/v0.8/interfaces/AggregatorV3Interface.sol\";\n\nimport \"../../../BaseOracleChainlinkMultiTwoFeeds.sol\";\n\n/// @title OracleETHEURChainlinkOptimism\n/// @author Angle Labs, Inc.\n/// @notice Gives the price of ETH in Euro in base 18\n/// @dev This contract is built to be deployed on Optimism\ncontract OracleETHEURChainlinkOptimism is BaseOracleChainlinkMultiTwoFeeds {\n string public constant DESCRIPTION = \"ETH/EUR Oracle\";\n\n constructor(uint32 _stalePeriod, address _treasury) BaseOracleChainlinkMultiTwoFeeds(_stalePeriod, _treasury) {}\n\n /// @inheritdoc IOracle\n function circuitChainlink() public pure override returns (AggregatorV3Interface[] memory) {\n AggregatorV3Interface[] memory _circuitChainlink = new AggregatorV3Interface[](2);\n // Oracle ETH/USD\n _circuitChainlink[0] = AggregatorV3Interface(0x13e3Ee699D1909E989722E753853AE30b17e08c5);\n // Oracle EUR/USD\n _circuitChainlink[1] = AggregatorV3Interface(0x3626369857A10CcC6cc3A6e4f5C2f5984a519F20);\n return _circuitChainlink;\n }\n}\n" + }, + "contracts/oracle/implementations/optimism/EUR/OracleOPEURChainlinkOptimism.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\nimport \"@chainlink/contracts/src/v0.8/interfaces/AggregatorV3Interface.sol\";\n\nimport \"../../../BaseOracleChainlinkMultiTwoFeeds.sol\";\n\n/// @title OracleOPEURChainlinkOptimism\n/// @author Angle Labs, Inc.\n/// @notice Gives the price of OP in Euro in base 18\n/// @dev This contract is built to be deployed on Optimism\ncontract OracleOPEURChainlinkOptimism is BaseOracleChainlinkMultiTwoFeeds {\n string public constant DESCRIPTION = \"OP/EUR Oracle\";\n\n constructor(uint32 _stalePeriod, address _treasury) BaseOracleChainlinkMultiTwoFeeds(_stalePeriod, _treasury) {}\n\n /// @inheritdoc IOracle\n function circuitChainlink() public pure override returns (AggregatorV3Interface[] memory) {\n AggregatorV3Interface[] memory _circuitChainlink = new AggregatorV3Interface[](2);\n // Oracle OP/USD\n _circuitChainlink[0] = AggregatorV3Interface(0x0D276FC14719f9292D5C1eA2198673d1f4269246);\n // Oracle EUR/USD\n _circuitChainlink[1] = AggregatorV3Interface(0x3626369857A10CcC6cc3A6e4f5C2f5984a519F20);\n return _circuitChainlink;\n }\n}\n" + }, + "contracts/oracle/implementations/optimism/EUR/OracleUSDCEURChainlinkOptimism.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\nimport \"@chainlink/contracts/src/v0.8/interfaces/AggregatorV3Interface.sol\";\n\nimport \"../../../BaseOracleChainlinkMultiTwoFeeds.sol\";\n\n/// @title OracleUSDCEURChainlinkOptimism\n/// @author Angle Labs, Inc.\n/// @notice Gives the price of USDC in Euro in base 18\n/// @dev This contract is built to be deployed on Optimism\ncontract OracleUSDCEURChainlinkOptimism is BaseOracleChainlinkMultiTwoFeeds {\n string public constant DESCRIPTION = \"USDC/EUR Oracle\";\n\n constructor(uint32 _stalePeriod, address _treasury) BaseOracleChainlinkMultiTwoFeeds(_stalePeriod, _treasury) {}\n\n /// @inheritdoc IOracle\n function circuitChainlink() public pure override returns (AggregatorV3Interface[] memory) {\n AggregatorV3Interface[] memory _circuitChainlink = new AggregatorV3Interface[](2);\n // Oracle USDC/USD\n _circuitChainlink[0] = AggregatorV3Interface(0x16a9FA2FDa030272Ce99B29CF780dFA30361E0f3);\n // Oracle EUR/USD\n _circuitChainlink[1] = AggregatorV3Interface(0x3626369857A10CcC6cc3A6e4f5C2f5984a519F20);\n return _circuitChainlink;\n }\n}\n" + }, + "contracts/oracle/implementations/polygon/EUR/OracleBTCEURChainlinkPolygon.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\nimport \"@chainlink/contracts/src/v0.8/interfaces/AggregatorV3Interface.sol\";\n\nimport \"../../../BaseOracleChainlinkMultiTwoFeeds.sol\";\n\n/// @title OracleBTCEURChainlinkPolygon\n/// @author Angle Labs, Inc.\n/// @notice Gives the price of BTC in Euro in base 18\n/// @dev This contract is built to be deployed on Polygon\ncontract OracleBTCEURChainlinkPolygon is BaseOracleChainlinkMultiTwoFeeds {\n string public constant DESCRIPTION = \"BTC/EUR Oracle\";\n\n constructor(uint32 _stalePeriod, address _treasury) BaseOracleChainlinkMultiTwoFeeds(_stalePeriod, _treasury) {}\n\n /// @inheritdoc IOracle\n function circuitChainlink() public pure override returns (AggregatorV3Interface[] memory) {\n AggregatorV3Interface[] memory _circuitChainlink = new AggregatorV3Interface[](2);\n // Oracle BTC/USD\n _circuitChainlink[0] = AggregatorV3Interface(0xc907E116054Ad103354f2D350FD2514433D57F6f);\n // Oracle EUR/USD\n _circuitChainlink[1] = AggregatorV3Interface(0x73366Fe0AA0Ded304479862808e02506FE556a98);\n return _circuitChainlink;\n }\n}\n" + }, + "contracts/oracle/implementations/polygon/EUR/OracleETHEURChainlinkPolygon.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\nimport \"@chainlink/contracts/src/v0.8/interfaces/AggregatorV3Interface.sol\";\n\nimport \"../../../BaseOracleChainlinkMultiTwoFeeds.sol\";\n\n/// @title OracleETHEURChainlinkPolygon\n/// @author Angle Labs, Inc.\n/// @notice Gives the price of ETH in Euro in base 18\n/// @dev This contract is built to be deployed on Polygon\ncontract OracleETHEURChainlinkPolygon is BaseOracleChainlinkMultiTwoFeeds {\n string public constant DESCRIPTION = \"ETH/EUR Oracle\";\n\n constructor(uint32 _stalePeriod, address _treasury) BaseOracleChainlinkMultiTwoFeeds(_stalePeriod, _treasury) {}\n\n /// @inheritdoc IOracle\n function circuitChainlink() public pure override returns (AggregatorV3Interface[] memory) {\n AggregatorV3Interface[] memory _circuitChainlink = new AggregatorV3Interface[](2);\n // Oracle ETH/USD\n _circuitChainlink[0] = AggregatorV3Interface(0xF9680D99D6C9589e2a93a78A04A279e509205945);\n // Oracle EUR/USD\n _circuitChainlink[1] = AggregatorV3Interface(0x73366Fe0AA0Ded304479862808e02506FE556a98);\n return _circuitChainlink;\n }\n}\n" + }, + "contracts/oracle/implementations/polygon/EUR/OracleMAIEURChainlinkPolygon.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\nimport \"@chainlink/contracts/src/v0.8/interfaces/AggregatorV3Interface.sol\";\n\nimport \"../../../BaseOracleChainlinkMultiTwoFeeds.sol\";\n\n/// @title OracleMAIEURChainlinkPolygon\n/// @author Angle Labs, Inc.\n/// @notice Gives the price of MAI in Euro in base 18\n/// @dev This contract is built to be deployed on Polygon\ncontract OracleMAIEURChainlinkPolygon is BaseOracleChainlinkMultiTwoFeeds {\n string public constant DESCRIPTION = \"MAI/EUR Oracle\";\n\n constructor(uint32 _stalePeriod, address _treasury) BaseOracleChainlinkMultiTwoFeeds(_stalePeriod, _treasury) {}\n\n /// @inheritdoc IOracle\n function circuitChainlink() public pure override returns (AggregatorV3Interface[] memory) {\n AggregatorV3Interface[] memory _circuitChainlink = new AggregatorV3Interface[](2);\n // Oracle MAI/USD\n _circuitChainlink[0] = AggregatorV3Interface(0xd8d483d813547CfB624b8Dc33a00F2fcbCd2D428);\n // Oracle EUR/USD\n _circuitChainlink[1] = AggregatorV3Interface(0x73366Fe0AA0Ded304479862808e02506FE556a98);\n return _circuitChainlink;\n }\n}\n" + }, + "contracts/oracle/implementations/polygon/EUR/OracleMATICEURChainlinkPolygon.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\nimport \"@chainlink/contracts/src/v0.8/interfaces/AggregatorV3Interface.sol\";\n\nimport \"../../../BaseOracleChainlinkMultiTwoFeeds.sol\";\n\n/// @title OracleMATICEURChainlinkPolygon\n/// @author Angle Labs, Inc.\n/// @notice Gives the price of MATIC in Euro in base 18\n/// @dev This contract is built to be deployed on Polygon\ncontract OracleMATICEURChainlinkPolygon is BaseOracleChainlinkMultiTwoFeeds {\n string public constant DESCRIPTION = \"MATIC/EUR Oracle\";\n\n constructor(uint32 _stalePeriod, address _treasury) BaseOracleChainlinkMultiTwoFeeds(_stalePeriod, _treasury) {}\n\n /// @inheritdoc IOracle\n function circuitChainlink() public pure override returns (AggregatorV3Interface[] memory) {\n AggregatorV3Interface[] memory _circuitChainlink = new AggregatorV3Interface[](2);\n // Oracle MATIC/USD\n _circuitChainlink[0] = AggregatorV3Interface(0xAB594600376Ec9fD91F8e885dADF0CE036862dE0);\n // Oracle EUR/USD\n _circuitChainlink[1] = AggregatorV3Interface(0x73366Fe0AA0Ded304479862808e02506FE556a98);\n return _circuitChainlink;\n }\n}\n" + }, + "contracts/oracle/implementations/polygon/EUR/OracleUSDCEURChainlinkPolygon.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\nimport \"../../../BaseOracleChainlinkMultiTwoFeeds.sol\";\n\n/// @title OracleUSDCEURChainlinkPolygon\n/// @author Angle Labs, Inc.\n/// @notice Gives the price of USDC in Euro in base 18\n/// @dev This contract is built to be deployed on Polygon\ncontract OracleUSDCEURChainlinkPolygon is BaseOracleChainlinkMultiTwoFeeds {\n string public constant DESCRIPTION = \"USDC/EUR Oracle\";\n\n constructor(uint32 _stalePeriod, address _treasury) BaseOracleChainlinkMultiTwoFeeds(_stalePeriod, _treasury) {}\n\n /// @inheritdoc IOracle\n function circuitChainlink() public pure override returns (AggregatorV3Interface[] memory) {\n AggregatorV3Interface[] memory _circuitChainlink = new AggregatorV3Interface[](2);\n // Oracle USDC/USD\n _circuitChainlink[0] = AggregatorV3Interface(0xfE4A8cc5b5B2366C1B58Bea3858e81843581b2F7);\n // Oracle EUR/USD\n _circuitChainlink[1] = AggregatorV3Interface(0x73366Fe0AA0Ded304479862808e02506FE556a98);\n return _circuitChainlink;\n }\n}\n" + }, + "contracts/oracle/implementations/polygon/XAU/OracleETHXAUChainlinkPolygon.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\nimport \"@chainlink/contracts/src/v0.8/interfaces/AggregatorV3Interface.sol\";\n\nimport \"../../../BaseOracleChainlinkMultiTwoFeeds.sol\";\n\n/// @title OracleETHXAUChainlinkPolygon\n/// @author Angle Labs, Inc.\n/// @notice Gives the price of ETH in XAU in base 18\n/// @dev This contract is built to be deployed on Polygon\ncontract OracleETHXAUChainlinkPolygon is BaseOracleChainlinkMultiTwoFeeds {\n string public constant DESCRIPTION = \"ETH/GOLD Oracle\";\n\n constructor(uint32 _stalePeriod, address _treasury) BaseOracleChainlinkMultiTwoFeeds(_stalePeriod, _treasury) {}\n\n /// @inheritdoc IOracle\n function circuitChainlink() public pure override returns (AggregatorV3Interface[] memory) {\n AggregatorV3Interface[] memory _circuitChainlink = new AggregatorV3Interface[](2);\n // Oracle ETH/USD\n _circuitChainlink[0] = AggregatorV3Interface(0xF9680D99D6C9589e2a93a78A04A279e509205945);\n // Oracle XAU/USD\n _circuitChainlink[1] = AggregatorV3Interface(0x0C466540B2ee1a31b441671eac0ca886e051E410);\n return _circuitChainlink;\n }\n}\n" + }, + "contracts/oracle/KeeperRegistry.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\nimport \"@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol\";\nimport \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\nimport \"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\";\n\nimport \"../interfaces/ICoreBorrow.sol\";\nimport \"../interfaces/IKeeperRegistry.sol\";\n\n/// @title KeeperRegistry\n/// @notice Maintains a mapping of keepers authorized to use the core module just after oracle updates\n/// @author Angle Labs, Inc.\ncontract KeeperRegistry is Initializable, IKeeperRegistry {\n using SafeERC20 for IERC20;\n\n /// @notice Contract handling access control\n ICoreBorrow public coreBorrow;\n\n /// @notice Trusted EOAs - needs to be tx.origin\n mapping(address => uint256) public trusted;\n\n uint256[48] private __gap;\n\n // =================================== EVENTS ==================================\n\n event TrustedToggled(address indexed wallet, bool trust);\n\n // =================================== ERRORS ==================================\n\n error NotGovernorOrGuardian();\n error NotTrusted();\n error ZeroAddress();\n\n // ================================= MODIFIERS =================================\n\n /// @notice Checks whether the `msg.sender` has the governor role or the guardian role\n modifier onlyGovernorOrGuardian() {\n if (!coreBorrow.isGovernorOrGuardian(msg.sender)) revert NotGovernorOrGuardian();\n _;\n }\n\n // ================================ CONSTRUCTOR ================================\n\n constructor() initializer {}\n\n function initialize(ICoreBorrow _coreBorrow) public initializer {\n if (address(_coreBorrow) == address(0)) revert ZeroAddress();\n coreBorrow = _coreBorrow;\n }\n\n // =============================== MAIN FUNCTIONS ==============================\n\n /// @notice Adds or removes a trusted keeper bot\n function toggleTrusted(address eoa) external onlyGovernorOrGuardian {\n uint256 trustedStatus = 1 - trusted[eoa];\n trusted[eoa] = trustedStatus;\n emit TrustedToggled(eoa, trustedStatus == 1);\n }\n\n /// @inheritdoc IKeeperRegistry\n function isTrusted(address caller) external view returns (bool) {\n return trusted[caller] == 1;\n }\n}\n" + }, + "contracts/oracle/OracleChainlinkMulti.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\nimport \"@chainlink/contracts/src/v0.8/interfaces/AggregatorV3Interface.sol\";\n\nimport \"./BaseOracleChainlinkMulti.sol\";\n\n/// @title OracleChainlinkMulti\n/// @author Angle Labs, Inc.\n/// @notice Oracle contract, one contract is deployed per collateral/stablecoin pair\n/// @dev This contract concerns an oracle that uses Chainlink with multiple pools to read from\n/// @dev Typically we expect to use this contract to read like the ETH/USD and then USD/EUR feed\ncontract OracleChainlinkMulti is BaseOracleChainlinkMulti {\n // ========================= Parameters and References =========================\n\n /// @notice Chainlink pools, the order of the pools has to be the order in which they are read for the computation\n /// of the price\n AggregatorV3Interface[] internal _circuitChainlink;\n /// @notice Whether each rate for the pairs in `circuitChainlink` should be multiplied or divided\n uint8[] public circuitChainIsMultiplied;\n /// @notice Decimals for each Chainlink pairs\n uint8[] public chainlinkDecimals;\n /// @notice Unit of the stablecoin\n uint256 public immutable outBase;\n /// @notice Description of the assets concerned by the oracle and the price outputted\n string public description;\n\n // ===================================== Error =================================\n\n error IncompatibleLengths();\n\n /// @notice Constructor for an oracle using Chainlink with multiple pools to read from\n /// @param circuitChainlink_ Chainlink pool addresses (in order)\n /// @param _circuitChainIsMultiplied Whether we should multiply or divide by this rate\n /// @param _outBase Unit of the stablecoin (or the out asset) associated to the oracle\n /// @param _stalePeriod Minimum feed update frequency for the oracle to not revert\n /// @param _treasury Treasury associated to the VaultManager which reads from this feed\n /// @param _description Description of the assets concerned by the oracle\n /// @dev For instance, if this oracle is supposed to give the price of ETH in EUR, and if the agEUR\n /// stablecoin associated to EUR has 18 decimals, then `outBase` should be 10**18\n constructor(\n address[] memory circuitChainlink_,\n uint8[] memory _circuitChainIsMultiplied,\n uint256 _outBase,\n uint32 _stalePeriod,\n address _treasury,\n string memory _description\n ) BaseOracleChainlinkMulti(_stalePeriod, _treasury) {\n outBase = _outBase;\n description = _description;\n uint256 circuitLength = circuitChainlink_.length;\n if (circuitLength == 0 || circuitLength != _circuitChainIsMultiplied.length) revert IncompatibleLengths();\n for (uint256 i; i < circuitLength; ++i) {\n AggregatorV3Interface _pool = AggregatorV3Interface(circuitChainlink_[i]);\n _circuitChainlink.push(_pool);\n chainlinkDecimals.push(_pool.decimals());\n }\n circuitChainIsMultiplied = _circuitChainIsMultiplied;\n }\n\n // ============================= Reading Oracles ===============================\n\n /// @inheritdoc IOracle\n function circuitChainlink() public view override returns (AggregatorV3Interface[] memory) {\n return _circuitChainlink;\n }\n\n /// @inheritdoc IOracle\n function read() external view override returns (uint256 quoteAmount) {\n quoteAmount = outBase;\n uint256 circuitLength = _circuitChainlink.length;\n for (uint256 i; i < circuitLength; ++i) {\n quoteAmount = _readChainlinkFeed(\n quoteAmount,\n _circuitChainlink[i],\n circuitChainIsMultiplied[i],\n chainlinkDecimals[i]\n );\n }\n }\n}\n" + }, + "contracts/settlement/Settlement.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\nimport \"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\";\nimport \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\nimport \"@openzeppelin/contracts/token/ERC20/extensions/IERC20Metadata.sol\";\n\nimport \"../interfaces/IAgToken.sol\";\nimport \"../interfaces/ISwapper.sol\";\nimport \"../interfaces/IVaultManager.sol\";\n\n/// @title Settlement\n/// @author Angle Labs, Inc.\n/// @notice Settlement Contract for a VaultManager\n/// @dev This settlement contract should be activated by a careful governance which needs to have performed\n/// some key operations before activating this contract\n/// @dev In case of global settlement, there should be one settlement contract per `VaultManager`\ncontract Settlement {\n using SafeERC20 for IERC20;\n\n /// @notice Base used for parameter computation\n uint256 public constant BASE_PARAMS = 10 ** 9;\n /// @notice Base used for interest computation\n uint256 public constant BASE_INTEREST = 10 ** 27;\n /// @notice Base used for exchange rate computation. It is assumed\n /// that stablecoins have this base\n uint256 public constant BASE_STABLECOIN = 10 ** 18;\n /// @notice Duration of the claim period for over-collateralized vaults\n uint256 public constant OVER_COLLATERALIZED_CLAIM_DURATION = 3 * 24 * 3600;\n\n // =============== Immutable references set in the constructor =================\n\n /// @notice `VaultManager` of this settlement contract\n IVaultManager public immutable vaultManager;\n /// @notice Reference to the stablecoin supported by the `VaultManager` contract\n IAgToken public immutable stablecoin;\n /// @notice Reference to the collateral supported by the `VaultManager`\n IERC20 public immutable collateral;\n /// @notice Base of the collateral\n uint256 internal immutable _collatBase;\n\n // ================ Variables frozen at settlement activation ==================\n\n /// @notice Value of the oracle for the collateral/stablecoin pair\n uint256 public oracleValue;\n /// @notice Value of the interest accumulator at settlement activation\n uint256 public interestAccumulator;\n /// @notice Timestamp at which settlement was activated\n uint256 public activationTimestamp;\n /// @notice Collateral factor of the `VaultManager`\n uint64 public collateralFactor;\n\n // =================== Variables updated during the process ====================\n\n /// @notice How much collateral you can get from stablecoins\n uint256 public collateralStablecoinExchangeRate;\n /// @notice Amount of collateral that will be left over at the end of the process\n uint256 public leftOverCollateral;\n /// @notice Whether the `collateralStablecoinExchangeRate` has been computed\n bool public exchangeRateComputed;\n /// @notice Maps a vault to 1 if it was claimed by its owner\n mapping(uint256 => uint256) public vaultCheck;\n\n // ================================ Events =====================================\n\n event GlobalClaimPeriodActivated(uint256 _collateralStablecoinExchangeRate);\n event Recovered(address indexed tokenAddress, address indexed to, uint256 amount);\n event SettlementActivated(uint256 startTimestamp);\n event VaultClaimed(uint256 vaultID, uint256 stablecoinAmount, uint256 collateralAmount);\n\n // ================================ Errors =====================================\n\n error GlobalClaimPeriodNotStarted();\n error InsolventVault();\n error NotGovernor();\n error NotOwner();\n error RestrictedClaimPeriodNotEnded();\n error SettlementNotInitialized();\n error VaultAlreadyClaimed();\n\n /// @notice Constructor of the contract\n /// @param _vaultManager Address of the `VaultManager` associated to this `Settlement` contract\n /// @dev Out of safety, this constructor reads values from the `VaultManager` contract directly\n constructor(IVaultManager _vaultManager) {\n vaultManager = _vaultManager;\n stablecoin = _vaultManager.stablecoin();\n collateral = _vaultManager.collateral();\n _collatBase = 10 ** (IERC20Metadata(address(collateral)).decimals());\n }\n\n /// @notice Checks whether the `msg.sender` has the governor role or not\n modifier onlyGovernor() {\n if (!(vaultManager.treasury().isGovernor(msg.sender))) revert NotGovernor();\n _;\n }\n\n /// @notice Activates the settlement contract\n /// @dev When calling this function governance should make sure to have:\n /// 1. Accrued the interest rate on the contract\n /// 2. Paused the contract\n /// 3. Recovered all the collateral available in the `VaultManager` contract either\n /// by doing a contract upgrade or by calling a `recoverERC20` method if supported\n function activateSettlement() external onlyGovernor {\n oracleValue = (vaultManager.oracle()).read();\n interestAccumulator = vaultManager.interestAccumulator();\n activationTimestamp = block.timestamp;\n collateralFactor = vaultManager.collateralFactor();\n emit SettlementActivated(block.timestamp);\n }\n\n /// @notice Allows the owner of an over-collateralized vault to claim its collateral upon bringing back all owed stablecoins\n /// @param vaultID ID of the vault to claim\n /// @param to Address to which collateral should be sent\n /// @param who Address which should be notified if needed of the transfer of stablecoins and collateral\n /// @param data Data to pass to the `who` contract for it to successfully give the correct amount of stablecoins\n /// to the `msg.sender` address\n /// @return Amount of collateral sent to the `to` address\n /// @return Amount of stablecoins sent to the contract\n /// @dev Claiming can only happen short after settlement activation\n /// @dev A vault cannot be claimed twice and only the owner of the vault can claim it (regardless of the approval logic)\n /// @dev Only over-collateralized vaults can be claimed from this medium\n function claimOverCollateralizedVault(\n uint256 vaultID,\n address to,\n address who,\n bytes memory data\n ) external returns (uint256, uint256) {\n if (activationTimestamp == 0 || block.timestamp > activationTimestamp + OVER_COLLATERALIZED_CLAIM_DURATION)\n revert SettlementNotInitialized();\n if (vaultCheck[vaultID] == 1) revert VaultAlreadyClaimed();\n if (vaultManager.ownerOf(vaultID) != msg.sender) revert NotOwner();\n (uint256 collateralAmount, uint256 normalizedDebt) = vaultManager.vaultData(vaultID);\n uint256 vaultDebt = (normalizedDebt * interestAccumulator) / BASE_INTEREST;\n if (collateralAmount * oracleValue * collateralFactor < vaultDebt * BASE_PARAMS * _collatBase)\n revert InsolventVault();\n vaultCheck[vaultID] = 1;\n emit VaultClaimed(vaultID, vaultDebt, collateralAmount);\n return _handleRepay(collateralAmount, vaultDebt, to, who, data);\n }\n\n /// @notice Activates the global claim period by setting the `collateralStablecoinExchangeRate` which is going to\n /// dictate how much of collateral will be recoverable for each stablecoin\n /// @dev This function can only be called by the governor in order to allow it in case multiple settlements happen across\n /// different `VaultManager` to rebalance the amount of stablecoins on each to make sure that across all settlement contracts\n /// a similar value of collateral can be obtained against a similar value of stablecoins\n function activateGlobalClaimPeriod() external onlyGovernor {\n if (activationTimestamp == 0 || block.timestamp <= activationTimestamp + OVER_COLLATERALIZED_CLAIM_DURATION)\n revert RestrictedClaimPeriodNotEnded();\n uint256 collateralBalance = collateral.balanceOf(address(this));\n uint256 leftOverDebt = (vaultManager.totalNormalizedDebt() * interestAccumulator) / BASE_INTEREST;\n uint256 stablecoinBalance = stablecoin.balanceOf(address(this));\n // How much 1 of stablecoin will give you in collateral\n uint256 _collateralStablecoinExchangeRate;\n\n if (stablecoinBalance < leftOverDebt) {\n // The left over debt is the total debt minus the stablecoins which have already been accumulated\n // in the first phase\n leftOverDebt -= stablecoinBalance;\n // If you control all the debt, then you are entitled to get all the collateral left in the protocol\n _collateralStablecoinExchangeRate = (collateralBalance * BASE_STABLECOIN) / leftOverDebt;\n // But at the same time, you cannot get more collateral than the value of the stablecoins you brought\n uint256 maxExchangeRate = (BASE_STABLECOIN * _collatBase) / oracleValue;\n if (_collateralStablecoinExchangeRate >= maxExchangeRate) {\n // In this situation, we're sure that `leftOverCollateral` will be positive: governance should be wary\n // to call `recoverERC20` short after though as there's nothing that is going to prevent people to redeem\n // more stablecoins than the `leftOverDebt`\n leftOverCollateral = collateralBalance - (leftOverDebt * _collatBase) / oracleValue;\n _collateralStablecoinExchangeRate = maxExchangeRate;\n }\n }\n exchangeRateComputed = true;\n // In the else case where there is no debt left, you cannot get anything from your stablecoins\n // and so the `collateralStablecoinExchangeRate` is null\n collateralStablecoinExchangeRate = _collateralStablecoinExchangeRate;\n emit GlobalClaimPeriodActivated(_collateralStablecoinExchangeRate);\n }\n\n /// @notice Allows to claim collateral from stablecoins\n /// @param to Address to which collateral should be sent\n /// @param who Address which should be notified if needed of the transfer of stablecoins and collateral\n /// @param data Data to pass to the `who` contract for it to successfully give the correct amount of stablecoins\n /// to the `msg.sender` address\n /// @return Amount of collateral sent to the `to` address\n /// @return Amount of stablecoins sent to the contract\n /// @dev This function reverts if the `collateralStablecoinExchangeRate` is null and hence if the global claim period has\n /// not been activated\n function claimCollateralFromStablecoins(\n uint256 stablecoinAmount,\n address to,\n address who,\n bytes memory data\n ) external returns (uint256, uint256) {\n if (!exchangeRateComputed) revert GlobalClaimPeriodNotStarted();\n return\n _handleRepay(\n (stablecoinAmount * collateralStablecoinExchangeRate) / BASE_STABLECOIN,\n stablecoinAmount,\n to,\n who,\n data\n );\n }\n\n /// @notice Handles the simultaneous repayment of stablecoins with a transfer of collateral\n /// @param collateralAmountToGive Amount of collateral the contract should give\n /// @param stableAmountToRepay Amount of stablecoins the contract should burn from the call\n /// @param to Address to which stablecoins should be sent\n /// @param who Address which should be notified if needed of the transfer\n /// @param data Data to pass to the `who` contract for it to successfully give the correct amount of stablecoins\n /// to the `msg.sender` address\n /// @dev This function allows for capital-efficient claims of collateral from stablecoins\n function _handleRepay(\n uint256 collateralAmountToGive,\n uint256 stableAmountToRepay,\n address to,\n address who,\n bytes memory data\n ) internal returns (uint256, uint256) {\n collateral.safeTransfer(to, collateralAmountToGive);\n if (data.length != 0) {\n ISwapper(who).swap(\n collateral,\n IERC20(address(stablecoin)),\n msg.sender,\n stableAmountToRepay,\n collateralAmountToGive,\n data\n );\n }\n stablecoin.transferFrom(msg.sender, address(this), stableAmountToRepay);\n return (collateralAmountToGive, stableAmountToRepay);\n }\n\n /// @notice Recovers leftover tokens from the contract or tokens that were mistakenly sent to the contract\n /// @param tokenAddress Address of the token to recover\n /// @param to Address to send the remaining tokens to\n /// @param amountToRecover Amount to recover from the contract\n /// @dev Governors cannot recover more collateral than what would be leftover from the contract\n /// @dev This function can be used to rebalance stablecoin balances across different settlement contracts\n /// to make sure every stablecoin can be redeemed for the same value of collateral\n /// @dev It can also be used to recover tokens that are mistakenly sent to this contract\n function recoverERC20(address tokenAddress, address to, uint256 amountToRecover) external onlyGovernor {\n if (tokenAddress == address(collateral)) {\n if (!exchangeRateComputed) revert GlobalClaimPeriodNotStarted();\n leftOverCollateral -= amountToRecover;\n collateral.safeTransfer(to, amountToRecover);\n } else {\n IERC20(tokenAddress).safeTransfer(to, amountToRecover);\n }\n emit Recovered(tokenAddress, to, amountToRecover);\n }\n}\n" + }, + "contracts/swapper/Swapper.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\n/*\n * █ \n ***** ▓▓▓ \n * ▓▓▓▓▓▓▓ \n * ///. ▓▓▓▓▓▓▓▓▓▓▓▓▓ \n ***** //////// ▓▓▓▓▓▓▓ \n * ///////////// ▓▓▓ \n ▓▓ ////////////////// █ ▓▓ \n ▓▓ ▓▓ /////////////////////// ▓▓ ▓▓ \n ▓▓ ▓▓ //////////////////////////// ▓▓ ▓▓ \n ▓▓ ▓▓ /////////▓▓▓///////▓▓▓///////// ▓▓ ▓▓ \n ▓▓ ,////////////////////////////////////// ▓▓ ▓▓ \n ▓▓ ////////////////////////////////////////// ▓▓ \n ▓▓ //////////////////////▓▓▓▓///////////////////// \n ,//////////////////////////////////////////////////// \n .////////////////////////////////////////////////////////// \n .//////////////////////////██.,//////////////////////////█ \n .//////////////////////████..,./////////////////////██ \n ...////////////////███████.....,.////////////////███ \n ,.,////////////████████ ........,///////////████ \n .,.,//////█████████ ,.......///////████ \n ,..//████████ ........./████ \n ..,██████ .....,███ \n .██ ,.,█ \n \n \n \n ▓▓ ▓▓▓▓▓▓▓▓▓▓ ▓▓▓▓▓▓▓▓▓▓ ▓▓ ▓▓▓▓▓▓▓▓▓▓ \n ▓▓▓▓▓▓ ▓▓▓ ▓▓▓ ▓▓▓ ▓▓ ▓▓ ▓▓▓▓ \n ▓▓▓ ▓▓▓ ▓▓▓ ▓▓▓ ▓▓▓ ▓▓▓ ▓▓ ▓▓▓▓▓ \n ▓▓▓ ▓▓ ▓▓▓ ▓▓▓ ▓▓▓▓▓▓▓▓▓▓ ▓▓▓▓▓▓▓▓▓▓ ▓▓▓▓▓▓▓▓▓▓ \n*/\n\npragma solidity ^0.8.12;\n\nimport \"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\";\nimport \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\n\nimport \"../interfaces/IAngleRouterSidechain.sol\";\nimport \"../interfaces/ICoreBorrow.sol\";\nimport \"../interfaces/ISwapper.sol\";\nimport \"../interfaces/external/lido/IWStETH.sol\";\nimport \"../interfaces/external/uniswap/IUniswapRouter.sol\";\n\n// ==================================== ENUM ===================================\n\n/// @notice All possible swaps\nenum SwapType {\n UniswapV3,\n oneInch,\n AngleRouter,\n Leverage,\n None\n}\n\n/// @title Swapper\n/// @author Angle Labs, Inc.\n/// @notice Swapper contract facilitating interactions with Angle VaultManager contracts, notably\n/// liquidation and leverage transactions\ncontract Swapper is ISwapper {\n using SafeERC20 for IERC20;\n\n // ===================== CONSTANTS AND IMMUTABLE VARIABLES =====================\n\n /// @notice Reference to the `CoreBorrow` contract of the module which handles all AccessControl logic\n ICoreBorrow public immutable core;\n /// @notice Uniswap Router contract\n IUniswapV3Router public immutable uniV3Router;\n /// @notice 1inch Router\n address public immutable oneInch;\n /// @notice AngleRouter\n IAngleRouterSidechain public immutable angleRouter;\n\n // =================================== ERRORS ==================================\n\n error EmptyReturnMessage();\n error IncompatibleLengths();\n error NotGovernorOrGuardian();\n error TooSmallAmountOut();\n error ZeroAddress();\n\n /// @notice Constructor of the contract\n /// @param _core Core address\n /// @param _uniV3Router UniswapV3 Router address\n /// @param _oneInch 1inch Router address\n /// @param _angleRouter AngleRouter contract address\n constructor(\n ICoreBorrow _core,\n IUniswapV3Router _uniV3Router,\n address _oneInch,\n IAngleRouterSidechain _angleRouter\n ) {\n if (address(_core) == address(0) || _oneInch == address(0) || address(_angleRouter) == address(0))\n revert ZeroAddress();\n core = _core;\n uniV3Router = _uniV3Router;\n oneInch = _oneInch;\n angleRouter = _angleRouter;\n }\n\n // ========================= EXTERNAL ACCESS FUNCTIONS =========================\n\n /// @inheritdoc ISwapper\n /// @dev This function swaps the `inToken` to the `outToken` by doing a UniV3 swap, a 1inch swap or by interacting\n /// with the `AngleRouter` contract\n /// @dev One slippage check is performed at the end of the call\n /// @dev In this implementation, the function tries to make sure that the `outTokenRecipient` address has at the end\n /// of the call `outTokenOwed`, leftover tokens are sent to a `to` address which by default is the `outTokenRecipient`\n function swap(\n IERC20 inToken,\n IERC20 outToken,\n address outTokenRecipient,\n uint256 outTokenOwed,\n uint256 inTokenObtained,\n bytes memory data\n ) external {\n // Address to receive the surplus amount of token at the end of the call\n address to;\n // For slippage protection, it is checked at the end of the call\n uint256 minAmountOut;\n // Type of the swap to execute: if `swapType == 4`, then it is optional to swap\n uint256 swapType;\n // We're reusing the `data` variable (it can be `path` on UniswapV3, a payload for 1inch or like encoded actions\n // for a router call)\n (to, minAmountOut, swapType, data) = abi.decode(data, (address, uint256, uint256, bytes));\n\n to = (to == address(0)) ? outTokenRecipient : to;\n\n _swap(inToken, inTokenObtained, SwapType(swapType), data);\n\n // A final slippage check is performed after the swaps\n uint256 outTokenBalance = outToken.balanceOf(address(this));\n if (outTokenBalance < minAmountOut) revert TooSmallAmountOut();\n\n // The `outTokenRecipient` may already have enough in balance, in which case there's no need to transfer\n // to this address the token and everything can be given to the `to` address\n uint256 outTokenBalanceRecipient = outToken.balanceOf(outTokenRecipient);\n if (outTokenBalanceRecipient >= outTokenOwed || to == outTokenRecipient)\n outToken.safeTransfer(to, outTokenBalance);\n else {\n // The `outTokenRecipient` should receive the delta to make sure its end balance is equal to `outTokenOwed`\n // Any leftover in this case is sent to the `to` address\n // The function reverts if it did not obtain more than `outTokenOwed - outTokenBalanceRecipient` from the swap\n outToken.safeTransfer(outTokenRecipient, outTokenOwed - outTokenBalanceRecipient);\n outToken.safeTransfer(to, outTokenBalanceRecipient + outTokenBalance - outTokenOwed);\n }\n // Reusing the `inTokenObtained` variable for the `inToken` balance\n // Sending back the remaining amount of inTokens to the `to` address: it is possible that not the full `inTokenObtained`\n // is swapped to `outToken` if we're using the `1inch` payload\n inTokenObtained = inToken.balanceOf(address(this));\n if (inTokenObtained != 0) inToken.safeTransfer(to, inTokenObtained);\n }\n\n // ============================ GOVERNANCE FUNCTION ============================\n\n /// @notice Changes allowances of this contract for different tokens\n /// @param tokens Addresses of the tokens to allow\n /// @param spenders Addresses to allow transfer\n /// @param amounts Amounts to allow\n function changeAllowance(\n IERC20[] calldata tokens,\n address[] calldata spenders,\n uint256[] calldata amounts\n ) external {\n if (!core.isGovernorOrGuardian(msg.sender)) revert NotGovernorOrGuardian();\n uint256 tokensLength = tokens.length;\n if (tokensLength != spenders.length || tokensLength != amounts.length) revert IncompatibleLengths();\n for (uint256 i; i < tokensLength; ++i) {\n _changeAllowance(tokens[i], spenders[i], amounts[i]);\n }\n }\n\n // ========================= INTERNAL UTILITY FUNCTIONS ========================\n\n /// @notice Internal version of the `_changeAllowance` function\n function _changeAllowance(IERC20 token, address spender, uint256 amount) internal {\n uint256 currentAllowance = token.allowance(address(this), spender);\n // In case `currentAllowance < type(uint256).max / 2` and we want to increase it:\n // Do nothing (to handle tokens that need reapprovals to 0 and save gas)\n if (currentAllowance < amount && currentAllowance < type(uint256).max / 2) {\n token.safeIncreaseAllowance(spender, amount - currentAllowance);\n } else if (currentAllowance > amount) {\n token.safeDecreaseAllowance(spender, currentAllowance - amount);\n }\n }\n\n /// @notice Checks the allowance for a contract and updates it to the max if it is not big enough\n /// @param token Token for which allowance should be checked\n /// @param spender Address to grant allowance to\n /// @param amount Minimum amount of tokens needed for the allowance\n function _checkAllowance(IERC20 token, address spender, uint256 amount) internal {\n uint256 currentAllowance = token.allowance(address(this), spender);\n if (currentAllowance < amount) token.safeIncreaseAllowance(spender, type(uint256).max - currentAllowance);\n }\n\n /// @notice Performs a swap using either Uniswap, 1inch. This function can also stake stETH to wstETH\n /// @param inToken Token to swap\n /// @param amount Amount of tokens to swap\n /// @param swapType Type of the swap to perform\n /// @param args Extra args for the swap: in the case of Uniswap it should be a path, for 1inch it should be\n /// a payload\n /// @dev This function does nothing if `swapType` is None and it simply passes on the `amount` it received\n /// @dev No slippage is specified in the actions given here as a final slippage check is performed\n /// after the call to this function\n function _swap(IERC20 inToken, uint256 amount, SwapType swapType, bytes memory args) internal {\n if (swapType == SwapType.UniswapV3) _swapOnUniswapV3(inToken, amount, args);\n else if (swapType == SwapType.oneInch) _swapOn1inch(inToken, args);\n else if (swapType == SwapType.AngleRouter) _angleRouterActions(inToken, args);\n else if (swapType == SwapType.Leverage) _swapLeverage(args);\n }\n\n /// @notice Performs a UniswapV3 swap\n /// @param inToken Token to swap\n /// @param amount Amount of tokens to swap\n /// @param path Path for the UniswapV3 swap: this encodes the out token that is going to be obtained\n /// @dev This function does not check the out token obtained here: if it is wrongly specified, either\n /// the `swap` function could fail or these tokens could stay on the contract\n function _swapOnUniswapV3(IERC20 inToken, uint256 amount, bytes memory path) internal returns (uint256 amountOut) {\n // We need more than `amount` of allowance to the contract\n _checkAllowance(inToken, address(uniV3Router), amount);\n amountOut = uniV3Router.exactInput(ExactInputParams(path, address(this), block.timestamp, amount, 0));\n }\n\n /// @notice Allows to swap any token to an accepted collateral via 1inch API\n /// @param inToken Token received for the 1inch swap\n /// @param payload Bytes needed for 1inch API\n function _swapOn1inch(IERC20 inToken, bytes memory payload) internal returns (uint256 amountOut) {\n _changeAllowance(inToken, oneInch, type(uint256).max);\n //solhint-disable-next-line\n (bool success, bytes memory result) = oneInch.call(payload);\n if (!success) _revertBytes(result);\n amountOut = abi.decode(result, (uint256));\n }\n\n /// @notice Performs actions with the router contract of the protocol on the corresponding chain\n /// @param inToken Token concerned by the action and for which\n function _angleRouterActions(IERC20 inToken, bytes memory args) internal {\n (ActionType[] memory actions, bytes[] memory actionData) = abi.decode(args, (ActionType[], bytes[]));\n _changeAllowance(inToken, address(angleRouter), type(uint256).max);\n PermitType[] memory permits;\n angleRouter.mixer(permits, actions, actionData);\n }\n\n /// @notice Allows to take leverage or deleverage via a specific contract\n /// @param payload Bytes needed for 1inch API\n /// @dev This function is to be implemented if the swapper concerns a token that requires some actions\n /// not supported by 1inch or UniV3\n function _swapLeverage(bytes memory payload) internal virtual returns (uint256 amountOut) {}\n\n /// @notice Internal function used for error handling\n /// @param errMsg Error message received\n function _revertBytes(bytes memory errMsg) internal pure {\n if (errMsg.length != 0) {\n //solhint-disable-next-line\n assembly {\n revert(add(32, errMsg), mload(errMsg))\n }\n }\n revert EmptyReturnMessage();\n }\n}\n" + }, + "contracts/treasury/Treasury.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\n/*\n * █ \n ***** ▓▓▓ \n * ▓▓▓▓▓▓▓ \n * ///. ▓▓▓▓▓▓▓▓▓▓▓▓▓ \n ***** //////// ▓▓▓▓▓▓▓ \n * ///////////// ▓▓▓ \n ▓▓ ////////////////// █ ▓▓ \n ▓▓ ▓▓ /////////////////////// ▓▓ ▓▓ \n ▓▓ ▓▓ //////////////////////////// ▓▓ ▓▓ \n ▓▓ ▓▓ /////////▓▓▓///////▓▓▓///////// ▓▓ ▓▓ \n ▓▓ ,////////////////////////////////////// ▓▓ ▓▓ \n ▓▓ ////////////////////////////////////////// ▓▓ \n ▓▓ //////////////////////▓▓▓▓///////////////////// \n ,//////////////////////////////////////////////////// \n .////////////////////////////////////////////////////////// \n .//////////////////////////██.,//////////////////////////█ \n .//////////////////////████..,./////////////////////██ \n ...////////////////███████.....,.////////////////███ \n ,.,////////////████████ ........,///////////████ \n .,.,//////█████████ ,.......///////████ \n ,..//████████ ........./████ \n ..,██████ .....,███ \n .██ ,.,█ \n \n \n \n ▓▓ ▓▓▓▓▓▓▓▓▓▓ ▓▓▓▓▓▓▓▓▓▓ ▓▓ ▓▓▓▓▓▓▓▓▓▓ \n ▓▓▓▓▓▓ ▓▓▓ ▓▓▓ ▓▓▓ ▓▓ ▓▓ ▓▓▓▓ \n ▓▓▓ ▓▓▓ ▓▓▓ ▓▓▓ ▓▓▓ ▓▓▓ ▓▓ ▓▓▓▓▓ \n ▓▓▓ ▓▓ ▓▓▓ ▓▓▓ ▓▓▓▓▓▓▓▓▓▓ ▓▓▓▓▓▓▓▓▓▓ ▓▓▓▓▓▓▓▓▓▓ \n*/\n\npragma solidity ^0.8.12;\n\nimport \"@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol\";\nimport \"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\";\nimport \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\n\nimport \"../interfaces/IAgToken.sol\";\nimport \"../interfaces/ICoreBorrow.sol\";\nimport \"../interfaces/IFlashAngle.sol\";\nimport \"../interfaces/ITreasury.sol\";\nimport \"../interfaces/IVaultManager.sol\";\n\n/// @title Treasury\n/// @author Angle Labs, Inc.\n/// @notice Treasury of Angle Borrowing Module doing the accounting across all VaultManagers for\n/// a given stablecoin\ncontract Treasury is ITreasury, Initializable {\n using SafeERC20 for IERC20;\n\n /// @notice Base used for parameter computation\n uint256 public constant BASE_9 = 1e9;\n\n // ================================= REFERENCES ================================\n\n /// @notice Reference to the `CoreBorrow` contract of the module which handles all AccessControl logic\n ICoreBorrow public core;\n /// @notice Flash Loan Module with a minter right on the stablecoin\n IFlashAngle public flashLoanModule;\n /// @inheritdoc ITreasury\n IAgToken public stablecoin;\n /// @notice Address responsible for handling the surplus made by the treasury\n address public surplusManager;\n /// @notice List of the accepted `VaultManager` of the protocol\n address[] public vaultManagerList;\n /// @notice Maps an address to 1 if it was initialized as a `VaultManager` contract\n mapping(address => uint256) public vaultManagerMap;\n\n // ================================= VARIABLES =================================\n\n /// @notice Amount of bad debt (unbacked stablecoin) accumulated across all `VaultManager` contracts\n /// linked to this stablecoin\n uint256 public badDebt;\n /// @notice Surplus amount accumulated by the contract waiting to be distributed to governance. Technically\n /// only a share of this `surplusBuffer` will go to governance. Once a share of the surplus buffer has been\n /// given to governance, then this surplus is reset\n uint256 public surplusBuffer;\n\n // ================================= PARAMETER =================================\n\n /// @notice Share of the `surplusBuffer` distributed to governance (in `BASE_9`)\n uint64 public surplusForGovernance;\n\n // =================================== EVENTS ==================================\n\n event BadDebtUpdated(uint256 badDebtValue);\n event CoreUpdated(address indexed _core);\n event NewTreasurySet(address indexed _treasury);\n event Recovered(address indexed token, address indexed to, uint256 amount);\n event SurplusBufferUpdated(uint256 surplusBufferValue);\n event SurplusForGovernanceUpdated(uint64 _surplusForGovernance);\n event SurplusManagerUpdated(address indexed _surplusManager);\n event VaultManagerToggled(address indexed vaultManager);\n\n // =================================== ERRORS ==================================\n\n error AlreadyVaultManager();\n error InvalidAddress();\n error InvalidTreasury();\n error NotCore();\n error NotGovernor();\n error NotVaultManager();\n error RightsNotRemoved();\n error TooBigAmount();\n error TooHighParameterValue();\n error ZeroAddress();\n\n // ================================== MODIFIER =================================\n\n /// @notice Checks whether the `msg.sender` has the governor role or not\n modifier onlyGovernor() {\n if (!core.isGovernor(msg.sender)) revert NotGovernor();\n _;\n }\n\n /// @notice Initializes the treasury contract\n /// @param _core Address of the `CoreBorrow` contract of the module\n /// @param _stablecoin Address of the stablecoin\n function initialize(ICoreBorrow _core, IAgToken _stablecoin) public virtual initializer {\n if (address(_stablecoin) == address(0) || address(_core) == address(0)) revert ZeroAddress();\n core = _core;\n stablecoin = _stablecoin;\n }\n\n /// @custom:oz-upgrades-unsafe-allow constructor\n constructor() initializer {}\n\n // =============================== VIEW FUNCTIONS ==============================\n\n /// @inheritdoc ITreasury\n function isGovernor(address admin) external view returns (bool) {\n return core.isGovernor(admin);\n }\n\n /// @inheritdoc ITreasury\n function isGovernorOrGuardian(address admin) external view returns (bool) {\n return core.isGovernorOrGuardian(admin);\n }\n\n /// @inheritdoc ITreasury\n function isVaultManager(address _vaultManager) external view returns (bool) {\n return vaultManagerMap[_vaultManager] == 1;\n }\n\n // ===================== EXTERNAL PERMISSIONLESS FUNCTIONS =====================\n\n /// @notice Fetches the surplus accrued across all the `VaultManager` contracts controlled by this\n /// `Treasury` contract as well as from the fees of the `FlashLoan` module\n /// @return Surplus buffer value at the end of the call\n /// @return Bad debt value at the end of the call\n /// @dev This function pools surplus and bad debt across all contracts and then updates the `surplusBuffer`\n /// (or the `badDebt` if more losses were made than profits)\n function fetchSurplusFromAll() external returns (uint256, uint256) {\n return _fetchSurplusFromAll();\n }\n\n /// @notice Fetches the surplus accrued in the flash loan module and updates the `surplusBuffer`\n /// @return Surplus buffer value at the end of the call\n /// @return Bad debt value at the end of the call\n /// @dev This function fails if the `flashLoanModule` has not been initialized yet\n function fetchSurplusFromFlashLoan() external returns (uint256, uint256) {\n uint256 surplusBufferValue = surplusBuffer + flashLoanModule.accrueInterestToTreasury(stablecoin);\n return _updateSurplusAndBadDebt(surplusBufferValue, badDebt);\n }\n\n /// @notice Pushes the surplus buffer to the `surplusManager` contract\n /// @return governanceAllocation Amount transferred to governance\n /// @dev It makes sure to fetch the surplus from all the contracts handled by this treasury to avoid\n /// the situation where rewards are still distributed to governance even though a `VaultManager` has made\n /// a big loss\n /// @dev Typically this function is to be called once every week by a keeper to distribute rewards to veANGLE\n /// holders\n /// @dev `stablecoin` must be an AgToken and hence `transfer` reverts if the call is not successful\n function pushSurplus() external returns (uint256 governanceAllocation) {\n address _surplusManager = surplusManager;\n if (_surplusManager == address(0)) {\n revert ZeroAddress();\n }\n (uint256 surplusBufferValue, ) = _fetchSurplusFromAll();\n surplusBuffer = 0;\n emit SurplusBufferUpdated(0);\n governanceAllocation = (surplusForGovernance * surplusBufferValue) / BASE_9;\n stablecoin.transfer(_surplusManager, governanceAllocation);\n }\n\n /// @notice Updates the bad debt of the protocol in case where the protocol has accumulated some revenue\n /// from an external source\n /// @param amount Amount to reduce the bad debt of\n /// @return badDebtValue Value of the bad debt at the end of the call\n /// @dev If the protocol has made a loss and managed to make some profits to recover for this loss (through\n /// a program like Olympus Pro), then this function needs to be called\n /// @dev `badDebt` is simply reduced here by burning stablecoins\n /// @dev It is impossible to burn more than the `badDebt` otherwise this function could be used to manipulate\n /// the `surplusBuffer` and hence the amount going to governance\n function updateBadDebt(uint256 amount) external returns (uint256 badDebtValue) {\n stablecoin.burnSelf(amount, address(this));\n badDebtValue = badDebt - amount;\n badDebt = badDebtValue;\n emit BadDebtUpdated(badDebtValue);\n }\n\n // ========================= INTERNAL UTILITY FUNCTIONS ========================\n\n /// @notice Internal version of the `fetchSurplusFromAll` function\n function _fetchSurplusFromAll() internal returns (uint256 surplusBufferValue, uint256 badDebtValue) {\n (surplusBufferValue, badDebtValue) = _fetchSurplusFromList(vaultManagerList);\n // It will fail anyway if the `flashLoanModule` is the zero address\n if (address(flashLoanModule) != address(0))\n surplusBufferValue += flashLoanModule.accrueInterestToTreasury(stablecoin);\n (surplusBufferValue, badDebtValue) = _updateSurplusAndBadDebt(surplusBufferValue, badDebtValue);\n }\n\n /// @notice Fetches the surplus from a list of `VaultManager` addresses without modifying the\n /// `surplusBuffer` and `badDebtValue`\n /// @return surplusBufferValue Value the `surplusBuffer` should have after the call if it was updated\n /// @return badDebtValue Value the `badDebt` should have after the call if it was updated\n /// @dev This internal function is never to be called alone, and should always be called in conjunction\n /// with the `_updateSurplusAndBadDebt` function\n function _fetchSurplusFromList(\n address[] memory vaultManagers\n ) internal returns (uint256 surplusBufferValue, uint256 badDebtValue) {\n badDebtValue = badDebt;\n surplusBufferValue = surplusBuffer;\n uint256 newSurplus;\n uint256 newBadDebt;\n uint256 vaultManagersLength = vaultManagers.length;\n for (uint256 i; i < vaultManagersLength; ++i) {\n (newSurplus, newBadDebt) = IVaultManager(vaultManagers[i]).accrueInterestToTreasury();\n surplusBufferValue += newSurplus;\n badDebtValue += newBadDebt;\n }\n }\n\n /// @notice Updates the `surplusBuffer` and the `badDebt` from updated values after calling the flash loan module\n /// and/or a list of `VaultManager` contracts\n /// @param surplusBufferValue Value of the surplus buffer after the calls to the different modules\n /// @param badDebtValue Value of the bad debt after the calls to the different modules\n /// @return Value of the `surplusBuffer` corrected from the `badDebt`\n /// @return Value of the `badDebt` corrected from the `surplusBuffer` and from the surplus the treasury had accumulated\n /// previously\n /// @dev When calling this function, it is possible that there is a positive `surplusBufferValue` and `badDebtValue`,\n /// this function tries to reconcile both values and makes sure that we either have surplus or bad debt but not both\n /// at the same time\n function _updateSurplusAndBadDebt(\n uint256 surplusBufferValue,\n uint256 badDebtValue\n ) internal returns (uint256, uint256) {\n if (badDebtValue != 0) {\n // If we have bad debt we need to burn stablecoins that accrued to the protocol\n // We still need to make sure that we're not burning too much or as much as we can if the debt is big\n uint256 balance = stablecoin.balanceOf(address(this));\n // We are going to burn `min(balance, badDebtValue)`\n uint256 toBurn = balance <= badDebtValue ? balance : badDebtValue;\n stablecoin.burnSelf(toBurn, address(this));\n // If we burned more than `surplusBuffer`, we set surplus to 0. It means we had to tap into Treasury reserve\n surplusBufferValue = toBurn >= surplusBufferValue ? 0 : surplusBufferValue - toBurn;\n badDebtValue -= toBurn;\n // Note here that the stablecoin balance is necessarily greater than the surplus buffer, and so if\n // `surplusBuffer >= toBurn`, then `badDebtValue = toBurn`\n }\n surplusBuffer = surplusBufferValue;\n badDebt = badDebtValue;\n emit SurplusBufferUpdated(surplusBufferValue);\n emit BadDebtUpdated(badDebtValue);\n return (surplusBufferValue, badDebtValue);\n }\n\n /// @notice Adds a new `VaultManager`\n /// @param vaultManager `VaultManager` contract to add\n /// @dev This contract should have already been initialized with a correct treasury address\n /// @dev It's this function that gives the minter right to the `VaultManager`\n function _addVaultManager(address vaultManager) internal virtual {\n if (vaultManagerMap[vaultManager] == 1) revert AlreadyVaultManager();\n if (address(IVaultManager(vaultManager).treasury()) != address(this)) revert InvalidTreasury();\n vaultManagerMap[vaultManager] = 1;\n vaultManagerList.push(vaultManager);\n emit VaultManagerToggled(vaultManager);\n stablecoin.addMinter(vaultManager);\n }\n\n // ============================= GOVERNOR FUNCTIONS ============================\n\n /// @notice Adds a new minter for the stablecoin\n /// @param minter Minter address to add\n function addMinter(address minter) external virtual onlyGovernor {\n if (minter == address(0)) revert ZeroAddress();\n stablecoin.addMinter(minter);\n }\n\n /// @notice External wrapper for `_addVaultManager`\n function addVaultManager(address vaultManager) external virtual onlyGovernor {\n _addVaultManager(vaultManager);\n }\n\n /// @notice Removes a minter from the stablecoin contract\n /// @param minter Minter address to remove\n function removeMinter(address minter) external virtual onlyGovernor {\n // To remove the minter role to a `VaultManager` you have to go through the `removeVaultManager` function\n if (vaultManagerMap[minter] == 1) revert InvalidAddress();\n stablecoin.removeMinter(minter);\n }\n\n /// @notice Removes a `VaultManager`\n /// @param vaultManager `VaultManager` contract to remove\n /// @dev A removed `VaultManager` loses its minter right on the stablecoin\n function removeVaultManager(address vaultManager) external onlyGovernor {\n if (vaultManagerMap[vaultManager] != 1) revert NotVaultManager();\n delete vaultManagerMap[vaultManager];\n // deletion from `vaultManagerList` loop\n uint256 vaultManagerListLength = vaultManagerList.length;\n for (uint256 i; i < vaultManagerListLength - 1; ++i) {\n if (vaultManagerList[i] == vaultManager) {\n // replace the `VaultManager` to remove with the last of the list\n vaultManagerList[i] = vaultManagerList[vaultManagerListLength - 1];\n break;\n }\n }\n // remove last element in array\n vaultManagerList.pop();\n emit VaultManagerToggled(vaultManager);\n stablecoin.removeMinter(vaultManager);\n }\n\n /// @notice Allows to recover any ERC20 token, including the stablecoin handled by this contract, and to send it\n /// to a contract\n /// @param tokenAddress Address of the token to recover\n /// @param to Address of the contract to send collateral to\n /// @param amountToRecover Amount of collateral to transfer\n /// @dev It is impossible to recover the stablecoin of the protocol if there is some bad debt for it\n /// @dev In this case, the function makes sure to fetch the surplus/bad debt from all the `VaultManager` contracts\n /// and from the flash loan module\n /// @dev If the token to recover is the stablecoin, tokens recovered are fetched\n /// from the surplus and not from the `surplusBuffer`\n function recoverERC20(address tokenAddress, address to, uint256 amountToRecover) external onlyGovernor {\n // Cannot recover stablecoin if badDebt or tap into the surplus buffer\n if (tokenAddress == address(stablecoin)) {\n _fetchSurplusFromAll();\n // If balance is non zero then this means, after the call to `fetchSurplusFromAll` that\n // bad debt is necessarily null\n uint256 balance = stablecoin.balanceOf(address(this));\n if (amountToRecover + surplusBuffer > balance) revert TooBigAmount();\n stablecoin.transfer(to, amountToRecover);\n } else {\n IERC20(tokenAddress).safeTransfer(to, amountToRecover);\n }\n emit Recovered(tokenAddress, to, amountToRecover);\n }\n\n /// @notice Changes the treasury contract and communicates this change to all `VaultManager` contract\n /// @param _treasury New treasury address for this stablecoin\n /// @dev This function is basically a way to remove rights to this contract and grant them to a new one\n /// @dev It could be used to set a new core contract\n function setTreasury(address _treasury) external virtual onlyGovernor {\n if (ITreasury(_treasury).stablecoin() != stablecoin) revert InvalidTreasury();\n // Flash loan role should be removed before calling this function\n if (core.isFlashLoanerTreasury(address(this))) revert RightsNotRemoved();\n emit NewTreasurySet(_treasury);\n uint256 vaultManagerListLength = vaultManagerList.length;\n for (uint256 i; i < vaultManagerListLength; ++i) {\n IVaultManager(vaultManagerList[i]).setTreasury(_treasury);\n }\n // A `TreasuryUpdated` event is triggered in the stablecoin\n stablecoin.setTreasury(_treasury);\n }\n\n /// @notice Sets the `surplusForGovernance` parameter\n /// @param _surplusForGovernance New value of the parameter\n /// @dev To pause surplus distribution, governance needs to set a zero value for `surplusForGovernance`\n /// which means\n function setSurplusForGovernance(uint64 _surplusForGovernance) external onlyGovernor {\n if (_surplusForGovernance > BASE_9) revert TooHighParameterValue();\n surplusForGovernance = _surplusForGovernance;\n emit SurplusForGovernanceUpdated(_surplusForGovernance);\n }\n\n /// @notice Sets the `surplusManager` contract responsible for handling the surplus of the\n /// protocol\n /// @param _surplusManager New address responsible for handling the surplus\n function setSurplusManager(address _surplusManager) external onlyGovernor {\n if (_surplusManager == address(0)) revert ZeroAddress();\n surplusManager = _surplusManager;\n emit SurplusManagerUpdated(_surplusManager);\n }\n\n /// @notice Sets a new `core` contract\n /// @dev This function should typically be called on all treasury contracts after the `setCore`\n /// function has been called on the `CoreBorrow` contract\n /// @dev One sanity check that can be performed here is to verify whether at least the governor\n /// calling the contract is still a governor in the new core\n function setCore(ICoreBorrow _core) external onlyGovernor {\n if (!_core.isGovernor(msg.sender)) revert NotGovernor();\n core = ICoreBorrow(_core);\n emit CoreUpdated(address(_core));\n }\n\n /// @inheritdoc ITreasury\n function setFlashLoanModule(address _flashLoanModule) external {\n if (msg.sender != address(core)) revert NotCore();\n address oldFlashLoanModule = address(flashLoanModule);\n flashLoanModule = IFlashAngle(_flashLoanModule);\n if (oldFlashLoanModule != address(0)) {\n stablecoin.removeMinter(oldFlashLoanModule);\n }\n // We may want to cancel the module\n if (_flashLoanModule != address(0)) {\n stablecoin.addMinter(_flashLoanModule);\n }\n }\n}\n" + }, + "contracts/ui-helpers/AngleBorrowHelpers.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\n/*\n * █ \n ***** ▓▓▓ \n * ▓▓▓▓▓▓▓ \n * ///. ▓▓▓▓▓▓▓▓▓▓▓▓▓ \n ***** //////// ▓▓▓▓▓▓▓ \n * ///////////// ▓▓▓ \n ▓▓ ////////////////// █ ▓▓ \n ▓▓ ▓▓ /////////////////////// ▓▓ ▓▓ \n ▓▓ ▓▓ //////////////////////////// ▓▓ ▓▓ \n ▓▓ ▓▓ /////////▓▓▓///////▓▓▓///////// ▓▓ ▓▓ \n ▓▓ ,////////////////////////////////////// ▓▓ ▓▓ \n ▓▓ ////////////////////////////////////////// ▓▓ \n ▓▓ //////////////////////▓▓▓▓///////////////////// \n ,//////////////////////////////////////////////////// \n .////////////////////////////////////////////////////////// \n .//////////////////////////██.,//////////////////////////█ \n .//////////////////////████..,./////////////////////██ \n ...////////////////███████.....,.////////////////███ \n ,.,////////////████████ ........,///////////████ \n .,.,//////█████████ ,.......///////████ \n ,..//████████ ........./████ \n ..,██████ .....,███ \n .██ ,.,█ \n \n \n \n ▓▓ ▓▓▓▓▓▓▓▓▓▓ ▓▓▓▓▓▓▓▓▓▓ ▓▓ ▓▓▓▓▓▓▓▓▓▓ \n ▓▓▓▓▓▓ ▓▓▓ ▓▓▓ ▓▓▓ ▓▓ ▓▓ ▓▓▓▓ \n ▓▓▓ ▓▓▓ ▓▓▓ ▓▓▓ ▓▓▓ ▓▓▓ ▓▓ ▓▓▓▓▓ \n ▓▓▓ ▓▓ ▓▓▓ ▓▓▓ ▓▓▓▓▓▓▓▓▓▓ ▓▓▓▓▓▓▓▓▓▓ ▓▓▓▓▓▓▓▓▓▓ \n*/\n\nimport \"@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol\";\nimport \"../interfaces/IVaultManager.sol\";\n\npragma solidity ^0.8.12;\n\n/// @title AngleBorrowHelpers\n/// @author Angle Labs, Inc.\n/// @notice Contract with view functions designed to facilitate integrations on the Borrow module of the Angle Protocol\n/// @dev This contract only contains view functions to be queried off-chain. It was thus not optimized for gas consumption\ncontract AngleBorrowHelpers is Initializable {\n /// @notice Returns all the vaults owned or controlled (under the form of approval) by an address\n /// @param vaultManager VaultManager address to query vaultIDs on\n /// @param spender Address for which vault ownerships should be checked\n /// @return List of `vaultID` controlled by this address\n /// @return Count of vaults owned by the address\n /// @dev This function is never to be called on-chain since it iterates over all vaultIDs. It is here\n /// to reduce dependency on an external graph to link an ID to its owner\n function getControlledVaults(\n IVaultManager vaultManager,\n address spender\n ) external view returns (uint256[] memory, uint256) {\n uint256 arraySize = vaultManager.vaultIDCount();\n uint256[] memory vaultsControlled = new uint256[](arraySize);\n uint256 count;\n for (uint256 i = 1; i <= arraySize; ++i) {\n try vaultManager.isApprovedOrOwner(spender, i) returns (bool _isApprovedOrOwner) {\n if (_isApprovedOrOwner) {\n vaultsControlled[count] = i;\n count += 1;\n }\n } catch {\n continue;\n } // This happens if nobody owns the vaultID=i (if there has been a burn)\n }\n return (vaultsControlled, count);\n }\n\n /// @custom:oz-upgrades-unsafe-allow constructor\n constructor() initializer {}\n}\n" + }, + "contracts/ui-helpers/AngleHelpers.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\nimport \"../interfaces/IAngleRouter.sol\";\nimport \"../interfaces/coreModule/IAgTokenMainnet.sol\";\nimport \"../interfaces/coreModule/ICore.sol\";\nimport \"../interfaces/coreModule/IOracleCore.sol\";\nimport \"../interfaces/coreModule/IPerpetualManager.sol\";\nimport \"../interfaces/coreModule/IPoolManager.sol\";\nimport \"../interfaces/coreModule/IStableMaster.sol\";\nimport \"./AngleBorrowHelpers.sol\";\n\npragma solidity ^0.8.12;\n\nstruct Parameters {\n SLPData slpData;\n MintBurnData feeData;\n PerpetualManagerFeeData perpFeeData;\n PerpetualManagerParamData perpParam;\n}\n\nstruct PerpetualManagerFeeData {\n uint64[] xHAFeesDeposit;\n uint64[] yHAFeesDeposit;\n uint64[] xHAFeesWithdraw;\n uint64[] yHAFeesWithdraw;\n uint64 haBonusMalusDeposit;\n uint64 haBonusMalusWithdraw;\n}\n\nstruct PerpetualManagerParamData {\n uint64 maintenanceMargin;\n uint64 maxLeverage;\n uint64 targetHAHedge;\n uint64 limitHAHedge;\n uint64 lockTime;\n}\n\nstruct CollateralAddresses {\n address stableMaster;\n address poolManager;\n address perpetualManager;\n address sanToken;\n address oracle;\n address gauge;\n address feeManager;\n address[] strategies;\n}\n\n/// @title AngleHelpers\n/// @author Angle Labs, Inc.\n/// @notice Contract with view functions designed to facilitate integrations on the Core and Borrow module of the Angle Protocol\n/// @dev This contract only contains view functions to be queried off-chain. It was thus not optimized for gas consumption\ncontract AngleHelpers is AngleBorrowHelpers {\n // =========================== HELPER VIEW FUNCTIONS ===========================\n\n /// @notice Gives the amount of `agToken` you'd be getting if you were executing in the same block a mint transaction\n /// with `amount` of `collateral` in the Core module of the Angle protocol as well as the value of the fees\n /// (in `BASE_PARAMS`) that would be applied during the mint\n /// @return Amount of `agToken` that would be obtained with a mint transaction in the same block\n /// @return Percentage of fees that would be taken during a mint transaction in the same block\n /// @dev This function reverts if the mint transaction was to revert in the same conditions (without taking into account\n /// potential approval problems to the `StableMaster` contract)\n function previewMintAndFees(\n uint256 amount,\n address agToken,\n address collateral\n ) external view returns (uint256, uint256) {\n return _previewMintAndFees(amount, agToken, collateral);\n }\n\n /// @notice Gives the amount of `collateral` you'd be getting if you were executing in the same block a burn transaction\n /// with `amount` of `agToken` in the Core module of the Angle protocol as well as the value of the fees\n /// (in `BASE_PARAMS`) that would be applied during the burn\n /// @return Amount of `collateral` that would be obtained with a burn transaction in the same block\n /// @return Percentage of fees that would be taken during a burn transaction in the same block\n /// @dev This function reverts if the burn transaction was to revert in the same conditions (without taking into account\n /// potential approval problems to the `StableMaster` contract or agToken balance prior to the call)\n function previewBurnAndFees(\n uint256 amount,\n address agToken,\n address collateral\n ) external view returns (uint256, uint256) {\n return _previewBurnAndFees(amount, agToken, collateral);\n }\n\n /// @notice Returns all the addresses associated to the (`agToken`,`collateral`) pair given\n /// @return addresses A struct with all the addresses associated in the Core module\n function getCollateralAddresses(\n address agToken,\n address collateral\n ) external view returns (CollateralAddresses memory addresses) {\n address stableMaster = IAgTokenMainnet(agToken).stableMaster();\n (address poolManager, address perpetualManager, address sanToken, address gauge) = ROUTER.mapPoolManagers(\n stableMaster,\n collateral\n );\n (, , , IOracleCore oracle, , , , , ) = IStableMaster(stableMaster).collateralMap(poolManager);\n addresses.stableMaster = stableMaster;\n addresses.poolManager = poolManager;\n addresses.perpetualManager = perpetualManager;\n addresses.sanToken = sanToken;\n addresses.gauge = gauge;\n addresses.oracle = address(oracle);\n addresses.feeManager = IPoolManager(poolManager).feeManager();\n\n uint256 length;\n while (true) {\n try IPoolManager(poolManager).strategyList(length) returns (address) {\n length += 1;\n } catch {\n break;\n }\n }\n address[] memory strategies = new address[](length);\n for (uint256 i; i < length; ++i) {\n strategies[i] = IPoolManager(poolManager).strategyList(i);\n }\n addresses.strategies = strategies;\n }\n\n /// @notice Gets the addresses of all the `StableMaster` contracts and their associated `AgToken` addresses\n /// @return List of the `StableMaster` addresses of the Angle protocol\n /// @return List of the `AgToken` addresses of the protocol\n /// @dev The place of an agToken address in the list is the same as the corresponding `StableMaster` address\n function getStablecoinAddresses() external view returns (address[] memory, address[] memory) {\n address[] memory stableMasterAddresses = CORE.stablecoinList();\n address[] memory agTokenAddresses = new address[](stableMasterAddresses.length);\n for (uint256 i; i < stableMasterAddresses.length; ++i) {\n agTokenAddresses[i] = IStableMaster(stableMasterAddresses[i]).agToken();\n }\n return (stableMasterAddresses, agTokenAddresses);\n }\n\n /// @notice Returns most of the governance parameters associated to the (`agToken`,`collateral`) pair given\n /// @return params Struct with most of the parameters in the `StableMaster` and `PerpetualManager` contracts\n /// @dev Check out the struct `Parameters` for the meaning of the return values\n function getCollateralParameters(\n address agToken,\n address collateral\n ) external view returns (Parameters memory params) {\n (address stableMaster, address poolManager) = _getStableMasterAndPoolManager(agToken, collateral);\n (\n ,\n ,\n IPerpetualManager perpetualManager,\n ,\n ,\n ,\n ,\n SLPData memory slpData,\n MintBurnData memory feeData\n ) = IStableMaster(stableMaster).collateralMap(poolManager);\n\n params.slpData = slpData;\n params.feeData = feeData;\n params.perpParam.maintenanceMargin = perpetualManager.maintenanceMargin();\n params.perpParam.maxLeverage = perpetualManager.maxLeverage();\n params.perpParam.targetHAHedge = perpetualManager.targetHAHedge();\n params.perpParam.limitHAHedge = perpetualManager.limitHAHedge();\n params.perpParam.lockTime = perpetualManager.lockTime();\n\n params.perpFeeData.haBonusMalusDeposit = perpetualManager.haBonusMalusDeposit();\n params.perpFeeData.haBonusMalusWithdraw = perpetualManager.haBonusMalusWithdraw();\n\n uint256 length;\n while (true) {\n try perpetualManager.xHAFeesDeposit(length) returns (uint64) {\n length += 1;\n } catch {\n break;\n }\n }\n uint64[] memory data = new uint64[](length);\n uint64[] memory data2 = new uint64[](length);\n for (uint256 i; i < length; ++i) {\n data[i] = perpetualManager.xHAFeesDeposit(i);\n data2[i] = perpetualManager.yHAFeesDeposit(i);\n }\n params.perpFeeData.xHAFeesDeposit = data;\n params.perpFeeData.yHAFeesDeposit = data2;\n\n length = 0;\n while (true) {\n try perpetualManager.xHAFeesWithdraw(length) returns (uint64) {\n length += 1;\n } catch {\n break;\n }\n }\n data = new uint64[](length);\n data2 = new uint64[](length);\n for (uint256 i; i < length; ++i) {\n data[i] = perpetualManager.xHAFeesWithdraw(i);\n data2[i] = perpetualManager.yHAFeesWithdraw(i);\n }\n params.perpFeeData.xHAFeesWithdraw = data;\n params.perpFeeData.yHAFeesWithdraw = data2;\n }\n\n /// @notice Returns the address of the poolManager associated to an (`agToken`, `collateral`) pair\n /// in the Core module of the protocol\n function getPoolManager(address agToken, address collateral) public view returns (address poolManager) {\n (, poolManager) = _getStableMasterAndPoolManager(agToken, collateral);\n }\n\n // ============================= REPLICA FUNCTIONS =============================\n // These replicate what is done in the other contracts of the protocol\n\n function _previewBurnAndFees(\n uint256 amount,\n address agToken,\n address collateral\n ) internal view returns (uint256 amountForUserInCollat, uint256 feePercent) {\n (address stableMaster, address poolManager) = _getStableMasterAndPoolManager(agToken, collateral);\n (\n address token,\n ,\n IPerpetualManager perpetualManager,\n IOracleCore oracle,\n uint256 stocksUsers,\n ,\n uint256 collatBase,\n ,\n MintBurnData memory feeData\n ) = IStableMaster(stableMaster).collateralMap(poolManager);\n if (token == address(0) || IStableMaster(stableMaster).paused(keccak256(abi.encodePacked(STABLE, poolManager))))\n revert NotInitialized();\n if (amount > stocksUsers) revert InvalidAmount();\n\n if (feeData.xFeeBurn.length == 1) {\n feePercent = feeData.yFeeBurn[0];\n } else {\n bytes memory data = abi.encode(address(perpetualManager), feeData.targetHAHedge);\n uint64 hedgeRatio = _computeHedgeRatio(stocksUsers - amount, data);\n feePercent = _piecewiseLinear(hedgeRatio, feeData.xFeeBurn, feeData.yFeeBurn);\n }\n feePercent = (feePercent * feeData.bonusMalusBurn) / BASE_PARAMS;\n\n amountForUserInCollat = (amount * (BASE_PARAMS - feePercent) * collatBase) / (oracle.readUpper() * BASE_PARAMS);\n }\n\n function _previewMintAndFees(\n uint256 amount,\n address agToken,\n address collateral\n ) internal view returns (uint256 amountForUserInStable, uint256 feePercent) {\n (address stableMaster, address poolManager) = _getStableMasterAndPoolManager(agToken, collateral);\n (\n address token,\n ,\n IPerpetualManager perpetualManager,\n IOracleCore oracle,\n uint256 stocksUsers,\n ,\n ,\n ,\n MintBurnData memory feeData\n ) = IStableMaster(stableMaster).collateralMap(poolManager);\n if (token == address(0) || IStableMaster(stableMaster).paused(keccak256(abi.encodePacked(STABLE, poolManager))))\n revert NotInitialized();\n\n amountForUserInStable = oracle.readQuoteLower(amount);\n\n if (feeData.xFeeMint.length == 1) feePercent = feeData.yFeeMint[0];\n else {\n bytes memory data = abi.encode(address(perpetualManager), feeData.targetHAHedge);\n uint64 hedgeRatio = _computeHedgeRatio(amountForUserInStable + stocksUsers, data);\n feePercent = _piecewiseLinear(hedgeRatio, feeData.xFeeMint, feeData.yFeeMint);\n }\n feePercent = (feePercent * feeData.bonusMalusMint) / BASE_PARAMS;\n\n amountForUserInStable = (amountForUserInStable * (BASE_PARAMS - feePercent)) / BASE_PARAMS;\n if (stocksUsers + amountForUserInStable > feeData.capOnStableMinted) revert InvalidAmount();\n }\n\n // ============================= UTILITY FUNCTIONS =============================\n // These utility functions are taken from other contracts of the protocol\n\n function _computeHedgeRatio(uint256 newStocksUsers, bytes memory data) internal view returns (uint64 ratio) {\n (address perpetualManager, uint64 targetHAHedge) = abi.decode(data, (address, uint64));\n uint256 totalHedgeAmount = IPerpetualManager(perpetualManager).totalHedgeAmount();\n newStocksUsers = (targetHAHedge * newStocksUsers) / BASE_PARAMS;\n if (newStocksUsers > totalHedgeAmount) ratio = uint64((totalHedgeAmount * BASE_PARAMS) / newStocksUsers);\n else ratio = uint64(BASE_PARAMS);\n }\n\n function _piecewiseLinear(uint64 x, uint64[] memory xArray, uint64[] memory yArray) internal pure returns (uint64) {\n if (x >= xArray[xArray.length - 1]) {\n return yArray[xArray.length - 1];\n } else if (x <= xArray[0]) {\n return yArray[0];\n } else {\n uint256 lower;\n uint256 upper = xArray.length - 1;\n uint256 mid;\n while (upper - lower > 1) {\n mid = lower + (upper - lower) / 2;\n if (xArray[mid] <= x) {\n lower = mid;\n } else {\n upper = mid;\n }\n }\n if (yArray[upper] > yArray[lower]) {\n return\n yArray[lower] +\n ((yArray[upper] - yArray[lower]) * (x - xArray[lower])) /\n (xArray[upper] - xArray[lower]);\n } else {\n return\n yArray[lower] -\n ((yArray[lower] - yArray[upper]) * (x - xArray[lower])) /\n (xArray[upper] - xArray[lower]);\n }\n }\n }\n\n function _getStableMasterAndPoolManager(\n address agToken,\n address collateral\n ) internal view returns (address stableMaster, address poolManager) {\n stableMaster = IAgTokenMainnet(agToken).stableMaster();\n (poolManager, , , ) = ROUTER.mapPoolManagers(stableMaster, collateral);\n }\n\n // ========================= CONSTANTS AND INITIALIZERS ========================\n\n IAngleRouter public constant ROUTER = IAngleRouter(0xBB755240596530be0c1DE5DFD77ec6398471561d);\n ICore public constant CORE = ICore(0x61ed74de9Ca5796cF2F8fD60D54160D47E30B7c3);\n\n bytes32 public constant STABLE = keccak256(\"STABLE\");\n uint256 public constant BASE_PARAMS = 10 ** 9;\n\n error NotInitialized();\n error InvalidAmount();\n}\n" + }, + "contracts/utils/Constants.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\nerror InsufficientAssets();\n\n/// @title Constants\n/// @author Angle Labs, Inc.\n/// @notice Constants and errors for Angle Protocol contracts\ncontract Constants {\n uint256 internal constant _BASE_9 = 1e9;\n uint256 internal constant _BASE_18 = 1e18;\n uint256 internal constant _BASE_27 = 1e27;\n uint256 internal constant _BASE_36 = 1e36;\n}\n" + }, + "contracts/vaultManager/VaultManagerERC721.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\nimport \"./VaultManagerStorage.sol\";\n\n/// @title VaultManagerERC721\n/// @author Angle Labs, Inc.\n/// @dev Base ERC721 Implementation of VaultManager\nabstract contract VaultManagerERC721 is IERC721MetadataUpgradeable, VaultManagerStorage {\n using SafeERC20 for IERC20;\n using Address for address;\n\n /// @inheritdoc IERC721MetadataUpgradeable\n string public name;\n /// @inheritdoc IERC721MetadataUpgradeable\n string public symbol;\n\n // ================================= MODIFIERS =================================\n\n /// @notice Checks if the person interacting with the vault with `vaultID` is approved\n /// @param caller Address of the person seeking to interact with the vault\n /// @param vaultID ID of the concerned vault\n modifier onlyApprovedOrOwner(address caller, uint256 vaultID) {\n if (!_isApprovedOrOwner(caller, vaultID)) revert NotApproved();\n _;\n }\n\n // ================================ ERC721 LOGIC ===============================\n\n /// @notice Checks whether a given address is approved for a vault or owns this vault\n /// @param spender Address for which vault ownership should be checked\n /// @param vaultID ID of the vault to check\n /// @return Whether the `spender` address owns or is approved for `vaultID`\n function isApprovedOrOwner(address spender, uint256 vaultID) external view returns (bool) {\n return _isApprovedOrOwner(spender, vaultID);\n }\n\n /// @inheritdoc IERC721MetadataUpgradeable\n function tokenURI(uint256 vaultID) external view returns (string memory) {\n if (!_exists(vaultID)) revert NonexistentVault();\n // There is no vault with `vaultID` equal to 0, so the following variable is\n // always greater than zero\n uint256 temp = vaultID;\n uint256 digits;\n while (temp != 0) {\n ++digits;\n temp /= 10;\n }\n bytes memory buffer = new bytes(digits);\n while (vaultID != 0) {\n digits -= 1;\n buffer[digits] = bytes1(uint8(48 + uint256(vaultID % 10)));\n vaultID /= 10;\n }\n return bytes(_baseURI).length != 0 ? string(abi.encodePacked(_baseURI, string(buffer))) : \"\";\n }\n\n /// @inheritdoc IERC721Upgradeable\n function balanceOf(address owner) external view returns (uint256) {\n if (owner == address(0)) revert ZeroAddress();\n return _balances[owner];\n }\n\n /// @inheritdoc IERC721Upgradeable\n function ownerOf(uint256 vaultID) external view returns (address) {\n return _ownerOf(vaultID);\n }\n\n /// @inheritdoc IERC721Upgradeable\n function approve(address to, uint256 vaultID) external {\n address owner = _ownerOf(vaultID);\n if (to == owner) revert ApprovalToOwner();\n if (msg.sender != owner && !isApprovedForAll(owner, msg.sender)) revert NotApproved();\n\n _approve(to, vaultID);\n }\n\n /// @inheritdoc IERC721Upgradeable\n function getApproved(uint256 vaultID) external view returns (address) {\n if (!_exists(vaultID)) revert NonexistentVault();\n return _getApproved(vaultID);\n }\n\n /// @inheritdoc IERC721Upgradeable\n function setApprovalForAll(address operator, bool approved) external {\n _setApprovalForAll(msg.sender, operator, approved);\n }\n\n /// @inheritdoc IERC721Upgradeable\n function isApprovedForAll(address owner, address operator) public view returns (bool) {\n return _operatorApprovals[owner][operator] == 1;\n }\n\n /// @inheritdoc IERC721Upgradeable\n function transferFrom(address from, address to, uint256 vaultID) external onlyApprovedOrOwner(msg.sender, vaultID) {\n _transfer(from, to, vaultID);\n }\n\n /// @inheritdoc IERC721Upgradeable\n function safeTransferFrom(address from, address to, uint256 vaultID) external {\n safeTransferFrom(from, to, vaultID, \"\");\n }\n\n /// @inheritdoc IERC721Upgradeable\n function safeTransferFrom(\n address from,\n address to,\n uint256 vaultID,\n bytes memory _data\n ) public onlyApprovedOrOwner(msg.sender, vaultID) {\n _safeTransfer(from, to, vaultID, _data);\n }\n\n // ================================ ERC165 LOGIC ===============================\n\n /// @inheritdoc IERC165Upgradeable\n function supportsInterface(bytes4 interfaceId) external pure returns (bool) {\n return\n interfaceId == type(IERC721MetadataUpgradeable).interfaceId ||\n interfaceId == type(IERC721Upgradeable).interfaceId ||\n interfaceId == type(IVaultManager).interfaceId ||\n interfaceId == type(IERC165Upgradeable).interfaceId;\n }\n\n // ================== INTERNAL FUNCTIONS FOR THE ERC721 LOGIC ==================\n\n /// @notice Internal version of the `ownerOf` function\n function _ownerOf(uint256 vaultID) internal view returns (address owner) {\n owner = _owners[vaultID];\n if (owner == address(0)) revert NonexistentVault();\n }\n\n /// @notice Internal version of the `getApproved` function\n function _getApproved(uint256 vaultID) internal view returns (address) {\n return _vaultApprovals[vaultID];\n }\n\n /// @notice Internal version of the `safeTransferFrom` function (with the data parameter)\n function _safeTransfer(address from, address to, uint256 vaultID, bytes memory _data) internal {\n _transfer(from, to, vaultID);\n if (!_checkOnERC721Received(from, to, vaultID, _data)) revert NonERC721Receiver();\n }\n\n /// @notice Checks whether a vault exists\n /// @param vaultID ID of the vault to check\n /// @return Whether `vaultID` has been created\n function _exists(uint256 vaultID) internal view returns (bool) {\n return _owners[vaultID] != address(0);\n }\n\n /// @notice Internal version of the `isApprovedOrOwner` function\n function _isApprovedOrOwner(address spender, uint256 vaultID) internal view returns (bool) {\n // The following checks if the vault exists\n address owner = _ownerOf(vaultID);\n return (spender == owner || _getApproved(vaultID) == spender || _operatorApprovals[owner][spender] == 1);\n }\n\n /// @notice Internal version of the `createVault` function\n /// Mints `vaultID` and transfers it to `to`\n /// @dev This method is equivalent to the `_safeMint` method used in OpenZeppelin ERC721 contract\n /// @dev Emits a {Transfer} event\n function _mint(address to) internal returns (uint256 vaultID) {\n if (to == address(0)) revert ZeroAddress();\n\n unchecked {\n vaultIDCount += 1;\n }\n\n vaultID = vaultIDCount;\n _beforeTokenTransfer(address(0), to, vaultID);\n\n unchecked {\n _balances[to] += 1;\n }\n\n _owners[vaultID] = to;\n emit Transfer(address(0), to, vaultID);\n if (!_checkOnERC721Received(address(0), to, vaultID, \"\")) revert NonERC721Receiver();\n }\n\n /// @notice Destroys `vaultID`\n /// @dev `vaultID` must exist\n /// @dev Emits a {Transfer} event\n function _burn(uint256 vaultID) internal {\n address owner = _ownerOf(vaultID);\n\n _beforeTokenTransfer(owner, address(0), vaultID);\n // Clear approvals\n _approve(address(0), vaultID);\n // The following line cannot underflow as the owner's balance is necessarily\n // greater than 1\n unchecked {\n _balances[owner] -= 1;\n }\n delete _owners[vaultID];\n delete vaultData[vaultID];\n\n emit Transfer(owner, address(0), vaultID);\n }\n\n /// @notice Transfers `vaultID` from `from` to `to` as opposed to {transferFrom},\n /// this imposes no restrictions on msg.sender\n /// @dev `to` cannot be the zero address and `perpetualID` must be owned by `from`\n /// @dev Emits a {Transfer} event\n function _transfer(address from, address to, uint256 vaultID) internal {\n if (_ownerOf(vaultID) != from) revert NotApproved();\n if (to == address(0)) revert ZeroAddress();\n\n _beforeTokenTransfer(from, to, vaultID);\n\n // Clear approvals from the previous owner\n _approve(address(0), vaultID);\n unchecked {\n _balances[from] -= 1;\n _balances[to] += 1;\n }\n _owners[vaultID] = to;\n\n emit Transfer(from, to, vaultID);\n }\n\n /// @notice Approves `to` to operate on `vaultID`\n function _approve(address to, uint256 vaultID) internal {\n _vaultApprovals[vaultID] = to;\n emit Approval(_ownerOf(vaultID), to, vaultID);\n }\n\n /// @notice Internal version of the `setApprovalForAll` function\n /// @dev It contains an `approver` field to be used in case someone signs a permit for a particular\n /// address, and this signature is given to the contract by another address (like a router)\n function _setApprovalForAll(address approver, address operator, bool approved) internal {\n if (operator == approver) revert ApprovalToCaller();\n uint256 approval = approved ? 1 : 0;\n _operatorApprovals[approver][operator] = approval;\n emit ApprovalForAll(approver, operator, approved);\n }\n\n /// @notice Internal function to invoke {IERC721Receiver-onERC721Received} on a target address\n /// The call is not executed if the target address is not a contract\n /// @param from Address representing the previous owner of the given token ID\n /// @param to Target address that will receive the tokens\n /// @param vaultID ID of the token to be transferred\n /// @param _data Bytes optional data to send along with the call\n /// @return Bool whether the call correctly returned the expected value\n function _checkOnERC721Received(\n address from,\n address to,\n uint256 vaultID,\n bytes memory _data\n ) private returns (bool) {\n if (to.isContract()) {\n try IERC721ReceiverUpgradeable(to).onERC721Received(msg.sender, from, vaultID, _data) returns (\n bytes4 retval\n ) {\n return retval == IERC721ReceiverUpgradeable.onERC721Received.selector;\n } catch (bytes memory reason) {\n if (reason.length == 0) {\n revert NonERC721Receiver();\n } else {\n // solhint-disable-next-line no-inline-assembly\n assembly {\n revert(add(32, reason), mload(reason))\n }\n }\n }\n } else {\n return true;\n }\n }\n\n /// @notice Hook that is called before any token transfer. This includes minting and burning.\n /// Calling conditions:\n ///\n /// - When `from` and `to` are both non-zero, `from`'s `vaultID` will be\n /// transferred to `to`.\n /// - When `from` is zero, `vaultID` will be minted for `to`.\n /// - When `to` is zero, `from`'s `vaultID` will be burned.\n /// - `from` and `to` are never both zero.\n function _beforeTokenTransfer(address from, address to, uint256 vaultID) internal virtual {}\n\n /// @notice Get `whitelistingActivated` in storage only if needed\n function _whitelistingActivated() internal view virtual returns (bool) {\n return whitelistingActivated;\n }\n}\n" + }, + "contracts/vaultManager/VaultManagerPermit.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\nimport \"./VaultManagerERC721.sol\";\nimport \"../interfaces/external/IERC1271.sol\";\n\n/// @title VaultManagerPermit\n/// @author Angle Labs, Inc.\n/// @dev Base Implementation of permit functions for the `VaultManager` contract\nabstract contract VaultManagerPermit is Initializable, VaultManagerERC721 {\n using Address for address;\n\n mapping(address => uint256) private _nonces;\n /* solhint-disable var-name-mixedcase */\n bytes32 private _HASHED_NAME;\n bytes32 private _HASHED_VERSION;\n bytes32 private _PERMIT_TYPEHASH;\n /* solhint-enable var-name-mixedcase */\n\n error ExpiredDeadline();\n error InvalidSignature();\n\n //solhint-disable-next-line\n function __ERC721Permit_init(string memory _name) internal onlyInitializing {\n _PERMIT_TYPEHASH = keccak256(\n \"Permit(address owner,address spender,bool approved,uint256 nonce,uint256 deadline)\"\n );\n _HASHED_NAME = keccak256(bytes(_name));\n _HASHED_VERSION = keccak256(bytes(\"1\"));\n }\n\n /// @notice Allows an address to give or revoke approval for all its vaults to another address\n /// @param owner Address signing the permit and giving (or revoking) its approval for all the controlled vaults\n /// @param spender Address to give approval to\n /// @param approved Whether to give or revoke the approval\n /// @param deadline Deadline parameter for the signature to be valid\n /// @dev The `v`, `r`, and `s` parameters are used as signature data\n function permit(\n address owner,\n address spender,\n bool approved,\n uint256 deadline,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) external {\n if (block.timestamp > deadline) revert ExpiredDeadline();\n // Additional signature checks performed in the `ECDSAUpgradeable.recover` function\n if (uint256(s) > 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D576E7357A4501DDFE92F46681B20A0 || (v != 27 && v != 28))\n revert InvalidSignature();\n\n bytes32 digest = keccak256(\n abi.encodePacked(\n \"\\x19\\x01\",\n _domainSeparatorV4(),\n keccak256(\n abi.encode(\n _PERMIT_TYPEHASH,\n // 0x3f43a9c6bafb5c7aab4e0cfe239dc5d4c15caf0381c6104188191f78a6640bd8,\n owner,\n spender,\n approved,\n _useNonce(owner),\n deadline\n )\n )\n )\n );\n if (owner.isContract()) {\n if (IERC1271(owner).isValidSignature(digest, abi.encodePacked(r, s, v)) != 0x1626ba7e)\n revert InvalidSignature();\n } else {\n address signer = ecrecover(digest, v, r, s);\n if (signer != owner || signer == address(0)) revert InvalidSignature();\n }\n\n _setApprovalForAll(owner, spender, approved);\n }\n\n /// @notice Returns the current nonce for an `owner` address\n function nonces(address owner) public view returns (uint256) {\n return _nonces[owner];\n }\n\n /// @notice Returns the domain separator for the current chain.\n // solhint-disable-next-line func-name-mixedcase\n function DOMAIN_SEPARATOR() external view returns (bytes32) {\n return _domainSeparatorV4();\n }\n\n /// @notice Internal version of the `DOMAIN_SEPARATOR` function\n function _domainSeparatorV4() internal view returns (bytes32) {\n return\n keccak256(\n abi.encode(\n // keccak256('EIP712Domain(string name,string version,uint256 chainId,address verifyingContract)')\n 0x8b73c3c69bb8fe3d512ecc4cf759cc79239f7b179b0ffacaa9a75d522b39400f,\n _HASHED_NAME,\n _HASHED_VERSION,\n block.chainid,\n address(this)\n )\n );\n }\n\n /// @notice Consumes a nonce for an address: returns the current value and increments it\n function _useNonce(address owner) internal returns (uint256 current) {\n current = _nonces[owner];\n _nonces[owner] = current + 1;\n }\n\n uint256[49] private __gap;\n}\n" + }, + "contracts/vaultManager/VaultManagerStorage.sol": { + "content": "// SPDX-License-Identifier: GPL-3.0\n\npragma solidity ^0.8.12;\n\nimport \"@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/token/ERC20/extensions/draft-IERC20PermitUpgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/token/ERC721/IERC721ReceiverUpgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/interfaces/IERC721MetadataUpgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/utils/introspection/IERC165Upgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/utils/AddressUpgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/security/ReentrancyGuardUpgradeable.sol\";\nimport \"@openzeppelin/contracts/token/ERC20/extensions/IERC20Metadata.sol\";\nimport \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\nimport \"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\";\n\nimport \"../interfaces/IAgToken.sol\";\nimport \"../interfaces/IOracle.sol\";\nimport \"../interfaces/ISwapper.sol\";\nimport \"../interfaces/ITreasury.sol\";\nimport \"../interfaces/IVaultManager.sol\";\nimport \"../interfaces/governance/IVeBoostProxy.sol\";\n\n/// @title VaultManagerStorage\n/// @author Angle Labs, Inc.\n/// @dev Variables, references, parameters and events needed in the `VaultManager` contract\n// solhint-disable-next-line max-states-count\ncontract VaultManagerStorage is IVaultManagerStorage, Initializable, ReentrancyGuardUpgradeable {\n /// @notice Base used for parameter computation: almost all the parameters of this contract are set in `BASE_PARAMS`\n uint256 public constant BASE_PARAMS = 10 ** 9;\n /// @notice Base used for interest rate computation\n uint256 public constant BASE_INTEREST = 10 ** 27;\n /// @notice Used for interest rate computation\n uint256 public constant HALF_BASE_INTEREST = 10 ** 27 / 2;\n\n // ================================= REFERENCES ================================\n\n /// @inheritdoc IVaultManagerStorage\n ITreasury public treasury;\n /// @inheritdoc IVaultManagerStorage\n IERC20 public collateral;\n /// @inheritdoc IVaultManagerStorage\n IAgToken public stablecoin;\n /// @inheritdoc IVaultManagerStorage\n IOracle public oracle;\n /// @notice Reference to the contract which computes adjusted veANGLE balances for liquidators boosts\n IVeBoostProxy public veBoostProxy;\n /// @notice Base of the collateral\n uint256 internal _collatBase;\n\n // ================================= PARAMETERS ================================\n // Unless specified otherwise, parameters of this contract are expressed in `BASE_PARAMS`\n\n /// @notice Maximum amount of stablecoins that can be issued with this contract (in `BASE_TOKENS`). This parameter should\n /// not be bigger than `type(uint256).max / BASE_INTEREST` otherwise there may be some overflows in the `increaseDebt` function\n uint256 public debtCeiling;\n /// @notice Threshold veANGLE balance values for the computation of the boost for liquidators: the length of this array\n /// should normally be 2. The base of the x-values in this array should be `BASE_TOKENS`\n uint256[] public xLiquidationBoost;\n /// @notice Values of the liquidation boost at the threshold values of x\n uint256[] public yLiquidationBoost;\n /// @inheritdoc IVaultManagerStorage\n uint64 public collateralFactor;\n /// @notice Maximum Health factor at which a vault can end up after a liquidation (unless it's fully liquidated)\n uint64 public targetHealthFactor;\n /// @notice Upfront fee taken when borrowing stablecoins: this fee is optional and should in practice not be used\n uint64 public borrowFee;\n /// @notice Upfront fee taken when repaying stablecoins: this fee is optional as well. It should be smaller\n /// than the liquidation surcharge (cf below) to avoid exploits where people voluntarily get liquidated at a 0\n /// discount to pay smaller repaying fees\n uint64 public repayFee;\n /// @notice Per second interest taken to borrowers taking agToken loans. Contrarily to other parameters, it is set in `BASE_INTEREST`\n /// that is to say in base 10**27\n uint64 public interestRate;\n /// @notice Fee taken by the protocol during a liquidation. Technically, this value is not the fee per se, it's 1 - fee.\n /// For instance for a 2% fee, `liquidationSurcharge` should be 98%\n uint64 public liquidationSurcharge;\n /// @notice Maximum discount given to liquidators\n uint64 public maxLiquidationDiscount;\n /// @notice Whether whitelisting is required to own a vault or not\n bool public whitelistingActivated;\n /// @notice Whether the contract is paused or not\n bool public paused;\n\n // ================================= VARIABLES =================================\n\n /// @notice Timestamp at which the `interestAccumulator` was updated\n uint256 public lastInterestAccumulatorUpdated;\n /// @inheritdoc IVaultManagerStorage\n uint256 public interestAccumulator;\n /// @inheritdoc IVaultManagerStorage\n uint256 public totalNormalizedDebt;\n /// @notice Surplus accumulated by the contract: surplus is always in stablecoins, and is then reset\n /// when the value is communicated to the treasury contract\n uint256 public surplus;\n /// @notice Bad debt made from liquidated vaults which ended up having no collateral and a positive amount\n /// of stablecoins\n uint256 public badDebt;\n\n // ================================== MAPPINGS =================================\n\n /// @inheritdoc IVaultManagerStorage\n mapping(uint256 => Vault) public vaultData;\n /// @notice Maps an address to 1 if it's whitelisted and can open or own a vault\n mapping(address => uint256) public isWhitelisted;\n\n // ================================ ERC721 DATA ================================\n\n /// @inheritdoc IVaultManagerStorage\n uint256 public vaultIDCount;\n\n /// @notice URI\n string internal _baseURI;\n\n // Mapping from `vaultID` to owner address\n mapping(uint256 => address) internal _owners;\n\n // Mapping from owner address to vault owned count\n mapping(address => uint256) internal _balances;\n\n // Mapping from `vaultID` to approved address\n mapping(uint256 => address) internal _vaultApprovals;\n\n // Mapping from owner to operator approvals\n mapping(address => mapping(address => uint256)) internal _operatorApprovals;\n\n uint256[50] private __gap;\n\n // =================================== EVENTS ==================================\n\n event AccruedToTreasury(uint256 surplusEndValue, uint256 badDebtEndValue);\n event CollateralAmountUpdated(uint256 vaultID, uint256 collateralAmount, uint8 isIncrease);\n event InterestAccumulatorUpdated(uint256 value, uint256 timestamp);\n event InternalDebtUpdated(uint256 vaultID, uint256 internalAmount, uint8 isIncrease);\n event FiledUint64(uint64 param, bytes32 what);\n event DebtCeilingUpdated(uint256 debtCeiling);\n event LiquidationBoostParametersUpdated(address indexed _veBoostProxy, uint256[] xBoost, uint256[] yBoost);\n event LiquidatedVaults(uint256[] vaultIDs);\n event DebtTransferred(uint256 srcVaultID, uint256 dstVaultID, address dstVaultManager, uint256 amount);\n\n // =================================== ERRORS ==================================\n\n error ApprovalToOwner();\n error ApprovalToCaller();\n error DustyLeftoverAmount();\n error DebtCeilingExceeded();\n error HealthyVault();\n error IncompatibleLengths();\n error InsolventVault();\n error InvalidParameterValue();\n error InvalidParameterType();\n error InvalidSetOfParameters();\n error InvalidTreasury();\n error NonERC721Receiver();\n error NonexistentVault();\n error NotApproved();\n error NotGovernor();\n error NotGovernorOrGuardian();\n error NotTreasury();\n error NotWhitelisted();\n error NotVaultManager();\n error Paused();\n error TooHighParameterValue();\n error TooSmallParameterValue();\n error ZeroAddress();\n\n /// @custom:oz-upgrades-unsafe-allow constructor\n constructor() initializer {}\n}\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 1000000 + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers", + "metadata", + "devdoc", + "userdoc", + "storageLayout", + "evm.gasEstimates", + "devdoc", + "userdoc" + ], + "": [ + "ast" + ] + } + }, + "metadata": { + "useLiteralContent": true + } + } +} \ No newline at end of file diff --git a/e2e/mainnet/agTokenUpgrade.test.ts b/e2e/mainnet/agTokenUpgrade.test.ts index 185f609f..e4b24dc1 100644 --- a/e2e/mainnet/agTokenUpgrade.test.ts +++ b/e2e/mainnet/agTokenUpgrade.test.ts @@ -9,18 +9,18 @@ import { expect } from '../../test/hardhat/utils/chai-setup'; import { inIndirectReceipt, inReceipt } from '../../test/hardhat/utils/expectEvent'; import { deployUpgradeable, ZERO_ADDRESS } from '../../test/hardhat/utils/helpers'; import { - AgToken, - AgToken__factory, CoreBorrow, CoreBorrow__factory, FlashAngle, FlashAngle__factory, + OldAgEUR, + OldAgEUR__factory, ProxyAdmin, Treasury, Treasury__factory, } from '../../typechain'; -contract('AgToken - End-to-end Upgrade', () => { +contract('OldAgEUR - End-to-end Upgrade', () => { let deployer: SignerWithAddress; let alice: SignerWithAddress; let bob: SignerWithAddress; @@ -28,7 +28,7 @@ contract('AgToken - End-to-end Upgrade', () => { let flashAngle: FlashAngle; let coreBorrow: CoreBorrow; - let agToken: AgToken; + let agToken: OldAgEUR; let treasury: Treasury; let governor: string; let guardian: string; @@ -63,15 +63,15 @@ contract('AgToken - End-to-end Upgrade', () => { before(async () => { proxyAdmin = new ethers.Contract(CONTRACTS_ADDRESSES[1].ProxyAdmin!, ProxyAdmin_Interface, deployer) as ProxyAdmin; - const implementation = await new AgToken__factory(deployer).deploy(); + const implementation = await new OldAgEUR__factory(deployer).deploy(); // eslint-disable-next-line - const agTokenAddress = CONTRACTS_ADDRESSES[1].agEUR?.AgToken!; + const agTokenAddress = CONTRACTS_ADDRESSES[1].agEUR?.OldAgEUR!; // eslint-disable-next-line stableMasterAddress = CONTRACTS_ADDRESSES[1].agEUR?.StableMaster!; await ( await proxyAdmin.connect(impersonatedSigners[governor]).upgrade(agTokenAddress, implementation.address) ).wait(); - agToken = new ethers.Contract(agTokenAddress, AgToken__factory.createInterface(), deployer) as AgToken; + agToken = new ethers.Contract(agTokenAddress, OldAgEUR__factory.createInterface(), deployer) as OldAgEUR; coreBorrow = (await deployUpgradeable(new CoreBorrow__factory(deployer))) as CoreBorrow; await coreBorrow.initialize(governor, guardian); flashAngle = (await deployUpgradeable(new FlashAngle__factory(deployer))) as FlashAngle; diff --git a/e2e/mainnet/oraclesChainlink.test.ts b/e2e/mainnet/oraclesChainlink.test.ts index 3aa220c5..0e939fc8 100644 --- a/e2e/mainnet/oraclesChainlink.test.ts +++ b/e2e/mainnet/oraclesChainlink.test.ts @@ -29,6 +29,8 @@ import { OracleUSDCXAUChainlink__factory, OracleWSTETHEURChainlink, OracleWSTETHEURChainlink__factory, + OracleWSTETHUSDChainlink, + OracleWSTETHUSDChainlink__factory, OracleWSTETHXAUChainlink, OracleWSTETHXAUChainlink__factory, } from '../../typechain'; @@ -50,6 +52,7 @@ contract('Oracles Chainlink', () => { let oracleIB01: OracleIB01EURChainlink; let oracleHIGH: OracleHIGHEURChainlink; let oracleUSDC: OracleUSDCEURChainlink; + let oracleWSTETHUSD: OracleWSTETHUSDChainlink; let stalePeriod: BigNumber; let treasury: MockTreasury; @@ -62,7 +65,7 @@ contract('Oracles Chainlink', () => { { forking: { jsonRpcUrl: process.env.ETH_NODE_URI_FORK, - blockNumber: 17465158, + blockNumber: 18940732, }, }, ], @@ -88,6 +91,7 @@ contract('Oracles Chainlink', () => { oracleIB01 = await new OracleIB01EURChainlink__factory(deployer).deploy(stalePeriod, treasury.address); oracleHIGH = await new OracleHIGHEURChainlink__factory(deployer).deploy(stalePeriod, treasury.address); oracleUSDC = await new OracleUSDCEURChainlink__factory(deployer).deploy(stalePeriod, treasury.address); + oracleWSTETHUSD = await new OracleWSTETHUSDChainlink__factory(deployer).deploy(stalePeriod, treasury.address); }); describe('Oracle wStETHEUR', () => { @@ -103,6 +107,19 @@ contract('Oracles Chainlink', () => { expect(await oracleWSTETH.treasury()).to.be.equal(treasury.address); }); }); + describe('Oracle wStETHUSD', () => { + it('read', async () => { + const receipt = await oracleWSTETHUSD.read(); + const gas = await oracleWSTETHUSD.estimateGas.read(); + console.log(gas.toString()); + console.log(receipt.toString()); + }); + it('initialization', async () => { + expect(await oracleWSTETHUSD.STETH()).to.be.equal('0xae7ab96520DE3A18E5e111B5EaAb095312D7fE84'); + expect(await oracleWSTETHUSD.stalePeriod()).to.be.equal(stalePeriod); + expect(await oracleWSTETHUSD.treasury()).to.be.equal(treasury.address); + }); + }); describe('Oracle ETHEUR', () => { it('read', async () => { const receipt = await oracleETH.read(); diff --git a/e2e/polygon/agTokenPolygonUpgrade.test.ts b/e2e/polygon/agTokenPolygonUpgrade.test.ts index 3fd70989..ac3d5ea9 100644 --- a/e2e/polygon/agTokenPolygonUpgrade.test.ts +++ b/e2e/polygon/agTokenPolygonUpgrade.test.ts @@ -1,4 +1,3 @@ -import { ProxyAdmin_Interface } from '@angleprotocol/sdk/dist/constants/interfaces'; import { SignerWithAddress } from '@nomiclabs/hardhat-ethers/signers'; import { Signer, utils } from 'ethers'; import { parseEther } from 'ethers/lib/utils'; @@ -16,6 +15,7 @@ import { MockToken, MockToken__factory, ProxyAdmin, + ProxyAdmin__factory, TokenPolygonUpgradeable, TokenPolygonUpgradeable__factory, Treasury, @@ -74,7 +74,7 @@ contract('TokenPolygonUpgradeable - End-to-end Upgrade', () => { before(async () => { proxyAdmin = new ethers.Contract( '0xbfca293e17e067e8abdca30a5d35addd0cbae6d6', - ProxyAdmin_Interface, + ProxyAdmin__factory.createInterface(), deployer, ) as ProxyAdmin; diff --git a/foundry.toml b/foundry.toml index a1165bc4..9207c5f8 100644 --- a/foundry.toml +++ b/foundry.toml @@ -1,29 +1,77 @@ [profile.default] src = 'contracts' out = 'out' -test = 'test/foundry' +test = 'test' libs = ['node_modules', 'lib'] -script = 'scripts/foundry' +script = 'scripts' cache_path = 'cache-forge' gas_reports = ["*"] +via_ir = false +sizes = true +optimizer = true optimizer_runs=1 - -# solc_version = '0.8.14' - +solc_version = '0.8.17' ffi = true +fs_permissions = [{ access = "read-write", path = "./scripts/vanity.json"}, { access = "read-write", path = "../../../deploy/vanity.json"}] +memory_limit = 1000043554432 [fuzz] -runs = 500 +runs = 10000 [invariant] -runs = 500 +runs = 1000 +depth = 30 [rpc_endpoints] +arbitrum = "${ETH_NODE_URI_ARBITRUM}" +gnosis = "${ETH_NODE_URI_GNOSIS}" mainnet = "${ETH_NODE_URI_MAINNET}" +optimism = "${ETH_NODE_URI_OPTIMISM}" polygon = "${ETH_NODE_URI_POLYGON}" -goerli = "${ETH_NODE_URI_GOERLI}" +fork = "${ETH_NODE_URI_FORK}" +avalanche = "${ETH_NODE_URI_AVALANCHE}" +celo = "${ETH_NODE_URI_CELO}" +polygon-zkevm = "${ETH_NODE_URI_POLYGONZKEVM}" +bsc = "${ETH_NODE_URI_BSC}" +base = "${ETH_NODE_URI_BASE}" +linea = "${ETH_NODE_URI_LINEA}" [etherscan] -mainnet = { key = "$MAINNET_ETHERSCAN_API_KEY}" } +arbitrum = { key = "${ARBITRUM_ETHERSCAN_API_KEY}" } +gnosis = { key = "${GNOSIS_ETHERSCAN_API_KEY}" , url = "https://api.gnosisscan.io/api"} +mainnet = { key = "${MAINNET_ETHERSCAN_API_KEY}" } +optimism = { key = "${OPTIMISM_ETHERSCAN_API_KEY}" } polygon = { key = "${POLYGON_ETHERSCAN_API_KEY}" } -goerli = { key = "${GOERLI_ETHERSCAN_API_KEY}" } \ No newline at end of file +avalanche = { key = "${AVALANCHE_ETHERSCAN_API_KEY}" } +celo = { key = "${CELO_ETHERSCAN_API_KEY}", url = "https://api.celoscan.io/api" } +base = { key = "${BASE_ETHERSCAN_API_KEY}", url = "https://api.basescan.org/api" } +polygon-zkevm = { key = "${POLYGONZKEVM_ETHERSCAN_API_KEY}", url = "https://api-zkevm.polygonscan.com/api" } +bsc = { key = "${BSC_ETHERSCAN_API_KEY}"} +linea = { key = "${LINEA_ETHERSCAN_API_KEY}"} + +[profile.dev] +optimizer = true +via_ir = false +src = 'contracts' +gas_reports = ["*"] + +[profile.dev.fuzz] +runs = 2000 + +[profile.dev.invariant] +runs = 10 +depth = 1 +fail_on_revert = false + +[profile.ci] +src = 'contracts' +via_ir = false +gas_reports = ["*"] + +[profile.ci.fuzz] +runs = 100 + +[profile.ci.invariant] +runs = 10 +depth = 30 +fail_on_revert = false diff --git a/hardhat.config.ts b/hardhat.config.ts index 2c72e165..72c4d5dc 100644 --- a/hardhat.config.ts +++ b/hardhat.config.ts @@ -26,14 +26,7 @@ import { accounts, etherscanKey, nodeUrl } from './utils/network'; // Otherwise, ".sol" files from "test" are picked up during compilation and throw an error subtask(TASK_COMPILE_SOLIDITY_GET_SOURCE_PATHS).setAction(async (_, __, runSuper) => { const paths = await runSuper(); - return paths.filter( - (p: string) => - !( - p.includes('/test/foundry/') || - p.includes('/MockVaultManagerLiquidationBoostImmutable.sol') || - p.includes('/VaultManagerLiquidationBoostImmutable.sol') - ), - ); + return paths.filter((p: string) => !p.includes('/test/foundry/')); }); const argv = yargs @@ -155,7 +148,8 @@ const config: HardhatUserConfig = { // Mainnet url: nodeUrl('mainnet'), - blockNumber: 17411982, + blockNumber: 18976806, + // Polygon /* url: nodeUrl('forkpolygon'), @@ -165,8 +159,8 @@ const config: HardhatUserConfig = { // Optimism /* url: nodeUrl('optimism'), - blockNumber: 17614765, - */ + blockNumber: 114397708, +*/ // Arbitrum /* url: nodeUrl('arbitrum'), @@ -190,26 +184,7 @@ const config: HardhatUserConfig = { interval: 1000, } : { auto: true }, - chainId: 1, - }, - rinkeby: { - live: true, - url: nodeUrl('rinkeby'), - accounts: accounts('rinkeby'), - gas: 'auto', - // gasPrice: 12e8, - chainId: 4, - }, - mainnetForkRemote: { - live: false, - url: nodeUrl('mainnetForkRemote'), - chainId: 1, - }, - mumbai: { - live: true, - url: nodeUrl('mumbai'), - accounts: accounts('mumbai'), - gas: 'auto', + chainId: 0, }, polygon: { live: true, @@ -223,13 +198,6 @@ const config: HardhatUserConfig = { }, }, }, - fantom: { - live: true, - url: nodeUrl('fantom'), - accounts: accounts('fantom'), - gas: 'auto', - chainId: 250, - }, mainnet: { live: true, url: nodeUrl('mainnet'), @@ -292,13 +260,6 @@ const config: HardhatUserConfig = { }, }, }, - aurora: { - live: true, - url: nodeUrl('aurora'), - accounts: accounts('aurora'), - gas: 'auto', - chainId: 1313161554, - }, celo: { live: true, url: nodeUrl('celo'), @@ -429,6 +390,20 @@ const config: HardhatUserConfig = { }, }, }, + fantom: { + live: true, + url: nodeUrl('fantom'), + accounts: accounts('fantom'), + gas: 'auto', + chainId: 250, + }, + aurora: { + live: true, + url: nodeUrl('aurora'), + accounts: accounts('aurora'), + gas: 'auto', + chainId: 1313161554, + }, }, paths: { sources: './contracts', diff --git a/lib/forge-std b/lib/forge-std index 5bafa16b..87a2a0af 160000 --- a/lib/forge-std +++ b/lib/forge-std @@ -1 +1 @@ -Subproject commit 5bafa16b4a6aa67c503d96294be846a22a6f6efb +Subproject commit 87a2a0afc5fafd6297538a45a52ac19e71a84562 diff --git a/lib/prb-math b/lib/prb-math new file mode 160000 index 00000000..57667c51 --- /dev/null +++ b/lib/prb-math @@ -0,0 +1 @@ +Subproject commit 57667c5113d800fdcf6fd13966dbd84c6b79de70 diff --git a/lib/solidity-stringutils b/lib/solidity-stringutils new file mode 160000 index 00000000..4b2fcc43 --- /dev/null +++ b/lib/solidity-stringutils @@ -0,0 +1 @@ +Subproject commit 4b2fcc43fa0426e19ce88b1f1ec16f5903a2e461 diff --git a/package.json b/package.json index f471ee45..349c0426 100644 --- a/package.json +++ b/package.json @@ -11,7 +11,7 @@ "check-upgradeability": "hardhat run scripts/upgradeability.ts", "coverage": "hardhat coverage", "coverage:foundry": "forge coverage --report lcov", - "deploy": "hardhat deploy --network gnosis --tags", + "deploy": "hardhat deploy --tags lzSetupNewStable --network ", "etherscan": "hardhat etherscan-verify --network", "foundry:deploy": "forge script --broadcast --verify -vvvv --rpc-url", "generate-types-from-abis": "typechain --target ethers-v5 --out-dir typechain './export/abi/*.json'", @@ -36,7 +36,9 @@ "test:all": "yarn test && yarn test:e2e:mainnet", "foundry:setup": "curl -L https://foundry.paradigm.xyz | bash && foundryup && git submodule update --init --recursive", "foundry:run": "docker run -it --rm -v $(pwd):/app -w /app ghcr.io/foundry-rs/foundry sh", - "foundry:test": "forge test -vvvv" + "foundry:test": "forge test -vvvv", + "vanity": "forge script --skip test --slow -vvvv --rpc-url mainnet ./scripts/foundry/utils/VanityAddress.s.sol", + "verify": "forge verify-contract --num-of-optimizations 1000000 --watch --constructor-args 0000000000000000000000000000000000ffe8b47b3e2130213b802212439497000000000000000000000000fda462548ce04282f4b6d6619823a7c64fdc018500000000000000000000000000000000000000000000000000000000000000600000000000000000000000000000000000000000000000000000000000000000 --compiler-version v0.8.17+commit.8df45f5f 0x0000206329b97DB379d5E1Bf586BbDB969C63274 node_modules/@openzeppelin/contracts/proxy/transparent/TransparentUpgradeableProxy.sol:TransparentUpgradeableProxy --chain" }, "repository": { "type": "git", @@ -50,7 +52,7 @@ }, "homepage": "https://github.com/AngleProtocol/angle-borrow#readme", "devDependencies": { - "@angleprotocol/sdk": "3.0.56", + "@angleprotocol/sdk": "0.21.1", "@chainlink/contracts": "0.2.1", "@nomiclabs/hardhat-ethers": "npm:hardhat-deploy-ethers", "@nomiclabs/hardhat-etherscan": "3.1.0", @@ -97,7 +99,7 @@ "ganache-cli": "6.12.1", "graphql": "15.5.1", "graphql-request": "3.4.0", - "hardhat": "2.19.0", + "hardhat": "2.19.4", "hardhat-abi-exporter": "2.2.1", "hardhat-contract-sizer": "2.0.3", "hardhat-deploy": "0.11.11", diff --git a/remappings.txt b/remappings.txt index c3b565ee..7e73f5f4 100644 --- a/remappings.txt +++ b/remappings.txt @@ -4,3 +4,5 @@ @uniswap/=node_modules/@uniswap/ ds-test/=lib/forge-std/lib/ds-test/src/ forge-std/=lib/forge-std/src/ +stringutils/=lib/solidity-stringutils +prb/math/=lib/prb-math/src/ \ No newline at end of file diff --git a/scripts/foundry/mainnet/MainnetConstants.s.sol b/scripts/foundry/mainnet/MainnetConstants.s.sol index 4fc74b98..8694d7a0 100644 --- a/scripts/foundry/mainnet/MainnetConstants.s.sol +++ b/scripts/foundry/mainnet/MainnetConstants.s.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: GPL-3.0 -pragma solidity ^0.8.17; +pragma solidity ^0.8.12; import "../../../contracts/external/ProxyAdmin.sol"; import "../../../contracts/external/TransparentUpgradeableProxy.sol"; diff --git a/scripts/foundry/mainnet/Treasury.s.sol b/scripts/foundry/mainnet/Treasury.s.sol deleted file mode 100644 index a645b8aa..00000000 --- a/scripts/foundry/mainnet/Treasury.s.sol +++ /dev/null @@ -1,33 +0,0 @@ -// SPDX-License-Identifier: GPL-3.0 -pragma solidity ^0.8.17; - -import "forge-std/Script.sol"; -import { console } from "forge-std/console.sol"; -import { ICoreBorrow } from "../../../contracts/coreBorrow/CoreBorrow.sol"; -import { TreasuryImmutable } from "../../../contracts/treasury/TreasuryImmutable.sol"; -import { IAgToken, AgTokenSideChainImmutable } from "../../../contracts/agToken/AgTokenSideChainImmutable.sol"; -import { VaultManagerLiquidationBoostImmutable, VaultParameters, VaultManagerStorage } from "../../../contracts/vaultManager/VaultManagerLiquidationBoostImmutable.sol"; -import "./MainnetConstants.s.sol"; - -contract DeployTreasury is Script, MainnetConstants { - string constant _NAME = "agGOLD"; - string constant _SYMBOL = "agGOLD"; - - function run() external { - uint256 deployerPrivateKey = vm.deriveKey(vm.envString("MNEMONIC_MAINNET"), 0); - vm.rememberKey(deployerPrivateKey); - - vm.startBroadcast(deployerPrivateKey); - - TreasuryImmutable treasury = new TreasuryImmutable(ICoreBorrow(CORE_BORROW)); - console.log("Successfully deployed agGOLD treasury at the address: ", address(treasury)); - - AgTokenSideChainImmutable agGOLD = new AgTokenSideChainImmutable(_NAME, _SYMBOL, address(treasury)); - console.log("Successfully deployed agGOLD at the address: ", address(agGOLD)); - - // TODO governance should call - // treasury.setStablecoin(agGOLD); - - vm.stopBroadcast(); - } -} diff --git a/scripts/foundry/mainnet/VaultManager.s.sol b/scripts/foundry/mainnet/VaultManager.s.sol index ac61d254..d85b78fc 100644 --- a/scripts/foundry/mainnet/VaultManager.s.sol +++ b/scripts/foundry/mainnet/VaultManager.s.sol @@ -1,13 +1,13 @@ // SPDX-License-Identifier: GPL-3.0 -pragma solidity ^0.8.17; +pragma solidity ^0.8.12; import "forge-std/Script.sol"; import { console } from "forge-std/console.sol"; import { IOracle } from "../../../contracts/interfaces/IOracle.sol"; import { OracleETHXAUChainlink } from "../../../contracts/oracle/implementations/mainnet/XAU/OracleETHXAUChainlink.sol"; -import { TreasuryImmutable, ITreasury } from "../../../contracts/treasury/TreasuryImmutable.sol"; -import { IAgToken, AgTokenSideChainImmutable } from "../../../contracts/agToken/AgTokenSideChainImmutable.sol"; -import { VaultManagerLiquidationBoostImmutable, VaultParameters, VaultManagerStorage, IERC20 } from "../../../contracts/vaultManager/VaultManagerLiquidationBoostImmutable.sol"; +import { Treasury, ITreasury } from "../../../contracts/treasury/Treasury.sol"; +import { IAgToken, AgToken } from "../../../contracts/agToken/AgToken.sol"; +import { VaultManagerLiquidationBoost, VaultParameters, VaultManagerStorage, IERC20 } from "../../../contracts/vaultManager/VaultManagerLiquidationBoost.sol"; import "./MainnetConstants.s.sol"; contract DeployVaultManagerMainnet is Script, MainnetConstants { @@ -26,7 +26,7 @@ contract DeployVaultManagerMainnet is Script, MainnetConstants { uint256 public constant BASE_BOOST = (25 * BASE_PARAMS) / 10; uint32 public constant STALE_PERIOD = 3600 * 48; - VaultManagerLiquidationBoostImmutable public vaultManager; + VaultManagerLiquidationBoost public vaultManager; IOracle public oracle; error ZeroAdress(); @@ -55,18 +55,13 @@ contract DeployVaultManagerMainnet is Script, MainnetConstants { address(AGGOLD_TREASURY) == address(0) || address(COLLATERAL) == address(0) || address(oracle) == address(0) ) revert ZeroAdress(); - vaultManager = new VaultManagerLiquidationBoostImmutable( - ITreasury(AGGOLD_TREASURY), - COLLATERAL, - oracle, - params, - SYMBOL - ); + vaultManager = new VaultManagerLiquidationBoost(); + vaultManager.initialize(ITreasury(AGGOLD_TREASURY), COLLATERAL, oracle, params, SYMBOL); console.log("Successfully deployed vaultManager ETH-GOLD at the address: ", address(vaultManager)); // TODO Governance should add vaultManager to Treasury - TreasuryImmutable(AGGOLD_TREASURY).addVaultManager(address(vaultManager)); + Treasury(AGGOLD_TREASURY).addVaultManager(address(vaultManager)); vm.stopBroadcast(); } diff --git a/scripts/foundry/polygon/Treasury.s.sol b/scripts/foundry/polygon/Treasury.s.sol deleted file mode 100644 index 3e633831..00000000 --- a/scripts/foundry/polygon/Treasury.s.sol +++ /dev/null @@ -1,33 +0,0 @@ -// SPDX-License-Identifier: GPL-3.0 -pragma solidity ^0.8.17; - -import "forge-std/Script.sol"; -import { console } from "forge-std/console.sol"; -import { ICoreBorrow } from "../../../contracts/coreBorrow/CoreBorrow.sol"; -import { TreasuryImmutable } from "../../../contracts/treasury/TreasuryImmutable.sol"; -import { IAgToken, AgTokenSideChainImmutable } from "../../../contracts/agToken/AgTokenSideChainImmutable.sol"; -import { VaultManagerLiquidationBoostImmutable, VaultParameters, VaultManagerStorage } from "../../../contracts/vaultManager/VaultManagerLiquidationBoostImmutable.sol"; -import "./PolygonConstants.s.sol"; - -contract DeployTreasury is Script, PolygonConstants { - string constant _NAME = "MockagGOLD"; - string constant _SYMBOL = "MockagGOLD"; - - function run() external { - uint256 deployerPrivateKey = vm.deriveKey(vm.envString("MNEMONIC_POLYGON"), 2); - vm.rememberKey(deployerPrivateKey); - - vm.startBroadcast(deployerPrivateKey); - - TreasuryImmutable treasury = new TreasuryImmutable(ICoreBorrow(CORE_BORROW)); - console.log("Successfully deployed agGOLD treasury at the address: ", address(treasury)); - - AgTokenSideChainImmutable agGOLD = new AgTokenSideChainImmutable(_NAME, _SYMBOL, address(treasury)); - console.log("Successfully deployed agGOLD at the address: ", address(agGOLD)); - - // TODO governance should call - // treasury.setStablecoin(agGOLD); - - vm.stopBroadcast(); - } -} diff --git a/scripts/foundry/polygon/VaultManager.s.sol b/scripts/foundry/polygon/VaultManager.s.sol index 4d1a9e5d..2f89fdf9 100644 --- a/scripts/foundry/polygon/VaultManager.s.sol +++ b/scripts/foundry/polygon/VaultManager.s.sol @@ -5,9 +5,9 @@ import "forge-std/Script.sol"; import { console } from "forge-std/console.sol"; import { IOracle } from "../../../contracts/interfaces/IOracle.sol"; import { OracleETHXAUChainlinkPolygon } from "../../../contracts/oracle/implementations/polygon/XAU/OracleETHXAUChainlinkPolygon.sol"; -import { TreasuryImmutable, ITreasury } from "../../../contracts/treasury/TreasuryImmutable.sol"; -import { IAgToken, AgTokenSideChainImmutable } from "../../../contracts/agToken/AgTokenSideChainImmutable.sol"; -import { VaultManagerLiquidationBoostImmutable, VaultParameters, VaultManagerStorage, IERC20 } from "../../../contracts/vaultManager/VaultManagerLiquidationBoostImmutable.sol"; +import { Treasury, ITreasury } from "../../../contracts/treasury/Treasury.sol"; +import { IAgToken, AgToken } from "../../../contracts/agToken/AgToken.sol"; +import { VaultManagerLiquidationBoost, VaultParameters, VaultManagerStorage, IERC20 } from "../../../contracts/vaultManager/VaultManagerLiquidationBoost.sol"; import "./PolygonConstants.s.sol"; contract DeployVaultManagerMainnet is Script, PolygonConstants { @@ -26,7 +26,7 @@ contract DeployVaultManagerMainnet is Script, PolygonConstants { uint256 public constant BASE_BOOST = (25 * BASE_PARAMS) / 10; uint32 public constant STALE_PERIOD = 3600 * 48; - VaultManagerLiquidationBoostImmutable public vaultManager; + VaultManagerLiquidationBoost public vaultManager; IOracle public oracle; error ZeroAdress(); @@ -55,18 +55,13 @@ contract DeployVaultManagerMainnet is Script, PolygonConstants { address(AGGOLD_TREASURY) == address(0) || address(COLLATERAL) == address(0) || address(oracle) == address(0) ) revert ZeroAdress(); - vaultManager = new VaultManagerLiquidationBoostImmutable( - ITreasury(AGGOLD_TREASURY), - COLLATERAL, - oracle, - params, - SYMBOL - ); + vaultManager = new VaultManagerLiquidationBoost(); + vaultManager.initialize(ITreasury(AGGOLD_TREASURY), COLLATERAL, oracle, params, SYMBOL); console.log("Successfully deployed vaultManager ETH-GOLD at the address: ", address(vaultManager)); // TODO Governance should add vaultManager to Treasury - TreasuryImmutable(AGGOLD_TREASURY).addVaultManager(address(vaultManager)); + Treasury(AGGOLD_TREASURY).addVaultManager(address(vaultManager)); vm.stopBroadcast(); } diff --git a/scripts/foundry/utils/Constants.s.sol b/scripts/foundry/utils/Constants.s.sol new file mode 100644 index 00000000..5eb3806a --- /dev/null +++ b/scripts/foundry/utils/Constants.s.sol @@ -0,0 +1,11 @@ +// SPDX-License-Identifier: GPL-3.0 +pragma solidity ^0.8.12; + +import "contracts/utils/Constants.sol"; + +/*////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + MAINNET CONSTANTS +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////*/ + +address constant IMMUTABLE_CREATE2_FACTORY_ADDRESS = 0x0000000000FFe8B47B3e2130213B802212439497; +address constant DEPLOYER = 0xfdA462548Ce04282f4B6D6619823a7C64Fdc0185; diff --git a/scripts/foundry/utils/FindInitCode.s.sol b/scripts/foundry/utils/FindInitCode.s.sol new file mode 100644 index 00000000..e7ad5809 --- /dev/null +++ b/scripts/foundry/utils/FindInitCode.s.sol @@ -0,0 +1,35 @@ +// SPDX-License-Identifier: GPL-3.0 +pragma solidity ^0.8.12; + +import { console } from "forge-std/console.sol"; +import "forge-std/Script.sol"; +import { StdAssertions } from "forge-std/Test.sol"; +import { stdJson } from "forge-std/StdJson.sol"; +import "stringutils/strings.sol"; + +import "./Constants.s.sol"; +import { TransparentUpgradeableProxy } from "@openzeppelin/contracts/proxy/transparent/TransparentUpgradeableProxy.sol"; + +import { ImmutableCreate2Factory } from "../../../contracts/interfaces/external/create2/ImmutableCreate2Factory.sol"; + +/// @dev Script to run to find the init code of a contract to get a vanity address from it +contract FindInitCode is Script, StdAssertions { + using stdJson for string; + using strings for *; + + function run() external { + // To maintain chain consistency, we do as if we deployed with the deployer as a proxyAdmin before transferring + // to another address + // We use a contract that is widely deployed across many chains as an implementation to make it resilient + // to possible implementation changes + bytes memory emptyData; + bytes memory initCode = abi.encodePacked( + type(TransparentUpgradeableProxy).creationCode, + abi.encode(IMMUTABLE_CREATE2_FACTORY_ADDRESS, DEPLOYER, emptyData) + ); + console.log("Proxy bytecode"); + console.logBytes(initCode); + console.logBytes(abi.encode(IMMUTABLE_CREATE2_FACTORY_ADDRESS, DEPLOYER, emptyData)); + console.log(""); + } +} diff --git a/scripts/foundry/utils/VanityAddress.s.sol b/scripts/foundry/utils/VanityAddress.s.sol new file mode 100644 index 00000000..bb75764b --- /dev/null +++ b/scripts/foundry/utils/VanityAddress.s.sol @@ -0,0 +1,63 @@ +// SPDX-License-Identifier: GPL-3.0 + +pragma solidity ^0.8.12; + +import "stringutils/strings.sol"; +import "forge-std/Script.sol"; +import { StdAssertions } from "forge-std/Test.sol"; +import { stdJson } from "forge-std/StdJson.sol"; +import { console } from "forge-std/console.sol"; +import "./Constants.s.sol"; + +contract VanityAddress is Script, StdAssertions { + using stdJson for string; + + string constant JSON_VANITY_PATH = "./scripts/vanity.json"; + + function _findDeploymentAddress( + bytes32 salt, + bytes memory initCode + ) internal pure returns (address deploymentAddress) { + deploymentAddress = address( + uint160( // downcast to match the address type. + uint256( // convert to uint to truncate upper digits. + keccak256( // compute the CREATE2 hash using 4 inputs. + abi.encodePacked( // pack all inputs to the hash together. + hex"ff", // start with 0xff to distinguish from RLP. + IMMUTABLE_CREATE2_FACTORY_ADDRESS, // this contract will be the caller. + salt, // pass in the supplied salt value. + keccak256(abi.encodePacked(initCode)) // pass in the hash of initialization code. + ) + ) + ) + ) + ); + } + + function run() external { + bytes + memory initCode = hex"60406080815262000f5f80380380620000188162000364565b9283398101906060818303126200035f576200003481620003a0565b9160209262000045848401620003a0565b8584015190936001600160401b0391908282116200035f57019280601f850112156200035f57835193620000836200007d86620003b5565b62000364565b94808652878601928882840101116200035f578288620000a49301620003d1565b823b1562000305577f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc80546001600160a01b03199081166001600160a01b0386811691821790935590959194600093909290917fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b8580a2805115801590620002fd575b620001f5575b50505050507fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103937f7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f86865493815196818616885216958684820152a18315620001a357501617905551610b0a9081620004558239f35b60849086519062461bcd60e51b82526004820152602660248201527f455243313936373a206e65772061646d696e20697320746865207a65726f206160448201526564647265737360d01b6064820152fd5b8951946060860190811186821017620002e9578a52602785527f416464726573733a206c6f772d6c6576656c2064656c65676174652063616c6c89860152660819985a5b195960ca1b8a860152823b156200029657928092819262000280969551915af43d156200028c573d620002706200007d82620003b5565b9081528092893d92013e620003f6565b5038808080806200012d565b60609150620003f6565b895162461bcd60e51b8152600481018a9052602660248201527f416464726573733a2064656c65676174652063616c6c20746f206e6f6e2d636f6044820152651b9d1c9858dd60d21b6064820152608490fd5b634e487b7160e01b85526041600452602485fd5b508362000127565b865162461bcd60e51b815260048101879052602d60248201527f455243313936373a206e657720696d706c656d656e746174696f6e206973206e60448201526c1bdd08184818dbdb9d1c9858dd609a1b6064820152608490fd5b600080fd5b6040519190601f01601f191682016001600160401b038111838210176200038a57604052565b634e487b7160e01b600052604160045260246000fd5b51906001600160a01b03821682036200035f57565b6001600160401b0381116200038a57601f01601f191660200190565b60005b838110620003e55750506000910152565b8181015183820152602001620003d4565b9091901562000403575090565b815115620004145750805190602001fd5b6044604051809262461bcd60e51b825260206004830152620004468151809281602486015260208686019101620003d1565b601f01601f19168101030190fdfe6080604052600436101561002c575b361561001f575b61001d6104dd565b005b6100276104dd565b610015565b6000803560e01c9081633659cfe614610093575080634f1ef2861461008a5780635c60da1b146100815780638f283970146100785763f851a4400361000e57610073610455565b61000e565b506100736102f0565b5061007361023b565b50610073610157565b3461012c5760207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc36011261012c576100ca61012f565b73ffffffffffffffffffffffffffffffffffffffff7fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103541633146000146101235761012090610117610639565b908382526106f3565b80f35b506101206104dd565b80fd5b6004359073ffffffffffffffffffffffffffffffffffffffff8216820361015257565b600080fd5b5060407ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126101525761018a61012f565b60243567ffffffffffffffff9182821161015257366023830112156101525781600401359283116101525736602484840101116101525773ffffffffffffffffffffffffffffffffffffffff7fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035416331460001461023057600060208480602461021e61021961001d996106aa565b610666565b96828852018387013784010152610833565b50505061001d6104dd565b50346101525760007ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc360112610152576020600073ffffffffffffffffffffffffffffffffffffffff90817fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103541633146000146102e25750807f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc5416905b60405191168152f35b906102eb6104dd565b6102d9565b50346101525760207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126101525761032861012f565b73ffffffffffffffffffffffffffffffffffffffff907fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d610391808354163314600014610230577f7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f604084549281519481851686521693846020820152a181156103d1577fffffffffffffffffffffffff000000000000000000000000000000000000000016179055005b60846040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f455243313936373a206e65772061646d696e20697320746865207a65726f206160448201527f64647265737300000000000000000000000000000000000000000000000000006064820152fd5b50346101525760007ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc360112610152576020600073ffffffffffffffffffffffffffffffffffffffff7fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61038181541633146000146104d85754604051911681529050f35b506102eb5b5073ffffffffffffffffffffffffffffffffffffffff807fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035416331461055f577f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc54166000808092368280378136915af43d82803e1561055b573d90f35b3d90fd5b60a46040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604260248201527f5472616e73706172656e745570677261646561626c6550726f78793a2061646d60448201527f696e2063616e6e6f742066616c6c6261636b20746f2070726f7879207461726760648201527f65740000000000000000000000000000000000000000000000000000000000006084820152fd5b507f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b604051906020820182811067ffffffffffffffff82111761065957604052565b610661610609565b604052565b907fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f604051930116820182811067ffffffffffffffff82111761065957604052565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f60209267ffffffffffffffff81116106e6575b01160190565b6106ee610609565b6106e0565b803b156107af5773ffffffffffffffffffffffffffffffffffffffff81167f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc817fffffffffffffffffffffffff00000000000000000000000000000000000000008254161790557fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b600080a28151158015906107a7575b610792575050565b6107a49161079e6108d9565b91610957565b50565b50600061078a565b60846040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602d60248201527f455243313936373a206e657720696d706c656d656e746174696f6e206973206e60448201527f6f74206120636f6e7472616374000000000000000000000000000000000000006064820152fd5b803b156107af5773ffffffffffffffffffffffffffffffffffffffff81167f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc817fffffffffffffffffffffffff00000000000000000000000000000000000000008254161790557fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b600080a28151158015906108d157610792575050565b50600161078a565b604051906060820182811067ffffffffffffffff82111761094a575b604052602782527f206661696c6564000000000000000000000000000000000000000000000000006040837f416464726573733a206c6f772d6c6576656c2064656c65676174652063616c6c60208201520152565b610952610609565b6108f5565b9190823b156109a0576000816109959460208394519201905af43d15610998573d90610985610219836106aa565b9182523d6000602084013e610a24565b90565b606090610a24565b60846040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f416464726573733a2064656c65676174652063616c6c20746f206e6f6e2d636f60448201527f6e747261637400000000000000000000000000000000000000000000000000006064820152fd5b90919015610a30575090565b815115610a405750805190602001fd5b604051907f08c379a000000000000000000000000000000000000000000000000000000000825281602080600483015282519283602484015260005b848110610abd575050507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f836000604480968601015201168101030190fd5b818101830151868201604401528593508201610a7c56fea26469706673582212206eca7257d81e920296a8c93c0ac0d93d9bb0927ce3e4cefa34ff129bc0cdbceb64736f6c634300081100330000000000000000000000000000000000ffe8b47b3e2130213b802212439497000000000000000000000000fda462548ce04282f4b6d6619823a7c64fdc018500000000000000000000000000000000000000000000000000000000000000600000000000000000000000000000000000000000000000000000000000000000"; + // Deploy diamond + string memory json = vm.readFile(JSON_VANITY_PATH); + uint256 initInt = json.readUint(string.concat("$.", "init")); + uint256 i = initInt; + address computedAddress; + bool found = false; + while (!found && i - initInt < 3000000) { + computedAddress = _findDeploymentAddress( + bytes32(abi.encodePacked(DEPLOYER, abi.encodePacked(uint96(i)))), + initCode + ); + if (uint24(uint160(bytes20(computedAddress)) >> 136) == uint24(0x000020)) { + found = true; + break; + } + i = i + 1; + } + + console.log("found ", found); + console.log("i ", i); + console.logBytes32(bytes32(abi.encodePacked(DEPLOYER, abi.encodePacked(uint96(i))))); + console.log("computedAddress ", computedAddress); + } +} diff --git a/scripts/getDebtCeiling.ts b/scripts/getDebtCeiling.ts index b76c53d7..95b12146 100644 --- a/scripts/getDebtCeiling.ts +++ b/scripts/getDebtCeiling.ts @@ -1,7 +1,8 @@ -import { ChainId, formatAmount, registry } from '@angleprotocol/sdk'; +import { ChainId, registry } from '@angleprotocol/sdk'; import { ethers, network } from 'hardhat'; import { Treasury, Treasury__factory, VaultManager, VaultManager__factory } from '../typechain'; +import { formatAmount } from '../utils/bignumber'; async function main() { const { deployer } = await ethers.getNamedSigners(); diff --git a/scripts/vanity.json b/scripts/vanity.json new file mode 100644 index 00000000..da1671c5 --- /dev/null +++ b/scripts/vanity.json @@ -0,0 +1,4 @@ +{ + "init": 8223543, + "salt": "0xfda462548ce04282f4b6d6619823a7c64fdc01850000000000000000007d7b37" +} diff --git a/test/foundry/agToken/AgTokenGoldTest.test.sol b/test/foundry/agToken/AgTokenTest.test.sol similarity index 68% rename from test/foundry/agToken/AgTokenGoldTest.test.sol rename to test/foundry/agToken/AgTokenTest.test.sol index f1e24db5..9450aca0 100644 --- a/test/foundry/agToken/AgTokenGoldTest.test.sol +++ b/test/foundry/agToken/AgTokenTest.test.sol @@ -4,14 +4,14 @@ pragma solidity ^0.8.17; import { stdStorage, StdStorage } from "forge-std/Test.sol"; import "../BaseTest.test.sol"; import "../../../contracts/mock/MockTreasury.sol"; -import { IAgToken, AgTokenSideChainImmutable } from "../../../contracts/agToken/AgTokenSideChainImmutable.sol"; +import { IAgToken, AgToken } from "../../../contracts/agToken/AgToken.sol"; -contract AgTokenGoldTest is BaseTest { +contract AgTokenTest is BaseTest { using stdStorage for StdStorage; address internal _hacker = address(uint160(uint256(keccak256(abi.encodePacked("hacker"))))); - AgTokenSideChainImmutable internal _agToken; + AgToken internal _agToken; MockTreasury internal _treasury; string constant _NAME = "Angle stablecoin gold"; @@ -20,8 +20,20 @@ contract AgTokenGoldTest is BaseTest { function setUp() public override { super.setUp(); - _treasury = new MockTreasury(IAgToken(address(0)), _GOVERNOR, _GUARDIAN, address(0), address(0), address(0)); - _agToken = new AgTokenSideChainImmutable(_NAME, _SYMBOL, address(_treasury)); + AgToken _agTokenImplem = new AgToken(); + bytes memory emptyData; + _agToken = AgToken(deployUpgradeable(address(_agTokenImplem), emptyData)); + + _treasury = new MockTreasury( + IAgToken(address(_agToken)), + _GOVERNOR, + _GUARDIAN, + address(0), + address(0), + address(0) + ); + + _agToken.initialize(_NAME, _SYMBOL, address(_treasury)); vm.prank(_GOVERNOR); _treasury.setStablecoin(_agToken); @@ -39,6 +51,7 @@ contract AgTokenGoldTest is BaseTest { function testAlreadyInitalizeFail() public { string memory name2 = "Angle stablecoin XXX"; string memory symbol2 = "agXXX"; + vm.expectRevert(); _agToken.initialize(name2, symbol2, _alice); assertEq(_agToken.name(), _NAME); diff --git a/test/foundry/treasury/TreasuryImmutableTest.test.sol b/test/foundry/treasury/TreasuryImmutableTest.test.sol deleted file mode 100644 index 5911ceb8..00000000 --- a/test/foundry/treasury/TreasuryImmutableTest.test.sol +++ /dev/null @@ -1,206 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity ^0.8.17; - -import { stdStorage, StdStorage } from "forge-std/Test.sol"; -import "../BaseTest.test.sol"; -import "../../../contracts/mock/MockOracle.sol"; -import "../../../contracts/mock/MockTreasury.sol"; -import "../../../contracts/mock/MockTokenPermit.sol"; -import { MockCorrectVaultManagerLiquidationBoostImmutable, MockIncorrectVaultManagerLiquidationBoostImmutable } from "../../../contracts/mock/MockVaultManagerLiquidationBoostImmutable.sol"; -import { MockTreasuryImmutable, TreasuryImmutable, Treasury } from "../../../contracts/mock/MockTreasuryImmutable.sol"; -import { IAgToken, AgTokenSideChainImmutable } from "../../../contracts/agToken/AgTokenSideChainImmutable.sol"; -import { VaultManagerLiquidationBoostImmutable, VaultParameters } from "../../../contracts/vaultManager/VaultManagerLiquidationBoostImmutable.sol"; -/* -contract TreasuryImmutableTest is BaseTest { - using stdStorage for StdStorage; - - address internal _hacker = address(uint160(uint256(keccak256(abi.encodePacked("hacker"))))); - // you should repace with latest "deployedBytecode" from `VaultManagerLiquidationBoostImmutable` - bytes32 internal _hashVM = - keccak256( - hex"608060405234801561001057600080fd5b50600436106103015760003560e01c8063010db1951461030657806301ffc9a71461032f57806306fdde0314610352578063081812fc14610367578063087a60071461037a578063095ea7b3146103915780630e198f22146103a657806313888565146103af57806323b872dd146103b8578063254cf439146103cb578063307439af146103fd57806334ce998a1461041d57806335836f15146104255780633644e5151461043857806339393ac91461044057806339eb4dc6146104515780633ae2325f146104655780633af32abf146104785780633c2e941b1461049857806342842e0e146104a1578063430c2081146104b45780634f7e43df146104c757806355f804b3146104e15780635c975abb146104f457806361d027b3146105085780636352211e1461051b57806370a082311461052e57806374107543146105415780637aacfffa146105545780637adbf973146104405780637c0f59f4146105905780637c3a00fd146105aa5780637dc0d1d0146105bd5780637e53bd97146105d05780637e56d47c146105e35780637ecebe00146105f6578063835986b41461061f57806389050f1d1461063257806395d89b41146106445780639a3b6f2f1461064c5780639f48118f14610692578063a22cb4651461069d578063af2c8c2e146106b0578063b1511cc9146106b9578063b4bd6f46146106cc578063b88d4fde146106df578063bbcac557146106f2578063bfc7ad2e146106fb578063c13cacae14610704578063c4ae3168146103a4578063c66d8b0114610717578063c87b56dd14610731578063d8dfeb4514610744578063d9b1cb5b14610757578063de1f77651461076c578063de8fc6981461077e578063df011c4114610791578063e182b883146107a4578063e1c84ea4146107b7578063e626648a146107c0578063e985e9c5146107da578063e9cbd822146107ed578063f0f4426014610440578063f51cc7dd14610800578063fad9aba314610813578063fc29b0211461081c578063fd527cf81461082f575b600080fd5b603754610319906001600160a01b031681565b60405161032691906141b0565b60405180910390f35b61034261033d3660046141da565b610837565b6040519015158152602001610326565b61035a6108a4565b6040516103269190614247565b61031961037536600461425a565b610932565b610383603f5481565b604051908152602001610326565b6103a461039f366004614288565b610963565b005b610383603e5481565b61038360415481565b6103a46103c63660046142b4565b6109ef565b603c546103e590600160401b90046001600160401b031681565b6040516001600160401b039091168152602001610326565b61041061040b3660046142f5565b610a23565b6040516103269190614325565b610383610ad5565b61038361043336600461425a565b610b07565b610383610b43565b6103a461044e36600461435e565b50565b603d5461034290600160c01b900460ff1681565b61038361047336600461425a565b610b4d565b61038361048636600461435e565b60446020526000908152604090205481565b61038360455481565b6103a46104af3660046142b4565b610b6e565b6103426104c2366004614288565b610b89565b603d546103e590600160801b90046001600160401b031681565b6103a46104ef366004614430565b610b95565b603d5461034290600160c81b900460ff1681565b603354610319906001600160a01b031681565b61031961052936600461425a565b610c33565b61038361053c36600461435e565b610c3e565b6103a461054f366004614464565b610c83565b61057b61056236600461425a565b6043602052600090815260409020805460019091015482565b60408051928352602083019190915201610326565b603c546103e590600160c01b90046001600160401b031681565b603d546103e5906001600160401b031681565b603654610319906001600160a01b031681565b6103a46105de36600461451c565b610f34565b6104106105f1366004614591565b611125565b61038361060436600461435e565b6001600160a01b03166000908152607f602052604090205490565b6103a461062d366004614655565b6116a6565b610383676765c793fa10079d601a1b81565b61035a6117f7565b61065f61065a36600461476f565b611804565b60405161032691908151815260208083015190820152604080830151908201526060918201519181019190915260800190565b610383633b9aca0081565b6103a46106ab366004614805565b611839565b61038360405481565b6103a46106c736600461425a565b611844565b6103836106da36600461435e565b61190d565b6103a46106ed366004614833565b61191d565b61038360425481565b61038360b65481565b6103a461071236600461489e565b61195a565b603d546103e590600160401b90046001600160401b031681565b61035a61073f36600461425a565b611a17565b603454610319906001600160a01b031681565b6103a46107653660046148ca565b5050505050565b610383676765c793fa10079d601b1b81565b61065f61078c36600461495e565b611b6d565b603c546103e5906001600160401b031681565b6103836107b236600461425a565b6123c8565b61038360395481565b603c546103e590600160801b90046001600160401b031681565b6103426107e83660046149bc565b6123d8565b603554610319906001600160a01b031681565b6103a461080e3660046149ea565b612406565b61038360b45481565b61041061082a366004614a6a565b6126c5565b61057b6126ef565b60006001600160e01b03198216635b5e139f60e01b148061086857506001600160e01b031982166380ac58cd60e01b145b8061088357506001600160e01b0319821663430c208160e01b145b8061089e57506001600160e01b031982166301ffc9a760e01b145b92915050565b607d80546108b190614ac6565b80601f01602080910402602001604051908101604052809291908181526020018280546108dd90614ac6565b801561092a5780601f106108ff5761010080835404028352916020019161092a565b820191906000526020600020905b81548152906001019060200180831161090d57829003601f168201915b505050505081565b600061093d8261281d565b61095a5760405163062a39dd60e11b815260040160405180910390fd5b61089e8261283a565b600061096e82612855565b9050806001600160a01b0316836001600160a01b0316036109a2576040516349fa8bc360e11b815260040160405180910390fd5b336001600160a01b038216148015906109c257506109c081336123d8565b155b156109e05760405163c19f17a960e01b815260040160405180910390fd5b6109ea838361288b565b505050565b33816109fb82826128f9565b610a185760405163c19f17a960e01b815260040160405180910390fd5b610765858585612977565b610a2b6140f9565b60008381526043602090815260409182902082518084018452815481526001909101548183015260365483516315f789a960e21b81529351610ace94929387936001600160a01b03909316926357de26a492600480830193928290030181865afa158015610a9d573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610ac19190614afa565b610ac9612a4e565b612be3565b9392505050565b6000676765c793fa10079d601b1b610aeb612a4e565b604054610af89190614b29565b610b029190614b56565b905090565b6000676765c793fa10079d601b1b610b1d612a4e565b600084815260436020526040902060010154610b399190614b29565b61089e9190614b56565b6000610b02612f4c565b603b8181548110610b5d57600080fd5b600091825260209091200154905081565b6109ea8383836040518060200160405280600081525061191d565b6000610ace83836128f9565b60335460405163521d4de960e01b81526001600160a01b039091169063521d4de990610bc59033906004016141b0565b602060405180830381865afa158015610be2573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610c069190614b6a565b610c2357604051632678482f60e21b815260040160405180910390fd5b6046610c2f8282614bcd565b5050565b600061089e82612855565b60006001600160a01b038216610c675760405163d92e233d60e01b815260040160405180910390fd5b506001600160a01b031660009081526048602052604090205490565b60335460405163521d4de960e01b81526001600160a01b039091169063521d4de990610cb39033906004016141b0565b602060405180830381865afa158015610cd0573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610cf49190614b6a565b610d1157604051632678482f60e21b815260040160405180910390fd5b806121a360f11b03610d7457603d546001600160401b03600160401b90910481169083161115610d5457604051637650e96360e11b815260040160405180910390fd5b603c80546001600160401b0319166001600160401b038416179055610eed565b80622a242360e91b03610dd857633b9aca00826001600160401b03161015610daf5760405163da6a17b960e01b815260040160405180910390fd5b603c8054600160401b600160801b031916600160401b6001600160401b03851602179055610eed565b8061212360f11b03610e3b57633b9aca00826001600160401b03161115610e1257604051637650e96360e11b815260040160405180910390fd5b603c8054600160801b600160c01b031916600160801b6001600160401b03851602179055610eed565b806124a960f11b03610e7057610e4f612fb8565b50603d80546001600160401b0319166001600160401b038416179055610eed565b806213531160ea1b03610ed457633b9aca00826001600160401b03161115610eab57604051637650e96360e11b815260040160405180910390fd5b603d8054600160801b600160c01b031916600160801b6001600160401b03851602179055610eed565b60405163e1daa9cf60e01b815260040160405180910390fd5b604080516001600160401b0384168152602081018390527f13b367dac93b85d1ed9b3d8961d8b48e1a677c9800bb1613b4b0416b2d5b61d091015b60405180910390a15050565b60335460405163521d4de960e01b81526001600160a01b039091169063521d4de990610f649033906004016141b0565b602060405180830381865afa158015610f81573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610fa59190614b6a565b610fc257604051632678482f60e21b815260040160405180910390fd5b80518251141580610fed575080600081518110610fe157610fe1614c8c565b60200260200101516000145b8061107c57506001600160a01b0383161580159061107c57508160008151811061101957611019614c8c565b60200260200101518260018151811061103457611034614c8c565b602002602001015111158061107c57508060008151811061105757611057614c8c565b60200260200101518160018151811061107257611072614c8c565b6020026020010151105b1561109a57604051631746545d60e11b815260040160405180910390fd5b603780546001600160a01b0319166001600160a01b03851617905581516110c890603a906020850190614128565b5080516110dc90603b906020840190614128565b50826001600160a01b03167feb74d4d9fea592587c926aeb35eb6a7893fb28db0c1c8eb2eb3c586e7164b76c8383604051611118929190614cdd565b60405180910390a2505050565b61112d6140f9565b6002600154036111585760405162461bcd60e51b815260040161114f90614d02565b60405180910390fd5b6002600155865186518114158061116d575080155b1561118b576040516346282e8d60e01b815260040160405180910390fd5b603660009054906101000a90046001600160a01b03166001600160a01b03166357de26a46040518163ffffffff1660e01b8152600401602060405180830381865afa1580156111de573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906112029190614afa565b606083015261120f612fb8565b60808301526040517f965a177723c641ee49150b583a0b9ad4730bb20d3474e00ae5a65e777c00d67b90611244908a90614d39565b60405180910390a160005b81811015611616576000604360008b848151811061126f5761126f614c8c565b6020026020010151815260200190815260200160002060405180604001604052908160008201548152602001600182015481525050905060006112bc823387606001518860800151612be3565b905080604001516000141580156112f0575080604001518a84815181106112e5576112e5614c8c565b602002602001015110155b80611317575080600001518a848151811061130d5761130d614c8c565b6020026020010151115b156113405780600001518a848151811061133357611333614c8c565b6020026020010181815250505b6000856060015182606001516113569190614b29565b603854633b9aca008d878151811061137057611370614c8c565b60200260200101516113829190614b29565b61138c9190614b29565b6113969190614b56565b90506113c48c85815181106113ad576113ad614c8c565b6020026020010151828560000151111561044e5750565b825181106114fa575081516020830151604080546000906113e6908490614d4c565b92505081905550604360008d868151811061140357611403614c8c565b60209081029190910181015182528101919091526040016000908120818155600101819055603d548c51633b9aca0091600160401b90046001600160401b0316908e908890811061145657611456614c8c565b60200260200101516114689190614b29565b6114729190614b56565b905082608001518110611486576000611496565b8083608001516114969190614d4c565b876040018181516114a79190614d5f565b905250508b51600080516020615124833981519152908d90869081106114cf576114cf614c8c565b6020026020010151846020015160006040516114ed93929190614d72565b60405180910390a16115bb565b80604360008e878151811061151157611511614c8c565b6020026020010151815260200190815260200160002060000160008282546115399190614d4c565b925050819055506115b98c858151811061155557611555614c8c565b6020026020010151633b9aca00603d60089054906101000a90046001600160401b03166001600160401b03168e888151811061159357611593614c8c565b60200260200101516115a59190614b29565b6115af9190614b56565b8860800151613059565b505b80866020018181516115cd9190614d5f565b9052508a518b90859081106115e4576115e4614c8c565b6020026020010151866000018181516115fd9190614d5f565b90525061160f9250839150614d8b9050565b905061124f565b50603d54633b9aca009061163a90600160401b90046001600160401b031682614d4c565b83516116469190614b29565b6116509190614b56565b604160008282546116619190614d5f565b909155505060408201516042805460009061167d908490614d5f565b90915550506020820151825161169791908888888861318b565b50600180559695505050505050565b6033546040516333b52a9f60e11b81526001600160a01b039091169063676a553e906116d69033906004016141b0565b602060405180830381865afa1580156116f3573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906117179190614b6a565b6117345760405163027f480760e01b815260040160405180910390fd5b6000603c54600090600160801b90046001600160401b031684111561177357603c5461177090600160801b90046001600160401b031685614d4c565b90505b60006117846002633b9aca00614e88565b61179283633b9aca00614d4c565b6117a085633b9aca00614d4c565b6117aa9089614b29565b6117b49190614b29565b6117be9190614b56565b90506117ca8187614d4c565b604160008282546117db9190614d5f565b909155506117ed905087826000613059565b5050505050505050565b607e80546108b190614ac6565b61180c614173565b6040805160008082526020820190925261182e91879187918791879190611b6d565b90505b949350505050565b610c2f338383613295565b60335460405163521d4de960e01b81526001600160a01b039091169063521d4de9906118749033906004016141b0565b602060405180830381865afa158015611891573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906118b59190614b6a565b6118d257604051632678482f60e21b815260040160405180910390fd5b60398190556040518181527fdd63b3dcdbebad734892f7c7a26d0f647fbc7eec973e0775f5229018ac4ab47a9060200160405180910390a150565b600061089e8261334a565b919050565b338261192982826128f9565b6119465760405163c19f17a960e01b815260040160405180910390fd5b6119528686868661340d565b505050505050565b603354604051631c86b03760e31b81526001600160a01b039091169063e43581b89061198a9033906004016141b0565b602060405180830381865afa1580156119a7573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906119cb9190614b6a565b6119e857604051633b8d9d7560e21b815260040160405180910390fd5b81831115611a095760405163180d062b60e31b815260040160405180910390fd5b60b49290925560b65560b555565b6060611a228261281d565b611a3f5760405163062a39dd60e11b815260040160405180910390fd5b8160005b8115611a6657611a5281614d8b565b9050611a5f600a83614b56565b9150611a43565b6000816001600160401b03811115611a8057611a8061437b565b6040519080825280601f01601f191660200182016040528015611aaa576020820181803683370190505b5090505b8415611b1557611abf600183614d4c565b9150611acc600a86614e97565b611ad7906030614d5f565b60f81b818381518110611aec57611aec614c8c565b60200101906001600160f81b031916908160001a905350611b0e600a86614b56565b9450611aae565b60468054611b2290614ac6565b9050600003611b405760405180602001604052806000815250611b64565b604681604051602001611b54929190614eab565b6040516020818303038152906040525b95945050505050565b611b75614173565b600260015403611b975760405162461bcd60e51b815260040161114f90614d02565b600260015585518751141580611bac57508651155b15611bca576040516346282e8d60e01b815260040160405180910390fd5b6000806000806000805b8c518110156121315760008d8281518110611bf157611bf1614c8c565b6020026020010151905060006007811115611c0e57611c0e614f32565b816007811115611c2057611c20614f32565b03611c6057611c5a8d8381518110611c3a57611c3a614c8c565b6020026020010151806020019051810190611c559190614f48565b61334a565b50612120565b6002816007811115611c7457611c74614f32565b03611cdd578c8281518110611c8b57611c8b614c8c565b6020026020010151806020019051810190611ca69190614f65565b955092506000839003611cb95760455492505b611cc38386613447565b8488606001818151611cd59190614d5f565b905250612120565b6007816007811115611cf157611cf1614f32565b03611dc95760008060008f8581518110611d0d57611d0d614c8c565b6020026020010151806020019051810190611d289190614f89565b60345460405163d505accf60e01b81526001600160a01b038089166004830152306024830152604482018890526064820187905260ff8616608483015260a4820185905260c48201849052969f50939d50939b509497509550929350169063d505accf9060e401600060405180830381600087803b158015611da957600080fd5b505af1158015611dbd573d6000803e3d6000fd5b50505050505050612120565b86600003611ddc57611dd9612fb8565b96505b6004816007811115611df057611df0614f32565b03611eaa578c8281518110611e0757611e07614c8c565b6020026020010151806020019051810190611e229190614f65565b945092506000839003611e355760455492505b611e40838589613059565b93506000611e5281633b9aca00614d4c565b611e60633b9aca0087614b29565b611e6a9190614b56565b9050611e768582614d4c565b60416000828254611e879190614d5f565b925050819055508089602001818151611ea09190614d5f565b9052506121209050565b85600003611f2c57603660009054906101000a90046001600160a01b03166001600160a01b03166357de26a46040518163ffffffff1660e01b8152600401602060405180830381865afa158015611f05573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611f299190614afa565b95505b6001816007811115611f4057611f40614f32565b03611fbe578c8281518110611f5757611f57614c8c565b6020026020010151806020019051810190611f729190614afa565b925082600003611f825760455492505b611f8d8387896134b3565b80965081955050508488604001818151611fa79190614d5f565b905250602088018051859190611cd5908390614d5f565b6003816007811115611fd257611fd2614f32565b03612035578c8281518110611fe957611fe9614c8c565b60200260200101518060200190518101906120049190614f65565b9550925060008390036120175760455492505b6120238386888a6135bf565b8488604001818151611cd59190614d5f565b600581600781111561204957612049614f32565b036120ae578c828151811061206057612060614c8c565b602002602001015180602001905181019061207b9190614f65565b94509250600083900361208e5760455492505b61209a8385888a613699565b93508388600001818151611cd59190614d5f565b60068160078111156120c2576120c2614f32565b03612120576000808e84815181106120dc576120dc614c8c565b60200260200101518060200190518101906120f79190614fdc565b985091965092509050600085900361210f5760455494505b61211d858383898c8e613734565b50505b5061212a81614d8b565b9050611bd4565b508551602087015110612228578551602087015160009161215191614d4c565b9050866060015187604001511061218857612183876060015188604001516121799190614d4c565b828d8d8d8d61318b565b612222565b80156121f557603554604051630d43af8160e21b81526001600160a01b039091169063350ebe04906121c29084908f90339060040161501a565b600060405180830381600087803b1580156121dc57600080fd5b505af11580156121f0573d6000803e3d6000fd5b505050505b612222333089604001518a6060015161220e9190614d4c565b6034546001600160a01b0316929190613883565b506123b4565b6020860151865160009161223b91614d4c565b6035546040516340c10f1960e01b81529192506001600160a01b0316906340c10f199061226e908d908590600401615039565b600060405180830381600087803b15801561228857600080fd5b505af115801561229c573d6000803e3d6000fd5b505050508660600151876040015111156122e0576122db8a886060015189604001516122c89190614d4c565b6034546001600160a01b031691906138ee565b6123b2565b6000876040015188606001516122f69190614d4c565b905080156123b05788511561239857896001600160a01b031663a5d4096b603560009054906101000a90046001600160a01b0316603460009054906101000a90046001600160a01b03163385878f6040518763ffffffff1660e01b815260040161236596959493929190615052565b600060405180830381600087803b15801561237f57600080fd5b505af1158015612393573d6000803e3d6000fd5b505050505b6034546123b0906001600160a01b0316333084613883565b505b505b505060018055509198975050505050505050565b603a8181548110610b5d57600080fd5b6001600160a01b039182166000908152604a6020908152604080832093909416825291909152205460011490565b834211156124275760405163f87d927160e01b815260040160405180910390fd5b6fa2a8918ca85bafe22016d0b997e4df60600160ff1b0381118061245e57508260ff16601b1415801561245e57508260ff16601c14155b1561247c57604051638baa579f60e01b815260040160405180910390fd5b6000612486612f4c565b6082548989896124958d61390d565b6040805160208101969096526001600160a01b03948516908601529290911660608401521515608083015260a082015260c0810187905260e0016040516020818303038152906040528051906020012060405160200161250c92919061190160f01b81526002810192909252602282015260420190565b604051602081830303815290604052805190602001209050612536886001600160a01b031661280e565b1561261257604080516020810185905280820184905260f886901b6001600160f81b0319166060820152815160418183030181526061820192839052630b135d3f60e11b9092526001600160a01b038a1691631626ba7e9161259c918591606501615094565b602060405180830381865afa1580156125b9573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906125dd91906150ad565b6001600160e01b031916631626ba7e60e01b1461260d57604051638baa579f60e01b815260040160405180910390fd5b6126ba565b6040805160008082526020820180845284905260ff871692820192909252606081018590526080810184905260019060a0016020604051602081039080840390855afa158015612666573d6000803e3d6000fd5b505050602060405103519050886001600160a01b0316816001600160a01b031614158061269a57506001600160a01b038116155b156126b857604051638baa579f60e01b815260040160405180910390fd5b505b6117ed888888613295565b6126cd6140f9565b6040805160008082526020820190925261182e91879187918791879190611125565b60335460009081906001600160a01b0316331461271f5760405163b90cdbb160e01b815260040160405180910390fd5b612727612fb8565b5050604180546042805460009384905592905591508082106127c05761274d8183614d4c565b6035546033546040516340c10f1960e01b8152929450600093506001600160a01b03918216926340c10f19926127899216908690600401615039565b600060405180830381600087803b1580156127a357600080fd5b505af11580156127b7573d6000803e3d6000fd5b505050506127d1565b6127ca8282614d4c565b9050600091505b60408051838152602081018390527ffeb12225c131aab793a00c5239afb778932d170fa28ce6e9d23703e4bd892121910160405180910390a19091565b6001600160a01b03163b151590565b6000908152604760205260409020546001600160a01b0316151590565b6000908152604960205260409020546001600160a01b031690565b6000818152604760205260409020546001600160a01b0316806119185760405163062a39dd60e11b815260040160405180910390fd5b600081815260496020526040902080546001600160a01b0319166001600160a01b03841690811790915581906128c082612855565b6001600160a01b03167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92560405160405180910390a45050565b60008061290583612855565b9050806001600160a01b0316846001600160a01b031614806129405750836001600160a01b03166129358461283a565b6001600160a01b0316145b8061183157506001600160a01b038082166000908152604a6020908152604080832093881683529290522054600114949350505050565b826001600160a01b031661298a82612855565b6001600160a01b0316146129b15760405163c19f17a960e01b815260040160405180910390fd5b6001600160a01b0382166129d85760405163d92e233d60e01b815260040160405180910390fd5b6129e360008261288b565b6001600160a01b038084166000818152604860209081526040808320805460001901905593861680835284832080546001019055858352604790915283822080546001600160a01b0319168217905592518493929160008051602061516483398151915291a4505050565b600080603e5442612a5f9190614d4c565b603d549091506001600160401b0316811580612a79575080155b15612a8857603f549250505090565b6000612a95600184614d4c565b9050600060028411612aa8576000612ab3565b612ab3600285614d4c565b90506000676765c793fa10079d601b1b676765c793fa10079d601a1b612ad98680614b29565b612ae39190614d5f565b612aed9190614b56565b90506000676765c793fa10079d601b1b676765c793fa10079d601a1b612b138785614b29565b612b1d9190614d5f565b612b279190614b56565b90506000600283612b38878a614b29565b612b429190614b29565b612b4c9190614b56565b9050600060068386612b5e898c614b29565b612b689190614b29565b612b729190614b29565b612b7c9190614b56565b9050676765c793fa10079d601b1b8183612b968b8b614b29565b612bab90676765c793fa10079d601b1b614d5f565b612bb59190614d5f565b612bbf9190614d5f565b603f54612bcc9190614b29565b612bd69190614b56565b9850505050505050505090565b612beb6140f9565b6000806000612bfb888787613951565b925092509250633b9aca008310612c25576040516315fe9b6160e21b815260040160405180910390fd5b6000633b9aca00612c368582614d4c565b612c3f8a6139dd565b612c499190614b29565b612c539190614b56565b603d54909150600160801b90046001600160401b0316811015612c8357612c7e81633b9aca00614d4c565b612ca4565b603d54612ca490600160801b90046001600160401b0316633b9aca00614d4c565b603d54909150600160401b90046001600160401b0316600080612ccc6002633b9aca00614e88565b603c54612ce291906001600160401b0316614b29565b83612ced868a614b29565b612cf79190614b29565b10612e7c57603c546001600160401b0316612d176002633b9aca00614e88565b612d219190614b29565b603c548590612d4090600160401b90046001600160401b031686614b29565b612d4a9190614b29565b612d549190614d4c565b603c548590633b9aca0090612d72906001600160401b031689614b29565b603c54612d90908b90600160401b90046001600160401b0316614b29565b612d9a9190614d4c565b612da49190614b29565b612dae9190614b29565b612db89190614b56565b60b654909250612dcc633b9aca0082614b29565b612dd68585614b29565b612de09190614d5f565b612dee633b9aca0089614b29565b11612e7657612e08676765c793fa10079d601b1b85614b29565b633b9aca008b8f60200151612e1d9190614b29565b612e279190614b29565b612e319190614b56565b612e3c906001614d5f565b925080871115612e715783633b9aca00612e56838a614d4c565b612e609190614b29565b612e6a9190614b56565b9150612e76565b600191505b50612efa565b603854612e8d90633b9aca00614b29565b8c518b90612e9c908790614b29565b612ea69190614b29565b612eb09190614b56565b612ebb906001614d5f565b915060b554851115612ef657633b9aca008460b55487612edb9190614d4c565b612ee59190614b29565b612eef9190614b56565b9050612efa565b5060015b818852612f07848b614b29565b603854612f18633b9aca0085614b29565b612f229190614b29565b612f2c9190614b56565b602089015260408801525050606085015250608083015250949350505050565b60808054608154604080517f8b73c3c69bb8fe3d512ecc4cf759cc79239f7b179b0ffacaa9a75d522b39400f602082015290810192909252606082015246918101919091523060a082015260009060c00160405160208183030381529060405280519060200120905090565b6000612fc2612a4e565b90506000676765c793fa10079d601b1b603f5483612fe09190614d4c565b604054612fed9190614b29565b612ff79190614b56565b9050806041600082825461300b9190614d5f565b9091555050603f82905542603e8190556040805184815260208101929092527fd1fa8ba00a3bf20274346919dce0de62d2a140af2c71fe7e29fa6472eea3bb9d910160405180910390a15090565b60008160000361306e5761306b612fb8565b91505b60008481526043602052604081206001015490676765c793fa10079d601b1b6130978584614b29565b6130a19190614b56565b90508085106130b2579350806130d5565b836130c8676765c793fa10079d601b1b87614b29565b6130d29190614b56565b90505b6130df8183614d4c565b915080604060008282546130f39190614d4c565b909155505081158015906131285750676765c793fa10079d601b1b60b45461311b9190614b29565b6131258584614b29565b11155b156131465760405163228af07f60e21b815260040160405180910390fd5b60008681526043602052604080822060010184905551600080516020615124833981519152916131799189918591614d72565b60405180910390a15092949350505050565b85156131a8576034546131a8906001600160a01b031684886138ee565b8415611952578051156132275760345460355460405163a5d4096b60e01b81526001600160a01b038086169363a5d4096b936131f49391831692169089908b908d908990600401615052565b600060405180830381600087803b15801561320e57600080fd5b505af1158015613222573d6000803e3d6000fd5b505050505b603554604051630d43af8160e21b81526001600160a01b039091169063350ebe049061325b9088908890339060040161501a565b600060405180830381600087803b15801561327557600080fd5b505af1158015613289573d6000803e3d6000fd5b50505050505050505050565b826001600160a01b0316826001600160a01b0316036132c7576040516320c5195360e21b815260040160405180910390fd5b6000816132d55760006132d8565b60015b6001600160a01b038581166000818152604a602090815260408083209489168084529482529182902060ff959095169485905590518615158152939450919290917f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c31910160405180910390a350505050565b60006001600160a01b0382166133735760405163d92e233d60e01b815260040160405180910390fd5b5060458054600101908190556001600160a01b038216600081815260486020908152604080832080546001019055848352604790915280822080546001600160a01b031916841790555183929190600080516020615164833981519152908290a46133f06000838360405180602001604052806000815250613c0c565b611918576040516320149b4360e21b815260040160405180910390fd5b613418848484612977565b61342484848484613c0c565b613441576040516320149b4360e21b815260040160405180910390fd5b50505050565b6134508261281d565b61346d5760405163062a39dd60e11b815260040160405180910390fd5b6000828152604360205260408120805483929061348b908490614d5f565b909155505060405160008051602061514483398151915290610f289084908490600190614d72565b60008033856134c282826128f9565b6134df5760405163c19f17a960e01b815260040160405180910390fd5b600087815260436020908152604080832081518083019092528054825260010154918101919091529080613514838a8a613951565b5091509150633b9aca00821161353d57604051631527804d60e31b815260040160405180910390fd5b8260200151604060008282546135539190614d4c565b9091555061356290508a613d12565b600061357281633b9aca00614d4c565b613580633b9aca0084614b29565b61358a9190614b56565b90506135968282614d4c565b604160008282546135a79190614d5f565b90915550509251929a92995091975050505050505050565b33846135cb82826128f9565b6135e85760405163c19f17a960e01b815260040160405180910390fd5b60008681526043602052604081208054879290613606908490614d4c565b90915550506000868152604360209081526040808320815180830190925280548252600101549181019190915261363e908686613951565b50509050633b9aca00811161366657604051631527804d60e31b815260040160405180910390fd5b6000805160206151448339815191528787600060405161368893929190614d72565b60405180910390a150505050505050565b600033856136a782826128f9565b6136c45760405163c19f17a960e01b815260040160405180910390fd5b6136d087878787613d91565b603c54909650600090633b9aca00906136fa908990600160801b90046001600160401b0316614b29565b6137049190614b56565b905080604160008282546137189190614d5f565b9091555061372890508188614d4c565b98975050505050505050565b338661374082826128f9565b61375d5760405163c19f17a960e01b815260040160405180910390fd5b60408051898152602081018890526001600160a01b038916818301526060810187905290517fddd3b70af631334f7552aadb582ed091018e62e103fa8b150ca66cc700d4dac69181900360800190a16137b888868686613d91565b9450306001600160a01b038816036137db576137d5868685613059565b506117ed565b866001600160a01b031663835986b48787603c60109054906101000a90046001600160401b031661380a600090565b6040516001600160e01b031960e087901b168152600481019490945260248401929092526001600160401b039081166044840152166064820152608401600060405180830381600087803b15801561386157600080fd5b505af1158015613875573d6000803e3d6000fd5b505050505050505050505050565b6040516001600160a01b03808516602483015283166044820152606481018290526134419085906323b872dd60e01b906084015b60408051601f198184030181529190526020810180516001600160e01b03166001600160e01b031990931692909217909152613f25565b6109ea8363a9059cbb60e01b84846040516024016138b7929190615039565b6001600160a01b0381166000908152607f6020526040902054613931816001614d5f565b6001600160a01b039092166000908152607f602052604090209190915590565b6000806000676765c793fa10079d601b1b8487602001516139729190614b29565b61397c9190614b56565b91506038548587600001516139919190614b29565b61399b9190614b56565b9050816000036139af5760001992506139d4565b603c5482906139c7906001600160401b031683614b29565b6139d19190614b56565b92505b93509350939050565b6037546000906001600160a01b0316613a1657603b600081548110613a0457613a04614c8c565b90600052602060002001549050919050565b603754604051635dfba04560e11b81526000916001600160a01b03169063bbf7408a90613a479086906004016141b0565b602060405180830381865afa158015613a64573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613a889190614afa565b9050603a600181548110613a9e57613a9e614c8c565b90600052602060002001548110613ad657603b600181548110613ac357613ac3614c8c565b9060005260206000200154915050919050565b603a600081548110613aea57613aea614c8c565b90600052602060002001548111613b0f57603b600081548110613ac357613ac3614c8c565b603a600081548110613b2357613b23614c8c565b9060005260206000200154603a600181548110613b4257613b42614c8c565b9060005260206000200154613b579190614d4c565b603a600081548110613b6b57613b6b614c8c565b906000526020600020015482613b819190614d4c565b603b600081548110613b9557613b95614c8c565b9060005260206000200154603b600181548110613bb457613bb4614c8c565b9060005260206000200154613bc99190614d4c565b613bd39190614b29565b613bdd9190614b56565b603b600081548110613bf157613bf1614c8c565b9060005260206000200154610ace9190614d5f565b50919050565b6000613c20846001600160a01b031661280e565b15613d0a57604051630a85bd0160e11b81526001600160a01b0385169063150b7a0290613c579033908990889088906004016150ca565b6020604051808303816000875af1925050508015613c92575060408051601f3d908101601f19168201909252613c8f918101906150ad565b60015b613cf0573d808015613cc0576040519150601f19603f3d011682016040523d82523d6000602084013e613cc5565b606091505b508051600003613ce8576040516320149b4360e21b815260040160405180910390fd5b805181602001fd5b6001600160e01b031916630a85bd0160e11b149050611831565b506001611831565b6000613d1d82612855565b9050613d2a60008361288b565b6001600160a01b038116600081815260486020908152604080832080546000190190558583526047825280832080546001600160a01b0319169055604390915280822082815560010182905551849290600080516020615164833981519152908390a45050565b60008082613daa676765c793fa10079d601b1b87614b29565b613db49190614b56565b60008781526043602052604081206001015491925003613df05760b4548511613df05760405163228af07f60e21b815260040160405180910390fd5b60008681526043602052604081206001018054839290613e11908490614d5f565b925050819055508060406000828254613e2a9190614d5f565b9091555050603954613e4890676765c793fa10079d601b1b90614b29565b83604054613e569190614b29565b1115613e75576040516371239a6160e11b815260040160405180910390fd5b60008681526043602090815260408083208151808301909252805482526001015491810191909152613ea8908686613951565b50509050633b9aca008111613ed057604051631527804d60e31b815260040160405180910390fd5b60008051602061512483398151915287836001604051613ef293929190614d72565b60405180910390a1676765c793fa10079d601b1b613f108584614b29565b613f1a9190614b56565b979650505050505050565b6000613f7a826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564815250856001600160a01b0316613ff79092919063ffffffff16565b8051909150156109ea5780806020019051810190613f989190614b6a565b6109ea5760405162461bcd60e51b815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e6044820152691bdd081cdd58d8d9595960b21b606482015260840161114f565b606061183184846000858561400b8561280e565b6140575760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e7472616374000000604482015260640161114f565b600080866001600160a01b031685876040516140739190615107565b60006040518083038185875af1925050503d80600081146140b0576040519150601f19603f3d011682016040523d82523d6000602084013e6140b5565b606091505b5091509150613f1a828286606083156140cf575081610ace565b8251156140df5782518084602001fd5b8160405162461bcd60e51b815260040161114f9190614247565b6040518060a0016040528060008152602001600081526020016000815260200160008152602001600081525090565b828054828255906000526020600020908101928215614163579160200282015b82811115614163578251825591602001919060010190614148565b5061416f92915061419b565b5090565b6040518060800160405280600081526020016000815260200160008152602001600081525090565b5b8082111561416f576000815560010161419c565b6001600160a01b0391909116815260200190565b6001600160e01b03198116811461044e57600080fd5b6000602082840312156141ec57600080fd5b8135610ace816141c4565b60005b838110156142125781810151838201526020016141fa565b50506000910152565b600081518084526142338160208601602086016141f7565b601f01601f19169290920160200192915050565b602081526000610ace602083018461421b565b60006020828403121561426c57600080fd5b5035919050565b6001600160a01b038116811461044e57600080fd5b6000806040838503121561429b57600080fd5b82356142a681614273565b946020939093013593505050565b6000806000606084860312156142c957600080fd5b83356142d481614273565b925060208401356142e481614273565b929592945050506040919091013590565b6000806040838503121561430857600080fd5b82359150602083013561431a81614273565b809150509250929050565b60a0810161089e828480518252602081015160208301526040810151604083015260608101516060830152608081015160808301525050565b60006020828403121561437057600080fd5b8135610ace81614273565b634e487b7160e01b600052604160045260246000fd5b604051601f8201601f191681016001600160401b03811182821017156143b9576143b961437b565b604052919050565b600082601f8301126143d257600080fd5b81356001600160401b038111156143eb576143eb61437b565b6143fe601f8201601f1916602001614391565b81815284602083860101111561441357600080fd5b816020850160208301376000918101602001919091529392505050565b60006020828403121561444257600080fd5b81356001600160401b0381111561445857600080fd5b611831848285016143c1565b6000806040838503121561447757600080fd5b82356001600160401b03811681146142a657600080fd5b60006001600160401b038211156144a7576144a761437b565b5060051b60200190565b600082601f8301126144c257600080fd5b813560206144d76144d28361448e565b614391565b82815260059290921b840181019181810190868411156144f657600080fd5b8286015b8481101561451157803583529183019183016144fa565b509695505050505050565b60008060006060848603121561453157600080fd5b833561453c81614273565b925060208401356001600160401b038082111561455857600080fd5b614564878388016144b1565b9350604086013591508082111561457a57600080fd5b50614587868287016144b1565b9150509250925092565b60008060008060008060c087890312156145aa57600080fd5b86356001600160401b03808211156145c157600080fd5b6145cd8a838b016144b1565b975060208901359150808211156145e357600080fd5b6145ef8a838b016144b1565b96506040890135915061460182614273565b90945060608801359061461382614273565b90935060808801359061462582614273565b90925060a0880135908082111561463b57600080fd5b5061464889828a016143c1565b9150509295509295509295565b6000806000806080858703121561466b57600080fd5b5050823594602084013594506040840135936060013592509050565b600082601f83011261469857600080fd5b813560206146a86144d28361448e565b82815260059290921b840181019181810190868411156146c757600080fd5b8286015b84811015614511578035600881106146e35760008081fd5b83529183019183016146cb565b600082601f83011261470157600080fd5b813560206147116144d28361448e565b82815260059290921b8401810191818101908684111561473057600080fd5b8286015b848110156145115780356001600160401b038111156147535760008081fd5b6147618986838b01016143c1565b845250918301918301614734565b6000806000806080858703121561478557600080fd5b84356001600160401b038082111561479c57600080fd5b6147a888838901614687565b955060208701359150808211156147be57600080fd5b506147cb878288016146f0565b93505060408501356147dc81614273565b915060608501356147ec81614273565b939692955090935050565b801515811461044e57600080fd5b6000806040838503121561481857600080fd5b823561482381614273565b9150602083013561431a816147f7565b6000806000806080858703121561484957600080fd5b843561485481614273565b9350602085013561486481614273565b92506040850135915060608501356001600160401b0381111561488657600080fd5b614892878288016143c1565b91505092959194509250565b6000806000606084860312156148b357600080fd5b505081359360208301359350604090920135919050565b60008060008060008587036101808112156148e457600080fd5b86356148ef81614273565b955060208701356148ff81614273565b9450604087013561490f81614273565b9350610100605f198201121561492457600080fd5b506060860191506101608601356001600160401b0381111561494557600080fd5b614951888289016143c1565b9150509295509295909350565b60008060008060008060c0878903121561497757600080fd5b86356001600160401b038082111561498e57600080fd5b61499a8a838b01614687565b975060208901359150808211156149b057600080fd5b6145ef8a838b016146f0565b600080604083850312156149cf57600080fd5b82356149da81614273565b9150602083013561431a81614273565b600080600080600080600060e0888a031215614a0557600080fd5b8735614a1081614273565b96506020880135614a2081614273565b95506040880135614a30816147f7565b945060608801359350608088013560ff81168114614a4d57600080fd5b9699959850939692959460a0840135945060c09093013592915050565b60008060008060808587031215614a8057600080fd5b84356001600160401b0380821115614a9757600080fd5b614aa3888389016144b1565b95506020870135915080821115614ab957600080fd5b506147cb878288016144b1565b600181811c90821680614ada57607f821691505b602082108103613c0657634e487b7160e01b600052602260045260246000fd5b600060208284031215614b0c57600080fd5b5051919050565b634e487b7160e01b600052601160045260246000fd5b808202811582820484141761089e5761089e614b13565b634e487b7160e01b600052601260045260246000fd5b600082614b6557614b65614b40565b500490565b600060208284031215614b7c57600080fd5b8151610ace816147f7565b601f8211156109ea57600081815260208120601f850160051c81016020861015614bae5750805b601f850160051c820191505b8181101561195257828155600101614bba565b81516001600160401b03811115614be657614be661437b565b614bfa81614bf48454614ac6565b84614b87565b602080601f831160018114614c2f5760008415614c175750858301515b600019600386901b1c1916600185901b178555611952565b600085815260208120601f198616915b82811015614c5e57888601518255948401946001909101908401614c3f565b5085821015614c7c5787850151600019600388901b60f8161c191681555b5050505050600190811b01905550565b634e487b7160e01b600052603260045260246000fd5b600081518084526020808501945080840160005b83811015614cd257815187529582019590820190600101614cb6565b509495945050505050565b604081526000614cf06040830185614ca2565b8281036020840152611b648185614ca2565b6020808252601f908201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c00604082015260600190565b602081526000610ace6020830184614ca2565b8181038181111561089e5761089e614b13565b8082018082111561089e5761089e614b13565b928352602083019190915260ff16604082015260600190565b600060018201614d9d57614d9d614b13565b5060010190565b600181815b80851115614ddf578160001904821115614dc557614dc5614b13565b80851615614dd257918102915b93841c9390800290614da9565b509250929050565b600082614df65750600161089e565b81614e035750600061089e565b8160018114614e195760028114614e2357614e3f565b600191505061089e565b60ff841115614e3457614e34614b13565b50506001821b61089e565b5060208310610133831016604e8410600b8410161715614e62575081810a61089e565b614e6c8383614da4565b8060001904821115614e8057614e80614b13565b029392505050565b6000610ace60ff841683614de7565b600082614ea657614ea6614b40565b500690565b6000808454614eb981614ac6565b60018281168015614ed15760018114614ee657614f15565b60ff1984168752821515830287019450614f15565b8860005260208060002060005b85811015614f0c5781548a820152908401908201614ef3565b50505082870194505b505050508351614f298183602088016141f7565b01949350505050565b634e487b7160e01b600052602160045260246000fd5b600060208284031215614f5a57600080fd5b8151610ace81614273565b60008060408385031215614f7857600080fd5b505080516020909101519092909150565b60008060008060008060c08789031215614fa257600080fd5b8651614fad81614273565b6020880151604089015160608a015160808b015160a0909b0151939c929b509099909850965090945092505050565b60008060008060808587031215614ff257600080fd5b84519350602085015161500481614273565b6040860151606090960151949790965092505050565b9283526001600160a01b03918216602084015216604082015260600190565b6001600160a01b03929092168252602082015260400190565b6001600160a01b038781168252868116602083015285166040820152606081018490526080810183905260c060a082018190526000906137289083018461421b565b828152604060208201526000611831604083018461421b565b6000602082840312156150bf57600080fd5b8151610ace816141c4565b6001600160a01b03858116825284166020820152604081018390526080606082018190526000906150fd9083018461421b565b9695505050505050565b600082516151198184602087016141f7565b919091019291505056fe70cf49afe7355562d5b022e594790f22b71ad8cc7eec902fa5feac7c67f71091722cb71fa87c947148cefc06dd890af5802a6a00207c5ddecf1191bf71ce3cd4ddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3efa2646970667358221220e59f94ab826df3aef4dcca1c7263b3c9c4cf503c792ab064f746ab7df9344dde64736f6c63430008110033" - ); - - VaultParameters internal _vmParams = - VaultParameters({ - debtCeiling: 10 ** 9 * BASE_18, - collateralFactor: uint64(BASE_PARAMS / 2), - targetHealthFactor: uint64((BASE_PARAMS * 105) / 100), - interestRate: uint64(BASE_PARAMS / 10), - liquidationSurcharge: uint64((BASE_PARAMS * 99) / 100), - maxLiquidationDiscount: uint64(BASE_PARAMS / 10), - whitelistingActivated: false, - baseBoost: BASE_PARAMS - }); - - AgTokenSideChainImmutable internal _agToken; - MockTreasuryImmutable internal _treasury; - VaultManagerLiquidationBoostImmutable internal _vault; - IERC20 internal _collateral; - MockOracle internal _oracle; - uint8 public decimalToken = 18; - - string constant _NAME = "Angle stablecoin gold"; - string constant _SYMBOL = "agGold"; - - function setUp() public override { - super.setUp(); - - _treasury = new MockTreasuryImmutable(ICoreBorrow(coreBorrow)); - _agToken = new AgTokenSideChainImmutable(_NAME, _SYMBOL, address(_treasury)); - _collateral = new MockTokenPermit("Mock", "MCK", decimalToken); - _oracle = new MockOracle(BASE_18, ITreasury(address(_treasury))); - _vault = new VaultManagerLiquidationBoostImmutable( - ITreasury(address(_treasury)), - _collateral, - _oracle, - _vmParams, - "MockVM" - ); - - vm.startPrank(_GOVERNOR); - _treasury.setStablecoin(_agToken); - _treasury.setVaultManagerImpl(_hashVM); - _treasury.addVaultManager(address(_vault)); - vm.stopPrank(); - } - - // ================================= INITIALIZE ================================ - - function testConstructor() public { - assertEq(_agToken.name(), _NAME); - assertEq(_agToken.symbol(), _SYMBOL); - assertEq(_agToken.decimals(), 18); - assertEq(_agToken.treasury(), address(_treasury)); - assertEq(address(_treasury.core()), address(coreBorrow)); - assertEq(address(_treasury.stablecoin()), address(_agToken)); - assertEq(_treasury.vaultManagerMap(address(_vault)), 1); - assertEq(address(_treasury.vaultManagerList(0)), address(_vault)); - assertTrue(_agToken.isMinter(address(_vault))); - vm.expectRevert(); - assertEq(address(_treasury.vaultManagerList(1)), address(0)); - } - - function testAlreadyInitalizeFail() public { - MockCoreBorrow coreBorrowBis = new MockCoreBorrow(); - AgTokenSideChainImmutable agTokenBis = new AgTokenSideChainImmutable(_NAME, _SYMBOL, address(_treasury)); - _treasury.initialize(ICoreBorrow(coreBorrowBis), agTokenBis); - - assertEq(address(_treasury.core()), address(coreBorrow)); - assertEq(address(_treasury.stablecoin()), address(_agToken)); - } - - // =============================== SETSTABLECOIN =============================== - - function testSetStablecoinWrongCaller() public { - vm.prank(_alice); - vm.expectRevert(Treasury.NotGovernor.selector); - _treasury.setStablecoin(_agToken); - } - - function testSetStablecoinTwiceFail() public { - vm.prank(_GOVERNOR); - vm.expectRevert(TreasuryImmutable.InvalidStablecoin.selector); - _treasury.setStablecoin(_agToken); - } - - function testSetWrongStablecoin() public { - MockTreasuryImmutable treasuryBis = new MockTreasuryImmutable(ICoreBorrow(coreBorrow)); - - vm.prank(_GOVERNOR); - vm.expectRevert(TreasuryImmutable.InvalidStablecoin.selector); - treasuryBis.setStablecoin(_agToken); - } - - function testSetStablecoinZeroAddress() public { - MockTreasuryImmutable treasuryBis = new MockTreasuryImmutable(ICoreBorrow(coreBorrow)); - - vm.prank(_GOVERNOR); - vm.expectRevert(); - treasuryBis.setStablecoin(IAgToken(address(0))); - } - - // ============================== ADDVAULTMANAGER ============================== - - function testAddVaultManagerSuccess() public { - IERC20 collateralBis = new MockTokenPermit("Mock Bis", "MCKB", decimalToken + 2); - MockOracle oracleBis = new MockOracle(BASE_18, ITreasury(address(_treasury))); - - VaultManagerLiquidationBoostImmutable vaultBis = new VaultManagerLiquidationBoostImmutable( - ITreasury(address(_treasury)), - collateralBis, - oracleBis, - _vmParams, - "MockVM" - ); - vm.prank(_GOVERNOR); - _treasury.addVaultManager(address(vaultBis)); - - assertEq(_treasury.vaultManagerMap(address(vaultBis)), 1); - assertEq(address(_treasury.vaultManagerList(0)), address(_vault)); - assertEq(address(_treasury.vaultManagerList(1)), address(vaultBis)); - assertTrue(_agToken.isMinter(address(vaultBis))); - vm.expectRevert(); - assertEq(address(_treasury.vaultManagerList(2)), address(0)); - } - - function testAddVaultManagerWrongCaller(address account) public { - vm.assume(account != _GOVERNOR); - VaultManagerLiquidationBoostImmutable vaultBis = new VaultManagerLiquidationBoostImmutable( - ITreasury(address(_treasury)), - _collateral, - _oracle, - _vmParams, - "MockVM" - ); - vm.prank(account); - vm.expectRevert(Treasury.NotGovernor.selector); - _treasury.addVaultManager(address(vaultBis)); - } - - function testAddIncorrectVaultManagerDifferentFunction() public { - MockIncorrectVaultManagerLiquidationBoostImmutable vaultBis = new MockIncorrectVaultManagerLiquidationBoostImmutable( - ITreasury(address(_treasury)), - _collateral, - _oracle, - _vmParams, - "MockVM" - ); - vm.prank(_GOVERNOR); - vm.expectRevert(TreasuryImmutable.InvalidVaultManager.selector); - _treasury.addVaultManager(address(vaultBis)); - } - - function testAddIncorrectVaultManagerDifferentConstructor() public { - MockCorrectVaultManagerLiquidationBoostImmutable vaultBis = new MockCorrectVaultManagerLiquidationBoostImmutable( - ITreasury(address(_treasury)), - _collateral, - _oracle, - _vmParams, - "MockVM" - ); - vm.prank(_GOVERNOR); - vm.expectRevert(TreasuryImmutable.InvalidVaultManager.selector); - _treasury.addVaultManager(address(vaultBis)); - } - - // ============================== EMPTY FUNCTIONS ============================== - function testNoImplementationAddMinter() public { - _treasury.addMinter(_alice); - assertFalse(_agToken.isMinter(_alice)); - } - - function testNoImplementationRemoveMinter() public { - _treasury.removeMinter(address(_vault)); - assertTrue(_agToken.isMinter(address(_vault))); - } - - function testNoImplementationSetTreasury() public { - MockTreasuryImmutable treasuryBis = new MockTreasuryImmutable(ICoreBorrow(coreBorrow)); - - _treasury.setTreasury(address(treasuryBis)); - assertEq(address(_agToken.treasury()), (address(_treasury))); - assertEq(address(_vault.treasury()), (address(_treasury))); - } -} -*/ diff --git a/test/foundry/vaultManager/VaultManager.t.sol b/test/foundry/vaultManager/VaultManager.t.sol index 2b34d744..d715cfb9 100644 --- a/test/foundry/vaultManager/VaultManager.t.sol +++ b/test/foundry/vaultManager/VaultManager.t.sol @@ -6,7 +6,6 @@ import { stdStorage, StdStorage, Test } from "forge-std/Test.sol"; import { VaultManager, VaultManagerStorage } from "../../../contracts/vaultManager/VaultManager.sol"; import { ActionType, VaultParameters } from "../../../contracts/interfaces/IVaultManager.sol"; import { Treasury } from "../../../contracts/treasury/Treasury.sol"; -import { MockStableMaster } from "../../../contracts/mock/MockStableMaster.sol"; import "../../../contracts/mock/MockOracle.sol"; import "../../../contracts/mock/MockToken.sol"; import { CoreBorrow } from "../../../contracts/coreBorrow/CoreBorrow.sol"; @@ -20,7 +19,6 @@ contract VaultManagerTest is Test { address internal _governor = address(uint160(uint256(keccak256(abi.encodePacked("governor"))))); address internal _guardian = address(uint160(uint256(keccak256(abi.encodePacked("guardian"))))); - MockStableMaster internal _contractStableMaster; VaultManager internal _contractVaultManager; CoreBorrow internal _contractCoreBorrow; Treasury internal _contractTreasury; @@ -30,20 +28,18 @@ contract VaultManagerTest is Test { MockOracle internal _oracle; function setUp() public virtual { - _contractStableMaster = new MockStableMaster(); - - _contractAgToken = new AgToken(); - vm.store(address(_contractAgToken), bytes32(uint256(0)), bytes32(uint256(0))); - _contractAgToken.initialize("agEUR", "agEUR", address(_contractStableMaster)); - _contractCoreBorrow = new CoreBorrow(); vm.store(address(_contractCoreBorrow), bytes32(uint256(0)), bytes32(uint256(0))); _contractCoreBorrow.initialize(_governor, _guardian); _contractTreasury = new Treasury(); + _contractAgToken = new AgToken(); vm.store(address(_contractTreasury), bytes32(uint256(0)), bytes32(uint256(0))); _contractTreasury.initialize(_contractCoreBorrow, _contractAgToken); + vm.store(address(_contractAgToken), bytes32(uint256(0)), bytes32(uint256(0))); + _contractAgToken.initialize("agEUR", "agEUR", address(_contractTreasury)); + _oracle = new MockOracle(5 ether, _contractTreasury); _collateral = new MockToken("Name", "SYM", 18); @@ -62,9 +58,6 @@ contract VaultManagerTest is Test { }); _contractVaultManager.initialize(_contractTreasury, _collateral, _oracle, params, "wETH"); - vm.prank(0xdC4e6DFe07EFCa50a197DF15D9200883eF4Eb1c8); - _contractAgToken.setUpTreasury(address(_contractTreasury)); - vm.startPrank(_governor); _contractVaultManager.togglePause(); _contractTreasury.addVaultManager(address(_contractVaultManager)); diff --git a/test/foundry/vaultManager/VaultManagerLiquidationBoostImmutableTest.test.sol b/test/foundry/vaultManager/VaultManagerLiquidationBoostImmutableTest.test.sol deleted file mode 100644 index 8aef73e1..00000000 --- a/test/foundry/vaultManager/VaultManagerLiquidationBoostImmutableTest.test.sol +++ /dev/null @@ -1,184 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity ^0.8.17; - -import { stdStorage, StdStorage } from "forge-std/Test.sol"; -import "../BaseTest.test.sol"; -import "../../../contracts/mock/MockOracle.sol"; -import "../../../contracts/mock/MockTreasury.sol"; -import "../../../contracts/mock/MockTokenPermit.sol"; -import { MockTreasuryImmutable, TreasuryImmutable, Treasury } from "../../../contracts/mock/MockTreasuryImmutable.sol"; -import { IAgToken, AgTokenSideChainImmutable } from "../../../contracts/agToken/AgTokenSideChainImmutable.sol"; -import { VaultManagerLiquidationBoostImmutable, VaultParameters, VaultManagerStorage } from "../../../contracts/vaultManager/VaultManagerLiquidationBoostImmutable.sol"; -/* -contract VaultManagerLiquidationBoostImmutableTest is BaseTest { - using stdStorage for StdStorage; - - address internal _hacker = address(uint160(uint256(keccak256(abi.encodePacked("hacker"))))); - // you should repace with latest "deployedBytecode" from `VaultManagerLiquidationBoostImmutable` - bytes32 internal _hashVM = - keccak256( - hex"608060405234801561001057600080fd5b50600436106103015760003560e01c8063010db1951461030657806301ffc9a71461032f57806306fdde0314610352578063081812fc14610367578063087a60071461037a578063095ea7b3146103915780630e198f22146103a657806313888565146103af57806323b872dd146103b8578063254cf439146103cb578063307439af146103fd57806334ce998a1461041d57806335836f15146104255780633644e5151461043857806339393ac91461044057806339eb4dc6146104515780633ae2325f146104655780633af32abf146104785780633c2e941b1461049857806342842e0e146104a1578063430c2081146104b45780634f7e43df146104c757806355f804b3146104e15780635c975abb146104f457806361d027b3146105085780636352211e1461051b57806370a082311461052e57806374107543146105415780637aacfffa146105545780637adbf973146104405780637c0f59f4146105905780637c3a00fd146105aa5780637dc0d1d0146105bd5780637e53bd97146105d05780637e56d47c146105e35780637ecebe00146105f6578063835986b41461061f57806389050f1d1461063257806395d89b41146106445780639a3b6f2f1461064c5780639f48118f14610692578063a22cb4651461069d578063af2c8c2e146106b0578063b1511cc9146106b9578063b4bd6f46146106cc578063b88d4fde146106df578063bbcac557146106f2578063bfc7ad2e146106fb578063c13cacae14610704578063c4ae3168146103a4578063c66d8b0114610717578063c87b56dd14610731578063d8dfeb4514610744578063d9b1cb5b14610757578063de1f77651461076c578063de8fc6981461077e578063df011c4114610791578063e182b883146107a4578063e1c84ea4146107b7578063e626648a146107c0578063e985e9c5146107da578063e9cbd822146107ed578063f0f4426014610440578063f51cc7dd14610800578063fad9aba314610813578063fc29b0211461081c578063fd527cf81461082f575b600080fd5b603754610319906001600160a01b031681565b60405161032691906141b0565b60405180910390f35b61034261033d3660046141da565b610837565b6040519015158152602001610326565b61035a6108a4565b6040516103269190614247565b61031961037536600461425a565b610932565b610383603f5481565b604051908152602001610326565b6103a461039f366004614288565b610963565b005b610383603e5481565b61038360415481565b6103a46103c63660046142b4565b6109ef565b603c546103e590600160401b90046001600160401b031681565b6040516001600160401b039091168152602001610326565b61041061040b3660046142f5565b610a23565b6040516103269190614325565b610383610ad5565b61038361043336600461425a565b610b07565b610383610b43565b6103a461044e36600461435e565b50565b603d5461034290600160c01b900460ff1681565b61038361047336600461425a565b610b4d565b61038361048636600461435e565b60446020526000908152604090205481565b61038360455481565b6103a46104af3660046142b4565b610b6e565b6103426104c2366004614288565b610b89565b603d546103e590600160801b90046001600160401b031681565b6103a46104ef366004614430565b610b95565b603d5461034290600160c81b900460ff1681565b603354610319906001600160a01b031681565b61031961052936600461425a565b610c33565b61038361053c36600461435e565b610c3e565b6103a461054f366004614464565b610c83565b61057b61056236600461425a565b6043602052600090815260409020805460019091015482565b60408051928352602083019190915201610326565b603c546103e590600160c01b90046001600160401b031681565b603d546103e5906001600160401b031681565b603654610319906001600160a01b031681565b6103a46105de36600461451c565b610f34565b6104106105f1366004614591565b611125565b61038361060436600461435e565b6001600160a01b03166000908152607f602052604090205490565b6103a461062d366004614655565b6116a6565b610383676765c793fa10079d601a1b81565b61035a6117f7565b61065f61065a36600461476f565b611804565b60405161032691908151815260208083015190820152604080830151908201526060918201519181019190915260800190565b610383633b9aca0081565b6103a46106ab366004614805565b611839565b61038360405481565b6103a46106c736600461425a565b611844565b6103836106da36600461435e565b61190d565b6103a46106ed366004614833565b61191d565b61038360425481565b61038360b65481565b6103a461071236600461489e565b61195a565b603d546103e590600160401b90046001600160401b031681565b61035a61073f36600461425a565b611a17565b603454610319906001600160a01b031681565b6103a46107653660046148ca565b5050505050565b610383676765c793fa10079d601b1b81565b61065f61078c36600461495e565b611b6d565b603c546103e5906001600160401b031681565b6103836107b236600461425a565b6123c8565b61038360395481565b603c546103e590600160801b90046001600160401b031681565b6103426107e83660046149bc565b6123d8565b603554610319906001600160a01b031681565b6103a461080e3660046149ea565b612406565b61038360b45481565b61041061082a366004614a6a565b6126c5565b61057b6126ef565b60006001600160e01b03198216635b5e139f60e01b148061086857506001600160e01b031982166380ac58cd60e01b145b8061088357506001600160e01b0319821663430c208160e01b145b8061089e57506001600160e01b031982166301ffc9a760e01b145b92915050565b607d80546108b190614ac6565b80601f01602080910402602001604051908101604052809291908181526020018280546108dd90614ac6565b801561092a5780601f106108ff5761010080835404028352916020019161092a565b820191906000526020600020905b81548152906001019060200180831161090d57829003601f168201915b505050505081565b600061093d8261281d565b61095a5760405163062a39dd60e11b815260040160405180910390fd5b61089e8261283a565b600061096e82612855565b9050806001600160a01b0316836001600160a01b0316036109a2576040516349fa8bc360e11b815260040160405180910390fd5b336001600160a01b038216148015906109c257506109c081336123d8565b155b156109e05760405163c19f17a960e01b815260040160405180910390fd5b6109ea838361288b565b505050565b33816109fb82826128f9565b610a185760405163c19f17a960e01b815260040160405180910390fd5b610765858585612977565b610a2b6140f9565b60008381526043602090815260409182902082518084018452815481526001909101548183015260365483516315f789a960e21b81529351610ace94929387936001600160a01b03909316926357de26a492600480830193928290030181865afa158015610a9d573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610ac19190614afa565b610ac9612a4e565b612be3565b9392505050565b6000676765c793fa10079d601b1b610aeb612a4e565b604054610af89190614b29565b610b029190614b56565b905090565b6000676765c793fa10079d601b1b610b1d612a4e565b600084815260436020526040902060010154610b399190614b29565b61089e9190614b56565b6000610b02612f4c565b603b8181548110610b5d57600080fd5b600091825260209091200154905081565b6109ea8383836040518060200160405280600081525061191d565b6000610ace83836128f9565b60335460405163521d4de960e01b81526001600160a01b039091169063521d4de990610bc59033906004016141b0565b602060405180830381865afa158015610be2573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610c069190614b6a565b610c2357604051632678482f60e21b815260040160405180910390fd5b6046610c2f8282614bcd565b5050565b600061089e82612855565b60006001600160a01b038216610c675760405163d92e233d60e01b815260040160405180910390fd5b506001600160a01b031660009081526048602052604090205490565b60335460405163521d4de960e01b81526001600160a01b039091169063521d4de990610cb39033906004016141b0565b602060405180830381865afa158015610cd0573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610cf49190614b6a565b610d1157604051632678482f60e21b815260040160405180910390fd5b806121a360f11b03610d7457603d546001600160401b03600160401b90910481169083161115610d5457604051637650e96360e11b815260040160405180910390fd5b603c80546001600160401b0319166001600160401b038416179055610eed565b80622a242360e91b03610dd857633b9aca00826001600160401b03161015610daf5760405163da6a17b960e01b815260040160405180910390fd5b603c8054600160401b600160801b031916600160401b6001600160401b03851602179055610eed565b8061212360f11b03610e3b57633b9aca00826001600160401b03161115610e1257604051637650e96360e11b815260040160405180910390fd5b603c8054600160801b600160c01b031916600160801b6001600160401b03851602179055610eed565b806124a960f11b03610e7057610e4f612fb8565b50603d80546001600160401b0319166001600160401b038416179055610eed565b806213531160ea1b03610ed457633b9aca00826001600160401b03161115610eab57604051637650e96360e11b815260040160405180910390fd5b603d8054600160801b600160c01b031916600160801b6001600160401b03851602179055610eed565b60405163e1daa9cf60e01b815260040160405180910390fd5b604080516001600160401b0384168152602081018390527f13b367dac93b85d1ed9b3d8961d8b48e1a677c9800bb1613b4b0416b2d5b61d091015b60405180910390a15050565b60335460405163521d4de960e01b81526001600160a01b039091169063521d4de990610f649033906004016141b0565b602060405180830381865afa158015610f81573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610fa59190614b6a565b610fc257604051632678482f60e21b815260040160405180910390fd5b80518251141580610fed575080600081518110610fe157610fe1614c8c565b60200260200101516000145b8061107c57506001600160a01b0383161580159061107c57508160008151811061101957611019614c8c565b60200260200101518260018151811061103457611034614c8c565b602002602001015111158061107c57508060008151811061105757611057614c8c565b60200260200101518160018151811061107257611072614c8c565b6020026020010151105b1561109a57604051631746545d60e11b815260040160405180910390fd5b603780546001600160a01b0319166001600160a01b03851617905581516110c890603a906020850190614128565b5080516110dc90603b906020840190614128565b50826001600160a01b03167feb74d4d9fea592587c926aeb35eb6a7893fb28db0c1c8eb2eb3c586e7164b76c8383604051611118929190614cdd565b60405180910390a2505050565b61112d6140f9565b6002600154036111585760405162461bcd60e51b815260040161114f90614d02565b60405180910390fd5b6002600155865186518114158061116d575080155b1561118b576040516346282e8d60e01b815260040160405180910390fd5b603660009054906101000a90046001600160a01b03166001600160a01b03166357de26a46040518163ffffffff1660e01b8152600401602060405180830381865afa1580156111de573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906112029190614afa565b606083015261120f612fb8565b60808301526040517f965a177723c641ee49150b583a0b9ad4730bb20d3474e00ae5a65e777c00d67b90611244908a90614d39565b60405180910390a160005b81811015611616576000604360008b848151811061126f5761126f614c8c565b6020026020010151815260200190815260200160002060405180604001604052908160008201548152602001600182015481525050905060006112bc823387606001518860800151612be3565b905080604001516000141580156112f0575080604001518a84815181106112e5576112e5614c8c565b602002602001015110155b80611317575080600001518a848151811061130d5761130d614c8c565b6020026020010151115b156113405780600001518a848151811061133357611333614c8c565b6020026020010181815250505b6000856060015182606001516113569190614b29565b603854633b9aca008d878151811061137057611370614c8c565b60200260200101516113829190614b29565b61138c9190614b29565b6113969190614b56565b90506113c48c85815181106113ad576113ad614c8c565b6020026020010151828560000151111561044e5750565b825181106114fa575081516020830151604080546000906113e6908490614d4c565b92505081905550604360008d868151811061140357611403614c8c565b60209081029190910181015182528101919091526040016000908120818155600101819055603d548c51633b9aca0091600160401b90046001600160401b0316908e908890811061145657611456614c8c565b60200260200101516114689190614b29565b6114729190614b56565b905082608001518110611486576000611496565b8083608001516114969190614d4c565b876040018181516114a79190614d5f565b905250508b51600080516020615124833981519152908d90869081106114cf576114cf614c8c565b6020026020010151846020015160006040516114ed93929190614d72565b60405180910390a16115bb565b80604360008e878151811061151157611511614c8c565b6020026020010151815260200190815260200160002060000160008282546115399190614d4c565b925050819055506115b98c858151811061155557611555614c8c565b6020026020010151633b9aca00603d60089054906101000a90046001600160401b03166001600160401b03168e888151811061159357611593614c8c565b60200260200101516115a59190614b29565b6115af9190614b56565b8860800151613059565b505b80866020018181516115cd9190614d5f565b9052508a518b90859081106115e4576115e4614c8c565b6020026020010151866000018181516115fd9190614d5f565b90525061160f9250839150614d8b9050565b905061124f565b50603d54633b9aca009061163a90600160401b90046001600160401b031682614d4c565b83516116469190614b29565b6116509190614b56565b604160008282546116619190614d5f565b909155505060408201516042805460009061167d908490614d5f565b90915550506020820151825161169791908888888861318b565b50600180559695505050505050565b6033546040516333b52a9f60e11b81526001600160a01b039091169063676a553e906116d69033906004016141b0565b602060405180830381865afa1580156116f3573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906117179190614b6a565b6117345760405163027f480760e01b815260040160405180910390fd5b6000603c54600090600160801b90046001600160401b031684111561177357603c5461177090600160801b90046001600160401b031685614d4c565b90505b60006117846002633b9aca00614e88565b61179283633b9aca00614d4c565b6117a085633b9aca00614d4c565b6117aa9089614b29565b6117b49190614b29565b6117be9190614b56565b90506117ca8187614d4c565b604160008282546117db9190614d5f565b909155506117ed905087826000613059565b5050505050505050565b607e80546108b190614ac6565b61180c614173565b6040805160008082526020820190925261182e91879187918791879190611b6d565b90505b949350505050565b610c2f338383613295565b60335460405163521d4de960e01b81526001600160a01b039091169063521d4de9906118749033906004016141b0565b602060405180830381865afa158015611891573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906118b59190614b6a565b6118d257604051632678482f60e21b815260040160405180910390fd5b60398190556040518181527fdd63b3dcdbebad734892f7c7a26d0f647fbc7eec973e0775f5229018ac4ab47a9060200160405180910390a150565b600061089e8261334a565b919050565b338261192982826128f9565b6119465760405163c19f17a960e01b815260040160405180910390fd5b6119528686868661340d565b505050505050565b603354604051631c86b03760e31b81526001600160a01b039091169063e43581b89061198a9033906004016141b0565b602060405180830381865afa1580156119a7573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906119cb9190614b6a565b6119e857604051633b8d9d7560e21b815260040160405180910390fd5b81831115611a095760405163180d062b60e31b815260040160405180910390fd5b60b49290925560b65560b555565b6060611a228261281d565b611a3f5760405163062a39dd60e11b815260040160405180910390fd5b8160005b8115611a6657611a5281614d8b565b9050611a5f600a83614b56565b9150611a43565b6000816001600160401b03811115611a8057611a8061437b565b6040519080825280601f01601f191660200182016040528015611aaa576020820181803683370190505b5090505b8415611b1557611abf600183614d4c565b9150611acc600a86614e97565b611ad7906030614d5f565b60f81b818381518110611aec57611aec614c8c565b60200101906001600160f81b031916908160001a905350611b0e600a86614b56565b9450611aae565b60468054611b2290614ac6565b9050600003611b405760405180602001604052806000815250611b64565b604681604051602001611b54929190614eab565b6040516020818303038152906040525b95945050505050565b611b75614173565b600260015403611b975760405162461bcd60e51b815260040161114f90614d02565b600260015585518751141580611bac57508651155b15611bca576040516346282e8d60e01b815260040160405180910390fd5b6000806000806000805b8c518110156121315760008d8281518110611bf157611bf1614c8c565b6020026020010151905060006007811115611c0e57611c0e614f32565b816007811115611c2057611c20614f32565b03611c6057611c5a8d8381518110611c3a57611c3a614c8c565b6020026020010151806020019051810190611c559190614f48565b61334a565b50612120565b6002816007811115611c7457611c74614f32565b03611cdd578c8281518110611c8b57611c8b614c8c565b6020026020010151806020019051810190611ca69190614f65565b955092506000839003611cb95760455492505b611cc38386613447565b8488606001818151611cd59190614d5f565b905250612120565b6007816007811115611cf157611cf1614f32565b03611dc95760008060008f8581518110611d0d57611d0d614c8c565b6020026020010151806020019051810190611d289190614f89565b60345460405163d505accf60e01b81526001600160a01b038089166004830152306024830152604482018890526064820187905260ff8616608483015260a4820185905260c48201849052969f50939d50939b509497509550929350169063d505accf9060e401600060405180830381600087803b158015611da957600080fd5b505af1158015611dbd573d6000803e3d6000fd5b50505050505050612120565b86600003611ddc57611dd9612fb8565b96505b6004816007811115611df057611df0614f32565b03611eaa578c8281518110611e0757611e07614c8c565b6020026020010151806020019051810190611e229190614f65565b945092506000839003611e355760455492505b611e40838589613059565b93506000611e5281633b9aca00614d4c565b611e60633b9aca0087614b29565b611e6a9190614b56565b9050611e768582614d4c565b60416000828254611e879190614d5f565b925050819055508089602001818151611ea09190614d5f565b9052506121209050565b85600003611f2c57603660009054906101000a90046001600160a01b03166001600160a01b03166357de26a46040518163ffffffff1660e01b8152600401602060405180830381865afa158015611f05573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611f299190614afa565b95505b6001816007811115611f4057611f40614f32565b03611fbe578c8281518110611f5757611f57614c8c565b6020026020010151806020019051810190611f729190614afa565b925082600003611f825760455492505b611f8d8387896134b3565b80965081955050508488604001818151611fa79190614d5f565b905250602088018051859190611cd5908390614d5f565b6003816007811115611fd257611fd2614f32565b03612035578c8281518110611fe957611fe9614c8c565b60200260200101518060200190518101906120049190614f65565b9550925060008390036120175760455492505b6120238386888a6135bf565b8488604001818151611cd59190614d5f565b600581600781111561204957612049614f32565b036120ae578c828151811061206057612060614c8c565b602002602001015180602001905181019061207b9190614f65565b94509250600083900361208e5760455492505b61209a8385888a613699565b93508388600001818151611cd59190614d5f565b60068160078111156120c2576120c2614f32565b03612120576000808e84815181106120dc576120dc614c8c565b60200260200101518060200190518101906120f79190614fdc565b985091965092509050600085900361210f5760455494505b61211d858383898c8e613734565b50505b5061212a81614d8b565b9050611bd4565b508551602087015110612228578551602087015160009161215191614d4c565b9050866060015187604001511061218857612183876060015188604001516121799190614d4c565b828d8d8d8d61318b565b612222565b80156121f557603554604051630d43af8160e21b81526001600160a01b039091169063350ebe04906121c29084908f90339060040161501a565b600060405180830381600087803b1580156121dc57600080fd5b505af11580156121f0573d6000803e3d6000fd5b505050505b612222333089604001518a6060015161220e9190614d4c565b6034546001600160a01b0316929190613883565b506123b4565b6020860151865160009161223b91614d4c565b6035546040516340c10f1960e01b81529192506001600160a01b0316906340c10f199061226e908d908590600401615039565b600060405180830381600087803b15801561228857600080fd5b505af115801561229c573d6000803e3d6000fd5b505050508660600151876040015111156122e0576122db8a886060015189604001516122c89190614d4c565b6034546001600160a01b031691906138ee565b6123b2565b6000876040015188606001516122f69190614d4c565b905080156123b05788511561239857896001600160a01b031663a5d4096b603560009054906101000a90046001600160a01b0316603460009054906101000a90046001600160a01b03163385878f6040518763ffffffff1660e01b815260040161236596959493929190615052565b600060405180830381600087803b15801561237f57600080fd5b505af1158015612393573d6000803e3d6000fd5b505050505b6034546123b0906001600160a01b0316333084613883565b505b505b505060018055509198975050505050505050565b603a8181548110610b5d57600080fd5b6001600160a01b039182166000908152604a6020908152604080832093909416825291909152205460011490565b834211156124275760405163f87d927160e01b815260040160405180910390fd5b6fa2a8918ca85bafe22016d0b997e4df60600160ff1b0381118061245e57508260ff16601b1415801561245e57508260ff16601c14155b1561247c57604051638baa579f60e01b815260040160405180910390fd5b6000612486612f4c565b6082548989896124958d61390d565b6040805160208101969096526001600160a01b03948516908601529290911660608401521515608083015260a082015260c0810187905260e0016040516020818303038152906040528051906020012060405160200161250c92919061190160f01b81526002810192909252602282015260420190565b604051602081830303815290604052805190602001209050612536886001600160a01b031661280e565b1561261257604080516020810185905280820184905260f886901b6001600160f81b0319166060820152815160418183030181526061820192839052630b135d3f60e11b9092526001600160a01b038a1691631626ba7e9161259c918591606501615094565b602060405180830381865afa1580156125b9573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906125dd91906150ad565b6001600160e01b031916631626ba7e60e01b1461260d57604051638baa579f60e01b815260040160405180910390fd5b6126ba565b6040805160008082526020820180845284905260ff871692820192909252606081018590526080810184905260019060a0016020604051602081039080840390855afa158015612666573d6000803e3d6000fd5b505050602060405103519050886001600160a01b0316816001600160a01b031614158061269a57506001600160a01b038116155b156126b857604051638baa579f60e01b815260040160405180910390fd5b505b6117ed888888613295565b6126cd6140f9565b6040805160008082526020820190925261182e91879187918791879190611125565b60335460009081906001600160a01b0316331461271f5760405163b90cdbb160e01b815260040160405180910390fd5b612727612fb8565b5050604180546042805460009384905592905591508082106127c05761274d8183614d4c565b6035546033546040516340c10f1960e01b8152929450600093506001600160a01b03918216926340c10f19926127899216908690600401615039565b600060405180830381600087803b1580156127a357600080fd5b505af11580156127b7573d6000803e3d6000fd5b505050506127d1565b6127ca8282614d4c565b9050600091505b60408051838152602081018390527ffeb12225c131aab793a00c5239afb778932d170fa28ce6e9d23703e4bd892121910160405180910390a19091565b6001600160a01b03163b151590565b6000908152604760205260409020546001600160a01b0316151590565b6000908152604960205260409020546001600160a01b031690565b6000818152604760205260409020546001600160a01b0316806119185760405163062a39dd60e11b815260040160405180910390fd5b600081815260496020526040902080546001600160a01b0319166001600160a01b03841690811790915581906128c082612855565b6001600160a01b03167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92560405160405180910390a45050565b60008061290583612855565b9050806001600160a01b0316846001600160a01b031614806129405750836001600160a01b03166129358461283a565b6001600160a01b0316145b8061183157506001600160a01b038082166000908152604a6020908152604080832093881683529290522054600114949350505050565b826001600160a01b031661298a82612855565b6001600160a01b0316146129b15760405163c19f17a960e01b815260040160405180910390fd5b6001600160a01b0382166129d85760405163d92e233d60e01b815260040160405180910390fd5b6129e360008261288b565b6001600160a01b038084166000818152604860209081526040808320805460001901905593861680835284832080546001019055858352604790915283822080546001600160a01b0319168217905592518493929160008051602061516483398151915291a4505050565b600080603e5442612a5f9190614d4c565b603d549091506001600160401b0316811580612a79575080155b15612a8857603f549250505090565b6000612a95600184614d4c565b9050600060028411612aa8576000612ab3565b612ab3600285614d4c565b90506000676765c793fa10079d601b1b676765c793fa10079d601a1b612ad98680614b29565b612ae39190614d5f565b612aed9190614b56565b90506000676765c793fa10079d601b1b676765c793fa10079d601a1b612b138785614b29565b612b1d9190614d5f565b612b279190614b56565b90506000600283612b38878a614b29565b612b429190614b29565b612b4c9190614b56565b9050600060068386612b5e898c614b29565b612b689190614b29565b612b729190614b29565b612b7c9190614b56565b9050676765c793fa10079d601b1b8183612b968b8b614b29565b612bab90676765c793fa10079d601b1b614d5f565b612bb59190614d5f565b612bbf9190614d5f565b603f54612bcc9190614b29565b612bd69190614b56565b9850505050505050505090565b612beb6140f9565b6000806000612bfb888787613951565b925092509250633b9aca008310612c25576040516315fe9b6160e21b815260040160405180910390fd5b6000633b9aca00612c368582614d4c565b612c3f8a6139dd565b612c499190614b29565b612c539190614b56565b603d54909150600160801b90046001600160401b0316811015612c8357612c7e81633b9aca00614d4c565b612ca4565b603d54612ca490600160801b90046001600160401b0316633b9aca00614d4c565b603d54909150600160401b90046001600160401b0316600080612ccc6002633b9aca00614e88565b603c54612ce291906001600160401b0316614b29565b83612ced868a614b29565b612cf79190614b29565b10612e7c57603c546001600160401b0316612d176002633b9aca00614e88565b612d219190614b29565b603c548590612d4090600160401b90046001600160401b031686614b29565b612d4a9190614b29565b612d549190614d4c565b603c548590633b9aca0090612d72906001600160401b031689614b29565b603c54612d90908b90600160401b90046001600160401b0316614b29565b612d9a9190614d4c565b612da49190614b29565b612dae9190614b29565b612db89190614b56565b60b654909250612dcc633b9aca0082614b29565b612dd68585614b29565b612de09190614d5f565b612dee633b9aca0089614b29565b11612e7657612e08676765c793fa10079d601b1b85614b29565b633b9aca008b8f60200151612e1d9190614b29565b612e279190614b29565b612e319190614b56565b612e3c906001614d5f565b925080871115612e715783633b9aca00612e56838a614d4c565b612e609190614b29565b612e6a9190614b56565b9150612e76565b600191505b50612efa565b603854612e8d90633b9aca00614b29565b8c518b90612e9c908790614b29565b612ea69190614b29565b612eb09190614b56565b612ebb906001614d5f565b915060b554851115612ef657633b9aca008460b55487612edb9190614d4c565b612ee59190614b29565b612eef9190614b56565b9050612efa565b5060015b818852612f07848b614b29565b603854612f18633b9aca0085614b29565b612f229190614b29565b612f2c9190614b56565b602089015260408801525050606085015250608083015250949350505050565b60808054608154604080517f8b73c3c69bb8fe3d512ecc4cf759cc79239f7b179b0ffacaa9a75d522b39400f602082015290810192909252606082015246918101919091523060a082015260009060c00160405160208183030381529060405280519060200120905090565b6000612fc2612a4e565b90506000676765c793fa10079d601b1b603f5483612fe09190614d4c565b604054612fed9190614b29565b612ff79190614b56565b9050806041600082825461300b9190614d5f565b9091555050603f82905542603e8190556040805184815260208101929092527fd1fa8ba00a3bf20274346919dce0de62d2a140af2c71fe7e29fa6472eea3bb9d910160405180910390a15090565b60008160000361306e5761306b612fb8565b91505b60008481526043602052604081206001015490676765c793fa10079d601b1b6130978584614b29565b6130a19190614b56565b90508085106130b2579350806130d5565b836130c8676765c793fa10079d601b1b87614b29565b6130d29190614b56565b90505b6130df8183614d4c565b915080604060008282546130f39190614d4c565b909155505081158015906131285750676765c793fa10079d601b1b60b45461311b9190614b29565b6131258584614b29565b11155b156131465760405163228af07f60e21b815260040160405180910390fd5b60008681526043602052604080822060010184905551600080516020615124833981519152916131799189918591614d72565b60405180910390a15092949350505050565b85156131a8576034546131a8906001600160a01b031684886138ee565b8415611952578051156132275760345460355460405163a5d4096b60e01b81526001600160a01b038086169363a5d4096b936131f49391831692169089908b908d908990600401615052565b600060405180830381600087803b15801561320e57600080fd5b505af1158015613222573d6000803e3d6000fd5b505050505b603554604051630d43af8160e21b81526001600160a01b039091169063350ebe049061325b9088908890339060040161501a565b600060405180830381600087803b15801561327557600080fd5b505af1158015613289573d6000803e3d6000fd5b50505050505050505050565b826001600160a01b0316826001600160a01b0316036132c7576040516320c5195360e21b815260040160405180910390fd5b6000816132d55760006132d8565b60015b6001600160a01b038581166000818152604a602090815260408083209489168084529482529182902060ff959095169485905590518615158152939450919290917f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c31910160405180910390a350505050565b60006001600160a01b0382166133735760405163d92e233d60e01b815260040160405180910390fd5b5060458054600101908190556001600160a01b038216600081815260486020908152604080832080546001019055848352604790915280822080546001600160a01b031916841790555183929190600080516020615164833981519152908290a46133f06000838360405180602001604052806000815250613c0c565b611918576040516320149b4360e21b815260040160405180910390fd5b613418848484612977565b61342484848484613c0c565b613441576040516320149b4360e21b815260040160405180910390fd5b50505050565b6134508261281d565b61346d5760405163062a39dd60e11b815260040160405180910390fd5b6000828152604360205260408120805483929061348b908490614d5f565b909155505060405160008051602061514483398151915290610f289084908490600190614d72565b60008033856134c282826128f9565b6134df5760405163c19f17a960e01b815260040160405180910390fd5b600087815260436020908152604080832081518083019092528054825260010154918101919091529080613514838a8a613951565b5091509150633b9aca00821161353d57604051631527804d60e31b815260040160405180910390fd5b8260200151604060008282546135539190614d4c565b9091555061356290508a613d12565b600061357281633b9aca00614d4c565b613580633b9aca0084614b29565b61358a9190614b56565b90506135968282614d4c565b604160008282546135a79190614d5f565b90915550509251929a92995091975050505050505050565b33846135cb82826128f9565b6135e85760405163c19f17a960e01b815260040160405180910390fd5b60008681526043602052604081208054879290613606908490614d4c565b90915550506000868152604360209081526040808320815180830190925280548252600101549181019190915261363e908686613951565b50509050633b9aca00811161366657604051631527804d60e31b815260040160405180910390fd5b6000805160206151448339815191528787600060405161368893929190614d72565b60405180910390a150505050505050565b600033856136a782826128f9565b6136c45760405163c19f17a960e01b815260040160405180910390fd5b6136d087878787613d91565b603c54909650600090633b9aca00906136fa908990600160801b90046001600160401b0316614b29565b6137049190614b56565b905080604160008282546137189190614d5f565b9091555061372890508188614d4c565b98975050505050505050565b338661374082826128f9565b61375d5760405163c19f17a960e01b815260040160405180910390fd5b60408051898152602081018890526001600160a01b038916818301526060810187905290517fddd3b70af631334f7552aadb582ed091018e62e103fa8b150ca66cc700d4dac69181900360800190a16137b888868686613d91565b9450306001600160a01b038816036137db576137d5868685613059565b506117ed565b866001600160a01b031663835986b48787603c60109054906101000a90046001600160401b031661380a600090565b6040516001600160e01b031960e087901b168152600481019490945260248401929092526001600160401b039081166044840152166064820152608401600060405180830381600087803b15801561386157600080fd5b505af1158015613875573d6000803e3d6000fd5b505050505050505050505050565b6040516001600160a01b03808516602483015283166044820152606481018290526134419085906323b872dd60e01b906084015b60408051601f198184030181529190526020810180516001600160e01b03166001600160e01b031990931692909217909152613f25565b6109ea8363a9059cbb60e01b84846040516024016138b7929190615039565b6001600160a01b0381166000908152607f6020526040902054613931816001614d5f565b6001600160a01b039092166000908152607f602052604090209190915590565b6000806000676765c793fa10079d601b1b8487602001516139729190614b29565b61397c9190614b56565b91506038548587600001516139919190614b29565b61399b9190614b56565b9050816000036139af5760001992506139d4565b603c5482906139c7906001600160401b031683614b29565b6139d19190614b56565b92505b93509350939050565b6037546000906001600160a01b0316613a1657603b600081548110613a0457613a04614c8c565b90600052602060002001549050919050565b603754604051635dfba04560e11b81526000916001600160a01b03169063bbf7408a90613a479086906004016141b0565b602060405180830381865afa158015613a64573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613a889190614afa565b9050603a600181548110613a9e57613a9e614c8c565b90600052602060002001548110613ad657603b600181548110613ac357613ac3614c8c565b9060005260206000200154915050919050565b603a600081548110613aea57613aea614c8c565b90600052602060002001548111613b0f57603b600081548110613ac357613ac3614c8c565b603a600081548110613b2357613b23614c8c565b9060005260206000200154603a600181548110613b4257613b42614c8c565b9060005260206000200154613b579190614d4c565b603a600081548110613b6b57613b6b614c8c565b906000526020600020015482613b819190614d4c565b603b600081548110613b9557613b95614c8c565b9060005260206000200154603b600181548110613bb457613bb4614c8c565b9060005260206000200154613bc99190614d4c565b613bd39190614b29565b613bdd9190614b56565b603b600081548110613bf157613bf1614c8c565b9060005260206000200154610ace9190614d5f565b50919050565b6000613c20846001600160a01b031661280e565b15613d0a57604051630a85bd0160e11b81526001600160a01b0385169063150b7a0290613c579033908990889088906004016150ca565b6020604051808303816000875af1925050508015613c92575060408051601f3d908101601f19168201909252613c8f918101906150ad565b60015b613cf0573d808015613cc0576040519150601f19603f3d011682016040523d82523d6000602084013e613cc5565b606091505b508051600003613ce8576040516320149b4360e21b815260040160405180910390fd5b805181602001fd5b6001600160e01b031916630a85bd0160e11b149050611831565b506001611831565b6000613d1d82612855565b9050613d2a60008361288b565b6001600160a01b038116600081815260486020908152604080832080546000190190558583526047825280832080546001600160a01b0319169055604390915280822082815560010182905551849290600080516020615164833981519152908390a45050565b60008082613daa676765c793fa10079d601b1b87614b29565b613db49190614b56565b60008781526043602052604081206001015491925003613df05760b4548511613df05760405163228af07f60e21b815260040160405180910390fd5b60008681526043602052604081206001018054839290613e11908490614d5f565b925050819055508060406000828254613e2a9190614d5f565b9091555050603954613e4890676765c793fa10079d601b1b90614b29565b83604054613e569190614b29565b1115613e75576040516371239a6160e11b815260040160405180910390fd5b60008681526043602090815260408083208151808301909252805482526001015491810191909152613ea8908686613951565b50509050633b9aca008111613ed057604051631527804d60e31b815260040160405180910390fd5b60008051602061512483398151915287836001604051613ef293929190614d72565b60405180910390a1676765c793fa10079d601b1b613f108584614b29565b613f1a9190614b56565b979650505050505050565b6000613f7a826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564815250856001600160a01b0316613ff79092919063ffffffff16565b8051909150156109ea5780806020019051810190613f989190614b6a565b6109ea5760405162461bcd60e51b815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e6044820152691bdd081cdd58d8d9595960b21b606482015260840161114f565b606061183184846000858561400b8561280e565b6140575760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e7472616374000000604482015260640161114f565b600080866001600160a01b031685876040516140739190615107565b60006040518083038185875af1925050503d80600081146140b0576040519150601f19603f3d011682016040523d82523d6000602084013e6140b5565b606091505b5091509150613f1a828286606083156140cf575081610ace565b8251156140df5782518084602001fd5b8160405162461bcd60e51b815260040161114f9190614247565b6040518060a0016040528060008152602001600081526020016000815260200160008152602001600081525090565b828054828255906000526020600020908101928215614163579160200282015b82811115614163578251825591602001919060010190614148565b5061416f92915061419b565b5090565b6040518060800160405280600081526020016000815260200160008152602001600081525090565b5b8082111561416f576000815560010161419c565b6001600160a01b0391909116815260200190565b6001600160e01b03198116811461044e57600080fd5b6000602082840312156141ec57600080fd5b8135610ace816141c4565b60005b838110156142125781810151838201526020016141fa565b50506000910152565b600081518084526142338160208601602086016141f7565b601f01601f19169290920160200192915050565b602081526000610ace602083018461421b565b60006020828403121561426c57600080fd5b5035919050565b6001600160a01b038116811461044e57600080fd5b6000806040838503121561429b57600080fd5b82356142a681614273565b946020939093013593505050565b6000806000606084860312156142c957600080fd5b83356142d481614273565b925060208401356142e481614273565b929592945050506040919091013590565b6000806040838503121561430857600080fd5b82359150602083013561431a81614273565b809150509250929050565b60a0810161089e828480518252602081015160208301526040810151604083015260608101516060830152608081015160808301525050565b60006020828403121561437057600080fd5b8135610ace81614273565b634e487b7160e01b600052604160045260246000fd5b604051601f8201601f191681016001600160401b03811182821017156143b9576143b961437b565b604052919050565b600082601f8301126143d257600080fd5b81356001600160401b038111156143eb576143eb61437b565b6143fe601f8201601f1916602001614391565b81815284602083860101111561441357600080fd5b816020850160208301376000918101602001919091529392505050565b60006020828403121561444257600080fd5b81356001600160401b0381111561445857600080fd5b611831848285016143c1565b6000806040838503121561447757600080fd5b82356001600160401b03811681146142a657600080fd5b60006001600160401b038211156144a7576144a761437b565b5060051b60200190565b600082601f8301126144c257600080fd5b813560206144d76144d28361448e565b614391565b82815260059290921b840181019181810190868411156144f657600080fd5b8286015b8481101561451157803583529183019183016144fa565b509695505050505050565b60008060006060848603121561453157600080fd5b833561453c81614273565b925060208401356001600160401b038082111561455857600080fd5b614564878388016144b1565b9350604086013591508082111561457a57600080fd5b50614587868287016144b1565b9150509250925092565b60008060008060008060c087890312156145aa57600080fd5b86356001600160401b03808211156145c157600080fd5b6145cd8a838b016144b1565b975060208901359150808211156145e357600080fd5b6145ef8a838b016144b1565b96506040890135915061460182614273565b90945060608801359061461382614273565b90935060808801359061462582614273565b90925060a0880135908082111561463b57600080fd5b5061464889828a016143c1565b9150509295509295509295565b6000806000806080858703121561466b57600080fd5b5050823594602084013594506040840135936060013592509050565b600082601f83011261469857600080fd5b813560206146a86144d28361448e565b82815260059290921b840181019181810190868411156146c757600080fd5b8286015b84811015614511578035600881106146e35760008081fd5b83529183019183016146cb565b600082601f83011261470157600080fd5b813560206147116144d28361448e565b82815260059290921b8401810191818101908684111561473057600080fd5b8286015b848110156145115780356001600160401b038111156147535760008081fd5b6147618986838b01016143c1565b845250918301918301614734565b6000806000806080858703121561478557600080fd5b84356001600160401b038082111561479c57600080fd5b6147a888838901614687565b955060208701359150808211156147be57600080fd5b506147cb878288016146f0565b93505060408501356147dc81614273565b915060608501356147ec81614273565b939692955090935050565b801515811461044e57600080fd5b6000806040838503121561481857600080fd5b823561482381614273565b9150602083013561431a816147f7565b6000806000806080858703121561484957600080fd5b843561485481614273565b9350602085013561486481614273565b92506040850135915060608501356001600160401b0381111561488657600080fd5b614892878288016143c1565b91505092959194509250565b6000806000606084860312156148b357600080fd5b505081359360208301359350604090920135919050565b60008060008060008587036101808112156148e457600080fd5b86356148ef81614273565b955060208701356148ff81614273565b9450604087013561490f81614273565b9350610100605f198201121561492457600080fd5b506060860191506101608601356001600160401b0381111561494557600080fd5b614951888289016143c1565b9150509295509295909350565b60008060008060008060c0878903121561497757600080fd5b86356001600160401b038082111561498e57600080fd5b61499a8a838b01614687565b975060208901359150808211156149b057600080fd5b6145ef8a838b016146f0565b600080604083850312156149cf57600080fd5b82356149da81614273565b9150602083013561431a81614273565b600080600080600080600060e0888a031215614a0557600080fd5b8735614a1081614273565b96506020880135614a2081614273565b95506040880135614a30816147f7565b945060608801359350608088013560ff81168114614a4d57600080fd5b9699959850939692959460a0840135945060c09093013592915050565b60008060008060808587031215614a8057600080fd5b84356001600160401b0380821115614a9757600080fd5b614aa3888389016144b1565b95506020870135915080821115614ab957600080fd5b506147cb878288016144b1565b600181811c90821680614ada57607f821691505b602082108103613c0657634e487b7160e01b600052602260045260246000fd5b600060208284031215614b0c57600080fd5b5051919050565b634e487b7160e01b600052601160045260246000fd5b808202811582820484141761089e5761089e614b13565b634e487b7160e01b600052601260045260246000fd5b600082614b6557614b65614b40565b500490565b600060208284031215614b7c57600080fd5b8151610ace816147f7565b601f8211156109ea57600081815260208120601f850160051c81016020861015614bae5750805b601f850160051c820191505b8181101561195257828155600101614bba565b81516001600160401b03811115614be657614be661437b565b614bfa81614bf48454614ac6565b84614b87565b602080601f831160018114614c2f5760008415614c175750858301515b600019600386901b1c1916600185901b178555611952565b600085815260208120601f198616915b82811015614c5e57888601518255948401946001909101908401614c3f565b5085821015614c7c5787850151600019600388901b60f8161c191681555b5050505050600190811b01905550565b634e487b7160e01b600052603260045260246000fd5b600081518084526020808501945080840160005b83811015614cd257815187529582019590820190600101614cb6565b509495945050505050565b604081526000614cf06040830185614ca2565b8281036020840152611b648185614ca2565b6020808252601f908201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c00604082015260600190565b602081526000610ace6020830184614ca2565b8181038181111561089e5761089e614b13565b8082018082111561089e5761089e614b13565b928352602083019190915260ff16604082015260600190565b600060018201614d9d57614d9d614b13565b5060010190565b600181815b80851115614ddf578160001904821115614dc557614dc5614b13565b80851615614dd257918102915b93841c9390800290614da9565b509250929050565b600082614df65750600161089e565b81614e035750600061089e565b8160018114614e195760028114614e2357614e3f565b600191505061089e565b60ff841115614e3457614e34614b13565b50506001821b61089e565b5060208310610133831016604e8410600b8410161715614e62575081810a61089e565b614e6c8383614da4565b8060001904821115614e8057614e80614b13565b029392505050565b6000610ace60ff841683614de7565b600082614ea657614ea6614b40565b500690565b6000808454614eb981614ac6565b60018281168015614ed15760018114614ee657614f15565b60ff1984168752821515830287019450614f15565b8860005260208060002060005b85811015614f0c5781548a820152908401908201614ef3565b50505082870194505b505050508351614f298183602088016141f7565b01949350505050565b634e487b7160e01b600052602160045260246000fd5b600060208284031215614f5a57600080fd5b8151610ace81614273565b60008060408385031215614f7857600080fd5b505080516020909101519092909150565b60008060008060008060c08789031215614fa257600080fd5b8651614fad81614273565b6020880151604089015160608a015160808b015160a0909b0151939c929b509099909850965090945092505050565b60008060008060808587031215614ff257600080fd5b84519350602085015161500481614273565b6040860151606090960151949790965092505050565b9283526001600160a01b03918216602084015216604082015260600190565b6001600160a01b03929092168252602082015260400190565b6001600160a01b038781168252868116602083015285166040820152606081018490526080810183905260c060a082018190526000906137289083018461421b565b828152604060208201526000611831604083018461421b565b6000602082840312156150bf57600080fd5b8151610ace816141c4565b6001600160a01b03858116825284166020820152604081018390526080606082018190526000906150fd9083018461421b565b9695505050505050565b600082516151198184602087016141f7565b919091019291505056fe70cf49afe7355562d5b022e594790f22b71ad8cc7eec902fa5feac7c67f71091722cb71fa87c947148cefc06dd890af5802a6a00207c5ddecf1191bf71ce3cd4ddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3efa2646970667358221220e59f94ab826df3aef4dcca1c7263b3c9c4cf503c792ab064f746ab7df9344dde64736f6c63430008110033" - ); - - VaultParameters internal _vmParams = - VaultParameters({ - debtCeiling: 10 ** 9 * BASE_18, - collateralFactor: uint64(BASE_PARAMS / 2), - targetHealthFactor: uint64((BASE_PARAMS * 105) / 100), - interestRate: uint64(BASE_PARAMS / 10), - liquidationSurcharge: uint64((BASE_PARAMS * 99) / 100), - maxLiquidationDiscount: uint64(BASE_PARAMS / 10), - whitelistingActivated: false, - baseBoost: BASE_PARAMS - }); - - AgTokenSideChainImmutable internal _agToken; - MockTreasuryImmutable internal _treasury; - VaultManagerLiquidationBoostImmutable internal _vault; - IERC20 internal _collateral; - MockOracle internal _oracle; - uint8 public decimalToken = 18; - - string constant _NAME = "Angle stablecoin gold"; - string constant _SYMBOL = "agGold"; - - function setUp() public override { - super.setUp(); - - _treasury = new MockTreasuryImmutable(ICoreBorrow(coreBorrow)); - _agToken = new AgTokenSideChainImmutable(_NAME, _SYMBOL, address(_treasury)); - _collateral = new MockTokenPermit("Mock", "MCK", decimalToken); - _oracle = new MockOracle(BASE_18, ITreasury(address(_treasury))); - - vm.startPrank(_GOVERNOR); - _treasury.setStablecoin(_agToken); - - _vault = new VaultManagerLiquidationBoostImmutable( - ITreasury(address(_treasury)), - _collateral, - _oracle, - _vmParams, - _SYMBOL - ); - _treasury.setVaultManagerImpl(_hashVM); - _treasury.addVaultManager(address(_vault)); - vm.stopPrank(); - } - - // ================================= INITIALIZE ================================ - - function testConstructor() public { - assertEq(address(_vault.treasury()), address(_treasury)); - assertEq(address(_vault.oracle()), address(_oracle)); - assertEq(address(_vault.stablecoin()), address(_agToken)); - assertEq(address(_vault.collateral()), address(_collateral)); - assertEq(_vault.name(), string.concat("Angle Protocol ", _SYMBOL, " Vault")); - assertEq(_vault.symbol(), string.concat(_SYMBOL, "-vault")); - - assertEq(_vault.debtCeiling(), _vmParams.debtCeiling); - assertEq(_vault.collateralFactor(), _vmParams.collateralFactor); - assertEq(_vault.targetHealthFactor(), _vmParams.targetHealthFactor); - assertEq(_vault.interestRate(), _vmParams.interestRate); - assertEq(_vault.liquidationSurcharge(), _vmParams.liquidationSurcharge); - assertEq(_vault.maxLiquidationDiscount(), _vmParams.maxLiquidationDiscount); - assertEq(_vault.whitelistingActivated(), false); - assertEq(_vault.yLiquidationBoost(0), _vmParams.baseBoost); - assertEq(_vault.paused(), false); - assertEq(_vault.repayFee(), 0); - } - - function testAlreadyInitalizeFail() public { - MockCoreBorrow coreBorrowBis = new MockCoreBorrow(); - MockTreasuryImmutable treasuryBis = new MockTreasuryImmutable(ICoreBorrow(coreBorrowBis)); - AgTokenSideChainImmutable agTokenBis = new AgTokenSideChainImmutable(_NAME, _SYMBOL, address(treasuryBis)); - MockTokenPermit collateralBis = new MockTokenPermit("Mock2", "MCK2", decimalToken + 3); - MockOracle oracleBis = new MockOracle(BASE_18, ITreasury(address(treasuryBis))); - VaultParameters memory vmParamsBis = VaultParameters({ - debtCeiling: 10 ** 6 * BASE_18, - collateralFactor: uint64(BASE_PARAMS / 3), - targetHealthFactor: uint64((BASE_PARAMS * 150) / 100), - interestRate: uint64(BASE_PARAMS / 20), - liquidationSurcharge: uint64((BASE_PARAMS * 8) / 10), - maxLiquidationDiscount: uint64(BASE_PARAMS / 20), - whitelistingActivated: true, - baseBoost: BASE_PARAMS / 12 - }); - - _vault.initialize(ITreasury(address(treasuryBis)), collateralBis, oracleBis, vmParamsBis, _SYMBOL); - - assertEq(address(_vault.treasury()), address(_treasury)); - assertEq(address(_vault.oracle()), address(_oracle)); - assertEq(address(_vault.stablecoin()), address(_agToken)); - assertEq(address(_vault.collateral()), address(_collateral)); - assertEq(_vault.name(), string.concat("Angle Protocol ", _SYMBOL, " Vault")); - assertEq(_vault.symbol(), string.concat(_SYMBOL, "-vault")); - - assertEq(_vault.debtCeiling(), _vmParams.debtCeiling); - assertEq(_vault.collateralFactor(), _vmParams.collateralFactor); - assertEq(_vault.targetHealthFactor(), _vmParams.targetHealthFactor); - assertEq(_vault.interestRate(), _vmParams.interestRate); - assertEq(_vault.liquidationSurcharge(), _vmParams.liquidationSurcharge); - assertEq(_vault.maxLiquidationDiscount(), _vmParams.maxLiquidationDiscount); - assertEq(_vault.whitelistingActivated(), false); - assertEq(_vault.yLiquidationBoost(0), _vmParams.baseBoost); - assertEq(_vault.paused(), false); - assertEq(_vault.repayFee(), 0); - } - - // ============================== EMPTY FUNCTIONS ============================== - function testNoImplementationTogglePause() public { - _vault.togglePause(); - assertEq(_vault.paused(), false); - } - - function testNoImplementationToggleWhitelist() public { - _vault.toggleWhitelist(_alice); - assertEq(_vault.isWhitelisted(_alice), 0); - } - - function testNoImplementationSetTreasury() public { - MockTreasuryImmutable treasuryBis = new MockTreasuryImmutable(ICoreBorrow(coreBorrow)); - _vault.setTreasury(address(treasuryBis)); - assertEq(address(_vault.treasury()), address(_treasury)); - } - - function testNoImplementationSetOracle() public { - MockOracle oracleBis = new MockOracle(BASE_18, ITreasury(address(_treasury))); - _vault.setOracle(address(oracleBis)); - assertEq(address(_vault.oracle()), address(_oracle)); - } - - // ================================= SETUINT64 ================================= - function testSetUint64CF() public { - uint64 param = _vmParams.liquidationSurcharge / 2; - bytes32 what = "CF"; - vm.prank(_GOVERNOR); - _vault.setUint64(param, what); - assertEq(_vault.collateralFactor(), param); - } - - function testSetUint64THF() public { - uint64 param = _vmParams.targetHealthFactor * 2; - bytes32 what = "THF"; - vm.prank(_GOVERNOR); - _vault.setUint64(param, what); - assertEq(_vault.targetHealthFactor(), param); - } - - function testSetUint64RFFail() public { - uint64 param = uint64(BASE_PARAMS); - bytes32 what = "RF"; - vm.prank(_GOVERNOR); - vm.expectRevert(VaultManagerStorage.InvalidParameterType.selector); - _vault.setUint64(param, what); - } - - function testSetUint64LSFail() public { - uint64 param = uint64(BASE_PARAMS); - bytes32 what = "LS"; - vm.prank(_GOVERNOR); - vm.expectRevert(VaultManagerStorage.InvalidParameterType.selector); - _vault.setUint64(param, what); - } -} -*/ diff --git a/test/hardhat/agToken/agTokenSideChain.test.ts b/test/hardhat/agToken/agEUR.test.ts similarity index 56% rename from test/hardhat/agToken/agTokenSideChain.test.ts rename to test/hardhat/agToken/agEUR.test.ts index 741463e6..858b132a 100644 --- a/test/hardhat/agToken/agTokenSideChain.test.ts +++ b/test/hardhat/agToken/agEUR.test.ts @@ -3,17 +3,25 @@ import { Signer, utils } from 'ethers'; import { parseEther } from 'ethers/lib/utils'; import hre, { contract, ethers } from 'hardhat'; -import { AgTokenSideChain, AgTokenSideChain__factory, MockTreasury, MockTreasury__factory } from '../../../typechain'; +import { + MockStableMaster, + MockStableMaster__factory, + MockTreasury, + MockTreasury__factory, + OldAgEUR, + OldAgEUR__factory, +} from '../../../typechain'; import { expect } from '../utils/chai-setup'; import { inIndirectReceipt, inReceipt } from '../utils/expectEvent'; import { deployUpgradeable, ZERO_ADDRESS } from '../utils/helpers'; -contract('AgTokenSideChain', () => { +contract('agEUR', () => { let deployer: SignerWithAddress; let alice: SignerWithAddress; let bob: SignerWithAddress; - let agToken: AgTokenSideChain; + let agToken: OldAgEUR; + let stableMaster: MockStableMaster; let governor: string; let treasury: MockTreasury; @@ -36,8 +44,15 @@ contract('AgTokenSideChain', () => { }); beforeEach(async () => { + // If the forked-network state needs to be reset between each test, run this + // await network.provider.request({method: 'hardhat_reset', params: []}); + + // To deploy a contract, import and use the contract factory specific to that contract + + stableMaster = (await new MockStableMaster__factory(deployer).deploy()) as MockStableMaster; + // Example of upgradeable deployment - Default signer will be alice - agToken = (await deployUpgradeable(new AgTokenSideChain__factory(deployer))) as AgTokenSideChain; + agToken = (await deployUpgradeable(new OldAgEUR__factory(deployer))) as OldAgEUR; treasury = (await new MockTreasury__factory(deployer).deploy( agToken.address, @@ -48,28 +63,37 @@ contract('AgTokenSideChain', () => { ZERO_ADDRESS, )) as MockTreasury; - await agToken.initialize('agEUR', 'agEUR', treasury.address); + await agToken.initialize('agEUR', 'agEUR', stableMaster.address); - await treasury.addMinter(agToken.address, alice.address); - await agToken.connect(alice).mint(alice.address, parseEther('1')); + await agToken.connect(impersonatedSigners[governor]).setUpTreasury(treasury.address); + await stableMaster.mint(agToken.address, alice.address, parseEther('1')); }); describe('initializer', () => { it('success - stableMaster, name, symbol, treasury', async () => { + expect(await agToken.stableMaster()).to.be.equal(stableMaster.address); expect(await agToken.name()).to.be.equal('agEUR'); - expect(await agToken.isMinter(alice.address)).to.be.equal(true); + expect(await agToken.isMinter(stableMaster.address)).to.be.equal(true); expect(await agToken.symbol()).to.be.equal('agEUR'); expect(await agToken.treasury()).to.be.equal(treasury.address); + expect(await agToken.treasuryInitialized()).to.be.equal(true); }); it('reverts - already initialized', async () => { await expect(agToken.initialize('agEUR', 'agEUR', ZERO_ADDRESS)).to.be.revertedWith( 'Initializable: contract is already initialized', ); }); - it('reverts - wrong treasury address', async () => { - const agTokenRevert = (await deployUpgradeable(new AgTokenSideChain__factory(deployer))) as AgTokenSideChain; - await expect(agTokenRevert.initialize('agEUR', 'agEUR', ZERO_ADDRESS)).to.be.reverted; - const treasuryRevert = (await new MockTreasury__factory(deployer).deploy( + it('reverts - zero stableMaster address', async () => { + const agTokenRevert = (await deployUpgradeable(new OldAgEUR__factory(deployer))) as OldAgEUR; + await expect(agTokenRevert.initialize('agEUR', 'agEUR', ZERO_ADDRESS)).to.be.revertedWith('0'); + }); + }); + describe('setUpTreasury', () => { + it('reverts - wrong sender', async () => { + await expect(agToken.setUpTreasury(ZERO_ADDRESS)).to.be.revertedWith('NotGovernor'); + }); + it('reverts - wrong stablecoin', async () => { + const mockTreasuryWrong = (await new MockTreasury__factory(deployer).deploy( ZERO_ADDRESS, ZERO_ADDRESS, ZERO_ADDRESS, @@ -77,25 +101,54 @@ contract('AgTokenSideChain', () => { ZERO_ADDRESS, ZERO_ADDRESS, )) as MockTreasury; - await expect(agTokenRevert.initialize('agEUR', 'agEUR', treasuryRevert.address)).to.be.revertedWith( - 'InvalidTreasury', + await expect( + agToken.connect(impersonatedSigners[governor]).setUpTreasury(mockTreasuryWrong.address), + ).to.be.revertedWith('InvalidTreasury'); + }); + it('reverts - treasuryInitialized', async () => { + await expect(agToken.connect(impersonatedSigners[governor]).setUpTreasury(treasury.address)).to.be.revertedWith( + 'TreasuryAlreadyInitialized', ); }); }); - describe('mint', () => { it('reverts - wrong sender', async () => { - await expect(agToken.connect(bob).mint(alice.address, parseEther('1'))).to.be.revertedWith('NotMinter'); + await expect(agToken.connect(alice).mint(alice.address, parseEther('1'))).to.be.revertedWith('NotMinter'); }); - it('success - alice mint (in the before each)', async () => { + it('success - stableMaster mint (in the before each)', async () => { expect(await agToken.balanceOf(alice.address)).to.be.equal(parseEther('1')); expect(await agToken.totalSupply()).to.be.equal(parseEther('1')); }); it('reverts - zero address', async () => { - await expect(agToken.connect(alice).mint(ZERO_ADDRESS, parseEther('1'))).to.be.reverted; + await expect(stableMaster.mint(agToken.address, ZERO_ADDRESS, parseEther('1'))).to.be.reverted; + }); + }); + describe('burnNoRedeem', () => { + it('success - balanceUpdated', async () => { + await agToken.connect(alice).burnNoRedeem(parseEther('0.5'), alice.address); + expect(await agToken.balanceOf(alice.address)).to.be.equal(parseEther('0.5')); + expect(await stableMaster.poolManagerMap(alice.address)).to.be.equal(parseEther('0.5')); + }); + it('reverts - too high balance', async () => { + await expect(agToken.connect(alice).burnNoRedeem(parseEther('1.1'), ZERO_ADDRESS)).to.be.reverted; + }); + }); + describe('burnFromNoRedeem', () => { + it('reverts - burn for someone else and no approval', async () => { + await stableMaster.mint(agToken.address, bob.address, parseEther('1')); + await expect( + agToken.connect(alice).burnFromNoRedeem(bob.address, parseEther('0.5'), alice.address), + ).to.be.revertedWith('BurnAmountExceedsAllowance'); + }); + it('success - when allowance', async () => { + await agToken.connect(alice).approve(bob.address, parseEther('2')); + expect(await agToken.allowance(alice.address, bob.address)).to.be.equal(parseEther('2')); + await agToken.connect(bob).burnFromNoRedeem(alice.address, parseEther('0.5'), alice.address); + expect(await agToken.balanceOf(alice.address)).to.be.equal(parseEther('0.5')); + expect(await agToken.allowance(alice.address, bob.address)).to.be.equal(parseEther('1.5')); + expect(await stableMaster.poolManagerMap(alice.address)).to.be.equal(parseEther('0.5')); }); }); - describe('burnStablecoin', () => { it('success - when non null balance', async () => { await agToken.connect(alice).burnStablecoin(parseEther('0.3')); @@ -107,50 +160,46 @@ contract('AgTokenSideChain', () => { }); describe('burnSelf', () => { it('reverts - non minter', async () => { - await expect(agToken.connect(bob).burnSelf(parseEther('1'), alice.address)).to.be.revertedWith('NotMinter'); + await expect(agToken.connect(alice).burnSelf(parseEther('1'), alice.address)).to.be.revertedWith('NotMinter'); }); it('success - when minter', async () => { - await agToken.connect(alice).burnSelf(parseEther('0.4'), alice.address); + await stableMaster.burnSelf(agToken.address, parseEther('0.4'), alice.address); expect(await agToken.balanceOf(alice.address)).to.be.equal(parseEther('0.6')); expect(await agToken.totalSupply()).to.be.equal(parseEther('0.6')); }); }); describe('burnFrom', () => { it('reverts - non minter', async () => { - await expect(agToken.connect(bob).burnFrom(parseEther('1'), bob.address, alice.address)).to.be.revertedWith( + await expect(agToken.connect(alice).burnFrom(parseEther('1'), bob.address, alice.address)).to.be.revertedWith( 'NotMinter', ); }); it('reverts - no approval', async () => { - await expect(agToken.connect(alice).burnFrom(parseEther('1'), alice.address, bob.address)).to.be.revertedWith( - 'BurnAmountExceedsAllowance', - ); + await expect( + stableMaster.connect(bob).burnFrom(agToken.address, parseEther('1'), alice.address, bob.address), + ).to.be.revertedWith('BurnAmountExceedsAllowance'); }); it('success - with approval', async () => { await agToken.connect(alice).approve(bob.address, parseEther('2')); expect(await agToken.allowance(alice.address, bob.address)).to.be.equal(parseEther('2')); - await agToken.connect(alice).burnFrom(parseEther('0.5'), alice.address, bob.address); + await stableMaster.connect(bob).burnFrom(agToken.address, parseEther('0.5'), alice.address, bob.address); expect(await agToken.balanceOf(alice.address)).to.be.equal(parseEther('0.5')); expect(await agToken.allowance(alice.address, bob.address)).to.be.equal(parseEther('1.5')); }); - it('success - without approval but burner is sender', async () => { - await agToken.connect(alice).burnFrom(parseEther('0.5'), alice.address, alice.address); - expect(await agToken.balanceOf(alice.address)).to.be.equal(parseEther('0.5')); - }); }); describe('addMinter', () => { it('reverts - non treasury', async () => { await expect(agToken.connect(alice).addMinter(alice.address)).to.be.revertedWith('NotTreasury'); }); it('success - minter toggled', async () => { - const receipt = await (await treasury.connect(alice).addMinter(agToken.address, bob.address)).wait(); - expect(await agToken.isMinter(bob.address)).to.be.true; + const receipt = await (await treasury.connect(alice).addMinter(agToken.address, alice.address)).wait(); + expect(await agToken.isMinter(alice.address)).to.be.true; inIndirectReceipt( receipt, new utils.Interface(['event MinterToggled(address indexed minter)']), 'MinterToggled', { - minter: bob.address, + minter: alice.address, }, ); }); @@ -159,29 +208,31 @@ contract('AgTokenSideChain', () => { it('reverts - non treasury', async () => { await expect(agToken.connect(alice).removeMinter(bob.address)).to.be.revertedWith('InvalidSender'); }); + it('reverts - removing stableMaster from the treasury', async () => { + await expect(treasury.connect(alice).removeMinter(agToken.address, stableMaster.address)).to.be.revertedWith( + 'InvalidSender', + ); + }); it('success - minter removed after being added', async () => { - await (await treasury.connect(alice).addMinter(agToken.address, bob.address)).wait(); - expect(await agToken.isMinter(bob.address)).to.be.true; + await (await treasury.connect(alice).addMinter(agToken.address, alice.address)).wait(); + expect(await agToken.isMinter(alice.address)).to.be.true; await expect(agToken.connect(bob).removeMinter(alice.address)).to.be.revertedWith('InvalidSender'); - const receipt = await (await treasury.connect(alice).removeMinter(agToken.address, bob.address)).wait(); + const receipt = await (await treasury.connect(alice).removeMinter(agToken.address, alice.address)).wait(); inIndirectReceipt( receipt, new utils.Interface(['event MinterToggled(address indexed minter)']), 'MinterToggled', { - minter: bob.address, + minter: alice.address, }, ); - expect(await agToken.isMinter(bob.address)).to.be.false; }); it('success - minter removed after requesting it', async () => { - await (await treasury.connect(alice).addMinter(agToken.address, bob.address)).wait(); - expect(await agToken.isMinter(bob.address)).to.be.true; - const receipt = await (await agToken.connect(bob).removeMinter(bob.address)).wait(); + await (await treasury.connect(alice).addMinter(agToken.address, alice.address)).wait(); + const receipt = await (await agToken.connect(alice).removeMinter(alice.address)).wait(); inReceipt(receipt, 'MinterToggled', { - minter: bob.address, + minter: alice.address, }); - expect(await agToken.isMinter(bob.address)).to.be.false; }); }); describe('setTreasury', () => { diff --git a/test/hardhat/agToken/agToken.test.ts b/test/hardhat/agToken/agToken.test.ts index 86e17391..9463adf7 100644 --- a/test/hardhat/agToken/agToken.test.ts +++ b/test/hardhat/agToken/agToken.test.ts @@ -3,14 +3,7 @@ import { Signer, utils } from 'ethers'; import { parseEther } from 'ethers/lib/utils'; import hre, { contract, ethers } from 'hardhat'; -import { - AgToken, - AgToken__factory, - MockStableMaster, - MockStableMaster__factory, - MockTreasury, - MockTreasury__factory, -} from '../../../typechain'; +import { AgToken, AgToken__factory, MockTreasury, MockTreasury__factory } from '../../../typechain'; import { expect } from '../utils/chai-setup'; import { inIndirectReceipt, inReceipt } from '../utils/expectEvent'; import { deployUpgradeable, ZERO_ADDRESS } from '../utils/helpers'; @@ -21,7 +14,6 @@ contract('AgToken', () => { let bob: SignerWithAddress; let agToken: AgToken; - let stableMaster: MockStableMaster; let governor: string; let treasury: MockTreasury; @@ -44,13 +36,6 @@ contract('AgToken', () => { }); beforeEach(async () => { - // If the forked-network state needs to be reset between each test, run this - // await network.provider.request({method: 'hardhat_reset', params: []}); - - // To deploy a contract, import and use the contract factory specific to that contract - - stableMaster = (await new MockStableMaster__factory(deployer).deploy()) as MockStableMaster; - // Example of upgradeable deployment - Default signer will be alice agToken = (await deployUpgradeable(new AgToken__factory(deployer))) as AgToken; @@ -63,37 +48,28 @@ contract('AgToken', () => { ZERO_ADDRESS, )) as MockTreasury; - await agToken.initialize('agEUR', 'agEUR', stableMaster.address); + await agToken.initialize('agEUR', 'agEUR', treasury.address); - await agToken.connect(impersonatedSigners[governor]).setUpTreasury(treasury.address); - await stableMaster.mint(agToken.address, alice.address, parseEther('1')); + await treasury.addMinter(agToken.address, alice.address); + await agToken.connect(alice).mint(alice.address, parseEther('1')); }); describe('initializer', () => { it('success - stableMaster, name, symbol, treasury', async () => { - expect(await agToken.stableMaster()).to.be.equal(stableMaster.address); expect(await agToken.name()).to.be.equal('agEUR'); - expect(await agToken.isMinter(stableMaster.address)).to.be.equal(true); + expect(await agToken.isMinter(alice.address)).to.be.equal(true); expect(await agToken.symbol()).to.be.equal('agEUR'); expect(await agToken.treasury()).to.be.equal(treasury.address); - expect(await agToken.treasuryInitialized()).to.be.equal(true); }); it('reverts - already initialized', async () => { await expect(agToken.initialize('agEUR', 'agEUR', ZERO_ADDRESS)).to.be.revertedWith( 'Initializable: contract is already initialized', ); }); - it('reverts - zero stableMaster address', async () => { + it('reverts - wrong treasury address', async () => { const agTokenRevert = (await deployUpgradeable(new AgToken__factory(deployer))) as AgToken; - await expect(agTokenRevert.initialize('agEUR', 'agEUR', ZERO_ADDRESS)).to.be.revertedWith('0'); - }); - }); - describe('setUpTreasury', () => { - it('reverts - wrong sender', async () => { - await expect(agToken.setUpTreasury(ZERO_ADDRESS)).to.be.revertedWith('NotGovernor'); - }); - it('reverts - wrong stablecoin', async () => { - const mockTreasuryWrong = (await new MockTreasury__factory(deployer).deploy( + await expect(agTokenRevert.initialize('agEUR', 'agEUR', ZERO_ADDRESS)).to.be.reverted; + const treasuryRevert = (await new MockTreasury__factory(deployer).deploy( ZERO_ADDRESS, ZERO_ADDRESS, ZERO_ADDRESS, @@ -101,54 +77,25 @@ contract('AgToken', () => { ZERO_ADDRESS, ZERO_ADDRESS, )) as MockTreasury; - await expect( - agToken.connect(impersonatedSigners[governor]).setUpTreasury(mockTreasuryWrong.address), - ).to.be.revertedWith('InvalidTreasury'); - }); - it('reverts - treasuryInitialized', async () => { - await expect(agToken.connect(impersonatedSigners[governor]).setUpTreasury(treasury.address)).to.be.revertedWith( - 'TreasuryAlreadyInitialized', + await expect(agTokenRevert.initialize('agEUR', 'agEUR', treasuryRevert.address)).to.be.revertedWith( + 'InvalidTreasury', ); }); }); + describe('mint', () => { it('reverts - wrong sender', async () => { - await expect(agToken.connect(alice).mint(alice.address, parseEther('1'))).to.be.revertedWith('NotMinter'); + await expect(agToken.connect(bob).mint(alice.address, parseEther('1'))).to.be.revertedWith('NotMinter'); }); - it('success - stableMaster mint (in the before each)', async () => { + it('success - alice mint (in the before each)', async () => { expect(await agToken.balanceOf(alice.address)).to.be.equal(parseEther('1')); expect(await agToken.totalSupply()).to.be.equal(parseEther('1')); }); it('reverts - zero address', async () => { - await expect(stableMaster.mint(agToken.address, ZERO_ADDRESS, parseEther('1'))).to.be.reverted; - }); - }); - describe('burnNoRedeem', () => { - it('success - balanceUpdated', async () => { - await agToken.connect(alice).burnNoRedeem(parseEther('0.5'), alice.address); - expect(await agToken.balanceOf(alice.address)).to.be.equal(parseEther('0.5')); - expect(await stableMaster.poolManagerMap(alice.address)).to.be.equal(parseEther('0.5')); - }); - it('reverts - too high balance', async () => { - await expect(agToken.connect(alice).burnNoRedeem(parseEther('1.1'), ZERO_ADDRESS)).to.be.reverted; - }); - }); - describe('burnFromNoRedeem', () => { - it('reverts - burn for someone else and no approval', async () => { - await stableMaster.mint(agToken.address, bob.address, parseEther('1')); - await expect( - agToken.connect(alice).burnFromNoRedeem(bob.address, parseEther('0.5'), alice.address), - ).to.be.revertedWith('BurnAmountExceedsAllowance'); - }); - it('success - when allowance', async () => { - await agToken.connect(alice).approve(bob.address, parseEther('2')); - expect(await agToken.allowance(alice.address, bob.address)).to.be.equal(parseEther('2')); - await agToken.connect(bob).burnFromNoRedeem(alice.address, parseEther('0.5'), alice.address); - expect(await agToken.balanceOf(alice.address)).to.be.equal(parseEther('0.5')); - expect(await agToken.allowance(alice.address, bob.address)).to.be.equal(parseEther('1.5')); - expect(await stableMaster.poolManagerMap(alice.address)).to.be.equal(parseEther('0.5')); + await expect(agToken.connect(alice).mint(ZERO_ADDRESS, parseEther('1'))).to.be.reverted; }); }); + describe('burnStablecoin', () => { it('success - when non null balance', async () => { await agToken.connect(alice).burnStablecoin(parseEther('0.3')); @@ -160,46 +107,50 @@ contract('AgToken', () => { }); describe('burnSelf', () => { it('reverts - non minter', async () => { - await expect(agToken.connect(alice).burnSelf(parseEther('1'), alice.address)).to.be.revertedWith('NotMinter'); + await expect(agToken.connect(bob).burnSelf(parseEther('1'), alice.address)).to.be.revertedWith('NotMinter'); }); it('success - when minter', async () => { - await stableMaster.burnSelf(agToken.address, parseEther('0.4'), alice.address); + await agToken.connect(alice).burnSelf(parseEther('0.4'), alice.address); expect(await agToken.balanceOf(alice.address)).to.be.equal(parseEther('0.6')); expect(await agToken.totalSupply()).to.be.equal(parseEther('0.6')); }); }); describe('burnFrom', () => { it('reverts - non minter', async () => { - await expect(agToken.connect(alice).burnFrom(parseEther('1'), bob.address, alice.address)).to.be.revertedWith( + await expect(agToken.connect(bob).burnFrom(parseEther('1'), bob.address, alice.address)).to.be.revertedWith( 'NotMinter', ); }); it('reverts - no approval', async () => { - await expect( - stableMaster.connect(bob).burnFrom(agToken.address, parseEther('1'), alice.address, bob.address), - ).to.be.revertedWith('BurnAmountExceedsAllowance'); + await expect(agToken.connect(alice).burnFrom(parseEther('1'), alice.address, bob.address)).to.be.revertedWith( + 'BurnAmountExceedsAllowance', + ); }); it('success - with approval', async () => { await agToken.connect(alice).approve(bob.address, parseEther('2')); expect(await agToken.allowance(alice.address, bob.address)).to.be.equal(parseEther('2')); - await stableMaster.connect(bob).burnFrom(agToken.address, parseEther('0.5'), alice.address, bob.address); + await agToken.connect(alice).burnFrom(parseEther('0.5'), alice.address, bob.address); expect(await agToken.balanceOf(alice.address)).to.be.equal(parseEther('0.5')); expect(await agToken.allowance(alice.address, bob.address)).to.be.equal(parseEther('1.5')); }); + it('success - without approval but burner is sender', async () => { + await agToken.connect(alice).burnFrom(parseEther('0.5'), alice.address, alice.address); + expect(await agToken.balanceOf(alice.address)).to.be.equal(parseEther('0.5')); + }); }); describe('addMinter', () => { it('reverts - non treasury', async () => { await expect(agToken.connect(alice).addMinter(alice.address)).to.be.revertedWith('NotTreasury'); }); it('success - minter toggled', async () => { - const receipt = await (await treasury.connect(alice).addMinter(agToken.address, alice.address)).wait(); - expect(await agToken.isMinter(alice.address)).to.be.true; + const receipt = await (await treasury.connect(alice).addMinter(agToken.address, bob.address)).wait(); + expect(await agToken.isMinter(bob.address)).to.be.true; inIndirectReceipt( receipt, new utils.Interface(['event MinterToggled(address indexed minter)']), 'MinterToggled', { - minter: alice.address, + minter: bob.address, }, ); }); @@ -208,31 +159,29 @@ contract('AgToken', () => { it('reverts - non treasury', async () => { await expect(agToken.connect(alice).removeMinter(bob.address)).to.be.revertedWith('InvalidSender'); }); - it('reverts - removing stableMaster from the treasury', async () => { - await expect(treasury.connect(alice).removeMinter(agToken.address, stableMaster.address)).to.be.revertedWith( - 'InvalidSender', - ); - }); it('success - minter removed after being added', async () => { - await (await treasury.connect(alice).addMinter(agToken.address, alice.address)).wait(); - expect(await agToken.isMinter(alice.address)).to.be.true; + await (await treasury.connect(alice).addMinter(agToken.address, bob.address)).wait(); + expect(await agToken.isMinter(bob.address)).to.be.true; await expect(agToken.connect(bob).removeMinter(alice.address)).to.be.revertedWith('InvalidSender'); - const receipt = await (await treasury.connect(alice).removeMinter(agToken.address, alice.address)).wait(); + const receipt = await (await treasury.connect(alice).removeMinter(agToken.address, bob.address)).wait(); inIndirectReceipt( receipt, new utils.Interface(['event MinterToggled(address indexed minter)']), 'MinterToggled', { - minter: alice.address, + minter: bob.address, }, ); + expect(await agToken.isMinter(bob.address)).to.be.false; }); it('success - minter removed after requesting it', async () => { - await (await treasury.connect(alice).addMinter(agToken.address, alice.address)).wait(); - const receipt = await (await agToken.connect(alice).removeMinter(alice.address)).wait(); + await (await treasury.connect(alice).addMinter(agToken.address, bob.address)).wait(); + expect(await agToken.isMinter(bob.address)).to.be.true; + const receipt = await (await agToken.connect(bob).removeMinter(bob.address)).wait(); inReceipt(receipt, 'MinterToggled', { - minter: alice.address, + minter: bob.address, }); + expect(await agToken.isMinter(bob.address)).to.be.false; }); }); describe('setTreasury', () => { diff --git a/test/hardhat/flashAngle/flashAngleEndToEnd.test.ts b/test/hardhat/flashAngle/flashAngleEndToEnd.test.ts index 292900f3..b1458a21 100644 --- a/test/hardhat/flashAngle/flashAngleEndToEnd.test.ts +++ b/test/hardhat/flashAngle/flashAngleEndToEnd.test.ts @@ -4,8 +4,6 @@ import { parseEther } from 'ethers/lib/utils'; import hre, { contract, ethers, web3 } from 'hardhat'; import { - AgToken, - AgToken__factory, CoreBorrow, CoreBorrow__factory, FlashAngle, @@ -14,6 +12,8 @@ import { MockFlashLoanReceiver__factory, MockStableMaster, MockStableMaster__factory, + OldAgEUR, + OldAgEUR__factory, Treasury, Treasury__factory, } from '../../../typechain'; @@ -28,7 +28,7 @@ contract('FlashAngle - End-to-end', () => { let flashAngle: FlashAngle; let coreBorrow: CoreBorrow; - let agToken: AgToken; + let agToken: OldAgEUR; let treasury: Treasury; let flashLoanReceiver: MockFlashLoanReceiver; let stableMaster: MockStableMaster; @@ -63,7 +63,7 @@ contract('FlashAngle - End-to-end', () => { stableMaster = (await new MockStableMaster__factory(deployer).deploy()) as MockStableMaster; // Example of upgradeable deployment - Default signer will be user - agToken = (await deployUpgradeable(new AgToken__factory(deployer))) as AgToken; + agToken = (await deployUpgradeable(new OldAgEUR__factory(deployer))) as OldAgEUR; await agToken.initialize('agEUR', 'agEUR', stableMaster.address); treasury = (await deployUpgradeable(new Treasury__factory(deployer))) as Treasury; await treasury.initialize(coreBorrow.address, agToken.address); diff --git a/test/hardhat/vaultManager/vaultManager.test.ts b/test/hardhat/vaultManager/vaultManager.test.ts index 850cc567..be8551f8 100644 --- a/test/hardhat/vaultManager/vaultManager.test.ts +++ b/test/hardhat/vaultManager/vaultManager.test.ts @@ -1,12 +1,9 @@ -import { Oracle, Oracle__factory } from '@angleprotocol/sdk/dist/constants/types'; import { SignerWithAddress } from '@nomiclabs/hardhat-ethers/signers'; import { BigNumber, Signer, utils } from 'ethers'; import { formatBytes32String, parseEther, parseUnits } from 'ethers/lib/utils'; import hre, { contract, ethers, web3 } from 'hardhat'; import { - AgToken, - AgToken__factory, MockOracle, MockOracle__factory, MockStableMaster, @@ -21,6 +18,8 @@ import { MockTreasury__factory, MockVeBoostProxy, MockVeBoostProxy__factory, + OldAgEUR, + OldAgEUR__factory, VaultManagerLiquidationBoost, VaultManagerLiquidationBoost__factory, } from '../../../typechain'; @@ -60,7 +59,7 @@ contract('VaultManagerLiquidationBoost', () => { let collateral: MockToken; let oracle: MockOracle; let stableMaster: MockStableMaster; - let agToken: AgToken; + let agToken: OldAgEUR; let vaultManager: VaultManagerLiquidationBoost; let mockSwapper: MockSwapper; let mockSwapperWithSwap: MockSwapperWithSwap; @@ -106,7 +105,7 @@ contract('VaultManagerLiquidationBoost', () => { stableMaster = await new MockStableMaster__factory(deployer).deploy(); - agToken = (await deployUpgradeable(new AgToken__factory(deployer))) as AgToken; + agToken = (await deployUpgradeable(new OldAgEUR__factory(deployer))) as OldAgEUR; await agToken.connect(deployer).initialize('agEUR', 'agEUR', stableMaster.address); collateral = await new MockToken__factory(deployer).deploy('A', 'A', collatBase); @@ -135,9 +134,9 @@ contract('VaultManagerLiquidationBoost', () => { describe('oracle', () => { it('success - read', async () => { const oracle = (await ethers.getContractAt( - Oracle__factory.abi, + MockOracle__factory.abi, await vaultManager.oracle(), - )) as unknown as Oracle; + )) as unknown as MockOracle; expect(await oracle.read()).to.be.equal(parseUnits('2', 18)); }); }); @@ -1148,7 +1147,7 @@ contract('VaultManagerLiquidationBoost', () => { beforeEach(async () => { // Need to have agToken as a collateral here stableMaster = await new MockStableMaster__factory(deployer).deploy(); - agToken = (await deployUpgradeable(new AgToken__factory(deployer))) as AgToken; + agToken = (await deployUpgradeable(new OldAgEUR__factory(deployer))) as OldAgEUR; await agToken.connect(deployer).initialize('agEUR', 'agEUR', stableMaster.address); vaultManager = (await deployUpgradeable( new VaultManagerLiquidationBoost__factory(deployer), diff --git a/test/hardhat/vaultManager/vaultManagerDust.test.ts b/test/hardhat/vaultManager/vaultManagerDust.test.ts index ed29f9e9..4d901470 100644 --- a/test/hardhat/vaultManager/vaultManagerDust.test.ts +++ b/test/hardhat/vaultManager/vaultManagerDust.test.ts @@ -4,8 +4,6 @@ import { parseEther, parseUnits } from 'ethers/lib/utils'; import hre, { contract, ethers } from 'hardhat'; import { - AgToken, - AgToken__factory, MockOracle, MockOracle__factory, MockStableMaster, @@ -14,6 +12,8 @@ import { MockToken__factory, MockTreasury, MockTreasury__factory, + OldAgEUR, + OldAgEUR__factory, VaultManager, VaultManager__factory, } from '../../../typechain'; @@ -47,7 +47,7 @@ contract('VaultManager - Dust Modification interactions', () => { let collateral: MockToken; let oracle: MockOracle; let stableMaster: MockStableMaster; - let agToken: AgToken; + let agToken: OldAgEUR; let vaultManager: VaultManager; const impersonatedSigners: { [key: string]: Signer } = {}; @@ -89,7 +89,7 @@ contract('VaultManager - Dust Modification interactions', () => { stableMaster = await new MockStableMaster__factory(deployer).deploy(); - agToken = (await deployUpgradeable(new AgToken__factory(deployer))) as AgToken; + agToken = (await deployUpgradeable(new OldAgEUR__factory(deployer))) as OldAgEUR; await agToken.connect(deployer).initialize('agEUR', 'agEUR', stableMaster.address); collateral = await new MockToken__factory(deployer).deploy('A', 'A', collatBase); diff --git a/test/hardhat/vaultManager/vaultManagerERC1155Receiver.test.ts b/test/hardhat/vaultManager/vaultManagerERC1155Receiver.test.ts index 1a7da544..60ae1f25 100644 --- a/test/hardhat/vaultManager/vaultManagerERC1155Receiver.test.ts +++ b/test/hardhat/vaultManager/vaultManagerERC1155Receiver.test.ts @@ -1,12 +1,9 @@ -import { parseAmount } from '@angleprotocol/sdk'; import { SignerWithAddress } from '@nomiclabs/hardhat-ethers/signers'; import { Signer } from 'ethers'; import { parseEther } from 'ethers/lib/utils'; import hre, { contract, ethers } from 'hardhat'; import { - AgToken, - AgToken__factory, AngleHelpers, AngleHelpers__factory, MockOracle, @@ -17,9 +14,12 @@ import { MockToken__factory, MockTreasury, MockTreasury__factory, + OldAgEUR, + OldAgEUR__factory, VaultManagerERC1155Receiver, VaultManagerERC1155Receiver__factory, } from '../../../typechain'; +import { parseAmount } from '../../../utils/bignumber'; import { expect } from '../utils/chai-setup'; import { deployUpgradeable, ZERO_ADDRESS } from '../utils/helpers'; @@ -32,7 +32,7 @@ contract('VaultManagerERC1155Receiver', () => { let collateral: MockToken; let oracle: MockOracle; let stableMaster: MockStableMaster; - let agToken: AgToken; + let agToken: OldAgEUR; let vaultManager: VaultManagerERC1155Receiver; let helpers: AngleHelpers; @@ -70,7 +70,7 @@ contract('VaultManagerERC1155Receiver', () => { beforeEach(async () => { stableMaster = await new MockStableMaster__factory(deployer).deploy(); - agToken = (await deployUpgradeable(new AgToken__factory(deployer))) as AgToken; + agToken = (await deployUpgradeable(new OldAgEUR__factory(deployer))) as OldAgEUR; await agToken.connect(deployer).initialize('agEUR', 'agEUR', stableMaster.address); collateral = await new MockToken__factory(deployer).deploy('USDC', 'USDC', collatBase); vaultManager = (await deployUpgradeable( diff --git a/test/hardhat/vaultManager/vaultManagerERC721.test.ts b/test/hardhat/vaultManager/vaultManagerERC721.test.ts index f2023034..d2ca735d 100644 --- a/test/hardhat/vaultManager/vaultManagerERC721.test.ts +++ b/test/hardhat/vaultManager/vaultManagerERC721.test.ts @@ -4,8 +4,6 @@ import { parseEther } from 'ethers/lib/utils'; import hre, { contract, ethers } from 'hardhat'; import { - AgToken, - AgToken__factory, AngleHelpers, AngleHelpers__factory, MockERC721Receiver__factory, @@ -17,6 +15,8 @@ import { MockToken__factory, MockTreasury, MockTreasury__factory, + OldAgEUR, + OldAgEUR__factory, VaultManagerLiquidationBoost, VaultManagerLiquidationBoost__factory, } from '../../../typechain'; @@ -36,7 +36,7 @@ contract('VaultManagerLiquidationBoost - ERC721', () => { let collateral: MockToken; let oracle: MockOracle; let stableMaster: MockStableMaster; - let agToken: AgToken; + let agToken: OldAgEUR; let vaultManager: VaultManagerLiquidationBoost; let helpers: AngleHelpers; @@ -79,7 +79,7 @@ contract('VaultManagerLiquidationBoost - ERC721', () => { stableMaster = await new MockStableMaster__factory(deployer).deploy(); - agToken = (await deployUpgradeable(new AgToken__factory(deployer))) as AgToken; + agToken = (await deployUpgradeable(new OldAgEUR__factory(deployer))) as OldAgEUR; await agToken.connect(deployer).initialize('agEUR', 'agEUR', stableMaster.address); collateral = await new MockToken__factory(deployer).deploy('USDC', 'USDC', collatBase); diff --git a/test/hardhat/vaultManager/vaultManagerPermit.test.ts b/test/hardhat/vaultManager/vaultManagerPermit.test.ts index 2c7267b7..f611d259 100644 --- a/test/hardhat/vaultManager/vaultManagerPermit.test.ts +++ b/test/hardhat/vaultManager/vaultManagerPermit.test.ts @@ -4,8 +4,6 @@ import { parseEther, parseUnits } from 'ethers/lib/utils'; import hre, { contract, ethers } from 'hardhat'; import { - AgToken, - AgToken__factory, MockERC1271, MockERC1271__factory, MockOracle, @@ -16,6 +14,8 @@ import { MockToken__factory, MockTreasury, MockTreasury__factory, + OldAgEUR, + OldAgEUR__factory, VaultManager, VaultManager__factory, } from '../../../typechain'; @@ -35,7 +35,7 @@ contract('VaultManager - Permit', () => { let collateral: MockToken; let oracle: MockOracle; let stableMaster: MockStableMaster; - let agToken: AgToken; + let agToken: OldAgEUR; let contractSigner: MockERC1271; let vaultManager: VaultManager; let name: string; @@ -81,7 +81,7 @@ contract('VaultManager - Permit', () => { stableMaster = await new MockStableMaster__factory(deployer).deploy(); - agToken = (await deployUpgradeable(new AgToken__factory(deployer))) as AgToken; + agToken = (await deployUpgradeable(new OldAgEUR__factory(deployer))) as OldAgEUR; await agToken.connect(deployer).initialize('agEUR', 'agEUR', stableMaster.address); collateral = await new MockToken__factory(deployer).deploy('A', 'A', collatBase); diff --git a/test/hardhat/vaultManager/vaultManagerSetters.test.ts b/test/hardhat/vaultManager/vaultManagerSetters.test.ts index 5841844d..0c41a720 100644 --- a/test/hardhat/vaultManager/vaultManagerSetters.test.ts +++ b/test/hardhat/vaultManager/vaultManagerSetters.test.ts @@ -4,8 +4,6 @@ import { formatBytes32String, parseEther, parseUnits } from 'ethers/lib/utils'; import hre, { contract, ethers } from 'hardhat'; import { - AgToken, - AgToken__factory, MockOracle, MockOracle__factory, MockStableMaster, @@ -14,6 +12,8 @@ import { MockToken__factory, MockTreasury, MockTreasury__factory, + OldAgEUR, + OldAgEUR__factory, VaultManagerLiquidationBoost, VaultManagerLiquidationBoost__factory, } from '../../../typechain'; @@ -30,7 +30,7 @@ contract('VaultManagerLiquidationBoost - Setters', () => { let collateral: MockToken; let oracle: MockOracle; let stableMaster: MockStableMaster; - let agToken: AgToken; + let agToken: OldAgEUR; let vaultManager: VaultManagerLiquidationBoost; const impersonatedSigners: { [key: string]: Signer } = {}; @@ -72,7 +72,7 @@ contract('VaultManagerLiquidationBoost - Setters', () => { stableMaster = await new MockStableMaster__factory(deployer).deploy(); - agToken = (await deployUpgradeable(new AgToken__factory(deployer))) as AgToken; + agToken = (await deployUpgradeable(new OldAgEUR__factory(deployer))) as OldAgEUR; await agToken.connect(deployer).initialize('agEUR', 'agEUR', stableMaster.address); collateral = await new MockToken__factory(deployer).deploy('A', 'A', collatBase); diff --git a/yarn.lock b/yarn.lock index 3d6be684..748d01b1 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2,11 +2,12 @@ # yarn lockfile v1 -"@angleprotocol/sdk@3.0.56": - version "3.0.56" - resolved "https://registry.yarnpkg.com/@angleprotocol/sdk/-/sdk-3.0.56.tgz#bc9977bc0868c993d7a355b9c1d952c09be3bf1c" - integrity sha512-TFlVfDW9L9FDNkKZlLTruFNfhmdkWKoLbATKELXzmrW8hIn8XES7frQeEDjFi7lJbsWTdQ+HTFNMlG1QmpdEvg== +"@angleprotocol/sdk@0.21.1": + version "0.21.1" + resolved "https://npm.pkg.github.com/download/@angleprotocol/sdk/0.21.1/2f785e40f44da487d3af00dd4234e1aa5222fc46#2f785e40f44da487d3af00dd4234e1aa5222fc46" + integrity sha512-/4G2AL+ccDgL4DOUzSGp7c3yKLoWBy7+hav4/Tpkdo283MB9RSW4k84jJQov+OH3p5to3j5SBRfwrhND5zwu6Q== dependencies: + "@apollo/client" "^3.7.17" "@typechain/ethers-v5" "^10.0.0" "@types/lodash" "^4.14.180" ethers "^5.6.4" @@ -15,10 +16,28 @@ jsbi "^4.3.0" keccak256 "^1.0.6" lodash "^4.17.21" - merkletreejs "^0.3.9" + merkletreejs "^0.3.10" tiny-invariant "^1.1.0" typechain "^8.0.0" +"@apollo/client@^3.7.17": + version "3.8.9" + resolved "https://registry.yarnpkg.com/@apollo/client/-/client-3.8.9.tgz#0e4ac133eb04c63e618138c1ebf273d9f110a4d0" + integrity sha512-IcQDFEEPc9+PEQsxhxQvsoQ04BRarOzi/Ila5PcniRSDeKJWgY22dnp6+V1i1fWXRDVd1ybdvze4sFESDVQUCQ== + dependencies: + "@graphql-typed-document-node/core" "^3.1.1" + "@wry/equality" "^0.5.6" + "@wry/trie" "^0.5.0" + graphql-tag "^2.12.6" + hoist-non-react-statics "^3.3.2" + optimism "^0.18.0" + prop-types "^15.7.2" + response-iterator "^0.2.6" + symbol-observable "^4.0.0" + ts-invariant "^0.10.3" + tslib "^2.3.0" + zen-observable-ts "^1.2.5" + "@babel/code-frame@7.12.11": version "7.12.11" resolved "https://registry.yarnpkg.com/@babel/code-frame/-/code-frame-7.12.11.tgz#f4ad435aa263db935b8f10f2c552d23fb716a63f" @@ -272,21 +291,6 @@ "@ethersproject/properties" "^5.5.0" "@ethersproject/strings" "^5.5.0" -"@ethersproject/abi@5.6.3", "@ethersproject/abi@^5.6.3": - version "5.6.3" - resolved "https://registry.yarnpkg.com/@ethersproject/abi/-/abi-5.6.3.tgz#2d643544abadf6e6b63150508af43475985c23db" - integrity sha512-CxKTdoZY4zDJLWXG6HzNH6znWK0M79WzzxHegDoecE3+K32pzfHOzuXg2/oGSTecZynFgpkjYXNPOqXVJlqClw== - dependencies: - "@ethersproject/address" "^5.6.1" - "@ethersproject/bignumber" "^5.6.2" - "@ethersproject/bytes" "^5.6.1" - "@ethersproject/constants" "^5.6.1" - "@ethersproject/hash" "^5.6.1" - "@ethersproject/keccak256" "^5.6.1" - "@ethersproject/logger" "^5.6.0" - "@ethersproject/properties" "^5.6.0" - "@ethersproject/strings" "^5.6.1" - "@ethersproject/abi@5.6.4": version "5.6.4" resolved "https://registry.yarnpkg.com/@ethersproject/abi/-/abi-5.6.4.tgz#f6e01b6ed391a505932698ecc0d9e7a99ee60362" @@ -317,6 +321,21 @@ "@ethersproject/properties" "^5.7.0" "@ethersproject/strings" "^5.7.0" +"@ethersproject/abi@^5.6.3": + version "5.6.3" + resolved "https://registry.yarnpkg.com/@ethersproject/abi/-/abi-5.6.3.tgz#2d643544abadf6e6b63150508af43475985c23db" + integrity sha512-CxKTdoZY4zDJLWXG6HzNH6znWK0M79WzzxHegDoecE3+K32pzfHOzuXg2/oGSTecZynFgpkjYXNPOqXVJlqClw== + dependencies: + "@ethersproject/address" "^5.6.1" + "@ethersproject/bignumber" "^5.6.2" + "@ethersproject/bytes" "^5.6.1" + "@ethersproject/constants" "^5.6.1" + "@ethersproject/hash" "^5.6.1" + "@ethersproject/keccak256" "^5.6.1" + "@ethersproject/logger" "^5.6.0" + "@ethersproject/properties" "^5.6.0" + "@ethersproject/strings" "^5.6.1" + "@ethersproject/abstract-provider@5.5.1", "@ethersproject/abstract-provider@^5.5.0": version "5.5.1" resolved "https://registry.yarnpkg.com/@ethersproject/abstract-provider/-/abstract-provider-5.5.1.tgz#2f1f6e8a3ab7d378d8ad0b5718460f85649710c5" @@ -791,13 +810,6 @@ dependencies: "@ethersproject/logger" "^5.5.0" -"@ethersproject/networks@5.6.3", "@ethersproject/networks@^5.6.3": - version "5.6.3" - resolved "https://registry.yarnpkg.com/@ethersproject/networks/-/networks-5.6.3.tgz#3ee3ab08f315b433b50c99702eb32e0cf31f899f" - integrity sha512-QZxRH7cA5Ut9TbXwZFiCyuPchdWi87ZtVNHWZd0R6YFgYtes2jQ3+bsslJ0WdyDe0i6QumqtoYqvY3rrQFRZOQ== - dependencies: - "@ethersproject/logger" "^5.6.0" - "@ethersproject/networks@5.6.4": version "5.6.4" resolved "https://registry.yarnpkg.com/@ethersproject/networks/-/networks-5.6.4.tgz#51296d8fec59e9627554f5a8a9c7791248c8dc07" @@ -812,6 +824,13 @@ dependencies: "@ethersproject/logger" "^5.7.0" +"@ethersproject/networks@^5.6.3": + version "5.6.3" + resolved "https://registry.yarnpkg.com/@ethersproject/networks/-/networks-5.6.3.tgz#3ee3ab08f315b433b50c99702eb32e0cf31f899f" + integrity sha512-QZxRH7cA5Ut9TbXwZFiCyuPchdWi87ZtVNHWZd0R6YFgYtes2jQ3+bsslJ0WdyDe0i6QumqtoYqvY3rrQFRZOQ== + dependencies: + "@ethersproject/logger" "^5.6.0" + "@ethersproject/pbkdf2@5.5.0", "@ethersproject/pbkdf2@^5.5.0": version "5.5.0" resolved "https://registry.yarnpkg.com/@ethersproject/pbkdf2/-/pbkdf2-5.5.0.tgz#e25032cdf02f31505d47afbf9c3e000d95c4a050" @@ -1369,6 +1388,11 @@ mkdirp "^1.0.3" untildify "^4.0.0" +"@graphql-typed-document-node/core@^3.1.1": + version "3.2.0" + resolved "https://registry.yarnpkg.com/@graphql-typed-document-node/core/-/core-3.2.0.tgz#5f3d96ec6b2354ad6d8a28bf216a1d97b5426861" + integrity sha512-mB9oAsNCm9aM3/SOv4YtBMqZbYj10R7dkq8byBqxGY/ncFwhf2oQzMV+LCRlWoDSEBJ3COiR1yeDvMtsoOsuFQ== + "@humanwhocodes/config-array@^0.5.0": version "0.5.0" resolved "https://registry.yarnpkg.com/@humanwhocodes/config-array/-/config-array-0.5.0.tgz#1407967d4c6eecd7388f83acf1eaf4d0c6e58ef9" @@ -2277,9 +2301,9 @@ ts-essentials "^7.0.1" "@typechain/ethers-v5@^10.0.0": - version "10.0.0" - resolved "https://registry.yarnpkg.com/@typechain/ethers-v5/-/ethers-v5-10.0.0.tgz#1b6e292d2ed9afb0d2f7a4674cc199bb95bad714" - integrity sha512-Kot7fwAqnH96ZbI8xrRgj5Kpv9yCEdjo7mxRqrH7bYpEgijT5MmuOo8IVsdhOu7Uog4ONg7k/d5UdbAtTKUgsA== + version "10.2.1" + resolved "https://registry.yarnpkg.com/@typechain/ethers-v5/-/ethers-v5-10.2.1.tgz#50241e6957683281ecfa03fb5a6724d8a3ce2391" + integrity sha512-n3tQmCZjRE6IU4h6lqUGiQ1j866n5MTCBJreNEHHVWXa2u9GJTaeYyU1/k+1qLutkyw+sS6VAN+AbeiTqsxd/A== dependencies: lodash "^4.17.15" ts-essentials "^7.0.1" @@ -2397,9 +2421,9 @@ integrity sha1-7ihweulOEdK4J7y+UnC86n8+ce4= "@types/lodash@^4.14.180": - version "4.14.181" - resolved "https://registry.yarnpkg.com/@types/lodash/-/lodash-4.14.181.tgz#d1d3740c379fda17ab175165ba04e2d03389385d" - integrity sha512-n3tyKthHJbkiWhDZs3DkhkCzt2MexYHXlX0td5iMplyfwketaOeKboEVBqzceH7juqvEg3q5oUoBFxSLu7zFag== + version "4.14.202" + resolved "https://registry.yarnpkg.com/@types/lodash/-/lodash-4.14.202.tgz#f09dbd2fb082d507178b2f2a5c7e74bd72ff98f8" + integrity sha512-OvlIYQK9tNneDlS0VN54LLd5uiPCBOp7gS5Z0f1mjoJYBrtStzgmJBxONW3U6OZqdtNzZPmn9BS/7WI7BFFcFQ== "@types/lru-cache@^5.1.0": version "5.1.1" @@ -2779,6 +2803,41 @@ "@webassemblyjs/ast" "1.11.1" "@xtuc/long" "4.2.2" +"@wry/caches@^1.0.0": + version "1.0.1" + resolved "https://registry.yarnpkg.com/@wry/caches/-/caches-1.0.1.tgz#8641fd3b6e09230b86ce8b93558d44cf1ece7e52" + integrity sha512-bXuaUNLVVkD20wcGBWRyo7j9N3TxePEWFZj2Y+r9OoUzfqmavM84+mFykRicNsBqatba5JLay1t48wxaXaWnlA== + dependencies: + tslib "^2.3.0" + +"@wry/context@^0.7.0": + version "0.7.4" + resolved "https://registry.yarnpkg.com/@wry/context/-/context-0.7.4.tgz#e32d750fa075955c4ab2cfb8c48095e1d42d5990" + integrity sha512-jmT7Sb4ZQWI5iyu3lobQxICu2nC/vbUhP0vIdd6tHC9PTfenmRmuIFqktc6GH9cgi+ZHnsLWPvfSvc4DrYmKiQ== + dependencies: + tslib "^2.3.0" + +"@wry/equality@^0.5.6": + version "0.5.7" + resolved "https://registry.yarnpkg.com/@wry/equality/-/equality-0.5.7.tgz#72ec1a73760943d439d56b7b1e9985aec5d497bb" + integrity sha512-BRFORjsTuQv5gxcXsuDXx6oGRhuVsEGwZy6LOzRRfgu+eSfxbhUQ9L9YtSEIuIjY/o7g3iWFjrc5eSY1GXP2Dw== + dependencies: + tslib "^2.3.0" + +"@wry/trie@^0.4.3": + version "0.4.3" + resolved "https://registry.yarnpkg.com/@wry/trie/-/trie-0.4.3.tgz#077d52c22365871bf3ffcbab8e95cb8bc5689af4" + integrity sha512-I6bHwH0fSf6RqQcnnXLJKhkSXG45MFral3GxPaY4uAl0LYDZM+YDVDAiU9bYwjTuysy1S0IeecWtmq1SZA3M1w== + dependencies: + tslib "^2.3.0" + +"@wry/trie@^0.5.0": + version "0.5.0" + resolved "https://registry.yarnpkg.com/@wry/trie/-/trie-0.5.0.tgz#11e783f3a53f6e4cd1d42d2d1323f5bc3fa99c94" + integrity sha512-FNoYzHawTMk/6KMQoEG5O4PuioX19UbwdQKF44yw0nLfOypfQdjtfZzo/UIJWAJ23sNIFbD1Ug9lbaDGMwbqQA== + dependencies: + tslib "^2.3.0" + "@xtuc/ieee754@^1.2.0": version "1.2.0" resolved "https://registry.yarnpkg.com/@xtuc/ieee754/-/ieee754-1.2.0.tgz#eef014a3145ae477a1cbc00cd1e552336dceb790" @@ -3112,7 +3171,7 @@ array-back@^3.0.1, array-back@^3.1.0: resolved "https://registry.yarnpkg.com/array-back/-/array-back-3.1.0.tgz#b8859d7a508871c9a7b2cf42f99428f65e96bfb0" integrity sha512-TkuxA4UCOvxuDK6NZYXCalszEzj+TLszyASooky+i742l9TqsOdYCMJJupxRic61hwquNtppB3hgcuq9SVSH1Q== -array-back@^4.0.1: +array-back@^4.0.1, array-back@^4.0.2: version "4.0.2" resolved "https://registry.yarnpkg.com/array-back/-/array-back-4.0.2.tgz#8004e999a6274586beeb27342168652fdb89fa1e" integrity sha512-NbdMezxqf94cnNfWLL7V/im0Ub+Anbb0IoZhvzie8+4HJ4nMQuzHuy49FkGYCJK2yAloZ3meiB6AVMClbrI1vg== @@ -4830,13 +4889,13 @@ command-line-args@^5.1.1: typical "^4.0.0" command-line-usage@^6.1.0: - version "6.1.1" - resolved "https://registry.yarnpkg.com/command-line-usage/-/command-line-usage-6.1.1.tgz#c908e28686108917758a49f45efb4f02f76bc03f" - integrity sha512-F59pEuAR9o1SF/bD0dQBDluhpT4jJQNWUHEuVBqpDmCUo6gPjCi+m9fCWnWZVR/oG6cMTUms4h+3NPl74wGXvA== + version "6.1.3" + resolved "https://registry.yarnpkg.com/command-line-usage/-/command-line-usage-6.1.3.tgz#428fa5acde6a838779dfa30e44686f4b6761d957" + integrity sha512-sH5ZSPr+7UStsloltmDh7Ce5fb8XPlHyoPzTpyyMuYCtervL65+ubVZ6Q61cFtFl62UyJlc8/JwERRbAFPUqgw== dependencies: - array-back "^4.0.1" + array-back "^4.0.2" chalk "^2.4.2" - table-layout "^1.0.1" + table-layout "^1.0.2" typical "^5.2.0" commander@2.18.0: @@ -5139,6 +5198,11 @@ crypto-js@^3.1.4, crypto-js@^3.1.9-1: resolved "https://registry.yarnpkg.com/crypto-js/-/crypto-js-3.3.0.tgz#846dd1cce2f68aacfa156c8578f926a609b7976b" integrity sha512-DIT51nX0dCfKltpRiXV+/TVZq+Qq2NgF4644+K7Ttnla7zEzqc+kjJyiB96BHNyUTBxyjzRcZYpUdZa+QAqi6Q== +crypto-js@^4.2.0: + version "4.2.0" + resolved "https://registry.yarnpkg.com/crypto-js/-/crypto-js-4.2.0.tgz#4d931639ecdfd12ff80e8186dba6af2c2e856631" + integrity sha512-KALDyEYgpY+Rlob/iriUtjV6d5Eq+Y191A5g4UqLAi8CyGP9N1+FdVbkc1SxKc2r4YAYqG8JzO2KGL+AizD70Q== + css-loader@^6.5.1: version "6.6.0" resolved "https://registry.yarnpkg.com/css-loader/-/css-loader-6.6.0.tgz#c792ad5510bd1712618b49381bd0310574fafbd3" @@ -6748,43 +6812,7 @@ ethers@^5.5.3: "@ethersproject/web" "5.6.1" "@ethersproject/wordlists" "5.6.1" -ethers@^5.6.4: - version "5.6.8" - resolved "https://registry.yarnpkg.com/ethers/-/ethers-5.6.8.tgz#d36b816b4896341a80a8bbd2a44e8cb6e9b98dd4" - integrity sha512-YxIGaltAOdvBFPZwIkyHnXbW40f1r8mHUgapW6dxkO+6t7H6wY8POUn0Kbxrd/N7I4hHxyi7YCddMAH/wmho2w== - dependencies: - "@ethersproject/abi" "5.6.3" - "@ethersproject/abstract-provider" "5.6.1" - "@ethersproject/abstract-signer" "5.6.2" - "@ethersproject/address" "5.6.1" - "@ethersproject/base64" "5.6.1" - "@ethersproject/basex" "5.6.1" - "@ethersproject/bignumber" "5.6.2" - "@ethersproject/bytes" "5.6.1" - "@ethersproject/constants" "5.6.1" - "@ethersproject/contracts" "5.6.2" - "@ethersproject/hash" "5.6.1" - "@ethersproject/hdnode" "5.6.2" - "@ethersproject/json-wallets" "5.6.1" - "@ethersproject/keccak256" "5.6.1" - "@ethersproject/logger" "5.6.0" - "@ethersproject/networks" "5.6.3" - "@ethersproject/pbkdf2" "5.6.1" - "@ethersproject/properties" "5.6.0" - "@ethersproject/providers" "5.6.8" - "@ethersproject/random" "5.6.1" - "@ethersproject/rlp" "5.6.1" - "@ethersproject/sha2" "5.6.1" - "@ethersproject/signing-key" "5.6.2" - "@ethersproject/solidity" "5.6.1" - "@ethersproject/strings" "5.6.1" - "@ethersproject/transactions" "5.6.2" - "@ethersproject/units" "5.6.1" - "@ethersproject/wallet" "5.6.2" - "@ethersproject/web" "5.6.1" - "@ethersproject/wordlists" "5.6.1" - -ethers@^5.7.1: +ethers@^5.6.4, ethers@^5.7.1: version "5.7.2" resolved "https://registry.yarnpkg.com/ethers/-/ethers-5.7.2.tgz#3a7deeabbb8c030d4126b24f84e525466145872e" integrity sha512-wswUsmWo1aOK8rR7DIKiWSw9DbLWe6x98Jrn8wcTflTVvaXhAMaB5zGAXy0GYQEQp9iO1iSHWVyARQm11zUtyg== @@ -7879,6 +7907,13 @@ graphql-request@^3.6.1: extract-files "^9.0.0" form-data "^3.0.0" +graphql-tag@^2.12.6: + version "2.12.6" + resolved "https://registry.yarnpkg.com/graphql-tag/-/graphql-tag-2.12.6.tgz#d441a569c1d2537ef10ca3d1633b48725329b5f1" + integrity sha512-FdSNcu2QQcWnM2VNvSCCDCVS5PpPqpzgFT8+GXzqJuoDd0CBncxCY278u4mhRO7tMgo2JjgJA5aZ+nWSQ/Z+xg== + dependencies: + tslib "^2.1.0" + graphql@15.5.1: version "15.5.1" resolved "https://registry.yarnpkg.com/graphql/-/graphql-15.5.1.tgz#f2f84415d8985e7b84731e7f3536f8bb9d383aad" @@ -7993,10 +8028,10 @@ hardhat-watcher@^2.1.1: dependencies: chokidar "^3.4.3" -hardhat@2.19.0: - version "2.19.0" - resolved "https://registry.yarnpkg.com/hardhat/-/hardhat-2.19.0.tgz#1e08658863550ba351788ea128e544ff80584a31" - integrity sha512-kMpwovOEfrFRQXEopCP+JTcKVwSYVj8rnXE0LynxDqnh06yvyKCQknmXL6IVYTHQL6Csysc/yNbCHQbjSeJGpA== +hardhat@2.19.4: + version "2.19.4" + resolved "https://registry.yarnpkg.com/hardhat/-/hardhat-2.19.4.tgz#5112c30295d8be2e18e55d847373c50483ed1902" + integrity sha512-fTQJpqSt3Xo9Mn/WrdblNGAfcANM6XC3tAEi6YogB4s02DmTf93A8QsGb8uR0KR8TFcpcS8lgiW4ugAIYpnbrQ== dependencies: "@ethersproject/abi" "^5.1.2" "@metamask/eth-sig-util" "^4.0.0" @@ -8213,6 +8248,13 @@ hmac-drbg@^1.0.1: minimalistic-assert "^1.0.0" minimalistic-crypto-utils "^1.0.1" +hoist-non-react-statics@^3.3.2: + version "3.3.2" + resolved "https://registry.yarnpkg.com/hoist-non-react-statics/-/hoist-non-react-statics-3.3.2.tgz#ece0acaf71d62c2969c2ec59feff42a4b1a85b45" + integrity sha512-/gGivxi8JPKWNm/W0jSmzcMPpfpPLc3dY/6GxhX2hQ9iGj3aDfklV4ET7NjKpSinLpJ5vafa9iiGIEZg10SfBw== + dependencies: + react-is "^16.7.0" + home-or-tmp@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/home-or-tmp/-/home-or-tmp-2.0.0.tgz#e36c3f2d2cae7d746a857e38d18d5f32a7882db8" @@ -9516,7 +9558,7 @@ lodash.assign@^4.0.3, lodash.assign@^4.0.6: lodash.camelcase@^4.3.0: version "4.3.0" resolved "https://registry.yarnpkg.com/lodash.camelcase/-/lodash.camelcase-4.3.0.tgz#b28aa6288a2b9fc651035c7711f65ab6190331a6" - integrity sha1-soqmKIorn8ZRA1x3EfZathkDMaY= + integrity sha512-TwuEnCnxbc3rAvhf/LbG7tJUDzhqXyFnv3dtzLOPgCG/hODL7WFnsbwktkD7yUV0RrreP/l1PALq/YSg6VvjlA== lodash.clonedeep@^4.5.0: version "4.5.0" @@ -9588,7 +9630,7 @@ looper@^3.0.0: resolved "https://registry.yarnpkg.com/looper/-/looper-3.0.0.tgz#2efa54c3b1cbaba9b94aee2e5914b0be57fbb749" integrity sha1-LvpUw7HLq6m5Su4uWRSwvlf7t0k= -loose-envify@^1.0.0: +loose-envify@^1.0.0, loose-envify@^1.4.0: version "1.4.0" resolved "https://registry.yarnpkg.com/loose-envify/-/loose-envify-1.4.0.tgz#71ee51fa7be4caec1a63839f7e682d8132d30caf" integrity sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q== @@ -9850,14 +9892,14 @@ merkletreejs@0.2.32: treeify "^1.1.0" web3-utils "^1.3.4" -merkletreejs@^0.3.9: - version "0.3.9" - resolved "https://registry.yarnpkg.com/merkletreejs/-/merkletreejs-0.3.9.tgz#cdb364a3b974a44f4eff3446522d7066e0cf95de" - integrity sha512-NjlATjJr4NEn9s8v/VEHhgwRWaE1eA/Une07d9SEqKzULJi1Wsh0Y3svwJdP2bYLMmgSBHzOrNydMWM1NN9VeQ== +merkletreejs@^0.3.10: + version "0.3.11" + resolved "https://registry.yarnpkg.com/merkletreejs/-/merkletreejs-0.3.11.tgz#e0de05c3ca1fd368de05a12cb8efb954ef6fc04f" + integrity sha512-LJKTl4iVNTndhL+3Uz/tfkjD0klIWsHlUzgtuNnNrsf7bAlXR30m+xYB7lHr5Z/l6e/yAIsr26Dabx6Buo4VGQ== dependencies: bignumber.js "^9.0.1" buffer-reverse "^1.0.1" - crypto-js "^3.1.9-1" + crypto-js "^4.2.0" treeify "^1.1.0" web3-utils "^1.3.4" @@ -10600,6 +10642,16 @@ open@^7.4.2: is-docker "^2.0.0" is-wsl "^2.1.1" +optimism@^0.18.0: + version "0.18.0" + resolved "https://registry.yarnpkg.com/optimism/-/optimism-0.18.0.tgz#e7bb38b24715f3fdad8a9a7fc18e999144bbfa63" + integrity sha512-tGn8+REwLRNFnb9WmcY5IfpOqeX2kpaYJ1s6Ae3mn12AeydLkR3j+jSCmVQFoXqU8D41PAJ1RG1rCRNWmNZVmQ== + dependencies: + "@wry/caches" "^1.0.0" + "@wry/context" "^0.7.0" + "@wry/trie" "^0.4.3" + tslib "^2.3.0" + optionator@^0.8.1, optionator@^0.8.2: version "0.8.3" resolved "https://registry.yarnpkg.com/optionator/-/optionator-0.8.3.tgz#84fa1d036fe9d3c7e21d99884b601167ec8fb495" @@ -11170,16 +11222,11 @@ prettier@^1.14.3: resolved "https://registry.yarnpkg.com/prettier/-/prettier-2.5.1.tgz#fff75fa9d519c54cf0fce328c1017d94546bc56a" integrity sha512-vBZcPRUR5MZJwoyi3ZoyQlc1rXeEck8KgeC9AwwOn+exuxLxq5toTRDTSaVrXHxelDMHy9zlicw8u66yxoSUFg== -prettier@^2.0.0, prettier@^2.8.3: +prettier@^2.0.0, prettier@^2.3.1, prettier@^2.8.3: version "2.8.8" resolved "https://registry.yarnpkg.com/prettier/-/prettier-2.8.8.tgz#e8c5d7e98a4305ffe3de2e1fc4aca1a71c28b1da" integrity sha512-tdN8qQGvNjw4CHbY+XXk0JgCXn9QiF21a55rBe5LJAU+kDyC4WQn4+awm2Xfk2lQMk5fKup9XgzTZtGkjBdP9Q== -prettier@^2.3.1: - version "2.6.2" - resolved "https://registry.yarnpkg.com/prettier/-/prettier-2.6.2.tgz#e26d71a18a74c3d0f0597f55f01fb6c06c206032" - integrity sha512-PkUpF+qoXTqhOeWL9fu7As8LXsIUZ1WYaJiY/a7McAQzxjk82OF0tibkFXVCDImZtWxbvojFjerkiLb0/q8mew== - pretty-error@^4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/pretty-error/-/pretty-error-4.0.0.tgz#90a703f46dd7234adb46d0f84823e9d1cb8f10d6" @@ -11228,6 +11275,15 @@ promise@^8.0.0: dependencies: asap "~2.0.6" +prop-types@^15.7.2: + version "15.8.1" + resolved "https://registry.yarnpkg.com/prop-types/-/prop-types-15.8.1.tgz#67d87bf1a694f48435cf332c24af10214a3140b5" + integrity sha512-oj87CgZICdulUohogVAR7AjlC0327U4el4L6eAvOqCeudMDVU0NThNaV+b9Df4dXgSP1gXMTnPdhfe/2qDH5cg== + dependencies: + loose-envify "^1.4.0" + object-assign "^4.1.1" + react-is "^16.13.1" + proper-lockfile@^4.1.1, proper-lockfile@^4.1.2: version "4.1.2" resolved "https://registry.yarnpkg.com/proper-lockfile/-/proper-lockfile-4.1.2.tgz#c8b9de2af6b2f1601067f98e01ac66baa223141f" @@ -11452,6 +11508,11 @@ raw-body@^2.4.1: iconv-lite "0.4.24" unpipe "1.0.0" +react-is@^16.13.1, react-is@^16.7.0: + version "16.13.1" + resolved "https://registry.yarnpkg.com/react-is/-/react-is-16.13.1.tgz#789729a4dc36de2999dc156dd6c1d9c18cea56a4" + integrity sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ== + read-pkg-up@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/read-pkg-up/-/read-pkg-up-1.0.1.tgz#9d63c13276c065918d57f002a57f40a1b643fb02" @@ -11796,6 +11857,11 @@ resolve@^1.1.6, resolve@^1.10.0, resolve@^1.10.1, resolve@^1.20.0, resolve@^1.8. path-parse "^1.0.7" supports-preserve-symlinks-flag "^1.0.0" +response-iterator@^0.2.6: + version "0.2.6" + resolved "https://registry.yarnpkg.com/response-iterator/-/response-iterator-0.2.6.tgz#249005fb14d2e4eeb478a3f735a28fd8b4c9f3da" + integrity sha512-pVzEEzrsg23Sh053rmDUvLSkGXluZio0qu8VT6ukrYuvtjVfCbDZH9d6PGXb8HZfzdNZt8feXv/jvUzlhRgLnw== + responselike@^1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/responselike/-/responselike-1.0.2.tgz#918720ef3b631c5642be068f15ade5a46f4ba1e7" @@ -12915,6 +12981,11 @@ swarm-js@^0.1.40: tar "^4.0.2" xhr-request "^1.0.1" +symbol-observable@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/symbol-observable/-/symbol-observable-4.0.0.tgz#5b425f192279e87f2f9b937ac8540d1984b39205" + integrity sha512-b19dMThMV4HVFynSAM1++gBHAbk2Tc/osgLIBZMKsyqh34jb2e8Os7T6ZW/Bt3pJFdBTd2JwAnAAEQV7rSNvcQ== + sync-request@^6.0.0: version "6.1.0" resolved "https://registry.yarnpkg.com/sync-request/-/sync-request-6.1.0.tgz#e96217565b5e50bbffe179868ba75532fb597e68" @@ -12931,7 +13002,7 @@ sync-rpc@^1.2.1: dependencies: get-port "^3.1.0" -table-layout@^1.0.1: +table-layout@^1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/table-layout/-/table-layout-1.0.2.tgz#c4038a1853b0136d63365a734b6931cf4fad4a04" integrity sha512-qd/R7n5rQTRFi+Zf2sk5XVVd9UQl6ZkduPFC3S7WEGJAmetDTjY3qPN50eSKzwuzEyQKy5TN2TiZdkIjos2L6A== @@ -13283,9 +13354,9 @@ trim-right@^1.0.1: integrity sha1-yy4SAwZ+DI3h9hQJS5/kVwTqYAM= ts-command-line-args@^2.2.0: - version "2.2.1" - resolved "https://registry.yarnpkg.com/ts-command-line-args/-/ts-command-line-args-2.2.1.tgz#fd6913e542099012c0ffb2496126a8f38305c7d6" - integrity sha512-mnK68QA86FYzQYTSA/rxIjT/8EpKsvQw9QkawPic8I8t0gjAOw3Oa509NIRoaY1FmH7hdrncMp7t7o+vYoceNQ== + version "2.5.1" + resolved "https://registry.yarnpkg.com/ts-command-line-args/-/ts-command-line-args-2.5.1.tgz#e64456b580d1d4f6d948824c274cf6fa5f45f7f0" + integrity sha512-H69ZwTw3rFHb5WYpQya40YAX2/w7Ut75uUECbgBIsLmM+BNuYnxsltfyyLMxy6sEeKxgijLTnQtLd0nKd6+IYw== dependencies: chalk "^4.1.0" command-line-args "^5.1.1" @@ -13322,6 +13393,13 @@ ts-generator@^0.1.1: resolve "^1.8.1" ts-essentials "^1.0.0" +ts-invariant@^0.10.3: + version "0.10.3" + resolved "https://registry.yarnpkg.com/ts-invariant/-/ts-invariant-0.10.3.tgz#3e048ff96e91459ffca01304dbc7f61c1f642f6c" + integrity sha512-uivwYcQaxAucv1CzRp2n/QdYPo4ILf9VXgH19zEIjFx2EJufV16P0JtJVpYHy89DItG6Kwj2oIUjrcK5au+4tQ== + dependencies: + tslib "^2.1.0" + ts-morph@^19.0.0: version "19.0.0" resolved "https://registry.yarnpkg.com/ts-morph/-/ts-morph-19.0.0.tgz#43e95fb0156c3fe3c77c814ac26b7d0be2f93169" @@ -13366,6 +13444,11 @@ tslib@^2.0.0, tslib@^2.0.3, tslib@^2.2.0, tslib@^2.3.1: resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.3.1.tgz#e8a335add5ceae51aa261d32a490158ef042ef01" integrity sha512-77EbyPPpMz+FRFRuAFlWMtmgUWGe9UOG2Z25NqCwiIjRhOf5iKGuzSe5P2w1laq+FkRy4p+PCuVkJSGkzTEKVw== +tslib@^2.1.0, tslib@^2.3.0: + version "2.6.2" + resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.6.2.tgz#703ac29425e7b37cd6fd456e92404d46d1f3e4ae" + integrity sha512-AEYxH93jGFPn/a2iVAwW87VuUIkR1FVUKB77NwMF7nBTDkDrrT/Hpt/IrCJ0QXhW27jTBDcf5ZY7w6RiqTMw2Q== + tsort@0.0.1: version "0.0.1" resolved "https://registry.yarnpkg.com/tsort/-/tsort-0.0.1.tgz#e2280f5e817f8bf4275657fd0f9aebd44f5a2786" @@ -13482,9 +13565,9 @@ typechain@^3.0.0: ts-generator "^0.1.1" typechain@^8.0.0: - version "8.0.0" - resolved "https://registry.yarnpkg.com/typechain/-/typechain-8.0.0.tgz#a5dbe754717a7e16247df52b5285903de600e8ff" - integrity sha512-rqDfDYc9voVAhmfVfAwzg3VYFvhvs5ck1X9T/iWkX745Cul4t+V/smjnyqrbDzWDbzD93xfld1epg7Y/uFAesQ== + version "8.3.2" + resolved "https://registry.yarnpkg.com/typechain/-/typechain-8.3.2.tgz#1090dd8d9c57b6ef2aed3640a516bdbf01b00d73" + integrity sha512-x/sQYr5w9K7yv3es7jo4KTX05CLxOf7TRWwoHlrjRh8H82G64g+k7VuWPJlgMo6qrjfCulOdfBjiaDtmhFYD/Q== dependencies: "@types/prettier" "^2.1.1" debug "^4.3.1" @@ -15398,6 +15481,18 @@ yocto-queue@^0.1.0: resolved "https://registry.yarnpkg.com/yocto-queue/-/yocto-queue-0.1.0.tgz#0294eb3dee05028d31ee1a5fa2c556a6aaf10a1b" integrity sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q== +zen-observable-ts@^1.2.5: + version "1.2.5" + resolved "https://registry.yarnpkg.com/zen-observable-ts/-/zen-observable-ts-1.2.5.tgz#6c6d9ea3d3a842812c6e9519209365a122ba8b58" + integrity sha512-QZWQekv6iB72Naeake9hS1KxHlotfRpe+WGNbNx5/ta+R3DNjVO2bswf63gXlWDcs+EMd7XY8HfVQyP1X6T4Zg== + dependencies: + zen-observable "0.8.15" + +zen-observable@0.8.15: + version "0.8.15" + resolved "https://registry.yarnpkg.com/zen-observable/-/zen-observable-0.8.15.tgz#96415c512d8e3ffd920afd3889604e30b9eaac15" + integrity sha512-PQ2PC7R9rslx84ndNBZB/Dkv8V8fZEpk83RLgXtYd0fwUgEjseMn1Dgajh2x6S8QbZAFa9p2qVCEuYZNgve0dQ== + zksync-web3@^0.7.8: version "0.7.9" resolved "https://registry.yarnpkg.com/zksync-web3/-/zksync-web3-0.7.9.tgz#fbb9a17f4b297c0fb9361de2a0d85ff2aac5becc"